From 2455ea4fe7286bff028e01bddff8f39f94bf59f8 Mon Sep 17 00:00:00 2001 From: bc299 Date: Wed, 3 Jan 2024 16:15:12 -0500 Subject: [PATCH 1/6] dropped unnecessary columns for each of the different health metrics --- dbdpy/__init__.py | 5 +- dbdpy/apple_watch.py | 48 ++++--- notebooks/apple_example.ipynb | 252 +++------------------------------- 3 files changed, 50 insertions(+), 255 deletions(-) diff --git a/dbdpy/__init__.py b/dbdpy/__init__.py index 7ccc9d52..9739539b 100644 --- a/dbdpy/__init__.py +++ b/dbdpy/__init__.py @@ -1,4 +1 @@ -from dbdpy.apple_watch import AppleWatch - -def read_file(filepath: str) -> AppleWatch: - return AppleWatch.read_file(filepath) \ No newline at end of file +from .apple_watch import AppleWatch \ No newline at end of file diff --git a/dbdpy/apple_watch.py b/dbdpy/apple_watch.py index 5c7a8103..280f794d 100644 --- a/dbdpy/apple_watch.py +++ b/dbdpy/apple_watch.py @@ -1,3 +1,5 @@ +import unicodedata + import pandas as pd import xml.etree.ElementTree as ET @@ -11,29 +13,35 @@ def __init__(self, steps=None, distance=None, oxygen=None, - resting_heart_rate=None, - heart_rate=None, - respiration_rate=None + heart_rate=None ) -> None: self.sleep = sleep self.energy = energy self.steps = steps self.distance = distance self.oxygen = oxygen - self.resting_heart_rate = resting_heart_rate self.heart_rate = heart_rate - self.respiration_rate = respiration_rate @classmethod - def read_file(cls, filepath: str): + def read_file(cls, filepath: str, device_name: str="Apple Watch"): + # TODO: Deidentify device name + # TODO: Store device model information # Extract data from XML file and put into dataframe tree = ET.parse(filepath) root = tree.getroot() record_list = [x.attrib for x in root.iter("Record")] record_df = pd.DataFrame(record_list) - + + # Only save the watch data and discard the iPhone data + record_df["sourceName"] = record_df["sourceName"].apply(lambda x: unicodedata.normalize("NFKC", x)) + record_df = record_df[record_df["sourceName"].str.contains(device_name)] + + # Drop columns that will not be used + drop_cols = ["sourceName", "sourceVersion", "unit", "creationDate", "device"] + record_df.drop(columns=drop_cols, axis=1, inplace=True) + # Convert datetime to ISO 8601 format - datetime_cols = ["creationDate", "startDate", "endDate"] + datetime_cols = ["startDate", "endDate"] record_df[datetime_cols] = record_df[datetime_cols]\ .apply(lambda x: pd.to_datetime(x).dt.strftime("%Y-%m-%dT%H:%M:%S")) @@ -44,16 +52,20 @@ def read_file(cls, filepath: str): record_df["type"] = record_df["type"].str.replace("HKQuantityTypeIdentifier", "") record_df["type"] = record_df["type"].str.replace("HKCategoryTypeIdentifier", "") - # Extract data and populate attributes - energy = record_df[record_df["type"] == "BasalEnergyBurned"] - steps = record_df[record_df["type"] == "StepCount"] - distance = record_df[record_df["type"] == "DistanceWalkingRunning"] - oxygen = record_df[record_df["type"] == "OxygenSaturation"] - resting_heart_rate = record_df[record_df["type"] == "RestingHeartRate"] - heart_rate = record_df[record_df["type"] == "HeartRate"] - respiration_rate = record_df[record_df["type"] == "RespiratoryRate"] - sleep = record_df[record_df["type"] == "SleepAnalysis"] + # Extract data, convert to standard format, and populate attributes + energy = record_df[record_df["type"] == "BasalEnergyBurned"]\ + .drop(columns="type").rename(columns={"value": "active_calories"}) + steps = record_df[record_df["type"] == "StepCount"]\ + .drop(columns="type").rename(columns={"value": "steps"}) + distance = record_df[record_df["type"] == "DistanceWalkingRunning"]\ + .drop(columns="type").rename(columns={"value": "distance"}) + oxygen = record_df[record_df["type"] == "OxygenSaturation"]\ + .drop(columns="type").rename(columns={"value": "SpO2"}) + heart_rate = record_df[record_df["type"] == "HeartRate"]\ + .drop(columns="type").rename(columns={"value": "heart_rate"}) + sleep = record_df[record_df["type"] == "SleepAnalysis"]\ + .drop(columns="type") return cls(sleep=sleep, energy=energy, steps=steps, distance=distance, oxygen=oxygen, - resting_heart_rate=resting_heart_rate, heart_rate=heart_rate, respiration_rate=respiration_rate) + heart_rate=heart_rate) \ No newline at end of file diff --git a/notebooks/apple_example.ipynb b/notebooks/apple_example.ipynb index 8b03c5be..dcc291ef 100644 --- a/notebooks/apple_example.ipynb +++ b/notebooks/apple_example.ipynb @@ -195,278 +195,64 @@ "sleep = record_df[record_df[\"type\"] == \"SleepAnalysis\"]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using dbdpy" + ] + }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 46, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
typesourceNamesourceVersionunitcreationDatestartDateendDatevaluedevice
171442BasalEnergyBurnedShunのiPhone16.2Cal2022-12-25T02:24:042022-12-24T01:45:202022-12-24T02:00:0739.415<<HKDevice: 0x2802641e0>, name:iPhone, manufac...
171443BasalEnergyBurnedShunのiPhone16.2Cal2022-12-25T02:24:042022-12-24T02:00:072022-12-24T02:15:4442.899<<HKDevice: 0x2802641e0>, name:iPhone, manufac...
171444BasalEnergyBurnedShunのiPhone16.2Cal2022-12-25T02:24:042022-12-24T02:15:442022-12-24T02:29:3037.099<<HKDevice: 0x2802641e0>, name:iPhone, manufac...
171445BasalEnergyBurnedShunのiPhone16.2Cal2022-12-25T02:24:042022-12-24T02:29:302022-12-24T02:45:1843.129<<HKDevice: 0x2802641e0>, name:iPhone, manufac...
171446BasalEnergyBurnedShunのiPhone16.2Cal2022-12-25T02:24:042022-12-24T02:45:182022-12-24T03:01:0142.906<<HKDevice: 0x2802641e0>, name:iPhone, manufac...
..............................
204284BasalEnergyBurnedShun’s Apple Watch9.3Cal2023-09-30T10:35:562023-09-30T10:35:232023-09-30T10:35:410.525<<HKDevice: 0x280280460>, name:Apple Watch, ma...
204285BasalEnergyBurnedShun’s Apple Watch9.3Cal2023-09-30T10:36:132023-09-30T10:35:412023-09-30T10:35:590.525<<HKDevice: 0x280280460>, name:Apple Watch, ma...
204286BasalEnergyBurnedShun’s Apple Watch9.3Cal2023-09-30T10:36:312023-09-30T10:35:592023-09-30T10:36:170.525<<HKDevice: 0x280280460>, name:Apple Watch, ma...
204287BasalEnergyBurnedShun’s Apple Watch9.3Cal2023-09-30T10:36:482023-09-30T10:36:172023-09-30T10:36:350.525<<HKDevice: 0x280280460>, name:Apple Watch, ma...
204288BasalEnergyBurnedShun’s Apple Watch9.3Cal2023-09-30T10:37:032023-09-30T10:36:352023-09-30T10:36:530.525<<HKDevice: 0x280280460>, name:Apple Watch, ma...
\n", - "

32847 rows × 9 columns

\n", - "
" - ], "text/plain": [ - " type sourceName sourceVersion unit \\\n", - "171442 BasalEnergyBurned ShunのiPhone 16.2 Cal \n", - "171443 BasalEnergyBurned ShunのiPhone 16.2 Cal \n", - "171444 BasalEnergyBurned ShunのiPhone 16.2 Cal \n", - "171445 BasalEnergyBurned ShunのiPhone 16.2 Cal \n", - "171446 BasalEnergyBurned ShunのiPhone 16.2 Cal \n", - "... ... ... ... ... \n", - "204284 BasalEnergyBurned Shun’s Apple Watch 9.3 Cal \n", - "204285 BasalEnergyBurned Shun’s Apple Watch 9.3 Cal \n", - "204286 BasalEnergyBurned Shun’s Apple Watch 9.3 Cal \n", - "204287 BasalEnergyBurned Shun’s Apple Watch 9.3 Cal \n", - "204288 BasalEnergyBurned Shun’s Apple Watch 9.3 Cal \n", - "\n", - " creationDate startDate endDate value \\\n", - "171442 2022-12-25T02:24:04 2022-12-24T01:45:20 2022-12-24T02:00:07 39.415 \n", - "171443 2022-12-25T02:24:04 2022-12-24T02:00:07 2022-12-24T02:15:44 42.899 \n", - "171444 2022-12-25T02:24:04 2022-12-24T02:15:44 2022-12-24T02:29:30 37.099 \n", - "171445 2022-12-25T02:24:04 2022-12-24T02:29:30 2022-12-24T02:45:18 43.129 \n", - "171446 2022-12-25T02:24:04 2022-12-24T02:45:18 2022-12-24T03:01:01 42.906 \n", - "... ... ... ... ... \n", - "204284 2023-09-30T10:35:56 2023-09-30T10:35:23 2023-09-30T10:35:41 0.525 \n", - "204285 2023-09-30T10:36:13 2023-09-30T10:35:41 2023-09-30T10:35:59 0.525 \n", - "204286 2023-09-30T10:36:31 2023-09-30T10:35:59 2023-09-30T10:36:17 0.525 \n", - "204287 2023-09-30T10:36:48 2023-09-30T10:36:17 2023-09-30T10:36:35 0.525 \n", - "204288 2023-09-30T10:37:03 2023-09-30T10:36:35 2023-09-30T10:36:53 0.525 \n", - "\n", - " device \n", - "171442 <, name:iPhone, manufac... \n", - "171443 <, name:iPhone, manufac... \n", - "171444 <, name:iPhone, manufac... \n", - "171445 <, name:iPhone, manufac... \n", - "171446 <, name:iPhone, manufac... \n", - "... ... \n", - "204284 <, name:Apple Watch, ma... \n", - "204285 <, name:Apple Watch, ma... \n", - "204286 <, name:Apple Watch, ma... \n", - "204287 <, name:Apple Watch, ma... \n", - "204288 <, name:Apple Watch, ma... \n", - "\n", - "[32847 rows x 9 columns]" + "" ] }, - "execution_count": 4, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "energy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using dbdpy" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ + "import importlib\n", "from pathlib import Path\n", - "import dbdpy" + "import dbdpy\n", + "importlib.reload(dbdpy)" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "filepath = Path(\"./data/apple/export.xml\")\n", - "watch_data = dbdpy.read_file(filepath)" + "watch_data = dbdpy.AppleWatch.read_file(filepath)" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "array([nan])" ] }, - "execution_count": 6, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "watch_data" + "watch_data.sleep.value.unique()" ] }, { From 1a2eb888c5acf79a34820860cd4a6da7d4bb8140 Mon Sep 17 00:00:00 2001 From: bc299 Date: Fri, 5 Jan 2024 13:48:57 -0500 Subject: [PATCH 2/6] completed the base loading function for apple watch, moving on to Garmin --- dbdpy/apple_watch.py | 35 +++++++++++++++++++++++++++++++++++ dev-requirements.txt | 1 - 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/dbdpy/apple_watch.py b/dbdpy/apple_watch.py index 280f794d..b875a825 100644 --- a/dbdpy/apple_watch.py +++ b/dbdpy/apple_watch.py @@ -24,6 +24,41 @@ def __init__(self, @classmethod def read_file(cls, filepath: str, device_name: str="Apple Watch"): + """ + Reads health data from an XML file specific to an Apple Watch and initializes + an instance of the `AppleWatch` class with this data. + + This method parses the XML file to extract various health metrics such as + energy burned, step count, distance walked or run, oxygen saturation, and heart rate. + It then filters and formats the data before initializing an `AppleWatch` object with + the extracted information. + + Parameters + ---------- + filepath : str + The path to the XML file containing the Apple Watch health data. + device_name : str, optional + The name of the device as it appears in the data source, by default "Apple Watch". + + Returns + ------- + AppleWatch + An instance of the `AppleWatch` class, initialized with health data extracted + from the XML file. + + Notes + ----- + - The method assumes that the XML file is structured in a specific format compatible + with Apple Watch data. + - Health data is extracted based on predefined health metric types and may not include + all data present in the XML file. + - The device name is used to filter out data from sources other than the specified + Apple Watch. + + Examples + -------- + >>> apple_watch_data = AppleWatch.read_file("path/to/apple_watch_data.xml") + """ # TODO: Deidentify device name # TODO: Store device model information # Extract data from XML file and put into dataframe diff --git a/dev-requirements.txt b/dev-requirements.txt index 6b6c139a..23ce8dce 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,7 +2,6 @@ pytest pytest-pycodestyle pytest-black black - datetime pandas numpy From e301b9f4deb1e56f789f79505a44cfa9b717e5ac Mon Sep 17 00:00:00 2001 From: bc299 Date: Fri, 5 Jan 2024 14:03:15 -0500 Subject: [PATCH 3/6] re-strctured the workflow notebook. Also moved attributes from AppleWatch to the more general CommercialDevice class --- dbdpy/apple_watch.py | 16 +- dbdpy/commercial_device.py | 87 ++-------- ...e_example.ipynb => workflow_example.ipynb} | 153 ++++++++++++++++-- 3 files changed, 158 insertions(+), 98 deletions(-) rename notebooks/{apple_example.ipynb => workflow_example.ipynb} (62%) diff --git a/dbdpy/apple_watch.py b/dbdpy/apple_watch.py index b875a825..b4c0961f 100644 --- a/dbdpy/apple_watch.py +++ b/dbdpy/apple_watch.py @@ -7,20 +7,8 @@ class AppleWatch(CommercialDevice): - def __init__(self, - sleep=None, - energy=None, - steps=None, - distance=None, - oxygen=None, - heart_rate=None - ) -> None: - self.sleep = sleep - self.energy = energy - self.steps = steps - self.distance = distance - self.oxygen = oxygen - self.heart_rate = heart_rate + def __init__(self, **kwargs): + super().__init__(**kwargs) @classmethod def read_file(cls, filepath: str, device_name: str="Apple Watch"): diff --git a/dbdpy/commercial_device.py b/dbdpy/commercial_device.py index c3ee32b8..8f2a35ed 100644 --- a/dbdpy/commercial_device.py +++ b/dbdpy/commercial_device.py @@ -1,76 +1,15 @@ class CommercialDevice: - def __init__(self, brand): - self.brand = brand - - def get_device_info(self): - """Retrieve brand and model name of a device. - - Paramters - --------- - None - - Returns - ------- - device_info : str - """ - device_info = f"{self.brand}" - return device_info - - def get_heart_rate(self): - '''Get heart_rate dataframe - - Returns - ------- - heart_rate: pandas.DataFrame - Dataframe with columns for timestamp (datetime64) and heart_rate in bpm (int) - ''' - return self._heart_rate() + def __init__(self, + sleep=None, + energy=None, + steps=None, + distance=None, + oxygen=None, + heart_rate=None) -> None: + self.sleep = sleep + self.energy = energy + self.steps = steps + self.distance = distance + self.oxygen = oxygen + self.heart_rate = heart_rate - def get_active_calories(self): - '''Get active_calories dataframe - - Returns - ------- - active_calories: pandas.DataFrame - Dataframe with columns for start_time (datetime64), end_time (datetime64) and active calories in kilocalories (int) - ''' - return self._active_calories() - - def get_distance(self): - '''Get distance dataframe - - Returns - ------- - distance: pandas.DataFrame - Dataframe with columns for start_time (datetime64), end_time (datetime64) and distance in meters (int) - ''' - return self._distance() - - def get_spo2(self): - '''Get SpO2 dataframe - - Returns - ------- - spo2: pandas.DataFrame - Dataframe with columns for timestamp (datetime64) and SpO2 % (int) - ''' - return self._spo2() - - def get_steps(self): - '''Get steps dataframe - - Returns - ------- - steps: pandas.DataFrame - Dataframe with columns for start_time (datetime64), end_time (datetime64) and step count (int) - ''' - return self._steps() - - def get_sleep_stage_summary(self): - '''Get summary of sleep stages for the night of a day - - Returns - ------- - sleep_stage_summary: pandas.DataFrame - Dataframe with columns for date (datetime64), wake (seconds, int), light (seconds, int), deep (seconds, itn), REM (seconds, int) ''' - return self._sleep_stage_summary() \ No newline at end of file diff --git a/notebooks/apple_example.ipynb b/notebooks/workflow_example.ipynb similarity index 62% rename from notebooks/apple_example.ipynb rename to notebooks/workflow_example.ipynb index dcc291ef..138c3a06 100644 --- a/notebooks/apple_example.ipynb +++ b/notebooks/workflow_example.ipynb @@ -4,14 +4,30 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The purpose of this notebook is to demonstrate utilizing dbdpy to analyze data from Apple Watch. This will be completed two ways: once without dbdpy and once with the package. " + "# Workflow Examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Using Basic Python" + "The purpose of this notebook is to organize the logic of how data is loaded, processed, and explored using both vanilla Python and the dbdpy package. Additionally, this notebook should be used to test the functionalities of the package during development. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Loading\n", + "\n", + "This is the only section where each watch data will have their custom method for loading in the data. Once the data is formatted into the centralized data structure -- the rest of the workflow should be applied to the standardized format. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apple Watch" ] }, { @@ -195,6 +211,13 @@ "sleep = record_df[record_df[\"type\"] == \"SleepAnalysis\"]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Garmin" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -204,7 +227,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -213,7 +236,7 @@ "" ] }, - "execution_count": 46, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -222,37 +245,147 @@ "import importlib\n", "from pathlib import Path\n", "import dbdpy\n", + "from dbdpy import AppleWatch\n", "importlib.reload(dbdpy)" ] }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "filepath = Path(\"./data/apple/export.xml\")\n", - "watch_data = dbdpy.AppleWatch.read_file(filepath)" + "watch_data = AppleWatch.read_file(filepath)" ] }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 52, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
startDateendDatevalue
5259302022-12-28T11:58:042022-12-28T12:22:34NaN
5259322022-12-28T12:22:342022-12-28T12:36:34NaN
5259332022-12-28T12:36:342022-12-28T12:56:04NaN
5259352022-12-28T12:56:042022-12-28T13:12:04NaN
5259362022-12-28T13:12:042022-12-28T13:29:04NaN
............
5326232023-09-30T09:15:312023-09-30T09:19:31NaN
5326242023-09-30T09:15:312023-09-30T09:19:31NaN
5326252023-09-30T09:19:312023-09-30T09:21:31NaN
5326262023-09-30T09:21:312023-09-30T09:23:31NaN
5326272023-09-30T09:21:312023-09-30T09:23:31NaN
\n", + "

2869 rows × 3 columns

\n", + "
" + ], "text/plain": [ - "array([nan])" + " startDate endDate value\n", + "525930 2022-12-28T11:58:04 2022-12-28T12:22:34 NaN\n", + "525932 2022-12-28T12:22:34 2022-12-28T12:36:34 NaN\n", + "525933 2022-12-28T12:36:34 2022-12-28T12:56:04 NaN\n", + "525935 2022-12-28T12:56:04 2022-12-28T13:12:04 NaN\n", + "525936 2022-12-28T13:12:04 2022-12-28T13:29:04 NaN\n", + "... ... ... ...\n", + "532623 2023-09-30T09:15:31 2023-09-30T09:19:31 NaN\n", + "532624 2023-09-30T09:15:31 2023-09-30T09:19:31 NaN\n", + "532625 2023-09-30T09:19:31 2023-09-30T09:21:31 NaN\n", + "532626 2023-09-30T09:21:31 2023-09-30T09:23:31 NaN\n", + "532627 2023-09-30T09:21:31 2023-09-30T09:23:31 NaN\n", + "\n", + "[2869 rows x 3 columns]" ] }, - "execution_count": 48, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "watch_data.sleep.value.unique()" + "watch_data.sleep" ] }, { From 58ac0b52666f0017aaf07b84905dac1aa53daf9b Mon Sep 17 00:00:00 2001 From: bc299 Date: Fri, 5 Jan 2024 14:05:24 -0500 Subject: [PATCH 4/6] fixed formatting issues with black --- dbdpy/__init__.py | 2 +- dbdpy/apple_watch.py | 88 +++++++++------ dbdpy/commercial_device.py | 17 +-- dbdpy/garmin.py | 215 +++++++++++++++++++++---------------- 4 files changed, 191 insertions(+), 131 deletions(-) diff --git a/dbdpy/__init__.py b/dbdpy/__init__.py index 9739539b..5cab1354 100644 --- a/dbdpy/__init__.py +++ b/dbdpy/__init__.py @@ -1 +1 @@ -from .apple_watch import AppleWatch \ No newline at end of file +from .apple_watch import AppleWatch diff --git a/dbdpy/apple_watch.py b/dbdpy/apple_watch.py index b4c0961f..444e4ee7 100644 --- a/dbdpy/apple_watch.py +++ b/dbdpy/apple_watch.py @@ -9,16 +9,16 @@ class AppleWatch(CommercialDevice): def __init__(self, **kwargs): super().__init__(**kwargs) - + @classmethod - def read_file(cls, filepath: str, device_name: str="Apple Watch"): + def read_file(cls, filepath: str, device_name: str = "Apple Watch"): """ - Reads health data from an XML file specific to an Apple Watch and initializes + Reads health data from an XML file specific to an Apple Watch and initializes an instance of the `AppleWatch` class with this data. - This method parses the XML file to extract various health metrics such as - energy burned, step count, distance walked or run, oxygen saturation, and heart rate. - It then filters and formats the data before initializing an `AppleWatch` object with + This method parses the XML file to extract various health metrics such as + energy burned, step count, distance walked or run, oxygen saturation, and heart rate. + It then filters and formats the data before initializing an `AppleWatch` object with the extracted information. Parameters @@ -31,16 +31,16 @@ def read_file(cls, filepath: str, device_name: str="Apple Watch"): Returns ------- AppleWatch - An instance of the `AppleWatch` class, initialized with health data extracted + An instance of the `AppleWatch` class, initialized with health data extracted from the XML file. Notes ----- - - The method assumes that the XML file is structured in a specific format compatible + - The method assumes that the XML file is structured in a specific format compatible with Apple Watch data. - - Health data is extracted based on predefined health metric types and may not include + - Health data is extracted based on predefined health metric types and may not include all data present in the XML file. - - The device name is used to filter out data from sources other than the specified + - The device name is used to filter out data from sources other than the specified Apple Watch. Examples @@ -56,7 +56,9 @@ def read_file(cls, filepath: str, device_name: str="Apple Watch"): record_df = pd.DataFrame(record_list) # Only save the watch data and discard the iPhone data - record_df["sourceName"] = record_df["sourceName"].apply(lambda x: unicodedata.normalize("NFKC", x)) + record_df["sourceName"] = record_df["sourceName"].apply( + lambda x: unicodedata.normalize("NFKC", x) + ) record_df = record_df[record_df["sourceName"].str.contains(device_name)] # Drop columns that will not be used @@ -65,30 +67,54 @@ def read_file(cls, filepath: str, device_name: str="Apple Watch"): # Convert datetime to ISO 8601 format datetime_cols = ["startDate", "endDate"] - record_df[datetime_cols] = record_df[datetime_cols]\ - .apply(lambda x: pd.to_datetime(x).dt.strftime("%Y-%m-%dT%H:%M:%S")) - + record_df[datetime_cols] = record_df[datetime_cols].apply( + lambda x: pd.to_datetime(x).dt.strftime("%Y-%m-%dT%H:%M:%S") + ) + # Convert values to numeric type record_df["value"] = pd.to_numeric(record_df["value"], errors="coerce") - + # Shorten observation names - record_df["type"] = record_df["type"].str.replace("HKQuantityTypeIdentifier", "") - record_df["type"] = record_df["type"].str.replace("HKCategoryTypeIdentifier", "") + record_df["type"] = record_df["type"].str.replace( + "HKQuantityTypeIdentifier", "" + ) + record_df["type"] = record_df["type"].str.replace( + "HKCategoryTypeIdentifier", "" + ) # Extract data, convert to standard format, and populate attributes - energy = record_df[record_df["type"] == "BasalEnergyBurned"]\ - .drop(columns="type").rename(columns={"value": "active_calories"}) - steps = record_df[record_df["type"] == "StepCount"]\ - .drop(columns="type").rename(columns={"value": "steps"}) - distance = record_df[record_df["type"] == "DistanceWalkingRunning"]\ - .drop(columns="type").rename(columns={"value": "distance"}) - oxygen = record_df[record_df["type"] == "OxygenSaturation"]\ - .drop(columns="type").rename(columns={"value": "SpO2"}) - heart_rate = record_df[record_df["type"] == "HeartRate"]\ - .drop(columns="type").rename(columns={"value": "heart_rate"}) - sleep = record_df[record_df["type"] == "SleepAnalysis"]\ + energy = ( + record_df[record_df["type"] == "BasalEnergyBurned"] + .drop(columns="type") + .rename(columns={"value": "active_calories"}) + ) + steps = ( + record_df[record_df["type"] == "StepCount"] + .drop(columns="type") + .rename(columns={"value": "steps"}) + ) + distance = ( + record_df[record_df["type"] == "DistanceWalkingRunning"] + .drop(columns="type") + .rename(columns={"value": "distance"}) + ) + oxygen = ( + record_df[record_df["type"] == "OxygenSaturation"] + .drop(columns="type") + .rename(columns={"value": "SpO2"}) + ) + heart_rate = ( + record_df[record_df["type"] == "HeartRate"] .drop(columns="type") + .rename(columns={"value": "heart_rate"}) + ) + sleep = record_df[record_df["type"] == "SleepAnalysis"].drop(columns="type") - return cls(sleep=sleep, energy=energy, steps=steps, distance=distance, oxygen=oxygen, - heart_rate=heart_rate) - \ No newline at end of file + return cls( + sleep=sleep, + energy=energy, + steps=steps, + distance=distance, + oxygen=oxygen, + heart_rate=heart_rate, + ) diff --git a/dbdpy/commercial_device.py b/dbdpy/commercial_device.py index 8f2a35ed..912bba9b 100644 --- a/dbdpy/commercial_device.py +++ b/dbdpy/commercial_device.py @@ -1,15 +1,16 @@ class CommercialDevice: - def __init__(self, - sleep=None, - energy=None, - steps=None, - distance=None, - oxygen=None, - heart_rate=None) -> None: + def __init__( + self, + sleep=None, + energy=None, + steps=None, + distance=None, + oxygen=None, + heart_rate=None, + ) -> None: self.sleep = sleep self.energy = energy self.steps = steps self.distance = distance self.oxygen = oxygen self.heart_rate = heart_rate - diff --git a/dbdpy/garmin.py b/dbdpy/garmin.py index 4a949681..36edc5ae 100644 --- a/dbdpy/garmin.py +++ b/dbdpy/garmin.py @@ -3,48 +3,53 @@ import matplotlib.pyplot as plt from garmin_fit_sdk import Decoder, Stream, Profile import datetime + # from device import CommercialDevice + # class garmin(CommercialDevice): -class garmin(): +class garmin: def __init__(self): # super().__init__('garmin') self.messages = None # helper functions def convert_time(self, df): - df['timestamp'] = [datetime.datetime.utcfromtimestamp(631065600 + df['timestamp'][i]) - datetime.timedelta(hours=4) - for i in range(len(df['timestamp']))] + df["timestamp"] = [ + datetime.datetime.utcfromtimestamp(631065600 + df["timestamp"][i]) + - datetime.timedelta(hours=4) + for i in range(len(df["timestamp"])) + ] return df - + def get_timestamp(self, df): - for i in range(len(df)-1): - if df.iloc[i,0].astype(str) == 'nan': - timestamp_16 = df['timestamp_16'][i] - df.iloc[i,0] = df.iloc[(i-1),0] + for i in range(len(df) - 1): + if df.iloc[i, 0].astype(str) == "nan": + timestamp_16 = df["timestamp_16"][i] + df.iloc[i, 0] = df.iloc[(i - 1), 0] for i in range(len(df)): - mesgTimestamp = int(df['timestamp'][i]) - try: - timestamp_16 = int(df['timestamp_16'][i]) - duration = ( timestamp_16 - ( mesgTimestamp & 0xFFFF ) ) & 0xFFFF + mesgTimestamp = int(df["timestamp"][i]) + try: + timestamp_16 = int(df["timestamp_16"][i]) + duration = (timestamp_16 - (mesgTimestamp & 0xFFFF)) & 0xFFFF except ValueError: continue mesgTimestamp += duration - df.iloc[i,0] = mesgTimestamp + df.iloc[i, 0] = mesgTimestamp return df - + @classmethod def from_directory(cls, filepath): newGarmin = cls() - file_type = filepath.split('.')[-1] - if file_type == 'fit': + file_type = filepath.split(".")[-1] + if file_type == "fit": data = newGarmin.read_fit(filepath) else: data = newGarmin.read_sleepData(filepath) newobject = cls(data) return newobject - + # read wellness file def read_fit(self, path): """ @@ -55,17 +60,19 @@ def read_fit(self, path): """ stream = Stream.from_file(path) decoder = Decoder(stream) - messages, errors = decoder.read(apply_scale_and_offset=True, - convert_datetimes_to_dates=False, - convert_types_to_strings=True, - enable_crc_check=True, - expand_sub_fields=True, - expand_components=True, - merge_heart_rates=False, - mesg_listener=None) - + messages, errors = decoder.read( + apply_scale_and_offset=True, + convert_datetimes_to_dates=False, + convert_types_to_strings=True, + enable_crc_check=True, + expand_sub_fields=True, + expand_components=True, + merge_heart_rates=False, + mesg_listener=None, + ) + self.messages = messages - + # read sleep data json file def read_sleepData(self, path): """ @@ -75,116 +82,142 @@ def read_sleepData(self, path): file (str): The path to the json file to be read. """ sleepData = pd.read_json(path) - sleepData['sleepStartTimestampGMT'] = pd.to_datetime(sleepData['sleepStartTimestampGMT']) - sleepData['sleepStartTimestampGMT'] = sleepData['sleepStartTimestampGMT'] - datetime.timedelta(hours=4) - sleepData['sleepEndTimestampGMT'] = pd.to_datetime(sleepData['sleepEndTimestampGMT']) - sleepData['sleepEndTimestampGMT'] = sleepData['sleepEndTimestampGMT'] - datetime.timedelta(hours=4) - sleepData['calendarDate'] = pd.to_datetime(sleepData['calendarDate']) - sleepData.drop(sleepData[sleepData['sleepWindowConfirmationType'] == 'UNCONFIRMED'].index, inplace = True) + sleepData["sleepStartTimestampGMT"] = pd.to_datetime( + sleepData["sleepStartTimestampGMT"] + ) + sleepData["sleepStartTimestampGMT"] = sleepData[ + "sleepStartTimestampGMT" + ] - datetime.timedelta(hours=4) + sleepData["sleepEndTimestampGMT"] = pd.to_datetime( + sleepData["sleepEndTimestampGMT"] + ) + sleepData["sleepEndTimestampGMT"] = sleepData[ + "sleepEndTimestampGMT" + ] - datetime.timedelta(hours=4) + sleepData["calendarDate"] = pd.to_datetime(sleepData["calendarDate"]) + sleepData.drop( + sleepData[sleepData["sleepWindowConfirmationType"] == "UNCONFIRMED"].index, + inplace=True, + ) self.sleepData = sleepData - + # get sleep stage information def get_sleepstage(self): - sleepStage = self.sleepData[['calendarDate', 'deepSleepSeconds', 'lightSleepSeconds', 'remSleepSeconds', 'awakeSleepSeconds']] + sleepStage = self.sleepData[ + [ + "calendarDate", + "deepSleepSeconds", + "lightSleepSeconds", + "remSleepSeconds", + "awakeSleepSeconds", + ] + ] return sleepStage - + # get raw wellness data def get_raw_data(self): - raw_data = pd.DataFrame(self.messages['monitoring_mesgs']) + raw_data = pd.DataFrame(self.messages["monitoring_mesgs"]) raw_data = self.get_timestamp(raw_data) raw_data = self.convert_time(raw_data) return raw_data - + def get_stress_level(self): - stress = pd.DataFrame(self.messages['stress_level_mesgs']) - stress['stress_level_time'] = [datetime.datetime.utcfromtimestamp(631065600 + stress['stress_level_time'][i]) - datetime.timedelta(hours=4) - for i in range(len(stress['stress_level_time']))] + stress = pd.DataFrame(self.messages["stress_level_mesgs"]) + stress["stress_level_time"] = [ + datetime.datetime.utcfromtimestamp( + 631065600 + stress["stress_level_time"][i] + ) + - datetime.timedelta(hours=4) + for i in range(len(stress["stress_level_time"])) + ] return stress - + def get_SpO2(self): - SpO2 = pd.DataFrame(self.messages['spo2_data_mesgs']) + SpO2 = pd.DataFrame(self.messages["spo2_data_mesgs"]) SpO2 = self.convert_time(SpO2) return SpO2 - + def get_floor(self): raw_data = self.get_raw_data() - floor = raw_data[['timestamp', 'ascent', 'descent']] - floor.iloc[0,1:] = 0 - for i in range(len(floor)-1): - if str(floor['ascent'][i+1]) == 'nan': - floor.iloc[i+1,1] = floor.iloc[i,1] + floor = raw_data[["timestamp", "ascent", "descent"]] + floor.iloc[0, 1:] = 0 + for i in range(len(floor) - 1): + if str(floor["ascent"][i + 1]) == "nan": + floor.iloc[i + 1, 1] = floor.iloc[i, 1] else: - floor.iloc[i+1,1] += floor.iloc[i,1] + floor.iloc[i + 1, 1] += floor.iloc[i, 1] - - if str(floor['descent'][i+1]) == 'nan': - floor.iloc[i+1,2] = floor.iloc[i,2] + if str(floor["descent"][i + 1]) == "nan": + floor.iloc[i + 1, 2] = floor.iloc[i, 2] else: - floor.iloc[i+1,2] += floor.iloc[i,2] - + floor.iloc[i + 1, 2] += floor.iloc[i, 2] + duplicate_rows = floor[floor.duplicated()] - floor_no_duplicates = floor.drop_duplicates(keep='first') + floor_no_duplicates = floor.drop_duplicates(keep="first") return floor_no_duplicates - + def get_distance(self): raw_data = self.get_raw_data() - distance = raw_data.iloc[:-5,:] - distance = distance[['timestamp', 'distance']] - distance.iloc[0,1] = 0 - for i in range(len(distance)-1): + distance = raw_data.iloc[:-5, :] + distance = distance[["timestamp", "distance"]] + distance.iloc[0, 1] = 0 + for i in range(len(distance) - 1): i = i + 1 - if str(distance['distance'][i]) == 'nan': - if str(distance['distance'][i-1]) != 'nan': - distance.iloc[i,1] = distance['distance'][i-1] - - if distance.iloc[i,1] < distance['distance'][i-1]: - distance.iloc[i,1] = distance['distance'][i-1] + if str(distance["distance"][i]) == "nan": + if str(distance["distance"][i - 1]) != "nan": + distance.iloc[i, 1] = distance["distance"][i - 1] + + if distance.iloc[i, 1] < distance["distance"][i - 1]: + distance.iloc[i, 1] = distance["distance"][i - 1] duplicate_rows = distance[distance.duplicated()] - distance_no_duplicates = distance.drop_duplicates(keep='first') - + distance_no_duplicates = distance.drop_duplicates(keep="first") + return distance_no_duplicates def get_hr(self): raw_data = self.get_raw_data() - hr_df = raw_data[~raw_data['heart_rate'].isna()].reset_index(drop=True) - hr_df = hr_df[['timestamp', 'heart_rate']] - hr_df['heart_rate'] = hr_df['heart_rate'].astype(int) + hr_df = raw_data[~raw_data["heart_rate"].isna()].reset_index(drop=True) + hr_df = hr_df[["timestamp", "heart_rate"]] + hr_df["heart_rate"] = hr_df["heart_rate"].astype(int) return hr_df def get_intensity(self): raw_data = self.get_raw_data() - intensity = raw_data[~raw_data['intensity'].isna()].reset_index(drop=True) - intensity = intensity[['timestamp', 'intensity']] + intensity = raw_data[~raw_data["intensity"].isna()].reset_index(drop=True) + intensity = intensity[["timestamp", "intensity"]] return intensity def get_calories(self): raw_data = self.get_raw_data() - calories = raw_data.iloc[:-5,:] - calories = calories[['timestamp', 'active_calories']] - for i in range(len(calories)-1): - if str(calories['active_calories'][i+1]) == 'nan' or calories['active_calories'][i+1] < calories['active_calories'][i]: - calories.iloc[i+1,1] = calories.iloc[i,1] - + calories = raw_data.iloc[:-5, :] + calories = calories[["timestamp", "active_calories"]] + for i in range(len(calories) - 1): + if ( + str(calories["active_calories"][i + 1]) == "nan" + or calories["active_calories"][i + 1] < calories["active_calories"][i] + ): + calories.iloc[i + 1, 1] = calories.iloc[i, 1] + duplicate_rows = calories[calories.duplicated()] - calories_no_duplicates = calories.drop_duplicates(keep='first') + calories_no_duplicates = calories.drop_duplicates(keep="first") return calories_no_duplicates - + def get_sleep_time(self): - sleep = pd.DataFrame(self.messages['sleep_level_mesgs']) + sleep = pd.DataFrame(self.messages["sleep_level_mesgs"]) sleep = self.convert_time(sleep) - for i in range(len(sleep['timestamp']) - 1): - time_difference = sleep['timestamp'][i + 1] - sleep['timestamp'][i] + for i in range(len(sleep["timestamp"]) - 1): + time_difference = sleep["timestamp"][i + 1] - sleep["timestamp"][i] if time_difference.seconds // 3600 > 1: - sleep_time = sleep['timestamp'][i] - wake_time = sleep['timestamp'][i + 1] - + sleep_time = sleep["timestamp"][i] + wake_time = sleep["timestamp"][i + 1] + return sleep_time, wake_time - + def get_rhr(self): - rhr_df = pd.DataFrame(self.messages['monitoring_hr_data_mesgs']) - rhr = rhr_df['resting_heart_rate'][0] # current_day_resting_heart_rate + rhr_df = pd.DataFrame(self.messages["monitoring_hr_data_mesgs"]) + rhr = rhr_df["resting_heart_rate"][0] # current_day_resting_heart_rate return rhr From 6f3139586ba432c645eef6a671d8163435666749 Mon Sep 17 00:00:00 2001 From: bc299 Date: Fri, 5 Jan 2024 14:15:09 -0500 Subject: [PATCH 5/6] setup max line configuration for pycodestyle --- dbdpy/apple_watch.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/dbdpy/apple_watch.py b/dbdpy/apple_watch.py index 444e4ee7..75db95b3 100644 --- a/dbdpy/apple_watch.py +++ b/dbdpy/apple_watch.py @@ -13,35 +13,37 @@ def __init__(self, **kwargs): @classmethod def read_file(cls, filepath: str, device_name: str = "Apple Watch"): """ - Reads health data from an XML file specific to an Apple Watch and initializes - an instance of the `AppleWatch` class with this data. + Reads health data from an XML file specific to an Apple Watch and + initializes an instance of the `AppleWatch` class with this data. - This method parses the XML file to extract various health metrics such as - energy burned, step count, distance walked or run, oxygen saturation, and heart rate. - It then filters and formats the data before initializing an `AppleWatch` object with - the extracted information. + This method parses the XML file to extract various health metrics + such as energy burned, step count, distance walked or run, oxygen + saturation, and heart rate. It then filters and formats the data + before initializing an `AppleWatch` object with the extracted + information. Parameters ---------- filepath : str The path to the XML file containing the Apple Watch health data. device_name : str, optional - The name of the device as it appears in the data source, by default "Apple Watch". + The name of the device as it appears in the data source, + by default "Apple Watch". Returns ------- AppleWatch - An instance of the `AppleWatch` class, initialized with health data extracted - from the XML file. + An instance of the `AppleWatch` class, initialized with health + data extracted from the XML file. Notes ----- - - The method assumes that the XML file is structured in a specific format compatible - with Apple Watch data. - - Health data is extracted based on predefined health metric types and may not include - all data present in the XML file. - - The device name is used to filter out data from sources other than the specified - Apple Watch. + - The method assumes that the XML file is structured in + a specific format compatible with Apple Watch data. + - Health data is extracted based on predefined health metric + types and may not include all data present in the XML file. + - The device name is used to filter out data from sources + other than the specified Apple Watch. Examples -------- From b0cbdec5f16888e84f817320c120d6ff00f33d42 Mon Sep 17 00:00:00 2001 From: bc299 Date: Fri, 5 Jan 2024 14:17:01 -0500 Subject: [PATCH 6/6] added setup.cfg file, tried to fix github actions --- .github/workflows/pytest_runner.yml | 2 +- dbdpy-env/bin/black | 8 + dbdpy-env/bin/blackd | 8 + dbdpy-env/bin/fonttools | 8 + dbdpy-env/bin/py.test | 8 + dbdpy-env/bin/pycodestyle | 8 + dbdpy-env/bin/pyftmerge | 8 + dbdpy-env/bin/pyftsubset | 8 + dbdpy-env/bin/pytest | 8 + dbdpy-env/bin/ttx | 8 + ...fdff261ed89b74__mypyc.cpython-39-darwin.so | Bin 0 -> 3757901 bytes .../DateTime-5.4.dist-info/INSTALLER | 1 + .../DateTime-5.4.dist-info/LICENSE.txt | 44 + .../DateTime-5.4.dist-info/METADATA | 1159 + .../DateTime-5.4.dist-info/RECORD | 22 + .../DateTime-5.4.dist-info/REQUESTED | 0 .../DateTime-5.4.dist-info/WHEEL | 5 + .../DateTime-5.4.dist-info/top_level.txt | 1 + .../site-packages/DateTime/DateTime.py | 1946 + .../site-packages/DateTime/DateTime.txt | 785 + .../site-packages/DateTime/__init__.py | 18 + .../site-packages/DateTime/interfaces.py | 375 + .../python3.9/site-packages/DateTime/pytz.txt | 192 + .../site-packages/DateTime/pytz_support.py | 269 + .../site-packages/DateTime/tests/__init__.py | 15 + .../DateTime/tests/julian_testdata.txt | 57 + .../DateTime/tests/test_datetime.py | 746 + .../PIL/.dylibs/libXau.6.0.0.dylib | Bin 0 -> 70048 bytes .../PIL/.dylibs/libbrotlicommon.1.1.0.dylib | Bin 0 -> 201200 bytes .../PIL/.dylibs/libbrotlidec.1.1.0.dylib | Bin 0 -> 104544 bytes .../PIL/.dylibs/libfreetype.6.dylib | Bin 0 -> 1142208 bytes .../PIL/.dylibs/libharfbuzz.0.dylib | Bin 0 -> 4348768 bytes .../PIL/.dylibs/libjpeg.62.4.0.dylib | Bin 0 -> 573248 bytes .../PIL/.dylibs/liblcms2.2.dylib | Bin 0 -> 523584 bytes .../site-packages/PIL/.dylibs/liblzma.5.dylib | Bin 0 -> 323280 bytes .../PIL/.dylibs/libopenjp2.2.5.0.dylib | Bin 0 -> 665760 bytes .../PIL/.dylibs/libpng16.16.dylib | Bin 0 -> 344928 bytes .../PIL/.dylibs/libsharpyuv.0.dylib | Bin 0 -> 69408 bytes .../site-packages/PIL/.dylibs/libtiff.6.dylib | Bin 0 -> 751472 bytes .../site-packages/PIL/.dylibs/libwebp.7.dylib | Bin 0 -> 514272 bytes .../PIL/.dylibs/libwebpdemux.2.dylib | Bin 0 -> 69872 bytes .../PIL/.dylibs/libwebpmux.3.dylib | Bin 0 -> 105920 bytes .../PIL/.dylibs/libxcb.1.1.0.dylib | Bin 0 -> 277696 bytes .../site-packages/PIL/.dylibs/libz.1.3.dylib | Bin 0 -> 174784 bytes .../site-packages/PIL/BdfFontFile.py | 133 + .../site-packages/PIL/BlpImagePlugin.py | 475 + .../site-packages/PIL/BmpImagePlugin.py | 471 + .../site-packages/PIL/BufrStubImagePlugin.py | 74 + .../site-packages/PIL/ContainerIO.py | 121 + .../site-packages/PIL/CurImagePlugin.py | 75 + .../site-packages/PIL/DcxImagePlugin.py | 80 + .../site-packages/PIL/DdsImagePlugin.py | 566 + .../site-packages/PIL/EpsImagePlugin.py | 478 + .../python3.9/site-packages/PIL/ExifTags.py | 381 + .../site-packages/PIL/FitsImagePlugin.py | 72 + .../site-packages/PIL/FliImagePlugin.py | 173 + .../python3.9/site-packages/PIL/FontFile.py | 136 + .../site-packages/PIL/FpxImagePlugin.py | 255 + .../site-packages/PIL/FtexImagePlugin.py | 114 + .../site-packages/PIL/GbrImagePlugin.py | 103 + .../site-packages/PIL/GdImageFile.py | 97 + .../site-packages/PIL/GifImagePlugin.py | 1097 + .../site-packages/PIL/GimpGradientFile.py | 137 + .../site-packages/PIL/GimpPaletteFile.py | 57 + .../site-packages/PIL/GribStubImagePlugin.py | 74 + .../site-packages/PIL/Hdf5StubImagePlugin.py | 74 + .../site-packages/PIL/IcnsImagePlugin.py | 400 + .../site-packages/PIL/IcoImagePlugin.py | 356 + .../site-packages/PIL/ImImagePlugin.py | 371 + .../lib/python3.9/site-packages/PIL/Image.py | 3944 ++ .../python3.9/site-packages/PIL/ImageChops.py | 311 + .../python3.9/site-packages/PIL/ImageCms.py | 1007 + .../python3.9/site-packages/PIL/ImageColor.py | 317 + .../python3.9/site-packages/PIL/ImageDraw.py | 1065 + .../python3.9/site-packages/PIL/ImageDraw2.py | 193 + .../site-packages/PIL/ImageEnhance.py | 104 + .../python3.9/site-packages/PIL/ImageFile.py | 795 + .../site-packages/PIL/ImageFilter.py | 568 + .../python3.9/site-packages/PIL/ImageFont.py | 1264 + .../python3.9/site-packages/PIL/ImageGrab.py | 178 + .../python3.9/site-packages/PIL/ImageMath.py | 265 + .../python3.9/site-packages/PIL/ImageMode.py | 96 + .../python3.9/site-packages/PIL/ImageMorph.py | 255 + .../python3.9/site-packages/PIL/ImageOps.py | 655 + .../site-packages/PIL/ImagePalette.py | 262 + .../python3.9/site-packages/PIL/ImagePath.py | 20 + .../python3.9/site-packages/PIL/ImageQt.py | 197 + .../site-packages/PIL/ImageSequence.py | 86 + .../python3.9/site-packages/PIL/ImageShow.py | 326 + .../python3.9/site-packages/PIL/ImageStat.py | 129 + .../python3.9/site-packages/PIL/ImageTk.py | 284 + .../site-packages/PIL/ImageTransform.py | 112 + .../python3.9/site-packages/PIL/ImageWin.py | 231 + .../site-packages/PIL/ImtImagePlugin.py | 101 + .../site-packages/PIL/IptcImagePlugin.py | 235 + .../site-packages/PIL/Jpeg2KImagePlugin.py | 398 + .../site-packages/PIL/JpegImagePlugin.py | 868 + .../site-packages/PIL/JpegPresets.py | 241 + .../site-packages/PIL/McIdasImagePlugin.py | 76 + .../site-packages/PIL/MicImagePlugin.py | 107 + .../site-packages/PIL/MpegImagePlugin.py | 82 + .../site-packages/PIL/MpoImagePlugin.py | 195 + .../site-packages/PIL/MspImagePlugin.py | 195 + .../lib/python3.9/site-packages/PIL/PSDraw.py | 230 + .../site-packages/PIL/PaletteFile.py | 52 + .../site-packages/PIL/PalmImagePlugin.py | 226 + .../site-packages/PIL/PcdImagePlugin.py | 62 + .../site-packages/PIL/PcfFontFile.py | 254 + .../site-packages/PIL/PcxImagePlugin.py | 222 + .../site-packages/PIL/PdfImagePlugin.py | 303 + .../python3.9/site-packages/PIL/PdfParser.py | 998 + .../site-packages/PIL/PixarImagePlugin.py | 70 + .../site-packages/PIL/PngImagePlugin.py | 1460 + .../site-packages/PIL/PpmImagePlugin.py | 344 + .../site-packages/PIL/PsdImagePlugin.py | 307 + .../python3.9/site-packages/PIL/PyAccess.py | 364 + .../site-packages/PIL/QoiImagePlugin.py | 106 + .../site-packages/PIL/SgiImagePlugin.py | 231 + .../site-packages/PIL/SpiderImagePlugin.py | 318 + .../site-packages/PIL/SunImagePlugin.py | 139 + .../lib/python3.9/site-packages/PIL/TarIO.py | 73 + .../site-packages/PIL/TgaImagePlugin.py | 255 + .../site-packages/PIL/TiffImagePlugin.py | 2159 + .../python3.9/site-packages/PIL/TiffTags.py | 545 + .../site-packages/PIL/WalImageFile.py | 124 + .../site-packages/PIL/WebPImagePlugin.py | 366 + .../site-packages/PIL/WmfImagePlugin.py | 179 + .../site-packages/PIL/XVThumbImagePlugin.py | 79 + .../site-packages/PIL/XbmImagePlugin.py | 95 + .../site-packages/PIL/XpmImagePlugin.py | 128 + .../python3.9/site-packages/PIL/__init__.py | 85 + .../python3.9/site-packages/PIL/__main__.py | 5 + .../python3.9/site-packages/PIL/_binary.py | 102 + .../python3.9/site-packages/PIL/_deprecate.py | 71 + .../PIL/_imaging.cpython-39-darwin.so | Bin 0 -> 560624 bytes .../PIL/_imagingcms.cpython-39-darwin.so | Bin 0 -> 99424 bytes .../site-packages/PIL/_imagingcms.pyi | 5 + .../PIL/_imagingft.cpython-39-darwin.so | Bin 0 -> 117776 bytes .../site-packages/PIL/_imagingft.pyi | 5 + .../PIL/_imagingmath.cpython-39-darwin.so | Bin 0 -> 72222 bytes .../PIL/_imagingmorph.cpython-39-darwin.so | Bin 0 -> 51327 bytes .../PIL/_imagingtk.cpython-39-darwin.so | Bin 0 -> 52636 bytes .../site-packages/PIL/_tkinter_finder.py | 19 + .../python3.9/site-packages/PIL/_typing.py | 18 + .../lib/python3.9/site-packages/PIL/_util.py | 32 + .../python3.9/site-packages/PIL/_version.py | 4 + .../PIL/_webp.cpython-39-darwin.so | Bin 0 -> 76864 bytes .../python3.9/site-packages/PIL/features.py | 331 + .../python3.9/site-packages/_black_version.py | 1 + .../site-packages/_pytest/__init__.py | 9 + .../site-packages/_pytest/_argcomplete.py | 116 + .../site-packages/_pytest/_code/__init__.py | 22 + .../site-packages/_pytest/_code/code.py | 1337 + .../site-packages/_pytest/_code/source.py | 217 + .../site-packages/_pytest/_io/__init__.py | 8 + .../site-packages/_pytest/_io/saferepr.py | 180 + .../_pytest/_io/terminalwriter.py | 233 + .../site-packages/_pytest/_io/wcwidth.py | 55 + .../site-packages/_pytest/_py/__init__.py | 0 .../site-packages/_pytest/_py/error.py | 109 + .../site-packages/_pytest/_py/path.py | 1475 + .../site-packages/_pytest/_version.py | 16 + .../_pytest/assertion/__init__.py | 181 + .../_pytest/assertion/rewrite.py | 1217 + .../_pytest/assertion/truncate.py | 115 + .../site-packages/_pytest/assertion/util.py | 522 + .../site-packages/_pytest/cacheprovider.py | 602 + .../site-packages/_pytest/capture.py | 1082 + .../python3.9/site-packages/_pytest/compat.py | 435 + .../site-packages/_pytest/config/__init__.py | 1816 + .../_pytest/config/argparsing.py | 551 + .../site-packages/_pytest/config/compat.py | 70 + .../_pytest/config/exceptions.py | 11 + .../site-packages/_pytest/config/findpaths.py | 218 + .../site-packages/_pytest/debugging.py | 391 + .../site-packages/_pytest/deprecated.py | 146 + .../site-packages/_pytest/doctest.py | 771 + .../site-packages/_pytest/faulthandler.py | 102 + .../site-packages/_pytest/fixtures.py | 1713 + .../site-packages/_pytest/freeze_support.py | 44 + .../site-packages/_pytest/helpconfig.py | 270 + .../site-packages/_pytest/hookspec.py | 979 + .../site-packages/_pytest/junitxml.py | 700 + .../site-packages/_pytest/legacypath.py | 479 + .../site-packages/_pytest/logging.py | 920 + .../python3.9/site-packages/_pytest/main.py | 913 + .../site-packages/_pytest/mark/__init__.py | 269 + .../site-packages/_pytest/mark/expression.py | 228 + .../site-packages/_pytest/mark/structures.py | 618 + .../site-packages/_pytest/monkeypatch.py | 421 + .../python3.9/site-packages/_pytest/nodes.py | 783 + .../python3.9/site-packages/_pytest/nose.py | 50 + .../site-packages/_pytest/outcomes.py | 311 + .../site-packages/_pytest/pastebin.py | 110 + .../site-packages/_pytest/pathlib.py | 804 + .../python3.9/site-packages/_pytest/py.typed | 0 .../site-packages/_pytest/pytester.py | 1789 + .../_pytest/pytester_assertions.py | 75 + .../python3.9/site-packages/_pytest/python.py | 1843 + .../site-packages/_pytest/python_api.py | 996 + .../site-packages/_pytest/python_path.py | 24 + .../site-packages/_pytest/recwarn.py | 313 + .../site-packages/_pytest/reports.py | 622 + .../python3.9/site-packages/_pytest/runner.py | 551 + .../python3.9/site-packages/_pytest/scope.py | 91 + .../site-packages/_pytest/setuponly.py | 97 + .../site-packages/_pytest/setupplan.py | 40 + .../site-packages/_pytest/skipping.py | 297 + .../python3.9/site-packages/_pytest/stash.py | 112 + .../site-packages/_pytest/stepwise.py | 130 + .../site-packages/_pytest/terminal.py | 1481 + .../site-packages/_pytest/threadexception.py | 88 + .../python3.9/site-packages/_pytest/timing.py | 12 + .../python3.9/site-packages/_pytest/tmpdir.py | 324 + .../site-packages/_pytest/unittest.py | 421 + .../_pytest/unraisableexception.py | 93 + .../site-packages/_pytest/warning_types.py | 170 + .../site-packages/_pytest/warnings.py | 148 + .../black-23.12.1.dist-info/INSTALLER | 1 + .../black-23.12.1.dist-info/METADATA | 1871 + .../black-23.12.1.dist-info/RECORD | 121 + .../black-23.12.1.dist-info/REQUESTED | 0 .../black-23.12.1.dist-info/WHEEL | 4 + .../black-23.12.1.dist-info/entry_points.txt | 3 + .../licenses/AUTHORS.md | 196 + .../black-23.12.1.dist-info/licenses/LICENSE | 21 + .../black/__init__.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../python3.9/site-packages/black/__init__.py | 1545 + .../python3.9/site-packages/black/__main__.py | 3 + .../black/_width_table.cpython-39-darwin.so | Bin 0 -> 50142 bytes .../site-packages/black/_width_table.py | 478 + .../black/brackets.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../python3.9/site-packages/black/brackets.py | 382 + .../black/cache.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/cache.py | 143 + .../black/comments.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../python3.9/site-packages/black/comments.py | 412 + .../site-packages/black/concurrency.py | 190 + .../black/const.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/const.py | 4 + .../python3.9/site-packages/black/debug.py | 54 + .../python3.9/site-packages/black/files.py | 411 + .../handle_ipynb_magics.cpython-39-darwin.so | Bin 0 -> 50165 bytes .../black/handle_ipynb_magics.py | 452 + .../black/linegen.cpython-39-darwin.so | Bin 0 -> 50137 bytes .../python3.9/site-packages/black/linegen.py | 1738 + .../black/lines.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/lines.py | 1118 + .../black/mode.cpython-39-darwin.so | Bin 0 -> 50118 bytes .../lib/python3.9/site-packages/black/mode.py | 257 + .../black/nodes.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/nodes.py | 982 + .../black/numerics.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../python3.9/site-packages/black/numerics.py | 61 + .../python3.9/site-packages/black/output.py | 122 + .../black/parsing.cpython-39-darwin.so | Bin 0 -> 50137 bytes .../python3.9/site-packages/black/parsing.py | 216 + .../python3.9/site-packages/black/py.typed | 0 .../black/ranges.cpython-39-darwin.so | Bin 0 -> 50136 bytes .../python3.9/site-packages/black/ranges.py | 496 + .../python3.9/site-packages/black/report.py | 107 + .../black/rusty.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/rusty.py | 28 + .../black/strings.cpython-39-darwin.so | Bin 0 -> 50137 bytes .../python3.9/site-packages/black/strings.py | 329 + .../black/trans.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../python3.9/site-packages/black/trans.py | 2449 + .../site-packages/blackd/__init__.py | 233 + .../site-packages/blackd/__main__.py | 3 + .../site-packages/blackd/middlewares.py | 45 + .../site-packages/blib2to3/Grammar.txt | 256 + .../python3.9/site-packages/blib2to3/LICENSE | 254 + .../site-packages/blib2to3/PatternGrammar.txt | 28 + .../python3.9/site-packages/blib2to3/README | 24 + .../site-packages/blib2to3/__init__.py | 1 + .../site-packages/blib2to3/pgen2/__init__.py | 4 + .../blib2to3/pgen2/conv.cpython-39-darwin.so | Bin 0 -> 50118 bytes .../site-packages/blib2to3/pgen2/conv.py | 256 + .../pgen2/driver.cpython-39-darwin.so | Bin 0 -> 50136 bytes .../site-packages/blib2to3/pgen2/driver.py | 316 + .../pgen2/grammar.cpython-39-darwin.so | Bin 0 -> 50137 bytes .../site-packages/blib2to3/pgen2/grammar.py | 227 + .../pgen2/literals.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../site-packages/blib2to3/pgen2/literals.py | 66 + .../blib2to3/pgen2/parse.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../site-packages/blib2to3/pgen2/parse.py | 411 + .../blib2to3/pgen2/pgen.cpython-39-darwin.so | Bin 0 -> 50118 bytes .../site-packages/blib2to3/pgen2/pgen.py | 428 + .../blib2to3/pgen2/token.cpython-39-darwin.so | Bin 0 -> 50135 bytes .../site-packages/blib2to3/pgen2/token.py | 88 + .../pgen2/tokenize.cpython-39-darwin.so | Bin 0 -> 50138 bytes .../site-packages/blib2to3/pgen2/tokenize.py | 698 + .../blib2to3/pygram.cpython-39-darwin.so | Bin 0 -> 50136 bytes .../site-packages/blib2to3/pygram.py | 200 + .../blib2to3/pytree.cpython-39-darwin.so | Bin 0 -> 50136 bytes .../site-packages/blib2to3/pytree.py | 983 + .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 39 + .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .../python3.9/site-packages/click/__init__.py | 73 + .../python3.9/site-packages/click/_compat.py | 623 + .../site-packages/click/_termui_impl.py | 739 + .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../lib/python3.9/site-packages/click/core.py | 3042 ++ .../site-packages/click/decorators.py | 561 + .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.9/site-packages/click/globals.py | 68 + .../python3.9/site-packages/click/parser.py | 529 + .../python3.9/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 + .../python3.9/site-packages/click/termui.py | 784 + .../python3.9/site-packages/click/testing.py | 479 + .../python3.9/site-packages/click/types.py | 1089 + .../python3.9/site-packages/click/utils.py | 624 + .../contourpy-1.2.0.dist-info/INSTALLER | 1 + .../contourpy-1.2.0.dist-info/LICENSE | 29 + .../contourpy-1.2.0.dist-info/METADATA | 91 + .../contourpy-1.2.0.dist-info/RECORD | 42 + .../contourpy-1.2.0.dist-info/WHEEL | 4 + .../site-packages/contourpy/__init__.py | 262 + .../contourpy/_contourpy.cpython-39-darwin.so | Bin 0 -> 707980 bytes .../site-packages/contourpy/_contourpy.pyi | 202 + .../site-packages/contourpy/_version.py | 1 + .../site-packages/contourpy/array.py | 261 + .../site-packages/contourpy/chunk.py | 95 + .../site-packages/contourpy/convert.py | 555 + .../site-packages/contourpy/dechunk.py | 142 + .../site-packages/contourpy/enum_util.py | 57 + .../site-packages/contourpy/py.typed | 0 .../site-packages/contourpy/typecheck.py | 203 + .../site-packages/contourpy/types.py | 13 + .../site-packages/contourpy/util/__init__.py | 5 + .../contourpy/util/_build_config.py | 60 + .../contourpy/util/bokeh_renderer.py | 336 + .../contourpy/util/bokeh_util.py | 71 + .../site-packages/contourpy/util/data.py | 78 + .../contourpy/util/mpl_renderer.py | 532 + .../site-packages/contourpy/util/mpl_util.py | 76 + .../site-packages/contourpy/util/renderer.py | 106 + .../cycler-0.12.1.dist-info/INSTALLER | 1 + .../cycler-0.12.1.dist-info/LICENSE | 27 + .../cycler-0.12.1.dist-info/METADATA | 78 + .../cycler-0.12.1.dist-info/RECORD | 9 + .../cycler-0.12.1.dist-info/WHEEL | 5 + .../cycler-0.12.1.dist-info/top_level.txt | 1 + .../site-packages/cycler/__init__.py | 573 + .../python3.9/site-packages/cycler/py.typed | 0 .../site-packages/fontTools/__init__.py | 8 + .../site-packages/fontTools/__main__.py | 35 + .../site-packages/fontTools/afmLib.py | 440 + .../python3.9/site-packages/fontTools/agl.py | 5233 ++ .../fontTools/cffLib/__init__.py | 3830 ++ .../fontTools/cffLib/specializer.py | 849 + .../site-packages/fontTools/cffLib/width.py | 207 + .../fontTools/colorLib/__init__.py | 0 .../fontTools/colorLib/builder.py | 659 + .../fontTools/colorLib/errors.py | 2 + .../fontTools/colorLib/geometry.py | 143 + .../fontTools/colorLib/table_builder.py | 223 + .../fontTools/colorLib/unbuilder.py | 81 + .../fontTools/config/__init__.py | 74 + .../site-packages/fontTools/cu2qu/__init__.py | 15 + .../site-packages/fontTools/cu2qu/__main__.py | 6 + .../fontTools/cu2qu/benchmark.py | 55 + .../site-packages/fontTools/cu2qu/cli.py | 198 + .../site-packages/fontTools/cu2qu/cu2qu.c | 14893 ++++++ .../cu2qu/cu2qu.cpython-39-darwin.so | Bin 0 -> 357207 bytes .../site-packages/fontTools/cu2qu/cu2qu.py | 534 + .../site-packages/fontTools/cu2qu/errors.py | 77 + .../site-packages/fontTools/cu2qu/ufo.py | 349 + .../fontTools/designspaceLib/__init__.py | 3281 ++ .../fontTools/designspaceLib/split.py | 475 + .../fontTools/designspaceLib/statNames.py | 252 + .../fontTools/designspaceLib/types.py | 147 + .../fontTools/encodings/MacRoman.py | 258 + .../fontTools/encodings/StandardEncoding.py | 258 + .../fontTools/encodings/__init__.py | 1 + .../fontTools/encodings/codecs.py | 135 + .../fontTools/feaLib/__init__.py | 4 + .../fontTools/feaLib/__main__.py | 78 + .../site-packages/fontTools/feaLib/ast.py | 2134 + .../site-packages/fontTools/feaLib/builder.py | 1712 + .../site-packages/fontTools/feaLib/error.py | 22 + .../site-packages/fontTools/feaLib/lexer.c | 18041 +++++++ .../feaLib/lexer.cpython-39-darwin.so | Bin 0 -> 497591 bytes .../site-packages/fontTools/feaLib/lexer.py | 291 + .../fontTools/feaLib/location.py | 12 + .../fontTools/feaLib/lookupDebugInfo.py | 12 + .../site-packages/fontTools/feaLib/parser.py | 2365 + .../fontTools/feaLib/variableScalar.py | 112 + .../site-packages/fontTools/fontBuilder.py | 993 + .../python3.9/site-packages/fontTools/help.py | 35 + .../site-packages/fontTools/merge/__init__.py | 210 + .../site-packages/fontTools/merge/__main__.py | 6 + .../site-packages/fontTools/merge/base.py | 81 + .../site-packages/fontTools/merge/cmap.py | 141 + .../site-packages/fontTools/merge/layout.py | 530 + .../site-packages/fontTools/merge/options.py | 82 + .../site-packages/fontTools/merge/tables.py | 339 + .../site-packages/fontTools/merge/unicode.py | 78 + .../site-packages/fontTools/merge/util.py | 143 + .../site-packages/fontTools/misc/__init__.py | 1 + .../fontTools/misc/arrayTools.py | 424 + .../fontTools/misc/bezierTools.c | 41552 ++++++++++++++++ .../misc/bezierTools.cpython-39-darwin.so | Bin 0 -> 1189069 bytes .../fontTools/misc/bezierTools.py | 1490 + .../fontTools/misc/classifyTools.py | 171 + .../site-packages/fontTools/misc/cliTools.py | 52 + .../fontTools/misc/configTools.py | 348 + .../site-packages/fontTools/misc/cython.py | 27 + .../site-packages/fontTools/misc/dictTools.py | 84 + .../site-packages/fontTools/misc/eexec.py | 119 + .../fontTools/misc/encodingTools.py | 72 + .../site-packages/fontTools/misc/etree.py | 478 + .../site-packages/fontTools/misc/filenames.py | 246 + .../fontTools/misc/fixedTools.py | 253 + .../site-packages/fontTools/misc/intTools.py | 25 + .../fontTools/misc/loggingTools.py | 543 + .../fontTools/misc/macCreatorType.py | 56 + .../site-packages/fontTools/misc/macRes.py | 261 + .../fontTools/misc/plistlib/__init__.py | 681 + .../fontTools/misc/plistlib/py.typed | 0 .../fontTools/misc/psCharStrings.py | 1476 + .../site-packages/fontTools/misc/psLib.py | 398 + .../fontTools/misc/psOperators.py | 572 + .../site-packages/fontTools/misc/py23.py | 96 + .../fontTools/misc/roundTools.py | 110 + .../site-packages/fontTools/misc/sstruct.py | 220 + .../site-packages/fontTools/misc/symfont.py | 248 + .../site-packages/fontTools/misc/testTools.py | 229 + .../site-packages/fontTools/misc/textTools.py | 155 + .../site-packages/fontTools/misc/timeTools.py | 88 + .../site-packages/fontTools/misc/transform.py | 495 + .../site-packages/fontTools/misc/treeTools.py | 45 + .../site-packages/fontTools/misc/vector.py | 148 + .../site-packages/fontTools/misc/visitor.py | 141 + .../site-packages/fontTools/misc/xmlReader.py | 188 + .../site-packages/fontTools/misc/xmlWriter.py | 204 + .../fontTools/mtiLib/__init__.py | 1402 + .../fontTools/mtiLib/__main__.py | 5 + .../fontTools/otlLib/__init__.py | 1 + .../site-packages/fontTools/otlLib/builder.py | 2920 ++ .../site-packages/fontTools/otlLib/error.py | 11 + .../fontTools/otlLib/maxContextCalc.py | 96 + .../fontTools/otlLib/optimize/__init__.py | 53 + .../fontTools/otlLib/optimize/__main__.py | 6 + .../fontTools/otlLib/optimize/gpos.py | 453 + .../site-packages/fontTools/pens/__init__.py | 1 + .../site-packages/fontTools/pens/areaPen.py | 52 + .../site-packages/fontTools/pens/basePen.py | 444 + .../site-packages/fontTools/pens/boundsPen.py | 100 + .../site-packages/fontTools/pens/cairoPen.py | 26 + .../site-packages/fontTools/pens/cocoaPen.py | 26 + .../site-packages/fontTools/pens/cu2quPen.py | 325 + .../fontTools/pens/explicitClosingLinePen.py | 101 + .../site-packages/fontTools/pens/filterPen.py | 164 + .../fontTools/pens/freetypePen.py | 458 + .../fontTools/pens/hashPointPen.py | 75 + .../site-packages/fontTools/pens/momentsPen.c | 13727 +++++ .../pens/momentsPen.cpython-39-darwin.so | Bin 0 -> 325516 bytes .../fontTools/pens/momentsPen.py | 881 + .../fontTools/pens/perimeterPen.py | 69 + .../fontTools/pens/pointInsidePen.py | 192 + .../site-packages/fontTools/pens/pointPen.py | 525 + .../site-packages/fontTools/pens/qtPen.py | 29 + .../site-packages/fontTools/pens/qu2cuPen.py | 105 + .../site-packages/fontTools/pens/quartzPen.py | 44 + .../fontTools/pens/recordingPen.py | 212 + .../fontTools/pens/reportLabPen.py | 80 + .../fontTools/pens/reverseContourPen.py | 96 + .../fontTools/pens/roundingPen.py | 112 + .../fontTools/pens/statisticsPen.py | 308 + .../fontTools/pens/svgPathPen.py | 293 + .../fontTools/pens/t2CharStringPen.py | 68 + .../site-packages/fontTools/pens/teePen.py | 54 + .../fontTools/pens/transformPen.py | 111 + .../fontTools/pens/ttGlyphPen.py | 335 + .../site-packages/fontTools/pens/wxPen.py | 29 + .../site-packages/fontTools/qu2cu/__init__.py | 15 + .../site-packages/fontTools/qu2cu/__main__.py | 7 + .../fontTools/qu2cu/benchmark.py | 57 + .../site-packages/fontTools/qu2cu/cli.py | 125 + .../site-packages/fontTools/qu2cu/qu2cu.c | 16325 ++++++ .../qu2cu/qu2cu.cpython-39-darwin.so | Bin 0 -> 380407 bytes .../site-packages/fontTools/qu2cu/qu2cu.py | 408 + .../fontTools/subset/__init__.py | 3738 ++ .../fontTools/subset/__main__.py | 6 + .../site-packages/fontTools/subset/cff.py | 536 + .../site-packages/fontTools/subset/svg.py | 253 + .../site-packages/fontTools/subset/util.py | 25 + .../fontTools/svgLib/__init__.py | 3 + .../fontTools/svgLib/path/__init__.py | 61 + .../fontTools/svgLib/path/arc.py | 153 + .../fontTools/svgLib/path/parser.py | 320 + .../fontTools/svgLib/path/shapes.py | 183 + .../site-packages/fontTools/t1Lib/__init__.py | 648 + .../site-packages/fontTools/tfmLib.py | 460 + .../site-packages/fontTools/ttLib/__init__.py | 26 + .../site-packages/fontTools/ttLib/__main__.py | 108 + .../site-packages/fontTools/ttLib/macUtils.py | 54 + .../fontTools/ttLib/removeOverlaps.py | 248 + .../fontTools/ttLib/scaleUpem.py | 394 + .../site-packages/fontTools/ttLib/sfnt.py | 661 + .../fontTools/ttLib/standardGlyphOrder.py | 271 + .../fontTools/ttLib/tables/B_A_S_E_.py | 5 + .../ttLib/tables/BitmapGlyphMetrics.py | 64 + .../fontTools/ttLib/tables/C_B_D_T_.py | 103 + .../fontTools/ttLib/tables/C_B_L_C_.py | 9 + .../fontTools/ttLib/tables/C_F_F_.py | 46 + .../fontTools/ttLib/tables/C_F_F__2.py | 13 + .../fontTools/ttLib/tables/C_O_L_R_.py | 158 + .../fontTools/ttLib/tables/C_P_A_L_.py | 296 + .../fontTools/ttLib/tables/D_S_I_G_.py | 151 + .../fontTools/ttLib/tables/D__e_b_g.py | 17 + .../fontTools/ttLib/tables/DefaultTable.py | 49 + .../fontTools/ttLib/tables/E_B_D_T_.py | 827 + .../fontTools/ttLib/tables/E_B_L_C_.py | 710 + .../fontTools/ttLib/tables/F_F_T_M_.py | 42 + .../fontTools/ttLib/tables/F__e_a_t.py | 144 + .../fontTools/ttLib/tables/G_D_E_F_.py | 5 + .../fontTools/ttLib/tables/G_M_A_P_.py | 141 + .../fontTools/ttLib/tables/G_P_K_G_.py | 126 + .../fontTools/ttLib/tables/G_P_O_S_.py | 5 + .../fontTools/ttLib/tables/G_S_U_B_.py | 5 + .../fontTools/ttLib/tables/G__l_a_t.py | 234 + .../fontTools/ttLib/tables/G__l_o_c.py | 84 + .../fontTools/ttLib/tables/H_V_A_R_.py | 5 + .../fontTools/ttLib/tables/J_S_T_F_.py | 5 + .../fontTools/ttLib/tables/L_T_S_H_.py | 48 + .../fontTools/ttLib/tables/M_A_T_H_.py | 5 + .../fontTools/ttLib/tables/M_E_T_A_.py | 345 + .../fontTools/ttLib/tables/M_V_A_R_.py | 5 + .../fontTools/ttLib/tables/O_S_2f_2.py | 746 + .../fontTools/ttLib/tables/S_I_N_G_.py | 92 + .../fontTools/ttLib/tables/S_T_A_T_.py | 5 + .../fontTools/ttLib/tables/S_V_G_.py | 215 + .../fontTools/ttLib/tables/S__i_l_f.py | 1037 + .../fontTools/ttLib/tables/S__i_l_l.py | 87 + .../fontTools/ttLib/tables/T_S_I_B_.py | 5 + .../fontTools/ttLib/tables/T_S_I_C_.py | 5 + .../fontTools/ttLib/tables/T_S_I_D_.py | 5 + .../fontTools/ttLib/tables/T_S_I_J_.py | 5 + .../fontTools/ttLib/tables/T_S_I_P_.py | 5 + .../fontTools/ttLib/tables/T_S_I_S_.py | 5 + .../fontTools/ttLib/tables/T_S_I_V_.py | 20 + .../fontTools/ttLib/tables/T_S_I__0.py | 56 + .../fontTools/ttLib/tables/T_S_I__1.py | 163 + .../fontTools/ttLib/tables/T_S_I__2.py | 14 + .../fontTools/ttLib/tables/T_S_I__3.py | 19 + .../fontTools/ttLib/tables/T_S_I__5.py | 46 + .../fontTools/ttLib/tables/T_T_F_A_.py | 5 + .../fontTools/ttLib/tables/TupleVariation.py | 808 + .../fontTools/ttLib/tables/V_D_M_X_.py | 241 + .../fontTools/ttLib/tables/V_O_R_G_.py | 159 + .../fontTools/ttLib/tables/V_V_A_R_.py | 5 + .../fontTools/ttLib/tables/__init__.py | 96 + .../fontTools/ttLib/tables/_a_n_k_r.py | 14 + .../fontTools/ttLib/tables/_a_v_a_r.py | 138 + .../fontTools/ttLib/tables/_b_s_l_n.py | 6 + .../fontTools/ttLib/tables/_c_i_d_g.py | 19 + .../fontTools/ttLib/tables/_c_m_a_p.py | 1576 + .../fontTools/ttLib/tables/_c_v_a_r.py | 86 + .../fontTools/ttLib/tables/_c_v_t.py | 47 + .../fontTools/ttLib/tables/_f_e_a_t.py | 12 + .../fontTools/ttLib/tables/_f_p_g_m.py | 49 + .../fontTools/ttLib/tables/_f_v_a_r.py | 250 + .../fontTools/ttLib/tables/_g_a_s_p.py | 55 + .../fontTools/ttLib/tables/_g_c_i_d.py | 6 + .../fontTools/ttLib/tables/_g_l_y_f.py | 2683 + .../fontTools/ttLib/tables/_g_v_a_r.py | 284 + .../fontTools/ttLib/tables/_h_d_m_x.py | 119 + .../fontTools/ttLib/tables/_h_e_a_d.py | 123 + .../fontTools/ttLib/tables/_h_h_e_a.py | 135 + .../fontTools/ttLib/tables/_h_m_t_x.py | 151 + .../fontTools/ttLib/tables/_k_e_r_n.py | 278 + .../fontTools/ttLib/tables/_l_c_a_r.py | 5 + .../fontTools/ttLib/tables/_l_o_c_a.py | 65 + .../fontTools/ttLib/tables/_l_t_a_g.py | 64 + .../fontTools/ttLib/tables/_m_a_x_p.py | 139 + .../fontTools/ttLib/tables/_m_e_t_a.py | 104 + .../fontTools/ttLib/tables/_m_o_r_t.py | 6 + .../fontTools/ttLib/tables/_m_o_r_x.py | 6 + .../fontTools/ttLib/tables/_n_a_m_e.py | 1228 + .../fontTools/ttLib/tables/_o_p_b_d.py | 6 + .../fontTools/ttLib/tables/_p_o_s_t.py | 308 + .../fontTools/ttLib/tables/_p_r_e_p.py | 7 + .../fontTools/ttLib/tables/_p_r_o_p.py | 6 + .../fontTools/ttLib/tables/_s_b_i_x.py | 119 + .../fontTools/ttLib/tables/_t_r_a_k.py | 325 + .../fontTools/ttLib/tables/_v_h_e_a.py | 127 + .../fontTools/ttLib/tables/_v_m_t_x.py | 10 + .../fontTools/ttLib/tables/asciiTable.py | 20 + .../fontTools/ttLib/tables/grUtils.py | 92 + .../fontTools/ttLib/tables/otBase.py | 1468 + .../fontTools/ttLib/tables/otConverters.py | 1926 + .../fontTools/ttLib/tables/otData.py | 6236 +++ .../fontTools/ttLib/tables/otTables.py | 2273 + .../fontTools/ttLib/tables/otTraverse.py | 161 + .../fontTools/ttLib/tables/sbixGlyph.py | 145 + .../fontTools/ttLib/tables/sbixStrike.py | 177 + .../ttLib/tables/table_API_readme.txt | 91 + .../fontTools/ttLib/tables/ttProgram.py | 593 + .../fontTools/ttLib/ttCollection.py | 126 + .../site-packages/fontTools/ttLib/ttFont.py | 1146 + .../fontTools/ttLib/ttGlyphSet.py | 377 + .../fontTools/ttLib/ttVisitor.py | 32 + .../site-packages/fontTools/ttLib/woff2.py | 1685 + .../python3.9/site-packages/fontTools/ttx.py | 468 + .../fontTools/ufoLib/__init__.py | 2464 + .../fontTools/ufoLib/converters.py | 335 + .../site-packages/fontTools/ufoLib/errors.py | 22 + .../site-packages/fontTools/ufoLib/etree.py | 5 + .../fontTools/ufoLib/filenames.py | 291 + .../site-packages/fontTools/ufoLib/glifLib.py | 2017 + .../site-packages/fontTools/ufoLib/kerning.py | 91 + .../fontTools/ufoLib/plistlib.py | 46 + .../fontTools/ufoLib/pointPen.py | 5 + .../site-packages/fontTools/ufoLib/utils.py | 75 + .../fontTools/ufoLib/validators.py | 1186 + .../site-packages/fontTools/unicode.py | 50 + .../fontTools/unicodedata/Blocks.py | 779 + .../fontTools/unicodedata/OTTags.py | 50 + .../fontTools/unicodedata/ScriptExtensions.py | 568 + .../fontTools/unicodedata/Scripts.py | 3509 ++ .../fontTools/unicodedata/__init__.py | 300 + .../fontTools/varLib/__init__.py | 1490 + .../fontTools/varLib/__main__.py | 6 + .../site-packages/fontTools/varLib/avar.py | 70 + .../fontTools/varLib/avarPlanner.py | 1004 + .../site-packages/fontTools/varLib/builder.py | 157 + .../site-packages/fontTools/varLib/cff.py | 712 + .../site-packages/fontTools/varLib/errors.py | 219 + .../fontTools/varLib/featureVars.py | 661 + .../fontTools/varLib/instancer/__init__.py | 1565 + .../fontTools/varLib/instancer/__main__.py | 5 + .../fontTools/varLib/instancer/featureVars.py | 190 + .../fontTools/varLib/instancer/names.py | 388 + .../fontTools/varLib/instancer/solver.py | 309 + .../fontTools/varLib/interpolatable.py | 1133 + .../fontTools/varLib/interpolatableHelpers.py | 380 + .../fontTools/varLib/interpolatablePlot.py | 1269 + .../varLib/interpolatableTestContourOrder.py | 82 + .../varLib/interpolatableTestStartingPoint.py | 105 + .../fontTools/varLib/interpolate_layout.py | 123 + .../site-packages/fontTools/varLib/iup.c | 19184 +++++++ .../fontTools/varLib/iup.cpython-39-darwin.so | Bin 0 -> 464757 bytes .../site-packages/fontTools/varLib/iup.py | 486 + .../site-packages/fontTools/varLib/merger.py | 1716 + .../site-packages/fontTools/varLib/models.py | 630 + .../site-packages/fontTools/varLib/mutator.py | 509 + .../site-packages/fontTools/varLib/mvar.py | 40 + .../site-packages/fontTools/varLib/plot.py | 238 + .../site-packages/fontTools/varLib/stat.py | 142 + .../fontTools/varLib/varStore.py | 727 + .../fontTools/voltLib/__init__.py | 5 + .../site-packages/fontTools/voltLib/ast.py | 448 + .../site-packages/fontTools/voltLib/error.py | 12 + .../site-packages/fontTools/voltLib/lexer.py | 99 + .../site-packages/fontTools/voltLib/parser.py | 656 + .../fontTools/voltLib/voltToFea.py | 726 + .../fonttools-4.47.0.dist-info/INSTALLER | 1 + .../fonttools-4.47.0.dist-info/LICENSE | 21 + .../fonttools-4.47.0.dist-info/METADATA | 3199 ++ .../fonttools-4.47.0.dist-info/RECORD | 624 + .../fonttools-4.47.0.dist-info/WHEEL | 5 + .../entry_points.txt | 5 + .../fonttools-4.47.0.dist-info/top_level.txt | 1 + .../INSTALLER | 1 + .../METADATA | 229 + .../garmin_fit_sdk-21.126.0.dist-info/RECORD | 52 + .../REQUESTED | 0 .../garmin_fit_sdk-21.126.0.dist-info/WHEEL | 6 + .../top_level.txt | 2 + .../zip-safe | 1 + .../site-packages/garmin_fit_sdk/__init__.py | 25 + .../garmin_fit_sdk/accumulator.py | 55 + .../site-packages/garmin_fit_sdk/bitstream.py | 90 + .../garmin_fit_sdk/crc_calculator.py | 57 + .../site-packages/garmin_fit_sdk/decoder.py | 731 + .../site-packages/garmin_fit_sdk/fit.py | 90 + .../garmin_fit_sdk/hr_mesg_utils.py | 152 + .../site-packages/garmin_fit_sdk/profile.py | 24520 +++++++++ .../site-packages/garmin_fit_sdk/stream.py | 178 + .../site-packages/garmin_fit_sdk/util.py | 55 + .../INSTALLER | 1 + .../LICENSE | 202 + .../METADATA | 104 + .../RECORD | 71 + .../importlib_resources-6.1.1.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../importlib_resources/__init__.py | 17 + .../importlib_resources/_adapters.py | 168 + .../importlib_resources/_common.py | 207 + .../importlib_resources/_compat.py | 126 + .../importlib_resources/_itertools.py | 38 + .../site-packages/importlib_resources/abc.py | 170 + .../importlib_resources/py.typed | 0 .../importlib_resources/readers.py | 172 + .../importlib_resources/simple.py | 106 + .../importlib_resources/tests/__init__.py | 0 .../importlib_resources/tests/_compat.py | 32 + .../importlib_resources/tests/_path.py | 56 + .../tests/data01/__init__.py | 0 .../tests/data01/binary.file | Bin 0 -> 4 bytes .../tests/data01/subdirectory/__init__.py | 0 .../tests/data01/subdirectory/binary.file | Bin 0 -> 4 bytes .../tests/data01/utf-16.file | Bin 0 -> 44 bytes .../tests/data01/utf-8.file | 1 + .../tests/data02/__init__.py | 0 .../tests/data02/one/__init__.py | 0 .../tests/data02/one/resource1.txt | 1 + .../subdirectory/subsubdir/resource.txt | 1 + .../tests/data02/two/__init__.py | 0 .../tests/data02/two/resource2.txt | 1 + .../tests/namespacedata01/binary.file | Bin 0 -> 4 bytes .../tests/namespacedata01/utf-16.file | Bin 0 -> 44 bytes .../tests/namespacedata01/utf-8.file | 1 + .../tests/test_compatibilty_files.py | 104 + .../tests/test_contents.py | 43 + .../importlib_resources/tests/test_custom.py | 45 + .../importlib_resources/tests/test_files.py | 112 + .../importlib_resources/tests/test_open.py | 85 + .../importlib_resources/tests/test_path.py | 69 + .../importlib_resources/tests/test_read.py | 80 + .../importlib_resources/tests/test_reader.py | 143 + .../tests/test_resource.py | 221 + .../importlib_resources/tests/util.py | 165 + .../importlib_resources/tests/zip.py | 32 + .../iniconfig-2.0.0.dist-info/INSTALLER | 1 + .../iniconfig-2.0.0.dist-info/METADATA | 80 + .../iniconfig-2.0.0.dist-info/RECORD | 14 + .../iniconfig-2.0.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 19 + .../site-packages/iniconfig/__init__.py | 216 + .../site-packages/iniconfig/_parse.py | 82 + .../site-packages/iniconfig/_version.py | 4 + .../site-packages/iniconfig/exceptions.py | 20 + .../site-packages/iniconfig/py.typed | 0 .../kiwisolver-1.4.5.dist-info/INSTALLER | 1 + .../kiwisolver-1.4.5.dist-info/LICENSE | 71 + .../kiwisolver-1.4.5.dist-info/METADATA | 122 + .../kiwisolver-1.4.5.dist-info/RECORD | 13 + .../kiwisolver-1.4.5.dist-info/WHEEL | 5 + .../kiwisolver-1.4.5.dist-info/top_level.txt | 2 + .../site-packages/kiwisolver/__init__.py | 42 + .../kiwisolver/_cext.cpython-39-darwin.so | Bin 0 -> 250839 bytes .../site-packages/kiwisolver/_cext.pyi | 228 + .../site-packages/kiwisolver/exceptions.py | 51 + .../site-packages/kiwisolver/py.typed | 0 .../matplotlib-3.8.2.dist-info/INSTALLER | 1 + .../matplotlib-3.8.2.dist-info/LICENSE | 99 + .../LICENSE_AMSFONTS | 240 + .../matplotlib-3.8.2.dist-info/LICENSE_BAKOMA | 40 + .../LICENSE_CARLOGO | 45 + .../LICENSE_COLORBREWER | 13 + .../LICENSE_COURIERTEN | 18 + .../LICENSE_JSXTOOLS_RESIZE_OBSERVER | 108 + .../matplotlib-3.8.2.dist-info/LICENSE_QHULL | 39 + .../LICENSE_QT4_EDITOR | 30 + .../LICENSE_SOLARIZED | 20 + .../matplotlib-3.8.2.dist-info/LICENSE_STIX | 71 + .../matplotlib-3.8.2.dist-info/LICENSE_YORICK | 49 + .../matplotlib-3.8.2.dist-info/METADATA | 125 + .../matplotlib-3.8.2.dist-info/RECORD | 901 + .../matplotlib-3.8.2.dist-info/REQUESTED | 0 .../matplotlib-3.8.2.dist-info/WHEEL | 5 + .../matplotlib-3.8.2.dist-info/top_level.txt | 3 + .../site-packages/matplotlib/__init__.py | 1505 + .../site-packages/matplotlib/__init__.pyi | 113 + .../site-packages/matplotlib/_afm.py | 532 + .../matplotlib/_animation_data.py | 262 + .../site-packages/matplotlib/_api/__init__.py | 381 + .../matplotlib/_api/__init__.pyi | 59 + .../matplotlib/_api/deprecation.py | 510 + .../matplotlib/_api/deprecation.pyi | 76 + .../matplotlib/_blocking_input.py | 30 + .../_c_internal_utils.cpython-39-darwin.so | Bin 0 -> 51379 bytes .../matplotlib/_c_internal_utils.pyi | 1 + .../python3.9/site-packages/matplotlib/_cm.py | 1440 + .../site-packages/matplotlib/_cm_listed.py | 2071 + .../site-packages/matplotlib/_color_data.py | 1141 + .../site-packages/matplotlib/_color_data.pyi | 6 + .../matplotlib/_constrained_layout.py | 794 + .../site-packages/matplotlib/_docstring.py | 97 + .../site-packages/matplotlib/_docstring.pyi | 29 + .../site-packages/matplotlib/_enums.py | 185 + .../site-packages/matplotlib/_enums.pyi | 18 + .../matplotlib/_fontconfig_pattern.py | 120 + .../matplotlib/_image.cpython-39-darwin.so | Bin 0 -> 165192 bytes .../site-packages/matplotlib/_image.pyi | 0 .../matplotlib/_internal_utils.py | 64 + .../site-packages/matplotlib/_layoutgrid.py | 547 + .../site-packages/matplotlib/_mathtext.py | 2851 ++ .../matplotlib/_mathtext_data.py | 1311 + .../matplotlib/_path.cpython-39-darwin.so | Bin 0 -> 157943 bytes .../site-packages/matplotlib/_path.pyi | 9 + .../matplotlib/_pylab_helpers.py | 135 + .../matplotlib/_pylab_helpers.pyi | 29 + .../matplotlib/_qhull.cpython-39-darwin.so | Bin 0 -> 458136 bytes .../site-packages/matplotlib/_qhull.pyi | 0 .../site-packages/matplotlib/_text_helpers.py | 74 + .../site-packages/matplotlib/_tight_bbox.py | 84 + .../site-packages/matplotlib/_tight_layout.py | 301 + .../matplotlib/_tri.cpython-39-darwin.so | Bin 0 -> 275750 bytes .../site-packages/matplotlib/_tri.pyi | 23 + .../matplotlib/_ttconv.cpython-39-darwin.so | Bin 0 -> 165337 bytes .../site-packages/matplotlib/_ttconv.pyi | 0 .../site-packages/matplotlib/_type1font.py | 876 + .../site-packages/matplotlib/_version.py | 16 + .../site-packages/matplotlib/animation.py | 1804 + .../site-packages/matplotlib/animation.pyi | 219 + .../site-packages/matplotlib/artist.py | 1860 + .../site-packages/matplotlib/artist.pyi | 181 + .../site-packages/matplotlib/axes/__init__.py | 18 + .../matplotlib/axes/__init__.pyi | 16 + .../site-packages/matplotlib/axes/_axes.py | 8454 ++++ .../site-packages/matplotlib/axes/_axes.pyi | 767 + .../site-packages/matplotlib/axes/_base.py | 4644 ++ .../site-packages/matplotlib/axes/_base.pyi | 453 + .../matplotlib/axes/_secondary_axes.py | 283 + .../matplotlib/axes/_secondary_axes.pyi | 42 + .../site-packages/matplotlib/axis.py | 2766 + .../site-packages/matplotlib/axis.pyi | 278 + .../site-packages/matplotlib/backend_bases.py | 3483 ++ .../matplotlib/backend_bases.pyi | 490 + .../matplotlib/backend_managers.py | 387 + .../matplotlib/backend_managers.pyi | 64 + .../site-packages/matplotlib/backend_tools.py | 1003 + .../matplotlib/backend_tools.pyi | 121 + .../matplotlib/backends/__init__.py | 3 + .../_backend_agg.cpython-39-darwin.so | Bin 0 -> 248670 bytes .../matplotlib/backends/_backend_agg.pyi | 0 .../matplotlib/backends/_backend_gtk.py | 332 + .../matplotlib/backends/_backend_pdf_ps.py | 145 + .../matplotlib/backends/_backend_tk.py | 1074 + .../backends/_macosx.cpython-39-darwin.so | Bin 0 -> 108969 bytes .../matplotlib/backends/_macosx.pyi | 0 .../backends/_tkagg.cpython-39-darwin.so | Bin 0 -> 52680 bytes .../matplotlib/backends/_tkagg.pyi | 0 .../matplotlib/backends/backend_agg.py | 544 + .../matplotlib/backends/backend_cairo.py | 500 + .../matplotlib/backends/backend_gtk3.py | 587 + .../matplotlib/backends/backend_gtk3agg.py | 69 + .../matplotlib/backends/backend_gtk3cairo.py | 26 + .../matplotlib/backends/backend_gtk4.py | 606 + .../matplotlib/backends/backend_gtk4agg.py | 36 + .../matplotlib/backends/backend_gtk4cairo.py | 28 + .../matplotlib/backends/backend_macosx.py | 236 + .../matplotlib/backends/backend_mixed.py | 119 + .../matplotlib/backends/backend_nbagg.py | 243 + .../matplotlib/backends/backend_pdf.py | 2827 ++ .../matplotlib/backends/backend_pgf.py | 1009 + .../matplotlib/backends/backend_ps.py | 1340 + .../matplotlib/backends/backend_qt.py | 1022 + .../matplotlib/backends/backend_qt5.py | 28 + .../matplotlib/backends/backend_qt5agg.py | 14 + .../matplotlib/backends/backend_qt5cairo.py | 11 + .../matplotlib/backends/backend_qtagg.py | 86 + .../matplotlib/backends/backend_qtcairo.py | 46 + .../matplotlib/backends/backend_svg.py | 1368 + .../matplotlib/backends/backend_template.py | 213 + .../matplotlib/backends/backend_tkagg.py | 20 + .../matplotlib/backends/backend_tkcairo.py | 26 + .../matplotlib/backends/backend_webagg.py | 334 + .../backends/backend_webagg_core.py | 517 + .../matplotlib/backends/backend_wx.py | 1332 + .../matplotlib/backends/backend_wxagg.py | 43 + .../matplotlib/backends/backend_wxcairo.py | 23 + .../matplotlib/backends/qt_compat.py | 230 + .../matplotlib/backends/qt_editor/__init__.py | 0 .../backends/qt_editor/_formlayout.py | 592 + .../backends/qt_editor/figureoptions.py | 263 + .../backends/web_backend/.eslintrc.js | 32 + .../backends/web_backend/.prettierignore | 7 + .../backends/web_backend/.prettierrc | 11 + .../backends/web_backend/all_figures.html | 52 + .../backends/web_backend/css/boilerplate.css | 77 + .../backends/web_backend/css/fbm.css | 97 + .../backends/web_backend/css/mpl.css | 84 + .../backends/web_backend/css/page.css | 82 + .../web_backend/ipython_inline_figure.html | 34 + .../matplotlib/backends/web_backend/js/mpl.js | 695 + .../backends/web_backend/js/mpl_tornado.js | 8 + .../backends/web_backend/js/nbagg_mpl.js | 275 + .../backends/web_backend/nbagg_uat.ipynb | 631 + .../backends/web_backend/package.json | 18 + .../backends/web_backend/single_figure.html | 39 + .../site-packages/matplotlib/bezier.py | 594 + .../site-packages/matplotlib/bezier.pyi | 74 + .../site-packages/matplotlib/category.py | 233 + .../site-packages/matplotlib/cbook.py | 2350 + .../site-packages/matplotlib/cbook.pyi | 175 + .../python3.9/site-packages/matplotlib/cm.py | 745 + .../python3.9/site-packages/matplotlib/cm.pyi | 54 + .../site-packages/matplotlib/collections.py | 2394 + .../site-packages/matplotlib/collections.pyi | 242 + .../site-packages/matplotlib/colorbar.py | 1580 + .../site-packages/matplotlib/colorbar.pyi | 136 + .../site-packages/matplotlib/colors.py | 2762 + .../site-packages/matplotlib/colors.pyi | 354 + .../site-packages/matplotlib/container.py | 141 + .../site-packages/matplotlib/container.pyi | 56 + .../site-packages/matplotlib/contour.py | 1902 + .../site-packages/matplotlib/contour.pyi | 169 + .../site-packages/matplotlib/dates.py | 1894 + .../site-packages/matplotlib/dviread.py | 1149 + .../site-packages/matplotlib/dviread.pyi | 90 + .../site-packages/matplotlib/figure.py | 3626 ++ .../site-packages/matplotlib/figure.pyi | 416 + .../site-packages/matplotlib/font_manager.py | 1584 + .../site-packages/matplotlib/font_manager.pyi | 136 + .../matplotlib/ft2font.cpython-39-darwin.so | Bin 0 -> 788329 bytes .../site-packages/matplotlib/ft2font.pyi | 253 + .../site-packages/matplotlib/gridspec.py | 738 + .../site-packages/matplotlib/gridspec.pyi | 134 + .../site-packages/matplotlib/hatch.py | 225 + .../site-packages/matplotlib/hatch.pyi | 68 + .../site-packages/matplotlib/image.py | 1785 + .../site-packages/matplotlib/image.pyi | 209 + .../site-packages/matplotlib/layout_engine.py | 304 + .../matplotlib/layout_engine.pyi | 62 + .../site-packages/matplotlib/legend.py | 1384 + .../site-packages/matplotlib/legend.pyi | 154 + .../matplotlib/legend_handler.py | 813 + .../matplotlib/legend_handler.pyi | 294 + .../site-packages/matplotlib/lines.py | 1677 + .../site-packages/matplotlib/lines.pyi | 153 + .../site-packages/matplotlib/markers.py | 917 + .../site-packages/matplotlib/markers.pyi | 51 + .../site-packages/matplotlib/mathtext.py | 140 + .../site-packages/matplotlib/mathtext.pyi | 33 + .../site-packages/matplotlib/mlab.py | 914 + .../site-packages/matplotlib/mlab.pyi | 100 + .../matplotlib/mpl-data/fonts/afm/cmex10.afm | 220 + .../matplotlib/mpl-data/fonts/afm/cmmi10.afm | 326 + .../matplotlib/mpl-data/fonts/afm/cmr10.afm | 343 + .../matplotlib/mpl-data/fonts/afm/cmsy10.afm | 195 + .../matplotlib/mpl-data/fonts/afm/cmtt10.afm | 156 + .../matplotlib/mpl-data/fonts/afm/pagd8a.afm | 576 + .../matplotlib/mpl-data/fonts/afm/pagdo8a.afm | 576 + .../matplotlib/mpl-data/fonts/afm/pagk8a.afm | 573 + .../matplotlib/mpl-data/fonts/afm/pagko8a.afm | 573 + .../matplotlib/mpl-data/fonts/afm/pbkd8a.afm | 415 + .../matplotlib/mpl-data/fonts/afm/pbkdi8a.afm | 417 + .../matplotlib/mpl-data/fonts/afm/pbkl8a.afm | 407 + .../matplotlib/mpl-data/fonts/afm/pbkli8a.afm | 410 + .../matplotlib/mpl-data/fonts/afm/pcrb8a.afm | 344 + .../matplotlib/mpl-data/fonts/afm/pcrbo8a.afm | 344 + .../matplotlib/mpl-data/fonts/afm/pcrr8a.afm | 344 + .../matplotlib/mpl-data/fonts/afm/pcrro8a.afm | 344 + .../matplotlib/mpl-data/fonts/afm/phvb8a.afm | 570 + .../matplotlib/mpl-data/fonts/afm/phvb8an.afm | 570 + .../matplotlib/mpl-data/fonts/afm/phvbo8a.afm | 570 + .../mpl-data/fonts/afm/phvbo8an.afm | 570 + .../matplotlib/mpl-data/fonts/afm/phvl8a.afm | 445 + .../matplotlib/mpl-data/fonts/afm/phvlo8a.afm | 445 + .../matplotlib/mpl-data/fonts/afm/phvr8a.afm | 612 + .../matplotlib/mpl-data/fonts/afm/phvr8an.afm | 612 + .../matplotlib/mpl-data/fonts/afm/phvro8a.afm | 612 + .../mpl-data/fonts/afm/phvro8an.afm | 612 + .../matplotlib/mpl-data/fonts/afm/pncb8a.afm | 472 + .../matplotlib/mpl-data/fonts/afm/pncbi8a.afm | 602 + .../matplotlib/mpl-data/fonts/afm/pncr8a.afm | 524 + .../matplotlib/mpl-data/fonts/afm/pncri8a.afm | 536 + .../matplotlib/mpl-data/fonts/afm/pplb8a.afm | 434 + .../matplotlib/mpl-data/fonts/afm/pplbi8a.afm | 441 + .../matplotlib/mpl-data/fonts/afm/pplr8a.afm | 445 + .../matplotlib/mpl-data/fonts/afm/pplri8a.afm | 439 + .../matplotlib/mpl-data/fonts/afm/psyr.afm | 209 + .../matplotlib/mpl-data/fonts/afm/ptmb8a.afm | 648 + .../matplotlib/mpl-data/fonts/afm/ptmbi8a.afm | 648 + .../matplotlib/mpl-data/fonts/afm/ptmr8a.afm | 648 + .../matplotlib/mpl-data/fonts/afm/ptmri8a.afm | 648 + .../matplotlib/mpl-data/fonts/afm/putb8a.afm | 1005 + .../matplotlib/mpl-data/fonts/afm/putbi8a.afm | 1017 + .../matplotlib/mpl-data/fonts/afm/putr8a.afm | 1029 + .../matplotlib/mpl-data/fonts/afm/putri8a.afm | 1008 + .../matplotlib/mpl-data/fonts/afm/pzcmi8a.afm | 480 + .../matplotlib/mpl-data/fonts/afm/pzdr.afm | 222 + .../fonts/pdfcorefonts/Courier-Bold.afm | 342 + .../pdfcorefonts/Courier-BoldOblique.afm | 342 + .../fonts/pdfcorefonts/Courier-Oblique.afm | 342 + .../mpl-data/fonts/pdfcorefonts/Courier.afm | 342 + .../fonts/pdfcorefonts/Helvetica-Bold.afm | 2827 ++ .../pdfcorefonts/Helvetica-BoldOblique.afm | 2827 ++ .../fonts/pdfcorefonts/Helvetica-Oblique.afm | 3051 ++ .../mpl-data/fonts/pdfcorefonts/Helvetica.afm | 3051 ++ .../mpl-data/fonts/pdfcorefonts/Symbol.afm | 213 + .../fonts/pdfcorefonts/Times-Bold.afm | 2588 + .../fonts/pdfcorefonts/Times-BoldItalic.afm | 2384 + .../fonts/pdfcorefonts/Times-Italic.afm | 2667 + .../fonts/pdfcorefonts/Times-Roman.afm | 2419 + .../fonts/pdfcorefonts/ZapfDingbats.afm | 225 + .../mpl-data/fonts/pdfcorefonts/readme.txt | 15 + .../mpl-data/fonts/ttf/DejaVuSans-Bold.ttf | Bin 0 -> 704128 bytes .../fonts/ttf/DejaVuSans-BoldOblique.ttf | Bin 0 -> 641720 bytes .../mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf | Bin 0 -> 633840 bytes .../mpl-data/fonts/ttf/DejaVuSans.ttf | Bin 0 -> 756072 bytes .../mpl-data/fonts/ttf/DejaVuSansDisplay.ttf | Bin 0 -> 25712 bytes .../fonts/ttf/DejaVuSansMono-Bold.ttf | Bin 0 -> 331536 bytes .../fonts/ttf/DejaVuSansMono-BoldOblique.ttf | Bin 0 -> 253116 bytes .../fonts/ttf/DejaVuSansMono-Oblique.ttf | Bin 0 -> 251472 bytes .../mpl-data/fonts/ttf/DejaVuSansMono.ttf | Bin 0 -> 340240 bytes .../mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf | Bin 0 -> 355692 bytes .../fonts/ttf/DejaVuSerif-BoldItalic.ttf | Bin 0 -> 347064 bytes .../mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf | Bin 0 -> 345612 bytes .../mpl-data/fonts/ttf/DejaVuSerif.ttf | Bin 0 -> 379740 bytes .../mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf | Bin 0 -> 14300 bytes .../mpl-data/fonts/ttf/LICENSE_DEJAVU | 99 + .../mpl-data/fonts/ttf/LICENSE_STIX | 124 + .../mpl-data/fonts/ttf/STIXGeneral.ttf | Bin 0 -> 448228 bytes .../mpl-data/fonts/ttf/STIXGeneralBol.ttf | Bin 0 -> 237360 bytes .../mpl-data/fonts/ttf/STIXGeneralBolIta.ttf | Bin 0 -> 181152 bytes .../mpl-data/fonts/ttf/STIXGeneralItalic.ttf | Bin 0 -> 175040 bytes .../mpl-data/fonts/ttf/STIXNonUni.ttf | Bin 0 -> 59108 bytes .../mpl-data/fonts/ttf/STIXNonUniBol.ttf | Bin 0 -> 30512 bytes .../mpl-data/fonts/ttf/STIXNonUniBolIta.ttf | Bin 0 -> 41272 bytes .../mpl-data/fonts/ttf/STIXNonUniIta.ttf | Bin 0 -> 46752 bytes .../mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf | Bin 0 -> 13656 bytes .../mpl-data/fonts/ttf/STIXSizFourSymBol.ttf | Bin 0 -> 12228 bytes .../mpl-data/fonts/ttf/STIXSizFourSymReg.ttf | Bin 0 -> 15972 bytes .../mpl-data/fonts/ttf/STIXSizOneSymBol.ttf | Bin 0 -> 12556 bytes .../mpl-data/fonts/ttf/STIXSizOneSymReg.ttf | Bin 0 -> 19760 bytes .../mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf | Bin 0 -> 12192 bytes .../mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf | Bin 0 -> 15836 bytes .../mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf | Bin 0 -> 12116 bytes .../mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf | Bin 0 -> 15704 bytes .../matplotlib/mpl-data/fonts/ttf/cmb10.ttf | Bin 0 -> 25680 bytes .../matplotlib/mpl-data/fonts/ttf/cmex10.ttf | Bin 0 -> 21092 bytes .../matplotlib/mpl-data/fonts/ttf/cmmi10.ttf | Bin 0 -> 32560 bytes .../matplotlib/mpl-data/fonts/ttf/cmr10.ttf | Bin 0 -> 26348 bytes .../matplotlib/mpl-data/fonts/ttf/cmss10.ttf | Bin 0 -> 20376 bytes .../matplotlib/mpl-data/fonts/ttf/cmsy10.ttf | Bin 0 -> 29396 bytes .../matplotlib/mpl-data/fonts/ttf/cmtt10.ttf | Bin 0 -> 28136 bytes .../mpl-data/images/back-symbolic.svg | 46 + .../matplotlib/mpl-data/images/back.pdf | Bin 0 -> 1623 bytes .../matplotlib/mpl-data/images/back.png | Bin 0 -> 380 bytes .../matplotlib/mpl-data/images/back.svg | 46 + .../matplotlib/mpl-data/images/back_large.png | Bin 0 -> 620 bytes .../mpl-data/images/filesave-symbolic.svg | 68 + .../matplotlib/mpl-data/images/filesave.pdf | Bin 0 -> 1734 bytes .../matplotlib/mpl-data/images/filesave.png | Bin 0 -> 458 bytes .../matplotlib/mpl-data/images/filesave.svg | 68 + .../mpl-data/images/filesave_large.png | Bin 0 -> 720 bytes .../mpl-data/images/forward-symbolic.svg | 46 + .../matplotlib/mpl-data/images/forward.pdf | Bin 0 -> 1630 bytes .../matplotlib/mpl-data/images/forward.png | Bin 0 -> 357 bytes .../matplotlib/mpl-data/images/forward.svg | 46 + .../mpl-data/images/forward_large.png | Bin 0 -> 593 bytes .../matplotlib/mpl-data/images/hand.pdf | Bin 0 -> 4172 bytes .../matplotlib/mpl-data/images/hand.png | Bin 0 -> 979 bytes .../matplotlib/mpl-data/images/hand.svg | 130 + .../mpl-data/images/help-symbolic.svg | 52 + .../matplotlib/mpl-data/images/help.pdf | Bin 0 -> 1813 bytes .../matplotlib/mpl-data/images/help.png | Bin 0 -> 472 bytes .../matplotlib/mpl-data/images/help.svg | 52 + .../matplotlib/mpl-data/images/help_large.png | Bin 0 -> 747 bytes .../mpl-data/images/home-symbolic.svg | 59 + .../matplotlib/mpl-data/images/home.pdf | Bin 0 -> 1737 bytes .../matplotlib/mpl-data/images/home.png | Bin 0 -> 468 bytes .../matplotlib/mpl-data/images/home.svg | 59 + .../matplotlib/mpl-data/images/home_large.png | Bin 0 -> 790 bytes .../matplotlib/mpl-data/images/matplotlib.pdf | Bin 0 -> 22852 bytes .../matplotlib/mpl-data/images/matplotlib.png | Bin 0 -> 1283 bytes .../matplotlib/mpl-data/images/matplotlib.svg | 3171 ++ .../mpl-data/images/matplotlib_large.png | Bin 0 -> 3088 bytes .../mpl-data/images/move-symbolic.svg | 73 + .../matplotlib/mpl-data/images/move.pdf | Bin 0 -> 1867 bytes .../matplotlib/mpl-data/images/move.png | Bin 0 -> 481 bytes .../matplotlib/mpl-data/images/move.svg | 73 + .../matplotlib/mpl-data/images/move_large.png | Bin 0 -> 767 bytes .../mpl-data/images/qt4_editor_options.pdf | Bin 0 -> 1568 bytes .../mpl-data/images/qt4_editor_options.png | Bin 0 -> 380 bytes .../mpl-data/images/qt4_editor_options.svg | 48 + .../images/qt4_editor_options_large.png | Bin 0 -> 619 bytes .../mpl-data/images/subplots-symbolic.svg | 81 + .../matplotlib/mpl-data/images/subplots.pdf | Bin 0 -> 1714 bytes .../matplotlib/mpl-data/images/subplots.png | Bin 0 -> 445 bytes .../matplotlib/mpl-data/images/subplots.svg | 81 + .../mpl-data/images/subplots_large.png | Bin 0 -> 662 bytes .../mpl-data/images/zoom_to_rect-symbolic.svg | 40 + .../mpl-data/images/zoom_to_rect.pdf | Bin 0 -> 1609 bytes .../mpl-data/images/zoom_to_rect.png | Bin 0 -> 530 bytes .../mpl-data/images/zoom_to_rect.svg | 40 + .../mpl-data/images/zoom_to_rect_large.png | Bin 0 -> 1016 bytes .../matplotlib/mpl-data/kpsewhich.lua | 3 + .../matplotlib/mpl-data/matplotlibrc | 798 + .../plot_directive/plot_directive.css | 16 + .../sample_data/Minduka_Present_Blue_Pack.png | Bin 0 -> 13634 bytes .../mpl-data/sample_data/README.txt | 2 + .../mpl-data/sample_data/Stocks.csv | 526 + .../axes_grid/bivariate_normal.npy | Bin 0 -> 1880 bytes .../mpl-data/sample_data/data_x_x2_x3.csv | 11 + .../matplotlib/mpl-data/sample_data/eeg.dat | Bin 0 -> 25600 bytes .../mpl-data/sample_data/embedding_in_wx3.xrc | 65 + .../matplotlib/mpl-data/sample_data/goog.npz | Bin 0 -> 22845 bytes .../mpl-data/sample_data/grace_hopper.jpg | Bin 0 -> 61306 bytes .../sample_data/jacksboro_fault_dem.npz | Bin 0 -> 174061 bytes .../matplotlib/mpl-data/sample_data/logo2.png | Bin 0 -> 22279 bytes .../mpl-data/sample_data/membrane.dat | Bin 0 -> 48000 bytes .../matplotlib/mpl-data/sample_data/msft.csv | 66 + .../mpl-data/sample_data/s1045.ima.gz | Bin 0 -> 33229 bytes .../mpl-data/sample_data/topobathy.npz | Bin 0 -> 45224 bytes .../stylelib/Solarize_Light2.mplstyle | 53 + .../stylelib/_classic_test_patch.mplstyle | 6 + .../stylelib/_mpl-gallery-nogrid.mplstyle | 19 + .../mpl-data/stylelib/_mpl-gallery.mplstyle | 19 + .../matplotlib/mpl-data/stylelib/bmh.mplstyle | 29 + .../mpl-data/stylelib/classic.mplstyle | 492 + .../stylelib/dark_background.mplstyle | 29 + .../mpl-data/stylelib/fast.mplstyle | 11 + .../stylelib/fivethirtyeight.mplstyle | 40 + .../mpl-data/stylelib/ggplot.mplstyle | 39 + .../mpl-data/stylelib/grayscale.mplstyle | 29 + .../stylelib/seaborn-v0_8-bright.mplstyle | 3 + .../stylelib/seaborn-v0_8-colorblind.mplstyle | 3 + .../seaborn-v0_8-dark-palette.mplstyle | 3 + .../stylelib/seaborn-v0_8-dark.mplstyle | 30 + .../stylelib/seaborn-v0_8-darkgrid.mplstyle | 30 + .../stylelib/seaborn-v0_8-deep.mplstyle | 3 + .../stylelib/seaborn-v0_8-muted.mplstyle | 3 + .../stylelib/seaborn-v0_8-notebook.mplstyle | 21 + .../stylelib/seaborn-v0_8-paper.mplstyle | 21 + .../stylelib/seaborn-v0_8-pastel.mplstyle | 3 + .../stylelib/seaborn-v0_8-poster.mplstyle | 21 + .../stylelib/seaborn-v0_8-talk.mplstyle | 21 + .../stylelib/seaborn-v0_8-ticks.mplstyle | 30 + .../stylelib/seaborn-v0_8-white.mplstyle | 30 + .../stylelib/seaborn-v0_8-whitegrid.mplstyle | 30 + .../mpl-data/stylelib/seaborn-v0_8.mplstyle | 57 + .../stylelib/tableau-colorblind10.mplstyle | 3 + .../site-packages/matplotlib/offsetbox.py | 1604 + .../site-packages/matplotlib/offsetbox.pyi | 321 + .../site-packages/matplotlib/patches.py | 4634 ++ .../site-packages/matplotlib/patches.pyi | 751 + .../site-packages/matplotlib/path.py | 1093 + .../site-packages/matplotlib/path.pyi | 140 + .../site-packages/matplotlib/patheffects.py | 513 + .../site-packages/matplotlib/patheffects.pyi | 106 + .../matplotlib/projections/__init__.py | 126 + .../matplotlib/projections/__init__.pyi | 15 + .../matplotlib/projections/geo.py | 510 + .../matplotlib/projections/geo.pyi | 112 + .../matplotlib/projections/polar.py | 1536 + .../matplotlib/projections/polar.pyi | 196 + .../site-packages/matplotlib/py.typed | 0 .../site-packages/matplotlib/pylab.py | 65 + .../site-packages/matplotlib/pyplot.py | 4373 ++ .../site-packages/matplotlib/quiver.py | 1181 + .../site-packages/matplotlib/quiver.pyi | 187 + .../site-packages/matplotlib/rcsetup.py | 1346 + .../site-packages/matplotlib/rcsetup.pyi | 157 + .../site-packages/matplotlib/sankey.py | 814 + .../site-packages/matplotlib/sankey.pyi | 61 + .../site-packages/matplotlib/scale.py | 756 + .../site-packages/matplotlib/scale.pyi | 178 + .../matplotlib/sphinxext/__init__.py | 0 .../matplotlib/sphinxext/figmpl_directive.py | 288 + .../matplotlib/sphinxext/mathmpl.py | 239 + .../matplotlib/sphinxext/plot_directive.py | 933 + .../site-packages/matplotlib/spines.py | 595 + .../site-packages/matplotlib/spines.pyi | 83 + .../site-packages/matplotlib/stackplot.py | 127 + .../site-packages/matplotlib/stackplot.pyi | 17 + .../site-packages/matplotlib/streamplot.py | 712 + .../site-packages/matplotlib/streamplot.pyi | 82 + .../matplotlib/style/__init__.py | 4 + .../site-packages/matplotlib/style/core.py | 245 + .../site-packages/matplotlib/style/core.pyi | 19 + .../site-packages/matplotlib/table.py | 831 + .../site-packages/matplotlib/table.pyi | 85 + .../matplotlib/testing/__init__.py | 174 + .../matplotlib/testing/__init__.pyi | 49 + .../matplotlib/testing/_markers.py | 49 + .../matplotlib/testing/compare.py | 515 + .../matplotlib/testing/compare.pyi | 32 + .../matplotlib/testing/conftest.py | 100 + .../matplotlib/testing/conftest.pyi | 12 + .../matplotlib/testing/decorators.py | 464 + .../matplotlib/testing/decorators.pyi | 25 + .../matplotlib/testing/exceptions.py | 4 + .../matplotlib/testing/jpl_units/Duration.py | 138 + .../matplotlib/testing/jpl_units/Epoch.py | 211 + .../testing/jpl_units/EpochConverter.py | 96 + .../testing/jpl_units/StrConverter.py | 97 + .../matplotlib/testing/jpl_units/UnitDbl.py | 180 + .../testing/jpl_units/UnitDblConverter.py | 85 + .../testing/jpl_units/UnitDblFormatter.py | 28 + .../matplotlib/testing/jpl_units/__init__.py | 76 + .../matplotlib/testing/widgets.py | 119 + .../matplotlib/testing/widgets.pyi | 31 + .../matplotlib/tests/__init__.py | 10 + .../matplotlib/tests/conftest.py | 2 + .../matplotlib/tests/test_afm.py | 137 + .../matplotlib/tests/test_agg.py | 338 + .../matplotlib/tests/test_agg_filter.py | 33 + .../matplotlib/tests/test_animation.py | 553 + .../matplotlib/tests/test_api.py | 116 + .../matplotlib/tests/test_arrow_patches.py | 177 + .../matplotlib/tests/test_artist.py | 564 + .../matplotlib/tests/test_axes.py | 8839 ++++ .../matplotlib/tests/test_axis.py | 10 + .../matplotlib/tests/test_backend_bases.py | 441 + .../matplotlib/tests/test_backend_cairo.py | 48 + .../matplotlib/tests/test_backend_gtk3.py | 51 + .../matplotlib/tests/test_backend_macosx.py | 46 + .../matplotlib/tests/test_backend_nbagg.py | 30 + .../matplotlib/tests/test_backend_pdf.py | 445 + .../matplotlib/tests/test_backend_pgf.py | 404 + .../matplotlib/tests/test_backend_ps.py | 380 + .../matplotlib/tests/test_backend_qt.py | 377 + .../matplotlib/tests/test_backend_svg.py | 643 + .../matplotlib/tests/test_backend_template.py | 51 + .../matplotlib/tests/test_backend_tk.py | 265 + .../matplotlib/tests/test_backend_tools.py | 20 + .../matplotlib/tests/test_backend_webagg.py | 33 + .../tests/test_backends_interactive.py | 841 + .../matplotlib/tests/test_basic.py | 46 + .../matplotlib/tests/test_bbox_tight.py | 174 + .../matplotlib/tests/test_category.py | 323 + .../matplotlib/tests/test_cbook.py | 940 + .../matplotlib/tests/test_collections.py | 1282 + .../matplotlib/tests/test_colorbar.py | 1238 + .../matplotlib/tests/test_colors.py | 1710 + .../matplotlib/tests/test_compare_images.py | 73 + .../tests/test_constrainedlayout.py | 694 + .../matplotlib/tests/test_container.py | 37 + .../matplotlib/tests/test_contour.py | 899 + .../matplotlib/tests/test_cycles.py | 170 + .../matplotlib/tests/test_dates.py | 1411 + .../matplotlib/tests/test_determinism.py | 138 + .../matplotlib/tests/test_doc.py | 34 + .../matplotlib/tests/test_dviread.py | 77 + .../matplotlib/tests/test_figure.py | 1661 + .../matplotlib/tests/test_font_manager.py | 348 + .../tests/test_fontconfig_pattern.py | 77 + .../matplotlib/tests/test_ft2font.py | 106 + .../matplotlib/tests/test_getattr.py | 35 + .../matplotlib/tests/test_gridspec.py | 37 + .../matplotlib/tests/test_image.py | 1505 + .../matplotlib/tests/test_legend.py | 1343 + .../matplotlib/tests/test_lines.py | 438 + .../matplotlib/tests/test_marker.py | 303 + .../matplotlib/tests/test_mathtext.py | 560 + .../matplotlib/tests/test_matplotlib.py | 77 + .../matplotlib/tests/test_mlab.py | 1022 + .../matplotlib/tests/test_offsetbox.py | 452 + .../matplotlib/tests/test_patches.py | 933 + .../matplotlib/tests/test_path.py | 541 + .../matplotlib/tests/test_patheffects.py | 194 + .../matplotlib/tests/test_pickle.py | 303 + .../matplotlib/tests/test_png.py | 50 + .../matplotlib/tests/test_polar.py | 448 + .../matplotlib/tests/test_preprocess_data.py | 288 + .../matplotlib/tests/test_pyplot.py | 459 + .../matplotlib/tests/test_quiver.py | 279 + .../matplotlib/tests/test_rcparams.py | 630 + .../matplotlib/tests/test_sankey.py | 105 + .../matplotlib/tests/test_scale.py | 295 + .../matplotlib/tests/test_simplification.py | 518 + .../matplotlib/tests/test_skew.py | 168 + .../matplotlib/tests/test_sphinxext.py | 225 + .../matplotlib/tests/test_spines.py | 156 + .../matplotlib/tests/test_streamplot.py | 169 + .../matplotlib/tests/test_style.py | 198 + .../matplotlib/tests/test_subplots.py | 285 + .../matplotlib/tests/test_table.py | 231 + .../matplotlib/tests/test_testing.py | 41 + .../matplotlib/tests/test_texmanager.py | 74 + .../matplotlib/tests/test_text.py | 966 + .../matplotlib/tests/test_textpath.py | 10 + .../matplotlib/tests/test_ticker.py | 1791 + .../matplotlib/tests/test_tightlayout.py | 393 + .../matplotlib/tests/test_transforms.py | 788 + .../matplotlib/tests/test_triangulation.py | 1403 + .../matplotlib/tests/test_ttconv.py | 17 + .../matplotlib/tests/test_type1font.py | 160 + .../matplotlib/tests/test_units.py | 285 + .../matplotlib/tests/test_usetex.py | 187 + .../matplotlib/tests/test_widgets.py | 1771 + .../site-packages/matplotlib/texmanager.py | 368 + .../site-packages/matplotlib/texmanager.pyi | 38 + .../site-packages/matplotlib/text.py | 2023 + .../site-packages/matplotlib/text.pyi | 214 + .../site-packages/matplotlib/textpath.py | 397 + .../site-packages/matplotlib/textpath.pyi | 74 + .../site-packages/matplotlib/ticker.py | 2942 ++ .../site-packages/matplotlib/ticker.pyi | 301 + .../site-packages/matplotlib/transforms.py | 2975 ++ .../site-packages/matplotlib/transforms.pyi | 335 + .../site-packages/matplotlib/tri/__init__.py | 23 + .../matplotlib/tri/_triangulation.py | 247 + .../matplotlib/tri/_triangulation.pyi | 33 + .../matplotlib/tri/_tricontour.py | 272 + .../matplotlib/tri/_tricontour.pyi | 52 + .../matplotlib/tri/_trifinder.py | 96 + .../matplotlib/tri/_trifinder.pyi | 10 + .../matplotlib/tri/_triinterpolate.py | 1574 + .../matplotlib/tri/_triinterpolate.pyi | 30 + .../matplotlib/tri/_tripcolor.py | 149 + .../matplotlib/tri/_tripcolor.pyi | 71 + .../site-packages/matplotlib/tri/_triplot.py | 86 + .../site-packages/matplotlib/tri/_triplot.pyi | 15 + .../matplotlib/tri/_trirefine.py | 307 + .../matplotlib/tri/_trirefine.pyi | 31 + .../site-packages/matplotlib/tri/_tritools.py | 263 + .../matplotlib/tri/_tritools.pyi | 12 + .../matplotlib/tri/triangulation.py | 9 + .../matplotlib/tri/tricontour.py | 9 + .../site-packages/matplotlib/tri/trifinder.py | 9 + .../matplotlib/tri/triinterpolate.py | 9 + .../site-packages/matplotlib/tri/tripcolor.py | 9 + .../site-packages/matplotlib/tri/triplot.py | 9 + .../site-packages/matplotlib/tri/trirefine.py | 9 + .../site-packages/matplotlib/tri/tritools.py | 9 + .../site-packages/matplotlib/typing.py | 60 + .../site-packages/matplotlib/units.py | 195 + .../site-packages/matplotlib/widgets.py | 4243 ++ .../site-packages/matplotlib/widgets.pyi | 487 + .../mpl_toolkits/axes_grid1/__init__.py | 10 + .../axes_grid1/anchored_artists.py | 462 + .../mpl_toolkits/axes_grid1/axes_divider.py | 694 + .../mpl_toolkits/axes_grid1/axes_grid.py | 550 + .../mpl_toolkits/axes_grid1/axes_rgb.py | 157 + .../mpl_toolkits/axes_grid1/axes_size.py | 248 + .../mpl_toolkits/axes_grid1/inset_locator.py | 561 + .../mpl_toolkits/axes_grid1/mpl_axes.py | 128 + .../mpl_toolkits/axes_grid1/parasite_axes.py | 257 + .../mpl_toolkits/axes_grid1/tests/__init__.py | 10 + .../mpl_toolkits/axes_grid1/tests/conftest.py | 2 + .../axes_grid1/tests/test_axes_grid1.py | 793 + .../mpl_toolkits/axisartist/__init__.py | 13 + .../mpl_toolkits/axisartist/angle_helper.py | 394 + .../mpl_toolkits/axisartist/axes_divider.py | 2 + .../mpl_toolkits/axisartist/axes_grid.py | 23 + .../mpl_toolkits/axisartist/axes_rgb.py | 18 + .../mpl_toolkits/axisartist/axis_artist.py | 1115 + .../mpl_toolkits/axisartist/axisline_style.py | 193 + .../mpl_toolkits/axisartist/axislines.py | 531 + .../mpl_toolkits/axisartist/floating_axes.py | 298 + .../mpl_toolkits/axisartist/grid_finder.py | 335 + .../axisartist/grid_helper_curvelinear.py | 336 + .../mpl_toolkits/axisartist/parasite_axes.py | 7 + .../mpl_toolkits/axisartist/tests/__init__.py | 10 + .../mpl_toolkits/axisartist/tests/conftest.py | 2 + .../axisartist/tests/test_angle_helper.py | 141 + .../axisartist/tests/test_axis_artist.py | 99 + .../axisartist/tests/test_axislines.py | 147 + .../axisartist/tests/test_floating_axes.py | 115 + .../axisartist/tests/test_grid_finder.py | 34 + .../tests/test_grid_helper_curvelinear.py | 207 + .../mpl_toolkits/mplot3d/__init__.py | 3 + .../mpl_toolkits/mplot3d/art3d.py | 1252 + .../mpl_toolkits/mplot3d/axes3d.py | 3448 ++ .../mpl_toolkits/mplot3d/axis3d.py | 753 + .../mpl_toolkits/mplot3d/proj3d.py | 259 + .../mpl_toolkits/mplot3d/tests/__init__.py | 10 + .../mpl_toolkits/mplot3d/tests/conftest.py | 2 + .../mpl_toolkits/mplot3d/tests/test_art3d.py | 56 + .../mpl_toolkits/mplot3d/tests/test_axes3d.py | 2281 + .../mplot3d/tests/test_legend3d.py | 117 + .../mypy_extensions-1.0.0.dist-info/INSTALLER | 1 + .../mypy_extensions-1.0.0.dist-info/LICENSE | 27 + .../mypy_extensions-1.0.0.dist-info/METADATA | 29 + .../mypy_extensions-1.0.0.dist-info/RECORD | 8 + .../mypy_extensions-1.0.0.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/mypy_extensions.py | 213 + .../pathspec-0.12.1.dist-info/INSTALLER | 1 + .../pathspec-0.12.1.dist-info/LICENSE | 373 + .../pathspec-0.12.1.dist-info/METADATA | 647 + .../pathspec-0.12.1.dist-info/RECORD | 22 + .../pathspec-0.12.1.dist-info/WHEEL | 4 + .../site-packages/pathspec/__init__.py | 76 + .../python3.9/site-packages/pathspec/_meta.py | 58 + .../site-packages/pathspec/gitignore.py | 157 + .../site-packages/pathspec/pathspec.py | 394 + .../site-packages/pathspec/pattern.py | 213 + .../pathspec/patterns/__init__.py | 11 + .../pathspec/patterns/gitwildmatch.py | 421 + .../python3.9/site-packages/pathspec/py.typed | 1 + .../python3.9/site-packages/pathspec/util.py | 792 + .../pillow-10.2.0.dist-info/INSTALLER | 1 + .../pillow-10.2.0.dist-info/LICENSE | 1343 + .../pillow-10.2.0.dist-info/METADATA | 182 + .../pillow-10.2.0.dist-info/RECORD | 223 + .../pillow-10.2.0.dist-info/WHEEL | 5 + .../pillow-10.2.0.dist-info/top_level.txt | 1 + .../pillow-10.2.0.dist-info/zip-safe | 1 + .../pluggy-1.3.0.dist-info/INSTALLER | 1 + .../pluggy-1.3.0.dist-info/LICENSE | 21 + .../pluggy-1.3.0.dist-info/METADATA | 140 + .../pluggy-1.3.0.dist-info/RECORD | 21 + .../pluggy-1.3.0.dist-info/WHEEL | 5 + .../pluggy-1.3.0.dist-info/top_level.txt | 1 + .../site-packages/pluggy/__init__.py | 33 + .../site-packages/pluggy/_callers.py | 152 + .../python3.9/site-packages/pluggy/_hooks.py | 691 + .../site-packages/pluggy/_manager.py | 505 + .../python3.9/site-packages/pluggy/_result.py | 118 + .../site-packages/pluggy/_tracing.py | 72 + .../site-packages/pluggy/_version.py | 4 + .../python3.9/site-packages/pluggy/py.typed | 0 .../py-1.11.0.dist-info/INSTALLER | 1 + .../site-packages/py-1.11.0.dist-info/LICENSE | 19 + .../py-1.11.0.dist-info/METADATA | 69 + .../site-packages/py-1.11.0.dist-info/RECORD | 101 + .../site-packages/py-1.11.0.dist-info/WHEEL | 6 + .../py-1.11.0.dist-info/top_level.txt | 1 + dbdpy-env/lib/python3.9/site-packages/py.py | 10 + .../python3.9/site-packages/py/__init__.py | 156 + .../python3.9/site-packages/py/__init__.pyi | 20 + .../python3.9/site-packages/py/__metainfo.py | 2 + .../python3.9/site-packages/py/_builtin.py | 149 + .../site-packages/py/_code/__init__.py | 1 + .../site-packages/py/_code/_assertionnew.py | 322 + .../site-packages/py/_code/_assertionold.py | 556 + .../site-packages/py/_code/_py2traceback.py | 79 + .../site-packages/py/_code/assertion.py | 90 + .../python3.9/site-packages/py/_code/code.py | 796 + .../site-packages/py/_code/source.py | 410 + .../lib/python3.9/site-packages/py/_error.py | 91 + .../site-packages/py/_io/__init__.py | 1 + .../python3.9/site-packages/py/_io/capture.py | 371 + .../site-packages/py/_io/saferepr.py | 71 + .../site-packages/py/_io/terminalwriter.py | 423 + .../site-packages/py/_log/__init__.py | 2 + .../python3.9/site-packages/py/_log/log.py | 206 + .../site-packages/py/_log/warning.py | 79 + .../site-packages/py/_path/__init__.py | 1 + .../site-packages/py/_path/cacheutil.py | 114 + .../site-packages/py/_path/common.py | 459 + .../python3.9/site-packages/py/_path/local.py | 1030 + .../site-packages/py/_path/svnurl.py | 380 + .../python3.9/site-packages/py/_path/svnwc.py | 1240 + .../site-packages/py/_process/__init__.py | 1 + .../site-packages/py/_process/cmdexec.py | 49 + .../site-packages/py/_process/forkedfunc.py | 120 + .../site-packages/py/_process/killproc.py | 23 + .../lib/python3.9/site-packages/py/_std.py | 27 + .../py/_vendored_packages/__init__.py | 0 .../apipkg-2.0.0.dist-info/INSTALLER | 1 + .../apipkg-2.0.0.dist-info/LICENSE | 18 + .../apipkg-2.0.0.dist-info/METADATA | 125 + .../apipkg-2.0.0.dist-info/RECORD | 11 + .../apipkg-2.0.0.dist-info/REQUESTED | 0 .../apipkg-2.0.0.dist-info/WHEEL | 6 + .../apipkg-2.0.0.dist-info/top_level.txt | 1 + .../py/_vendored_packages/apipkg/__init__.py | 217 + .../py/_vendored_packages/apipkg/version.py | 5 + .../iniconfig-1.1.1.dist-info/INSTALLER | 1 + .../iniconfig-1.1.1.dist-info/LICENSE | 19 + .../iniconfig-1.1.1.dist-info/METADATA | 78 + .../iniconfig-1.1.1.dist-info/RECORD | 11 + .../iniconfig-1.1.1.dist-info/REQUESTED | 0 .../iniconfig-1.1.1.dist-info/WHEEL | 6 + .../iniconfig-1.1.1.dist-info/top_level.txt | 1 + .../_vendored_packages/iniconfig/__init__.py | 165 + .../_vendored_packages/iniconfig/__init__.pyi | 31 + .../py/_vendored_packages/iniconfig/py.typed | 0 .../python3.9/site-packages/py/_version.py | 5 + .../lib/python3.9/site-packages/py/_xmlgen.py | 255 + .../lib/python3.9/site-packages/py/error.pyi | 129 + .../python3.9/site-packages/py/iniconfig.pyi | 31 + .../lib/python3.9/site-packages/py/io.pyi | 130 + .../lib/python3.9/site-packages/py/path.pyi | 197 + .../lib/python3.9/site-packages/py/py.typed | 0 .../lib/python3.9/site-packages/py/test.py | 10 + .../lib/python3.9/site-packages/py/xml.pyi | 25 + .../pycodestyle-2.11.1.dist-info/INSTALLER | 1 + .../pycodestyle-2.11.1.dist-info/LICENSE | 25 + .../pycodestyle-2.11.1.dist-info/METADATA | 131 + .../pycodestyle-2.11.1.dist-info/RECORD | 10 + .../pycodestyle-2.11.1.dist-info/WHEEL | 6 + .../entry_points.txt | 2 + .../top_level.txt | 1 + .../python3.9/site-packages/pycodestyle.py | 2655 + .../lib/python3.9/site-packages/pylab.py | 3 + .../pyparsing-3.1.1.dist-info/INSTALLER | 1 + .../pyparsing-3.1.1.dist-info/LICENSE | 18 + .../pyparsing-3.1.1.dist-info/METADATA | 126 + .../pyparsing-3.1.1.dist-info/RECORD | 28 + .../pyparsing-3.1.1.dist-info/WHEEL | 4 + .../site-packages/pyparsing/__init__.py | 325 + .../site-packages/pyparsing/actions.py | 217 + .../site-packages/pyparsing/common.py | 432 + .../python3.9/site-packages/pyparsing/core.py | 6159 +++ .../pyparsing/diagram/__init__.py | 656 + .../site-packages/pyparsing/exceptions.py | 299 + .../site-packages/pyparsing/helpers.py | 1100 + .../site-packages/pyparsing/py.typed | 0 .../site-packages/pyparsing/results.py | 796 + .../site-packages/pyparsing/testing.py | 331 + .../site-packages/pyparsing/unicode.py | 361 + .../python3.9/site-packages/pyparsing/util.py | 284 + .../pytest-7.4.4.dist-info/INSTALLER | 1 + .../pytest-7.4.4.dist-info/LICENSE | 21 + .../pytest-7.4.4.dist-info/METADATA | 222 + .../pytest-7.4.4.dist-info/RECORD | 154 + .../pytest-7.4.4.dist-info/REQUESTED | 0 .../pytest-7.4.4.dist-info/WHEEL | 5 + .../pytest-7.4.4.dist-info/entry_points.txt | 3 + .../pytest-7.4.4.dist-info/top_level.txt | 3 + .../site-packages/pytest/__init__.py | 171 + .../site-packages/pytest/__main__.py | 5 + .../python3.9/site-packages/pytest/py.typed | 0 .../pytest_black-0.3.12.dist-info/INSTALLER | 1 + .../pytest_black-0.3.12.dist-info/LICENSE | 22 + .../pytest_black-0.3.12.dist-info/METADATA | 112 + .../pytest_black-0.3.12.dist-info/RECORD | 10 + .../pytest_black-0.3.12.dist-info/REQUESTED | 0 .../pytest_black-0.3.12.dist-info/WHEEL | 5 + .../entry_points.txt | 3 + .../top_level.txt | 1 + .../python3.9/site-packages/pytest_black.py | 118 + .../INSTALLER | 1 + .../LICENSE | 21 + .../METADATA | 74 + .../pytest_pycodestyle-2.3.1.dist-info/RECORD | 10 + .../REQUESTED | 0 .../pytest_pycodestyle-2.3.1.dist-info/WHEEL | 5 + .../entry_points.txt | 3 + .../top_level.txt | 1 + .../site-packages/pytest_pycodestyle.py | 98 + .../python3.9/site-packages/tests/__init__.py | 11 + .../lib/python3.9/site-packages/tests/data.py | 647 + .../tests/data_expand_hr_mesgs.py | 16012 ++++++ .../tests/fits/ActivityDevFields.fit | Bin 0 -> 94199 bytes .../tests/fits/HrmPluginTestActivity.fit | Bin 0 -> 25121 bytes .../tests/fits/WithGearChangeData.fit | Bin 0 -> 90970 bytes .../site-packages/tests/test_accumulator.py | 27 + .../site-packages/tests/test_bitstream.py | 165 + .../tests/test_crc_calculator.py | 45 + .../site-packages/tests/test_decoder.py | 561 + .../site-packages/tests/test_errors.py | 56 + .../site-packages/tests/test_hr_mesg_utils.py | 51 + .../site-packages/tests/test_stream.py | 234 + .../site-packages/tests/test_util.py | 30 + .../toml-0.10.2.dist-info/INSTALLER | 1 + .../toml-0.10.2.dist-info/LICENSE | 27 + .../toml-0.10.2.dist-info/METADATA | 255 + .../toml-0.10.2.dist-info/RECORD | 16 + .../site-packages/toml-0.10.2.dist-info/WHEEL | 6 + .../toml-0.10.2.dist-info/top_level.txt | 1 + .../python3.9/site-packages/toml/__init__.py | 25 + .../python3.9/site-packages/toml/decoder.py | 1057 + .../python3.9/site-packages/toml/encoder.py | 304 + .../python3.9/site-packages/toml/ordered.py | 15 + .../lib/python3.9/site-packages/toml/tz.py | 24 + .../tomli-2.0.1.dist-info/INSTALLER | 1 + .../tomli-2.0.1.dist-info/LICENSE | 21 + .../tomli-2.0.1.dist-info/METADATA | 206 + .../tomli-2.0.1.dist-info/RECORD | 14 + .../site-packages/tomli-2.0.1.dist-info/WHEEL | 4 + .../python3.9/site-packages/tomli/__init__.py | 11 + .../python3.9/site-packages/tomli/_parser.py | 691 + .../lib/python3.9/site-packages/tomli/_re.py | 107 + .../python3.9/site-packages/tomli/_types.py | 10 + .../python3.9/site-packages/tomli/py.typed | 1 + .../zope.interface-6.1-py3.9-nspkg.pth | 1 + .../zope.interface-6.1.dist-info/INSTALLER | 1 + .../zope.interface-6.1.dist-info/LICENSE.txt | 44 + .../zope.interface-6.1.dist-info/METADATA | 1120 + .../zope.interface-6.1.dist-info/RECORD | 110 + .../zope.interface-6.1.dist-info/WHEEL | 5 + .../namespace_packages.txt | 1 + .../top_level.txt | 1 + .../site-packages/zope/interface/__init__.py | 93 + .../site-packages/zope/interface/_compat.py | 135 + .../site-packages/zope/interface/_flatten.py | 35 + .../_zope_interface_coptimizations.c | 2101 + ...erface_coptimizations.cpython-39-darwin.so | Bin 0 -> 77904 bytes .../site-packages/zope/interface/adapter.py | 1015 + .../site-packages/zope/interface/advice.py | 118 + .../zope/interface/common/__init__.py | 272 + .../zope/interface/common/builtins.py | 119 + .../zope/interface/common/collections.py | 253 + .../zope/interface/common/idatetime.py | 606 + .../zope/interface/common/interfaces.py | 208 + .../site-packages/zope/interface/common/io.py | 43 + .../zope/interface/common/mapping.py | 168 + .../zope/interface/common/numbers.py | 65 + .../zope/interface/common/sequence.py | 189 + .../zope/interface/common/tests/__init__.py | 136 + .../interface/common/tests/basemapping.py | 107 + .../interface/common/tests/test_builtins.py | 43 + .../common/tests/test_collections.py | 142 + .../interface/common/tests/test_idatetime.py | 37 + .../common/tests/test_import_interfaces.py | 20 + .../zope/interface/common/tests/test_io.py | 42 + .../interface/common/tests/test_numbers.py | 41 + .../zope/interface/declarations.py | 1188 + .../site-packages/zope/interface/document.py | 124 + .../zope/interface/exceptions.py | 275 + .../site-packages/zope/interface/interface.py | 1131 + .../zope/interface/interfaces.py | 1480 + .../site-packages/zope/interface/registry.py | 723 + .../site-packages/zope/interface/ro.py | 665 + .../zope/interface/tests/__init__.py | 115 + .../zope/interface/tests/advisory_testing.py | 26 + .../zope/interface/tests/dummy.py | 23 + .../zope/interface/tests/idummy.py | 23 + .../site-packages/zope/interface/tests/m1.py | 21 + .../site-packages/zope/interface/tests/odd.py | 124 + .../zope/interface/tests/test_adapter.py | 2107 + .../zope/interface/tests/test_advice.py | 191 + .../interface/tests/test_compile_flags.py | 29 + .../zope/interface/tests/test_declarations.py | 2453 + .../zope/interface/tests/test_document.py | 505 + .../zope/interface/tests/test_element.py | 31 + .../zope/interface/tests/test_exceptions.py | 184 + .../zope/interface/tests/test_interface.py | 2638 + .../zope/interface/tests/test_interfaces.py | 128 + .../interface/tests/test_odd_declarations.py | 255 + .../zope/interface/tests/test_registry.py | 3057 ++ .../zope/interface/tests/test_ro.py | 426 + .../zope/interface/tests/test_sorting.py | 64 + .../zope/interface/tests/test_verify.py | 656 + .../site-packages/zope/interface/verify.py | 185 + dbdpy-env/share/man/man1/ttx.1 | 225 + pytest.ini | 2 - setup.cfg | 5 + 1627 files changed, 713193 insertions(+), 3 deletions(-) create mode 100755 dbdpy-env/bin/black create mode 100755 dbdpy-env/bin/blackd create mode 100755 dbdpy-env/bin/fonttools create mode 100755 dbdpy-env/bin/py.test create mode 100755 dbdpy-env/bin/pycodestyle create mode 100755 dbdpy-env/bin/pyftmerge create mode 100755 dbdpy-env/bin/pyftsubset create mode 100755 dbdpy-env/bin/pytest create mode 100755 dbdpy-env/bin/ttx create mode 100755 dbdpy-env/lib/python3.9/site-packages/629853fdff261ed89b74__mypyc.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/LICENSE.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/interfaces.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/pytz.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/pytz_support.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/tests/julian_testdata.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/DateTime/tests/test_datetime.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libXau.6.0.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlicommon.1.1.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlidec.1.1.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libfreetype.6.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libharfbuzz.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libjpeg.62.4.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/liblcms2.2.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/liblzma.5.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libopenjp2.2.5.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libpng16.16.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libsharpyuv.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libtiff.6.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebp.7.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpdemux.2.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpmux.3.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libxcb.1.1.0.dylib create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libz.1.3.dylib create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/BdfFontFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/BlpImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/BmpImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/BufrStubImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ContainerIO.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/CurImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/DcxImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/DdsImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/EpsImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ExifTags.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/FitsImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/FliImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/FontFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/FpxImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/FtexImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GbrImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GdImageFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GifImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GimpGradientFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GimpPaletteFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/GribStubImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/Hdf5StubImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/IcnsImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/IcoImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/Image.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageChops.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageCms.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageColor.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw2.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageEnhance.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageFilter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageFont.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageGrab.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageMath.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageMode.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageMorph.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageOps.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImagePalette.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImagePath.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageQt.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageSequence.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageShow.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageStat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageTk.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageTransform.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImageWin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/ImtImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/IptcImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/Jpeg2KImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/JpegImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/JpegPresets.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/McIdasImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/MicImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/MpegImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/MpoImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/MspImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PSDraw.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PaletteFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PalmImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PcdImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PcfFontFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PcxImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PdfImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PdfParser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PixarImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PngImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PpmImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PsdImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/PyAccess.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/QoiImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/SgiImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/SpiderImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/SunImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/TarIO.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/TgaImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/TiffImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/TiffTags.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/WalImageFile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/WebPImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/WmfImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/XVThumbImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/XbmImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/XpmImagePlugin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_binary.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_deprecate.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imaging.cpython-39-darwin.so create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingcms.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingcms.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingmath.cpython-39-darwin.so create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingmorph.cpython-39-darwin.so create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_imagingtk.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_tkinter_finder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_typing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/_version.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/PIL/_webp.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/PIL/features.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_black_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_argcomplete.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_code/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_code/code.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_code/source.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_io/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_io/saferepr.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_io/terminalwriter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_io/wcwidth.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_py/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_py/error.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_py/path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/rewrite.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/truncate.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/cacheprovider.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/capture.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/config/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/config/argparsing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/config/compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/config/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/config/findpaths.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/debugging.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/deprecated.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/doctest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/faulthandler.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/fixtures.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/freeze_support.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/helpconfig.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/hookspec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/junitxml.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/legacypath.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/logging.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/main.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/mark/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/mark/expression.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/mark/structures.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/monkeypatch.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/nodes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/nose.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/outcomes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/pastebin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/pathlib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/pytester.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/pytester_assertions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/python.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/python_api.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/python_path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/recwarn.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/reports.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/runner.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/scope.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/setuponly.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/setupplan.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/skipping.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/stash.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/stepwise.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/terminal.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/threadexception.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/timing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/tmpdir.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/unittest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/unraisableexception.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/warning_types.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/_pytest/warnings.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/AUTHORS.md create mode 100644 dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/LICENSE create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/__init__.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/__main__.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/_width_table.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/_width_table.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/brackets.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/brackets.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/cache.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/cache.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/comments.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/comments.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/concurrency.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/const.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/const.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/debug.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/files.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/linegen.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/linegen.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/lines.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/lines.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/mode.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/mode.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/nodes.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/nodes.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/numerics.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/numerics.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/output.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/parsing.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/parsing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/py.typed create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/ranges.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/ranges.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/report.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/rusty.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/rusty.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/strings.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/strings.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/black/trans.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/black/trans.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/blackd/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/blackd/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/blackd/middlewares.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/Grammar.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/PatternGrammar.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/README create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/__init__.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/conv.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/conv.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/grammar.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/grammar.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/parse.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/parse.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/token.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/token.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/blib2to3/pytree.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/blib2to3/pytree.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/_compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/_termui_impl.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/_textwrap.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/_winconsole.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/core.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/decorators.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/formatting.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/globals.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/parser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/shell_completion.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/termui.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/testing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/types.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/click/utils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/__init__.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/contourpy/_contourpy.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/_contourpy.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/array.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/chunk.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/convert.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/dechunk.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/enum_util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/typecheck.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/types.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/_build_config.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_renderer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/data.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_renderer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/contourpy/util/renderer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/cycler/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/afmLib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/agl.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/specializer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/width.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/builder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/errors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/geometry.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/table_builder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/unbuilder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/config/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/benchmark.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cli.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/errors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/ufo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/split.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/statNames.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/types.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/encodings/MacRoman.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/encodings/StandardEncoding.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/encodings/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/encodings/codecs.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/ast.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/builder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/error.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lexer.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lexer.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lexer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/location.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lookupDebugInfo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/parser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/variableScalar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/fontBuilder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/help.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/base.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/cmap.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/layout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/options.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/tables.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/unicode.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/merge/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/arrayTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/classifyTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cliTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/configTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cython.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/dictTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/eexec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/encodingTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/etree.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/filenames.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/fixedTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/intTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/loggingTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macCreatorType.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macRes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psLib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psOperators.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/py23.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/roundTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/sstruct.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/symfont.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/testTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/textTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/timeTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/transform.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/treeTools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/vector.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/visitor.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlReader.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlWriter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/builder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/error.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/maxContextCalc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/gpos.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/areaPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/basePen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/boundsPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cairoPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cocoaPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cu2quPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/explicitClosingLinePen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/filterPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/freetypePen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/hashPointPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/perimeterPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointInsidePen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qtPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qu2cuPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/quartzPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/recordingPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reportLabPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reverseContourPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/roundingPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/statisticsPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/svgPathPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/t2CharStringPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/teePen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/transformPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/ttGlyphPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/pens/wxPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/benchmark.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/cli.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/subset/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/subset/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/subset/cff.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/subset/svg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/subset/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/svgLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/svgLib/path/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/svgLib/path/arc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/svgLib/path/parser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/svgLib/path/shapes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/t1Lib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/tfmLib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/macUtils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/removeOverlaps.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/scaleUpem.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/sfnt.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/standardGlyphOrder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/B_A_S_E_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/BitmapGlyphMetrics.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_B_D_T_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_B_L_C_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_F_F_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_F_F__2.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_O_L_R_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/C_P_A_L_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/D_S_I_G_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/D__e_b_g.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/DefaultTable.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/E_B_D_T_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/E_B_L_C_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/F_F_T_M_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/F__e_a_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G_D_E_F_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G_M_A_P_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G_P_K_G_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G_P_O_S_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G_S_U_B_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G__l_a_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/G__l_o_c.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/H_V_A_R_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/J_S_T_F_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/L_T_S_H_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/M_A_T_H_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/M_E_T_A_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/M_V_A_R_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/O_S_2f_2.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/S_I_N_G_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/S_T_A_T_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/S_V_G_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/S__i_l_f.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/S__i_l_l.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_B_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_C_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_D_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_J_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_P_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_S_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I_V_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I__0.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I__1.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I__2.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I__3.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_S_I__5.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/T_T_F_A_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/TupleVariation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/V_D_M_X_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/V_O_R_G_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/V_V_A_R_.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_a_n_k_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_a_v_a_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_b_s_l_n.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_c_i_d_g.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_c_m_a_p.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_c_v_a_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_c_v_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_f_e_a_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_f_p_g_m.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_f_v_a_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_g_a_s_p.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_g_c_i_d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_g_l_y_f.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_g_v_a_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_h_d_m_x.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_h_e_a_d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_h_h_e_a.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_h_m_t_x.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_k_e_r_n.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_l_c_a_r.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_l_o_c_a.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_l_t_a_g.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_m_a_x_p.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_m_e_t_a.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_m_o_r_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_m_o_r_x.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_n_a_m_e.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_o_p_b_d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_p_o_s_t.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_p_r_e_p.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_p_r_o_p.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_s_b_i_x.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_t_r_a_k.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_v_h_e_a.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/_v_m_t_x.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/asciiTable.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/grUtils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/otBase.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/otConverters.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/otData.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/otTables.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/otTraverse.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/sbixGlyph.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/sbixStrike.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/table_API_readme.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/tables/ttProgram.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/ttCollection.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/ttFont.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/ttGlyphSet.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/ttVisitor.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttLib/woff2.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ttx.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/converters.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/errors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/etree.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/filenames.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/glifLib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/kerning.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/plistlib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/pointPen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/utils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/ufoLib/validators.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicode.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicodedata/Blocks.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicodedata/OTTags.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicodedata/ScriptExtensions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicodedata/Scripts.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/unicodedata/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/avar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/avarPlanner.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/builder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/cff.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/errors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/featureVars.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/instancer/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/instancer/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/instancer/featureVars.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/instancer/names.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/instancer/solver.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolatable.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolatableHelpers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolatablePlot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolatableTestContourOrder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolatableTestStartingPoint.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/interpolate_layout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/iup.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/iup.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/iup.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/merger.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/models.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/mutator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/mvar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/plot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/stat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/varLib/varStore.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/ast.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/error.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/lexer.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/parser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fontTools/voltLib/voltToFea.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/fonttools-4.47.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk-21.126.0.dist-info/zip-safe create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/accumulator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/bitstream.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/crc_calculator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/decoder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/fit.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/hr_mesg_utils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/profile.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/stream.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/garmin_fit_sdk/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources-6.1.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/_adapters.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/_common.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/_compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/_itertools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/abc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/readers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/simple.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/_compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/_path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/binary.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/subdirectory/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/subdirectory/binary.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/utf-16.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data01/utf-8.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/one/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/one/resource1.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/two/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/data02/two/resource2.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/namespacedata01/binary.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/namespacedata01/utf-16.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/namespacedata01/utf-8.file create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_compatibilty_files.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_contents.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_custom.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_files.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_open.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_read.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_reader.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/test_resource.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/importlib_resources/tests/zip.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig-2.0.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig-2.0.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig-2.0.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig-2.0.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig-2.0.0.dist-info/licenses/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig/_parse.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/iniconfig/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver-1.4.5.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver/__init__.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/kiwisolver/_cext.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver/_cext.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/kiwisolver/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_AMSFONTS create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_BAKOMA create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_CARLOGO create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_COLORBREWER create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_COURIERTEN create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_JSXTOOLS_RESIZE_OBSERVER create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_QHULL create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_QT4_EDITOR create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_SOLARIZED create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_STIX create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/LICENSE_YORICK create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib-3.8.2.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_afm.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_animation_data.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_blocking_input.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm_listed.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_constrained_layout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_fontconfig_pattern.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_image.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_image.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_internal_utils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_layoutgrid.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext_data.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_path.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_path.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_text_helpers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_bbox.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_layout.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_type1font.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/animation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/animation.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/artist.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/artist.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_axes.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_base.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_base.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_secondary_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axes/_secondary_axes.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axis.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/axis.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_bases.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_bases.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_managers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_managers.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_tools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backend_tools.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/__init__.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_backend_agg.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_backend_agg.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_backend_gtk.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_backend_pdf_ps.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_backend_tk.py create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_macosx.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_macosx.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_tkagg.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/_tkagg.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_cairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk3.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk3agg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk3cairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk4.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk4agg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_gtk4cairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_macosx.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_mixed.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_nbagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pdf.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pgf.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_ps.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5agg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5cairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtcairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_svg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_template.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkcairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg_core.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wx.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxcairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/_formlayout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/figureoptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.eslintrc.js create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierignore create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierrc create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/all_figures.html create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/boilerplate.css create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/fbm.css create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/mpl.css create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/page.css create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/ipython_inline_figure.html create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl.js create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl_tornado.js create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/nbagg_mpl.js create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/nbagg_uat.ipynb create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/package.json create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/single_figure.html create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/category.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/container.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/container.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/dates.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.pyi create mode 100755 dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/image.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/image.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmex10.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmmi10.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmr10.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmsy10.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmtt10.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagd8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagdo8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagk8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagko8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkd8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkl8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkli8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrro8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8an.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8an.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvl8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvlo8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8an.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8an.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncbi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncri8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplbi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplri8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/psyr.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmri8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putb8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putbi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putr8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putri8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzdr.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmb10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmex10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmr10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmss10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.pdf create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.svg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect_large.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/kpsewhich.lua create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/plot_directive/plot_directive.css create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/README.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Stocks.csv create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/eeg.dat create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/goog.npz create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/grace_hopper.jpg create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/logo2.png create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/membrane.dat create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/msft.csv create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/bmh.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/classic.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/dark_background.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fast.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/ggplot.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/grayscale.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/path.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/pylab.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/pyplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/figmpl_directive.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/mathmpl.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/plot_directive.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/style/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/table.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/table.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/_markers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Duration.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Epoch.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/EpochConverter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/StrConverter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDbl.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblConverter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblFormatter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/conftest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_afm.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg_filter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_animation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_api.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_arrow_patches.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_artist.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axis.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_bases.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_cairo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_gtk3.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_macosx.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_nbagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pdf.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pgf.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_ps.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_qt.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_svg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_template.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tk.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_webagg.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backends_interactive.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_basic.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_bbox_tight.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_category.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cbook.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_collections.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colorbar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_compare_images.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_constrainedlayout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_container.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_contour.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cycles.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dates.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_determinism.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_doc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dviread.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_figure.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_font_manager.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_fontconfig_pattern.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ft2font.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_getattr.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_gridspec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_image.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_legend.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_lines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_marker.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mathtext.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_matplotlib.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mlab.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_offsetbox.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patches.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_path.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patheffects.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pickle.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_png.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_polar.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_preprocess_data.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pyplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_quiver.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_rcparams.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sankey.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_scale.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_simplification.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_skew.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sphinxext.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_spines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_streamplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_style.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_subplots.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_table.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_testing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_texmanager.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_text.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_textpath.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ticker.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_tightlayout.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_transforms.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_triangulation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ttconv.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_type1font.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_units.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_usetex.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_widgets.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/text.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/text.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triangulation.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tricontour.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trifinder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triinterpolate.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tripcolor.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triplot.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trirefine.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tritools.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/typing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/units.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/anchored_artists.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_divider.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_grid.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_rgb.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_size.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/inset_locator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/mpl_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/parasite_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/conftest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/test_axes_grid1.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/angle_helper.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_divider.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_grid.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_rgb.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axis_artist.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axisline_style.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axislines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/floating_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_finder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/parasite_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/conftest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_angle_helper.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axis_artist.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axislines.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_floating_axes.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_finder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/art3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axes3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axis3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/proj3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/conftest.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_art3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_axes3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_legend3d.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/mypy_extensions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/_meta.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/gitignore.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/pathspec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/pattern.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/gitwildmatch.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/pathspec/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/zip-safe create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_callers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_hooks.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_manager.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_result.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_tracing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pluggy/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/py.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/__metainfo.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_builtin.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionnew.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionold.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/_py2traceback.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/assertion.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/code.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_code/source.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_error.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_io/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_io/capture.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_io/saferepr.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_io/terminalwriter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_log/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_log/log.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_log/warning.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/cacheutil.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/common.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/local.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/svnurl.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_path/svnwc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_process/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_process/cmdexec.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_process/forkedfunc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_process/killproc.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_std.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_version.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/_xmlgen.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/error.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/iniconfig.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/io.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/path.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/test.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/py/xml.pyi create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pycodestyle.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pylab.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/actions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/common.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/core.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/diagram/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/helpers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/results.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/testing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/unicode.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pyparsing/util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest/__main__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_black.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/REQUESTED create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/entry_points.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/data.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/data_expand_hr_mesgs.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/fits/ActivityDevFields.fit create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/fits/HrmPluginTestActivity.fit create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/fits/WithGearChangeData.fit create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_accumulator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_bitstream.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_crc_calculator.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_decoder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_errors.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_hr_mesg_utils.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_stream.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tests/test_util.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml/decoder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml/encoder.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml/ordered.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/toml/tz.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/LICENSE create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli/_parser.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli/_re.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli/_types.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/tomli/py.typed create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1-py3.9-nspkg.pth create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/INSTALLER create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/LICENSE.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/METADATA create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/RECORD create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/WHEEL create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/namespace_packages.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/top_level.txt create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/_compat.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/_flatten.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.c create mode 100755 dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.cpython-39-darwin.so create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/adapter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/advice.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/builtins.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/collections.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/idatetime.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/interfaces.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/io.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/mapping.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/numbers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/sequence.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/basemapping.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_builtins.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_collections.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_idatetime.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_import_interfaces.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_io.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_numbers.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/declarations.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/document.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/interface.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/interfaces.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/registry.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/ro.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/__init__.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/advisory_testing.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/dummy.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/idummy.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/m1.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/odd.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_adapter.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_advice.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_compile_flags.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_declarations.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_document.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_element.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_exceptions.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interface.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interfaces.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_odd_declarations.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_registry.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_ro.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_sorting.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_verify.py create mode 100644 dbdpy-env/lib/python3.9/site-packages/zope/interface/verify.py create mode 100644 dbdpy-env/share/man/man1/ttx.1 delete mode 100644 pytest.ini create mode 100644 setup.cfg diff --git a/.github/workflows/pytest_runner.yml b/.github/workflows/pytest_runner.yml index 6dc27173..b9ce0153 100644 --- a/.github/workflows/pytest_runner.yml +++ b/.github/workflows/pytest_runner.yml @@ -15,4 +15,4 @@ jobs: run: pip install -r dev-requirements.txt - name: Test with pytest run: - pytest -v --pycodestyle \ No newline at end of file + pytest \ No newline at end of file diff --git a/dbdpy-env/bin/black b/dbdpy-env/bin/black new file mode 100755 index 00000000..85fafe3f --- /dev/null +++ b/dbdpy-env/bin/black @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from black import patched_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(patched_main()) diff --git a/dbdpy-env/bin/blackd b/dbdpy-env/bin/blackd new file mode 100755 index 00000000..eb57fc84 --- /dev/null +++ b/dbdpy-env/bin/blackd @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from blackd import patched_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(patched_main()) diff --git a/dbdpy-env/bin/fonttools b/dbdpy-env/bin/fonttools new file mode 100755 index 00000000..f685e6ba --- /dev/null +++ b/dbdpy-env/bin/fonttools @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from fontTools.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/dbdpy-env/bin/py.test b/dbdpy-env/bin/py.test new file mode 100755 index 00000000..7093814f --- /dev/null +++ b/dbdpy-env/bin/py.test @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/dbdpy-env/bin/pycodestyle b/dbdpy-env/bin/pycodestyle new file mode 100755 index 00000000..0c157bb3 --- /dev/null +++ b/dbdpy-env/bin/pycodestyle @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pycodestyle import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/dbdpy-env/bin/pyftmerge b/dbdpy-env/bin/pyftmerge new file mode 100755 index 00000000..170d9930 --- /dev/null +++ b/dbdpy-env/bin/pyftmerge @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from fontTools.merge import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/dbdpy-env/bin/pyftsubset b/dbdpy-env/bin/pyftsubset new file mode 100755 index 00000000..663cdffe --- /dev/null +++ b/dbdpy-env/bin/pyftsubset @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from fontTools.subset import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/dbdpy-env/bin/pytest b/dbdpy-env/bin/pytest new file mode 100755 index 00000000..7093814f --- /dev/null +++ b/dbdpy-env/bin/pytest @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/dbdpy-env/bin/ttx b/dbdpy-env/bin/ttx new file mode 100755 index 00000000..3dba6561 --- /dev/null +++ b/dbdpy-env/bin/ttx @@ -0,0 +1,8 @@ +#!/Users/billchen/Desktop/dbdpy/dbdpy-env/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from fontTools.ttx import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/629853fdff261ed89b74__mypyc.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/629853fdff261ed89b74__mypyc.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..d6a0f644a010bce9d897e3dce53a0c9054f77f4e GIT binary patch literal 3757901 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�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%0DxBhY!pp#Y2E1%et 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

saMrTSae=bw!Xr`M+pg6-Q52 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� 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�Sc zohN$F)|mNOwmXk!g_FH!g<5y>##oWth-ybYPP$DeIdKhzQ{+1_+sUwL36u1E->;D3a8?(+NoEe9 zDcZa7(}aCLKh5`Dch*iN9ws{|53}rCY&ZB?h^(t^2lGEzrtZI*|75!Zc|QHW@zPZM z5q#ys92tS1w1@avgl@TmwqKbMyLEgFyEh<<)iGo~=CrMz%~}EfP2Fn0qip*zK3V%C zp{?Z06Kwf1Q{m#bRhMb2ELVI}f9!$&nm}JK2ZrkX2ldLAnSgr*XKI4`9pIh~?!oV3 z;ClzS-w*CVrqc2<}?z5Bz|a@>VHc9FMPvT^JQ2UEA*)1{caFkYO`_e(a!jqjzJalbw&OX%!i`!sRyx5G#JPdiHQPL^H@ z=-myRwbF*(Z2?v${`uwb-r#metamm09JQ}LN}jP6o(rC*|8n~DpT3J?BkH}^W;yOe z@SJ;;r~f>i=9Sl&8CL#K%CCRJ%+o{l#WG~L-tzea(?_%2BEAXI+l*ZzIUde)pYBU| z7S^UePSd6p)O9NJ9MMyc?b@kaH0*QQ1-J%QiKpjgq=7LT7%|Vk8cL7po6J)*PRf5^ z;P(3=TZ?9nX`Gw}eg=A`*ut0pwi~@1?H%LgSZzGq_uqQ^*jaa1F5ozQ!PMi&=<|FG zbzrw9=y<`F|8`H!^^oh=cV+#8zE`{|-lqGvxDUg3SQ>ms0rN}GchnKYw?y$k^Y#nH zcYO%HP6)n&Eqom-ACrxIiByI{`kvVOWr>+ z6#oZ8@b93GWPS^_@b9qsv#+ywda-$V?gH**cW&X^>W5PIkuGFuwS{qog>jj==DC-0 zmF`~vZxox6`{1Bb#c0jv+R3#B-H>dLKJ;LC-?={xpVmRkuMG~g#}u#5v#2xe7^QeN zzWdPfH_Yykz3{tl(4SOJ`DS-kpX>;&5v{fSdYL}Bvv0b<@#!=;3g+50aP(gJeC5L! zNPE-=boYkUo_+Bl^1X6(oH2|XgOrh7P|drbp7U+Y4V3kDQ`9j!*zEaIt`4KWnJ<-~ z?@e43xg6t@w7)PsPsh$^zYe<9_g~qCb$W|;4f-*%#?!g~11>KcyjiEEjBJ8h@K#=q zoxy%B4NrYN*=5=*&z(kl?Qiu`O{MyCmV1G@=DO!|4bw}Xo|n2`3+^kPZ?;1@pM5=Q z`gO^;(0=^~Xie6mZ%{{azZPuee15~`az4u9JJI4h0p4hhy$*i$&<9@>kI^UoUe6|;6ihmvA?B-cIafE40SX_i^eq${_V-jcRS?Nhq}>jy7_dCkzRToY@hJBE?Mp5I+BYHhaMFE{c0Vtl zX@{o#1RvPn2hbM8GugR<$z_JGG9i~)k+t(5BH!M~sB>AfWsWi&Yxr(6Hg#}4xMo;V^|9|c;@oh zWB58R+qmlff_EtQ0d_ZW>K8Tdz2t6ZuRHDz@}b!Bq}ahO^!lV(hfuEOzs)u}rqzyJ zt#;1bS~PIK#*F*X`;37>d^G0>;`8JG$N2mnd`_iK^`&?DzXl%4S5bXXcn-}UQ2*S6 zkjX=tkKp5sAsdD43)B8!<&$L0(HL&_a22bKreL#0vE61JWpv~^;-G?O&YurF)0V!i zd4<#12p-5!0&mvcm)*-* zz2F@I*Za}S8_{d4ne#e-ajF)~jxV6;PyPQVI4!x+DV;~X)1G8rX!}nK@XEl| z%;#4#568!<^2+o4$KAZ|ZCNwFEMzV^e-P(Q-RP_+pE23&n?DddOl_3r<~$Q+2+Pg&cP#Wmgf~DL6j{&Xt_Sxu=D5D(}W` z_uy2s=QHZS8{vbFJb`zD)m%qh1MTw;vR8DBQ?+?lC!73tw+4B=;p2GKPm$51?Kidf z6Y2x{vAQ%|=NwM?xus68+GPBriEZN78AD!skm*-A|8nFYXG;_EKS4ep8z*reG|9gs zU9NTM=HpoB<^6nqYw@>#p3NDmTxaCy4AmU>Df+bhL@idHC4Zhg=eWCp&*#)r#0b{(`0cSh_KFf9wR7`lC~txv=#;Vyj_<&;s zztITE;?-V%nD$UO@2mgl@xJtX9`Dz*lG}s-KJUMm#QO;H@j35b#A~-Zo=&9E*P~7UiyoUOnmj#vmW|5_%Dil+S9f>HO53d-+s)HsFCiDn zx>V-^OxxWVzaBYC#(Bn;M4WFhIOn*NnVa~!|C9{=5A<~Z9iJrP+}AI*vZsM@$?q4x z=Ns|Wr{Ulb8nBU@Zt zxkcW3-g3%|CTB=wg@;$JTg$WL_U{CCyOjrxmxYXp^CLZ__TOaKs zz`O7a+yDQZNV_jb)hm#ZDgAQv9C0zCKS7RIOL{fRc-Us-s3G#KHzrq5-wtv_*=gis z_4&X3T=pbPciQGNK77&bH%c?2tV4ipJL__FroJHsg`wn6rK7Gq!dkhe4j|Jce%g zTVv)y#O8vJU+9wvS)a8|a8K55GF*$-hp< zuO(h}9QesT3AU$yhOFv1KyVo!rnkh~_5-$LsfcIi@tx@2m;XNfH(2<(AIX284|Ttd zSB){{^W438K38>eJg)!6o5}qI+2hzRMUTg;R+xJ8-2puJ$I^@W@9DdI zcOd_Ld#33z`PaPo{w{F689lhe7z)e|TlZFnoRyDzJp6?JJ&(oP9yaymy8q$c$7Ai< zc-5^Ij}1Kc@t6|8ql@Q09x=)X@wg}ij|k_d?Ph6S&$q9x_3-H6|D9`Te~ZUox%YKU z(bMs&SByQH=dR|tKMo%V9->qCYk2PC(PYjs_W6htWdA=D>XS9|@2=aP|?kHp*Fv$);KvoRLt9sHM`+4@$zjXsDB zkvEiQee&@Rd@y>793MQ_`*P$}?cvvPQ=q)&+Rod9`sQfWhoUF5y*b+Fho-g(HGWBl zRpaYOHAkCCnO6_nagNq%@Z+pt>>Yocz5tx2=Xm4v_`||=Q|xfhe)@b5&wgqeiw|Z` z>?8Owp%fkD*~E>qiAN5|-c(C&yXYc+4^F;&sKvQ5QDftsTqUQ^GPdj>7w}o{vVdR8cUSRS zmDg{VwU-u_nszNqq}_}k6ZNgPAL=Gxi)YfU(znv5G3NV0om0#GJJ=a(xPG4DjIV;< z$>aEI+Y-m|7me=Bb2kA$2y3lbJI-<6=ec0kaX;o9d^&qMZN6@-F2hd!a8Q{qYcs5@ z`7#;dJlPuHC(qrAn7ducbLCkGwnc9rlP2l?{tC#EfFC25W$JvVE@o*8(23eg_%YVP^y7}*o1-Wh=|BtaS z=G!tF`%dS(YW$$kVtjQ?zhNIfZCG;vW4o2h8syUJQ(5kGXu5pY?Mth?*x3f_(`vAO z$_Du<*ENx+4BYTZg}%?YkMo4nydU-J+NqE5UiS3(Wr=N}eis41p}TwW-$D8I?X5$= zaqj)Zo-_B-T0-|Sas^gXl=GERmvAnWA&4#Gw)9ff|-n&upn&NZtT_$@6O7<`F{i$AV4E&~AyWbOB z@u&9Z#^CwUXB&U&4sED>a6{>PsoGKPJkY-XruA<|-z3++Pm1~vPeV6rNz3u&CeZeJ z2<%-`z#jiCVXq5;{qb4he0wfq$2KwX3484y+9nT%z3Cb<&5T;Ls$yP-Oj+chu*aZ(3rQuZt zy6>movhL9#b)OPeH@^P!Ltv-V2SY<(ADIHSWG|YA?_Jb?xaIS0hR-?fCn0?y9X{Rk z*JS;W6M~P%kdhEu)3xCXA+WzbbH_d`*oTC`PKWp7A+Y}w0$XF-_7I+=!~1~{*c~Zg z$3tMJ!~5nC*pG$4&OomJ5du3M-t$6WFG~UYg>MP_oDkSIrGR}wnlVgt-D&Gir%zSx zedd18kn{YO5L`>j)>`6G^DI3RJNH#^` z51p#)ntq$&CtvlNIakc7oq9HXq_)Oeo1I6QCgw7~qK?iBofY_KdrNt?hG#eOET(6i zrxvvPC|6bqoE_}G;a*&h#-rDIObkwft>M#M8p4xwvhiQwCHM2;Av~#QuAO>V2yDOJ zFkSsBu-k+C%dv3=0^70s%OhN6r!J$P=L5T#I1r5kQGMgtR;{wFEbP|cdi0tQ*dLt{ z4ts=!Ex8J-dmD23ZR&0gsr&hmy4OKhR|ssQ2l{0+fvy`vV6O^+U4j1kTL^60IwjAp z2!Y)c0(&;FSA@U@?~Z^yn}GLOA+Q&Rz^Y*4C=~+K{@_ z(RDyb-KT}rJqp+thQLlo*B&9Tk4gdi;%^DNhklma_x4W#TlU2M$_a|y`HSy)cISK8 z7wQvXd=#zn1*Ce9-Pa-8SLM!OuA8cF5nHfBzf0E^PleF5`Scz8d&R}4*rThH|L6g%cL~rh3l~)xTfnv z-wVO@;t*Uj7{8PsAz2pF@!`M_*i|WD`}4t_^$DLB!eHmUHa{Ub4uL%+1?-7wXjR?$A$6ytYjsH7 zAI?mz4?ZN%v3U6dczHtz57W{4n~=I*NK@Afwyv?J-E!P_@gXjx?JmH_^lfDDhLCz6 z38{A>{CkEvl3}N#>CzC`_lCfpjjn73_Ehi>^GU8fGhX#3d;U|&@iOcQ?b}br&Gfw# zc2H#qZu3HL6YRynUemXSo^w#hg*V=*o%#VdMbEZ5ICTz6;7r3V-t7xLzAtgj+3~h- zgI{3?e%}wluM7NUrJ_Bv&kvQLe=|d1mxjPr9O?5pxP!Ao!5Dcf!5x#mIzz+JO6-u7$mn^-?J^Pf8hm9EkM zz`SSHo$;!t82=up+*+=g#9(Uw^pI)wZ`?T5%Q1Q#F&8OwjC%fK6T5o{=QLhI+a{mW zcmdDC&S|Xv|5!Wo_$rI*;XgNFxdBBqdqhdVB~jdgfYq7=QP8RtBdDz_;pluMXPyusMxbOGO%#%FN%{OgF;^reN zZeHSd_sk7GTP^b-)(E)|z}?K}k2}b9dd`dB69FIY$|D|H;^bAktvP{qOK6waV-+V} zK%W;7>#EME!Y>c5;NrpdV!s#BhMEiIAFA%K{*WB1iQ{)QYnXXXpITY_et!Zkm!OZw&2&+=Bx6w|!0DTkwy7zuCK~mAxD32ao>( z-;eVRcAU56m23W=49;@jSR#yFlm3Eyb@5w`W6pU_cAV{Lk@@#7WNZ{b(?Z(E|Jj}z zS#Yl(Cy8~JvuXq2sraV;y_ljd{8e0aCI3a&cz2)dnzXh~=nx(76#BxzRdrXZJHJxh zM|p00N5ia*>O(AkDor-E0=wARiEGIC3nU=Y;OjJ z#2=QMJ->4P7x5ptZHbQ6ar)5KlJ{Jn+SwC(Eq(%@P~=POk-v>8?3p(SkIALXrSQ>O8Cyf$!AhzjR{x_wQ$AkYFt&#dm`5zr8;~yOO zNWA(FX}?=s068V@N^yph$F(JzF1ef1w^ov~q~46Pdc~u3;)~L@=JMP>{`7rtsVWZ6 z(698uCdS|Kv{h$#QU?rg5A`45<)<5(1H5y{?cnht>U8O^J#$Z^ugB8or`C5&MjqE{ z`_pXNkbbC?92UMd@u328jSL3bs^b56)gKw|GvHNj-jzO#s5pRBw}Iz(D4!(LeT?55 zcg08e+bBwCLvZlJ5gc0SN6C4&iLw8|`REVgwl^`B|H3k@7;m3hR8&N!+KJq1*Zr&t5^rl?^O73^3EwruCQH`B8&z6k-5qBd)7L& zO4mHXSm8`idtdHmqP-^a42eF3<_4#?(udn37mkhfVO&NvD^4eJ^G=_7gX%F&%`9|61Ouj^3v zJalzC<6qI>Yd@DTiq2Ym6^C4`_$twWPVYK@>y3#oiI)uH z_X_y^1hjeM)N4z8biaSD&IFHfYTcoo^P84wO+z|q`Y|+>;osIRnB38s|1Od{vWN zEO+Y-Pb0S^cbxkCS>wBKN8#u3rOU{NDP!I6R^83n%J@@o@Dt}TE^_f({Q4dmN~6rL zoQucC_M4@B!rWgwD^FMUFxCAJcE|sIp7HTsxi2pF@u~KtAAVhmAHvxzHCH~8JHU8P zd=T+pMW1YmXnj(SKB?yZ(6%vhCts>XpGfRts?sMdz>r)wn^ax>+|wO@H1I`-H5+}? zjQ!H%oO6Mcx6}4N&=GQ{)!+G^%iS6(Cnz+>$qAa6yQWC{KqLOl`n~A7r-9+|rujO} zo1z7dtfzDz+b3}cm|Hm^g?`?j*dM7Q`9qqSYs&rI>m>H${LXce8olSI?-5)}JBr7h zXHX-x+s;$#eaa_RV;cA+z?V7AHe^lwV)&ajpJ$SHeiPqeczr^Bp=X@lm$2jh$I1z# zDDTocneG7In<#q9@V8z3A!W-m-Cuz7#G`d?4Ji6I;uFzf7!4?vjaeeCf8K-z^ho(yruT4x@Dibi4{3D(^IH{yw42h2N5ER<#q9 zr%d1qZbjHSn>-y$xyX~c?}RaAlb=eSZzP6xSPy(&1AZTYzn{;I#Fi%VS;x{6w=eV# z)qF0R#MqTML*{mO!1HR8C+SmoCwY=aW8=LXbyMb$uZuJ3Gw0G5rf;sNZ-mAV7z-DT zDdIeH9UW2N4&Aw$lw&{lf1@Xp0m6=bo}@qEx2pln(1B%>V`R$rJps zIafFqzBTQLuathgpWnF;8v8xeiCtju47K0M->s`#fuZcTsvFd|e=_i$gf$e;ey^w8 z)38&)?k>FN~9ivDpaPoL`C1+@=(K+exXahcDo%n=?KY8O=tD#KYrwK0&y|s#7U@n9Y!WTauw2Y*? zXMz`TVIuzxkweEI|J)Bjed&Kc9iB{`Lj4iD*8MaJI_0j--}?yFdoS``eje$j}iNza;Bqp#KZGUU_Thn(deX8O~w z&$WDJxl1XFqno9_h_k&q(YEIyvwgsevpf@Q@_nnocC^jUWsWanQpW1u|LAf04E!3= zN1sd0g?`a5mA}L%I?##zga2Z~JULG3)8(7jA$$7nHk%x0bvaXRr35@Y|d>W zA7MVqZP z(I|d2a^dV7J=>|QI?1V=&u0Ojn@)-jb7D^AEhpW7v$HspyQG$q?;tbYr(Sp@Yml3e z_gmM+l`rb&qc^@*At#Kl?YX(+3t=o2az0+(y%>JPz#(^{(-_NiV%gM_yNWu;LauKt z3}!4m9H!IdE+f5mv0P*lK2;kztHyqdzfx}gm-Am_X#+lU6#vb+WNhq-YxNp~BYp(A znpiUn&lp|9Z|O6ekA77TW0=^v8o3u*{Er{OAF

uqzJzviZ|=FB6HGfx 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 z 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

ghiESkxQ3t5x2` zAI5ig!K=D^B}@DQ-pN<%b6@V~ERl(J`%GRRZQtX;8g_r+GJsdkbs(2Wg%Q08d3qdb z&8=uXQqHYb&^+SMYuJARhMZf;y0N;m5oMjt1Gl5>vF%2U~y1iAN%M15QJRkc8b!@q%3ry-eUB~?dbvH#NJ(iDuJeYrKkPy&C#E2J@#Ct%8QkqAm-T-VtpU|DWz%RGD@*datWpI(R1NjDW39RO*ka? z|5L^Hz!{_Wa&0PA+)gyBIYjs(#$}FTTnn=UqYrFpOQ$&N1i-TDg)ZcJ^_OzJQtVm( zQ!l?jm0!Z;Yfyd<%A2H&WA$w~@OP$fV^Eg4)u3~ZOXRx4Sh?=7-dcAUi+(mxF4rBl z_Njgm&(c;bzpu{UwXZu2q&`0My2B9Ql(r%3#;!Y%o=f* zFQlk%o>6}F5xlS0w-K`oeC&o^lBN-i~tUfMsiPJl+kxa{p?N$74{( z!2KAs4=v};OL6`WdAiT4*6znE>J8gl^!K*+8DQL^#$)=g%c$`^^3yKy5%S~d`xNwr z-m}Nzx?!xFjl)?to1o+UU{8&(8Ov4<@5EMKQSd3w3=Cm7l?67OlVK}_UzVSu%JY?t zASOyuc6-eyWVg6$2{Awt&YR4`9uD0F#vY+fZ#w_3@oeO+zB%EX1hjKZ`z`p7& z8;uTgjMu@7C)1u|e7wo%bdE6xuxO6q{>CUC^Q|H07-?uv_T_sxc8*bw{CGcKhx>Z< z@zY4hcNfx)+R3>4uSxcCtnHr$eDN^Yo?HTemfZrL{mK^n?Y7_)7o&{iRk{BLId_-> zT6`yPoN^BTkBL(r|1~a7IiBN`(*cL}%g;dCnNL3jWxB3e^c|0U^z}+LUazFs^kl;Q zrELpK@Ep2di%l09(S^vCY@rl;1pni?kJP#Fk*ss( zK-Rg1D4+5SbPch?M<4STv6fQAN*~BHQ#gb4>=N}H&r3L=ehjDH&2W|j&KL!!R}AMI1X5sipJbEQNo7!jJn<&!u)4qh3I}(|*GkAo+{cgEuXiB=CD*p={$viS^(U zl#w2kw6Gp*K|g!WVm(;H|6}wZBTf&zXR;ow2Ar*sV|;8_xwWnMG`aub5-U+h*KKbz z$A$v=x72cM_#eP0Tdh)j=&@l4^@i4PZ0N?F+lkhqD^LfrwD11_yv}0A2T*q$zE`U0 z;ClK-$`Z7pcgW>9MKR+{Bl-*Sbe-!EGft+l;m|ST4B(UFqO2R+e?=(kYz!|&S>{Vd z%^<`Watyyhj^XX^W?uu^43yK^tzBDtRlkL2qTSJ5t(&Vc+<|X-%J_C5(V8I=?;T{w zGxUWPt+FnS;Tgi(JLr!x317u&j`lb$LlmH_ri%UC7|;<~#bdaEGsta$ZQRfW;w6#K7y$UK<8X#s@kqK`^z{wxdjyMna7;@1i#OaL_Xr|5mqO2}cy3&g z^tWSpGH{GM#2Ee;aBDgv{Z=yajMr_yRf^~E6wPnlY($HZr|ZyEryV~#=v?xmzt^E3 z0b?m>v&Pw>za)-HH=-VBl)lK*I$5r%mK>OTBgvr@@$tAudz|&`Q|0?rIebpu)42Z# zX9uaicijybQ%P?2nEE8(lMdjHw;D$RJ*Y*w98-_*L^q<2vgh`7J39BW9kf$FC$jbD z&^`lSw-_+MxXFh(aUxqM8VHAxllVN;GF9%%k!PWlPr!FSfLGeK@-dP2aWP%oi#El$ z+feIY=@afpo6ysIUP7LQx)ke=$RpoUrDEm9x!j*sG!Es`e5f;Bv){?^179zF{Mp8R zVQ%NXpz&wzQ}F-rL%Y%MR-cBNxnBM6T#wf1-d6ScujBD3Tc%m!EVOHqx)tkljsxz_ zVuy24_HZcim~j@$NH6MF^O$itr%~zeFWhdfYV(6^lP%~Bdwgu-jyu!n!?V`s(xwlm zKEJ@W=^1$ToUg^@la1&km_^Jr)zrC%spzTQGCiiiPeeT(;Gs>5`gaLS+`4AeL#xCsWOHW0c z(0nbvIv?->19|*O{C=BD#w@A8C%?ZUZ7$Z=?KlLTJNt$ z8D-?_N*-cgmkl_^aqR2<+#>(S_`1uG=U1|&`Ib4Decev9yBNMM-VfnxsKr55KZyDs zJVT#i=0v{%W}v|KLl+Va12sQ1#)zJ2@u%cBQhlq4{7@v7VvEk?$8w_cB5MId!2ei& zqd)K_(zEwa&(e8cE$e*QYS#Ir{#Y}E?zWfLsPZ?tya~2;gtE1pKVto#MJeoP7R}}1 z+lhZU|6j#zD_`ff$;zIlsQQy->Jm?5PGq$SujDpnEw>?Gu;&SapCQ)a+>TW*^a|Ij ze~s&{!P@rAz~3bGjBL)1bxOc5*^J&#)*N;o%EtMPn)rT|<*@ymSyoHb9Cr!Lac?8N zx!LZ|Z>fJ>+@GmGV*h1?5nYEoeO&1<-$?%Z{u~9|a=sz!#@fU2DC^8_&qLY6_+Epq z$IP!&oQ*QFhsL>V592^*-H~h$`TRe|9v*0lwTF7F<JO>6v9uqwWTV-Q)gS4ATRSZ=?R^yO=4_@tkLc~sw0GzKF|=P5PdnDziT1xx zcZ){5=P9PWq>^c;vjW+m-O@GBld3$#<)tWhqP#Pm`4#ZdHb!S!K#LE0Mt$bN{>ufZ z6Ha2Ck@uQiXhhFI9>uj*JUZwwJ05N51s^bibmq|Kbw30Q$kO%ZB6)6A_KoKeMgQYW z|8mg31^Yxaw!Mw|x?MD?vx~LJkLTen@DQq%>xgXMOBrrug^~+=$B&qESpMf=V`BgF zG{crKeB}(I>|q;*`@gpAeM?mNGA>WT8e$D-Ujx6;-ar3R{4M1=&5y%hfVVzdp?_LE zLDzA~^D7yBgJQ6{Uy)U)6M|?sjh1IA67c4t57U0gUZ5 zE){@hU7nWj`wp_RcnaOdFzWAM7)j`l2^!C#IjVdfm*;|~|7qiB=vGyJJD0CPtUFNA zez&4|k>nvmETT0@l<$X*AAx;fi-y2#hEaJN!zjf*L0<*qFPs;ny)k;1c^PCz=a1_b zwpRRzHB^ZUYlapa&rJ-cK~XJoFXeAXryw{cX%p?Pqa&lF4Hl zoyPU5{6;P>1Pz}n94ATG>Ea~Rr}Y_veTfF!J&oIXZ{W5`sB^qF2DzuI@)>sd8wz%& zqQ8>Q6RxDQagJ$|<=MNbiY7XHm;3ZpF=y{?fIg8wDH?Wzd=HP#-aQe9eNJIqjZ+yH z$&$|AIW&4g*KnPBzg=gkqG!*Ctrbz6Nt=T^6;|M!X}kO+xkj%I8Jdy49YKB)? z%J7;%&(Xj~G43?LTd3M>(%OV4avQUR+vK9|y{KD=l;D4lx=m;|8F?1po-4Uc$s~mb zS^U%$bN$BgT)!0j{Hn>QZj34)XP18g zenuzgpUR`#iU$KW$&uu@0C31=>3xB|nhf2e7^ZhD!(0QLKkyu0_NDtWRbFhDuhM+3 z`%+athRd6PZ|kFM{}(_9$$!#WN}|CJ8Wy6QXxORwJL6)8ku!>6P@QiSj8j#=<*R=D zo%i~sEmmEu`tK60|H@+f?|!TQGVK0)b2IvHB;zc*m~k!#&JO)o#C1w8vg@o=boEtq z9aO$Sp8q?K>o;D&^^*WIsL8VKTva~OE}x{yvhEyJUc}{vkliwcZ|?`BAnVjsXI zdG^qBBV5RB&GWf!De4qyu)|(eex42cP6c~2VAFR4H{kwH{kwtCOFPE6;{0d^^vvkP z=LBZrfBbg?&xc%TU7FTjJ_gM3rZJRkCwTfz@|#{EN5^k^dBKnVJ*y#rVSUf)Z2Xt) zhjaVN>I20F=Gy~IS4$nvkSvBjqVIz(#{8egce*#kl;uuY?q`2hPU{Ixh})<^8XwBwEma*nW6ZZuK1aXv_Z+B0Wui;gY-2^NLPI)EB=NtJ!Ge=m|iYFNtF+^ z%WL%Vf2i^yTwaRy%@zFZ2gmW;UpY@6C|(9%b71CM)qmo9kFArEs`rjduHJoVm+FJ_ zx>g??fiGe#a(qd1GdW%+V?WCDM5~gsS|0>YxQ{@_-JxR=?^8^J4!(8__O(&Bu29t- zoVe~Jsyi6(W@2y0HRHT!P|1bXj$S{~6a5C~I(1pmzVQ_337sWT`8!F595dn@=YTf^ z^i9N^l4zf|XU2F+^AF4ze;DaBV!A@qQFwL|o=~b$Tv5pbA5^~wm-xiiv^J6#+PxL2G+Z7{B(jiK7m^Kv}9GkG77o}b1uy^EY^ zA1DiO{>(J!tmqO0Isw@%$=ZW6WLX|7ZKc^ zhk*MF$|fA$S}+OwUx8$!ctCPmiw9{UIc`GT)zGcE#~L+CKIM79NjPZVwuyWS>d+dN zEvk>C5ZDMQzIdYAaq1Jx)wl zx}@tz$e(@O z0&?hm*|Up&is~L$NY{0FXWGCjPe{P zmGi1blgF5a0|KKjLyVG!F}$6>FKzyEqQpa*z?f2gaNfBXXU@TRGXmpIA;uqX^?{lH zsj5q!^bPU<1MutoSN_5LZ$y3!y)qwnoFHHCzZ{v5wQ=O@{fM)Cpdm|qfcytw3q8RP zVwGCrHMmywEy`UQpT-{Mv+~bUdCp)t_)G(zMCWbwlsd(&GR1qpGR+V-A$Ies41;9VRl&GU!Puqh)7+>WZGhHJcCGB+O z4veMi5k*(gTQ*%EfUdf23jPj;Priic`ascjw4!UEOmT0VF24x3E&Ct0EdNLvVR zQTUtfIu9zo?gSlK^II$0lFcu7Uz&v2D!KaL2S#}$IayHr(mcW_-!>V)V~y$++vfJ6 zJ`E?E7~_&KmN>)-ceYj-h}E0Ad#g#;-uSq!;^4dyu%E(ez$_=5p*S@@uk8Z^_)Opf z&P5u&fzT6-ql=n5;@W=)<7&hiE5h}Y#8n7f-fFpw_2>(sM4;i!%;uHtxdBMY)s&nzK8pGsglHJ~M@1o3>({9L~ zV&2Q)=juwart~Q8NrQapTOZV4h#hLkW*n7+%LgI8^dDnZH&DHYS!T56O|c2puQOT; z7(er{ciack$LYQ;jJc8%@DtUeyhq`SIxE*@LGdclWlZUm=9P~6Jj}=Jd6|E-S-qgI z5ha=QAR9G|8eba4ShmbaM$$*jh0otmdKu|w&c*z`>6&hV(HoY<-sjF^h*M09q1%?X zPBY0fPsOKs2KJQ?nAJqf)*ozI+>o)=e>yGU&zY9`BAb?#pv4ncziov1W$PppV@(qJ z8MZeM^BdR=;U->!PtK6@nn-seO3#ibW{hvbdE33PzmcGg=CC+77agSj55oVF!*NCi z?`4`jjp7uH->9=Q#WbP;jN#+Z2jSZ}UQabgaJ&wCTsZc&BW?-h|9^Q7?=-q?4#0y$#RuJ9KD6_XkYvV(*7Jx?n#n+2~|H zEDb(|@0T{vH}T)Ht4AD8cYP{;%88$No^@X95#x}&0^n;qXj%h5*CcT>o`L8Gx|87} zi(cp*-CCLZ^B|E(YtQj1}_kvSNi)k%D}J<9mzYc!x3^YTrxgV>|teZTj7~L*-fU zNNodea@&$q?6wD&@_0SzeY`Ud*&dwtKJ?Zo&%=3BV@9lvligCjqkeF?!-07oWac=^ zh#s6*Fa1qS+gY(~187S+=O`N_+gfen{bD}g*WHTy1mOR4d0IZ(@@ zdn5b69MI)JzVX!g(PG$X=pl?d-I68WMTSxP1M36sUg=Uk9D3uP=Zz+H^;FBX55WKP zT7r|+;=y|*ChB_9S_{xusDF65Ypkc5#(>KK*I2~sPL5u<3kyERT92$&|Eu9|Tw{%D zf=}(u&%DxKlg<%*AMOrr1|0Gsx?C+Cc@?;KFOay`JG`0Y@+^B}&+^Ez-Kqg^y`wUh z^UPkz>&|&OndOlYJl6RBJ@HABS0&Q$z2-}iB>1}Hj3~**VV+fPteX(c1#QWhqoZ9g z&NMDE%YXU6DBpv%PS5SeP+8A=R=L@KJnYgF9f-P3h+n2-A0x0p`h@kyW42uH2EDRP z3EJ$5ZF4o+)ZzRZ(QQ0sx4F&gi?YMZ&3B7p@QgwmgWK#d?qt2C{+rHt;E#-QbMAzg zHs_#?=T3#^RU6OMjAx0XKD*q!`;wS81;h`|vPs&?ySMAfD65UPU%7eMr7>*=6F>7T z8Q5*kv1rS2l$#G<5!0qW@nf~=+NB*&fz_tId%5{sY@0sB56&S<+DvW}Og3srry%Pc z&Qy#&a?LKQC4@1S&L|8~I%RY*YWLzjnZoa(t60OK{&NS_cyuk#Pu7^wW!%j;9ChOL zFz2_n;;S(>^ag#2@KqjYllW56HZ-B*SO}U|I)C>{+q``AjF@i%D}9&i^JGtxL30@A zyC@Dx`xNK7FgDUSYapNecu*U|F-8AZpc%V%Tl$G_hjojT@{=(H~`jyAt&R7Vhd`5=d* z0NY){av(oRdmBxl`+Lh3^h#2fc^#3Z91tzu@ynxg*k^A{s%Da~7Bt0ZKTK==t%l?zbhgX54&TK8f z_`b4!FZNv#SCUU!h&t3Cqx<`IJZ7wc>2Ce~MT6zgkl*TCqzLGOd8 zV2xhK_V7esCFkn6em|@^P1Gvj>wsGg4VdEwmgQ!P30Xp-C1NNaR)Qz z0I{)S6l+6&;!G!<2_b$W`7_2x(s|z^{WDLr9I$BJw*mZ8Y+jwjv3Uc|s}^DWZd^gJ zc^ZAs=Bq8hV}Cyq-}yy8omb6-uF#rxgR&ot`_We5G!X~T_}(O8*!6z~oc{rDqBg95 zX`(w|R*W}l_Je+sGxf)xSO=DNi1q`_%od6>PE@jpDBKa?rtz2Iq>DW$PdlCEX`ak* z7zXP}0DaXTbpq(8T+rGJawHkX!)rX)R{R_EwhPKhN2q@sl_}*k#uIJ2j-&t{>4>aj z_9#z!^|Gjmu}-f?I?|^4n{d>|h=a(tpVc7Ev-ZOE^H2_-QqVGM$%fJ)29v#4QP{}+9 znb+aDNIQH3#Gn{M;qCfuv;3BpfBsw)}9|@^R&N1b~Z-Q?8ZHNyPQUJ1)iyos+8SM z?Uqq+E_8_c@>JmStG@7~FY47=^eM>Kc`lRrE^$2a^}h4U{8Vua@~IC^JQJPaBGyT- zTGu6=oCw`I8+sMbdl~$EJ?w>O&qa9vdu=3hUGIpGS#f+UR{p07{wI(8&!WFy8;Dvk zH2rIYef1*WBiqN$@4rY;-x~LtQImhajnR3KlLzM2nHdE^QNZ7z2^TcwatLG(mSG+-*Qg^01C2*z#cWvcm8d1`3 z|0@?qr_O|aW6hOfn|}bl`{<6kP5z-X-KH`3;el#Q$DB^-h(4w-G1tb9>2B;zZA{R= z%%@X41(>88Umq|1-Fg?+kF3~-#w^%9^w%X;00zm*gS})wbe7hR{3-5y(s>i#0wDYB z3s~`b6hixFx)~>jk?!te3^Op^>;NodFw1b}nMQ{;7Hu@)Pw*_|sO+o5{pyoRFAx2mG1)BLuRiCSj(nA1 zKWnA550{vL@(}KhkUqe${jw#e$lhZMr2QSQ?5`(}2|wR4@uUG5(@T$~bswi_`B!Vj zT}7O!hn%QRKq<2XozSJZ67I|cbk-El@2vh)pLnDqxIN;@B>;8g$)t zF!HuqFkB)>(d6r|+VAJ~)Xzr&2HC&G>!9CkUTJ;v;Jiz)wsA4mI4;6k$Awt)xB&Z< zBe55fEY}%{u22@kHKPnS33K>u&_&t*nOv6Bs>;xhU#YTi2A6sFaakeO(mzpUhAJ!B zYnRb}9l>;`bGx!VTvm#8#&=bjCymQ0cPo6!fzcnSGG8i})$ii6T$I(RvVe=r8vjuE zP_|l?g`8Yws?u{| z?!)cM{-%lt`R`m#CSU(RP#`VqLRDC1R zccE5(H2&v8$F4&v;rCMTw{d+cyH%BWdU9E1GnbL$4%TH$B!ee+Jy9fLU)oEx@ zHjDfM&=zhhxs3A5Zs+=I(9c`oKMEi>ve_RY7YmQStwh4FZY$|SZRGy$iLrQgfEOwY zuC?*>2cFOY#^asC^_vu){!*u0;>%kZAK8klb-_bYR(soO-@@~=D0>ZX^*t?XUw1^; zj(d_zZviaq<(-c?l5XhxUPQb5Kj?35Ow-HV zt;{>EFCFt>Yel>M?@|2S$owq_f4`zU9)8C?+$7$g9%z&&-R6^Wojim6`LlQ2z;ec# z2=7%p#D8W2X0pZ`*2IZ7lg@Y1ogElMX#JJ;mHdD4KHu+OV=Tp58SObr{@#!0FLv*j zX^zdS+gWlFwI#kIxNp|tJN!HIU4NY#L*ZW?7$@4xe^cewIvdJE?Q)65abV`#@c$k6 z5b1m*;r72}*+(=n~G z?<0@9k9hcTT_5t4ZsZw8%o$4Bj~)YATf7^;Fz<~KPM5>Sm4NpM;``OO2bA{HcH{oU zIXLH50Qw>vTa-t@3(bjs{Hv{k);Uyu%=yRPU{eEn8nfId8O66E_VBB?gydkwl3U2W zfvXYmOw$OXygz7bT;#28>Iogef0Aj#H#cI9Kdr^UyOrwzgLG$|#Gi)siqw`6-dohy z@o6oR&K`S^A5`=PQJ;8E2h0XVM?*UuX`&uXd4gGhv*+cf9 z@&BU#wrs%r+`viat5WfE;V1iNS6eOhYdZX`{|B~(<{xZ7nA=VHLCBl#o_-m05#2>k zDL;t(9{}6;HS2=+J5F;QHaoti!j4T*nv% z0o*^_8}g>PfbSGJCy;x%-ypBExzr@k^f1n@&jB6oqj=p7bNlt-xbqhhCg!okuXX++ zi1Qbb_VX9KCQb86T3a))7Nqwd>z_-E06vnR-tRu_%Qt8`62kLt-2dq7u!p$*`XZtp^0_P!%3=SSp|$sQ}Wv=!5SE!m*?b6YX3aSjI`4Vp|Vk)Mlk zllW|kv&l-ikC`TZME>mEtkW`nd!O~O>;p~<;j6r$mtcH}y1Got_R$`KOMHU-%lEbA zTmCNaF1IbI=d=_sXg)>d6sJV$IKNuO8Zv(P?MgYuk)I;F2?HkCO>mKIH-~}0&|BQL z>^)9%0h{6!IyVgXD_s-^y~lRBc<#g-35JB<91Fj}f*-Kq@A(Sw-%#-1*5SLv9=fj? zc*ecaT9Gd0kuIK@O?m0!S)?(2t@`b5g(GhPD}pXZD{hjC!$T6ylkf*p93VV2Y?*zhfD75&G8{zulg)&9!yoRn8y zEz4`MiLW_*|#JIS8CRuJNbslvfpASubz9SDeg9pUx*8HWNhZ4m@ zPDv~er%1WR#?rnDo0kKNZC-p!RDS)H(&mYmciMT0g`vh%d7g{TdnM|F5z9N$KZN=| z0sSWESN^h`#zyJ~Oa27EuH2^i3ytQw`&9l!KGQ@r{|hwR=QZtfkMZZJs86cKT|a)3 zVeE973m;z$zhs?HS%5sJx#)47CW>QeT>0rhTSa^vg*l}~|4yPmfM>EFYhG@h%_4u@ z1-7J*4fS}Rh4}r8d{TloWOMQFg;{pj)@D{WPlmo=pUAdBoMV2pqwM$3g6tg~b;m^9 z9O+(I-P{{73uMyc((4iT8#~9E!N--amN67!=$*yp;>UyRzg4_M_L2&@xI_iyLTewY zjf_cskb|l(W2TUl3-zu2{()uh#QVFDfnL8-%El$$kh1BdUBK3jB272Kb2-2MMfQoL z8;%&==tx7`2Xt078S9N*uHnJPZ3igxGmksR~vEI1ErAj_Je>iJbO!0e=bRPf5U@qRE#cQwcqE12arIwAbIH_}0AhN5 z&PaVu@hY9k)$NaB@Bt>?Q^kIb;$Qj&I)8E(a8)UpR6!;@r$`ki#_?ST{JQK6z#`ch zr^c^woQJ+X7kz#X))+=$ZJEcP2CW|`_SbPz>>pI+)OSW4t};B2l>Lz=9H2|5gZ3ZE z-jk63pp1*sMH^)L&EB?QIu1`94x&MaLo|fZk94Mi_63iJT*6rAX@V`EivPy}KhF(Z zEjfFvxq-8#4F6#ZU!4*s#~kdfye#R#`#+#Z$K{ppD>=nR*r6x=Or4Ow#@42 zA0N08=hc!r`o~HYyIbSYKEz<2t8AZh9PG%7S3Q@j{ClswjC75BP7BK8;{lx}np0Ez z_%p?!ZoHOEW%1{Vm3*b2G5RE4JDvs^(Au$t9e3uKaC+dkP_~}V9S3`~&rPMB1rARP zb1Yyk#o2qBt2zwNLo~5?F)mhex{OnrvsFS) zG}q~@jqgIP>%G)&vkYy>miE3zX)LZ0==*q@_+5}DjjvluJL*YNyq>6a z)_6Uk`#Hiz9HZ0PXyv`Oo*3sU{)=p0N)qVF-@O}7Iu`6}t$k+6J&2SP8OQ8=7V>u- zhVQD)o!Z(JeO-k!d|2~dX{~uzV!h}!tdnfOSqAH!8)frS2d4J$M02o*F&p1bJ=<`# zoPfQ@Al8Ghj|XqX%=Fhnyuur+U`x>V4t7=)VA`E{(_5eb|@(1q3oL@+Si-qx^koRwdvw=l)VF;?o39Xe~vZGBUnZz^oIJPnEIl-QP7#J zynxx6tj>XKd|3OYID};N`2Pi2%<3H*=g7e2xPq$B(XBSG2XT2W>S;8ik$o02@Y!fBNaT$#%m&2D> zd*+M(nBKl7gz>BREa1&E9WNe*^}wmn!~D6pGg#?j18h;J$s6HVWHb0gtX5;eYz95n zI+OPos`K~n4O{fOk5sBlMgi>uI9t&=RFwZ&kT+M7IalJrlsmbGxCS|?e` zYm4i^KlMXZnERm-`FlTut)?@cvH>=Hngjm8>oD9uX^Q?Mxy~BU@F-~gyZQZyQ#y_< z^KQWWzDs)yvSg68hlhTpcS7^v!|AM%Bgx3mb6~y(d#}X)US5W0HQSt1+>E^;Yu*VO zrfQeQ*NRmb2R9_-^)px^5C<&7zN)Q zXVmmK)>B=CwluyBf(|w(8~G{NFC@Grh&58OJ*$U<4r>gu{A2@s+1cHVogsYN4f zKQD+RpE@|pH2O|T&Y$K++s#QCEi;f}>@B#hn}P3!XNV2x7uq8r-?I+?iN@CbZMCOk zoDN^kvZXQbLdc%(9vF@>vJraFyuYmmG`(7a`4Q37oSbsuAn4}zD3kYy0G5tF2k&T5 zK8^ELh#ABCyBADK9zKoMbOt16w*2|RGg;q329KFUSEhIg?J0jS%Ab++QQJ)M7~0Z( zF2vt()X#Dn1yw3OAbE#jEBU5TFb{Xy1kq;;x;t8q+tnuT%Ah&Ue8?%ktvhg}iDkf{ z*K5JO349(lQ#^>W@dvx-zoGb9jOWz{y60Q`-HqqrcqUpG;{Sh9uP1bZ)^AQ2yLeMC zobPxUeRdA$e{k-MH(#3D^Zo^MFK%f`K1}?ce7Lm9BCKI#CVN)V{PcR*-~+HhYCrY4 z`!`Wsi*@SPQ(%J&5C_s4O$uzV4Eahg<$8v%ckG-QX98usSX9eC_R&x6F)r|%PtKPb z-(|nNya&!Bp-97g+v{N6xM;FT~`pEsb-+hYsa zp6gn1SfhngtIs^(zE6~;V$CInzbu|l?MB&p=v_>ioTIwL?9h3@lXQWuEJoi9LrkLTvM*Bf1xaRojbbba*zv&+tQ+P_tQ$Z7 z=<7ptEQF5y0{A7+6N)v5s5Wvxag$Gu^-~9MUAcdiqQ?B2dCdP5bV+_H)tHa`=qFhF z`i}9HRol8q`+F375NyYH4145vHteMCv9N0u?7XLK*iC@#*~qXfpXd5b;DO?arn{Jj zb5>HCDhiQ$VNVuL|JRJOIm5>y$)1k>Yu%7EQR@!ym zRWuDyH1(HhnwT-8wIWN=Cgao375oslUDy+69MJX&)RFRiMCr@7OnV44>3Y)G(pEfC zgXjK~;gvnb@Nxm~alj+rPQLMC;4f(D&hxuv3U*||NrY=LV3W@XYWigPg<~L}aq!I# z(|IT8ycgre(|{$`D1=}h;--rS6VB^se2b2UYRM^q-o9+zb4%mwxO@BZUhW#ZM6~qN!J=) z;`a1TOMLs|(Vpb?|Mf1$b%YoG;4IKhKJE;eI>l*70l!n3l03t&vOII%WqB@#JR8v8 zM0?}~rrnD>5dLq_`HZ5|rReOd=@by;p z+&E+36ZIV0oT?K0MKq_f>UL3e>#zqvx)Z!%y1dJA@eHH}&KY8#&|%nfuXtH@ymv{R zYeh^{TFtWCHrXg&l*W7LT?WsP{;j#qsNSZXZ#{ep=Ei!z<30ykhot#$BlfUpZVY`` zKd9{dXb+?p+k+MD@Wh_mVulqbS@=y_nzFL$f6sZ`LZ;`={L=xl=;iyIKz@mQQDM!;v&I-DoXQN3+PJ}-@0JwfdyT6@2r*NU|M3d<2 zC;kZ<2=~0P)5m*$;yu#VU1oLL03(_Sx`Rg=eI0X;?2C7lSC4_5_ToL_J^1~Jca|G8 zxzHI~qLJp#M7syiezoT4hYbYqOfiK6bde53RNY8BU3do>Wp74I(3K(lBpZB7p8AWP zufcO&AG3z$C-m&Yv&U)TePn)~NY80#JCOL#5aX$SrYZM)=@|!r<#|$?XUEU)*8{Js zzgatG2-`E>8!RKN-S*Q^O(59w6g^LmBM&k&Q5AN~pX zh`;t9OEhFdmt3M0uzo@r(HT@c2itjeiC2N=hi2kATYRQy)aAzdmW^+m0>-g8?-_~8 zZ@~L-cFuXeQE&x*L~k#YhreffZ$=)`dKTb$kVmu*mw6dtIPyZ@F`YCXHv%us32P2P zV-T=UcaXkhi)Rl(<9tQq(C&Xq8tYCr(dXIXezd9UmLz5QM+0K1GfcTAPWb$TvN_LAA6!h?q(W(2F+2>|0m9Z)qO^Ac|BziVAJ|n zp3=EI*a7!vrWgX)Lv}I^QSY#;WhbUs3O z-i7u0Xm4JFN&}oK%|=bEuakf2gM3}*>YFG(Tl7G_6LW#r<{1UVTNG(TvsKW%@{|P-eVN#Hb!!ia=8bzpnhf-Bfp>v(UU3uKpUOjO2l&1C%++oY1C|gFSY2; zoO}n?j%nREGS|p=U>wBS?N0CQ*dN6D7`>;Y<763Uh)sZlcP@9j517SY&ov6jpSfYP zw?TG+I<}Qlp)0%KHwkYe{2}R%C0m^~hUpS(0dqqG^&9rp0EgyY{sevYHtH?=h;7w_ z*zMF?jeNp=h3dD!I|>GH4uJnH9W;G>Z?x$Q-U}!jx|iDUH@IF?aPzoF)n(mluH(dttTH z52OA|7Yjj?j*sq&AvxZGd}{C94H*Lm%hoB*L3^?jy$!7?`Zf8vG3L!hy!W!yS-k%b zSbBMmyyL|w{q1VN&r^Eg-;u+YHHaB(YeLPifFt_7qo8F z2RcWx{}y@V7bzC(30Sm#>Up)Tc276MwF`AAzpKg*tZb{@j(nqh!eyi<6yNlN4i*63 za*Pv>-Mpt(GKuA9?Ww(lyQh5rvfK1Vo8f3vjW!Y0CdU`srV4F{zj^-Fip zmNv7*9B$jp4B!huhe=-7;D2X*eHPjmf57slHI)X{Zw>AJmWFSf%KOt+8s+EnT0ZXS zJPk128*H0Q!8kXlagbaetll|Ip6TXy(^6Uj@RvhTpW@;^7;pdaAIJjdIOy47$khsk;SI#SG-r+{Lfx^S9II6o-MnZ$39`BI%yh4c*oEJ$6qUPwx%- zMw`VE%(0yKcC~6N_Z7*<7+A*&A^yexCFy0Db16Sr-7;-Ft<96KG@yf|OC&$fZD#wO zrGC?0V8GuWSPQ$nmB(eBmmu~u))=b+{@0(d4I=DYT|_dCh4hWqDd{O_#) z-viENuW|ne5PMOqN`0f#;6?w{5N+_AzXDd^lIR;)t9WPt?t=Z)1Kh0(Hu$}Gzxtqe z=_M#9opaA4KbQqyi+d~&f&Xd1bzKyNjk8~#gt~cZY^T_h&Z1UnzQhARSJ%_1{rGUK zpAgTrHqR^3w(e8r`GrH^EF+#jVV;R!I-{D1=Q)z+EMelEu#4z@=pSr-r@jrIVdVRj zKW{t(eFXnYah={*JT^F`4a&Igd$XAKE$MvnkRuE!D_T?5c@7N3JB3FX1+PIjqmW-7 z?4lU7=x|NB&jb5Meo)hedc3bfu}cy1<8{IhnFO}C)w(fOQy-Dc&yqYkW6qD8IIGI# zsUlyM(;NZwh?SW%cc=crUM2O<9>AdeJCa8j^Y5zH%=`u=lN`J^+5nkQ9OLIcE%&31 zz8{{4b`7g?@)iFQre0U&?<8ClXQ{HC1jk3uDt@Xm`xMZ3w~40|(5%;Ml;_#AMKa~9 z`VEkvJX1TKfSLZ z*BEZbJBU@9zK4#)+NEX>ct^2#=m4XD&X3PQ`e>;!tQq|>sBBpIa1%TzIZJtsnke@e zvw)xch_60cFrc4tlYuo`9VXM6Dc(lCZLo)J=a@A`NAsD5A`|N~kij<0H~faX;7r(E zRL(up#TxiN(vygyH`4Bt(?u0vEv@HRC>QmN6P1rtu~44dj)ltHJdSo23q1^26bl93 z=UC`)zzdub3omk{4bMA(;dK@Zl>wfNh2CR$e}34xf4miSi-(yM3$5%l7FyB0x^asc z6AM)-*@WLt91HmXm&W`%QLi)KJdSYBU_a$XpMC!Z#}w19rF{vGi9W%9>VpbdmM$ja z*@}%m1YZ;z`TT9QFJt~{#YXR`{Lpo6wN=QcwJoxn(P_ph3^!!b=;%kHpKTdpSI$*`{o{V}! z5MPZ!YIrR;{lt@iGlXI}Ebs$ zXN)k0VQ(P4$B%6_@JFxa;Ox;L_#QfMGZ^P>CM&#+sOwOE!vSAut!b3aCHxtp4tQv7 zWB8riPoEQP$YdzwwGDEozFCjF_`dVrMeWnYO0*9u_(8xoWqv;)kl!D29St3$bL!16 znb_CxtlBs8oNDUR$a~%MF&;b=r5Jap)hGB4D*A-<$N+EtG^5s{cR%Kj?jd%)6Ht%h z@E#P0r`q+plK!1+)x%kHr7Qi>KA2_HTKF^Ytnc&OH=57N{fu)4Jk{}Wh`X|R^Y!RmqYLUe}jE}Y-#43_F&c{a?2b3+zg)6jo0bSYRL z;(o=>V5z<=r@mYYSeCrPfF;iZ_Okc0uEjV@dE2zSsmQZ%_P`m$3sQ~pNtrluE z;&W8bB4+FC9MxcqgTPgeJ-Fyl)0T@hUWeAS6<4p}^JUf;n>Ir-gq8~m)pI$%r`Zph#+vEO8b1!PyhI5p^;p`Uikpg_y9WUt`zJs70bNyGn zbcSE^4I`nel-~%Q)AKJzzLa$jTh^CbvexphK%T$FK96bQEC=l!TK(UGK5O{RE-%4- z$$I%d)u$Jv*my1iOgeM+De_3x({SeOGUQ!|ycdC+mlvw1yQOvt;3)*pJTSod;UaS3EK^?!VpZxZI1 z=KuICpVfai0G`}KrgQ3$JDtIOC(dt8Q-13j#08zn#INM*hkeb~?CLxC8fm}U9`(zB zPkB9(Y@DwlFY<@Ydl}xLBiTQDJIeP;wbjT zxWM~b2G($~-h4C8Z?49#NR2B+@I^F6g;A!DHEzsPC#=DmAodApO=r+8)5b4IPHDlr zTg4PhIO>lp&rH22nn81X+#TnFeOhz-b=OamYoNHx5c4pXIQ#>SVZ*rFa4haY{*#{f z)0pTKeXhY7Px(Jn9ESh#bd|{O#AS)!(MG2)N9OkvTakYf=nVhaMr#Z!<@trsB)JY% z^716PCYprr-+JazJeMYxKhNjTLNd)3Hz2-HK5{4dNDs~;R&k%o{mME#=Miu4PkHcl z9=wmE`g|w#c?i!WAODnTavdcTv{-b6o@6?51k=%!if?{*#hiM8(HC=~S>eqis>2tX z3FpPHf-hYbbrkz3x`<8#^C_K9x>E^vcE-%z0(g$7HW9R`!?P|!oD(gk^_-$CW7szM z9O|pe`lMx{GdkXJi9TO%-pTiWE(4Dg^XhW2=HQD!cg5*O4Xwxhj(Wykh82O1Ies&% zqd#=5-m|D%^-n0Hm^>19E;VAEOPy@u{UGcm08Z@tL9`!}jsL>Hlf`zlP`iM4MAAfxLB?m1s|PaWd$kd#*`mPsD$njz+2b*#Adcd=uJxFZ_<2tduzp~-3?a&e33r*L0?eGHwYbK zdEx#~;2?N`yBVIjRM{Hf6hg;$C#PV(gLiAdb2H%R^q1ki8!k^3`&7AZVBir!twJENcFgKJn{1+b0^cmHw46++4tWo%Ve(#wS`IoC#Rr_;G9$#<5Wt$MDmAB#mPw zQ^^c{%#5I z?;eQp2sGRb{Hqht5Js6UQ+FHEs!7g01u&~H9G`_;1_&mlYqm0W}HIbnL% zcydqVvBPl;+fCW~eD?cZ@VW1Oxt}9rF~>kIC;x1~w#W~Au3)>Wzt;A{$#Xg8ner^h zJd-IU8ouj!K+2kF_ zZ&3U;Kpv*dPs2A(WBqhJVoX}Uxe@ug%xRyTeDpNr6CXOgUX)#fd|kddvVK2tHNnyP zp^^4rFoujrKAmUojK9kWPn_=||9k=R=NxIq*p-2EsXA}Cl`}?v0(jPWsl#(T4+hS; z==8hstkdnoGx=3VD))coOROLAJJOx_&jAT|AV29IiSG%H#JM*7ij+=b42#wwU+2TP zAl42%c-Hv{(6c7nIy~z<7#GIsxChU~L*#Jgp`?m=7zO>d;^uH6>vG9utjlYT2#h}A z5dQpE*g$+g`HIlTSPRp2B!E1fw-BDI6zx^e$1t^tvuTo3MAeC)jt9^2{T4u;&T|OQ zw4O=tWg!MwVvagL`VsgGkK}JFco2^s1Df4W@mT|U&c$=+N#3u$xtCc$_EL;C2J-6Y zoSw|f5SJp)_XP5Ap74?Xnbo_e8_^zUOEG1YilwLa<8Q;zw;3G$=p8TYgTS70JH*m- z2LOM!@gczY;Sjd)Aj(@86;|u=bf1rVeQ9RKBWbMIoj2Zpyz8`)ivW|w4lL5(-EJ6+}`?26{riDIZD!RPL{ zzVo5}(hCtE;HSeS{)~%a`SakpO5-np=kT$ywpB-YakdjiUPR;3xHy(a51zx2x2{tG zC8cM{ea>P23B6YLd3c zb~aGWLmwj?WUrb`ImS;Fuc6HOd;2?%@_kb-bBTYWjC^O=)~WLB$A|AhfAeT==@cvY ze+|ut>6v1K=)19Vx5i^3Z{$A?IA>rF<58qbUu0fi27gz`|C!>&1iYFrGOzcejm~Sm zp!_s(H}Z9Ua#9Fas-W*`%tzS-i$|F^x5}?&VJ5 zakDZ_&8@KRg>_~Z=|g{_L$jkCybD8TxYCiY<7t#=!USLSDn9i-C(WBr4PvTewZ zC^!+wuJKudpDunTIGRi=WxiAV7x_BxB{ILC_>S^bed?PWneP%`A^%ADg7rw#)t>LK zSL0mf>m-Lvu?7E&6um|0o3huLZ?eY*1+RhpfXq)5?;*cR+H9pE@zEk`g`8pq7ncq)5Px%@jrp$MV5b~b`A5SBVkA>>rXe)jc`8vIo$Rk^R z2>Cj_B{Dx%JV0>b`XdKr_aHx_@Kb-7vVOVVobE=M9?mv^I*cLwEadP93<eT9L2w&2(jpKad~KH|fZ4$d4#Eq-SN4k96@X!BP2s#H#S$^V(+OZ?aAAUS$#sL$~J585;+8XG{PDf83B zi^#81`Bg;wYg9i~Jcs=Fn5+zC&rp7x&6XhlG2}-SoCwKG!bulPk?&Xee!?sBo#H`) z6Bn!1uWBp47x}u(Dv?JvP=@@Vl4TI~Q6lsEiFpKH<@=GJBlEMxEy(}pA=VmZpgcZS zce~?aWIR(pt$Swb_&k$+PM(Q(%#g3kER1KJ26s+uoa)1Ko}w`iG=}gT)OZQwnea3` z%=+-;+qNDUpDF*eiS=Mj-@xek7)MK;fzg((gg@arCEs(M$8az9F*HthGKW7g0q?ZV zl85{vMOP8%wANX2k>8-}4(gI$?}vO{4%RwL8uE2{SnDi(kRR{AX`Q79@^yJw>nvRe zj;1@-I?G?MlS8eu>_vHe-+B$Bcn9*+ABkO``2TaArC~AmZ%HoO`=QoZ)+XSA?70qS zhxVo8-kgkBK74Wec_BROeG|sB-Y0I_+tXz0i`&Z!(X%QK!fwNOCLOI>#60BmXCC&w z#bd0z-{K9{!<@COhq>6F+<<-LaNL@g0a|oDbH~x{i=#ahM|&905k(vM8h0G+K1Hiz zKGSN}UoH2fKGkUTtWy5mYZXHZx5ACrgwdpZK4;Al4VuZ{{_$5O9r0 z9bM)nC?j7w8u_~Hb7X$DxCr?=AC3Q|`sw04ywn%^jq`TfLc$ln3l z7lJ>`*ZH2j*~~kgiN9atJ0O^E^G(G!{K$iJ_aJ=5*bkASuYP};;+`zgB2(N8A=6Z` zRi-!_OX)yQbc=k>6tBS7;C;5f6l;+l_+DTfjWvwp76t!I1%IP#mnAmHG);Ud(^T<= zO!0oIOw+|DGR+iUV9YbYY^|Cz#t|9XEl%Kf-3u?If1LFq^Xbfi-4 z;cZ8LOdqNJyJqCa^pVWZ7F#G^vy(=-PlvnBk+1hfrP{yymhv^bDUtd3HW%_wg5O?q zWoyOf_^;EPBkvZ>5)H`LX=Yy1#2V!5G&3)$;vMAcG?yrvUq^mKvyU8^kMn=X*J);6 zaQ+YZLqS`6|2?Mq?|Eg%h&{TfKK%3p){$#u-#A4L_@Nkil}xk5Ea-v-$6dj2DxYOI z%K_&P+-py|_LhP(TESVa;Dji}8relMKTTX9(^OGJDb|RZ5lgniU#8$!Dmt;QyGg-c zuHc_0+h>aV6n*&$?ob8y6qzD6rW87TqI^yl$5RS_`w{pl1l|2qinBd7{w0jx?7{E- ztigA=-U5EVrY|KJcPM5aMSWt~$3K;PpHOl+JTUs-XlLL|!EDg&L~7l2(>!r%`&~C? z3Bzhz)Dz#av+rbYom7bLJ$muI$N$K0nOJz-_bd54%6OW9=OKk>0`PpO$+B)S*Y#F# z-K5@u(f6vlmy#^O!`7!LO%uN${Z`YL@V(r&j@Z&IINw{vKdF%b~N2_3}Ga`Tbme*JtD9*hTf|Tdy~QrunE(dl(k&;d$Jq zWHGnNRCG740iBT7TuDckm?P6Paf?h-#mzF!7I$fS5SXj*-^;MpK>l47yw4Q8DGJ_X z1+PTGo21}fMJa6QO8J~FuAmgMUZ&yk+{$?B7b!g8r-kkmguGub(xG;yj-F*lZJwirq&XgWnc_Y)_{6!%#m#re>7Uueu? zoMrPFXA|hGS2!0doH?>>x|pT(Vy42KE%Vbvrc6^sx=gc0Dy6{fl+XRd5vsg5(j?$6 zh0N((A>DsV|C5j|L~6;wcRkb8IG1U9O3^b#(R1)gz=y6}tmwIrQux$;GCxi1k!h;f zCDUxNlT!58cKMtxey0@l?Iiq|Z}dQHQAqO*q!tYxzv{nRR9}F;d7z`0)?e=HxK8D4 zu5;8ItjnZRq|5Irx(gKDUr78};xn1zo;{hSighy079UXxI@ikQbnyYDm_ydf=M1qH zxSIf*?wKh>KgHO0DbwP;k!iV1;m%OFS4tRJ;$@kpiGRy9RS218iz-Ti`+50{?^emw zDbCjT4NYPkIWrgs(U7n3{8f+ku*FAYyDYIxrdS)3X{uNv(`@linWl>eC`BLKM=5v= z%KU!f9;9=%elR97&a$aC&dj)e2v6WTC4R2+v*3Op`hI~QyHe4(QPDU<;>r@!Wtt|Y z$~0A6C(~>(MW%Rfg;LOV9b`}nSoA*s0?fHB9dVCiyp`85-i6SmKW=QTn1lN6RpaHl z8^xzbBd^efJE63;wC~^^tJ;@x`=g#ybfYfaXLth9jkS#z6y0Y_y0XNXGEEbw%QRIC zmua>rkZHOYCewamh)kVg(G>(IQ+&S9rrk4&ao1n1Q7uhyT zB*_%t5R_@E`0EMcC0iVjX}b7Rru{_g|HIn9$46aU|Ks>;6D}Jr-f{qiGrxrx&dr=U)Gi?h+3-&+BRx0;0>)>H$mIP z)E4Bn3u3;{=bU-v_1a}Yf1ls`k33%4nK@_9oH=vm%$b=p_x`Bgy8>iDh z(CP1~FYJF^=ik*A_CLSi+dJxazWJ8=;%uDyW}1J*m-BqEzpQb}#?DuBWYuQd#_~?k z{dci$Bib?&=fW-7^p@-V>5@P3VQEVm%6$o$dK7K>J$$}a`6jQFFS|&}x1r7Bb$fg3 zc0H}=8(==AzB%U4)i>LGTzv#U=$FwN!GS=a( zzz<%Mb!~B)UN0g&4Se*D(fpY#b@N;u<8Sg!2adUgsCPE{m23Qe;+uxL=L>(gat-J$ z)$kKFJj&_$L-I>>{scR}zl;INAFcDtCBGc-h0gp@I=@Wvm!tkqt`*vxc#N~8T%A|S z^{ChV418ZgCVwsRt?CS&A!Q53Ynp(QZv~Uz#hTwIYkm(^Uz~wZ-+`t_eRIu6K_l0w z*HkC2OB-9it9oxA_7HGSPMyEl(@Vt>SSvb5>OW1_e~#48x&N2CO>W>nh`uH6IZ3!( zS9Mk8fcNL1FBd>Yta}bI+>@YQwSMOTKKX4g>pcs|`Boz-h8g#i8N-ZYz}-Bu!LMVO z`Be-v*@Nbt=>B7jReTHDSLBC3vkq%9;_~kDSAPu|_anY; z_84z`?{K3ugxFgTyeQ|;19%I#9eX{zAKfw>v266+XczABw&VUx4(<$d?czsy-|2D& z=TZ9(a6=gW2G+^1@Br_Bvc7cS#2swX!n*VF@tbKnR=8DX_(Z!--m_($ycg?S(+l2Q z^Y_5Zd$CP}5EI;ElzI^R=MvDx_&45M#00?IX|_4i=Eokt#Eart-4J;6s&22QLA{3& zz7tw;Ifvd!xJd7il(ZFJI9r_%Gy+mSv8Z}D1u^B;4Z^cC)hyAUrb1|GBh z?8jh#cS#)Qsf+b*cmLuNO_#chr|~zi&8hfYgSuk)fUcVdL!Pu8QMP=AsmqQ;*`p410pPuiRkc@JhVgeSX&3;XEqHJ= zABJ(J=tADjcna}>anJQ#-bZrwP2FznJ7M1YdbYZcyfuAOSv)jc<~-MU@%b(|F;F=R z@w%r%<|^9sy}&vvCOoXohIWOcYxiXAvDjj zXR!_hy<^b6ETmJflCJ1ULRZ;Xo30U{i#T@xC&$Ahf8iL#-q_-)wV*`sP8l zaJT4lX+v4R#5Tk*?~K7cVBRyf>hu;$osA_@=W_7k1XX9Ad85LaZ(fft<#P*YAT3Rr zma|%fma9~`Ow+Hvc!Lf!G+_>#Mez)PRKiyY>JfWfWM>Y*_Y8p;fe83rFwCOVk9lSsJmA>D%{wVkR zoOHxd|NZDU-r+;QlJ0whmOO3+U7o*oZTbi5VVSobWo`$YKkm4o9cewPXOPQp0@4VYt!I6OvihEJ@BqyPrUDkcN~}YjvT_ z*f_hC`y)M|i*WD!49r(mVa&DeT*T4Gn-92;toBbBYq6IPeUJB`IIr#Qjj@PW*Nn+> zGsf(0==2-#CdXLByscR@5#u!9yaVaf$6Bw;T!u4G1Mp_d<-LtFIJcCb4L;mkw`lqV zyb3&0hI>l+W-;KKPKv468(zqj6OYWj`R1o6!!c8aHqC}SkhVwr<2?)f-Ul3P=bwO+ z^lU@fOAsdw{Ml-3n;75S7w3!+*SD>A+4H=6mVx|0p|SBx;ILwkxr;m{FXQc+u-2hr z1G*dY@!TGKPb+tL5ce)WPs{D>1Ns`lTdVEok*;2dsRW*q)^A@xJ8_?$b-V5s{)|SM zWd3-u7yAU@$e&jH|6jm`0B7;%5!IHS<}U!7k9h5~)jJ1txdXjsw3LKT6BSF3N`RGSgfEocjjF6z`5CN8~5R{%pjiclHPEPV)E` z;E=b-^35gq{~z(L(H|mKJ^O<=3BLgFR(md2?a49gLBF&O?%jky<{PDydjoQ>&PnQa24xJWGnb5e!#Az8e@xl?p1)nHd?1Zq$Tw{O z>Ezs#WljS9k0PF8J9QG)Q%!%7GG#mDyJZm8dOwkQ!u42e4P$g!Wqt2RnbubME&$$D zs%)0IZ;in0QQsVMBHBRS&^~9(Espi6kNdm#910L)gEG#$g@=|-fqs|_JuwOT0>1Hny4Z zw!^T`Noz-gU)>FE?vFA0ZP_DrM(o81%emb5yAOr$qkd^kcO%|r?BS<@i|YvkZ>9OQ zeeaK*Qfl!n)GYie_(;C%kC(OL7VwY$jRx=#v}SD?sC==iUyLRxTlb-S$7()5srmeb z=JQuoF6iVYXZ~wzI+SOr;kFOEP6bD(E0D_e9%#-@!zHKzOV5H@SFYk5a5@C zzK>=D*5!c|QEHD0c;LQJ#JYy3bPo<9(I=%bq_2`kj5_-L2+fg~PK+ zU>mhOvme@2U65O}x6(mZ(+g6z>}~n3McM5rI}K%)px=+S&g@F>yKP@O-xQbmj&Xr0 zTkblU^TO!^Vm_m3Ty#WWoFDqQy%w>c-bics!zIS5rp2-ja3kFfxnyjrzBnJl*p43P zog2~4cE}^*FYIc)8a5l(eJ+%BuKTo}Xz$jCx#lF$Y^_~duCrs&x^Bcd-lN2#Ed?Co zRzzwlUFV5KI5*|DJ}3>82!uRd*)!CU6dUK8L(ZW*HkRU^}T;WcvNQgLBd%-y$Yl%|b0dnSpUFlpn+oYv&yIcw(G; zZfs+d@te@J8>dLSJjdp#_0Z#+2{vzlrNg{y&iF5 zXQ5A=Wt-tk;+RN7{dgdHG{)Udmx?hgbQFM&rt(BOB2$HqGT6kV!(W-24#Xj;+Jra? zuS4gBywG_LT}HUk7yGLj$EykSQfJb}zjUU&fiw^{rO44B#g8i>NAv|91g*aRc5UMQ zTJq|B&}YG3q+#cM*BkvZ(EL}Wynod6SDOd5DR|JTW0f}p*QNt%{jgJF#tILj=zGt- z!h`MjpYIkpd1%Sc?*PB|?pW#TgAq#*w!O2x)>sOo494+F#*9_GM$FjffU_xR^O!MX z7q2K*F=I2l^byduhrWbQF@UwkuTY-6pgp>F17P8^;%~RCVH(_q5zj#0cFB|b$Kx$O z;2<-Kbov2PwIKldZobR*_qh?{y(W55$<9o7z8aqpC|n3};Wrw@wdx1qe{*GTXuKn9N#FG#mj`8D>ypFliK zz@vN$hV4^e`pZZUI^M6Lua-Uo<~@(R3azgyy7konvj{w6yLi|0pjyk3Z-dNmrO3Qf z#|2>X6l)yCz|n-?-(rs?7k<-rZEqKkwfn5@9O1!{eA_)xH+|dQF=9&MT&lZ2Jl(vbDZm} zTnc&TSa^9xYz_B&mLvAvbV7JEYrcA-_dQMV(gfmcXUJ`5|3APEp zoqTt}|H-o#PTE5#LwpC5aCvYKC8+5Lf({>kJ8^}Wul0WrHbMdJ8uFeY=jdASfjH;I zg$K8Q2gME=}vkJ zpzAol4A!{EBA+xajR}p@lkgX4{3B7$$%oectap$(JPCiJO2_>lmUr;QlFPwJr!K6> z)O!0_SufuBTie$6T_ZA9Q!n50!a(H>(2?|ue+#-X&!{zl=W59>SgvIfYl6in$2G=D zXh&T3vt|A8V=2=dkZ+qOPMcaZrizZmbY;M?xN5n3#;jd#j-OF^LW zLf}{jnn)x0cn|)E+@HWU?mgCDeKN)x|9`8mzuM!%S`P8uPQ$%n+PUqJr^Z|6jAXta z<=C!Fj5YUk!QXM4{$lUF@LHMcqgaP=?|mP1nBrqE%}1mcfro*G0#kRZeA!O!y%*`W zett3b-cgtFm^J?({_7%{f0jDh>Rll4WjD)r0oHHpC4VK?W8NB_f0JELA6>_vPzU*W zmEtGjHsSjyU@IPw{f8Rd_jbl`osT@ubsGT3b!1&bSJgF+x}uj#9j({fb^Q-Cv!9>U zbxl`w4KgoOU%Xe0@2w6TP4fh{`8xSdEWK3mo&5O{V|5s4C(YvkM}3UGQ0+7>k@Bu< z@oLx!-(K#Ge~RxO0pcI--bHr7jIK|>4)rN z)}yZ&JMPz-9s~Opq<^KR|3OXv1L}+QEO~JFv{fg^)SFkF+oPBV*cUA)`~*JG zft?2CvBj917}s<$c*Hq-h-*M6=f$ZyeJavhLGKV(Zl~9tQ8LusBwo^CN9L&LMTM)hSy(^cjDoQt^blx3^Uk0iDE z7rM>gEZGHeagDK|c63`jr zSpnd2^PV*D$lRT0jzHd;gi&dU6t9XwSR?o7Iw!ny+n`X8cc>F@T|b z{H8(Xg+-Svxw&||gdN2s$>$w&>}aJU(DShV|27Mg3$k?+LmVk6MT_!6>o zC)zI3AprLpQ1OKEoEAV%lC`(geI2ddD8=$_9d?_ zQhq1KQ=S6dUxK=vJ^?Gncn|3QBl!gMxL0##7UF{Mi>LN0-1Yy%IR*9udAnruqUvne zWb`i}R(JQAg-=lj)22Dn*#7WA`;0;v_T1@j*oLw=6a1nZv6siY+?{+&jOkV#voAa>y3*=BLQ> z{Ad1k#KS#P-r)$HZu$7!=2g%mN^Y?4=K1IRi&?I*bH1X#9QU(^Lk_5?lIx3I{wnre z5ua;%8qQ~=<9vqE(5}x%UXHVu`_q>XKrpSH1+(ayKo>SN{r!z*^ z*@mI)iWWV8v|t`+Li=?&b+*X>ud3kNZyRi6vaR%&dC*?=LC`Vp;EZV13*aZqSak23 zQ-(d_H`RSK?)No7zdCW3sdzEj=KV;|I@Gmk3(gnI-hGyN57J&hS{u?VUNyZhylVZ| z{E_5Y6nwPLluF+?>r6i9O52Zc{zmk*VeHCs)jgrxplnFigO_3w-UjCRJhqj2?wV88 z+rV7&ac?6d+M~e;q&?^M8u4jJ>*Grs(l|9A>SSo8FC%YYy=)U z*O(X>=U#>V5SQ_s``1R?{Sy9e&x;s=e$Ng02xYDdjMMy4c9(Hn>T`DE!J8$B)#l4d zonMOl8*>abFBp3h+e14t1erj4Hn_`9YY6tic|9!`e)N9;a+2zdVIgonf|zkU`^Wbo za1O1?i?bcehIhm7B0S^`c0|@;XM9y39)i4&kiFT~iL!1hABFut^dn)mJ``I+`|GIi zr)l_d8~!o{51%LCQ^EFw9!REBeCnCze=tT;!TeCY^G5p(YTP>Y&VSDT;d*Ds!}EMCiFzm6$JRR+)Y^K-_lk_Ay1&R+T8?qn4}46e zclJzw4f@6vIRu?cJ<|p~^BL;qxCp_|)Y1I5d>7=xh5-%9 z<$oxz*L{9CuN%PY0M08>$G?SoEgj#gb$qcy$A5K;@VX9p)B};aL|)_W{~CyM5gA@V=VZ2TkA2Rx-jfD4h!sN66yOZ!~H=E>h?8*v3J(EvgRJ4~Sh3 zeYYxod4j%MhQ5rY*ADa?8U-!p&qujJO<{WGPdaZ(&vPHo01#s*@ zoyp~89fNa0$a?|jm$eR0@SE>r8vuX0rdhQOd-w-Tq-V-rmP%85_}IHaI@{Z>>1u~A zlX`L$4UgiC`R;R!_(YBGNIYnLgL??V1Frv5@!&5Ojubp-Q}8wq=qFg4qP)d}SCO|F z=giZFaDJwLA=lh@sA~;n!E+4syrVrHoS#~9EZT8HdgR+1dPI%~EZZDR>d)@;2(T}x z8<(Rm65GPFU~(SeaSMm8CkVb-{n@7ArEEQLur1f7C@*cvGFKq)L!SL|@C9>GLX46! ztVOMJhIgR6Uzg?FBX}~+n~@%_za&Qa&!}BwpJN-wxhWfS(?u9N7h()ufU$Hw#?&;N zVVfGk7*qNc@-F(TL66U8#5OC;!?}KpU*27?%6L{vna1^YnO9JTvNz~KnU4nGn~k>f zY^eq3dr;t7*V=Hu)^NutxLoraNBQUjQobf6U+U5j$~*hFV3(}nOVR$lJ8eB>+%GV7 zPfK0pXh#EJ_Z7i@)Y`UvK;p$k{>U zeS&YX_!Sz8;a8~8|5xCDzy9Bk|G7^3E9b|q>{(ye^g&L7ICNEYx9`Cm^uHwtRjGe`~jDerm z8O1uy>CfSMxCk@{HLrr;RUA0T;{kiSHaXJ|Ae}t_Iri|J=?9ViH0WnPwXVY%;(GW} z!_aN$ueRRhk#x}Jq`{kl2Ks|J*U%5han^ycL|;?~$1wB=eGKA5%Tf7yTsE{IzYRK0 z`yk%!WW8vUPw^$!yi9#_%=!3Qel?y;Jn{dizQ61GChGdib$woZDbJ&{JX4OH`XP!o z1|50|bA1)wd)q|c0>|rO^t&@(-v7=rYmxrgXI&eeynfQb>oESe`kH)9?rZYt|ANn0 z6eR2~ioVM;&jEe=VTZNrwmIjnQOJ7{c`Z7Redhy>)JL0DyK~G_QHH;sbd-0o zjHTu~?6Fi|!||MNe))im>mBNg^Mv>=bm%MJB7tpPYQx?L*m)?^HNmxQ&vdL`m-dJp zN_SxmD{K0$E?1M9e7@B50eMLwJtb?XW%joRnzizjd0} zo;$REA&5CU8OH?7nUqVM896M^v)HyV8HXkGtZieyM;@n>$4);%YQIVSio<#PYDH`f zeAZjxcJZ!*E5k6dC?lXot*bQ z&&*b9fBIC6^>&-H9sLxTspo*j(of4V-+h35>8C^=&iC<&^0#jJ;XJwlJo2XCQCSj? zDm0HQc^sB*lvwZCwNfYJ4ZA{|R~o##YYp_1@-^_zs~3I$JjT0$wR+}Oti6(aPoBAn zeDOVL^TqcoOMczv-w{){TYjf$`K^)f0-VQw=m>mSd{ExmD}au4zOzSKcYo8hrs+V} zCfYN{VjQM=cW)u!j`Z$c8s6G#1CCIvYt!4n!MEx<4g0M+*6|PK?}twa`73Z>v~}<;{MW7H}p$dgS9RSpCId^ zcARbH_%1#kvWj(4Cj3Bt(T@#&=*N$--to+t82<-+K4sG<$G`p+?or{aC2eK!a)WDi zS-c%-^rblUs%4XJN58#)Chk?@obcKBpY>Zdj(Swud%#B*&J5G`&O=%VceHq)qZwo6!(Za81N1S< zY^Bd2G+K|{i)8FBz}-K_Nv9sHxS!t~bF%ton-lS+zvwjVhih7t&r<5oHkY8TF#0PS zcXFJx5(oXC2UGMRZ3HJS+6XtoMkqxcg!2)nZY$d@HbS;}3DVy`$=JyH+%+dPM_+Zzk%E`9oOifZ>ye_o)whF@ z_m~Imb@0OCdoJ>X$2gY^x;bv#V(TXCL-t3xn{dybHa`6WYfx5=6^%0p{<1$>^zRn@ zW`8U}f4m3%Pq=RZP)07 zzgqTRD!&28w)jq7vv4^0(cOOvUdmc}U{#9p(nmSwZ;+Rb`|CjmuO$z$bdc9Q=5swI zR{NhtTSM@-C>~;s?3z0{{!88dRCrbcPYKrZySE#WeJH2&<&oN7B<(+3enmE@8}9_Z zWS!gHeg!XOE%~iVQQm6*HORxIiH&~Uem`W(NZR|LEg00gF9j>_&=<1hJn+i&aWf>C(Akd!e_m<(C*YrV&DLv`yCwj7VsOU-Fk$&923RbZF<5!!Fz3G~+a9y@=D#v_0;tb7C7cF(s1?8`g>^nCrY`6mx#Ty7UdZeDhwE&FE7Mzi>7Frz|;&Bm>C-H z3!0v*o%mfE{{Sg_*9@_(NDuL^)UZAWOtfpBS~Jw-3CtJMoiJG@mLzLtq5OLo2VHL% z+YT*-ZC=m)yL9*uTxvfPPJwOR`cF3_tPVn+XiLpZPqd|A2VySk zVFnG@8}Kaz4MUwrq5SzUe!9{Ibk^V;498D}!;i%CR6MuBa;<6%<(hTm9m+GNJnoWj z^&yTG=-Qg+n$Z1D?26xCsrGGsxC_cV<99tHwo_n;!{+G^I|gtD?l$1N(gnNYMwE*d zN-U23u-o3oZ~AuJ@TWNSwfo2ZSTWXht>7!An_7 zUl*q+FZv4Sf0@UaG>-Ah`>@3tcQJfOA^ctj{xpKGnwPsOkY0y5l>HQX`O4~%z{BxJ zzs^~Z75dh_LorVd#=WIm2VY-@vrK-eqrnf}6JKDc=sDV>x4Ptxgf6p-Wdc~oe1NsM z!httvn@~Qe=?pR-cL2cW4aVJ5682VcH(=9s=y&ofZ$0cl%oVhI+=j@C8?w@F>ECZo zDXm3+hrW<;R?s!?I<{&3C>dvKadzWN=(?WDPRlg+q5oDN>>ACs#?ypmCr#E|_aBtY z#+>#c#unS^%VJwOk7k-B>9RlWY^w)z!qYt4igWBIfOcnID`bvyz;@v5*6+Wy^?L~U z?;($6{)R8{Fop+ZQQhzUOxji!leR7J1S(H~?!FK8(6(y^jI+NRchcXRZ~h+Xq`ejX z-{n{fvCS_cEfvoLkX>bmpiZ~z#0Iz9zN=^CVSoB;_;X?ZxudQzSM<|&@{;C7;T>X} zN*#*!=yt9Dz7g8faF#VTKepx+MZ56x!(NB;Q*dRP_W>9A!8L)!5AO$pv-y95lV^5! z04Mv0y#Mn$b+<_F4?T6Ijw6(3Zbdp}#rvLy|61TFBkw8rEOT^F=E}41Rr8{rk5@F> z{nhvl`OE!+snC%X(3Ml5GbclLPQrcx=H&XsIl1ZYy8ph?JV5_#MtuR$N_v|9rt>>& zdVZ_vIbPFqtor7fjQ3&j!T77d)%{!GdYmXSPx?AL%NOm#|HKpigW&N&-zVdl4m?(S1AmnE zx}wtFE$Fu^G@n*E_~Lz2$~FH}%1z9&`7-n2E34a-PRKOZ1Ge4)7ucfle;&#N(-v3qaj&)$aMyP`=F{lxiSd`9UtCx-{Q~?56pQcV70dx;Gt1(SBTeZb zJx8>F$D#*v%pl}4`xLA(5F@Jt<<#0LY0VI})=c%BgHydhDC_%l^yg23FL`~|JqIgz zDO&`c$2ISi6y+^_SA)C~*a$74hwWZ^6KoB9Z(T;4V_;`lkx}(|TE4pP+Tv(i2DB7fL3SP=uGV)rA@)j>XLf%IB9XR$& zF|ORl-8tCs_y^Zv4jqW!2JB()36_60%UlF~?KWE84fc(F<903jMNreA>?Y7)bMS@mulF(RQmX&j1$! z`E6vZrC#`-wqh`e&)t5^BJw#^>;gG6$g%jKg~QRtZayn`DQoe0VT$rXTb6kz@@~NS z2HH}eHKwh~P<&pj_}q-&Xi^UGKsCIZNib4eETCKzM16A|C!E@ z$hQ#ZpT{BJ`{}IXsCVcW+CEqA%(rNsQkOP$o8T(|zR_)6qdg9M8PzsE+HOa(l{$(hT-~MZrMc*zKxfxR#sZs- z|9$(qHqus6{@=T$t&NTHU4S-UiN5nX>Reo9*BQXM;qNHJjx%au+O~SFn&}E8`1X}e z^zz|nBAZ|r)BbR`j#XzOi&0+?aSwUUGqC*ba|6roIhXRybwL_r`M1~E@hY6-(2~y& zK@)w`PT7&XO!M!^!-WH-Bc|UjcORTMXn$lvekt3BmfGj)Sbq~>XW|Un^3ie!U;)00 zcOR6+jn{=|&7X_ykO#im=VNU=UFkjH12_hD?6I(CkAq!%JnY*O-~-6Snc^PmEE#nI zWz0QQ=61%v*@Ql7G$+J2q0fd4!Z`=X4}X)c^+*d{rq^$Jf3Q8RxKz=$0=Dm?^OVfi ztPvV}{CU<$;$P4o?ZAEbF!a8WUmo9BpC98nGAkz9o4^~LpNKbnX>keG|0{j)%K~mI zW3$|aa!uHyp`|+PlG3Ffm>Mntdok+kt!x zj=i#aQ_;-c=MX) z+H=edt8EUQXVpU*V%TTdSf3lCo*}*?`EVMG$b(cq9NIqO!)di}r10UaRq#^Q>etOF z$_s6I<~HQzz<$L3;!4jv)t5V6Czi)Q2w}b|65o@xHxw>*#CyWIHQuuwfIUyQgANPt z?|~Qb`gTQOTWY);T&GQpzfQd1Iek#K4Kqr;hzneWG|EL_HpbMvj7SV|iO6Ra2QbOk zRc!gX;1{HyVF7d^=W$zBt?k{wPaU+7!H$tpyI+*;l71FYU=U??v8N_@taZ ztblz_QTYU$@Y~4?-g{KzpzzA-Jw-hu?M1yJAET{Y>v9}9eR$pL2X*!WLShilbt29MFn}qW1y54ro z>kN=R`61Gg68)pR-KOW7Qgo*?-9gO_Uk-9co<0HH|G5++A~({u@%SLwnf=E+A}jT zH&$YfoPoLWV$7M-;rqD=@eX?`|2pSr(%|GZW4utGaa?zZ-(f>K=D^TpG6$AjE^}ZS z?)r>CoJ`!qq3=VL30x{=3NDi}ZI~ZVMj7@g*CSRr?|doOI^QlgNSC{_UVIO?t8cbh z;D8HUqVdlYINmopM#E_z%u3SgovZQBm2wMEu7@gzSnq;Ql{2cPTw}GA8yb{(oo(Y@ z$s~t(3 z*e-Y4T_Z(LS}~nBieE+5)l?~U)y%Zpy;awBrm6$)D0tb)TBN;#u`biG#u*;V(}-#A>yeW&poSR0a-w&mAxmS7_D=X9)+5Ao~)=tCFM*0?UMhb1rHyMA0{e58f71d6@ zkZ-r(+z<2ekmux+#mi4|j+Xg@zPX~>$-6N1Bl@9r2m0j=qhUDuBZ~fL>pdY-g8!W~ z1+brzOw%n6+4p$0{CY($I7TKo^T+G_@wR-QrQ{~ZT&;MNWsY@>htN1FUv{39fAeZ> zBdf85_uYZpz}(3*#atse&zW*e*gi@*&#UK-?tA@~kFx72+FSYNjf#dm^LpK1*WsHF z{JaOxbGy}!wltkBwAGB!ZG~QPJM&9*{@Ieh7Ws^m&M_ZxjHN({lq)FJZM;(2$nxC3 z83X`l;ZC{y1-=6HO$_e(pNddxUWU>nb}Vc!KTWzgBz z&Dcx%zu;|H^Y%nd*Fg2nHS_VMZs?C#yYU@m5$XfyoDoHTh8=U52R;exwQb4XR~ksT|0ZT>db7}^mldfGk(zr$t`o@JWNXlKgx{2M>~ZdmYb=t~#Q^x;le zkbC+CXEyN8um}4@IX%6R=h0sVe6h3%U-)E9#Em+S=J%63Uyx68?ysUU-mY2FQbf;v3lvT4|fJ9b7Ng{iR0yY2Cgft#ez~aSlKFI`hwGy?b3+q@}oeI0a^w`Av-;p?lWLDr*X}3^!sVFr(OdtCq0eo zJ)BJQC8S$)`45hu|4r=Q1M)s?-M5!08@k7-dfvr5tzUxfd6<`|PxT!&vCrcI(|SN) z7NBf8${85v?>r;r|L(M3_DlJixLtlfVnnn2>nKkhHz&X^;(y@F`nX=TXbkPu@cRXx zZ^-@|@NDl?l*c-=p&ftc&V;Q!&l_okZM_z@^okDK?_Zbj@U zb*BnzRHu!o=cB{!u5pZvQ1s=Sr>XA%^Hh9y@8}VUclM0@@yWDRj0+yra{4OlSIf4h ztOjXY7jdkmy0a!Rx2Yp9Kp!dFT9uV_OD<1A9_#R7e~a|=)%0X&dU~txK=V@2B75}% z%`~KaG!W-idG`!{k)X1vb33E(iF7~?tvg-hV}gD9mG0k8yT9(&{WVkfSLZU}e+Rzo zFZiCj`^(d=;X7>jrK-Pj%n2I)6Ad>Ba2)rKtxmMp*-!Cr#8!WK)fLswzEO7$b>2T7 zNn8Uw0DSCoo_lVqH5$%F-$&8+ZTFT%CgOjK2VRWRWFFY}-sE1}Tbf5a)4(xo+tJy| z&JN31RxueEv&gcePg8Z~nrju0a?FtWW}Cmjm-aL7yzy*_eedo6zxs~X_1&ZEyGz%% z9AA!$n<`~oa6CA518k54A5#>+OL6Aj$-nj|Z2s-R{}%taPD|z=WBhY0KLr^KYCXp} zy+->z)*!tUu{+q`?&Vj=xtxzKxsJd81Kga?Xq$UJ)bg`kTB0Dwv$HS;yAblH130q*`o8DdU_G^_98E=^TOS5*`^P9q^|+=@qeo= zO@EiR)NQlJ!b@n&Wsp;=Oz3Y?re>>M=C>%raeln&%Y5@#^&MdL$9FnlyXsvyE7}uh zGhNVqa#r;9W#c2SFFP;Nu?~0TmZe1^^~N^2E9Z(tCgA@fxi?qa`qSgcbL$N0&OdwvR=8jh&XR1v& zH|YsWTN<}W|1L-D&fCx?_8s5$0{zNQ7Qq2n((=wvu25$t-d=J=^_vNdC(g!C`;%~szw6pWJJKpQF{zyI zn<~wd4D)Z`Z|Iwf-&*BZW&*a#UE{@CYoNkj3~!kb~_kzxGQ;|f0EHeh4GC*n4YINwbKeR97L=Wm++ zW79s%(ISttZ+qik`)?R-hjX{k@eoXpsADU*bLu z##O*Awl?PF_;>hCKd?179(K(3b=#l{K5-9i zev0yz4R;grRzt^ywT)JxY&7v5pV&uiv{d8U4>;OrA*>rcptT+I6M6BL&$iJDFsE4e z@fdFid{lj6jdR~`Wt_WS5dIh94bM&JANp^tGTz^4-S;~wbJstmFIkp;)BPwVb8COqAJ)klBFN1C|b0;SwES$!v$=DQSbRfO324 z$KRPd+*J78a!LObU|2pmg zYaM6FUd1dedpPe@2-)%tjg=x;*jDa4hcJHpA|vYj9nY9Hovh-QY;ZkS7I&e12y0m4 z;(i+A)vp-tR`KfJy66h^z8+)MH+qb!0`Qpc0$umG?1N~$>RgD(5@L`5-zeB)lx?*i zJIsyoj5z;*VI4t-yjt@2Az&UEWNh4wxh{IAI;XzD^}Dk8KLFE&^(NQX-Ftn5jgp{_ zVecA(xf(I-v$5Bg3U3qezK*wDLO4IgHmmX2FggAv@ESZ51-y{44erMN4Xig8Yx+O1 zPULZYHw*8B@}1L4q;ag_toFveGmQxSrhwa;dq;V^FX}kj-f^oMi`L$8ZpyvmM}Xsq z>tF@%+&j)S7pEvMyu{mF$lDH{wQD}NLoYO8e1`RJ&d;2moc!|Qw;w#s03XNW9>IP1 zP5&w9{%e8H30tP`=#T~{4wpVtRf}{du1<`9+IF<@ZdqV7@SWNHeek9$>cbi5hOS=j z&bKk2eU7&;zCt{#tfe=_f+u?;)Z^4?#gNBhH|GR7hfkeYgg@?!K8Ab1$vV)IsWQ;9 zw|AmlQU+bXwdYvmeUACduX*A}J(m2Qg*>IpFrKN)7LT=cNi*n7euLARvsu=Crr2)< ztE#T!@7o{KHV@{0uV2P`U9-%oTTVutc<2J!hM(Q8^_Q;mtrELVp4mAbG(p~W^30EM zrPdj*3!WY?if$o3#zou+oSkT!RX(s#$~XT(%D16hn=`*w=f5iXYmv|M)ZOq4bpG!p ze>w6mL>=#=Od0xtZ&5usN#1*K^0W2xt}4Xb>c->s37)!_1<#g~0+r_g5AQ5{e=oKY z{S((9rt)au?T7S=R@tj!e0h#@Yp;rLc6QTusiyBmn|{VYCtvRcU)kT=$3W*gV50K` zreKo|lc!;B(=cxXhBEg!;5Okc&NL_dTn+z%4e!?QS1EYJ|JHa`IN&_h0$1}pfgAdo zw3|HTdufw^<4#BU&}=E+`dcZ#{#9pr>~Wwx-x|9Wv^ry6-lyNyJeogOk6ks!R^uIv z4d|<6f3AtNRQ}xcNauW-95X@P%~EqJ;sE?CaURVd9b4nW8F~8DFVOMO_`lmwHk*nK zY(P)Zo+!ZAngjPthYhCZ!3&^=neXY6nA*mPnD+!;+kA=f3X)?Qa{igM2DTXD5Bm_G zuM+>`oZ&_v;sdh2Cj1WZH{t=FkN>@}*>H!Ix_(1ecDc0&p?F3ev61j7LmlMB?*@$b zChSpi?jXK5i37iz-gQO7xGSFHGU7|{_V6gyL)?W%{0v>jhx2o%%`G1i7w7!ALvCjMjI{#J4FGT*C&iopk|9isCltbc~ga1ME zR%3-Lj&=LS+i?alV8lw#Lab4)eYnoE>U$b^oMWX7c3lwi_5$Gij(IGExf^>F8;Ws% ztQ~7c@_zi?z2h0!$AE8ZR|aITPQ8)jHg5s^G2n|6p0)z(Ogu}OX93I1ADrXF`sF4SOtX*yCWs9*=c;j|R?@6@eHeDXjB{01k zTvyLYfQi#LY{9sCbhjl_V0OA2-3{4yOo`{zl*hfOCkyq_1}0xV`I>wgsC+$~Gjp^| zd9VliChqhx?O5>1TdM7PhmPDkueah$RzZ23@=4w0*FIWn9qPCC65gPHHdDtabe?q!+x!AJXh%C`sCyl%;H4~WHlBNYB}IA5_Ie+A#ia#!8<=e?5Zp4;Bu>M=?G~`&+<4x}$iLnfygRZOA-?JD21! z%E9-e%2D2^&qH`y_I~j8Z>tZlyAC#5E9PP1{T=dsh#5lMP92e|4i|iYgjo-m5Mb1v zlB2KK*Ef8z5Nj~*CuN#Xf)@5yiyrSSX_noZW8RH+FZq$NkuY;x7bf_Isn@;&toLcD zBmaFD&Xmag|9dsgpvD;lPR_&5I=uMJepwCqI#=Bp%`z9GK4%#h=48@YtNA|*=So!{ zjw|oxKmEZk)OVY) zc0)S*+1pRsdvD7+DlHx3`oh?nlL1@jfUVeQ!Qzg!hV}Ik*wz+-Ed=b(0GkWg>m9KE z=WW=f8aCh-Sl6Fz*q!R_pd2$F^5bkzqk0!D&&)*n=F1=p&^>pMKR*>dW`AnyZ0dnj z228VENCG@0)wLypqnGugk2xy9PgWnQmJ{ z3;rknP6JJpL-H!~Ba468=G&kl*?yp15O&N(9?bvb$qktI5vxCIKj^Sz%)QR)>ul4| zeeH?QRW@ehX6fs4$Vocnv&gM*(~Q7 zRj+Bj`8ADfuVpvg1017fD8BDZyLCd`czmg%#RVJvLcE9Jy-w`FmJ1fCblAvShvAHs z(bM}J^w4ugM$egRnixZZ}V=qR#susse(bpR?v4+uYSADJZ&ra78iDzQ*%7=G` zZ#W9C&H>K%7b%>0qu_)F;z@(w*V4=0(MDA*;Ju?`rPI*oN`F9xC@+*b7viA!yKPe4 zKckGQ*+;2!uoLKAKOc`@!YQ7(-5B>%Lb7 z>AXVpXHd&Uuv;!*ucKZ!_GHw#n}zNYH}=`oo9md%??2V38U*>^89B~@TnEyA+YOvf zTunHC!~Fe|Vx>30Z%Z6c78wo8;J3YscWvOq$y$7Sg3p#bqu;jud{0U9Y`d-9Hax~w zAJmhq!=&G{%y*GT9DAq5O5bD(jzO`?}MNz{BUDKF<5jKC$=| zMBXg$Y4#NC&2vvA194j`jH&~$^&m4V-K`}J`FG5W=VE-e!2gst19C35oSc&vnNj|% z7A-$5kRLD3#e}gY6x)t(Pw`Eyft>-QKZ*9Kb&A6#6ngT^g`j6Pdenl|7VY&eeE4XLQ?5E3^m2|_iuzKuwHfz>W}>f>+sgOR{s=j`K+9NiI|^U}aj%?mb~?&< zPd%dTlt6EzvYqg5Amsxvs$Pd|TC@kxp?rwVeFEB+JRcj7!-T%XZ}M{$>~6&M#Td^v zIp;ddSa!f3q_gZstlhx-ojDF&$Nr>EL0kWTZo3!fN69jND zgeK^auYfywy<*Kf&nNN6yS*!6zpM_wxi$%-9M-2h=WOpP`8V|EpFvMDPRo{Y+In8Z zL-N2rxfd|60ET_&*W=HR@z>bgRn-SR_7_s*6};V5brJG@jXdL>t`hRzyGd-1<{QNJ zSe^}E%e2^`hvOX&Q%PFO-!}GkhZ?2O%CbrESNqakO zknB6<;BApg)b||lS$0y(T+2?%F<(SF@kD+Omm7w|5{DIPhi>i(*Vo8z!45u_cRMO%RF1ddO`x* zc$vT!0`?r$_B`_qzz=c4S6J}bX0ZkT3k^SC;L8Djs)m07@W(pgCtL7YW}XHAq=vsl z;1>XXpoU)u_^y?<+`1>)@NNtK2@PLu!}rzj4S@fj6TaMn&oN_2SL5d~4L{q4KZtnH zl%Y#i-)EV1!1I{{Ps?}h(#lNPA_Bk=G% zp2}aT^DmP8Ey(`^@~2q&59$01CI7D1r4IHl_p=SnW8VET9+a|m7f4x_*+H91(|rcY zP$y-ay|CJYF*5{q?gfaSH5KEj1MeD^trOfcKzkUr15(Bmz`y^&A*^*y~Z23SIW93OWF0Con>>( zW|X}TWi48bd!&5bL@5vZ@Pw;SW)E~Zd2QUS^Cw7t8^-nmMO&u%l`a#l*YuU!W#*#H z4&)m;udYnz4GdIPBJWe=Re*;$Hydw$LTDVS<uusPGO+AjEcAx-u0oSJ2$CA$; z+WUK?si_$IRSw(CxepfDG)K*goLkSSP0KkSZ-_YIM{67R5_vvOonf1Wy+B7iR2Sl*vfY3D zue7@vep{id9CHoM?7bo9DB1R?C%Ns3WdhIH?LRoh(f;eC{ms|SRsFiWU!d~$-R)1r z(Us1)t7(|q(lN*Nz+Bf8bo2sG5T_n{N{so>H3a+i>WAd~RS^A3`VM3*#NOC|PTF{| ztK!k2w<~^)g4{43GtXmL>*re_!v@l5KUUy>^4Vz@i#?cQo(|ae3}X{x8V4O~rrpp_ z7!zubjJ}qSaSooJ)Eg8nB zc8$9oHlU_M`LcAniseAtSm*8HTFr;w?P$B$-=5N|Q4jt0F3{{O*Q(BE<(LQ2POE%H zKWi<)^;wQN1bK1rz*%1^AO5YbSjhri&%XiVtfxTl1GOT3Okb?w*e~dh0u^@wXSmQ` z%hHWbyjM`g{_5v)9>dG5pYleXazr$`0 zkr(6Zn1bJ9)^6+o@N1AE*s^oACWUy|Lq#!}Z2ZBVud76Qwt>7rv7^@jiT=IuYmGt6Cwy z#oEV$I7L{0W}3NpYmsLZj;1RDUA0MiGI5-H9L;|ECL2 z)}p=7L9e9JPv6Ib^cxQ6!D#Rx@I5^EA-eObUEj|SWB<|l5vsTO@oNVUypy$DR0t0W zarfgV|BpN^U8BiZjlBjMXE_fs1=ukOL3p;Me72DqMN$Eui*)*W&!WTb)JV zc&@?kYK$?Kje@U~l{5ByKW{w$JvwiiZnJqqS&24?tSoTw$rvYmYV-=9+Q6s6Bk(EF zhLHDu>aRSUH&1~#*b6u+ZyGUQvYnP4aNpm*%k?g?=^f*sFGwvkZAR!si*3Jmuqzf)}_XvUTFwr)f=`s2 zP>S-F+`K}1XQY;!7m#-&-tkG6n{JtL$jVD-C)?$P|9#IXM%)e9Bgx9M4}d3=QpgJ6 z$Y&?qVX{*6{j##$s@u``-TYDTiLz3iqP!(5*CX#m?+=g_$cZH@*J@cAt7WAII8w>V zJfx3yz|{aQ1imO)DKg@lHBV_brqnU%-!CiUQO6N=jDk;;mFyJdEm;|XyiMRm*uhte zPsPZ)5$}rs5Lr1*w=0A*d3*3i#2xtU>~p7H@jzArqf^KV;K*ku++nh^gX@u_>y`Z$ z4o921Wkta!%F16;l(%^BZ{+20Z$;y3!MIGRSNhtr@&(#Qz4D^kkH|4U1ddd)vK8s0 z9dI9V41q67R`Bk`kC1;GwX8gayc-An zFj-lPcCuZJN4O`~h<}6M&OUd_%If>UOT2-_@@~W4%Oo86?1Vc^R@QyLto#IYD;%k0 zMZqV^N_mR%maNQ2-c1ERKvs^mWo0hfKv_9c%gXt{kxEu3A$_z1?tH+7a9>Nw3gV+T z;`dQyrT+V6Wf_%1ac1U*vEKMuy^K=MM@ZY?s+k;r8|}rOvyy?CIYy}ucljBJLyPw+Gk6g*op1C?h3?hg*QmZdh_pEO)_ zo34L=z@?#n?kD`#0q4HWhI>iFdA15%S)Ra^18xxD8Xa&Ix7cu|hV%VR;OcS&ZaLt1 zR^<@~T<|6v?nw<7`ipK~mTn*5o>qK<59(Us)A_(dUU=V;vNf4fb}e{Or1N}l>-tZS zyf);KZo&oLlDx*_C9e>5Wb3?8i?07T$y=c5CS22>C9m~ZT_5s#Yq;p2B+sSu7NEYL zf^POJ?zv~(fV*gv+p8fHPPtwD)sWIQC99%?Cg}CkKdo{O*|c;}40)q_B(r@OuU5dfH3e_5$@}oMMM#4a zC(q(=z5Ef~xyI+JgVsaateM{SqI4xgD zQ~Ko}vac@%u4Fi-&p~=}`K~w85o@6zo_s?2>R5zCp2|F z*YJ4n7Ij0PZsk3pO)H@LF(*3j37w0&z>lqc>hc;|Ak&K}7r6fue)immr)+L~HF&l5 zQQZG|S>OM`Ud%H)jBP9FcRc|e2lbI2cR^8u z(f^%s8QZ4E`xMNM_kC-6yk9{@y#GnFW6)ccjT_8(Xwh z96Y5|;SXv2a|QpxcPdAcPlc$5_i``CxXp#`CH>EWe$vW%z5#wOY*PoF1TW5vMBG*5zTD8BRsUv%4pXshPKt}y<$=d7>}0nNnSGF)VMB53TEpL+y%-Mxal5ICm-AK&k=Y=pPK1MAF^aUu8s zd>rG>y6VmspZRv=S#TL6Y&b9Szkytmho9byIpWyE*Dc-r+&iL_?T*$7ZH>!?wu#SG zs`g8}vrWbt=!v#?fJ@P<<%v8l!~0;rLVm(MSd)J<*O<2#eiXqIK*Ru zZRCybE^=W_|HVPI)e>7X#{{oZtfk}~jf>IlUqYAu9DQ!-(qOKwOV=ZveI2-7`nv1} z>1+1!ue>7HZ@^c;I#&&>tv(ffs%XZYh26ND@U-R$^WAwi&BN1dnp+T0i}~58w{?Q} zUJs|4che*ee-UVQgJ#0iWTS5sOqOZc;D>ab9^A*~*i~oM$Judgnh`sn@hx(W5Xa^i z;Qt(PY+Q)3t;Y9NdVK#_+TPY9Q0Yh8+p)%OLTulC+hLy~_80bbwtBFRyba&7ffM7s zKu6$Gxj%R*{!f0>a5Q);aT0UQmwt>miQ{Ddjyj6xS}9l0BR%&5w1aX`klElq$s5_f z&WP}AiVywzne>eQz=K?S5Yo|Vg+$=7UwRb!A zNZch>e8}7saj@j=b?Wvvf#X@_8_G2Kf7m&uJGjosHeW+}RtMJ4keeo-)?YQkyDgBL zd@VPlwcM2TMjx(|ez*GY0pQ>`gNMP=(`wJenjfBF-MVk_E@(+u$0#Z&!+6tu>!i)n z>1zPTzV(zQ>PJggJcNAmn(yA@yV7-ad3+W47=mp_dR{!%C~bmYV;IuNci)Auci>0= z62CdGkS6kW>aliQ`*y&#rXOif!ItZ*QMbb3;AtbyE?*B>2Q6D^Pk3hwKV5T#pK0Ld zAID?=UdL-)Y}h(IG{~sB182A_SYMUE7R(aZyY7~Gia0n=xzI0Hp*+Xc;`oB@Gkp(W z-D#caYg{Ngo^ci}yrCI-d{heFLf{L5CdzLbWRfz$^D9<)&&5){^gBPdGlVV^DmP8wV>q=jr;SfVr%dYv?@m% zOv&f@Qoim2DPP_b>wi@qZ;TY<&La5n9((}oTtM}#o%1+^?!9OEfv%qH^gKPYRZ2m5=}oa>#e+c!n%z3ZoX&IR2M={9*L zNtxD3cAL)CJop88V983x{}y!H4PLy1{0-uU-wIw2>0#`Gtyz_Ac%T2^9s0|h?oAmDnF3PjBt=2f(gfcf`E`>}W{&;3XMu9i7 z$D!9o<4i5bS1SC!1nh3a(FLp;r+$20`4i(N>NEPwINd!S_v%qDVNCXPj7j)mT6cW^ zm<$3(p_UonSmA5IIl|XA$kxB0|Jl|G@Rc^kWPF{rS;r2W$7L^wAM*Rol(#9m5@o8w zYD)^4T7bN&o{2JL@p&Hd)I9mw0<1x^%p1TX`1eQg|4R8^t=IUQK9%s@iN2#&$R^u2 z6?l4p4*|$2ZNy)oT&lhqk8&JW#u>t^<}-v>X_zxBAz#e%jMVZu(#~6@`M3cx?7dR- z66^WXILH}fkFoWGTO>YJ<0&$KTk)xmL0(%C`%>m9YaAX#`>gpjx)^WScxZPa{ully zPnzE+Px8#uQ4V)9z>_?)zx=OxLVQ?5C-I~Vb^-D9KwEFtW3>f1o$nc(0~p3z;@cfl z@IUJd9=H;IlblZ46$bRgZCb8ErwBi4iuHH}uP#>n$TFV?UghHi-+U))`8&ntTOHco zG~eP^wt1W8R~gckej6$uDc8KKWASm7 z=A+@@qvtr`W9xCk$K{asRhp0fR>9Q-pY{I>A6v1mOal#9t9o$<%}>3YZ9aza(D!7! zFO7aeLvug7FWsQq>T9E~&hIPvY3S=8gGTb?ufWN6yFbtUB2>HQF=EIo>NbAS3a5r?T`)(u6U z9SKKR%Olt8F9OGpFg_TwZa92!LtMtL;%8R;P~l|kC~p0@?G_eZH#mH6BtKd$BQkJGx+JJi4We26}^6FYz@|`qoNqA zBMvgwGS1A`%b9t~pYwOugtTo37WKehNl)yV^n#BYXWEy#ai%Y=`%GWUFBd2uTRYBs z_~|?CKQW$;`^c0d*mEbGi?QQD`;fQ6_12_#E!G;811ob@wsT7rJqn-|+0?9R_J z^R0Zupba9wJvX))@g(1KVXYqk&Kscv$j8}(;bTe5>FgYgat`e-!W^Oceb4 z(B76IqycxNbeZTxqv}zVaq_MJF>+bv5NO{wIQHU0@cB9M??SqwAL~!zcfyLzmSz4I zWoC_xZ4QC%?2~k?Ps$Nwr)-*0HENnsT8B00DkJuyA2{4D*Zr}md9u%L7TUh=`}-rG%`=xX zXU?2CbLPyMGbcblGkyhAd_@ny!%f6{gO_=irX=zq;}b43Ix~J7r&8CgGk5VzV4lg? z4}q3q4~WIej_qTA@4ztpC-S4yFG1Ch*KK7TN!<5pT4dQzNZ#n=y6q$6b?%QQ_=-%w zc#CyRIrY}#oyw4zJ(^j%d$W3(y!SE>zB6eNnd5{Q!tYCOV!t99sTpNB;}oc z-Adl6Vw*RxWdBqLFN&=21huTFk+I=TdKuTN_5T}$PVz1DRiQ7%MIOm>$oH`R`4W7grYk>V{7?#)4i~FY!B9g4Zd~Lzo+}KBy_B1zdFsx zA@L19j{T^#De|Y7_2JgmbMUPi89xVKrOhDn zN5*9j{&9mSEBG}WYz{trFkXnsmPZ^IE<8JBi>eEj}$$PH+&IC6#(^ z-4C2VYjk7)ItYx{5@2ZjGVFQOb9ghjQS)Z=bDB3xnZpvJRoa^6z@MRU{*loAKy+kK z!Oygx1-_eyov|x-!++Mm-=N{YgueS*V)4rxF>QmjY*>7G%$Cv2-FR6CzQ3~!ooWoa z)%oaH=i!fXF1{!!>fDsN_s6xnIa*$Z9xl8(8l38w|H2Pmi#5!=Baz6rBk4;Rzdc#A zc@H|Yhgk6UktRIVV)zK3yCN^=A1&CiYdA}gJBK0%W_4Mk#8*e3dmK*R#Rq7+Dy!3H zQ(o+MpF8jkU$np%nr7K{8uf1FjW>6{&<)GoJQUztcwFge`-ToOm=xM617;}rgx_RK5wUT`$FMe#-Y^H?PsYN zDFaOVBev-F@1^}ce~&hH_U{4HzttM{LfX!AwOzN$Wr8aWeyenu zmtWL0lCnbg6lm1lRo+^m%a^RwT(Me{WzxsZX9P-ABzL^KA)mV=r+Xl;(~#TjgYQgd&z({$HfxDZCb*TI5Ze#`5g39k?CP{#B5-SENL_H+|kYDT(W?(60IX9v+ar8&QWoZf9=3<;nt}aY|?s#ly!9T zTauL5GCs%t8F`J!_?9H{|6cMOS=~0!S0w$co>&rDLZ6yA*OxwigRaxcxAgCzeR^1M zO4cXw+17oULt6?)vOcN$x~$WuQAx@>eVRtzJKVi*G3!!Gj__Ev{XF&)Kj$!lx2yy2 zf_FI08X?cW7pSeG~>BN{G%sPM*JY;?z+g!e^JHSjacU|o5=tH@- z;NXVgQR!KBgmgEox=*6zZSHa9TlnEi$|cUHhspENM@J7E+drmYV`OC~`>jxd&#;Z??Ts{pQ&B z^XqrDJ*Q8sZ9n#%SHahT9jMf>OU~D@XVLDFz(2tyNBsfQ{&~7gDP^)KBmRC49N$bM z)6R{R>22_A0#EUOr|fdsvo&3=%hs3bvfUPI87XjOT^n!eJwrW-6X(>krt5mGeqHa} zdv!g*S>7By$JBeo(B)6Ay1q*dexr2Vh1B`DSnEg+n)2rwI?8$0OXSzN>sOfiXY2Zs z|CXwcZ=9(&!qEQ|^_y$|n);Uk`};dz#C938kv?1#zn)AOEI!B9htW!?>522m)3;bgr^hZPw6x)yJ zP1qJU$k=&HhV#x4ZwSFJ@{aTZ-t`Fd4W8YU!W#hi%C=yuYD0hD0se0N2VYL*f9grl zqxIa)u!qBAvA3nq1;5eoI`JGvd(=MTyX$`k&wJqgu5Wfl7kS_K27B@z)en7#yKF!G z_u%`8-(-Q=dlXn!#M4{eyw-b>GQLy#VGrip_^8#&TMhy2uT~!KRM8h~ki~WMtwHQ~ zyfYG9xbQ5Y^)%#R5Wm6T5PT@{v6Q_Dab7pL;nW;sMf%=NIpn6SeN|$|!$v7Fl#cCZ zl@Bm$@wYoGD+Xal-}vK;l-;xncw_h9y)_44uU)*`RK~ukEyYsrB985073~C$yeUgWd4ViI%Lmnm&l!mp7kfT@)E2=V#lIWh%BH@~NFNvR1g|rH^#C{0s2?Lbr~h z$;@q$Ke7gnDdLQNlfLatO&?eIWB-ajlb8GLg8P%TpO1|C z5=Xo#h3QdZ)eR+^R^$mH_EtJnY|brVmt0We(K_F zpK*@z6!bk8-d#5T+UK8~-)qT&`4igPQ~TJTr}njd#AhiZzI_MhCo+fUaaOX_Qn4X- z&v|sowg*W|k485x@C<5iX01r)JY)rFt9X;fN57r8bfMPDPG5~y`VU{%Cccez;OY|O z{;O)9Gar|yHgeWpe8~+;-(0L^%`AMNUx2PMP6KCktnTB;Qpz@s)Mcw{Vr8E)W&2T9 z=oLV|_+5DI{2+!`0NRy8w@H*y^W)RBB9TYM^vA)c?iAfd#bnwlh#qev%kMnucvV^A5DO1 znKjdMtb&=ePAI;P<=|oJ$U5si%HZIacdC-K%bSz#^%~tkuhq@*?Iz=QVv{Vlo<)Yx zuGjFk7v4@rf8Q7L)%=uuQU@4Y>se1k_>c3Z<=pdGj>GP9KWCh+MS2}8Wt>HK5cs<( zujtr9dBLYV5qNOJfl>ON)-^^CsptJW!7EJOVESSD-g!@}2Xku=c~yE| z?yh29>h&?hj?ypH7xW}m{})~B@1sl=dt+)ooGbe;9y z=7F`IpIjK%&N%8YOLRN6nor8mAFg!T$@kWJo}Lz0=N#$;LZ(jl*jrZ>PMv1n$7+tR zb24?B8cZG6`&i?sW6@{&v?cTX*cx*BDp^DF+U2}N&LS^@elnkfrvL*zP}b(L_v>}0 z)tsq#e_2_vfV(q$c`Mt^FV5UKiME7RYk6}paFSI%9onvJcfUoH*WSdMDD90j?S(ln zGx#mfn&8AE&ujN7yt3?LDJN?fc&hiLr0!97V!t>p`8_qkd+}0@cYr%*O<7v+kaL=c z@wG2U=DKmOrpz0xX9Bk`aD&Hog_{gN{oYHK?V(N+brRQE!6SQlWkri??U%K$oc;t> z>pesE77uq2^_lZ-;0O#iZmbva_6)v-zAIVh&oDmxTY=YLvshh3+DM=+LdvyF)(U6WnrfM2LofzP<4-SeP;jITMoiI$YnK_FBurf zjm8ha>y00Eh1ra6iGHJmH&@9IoZgkrf@e1IMGd{zXFi19#ePlN^5OR)WAr#}iSFg& zy#S%-V7~E*(e&@_kGOr#vZq=hfmH?{W@p7W!-V z70+bZ=QFNtX1v=NZykd&$M%z6L~I&q&jzkH;xXU z4mCWsSI%+K8$6$M584Bol5^9?jder4I+DJOIXx5g`Y+bA;$&sQ2%IeAfDL zU3p&GaN{BSSJB_wDId79t6WKjQ?;q{PwM!IKPPy(c~@l78P`-+D4t?3>+sac^ugjy zGO-;GP&}pg?SG>$!mBNYM_S+!xx?w^nL56|;XSFN>HBxIiw>gRlWLgl>;*FI?!b|` zVm0fzQgVl$D?^woUgpX*)cxF5x1};xcOU6e*Y~2XTX~zVyNGSk%v`#ib`Lg}Mj03@iaUyLiF>Dwx@I1oZ|VzQeLJnP z!hf-uPo3|f<+c0G`hBM9qeZ`kcOO6>aAbO&DwA!WLK)$=I?5#SXbpK5eD(#jJ(F=w z#JisLTkHZd$BralaJp=2WknNnT*|uVftqVB96e^<^rN1S_;!hFcp|>imdNvNln+oo zQJyE_K22~p_xJSt(lT3kJ5gr)6XsWtZ{B-vyn}upMR|wM8_FC$=Z-b$YJNRt=GW!1 zwdf?~$o_dKUwwk@=hdVzJiUj4LKy(!d_ zb?GVk-DY^Wjrq~6-fGLS8%TcuUqxA84(EU0#IEbhZ-Jj|PPpfjdroAkHZ$y6;JM2< z>x;}^!MD7`tS@nIwdpw#=x>!jL%WH*rS)3;e}It*jGL!wJt*s;(nyd#v{J_!tNF~r zUn7(6ApNUi?GAk533>Zqdu08-^NW;Fjk2w3nWE!JpnGG#U74i6jy^q|cHf$;+FYJe zJvzevc)8^tuJ*t~k)J-fyC||r_AA)#H=h?(d-&mBS?V{v&gU-dHp_d`;U~Z8wdH?7VPdWY^@0k@k!EJuxNJHcWI6 z&IIWHBjD~czNcEI={L%znLfG4L-#4m9!8&5p5IZ-9ow&_{L&K_uR!LT(gD8L`xJ*x zKIXy&hoF=2(p%?t6qo<9ByuNmukzW_h{*43>d4sFai>=3#C~MU1AmU+kNA{K%eMPd zR_1dPdfFaha8~lI<|yN)&Of{578kKk9&krjKFMbOZt&9;Sq7_TiW z&emfGPpmI_T#w!3)RVEZ@UfM#OB^>xhkuxIYTVEt<&N|ozTM-tIW@QVB*twk^mSxt z&5@2gBUS?G(oXnJEzj~#)$(jRdd5e*6Hub|1=;q!Qa?%DKxtF@=x)>Tf9M>aq5pn- zW+b6^=lH1l@#8ZhNqJ{{E|k1elaJ3B@*En=_*@6>Lf>TLa~5UyoZL|?z5`{9lPBx^ zND1X{L*4|~S4zDw^34a|)svpc`wmYG2hLt%3%<0_$gsMTYGu9t+T0(jF}zXJ$s3vW z5!9J7l=(o6k~Y&u4Qten+K-J}XWM?K;te z++{CI+?p}8?Z=-|`s$%?0e$i>eM zOjAD2PKsi(a__*7Vj27S%&%{6bIq?*XMSbb-JJOqF!L)nHovZ>-mBD0 zd@)I0rJVbb_mQhTuN7;rjdYpMfy<44k{N4H-pzW$Rj=%afIfSIhqjq|b(iUSt%vJ+ zDfnZ3$bFzu)P2cSx9U5mZkGL;soOM7*Y)&|)fL}~4X%0(2b_A@_8(0>t3uZ+IV@JM zi8f_?hg>GV=(fOF=Ymt!5rgxD)BaS`ejg2INV<;wx6)OwVPCA?L!>X{T@@w&rs%r) zy>#6=(|!u=`x)c56SYln&bNWib4<_S;=3{q+wBF|aK~cHEyJcehBM6bd8F2SCcR2g(`oX$xk)#i8DWw{AMTr0+XMj^HaE2b_w|}IQe5u zzQ@$ZC*-##&oX%>RxGcKy0(*Frt6kOCn=dRi?+qzMDX&B(Rr0W=)BUygOh(@^8DxP zyz1{`d8YtZ;{OHC(|PsZ={(`%9q`d`@|QaG&o%YG)n&w&bO`zPIQgSZ{s99Ye)^Hg z3zQo8kyu^^b#EnK-s+ia%K1ukxylY*PV&+zC;5*f8#!@u8^Ea!{SwicV=^XLFyU$$IU_ZdfC_v!`Ee zAw1r4406`gYeRm%%US71v#j~rpCJREh%8%ZC_d)h`5W}Y56VYJ{9amgz1=OHayQ$a zNB{8Selx>s6*riCk;~}u&Y7}0I}Y;w4*isNlAXDT9GC_y+1uX!PfZ88S1R8H@9O#d z_^s;PVvG0;1V?I`=NIYUg^c}g@KF|A4%NowoQ~DWXj+Xtmi1F$*PWtamYk}8@40c( zB*8=ee)4{xVjXRLL|cOMdBEGjILrT~{O_iLN4;;u{T2FEV`x(YZJOzq$h#v*e_(%9 z?rf@d!zbwWs!!Cv($4Lwo#Zr&ZW3RpZpfzYoGbAb(jrgnUMju-_QTd2yI4~no^`F7 zbI#q=%xunUcw4BR_;LlG2(_9h&=xYFf9N-&xRHeBCYh==(d* zhqmV-_wiHQr2V+&dak;EJh-gIpQe&|I6lw+!Ycfi3U9o8YxehxcZohL{SESKU7-0! z-WofbHib8ZoNN$Nv5c}Z)jKWL z15*``WPqm^JO!sVaQfylPiW83lu+wvtM+gB>m{Sff)vJ=`Lm9BApZyGyYF#LYdMqp zff&T%8z+7LCuOV&>EFH6?9&%TLnfTmC9Q}+UBx+}HkxbgT+xoPWR-h?RI z2Uu(IZTk7trQ0sN$g2H{vABnNf1iK-^Iy*Iv*gA36Wc#eJXr) zM~OevQ}{UbrT+rwH;*pc=5D8XPqbX()QtZjy0JHYZ7+Iyx3_Y((;L4hce!fzy+5Ix z%){@l_n;S~pdX~dFY$9y^jM2|^W-hcZ#hzjjl6+zc6{lUlv(ADU;E09feOk;8W{UI z`|jSFhYwxBFz(Zd&kpGYjITGHdB~gFgZnTakgEm6I&k=+&>Q26X5MBV2w%*>zghTV zY?`-d5PVU?xA0U;kAkA%*gu^)T!wGn8N>)HbMm|QD=L$AnD3SF<5=1$F#Ooo%_=IP zuHq^9xQcl$yd?9y0vNr3A@lr+;aiG&14HI{$#DFlf#J;azZUw6dIQ6m=MxHJ^Sren zex6@j5I@g98)g-aho79feFo@x-o%~jU=Jt$Zk|08-Wv$N$h+opPb`-|@mnlrEiB@% zK%YS=|G@w@@84Ti<1S@`&a)d?Z@xWC+q#7QV&|$cXI3@*UwpJxd>em8=BxOWUX$-7 zzs&q!#{X5O9f1)RzXkIxaD1HA-JWU{Z{*Ltez5P1^Zl0nih;RXUJ?scEitCcisot)uiwLE)Adh9D8+E$Lfvhf6fT`-`%d-f1n54N_nrr(@T4f zKjQVIyYZ0o9Pu}wL%QJe7Wi1~&BdScok5n0Mb?9~0O#($cRiug+EYRW25tdx^&UFU zo<@C<%NA=ezss|+L3-tE6j`zPfq?P{^D)oGK0O0?GOvQ1kvE7eg`aCY{fZ^#m*kh< z%wBDHS6h=)wjiaSj>iUXHv?1Vn=^;TdaR-lvUU`5ycM1Z@t%kLUoHRhUW5Ek?BDXb z{aR*<{pposiQPlrcLK(d*vJ(7vtfDN{EL9{r(Y>tb|_rZ+vILTs{&(KFt9 zGbOYU|K^=C|B(YD=NEL`%srTIpuNbS1wFj&uYC|LKMKB?N7_<&d>-Sm)cj9OwTQFU zHRJCqYu#$rx@%aot|9JDFXr_E=Cy~rG`*PDbCC^m8HXi#zM@{t>v??3dfq#)U(q~S zGbvk7%!7I0;>dvGa;>7d$Rwxk6FFAVv6NjP>nnP}v9x)ctgn`=Zx%YN74h;;WjYU3 z5>sH;$o?zWRGD>5cq7nPuep_shs<}8MP89-$fBO$ZTMNebw8Z-)+_Q2ykx!g(g$bF zEMvX((g%kp{@eAoMD(VkjNArik=wHF9$?-5(Fakr?uw4!zf|+kNbnW8B=4%Kb)Ei~ zAivY;zxYRA!#Z<-wel_U2dBc9@8S1h{;xw$)XjC)+gy7Hutd&D{5YBGt1^ivu}$WE zwtYYU3ydb>#U-1Io{yvDM@T*L9li_0V}Z}2jSn-oEPR-+B)&ul{9Mv~d_X^oAx2Snsc!x@6n&=na1ty#c(Rnt$E%f1BTX z$=dlBwtt2{^cUz3K734$1=d`6?pRxd9_GkEeOTXMc{<-vP zE3n6b_Y&4Vfiw2e`?k#n?q>9#blRIq9Q8`$_kB6(r{5H_gO$yV*;-0TM{ciI`?Hp* zH;CMB-mLqSg00|O_%h5~eC%S`I}NlSQNM%ib?P_A{yL*$bu^9jkuq*Qvt#CHbgNQq zF7ocI*29}A>$K&2MYmP?YOJk7)7BDTi%*VIwrP_t>v<(s_DITZr_7=5L~c4TPwB_b z9_lxTC%Y5rRd*uq`ab?nWH35$lF;HT#?-+h_@bdtlg2~tXnse&#aO!UQ;KdGzrWLO z8;982?d)YmLW`_7hP*OW>C^UX>y1suzSiyJSqfj-|LHdny!QLO@wwyPTovo3+VkQ6 zDL#hv>|^Q|&4}#<@#mCu+25>7ozYQd_J3tPy+sm}yi+E!AMD(NaDF9wkm1Pu3y^iY zke@w~>*LItFc)2NoXB-qFOaq4DC?{bOVK4SpzL^Oz2LiwvV-B{d}Lr1GC_1@RiCt0 z2PvX0hdJpIDjf_L!vOtBG^+a?!FS6O;HK$B?*Azuh z*|+_@Fg9l4r}dcC8~fTqc>3p^V;0{|-Sc`(WdHLeyk)(h>wYHxf2sLFc&Ux=0^}ck zReK-ls}t+Z-RB^-g#Jc`4Q7t^om#W)S|h`{p$8sJhE*}Y9l8bfMa$>z({i{T-NcdC zw`v08i|lSY%!*|B&~?y@ zWUR$5m5Gg_#(aw{ri?RMtG+by%~mVaI@F4b+5OFp`rIf;+)4vO#jTS4t%0FzTXmv$ zFsG#Ln)A_9iIXjMfWsLt(f=MsF1pLttNWIj_CusQ^;*u=_39WGfm6bFFY^7w#%n__ zk+cx73+b1{E0cYe*qpw)rEI6GvRep&_&9CsFQ>ST- zu2Zs3*SR8Xl9~%rSKd9yhu>wd`VZ>d0DkVbN+c$loC`g?Rm)2E+bfg$sX^`!9`df;rk-yIEz8c* zJR)zTW?;u!vBKIg2fiqPPpaUHTZW^r5`(#El~tbk3#(Y}=j~^{?!#_-OFwG^{=d6h zAJk*jc3PlfS`TaeNB9j}$6Mu_;f3KL{|hrc){VQKTRR|1dK>=4Gd&s;{U2ZJSbR|4eM5@QK`E zJS=#2+iZA$s1@1Ecm?~8=?KT}MyUG%furEpb7)hytI~p!RvMpHM_Tx>rn7@7z#PiF z>B&BpeOV@V0wyyz;^S>%cL&$tAZtW`y_4^$`1=@{zW90fXgPLt_Ej$mjem=u-7{8k z9ebX;fFb+3rq^QrX+vmB_B_I`tEngayNcg;p6)2Vl{dat{o2}a+nZxTZrZh&Io`rp z)|mfm_`e_rUsPgUTEwvmkuG}*iFGM3)w?Ccr`l}NHNm{-vy4+_YIU2A4%XW z_u!)*?^r{;pUeT=IyoAz3l|mHu20P4q%Rb6ZK@Q+BD7M?sQgC{^EPU zWr`Jf$+V~FH7e11h?;-q{f1_vZ(nV(eigBy)<4P)sw!3^nb8l5t%RZwSIe4#i^7z>e->=s^&;Pq0!PQA}g}( z`_ylyUBj=~;ALMWu|)1*tllGbq}wKtGYr|O>8S23o4nm({}P=^?w9@+9HedqYlge- z0M=d|mvwzQwnebG*ZZ&B;9;LJyIDe$qqq(~*B-!x9>XkLfy2n}Fw@W6qqp7F@oe zuWr86d0F;V#lADK$rjlHa!d-*keRdUtzO|8eKFY3J2lu@!2t4O&ir}RTV-=?fS`{es}WazuV zZgcV09mtf5%6J~?xXc^+W=eYKNAR%NPupbuaLLEccr&RYA9Iq#CdpIx(#1zE1v)Dj zW(?XGgHHLV>g%$LkX>@#`<~OLtGpgF_U7c}1v+t6^TCG=)J=x~-)=f!KZ>J6m~Xke z{{yraf0%+)J!Wnju;8$FMn~~lc~dC^S$Muba&bAn-jm0MOk0N>7m<-wnO9VZY_PCP zCgc4&&Ipq6zMu3OGd{wvvc`8i2=6}yp6CCu$Q^JE;*w`fR)_={cFt8Qh318mQuJcxYGPA;s<5cuzCF2tC@q8vW`7HY$(%pD9 zx9hX#yGa+G#5f}7&&zYGSHx=KJ9q{L$Wqu=b3MXs5ZJ7Gaw2$UjVx)*Xy$qNwhITE&qn`_o z+4fY@4IR|Hs#ob*_C(U%eX3OHnf6%HtDuKo8?xFx@5k1LO8y6@Hl&`bba4gH6QUH+@rbMtE>` z0?v;7?UO*CChX;Iy2u*;Dy_qvumi z$8!>Jswe#n#f#icp}rfBX7WULZzVl(PPFy3M*b2U+vb4_eubhtdMzavl z-xI82_BHn(jK4ppPI^{k^#h&lX1C|p#oDdre`)trp(XRDVUk`89#g-W_9OfX?>;y* z#=D|dKlpHLO{(dy*Q7bKv>i&;q?E(r*Q9U2L&m4zvDlh4gf;`+jJ>F@UXx1k%ab)} z2=U6ZACET9Bqn1I%E3cw-EDis)Thj0q>HR-FuWr2C!e!Y>Bnzr&&(yYzink-BJ&_b z`o@1~+~o`;V43!N>h>36uSuot655qDSK`RDq-*>C*avim8Sp~m)Jp4x;_`iz5e^cNeFz~y%;b+=! zB5TCHF@o`9vCS0zyQ`0+W!lyJCYxWgOdBn0bQ>FhFE|RFeEW4f`JPxiFVKeU(VTan zHvf8Nr|q-(49)Y=O+618Ur6AKUQ-nSqCmu^&LHFlId?vZH%Trrq4}Z>h_u=x;^Fx zdQztSW7?Ft@HTN(-EzF`jp#@@pOdz8!PgtnZ7;qrrlT#~7vJ{DrtOAhv9@Q>cDP-) z-TIBY?Oc0?>TkB)WcvFj^~>FO^_ye=j^7sz&kD`zc4|2Fdtx-3U|{^#z`j=?w!7>`nBFSgE>-MXKf7suvB>6h{S+|L{p{;&FJte;2G&$^Ed zeqXrzNlXPprP~;LSFDZFw)i$)bo#d-*2ZVo(7z8&|2}oMk!yd39F=)_ zA++9uJQ6#Yv?pU`eW2@j{uQHl*px3-<#W|ti&6Z)u|>xfmT{>0MB_Q9$R&Sw#N)Zj z;92ma7@jYIXW%{EX61H+r;@*!_Di%o>)U9~Hv)gVhM&Gemr?R591s7;4*c6=@NI$r zwt@eV8-A8;tA1tLz3EFC?TF0go$A%Rv2p+01H3s!yTPrxZuN(;y1$~{S(F!=iR^6n zP~*1vgjnB){39N>iw$mNH^p#U1a84C2L3h;U*yWu@R&0m!M~gQ_hb2Yneq7Ng))xW z_6PjFXzB>h6ufU}H9UsTx_9F7ImO`9a%~Ksnc!pnRk!DPN4KZf!d!c%YBR@frmfqq zi#Dz?{TH4I{6*KPd@F|I6oX@;Rc4e%Mfigau z4EtA8%GhM+|Vsl;soG~t3 z%U(0M4vNv^rIvVHHyK>pX2x*+Y7X~L|D@Z>Z;8kCE998)$z*Unj<(i;XEJ@Q^_gh- zO62Mq@{{dXTGw#S%DYE*(f(Y@L>GzA0kJjj#IKzFuyd}rlQZ^R5A(N+*)O%;@Y(JPfZD+lNd4l8wRW&%5IPb~hKLW8OAyX2nd)+MVfH$TQp8=DnEq z7m$|WS+vHDlh|8ChrS+~$~k0>(f?~G?~mcXTksF^Eo+NI`+b*eQs>X22S0|4F>qDc zW_9L|U7Pe|b!5)%yCfCdyUx34)Dzk{8-BsxCpHJU*Ri83?H>}_v-eNre-HjSZE2;U zoyM2og3&YC%UZjqdTQ1*n7wHOed3&Qce!Wr8q;sJUlkfV_ks$ci_AS!N7?1DX*&B` zWt*r|bdj;ubA8_>qdVuj^j+2?17DSQ{2`_(+9a>%TNmREi39D-P5&yL?y1wVRCvRN zcVfKJ6$kODO6I38{US!dmN0Km74YksIwo=s@>gt9b@+e?FReV?*k6e;BRnCrk@HB+ zH`uuLYx=nR7sQ7~&L&iO{-45~tQNypEx@p_+f|wGD!%=EOIrme>vh0$hUWWgt5R0} z*6g?XCeW}FA8)A>95J&Zjl7KSqmB3g)HV|*^qZ~z&>qIUvtQGQPa^9I_pu}{t{)rL z)qFRZw=A>6p3tRy$Di-#*r(8b;@PerU#thXOC)VKRET{ft3AlwVz+Hm#$4=NKGNOu zPwqz#_GGC0Y^MK8E=Wv-V`!_v(4+yHX!}T(y#>5#OuEpsiS|uhHP0-3)&v*-aWj+p zc*$KJ@h5bAy;@x35X3&@Zd2?n)ixh}2S?j{GTP-n z8*|~!wy_!xLC|NUau?w032Py+wn z!usxtXF^W$vpx zSDbfvQ>>x_ulAFz$M>ip*Z+bCpIE`CGTK!qw64&55YcZ_ksH3{nt!u3Z*LKrH(jb} z*L+2ccJGj{c{^S|Z1~Q+bq$|M+m7F=+&gf;1v`8a_exm*UPdoC*gLNIyyGr-pPB@3 zdAs#KOZ%6~d#-Ztpa$P`=k3;fbSv>4Z6-b0U2BQ2uhysUX6Tsuiv}s5zl=c%K7Yq( zpFcmoVJq|Fef~0evt4}tD)aUFQWlwk&zHA7%o*GNrN7^mSE+ceYAga5>ap-l*T1E` zgOhJ&EZSHHUOPhUgp3FGOsYytPM5PDKX+r5@12i0{ucLL@M|oqw@#k}?ho)+W#n~L z=X#o9e<$k+@LFfHzKphNi)g=fQAub!K0>AZFLZ0m)8`((KFQBAn`qa)-aEb|0n*JH zp>!qDkxl|;i)+o*>qE9JYuUlhJ+_j!H{sl)gmYJ+KfBPG-Kf5ekt;6i?TaU)N^R_L?e%=BjZ!YI|RtaNIK&) zvfh8Xw;N~6rJmD=kpCdKzVkKbFz}+tX+Lwz$~EUO$0R>zTtc14`$ksZN`0B9qJvd) zht)a%Y2|;>1>OK}H|?vzwVpY1C-ns{!NHB&aP-3A@J|Elii1xx`1GKi>!gkg$1wNN z%H%BcAUMvVyqg!s0Ym5{XCPJQ8QX}l-H07$`zT`@fj7nP;4bRR7<=EHq5Td>578h0 zNKM<;QvEBj7o0N?fiJeGg3)>$(qF&u27#gApA`@P3J3mMG5ECt{}cm%lpB7gU3;Wn zPxg$Boq?Q*+!mhn^IMfwZnsDXX?JsshOzu`^vsLGQRIe8@vks8teOHa0?9AxOh&}zYCE+ za(*`1^nC+;&;BUd_%1x;(7L5qx3}}2SbGakj&CpBp+ifoy&~ERAEVo;9-)7?_XBOmXyS6)r zc3n2JErrD6ciYTbn`b1onH^0VfkI6e(J8vICOP~Z%+=}5FKPOUj{GwDT91ggnYI2Y zhIc<;{yUv%=+#~OP(~kIHnYw?I5xB9-^cf1pSq(Jug_RRV|{sJP^>S$!*zP~pqS09 zwzDtsFhs7)T@$ax-t-_gv)Qw|;_sEQkJ-#R@&9)=v%nECoF8%F9PDjyelE60xdNPH zc9GZ^B<@p0)|5Rn)&j?HZEfG#$(^&V_yXVNd9%VxHQZ@0~C8Q+OEvny%;P&PB~i}F79 z|BcOT8f`Tgy`!O1$0s&sLcb4YGpoCw{gF$4Irk#}f7#4FgkJ9X?%2%UCEc-^y~Y3k zTbr2&x;QqoKK%dhY-VW*badOy)+gZX*vxFw9h=$X{O=wI$7WVfx|_!xo7pcDVCp?l zhP{e(yt}Y-Tqi^OEWZr*@T(m8o$yv-OUCP|sdK_Uvw( zS-4Hh7LhsDK(&UhSNiRHI=y=Pgif1T6ZwhyfEy>VL7`8qw-VkM3KO@%*vi(6ZOZG_ z_iwyMVas9<;`Mt@H*{9}&V$*;&W0B9R+MTZ;SC~b+mHQA^cgSj5dEk2uL58y`xkp7 z=2EAvt)4yUf&~4wi8O69imkYi@yFG22(yI^n+>8gGl$xtcmM zMw`!f>|U{Y+3-LjPSyAgO8I>3!-%oF(KC-7n5@6KK8 z4Eq-3ZfE~rHT{1p)|U}U_$4~JJF%AzBR)Vs?E3wQy>vKdXc?ThX7V;<_uB2;yJH`h8xZd*HVh6K9+*{q=xzUAz(fL%;FpH^_06U z+>4j7keJ8*>oo7zQ&)7YWcb`m-K=Z5*Rr)+sEvDGJtGV5_kLfpLhgjNaqga;&siex zP=r`|W*e>!7|++WPHzpiBeOAL7BlidwGusK#0T1743BzNN%T}zLsLINU^^9TJEu|pj;jA6?}V;{*I#^i6^m$ax%`erS33JJsN0EC1rd=Z=ls=`$GSfZ{SSyIp|NBL`9ltQ}s(QrV!KpHL6zg{guEZ}z<_Mm# znA8#jU2LquH}iofIJw8E6+5W-X0228b=jf7kUKd0oi+_Ut2*hKVfP2thRN~%znmMC zzxB7$&^!3IoBk-7_bl-k_wg41?#~%VAAZkr)+hYXa0K)p>W|cuE<6+_M!lbMSJ8Hm z|K-jh!BQfUR!Lg;LLHBIE3upc+|gYjd_h_eJO2YFzSGZ0tD8U?@^mkM5=$q`V?}mx zA8ssn)@6PXS1Ho-Lo3u)?0=!9hc#k9ej(EY7kJ@r>I*LfiH#M>%7av-=-WSMYGd zm$StNm%b?Hn^O+rAAb|@za3+#I0RKCGb-AKria?N$GgRW%ejR6o?1=k8`>$gB3l+h z=lD4y=jMad9H{`d!Yx%~9p~iSwRGml_MuW=mt6!5nIk78DX-}`$Sxyqg}j51Wd4+p zCvlPT_>)*mRkZgVazomzqRo6_D*XxjgN$zxW!<#Vx>}Zf66qN(Uh&szUTIyYd8HIy zyf3d~^?C4u?-i}ema#{OClS8 zCuz*vp`?9-U0&wpozT5$d$e&mcS-{Irpa7r9zRFJtUPW-O--IkWzm`W;{|<@fhHib5OPi$ljG@aayEeqTWNw1)Ty z^|Mou<%j0er+^`Mf!3+A@jSWMz^@}Vgy3?m!DX(&WsdsIuwSIFA_Ii}SCBTMzrO3Z zhxrrc3~w;Dm#Pb8Pe_b*;^Y+4N0FU{s*icL#Icex6-T4TxacBuyKSGoBY4|UGve+R zI<(yOjn4nk&>8xjB;X3|8f07<3w-x#x9{-OHqJ!eFdp0Q9TRHie`&8}tj38m;Vw88 zfRpfp^5sCsbL&&G4oWOhk>|3{<;>WTIqKY6WRv7$AAB<;?ZRJ28d?ofzghMGer3MO zyp{P|rTeYste*D+?F*oPjY${z(fmTR{55?`?^_ykyBG8!xf0EI=*@zqBft+4e{3cYysNzrqu8KGRwM zT2p^Ptp4@XmvXBq=RR}&3vWKlnd>8mICFK+rT2OJS>(^ppqZSv+E(nmRnqSzJ=vM7 zM&z)BIYOp7_y)LcuzL=6H+o63gV3rx)k@=u`YJlCy zT#az{RbcW8I`i`Er^w4?u6s?Mm%M7uf@LfpCr{oBkoETw{%>%tv3h@=W&fJ=PiLTS z?T^YHbGhvK!ZXbH-k`^K9sIE$d3lwARhs~-Rr%}iei!K*7=O*{dF>^{iqi8fx4oYK zWp2GmTkbxV@LtiMsdK%h_FTICOHKRpV*K?k?MpvS7rq?EJwnBwdG@{36P^21^*zYu zQF&QQ6r8#W4X5OqSU+AdaE7V!tfQ{-zDsoZ=Bik`FPQQJP5C_2?i|%_hV66LpK9t~ z6{{aI^?OM@@J=`Nry0Dvt8d=JbioNvHvPXM24}T_6Diej_RBB*{)S&ayzIPvzBzJv z=h<8}a{T){%h`ucVLv*Ved$H)PbU$-Zeoc2YOU<09a{M(>NZ;gFrA`J3LpgIGAS7WVy4$8AH8C%%`JIU3qZy4R#PlP>)2#Ji%u zijJxupIx3{x70DQoHG9LF&jexumg8!z3gcIFF2rev1a6?+lNK`XyW=58CIMvb+4JA zXeY7ZviNq(T*uGl5yt;eelBjfE&GNQ2dgHWB>fQI`BPa-9Nq|=qsQDc$?zj*j(f;Y zMhB7E!%Yk}@sa6*|DIvR|AJSbXQ$sxJ?oSB%_NpB_cmyc+3lrrPS^NU)etj?k%m1frl~A(R+mQFyoDX^@^10IR9!d{z_uckiByFc)i#3 zVuKkR@qbNh!t$yldixZS|Hz;#kYTbw6~Z$wU(Q-1aXl#OHFgW{ zah8tv%bHk8jIIXk7CDTuTQ+N0S#~k7q7sYeSZ&{&PrC=RwaB{m_OaH6XR(Rw>G#!h zn~$^(H!$C5U@a`1f8^mi2UsIo25Fm$kMcX_NMQfN=S8fBw68#sce^mCB0QJhAapR@>Rrvb;J-Zj*# zJDPaY!~on+jP5XYiz`X9B#js|zraTE?YmZJ&sI-pF!fa&DP!kJ_v*cY#G-0QBNo+A zi7lC(WDgsQMfEr^PGelFT>M*tOc8#RJ;No~IT}o!@P)%`zoMSZAMd8im0wH!W%`Wy z>*>ljM9F^Nky;LvoIFLzo`r{D(@AJ6h~KlDKbnjmbXk*z+ghRFe&B)|7^vY^pP=Cm z0j}sR+f{#c-<&=7Mc^sC(KN6#wt~{t!U=QMhu-DJBfxhHbREl>ioCDqTl(wy)8+US z@NO_;62yO8{=Y>3uk0oAEqjM2!PiaGYU&G3F9e?wp@F66)dhSnIN<+U?qsaavx*H4 z$`;m!jw)@2{t#QE!@y~#esPZGjepXP@DwtraV_c6#z!K^I4891X~m_s3rbB_daBAqxG9K zT{nM#uDcMpUqR!xH}(2l!rcLp*^aHG)>YTnUDqwijnyqwZRgk@e!qY9E5LEuX-d^) zTeEdp!T(5u=P7F3bL=hDX>iR|i7S=`jJhJH583uu`XKh4KY~ZqyBfz<;dK{|jbgW9 zKhOxgOWqgzV~+g{|2r}+kF=54RYZ?WgZBgPM;n)rZ;>W)>voCRjXg)=b$8O^b2moHUPO8{RrF-;;@yd^yeW1cFDg3nXwE}s z%l$?xwCJL)I`aA7?RWc0b?V3^=(MfqyB_ZKIKJ5pDZXMQ*B=x;$lLCtufaUcKffb( zwKJanFZFmI-d6H17|ho+OYk3iH+#!)YmN4I<>@Jm$nL5X`Onz(W#d! zAE$U2rADt_oFvcMGuh~&8MgTJSs5{1cPrn~P2JE3`ydPYA`=cnHuOVA^oN#*bGNY@ z?+SFYJBX9|9eUv&?pDfrEO@mo*ScW?XKn?o?^bu-sgkob-dgm5nTIlzS@;cKi_`-bN*HUGh@?nJGBMY!ju=9STJ1m~s`w0_fo?5`Svj>CE0$$|&zA}bnzRbbMO zCEbs1Eqc!TavpP8kI;cL>BAz4*OO~I{rDs0n(!5ub0IU|cFTM_FlBT|>nGg*p=~er zC3W@(oxJGTv3c2lnJBPCOp5O^BM%R-vi_!IncNxmf z!)D96EOwb6z(aJ40<90Kw^(%hd3HJN%iXnohcUOr7vPoBNC)#^?~ZPveJ9eVp|NpU z44g3i@ml&E!E51zm!KDg`F8hJ?xYD^&t^H3g*NPCX8|YBtD{))=&jggBpvxWo%FiF zCVkbpIvv_vEbWpGoaGt3G0E7)jkV>|W9{Qt#(F8`{opBmrfkG(#`&kD2jOecMP;1J z2J3Nt4th5oiH?trzkzY~n)IhhCywogFk>w5xCx%3Gs&B$!W*(za`&~8J+$amQSwgZ ztxO-dblNX&j;#yT#Jc_d&dJQ}imFI?KSHWZ+*Yzs$Rdz{i{XJgg;0tTEYLqf1e3I@dgR}kjX7*rE4^Z{P<^D zk$iv6I_b3S|DD0FPYk~|!7t3Y?g(jTpg(eoY40S}{y_Ug7w-P&P5oZF{!y)N+;iZ-P3wgc~)idT$Ju-wG~_SASFgFjK#esozWe=BijI4xGAYH5|wP zQF!Db11Ea6z~j9=euY-2vFgISa9+14Agf0&^DzoKBK`W3xL+XTJ#g?sm}_Vw2G zz(V%zg~a@p{aZEn4&3&@n%=&m2HuEp-h|-(_)XhWYu3zS-|T)XVw7jlO*=?mBp8Z%F*b8~=vHINmmM-jHZz-|2osVqRMO8xo&kr*z(sXqG){!W$CR ztOK2INIc9N68H&y{IGsQ;#G8`!Cvb|AO2ZFtMJ%F`{Ed6qrCr`(rJTysZ4aQl=cAo zzq;`FNm5Vt{qnnGjO3-Z`^gJz)_Gz-JdK$64sTg&^%ytr)?@M#@1u5*Zz-E+e0$-y zC!Hj43eX*Lc5A-uJ0z zjd8y#A!m#KlXoS4Nxeh8E8#oHyAty5>%V(f!heW&CGMhr*FA!sOR_&Gy4g`XMkMlRd>Lz%##{JA?tX@wG~cZ57vsV3eY#Bjhq_-W z*}=(|bn;+4ysk9TZ$CJDD2En{cFs|<#eLSWw}W-aoHe-VQfc;4hAv+fUTN;3kS??s z!v3nv*mKcS_5SMk%eklERquO-Uv}nJie2gIm+v0kuj&W&{w8H$aB}`Z`X%)KP5r;8 zx4-bv^bRhL(OY82S<`jf+xY*`?^Af+_(r{>q2HPio0N=i%Q0pT#d{T_yu1y@S>x(s zIFBRNX`9x=R9sKl%gY$QU4c&pbxod%Q>gX79DBhu;+J39QC!p4AIZs&k9Y3Wzx$Gd z*S}usU!m&{9&Ftd#wQ>PI1R_>_s$y72LiP@Lz0|`&bv> z1b@+g{d24hBm3&NB|agoX&$~o^xN`S5#ImI%sD!F|Iax@|4*c?+-p0ErSBH=ROpyp z$ez`V1H2g#95w?(+86t^wr6J91*9okv+0AB4fx{Ezw7wk@9QY~3jEX<0o#nD8sqn{ zWoJ(kzqwp{J@8~7W?dy`05bM@b{1(uWAW=Vw93t*C_eLA#P z<9GPw6>GWUyxGIPg|*OGtLo-x-fmu~b%~=wdfug+AUbrW{UCF1BQmBAyM!}-)mI#P z{IMan;3GHUl2Q_|IGJapD71d$Gx}UjY_Rza!4_(dJ3!dTLmsk9S`rx;Iz}uyf z(~+gc*qd*=Ow;IUhaSZGZ-52{hT4bM!E1iXsl7PAe%d|?SV8xr=;@U*W44C+q>KFS_{Ev|j*jGT(2aOn^Hx z!jE1{?H9Ymb*>CY%Pq!M>Q+#<#WgoP${(E=XQaDvZ6fXhkv(pD>b_>%Kah883G)G( zNWI)$(<|gRXAi&l$&^g6%H^&3eb^G+xaj&>_7~JI%C<&))Dt~9@$++xqIZ1H}hvdw#6#&4+0FAz)1%8Ed=wfRkdj3s;C2Oq2v&wC^Sl`Y9maG$wUuMf2)73fdUDS7EiSHyMpT=rgvhY}N zWv(Af8O{aNI^&j&V$YJfShYpN5}7rZvWYUIeq*%!8GP@il80ZViecUIH>XaPJ%eFcN9En_JAQu%HzSN-d< zhNP39?dp5mt4`lD?7^f9y^`VcBKYj(-GCa?mlpgSY8*YYQ0pn#2hlUvQ}-kE%bu8( zI{k8Z$A6^eoyuaf4#7J!%sR1l-~QF_qZc`P-)i6q-2&^Qja&FX3~vby+Favbxn9OI z$G)3>xb?q$m7ZtcA+-5zw6U}O0jB*^b^D^@No)b(&k@bjE2`i>DJyY2YCO8^*i-ag zXD4wy*5!}a`@gL^j>mn#m%1&_o3SGOIdHXdblv=ubUWLJ>o^`mY0JSSoTbZnPK=cq z=+4hH`6uZ7Ao(h!(Yljw!0bM z!3H;Y@kA4MzVa6^7q{I zF+AQnz`z5CAGz9VvJ8FlV);E3j#>8a=;Mv9vVrJDH^^M5&edfXGKN>X^M5e;IXZtG z`Fj{o;giRKbvb3jN9*||Ytm8VT?|cy{*LbG#QtqM$>E7?dw}7IRm_bl$G?JiBt(Wg zJh6;C--%A0OuG+tih%ulnQzA5p_w{v+C3|Ij{e-Caj);Mai0b5FB{zN0C(Y++xR`6 zK5T$z_Pvv)?yfu!4FBL*pS~m>abllDR^3fK>&RHSPm+{tChqYH$~6s&mHS7Ma+QtI z@&?KU2gb_1k))jG`DpncDd!&$EBEIlG(IK$wTyAbFmWKaszUzz z+_ZWC7+=fScf@>E#OGh|OYBSa9ntb;r_U}r$U6x_hYMV3ACT5?AO^F<^!Z`Zllk-} z_T!rWz?Y}W&_dR*Tj<9)cunwd`_`OCT8qoKrqaaT8%6pd?V5{vzOg+cCA0$@iO9UN z;B*~}51$b4Abc7Qh(CeH7X78LW5N9r>$vc{k`+6LSrIuO!gpZzxqs&FMjvdJ^XGK5 z8U3*hTnj`W$41iJNJBAj)|2+>0%GaDU#0g0IrWj&I6Vb+?K<_z#Hv+B=o~ zi4|5h>h{~G;{(*Iy^{Gh0H23(z?w_`Ygt>0#sh0DzPOcHyjujUrNCMWUY}+9ipB$L z8Q)LxeQjpHqGizGMR`A+J^G>AXBYbE=J0%TR&P%Cn#{F*gI=&fx4IrisM*hBu_ z+Hhxo{4I^|hWPUC=j^!-xm9M;%18_IZRXnU7GU^z3()Y}ZsE58-_IRx6>aHmW&Vb? zmf|b&8`9^Q|L5`lc>2E+UanN#}q3vJi^edVtu!Qb&tnzu#(xKgFRaVhlXzA3Q%lEOA!Cu<8WE8@Lz`igXq=RU8;vrBk;Zq@XPv-&StQ^ow1ahE+--Oh27B=1aU zt!NA%lnGD42R*^x&`RCMvnB3?@EG`&Fji&s#S8ArCf?0gR7PJM-X7a6#@nsPC^GX<69wU||vZHu@RTmjk z@SeA57ctsJ&d59UaxT$+4)TP)dC`&ArslO1r=Wbz@m6tTPkak0_hJuk`(Mu1@+h?L z?yb3V=5%<6Y5IGa7efDrzDB0Vc;l1rmMJZL7(>RpCu4d6WiQ}+IQ%%1wktUU8V)~B z2NxyZNGsu8!F1BjAkAy$pR}XrY_4rVm$l-j|B6-qK`*O#KyRyfI)7{AcM9{EzI%`G zM;7Bl-;;KJ1>NM{&Jt*~nzw1kdeWbGgz*(QJPZ<_Q;%vNGB^iz&BW)O^;8Kg&(PQT*^@$(y75-|9cfl^3o=J^6_Hco-+mf#6b47r zc0bA5A@muT*LlygR^V{oVC#h!q3eCDV@-?&=cY_Y@5{9%KJ{7j*+r&qXnz+&E}Q+^cXtBGanrM&2m>8AY6qo-Hgq43DHe?}W}j>iehEncpUP@`m3a`%KB>TkuUrCxLMjbq3+zT!rit+|y4J zo7zBCU+i;r@WR#5QfzAOu?n(w)|j!Yf#ywoXLq+6moR^)P2!w|a}%lKMJ_XT>Wsl% zKOa3MgK@c!ve>{j2!F-p<0CBoT!K@>2**Y+$X-VI#IopY&}N{0JhXA+RISnn*~3WR z$eZgeMyK%h?5FS1Fu&{3P5uE7N&iKj7o>ZOK0x27G2ac|f+B;L;w=MT-I0kKALgTs zPjA|~EQEc+#n;s;Z=l_syo14tz~|v%tkd*Q=;r&IoF5Ki9PkgEsO=P{?cG9eXcoVI zGfp>qI*KlY{!(ujW9G(B+YPhrk4b;Fp`&;KXBN$zSqOb^K5=@*wr*B&Zg;ELjklaf zx!Y`gJ6e9M%%vsHT9R$gB?k9E#!l8ycYAWb;t%lj@Q?I7sl=}{ah^PT?DUG==&8c5 zTXyeXy$?CHNzH=+_Ex@EsJsCxui{(H^RJWc#!;U~4YZ%4Uv6Bhx9Ih&f%IzN^a8(` z_`gq>df&F=F0yK$LY~|M&n}yP?ekC0@3myX{0Z&tseSCvQ~TOJY^=jQ$ana5xW|f| zf0G3Cc>_ zV;{Xwl|40odc{=->Fc@wVP8)(IBh+0dc_i8{bhf2V^6E?%>}GEm5gam_DzD<)+6Ha z3b$~7neyq8=*D!)%epRiozqSEDTB~q$d^9;)r#-q%>$=bi2e01>>)ebV(vO^-8^7= z#nt4CkE4+%yS?a2CI64NH;<39NFKPKNkArCg5-b@WdbPS@L0h_JeCOvhQkYjjG!_B zkKl{2wcqu! z4%UMbw^s5HcMZ5-7kXI7LU-WKWgax}&_?b^h0%G7d7t-Cq++V{6K9c-=$vkY7b^%k?c5mQa54_&M zI~#akVN-byet(X0hv4<>Qwuh^Y1DEt@uu`6adjsrS{2gQyr<@GdY^WDKkVh!tfMs^ zbb4$HtyxFzw!PpLS%>pHqT{!!3oef2SMI*p==dG&=H$F~pB<+FvlTE~0dtwBm9o*a z0_F>p3mor(ae>?mho2_@Oa3u=meo_1KYX(MZ!xwPE>u1=eLw6{ZR;wyQSSut2g)_u}%|7^VnF5Wdx`P(1eKQ53lMAP9?bndal zwaIzq^$a<$kPjpwscxRxH_Lt;r+kZr7KSv6%^)W?x^mp9u7y^3h#pRQ$`(C

h3D(|7mI!u@;=CKvDqJxJGS6EpR&q% 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

+            e = DateTime('US/Eastern')
+            # returns current date/time, represented in US/Eastern.
+
+            x = DateTime('1997/3/9 1:45pm')
+            # returns specified time, represented in local machine zone.
+
+            y = DateTime('Mar 9, 1997 13:45:00')
+            # y is equal to x
+            
+ + The date component consists of year, month, and day + values. The year value must be a one-, two-, or + four-digit integer. If a one- or two-digit year is + used, the year is assumed to be in the twentieth + century. The month may be an integer, from 1 to 12, a + month name, or a month abbreviation, where a period may + optionally follow the abbreviation. The day must be an + integer from 1 to the number of days in the month. The + year, month, and day values may be separated by + periods, hyphens, forward slashes, or spaces. Extra + spaces are permitted around the delimiters. Year, + month, and day values may be given in any order as long + as it is possible to distinguish the components. If all + three components are numbers that are less than 13, + then a month-day-year ordering is assumed. + + The time component consists of hour, minute, and second + values separated by colons. The hour value must be an + integer between 0 and 23 inclusively. The minute value + must be an integer between 0 and 59 inclusively. The + second value may be an integer value between 0 and + 59.999 inclusively. The second value or both the minute + and second values may be omitted. The time may be + followed by am or pm in upper or lower case, in which + case a 12-hour clock is assumed. + + New in Zope 2.4: + The DateTime constructor automatically detects and handles + ISO8601 compliant dates (YYYY-MM-DDThh:ss:mmTZD). + + New in Zope 2.9.6: + The existing ISO8601 parser was extended to support almost + the whole ISO8601 specification. New formats includes: + +
+            y = DateTime('1993-045')
+            # returns the 45th day from 1993, which is 14th February
+
+            w = DateTime('1993-W06-7')
+            # returns the 7th day from the 6th week from 1993, which
+            # is also 14th February
+            
+ + See http://en.wikipedia.org/wiki/ISO_8601 for full specs. + + Note that the Zope DateTime parser assumes timezone naive ISO + strings to be in UTC rather than local time as specified. + + - If the DateTime function is invoked with a single numeric + argument, the number is assumed to be a floating point value + such as that returned by time.time(). + + A DateTime object is returned that represents the GMT value + of the time.time() float represented in the local machine's + timezone. + + - If the DateTime function is invoked with a single argument + that is a DateTime instance, a copy of the passed object will + be created. + + - New in 2.11: + The DateTime function may now be invoked with a single argument + that is a datetime.datetime instance. DateTimes may be converted + back to datetime.datetime objects with asdatetime(). + DateTime instances may be converted to a timezone naive + datetime.datetime in UTC with utcdatetime(). + + - If the function is invoked with two numeric arguments, then + the first is taken to be an integer year and the second + argument is taken to be an offset in days from the beginning + of the year, in the context of the local machine timezone. + + The date-time value returned is the given offset number of + days from the beginning of the given year, represented in + the timezone of the local machine. The offset may be positive + or negative. + + Two-digit years are assumed to be in the twentieth + century. + + - If the function is invoked with two arguments, the first + a float representing a number of seconds past the epoch + in gmt (such as those returned by time.time()) and the + second a string naming a recognized timezone, a DateTime + with a value of that gmt time will be returned, represented + in the given timezone. + +
+            import time
+            t = time.time()
+
+            now_east = DateTime(t,'US/Eastern')
+            # Time t represented as US/Eastern
+
+            now_west = DateTime(t,'US/Pacific')
+            # Time t represented as US/Pacific
+
+            # now_east == now_west
+            # only their representations are different
+            
+ + - If the function is invoked with three or more numeric + arguments, then the first is taken to be an integer + year, the second is taken to be an integer month, and + the third is taken to be an integer day. If the + combination of values is not valid, then a + DateError is raised. Two-digit years are assumed + to be in the twentieth century. The fourth, fifth, and + sixth arguments specify a time in hours, minutes, and + seconds; hours and minutes should be positive integers + and seconds is a positive floating point value, all of + these default to zero if not given. An optional string may + be given as the final argument to indicate timezone (the + effect of this is as if you had taken the value of time.time() + at that time on a machine in the specified timezone). + + New in Zope 2.7: + A new keyword parameter "datefmt" can be passed to the + constructor. If set to "international", the constructor + is forced to treat ambiguous dates as "days before month + before year". This useful if you need to parse non-US + dates in a reliable way + + In any case that a floating point number of seconds is given + or derived, it's rounded to the nearest millisecond. + + If a string argument passed to the DateTime constructor cannot be + parsed, it will raise DateTime.SyntaxError. Invalid date components + will raise a DateError, while invalid time or timezone components + will raise a DateTimeError. + + The module function Timezones() will return a list of the (common) + timezones recognized by the DateTime module. Recognition of + timezone names is case-insensitive. + """ + + datefmt = kw.get('datefmt', getDefaultDateFormat()) + d = t = s = None + ac = len(args) + microsecs = None + + if ac == 10: + # Internal format called only by DateTime + yr, mo, dy, hr, mn, sc, tz, t, d, s = args + elif ac == 11: + # Internal format that includes milliseconds (from the epoch) + yr, mo, dy, hr, mn, sc, tz, t, d, s, millisecs = args + microsecs = millisecs * 1000 + + elif ac == 12: + # Internal format that includes microseconds (from the epoch) and a + # flag indicating whether this was constructed in a timezone naive + # manner + yr, mo, dy, hr, mn, sc, tz, t, d, s, microsecs, tznaive = args + if tznaive is not None: # preserve this information + self._timezone_naive = tznaive + + elif not args or (ac and args[0] is None): + # Current time, to be displayed in local timezone + t = time() + lt = safelocaltime(t) + tz = self.localZone(lt) + ms = (t - math.floor(t)) + s, d = _calcSD(t) + yr, mo, dy, hr, mn, sc = lt[:6] + sc = sc + ms + self._timezone_naive = False + + elif ac == 1: + arg = args[0] + + if arg == '': + raise SyntaxError(arg) + + if isinstance(arg, DateTime): + """Construct a new DateTime instance from a given + DateTime instance. + """ + t = arg.timeTime() + s, d = _calcSD(t) + yr, mo, dy, hr, mn, sc, tz = arg.parts() + + elif isinstance(arg, datetime): + yr, mo, dy, hr, mn, sc, numerictz, tznaive = \ + self._parse_iso8601_preserving_tznaive(arg.isoformat()) + if arg.tzinfo is None: + self._timezone_naive = True + tz = None + else: + self._timezone_naive = False + # if we have a pytz tzinfo, use the `zone` attribute + # as a key + tz = getattr(arg.tzinfo, 'zone', numerictz) + ms = sc - math.floor(sc) + x = _calcDependentSecond2(yr, mo, dy, hr, mn, sc) + + if tz: + try: + zone = _TZINFO[tz] + except DateTimeError: + try: + zone = _TZINFO[numerictz] + except DateTimeError: + raise DateTimeError( + 'Unknown time zone in date: %s' % arg) + tz = zone.tzinfo.zone + else: + tz = self._calcTimezoneName(x, ms) + s, d, t, microsecs = _calcIndependentSecondEtc(tz, x, ms) + + elif (isinstance(arg, basestring) and + arg.lower() in _TZINFO._zidx): + # Current time, to be displayed in specified timezone + t, tz = time(), _TZINFO._zmap[arg.lower()] + ms = (t - math.floor(t)) + # Use integer arithmetic as much as possible. + s, d = _calcSD(t) + x = _calcDependentSecond(tz, t) + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x, ms) + + elif isinstance(arg, basestring): + # Date/time string + iso8601 = iso8601Match(arg.strip()) + fields_iso8601 = iso8601 and iso8601.groupdict() or {} + if fields_iso8601 and not fields_iso8601.get('garbage'): + yr, mo, dy, hr, mn, sc, tz, tznaive = \ + self._parse_iso8601_preserving_tznaive(arg) + self._timezone_naive = tznaive + else: + yr, mo, dy, hr, mn, sc, tz = self._parse(arg, datefmt) + + if not self._validDate(yr, mo, dy): + raise DateError('Invalid date: %s' % arg) + if not self._validTime(hr, mn, int(sc)): + raise TimeError('Invalid time: %s' % arg) + ms = sc - math.floor(sc) + x = _calcDependentSecond2(yr, mo, dy, hr, mn, sc) + + if tz: + try: + tz = _TZINFO._zmap[tz.lower()] + except KeyError: + if numericTimeZoneMatch(tz) is None: + raise DateTimeError( + 'Unknown time zone in date: %s' % arg) + else: + tz = self._calcTimezoneName(x, ms) + s, d, t, microsecs = _calcIndependentSecondEtc(tz, x, ms) + + else: + # Seconds from epoch, gmt + t = arg + lt = safelocaltime(t) + tz = self.localZone(lt) + ms = (t - math.floor(t)) + s, d = _calcSD(t) + yr, mo, dy, hr, mn, sc = lt[:6] + sc = sc + ms + + elif ac == 2: + if isinstance(args[1], basestring): + # Seconds from epoch (gmt) and timezone + t, tz = args + ms = (t - math.floor(t)) + try: + tz = _TZINFO._zmap[tz.lower()] + except KeyError: + if numericTimeZoneMatch(tz) is None: + raise DateTimeError('Unknown time zone: %s' % tz) + # Use integer arithmetic as much as possible. + s, d = _calcSD(t) + x = _calcDependentSecond(tz, t) + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x, ms) + else: + # Year, julian expressed in local zone + t = time() + lt = safelocaltime(t) + tz = self.localZone(lt) + yr, jul = args + yr = _correctYear(yr) + d = (_julianday(yr, 1, 0) - jd1901) + jul + x_float = d * 86400.0 + x_floor = math.floor(x_float) + ms = x_float - x_floor + x = long(x_floor) + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x, ms) + s, d, t, microsecs = _calcIndependentSecondEtc(tz, x, ms) + else: + # Explicit format + yr, mo, dy = args[:3] + hr, mn, sc, tz = 0, 0, 0, 0 + yr = _correctYear(yr) + if not self._validDate(yr, mo, dy): + raise DateError('Invalid date: {}'.format(args)) + args = args[3:] + if args: + hr, args = args[0], args[1:] + if args: + mn, args = args[0], args[1:] + if args: + sc, args = args[0], args[1:] + if args: + tz, args = args[0], args[1:] + if args: + raise DateTimeError('Too many arguments') + if not self._validTime(hr, mn, sc): + raise TimeError('Invalid time: %s' % repr(args)) + + x = _calcDependentSecond2(yr, mo, dy, hr, mn, sc) + ms = sc - math.floor(sc) + if tz: + try: + tz = _TZINFO._zmap[tz.lower()] + except KeyError: + if numericTimeZoneMatch(tz) is None: + raise DateTimeError('Unknown time zone: %s' % tz) + else: + # Get local time zone name + tz = self._calcTimezoneName(x, ms) + s, d, t, microsecs = _calcIndependentSecondEtc(tz, x, ms) + + self._dayoffset = int((_julianday(yr, mo, dy) + 2) % 7) + # Round to nearest microsecond in platform-independent way. You + # cannot rely on C sprintf (Python '%') formatting to round + # consistently; doing it ourselves ensures that all but truly + # horrid C sprintf implementations will yield the same result + # cross-platform, provided the format asks for exactly 6 digits after + # the decimal point. + sc = round(sc, 6) + if sc >= 60.0: # can happen if, e.g., orig sc was 59.9999999 + sc = 59.999999 + self._nearsec = math.floor(sc) + self._year, self._month, self._day = yr, mo, dy + self._hour, self._minute, self._second = hr, mn, sc + self.time, self._d, self._tz = s, d, tz + # self._micros is the time since the epoch + # in long integer microseconds. + if microsecs is None: + microsecs = long(round(t * 1000000.0)) + self._micros = microsecs + + def localZone(self, ltm=None): + '''Returns the time zone on the given date. The time zone + can change according to daylight savings.''' + if not _multipleZones: + return _localzone0 + if ltm is None: + ltm = localtime(time()) + isDST = ltm[8] + lz = isDST and _localzone1 or _localzone0 + return lz + + def _calcTimezoneName(self, x, ms): + # Derive the name of the local time zone at the given + # timezone-dependent second. + if not _multipleZones: + return _localzone0 + fsetAtEpoch = _tzoffset(_localzone0, 0.0) + nearTime = x - fsetAtEpoch - long(EPOCH) + 86400 + ms + # nearTime is within an hour of being correct. + try: + ltm = safelocaltime(nearTime) + except BaseException: + # We are beyond the range of Python's date support. + # Hopefully we can assume that daylight savings schedules + # repeat every 28 years. Calculate the name of the + # time zone using a supported range of years. + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x, 0) + yr = ((yr - 1970) % 28) + 1970 + x = _calcDependentSecond2(yr, mo, dy, hr, mn, sc) + nearTime = x - fsetAtEpoch - long(EPOCH) + 86400 + ms + + # nearTime might still be negative if we are east of Greenwich. + # But we can assume on 1969/12/31 were no timezone changes. + nearTime = max(0, nearTime) + + ltm = safelocaltime(nearTime) + tz = self.localZone(ltm) + return tz + + def _parse(self, st, datefmt=getDefaultDateFormat()): + # Parse date-time components from a string + month = year = tz = tm = None + ValidZones = _TZINFO._zidx + TimeModifiers = ['am', 'pm'] + + # Find timezone first, since it should always be the last + # element, and may contain a slash, confusing the parser. + st = st.strip() + sp = st.split() + tz = sp[-1] + if tz and (tz.lower() in ValidZones): + self._timezone_naive = False + st = ' '.join(sp[:-1]) + else: + self._timezone_naive = True + tz = None # Decide later, since the default time zone + # could depend on the date. + + ints = [] + i = 0 + len_st = len(st) + while i < len_st: + while i < len_st and st[i] in SPACE_CHARS: + i += 1 + if i < len_st and st[i] in DELIMITERS: + d = st[i] + i += 1 + else: + d = '' + while i < len_st and st[i] in SPACE_CHARS: + i += 1 + + # The float pattern needs to look back 1 character, because it + # actually looks for a preceding colon like ':33.33'. This is + # needed to avoid accidentally matching the date part of a + # dot-separated date string such as '1999.12.31'. + if i > 0: + b = i - 1 + else: + b = i + + ts_results = FLT_PATTERN.match(st, b) + if ts_results: + s = ts_results.group(1) + i = i + len(s) + ints.append(float(s)) + continue + + ts_results = INT_PATTERN.match(st, i) + if ts_results: + s = ts_results.group(0) + + ls = len(s) + i = i + ls + if (ls == 4 and d and d in '+-' and + (len(ints) + (not not month) >= 3)): + tz = '{}{}'.format(d, s) + else: + v = int(s) + ints.append(v) + continue + + ts_results = NAME_PATTERN.match(st, i) + if ts_results: + s = ts_results.group(0).lower() + i = i + len(s) + if i < len_st and st[i] == '.': + i += 1 + # Check for month name: + _v = _MONTHMAP.get(s) + if _v is not None: + if month is None: + month = _v + else: + raise SyntaxError(st) + continue + # Check for time modifier: + if s in TimeModifiers: + if tm is None: + tm = s + else: + raise SyntaxError(st) + continue + # Check for and skip day of week: + if s in _DAYMAP: + continue + + raise SyntaxError(st) + + day = None + if ints[-1] > 60 and d not in ('.', ':', '/') and len(ints) > 2: + year = ints[-1] + del ints[-1] + if month: + day = ints[0] + del ints[:1] + else: + if datefmt == "us": + month = ints[0] + day = ints[1] + else: + month = ints[1] + day = ints[0] + del ints[:2] + elif month: + if len(ints) > 1: + if ints[0] > 31: + year = ints[0] + day = ints[1] + else: + year = ints[1] + day = ints[0] + del ints[:2] + elif len(ints) > 2: + if ints[0] > 31: + year = ints[0] + if ints[1] > 12: + day = ints[1] + month = ints[2] + else: + day = ints[2] + month = ints[1] + if ints[1] > 31: + year = ints[1] + if ints[0] > 12 and ints[2] <= 12: + day = ints[0] + month = ints[2] + elif ints[2] > 12 and ints[0] <= 12: + day = ints[2] + month = ints[0] + elif ints[2] > 31: + year = ints[2] + if ints[0] > 12: + day = ints[0] + month = ints[1] + else: + if datefmt == "us": + day = ints[1] + month = ints[0] + else: + day = ints[0] + month = ints[1] + + elif ints[0] <= 12: + month = ints[0] + day = ints[1] + year = ints[2] + del ints[:3] + + if day is None: + # Use today's date. + year, month, day = localtime(time())[:3] + + year = _correctYear(year) + if year < 1000: + raise SyntaxError(st) + + leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + try: + if not day or day > _MONTH_LEN[leap][month]: + raise DateError(st) + except IndexError: + raise DateError(st) + + tod = 0 + if ints: + i = ints[0] + # Modify hour to reflect am/pm + if tm and (tm == 'pm') and i < 12: + i += 12 + if tm and (tm == 'am') and i == 12: + i = 0 + if i > 24: + raise TimeError(st) + tod = tod + int(i) * 3600 + del ints[0] + if ints: + i = ints[0] + if i > 60: + raise TimeError(st) + tod = tod + int(i) * 60 + del ints[0] + if ints: + i = ints[0] + if i > 60: + raise TimeError(st) + tod = tod + i + del ints[0] + if ints: + raise SyntaxError(st) + + tod_int = int(math.floor(tod)) + ms = tod - tod_int + hr, mn, sc = _calcHMS(tod_int, ms) + if not tz: + # Figure out what time zone it is in the local area + # on the given date. + x = _calcDependentSecond2(year, month, day, hr, mn, sc) + tz = self._calcTimezoneName(x, ms) + + return year, month, day, hr, mn, sc, tz + + # Internal methods + def _validDate(self, y, m, d): + if m < 1 or m > 12 or y < 0 or d < 1 or d > 31: + return 0 + return d <= _MONTH_LEN[ + (y % 4 == 0 and (y % 100 != 0 or y % 400 == 0))][m] + + def _validTime(self, h, m, s): + return h >= 0 and h <= 23 and m >= 0 and m <= 59 and s >= 0 and s < 60 + + def __getattr__(self, name): + if '%' in name: + return strftimeFormatter(self, name) + raise AttributeError(name) + + # Conversion and comparison methods + + def timeTime(self): + """Return the date/time as a floating-point number in UTC, + in the format used by the Python time module. + + Note that it is possible to create date/time values with + DateTime that have no meaningful value to the time module. + """ + return self._micros / 1000000.0 + + def toZone(self, z): + """Return a DateTime with the value as the current + object, represented in the indicated timezone. + """ + t, tz = self._t, _TZINFO._zmap[z.lower()] + micros = self.micros() + tznaive = False # you're performing a timzone change, can't be naive + + try: + # Try to use time module for speed. + yr, mo, dy, hr, mn, sc = safegmtime(t + _tzoffset(tz, t))[:6] + sc = self._second + return self.__class__(yr, mo, dy, hr, mn, sc, tz, t, + self._d, self.time, micros, tznaive) + except Exception: + # gmtime can't perform the calculation in the given range. + # Calculate the difference between the two time zones. + tzdiff = _tzoffset(tz, t) - _tzoffset(self._tz, t) + if tzdiff == 0: + return self + sc = self._second + ms = sc - math.floor(sc) + x = _calcDependentSecond2(self._year, self._month, self._day, + self._hour, self._minute, sc) + x_new = x + tzdiff + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x_new, ms) + return self.__class__(yr, mo, dy, hr, mn, sc, tz, t, + self._d, self.time, micros, tznaive) + + def isFuture(self): + """Return true if this object represents a date/time + later than the time of the call. + """ + return (self._t > time()) + + def isPast(self): + """Return true if this object represents a date/time + earlier than the time of the call. + """ + return (self._t < time()) + + def isCurrentYear(self): + """Return true if this object represents a date/time + that falls within the current year, in the context + of this object's timezone representation. + """ + t = time() + return safegmtime(t + _tzoffset(self._tz, t))[0] == self._year + + def isCurrentMonth(self): + """Return true if this object represents a date/time + that falls within the current month, in the context + of this object's timezone representation. + """ + t = time() + gmt = safegmtime(t + _tzoffset(self._tz, t)) + return gmt[0] == self._year and gmt[1] == self._month + + def isCurrentDay(self): + """Return true if this object represents a date/time + that falls within the current day, in the context + of this object's timezone representation. + """ + t = time() + gmt = safegmtime(t + _tzoffset(self._tz, t)) + return (gmt[0] == self._year and gmt[1] == self._month and + gmt[2] == self._day) + + def isCurrentHour(self): + """Return true if this object represents a date/time + that falls within the current hour, in the context + of this object's timezone representation. + """ + t = time() + gmt = safegmtime(t + _tzoffset(self._tz, t)) + return (gmt[0] == self._year and gmt[1] == self._month and + gmt[2] == self._day and gmt[3] == self._hour) + + def isCurrentMinute(self): + """Return true if this object represents a date/time + that falls within the current minute, in the context + of this object's timezone representation. + """ + t = time() + gmt = safegmtime(t + _tzoffset(self._tz, t)) + return (gmt[0] == self._year and gmt[1] == self._month and + gmt[2] == self._day and gmt[3] == self._hour and + gmt[4] == self._minute) + + def earliestTime(self): + """Return a new DateTime object that represents the earliest + possible time (in whole seconds) that still falls within + the current object's day, in the object's timezone context. + """ + return self.__class__( + self._year, self._month, self._day, 0, 0, 0, self._tz) + + def latestTime(self): + """Return a new DateTime object that represents the latest + possible time (in whole seconds) that still falls within + the current object's day, in the object's timezone context. + """ + return self.__class__( + self._year, self._month, self._day, 23, 59, 59, self._tz) + + def greaterThan(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time greater + than the specified DateTime or time module style time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + if t is None: + return True + if isinstance(t, (float, int)): + return self._micros > long(t * 1000000) + try: + return self._micros > t._micros + except AttributeError: + return self._micros > t + + __gt__ = greaterThan + + def greaterThanEqualTo(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time greater + than or equal to the specified DateTime or time module style + time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + if t is None: + return True + if isinstance(t, (float, int)): + return self._micros >= long(t * 1000000) + try: + return self._micros >= t._micros + except AttributeError: + return self._micros >= t + + __ge__ = greaterThanEqualTo + + def equalTo(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time equal to + the specified DateTime or time module style time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + if t is None: + return False + if isinstance(t, (float, int)): + return self._micros == long(t * 1000000) + try: + return self._micros == t._micros + except AttributeError: + return self._micros == t + + def notEqualTo(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time not equal + to the specified DateTime or time module style time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + return not self.equalTo(t) + + def __eq__(self, t): + """Compare this DateTime object to another DateTime object. + Return True if their internal state is the same. Two objects + representing the same time in different timezones are regared as + unequal. Use the equalTo method if you are only interested in them + referring to the same moment in time. + """ + if not isinstance(t, DateTime): + return False + return (self._micros, self._tz) == (t._micros, t._tz) + + def __ne__(self, t): + return not self.__eq__(t) + + def lessThan(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time less than + the specified DateTime or time module style time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + if t is None: + return False + if isinstance(t, (float, int)): + return self._micros < long(t * 1000000) + try: + return self._micros < t._micros + except AttributeError: + return self._micros < t + + __lt__ = lessThan + + def lessThanEqualTo(self, t): + """Compare this DateTime object to another DateTime object + OR a floating point number such as that which is returned + by the Python time module. + + Returns true if the object represents a date/time less than + or equal to the specified DateTime or time module style time. + + Revised to give more correct results through comparison of + long integer microseconds. + """ + if t is None: + return False + if isinstance(t, (float, int)): + return self._micros <= long(t * 1000000) + try: + return self._micros <= t._micros + except AttributeError: + return self._micros <= t + + __le__ = lessThanEqualTo + + def isLeapYear(self): + """Return true if the current year (in the context of the + object's timezone) is a leap year. + """ + return (self._year % 4 == 0 and + (self._year % 100 != 0 or self._year % 400 == 0)) + + def dayOfYear(self): + """Return the day of the year, in context of the timezone + representation of the object. + """ + d = int(self._d + (_tzoffset(self._tz, self._t) / 86400.0)) + return int((d + jd1901) - _julianday(self._year, 1, 0)) + + # Component access + def parts(self): + """Return a tuple containing the calendar year, month, + day, hour, minute second and timezone of the object. + """ + return (self._year, self._month, self._day, self._hour, + self._minute, self._second, self._tz) + + def timezone(self): + """Return the timezone in which the object is represented.""" + return self._tz + + def tzoffset(self): + """Return the timezone offset for the objects timezone.""" + return _tzoffset(self._tz, self._t) + + def year(self): + """Return the calendar year of the object.""" + return self._year + + def month(self): + """Return the month of the object as an integer.""" + return self._month + + @property + def _fmon(self): + return _MONTHS[self._month] + + def Month(self): + """Return the full month name.""" + return self._fmon + + @property + def _amon(self): + return _MONTHS_A[self._month] + + def aMonth(self): + """Return the abbreviated month name.""" + return self._amon + + def Mon(self): + """Compatibility: see aMonth.""" + return self._amon + + @property + def _pmon(self): + return _MONTHS_P[self._month] + + def pMonth(self): + """Return the abbreviated (with period) month name.""" + return self._pmon + + def Mon_(self): + """Compatibility: see pMonth.""" + return self._pmon + + def day(self): + """Return the integer day.""" + return self._day + + @property + def _fday(self): + return _DAYS[self._dayoffset] + + def Day(self): + """Return the full name of the day of the week.""" + return self._fday + + def DayOfWeek(self): + """Compatibility: see Day.""" + return self._fday + + @property + def _aday(self): + return _DAYS_A[self._dayoffset] + + def aDay(self): + """Return the abbreviated name of the day of the week.""" + return self._aday + + @property + def _pday(self): + return _DAYS_P[self._dayoffset] + + def pDay(self): + """Return the abbreviated (with period) name of the day of the week.""" + return self._pday + + def Day_(self): + """Compatibility: see pDay.""" + return self._pday + + def dow(self): + """Return the integer day of the week, where Sunday is 0.""" + return self._dayoffset + + def dow_1(self): + """Return the integer day of the week, where Sunday is 1.""" + return self._dayoffset + 1 + + @property + def _pmhour(self): + hr = self._hour + if hr > 12: + return hr - 12 + return hr or 12 + + def h_12(self): + """Return the 12-hour clock representation of the hour.""" + return self._pmhour + + def h_24(self): + """Return the 24-hour clock representation of the hour.""" + return self._hour + + @property + def _pm(self): + hr = self._hour + if hr >= 12: + return 'pm' + return 'am' + + def ampm(self): + """Return the appropriate time modifier (am or pm).""" + return self._pm + + def hour(self): + """Return the 24-hour clock representation of the hour.""" + return self._hour + + def minute(self): + """Return the minute.""" + return self._minute + + def second(self): + """Return the second.""" + return self._second + + def millis(self): + """Return the millisecond since the epoch in GMT.""" + return self._micros // 1000 + + def micros(self): + """Return the microsecond since the epoch in GMT.""" + return self._micros + + def timezoneNaive(self): + """The Python datetime module introduces the idea of distinguishing + between timezone aware and timezone naive datetime values. For lossless + conversion to and from datetime.datetime we record this + information using True / False. DateTime makes no distinction, if we + don't have any information we return None here. + """ + try: + return self._timezone_naive + except AttributeError: + return None + + def strftime(self, format): + """Format the date/time using the *current timezone representation*.""" + x = _calcDependentSecond2(self._year, self._month, self._day, + self._hour, self._minute, self._second) + ltz = self._calcTimezoneName(x, 0) + tzdiff = _tzoffset(ltz, self._t) - _tzoffset(self._tz, self._t) + zself = self + tzdiff / 86400.0 + microseconds = int((zself._second - zself._nearsec) * 1000000) + unicode_format = False + if isinstance(format, explicit_unicode_type): + format = format.encode('utf-8') + unicode_format = True + ds = datetime(zself._year, zself._month, zself._day, zself._hour, + zself._minute, int(zself._nearsec), + microseconds).strftime(format) + if unicode_format: + return ds.decode('utf-8') + return ds + + # General formats from previous DateTime + def Date(self): + """Return the date string for the object.""" + return "%s/%2.2d/%2.2d" % (self._year, self._month, self._day) + + def Time(self): + """Return the time string for an object to the nearest second.""" + return '%2.2d:%2.2d:%2.2d' % (self._hour, self._minute, self._nearsec) + + def TimeMinutes(self): + """Return the time string for an object not showing seconds.""" + return '%2.2d:%2.2d' % (self._hour, self._minute) + + def AMPM(self): + """Return the time string for an object to the nearest second.""" + return '%2.2d:%2.2d:%2.2d %s' % ( + self._pmhour, self._minute, self._nearsec, self._pm) + + def AMPMMinutes(self): + """Return the time string for an object not showing seconds.""" + return '%2.2d:%2.2d %s' % (self._pmhour, self._minute, self._pm) + + def PreciseTime(self): + """Return the time string for the object.""" + return '%2.2d:%2.2d:%06.3f' % (self._hour, self._minute, self._second) + + def PreciseAMPM(self): + """Return the time string for the object.""" + return '%2.2d:%2.2d:%06.3f %s' % ( + self._pmhour, self._minute, self._second, self._pm) + + def yy(self): + """Return calendar year as a 2 digit string.""" + return str(self._year)[-2:] + + def mm(self): + """Return month as a 2 digit string.""" + return '%02d' % self._month + + def dd(self): + """Return day as a 2 digit string.""" + return '%02d' % self._day + + def rfc822(self): + """Return the date in RFC 822 format.""" + tzoffset = _tzoffset2rfc822zone(_tzoffset(self._tz, self._t)) + return '%s, %2.2d %s %d %2.2d:%2.2d:%2.2d %s' % ( + self._aday, self._day, self._amon, self._year, + self._hour, self._minute, self._nearsec, tzoffset) + + # New formats + def fCommon(self): + """Return a string representing the object's value + in the format: March 1, 1997 1:45 pm. + """ + return '%s %s, %4.4d %s:%2.2d %s' % ( + self._fmon, self._day, self._year, self._pmhour, + self._minute, self._pm) + + def fCommonZ(self): + """Return a string representing the object's value + in the format: March 1, 1997 1:45 pm US/Eastern. + """ + return '%s %s, %4.4d %d:%2.2d %s %s' % ( + self._fmon, self._day, self._year, self._pmhour, + self._minute, self._pm, self._tz) + + def aCommon(self): + """Return a string representing the object's value + in the format: Mar 1, 1997 1:45 pm. + """ + return '%s %s, %4.4d %s:%2.2d %s' % ( + self._amon, self._day, self._year, self._pmhour, + self._minute, self._pm) + + def aCommonZ(self): + """Return a string representing the object's value + in the format: Mar 1, 1997 1:45 pm US/Eastern. + """ + return '%s %s, %4.4d %d:%2.2d %s %s' % ( + self._amon, self._day, self._year, self._pmhour, + self._minute, self._pm, self._tz) + + def pCommon(self): + """Return a string representing the object's value + in the format: Mar. 1, 1997 1:45 pm. + """ + return '%s %s, %4.4d %s:%2.2d %s' % ( + self._pmon, self._day, self._year, self._pmhour, + self._minute, self._pm) + + def pCommonZ(self): + """Return a string representing the object's value + in the format: Mar. 1, 1997 1:45 pm US/Eastern. + """ + return '%s %s, %4.4d %d:%2.2d %s %s' % ( + self._pmon, self._day, self._year, self._pmhour, + self._minute, self._pm, self._tz) + + def ISO(self): + """Return the object in ISO standard format. + + Note: this is *not* ISO 8601-format! See the ISO8601 and + HTML4 methods below for ISO 8601-compliant output. + + Dates are output as: YYYY-MM-DD HH:MM:SS + """ + return "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" % ( + self._year, self._month, self._day, + self._hour, self._minute, self._second) + + def ISO8601(self): + """Return the object in ISO 8601-compatible format containing the + date, time with seconds-precision and the time zone identifier. + + See: http://www.w3.org/TR/NOTE-datetime + + Dates are output as: YYYY-MM-DDTHH:MM:SSTZD + T is a literal character. + TZD is Time Zone Designator, format +HH:MM or -HH:MM + + If the instance is timezone naive (it was not specified with a timezone + when it was constructed) then the timezone is omitted. + + The HTML4 method below offers the same formatting, but converts + to UTC before returning the value and sets the TZD "Z". + """ + if self.timezoneNaive(): + return "%0.4d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2d" % ( + self._year, self._month, self._day, + self._hour, self._minute, self._second) + tzoffset = _tzoffset2iso8601zone(_tzoffset(self._tz, self._t)) + return "%0.4d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2d%s" % ( + self._year, self._month, self._day, + self._hour, self._minute, self._second, tzoffset) + + def HTML4(self): + """Return the object in the format used in the HTML4.0 specification, + one of the standard forms in ISO8601. + + See: http://www.w3.org/TR/NOTE-datetime + + Dates are output as: YYYY-MM-DDTHH:MM:SSZ + T, Z are literal characters. + The time is in UTC. + """ + newdate = self.toZone('UTC') + return "%0.4d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2dZ" % ( + newdate._year, newdate._month, newdate._day, + newdate._hour, newdate._minute, newdate._second) + + def asdatetime(self): + """Return a standard library datetime.datetime + """ + tznaive = self.timezoneNaive() + if tznaive: + tzinfo = None + else: + tzinfo = _TZINFO[self._tz].tzinfo + second = int(self._second) + microsec = self.micros() % 1000000 + dt = datetime(self._year, self._month, self._day, self._hour, + self._minute, second, microsec, tzinfo) + return dt + + def utcdatetime(self): + """Convert the time to UTC and return a timezone naive datetime object + """ + utc = self.toZone('UTC') + second = int(utc._second) + microsec = utc.micros() % 1000000 + dt = datetime(utc._year, utc._month, utc._day, utc._hour, + utc._minute, second, microsec) + return dt + + def __add__(self, other): + """A DateTime may be added to a number and a number may be + added to a DateTime; two DateTimes cannot be added. + """ + if hasattr(other, '_t'): + raise DateTimeError('Cannot add two DateTimes') + o = float(other) + tz = self._tz + omicros = round(o * 86400000000) + tmicros = self.micros() + omicros + t = tmicros / 1000000.0 + d = (tmicros + long(EPOCH * 1000000)) / 86400000000.0 + s = d - math.floor(d) + ms = t - math.floor(t) + x = _calcDependentSecond(tz, t) + yr, mo, dy, hr, mn, sc = _calcYMDHMS(x, ms) + return self.__class__(yr, mo, dy, hr, mn, sc, self._tz, + t, d, s, tmicros, self.timezoneNaive()) + + __radd__ = __add__ + + def __sub__(self, other): + """Either a DateTime or a number may be subtracted from a + DateTime, however, a DateTime may not be subtracted from + a number. + """ + if hasattr(other, '_d'): + return (self.micros() - other.micros()) / 86400000000.0 + else: + return self.__add__(-(other)) + + def __repr__(self): + """Convert a DateTime to a string that looks like a Python + expression. + """ + return '{}(\'{}\')'.format(self.__class__.__name__, str(self)) + + def __str__(self): + """Convert a DateTime to a string.""" + y, m, d = self._year, self._month, self._day + h, mn, s, t = self._hour, self._minute, self._second, self._tz + if s == int(s): + # A whole number of seconds -- suppress milliseconds. + return '%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d %s' % ( + y, m, d, h, mn, s, t) + else: + # s is already rounded to the nearest microsecond, and + # it's not a whole number of seconds. Be sure to print + # 2 digits before the decimal point. + return '%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%06.6f %s' % ( + y, m, d, h, mn, s, t) + + def __format__(self, fmt): + """Render a DateTime in an f-string.""" + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) + if len(fmt) != 0: + return self.strftime(fmt) + return str(self) + + def __hash__(self): + """Compute a hash value for a DateTime.""" + return int(((self._year % 100 * 12 + self._month) * 31 + + self._day + self.time) * 100) + + def __int__(self): + """Convert to an integer number of seconds since the epoch (gmt).""" + return int(self.micros() // 1000000) + + def __long__(self): + """Convert to a long-int number of seconds since the epoch (gmt).""" + return long(self.micros() // 1000000) # pragma: PY2 + + def __float__(self): + """Convert to floating-point number of seconds since the epoch (gmt). + """ + return self.micros() / 1000000.0 + + @property + def _t(self): + return self._micros / 1000000.0 + + def _parse_iso8601(self, s): + # preserve the previously implied contract + # who knows where this could be used... + return self._parse_iso8601_preserving_tznaive(s)[:7] + + def _parse_iso8601_preserving_tznaive(self, s): + try: + return self.__parse_iso8601(s) + except IndexError: + raise SyntaxError( + 'Not an ISO 8601 compliant date string: "%s"' % s) + + def __parse_iso8601(self, s): + """Parse an ISO 8601 compliant date. + + See: http://en.wikipedia.org/wiki/ISO_8601 + """ + month = day = week_day = 1 + year = hour = minute = seconds = hour_off = min_off = 0 + tznaive = True + + iso8601 = iso8601Match(s.strip()) + fields = iso8601 and iso8601.groupdict() or {} + if not iso8601 or fields.get('garbage'): + raise IndexError + + if fields['year']: + year = int(fields['year']) + if fields['month']: + month = int(fields['month']) + if fields['day']: + day = int(fields['day']) + + if fields['year_day']: + d = DateTime('%s-01-01' % year) + int(fields['year_day']) - 1 + month = d.month() + day = d.day() + + if fields['week']: + week = int(fields['week']) + if fields['week_day']: + week_day = int(fields['week_day']) + d = DateTime('%s-01-04' % year) + d = d - (d.dow() + 6) % 7 + week * 7 + week_day - 8 + month = d.month() + day = d.day() + + if fields['hour']: + hour = int(fields['hour']) + + if fields['minute']: + minute = int(fields['minute']) + elif fields['fraction']: + minute = 60.0 * float('0.%s' % fields['fraction']) + seconds, minute = math.modf(minute) + minute = int(minute) + seconds = 60.0 * seconds + # Avoid reprocess when handling seconds, bellow + fields['fraction'] = None + + if fields['second']: + seconds = int(fields['second']) + if fields['fraction']: + seconds = seconds + float('0.%s' % fields['fraction']) + elif fields['fraction']: + seconds = 60.0 * float('0.%s' % fields['fraction']) + + if fields['hour_off']: + hour_off = int(fields['hour_off']) + if fields['signal'] == '-': + hour_off *= -1 + + if fields['min_off']: + min_off = int(fields['min_off']) + + if fields['signal'] or fields['Z']: + tznaive = False + else: + tznaive = True + + # Differ from the specification here. To preserve backwards + # compatibility assume a default timezone == UTC. + tz = 'GMT%+03d%02d' % (hour_off, min_off) + + return year, month, day, hour, minute, seconds, tz, tznaive + + def JulianDay(self): + """Return the Julian day. + + See: https://www.tondering.dk/claus/cal/julperiod.php#formula + """ + a = (14 - self._month) // 12 + y = self._year + 4800 - a + m = self._month + (12 * a) - 3 + return (self._day + (153 * m + 2) // 5 + 365 * y + + y // 4 - y // 100 + y // 400 - 32045) + + def week(self): + """Return the week number according to ISO. + + See: https://www.tondering.dk/claus/cal/week.php#weekno + """ + J = self.JulianDay() + d4 = (J + 31741 - (J % 7)) % 146097 % 36524 % 1461 + L = d4 // 1460 + d1 = ((d4 - L) % 365) + L + return d1 // 7 + 1 + + def encode(self, out): + """Encode value for XML-RPC.""" + out.write('') + out.write(self.ISO8601()) + out.write('\n') + + +# Provide the _dt_reconstructor function here, in case something +# accidentally creates a reference to this function + +orig_reconstructor = copy_reg._reconstructor + + +def _dt_reconstructor(cls, base, state): + if cls is DateTime: + return cls(state) + return orig_reconstructor(cls, base, state) diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.txt b/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.txt new file mode 100644 index 00000000..aaa9f8f9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.txt @@ -0,0 +1,785 @@ +The DateTime package +==================== + +Encapsulation of date/time values. + + +Function Timezones() +-------------------- + +Returns the list of recognized timezone names: + + >>> from DateTime import Timezones + >>> zones = set(Timezones()) + +Almost all of the standard pytz timezones are included, with the exception +of some commonly-used but ambiguous abbreviations, where historical Zope +usage conflicts with the name used by pytz: + + >>> import pytz + >>> [x for x in pytz.all_timezones if x not in zones] + ['CET', 'EET', 'EST', 'MET', 'MST', 'WET'] + +Class DateTime +-------------- + +DateTime objects represent instants in time and provide interfaces for +controlling its representation without affecting the absolute value of +the object. + +DateTime objects may be created from a wide variety of string or +numeric data, or may be computed from other DateTime objects. +DateTimes support the ability to convert their representations to many +major timezones, as well as the ability to create a DateTime object +in the context of a given timezone. + +DateTime objects provide partial numerical behavior: + +* Two date-time objects can be subtracted to obtain a time, in days + between the two. + +* A date-time object and a positive or negative number may be added to + obtain a new date-time object that is the given number of days later + than the input date-time object. + +* A positive or negative number and a date-time object may be added to + obtain a new date-time object that is the given number of days later + than the input date-time object. + +* A positive or negative number may be subtracted from a date-time + object to obtain a new date-time object that is the given number of + days earlier than the input date-time object. + +DateTime objects may be converted to integer, long, or float numbers +of days since January 1, 1901, using the standard int, long, and float +functions (Compatibility Note: int, long and float return the number +of days since 1901 in GMT rather than local machine timezone). +DateTime objects also provide access to their value in a float format +usable with the Python time module, provided that the value of the +object falls in the range of the epoch-based time module. + +A DateTime object should be considered immutable; all conversion and numeric +operations return a new DateTime object rather than modify the current object. + +A DateTime object always maintains its value as an absolute UTC time, +and is represented in the context of some timezone based on the +arguments used to create the object. A DateTime object's methods +return values based on the timezone context. + +Note that in all cases the local machine timezone is used for +representation if no timezone is specified. + +Constructor for DateTime +------------------------ + +DateTime() returns a new date-time object. DateTimes may be created +with from zero to seven arguments: + +* If the function is called with no arguments, then the current date/ + time is returned, represented in the timezone of the local machine. + +* If the function is invoked with a single string argument which is a + recognized timezone name, an object representing the current time is + returned, represented in the specified timezone. + +* If the function is invoked with a single string argument + representing a valid date/time, an object representing that date/ + time will be returned. + + As a general rule, any date-time representation that is recognized + and unambiguous to a resident of North America is acceptable. (The + reason for this qualification is that in North America, a date like: + 2/1/1994 is interpreted as February 1, 1994, while in some parts of + the world, it is interpreted as January 2, 1994.) A date/ time + string consists of two components, a date component and an optional + time component, separated by one or more spaces. If the time + component is omitted, 12:00am is assumed. + + Any recognized timezone name specified as the final element of the + date/time string will be used for computing the date/time value. + (If you create a DateTime with the string, + "Mar 9, 1997 1:45pm US/Pacific", the value will essentially be the + same as if you had captured time.time() at the specified date and + time on a machine in that timezone). If no timezone is passed, then + the timezone configured on the local machine will be used, **except** + that if the date format matches ISO 8601 ('YYYY-MM-DD'), the instance + will use UTC / GMT+0 as the timezone. + + o Returns current date/time, represented in US/Eastern: + + >>> from DateTime import DateTime + >>> e = DateTime('US/Eastern') + >>> e.timezone() + 'US/Eastern' + + o Returns specified time, represented in local machine zone: + + >>> x = DateTime('1997/3/9 1:45pm') + >>> x.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ...) + + o Specified time in local machine zone, verbose format: + + >>> y = DateTime('Mar 9, 1997 13:45:00') + >>> y.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ...) + >>> y == x + True + + o Specified time in UTC via ISO 8601 rule: + + >>> z = DateTime('2014-03-24') + >>> z.parts() # doctest: +ELLIPSIS + (2014, 3, 24, 0, 0, ...) + >>> z.timezone() + 'GMT+0' + + The date component consists of year, month, and day values. The + year value must be a one-, two-, or four-digit integer. If a one- + or two-digit year is used, the year is assumed to be in the + twentieth century. The month may an integer, from 1 to 12, a month + name, or a month abbreviation, where a period may optionally follow + the abbreviation. The day must be an integer from 1 to the number of + days in the month. The year, month, and day values may be separated + by periods, hyphens, forward slashes, or spaces. Extra spaces are + permitted around the delimiters. Year, month, and day values may be + given in any order as long as it is possible to distinguish the + components. If all three components are numbers that are less than + 13, then a month-day-year ordering is assumed. + + The time component consists of hour, minute, and second values + separated by colons. The hour value must be an integer between 0 + and 23 inclusively. The minute value must be an integer between 0 + and 59 inclusively. The second value may be an integer value + between 0 and 59.999 inclusively. The second value or both the + minute and second values may be omitted. The time may be followed + by am or pm in upper or lower case, in which case a 12-hour clock is + assumed. + +* If the DateTime function is invoked with a single numeric argument, + the number is assumed to be either a floating point value such as + that returned by time.time(), or a number of days after January 1, + 1901 00:00:00 UTC. + + A DateTime object is returned that represents either the GMT value + of the time.time() float represented in the local machine's + timezone, or that number of days after January 1, 1901. Note that + the number of days after 1901 need to be expressed from the + viewpoint of the local machine's timezone. A negative argument will + yield a date-time value before 1901. + +* If the function is invoked with two numeric arguments, then the + first is taken to be an integer year and the second argument is + taken to be an offset in days from the beginning of the year, in the + context of the local machine timezone. The date-time value returned + is the given offset number of days from the beginning of the given + year, represented in the timezone of the local machine. The offset + may be positive or negative. Two-digit years are assumed to be in + the twentieth century. + +* If the function is invoked with two arguments, the first a float + representing a number of seconds past the epoch in GMT (such as + those returned by time.time()) and the second a string naming a + recognized timezone, a DateTime with a value of that GMT time will + be returned, represented in the given timezone. + + >>> import time + >>> t = time.time() + + Time t represented as US/Eastern: + + >>> now_east = DateTime(t, 'US/Eastern') + + Time t represented as US/Pacific: + + >>> now_west = DateTime(t, 'US/Pacific') + + Only their representations are different: + + >>> now_east.equalTo(now_west) + True + +* If the function is invoked with three or more numeric arguments, + then the first is taken to be an integer year, the second is taken + to be an integer month, and the third is taken to be an integer day. + If the combination of values is not valid, then a DateTimeError is + raised. One- or two-digit years up to 69 are assumed to be in the + 21st century, whereas values 70-99 are assumed to be 20th century. + The fourth, fifth, and sixth arguments are floating point, positive + or negative offsets in units of hours, minutes, and days, and + default to zero if not given. An optional string may be given as + the final argument to indicate timezone (the effect of this is as if + you had taken the value of time.time() at that time on a machine in + the specified timezone). + +If a string argument passed to the DateTime constructor cannot be +parsed, it will raise SyntaxError. Invalid date, time, or +timezone components will raise a DateTimeError. + +The module function Timezones() will return a list of the timezones +recognized by the DateTime module. Recognition of timezone names is +case-insensitive. + +Instance Methods for DateTime (IDateTime interface) +--------------------------------------------------- + +Conversion and comparison methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``timeTime()`` returns the date/time as a floating-point number in + UTC, in the format used by the Python time module. Note that it is + possible to create date /time values with DateTime that have no + meaningful value to the time module, and in such cases a + DateTimeError is raised. A DateTime object's value must generally + be between Jan 1, 1970 (or your local machine epoch) and Jan 2038 to + produce a valid time.time() style value. + + >>> dt = DateTime('Mar 9, 1997 13:45:00 US/Eastern') + >>> dt.timeTime() + 857933100.0 + + >>> DateTime('2040/01/01 UTC').timeTime() + 2208988800.0 + + >>> DateTime('1900/01/01 UTC').timeTime() + -2208988800.0 + +* ``toZone(z)`` returns a DateTime with the value as the current + object, represented in the indicated timezone: + + >>> dt.toZone('UTC') + DateTime('1997/03/09 18:45:00 UTC') + + >>> dt.toZone('UTC').equalTo(dt) + True + +* ``isFuture()`` returns true if this object represents a date/time + later than the time of the call: + + >>> dt.isFuture() + False + >>> DateTime('Jan 1 3000').isFuture() # not time-machine safe! + True + +* ``isPast()`` returns true if this object represents a date/time + earlier than the time of the call: + + >>> dt.isPast() + True + >>> DateTime('Jan 1 3000').isPast() # not time-machine safe! + False + +* ``isCurrentYear()`` returns true if this object represents a + date/time that falls within the current year, in the context of this + object's timezone representation: + + >>> dt.isCurrentYear() + False + >>> DateTime().isCurrentYear() + True + +* ``isCurrentMonth()`` returns true if this object represents a + date/time that falls within the current month, in the context of + this object's timezone representation: + + >>> dt.isCurrentMonth() + False + >>> DateTime().isCurrentMonth() + True + +* ``isCurrentDay()`` returns true if this object represents a + date/time that falls within the current day, in the context of this + object's timezone representation: + + >>> dt.isCurrentDay() + False + >>> DateTime().isCurrentDay() + True + +* ``isCurrentHour()`` returns true if this object represents a + date/time that falls within the current hour, in the context of this + object's timezone representation: + + >>> dt.isCurrentHour() + False + + >>> DateTime().isCurrentHour() + True + +* ``isCurrentMinute()`` returns true if this object represents a + date/time that falls within the current minute, in the context of + this object's timezone representation: + + >>> dt.isCurrentMinute() + False + >>> DateTime().isCurrentMinute() + True + +* ``isLeapYear()`` returns true if the current year (in the context of + the object's timezone) is a leap year: + + >>> dt.isLeapYear() + False + >>> DateTime('Mar 8 2004').isLeapYear() + True + +* ``earliestTime()`` returns a new DateTime object that represents the + earliest possible time (in whole seconds) that still falls within + the current object's day, in the object's timezone context: + + >>> dt.earliestTime() + DateTime('1997/03/09 00:00:00 US/Eastern') + +* ``latestTime()`` return a new DateTime object that represents the + latest possible time (in whole seconds) that still falls within the + current object's day, in the object's timezone context + + >>> dt.latestTime() + DateTime('1997/03/09 23:59:59 US/Eastern') + +Component access +~~~~~~~~~~~~~~~~ + +* ``parts()`` returns a tuple containing the calendar year, month, + day, hour, minute second and timezone of the object + + >>> dt.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ... 'US/Eastern') + +* ``timezone()`` returns the timezone in which the object is represented: + + >>> dt.timezone() in Timezones() + True + +* ``tzoffset()`` returns the timezone offset for the objects timezone: + + >>> dt.tzoffset() + -18000 + +* ``year()`` returns the calendar year of the object: + + >>> dt.year() + 1997 + +* ``month()`` returns the month of the object as an integer: + + >>> dt.month() + 3 + +* ``Month()`` returns the full month name: + + >>> dt.Month() + 'March' + +* ``aMonth()`` returns the abbreviated month name: + + >>> dt.aMonth() + 'Mar' + +* ``pMonth()`` returns the abbreviated (with period) month name: + + >>> dt.pMonth() + 'Mar.' + +* ``day()`` returns the integer day: + + >>> dt.day() + 9 + +* ``Day()`` returns the full name of the day of the week: + + >>> dt.Day() + 'Sunday' + +* ``dayOfYear()`` returns the day of the year, in context of the + timezone representation of the object: + + >>> dt.dayOfYear() + 68 + +* ``aDay()`` returns the abbreviated name of the day of the week: + + >>> dt.aDay() + 'Sun' + +* ``pDay()`` returns the abbreviated (with period) name of the day of + the week: + + >>> dt.pDay() + 'Sun.' + +* ``dow()`` returns the integer day of the week, where Sunday is 0: + + >>> dt.dow() + 0 + +* ``dow_1()`` returns the integer day of the week, where sunday is 1: + + >>> dt.dow_1() + 1 + +* ``h_12()`` returns the 12-hour clock representation of the hour: + + >>> dt.h_12() + 1 + +* ``h_24()`` returns the 24-hour clock representation of the hour: + + >>> dt.h_24() + 13 + +* ``ampm()`` returns the appropriate time modifier (am or pm): + + >>> dt.ampm() + 'pm' + +* ``hour()`` returns the 24-hour clock representation of the hour: + + >>> dt.hour() + 13 + +* ``minute()`` returns the minute: + + >>> dt.minute() + 45 + +* ``second()`` returns the second: + + >>> dt.second() == 0 + True + +* ``millis()`` returns the milliseconds since the epoch in GMT. + + >>> dt.millis() == 857933100000 + True + +strftime() +~~~~~~~~~~ + +See ``tests/test_datetime.py``. + +General formats from previous DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``Date()`` return the date string for the object: + + >>> dt.Date() + '1997/03/09' + +* ``Time()`` returns the time string for an object to the nearest + second: + + >>> dt.Time() + '13:45:00' + +* ``TimeMinutes()`` returns the time string for an object not showing + seconds: + + >>> dt.TimeMinutes() + '13:45' + +* ``AMPM()`` returns the time string for an object to the nearest second: + + >>> dt.AMPM() + '01:45:00 pm' + +* ``AMPMMinutes()`` returns the time string for an object not showing + seconds: + + >>> dt.AMPMMinutes() + '01:45 pm' + +* ``PreciseTime()`` returns the time string for the object: + + >>> dt.PreciseTime() + '13:45:00.000' + +* ``PreciseAMPM()`` returns the time string for the object: + + >>> dt.PreciseAMPM() + '01:45:00.000 pm' + +* ``yy()`` returns the calendar year as a 2 digit string + + >>> dt.yy() + '97' + +* ``mm()`` returns the month as a 2 digit string + + >>> dt.mm() + '03' + +* ``dd()`` returns the day as a 2 digit string: + + >>> dt.dd() + '09' + +* ``rfc822()`` returns the date in RFC 822 format: + + >>> dt.rfc822() + 'Sun, 09 Mar 1997 13:45:00 -0500' + +New formats +~~~~~~~~~~~ + +* ``fCommon()`` returns a string representing the object's value in + the format: March 9, 1997 1:45 pm: + + >>> dt.fCommon() + 'March 9, 1997 1:45 pm' + +* ``fCommonZ()`` returns a string representing the object's value in + the format: March 9, 1997 1:45 pm US/Eastern: + + >>> dt.fCommonZ() + 'March 9, 1997 1:45 pm US/Eastern' + +* ``aCommon()`` returns a string representing the object's value in + the format: Mar 9, 1997 1:45 pm: + + >>> dt.aCommon() + 'Mar 9, 1997 1:45 pm' + +* ``aCommonZ()`` return a string representing the object's value in + the format: Mar 9, 1997 1:45 pm US/Eastern: + + >>> dt.aCommonZ() + 'Mar 9, 1997 1:45 pm US/Eastern' + +* ``pCommon()`` returns a string representing the object's value in + the format Mar. 9, 1997 1:45 pm: + + >>> dt.pCommon() + 'Mar. 9, 1997 1:45 pm' + +* ``pCommonZ()`` returns a string representing the object's value in + the format: Mar. 9, 1997 1:45 pm US/Eastern: + + >>> dt.pCommonZ() + 'Mar. 9, 1997 1:45 pm US/Eastern' + +* ``ISO()`` returns a string with the date/time in ISO format. Note: + this is not ISO 8601-format! See the ISO8601 and HTML4 methods below + for ISO 8601-compliant output. Dates are output as: YYYY-MM-DD HH:MM:SS + + >>> dt.ISO() + '1997-03-09 13:45:00' + +* ``ISO8601()`` returns the object in ISO 8601-compatible format + containing the date, time with seconds-precision and the time zone + identifier - see http://www.w3.org/TR/NOTE-datetime. Dates are + output as: YYYY-MM-DDTHH:MM:SSTZD (T is a literal character, TZD is + Time Zone Designator, format +HH:MM or -HH:MM). + + The ``HTML4()`` method below offers the same formatting, but + converts to UTC before returning the value and sets the TZD"Z" + + >>> dt.ISO8601() + '1997-03-09T13:45:00-05:00' + + +* ``HTML4()`` returns the object in the format used in the HTML4.0 + specification, one of the standard forms in ISO8601. See + http://www.w3.org/TR/NOTE-datetime. Dates are output as: + YYYY-MM-DDTHH:MM:SSZ (T, Z are literal characters, the time is in + UTC.): + + >>> dt.HTML4() + '1997-03-09T18:45:00Z' + +* ``JulianDay()`` returns the Julian day according to + http://www.tondering.dk/claus/cal/node3.html#sec-calcjd + + >>> dt.JulianDay() + 2450517 + +* ``week()`` returns the week number according to ISO + see http://www.tondering.dk/claus/cal/node6.html#SECTION00670000000000000000 + + >>> dt.week() + 10 + +Deprecated API +~~~~~~~~~~~~~~ + +* DayOfWeek(): see Day() + +* Day_(): see pDay() + +* Mon(): see aMonth() + +* Mon_(): see pMonth + +General Services Provided by DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DateTimes can be repr()'ed; the result will be a string indicating how +to make a DateTime object like this: + + >>> repr(dt) + "DateTime('1997/03/09 13:45:00 US/Eastern')" + +When we convert them into a string, we get a nicer string that could +actually be shown to a user: + + >>> str(dt) + '1997/03/09 13:45:00 US/Eastern' + +The hash value of a DateTime is based on the date and time and is +equal for different representations of the DateTime: + + >>> hash(dt) + 3618678 + >>> hash(dt.toZone('UTC')) + 3618678 + +DateTime objects can be compared to other DateTime objects OR floating +point numbers such as the ones which are returned by the Python time +module by using the equalTo method. Using this API, True is returned if the +object represents a date/time equal to the specified DateTime or time module +style time: + + >>> dt.equalTo(dt) + True + >>> dt.equalTo(dt.toZone('UTC')) + True + >>> dt.equalTo(dt.timeTime()) + True + >>> dt.equalTo(DateTime()) + False + +Same goes for inequalities: + + >>> dt.notEqualTo(dt) + False + >>> dt.notEqualTo(dt.toZone('UTC')) + False + >>> dt.notEqualTo(dt.timeTime()) + False + >>> dt.notEqualTo(DateTime()) + True + +Normal equality operations only work with DateTime objects and take the +timezone setting into account: + + >>> dt == dt + True + >>> dt == dt.toZone('UTC') + False + >>> dt == DateTime() + False + + >>> dt != dt + False + >>> dt != dt.toZone('UTC') + True + >>> dt != DateTime() + True + +But the other comparison operations compare the referenced moment in time and +not the representation itself: + + >>> dt > dt + False + >>> DateTime() > dt + True + >>> dt > DateTime().timeTime() + False + >>> DateTime().timeTime() > dt + True + + >>> dt.greaterThan(dt) + False + >>> DateTime().greaterThan(dt) + True + >>> dt.greaterThan(DateTime().timeTime()) + False + + >>> dt >= dt + True + >>> DateTime() >= dt + True + >>> dt >= DateTime().timeTime() + False + >>> DateTime().timeTime() >= dt + True + + >>> dt.greaterThanEqualTo(dt) + True + >>> DateTime().greaterThanEqualTo(dt) + True + >>> dt.greaterThanEqualTo(DateTime().timeTime()) + False + + >>> dt < dt + False + >>> DateTime() < dt + False + >>> dt < DateTime().timeTime() + True + >>> DateTime().timeTime() < dt + False + + >>> dt.lessThan(dt) + False + >>> DateTime().lessThan(dt) + False + >>> dt.lessThan(DateTime().timeTime()) + True + + >>> dt <= dt + True + >>> DateTime() <= dt + False + >>> dt <= DateTime().timeTime() + True + >>> DateTime().timeTime() <= dt + False + + >>> dt.lessThanEqualTo(dt) + True + >>> DateTime().lessThanEqualTo(dt) + False + >>> dt.lessThanEqualTo(DateTime().timeTime()) + True + +Numeric Services Provided by DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A DateTime may be added to a number and a number may be added to a +DateTime: + + >>> dt + 5 + DateTime('1997/03/14 13:45:00 US/Eastern') + >>> 5 + dt + DateTime('1997/03/14 13:45:00 US/Eastern') + +Two DateTimes cannot be added: + + >>> from DateTime.interfaces import DateTimeError + >>> try: + ... dt + dt + ... print('fail') + ... except DateTimeError: + ... print('ok') + ok + +Either a DateTime or a number may be subtracted from a DateTime, +however, a DateTime may not be subtracted from a number: + + >>> DateTime('1997/03/10 13:45 US/Eastern') - dt + 1.0 + >>> dt - 1 + DateTime('1997/03/08 13:45:00 US/Eastern') + >>> 1 - dt + Traceback (most recent call last): + ... + TypeError: unsupported operand type(s) for -: 'int' and 'DateTime' + +DateTimes can also be converted to integers (number of seconds since +the epoch) and floats: + + >>> int(dt) + 857933100 + >>> float(dt) + 857933100.0 diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/__init__.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/__init__.py new file mode 100644 index 00000000..4e2df6da --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/__init__.py @@ -0,0 +1,18 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Foundation and Contributors. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## + +from .DateTime import DateTime +from .DateTime import Timezones + + +__all__ = ('DateTime', 'Timezones') diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/interfaces.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/interfaces.py new file mode 100644 index 00000000..80e7707a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/interfaces.py @@ -0,0 +1,375 @@ +############################################################################## +# +# Copyright (c) 2005 Zope Foundation and Contributors. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## +from zope.interface import Interface + + +class DateTimeError(Exception): + pass + + +class SyntaxError(DateTimeError): + pass + + +class DateError(DateTimeError): + pass + + +class TimeError(DateTimeError): + pass + + +class IDateTime(Interface): + # Conversion and comparison methods + + def localZone(ltm=None): + """Returns the time zone on the given date. The time zone + can change according to daylight savings.""" + + def timeTime(): + """Return the date/time as a floating-point number in UTC, in + the format used by the Python time module. Note that it is + possible to create date/time values with DateTime that have no + meaningful value to the time module.""" + + def toZone(z): + """Return a DateTime with the value as the current object, + represented in the indicated timezone.""" + + def isFuture(): + """Return true if this object represents a date/time later + than the time of the call""" + + def isPast(): + """Return true if this object represents a date/time earlier + than the time of the call""" + + def isCurrentYear(): + """Return true if this object represents a date/time that + falls within the current year, in the context of this + object's timezone representation""" + + def isCurrentMonth(): + """Return true if this object represents a date/time that + falls within the current month, in the context of this + object's timezone representation""" + + def isCurrentDay(): + """Return true if this object represents a date/time that + falls within the current day, in the context of this object's + timezone representation""" + + def isCurrentHour(): + """Return true if this object represents a date/time that + falls within the current hour, in the context of this object's + timezone representation""" + + def isCurrentMinute(): + """Return true if this object represents a date/time that + falls within the current minute, in the context of this + object's timezone representation""" + + def isLeapYear(): + """Return true if the current year (in the context of the + object's timezone) is a leap year""" + + def earliestTime(): + """Return a new DateTime object that represents the earliest + possible time (in whole seconds) that still falls within the + current object's day, in the object's timezone context""" + + def latestTime(): + """Return a new DateTime object that represents the latest + possible time (in whole seconds) that still falls within the + current object's day, in the object's timezone context""" + + def greaterThan(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time greater than the specified DateTime or time module + style time. Revised to give more correct results through + comparison of long integer milliseconds.""" + + __gt__ = greaterThan + + def greaterThanEqualTo(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time greater than or equal to the specified DateTime or + time module style time. Revised to give more correct results + through comparison of long integer milliseconds.""" + + __ge__ = greaterThanEqualTo + + def equalTo(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time equal to the specified DateTime or time module style + time. Revised to give more correct results through comparison + of long integer milliseconds.""" + + __eq__ = equalTo + + def notEqualTo(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time not equal to the specified DateTime or time module + style time. Revised to give more correct results through + comparison of long integer milliseconds.""" + + __ne__ = notEqualTo + + def lessThan(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time less than the specified DateTime or time module + style time. Revised to give more correct results through + comparison of long integer milliseconds.""" + + __lt__ = lessThan + + def lessThanEqualTo(t): + """Compare this DateTime object to another DateTime object OR + a floating point number such as that which is returned by the + Python time module. Returns true if the object represents a + date/time less than or equal to the specified DateTime or time + module style time. Revised to give more correct results + through comparison of long integer milliseconds.""" + + __le__ = lessThanEqualTo + + # Component access + + def parts(): + """Return a tuple containing the calendar year, month, day, + hour, minute second and timezone of the object""" + + def timezone(): + """Return the timezone in which the object is represented.""" + + def tzoffset(): + """Return the timezone offset for the objects timezone.""" + + def year(): + """Return the calendar year of the object""" + + def month(): + """Return the month of the object as an integer""" + + def Month(): + """Return the full month name""" + + def aMonth(): + """Return the abbreviated month name.""" + + def Mon(): + """Compatibility: see aMonth""" + + def pMonth(): + """Return the abbreviated (with period) month name.""" + + def Mon_(): + """Compatibility: see pMonth""" + + def day(): + """Return the integer day""" + + def Day(): + """Return the full name of the day of the week""" + + def DayOfWeek(): + """Compatibility: see Day""" + + def dayOfYear(): + """Return the day of the year, in context of the timezone + representation of the object""" + + def aDay(): + """Return the abbreviated name of the day of the week""" + + def pDay(): + """Return the abbreviated (with period) name of the day of the + week""" + + def Day_(): + """Compatibility: see pDay""" + + def dow(): + """Return the integer day of the week, where sunday is 0""" + + def dow_1(): + """Return the integer day of the week, where sunday is 1""" + + def h_12(): + """Return the 12-hour clock representation of the hour""" + + def h_24(): + """Return the 24-hour clock representation of the hour""" + + def ampm(): + """Return the appropriate time modifier (am or pm)""" + + def hour(): + """Return the 24-hour clock representation of the hour""" + + def minute(): + """Return the minute""" + + def second(): + """Return the second""" + + def millis(): + """Return the millisecond since the epoch in GMT.""" + + def strftime(format): + """Format the date/time using the *current timezone representation*.""" + + # General formats from previous DateTime + + def Date(): + """Return the date string for the object.""" + + def Time(): + """Return the time string for an object to the nearest second.""" + + def TimeMinutes(): + """Return the time string for an object not showing seconds.""" + + def AMPM(): + """Return the time string for an object to the nearest second.""" + + def AMPMMinutes(): + """Return the time string for an object not showing seconds.""" + + def PreciseTime(): + """Return the time string for the object.""" + + def PreciseAMPM(): + """Return the time string for the object.""" + + def yy(): + """Return calendar year as a 2 digit string""" + + def mm(): + """Return month as a 2 digit string""" + + def dd(): + """Return day as a 2 digit string""" + + def rfc822(): + """Return the date in RFC 822 format""" + + # New formats + + def fCommon(): + """Return a string representing the object's value in the + format: March 1, 1997 1:45 pm""" + + def fCommonZ(): + """Return a string representing the object's value in the + format: March 1, 1997 1:45 pm US/Eastern""" + + def aCommon(): + """Return a string representing the object's value in the + format: Mar 1, 1997 1:45 pm""" + + def aCommonZ(): + """Return a string representing the object's value in the + format: Mar 1, 1997 1:45 pm US/Eastern""" + + def pCommon(): + """Return a string representing the object's value in the + format: Mar. 1, 1997 1:45 pm""" + + def pCommonZ(): + """Return a string representing the object's value + in the format: Mar. 1, 1997 1:45 pm US/Eastern""" + + def ISO(): + """Return the object in ISO standard format. Note: this is + *not* ISO 8601-format! See the ISO8601 and HTML4 methods below + for ISO 8601-compliant output + + Dates are output as: YYYY-MM-DD HH:MM:SS + """ + + def ISO8601(): + """Return the object in ISO 8601-compatible format containing + the date, time with seconds-precision and the time zone + identifier - see http://www.w3.org/TR/NOTE-datetime + + Dates are output as: YYYY-MM-DDTHH:MM:SSTZD + T is a literal character. + TZD is Time Zone Designator, format +HH:MM or -HH:MM + + The HTML4 method below offers the same formatting, but + converts to UTC before returning the value and sets the TZD"Z" + """ + + def HTML4(): + """Return the object in the format used in the HTML4.0 + specification, one of the standard forms in ISO8601. See + http://www.w3.org/TR/NOTE-datetime + + Dates are output as: YYYY-MM-DDTHH:MM:SSZ + T, Z are literal characters. + The time is in UTC. + """ + + def JulianDay(): + """Return the Julian day according to + https://www.tondering.dk/claus/cal/julperiod.php#formula + """ + + def week(): + """Return the week number according to ISO. + + See https://www.tondering.dk/claus/cal/week.php#weekno + """ + + # Python operator and conversion API + + def __add__(other): + """A DateTime may be added to a number and a number may be + added to a DateTime; two DateTimes cannot be added.""" + + __radd__ = __add__ + + def __sub__(other): + """Either a DateTime or a number may be subtracted from a + DateTime, however, a DateTime may not be subtracted from a + number.""" + + def __repr__(): + """Convert a DateTime to a string that looks like a Python + expression.""" + + def __str__(): + """Convert a DateTime to a string.""" + + def __hash__(): + """Compute a hash value for a DateTime""" + + def __int__(): + """Convert to an integer number of seconds since the epoch (gmt)""" + + def __long__(): + """Convert to a long-int number of seconds since the epoch (gmt)""" + + def __float__(): + """Convert to floating-point number of seconds since the epoch (gmt)""" diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz.txt b/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz.txt new file mode 100644 index 00000000..3a87338c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz.txt @@ -0,0 +1,192 @@ +Pytz Support +============ + +Allows the pytz package to be used for time zone information. The +advantage of using pytz is that it has a more complete and up to date +time zone and daylight savings time database. + +Usage +----- +You don't have to do anything special to make it work. + + >>> from DateTime import DateTime, Timezones + >>> d = DateTime('March 11, 2007 US/Eastern') + +Daylight Savings +---------------- +In 2007 daylight savings time in the US was changed. The Energy Policy +Act of 2005 mandates that DST will start on the second Sunday in March +and end on the first Sunday in November. + +In 2007, the start and stop dates are March 11 and November 4, +respectively. These dates are different from previous DST start and +stop dates. In 2006, the dates were the first Sunday in April (April +2, 2006) and the last Sunday in October (October 29, 2006). + +Let's make sure that DateTime can deal with this, since the primary +motivation to use pytz for time zone information is the fact that it +is kept up to date with daylight savings changes. + + >>> DateTime('March 11, 2007 US/Eastern').tzoffset() + -18000 + >>> DateTime('March 12, 2007 US/Eastern').tzoffset() + -14400 + >>> DateTime('November 4, 2007 US/Eastern').tzoffset() + -14400 + >>> DateTime('November 5, 2007 US/Eastern').tzoffset() + -18000 + +Let's compare this to 2006. + + >>> DateTime('April 2, 2006 US/Eastern').tzoffset() + -18000 + >>> DateTime('April 3, 2006 US/Eastern').tzoffset() + -14400 + >>> DateTime('October 29, 2006 US/Eastern').tzoffset() + -14400 + >>> DateTime('October 30, 2006 US/Eastern').tzoffset() + -18000 + +Time Zones +--------- +DateTime can use pytz's large database of time zones. Here are some +examples: + + >>> d = DateTime('Pacific/Kwajalein') + >>> d = DateTime('America/Shiprock') + >>> d = DateTime('Africa/Ouagadougou') + +Of course pytz doesn't know about everything. + + >>> from DateTime.interfaces import SyntaxError + >>> try: + ... d = DateTime('July 21, 1969 Moon/Eastern') + ... print('fail') + ... except SyntaxError: + ... print('ok') + ok + +You can still use zone names that DateTime defines that aren't part of +the pytz database. + + >>> d = DateTime('eet') + >>> d = DateTime('iceland') + +These time zones use DateTimes database. So it's preferable to use the +official time zone name. + +One trickiness is that DateTime supports some zone name +abbreviations. Some of these map to pytz names, so these abbreviations +will give you time zone date from pytz. Notable among abbreviations +that work this way are 'est', 'cst', 'mst', and 'pst'. + +Let's verify that 'est' picks up the 2007 daylight savings time changes. + + >>> DateTime('March 11, 2007 est').tzoffset() + -18000 + >>> DateTime('March 12, 2007 est').tzoffset() + -14400 + >>> DateTime('November 4, 2007 est').tzoffset() + -14400 + >>> DateTime('November 5, 2007 est').tzoffset() + -18000 + +You can get a list of time zones supported by calling the Timezones() function. + + >>> Timezones() #doctest: +ELLIPSIS + ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', ...] + +Note that you can mess with this list without hurting things. + + >>> t = Timezones() + >>> t.remove('US/Eastern') + >>> d = DateTime('US/Eastern') + + +Internal Components +------------------- + +The following are tests of internal components. + +Cache +~~~~~ + +The DateTime class uses a new time zone cache. + + >>> from DateTime.DateTime import _TZINFO + >>> _TZINFO #doctest: +ELLIPSIS + + +The cache maps time zone names to time zone instances. + + >>> cache = _TZINFO + >>> tz = cache['GMT+730'] + >>> tz = cache['US/Mountain'] + +The cache also must provide a few attributes for use by the DateTime +class. + +The _zlst attribute is a list of supported time zone names. + + >>> cache._zlst #doctest: +ELLIPSIS + ['Africa/Abidjan'... 'Africa/Accra'... 'IDLE'... 'NZST'... 'NZT'...] + +The _zidx attribute is a list of lower-case and possibly abbreviated +time zone names that can be mapped to official zone names. + + >>> 'australia/yancowinna' in cache._zidx + True + >>> 'europe/isle_of_man' in cache._zidx + True + >>> 'gmt+0500' in cache._zidx + True + +Note that there are more items in _zidx than in _zlst since there are +multiple names for some time zones. + + >>> len(cache._zidx) > len(cache._zlst) + True + +Each entry in _zlst should also be present in _zidx in lower case form. + + >>> for name in cache._zlst: + ... if not name.lower() in cache._zidx: + ... print("Error %s not in _zidx" % name.lower()) + +The _zmap attribute maps the names in _zidx to official names in _zlst. + + >>> cache._zmap['africa/abidjan'] + 'Africa/Abidjan' + >>> cache._zmap['gmt+1'] + 'GMT+1' + >>> cache._zmap['gmt+0100'] + 'GMT+1' + >>> cache._zmap['utc'] + 'UTC' + +Let's make sure that _zmap and _zidx agree. + + >>> idx = set(cache._zidx) + >>> keys = set(cache._zmap.keys()) + >>> idx == keys + True + +Timezone objects +~~~~~~~~~~~~~~~~ +The timezone instances have only one public method info(). It returns +a tuple of (offset, is_dst, name). The method takes a timestamp, which +is used to determine dst information. + + >>> t1 = DateTime('November 4, 00:00 2007 US/Mountain').timeTime() + >>> t2 = DateTime('November 4, 02:00 2007 US/Mountain').timeTime() + >>> tz.info(t1) + (-21600, 1, 'MDT') + >>> tz.info(t2) + (-25200, 0, 'MST') + +If you don't pass any arguments to info it provides daylight savings +time information as of today. + + >>> tz.info() in ((-21600, 1, 'MDT'), (-25200, 0, 'MST')) + True + diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz_support.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz_support.py new file mode 100644 index 00000000..4acf3248 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz_support.py @@ -0,0 +1,269 @@ +############################################################################## +# +# Copyright (c) 2007 Zope Foundation and Contributors. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## + +from datetime import datetime +from datetime import timedelta + +import pytz +import pytz.reference +from pytz.tzinfo import StaticTzInfo +from pytz.tzinfo import memorized_timedelta + +from .interfaces import DateTimeError + + +EPOCH = datetime.fromtimestamp(0, tz=pytz.utc) + +_numeric_timezone_data = { + 'GMT': ('GMT', 0, 1, [], '', [(0, 0, 0)], 'GMT\000'), + 'GMT+0': ('GMT+0', 0, 1, [], '', [(0, 0, 0)], 'GMT+0000\000'), + 'GMT+1': ('GMT+1', 0, 1, [], '', [(3600, 0, 0)], 'GMT+0100\000'), + 'GMT+2': ('GMT+2', 0, 1, [], '', [(7200, 0, 0)], 'GMT+0200\000'), + 'GMT+3': ('GMT+3', 0, 1, [], '', [(10800, 0, 0)], 'GMT+0300\000'), + 'GMT+4': ('GMT+4', 0, 1, [], '', [(14400, 0, 0)], 'GMT+0400\000'), + 'GMT+5': ('GMT+5', 0, 1, [], '', [(18000, 0, 0)], 'GMT+0500\000'), + 'GMT+6': ('GMT+6', 0, 1, [], '', [(21600, 0, 0)], 'GMT+0600\000'), + 'GMT+7': ('GMT+7', 0, 1, [], '', [(25200, 0, 0)], 'GMT+0700\000'), + 'GMT+8': ('GMT+8', 0, 1, [], '', [(28800, 0, 0)], 'GMT+0800\000'), + 'GMT+9': ('GMT+9', 0, 1, [], '', [(32400, 0, 0)], 'GMT+0900\000'), + 'GMT+10': ('GMT+10', 0, 1, [], '', [(36000, 0, 0)], 'GMT+1000\000'), + 'GMT+11': ('GMT+11', 0, 1, [], '', [(39600, 0, 0)], 'GMT+1100\000'), + 'GMT+12': ('GMT+12', 0, 1, [], '', [(43200, 0, 0)], 'GMT+1200\000'), + 'GMT+13': ('GMT+13', 0, 1, [], '', [(46800, 0, 0)], 'GMT+1300\000'), + + 'GMT-1': ('GMT-1', 0, 1, [], '', [(-3600, 0, 0)], 'GMT-0100\000'), + 'GMT-2': ('GMT-2', 0, 1, [], '', [(-7200, 0, 0)], 'GMT-0200\000'), + 'GMT-3': ('GMT-3', 0, 1, [], '', [(-10800, 0, 0)], 'GMT-0300\000'), + 'GMT-4': ('GMT-4', 0, 1, [], '', [(-14400, 0, 0)], 'GMT-0400\000'), + 'GMT-5': ('GMT-5', 0, 1, [], '', [(-18000, 0, 0)], 'GMT-0500\000'), + 'GMT-6': ('GMT-6', 0, 1, [], '', [(-21600, 0, 0)], 'GMT-0600\000'), + 'GMT-7': ('GMT-7', 0, 1, [], '', [(-25200, 0, 0)], 'GMT-0700\000'), + 'GMT-8': ('GMT-8', 0, 1, [], '', [(-28800, 0, 0)], 'GMT-0800\000'), + 'GMT-9': ('GMT-9', 0, 1, [], '', [(-32400, 0, 0)], 'GMT-0900\000'), + 'GMT-10': ('GMT-10', 0, 1, [], '', [(-36000, 0, 0)], 'GMT-1000\000'), + 'GMT-11': ('GMT-11', 0, 1, [], '', [(-39600, 0, 0)], 'GMT-1100\000'), + 'GMT-12': ('GMT-12', 0, 1, [], '', [(-43200, 0, 0)], 'GMT-1200\000'), + + 'GMT+0130': ('GMT+0130', 0, 1, [], '', [(5400, 0, 0)], 'GMT+0130\000'), + 'GMT+0230': ('GMT+0230', 0, 1, [], '', [(9000, 0, 0)], 'GMT+0230\000'), + 'GMT+0330': ('GMT+0330', 0, 1, [], '', [(12600, 0, 0)], 'GMT+0330\000'), + 'GMT+0430': ('GMT+0430', 0, 1, [], '', [(16200, 0, 0)], 'GMT+0430\000'), + 'GMT+0530': ('GMT+0530', 0, 1, [], '', [(19800, 0, 0)], 'GMT+0530\000'), + 'GMT+0630': ('GMT+0630', 0, 1, [], '', [(23400, 0, 0)], 'GMT+0630\000'), + 'GMT+0730': ('GMT+0730', 0, 1, [], '', [(27000, 0, 0)], 'GMT+0730\000'), + 'GMT+0830': ('GMT+0830', 0, 1, [], '', [(30600, 0, 0)], 'GMT+0830\000'), + 'GMT+0930': ('GMT+0930', 0, 1, [], '', [(34200, 0, 0)], 'GMT+0930\000'), + 'GMT+1030': ('GMT+1030', 0, 1, [], '', [(37800, 0, 0)], 'GMT+1030\000'), + 'GMT+1130': ('GMT+1130', 0, 1, [], '', [(41400, 0, 0)], 'GMT+1130\000'), + 'GMT+1230': ('GMT+1230', 0, 1, [], '', [(45000, 0, 0)], 'GMT+1230\000'), + + 'GMT-0130': ('GMT-0130', 0, 1, [], '', [(-5400, 0, 0)], 'GMT-0130\000'), + 'GMT-0230': ('GMT-0230', 0, 1, [], '', [(-9000, 0, 0)], 'GMT-0230\000'), + 'GMT-0330': ('GMT-0330', 0, 1, [], '', [(-12600, 0, 0)], 'GMT-0330\000'), + 'GMT-0430': ('GMT-0430', 0, 1, [], '', [(-16200, 0, 0)], 'GMT-0430\000'), + 'GMT-0530': ('GMT-0530', 0, 1, [], '', [(-19800, 0, 0)], 'GMT-0530\000'), + 'GMT-0630': ('GMT-0630', 0, 1, [], '', [(-23400, 0, 0)], 'GMT-0630\000'), + 'GMT-0730': ('GMT-0730', 0, 1, [], '', [(-27000, 0, 0)], 'GMT-0730\000'), + 'GMT-0830': ('GMT-0830', 0, 1, [], '', [(-30600, 0, 0)], 'GMT-0830\000'), + 'GMT-0930': ('GMT-0930', 0, 1, [], '', [(-34200, 0, 0)], 'GMT-0930\000'), + 'GMT-1030': ('GMT-1030', 0, 1, [], '', [(-37800, 0, 0)], 'GMT-1030\000'), + 'GMT-1130': ('GMT-1130', 0, 1, [], '', [(-41400, 0, 0)], 'GMT-1130\000'), + 'GMT-1230': ('GMT-1230', 0, 1, [], '', [(-45000, 0, 0)], 'GMT-1230\000'), +} + +# These are the timezones not in pytz.common_timezones +_old_zlst = [ + 'AST', 'AT', 'BST', 'BT', 'CCT', + 'CET', 'CST', 'Cuba', 'EADT', 'EAST', + 'EEST', 'EET', 'EST', 'Egypt', 'FST', + 'FWT', 'GB-Eire', 'GMT+0100', 'GMT+0130', 'GMT+0200', + 'GMT+0230', 'GMT+0300', 'GMT+0330', 'GMT+0400', 'GMT+0430', + 'GMT+0500', 'GMT+0530', 'GMT+0600', 'GMT+0630', 'GMT+0700', + 'GMT+0730', 'GMT+0800', 'GMT+0830', 'GMT+0900', 'GMT+0930', + 'GMT+1', 'GMT+1000', 'GMT+1030', 'GMT+1100', 'GMT+1130', + 'GMT+1200', 'GMT+1230', 'GMT+1300', 'GMT-0100', 'GMT-0130', + 'GMT-0200', 'GMT-0300', 'GMT-0400', 'GMT-0500', 'GMT-0600', + 'GMT-0630', 'GMT-0700', 'GMT-0730', 'GMT-0800', 'GMT-0830', + 'GMT-0900', 'GMT-0930', 'GMT-1000', 'GMT-1030', 'GMT-1100', + 'GMT-1130', 'GMT-1200', 'GMT-1230', 'GST', 'Greenwich', + 'Hongkong', 'IDLE', 'IDLW', 'Iceland', 'Iran', + 'Israel', 'JST', 'Jamaica', 'Japan', 'MEST', + 'MET', 'MEWT', 'MST', 'NT', 'NZDT', + 'NZST', 'NZT', 'PST', 'Poland', 'SST', + 'SWT', 'Singapore', 'Turkey', 'UCT', 'UT', + 'Universal', 'WADT', 'WAST', 'WAT', 'WET', + 'ZP4', 'ZP5', 'ZP6', +] + +_old_zmap = { + 'aest': 'GMT+10', 'aedt': 'GMT+11', + 'aus eastern standard time': 'GMT+10', + 'sydney standard time': 'GMT+10', + 'tasmania standard time': 'GMT+10', + 'e. australia standard time': 'GMT+10', + 'aus central standard time': 'GMT+0930', + 'cen. australia standard time': 'GMT+0930', + 'w. australia standard time': 'GMT+8', + + 'central europe standard time': 'GMT+1', + 'eastern standard time': 'US/Eastern', + 'us eastern standard time': 'US/Eastern', + 'central standard time': 'US/Central', + 'mountain standard time': 'US/Mountain', + 'pacific standard time': 'US/Pacific', + 'mst': 'US/Mountain', 'pst': 'US/Pacific', + 'cst': 'US/Central', 'est': 'US/Eastern', + + 'gmt+0000': 'GMT+0', 'gmt+0': 'GMT+0', + + 'gmt+0100': 'GMT+1', 'gmt+0200': 'GMT+2', 'gmt+0300': 'GMT+3', + 'gmt+0400': 'GMT+4', 'gmt+0500': 'GMT+5', 'gmt+0600': 'GMT+6', + 'gmt+0700': 'GMT+7', 'gmt+0800': 'GMT+8', 'gmt+0900': 'GMT+9', + 'gmt+1000': 'GMT+10', 'gmt+1100': 'GMT+11', 'gmt+1200': 'GMT+12', + 'gmt+1300': 'GMT+13', + 'gmt-0100': 'GMT-1', 'gmt-0200': 'GMT-2', 'gmt-0300': 'GMT-3', + 'gmt-0400': 'GMT-4', 'gmt-0500': 'GMT-5', 'gmt-0600': 'GMT-6', + 'gmt-0700': 'GMT-7', 'gmt-0800': 'GMT-8', 'gmt-0900': 'GMT-9', + 'gmt-1000': 'GMT-10', 'gmt-1100': 'GMT-11', 'gmt-1200': 'GMT-12', + + 'gmt+1': 'GMT+1', 'gmt+2': 'GMT+2', 'gmt+3': 'GMT+3', + 'gmt+4': 'GMT+4', 'gmt+5': 'GMT+5', 'gmt+6': 'GMT+6', + 'gmt+7': 'GMT+7', 'gmt+8': 'GMT+8', 'gmt+9': 'GMT+9', + 'gmt+10': 'GMT+10', 'gmt+11': 'GMT+11', 'gmt+12': 'GMT+12', + 'gmt+13': 'GMT+13', + 'gmt-1': 'GMT-1', 'gmt-2': 'GMT-2', 'gmt-3': 'GMT-3', + 'gmt-4': 'GMT-4', 'gmt-5': 'GMT-5', 'gmt-6': 'GMT-6', + 'gmt-7': 'GMT-7', 'gmt-8': 'GMT-8', 'gmt-9': 'GMT-9', + 'gmt-10': 'GMT-10', 'gmt-11': 'GMT-11', 'gmt-12': 'GMT-12', + + 'gmt+130': 'GMT+0130', 'gmt+0130': 'GMT+0130', + 'gmt+230': 'GMT+0230', 'gmt+0230': 'GMT+0230', + 'gmt+330': 'GMT+0330', 'gmt+0330': 'GMT+0330', + 'gmt+430': 'GMT+0430', 'gmt+0430': 'GMT+0430', + 'gmt+530': 'GMT+0530', 'gmt+0530': 'GMT+0530', + 'gmt+630': 'GMT+0630', 'gmt+0630': 'GMT+0630', + 'gmt+730': 'GMT+0730', 'gmt+0730': 'GMT+0730', + 'gmt+830': 'GMT+0830', 'gmt+0830': 'GMT+0830', + 'gmt+930': 'GMT+0930', 'gmt+0930': 'GMT+0930', + 'gmt+1030': 'GMT+1030', + 'gmt+1130': 'GMT+1130', + 'gmt+1230': 'GMT+1230', + + 'gmt-130': 'GMT-0130', 'gmt-0130': 'GMT-0130', + 'gmt-230': 'GMT-0230', 'gmt-0230': 'GMT-0230', + 'gmt-330': 'GMT-0330', 'gmt-0330': 'GMT-0330', + 'gmt-430': 'GMT-0430', 'gmt-0430': 'GMT-0430', + 'gmt-530': 'GMT-0530', 'gmt-0530': 'GMT-0530', + 'gmt-630': 'GMT-0630', 'gmt-0630': 'GMT-0630', + 'gmt-730': 'GMT-0730', 'gmt-0730': 'GMT-0730', + 'gmt-830': 'GMT-0830', 'gmt-0830': 'GMT-0830', + 'gmt-930': 'GMT-0930', 'gmt-0930': 'GMT-0930', + 'gmt-1030': 'GMT-1030', + 'gmt-1130': 'GMT-1130', + 'gmt-1230': 'GMT-1230', + + 'ut': 'Universal', + 'bst': 'GMT+1', 'mest': 'GMT+2', 'sst': 'GMT+2', + 'fst': 'GMT+2', 'wadt': 'GMT+8', 'eadt': 'GMT+11', 'nzdt': 'GMT+13', + 'wet': 'GMT', 'wat': 'GMT+1', 'at': 'GMT-2', 'ast': 'GMT-4', + 'nt': 'GMT-11', 'idlw': 'GMT-12', 'cet': 'GMT+1', 'cest': 'GMT+2', + 'met': 'GMT+1', + 'mewt': 'GMT+1', 'swt': 'GMT+1', 'fwt': 'GMT+1', 'eet': 'GMT+2', + 'eest': 'GMT+3', + 'bt': 'GMT+3', 'zp4': 'GMT+4', 'zp5': 'GMT+5', 'zp6': 'GMT+6', + 'wast': 'GMT+7', 'cct': 'GMT+8', 'jst': 'GMT+9', 'east': 'GMT+10', + 'gst': 'GMT+10', 'nzt': 'GMT+12', 'nzst': 'GMT+12', 'idle': 'GMT+12', + 'ret': 'GMT+4', 'ist': 'GMT+0530', 'edt': 'GMT-4', + +} + + +# some timezone definitions of the "-0400" are not working +# when upgrading +for hour in range(0, 13): + hour = hour + fhour = str(hour) + if len(fhour) == 1: + fhour = '0' + fhour + _old_zmap['-%s00' % fhour] = 'GMT-%i' % hour + _old_zmap['+%s00' % fhour] = 'GMT+%i' % hour + + +def _p(zone): + return _numeric_timezones[zone] + + +def _static_timezone_factory(data): + zone = data[0] + cls = type(zone, (StaticTzInfo,), dict( + __reduce__=lambda _: (_p, (zone, )), + zone=zone, + _utcoffset=memorized_timedelta(data[5][0][0]), + _tzname=data[6][:-1])) # strip the trailing null + return cls() + + +_numeric_timezones = {key: _static_timezone_factory(data) + for key, data in _numeric_timezone_data.items()} + + +class Timezone: + """ + Timezone information returned by PytzCache.__getitem__ + Adapts datetime.tzinfo object to DateTime._timezone interface + """ + + def __init__(self, tzinfo): + self.tzinfo = tzinfo + + def info(self, t=None): + if t is None: + dt = datetime.now(tz=pytz.utc) + else: + # can't use utcfromtimestamp past 2038 + dt = EPOCH + timedelta(0, t) + + # need to normalize tzinfo for the datetime to deal with + # daylight savings time. + normalized_dt = self.tzinfo.normalize(dt.astimezone(self.tzinfo)) + normalized_tzinfo = normalized_dt.tzinfo + + offset = normalized_tzinfo.utcoffset(normalized_dt) + secs = offset.days * 24 * 60 * 60 + offset.seconds + dst = normalized_tzinfo.dst(normalized_dt) + if dst == timedelta(0): + is_dst = 0 + else: + is_dst = 1 + return secs, is_dst, normalized_tzinfo.tzname(normalized_dt) + + +class PytzCache: + """ + Reimplementation of the DateTime._cache class that uses for timezone info + """ + + _zlst = pytz.common_timezones + _old_zlst # used by DateTime.TimeZones + _zmap = {name.lower(): name for name in pytz.all_timezones} + _zmap.update(_old_zmap) # These must take priority + _zidx = _zmap.keys() + + def __getitem__(self, key): + name = self._zmap.get(key.lower(), key) # fallback to key + try: + return Timezone(pytz.timezone(name)) + except pytz.UnknownTimeZoneError: + try: + return Timezone(_numeric_timezones[name]) + except KeyError: + raise DateTimeError('Unrecognized timezone: %s' % key) diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/__init__.py new file mode 100644 index 00000000..e67bcb67 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/__init__.py @@ -0,0 +1,15 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## + +# This file is needed to make this a package. diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/julian_testdata.txt b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/julian_testdata.txt new file mode 100644 index 00000000..386c3dae --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/julian_testdata.txt @@ -0,0 +1,57 @@ +1970-01-01 (1970, 1, 4) +1970-01-02 (1970, 1, 5) +1970-01-30 (1970, 5, 5) +1970-01-31 (1970, 5, 6) +1970-02-01 (1970, 5, 7) +1970-02-02 (1970, 6, 1) +1970-02-28 (1970, 9, 6) +1970-03-01 (1970, 9, 7) +1970-03-30 (1970, 14, 1) +1970-03-31 (1970, 14, 2) +1970-04-01 (1970, 14, 3) +1970-09-30 (1970, 40, 3) +1970-10-01 (1970, 40, 4) +1970-10-02 (1970, 40, 5) +1970-10-03 (1970, 40, 6) +1970-10-04 (1970, 40, 7) +1970-10-05 (1970, 41, 1) +1971-01-02 (1970, 53, 6) +1971-01-03 (1970, 53, 7) +1971-01-04 (1971, 1, 1) +1971-01-05 (1971, 1, 2) +1971-12-31 (1971, 52, 5) +1972-01-01 (1971, 52, 6) +1972-01-02 (1971, 52, 7) +1972-01-03 (1972, 1, 1) +1972-01-04 (1972, 1, 2) +1972-12-30 (1972, 52, 6) +1972-12-31 (1972, 52, 7) +1973-01-01 (1973, 1, 1) +1973-01-02 (1973, 1, 2) +1973-12-29 (1973, 52, 6) +1973-12-30 (1973, 52, 7) +1973-12-31 (1974, 1, 1) +1974-01-01 (1974, 1, 2) +1998-12-30 (1998, 53, 3) +1998-12-31 (1998, 53, 4) +1999-01-01 (1998, 53, 5) +1999-01-02 (1998, 53, 6) +1999-01-03 (1998, 53, 7) +1999-01-04 (1999, 1, 1) +1999-01-05 (1999, 1, 2) +1999-12-30 (1999, 52, 4) +1999-12-31 (1999, 52, 5) +2000-01-01 (1999, 52, 6) +2000-01-02 (1999, 52, 7) +2000-01-03 (2000, 1, 1) +2000-01-04 (2000, 1, 2) +2000-01-05 (2000, 1, 3) +2000-01-06 (2000, 1, 4) +2000-01-07 (2000, 1, 5) +2000-01-08 (2000, 1, 6) +2000-01-09 (2000, 1, 7) +2000-01-10 (2000, 2, 1) +2019-12-28 (2019, 52, 6) +2019-12-29 (2019, 52, 7) +2019-12-30 (2020, 1, 1) +2019-12-31 (2020, 1, 2) diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/test_datetime.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/test_datetime.py new file mode 100644 index 00000000..ae67d452 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/test_datetime.py @@ -0,0 +1,746 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## + +import math +import os +import pickle +import platform +import sys +import time +import unittest +from datetime import date +from datetime import datetime +from datetime import timedelta +from datetime import tzinfo + +import pytz + +from DateTime import DateTime +from DateTime.DateTime import _findLocalTimeZoneName + + +try: + __file__ +except NameError: # pragma: no cover + f = sys.argv[0] +else: + f = __file__ + +IS_PYPY = getattr(platform, 'python_implementation', lambda: None)() == 'PyPy' + +DATADIR = os.path.dirname(os.path.abspath(f)) +del f + +ZERO = timedelta(0) + + +class FixedOffset(tzinfo): + """Fixed offset in minutes east from UTC.""" + + def __init__(self, offset, name): + self.__offset = timedelta(minutes=offset) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return ZERO + + +class DateTimeTests(unittest.TestCase): + + def _compare(self, dt1, dt2): + '''Compares the internal representation of dt1 with + the representation in dt2. Allows sub-millisecond variations. + Primarily for testing.''' + self.assertEqual(round(dt1._t, 3), round(dt2._t, 3)) + self.assertEqual(round(dt1._d, 9), round(dt2._d, 9)) + self.assertEqual(round(dt1.time, 9), round(dt2.time, 9)) + self.assertEqual(dt1.millis(), dt2.millis()) + self.assertEqual(dt1._micros, dt2._micros) + + def testBug1203(self): + # 01:59:60 occurred in old DateTime + dt = DateTime(7200, 'GMT') + self.assertTrue(str(dt).find('60') < 0, dt) + + def testDSTInEffect(self): + # Checks GMT offset for a DST date in the US/Eastern time zone + dt = DateTime(2000, 5, 9, 15, 0, 0, 'US/Eastern') + self.assertEqual(dt.toZone('GMT').hour(), 19, + (dt, dt.toZone('GMT'))) + + def testDSTNotInEffect(self): + # Checks GMT offset for a non-DST date in the US/Eastern time zone + dt = DateTime(2000, 11, 9, 15, 0, 0, 'US/Eastern') + self.assertEqual(dt.toZone('GMT').hour(), 20, + (dt, dt.toZone('GMT'))) + + def testAddPrecision(self): + # Precision of serial additions + dt = DateTime() + self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt), + dt) + # checks problem reported in + # https://github.com/zopefoundation/DateTime/issues/41 + dt = DateTime(2038, 10, 7, 8, 52, 44.959840, "UTC") + self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt), + dt) + + def testConsistentSecondMicroRounding(self): + dt = DateTime(2038, 10, 7, 8, 52, 44.9598398, "UTC") + self.assertEqual(int(dt.second() * 1000000), + dt.micros() % 60000000) + + def testConstructor3(self): + # Constructor from date/time string + dt = DateTime() + dt1s = '%d/%d/%d %d:%d:%f %s' % ( + dt.year(), + dt.month(), + dt.day(), + dt.hour(), + dt.minute(), + dt.second(), + dt.timezone()) + dt1 = DateTime(dt1s) + # Compare representations as it's the + # only way to compare the dates to the same accuracy + self.assertEqual(repr(dt), repr(dt1)) + + def testConstructor4(self): + # Constructor from time float + dt = DateTime() + dt1 = DateTime(float(dt)) + self._compare(dt, dt1) + + def testConstructor5(self): + # Constructor from time float and timezone + dt = DateTime() + dt1 = DateTime(float(dt), dt.timezone()) + self.assertEqual(str(dt), str(dt1), (dt, dt1)) + dt1 = DateTime(float(dt), str(dt.timezone())) + self.assertEqual(str(dt), str(dt1), (dt, dt1)) + + def testConstructor6(self): + # Constructor from year and julian date + # This test must normalize the time zone, or it *will* break when + # DST changes! + dt1 = DateTime(2000, 5.500000578705) + dt = DateTime('2000/1/5 12:00:00.050 pm %s' % dt1.localZone()) + self._compare(dt, dt1) + + def testConstructor7(self): + # Constructor from parts + dt = DateTime() + dt1 = DateTime( + dt.year(), + dt.month(), + dt.day(), + dt.hour(), + dt.minute(), + dt.second(), + dt.timezone()) + # Compare representations as it's the + # only way to compare the dates to the same accuracy + self.assertEqual(repr(dt), repr(dt1)) + + def testDayOfWeek(self): + # Compare to the datetime.date value to make it locale independent + expected = date(2000, 6, 16).strftime('%A') + # strftime() used to always be passed a day of week of 0 + dt = DateTime('2000/6/16') + s = dt.strftime('%A') + self.assertEqual(s, expected, (dt, s)) + + def testOldDate(self): + # Fails when an 1800 date is displayed with negative signs + dt = DateTime('1830/5/6 12:31:46.213 pm') + dt1 = dt.toZone('GMT+6') + self.assertTrue(str(dt1).find('-') < 0, (dt, dt1)) + + def testSubtraction(self): + # Reconstruction of a DateTime from its parts, with subtraction + # this also tests the accuracy of addition and reconstruction + dt = DateTime() + dt1 = dt - 3.141592653 + dt2 = DateTime( + dt.year(), + dt.month(), + dt.day(), + dt.hour(), + dt.minute(), + dt.second()) + dt3 = dt2 - 3.141592653 + self.assertEqual(dt1, dt3, (dt, dt1, dt2, dt3)) + + def testTZ1add(self): + # Time zone manipulation: add to a date + dt = DateTime('1997/3/8 1:45am GMT-4') + dt1 = DateTime('1997/3/9 1:45pm GMT+8') + self.assertTrue((dt + 1.0).equalTo(dt1)) + + def testTZ1sub(self): + # Time zone manipulation: subtract from a date + dt = DateTime('1997/3/8 1:45am GMT-4') + dt1 = DateTime('1997/3/9 1:45pm GMT+8') + self.assertTrue((dt1 - 1.0).equalTo(dt)) + + def testTZ1diff(self): + # Time zone manipulation: diff two dates + dt = DateTime('1997/3/8 1:45am GMT-4') + dt1 = DateTime('1997/3/9 1:45pm GMT+8') + self.assertEqual(dt1 - dt, 1.0, (dt, dt1)) + + def test_compare_methods(self): + # Compare two dates using several methods + dt = DateTime('1997/1/1') + dt1 = DateTime('1997/2/2') + self.assertTrue(dt1.greaterThan(dt)) + self.assertTrue(dt1.greaterThanEqualTo(dt)) + self.assertTrue(dt.lessThan(dt1)) + self.assertTrue(dt.lessThanEqualTo(dt1)) + self.assertTrue(dt.notEqualTo(dt1)) + self.assertFalse(dt.equalTo(dt1)) + # Compare a date to float + dt = DateTime(1.0) + self.assertTrue(dt == DateTime(1.0)) # testing __eq__ + self.assertFalse(dt != DateTime(1.0)) # testing __ne__ + self.assertFalse(dt.greaterThan(1.0)) + self.assertTrue(dt.greaterThanEqualTo(1.0)) + self.assertFalse(dt.lessThan(1.0)) + self.assertTrue(dt.lessThanEqualTo(1.0)) + self.assertFalse(dt.notEqualTo(1.0)) + self.assertTrue(dt.equalTo(1.0)) + # Compare a date to int + dt = DateTime(1) + self.assertEqual(dt, DateTime(1.0)) + self.assertTrue(dt == DateTime(1)) # testing __eq__ + self.assertFalse(dt != DateTime(1)) # testing __ne__ + self.assertFalse(dt.greaterThan(1)) + self.assertTrue(dt.greaterThanEqualTo(1)) + self.assertFalse(dt.lessThan(1)) + self.assertTrue(dt.lessThanEqualTo(1)) + self.assertFalse(dt.notEqualTo(1)) + self.assertTrue(dt.equalTo(1)) + # Compare a date to string; there is no implicit type conversion + # but behavior if consistent as when comparing, for example, an int + # and a string. + dt = DateTime("2023") + self.assertFalse(dt == "2023") # testing __eq__ + self.assertTrue(dt != "2023") # testing __ne__ + self.assertRaises(TypeError, dt.greaterThan, "2023") + self.assertRaises(TypeError, dt.greaterThanEqualTo, "2023") + self.assertRaises(TypeError, dt.lessThan, "2023") + self.assertRaises(TypeError, dt.lessThanEqualTo, "2023") + self.assertTrue(dt.notEqualTo("2023")) + self.assertFalse(dt.equalTo("2023")) + + def test_compare_methods_none(self): + # Compare a date to None + for dt in (DateTime('1997/1/1'), DateTime(0)): + self.assertTrue(dt.greaterThan(None)) + self.assertTrue(dt.greaterThanEqualTo(None)) + self.assertFalse(dt.lessThan(None)) + self.assertFalse(dt.lessThanEqualTo(None)) + self.assertTrue(dt.notEqualTo(None)) + self.assertFalse(dt.equalTo(None)) + + def test_pickle(self): + dt = DateTime() + data = pickle.dumps(dt, 1) + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_with_tz(self): + dt = DateTime('2002/5/2 8:00am GMT+8') + data = pickle.dumps(dt, 1) + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_asdatetime_with_tz(self): + dt = DateTime('2002/5/2 8:00am GMT+8') + data = pickle.dumps(dt.asdatetime(), 1) + new = DateTime(pickle.loads(data)) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_with_numerical_tz(self): + for dt_str in ('2007/01/02 12:34:56.789 +0300', + '2007/01/02 12:34:56.789 +0430', + '2007/01/02 12:34:56.789 -1234'): + dt = DateTime(dt_str) + data = pickle.dumps(dt, 1) + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_with_micros(self): + dt = DateTime('2002/5/2 8:00:14.123 GMT+8') + data = pickle.dumps(dt, 1) + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_old(self): + dt = DateTime('2002/5/2 8:00am GMT+0') + data = ( + '(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05' + '_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq' + '\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU' + '\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU\x02amq' + '\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq\x12K\x00U' + '\x07_microsq\x13L1020326400000000L\nU\x02_dq\x14G@\xe2\x12j\xaa' + '\xaa\xaa\xabU\x07_secondq\x15G\x00\x00\x00\x00\x00\x00\x00\x00U' + '\x03_tzq\x16U\x05GMT+0q\x17U\x06_monthq\x18K\x05U' + '\x0f_timezone_naiveq\x19I00\nU\x04_dayq\x1aK\x02U\x05_yearq' + '\x1bM\xd2\x07U\x08_nearsecq\x1cG\x00\x00\x00\x00\x00\x00\x00' + '\x00U\x07_pmhourq\x1dK\x08U\n_dayoffsetq\x1eK\x04U\x04timeq' + '\x1fG?\xd5UUUV\x00\x00ub.') + data = data.encode('latin-1') + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def test_pickle_old_without_micros(self): + dt = DateTime('2002/5/2 8:00am GMT+0') + data = ( + '(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05' + '_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq' + '\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU' + '\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU' + '\x02amq\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq' + '\x12K\x00U\x02_dq\x13G@\xe2\x12j\xaa\xaa\xaa\xabU\x07_secondq' + '\x14G\x00\x00\x00\x00\x00\x00\x00\x00U\x03_tzq\x15U\x05GMT+0q' + '\x16U\x06_monthq\x17K\x05U\x0f_timezone_naiveq\x18I00\nU' + '\x04_dayq\x19K\x02U\x05_yearq\x1aM\xd2\x07U\x08_nearsecq' + '\x1bG\x00\x00\x00\x00\x00\x00\x00\x00U\x07_pmhourq\x1cK\x08U' + '\n_dayoffsetq\x1dK\x04U\x04timeq\x1eG?\xd5UUUV\x00\x00ub.') + data = data.encode('latin-1') + new = pickle.loads(data) + for key in DateTime.__slots__: + self.assertEqual(getattr(dt, key), getattr(new, key)) + + def testTZ2(self): + # Time zone manipulation test 2 + dt = DateTime() + dt1 = dt.toZone('GMT') + s = dt.second() + s1 = dt1.second() + self.assertEqual(s, s1, (dt, dt1, s, s1)) + + def testTZDiffDaylight(self): + # Diff dates across daylight savings dates + dt = DateTime('2000/6/8 1:45am US/Eastern') + dt1 = DateTime('2000/12/8 12:45am US/Eastern') + self.assertEqual(dt1 - dt, 183, (dt, dt1, dt1 - dt)) + + def testY10KDate(self): + # Comparison of a Y10K date and a Y2K date + dt = DateTime('10213/09/21') + dt1 = DateTime(2000, 1, 1) + + dsec = (dt.millis() - dt1.millis()) / 1000.0 + ddays = math.floor((dsec / 86400.0) + 0.5) + + self.assertEqual(ddays, 3000000, ddays) + + def test_tzoffset(self): + # Test time-zone given as an offset + + # GMT + dt = DateTime('Tue, 10 Sep 2001 09:41:03 GMT') + self.assertEqual(dt.tzoffset(), 0) + + # Timezone by name, a timezone that hasn't got daylightsaving. + dt = DateTime('Tue, 2 Mar 2001 09:41:03 GMT+3') + self.assertEqual(dt.tzoffset(), 10800) + + # Timezone by name, has daylightsaving but is not in effect. + dt = DateTime('Tue, 21 Jan 2001 09:41:03 PST') + self.assertEqual(dt.tzoffset(), -28800) + + # Timezone by name, with daylightsaving in effect + dt = DateTime('Tue, 24 Aug 2001 09:41:03 PST') + self.assertEqual(dt.tzoffset(), -25200) + + # A negative numerical timezone + dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0400') + self.assertEqual(dt.tzoffset(), -14400) + + # A positive numerical timzone + dt = DateTime('Tue, 6 Dec 1966 01:41:03 +0200') + self.assertEqual(dt.tzoffset(), 7200) + + # A negative numerical timezone with minutes. + dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0637') + self.assertEqual(dt.tzoffset(), -23820) + + # A positive numerical timezone with minutes. + dt = DateTime('Tue, 24 Jul 2001 09:41:03 +0425') + self.assertEqual(dt.tzoffset(), 15900) + + def testISO8601(self): + # ISO8601 reference dates + ref0 = DateTime('2002/5/2 8:00am GMT') + ref1 = DateTime('2002/5/2 8:00am US/Eastern') + ref2 = DateTime('2006/11/6 10:30 GMT') + ref3 = DateTime('2004/06/14 14:30:15 GMT-3') + ref4 = DateTime('2006/01/01 GMT') + + # Basic tests + # Though this is timezone naive and according to specification should + # be interpreted in the local timezone, to preserve backwards + # compatibility with previously expected behaviour. + isoDt = DateTime('2002-05-02T08:00:00') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-05-02T08:00:00Z') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-05-02T08:00:00+00:00') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-05-02T08:00:00-04:00') + self.assertTrue(ref1.equalTo(isoDt)) + isoDt = DateTime('2002-05-02 08:00:00-04:00') + self.assertTrue(ref1.equalTo(isoDt)) + + # Bug 1386: the colon in the timezone offset is optional + isoDt = DateTime('2002-05-02T08:00:00-0400') + self.assertTrue(ref1.equalTo(isoDt)) + + # Bug 2191: date reduced formats + isoDt = DateTime('2006-01-01') + self.assertTrue(ref4.equalTo(isoDt)) + isoDt = DateTime('200601-01') + self.assertTrue(ref4.equalTo(isoDt)) + isoDt = DateTime('20060101') + self.assertTrue(ref4.equalTo(isoDt)) + isoDt = DateTime('2006-01') + self.assertTrue(ref4.equalTo(isoDt)) + isoDt = DateTime('200601') + self.assertTrue(ref4.equalTo(isoDt)) + isoDt = DateTime('2006') + self.assertTrue(ref4.equalTo(isoDt)) + + # Bug 2191: date/time separators are also optional + isoDt = DateTime('20020502T08:00:00') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-05-02T080000') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('20020502T080000') + self.assertTrue(ref0.equalTo(isoDt)) + + # Bug 2191: timezones with only one digit for hour + isoDt = DateTime('20020502T080000+0') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('20020502 080000-4') + self.assertTrue(ref1.equalTo(isoDt)) + isoDt = DateTime('20020502T080000-400') + self.assertTrue(ref1.equalTo(isoDt)) + isoDt = DateTime('20020502T080000-4:00') + self.assertTrue(ref1.equalTo(isoDt)) + + # Bug 2191: optional seconds/minutes + isoDt = DateTime('2002-05-02T0800') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-05-02T08') + self.assertTrue(ref0.equalTo(isoDt)) + + # Bug 2191: week format + isoDt = DateTime('2002-W18-4T0800') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002-W184T0800') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002W18-4T0800') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002W184T08') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2004-W25-1T14:30:15-03:00') + self.assertTrue(ref3.equalTo(isoDt)) + isoDt = DateTime('2004-W25T14:30:15-03:00') + self.assertTrue(ref3.equalTo(isoDt)) + + # Bug 2191: day of year format + isoDt = DateTime('2002-122T0800') + self.assertTrue(ref0.equalTo(isoDt)) + isoDt = DateTime('2002122T0800') + self.assertTrue(ref0.equalTo(isoDt)) + + # Bug 2191: hours/minutes fractions + isoDt = DateTime('2006-11-06T10.5') + self.assertTrue(ref2.equalTo(isoDt)) + isoDt = DateTime('2006-11-06T10,5') + self.assertTrue(ref2.equalTo(isoDt)) + isoDt = DateTime('20040614T1430.25-3') + self.assertTrue(ref3.equalTo(isoDt)) + isoDt = DateTime('2004-06-14T1430,25-3') + self.assertTrue(ref3.equalTo(isoDt)) + isoDt = DateTime('2004-06-14T14:30.25-3') + self.assertTrue(ref3.equalTo(isoDt)) + isoDt = DateTime('20040614T14:30,25-3') + self.assertTrue(ref3.equalTo(isoDt)) + + # ISO8601 standard format + iso8601_string = '2002-05-02T08:00:00-04:00' + iso8601DT = DateTime(iso8601_string) + self.assertEqual(iso8601_string, iso8601DT.ISO8601()) + + # ISO format with no timezone + isoDt = DateTime('2006-01-01 00:00:00') + self.assertTrue(ref4.equalTo(isoDt)) + + def testJulianWeek(self): + # Check JulianDayWeek function + fn = os.path.join(DATADIR, 'julian_testdata.txt') + with open(fn) as fd: + lines = fd.readlines() + for line in lines: + d = DateTime(line[:10]) + result_from_mx = tuple(map(int, line[12:-2].split(','))) + self.assertEqual(result_from_mx[1], d.week()) + + def testCopyConstructor(self): + d = DateTime('2004/04/04') + self.assertEqual(DateTime(d), d) + self.assertEqual(str(DateTime(d)), str(d)) + d2 = DateTime('1999/04/12 01:00:00') + self.assertEqual(DateTime(d2), d2) + self.assertEqual(str(DateTime(d2)), str(d2)) + + def testCopyConstructorPreservesTimezone(self): + # test for https://bugs.launchpad.net/zope2/+bug/200007 + # This always worked in the local timezone, so we need at least + # two tests with different zones to be sure at least one of them + # is not local. + d = DateTime('2004/04/04') + self.assertEqual(DateTime(d).timezone(), d.timezone()) + d2 = DateTime('2008/04/25 12:00:00 EST') + self.assertEqual(DateTime(d2).timezone(), d2.timezone()) + self.assertEqual(str(DateTime(d2)), str(d2)) + d3 = DateTime('2008/04/25 12:00:00 PST') + self.assertEqual(DateTime(d3).timezone(), d3.timezone()) + self.assertEqual(str(DateTime(d3)), str(d3)) + + def testRFC822(self): + # rfc822 conversion + dt = DateTime('2002-05-02T08:00:00+00:00') + self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0000') + + dt = DateTime('2002-05-02T08:00:00+02:00') + self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0200') + + dt = DateTime('2002-05-02T08:00:00-02:00') + self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 -0200') + + # Checking that conversion from local time is working. + dt = DateTime() + dts = dt.rfc822().split(' ') + times = dts[4].split(':') + _isDST = time.localtime(time.time())[8] + if _isDST: + offset = time.altzone + else: + offset = time.timezone + self.assertEqual(dts[0], dt.aDay() + ',') + self.assertEqual(int(dts[1]), dt.day()) + self.assertEqual(dts[2], dt.aMonth()) + self.assertEqual(int(dts[3]), dt.year()) + self.assertEqual(int(times[0]), dt.h_24()) + self.assertEqual(int(times[1]), dt.minute()) + self.assertEqual(int(times[2]), int(dt.second())) + self.assertEqual(dts[5], "%+03d%02d" % divmod((-offset / 60), 60)) + + def testInternationalDateformat(self): + for year in (1990, 2001, 2020): + for month in (1, 12): + for day in (1, 12, 28, 31): + try: + d_us = DateTime("%d/%d/%d" % (year, month, day)) + except Exception: + continue + + d_int = DateTime("%d.%d.%d" % (day, month, year), + datefmt="international") + self.assertEqual(d_us, d_int) + + d_int = DateTime("%d/%d/%d" % (day, month, year), + datefmt="international") + self.assertEqual(d_us, d_int) + + def test_intl_format_hyphen(self): + d_jan = DateTime('2011-01-11 GMT') + d_nov = DateTime('2011-11-01 GMT') + d_us = DateTime('11-01-2011 GMT') + d_int = DateTime('11-01-2011 GMT', datefmt="international") + self.assertNotEqual(d_us, d_int) + self.assertEqual(d_us, d_nov) + self.assertEqual(d_int, d_jan) + + def test_calcTimezoneName(self): + from DateTime.interfaces import TimeError + timezone_dependent_epoch = 2177452800 + try: + DateTime()._calcTimezoneName(timezone_dependent_epoch, 0) + except TimeError: + self.fail('Zope Collector issue #484 (negative time bug): ' + 'TimeError raised') + + def testStrftimeTZhandling(self): + # strftime timezone testing + # This is a test for collector issue #1127 + format = '%Y-%m-%d %H:%M %Z' + dt = DateTime('Wed, 19 Nov 2003 18:32:07 -0215') + dt_string = dt.strftime(format) + dt_local = dt.toZone(_findLocalTimeZoneName(0)) + dt_localstring = dt_local.strftime(format) + self.assertEqual(dt_string, dt_localstring) + + def testStrftimeFarDates(self): + # Checks strftime in dates <= 1900 or >= 2038 + dt = DateTime('1900/01/30') + self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/1900') + dt = DateTime('2040/01/30') + self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/2040') + + def testZoneInFarDates(self): + # Checks time zone in dates <= 1900 or >= 2038 + dt1 = DateTime('2040/01/30 14:33 GMT+1') + dt2 = DateTime('2040/01/30 11:33 GMT-2') + self.assertEqual(dt1.strftime('%d/%m/%Y %H:%M'), + dt2.strftime('%d/%m/%Y %H:%M')) + + @unittest.skipIf( + IS_PYPY, + "Using Non-Ascii characters for strftime doesn't work in PyPy" + "https://bitbucket.org/pypy/pypy/issues/2161/pypy3-strftime-does-not-accept-unicode" # noqa: E501 line too long + ) + def testStrftimeStr(self): + dt = DateTime('2002-05-02T08:00:00+00:00') + uchar = b'\xc3\xa0'.decode('utf-8') + ok = dt.strftime('Le %d/%m/%Y a %Hh%M').replace('a', uchar) + ustr = b'Le %d/%m/%Y \xc3\xa0 %Hh%M'.decode('utf-8') + self.assertEqual(dt.strftime(ustr), ok) + + def testTimezoneNaiveHandling(self): + # checks that we assign timezone naivity correctly + dt = DateTime('2007-10-04T08:00:00+00:00') + self.assertFalse(dt.timezoneNaive(), + 'error with naivity handling in __parse_iso8601') + dt = DateTime('2007-10-04T08:00:00Z') + self.assertFalse(dt.timezoneNaive(), + 'error with naivity handling in __parse_iso8601') + dt = DateTime('2007-10-04T08:00:00') + self.assertTrue(dt.timezoneNaive(), + 'error with naivity handling in __parse_iso8601') + dt = DateTime('2007/10/04 15:12:33.487618 GMT+1') + self.assertFalse(dt.timezoneNaive(), + 'error with naivity handling in _parse') + dt = DateTime('2007/10/04 15:12:33.487618') + self.assertTrue(dt.timezoneNaive(), + 'error with naivity handling in _parse') + dt = DateTime() + self.assertFalse(dt.timezoneNaive(), + 'error with naivity for current time') + s = '2007-10-04T08:00:00' + dt = DateTime(s) + self.assertEqual(s, dt.ISO8601()) + s = '2007-10-04T08:00:00+00:00' + dt = DateTime(s) + self.assertEqual(s, dt.ISO8601()) + + def testConversions(self): + sdt0 = datetime.now() # this is a timezone naive datetime + dt0 = DateTime(sdt0) + self.assertTrue(dt0.timezoneNaive(), (sdt0, dt0)) + sdt1 = datetime(2007, 10, 4, 18, 14, 42, 580, pytz.utc) + dt1 = DateTime(sdt1) + self.assertFalse(dt1.timezoneNaive(), (sdt1, dt1)) + + # convert back + sdt2 = dt0.asdatetime() + self.assertEqual(sdt0, sdt2) + sdt3 = dt1.utcdatetime() # this returns a timezone naive datetime + self.assertEqual(sdt1.hour, sdt3.hour) + + dt4 = DateTime('2007-10-04T10:00:00+05:00') + sdt4 = datetime(2007, 10, 4, 5, 0) + self.assertEqual(dt4.utcdatetime(), sdt4) + self.assertEqual(dt4.asdatetime(), sdt4.replace(tzinfo=pytz.utc)) + + dt5 = DateTime('2007-10-23 10:00:00 US/Eastern') + tz = pytz.timezone('US/Eastern') + sdt5 = datetime(2007, 10, 23, 10, 0, tzinfo=tz) + dt6 = DateTime(sdt5) + self.assertEqual(dt5.asdatetime(), sdt5) + self.assertEqual(dt6.asdatetime(), sdt5) + self.assertEqual(dt5, dt6) + self.assertEqual(dt5.asdatetime().tzinfo, tz) + self.assertEqual(dt6.asdatetime().tzinfo, tz) + + def testBasicTZ(self): + # psycopg2 supplies it's own tzinfo instances, with no `zone` attribute + tz = FixedOffset(60, 'GMT+1') + dt1 = datetime(2008, 8, 5, 12, 0, tzinfo=tz) + DT = DateTime(dt1) + dt2 = DT.asdatetime() + offset1 = dt1.tzinfo.utcoffset(dt1) + offset2 = dt2.tzinfo.utcoffset(dt2) + self.assertEqual(offset1, offset2) + + def testEDTTimezone(self): + # should be able to parse EDT timezones: see lp:599856. + dt = DateTime("Mon, 28 Jun 2010 10:12:25 EDT") + self.assertEqual(dt.Day(), 'Monday') + self.assertEqual(dt.day(), 28) + self.assertEqual(dt.Month(), 'June') + self.assertEqual(dt.timezone(), 'GMT-4') + + def testParseISO8601(self): + parsed = DateTime()._parse_iso8601('2010-10-10') + self.assertEqual(parsed, (2010, 10, 10, 0, 0, 0, 'GMT+0000')) + + def test_interface(self): + from DateTime.interfaces import IDateTime + self.assertTrue(IDateTime.providedBy(DateTime())) + + def test_security(self): + dt = DateTime() + self.assertEqual(dt.__roles__, None) + self.assertEqual(dt.__allow_access_to_unprotected_subobjects__, 1) + + def test_format(self): + dt = DateTime(1968, 3, 10, 23, 45, 0, 'Europe/Vienna') + fmt = '%d.%m.%Y %H:%M' + result = dt.strftime(fmt) + unformatted_result = '1968/03/10 23:45:00 Europe/Vienna' + self.assertEqual(result, f'{dt:%d.%m.%Y %H:%M}') + self.assertEqual(unformatted_result, f'{dt}') + self.assertEqual(unformatted_result, f'{dt}') + self.assertEqual(result, f'{dt:{fmt}}') + self.assertEqual(unformatted_result, f'{dt:}') + self.assertEqual(unformatted_result, f'{dt}') + + +def test_suite(): + import doctest + return unittest.TestSuite([ + unittest.defaultTestLoader.loadTestsFromTestCase(DateTimeTests), + doctest.DocFileSuite('DateTime.txt', package='DateTime'), + doctest.DocFileSuite('pytz.txt', package='DateTime'), + ]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libXau.6.0.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libXau.6.0.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..fde0a8ed3c07d868796bf743c866c4ac67ead719 GIT binary patch literal 70048 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 Y2`~XBzyz286JP>NfC(^x|3?J=3orZQ-v9sr literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlicommon.1.1.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlicommon.1.1.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..39b7ee8a1210d647b621013ac6d3c805f4d3e180 GIT binary patch literal 201200 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 U1ab)E5Xd2rLm-F1|9cSlPf0K4SO5S3 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlidec.1.1.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libbrotlidec.1.1.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..89862cd15a25469626a814d7c47042c9bfc0ae26 GIT binary patch literal 104544 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⁣p}YWdo<`tY8Ok;LH!^D>0)Ycf#2~-_<@|;;D_?+ znzey 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

A#uz_1O1Q_}fzWYi9WA$!+&R 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 NC;$`y3jCiF_%By&6pH`= literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libharfbuzz.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libharfbuzz.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..196a377a1f8fe5324e268cab5f25c0817e80867e GIT binary patch literal 4348768 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

@zFh-`Hy#2E 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�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 yc#(*&k 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[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

3CYWAM79#+G@*orq94m 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%0AuFma!2;O$Q*hxKPUb;^9zHG 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

!0lT&%Esc^Bi>k?PpC6f zqw>WL=I(fCJymDtD|VNkuch;oEv5oo0e+y{lR@5?-Pf!5NG$Iuq7U&_nLbLM-iFU~ zABM&!dSq;NUuJJUD7=}mcDOrZ`2RuvyF7ZM4}3u7DOp}I??1%*sy%QX4jfLC_ir=_ zzw|3vv*yQ@J_K`B9)RB-^P@OGE#2^Zwad7~%WtuE!+p2m8lN{$X*g<+>s;CP(${|` zr#QxcK0I!2kU5$&>48>0lC8P%PcS>8)$w<*d?%>MZHOEWm z=-GiGo&0=SxR#L11dm=CguFN>Dicg+?<#!y>F?UUYP);;i0EA-k^Pu^XA)*hpPu zOyeZJ!ENJY^jiee3HyZitdE6HgeQlifE>eF(3Z^`eQT}7zl+9rV=u~se?RB`?2eo# z$MesoJa~f{J8@6u!S{S+$GR`_8Ewv!!)ukS^K^idooRXS>(p0PG2K0r2fv#Bl=I|p z`>ANG&!(KGjmY1T^5EM)Qn4TQgWoj=(si=^eEIC|#?U=#?!F9U?bcp&KrI{4)$#Mv zm(@7eN_4cR^5A1Ir0AWHMm;+|rHp9txjguAo#eSZ_|R^uq8ranDcdEbid`z+k)0#^ zvaT$dm!}ehXhW2=jq!O=r&OY3ckH>+OlFeiWQI5&Xiwg=TsAuSFBX=dBqv4&W`c;R5n6nn-p!m2Rqfpf-A8+ z&mMrk{J62p(F9h--K+1~^7?vOY#^_F^KF4&wpb>EO$II-_#QJZu=8WMpuJRFczu`g zn5etR^xQLLACBAl#>f z4&;^}hx=GM`t|;>A>}%1{Y?1nU|q&?Mu?TN*Jo{O=A=S5>oDEfC43GW3KTa`e&oSH z;l=J=tA5s87C>M5VE7e!Mmyd8c<}A+TXOWNn7yOX-h-Zu$L>oNe^WH& zaw=6`>maJDJiqnCvHQ5YbTs*uI$KD6i>8&E=C2jGwVEJ0KkIci=F#O>ZqfNdQM)Ui z3iD-cK7h4J`GA~V<<_C@qpTmF^3P^-^2FtO_a^cPpGQ7I>Uxx?v&wBS*MrUR{Km_@ z^Q#W9wsucm%G_FT<#&I6W1u{#y(GW!bkUP&5nP`NAG`H8*%MXkjS2c!8LdrUV01RJ zO(uEt;^-W!(~@=4@SM`$fBbm|Y1YA%*qW3_J38mH#+uzG`C3AVIxMi>)rGCI6waT^e5dR`54R!3YsS;ll$GAgTt!v z9Z4?Wg9j|Kk%!M z4E;sxJcip@(OBijuXX)P2WSo=I#J)@_`JRoJYu$KL}RKKmXF)LReGFqvN2_APJu3C ze3_U_@xf)uG9!%N&#@TonK)JB^yu_|onPn8@&88O<2dE4L7(FPJsz9R>YUmMM+L8G-&KHrkRea(b;V3 zvSmA%=Pu=m;lmuGXO!u{zZooH2Ri?x@91(qxz0k=J}I?1H)^w&+^YcpW)AmVLyM7q?`I{R-T-2e#gLa@-}J5^d$a9??s$Xi>%L_6in&o zeh$fZ!FLXA%O`mya}~4k)5f|da}HDRvDd{%67$X6nvduF!()^5LwV=xY-4Vou6>sa z*t->@trR$gOVQ!^`z6aN?m*08_2lmD_|3Lg5m?Ld2Y9j^e~|CLp%Q-(PrLZTrmdU- zK_Bu9-_jUtIbI4=3>kVh)NcXwRk9C*JTOt4l1Qop=MW2JN-9cf=ds$vg9Jkqs6rK(-AM zYfwz1t34xxHklhu^Y?YQ+FP&HI>qC?(`oMEifDoXPlTkLAPs z*R!#%x$n+BmWQ#&b5~*zo$SqXa(kAwwR>U^C)I*0|Fpy)*6uAah+W-dc|CiI+WFLz zanfzlckiTJ5A!Ekw=!8L4bSayn?UU-eq0rUNGYe7z48L9%8s%h;_!RrS=z|Zwa?1E zG5OK$v9$5+^D(<3+Xel&XI7nJk$$Pf6h zXV0V_X<(1%uIQ1Qh&ekwGQrx~J$j_M7F=m^r&Q6~_!!uAQ64(Bob9_n-n{@h)ZzAN z@c$+J_u`CyH+tkv#HO#bwGGe5OOfl+BX6MGXP7_fkqeS_((s(p&U1R?*{Vkr56Q6( zTe-JK@l=c3;t$OgzYw$NAkLszNC&Zuj`k%(TJtbp2A@JP4(*q;wb*v{WX=qVD*x1t z{GJ;W!tIzAXam1jrr*@w^3z_fk!Le@mnV<6?VO89=srYIi? zn!n8I)#ekwp3W3-a!%`)_3Sji-YH&x;aM?WfB1ebCe@8E*rhlTvdiDAslA7H=BM{O zjNkT~6WEK2pQ*cwG*60OWg6Rtwf35}2lKn!onbL98QOzTZ}4&lr|rtwt^XCRr}gd=?yujI`=;JPKF1sRxb?J=?hi2-cVRv44E2Sru&4G- zy_o*Ap5}1->S(Obro7mTksTdDVEZ}uhsGsmppmIs_fs5SG3=M#5a}Ugf_Oq@p3Z$! zZF|AKsTd6H)iH^1t zd(po7ckiaVM4TP-oPEgo;wiSS`7y|~ZLH7!lFy#95ARW5@baFr5AUQu-#+|yG}dR6 zefYrjBio1n`o8DvLqESw`npQbqj!>Jp0f|N-u|3@_)OY|-?;8M`|$70J{A7df zKFp3Me`yN&O9zm@IJ$jPugAA>c}q9m8|Ga5`=%7bmaVIOQytAZfA`QK?TylYoACKz zL+)JO40(pyw-i2SPgOsAq=-S2(;V%yIw;y_buix-4|TWe`yxJv3}Ls0`>tApLd##Z zCx=|Y{>r|qm+2XB3^q5|`HH=-!mm4vPd?mtW%XH$4)+Pg_g&dL)}ogIo8|Z@zLMB? zHL#qVD`MuSsElGS#HRgyS7uj|2c)VD>Zjy8*BvKu z|FpeRhV#VUsr_xdVUG6!$+3ELCW2 zq&Ps6_97tzZJ(3m?oP%5{Jm2zR-3^6bnKmaf!cf&!Je`M*<@jP?+MOV7E z@JqVkpUBVH)XILTZqC-0pVGy74$3*QeN);iK@L#gsxaqB?ftiYTdooLN6m^&E*bi{ zo}ClrAI;$zc|{NK>{0mx$7gnrlPdl4CsNVR43V%yDBjc|^xE{Lvl4oYZ$)LuJRdGX0K z@HrNmtBSe$cmrp$wT7^$PFXyOeo#vgxJF_p)g2iKR?c+(7#=zxy7>n4i&ecXmdP;3me> z)14=Wjwgg6++sG!q&plerNcs4N*AZXV*5^+AIrt0UMJ-qryWPbqFaN79KOGnD&yu} z#1IzB8!YrASR^}jmN$D;hkJ>a+!(>3HgX3_UeOoNB}+{1@p~0zd>cHEUbyv#jt@q^ ze|5^bgbYmK3ny!T>&6IAR?$R$Cvx_pI+9DZ^7v$%Xf00mNZ6;hXW!?Yhz@Pt4%&VH z<|sA>tX;_Q5At7ofOi}a-D7e9y2<2sh0dfK`glHrx#$G<>yi07`|^3nou(+)z2gGb z<`)D7lRu9&7D}I6vuI!5BQI=jp{ww&2l~<6?k}08I>%M&WV_ZZn)L!VSDxQgiuJYN!0)*Ir&yPFR|#@OcW}5hZ|O4VZ>8?a%*_fOU$|dz z{-fX*Uu^A}vyRlcWc#17>Mrr%twCnyPc%Qm$B*boW9hsolE1zC6|&>kEc*R{JJwyu z_+7bx+;=PY=1RF{$~{Oq_7a!N>D(79cTJ^So^rpS9C^{@a%Z`6*H_9dr`#6GamP!! zobvRoy<02g+9~%P$`R8km%GW8TURN!fpTA`+-$F0kDI#<(cCfK66L-~IdoRJy(e6` zb(M1clQHudf>~kc=E5C-4|xF&<$&dnhNcY%h&yPx)huWS7}X@VK*= z#2;%So%vU2%+comyc^q_vjCM(y*aWynKSO730AJj1m_v?&0h~bMtl!VCX(1Fm;IAY})a6H8$(b)S{$^-)gk zI~{*;G{3S{8?av%@LzMw{=zs}$EeTlk938tMZ7`fWZY_%+`XK9P^$_E`M# zo!C>@6&89??9HV6&CfhhW-6Hd~Xtl{F&hOP0!2BJLc%7wkBNJBWIM$`EwK5oX#igg}204l9SkvWuE;m zy2;5ZZ0M;PXK$Xe&_$*-C}tW0;v zi=)A>eE*oeEZ-k{xd~eg+?$W4bF?)c=5Pve-6>s9%$zsLdv|T(9eX0D<}@Fab>%hg zt|u;;7w{||kMw+U$pP^qa!Pwo?}qo}Z;b;^_6YafU78-npO*A=XG1yIuuo_+y0}$m zX-Uta;NY*<{7v(7y!u5aPVIsxyLqSh*|KbQnJG#$q^d{~5~DjCS!%C2-WaJ5%fa~GEZ^=*wW>}BI#=#6Ehai8Rs9qYJP?q%bi z=#6Ehaqsx|B%P05=N&iJai`F3y*0MC0NYe(uou}h+BLS7>@V`-MVn6j@+@0pd)NNX z*NcyDEPQFULl!xP{W+F3wv*rS^sTY|_s1(X=~EgzG68;$?JeHn*`)syl@X0AHeZjw zHC~NXcfelyKMhfyhQFp*Z4<0VfA+HuWVV6yBJ$Q=RCY_2~Upez!$y8uE`=3mGPEj6W5(XUgjul#zaC zEuu&c*EE&K7MP+seAlsoJRLiN4XB*UnD3OLlZ78!9|bo(E5Qr!?BJXf)03QiGAKB~ zOM{0OhXd*ILCR#ftNRQO7mN5^OAm9uW~hUyXXB@@hsUCWeV)axDBGpz&jlXs?GFrT zw71NoJ!FxUNuxdIyX@+Hp!hpmoIjNGcam`sty#wAD`l+Pur1wuoy~mZh<~0E#Xn^S zi7q+AqBygy9WA}U+-v={NAp!rz9#AM{oKV9qemaN@SfJKe7V{M&d9Oqk^iOf zn2#cyAU|&O94BL*WJ9 zv{;YsJ-0a2LBt-;X`3(KHuv^merzuC;d;O7;`bNJF@_|(_;AMO_;24n`$?9s6Zdo^ z%WEA)a)H>iau2J@C+8GD+R2xjd!jXejR(AbnEyIMYX^B-Mz7>yi3c>lhmQ+=W9y6O zAEK<&jau_>kxmn?E)lNCd%L7!**iw+AkwFWMxxz}i!uz~RuBFBgq=%JBt{PEzn9UFqmuv`ydP zn*a3R@!Vu@&3|i4`kFuEzSD!Tb2V|@<{9(KFdo!W*ueVq@YQh`uV=i%tMJ+H*Ju5{ z>wtLu67>fY^{@8o@5kDmn~T17aMbSMi2nPj|MNusOT79o_3N{)K5%`!es;o|Mc+%* zKgX-T)UUsq`m5vho2g$+)L-D$-{jZ7mipJm>*uN8ov1(8tKYzRg5~jFL;Y*w^_Nrs z6N&opV;TQ*{Q6f@|LS=CcIw}fsIPd~5#GG@t)SkDc)bnOTb-y^i#Czt!MS|a^4Y>? ze+nu;VJ)96e2^V>Z@I?VBA%NW%paK9HeWF`Cs%U3)Bnxc#D0C`n{2A}$S<9jE}5(~ z*duigV-#Bv4tyTsjD5pT3-Bv;n@d?oZ)4qI7UgWci8h;jJVw0Q8?J?~J@uDI6`EPE zJ0XD&&4a6dm|y<_@OeQn->;vi{_I43&BHf$>{wTx|Haf>9Iw|;y@M0=Kxujm($@_& z@OH9?w_icKKHi`S!`m<37TIyp+Ke0H3H}(9I9mAPLWwow->a?{U)30I@yD3N4fTYZ z-bB4!8RL9!jCa%+V`q&q9$RmWU!Pmpz!<-hfK_8Wx84}3C;ItZqTa5I@px~HD{74K ziW*~lalJ7ff2@u1y$M(~#%cA&NIi}5ZHaojGR9AER=4BvV-sV1bwsOk>Cf>v{_gqe z5Btnw|C`;~qW(_`R<>aiC{N7M^DVSr=Dj36cO75of71<%UY;1wT(AE7{rX9|rhfMF z8x|dvsPD^+8~pl7-lu*u^$$tZ*F1dXDNkmcgUrC*E6W<{m8iF0qTa5|!({G~aPxqC zkI4)-5C3u1&d&pDQmONBYA$%})Sj0W@{Knx`Wfx}a>bvA?VO=so=0yUT>a(Lzc*3e zp9caRmHOU1xccqX?@83xJS?s;53XMG#2XiFOw`+zdANXkI@~^1&n8 zH~Sa;b}n_xIPz%SVEyGh%LlnW0jtJ%h(E?8ZmFj{k(G&hyE4Wl-WU}x^5@)*@z}%| z9Y4RW-WYop6qHkSdIDCBv2VM_PsuS-Z#nhmCF<22BmPdkn5m27e2YE<^Of%DGMgvG zPqK00Crt(qVOc-6SiRQZ%D*tJyl)%eiW*|ayRvVCNXcn|KFc6%Kk@~m$X=z!)L0W zx|_!HZE|M(@qF!BKAx+-8z0XHo~iM)SI6FkXXQ2YZa`-egI6xZCI11u__4W&p5Fkx z%2kT|>6i3H`M2T?i<3k?{{fLn>*n=LLGD~SPS3zk_Xc-=^ufraL)b?~ndYc2=a{_8>T-@rGxs^oCT=w+ zddE2?lCwwieo*-g%!Qq0vYh*v=2GrBep2bfNjvKAn3wuXxt}L7~F`uj$@V%2u7vsBvq(Trg;Uu}5uB%SwI|!?awd z61Z6Y*n+~gYCD5uXoDUkJ>!l@S(M!u-zu^)9TA}uN!wY zH$`_qUq$&?%(hfn+qd&OX-l}zWrQ>410B=ROzehwVSLhus}cuvzB+g3G3U|UfTA^G zbnCM-hBmNwOEgXlr{LyZI$Si~%dx6`#|3pM&92$|*LNsT>f0{+9_h2N!$vwe}=jU&42M4^Lcw%T9YEWv<{;rR%ezjqr>zM;FO+NhS+_ z%%$l3!2k6*I(Yu5qCw%27`vRvAHd9aDzjn3#3Sr_sr{WXkVbN_YcX5;H!Bedn(xg7aY zch2Au#jv(XMle606<$T_(D32HE3lMld1!$rZ#?{tV!qaT^R-`MzO?3|xOH8-ECJ_x zJvfIhO~9FUM*1jVe6t5*zuE-%8oOv9oXZ+xPQdnB+VT19B~E^T)Bmt`YqaUng66={ z(Prwz)|ULSB>H}thnFv=;N=^{Nn*Bd8Xc7?GFd$B@-%}RqC1`=oJgyKK`fjE~H~`4$@#x;81h-U)WJM(cWlrI7x6sJTO~u zRCr*M?x<7F)u><@#hCqj!S_pyxq?S;%zm4Rx&JkD8_}KJU#<0cH;zAp1HBVI@GGm~ zPvFhb-hDQ)AsM1!l8%!LiP9YsJ6gYzWJ@yzENL4`rP!SkYU>9PKgu;_PxS4lt3Soy>hxF6!=O%1c_{dj z{UhdK)Sk0?_V3|>NBscLdbhuhHNvhSU^yw6dcyDU0pK6)+1%&Naa&maaqhI%QJ?i7 zT9^P`#P}kOr%DxhV0onx9qCL7$p*94kOkY2Z=sy@_};6#p7PGdlYSAei?@_VCR!H_ z#q1D|Zd6yfvC>sO?KELy2He%!gnb!sS8F$IDK9}bnBSAmhx{+E${iY z;I$mbVV>Rg%@?(5B6nkfX#{kDAQ zUud0NdvD}Bh2t2#zxwiDCV0T3JIlu|Rr0=)XR*BOiVDAOi1_twv?m^gKBi8;JkFyd zoyB7DIpmAh6P3RKZf-Ny%*w^j?X-81zx!U^JKryPc4t?A z=}`A*zz zT&l<{&4u%Uui>mO=|uUGic^cuBnR<y`Ms<^D?i2NADi!^;5B9^;rFf*u1E5FX?q@RKb?NB{BO;( z!HVCj{8P#Am+>9bH}H-xA4M0ECkyzDBpX#$<%G}Cloei&qpa?2l>AlPC8mcHu!x6M zF4V7{JqAr^zSMs?2IAF)*VBE|c)$ zJzf!CkK{+>;m6(ONBo#^pYYTAy2AIReLrHB;9!m-U;1hFBlby*xq`>qHmMJHJwM_P z;K0eur^}CM%v8=*t-$Wld`Yr+AL6>~mx^eheBUKH;=IdQ?{)Y85i5N)|8uN6qDLyZ zsr;5bjjcW0H=8vfY>jCqyU_=wFb>;?PEzdI^d;qFyO`~X4LXlDRTp_(wA^>c@z9mEvx#73!%=XBz=(YeG)nkH}6 z;Y4c`gS^YFy0XXC9k4-kW}WGF#-Q`d^Ztg2JzzNo6QyQTeVdEj(S z2lFnzRc`n3|0TOTJj>G2YzF)Kp(jFG>?lp|8Qc)^v24xG(vlwKpg$?wMtsaXN#^y! zKijZdu(=KN>@HjIV&`~*2etW!H->FWMoPXu%74j4_45$)XtEKy zy#pFp zGR(#Mg$wA?ttEf=l(?Tw&QaMH+MnN=W7++R*UV}R*3Rn46dJG@FFG@OyJVg7w-vJu z;q%s|z^89V3tzHb9i4yvp#+`#bDRxzm3$n@prpV32GLX$A9Mb8FYSpoymn{(=O23h^C1qGlDEvGbQ(C0ts#GR7yReOUGtxf z2I~3GKk0P%Su*q^{TA)RM|J#Xy92reUOoR{ZGivWEnM$i{_|R$?Y=kp&n&7xWB&6& zXY8E+d^tQ^CDZdMetc=C{b!@8im$Qr{__ujb$9vCOKIyX@ORASPRM@W5B2@$je-Mt z5c$t*pU!o-+Y)20;4$5v4c+sfjbHqAxc6Awp=^7`{O7#vhaBgPG*tV~*lrtu zk+Wb}Z&^C@fAt&tPkAs!ew#0h&DNEjZoaV2ZhzNh_}lDtQ~7u3H@=ztJv*bAdROV$ zg2)$a#+S`58M=aJee8#Ogtq$e>Cn}~4=unpY!1(A?`Xex=q}1#g&w~P`|!6}&N0aZ z!?%tPhEL_$5qxxBdu47GcJIhHMEOq@f1n#(*@dm?Y)8cjHjqPi2V=T3KfUK+?EK#l z3($Ub#m!|e=2o`Nzd71xC!4wvdyx0VdmF+vxUM{Y0ncRDw(yJ?wE4*HnX4Q6>`Qyr zg9GX8?09S-zQ;|*)>mwl`WA!0CJt><&+cuH+fdSlH(Bi2Af$^!LHVtN@wY!o}e`-G~uht?-Pyb465Ea_&|-pW4Rj+ zkFBxEcTmov`MU6p#dZ`+f>)KJ*gGfmeUB>pzGo8Sig*&d*YgQJw=F^2*&6p$M84%G zf1|O6zWh4`!wmZ6 zR6fKbiYGC5jH#&Shx3d*r17<)s7>+{iuk_8LCUop9IPs@2bC&zq~%|rcch0DLsC2@ zxHKqiYYqw*&~8WMZ}7g@Rhro|RkQ&vzsa60l`TCgSppsK41HPrHqRO3mralHOl?K6 z@1oXM?RnIees`2E>50kX2zL4GGv^2M(_nVGdmA}IPEJZM6Z2H;dS9Ih!CHASH!E0q zMzlAiEysHI`3;563BjgWubf|4f8d%$d7dp_(@=Qmw5-83s4-CQC~&%P*1d<^MVn{N z`u-ug%)}KMn{d#2&#Cht(RXIzM8&+@YP7%2wSPxL;Xk7GW8?Jnvdbxuy(pR^o<2|Z z1-VMafV*1G25-3&g9984x$(hEz_G>W1yk<2>|%?-&pM-K++KObR<<#iqVwTeQqI@W ze59TimH1 zcoaINh|Df3N2_W4#9N8u9q1Iaxkw-3zx_tcw83{Hx)`2ny#c)~8x{ShdFw^TDL(d<`$9OB=a!q5DR55bqgH0e4o5G< z{WAsl*v=n@$84RZaaF*1EK7zOPvJkdcjIZn@XP`*wJWc{vqK~Pl_o{9$~e+wifkMRo(f zbiCwr17~P;|1zTEMsyC(I2XZkBlP~&{I>DtiMKQMCg`a3q;P(Zjp$Cab@|1D!K0b1 z7oX0C@m$Fc*{{JVZNuMv|8~W-Y@M$wyJRRht!?;PZ@!XzzXDuYIqG&U4z@l@ef@6? zv=(_-PXO%4oPjD6G@okMwfPyITfaQl8uWKm zjx}e8gXDOLsZTZ89N|W7eM@!J4xi+^f9Kh6`8YrQ5BzqtpKSXe(H-qRPMOa3B}4lt zepVyKNc_dhx;5MfsblsbG^Bbta8{d#y!C*He?)t^$5+o_O^O9sNc8fm42}`!hV?N+=0wn5PU^=PmY;$$fi0wS^J9|Jj;MbcBr$NKP5a% zegjLcA+nc{;o#!SYFE#LSwZ1`%E^C0-DfWme+gflvk*1Qm6PbmpN11(C8wXudZmm=2KTP zQ?x7`%YH#W3^Pw#L^pr=m-sv#8iwQG6=FE^bry4Jd-jOYY0sYM|7PR=>GR6-iwuDuQ}aZ=&iKsU zJrKK|&so$zv(aq&eO<0gdt^&XR?E-&+e5X_n1+t5J==5pF81sJ7yLJcJ)A{7J8C-i zN#lKoa5meavP}lC>vqiHgPb?MrVq)F!MSb44`#wM+yc&UyYAs9*R|~v?g`YqrInF9 zQMqL<7J1E*d9}v&lh`Im->cJ&*T#j(;qloQO7a2elP5__T|m zPtA>BsjY8)`^$@Qz)!ZOG7WnleaZTAc)lLv9N?MO(yM6r0O%Kg)aVzvYqWU)zUkz~ zTeaT5EZQdvE@JN_S6{+=&a1M$uF3bOO82^RU%k3H+Ldf#J!GoRB9yE)-<&=l!In2V z1fCcj0^`r2z4+OMo~(}Kt8_@k#t36C(A{v3xfbn!&v)p22;eH8_qD^5tIpn5zP0HL z)<30_HhdHfk0f)|#vRmedKzS(?iO%; zjYalp-qEGS+^;+4mG>;pejK zYsBXBPs@G^BR0lc-iF14;B>GIPIurRTm^D6h=}O|)^5uGd8P#c; z&O81KKP|KLd&v;`cDQV3VXq9Hz}V5P>!b5k(QU(nJeLgEz`9CXHj**k^KZ#7lbszs zlP(H%L&M@oKUy1lE}r>!$|wCG&5wM`{%Gvc_{}Dezb`!%J3l>w^D>7&_1zr8xsmp* zKL5dkoq2Bfqs*I`^CWGlY$b+!M)!_(w+3E`sW}~1js@Xw{Bj#-!Xt-Fe(^uYUPk?% znF-=PS;SB3*PV}PegJ1=PSl*qX5u@yYQ~h@_=!igU^gZ8?Z|a!vQCszH;TdE9L1Ss zljv?0;4C&y-u#B#xHb3Z?rD8gx>tCB#wvZc$JdpjaoXBQEBab=;_?Ue4jWIo+vXeT zx3!0EFYmSU{LS)uRiyKY_Y^z8)9K7z>fWpfhXdd{=Icezh0hk|fOScu)iVAVLz+MQ zD$y*k#e68ry7+=(Q?e(KYbLjB?6NOKPr$5k=9teI-rA!*h2FYrt})mGFTm@e?}!X2 zYVW3e%}$*^(?kq$|26mjWI@*AUIWl9a-gW3EY45`$H9uc^R-kDKAWp|jJJ{f7`Y3t z>=A$1oKjc&CKxj>+SXIr?Yv#EB4d*)Zg3fr$%6`XFoObek}IWj0>vmr$O5A?WfN%$D_5M z{x4+*vK9NO$p1ZIKivb&;-mU{!}A>@nIzp%mP2XJYRIM&(ScR6sZ_0tSRb)<5&2T` zna5zM>B2#TRGpht6^GD*=~ejpR9cjddjaZ)~GRbX53zM&+#S+Zr^)aXy`{Gd)7(2?y?fF?}$j@TYD_z%6|Jua-n#bm!b zxA7=&zkPLdW@Fxqr_1Igrd>XhUHSq0t1F6;K89~08{q}eNg|fLNiouY{bW2wI`B8k zU9(vBy+I{@ony@M%%LJ}PqoN<> zR~jBOZSxsZIrcE~o?yQEPwL4uohp6UhyH2h`*7?Ttpzn~v3QU4U%XxDXEg1Ko&#HJ z@M5;!*wijMGTdvDkMytq9(v{d%BuK83LbLf+KL(MW^kW~tyXwXdYf2~?sL=`ZN@(? z$Dq~vs@O!tV(>4*b4Coe=w0d+CpK2@q0n4c=C{JLY4hvHlUt<6XSLcM9><^RkG(|U z`Vu_RKtG#LGQA$7bw?Y%d`jytMo-zqdL+DHv1HbGa`%MyCFqXAR(`k2mc=#rLRdZv*Ao_kmn$_Dn$;SRU>k_&+28=i8!3xCEGmxQOBst1N6$1DCKGK8;rViUR`CzK zHMunVC>uW~&yD-fw6Au0+k*mp5j!XElOIDCfDgr0*XcJlp3315nV)2Ohxq+AcmIKK z$=>dpev3?z+y`IQ5BnXi;#n=5iFof+2g4BXjA`$uXS+)mh_1E1C|msj;1tY~QNNLG z3hlug<-I4p-u_ALQ>nEsuQp7kQ~&>H>~37d3s>`h8tZ2f|Alw8qsL+~LFi=r>IQN` zL;ISX6We3f(Hv|&l09Id46X3kj&|ioP9mnk*_Mn&^4;Z=yp_J3Eun?~(4Y=d^P@&mAuzC-L{E_vrl6A+1Ade%jfOhK%^? ziP_tA|0lUDto=8Z?gZHl*;miw;a$aeV7kz3txZux=HfEWSD$Z`WU3IAlQ6T6Z@)jIsEj- zxb2mukNoyrTdB4{3QmygwoAfya}9|&#z*0hBmNgZ+Ws`a?;kqMCbIse>7IcWczd!YqqxFfzJS&$sgLy zAb)=SVYg?i8n#-rq_!L#{u$U}^y6JS{WwCqqGQP~?cbKJ6h6$ppuJST(u2vb>v%zOxhXnNLG&-)7;QV&zviAc ztPb^KV@c`T#bzacHII(=unXgLN5F&89R2lzSLuQVWPxOg*`#%B4u=EPS*UxE7I5d1 zhsS{hZS&PuDh^V3tlSP~M7ew|#rL|IC#?ZAW&-AT&6Gyg-)BNcy5sB$XQK$;&_L+d zg|-;we6&$5$J^!4k4N5xcZ9p~P2leO*!W~C(U0YV(4P3%~-|XJX6ME{@3taeanxLY!zOV zhv@3Pi}%D=rg3InvDP@mdzLdyzuMQJwnN;KXBpzT2%h(i$&hGFVYxSdCU||*^D^^} zIl8H>X+|zMa>hV5cT_L@R@N(}iVTkYkfLOQ$;o=LH)N_}1}ba5CAr(>Sew_TlOHBC z7)MRn7r||M5qz0`LB^%Q>F{D_dPcZ$cCuSnXv&etcYL;RkM?=&mnp1Y1-R>#ha-=Oj#M$d|C9D>=Su9RnL9Dq;Eu@p%S-C%ZqV(%f(ToH~l!urImZG zT&%_7bK(`9Bf>h;rdcfwg=3&|`7p8PFKV!}^9A!1KBD!gpXxS_X(%Yap{kAJ8w&DA z)P_FR25~pm^ust|)TZKo;Iw$J%b5f=i@)$p^@LyQGN-|mmU3LtlQAj0;A|0Rhs*(v z7@dux&W-qeW3BVlPSjaNj3L%f-s6EtZYv+#<{OzHeo!8R^t@t-@^QDJSG3OkYsFEt zMjHex2g$8s--_*Z>EjMb-Iu*hIs|>IykTsCqUj{zJBoGcJRoqsY1Wo~3x|Vm#bQHy z)~ChlyFCQU8Q3n}Pt2HSIph5^=G}o#GnktL+Q-I-=J#_MXsx+z_-yTC;9E9;#UQfW zx1!(e#3M>exNBuP@ee+w!+P#+=ac7?J*=k#{Ji=8C)ag7v2@>JT5eFUe# z_q4N;ev~u99#-W|gs~IaIObO5#4CjVPzH5Iu}s05EAL}aU)nE0&Y`n$ytdy!+ro?D zoYr6V;-1&)8T%r@qpevO%skI2#sN;k|BTK4E1na*18*9eJqLfYH72jG1#TR3-iSl90VQ&gV7P=674iV`=S-` zz<+>r3g==8x0?!T~*x8E)=U`Jr`2aQ-5w9tSSLFugw2`}7p|Kpg zQuNV^pV#{MbwA2oc_rrs5;HU%dT|dqnJdradFz#LF&gR{AH}Vh*J$2X8Z3F6_mzSt znyZzCgwJ^%FO|~Uo7rYxO zuQ|vu2S@Rr^D=r?@PFZzbC~}nJrm)>jnJ3tPj*iWzKFx)ozZ%>aH3d`aJE`FL)R(R zxeR;>Hut$I;*EPF-KpmqKf3gI{WduHZ(|T0YK)^8zkDTYOJk1mKl){^&3|hz zK})*}AD8<0z#kGm!dPgCkHf$R>zW~~yjz$FVZ#R96x?Ap=vvvJH=boS=%(fOW()Vd zEX1MFT?t$zczW>OC)eGLe$aTOQ{J#u`$+5G<)mC>*-o56V0KeXZ@1Uad&1V8Sj&Ew z4>E$Sy(zM_ZJZ6Et-VRM_S$HivXjPSYuB)WEM7rdq2BlGEXL=@{hS}MEep>R$CE8t z9s8=-GT15>>vsFg%r-!_I9ptCLD|R1o8rf=GJCt2!yZ4?*|EHr?W1*&%p~QlFSXwd z{6^o%?y)tJU{&i-NW+yifI(;{cJ6ojTq!qrm>e~H>&6e3=L*``zIq&I_QcP;9gRKq z!Vs?v)_w%%zP!LQg|G_v0_ zPa_-4c-k9iB$!#Ik!epmjkH!|S+=sqk6jSwarjj+9j)ux*`dgQoOlA6A%9c;*(2m* zZC~xJk0<1e%9(tbmqI&P@n(3YNZ3yp=W@KM7^7r?=v8q*#dqHKR%A=)Pgd-2-kWTp zjAV<+6Z+Lz4`q46Z*<^f#T^oae?PyDuGA zn7fYH(93qL)4AQ>d8K9!(pN1j;q`edTKYrC>u;H}B! zD{HXC;VWxjK7D4HpY|xHfw3I}F3sKtX2lv_%72|Xw}Uu>cuQxA3|h`{M!-{ucrUi@&22se`%ur0t9X%tK;?CssEBheeAHQ zM|ktrw}N^r;`KIAuQ^fAY}u4E29PtsxqR00*}`Xk3ZBb{b3}qIe2D9tY!aT_{t@;D z%n#rn7xT~YPX9OStQB9rA_KHuZ)cfFc1l)e8#W%vxO=1cns5Mpm*eWhfDJ!eUde^H9Xe>07@B3@o^ZU^}xcZ0s z^}RdVUHv@u|1(iv^YBe{O__ccGY^Y{`Msgcv3~ohcTb`oDE0FBJl!w~yyZN+{R-Ok z#{*3m-fmQX;Ovyh-*IEi_+w1s=%D=yCGMgBrv$7T<1PLelenRtaC38_-mZ*sfN?q6 zxTD4x&!{oRKA)eHW4!%&g$;~xNdi`l@!Wc2q@L*KoJ74{8RNa)7+2I7h_|0luo z*aR=3o}=fF*Tciw0}B0bx?#~a+V^>6u2=t~e*Gj}Q$Kt84U6ti)c0k^NBsIp-lu*u z^}m^@uX*?i_GnpVoP*3b$CDYtg(<0s^MOlG)wco+RSSv%HwSn1;- z$#Y!?7V?cZE?Scqk3SD@_3J0+f%?m-|Mog~!r*gav9&eOSyK3zK5eSrG&WVhMB=(olG7?U`DU|J!6(2a{`Ct%eW5AnyC z#4YufQ}5tJyIoDDzWt zjMQ6Bz1~Ei(-S2gfD8b907 zihTI0c5BVSSfB6Yoc&#nHO&_%exw+XVhPE!mb2JRzRYoFEnmM?xzFT`$)~|@cl++% zujlwBmQRKcpCLvj9#Xu*KWo{1ixUsEvzB|#jLWsSeDZQ8Mlp}|Aee@?E&wBKxkFvaInI{~u*_9^iW7qoTV4 zpC%W}xqw&>Yh{MBH_ozH&PnX0APyJCZm4gu8~XVTv779p?1xmH<0^F&uUS0sl&#Ol zVsbt`MB`Zx>@GHEIijqADlTlXnSF`PFu%lRHl2A&raCsmcr=d7fnP9mUSu(&wWqcn zVeyz_f#DqB*0@#fqplq1Z`=4Nr?^WCk2Pq_B-lnW@wzPEC@<*poYSXXX2 z<^J-Ur`8?dm6JVc?V+n1a=~N5OFQL$OF8n5rr!QYGx_z>yg3n*pw9X1 ze=z??N~0a@I^cQ zyzeOE!;2x5DmkJqpVP($Z`xWLV;h=S8QW{<`=DrU-pSZ<*q+SK`NDG_^rzhINDscVYrywm%E#dQ@*MMl zUmw92B;n(IGw_|elkgoir2?PMRC4$`q6U0NQa%RXVMiN$$3*b`Y%qa8-V45#H26|v zZ<2O@J*@)YPk;|Q+;N;(FGmevE&DZ@}0w>>a<;plY)_mGc37p&=m8;<7So2*!8{yz2KO+YorhJT!Z$IAr&i6&|9hszK-pjvycNxC1 z$$`Ik@G0Ky`0UICd`?dNF$v$fuP~qSbrF0|ao!`Gz2Hwrt;<**FU?nvuy zqI=;Hf0Z1H`o5qmd&oYCvL)ShIJtZK>M86o9>={;?Dfdb7&5z)eINn%b7sMft+8>| zl=2gA!$#7%Sez@})6uWJ$HEj2R=%kX#N7X zcX!`t@9)Hc+sJYJDEap#^3KT9EI+@M^Tv*4EP6*h<-E$?!=_#_%jMbgeDF5xK;8{F z-OT?%>gXByyQbIF@8GTBvxQC$^52!~it4stvk%-96kEZ?8ttcH|4k=2`J5Yv@)c(X z!+mo&!(Y#q^IvNmb9r_g{s3d>>nFaa+}`#jJ?zIST05LG@NcdS=%SB&pn+!A`#127 zAE9|sK3wL~pkU>HwxDpG=25-|eAri_O>%nQK)D^jCwZv3`o_x)=3GKY-|2Y2V*!vaV z59RT9icAjutME?H3)MeCW$#Nyj+aW_3A)x%1ISoa~bf!I3=q)nuD!Br0=RdUTO1& ztoq^Ue~Zi4#C*t4yPLd6Xos_F$Tz@;pZy-_3%u+1QTmOn5}oKw4)WuGr}5Fvj`w*c zzSDT7L1%Ucv-SkirmK_VK4s0L_JP@Z_V;y1azcEdTto4M?fv4n>Jb-UzgYU5Yag>a z3p)Vrk1$C)7}yY7Y;IsH+_g}nBJ;}&8k9u}f z0*}djO0|DA?RDg5^!R5VDsNKq^qY~~)qW;BmlzzXP9NvMEn`o{GU|%vdV%#-@57#p ze0eL+ys%fNT>gB@pYO^;FSlK{-RwNWKkaE8$jD-^MoSCz=zI;u=l{`=y9vz z!`rKw;34t9_)mNnu;*m@4K8k7+Xk^UhXXjnPjt=t`~KA78MHk5I+in(tmDZ%w~ycL zE7m?O{PhzwKIu z`trulMV{U6+KKL>S^@5j*A%N#+m|{yA^k)gNPVdNmPGp&;{ey&@LBvm{z-j=ZI$b~ zaj1Qr4V7b!L7%QCX3i51D(C%p{8|ftn&SvBYVV#1-d^VXtLmF~&|J|klkD>f;fC@m zlL5ak_;+kR{tHjN#MHE}TJ*CGTFx`>ao~6=Wd_4KMYpH3d~PexbCXQg7Tw+xhu<5V z+@Os1W4m&koqlU(d|Pq#jl@rZp_l;CH$1I;T8sU#Wb2^kfm4YxGd|l@l;E0+W?_VdK8FXrvsk^kDiW zJY0`%Ytn-+ztJbkwbPv^k~z}r@(aW(+OwxKJ>O0odrib++TSYv7T%Z_qvs^Qn2aMI zPi6gb#-qqOwR@4p#=~<++nijB>a^0g_8yr%&Kc@H{s$uY7PcMEkNS87TqOA_K7LR3 zC&useX}AxN_^os&{p*e(YondK-E27Traz%)a^QMidmXkl*s8%s%gY#;o(@N59h zrHzOF-8^b6xmm~v^qT3T?Gsiyx#!Pkavsl+JjpNZY0M!H8>2I*`JX$Gwo3SaC48;z z!Q+QVazp>&DAwv*KfaW^~=-I;@*WBWAZFTTd%@t_=jUr2LFT6lrRLY*9Y-`*O@Y2jP2 z2nM~&fG7Ooo8GrN%f4qP4Dc`8G^@%G0VXUqo?y!4^>F4r)*hNX8pe{U9_ zz}DpJ+bJ)n+{t`mcuC+;Z3<6wDR(cQUSNGuvd$=BOI=$}=}+fG=+FnC!z|GzriY8y6 zxqAFK)SBLp;4Rnl#;&-T8;{PE>IANC@Ub2oV>dYa)_gMUn;g|#l`6EZb}ZH*Swely zkI{DfB}3+`K##R(T6L5DitM$f=xiz5Z;9+vj9h#a`98Gg&9etfX9SDE0X*7cSE=Li z6*v$d8Z7~z@w$J`N_(6q+#H8A=J5pWRLM{e9=%iBz07k4_@#3j@I@q#1fy*67;e0} zZjDiO7VgDoPDwwQ?gZDh=A|qTnakK2CE(z~-$|FRnG&#%RB==0%l3jT=DGf>?J(Zs z&0k`EgkxyjbaMt9;pMVBnOFRu^1goaNBEz^hH04;wj1MD5BIx`j8|^Z?8QSTQ>G((D1OVK_Ww2Z{}BEkGGud=&ur~%&urb;!XB(> zAHDWh-_8Gy(!o7CueP&vVbA!PoT<=$F!>r6%3gZOGUu-YTQ|=J=VEUG-`9a}V6J3a zu)?i#Op@KBa*U_-QfyW1Ma5QBPxm-~fjXuWu}@#u6Q1oL7&ZgL&#+bGW2(OHWNDy} z0ql3pvB~UQPU@;VHb2?aB1olpo=@d%71-f0P)!wcAd+j74WZyf|uCwxnc|&Yp?2U8?v{$+n-O ztb_Sv`iZr@&zk#RkZAj_)^@rtAb8w4g&N~F__`w>Y`vNN6|!|C&uht;TJ|z)o45DY zu$OgC-6Thc(9**9#BFB9q+{|KSgPcGdt6sY50AxWCiZsw0-H-uucWjoU3CoQl=~#Q zm)#eWU!#Og`mo9lPU&wj`)u$YcudqYa}ca4NcxooPHQ z+7MqrFY$o?*L;4|DtrQ%isveRo4=&hIlgpC-TWPW2;tjC{16@%tPeMW+srw^_TP-#1#H?+3MfK5!}f6Z%W_ zr!h|s^qU#s+M0SzobH9TlF^&=G(61|fX#4?Qs_LfEUCNl<`I6Ed zb$J4s_3ci@(JZD4%+evbah$)3?z1>eqHGI#HNcWj&JmM#GmHRFwc$Xf8~$e z-5b)PmGyigyYDNKpGKSg_(TgBZ=O#n^og|gVzh`)B)#waqL+JjPxO`Wi(Y|Wl+A9H zU9d>=CO9L1$?EqmD99c$9}Hj5`pZ{*u-|HIf`!}xd)Lmp85;&Z&j+;Qnma$)~(9tl1NXo z594;@cW4Uw+Y(@h$Okl8&U@L6#F2N(uT$HynXCMo8v4u0G|}4sp`K_$^5ymLgKxtu zYd8Zdd)pJ=M<# zkuz1}@#hVj!Cxbg4Ji6I8p7sQezDC3{5n8e#v9Db&aAOeH{I4w;8*3uKbpr(rdo%j zojL9Fw)kH>_u~`)7Uq)Bj%?c`kwCw{-!qwgV3=I}p4Twsgt)4GGWRE)n$6}jU0>uoz3 z7wA-Mjj@Y%p7FRq3T~_Lno>qGV|T|O=5gPdv!Cz6R;^_}Ph}6MZ$BT!f1BIT-m$ge z8uqizt@*~#kXuVNekBGm$UTfn`*~+$5Q~7x$!^6`ec3I0dL-Iv02fz{L??A*(Xr|u zoiF-2QvFA~?DShW$DY6Mw-wnt$ymp9Z%mUDW2)O;LQd`*&6kstFZE#knC|FG{(vRfkuxP>B_VScG zzO3at?=A6xSsEL2=Hdfy*184%YsvXq!z(??3KJZh&4Clbg;saks9jyyqHXQk#@ZktP@D{BL$_Ktw z_qww-xJq{j$Y(`fjKT-r65s>R1fE(x@C5g63_h@pXAk(mN5UJDRgzz0@qs`63C&07 zr>6P9`>S1K#?JV_Q&?-2tgYn(56=u?-WebGK6uTweLrI`{`Gv|ZHcy@1wQbmz0n80 z2AcQnsONm(U`lK~*RuyikK(~y^|kLrhVG;fyeUZdz*(EW(D&Qhec-9{Yx}@Q5YLR+ zEs-G=>t#q@Q~sIZ<7BRP$t$#%G{3C2ma~@BiUrKx$fGy!H^-I7qex( zF**9$Ss(Z*#`l~L9K}Ywb@-2gb7wbx2b;f^54?CNZZ}@Zf8TCYesm2V*yc9H2i_#R zv4wV$cH_?azy;cpK9{ew!Dzm+20I!b_!4k&-$-=g`DiXLbQ`f1^|@00OAca(w5xyU zUhypKAk%ME{-xg*zMgWdl0NXo-k9E&7*pN$Xv>cko=H2JFM|a+`A!ek*IT=xoUCdy zk~P%D2L1cy|4x>D z6o0dpENl8}T$a6z|Gq4%;{%&4OYwnCmi_rJ)w0a@fnN@v{k{9ZhkrcP2j1d*;467= zK2?@ATx8`9{Fe`W($CBCX$$tBeBdqefjj>^Y9Dx$=L2t%58QJT^E`SVc$0kK_X>X1 zNm&PeqkA_tA9zc!2Ylc+9kz2maC3*|BlJ^OMdw8HE|1oii4mToc0C_>8D&Ph4t(A% zlAmGQpLT6KKb0Jwc@fOc2mU~^?NaS^;6`}XwS6IDF#dIIvkp8f(e?&wd+h7Lf1%zU zS_j@Mec&z7{8)Y9udsGrv~~B9*MT=uPWPRP#y*#<6WJayKPSa6*;DJYd#axXaK4j1 z@YNFd%ci)Px}HzGR&l4io-x+QPhK1RX+fb?eMI<>4WA=_Q6HU; zBK)|1r(oadOdzfA_+|9Ia)yd`K90{*@RM*Py>q5u2z_ItqZ9eBXLaL6K3%q_`|j@) z9wIvb+6Ur#RC@-(IT+iT_|d{=)aIRuHs4E|vG`egb&l5k)VY#Ry*RGJOUR3!4$s%m zf0L{e?Mg<}#a&_^R7Ycar^!g0AsY@9?gbCDb&>EyA7vUN z?o`p`W5fTB_f+tIS_1zgwwZwOx3rbvybR+lVlsbJ+Y!u1)Anu0MSKtJ?_S|-f*SB9 z+P-6DrL9Ag<42Cym9sVI`8Kr~(cV6ZvDa-c0o!%7&J2dP zern{H`yyc28J@n9w(Ih5Vm>Q#?#Y~#GNQpT=YplQQzhS0%Is8M`M5o3`G{W3J@|Ab zPBnq`u3B-bcmFXSr}_~8ZEmrfMEiAO?l!k6G558Kxt~Ql%;#>|`}Sqpax&q0%(w3= zjwa@QA9Y?j5}nkM^CU`_W#;e2bH1G4NjZ1DH>RH(AMc!fdKK+xzMOo=ST4g_^5jF6 zoXh`x=be3RTJ4zoJ)#BXFy;$+d?|a_d_;>$g+5V3#^u*}awEc_+N!liD)~6-JvgO` zKPFk9R#*Gd+BG&{6CG+_+V_yhvN3DP`C8-ITk_7%(RjR=djT5uWA2~izl*s)P$%Y| ze>^VBF66&2%WB2k+mt_rpOB2X+jC^uL9~;UWnEt0*`4s&vmxfLGeToFj7Rgb2_^4E zQ=+ABKY#RPubvez8{5-Wny|HtJ0)`CvDx7vJ3p7RJ``W+$}SliXjbg@;-Pl{o8m5A zoZE3lbZ*$C@>84f?_}!(TUS4E6nsUMzlCQux4^odI`7rl^`*>K#br9_Z`QJgg7!D| zya3vwjoxTCCZkwGDCgewH*8f*ssJ2= zT0hW!ux8>=vuSfq)Iaei)wOrr9Xe{N;!nzNR{K>kr}nt7 zsj|?8#V<1Wa*rX`WAvQ{3w`I_6rO)`uRDj8c5;njzqtqo!KZSxyK>&opsiXkd3{(c zDnGMF^1dH>75uu_yXgw&S9xdm`1S^E+u6va89mzT`ylldC$u}=IV0vs=o6e3Ek4Nk zSwHx!&SCd`w8|blgCVQ)q%Ilypkm&%B{;hIZTv!vMDwED?8gtRtmpiL#l^k5?X#6O zll$XdyrTn&b+i4e?mwx)Ms9m?_ayn&V>pAeLJBu>e_RU_~pG>w5KYuIH_6^py zx8{-;+~FQawe8cc=&A!=?u4h;n+!t!l%OBrHohW0EPUO%I-f<@6l}uf3WAN-CkCrWN2j0a47GKN=Z~BicqJBp{*!l+G7k$<{$Hsg*wISY&+OYb~ z!PYmbJ~)oqJ1H=z|3G^rvg|vcZ+DK)m9_fMR%l*%Hx8GQ1b7eHG+e56+ff0GcJ+sB*KleskYic=x2%wfoi@>}bn!T@wN46bOc+Cr2xyUr^AD9EeTj^ zk7zx`td^>cG@w95LE~gFcD^Hlwv;XEkktM;#Hyng-iudHr?NClx!F`_P zV60r(8qHhZ3-2qBUfC0^m)6$r4;-^~Q;uNp&tOrg=iQ5vtamD99bT!f!HIFW{Pgo2 z{Gn%=D^p7<=Wwrpp1Gq%<;lk~RdocvlYocX7w&XLIg?dZ{BpL9w{j(L>tK(VoYKs< z6!>33zTqFw7i|x5PWU!2EML{S0GwTLMs1Dfn*z3$Q{SKe+-M9fw21@N{1ocDw<0)H z+)Ld)tFwJ zpefk7JDf~rvw64TBXjb{dvmZHsD^u0xvTSCONQobob5BcQ#t7V{i!P}Z~Ow^<8*%* z+T`_LF6Y2L;H%4@FL)lxZPNW;7OL-L zE@p4cP7Y4`h1XKg*%EKz+2n%A7w~a@$K+}cf4hLY`UW3AJB~k-Pne&{js`l-o2GA;rA*r_oDyDlfO!o8|@j1m!%&Mo?0KtaDwZ<{=d*Zt^05s zpX&u?c6S47(#(6KZ|uvEzIl4oXy={{;VxQT!(MhYX;7|fAGhGue%!N*5imT*$2M6w zCVXKZC^wktN3rA6R?M_Tcx{xDAch#;n8_4p0?Ptj)%5i>XB$Kf3Cv(4UxX;m{dWeeA?YA@7>u$dt432hT+tVJ)C?_y@{-ycYh=NGA;oHCSJEMD|=7zeK@#?(MD@dwompveD0&PCwn41y+ijm%%k5v_FI76?ZbRy z|8!U$0=36px;eM3|CY`(+P}iS6E6w(m8a|Gigpht8|q%IwaEI9GM~p7>*Mrmc@BV^ z>}YGSaVXD$oV2X3w zV}k+o$Y^|?EyTw&tqVLzvV`n&F87P%M0CtUH8(v=j$@yiZfo%7+29QxV^{CcJ%f_H z)6ii3AER;cf9%A%feywHm^|b0hxAzTW^)(k6?>95drZEKvaPgXInsdB8rElRc4qs{ zxf%VpWM=^D8SS@{>$)vH9ox{f{;q6A{;O2tGP~O&@@yI?t8~p5MZ)_s>w?7V*(Vv6W8O%fD zI{Z0wQ0TPyVQb{;FxX-1Blc}_@3y*y=oF#tg0X`bp$tL!&-09I#~ir7lYVuE;LFk6 zOb?wN%>_8#6RjEh)^s%H6ONm@?0fKdX}{Jy!(tc?Q7h% z&xd}vUe(ckdEnFgkm0v6Zp~9`_3h7rZ`AoF|6jaf3AyJQ$oD-q${Q&AT4mdde0R1Z zmz(nD^vwQSz+;`eSp(fL{(>y=tmFpKlul?AYlb~^;HjhZ4*39j)jgMaq{Dpg7B>j( zQ116PFlND6;{wkHbO#lDdrPCc8%+KYqc7kB{MqOndt0>Y7~mk>GFY(Z)})t_3uP(1 zcF{x7*u&MP_BU%ZNq>qNl%DST0;i28Zvr-2SHGOf6m5S;w{6S0_}-%JEr320WWQ`o zJ{_3Hy%@?HU-+Jj>!pl&K(cHvYdHJJ@VIzQe)jDCj&g>%ziZX_L7bUWq1K?ldgAU-|(YvT_VI^bPkFm)1dk(Y& zdBEx*=S&uibXV5Av1aS&(DNMDKj060FnW3Tea_Xq<4PN0 z(&!F-2(JZ~Z{N&*=lzFofwo2ZfZ!wO8V-HETX*mz=A^X*KEnHsqf+7Bc4uPS3T~e&8&{KTT=g>>8&>dc#c!tO zSMToG>8MjhADX9Zbv3DkjVsZYgWs1}H@9AbndsM0@SB^2pGRZNugZG+aAe=L4+Y0- zA{(gYu6t)49AyVxi5+xKYW%7UFvZ8-;q0RFr+z7#yARvGq>alPo7u-$+km!0yp3?N z8ven03m27Z(|9Fw5WWxcnI&Mjz3Vl9d)5oQESwk7_{Kq-v{%MS77RkW2m404bU7N> zMLmr%mBLQ}FH^la%u%+Iq3Su>j11mkd zb!UQ(S-Y~AauMEpb9*KFayo^^D4MMtXM&St5J$tcKVoyt4z1U_dDs~!;4YemT(v&< zK^U7psJ&7!pq{M_eTTZMXL~DAUh{xfEWFq80{YZ%$KT+i$ga!#Q}=-5e5>HU8+uhD(K(BOw@+xN(S1mcQJWngljq+oI^ba zILkgDIEOw#TYJHID&r8GZ7t?RW%w_ja^d}v(R=<^`|q!g-t&JR@3(h-2Elun^_0DT zd)70QcSpYdZ6j!3G^hS&vQy(LzlWQH z`jBm^R3FGI1vw?eCu9NIMA!YSWIfdx)W-;M$?Y|N9}16!2kJ}sGY9+;4t)YURP6m6 z-t)J;dv1Hn>+Z;%1wVg{1V4j!sWloQ{JeD==!16~ZbbCRUpM+Sc(P7*wt#+3X4mi7 z+(y`MsdZbET%Ty&rYGM=>oyXa?$gSVlz*k*p?*c%Bp1AiT$RGp7+iC4U0L5HuNUP9 zPX_naV0Li#TY{kREj1bTStb~yo2#9IKJM`jC*SqbhvKvk1lP=_0G&W~GQGg$CuAV` z6K($yhb$g3q|BG~eGOsW)zHrw#(>EtB>$@BCb>txQs1U-_S3ZVJ71>salyt<>(UHt zQ@?uvV?JYQ~J5NtF%JM|@(Xy3fOT0Xxbe-oa) z{WBi?xR<2t9*^Lov6sYAAD&U!25`D;d2gR@BV zNiSmeO~fnueKTLp>lFG9>8rPo66Lg4Y@fWXB068`mCc6wfbc@&36Mof?%$}t;rh~; zgtOw2*f&kb8dN9hQ)LT%dH5%su(gbAv7$|q|4g6fc?&sKWFNr))Y0f-*m$qIi0UXO zycMi<7tv$f2Ws?_ccPys@Llj&gO9hlbKid8VrSAs`@{oWE_8d(IS$FZ>}l&u{r3`A zdu^%v*b*>za5$3sW(NbdZ{<0*=hC7DY5X)n!EYYYWbl}=YVTZ39isuzl~)0&g{ z79{;YrC>XPetLnE>*o&TQf9o`$C}5DHtsSutY{Btz26Q^DY<7#jj0U0ULWlX?TJBn zQ>M=L<66-^ejxUQ8gO2BOCwViao>j-e9z}alFw|O;LCwp6JQkaBFjY~+v(0)7ysVw zJre6L`Z%bcA;$ekg1;!v#Lc6BPDCG>OA2^khaKE@0{)^I;_3G#c}cPyHXqp~#7hGH zZry4y>v-aHcgDe^M?;K%k#JOW2)Iv-@_qYo5AnsrQ@<@}igfbi{yNaZ`xiJ*?Bo5A z?Imzx?}*MA-5{Q)-W%)V)^50$2DOdSNAAB8aulKqGT72*%@X`1u@1|QmK=>yzU4eh{UiB_io_(IReyTU6M|%Ps zeMqdm%x*S^=Y+BTYiOk2vQ;pnfk=I=d0S#XN<<8Uu$l%Tb3)k z`IDjVT=rYZDmC)s>MQ_0-pSMxT)HWvb&a2&EXoazo*4c!SHVSg1kE`HZx5cO>S$iu zTc^nL%Iox6J2$p0=T_B+#@GOyM$(_@j#@+NfP10+j5Z{f52_DNx%DoEN6C55VmwBJ zjtue#4ZtfkHh6{nZ3pvvQ2U%^f8m0e#N+J?PalV#$5~SNx$%(s%yVt9QM@BX{Lfyi zmFq8z(K?^8!XqqJ<80Q_@|QhLY;9WcmCFj}-B0IR*ZjJHk7{nBLpfrX(VJENe<*Kw z1x_d)>F!@KUdlEjrzrkOex9-P*-Q+Tor9kn49sbe-JxP*S9LJ(A=*^=zG`9t=GG0| zmQ8Qm0^dWgZ(6x=a{jjTp8fXx%+&mCxjp-jMJK;4J-Pih;+}5HP3~WpoXE{ z_Edp3wO+{w~6`!a4 zd?x?Mju^$wiGOd(a_8>i7gyIsv5MMD$YAg##lhY*&7T+aY_e=Wy1&|D@)?Wb{Jz0> zjP?PCO3sjOT7+Ga*eJEH*qDd;uGlBPtvHOl7@`l@4R_(jo zGXB^r;O83F{&CLZu(lR+DZFV(FYSNm``cC%lRw$zDqgYbh1HVxo7sQjYyLcTjzAE5%#(M@IK`(HiEexy`Y2M8vhxZitg!zRz57O-xP!Cxwr1)%kc}Cz`s< zosVZ7gcCZO{leHVm$GEAT00x>!6#dk2a#oHBl2z2?r(ReUD{B)PxIUhj^M{KeRQ^W z#(?-k_G2*c5M^R#6}Y4mTUCF;;T#(N37w^$qo8xX} z)=e>l-?njh^6M~dxpum3Ef^1Q679Y_*-n{#`4h?w-j|7ZS@?~~C(I>)$289h>5^jX z1}a1T)rH)tZ~xA>+8^>xGNaZ}^yP=+q+({GYGHmifE?r-rvXQ zJCj|TAECZtrIPgUV9E$rG^e`bh|BE+XQDV@bd>?o_SNE-ik0K}3wj3bYFD(%#r<}< zn68L^8P66zvDWVbR*tv6@nrUHLi;Q}%oCdiITt zujfnrw)GSpi`MhXVb&8nMPWTBlv&TYS{K@sj5J$$mx%HH7;9#Iv9>P88-pe9;O|-^ z*13BwJP5eB{K!_9JUCi=s|&qy`I>vP)MJmF#y8PHqdgOdVWB_errnfIuhUsPpHIiv z>{w#f2cQ26QofHPlrDQDqbRbx~%_RJu@$r`$#l5!%^|gtAO2A!9s%zKIHaq!gEB+*!%X5oVQ=* zT{+yAe(A<=8EyY|SiJV^8_)wMJ88Wf?H9j#QF0e!7GIe}9+4zp>GJLb{R?Hw*$>qQ zd(?Er#Zf*In-})kh5Xh#!70>P!3FkpIsM0A$hryE0sKQ_=mJ(l)=}GxL9{5tdTXBI z>CM%_#y8Tp=2xyi#}B0osUPT`=`n8n^Z2cH595EVja*#j6W@C?W$O3~%va>u+DnwZ zlyX;$u&iW?m6Sb8>&3jz<2f!P#>e8;VnlW*Z)}2_gTHJl^6hF3%Jc9NI-S>^YfHN5 zNMIu0ZqcXX!7n?qex!rS*TR33aRcPI7@S7fj>fC`4_h~CFXVxqKetpropHN>)19Ty zDt?bOGkH#UxW9fE>B9!)zbnGf)91at?e=xj?{Wxj34g>(6|by);rxx0`5mr{C)1T0 zdoGS&!u1>RMcqvO7>xY!M0%RL8_W0Q$>$~7AJIR{KTy&SR%$Gz-ueAT@?#PXL&cI5 zVe7%cZ!MzW0PJMw|mg*^OuBmBAiVlM3bS zg3T>kf|h!CBY4r5(V{-=4K0*!1OMe`lWoZC%(Trqc>X$X-;`>h?QPMX7`;!-+tpD#on*<%iJZZ?eAc9Sso)Kj6FJi{CFrns>|6W2 z5ASC3H^;sW+x8r219D!+XBm^|j`l@>ZS_We+w&aGRFX&PW`4)U>EXBJeZiIUTOH1Z z`0eSy8{ItP+Ym)_upyp_4UxF-f(;SfiNU8}@B{MR4@{K7=+RzG8G!_91t6TCr$tY7-t*F($Oj$bR0(d!6?^ zKz%Z2*=^2pwhYaK`C<<+`@sy&L$GIGs9p;HU}{Nuov&cepe*y4C?DeQhSmE#dt#?& zZw2S=J{NDjG~V8-$p6V$IlnrojkRlIog)2zgX#aoYAd&|d>1XU&0=rT8Scx$?Pl^B z=vn@YuK6LKY2|Ew-+bv|m0N;coDGZf`g74UX-7KGuciSn)>!ir%u>`czvTAUo?)dFpjP=b|~4z3V1|6vYE*5QSlD52io&kJ(sY9)g{iq zi`QyjeM<0(@ayVmEZW1eRpf|yDmRt_4#_4a-w<}VM~B5B&(56<=|HdOEIdCcL-_WU zpFnrrdCNjM*39>dh(CM^e0q|91)oh;%j1DqM3?$(Ypg@CgKnd zA?{*6e{&16aF{pckh+fRQpI&Rk+ZsWyF_v{&dSwUMZZ~U2uu)<8B?HMHkf| zpXhrH-}N3_#H1SVKshg~bVi!zV=fOS9d-Gv1vL}HK17?QVf(XlN~){a6zqY2Zr`@L zlJkhdEpWF38E6t`4+oA$PQQ&cwdb*Q9V=Py^FO%nf}_WVeM1W;?M45+=u{eue$R=< zBYYFh)Hn;{((lB$1iN{2C<`98MR+LqRjR)5b2rYTN9!W_GP8GGM`})R(L8We>yzY- zdRMfWd$vViMu~U~u{EJQf=poR73GBhpJV)%*bB>(qV*IGBDbs$kXx=HR@Gz`@k+*~ zoVcO~qJ^1?;9DAtcrUy=eCBJ0OLn?4Os zuh|D04)4kMGUFb=7MYPToM^sfc)et@HJxXWJG^cnk_RVuCEg>4eYS#mX>M^kw!<=@ z!SWDb>14nb*=5-erDQb@sh4XRlUq%BeX~5HIL9fFj&_Wf6TC#MJK?^iwET=>@4cP!YA4I#Ip?N zu^-7cu%xxF5dw6`>#!+$%9{*zu=3@n?{oH|) zH7?#8xu|odG3% zqn|boVy(6v67>b2kv^d@Z1QAx&9$3vr{4Pf>Ni?nrZcRZ<76;siQ&3*8|MC6%9sqo znuv!=exGFO9_nf4%- zX#)1AF@;#BHLS~8$>7jS$(4c+v7=!OBQmDR@SQW-p+R{kr=N4Q)-06M&($;e$JD=M z-8OP$0hcX7!Pk5`ZBH}ba?1n3#wRxx)lE_g4ctz)y&x4*qj{x5M}hv;y!5i$Fxyg zcVa#02q^`rs-J);8>1&vCv~P$*WzSJha1o6z?zv_C-IvyN%<=G1W4(^CO79^U z(_kn(Vyy?d4yhZs|0wt!I-Z_?q35~bypc5q`sRveRc`5u@JR3E|L?749T?LxZ%k)K za>s1-q3`tZZob1uCz5xmqlt)~&lI$REYp8!V9T9F6Hc0{ifyh&GDG zM6w?=IX+*?J@%=P#uz*pqj0R3IsM%B-|@tp9oM!kJ0^@d>-6YlI?|v2iu%GGl6(FN z`hw4o-@zGyQu=~lMzWg9o#|-&cIpd$TMe```&FnfR940Hgc3$lzjRhVsNq>XmBz?YC%C4A*qe3Pz9UPfIgI-fk7v=6HyX&AP z%Iz;W>8^uy{FTzjoxYPC>srwv>Z&ivZ!MQ#FJzyaY{nf8YnB8Xe|u-RUYW~hEn#gY z-p6m^i;-=}_piCnxo?`CM@gU24({9^kkkG7=PR&}iB}UtoQm!o&|0b=Y~nQ&gN{rB zZjFpZ=ZMzOj`dIcjq*pfrc)bToR{Jw#ba;fy=btW*XbF0Yjh1-+y@O6J!X%d=-w$7 zw~N?YYz?+%vV&!gBo>D@wnG1;Ykrk)f@9a==$F#9rv?LyrbN0XYpXFwHnEFpu-&8k zwtpk4GkYfA_$?UKV9(dQ!MlNijbbiz`f%os9Ja>s3G7nvj+jpHPHZ|s6k`L=DtzCJ zjO^@7KmP8v)tl3d6MpK-=$m+8D2G=p5#LLG)4pomGT0WbHIyy<>k(`sn1%A$+)xMD zRvq!tYHuD6z8WX*ecE;jd(hh9eMWK~^`8-(Df=F9BZ-G9Thy_=xU@*NSNR%jRIKAd z+1;>7FRap9ky56CAe`vx@QP=h@*(Ci(8KVz4D zNPAAt`VP)_6wjO#^n!tn7<>7l9JNrVijC`8@cx+!s zGF01h^gphyc zmZK*PmRrWN-oD)OZtQR)m0RwkZg09Mw>%ihQ7^aL(gTmt9vhkldvZ$|dZd`ZLG-9| zu&qaQ)7cFzt_!+T^rw6AD-kV|eMoi0lV!Kfl*@~l7?`mnxqvA=i2QL$R5%dzrtQxf$(ctoZOobVm)c zkmY+&T(GOFIL%k$j+#%{nj=fGHmi8%s|>k5sx z_@U2JPqMvm?gs12i?b@V1|`}N-UTCwPu;FqOmCiAXTx>YT=8$>w}bAE0gs-#3K=^4 z^4}e!Jsuz*6=aL7XH$>#digBm$I;nL(K5p~?6Sf)TQ}@i6L>cJA8R2WWS18kt#YyR zHl^00)Vsv`(6`0+4Z1tV+e_iu7|zj0J`wHrObYy{#+CuhWmkUat43Gte6Zvb_P^aN z!&#p8bS1fyAJ=)b!FFunSpiPonmXKt4h@aBCF*>DxW-}YdGph}w71mf?t-~+A6Z_s z=f#i0Yp`Q!ze)bonv|436L8hME@d3V@x*=3-gwQ=13s3@kEMP>Iv=OiK8=(O&vZ6& zKYjG~iSvGmeoE!ix_H9iTv|QM*Km&go=N7?^6}WwR$yoJ5%^)R4QVCM8C!$UhIqHj zQ%64jGueBE8V|2yw}x!V~*99oYJG`W(K6G;o+b zFoJ$Q0K8m3L@|pc+DUN_>Y%!mi{{lKIa7YN8hl&wvDF}>6m_qnu33oBLrxG5;-?E~F!kH^ z0KVXw_J5%BN#rBM=C;$;($4|)Y4s(X*IuB{BH#4Z)5i~R(0ruPxLpn?8z;O(=Mrqq zna8EHZTp&bQ@}%fau7ZyV645U^%;}{sxvNcD!y8BRwX>4k3Ee&#B}h-bml0U%bM)+ zcI6fc`}Anq5c9bM+q)b8J0 zF3E|OMd$UIv*S-%3&n!i__6D1FU=85qdnP{BUd^6TW5XcV>$Ojk_W;V7=sVEB>vkM z@n4-8irvBC&CAhT&fatoKhXg$b~IN98{bKt5FXy1Pu3H@0gL@9>+dQ2wV%~HC*Q~7 z54<+?-QY?)F`bt-XH$PzIZE_^y%_G*?a*(cdM{#|v7AZKJYsS~j{Odd-T1VxOutSc zBSpD$w1I<_d!PCFI8Cg#tz}n~Uq>`9qa4ZL(cNXvvS<$!=}Kw% z&n}m9nf`s5*zKv3?IqyqbVkXolKC_8Kcu4=Fa1{B8g^XilG}*OF`05tVmshv@+r9Z z16Ma0Yji!fE>}nG^wI`;)>M@b=&SKh71l3j6ikMejXml6h^=jjxz0GScn+bOXTef1 zKQD?^6J8%+@9PH6iTabArZWqloagdPcrZ^FZPJd8m<OfUWp{To^%esEqCqbI+=d_>BhD%@7Ny&j3$ z1RnUM`YZ2+UQ@>I8KmDn(RFFsety1hZuFcwDBm|f7&xD~^qtNgAs%Ae;rt!Jd>M=K?y0Y%=}T=Xj>E+*sPZk34&t*OSak_z<_9$7LzOx-U!Hz(T$S2j{(* zi)f?pdmPU(yvTa?1!$qkW2}|xiwE>DPMv$}x&nSiyD83+Os!$ev?X0VM|;xYv#ePt zpLsEPiMH(?RoZZ|Tx$DK@sQ3l+PhAteeh51Z=0*Np?&&T8MQC?eE!E8yVpKA?bFAC z?W7F7klbYBrtN9qOp@06w7@TWc=CQ_`Yl)Xj;eUOFI@0n#6_jJr!L5E%Vsv7mkFMh zjGIZ-*L&_49pOf81K}S=Ki%oOMqUr;O7;P*u2K66E zZ%U(Y(6{m)s{g&p_0KoKSa2-ZD!q0`>uX>S*m?9%nD3dx<=)7}X|Ld_KC7trtm?8R4x+htRI?!MN1COT9~sk@ifd8D!Tl zQBHfQ517v$i!PoD?e_Y;AGV3n+zJ0}V031rA0G1jFI^%KV19K~B|e?BId0RzzjgEe+g zbjpHn^a;L?_OAE0enLE^NN>g%OuW6Y9s5i6O}D>ltlbdyp+ClJb369ZpRk$7Xi}NI zB>Ls{k^Eq`k652@J|4ZuiLXcZA4jr+%S|XfAdIJ9-rs}l;`Y%3_L0uNE@n=W<#g_= zLC@$ripyKZv+XO&NDs2O#<{`3KD!d5%{%EY8DvJ`it6sk`>sR6*g1QTys36}(|c@R zl4+~FAcR~+5MlAH>)pY|;h)>L|LndC@Kb}4m7b#tj{g|Jh3I-13 z99m6fsOyJ&$cs5k7iFAv;8`0n@~zMUlXbGQxZ6Cu3tl-JZ^_PVe;m2+31S8}vwx8X zb#{e**%QFozyDo2*e%&*lxKYKH2MGCxgPDymh2g{y{x~7IKh&4#ZP2kQLk`U`~jks z#k=BfgvNz)@$RzkEXq`6$IrN*ur<&a!n^E6`_j-~{kOZ|`9F3a@<4SLZJj}McFA;d zWI>(Pyti=YJh70RDO9W(xE7B)3+Y#f<{Ilq^HV=F>jq|c{oEbx{SZdW+Bw5zAO@056`II$IaG_RXqpnZS<@Xvq|6#`G^;ZrizK?5K z0w$$l?)O>bgUR{)272tvREiBZ*fYO?enbZauZ;E-^VWP7Z!zQ?eR!)*1oL~6wBMWe z_S~t}@Re}P+5=fVd$9$QNlW5IXOUk!dQvK8ptzq(+uBvPR2;yCnZa=Y_kGlZUosBB zhfxHd*8}g8_~@4v?lJGde6X}WAiwf<`G~zW(Oiv2vIj($v^PJ^7~S&;zb(?#M&EyQ zPmqVln%_yfrtZl&_9xMr(T3!u@6e8LX$^7u&7IgnrN2QxzNGiyo{LMc_xO$EF9y$J zexs82Or?eEL*E&70Bt$?Qo*|U^3o3ZrJ+YYjqrWno5zLo^l8Kn^}$+{^2Pde;pgg$ zy{f*1Bf{lSkMm?TA3lk3d%kbWkLLTn+iBZq0qv$n>-$dNGx*TqY!Lx;=3MfygBu;U z9$7*^%$A_o{d9B`0wEH7E3hyWNH}~lMg#Of=ApcF?H>W4| zx2~<&Sa~GAgu{{RvE|raIHGO5V_xwr#^P+;y?}rs$cwE;g?X29CjJxB1vq$GY^A{>`@q1MAWa z{hR+o|4-=O{7wEd9`eTwY)MzG+wz@Y;8^TV*16NB)%p{`vluFZ>?=O0FuuJ^q!~ zfCDl8CMOvw$_W?A72;19YCeoj`s(#O8!l#LW5W-Eui_5+mM$PV_g=oo;#jgp9RoQb zv^gMOsNMgPJ(@Pu?na(9Z)abe?b-3>RSNdVhGw_+^p|u|rV}oh{7&1l^VmJRk{zRa z5MKKi;LiBEmxw-x_aNBXJEGEAxK5ZyFttU-x(in6(H%Piuf z>u@q{*SBW~;A%6~A&)d_o)44da^{lgK zpF4N)d*aB;+eS+752LN%!_Ksg%o{V-k;W-7=Oew z6azL$=P!k?9u7Hvnmmg!A9%TbW&mfupO4W`Y)_QHWyMgxn|ed;fl_134W@${$A1aG znQMSt+wk#(Oykc7*`S;~=3{~vdnB^Q*!jel%O0~bu{K4T@9n)I#_ic-nv}2Jx5u1F z+fGhMjn*FHt)1KdvYW{N=AT9Q{;kpe0e)-X75~=f>@yy}7-BxFe+Vu}#)8IPi(Z^u zhtQr-1~!o_l*G|%)Mm67E>WA_UKp~y1dd!tJCb+V;|A+5cw=2=?S?Yhpf)4?r7m(C zxXD@+{3)ey+k;OjTUCHO+=Wm3@8K-M05CTF5`F8QAeHNifwwWJl{lGczEJ9NN9lwS5W}ET+ZUx&6Z8!1#ReBboNjaXimtHcO7~*E~ zEW(#QJoH(F5SRVj(?vO1bil>iOK;O2GZ?b>MaLxjCS_$mK25x-7noprBj4W@6Nzmt=KQl-f4{D$XiI94Es6J6J|J5XF$u&6oEOD^A1hlD?dzO~WEhqE zJmsuS@OTYnKk;4FTh@Od?JFmd;vdv+IIijaeLZ1pH}}P@x7hAQ*gf>D*zRl;+r0`q z{jsd&ar`YIzWZeUu(xc(&a!PqfDM*7g$3c9f0icJn=vUTQHFS0*-g~{y}a*Q9K}lL z{alTAY5({2{$#~UEDd8N4pI5j`@gGprn1k8E!c#erDriQ26Ks}IhlBgL!x+z1?cRQ zB{m}O;tCc;aT0f84-h=gAosUu&5Ku@KwRqaZQF8V2H#N%{)z9Iy@|FSQ5*>PF1@F3 zMHn-$7zx=lv~JJv-C!)*!gEX>%Ap5R*6pD|G1(sOJNZj@-s|2SwcnktSf_XOA?Qr8A!FLzmExIIrDE=-w5z-k?&rR>bp4p2%GnE+Mv4uRDI?JzfWDfrqGygNA z`PVUb;Xwe-Tn?;V+|EYfFz*$+gS{uTwXt@0MKIF6zP&4W&zMYp#}4%8C6Ys+Pt{?p z_U7v-OMS5#hnt&{TDBtJ>H5N}TgZ%^V5 zyCO&A^nMZ-ISZ>_6M*&JsQXJ-Q~w|5aZBXl?yzhvp)2x zy!WCTcers7r(|X3mKlfkDY$3*lzQEi8|TIWE-sA5@v9-mfxkQ)2X$>6^r>-Z4`-CK zi@zcBQEkBFYAee#4%%J4tU|NjRKkJ*+I?TR*mU*fSH zN2U6WPRt&M{CfM;d<$`xb1oZ~ub%guVl8^*UduXFJaWF86_d8Qu&2woc%FFeha;@7(*s{OppG z&E~B#kv zwq}jxP8?v#|6-hbiSb=Eqj=`*V>}B#)Yp05nX_x{eciy1>D%Cq-V2`G|J3vnXU;SR zV%Fd{#PN}vjI*Obsrw8tQx#XO`R7Vncs)y7=*O@(M3+zpf(8^Nr78Rc6lJ zm&>l=z7=xy9bLB&|4IjRw{Wl32JqOG^V{H#pv$34?VLU7pw02%g^kah|638|M7vx2 zo_IxM8q16PU49EE?3^a^S=-6^8orMqHt&D1DWDI~UYN6+|C4lXa9(QG#eLk7Jx_Zm zRe8)&sj#iaaoDYY^OpS8{GW6DTk~h{+SriedBufq&DTZis`joOlL_-*)0c8RBDY+W zitdHc+{m%mvC7~x-f|XJ?N;Z(X8eud^r{-(S)PR50_6uVm<*~{S)v~AtR8ZUa1bBY z4%KzzoOk8O#wc9Tx&yC5?z<$s_S-#z*LN4?pM5;s2Rf@}xeEm&mlu+@IR6sTXYkLp zi>>8E&B?~bdk4d+^UrU0IHU0z{6aXaB*xWXD?BdDWo!w!h45Zk1H6siP(CBx!8ov= zOr1x+nxnlN7nK|G{D0vC(v>j}cMZlaswNh+f;C26v| zSMQqNzXV^3?$wKEA9AS0@NoWCbZ3>LJFZTec3qu1`RnScO3L5T12y(LW=Td9zggb@ z3GtZ7z8OUJ5z|E(|C!dVC&zXcby(GRykH%3>;;CB*QJw9S3WM_BUnkMR$NX@pUoEi znTpA5$?n@8+MdEVRmBX~MD#^)yf@Otv_=}E?z))^4E39H1<*?HnK}_2T*;hlPi*5o zKAy>Kd=ottKB}zYGVNX)@dMqT-Zhr96n8Jm%eVQBftPe%zC(Fm8HcrRb<`g?qW0b! z-R(op`&GI>qM5bY0=#T(fpHj{>-ix|!0rOd2lzo{lPU=(kFWSTyx|sjYkkr0OxkI5 zcboIu@)v1MSrhDxm-o#NE(cBv@!v1RPkuT4~rX^rFpWOJiW z$adl00@sJT2h^uM!_p&fysWMD?PL;Y<7AVa8Ba#{4#A_0-@`|0;6F8tC9_+JyF2}P zF(1)N;WY799bH-UM6F*b8syazO*UHscqW>twU20EM^Vo8?C?302SfV(HPo^(M$SE%Ikx0p+p&t{hf;wdX6_1(P+a1<||qvJpWby zi^dy-Q`e@$9Nl_9TeuPNx=oZ3%%(LEnxLb@&1>g^_D#;AD&iY}CB7$uH+1V;1{c;|a1*a!9;S!%QpSCY%|Fqu@YQft zI8Qr8HZakRCMNZ}~8=2WYQ+{@LfyvEY^HyS*o;7Rn}4-+Eoc z*_&H0K9YG!F3?(^!n6Lr?(vsG+aAxF$1+!jd90!CBaghay3RY>_inzwch47AubRZY zDN$Q*=bgccHfGS?13la+!gB!K5KZeMms5&+-wp-t(R6|rAoEP!!c27MgJ{)x=SA}b zrWXQRhY!kIbnm&vZ`yaUesXa-0jx|$li%*}*Xq7z5APFYHRkUm%M62a_vs8?a;`ba zcJVt=4S%qm3oj0e=7UZ+kQysm7usW*CAXe4HjgcJeLenIkjbRr&8c z{}T5@VxOhH>Sn0h8_^oQU(b8_1%#i(4%%7XnlY5YW~Th|iUk#Za<^u9Pb_!6){Kkp z*;0E4p`-2+QGmgsMN1f!+|jMo2X*YWxH)8AdRDSXji4SxnJ z&23C^ZkZPFZA@tUmR(qM`HacPR*Wkc8(56aI^G{cexZ4(s#TSh;3)7o%DZb$FsW<_ z7ADrP{P?~*KL1aQ?;1}p)4J9B>j^E;9lZBOe5Ms!Z{`={&AtqMn{2$lTBnvz=Bm_Jf$S_GVV!$gh87WNXnowJY9P81Ko9_vCoH={H`} zaB`wu&fZLxex!Q%sAA*DQU2IOdBL!Fe}kt-=EmZqn2e8N3Vyw@`BrF=d|%DEy@<)& zi#>c&zx-gbdmf0ryDfcE|2poOYD@3Ux2c>dKBd14A6ZNK6z*U@xgVRLbAVy~l+%-vh}d70!JcbDzfCbjs)>-{yV@G?eE;eK&XN zYb;;pTNmxxe9vX>^li_VdUL-m#oYI)ZN4=X&i!?7wYh(f{(?+m?$~3)xzAwk^2u^v zTaNSL)tdWK=6-sA?SyFV#}(&(ftx$;3UjaKo=G=%&WsnARo6e%!d^u|l?uO6D$>tDDYMHNjPiM_--W%$_c(Bd; zD*AGJyJc0y#=Cl^)HZ)S!ixvf`JMx>Y4}&l6!!L#skLW-TV3GCnR;JWchP;7k)P;T zaEAAr;aA7b<7_*7W<0c<`%v)T;%|a}%V(NONyb{%|KJf3?B+6`XwS@cu;X1_^iH}> z-+s@Bc!TX^b~@TKyziyY4DCseQNAXVWwu58CS5o1hBp^wziOThezXxdStn{kV>*QI zimfylVo$;U7e3F8V0asTw-qzNonYhl@wwEuPBIuC?8ESSVE8~BhAZY@({MlnhN5FF zH&krYcv?H-i@?VcM9Yyw9eUiHnD z|6DmniBAAVE?f zf9Y-L#kcc3p7K@5wO@n3eHDKB)rEWHjZYr5NB(En@G}!X^#v!hycS%T4^H6AA3&!b zKz=cPSpol-yoIc_{zuKb=a*vt62EM9eCK)i&hyawZ4uwuP?gUe+Su^(=RMrqI-^#6 z=X&bu+(s{ZL;GnhW#mK7965VcAMc=nTh>JPz;yqGcK;G@w}*B+673q_*&6Ykt?}~d zH#RnWHBsKyYwOZzy}TR_W#n1$Z^Z));?3Dm$Lk&!l(fHYE76{GImz&w7BIIxf{xqC z>o%xeub$aS**_YCc(e4lLFGN2j64Pd-O#Je#B1~k&bc7J8QFRrxFj5sZ`$N-_PTII z_NyX|37|3Tp^sb4!utAunUJqOy|H0g41Tj}YgxycT1WQh0>0s|Zoex#v)$mDUDodI zFRgcXhf+?sYyL^>zw%-GcQA@RC{E-N#$vXa$gcNee{A1jYzyLJ>tSq%CC0`XdSdDE zk%RxbZ4Ta#!vjO%qo!9a&{MJn8g)oiS@kpWgpRWVMWFN^V+v-Gq>z{j@)nL-ejW z;_qDx#CPB~a|8L9*JXg2`0g*Cdv3Mp1vXmZeV`dRVu`Xd+K*D3=^5>ozfXKRy|g`p zZ>TfcM{Bk!hI(oHJ(N3w{<bfX9rs3ZrgBkA-&T3;dC79h zw-S|Isj@4g@uL$B=v&Q9(R%#lGtuEw<_|>zlR_krgxzpMmuC*MC9MChZws~Zv6OM7nh_xs#tJ8Hg|_&u32vv*X`QI)^5CA^h|lW)Q9j@bgBZLU8GgM zY@dkP<8IiN+}_;Zw>Na@)c!8;cN_dwXCle>i68S6PASN^ZOD_7MKdPw@U^X{?KD35nZIcLPlH@GHc0kmABXZga~qG| zvd-p&Ua>Znf3k-^71?ABbc!`0!V0UpYIKL+KmB8+gbjtttBpyGbac z(H=A;w9(R@#&)~vxxL6f)c9;)o*c<%KSe(4nNi#PW8*DN^^fjt^4X8*+t&-+Ug&;= zIF?6J3!BH8yxUZN)YN?S#f=SjP(IuXiCDtit4hvlisY=O%*f=dCfRK~Ijc!>R)z4V zyqwikf6h#kvpxt+3OYa}XT6cSzMOS5Wkx7xS-X<6mM7XRBWGE8$yrMh<&D0TlCyl9 z2E0W6zH+n+ejcM;v-usazeiJslf$C#qD$rM@Uk-}WwX7>2O9P@v^_>~qorsfev1*( zM9B@iVe63GFb#N2>)!+|&^_P1=n5gdOX#^q6GA=r-++nR|IN|<|Ms7YG$HV4!egwF z(FEzK&c0zZA+G0sufIqW{$gtY4Ujy^bD@5W1}yFW6W?Nbu15phzE0@6P4zeLXLR5P z^k;LJ%UQCjkWOxqj*uR|u1YeaY!JkfZh=3PlV$hk>~a}dwyFNi*PAT6&iX0Z!X(SS z7g&i;Hu7y}$+GJii!aOmn?JU=ENf$vESpP=ZG^I{)t4-LNuqwZ|CZPKy0Tk`?i-=6 zH>MVL-IS6IvZ;RmIr+|iZ)`Z5HbR_#Cpv5-Yy2Oit+)MY7~1-8uQA%XZw#iP4*NUm z`n2_rf7uS&O1q-1nMAu~X)EPLTVJ3LpT?J^t)A}a`=4G;9d;k=nuF-1H;$wZ8}hkQ zb;QG~+Fs06G=oZT5AUUNEdeDYmC0$6ep7bD-0V7#SHl{Y@mNxVv=_*6Y zfS1g`Rzevk1M*yu0WVo98E~iY@QH?JOKU5U!#JPOac@M6#fvME0c8gDn9d7*IWS*+U1P)Pv=OfJF>TvAqq|{-(RtrkRn&QBM>_BBz(llOI#A;jB&+44Fs=Xoca?&Z?EI zLwM-FbNeDNTdpVfdHsv7wyc#I(d-S`gTAx1{NDJ7Jt)|z`{UEVdPn!i+2ewz>z_Q-_QwEmCm|j7_Q!VURDWys zpevA-UP*hYFmA z@4c|qU&qh~`(1EAcB}jOwzKS3+u?(?vB_@ri^SMQY`0==vRnNyQQyhn1${K`gKetc zb)5NNzeBx{rjFbPo8M)y%>7>AI8vGWQu-XN%>BPl|3l_3=Yzc-SxGvnleI>wla`dZ z&`G}ztanuAzD9P@^L90vdqx4*{yt>xFC$m|Uy!+9Z|lEvW$scw*i-4Jl+67J@Ma`3 z_gQ}|%G_U-A0_g^o$=s(>KBT(| znfw2soYnHwFml%IQ%ug93`~-8)`Qgb{RF+wY=@tKb|q)ML><4~QgYVWvJFsPa@HRc z<;%)hzCJUI4|aWjTt6zt!g;z(cJ#4ue;lR1^<&XEeZ8xsF4w6XIQtM^J`G>PF8S6K z05ZM_vjL^=oAz^3OAUngee-O_*srFvyYd9TW z13uJN&4n28R$^|NiJxg9-e$scfcE}2rxIq}J9 z?IFg0IQ#4F$hO;ZNIL9$NxY5R`Hc;4NVGwG^JLYp8h7u>#L-ZH3o-mp-o)AB1?l{gKMy*pb_)i$BaC~s0?tqe1Ho>@D;-Px zbS1G*V>v&8Pt5qijo4tKIGqiwi+k7QeDcR~riQs0kGS6Qs9Ic&`t9OdCG9ExN#|>n z7yjX=BR+9N-M~lb!^&|UAxIJ9OZ(l6qIjJw_ptKawHvsYYT8sCjq^&r$Ic@#R-5yU zUQGT<#ikRJcCO*X)Ajw+jA#6kaX7r`J|vyrc1U`mznw@UcQk|Vw)V&acSo^b zhAVulq&?27>3(?gtJX7jXYYHOKCIky`k%smbHb_V#Tc*$`R>{+;1q2dPSI{J-@AMn zgmD>8E%9*5iv_d&AK_Fs#Fqwxz4qP(oPCS-eD_lo`E5^C#BuCji2n`igfXn(80W0) zY+Lu1ioA_;OT5ks>dZ^jG5U1LyQ6sU(}>?c75}Eo^;NV3l=Az0V(gCD$mUY7v5c>( zhqxh)-SHKw>iTln$0#$BSUA_N zHPP9jXhSmGTH9qe!GilcX7PkwY0l;qFvclUAy#iK38l_hO-I8 z)>IQ)1O0bra1>wf;*ASukme!dq8IG!Ge|p2#y#T61U(>TWm^=pV(b4e`{z3sHa2`M z2A>(V?`56dPhFk2{s`ZYVJzoa_ruhG82A$N;_9!cYi#&(qP~3Mq8;QB$bUff(_wvk zhhA_2?*jiFG3xK--I*0$InFM=hj(|oz8{Fz_kno-=_83$beKx^F%*4l&-)p(_8Zk>TKn4#;PZ zZftn*_s-tp*||L)@56%JO$LuXz>G~uZLD@jo~}3BZ!j&b{p!So@;)SuK~LvE|!jybLFMG zu1S=4^pu#xP>yB2O8F(MjoXRsY-nuA7uL%=TR2QC&`NToWsv#&vte%oChpyEu|Ox# z=V<&AXVLe!HbWOja5n6G$)tS4eKXrXQZ&%7lrWr1-!L=(r zZ@)ylW%Rra^^8M$-d>6FaoNSA|K6VXYsKXsHot@(=Z)j#j%zppJqr2S?3pdAif79W z-p{_(`16mp`0F^U_Aunzk7*sz@4m>la&Zk6L!2$ojICVd&XoU-F?5fM>{sLK27cs^ z$vcPR#?*rh(2^KaGM+)XW0PmfU46wf-|>}&d%*{}0GmKz4W#qt;I5e(?8vCflkh6a#Zocvv!|7T1E z`9DVv4bB6#U?);OKxjs2lRvze=jVgKN_(J}cZKth@Pb>wcgZ%KCn}zQ9*2 zvOzSB&<4?zutC^)`_~w5o>JTEY!CS7`tS`Z$DHO<@b%(TOr`1uj>Mi@kZ;tY^`CLhXt&wqnrPOxY4EWJklMdhsMO>^fDcCD^#FmN98+5)fGjD1V7YEOpt&w;+JOS~Wr{GVWh(B{C_R{(IQ}KIV<*(fqov|c0#S?+z5jNBZ``X&gij8mI+C_}* z5pv0P&958yQ!liKKC!)a%$gF?`96NvOo7&u_eOq&O-@D?9#Mx}Bmi;$rOhwM2JS2oFyIUuKUDZQ|DnrmS-czPt--da`ioQgV8WPhS%8&`a=> zgS&!jy|Zl#H+Vll`^QkH_tMaw4Q`*PF?Zj^IPZ#&bM3bp8`=`%B=57~T`z43M(R^{ z4p|#_rb0jRo$+>hXlHezoe)kZmCgf~jmJlA9#_{J zrUjfmEaa(3(C1!s8ObNI1#~iJC!@6U9LwJu^{4W|L0<0n&Z0kC`k!+5bRqW~skx8` z^q%N$1hqfw0%C(YXSJt+&t3f2{F*zLw{OoG$2VGjtu$yt@?osOKHP&GWjZ!8hVC$x zuTb}YK83C=9b0*ByP&mSr0>m)f%|fJm(ab_04&CmHVz4uVIde}C!mqW;|y!9_VDKPb2`SI$Y=-7f`woc5sc zW^0uFKx4a6^>{D7g`c=XW3lJOo<5FUQn?S6^U`F$+vk}+-c0`?tUVjDLPLd z_aY1tSGA%3-h)jaUkW^ma%E_5pTS!A`uOW8GeUjb+Lb>3Plmkt=<)!&|_LKIm;+I;k zVBb`eXXaAdH|y)KU65b93pqF*^YLU>?NzLgtN*ZH|0?S58L!_-{qHC0a|c$TK5}uP z|LzkFNxP*LH&yp^=EnYXQ5-d_3OTX`WM9O z=cs>nqW&J#|KHhRes7CgTS>i@@p@~icVePmxG!BCT9IGj+YOHAuZh16{7sxRz4x!&HNhX(G}79m7jglqf23YpWwY4<3X?K$e`2Q9qBaa zLdwB;Q5`vG=P)nv5w$tjhs){A?{s36mRlUy`uf)$mapb+h8cr0QOu~kGg3S*T^+q$tJI5C1_~;FB+;DUJSeZHA zL)|iS+))3?>G`$H@e7HuYL1i2&(Z1$e?FP0H<~#ft-BN={J*Wt9N$@Hj>koJG}vB_ zuOs&kyvgQxR${E0ABTt4Pyh4P4SOW& z`!wT=e*O5~xBAu8-_{e~`&x%f{dFMLnY$z$t+INZ)O#jTZ#3&rwO4T+CX`u+Z_wY4 zuERLmFSQQW=X}`X=4zB(R>VGv+-(QDqQ@sAYb#V1_)c;bV zzSdz%nRRgWs;jPPxIR&DH0$ultl~O+?K7q6+VSeoqut_zij#kgx@BNYj{imZ?B3Tj zoRb)<=J=a^OYeE+X!TZ5@1#V%(adql?BX0hSZ0n>6LWO?`Bdtbnd64~^D_A?w0nMH zteWH6@^iF$E2uX!QLpSAJ=>~_@!5pjVtIvGi$8LvJ|o>1xuiL=NB*=69g5#-Q}T&y zzcKr2i8kGxQpBYUKBqB6`PN~|k0>4}H#k?ZzpG#OHS=<$RytKl58>W#<8Z#T^H%3o>6vO_Y0B_GY_Z3SW)pH7Nc7 zAC$9yTwr;xS=Zx=@dxjwU0ZA372*%@Q+*U%5}tC0R5AX5_oka+e=++9_L*gyif8gp zqb;-ZV~e@V&)@9q9n{xY{+n-Iv}?GOxM#@49>wAhfIdMrTSzqT~Q0iLW%YFNb?lj;|r;pqD z(e?F>wfP*f!cp`W*ge2ro?#DnM}~_yIbxMt zp@lrLYp{U@ZtadJuHEC@FKMvgU19Bj{a$YE=6Y+#dl$E2HZ^qWKXgZHhfckPwruU7 z!^gX|Q+>B~)Yn*+Y3+D#@SBURioWgn2oIL{DO;VNlC$D&?fyi6Hr_or>*;*g*zWLo zmdr1^JNE5n7nesoipwv1w(#LwW6k&3Wo;JoWXmp-%rEQ8%WwT)qP)hgyWMm*v(1CM zDIE@WKhL;|F`Z5I|NW+X4m#UO8zD}3Ha8C^O3~CWSzf6)P5oD3zN0j?XixEMG~O6S zgqN|Hy=nd3>>Hzz*i0QwQCz_~?6T$VE<4TgL&s@Kox{rnO}UW0WHg0%qb`@z-DnCn zUbFR*E15lf6!0}%WY50c;U##Yoalx64lj+SEbade-?&dMTtniRMB{8dxx37*r=Qau zoG9SsafTDjVHP%Em(v~FtmSl9Oa(CL&63j{-Z3brJNrmBrxW2>1zg2e>+UByTQbNG zQiiKCxTaFAIR%|B8wr#&nlbqr)uN*FYfcl6ptab zG06`@{lb0%mIi<9*$)2QS3sMuz(0LeN--f#^%pL({q$6q+fQDc zUko<~-%)fQ`D#Q<_x`4f<+*rsw8zl3L z)L)D2vmqh-Z1@rW+ReWmmG5hP{jQbf`+9dNJoD{Q#BL51Px|e{fgFTyedgQUA zEwne9*wM#?pGOhDcU7ydCb|!IJojto~NvYnl6Sj2|2|*?d)B2OddZ)kW0xeN`W&%m{r| z>+5M(zN#A&?UwOXS$X-Yu1}N?Y51$--odx+3|%l=^fPr~r`H`ieaN}J;-}c|{j-`E zk;lKl$IHl^*%-XaoYjnERLPu&C(1h>S>TIDAZH$deT?(-h94L1lkcn`{|EKL{ZjNx z_;)or84n+GEWiAlkTo02?nV3TKWc*t@g#bx9F z_|4zGYWqacemNBYj?%*$wYLN;z=t&L_6BO71+yP|CTVcIe|8QR`MUxoS!+4yO` z?Wk;gE&bVeUoP3WZnnwB@3(%6dYokAgM|a^(YNt!w6gJ|N5pyekg_pjl5Bi*VoW2J zjj1o$cwwTx+xOBlhLMfe*Y|Q~8oFi;ZG<#nm?gk1Lsl1g*DaRKG$U9PqXHO@N7F|<6RT`YqYX) z|C>f98_$aHJt-R>$9^(8IgD&P7kC(LO~0(?s>oA*kjcge7vTS@m5tX&va#Xq2xQ~I z_=;?N>HiKX8#mS0EHK%4^KS;r#_Oo-%f|mjnGwpy)~;mZ2NUg(nUIY)vDO9Ib_l!i9ltKh#^0eWCmSm# zdZB(oHlD|~?Uap)Aq;&{_t2k>_vMj|xl4GF$;P)@KXKXkT;Tw+@s)fVt!(_B?1*J! z8 z-S`yXVsr~zL&0y14dGgF+vwylvhkU~&wP}`PGPJV{2Ek@otHB%gDx7Ub1m2QU28=8&4(F~_6r)~!?pQ1g5P002Xduz13 zJVkq>;pOiEE~R++=fLfe@bdQokG}#hZ>n#6jq&mi6yWde^IS1L?v>6Dh!5D#D>}R# zft_nGzGCP4-Y{0pWSYr>X1n@-dVdv7L){#mlE9+AYJ&Z5-m| zyC=%Ont1uMFOv^ge6|bUsqRbsw&hR49x>jFO=O=}5@%J)Pdwk}@4lZ{aZP(K$XCCw zv7zH(e{IXy!lLq7%6~Oc-tkV2NzaU<7)urR88_9x@H&ef{~~P+vWpGFNB=dNyLjfA z6T@@S$AN>6kKR2Ye5c$eXVJdVmF4&}_XrNvxb$8z)XI0GSX;>=y>o+slPIg4H{!7w z;{DeV+uBAfq3*6fN<2C}gR`E?`pH>LeeSiN7+lmDosU_wHQ3mkUD~d^80`=40FRw7 z*=Q+!Ep0EvM0awwG{@Oe;%eK7LvG`YcpGw(%jv{DBORNG$JM-b7mH$_?{(*Mkohu| ziWfM8J9sL$C_YkrFDkoIWmiOFmwc#iH8VNWld4)-Gn4auDbBGzeA6_Qv$dqmW@4Wu z7g;Xvtut#|G#1XvzKz^2U*mZlf49+2xjP8amv<_UZ352acx>5CGUquC5RR+T0*I1$kc*Tiv|#p zr_F7(#a0n})r*!uY_-K+GgXVNZB3xo1hhu0HMzD08>{%L!M?10m=IehV6R%*YeqzV z-?h%!XZAUnNhSn^U+W+Fm*hzPoXze}DB<-@TdkdZO>vf)}M*0o(QO8K=_8E^OEL|N1@B zcfTK1eYc+eoPB<1>bvK#-XyNWtlO^i-HhuMeK#!YHG9l+Wyu9csJ?q8_z3E|rwL6F zn=1TL&H>G&OwRf)?TWs;B+zbFeV6j0@0JG2J2d>zh8aSJP)tdHIf}_j!3H+x3Cw z<^Kbod&J8h#J7U&`gm`hSu$fcczKcRDQsE?%62`7_Ikq0e+*tS@$$bi&Rlr;&z^se zc=^ktm6!j5{yOaQL&$c0pm_O_vR*sm<>iIS%h!O9G`)3f*VBcjSiF25Wpd`_v@5)P zd7#~_yqxmF%a;bqA4e z?!E6$9s#khiXBwWZ`Vc^dA3e+d`nK}T{~~Mb9mYYIRYCbWn3HNJv@8)>vu0K-jDUw z6wqz--uM4}PUzvn;(YYhwz5#eB}Y2;CR+9^rQs8?)rj^zN}X`W@dzzdMWm#$Q)3qD^!MY}7xbj@)^%6Z>=<_TqJX zUw&O^L^RyDZwH%ku6k;`8+s~bbJ9~O=jo~O9_y)1uAbV|O+B^aT%xB&bS@VcCz&&a zvCM%F8+k#?9h~>RL-LV_6KeaAyAH!^N>_q+hmLlhQzLk;?RsRUgJoZBpzr;$3C}-> zFyE9T%$?dxD|&5z`?8~I_pa(sp59)G<{9|Q;_Ss4>`9?NCVxpBJ4?kdXbkseR178e z?t*r?yS|#cGd6G!Mw8^YW`D_@>E)@b(hU1RI;_FX&IlfDfl?fJ2|;E(FDaL;EM(ayz_7X|GdlKV4{Ts-m9ODxFgNeL9Eer1_%9Osm~c4U_%a@957Pf;DGwo z@Q5S%*35ey_rxqYT(~Esrp&qbLvb*-zsf+@TR8A?WqX)C>eoV~sXuWUkM8+p} z;~3wnDn{0CiH~&rQ1M0e@Hoi>yWG2PP3^{u+uQnt+}J3-%YAG3d#m7yFU|1F!l&5& z+&6(~k{>3~FV76XZHiouK-l{6-XEpS*23m#B z2j9m9?4jZOM!tiFh}`GoD#MSCOeeXVM6Q#3W|GUy__8y~cPo+aq)gcHG2g?pC*Q49 z`A+j6U<*{)AO~AuN0|Uy;5*NV{;<%y3rOhcmNJ)~if`!UQxh96T2s0LJf`)BVa0c| zA5LX0h`cBA*~j@_6&YGz6S<(i#=V2Qx=-HrExU&}wApPd@~JhYO9E{nbjy8asVeXn zhAwTO4asrg(Vf1u)9P=hkaj*1XlE_$Y^fOH`n%`X*V2yAnGFTb-7N|$?N?XKukV9x zTjX)Me`pi^GKTbBOvDc8oj$!aA9m_+c(d*U{OZl_+3>%EH}fv$zH3G5rz`z9Ed!@-0+T(@CxcU^ec()KC-|-9 z9vi`>@Y3vjrG%oy?jgi5YcR=->C%~iF@{-_D_sXo8n+wy*1=r2FDgXDK zn>tq)t?Q;PS{JY@=vnw>xy((b{n|(5Qtk>tX7~{~qLc>rVGp~xy>6o2_bMjlN8OBx zS>5LV*q401iv5d;xj=JBJMk|@uKTE2*TQoQKZE9c0s5-E2s=z?c>q8Dtjo)w{c+kd zF)=mt<<&QG9qo$k>LI>$Cng47=AGv}hyHZ#-<_D4rjmaU6Ner#N&7LnjpIAp{gk8I zDO&KiHT8|M7KFI08=i$Gh|||FS^Y;&)7VEOtHf=bBc*+DtZ01L}TNc z(!bG$BUfAg4d2@A7!&h^=2r6i(W=0u%wsMwG56AEPyJ{|$=to42e3mPKzQ!~rSHin z9p3BZu4*0Sth3g|#a+e3=vuw<4E3YU$+XV8;YT~^9RL36ss22a_HxyqiJ$9mhxE(f zMd=pw)T6V=yo1=&N+-L}pI?1Ctv|n8c>q;^emPHVNW1B;gZ}K3nMSs^j0>f9Aj1+D zuJPKkM~yA178{cIH6+fw7F$P+=5UjEZvHC7=9G@<&a4NIMh{NMTHnKSS`S_#eh$rb zf*!1LNe+5&M|lK2_#?7jv-r^zA6xsVAMHNyk=BnKKiXx~wf$%nl*z@9X4(}$+P4Dj zX7Zz%^5RGPdZ4^R!w-#^nAjnDo>TF6?vcvZ&+y^T;p=<1F^|}02lA~;zD~K$&U1c6 zVqK9@yE@NlU=qGQGyqeMeEszj#w2__8mMphy0MkpF)`Zj<%cKA?q5^-)>9ewco)3< z*W^GleB0#oy%+qMcU|T5{U7@5DK8%-^YuP2f7f~WKcDCkFMqw{)HacTkyz@ikK-T0mMrro?VW73*Fx@seOtI&(D7Mnd+}S=l%5f2ZwBq{ecYM* zxU`2&Tkau|_J-N*t)@M>lLv^1g9IZpHq;&Ds;-S?k4@xb}35 zZge3ZJfk_I{JQ>K;3HT0-~r(1iF~jIo5Enhe=hRD7e~(#pRkN|C;suQXHj#FDN8kGsYxI$W2=j^@VeZ@~ei%OSVfe&{;}btDQB^Upy=A$?y3A=$&WF~S zSfl0QUmc9TKN$b_An5+Q_U45`_vaC3Gq?RA&AW^(dP_Ra<_^}A%2mAcY$OX~si#>V zDp%cY*`j%0LtC8Xr0==y_S@@J`OKs7!$^T*Uc1wL@i>AK7GJtQ*ycZgf zyc?e?ee3fUJJu)|T*?Hnu_0DH*qCbWAX4*a0jWwE&UsG@(u||r6A>d#LI5-*{ z%x`aw3l8RkgY(mgVh!ecwa+X=m`c2s$u%PN4GyR;u+?Db2g?NqM;BLJ?Bc+UHTtZDgRR2@ zI1nGP;vf)nMogNCIh$v2aB&(3!we31=ivbQe3rq%d*EkGpQ6}c>7=wetSn5cF z18h@w85~G`g9GXdEDs0{c(3D@m^1p;=Zh^I_+!q0d(7D& zgM(>l9K7(DyBB!p;a~)3Dh&=MS~%c+Fy^fJad$8Di>02WE!_*qB>!P>AoUFns4p>R zD+C9;*KteC8GY-s74uZ>k2&*j@CyBzz2L>1fdh>>8}HyC8Hprzm1U1P``=X7n6svm z!%tRu=vnQ@_+^}!v#&Egi87yHfaf%<}T zjX8s^DE@Cwufdk75$>Uga1TX9;&q!!q7xF0ZEH$zppB5;fp;OX4-1HWIIP<-XQhF$ z_ta+oQQFJZX8u{?4R!rYPVa#sW)JYr+XF*lsTu4yh-1J7Q4vj?azF=rC@*v*);rV`g?eu6g#mb{!nj_H)YMufi}4SyX{ySK4-qNXr! zyTsF0!ADz`hEn&yvtFGbeD?576R@rCTnfM0n3s4J-rF}UdkcO8uL*^Tw^2Gfzx_YZ zAuo- ziRAgR#_x~~Ra;KjVP+?kiycW2&|=9lthFV&UYG$|43wYKy@ zyWTB>i;oP423-j*-J-rL&c5z^N;#R&KEQQMEHzZ-vrpRh5VGfUKJfjBSaAzJ zna>n3c(yR$^X8Mbbv}Vh=X0SupBw#c$b2RPZRmW)@%Oqhhb_eL?IVWI-e;}M$BTA7 z_StF7$F~JH;QvJCMEBR^P-^F7)-wC6;B@BTRK|Kb@sOv+Qhy>o*rRL2K5j9wkFuX! z`^lqrAG=2vi%qWjJ~#e*jvFiKmXCvvhXUnwEX03%z7)>MB=7W(CEj~&>D_ic#^S8$ zd9M9rK0NvS+I9<@ z58(}+<@0*%QRX2R8_G3f{;g~%6UoIOHk2a%cPAchEah#R^$Glz93tNV&-;7sSoy}H z533EO4|DFwf0hlU8$OnNXqkQPxPaeId)B>)@z8c+>{4R)*cT7E@@4LKDZaihcX{w$ z&07p@nVgmfZvj`b2jrbC4>mIPB6&Zgb9wNN#ZGBVF{|6UDsxnDkYioCb@ z%Bnv(^0UNe+joGgK2n#LC_Hj)X&Gbp_zHbEbabgp4>RADmkA%xYbTb*!bktE@DWL` zNs|*giR>x&7K=>OAw~rq{oROBIhnN}d0Pyv=*q8^kw)Oxx@D{5*UD#&w@tvt?Akn^ z|tzmUo|$Gm1%l(nZZBrJbHwzawltF>B)SH9`Rmnb>pOO zY;}d9)K%bGX%PC*m9(YL@a^9l8;#UA^oaTbi`emeb}IVTxm}r_+iJ^JXVarE$(j&4 ziCt%_dxy51jeKFeK3S%Hxptach8ItU#uUn$VE;|wTUEtS&IS&3^vU=I^_&Y)eezhNzfi6X*v8YJ zoDaX7^X&S(g6tOMZLupkIGcxJ2GPBLJ6UtC4o)eBjXfKV{Zkw7$r? zCkN^)T|;-VZDpR^yBa-YHG0Sv)i0Y$k_CyfUgf1D?Kb8dUHolu^T#ddm&}8lhnYlt zg3O7`O*8uBu35n(if__qXc+p)U{@dEchO+h7P$y~`X%q%s8c|{o<1Vwj6Tvomim&+kHt4WW6w`e zA7S0d{QM>WpXwtn462U+S5|$5He`+-3$&qgWa}ein3pl$yl{_WL86s;`LSJ(c@cf& zKLt17e>`zrIv?nRg~K`iSnq2Yc(j_^#bY7JbB&7kwlV zD6eC&^%3`cl)J`sEb-pur4@EP#-jD+obU4A^U+7qe|6c?tC!IC{`f!NMpigjFrT`gFpGS1uwd?$3FiHY-GZ;YOERvWM@GhN z$|ZIS8Mi5*2W!5W7k}Dm>{eaLACK19t#h_o{A;%phkeA)9J#{eCd@H#tt=${R!^cmoKk{l7=h!7a zss(xV1wDfe-Nj!RI^6O5Ze|XJzR0^}eVum_2ldk}j@+3qxqtY!#yyw4i*M>56kj=Q zCL2SEUD(RA-PbeMmLJwhP73UIH)u|Zx{`m4Q2zQ0?JG_5B$x4*flK6@YgO(Xh1@yH zl{*(BcP{q(F(~K7cgvoM^Zf{NQb6}4KSoPHrs?F|mck@5O;rG<9OJvSzQ{9`f%=AK z3ohjuxg@RE?IFHv4|n(M3pqZGmxm`JyVjJhrVWS3%&grP&vW>G7k0?E|Ie8>+Yb3b zcaA$fw*}rL|I=9ToyiV)BWolVJ7hRqUb^8Y%v~;a$Q7gh-RzJ}t{qb8ZmzLh8R;)} z$o~S*J+ebSI7aP|fBBhNXYaKgQfy!me5Rp<*uYw_eeDn%7P1-n2vSM*wd`Su6A(M3 z*gAQ?No1Hjbj-BP!LoNoB&S9DlTRl6w#J7$U zyTM{&d=|Bno5HbQ%}Lu0E&|s|Cwb@D4aQ-A`->}IqMv(bZh5cwZ$K9%kBH>nJ=@5q z$ev1%WE|+r&$}|8=%Sw8fcgT zrwZ>l;ElR5KG17?oQX6J#()FPd0~50IT8GeT)Y7r;wH`oY5l@94#pZB@Xo^lbJX^- zC1aa=WO*Ny(en)sm`C^uwrgiD-=eP~;Xxwf8yTJY0!tst`DAqZRvZ+HZcF}*~7CxVdLu(H$ znN82mA+y!xD6`cCWVSkqxBvVjoyu(7FH)p3Tk}sl%4}8Cl{IT*w%d@Wa+KM$U6I+I z3bdO=X4CQ_v;8bkUgo}L_n{%PJ#>iXlg2j8T}e*t)fasDbI#6vK<1JC^)bHf*V(!J zv~2a~fNb?RzpGpya`nTK@5__-6ef|a&I-Vkqim)1MYfs}sPC+arD=b!-%egxGV-KE z<4@LRD;qT7}+Re(}DKGr}@j&@QiN7b{ zWzIhCflbDa=WunLD&$(R$+p0QKTpmc!!Pl1CiX4F4zN`10F@<|e>4%PTT^6{-pRRZNt?WGC1it(OA~RRjzq6h^)(vt_HG?0% zvSit`MA@b_r31lF2l=8ggg%;wKO6r(x@`;dPVA=YwBl!5%N$AW(PfrTAnf`C4!A!c zKBnID2gH}w|GcI9{s4iu9XsN|fcKl3;Qbe*;k{UIot%lTD|w-p((tSPry~uYOkJCX zpM=btBMsMfg@#`gXg3QD*YZNc=LO0iN;Lf22SP`ScWzhDym)lV zd3JU58L_KB6)Jz8T>p1K2R-}x4q&lk2IOuA!_zwGfWRg?;I;s4K^^dq64UXB$@y&Q zkkl6)us%@V@S+^->*$gBiN@#Gl-^An4!zFZzP?8Du{ru+%)P(&LU*o3ALQ=d4+$*Z z-M!cq#bzn7Frp7$OrM$T>oZwDx!BhqrQB0LW)8F1*Ds`R@fpkgyiZa#dR_jAf2Z@( z=!AM+8lAARo3Xx?0ee}c#QIi)>mKQZmy_>@JBAMT*4lfm6TS;JcAw3}$!jS#cFmp7 zdT%2RO7dpcM4a5&a?a7ot?lHj7k#uA`?lO!E$8<;&#gU@oMP79DLkihiY+Qe#;bJW zHFdsoh}Y~m&)7xB$vm&buE?Hg#?Br!Hgjz81?*iJljAoC*v!$djm>;IbWi!fjI_;s z4(*zEp3NNnd*n;5o=m)p=QrTJ+RX76XdEv(`$v!|RZqt6diUdQtS|bs=q5$LD*89H zV6xI2>I*F23qsN^wV0? zhn75cK-NapL!HWFl_jwuDvu2WAL;mMC(hwl)V1ZYZOBSF%46ED$YXmS_P3iw9@Fw7 zkG&BnFLU2roB2T2kTbWLbzc+zt1^`Z9Hb zded*=#Ro$Vx$@8Zr#EdnNbt_wPk6s{kl-EJ1-xeM?Le0{@#j0xrQcw$b+(R7y_yRA z%hXM>ZbNH&CHk;tjbEAlo7%g|TJsg6zlXV_2mPHoVqf7NtXuc4n$8^|?s=LFW#lYQ zhjQ@@XK@1d0f9+;-%8K%la9K7uf*iz2alz0jD#LC@5j=9l`8|DKp7d^5cYX9b<o zsZ$ej>X>#+eZg0ly?30`j>A8A_qV#e>vte~OF8MYhIZvy@Z1$%#O4J4-bfC)b9hK? zLY?DCXv|Rle7LmmVdg71&nJ)1K$~3L3e2JKoObW5Q=q-Ej5!=BfBr+?$-7nPir~8_ z9C}dk!n5E_Xd2_VRoY5Y#(eXQKhUn6y)m{Gp=}bIAZw+^bs}k7nmH$A?1!>uo%tz$ z{-e@g8Ecfa^Wl4-Ppku#59WubNKV#I?fhzK-p-mUrc=)N-7j!qOno;UFDv6%Y|1bW zi3M1<{+;zP*FGggldxm!Z% z0{Dx*5t~A6fwL#T!Qo@y_IwqCfWfQ>?5qu!j!A!$edn9+3P0@t?@B);j^z)nZ>{&O z`#@R2^Frb(d}X>A>*qOB*I~_7i2UCh`W4m~8#!mD>j&9V*2VVC&Uli@m*L*TBO_Br z*t;S3?BlU=e@FZ9L~q`|9O=F3FgXKxR6%0lkC1Dq^LOe?-6(aFF0GOGbHS6yu(CeC z0sW9OA4R<=gKXPu$**FcuECBg_O7BnZk&p=cXF)Z#>1R@2n}rcyh}#%H;o6DwlSfG zeEt^#Yg+`HbvTsj6y~CW#0P*`;Fxw2GBYq-&V03vp-tZ9hw=+*fkXPO$;;etxB5H0 zZ(;!bZJ|wBFY;H!pW;f!)+^mdw3_wS%UN%7_D|??-ZOg?uc6+Y83DJOcz-tMIk;PL zUB2uc-p$N&=$5o8ILWULP04u#@4{xM}N~d zA-og%HYh5;-*A3QeW81QW!-kQhMu8cX_xh)wh|e0347kG7qMT+yMI2pXZ_Lq2_KO5 zoxOi1d^haG=VaLr0>_ceZ4o$8|Ho8pFH`YnkVj9~^W2e%!o$i-$30~97mMF_;jiiA zx4&J7KvyjC&cY zDlTkC*QUP<8T*3vzie^GepPzxrDp8B^Ts|I-;Wvl#n#w)Z|-nO8C~ydmS(Nu#)tx&sSMv-z;|#4&&~ruru~kKB{BCi2l5o zK{IwaZ>#ez_ub0uTy^woH%-HR?N#2{h z^fk06ykdkIJM>I*FI@XZ%DN#8p5*{=PAb9Oau-Vfa`w;!Y9 zE~Kw26T7rd?lB`j%?)|mwan|I6Rjt%Egeo7Zx7BHQoMwQ#aMH18Sj(y8Kpg;&l>X)A@|Ua({UERr4J+fJ;AfCogvJNk#*cQ!nE-#zWd@X zfkAOdEG4p$@7^--(^OJ3Kymo|k1QPC3=V(g$6?uowWUu|#>S!0vFcmgoIs8K@{N@L zX`sBoQ8Q=0doFGs=i=tV6Wnug6(TR^L&u2!Wu3N+!{1s6K3Eq?;&I!?iEYxcL%!Sh z9UK8Y5!=Ae_9-9Hul#?&ZE6FjY*$}QT%N^RsD8hAO4(}%}48)NA~CM9?0&u%QNS&DHrtH z=^1S3f}Dr>Gcefxx@<9<1}5>>{gHmXJJV6iWh)8k)Op!7yUQO#nTU(C}&^{P0TfBGb3%pKi2@B_t!tC>+IHI z_0JvWtuxD)Ve10uAk~pEnxDnk56w9h*_Vgf8S6|jn|0ty<+I6_EQVaw%-D@A;Q69> zA3VQNe}7t*c(-CUnUkiH$Ieh$VhjCs*!zbTe{XX6yPoIj%J;|`ZnAyM@OM2&8Q@R6p$j(=&Y&>8DY#%#*u%-?BO`1_{=?Plfglo$TK zAW;5L;_sg*%)qa^%iqy|ZJR$bvuC$U%LBG;JD@+8xp`~Qom=LM?1}z73E6YL@MZE! zME#0q{49()haX}|ad#mJrqWNlvb zLs^>_6enH%Lww+ElQ{P#=YJVbL2v9+VQg>cGom+KyUofovt05kI(OaY$(fWvN2`4E zWSzB+ZyDj__q)u^RXE3AK9211(?EG$Z?~lH!EU*O+#q+58|2PB$G+1e)xdxiIxm);R*k2t46n*W9PfE9de z&Kv943ur$Ce)`j<m3t3d|AeOm$RnFKU%e3t#FXn3K{-{7Mno-byYz$#? z($v|qDd!5exaSI$231CN?k@DfH@bKluniZSVw*UHZ_;O|lUy`AjEpMlh&tROm)eP5 zHXa<3mnNO-bTGNYpLFxLU8p2i@fq%1PGO#+$Awl@_jc?BvJP)~V&D3)y`6lhzhJB~=h%Wve>-{K`qP=4=Bq*t z%BNSlx;Xix+E}}q<0s;_BWr{APg19dI!Ww3*g%)F?&b>2En9$diyzL74`SQD&)Sph z6?}8L?vk`6I7-sz%dV}s<&m%xBmRiLomSd;KG2SXCzHb_psNSyvYhj6Mo0Ocw1JKE z(U3c)KKPu@fUY!-sgD5H7XC}SRgFvQeg2j%^n!0_4ky1}upB%`bJPp22Ckm!1%J4Q zd3|3m=x`4jdV!veM=wxWsvCMiN0|z};78!OM|#0MPTbyT=G>7%ExjOa<_YbHhM@V-Qla;o>1QYXwLvSB(8*1}>7DhCxaYmC*fnxid$DWKAmwA< zrw!Q~$r+)Ba$|plxBMEMC>_EFx6Ifdd9P!Zu`_0gVYugqX?>wu=odH;`@{8u1IAB0 z&nDUPU*Vf+kG#wa(4BL19x@@r`5(^QG zZ|gJGwA;DQFk2prU$}5e?1uOQ^N`=u``?DuqA}PVG(T*7biJpO$CrrhZH2_AM2`u* z5gizsyNkU<+)?G(=k-l6&qtkg&1T7yvn~`K^IPdl{QaBUy(WIq>Q(HULUJcurTeC- z#w5zDu4Y7>Q@Kq&$jAU+x4%a{#E|^ z8>ycN)E61q;BPuItvCLa)L-eZ-$?y6f%?S2c=d0w>t9Cw%l!3QslOsne~eXslMVlJ z>M!@#kKh--C{Vv2^?#pqXui(d#nijlUr+q$a{~38eQo^BY2J1e8}nTLD*0>T?mbP5i<8L;LK#&-$0#Fq$7(_-H?5T=FB=F_vbRUwn3vKR@ymcg%f(3BJ=1MV{R1 z%9HGUVv<5DVw{;ghH}D-q|N(n+;A2%>7K=er;v+tY@#B+ymWYAjDlNJ|6aSkb>`C4 z-$?y}Kz+gOS{t{Vza-C#o&h!W8mad-@ib}L9n8&a(TyDNcJ^Uuyp70$x1Z8qu6Ub8 zd)}H3;_ddyiPi}A{{Z|p-e%bKgLtEUggl==3Dg(7oz@xNsJD@NKMd4kd1a1)$N_I7 z4o~Cl*@gb~MjWN?(aWSiE55_5jbo^r1xK%!oJJlra8wb1RmQmI6>H!5aijI()cazf zUQfpOlcUmOyfw=hKa^#RKc{ZiG5(`CQ30%H2Vj*k{=Bm>QcvdpBY}E78RKC?(_>ti zWsG}?gUU3Ihf_Dx7)!*yRX$P2*gpWPjPa{k#%Suv7$bptJsIO&Bhq6$Hp>_v%QD8z z)Xg%+x{||>)G@vwb*)$=8RNOx$EfvWj86sX^<<21j!ciS?ZV9aaa~}H!iVL2{9fv2 z9V4*}@u6!=?+m~yV;s`i7^zoAy+oj1)-hW44?EV`+$-=I@-IY1|AK#2xi*7owaDxI zmNtct5xc?JdrKD0(5A%Ai9Z{kZAV{rC*}W(yj-y7tnKIID{qv1Y)5kbJwiUV;rP%b zZt6m{hu0FP^j@74!yaDe`fBQO$)AOws4R{hZFR#AQt*I}t#Q4TtSk77^HYy1`x~`U5y0w*GEf1WSdoo_2 zKZO?@Y;|n|x0^BWZmjVafEU3>o7g29$-OoeTQj!a$m#pmA76%j*R|t@uM5xl?`vca zGghge=f>W-cpWeP25cVM7B&xT%!&J0&l1nOgEDGM!PX&byqWqsj?1iZtRv>Dl~}hM z!eS$6D%pCh<`4e?<8apaC&{ht=6#D;IRqnV+sj6YdE?w-v*Mk2BC*9toEmeRpx?G} z*jm7?$=O@gh`z?$b0!(Mmtubz&EFEwuM;JncPDX$GG^j>cX3{_-n)w!`!sR$)LYVy z4!29z)}}^uKBw$*DO={+bj6k}--<>d*M+> zc8@Bq7Fb;W(GPjv#NTGxIVaqAowWCAq+pZrDb?*>T#SuQ^DSYc(>>G;8(qh}gpKa0 zyB!;y@q1PimuK$d(m5J>T%z>@4wOn_KnP~o*&@5;&7U^o+h!L;{LuW=xacr zFR544y4a0XvvLc%wg}-zp8cW1?{}1M=dw>iSC5(FI|q=V-1b^WURT}bh>=&w9U=~I zu>6!A?$;pBcTPIacLVoqv@Vq2=ePe<+Pe?>c3-Svo6CEW3uR5JUX)UN=(nij^UC<` zs7}5O&H62x@A%Q0X;bKf>2m`5mBgURJs{jg!CtcBk7o&eb>ff3#-McM&NO{p!CEu# zJo-9|xn{m}4cu(eSKbHXkFNnAN>iuBQuor9KF7H){%Nbep|8>|uv`WlzW8I{QM}zL z`;-_;EB2W6T37Pm32L`oBe-|l5}2i|{M8U|`m*qS@E*-CQv3yRB)J&UILaQU{3psO zKJY13xwN{-;D~n~jwZ)a7Z@B}Y~hIa!8qkp4340I|6y$W!4dT(PFd!v znfHp9i{U}^tm`Z8?= z*HNj9qf7FOGver6`b^Fdo^d`h+Pro-ujTpr;Y%93+}p{+d$z&TIAC|z(rpG$yo2T)M_C1WHOpd+>ZC88`9}2Xa#rL4)#rJSxpuEmuj zUqIS!pIQGh`jLHZy@WMXL{6r1E8iFEy+L^WdvOQIV)~Z8vgwQl=1$|ED?~m%f*AW8 zbvnJP?ZD^$K&Lw(Yq&_)u$%j1IWmvAXA8X|SDo$)Mps{&=BIOMS9vV&Jbnsqyq-0v zG!P!*@e1Atb-G1&r**mow59Y9p71mJ^6DF2L4DEbp5|LOb-GHU)0NSm!V3SOS?mtEaXbu!vizP{X&q5V2pUCG!}5{=jhr_)YI z?GEQ~uEW*I;vM~AJJ17L@e8~RAJ8+c_?#yK6TGQG{O)4sAy%lNwO_1Z2zlD8Onl`; z;wvX&W1p?(0qaVxJ~dHs3TH`m{ONOhCkTC~9b3<6nc(I}oZzqDO8tR>`bSg$SKo)m z!N0`!wgcP%3-HDo{sK(I*raVxBqx4IW6}s_4m<8ACCw65S+=`+!pe?OKt#JTe@!O zFDh|J^xr}plAOI%xWz|f!#xTAU!YBg#v4DBb$-<4(cSR}?*M~*s8=;EKS_FkcGaw;*5*qc_I3Vq|bnRBCJZ~DCXeRrrK%6B;-aJXx5oboxfnFjvvC`ek(!Aprz+v8b zyaQVMPhi${4^Q!U2k+IUIw9ofWaC1qXYX=($GBMPDcVxr0gspn|M%(}-a&nV>?`3?nlf`bY03cU+4LY!(GoV5~*8s}cb zX`$3+Xq4|R4rqs*sjB8oj4`ztr`HAQJM@h6^Wa+NXGVH{B(69q zam8CS7P_*8wI0Vef2rLDYhBw|Y2q@2x{JtnhjWjV$afvjSH(2Xl|PPhn7dwcIbU@G zu)sTdbiV4V8<^ww<0w1WXkTMb%K54!|GSg_u$l6GnU465Z}rc&o-y;)~-fIPx7bhl!(;&@s=~ewMRpZ%>?>%HTy+r_L$D&EzbqVO6Nu1ba5r|mXFEZN#N;SinpvQnOmTC z%Q@a0ADZ!&e`8IH&BN@CuFh*^+!NS5zEjYPbJVqM9<3X@Ve_C} zv3aDZW4D{t=0SO}dHgL<-r*k^?$C*d4&mO%MZ9ol=N%`?nv(tJ#xcHI@s`J7AMPOI z+HktDVcFs>d%JL|pOHO~hix%!x3S`;Y?}sg*46O64ajV2zeQH7#TWEm-6tc z&N{u()#XoN?TvMxlvO@YA(& zPHTqxQtL`yADpO=_`kq9I}15ypsaWL8qYVe6%YeZFLIX1!P39z*5Z?Fn~mM2w`0rI ze6eB!E<~QCjGS>2UjsJigq(-@#tGydgD!f0-@;hx`xO@w8@sT*H?W?8-l=qSmdeO# z-!^TkF9})C*yByR@;#g%Ygi?1Bj0&#kMOsB0&O?buF74rkdc8~pJ%6KuxfnFHM{XO zTlgvKQ(oFPfFJ)pv}_%jcu{<0{YGS2jr|8NRq;jj_y+1X3=D7oIP+}AyR5*$p`8Dc z+`1xXda($`AFXzruKm&C7xnzn;Gr{rw3PMy(Ui^RkCt+ZFUoKyx5n`AuRr=g%Q`2> ze!i)p#W~kn>;iJmH98#~O6>yTn-#kNf1G)h^RAuR z23BGlkTPyO!aY2Dwtojty2@^LfbtbkYufEaKsV}gU@~xS6bss$k4We&-e#xRimfsXT-MhDZC;e5qdFwgb2aPCg z*BnLY=$jaS-~51|Z$9?7-VWdVo#rLM-t{nJa^=%I%=md1GcxP^SnBBwF8tU^JU<`r zrBC(q&365K*ibeY9L$QPZZ>C?0M$K6JSwlk-t`hql`|xLDSLi`VL1&ntQoP7)t-0bgKfyaHh)BIoHkgGZOA7fXv)K?@9`a( zWJ7#T{lvrESh4G?X7^_Ve7dOhGR5ON>lGf3nXtjtu^(Z6jAm+agn3cbp?r zY@nR#lZEho`nijK#=qst6SL{Zm7fgV7|*!HcBJhMaoVe9?4OnPhDdHNw>|isX>Ty? z`Fu21&UG1!&fUe<8lD{4UNdQ+Z*D}Mc(cksH&U-=_dGY&Xc2j_7IJTNpA2`Ix-o5? z$P}l3@84FY&~vEBqD|ejpEL#RCrx5M=?@;elqoXVBP=;1Q*7{3LxcLji(ETcF@5c? z?;))d^}v@9x9x_`y%1`bW}g`zE4d>!Rb-F38L7GJ+0*Q`Dwm(+nYGBfkl``x&ksU3 zlrB!Tcr5Q#XJap_j6V=M&OTATIxv>%LtFaH-n^8)y!wX6QeR?jt`Rwkc6BdK_RIMi zmlWhHH{w(H5b=NXWoT;4D$d%k;*9+2u=v$DAHey#!^zWX@7p;eidV94MK=;%=n~_1 zMZXam+rsqPKp1rz?7}~4+ZI;pIKkl?>0c~PCA0&Aol99ff3TQ|0o{WbRyU_8n z9J~Wf6?xTJYeJ*8uV@QJxgp)9pAFuDU@gI?Ud_~o6NdT zwpHl7WvhDHhRM25R`Cf;VqbqK0F&C+<6Y(^(=myC{jNZLhmKmg$yS2%m42LW1n2AR zdf;5^%~|NuU)#=U?~9K1^h?RVBz#P4=VM*j>`ZWK-j#Q8r%)+yw2fnaCxBbxm222v zRnYdC(x%ZF;iK$}di+)^8r`_z4ZB0zMUPxVxre^P9OhzA|2Mm179I0|@`JB~=N{P8 zD@*=3TJ7oW-^*Z6x9wtG*zfi~Uzuei?85dYcg%{7uuI!pMD|DD+P#hB?8NR?jonS| z6WWCBXQ#+&*k+u&cSfO`x$7IBT{C{pYU1%XVCPs1osj)PJhR6)t_0WSoyRxWC*Nnk z6iL}>7T@5#+E$R|G_L~u<63ZRctwlQB{!bsd7i!chHp?`V0npezF195wi7!SzQ+Rb zW!999GE3V#WJ3F}f9k5w6 zx&8)~C3EmMbd(|SHJul_!Q@5oiBQdjCp-_zK8LYq`pw9X5gz9qiyvw^-(w(4JD*SF51oBFNP zUl6E2%Bp{tU7z?mI_p z_YNyQk2*b30UiA3cMKi0a^!Xg7ufy|bzDsA3KxsG=N();kO>!!y|8EZ$DTcabEv%% zHD#Q8!tRD2C)F||qpNa|a{8y2Kv-9`}WHiGz{F?k7HBQ=xty!NHwC2hwW zqB&iX)7Tr>#N=KB8G8r4e3Hl(PHz9(f9lF6m!)Nkk<5w8E4=e$3-ruSuwR7+$$3&= zj2dmpSxME)k=>31CY7niamI+Y^cfu{Nnc)lBU{j}!17PNbs3}P*UeuqdFCjUuO=uC zfNKV}SR-FyUu^>q#sDD0zM2`omYreASVM>#8{%I#!Ylqvd3)VBwAbX`FU7`q9_MCzb-0hk@KOB8 z-d*S78*76%mLDYF*l6krC)t9`4`97$2whHmj;hS4EiZd8} zxaVLXez^hAs5$N8rxTw}Z3I7E#X$bg<^P=aD0cT+{B$*(@f1Iuoaw5?pI3`7FB`ve z{IY|JtEG&gV?29)x!rRQ7#(}!cF~LH>bd&b#{Tt1$2zzcKZ&s&%D6TuZFX|#RzaVe zm$NtV6>f;kZ$HAdquBnr-L$KF^CfFr9 z0d_nG2ly!AL6S4L3Vwtig?<-+g9Yu+Xl`cK>%(dK^nk$u?>zc6pBM-FQXJfE;ehw* zo185;z()y>{2zmZS+Uf^1_!gb!`9$H>KhzTUtk$8IN-g~nY*D+^sUbir)f_0)A;6E zhZa{o!TmE94j!dHnKQvbbN>JiR92C7Aa@5lcMMDZL-Eg5V=vf%tssF6s&jsG8V4&3 z4tVF`AP%es2l&rC8qIsjOQZa{(#d^ZZsA~Sz8?qU@lm$HKV>Z-lj_-<^C-UyKDu)P`-MGILp)Pe zWI+99WLm?^YOtNixtL~bD~6w4M2-)|)y42cH}B&K23Nc*H}>|4vDEnnS2L_QMBXbu zgGVYqgRgzS;A%)LwTihhOii3wutjanfzr3-HuS{>JybY>Jya#eL~M_et~-&JGCR69avDD-IHg=C{%U5Gy5?{^P0hn^} z)tLI?tNC!CzOyDQU(F-f93H`juqEW^Ki@el5kW6JiF(dHw{&Emzp|rW<}l62<@d|H z^i4;e$mN{FtGD;uFEg9|pp7bb3Z3@OpW~bJ-6Qkw=a;E;&p9Yf%rzGcww8{x5kLJn z@Vvi%8C{=;AFh6xZ!qW1Inbp@yn=BANfOk%0>p0_-Ku>RT=fb zpY_IGazJ?Cy|)PubkBO@n~54b0J4+#S=3LC4C2MiB0q^u+OYvF#RjmXeL8ebWhUg4 zDpx-GJ?)xzo_vXnlMmfd83$e6lP`I%eipR>U<<$o(6T;l1Nb=cK`LJ&KTYP@t8Zj% z>WiP{Ya(CLuF$}w*Z?efDd=a>HTtS!2Wg`(?(1~w%}LASwx31IU)e7a!3OXr%6C}P zhnAn^fUJ!ZbZsn2+tT)=@8MB=Tuz)ja?H2DN7^Rh$VUsPYs*KUr%cZB5$%e6R1s)5 zt9(Rxk&mtll<$swbf9usNbb>tWzX3}-<{cWve}?!9z>Y0%LMbk;9i<@YZto4J)?Cm zJ^sy(d+96GwfEAuDUxN*<`a#gPYUOg@Zt#O$pj*6Zf5qd%Nhs6MulzV$J@ z_)d84AF11n-0=6?;N2I;8uGZewTyS@Kq{}d+(275_}da6ReqqYo5X)gJI%C{z7e~N1*)G+|J*wei`M*=dG z#LyUd$;ePQ(vNv(%TV>;%aeif+;adKWT;A+2Z_-cNS=f@(=yawdG_iDWT+96e=c_! zs;T6`4!0A1b%Vd^2AG7>zh_C!h zfi@hvbfFt#Xq_3eY!99vqaX4qc$fSiJNm^M;^>di!H(xC;~DP7=xyDL;p0zT$Bu9K zhC7d(qxyF`kM+;6Yumf8F!ZZFpOi|$WCtxT zvcqkG@>ykv414rI$>FzTf$_0JFpE-yy-_Zrk9u4h-uS9qkRSc}Qs3Z! z`r-?g9P8cj1=~3IsD*?5@dY25a?kGJ_ciO_e=FT}z&j5I_-scT9CYCe{=aXy>i`+| z^R%z)0AKJDo^>5%@C7gDTQ_~dbtSGZcrX2#b&!iM_?ML5A7AjtjZBVCH`et9Z#1~# zUAg58{uT40W1Z2tFL<-T)e!u>v~PUD6|`&ng1^Bx)1J3}Twn0rQjdOAcJ9I#tn$I2 z(^N*kkG^y81viyEbE@8ZwvqCVo%7K31s^CHyX)pIWUSB>m9dt9le9kR$XKJ9J6p#3 zAZ2ovv1nIhteJs!v&vYM7a8j#f$~{pEZgqUg|B4?ICwAYGq+`mIk(~L!ah?UfHN&O zSh3HI;!7?dzLhgH#KuVenjI2rNorDN zEsZ1H_>4vM*n=|U<6F|+#<>>B)l%EYnKg7#;_rwdS{1GuCoO?GgiVwOr0HgY#wI9jHH`2++_lMASp+_|v{q@BM{jETKXDwPj z=&5qg3A+3=wIL}T-&j^&x{i7deL0($$vh`!(&uCA=!5>W=8*FHpg+pEl^<|ku&c9y zv*@!8`^^5H4V(@Re)!+aUoJlAYsSo}i92(<6WXo$XX1-G=AR)}D3|+C#GmEmpJDxU zntz6}Uj7-%X3ali_y}co!b>C$Yk%|4pzrJ1K=j?FZtD9@0exT3ihl(>_rM3;RPtC< zeb8@InssLRpyO8lWS1^>c4x8JiO_2_*WT^GrF4?LW^(Ou&uDJB_I&n<^j$iw*o!mW zWBeLt2BX$J#@Eodk3IprXH!%f<@e3rYveuV*~lY>M#*$%p zufADmjO2dCCZ75)@ToFhB$gT^xf@(sR4RB8`Xe?+Xi&Tj*^Vz*TME_0Rz=LHIXr%AXYyz3|>k~CUmS4Y)faCY| z>sacC#6~0gHM#aRr8ha)*E-S}>}!{P-LGG7+mBf52Q+swbM;bMuezOfb)WIh)2o&f z1Iqfzy2<58U0%9E?#}3ThgxR*Zug`P5s)-g>*Ol3B00TSM5iv^$LRn zOTV6Pa1hY1Z!kExyL0_|slmalSZa~M0s8f$ChxPtFJ%oBFkfgU?tvC?DXD zGd?kgSnCh{v!i}}w823@zy7$v!D(K@W=-0Q=zR|D0!n3Xesc&#VeTlWc zg>T)|uPcpyeY}MO{1xiE`^!zPjK$i>MdyCwzxPk)4!67byEx6S9(Vhem}ie)Ay54u zaO(JHSp16j!T9T60*m4do%<5nH#+wZXxG-c&*7VC&%-C}N&NMvq#pg`sB?R~>UsLk zN#|ZfEE4h8k5fLBDgHWxt$YW3*Vtn3)Vx%FUU4y%g6G7x%>-l-06-hr;6_eF50 zG?!^KbAkGy0f-8IRx+!3#G0yl4kFCGx`5f1eLep?bYnXE)uDw}&I8*{BzjwXOugPI3caa`FRhPW zGiE?^SZKvD={y0c<}za7p=n{x^^jYWuniVEa_d55R(D-I_o4uYv`u@mpv(Qs`6JuE-A4AN*!oL{qLo%_>y|!7E-O$Yv;G{D!aU~yM#1HtCjQJ z+J}N`jo$^H5npGo$6_mLLQdSuj?e7jZk`OdfzA!#PI~#4#!Z$vfseF+56M5xT|^D$ z9-_b9#9r%5e6gLwp)YYCPjC~jZ5o&^IGA*V-z_d)y&+>+6aeZsb1jOch{)B{@k(Z z7#Z*L;IqoL3jyb?f@_5fcw~;nX15tUs4PPJhr4AIu8O7YHe7pGZ6VieDA8B@f3#+6 zWa)3Y7j?U=qip#;OdZAx%ubzUl1m|0;O0E+e5`CX|5)uc&sb_Ektcw0dV7v}mV9Iy zPa`@%V|<9;RTW|@UDEy}&&;LfDXm#aU0}cQYhNwhc4N&IHS8Pimr0+Oq3#ddx(+^; zv^Ve@In0S2rG3F3-qYv-Qm`Csoj0&^BTgY#jGo?4wYp#GkAWsN=D008acpW}u!*AVR z6~MjNsWxKkF?8=%&IZc(%sdE8*U5Q7?Avm8R6?FznB=#)lWINhhtRjkYenJEg93-h zYXV~nFxK&1zJVv*_aax%bjvC2EOY59W4TMp^4*k`w)U>F?w0Cg-}K61-~4IaLEJYs z?97F^2SDiP$*e(*6D~z&e$6P~phHnb&Bre1y4T zKPbIo-anvir`NQh2@CB$8?Bt(z$|^rKDr(pC!u{ppJcD7?9X_Fo;SN|-gi%8CwP%H zuXrG5P6R&HD^xz@EW7b1M8^77t zD#Hh5g)xF-fg$3S2M%!G!2Ui>aLziAn9LQ>4Tm?&Z+Nx*7M@1FJgM*X0nS98@_tJj z@)wk8ZeG)~s1%uOEa1)oPlD>+&oW6jWKjMCQtWayWM| zGzh(G8&lq}6W!2Tzs#}teq|jC{lENc+@B_U3iw0eX}@J1H0YdjAN^AXx7fc831n}p9;bD!!^-rB=5_X3a5)&KqK`+P;>&EMxM{~z&{<|7YjzVhOY z@ADO*FUWlj$N#tkU#ZMh=j{$(c@a9+6<_($josrb2SC41kF^tCb5x41hJLPG`b}6gl&hLPQUU!6n5l)(FJ^EU4AL{JQVF)<+~|s^USXJ z*Q6l7%fi1t%A6)ehI93zuJ~5(8xA7h3g{(4J>$`3dwhE1zIcY% zJ^V4sTd-T!;B!$w5O+IN8{Y!{P0^X#(9gxT^_tRjCr&MVMrh#VrT9M3>9NTVN}96h zFjDqqQx@7RWyiW@#g;)FZ^PbImfiLMz_!iwhrTWS9n}eJKQ(1t*iuWJab$$8(XxrS zx~STcvBfLy#9rKpK8Srp{9%*eOA_;3gWt*E^HGy;8ykn>6CNlyy2HQ$FBX_v1&%_o ztu4l0>g0*R4*2{@n`Qrt&WnvB6zwZEjlqI*)1Hg-8%%rdxEiIsAsyTM`zE(N?1-j4 z9XqyY}G*mCe^Hi-R7e4ApQ zolKiMkWs|%RXr!PUF@wN&7mJz?*dZ`_!1dW`ZTgs(6%ISq-}TEaVzxgjW2g18wTb= z%KxPs<%9HLJaGHw&XyM}n@cO}=jDNpy>}LMbR9+|}VAnSG(0?gkg|#+} zy;$PXgrCS-4chImH+K7FgAQpqb?x>4+H&d(_Y1$X=u?0u2WjkB_G70s7CNXh1pH6q zaC(PMebn_|h%fH**F)ndBRoX>2yO7KHr9#6<%s+sG_!<042=`n!>7x4LO-vB4s|8p zoUM*TK(*FfL>#@fR)M=;HfG za3^~a+svSM*07G*hxqO|=SDfsj@9r@=0W_PHja&t!HysC@qxfNWPgi&KW*2x#t?U6 zRiq5Q#s*J@IuLC%`u*2tt%g44#G!^Hr{%AwCBpnZe>!p(Yci`3JJ6QE3*I{CV;Sm< zi|r$PX6qTveag>}^)CKd-~I~Jas6j%_Y!$7k64rsE36sn#?!boc#K*6*?tb%yktDz zy#KBB9qgPIJhE0~E&P;nj%DH?$X=fu0gSD3cq7*IDTeq zTGFPhJAui@&Hk*ri*g*(jfd=*B-S_|KdGEg1^?&{Yn~=omguqU@%%pJ&quGzzazRP zl&Gl?{cK5n3x4mh@Xx0&$-A{m;(zcz-xvx#Bskr|9G3E5-i4`C1q~7WFJ&G?-jMb` zD|CVHrHl8hH{~|aS4j3t)3n5;d`~vww?$8B;Y^~Qi7kw!$eHED67hVsJWKqN%qu!u z8@e*S@?BL%&lcae%C?*p6I~Ekq`oO1ZE-uU8Nwl}jK4X z!5tyubG&i^IuIONFZz`>gx8NfhC8MCE8v|E{!ZF(=!a83+AEYAb5scZzI;G*5V0~t zL+JJvo*AdnOMJY>=A-NniQ7{A!?V8olxsIYXRZ-Fp5J0$*oS_o>jV8y)|ITc9qxK- zrfduEt0}8C4c4jL%O>|LjCFODs`;VqEz`(PcNlp~t{jnQyt}-#kbMnL*0>C8OHQsc z`gw(Qr#bAT&ZKmmNKJX^l(Fxu7dUMG+^OA*F{#~4Vp&*U(NUo{qJ2YicQFUV>(rgy zl9zz59d*_mXaxES~a?&^iyhc0kmKRU6IyUvFK!)#zM2eY7@qTN}JL^xi%E`SEiq}<&qb7l` zkaDk6Zk$zaJUX|QyDVKUPPxBQPVZ!M$NL|q95N{IX?taq`y=HBTJ5bh<+wM_l&hfJ z^OVb{+)x7-ceR=C8~Oee-<`Qj+XaaS4iOI+TE-tVo1olK=mq{l6fELT_MON9{2pNT z*j9=8&9H_yu$M*0l6~F68J%+AEO*a;eVJ#)3G-gLM$R{|Z-}|xYGR4-mm&*l%(d9v z3~%_7jCB@kV7AUhQ^}>rBnrv5x8B8xDTh7PDd(&eEf=TU*Ik_aiu20SPRmjkC$!Vb z_b+=m$!<##8lq!kEvpR0*e3K!kL{E64bF9)EnsXit~D;-X<=@q&N#|9PsJ89+3ml5 ze4>%ugP(Tc+YEgAeM0)Xz`xjo&!Q_C=u;5BYGTX{?oY7bJ2eY@-=(|{zS~brYy`eD zT=*)2@bO*d;q?84?_<$4eDAPc4gT`8z!#&u55CjRQ1}MB@GT6&$9IA6h)nS1uy(if zPs8_H;5%LBm$lnco?g2#BU`v@*YJOMmvdeK`V8Io*75_iX|3hgORha4(fa8%r7w?m z=zv+vzcJ+u-J@LOGiyp;q@2(JQ?A`D=dNjOuaI(0loL8|v|01Sx+=Y+okqTI<9i1h zo&!#f9G}LC@D_uU@ALpCVcPWJdbbI|Dd5&XhAap3=)hDLzBNJk z_+G~MNtxiQu;Pp13q^*HRJeW%zMGiLFm>FF8P<7W8FF50=IcP#bU{;>wR3-D}Y z<p_n@*2}PtWF5}rtZ&Wk(Z$A2AUs;u zLe1_a#bWcA;lXu>(4!PWCN2?HjU2k;kbPTxq z=oH_aRXGpb(f*`;*gXWlA<;8O*V|`w?oe5ON&U5pzs$JevpFa7P3zkFkM1g6&3Ww}3q=?It4yo4mH)J|Xclx9t}0I+ppD z`;L9M8HlV9z>Vzhv|rIWGZa{h;%hVdv)GHHw7&zJNQ8CNi$C-mJqIQ8D&N07Na6-8 zIvx+i4ba|($e4P8^AdNRBAXAWX?52tb`EJLG`&}1v9v9=jyHkF+mN)%H-}u-Raz!~YW%SQI&h_K-M-CvDS-pYfivlO# zWUtA0a*Q>Eu5)nrk5T*9W4~!&jy0E0IGlgtE4&lF#vZEQX3mLZX?qE63tZ5%da3&Y zb(tR@F6L22eB;~sCUDE2FP5T<`F{+WCwofgNbC#X$v@x97xlbFbEN1*qgMrOEWvd( z;68u5Gx_an*MiH?Db-hir4|0#fu=&YOgTdnIX^N*)^AAkJ;SFn(9r$m5eqKp$Rmc{ z``+=0yP1m)c*rn5gOAR5M3vW8&w0eBei`5qje(dB&Q>aqVDDFLB>z;!sP-_vleyGG zZc*B5_Rn2=StqhTuz7|#3$yz|!8!Cg!v3{*L^b*LwyY$NmBS%8uavKWHs` z!s8M1-2H*=vR>&4yy8yEC@m5Hj!SdAT!U778)@(1Kzq|^PiVKmJM!9&yyFKA-Qpc} zCGd`q|EI${gl@>)@ET7AoWe&|hTmSl5*XCa2A{8FFPQ${UbWwRrLF|NQsnkqeV?0$ zaE>3J5qR!Zf$!k%pMb2w)}0ECb9p7CjC-%g^o0-{M06JmQB+2n3JXZbn z=qKv0clW#Kxw_ZUL1gX8x$-mkFYBIIyn>cHkPq+h_t8opUk~)*-=~)R$9^(;tH}HG zp$DK2e`yvCj&m^Cb z_@JU;k;O;1bDv78WfHJYM%Kc&b|QT@FGRmx=;*rPsO#sN-VfT z&+=d7eEFY6&aW#;ejxFOD_vSmd|w-7CEslbURFT=I&bi;aeI;T+&*rhUnBdQcfr20 z$o_RDRTC3i-2PgYy7#v%CFkqvu-L@vO6H!D5Zn2Y*4!sw3Qu`S))#oF=@a5OA zmuJAiTMu^=2UmVD@oj?xx7|GSCDX_J41Kh8w~wMpi8W^23*B)q42-*=ytE1aXZDqh zyPC1u<2@|{EI;cmEH6w-ED4NPXhI8dqW`t$t@RMUTU&_poXI=vmRCgkuNj`4!#Z?v zv%)RYJR3jQEY}Y<3mrh#DSoiE#veO7)_~6En=k3-BI>tLUhF(NHnZ;Fi5h>xw-E6s zp92@V{;+ZEm}8aaJ91Nh?pSZwfp5&fb>GqHIoo;7TkE%)J1SkcuLMuct>J{w!f<){ z^P!9KZWX_y_^+i6*(0)U%{Y?N+_6pL9pA_EeLUZFjJ;f2R3Y_glXttYQ>d=r#=D~4 z&@|e;kz8%yK=r$3Da&6Q)(0eYg%@Eq8Rw3&Y1!y|D)m1I%!jJ zMjgcgFuq{nK*k|^9(^n!aM8Eu^K~V~rzKieI{UokHCN|;jr)GBeOHKVbP71P*Pr(F z()20N^9GUQY?>uwUgr9Xs+R#HdZ5ZNkpT&@ue^QP&wcr5gg-=w#jc5lM_(a%!?bMN zwLQj>iJ;wDW=d>I=(^qmJv}T)-|<*+tZuL z_sU*|kJSe7@+HBGYc~*jwmb#idO;H>NWK(o%O_87kaIiD$P!mWOPe|8ljON=g7VOU zHaXjKyptnEZ5MkZE6lketsg#f%FGNlX5rI$3mn@2wO*_r`nsI<#U2ukJ~^CtxDn_T z%auQ3Z&e`?bxt`cJ_r2b<0*# zS+aF%V$TYPFAI&AaVLcj0$W)8TYLAcF9HUYgWxY`k`LYB{C@g3a=3XX|83iT7CF4K z;op6k-@f29IR&c|MYNT^F|Pxw>e*u<1qkpxmiX`@}^4Bk;{vQMN|AYET`j6s=N-htj+Loge z%5Qj@>Yg_tQqUqG1<$NE{H(NKIZhVe2sKYnW zXM{gjyvbNT5}T5|Atd>@H0PQ;D=nS{95;ZgQK13T=Ab777w?;nIkzAo_cQO98cLNA zlh!g7{PJxc&&k>13ojqg_B6T>?=&7^QY6u~K7_7Hd(-$oMe(#EIWDaIB&Pur_Qtkx z_(z$y&mH61v}kK5-_GLOcy#--81q?XT&KrUvv_|~UitIOuREL=?Y`>@`iC^mA-_L( znixt=03Rn(KL3bVs_!wORKX~|5999`zE29J`i>&Lbr^V}oxZ2?{bat)BTw3?e4mWH z>*QE!^MAgxz706Wo(F!<0}e;mFNo%k8ITM)`R=0NF)BV}{%Up)D#o5UNbtb?AxjKZ zKdRX86gRYa4E^QtEkau}z^hqHQdjt*$nti3&c2x|KHJIiEbvH~qH~C6cKZr3j;X*J zinxATbpGfu%&S{R`j#^1P^Q`B5SB8>cPz7jGFz>_X1aaJ`jB?U(67Lu<2eVNd2py9 zI@p=hM_oBeVAOgihZ-(%%eGC7rA}l{b{2wb=49tM@I56Y>mh}FD0TqWftyosf&=gW z;=57UuW{C=_Rq8Ff9JSZYFA+_m46L$cqZ*mr_Jk_!!wyf&LKpn(`Ij3Kfo8xFW6>$ z&*Wy0o*bJ}=?Ju?v${IoeIJ`LUfawsNREk2 zNsft6DeC9$8*tSI?N!+RzAa=v@C zX&&qHJpSgz(sT(L-1j2Z>|)+8;O`>Z=m%X|97`1}aOu(tzJH!?zhO?W6b%qsdR~N5!yNiSuX1Nmq%uxOCvd^ zE;{g{j&$i+i!L#a!NBU#rGCtDkST(Pv{q zcTSVvslEG#5Mwy#P5$p25t%{^hf}W6k`*}bpmpcK%Np|%$%P?ZyKR&aSz(Rns!Kzu zOIq#ECGZ*NZYh3xHnQtOrTuU2U-Mc`OBjQt%hE@Zw ztepw02eXDwoCj>rLDQ~d{{P9`zY%JPUdLSZW&Vc&6TYxNeBqt-*jjaubLM4`=!!Cz zdH-Y%--tC#mo?6x#5eWk@3CEuPATJT*^=kTH(T?k+;R z5<P=@7_>P0otZgv=A1J#=gjP3zxQj>H$C>E-(V{^M&O&iZ_|D6)VxvVbr!q|T=UCC@K z>#xdQ^o90!EB!4AWn!UFCc2gWl;-=}9_(+a?r%vd6A7gX`uhcMf1e1a2cGcvwR_Z- z=1qaVO8c{muSr_qYakNy?^(AEeWv)cANuutpI+Ntbu?QuJe|GGvgemt_lgb%uXE1$ z9zf6CVcFRS=+Eu+7y9}j?dqusWwJG?{C>n8!>|_|mh5RCCi>{T4c84zN1%iG-aech zmV7QkA1DX@H?S}5&^3HgbiPjZ`_2A@@J@-F^(bc~`dj|1^FjWL{t3VGokOU4KRZ1A z!Yz7#;&$3hUeT>1v_tJl+={;R-|U-fm|vn!vnOHVg7pl#ClN1AAJTR8-agEs+1mp+ zK&LJZ;NVMw1KO5bJuIDD&wafU(4Uv`y^e3urD+@I(sm9!3I7(HS3}2p%LjJ+bTv8! zb5HT~_4MsF?#-A8U!G0AvHbt_z^m(8C#1_q;agS#y~ZrNZ_k7@c8yBkjm{Qc9NN&S zc|-4n;pu@1!;?K#!<}*a>uCDq&MnP9WJo#o_kb8nU zo}kS~2s0*SlS!KkUzkkX3feHYJ~I`0Df;dL#%;lJ!mJ6VioVqXFC!ftsQ8*-1!GN` zSrh!#f9W;B!=5z(-!eCZmt`M@|F9diU37de%8{tBCu&_}|d3aFG6{v( z*t+-5cW7G0Q+Ir(WoK8Hq~p^qzRA0k{-Os6{l}L%?N)i=?V?`@{zSLiSFPs;@cT$> zlC%q1XQaS=EkATUS&zBvj9TRR62@W?X-)hXhulKwWl_Cd)&%Z>@5=jwjGf5)#g=WY z|8y(xb@pM`_1F)y6^PdA22%RO<}NM9J^U^TqU^xEL^%JSQyztm%xEOKX%3 zt}_Il;(aYm$!Co24;&eX_yH}?30w4|nzp*~d?EFF<+;u?i#)D8mpop1uJhE9$Cc;A z&DV7)c}}>BdR3eFjvc7a#5P))=tgH;yUaSnl)GE6GYIGA>2<~&#)2{Ft79zIT6T0T zxM}47c-muh&PMt~_(JA4Xva&8;YQ$Y0Om2qa3l3y3Cs<^ zEVjx>!HDdRcVI^%e0 zQmt2{t<%Y?ap~m;qNgOBG}TVQBlK~x{IZn4n0CC%TH~y&H#8j5z9xNg;lOW(f}#3< zd|r}wJDfEb-%p$U%#Js==!F?ua}}%1oFxq^pd9Y|^VHRZ$2fE`Fry@?>Pyn+J(jJ$S3(DM zX8$Lp&fVdKqU&5Cxa!+O-a1Ez*%rnYGST_KuYQ3}LH(jzXUFlz82J@m7uRRLpwEPg zmHVmK+Zme^4O8kCTFufnp;c3t#Q#Y2)fsb>U#QS)LdHtTUfOh;^1eN%t?+?Xep@~3 zx>n>s8Xj>s@!R;N8IvmHz}?7!ZCVcOCVeMqv(a^TlU{=y*jaB^{;8G&Gil#Uk$DQQ zL&$;hyc{6ED+g-8AMK6-Q^^6+BEZ`JF|QmbFCquZlM1IT3k&7I^pLaP1YC=Lv~Tdp zfhuS(CSZ%asFst2R-uoF9r@->qp+cv}{ILGr5c)Ofd0_)ld4lRe5LBmT5*Lfqe+J%iO&0n zpJjcb-zqh6KRdvFce#^C)0N&ERvU3Uq5HGZ^9(HZSODtu7m z$gJ0LVnarqwA22k-1qRK()4wo39JQ2TiCSG#|iWWoZzpL`Ag1~c`r3{vWoi=#qVJ> z_cl&QWlqq4=G*8@Z_aZ50zIg7 z*2`@dZ)ujcxH1)bQ2jo6O)@*qv1f~yTCd7_NahmbcA7nw>m|>bkE`)^?Af}j{CfkQ zGiP)6in+^9-KkOvt+5t+^xA-58G8!K{))Pb+Wj{=XW*=>l^nwPT@^`!Js$e;je-Zh!v(Pcg*LjkBZI?NIXKkN6)QJt9 znhWkdJiMW!>)uCtV$)|1dHLXnfwfDoM~=LH*;Pk?Cu zfiL#m?~h)FK3L;f6Z5TL)}SAEPvD+4@CqF6Kgt|<^_M%Im-m*T_g!sHS_g4Ig4TC6 zPB_%jxZ)7&)QqY})4N-qd9#zeySrB$dJvz{OQ>7sj->A(zVEZV!TLdKLrBXVQ|?~U zda3_CuW!fWSY!>RFpoyOUTdG(pEfP2+{(mqc7 zx1bM`kNey*bBViI#-}nrKJ~kLnd>+w>0e<1${1lM)ox=!tdt2LTB?+@a*)Pv*Kt@I+naj6H#a|Umd(CCRd z^_i#uc=sm7&iH>7Sw8J{8c=2b;)2qL}rFr~k&70K=ct*-tW)o3Bsu zRdQ}XUyAAtUb|A!3$QJH+x~(*vmINsCqLxaqV2jeyU|>Lp6}TFO}d)-2QQWTMDE`C)@}aY4-FN}g#e!sS`XeQvYs(5C|88` z&0HGFSNvud)&Nzca^2d7Pu9}fhVNKO-iGhnd?O2NwZ2(3ENz9JtUb}jot@>}JImgT z_+SoZ*JtYQp4!^{{y_c05A(M0^EwA2jvV)&e~vqvJz1L0K2F%9hHpG( z+5g2EU-ognjItuIoM?%QM8llEG6btinXW<)y9UK}u^)`-3Phzhw&Yqo0 z|507K=ON4f1D&T&>e-|7wv9+n-A>*wv&L<#NN4w3_It?J^N>?-FKgrM$&u;!Ch{Ds zx8s{F`wh;uoHhYxzlL+NJUz9QJX?X&4V;H9`+IW!^>Dr2g}z&Tk(K@iVWC@DZ}qm1 zOlR9iCVP&Il(p>h4gWAIeR4!=^RwVB>h2F$COd~g3-l}2%YF;zhOv$8vuxC1_A%t_ ztLzN>jxVzJa)vfPK>CZR!OsrcEjvoO><7vIjg%L?Jf+tja%L@SWpj48{tWFAd%_vc zo}9=n`4$@KX{YZqQtIq*S`%w}+G)|Y-hqKvU7NytEPFaWSH1U;SEttz7W@J0;`k{m zQ`gJy7{9faUAG1t0wZqo{RZDQ z8ajdOqcxfS&MsnS7z^345`M81_8Ok^zmk+)K0aiZjU{aqzwxBs$-eK{lwCF|<(&T| zNS{pF+;AqAApI`pz~q#j{$qz8C#AyJaW-TUa~lNDL+tyGa`t@%FXVUkeeZJc76Yc* z_a!X?tm)v}rIVIXMfQD1DIGD}vLwIn3v8jkcx~9(_a$u6k80ZLp8wrR{oZ|Foo5z# z+b8j{ExD!TN?6qhNLk+^5=iRP-k$&EBp{PeTi)am!UB2Y*4to z(adFmA#vXGKZyh99p?Oxa22>#=YKj4-Pt++BOI48B;8jxVN-W>VnZf-+;jeS+?l8D z`JaTn=YPP=-3Q+1GJbOzzjc=X{BIp~GJcdPZfAJB(mDT=w!T4Lb8bgC3tZs`vJOZ% zX{w!q$Ed6=_+=^YJO9&gNc)=f$>l5Xo1tK+{vThQw>umtOJ)Za;<$<&YG0nVW{jbIm4Fo=7i=`F?gYmw^Od1bf4YfBIvY<-=dT~jX9z0p_|}S%c0?A z#4q8u92#B?pIQc=TB7;XTGH2$_Eb0%TTA*)@ToN^`zH40rO%VP!kKs%eCnwNMel>z z9cCAg&hshqyL{><@GpG^rs7kiMSvASpLF>YWo4Z&H06#5aSE4p4VL(C9mi$drH$i zzp(7=n;yO82FspGx`HEhEC$b#7u^f{AUR9m3^tl(@6qnVcTnk67Cy*zrRi^?8#TOI zm%fZMVAZ~*x@==Fk?jK7D7;sMhAY*ZK9GTdYH9pIQVK9Y}pM>XdY#~Org^EN=F^^w+ep*p};=0+>Ot;~%&j}Fkv z+}h6ENt1RrzwM+qGPlyqt-JNy+DrOw(rP1_*k01-F}HT7?0cbCY2&111b>dkOro}N z$hqbE8c-%mes^xoqo2gZfT`vdX%S$(e_noWU9hhKa1>9U9m&rv`Z38nw;HKGIJe02 z`{Z%wmgEV}E%IDVo`ShWUGCiC+sv)l?8Z#&TsRXw*P!H9S5OBS8_DYcby^3Qg$}@& z^j!(>Jb(;20By{%{5rrKM+bO;vm?QqwaQaJ-=_Y)E71XFf!9@yneq%{c#tt%!x&~5 z!x_LlIEW4~qrOlF&~XXM6x9JXM;skM@&$DO;*<_R+0>fG!F2#&_~bBQ)0fz0aA}7# zQM;i~2avd+4gk)5IsmwKbpX-|bO6$QbrUvqN5?j1vNw2ifExljfP{lO0CO|e#rSnG zep4*J4lo6LjISSD2RJf1uLEpI`E>xz50nnzq^WlLbO6d1=m6yP=>P&pbbujXsQw>W zTA%~WH@*kZ-eB_FXLIr_boUg$XFW3gDfrHd(Bx6#pX2u;G+71TISSu-PV=2pr1z3` zIFgB-BE1H_)0?vYl>L6icQWvu41DKs<9Yaw_9dXbQS!Tdr$+M~U@E>tS_D`lKkDT> z7wAg>Y{hpDdiW0g2-8+~?NLSjLB2ztG30Uij^qjQ9r8>fPXXVdE|>4{?b7SP#te2_ zc^$VGnCNNI+3=W+j-Gax($nM(5#9<}V<~xLbjvtvRRb$_OzCfS?gdN9N?AK+zr%U% z4$nGu2kULw13^B8M>%^Sq8s!?upjTH9J+3fJmQxiXR|#|TXyzo+QXht_K0Qo@V#p- zauWZ9wfdYj`vU1wR5 z7iYjl4qVvaqBM_-c|ly1YFwNF7r8=Qe9()Fm$6@b*^h^|ajnhO0X(Qa%vkLBS9Fg% zuMLIxwEXQk<}>Y-Gob6(6I1j_+q#FbzmL9pA`;nGNxT(2OKHsC*_(|>dFLEN?zyNf zk$rUs=GVS2`ZRPZbPwD~?2Gm`vMXTdu_srC{ryaTIXm*dYmdV~)lFqJ% z@0VJS2v3LiJH9=40<(=Xx;ub-XT9BXlVvAw#3AZ_g$yyqdjnC4ZvAQ}|YM zh4kLXIctQs4=CJ1qpR^{Uk}_{E&H^IBVYD5OWA~B7i&)fW|lbiu`^<4mY{s@2Ie}v zcRXol7T4Q9eW*Tj`Uc9aX6Sl6)r9DCid)Uf`lu1LSK zFZcS!tiU&B#qeZL%W&D(ex%{Emnh$u(Sj4hKi8Maebi&5ow3xse%XhPb%p!Yx9oAJ z!qnA3T@C#Scz#(b+K)|cCYGAtFKer^R(xUD)0MrC0^gX0$R^Sgq!r!Yp2t{{X7;xq ze}#5kfWQ2$jqGpJUW;~xy5{zWQ*--o6Q3v(m-=Y`HXT+rLv8q2RO4SnAO4;?x_-(Y zcpK;Dl7FHT|98Y^uz}7IH)%Zk-(&F=fmY(999oh1_$bjqk&WmMpI_j}Mioyx;$5-+ z>>gxRD#mwHf3}Xkn>BJe55xH5C(;g_zG^LFf&Z5L@w>_yBYs^A`*X8AYvj~I=%a!$ zs~~LzzeWAIE74U`i~7sDuI*2Rkl9_8q*wNf-(#$6aerOHJga6}cliush z&Y)j}V>iKDC=V}j+Q4@e->MCKi;uzSDddYWjup(m7%(ds#|rAK0cH%CC2GzIo#uV= zYl!#y$^a{?Q;&3^f6;7FWztt@fizQgR76Rra1YOSo(o-zC7gcaS8uIeYO z>L+aKk3I_zz=mtSIZvo_+5lZSdas1NYh~$o9k?HB+0n7!V*>vfv#jx#L9dU?m=3mI zUKMrL%F@HKCqU#!IQ>M2aeX|{X(<3)(@R!;8M}E11{pc9O|Dfs2)YLWo(?->2 z=5LyIi2ZA2dzyeZ3eQpgGUF`Q?)Apg_{)p~pVU361b!39Z|q&KH+-FTMJHlwH(uKk zN#9v#WVIiSY6t1a8ln4j#(q=9lTX?p@%7{K{FX7ybZ9>s!R5gElBAMzN!qoav6VKh zq>jbT`Z2pW<@nM}!3Ng&((DK4#0x(#zBCE?rpAW$xc)ShQFx!?@uw+L_B~>^Wc+C~ zT&Z7ZIZOM5mQ8&U|FW!8*3V5oWBh4^M(N8`@SX$yX<+#FHzvX_#`Bx#@FtPlF=)0t z0WX2{a%@&^ZbZBuFQ};UYViuWXa>o4B`}Dp)Mse2v_l~#+q-TpQ5q?{lf4i)mFk% zMwJuVhBl?#Zp{ySXD}ycxO4Je(dERyX4e}3oLr`1@cyOJ=|mP}jbDwxWh`&jVKp~M zPY9hdH+Gr2rcu{4e_i5hvo%l`_J^vy3Ql1DdTnd}4Et4;r&{W<%H!403VcF%o#*;k1M+MxPYGdC&i>TO}&(}F+8@rbMy?rpee zOuFVx+6+Eef2zBPiv|zT7d6HDeEZU3`8#S?>j^aZMhzdT;9K@Z6a%S z?p|EYeZ<2o_0I8Z?9`-9J;br6bAP>SH*l-R6Br^7gzkhO%!Uwsx`?fv=j{D^Ts?UGxND@MwRC|3SM|*Jc|S zvX{Vnt@qdQv(&!KAU4@LujCVaUPxZS>n!qi^XmbxALPGxjUIf*yjRA7eDFShzGArW z><46}oNix~vcTCVaAdzE0X_NZJP#}b=ko8u--GxlR<=7oCNdtz?$K(s#75L<3pkc> zTEl*k@-Z^>15LrV3-^aS`z2;?NbEihY}sR(OgTlj$hyC#t!f`j?~6fq8m7lSvRK=_ z^Z%B!;AI>^@w%9PR$YfG(b`|p{n1$o~M z_>Cf;qMhd=`1pb2-Qec!$fvs9dHM7a`IfnH0rKhn{egLke7cypo_9??&F>s&)V@EB zznk(2JD&UHU8Dlu-R7U$LfeAZMdW=|XdQZ5!2k2jbIJFv$*1U+@3zi=d-5sI7l-C8 z?2Fx>mj|A_#m27)jy}ozLj|}jR7qFA54L+KdHE*__HR#K-pA>B z0j(7oo6&Cu;=uG3#jML zb}iGW=fyxhYpBQ9?nXz>h<;^-*jH=RZ_aq@8DcIT4&w1QsJlKG=*!!ki)w6H!+CYr zyAB-i;YHJ?%#UJpc_DgwY!G@M45rb$ z-%Z_J-r!LBKf1fDnLqhawFhGt=*rkO1X!42SdK4eNyflgoUO>-x0bTOZX+kQ5GQg%>JT}B{g|A6IllG4DhH12Pl@f$x!XPO47JG5c#V5 zLA`<}HQw;R;Cj-VSL6@;(f+NiB_k2&tsKAABKO6x-?_JO;vvC_>>G2hO8>65Pxk*s zkGu!OohT8xzlAsKxp$+Jc(JvRJ^7ACo#u_>K9nQed!lp)?zJ%YjC@n?-|yqz2%+&# z(t`INnKDuK*gJsnD)e)NJ5wZH?&a9m$eTXUwYraFp65Oi>W|8OB*ZCNoX0srwL^;? zZ7chwti@eR%Uh&B+`$sbw`;ZDCw^1(E#TDB=blEnci@xkfoQsDq`y|QyrcV4r|p!F za>r6<_a_7=>kN!O4MX*hJR$Pj|G=9&Zq&YRKOvpFYx<*y1%K9tKh|~ksCe`^aDQYa zX9wmk70KI_5`PypuhhN_dFBGs!Id*!*(zr*FWSUj`vm!R`W&Ut7U#Va=r{Ms*r#Ql zSIPK(vOmTcntPP`BIWz0hAibH@}S)9^mpUaFWunm%d2^!_>v#yaDgfC;6MM&{4ss( z^z`LR^o6;o+g`jc7YF;I_I~J>^hNDa`s>YpihAKM$~PDJl8dmX9x2<$*@>;%KH}2! zKHYX1!)LKol=}(f`%7k?!>eRGx$9fKr)tJgY}2zh0KI1-$Q?++?OMDOF#6zHtVD=hkkgA8yG?- zxf`}{7jo<_X`{r2BCk*Xk$0y)%g{=EZa8qNE2@ap(-+Ph57kz(tL$rZ)hD;Y!N z39JgGUoAo_&^LCG#$1aeqhF(^cd-JcwKyMC@E_@dWWyOCSTb^W`wg@ic$xsGco+LEp!czEn zz2z!+UEzHs%s-`nA>X85QO-XF7jh0Nb3Og>=nqD(arF^!AiB-V#mW`wpTWma_gkEBVR`gVPa6zwMaStt<^}Z@ z@A;luyGR>_{uqleW13%=diDd`WbZoGd9E?PcRe2(?zr{xt7M--c)Rz$jKwdoMpL~1 zQ%VlXIr=A#VQ(ff20kBx<~lxnp8GP^Sx1op&o}(xrRmjkTbs8af4uYNI-yTw$1d>5 zU2pv%Y-4MwcNh9j$E}}|_bimGqRhR~4cyHD&C$0p*>eNWN4vP+fw1C3GRJE~&VI5# zJB9z0jq5Xb;YG$~bSmu^o6#t586sb=S98si{$8El5xM-3*oi54%r!5J@dgLrTyXFV zZyU%PjjA2=#dr6|c<24D|NJj!ohtM1wO@c&^aFFx$B9TN{T}9+(2eki-XqF)B)Q9j zyPA2e%`*eIQ*C$oL{sNLo8Gtg(j;pjdB;-D{A7%ywcH0GJQ2PmIA}2Zjc{l8rrRt}7KD1h&5q=a~z%!RYb@^S8~v z_wSt(f>)Un_3ZaLZ%gaBnJiH@-Z`m_;VPIQ;ol3XHjg8~G8o8|dwhNwOeeSaK?h@T8ne zPmkWx+=v~@>Mh}PPb#eJLbCKfN4crAsj2$eOZNkFLG`yTm91^tJt3#Bl5M6eApZ&@hO`c?+Pa`xSt;SQs?~WV<)Iv$rfa?(&wBul)LjX*v~`x zem*!R-_Nh=elos77pkB0tDm`aKRTlHleVsdKZ^c?jZ;IiPyRdiy{)VF;?V>Dgn|DL z;q>2l;7eJj|5MAP|2}!-9ZO`qD>pgM6qzDC{Ta@`$3Y)5CZhXW@Wmgl(6U6v_AjFo zl&(tK@txbSN9!@_E<5O4^ca~RLi0jX$i<9r57~ofk)3Ak-$fn5qoVA4K529#;eFWY zN|?Plr4xxQ#IEkDLvqiY@Hl8)g(HOJjzg()SGU|}=$ZG8&OXE>+U4q>ZGJu^{gw4z zJMFkS6tFP};O(90M&Ft3=tj-g=5?dL`QlsGjo$9vUx&G4z~QYP{1oY*%p1`ahtiGy z$%W;S2jJD{M3&&Y%{e3R`2cm}1Jv#K{zOZy=c6SK|LbVGyuYX2vU?wZf3`DMZnC(S z#(956?k5sjRDK`Ft;~DBr{(lI-r1DzhR!8>Vj857!4PH1+ z>GLyp>v`2{-Um7|EUomP|GF%_=aa3?_0WOQf3lS&$rgDV=O*FN_yy4p^#%#_GMaqI zFm-3d7}}xgjPMp`8~wPGHcK4kdhVhx-Ms18!hdw4#L>!h?snRH2VvTrTS{Kw4Sa%j zOa6yhA4*--)U|>%=4L->XO`lF^e{e1D=34Vq1adU-Gz-%2p^>N_#i#ToZ`OozWu;` zh~H>zKIerpBats>*5iZp82KO4K1lpu0PaUNS$4(U;)8^3a4q(UNeg>j%I@Kwu$h)! zHQlo14GRDJJf*zPQ_8*Yr4HV-57N(Rql>p0(d54wAEYM74l*_w*z!%kV%5}D&3bJz zVb+IbOGw*^ZR8UAHjlKO@XC-ixDOKP*o9w^57OWM(9tK)_hx7FhqMn8?F!Yh2cN9B zKb~{!zAcGM)!R4gu%g8_Y>{i>lk{OTb?iFs@j*&D@wXBGcYWFiX*NDcGqICpZp5cM zJTk`^#;4O4h2z+|Z+d-@s58D2I$1qD9bb;VvXU{cV?2_K2kT#XXGVCQz%afBi32iL zo_jh-drLk@w=fQC`Q5@e%<}jktz~a|Gvl&}w2k~WlYS*Mv#DPB;LF;!{BF{>kygQ7 zX?K%82io0MZ+~^U_CboFuf*`xu3#Pxc~@7Na|aG>kCNZDC!gccd<>Y?)E6c#0;~qc z&854RvO*su;sj6GmIe7ca0Kr%4!oVF-UKBqcdLDfwpv5^Ajy6Nd3wy7pjXmHuRXbj zb3J*GUF!T-#%I2+ORe<@S5dEO6W_5Cd=Q?qGV%tWjBA&cfo{1|mUB-Bd2_S$JsnfP zHDjXukG4Y-+riBY{*R|UX1`UaH*c=MusH*j|{hO-&N z-IT2X=1yRisQISG?HRK_Q$xJh{|LBQ9haa?f_040;w~f8Nv~QIa_;Gnd@=Itw)T;h zBQ8!{J!Mm~Q~7&3NQ;6$&MllbL4hIbOBX+cO<%aTDHD4ZT;c~LxV+Km*#bl2g1$%K zyu<5z1g>RGseC<1dnV|6M7pnT!lrKVD`$RQxbKnlxsLJgwCrdnxR}6y#w&ZFzDLJB zzDLW!oyMh?AAo~V+?y?Fs-1$zs9wKhDet?dLvTc1(!VBsa^b*lhJvB`e>~uOl%ULP zr`}$Cjs{wW8+oC8R>k+|kDyC;-XbrqHoiyjJ=R2-sWY*opRRq6;IVRlM1nNoH9_B_ z)PH(>kE-FZf&9kzXtv?!6QL3MmG$}_&1Mf320W0}Y2X9jSQo8UKnWy}m~? z(Z9#)doL(IFk^U9wId0vm}RT)mE@`L&`bq;nT$zp3Tpr}uP7_;lSD}q8a6&iQTnLp zQux1l(}!{j|5NCT@n;yM{C{T$c1+TKNU9$izO+YpVV3q{r{?%qc+$Slnln4&qsb2A zk0kIJ2mBT7a`O3nksgJ29N_n;#~0}U`3}QZGQ=O`cNn@aM|Na@bI=*j^5;l@mbAO! zJI|3`iR^f`-X8Y{T6Szhc5Fj-+qjsa824$>mPdh80X>=;o* zc8o|W{I*hk#_1?IEY7ilSUt?0Q{>cJNYolJBp z;eDcKJ!E{5H19|dUp8C6|1&)=gOrS<9?|V$|MANmwZ-64M}jhO%}-Um(l&J11pG?k zdtcGMNUsF?h%Zti&_{*08S|6gxf=^%yS)UM{Fi+s<&QKkm6>!>%W>j+*W;7K8%ICh zk53Y5C(zfI@m`sXH8@cFQ`wW+CrRj@GU~1u{wIJrmGt(^>egQ2%p9e3EE`>f_0|?mbSuNAOEJf?txe?s}wwbywTU z*5(tOKf3auQkScoo1{(3S1IbbD*}2teWTVZmezWFmAV7IN`XBGV{;(;g`eP_Tub?u zc-F(7HLT!r&@&Us2ahu6Jd)P}?`F+AP-I>Gw(palG{d=1-uj?(pM1{;fA{Z`|Lg?k zZuaXgbM9vU;KX#P=Wh1JzrnlN-wvMD9r*XwI&J>!)lQqQt4sfCjAJV!_x4{i_IK|- z`47)@_LTO{&+jSOTYr0dN`HCrySJyb(S>#XJtf{g;hapr<0R)N>>m|7AKQcNbntxa ze|%r>4~>SmqD%J7I?wsoP3nB?k%ns~rE89~HXr(Uo=?dcK#i;y&@Vcf^EvpZoRP_% zjl3f?`R97C3Vw45-*RTw(=B(%TXqP3R=sOjT5SDReI$Ip*u1GTb zNXJ=UDj3`=KbyRg&$(B=B0Xt0dh%YKF89hmZrKxb9%Z}on9kc)k)GN~UUbcDBX_+& zVc9RUf8F!AQ*STwFnh8x9lx7AuOXMy+;@)8uG1#k`-Fyb(sMt3H*k(v_T}W0``vbP zzpLCUKiv5G%DG>ACHKl#BD*SO@9U9k<9s zr5B-5xp!x==U#cfg+_WFrtgbW>R$Qn@DDZKw5@Ak;Cc66`F6|R@niP0+Q~~lWFM!K zu;4E$XG;~KOdb0?o&)tsGxwkDr+GKvyN#DVGBaz}h z1bw$-E$Kx~B- zyv2a2)*GZnfVBgByE+bKWxeIo*@#p6QcH7wy#Z{=6JHZ{_NoZW9r$QU^0?~_$>Uvb=sca|an~Ef&DV9Q^#+xtgiYPixedIV>Dj9qaONrWbiK+W zVedUTz?6FpV#`D95iz%KxBPomw^JwMN0~wHmA}Zj9|1V*>B>6E*<&J{1+MS|S+6CW zG}TVQW7Mo=j$h>8tI}{t_rrnT3S|mGA&b{&r^Y_XFSMhA&(X;Cn&n~!E z9)2f#&v9Z>L;2>FY>ew|T?^iBS1nWvigmmHbwD?x0->pSlGaUQ7HMez!ow zx5B5^!l%|~KDC+jO{AR(XJVU4zYRXMDPNfB%eFmoDQ=~-7OzYPpYuEPfn+c?s607 za==rtq@EUVt?rhOrl*c2?|2K^=RU;Mmi>?9Q#z5lTRxh8kUHdU`89GcJndAv&uU#B z{jIMY8Cyd68t#2xXW7?~Px>SGBg#GZIdq@gFDyIy8fD(J>{S9s+OST;;C}nu0Ocbg z?w1F~ddrr3?0eQLz2_0pdxjAfKBDZM-o%dU&2ppn+$(xd&ED4LHA&Ta6E6|}|Z0wvB}!3uXP7;80;8Vhv+(wg)fJFhPAW#-6seqUyeEcWOE z+nHmX%%Q!c?dI1>`cmfDUgp?tJ;ySnA0%x}#JQXN2Iknol-=K~=h&(U_aHTL50Yx* zpmWT{`9jOD3oLYWfjQ8Y;LY0Rsh@9Cf8RWGfkyDUtua&n9Ao$_ zV|X`X_#9(g2h3+vc2QlRj=p=(t*AqtpNcL(nWDPDUVXp3l#P+!s|ygPbOFky?)Ka- z4_uL9?zt5(eDavE=}T-cxU2@3)ebIwx`4z5bpdeh(*?k_I=7NKNh{C=NcYuE*wh`Z zZOmkE^XLM%1#|%k2Xz7FCU0WNTUU1WO3SYcTnRpg(glu;$?F1J1G<3b2TB)k(o{Qr zx&Y;U=T_2Z^7?cEfg`%W5HM8#k6d4%3(Pn7%L8{Xx$ZmjI0oIl#P66#w!Z}5$w8B+ zi0|c>gC=LdcTT}~dNtp%Nq>X1QxV=4Abl2m=Z%#8L-t*TH%{t>@ASfVPBH#N$o3B2 zc^->=lerQlzsq-KX}$wY#dk=H0PD{_;N?3Pc)vWb72i4L;XCx>Gqly^J2R+1$al!| zm*jEzj^qjQ9rApEJOzA*x?H})w@a_b8uRzdOS|3x<`RCh;W68=Ye8oC?w8+WDS2dc zOgZy6uwuwZ)(Up+b@-8dGq-bR_4g>gPg_ccM#qB7SMWP~+9|7K*VC-WWsih)c*A(D zH={fBbaU_g%alVG&XGs%o&O(l@BDGg?m1p>PeIoA{DAKt)Z4!=-!C}d152Hca3yx!xe3As<)pRuG=W>ho`vr;7j{U0_`71J(S5#(CueW z?VqHcak`!fp7sy3u9UMWY5xK8|741-KXsE=GZi3UE=H$Hh%ST$E~Dj0G2?3UP6r7Z(e$Nm%H|L(M<7 zHm3r3P<@zjUDA@Xo$mLf#qa!A>%Z9%^v5y&C_RkFKb>Mu(@ycZ{g$~qp0>5&|8DNz z|03~L@a(BEf3H(EBIO-l9Px`j5#Oz=aoy^VzI-T})#@g}k; zl2T^@o1wFw*9pU$zaZbp#UA+QeTx2|J!D-L`IsHx|I?Pe_&RtbaXrW^;i2+Qi zd*``v;Y^No^uXwFW+d@v7B^&mTEn`eGG#9WFY~~^``9LQx4EocQs@S? z7Pe~R)3KywSIxG>J`Noqw4u}3H@sZN+aA2dcDyXDc&xUMol3u49(%Ujv5%!Mu_aEs zV$*>w-*R4%psoaI(+ShwvgM>5z&>_4eSdrxq&zsZSznE2CgQ;sc?*l!(K3!FaEnl5yoVI$+Pf!{{P;UUjH z!-jghd@JM9O4??ATS?y!&9v6rWt$lT;FoVFJx$s~&V06${xGsEU2p&A$I$m_$E5Mt zIE_cAoQTXELf_9;jdb?%C=(^WtM5PT%#9c@mA+3}1XzE;xVdyk*@C@1;*^}L`dEH1 z57MNz0dFfxMocH+QIiuOWClh^QiH(N3Y#w z-&xKasu#nzC~KuW_494&?`vnD;Q`u_LO1IK?p|Qd6`L9A+X3voz$|v=u!DH-J_B`R zbzFin1^W!7SFP0cv63%FezVU&T8=oi&p_GKT#tP$X;JX!?lS;G>2Aa;yb?BjiLC^e zFM-RK99+8l3<5*qy!#9i2hKapnFHY}aIN+kblNlK%z?0?7t(!o6E=18o@^#NC6u?1 zouYKZ4bYQw<{)A3J_9gw%uP90=8XV5dk_B^udK0;y@xtwJdp#kmn!v08yH{5{;7S0 zv(F%HT}57VRzTSB1GUfKq^Wia9=+v#`wSWm>CTyhfg}42L%>k|Z@)HwH$Ua#Ql?h5 zDbrhpyr}ZaiyG`>|Ndisd7>xWux9}ACF_OYZ1uTl1~cUiWvd)@Q` z_OW+?Ps&dcAA~@DlkXP8&!vc+?H<`dKaOAPksWt1PC?m0p4Z6Z$_~jBlpW+bN1g)NL0zuw;9Iqc{zSJs zJf?pxX3?8efF_ZKl1~+yTXOb zytvue$C4f=Jt6dpPO{7BkNc@>zrQZAkNrxZF4sO*-~{Hg*FN^HV~&0mUnKQlAB#>V zI+gG~(X*6&EHGl4cPRVVTG5HDjPMlZo#J;&MpBRHb}4KA6p$t$9hTY1rNu>&c@nM z7Gup&5zfS7z`c#MiiW{`(r&ld<7pUN=e`XbFxQRF{o224o%w>p)+5Uj*klQ z&Hnv*+KxODdY8B8&A4UP(`IBzVq$}$PuETdTInOLNzyLFPG>TBtmZcvJg)ZW%+>6X z&t?yNCTY|8%_jXO#%LycG3pGlj-+)-d zdN!AB*YB!RCQ5#n@2%5(515MYkrn}#;N8`kDObzFinMRn%G+D=FE zG4~C>>XW_^r*vk@ruKU5bVw6j&()cMVdTMl;^Tx(Ut)*BWip(JCL0tkZ!~r~0z=}0 zIx{%;>CE8T)tN~v(3wg1)lJyc9bE>$YxkVZwLA0F)tMz6)R~!^u~m%UD#mZ2<=2@P zf)B=TP@TEz;=Im0%5yeHUkyJHxshY#>3;ITbd7E6WG(A2ado~_&Ipdvke7%`hVY5#Lr?+EO`w7 zIivH#H49sjN@tI&qM|-CBIN9CE!6)PRItaDMm|oAWJYWYv4=rBTZP~9OKZ8f zk?)Pn+d0q@aU#P~$gkWSr=77chv0LOjIzC`gNICS99&K|0)uqseeu1iI%tzLBPXYP zOUudi9y!Uk;Jc?$(UOvrCx1`NN!l6O%DdOCDf^X|w49W9dl75u5oe|ap zq|bn!jjnTYgj(w8|q{xW#psroj!T&#MJXFcFKJD#D(7MRX@fU{#@y#k(Hxk%Xp zxk#KdcmJTsdO)8Y(>{xSyxioGi_^eoP%e_^40&9+D0zZ%kvuke3gqH;eRfP;ReZbi zb9-YZwlb25t^_aWJ6%D!xKZ1zP%bw`%f$)MG-J|NWr^O%o(S`|#`4R>8u|oZ{hI|^ zE_Qk9=iAiZSA|@h0DtIe%((UePcepKA21G>r&2=yg>rEmeGl#>>9_=Cips@f+Ga)a z!4tAthAX*9oRW)_O+DqYS)t#;&t16)44-TwZ2A&A1}>L_%jFI(eR5Iaf^rd@`{W|H zcI6^z1#*#eU)_XF-O-JW>?L{RBL1&3o~~S!F!kS9VqHHCULkW@eCK1Yg*eY={3^jU z^7*{%?$h(E9)~Ba0VJD`p=jn;^$P#{llR_-?D+;lt0dF?n9C` z$s0AC-}~NL`_i58(NZ~2UD>})z9XEqk?$Jv^+uq5=^Oqn=B+galeZ2w{U`oQrO-HM z%_@$!Y+8uxdDq^una91M`c6E~PNj`OKjyvl0vc-b+bqa{~_ z^tUIU@_f-FpNjAn)}-&~t+h{dze73LRVWAFN1NU)Ip}?B?Md3|m4oQFg|ed zck+tl5x)9vzqR)GH}h|;-Nkp5wZw(IwRT$k%aQ3~-zxXAJV03=4F%p>Q+)JYerqiW z&XlaF#0F66_vnP@!GDdV*} zemC@a?tL!$2BB|%z=Qwa#+z)vnEL_G>Y^RKG9wJZvj5zi|2Yr)mfHu69H`#Pui&9Adh_anKS>qd1b#V`rCXDtvkOT=WU0y_klBJ?eFQg zr@gYrIG;VnEN?al-&Oma_;e^=8qYj7elH?J-_9E}8!vb6#JcJu&f1T~^GpLnW5oMBh4Zop_ZxQ{rrF z*GcQBynPqK4mb8R{xmhvFlS|)W4Y(J2fNu{m;D>gze1cNM5;NjB_A|^+*Riz?!D~0 zU$KrJx%INEcI~&0vX_2u!$s56jmKJ>f7qBmR}h?iQTFmVOWV~b@6t?A@6x>SuhcJb zZ4-ElPvS4_4{>MvSvUUD{$1S?KfXUyjsFPoyV}O{j?K!eZVs6@*H-Y(-tvCgqwmst z^zes!qpj1@S_}F*0tQ)SE+(^1}a!8Dr*vjPdECj5&E_ zj8)tD=DiTRuQ8PFgJ;W`_M`;&`jhu%IcL!Odq;aU4b4Eem;o&4=tNs6{q3K6-ruR? zt(Ce^(n}*XJ*~}40yHA^cD(*6{Z7|)`0g$49B3R?$aBz-f^YCdE3At}_mi_3!BvC7 z72(0&;kiukL;s<5r5BlZcsjs^oC5`6NqSW7$p*(csV5Yh`i|e_@$#CY{c^_tt@drg zAbr~q=o`MTN{=>ulYYf-xop-u?pHCs2d<5*Ea16q{(WcYOPwtV{}bLT{O>7bf5Cor zk$McT7TF~-TI$5#`8V?3(0hL}Ap4ifrbzg7RG&Hi-}v58g1!juynS%yqWv!s$IJ#TTgEYe-su}Pfi}F8_g=I9}7uFmTr z7jJm$ddS;-@8z0eKE_4*XJ~sUJ*3u!+?D7zMS`79G_Es|NTCv zv+y~c5khWakMWAqFVfaC@cvgA+bJP@RibIRe<53iALo=5@^4FX@9|J(6nT`aIE@W} zd>>C`#7{Ll!?8{K3ifeI*LdBLLs|5}o_XO+c3y+nHMn|4?{WM;xdXqaC6@lQ_`+Yo zJ-feZZGJM9*E6!%{GS-knL72qgl^L_j<$?T*&|ImN7GKqCQ>!&N%&Itb(g05j>Bi} z*ixH_A@3seuasXoze@7bM&6!NcP6w^kLv3^A-QKWo&6T&sAn_rJ?;3r@U7xsAf7sJ zllX^;=UePI<&KFSY!o&S|5`WxviIOG`z`!s+wqru0e{(t@!xovHXMgnokZ@EcLC)_ zCGeMBge{{&A)?hca3OFl~^?NQ&$ChJ1w+x-(n8-PgzwC+;>46m^ z7>5zgIB0*_Pth;*F2~+teMR11c7xNd*dk!dH+&)1L|skw*ew$lf7wl>oxxvr6a9aJ zv@_@NmnD5ro5Uy3gXo{JNep*6dQ^7((EhUj%={O;TeK^*23lQJZ-4VU@B$OJw%-1p z4!i!ccjFgJA97Fra>s~&_4vzfbK*}DKkTUXm)(lLY^&p&6yNOVSjwhxGksAw4*1K` zj`&vQ$)56byw&0xx_FH7Ft-2a@-U2lT;iP4N!Iyn{~vR09M6A8=XS;+&2Kw>ddOqr zn6BpzF2-dyX*>DtC4E0Mv%B6d+sPQB6P6z&{ZZ0Z;`4Nn^oOC(N9*m2>$Q#Ja(tea zV-vjcJU&m{*E&{o7x2#Ag?Zcmhn;yLZxvKiUzoHAu>Ke0=F%Ny3v3*TQ~GTC;zAq8 zWged=`te|$$Hs9#^#^Sn$@4Yx^qBW#Bu~)Bkvvb5=SlOP4E>l7FN{+c`*W&aReY;9 zkrrEqkLN^q%0%!|%*Jtc$aznOygq+f#-y(ud>@7;4uhLL{AZ3MyB#~UJW6 z)jX9kB;8jxVN-W>Ha?4Q$6xj+I6lhw-NS#zD{E{V?_vJScp?Mh@O-JqtDA{mIrpGD z^Q4u$dfcV0h97`~Q3)qawKGZ|jBY383vB<%Yv{*?BewrTz)=0i7d;- zsy1bM+so4f?c7D^kry@i%YL`cFE3nwS@@ppF-%>KZ9cql{-$Y%@P%{yWl0lW6ZDro z@Gl;J*$wd6Kz`#dyW8;dTdYiUTfkp-YrtQY^uz{-pN2FYDLNou;ua^~=P%pJy2-pJ z0}ck(mnT&_lHg&cWvlO%21i4*SLe{YArinLUz1_>^R1} z9_p@z9i#HHgZ!@FSQ~Q!e9N6-N_LPI0an!nkL;jqf$Sho(f5ueg|g#CkL;iyqiL&U z_HyoE{DQKBJd?@e$_~jBlpW-mNuC1PL0zuw;M?UnFAgFz&@&95lCed9P-Wb5(5j66 zZcW#{Gnk_@0&|r2WO7&g=V*byEb}Al^_OK{-0bz2B|RbZ>h+hMMqShVb&0?1w*z(g z{AC04+3PQRI8qvPWfG#1RPVkGJkU0ycfSuDsyppp z@%RGqEq(U-%=V1edN=I~jl~yeRLcJGziYi);>M@!|JLEEa}Mn*Je`9d)HW#E^7+hC z204vBG%6jR8R9$T_nBQ8R&5X%#z!u((t+dCo7cYuy?HKpO!1ow9#?zx<`lj`%fR^( z!85;Qq~8SZTap6T+Bawo>8nUP%s8weeI2}SRm#4mR`b40I1|r+_rt1bAXJJ^sBKjY|T@B%G&1$~3I58^Y+nDni%xW7AOM{j{P zS}ecb+yV`cuea~4)p~QUr+&Uo{e3I6&uni)rhF4)xREhD#Tag443`3PBkTSW_yRwX zS=UvFLrA7=ap)tm7JclG9( z%I8L{m%RJ{9E?ghX{w!3@P%w~_BJSApf{73bUz%?n}>j*`j0=lPj9y2X))~w)IJKm zc~r7zV3h2$xIVMPpi6h&p1nBlGYdbIcE{n7uFq^p+U3YX7w!Y_MUhVr_+g9B?3s`F zVXHQtZT9=jB8!yIEdPzqEHWumjz4NyMTGkoBIwqP%RKnl_ zC4EpiSqE*>J|ibT@eM5}*L&n7--7#|MkS+^&+H}d(Q=Y@hV~*Scc<)2zoq4*#C4|Z z_v>)g|Em|X}Q~5`K``k&u_C+Ham-U3hlfTpV=3I zdz9ac;BAUWE*?cLo?;w&Njt{x6zS7sO^{+uz?e{P`5UCaCg~B@1fKOf z2_mcs=-V;Xx54FN`}n+EB)=;cXK1+yOlM61EduLO@a)bn$`-5%h;!!d@;xsV+_$Na6a{Bp6zk&9h(v|QxATep6`P5rLVZ0MRyd5rsDOTy@^+zA_N zaC~M<8if7}<>EN{9^6mTaS6&4m5URHIqwroz8K?K%x9Lesgi5*?-PR~;peW;EHHes ziLmKQY~nTe$%D%;JGk`8MTrZ_MR4wui{RRoi=-9EMbdqB6E<~64>rC%pV?7i&LJ8& zzi`GcYxa{W&m$M{1$TXByHbTdvwOxVxe?zK$=s-YW`EY>%*CkjnWbEuHIVedCo_S4 z5ph1BS@MDpXRlJmgm6)xS&xspPgYhl_jhVpS$9c#pze}nPx~c~tkgcUNoY0do=J?$ z`^>@!xf*|ngCoiX6tY8`^+MbL{9dtN4J9B%f~Yp zrZW!`+>Jb*@hQ*C$4OV@<)hDMb~<+>C!D*HMP_?_W}}Z5my!4ss6D|L^-rSyUg{51 z|979z^OpEfEjB$9>odb*^>zt;KEZjz!`+aGPoa>vj z{1URHhsRt99r z0-E#C=wSARHw-IMu1Nn3%?@?0f1L~K{O9_d@B8ka&dRt%IERKF#rE$;Xwqu~?zaON ziOt=xquIMGJNr8CBizH;^%KmQ#|b}yoV}0m>XLN!VF%VCVD;=E?eV-``wtoTjo66o z0O#_oZ8Sd%3+tc=sa>SA00VdgPYoe@l9J$}dWiKZ(HC zfFDiD9&l*GF0*&Jg7Pc;<+~~W^+5UWOZod~A7}U9JwkgQq7M&oXNa_Y4{fJiocU*Z z_HchTWwYEt2`^l?$J8@0EIlwV%-_z+EzP?E^?XCulRG&qEqiJMb3&PcE4japw&!kz z=TrY@Df81?kqxvbcN_S;hrNVI*}iqyK8{FP{T4Fx^vjmL|J=YM>yB2YPyfKO`(Ci@ z+;=SYndT{eJ#Ex~yk4zYa?HIR+SvO8 zYyw}v*5PSvr6l|^H1W*9j)6P%ejfeL-pSe*IuU;Hd2_c9@zTdwSGYeH8J>=%!u_$X zhJM*2tEzVD%dVqss+{L;AIkL+-$cCZbIM+C6YZDvY9d+WZlA7U{jn6ku50>pEuM8s z>YD!YuHpSG z2vyLHHd|B8pZ<0m37W5Zg zr!1!L-gOFavpOz8nSynS)Z1k_>lDd{&XqOm6w-3U#fht@Y^t+9zfK`73jW-63NX}K zfp~>i!lo~=E^t{3E^8fJy6Y5yA#vVyio}8Q4s-5JxC&gWb&5_yFL%zp2`hRb-B&kZ zQ+E_TlHK9C+h>Q<2G+gTt2`2>{u|BRKETW|H)E+0{n6C5$__fpcxBBxWgc}B9(4ci zc&W2aQEhGLkLvefWUie6Ztv<+XPq+9l6A@>a<|XF9CPNPyG}_p^v6R^9|Xtnc}M33 zwr`!H>i{3lIz@+zu2U$h`g?p{k~S%O&}>^Ollu<+p|0KmSP`r)ZI&7e(J>pNMILt>LI zvhUmEJu`=SAaaPlW$%J-5`QiFK_B^)oZxJ00d1+MfUlvmjVR&$L*&wzkV_*%@XD^r z{;9T=>3d;VdTQ6m{;~?nA)lspRrF8oTGXGg9UfdZmN`3_`8AfhWDjlf5b~(e68{g_Q#2i;@SdFGMFm0izNnvAf~7%PcuR_RB6)?iMY(24 z+N0$`w#JcN*$*MRD2o+gzJ9(<{q7!HhA~{j7_MRr4>N{qsBauFR{@hXe}bRr9M71u zr*Xu4Wfyg@PE&CS$`r^h(yLz7vP<%LWta4gI3>F%n>y@~U8D(Lb!8VYl>8uG;gzuI z3-_Z#d*E`3gG*O-2@Hwz$}Wim=N(3N5v~H)N_Ocq=*5v;gcZGz?yH-ysXKZLvTKS* zc1>~G;L0uuQ$PNQ*S}BGoVu6p7K^h(a97EH#xHARS0#1Icn)H-CGUo+vnOfmMDm(5 zBf{=}yPQ2aX{w!qN9aSzCn@hcd(v3_%T*I(uCr`7jH$NFhg zrnina4(fR0puNnIRX02LwXT6KqgqyV%)0n0bziHLg(r%HqL6kYJM~?w`Bd%J13Pnab+rVIXvI2H}_xh%N>?^FW_2K)zdcQNw!Nqs{Ys$9KTbj!~xX7~hRr|7xwX7l4o+3EN zfrIjm%>7f$`(7&(-AMaOE%(f=d`4hTv6OURgipbPd*Q*1gN%iDPx1Br4la7X#aj1U zZoBT4HF?dLEzPH9=f_{#rRLEu<|ZxZbD(?Vp!;{qN3^l(ki46OkvZQY+}V5REGyrc#$O&0Z=g=3e2-|g*coI8mw}0S7fd>XZ`$DZ9QN5q_$ZH9 z0nXz16IFgB{T)l$M4`V)e$Er=8~HhGo|BD}3w=>X1Nhgx3V&(f6}<`HOEz(~f-$7& zV_VewvU@&`@bH6*Q*_)cW4}q zlsm|Mh=$(zubgK3E!-F2wg?W;RqkZ&pHglLt&^b7E$pLHUy~>gUoFI003UAN4+6LP zH?&B-U)=@|4Ex06{#*-B-p!X~@^qBH%TMhox1{j!mD7b+gM-FL?e8}Fc<|y6Htu@! zXWuINGW?J-qVM-DpgeO^aF<^(SXn#fd>C`c9p|+%yMJDF_kHqNpT{z<-=a@57d#ga zs0_UG=_qivI}ylZ5am25_u|Pv-#rQbLd@acZCmgSb0$^%MtsIA^`7)zZ+wm0m%i=1 zWGT-djh5~i&GU!GmnRp!6kU-z4^dxr(W4~aeH!C`HDgZEzG&b>&_Iu#jiL;CSNBwS z6*v-KResLYmf1C_E$eHl-Myn~Z()7sw$b)J4F1d3DC3!A(|qdnRl?8tt^!sktA>QR zx;$9|%z~rt46jo#yagEgDru8vWnNi%J8-Dql-sKr>i3xXJE0=^+q3_+V;^m5uJozq zV{oOhjmnQL*2Y}hJhH9eOl#{W7qO3l{uxuYjIrkhhMKq{wMIg+pbqbPqg#3;Cw>6nwN*&*>C1P_T!4Ai+cYasy8S;its?kt0w^806slL`FD>Vy1dhSM5CHp=_CW%j}FXB zZ0Lz~@I&TD{POZwJ+p(kFm!vC=)~q%5Rd*2W#azWH^Y~VUr*1!!E-O>B~||d>N}cj z+eA)?=Gir^8%=z3@6xwLlJVpI%w>pJ9rIi<{pMR}41!xfA@2gA33fxFg&Ff`xL(s)h?hVy~pPiL`i zsju~)vh6Ewpgwk4zjTT|q=O)bw720Ar;nJk<=n*mD#1j@rAau;0WxS{k2vX(5j&q~}1c=K%dES4htcbgxS6kr~P@F)Kq~ z0N^WahcOt|t0v?H6f51F- zHd{RwTZry7=T`_fgm*~RB6t9RA2uv2)450h{5s{NF_YLs*B z^)EwS)0dgE!?SAI1dE-s&+&T?pL=NM;z-4^CE z=J8DCaUt_~2J^Upc|3gr^EqXZ`P}xBOm^*x4?7rp60EHRye9x-g8Gky>Q@f}<4VC8^vOrMM%I37bZB@+q*uiAbnf<4q1R>0 zkO8vU+l>tH?K1Io<~T2(3w4C;OFvMNtZHg$e02!-^6j===N-_TrB>y13R6B#`T9_K zH&^0MhPN*PmL>4^I;%roSe6w1zLa|YeB|fzXgtcgJ%M!_O)4i<8+oc)$=%ew7~URj z%6z;_aSPx`Oz)^4@ALJ?&a^pHdDc44f7ZPi9|7g@Ez57QCx#y;y}--<{u9KX;5X?7 z!VPj$vLil|HBOt+nH`d!=|$2()^?x=ZSJysdDmg@Kx=$$#{=|zIsJ7zyTy#r`i9|W zSAi?(3@OTfTkqagHX}v*!b$%k`b@0N=-nRVvzeR!dvayJl`H#W=m*CjSN4bWg#8a8 zSIz*}k}L3O-~SGd4Sm7$MFZw{;;IfuYi%pYRn|Mbrgd3Fa%cO}niG@JbuEoM&T_Q& zYVuh{eH$;Z_D8hV2GPON_&bW~VeIQURy}NlI@o@zgBcu;KnEL$TXe7=FZ69?<)Z0E z|Esq4hVc!+KYGxCq_;iv5qLiDg=^N0(L2n#F4Wn!FYOqg+`X`+@s&AT2X(f>J(R{D zi@qXX>3qIvZ_{V2p6`5(((}{2cY1y|I)2V)n;5>mdyb{Oxb?{*f7K^&b$ZDCyuWT> z9><~Wz0u?ZJc*ouQ@M+#)XxdHNeFPCSq_szbV_UK9Qp(*f#EBL-V6RU-8 zq9^lvDmwg?=I^X9GUm@N7xX{fq(GBgDK{tJ0 zgl=Y9{dzTcL$^I0UaS2=d&ni&u3UlS4s4BHmFZp~{d`SkS9DFL7da$8uDcprNBQ-) z(5`#t*=OA=>a#yUPDu8!2ePx81nfijIo_F1}YiRp+{B^)%e(%iFdE0-9r<`2V`Yp>->Zc^TUf$C9Zu&Fuf&*`I z2nX{W4rYRb8Q=gp7G0a^K36zs0tb8?4zADR;H3@+Jj>zWT<%G8IM^7#0nbfdLnE({ zb;!3@I2<6~A`S=0oj=l-!GY>K98h1d9OYd%&&{|uf&=>$V&tqd$mwDMaW1*+9Jg<@s$#d)w_=7n| zCcA2Yowbtn>g+7q>8paDP>(g>+qq-mEzpj!vnZQzb{6H*lxMF@XHi>=vIYl~>!;kI zl|C*up^x8#PoshMD_Cc*$3}h)zgO^iHEmrRIpNle_%5`!*2>;Gu5$5>XJ`$stsx(g z59b&2bJg>U5^`OYaQAkJ?~nZJ#AE_`{RweTU*B3yUdJoAM{2Y$2Mg@!nVBARrh`>l zS8FqAY+~t41AGkF$uDNvHe2|?w~%svpJ(y=Jc|x`)asyXrzaEVv@|Bc33i^1?a!>? zKBmc+Qny?7zi0%1(iK&{YV1a4B6ghWIOqE zk!i~R+m4JwC+E9~@2fH~_`I{RWLIfk+oQ~HbeQ=)JOe!@Fu(lH&F|qR&F@~T|L&EI zF#`Q}Z^*XT`w;r?6wNQ~nfcv9eDp+LeqG9Qt%WqtJo_w-tkf7q!;)V&u-5bpy*TTk z@4N~f+5BHZ9dzd_!MFbR$)~;q-h5-_s`(d)e^CBZFZl{rzK-(f3NPn>e;u-yb)off zNcE867rm=u27bU>#cOphi|z?Aen@2gi2RVq^_(9PJzz*bBxQ4cNXicChjh9EW%|(< zWP3diKjdC(FPgbL277VfoMJDwo~}7vSEIQz@_S2OF1Fo+9@jjrruFW~0kbyVGB?>( z-qJWew>DnWezeQlhL$fXp7WgfVZdJ0+~wlq6<+qeResE8>+AC|pDzM?cOd5TPRiUZ z{i?pcAm;PWJom=?F`rG;FUD`o`1V$rn9tA7DC9RT=JR^mk#9utANfZV^VwkAejoil z-bbu|DL-2>lJmh2M4(L+cwP=40?P=hS4h zvZe71@Z-y>04@T$#b7a?`>n0fLqAvB-`((1>AkTz`0{MLN6%8oBI&k2;GOXKe>~Q6 zTzTv=@H<$n$IN5>X(rb5HTLP`bZh)}BZ>96`ik}J3Dr02r1#ijJ!hRVY^-PdMK>=z z=2(w`^Uc*J*3%M%lYJhF^%!1aeZ(#%bG7X3F@7B7$u|xk>v4U^SH3aS$4Fv5uD)VD zt3&k_>nR3fFxK-e!5Fo2bdXq&>qD`ge+c!VSkG5zL;WaL))R>JxO$59oE559$Pe?e zf&a-^kIqdGu$_jmweVFQQ~96biy5l@5$WIYL1I1de)&wpw#a9*oN+H=ix}M7SkD3W zWaZW@r9I!f1U>)#Ya)p|IVB`|NC#Z5AT0BxPE-0@xQOl;W{8c1GGFcTt5&0b%X4_ z{}KQ7anVC|2=7Drud&C5^ItD!Z+lGoV!(ghMZ4}<&Ud?l^D*c%hS%O6@ZIt}?7#l6 z`Fa2KhiKpI^No{(mEXDg&UZ_F`LDP0?pXZS(8>O#)_3~|{TX=iArA0gW8?Zb7~FsT z$7d`K0{-iFI~;`k*T06xn=xQJ=6v|r$6^2V`yCDzkjum206TN3!-48M98h2W>y^TR zvq?wbzYgLc8NdPS!uYQ*bz=Z8^~L0xG;KvHA4aEzL?-2hJe!x!r@0;D;T6e#!_TEdEj76}C z$9P%kck+P+_e>qxx{v)ip7IcJM&^Ok{m~6SY1O@`_2o96H1He}c0~4V4dfz;`un5x zJ={4Q)xl;oIfKe37$54y`4R7>WfM5RHH9-8dWO%${GY}%_DU)z3Gaq&doHrO2V1NY zn6S?}74!EdaJM4=&2MO5XC=PP|B=9{J>LVy6vDmsp<(}VCYCYLUu+8UFKY7|=s$Z% zW7;i3jXAlxeZ2D~l->Hx@B8;j6PGac(T6+#$i8DU4*Ixx ztbYfq@S^$Do{Kv0R}KDR;IA5d2IsffnW$My^LTj)zcn{$=I|POepX{Y%{;HqzQOh< zzqoLC8#q+IK|BseFDvFBEyR1=?$4lK!LPon-yS%Z7cJCRyO*&?`W9lt%fRc!%ZiOnxWR7O`-(wFkJ24~lqr zdvrEybQXKk*l)jhR!u63f3(WWrWSKgVyWF@P(^J2W-qymJ^1y?ud%-_sl9)1z{WK3 zhH>-}jqGXbjT~rCpog>nVg>Ky>uueQ51hD78}S?F?#@(mP%J}Hdso!eHHbHjgp7sPMvpZARpmee9~k1pSLGx*DMr2DF!d| zSW8(0FLNn)dlDtdKK96HUyRx{zUeMv*-gyl1~2a&+(~1-vOMCxa~g=Z2J&2;`6{j z+i{<#$u6qKKbGdML^D3_NsNgvM@nm-*BFlsgyY-A;0TS;ofFkrh|^9}9H^4L@*6s~ zMdld$Nc1RK`Hl0iyTGY%HG)R{j^rl~6xAzpAzPm9N1swWgV)AF{68 z`PMkRt@+8iox)WMdc5RvcC>mg5ESgx_?mn{I4m2rfi$<;1-zgdO~%8cTh)waPni zxB4{w1@IZD>(;XRcuin_`luI}pY3jbQanGF`S~+@-`)I7q3%%g^8{rF#mf+5JcC?~ z1IH+u8OGH@+A?&evX-#j<;--=9rPct-2-#TM< zvwnkTl_Rcsr~Lg|)AD&AwC5sBo7|_q8C;sV_vvW6_ouq#YT?)NAybdFul27pqnt%C zXUfzzj>0>2ue$iD-n%k_F@GlXRm8CE8CGb^zy&4?S>>VyF zR}2>c*t9kru8@Q1CGa@!{`2NUTF#5bn9s71O)*S+t}WRGBf$x02JU382bLXSKj<)b zlDAm8%;xl%B6$u**v_Mzof`~y#-6}#%+XS@HoNjVhL41R^P-=3||x9B>rW1L2i8MI+F`zM6eWtFW4`*b$9Is@$h@# zb$ED!-$6X&aT~xxu+7j|{@c_y@@~5aKX5(*jqPXlo$#x14j5Aimu_8tlX?ZXEK*K% zrnN4a72%VIJHS`E3h7MrUR@@= z0Qs%Dk-DD@sgDNwmJCpT;-&Jbpii3ISHhKO71+%g290Gfy}g(}rP#BUQJke6!pAaT z-G*?hxe{$)Q`~9hl5r2H6E7k&>@&@a_@u^pjU6XEXR^hgd=H!9liI&+{1BY~S{li*1gFuP8;0WZuCkId0}h~;4-uX-!tveb^&|= zSlTQs1`gVi9+NHFsZl%?0{)a_WudUiXpdl}-f|;ls#zI;@Nx;CpWZaN5szp{fVEsHE=xjzFUsC+-HGt#*6UQ0Id(F zFa3-*kC(o5s=+H`hi^TmcEO#~m-2dOKu;(Jdw?f8eppNo`kvZ{R|WN;=hO#$vY5_; zuREvnd?7Rz@zDXg$q;b=#_Bc3UJL0wcbT?*nRF~V&v(N7H$Z=)J@M(|sq=igtx)GV z^KUlJAJ%zFk3r`N!K^i!1|J1$au^ypR+;XvuL!@Wme z%jGIG`bI>4G;?Mb{j03s*_t`ME-(hCCj@l_#q+}YxAb#wZr&d}S-c5amA;6cH@H98 zuAA6!Fdgd{hKnWLJSusr{1G;mbZ5+uCEdmMNMcE^X5UOOmek6Bc)*_SdG*;T*}_;- zLbzB2e^@lKSklxtJ@;7B9N8B(mh=cP4Hir45d6R!j3xb;XG6u3OxwhgerD?yizR)4 zcQ%%^U9qIM@gM!x`nd+il5+4u2cM?wV6h~%YixP){~)}+UvBtV(!=c2bg`rlXNHI+h2&NnXMuDE$iy|e)^~93wNr6oXvX9n z+K0S6jWuM}5%6QTW!ov|jV-(N)zitlX>HdFUH(puaSZ2DD3j*<7SWz9v(4sTRGX|} z-=+<;CmT$$-nE}#&#Bv=C7YnM_*_y6ompGo(L-*4 zInc;b@X)F_H-7XWT{VJFJyUGE6=U0MYLJiKbc_C*4=KUztplwKTrjj$d}L z`djA8Ir^d8ZpyvRjz6XG(+>My{PFX?i}zRM#vhQKBN*GCiG{kcRRzX&<}r-zam7>f zW81s5qa@iIC8u9#Y~;G|%lTt7<)Win8W-5HZ7v*}dB2nwD17Y}hFZdGA5x$;TdH7x(fNymOKGCFP?yo3c0AGyrk|)2rvDw1c z9)^$i&Ae|a1|PayZeIz!teV&sd~aedPgW7$@SN`+-8;d*dvyCm|L)PZOiC_A9ywX} zetv8JlF`r61Dw7y->yHsGkZ=ICz^r|PZ{Y>K0hCtpFL-o>zDX2&v~T}vv*$dbL=;9 zF#m<$|5Gq4M%{~E@hJ1+Vw1Ah$|8QesH~K4=z&}!W>0I`SmNa9d=s9=7NK15zSR9I zUby>GFBxVpkJF<>YZtP|WvKg7m*?6F%&%w`yeO9C(MFC|d46PT1YOO)3qiIAv98>G zsXd<#-BA%8m{Z%>cj))Zbvz%tQD*|XduaoEAi{pO{j?!lK>K#ER~wr?E?+6W7xexJ z`DEI$EwuMmx;=Vf{*Kh&kmu(&e*WfDlvm~ax@1?ZrSayOh36-i!=IJYK=J3_PG>*9 z&FAf&>05W==)2gRI7Vk^^^%jO*gJ8sPn1(_KKt$ZpeKz>_P%nAT=iD?EO>Nd`CysZ z%bq<*onGkbQH={5Wy%GCLYu7#a&;!wb~t-qXNhDVI~)1L zh(8Z8;W|1K+X#Hm=T5&HD<|sQgYE+H%g(4#JKNkmMac_b=|gmZj%V^>w2{mFZ{RV8 zzLcYv^Snvt|LK_>%3D-zd@o)FHk#pQew#6~U(Dpuf+jUj;Wqnd^DuJ4w8^|hXmg2c zQ*rbNZ4yT}cmvK@biCgtd26bJFdP2}`Obm!N3{8C*QRV(+MMp%gvL#q5!WX9!tEII zeViQZ<6QGxc(JsmKJKNDZ@NC9HT5yp^-*g2*i>CwybtBp`r2k_*Xr8gx!Wlkp}*Lh z{Jq!Ey;Fmpuu1nw_~Q@J7yH-DI*;9qzW_gjp|AJy8$P4Ck462xvTD!GljeU{RCfCMOth^e zDLlRhJSx}G!7A1)`~M%S``aM&RBWEA{doe;q59Yq>f?{Dj{)>Gu#an^XXR*No1?d3 z#)Ms4Fs8k(zY);hHPM=2e?IPq8QO+iPxdaf%7k^ zj&zA%!dGK<@16FaS3pmSlT=5X@2=u>Xw1;8*?%74J{4QHFoq^R7~_0ZKDWJc@%8$2 zm2rJ4-~GNKeJaP+aDAE_$MDjA)**M)K);+p!8el2ACRzj_`q{_L93%)Y2$~B@_8z^ zoovq*^2~F&I^ka(GweCv%D_2ao*TIg{}Amf4!9lIo$vJGIM~&>6Dl(`LaOcI9nWr{@@3mGVD4 z;`RjuY)IO7<(y8Xvj8#hFq|&`Ty@MF;MHLr^W5bxoQ^5^;e~Ut7qL|wK8DgUzm#k1 z`RkY)KNXtGB6^9TW!7X+$87D@nW>o>>6lm0M)$nDUiRQet$d$n=%sVK^!p+@X4~($ zGhvH=Uy9K&*G7`N(J|B03U$nl(5Tj|?qKQDxm$F>uTv&X{y2Edrrp-w%H6@R(L3PU z>!rOPh1y$1ds>&$S!+)|cAeFS+1?;&zINj4)NtKo%fwae)Z{`_zdf%>EA4GKG)~X?SF>v?8G;<6J8p$|LaP)kC&Xv`%03A-_?{R zd&gq`!*kI4jNO?Y7p+~5-I=EE7L>pt*yaNLJ1 zR33P9FA4fQ=lyf{R_l%^kN@A9%KA^t@cZIhed%mCabWP&#JwTPpNl`EYet83eeUO_ zP3&E4o%zPzDJxI8yT*~1G42|_CiGwVcjuocyQFMWi`y%LKBBoHhk)59LL0`mQG6WV z1~IF(nYON`j#I`0C+8z#;DlJjTVtg=r>Ce3f1PZ`&ToSsyCcitrMwH=cSEh*^(UjGl67dr!Gp&#dvG>Y8zKM|jHK-`Niz5ic?KXy3$| z#7EX1Czc&mJlnUcprOtPI^LVfL2$Ljp>Qf2bys|S$L{F*jt0TVXB6Wr<#WYtzTVdJ zL?n6i3C_3&dEANkc%jKyfX4|J>BaC?&KaV!Wz$RWN5b!V;F%S>tSuMitZEy29p!r9 zhb8EF;&oAQHW__g^J;Pe9*QK>hYI_Qk0VwX>eI~WxOlDfnc9b zb!_B+TK-eyLMpCutTA}1WJ{`RZO8lItJ>d!4VwMcN#wkNzWNxea_Nw}`SgR)iaqzl zn>u>=p2OY^*#$-isrQnYvwjxGgyzxJ{2qo?&ro)~B7LLz9ogyqzCQPI2=V9*f&6!+Z!Y z5okbkSOWifBm2F5SelTl7T>%RZ%VNSG>73jYg`@5Ngl|L-*#QZ+B)2y^iyjyem#~{ zF4kqxxZ?q`#W_DPd5>*Z{7A5v9GeFQ@+65*pQFd;|4zMiG1S}@k01GFuSvn z*5AJQJ8nOWmA`^vqU3|`kKg>g!uJ!Z`l$iGeoZtIvPoY{FA>c3glqi;Pe6I9xnvjK$J?O`e zk9L(ENdK@jNe-uM_gAqEzX(l#6`H;do9v6$HoS*-QOfLQ{UV1xNqgN}cy`mf5bLi8R<-~B#s!g4UdjW9z8m$w)>`1*@pX<-d~Yy9?$*X$OOkT(?2M! z{ay*W{3c+ae`6osg%AEN{?ngi`sodxSr4Z-)bm|0-L^B$`|1ZGne-P&C94}End%1` zGU<(8*4c;E1*QtS8SNmDPPtQ&s026nkjE6<=rSg7i9XdyDJ(l z$do^Der7)HR6H<-_hT|;n_1@%EX(vY!~YwWWuBVExdh;tb1m!rTHx4h_|p)!;?x@L zt4mWyvAmSC7n{Ks&&p_XF8!78E=pUsJ(hRPW@+p}7)_Hz0wZ`Wct99qR(GdiX zXtw%I0jE7if+1cnzXM-1b`2&`33Pw|Jxu-MNrmTD$&`Pp@rEK_krhk=}EqfrAi9K+k zxl>NI4dXWUTY5F{^8XxY(ZK#;KmWMtpWm*3*%pUZg4Yi-hYjV-XIZA~qs(E$MVY=8 zUN-i?a%4>2#(db>T`TAd8#8798#=Vl=2OSnnXOI^Xx#tdb)KZLs9YKIX<_Z>T_4Y6 zZ`M<{;iL7P&fZkJG4O{iV{Fc9+F)2s^6gUn*S=Bg z(wDgTWNnr;RAgceD>CvK71*Y6`qX^FpNiY26KYOzur@TnH>}+btZB;+pr;A*{dWdV z;W3tzw-ah4ub=$e(Wy`HF=M7I?+yKE%%&Y|)uGzZ_)~{3tw~#3RqY(Qhxz1lI=roK zQ3G^!0(1pU-N)QCyxQE^=XAsSPsrKL;Nem@U> zKd+&)y43ea3>cTKC%#(IFg8|$$=Zwrrai5=eo#`nE}&p$ocYb6@u8^t_xCTw-oK^7Uk_=z-0={iTr3uo+a z%J!oByZGA2{(`MdTc({lGv5=_j3o`8Oh1*#CEL$I>ZaL`t$1V)<4_;MX|%NLRrRrsG4SW9p4lrsA6X)se!k_&diPxSQ$JT* zwExgRTeQ9Yg|kK5M<2iV&)*iEh#U#}6$)(8M8$#r=F!Q1yk4!@t-yLFMr^F z0>1{&B-{RiZLK<9ggOz$wpd%mu(&n{uznl=49a%x3=e%;M;!BR$h=oP+B zyUEK=1SY}T4ez<0KFn|A#x?wQZ2-UF`K}GY^fumi)4t&ezk@#lgZcfmFE4s#j6uGQ zsqL;DlPuAByl+&SyUHXCX$vAfUc*^AX&eSorABlRC z_n+wFzfALkF4fnCt=`3Wn2Y(B*LRlB2X7a9eDmz$`cB!@eR}^gFWYyxG>I+8Z^pjS z%T}(lux|8uI(pUS_nl&OCUDfx^W{Dd-&|mu*A}tOFQDB9J{Qn-Q_wbNZZBs(FXi3E zd@kqx25fV5i1Lel8By^D-oKW2_aP(R!24$A{k6O&R@4U^b2_ojJCP;#89p<-ZBCsS zdpBYLR*vbD|m?=g;#L4$+Z=C;gdDAPTdZEnkS zP$p-a^Xx*~m$A+HUrE1)zW81C<@(ODcX^$$cY&9nZSLw}M_(fylmCUbIdi)Td|wOw zU(0$}?XLso-`G~pHoq7>!>n8M<6QszcKzpU^B!#T8=1qm)8=E$;f?gSf;QjIJdDIP z2fp+Q%3`n2r_KP|ocEPS2C>aGHtHJNoVpE<1#ENP#lT}Ab9?>OJ^#Bjbh7(u-W@%x7$9zhfiDfKY7%P z)>V75*Q-mdeocAZvD<%BL#N|$^JUY%4|*FL=`1UYbjIGt*z4dK)9Ou(`G@2?aq%4G z0W>x{?Ual~=Pzq8HoN9TIq*3bYhum!zSr9APm~gCE-m22&DiaqCH@t2Iv~7wF+Nkt zxZHliCCJI$_-w!G%gJ*-?(=Er-?!ttd|nr{+=}eRiSFe%$96#=fX#NLqJaQTyuxtE!(#M`l8MBJoE$LGBD4p&wiFZ%d&_f%zI1hTLg&x{~ zwJJ{!E5r0q<&Ul8Jm{geI6a)}=wT=Hurovt_&Mf>=;8DDIr{Jy2xo#%wohL(@G$?9 z%Y7Sw3z;qZ`d`Q9@76Uq=J_0+>%FnDo3Zz?@%uKAHzZoNr!R`1JK|+o6N;nnUHbTh zx)_3JO1j$@INPoMBJ`7^OX`Ux`)7D2&Q^kdsW)Dl zd~|WCDKFhjb-H^;CHrK~d4+-k$XTD)$0QKYjUzhJOj8U6rc zUq;F|iSHGCUj}c~`!cWdz2ZB-d`TGQNrS^&&@ZrSY=ib2d>`mn<6Nw9P8xok21nq* z;YfSKx>q*bR~3eNTma^=gX7uc0x5;xtZuk(qF@+T1cp%kf-&1UF=Iw=Fu0_>qPQMw z-;eb=Pq%RYd2xt7Dh7wUpx+=ai}f3PALv)({26^7s(_vy%~^apTxf5e_?+Q&w3A*C zG3zvq|5kI=1C4k!b7wz9J8C0c#dF&2VIK7SevOIsSElwWeIBCwV366q|7ihj&Y(?v zd#3FfeA9Mc6=fvju*>^sv#(O?t!z`8HViCU)2xFY>T5lgupWD9qaWK|{TbTeo#Jm7 z5q~?Ky+Vr5FJI1G5Guzz#<)pw!bAL4jP4?0bj#;@H;T8w#gmapOXCS+eE4%~-kx)8 zaQYQ+xxU<)x_f&N747JF*6RWW#Ca=#|vU}@4wO2aXD({^NjH?c)-Ow+!$?L zSFTR*JN{&0&BbJFUrvV8-mR6uiC!?-@Cw>0cxPdB_*T2(|D#WMUi^Ri(${`LT~f+lgI^cgMAlFBI$uG*I!gi1&)p^SMQBa?PlUg@ z_yN;nSVzby_LZV!^1$t8ritv_EAsE$ zo*LqUwdpa;Q-!f-&N1{brXIU7X86l8`YzTU_nFnFID@pBkHMjxA$zq+4x+*++>?Trh- zS5Qwf5q?#)o?Vv)_E4Du9>f@-DfYsK`h^DyPr*G=#qw2Ntvj$>Ui9F;6xK=)GS#dV zWKMDbizyV=wFC_0$gJH|M)A8P(`+DFIH{_H;BmM!zz z6IuK6t!aI79{ZHn{dEWQW^#$mVU3xx;6uK`D_mK|t+G`ri_WIC7|gB28A$e0+4HF2 zLiu-_>YObk5#G^ZQzUCuVl+i_h!;7iO_%@EA%%-(k8QtPY4J|?CV)!bA<-x?$1PC!$iI_w>IjPsjKS;KGrGvTyl z*4H9@Sw7vBr;mDyS=Cm%J$+qkJ0A9Y-)L)m?bkhY+U^h}+>h1Uv)D{v`X zefPD0-J!DTgR|`SX%C(7R?t4+dt|j|;UQ_2=TSc(%p_Z&myEt9{Cv_Q%nF zg1y0JUIJ%QJC3H20=o;gz*CES~XK=kd%L0oJOyQ!ueU z(+$sPgI;$*Qy+AAX1%mpoKAFj=2;HUthJ>M&#c89o_TKe*RxK{o^JTibcbhn&}$r? zSvS9?FEdZ7@9<20!E%Uq!T4{w$og%&M}CW0HLZ7h1$dqtz;iGD2ZLwMC1~$O1U!(d zv?!kc!{OP`a3P+LY`ugy<4Vqdk1BefDYS#lpVx!FL0biS&=7k{-$Bk%R6EWv1ol!Y z<_Hdz4@WrC9!hApR%?K{&*yS_A!C!Ey ze!Ky58`MXv{B(0X)S32o=GrRM#~qz`(8fsfCe7awqR;pkWXB9-$4q3$7-YvJWCv#t zbv}u8(;i)Aawqj|fzIPmvxioGt*NxbUXX0}7GwbZpYVPwx9a$hAMUE(v5tR(?(-XT z!r=bcx+rnCXl?7VsLr8pU)nt-xtnuEFD=j8NU1H8Ywp6gm!j_&>o(m?Kh0{Fyzw_(vDNDhwS4R^9G%EqPzHhuO;=_?k+!XdIY=Sq>mtDsbls`QjZvs zSu6A3wdXGFnOyT*qq`|awMjX))Ry|@T%6)~<~)tYEI9PsyaS%J(;e;l(>m2U);?}i z#y;0tK2hgF1Osc^lw<81{%|qt8ou)Yduvrkyuy{^Ip;KIW%k9%?H1*O{-gbGE|xW? zBp=H%`%kfjbieZM=sI&YNjMG0vC3|;aV*YC9^F@BcpLGQC&k-(iCa7y3$Dk>HLn*A zz@_0oz}a^XdQh`}H?i<~|Azy3y{B*=>L_s9eK+%Vx6fC5?D+Z_AN#60gJT?UCKP?o zjq!Jp&=@Bbo(T<)asR*AF>YXt8w$tRJh`Ru!O$2@%vAJJ#kiLF`qwUKO5@g^Dvg~O zOSbPf_%ABF&OXM|Hx4{RDIcf&d@sqw`Q_1vWb^$iec;p39bd+$@hH0FW3rX7TYt;g zKSKM0+ngnB5}g*p*#(^c7J^f>k=k-ujdZIcTi2rNHKFT`DX!~{0q^LtJ+kHDOON&r zetyX0MZ`ZOn^@~3=o^wBU_N6LtZDp5-R16VV)3%8|INnvDBDuz+fniZ$(|L?w%M4a z`YNX{bN4Q5k#nhy-u(8v-s9?1cFq`oEe}>U>foa6{q~OW!N#!oHsXuS-C%7k;5~D^ zras5^muve=hF(yK^ms$S-!gIBCzqaeaxzX1+h5U7%*M}kmToJ!F=zMT zW9B?9JX5jDpMQuP`U(64tV?rtob{%1((68Q3u}&bX7J5AD?!ibt%@WcofJvlqO-Ti zUBPME6P?qx^T(T*WR$Xpz2rM7>vHo{;YYtZcdpsbHKcd`xn>`4;^*dEGwp@rv4*#f znvuNN^Ldhk^}wItjoA0{vGlCKjw6+MX^Kmp1m%_a;Cp^z#Tt9 znEi74zpJMSjzWDA+v=i z)-bg4ykaTDu?y#+OMcgKa@*wd0Pc#J?Mtfzms&VGeYNxDZkmT_(XUq82HH1=>TW3W549go0HDWuJz)_(x5uMPs& zgaBM$915->`k5W*XD~kVH2m4o%L~D0>a~Z@#i6oWEOH}&~_b>hB>}2AEmd3MLqd9$b z%cPp08y{e!?*rV5uCi6_a_<@-;_ zXP~k9KEO9kv%UiQQCZ^yqzteJe1MbDb@?R7&4%7yp7Q}-mf3^vuRSXNpL~SmRXdlw zY0)e2H(hRhfaFypw_2)eYKP)w@~^f=ugok&jw>yZ-X+?a1(`t;KxMfW)Pmbs?6`$(oO#|i!qX8cve#Sx{;N_Vg>%H>< z>V1I^@bb(-y)Wwdc57vJiu51A}|g%}$?z!}U5e#H26bo{1_{EM=G ziuwSn7+25-X#clUexMI5JYV}9|u&BW)XeE@vW8x@mv{;2qoBf0(K#^;9L zbQk*PZuHIu=s~m@^tqk!4(pHF2`|}M$V z20pjBNo+Zd2^+Srx6tP{uct7U;e2j;D6g`?G44T!ZjT52is9 z9ixkx1o&l~{qc`Q3&(hy9b%XG5z?jp?NdD(tK{Y@Vxz}8`J0UBYqzLTwqMQ@s;ik zjY<1si_MFCXm@NwpWls5!92)U(KFBM{Kv#IJ8t7S`gW&sck106c=oS%Q1&jyx*K1V z%|oW&eLJQ5mug#KX6H_t$Z@xg^S40~w+~^1M9U7qyR$ua;m_KMe{wZ( zqPy^)TnazD1KGu1ob;`}4YHYbj6Ayo+W`L8f3vkg;GGeC)iv0F-R!?lYcGD#2B{-o zNZly*YLC(x;r&ZHs*DXXo;B@wWO`g_ZLQ9n(RXYvyeI)23E-hG={|jT1K+ZUVpn{V z7bb#Eq4z4!d4b60nG>(Wr=fE}DQu_oVd4jg@kS>~uj2lq_;{m-rB_iNSmB48-!$9W zAUvzqGh~R`tuCbu zyLi5vHtzma9=F4t{Y_cBK{74XHO1y~zAWxey>~Xr3h))Q zNqB#s-Un?G+BW+V_%`yei+scJiF_Id+9cR2(noY(yV;kp1e*jL_thceWY=MXDRx<4 zlf>(dO|m)yA4u4|(R{0~K6HZqCBoB{9l`w}?btSb*pAxQQPd`ptrfIM?0@am9AJ}R z|Xe9o+m{u;m+Y~uLjpTf6JZfD}&<~%LyB)2CdWDoXX z4^~gpxQEV{l}cQadD!CRAnm!cxT)y)j_#;`7Iz1C#W@|Xo$^|ff;T3e3*WImslyX$ zbWiaK*hdwzktoM_zhuV6@8Qnhrd@95JK%Fi(aHH1pONjfhuC2|@j`NjV>_`gc0pbT z|5G-kgJbLNiZ@|9H5Ij;e)Z4Ru6P35=?QYL_&kuiSF4g;W8jqz!JeEn6PIiIO9 z-awh2I&2E;U)8^adYc)y_7!!@h7Q!#ISEz_c#htuP21k)Z@YK2;o0r>}m)i^Hr5Ag(HZ(7<6YQ&{=jZM4cio2WAHb!fGwmn30QnKzQ^-Cg z!xIJ{+u(NVyztnjYHWkst>fL;tSw%!X0TgJLSr-gUo^HTV{1lNL4P9G!R&*X3T*{!_gr~wMD2fh=xBBadrx$yV`netp>)Q{?0=cW{ugNWCr<}# zz$Ns%q;L+D5AA2P5euwsLqFqeUZrR#uhK9!#?6_KjWJC5+tGzaYLmS41-41dJ<=8O z$8O-@=f^c2VMgTC@*V*8r+G&%i`l4D;wjPyyfH(u)yJ){g-qwn%H@EZEk zSySaFc+l|`-o+XkYW2*}%?9|)$-XXjbRTWfm*i46<-}jdurDqxd?1gc2j2b*bf77I zc~|Cd>?@0ng7*Q>{DsC3U%qX!Q7XN)A+)0%H|*XL#A&yywhQHZscFK6kvAyp{iswp*{j9C4_1e?x z`$AI*>aoUt%{%QEbTB`}{~*ko!xXvWk+tMDjMzD4ua)%$RWoP0qe6PC=<+JNFY+wy zLuGy+w&mQqI}9H&baAMmR%`dj)-~)gypo*s_P&a!*6>NJ;i>IMx=NF}kEn+=e2_JE z^g7nmxptkhu1q`N)6lur6tJ90|7L!mS<&lPpwoJ{#%!5W-5R4Ux5ld78snMh&a6?| zo31s+e3^c=#^58`=byfw^`!N!^;lP*ZNZn_y@h96pzG_0Sz~o}jZrqY#1^Fh%9}OBTJ+D`&B(YlluAq` zPU`K~8mgq6nV(7i`Z0E*)(>m%hqT*06&hu|Y5m;G{~#?c)cPrecfVQxQPw|Y4ZKkw z-kwBBQv6W9618jkWNm0&^lb35Px8#H9oAhdJ^{0K;&$zh4<+Yyl(AiUuwD5&vgy8T1VuR2;6sCR-T5gRkjcMtVZS-AIIfZrtr+z zJm|W6(npPcr*{0cvzoPYMf=gHT{~U*eHHQvOMYrkDPxxnZgP^+_SyI+J6o*Y-3Pv^ zng98`FCXLIBO+bBr=mW4GHX?34UOTS_WKO@%@PBBuAJ)~(4PGCY7?EI&__O4{jubt ziHHtZpWyBkaHhKzJmhtOzBGdRijlec1$6_s(zzkcBQ%!Jp_%V-~KSc`3FD zYb#CNZBY+(%YVLtcJMbDf7O3H{Z|v?m}=i$!aG+7`C{s%D5Gbt{z2Mf9v)fgw`2DE z3ceP~9Yp4+occ^b|N8Ck=L+CH0JqkN-v9n|D>JIRWSYLTZhV{!UeBy6%Hc!m#231G zm(>Z0*O)Pwm=`#SLC0#-zz`58wD**o+u>*hUG7e;j;}ps?vVEBfV!*R$bC#| z6B=xyPlI=!_pm;{_=fzu0rQ&(XB0B6<)yEfQhY| zuh*CQc{P8uFj>m;N28^CKF#xo#+N6%u&bqyUPXP?#ebPiTiVw1uk&1cy+yAdf?kzp zx_T64kcX0mNpK_`OL5H9mf76nw7#Z#jMazL-a>SU(bhiTzhEolnf8c_cPc-CcwiN< zA|I2|XNQEjx;*(2U=|#8XTX<$;Vr;`4#XJ(+V;xI+kr#Q_aWVN@E+99~(K2mW#5vj(qTsh2Hd?0a~A5wcAAd&?V=rOIb7tn{y`Au{s#n(;jgFRb1r>VOz73cBwK6JmtmBdN-pwG2) zrn4Lzg6Bi!KE4n2-?DSM@Ou$wHur3qTGOU7=-}t$ul)?al|!+-tUmj>Evsuj3ywZp zJ1%K(vv6GU`w{N0m~h+29G#v4oi1Qbo&A=hS>{}8%&f206O)HB!qMs)(VWhWZJXia zO8zY2H_fx|>Hag_Yg+rP{5{YBxped{GTr*od1vx4u=hoH*u#FPcJx~5x2^1Lk`JLR zdKI|=)?^-GJ(#w!vw_RZO@-@^XP(Q!u#Eh_f6e;)uWtbkw||@G=AKaO2(xc%iI<%O zT!wEgsn4E`Z^Hb>9zb{T&qb-e^}lpeU$89VT{q7)=j6-kl-+NBW1njt6r*apM>!a# zksBc5=QMnLk=esN-QvOEXM#Tl`3zhx3LgjdK238@hddOEg#$kih4_-e!F72Ye22Mk z&vH0ej4nW5)tU=zxEv06Zt_qp5DxI)&%;K4#^PXJefCM(H#k@T@8)-|zQY0a1mqA6lt^&y<(Kf1p_p`eskP;lrE_%4X-vPr}&ajNQ^ji^CJo>K(0MV=kwx8Rxly z9GEiW9G71%46v&X;Go+s2fjxv08I>#|H(*q40tb!hxSNT)=paWySM)ApW{>$By*p95^ z4n5W;Ii{j~kkz_JeQ16(8-7HY96wqg;799^8$bHi(>~8mxwB}`ddZ{Da_-?MJ}c4Q z!;6!Nb6Of-VQA0A$!6A6fy-y8EB{ft%9sBqiVm66Si_uK`*_BBKD5i)BRx;k?$d?s z_R{W4LhX*F-5$=H8M-=LSU&o)md2Aq8%qB>xR|kx^E#J}FVb#6A9VR1Bu}Mh=53;Y&YDmzAo2ihodBJU zN;+S#e5UgC_QgeG@@udc8TqD|bqpC`_QM+fe-$*w2RWcP^w2am4H~0Nj>gsmXl#vW zY`c|t+hZe>dE1R{nU{InA42AxX=rRsjR#-h{uJyz%fFEw8V~uTfO#hC!{!eP@a+V1 zW%yBmZ?C02_snzr2>$v3Xv5IWFns&<**xDqNc)a&|B&Cg`XRoJEITH?eNg9*F7tWO zCi*k*GIlQ(7`yT)5!)6H%vo>zU%A{q@MM?U=YHe+hbP0=TkUvfI2`aShXeTL3Wo!D zW=?kT-1ySq$L6d&{J6^D0DfG_z97es$Mf6ZK=mCCs4rM%@veXu)3@QN%Lejd!#mc- z3@=_lUz&GQc58tDKFisvXSpx zL&5kfYYe_tTY0s*uzZ~IZw{6B@#TDMff!;ue@0#B%-f>=S#w{9ZOSx|8%sQdy)qqh z#``>EI`i+IwOF3o4Ieaj(xaP5C)C~<#q{O@hx8MjFKtIZ5zlRn&+NERZAP`HpBx&C z;15ym{+-}$?y_=w7diRJsn>Bc<=+2i=*`-8>R0-gKB?YWHEWQ=#&)D^?CrBxrD$7Y z?O!B$#ht}GH}?rk59(qsIsqakk;!!|Q53kDPqMw+)S)gok1q-k!4!&y0B4g{5Bh z4D{{=W3dq@c-iVH#;-9@UT%9y@^#=jMY}=#8oKFSSEKnizY|xP{1L`xT7k{f%e~6W ztj+X|(qwd9OXK&Rc6>B&hP;SALd@IvleITtDR}rb`Qch@ZpAd~1RdV^d&y@walDn0 zIoQZcAiKVR9(ZP8%$;Em=r@7>rI)oeSKc7KO#ZjF<_$MYA~&IQqoCgro$ke?cOMtN z-}k4%`M!~z+fFcie=Tzuv->?9-=C><7|^@VqRdG6zH3)}|5c%Oi}8I|UVQ%*q4NIx zzBu&mSB@>h_XBh`GQC^;cPu)0G#A5F3{~;cK6t9ruXS!rz7X+Mori*V!b{h}zxcqn zm0PMDyLE6s(+qTO%H(wJrhv}fbli0AOAUQB`F^IA_?c{u8tr$}c+&AmvLCsy2YxJj zl(Rv;|5$owVtwX{fGljg)jO~c9^ZP4y=USB6O1hU@?V0qSy_XEKl$zS+YL{>m3QPL zAW!TppI^n-bzl>Bz^^tfwKP4U;ZWj(YAZpF9E+xRTb8cu5D@jmr#Aj&xoh` za${vckKKwMyA?f_{4V~Q8J~=v+0u9|ZTNa@@DBT-<@_@8pNW@>&(~WyKL?z;XRX7? z`GxfPeB}HC^u7J?;BsF1CB*L~&%aIC7`Y|>o@D*)_?RT?xA85Tc%-tvMfn62cd@qd zzw-YfWc@~P{aj_e(aYydF|z)VKRa3r$ohcpYh*2JU3Uc<-3xi^_P%L9jUU^xYYh3z zes8Nw2X$0Go+kO6i=_qopnaXeI#`i!o47Rkwy$42Ne*+x$fcL64fz}MK9FEP!8I~H zWA@WXH--1g@9OhoasWnsek*-9rhLTOJ7RR(b?{?8@Mr0sL-XUA@MFs4`0?5RKVDmN z8}lR|h@0=>{QgDf86U{+|0sEnykyOEuR;%Xet>!4T0VU7WOU`6jtoyWdXe!1Y`~Ad zKGVRQh!042ZMA-YY0!^*<~d&oe04c|pju@I_yN$njUQlrh8$bjxzLTV{U_CDTWR0< z0bCr<)GzP@Y{-0)azpw7HYvaF?3&h%-T_0Sub*c80Q2cfV;3*Qcc1h5_cXyjo8X@t ztRG;`$;qzMTN-B-qv;osE_l3Xb4^?d*zrEX9c z{48Zgq6@lqr3-e2+AXFFy7JNmzZxq4V$uaaQ119vahqdAx?p%u-v;(rGN^}zU$A_DcipsW#=ROG(6{-$F@S?j!U6t(jn*IVuxD`aZTd5F z1`h7G_P`-YFhfX3qmSHS@4DKM%q9 zqT!#H%uVh-t)+1zZTNOUXg}otLD}~CCkOX)_&7Pu$hK1o@aoI9gVYVmw!df(3-di( ze9^Tl*>*yx-9csBC8s4N+q_VDe|}#aeh&Dzmtw4cMo7LUK5<9O*#Qw@C$^m817 zry9Pd_?q>192&ykaTzks`Tm3c4ns>XSz!DfH$s1TUtDF)%h6+NMWgVwmAo6w-%&Dz zzavIY4Cm+Qk^UXvXNqU!U<&v-98BV8mxW*o`#FAH#LwaCi=Ukzs_)bLhMM909Hx!4 zPEYpEZfRUh8^`MB7;AEc6~;4u`$XQ)FDgd>s3&k7NHa`Z)H7d>s4b<2VyMKMxD&Bfzg2EeTA@w9f9cQ8F*@Zrxj9+JxemMc=EbGQ?6>|KL(3!Z z-wdQ-{5S9V!;pFmIS^}%9`odrK^fueF?*>S)MLIunGxzSrd{bV{~c;~5Ix3}mmc%| zP-hQD==r#QtMxmY{qL*=_ReSDPL3)kJF(q!v3%s#{-s}fWwMI% z?C&kWQDqHhJtkkExxzQu#5-b=g?CtvA&yM$iu+wGTK~DjvL5+^H@D$fu3J#P`kS_C*@K^4Ru8 z_AT%_{k_^l?~O#aJT7a#<@ZN+^ey1r0DIaMXYaWeT;2A^18Qs!&_z5SM z0zB|oaAEeWzqoO6-f+0s`wz*gGV=cw!$rZ~7T=$5d?4uKFR(BFxX{Hjk4qLF(doY zE6xP>M&2XWUq@T!H*4>Y^p&gcWIy!<%TeBS)2@;Cb;y4DHou8)N*@m9RNuuum!;nw zZ{+^V>5IHwe%YqHp3oDBg_SM2_Zcrb)nldBQ$GB5qR8sob zKZn{KL?1KdrH}n%sQimbAA2yD7x4M$W1&0<|GP1hvM>i{ENduAZBu{!$Bx!@(G87)d3t3^9aXG-tKUK{Q4E` z8ypZb`98l54piUafclD={DODK5;H+=<#6!M01jH7W6VUkf}JfAjF}kucx9RKExyk5 zlaHCmw|EM;l24(AcZ0=D3Vn-(F_YL>=UZGi^d71}ti-`2-{N^8n8L9V<68{HN?d*U z78i!<`#f(%v6B5u-xf>uPH$bn?=#&HZOaIyA$tv_Oe!qX@{>5KB{`~xl z5$-wo2l|5+hxadTp7rIY%pTL1J0Bg zo0Rj!$N5Ydw)tM`k27;W0)O1VImaLO(LTv$d!{TwzEQhZQaOoCEL(ByW%9ocezxo< z+y!Oi+jV&v{Y~0+&vG)F_|c!C4I^JR1mqLX!)JoOcgV_UWYWvXS8n7JcHwC@zq>h8 z?Bo;mbtZT*?~dh6a8N$|i2e+`;9!p1Q-)5^2Obu%C$1knC^uV0Bp=iFBAh?OKjY4q z-RbbKERTnT!voK9ct93?(cu9f@lfZ>ZgqIT4}O^T4IZ#dALX~fqv|_6(5_&4ig!cq zE4wFuZ+s93chFZi<2QC|B4CTo;C$~4&i7W9`2L#jj!X7VX=%KL^8Pw+g z%SK?^?I2I&|CT-a-T%klxyRR8ReAq8JxzO(a%(99rB|vpr65XC+JV~8qf%NCNI{U^ zfTDnPUSyaVVX6{{j%b~sXNHkcbV%AFNl~ndV=ClS?mL2K^(SJm-1#W$m@sZLhud+VtILJvxXUocX7iKEin71Kix|-C*&= zM}n(;jVJzKzJERVmw4i6zv{w8;Ci2Q;b+I1F8uZm&m*q@U0B8=FL^xie$jsqKOz0M zZ}G(cfZj3P5y<^2=*Pbc<^CIy14X&*^MW9^%?BC86CViOn5;+cKkW4%a{q^3|Mijk z%L@-l|MA}Bw{koHk3DlPFX@A{^@WRPJB+@D5Kp{i-ulCH>y9ReN+p^eg3KSsTH>XW z`DfC1ADKS{n16%Zf2m+TdM{z#{1U?ad;0E!=Q6)(oMUS(agpoT%UVwiz-`!;w&#c~ zweAhN^M-Q`;)yKhY5CpMaa0@oX)!G?=+i$0Ar}yJ)FF(uO zuZLrcVH1sk&pU}N(0$Se>zSB+-4#o2R_)pIeo0{l&z4u3z58zVAGgDMkHK?~3m*Lc zwJIwfCq{r=!tJN9|9YYGsW-9q@8T|Kv!{Md-2LsW`}t1nLVHWcq&CibT8=B?ge{Lf z@z3o)CZ^~N%52@aNG=z z*JdZQtpmsF)8oPQQH9SdHW!>IKc_p(b*1uPWF|yUXSjFc4su~|Ze`7aFHg)7r*+8b z*W97F($!IF(u0cC(7k@b*S8+urMoehyCsEh=$SZe#rr-?>_!vu+fDe49^|>1*lzB= zV7}i84CfV;tGkIc(;_pR7r?u{P;GlRg)f`dqI*|CK&F zjx57%dSpXAcTE{?ul0SN6!&?$`qA2!KHsKi*0dVuyVYkl?(<^xc@llHHtL>BpZG`p zeEv{jj zBDc>h^*Ixtd-GQ{pXGgK>GN{e=UaWBj?WKPKgbF7d4QggJL+?W`ebiW^I5At;r(s! zeK+!DJAP6>PTfJ;+@bj_?{fuxzTNeStcYm{Ii&gg?PK&aD(>@1J)10ATsTO5nk?e{ zs`?yBpQGs0%OA%p+FNLTK=XM-*?czA=kcyja!`()&9m}f>yDK&o}%1qT)9}DEJL1@ z=U_%gMIYg>z~B2Q)XCpD!=i|s0nsU34#QbBy9eFn_K9-qNvDZcZ0(SozT|CC(vE&+h)iSx7p`<*Z!^USxHCdoNRMSe3;S5vciWnk495V3;&>J zqp78ZPydNIHJVyd_!Q4ww7m^l>V}rKLrZp70rd1a&1qV6G`_9r2`Br1G&whQctia+ zpasDe(@}iJOnU4>^1j#uB4Yr_jiY}D~cylKFv_qKL%cGPDJx=PL>jn?dN2X zo0H=-C+OdW%!%d$Ti9|S+aA5f2`(mR{Asnbv@p)&1)V-yxBxG*3*IDL(9X6rxBws9 z!H3}={yL3*yE@2cG85W-)M8OK&O3{{&eIL`7X-Mtgy*iWQttTja>ChJeQ;4Zc4erz zI6J_FatMhAJT5W=;NpL_mvHfro<$?z;t$%la=3U#dtLqD;^a!W_{Fr`I&g7#fQu=W za6viI?1B3k7iSGG(Z!F^Eg>$x`*{C!adUu+n*v;XHNeHj0dVnG^xKCn-Z#T=@iXX2 zaEM2KCE7~T1?7Z`AG&fS9tr3oTt`>n5!u7yk+qHEux(o-{9~N>tN)V!93QT)7fm1b(5t zpo>KTT?|jq#q*Et8(n<28yq>hxL41PF1oZ2?C9cGJoiTzC-$X_HS;E)kjqwIUq8&@ zAxRf4>c`Q=ZF+We@g4Q)=;9vVX9c?8LW(3^Sf4BC^D*YOOs6`!Sgn2>UEH8&M;EuN zPe&K)eV-NR;>~^O!uo8a&-+}TqKo@QTjg|N<)+qLU;k}at|DEeOYxvX)gu=Nbn#)c z`$~G`@1cu6I#uI`FX#L5BMaWDXN@1eyhOMFU(%@;@vQs<+bY->Z>Qgc>|8T%$s2Ro zBd)LiXn>0wc}~bqE4PAjtNP#~kez#hi(8Vy17jQAf(S>j^ zQMl+wr=D907ni*`mqn+}3vluFO1Plh3d+qI2p5gmawwGv5O;O4Y~i<@~rwi z^C!~Au2uK6#5Qwz&h}>X&suD>b@&R_H%=%#29H@@3wY4ywU7?Fcbn&nWra<8HojO| z_?3K)q6=j6Bj%^9Oc$>O@8$X3_YRJx0FKWEaC|d>qkRB4E=|JGC^)LfSHzi=Ko@r- zceaCr#~7RGO5=lNg$DYRPX`~B#cL&~x7~J=6C$3LEFu{*M z?GN;cjK;6EtgQ!M8NQ)WoYT?&8p}x+zwfQ(Zb;>q6J6?AvQ5wOhn3{q0ONOShyLbb zg2%m^izEGSHy0-*=0f|!$gQExMOJh%ymc48Iim|V7v0drcF_d(893oCbLIlx(_DQ0 z#CR^2YA(PNv5@lh73U%keYCi_&~rE!M}Ql>yDZ3AZ*$@AHbmZPF7QdTS6%kp%~i~a z{3$jE(3$Y7vr+@&`Yo-yp>vZ1gUF8E9ec;0ZCxcf@ijd=Iq@^?Njo{Q)%LL~%ZZpL zf_os6^8ih3V-C7$YddW}2JW9{UU#i};m3AeFt!f|WBXh%w$JRz*pmD{2)$oKpP}qo z>VG?WUq#=c?D;?p%bwGFBkT6;q_(x`N%)PCJ<GD_>bF-%PHNe@fBi9E8HF6JGOPWr-pg7d|J%A^+mtOsU3Hpw&1w)PDe}7GH_l)PFMc;e`s`#e6+-= z+Z?OxU%&BBH$TZxG%DKK+CAxN(U-vmt^LzBr*jz-@7rGk zElw9b9?U&+qC4ITpObiZ9Dn*fp8sVqG!ASZ?yZcU+gXzFr|8+q_{H37>Sg@-JomRo z*c%z&h%76kg%@aSnP6;H!Ps6MjBUyQW1DaM8R)N$z0;$QKU%_Zx1Jr2hXru#F7%J% znfnQj?*wq%6Ts0)-+r!tIRG3JlW>Ic%GujVeV$3q^$_Yj2VTnPV+eKrH(BQeqN%F_ z9KJum;f(Z;^i z4}m`3vln&Vm8>%uO=Sa{$MHkBU*dhi%9G%I!M5M$_OM3ce~?d$_4Qc!BObie-OJ3g z&JCN5gdOk;-fK-FAJ0#Jg*-vm$lv=TJ!7}X$FuW~@U;AGjoib+^FXl>kLf$M6gFVH z_O9;LJq>Az^4vacBbje2(S^iGW#T*!ZM zhmC3ftxFz+hRbA9$Kd;wpHI737;MzeT4#eyW!=br-DCWgPkDEc`>{0}$HL6RuP=Oe zQnrhnkk?$sd_yyS{#%Hdk?p1N&qF5r`G1R^-Tc2z&u;$TCLGD%nqE@CM_V~A2An-1 zTLfA=l`>j;>a2c#Zfdq@H9z;%*(v-{-?aRB4k(?Enz*&Kb*r+4%8}uK4b31!GaSYB8K@853x_9mAmSYry!+kP} z!MSK=&BWrYB^GBL zu{i6APq~eFAH_H|k)v>VfZygI|DECYtP#0%74d&%_?L(c=T(Z=xs8}157XB}n64lv-=a7tpNDBGFl~P{ zob!pZ#yFVrt73WfQG;W&;pt-r#~8!Y$L&4O#C&|*@T4(ZP`H8jU8{&8YCIb})q|&c z@U*B1)4}Y`dOB1*QA@TQrYtaRO2G6R=sApKx{y9PSH?W1xSGx@1nc60_M1De(tDnP zsq+JRe?eh|V7e6fw37X>E7%Xaiv6$;#PMmGyE!3D9{{GA0@Il#m_8lCbS*F)S`O1XU^*)S6MHBzo@S_zC55Nizp_{*V0uQ+Gh>*3uji9u zn10XN*W#&w>36)hIFRFkX(lk81WYHFVETRtQzI~?%VFvOrWpyClv~T_$;s>=sc$E< zf1+oz85S3|=ox(?JZ%w7(*)}Ug`Wy0_EpPboTimvnomqXk;Xp;OwVwiAh|F--*p4i zhy+Y0dYIDcV@ct5^=*2Wy#9JNy}P(@hn{7F0Mi|UNjeCaHVCFPFtNri#;)Ki^0MFu zAxx`*sk3-WyAxsC0Cdy%22Tbosz$98y{8N#Zh(W+MD;rA(_39G!Vp{U| z6)hykS335?@8z7YXK&HZ`SO0|{P|z**_?lqeZqK;eQ81a(SFW1>)Flu=0}|T0Kc1f zKhT^v0%H+R!JOZ#wZb6><+|D5`~xtC^qQRWo7K0Q^H1y9&G{{Qc5{A7e3Rf;so~)={q`QLo=QAHtgNaqw+%a>j!(pMNfx z^KIyh5O2hNj@26GTEU=rIUn~UJKXWlTLN6ZEx_gc0GIO}F13zO{7n~aR+7cypX&l# zc9Cm6@9w)aoP3iU#?0@B6F3nrJK#%?OWkLgclTNPdfFdg&t1L5+o2g2pw9+qnaCo>W_5iZ|9 z5H6`FdY+J|x4&`ucL6R>=?9k&|Du1o{Eq;aO#v>~2Dn@s;IerTT)t}{T)zHD!{yHf zPq0Q5E+-6xOX>-iKTOoy-?+Rez-15Xo)AXQ35L2&uj zfpD20Z@Bzu0w==d50M@H@;LQ`%MT>#^^42K(w$O!Vi%ne;PO)mTz(Q5Wf#o^25%SD z`PfNk7hPE8VvhA&v6I!&If}WIPeteXWs^L~-g6uax3uuIo{x`hl4ta6YXa5>4BPq?pU$37Cp{-1PFY z!fon1O@G*Kx9eH56M5OHXIm4nJ`hZjoxs%MVPY*%jN4{!&tPIb@VXGDq&@~F#biGE zNM9a*bwHQR_>Ee=8ryEBd#I-v&8>-g<#ZX`LA953c}_r=Pq8iudEC?GKLNwO(B&B2@Xe>X+1l-Ob2v1%)`_V zUA{4dDM^>Wq?pjz378}=mE)<1-y~g9Pcfo167~9}%e}OT76){>AVHU2_dM}G74*2_ zY+2z8!lmJCY2i*i8!s;{Y}B*lK;x3a#-GFE(12{BFY(^?7)HV4@b-52Iy`SVH^5~d z`||2(7E}7T;7RE5838W)*q78(jOou4^~!M>*q4LsNB9`agXj}?0Db}&XPFLSb{kpC zvz`y*EN@FsC_E0$TU-tJ@bP3?(_bKbIh-!hv%~2!Jv*E(6CS~-eD6zzN9eIXJDu|* zH^s2^6Gyv;@SPCAcVYnFn*#XW6u|e!LEyWh5`5u4Pr?_n9ewr~ID4G&+x~{(WLe<= z`my*Yr)LiIzrm%}MhC^e+lk?@*v$ih(c-Dt7wLrdMul(^&$ykK6n|Ezst99gZ~yr# zzKyRxMeHc~ej97H7XAIq?YfTfZR;Dyx7~)nMt*+X5!RGN-{7}Vywp{f5HHoZq^(^~ci!+Bcgf4g~FAO9}S)4GSs=c$?RMS9=U zdFmKso@6Tp^Hl5RDgU2Cn4Q6CmBN+HD?QSu?h81tO#$B426$T^;B9??w{?Ty ztt6xO9B&g}@@Yw&?yqRyA{eR6HYf_!#DD&m8#_%zMvnW&a zah3bFx6C`@Sc@I~n+MDNIpuztApg~1_)E*?4bItQC%JPmoMS@&>O70u?g3_!SD^(s=SLFfZUckG#>kPWS#qr>1fr zV19d8Gt^#}%1uuV%k?0Gw4EMiniXyygo5I zb<^&d?rhOa+6Rt{-Cm5^@8R8!boGYTbhL5$MI&<4uX%60)=ojsth32Y)n462&R)vB zy1Hg{=F9ZMb5(WqYW4BGukX59?Nmq6l|AGys@WRlcJh5X>)q2YpFzA&+>USKXxi^S zNi@OuT|4W6^Y?AL;<@IX#i#=F&%lAjWI-#foL^#o*ZBG6eC*B(-TMEeyHhuHLNm$O zXzx$bJnDRt`~m-u`*`EBr?&dD-Ta5XW8YI)c4eiq9l^ON=&1|8z_wAG#TrF!y2zak z10SM4Vot~EERp)fM`UHTL4RifZytD6M)R(7YGvoFvT-b}=x$OK=aO_bsR};J#%Ixe zEL6YW0~o_RP>Coz?j)`r8Tjym(PerTj6<UTpiD~(5{`S)^jz_>E&(q{y^!)e$$+BObfgZfyeWb0n)z1)W}l%w7QA767yE9@9Q**R-g2+i6jIH|Jfpqw5|+e;q?VKZtblu8z|jKcLVuZSCb6GUb4+b@G<(M*r84pNQ8k%sCXUHex$h5E`aWSy zrrLdfpwjp8V=@QE-}C6?7={ua;DOP3@NzdaBAn#Gm2y{bwl}6*y@P*+f8u*3C-@$% zY^8I8YvEDZ>eG>J(b>~i|EK#deoxA^vc0-= zW@~7dwctxv9@}QlqpVFI#(v#93*6m{OjE9sv2Cp#=a7dHnKI=E<60WWqGQf!Yvp`O zEjnQndwrX-V`JMQdroXycw3dYo@#8*4ZN3)x`8@(@O=6;Guo=LIqiLl^+u|0w!STx z5+R2u3$J)Pw3XkLWTxtRnW-|8nJxS`+0qzo9nL%yf3J(S%J#kgKVy4U?=?Ryz|A?K z!}Gu?{WpJHENAU^vz^B}$>b~Fr8{}vIOVJvxjTtB_V25Ylf8c^I5@OTZM38hHC(lH zjB)l>eOqgK5wg8{<-Aw9cq-2Nw06|Dtxh-GKm9|aZpmDJIrv;u*pOY+wt(N$FPAQ; zURmeXUoEcuC#-zUE!b77@8Dev<>PT2+Qzr~%yAoTnXL6js$tILdp4gE-P3T&8p-}d zecE2FHHUP$^07@G?(<0i7j3Ga9W$fe=^v`O#mc@R%Bk#E7&q$#?8+E^gPpdNH=zuE z<`fy%-lyE?3gxg3W_TD~-^G3%j7I_Eh0X@FHk0KXe4lpn5|-I^i8kc$=4!Z$>j9&@xCo_ z8<~6D+FWJa8evnTF2nR@W%^{;idgp&=; z9cQ<_oBB=Z(a6uU3!cB;2R%&ow99+(3jJProwGGIbsW+*T6EQ&-l{nD40^1k@sKua zgReI`vl#Y5VlhcyxOa4GLKZ!Od}oV&KsIc6)iWRW`^X9?C(lHY>a+czoB z25y>p$gJH5r((T-@Tq36&U5+X^ZYhBirkca)JogPXtSX%@-d?75Bls;UD;6lw|POw z)n0Rq!K8LV{9{M2Zl>P0^zhus-si;AcBfgs5n7=AVjC-lSsS9O7T_eG3^`WRK7Js+ z<#*p&@B7f$^-Xh`XFSR&-!k*8S(jBsCcFJyq=s>BleuVevTpZoXY=f4T%oP*=q%5B zXQ!_5cB-F*#YceP-|rd#qf_V)c5Jki|i_UW=?9LmDsl8z19lMm(dMnt10X4FkfD@W&KQG9-$+xH=w)v zzBqJi4{%{LhrALUwjkTc)f?MDvCU&V>1mC!Yo@$@PEKb;RId~MNU<(u-P_yFJN;HH zmGZOie$v7EB(O_%PxtoDxdr)+d-NXLI)4>wOl{~h^b-)T$VyPORrICT%hHp=CF*~VzA>525Y1;I8PId)s4 zY{)1#HxMT`*SWBcy_X`Jx6u*F25N4xS03Y1%?~RQ3rR*-|Z2?t+J!zvPrnrP8IZH?ZKy+ z52Y3z8`HuV?zQ+E`FZ`f8>;8m=$&NK4(ctS{3i}vP_uw{zX{)sj^FL{?~pZLOdU}3 zKK^!sqrV16?*m8g1wXHKxY@~`i^k{2n8|@3aI#5u!z0WIG}m(#bkDj)^D}RBjE_#< zodM4BvTd^X78l}kIFmo>1(pQhURhXTBpNdIgh>2iaB} zqxf0+9y#}YV7kdo(!Py&P}_?1n4)@VHv%#;R|~ zLgk1wKenDVrp|O-Z@9lPSbHsd(q582*fXAQHtnQYwyyx(+E)HjcB z%^!1#9UA9o^>gXhAmk6UeKzIpy#+pMnYnxx?V9Z&znI=j=W1O!1$$RxFQdV%<@RHK z<)6RwKce#|AC#K)`qxdan@oDF*G}xu=O}-@U_-|ne4-U_jhu#tknJA-yMf93+VbFB zJVw2Ct^56YzTdq-=xe{ui^l5Uyuqypb~6rJ7XefC=*<^ohBw@wxo7%LkAI{0tfTji z^8L@j{EiO?dn(iMr%oNn?~45{zw5X?@w+;?^A`M-&^7wLT<)CB`~4wz%H#(4D$0#O z29?PT${3FgBrBjB$%Jjt1a@%!O5$b*ln+69tv!|}%WG~W3nYJ_u_E2N_w1peTVh%G z3FcU|r*(9(TsXHuJ1OY-65-LwbIp05+@L|-Ja+>L4#~4^Y33sx%Rb4&RfDw?$PLlG zWVm!erW&8B%cZUU(Y=h5_nEr(F4pq+$aI&+Nn+tX3BWku)fa#xOs zd0+eAP2l9~lvlpkI5%pblL8pTx60r9V#ux|IHNU?>{?n$b_IBM^D`uw)InbwoAG@h zleDJlR~9Au8jSb<4*dE(m+$htN%*GE{`MSfKKL%aN$xp7qek1}7uL@0lZM-09~vL< zJ3N`#i#?`D`)a@M_XWl8jpce?{fGxe)lOJ+$|T;_5COIN?g-q-cs_7&nss1v#Ne@y$aPOBWR!2ZmZ%#`VtTV3^} z|1ZuzdowcZrXJc=&fm%S`QfGB+Ui&)mBAa}zKD-X?>b7lLGvuzMDr+qBPTn1dcl5i zrTUHKI2KQ9+}H!u4aU|_U88>|w=&4(>2JERzUO;i{hNq0Iz>CDBglD}F3$_(&%*7V zhX12+X(5AeH9ytaf77rd*`t+SKfwDoOYcUV4lQJ=e=v@`MEJm#6?!H$wC^|yS?l&a zB*Vo1kXd_~cT%^?mU5VesU!xT34a{Y<)lb=-iq%Y(P2fa&Li^f1(4g#BZwCUS zty$`Zvo};XGIuKfr(8WUH|)5E`Yg{YzA!S^@Z~u6NIF_|Ypb;18{lw1_Vw<;`U>@* zcm%s!^faHmTPyOF6o#KQ38b`dh}3x_2XANJSKrjXXiz?O z`e!c%I-a>~R;^zz($6{clf?Hl>IsHs+Jycsen)WT{rxW3sW%LZzNYpKH+=K!@cwWk znXWb!=a}qI@mOj{_AfMuOt8BL2BF0u1~QNr-Y(pUuEE#Zds$Uo@8wmc_2&-s&Psmc zvs+0VLHz>c?6!2x2CWUSU+S~JhmMea(m&#dGP&ev-p{e*K>qf`J*JK2dR=8@gNP3x~5GxnxRFKCT_#P``qAD?TzMH*2GlkHB$^>e>9^??FE@cfb_b2Z8*uwe#Vo zTW!4{Il_Fr(b0jelg_5?P1q}@LxC*z2$noOXsOhY?lT+AB?S%ou$|( z*;#qumYo%0XGNRicnZyZ8Qcz+dY_aZtYNT$V)=pYLXXtAoOeNN{-24g{t39yT=+lZ z6Xr{_Dfs|R7406C*;83P8o!&zHFx}A_mtmVq&~bZ^s@Rpz=RIlYgv5&dmS3bD@9f} zfDhqmk7PAAn`HGh?5z(~Rx7SEmIb9b4`nraa=*&zMHTvcQDn8-6DpI{;43MsfBwt> zvbv+(h982xy2jb7YXW<9jqKH*-8qQ8>SWpe&#vuD`!=`|jfU8=mh)hnX*n^>^QWf(m*eyo<-*sTRs5Y?N1= zjlRk4mA_DO|F`h=p342tOTO&6+~4AD^nd2u_$x{7UkpC>RPHODN^<`>bl_0szGCPH zlKWaK$oAV`Hact7`KTmQuu&Msd`+mgQ- zY&hu=Z?FabfmMz1N{me%hzErYyV`r=n+4c_QNagpM-WM zG4$FG_xZTA_fhNjK3ES*U)Y|A-}|7i(`jG6H`Y~lpPAqL=w>f{Cf_78wP&M!k1W4S z`yTzQ8EI3#ZMDf+!FKJdjj%D`XQ7?4HDEAq?;GSSM7!2X^0V1_L)MPUuMzvu0>4(H z`Q77vZ0aa)mi&p#xve)d8T|YQ5Zl$*cmJ{27qF6dspxCA+-=wcucE&)I2pU1kK%7}p*6j< zu%U5D!TW@jzf9+nGt;A|k9Iy~D@Pf86RSB(WBc@+t?6wgzbfx`-s@vhc&GgGn%ABg zI$OneWCC#uwr|_&*3@~v=?pPz`JG)nujP4NTJ1}o#XeNO&+GilwuVu=s;BzuSA9M1 zd@=T({ymI8=Y0?5J?tA8(}Jq#X+KWdhn5*X?Ws;ndSZ+Zeyi+4WdDNd|N4wCuQMd_ zd${sDTUgh&0JF~0H{&~(zg(~%=Y2=K7eBwZ`$V_80i=;a=g|RW7$A>^?@^+Hm94_%&zB zF_;{Shug{%D|?5iH`{F8r9jj_ohO@8WIWW~DkmqmFQ|y$R%1#WVEpxkG2}!n+j8 z{YuhX+NbG8E=sRSe~6|%PkCPS@3+BA@_We^)E(8rm+r|H98Dd%$1L!np+9^Kn9k7I zSYjSptv!CD8{v$8HNNZp-0=<{;_Uo#Vr!v$JqwqtrFh3P@AT~JXR6p&61}Lbp5eb8 z%v~{-tCAkmco_>c^YrOHKG@)hp8kP{gYO=;>E8DYuC+hb!#C!6wRF<=*keF$nGeyv z@y@fR{D@J*oT3g3{GER;Yr$8L575qwX}@L^dyKE7wcuX) z0Eq$9TJUP}{9voK8}AOXU-M_<19UN4;hJzY_)7W!ANt<`)`bZfH<%A_vV3psSx@1= z_W@3o?+qW|1FbKr4{(cofF2I#1Kc7X;Fmod$j1G>H}pf=uIK|~F60Azj_*TUhptKb z01rk#vgbt18f!LSzn(TbXm4-VqMNn%>(`=zPLLl&_GVOtzF{q@oUL}x`qcRDZ`saT z7s|&`S{DZTc^}uNXK9S4yZWw8Kk0mWer-Co42GevO%J7B#dURp-hE6Gvc=YSlT{Dc z%5-jpIxpCI7Q7oQtX~C3Mg8u|G{Eacogctx^md%(b^n4+SZHJe3vcCd53GoILqkX!TuLpvplBgzmO5aum6*cCOWI#Py5XW?!|udJ(62{ zzVA@9HQ%p&LeaUM`~JTl8}uRYp|$3o>^J*;hhGxkf(#v!t@%Fs5$~}cEXEjw`^~a> z_vgNYbZ4@^mwMk}?yvW&eYwTimsE}u%D*zk_NF%CK(Cw~ij z5ju;~n<7r~Vq|V}c6poHSZVS%@b4$!P4?eG|0BVLhe0u31HmuYi+yv4h0b=DmG1{; zol8+Y>EpYp>4);2cLl?UdTxJ~oECLqc#PE5j z<=Aas&-a*?g7$(nl=x6sZ#d9b1j{Gk6NtQiHVl zn4?t>Yb|iT&%qkD`xrF!`6A3g`(-wF0%rW3k70X0UIF$UZf=Wx;3Itud--w3K<-h- z5ZJhTIEFvse@187{8{_Jy&n8LM%&8A7xParh6F8@@egNSx(%K{zVrhR^WM9ib%1cH z`#fa-YR(0N@+xzV<0kfnSd(yX3-;W0V0jD~znJ%BbC!T7DGxR=K5~EUu}l&?8k=O& z_D$St!{)l@OxCKDWuoeGT^O$vT!x)okbp_ku8fATL_ zJ$T_u|IT?tXliX#xg_@xu1CRh2-mcJ;L;p~ zaD9A_;VQR9We0__;lqrn%#O+qJU{r(bjI^r;O<+gLynyo)lQih)xD;4zJHMVo72l5 ztYja93-jIe?sT+Ol&OJ^8l-K54f^!DB}rS!ev`NuZZsG4m+rfN>-pqTcwjI-sr&Xz z$tMHPJ2Dpj>SwIZPLrQe_Osy$8x6envT15I$oyO2BjyO&Y}c8w2p*cpH=VxctqxUUXb;EXkaKae3u05qPJC4jI!^>kXh&3`kex=UEJI^Sei+=2jA@e#m zZModcY97naHp!M&teoVfVm`HBwvc+tq4Vsg$xFbQZJjgEaKEb0aoCBiq3<`{@$Aj> zu=P7iAl`CDY0d`tN=DPyvrL-9Z*8+IUh+lI^;On2qJ`SO*w zhdq*zw~YhK=juHyKY5@zcDk|X!_ZtyM+S2}S98t!^IGOwb7yDtnLEwlTll6mvaRiy zZ^afbwf=@Scc%|w?v8#L&)w($Coy+>peuiUcVAuk25{$f<>l~$@LklE2M(kw`|>U8 z2j&Amf?p4LeT|JH9ZjrT`vm%9-;w>%Xl0|@J5@}c_7l{%_El3=)vL)nnInJNO~l%= zw#J7gIQ!w%L1mKD9}UQbqW&0!=Fg$OGW)Jk;|bd0dt8jIWS8C* zbA4b7S+0+%fpo=UZw#N}t_>#Ecsnjd+57teV3rqaLs%P z{5F_8odZr@174( zC+~d>T94OJ{j7~;chawTZ5@5%Tci%Y#Q}J(PBx0;IdWZ`V|3+sErQn`|3>f4b*VTW zTeQ@In?q&vtb3pIEFM*kyCjdkPGf{e*HRY$W$$+2*S$KPjraKE$=fi#&CaY;$78rq@kndPH?OtW z%xLS{XQHi&A(lN6`@Uj7MuzkJEothemykbYSz)@)_rnKWQ^{kwFlt{!`FNi?zT3T( za^eY#w}t-5ntxh}zcuE5=`0_$vz^u`lqC8WU$zBomvROw2?Z z$K>b6Id!;$kGe|>J(Q36YiZ#wom1nx=0@LjZyR@9u*a~ZtlURb?qqT{r-^r=Z{-}% zXR`(JjoTVX?=s?h;NJ=_tG%Y|5^SOV@8*;LNBF`&P|WiP&BSzNe#b~OY_uX7s5a#@ zDW0D}_G&(4*Y%e-a!=bU%YT{h(Zu}J&srUR3T4r$$eF=p(KzPoC6h&I@z2QCT^()> z8ps0gdxQSlEbr}+_@G_hb7-!n<(UbyTAo>2%vU2m%CKi7-yeHoW9>KoV*R!`!w>Oj zJNRgv(AK9Ox=t~B#d`Rr^;`9fKcRzGc(=2I_nfC_hJHT+56MQaHa|7I)*)V7YJ9ZL z(a*;uJCF;?ovJ?Jt&@D45wPA3JgNt;jB4o^Z??Pjw~qC_^f0m`njYnvDf3a<^7Hif zu3fbi`&olKhC7CDeg2Bkt-Dr@VQoJgzvx8vXe47Nuy-(_Z9VekwzSSs!9&O(@z{JP zUz!@1Qg&I}XK7z>G;z*KcIuDxTRJ~m%KhA&T}qov3i401Fpn1Vm_7nO!V!h0^b*?V zoCSPU!(On(MuNj_>0vq6K-@D$za1&_(<0NhL^qAdv59$;e9Ah*)x;T&JbsC4>e_QU zl{=Vcn@8Sv@p~-4sT=1c({@lm_Zl_;K!d5URtw68+v`79v^TG6``I4^i`p%D2XE_8z>xyWrbeq|PY27~@F2Su_ud0t;i{q1nJcE;YC)p;xmu%3!=1l*N z@ylNq?{!Tou$OMR0)-nd1I&iVM!DCkoQr#q&;BHSKZ_06IWj&&(XS4xG>-{ zI4WyD7?asm*-33iYs`yes{GxfRF`qabQxm)w*6CY`490Fp)0qteY|`K`6bHguZS zPtw(j9f{XYL3}CWNXo0T+5eKhE0fz5%3Vge6O-jSN;y7e90csytFuZDBYlTi)(o1vpkNaq%XXmB#Z&9^sXs9tNRkcAU}qmhrIHFB+ig% zex)C!3s^UspGkC4Hb>dM`f*Rj8_t*FmZghiO9`rPEbr`jU6gyAXUVrt-gohP zC%-$rUCcY?+|JM`2byG!;zictV_k=DlsglPb?5N>r1Nzuj}kKZF14$@rDn=@5`#UJ zvwiwTo3TvgoA8jiOFq%F@rj;A9PH41qJ7pdfn1cG9`0ov^tHi#luvwh&wP~PiJ|%^ z2j#)WLH&&zBj;~?ihe!sRq{7J$M=E!joft!+=KfY*MSf5q1HqZ{>FET4xsB7(%(2u zdKOxhyq7<4U(c5t4>*5g0p1(T-?+f#^$pLLbN{8$cu9Bmzn)F{MNTlBfkXJFOwU!2 zee-Nyg1xy4WzI;JNyx*b-?0k+-e7*m!{h@@*f?dd27P!rJ%u{2QN1D41AF!Gr2OZK zi!phP?NTEe12?+=WHK_r&UYa1L~m)MzgWlU?27hUzW%So5BTy`t~|0%GUSh63HN5= z@^^&gSvOhxz^whVoxVIW$hUuMSe~_2gl*YHIrQ!ryQ5{aa@z;o305fUmL@Y>^5yE?dj{b}IT)DzyVWgg(eujBho-Ptit1W|Z0V zfANJ5sCRXCv`lscIQ4RM0cG~a7rK;s___8#9=~#Yp}SZkJjtKgMEl?i-ANl~fx~jU zzqBUvbEKS)Z#UU6@Hu&{lcWnYpJ!-p&;_p)U+6;YB;A{hpLDPNLLY->|ARl|>A@tSVS0TU7A>fPiP39Yw%|2Q8ryj!I9_zJz z@R3#=chUZ3-T6}aNFNJ)r0bBygV`+d9ry8zbKxKrc)GvjtF z?p5>nA0T?e2b7yRgKlJM}6^`Zltv-+>NXYDf$ z`}im7k8WxG8^y5{V=KVtdACs>yzN>w@SV2G^XYjk^K{+pjEjL*-G4gbxj3d2n))~T zG~DwZUt9Zc4ljM{Gsl6i)t_CqGu8N|6t8)eYfJIEsVeQYG}Lp4<(OzVvBsBFL#v{^&odVlNjMHt>GIk#^2&b#--Q z_?|y3-g8hn;iS5meDgz{!*7nV*q!U0d=Y$_w;RIwgmyJA_xW6p+!vhr?@=aCBnyCf zW9I4jx9W?}bhas=p^c)Ui_u{r4UGXWY8QI3m~@SK`@PQ==|%Ze_3mcgwcSH*8)!)F ziPQ%bsVF%ZTSI)VwiodCoc7@~o z74QS_*z>izJ4pE^t81F?NNsIdapbI~+f!R@K7V~euH#J&^;bLG2rrWlN#Fp#bBu%W z;6UdnIIqAyVdpgAUTPiGfPDr@LqRz=xz|Z z&xAPi*Lxgrj^RZ7(uM=hE69g$I8c3$1L_Nw6Xd_8xBqia1dn@IKZbK<6t56VcVOv|e51-XEa#&0=hn$e>{zOCl zPRhr6xbGgQo%!Z$>wdkLJuN++=Im5d%zY$z(G9+&3zb(xzAO2!-^{b^F|!X?r#OlA zBXX1V9h^!Jze(Sbaf&ms@9ek5I=4K=B=n1G?Sjqpf}Wf6=csI*#8`mI_7?FI_G(^a zi?XhW&);M#>mHk3| zQ~O(p4g3PnqbOffUDtajy5&H0(-&tSoXbc@9d~fMX zY^Z+|G@U{Jh)-Ic89!?(INylBPv@)hQ)9cQhB7)cl{t0t>K@)9S9h*;@mO7dq}@N3 zx7$s-lN0UgEN<5`*gMh%&y<%>zphX(tMHj%kbRAf(YJiMbPf_( zVdsu?=aJ49>0YBg^!2Xv%bLD^%Gy@+6)~TkGr+BnrA8*}9;nfhJ-j#BI-?|8yY6OP zcQ^CD$|y+I z@fl?L)w#j08IG=Jl(*4M8_N=H#B{yf(RCnuogBMxM3D0#t2^@!Xx)`gBmc)0y0DkF zVJo#LJ_s4rGgEY<`|yrJ?kwg%_u0vQbFxZ0Rrlw$avoH7Vht>p#v_*~Q|1G2T1IoBO?wtorF=uDqt0N(l|XYXS7 zG&x(d5qX!9Y~dX;F}6S9uU_zPGUueg?%=)A5jMC#BfE8jvpb+)(T3Sx$h?1}uVQ^~ zcTnG8;T!Q>G3}j%?G@NzW_PTV-7#@i)1}eYVch>R??;E2-SIGeY3xR`ivr$QOnlkm z6m*!1W%N07a#Ke()c=_Bv0Qt5>+Wp2OcxGCu6g-{?vKwPBBSPks|U%$))1U?ldd=a zz?^7|e03VP#u4j=Nwc)R5st%m<@6lL-9SES9i$jQn@8ki^NQtHk0KwU`U-t8yI+BN z_@m?%=}!-1i>{g1Hq7+!Im~fM*2H@FC-6$BhifS_6g}+Ql^%X`qTNb**q4_cJ|R&) zp5K>;9)4F%1-%;3nWyuC_3%hyM8^>$dK7l`h+NB5;xI2&tka>as}DuqEGpzzM#MTT zLS~LdrjF(RIs8ATkkOi`@l`zY*Z5B46Mv0|@ptYZvh^@zD`kqZ_1r+Vo-5h9#@T#p zhG_GxN!WaAWb^GHcCO{Bb7xh`rSWiND*l7zlBwq- zQ_m}m!p0GA=f7W)sjq|n{JWw|U0&C_9vYEs$bUVMsl0EYE!LmN)bk4YMN#huTb)c@ zRM-1n+Bcbc9=W1nEKHE6b zwn{#~8duP4>@PVsoS6hBJZ`FD7qr%(C+dazf_?>-~yEwng#m{HezJ2~Es z9?c2$!*zQFvnfP*1;^GDFeRzFq0*a}w=V($l`Y^z{5h zdClp|WxaeCGQ7_^d{6asBFBxLtw64l|EX7gV{%Ke_Bp&jt}FhdZ;+kw+UH30Gk?h6 z)--?8dFZ-<*FHy}pD9z+&*umF`TYH+pNAQZogeGxE28$x#yB0tnn&Z2pShK_Tzm#( zae?(S`d~5o`GUgd$t`U%Xn9FDz0G3fk(<0L>Lz6CH=zxaACgzz=gxbr5A(=1TR*a% zy6JW&k0;gjX1#7g&isMCiuJv2qP}2Bvu5ZF=;TrFBnH7T-dD zHU`GtP!o@RCu7g2M{TgRA2`T&q;fk?j(RuXbN1_4-C?f0KRTasZm@1|{;z23rta~x zn!X>!a_gI;b5j>L)L&=)cpjZN3*YD1=fJ&q^gO;bHI8rFl#O#SwPcmkDb9@stmoKR zC?`K(4>H>Pe3VfhX8CHGSWnB(ul+drQnerV!w{xF0@KWLn7V;!NdhMPBV*Nf1|Ohu z!2Jq8Li2OcR^h#6YI*(il7{-XC+f%i&R!I_G?=d_;lJxS){)P#j@<3mk)J#yw_{>EAUR9M5GZb7?d-4L$`o z!d)I3e)jXdH_L~bhlZ46OZo4b81sC!nN|)veE;%mq`?RGK6E(WqH^CUx7&4;o2L2m z`+58>u0gve%z78N)V`kK^Y11u5PqgJcEU#Dv}cz^Lm@{Jt~e?1xd zi*4<2$T0bfZ!G$YUzdt{kE@D$kFCaUd?0?~(fEzAbC4H(*AO?nI`=Sl2rG|Sh+m_% z?xnLd|MuK?L0fTuZ6Ung4X>Z(_Llzkuv~g+Lwyr-9@ARjvk3ip@(JMI(SC-_$4Je; zJIi=5wxf6~?Rab?z9D|c?e+DU$&XNseF*!YeVv2So{VqXV(I8h{@thWbE^;0s@jn4 zI~AGQr=JSCE9pyVBoE(93 z-^8{I(MH=ck9K9F?W9iFZa+4fm6wh7XrjFF&dX#^W85puM*9tWp7No<%TEo(hr+(; zQ=t!qn2V?6L;3U{MPqwsqs<{NuylcJq9(US{v|Z)--R~XB51T$We2g*WPDWS! zkI6)2)l}lD=&M*iVWWM9Z+l{+A*W)SW`S!TY_wnFH)?Y0_=JtNW!_mwn~iov z8E?ck+P~=jdTg)%C6;GjZM6BqRbZpNp5H~7%55}*NjBOu^jqTZiL-`iqgj2~Xx)kW zF~1MVM%yy4c1kWiwW0og+KBZ}!bS`A+RIdTo`a0t8{K&qc_&{g-PuFmeRO9wjuGg0 zZ{=mQPqDw`-r_$Ds9U$p8-I-H)?>YrQNk8T~r|M4^Ol4#yS|Hq}^)4vLQ z*q_-rFFMKg+B)gWuQ$4$B);s)Xm-;R=BM5`@2)rIrk>PL{}5%0>y1SdOYvpkNq%A7 zr}0I_m+f@%Wjo8;SV0@#OSEBfaS?HO#O>@_HJ^B)VK2KqJM4)qZmqs$h->vNiM9F` zt<~>*WitDuuX6Nd@iZs158&>ixD47cImA0+9^zO- zY%3oxEq}7@eIU>7ZbIfDODxwHdqwk+Q@Yn`82o*NmvOY?b-QS?3tUZ>+~K`wB!6JXMJo<|32Jw5L zzrp#@?fhLj>itLhipLQhWpZk$F}RBFq)#7%J0E#ol#%5zxEtrS&CR8!H`M<#eHCTo zGkX++Yi&%WjSnT-i21HU3~t%F9zBPSTgzV3y0qJ)f}XV>#krfdwTGs*UJrd39V{fa zq$ZAA*Rx-zI#sS$|3DJA@_@WPSC@Edrp)s?m1Dm-#sVF87)y}2l{1S_MEV} zwm6&1|Jp@(k)T@4P#wA(n8rQoCUU++4ESZCCWNUhds*9Pk}-rG4lVt(u#>`77Y|N9TO zPCJSF9EkfcAKl4yy<6z3Sl_SHs4rN4DOpClra!JFMwGto`Nop%)EvZ!qC2+uJ+Hr` zKZ6$>TzEhN2X-D>I8dBOa1NGu6@LzPuEzl}s(#<^QTW%|&Q+Y9Xq`L;MkCXqamBPo#L-5yq3@l?GiGAtpZ^@ckFRUj zc`&no*~1*h9hJ&~;qlEFV*8nT&9pm3b}#)I+_wa9FC0dk$*YJnv6$~I^PbP-I#zMs zkv?PFbrCVD^~9)F#p~UGzx%U&v(Vy)E7`tf>zLTzVe{g~`8|z`F?C{7X`J`!w_-@N zZjUmfh;OPGUp6oFg}`6J-3IK*W2$P*Co+&f#RJ&$DB{0)F4p%n=KLW?@NJL$A!A3GKjgFY_0Tr|0`vRwtnCb3FG9xP&rP{+E_sw*C*N#9kmSV4;kFn{}{5;X!g&~*5BxC{f+X~ z?18PnG2ye>_&sd>Q=c4yt^e|}=QcWDm5qO}^Vs;6`;Hr5Ra)cjKXz&3ysHm3d+z?v z20Y+=Rd0v(LVND>lo_HuXYIS0{1t(`_iL>I z?YRz}tv!hQQ`44{UuSFc*c*yh)frUTY0A?tTMhqw?&pTTDJCZ^z6)_c9*k?@qdv(PiuwrOlX#~23Kye|e$u&K zUp~toXLq7}%rnbp2__rI;?g*}RuQAUiWu!{Ek=9eyp4zEvX>M8LmM$|zk_>c-C5sP zpgi0}ZjJ%v;n*Wh9{zI~PUH1$2HFhe;l-30vOJ_+$-}D??e;4VDKB~WzC`(WZeJej z+sXUGcOTGLrTi2I3?O%a_mvqlkWc-}j8i6>%-HssA<7KOOJ+QnC|{Hrz+^I`|J)fH z=N&sC*KuJ({dZ|2mKlM+bdZ>aTV3ua#Wd8pbD}4pLnQO{u4#}n9UrAnqXlGaQLki& zex~D8Vj8}}9Ch{+({KT@R`~{G`=3r(?V0>Jo$J8IzF+O`6~B({?!7$Mv2k7l@u{5a zIHpKzL0m%x+bijtKlw{9ouB*t^xem2JP3b0Wci57V}9NXy?Xu_EavB1pWZkA(3z(l z%vpc@@#lQz3Eo)a)}(9pa80@h=8E^b8x$zoa zqJ67Y`tHLUL*VDrUP72ZSP5qKtG(T_jrE80x8fCd;&YU3$o-JLCnq2Y;Qed2%YBL7i-d1`jc3UaeBZ^%0C z#8k}K(n5-L^du`wn;qmeX3eP_n%4IhM&xwYo%L(;tb6z97rRyYvXnPl^C>)B$+Pfq zB6j_*Rf)3}iMjCS05p%EQk?L}y7oACVsKv(^cUu8Y?&EtWjx#y=dfNb``?UXDbKrB1@U-|>Z^)74pYUvkc!QC!nLpXjud#X_Evx+ z`W{x*aDVTIQZc@TW6GB0q|K_$;l%iXdz;_*e5Ts{r1Fsfx7z(Q&w1w5aLn9I=05ta ztny1Y%$Z!Zc~0l3hB+UlOxYbe0dA6Qw+C%+tCI(Kv*o2z&qS%BcaK{x98|H(C7l%@Mh-MN#gpz@LeTyM$hd<+6MEOm;Ee zObWiuE^GTlg?sbHQ%~hI&+(nJ!M$mr9&ot(h4_Zt{hAk@q3v^LUNG04(6RC}<|$VV z44EpUn_kJ?E^sed*p!X79s>-e{s*4l`OI6t^Q-xz?WU2@)|1udGs|a{$=H5ii=g4o zG;|igWc7MZ7RhPk+U;%0XKOH|M(SEHvXVIR$>kg6|9c zJ)iu31HZkTQ2dxL_eP$7$KFWUcq{eU*q3LNNAV>7V%sH39%LLKiHN5*6f8w{l=YJVo6=2ZW#$Q>vp#KWx#JfMG+<5$Voy^ydl6A5b z@LZvtQk?U^{jmnMJ1hF&=4IB8>8}D_wxi$r=r%W2=2*F++Kcsv zh=V`SCg(lM<#L6-HMct{t9V4sZJy_WcwKTuvPAbjw7h`#PKWoJv=HMx$eqvaqJQDJ z4E74R@_CBGd#@W<+Z69{3Ggnxsc~NB#>rfd?Ey!%yvtNYSJqZX?X?HSapU9#1_tCU zdJR}imJB#&9g+#duqh+6Crk#>UvyoRJDRyLc|%{4QRD}$?lcj?;`dre1 zJsZeclO6cq!(0!N_s7{hqm$8D$6G%oo9Iw}m)SfO@E6XDm#yQVnZ;H&;Oh_;7t5-g z5b9SvV|Ae=-M?b89Gie~ZH(?3k<+_D;iv>#*e7y5nd?I1{|&H;<^>0LGP4(78h^}# zf!+z*ON`+WtLtEH8`^^o%@WZv0NW8*VspOz2Bo=CHj@VgSJaD zpc3ssC()@NqOQiBpDE`P$@e~bGBF;N5r2;auf~($ zpiiCb(Cn2y_4Zd^u7BzFz0xsn*mE5to$Y0k?%7eUpECQf5>7fwI?C2*v?2K>{7Poa zo|D`vYo~(Dv@>DU)jDZ1c7MbjWRqF9MpX@Sr0=X9+AEX!iN390+9;I`^qyb`Cc!eG z&JAD_-VGnr>A_dhOdHy-UJGvI{}6u_*H6M7JYaq##vkJ@&=cxkxM2*%{u@jFg0-}} zj&^kpL3+MPexvlnLJu-Q`}TIn2lW+CD1VuJXX1Uqv5o$^fu%I=;C}i&=)<4KQywip z2RrDihrV{um*k6I^GlCZ>@QoAYw?}sC~x;8=<4#)r1;qItt>?wOBUqj``nV9g^QQ7-xRNe6Ha6+3owdijI04~yk(-c3)nYwo6F3+a3+>xOfr zqrAQ{-KDt&7SmngW8dD(mF5DRN;dAXdC|jCIQVl)I~r^@`TWou1eAyE^`jT{f27f@9e)D)y_m z1I?-AX9$b>)&6e?kKVQ5XN>H;TA)MvnL|%QTK`Qkn*}~&PIi$`I$Zxr{>470fOf(* z)1};o;&`ecy%&tzfEBWtb zli)PnP5phZBUxU$$5eKn??>||xhJ2ybkrFiV;`Hjm25ovlmA@5_6uM98)%~Fe|VkB z^8M%={C@YqcbfWsG@fHrcL?K=O=A2FJjr`d7e4oFeAWUO76GfrtL{O)L572`G~^u{3b@-@yL^%+NFX>H(TzGPD;>jBB|BOR=guc<0zBJwYdtlKQV zANP*UtKuBht7jDNS^XaG!+Tc$iu$UXp>967XZ5qZ*E-d&TggyX_3ueawA$&#L_%;GWg~`WIiTUFgNy z)tdAZxAnbebq?>At>0hwtm-_#f$XU#&I3$k-8Yl{Q+JM2@&3BwgLM`0uiOoq=8u^7 z)-->O@jYAvp9eUK^8ky3^8ky3^8kxy{TLkTyoup%2>1Va91e5${~7;r-sB#9Xf0PQ zj^kg?#1?Yr0e%c_#lwoNZyM#!-c99x&3{qcDtGbfu2{a^oNGF}w2gcrZL%-t`TXpZ(>;svT^h^-Wy)+_`7zSV3hz)11U?0` z#fb-km`bpHU3uEeVe2Ly_qR8e!^XZ9F{t!!dD`0>e=)#y0o}f&Gxm2 z{XU)S+FE!dGF!j@`$Wz6kPYwd>zh-5+xKFA3*)aJhiAou1IAyo=F}Ob5%5XRG{!Ik zUa)wtIH&#%s-JfGN{&Z9r~ApNPfYbn`s*A*{PoBG4CAkViX2vq>HlZ%-Q(=6s{8-v z%*iBY5<;#J5=b(W0W(9ufWamKF_Vm%1XN(c{g%LJxkSXkS0N&0V5|lMnp4oU@@<(U zSSP_tT5Qd+Vgh3o1T}$HthMz_2K7t=MWihm0-f*sv!1=r+0U6XlW9_gG)!y>ccS&OE_lOn>lMFB^gw({NwdKG4_b z@4nYQ^Y?YHe#QN4duh$>;EsfD;sbee6`tjNOL)9@u6R3s4@KwgbcaHQb;$F(&YbCe z2ffj)^>@g1_XXBnmGS5B`0d|O_}U9^+`8MN_bq{k{i`L#xSwIwxf@uhiGr3_b(gk_nVy1no{e|wLInFlh)?Xg0pr% z!&)nurMu)-`1iR;H=eNbdfbhNuK!!gnXeX|(){vn4OPr!xQ2d|wmm##N4$3io^bmd zd4rwblg(rU`aq}G2lOsXG{esB9R^Q}R+7bqLC(n89N5P@+`NxkQ=9|A`sn1gY!%wO zVw=h(-ubN{*Rk27^OfQr%#O((INWcS_%_&YGv9uHvBsrys~QL1q~2!xwk~3S(Zw{b znQ@G7J2Ajrmu~AskGkqZpKWP8>AUTW=!KvnQzB=!?GiY58I&rQ>SWS%O^Cs?8P46t|>)){}mi6;rs8T8@^o^7V+IE ze36Hf%J4OQ02k9axqnQ0fc=&Z!2Hu+C+Ao%494N{x9?xC_ZZ8^;d`WCPWqtZfV}qO z@DG%Yj!0$SQta2{V!yrwj7t6LBt7oe1;u`Sh_nu5fA^h(j6?h60poB2G~G!(8;9n} zgN{RiwZ)HJy~g2)DEpGhkr~r?Tkt{8H>(H1_Y)4^{1r_PdcJ8QEsxy(yE1%j9KgkB z-+aNgPVlzh?H44*VW0K}Za!QM4f~L_<>T-H(Ux`w8;62)JO|?fm90%>zw7&TUa4Qr zgY@e?zF+5+`ZZGhn%&fQOIg4CeCXxv;_~_Mqd$Ln{fDWianQOn*nB9kj`?wTh&oYi zl>Kv$?}8G(lLo<8_mqfl@(W7%DsD8-8nmnoUyVb!@8V6;c#YxB<#0ZH!H>g+s%-0* zUS7Y%_v4fy`eAD)^O`#6Qb+Upk9|L8m-_KbaI3`s*f!#R%r5ogE9!^Nrrwd{f9nUh zh=+6+WQh9}0q!S($7GNDtRZk`y|*y{_nE?-xiHt`KD~td-w%R&&f`A4g!|3H9o^w? zD&Y<;hC63jL)^9R_jpu;#~xr9{~S34?y@J9_lQCSpOOBTmXL&?k>WM!(iN)kThPNB8g30;p z{~P3S-$5xamCAlT$g52Sc{Qo*XAPG)j#zL7Q}Nz0UV$DYooZC{Ap3vmT)Bjv;odx{7cvE5gzqUu_7k z>a+KGu;>?QPmVzzdfi%6?u!Y04{2g5mT{hkd9%UkS)011nr^&bx^pBIbhW@#&_%jp#C)x-Qv6x`(^!nt5PG61F^BYU)vA!Cocidk}H-3D^!MQ7$e!ENO zt})}U&gKhaz4uuM=e|<=7FQ?D99a<{iJNk1iOFtCr z=d~A>(yuzSl%7AMl-_%MDSgEyrSz-bT1u~7R!SHAnh!hpSC`TS->35id67PX@6%UY zQ%V$VNK3Yl_eSCWU+ERM&op-c6`qdbpj+;yASADjWp1&bT*S_g- zw|^<_n=agDwy@8-sJzDJ#?A(b8V8QGia*(Xi@wr}fi?7Y?m`$GNwKPe}8;A`uptx2>M!@kh; zUg7nZ0bXCFjiny1t|NxPOK;Z4cy$P`6H?h<-tO>fKca}&TEpx77_av8ZC~-DN_f$h z;nj715w9D-D_%!sJ7o{}?xqJbwdk3C+|@pNxQSmt=U5VD_ag5)*k5Vic>fFdpxAfG z*4kMW$DHW*X7*s(b62_dLv<%Kb}HVIeRRr(dfv@!KXTi~IjLQlTCLwlZi}!vMvo8A zuB0D2%h%a83EA!N;&+VmdB{k&uVdUpS#axc$6F59-p{|h{&r8__DO@&xBc*#zVz?s z)KUK)pnp-MJ@up_edmb2?dQhyZ9dQF`>{&&r7gp?{k)jIbB>%R-avmcUele2dIO?C zF?ctRJhH*>x940mPdb+PWCG){y=zKhENZJ=|HQY$9N)UWehs|ePhX>=-Jp!O+Yc-D zag*!g$BTVDyx7N=h_C2qKgad)T%>2nOPpD+go%sJXJ+BcsQ)Bb@eMtg5VsYLsb-&Z(Z zHT%d<>;6P}sio*@nYw8kutC)QwC+;<{t5VK{%ag-Q{*chdrBsnH_eZy;qkzQ#WDS> zw3A8j*&_P78(V3{bk~VP&}TxCK5rL&&X2N(6zMauNFSY1?r2};=ySHw=d%^*GttrK z?3h0A+KnDB_7puEUS9u55w8hD;59zRi#k7{j^@m-;1ioO=?O)={@Czpad<5=ysoT> z*93>xvLaqB0bUQ%#>OIEnw*?i{aH?5wGzMua+WS z#|3z;r;Se(@ftS-USo@ReMWdOj$bU|HLi%)6vOLGhu2w#*CiG48t3pjtBBWdj~8p+ z;V152|8`(4URXu@1*Gi#YyURcT#*_JsZG521}({*LBPI2PunaytSXGez4ccKY=t z9RHoVuYkum>P49-yV&8GpObpfuhZWbp6g>g^K%xO-D+e7Jk_S=YGLj|+v7_9J`mv9 zMO({Fw*bGHsa#utU#LHD=W>yTe@~sLfiqwpulf>R8-&;A9A5P?UYm%^Dwkzy%kY|6 z!t2feufL>?`5v!HL*Vu45?y{E;R|~IsQTCrbUg;8E=LoM`9A4=duk$M5MO%i~h!S241H8_n zjc0k^+W73nXz+2op@i4FgjZ9P{kq5Ng{a71vxV0U4zCwj1CamMRl)H}t(}Wi?_jZq0PYJIY;dQOUt0%^5R3*G<%kcVj39tV$+juMo zs%c|`$Lpyf@VcUe*S^`{h0JaBcs*Ids|VX0_G6P9`6pw%-ckuK+A_SJD&h6x0Iy%r z#!Vit?+=03@)BN82rp#rsUEMc5?=DdlPV#s?P{M1y@H)@o^+1f*&nn?XTZY#+OL(;hc-=)Cvprs4 z9s;j3N_c%rcwHG~pJ#kbPHZaSwMuxM;qclN#h=Brwgye4zIgnygpkAFWNG^)|c>_>+!0q%AS7mE9);pzxEivKdyuy?HPWbF5x#O zz^|TmPNtorzu|@<@S9u0?=b2eC;ad^+~o1QzJ%X?*@5xrXkE`=ALIAVO8C*9;des` zzhAR{di~+Wx9(qm7iUe3c2^8BuI9UmWz8Py$d`GJ$E&r3*FOud*$%JP7_TEL;YC}9 z*A*qa9`bmhbARy9US41A`R%+R@S5ppMxFDiBj3hskJqviUSAhpGaX*bV!VF)sS0v~ zwhXWHN_gGl@j_R-pS~~l^jbUwUeinS;IBk4e2z69ujUe7w+pZ74zK1Iug5FlMO%i~ z;u2mT^?1?u$@D$v@tQjXUXx1nIz;q3BFgqKKF0rZN_e#juSpKCIWb;;T?sGRGQ8%N z@H)fe1-+Kj_x;4$8Gp?j0 zcr|*wpw|zxFR#DG(`(WYc#SC0YX@~A=Hq&g*Mt&YlZ4j@hu4G{uL~>TMO%i~q!M0f z@Y;@^p>+B9u{&pV*5c)BAMUjHyfPcMj~kIKI!X=8z8J?cS}aKw@dL8ur&l-SULrkl zW&=3*80@U3?tIgkiVSv**M7#(;NiDudN4KixM|Xj6UA}-*#9D zPH6v+!tw!6M8UY&_&WRi3TImto}vA}ZBz-qjh8R)-+B?B1or>hno@c5*ZA_zwkh~w z+*C)x!yR{y0tlKD50Z@7Y=@V$X=%}?%p%>AF> z_bLY`HHLoP6=i>W`+nV_dXna?#qY63?dFW^&1?6s-{I!9&Ukt{AZvh2tlaTUxuvv~ z8U5%KpC=gHIT^#LiQ)eY`1sHV!2cldoBTP``lj3-+7P@(?AnaUC=XNd0=~V>>gmg_ zs?g>;f-+01k~nd{o8faAbG#1U;%3v%or;ZkB{!8@_pP~)<5DXW0~s4QZ#<$rp3J1ORhV_x%#xwjaGuF*g~`P!qpZ)B$_pck$LCUPdwJT-qp`Q~0^`CbxVDz0=z?H%j!O zUv@7q`00Gtao|;;Uy6^=JwfPHImyCIDq8geuhVd@+v8xd5H6oHP4U_o=a1vA*PP~C zfp4AFZ$NfPX8{&+GLC`Nxo?fhk92k%ynVTNzLd(TOeu~hh?%G~cEkl2?;ap#M0bhW z*(mz@R6G7cch=&8i{mqEBY{nfirw!b9@%=Ei``&sM?eqpquLk$C(r4}eB*W2-Vv2! zod?UWr2mSajJNndace1t1RhTEi|hAbu+dZP{+Yq@{aG6HbKu5jXqv)%MJmy?3z+bs z-N^z?(bLB39_FXHv-y|s$*rccPnR&GzTN*pC9*1<+)S)_ZM5=o|K*HhwjT8Fb67>(|VAU ztEGLKV#2)awsipB*!fMJ#U`CL)&zGOoDLi>C!YCu@@|7O$@6v4^XzVe9?BH=b>cbT z>1;gq0>Qzo7q2`2K)Kz>I(@56ox3i{mSFv0u7zhJBzwBPKJZ?mm?neQvo(u;+Z{wF zzHxUDAuDzcbtl{J>K=y0Ka+h&yd2P=IhK8*ZQwu4#FA%jWA?!;1G8NDp{HWmqo~v3q6XrE){vL(sUlbl1R%z%%{;rtTrQ zeNQQG!1%VS5AM!!);8%0wzerIlJ$FxgM~htxF?`Pz)9` zr{t+~0`*llQ_VUQ+!OF;qz`pZKo%O=+8$*_c3wYip3aRojEMCzgNN?AW_YZ(d)%ZK z>kWWL=*~N)=n8Eu*rvx5t7-S84v91O1Y8Wx-Qc?5IL>lm&-(~C^y;a~5&&Y-Q@^j#A&ZAst=hg9juf(S5-bg-;K4;(?rR68Y{Fa{sPqfL7 z<<8NQm-6-&^5XZO<2M91w{xD6Gdy;l5nY>eT*OCko-wU6jhtsB7GcQqjMpEUDX02xaVTX=0Z}j{$Gq&JxYzbB@}p7>$?X-*ItW&$w6<^uN-( zgtO2$pnHSH;|#{5%B_2(Yj4J$h4qg33H%37ft$rg;~&`KI)av zTKs)(-*X1@oVLa1yaQ5v7i0r(2zIu{ZvvXE%gnX2jsH%2o=-ZeoLq9ep!*9%i$>zd zb^oH`#=kDwk#BD(6El9l@SVWAKD#N`qnL5_PDUO;x`4)g|9^00=%Hu`uAxZknNd;wQGAxW1qX1b9c7S z?0ylrFDBvk@TOpE8QjtENcRh@DdNi)lI8WL;CW@`HJ+W7-dJ^d#bA4?a$CK00O=9Z z6*y0w?H?26roh94=_`Z6b?t`wyw}+WtrO@Y(t9bVeU9Bps6EdjXff~Z-`{&j*U)xs zhY9qy_N3k~{jDIJ`F|F3&7Y?jun#!UxB&M+z9H?1Kv20wG;?NHIes_a6q3$n=GTEZsK z1Ft;|EN?5+osK==@-(pHaSQg=>A;_aEGwSrLEhb`br`v(e*Q%FW60;6mVYSTZ`DH2 z=(`iL3*qC3ccD{YE3PhK21rQyrbyhOk1u?}Oa`L^KD zxXw80n0x`|8W)FcHa%oA>)T0|M_bt0=lgQ9x$F0K+SGr}4Q)%OaJ>7+ZNPcKUho^3K8M#orz>^t|{_<-f{#vE9-2 z)y#{d$Gz&Yu(_Z)bHI5~LB3(@9cV{#GA<#zyGr(#N_L|&uQ~9Ym={pyKzCw#IN~q) z6Lupjv|l_LJVU!tEwB#CZd9SqzbjkJ79_Vm`X(mtZpDV(_KA4EM@%IC#>~n^ZXIK-+!~#< zAX}&N(H~lnUGxs@EIJ>3$AauQ=q=t8yc%HH{)hiB2@iKRHpO|?e!j1buwe*?RAhJ% zYZv1&JH|t}3y&4TgL2q$wh%9eU8iPc4e#Oz*QZ^b8e+4w?^4EZd(_jL(6Yzp zH>I-AyRxEN_x0#Uto2pchlE@I6;8Lg0$qnZ`M);0wcT)}&h4VzY}R(l2%dDnO`;WT z&-JuoJ@1_z>q;tj5BVAo-Irng_xaT^oV!SWOnKCaYNFKzwXgc4BU>Z%jXp500Dipr zGRfltjknejFFJ?#pZ@c>8{OT3&WJC$?I^yTy%ysY<8qlh zgXG)t^-uTpX;XLc`}*%zI`XTAbnVkFb2>G8s_~aEcZ#c@N4K`L^BCJ<&!|C~BI4f^^GjMtK=R?N?sIF*Z^oO4A9DZ(u&f6PZ zgZ*H$_82ZEKr)s%LXGzl*_a=|#>4(VV>nE8E8U;R9XpD1>3o2@QC-}$__GRmhHdIM zQGR%K1NRBMLVxky+8#`2B6MF;(Ni-dy&GU(c#gl@0(N0YU-kK_M6ximH#hi_Z1)S zpg+P3Uv@6wx1j!Aho??#ktTAg#S>CeHY z?_w>~P8aQH-i7_23Es-v0L-Vzm&{e$#H!oghFF5WHC3^kGTM;mX+0Qi6k{NmU#`%e z;s*pra2u-Qw!m>foPp7^(*5wk+?AfEJ)U?98D=n8GskJoQ9mVLW+MA{IJ@L`z-JqO zk|~OF5FQQH#8y;8H{@(|R^!^OE?@1(aw*{NvbiT)j{5l+b=WiJe#HO8Tn+bm%!guJ z1NgRooHdua_~&yG{Cx}G= zJ>xq|pmB6rb@rD(FF=$q!>M|Hmnye)nN&y$3Y{l+Fz&u`PcflL3* zey6#B&wF(*JjS~it0nV_x>JR`PTQW!{?B+#>#HqUMSGvDox-nQ=912aOphqhtAcc_n`G&P~X1#)7rM z*0T(8U0Yn68ECCFL*uTsN54g9$t36k?YZ|@^xt&pJdKI`jjX$KRYrAzRa^((LYm2C z%KN@8^=p{cW4B%lwqTyg_zI46#qxTKhN$=7SG{b$bJf+KuiH?4pf#ZK7*)~_A0?h% zcqVwiIgT+&A ze!z9%eg5yEzWJWvi$dV1?<9RFKmGq@@1!}!{_u_T(+`gGn{c21kTiOo_xYduxi`d5 zKR7)GxzGRPa6FNjWq$f~Wq$f~nW6pk728LT8gQTg7w#PBr(a6i)prcxr)Nz+_&C6U zcMIFS!tBd?Ipa6rUSWK#Z^pgC_~F+%Km5AP!TI5hhJhb`-S_-`{@g39*pc4WDEG*i z*q8ht(AMN9X|*m5+ehEj8~fI??$~;z@5y|tT#fGcr|d(co!^N((W7@3bdfI_I`qzD ze~fN)2z9z=I=jfMraryV?c3Vneg3|_Y$~$X5ckn5KPu_oSKOh!4f|gC-_2)?&tx-x z67Mt4OeS`kwgtN}HF9rZG5zy40BlgKr__@Vre?2j+`<~+%C1z|Rwt*4!Rb?8gV{7j zu56eZv9{6Qr|zAia+1@;1o!P(9PckqOVy0r^1@W^g)aG~zsBz^{M`?n_oYUy6})HC zBe!^e^;Yii{yJl-yTLp8uQ5H?yTQHuNQ^CagP(>yU3Y_HcW5CtEQegRxN?nKH)FFF zx+~rAZ;f$>79+dwNo5Q7q~_=EP07E#b&r9ei}N47S@B6`lSK}U zgrD||p)7GI=)T3bKRVd|>z-+|hcN%mp4@!tww=K4@Na=&{f{sZ%1d)mGGk>=eGU`aQf;q9x)6~&s!_D7sl^34zQ+75g( zKc{WkrOcL#j`ZCSm+yni3r8hzNx!SD<-b0b#6|iz@h$E*f=&k=HC41N!G8Y z{x8ewYo6-NKqKR7^OX3LLVq;BW2VLBY+cmGJwx-`TArd_JWo&C+~4KS!8DijJ0C+G z$LojjI#aRxAGL2|^HJM2rFCB!ciAwm+}X5^JMOn_oRHcz3|gA3KAn5tN5;DHo_f*m zV(wYIXj?Jv%FAZP@1SJ!f8&Em$aU3SX&eoM(RvyZ}q+S8>{yruqBnT^zqvFt7?!`=ayHEaENSBmG+ z{4d7zuz!1zJ&@#v^y%(d_9n=Dd=BwC@YCvS4}7_x$X|i&C)}&C&(q!+*u=-Vy;++7 z%%%VTt%xAD68Y)Zf4voPC+Ah9)2-qE!RT~tI^RMJv|sl>#kX|2_bRrs!dnrmeQf1L z*yYOKifDXwZ$-Qt`Db$A4D>^H*ZyT5K51<(t}>5o_!%-;JawSAB0lv|7Zb&LV0Tut ze(27rzme=^eK6U}T+Z_C;rac#+L2A>e)10Xtq9f)-ioNPc*@Vv_JQ7tu=4*jBHJ^q zt>sTBKTsD6W$EuX_VJD4rQFc5kLwnF_fU&{JQ;eF*4;Sv@!!f~9}lIB*7?kVV;>E! zVjqt#gDV?uh1f?cuh_>U%F4%U=Ed^{$ktaOuUNMeYyV`v zkc*m2!m*ea*jvKAspu!2OSTf(yd+P1S(Cr{f7l-ZTe_Ftc<;o2FFi^+l-Hjg&0*j6 z`qNG5EcN)DZisemL~blP;Y8D)9sy2i9H-9{y*J$Abd(9n^6ltb-!3a3)7!sW8@%IQ zssHWC^-Z+7bK}9iY5on$nN7ByHA-tEG{Mf7^e=WL{d|eDL)h0hIy)gg7uzf7EV1a9 zVQm#m^+h;^b~1nN3>ztJ#peubC5M|v7S9QWYqsitkMT+PJ?OXmNZxm-F|>9EdvDy) zPHQ^2#e2^$$M?CH_$7b|?yet+`$D`eR(a5F=$O#5u~FNqTVp7-FQ@6%O=uVKUtUk+68eehHTcy3UAX}N3P6Zr*FWgm7qy5AB{G$jf*bo3-(m@ zuCZ?bJfiBRzV8EDJ{ow{Y}`syxzw|tc(RW??Qb-Gv5#utJPqezr7#Fm6v>p5QBYgX*wo_wX31VH{xE-ji1pid16Y6d9>6P2u{X5xyd^tOB{kOBq(4H~t z>qWN<-!dG`=3a>wmC_D~GvoRDd&{Ua@1-}3cf}v6YV84->oE=E*l~C)oZtP;fsY;; z+D*)0Cws#J^OZeGuEF_zHD@ysJO?adS#sUjkI=jOmI5DNr{>BQ*&cKc|8DYnkk@m_ z6Hj(iw}WwR);O7b);a9p{C-ywf9dmrxf^{xj}MA>#O+-P!AamA)GOcL=b5{HkB^)i z7@N=@$Pe}e2b4*b+M@qGw4*s^ZGm$S{C7C*CGc#H_o5L#`l9@*0MBA7fGJq4Tgd3L z{-$M%9mV}URoNw)ql~e5UA)a(pX@=V@~+uY#5y0vddOK5*(|U>=q%J0_N)F*h0e5W z8Jt6DjGmuSyz82BlwqH}wlF(h3(WSYvsKs&ANIC`*^Ke5IKOumdr{y^&Y8UtI&OAy zvOu2Tu^-#p&F_u;-jo)6lOwD2J_kG&?**Bwq?@fy{GxiQuXfcI?>SB?rqjO1@u#Hs zQr`MVoh|g~wCd=2-%s(d&r=<}vFg87_H^PUPOEwBi@v;c2+3eahrM<_2b}F5SmuQ8 zQ$Pl;I^O%U(A6~`G+zW;>x^IsSJ{emc2GLHulKCKznpZdN1nB*deUKDV_Vi9Fp+si zGxi8)D^2Zd&WQH^2u~`_))<@P7n!X?wq#4gZeed>s0@1x*`7uJDreuex>v+=Qd9`9BMS8wB#GR@Coj0H?_mw33 zq57n$A6L45Se%BV$+6xZ5AGhZpHeH&yfK7ln)FZ8v*eU&rnrNsZjA zxh?(N_oKYdKT$`t-;8{0(D@lBuLPeq&sN?Q=cSO9r*nUed!IMZi}W6!Vh{9AZx3=& z>zdXN@wA^)elGg--OQzt^hf*UgYoT`?={>UvU_KYZ`42970$#C8qVr7a(BM&&M+S? zzeP)QJkt2hT+nY{KU0m)E`A~1el!2}Fm~uUu?}5fEhycA7d^i;?bhP4m$ zk&EsY-^V#?i&LQArccmkN4K2l(`b5q5YrLUG?AzA!$*K9ax-_Ozq88K6Rzl8eRom6&BeJ0N5y2Qyl@h&<1;|Pelg$yuk-Gu-M#1+R|4-U zbUAznxt07sEj4Q8Y3TjC@ux+^lMticLY&Fny^N9CV6L&(2yB%VU^Az3tXHKNB-)Z5 z!Q8RCbWDE&mdZ$HdT1(V@;>)Wt?5b)&i1N22n(9?E$LJG$;o>Ji^C*U>Bc z6!*BN6?+}GzhM&JKe=Q??5~%Pt3h(c z?Y~u5X-@X6)jMPwKk3JNq-SVsSl7_aa>Pf)vYz!)^2*lyndq$KxiQaWTugEY^`S%G z?gzN98N67NEN)h7u5<~VIlm_0JHK9D=42TA8{;AMOS+i){jY9q_x}30FVG&C{%oOs z`+ToUORv|uFMJ>NYeE@*@GtwYsr&Na#eL{^OJ-zJ(I~ZusX0A2+AF z{cjkz?G?tYU%Hc%7r*auW1%jN+hqqcZq4D|KK4;*zWF=(Y#qe!B|WCn{e048Z2yhC zlTElbyr+*iyn&0le zJmikeyL!&NAamgFmGAZU<(1M#Awyd9E);VqC!Xs)a_IZ=mT`XD)(&K6@4Zd)XV6#M z$1oS%yeQq9r?)GSCG16VifQ-xKXmh$`KbJH1@Jaol!|4y&F16mQ#OAh8PCzQ-Av5IMy3`4`Xsq%kKVrTDswn$m>OjXD!*W>GP$T*s7+`@86ohGoIhBS8kP(y#!&L+P;NOsO|D%}^Y?}hJLKeRmJ#_u)WdI^QXIUF?hPa^hDabb@29Tz^9S+6zg(2 zecMalmeM!X9|{+pJxTO+T=e`bXJ@dsH8+;h_CrIo4Q_+A{aW!7o&2Bn1I0Ph%p61? z0B0Ll?_bee*O=osGoH_+YKy*?B`(k8hw4FhU++qnC)r>y;Uk~7#^q@a`*OlbYjtry zCVXfYKTD4NqscGL6Pp*zl|B4Mzgem8!l#G!r?B5v{k|H;ub1&dw#?UFQ*)Ymr*G?X zmzOcX_xTR55}n>8y^nj^zoE9I0}7ut2c!2%k9?E#zOQ5N&>k|>`@Zx#^#{|5M?d<- zGW~D0`W@Ew}Gcy&wl56;2+vJo{CMRd>rM=cs+WcAD=g49LIsL zAIJ9`%s9Ro>l$)wz`BOM;MTR(I!hVKc2AEC>)HL@o~88xIO1VjE40=&E*-`1zGDMe z;?tUA(4|=Sk!1t&H8%#xASW9IS2DPfcA{hMol=yYe@HT_=FO8)pHhs<8!V%4*Zyyy zjEZ%hV2|p{y&4&HA^3XU#(4CGF<8tXD>|HY0XqO&$ zN6XT;cG{k#FzMbYjljiTnH$L-Pc(x-_cGvR`_!q?_!{91P1dAK=QTqZ8DK<|TR6O}<#PU- zfY(4B*~r@5UeNccQv2_sy!2W;F=VoG_t+Tx<5-#$`y9~<_KoU?D(8B1GV(0LPfcC9fBqWRsY zMDusg#TT>yo%s~evt}h@GQM|i)BHVr$2xf9%EI@{bnt`3^L+uHjFsuYrjy@V8oNsP zQU;wp<|X#($vc;sZ($sl;1#eL6y*20HOlg)#@!Z&LHd1X%4ZkE{Zy!%pdY&Vl`fu1 zd%S*VX=CX24Bi*CG4yl6v+O5w@Yp`=^g$mvXF+;I`fcE0{T^riw)g@2c6C)|HD%P6 z|1%nhZ@?ihTPOYbh$}NxpH%MYbA~w2FP=(I-?tI}h4~_x2Q&CP0lMk?gZ$T-+}_9U zZ0Y^#W|IpW+}=s~e}z3yIGX&pfVp7yD`d&r83*i-x_eUjnj6?58ONHH4?Dfd`}^b{ zT8q!)w3|oW1COn3d|%W2k<3x2cjX#MufZPMfP6BUQ(c0Y5lv{L08J8Sy91uIdBdF9 zjT}>(;t##;gneB2*uFvdW$L0;?Dx+Wz7h9@Mmr~DAL5Kx-Mi*zFCWkSp2MPbt(@K1 zeMUSs;xXxE$3m~Ab&pQDADE}rJvK%2q!;;+d1%pmw~rmU#QEFG;cf(OnzmYpP0T*- z;PwJnd)@}>TYn#_nxB}jK|D=IyJBXDPl5J&7v6qDd&SUXd?MACwo$RrA3+jk=y0>?GvwTtfVTYF8 zAe!8iOJ&+xuIGF|F$@;ZB72SeUmKe**~UGS+ZL+7{Av9>8aXR};WvH}pBLAhXyDK2 z#(ff(JGyO7U$kurPq*m7_QB(Pr`2tw*1ZV1E!rX5WU{xhuy7+ zpZRoIA2&8%3VxRwe(-e5Fo)Zn0dB%ie@5Txrum}p9_Ud{U(r=_!j&_=vwDtpxLWS^X041mOkQtj{8WTGG|p~d&#%?!g`*VFD_5>D_mJ^}3fCpBP5l6Ms#8|6Zond-2!9#Td)w`)WqhFZKqfX>R}yTI1yJ ze#pyD>Np*Hr}Xr49s3IQQJE+rw#l9E?7}zBJl1_$(j6qDOwWjQ{UQwcthR7(hh&W8 z5_^y9QsZu)64AH0^ef@VC;u<*(!N`CX?tQ7eG>hxKenb!+x955FVbzrtn8JPvG&nb z1XD7QyO-|Xt=Itk3Ejut*>daqzIL7Hz7=}e*g%VLpVS@bLpB~~9+z!#ZL6(YKYM3O zof{9q`71|vrC;{muU+>TIQxBv$9)m?eO;B&SgP*lsH;9HukM*UTIv`_$x5ox_~_CnRAuS{~PcXz(2j$H{oBZ*`hm4@Mqb(9>=DT1=WnP?r;9& zc-uGWev{#RfA8mqXMe>VqN=a^6W1Jx%xHBoqm{Y-7wJ_?X2f#e+9A!_xgu^yd|3}K z_okz4rFQ&XD%RHdld_M|md3D``g_3D&!@t&D7Vqgr@~z168S~Bgg&ym1ssJBcWf3E z(?NN`(fx?*TjG5Lb&ySV52SSB*NyK_CuQ#yZGbDfN_Jl6_#OYT?x7xl=NSQ>SGls^ zQCVPwZzl*|1nmSfe+IrEuOkWO@?_sn7EI=3FZ~bec>T@rD66xOI)ZC7Vtp^th;l}w zx#+QE$@x@H+gXB zW=`w|=9iu&o+=n?*`lOhD;_g!Q|n>X&71F0yLn{#FMzcN9d0jmHNP~j;5N$RsPfVA zo9{8$uJuiOJcp*m&mgZ|CdB~Gz|EGVF*(d|K zMjLz4kxZv-0bk@^R{QzlJJn%)1G<4fudSF^^mm&R`TEk?I>qhl?)ypPCHBJs9NE#? z?-tM6{P#x1lBBkD14nUo+P8N!N4wAoO+QeK&0w%>Z;hU!Gvxjph~cn|_(OPp7<=T9chLcz z-QFfBfQN8Ke*riC*D$7;2syy-(fmGy*v@7b6CKbw5eGhoxz8G{bz5=Z*dpu=(H)*H z;E#OzhVje@_>b>~RLn!tVKc}X{pqd@i~l7*lXm4<=b>3{iI3?`8$YhfJH9IDn?0Mp zrH5OL5Bh;`!*uPkHid`QrLbM4m125=c#{e=Rvft2`8?yTv8fXMpj!{J^plJ`ZEpS2 z)-?Bw`7^qKKHPQSc&p#Vo20TGLOa8M(AcW!F|8FlRWY_I&i~!KNm^kXGzQv}$(E*h zr8%WJm`drsO2A_77Hyx7$KaLm+GiPWQD5_WByD)z zCi8jp74mIf!)rzVMH1(2de4J7y^T9G^$tLexOTJ4b$DLpTd~GEn<5)t=GJJ{ZkMOM zoy`?&ak2?Yo~V6qpJyG)ogTH@KB7Q6@#t4)*h?g1mjgbe?_M7@c>w;RO=coIK_9A4 zLWXj-Dq(+hG&DI^*R(ns7n~JO_I01VT|yuI7?}-ZY+K7n#dA6vjoQ=O$GhqGS-6!#oVp*Lw%M_M17UbX7RtqHk(klhTf&VAcx?GT;}FOmNCCqi7zs%qvs#t zE&09h2Qp&aY1t#P$h)yiSKqJw^4cgh{U;VTx1+6P(NVXyJi+)BWx8Ocj#yQbipF8* z+nO0SGMia?)jZMlON_w={#5rNXus&N_7-Aq?p{%nd$~tR*IHY1=coboKTlomk+Ax= zrasv+WArCm9w@7SJLy)x?$81C|CGA7y85Zi=UXm6^z+&iB-*bb-Rl3vm;v=aO5Ihy z{`t4I)I}ZF?Y`tzY~&r+f!Ez_K|gB9ZzSDdT{U(9Ecw}th97ZoJ{rThr5q0VML3P) z2EaMf!|90OTz+2+hjVL5e8?}t=^Y4%`?z9!e&yiw#c(bvheLi5&g$_4@Zs%dvkj_m z8z$XmG}<`%Hlxv!GFY3*FT(1bH~^Mn&osAOM~_HGFUa_7hxTL*Z^3H zPp{%nGAF|xIXTZuejv^~MDOMA4*uZZLH`~fB>xZ^IAMr-gTed+b&#{KJ@zfAi{7O5 zJclkkvM9SN=O0_lMZlbCk`38$61nX8=I#iqtW~5m(ES0 zN0YXETRU-2lG*6ljF)?_lYI6yIdpf{Oyoa#qOasMWd`+msx2QksW#BHh@ouCT}>OX zEA>izUg_8XSGJE0Eywf*M1D~3j zA50C}M@?m%-lV?KZER1isL064>(~=#b9Gq=liL7 zj=z1yKH{{H4bqz%+&MMB=V=mOE6e)O6#aZZChI=!Dc2Q7l*KKy2l5KM)RyiGX>+zToqx15PNWknKR+{? zHc3;P@j1v~ZiVfsZ0e|i?FD0|m`vS6!5n)cHKFZ^%a;(FsoI-EPFIK`Y}0+-Ti8y|i9*u=oCCw?_uUS1q47`K9$bb1D3K zp-X|iSYu6TZ7a$R^4Ocg@5F9szefB8ZN__XpH~;>$)6|q;zMv5|1sLom{|Q=iScmt zAMx=mXz<(EWL1q4$wqCjELTp19 za9`wbJA>`-e7S_N@b?@Ikn_l7*=Hm>`;l=5pS4DEeh2z`^pV;uI;D?MT)ENvebRAU zm-b-Jx3e{~s@7t#{^h^%n=s}X(FGZ&IIQqn{+~x&{FR^o+QY~eWaUKbxL(oUrEjBs z@qI$z7t39>Z~MRhPu!+x=jv)N>gB8Y<^OEoD7j02|4}wM%Gr5-=8*ko{2G`?R$qId z^|5S7u4_sCNU~e9)ayHu?o{&kNxAu-r%X}53g&>H?{>a{^*O_P5b)30!WUgv`$@Yu zMmnzM%WUxg<={gr+vNQMvgP1g-w}RuM^+QIbLq|=7BM#K7UgSs$E&U7A015HXOYNn zIN9>Y+1o|a_sM>d$UmXZYN7*4Vs8NS2tq3k;>+s%K;h(-8IdidSic6j#4#k$ie zDGL&Qo%GaQj92ka1@r5yMHYTKqW`HJyqjzIF1k^_HEEM0|SlEwz+>d?0@m>DY(3SG?oAx}J&K`Be{`K(tN!ADDQP%Rh z(%Hkv%X|CTi}3pkw9DFGq&sPf@qXCr!^-Eo)qR^RRlW2=`~)>ydQYE}t*supHg#$= z{xbY)1O{uGul;;C)0Wn4XS;bqwkx9v^P@oDRp%?fv9!+# zAI{mgqaOx5MSFW!xN*7pJz7`Uqok*1L%VvCCl49GlO5@C=&@t>ZA_2d*E6On*WV9s zzQEse{Oxt)w0EJ|`SY_f+5esa?XD2dL@Q_bn5y)d`+6zkeFmAU;L%^Favkkw?(6>b z!kG8kM`S@&!))yHlt&_=QR z1nvw_8s%ahD&cD1;QjQ33R<*ES3i@Ou_!yO9$Z^vdR%^JTwi&;{~FK({X9e2Uh4h;JxKaE?UB~By6~i< z)02))b4Fy33+QwqbUIjgg`TKy3A8F~N4DtybHnHNf79XpP5QJQTG7wMxE%zZz0@_i z^FS(Bct9{>*<$0%_wEOVXWt9XZGP_3F1Ch=g|E}*b8dXO3!{;Bsu#Z6%zEL+`fSG9 zcwB909Rpv*!xf%;kIq`oRi5O1LAa~_3o*RScX0=##{b8(;nI5lbwrVe-YFjP;|LGc z5LeWI{wEj>(l4oF?ZNBTK4W9wjPs{y-_odWY4FO&gcEhVeA?bVZr_K&E8jXS%YDS$ z37+0nb$DCL&+3ss$eR0TKaadGtYz-b;{TXM+`GiSzdz>3nI=1sF`Lra{0-#a#GLO* zXGgCKYNK&C^RDVozAL z;3xefns)Vf%^DzMxsRUpnRS0ZbaHaFANknd!(SkW6f@BALbR)AHgs5?l(DS$eZBDG zX(Ng;pf^e`<@=lZx|zeazAqb*o%+Et84F)aHfyck3~WE|K2}8=md;zMbJDwtGFEfO zm!D7-&oRDj9{BYjm=`8v$rs*U#%`kCsybvWvdzZe$rz?&&&IJ%#wraN+eulIu|I|u zkGb-XA!G4ftIv|L_lX|nr;b)uIT>s8VD1;`;bkm!6+@UI*0%6{N1yLI`lLr>|M>$Y z`dlEnBDxL%r|=7SQ?eAfWdDDRO#QmU^Xv3Ma!YH6x6K>?UN3b_mfnvny| z9w~TE-uALS8%)7Daa_EncF|Ut{(Nl_enIzI__2d;2FO+FS-bGJjlIT0crdn~@p6^= zmIi;U7H-t>awTN3J3xiB;&!ccru6gdeR8IA71Z-6m(!$W_TlWb3!d&m&*EC0oG< z`%*UgO>OougNICNM`lV!B44+wEHbuR^3|6;VO;i-B3#NM6T6YIf332}*>1^L#?RoM zS(E*{B3xwb9P*H}n<=|{v6Hdrn${2c+>89>uJXQ~n~<@$AY)e|W3NTVUWANYj*LAW z8G8mY_7v(Y7+S`@SS$L(GQ22brw^O|W!A02^gzZ!|8w3N$XLF=Algq4WGugJjHlBs zp#657zRE zdh4i6c8U63rneTrQL^p_rMP<2Tl1q9+PIobMQ?qiwInl&dh3gB-T>Rn)VdUHSUP%Z z4`%>Ez15e0VMIK~__jF!-bOF*uy16n$yD<5!1gk=hk8fRhj6{<6%1t0A}>=VyQQ~M zb}+qFeU?l;`>o*W^wy33jU>^7wWLT7FH@hQ9WPUvvqm50u+eAEh-_OxpK~Q!4gg1b zs>#v==&8GlvCBi_HJE;Ccs>y8r}u$lQKmk30R41Ss<=*m1)GA6&o|xpuns&Wne|*r zo>tUPdj{&Ko7a}s-!A~SsGq_s1LWunu043#+SeFJjy{#j-Rb3MunvDhI8mo4M<=BE zLjAP+AK;}aZ7pxBi}ll&X+NQ#j#w1yr|^{c?iTT~Upuv=xox$egU_0y}# z5B1Xy`uuT&h0F=`(+{hhcy~ar(M5PA{q$UwlkD{RDP!};MR+Cs^g_zL+4^bc zbkT%<%ued3=d(7I>!-ty4`gTSu%f=Wj#n^c#Kb*oM~SH(qg_?(HeRw>UUQi%rhrHO8>sjB@i7`>ElD zf6SjNnBmTc$cI@7e0UZwiY*U4;Urgwek|X&2Y=mZoF%Az_pxj3n|gKFjr={K_I4Td ztPZxnN4yQ6dhq=!wV^m)?=zL$yUf`>-iFMPtrdS2Wzqdo=ze3O)s{wm?K`7)H}bBh z-Mg7f>5dV~%8zWiTi-2DUJE^aeodUex*^5;^P`&j8oZ61--$Lx#rcBc+faFZS8C&2 z+VJ_-#;7K1Lw$C%isv}={t|sn*l4=~zbj)TKbUNo!rA&e9bBfg<{DxB1nMDcz}PW!FU6ZtB!M5@jErfqhbU@n=%m#}>vu7TL_-OWkB&OK*E^A|C!e z@cdHy)O~-Q<_(E-=}joz>!;Y`4ei{4+kEl1qrqo4=UDz8cpc8)ykWoImEbL_7o%OQ zCp#DY`Qh30p~%6DlkZ9>Mnq@QMoY(m_jT?^_CjQ!-3{BJ_ssuuZgxW}?^A4wcKy=I zHO2P_V*ev9;_k@5F@sKH^%>g7lM-EW0a1iz66Og?6Pn8{k+!vph%d7UlpGg_z z*NMi&t$pC5FRcgHT!A!ZeRd_^_8b2VwU>BRi_%is9QWHtx^N%@Xf- z_g5NNJHbbHuT|`S8D7*kSlD>s?}0v4;a&8hl+{(-10Xhp2ok3@5An?jd(+%mNz7LOTc3Ng--%jbL@9c^x^fS zf!l%NRFFq!o1BFAkaKYyHF)W_(nSyNvr-(O?n3Q8GRkpg2>&T_()pX&Z`r%qsv|$< z-Xl5lKz_r`_urFwWyO=6!#*-2Um1S%rPvCiz!xUCKK7>)4X-?Qzs`Rd4KuvQz#8KC z_W~ku|yb-_9PxHa6y!I=SNi+EWPRdB8$e-L$ZRh>^mZTzh!Tql0_c8AG zTda#mMiff~+t$~kB&em^k zYgu(+ay?ioT8d`Pmu{0k@8`UkZ1DumO{;6!Gb-&Vy`xMS$yUAN#CaaGi>2Y4Ox)&N zjW;%xZ2uL>Hrr|Q?6NkGqpZOL{;}k>rEAS+rZrLhI3?^yD==G=FnfTxpbRFmJBA64 z3#l(2D%7Lv-8^=gct!pA68$hd7q~T+dqG0_v~J<-XBk|TFRhn@ypIyh$Lb36QD>yf z=i{h@n2#4WzW(|6W7l@&`KWl5NyMWZ0e=yX(wf>;s7DsfjQXOf%xmU&YAS2~EWRf< z^>qoBXGn+IPyh}suStD<{9~0%a1FLPg z^Ocg{OTP4@2J#Es&)HDN{j7DI!N$hChka4QRNm&Kj^N-=*wO*6H7W2zChZK;^Vp?o z7N+*47B1ZPH>3+LYsD7fu;oc$p*te8a-FSJyQJ%l!|##D_uJV+-;u>f@on$?q0jXI z3teDmv~OEQjn56&M%$x|6TYIY{>(>0dl~Y?Z#D3n(pEtetxFl+r{3Y$Gv-i+ zb1M-xWa**mmvGELXZeK-t?Y*--)Yxyco{tuTYjg|!)|qYAdh?0DUt4a5R#@2RrF6N*U>i-F&Yj zKc;b@JGGZ|BGJ$GIS%f_=zW_1(g!|*{+HY{RMubU|M<>1)8?7}0!_5;|EF|EzrOI^ z<95CE$QzNd962)EdJcCOFiwm|F-CS4{T0rtzw!EL7w1-m-$U!1bLl+cygz8SyB+>%XCEE3yNPz|%i0~Sc5iWd#4XA4U6h|xR$lZxkRBmk z(cahdi^fZ1sJ?s}`-Y8SSsy&ziEo4MgO8WS*I@Dg9ioTez!TpxJ4~=oDVsC?&T+MK zrS5=7XRO8XxZEZbsc=p|= z#xhNE1s%Ar5gtv*v$DD~eBB+xvw!63TD#Qq?P8A`62>AA}GncJe=Z}4Zl$d90(U~4bMUasXH-rW`7 z8f@i_i28Kiy@B7{-Nl_{k;&Xa`#6NmSQN+%eA7vp5z+=+{kiZSl?t|qH_;>UD=FH7J<)}bG5gOjul?4|2gq=Z7}DwzdwhV$WZ3% z+=9j{qx~m;L!OnWFy58s*?QVw{uX7~>z!u}z&qG^_7Lw~ysmi`=o_~0b?b)q>-esV zx?P0s@_y(YrQ-dz^bXEaSU&rLy*mFP+L|0DPh*ih6LN6t%Y7d%tuOJq6s#|0G9g@- zKDFuP;<_Yxn$#nl?Ff6X>Yx{5qpMk4)b*O*n0(P>08G|8wJG^n%nN81~^Ga6WmLIdAYNP z3~Iv;>oG^Y-Vw2mKYUJX`;m=G{r?W%nv?Qdbks+?KJ}^n>j&8R(!sk}$XI`7ZWI0- z?XwE(z1Wv+jo6oc7u>}AdfVz-oGn}7{3&|hvqyN-kB;_B_7MnfeiW6{Th_KegC4t^ zxz|HDBgYM9W?uGZl(oI@UF6MVAEvg3&C7mEFx(zKQzk!(@&CYAyFbSlH?)ii-ePJm z>Bc749PN>u(jEcj|5tbnfq zS;zSF`8ztaZknDgypXwnBAbG@6P}K~dpdToGt5r7Zc#KNyJ=!u%N2}sD07ctjCPCv zG!Kv?@&kQ5hGTma;-0eoi<5A=fOAe6oC&}Y4B?SNKJ8w{T`I)Yr@1@3o3RwliK9y3 zlRm7irMV1FQlAdi_vX@mLt`O&N`H_(l^yH(3A+HlwWj+0el2zlwVxl+c51Ec8l&1y z{S0LWeG{3n(!3O(X&wmnfO*hfjeTt*_O-({ztUXIop;!ruw_}B>8dTV{nwnx9_{$3 zFLNTatw;Co!48F8Y9%~wd^>TT>^@uTj+mFdk2dgK#QPX*RvUoVkfKg&YS*X8(;0|D zJ@yyu85jBbvE68^>_$6n-XN2(ZFQ$9*Btc~HdSRGP&#nC>lxeQoBF<>zIguV$41j1 z*l4~xCfm%tuD>`tm*`Sl zW72_r2_7CwSG|HWFl~YUasXX*o!g78lYOZw-V3eMUTpXL1L~@Yx-)!T_F_-Ex|&y+ zYIuRMl@8%_&XRqKdxyjJ7kL=$#UA!BsQX%V)i-M|c4!%mU$2gMZ~ejRi1Yehr;b>O zzq*okD!=ZGfj6~2>MnNHOVf!>?qe53e&5|ey3GO3(?{svL)jg~&%`p{&3<#BZc{c_ zR2G`vEq`=m`?jPWr1_MX9~J7eX5Fpv=fC-KWBgt{9PDU!AJiOmbdA@=vUi`#@eSs) z#hIEv%hJ> z@uAKg>E+x-v>iW{?p_n#aax&geqDKd!|bPC3VrjdSua^rurWrjsb`c!J8Qd-ci>@B`+wRbk~Ww$fEfcTX6s6G0!jQ@$T z2>8tFKZ-B#wiD?>nj?Aj10Lj_NQ+03PA}TvlW_Ad)T=7c=pfn=jeI+@$H<21+gZYQ zB|H9s=D6TBfb*veHuh_NC&shA!WvAwuQnzp)aAFLpW0XtrOSu(2-a)Scq=#(8-kCY z`(YT%TlvP;#+_nj^H{0(NMczP(0mAZe@A_jhrp7Yvi*+djYH;H?9u^g8^UK^dOKUl zC-25o(G5T?N+zMyXagoUx5F=khdILBlI?#wD?~ASx8!<4}*;Bb<`hf z{KZe|Lp(p3ugF-fNe5F$viJzYHD1RKrcNE@W4>?d!*`Qxr_!8vX`0L8Imyf`oqv#d z8rxq<%McUWfNzbMP5mC%Fq+>fr}K8|b`Z0vJ7csbH(MY38Tn^^$R1YmE8oRFi@lHb0&C~8 z7hryLv!B_`{sn!b=u7T=Vd}ij7cQAsa5id#C7Fo)(mpYT?$J7jSW0-v%M`_@Dwgt_ zv?Uw7${yu(C&7y6*b@B5Rk6Mv&VgXg3Vyl2Dc8kq+=TlbnIRa1G@jA>DX^Cqw(w2vA9YoR{2*bpFEW(bAikFHfw3KQ)(XwT~rDzSrR@ zN1KuZ8MpsddFkTf^%?v>hyI{17JV|YpPluv#`)x{`F)K0JxGjRi)&kbJ)q5^9(x2f zi{16~gY&xBZ2D4%F<)o$jSu=gg5`a-K}^uY+?lcHpJryeh(Z3RGn2N0f27^+`X<@y z)GL)KIf=;H7VLd)^&EJcBxG(tMAsTU8nPH zeIaiH-)HjOG$P)&bdYwwE6-ZHdUNaHH{v^2?9GX7&d<=XvTD~Fa1>0-;|}tT&Tl3; z&`JA(U(DB;oVnN)srPZ!o2xZETFDrnZTthAhQpkUrZ0vYWhL`IO!=Y>2YJUmExD_F z+mh?F-Rs~8{^c$&f)0XXu;|nA^y$0UC_Cp|JkQQwVCTHj**yfmVKV0vz~O4}*Ii%i z!|i?90_6lFKa;sXle>|W&$|Pe>U*cikM{EqIywlKh1>z+?=9EZFy5XQbr;6pPT#+N z!?jhrwl9lgiTs$?V>3AqyxD^}|ID;`=z7-XTS?E?N6A>IdfFluY6Wkq%%Plk!_hjn zAJtcx{YdLY|JzwFz}?%9_66(3hUyBVJqPVO9J+|fG49r-ou;W%z+o#Kuzh9<(Z08KK;mke{SLflcJ zzKc6r*Gk;cd&}xe2U{~T-am=%f~mBv^9IHpokKs=w${sHT+ts;+z~oWY!|N%Y$6@6qsx4NZ0bGR24O{MpqggrC?zYH&xnSX#X z>YvI9_chr3qjK9!1(=Ug?uYyxsBNu}-=W+xVhHoV|A+EA$huc<8qR%boXOGIMC|6G zi{6j%`xMg)wcfU)SE6%j4*%Cl@!1G3Cn9v@<{(aS!|A*=*h75LVmCL>J}%oz3}oXO z_(!dO@8KS@l(XrU+40-4EPrMt`rB9iIMIQU8LN26I(*!x^j*PZr}%jRx(+dHx8PAq_s~Xpo`) zBdIt(a>Fuw99o0BlJz%H|2t*%Z&7`x(=K42G!h-+SmFq!OB@T{3y2-mT`BqVSYOgr z*^|KEek1!&=C^Rolitnu0={?D#5#o17W1usikA6{xTEds0WC*Gxf^5p7%kiUy%3Z) zdZTMZejW8`8UuXUf_0VZ;?LGNJnD4_%BkNCF5XdRRd~~{Z%K7LHcRN2-s<44we0Dn zJ(C`_{y+t#LfO_5cN73sxiL zegGWZSEP61gr8tFR7a~9fTzmVLQC|`cn=DlJ>4?U2s?-I1M5TSJSea=|DIE9vhDGK zSs$4WN!^`w`9rcVY5wE4>PFWTyzcGJ7r32xvpAO6_(u9tbvN8+si+Xn#V5wRC{pvO<|P*f<81>niO>wPt!dKKd{75dCdV zw5u0ALH-=+Uf%(R*%6yrMQTDDbIB2c)J_5-`&3VOZH}YTmjZP=a zl*hb3;MqNY#?I?5?cmeN-(Wg~VEVFOMfRYlnElY!|F;eP9&T9gUdeT6F@Sc>K^y^V zeMmpU=iz-Rw~GS8-Q~*nwco!uF@oKea#E$`ABYu`bxYw`kWZ8&gkz zKepaS!yeM~sf1r3?32bl;0gJHj3-**3G1)UPfWLWm}SH46>Y(#(z%GE4fo(|R3LM` zpKC1rY_vAe;p*Wp+LsR1(H!lPzd?4o0dMgHef8r!9XL9tEBng9#51XngVE?N!GZRJ z(Wt|0oR`{pf!}g(v)1E+zuysBJWHDK9KWR__wrp#1Fq&-d}eR@zOm9RD3_;B1b9o{~~_th`;uYZYkG(Td;sU7Ki-=T6P`UG?i=;Qlod;o352kiMQ&LYvj zppIyY49f|xN5MfpA$W639vn0_qA&6wC*H^dPcc73!4jNr2K_rw9pUWWL@^pKqu+WD zgcwA_`wYGl?X^3ZLp+n#MaeFm*=Uq5g1qs%ljcl@G@a`Z?Ie?Qmc(=x;^rE3K1JWM zaim6$k{w-e^aff(O6xAM&8et#uDChggZq7u=1D}nP!zSDTAY_2H|Qomp={ccd%j#e zkEt_^I_*)suL#D%k6-9xG+j&W5Ia^&Oj1PbnB=qWBG-B{fOjjv3;Dt7P(MM_3U&Ox zO5<1bX^N)25tXRhT){R`0bVGZPbgO7sh4r+C7T zg~nWRwkU7lv$yaa%45+)v17Jw69*ZuX@mIZH22c+-Pyhk$(Xl^_Rv%O`vP-Wdw%a* zksmDKk8}7BwMKclz2ZgoQ~V7nx5K`Jn~!%AE|N_Ki}CxR@PZ$Om-Y1x^mqOieZcqs zfwKM&NzXETdB@(?2Ez|uy<%EC{(ot3|D=^h{YW3eQv zr!qQ6n9-gdSnr|yv#j6T6&S}9E>Ggo%3kerWq1fq#q(hSjl%Q)S7M_oKR?HURI)n- z=jX6J?_3nU)6UPWDrT{`w3Uq+O00NtMv?iEyh;T{#Mui zR{5P5#W1$YF0j(WK%TmKulk&ubnmuTbIz@7d?bs$x|BJ1 z-*R^Eoao0K&PhI=jK2UmCLiO-?pf$tvxu{w%^h8m51$yGt^asi%QKIJvO2J71a0{> zUF+n@jHP%|dI{s1Jse-ckZXJ>&yexm=qn~?&|RdTHTX9S;8A3(?Gd?;DA$c{E_=(n zfv>gSWD&eyaI%Q^0{do@Cpn>giuRQY_^!Bb3UOeq(fJfxYXV&Iz)RCNe6~61ACdKw zHJg0`^eg&@S$pi=ocGeM>iqW->R>xD{fXa(=Y+VyE12Zk?}-z4r&I3x8OsGC2n(~-W}2y#cvD+d)W$ef3S0zUpXQ<{|_LK6Y{Xi%R}Vx%(os;9w+L~ z@O6>LN4UDLM;?#xFc|aKDvzZXzbbiLfzFj=?6NW%zg`*p^rVBAu{S^adSz@$uY6rP z(>F$%&U7?(jKquMvWsyW)8+yhEiSi#sn!n%?9MCQoXsyAI)HYTrk zPCs|}!O!V6&%Dk#U8aA?ZfQ0E)+yO5&1Q%`FqDn5Xk&9alJpm^CmpOk4WGa1R|l-i z7PR1ueM&Yo)>?aGeY)OOKY%T;NBd!~&%p;h=vuLFA<)gxb)=K+fIo^lWk4_A z@6Z<5fi5V%O4#$#X>1RpHowwEj1zZy$^V#PkE8n?I@&qAo1VIFWBXD2Hl>eZe|`yn zNAhooUiZ%QQyM&+zZ9sT^h4tE|=AOp;B7*@_{$NNIb~K`nMp zY3QYv-#d%@0jQUuU*4X#+1vBT6Fkm8@9pOIMt*Nf3x4VBPiWgC-DHv4RlNdr)UMk4 z6?^q!I_-NLe@Z%j6z&<0ao<9pPOFZd_x%Juv?=wgGmRb@lsz5Y{j{3LzUa%#rXfAc z(P6K}uz<79I?I;f??ooI&uC#W)Y$o?9}BklM=(sTs~+h(*X!#&>ueULPpckz)~4#o zrt%uwvi4}p?{)J&K9MxdH_`qdk#Q=g{>cU@I{ZKO-agK*s=EI_cW#ED3eSrga?rUaArd0`y z+Tc?O`bDi;CKJ><6KX+fI|GFL-k){$K6jrpcOF9Up?&p_`?~j@v-jF-uf6u#YpuQZ z+W2TJr?ov}Z(q5#tjuim9nPSN{#7myefIe##}C4}oANuQCvzWp_xb3X=QDrE)p?!6 zLwCRF8McGv)KctVFLeaJ$Cc^k*-oAb*H1cJjSqNkwAGr86moxRQU#p7+|i3t_nq7^xB9M*`lr6;Y99ZjaM8To$@v;zrw>?~@0!~lW~DkmpiVqi z}7sboFa zx37=i(ehPWS^cKHKE|$6?pVJTXrIZ}qg?d-V&ZNMmf;aS|G3A4zH0AGxYaqCq%}nQ z1+rHd=kK+!og?>> z`88(YZ>_?wq4h!j4V~55=JGon$~`7ajPK%nu^QWP)%2wr*}*xQ+lgO}>e}zU*p(4} z!as#$##U1PIE}mfQEd+&H6Om8)VBGk`QA^hoN@)^(iX>i!i#b4#P?`9|MXk!Xx#-L z_8ie+@F%owUNT?(Sj_za$ktO-MsDlo5Nc%*`#s1Y% z?-R|X{1E#@hKKfvsxx?`=Um`Fb9|7Ra{;}F;>$t%B3*-dP-}(pAv8C8i7_6vy+mEx zU#70s4DnU;KOvq${7Zjc)tt<%D}J9_Ys(7lb)3O|VV*pt(5&f@ee$DhaC<)+f-{Gf z*W=mR5&bBsy3W_RVL86epSijv$;@hWf>?(cl-FaM%j@wd-@)F~2JJn4$HSnm_&_?4 zhqKwON4Ad|y#HP0SUfyK9zBVc-_v=H|a~Y$Wmmb#YM(>76ZRQ zARi=;B|DVcLHo$5wW>ln@#Y&S_hmjBH+-V$I)NPVYlGm|Sh)a)hS+y8l-%-oX`aP( z!*yYFbx;1yDAwL^PO?V&n3zg&H)pYy4-t2>HF}kCH`3QcQ~8M|<4X?XZltfIVniIx z&>_*8gMGxX57_%&t_WrrKeOlGQ}Hufqu)~e%r3P9ZzxVj;~TFvfu1-FzCrxV)+iG{ z^Ie1c8pqEd*Am}Z1%6*bo2fYw^0(FkjU9cR%UEf?5wl`=E5D+i*&M(I)SMj7N15nF zz&a@d>sbD8hL?whmBHQPHE5l8Jd~PunLg>=(d>8oc-4xy??-z+pG%BeoX=$&d0y~| zCNWSY&JkyGy1eq?J+e2w4!;T=ewA=djn4@E^RiNUjn?rPhd?fcw7~Y%-m~Ugj`_ye za?bG-i@}^qj@Xp_;o9|d4|yu_2Md<1fvbJIyxG{_adxABC!GzsXZi99w5$Kp|HNm* z`i-5BTK$r*S^0b=J0)MVhMVoPX7TQBo~Loo?dYCEUuWa5z#q2dxaKFfe0TG&&;HuC ze*NC)`Cseqgwh;f$~Prn&untw$Y#UGS(t!N1HXg!y*Z!fw@T1XW!c;RDE64;JXasA zK7I`O7G`?iFXd`x5n}~>>o0UN`xCksu3G#pZ%_69)%qtF|JB!ieeFr#{&nv$&-}V@ zbIrYa=gZc7b@8_>HrQxf6XU?|cKXv!e-_i9Yw3^G1HYf)E76+&hlrQQNxtU2;u~o0 zX!*SOp)fUi{;YA)MY|bS)`<;gUvOBFxpDB~RS)8esNt@?8BfXoT9}I8i18K=7aoNs zz%tl+H#vCMnt3-dc(*3=ZbIdd>E;N8N^yXxTGtjs(4x;&n__?;iu-zE=;7Sc;? z?upmLxBRcjYrOMiBX~{ncyB{|RutPc`V^nleBR0DEI!Ba!4DJRk3+6iah5f*JSvLU z@$zRT^D{jcW8G$u90_1}y$buRlW|S%0ac6zJaDMVYsOpeBm<6reeUj-RQ$!h$-AH6 zBlsD21ysT_wT?I$IOv&TRESAg=W^TZMNW;CEZ|wq#BG-s#;ks_@MxXIZEHNxTRMlA zpTuj@zdCo`XmcPxH8+syCOa$2&7p8)UJSyUXHoXfrfj+9@|qQ{;qkgMg3cO@sb7~u zoBO$g%IEma56D~>Z{i0u`RV!uc4UCx=K-$Kq8o-MzBYVm!?#`d4&Kk~z5 zrDX3=br<=%&rU5~AU$Em=_NReZGKkG+9O4H5cRi#7?f${h;tqyR#idk7!}8xLA6DaKyJ)pj~49jYg$8 z=~(|2F3+&))vVz>FSx3{>>uzpdubuRJzVKx26L+Q<4eNF=za3Egx)=;IC|ePt$47f zx5Eqn5$ERX2hKk5rT82*Z8h@j+uCChzUmi!3VrXwhrOMO{i%2T&f>6kzQf^}X~lm( zCLVL)ni`)BuZrIb_|$W>e~#%h0l$Viy7L{HZNwO{ZY1}ZpywXy{ovY@G#zRB{9>2# z`U2l<0Qxzbyy$jLfpw?k?=;jJ#F*yrcmFYW#a~F;SC;dKq75BfansHJs z`BLKk1a?HgLz0Q2r{+Aq3f(DddxE#TPC4Y+2c-|@6Bi#cf8m%=NOlt8li{I1t90annp@JP6;FQd1rMKS^oV2*ExO$C@2y7^ z&v5)}vV*Z&oMUVxvnDW)nAh4Pl#Zi)6zx%z+*r4O*CW`!^1+;O%gY;&fj9MD`tG&B zlzi5BQr`5@u>47sCtl}J@qy;WEZQ_a;ahu|ioMV~)t?Jax<{9N3ic|;t)B%>wcsY1 zqp~_5YP?U|YUA77Q6b)yZ*S09$ADJyYkS*WyxivSjQ8_r^rOog3|nWQsrDon(67Nf z8qARpK6LSW0E*og9Le1i_|3dATRp;0+szq8$EO3&aOYvl2hmm5Wekrz;|pEhtv<*0 zuh~eK^8YK^*J56(PZe#*5SGe;kKad_$v&QNOU(~xsWvOE)2U|_`mB9e@7vKhNbeF) ziZ_oo++Ur)Lb4<5xAr0pN5)3J7mbbNzxI_=bR2D8Tshh>Iw$LA^M2?Z4(3c`ZvwBO zyw@VRrSqA}^|uS#u9kA-0yFuGotNAT-h=%izSc9Hf3e>>CqsGePD}DYC@#hB0p}fY zH0682sW<3eaOxQx_DE!0zp|{~rG0 zI&5Ly3w{mqDTM!<4}Sjw;Pbvy`}o8IHz+;}Yu$E#}$ zIp!ylV}25L#hBuQ%X2$+W4nJIzWW?J{Sa+z!LDv6rlO5_jpb9Lfp;Dm4ZLe&H1O`p zUi4&SeOwv?j)ZzV`8V>Jh$zMhcj_%02w10EMr5$T& zU-xeRxTn02*7{P8JGT$#&h6X|Vt1Zf^cC*wnoPdB)5CqVqvoG0*#(?8?!t!(K7tud zK-SDzeR@>G_iVm7>#BPNTblpnG~F}U(){Dox~Hr@z2_X_-_GaW?1uV*pPyMj@QYLH z2Yz`5cO#s{KJqEhavtMz0(8$uMfTzb=Fy+I^skowUBw)X{9WC%wU%Gnub7;sXXJn9 z9_bUJ&OhgOH+(Mq#Ou;WzD-UL#p^tCLVV|i;#`zpGDq2+t%qm#HIuDCae4B+vW>WB8H!+ke$;UOKdsjRuZ^H;;ukUk`82fj5t1?B+3cTj0rB#?td-EBvTC8#PXU^9$oaTgO{>!-LD= z!CyKae0fGO&z+=SIxWqE3!$sVQDfJZKfI$Yf2rMldt@W$8F>C7mFKR`H7<{jk8Ltu zo#=Q}JPVH+&-%MC;Zft&L*P|-bk~{i&8hGzJo*cG^q27Hv-99pc(e~5EX}FRt25wL z;l{a-ajj#?Y4^gERG(&#UEO#~rcbOfhwAS5y?fa^4Eoo@G8f$armGyxQG(t<6OP&5XzW%}4fsCVy1_XNd`YAb({4gT#YwAvUxfS)v%w z7UamzQ;-|^%lmgS?%nkNgY>P%-z{-3`SI?}E$F^4S2UT?KfBm`An`RRd}qvmAAK`< z3a`xMjLJ^nh-XD3#r?cLh8geYZv^JXG|bJwJShY75@2$#u&ptY!=>frJOYo6jn}iC zJZsq;?RWtA@>i1ksk3(}_uvQz-hGbeW^aIx{Bu1^DZeY)Ve$l@47kPTv+=+5&c?=+ z&N7GjGtZTso!fCBWfVh&%-W*4XZuRfde<)epvdtOa`%2@`qr?IPczO>b9O7B+vW+x z|DPK2`HcDG?H~tXjMEs}vEQ_LFu!fBp%1p!KnLQqrl^k*XOBeRO^p3y%6UHA`4i&G zev)o;Ho2I7mT5EQt)=rL#%0e<=W#EFi@R&Cpr_Dp?GJ^qA8(+|v>!jvN6?GyE}@2_ zbbsog^RHi|uIH`R;QXuc*2}eamg5Twun!dXtb1N;U+N%aZhlGsQ~p2q_UOK-AM#&g z_6yA`=2H)HUH3UZ!(9J4e7=bHp10dxm` z{TOiMXH?m>=tJ>1UFrBg$TQtlUVF(shmB=+4t`nYRX!dw;CJr2WQ6^_QNlUB5X+{~ z*j!%E_hazsJNH-~mbHRGpZ}WwDf=tHAzSxm=7Ms#unA#xSJ`|Hd?j7tzc` zT;k9~|$NutbVITOl^C;sL(XJUX9537dK}7YiH{$te&|Kkr_tRJRMNS&S#_4bPr8ft2~OCw|M4X1qjbh@ z;EjRy-98?lzObe}IZZkuyoJBfa)&72|2UOn%`+Wphhzuj+6+tN)2`BJ;2 zmyN@BR8`bEyqWdb+jTAIUai=6pT(wYMF*1&*TQ+7U&XdaY;%vt=H7M0{Fbq1b3d_Y z`UyqlL;vCYv@P;Z+9r1b{+=uQH|3XhXkC=;)*IM0tp@??`)OEt@}+-0155jXk2D`) zJ~Pglb&!W#u?{QQGc`YCE6-%NE!Y#^xr2?uhT{qC;?w}+X1OARqje85{mo_zA(QzB? z$ro?79P-0#Iq4(2%C_7b@qv#$cXnKgcJy~$roTGh)e3yI^HJI`9TVK>*F?@>cF1;< zeI}a9MhoFJa0lm~XW*r6iL>!3xw}vrD$L{2J`2|#cuo5Ym2%Rb4nHq*bA$a)I~Rj3 z_h#YrHa@109BX^5#$PSuCQ(j$zxF66{brsiC;i_a8SH6OM=~RulRjHtIq9uFIq4tB z)Q`wLw~HLH!a?)008Bj_&%GSmg84iPI&U5OKQ|}+H<^ARlpTo&8sAGda}&zrH&SsTnghYqsO^Vr2FfgAp=PTA+Z ziUU9<_RL|ANH#Qb)@(NH_g&cL&tRKB3_Qs&`90fi#Ads3_`9E;AxDXL!fbMA?QQa2 z;CP$-(@wV$tjK&)mG5oVd}rU$d?!Dm%$Tn@P~pKIVyEu%xaCK& z-fH_dz-(#$*VDR*-;q7Ci+OWz+(x`db_Q*5#xQInkDc(|OdF;jo$Bn0Q`6;VQ+`RN zd|E$xD|mkr#yJlf%X z3z`G5t{CT*#s0Q4+nUFTZa>@dB5>y*x-+zspWuff|K0-s-lDxoH%AJm6`NOb2kFV_ zIYP|suxGYgz-xW$axXY0p!DQ`sDTS z&+5_ZlN)pn7@OJVfLqJ$9B|*%5!dom-J@eYz|H~x#MKqQkFaNug0aZMV9(%N9>#vG z<-aX`@~{kz_g9~MAV2!`x&FudsZVy5_ZPJu$`-XaN3Aie0UskLHS3M-UB2DsYuS&= z*%j8RG2HK)i}!?CuQoNrxlXiqmCZAKc03m=+4x%*Z9Stn`@Q)8PD;qLjp8Hn*4`=U7<|J$8^~i(ku?ucO&S=d9hvne#cNrXP zJzMG4vz6)c&6MAgDW9IVfxREl+I-vS8rlPx{GrS~Y4hlG{PQZkzsMXcdTnj?$o+_ z1vP)RJD-H`mM=_~Ze5; zoomrNH2sD1(IOa3J%|FUI~v#q%Y|rNm!Joe|H7`115oxGRoL{q}o!k9*&y`r+tiyu$zex_9Sy z)oxApz8}Rv9>{u_Pxi#5x3&_eWOkdy2w&BITO9u!uYONkLg&M+wq+f2R7RCAeXs(Z2qom zd#5;b#=M2{+bHk-%-A-z&(_ujT_S^8g54zX-_2kbr9JtfE z!R5D8oS5tj#dlSaXY7?o_gS+CdEvDAx^vQW3C2gZG z3+}VtMmu$`Tq|vvO|Cfhd92STaCbW6E}F~V-Fjn=yQ|af>h9_fW!jyYg@^y#$F@l) z^6(U!UQ%3o&=2j)Hf7*h-0&mlPmiDv1!bG@IlMbl*2d@sAKQ6u``!i@+u2ZI->_?V zee?y+lX-pgW$;eLmj(LhChVfktOL4>&EFNUlQC||KYdzvp1xy??1Ina_xO*n|2Lsq z-h_>at!U%;%ow}h_eA;>>qLPpZ79$8He^m!bu^H#iC7b~-+LtaE{VO-J}+Z<&o6^` z^YonGy6Bw;+1GZj_W5S@9$C4~$;za>_J)A*LDfON zs7||+gX&)i97R*?xTA6Z^d{1KB_q8ye>*FoJ{`r99yw~Z=HqyZ?O!N6H37I|XASOcFyF8mxBuy>Ap5a>?Y}1RXmizbKpRrEpH$^v~}} zKGGLoj&&$iE5@& zT}ygan~U=+kV{88t9&SWUdWOAhx|W!ra6W`qI1;n>7U72>{R8<(cCuLG^b_xkTNq< zA2~9>I??HUKBXy+)*fD0IbK$N7k@r}Grp$#^G9`jrt3&_u%-Ql3(y1eoNLN+PX?dd z#r2(=@b7$>xv&3)HxsLftW$j0hpSdU*@tXZ&NRt$l(W0>n^<2;Cq?Xm;e*#1rA$3v z{zS@`PSSb%!npQb@)vmh{>qN_hB!8Mle2k47+adJ?5JDy-VU|zVI2jm7MFwk5!!qN zcp4{@eUvX)%<1%wUfJiInX)tf$k^?!PTQ_4=ObGiC3pSWfIkB{T0>0N^!ZzEjO(o9 z8L@&l6eiw24O^(Ajprq|za^SggGXU{G)ZfWV!0%Xll6wRrmgFU4wVxRqpx;;=yL-b z|5!F9avpoi-mT^t{)W3-h~;e~epd0n)=pKNPavsJK7qfWY-`sQ9hUfbl+>?NB z{i^=!dA?{ne!DkDP522eQlEUi6};O?`?6p4+}<(v_=q|-<*)3>eeIR_&hYacEzU3J zOgP%*Oi&$-iSiohykQ?@#xW-9FZoT(ulShvw@|LIaN&Z)*N6|Uie3r9w#W!e8AXkCTzVd#2 z=}i1Vj_$RNW<6)tcm5hZ*!s`AH}G8k8($6|SLcyDdn%3rOvdMMo?Y$6N9_w2YlCsp zoier1MEq8JahZPlUxJ>W6aT?$ZG||GjN-u0D#Uh;@i=u$4X$2;*7U3T>n=0+D|@_; zj5_EZ=p^xc?4?{d7q&>ZclP13#MX<)OY=8dezs_R2DCn-zH^0>b;^r0h{nj)gvKvK z#s3F?A-l^oK6PlE#G^f@)^~o~(YplBMictVJq%Mc20Nd2HrmtJXd9y)i{y{|v+>2{ z|FF98`QyC*BZ&JB*9deK0-VNz4d*Op_H$Uw?>x|X}-D9ZvSqs1FxA8#N z(vFlJ;MNHG=+>|q!>?hs&K)_pOo*pjXaD%CuWXc@DAXV;W^g~ojQR!0qBjcFk?fGH)F7dYs@Y7fS7{Xw@LQg}SUm)DLuzOy7-`YA4Tmbk@^cVRhr5 z(3aNfnp`x_cfs`OI_CM19tJnW9UkE!D%{Nj+pR^(Y_bW6^km zLm@ZC#%f<-;u{?X=HVm5Y#4<-1TFF189njM$X*(x&z1Rdy0vNggSQ1M(Bf;~WIZ51 zgx3vHv>OSht~Bq+uc&?RUqB1_&SlrmX6-ZIDD+)UuG!_cjw|-$^IN#bhcnL_tIB)# zvHgTjg6$^z^561hn0xuHdE4v!@-x}*+DRX~i4mKrd@G!t<*YQec;F8SY}qXAsl-Nm zd{5wa7PjCzn|I(4i=!^vxnUkm!7v*g+*VRf{WjT1e%-71|I(+GTZA&~lZZ}(a*PBx zdV3q0jonC}@DJ&><3G$p_~opkL@G(LHYXf{Vt(rBjM;W~^-O;hAJ_eWIf+ z>0g?R<5m4v>bLv^l)Hi7;#;k$(*1ju;+I_-Eijnmmw$)egAevuJXgldFP@_MZhf|T zfq#R%z^0oD_PZ&ke8-aIg`kXZEcFZudTzEg6m zIc=AUzSmObIzBPq27bg~etMqG=5f$JvBA1k( zUUWxB4w6gU-(2PV$>Y?Cd}dr+N9^sE49tKl28 zRjFRUcha}f*IaB}ye37mb%V2B`zi~3jFq>oq$i1=#INM)VE=b%zhtobom$TWUiC1- zI4$9-+=?^7FADDbv)HY`KcMyWoUaqdWAFpJuM#bSHbYwU>YNef+u_Mg$Qj*xEq{7t z+KkXfKyTl#-!^Rq(S&uRO!ENWt}_1{@5?VD{&zg-WsKE@FH>`&nRrvpm$1%Q#wJ>Q zdUBr-Wy1O3=ijLK`?rl-0N?nNIVc&M%hj9Dx{B}ahNvig+vEX!oa%p2-`lK`9jTaU z;8mpEDC$Zc$WAkVB6nnr)V5zcG-lNmd}7@&kj)j!UPd{~Ep2|;;meAy z=TTmM0`bY&e5Z8E4E%kXdqLeH?fJs$Cr>!=58IyqFV3kAqI*L;4~821lx_BCRNT?^ zyRpr_A^v9^rPm9$iZ)U(E?!PcHzfB_dhCNWC%pebYjJ3swWa5r-Q6hNX^pHd9%u)j3eG2I?xyavI|(9O?rQYQPik%g|?7c$qOB3!G5?bO*S;BcRP7m>GWZvS%@M zQgX%dV`^OrXcgKgIu|MXJ^BN*)nvDuK8>v=pa1K}#diq}vPoE5{~10~e=FJQDLQnO z?UYJ%sH*lhbD-}AvK^9 zF=)>(>7SXgMLf`wb{SRabe&K)6v$A}7Li-LaJhQkA+EBYXYuD!VXu*0K-qXIFY=%8I1+n-6 zoxM#nqFqs;j`wYA9?OpLJ_c|~+cA}RK7f~;=Kzk@3iZ>*3q2{TcZX%Y%`}u9D&G3y zM|EZZS;Oxy^V{eQ+<5*5y0^n|NS{w$=e@?010TCdGKlyc%TJ;h&SvhkXgIP%^spGt zX3l9fU)g`%{mMyBoMK)vm7J?07OtJ=b&63VZmzAty$hcaqnOH5N{o=oKIY;Gw-C!E z{%j`>t%h^IwK>5WH@-F(^MGR73Knm9M8|WC{UgLNiZ>K1x21s`3h<=G2%Z^rCNYAv zZ!v;AGd?0VZ^bO9TVUU*ZbVz>&Q^bji_DWh)#0_=#Rb4T>e!{~D`tbdfrQRcR#FK%4s;zZd8<(?*R{i^yLHNDTr zDA{x5B=NIfoHej`9`zT84z;9ZA%<-SyB`+{FJ=?gL}+n1lHU1UR_`hx5h{-yl5 zE$~l_`+?JnpLV!w48O7&9FQ;ieTyGY|1T-WG5#fe>E*wj zp@sL2-y4_<@b4DJS8>D||2}_iPJHcogK{;z6Fka{7i`ZL;vK=VF;scQcM|^@myMdv zbMW-v@#*+NF4uIe|X0d%+aDYjgn)dt(;k8TQx9lRk})!?}_?u|7Nc zN}gE18=QJj6rHHDbEsGX>f8F!Z}> zjXQ+=d49b+jNg8}(^}A55^K8{{YXD*wl~zIJhs9l(9|MEju?KLSHkVJihEr6;~`@1 zhTxSW174{P;vPd@`8xOw;*~D(N_?&{8}~RVh)q0(-!{jZ%W;pp4oJs6jD%8G%P_s)@bt;$_CllKs)fu%<4G)_ALfG*y{=SFqFO0sau$Dw^Dx8Q7aObwmz`Ked)8{?M+n??vmP z*)5cjzhd?ehus@7-YxqegY`C$MSiW#`iJE+vH8Io@@nJOv^R3eaQY2ve7MID`fW3D zYa0~jS8-3K63r?-8%3Xoi(M+yG0*`*n3=u=aced&!~K#lZmpUzjMumTZgW~*vyPb_ zygzYkr*ifp*iSIthl#uvY*xHTL9L9t$y#<|k7aGaP!mHgDhjr|~>atJRo?m^s| zjl1@2Y)-Rg|F+}S)}mAWU+Goo!|w?w|2GKGJQQAw^pNeSii%# zH9bq|<(0;%p=<}ldTBZy?X9%u;?az@?{$5Zza)tTm(HubN@S?^d}Noz;}_^+U1^z` zjXRseTuIq;4%Z>=rRMZ}mHdv|99oxB8PV>wh&x+m_y%oNqHVylm3;V-^hxwrpJO~8 zuRtb^0P}YhTQw8?I;z$^q2vq$U(e544+~F?az7*Bvyc}58+R7-q^IdnzW)D>JFDW3 zwaE4xyzH=j8s@Xnj=5ctc3qX_PFVL^ld0H2z`%c#-e+kTIYw-z&ijuLBlack#qxI0 z7xY{D#V~e|!Nd-Fkg{H`+B58+J5>KQvxD|OM$GWS@A8La2mL-{#6DZ~hiwP76W0;z zzay+)nYokLL61ho&Hry`JIM2HS%2R*eK)j&`Z94c744Dc!Mecy#E5-YZ6XV#%UEB~ z*Q8SpvKdBLpNF#Z!WgkHX8KpAS)d05dPKOdZ~NLVM$FH_(B`?$j?ph4jF-5MPEdVrzpKv0t(8uYKN1F=F3u!C&JbSbn1B--jFRZXbdy7sAOkNe%`G& zz&tDi^GaZ*_9-fi!6aYDbNxuh76FrM_aoJ-pcc08B7!GgpbH_!iQ1ZA^EZEgQNXLR*q&)!fm0-ccVJw)J$J^4eV0H%mvm?ZU zNhXaH3l_#!Y5qutRkSbQ@35@5A(DL*$JaypF-Ce1{BU2}@7IWLzCccPqYr+cLB5ZX z;0ANc{654thw%diayKP01gA%%iXoUjL<~V|TM$DK!1A#Qg$dIqDaRABEpzufreMT= zO`lY_dCVdE+Bfc)sTd#e-b~+)_Hilb5Q@W4ziO|We$syTYZyLQ&{EzP+-E)*2JY+t zuJSXa4d{OH-Nd9>E?mW|;-l0Z zD~e5f@1D|j$Tr0T4fVxyF3XMdghtEsb+sljo?oEx+`s zFyB$A?KcrOt=!(xmx-60+0uAB z@h;0;9>%p*%9**Ozi=XJ9pB9TQ#AK=Px!xV@Ugb!M6F}(u^4A!BU|sg zoP4@=Kh7h~<@~k<;wIOf>+Yjb8|3(mW3l;7j!xa3V{MpZrw%NPoKyPx{H(@5b);5RdEbgb4BUIEMXwi2ka)$?Eqop4Bd< z8Mx}ZXsB2j-BqIdDlE7032|=Y+_l$s+;zZ<8~aWmeyRCz=pL6*?qSAbeF3@_W<^a4 zoet98d?~nI=Eh36^IP%o^o6~qL+yRDdru$R^6owT6n@)@akc(7(3bk0cm2*^O8wQ1 zy~F~q7#oZ;&(()Y{r>;xx9R=V*;XBox6vx76TutbCw@gdt9ameJN}EnTOBp| z*j-;n>vk`3z8(+3Jesl=13YWnG{rS*Z8Ti?ZR2o$edq0eeP3hEb1gSO$M-6J)5kR{ z=2tP#R*v}K?Jjp`o5Nc)vHPR=?{nYQFivfGi{~HT1`m-d$>Tl_D>4_ZqD4aHC)=!r?WR*m)cz@M)wnfb%F=q~W&Wy;-u2A0n`@3B zhcUFjtb_S-gx;T5&go4YK6NOATy45D(cy=vJK^zZ;;%N^6JPATZRmEkbY0SMHgnFm zS!yOOyBU0F=XfvY^1?T2`kcR~h&skA>W}*^+^r7|PyO$sUkTh>fO|^}H;MV@e>?TJ z0N=`icL`j%AKUm@xZ6Et`8eON+G?k44Ro-3drZbpN8VqO@SY#bTKLZMn)pm(DxOaG z?72gWpI}TLpbf1{t?qJU$Xz|1-8Vvq>yi7-SM--C@8y8j9g~m8Mol}N zu5A6fUNqxO1$AtW^WWwj_0^uv75H`vv}1FzS@WZ2i{_%I$2{mUmw6~XqY_8EKy#()a&}#dt35;yxyyi)=%m@MBBcPT2rl`CvLfyK5z~qz4m5l zIhu8MP#xMEZryE*`(?UJ&@aP#n0{HmeZQ=4qJhq7K*O#6yocij@!5OaGnLi4W^+>M5nXd+RwN@5zRlWcs1X%-g#KD>g}r= zm-Bo1w!?~7z7(H_l)j`hl(m&4I2gd$WZ8TOi-Gts!IKm8jOvQ%NtrvsdeLWcjI$hGQ$_weBkW zA!YaaeR%nRWy8jHYp~bX5X2Ta|Frhqr`kTow$sTkZ)YsJi76=@44=+cZv3VF&^0+f zsT|)~olbEw@~0&FJ$0q)?Ta7vza{>e@zl6o0xh~-EPx;1!p((4@O6~+9DZv|DG!Z; zJ>OtF<-=55c!6^)@{R2s@8r*T{!_n&vwTr>Oz}dE4RDY#D>>H?`y38JMp3R0nb=Ob zy4*2Ef1YiplS9(!s6#$@?3Nd1%x9l6mP6EI{!P?90zYS7N-qn`*&I#I4u!lG?-xX4 zg1e(K^pTAw8YzYmTgv1LJbox=uILkeT_}Co<)W8X&SeM( zjh*^||Gl#?F>0!EW28B%XFA7Siyx}cI-#gDrL5hJv-v!EMtuK-)zf$YM`z_yF?kvK z3P+vUUh|PV8)v=mp&Jh1>`01!0j}b&ndk{Q)|ofF82i6ef1SHSSobJT1Mj_#SB+-i zzsU0#_^T~F&-UT;_BdCd#x+`1XF8eHS3iJ9oaq#`mA+d!;H6Bz#4|I&G2IuPd43%+ zNcmzL{gSWncJX?(o!{dwni>63HU2~NfK8lvj&jIE=z27tXM`WVNIh$34bgAAn>Ih4 zbDh-3=5FV#GjnfX#>H;@D5L*6Tf3!;Glsyiv&!7nLLU2g-nlY%UYX}M?%dzfc5ZA_ z`Zjaaop86^*~hxh-7d{nbUa%9SB*V68fy!yjmN&XRv-??@PCSkaBj$7C5p)qvPA}HTw+ss>3?I zK0bpU_fuu6Zf?K#D+A<}hR4FPoVi`!JtOufNN2BQjS-D&HNPC~x%a9Qo^I@>Pc2T5 z))~+>owqjb;#uU*EZezI`u-L5-O&X5oj%X#SVvi%cO~!Iq4t|+_Ks&ZrjDMo7{^6? zHaBo~seNE0`%#96jRCY)Szq30$9UP@Kn>G7@ZV4II2ZJsXX1n0%(aa@^VT-zkGrSw z))Ve&{3iI-Pbu?{!C_nr(6hY@K4knC9aiQ)oxSh9KI#+>!tX}#uyexbUft+nx#NI; zGVuTNlZ{{R|77Fmfj{%mGW@;oVXavn!B>p6+NmkGQ|0U-&m#+ge}#unz3%q_|INTZ zV{PN|floHRbMGe`KOWQ9^qLaydudxZbDpy^4}H{LNGIW~IXFvgI~;aX?^@bAo6kyg z>AHy@o>qna_kq7*9}8VvG+T7^+QvVkt(F7gzNoLW=5F5Vf8)wKfV{ZbAhY5|6%S!arWN$-sOUe-Lf=3 zkG^whedn3LjGSHIY1T*kE9l2!^@qOXxGzdFY1fUp;tT9u`MDxK*~R%~&p)DzK<}y<2hPsxUKW!9zj0;MjxY1Fp3#2E-pZ{a>`u<~KhHb#hDoKRxdl4oUlWhb$`3PEg_>`fuSm}| zel`4eW3*DfrqcP`iNv^BxpU(GsWNBs>`Y|K*w_Y7`jMG)NBesr16lA1=oN7$Uvoe_ z^>Lm3@;nuk`v~PUCzH9*K%3yJ`FJ!EN30F9!Ks=ww zBXCrQ@&nW|htyZ{ns)Tkb}5z%_^^*c4(iPQl8*O_eh0=dVtKu!;|9TX&xCU+is!Pu z?^@FFUcDb5*AX3dQ${=;%8uSsWBI6ir)KeP^NrDtL!n~{daU!bre3YHJ3T#*qpv0E zNcNV1F%z#DS z+Vj}+bmexV)32o5Zp!&GXZbR~@%q9hpJQMI_>x6}pX$pnbM{?tkLT=Hu#1iUZjDX) zo0%s)USACO|9i#qJPCPbJY%=a)8Cb^#KSLss?5WNH{-V5=TU*K8Xqs8^xpSPJo}Hd zeW!4D@XtB##f`FQSD3#y*6|pl-RMcC(_Q*s(mUVQzPHQY4L{h1R<0e>``^k~qlX$T z#zbFIyB1S%8GJee9}YIM_Hbky>^;cw4>G$K9g#LyCb~7aVZRO3v41cQn?S#7t5s&) z+}i4LJ>x^*n4Ne*Y;!z|UZHj^W|Fa$oOtJ#Um;c?IQx^)uf1J{&!AJ~^L)N|S|+}r zt9<6%pG(@5|J~oEdz$RsJi5H>kK7qg$=_l&5^L$VydExk;=e1+jynIl-KBfigQ9z2 z3!z)eS0o!K@gwOO{l?$ZNq!FNzwCYSkZdmW=1%D+`d_-u-S;_!y{cSM@&UDyQ=^J; z-$l8v9`+LJQ*67=bh?7da6ftHiYa;*?|Fu{ZG<0T5Z(?)jgRo-uCgJ0VIdC^dr=e* zPCUT1 zb{y7(4+A?mdVbxM=%U?>1Mv+T&ffX@BJd7gyy`*OWb32cjHfI=&by{0_pB0oHqf^G zzDD#4ivv)b;<+taC%~=nc)DyUQPZEY<)KcT2xQ0l+>4qw{*fbP(;On>~)hVNqV zlkCEGW3W_jT?S`j+O6!h70R|{%8C~LbH1x5KUCqZQ=00%o&;YNuA9=dI{aUp(zK2L z+&6Kk;gF$)aIi7WJZFB|^X-}E!r=ryMyt=H>3miOXWzd%V2nfy-#6uqssww*KENK1 zc527R-i2or4rVgqZ?O;SvmJ`q7Cd`4_}vB&m4z>&TlrLq-P?o>u12EI4!ywqP`p!~bJkX^mvKG#(ZAE3blrK=tvU-A zL{0R^coEs&S-3cAderR|m&7-h1@HC$D&BivNuK}j3f}8~Q@-g@H&3Le3Fn;j6~5(f z`!YVe-5w{N%N`J3IeceYTi`j<{qcdUpQ)U1Ee92KPDTDI8zbI(-SF?sXB@=;hjKDc z9sp?F1FaP+Dg9KkO>N9zo{HwITPGV#XuZzGKRtq6M&@b%VxTY+xk|Yn-tVH`nEF^R zlk8SK$?cF=h{I0BrU?eIysycgNu@m`VxZCA2kTReo9(?7Uh_SK!S=!Lb&oBiH#&~- z@688tCouem9#VK~^n7U+>livUW4iV13&svw$E?nps-{*q2hLi<`K?_uK2VL%hJ6fp zcXeaW*wu{~9%cJY^Q1Lus>yNRwbp?4gNlW>)~#nvU8TDJDgII2!>BvW_L$OjAFXPt zxw>-QU;4T;*EIJ0?V82`#(0^x8`W;^7~0KMZ1+dh{eiC^;j27kZ6ka0>H5|6)IX$R z{q4T)bJX3lwo&&PvS!5oP1>&Ex#V@tn#mRGcli3BY;NqiuetGC+4?-U`U|I2tj~Nr z^nN}XliTrAtE?ZF6>ePa^KImAZR{CyYvUKPZSdUM$Q@p>jk|pP*HQoATN{C&?jz6R zK31-Oi?9C(_4yRD^?7FXcUG={J@r?57}M`*?3r;-Z-5j^_sN(aP|oU)h{{kAuaxV9`bz7S9t{ zJ1fJ|TEp^f>rG+X8j}Ym?{_WzKxmIhH+Y86{k%MmfP|qw>j0L0cP<+QdbWXYY~R<+ z<_-5~wGRtw8)h9`TYNivuKK^`x;q+o-uby3sz!WXKGxd}Dv-=;kZ!-f6WurB(5 zbe>L=&o zJFR2QsRLf!wQ(NbtDRmicr}z^Pv>6WCUa)J;XvD7hf+D|P{Mlf6( z54}?&)|puDn_sV$*oDVqdq!vJjMh`YiFy_z#~9+j8&^9kTCkix^uYryCml7v?W861 z3pZD3J)WepR_54ff!d2sjEd~dOj`N+7s+YLyIHPnd>m&vKZdofz8`;AHkfA7 zUKf{H?91eG=`zoLq;c(e4;h?#U*_senL9qxc#VT|iZAnMy3D4Je5CQ{@5F7rfiipX zomyY;>nSe9@S9atJd1axn-KeQjn~I16V9yyb1Q;A^7AjGe2dd(&A-LmR@{sFX|W8{ zt$F_D?;BreUJ_q8uGP-f#_corHAZ!`-ACCZpE1A1EAsLF(D6z-wqa=BtMuRA=d-a5 zfp3dB;{8gAj~TtKguYfdmb}7l&&~XE$PeVxz|KF8=Xy%-t)%y(^Y3DwOV2lZ_#4MG z$=)?u%Z_Q9)6^aQ|BE?Ik&|P{0qmkTG%+tPnhXs^Pw}umiYG$v9`tNVg=g~5X6u^m zt1*$!2Hbk+*Dm^X&g8Vu#_*Uls1_a1CiJ>SW*sr)w?qdg4dn*G)u27D972K6HA zqfX>JW zx4paC_f?VG)!6A6I}7C z=B#kiZ}nMxYD=_C%IO$7*VqOR6ecPU z0W_sdNYh$(*MVaA4KA=`C)rsUwJY8MMqy!@Cp=H7eSJ7{WOzx>cldGUFZNv`&)^@2 zUvn8hKL-u=b<;02+<0FRH=Y}Az|kDs7u;Sy5^fFU^PO4RdE8h--W2oW5coAX{D8Hu zw0i~rpUtr$Xr~xIeB9RWXMzWH>fy8Cd&@^JRvg+3u-%9G)NbbEVQe?z?aZoOo_HT^PsV z@5?+sc_^IDceFZxFs;h-!|@+wD$wjq<+{pm42A0{4%br# z<2pztQl=uVJU3i{wXe8p4OR?;^iAnMb*!iDTC?*C5;#ux2HCpXu})3XdOOEUfDN z06I+5@s59!cKth(5z{-)cJTJxbZ-0JhB#Jp9SX7bAEpzy{tS*?C0W=&$G*h>bNOH5 zzdkc5^90}cqHR)~%zi_O&wqem3(xOXoI)4-57;t0=U@|RU6c=m*dqIV88+e+p5t%m zom2LCm`;B>K054N^|i#i8tB{$jJ_$1r^bRfJXZF+Qb>jOVb=6fffa zaK@9$OTt;cR`1IV%5e8$e3lE}w|wowOL2Fbu%GcW4156G`tYgXcTeI_1T%6mx^XW0a9sr z<-?cnRC_z0lD|)KL$aVcI&r7R8Q-b-LTZ@b{;UqqSEu2foQ22xEWCLEycG`K;T|4) zWFdYtv+%TsmcfrbkOV&uPkx(q^e^#M;djv7apw{?_%UFf?Ox{A&o}Ls-&yC!Ltkhh zXY$CI=A-&IH4sb3x+OWnnr3oDem!U+zx9BA6O$SoA z`|#@z%p#6wQ}dGk&GOkStY0t&KI;0nm*v04+|ilL^nOrsz8p9O_>%q&jC{U4xEES7 zmi9}u9We(|vG6<>PPII*V{Uvn7oVTeot&np%tad-BV@t^XRk$mVLz%5H4WYy7&H^y9J=pWXreRnBn7X5F5gyCP?j@zvChKKVJJ zXB#{rInV}QsQgKMj6UKGPdnD?H9;Rd?fl#@eMMuofIMp6&ko+ct&07?&K#*9m#ZI? zvwmQo?n^(cP3YE^hv#27-1??|DOXb+ywJ{b>j(dRKQzbBqRnuAXUkY$rJK#d9{0L{ zABO-|QjWNyR<|Csy>RLLHa`}W746^T=`DV&RG)TyeH$m&7v-H(eeL0E995S#SN4pA zlbc(u0T0<6RDI|o*_6ydbg-)(?giQrP4!XR?G15zD}J;0B764mW%Elu)}~AE<8$u| zT|36dJQt4A{nk0Sl1ElwyhwgN``vsgbKCXDuW!(}^@ZFHofB;*x1Nm)jZ^RC5cX=i3S%tOB-$C8>!j$=zr%>~` zInJrp)~sA)4&Ok=#{K45&;I2p@+nT>y2gM-xoEa0i{j|XF5uz2VDqB(Pu z_U?VG(+ii(ZyVJ2a`~|Bs~r!Nu4Lwu-i87oCEH6&zpU`tn)U+v>)0N8AFy`XBf^zQQ-$>Ruerw**m(H4llDN`w>k6@6 zpgy*DT}+-s&6|rmo+Zzr#{UlH+{)a6>#xPG^z9|{(DB#8tWHIJ&pU>@WGV6heJ37E z-nTV48ZF3gl`lP&SqU7pG)E zGCr=3@Q@r3ZHVQK*G2IoI1cK=n^_M=>Z@o%IpQCZzWV+x&i0Qsgm+3Fvlirn{?)qi z@H!E3iI&fFp2M+@`rz4Ehn|>{HAD2F4IWfq{iiL)0r@hy<4WlZ$h@{Zd@9*2xzlxM z%&T1&CA@lcptBiI@Xpgpvf|H(b*T6GTl3b(iKTyZ{P&N{N6Krw9}DOqIK8~{a1y?O zmVJ)rHQq)K>SyVpvF@Y3pZ}f~#`8Q^Uxb5XP8;>r$D_mX4*FniYaA=hw@kUze48E2 zH-1~&vzc$i?gMiidcnzh=G*sU;GcPVe+C>iAC0!mjTBAf$NYQzPCPF??Amx(GA^D& zJ`PB5Nf|KCQ@*O_bSn+rY-9#`ol`z1QJ* zZ+UEb*z-!-kR0G$iZ1du?#VYrKKGV*n=+-1&|2Rgi|2#!IR8T)cmDeErMq0acQGE6 z5zZ}6k6=A{B0`7Ud0|zt=OjM(U{2&d7R9?tmsC4e=Fce8P*waXG5q4e8s(0mZOsX- zn|;8}uA3{ty)HL?eDC^*Ht8E>e7=y<4D>@{XO#C<_;Dw1Jn!MH(%5Lgx7qr!+>Rb_ z`!9-kZtQFh-sbv$TR`_fu9p5j)|vZwAJQ+85j;1z zz_GnU`b<2d@l5Y6$Qj1DfZk#IC}V?t6zF9Arc7!~HNRQAr0dexm~Y3{cb*ma6l6!w zEo!Ww8})@(9r~N)W2x5jAP)!c4L@-DsiULn*L{XDYL0jZ9`J6-`z?i+o&mcsImj{N zp4WVuF=Og)a^_|Zxv6t~#;mb?pm3Zt9_;MaJuc6I8+C2N_1Mi*7 z`nnh%W$w>iTpe|)++4~?PK0>XaF&=cvvI1WTr!Ux?xM+8+&mV4EoP4OULVE${MYd4 zIImM&M!q@0sTuEefhs3glkr~Z=)00R;mR^@_(|fizsAwo=YlJ}Cn>k`nvBn(7Z`oK zXTFbTEE3;ZFV8IB>BG^EX$}Hp;&VncL$0q{@9~Yr^s} z4x0iTjGpx0_yJs!d`$FlxH%HWv1zZ?+XI$IS#p#59gg0b?}qnMhs)Bk?0hWClf3gh zDP8G)eEHGXfcM3>K^ex$;!L&Ytj>&dMY*xc5CWSjN>l1lS) z?zr0OGC%cF#&kh1qw`Vc?E$}gIAI^iFL5_Mp~ezrZ7lNmgl;Ycn>oJ%<8kZ4x@LhcS*l0QR7SL)wnQ zCwH~e9kpjDTr2G<{&XPD@0!{(>?)u8(SD3_{pmd4ueCqp_q1eVv)7`J&e`ZpjrL*{ zJ1o1Q%F~u-DSd5xps(@UXgD4oKS*O4-?0$F)%$Y1eQ-uFz_HSK`zOFPb?&Hn@Ol5- zft*#quN`G`xKt?n=;~r)D`!+YhbTYNKK?^qkB1)c(|~l=(%AU7`q<6hR&qBSdqSyw zdiF83PrsS{dHFUJD{XY?x(a(Fjz@p&z*r`?@vJn@(RCg&S@IG(qgR}4b>Pp3nwR$X z@~#e^k*tvXnu*Uq`+QrdFB@_e@>_YW;Qyx557AMAvD)r- z`QZ0Yp*_W$C|`RY{q=I*kBQ`g#^@8!Bo%J}UwJ;U*n;!W$7s8xd86OZSa4k&%gQo8 zlsG!TH(dI9BBMnm?keER!nDcji-izBl}V;onfr zzV9LI`yR@flxY5csL*5_oSE_&Uo~5Pl=tsJ?W+XjV%qFBWSp? zgFW1MF2k2Tzo6wVZobNN*iDI_@ydRm8`0EaU%2`Hv+t9Ag2g&J9M@Ibs@Fq3%@La?dGOFY$xrXt;q?vrS}>gknd0&>wY_iz zdjRy4{M1&j86S-6=b{--=BXW?`?cG23+9vjC+m-NWnQ>qeyz*bsT|5`+rzoW?+>`= zZS1#OTMgy5uJL-h+TwYtE%aBNZKyNcYsRf`cOO~*gR-K*R%lS~_mDEM^!^Ka?{Z*E z|H}3|*(1Fr>Rja3SZk-bjFaFztTCdD`oS5t^1dSFjPB4=x~OR3=`a+$WK3Ob)gz3F z;CkKB>xrV9!AqVeEw$W6`T{#z0QxL!!7UVpD*L)*S8o({5+w>O&MBH z&ySC2kz?<U%M^EA`? zX3vDydf zQTBbpzw{kjIi902%!HPYIUX^7aPLw+5PTR3@AF=|sd)EsPul>;N8EU+AJW-vEdqB> zALB!nr~V?hA3Yq-GZQ`ia^_obrqAI}mt$HbxNA+L-wTtq$kCEBbGom{&xbOf z!Z!{#=j{wVt{A1m~r7^OpQypC;X0chy;+DCgI5!;k;sVd0n4{xNL{mS~}8 z+CP5ZPIU8m(q(9e_o^?s(vttN+dID8_Kr@8^i?v^a;Y@=>>L zj&_WNKa|%VJ8Db!Nt~!7FX2hFR6ZyctKY;)q55`RmB@Qz{maV^Tn-XObCwtdan z+mCm;rgSrWIK&#_r*-$womloUe9F;P`1<=G+wZEJ4ActTh;i<7xqus+LX2apIW*9CCN?ee=N7I zadVq>)nvBa4R|cEg>J82yg4jxr?6k)WNDTb32yjwJpK=gXJ}u(2z&@}Y$5ya$`fvJ z7bgWi9)4S2PQouxGx-MF@1Q+`S?-z&{kzBYPjw}CJwNFGAYMCRcwW;PQsXts z87?PO#${i4?I~cs8eY3>7+$+neH9;R&2;=_eO3Scyu$zDeVI0&p`D*siR>bdz-Uid z>o0zbWKE{Lhi_}L<~n}H!q`~H&BBzvb1!`*PT1LiUSA7iw1CMv@K`cG;2C0qQg}IE zq30`WCsQWnJDd~n6~C?rT{qGD z7Sm7;>PuD$D&K02k$`=Y=0!^O*9j_1%v&t+f5 z<~n6Xo6?jr@B8w?OT2IIfsu?^AQydE58HBX`u$qfX^zMFv1F{E2hTmviylkB#jh(4 zp6ykuU2FS3^n{J>yc2ax8{<9hCvS=QvX}qHm+S}lwcq@xvmIZ4On%ga4uKyv#zl4H zM-^Nj2cZ5)SIdbn@kxs>^)BJd*^Vzi7W1X>_I$Y_=_~g=0n_GunlH_c^ZoNWPZD== zA9C8!J)C#GZ>HCv^RDr08FONLKIXSzz9r*LuJOAIsr#R?38_;jKX^V$@y6|xEwQIl zP)@C}fo$Qojm22r9Y14Io4bESzPNE;M*q>g1?EuuZ15U6l9pJz?6sngUS+c7SIy-( z1;H{Io7m~h3FcL3i(T#LD4KaWwW;~4j`QIKPtQF!UBrIUg`735F5ms>_lnH7J8iIU z7e92E*FWN}MA^xlalZQ;KE3cjt<{aj)lQ98rSmFgeaF*Bgx?Lk?rO9If_`SqgW5wrxC9CB^`CSTyaYS-xJ5JuVd~=_V^gANOwwt z^K$Tu?}?ew&zU@QgC!m7d`y`3U4WrH9MMF@_t8)0YxNH0nL_q5wzB!9XX&@-%-+m^ z_Gq-fGZYSftrlHE_^rVI)e{aj<0?5}W!6N71Nnv4O9ljcZ8`(j*^AD`o@#<8dunkU z)bjZJ+D_=++NFKJc-r}m?|(t9epgJov}F$srAw;}H#XMn1p zv;9Zyp}`xDR+IEwZ8A?e7g%}ER`A46@RD*xc6QUQodtwu z+#ffPs+SiJ$9HOo&$M?IRU-qS)!`?T3s$^1TX%p06W(}p(D!n`gWP^Wzf0Ut?s0*q zi@>tGOvK|S0>|xt4`}~;5MBYCWKRk{(LPx>`<$Ft9^m}0{Bz{+&-AI;WJi4Vn>xzl zXS@(u|2hkWsB^}FVbyZZxX$fU$)lY zF9r_VT~1t$Z)9f(?mJESBy7BCOZf#<$LA(p*$olTE;7&V5P0 zp@-u7HpKCUQE|$1lK=2H&%wjsTOIKi{S!QYj#7Gy^31g~L_1pPugaCjH#mRVC4M=8 zJ6UtZ|GgthawZ+CA-a`gD*lu^#d3pq%=5G4fcQkbskKskEM8Fj6wi?hl;bXkKM^mU@l;ACFn>ZF#`qJQBzq)xp7|ww zbsG2SFrR_Dz}jF>lHZ-&gMFd>XFn^oR%UQj-~AoRnp@Cq>#Sw3E3T-G=bHU*nOJl0Y z>%m83tonsxM}~R95HM5p9)UJHkGr#R&2BPmqq&rep0lxGZ@u-y z@P*S8Z0wL}%CF+%LrgB>V~||5SZCg+^D_r)REEFd>47!$ImNFT+SnZ`tbab2^5g#% z-vOa{TR4*YHHhEe&3qzH;)b)YE)2?(DBY&Ef34;J)%@5_{aWUubj3mt>$LzHXUmp` zD68?vmMyq8vT$ctD7$WmvdVpsh1)hn*+IFB>8J8I|CoJYbg(4WKz)=Bt+`W{kL58r z7-Iw7D_X(l+2DiC8ExZ}x1B|kcC=r)Sr@*ZE8n$(&@q#nkRJNw;zwh9-)8S z`)<0OkNLMX9DFR_GO)PQuJajaw-tCH9n}svcg}Y7wtUMxOZpg1FP=poRYzq#k6rSK zSGW)N|7Y+0>r2dI@;%GlbnaZ=!c2|*veAi=N+sv|7G{}EydXYD z^_89LI|vNs$_r$l-(S){)z9^{ys0>^`nP05IE8k-^^0AcM@(#*@r!ePjbC4L^w17E zyVufgdR^JMzN_JJt)A%VY~o100wGbCAWluxg;hti$vt93}zNvumA>6v$P9bUto>l?21dHnYH zcIl7tQ+w|_XBgZ_H{8xS@-q!<4~5%&rvv8WS706{nHkDEcP=P-s`8F>!w*+nDcF zaU$Jt0?v`1TbUmYr`ZlC`HT+Lw&bab7wLu{- z0_#Ze6hF;Aqz?&(`q2``{%YrJu5{@tqhDzpyI_1g4l0Jqwb9|6v-yVKxwtp#u6E9* zjSmaCo3F|_n`Pg$p2Ar32M*qWn_IfE1YV>C5@& zkRcPSqsaT;XK7~3*CenFhh4K^KC1b){Hw3Yy2^icc*EG{ujXt>A76+s&2(HH<2-Rz zRrh7#OC9DsN8M{NhO^^hyI1$;*xn%e^1W%!(v=;2f&2>WBf!UN`v|nBpo8_sQRp51 zb6M(VU#~rni=X5BEo|&!y*9SxWb3iVrEJ{aicO-m%Wl3&KMl7Z*=$$o7+^_HZKuzc z?lMa|_~`)tWEXEB*rfY4bMTD!32NW!c$cRcyNEG@Gu>>A(B22>Gmq=T?o2oBm5BA+ z)Sj)t_4%~kUE0sezS(*gf4;rn#hv#P&jS2K-cE#P?1$~W&%x-{clMbIPPP53UHUHC zfv0(n?#J207_0hg*iZYD8(GT_=-h|B>({&Gb03)G*78@dmS2fC`(-W9F)mND%cC*e z?bWq?Q-V*LU+=g5A3w&k1tnqoY<1^!}wMD>(!{zgRPr+yWZiXM_1>g8wu|G|8 z_@9?m?T>jA^d7kRBKC~N=Sj0hTDpT$J_r0@y~LIzx*Xl=edA5+Mb%pJ%wG&$Oa9rS zmvkndeLu;4SN+UChgnOeUSzc{T(_={OR|pJ|KDpd%-h)?v}}JvD*8XR7PAGvSDD{j z?Lu40Z=9^DCvu^01-@m_YqGh?*Sm3d^)-_+pL270Jb{fj>|^K5UCxfi52Q7SV^7J? zI9Yqym+dcG6QK|34%01+Ro8D|O$1w3=eAlocZcbFNiV^9dqaL4aJKh*9}Dw?8Q_Y~ zJ!+qr|2M`+o%f56Wc4Dy7l1nPR}n|f8YRAc^S7*>h+P@)^Nf&P#kxF8S^1+_^WCcT z2jO)=sqXeC|E)e=o3K0cOqWl$^V%G4k87Rfr{pQwz8&C(@6d4To0#7z+%(REo1ZhQ ztb7tBymm~?r@*TQoK*iQ)UW=hJT`uGOt&*E%VH^pu}cKo`^=!J_mYp7-=EjQ`)lQ^ zy@<6D(-X*y@Ra<#5?}4>!AZWpPl#9iAIev|*!d1iK1%p)c);hw_0`_~;W&0mdNcIZ zo+;Sazpv6)yKT`GQ}ZVj4(+QQ6R$75B46z&;R?@7eBjx)$1CyG{weT6K6+oRVx;98 zukh7wThuc(|1Uoq>Z_I9J@*&f*_LjyHMiZ!^v`&&>c4gRshvC}{ZxG{3C6YIeZJdY zrN8$t@P&y7n&+C%$l=4)J#N^6o7_BiSbuNoxH5mQm4D&vz~6g(nZMV*cjM3ef5hKw z^n84NOpo*TTG~yGmd1LSouxbr9?Rbwe#_w7L4OoE3;BheGfV#7Z5Li!JEFf=Z8e;K zx2kXLFnqg5>RaPH4D&~tu4YUt;e;<%&joz5!~52ppXV_Ax<~5gd2~3u{uB9gBXrB= z;qd$q_T&DU!)sVSb2z7Ij^{L0WsW&ZRUaPdHf{pvNM-KIL*X{t$=>XdWY78R$x{_S z(hWag9jWYve%)Ic*K>!$cb3CfHnQWTx0ky5nZJkYGvuj?FX@Iau#Oa8^;7+v-hVtZ zinTfEef*4TkHEjV<`Di(bl&5cwgpxFn`Pgee{*XU|K>9wdN2OVKXZQ06Y+1JOWIEU z|J#=t%zqDQNBp-hQ?VScr7v@UzA~DAWVRzQPu#t%c+l!T%nr>VgL{aG3EZ5X5&JIf z+>`0}>Xz9$-}ZUa8_n**uCVo9yUT+03;bAJe$Np8wQ6_R>P)<~rTshX$7qh%J<9xl z>}$NXv|rrisXX%z-y`dfS4dCTzC&=Z_;288jA+1y?E+8xKJOZxe?Q;n)p!3~2z4{` ziH5|-7@t4n{hrz@bOB>zXK>b%U@68{@Ct#B{yF|3(MG&MY-lX+ zMQbh`f7=wDSEqU(_VmEJLGt^0<(KLrzdt`%z6-Bg{n-WP&v3eWBseRFfulK=^NAP_ zHjjYIItL@f!}v+M&Wti%h+fCfhfDj`%ISjU*pHkK+Oi7m9_Mvx>x%Cs81g5Mfb$ZE z^Nl0H*u)vx4#rmMarD`FTqXHrKdtsV?1R2iOad{h*Q)*TohV*(Q^`j?482#<2V6ZF z{0!om%6hnE<0-H&^swubelaW`P8pdG1;+>C@nd`s2PXJ>-j0N4T>$ftJOIyj$AgB$ z;DOd;MylJ(obMOQk!Qt0DQ0;ya>#Ie=ZZ7ue7Q}|Mp103d}AJNfx7hU-wjvl-K)Mw`N5NrAN0V< zCBHZ^Wu)ugtQvee7hlKO$a3 zZ*Jr>*ZNgY4SNWpyxRj}XCTg`4#qn3+hmaMOb{14Npd5&|F_OSl%3=KxWk>}7SQ2i z`n7&5pQrZT;6wV)eQw%+b^JTZ<+V`ZbN}0?55wo4mfveMYresL7Hk2|gY3B%yXcD@ z*hc7$XmV4p_C{BiQu)x`c8t&QD>?~=K>$+xYQ;a4UG z_0C1dP0J7LiG6;RF#j5u%KJYl+gGjZ>C^L1P?mmUc2Q+{`2pm=UfcVz*3F!Q%bEJE zXaD3SpP$y>G*>Zxb zc-pV8Dzg8CeGk}tTDu&Sy@tNk{l>z>>^JU^^mE>|?o1!0Yt2;as{^b(>MRzG*&eRq zGdh9I-ZJ)x@eMt%Z}<4Lqew%~EA2BLhmWwIvp?oZpVRlo3-VN@6@T*PK(~ulJ4clC zg5U2BO@(xV*Ui*5h~KvsnoB$*f1>|mzO)IaCD=8>2Y%R@6y!6WjE3({w+jC?QQ#f|cN>-~DZ>znSE(fdoUe`%xr`A3qG8rrll9GJn@d*4%_QH4(_iR;Yr#P=+|zH@o>0!6vAV=52hSN~*vr;OC&V(Ra+1ws)duXjQ{0#OOy;H&CuAOLY@>dY zP346X+w9MQj_RdZx ze@=&RPS!MA_p^8AgPUfQNvahr?@Xp>E}kM&5i>3!_R7#CAuIxC=o zxB%IE(PdgsEl>An-}*Bq#5b)Yt^E>?rs)`sy>?=fl* za9-#3L0g$=(ob$2pl*FvJBqGa=#pINx5~-E49Q;yIF90+h%+{{W^a$rkMsTAzU|Py zuUO}seGFXP)wu+o3)X>~gT069N7yBU^os`e*=JId&uXZTZYr$}RrDk6BQ#qY+tKQx zjP&sU=kWCbpZ%m}x9;PPi3?LvEjqjw-V*b~Iy`X8*2;r5)h=w*&i)xan>z4GP{)?^ z493{$JLxY9S^9#{=gSH|!x5Zp?nJxZMxU%UW@&yk+_@CY0c@D%i zV1Vx)@O_XvqAK%DA9JO?t$v;Pc4O)OOy*mqG3fJ@Z}<1GDBrXNrLkA}HZeXu%xC735`F7NqA$?*%!zw!PdfhagNhq!mS2`NY3-REAHA>=y;s^ZyZh{+ zYtkL~fZ_XjqE&k9?(_4CKT9=sR%c+`R0FMh=SBIppTD$`HaWWlhi}5o3HqeVoI`$J)tv3 zH0O@c@Ax} z&70QK@zH}DH>a2OY-wIv7MpiVMf%!5yuEeP_a0btBk7ySFMC7duwv{wu{qYVejymd z1#KN*Jl-+x_SS39xPQ%R@@s5GhPKsjJ3hagx%@=ogk4gC!+75omS@b~G4}S>)Y~3h zbH@0f{J^CAQIy@yy|)Il0*>O~mj!S-JC^R>asP(ag|B;XO-mUb)APTYR5jLcThv~Y zSA3X{HQZAg|Djhp0~^o9^li(mtr-$)cs})4#u}bR-ReVOe4%`^jxTrCch1az4}A2# z`{2P}D&Fur!mlHUGhv(=K<7litjS+3{G^A6k2l1os)^$b(HCm#r;n{3Zy4jy{^WzI z5BtsV#6BZVC$8_zbe?r9^`oKnk*~yyx#_a_#^=|%`p6^OMRuCjl*(+Ez|NQ7Rp&k6 z(|U5&cd-$iuX9~+-orF_C_NY<=UzU}|1f6)S)aFYSZ4+Ger^)woo|ZqvG}c_KozysnoZfLW=96aUyZr&O)!&OuDX!mtmyJ%j+ak`H zvG%5nhZB}7HsIy+O5eVc)gD_|NI@ERcBN=mp#;& zIt(9-Ue`7y+NmEKtwfXBMD66)kF6chfu(sYZP9Ri65DERL3zb0SH-m>h)YmE!q>)` zbMZV{vd5U@=aO1$*P1PDP}N6maaw8o#G-+AW$tQoartH|+fQdZ$}jgUF~R7Mr2Tky zy2pGD_8hd|9)A}zX}+yBpW7$C0MGo^%&SWLq0RK&^GC9(Ir1QM@O-`QTtRQebutet z`FbnLDK_ERmqMtTq4rlGd zSjHLT)y`zOfIXk?%&KAah2uT?LcV;9EvL`3Zou50dR^aiHSGvAWd%p+)#( z`}Dp;_=Bf-o5*&cZ`2P*qhFx4G^Zb??}g`&)ad+?t{M4jf6V%gJMY-of5gX~SiBMG+*RA#0$+_cJWJpCZ^sBWFr>Sb zrg6gPdU-~EHgu_s()~E`d$%58%sPDS4EXx;2fxWZPbtnOiSh?K&U>P3Mf3!BE*Cq| zCnk&Ngzk>$iNUW(FK{Lw@~`w7^t;(}?dkmE=u`UQ)`1m``NA=yIcsKg@qhWWEu>8% z?WEDg!d{;5W1fQ@SpTtfe)l6$@j>z#oOS8^z}NXUqcOjS?~691^H1?@P;l=*ciUVI~op{Ck{NTSGT`auFZ_E6AVLN+(1@F!n z&w+1{XM0nzYj66ALVr|TuKN2)dqin9PZYiz6_+UOyS(?Oo+vyGPQv%DbbgM~pGKDW z-z~g&F3fyWzVMT%_^7`9g!jE?=bv%;3R~vo3;&25`}Y-RqfOCTHm&NDH6mA2bbKY7kd?_jxZo63ab=xIg*PQ>>BEEnHg~iafVs5^Z`lnHU zVe!J=!TE13<`j3pc=)K-J?S{lamq8BvV0!|M$Vo8LQL2d)?c=qX|QUQZ$^;MpZ(ID zvN1{c6nM5WUqY`nFYL|iTGd#%RlMdru3H_yE|_5aQX7=g*0M)}xZ0I&yhH|*{O%h% zu8p(Ei zd_$hIv`cv!m1kp|XA{pc?PuiGmfz*QaKlBtgo zkA{{s-=XCieIE@i7Y#>?_E-=Xyr`>;#2d_c6^7}N3;&(>FFo?^5_!u4|Szs}Ke9nU|5mj2fpElis4D*Oyu&KZW5 z)bzMrC|8vh(v242A1N(Q)<8?g%slsCm1y}r(elBVmMxx^^h~4WG2!~%CB228Wa4)D z3C}--mMte6E#KDnA41DlmXx*2ApNBay~CN!r>xAn!7WWqZadg}+|H$*#p=AZ% zp=FuAe;r!3EG}!85-nNRUnp0V7SfFt;2$Y1veo>#R4w4~M$tBNTAq8VOSJu^XuB$= z?PyQimZ?VDnZkV@^elF?E#~=4(ALa%Xlu~-FG1T$!_bzR7WW^@Ri%w|qYd~+N*m+B zal%2i&F)L1;t!!?;8JX`^htTyQ&T-H9aD^!1AH&s_txIR_M_u=+RpPvXqm}(;QU(O zH$uy&-fHcH-5A>(;kZees&tTUbO8HE$IZvtYgnRVaa8=G=vXXU@Og5JVIqvAGsi02!jW$*Du%boguBeZl}P`&Tid3cPQl&eY$ z=|&6ikCc|{Lt5rX#q&kWd}!HnoYC?zPs_~XjF$Ha*NNai%h586=j))Qf1=T{RNt?I zmfyamIxT+Oq+C^6NHjx}1Q zds_A$W3(LPdm#<}lN>FRcwP)G9ek(1{6^mwL(6l`W$iL#+@xGpT1YoqfPbX4JfZo# z*I_fF;$MlD8PL-FI-}(|-mUNVk26{x6|OfoV~eNbcKIaF^Py!0-+}WjeV-34E6Qmp zjWvGUq+C^6NHbfX3MM@maLZr%(Y*M+nl6BW-TO@5d{y4Gl8 z?^aA(N7iU#kHlSt)zJ2lnz)@l!t*3(o5^=*`+a?%1Z|fOLz^ErDOZ&?(v3FYA1Q5T zLrY=r=sas=X3uC&`d;v1&Dm@MY-~5)j5b>42-m#}nFF}_^lx|`4J~QDL(43E9}O+v zWsc2!(~mbp`VZx*(n7k?0{kPTMSVj*=eyXJ`TMD{|AUyr9fAKt_P_>rc7*2P3q&uz zo44@qeJKz9*2VA2p1_ZDH~EP-xA^iB{2eC@*%v$Hn|uTK8Gh#A;aAIR-R$KLKHSxp zUiQ?zuZyA&5!k3-Cr;;Yv2dq&g!gi2`{_7!BLXmXLe$xrD0-RK_Y(*}n?;``*kL&v zb{^%sHY>hNaLJDd-Z+#0{ggY{kKdGjw_AOPe&_x9_UzVU%>PZF@;+YL>$c2!O$$nX zVZLRV?+*e)=fTTA>to6{dwU2UFY6ga?ez-VGY1^Czr{%hK56_YF%RX_qzrh*cQ|we zYZz`_$*-MtdH*A^5Ee7cI;{7{Tt$1A*2AE;v`z-j2WLV%brihM9RI1>zL&V0Vb`1R zwM&Myk7|&zqTylApSLvlI7oUKzvR1Wsqll)9~7&)`|>EilKQN#RXjFd z=eMThTgPY(3Op%i^^E3O{(kb8*1zOK=6xSNbK1c6Li)b7RcqYBjXY|DVb3DtyY(&F zLwhf+F0CoRC-aR1e~owp5Bm6CwtuNvdpR=Q2hzj|;9Jj(LZ(vqMQN)}`GSd8u(hHK zNK5N^sbXx4w9{8r&yVGqk`HpuJ|H)Z(F0Nl?wHB`P_p}a=%>UA_``@&N z^-q^BpLBFnj{B4-ud|Whqc8ibap)ecIS@;ba`LHi`+(O?ImxfT(;$SGRlH|E@QAZj z%&G9zckxQ+0R9ua(04C$U(|Qr3*4QhGd)?C=v}9FJ|A3&)3ClqY=}LpugyUgXVac@ zc=obLKFQ(<;y3M4b^QhzwlMCk51 zaIVGIw4m@2^oqM1TX2>*IGItb-N858FM`Y)y;`q=Hqm>siyJd~N%!*2H(LYjZnk!- z70i9yet=t1KfQ6{|8RIKbChdrEOP#2gqL;MKtApBk(%9wiwAgqL6` zzCgO^)07`D_{2)^Y;ab@dmL*}lfsQPxDG;+x4+cDC6FJm?B|@Xro*$b)YhtbhkW+n^WX zb8FEL{!XsW=IDvPd1uk$tKxgns<(ycQJl^OY?>&F_hhL}i02ydjxx0!al^L9Qguzq z#QS50)YTmDll<_M`^e()pcMN;yG1$|6y9y=V7-_6b&r-{j>JEWDUv_r(e|#+Cck9o z4g9N(6_dthEnozE>qz3CJ?+!Tb6HmTf_=4NTYBX;nOru{=#hP5 z{ik_Z&l0yMWuPW{Ji20hKE>X{`l&PW?>VWxHO=#i4Kwne+!5Q-gYc;V`ERICagS3# zL%(?H?*DSKZ*?FCnfiqbb~@Y1Y#iRDCr;E@1fTWY_PQ}1W@_U2arNb{EzuMAzys}z zku9OVROpEEpCL_g41>-lG2KmB(=&{rq0WmeHYV8fQUy=-aq->bl2HsqU1|aAs`(dH z*F0=D;=8PV`qQ5%P4&!S%a&=P9wkc4g47zlN5jyKgRH=-mitXms#IGRyh3sKrmeYc!R+RWUGP}@mKov)08=nyejt>Jda4f z@r?dQ-Yc}u zkKHqeEmzLRYB&dFLs^8UF~0D)CfokxBYlSf>kzmL&ewn={AbW7%V?;ETZQcUaai}S z>K>>8@p9Xg{K@FB)4|uqT;@6h%_-u}kZpaxe@b3c(=uD3T3yY_ydoU)wO>^6E?y=i zt20!W#u<2HaVYd5i$jqNbs$6NN#9O>tYNMU4uS0x@XC)dd$5x&&Us8zZ|BVDiFbYH z0Q+%u=V*2LuyV+m_^CTPL-|tuXIXjdmJwihTD`4wRt22b^De&5<$pLlyqs#hHd%#7 zMmOc&L^<)PtZc_?Bd?|lUu#*yI@`jWn{A)jc*Jy(8~OVIXS zmnvr3+mEsb{>AW$<=`hg8_%3g&G`)uW*`HHklo?x!MOqbaXsIzsOR%G9~)XnY~uvu zdB88vW6t=yt0361-5#IQLVF#GXTs&5DA#WDyQU(SU(=TYd!i$HVn}8sIZoC1SS<}ad~BqrS$%UzTUW`4TlX&9wL|k(tEWG)WkidY z!@ItH0DFtQlFT~>Tz{~3sgJa`@2*bLW$$VqU}W}sFm}CKoT`*powC#T=N#O4&uv+| zRimv69PPCo&R#P5viOLbosT%|N9a8HD;T>?cQQAyIlS5%-)p&E`MW83rNwPERKC@B zOLbJkJFJ&B@p~S;jH&-}*7Qc-uQ(fZW7vNaISK1d=Fi?1=KgZ@^ELa?ZVZt@>wyrl>7|>m+=7~bvzE|@PEpWhmOBO-wS-tjEa57@>hHRrQ*xy zsEzzNEhFUPZdT4`#ka^fVe?FUjJp36d9*p7>i0PPn6X0jYQ7!ktrnLbv`c@||J2VV zgQ=9x{%R@?ActmO!jB<-6el;zZ|7*?WA*)_QnoCQ&Wae%9C>ZjcCz=qsx0YQ(hcAG zT~n|V6W?&KK9I?tux1GS0C&^>=!DQV^mkJyHbtN#D#~`wwxWX)Si!su}l2fjo({s+6m6mb<(Fp{EZ#u{E^PS z5N+zn+i4MLqYO0ObWdpiJTQ$9KG%{ML7fLpl^u=N6gy({-PC}mO+9W_JM$y_R{|?^O9|Z&dUGbgzt~m+3 z*}Nip!uGbLXT*L6<|LXo+gR%RFmsYgq-m^CeZoQeuvY$dG+|WoFAhJ>ivQ9nEtJ26 zpX5#Rsj@Z+`pIy*>Cdff+=sqw`X$zZg1?$?hh^6sMm^sO>iH%-4t3yG!#mJ{&2e9m z9MVq``zeqYuVbX6U#72)sAn8J(NyYl9f|CFSmNiY(jk&}^v4j}ahNiaNA*v&!H_c5 z>UL?qpQ)d(bp2d*hUC40v<&eb4cVx-VO(r;G>qdJeq=Zci!svVw?t3a2FP4E&V}}C zquLlggyWq0_-ob9;aE4VLY}JHsw3e26Dx1F>f`dS8jtB`vcshptnWcfVwVOoRMA$_ zyK0~BP_C?x43lpQG8*$F(ElUg8rl*^OTH5xKOX%bvL$~0a(O>`g|>w8Rx)7y0Ny@j za9^b@;bdHVxBfIL=zH#4S%2(Te~izTwJ}I~6&`xum~7{oxv!e8lW^?jYVoK49z&#g23{erRt)9lpAV@lflw*(~D$<3q{U zgwX(RbH6%!!8rtE~Wn1g_4 zg6;L&spOOF7!Bx5)^P7q+KA(00L!;yIJYyK1^KEM9CT=zUE5JUj(R)}Ya9&f6%Fd| zH~v<7cZ8S%>hr#B;V4;_4qTjBig!5FEv$+C6}%9+eEANPG%ehAIyPg8q?kIwfVscdDxPjqXbt1IfO zETeVAExmDl)}F*1WZXJ`S>4rm&`}|S_%ehyZ7csqxlLSwhx`zpZsf=4j_nL@%LO!4 zt9t}^;-O$lcJwTp@<`g@&K(Cfs@(Cw5Iq}sFXP1sb)VsAIn$NZ9OqDFz0S2Ui~6K< z#`VR%VPvbf&Ycw`KQOVoZQbyWHZot7zS}qh&v*K91{g;J<1+A8OlVpC)p%JgtqP6R z@H~lnYp~HhWeuVgxO8_URgiv zwK0>JY3Z*BKV+G_fV^%d@P%m^Gr@pUeYX@*BjUQELI&b@d zjj``8m~&LgcNwx4+rmM<=6Gyi?P@~FuIkWQZk97Q;(O7>5A|tl+nFg_yMAj=bl1Vf zao-&vtp!gd?VUh0bXV6_1Nm(c2NC(oxV=+ z#FJrSV}0EkYeuZM3cf!^mh#x8BbE#B?P})S7I+`xJ%H`J8{9RA5uYamPyK>?7EhC* ze>C9JM=DD8Z>0GXHd+}?!?f?o$b#BxL#3V!=&6*e<0+%DQ{#_#H=g&h{yak2S37QR zMz+Fn`}4dXZr$fQycH)Qyw5odyer4U9A##F^VN;pCjvuyaL9NVw2_xPjc4zJM&mW@ z^d6&ksBV%>oHk0bAbnZ8S~5{hPx!X1q-z>D)$@Bbh*^ z@x_n7x1kq?8-MSW{_=ih#@}Av!}0eU`d)qf-KP2f-O8VgzuPqaewegZI{vCXZ>6t# zx@8}{Qo6rycvSbNe?aqLPxsm=|54sUx<97xBhdXG<*%T-nY33!_a9T<)4hi0GP;M6 z{d3Su(oaX?GyZT;&yAJ!G{lO&UEwL zS;;ew{DL(?j{`R8asK;b<=@9^k2~`OTT|q2y#43|+hYf;(ixKYIxMc`d)V^@ z@b>vMR)zUAj&+sp0;=vW*0?Rdjvu!*M-p8F&?A1Q827)qO8Oz_SFSzOmr89>(SIV& zQj~2g`=P<^bc<>mChNYE3LC@mYRLT#uDvr>cIwdBmWp|jd_vf_wg*T1Er;Br>h?lv z&xxH?O`Odh$9wH5X%O!eUo$6&ui;rd)V`C!qUN7FPLtOO&R)rTx?5n7#g`J^o(AlgIh8z$e|uM*$2y&qg2Pd3OIpPwtxb<6i;y6Ls)Hdw!RsqOX|@iM9Z) zVza(V+lKcIN$$G7GOe-eD@z-BwzY8Ge*>ov!p6 zc=FaOi=1_w@K$#a`F^PRNN4(go|_rZI!St3kI!d!jDX`-%Go^#z|p-$Deh)6oLn0y zt>%{Qd;a*V{(h5~PLp>06yN1@ zk&~N?tZ!O-Z+812iRSo~@YPl=v{j#v z5vA@})=ug_8bwL7A? zZ%%Ed{ljWA$*=zjj_N7UK6jgMGw_2{=&u5L%i{LtMs4_*uCRXM)BY*gA5EIthW^x= z`?CD1*kVqvNIy=6cj&>^(AOGSJZ_)|!@8aBmCvW$wVCcrk?a+qmwUo&Pq*&35Kcqx zJaM|&@E`6j%`lJPrK;#x<&jM}hIWFc?%Qu~U4MGl8nr=_zvFK-XVsp*p|#}=ae8~E z#HZd>Z@Z&4`++#U&!3k-{`HUE-kQ6=+u%e&dhW3#y~&Ts>an4(uq0u?c6)a9Swt*#QB5v z?_K}%4XuM8h|_7uQvOvJ-_e@;V4UvT-}$R?f+Q>5ZVK*=WLP<7&t3;@sEV+GF#lU48wZmcH{X$G6-C*`yr!=0=hB?CkLw zU||y_I*Dha3)zXLRqTCmvgh|sVjuJhN5QaX!TsaumuGUjrbL`wP~u7RQBS=5!DBd& z_*mlPj^h5XV67h=;_nRo1?RdgcV{YmVHEv?Zy(F(KD%q;JH(pfae{FhT{*Q!^3{ED zET?tTPU2rXLbMkvblAe3?j@IrCaeCzLz*PR0w*luDar(gAB!4&kz^8Y< zK1pvuezPBl<#hSYNqTO>hSps!z3H+fz59$$wyt;mpzobYdhT}Q(WNiHCrCg2ldUbT zAJolH(yjkF`R)AkBt5JC=h6q3CFw2Pjgs3C%XQrslJxZtB|^MO)74i?06P@5vNj-`45$guNesisi|MX{V6JnHa15c&>8iozgbo z>CpStak(y+CSB154WjD;>2-(CRUV&?7@rc14q&Km>Zu0f>;T4Ffss{=cEeh9PkaWC z^pEOey|`4@xh1{j&iNnpw`T2OYmS^Jvl)hs&@2$wT=? zn(?du>YgRFj$acKesxo~_62lxOom?#3BNk7?#b-RwfQl)OYe{6+6EY_=LhuN?aMb) zz8I8mCVzddt82HL<)sE_Cg&iT3y<=NBKA{C1o;v^_|(_UL$L&pI!^ z>7+d_@VGaF`|+m*`~&afXScPZ<5+Vo(YnCpXCHNMrg&OOz6%}nYvuR0kKU)vHhnSZ z_-T30APwDFrbEC-IEHdOgLtMGv|E`!0rl z``&~PUvv0%eJI9nQ=rc^Za(0?FZomVJ?xLb@iaUn8upgcu-?(|18Cqp!NckUg&V5S zK$_8T1LsNkKJfj7hL2IVbP{K3_hwqoOy+eTr0ouzS<*=by-%KNI^5vtJvZ0xz$9j+ z)JHz#;jISVT=IMQUrqii=a%av@DQx9&6hi#b$z0u&0Su#`3mvt`{n#P&+$t-d@tu5 zACAt@S+kXPl+uj8>%iB`et*KRMo-@g=sV@CMD|yZ|BSN|diCCN))3imaP;lmSV13k zgnXFp@~yjjXg=X*`d57DFXzK=*(0p)lKoAG%ZFuE_&}QRVVTW!&9>P7m4pxfUrQ`E znQ3RYao$!jb4K*SI_6@}&35-X%pKmI{267{{|j3yXajyIOaJ2X?d%$wZ@lLL{p|Y= zm%^pAN%8EY4KAe(mcFrE=BPt-c^*Da*{-jY^Kh%<;aB0|+YgtA7ggaQX~si*EDhcs z*pl$@iw^J1@o$nJzL+^LdSNH?|L0~J5AVEi?y1At=Jm(l6R=+-{N?VX-ZE+53kQry2eJW{-MV_Ad_;sR>w&tQv^T*&rxWdZK zZ|Yr@O464*+t$tw4$>oRhLZz6o$mQL`lGE44yMkLvbhHJhdix!d3O$zS9@x#-y`!U zxV%d;)!}-co=Co~PnGlZSDYW9@7v(%XAhUB^Q!QaG~>-YZ1}N`ryU7TpI_p}7S;^1 zO$qPXJ@4i;_3jGNBk#*1ef~shyCg`*Cw6|olP7$Av!k-|r8b<6U*)Yy`N+2| z>8pbDP2o5VJ)$wR1HVo^>PzduaY&nzpZ%7lcDmo;lnvmkZzE||#P)_fg9lg7t_ZjjYmX4TFgD@tkNq3Om^64bMbVn#>)2L5!mibH- zIRmdy&L+6LOEy-|%igk*OpbPRbOYDxxgjzM{E+WQQ>JT0Ip6WSm>&5OeE;*q<@=;6 zd?(HLPORWMcmC=2%M-poy*Sn**}igoIm6Fn$jjOjE?@4E@_c1|4Y(m)k5i`W@^ZSi zI=cQ5y54@cbWN;67imVn)(`Ni*#if_&3e0#U!o93T2z!hxe z9g}{^;qr&Rk*s(z;qegA7W*3dl15$_VOor3FA$b8v8ceS05*ML_M>r5lH+Zdhg zL7N(UH|EOuEq)u-FG_<1+)irIOO@MXNoEIpBR zw#K%#ejQNx)A2gCegAf&)@zHIwwf0j&^OP43+n^SMSgF{TqHA%ct~hx-}rGmr^e4( zgI~vauKsMYtgm;lv2ByXX=m_V^ptq1GqYK%%Z#ddVI{WRbFA0d+C=K8A$40F&~>`% zocp}*Ksl5m0z$!xjEEx6ZzjB{N6pxv+@jw!~fsY z|L6#K(_WExL&bZ@%g?%R+xWkiA3CUXW{$=w9|ydO@o#w)$Esz}U5Y;_Xgpd-OiX?D zG~SCE^QFtm#-NHl1b%$in&rwUQ`>dJ^hU*n>b%;A)7(3~q%Pn8_xm^cy0F(c|L2e|cP^BHXH zt{bjt9L3u2BJyDq*j*o`afx^AW;?r$bNK8`P0>&)k3RS1&r&@hji0T{e*zj~UX6SP zP71mf@nbJ|Z|i#x=o|!#%hvh9Z{xk3*X6cF2HWB_JtJ+Hw%pP@z2_O)#@3-}Q@gW5 z^LJ;TX?+|!!)&y3Y0t3Ty2w-3Zj_Tvx5&peRcW_>Anu*@Ym1vyyI4Cg*AYJp%xwl8 z41dQ9X*%1s%r5*IFuaT@Ud)&Euzpe5rquHcFmxA(WP?tDVBIuh0&Ui|!|_UIdMreC2IzOA)DL(^2bcQce5HkQHBguT_rFW} z4rcw=d`CeJiS6n@1_@7yy{}%X*k7Z}i_a}QS z6@#t5npr}9;IT3l_j{c|eZj7mHb!=SY!H7vLfLge**6_VS;c-=J2&ECcXoVP+;>I2 zDy#mnME!$UHqkJEO{+Ng0x@mk|JWz&zV(YZM!WOK_q<~pvsvW*Qu3sTNgvfz{Af+|%SF$O%YPt{jYX_q5aU_Ql7}-Bi`$zg^kk#< z3Ek-l+${u7izz?3sW+8rZ~Z!W(O2H6c9A_hu$c3|np=Ceq+5FwpCVaMJF8#(^@3P_ z3^sKS&PP_Lqi{}Cyyb_*jeF*E?(;dE)2zLdTR1m_yDhaQde1$@jRWWF9D%o6e7Wx7 z6i>QbdWyFCd!D(grnv7``XRXI*yB8SLu54MkntS-CrAGol#HipYX?7)ULg8(j^^Og z_)_%DJaTY#j8o=3@VbsUVui(~v@6!k^4#{J^ha0q+YrhkaiBo%`C0 zIlkqtjPY6M{i1Wo&$ozg8XKlG;{!XF`+=?s=7T(|tp?^n-&M3BafMHPzPM314T4kl zl!&u_()nyXd^m+Xv-n?N__uX6AJ?O@g;~^-k`BMZ=GdpraQqNmd~4xbj`6PrI$Aug z@b)6oH*k;E>RZO%lS_@ct@e$y&s=`uJNry#LnC`6Noy*OxgaXmF67&J{4U`8jHozf zA#*$0B?p`_SMvQb@oq{__Da6bL?)s8m)tMXnVv!n`|qS{+p+mgao{i0X+X9^D;1RY>shq|I_1O@X;CH?FF6m4g zfAqbpe{#<>(giaD_YUyGCuen`6N{O8+Q;Shc|J{^K4*Jao>PYA*(5q$xh1ZiH1%w! zKEtE`YGUY5;P(#2gtu*S<3^l!QqQ{`PP)tKH2A&`|4A);-!~C{FQv_w!iP!xBbVU! zRl#IVs(xSG`0#$t@t?|7lhnt*eN)>{Y$`s74@Gx~jadb}_t8H6Q+u+jXrD2_dLQ(T zl5CjV*6wt7yJ!r~oYAykoqH$VJwDflv>at}+H=CV-|lGGj!mI+3e|o2$c6=)>Wi@`K>@=lq213E-7RClH%+s8Ma?BF0{#RktK@fNu1ztTy$_?zhj z@hB{>n5|LhtD~IG5*)tAy!LR=4I{xY+F!g<`&6t?gu0Nkza|wfg-+?#?Gg9f#(jJ6 z8=PU90?*Za+n(sx6#h0#`v!Hgr=f=Tqquv1;Oh~0fhYS!KQ6jI(!2nll=ZW&d2ero z{zVmeG8lqxn8Z^OvB9=c+WD4uIxSDaS|ZCu*Frf2lLbZ4dQ9@^K1FGLIM zJL7v{CT9USUmyBDnWNOjx`AVck*53`w99!E$(wx&neV%RIoQG zfR~{kb%S?~Jd)K-UMGFQbaLE>m|tXatPM#=jN3H@UwUyLFeJyiZ?9q1X+4~i!dSX& zfA$REm@Z+T(J=Y3!ERIA`?jk_<1aLKI4R=JPT^&Hf{K|di5WT}@G*~{GQ`h&zxqG8 zv({IJJ7Zn%h2WDL_Z?y>vSai<94*p)cIOtfgyrb3V?1rcl@DoK?{Mkz=SLYI+j}#= z{vY3Ofp^sZxoW&rtWwBJ>Rnyn9>&ZqO`jU6Y*_d8z{niU9OzQFKjzZD1(|1~w)>qQ zUvtLYr0wAhlQevJ`fD$3tV_o-BL1y(I9t9+O}!s}2s@E>FO$Vpxt=%%4Orwk^Xo4S z$pf!%i(Ffm=F^wbKJt-(o6cg4V=|WQ-!Te*hQsIU!Y37vtHNPz@NL^6aJ}>}a2<6B zTqT?G?~51f{FqQdzt`WAs|<40fDRWwD*0sj&}pT7f$aM}puTTBK^OcE9TlE=C_gGT zPt{*v4W|Yk;-|8m`~+tz74GD>oHCU@J+13qqw}l&DE0?L*b~G0k%rqBSK%iV%%9>@ z8F-~@Rp~T(cTD$z{`f2>?;DYC>E85on-g})U-;s*#_b)`IMWWFA@BJ@FThytJ{&%Nb?mcVhlLUgf)9T-un12dAS?Y1`Omf`0dK_F>n` z7Lkl+8I#<7w_|kQt!(4Ux|LV;e(AyD#(iU&ik)fpQBkMH55cr`MPRL0ltEtrGDEhicYb;wkqrLlxRU#yE@{%qFun3 zjCOYX_}qa>>^a33K)+>u3f*!MXN4=By{MiJ8~dQeWOPocbqG#DFa_&f$=K|98n)BBX(t<-FN()U@q_+tGN8r{>$qlrRyGsqvL|Y>Cp5;&rttDBInn*w)N|X6QBm(! z_N-NYGaZ{153nn-RktF)RrAnKEf2Qi8;s}3{|J32l+oe(PK=+^0~LM8d<@X2J~j+2 z^o8rgE>D$yIL7xw@l!wXE2A-#KGwh(df?`Zx)0*J=}Rwr>R?*7YJ3;5KT}HQIyAsn zTU&V%|1Pp-u@mSp?YsBBYWdCmxe53$<2FTCRj!fzK<66~Kaq0&_^ubPX)L%s4+dMb z0L#yHYNdBnr%Ny0ryjT2YPDJAceQt|@v};~xE)tF(2nAV%9p(?23Bh zc9I;Gcu5)K|BZmBv1O z5B8qR51}?0b{~2;mI7b!z6HE?Ht z9>r#Q94qOTE*_5FxSu$lBTpH4zLGt?E^g+|3&)Qe!gGAO#@mL<{w5mfn^wPlgYR?T zqvx~QSvpE{w;#sw>*9ZoygAYaN#h@%YIb#LT;qE!-vu+Q&&!SQ-#5SP`hd@0tC;4S-4`bKbC^soLf2^^Rg89gChJ}tmY`Ak0J zG^4AG-njhg2GIr10gp;~!?m&f5sq7aJ?>x6hx7CKHBV6fN;p2f5>~Z*ns4aW!0+#X z=l}J5IKO9HIsY$MDp&bm2}?96E&Nv*y$=&3S$5XjYkiJacy^pWvjJaKuh#5|{jzhi znQPhl{gC8~;m_*Qdac%`X#;nDZm>4otg-Sa&d5k{ zMn=3IFB?|p+v<#d&fLl4UnYK*`4IO)$%m)06Tc0(#`kwU%#1NSM8swLKv)M`1 zkwc$p?1KlTIRkyc&Ph|>)U)^@8@5Di(9XlbE5#*K*CF9G$F_P|->H)3?`K2j+$H%E z|NVV&UY~?8jCKdd>+eByw|o|*KKdGc59{@~yxKZn3Cveg=05_@L)Cdibaa%*IC{Ai zjAe!W@fp3yFY`9eLl5HV53}u$2$#czc|`O>U#N$x_1`1vZvnsPn~zuCqxj8V?BA$9 zruFL5n3vHUOk=0cbsx&ZG9IA|(XmBzY;g}d3g42QOaC0P6Y@)GPB}>2!9H}M)<>>C zP}r$)nYrF``-t@+oq=(RR(nAIGe=fGyYo+fB%iQ^4jQRgp`g_1T>1(rJ z*uw!Id!wT`XOZ|Se9y9dh);@YHMhudz9ICLosCB<)Loe)IU7%7gLqH72&Ukn|IA4+UqgL}wACEMn zQEl{EoKgG9^R)-8!Ul5k@}I3O{+Tr;`o{mW=LLV2efUG#Vx+lX(0Am6ta=`0l|K8P zU*X5q8VUL`wu1tl+@bRVIVtbzPeFk4Y9Yq#3fiPl%44&ov!tzi=UEKU7)_ScFhv`JTba*v)X&jrk| zUeMKXqOIq3b-a^vg*meeoBia_m#Vc$zJ=>OzhI16?tIRE4PWIwyysbe2;n{KX^Hc+ zmFiq^bz_6uudQ}u-VD!#2fkZmMYt5^Yc74we#Nlvo)`75Y%FfvjsH}3fYRTqcl=*_ zWCLifJrjFuZj}ExKIpy77N%n-RVy0i`&PGw)M!VYI(>}Wj?W7s)_@N8W$9FS}uUlS3 z)?R#PV`gkjlkuAN+?*z!{7>ui|GaJg#=0>+{-#_eZOv&hbIMyC>{}C_J?ziEUCi1M z>7fiZfIIDIx~35x7WgjS>1;K_u_J*~+TS5Kq=#@$2;g|W70BaZS&TOCs$cS`eKOtN zek5J-=OepJ){u}yKTilD!-?OGg3RCSNh|Wrs7H$FBzuA`x>sbN z=D$q|r^k zTQc6sq4X*-wxxdQ^z6c8haOxV>!Qo&$1#BhGw9b4!_Ppywq|&|vhb%x#wxH?9$H%zqfeI2{-t@I09r^JKH@7hUvY&3QP# zWxxDOhR*`pi+aNLB2P(&o(MeWPbIb=eaT$uWPCMyKb6W$_WIm8EuHk=-PcK;Qx*?) z)&2OyT+E-Tc z*Pr;g{d&9nS-RI$>(bFU=W_(cUToGk_t{-NHpa&`S738jgT*{{FYwA>F@N0)yf1%g z1X#_&7izFuhRx?x#k z!OcC5HtadY5$ZWzk1WFbuif|3M*8g8Y9qnXnF_0E+jpw1$tM_lD5J6XPe|_!@;=A= z+sNnYv9WTvdhV%G&t;TXJhjLF0`UI{Y0I4rGeEsR;wOC_DdzEe@C7Tr zvIF>D9t+UH_`o_i3b%|^{=R;Z*)`dWZ?QS(DN3ccg6i7h=HhRXZh9D*7D1D%`0zf zqYWLYHWnP6yRo&Iv)0LPHWuyf?L*6pj>acrc?-1dPQO1!JYw8Zd9T|d#-ev>oO3+0 zxFTS8&0E$e`{r7{={!Ks7aP;T<0npEs6MlMLVRe0A^4DHFyOtn`ApWRM{>4^xutqLh@oVNPD04cIZMTBoEd{ zNXw*Z+V+<2|3JR!3-!p<7u5gw{==;=ZRGBRvqhKS>-$2!qugzeb|!VwSsvEs6Z8JR9tMpFnq1^b6;& z?vt7jwi(3NJ3Xg|rJ<#Er% z?Ht$T@+hu39huyU%CmsmE3h#AwSYZlA-JAFUy^OhQ53FXP8uh zR{$O{1{T``KZcL(>8~-AJjvFSPF2@rBlOU3+Uk>b7E6$8>zH=wa*t-TkJvlAlEOnc|UaHD88)vl(Y6Hk$cT zWHXYcGKJabwQ=#7E8j{zW!?qPBIX(R1vWAlcQ(N_`>`{zp`34#G2$}vW!!wkm%W&@ z-RNRVXADvLVx=*D??Deg!#DF+uQ|a?nA7izi8{D@KyKiUmF1ka0ZLP3pOa5HS%lDY2-a*=Y zr5odX-Q$5JK6St+KW3>P8()z*#tXA$eEv}mm#Z8u<9L^Coek)D`K*{0=3Pe1Q4Zhr zP;ef|A?i@YxcJSFSTyRz&Dv$DVDUATmMp@>C6zG}J;FxE>xH+67lAu_fXK0X8P zl2`f!Y0G-h9e0^7K-MFFo)6!}+da_7_-1oAqZiwUJj8)i^dr|-n9rB`i|lO0e-P87 z*wNK`FWefhpOn_gIuieZ@Kk>j4B@Bw-5$yp;QP@2la$lC@NRqv1NaQ2S5oK|{nsFO znp6JbOD|Q}Npatnz9_p3GT<5W1&hPe+COrP4bJ-V#T_<(+~n-Uo$T!?jsJYlOg_J@ z@|*Os>7{4SEqyCs*Q%W4K{(6rl!M3EAdhEyPt0dpmN)9V_#NN57VtX2v0A%63;%xV z_~+aAv+&Q_7h9*PO8f4G&(FZ;8^|Yn$l4j(W=J~+ZDl-n<3eUEG*G_gbm{c-pDMFS z!+8xhDY1=3#evDT#MZ#qmf70fF=M}Cdb26s;dh)aQ{T4E;RIKoWlq6OMFltVU=v(qx2H4792X5-A&Q89Zpu~)45@V#vxYev~k zixyl+-rP;ob+_1Q*-bSIl;^ZI^g!v`vAtkmoG4sSR~Li{>G; z%@rQ@IiGtu)=R9V>6^75Z5ryRYHcYQH~8b?yy3ljeOJWrCA;0aKkN*54_S~N-pAK> zL6SdrJNI?Dd(Ma&Gdu-n)$QEN<vg{u^ z{siga{cU{>psCjm);lfVf{Gnb-TmC57M)5_+;zg{SN=d37q); zHV6N$NxI!{_GzU!)tejZ z?p16I(y7;{HwFA@c^mEM^Sk@xN^&yJ-NSf(0w?=D+SjE=LAv;#yEx9@wFi7ybqDYroW2D~{_q~Y z_A`U@aomIXhYtUMZ#nUEgTp`M&+|!o-{}dQRbzFJpu<1J^M3N*?%=;M$=^b~{@%>? zvy=4P`;+v(c}e3sno!utr@XC-jL z`v{xnBJ_8A@^?Q^|9#ZK zpPi%|A6$ChX-RtS=kVX9M?rdcuV_;)$RFIN7}X`|;eDfh0UyHqMx!7-yl=GW)CA7@ zi|=S%KQ6u>vHg@JU2t-z$LUS457KGhmP_LFC`=!l+*{f-Gs)lbp!$)6e{zzpdb94{ z$G-X?op$&4K}KP^yfEzqjD8{~mny@Fykt!+S9!xAtm$fUaFGf8X&*{z2*;bm>u$o)KpXATVPI%1m->o|v{^+Gu zKabP<0zTv}`DAPN>G!SC{2~g{Tc9_0ah%@d_<(J;ErZR5ZB*=#Z7%zYxz_qmtZ&`5 zE*=}}Qw|q>!!`=-oVDS%EH;1TUUgzSGS`kW_^W{*)^{E6UH1JL`@X`z?;dUM%l!Mb zS$lsM@73_D3vmGVUEh zbBfY_iz@cH)~V%7Vt!<%r@FN}&W%R3pVz=#Vk`5ZCFA3HkE zd@xSS$G&@gTgX_o>3a{XdCY(NbnNo!*|yF+}_SsprtE#1#Nx$QaX6pvbf z&AK-8wyE3`J?69)VB#C=t)(CCy5tV->3(p{PX4>z|G=6HnJZ;d>+LMNQoZ>8Yohii z6(`@y`Ved4HW!75y+-4vm`2SJJuT|vMn|fghHKG}3-5SvO%reo{udpLFAjwf^MNyD znQMl8&{{-2ym}Wf2ItGy@deHU&8!xW(Pyk1a|VIhM6ptr#qBb9j`^sPc5&Z?Z|)4$ zjh}_`#4_1jkozq651wOl-wE9_r#IqvEl&UB%Nrwio=ZaKWaiFO&Jupswv^Lc_%!g_ zH#6#;4d2V#V8Vpl8{;+*%=dKd-?(pP6MT%@Y!Dpq`_y(%oZhJUv-#I%;R|;@2<20` z+dkvwufmz{s=F}DcsK!{XJgmQYZ|RAzR1e5-~DV*mhV;;-=pN(_{VuST@zVTa&vcL zTuSHl>f9RS+2S1%9!!J>#~BaCNWSAd=HE;5oIsvQB|gQxqK%NvLVCHu>zYTMJ`Pgt z$G1#+N&F3bsJ8-UQg3`NNz9v%Zm@Q$$a_5XpHNnRh=XV!JSpnknR4~H`h9vP<#6

&v(rtx}c#IM>K#y9x5hLEH{~Qv_q+!Ym)(dVI%q96sNPhIm#0QWHD8d z!}Vt2%D68dBK;%APtW6{y!qyD;;c>DNA*c>>sffRR#qM_Qn5dv3;RO8Pu5FIXHYYS z!4uLL%dx%8ZsJ_xZ2MHT7QZ%ILfNrI!BXDF0*1 z7_XI=I(9mq%idv6wx!8ut33FAikSirq;_b{gKJ)iY2@@=Ai z<=aiV&SkW+%4LYGIa&S1;6#kiUe-^(1}+|kx2G0???b{dfWHGi z)Q|06(_NXqc~9fQOF!AV3BR$?h@E3R zMz-%zUDz{wu|(va{1J_>}^e(4%)h%zGW<~WLnS9ZT-*5ikn+5bmyn&+&+{04(epA zwmP?+mY<+H8L#Po<#m#;ROgpZvpQ$`I{9XG0#kLO`>nmb?Oj8hfcS6;v|640ob%^m zMinP4o+^ENv%{$w+n+qLJvSrQRwm7yhx82n&i4FJPI^yq*|ZUHYtpwo(=TjX!e)R5 z+q+=t4-cdS<^_(>|I2`Eg3o&4a ztE(+G+54Z!nd_A>7e``HU^JT?cXx&cn*Rl&#_D<~eGF>}NS>vN{lii$J zVs_1L>aXi$oOUozV%kex zfuF{Gp&ZtShUDx1D}M(^;1_6)V@>K94@zs_F0Jx?#610q8#$VF{c`_;KcCEGdTlB{ zFf%@TMK*bX_V9B^*%*p1pzo2!Kl5PIVT=z485{78+(rGZ;TcJlG5#i}l9##IWAM1) z4D4wBBhp@GoR}UmdXYUr$;6pG^H`^YA-!gaXHhil%;KZSM6Khn%(Et2ED%!-PzLhiPlvveYf)!>P|@c#LTASx#oYfckc0Z zRb}4ar>B9FmI{S3+ix1_C-v|b8$Nq|n?@9)`b?X%84`y{6YMnCg;|Hvn2 zKYQ(Gt@Yg2v!1oqv-oZMq16U-*7o$^3m*2v*tVAW()m)nt4p~JpsnbyJVfN?%xCPnTDp^yR3-{$r&APdFcSKKi=0AI~&NxQ!S@8g!SCn6pTOSo?p8@SnPI>>@ zmhMM}*@rZV_!HwnGcv0AJ!iM(=sTU~)R<_$UyF<&^V*wdx~h4DjgR%0awfpWCY|F^ z*&IHx?j#zc`7btu`9-piKF>b-t;B~K;ep3fzz(BB-P;*c_I{0QEc;H_INj6I{rp>p$XtBa~=^M(oo<@!%cpcJ={%l|5c(VEy@jZKv<#R3Fg-^PL zK5wP38o&DJqd!M+%$>n`5cbpmEcg}d^mAR6qRj2n~ zgd4cWeQ*Zuk2&0;Q<;2(_A3AXa}vmB!T)gcsFyD%!46`jWp=`iEwWw7_!8J0zrSf$ z^Nh72ml{V$%QKeL>Dp2C85`jDQTn-dKRSgCAx06$o;6NuE;zXLzb%(RgpCDy-?&AFWr%O2d0-Tf5I2~;?o+!`iG~yckFY)W8zOO_#n7^<6Wf5a=xr_(r9h~p2aX@o=!_7FL{j)mrAX!n)a=)kYI=9X# zUnt2_&N!N!p`@&%YD_A@suJ2%3!#!x#q!Z@15q4=%(bzY|a{kmi4 z?)PczTI}XiAJaSGy0APaxo?-%%UE>bM?br;k-Nh;^Z!u(UqCw=d|W%|hi~WK^Zp-Q zzZd&^Ez;${dokq}B{_*>dNi}InDb-{o3B}Oht89|Lv=YHYYjL=OUAv$5Qlr_B??HZOUfowqjs+<&Wk zjeL2XmkV>GYrfKfU#dLmzKo~key;smgY@sh^LFc>WA8VAdEy#9+WXBOPwoAl!*?U` zXeafFF6qCpy$kU*%5ooer1p+8u1em?1!QO3KS7=N5yuJV>#V);yGCTQUGMywp7d=s zev?1{D;(&|N8|5}m$Ud@K7#HvAG4yg|9=K>#U=3_hd4ttG<;Ijy_7QAZ!S6>L%-yc zv~1z5IR9n8`-qP!*G6y0BPWNsA^T6F4d|1~e|;uTKkSu`>@+d`}nOk$;ZA(A;?w)|o^tnK8>Gf`(iN$A? zzuG-NOw9S=E&Tm}^+3_U`S=Mvp#5;rKl$+%i}L4o$TSVH>cknkRRnG61%pP;7ip9=<4wpJ$*dU`SpUazGE>v+Hj7_ ziVur@4377vSs$w! z6S+>gWo|pPIRDNnF%iC145R^E`afDs#PAIsT09bbF+T(PwpRLImS=@Aa1Ug{+u7?S zSLm#bPy4hlRBnJm>g;FN74i9aE5mu|ANevqKh#C;{5*P}oQZn7Y{}HMcCR)5NZJl= zes1{w`TOLG&k~QTW~UXqSHI+c$={OA7&AWB1)Yr*+{d2fzxjJY4t2I%zCd{Pp6~5` z)B1X?r%NB|XUSGu9eiJq9%Dy!E?)T-SdTOR#KrIJcRRZK*W$T-AB{`CH(S4tl~Igt z9)Ax*Cs!`1M|E{wbis+}qLpo-+(}vZ)Hgp4VC#L~{JMqk>dv!myz_UMv7aNklg!Rd zt3Tk_;q1TGKKxkT2Yz_4Ts$a>2hjQ+%9Z;v4(O#WFJ^+{L-CD7DrXgh<2FG%f<3x zXHux=%ogS>w8_Rx#w5v1wKMtOWj?6$?$6$yeJ1}~yw{xTf8tF3E!4Gc7tZ9jR4M-| z>5}?fMmv+glpKCW&sxvqyZNx}aG|l~s;J8O zP}Vw-t;!Rn&{e1mGcv3*$&?lWMitUl>b0JqlKGGiPaBXJ|ze2mkNBJ_;W#gZn^@G1U zYj_%MkulXe ze1Gu&S~B|M&({4L<$41jakPHP4ld%GLe-p;CA(Se+~iyNK2t_2X;8}7E*e2sFY|?$ zI~P(m4@&iSl=@}-%@YeEPPL%+zLcHOw()}axYi@(e=Dviy=&&bbQM3^{9e85r!LKv z)OY=s465#AJfLlV>G;A}s$|Ic$o#fItVZi5^l5n`b62f*YsYgSd{r#yN~J2A2C`bOn7ztGy%dwv?PZ43WYt>Fgsw7#j*4@=9L+9aP%W8n)Y z4qFUIZ8#LzpLi~_!z1+5`a_%4pSQ5LQqR8q8=|92?T0RxGf%W}A}kZk6~jInZA44T z=9xq3|Jdf1?o;lteUGN|VR_Nyaqeyt{_?h$$KK2b1TS;#*f-Rigm{hliJGghSIo*B zfeyNPC1aMKYg=9i<^$fB94h>4OSkqwYffW*!-w|!YJBcVd`9px@8De+!_@s_Paz}Q z>6?7*_^w9$cgpGh;pQcm*!-r~&*e2I6Rq*t$A4;A_sGWdf(0$wih%%pfBHZ^MevCrtMoGjxf)~XPhr>a@tjQp!o%we;FRl zLx_*bUf-4MEu#Oxt^eqUkCET0{=+-&>M-Bi`a!u7`;Wi+onp{`p8a=W|J4@X9_ttF z)7~P%MvFh1471K*a-#T^WO46!-S+e7Thf2c?;GK7xJOC)>)?v5H1MoFp89<#{PX*B z6c4oasr|fbM!sz>VN*&$B)t4}Ko5y5x6znWW##ps|hh+B@y<-}c{I8^EV|xb_scVW+f@ zB^>KR8z(B7YkRV=QOO5|^`3vQjvcd%fYwcG^o`pZia1d{xDs(YD9fhkR7j z{RzHra=#USDY)O)3f>c!`3S$smtyraM<3UIic9g!p?&mB0UNa)pUCR@@?I77G(8gI z(E3uF`+bRUeLIHhtXpA2{QF{lcRBcl{NCVxpU>|mS4L;u+T3sDtX%AVD@MQ6{az@z z`&K!{mb%~U$D7pTe(S7ToBRDne)qe!weq{*`pw*RlFqk@PXik{Z$rOVIzMo!qtgkz zKh~9L?v2YxUkaD!o>^K4ZIA_Mv;4HaJt}C^S}}Gh&fAF1yh&#u-CBpe(^$ox&Bf6^Hip;Pec?4 zGB)tv#vZ4O{l~h!&-h47-MZ{H%=u3oU0(7kIxLh*_+B(Yg9eJ)d@V(#JmfxS2XmI-DGJ>MuTm(N^P+qn}@UUDIWgIsA_(SpsLs>39uX}Hz zHCiVr91~rxxZgZ4qZ#E7)ZCgf!l!e4^*QBjZePgx!S@v=-f*ziIOLb6>(O}x#_-#$ z9kjvvc|g>i<=ck-WWRh#V!w9o0pGGeYO=XkFL1_qt&b(=$tc^6eh~)^)5I{(2TaoL8eG2caNn+9pFT9%>l2qZUce{MbIpAf!y5pmxghef zY)qr}m6gMki;xBOm|v7Ne!=%&BA4Q!-(wNBSvbaW=Fhi#k9(e95$-h@v5n(1+6b(o zjR8z;Z1QacZfzW2YNMyS#^7s_(R-2gmS9hh;utEU*pB{>foHe>%*Qf<`BujIt?@V1 zKgaK6%~j9h_kQpj+&(sAa*U3&`E#s#r?SYBAM5QL4`obO(3`S7+>{s1A3^pLIXJ|X z)%@S-d|D1{{nf<*L{pOk_E#%5P)6evOf>HIdP`ZOG4**lP~X%Zqa*!z{S7agtor`8 zfZYpWWqWy2V~0P7l2ylk{{wYAxvZie<1_kUu(E!n=-dP^EN8mgk77EF%`*9x zFS2JU4uu_)FEZc9bl~RzeD&j!{OWfjZ=G(RhxUB5C3|+^DYi6SeuBUe8)->SMCm>e@^NDikC4X;=iju{8VW69tkYleRRmuw*L9P;)oaQyG%ROf4* zT{6EQ<)`^J%OB7xD_|uIJ*#xe2$AD}$>vW0!a!#f(=XB0p5(|E2|!9Vz__Lt}P)!L0a zI|)7iT=%2G7du0vGpdT+Yu=%@78s`=_r3!2Zu+fU0o{si`1kA?I>+b|zn`cWbG_c% znhm)|kR{nLaP6zVuIHwmsMw&s(HczuOnfPLsdCb#u$;=gl>1SMiw}Krf8|;ZY><<4 zjdO`?cZ|M{zRLF#8ujO+(bwgPSG??Z%)7Qn=ta`@z-L~XKJSQ*k*D15hu?g5RBVI3 z+UwVePSkPkw~u=lSAlaY|C=NOnlHlh)vmAFd#ib79eh|yKDrI$qtmnTn{j3UA69&` z@8r+<@35=#2g<(V*}jv0+1MW0no!tg#;xtxbd#q~UaPhJ;GT(|Kv#OmACA5#kC~k_ z?wB(8OZNOr&iWtL`Aclcm^f#M;t)%Hu9QQpy$_gN0WV-DyMkDu?4I8JAO2)t_TIt1 zTbp>*f^ta>@NJ2CD=1wbFiV!89%_W*@)Dx8FO$uQI&>N6Vb1y2K|R zDm?Rx6ZL(cn^U4&Lj{L(UI=q_U+ev5%BddNv<*=yM+$oSjBKjv+go*x@Lpy7UtDk8 zR>ceS9rXE{Z@0&(XXy`juyA+e`GXytd%ozL={g&H|Mk83A_#BOTxuXMosP7gF;0Am zzu`zh7iW^(9%t=>_OfGl zQGN^c@Xc*W{~m_!3BL0OH~2M8`moslrcaWKekT`kUi!G7+u1`bTvgAaYfPBlLc8O( z7dDpeEmU8W>(I|}pl$c+gWC7S#~6n_yiI$iq%Xt~yFcKbRacyEJr!qBJ(Pp@-3xwo z)548s-uFKFe34tn@5cvQ@R)M!#_;e?kp*wOdEtWJ#PIN55y4mgHin0Hi!As!`2R7^ zkr?^23&MX7xq!bA!`Jz^mxDKd$(0Y=^Xgm3-R#PjeADg)A1AlzO<#=LAL0@GlQEoe z{hVfK(NC_HF7kEDw&=O(3G(XQ6h9xvbK9GFPkv~sn1W-L!B6`HuBo zcbIe?am&J`v?V?$6*usc=cYq zYa?$<+h5;n&*B~H(Ix*$w%hS7%8hl!`_-TT5P>C2fhZq`$* zTww}1x48SJ(c1&Q)jDrIaN*(mS?FwRcacl2{Z^KZD$DBItH$iBepU3Nr+glGH+i*W zcNL%0Ija_E&;kwej4zw>`8B_6jfzF?Ik8w=Ft%V9EjD3e1a#eitcLZKjoBT+9+$vR z+HycNv{i8*Z1vJWf1CVo^cuVPfcl`gjMHoLAJe|Z7bqi}&sn0OH9CiZy_P-14w(H* zmtRSF?Rz=DopDq4Iu|XY{q~KG5!mw!{aSI8S1NZ|?8)um>wvG4tet~_z@!)>m)vs?})}-+!H%@cZIckHogK~^7w#WYa8YA?q zK6p7*p8{X+t$e3(u%h3rwe@1ZvikjL^@(>@A2y}m`{vko`3~ElPs5T+$lZ0yk3QKL>8rH*hxg{;lZN+lZegpTP=HlFUvNMv0Q>ec#clo7WuJpVlclobfeg1vnV>vs=#n?Sbu*6;wIk@4V8Vr5vet13XG7nywm=-!+xSJfXnE9m zc(I>#C*`}knl^P(r;TMQ%YF4h+54l2JkhS~2V7a<*PqdvZ|>QSPkc6Wh&=hl8jdS| z`~ zQhA$JQ};H?oyPp-G}`I+B-+{l-&sAx<2U$qZOUT*F7H>Lu>pP^UhAeBV-$NS&_`R} zX0G*4@9XfL%3xE*m#u+QW`44k6t`^~<@kPl;mqdv>=yV2D94=UIJL*q)tB@1P5P4V z2j5yhG`~yy-|V_wtBdyG6$&LON8H`+@D&vl~4UiY(_70S=sc^9uxCF$7lsyKCbs=+r1qH zzGM&CVr;y|B511nu`gvz+zxI}H=BbZ3tFF*PAmw%AL%=z6FRQ3!hd^%rxWe|uG)=X zh7VBI?iP<9_-ObwU-vPW@;Fs#Z_QHlyHF?oVOu(g_qR^LzMQvKcT;S1^NMTTSVA7a z!4=?f(b2DWg&QGzJCpLF&KQiTQ)H%vmg=`@&mp`b4xxs6+GaNKHEP?;s%^W!kgKbuZB{O68?tz>+J+2WNZXEZZF@tN zwsl=Wj#g}Lc%a=tx<`)R??_V5zkKEW>n&Un^!#ncm-^RiDkw&jxRUY^Cf{(Su!Vgp)J z=C14Zr{1YE!q-nPe)t;NML$`8+IIljh*zc$jJ=9I$UcN}sd3lGi*kIcJve21IXcSD z?kJ|+-Jd5udHszGZ)kS+4*C0V^4RA38yB*>>wVJKbs>Dl(uE7M;1}PJ4Ig{M!W**6 zpL*lM1#KDl!PC4T8-BxS8St^R^O6j>@K=EkxVt3E`bE7PZ^*zigMQtZ0e=+uvJ5!o zZ&;H7r#;OZGT`7D7|4J_=hgM@KAe#Ll+T1;zjWcotnzm+UD!N61CRLFlmXvLznU}P zci*^hV;1~ka@ozwC~xwU0lyx;WR;&GzGsyOzBmI;zXr14(0SvMjPhfla~7QTXTtBU z0>7UAUXp?TQRtQhp8>zJ;IuOn4qsN^kb!?Jcy7#qgMVWdd@J(Sl~I1{(uFsy&VbKY zmJO%;#;o!eQ*Rdhdgzt`zv1z0c>SaB_uh>5j0L_S3l80~;1|>1jTz;k^FSsX`5(wA zzZE`i%YX}i!QF2Y>Z9;y!G&jBMtS%nKVfdZh_$F_-H}C&<$vtQ&tYEhA0ECbhVO82 z2K=~ubd;6f=HTD)@V#RARtNu9)4~Nf6T!-7Zu}qcMMtp!eIrvE)es>H%$H55(#{IfKhQHatkMi(!F}%&en>~DM44?1d(>;7g3_sby zr+9dDjM43Q2Pa?{*Sk*)Kia`3didlRKFh(!d-&`aKEuHk`!fAHIfhSl@L_yxgP#$@ z4|MP$4}V(>-`ByP^YFznd@l$8jfa0QhVS9vPkZ?FF+6hcJ`cYwhClywtnWYZ@Xi?i zdk6n_55F&l|JK33@8N4>c)x>h^zaQae6xf1czACN|EYsN&-3sXWBC7Z@V9#SUdI~!FLUs>c=&-a{1OL0-NR?Z z@QWQ>b7Z5#aWVXS2S3HbPmSSkbMQGHzBq<2ba0)gGdwrN@G~6z2oJwMhQHClXL|U$ z7~bOGjUK)!hQH3i5ApE+7=E0CYpv1hEgWZbIMTtjR&Vg87~bUIT5B|TOAJ5M!Slei zFF|wUUSe%!`!yA>=iQ=%!o4CftbIia=GO~|+hcPq{x!f_fYuzEiS27mV1kQ532yOC z))t8Mb#D*X6Ifs9|Mr~+3$8ZVeA}--YCVDVi)7zQxTe>mwL|WM&rcg%MeJYkxmoP{ zBKE-fmkUa3c&+41<(asF;aBW$!^AjNeiw6nwO40#Iw_azZ@D$z-*Ope=ZQ ztnq>5hQECpMRp`6c z>MGt9$nU9lM)!>O{#)(Y*#_Rz!Mh#2vvT8>)lX<&NPKcm*1HAVcT?@%l2?uJuF7|o zuZy~t=HorX)?Q+kO=AX6(C;pIK>V`1aM;F!6~{V8G)wg-S?g0d*6p-z{5#@zqP6&< z`0?9+r97W8p9Np_!O}hu)l>C+JTmC-gcmMin6~~aIaC}}x~O$x>6Yi~N^mRI?bmk{ z|1OWK25WK?*avr5RK5-;*m~Af(G~5(x3xLJSeq*})4x!Mph-!G%Hmt}JI>3|N4|l} zpj(AK@Or*Js?_se#`T=(;(*qMEPL?jU9blS?TS4p^`(9h z{=H~Z5Knl&9-C2^Y;?OEx*0u9zT8@7ReEIg)7iZ;dSLS^?4xWRZK$x1w7tSUipDkD z#}YkE)&kz1iM)kJIG3 zoqEsODEB^{?#_+&0$YiV`TE}2v|A{53o`B2MfH1t@AS~+jn3Z-^DYEtHAfEG(P&#>^SYq$5-TE=;s^l9k`G+wZ=zh6x*&exwSnh zrU#OXw$bT+5AEpW&*O9Yb^rWd&nUK{U+1OzS0L_FAdWK{{g-FqJn%5X*#^#bx5l(s zcZIE=Tr6l!Fh6yW9WdsH4ID5pUh`(}LH{kBC-U|Ixb(VNYvQb_^v}dMi>=#z&&!*O2+h8dsmhnh8hT^Y~^ zcm;iUZ}hn`ppVLlKCJGLmHINM{KXH}z5 z$H9ZcFF5+V5YXp}fIh%0=)-%X&lLfER8I7{D4-9pgg(MA`cR+I$KlPQ&%3hva^Fnz zkEf*Rb20Oa8vLKLvT!~T<1D0cvNl!=&Xclm{yN6_++Ha=P-8n^orQC+ChPmp(>QBv z=fo_Wvtyha(>QBv=ZoVrbo`7M=L2b+HMaBVES&F-ao(B6Sz|k&%EEb5jPu4c&KleK zP!`VnVw@jH@rn!ujhM=jmyjHMa93SvdDAW2@~HptnXIp zI?ju<)wKi8*yT&16HuSVCO#{E1dP1hRbZB@FyU&nl$Tdh9FNBCbZH#PF{ z6IJSK9EFeYKbwyo2MrEC=lJ+sz{g7iJ_4`cBkzrmmj--PIq`8-z(-&SABA6hq(0-L z!<)s&GpqFTY3^>z)DOo;_+L)f8u@rky1o}3cvVBea1(JH;a!;s`N8ojjoQ5@V}g{ zHS+PybbXU!K0bXp_(m8X;eUC3HS+P8D)oJb`bN@6_@B+kJbZlG@$u<^j~4`d1YW^M z-Wwk;2>7US;$wbHDJ}vm;iK@2kJM*;ba=D)_@_cjA01tb)#&Q@2>;9JS|cBSlCE!d z%*PK@tIz2p{4cMsMm|1VrM|b1!bkX@&Bu-d28XveK5hy4_>O>&z$^I3d*kCf0zRso z_&7b_Bd~;z!Y@8jpYhS*&En(7s`PVOHM%-J!vAu**2u>t>H1EN`IxU(pW`F^FR!mg zKAu^nzNar6Ss&qlHXrlw@fVJdzXGf z|Fikn@mGVxKXH8gNx;Xm13m(;;3Myik7oybR5|hSqJWRU5X<#er)j~}DHj|O!n^Tcy!S-kb+G~OEd_1-L;OJkfftMMccPyWO4dyc+wH@1X#io;TKP+&v@eSX7S|YR9`sXyJP+Xvn&qsd(NhwUSfLF*A?@gvo4`fQ^BvY#bnF5x`l<-TYsLy1|;mwk%&sXW^ylQlHdVWxvt~JWW zGV1$SP^a|V=+|(#>G}LL-WvJ!fh?S7#5j+r#*;ie`M%@H_XD21Dc}k43ZC%Zc=D!z zCn_hN^aMNsmheRQ#S`i?o;bW&Jei->mk-8$d47-GljkF{aNZr`{3STEWp>iw@OK=2 zz7x==HJ}gh3i|Ng=+hd|N99DHEdhOiCG-(~(TDnsJ`QgdeV(r?*@8rVHXUwu@GEKh z)My8PnT2yljPqa9IBS&kO<6einQiS{n#NgUJHL^I^XM4o6=|F`w)36uFkeTq8u;be#RR4cwD-^MKK@0SFJub zM#BH{`fB9kfmQ1J3iXY|NBE!3$Bz95xv$4~GSCz7@uYx{z$^I3d*kCt0UuRPe4HNe z5m>@U;TIpN&-m!@X7TaoV@vkN^uy8hgVpHj_z3^Y=~^QnAECYn({)}pyLgu9>T=e$ z$+x)H@0o*c4?DU&9MJ8AfNsDm=*D}a+X(^PR8Dkj4d@0ep_}lFZq#RVb9l4pwmjX3 z<+F>^L^GE^%=ReOX!ov3Gpa3QTaIBK1!1bzmKwG-@)N;IGOlHAQQ(1G6B3o zCU|c$acm$HDkqt^D3A$YiA)H;WPQC?!M*^e>AZ`(U;S>{IKq76>~wuK^7va->brpYMzWH;ex_R_W)AYIJor;6?Hzm+4N8e0)#3z8}vn?!3fsmCj0>${8PW zn~bL4??~g?F}t`ejqA}H7B+onbX?@1o-{v=uW&?hzH+F8Gn40&jxhVw4K2!aex>sT zJN6kIzSr^m-hk)R1D*q~;5qM&=hFk8tDJbgCEz)*gy+I9o>QOk+~LjQIp^3W?HTkn zv5PZ~u(%JhU(VYab>>gxEC|o75KG!L|Ew72m(n!yzEK_;ecsXN^8t;f1vCO)K_lK9 zjiv=OQaRBmKejYq1eVZ9_(db?Ga5O(Su}byt1llu!r}!VPSdAGyZEInoS%tt{zDpP zjrw$ZfYa>agGX4r;5g|)rEiqj#l6z?)yU(IRH^U4YC7WV;tq1Om+6S(KQ?M;c$MS- zs(}B81pEhH!GGQx{|^cHuX6Ce{~~hr`7=hq68;On_)mSte}^}V|J)6i$Z|;6pD(FG zS7#T$PCs|YF4BfcoT*CcOmy;zSU!G{##^Jz?F-Jmvhe=;h~jk4lWk1ntx*nM)EQ=X z<}GRKq$3UI1J!taFTB3f@%qky*9Qc=242By-W#tE2zae>;&p4lYhVelgY3 z=aI`hoLt@!$mM>4Tmr9w;EWp@?ibyq=t_0FEC*cs%K*aCgFj#u7n?ik>k&HF{gp9Q>7u89pUUv59` z8Q@ub7k$GsuDU;Int0FqLO#xYBD(hHb=Rf4Qzmb6l;q^^*E46EdO4r3yNZ>=g71?$ z>hzqdGtFz&D_AM#eD=MaYO7>Heb;?f^mAwn{+M!cD0howVqhBW;XLqWmoFfcDb=HU zFjSY(irgJ<{2h0CldD91?)Nm}x8zOuwp770N&TXn>eGD+9l{eumS-eQQ%4gk3(jTS zFKfAHMcWN8>>1}KA;*N|x9nb`5%|rwLrI^(Gg6-s^SHn2BV{*ZCm#O?-Mb4tk())% zUsE0u%a5{T;6%G)2N_0Ajx*i_?+V;MVL8lsuXp0F@Yrv7UvN4+B40<)m)mGtn1h1# zfJ9$9$&=CtzsS$ftz0O* za97Dr?5o@?rt^HSJnLcJ{=z?%a#(@CBs;1T9g^+T_XFHVw3_>fq}Ne!*HJU~60PQ5 zBEi>%cP71=^4w1(I5C5Byk4&6o+1x#3E<7#SG1A)iVS}MU(LNmH*jx};ScXj;y$8g z?jy4DVSBjOXaV;cS$Ut|o_^iH{YK5)XCyee!b|NT$NOprZvozn{b=K!sSVsSCEIS# z+%MJT?(8{C@3}v!jeDi^zR^8*ai5f)r|6k`q&9Gml%5aLGr9Gba(|Sbl@G0r`=Q#n zA4<;?tvq)vasQK^C-`UXiPE$9rth1$XG+iLW$Au8o<&#eK<3>`;@gI?Zk&V$&1c-a zuz7-`SwPEy--tGqG!uNucPq;`A3^yiTu#=2mIgoK-k2vow-WX0j;Gb!=VUxVE=8l{ zjy?LIXWjYK#63{zqiEKIyfwYMM6<$H-A`4bSz+w;3!9GkQbIGmU;N$py=YdLLHQ?Q z8j5C;<3cX~8sV>?8Fn@Fm86H!wfW-Lxo5Lv2ZMXbQst$W6WRw?V28MQQ)X!Eg5s)4na(%ebzp__GorF$wxua(C}Pv-G?6e~C1hkh<{dn{Ck#sYn_791;~(|4h7lk+(}ePUVLH9ABo zI_$1oEDhx1$`Rz^oukObp((leFt~JwntVUxVZ4`-G5gmqyCy?6ev^`o18S5FuO|;8 zhh9%IWujGjGIsUOe6A>euM57xPvkz<7x{fB&}Qy=SVLZjHOfgR{TPrRkAB>BMa*a2 z>GKU}k>>SEayY8|>&0h&OEy~RXEv{cdqT5p1$w`f{?uewj){s-d?aO8QaE*Iy0=&F z1Fz$K3%5{9f9idut@q@g0z%K9<|& zusv_C)}GL=F}GRSL!Qh$KCf(5&-rWjrA?jWbdp@9+jOYL3jC>PPE`CD?b7dFd@R|V zYxOKW#)m3=VCvc2wKb9ZdM<7Cc`PZbyL;q|sr&~h->34}-&3j6zU{yUI2(C1uy?z@ zL(@r~E+snbnqH3!}pu?(;DT78IcqjTij*R-d!rJ_OM=`A) zP}@W|e-F{a@J+d81zVcjN9OK-^Y^~WF6Pfm=yFs*m;a`&G+lJhD!J4bie|msb=${X zFvGz*$G}PPc(U2&-a5q1d+Y0$MO&kzK9BzE9x|H?U)B7e*-FjBHI{%!`7;ehyTqsQ zjt3>WziIVw-rcPf&UrLOLbtn+C%cQcXUbac12Va#K60wYclBK7+9g>Kd>eBs>Aa79 z38uDiPte+DX^Xc*Q*L>Fh59>ul$*OA#r;3g0~S&;KnseUBnv>hxSu_Ic^L z7l<*nn667M#}FSmc*6@ThTr7m?oB1R+wA5ECO5!sJt?0n+I+KBF^_Wx`+)zc2+mXV z{EorCQ(C(3f`+Sl&R@IrsFtD0pW@v~(L=o_wLJ7R`mWewuBBmWZ)?j#(T^L?kD3~% z7NQfU_JeQp50H=HPwcDvvbOX@{E>l|0r-oN9GzoQK)_#u_U$#%kOd;D2=0k_TrE53f+1 zCw`7~w4Zm@S8&NUwmQ(yzd@huPH6BR#dqboc|$*DD*8Eft=cGGler@IZJoaspVjss zsQwMk$EB{JD7S8IXa3HUl^0ykiW%vCb$yfE-R9(9_s;45#?`!2OhWccWsOJRUF!0z z5+h4=xQ}~HPsE;x7m8=l4#RKXsJK)t_W1y|sh5pGVJL`OoP3$GI`+(7r^2+rsdD63d>Ov3?J`9*ISCH+XEgJ7+ zbDR8{1NK_6ls3QS5bIuP%|Xv@&0#$FwC>Ppt zeSw~_?z(#@p=BfbBVSu_Vb;uU>qAzcq4}Ssc}=jE5#j`&&jqfrL4JW`S-9v^?4!kU zrI;0Z8pqrtTO$Z?IvtQ5OXNNahU|th7wL?*eShqFv8Gsu=`sDaxgzz6$5-LY_0w<3 zQUkgxoxb(z09FqS-M!gh(8iT*nt-13jmaSY=TYX+x1i@2M#U$wFXG>{DN%QszIRBz z>sIeY6E;jxOzR`tvYjgkpiBZ`V!EH(JHmN9?2zAMjw& zoOc?p4Ht7N%}Evs*WSpH_zItL*VG@vdL?6hyoMv1l;wMOv>(YPg?tbXZo8dvN^->S z75uh240K|iUCx&j4^^J|Q!Io0Mz@f`n8vJ6mB+byO7WV|W@_w<@L!sQhrUZD-CVMK z9c8qBx%c85HnAj&8Eq~UV*N%>Z=-y7bWLj@pd&al& zY5aQYxr{;CeGcp?wsd#KZ`nIXybQ|Ihr5052c^7cbVgMYV7F3_t#j_ z*)#P)D}NDpo+2NLt!(LtimW*gJ$?+5u16i@x()?Mh7-d6+YSeuuR|dmWS@5Tv$eZ zw0?rWu&HZdE;n;(RA`(!gLcX9RV*Zaf5F-^-zBuq=(pyc-lr4|PL-TFdq0og-rifk zw@!|ANH!ch!M!l%H)}kw_spC20#@!Hnm_RnHtC_|r|8SB@3+9esY_sH1SftATvSRe8% z`>wf{=95izrS;42__zi53S(QkbNFU{uKHf)U+di7h6ViAekSo2pJmc^$}g^K8Cn9a zZQQ+k8sA+~$JmM8`Ig#>%@ALWFW3mRPyRwZ^NxD_hpP9Q1ajoYCEHWNIBaY0iuZ%J zyP10ByRLFF)JXf(Hti`=Jq6mvTmpZQeHXw@?`_NuVxFzB99J8&*J*8klrk^*eMhCP zkJx86Z5Cg%t=_a3}@u17kFNt44zah~=F}v;f&YE*IU32dpg`JCj(0tAK zL(ofGTjPG7cwZGZza~1+kI=sfb@JAGTznS3(DriwWHkELK%e^pJ0f`-l|JZ#?d?Dp zMAJ0AcWv&KVGCWK%IsqnjJ|oAE!N%Wjm<^uq}d$x;}bnEXsz?M0m(CZ(*#e1Gs|Zx ztE-1L$-gCbr*UjC`%C&Sh~{i%|KKn2Z+``D_N-*bQ?M1`*rz=p-Y&hK-)XzV9;3uA z9k2H(yA<;~n77d9WN%Fs`XjH&xbSlDbC>idi%+$}u(`d&&^52v4E>p#a)(zmw0#=? zxi4O8RCXU0_E7hgU$V1*gZMp;{bt(^xbxs`@CTc=z0>y}TIzf0EAwRbNN5gQKTf>t zzo2D~#xL@**QTGY57lg4t#+(T&PK!8QIhXhIXR+lUsHeBk7sgYx{7>@4uV(6cYvdT zvoX2)_NUgI7t5sVd}7-i4ty>73qyNvA%>{`#2xj&QF&v|I<7dCXMI<#KJO!pZ`jHB zo$VW_jTLq*Xs79muk*Oq7IUu74K7xq_WYp8UG!0Oyz$nxN8_sAy^iuNxp+@uG$y(~ zTHa91@xQURp*UuG`@%fGFPhX?JR3R~&G_cu!8cOB(*BM5fKPqfA~(K^4}!hN;ViQ; z)%rH}_@dUZRBza~&(M}$*SB=srP1|KG%4$2%b`gh=g%nh@!+734}!NaHr{ipey4G3 zjv)H|o;KdiwdnnsNKlzc<<2wUv-*y1mQbAYYbOwIRK;y)>tx`i=gE3tvhSWjy( zcf^(^u{d;pD={y{Ej+C>w|L74v^t6YsLa>tPZ_P22DEA_(dzr>#_}NAsGg`XDt=k` z-I&sqk998^*Zx!^y7Xhp`*;0LFVi$7K4Nn5y-#uXox{oe8C`9E>PNuf^9d${z&>kr zwG91Cc!}+K_)6m5n~C#juDF#rp}s3HCKa$>m3u{lSX?M~^uc^=>d_cfp?^KHHDgxq z#9uMLQGJF_p4OV1{c-uwigqWLiVLw7e3Ibjr|H{YqVHXYm*{(?qp$FawtuJo$}goo zOC9}$S8+(mpT@$g{uw<7CR)TXqrm@6^-ucOaL`WC#?4Iv`Aqe1H8B925Ae-?eADUr zwF$WQgN09P6gQu-)8cAX{osst{PsZEzo7n%GMC@~;)=-ju2wG>#v4EI#a%1k{F~Gq zDxiV-==bM}u6{3Y2l^h%MnLB(-?3)IJf!q3dTlYwqsY||_bb4W>c9HM{LB0?_{{H? z?w>rDYH!9j#uLi_qK2|*{68P<8)VV&BYP#=Gy-oZZ*f@4H_VHQIsOhHug_>aRUH-j zm+Gthf5m_A8JF_+Q{_UP?m*^7t2-?J>R>}Y*c*)-jr;!dHF^yQ`E z&v7T%D~bP@QSk2y&wo$@u3F^N%h311H=10iec!(zwVsiZHI->Pa%7oNndVW-guFca zs9lrUTKX;g>bu4{>ClB)b@Y_RyTleU<|Vd}?@M(BcC5;Gi5=uS)p=t=^U=S3x$3;T zhB}k|rr2NA>-Q6G!KRL8_rq`1-|$=Y`5Pv;L4Pyk2ft~dZ2zj8his3Y$tde6Yk0Qb zjo49qqp$K@rmvx2$k-+SQf<)uPJWg4w(8mYE9%>Na4?@#zs%Rwo+|kfefUz^OR$X? zPCf0JjvqyQtk{&3FEVaTQ(ZK~ykU8C@w6iQZ8&SvzHn>4Zp|LR9&4XgjQ0~&_p_t} zzMo4{{k$yI&#Th?M80Z{J!H`LKJe9|>(2!3805G2!xpzNA=86s?=vkZYgIde%@=eLUut;cBfhCKS}^eYtN0 z{d%NIzaDk{%BT8ucvipuoH2_MXdc#$l5~?CYkBqAA7A`TQEr&{WP1 z0(|=3`~&#^dd|uVM+4tSdrc`G&GW-wdC|_Dj<((|`6nh9$M!l>`yUu9w4ZnjF-Fa; z4gcWe;&E!fV%sies51?(`7-t8<2aM{Kc1~JtO2mMdgv_uroAe6A?1SD?WU+OrFbUq zZC>U3Fm{Tq@%C1U?T8<;tHSqI)k_Ru%r=8`Lh}Cg^$s&sHD(s!G=y zbXe=O-WJ7mlysP*;g0X4*pC|OVK1_cSF(ABTVG1`Pzip1P)A28h8oIN#T+Gzeqmce zTS>i7stw{ja<6f%jQ9IYDGFATtqJR>VjI66^fzrAiFL3xuQizHnbMiAp#LHMR3AEn zKKv)Y%la^BN-?HU67k9}S3=NgzEul4Tb&#RVT;}_uD7V0-1EZ^An*H3Hj-p0C1 z^EKn{V69}C);n$Og)yQNTlv5JO!KqbH17!JFj;m%FzC^bY%`|XdQ71Z=UA{kl)wwQ zb^leExbD9)&vE{R@RInrtvzUr`rmXuU3&QbTKR|#kI1W(_zI!EI~%9799y&x7{5mP zP*~qGr^)T%mHpSc#$D{A+`@i;o0rY_b1$XS9uqqjM}KLDKZI1|Y1F5r=WAv~qILWrl_=BR8_R2bLw+|(28 zJXX(?wRd++S*!WC(IwY1r@u-rk0tb3=UaGh`}Wg*&4rF$Z|m1ONqjD=s}e8ag4 z(M;dBjf>BT8{K(#DdlaR0&V(_in><<>w50|6UWe}?>x=CR`CIz+k!pUv?116**?nY zPwOZxt_?a4i&6A1Ms~-87D?83xtNp2V_OHkAT;2t(Jq;AI7(gx-CpkvS>E&~|^v@(` zLLhJbLvhX&#?Mjw%HXV&vwv0By*o<&RU2!>>3M(ivqLKy83)}S4DEfk7<<`R9LQ_v zqe-@%pL)Oif6Yk;z~|;Q+52sS_Jp`<8e@ZRv-)xXYvLbfeQ3n}B%|Osi!})KL;dPy zoEXD;{2%{DzD+IrQgqhrRrmn;;_6k=lLL(T4HKfF#(MUoO+fzf17w>dlg;&v;rwnk z`L4fop5LdYJr&Gda=e${UkKI_kCgoL{@;PCjMagC?8L`FABG~n`JUeC>@e-UYfJQG zXUAmDa!nZoW_zQUOWhw$o>H8_TunOKkH4aQ8>jGW?;55Q`(B8Or}1ohi!a?btg}?n z9NqbR7LL^T!8MZ8n`qasa)VGk)%zQ)}fqvf?F@ok@r6)EPwE zJ0PECAD-8F`#_rub)2&T?)S(sU$gx*X?_1V^wL^p;jk9;UFZGKLw?Km(mBv!#tgMj z`nZNOLHfQqH||pDB=#xZqoeZ|&Ob}*YuBD}8%4)HaIB`Co9=s2dkW)y55TZ7c2@Lh zbXtAs1K*vLdn_ym%*xT8pHa@%Uy0WW=l+~w(B3HQH{;v+gNow{$KJpd572%??Gs$@ z<;S(<4Xs_@#rN)4Ac?@F2J*BbT z>=OFZOMF7#Yphx`8+wYi=tG(RnNOXC4*Y(_F8Vv7qUj0oi(f)_)vuft&+(f)F|my2 z&mTPOMdm8Vekb#TL-kv8SISL652ef2561S*A4L~G8qG1B#4zv;!WhQ=5iyLXN8oP~ z!vOb0zLmU2HG0O`K7nt(w-EvMHdV{#qWM>Coy}AFEw!HudkJT3wyTD zZKzu}w|9K|+;38*Y>zs&#h-!E-X)J)c|_!+c^XQle{1+-`#iA9 z^QKM)B4j}Pcl#KI2HDe578eNh&(V>yjorw8cjxrz$)0NrC^{nh{fTFwr2& z{ljOYw>7*fcjD1UHgHb35WRY8f4(rQml$d?p9t#pa;JS4()C63MK;r95C3K%&%%2F z|I6CZQS!08>|9Kl#r#F-{UaH4OUK#|g>I5_#m{aBM<2T6*9@*pa0c^|8gNbsaDFU> z6MuQc7>#_NUsGmBQg`(|7b z#`s_Gt`m4{6E0XAF$R^%T*&i$uug=`eCqj9+)HiL_~GJS%cGY$_Iai1aa#+(5DgcrP_8fc$__0uKCV) zgSOspc;oS|0%uBoyu7dCn=%<4fu~b~y8bDHF5fg<0bOd4LyMQdyXe}eI3v&>jbVp* zxzV_dJ;Vks*P2O5KLR@(wz~=sjsc&SlVh!}l1=+7o?|;XO8Y}PI-4jf zTG*}>FUgM=e}kP@OsGspkTbz*YEu@S!+NXGLuX(;J<@tpqH#cv5NE0{|0Q{d$0?Ib zzZYF&*pGQrB|3dnzoTKq0;3$(*`Yahy`!xq4&w|ZClsi?ro;9{g zhSVN?^ZO?DYtkOY+GOi?@T~Ps*{IIx(UW!m`h0C;eX70Uf2@0fJ~?ou*R-o}SWJAYOR?NNc%@JCxb@tab$7i>Ag0M_2Jx zveQd@%J5{!j`^L`uN)Z-_+}CQZ3Dh}gnui0V0gecl8KxRO{bIBjgDUh^|)e`6LsI?DYu-;SE(AgDLt?M&^F zi~ZZowo)Imo}9^&UuScC(LHLP8~dvK9@{=Q$;lDc<8^0OXr1b#_sirbNnU*%DvAoH zmC0;R5K~4bZH!>f^f10i0U6gmF3rhx7E19?{nnXai$O8BRcv^**0`8^H2B=0#EO)6 zXh89={h1eP{fZdQIAUwbIu`Rct=YE|*I49yA>}o&oD6y5xa22LT!z?3JQg)gv2jUp z*f5U)^^VtCSs%D0Ll$SqMdRgTnJ+~<3XSxGw*Ncxolf%G?7X@%o@zX)3-&0q#x_Cw zVw-@g{SmpZvSi!KqhwKXC|g^mj{$GfW#jeIK#$;~*K@TA8{XY~{4EOy9{cM1B4|=g zUStQ8m;L z%^fYDVZ0kE927mnI?*}X;Vbi#<)`(XLVm7jp9NRltC-@lC^zj#$N=S9=Gfg2qUCyM z0xrX?cl!tLR;J!f4BlOvdN(0>cVX&XeeiBx>Rny%t}*qFb+x3Ox%i#u>nkY(qJ_^V zW%VEzlAlaj#ez%C$JUpW&~azl-^6<8L;9`|w9jzN-5ge0(#~8GhoM z??PYICdDn^vL7-0AinvVKjQCFr{bI2^c!BP+(OF9PNn0UhLicmM&cGWmg5^5jQHl4 z6w9a*zYgP@Zv^+~@y)>Y2Y!;|RJK|Bm=)K$LAHoC%SJ8ZcWjeN@y*^Kwl#Uu2(c}2 zcsnb4@jLDpHd^zTckyklevcm)M8D4I(Ub4rKO;sK*ly{MA8+KROiIC`JbFTZGyo#pd$ja!Hzv5(s3Lda|xO_M#d^!Inf)#0nf zq;rg;^H=)wS^@6Xc$_aAud4L_4;k~K#3y9lye`PEP=+t7j-JxI!1GAC-TauSGl_@O zw=%xe@Qvb!yZTK%al2jp=Bo5JjLS*RHm665<@-Gv(y5i?+>zef+7|KW&Deus*5(eQ z&6-y-{$D;o9(1jxt9;)TyvMiOd=YCPtd%L&thuN06#f=mZil<^NwGuA8}Hw*cqsGH zJbzE18)fSa8MIT*KkeZl|D?_T%V^M1?!(99G;?40(u^!coLkTG#X?@%+<@|*KOm)F z0j=bFcs)tz6|4_PM-;P{FMQ&kkY}5FlLIu!9V}XDeJ+Q8qqPD39>Z_#|5Us6OiohK z2>-ei{~y4oD5Ft!pUr2X&&1d3Z%q0e^r52t>eK%Ozb`u^;rCguJilipeb103>8|JZ z11}T5A7tG8GxK{*(&xVfejhzO;r9=1%njD3GI;XR^t-vF-}%y-Z|EnOz9Q%GILq3v z>=d&9E%+~gL1Tb?na}@~^gmcv&6n2F{1}~_pW^$6d*Zc0$x~Mky3e}U9LWM}W7xb) zH~YN`yf@vajC9}hojR5GFVS~?GpCu@1x~GxmyN5f@z{q?VsownI^LUaDy^0MCGb2t zJmL9UUjd%iW6R|O(RXZm6`ngkN<0$JMRU*V)5L4O7q8?W&rb6?LoRJh1gDS5$WIUV z23_cFyV@1+AF_P|k|&K<>;c%(c=VLwi}+5;4^;-AJ*7ART(*8+{;Y4+aGXe-fc;Yy zIF6fAeAeL*9!H-!O>U2l$7%cCkj)K#EsM6Py^>db=jKF`*?pVVM{@)#8)IK7+R(4> zXVHd!JyI#Ldi)M~3J0yM0rl zeG|Nx<@UpDhc}n1CHCTUo7cRO zV?_OF$@rKd%b`zDL9338IhORBal`Z*zE;k+NF6R|7Z6j9#81h8jm@$AsS01 zvrS%R>3blv?By-VW)e#bzL%{bMo?OR(mOYnEp>Z}b)Qf{HVoVa_Wvtx!`XnR3hSG< z%cqu2!pH7T@CRdacsHeAKT(}+E|-yw@A&7^#XFf>QctpXxj}g8qsISLoiDCvci(9J zg*^cK(r3#9sQ=m%P%yoW_dPR*wQrL-2j8fiaQzfq8ZVj{uL_(i5!_-a!T0J@DHn7w z*WJy&Eg*MPX5VPnd#3H&y}pSK^dasGedGCFaEU&yZxeUBZ<>D+|5x0BGllUv0XN=) zGZ{ZgP-S@Gt*xXoF@WIM_sK7TYyBnp)?Zc-H+9$6&J05Q3 zFAqHS$&TqIChFvGsIV9MKs;ObsNDWj_R!O=-V<0aCD#0&cMcj|dfCU`&z|?@{o%d# zVtPMN@od4l*Q3C_9s?)D?|c1v47j3s>?7rlgv~usu@!mKokH(IW<~E1=X4k6HW{KV z_4tmf@f{_j&Fr5iuHH>7&f2Yh72G%?xW3UIw#AOd>ZjI$W+|Tl>o4M`eS_R;|9n6G zXn6mL^4VSn4o?%c%g!8tCr3M;hY#E@!}$jG^t*ElZeKt9*<#x2Ti&_^q$>aRW3JY~U!@Kk*FN&Fr6(>3(Fo%kiwA@5J)~=(el8 zQ@!y$OyOLoGB~C#+zAa#KIw;-&(H6QY`T8-2eP>l*_3?wJBG^hR|hiV#(35= zH8+zDERFG@z3qtY{9XBJYgaKZyPKHe=Q^guF-O_m`~_?4S*z4}O0y$87xrh2%_DC; zlVcv8u&0`X1Yc$nGB*d8=S%#SEsE>PT`qs5YF*A(fq&hL-8lr&RyLxE93X|pjkjx^opIsD z4gNkY*1F9O*5ZRV;e=8g6uJMZj~IUKAyFAK;^wog!0l&xx~hae)=AMu^;Y$PIyrk zQ|SrTtuo}o=GXt$KJC8lKZjLc9n%*UlULGwtR1eY=40q|`58^X`hF5F-jOE%J#-5h*I6oB)ssF;!uX)MD zxE=I2X-Aj4BUk%abg!21j`_`pfAAP~QfI$Ctycq=zc$A2>lZ)jxidYA&rWhTjje|^ z)w^%>euBySG3(s8qcUyKu4zJ`D^7=`)4ziLRv+!%O-shwsutEC*KJYzF5a_jIzsbCknJ$w!+SdmD>?4_()}d(~B5{z#O|nV+)G@kBIQ zJUqOqu=0pv6LlB(w$RsDY@!XwVAVV&A^irTYAz>MWp(lCkyB?9IIEB&VPDYx(u<9(L=VE@lH0`!zK6s{3h-BF6Xh{m*$^stA|_NorqQDpNu8Rxqa!q+Z)N*+c?&x zxuNFR%c-m1bb8vL>QF4Kd@fdstNS&n^c-+F@ae_lcY0qCysA%Qzw-arbH=gxEmMk( zS6#w9GM*#q-B^6__bhnP;;Wn+j>jZ$R>amj%Hun|;J=zYoQh9u+r!^!h%82h?WH^+ z!5*xP?>D&b_usRI@1eEbfr(9&%;Q@O6`Ha8@T{5tvPXU%7xGW%KBYI_ewiPPo$=qi z)6H2WmxYPQrru%mY~Cr{z~oDu2CR9>C1&@o_4lj?-xMa+FDul!_PB4FCyraz3`}k7 z3+ArA9{UEnX>n&{adB|xTv-`sJGDPKoR=1ek;uoAtuHI@al*$0XSz&?)5{RPm}H{a zVlUO{>CawypGWq34SE#XM$ug|-9PMNTAbfqr~L#ymHPxN28d&8GS)`=9nt5q zSbj=gwWcJQ?*rEu@;SVZ^Knkj@ToKIIuC6_N4yWm>+V+O(du)OuNqtYD{vFTuv~y~ zoHUGcrRJRYq)C1R?`vTH??c};2ivZBHe zJfF_H&~G_fWz;TL=D}~1ZyCSI>>cp0Z;bO+OOKmqlVmx%Fe=);nc%*g@%eM~=^p%% z&(kOMXCNQvQk1;q;M?u2U*IR5Ae@Rd8jfpo_zD*c>h~D%wS2WyMm~|?vdfZXU#D`< z2#3ajNpFmQOPxbZ$ zpEwOaG2CD6`*AC_JLyLXkJ?lb>krFFm%tsjv#z*a?c^E%@d2Yhzn{CRdj9<|-#UKO zj%ay9alO_Md*l53J^WVw{VV8$$M*;DsSaXC<_D{dVZVsym+cYLd!0S=awVA&>}H3v z>bGIv_S&O(V@BT|q%Dk9=65?AlEm2?RS)gFhBLk`F2-(sB>%qe<9zb(`#!!d=;Kep zTc{!b{!DnMI$qCz=}^J!eO9jbVEnFT&ydwuGXMVNBhbp{-+xV-R^;DLXhr^gPpjXZ z8q0%ZLN+PFZ+=qvkqPs|Qu+6}SWIzpd)M#mSDIf3JGuDnhbr^${}C8`HoGL*`KHx{ z+zGGqI|bJ|dzgP;-xY$j7i({lgCbb}OUZ0FMpfuvPifrs`z~c05}o7sU(vpHCzoOV z{r_TbT$wDAf8Wzr`S(42S2+3#uW0)r^%s4R-Ys?XOXuJJ^hZX>zu#I~TZ@he_TTS@ zENV^JWStxY#H{8Jx0|!r`v>yljxgW%^7Vdx3aky?Xgb3A2$YY^M+nB{4*BQ7y_arW zR^G?0_(V4T;5*uQjJ%C&X3XI~b(M|DhvyiN>llygOXIPP#miss$Kp+oT^1EDW^aSV z&)-h0s!E=ttC2_L_*oS5%xnx}{HADjPWPN_YP>I3oc|i`OyKuLJ95QYj%WJjlPv2YRJ@xz z82H}uHl@Fx@4w$GUt~?w?77hpS~6d~-_KVYT`a2N zqHfm7;1h98d;|2&_7C`YRlmiPO6#BO=`@?coMVW&D)q*5)rxxi#wgEoTrYb)N2>Sd z3!g95OIfwuo%cz`1MOuIJk1B|XJQkAToBcCgZafS`<)%i2Q-0uUGqg->&Wms@5xUd zyce3v@07pUl|Oed^f$9)TREO%`F@?3@B1G+Yi{vAw+|(jk3EW4KPKD2-RPp7 z8+>BCsvp;N#UUqlUGa_+oA!+DYc+pS?eYF%?-t#o9{Y^SC(!9^^QWm-KHi1mG55AB zmSVh6Y-MaIj#S9SzG)wLzQ>Sqdxhu5#M~-)ji+wS#ai&7Gw8gL@2YXp!41M!k_Co7oYgt!6D^ZQA`n9bosqG z&bK8e>Ll|ki6_1R-Ra#ATg>?%%2|Fg?*mV#oPIO+8$x#Ri{GKR!B7)6$@5|*FpW_< zljd!M{N%6D{$Aj1;Qth3n$E4&M2D8w7mwDrl)uc;Ks1kIAZM-~?r?dQQe&LP%Vk&k zJj;Q95{z%+rN2K;_%wIa{`2*;J+i&{fe##f=f_3%xpdL)o%!B6tDtu} z-!+9kck<5K-J^4O0p3)* z#>=P2Bl@b0zt?C+j3@D{J`1kR&Yu#UtLBx?==U^m!P{pt=kOWjb+%CFd&~U)fF9Lk zZxY{B$X;vU-&}jaV6tZ?qu$%UoI1l^L!G6wCxKitKK$A4zzf>!=eVKVTwR0QTwjCS zcs!%Y&FTLe%8Ao7yCVbQ2z5w%E*V-UNYsAsAukLWrl}s{%ha!Z8J0( z7>~crI+f`a@dVkrL-jp<(^`c8-paV|WB)gp&t=G%`WgFsqsybp%68Vu8^uW~%C^RS ziujJd)IDvi{gv_|yu|mBa=NyRb9ZS}#$kUhIiqgHlzz!?^+_=$;x`X?oAtE8nV+=8 z^i^5u*_(l@Oqs4#p{aON(f6QillB3m?tuO=I;c4D0PT6D?j1^W;lil6AG)c&zY;p< z^?Jn@T^%c5Io*?wF8%X*RzP38u30|FdC@b{H~Ht%HR)Vh*KE!z9M{GC-Erd%L2iyHfTVe2kG~RsHt-JZ~4u&dn;zoFSbn zGkpeLe3D*jk82~p`;gJi?yP!g9umY(L!5c$>)1)|5wde`V{I|+2eKF56ZPav=>zsC%*CX+cY(E8?OAH( zzxEoi)@x&tpObL9MjtmVJ`{qo36R{ zj>67GKWM&Y{2>LmUw#359e6i#iyCiG|bNBPH@1D@+0@bE_S>!eG-CzcY|O1jVwM&`)yx7?fue?w$@|c=uDB-O}XcxiGGWI zw?jYGUB0h5@J*y+d`qmYTjj8^$N+f+T3zmlo>H7BjEig`z81#i;=3W+pSs@iQ3SCH z;dgc{3ujgg!QzvABY9sM#GbDET4_C5eqJ~aRXj=c=o>HllO4?HB3s5g`4f%$HkgMV z&T~!kP}djLQP}y54e-|1zQkBjQiZM|O_%V^XmcB*k>5j0yVRzi z!vpyj$mn+ZX?8^8$aUZoEvmI+5wyvXm+IcR(9+qFrNNpXbeqIpNux74l}z5K-}WVL z_UC@62Rl}_FHz(6HegLx%`!jSzR})2aO@!F=f-vRxN#1SHmDr^ULLJ$C|*Zf%${NE z)%JLNFUi-4HY!D9f5usOM30-GlkaDf_d|gz)~q`{b)BTPI{<3vH(iqvf@5`q9 z=Ck%T zOX*Ca*5=&&LG2r$jNe1exVP-b!pRuQdgB_M$6e{}L(3|wJdkReaE<||Xw^^`(+e zhsp?67w=2gH@8#H?DCE|#mUsIdO4F}c3Ec{u;=V2U~fbqOQJP4)W)Da_(pbj=hZLY z{_CT`$#`Nit2V~tLolyM**cxyQX5zU?3QmolFd`BxSGEk;yHyjgm}{XW7Ff#Z-`lr zH0})Y9-5h7=f|Dg|I%^i-jhzf5blD=EhGda0TB?CM5GKv3wWs-w5VJZ@dDz7n^kMA*w~8o z=ay-0-QELeH(=YPmu-_Ssn~QYw!2%=?Y7(Q)&#UB+IF3||6fUw@_&EM_netClSu%f z+x@+MzX`)U-}61!=RD_mp7WgNoYTfQuA33;*V(IPeu@u;bZKk`X8kvczC-%057(6@ z{~aFbbVzv0x6L?#R)V;(Lk&4+r+gX49%3FeR6bC7>CMW#pxC=FuE#dbHf@UKwCSg& zzrA^s&9`oVmv3{nZZ6ta{p)Ej?KbD-N>4VpLZ8PLBRswp3>}sf?Q7iV?w+0CMtjQx z=0{iFMH_*0*TGNqeATx_s~)n2eRJjEC%?z{c*at&GGf}GwOpmwJq4x>_>Y%#(+0mx z@qoJfa?0}h$B6b3gl}UUt6BhcN_8BUtjO$>%;-~qRFAL2k?Oh z7M)<{Y3!+8IvYT9$c4H)Z^qb4=2!4Ecqwz&pfsACwej$iIy-7ReN#W<`pQ?Szx-74 z>Xx3*PYgNk%XRtUY>SRMw7q#`1H67n{kKL|J{29wdCB;T$OonQx(58~8`Z{xwoUQ{ zVLXKXOdCg6;{S{v6+Sk|HO1Fi$J=;rX*M+0d7w6u+;K42uXMdgxA>!njgN@&;lKuQ z5SjhR!-QELmzzJf?xFSHx~>u&n>EL}>J@v=!aub2)Z~cpjK&iUpO$JEPYfB7LK9>epRy>NhT{6i>0TDvcjsRxLdrx-xTN?J4Nqmql_w zWvJh%X<4(&1PAogO2+ zXZ=X$&zN&Rba$BaI{EFvAIv_danx~>XoLD*AiTv`(|G?Ob61q?{3VP#KR-hwX+KBr ztlMg}sTX^3xvv;`>drDd2uDu@0N*yY9gS!F0vnf5W|mCM?T=b(*R1{T zy=(a_$v(!Dc0lcESIg~3)eB_Q>kd;~^qDl7 z-SSxVwC^?k zdZf$ROuwQ}Zq4o?=te2dj0fsnZACv z?K_!%IvM)+`|0DK|I4=Ht0y>)jXdsw&pdO2`8oQH<+=a+%r6|4KfUq4fqojHA7i6C z5xU8j@5~=|KKUwgQ+_=sns09VgGi!D{fREv6qJ+}pOEZ?zK@mPyTxbjc)9IMCqZY; z8Q$sEdfj@Y>?~ROZ_b!Sb{l=UyD^%@V}uX!X6Ys1G=^T1_dcO&6VLGFEtYp{o!iVI z;pg$ed#{W2>fzi>l_R~f2Rc5X@vZtu2g}1R1N;)wJd|=Bz328%!O8Sb5BdJ~iOV=eeIvehcB0Y{-^PQ|IzjH>CVpY&G{LO zN6}b0JjKm<(spXi0c7jPMlF9UGv3hGuvz$Xo)?dI&T~@z)x&rf-wNW#(3^Tl->pt! z(;Vx4J|5I<8gK06@}t5B4yET^7b7dP#@sRMl371?=V;3Q^yoi7Ui0W3yEbU+ z>hFgLf9Q^{Z|I<3|3CVZ^_@Nc$v7A9ka@~J8?49X zS5i{E*XlFMPhm>C&(w{5$SVty|3-aHy|5*|qPkn#WXs$zF6V)na&%_qqf`D@&7)_B zWhLDCYLgRKQ3W{_qc-PY%HLskyh#^kM#O))CDaX{?!iA3wI!w9dsl@!0l>;M3Sof(@}koq;p1 zSZ#mQ%kyu^Q)#qkR%i8208Tg?FJ~aO&oF&b6hz93BZEqcgEO$tmjzASscZJJ>x^Ia z&%SgZTDa>VU!6@e_I&O=vOat*v(Tx2QTpM?*70H5u|bn;5y7Ad#n@s(yZ%^gyX0x? z5@jLIZ*X-iEl7U6;GHM8^&-zfp{@7YD_FCc8Z?>yyeRDBI=|lu<1DJCmZ^!R8u~NB z-R#)9n>0^9Q}`jRDU0{Q$3?CzaJ&|L^lAQ+>Thk3I)APpc{AY?m3Da0WY#dCWvx@K z1m`ys?r3IpoW5Z#jx{)FKa6t?an=y$(SF>;J#cdkbJGp6!HB{%6Z9v)-18~-8p@4xp1_tRUb)0Gn*_p1*-R8t;r*bu?q9>hwEx7lKI_A*! zPX+t&5jE#czlV4&`PQMZgU_OkvbTLqaqur`Eekr2&a!x!1>M7Q3@>tHnYiuP%Z>dK z8+I#kv|s&mq(?tC{?CsoFV@+#XBv8Z!knEP#MaKUXTFIZ7CIe?INO?+H-K#IZyloX zW#}am(tyTz4EvhC_0(7WYWj?FWAg2wuK$Y9hQ_xaPjT{|g_nbWBjY-Q1tdr)kcfXP9+s`t0A8W@xa!*_&HxU0Adr+WSKk+ySfpl7CtA5ntEv zbX-FZ=$`*T-fifdqJORDKgTn3khIUM`tb*jS3~pQZ+*4*{KC;MgG0`^c4zYy5r?z- z%KYbfiS^qpkI`C|Y}w_^WzngQ| zJS)GD7iIh_2L(Y;!k4w`Ai?)4zBlpR#P?yoEcOMm_2oL0HttG%0 za@z1@6?|*2(-T;qL!SzLYFM|i=TsOOlRGAu3xs@(c!rO$E~Ilb{ZaP*URRu|uuS_3J z50X1B&GgX)yz8-#a%hdd_17djw~#(-eCNgoKjM>LBcA--cIU=#&hTOJ1Iaqg$393M z#V5rR5*|Mjzsq{=A3kfmw!mAzul6*LZRls8e`uePUFQ9d?X!3}Ja0($o`lTU%~~rH zZ6ezZABP?nQ#Zq_sBf%4claWEb&rtYRguwMc$M1!9mTBsm$C9B=pZXEHW1XGzP)GcGGwUaYH&NC<5y$Z#c(#dScykW#378A)J)ZTu zJZ&-Sp0owOjwE=cJ$c&UrE_*n><(tXis;+;vml?5BiJ8ua8T>n3`wK)SjkCfSUk8f z7GvLRzaX==?C}8S!;rflt<;nQ&dI9`xRo-^+AaN}I?&C>cegC{P=6cUn7rU?{=T|K zHfPH#+GF%;=6Pmp zR#@G{+4PZ1rp{))fH7xu6rsIQlc1kYDzOSO(mUV<~gQbJZS9dC zq0`XTK>J^O5S5-o4>_M~1SJXyV{{(R2t0cUKIG5Rh#oRQT^Q*YPVzD%674MTbW z@3bfN@-QD`t5yB(A>MKAN%i_wWy_Y*e2;7$jIpxNcT?-1Ax<)UF7F-{;%Pnr@wUO06NQ`{p_{{+Ydb%7(L6wL3KDz3?F`I zY3A&;9RX z{xWOR$T7n+p|@BnQNKN{3GxlQyynrWn0+8Alu zENv_NlZ0zOyLiJVp^;X?%6k#V+C0BN`f|;$K2@j=Eup}Q8!n8zXabxvz%k998Zo5bexgz7Q(EcAJ7s`vA(vk+AOxbFR- z9x4~x-b~@w;l!1DLgn=|`&xVT#Rn4Cvu;kk zg2JFPPTO}8e(?zT!uEYE9)~^%TUcQ2D8v&^;@h~Vf$-z%!#zdGY1Ho{*i&5n)NkYc z{)BebFZ(QCTS(u>epY1sz{Lm5b1HmR9-2?-?t^2MKZJ6XFZ5#iTW#LFoHMsAy=b1S zuo;A1wJh9grToRyj@<8^S-==NZhzir@BQ!Gb^6XD_YdEBq`8nYa8Jh;HjH(E_aACo zto@2t<2yebdOe-rCH%hs5d4pGqecLqLA-0(8*>fs&ft5^p}ydmzId~5*e7qk@yM4) zst+#a%!FNU53k&&IQX+%i2ePmz(vIG8&7n8{p}@{mx0HxRSirU{7o5{{O5?)cpm?p zqvhOt9UNV2FS^d3HDj=DKyokZr}g9~x@`Yj?pHiL#HZGt)CX;ZmDsSB#fi?|3uVuQ zPGsZd-MnGeM#ekoXn$G|$_wV@S|?cFLY#`BVVrj2XzUfCyX^v3f@9bkpJ5--F7^@a ztQ`rCMk06E|8ohvg?%R5Yp**r*wy9B)WzOUb(H=$^&@O^udvQ7mvD{+I%2u%{fVIQ zhN$IzgquA^)zBjOamQNc-x1I7!r6(=d&!^u9L#5~JM;i>>s&jhu1<6==h@|lo*wd2 z@>AXJQ98;IUA27z9zb0T{AI?NX@9)$w#Op->kp2ota~J~-|)diJlTBS=9-^_CsTj$ zQ{wK{13%^rBy4@{6GM7xpB#i?*!$Y2GVgCLNVY9SW)f!xXZ`+mBEBz^ITJx?r-I*u z1<97{x%-1X1kbRBwTnFjJ6WfyXT3_}fjd^IJLg^3EsUKhak99{|68j|))n?1Y8gX^k?G!t=A{d6cB${W!>Ktgz;~RCCe6YhYRsTxxQrQJ9oW*=h0~I^d9`b zgde}|ACZkowx0I@r)@nt&*FmN$r8Qq6WZU-(|h=)u?6XUplR4LahfiD! zZF6=dryF9YH8c}I1G%;WKfbXK)@rRc&e`P!@a@ruS{Yvl%AnimGILfyJL704V?}Ga zy0g)oOE4JTjqahn_0p;2GqRI$r89bZoP$gESvyRXDIPcpFH>Ugb( zgXGb}K~>99d@H1LePKYdcIM`qJ?|B-acjGyE3q36{ag7%G5*@hLVareBKS6AGB&T| zv39~(pM2A;KeqmXeE*Q0??LkYN>0AA-M8Y?V#e{?+3}<2Zm#)UPJE5a`nQ)=hW)pQ zGrsfOqXz!9m&><Ny_cm*9hkftU476ta zGm#NS7f~G@{T=o6VPAI;{@T!Yq;s`tTrzIk!E+VuHfvr*(3qhmd<&|>bqLYP_UaW4 zn!D85e%y9{u>aYz;>x;vEI*rhT5?r2dO;Tc##Rd7+a3(}TGpSI9lw_N@5zZD;`@4w z?`$3D$o&O7kJJWc@0^=QXg;Dj2lvC7`@_|*(zRPBGZ&mp|4y}Z_Mu_PgBNbD8Ao{` z?!9?YbH>i5Ii<_n`2s6%_RZI1Y}a1etT8(VU28PB8r`rXYR~v!{MJ=3YuFZD*0BAw z$o|hT9*jJ@1liv=l+|xQ%R7-d_03Bgc2T~;e{*qznIj>O%$P<_?u=%}bPRpWo*$&W zU~jg~MK5w|^Nbnhwc&Z6j1kG}UCk>v58mFjP25#>ol9qV=w103$*I0;%f|$gSL@q; z&fYTO8M#E9H|B=2Db)MMp!a2X$Jc>(@qLDTE{haBru=>z?YqnIlihDGubj&LM*oQ} zSk7+@U2sr=biq%gb-}YELFbf0&T@})*H?e;78x9LmJeeNN_@@FoKA?Z(px{;GCnyQ z-@SVBZ3B;{j+bb>h{t+kG^=m^vix)k^_DK|+J7uvIB&brg^!?5b;nPCP!PN|zuy?c zPgh^mm7gw!_I!Ri20i(B_^HcR{In(~-+cVk#TP$)Z%+JheCOe()!zC%W5C}VYsLXQ z%kfm{h@yk=jWAn>vd#ZwcFyWqQ$-Sy(T$a!PGVEjA&d!f&NpMn3b8iRfq z>^JzHS!($28|0snqhl+v`wjgM#)`Yc8J&Uqj^PFP_MnG_z5|SJ=?gmhcPH;-g`B|y zZn;bN(BD(Xw9W=z&-d%_Jau>*oz|;E6dwCRP95a$qH<%*5q0nPE6l~W{lv6nWj$kFbRa#=ox`cQlIcTy8tbg>;7!-Bgayu?Abk${6^-kj)fRg$ zh3tOLr%CoE+4lEVTYCbu`f2hvwgu?*V|I*~^ln~Dde!AqyrW*BjKx1mK9(AfZTMWK z?FVZ$w?((R)$*d%6=rVxJmrPsz`K9)-N=a{Nl?K6l}n$C9sk z@=NpT8O+}X291wkN9mHUm(HwhBAaA`)m$hqzpT#qOt+waw=y2x91=Tt*E#h6aQfQJ zIlWo*^(%1oE9N$@1W7|*7fw&Ef)3uCpG{v&8K=L7HpL5`(>vKi(MjY-hHu+dZ=!b? zKeF|+y84lkrWIT*w!Fd2seaC!>gUH#g+eCKmAWg|C8+Wt4ROFob+b=Ja26T&u7Q4C4Mp| ze)jmuob`v_SiqVnhAwUJ!ne(n6~@0F-Oin-*u}1cE%iis9(LG9Ge0|qZRb?+y^l5%9@}K>9IVs0u_OCF^B3k&qxmj7 zhW&Fi_D|xtwJTs}ulPFWr7=cM2`&bM3!T4a)~;p;TI)6I75Bo^jebX1i(SLeIbmjP zg*LUrr`2B0pfYP#SAr`uPlT^_XP=u4ughnjLq@zf|EBZI{P0Hd$><>Y?Q<@^>~rtW ziSOoOtWSk{Ap7B*9w^&xo3-tlJgzx6xvGNkpYG?2cOGrF_ES%$`!=_ zN;7vmJDs;@lj|mLr@P3W*L;fRTHEPg(~tl6+4Eks_B_KYPQaemm1khjTfqGR$DC_< z{p$2UY#5<$H@e__`t$|PuH5YQU@*^#F}|fIM&<-VkjJ4d06SrfulA5>4PO1HXBXyZ zJhUfvPgmPkjlI{*+t5e1t-Ai+KbdngvwejAqGvMIX8S8^T|x6e;iLJE%v=z^|1SPx z$67P1cl%Dz!<8rgILACotF=438}&R^dCtex`KcXGd1_~RJ)}BZE6ED;@Y9CvH20jJ z7W|Fil_z{oi(C6+F3$Z3fBCcI-}*xLXUU&Q`(#HIZP2IYj@|C=kzh?uzJH;A0rAn( zPsu$J4qxL6J%4JiZ&W|kGt0lXInSC6@zOk=`e`q1sCRl}I457Vdy9AWv1nQ6Fti!o zk$s;8c9W>k*w3#VHYAol`<~~OBak2c*01ap+SC;%UV)4uKm3P=#4Z}LICgb>(oXOt-A;CJ zTqRPzLBBT%NvLn-kCr>wJ)KbFs);jvrpLJ zRdLzRN?&>N!)DJXH5%@TGxsRbPwdz1G<`)r@)0^ry>k2NVUy>Ih6~t39lIbH(#D#L z)>!=dV5fKY0<3rM!AqmT%jVh1tF-@mta;uYEac2wp3R=h&>slD%y^O3Q3~9Cc=DGG z)uq2s@wKNj60Du?_7xIGeM0-U#vYoTjNP~9UWX6i(WO0CX^E?}u5LEn?%1MX$vEj2 z26gBy(3Hie!8!OC>*033muHFEgN=}(EfD)vsO3MmGhv= z$=~j+u}G21;9fmwkTDWFa@))4GR*VUFN^+i^Uu&%<}6+(bDWGm2n}WV=YS{ee_K=W z#hQwsZiD*yM%T}T#~vtHtZ$s}!jII}#QQHQ+J~7ZHg9;c@1ix8?Zm0zUHTgjhD_?; zwK4XDBZ}+Nr2UMbf(5&jOQCt zZS*bEKJD|57liFg)3Iq^g!VDt@w4ROPJ-c^8;iid_~(xHb>Dg+OULp=CxS_mIj`|`G_HlyomPp^s_M+7J{y`ne4L z)9-Ej9^Dzfi_-@x8`&@<9v6RrCcZHw8N0Uq-fsJ5PHmmNL)355&UW+Tp zcM^U2LeWRFX-<7^`+HKPWN?>$wfK19)-c_P^dINbH0n%bbAB&-*W;T%E&jH)+0~!0 zNB`?{CTyGwgTJ=V{D=vA)U9U|wx%)+JK%Vgm*2;^cP1YH@ksXda2H^F?Y@XTCzUwn zY;E#mjIQNf5%@M|T1ZyWmqYYzdoZZdy1HaRyd*5A%<%@o){G0o9NkF=*K5@0=tS+~;chI>j%h2i ze0d`MP!{$>KYN!{TPCb%k;YN{g^{{LLw?!qV>dUxf!#ArCu)n@2tSsekM{7l!H@rs zKJWei;c~cWKz@wn=zXF+@lkzcgA?s#&S%Q#XwJVi*Jfkn1ay)sCoC^$e00-C$v^*n zF5-JLLVjTQrY{Gu0nJoh#An4*W5|fOWQ60jj2qQo?_E0XA6wfN%Aam|?{Jr=csF^* zLYYydv6`Eo>iwvZPcMut4`oKT`I@?R;oqKaSN-LhMOJrB%NWME(dQ;^sfiEEC;yTC zgOUBi`W8L9WQ&pg(rJwDfZUG{MyKicNDb{SYLiZgP8Yj&O;5T_wtfQdFS*s@ZI0*n z_rlmJMhfIs@Wqnp>f!unErKI7q2c$-KX>6grzjlJ(ep0x&}b#vjg-iB*GhvFOj z5dncsq#&OHn|KURWm5WcPaBAf{rzK|Efd!pW*ZhxOE;2y?boS&S) zvrDhGsn31da5%g+@aBZInfZmY>p^%=Kxanhk#3_hb#{*O^!p_DOdG{pVDk3%*^|G~ zbFBW0EwLu8kL0`qFWtUt>FFIhXLorfF8@SL;__!U2p?y-vS+(zI%0c@;k(9z(vV&W$m9(%&F{!tPnv%v>zkT9SN--_n+nWI@^Hnp)shLrasN9vk+X${J37E+0et z^w+Wab2e(#bOS>ggFBwXzIq|N}iN~{v zcWzF+Yjfi9Y~oer#9N*dk7pBaPENd)Iq`Tl@#f{kyE!Kw&nDhQIq}xy#N*k-Ta+Cy zh$lLq#ul&fvfTDhxBZZzldYxyenIlAJaqEdV$S8Z<26?YVQ-6}mlfIcvO7qO6TR#f zz04nP=w-L)CGOG7Gvph?w~D;4QlIAL9kY2~N#5m*PiUeW-N)kx$eDcp$GSgTP_%t%Wo+}ab)g9%VUwVP~?p>ReLAkip`HG^4XBnd| z&jUPbFZuI?(Ff`EsZW@)So2W6cK^51%AfuKbJK(1?p1iA($PoV^oh5Bz~@V}LHn+h zUn@KV{+}g>eK{uCg)PU(LWgU~rPpiBefCCv=zdMs-Ha@2!Y=FatldFd2EW@UXYjk) z;#aavxV=Q}rB32qTip5p`D*Sjz9#$rZP(=PGxyeVa@wap3fNyb^*rM<;+?bQ(P=kn zB#S>t`??*k;6u1O$oLM7Z&=TH#^41GccxxEtF4l|L$wzK*zjuFnN?O4$rz%FN^Qf zXX(6w^}f7+&}r64T)zD?;mTX>Hu0u}eQe;%0_O6(>!Gf`ZsXHs+V6(GaQJxeRNw=- zr$-plBv@{1Fr4}EAXW?U>hmVz~79W#O1wJmy!N<)x_~6;# zgLpmSV?qu-CRltBo`sK#Jbc`IYVq+pdl65Xe=N$u$C?~`@NDowydLpUk%Ny4ix0xH z@Uh6l$C?wwM~;4^H9ey$yT;9ql~hSc_ z%ms}P4sj}2dy;MUInQrWej4)M(b|k`!Ak4)^q1c^sX@>3I}$C1{xROX&g)C9ck4a6 z;}fyb-JGwU6JKl8?Q_STqdH-)vvt+_c%kuY(E4~Fdr8CSq;zYy4im0>7qUi-Z-ZIC z4~i-x5wm`ue#hE(1-=Xw^9nNI*py4LDF>y!%suwZi5jK5YksG7aWmempF$SRR%2u8 zW9Cnd(toiN;8%fPf?Eq$9Uch6wQ#LtR@?Qfyy=c(4c)_&v-7F_#`XzaWz{WDT;{Pg z8Y|N-&$<7TXESeMo~F5Kg6FKfs=awSb2jZamh6|Wi{`oY%-i+sWSr>sedHnkq%l&ce)E zm(9~o;pFl6X}+0*lV)oZq~5X#u4Zo6c70IwDr5XL#>a0+=hhhUz1bSnO-P?#l(zZN z-{O()p?$}i8!BF{hue<}CzPT2&}w(D2=MKOUhqEbxnVw$2tNGS48lJ5cwKeK1Ju{K<2x(NFSDC==-ge`j{jtC_paMP-Q8KC zYLk41u?HD^^u`YJuG;|ZIe!PUzDeFOWQXjdPKKP2FTC=DFSO!YBmA3n4{IB0W6!O8 z2SoomAM#E7Pvjd={=hSzj~%(;<%$Q2@Q-0_pL+xrA*+xF89$Ncu5w&F>2&bx^gH%j z3^ntYD@{Ldtyn)MiM)A}_ts8o-(w%q{6{{(YA1Zk@Ubkr1?}+pgW;vvrnXE!G24{< z3d9>?!xB~SQe%75bAT?~LfwT6^9+C3WBJ?nN95S{gj0*lSWeqE+qNAA=P~7_{Kr4#a%_#RoPcs) zgC>quzch^#zwhUB;^(1n@lp9Q%%cuQRzZ``%=u%QK06H^Y8?YxGyPEjUzYB#y3ew| zS#+02E-pkbtAD$=Qo3af`=j*4cJ#B=R%deI*tZ)Oef9C0io3#l8FkkNyr$9MfcZ%U z>EP*o>ko4N2YKy0xT3QD?G=@!)JgTaP;~F(0vIi1(U(<7(#wjnD9`73s&~PqD$8^RGBm!I+Ib z5dVCvG?9!Qx#DHfdpeG>vv!T6{TY{0&(>PbV>m7JSNrjB4HNYz)N$HV>9tK-Kvn!nr;qfHKn*0@v ze(XZU|I^4}|{B;)Bx4H7r z=?by|a1KY7>{a`Wo*apW){>$;m=ej8KVdUdJ>$~lEVHBE#-@h2_o0B!S{R&|}`ji6o-s~kEIy@5NvlC6o(|GFqg9@cti>Olj}4r2H?ygL|lb}{FY?xFwpnDJg= z_|W@DOyGN}7_{fSpQrooJb<}WsEul-_!D}O2Fo4Qt*`-N9w+)3)}qNVwl{B6gq2e5cBO3jT?IhT=1p{P@gCjeS)*>Ll7D*(~}k9}&tK zL$jwvl548bhsHuj3+P*mW5G_=o~OPT#rsi)-oCAVrtFYsPlY!s9ei<|(+$VcuY~JP zZPzZ;|zS|Wyi`EPp6lkh#5c3nQpw4xfwWQA4q5U1lo(-6+8)? zah_}6^1(q>+w3rmF)*ZjSYX~S6i$(0iW_5}g!sM56ImeppWyE1dRgPWZf0@>@w*%E z;`eHUY($z{W%K*4GD2}rhff_(Tx4d~yKkzI@$hYxo3<6@;9U3;4^rQ#oX?yU-ccjo zw8gvYX58b*8EYfJH`e&b4!3EH9f@+3rr!3=P_>aTm#_0n(phQbV{|IjYXZ;5bJvZ- z^T*5oh@8yNPtPQ;ES!36b@OGje;eMWv8FoxzT>d9PjxS^4K6(2Md7Qveen~9I{A^` zho_YKyFLLoTT8cABsHhix{daxA3E!gPioCZxH0cOM#t@BL$ zb(6E=?=IcS+0W!ZVrou!(BFiA=IosCLBmY=%xO8{b;TxpM{f8Pr6&Bo>ACS|nDF1_ zhHtGj;VaI`iO*hR)w4M}{Ke9`0ux?7BP;%krMm~1@ShQGa7McW9Wl21jARFWp|EV4 zkY3fBGnF`_5bRZbNaq-wsAAq?bbTYg(3f;S{D1ts^U2rvqH{NHcK6oeZx>H|Msvosn;q{} z*bQOW4Xi~$)9e#x-~5s2`h`ya_UaOwlNhY|*>$!)8gJ&_Wz~iH%9e2`jI0J9 zl1Gs_iBDc;({OKAxMyAQp+m)2n@xOZ(Z!!<<2(7Nw(s-yw2Oah&$#k~#|@P(@4~dM zr@ARk?w(|&(L3Qg;4Fu5eb3wb((Lt_)q}RP{%FoBKu>rL+4dXc&+DfJW_?I{ismgX z)nWgAh_>iFMU~M$kh6uG!6$XqzBkR$e&Fy*8q>#7bEk2m@Y;(uOKt|phnViy#Qv)^ zrY+3#+T6U3G`g>Sr|OSBu5&C~k&R#DS+du}r)(oDsf(Ex@~kiGle2(30|-4|8s z%>jH`jTSfHuiE*V+ADg^X>WqO)PA2{(dQd9NB{9@ltcNv@7i~?i#86`JEKR_X7!)e zU0s`1S0=2skNh*~^Yjs8OMRqqfS$&8`JtBPuuq1QhuJSDnxicS9+9Zp;+^G+EyT=Q zeyBPZC62^`TfP)T#(fFieWV;X0xZ1*Jv9A{P2k8v-WBk!G&Zg{C@(Dz_M*F3{Y?5F zbCV|NfAJ~kF@_F;^|5VVzK;BOhrURjiX)oM7mqra_oh$Hn4fpwYInDj#^$hx?i0Vz z95*s7(Yb^AOLt>z>8yiB!%IeF$N8Ker_jb3lN~2X95eUFZeZ**h0qhcBeu8vO`{ve zgGR|@S9Z+!fQ9Evq{ECK6k)auWA`bwb|3QHMLjPjU$ZClxr%hYYO8RQDIeW^o+-ab zc(eLpv8e}bba5kviKbHN-J$*%zNhT;`*@!Bv_o`qguN-~e>GWSA{vE%7jecg_k!f% z1y4uE9QsQ0=!U)G%~ba4aI{TlU3~Fj=WiTWdgxC0Q@E*DAA^%d-AkoAXM8)O!}WaUJ3>8$XLRA2woQ$U{fut{ zu)^Pn%08#IY8>?~3fmmE@qWLJo;{Is@`o#}==fY{_{ja2aPLvn`VDyY0$*Mj-n+uo zTVtW_V6b0$jrI@eS+rhn`L3QNHypj+to|PB^)YZ3y_aR44*(yF_trI!+9P?8kN4I! zFEw*v#WD1rC!XkC?}Y6g}<0&Od~@?{(`#%~ltIPNtJqWpNM5 zJAPaIxp%$gAF`LEX@&a4=0OMOeTG(4Kc3UHLb&N~bey)bfWBRJh<7hRM{mX=F>L7< ze+oHjbQIAf^kMWwrDt3i`e-W)>CEKA97Xy{?751^B!kNpkNWGK`ta}Qzff25?g6M4 z4a9aHiR#{@Z2k5r==SMa_@ZP{89GuKI?};V9?u{zJsW-~TY+HcVxPUA(daW}ArEXB z3{CX$Xad;Bqc5LX$2cZUv`mEu3YQ*lizAQ6NzP6c57ckaBwiCowwEB=CFd6b69*k& zTrqxf>F0yMYj{`2yZNy)bO7WNI)IV=lY=H>ccNb_u!E)L{$$H*dC#2R*wSF>EcY9 zZq}$?LPkSZ#5FtwnF+3>N3k}NBXdK33NHuGdEVRfqA#QCS)M1_7@elE%vsLmHF@%4H{*4 z*L*xZ9tbmdr<@dJgyX@}OFey|epRp^K5XvSj6{M?H}BK9fL|k*G&YtYXCj6_-f7N+ zl5Vu@Pz80=dAqSf>boe>RM$Kb8zSSIF+w}++RoBLt>8@dy5ZEnJxcpeCGV^rwWpl& z``U4GF?j6DIGHb=SS{YE-%)$et&a4C{u3G}z!w7(Cmbh}GtUQsZ{uBco^eta9kr)| zvY^MTaZ(qxJev3NX;B;V)rqoAU2^l#SW(`FhoOTQ-VGi#R$d;IXROQ$8oy3CYM;@| z7$cF=Y<|NXiA}0k`u&8Q_u?Hh5>4B@JPJm1gK5RP;0cSQlhd~Jb0N=4vv)i? z`SL@hj%QSs7E2DAG}6O0A98V=F7LCTt$I5vzwOEG~K?j5Ghj zG|-lK!5h}L&U$S|mJ&xaqI8_i&%A^-6p9v$iWX7#bXb2AwssNqF!@stt=*gQ87Eo! zOO`sljyNuV6Bl{B(4Cb_yhX(8+y8};As<#g+y@2@m4P z@sWSjd3?<}&(G7-n!UNQFQeg~I(yOBGt8VAIi15t7m=TMW^4lUW^@UyVH$Zun8r{+ zzA;2w@mWr_D@&Y~&I& z>xn~n2$KeRQMJX=J3dMwEg`#*FUFqpKI+~Ql|9FkMb)~Gn7fGYKLh=&ce0*!SVMb8 z_Fyxb8g#Z!#tuA@J%|f}##dR>5iPV$rmvv~&EcI*@_DsKHU`mw+PWa5^}g1Yr8!#b z#6;)qv`gn<%6`S##LxrqkG6s6k<0-dA8KU{=@ZDhSU~+LSLqHc*xXpRs=%xtoB>U> zg0FVM+MsP6atGxV0Ln;g0Fi#3?qKboGL(PF5kz|zn59Sj826x7ot+N~d zDz}Arza!3O;z-AKby4`+ghQ+6y0O-FYk>X`G|Gp@FPnZcb~@9K#1U;Np5h39uM2m# z($+rc=;*@q!*16P(x+~)G=44Rwa}+W?!SinWtZ$cT5a!_ZSF-s4yGT6U`OtS9io`E zS?tKoW3Wk%IrJ2I#M4o93FxFAok4P`t~%5yuBB`vr|7qO?oY1ceq-4U6&8M! z!Y<8W22y^VoxhmzQ9ZKZ3$#IZBAc<4GmeRC#<7c=RC}unlG}9F#|@_?3wm#UX%%^H zi!SG^&}GzX#Ubf3EoG79B_BF$?&207-)C`bY(4Yvu^Zs#(qXwlX*8*KkvW^OBdj=7 zFmH3?+pJ$6g?3nHGGUtE>?^Q#aN_uLYVp<>yj8T8jz1-vewA<5+=_hFf1J-v`x$?h zw>x?_@u_=Ed28NI-imMH9%tT$h8CE4yP>hRYT9n^qfg_Uwln`T=gvk78GEAl{)`QN zDBm;+;{g4C z0KND@`mhCg+Z$SV7FttW(d{T`_Q?G;jDah;v!GX3TSG1%Mut6IJ*MF+(J>8wBb^$4 z9L}eg9TKfYusyIy!+Ze!nQ@@GXiHhhk4=~v2e+Gf{QIbrKL*<728|!0UTwtBHwIeW zntbi`jLGX6lPegLD;Sf@snc@mw46FEJM>G`FIHu{P}Xg(fa>yLevr*pkrUF)f<(gbmE zEt%ocMiPw?&QFxj8GaM2LH63U=mOTLpi}u4m_1$9L2@{2eK%O1Fob+v`*d!E@{3Xj z{q`b1+0(>RCM^7T&1(zmH~fb5tABA=>5aWjG^K9~X)EXG+=>vN^Qoi4U0+0j@#iyR zSTyrNv$mVDbGY?j{A_jyth;}`pSSMbob8XVa}LxVt-E5I=-fbF@O9P&^RM~3GgEiI z5}uhl&eD`Q%T)WVI1@C&wAmJSZs=M^OXi!$37Tj}@a z+)(z5Z3_mc&q-zf7Ji93OYE)K;PJ;iODt<$vo_;DkX!#7v+7@vuD>ZKd495uu^*Hc zB!7}sNA|SYvrkPMwiP7N{k%5t-nC&~G}8w5yFrgd@krs|lWm7vCvTyCd(~&)FRRUY z`dRcRJ}LegkI=3N{=)M^fArk`*81%!-wP6ze%ke}Or2F@eBeww;CJwIohjBzo8Y~> z3@tIAE75!EFTFnJj`+7UXAJjcdVaw4yJU!Hyt_Rz^;R!%z8=~mCmV|T-Hb)*klrV8 z9Qo}yk^HLj_@LwobK_ZlEaCykPR`c1eja(^8-F@*O&@mBhn)wET%}F$t~Zgz;z!bp z+mW_?qK&@jcyC~TdIOzMGPcgOM>rw9aKaob?a!?}du`Vzs#GWLFbUGp7Hzvz8q!#$k9J^Jm4&e0QfA6N`J-{<-Ai|!{u z_iBrHUl#4>se8Wr)%`kVy>F&ZrOPmW%swh`+`bXND&(KBSL^KaBJdKfTTBOUMlUtb z51g@B`>SH5i`GK(COp*H!ZU~3o(-y?0nJq#W6RmA$v8mAF*>~Td3_bf^wG1nPnv_Q zK2d)#_EW*rTYl-|FI{K+4K#-qEug<~e)*uq;4akp*!LBqj_|ITDkHaUg9)RrJKJcl z=1@xC_kq}AWOie0W#37fXNY#*V9iXvE9-`Q?_3DC!XvW&&}@{ zHzvTp_{7QbjIW+Ze$`sz?Z+HBDtnn3-_nVkJ|tbcBoeL#lwy-J&xM(_fwqaHS%BTF zI%sN}NIGaWhF{LUcsL(X-}fzqM$m_1D}yBdio{Jc?P5OGJ|pPFm$9>T3F#LH*we2I zZ3$C}i++P2jiC#3ckK-FCVUrjJ=uoM8Z-Kg>@r#>H1VU(X25zY_A`Y?`iFg1YR84b z(9ObkgTr?>xOqJI-^ScZ7ADP=(7W!&ybXM<0bi@ZR}1)R1z$JHW{Ax>BDvJCdpk3L96ut}om|~@aM%D=kP~dgFmHl_!BJr=~wvEuf<k)xtuM-c z>H0=%k;m*ic+)|6(*bbbI+s42ZF!XK!`1Ho!<;@m$e23-Zd>Qlm$Nn2=u0!V9*zBS z)Sm6NqxNj8X6;8j3pxzPT%JCqpSHuJzPrWp4)v)GGi&0tOZRMNo#f!+MAH<5Kh{Es z@A!g&!QVOg`Zk9zMBxjna|?BDrOr1Qelb4e7ixny?sw4VoTr4J8Y4&7V={^^@g#v!YaSF%e!4ZS=S z9kpi%Ynj_?M?ya%_h5H7<2U39p$yCB3D6I+W}?Hr;R#`w*66f$ww?8^9kti(d8+!l zJ+G~z{71wit^@DLAITTO3``$fkdKb2dnzdukFy+wrc1sdVF;DTk0=<(b5B*JypGY&(qQ6d;Z3>)uT7Uy3(5` z3%vPadLD-!EjtB14%`72>_>p$|Aalp=<(j%&+75g0|WH^w61HzrKgq?UV*&_E5l>y z_sw1HBeGo?8ws-4m7UqAkZmXN>)C?5679tT_$2j>#e&AM{jlrShC2B>cYPl_d1U92 zYW9WJ7VU3aRhX217Bn%>YSbG1n1<*#&@aChbUxiYs^KfOqZ;}=9dyPU(a*N=yN&u! z0RAFrzKG4dd1*t0`zyCMNA_PE2QSSd8tR*`ZK!v?RudDQV?S-@aKJli3-*tFAm|+X zP?&yOb!e*_PFl_f8nWe#P(PEN7@@3!ChS??z?Stj?orU8Opzj04SuNt}O78Ex@Q8SyH~ciJ_FUt~p{Jqz!$;jZ_7q_@;&h8`{B_K22G_lAAHw_w2Kz#>j?eavJt*@ z4}9=``0;~@rhonp=_%_4%HnXiu%ot&|bdVZw&WI`14Zjeg6u1Tx09-RFpB3B#$qKw7k8nVE>L81^X93 z&&sRr?ctR%#zvdnpI!gmi_F9j~;_j-Q0+f8{LC12Op7~?g-w)z%!WYb2* zZG>^Vy>>}M6#R{%tqOPXcIL!8a6LY)OB0Q=Y`nmxzm{iLMlKG7n?gIT_Z>QFbmd%J z%10^Y&HII4<)^a%pkvOBDN4$Y`OaNG2=|3n%VyY%`7V1>kXhR2$z6t@EmYtYkg;J>e9H<4XYvMTG`D#?U_$lihQmO*EQe({M3#c7$~ z)gdgOJ;u~QvP-&v)+(@LtpA;x$M-S)XTol`VOkr|ydk!gxLOC>8Z^e9u<#SqJ^IQ8 zEq$O}>WXaZ90G4@Cw{r|X1%OD8TM^fy=yae?H1~x{9B@&m4JV2*hX)kmDh%2;nB@4 zDRd&c&+D_Z&q(_{&ql68->jd%^aq}gW&0Lw2)Ch)I7enfLzIKf zi#jsTt2plyHSIt8)`o!fA1AA!g|7Pr6=rRDTkPCWdug;b4_|GJ58iuStQTw6>=j`C zYQ`osrgdGrPH5<^NBi^%*^`?yx{LUGD`jGXG`2=`fY62q4zyoWc0}=6(Mv0JQhl|q zUeBH!^;>s)I=jV#_-ZfjZk8O{Y^5C0z}Iuna_J7QmY)A?xbo_Uk3*L`o!|WX!%xcI z-Yyyr_RcAZY@QQ~F&^XLILo59<84E}c*m&6ulMAs$Dl-G`Cxo$px0y7BTL7O4%**V z)+fpOKlTfJGT>p%C*fnpC*SzX$bVmZ3F@N1zMwApnG3c>-%q^vAKD=~2Vaq1xZ2Xv zD^d71@}%t%co{q`;nrXufoH|J=b)dpZR>e(u)gjL?|DS9o^$_=jk`_nONl?;d#(u9 z2a~<$DZ%<1rhCuR$?v`1a~0_?@t)@e>o;HFJ+I_>srS5|@^AK@AL4nP_xw@fZ}Ohm zW0>H%jy69V9d_v1+F@pog>Y35ZX)oa?ac-Ims=dQ**#D7)z>s^d%0kLee=);;aU8U zHRYGCU1-*gjc+XH%ds~je5bgrbA!(BFO$y+VR4N`{F3`8I$zp*n6ntvH$S6qK1JUw zrf(J>x`utwxp8lVcfLw|Y$7JT$}ObKf1#}P>bK}M_d2~p{>IYL(IfiSzdeL=d1@-_ zqs~7C+L%KBVE1R8eMp?I$_m5KMR+z}tCz@bSwZ{??EV$J(^q`}iidd^pm8t&!HtwT*^ zcjYsWH05I}#7FO%d!={PR}X2}Sq&~0*Hk*aYv(FpwP#~iUZsvn>oXdge5qGa2x5zQ5M#~z9$+tx-*zqQ?E!y?0yZ5tz!W*7ALX?_+#F!S_>qpA6Iac&v+F_fCwt1OCNd(q6ybk%{>GpIN-E_PX>Qk5Zno zqrbC|c=F|)&-0GjrSG^o$10wmVo%5x-uL4D!#qD-yX>8Mo(p+?n&;P_JN)D?3%oYf z#*=L`yf)3UZJO=1X)blH=DUFJC44XEyO{41zDxOD&v(^du1y91aQMlm{Wcwhe;y4o z{S>ur>f^Pkh&m7Cdm7*2d`Iye%eRd0M81>xPCa#PD&!oF`Q;OeS08?;raWH1p%?u- zKQ_Kg|E(gzB|?7fOm?!a%oqdtF*#NCph!l_PIQ5 zJMhXpQ(0Zm(J2ey#T z3D~-Wpscv%L2MTf&TDG9OLkD&#Cz*&Xx9B)SWtm2g?+6pYl9}OjhZyT;)yMHG2dUy zd+jy8-{yC#m!D*f^Ch-r1XFB&*k9B60h|18B|mJYCck?krd~chv^0BrvF@K|_Aj?S zpGez>4%{=(tkWHMIkV^CAn~*}>fp~aHkVh4r?K;uZ(4iA0!zD*y>nWYLc8CBcE6kG zyc?U2@JJiNa}H>OU!O-;g!5o`?)%)B#ooJ^R9dlNP>Pg~0Jv}G!7nLMxQ8QNm(J_~}zn9lHd zuvb+s9$O|7w`^Y1*)P!U1&jg3yFX7n^3=Ii%D0r?C&*i86v>uj@N`eF44$gNQ!RLU zB+>a(?zL>Y=fZCBG|l3v?f&lLOmuM`>^@Ghjq?j|ZfIgG`1ble>#TvJ+MASv@52hq zp_4y^{J|ebEk_ymhZ9X#Io!?)LY)0H+7-8dz^?NX@H#6I#`#H}IOJ#WN}j^&dxTfw zYYo}p_4#N9ud~7HM(}!1qEmN>wmo0nEna`g*(;*Iwx4t#XTOW{)9&N!vvJIMl^Sc< z$$i{q;q?`*v*+OTS9$RIbH&TS^~-s1{R+7LRiddAnP%vCqQ&*xJb3&$abHd}{YvBPe|e(w zw>EwZJ}SQkrHwJa)4CyWiigJ)CZD zv+*^r#SaHQsB#yc9-bX~l<{NMuceD&hcxxU#;Wsmv{zf}WU^65onH=VLm!%Dy4$Q# zdrq-cnYt+-(l_oTtSmMp0w|c_-^j}I1|=&UJ8we`$lu-rY4;E@f(k@PatOb?sm)Wt}#?}X^Ek(gq zZ(?7>&bamBm7IAW1cMgc_l(BOV?ku>zsi<;wJQU-#+3oAJrk={9`L2WTP(Z?xZc9= z1>R@jYTz~tCxBy-Fzp=RatogiywJj;wbd4$3B1L^(}C+Pd^Yet3r_}avv4_ZtRT#v zGwgw3#)HTpAlcbz73wd0`^S>i&Yhxu;h`vt!Be80_i zFW-OUi>`wkoHjfJ!8?5EV^bjX6P(3Y3tSiSy@KyDzIkovo*h_gIc?CT=tOqAFJ5NX zQkXA%4!8xH$+G+Aq?KKG;dz-glFNZx$g7QX(D=8hg7Me5(u5~Ew`v`nG+HmzdP>8& zp-)G5WneFVF;-f^UEP^_UN-B`aMuZAwx|2u&pAVD#nholz8tn)v_rB}bN%Pv?0UcZ zi-cwQd*{L3?L&2rqPKRICyv$zpsVaN6|3{C5qWKJbydH*K0v=Pdm4oQE#8@ukKc=5 zklll&b0D>5H{AAHnU@Ay{5$2v7&7^|d=HSH`m#i6y)z{z@q9dIN;(=- z?%a9|ew#0ueFizWQG2p*=e1vLaCkVQVn$>?Ho(W(`dAZSYB+eqL@r zMxD-&<{aZF@zeV;a@y8$=9X!hH@zrps`eo)>%d>Mu+DCK#=@NYKm2)wYEc`3rpIP`9z^_{PXTY3qWa{%0aDZS|-F^x@ zz{39sTx{VNfX}k; zwlMw6&W zDd3wdycPH%3qKB=wD8A)cUbrl;N2E}82C90KLq@ug+C1ZiiPh7{=J3o1wLxwyMYJv z4(ql7xY)vX0iSK*+kxL>;WfaQS@;&*hS7m7avc#4Im0asgi3h*@+o&>z!!V`f%YT@y~brvoK) z`*YZ^;tT^Wx9||)^DR6O_-YIH1KwcaIPg{r_Xgf&;V3Y7HkmvF;9pz#$e$?J!hZxF z#8~^>XZ2~HyK2KND~rGd)iR$|>&{tqCJ@oX=Z)dBd%x-Sm8-_vcM7|C&$!QN3p@`dp4T%43Plx3y6P{;=AWf>+Zc-eUE+~4C1?L<%U~S zKUbfd*4%Ro^GZ`+bf19wtkyGR6qx6YYgRLVH6P`>^3JuZ$9d0`w_4#U16xRN`>l7b z7U3yOpSy0mYqj3>m9xTUz1Q=M%J5lj z*YmWh@LBEE^GYhDvR!_6+^#67E!J9p8VDcmnvU%r2Sd%d0wyl^iJ`q z{sxCT{oZ%u-5Z$8q}y}LoohC#K8ml;x>a{u8RT4|qE_F%qM_Sw~jflDc@Q4 zc^t6tP-&mX0}F3e_E}?eBHwA}g!L26SMc3<+K`oggMD`K@7i$l2UWJp5WRH!859{@ zGOZvwNbfRaQe?6|T~p@?>Kf@?hMW~S z&X!I|f8J$DUb0D%v-R;pEJ)B)7dp)Wr|5TjUcoEekWh> z%;QC`<4Aq_oP43vBj@VVH6wz~v!S!PzKujG^93GfSXJbFeY(abXtoW#pzGU{3z>7g zg*wJOV#LW6sMK?g7rpOEf5Jjf4!uSo7NOIO56%hZu%`0-V&K35k%HcR`VTb!4;akfkin5&0|rOLN%BkJQ1@V7kvfd72^?ctN&WykC;Rv12R8Ts&axdCaiYCdXF_Qy0bJLptB z6-1)?bj>ar=@ltNO^L+fSugvdp+x#e`s&vXKTvj55)%M)ZHT@blIpRP%=g62db@0sg9k;FXriOkoh zYhpjBy6fwc3%T%kOLeuJH}B*MG^sC)Toie4 z`gBd<2VK(j^~r@?dc37xmj0YvfhP5(k@rR3r%%_s@&wsPmq#wwr)!eSBUfYvURmQl zk*gNJ+t1aD->*+r#^%8fTGI9P$%R}KS^TauSRA=lpRVcspzFH6KDm&k$6M;M^ylOX zG^v+HmPeNB(>1R=K{nEg$O?VBCdm!D{s#9s-o~v=f4b&=!XZmTGji8-f7WSBSm>tU z6T#E??(GWxBN&K9a%-e_!Lovv3jU>_PqZp}Vf1^^X}!+rHM7^Py*}G(VBtp#w-kQ7 zu&MAr3;$TSuJ>kRUqsJ7F zEgs85>A14-6UI*fnpj>jX)?c)r<^_YoEcN6O$X-RjC0RBXV$FD`iYrFVtB>^AMIr= z-sZ7)Z<*r@3SxM^>SF@?_GL}PK>hk@HKd?mzyM8+3kD5h^<&78(}oTm#wy6^r?a#X zzkBj6({5odY)#(E#LT{PdjDN@y(aEGeVD82b+7ctMh>65Pifz$ll3~WbcMa$Ct@sQ zT?^`y6BJ8-c%kWY_?#2Vd+gyo^KE^+$QH~K)HTw(3<)B}0NFM5DKJNN&D4hUKi)#! zs>pyW(?PfS_V}WI$VcuBo(T>HzYkVLei6B>Ah_d#S$$=tV$enl`^0(|_KNiG9l?a8 zQCtwkwiFcFg`_le`=$-ShE2Bzn>O7T+_-5|I5Lj^|0yinO+RPG%yZA1Ras?|t-Nv7 zO*h|i>*_VPt-bw@JMUVze#6F1cYolXd++<8B1{Q-et-OB|98a{uHBlP7?HS*);sZ6 z4<6)unC}rH9bvKX4@5Wu8#+paBXfh`cSJ}X<@snNID9n9Z=c`@&h&pE!VwP6PaS=b z-=o355#jLBqfvhQJb(1)K*GlU$I+v>eGs9`rzBOH8kbV=1oMA+svKmzVroNT>cIxj^-${Kp)sSjTou8Ub+&O&bnlwSMG_@?X+``JM%!BnjKId6s z`ka{)J~91#RvJ<~m8Xx&`&#OvRCVg_QwvhxOU+ANoZ6YXH1)pJm8q*zOH$XQu1#H+ zx*>IA>Za5!snw}9soPR_rZ%KF8QT6`pSnABZ|Z}o52ZewYE3ZFQf%(!$Ml|x2do5H!n4x)?A!g#NW=;E?RYI>Jt9m$KPfAU75Nf zbvb`mr52}Z_*;^Cf9h)ft}(4vyVY{F{l?Tv{%+!L6@RzzcQb#h`MZ_BHTLf|aHGFF zQ+K4+rfvsI>r;27)`6e9QyWv8z|y^`52Wq^S07B>$KQweyPv-g^Y;LMt^7U6-&3g_ zscot4U{bhz25kOK>MQ*1O+A%jpSktk#V_nClj(a;k+_Al5N5`&?uXhCL zzw0}`+3}r@?{$2?;|Co->iBWTPdfgkLzl#6AlmBPzNa~8z zm8rYHU6q>G{-isUM=OnowFDsrJ-fl-YMt zYCWm0R5!}5FSS3_ixNDT8b}>LIi8mqOdUpPI#RZj9c4O%QuUx*hf%VAlx-*#NCi>C z(bPyPf^r^B#Zw8C_9dxgY8++$VCwSJpHuHlJ&MwQ1m*v()MKf~Q45|-J&}43%K!bT zr&8}jEqFTh!PJLP7e1PLCiM~2h)KF*#upSJ8+`9__r!h(g1_;_36W9_gygZZmUacvQO_8r4{R-VPOjg;FnJ&$Vz^~1eV9EIebb zf#tXp&+s}#>|0y9>h#^?SF`fc;_~9ticdFT=#PQFxd43(O#_%}W@mmndil?KD&w1% zHvGM9^vc73{rfq;%j-G4t14)I`st6{v4OyS~7F1_r*haP_9(RV)f_`BZy#Cx86 z?^Eypzz09{;b%Vb(T{!n6QBI_XFvD(FMRP!U;fIoU;D;4zxC~3{OY&A`~4sO{MXn2 z{*N@%^cVsWD+9Mqo~8d^qknJmSiS-sBwtp^ zy)qG`R@0=|AXg#`23H4 z{F9&l?B_4M_={iu>ZM=*=4Hz4KmO@IUU~J;sn`DU*S{U3Y(I{j*+`7Se$9TvUS_{# zzhl2=e_(%Pf5QB<40|ZcvE$+uJeT@s49i|)e_?-Re`Ckk>)2Vk1do>f1GA{(?4K;d zU3f;uFU|%7&JSuaQd3+-wZg?xW{fu?A#kg_1R9U7} zE1I%g!A(_Vr6O)OuEM4_Y)w z{1$)CS|uGZcp6B9%1idtxB8HuIyDhluo4!E9|r`zF+CZl5)Q?pd3&R zDudiYU2!N*#ia}>ZpEW`m0`uF_?3VXR6KNWn#>~npmanX41oPx zxsdHtE@EdYHg=X`XJ;!8)Mq!_rFdAQ;$=dn_HswZUS8l?p)y>SQ+`?SSt!zlS zjk%TEnMb*Ud6hfau<{n>Q|@AZI}0oKuo2~67E#{8qG+cv<$e}d z9$*ROK{l#9#Kx3|SyFj~jVq6$MpB(DL~SfWEi6WDw4!EIp-z^dPOe6sT!T8f3w3fk z>f~vtlc%FjHlj{8p)Q(G7xPdDRn$Q<>R>+VU;*l2De7Pu>YxR6upD);0(Ec>>fl_| z!Fi~I^HB#YQ3n^G4lYC;T!i|!81-)n>K}H^E6Y&-s!{(m)W7AZe=AV`YEb`HqW;yQ z{?(!W)uaBcLj7Bd`nL}CZ$0YY2GqTcs1FUO51UXQHlrSFK{;BfM#dcB!Z!zsgOG=w)? z@fa;Zvg{h<#SCMM%a2@f@lCGKVT$xG zabJ#>Md>-cYEUf*E0t^;Xcwpz)B_p>VYvx2Ajar6=vAPjpqoK7sJIvO5a=<`6QHL+ zPlG-N`ZVbCAX-EC7U=t+AA?>3{SNdB=okpYU5qKQvvn_)Cg(? z?E?*h&I36>eoz8*1auRKzsv{t0O;MI4}hKqeG2p}=!c-6fnEf?4EhTQx0qQm*8b*# z7J_O)YeDp0i8j!FkR3$tkO+fDLF1rHK@*@GKyL-%oz3ihppSz-2YMFtebCQAFN0nM zWk6+StU-e2ftG^Sfp&u0K>eVLKz>jZbSY>8bOY#a(1W1IK~I4`4x)EHdU9U1GvxQ%A}s8RI9$OP zvjuP#wFR9*ISNaD7an?#xPpGyP)wXfylxLvqcK;+8}+fUAA7bOp+LaKJjt-f6(nok zkdsCIwy1}VyCNYL3c6TqG{j<_h|9%>Lh%S2@+Mp?>K$WIR|0-q+-T4XMMuaVLeyOW zuQ>C&qEY4=iQD`P>9QeM#Lg9sd7)*CVe;IBTP@A3h3!Gt*T&k}Ue>`nSr_X@H@J`O zXT7WsFSHxLBUlI7A#{s}nLT22_*^lbCOb|=RHal;pTp~Qcq5K@fW?DOWQzk2MNh++ji)-UBahJ_;eY3B5)ZUuh8)d9hooOx;Lv66xKsRH6&C+26LgTYDlQYg=$== z#to|Rtg6%IcB90dh#smAuccJ;{FFUWmxI>=J1W16*G@`)*u&rhPvWDlM_I(>_L2ve z6BR3*6j>gN*qknEDon&68ycFEsA-KYtVh%eZ*a&P^v06Bq6hGNew0y-oKztNlSDlZ z#Ho?Qyf(knJ2b?iakL8_$8aR%j5`oXFY^Xtl-Yh3ia3W*&3UcIdB7HR#E~!;>j}8r zHfD3Nkcfj`-<_dRG!@>Q`KdqT_Bw2S#F`;RbjpVOArvpOg%RMGh*z`AAG0xc95u-m z2#H#sK(ceI~p1FA)@nW6ou0$Yo3G_7DB%gbW#g<1vu#43$NljBdl{S zCl^AeH{nH<_lL$^LAQ$~vt=-tJsU!k;hE=%N6-a1k~|T-SK`(v5u6hihrCEVUa>$G zhWa_t4^frj#m{5G)$O*ZE887%2C6YnD9*dSMngSpF`PGwy3&%3UW>?@b|G&!sJ3Ty z+J#P!(CIPgpoGx3_6YX@;XYt+9}q51DzIqOi&sNXU&Py-D1?B`5kVJ-;zExEH5*zq z`f$;>WxwHx2i>+vJm9y*V=UxGKkQ?8Ck(uGikjsY&?kgZ0fz;Q3$RB*K3C9=%S1~I zr41Ssu}uo-_k?h%LH6OlXdi(%-is0TC#m0$#(6PBsQ=HM({&)rLCa(F50N%{`3QCJ z{6Zm_C__C6I#{bnsarsMF2#L%PZrfrc8i!f1nd^+a0qZB*KpYohdz$31WWG}Sq*9c zoepXOb%73o>>wW~3`&451x@R6(0mZRE3Fo^4s;sm zEKob>T+lEm2|5b81N129BcLyXo&)^~^a>~qD#BRU3aSBZ1f2!y038AifyP1Cf$j!9 z2zmna5zyyAUk5!0dJ*({&|g3q5IqP#7qkRa4XOdvgU$eTg3bf^Knc*Lpb5|opxZ%j z13dtG4D?>m)1Xg)J`Z{p^c~Ripcg>D0sRT|7f>2xDnfcd6(D?zm@Naz?j)U^Cd1@Z07PJv`Ca4WG0J;F=0mVUA zf^Grb19}(e8PFF%-vRv$^gGZokXnK|1X>DO3pxX|2h<0$gGNA?gKhxb4SF2(A<*YR z-vm7edI|I@=s2hhySbKtR)MyHT0s4v^Fdxv9CQWfcF=vGCqYkxJ`4H==trR6gZ>UO zV-Hvbs2Wrc+6dYXItSDO+6(Fd4S>!AIYGmqC`g}M{TC-uVr=s7IaF>Al^YKJPtBtY zL*&UbhU|!v#_DpYtj{8{gUsAOF*i!gjyER{p-(Xul_O+*4l~op6qQ3xT;xn97lRXr zs@x63TT!oO8pj(4w3B8JVpJ)|N3$GKW=FHL99zm60p?J~8IBxr%4t;(cg#(BFxklt zb>*N`PJS@cFwEzSLrTN+2lKAnq>jd^`k<1QC&Z{!j8hGROgRI|jc?^7Qw(J%4?&Hi zSHqN2Sf(*?cFfEDWyiL;Ij5XH7-tuT>AolyG3%Fet=;-)R!;tnbCEYS3DH*%MBy9f zBDn5E}OLe@rJuP{%hH4ulMY<*qA z;4`-%Ay+H(bqRw`Zb3q>R!mu!FsK?9Bt%5yx`dnt>B|!aAGvi2xo9EhK)KngoHU6Z zC>pR~S+3162@?{r>=yDnqp>6=fr8D}nd~Z@P;R89A90$!iez=Ugm(p55vnR$60O)_ zkt0G4!N}5jTsC01WzXR)cTV%OEJy2gIR@)?SqAHOxpP{_%W`}@FU!#iN0#Ahg}K;L zQ2IkHNFOdhftlXYGqfS1{IJ0NDDW*3o^JmWj*|T8wEH_1sWM$FpSuPAL z?F`X!1J)a|WrBqwTKL3jDy^6DGRcZ|XM0+a2(eO{HQY+8in6o?Gzr)(pjkkRfIR|Q z1+)oh7qC}Ahk#B2T>`oV^a$7|V84J~0eu4c1q=u{AmE^YLjnc`92US=Y6GZFF%v*CYkkM5`a-bT_SQ zNF9AOM6g|ar9_+$dEId=2GYWnD1>Yo_3-5pq18+4U%c_|7Aq-&(Q6_tz6lAE%&WRb zELn(itXQCx=;wTaTW2VXJl=?tmP7bSl&_FyYXY^k90My^25l{OPHipAaobsr+FF*O z)}Bou!p@!}_}n=)!7N8H$T5gPmO%`1=M;l1$77J?Cp5 zg-4Og;@T1ar4_L41~Wb(x5O31{OS)Lp08de#lyz1J=n$WiKFXUsL{0>hSniKA*^t#+} zy7AN-!a6qy6i<0zNr-N*(vl6s6dk)F#Xaz|fR}^*H=m3BSBT61bsU-o`da&X z_O&AGXFU9&sMi+s4s8Z)0b$iYuo;AI!AqVBP>=;E)dFlL$RQq4n<_V%;hvM{V=**e z$pfjNoE$GLz#dmTh5|XBM$g(Y!@e2em|@3ku!9vT!~(Sna(WZ`3E^U)jKUQMR)zRq z_Gz5#Ngl%!@1{KZ(ZLyhHsv3jvwmhiff6i`$tm8sVKSaOrfN*j!%)_Xh$UWcffrox z1Bse^(5o->1NI6Fr$)L!Eri@`hD{1D7frkffH<@6ds@t?^H`Au!=anxsOP}6cHWfG z5YqIgQ>;!+`V{9`vLeYyjUnw|vKgJnC^C#h++wz{awlAYtL2%nQaCx_TvFfxW?)B% z4B>IXWN!uz{i-PEDVCv zAm~Dn?|9gj4pI^?45d@*TtrwTry3ws;6|q?%;^tdi3vmGb*6)d$Nx>zFy;dsW(tM^ zCx3c{5jLie(o9mSy@)R3Mi3KzLK$kp{i-RR-b5ygC>j4tn+1%nBXmunYYbg$=$i^U zy^wh+^GN3CKVQuJKBJ^w$~=&nliHu(nSa6Y?);06_vG7-@5{Fz@5uiTzGD{mH8K?C zD>GMcoXA|o@tVxl9FJzM&D@Z=F>`(9I?msmxhZp7=Jw33nOiu2XXcK~-I=#$?#jF+ zb5G{p%-b_>%iNDJ@5{U+^DyG^Q0BqRW0}V@@60^P_1~R&7svNxp5XZ2%#$47mw77l z!OVv;AIQ8v^GxO=nGa{4&U`%ciOk0`AI*F^^O?-2GM~(RKJ$gl=Q5wod^z)#%$G7> z%zQ2L^~|%GuV%iL`F7@;nQw4Al$O~Z-^+YI^WDsMGC#~bpLs6xgUnAdKh69&^P|iQ znHMuZ&-^U&E9B%aGr!2ZocV3$H<@2&{*d`2^7MB+od3xDDf8R(@6xYkUdg5I~~^o8jQ(*5aybYHqR>#iF;lpahU zOdm)))2_55ZBL(+`9zGhneo6vGj?)--I^>51Gbhf6-{OLg2mmbdA z52r`cp>#0I>-x8*Z%f~jzWD^X?*4=HbLsD=zn68tGyRtI9qHS%{JrUSr0+?;JASMLZf7=lfBL@kL+OXp52hbD!T)>GPo|$pzk8DW(exwf$J6ghKbC&yB>B{^ zevy8WyZ<=-BaY9ff5`Et>7Q`?Rr;44b$>6Uf1b{y|16g>LPQNtC z{i*bOIsg9j`zFb=BlZ8o`QL5m1q+YAl)3--1DSh|KazRJ@y9dw9XF+#haToV2y^Zm@}c{@ zA6JUU-;~dX;q%>Z%I9P7`JOlB^MmmDzBlFb8Tf4Yr=IFJg5Sdxa`T%C^9770&Ot5s z>hXs%yN*ASdG`1_GmWSXUpxNGOcQFz*HO;R$N!l5#_=mNf6Yu}j%AK!{+_uxlg3s2 z)yy@J{teRCA^iuW$7gkw{uM?r-$Yp7LO9<>7~h$7%wI+w>V}UWAjaQ?h40PU=Wmfi zx6E4GnD?(Cwm(K#KS6ANim-n+Yb$?2Te%Hw<<43AFoyd-caE((v^v38DgGxyA^XN7 z6d3k{5+J@!t^s}UCeUWk7SLAEHqdDxI!*_k0onoD2|5!*$Jr8h0UPD{ZeX)K-vev~ zwSn3}dqFrX`VY?(;JjEp@uzF(SXfp_uY34!_!X;Ui+(2cR6o2d;!XU@r}0xzR8W*> znNtQd(fRa0wUAtyrKqfk$53cZjRVD+TqrkA%sG*##*|I7`5n}EE;jD&zX2U zNNz}TIqYCzj+d1#CyuAT6e%p#Q%_RxCXS^ArD~z>Pxuyc{hVx(Ws2d+(ogxX`!OQr zjHpGT{3oYh*Zl8Fzldw@Kcye3Mf%H-(gJ#^1^?;igetvOfV3p)I=Nh&nzHH2pHe6C zs$$xFpj@EenX^y6hK?& zD74wsf6~$Y%!HyHh_cp8oOJbbfw~<%WRXr`Q^@FCOsMJXfg+4@hdpV~i3 zQ2+CFy&UG!pOfXzW>@|>eL54hpZ*)uPv!_#ijp20Vukb4tuK&EA>;HM{pH%-X z$S3_LLY-RwMU2S;>CLwOPnUw}<2jus$&A{Qb4_qnB~>N!^XKPR7FHHo^NPyoe11Ol zxrJq_MYGgdR$6K;HK@bW#hGN39x7i7O%H*rl0`lAI@nnajjED*OFh>l4LTP;5qlB# zeB3si=~rv1DzWB~o?aUSDyTQp#ZS0mKRb`(Ojc)>>+#QN=qa2TDJ+qv6i>>9%EI~i zlwNBd{pf6wWifsW@ms`c5s-c=q~u@xMBdIR6SC>jr)v_@=(7l|N8oJ!&nXkXB8hYO z_@hYvCkrA5#!#5WY{}>GGsb7KMvj}#|I961@8fg+b1h|d>C#g~XtY8j&s-T&eaLb8 znK3>3x$dUd?;L;PnQl|~6`?C?Js-P}_A1NCf77L&dS4p(@E?o$;=wLV#DX55jc~{l zj&u@6d=bvOB4N&t`t2MOb{j{0jF@9A%H88JTY~gsj$sE!+@~S;DEt#2g+Gq4!x8=n zgRnzbSg4kn@hdA+`LD3h$f;$Mc_U|rn=&`ABCkTNP|D3k=At4HUg3vd9&C{v{4dIb zl(ckB9dr6d?VP?^rfcSL`?_^q8{xvbu1~R_y}p9jDC8eMVV7d5#|Vo6xVNU#Mg^wg zHX5#p`k9oe3^!4A1zopLW%ztXDGV0jvym2jxv{idoadyaMHM+l*Pc^~H);uwb4!cn zSK^}^`0U*R>%4{YaK4y6{%c(%rSx&iMY;-@B{})BYP@w9U#eT7Ev;FK^Of}3I*raq ziZcx_>B=&-xl@>^qZC@%s(SIlPis}frcDd1{Qdu{Pd{VFPSt$o_U(o0_U&hFKl_Yx z&f)BK&Q9jm;M-ig8n-LZ#<6C5Qxlzo+fDyTdM2dJQZ97JkI*yl1{-*%Z>t`l;WQ@{ z=C>n0_#Bk3xoa3OZBfsYw{KCe0`#R{?0qXBKzvJ9~>vqz(E#;-2sW`a@oPjQAI*TTtz~7y`&_T;+@Kq^24=$ zXb9EB>2zA1&aKYLoEu_~*SV0KolduN-TGl4S6;xC$=PpkhFYM(Nk1pZ?F>5o{+ws7 zZQ$|Nw-G&L!)Z<^%u&SFO^#M18r3~|VibS~#v{?sWr(Xtn20NHYw>t|fiunEpi<}OPl5|me16<6dub8Q1ZarHIVaAOGBaGDbea|t+)PL9^KM~~_rFTaig5W!q7@d_@Z?to_p zbqCHhTb-w0KdCby_Zx1s-gNVJxNl#xb^H8VZn55k1_@4Yme%bzZ{L0^Xgi$|-b{Uf zt_kUy?YG}{#~rt=x>NqY^S0aGa_4RIyA8Akxz7)L*C-xe6Gu;F!k)w`ww%@A4WwtV zX1tVQA6__d9$pg>!BfLW@x<_*c=O`}cslsQ?6Y{s&NuKZ@Q?6bomcRzZyFc(rFcu~ z4!rAiAKvSF2=8(YDwioYD{ogGRi08ls(e9tR{1Wzyz;X0H^pq4Z(3p6Y-%*^GhJW` znqsDe=@Qe8rh83~n?7jzr0L7}y3_NfpPPPT`lBgrD$c9STbZ{duQ6|b-bH!gyhPqu z-eq|==iQh0?!2e-KArc~yyx?NmG`^6SMrYK{WGsrtx{L0o77!uw|apZP%l-lQm0q&5O-z%sb6{%=^rT&F7iz=7@RRe8hYWz9MzA zSt%~U%XEv26#+U5wn&*vpBTpbuFd7;6Wgu_iQgX zqixrYvd*1_=QQqaE^aMtuiiJm_o9R4j*0_^4xc;s!b)3pwcBf597uSE$3j)Xa3s2L zbV>5k%dR?d#nLOQuU>ZTQC!k#eV?`g@pXReqEWF+k?&EY>7Q`LOGQge*r8ZjihYXs zu`=>QJC1165$(Lee@jj_*`XZfAi)^H#6QPls-U+MaeoHy_=FV+=aCb=$u##X#=A_7 zzxjCQ=weCp@#MVmr?6G0uOMLGfZQ0_cqHD+^`T7ryY(Y7EacyS z+-S#^jP!7QJU7e-z|w<1VC(1hAurX90ONiamv=!(a?&BPIfETsU&e^0^L2%yl?IkI=lxya+QC{Ga-pDpeM%iUHXKhkUzn0 z5DO#4Q^i69pBzCs84jUcI#nz*N~et=-kwm7D~92ypz}F%E#>98FLh_n=v#dTUCVr^ z8F>r$ZJBGStehkkOohd2okm<`S+HP|SQuG2RV;L{Dzj)B?Zs2YLT9mM>Cz>bBrRF8 zq^u18mV%a4EL>c*WX|0AOO~%#p&1WTacQAerkb^y8l$*ITfTCoQJ`@}%onxVy1Ek` zG&sO1KYx-Fm_ki6!J(jFssp*fp}u~SgNgenhQq2=lO2l5RH<28K2z}1I#7hytXXY1 z)~sH(cCCS5y_)i7HSz`*?DZ!)tcC-eDk~>BfvJK|I9RPy9mow18#YXGsNg;p!eQga z$qoz2)Z+Q8m(3J>c{v`R$sHB^bS}MprV3-nv+=?*Ki=8+cDzI8D|lDT-|$YwmH2i* z2j1(S#Me6?Q$D5qK>4#$Y+7X6V(K(?o7|=&rni|sVEUTrCDUI_WqEaZt1#L-oEOcz zG4IhltF_#kJ@nJX3(6NPP!{kbduFXv7FRD^q?(r$EG=55RhHJSuBlvEUQsu+&^~RmBUi43S@0xuT@ZGG|^TMldvr;3E|bW0(nJLY*x%u_E-?qD7a8y#{E()Bega zq9~v8V{G}fzcqN1`sCjx(LGH4KVA1URY&sEb#ODN{x^$hjg77;L%2Q+;o3mg4O$v_0Ii=68L(ic{-2GG^t1BB zI2q$UJ1wM;j#JpmYOOw5#tKugr6}^0gK}a#7cZG6?@r9&S!o$7fF6VO(*>EUC%W3n zwe;FlS$A^1^}^iBS?isU&?!mKDpw#APaUd;fKREnfwzfM>%kVXFdFdvW-$=Xg+I%)$y4%KddjKM z^YZ#Zrid3Kb|E#&NTTcOIyyfS3M=|BU+2UcioSoDq zZhn2QrS#ZsuXk9=j@|isr^RyY?$=MZEI4-0>t|RN9=rGT9hODM-tjtF#QtH6`Phx{ zm4ECO_$oMdJA4%$dkcIO9eZn5XWp^vp)>#3P0*=4b}MwO$L@em)v>!?-(;ycHu3sa zi*oGh*SA?r$F6z(G)vyGYhT}PQI8#cz11@J*mbXWS>_yjo3vJDDL?l1*DEaS*nLt$ z_r`}XUgzU?+`pzVJl+4Md*Ad-qVX9;eOyoXx%oIBx*{c;wyQHE+Tne3oH1$eRiie&0lh4XUNgg7hK2irKQ=vc*y`bu#BbA<#kJK_pz8 zHGeY2tg*UD#>fC2FqSh@S7!`QD4d{DXNb~FD!SZ&XPs>f$Ka4VC5;)PJ1Olm=+qhW zXC|FGLmoEeg07o6XkCeCyKa^jzHreCpSY72&8!vcWOX{F#kx9C?4Tr5iVv*Ls5)I^s>?P!c$>K~)l&rYLodMDH5uJk z7SY197P7+J$<8{prFoD1+I034%qo3@xfvf}CI|i@W;!{qStZa9-B&YxxLFrA>%N-t z`R4OU+LkqcGR3U1=1InMvoMx3)7)$fZw8fSLzHGx(d7m_G-wRR;E+2djTxdVb4;Xt z2AyV+t0&iK<~c8PF1)~STy()qW@Q9;s4Lq}&GI);!f_^UO9+P^D~|KKLoBohOOubd9Nbrp9D991go`DCG+- zx2jA!oi@KRj;la5jH^{y>nvxQKyPJTcmg9Wc#1b~e)ooiC>Vjx?WK z7b-?wJx+w#cu@#B2MU1>gm49+e^!cFW6hI{kpVhjEN7;<*%+QsI6Cv;yE@O3pwEm`v?Q_LEhm}E>h3u8Gm6BEYpW>A?hL}?}!U2eeTD~#b79CD|m zF++4^j)}C-pfe$I_2fDeJm-bZHMyWCW)50c;@PeT%?nhxV4^p>qM5bg#B422OiUN_ zwb@J*v79#_5uJVDP@a_A;4KqVZBEQ=^8{7Ors;#9qKb+0jH=T$rU{y4>ye$gF}>lo zb(CVvkCKVvk_i>3L=zJ<)8{7>6VtTlrOS*hT33|%Mu6f;Tql-IsMlS0oqF93*Pr^h z@%o#tzv<@dXQ8Uxc;jr;t|yDLFvs<7x_-K8)rspFN}UPo8MJPsvYpsndI#2a|Ag;# zZ^6FNG3*z;SNV+cl2T}@GVL@uO*ff7YkGFOURZcT;b#kfU07JOwy3)(Ty%TUokbrh`e_j>E-&6vd|vU@#qTZtVX>)XZOMU> zD@xu|@_fn5C4VcaFYPP6uJp;$Z~Pt6Wk<>$Df>#<56jYJD=l4?gynwA zvzFH^%gWo!W91K&KUMx>`5(()DX*>AU16(mSKMCl(TZPGl+4LHZSC4^H7i!ESiW4T zsj0EltirKo)tWVH)>;~tE}hZM(ttRf#C1leh7!}ZrAy6g>grdo#rNq=)yj@D4-H0? z*wEo~&pUsZE?aJo7as!06*i2`@Ry7zd8#spzDr(-R<#Iiv9!#xblGB5`6cBQRz*|R zqX%5MiRR2$@m{rh&31gR_4G5=Vh`|UMNxKw&N{o}oL!AgJs7z6V_d$cwQXQ`bIXB) z?R)nrPM0qVmE<^m`jRRF9g{Y5af$qgH(TPN8lzR~V-}JAAP5--a2DyWgiwhs(o8BKuPww|>_FwtY$J@oPo)Rw(eW_gM|5s68 zSN~rPR0dYDdCQh9TetKjuG(_Ojt_qREO7s$hef<{k={N?JEu+Nd{Y5kRnXSTD@-O@ zJLXREA8sU}Ez&LiYR$Bqgez*Y?kjOto8?S(rurN+>oc@ttP-0x%*MmU2GgdT-sUa( z`POZw(@duACKEm4MC)j~8cj{RP0cNPT1{;xtRQuoOn4}0pJ{)usZSpLy64&8zyYas z@X++?gM)*Ir+3k%=bopZov)wFfESod7sBZx-Pxv}aJ1VUPUAFT>iOhKtk7mNzTJ$= zv8`3~c(~b@+v=s?XCjqC;|62lnOhM5@E8%_d|HHk^*GA#RppX$gS)u*V68xyiiU{OU1jI+25KpRqc(hGhL2;?UEw5#waTcvCEr*99eBa50KUO<; zUNu`>x452fpI=74p-cy=6ZvIa-vs|M9Qc#=D;Ha97I2+qt5>fp)#D@F*W;7R=#)*% zmT?XI+rYy$A&v+fLE{TkhzAb~ajUA>$QqV6=<&seoR?A+Eh7Eg!R8=OHd^bf)a5O% zrjJ$?i*TXCEYf9H_RUG$H8Yh1sx$!f)=77dOLygM5It55;jTHE(Fwl7_3+G^d#olJNDZRyhP z9?mSqUF)6u$jma+PD(!P?c^Xc82Omx_pi6^oKO2c%W-udIB<~k4$+4AWo&RiZ+(=& zHEVJ$tqg)Gt*ywqZ@u*byaD~fi!Qv-W|#3t*;2OAAtEVosm{X*@~sY(lF5Wm2)oZZ z$5VmmRPJkN=tPt7Zdg?^yjOTN`H+3qh6bx2ys*hI*a?NWd8VtKdDhN_*6>;62anXP zUq3`&D92$koi(?iYGi0=C=wMsG>|4`ORL0j88=Ej1wY6d-h%}NtM&32**`LW=lqeOE4ZAMTnPysS5;Z(H{dZiA%@=8 zY_%-5?sRlsd-OVTGF?x~Hy}rl(4KPBHtUV({!QLunbqWKx~Xy@KHYu`*Kb^3wQu9C zY`;9D`FzTjB-x{bcR;ckP^f6*N9HfC#wWgSH*_J)Qj2emo62etxSo7&4lFE`tmfg7 zy~TB87bO*o-Kp0rypMtoDDp;)J_}~>QT4m-CLjEuhBx186P+wW-`~V znrF2>xDJY&jtF&12YS717on>c(u%8ofz=;sXmH@sItrDOyCi5iCr z#3N93S@|3aLPql8M`U=o0L*W4EPSAZzRah)3s3l3LdiQR$@*b3&1Y56udL{OC!gKH zf!iy7Y$5WITi|@r+M}ploiyC0$dZ39HzBl2tCx(DocEq|eZf&xHCJ0+`uMxv{e%dO zWTZr~$41_zer&X+V=Dr(-Ux^HJXuoy-nOSOoWDcLE5umpzWeTbA3w_9k7k7;uC`iB z-pOQl+Em%gGX@rT7H+j#t680OamoE3crV$3Tto;bh}1@FO>Z-of3S&nm?a+~2Re|# zYSvJ}Ydt>lCyx(*_`}b9=dk8F8x zp8I1vY8ka8G$a%<)j(lS&t8*0t}DT{gbu6KWLmdw-Fe)E85^dzu&wB?DmHG!R|%L> zTU*O&6-~o45zA{drN&A#R!mu!W6D};tw9+tH)DSkQ&wOf5;h5yvYPcwLrE+zWp%aH zcs6HAb#=}1T3jNn)>?(FU0bhU!aJ9t?QB3x!5WQ%h$6CJm6{b+%plh-U%G6`5@pGf zn)-TWNsV>+^7{HZrG79o^MW5_xj7#QL|O}oU@OAHM2$!W$TH)0ejQ>Vu?C#Ko2eiZXBj?haA z>1jyJh}j%Am(9a-3zgX4RmB#th2R(A*+}A-u%&1oC?gc-3h*^-B@E4FwXBZ2*F%35 z_|@2rsRodGFW2HbH+g)g`#&eT$qw4g7ZSr{l@uO$dJnR({Up?q}h7kz#fZ z+r=8;zlrU}lgGuF_3pv{R@TPa*5zwdD$@6D#q88 zg?~Q_upn$w+2xK9cMY=<$RjMuV&LP_M*>fBlHW0wWa7e~^M@}0vrG8bnT@i`@NJkQ z>M4k7@aZq*AH=>(m8?GW?2#AqwG2^xjrk$w@neB8^H^Wo7m0#>=t$_;(r^S zASL-7pgY-HxUajoxW5f~Mec8B_pp1x7vn3^!p?o{erP|y9?XVB@`s@Fa8@$i z$s<#Qk51v=$=-=CRIgxF>hjQ8Ernd0#j;-MeJzYjW- zk77K#^Z|&9*$279huG6n;lq#>J5G`P>;`S{Oq`RAqk z7uXk3f4;=)(+c)wJQwvPC?B{syD(C(p`$aaz#q5{tSE$i1$?!@0*X%cv zW9()2TS$J#exLP0-}xr3Kk{#V{|7&Rg}sU|ev>rCzxti^jL?>m^K~ z74xr-3s=Dx;|f=x6yk>m{ImW_aHhMTh`5;GFv^FK!VB?qn=#zU=N5(ZTUohMk<}_@ zb7VMkWtxPaV(f3GHY9%YrQ4Nk^6z1^pqYPHa#I29=cM2Qcm|6w9B?=Y{rK1&p)X)q3+X?B~| z(F7a<67REVjUB*%O>64{25nkvFE9c*VbrE|^#K#`e*l;SKL{MRX)T9=HoMl=*Q9AK zyVltPblbJwR-o6e^|cG!w{JJ>+qI@H@IkxQO?n~l?fnSHuC?@nk3zo(Xme=&jnH>F zw3arY$DuV6h8%DQMj-D6MjhHCQqT4yIP=+audfgzXH)8CD7T-v@q@G+Ox-VcnswEY7>+mP1V zxCi+-q;(Dey+c}eJ8*bNYu^hD4I#e3$Pn@on1r0r<_5NFn$xYdG`1pKx7JA*bZdTEN@9T4OiG$E!6<9PC86F0ajPltFyTe+0J1{Y<9Uy*GqRoeT z(1GxM4c$FJuTSe}2M+s?Pe7kfJ526=pVr-r{0jKAt~T&N@FWlUv|jQDY$J?-?*>M} z_W|SJ$xZ_P$bFRbsr~>d9Gf5EccQ)cwZr{Dw_j@=0DAq%2Vl^TasY<>S`X>P{8}67 z#r;|n=_UMH`vIUkptVwddIDNoBhVW_`2&3ct+@l}51{-7_L5!@`c&>A$a@5K_4FeC z0n|6}(SXSBSU~IR2cHaRUDSSTLDUn}S9=iY06K$OQ!~&N)b_Oi-9fFDcz;l9?gR#d zTK6C@B=sXwKM_PZKn`r{r}iGy+NoVRLR$Oo9^`*WYuXD8gtVSsU<7i)Xh`ep1KPsK z|9wbj80iA~!&*ltFdEkSh>wM})_!1oL_0jNA9f;IUl-CBjG&$ZLlKk*Fb+BKqY;!h z&=!T=KExxcVf!4?2kZvAqUfIxUw2gNX$9|zihcyh+XJwP^u1B7jr4s{ZLkCAhkGY5 z0DoP;V6>r;+(S_fuYJf6;Al*1KPZs*+eygDt~;)^4i3O>TUQ)EnP*Q7bLc6z(BmRfsJ`Q(ad>sAWVa3guG> zNY{&)jp+8FH`t|( zO8Jx7|%`+9;6h z*h0d-EiA%w04bhMiNjLvljxTikT@#QF0b3(h)4$p6Fi+k$oHZD7?JK#iAi8D`WZqB zZ(QPVjPku#O91;j8@1s$_@*XQC!y!Zc!2aBay;Mx67QE7lo*y60n)g^j&Va1#tnot zesBWY(BBM8J}CKdiB6lnp}Db1bKC4Z9UhD~sJy(uPK+n~!1m52EiT<1cDuG4@g$^t z9|n?M*e>iu?844C{s9r6kPA)m+} zo8PYO>1fhiKyr5j8*$zD`h}hkd241QJ-@_2K!ocIi+K3MBK#4F z-Vu~jZ>Q!P5$-mO1KV*Oa{zhyMufe9L{C)k_L#_bC$Jg$Pe|qLjS2T*@H8F?0J|V3 zB=-;@@-GVP15ZfuG2kJI#E*kNERpy?T!iOJ2)l8Ku2GQ>zA=<5uJ<7z#XAh-^#VB1 z)T;%P$X|q;03H|=NcGV%F7js>Nd9~hZ5aPjKj)A*1nk9lmyqh657>e6F(K*s?BJWg z1IdmbNcG0=5Ip7^3<)Pmr7eh|Vv3>?Jun~>5mBK?m`9Q8W*xFR_$ z;$`!R@a;evrv)V+1(Mwukis1&IpvpM*mVM_KXv&<{D#3(I${!o0bxG^B)L5(&?C_& z(H|84!{8~OB0w5P#H2h9p0|6cZ^QhA>YW`(@fiW~{vs^wxWXddLlV6b$ADztIRbyk zzc{cB<03*DA9*5}525_=op+w@VPNm>7ERzFN16}$xcs2RL5?K%OMQWZoF{pJ%h66a zc5)mU}()D>J#qnAmTd! z_n-*J8-hOK;fXl;Jc2$6j|0PKC;HcBjx=wzN1a+zAFf9+*v0%H7#DisxRcjo-zfCa z?&83`u%DC|PdYK~+p7h~g?_~0;`V($F+WZM>H6RcxU`P07J-=0B*9bp*fGEE#Qbas z*wVd6^Kk6P@Ez_wtr(`mALf@ni6K7k#&t0+!ola^weABgS`gR)42@E_=--pVE*_N? zqkHcKs3~5^Y$g zpz%n^?dIiU^SF7x=L1qXha_+JO8;JWLuY%d79SS=!am45S~bGXeI1$;>mA(~?~MmU z{Owrx;O&kOFt#x2tJ_4k8jfLEN9Ow!QJ`@rDBM}jw7_bNH0C8X|=4Yc( zVI7D1dGD}?x3id^)^ql2wt$d3Bszi3&?6*$ zmqfQjk3_G;VTpc;0f}LWBN8Ko2rnx6QHe>3kn(33*o%B2r21mRdK85dAcQ}A)Pw$J0Ml%dZ^N`M1$h`q{-eZG|2-=5Yc%QM z>r_cQ)|K|QqaXJ2ar?GbEf^;Y-Z3onT@r&5qq-dHSF{f0@`?4R znB?79$D(+6fUR)%M!dXS15ttFSkI#P`Nsr0X#EPj56H)xz%Hy`1%SLh*@n6QG3oBI z5A${tlo)ak^M1tZ6?y?5?4dn{B|76m?w9Dq`WV@@VO^{PdUl(yp$YvcklS_Gd?LQ! zo4Pu%d`s(MXm57#&`Sbo{mbTnf2@-c_DMVd41y>75hvEe;4cOoME`GdVZE(IAkS}? z2*(F`2jqm54`YNK&>Qk;&1km~;BJIF2JD2LB(NLta=C?no5!cMV;#;8Y;HP)`HhcX zukdjIo{p%*807tkA7M8zp}Tv9Ufk=`2HJ6*0@8KUj`cx`kB8O?p&thB+bfXrBS!AP zpilT8$2uaFd%!RFAl4J<`ees?Vs}#)mg9sxBryUxjYp%BPk^U<83pzreU6~WXLnGn zTMmP#_ymE}pGAVgo--uSBhia>%6)Jrr1i+KlqbPc{Kh5k3L}2#NBv>pKMbDIlK>uu zKSJ`K1a=G}o+Bt{@n0s)R#Dr)^kUJlrC>v`1ebUV_lZyqj4Ya?~_t) z$2u*wGe3~*jYy10c}((giAjm0Sl6X=B}YYhIK~h^l#>%k_J)9D&nM9jr1ZssH2(1= zMf~De7akad97y^OtPfMUI)Tj?4|!~UUT=L80}{t2y0DJif%*S1VRI+O9YBm*T@Js9 zheWT_&)2(sPGN5d>&;DFomvFQ>lu*Zo%H&7{@8t3cc%HL#Hd8P-yP$HPFz=n9lOL} z0PEL~k4oMa6n6X)<5;$d{BS$g zAAoc{NCL@y97ywjZ$kKs%Jp*hsBrg;WBnc1*Ky!s#Mf)X`Z?CShiw6w&sYz~`gs8I zE{wAYc{>AkV7wWYdZQA@Ag6pIq;w3~1qSWHp2s0D;1KeNV0?h}gb|T0 z5AJJFy%+}4`hf%YHz+(0kk+ld@_q*)rP~t|b|bj|LG!Dq-V&@H8G7 z0rGK3g6a{*b3pPx1f=^dzEKhG2$13v0h0SD;X#4qKY;r!-7UyhAjLBQJlu=%$2jUE z)&ZkHil-a*V_GrJB_uuwpn|2nT#1D)R?CcaI6)6%X=u5SKU} z7w)c65snl0#dth`ov`PS_r=^2qrhI=FC(P;Wup?EKHN9Mc-9M~aYg`0_a`G#J{An| z@{5E7I&goD<{d#G)$33s#LGQGa@dJVc@jwX;YMR3JX;*$qdwYfVXp6&7`BBQ_TfGp zkcShM@|a!RpNmU$IdGp2_w9T@K8^=cy^1@*+n>)p8d&>kuMeMkU&Df3xi%))(b{P6u!|*7FD{UQS^9f&Cn5oo`6$xuu+tum1sQJklY zi4RMR0LdRA$zwpuFGAwu5=W(+kmPP#g!fN=Ahln+J;K|MA4ucQAxDJQ`yp>c+tc2w z5mJBQ^}!wE4+rkc58^)jkVL=4pu~{GXduG-mr=pCI`t@kqA^`v~a%zYj?I<3Qf;4Pk%5o<7_U0Z-!- z>@%SLDdZOM90lKs^${=j8ML?IzA%vN`GMp=4y5~xNh!B`g+I5%aqLSVedjRkV}M;? zQ#;}fB)J>=6=)n30d^q%QJ)MKJmo`D@;1Ma+pwPjpSQxg5yHp(b(r&*Zv=#Ukn^~1 z0Q;~HB1U>tKZ1xS?)Q0uGJYX}i7?WI>q-*H=f&bt8_XX?e)=RI08jA=N(@Q&D3J2g zgZ&fy{%};-4M?r^+)cv@JRHH z3ilwnBi|B0s!xt2c)GuieHj#wVH^MUyf#97S3gJ6kAkOg;!@A<5c)2O9w51gfs|iS z$tQuG1O3{#l#e;FUjyakp#2|oeFt_UoN*w96C4tDJ=hmQ_J)Bp-U+%zydo0EAgA~y zB_G575#kesut!Mt#wAZkybb$H2;GF(M-m#AJocMVyaGNEjyoX2_W;QrA&*}`xQ~LT z>z*wrc$dT>>{FrZBOzTM-BRuh#TuG>`muh2aIlYMnD(*Yy5a{?yd&gJ>kVP}-v>P) zrGE(fTnK#;5l$R@Bl44w%FP`WatHRmki7tq?2Qmo`2l&l<3i6bF&-Cs3CSnHQ+Xs4 zB0R^Ka8Cj$UlQ0yb6^1ZFfPIwmKXqb9q!i%DVz|n2RtE9pFPg|Q!n=2(0W18ALr?b z1mn0bgLwt^;ZQz?qu>$$pxloWl^C{RUk>V%1N(9)A7b7F@Be(hgzyLCa>+;i3Cuh9 zVE&#!|A={%ZItT=?4uesreHheD8@Ac`8uo%`+G26ivr0`oOlY)Kg!#Y3rOwG2c&%U z28BEs8RhNA9fdyD<>T>DK7aAs#a9r@AQ4ybE zTT;wlZAl&Cs+5%5U0>h<$lov?hampfG1Tng;q>`+D}Z8r>CUhK2h;$M=Kf{#!kLuy^ z9afV(K0bAXXOLeFMoAD*#XifR>gW5PLaL9)Gpu@f!bVVD6oH5;*59IPjF(4D73)HA z*rx(WsD2*KsLIWcS6Ml1o~Ga-^t%Kh(8tVwQ7Wy`%!h2>)j~pu~I1ei9)o0EPWLeiuPVqDBF3V zXy>JcqJ38sigrA=P`2Mf*?tRyynL;NqTMbi4DfIk7RvTo80GO_S}5A5Rw&wIeW7Sy z>k38t*-+?=QpTQH=;q~ocA==py9-4#>-0J?%bT3&+9Y?^e?)zf5 zx)0o|uh)y~#nzU~tFPCquh*-u*Q>5K(W}Zm$g7?+9;f5SA^zfd%oV5O$LaWSI)0pv zAE)}ML2-*0&;}!Ksp7j@>Ub@6yp}p%OC7J}EZIJJf|B5FB> z^9(JQq2)5PT!zj!ONVFa@GKpkrNgszc(xAD*5TPYytfYTt;2ik@ZLJSzY34)ulfBo zf3S`>SjQWz!w2i|937sc!*f))XSk+^YkIV%M=LsNti}ZzPuBRb!rsFweddg}_}V(v zt6=JW8%#YvCR5Lig)a(HxXo027gOV|o2lo>!_>Hlw=QM>70uN6>DA-AkE!uDhN647x7^H6Fy&crlpGm*dM2rpA?_OpQmwm>Sn|nCfqGnHu-LK3 znd-NOGc`VrU}{_)$@DnO)c87@sd4mVrpDD%m>O@#Fg4zeWoo<|$J97E9&fEtIVUhR zeikq_FPX^HJm*xr#YW+inCeF-Yh1|G_*leLzgW!Fcr}Ho@n|Yj^Mq+kjT@&iIUM1= z;e~SioWYbnk)O?#{d_f3<9Q8J^Pg2r%_~lPV zCkWv^d4_k18T%7Le?s6F2>cm~d?4`WFvh-uz<0+eU(Wt@%m8+=Kaa(-Um)=3v0(^1 z5BM1S00RFycFX{Fy>RSUEO^NuA3HV-#Xt%G`oJI#Ms&GdA@D?z7ss~wLI;7iYE7T4 zOmMl{Bm(2iwpKW_Ej6t}dMHwar=zP=XIBOoU0QW@xiVe&hUfpm|ELDK{Y|>Khkpep z{Z$~sx;yP7bdI0=0!+loeW__^1vu&iXQ`;;_Hce?4;%^7r!PK~p-;@q$<34Jca0c* z@`w>Rr{v_|oGu)hH}TXF^02KbQ%8(I^uL2?BygG|H9akD29EZ`A)j<+R;j~ogv-uo z1oMxBv@|*|G%bxzt*5iIan83qHoLkeEp63m92$kgp)R~=!^M}Zy!5imuefp}4pqAL zx|P@8u=2*6Zr-%AcJr34+itma5hk;@y?+z5l_=l^=rsNb>fjeH@gY{q+Y{9z3*i<>60`e0p@{ zh|ehAh|jx}O{_&^dC)}tx{JRm29##RmNr8S+$Zk&1(+~mjfJ+?0;{cu!j+3L*QxYrM zwQrjgA)O3=iX#e~O8%4xa0>4*qtnvj(o#~Q)1u>|qtj9l87|Rr#7j#{>5vkap58I7 zQ^#=3v`&zdfW#r5mZr$KxXzSa939asp-UGB%daNm;9lVHC!I4jq@;9B$?6stm6g@y zr0DM5k*|hq!ZJy6(&A7$$`)7D1Gz@0^vulc1scU9h?C+fYIi!fjUvge!pTTsbR3z3 zaF|n8dL#_V8k#;VhuB%Uxw&pnp2(NtgNKU|BsVfMQ{5ktJ}MM%G(=8DDR5F}W~Lgi z(#MTQ)&vtqYB`xs!BC>4ca+Q}D@&&5q=ob|Gc)4F!~rd(+!&(Az+`5r-7H1yiR@Ek@2+Q<3}7^h|vTE%CYf{=*6e6e1$(aY#CTSp`MK1z7_M24rRp zK!l-`ioWE`^pUcnrF=Tl(fJ{s&L?v~;nd!!~Inq&f6b3~ZiVL7?AjrxpDx8*8G_6RckL$?FYI|CKe*fuNS%pP(XNOR{Fl3EF zolVOuzK7p~ORm`biY`rihZ$sg9KO zNcoRLnf*v-CT!c&Afc|0WOZp}y$q#-56LRXnp%`uP*4QODpKuK1|x7JHLHTG5_reJ zH(0e(l{dLm2P*raGK!SX9EEg;Or)4n9@Mye-O>Vq{LK9Pe95Q6wZ%bPrYWz&$&-pS z0FeQO$P(>IHsDOn1G@kz=m`SB<+%9oz*FQy2Y#f8PAR5^tJw+IPjjw+hv z$K@d<{e%@37Zw#2`=wk_aXudH?5wQpEPAfv`gB9TBri+W58Z3B#L`#?69NnwkV#iJ zTV4-2bF!#_`KTYHOKE1!Rg&5rH~REQdS0n2|1eQ@1|^4h>6vJD)U-3_%Nv5{L4t~g zb`+vB>CvNGS4f`BOff~|jZ_a0V#p!^qj=?FQ0C_o2c#hDRaXO51;R%b7H8pp_~{lE6w1=dM2Q@L^3gHE zvabPS0W1L?jafP?L@R`RA<;v!0+c9v$4qKWXaSCxA9aBmp*V$^MR<%+cDi~r0|3e6 zA;S5mvV5ps0t_UwKVJw**~NFqLG4r+0Ggi!D)cBk4e9Bl{F%69*-o6%sGFiRii@kr z$dE$`1``UQG=ZG95J%^=5+5MbSp$g^+I77a^isE=K(Vv(*XLiDPXl?%h50?AqfzJh971&TMbXh6(mUtJMZ4WS z;^GqXH^}tilsRzmC1sc5L2$b-%g=Y`=UDTA0UD~;Fy z@^96(h}naTr<`rN6UoY=ITv7LuUllx!+9hG8T0_l7DOE@<$%fE7HYFylz^J7!B5W| z>Qi#N-ilB6ghIf=d=)o}|GCClaQ84sa`-=9gd{OqyA~ET986S6t zrdZOF9I7WSt}-KoP(>G{?=LPYoL`LVQ>h>}%}&$r&~T>)h*Ninrih*>Yp5I}cF4@A z{b3lyG)#h=eZyI*($mdDg{7x&lnq%^km#qp+i5m%?J6+ryYAM{(W+}#iSzCeIYQjH zapNj+ulv3{+yUg}qy;==!VLX?hOP%EtJkbDRTZcP8WPQ*e8YA~R?GYQUy$g&O!f^E za`SbuR9i+CLq$&31FETJ$+lcpb}3EW6tu-eL&9{7e+m@cGwVU!zI9x*9||9ueghTd zAu2!G2ks1!fEiTp&3N8ANa&Y`2gsO6l$BUJJ7ZxGY8-*Xl@^x zQfJ}122h%FkQg;`>Z@e@^hc63ru@>!OJZaJ<*3C-j)q~nc`^&?-6$>O4ZiC2sDRPk z!2rnCNa3hXqDdAoMN39C-oAPZg{vvv3rOrutzqL;iuo^s2ZpGktWpTv9j-eO@tD zjsv&{Su+2^V(?Xmq{4F4^^7d0i!Y|~!h@3P`CwZSpt>#|jQgi9Ulm@)QXL99*s0S7 z6porztQrB`APS~Z<6?_OjmF;}fc!^5y%KevBjvptr1_XxQY-*vM*ku3!3*7_)c;)w zf{(c+$|zd}+OLX{P5}-~g{Lr6_si4~p|r@ZAge(B6_K|J(VU);rkK+*rxwdUv6$`3 ziF>ABCyc)#h*?yqD-!?8(1rAGxm|T6dKk@`p{Gp`IR)0s2DEM<0hcT<9Yv$dMR8G? z5>p-I=VxRDBrV$;H8!eY4b&dMNus)tEd0%)KShlJ2@J?Qg*pq;R{=2#NPb19LUpUVzV_K1!H&O*hNuH$r%&g!0x**tZen1WwTou<=qMuVLVw(L|@ zTq)SSJ7v<{NkWCF_=+dXkQ^CKD`6zzfDCk)|DhyBOHso=-9xGo^*@Jda4agOr>>l_ z@w(~K-O7~3QA=dx#n_GOgo{Yj&Lv>I1PdJ?aZAJu`QJEBH<<#3_4-tn zTnCT~LEuyO1Up1_X>oB#`xK{N-rDv_{eYvr5jfL8v<}rEv2LIi3@8<9I+%q3kRtd5 zz?6f`MgHxEA5rD#1MJo%SCxT@g{~EqU1;PcDHWmzZX(F5rmZ@#O_wgj*VJ?;v2bKL zcUPpI2}~dgpr=a?#-eNc`1ttN@vWN2w~24&^R;QyCO+N+XcgZ)AufTwP2Z|bb9{lM zbz*!%qN`;ao|ur>CN?%9*3}|5-qXfoS#2zjg*)$YyDgVx+X)GFg4c^_zU7I>Df|#g z^y27v+lp@{L}FrV;ce!P_j==9)S1V}3(n(PCnoZE?2UQ7u6UQ1du`k6O>`wDx&-&) z?*g{NZ0_|&0le|Hh>8-iiHSnQyP{%UqIG;?lq)_qRy1?9cez?M7cnt0uBiBC@zGuj zUq-?on*=LCBzO`MMEmybd9!9MTeND~wjFOD-?Bw~d|X_78(eyPdoE(_<~9l!?MY1Z zBwAKtjK_+JiEWdZ*s6JA^ES;}Szckaibq8?OSD}v%~~~Yo*2{2jRYhta2-nA)wR z6W0H0zxz7bU2K4>?9HEoS`u8C4i3bXRO;vaHz5Y*|M^G z!bb=B_aT<7?|wMKA20ybjrt}pw%>a*S?}=XQoZLh`u5Ohj-&fgr?OI^uERK&wKtKX zjH9Fb3C7d;{k<7S#iO!|C2xwnp-_FDhI=5dfGQrEH~!g|(Q*415(^*?Emx`orimwn>nEf+ z0$QMEu=~YZoALVTAbEWYJMeV*4C31pG4xCzt<3bSZt?PNwcxn_-C3t>&hcdlx>@)L z3R3G7VQwd7L)N62S5*A$a}{YrANgV%N$vYD9W5Z4aKHP7ir-( zd%Wf}_i5ePz@99g$4{R@l|xSypEYpe>^UYiEQk`Y4gv+UEF?NLD=sv*F_sQM&(n}$iVsfHL=G!C6vu_{8 zkz7PO^4aH~)9(l+#iSrPK{yBu9zLSKFo;oxzPLjl|7gRG>|@QLqC(lLFAS!pNpXrq zEn1d}97=E>Nc1O1REkKH46*|s2!;SMR61EgwhxIOaZxfJSS3v!JgoBJmfwt{z;$Po|aNEwq#5K@r|QQn7PgUB6-1W;xa zkpf7<1s>{=!ajd@-%GN*M-Ly~_u-Mxu1)7NcWtrJ+wmTe%E*p{mhuEtDUjszzI#6s@w_!JX4q>?BFyGey74d23n z(gJ-g7A?db&nXDP8Pr~o4Zfg6B=VqjcM0*XmR%fwT0FzIHd!|k)o_waeTxFA%7}`c zn1-qcM`cavQQ8q;bkBCECUw*3&mpO%g>=(=t%z!!fI9|^2h;bDbklrFH;v-{AN)^h zpc@(x*0ZF3;R*G}q!uB*&D9Y)WDOL^gwQHvg9Z&63`;O%2)XnPR;5rT2la8|2aWuD zm_Q;04oo~%edlq?RQh7HKjojn%#!0^X_6_p<<@Pt9hVar+i%x!N25^s_q+qVy8w6JbMJi= zeE$Q`8~bZ`L~&<{EP3ngcS=g$1^u4nz5l_7A4$)?kAo%q>q|-w92|7$a0%UG0BMqaHfYf2 zUkv(E3c+b`o4;y6f%tmlH;q}5^tU16JMw+6)BC|mJe2;AAwli=$r1Uv`e-#649UXhN+ZA_`ZWMM5;(Vo z+>$)bAvV6y3IYvJ$Yeg{4x5(mYL4P)G5RQj1l5N1G4oz}} zNY&uzb0{p_vMg{x<4=g&?bVRv0KSo(gbhbc5)KjYftD%I%4q}$(N05XR!Sa-b_fFs z2SP;`-5P*q3eioiNoyA~dA07ZT#`B|5{QB&esTjKnz%xwq%fAkA}1M|uMomhq)!!J z2-0kd07;WTHd#RL1^~4P0)!2W0Foa#kX*@^F22zj0wMbLJ*^=KNeV(Tnxf&?ow`t4 z3fhH;;~T4CMg*u7gdmnPpn|8p%6GB`TMMHp$VP$u)R^dujMS#|zXU=EmNC@0Du+co zGy+SKsF0^cI8aLIaTG~lP$eV5K@J8}j>FDSOCM-gc@t9q?^@vD3WGDe3z-X&SEWS# z>FZOX^xw0EBTIfcFCY;RQc~@{v~5fB;T#0(uYm@ADX2$(=kw{3hp&9gPk*cQWD4Qw zy$E?pRuMV}AO35GLg|is<=-q>hS(;78U~Jth>c~(|EXuhljTVagK!>ng=O7I8Rak? z>?FrJM*?ItDV&|waS=dCOwd5}OMtQ~PYc{A01ym;BqfKa!I1#2z70a{73b!TX#h@K zVk*CU+actz5vN3eBMp3tygqm)HvqvVPbR6!lXZ6~hBpLF3t+Othffa!MI?}%;)dY# znRLmaifG}XD^^#i#Dyp>R*6vgluz9$pHEQ~13-kFOiFHe;;1HyA_iFfFzHhf_0&<# z0x3`B(}9NSSLB+KYzs0}%OC|NnbZI!IE{?bQ7uJcN=$|e(IWyP2=c-@94RM@fM^l1 zb#CC`!IvPD#lt%)5)eYWoD#I0?wVNF2+%=7fafT80ZX>jK2?sS`!oR2NBsd(E(th3 zz1y78O9OPiBS46rJ!Nv@f(Rgv^Ac2P1Sm=AmTnG%&|YBjMv_7-YzUgB=SnsYdb}ib zmmoxUp?nQpFp({6_lXTaOoTSB1o?IQu;UbUNp%=Rb+u$mPF@6nn>RWHQfBll4FL_r zC9iS=fdK%49|8FZ$P*$Y$8n^L5|uHaE~;Uv2GT^10FsjA_yz#3rYAK3Ax;g0%z;*p z6-ZJDBFL+`QytL3w4SV?0q3$1DE5sZ5b!}`5HFmmB;x%F0m*nsb~mdj)u@QnkLMMS{?$&tJ14c zAZi48q@!65t>hMjK{6IBP<&e97vvBK_{c_rLsF3B3$74R5Z1{^q~nE>024amAy9;h zaCQh3eO3byqB0U7Qdz0wFyE9j&eKDn_~(W}2<@j3$9qWx5dWMo5b3}<*DDa>di)&X z`s+h}9Sn}cQc-ukqC;*tK#3DA;c^Ewf2#w+@oYs1`ISJCmXrUGwI8U}un;Jw zCWXXc5vGuv!XO2mn^c5(4M2$H4S;CHlF|sf zA`Fr>I}Ak6mQ3Jv7x{cQfLN#Dh6Vt>7NnVi(9;EA(M(TYiLD@3BCv(fEE2yc0!Tn> z5fYN}k|w^SC|t>?d5oTh(BBhhLLmJzG~|Z7A}Q^=RBd=h>V~EwMZx@ zEwnlUbkQV7XujlOWY&KlM1LVd-u}ufMbz@4P64V?*F*x?iX==j*IZNE5X7}1kZD}2 z*Rz2nt^U>H&-A69E)s%^Ky>ypX1au+Uq_j~EK1mpCd1iHMRi3M;>2g=0#2 zq(K}N7k_2wUTBb2tt(njgX#a07S%}aP`T+3WRwT{Qou1DPb|^@V~A@O&Y*dVmQZT@ z-$ASYUDE$`%GmUbfY6PQYDJ;FLAjS3AqM3DN4E@TZKSYN9B?Gn0q6*WNIB)#T16m~ zV$tyu4LNcLRI*O$E>U(!%S#LP>;+G6rc{vNm0C!^{d9PLjg{JtLxizDQ6X1x^1=cC zANcZzvk@aB(os4y>ZAsJP=nkp3!S^Y$53c=NM=Jv@?^N#>=eWq z13OkyuZ;+W>Phs7u(T>@s$_q_1FCvW@I2b~X6duxr_M?0Q_) z4eUmClMJWWH?vKwmThKR*jBcU-6HSEt+KXnLuk`xJG)(mY?tmG>`t~rOWvvRUF>dl z5B&Ga^wfR6kKM0Bn@aToggwX}3Q0W79)bT+*vDWWXHT#vb=XtvY4!};$?DiHxRlnj z(%sFT1AbomiTeWV9`+)8iM}~cAQrpSiW$!`t zifVHM`#^?%$UZ_1?PDLaAn5(F^<=Ypc0h(6WQU-7MJ?(RC`i$je#(xr&)Dbe3t5X_ z;&~wR75f_WH`4Ds6{>wly5BZv`QNec*>^DCvmfC8$bORMXZ8#GmHozk$N5ixus_+q z*)chH6x`q@w_t4U;%@GNc1<+*avzW3u{;i@8E+2V%e|~6kB1BW%SI*v+%~YvB*NDg z677K7^CZnr<{MZFY%J1@<*6a*G*C{=h8PN+GNfaJ@JLD*8{rm|3aD?w=Blt)@ijU^%Iiz$?=HWJe3Lhi$3Wx4tVn{$;PvKLc zVLOeV#;5CgnZf;hCNJRuK8w#rtT}uxq)+GbbevLNCVgk{`Ftm8r<_wOUjW`hUIF(S z-9IkkXYxwEm@kpiOZhUsoUeetO48YEB|nRw&ClWI^7D8#YMbst4PPZO`J?4^u0|eo zU272Qd>QjKww5!X8p5K5M0o2%eBfp8?jPOmcdsr>s%(w8Zd>g18 z>=ynCN=NO<$wlE&>{j^<-6o&SIKG|V&hOxN%Dm}*?~p!<=NPJU6?YE1i{CBFa}V5m zrSCqt_e(FfW9O&m^UkJ&o^!DJYUzAt=5`P)tukcs-YrwC= zz9D7z!uKYB3oeHa~1Lgda(|qCI97p!a9YJ;dhA^Q( zLZwu+EnGrf6VYz$MMOdKgRV`5dxa0-G2jp#E8?^?(RZ5{fwciAnB% zI{r{GOyr1Mkq6o-Nki<^c`VNl)dfj7`Qh{`F%o7J-mi6Ho-9rYm0!s@Pcl(2$ef(# z!im!mkCE}mig8GDJXZ3Y+#F0ZrLY-=zGpWp5EDZsz&rrvRFT3a31@^-IA7OiL+)@n zx=q%yg`!9l!#_pSG^cRnr$*#KWsc?31X(A1FH1)M@hbPQ(?m3zE@lY7_zvxMrYI2s zF$>FqDrAnBi}2IMJW+}jIS)GnR5(sFQ*j!G%!gdLSRfXP3P>*kb*88ki^UR9OF=CI zUXFu5$f$W-mBcH>S>kMQj_4L~k8wy_YzSVYT@BDevp0erQ)(sy2QC$ zToIzLM4Q+st`b*^Ys9tUIxN<|#%_RBY1}C9$4wD;WiQL;Zj~wAF76Oi2BPki9BPXj!EsXJnNwFV5lDm$0gsKh*%U) zrKd3Y6|LgXf6=gULN~A-xRQY)Y*hO@k-LF4oGslY8q#+Q`oA9uv=%@!8V85NOn6Nh zYDrgMy?|u@6Jv*xqcsKsHC{LEIx7${a{Ynau%VR*qMHAWY4JDVk@0C&gG?*AzM=f_ z^r{e6H^L@S`)Q3MF|^8&jI|CjYK24j(>2ct3*+{o5LyT6*uZoSg^_$lgz19(x;8NM z5~E|f!AI*NWU`TB51kIJk%V)0e7!ZV4^~bZo4(-m(_Cj2gOPzHSwQ@2Gt0=T` zLhB|oVG{Mq39Xxy%9RsZM_CAd1*meiNUxxr3A`9~304tlC56^e&crIpnQ|TFY`81s zTFSXtRiTxXYOJKJ#Jg09c#o0RQdWnIT3K0*l@-NXr`J~21Jmltg>rReJ=Ry&v&#{m z)>p!2qxN5g5M{1LZ+@*@cOmzBx$<%?)?S?Oo3Z-R&}`ClEmmcm5XZL}9JNm4#NUP$ zn}1?%!MYBaTiI>eM-;8%{I$7*H8!-;b7urM>~}(TM1)f8u!NJ=U0UL9jqkxK(edU! zM(ag?Z607`Xw|5(c^I5WuzK_;R*z`yh*pmh*;6o21FO}eM64e*Wu66hx3te;HR*ZG zrN}+r?1|vLcw9+eLOw4`^9tNorF{+V>(ab|@hK6jPmXy@``!kACse9;u^Oe;qu$4w zlw&^7z7K&v(iX4aN%JvM4VxfVtQwmA5j3q}H8clV*wCuhCk@OIP_(ucHqEil<+QC^ zu;O(9d4GX&d?{DEz6p&E-(sc}9w}%w>qpQ(Mer!}=i|l$>f?Wbae98`|5ejrK863L zEvw4O#IAl`G6vf*p-gyK4~{|y$% ziws`tlRhVnXsqA;m2u>n!d_i6-(Qq41}lS28Rz<%VVpgYp%q2v-c!HQ46BP_L+gyq zIX&?^a9ukZ8E4#Ws@!<@PuE5wy(rv zr_{Js!Xe6+g%#GnHr*P8pM<*Wj&)eaWMd`vpP3%A)}8y_8298&neg-13r}g&rgx(d zTIKC0^XiX~0a)WzW*};15FgyYB(fn`?~OFH_B#ZtzkT%lCl~9$%H;8UZHDs^`o7WH zZ(}nWoRhg4lWF}oY{sHgWB535#_RBHYywt)BTa!U`9yvy%p~|Hb294r312_0>=yIm zN6dS%I_#J!@J$W1$Z1G}+Eiz({)SsAasS#hZa-l^oXw0N`;bEnrr=|=(fxU<`8pLa=MDuyM zj^+Gca_|B?h2cJ9Vdy!pz`A(_U&Jx$pd4z|yb^2YOJFPcQrKnEI(LP*CpNUo9)6;$ z;CIH!Fs3n(*592J!_O3s^}w1u8CsVQn`+3`$aFKXMz73jzJ{MK&Dw|+cv@X2Lo4jc zYyiGEBCkuZ(%#ryinVvgT*k><4toW^Qk#ttzN@%n64}*Qg?EfvjlUi%^0Wqj9luf9 zn<8>n*LyS8_up#}*C}&TSUrtB+56ZHQ04>v;c>A)!V14* z64}SxF+nN0pOdK%#X7*r9F+7Seh6#*iR=^J*c`#Szv3Oi`u}H*%;)?I{-rcu!Tp+l z6JfrU{zUd2b_2+KkMw`Qu0T`fN4_5G@`>zcxmQ50GQY~wg=>U%4`}D$U;I!0?*`@= zD0E{`LZjUS+CQLO1H3w=cMH72D-xLxI|av^7!ivwGI(9Fks)3)9h%6R(<_16w21II zCB$2e4NN>@w#1&o^Vm}$860mGVcNjoCX}{JLnOkqg>5H&?Hh)&B(19rxb}S zMI3Kvr=o-0i|8cC&`v}Lq|gcb5#gB1*HvVSt|3GF6N=wWG&YIYvpC*#hdlk0&BptA zVbeqO!QMsVydvpdqBr(7l<5Q97t)HN-3w&~NKAVakujAYXNHQQ+6=}n#8Ai#)q4^7 zf{fZ($j8pY@v%?L8I662(Smj$P7!0IOTMw%H?GOF#)C_%HjbGfXfNTPm{Xffk4ksq z*ptL$#A+N~*hET2*oSD!6hn3jj>`W}&D4lIriuT|oE8z6uCJ+C@rik~4?@NdOFJQr zO#mF)8zD0XCXvm>{z#-bUGnB(zl6A@(xr0zQ&WarmgCJCjjk%38eVm1WXc=S3nU$m zp?nLGBF!=@ut)RXn?&sH{O9J(h^wi<&QRmB{ZpEDl$MId|2F?SdKpTwT$f}8a24!I z@&DG)e%6W1IS4ry_B_~XkSVBIlpsxvS%AoQ}h93ezfq10pmN zR~*`9!wGfbe6d#Vaa_=7uS2b~gy+f1_sie3bV{Ad7>Okj;n2)pff+G74-3e(r!WcM zG3@cJNBJ%k7d0xSk8cpiNV`kI#o`h{yLFn3K#|8MMX;OjI;%n|=yLIQ<_ff=E5%00 zIrlUYtN)}k_*LTgxiQIIEogN~?Hx96uorW^PVa^$({=K=Q8?x%_-=;Xbew#xAhTKW zw}?oy^*C8dcN_KtmAR$KaFW@-^4;Pdaj&>f+%FywcZ&yM?}d2?p%248A|4eAN5<}jw8D_l zWLu_i^*pF2kjmqfDf0P@T+^dG9@B03anwW@C=V0*VVEQ8D+z~1`kp}Sm5?QSVi5ev zCY}_MAB1=r(3GUS8($akDBJ<3d@W_UBI}3zO@XQpdLpTOk$r%Vx8!u?>N=e;T5kx0 z>X%g7gHE`{;*=x29z(wACy@WEwVLpXO~bVQntBTN?Zgt!3acX%rk!#-`1mxQ7RU1x z$B7e(pV3cJxc(aY!sE|>?rWG*)6|{D4&yH4ZsUIAL4&bf#*4;F#>>VV#%IRo#uvu7 z;CakAvzgi4Y+<&R8wmZ)0p>t+s97YbIp$pRbaS3L-&_FtEOV8)+FWCc_Ys~}3_2xn21}XccajW^2 zahv(IvEBUHxX1hkS3vNqai95z@i1imZ9Hmn^9l2q@tBN3p>A`R=`&w2qs`|uuci5# z8E?LBwlUw5oHTQvnPDC@)6JmS)jVuwnxB~2=I3TN^HZ~r`K{U0{7T9VGJiG)o4=St z%wNqM^IvAJ`G+~$G^`0`lvQlDuue1mW?QSoY;Oh3B-B8A^Sw|hs3Z+x1ijSoU&2Gi zLi2m$PBYPb+srfnG>2GItie{XHPo7F4YG=mZiba_U1(ioWm+R;F7?KB=I_RXX0rK# zxz1W|U0_{i-LFgck+D(wTxOlw#TssPwMJM2twQTzqr!Z|SY*CsY%t$8E;fHKc9=gJ zcbRR?cg%L?yJkmozuC#GH}lPZo5RgxW_R;5v$y$;OzRWl<_6b(pK*ryu5qb3z?y9J zvre^InQxevSeIH;&G-}60=?-$M@e3OLJ3uUt|n@+LAS-ytSc>xU2olNZADslz}{m$ zWPScO={AupyVbhideYi$?Xh07zWOiX@3r<@?^^q;!=bp}THl5I4Rie2`V}ER>Co@P zQuZH~5mr};i1hEUOawRVZP_4}7pJT<7Oi>7p|DmsvAs=*Qn6F))J7cQ|7OKD!FBTc z!SdKYT2WHs7t1Gcn%%+v-HNmSWi^xZpH>U|m=$kxyS1d#?T)tFPO^oaV4HTLZP{&Y z+ioYrTy}ejo%9Khv`5(|+oSDMjtjw2$>5D?f*%>5v9W(E5tg6aNVZtgQyOu@@(q3C z?Fn{)J<&eZo@5u=MJI?g-JWrR5GS>%_B2SGrln>{Jo|6rsJMQ6rd=W>15L=!lf2XI z(k8;3ya~^-=QfZiYd}Rx9`8THF1P2OKz>0Z{=x?IBKu6x6?SCVl+UpR*Ht!yHs8oU~NJ=_bA3te>_r*Vq-pV)-V z`61rgkne(!Z(YdOIJMO$47uopAu5dx2)`Ki64*;&FM}nxTw_K36ZZ``)R@m3=b0}U)#fZ~jy2nwYrSt= zZhl}~VQ#Q4wmvkjG(R@3HV+v$nn#RH=3(O|^HZbNJZfw+LS)Av4Q7VxD9kHP5i-TjkaQ>jwKqyNCIO z*~|Re>}P&&_BFpVM`7{%6w|U!Hce}xRbef%&a}puwl&stS>sH%HQw}C6HTvGU`AV~ znlaWSGuE1H##z(MR@O|joi)o$wq~0t))w-8|P?ZJlGSvZ}4~t@ErkR*kjRDm0r}Gt5M5x|v{2FQVt;0T zYJYCuW^K2=u)nsyw7;>xvcI+8v);G9vwyI^w||uB-D&NxezJeDf3|;>biH-J`py2s z{@wo5{+Io4@E$<A{%f8#b$G+FT&%WP&*nZr8!hX_z%6{5@ z#@=baV!vVUwcoVgvfsAfvEQ{nw1f73yWT!vAG8nIhi%K{aYebJU0#>Zg-@ioTDV%f z5?pOuiLSP;cKE8x)7Dc~l53as7)o7drMj-NHdf#DoA6s8qZP*9a zht@&sYwJGiUh8hF8N16$wW6WNOOWC^YJG$BKeal!ZnxstgI06)sHLWk^p5U71v>4U zKMm!bLM{@g0w;$a8 z4Ww>I6%A~_af&&>wcWVG7~~o(Lx;GAN<7S!(?B}cl_%*Du8|Uta*b{f?xfZjk8zE4 zjdP86<-3NvPIjHrAkG9=for1c)CRn8{1oUI|2<4PL2M^xA;ODbi(#k0PKBKYdm8L? z*cq^X*qN{;u#5%Z&VrpSDJPvduDPI3cg=%a>MDbKhHF0Da@PX5VVK;2Qv8KY@SGTn z5OyYPCG29@C9q3jm%%QFT>)DKyAt*+Sm-jqJqPw&Njd49=c)!><5~rGwQCLB^IdD< zUf@~>Hw+b$TJO5hb&+d>4!Ickc~QgP7B7nz_&jKl4lo87-?MMTtI%dF!1tY|;;o2n zSVuc3Zs7N0{~5cs;&YK~ltUx67CXsTi>^isyxDdIR@|oWGq5(;5qcDlVrTfUSOVSQ z?Q9YB4G!>F?AUC?+ZAsLpV7hSVkBY*axC5y`B`KdPl?Z1CLe;`nooH<@sfx(jPlf}P8 zs*z=MH@2{9Xgz!=lKClkYjq*C1omO~`6RqQG)ufIHi)43MO=?}$)9H*@H>%5I`pvu z(2W=@zUF7*jcS7@-~%H+VCVWY>_>eoqKp`$rLh$6dwnTvBZn`*`|c**U0#Z-*w3S} z;(b8$GtTCJip}gIXp=k)9fqH|iJjt6qP4LOI#S$N3GKtD`Fo-V&x0<>w>VV#2I%?v zcono&u7;k)Puzufjdoxa^ef>u?!h~X&#-#zkY6cGqodKyxEOCe&d2U*f9#Qd0X>9g zMFl%s+=%z(Q}{HVCm8fI&f_15?cx|#N;~svXz3Chf;~(A5x$yz#eLXird{ML5o_d# z=~(Hz3icVf3b|i=Dlv2pjYOlZkzsryEMpn;(N{q$`*!F$zYe|M_n?3K3G-sje2CN| zn}9cKmqSBmBYzB<9WOzH;V|AEY>T(-I$-yj-lOY;UFl4`2iIE+z#W)~_kN17_g5~? zgt-Xoy^n}Gu}i!nUKJmU{la53H(D8k_*|nxmgaP5v9E>hd<`_)Z-J)v>v&iGHM|Lb z2ztKXLQD5|=+Ab7E>w5COFayFZ@JKI8wriILcA$l3Js}BXcm!X(0b^=Y{#A11AUU0 zpcC>jZ!JE-TajNuGl9;_p*IwLIQ=mWZxpr^?eT8j0PIDdf)W>^wCCV`r!82Seh8&~ zTs$M5K$&-nr%~?bQ116dz4$_W4@Cx#5o^TZ3R>VA((o)67!!=CMn8Fy!(!uXW24d6 z=&x6-`Xh$?q+wlvmxEX?q&D3``G>9 z?+-h`9td}kJs9p#dzhVL=i0;VlkBc`Uwa66O~Ga8S1#9mOjF^EUGbNpPMj-U8&4p2 zmFwyggs8aJx~@U^btjOy-gUzXLKwU8gdt9;!uTfF&8|(ZTGwXR7T4DQARc4eT(`Jx zb!~Uu=DPiF;+=u_Lgur9Mx}h~qYCeLoQ)^y9G1q08mr{n9qZX3qXXXYxQGog=wysV z@@$M74SFx5Bi_VNr(bkJ>!+uX-eI7VEAEx=9z1||2p*Ou*La)Ln*@0Vy+`mA-VWFa z9sOr<-oy)d+w(PugOy--eMo(N&X0W`|qRw_*|YEu^*>L9ANc0A0prQBBUMv zBO7jvFw|KNKSOK1Gv4<36T5xK*hqszL(srU4x#%TG3%^HU6b ze+8P+_^KiA%G%YlvB}1{#!1lEJqdaR zq$k@S+OXMpUuXy)Zw!TYD`~b4$7u#9OD)y0&{Lhj3#2A0>6@MgJ2{Vm`@O0j_M+w<{8 z|Al-VpJMc7m*TzrE6}%1Gp>RT;5ED-qj&7D$D8!08Jl>2wwX^iw(tRLE5B9h)y*(Q z8-C*sKGV1h+H-e8ckUtdi=-DvT5u)CgV1{0#Ro#G?KvJWo`DA2EMvCuDt{9_(i?mb zw9np!&e{8Xu<;R}V+8r>#v$l(9pUo~(&Q>N%8YNImo=Du&xhb`Cwe!VbgPc>p*Sn& z48suf4O@&g+@joAU@SC-u^i|^Eix*MGmT24IUO5}-Yt){67*iw5+eZ`OYOx7w$$h- zmKn>9EWFD+lJyYuw(<(23Z|bJ#a0>vp}8}fon_>Tli3Jp ziP(m>R+ow8qDrhYRzN4g>x*|VthCk`{cAszTUXVxX_r0_eL+l{_>^9dns^@Qx(yzut_#n)X|_ibA}hd8;U5^#0^!#$DJ|EN1tKbauIMg+Zs| zJc>U2Iq`zH(%2(j6t9Wb#Z|^IW3PBayd`pschIw6ZCqm<5=X>Qajo&0_)h#NeiA>3 zU&U|YI^%aSjr}36H%?WG1keAn`Md5ul zKlNt{qgr-i9Xp0YI;WK`ESrYIYNyQ#ROT*RP?nQ4tusa7ke7f~xXyfvU<0Uq{%$rcT zaOtTi%cR+rRg(gUhZ7yAE~#8RymU#$sPe#)ljoE!&8tA(^UCK{8iDg*fo0w`N~V9e}AbH|p=t{Pi5r)uo{+2s@F zEj;7Y%B6uxa~3Y0R8|%!TC#Xq?$QN;yhT;>MwFq>%E}RcNo7G`S>P00+nA+`%f^8%x|p*tFmA#8K>qB?x#KEe=Tw##%&9D$ z6sWA2R5?E|dGX>v-mKDjx#f$N4iC&KAF(h{IqHmx(lK*TM*&>(8Kr@7xEJH*ESx*8 zY)-|vii*l{O9HdTBhT>*D(4o=Tex8Kg7QGY?4^N%MJV5#Ic1YdE6XMaDg(s}DoS&g zFD)Nkxg;=pN%_)o^A;{0y?o)kNejy74d=Ig_A3mR7@^iQdU&DWWltu<$*B^<^{$tOuNKY zl6JSNBJDNTPL|@X%SmzXs!nk~yEDbjc&b~}q`EupN_FpMY3?olH1~7WY3^5f2RGZ* z!7cLA-L=6CH}iLKo4l)A1asYHaJ1X@k9FI*C2n_3i94z;;P&#_?iY5Jxub$L?ijw> z?G3JT#|78BoBJj2x z-2wLze#o6x_nAArhI!J0+|wyZc#<&5P7k_089|Sy>&?-gS6GVY)tnU1Yt<>9jJgz0 zSDxz0s!8=^*QI)1XK9{2{xr|)yo1NRtAi&hFWvJ}FvD{a@9N1)%JTHC$?;_SOFT#U zY){W%si$vUnWwkE+%q7z+B1Z&_Vf*|^9-t6?-}gB$TQHt!86of>&Xdj_T&Y(dw%6R zJ^8siJ$rZV^b8Nyc}DSPJtKpAJR|B}^qk^<*)!VziswyM?|Cby-t%^Kz2}{s^`5c( zfMd&wk7I_e@oQDnk`X_>b69^#kWSa+_g2TRo=F!d+KhDIvm^{Rhe{q zR3*P7YMKAes3l1|qRtNPj5;^CC#pKBK5CV}K59u#ebn0Efv7b}2cy;nk49Y>PNs0b7m=fJnq()y7OpRW_)1rU&r$zr5%!sba&56G3=A7uW>T;vc z;rY>51V=}2^pB0MXDQwTIVs+Q)hXUXJ5#)zr+ST=RBz{9soujZ&AZi~=KZ8P&HEbf z;N`nIc#XVt@8)2Jm;1YTE#B2@1arMsaJ1LuAM17HmUuliCEn<|fY--odq3S-=8X>4 zcw_l$uP?aH+bp==+rod5H`c$wdz96BKg+50eqLSceJWV%ZNWEt<7+m1Ti0#&e!;eQ zpYU(-w&h#B)~>BySKc=7W5Mm-F1v2`w&8bp+xYMFwoTgMO%B$1f6A@*wy&x8rY0Tm zCf6MBrq&(se##GdJJfyV?O4Nn9fI7~IZ61Eh2iTMbo;slJ-*DFqkUKVy}mD5itnqO z6yMj?DZVasDZWge>g!gM>idSJ`Cjy=`QG3ie4bq$e9?L7zL$d;zV5uMuUk@m z?^~Yl>)|i)ea2_|dId{;{p!kmef;IVfw|Sbp?tNkUvQmoaNT;}5dTHKLH-TCVg6cQ zZg8_NKe*lZ8{g?0p1afc-Oio95y3j&X#T8kRB(@PWZjFtG5(i*C;MOVeb4HBKjhT= zeypzd{j{^*H;y0hO{h8G>%QxN?`L+<_qzX}Z(`j+-<$l9&$sK4FE;P6Z*$!d->bo+ zzAyOazCu5XDGu_O!rYvgslnWssXRZX*{=MU7J0*CP798XDXu#?W~P5^%xSqLF*9mP zVgkWHOn}dhnH?;RX|t*q-yE}`W^>FRY)j0i{w*;THCtlNtlJXvHs2Z(ziVqu z>%46-_txDS^GR@f%;KcmV;1u}VwU^wj9HqrBj%jo&Y1Ipdtz#m>SI>>>tmMI)W=*9 zJP>n!(!rQ(Z$22aK6o_dq9BjGI7!6*kdzYpXHH7&@|u*`--0Qzy+ms4rNPwLV=OK9 z7k^spbvLKQ{uIoJU74E`d-=^dv1ixi#-7XbW3LR3j=jo1HukGz7Jq&|i?7=h7k_I~ zPQo^SPQo3*oP_QEyo4aHN%%dtHsO!loe2kdU4q+RpRhA2r_Iy;oHo0IIc;|N^V*!` zuW$2aQgz}R{_4bcgVl*|`&T87_17k5iOq@QleQ#w6?KXK&Sh;s;?-^6%dKwv4zFqZ z0bkwrwxpbPxA=3~-5Jbjce_8Y-F{xv?q9jJ?f%T&+3papYv=LTx2sFaY5$Brr~Pxm zoc7Q9^V)a!*SCKwsXA$|zdGr?V0F?v{#8li{IyBl#O9<4Nn4UKMP1UdT$a3#S0}%p zTb=wauSx!puTH)%cPvNR{or{ z_@t7w*8Y;Tf~4v$r~0eAOiZfnGRa@tWlk_Rb8aw@d3um%%?qYxt?;vMRsNK2E0glN zos~4J+YP}3-S;K2-XHo|@A@F?9rTOd2ZQe3A19^s{>Y!w`#>;XL!4t`H1#6r;f-Lbt8I+10%lS`KRJ9Sm5#Gl*+aFDV2{Ur&d0?DYeqQKfThE z+_Cb>nLR4^B-d81%df3W*uSl^P4X?3FD2JkuFtQp%-DapvP<$Om9NbFuJXg=l*Je3 zr!4*;Id$>-n^G6wVWchYzdwEPfaH#ge@(7mydl4S@#y`B7oVK`$>J}QJ1+S=xpv7V z`L#m}s)NZTRrltXRDHT>QPqz#_g1}?pR@99BX6b4+*SR?8ougH6Ms;Lm#kuD?W%Xz zY+l99EvxF*)UDcQ?phTz53cf=Z1q8tuWqx3uRd&w)!yMbtB;twR)1{<*2Js{tohcQ zwdVWXv)24*9$fRQIqUo{%`NBeUBlPDWs0?vhL@}@Fl*Pow`TL&iRPBIyVlgL{n*^K zcE5RW?F^G$aLD8r3|PZ2_{0-=j1>%KE*t@~m3taU$`2iN^( z&RYMKxn+H^x$DAZyH{VbeD~H%J~YJ*ADL-4d~S-HzA)2p3UK|yET=X7NqI!!>M$No z{Q5_j#Ndx68hEV61%y)`VUsoO;3=9ek@#UYN7D{2)pR*wq%SejU8MOdG_KZojm8@^ zzKk&9NsM^cYW|HH*J`|taLS`h;v9`3zn%EF?mewpnqBe|yD@=vu&X8RXxB=dPIO8e z)`@UN8@7wE*_ORUcywE~lkjBvAXRl|J~>_CDH>1Lc#+0yG+vj^x_BU8tLYsYKbg*Y z5PxSn>rMC-$?wP4bfR?o@pT$M*@?aE+1Zb`>&#y9)DI+#@KJn9hQiY|UZn93jrV9= zFY!FSCX3|f@pV~jO!Urqyj?doI(p|BgfTOccw=<^N;(Xrz-fRK*{y@gj}aXnd{4I|w7*9*tia$~wjEw8X|7X1A?9-Dp|P+=Sbe zvnayp<;+VstDMCU?p@BB6CPg91`$45&V~^Fww&b<{ z*Z{)&RokU%EnBEpaaCX-1rkjx}AlRyYbQ`22D z)0w{Ls!nF&g!@PW$RTnlg4eFN;(e|s0e8J`UC&iecJ=SIcCWi0tMdQ8SM{o1o$qz^ ztL_QA3FLKM?|tw4e&6x#<7bp>F+E{Mxen78%qZ7mdg6?71Ewd>D9^(D)EVV?%n#DP z!TcaSh|eK?Ha>sljPe|O4(W68Ii!d1Ii!a%T`;5Ei0PskQ=}CBnmrJ zSK>9K^N}7%Z^ir}Jq4d%JEP3Q=a8O?&mp}HpF?^(rUz$~*J66pjB*F2x6UZ9!}N|B zA_?^xhfeG|cZ!Gs+^&57Nb$AEbBVb4X9e=Wm-)y6`!qXW(;4@4@Ggz8=#D zW|TKz`rwRmFQ)IEQQnB@2WOP~F#YI^azCb@m{FEtehG^oA9#A&nHKZ5d^(zl3oADabA-q2CfHH#DkZ#9(Asxp1>kcT}@IIs$;(bVW;{DtK zWf$IuG=ujc9mV@s9#C?4AJQ?r59ynb50GZ@`LzcW9iKxwj?W=|Gd_p(EtnoWpu82+ zn+_;%!}Qhz%HLsn#{uQo9Z-t+ z9MUpAhx8rz9MXTl^nnA)J28Fmfbt-w?>(Tr3)2rCP~MH{M-M3P!SoXcl=ox$&;jLP zOuu$OX<+)>1IkA*{qE(;m$AG*U#@%w%Y*c*SRSOG#pfqpq5Ph_cZKq=_}(9`P=18( zLHc8S57O7qfo;joyIy$%rW>zU-i_&&>ybBB}~re8XwOkw)nL&`L!KRl#diRsS|DOX|ot3%48nEv*V@))MS zJEUBT=`#*1*I|16VdWsECmvP~VS4gma(z z#Svu-rmK!9Lzu2RqKsg=>4>r&(~%>}MVMZ4M7bE#+!5sxObbVp-I$t3luI$4IiieW zdhHQK$Mn`C$~dNXA5rp{zUhck!SoYHl*^W!M^Xc?KX*hi@fy;-c>S#-%09e?bQ-T8 zJ)-Q#Ye;AC`d3Gk19%PTeRyp?to#nsyB}5_#Pq?3m3L$M!H1RiV)}`PmG@)%nTM4R zV)~_rl@DY3t%sG5V*0~}m5*Wi_`}L4F#XlT%BL{>9qf3I>7O4~9>(-o7=y(0gh!Om zVtV2u%I7gvA5p%B>8eMRuOnTMeiN@ZKB9aJuOa;xydHT(`3_z~`aQh9^bzIzcn#?f z@w)Jc@~?Oe>F@FS6OSl=!1SR=rgyA8cJcEbd*$5EtULA$Oh32o*bAP2WPI+)n~&Y}{KxiS z`iU1j<<7Z}4;}mQ7xdhP>8D=sW|DsFg^zt`?xWj}{WzwNZ$I{|mposGTZ{t!vdz&$Cl_|8bnZ1?kT*h3|faDSSs#xc;qu4e2?s z$Kjg zdFt9z*S-n1CR)+Eqxajr-|Kz$y2*8?_wDM_`X>9n)Az@|GuMA={b$#|uK(ZrOXu%B z|NZALzu+qud}Y(GH~nGL_RY^3m_M*=;H-hO2UZXC3|u{M{lL2i9vb-4z~cj#4qiEU z{osv*?;ia4;HP1k{^?uxZ@Fj7SGRnB%g?r)x3zEU=B*=Jb6dx^PHfF@EpFYn^~$X` zZ@qo%>$cvt^=(@p-1?!dAKCi(tzX*u!>vEs`d?d*8G8EAi-#5tbq}30w0@{Mv~TFp z&>M!{I`n~|&klWl=o>>n8hU)_zlQ!a^t9pQhF?5C`R|bvwhhC{fZ1)=Zo6UIJ=@;6 z?VZ~`u|oPP+Kii$^aW zyZA#FKV#>DoojYpxAT#m-`)AMoxj=npF5w}dE6y)FFE&;OD`F{BzK8^N$HZCFL~&a zm+b1@wPn}juF|fVUGLxZv0abt`pK@p>{_sU_3r#`bNAoxe(&xN?EdiX&+q=i?r-e= z=I-z9{?+ck?mjj%H#3|W&EzwanHw{&&%7h^uFRJ+-^u(}=8u`bz4YWuYnNVi=^dAT z_R{ZO`q-t<(AH@iwN2W9cBwX@?blwT-KxD!dyn>h=(uZW{|y75Cybsnx_ETO=&sTC zjedUgtE1l>{nqH8NB=syI=dx1k$rXcn(Ujh@5p{8`%l@&vnS`~=7w_l+`io9x!333 znEOm_P~WZ>^eO!w{h#!o=s(q;Kh{5HjvXAkZS3B$503rw*zd;vFs6*Zc>JXCIpYK4 z!{gh>caOh%{JQbG#{YBtPvbA1c*Vrf#8ng5O}u8}fr%I7*XG}v|3&_(d!E1Nfj!^c z^MgIdPR^MenXFFko1C7!fAZavADjI6IeZ{Hbb;U0hzhC@C@sGuqmd=0^M(-_stn}H^7fW9+{h;*R^4#(%}!{uP(7)-pn7`s%<7iv zX!XkK>#FamK2-g4^)#bq>^E*OZZ!VRc)#%@<2dt~=3H}wd5M`fFEg(*51DtHUoelW zy|Q*rZB1=QO|MmIKdGIt_hoxuv3Kp>{N69@{lVU!?fo4be(>^ruh@6qzVr9pxbN-z z2Bs#bZkoDn>I+j}n);uq)23HVubJLB-9No$di(UQ>D|-%^cB-LPrqjRmg#p-e_{HU z(VJOq=U=^M=F*v0&)h!qshMxg{L9QwXMQ&G zb2uL6gadOAoN-|1f$V`d9r)CN&mQ>Qfu~;n%*$VOdC%p2m#?{^dd2h=`>(j}iq~E7 z`YS$p#hY$-gxD^u6+NM$6U4Ms_$O)^Q(S+)l;rM_UaR_ zE?+%;^^I5GcJ&*te&5v}xcZY<|J&97e)Y?)Ipvy_*9=`Vd`%M&5pRPOZ`oF!t>-uxA-*WvW z*NENXYvj-nO_|=2oIryW4 zj~)EO!9N{5;ZV<^+@b3a-FWEELvK3#4~IW}_=|_Xarj>j|N8JB4*wN4n>zc(i*CH~ z#=|#mylLA_@4V^AO%LDnxtqRu(=%>9>E?Ymf8ypZ-uxdo|MuoDyyjc4nSaY^x14p$ zIk$}7a^EfQz2(EVoO0_~w^nbRx%HM?@3{3VxBlqX`mKMt^?A3QblaZW?z!!Qw|(ih zuip0c+g99u*6n+5pSk@zw}1EcV_$pzYybG#7v6E>>)!RckGyX2ofq7>`Oey%Q+LkX zdHtPlz4Ie?e)P^q?)=G}KfUw6@BICpr`)ydu8ntXzv~BgJ$ly@cRl;=6YpMl_c?d( zzWXP4|Hs{bzI(wv3-5XRJrCbgzvr*_?0Nm)zM=ev^X|Ry-oM;C{>Bf!@lS7j`F&U1 zch`OQ-}mwRzH;9m@B8b0PrLuQ_rK`=bMEiG|K|H&bN{{f&wa|tPn!p;1iFtq_8C8V z#-e9spZ)j?9(d6&Ui7(_oOsf+U-tOR{{3aw%(;Kg(o?=Qf8B!f7aV_j{q$!o`RKCD z^4BiEcljgBzrDP;;;k#+e%8(1f9n3ks+X_+`kLM6zUJKQ+TW~wXYVuCpSj@$8&__+ zebbuOJmD_Zh6Vp7RJFmRtYnNP~`M$Pbbi?TP zM%QG&pF2f=K!5xAhsIY;t}J}JFj-tweqZ?;l`k0Md*3}ZHvPcNH!nZqif>%^>+2TZ z@TVL1-Q0KEk8gYF?a#X7&O1K*x+QP;%A20{=D&H%ZEv~#tuX1zIhO53&pqLJFNS04 zUiddB9{-Z(JnPvnJ^5uXe}y{dq`9Zy$!iN1o_6}8uEl38S-NcbiZfTf>a4TrIcIBo z*Y&OU97J~Pw(S>QwBzEZU9xL8J&5d>iTs|)0t_ElE~^@54bKcCM}}Q-x~wXc8Uo8S8OzkKJr-~0X#e)z9H`thTW{p6>Q z|J%R+?C1aQ7r*?~uYdC&zpXd^^LPLC-@pIEAOG|}fBwr~pEv=|lw9_L7vj;93I6Q8 zTd^ixU^GqsKtKYK(9@1nV2kZ%S|{DXeLTSn{=fv5=RFTt{JiHufiHUAi=TJmOI~`? z$xtpiiXF>;8Oa3md@2NRR!+*(p8;!pm1jN+Rx&Ee@py9H2`4-c{zqZG2s;i>gjuZ$ ztY?7Ezmu^T`17)7Dj>ZR=799@a^4B^PlW_~+mwZha@q;FcXij|6HWku;&bfIQl_g|m;ba)1IoJXrZ_30;mk5goxI2UG_ocqLu>QkR` zqH^n&kHQ&A_~%i`2qx^puGo(fO6S16r>Kf@i|c39-&=oQ{r&Y1)IV7NQ2oR8kJLX}|HpcF{Tz6AHT-`r`37d^ z*DtB>vVUVeV_-i?{z~>b3e*eSdwXetG?| z`rGP%SAVenK>f4z&(*(J|4jX#>R+gTzW&e7+w?0ZRhHD3)|b_n*H_fftgo!Us(x1e zY@lg3@XMl*{(F4=IrYD(KexWBzQ*^Yuf87WUk5e7I&6emyr=$d_}f!o3$;1F-VcA@ zQU3?1)u#Fd@OJ?IZic^G>s#uB@OPv>TpxnJ7uL7ex53|wNUgEnSaYoVXkCN9Iry7} zzhm%Mhrbi>cO3ra?Z10~H~6n+U^>V!e{HfKAx(QsGs_(7u177W~Ps86C z`1@-3dpZ0)0Dm8YzgNKDx7FWTe{=mUz)9rgJAs>Tum3&#eW-q<{;B$>>kro-seiKm z2_F~K#+=6726Ag2`FBBMVdJ#M>5biuuEyfV8RTAf;~Yp=!~f@!Yrq+#yX@ci?J4%} zSK8@(J3Y0rh;FvS}Z>I77#)lgpYkaElaO0mFUub->@vX+!8b53Nyz$G% zWH3vw?=)P*0>Ej78%)jlXF;x3Q|R zhTM57{QENd87%2gUJm~sYhT}Qr;75ojpsLB(0CeLpX}UIl;hy{E12v5fZxAr{JQa5 z``!yldOP{|MdaVtl7C-E{(Uj|_YU$e*r3K$jjJ1X!qqj6Ya7=!?y~Q{9@00!|M%M0 zC)z2@!E4;mIM{e&vHG`T@vjBS`7Hjelu;2V}Jtq;)}~zi~du>>D7p!N%ss0LX5*v9&P-61=dn zt+5^Ccu8YN<6@9zwxKmfL8fCM)d`U69*}GSWLs_&8zqpi(YUNp1v&3))Eaw1+B1#m z#(t3bn;Ta&>W#l|{2fUDZ6N=5G~V8L08sF*#ycAig8bjtcu(WKfPxP-KG66eVBsGd zA8C9P5b?>z#~YsjTpVe9y73U8|tpg1!N8 zi3;wW;QIrIRuBh?UiO9X>_rOtN9Pamws78DSifCqXC|KrHl74ZN6!2f@Nm;M4T{2pHT3xq^Zzzcsl zS5bZqFVvraYnbo)KTjM3>C<8M?sJvj!wY|bxS;;T6_7rmd=FmuADA2q>C->^#1qej zd$0Ic3_6~G7YtLYnkr0vEa+;nT%A(%QjWd!JvY72P0#l**_HjCTn_gP^pEsk+-JYI zb6#cf;(3)_>VkQNnmRgd>c&E)svEkQDUa^av!*gJ+GW5DO%rB2E}ocB%!$0wwZ@`i z)oRtc1R4n)PHyvRs-DZ6YE{3irW>ZA7%*A0G@028IhL!Kr}YbSG$3acvMT7MadSc$ zEtd;wPtQnqw^`LDySueYr7*pK+?W{6XquTJcQV;>$<(LJjH#ZsP=yNvNzIHF%Aq(zrTSuBwI(gygKZfQzK=@GX5+&6hl{oTIMq>EF~pumRpRtJBJsp5fuX zbqd~ugfN0q{FI*Cu2+qGxwLAHa0cp5@*%^G{*sATt7;`95A&&W zsxeWnnv2wBYv81n2|YWRsQ?E|6{NoltLUJhYmGY3PzEnh2DgoL4X*DR>KWM3=dG7b z-_p#oRan(c+H|>Qc6SdKwL$?4HJTxud|-<(nA0w|qmTzz3w16uMen1+sFGA+!1!V**4~-WLVSARF3Pd8W>ky~29nvMZYX!kIae z_Uq6v8o$-*vJgtwmtms4xiqu9otn{8t!mSQW2DIFdh=98NIl||A+G36dWq6 zE_HVgVQq%MiB@w_B&80$L^O$tEzBCTm`qeSI?iZJF}j!ptcfTRWydb1s7+@uQUu^a z2<8T(F)-c$VZ;c;N9+0q`q?nat^Seux`;4P}e z1n7&(s^ih$#VF8_| zBvJAO;MDQ>%%l63k==q#eI6h@4u$tJ!~A6Ekwm4a;3)1$pA&HluKQ6>W82v*8YK~# zDvl-5D9T7i1EiG9x4yxMg$OgUPsR)Rwt8A`(VY(8sMgD5L6rD6<;Qz9=n$O+!Ml$X znYE`@gtZqQE%24yIRy9!k;w!G0&FRKMYg@L8^lMNTF95gF+4BSL6?<~L{T$Kk>>g< zme+zFDmcbWbz)ZOx+Z|65@>nJzkL3yS z@aVugeQ!S7oQdTZ*)0AYB4mo5n$Ae)?3CI$+&d)5tT=;tD}TPg0(ggw|4f**llc4X zuwkHP!pxe)Ie1XIS*uPGuQ#llMpN+szwXU~)lZ8|(Qz^BFT8Wm^;05~4Ge-k#qfn0 z0J7)%;#`^2ELvD#EO)Q*h`kM_wZ+$fB@jQ4C4)7!w5* z$7K)06y&IgFrEw1<5QLaaAd}r>lq+LUhSzxii`>aWp@e;0Yc<4fq{Ux6uzzp9IVIO zKyE|&ID~yMgA;9okcSd^%o9P7r|1p>$U}!b7I^XF7Louy+hEfCem%#=R}P4Jrt%{5 z+ZU*EoOl7&@*ROS&sWla=2}eB9);o@)Ez>6& z;!tV1u_Un1YGe|RB^X7*N9nPU2Z=Bcw2grbz*;Pmujj#dhlnq-2h^2{JS#;36X)ui zgo0afo}_~e2$Ovp)n>$OXYW!SrQ+19e928uUxWh$?_E|m;nb)C9Jh1xU?ZG$B~{5@WjoR z;a0zY9hV)c2(vG^iiPB0uVGoi*1C5>%a=l`EKp6ayYrwbywZVkhiju`0cEoCg-SGG zbyi6$>bS_uT87x&4Rcm%)e@{eByu4fh^Hi%H!7N$omk*xqDD0w!fQ^H&|U?(S`A$o z=rlAe}e9<(4fQCC))WnrWFj?D+QY)QjV`7_3+~e8PGn~weF2N z#yA%JV(4nd9s{03p~x)JCCk2;>RX+}OL!Phg9;=yqyZ9eOb+!;+k*HgEV`gDcqgTl z4_02gDVok8n(Rs9of0R6VCesIYxAXH@G98}+O}g5H>{5nM*{RL{(3ahy_*OFnd1w3o*Xf$92#OYR6)S4lL z0`-Xo9(mGc+zFLQVP`e@o9C^!OCUv#w2oIHegv(Xjdr20`B0{fRty2zsIeK`IYCeJ z&MYEqbi7@ffny?Sx$z@Ix-<3>vJr(Rf@GavWYXM>iZf__cR2ntLEGC6as!;BXALOCVWxKTn4C5Duh02P8#95ty1Vg5+xgOrc*+EDU8$8G%n^|8F2bqUD64PQ>`p@0-9?OvhT31Ei&}i0ZX^ylPru zHuW44n2D0sSAy-fuxp&*UQ`E{muqa)fZJ2i*xc8zOZ%FVQDt)*eM?xhfn(2uW7dZ*!xqj_BL>(1#)qg#t{qiNQT8_zgZbv%AE(TqBu^&Lln=y;x} zsrct85gemjww+ClaDIg4H7?OEgrngp;F?8ph(B_`&7llTSito;N@mS8v+POJmN=SO z9=j=vKI*5frg}TWv~FNePcCmm=^_1n?N~?$sxUA z_9l(Zl_TnJurMZPYWz4(f%$@|GaocOQ^MpM#dK@?Sms5BfT+k`km*8w0D%z>mJ|V6 zqP-cTF~P2Xwv;d-Nu`}9NSB|%ev4TCLLqdts^a#tbqm*}Cwv-U!GIuH?+E34*0eecMGA@X0wqu?x znU4|Iv_{4u$bKP(ce{{T8l>5?@a(B2W050=S{^oB)&;#%IIU5Fv%1e&rb!W8z^vOH zh3B(Q zfP$2@SES7nwM*hm@Pet0v!KCiVT%#m+KkwV^&`V3oTM^Nc1n+kMC|^x)-AfPFwR02 zr&|vuXTi4nOw5WE_eQ3)1=~WM650JkHDYDx$$&3R8kl&3QHcacs7Hp%N3V z0Ps_iWCegH4+1c`D*!zC3rI_dTka%e{|W$4agtX6`0}QsvZ#$VWH4%WS}?>Kk;5^p z6$<#U-@j;v4v9yNta2MOQQcA0R=ABAPNz^aluB*cgaz|$W+Kn}2bt-CDea{17z;fX z3lE?YK^))TIF;PEc3bbpo*}!n7ztuV3#dzu1${)s;b30CTttJKQ!*#~aA*iar|in{ z;OEEzT`x}vi&W97c~BG4{_xm50eN^x4R`cxu^jVlnNUH}K9H=a4+d$YFTQmWJ#4NG6C_}jQ8#kcOwQICCHl|m} zk>li$bvSbz4x7#t^pcX#P2mybc#gS2oFJ2$6}X~sN>O3Op=aAPafWmM-p|w{v#pBvr{Kc!*cR!6C04oVq4FaEt_^I zSvVk9Gf|+%JUFu+QbvXm%~nsnB?{6lIo$fCRW27<-IU0rJ7|G6bPPF%6881 zZjbe;f%|T%^KvTmcYz3U%9d(5SIfc{Oa*)Fmt;JduT(HA=cYrEQq?O3Evs9KZ4j+J zT`kp$88~$w)E70`WonFdPm8l|;Sm-q{enXbk>9H%)+kR#2@R1a4^XBghRBmgYKF*D zN-Jvb$%qYldLs;u=Yv#ArY6AavC=O$MkmuRJVGbaDj3}1XrVj``+=Pnx-*yCt|9N? zun>J8j>5J(j)}LN)V*8ET>#h29$NSqP$Irl7mf47@&!bYtds8!g4EGmgsBpUYP|Uh z+6`#$Bp4lKi=vbIi6qzu7KfT)JbaDQb{PIrNd)s{+SIh4hf+}5qUB+YGWK^kyY5)T zgs<}vDrdAzR zbdnqqVK+yz{O$)I0O68s7D;WcVnn1*jw<3f(}6(dOV1(8wagM4n!)c(8C~5L|{M&c-N+MC?MDw|1@(V7^OUDi9&< zo3vYJmc8WUtdMq`{fd%MOv5Z(l^n&U<5xDqHY2rF?e@_iU}*PcZH(8D8+ zG-uGbS?4lKCX&(SeJr5TnmNO|qtIxsT}WoS0dt%$yFV;HaQD zs3(@Gh}dg#7MNdmg=Zv_1iXWoYZfRgu}>Dro2ds6X|A^mI%9#7qF@lQzhrta2>7h1 zy(Lp2f$6Ysv4dYLO;%Z^;x*r|*iv*?3Oa6r;R^{moCj#?s4*rl^^~#`WxF#uQbU^a zB7%Jd_6lF#s725y3Mpe}sx7Dg0Xahrg%z8H`c0UPLUtbQX~t2Q zMz)3%kqA`_M34+ss11u$|K`zr6j~9G%iJ&|CZbm=OBr}JPmBo0V&`ShC|+z@K$!Sj zA(|&czr;KZ4>6LXJi9eC&?ysolzH|h`e>PRCfdtf#z94MH&z!sz2F_I2h}mldWA#+ zN0~4Z>G?F=_K-na$qn+49Up2dDMHp^)^QGlz9!V2xZ)1< zUI;N)-1K&;8eYrG^n!H`wRoyCi%L(E@aRHD>wch9xColDz!>lBwq*p^zWE`Y@CRN6 z3khvJZ0vZCM{|Q0;;z|kk%kGz9dMlu43OH?rSfOHhhps8lLHMryGI$|qQVW@p2S!P z8dY{efJgMr_b@c4xkBL!>xEqbb;63;oD+@>-C_Cma#e_}B2i(dDnQK@EBfXGuuf6W zu%BmwTs+53>S!-|g7%?fJu>2+-3n=3c6QJ_1e!0_6r1)6@o3{5Y(P*oRl~P=2Yb!m zLW5n7B)mu+OpLSGlt>Py1&Qv6!4^nItw|p21803+GfVg(gC^BsKsyX5i(gaWO9VXkW&U9NR(<% zd=mmIRHBexi;Zj7=cn`>>6xZR&ekzFTVUlH!Fiwl83574d{)Hnwy2x#XAz;8D;KAV z4k1yqE*9b7WT&vi6;6vqmd7OH#CAhhK>rbcGwuLAL(hCBn9d#Z5cqn8TD0fLeD8RF(dhK^Sj3|#TF$|DjTD%ML3H@z|M*!+FXR@ zPwfTA;0EF4(#01BOJA5E0=dgme&REpR|9>WnRn z%F=6wqUGeznu^GRGY07jys3>AblCjU+7+}`%1Tb*Yp^g_)W z>byct$wGO+ZnapcmQ6its<0F4&Uux^i|18#sSDr@b#&U)jfINyf|WVR%&29vx?zmf z3WaI4sO9v~PgP3hv&3rxm4F%|Vf16wuH&-;54zT<>wEe)^{o@gAM(xCs#P8KcFjSD z0dfI8pI3R7lB-oJz%x&k>_^p6<&4FPOJD$UW991P8C9d2RmkpyxUFG%bPwI+7U#fulan-@A#V*od}_WZuy5oMmCR`s!LxmGe)!%ndN{NR}mbY>w->=J{8&~!sY zCr@HP?c$x+ahqrB9&YpO(w8?fd$mG7r!Ih}3mr+=pXYSLtd^(6%CcW(GDrB<;8e~G zGL^Xx@MG>{&#xYWV-WdAUWv zcK8pIQ|4WytRi>d3jSN8%pITGtt^_GEzIqPw-?RLO~H>Gq|=zf4b8rx(Hmp*)u~bI z)oGH#tNX0$3G$^~cTm-AIj1Y471%b=-#fUjuhrUbJAK}g6&ERUYf!rkB8lt>4ts@H z^MH>1Xi5l75JuLsF6Y_eY*v|L-&_OyhwgC$JR=n&N(6+rgx;n#w7yXHLJ?!rDzS3i zDq=z1rx|ER7Av8zWD7OJ)T@T7!Jf&bvZ)r!@Gor4OyAE~S!N*e(8lzPS7It zTQ4BpWK_cH*B)deW{E)_PAUr4f8vl^!QfmK60U@JUl_cT!Gc9=WX{1m<6W*BnhwSt5_$Cmaa8^YeV1h+~;NH)~y6vgIlUYHrqFxa!6$y z@)QFOCROJ6Zo1jz@?&F45xgmQ>rB2_DcJ8?A}2NvS)MPAm5~P|1=dk9;4Kt@-;G4O zB}?&5#xeQ7b$m*wTd=>kV?(HjfGcsn0SiC4Wu$*_U|0b&0ieu}>R@liyKtv-&CEkk zqfkq9*5c)hmmruhAVzxwiVofif&{k2h5Og(7r}C(e0PvC*77HL-b+_yt5nc z$86V(4bVa08-i&)`1SP=iZab%|06fgs1{YAkw&wydm=CZPLK=RxlDSUhV*Q?3SGol z0sp48t!*5PIeLoNWUkF%XQsW60xiy&jd ztZUlrU|=z%Tfr^NN|{V-D?P0Ab=jdZ2h^T!%M;b}?+7-0Og7rCK_miAF$WGD*fmS4 z96*xcAnL&_fa# zxxABus?<2gV1_9}-0ejSW_WmLM=+b0k}!)FgKZ+KnGt0goj8{UT4~`@gg`D@8EPG) z9O9!ROd^+r*hQo5VYeJ8b88AVN-DD%h;z#p0e;+UpCGswshs$g!HvIVz$G^p6x^@f z%JL)|7P+-jRYoMiY+SNIaR_YMz#=6|Gr3^{kKb z*cu^f!@^<)^;kw5CnE;sEtQ)LwE4^tfx1^LBF2Yy-m&H+M3Bvp$1@P#nI3WG!Xl30 zl2;xg9ATkp7v*+ldEjZAK+hayho7{$5FZmq1t+A*vfSydN;x!XwFX>>JJk`6T_QUe zI>&TAO8t%IFr-SNUn0vHZIMBoh>peCnSTF-T33@ev5wu&ryhreklc##kPs&KmaDZ( ze0XdOk1b9-FlK#iqXI^!_=An~3u&WT*`iiqV2PJ}SOttVEA+k+OaXy$OzOQtJBpmJ zq2;cBe{me-It5egy1iLgcW)1Zlxih`aMDUKlJsW5muWN6cQ0@X4m>5(^y0lPZSngS zV(}UTj`QO5hWZE*Gu1dWB>a^x}_`Qbz6WOVq_ynZ9OG%?6#v!R%0kC;_ze{ z>Un~^(zAl6QKdbT{}b}EYW z5FxMf43t<)u+3T|uw5(E^dYS@4u>KMszWjx5K^9)DufA7PDPT09Eq#Jh`|HBfpW1&sJT;N3pF8CEbrM@`!5#}p(< z@0c6~EeB6XZh+)YDg~G1a7c`BNsE86PJ_dAe<=Hk?{$NIc6izLr6aIxGU2z&TKM+N z=Dr>78|sIpY!~<0s~4Q*SvcL_xghHp?4^#1b2noEh+%03yjg~+zg=T6IUnCN#&GqW zHm=TDt-{pk5pA3aL41?>fkVz>F)KS_+njq~&+IMWphpTiUm;uU_U(tITpGl(u#S=b zgvJ*4& z-6FLFYg%Ce6$B%&Pz}~D0q6GXiaC)ty4Kjs$X3JRLs-0pOEaN28W!@o7r0W&dUrzC za>@ey7}r`YaBsqjDfWwn_z5Y)nerbpPn6;Plbh)d6NZU|SZnNAoPZi1SayJ|JPOAc zHnEU$SJz^Wo+7;VEKpd4&+ud+i^@eR@}(78LF3?Ka=f^H(B%jjlL&OV%FW_Z4E9S;P#Ed1uOYulV8WozC3cM7j!ZF#b zvF@458>ICL;bBDZ>~!}Fbk4=Mjl6|m-z zmRQeI!PJIzv%i$nr=mq^cSWY&{}dpmjjiBydZ2WO7y|H$X9W)&R5tMq;Sf^fF@iyr zznla%A;2Fxe?~YjXZsT;Y_qZ$hR_-s5=&#~wTDuzx%dG}977;rf1I{2=s+*-anRHt zrk{`TblC`!N|l{w6SH=(bru&3#5z{;u`L)OziNMA#X=d_PXimOW>jIQ&CNHvc} z2%|!4mkHedg6zCNT(M$|=BG%L7Ip}LEt2d|Zk3AnF<6r4vwOGnY+_J{m%?avo7ec6 zXx9TZ3zo_DPC)fu1v)sk!A$4NGl4HF{{T#wWl4_(jQBl;Brr6rad-0Cq5(+SGJznxNKP}%K`^^=gY=hC6N&JT zo;DC(Xq>V%p~taE@Gw@amSM7Hvf+!|8vq2Hyhn9N#vQdAl!7+e3tD9J#!`-*pykV} zGJ_eCxd=#t(|pMOD=?UWy}h`RCC-nvMrpdct2*qe1^Z$V7h{)^%fn7lu%Vo_J0WiV zgzGK?`8v5+Lpi}Mqrwb4DWbPrs1he=@GBI+`9OI)_K3p9Ph?6e$#A#~n_Duv9ThLQ zI&IJWbHDbpnq--PytIi6tNx~ZN!O|ys#-1&J82TOxUY$9Ulq=m_-y?Qi+@{~lj=_3 zpe-G@5=>zpI|oQASFvP&rQ>X$yNb;>*E|X~)bgUgu{xJS)PZS=#8D+?9FRn(w8V4o zr7}m3jcgBV7`Q|hC=Zcr=;cC|Ad-|mY?dn^&(OG}nGUFU(8ZL@2~Zpw!VI?T%JE?2 znj&|GiG->#hzMHf5Yt6pl4?DjOc`p32Z|#g5l(4IOhGYrlfE4VQWB@P*=n*hbHkQ0mr|Da^ynsFLYR$(=+<<(*6!YPbX>syHo) zDahpoQA$$o@IGCyNEdr-t_($d5)#$jtte9#Wk_7z={w0~9;~^OCqqj_y`5JR)tY|o zFNX|A2J_vPiL}$qu zgB8t0tz5-xroRS&E8HjGmOu*Z85@KCfn`$|riJ?7_FyxPsy5;^j*L!4xN$VeV-17r z$O45;AWTTH@#w&d$=|sroS$n_LsW)Z?PLl=zh>z3STOp0HYrOqP4e)-HSN(vbV^a8 zDU!z)1||{334=ObNqkD^;=TY!X*C0Ns)^nln0k002$S#Xq=ymS+@um3#*$$;q%Ao+ z$k%>WkegE2AeXqv>i57l3#D8yjBV)E#0)32vN?sag?&LDi`ZOKsX!#_U^Og;Uab{s zXA;UV`O8CN!732_3lJBZgm(Uy1&QIBO4*u6k6KFW9Bm5NQc~1wwivO>_#|hsoG&{%QX{gM z7KvJ0o{Dn=k@HESycI3qnJ^eOTbG@l=+GbrdL+onJMm;hr_e}ckE}S)ss|YmX6Iej z%d57)q-wj^?(Q_FRojJFi%OH6XX@$V^yVfIl(_7+M@76jNL-aSynO?srEtYp&)8rN za#&Z+){4-#NEQ(GmCWjNgmyafBpHtIpy_hPoz56hCdWoOrAy>y@7hhh3_J0%MSiZ$ zo3M@-*JYD!WFk0e2a*gQqitJY-2r3C0;O?y7#YA~&7&PwpqLcBR-i1gDlt;@<-ivx zHJ>8>izo@*)1I`7;zdkXC#H2?Oej5K_MO*qjySol-@loN4XT*KJVS|$bc1e-(a$uV zv7v%=oHguDW(8*KUihKZNMsoU#b8k)Xk^#)28?&enqf~VsVu4vDIpm6dR`)`;k77D zQ_dH62&bH_GAtVfyCqOciybWwR+p2xFHweFC`w_)?-*TSzA{`3u@Y7` zu{17H2~L_ORirmjq+n_dS>(&A2_N#I%xA(xaRxGiXbLJ$aNe{8ngEMa2t#F)Om?zp zKVbYtOMr|&ONROBg2rDkBamSTzi~O&W*zn*$~LjUS=vT^y=&KvFa+Tx-}=%xOBxlp zxT;RCnB7SLClZ+>9Ku zN|$v!#dGXkz&?+(Bv~=WF^FtkT6{bQ8)Weg*CQHvK^cV$>z!p*pC|Jm8^TbKQso(u zyCv{NM-8H5iXuHNgIlsrBHqf-4iSI6#^<3}l+yw=5<3|GsMDC>;qx3xl@m=!Z+Ie(iQ>R?JFcgVx_I@9Khh^cKBbIXnDI6Vl^4uXW-J3 z1pE+ibFOwWY?H{SqBg}Iriz#1Omg^(pNVdsNVQp7c;mqM zuFp^T4$yS~zDQjP6WAg&+8M6Ik-0^xe>f<*mFn*Uj#u}@G|OqBc*fb-AeVKY9b+;N z4q|Pa*}!5(?~;+@>PR&5Soy`Hj;|JB&ZJe!`Ql`25av_(bnjAdTk=X7)ECZS0TYK? zl9T<)@l+YSk;xY;aN5|GjXeV+gPSwGgWCp1$VZ^KX1P|S9}nYu)@IR|hjqLQdBafG zs7vHE7+{n2Weh&>k}qu(?(MQ;YD# zE!YRG+Uz`inhWWTj~$6%LWL-JI^rY@x7#*R!#*}UC;`jXud`0%<@3e6XFBB)37bi7 zG$(=c-9@uno>>vj9LCXvMq2bJ1_ADc(xUF%(7!G-vSUkM6gwFT*2lj|X<>j!V@D6) zpt2cqAZm+Mj_|q;!9qNVnx2#r#iH>mwVj3u!KQtl9iHXDS~u^EmD$2-o`rUl*zQ2? zFr!&BK^0pTKt)WA73zf@3gIv+H4XK%K3pH2C^pmpHK%PXe1+@h5WulN4k;}fAg4S| zg(K{b{dwE0k2tv;(z-$* zx@Av{!b^UwgJB$4znG}hF(v|f>{zncxYWsUmqJhS+=<;(_9012yG+~^9oq?cb(IPS z?~y~Q*kByasD%?H`E~V$33L`|Fsr5`SmB(PW|oC}6B;B6u+>|b_X-d0wOr@UxZstR z#wuK|#m2Z0lzt{aWUFLEGRlFA01;l^c&`LGtDNry$Q0t0lOan8jm(@E1))>kI}`^@I2JrQM^S&6!ftGi{txj`u%g?Y0isOj^lD)w1NY+ zZ%=a7nswwHjtW+cMH|IPvu=fzGl{L8j4Wf5rg+246RbRKZH7rTJmXlVGdOKlnBk=f zR)duxWVCd+R;hpp)@f!FV)~ZIfny=s&u2gsTtPpX0h@=Z@e0!7J$V<2-;9SMBcL8@FW=?GOkJ!v;lTus?jE>G5A z8mXYCa5Ttv5U_()xdwq2I%a!x9(2qwt!$~fc@+YA1kpscTqx*S`y6s3nI9A@KB{)? zs7Ocy-U(Ojx~51o1bGFWFfNMLz<6oLmka+K@;z#HKhe5QKqu6SbDnR??egY6j9N#$L4j zK zm$ofhzB)T8>#bFd{9b)_61Q2aPU4;&vzIz>{{xmLPQLt+LJ*?FC5l$U7UpQS>uoWLdx(xf#Q(;!Y>YcUP# zq%{>=CQd@ztaTbBH4Ea`i&&d5wPSYo|k> zG`}r@JPDp#1{IQgw**og=RCW-x6GQ&O8+gPg6;9(G6Fqi2Nvw*GL;aO z$fhT(NX|+fM#R=CK$w;QV0J5DX%1VB=sm5&%Ez3dfyGq0*=1!ei7av4RgX@E8L7fSN@!^2Y0X4?y{LIem} zE0a46>@4n!L(N5eC@bljF=w@-ho76Y()jSS!LvarJ3p5SnLMS4W7oP$th^jFrBihV zPIdw5;feKbWSb2hm>BCG6${2YG`o~$eHe>_R*2>aKFnw|NiripmQuze*n!hUpOu;whn6m=#BrO!hE} z6NNEM-pvdp_ng-p$pW8PibI%lg~8f5Z^!Gv9aIN(}p6xyY2(W+Xp z(@jG^EixHQ0mx3TjtnFGgmfHjj(B9UB#1ey7!l;bYGv3)C1VD996YSU6X*H4aq=*y z3($3+&kl=hk{F*Ctl6t-Sy<0Yc0Y%W;1dwX`t?AsChSABNL|j2Hd}V?(FKcoJE{+? z4oI#VFE$K|qgt;RgKCd=#YVx>m4jp6o3R@V@H{bB&MCXC>SP~?>>9tLnNN2@$akML$4 zh}&V429}~*m+5gJ)h23sWQz)p(f+iE5kYseosMxk0fD+TV-p+$o^<*Io%0gDFA-1q zBccLH?uTc@WHO3@5?!xLM|h*UBV2&|)> z@F*Uyi|0C_VGQQP*b(}W4X^wpEwj%nr0=Ff5>C^{&CKzn7i**E?(V7%I~bNS)~r)n zJVR>hE1p`Bou_mvJ!>miN^3f-asbtom(?$;>7}gh@fZw!yntqwML%+DBkF;vKVd?l zpha#D7cF#U$mKz2gDAOm5tS!n3Av$wObXi*UhyeTBi3SvjylBD^n$JSvXp@*^(c(@ z8|Dzh2bplZki)o?Uu5La#TyzRG5;f~WZrY^}_m1ZRB)Ok<3u?b; zd6v*)0qh0?&uFJmA5p*F{u_ zj4F$I9Vsy5TL6hJCx&8~X0a826GP&xbT%>c%48`6&lpb=MGPNg&AS;qrnCUte6xd# z8`o|qOjjoQ*DYPi8z&SPrjC!SJY|V$c^ER~RU}Cqo~RlEQ!RR1I7&~rF>V(^+uSSK zi9Z&19*aFxgX18hy(|xy9UQ=xOL?<8;SN@did8URkz1|y1t)Up78M6$=~II>-ybv^ zbntm4(;J4F@is7vXWxTN^SD*J)3v>EbO;<_v<_)$AlZ;JD^l9NDBmzNm){fp;@f_F_EJ=%i4=_QgFZ5HBhn#(8<-AL%6V z?NPIFkRXXNT|LEez6(-??}l+FiA^Kla2Y(zy)M}tk5M7yZTpi1C2 zSw+O!tR0tBsSX%%NtBC2unmQucapQV-9kO>{Si&t&T@7mMXmcXw}juU>@{$$6^Z!LeOBYokSy zWlD3oS7xj+^27;}NKe(Ir9rSLuLWjf%(hc2dHrqNMIcUv>`pk3<7XD1I`6@zBZdjC zHk~}I1HnP+q!W`Yk3dHu;Rm- zeol#@%#bsZ8AgjdRxn|Ipdh|jZF3l|-v0bz+ix}}TW-BY70U7Ujv)P~T>A4fyeh<+ zGykhi)|ZDC*Y&vOD5^-Y+Q!JhPhgOO)3-Z|NVmTdcog|Rhz9ybir3lG|*$MFp7Ys^U<_aI$L6wXTG1M>&;%MRLAP-uUsL&Gy}7n`_d1&YLy#j*0jmRf}f9 z7ekahflw0`=_X^S=x`JsCM|i4VUQZdf&{<~iBSX9h>cYp-_x?6jH(qaKDiT&$~oF0 zMtwnPN!8o&3KwOB0AkVz~2NivebmBg+z?&7QBqR?;1|&y}g>aG~6TC;fsnWslhzSbo^u774z${}P zHTGGeZY6oubHX`J1nCf%&R3 zz}i^bjDxoh-YZ(8BzAm@malfgireMdHoUzj3O3ci0sb7F>v=+y5t%NpGNN%ewbQXa zP!td7Oe5?yr*^JA%VY~>qgK^%K#6r8M*%K)p2s!?o>4DuW2YmiV4P7q33O4w^FE?+ zPa-`_=<=M@_DZ*p3!Dq)Aotne#7@Ha65-EMY(gai@GOy(J zos*@cz8Fgo7L`rxiIAjQVY619#K^1@4wot0mPi|B$}w2uX)@ABoE_h4rn=HB1avHE z35{ZG6Qvo0$I`;-zzt5?BS&db6eGbt_olG842(bhC&BLiB#-$7@hc=mPW1tmj zgsg)3jxu~0&FOU!gDxMm5$!}TwtPd(v)CXCRj2bU-dOggjC{aELd+*&ZnBw17;M0S zmz`>%Sw+vv1{ysEbe1;K{NyD>T5LltsZ;XPHmgD%KXEb{$GRoK)m2^tg^J%_GO-7G zmBW2!l2Xg7SUA42NrPoA^l`|99WU6(g>7Mp`A{cPh-Jd;nmgW%_a1G36(oH|ZGbGJy zc@wK0T5T2|1$A;-M+s?9zKLnLL_{=;thEt`0$mW`@2G=y{`N>PykVHux-9y#7a8cy zVH*N1o7D@jJ+!H3jM}KFjl!wb8D}Cq?EwJa$%Vb+zhjArsv~RNLpsnLitHMvPI-%) z#x~1c2eV;ZbZMb>Zn;Mdhl^UFfMFS06RlDyOfRs@FPj;1?Ml>{#BWW&ind-cny1*dhsDKv3wD(+Es95j9X>R;io2u%vxcNHrs+t7cn`;F#UxCxK zkr7d_j$LCS6C@sLC`@9u-;l?<2$&RY_6Pwb;^kPV=$F;>Qa19OT$!4X0~2Wm6d{6W z^0HqOBHp!cPy6y#?E86|jX{*pNMwY23Z`Byfq|bLK=qQ-R;0$k$t6oSJ7`=rDl8$j ziF!MUIip<R zS+6FGKQ^x2fH715x}__bemARLNoi+8WIsiV@NkE0Ij2|3(A9;tVc%ZJcO1ReYTWk5 zF?OL;zgM&a%#KoVPNNlwA1Gunjh(u< zQSX9gN*1TtLzBiVs|9O=3ux1jmW}-o%ntj^wL2cL#-8Y9wYlPr6Utf`7%+D}15Lbg z7MtmNwW^ZSJ(mt}JT$@tO3^4^z&28gWf>0X z6k65;wN9JRwOqV@uY&5a?*-e8g-w3_t1khTAFZ&O_sD zPdo`dNlbeNFWqmWCWO%nbJ1>PCpa9IZDRW%BF~;42-7dnt5an6cA`meRT>--n7QCa zYWDbp^(Dg!>jsz^lKV#RZ+canH4fk~8=472BE4nh+YG^MhSt}f8hA4n80BH}iz84_ zifndV^1Q}26v@nhl~?GrqL!X6i6for2M5pU&ZdZGutH~_P(+q+UkGcG=Gr_Q@1#|; z6BaX8tr3uQ$Z*++wQZ)a0Pj?QKv90)q18-CYO`}7nj_R^CH-j1E8C?VlWhb+)+h{u zWzgC8GId3EEQ&L=gizO8&v zn?_U;C?rk(#sx~QGo3Xgx$d<6B%w=W;p;adZKcRCwW`VVVvp(8aNMc$vew^I6=O1A zsX&jm+tnR>NgdU*S`9V6kPuZrZy%=AsX$5ScDB!qqE{+~P5>IhL5Gs&drc~3gB*hE>o-y8 z{iso6J{7Qqg}mXCkmBt913S)q(R~cX*}UzC=OlRT^6}wrolB@lMqQVJI4CQ;oZOtr(^oem^)9CiPJ*z_ef~g&46@mvAZ== z$3g9q(!5C_L&AG?=zuk~?1TeRyF(TRgPA$4iuYxT+wgaj7-?M4(8{(n%{st1MPg{N zxf-`k4OgqA=mye6I;8~6lXv9Le`R$?M5s8sbV{A?|CDv?cC8c_Jw+gq#SG3TU?F6^ z3DDuam=r&olCPPS4Ihh?wxTB~*AQ6{U3T1*Assd?vx{%eU?k}V2=QCa3&2M4*7k_c zOX5M5bUVW-Q!n93l8|A_alS*l&GVzMj>G_yz28gY%EV|_+3YHiqZ}4zv&x*&+Sr(0 z?OHRT?bS2onhDb<;U(u7($LWqx4VclF1WU5xQ~fx@Y4O3GmheRH938(XoY&F@*s2k z72UN*`=C?WnZhPPR^KvG8QZnoVzpcEGG+*nS!o6t$kJAkFidXA1vA)W#vwx{1AMr#%1D44*2@Gi)LSlBb4}?T?`44*0`Y;Q6dFYh zJw=(DLk6hMV)H&043oX?BQc zE9#w6JLi-g5@c4K!Ml}z0*tWEcshFTZiB^q~sy`FHe5nDpHfso&HdfkbU^Z!`@!@HsP2vtIQIsh`d1Gc)S68&mLkdh) z=pp5aR*;c;AeW?K=MVU{e|J3?P8-+F3>o%^rTg{{Oh$&zK*k+9tgcvgE`fihLE!o{ z-&6$kwE44YYrffEZJ6HE%9d@jzJi-u-j#0FSJB<7EAh^Iv%ZcnZ-z|fhFQ)DHy4~; zRqSnHd!boY6J}qGM015^S9P3uFWw0+QTrXVFs&ylOA^aDTPVy@?u51n5pMopA%&x*|;~P`3x;y)+RWV9R)0KR<}e|J$9YV(I#)$ zx&UPUzoDw`8iW50wZ$pO*hK$dB3!I)3-jiWGOcCim_O;T++tH>)_NLtFSRF~&?1^4 zZd~EK0QRVb_&PkpKoexvg1})zXoDoYc28b*F@Y}pqyvWu_BGqwGqRECn#N0hZ**YT z!7~QESu-cV6u~0>lG*9WLVj9gj?U43?8w1*f8iY*o%D%BCL37vu*D>Rk%wXK_n9K( z3%maoYI+8mb1;9%h#HOzAQQ7BlWVLYFgMev95@4P0iNmAQK5O)rt9FM)|LlNN6kRg;Dg>`6LOKhz zD5_+##|OL6A`?K6ohsn7k~~ueaTN_YqRnWauZPTpwhoC1lqWihPN4#wWH9X?$NDj= zP?ki`8VHo0>YRZlWB}y6G@C$_5kpMQ(3{202isXrvnk4S5yf zg=bN5d*bRaq7AKu?YP=48DFu|h2zUV^=?WcA77!OmD(k5PragUYK+A3vPJz}rxIU>ZZ&%m4?fFbqbPkU3LPvgKm2T(UQIwBNv;9hb<1+~(~)Lri7xl3$ZR4DE?V zh#uk8<6*O0h3yYRrDjaPmVS%WWw1#f@?(*j(k6TXVq`jA3gpP%fI#V;3qk^<$YjJW zMT0?^f?m}?bX+?eU#Dro_g zvn84+Sv+g%-6=aP0&1&!Ns#3R)?Xt-@v&x*Zf46Iunfc(z{bqA#N9rN7BXU296U zVx~YA#lsO5tJNieyp8FSIiaJavfslT4BfRCA#1+KQdPP<%Fv}DR0(H-GIZot-G+>DNgYuTmNP>++#Ikk|m29*OC|d z*DYNM8q9oZeG&C4V|)TM#}NzWdmN7|A%Uh#dX2fi&}9?bOtTCVp*dQ$?9hi7C!wRD z+!Ur3H5T~EIEdy*;snEvd0<&f_8;%=W{%{xR!710t4#_!;tN68emVm&RFLL(s$j1T?7R~E8=&TL^#pM#w=3lhZYBl8p{ER z{GdK|L9JAR=p?5?Li;OlS;~1X_z??EAfRHCW zeSo zkR-{VvS9M6bRwD(z>PImiOOt?QYE5HoEus$mnq~+lXx~>6{cX*6wVsbwVb*NnzdGY z9D7=D6Y%-vF~e;mQR>3m2%T13i9t1ErdZr~Or8`xJgEbXvsZFk90P+Rq_xqvj%{pI zb!bzVicx|_69p!wimBxbh*I(dFBI6NFRN8^aF&)AA-Vz*y{PdHy`n17k9fD3xC*xYhTFgfo zfA|LsJH64YW%UdNP+l=^#sQXYbtTeQ7?E>B_0bna-h6y zj@`oO)$AVN)U291pW7J{;m<|IlQcM<&5)B+C%JfwB1#x+*>X;=l)<;+AcZfu5^n;= zLzV&4MhHp@5Gt^yjB&V3iq@H_1vPcF z0W7KW+Beq4Wo8r^G-Qx8WWhCyel#>&kE6URw%O_)wOZb6MdR_=xvn|Edh`tStnKer z<{3B^rkmLb91L49ueON%w@@kSno+}POVIscnwVB~Se#!TQ}@AEE!`^o$(Cy+bM?HM zx-XxDiBI!#%2<912G`6yn0xXDeI;kTvKn5g>J=E`hy3Vkb}q~-`|^c?3cWBYv`4EN z@gGJLnneShZZltl`Xi$Ol`o_-w3Ph09ZscQADv?*Q|{pO=Baoc(w`Ff3<% z=*@R{B0om5!A!g14a}@+(E=P|uFcroMp5HocrDQ=SP^oRhef|pJE$clxbA`Z* zyym^*dutLFn|j|OcRXdXg(+p|5hC@ifTmQ-*hSNYb5qDm{(JVDWy7Se61_33mxH&v zCPs~{0{=oOQzYq{x8$rTr3*Ieg>EQK>8g|q(I)hSa z(`8WlY>EK47G*Xq2BpcS0;$FN7%*pv0zX$t{;S$*}q z3d}_+X6$SYjLh&li)V9^E6a~T&$|I(TScsPnJjobJvW;x>8lnDNsK`R2~igbvIzZ( z<>BET@U*O2_ekd+E>U4*tWW6>@9G(N4P38QAfpo=2v~E&?A__D&FO1nfJaf`E>!$N zvgyb9W+0YDs(pA;!#EDLY zy4Dcj0>ZR09pf3?cHg>5;1PtdepyX}A)ond9+Ud?VnjL2b)9dO(Y1zLFAS)zr7~eU z@6gnO>N9yXWdS_jZCslnCSWMDsegC`*+5SpK&WUKOv5~2P(5qTFLb-nd-xs#hQ9CG zCG3kD9_bljx>@kj{g&X2=Huk;95L+5Y2dR_DR0gwrd5T~NtPL~iJZ?upZ@s8=*_pP@P{e0HOIg@rA1^%&V?0`k z>PL2`weFH0v4~!72in#;!L;-+f+C3^p|TOvJZeW!L&IqEE|*P-xqLWSm2s>NO!cwu z&`>psd=R!o)-o^)L3=oJBH-q%X`qImEKC(L{H$uk8+{2B1<}MuN$R}e7*-^3 zh5>_w+(fLkUkT!c@5o6+2N*ayN*3bU5u_9mtnHV|0KRnnj0lr(TGeO7?i9fno=u?} zJUZXngJ`X1k>reY9~DW?NcUy2B0)t$?1htSD$AFBxrZUTDVq3*<=G=2MZu1i$ktk| zl*d^FWQ`PbYcO?bs;|bEjg4}*`5Mz}6Zmxf$p2^WeZU*5%6;LzchXL02r$S7qDI`n z79(zTBU|0-79#`<5HUzRH(qm2(`h=BUNUV?n}LicdLk69P&H_kDpf01samjN#R3&7 z7N}CSV1QFBdvQpzBPq#}B>C{A zPra)E>#vq13od;-S6_-Je|N$4AmwhBntA`19;;0+*b;v`-Vz9~a?{rM6};Wup00v3 zpFWzsjtQ6A{9K>^YW(NQi^3}Pti-F}?QSJ}yE{7hqAgzQV;rx1eXGCqovpZ%C?)*I z>%!d#q&_BE1i$d&N>t`n@OF1gq&hI^<|D^!;%-8?EzKMo!mUfP<#lv-W#nz~{)d5c z?ACnOU&wLKo{m&~`(r0^|H4V!ofU5BWR6>2&fQ9d;sQtf+&}(`t>F}p=1AqU@qQkz z{yTREgxgm*G##ZG6aMz4JluWRq4DbT_g#Hxc%|&;;|>oUnx69i&*n)b@BSMPOcTaJ>j*a_+^BF9!c7Y|C)_^a_OJ2$2ZcK#+;QPf33pbw3&LF%ZdthN!j=9Y>MLBY zaCPCD!gYij5^hwu3E`%Nn-gxIaErnn7VemECxtsB+4K)xDfN^ zzWx*0+XKS=d($a(&dat0{q318@IMFg^S)C5pXc>|Ax81uCYG!Br`#P`I`A z_a7;`T>rxb|42rSwExE_u<=^{I|ue@+|3DhRJbD+_g@h1x^TU(8P7VemE%fj`(k;ij{`=2#%S z@TsA#Z$oGC^0xZ^_fh0r-rjJSyP@;BTcP{l1sn%2>D~Co@Lk6DVSIm!ZyDbof<*V=`y+gRjPFnI{VBeG#Fswx zBe9-El0W@U4}F7w((wHIpO&tdvOrz90pZ4ln-lJkaHoa4BHX{9b0efdfd&N{6lhSO zL4gJZ8WdI8qLCF9MsTzKZYg6|5En`wF1+cLY~bq2k^`^-!P;k)1cwhPaUo^j!s z1(yx)Gv0M3lI(u>iBjU9-iG%j`Q7G%D{*u%lgfk=N1yTT;J=&^4`;kFNjfUf+S=Nl zx~MmMQERfT=aSAY>4JZiisajyZEL@X!dmwoXzNKz>Xo1WHAscaQXfKG5)3 zO5FPPj_jGKwjP9ZwsmFCK{+{!qVXsQZGBtv;ootZPbS%&tr#|XC_WDV;HJbQSgt+Ojj6$)(&Pj{mE7iPONy%ZX$h4PZmZ`;oZ z5UT~8*U{6}*|m?NCu+Vms-$Y3l)BcqOf8^Vo!mCRR@M+!mx5dii}tj2_3rKN*-xeR z*9Cyyt!Jb=x{|GDc6awAJG(9M>dO2=}339vp!o8A@Azg+tJg3F;p#XNrdpYtu&bS zw_)r{JuB6aEc0%?u=9Pa66LypEo5D*3m~!vJ9<0!b#15XhRh~pTW@biPqwuu+eL*H z6y}L}*UctIKgYHCxwow|O%aO}(6)#5&=7miwsq~LkP(hLa-FQnV+8lSucN1%0w)Ny zx24nF?F6S7OjoGNP9(PC07{i&UCOQlo`tOV4ASVYYg{v zw1KTiJsScs3Km>c28I->gTA8he&&VtvdR|;?d!;PbX`n=Lj+R?Gu=Gr5rX@xjTvLG zV}JX8)^8IPm^sLrD&YR^i}?@|xVM9qG{>Om@&yJmJ>6L`ZkCwGfv(DsAlTJ$Nv+yt z@~Kc@jX)-wqBghgKalOnwI(}yvpwCcA{&Q>c4BH#9SiP55~7HU7+nqxI?z=KEK(p! zt90uSVKl5(zY*rs$w$Z-16{Q)nqVH;p7s$aq@Bs6mnl1_0 zCHi5dih267z?IV01O|a9`G$bmZZ^&fP1KZZPqzC2!~F~&>}~JnZ7CA24E-Sj2YTy< z(+K%oytmfWG3L=*YdjV(xiz(?Rr;LlmX@x@g>j{em~CfL+KHSn0I+y~aNWJqDQ;!Ylmc|EV$t4Z^I}(C_b!I!e8P`wt z9@x{H?aUq^59t$fwg+o4EeBW2E~(fhA>kD$?1;9uY-_shVD|wOWA2gebGNhgO#0}N zN$K$;_e$3sw~sAtR7X}B4)>igenmwf(Io z(rtlW>AJUP+xE3ezdZjyS7&>75^=xu&WokrUFeo(e~!ETN_Xa9>m@y%Sz_d^AO~YY zpH(p8vK`X*6t^_?qZi1n(nENg`wzTTqAbH>=rQEr+S}8;zjbdX=J-8ICG>I^DA2km z-MvS;(&d&`fBXWpdEkCT-_b6OD3vKwaxn^D>hA1q?c9&)#Fmp=-22-uLN8T4X52j$ zrY_y(#^9%c&;vmy+a}Gs-O|F(DErxmQN2o2q)ilCD4{?%i}pKL$No(Apfu*jP~MkK zNjJD_c}yaYC051phgnW5^z38rYY))-<`O+8en}KVqgth_TnF}IooSU;n?Ry_jsc0* zkxT#TF`x+1In#|U=#?IGr`xifU8hQ)XgUDS_IboE{pJ|tHSlwadFtz>p{CPbE8Wm! zOOptj`Za}>@1w9}QYyJ=+9QMRuGZcI?d=`Cy?ZfNR+=(k$VurDq!_q|QcOO96g%6b zTbkOXndYQ){f>Ror+3jPtqjXv>9$>6kPX_>SmIjQIO>&VcV#ft8E>KP{^72k4(a|~ zScgC9aZ4jVM4n2z1FIZnB=|I%b4xQH7!Nk1%x|OBy`B3z(-8E2508oOP*tWLKN`tI z0e@%~!%iC50qT57MNkKXKUN9p&&`Z+UWcIZTc|KdC7;;Qxp%L03%mxeJQmrl-_2@q zpf?L@r#mk0NJ}$2cy-tum41V$qjwFm0=v$vB5JoA!1u`?}werFfv&fe|=kdnCX)XtucOd4YAel#5<5Pd4$wzF6I;m!ln z`cAZHmYO`w8a{-YVov;o>dTqRT1$=k1BktdFf{cC^qjeq;)w|?4ejKk@QrdeuGg)bNXU9HPAuM4TNEe-;SsAIu?qYd=pJIxczV|>^J4PT_otP`d zT_DvA#UQ@+`yB@`p0Ji2lHU~K&0-9?rR4>d>(lI=)u=p$^x%?A#F7>;ShCXEu8TW* zFlwGex)P(s;Jq{>K6DtS{=Ka3Y1VDEpu%-Puc>NB+Iihdq@+_fZVvB~ zQU;L{EdJ+If*60&7Y{=wKS7j)kRN4V!E+6PjLqaY2M7TQ8vI*jMR;vz9SCp?=h6Kgz*RhQ6smGpBs*-j-Lg@D}I;a z4L@}(I-)I|NwrD$AF(HWphNoW5&IzRbx9vQvZo^{efUUBT|`3F*>jQ-D2&@LAHjrv z_CAJa{r8@ZAinbTvOU(dM|R}EZ<5mY5WI|F4BNXYef`+D`^ehZcogy0en2rQ)4x^v z(UCoEm$XV_yAd>Z9D+#PZOycS_xJ5Su&1-VHQOy+i_pT|2nFA~VmF&Gt+ z@dYGOQpBfT@UI8jl09I>EZs9NK&}%=x1(J!#NCxO?Hfn2mfd>PmNo5xqqePSzdWk8 zragQVt!dKL$aH%0IJCBOBUPC5uWuh!Td3|m3go(tV)T8Fp5@!=xq;ZI&h=Xw$;aHI zM~Rklcoj-m`WkQU<41{B@}OT-n#$q--qK#~_uCiLYVse*Y4S@{?))%4r@una^;_s! zn5E}9tKr0*^uG3;mw;)sC6f^6Xv28<(SmFfNB4GPhs1n)rJIgMvdNbq!ThaA(6Z-1 zCw6{VWUoBBUApp^3WdLQ45RSv$84eS7mwXW;p>jAQTX~}8HFD_7X0QzUeu+ldq1|p zY0m1g(a26m030ex{GEShonKPlbW7_hA1$AO-|C~s$;7fMjlUj#bB_?UhSumg_$c)g9|JcZ!`H5M zEKgv!$B>35Cp~!#m)aoU^-7z^9FY3ayvb)M@xb5cxy0UA@h&Nuj{VZ5pn_Nmu0hoC zKU1W!zpw;P(R1-J)Jgg-!bUbJ5fk9Pb1d()AH#crMP7Xxfv);0EgmbXbnF4?(&Nw& zB*&z!mb_Uj`BMlUT1N(M(g;b@M+<>lnmGOp2qi-2O8~U~p^t8?e zX_l|l_p;h}y5eQM(wAQjKKKRvKBAJMB`qoa%FBEA&t6dS@)IE(K?dH7MoAxeAsF&U zPDEul2PuKrF@F4o#G-iaiq2& z)oOX`i`b~Y`$eeelNz#~Uq{x0uYB}Hwb}et#3)}ug_k}`&$$75E+IDR{UeZf2Uwq| zDdz>>dl5CPRhoJ+C%ROA@s=qiedhQ&+VM0u9$zbQ>iF99;yJK2^0wnKc0Yy!l~gNR z1G2p$?Tato>aqM{RQXd>&Eof|f+V7LALxO+OIsh7*+VbhlEt@ud!_IBQmxX{KDG;F zalZAE-c%cQdJNqBl8alVU%do#;&#e-=!aAh+TGOR-|C~K{O3M|-bMYn@+FGHlmFT$ zD!YN;xvwJtERU-*f8)D|D+GDW>t0eBq?FtBC~<0vHRYT1T)m5)^Y>8xi`Uiizx^d5 z|0N_Czo9<=J72OT{|_HupZ`Ze)U{hF&(b7&ex{b^Cyy6-jw90i=P0=NQ+h6bn4S|O z^c?;u4O+H;nmwLYX6hAiuG;ka9a8uI8QJc{F5>vTq$s}mrF>xD{?ck!O4BE99VB<0 zn30xFgj9G^ZDh=xbg?vl5?IZ(Y`!d?0FLyRm!c9Iyw+RF{lQDO*JK@0S12kt0;l~? zUb#DUA?dFtVE9~h zB1D$|K&6R5Ji63>0;p4<=B)pIYsj?-S$>*mJhn#9*@sS$d!;G(4nK@GRL9Q^m5NEf z6m^guMx^;NC0hI~JvTS$Ir13G<}d8|1U=VSmRF)$Q@^Rt@`ERewn`HxihACJNF%?a zL`9Zy;TQBi@oTEnJi^MqCfxr;j0RU5HUL@az7uI(dF;e2p6iIw_f=};{MYC?cpb%K z%D=yy$Toe_=T175vPhp_aNY3UK&@bi~ZH~i^k)D3?{4yzzNh{HN#{mWD!>xK`WTqFOrC! zA0Y;oylYuJJ|2*9HR2tJIQ3DAGIte=B7MjYg(h2j+eO76L7b&8P@E06TQB_(a+AA$ zgg)^Ks&cYpZ`*-%RvJGAyJQfnSGw_(+Q^-P26XaXlBYKBqi2D=ua-`dB#%%KZPP;C zc1pW+<13RL(l1_#?4`$F33Zcng8}iRLz*=%>NwadJ!o`c%1SFnm6p;Y252R%8V52M z@7M{v>f$!+9($!LUj;I(qBIw2oTTwrLNO`*;FY{je)3At@;4`;T2l|wbF7SrN?Q8a zE1?{K>itoKFa4523co!G!{Qm>)n8C%Tz-D)m6`6$0n)@lF?6j_n@(c}=ICRTaNuEj zZa#XFoRX&CJNXB~eFzgP-)#nVfN5zFVH+&P)RPor;*azkT&CyrBPhI<`7;#t*DT-( z_S~T7<~L43y{JQ=`GwjE2hP_Tv;q6tnrNj5PUbN_{7S2Ck? z5%)4(e2ihKR~$jZNeWy(xsaTFHcezw6>>V7?lQ2 zgU-K8fUhCW;J1k^^V1Y_^gHxk>ZkWHN>$lyQc`e>J5H-;R%zS*=hL>>TmFX3MlYkJ zMNiydmkj3ZrUv0k0Aupr+{p=|q#jK65H-SjO8Sh$ZRt87oNvwAxI^#Jrs zwOm#ZYw<@IV=T4wIN-pKD3MUkVNO_VkVzkZJvzLMAhPfsL$Y)@Q4IDP{+tL_n+?;>k>$)=#tf-Gki7ox@b(mDY zAS#SJ#R&Tcs#&X4d>wSY)f}sZjU(r=zcH%MA)AP$g%78+Wj3SIl=*!$;r1=Ma?l#EU*>^F+M*Uqb$+B}%z) zGd;&|r)T-g9W;x(nT(i~zG1U|YLyG%Q8!OWGZEu8*v$d_govaFcE|WfA`tciC`^d_&h)m00=|FWx zzSaRjX%2Yy>x75K=-GcgJvVNksxsPr+a~VB1jvuQ2@5cCF zW4(DG1q&RpvMO`94BoRJ?!>^aOjv34P1TN+ZhLdC#`dJyHy^A+KSa`@zE0G4?345? zvFGw_$c*e}3vY(q?2$Ly(kkMWzeh0^ZbcYt1KHZ{e>1ZR5bK3_;eg5CLXkFpaWO@r z>4P2;Q|&4TmLBR~J~=C__j^b+@!-Wswe;X6NX3Mz$}EuXb|5}Uzek+O$0)QK@Eb>r z&JSWKDlbwP^wAFXAUBZ5k1mm0+rW&f@yFo1@RMo*BJn5QLed#uYPLjw0MSQ2nM1Am zZahfLXK%Okd-A*KAn42{Ra>sJSNi2!SkK&bdUbI8?({C{yKlve`37Q=we3@2L1z+6tyiUU2{57vbKE^ld6O`8{avI%FNtA&(f`k@8TNMQD%cbJ6#rPwoeAo)SsS?BxGrq`U0>^LBUfIo0$9|O(D|Q&k+g6 z>dyq21kx%EzO8dVY&p{KS+v+f(Ad}0mh7aNd+k{n>4CEdkwUrRd*j)?mvnSwY93Q( zgGM*AT)9;HvA0!pdk?>jwe9h@ZPD#rdB!%~-c@H*r=xWB8Ent-yED*5-#s0ToV=A< z#pT^c-&T`CFGq~hk0{2<0zGGcLeDwGhR+D4VY;u+oxzy~SA-$W{2+z#^9Wx$<5|eW zRaqrOow|v&O1k|FMj{??FV5p_p%eFh;LMD4O>i5rc+eGRZKW9ZEuK|t%csvmTfRg! z-~0+aOP@o*u67*!<8gm^=Dwcp0|I@-HXiDmnh=;eU-Z30Lq~5{TNp(Y)G@ZOOKpY zt+sS2!iK9klH#vVjCKLH}mo=t7Q|4RIW8>L4=WQ_ukYwPK0J1E_b-~tOyCZ$h@p7kik!-%u6 zfh-PdlkN<)OE;f`4e=k&p;}89;Y3kg%{qPUZtxd3nb3vQS-iK_!@ozjA$B1X)GXWp4 z8TMRzk}@0x{Zi5j!Z!X!c>WnGnzlWdG14RFLORMy&meg9gOpj9w0bVqnep>be`*}p zB^S?Q{rDC57Lg13Rr>UKFr*`GM^d`$Jd#o&oy;SA>Qbt~?9)`%#%1qA-#rB1^$$_z z``fw>O3UYQI{Xpd1D8|eu|7oOp8X(d0dbKQgh0BdLAP3?uS4+iA6W&m(qLGqp`^v| z!TtL?aQL7dif%gWLx)PG2N8L^!03UdVKG6=QUBln8|w5V!WMq}Z!{wgq|?$`m@@3wz~{5%7^a2xV#7P_n9 zcT`r4{_{I>9ql-OD1GdFHrPIUer-VAc|NTTwFcgUnKL~>`If&!&*AH-j(j)_p3mzi z-F$v6!R<(}z@n~wn-Xl?K+okH={f$bJf3UcC&o~(WP0HInlkArN`Dv4?v=m3AMtRc z9Q!n}*L&uCNCO?x=iZ52{)SL&yZ1|%zcX1q1pJqGcCekS3Eb*k2tHi}05s z`#QQhda%yoR8+@494eM3F5KTqr&Vbqc+-VKcACBr6@B{sG9-}wF!^`x=}dRx^w(7p zkl^X}qh14>^eip0^7-ugT%4gQXvZ9}=WBw)fTtVnoTJmM- zo(qVe{QZx}YvNB8s@{7+m8z}MWAEBVR-WP$7j7ph_aCa!m3w?%5SOFT3u_Jd8mPVS z6jg2uxp~C$yV%+}fH*UMrY5be(zEb5J&S*!=g1%FIaH$OD(jdb3=GV7_ALEj`%t?B zNAWAif=bADcAa9>%=L2@f)Non{a_T`@zAlDnpfd%;~^F;3k73uR=P4O*0HZ3XqAHS z8I7;VUPIM&$Di1cwXjo^4MU5VnWC(ltLz)s^)a_)==PvIt?2f&Vi+s3;Wu@2UDj>? z=nlN~$+|kTBdE_RmKlvDyt+0Z$1+AFqN<@JGSu+Z4a11e%6N^YHHSc2qpx2N*yf_k z9Fq-GOx>*$bVI~0zo@ftAmi zuuL8@*u>l=WkIIkf^3!D5p_agzGE^l{wh)Hg3N-e9u2t$P{fcZZb4ad4=76_b$uS| za(^|QW#>_kNHzb_9lV@^JMIj-^7R!l=iSDz%b&D0!^-0yI^2$`b`(A8@uJ67%`+i; zZF2-g0-(R9NkjjpAxR1smp z%^qc%!!E}giBR)==AzqJ1Fief9gD6}w>R#rp|95D@Q^&;qz)_Z;{A0<-bBYWA(AZ2Uxm8uwGif4~KcuI^8QXG9%VA`4)Jd7>gwFA>LFyw?4K>kF ziLSX!R9(-Z&nONb#GI5wNRUw@@_~ASc${|r7^m9=Dw6V=GcH!mSd|K@ZwncGXjrW^ zJQ{|}ybD#*(xoPCs@a)R=9;ufWL1uZ!9)h+pn*wdSbo*1PW?zM9EtidgI_bW3>C_cE$ zOr!n_vYt$4l5?^)FJl;n1A|H)Z*m}Srsm~vU|2CynPCMrjVIK8*+E8qa+Zh~}gkg)6HuXGeu?AcbLPdOk~ETjmjW)sR{IT75us;e4{ zFKV`R(9O8j0mT`1+ce%*Ts}Tu%>{WCtV=himHOE+zH^($!qJxhS*P=JO*u^mS=j8T zjs5ZtFye>?UbaLmuFo}!?}mHJv>pRvW|Mf>J*c4H*!w#13O1pWny-Lqj!8c39wx86 z1={I08pX!oh~k9SUSQba1QsLH7zc++(0VZ=hhwH;^RZwuwrRz@me*U5V_E^6blPRm zqHBcH(WrMy&Sn!%FcA#q5@4#TCpas|Id9Z-(^r&3s((bT8%vIw@n~Q`rlXhHkm{Gs z%4nM3Nu$YDBYs^A<|-9*W-)(!1InO?E{5LXVP;@dG4tc#n(5rAJc^pn$jPGIk5_b< zu9`Vk`|8LKRHqRQ`+z~yqFTsk6UM1#QYYgDA++}Cs+c!4OKQ_l%o$3*q-ym1fcBcE~L0ONL z+ zd7#OdmlKi5baTHFFv7#2a>#%vVt6$#T)$s8@n`6e-29q7E$dO;7?t&4TFa`mbf|`9 zkAbB5IV^r52Q0{(SE2|pLUXd7!+S_IvDQRlnRIGU_Lu|moGTL!j{p@B=mkAN ztCBmeqli>;UJfo}{=|w(HnE{3Nsx$-$=+Ex5*U^9W^7y;Qp$3vXqW39NO-`_=6qO)N+n{X+ z9cM-{R+Q+998FMFv%ljd0ZaDzc~=?+1nHwl9!w86?q;7t3k~B71^d7=RjoL<|C2vg!JeS zdP90V1im^53Pf}pc?Jy2avURO`OP7k;sirY@O}2qBQko|ki&_@;4O!L5Jm<~?6U9*s1aszVNN%f&iLX?O_g&60-#D{O#2>Y?q z!K&_c(peRQ$pfjkPqDMn1jvvp$dMt)JRXAxY8o-xg@w(irh%c)%E5JcU7mMOy7LRo zhPvtYCv??u0ufB$g=Pqee*a*T&#)~csbi?x(Wqh2md(&fJb>Wg^^@EY3#oCwT>_0g zSlA)NGj7fvB2pPs-#6hZDE&LsGS=tXCW3Z1d2CR?hQWQg8!ci}lhnW?hh3}gWST=? zKZIrQSuC_{7PEWIL@RT8j<7@$+=t0e8d#44>3s|lExv4($6W~uoyuf}5NgBX@r3mSs>glva{=#V6; z83V(K>S|nd%w#C;1d$my&vvoEo@^;AB^jGoM#hqC#S)nyHt6K*hc-lqLS#g-V`as_ zQl~@$hz$N|s}@mC5YCDQ43M;Q4|Ah9UVbG;g{chjF=h*sFr3wwY9Qb+@{E+&ux7*pF5?`Ltb>lionU*u+rO$CYu# zwsk$|1WesXU}n$)d1Uq=$= z>++IIwe&=K-KCCTwO$74nfMon_!l0Ly->H5uv(4CSgB(fycgu0cfM)JttU)lrDf^E=cARD8rNyyzNIDuMnw*n^$|R2II4rNQon>fA&Sm?-DuTp{?RrLR?A{Ibj&*@l zI%&&Z-vJqDPKHnx*~$R1EHgP`n`9INt2~tXth%`X4Xur%y0IdV?grDgPHn-M)Liqt zyDa$PESOcnRd89Pd;%-Ap;O8*83z(F7e{4+5%L?CZq7)667&Ez1P$wKMirFGO#6WNcEh^g!cf9K4GO=`}L)F?*ih|GDBA2W;1 zb*nnp5i72yiF<)@@fq(VF^)-e1V19_(E#5uj7+k+Y(!$J2XjwRy?!G=Ow$q!oy#V4Q4BN8KFdx)IYIwWYzE)7I_5HFT+p`+H)V$8AvqVGa!tD+ zMf59>zEDly{bQVt_1T=^SsGbonzrwoZf~j|RLM8zXp1#@4zh`@PtRSw4Tj_F{x! zGq5C2$|>9OMX_IxKo1pOkvE_=!p?O@>EjiAUWHoDTr)Iy8?JC+M@oe#<;fRhZJ2aR zkbC_`aQB$9+jhbrlTd30<9G$RRFB0<8Vhp+KlEzNG(lV?xPEloj)9udw5X>~KVYwcKL z&4_9`JS}O@Xj4s=39i=@`r16#}+AW4*MM}#yNP3tIyRjOTczuR#|nEm~GhGBg{fGm4cwAk=XTZJtd43Am z^E|&#goIl5U{CC&RD(9V4r)j{D~>{%T>}nk1D>`uK8QuRR8vrT=27Qq)@72=qOr7= z04;QEigiCSoCi0>=7wcn{|-;)U8{i+6A5)ci^yXmmLGMlE0CM8DpjSH*75+$v(bi1 z3$fC(q{yNEL%Ah3Wna+9A%X`<)-PKe5BWQpNLA_Wxl4!6+UY&djMuPn{g|c zP+_1z5jtm2COC7P@hp-BOtU19H*0>cj_Rz}SD{d?f~Y|0kaFe~UIg+-J&83Yb#oRA z12lNWLt?MMP-@0=HELjI<)MDyZQg(^iUE|-Q>Y4dFjke1idL;d9Y;~A&7eoHmed+- zf}O8RDyL4>!jaTzxVWIWIOG z($ILxN?->|%{fp78#IW1WLhmY_^G!ZLN4Px2+WP6*j6o zAwwsO>P|GNW$brX+*1l{1}glqBgzKgfQNvOK$mM7G}faYQdVM_v@|F|c2CMs;p+w{ z6%@N@rgs3fg4jxo$@T=S3ixR7j!STAm1@M<$y<3ANu1*1P7$rc4FP$U2~h4nhz~FfIixVuBbgnrAmge1FsM zP9s%>ZUzL|s!-7S*+!eRQ$z-j20O>RY?3Ovgzcc6)9{C~FjzdRZVyIGl@OSqA=Y%( zb`ZxNZ*+a;(_YW zcjz!w!$+g%IX`Z7T=AO092xVdCMNX6CX9dPtlLajq9R3Dx&x{Q%BT?YW--Y#0sAM# zEXx#tA7(Y@0^J6BHYj9j%0gB|tr<4eS7!Q<@eXgH~IMYTBHexbVE&4-@5#tByksFtI~yqe-vAx48^AE56huYB1a2MB$?MSUy@`(!s&}xI0%K78k~`-i=bDFphLnS z6Hbg_+~IEl!i>4F6U^3c*#SEeN(^8=MF!=-n(PeV{7NKHQ2eR583;!fU<#kWf}5~2 zfs#C=;CxrwOe`s3KPGFx(x;$!tP>WFUc_}H2+GHBbsDu&C7{-Q6 z_d@Gy8CVEaV@(-%>qdOJ3CfqanqQIE6l-xO9!oo|MP*vn2bI{cQfP)el^8uLfjs)< z83pIrMr3^s0~iOoAdTU{P!VzltaO%BcJ0<8WCr9`Kss1NTbVIo(Ral8IMwH7`~xF_ zxHrC}p`y14mZm&jm<1oRfS3rk){nr%#RM}l=1lFxeAZ@^MF>sUn&X@Y)DWp^G1CgE zgy=lRpn{_W_JRvKJd>Yz!V~;@hF2C9+)}@ytcu(zZ)9AbrCG^L8wXKWNc@A^D+rTR zFr+4+7ogpz$24;h%pEJ3Vr&81$+|5pX=|}CCraW(3nCA?M7(G`#?nPY!MbyO{AiyS z9Up|g9P0-=)ED)KX60dQtotFfK=NQ&*qEY2u9&9T;aWT_ZYoY8amGZmkhEDAvI?qJ z+`x92oz+8~96jI!pm)QmJ=K#yzN|ITSSX5x8gc|Ca^;j^CHEMq`}oPiAhQy39*-l6 zmKGFeEsWGZo|gd|v1kFEBl^edWI#w}BwLbMU)A+cB%0&2f=V8v+KOZ+lyKUCv}CR; zFf>m>n~1p(js(2vU~txz&;k?6Xj4I%m*cBgpR>>+Ls757*bt^uT7Iiyv4oLd9MK}G zLCCXAkR3b{W4y&52!$(c96%wQ`p`57``Z z_sq1gP~KTlFNTX6#ocXFlSlcmi$}aRY6^>% zFXG2OElR@}GI1133^S629o{I2OPaByAQxm4j5>8>0;PCvULuwm39v4#n^l-CkO>)$ z;}H}WiSokGUwq!M0t0F=jxmm6D`lEENXw?r^DX)Rg)*0A8a7)ALaQ?)MYf)|)KQ^2 z!8xC(3>)6q|FexSj0sFQUdLw}+xCWNz_SLzO5|WXg1b-4`G^xz)7Zzrbby8I*{k^+ zEdvLvu(+uI`4Pj>7g2d98Vg2i)k6hvWQ{FPM-?JLSK*JMcG zY+eiHFHXLZOioMVkTTq)>7;mvZl{EU&iyWOH3Su)=hpD#-x=A=ZO9SWj<8vWt$-cD zwQ<~*oxQCby^Z2TJ`R51h@L~N4crJK#t@Q1oQTA+!A4R#V2Xs|ur5+S=8P5 zAHNw?aA-Dc&bWD-*m-1KjYa940hCT$(11PPQEgb$Ay+~mwqPm4kpNHz@(T3or2HI_ z%ZHn&muW#wf+ic)mk3r{jeJ6R*t87q-|a1&H9?K5e*^)zLliMU3R=%9W2$})n{?;$ zem_k-$4}OpSy*~es~MbPqm_No1v_=Hx}fQGtC<%EgW2h79L7cq<1p9_xv}&()%DA- zg1n%_oQ(C@YlAMduK0bleyDb^9|e)+6B?;i1qm^_YU?@{EZA1DQbCa5xv-3|G+||; zWr#9id7yp&*OFu9K&6PEn#o{E4o4$?S_mT1I0-Zsn9YA)Im6g=#m%H0MiVDs!-6@B z9sa}VFlZle{xy>(19QZ-NY3O7HJO$DI49_j!mvZd2R0yc^vMfN&`w}9T2@g`j6)8_ z-Zh_&!6wGkUJmR)4yGISAUHaQ4`<;}^k8v^t_MPR#8H3-BsU2MiAjWHv=pdln3FNA-80w!umOhy#?6*Ld$Ur;_u zM*G67eL*#h!^V0Jr!YwlgBcX(U=5sDUQ>ec1Wh4mFwkx2vHC6&om1@_oNdLdsS;Pv zmXQ_3GICZ)$tWqP*Mz)@T6K9xtMztjwSJZwI~G-S274axc@5k3VHfVnK${fRlG^wV zF33fok+%9})yN6kBq{@W4hwET$7B~uyAg$sok0~J#Tmh!TWoYou$Hk?(<87I!Lnve zLepK4EoM_%az~?l^K?dubn$(G$_$%U6;Iu%zjM9~>k>v?&yqASTZoww0!zE< z+sI7Als*3V02bJKDH`b94PfL#qh3B>?T zK$=_b(-=4`j6ERvoAqXN?oYRGa8{uH)Fdt|h{!DY?AsrW7}c6RTY_V1-t>%&+)p; z^ka|C0hAZHjh(s={LtR!U2+HNy^6}%G3M$^p?g}~8O9|OJz~dkm6Ii^7B;F(_#wDO z;&D4@F1~oX00+JV`K>B~)dyoCs}u2XYy(3Pyb#-R;`+3B(yD^Jq-r@Eu%v)L(t}A0FueCV&a>?Vu67&gOjzRZs-m14h1`I zGvVe^B%+z)j0yX2u)$nyQdzv=x_F3%C`C34-`u;R48=ZT?pw&Qzaf0)0InL(CT^2B<6F|vOEh*s5b7x?gg8d zWhnIdsHG=pP@%%SYj|gR5c?%DU|~+60b2))15=7o312;qh4TSDu4y@(L@Byd zI-ab02BGI$#nGwSkRLvRt`W|`rpO}Xuq+_1$#sx*@dkI({N*#T-uq|}pLLsecE@yc zCJ=D)u#s*z(GH1)akzG}8tjF0t@74m92+eaZ_ed88Wh)VIcws6YhaleYLmnT#hDl$ zjOU`F&fsd8X|?c_bY*vloyFE*{_BSvSx^S#6&XkK=y=`$rbkJp!$>(bBm5{DzS~QNTw-@J?coNsxX5}f@ zl&dJuD-j4YFu^YOVT$UBR&Ucv&>w+lO|CM!6&D-_N_PU1EKH8G4+ zxcTAcJPxKaBU{>zE#lT)3Fp>9GkZc&=M>GO_A7%;3%km@rgmAQuE4mA|7g@U!!T13 zPf^jMLAtNugP4lxp$$R0m~G1UyS%wY*&b11c3COOcDxJ~R!Pp4 zDRFZhCo3otl<8bIk6Q?Q&IM_26(nK9f<7byMMnZBeQ2=Q%Q7W_Vr7Tg@ABFB84J^I zK_#?;Fk{qT`02f}0&>#XueGG}z{# zi*jLpu#u1%s;&zPbf7qewu6aianl}EAZ}5%mPV-@GSQ%XDuHWebRrf!RW~Sw^ICMT z!|=vnoMuO95P3lcLxG)_3>YX&8&?vMunF2mVQWD`Nc$Tu%eE(7OK#BA%oUUnlxjM2w({V1)&aDXgj!il2H0?M|-B&~fA@npG#W*6h!W z!8VL$Auo&$jo2{$pa6qy6@sv-1>k8e?u3jB5!VazD*R0?5{JDy%0*kD)FewPQ%+*_ zsryj@p{iioY*JsLN0?y|KTHDBL5fYF(@C|Be&^N!a6GQ_fTEKN!lZPF;V2msgK^BB z!K!@8WMI}Su(s`r%*tU0OK5!!Z5vDbvt&xS)>kZL{=Hf~Yx24}J!_RfIa?z!*VZr_ zaFaC?iTL0N(qcuaydWe@U|z*f$>iw{EH0{I{NvIye&$8rKwsjNQ9yN4S^#%?$VhH) zHalzBv_;HBUM=hlIb%w2q*;dsVn7+g7Hvgwa4hwOxQawG9zt;uV`BAEWXWYmbXH>758ZLZh~RFl8tcPB1>C;D0Rx-_TW4oVV$op*8f<+{fiyCR5~dXh zgq7@vWzg*MrcA3nI2-;oO&_1{~ZgQ6a$5 zg%POSiCy{evp8WhVFz&u#DqZyF)STll!8ACx7ajjexXsrgF4Vl0|3^~g_e9+*Ebbd zY-U~+KnLJwVl3~P?88oe-QDkwj4Oe}46e;Wy@&G)n=LV{G?TmL6<;E}wqpQtE+;UK zW3rAg?XV_}R$xV~jL7<-Nq%6*dAM7TR%{++gu{ulYgCD3HLKtbk_D#djyQ3j7Fcno z@oPc2+?KZnl|Fg+SZDq42{|)@>sr8cm0%fV=mBk70X1%c?ElD6^A%SWti*&WU_PYRqPKk2vyTIcr4E0rZu8|BnE~7Us_;|40|EM zs~WCg;Syc-29^=m{rEwPAg;WcHod|wME`K~*`V{fCS+c$WdR&6g-xDT@A@lHN%SYy zzc9wLAG}u_E`WrCrh)lmZg4}qIG{4F6q``tc;3MQLD*o-Is+EW;t^FCv0_o&G{sa( z(vQi2Ra-*N<5R*=?E-Y~*veaeN2P_4*?(|Y7sm{+@L^t&F$Zj^V#g6~q+-Px#?qbV zQOMR4@C9kloEvGLbo++fgRWvrVgT2D=fHmg;USlS8HW|7j%v6`GuRaFYx3K;E*}VR zje>6HD=#>$Z0k0E@*8?4Zdie~=mHPBOXlDREAxS86jX%@8{^35A8~2eyvR5LVMk^l zAYsGrBZ-lD^fe_6AI`hw^l}VH}E<)h*~+oXBqx*5ogTn|Iy^28*;e&WTGK9 zyCHbUk4wZdRt&e5WAie!02nqVey(W7olXrw>*+Fl=1LPpUkqP#E7f=a7Mcz0y36k2 z=011HJuVOKoK~js+Z}z)g(jaxhcyixTcb$~)|!X%QPYNGAAXSq-L=v*jtjgda6#bX-^|mG3VfcxD*_)BxW(kM50jG8c+W& zh6_?c;I9f?6!=dfzGU(EZ^m!v61|E7e^cN|f&U!0iIh3Op~c1Uk^?VSx>Sl_0NwOyIW&Y=bWJ$pRmN z@tPF)^DMj|O$*$77B8RvPY(KM3`^4P0E5y+BHRr+(C2Fc`vqPQI3e(x&gS{`3;ce8 zx_J(-;%(*;%LEu4w?-bY*=HV^p z@c2c6a{`wI9uhe84j%u0ffE8hA#k6-UX(-Qaa7O+&#PfK3 z{hd61MBuEz9}sv};9CV=68O)+RQ{^K$DtjBtq9NWJpvC2{CR}-~oY8MZH=51-?w+@c-cH?-4jHa9Q9% zfhE+N(oYHeI)OI?{uhDG7|-uEffEA%MqulI@^Ba0LHQ*GJ_DG>yXU<;{9+Mq3p^;o zQvxrD@Vvk;K)WcvlE7yP?2YsM^1zh8A@H~e4-5RDzzKn6w2Sgf3;YIw2L$dAcv9e^ zz`OsMm*+vdDSbfTh`@P)M+6=h_Sf65$^dHp5H6p!}G(>!?VvP1RfIj9)TAH z-T}H&`R)XduM2DloD+CZ;I9ijF7RK0sXmhepAEWFev1PCyTG0{iG98ya7f@^3!D@9 zc+iQ`4+#8E0GY1in>Zcao=<6Fl52a6n*P;F!QM zfqMlW6!_!7RR1Y~?-qDj;F~~43O73>_PGM>qWbj<`~!h!1#U(?Dcrl4$3F*{(uW1U zM}!Xv{G`fztwi1TMuN5%}eu98U_2{~3mbFAMy%z%6j;6Z~I1+$ZqW0!IXXMBt>r`b9kc zfWY`~vUvFde@fsffqyCRyuc@>dHi*OQv&-@4t>5Xa8BTd1RfCh`2C!IBLas7E(v@k zFwtW};JXF(pdR$u6xb`U-Noal1^$`91%XrDyu1a0kIwM;8tO%#w7{0Y-vFlmj|;r# zUpXEVcv0YKf%P7dzra5eSVKMO^UYo!J}vN{fT?{Yf&E#IE!3Mn?-e*C@PNQ^fo~Ex zC2;5fPd^~=l>*NQyddzRz{=ho#^vB zf%5{Nd60)M2|O&Y3cAtfVS&Q}zwmuLe!sx)6nIwP4+y+2@T9AfijyD9p5txlf(1AXG6F4hy>_a?!S>Q2X%C98w6C&IVI??Bp4~zT+ zeviO8f%^p>6ZkHHrv?6-z*>Q2Cz<^`KTF^?fkOgc2~72g3cTYZJbp^x-vCqilE4pK z!NXSt9=nob?*}FJkq04J|9n7tmAo_=bgQcd0%-vK7~{8jZ4(e!(DRZ7Q6-fnCGRvUG;(T zK>QC*$Bj#s*W*RYbbKH4JhZo~bLAKui)-;*9BiJ4_V&<+^zl5Lj!TVOpN}|ix%v%w z!3yQ!=6P#xzZ=`vXAEAKCuif=Rx*#fd?W{%=efPD#?g4fD&-ltbG}^Y&T+ka9($YD ziM^f1QTXQ7noq%taUSmQvGQU(9VeRCmA!4onfN>|#ZP~tdHXuFw;ymbjww(cVqTZ_ zwhO1>OE?GLwnqIz{4_4Xhp>-%UEABgI1=~!RP!l#ERHv?YkQlCbMOURj<5er^Nn~a zc9_?-y?uz&@pfE*&)`aYO`-NV&Fk9UzQl$2CtQcGT&upXd0pGv?Kl*#!Lj%tF2{f1 zM%?pr?MpDPb9)<%)9_eaj8kwe-hxZa>)hVX;6n2{x3};w^m-^UuWNgI$k@Ifs_{qU zF7rCEw{OYo@xUVWv(4+o-b##HzrNv9&D(Ha5Qeg+2(a*Z$s9ppJ!ed z_BJ2KnCG#*xp07a-r8H(di68R^UB^f;U@FA+FM|;@?`V4+1o=n%UpMRn}^HsYV2vQ zo4swqVfY|Uz(c>%eqVFH?XAMtUXMuJOdgM8zg9mNpTL#aZ-a8DxgYj6AA6fU_SUzA zuV>h4Y#+Zk{4LJLPi|D+V2)#NTX3n_Yj4+oqde2h+1pIqWd7IQ{=&(d_IL$& zBlg*%e0HhM&xsEj+kP@$wpq^Ks{R$`|8Mh{ZF07;y?$wUCwU(3ZRTvh1{dM9?V7*7 zOu5Gn`EeYIcjIF0W%k&8^*9-4@6>!dv$ys6jRzasz6&qH{=3xgZT8qa8c)P^70Rn{ z)LuEKT>Eoyy|JAy#6{*f*0q)D_b_{{Gxp0XjqUlB;Qiz^xZk(x`y5dJOB{hu;j${_ zkDK$f`-2Y2eRgYq3Z7zY^GqDNM=q^ae>qM#A`dY4!=7Ibo@i|6OYjEVh$GGYw0Xc$ z%}>WAHS$JW{=NJ+uKGb9yifD>wenJ&{iEF5T$k3z6OT5w$8+I)?EjPc!R9*IJQ_cN zbL*7nVDF#hYV7Bd|Hh5@33Hw8zNAyk<9zISP~Kwuj*$T+v|~wza=llH<`!P_M7n6IPf>kH)6lv+F}C-w1Xq&R;9&E-wEKMiR(~^&z|Gk8kMd`atDn^( zUof`&%W#l+-r9Y2crNz)SN$I5d2911Jl5^Y%0I*T_&lz|chzY=wT(Hbxvjy?_;(!K zR(Zk+^|L+YTTkkIU3j*!J)dSAZC*FlL07214p(=Ohnm-oy}zDb^7F>FABeZ&I2?6K zc_yBYYdUH^2YYss>u{d8>}g(Cc7Fx#Yiy4n+*x@tj>n(SPshh_5pKpV>@=@KyWeS- zn%gp*jXTvV_vxbiAsmTQa6DdtGx4{$2shw*+}*s6?V-Ybw12p%uElGy z-_@GmgQM_y9EYzlUnlJT1Uww4;Z?W@AI9bQTJv?q&IfnZ@nVhb`A6UkawlGo6S2d5 z9kTQO*Jyql4#h!#C{M(za4sHlMtQie=D)zDxCIAxQ$Eam9kb^bhF>?f$9LdjoQO~3 z6uiWI-Lw5leE&H)qr3K>#zd7T z@L25MQ~8_5_Ws4;P2{P#5$EBk3)<(xc{u1=?Q6t^IKX_Jw8wA2k7A$e)L)IW@nKwz zJDRVfcD@;p!QTFwPs4$D7mmZ1a1IV>*1l@|1opgM`*vb~-2bBb4qT0k@IB`1x;;OC z`$I?O_Nv=A$cJzS?s!T4i~!}s-M&%YVr(Cevfgr-c^|O*t8o#o#{q54cJBUSqpI5?>UTHqBX&L%FThdw zGLFR~&HIc!pG=%&Z0Egh*1nTC6t``s+=+YROgsXY<3!woPvW5d+V3#$TlRRd_#iI8 z54KlcffI2xUXQ&7Xx~3L9N%T$2kri3oP_gn1_C*wSP z64&Br^FC{jUq3?gN!WL!{3DLTcbfNAd;YPJ%AYf~^M!Z?uEI6A1Jki+R-)j63uEX5|m1j=UzRkvVe=Y9NS9uFg#C|WR?|YN-dORQ3yr}#% z4o#E?_ESFz&%!nMJ7atNI()r(AGGK1F>lGzG&xb@as5jrSb+G`>C8~-sfyT9Xsxm zi}7aMhzRz-!r@z#e}}!wXX@%=Zn}f#sSXhs`f)ZoS?g8{2sYuE)7} z=%bo1!tda6T#c)+ulc^j?hE}^`yVm3$B)8UvvCsktkAw6jP3p; ze5FG!#Sa+U`6@gIyRiMf$mWgsSM0Z2`$tbu?!;f=bX<)aaKK~ghwagPDlWhkxDNN9 zsJ`!B^(W&PT!hnb*Escy@iVv)@5Qc4?Ys4HuKzyyeVn*oK8*`-$P?OMil4(t2h^{^ zIoR(>`gk5ru2R1U7vfXczN2KMjvHw*5T371!dMrz)>MqxmH`pNPZpBAkso|4;phf7Soe_$u>%CgEoCEF7Prej)aHO|He`aOP$0 zTaO#tv~9g!9bZ@9(N^w_lkk3=hx<%d-|4CT2RN{^JT_H%Ebcr*PRDa`89s&muF`z+ z8|tUwW@CH*Gw`c3l^5W1IMPS+3)7T0UM)|0Q}YpB<&)Tnd(Bcm8GnhhaK>!qE_`*m z9Pg`rD{vWJ_?C|6(@pu!bJP#SA7dvDoU6R0yZSvcxV~WDG$Rtjcs0iv-(%Or@RRd!T$Y~&%hCQ5B3gLei=J)&_eA?#t-5&JQL^P z9oYL8?ekuw^J^R=_cOL%?|ee!vE)&=%de29;|;hpRCzP~^gHD1vb8@SkHSqj6-S1t z?_8{Y$er>F@5>qZXIzb!E#Z9cQvZ7#jxXQ@e1DGiHQ~q)G#@rp^S(=!$KzGF1fRl{ zIBuEd{lhiiKUa>z7me-XpNda>DCgtD%hfNzpRACZ@N0Rp*WKDbVx=5{7vebV!by1K zN9yO}<+udb<2ro%Dvpn*8Qb&s9;V~}f#Yy$zVc#x347e5e#&a)G59jh$AdpsUWuQ> zP56|teLhA+Xy4bL$gy~4f#wUabB*#Ad=~o**Zi0i25m6e=&mUDwK< zBebvG=W;1tVQkOWg}Z$rCy!J=7MJ5ixCT!w;{5TaI3!Z@mvAJ$^Gh8+2X|km`9j=& zz4B)Kim^RE?|ZfH?qWF#xBp7c!P&SH_xW1;8gLT!yifb;jO~6ue8UDg8b6J5@M>Iz z|HGd5YoGbd5k3C+C7gu!;(UC~M)m7(8TO6RzRBMx55@1{GQ1hL;0EmbpyvHIX+8#z z!3m?3PdB!&mmK^NuD}CJl}ARaZ$3r1_5L|<0eJ>KgiG)8OgTJv8T+v^>L1GdPq zW0cRr>G%XL#>2L%@4|W5H%9aS;YfT(nffvKJzS0Ju-914-@8ryX#5@a9H+bmhvHG& z)py_`T!|O_A23mV6er+$xEy!fseX-9{YBX8 zDY*hC<8Hguuftlt9(#} z_NC$vjP3bEJ*WH#dD`=Gm)+`TljNzm2-o1$7nEPOm*?|~ z@-$=nd``xn;YQr4Qh7k4`r~j0-iTu-EAO^X`}6R##&&-l-i=$PsQ)hxnkx6*uYMM` ze~x13J(84Yu?$c=|#0 zi}5wz$%!fIr{YGu0>{6meBvSXvvD``CSncpG^p?tM~y$GhsM8ryz8-b3!f!9T0-@t*om;9xux$Kf?N z6Ys|jxB(|F)V?T}_UGbcT!hzSzeVbwHn!&*jJuuEd^ElbJMeT|fJ<>R{uL)>YyWk> zXkR+M4`<=cxCUQ!TKxu`fef1l09KPpQ^)qo1PFte>4ZrDn zRN?v9>jUMdjqUR@3J3l!m*Xk83V(n@mTLYCF2j#DXubvih$EJ%pYezC<`wc;oRKG| zo>5+cyPlQn@mlP+QvGI}hNBvFe>3nRV|)J!a0B-FNb|3pQy!12unP}3ue@oM`ak2) z)$*)Al?NBf1DoVHT!l07+zZN!)~f%Vv3+x=5`}kK@Xnt)Qxn#Gzp{?w*N1obF$BV{maSFa{Z1;KY zRlmhk{U}`7p7X^^uaNWbqz;;|#$&zY7JToO>ibk`e~*rGH2xJk@w!gRGw^J0ITuHF z*8WC(%T>xF_i2BrvAsVIyt<2AfJghtr8x9z*=N7z`*xKp@HS)n^`H^oagCgIK>f?c z_IUZY)>nB6-fR9`*3NrYslTYZ9DyhHkhAb_xE#Ocr`&~a>M8pj)V@PF43D^0dE_DG z`8XN3yH0sNcH(Nh9eY-5KEPjn^IIxf|9t;-T!MGw20ZY3^+OJ;zX{iWFL&&v-1`T4 zDt6)mT#HX&*D>`|Z_s?;ak&MDos{PVC{MuUI1hKfQMuR8>c<<~$Ik~Bl84|^xEv?+ z*1Y-s+^yH6Z67)2lso~~;O*G=7v*CD)py|2*ynfUF@2S1WAB^fa{LxHzX-4O`0e`X z{6p~!WBYuI#T|p>0z3%^{-OB_9DGKeaM}Hvq?UM11`t| zgO$hOmvK3+z_EX+Kj;?qv+xESbxC=zfy!%eG4^UvK75e!FkFiha7c*qD!dE({Kx#Q z%DvjRYrVc(aTt!hO?m7U%HP8o_y8`(-EUXlzk~WuVFxb2Ww>pq`r#ebci?hdhCMnd zj~=XkB>ow$e*aMADLv&caUQ;i%khih>Ze|-ejYBwKjJbRd$;=axB>@Ur}^+<%9HRkoPjss z8r;$Rxwm~iMfhueEcU-aUWnsvluK|DZpNv-m5+(gz7qVlvHki}9jJUWxp!aLcewho z*ny*OQa&9g;R84^Ncnl3gY!pdUj-gFQf|gxk#f+@n*RnnaN@nnGjOl_~>enj^t9j`UE_a`3@jFlrsYrYOA;h~R`k5~Q%PR5_%T-;-v z`cV_q|Jv9-zf*8Cc@7>oUj1Tx0lV-phw}J1?Ryu;KF;~#z$fHeC#YZeq&y3!I^{z+ z=4rX_W9lcz%QJBm-i5uNRese(^$VVp7vP-d<<4=+GZN&fxEg_QSO}^r3ifQ;`8RPYuE35IcrPh;y({;5S^IsnaTf4c}%u^->Y&i{vL-eRzBr_^q0ujq{#6(@^a(W zuXnirYsz!*=Qtlf|GM(*4>aFyx?G1BV2@ zvyE-P0{56HSL4k%El=|wr)l1WZ+TOF&y~t|;sE^lEaiD0DSv9VoV7~+8`t95>B^Jy zm0$f9{g34@aN#HN?Q?WKWw^xH-k&-=c&^-l595Ra%|~S@&&6}F=Njc@#`f{^#!ckG zc<9@jkHIhC47>xUf2Msw^VBcK^RWw`$L81UwmyHyzoUL6F2%{XXQuM(wd%ixt8gRs z`&@bQeDyOn$aT0Fk6NI-0WZX1CF<|QIk*{D;Fxzc@3~R^$v70x!|`}6&caPNe3Rzy z$kM)8JQb(m4{#mcf;~$$Kjb~l2jNF?DSiW|ZdQLOuE5{ofGx@|;}{&gQ2SHy1YC?u zu?wHY&3N!4%{#Yhf0D6%z9r+;V&8Ojq za3)@l%kWL_tM9i>`^V!D{5g)tKjBpDvqbaRcntR4u6@PE_IwlZaq>*;pQCy29qLcS znRqFV+Nt~;PR0X2;Q06jT!vTU2K+tt-lcurmufx?k1@9An~s;^M!XkCeyjO^a1Oq0 znf4Xo$vB}x{pGk8cgs~jX1DU0xCpPr4frSy*`xmLA8I}ePr}uB1@_yk{x)|X|Arg! znC04+P|5k=27D5G>{C8$h5Fw39UOyeu7{d%5+?cej*ukY~(lpis+*S{F| zSt&PEDUZX!2jw?#G+u|3a0AZ6H-Dt#mEw1C^mp3VWtH-59F7a{6UO%Zs_;_sq(ho- z#wGZneC-RVR{kDNz&mh0zJTj+z-rC=9M=3S?0G~!X>89Y77zbe&OE9-6IbAJV|%@8 z@t-)lM*W_jXx@RNjcq>#FT%z67>@Zt^A~U$_AAhQDIS6A@CsaUO!HT*QQxyxeji8S z@t-R9IH7zO&cLsIro062!vQDNf3#3}GX4TL;Vaj2e3$w)IP#Rd;B)0ZzsYxgAxGfz zI0=^(DbN00{f=Mi`c~qBxDHP=w%0qPLH$p#1E0sKIB=c%xi}Hm;jggc5AEx^Uj39a z@*B7q|B74i0yuO8}W8r#=T5WaGk9FAw=DEt>L#EIXk@8hR^Cvh5fR48}h{kX8F z`a^dsuf#tY+po_#*D8N$kMbH^k7KV>{?15ZNI34#sq`VS;jKc@0-?dtK0-k~M@L^nwhaOfxZJ_2Wa1m~QMCThlNO_pC zz21rV2+qYmN0k?ZsDBHt#CvfIeyT?O;9J#Sjw|p<9CDlT0pIIaD);(uwUNBy^PC@#hk*y{xM2Rn@I{vy1Jyb9OjpyAs8@JY?b;H5Yjd;hFFc!c`5 z;duN!F2Py260gHG_%!w!seOH2+V78-;Yi%&l=4(O8&~2I?85)y&`9kc`-|ptaSl$o zU-@qAHA=qywED%-@?K+mJv~Ru|KLD8qF((lyc{RtA-^gw$5U~^Snc}{$37x|`Bzo!7t&^IOS(>-Q)6-bGm;aPsk^X?fr|vW6sNoxEY5(ss6)%D$l{2v7b|U z3y#Jko77Lj@i-Ol$N9MX1@$X%22OiQ`#;Ae_-E|>v~usiG#`Km;$Zv?j>9W)67KOg z_Yc2=tMFwU@QjWZ+N^#!ejR7xeYgqxUR1y8InCdT(wuA0Dq4l+QA@k5?qF zz-hS4CFTB!>VJxp@Gm%iit>mS^~>-a+=BPvoFw&q|FwPd`)Kg!R-2!XdRh7NI23=3 z6Yv>akL}NG*!$z3tob`y?couFUm&kYQT_#P!c92gHRa)#wXYs8z#*?I--%G#~PY{5-D3TX6PFkr{KZu zG@p;%zaOXycTUsiPkPPLKKJk2io&lmABWw)k24j!e}88IcK`lPkJ;Mi{(YTE*!}xD z%dq?Rb^4^M@BV$Af!O`~6vD9k_anw)_wQ3k!0zXNB6k1&pET_Le9Jt%mHX%amX6=a zvt8@^N$eas*4RGZ67VvdicjIX4D}yruYT0qvitKr6LB7SDgFZo&r{$1`JOrWsVj6o zEqE!8dPjYiu|2;yJfMS|gkQv|xCj^EX54}w^y2Zjm&xDFr2!7J6j z@f!7u@GR`YKVz?t)Q|90-yhF0w%0ENyFX7S8E>JVfjzrvJ{ONPw(|w}9bAgf(ywy& zyK6pTmCk3Cv7JxPm+$Ez*WfxFv|9PSewq)*OO5S(8NNhbjoqKG6!o#@-Jh?NjfeEq zd}4v}XN>LpX(M)jeGM*DK9_zTwm)ZQj~~2Nc_psIO}P1U<-@O4KdDHbg9E>mi?IW{ zjP3bkuT$=Re+c+W?slE>Xzc#?c79(gAKsdqKTpQb8r$=Y{YLp>9JfjSiheGxAg{oG zVBb>pd-&_|D8l`5BfcN|Z&p7Z$K%;J3x9~q@d4b3&tU&8+UIq>jvs}4Vr``(p6| z+>8sbf4Sy=!cIK6x8^JHo45h*!OoqU@771xCmBDC%W$5teLt(lzvFs5C{XiFc(JkV zd+pNx0vw9>-~`;MuljlTL0s{z=AXum*!}&IZ-w$w@+>^~Chc?VR$hqX_sIVJlo#Se zT#t`p=U(-Lg4EB!Nw^x9V9!eR2i>ge5wlM|iSzON{>mHiPuO$6`cVUPJU_e;N8(1D ziKBznk3FFI4{-|q3pe74x9Irc2i0%ES$Oe4>~}=@L7ax8Z`JYgzgO=5eX71c$Um9fo^L#Edz<>+ z$CL-*D4dC_epcRSZ0Ezz$iBC0-i4>&mUGH0aN=L`&`|XwF3O2G8GnsaJG5{8`<{!q zrK{||ekDC+_kWLgT`NZp)_#9H35VkaI1X>Zh1mUmSB6iL2VAH9jkp|NGepO0#CKqS zfAwQ<0e1iQLdf;XpC`}8Z{jkXYux($!dr2EFU|iME@LKE|to$5~7$Uo$Px09OdMw7>@6!2r-=Y3coQmC#rwh++ z&CTD>+@-#IUre~Xg1i9lU|-4I%H7Yu;9>HQ^fR&hc%Bi;+YGhm=i!ln`(v-+${)ZP z_!;cNGg@taf7uB2SCi*s_kaH#+{;W|IRd*zWh3Mb$^{AR1o z=Lg@X{zv4l`{fxi~6TUW1+E zXoLi))^c@3}|&W1R9_ z<6dpd=hHtce~Nu3$yM|VanA_NS0yTc0k=$*x8k6e$duimpXS8w&qvF}?$1Xn#qQ5X^PaEySdJHm z6LB(jf4)#Yc7MK5zyi%Lq92OgpC=TL-Jd5^hqtueAM^X*aNCi(zd>2rHy(#Al;>e5 z{?yoB&oo>{UWn^)Gwv3te)b~mbN}~S86H61fX5iy=VLQY#R1uxcYlAIj@{qiR$=$| zuP*HV{<0b8voCqE_Km++$E(2Z@8^8qSML6PE(o{1PyKMb3TNT}|9%U*zn^Nr?yuh- zOSC`yeqEm!JPs%0WSo+t{z7AWeL|MWMdXS2J6wdDaapeVy`pryst@Hz?7Li^g0pds zJ71yvE9}5Wa2Ea>SK#X((DA(UG=D#i!qZx9{`>=H7~A_-zEb@{oSrX#gKO~#ocpnI z_xn);?((4aMSr3^*w{XQ1J=mT<4C-ke)>A)?)R^R^|Jf>v5*q^5dAdl{_~P-e33kF zqxu6z>3q^kW%u_}zMJKHOm5FF0;k}3oP%@l2JGCT`M=yb?jEhpgMya4aSe%q8E$HhD3E~9n4nsWJmoVinWVxL{|Yq%IM!lBOw8hn&Ib&v8+59$8;?3JB346nn{_=+*=dseC+h6C|4I2MDwLbGyBzF(zjI;t`&~13zkawedj;Qf5SDG4#&&<+zsifS&t-Wp&hogT_0Jpr#QAOHpg7HY zwv)4P5Z;UH@p0_yss4?RYd#j=j*D>$4s5T!`}ys}o5?frN$kQ`KcW48S7`no9DzT_ zN%#o%>Y#qlCpDjh#~Rz`LkgZvo`XNbRk#{^duiV#9Ek@ywZ8xt;TqieDdiDYYJRG* zJ$@A4N1lMMep>xH?Ed@YCLBfHj8m{@NA3RNn#U9D0@VH;nD|h{v6tlS}Z2*uRVVKjRR5+wij&OLo`6r|One!aVE6A63AkSSA4z6EPB*suqw)Ax8YxE%MMuDk{> z!yY$k{zn{)`=qKLfnUMNcn8kF9y8Q0!ozSmo{DR64sOI-uwQST&nX;@+rOdxxwtPb z!jZ=I`j%t&?}zp3qkWIk_s7XN1lxc2Z?AVa{tRc~keSN!@fu@$ye52Cn)1j%9q%>l zz?+O)pD#G}O}P>m;yOHXmhzCk+IJjh;DFgWUJ-s6d)%acI`+jaI1CR<*L)(Lh12kQ zV|%{UIN~k!>+w&tiiPP})?{L1iXx@RtaRGMWW}G=t{c)L^j|q{BvF~m2Z#WWPHDCQ4+z3u|8-}Vs8wZ8UWyY;vPw;Oz5&JAuo`px?in}%c zCib{T{u0Lzm)kGWd?mgchmBC~{_o2;?Ede|LYze3bENvKa58rP`Cc9Vmpn33{kyVt z{DS-BW!Uq6xeh1cfW_)(V<+~EQvX|=h|d_?>s^PtzOVTvd<*t{K=b$G82k)Q#B*>a z&chA38V5Y6eZ7|Gcv;c%!?+y3jWb6p--Ro13vR}D=4fBYL+ablF|p5&e4LJb#wxd; zTVnIvN91pD39iSbvC6$ZP(OH_+!s6W3%DA8gd@hQUyY+3@;RJ>uUe}8IXDd0;W+H~ znC9QWsd4glT!R~MdZ+pie5n1QPs!7;6E88g{X%>MSK}L(YrY~nV&#V6?PQazO4maQ?-0dUn_ejuu3{JuB-)GQ_ z7n4U#Qs4de8+G_+@{kvlU%!g$g=26GUXD|75iY zS*rT);d=ZHj+&wTw6Wcvi2Hu3eQEe%T#9EJ+kP`%io@Q}z6$yo_;*}|yMCtqIWyHC zWo-A=&ywH5E!h3pGVgC&6yY6$HPZE9rm*W?4Bc6r*-`4yG z*n!J&I&Q&5xZf8#UM+qSd(C4X4#su33i}u7`UJkCzQfpl{}6^3;%Hos9k}P0>gVB! zxCAf5b@&hLm#O0oT&MY1JQZi*HMk5nV!!#Ce|Wv-op=FG##Oiq2NbIxwLtT!IQ(7t zh_QXXWa2?z$>mwfla1~5@pw;OjzjP+oP#gneEjg&ny<#`xNxEN{fKMvH5=4VU8MX` z?82GGt*>vqncOd1efzm#_I!h}Z;2d+C*VB1$k^^H#@~`x^QSJ>N8ZQ?>FuoP$g8$ivFxcWXWmSL~HfVE;iQ$PvT14`$x?; zV+RgAto;jc3@*p1*z+gN7vQ^aHBQ1FN3^d92jfQUz#(tBMQSI+^ zLi3?`1a{)ra3(IoCHORU;p39|{!X>yCpTSKyutDfa|cIOZ&V3t$rkq#&I|kXW$FC7!PRHd>wuY zH{+E!@RW|%@uK=MI0C2QS8+Bj#AUeaKbmjA4`9DvwBLU2qJ4cv;?p<@KXgfXE`AGF z;0D};`?RPZa9aE4;b^=Kr{JJ})z8OI;wrogx8Q$qP`&oY|EKv_ycDNlkITvn@eo{t zbFt^I+EEGWgLPFa1`$9slEfx!U=elvHkux8Slfn_&j}&1|9GA_SzSKb8#&0 zbcON^{06SU-{5B4rvv-`(Eh172ye#G_#d2%U-r^`IsOW}aNw27z0YX>tJoLs!C~0_ z^Sn;nxudR6EiS_$XSL7$^Sr6p{qww8_{C0|&&S^0ax-@SJa0s!_PKwaHx{opef#=N zz+F1aS$HPS$LDa|IqkdsD)m$G^SBTn#$|X^7xnA$Rvd7ieLl*Q@bfqWFUPrfKQ6#` zU#)qMKeg|99E#t=33wB(zM%eD?DdyCpsV(UV7Q zpo{9y#ZkBn$Ke*7iv4}HKlmTbKZ;}UMx2a~8r#=nC64MQr(V+hH#oRO4(_h~wKy63 z|Es(l$Keh=)X&C4aWVcMuEw9>dVCoB|EK-e`DtIXM~Bv*j~<0H+sQ?^sl7b9r|wVW z6>_$*eSSOet=Gzhcq*>&QvVoE?kK--o%ZG9Tw}Yh9RGt`@Z0{%gF9({J8tPLx4mAu zR~LB%PU|W!!6CkK1Fq{PKh#U}Sv}+;9MMxgXKWweqU+>dH>mI7FUR9lybHT}DZed1 z{g@l&JY3pG9)F|udk4y27~AU+fS>CvC*!rapr86Z`Y4aRSj6cN@xcval zXW%fLi$B1X_!RaXqT>w=)_gktA1=jT;AVUphu)!izgsjPk0)bCnDR1X`}h>#t^?(| zJC(;^|GVTl#`gIbg4f_$d{6Tl3z5o*E{V2c^-Kw{u(DesQe@@ z!F`5kzhjj0c-)NF;hbpY9(Sl8Hd=P#G`t>H;5K3EM?9qdSe$~ha4|lB8*zs_H6JiW z^G{*l7U?en`9zeb+$u<{%n^oU%9owx$$;M2x-pEFkd-a~b~ zgmLm@+<O~I`SW|UFAq@aY%yl`NsC~i^J<5l#6gZ4x6O@uu?Tbp3uYX8R#m^breMR^pc`fcYMt#Q=%|C|HH~N@C}d1rPw1@uEP7UcarumeN?#vm*Y%)23KI;aq8FN zBe)Uw8m~NXn)W}3Bk>4_@>J|ULC(T|;WE7AG37olY2RBDTrndp%3=uh?^@_6?n;c|SZ42jlOI?R*%{cuD<2 z?807Y+86P%`jNP2vh2X8aS5LGigLdgO2S$2%OKBag>hW-8CXCvXeym8Lvsj`lr)WARFyhIe5XZuh3<{pK={Bk@KYk1yhM z96n3)C3u#xyignJI0}D>bMQr6g~R7+-fO=0O~;Y=8=Q>)!A1D449(Z! zw{a7$#8C^hzuVjD=i&tH^{(#=gddn!n*4<(`Y=r;P3O_ruG{gR%SH`@~@PzxT<*ztC^S12eThAzS-DG`9Pz z@ImamSb6vP>IY#54#$gd6h3Nf_f_IS3pC$^6R_X=+MkWXaiy`HPshLEeC+;wg%bSG zyV~!<3vj^_?cabav1gY0_4r;~mZSb^9Joxr<~{XmvHRagW#%e>oV*d2Vc!px_gSd< zbiCHs-oFOyy-2yoa`h(}+uRqsa1g#dTX`a0WNe>LX}A$*={4_RiD%uBFN&@Zx21ES``nr{ZI{06+4f zj#q_O8r$oYvr_w8$P4k^%a!}&E1zL(&o>Zn!eRI_F2FCW(7f+z%`e4He9YMHOU6C( zb$`Z2RFjAE)Dg>6hS_ zzf|A*bIq?aw&xRq?^`EFVi(TCPpsE`G5!=c;=hdTzJM>Z|M6lu9hV#1^R2|AzLJBA z)c+301ErG~zMj!Rs}jk0Y@A_d6tG_wRRbl&J6i{SM{W{rerFH!A;^eRX);MxBr6H_BHS z+v^{W7k{HXX^Zj`xMr*D{`vCKGC6pY`c*i^*zWV%rhHzh@<`lnv+^Q*6j$RlTa-6r z=Tw#(>^DT$B{dfXWRdxumjJ* znfNen+NFM<9okp(t$cmC>`@`N-6{KG`?>6`j|cu_mmGtg-|Bpl@n<*}|BZ|AkP7uH z@ETmdTgMODtvq0l{1HyUfqRtK?NvSldsoVT<818y{j!bwl)L{uSHyn#=DpgNhR+>n z(|Uj74=DfCX+bSIR2pK@2FCq zg41w0-h&(QH3!uX{7&;vVh1k3+4xUffQNji`Jh9Ze;>!;!^Zah6yXJj9@%K0j2h?d_K90am_#GTnt9?g|?fs9& z3r@&RJmsXEi))PS`4?gTpJk8Z+BXr0;Uzd3A2PPb%Xjx(auxpB*zR}X$4|+QAGLo0 z&ca_~kCVz>IPDjC=r5YD!HbRU@k354?{r#@#IG3J<0s-W@+|x#c@gehuX+D^?VDw6 z=c8~9cH!%ORi5#y`crVkZ*rBfJ-?hkx9EHSss14xjKdnVF9N?~Z1*KJso&-g<=OaQT#8p>{|oA$H@5Q;IOL4x z9r#J(*7N;K{a46K@FMc4zm;EmR`Y52G2DPxW6x&w&){Gj)u{OXgZIMdiZKH2yOT!MqnD-UYXz7LJ<{%m{{*WuoOaz6M4?DenaKQp%TzPM8p`?34q zW2atL|6%ehyb4!h_rI6+^6+Z?`KKmw2OfGs`}6P|oX|%7Q^xju$~-D``i(dZU-6Ij72&6_Pbc+DaSrZrNqrA*M1VrOT~ z$F^u+BhJG9S1CV$ld#{v>eu4&xCN)+=q{Sygj4V(oR7o))4nP^9k;mWagdMpH5=RK zPbvQNvh01e^5GusTb~~eyvEq}Gw~tvQarGY@_IbO*gn5n@Okp&uG&Ant?~@)GPe7R zab7#+p4X_~!BY;#Q?V2OfRpir_UaelYFvtkU7_5CbB*osTkz8zWTb8rE6;}$n7 z_u^-8Kzr>kH*6k15sz#sJ8`vPbAK)#*h;R%>u_iX?fV-i;70@1&&E4&1#Z<^c@usH zN8P4<2XHd3!@2k>F2RrAqJ17*f~_Ii7j~<1H+~71k-va{Y&Jz*!O-IrMD}O z3R1rwKWq5f_aA;2hj&un_x=%1?0f%6wLP%4sWmdDx7TCoUg~X zbda0zIm71lv_)wD)3?d__=I6|z7}r@k%N1wAJUO|{Ip@SUx0fUpNnL=6xSLyKhL8M zU*Adg;$GPQF71C9hv2z50ul#LXj1RD{0sDSmpE*E%-{*_e;WNxPVe@mH%;Q-Hsy`oR;3DkCf8zWo^?To` z`6@gWd+~Z4GD!VeY`a_T+*$K!gXPC@0e&6V;jgj3Rs9>oG#`N<#;G_57vRruJ-)7s z=0on$J{yk4t8oS1k28m;e*rfQm%DV;zEGPy2fIed2e5Obd>NPEKHaz;vC3!Q_)&6! z&!go_I4({e9 zJ}J+^-l_7ZxGGt`h%=v&2lmu_M2frsd#A~t88&}@b5dmwuEAHX+2L0+L;2ki`gv=7 zUQWVMX>vBMpCx~a{b$Sd*pV*Z+DrQq=E!&Bh`I7ioH$Qji<2|teYkYK{6Ac>Kn}l4 z`%7PxXXD~bc`vS9DBsXq{fd|5F*tXTyb0$xNMb@d+IMzWS{OYM%oS!iD$=T!U8|Hg8YV2b!H2UWvO6(R?lb!LHY*G~l)5fgkDkhp`Pu4Ap!(o`8$+5?qJNaqMpG``57f z^+?2#(b|`ZC*d5t)Uesl!=IA}e5`#Q@@U-QUd|6k;gmh2+?MYtB%;#R}7 z&t0ndA%@NQl)dc3C3qeEfPKoZ;%NN*ecG3Xf5m0^ju_>2csUN(uYKR+ARKnT`cZf? zPQ*XpLL4$&{Ytz7d+{;cjQc#Geps1~pN3;`Ax^}<;tJf>rukYNY1q7e0SC0tjuY@o z`i*!CdFVm)tFaCHp8r&Ueb0aLV&C(h0uE{3_xjyX?0fxgF7~~Cw*mWJziTbmyzlk9 zaoG3z-6ZUL{cbV#y?(bD`(D2r^qKbgo<9|ieb1jt$9^ODdf_gH&Ffc#$6&wDwJ(i+ zGCqd0ao9-hE5fhhlrJ>D8|UNSu@|>}Q1by5>JP-hI0f7AJJ^nIkJY>bzl=+;-zfGU z*8V{_3@^Z$xDtDC+tHdYtJJ*j{oNwJm3{A*numSw_tt=Yzu%3nQs4J{g?Q|HKe%K( zoZ~t08eD>F44YrCgzvS__xJi7?ECx~H@<6(&c6UZk3D#oVRN6OTKmqB=i@eUnlHh_ zaRXk7{f=t>TO5w94{1IQFT!cK5l8%>`SxSgPr{>cF`k7h@N2jle}Vmf)IR@*wJ!wE z$1%78XW%E|)vv%VT!)Y0=o;X&jmRH2V9h2#>IFCwtJOVZg=eUEPvu*-2XbwSK%m}^`!C?{J>N> z6JNw`{M1v*tMF0m!9$aE{J`sVyrtNRzs7O6_tWY-@G|Ve-{4Z*>KXN`u@%SPpySOk zY<@lRZ<4>jmAJ>V%DuP_2eeQ>Cq;P@9`u}!SAtg=HuqQJzp)p;J570Pfc6DXmlN?! zoQ6B4DzCs7aO%yPzkh~u7k+u4^ z=03mHnlHl<_~vxw(Rid`b6*ZVgX?hY9OYhLj$?1p{vC5UK7MGP9CfSmS8y!um7zQr ze}fzF4fB-;2WkEh9F5oGWZZx=@U06p@7G52elN<2_%0mSR{45t!?$JX`sCmdhRy3! zj_Yv^-nUSBSUc?-`;r`m|HHYsaFO;02CILaLr%dH4V%Yvf0# zUZv|>fa46Cx4$x6{TbwSxBxfdUvXG>^;@jgzBt^+u(>ZApT$LZOSbZA9RITH-$VOa zzamHD3Y?1PtzjOYHGJ*or>Ev)a+HVQcMO}k8~+d2;(K0IzY#xW*z5;HXkQsF#w}h` z?$=BCI2?s@aT-2m*t{N%IC`z-!|u}jJi})0#5R{)gWWi=xBA^)S009U8#d235C278 zgP&f<`9^Af9gf4Nu>;@zhW6*RtbMlrntu}K7aKOuHy6)-UoOJ~KajonG7cD|{o6lO zZo!iZHF*vAsljShVK*eH5XAhT84$}MKM?WY}Bd^2reEnGEzR$19$8VB1;xg<%O8xWLibMD6eA4h(!{+(a z;B@i^>?Thbt$kmTr{E^?DtzZY?f2mEhRywPV>F*Zo`ego+2L1*y*MaN{iyxg=fKmi z*?4^Rkn-K+7JSCAdAvN_x=iy$__1p?UXS^(=BFDr`%dg8w~bTo`+Hsn-cO#3YjF|o za6re4OVIpN*KGX#8E?P|6O@8;KSJRg!YgBT<4R3Kg0$27_Px1zfeCgN%M#hc#dGl=Ahs0soGhaQ83OwYjG8>z%ePB{|h_ueP45ZaUl+T zPW>}D5{G@Geg@9K1-R9>%G0N5J{sGm%dg@*d-Hch4^D!i@(E> z4$c38CFNai^6BY?Alm;?44nXOyRGk?+De_(|;NR=yF3 z;_nTcKW`S?gfnr!dhO4_PhmIC!9{o{Zo;Rqn^Haj?=JvhvwJfyq)qtxC&44YCd?E@_Jl{otKn{6)V5>vYhmhJPmtx%U5wo zshstf`f>R7COH{z!)`qCZ{^MS7o4zH`{w_nycE}C%Rc4Kf0gIqi?|6-ZC0MJU;XcJ zP?3f!9_>qnb#}#;Gb~WkIF~gpgirEyc>ts$`AW1kH^J08=u0}C)D@9QGNe9 zxf_nc%W)e17^j?6zspUUFUF7IsME?lI1jgJp?(qWi|cS2E;*z5b%xEKuX6k!c}%_X zaRJ&_hF!Q0pD=9BXP#BRxP{)oqWE`t!p)kmz`o~O)#7dBb=a?^`VBZ52cOfvCvXfd z#7_JNcHwTVw6C&3^LFfiUY>(v@GhKYJM{zD5 z8l-+D{tD-MwQoinUO^&;wz7r?m9wEvr@nT$uYq1v(?x=piRqZ>5qjA*j%H#1GoQxZA1|HK% z{cQXJ&c`i6l^5e=T!9bZT72gn>Nnzf*x#?^wdeD6yi>Uq&%$x|E1ZPGJFB0L4_&kI z`V@R?nDUexw0}L$#-C!lzw$FU=|*{M7tI&rFL6CSi-T`c-}n1AFP_m=^T92YZ@OmV z{TOfqF2V!5sULN-`tRcu{2O-TC&Sfuwp4#D&c#P@S}Wzg``1kDyT5G0zWYl{YxRBi zk2dVrUH1>M_*ui|{Xse2gKf8H{t8aUqk3rG?^fme4V&}UAUUL`9EYc2JNEtms|ox5 z{}tOt^DF7+;yt(;*I>W4>UWRO@oacFPQz1iInKtGcA785@%Rs%gd=)se>R?s%Y!xl z8g9l_IJUj=!FOri-9df@hukK6u_Z)q(_8&SJPK#x%{T{Nz;)eq_w_EXD0g+0@98g><8?T) zoAMz8l-sZeJMohPm1l&j-y%w`!dr1fcjXfYDbK;jv40Qc&byVT;ef$%CC9?0fv*_<-zt{2y(TyT)if9+%@B?E8IP0rvgA zt^p_CuX(=_+II|>;EuzU$BtBbzKoObESvhd_zhg->*H$N zZ-n~(vD#mNvv4(b;FQVG3jE09$^&L7ufnm<%kh(#pDBNj z6KBZ@iOR!g%hlMKPCi+=XAU{8TtGfWdGR8-3P&xLXFZ`j1vg;ZQsvJjDfc?%Q#gNx z{L+)k>u~$2aueQ#BeT?xc#7lU$8h>;<(0Sy|L4nJRz5FT^JREDuFO$B>S^UsugWc- zk*o16+=N$Q`)lfN#l`r09J5yWC0vO^p4I*|m-68_YMuN(w&TxnDgF&-yrF(TiuT3k z$`9bC^>QH&-5?*qnYh(+nzy~Fd=5^*Z{a-LVw(D8xF0Ug)BH?qeM>IDf%)?$6$ZA=I7!Nya`9*1K5iHhs*ID zGqvCLj`l6Y>3BCT!m*9|{aqctK<@Xh=6k1UpA}ES>3B7E<1cXuzJ8YGL*LWByRijt z#7Vf?u=(#{0k*%O`6j#udkVDgueo}DRLJ}CL-XWBTuDC-x0|i~^>~(H^Xu7+x8sNp zwC_)xi~FRjUxue)Fa7`re5m;=I2wyw3}4V%}e06&jQ@p@c=_hb7u?LUX>@z@OQ3)!xG zD^9|vaXPlnSHBc5!%;<=ug0mk?E=mh$72s(frEEwz77ZMln1}4+i%A&pF4lYrUS!z3o;A1( z2Y;e{0ZWu;<415gUXA@eRlgiZc{Fz8 zdAJBy;gEgm-?>ct!|=0)&D$G;H{uLjiHq?+%zJS1a?Lm4y@t*6Pus8KbzGs`i6`J9 z{2>l2Q~wl>#bH^R&%{%34lcsw_zJGULsx3v?|}BF;t>2Mw&UYC6?a&rc^4j!EAR>& za!~vC;7I(3Ve@*#;C8EJCmvT>c`;jI2jMaF8nku#jCIv@58a*=y<1bB5v`9j+cV(!=7)| zUw|z~-$W zg_CjU2F<78G@OI0aTyMNQ~ih^bi7f9&ErMm4Dv+$4o<^g;Y{3!^Kr*K?N6=I{#aa( z({bQ2<=YLL$8W+7?h&H*n#)a&&Q{51#Y=f`}}^={$V%)KZ8^7 z3Y?Dj7&eceg|Ct~;$fS#Kdn~#r{hfgB`(C5vEyg;WAZg$j~5v>kJpGx$b)`SzY$yT z=*^l>!kIYgg!%_?9{$&`xxWbadt38W_(|-+*|-rO$AQ0Uf5aBeN1T+W<5;{6r{JSF z2mgaBa9_9fh5n{}6R`!)!_l}7C*z*)Xg&+);uw$i?Zp}RPh5#RzN`5b+_UfYzr@DyBxx8T4g&0oUlc<6S`$N#H*I(FXB>e}-qzQA=js7U=#f8~$kk{jin zIQS;{FC35W-J$u07Ro=sxi`y0cIy740?#mP{(qnzSK_di>L>2v{P8+m(@Obu#ma5B z$lDB?_fIZ-mAn8Kex!agZp0yNG@r0rd3js;C&T7GFTU|(<-zTgPr`BdB+kTll&EhH zR{s%PiC5to{4ow}um1I)Xg>Z<*^b@#cU+BEeX72HXZ3sTk)!ZYoQxf%%3ZkcUb!3} z!(P06pYrf9?YHcg6YyT_#AC~p7vl@qgV!EV9^6Iy1|O7dxCW==j6=%ZxP7@?jSpb| zuG%;4Gv!gZ&F6A5{s_Bp$`{JZaY%*i#h>8tZrcCoVdV+f|4Z44x8Y(O_my%FK7)h9 zwePh`f zDCaj&-iMQ->^<+<2ymCs}UA#zrYZch~c+^~6j5^%p` zayI@Fm*QKFD^HEqzD!&*Oumd0?vscAq<$7|#3lH_TICHf>aWNC56HHkl}F)RoMKac z20KQ|u3ywI!oOqBgUW}VP~JRBK7}Jk%ho#ONn_;YIO8F?-LJ|E@Mv82u<~sCIigYhB>X&f%}{>(pUTVeOx*Om@|`$nmOSZ#`Z0JbPJcmp!bRn7?8Y^- zm7m0obL8b-^~2`MM{vSC@=MB{_#`gLP#$?%dDQ~B7W=&@5Bf`aRHpm`PR3zP%5xVg zx8tHk@?~6y@BLf-;Kj;+$2J`EkMfKq%AGjJDfj(Xc^O`ey~~t$ZdM+?Tz&@ISIBST zw3YJR|EZsk7vSnu%DZ1t?!Q`|kFDAA9vuIQ{M1$T9k>`5uTeh2uf?^W7Y}ye@U_Yd za528+I`u6swrW^jE(r zSN(Tz(wp)#H)?+o-f7spe<;VZZ<4)v>i>+>-jZ)`q1=rZU=TLoyp16vK7`}6Uu zxCVE+S$ROd<{!oxZ_7p4)C(#3k>ke-tObFHZ^7J{MkP z*xXl)PvQnVy|wbt4>Vtb6F!uKZc$!#$w<5xu#&>`?+S~?!13%9!|&AxJz4| zpBF!iLw4x+-{TnkKs)sl@NOKqQ~keiB#sPLKM}u)({S7N%5(7wT!ou)*e>nw-$DIo z{49>g>u@5z={EI?aX(y-?Krep`xj#;-iAx?RUGz_`jH{pABP{q4!jX3mZ<+V&i_Qd zr=#WrOXW;#!{>1t4!m9cJlq>s;L+HNXXD7d+J6Ek;BlR_F9m;w!}h7)B2;+{j>c)Y z5Ib@B9qJe24cLQ&?o=MNU;9Vkc$|roaUo8_cXZZ#1%41W<5}2Jru}bXFFuST4k-T% zC*o0I+Fy?6;YNHI+Yd62ow$1!&6nWuxB;)n6`yJTFwUuv`*qcP^Oy41hRuI(;=YoD zyD3k?J8?1o6UTg`exGpld&zgSNA+xnIEy^qLXk2hs{RKGmoV*VwU`v0^J8(QM#A&z&=is0Q z?fVqRVh?uU_yO8qfDhtQeD^@*>F2dC1H156T#oOEQojbjj{W}7e5*mqt#~oc!n?5> zpT{Nmj=MEqj$gr{|I_{w9FI?8Ck`B}`DQ!>TN*W=jdSs*xE$BxCfwJmebpB=KLw{= zmVfZ&O>*u%`u-39TRvgf{CT$G%|qmrf0VZxDhD?+Z`l0#vEd5xWE>u?ejeU|D{(yz zzoLD~_p0x}-{Mj{beM9xU*NUhkH3ej@o5}zo$|ZxQ$Ggh;Z$6Tb8#&$$IZAA_lPm~ z`T0d$ul-}L+2I%EFYm%O-06NDKLIbt$@mYPjvpJYz7v;W7w-LlayMRwi}4j)j;Gty zuf|8Q2M-^i+=~mb|Bbpm9Y!h-#!GQHZp2Y|@`LKz@E14%_m5ScjNioRIAD}=Cw>9D za4mM@QKQu_#=CJj?lwkwHGUa;a1-|8r{dK2ze%_M8yt-9c}RIUcH<~~>saMByZ|R) z4^GBoA67pd@4-$S5wF~ZUD%DUT(j}{x;SK<`o#e{|3$bSpT?m#E02Ff{doK_cH%DM zm6zZZxB>r(!&++Jqy+U7@Ijn~`%X|^ir>JE_=btf!&_-zDz@XJI2+&psQP7iEB4}! zcI6R)+P4HJ;&V6$Cp@NpIWEIZxYy&#BU@|VYd8sC!7e;)lKK_+2i%PBOH^*TMf={z z$++EQ<+*qvuEb}s->sS-H%0v@ya%V??oTMs!>`~f{1^5Q(!QsX)VJbqaVj42r1E^c z1y|$XsmjCKXy1!C4u6c3a5Hvd%Tt;!#G7$54oGHyTkW@DD_)5c@kQ*!cR$U3{2p$` zw>-oCcG^E0Tk#s4h;Mk7eRu?}#M`kK-;ttzK(O||jH7Tlj>TS_fP#xWjG0M$GP|dF2m0}ul+$GnlHc>+;*mNJ9gky+=z2=&ouQ5@uRo|&%+-4 z1`g_|C zZhRSgv2~I9!Cke_jiYg}LwP)2jx+IIoP*EfJluM*<|}X?+=L&+mTo%!25iScOEh1A zAHfxPA8y2bm#Xg{u6_B~f`7y|+``H2!#!~(eh?SnXK_Gx?LUMg@D0nfFB31r)%aT+ z(?j#OE>}MZzmCiBIoyDItWZCsr{>3C8=j3*@D5yxeb0vriqL$^EbWWNu{a4kaTeZ( zYw`6fH6Pnc`=W6QcH*eJlpn+ixE?$3EvvMz5Z{Aq@H04|xAwh?qi`us!oTBU+;z3~ zhec{W9>?HaIIxfMz-;v+aU8beZ0y9J;v)PzuEQZOYhPer?H`G)cplEiJ8={K4Ttp8 z{5`K|pADzuG`t??;c8rgTdmQ&7u#^SMf+dG@pvcB#FwxePtRc=-im|!YhTA#l}F>1 zI3E9tGx31e)X%|FaUNcREAZRcix1+k0Xn{It@dT$FL4bHb1C;9sQx5u!48~=3$O#9 z#?|<~*R?MqO8aKvIJ_CBX+8-*gtPH%T!MeV&bu|=?+wkn@l0HWx8r7f zV=m`ASo1MB0Y8l$*o6!6kGR@5zh3*A@%uR3s{NrGl&9lmI1eAhML6J1^{eqqIQ$;% zE5kM%nWug#&chCT%Uj9|@d#Xo=io~GI&Q)r;qW0k{!yHWuVNSOwNb|_!{c!ScHo$y z+V?Ro#2#FUdv4M`FW!J{(VD*@pWBaPumdm0Zu~d);;EZ8A9}C$ZNe6O3Mb%kZ>yh) zUD%CVZsB}!91b3){UtaWN4V9G#~W}a{toBh>)ug64|l;8_?cUdXEFOr{@pIU3 zxaK!tEB+ZL;rI`4#`OzP#Z^2t}3J%(>yaW$3Y~J3;IL*(*dH7u%_K@=9I2YgXvF5YJDxZi;ACcE% z`*`_#oHJ2wQKI>f$7CDMoFp&9VUy*i=_P=&} zT{yPAY`n2&pT!Rr**tXyT}RH-AzuxU-yu+u1Nk zuk3wB`{S|YSvj+xavOeRmHwWdjD4?{$-vVGsc%Wq{3rLwsW@ne?0!zU@BJD)cs_X( z&c!9u)Gxw~xB^E^SKf7~_BY}gI6YPQaa@Ww@%`02L-`-L_IWw3!3z2pga@P73x@p4@DqWVV+oA-}FnR4ecId-A^sA2PXPMnU5 zaUL$iZ4apL!Gm$YOWL;qTk%P3$E^->JUkJX;uo<8zsL7e%_8kTL*9g2AJV=Mhw{-l z8qdSU_#JFttp0b{e~CP_T>B#Nhd2h`@tN`_JPt=J)%+JY9uNIo{VY5a=i^^+6At)- z<2$u)08YXSas6`T-{Q~}@_#rU&#utE68stV;M)!>kIT~h2%Ld)aX$VJm*c5lYQ7#X z!9gpvuNvF%^PxYsw@*NpRU z_#4{a`dj6R_Bev#h{*Efm2fr!XaZ;YVA7|kkzf->ur{m0ZGYbEx*KV$_mLt*T-#tanJ|a*M!6I zy~i|f!SCWE`~|MVeUGaj^r7}WhEwroT#bJ*Y<|7#ar>V%A5f_I(Kr-m;0U}MXKYp9 ziz~Lt57cU36MhXxY*)Sy2Nub`_d~Vrk}s3nal4A ze&vti6#N#p9aR1`E;uCLeMa+Dcp>)UKX75W`t9n~_uvPy^)ux&aU9OUcKjL6!b8q# zUlHDl>+wnK_qq1>{9XM-JRg_i{W$-y`v2gDFXdt9G#~zz{4|cktFROA!!`IcZon-X zw66(2hl?t;KNr{Fy|@|QbYAmeU#mY3$KnmxfiK`{JnRq6*JI!N1$*&Qa{D*h--I)9 zoBwIP5Xa!OZ`GfIy|@C0R4ET`)O_f7au$yKUj7p&VC$diXW;j-<%s&<;1qoQ1@%ku zUAPL5!L`_d1FN;~5{|+t7qu@HzlELnB(B3zUiD*-YTp7JUL${i{g2CSF0sE>o{RJF zPq+zpx~zWM&+0#iOYlBi_>1zJ|5D$BAHZQJlrO}IxCm$C8=Ca*Q!So=gMZchTEph! zwFF#@9r!GE;oJUJKOZl}75Eaa#n1htzU!opw-J})4*x1|z}YzbH}wzTXgr{qeK-+U z;N`gNl;(@E7oWrtrQ@9*YysCaZ?z=<( z9}BG4zQg2+xCuLP55ItGU#}9JfE(~09DG*$uDecsD^A0W_;nodJIBYF_)naJ+g`7I zd3YqQ#GhafeeL=E`M4C9;3j+;M_#9X&@I{*hbQ6)f91=u9q-4k7RpcH z3VhS8+E<7B;wHQoyKmO~{Gfnqj|aT?N5kg*Yj8{D_BOHw2e*~|S}9+Q6LBrh#nyJ} zN3~Y}37m+X*o8}QJ+8ye__|>23%Eu5Qg9k}VHf_(u=#i=4^M2b`BJX-GBAHofIF^;%P`7WG>>u?rs6{>wjcr>oZIoPka_U*ut_yr?f(@!`^mv~YQ7n#<1mZz@39Sc?yP<~UV!uPVVvAw^WDSL&&7}7ssYMB z^Le1$zl-`+QSx)xZ;<>s&K)8Djk8C}cXZW!8IH&Gcs8~_sQwO|h0oz)9Metv;zz6h zF81OhIAx6TR^i-U{1A?gQ=W>Q_z+GXtNiBfnh$wc9*Qk^I=15lS^E182w75{1Y+WkEq(Odhg@n*wj9x_S$PLW&j{gLWBaV`!^RR01l!9Dt@pE+6i3S5Fu z<4QcDulmi{g(If0A4lWi{nSsuOAMRmANqv)yT~p0B)JXuv#4*!@z{-*7&gCOO7IR` ziI3qL9MNBWYm$zih*R)RT!kBO^pooM9H9AlJPDWL)wl{Dz@Dj^KaT^Rk}U(ZFA>{u zHeQ8Ga5Iii)_lh(&1d2daN={y8*v^E8>D_2eh%BGslO3t<0fB!hVt;cHSfi-IC7@) zw{g)d`7o}-_1OOf<-vosuN2>ntMNqa#Y=F^Y|a0G)90|ys(rP%KMt6yd@L@)vv3oB z9ed`fU+K$nGxpC=-uE6IFAC4ah4>qsHedaKA?n)~$YXFJcHnCKF|NmF44XecUYsyg zj(k!3UNLO`JjCJea1w4Atvm})#wGY2T#tXl@tN9RmZitf$@q?Ywa!j<~|%*E}yaeeV4IQBKo z_X}5^h#xlgo9B~;pT#-&Ajh|@)%*qQ!d=H`-h*AZ-le|p^Lt}nmwlh#n}h4<*Wv5p zv@dX-`hBq#Pr=#v6jO zbiDcv_$h4PqW;%76Aw;MKOc|Bm3SI%!i%xRt$jOiBK{R;;x-dFA3P0bf2;XzxB~wV z*Wu0+HQ$IQV*e`5ufZ|+FiylbKC1bU@6^8++wfeRfw$otd;tf1ulXr<*#;b8IzAaJnO~=)b#^FE7^Kd-= z8fW55xClQuS^Gk2HJ^&(u?r{TKd}qnHbwK5I05_rtbJ>+6}Nsu{Zzcxu=(#z=r8J5 z<7j+alJac)G_J*)apVcj|6=&szel*klX4E8h+|HwzaA%G4=z2WJbbF=tMCNu!8zDg zul{+Qc~+kBl;(@@huHGF@_KB;ZIac`!0Qd0*C*nf`Zc~Bw|iRsLR^IF@J-JsPiWBm zDD1+27&iCY&MUv?S@m7`DO`@Ta3lU0hyJ1YlQzw&RUB@E_$zu?7Eu6S4pE+ULLz zVC%n{pN2E>2E*p{sQXX(VRA3NOdfDW`S6+AAByMT7+iph@bzihA97XmU2q~EXZYIx z_wY;DiQPB{e}QYT@AKEo{cgGT_c-6@uLoQwpQ9g&2h7s(+;|0!yI%bg?8I-D>i@IF z{>uMn*e1; z{SFz*qj3_B$8Ma5JI_}?prhuG<5c|m0_9csAH(MH5<96s;YHbnvkaTpzZidyD{!Ao z<&k%4z7Ut#;O_Ld(tY#y%&ZznIuH8?O*{VUjtBUf<#I1v})Rff&|jrbsWSRd{C zlROLGmZg3PejA7ORsS5e;M-TKpMf7YY+m1N{07d)U*kf24p;i-S7~2yKOJw4VRK(K zK7{LWBlhCntJROTXublc;g;FTbMREd*S_Ak5I5i!FRSm@U;BpONc=g@9H9Iv_F&5^ zns3GqTr^PqB3y+p;H)U+-Ph>+8t#@KHEdoFzrpef@?iV}c?1s3Q9lk3$EA3aVe|Hf zTea^1PQhOKnK=Aa?aRRr;XJ$m7vW7f_#W*q!x7m3HSJ5nX*dg?#Cdq)TJ;l#Xy0n= z#5cH<7vlNYgSX*k-1&9(4b{F;I1A6lrT8sujaI+cI?Y#%kmqAB{t<_cRQ|*p>c?Uy zPRILkK5n0@ekHyahd-!&Yj8F$#^tyc*WljkwJ#=C^Uvc1{E1=n`=NA<^8d(dasLgP zx5p`;jm*eiybHHou=e_<8c&c=bQP_4o{Z>p0~hZ)rXbkH$&Z zfm6n-zZGZV;Tv^6`FMe0^L!fdcJic&nm=C{=kd0g|a;tJe%i}GfC#IX7GFPxs@8G~G+IJ4u zC&``O)4r&w^20a_r(qY~W7xbtdDyQ&^QAZ%*WkH0_$lqbh+}co`X>v8W|17z6q4E&?v|;o6 zJrcWdJpK)r;Za*PANhjzrQ-}-WZ2x7jnCqI+-aNU3vsMrvtNlFxO%qse}}DeM5BFV2uJ<7(WiNb_Di9{bH#|0NuV-G<+sm--1yln*p)_S5k~@rL%XL1**oM#JcpST1 z^Tk=}e}Qc)ic{1$fOBe)0;->-g?OZ!jY$k*lR zWy)jM$$M}TK8zRy?6#=g%-%EuSDy=8bpxvozm z{uGD3qvN;#OnEAvg{$yx9QLmIXK@X_<#WyZzo&c{w&58#6TgNF@Ygu0K=W5{J?{R6 z_7}ddJOP*E#n^)jvEPU4SK>(AvqJk)@KPL9sD8jaeLqCt!7s|O_+{+as{YzcHOi)*YG;ujKmS**I~h@-oBb`4{5AuVv3J1hic3CH z|K4vjAGTXgGi)9&3cp33fGcncZoujIzHha!0l$W0OSFF%&coF>^%LbSt2AGP!*CNG zfnA@fKMR-P4Y&c<;Nm^%|B35xeKAKgUy74(zyam28aBWFp?E*G;L|u7U&U#-Pqp?}AJV?Z z4V(Mw@iOve{55${x%yXd6z+Fa^KQJtuzCA~K2zU~6Y=--)9`=TiM#xueL466T!|mY zO?Va#|6Ip=3&-QnaXCJR1HMo{_(vTt3di6i{2b24uj4xW6^^UWzQ1rP?pCAyx%d&> zfLCMtVaCD?*H|ExR_FU48-D_o3k`$hdaJO>AUul-fniu;~WKN+vYIrukRiigyxUyt)~ z@Dc65;aBA`I2otngE$xWJE?v-UXL5G7l&4Bf81~C$KqW$9pC0ro{wkZN?eYcaIaJ9 zhac7c)i@sih%<4k)B1UI;71IbKkqKQ7MJ~?eFt$3{uKxOsNC<2=HqY=T#ldi~&=jbl4#6GAM65E`-22(b_{A%qZ`g-onjBV@8=V%b9Du+V5*wr0&T z*+L^*XvDHL+IOMR$QDB5d*5BJ^XKz%UGMkjzVCC&=10f+oBBO(sPBW<;@IDnKV6|b z124gjmz4j2{jl|K^*t^tpMsO{PQ&K&NyC4V=iv@FHD8QFaT)#BgJw)$mwCib|Z{{L_Y4){m?Y@CcM@SiyNs^&ZYtLG7c z=NLBM&k1-pw&9C79S2u&-ZkyphJDKACU=yl;4wG@uff^)Yg~dG-_^Y1U)nbp2i=hW z#&Ou|p863L%GcsddTI#zE6Hzc`^>hMcDNp<(?1J565xXyGpsk zLvrkE_Z{UcaO_?A63)P_YBcYBPx%y_c3)nP10KkiaUKr)PxDnc1G_&|zx^ZS!8jV{ z;6sMZub)EvA9*Dn@L2Pf8tq$xo$!}9;6LRK4)tr_Z+UnHuEHmRTUcegt;KE3pUu8HeB|bu}O1(5UwBqYT83PsqElFTRcA@gR%lvv4d< zt)uxg99UPj)KfnekHLBP6I_M=!IkwiKmAF~yFDp?jU#Y_r77%Bp@5 zj=&bH`q{XozTB<8`i>3cwKy0T<9OV>f%^Up)gOo*9p#U(FTR1}@vw%P&%#MK;Tg^U zhqLhnNA(>VDc^~`a0zyGQeNk2^{a6h_Gqm96C8!>JfnUp9*J#D)&Ck7;D(LVcXn1j z3KwGAYW@GbLo?-nW1r^o7xZKB|FCNd<vQ z{tx?g(Ek2Scs+0eF2E;oDX!a8{R-@deL891bR33{<9J++BRi|#)mi&IyU58n7+abt zkHAZ?TUYfz#X;DuIroE;aVE~k`M7Tj_1(H@-%K2g*Wm>GHBNg@{XcOre!@ljEZvol z$B}pyPQjTt7oRt5{`ygdTej3b*B;vUF8@Bp4-X|z!cjQDOZ^=<7U$q(T&I=xM?J58 zFYMA=o{P(H5_asP{A=uw|H3J_@w3{WfqNM??=KsV!^L<5{R(^*yZ6<3bzC)Hu7=I?tMF{Q z2P?PXh@o-;^JTb#++&#XR&BK}6Z;#k{qGCBjy!U>`q|`#_%B=>sQlV9`u9EZOpT)&9)%WVE z=i@O;UXR0O%NGpSe!b&*-Q;{6fjz_3Ps8E3uBZA5cvP*8-|xlC$m8c}{wrLB|H7{G zm3Mwl`vUN6oQyxJwek0<@G)}t1)8rSPr=Q)YhUSN<-@V%HTex3gYEx*w;b=P%^e(k zqSgP2elYIeL;GX#Yd8z#C_IO?UEMA%q!QMC-hvPhK|9L~%OEkZY-1>(68+OG# zdTM_VUWvo;cQ_H>#%b8Am*%ta0$hPpv0seNFTzRK`n=}Ta6g=l?f;%S58FSF!1|{4 zy-eQ~Z!ui^^^XtXSX@az2~YFpd|ZG-muml$y_Lt}**FPbz?pb>AN9*|HuhPjeN~3d z>#M-S`pQAE%2RL_zHQH!D-ZBd-))7w4Ts|&4Vz!DaoF(%Ibfywy>TL*XV|=+%2mpD zV9Q(b-}GIu{pV--V*BTHB;tfIYW5eeC<-RQs_LWoLkyqHAAb*Fw-<9v-%yn|V0h;$&FR#Km8{|A3 zkR(^*yp3|VftnBaK#s$u$?`cIvsvymNPVXic?nMaP|m=v+vFN-v&n<}H1E1yjy7z* zKT>fTc?B-U(P`>i2Wvj%V|f~O+ADvG9n$4e?2TQ9=)Cd_<7Uk~Sfau^Q7@6)fr z_Roj$_+0&c`@d%o#P;`781Bu!5?qeGGBv-x zE5Cl@%Qy*t;IHdR!`?&XYP_kt=Ka3ZzPEeG!Px%w7J= zzaNMv4b$@v#)okP?l@ez+gF+o!+!Vx4#w>R)Q`rAI0N6sHMr{t-EYX(+W#sp!k=O5 z0p)jbJRUHT=Y?O#p5Lhd1rEb?N2zbaez+KagwwM%UxTah`-j~^Ykcu-*nA!-_!Vr;RsS^h!o7mj_s1!? z23KIGBbuK$R(&u09ge`A#wpLnlMS2K8+=sryRZ%4z-74qc=i2{slOKI;4ciD_g9SV z|NWPjr@sB?w>bYGpP?U)?cY!Gao=F>|G4_wa0D*GnJ1Lr$7Q(F1kDHJE4TmsgaT~; z`v|4j{`U*2u>J2B_?^`JMD_*aWjGyg#STBJpM?YQX`F-~;2hj>qMmQqPnw@^*nFPR zcq`7ve_&gI`gJC$AAd@A!~Umb`_B`p!S{Qwej(%Xd^%vCU#=qylTX5MW<+(Wj5BWx|9UQFxliN<$^;-XwhhZ-~A6MaZ z*u6~suW`^-`4W!5CO^W~a{0L#IxhlG#7=)HUyTEA$e-Y7dE{Q4`wvDoil^|NpUK95tdb(ZGy@nBqozrrDR zwC@4V!kuPoz8H_dmb>cj#sT;Yj>P}q6g(na`||K&?0--DcHsnk8hcc8eb|OuysUk> z_mu}?mk07XT!pQ3%)Wy|%0uP;hRxR}53j1t;~c{NQ+^01VvkpJUMY^oL66kmjAL;j zPIYjq{qxEioQL~FXkQ6_)3A9xmM7Hz76;>dwS5PNV%&4C<}G#9Us!7ghXni;c@}<1 zo{tC4(|i?PgOi@rzAteWF2<#}?tIO=G*G`c_QZ2>0^W;lxD;384w2fI&`|qk*V_2+ z8Ao|PdGXWo8SMCs++~3|Z~VN4Ci3gGj&lfdmfy$mxPpFYOXW*n)$>onHw~L#f2q$Z zpRiEQ!^wut*UPK5@^j=F?PRAY^$R@Z0k|4xTYd*Ktf5SQXA++wl% zIbNC{gX4S3F*pSuFkJin2|xLoT#Y9fHt*l1m*zjfe)upB#x=~x;?dFCmxZ?*Hun|b z5?qa&yskX=d7U=`CwR+SaY}Ew80TaA=Yv+`7E83xv5)%GaM26$dTi|{JG`O3KX&{; zzhCR?tK9zkb)k4Hc?Pb=<@i~Czt=iI^Y-8W4Z+I}X@5H2g^O|b9Oc0SHJ^?n@Hw1< zXCGGId64=`xE~Mv7mmU&G*LgoPyG=wJb(NpuEZ_hRPHud{Z%*!U&nEHJFBE_3$?A6Ri24a3X$yOYwzN%~#_NJ7uql znz#RcdK7MZUH21@*W;W?>W4C4gI8eJ5as)^AFjYrxRkHAL_A`-z8+mCYkvA}e*P{# zNp6{<{2q3}|NB_|Fg$pVoHAAYL|lYh?p0onhw$h9)=>2)tkCs%;IFaMH07OFDi6dz zV#_S$zH!PE@xv*4Kjq+4Z+m0>@#GWaa4}sGow% zaJ@~+J(D>P+qTOOaXyaNtiHnz<$2f_ci*DC08hiE_&c2ck>-1*sBcM?&*PjlIp9O( z{vXQ^aQq&5<5uM%pUK^}$qBdwr)4M~U{hYOPu_>EpUbVbD-Xh{IQJXnPCJxW;N{po zTlqyChF|dr}^_QI7smUX3&H%}vVlu;*@FPchEkrrhf%&95Im*EF8zY0a<22{;?u@B?f)qkhki zb^R`QmSOYzpAUW)`{Rc=+TP!zej3g)Y(5XyLhbk2t2`1%;w-!yr~a&dsbO=z2scjG zyvteT({UW$iOcat!?nMD;D(=Q-u0a3`(rO0j(zcA9E3-|q1PuAH~LijqVPn+=6U5f zi@XN^gFT9LzV~OEPr*?*7w^MW_-|}Iuld0ln)k&UaS$%VF}UtN^^@=roQ9X+D*P$7 zUeI~J<51lEbL~sU!*C&9f*pR*{8k)>?_>XB_nj4nM;A zxW~839ZS_;gWd3pNXfE}mhy_WAvxeQ$p+`{B=X+=~T!mBdSW4>W8(FP}2)i#RC<;-u4;e#pLKo&w&6^C2S;C1f8bg5oyz3|oQkjE^uLskIj4Rx zPQp>wmH&*bH{@rE)Q`e`hRx>@k0Z&`@MfHi58^z09oOLA=e0keLg!7v1^8_oepC5{ z5dMD@+dtpE1fQl~gCAq>TbdtvLDwIL>--`Y;)~d=QvJ@wx;}6Gu3_{3L-E{;ayl-= zIe7T5?8olE$!@o`zhQ|Sjptw+p7OhLhkw*>e@PC<;W!2-;Y2*^vieo{E$sNO_T4sY ze*gEy!KHE}-i(XzDZ}Rdm*Yp|)++6L?hnno;tALTe}Q9g{r{<-h-czdyx*{SUIsq< zr(B4W%Vf(PogZ>VcEOFVa({R+j>5m-ceBR?=@_`-YNLW zf8;_OiXHE3e!pS!`h0Plf8`kbF1F!oxCFaZsqgZD>%k#-HBQ9)44c=Nfv4Y*i*cj7 zat-c{eI9E6R2+)m!BIE^$Ks!H34ZdP_LtRY-y-b%pPY_8@IN>S_pH|arr~*p&HKs2 zTgeOY>-W`nf293=AE+OT-@$qKC+zZA{bmm}ABfi&HqVR09cq+U;nRlA-0IM{_Rn9Z z{3m;5!bY9Q8%0qDsj>1O`oBb3#+aj0YW4Ic(s>lAi+J6v-;;Bz6&%%2Q zo6oxhmts$g=370b+z*e#!FV+e!*#9d$K%mB8-Iuk@L9v={khfCd9T#hyf=QPf$|vq zreX7X6Y+hVZ_gVlcY0F$a(~vqZN&BBw{b4MgtHoG-rGsf%hFI@i+vsC9}Sz&FBboe({Z!L z%AKB8zdw$`i*U>{%FA#%c5kBj9J~a(H&XwwVe|F&!H>y9uuoIv;n>+(&c?qOHm~2w zN&7sS$su?F&cNA*&GSlem*(m_H`aWAPwArhWSon$a3wCq&v#Wn z>{;!fiqr5hT!impi>vz2chh_%e%Y}3eBF~XXW>gY7rS|CpI>Y3pJ>?J7tluT z^_*f?9IW|F56!=g%kW|B)BqqIK@pTw@c)$bIj`}e{t4V(8LgfHN5dw;a@C_D!{^wGXO*txI#JNCy-UebIt z9)Z*GtGF5`;7A|s+ly^4$VYKGeu#tnDQ`YT=Oy8OI1|5)!~3hh-LU!nBpKfzw+>L= zI7s`v@Kl_Qx8TTu>R-TVxWQP>7vW*pVUYS8aRNSK@8j0vH1F=Gek2aZNjMgt!sYle z_8hGFp5wJI3WsCw7nQHX$@mD)!Z&agZW7G(4b^;ioIhL+wmU#xjFU&mXK^LIg+oUv ze`bRAI|a)9a6F!Zy+$ivW!QW@gYh+-hKEnozDm5vu-SKiN%LP}AAA$Lj#2)?B))#| z2E*ppPb@x2o{o2K)t|@L;E^GkcM8(JV}{N7FkFEXaP!IP=irIB4DT{*&R63z*mJD* z*I++9V2b+DcqvZ6dvGQ`ZrFT2`PhG|>@rUK-@=}_X{hoIV?Cc( zY$H#@XK(=yny%}23D$fp_Qcz9EdCBB;oor@zJoJyvl+TR%LMHY!=CsX!{+n$!JO;Z=)c!~ufRAI}Ny^*IY{TaDSSHJ7u_L}m-y7GTrG7LX z|FQnOJ_q+Cw@%T%DL4=x!?E}t&cMBAYrpeU%|{qE-#;FB6L|p6#i6(iM_{LL?W@8| zaeAosm*HaE>SgsS@N67BP5qsQ&FhK47s(T_b&lqf@mL%=UGrOT87{#dGnCsu@7*&@ zc7H|Zh2Sv5=Ia%S({VDcz*X4(dGRhYwa@-}@qXC;dGW#6J3{+o@j{%0cVip2&Q-qv z2ja|GI?sk(X3KvVHlLp-cAKa9Ks*hH;SUU({YacPU(Us^M9MDV+JDEe`Fz6hiwl&e z;G?)0kAGFU>&u$2zfkjD_;5?yZsZt#X&g1^F*xLJ&HON7qbZ`iy) zPu%rQISenxHv9uFz;%~$y>qoM2?yXN%aljrFr17(#%1_AuEx*BYTj|4_RqyG_&P4c zKFhhk`Re~+*u1|G?6g986#m|@ndf5Hm2wfDi)-*f>=dc}{~0#lPvLk+oSch0-q7EN zF2YyH%W?fx>N_mZzFZuL`@E$*4Bx<+c=u}M)>k!uAA8}=@wy*>JaCQriFlu3^ZrwD z&$s0={539FsQqQwDM}vv4*PMGVe@&!;ceu}xSBi*FG^6q1m87mUQZ<+zE*Z$r1NYz z5?{q>xbwT}m*NQQv{>`SI1mS{Q$Gfu##wmkKK*)FjO{;U4Vq8J6AhcMM>>9sJRg6Ii|}n+ zg~Q*|KEF4#|7RSDhb3_y&c^B3d!zCKyaZR^dpIXX`J?1$p}I1`8LRvww4{*O2pd!#A1tmXP~9R3>T=?$dlFeuORWsbBoL?k5Bv`$GM69F{5P;H`$u_d^+8|E27eqK=RYu+6%$Dzr}FB&$VM+we5sD7p0-zxXqq<;HD%Kh*|9E*!`lo#Pehh^(# z%|G*<_Ico`I0$DMHlJrW{tYMN`rj+h$9-|c7VTey6Y)75o1%O}uI4lGh$C_#{vPLl zsD8*%U2ioGJSGQjRqmN5r{g9+XrIeA&NFO2-ymFy_uX zLmZCVK2)A)&kdXJmo%JFBUj^?|G1woblx@WhW9?wz5qPru^fXx!}<6LhlaJ^kF1&6 zHxx(X6*wDzgKO|@!{+to?$>|1XwXypC_+`UpKL`(NB4^-^P1%qCG;H?0v$g+6XE_cpY$hk; z;O24}ezAq@b5QfA4V%AS1>+?yavFYs3vg6R<<@UCe*=f$IjxjO;>$P=k9}5oB0gc* zyq{8h*HyM0(*DxcTrVzYBM0J)w%Qkk=efygxNAE(8~=;4?S*L;a#^LYp0r9I>*?Czz0JpK@8<0d_oJLGEL``8E9@1;B%$Kf>G<$0Y~ ziu1AS5$$`$Te%;;hvV?<-pX_E8N=rLw+6@bk-d&;U%S3?5I&BhaDb0;8$N=oj%j|{ z3p&p|Pww1bj=}qUcP`Lt6nI=0FXnw?W*#pm>AxGm! zI00`9Q*Ogw&6F$f`B}2xDeVuREl1!F!sPH3mf-mj zvf~-epTp7EYp&)K@H>Xh`E*=@b8y#r>gQvp`LcVV_E#A;=cDmAkz60%y+E$UqhFOB zf7X28g>oqF7A0rmLx#=$1vp}n?0Q!7x3NEtT&z3}SKvZ>{+jYKd>vQgnbFEE=d{1X zu=)Kv1UFtH$6|*!xL$l4=iv)6+Eepb8cV(|)?c0N6aJO~JGx1(rfjcBBcfF|jpAFZ( z-gwb^IT<(JAZO!UxEeQlPr3K6+81lM_Ui+8OOn&^uQ(sC*r>c5KgQ0#Y2O>~D~~LZ zn|z@2Z1~q?xe`y`EC>Fse*6|W9epiDzdhxBO50>+F+#@OB)CJAbY`8h>oqeE%iloG;{3 zoS4b|;K$hdr_MX}rS^H@S^MQMe8#Z3-?vQtAz5+~e)(&;9J?IQy!RFLZHCSH2;Bc0 zIRk%>9j>Y$k*(Yp_c10Q%W1fCuAGhQ zAJP4k;tklbT>F|GRqlo}aWEc!OnC%8g_G=gp3Y0hV}6ipu+wqb=`WqP61!vX6WSk$ z^KdMFE?;>iUS`;QJ^Zh0-`taO2p;vLoQ?y3lB@Ai!{+xV#~Yd-R-oJ)k2xjB;Y&Cf zFFDPAy!;IN@rFVdDbL1T&g=Ti@i*Azrsi8+ zP#%XD8#bR;GR`B ziED5*_WwuwWB%lR@hzN<=agxGIeviM|JD44E6M|K)2ngdWTykYbGY^l=xYu98S z+_+rxA$Z(hawLBHx}1YI-;f>eXkUv8*$vnGTModjZ_3H|8=Q{E-%_4~=T^#&ceQ`* zZ8;3L_(x8_{{PAqcxaUzbWiiga5z4FM|lBWa#zoz1~044d!2bnIEJ zem;)FCHRzKvtN$)-Zuo6BqrbJQkmLBp2d|kF~!7 z*Ku&HeLwg<)V_CdIJP{YJQc6TmAFnF<(3-Fuf#6+4tB>2>pIrne+=Gbk!?7so?M9I zo|MaQ_)|L1`k&70WaawtbsU5@)mI*mTQ`ui@m^ejJ2upLZjZFT3VY+Ar~dgXkRk+#e<*Kc`>*YXW^Bu%8PNM z*0M`o?OTR}@ioKd_pfA}+(ypFgWJmG_!PEUv~Pf$a&Np3hv7Qylqcf3IH#WG|21qr z&kEeCz3lp=@^?DOQ8>+A&c}frwcq(E^?xvI?hC*(I?0Ln5-!E7IxBa#YJP-=?1SIv zBB$czUF9qs-c2sWp`Nl=eeE0koE(BXcb5~fQx7>6R~R;5k9<7GORmEI!`24czqqGz zU;GFM;Wv9JkHO`J&F7PZuRkxB;g7xLYFxj!?ATD}Wg9lH&l~&okt6XBhRyxqj_SYU zBWL63FUU?$E3ey6^P%`n!?o9k>-U$7@CxkljOGXUDv!kN2FP)E{y@1LhYyl#@IXJ= zqmlNF8!X4*u0!NhT=zw}2w%qK_;Y{VkCT)3bsQ@D;vF~$cN?ZW9%tbc>^WR{E>1CQ zKA&QIAVBtPtn=27kp1vY9E=Z+)V^38I!eyMmkgWx-F2tv?#aVrqmo)E!-^NAwcO2AA{bOU)PsKI31g8WkcW|=fEJqH6)cD1krU*2{1Yz6Qzt5ScG3I|!{+nw!L24K4{WLY4i3Y4A<8rH z{>idKEA?AW(LQJVo?-L#@WpGU$_cn$sBE+MaVB0pjs4GR|ElS7FusFhu|t^hQhXWv zyK4T$naV@3=PWrF?>B5dk4oHaw(Qng^DA)z&Npn{pA9>PtDl2k!i9J(F2Q%PXB+LG z{j%o$@M#>3d(F{#Vc6jn_2cmpoQ-ed0z4%`^KNZ*UZc6PH@3`^Oo<{T;PGb(tKE+r-K?+-JG$&`JIFE97vTgk$jAE0vex zmT|g%r_P%H2>ao?I2{jJrTHAZ*0A|}OYmu2i5=fkUV~$Cpoh+@z+rgGYW1V>5yR&5 zjKj8gznDIUH-`<*;Be*p*Lm)}z!g|FaDJUB^t z1>SDhd_6s%)4tvtHYN$hmkQw)9m0^%UhUc=v~L9R6ghoQ#vUu@5KMWT#%*w_v;MgU9cXBeCyCavXL^ zmD6#nopKF6kDZ>^{`g&bem>Z7xB5}I3diHZH04G3r;lZKZ|(ElBm3Y%d*yh15~tuF z)0LOw^PkARy|r)rr*b%+|CyYRCuPW;%{&_)$Bw?5ucq&bCw{AW ze|!kX;68_xC*o9`ho8t%?l3_6XJId#hr{s1!|KQ3pKu2D`%ZZ=-ij>)wg1WQl?M%y zHyJkXHx562L@vU;kIJ5Y>i=ojd_7|DtYgYE@Dq7*C0>L52W$TMACxEHCy&cEJm`dM z8KQnrzU+dBoRt0X&>!Vw-1{dv2X`uvD{-q+vgJkXf8w<6#}lu@A-L`t<&pS9oQk^@ zD$l|hxCFQRS?5*Z?q}ryf1O{2L-F);%A>GLk@lzH&u}5`e_s9kq1sn;L3SM`-}*(4 z#vc}IUoLjOsJse)ihYJ_zT>aT6LA$T#O1#!FT+EAmjeSdKkSkmhPz#6A0AUGm*8H1 z$d(bBZ~i~o2mgly@h^YsexmXCGC39hjI;3UE6U69ZCrz2y{g=Oq|U!=*!=qN#ZQ;Z zNw^B9;VFM9&&Iv4YhNiY$1bC^Kl+CHRroyi3{>8yLU}mejBPmZZ{=yD)!&Nq@MXj1 z*J~Mey(v4rq<*Mj^Zvr|mpC48xurY>FRGNw@x0rz&lv6d#jtr^ARhOR@@PE%UpW_F z#6>uwiv9SNJM0hA{;0chBEF8ZutT+Sm$B+!$FVs0zVaj-@IbD{7Y&=&?=epE(;mtp z_yEqumKx0$;n9Z8`6`@@t>d+?2s`6p|EV92vvCaec%(cLZ!~PaUMYCqW92#c3a-Sn z9G%`_*CIPl(7qBJiAU5^o{kUT0zB$TubNqB<)MX;kZWw^(#K`?)iZGjTrd)KPf_{vJDrX+FG@uGa&f z!=ZRsXXR=52rj|Tdnk9AseKQ9@kZQIsOW}&(c2UZrUG?zrm?^ zil_2Cd>n^_YktCW$`f#j;o8>^2ltR2UsgZXOAg1+_LS4{N4N%$?xoysj^^E-mxJ+S zZ#f6g>n#`J&^~evp3zqhd`0`l_{h=N?*%y>d-s!b@U#8pGVI|i`$TBpO&o~R2k7}k z~HJ>z6xj$Yqiha0WAp7v}(Q*NP?j_l2f%Y{W z!#rM#)9_=Qk3R@f-}0*FJCBt;a0ZURPmfcchF>*o-cK2BJYIHNsC`-3AJ+@kd~}rZ zSi|Og2EL0+@VE);2QO0pPn?J+Ph=kF;9}f%lJW|?3|HfxAI@+!O%M=n+WA}+!nvvj@X zc#&cA`mD>;&&IB}8hhY~+3Ne^pK$>0AFkXzR{M5ihvjmkmzAgDSnRh#c{wh{6XvKN zw^I2z>=q|4enq(-{uM{!ArZ<`@J?KYJIqz?yh{7t!eQ7lPk9pFi8Hb5eB~v03%0(c zef1-i7vde*VYPCv1Tk~rdGmo3UCa2($*ykPfcjDp%xf*Az zl|PKud;zZWx?GKCVgGm4zk;LjJ4@70#!tQ>=i*rGyH4}XVw6YX12_?Tzo|SMe}cUe zH9vT%@^Jhoj>of>DbK{k*mJ$+7sVo22|Cj>I>y*GA>NR%u@fo^RNE|774D5=;+-Z&a z*3HTzu^ZlvgYeUDs~?Bg;gl_!e}sd#$^+g}KL)>n3AD1#tqji4@uL$Ww;nO z-k`i1$77F=)xV3=@%s1F&&N+BF^{8h%pT1**r+@OFUR@#7Eai!e&YM;XX82_$X@Bn z=NdNOpB|scec*bVA2zTAW`}tG#Be6TqP9gtHdDE@3JC4~VM_^}uUT`wLg3EEH zO?{sX?Yp{N4#%xOl2h=4R5=%)+$k5~y1Qk^ecCr5O?JbJcI)T!2H?MO3XV-vUWp%K z-_Nx#hM(`7h-BTW)cm|pl)K}JpUQza z=rh@d8)nFvxb8mL@}>6G`&;Azu^6ZciO#Q^H&U;?nWalsCaBSHx z$Kc6d$yqodORmJ?_;O0wQuS{<$m}uj>492 zm8asDvCjd`-@p-g>>*u$DPCdNe11;fsDGE-Gh1G9Sp8V+_`O_=uVUAO>JK@h-1@DY zaa4B2?egR>9Pxvki1!_rv+=(tnLpGdsxoSck5E0W9b>*wWa9D6|yJgoief05JhsA8R0fd9bO z@6?}oQT<|Efjz%h9`>tp-&}deZ*mykULr^1CoaiZc+h3J8ZR&9{*P#1_dn!hd>Los z&;O^q3NQatb~&o~OE?#Ym+8DpywR}ve)K)2{x9TJ_^B((L-Lfb!!h_DoQ@}7RlgX2 zjIBRtzTq|H>DY#gv9(-z&~eT)T>JW;kULzLbMTQHvP-`5&no0l+~TGja8mikTjaR; zZ8;S$_(v|lNB@rH2=g? zasZAqT>IY(rQ6*CpiM& z!)f?JW99kSw~3tdv-X|B71*Vz^6In7bFs@gd8o7UB3y>6aC|f6&PD21V1Io3jDG#k z!{eLlev9$7i^^TjYyKT0H@`l8@Hg~}@J;dx+^B{6ITtkViz9xKU%@WL@*3=imnP`v zbB5u4LLn_PC;X=Qesjd0v%+44dyCKb(Ria0$-G?rqhtz_EtSuW$G3+INoJ z2RC+8-}7(feQ`8ii8Jl~R6k$30&m5hH#L94=$q%o;*RaKKN~N@h4>7v#7^zicfF;3 zFX3>Uggq;jkNQm46aKG!)yU2BV{rct+Lwr9aW?)LSK&_X>bqBI-x~JE;aA9$aXQY! zr*Rp+ja}|&-&%aZaiQ7y+?C8+6_TL|N^-|v(e~XiFy`IX` zu)kq*Ujd$n%kW8TeM0;1VPD+2m*#_TpkecQrr}fM*?9c(%4_h)hRySx>S({kTMopt zaWdYF^YKZ;=6RO7ny)5z!A*N}eYiJH!IQA7Mf1yXG2V@9@Q;Sg^Rnux|4JXue^SoH zKG>%(_k*|L0({=ExzF(_&HqjAi~IO!J_@hINw^T_;dU>mUxo+a2&?wb#&PxK^@h#! zZ4Kl+T!bDx8{h@dwuEI;PTMPB~;9PtS zSK_A!YM-l%`hkYc^CEE+c?#Z(-CC-jhy8FRF2y|uX}?n|^(SFpyxFjMUOcYjCp$c= z{y^-9=io?u7TfRxoR5bL*1l4F6j!@yf8Qa>v)alrxEN>QGVJ!E`mXKN-+&$3%m3jr zJl|ja{0_>G;Gm9j>!HevJIOYj(^+;NraaX{{uJlp2E&=h%dw@4`jyxV2Lz}efKzc8 z_8Fl(4)4Pm_^FY~^X&7u3^yO8+^MV1UxYny{XovgD{wR}#)&v&wE7u12Nz?vmy}z& z>Abnv3-8AP_#qC%UB+lW27iH5uuG8gJiH25;xpLQQ|GrHtG+j$j|1@z9F7CVsUMHe zV87?IFKWEEAy1OJ5c@X!hBCwJGrEF9$}KRc20@hTkFQ~6)mp_e>vlKQFm zTkQ9|@&+NwgT3W29MN08h^>9(QIpkA$5(N_J)fey3?IWzeKp^Is&Zev3rD@6ya<=$ zHlgZ=_ftL@C*owowZER?Z>P!D{^}P@m&0(Y8QPbD#~U{1OL2oR<*vS*hy8InuEDo) z;sEtSW@zuo@w@7QIi{0L_ZlUvW$ zdBMZwA%@NSkHgc*^YE~6@rXNNPHW|;iL0)y+wFOr26h7wcm4r?1Nu6Y~Ftu9`UN2fh%z?KD$u4(DT3Sykm)6jXmFx zJx6Qbw}#F84aEQAXzUZCegcldd3ZZ^d`bI$#7X!euE5>i)IPs4>i>eH@#>|@lks)K z=JjQaRljbm>@ZG#X1N@SFXL?7Wrgx8TyLcuK3?fa5J%uyYm~?0e{dQ;@wW18yzw3OPtbXN6XZaA0>|N`waU|QpLgYAdgu$*fm7^oHi);!Xt4AUa>&? z({MR?HjaN!^VZ4Q*I}Xhp}1?3@_0NSr{bv_l^5Y=@5|-*5_X@W{d+%99)%kvvmgI} zbMT~1${nU^{x8Gk*QYg9_L-yW^~EhVE04ksbCqY{F1Q>IHTvf3QG?^K&ou2n#J+GG zvPJvj@mZXS`=@B1>kQ4iZk40(iEVNLcHS;~gsIOFE5{%f!7F-!Z#eIonfeV@wV_}FK168JoR{^8m``fE7^ryr2h@!@ae zLVPk?_Iz3MUmldh@#=5o6#V-kIS2ofBUj@3-^rFa+UNYe?15`=D88DjJPLnvMD}?_ z^P7+AeiQKcW6E=JzdYG7LjATs$f5X|<8mfW!3DT=KJ#-mKmMfbhClyN4#)Ki@CGIURp_LoUQ0Rme5?y}xCr z#X4`!P1y%W-I5dW^ObTczHZoj{qk|_ZMho%X4rf^0$$Vp5&z1e_|qym1Lxh5i}3lo zvRAa`kKU6b@Q2m14d1^n=i;Uh7&xt|L3Wq5gupau}Xzk+X0mF2u{8WIjgo2cDAMaf|wL1deGS=ix6J z%GEg2QFeS&`*NR_190Ipaxy;ENG`y8oMfk^nqS#i_wTYyZrel-#NXpc9NLuUg)iW2 zJjhx5-Ir^hdviGkpKBo(+4GjN*9!Ifw~`Za8P3Q1pH*IhC$^UTS8D!`HgX6Kbd%%p z$aZoO{;IuPgIl}HUUAy@Zb#W4|J6y3#C1L76x_CpoPm3Em5Z=zH`!s8_BZsDo$(*o z7ytE~@+ACecR3Bu=%Lr60N=tjc(j-L#c%1nFMGiY6pOds}%DF2H^JDR+BE`4PkB z_p>PckURy?>#u$;zGB$y7hz9d*_xnzZx}YOCkQtjAgAK}xC)OQNPn&7|HL-@+92f> z_-Q}c?_KrB8aA&d0+(VNUN~6&9Q@l5xe)jBm)+KB-}s?&0G>TePQzn{%O$vDfb5j0 z`PCz2Z)_VWN8oQp$+7r&pqz^LkCuyY>PvDtetnFbxnAdm1nK@AHpnflAMB*LgW&BYqIQhXJUsB)NeUkxhH-Lhu}gSk3GWGkK3gA zFkFJuu;XUse;PKw9-^?*|9QIq_!l5sp=Qt7BO-i-eLIO z{6@`R!Ued+H1ZFW55NvQ)v$TJ=^4t?$aC->?D4U3>vZi)!ToVWrt+z{82@0{-0%O1 z@})E65d2T9T!4dT$t5^twp@>s;^fdx+IQ$pISDs^OU}n*;$W3xDIFFk@M8A!3(fgmiB*%{cx#a^ZrEOlk?>q{N4h&5I0PeOYv8R z&F5c_`z(}$KGX5G;;_%KLChsawb$O{=ftx4G{@I!@ z#UXgbGM!&6eq_0vi<1qT=a;=j^PVf@kgf83?8Kc@lxJ)sH*DUI{4eG0xCEcUHP~~d z=6$xS|EghgJ^)Y0F?cb~#JjLxuIA6+RD2r;ex-&^OAT z#W{EucFR+~7iZ!dxCYx(wJ&mq`r~mLUWuJ}7k1yN{y7|gt?y}H9PW*?@N~oG^Q^{& z3M zc-Z?oUKxJduz9^fyEXqYj>TQqD=)>f4V&j%g}=aFdo({hU3mz;Y}ni%gZ($ki8%5D zxf1uu(0uR@+PB}ZIUj+uKa`X4%8!`GJwKM~a00d#YTx)w|u_9@k^fz1rX5bLD~fzRhwh z{u3wRUD-N*aFOPHwx}PEn{HL^#LEqv$FIN-e4*TLpXT4j4qS!f@W34Pv+*=sjz7RP zxX`e9JllTle}9`Cg`fJ8^Tmy}%T9a_`ySBz^jsZ34F7D{+@FHSeI=LSi`chV^K-ve zo`AD)I$r#Z@*I3DPp-m;cF6Vk>P|V}p!R#_>-j~a9_CBhG4*@kP&@=D;sv+>uQhC*e?7iQ?r~iEp4_M7MdEjHK&kRQxC}SkufF>Ui`ao6oNVzjsKvwM_jd4$BevreU+6iQ744C!UQn ze${+24l9@M;%MCCi1sJrHb>>S)9QEnNp|9chRx%9o>6WuQ67q`aI(wCI6wUTak&ns z{4D#N)xL41+82R`o{$r9&`I^v@Wa2zCHNAq#5>EBTPw8xkyCO2PQ;=38cxI$f8}_% z5EtObe&hIfCa%KIl`F5u%}?uk!p`Y@Y7LwBGYc<0Bj@8whRxSo1wL_B_WND)3oGPc zd=*FFU(YGe!AE|V-Tu)0v_Et_JN^?pa6l#JgX3{6{v10hweMe?i$l+Az6iIzAXnkJ z*z3IJ&tgB^{i4n{3Ad=yd^&dfQ+Xv$Hf-L{I{eZl+5dv}x4SGS;jeH$4zAX|GJG6c zE^0pJiso(jI1a&!|5BcS{r{FT@EBZzml!smuf0n9_mIcqzp?#K<)O>%EaHt(j z&%cIavF{Dd=iu3f&FiniJF%sq=5JzO-0`OR;W!Lu-~~9Uk>-EI`HkfoT#0+sX`go! z<#9L+Z^GHQ#ISk&W%!4G>C#e@J-7vtl& z2D{mGd`}M@?^hg+XFsew0S{>`n2kIeUx}Z=L2Z@KF>IbsCT`G0 zF2pl%H9n0!y)^IFRsCSR5(l+Ye$udczOi_PT`t1^J|TNQrv8IZ$q9HnF2Zm4DYtm5 z@7Y}r#+Pvfp3qad6X*NO6}Z{cvh{I}-&>Bv;{)V0{8b;h7&q=Km*bv+vRixYYuiuu z!}s-%wRbm+nkJ8QlK$N9=bpVxd+ z7x`bDi?_U>`BHpmgj|KYz9@%w)x342_T}J@44e0-5HER2uE8_HneV3gM@GpG+;BAW zxEA}_)nEIvju(Ng5pod@$CfA5&oFGBPdJW!MNV|(ugY0?@ff)b$3)82c)(aW=Sl7F zI!?#8JSA^8Y#z^smyegDu&+ao#|>B$wmn zljR!R?{(SUUHhj*YkwlXjq~uzDe9Nv&^P2NJb0??+e7=jV&oY7k74ucDXypTx2DP2 zxZbdNJ;iv{blJ^ceeW6S`{5ECg%e|yC*ck=3q2kUtJ*E`)XhFg>n$~T%_}l#)ohkp1)XmHg1!o`Fi~P64?=`{m;BB$KhXbGX8$4 z_T}Q)$?ALb)BKucvJc*{T>S_v_B<+BZ& z&(jNUCJ)4?aTvDds2_<_4V%Zy!AEc{cH5@BYLt#Q5POZ5lMUbd`ob5;^RdsDny-2RI-5{HVMd$K%Yo+V?YdpC|X-t9~+`g9~s4_DxiONs-Pc z9v?Mqo=*y%y-%*dJ8{5b%}?0R@v!xPT#jes$Rzc*;Z*#1vHBiMlt<%W{5!6BS9#(= zov-&&`G1DZ^9{mJ9FpVlVVsRy99HhPO!EmiV}<;LQ~RrNieYoVB}I9^BXT%S#5t>! zU%(Nm@_R?MFB|VRZ0;+@5C6pe_tY=M;n-H9JaN79(Krw9!~W^YdmK~0VuQTbu=(}k zw^6=99)?F9S3enFz~%VypOuGXXns7lek^~6Ju~GRT>Odre5vOBv*ZGthkZ_vf2Mpq zj>hG<3U@oHzSrmK|A>n>%d39T_157#hRyr!nXUZYGC2&7JS8XM5^UM3{;R(#kIs>w z{Z0GxafxAbzY~93F4u2Uzt?Fwd%Ij}*nA#kxYZfubvOz8<*MJ|ta1mA!KwH#F5aR3 zEyL!1%T9S@h2{frA`Zj*a3)^SUjKhS_ir`d^_=E?@eCY}8~m=k;CuBe44cRIE|9zY zq1+$4SIQ~7m8al5527154%;%4*Ua7#XeV*S0B~< zS?u+b9Q>DZ%P~0*hvS)lD^J2t*2sBy9S$qi{F7Ie=bx0j{3E;nBKusE1Ipy>xbl=d zwpP#2_N)A*Ve|R<<8IgG7<>w6;O;k+NB^ezJ-7>hE$8LYcXYjeILEMgyvj2urgGp7c~~>K z>ZV+0*nGe7tdoaYl?UMcI2Ok}pga>hamK%z@BN^1d%awQbFj}t$}8{=?6{+T8xQ4a zcqXpG?V2n1ysQ3U9D*ZTD38bYx0JK-cpTi|;d}pmyc*{;l26*yug8TC%l7+}4`?Nq zHI{!jY~DZjCbDm9<-T|WcHlry<*7Isd)%-27HyQrHia&Xel|XV%WyYu<%zA; zfB12^1pkLEZIq|BSMG-o<2otfHuXNM%^y(^qX4rhc z2*h4?IS%i`S-ABR%6;sb{~V`0DX)4`c{!f*lx+1=eiP?+moxlyK2^BVuz5c2J(R!P zT@J$aI2I4kLTdpe#)mlP2OL2 z^p@iW$Tx5nemX#T@^i|+#Wh3Z_xtF61ck^~44d~O93Of{P8zB_w69!-58Bmk9%4DtA@?@uPp5Qobn>P0@vfm1}nEmXnrjAcvU`x z<0IvHL$tpbA2)11uX4O3MD`o2{$ZRjUhX|qx$gvdzhU!yBXAvgJRUtv{akz=SKxNT zl{;S3z7KKnBzbbE_Ipm2cN#X&*NzuFFGs$v{33RrBF}n3^8q;1usI)rZ{bwDWQ6iU z{2k7FL;G&J@~QHKF!cjtVaWJEzNzkviXc{E=bve7$BUcYjF^ z$DiUPT!mw2sy{Yd{qouJW23a+9w)zJ*xVn4`;C^<@CuweNByffGG3nhvid3bI4;6t zB9zzRy*Tb|&ELh@IQ|v&eda3Pha+&ntIA99eC+;?`aj|zd=@9-m&a&63-85F+$&Of z1>SYzVUd?doPgt;&7aX3-Cc) zh3m03QS;p$oDZIly%sCqfn#yA3F=2BDPMs7mdPzADlcCymm4~EmnGY0svrHCyb6bYE?>odo8^~gsc*}ccj7wSb++>I zEy~wnzpZkgIOPs}8mHogZz?auKjFA-ntyJN^0Mu6BCf_?V_UBBi#QZddQ0>9JCtw3 zPTV72dHgQrn{h6F;%()A`O25zDBNYP@-+MwcK=@ezp-zDJm(!f-^ktaR>S7=O~5S^ za+E;)t8aA(|9KV(%+YYMVbqV`%2ChAPNQCwajzrITQtmouU4V(AZj@z%6qwx1Q4d2D~KQuoyRsDcUISmJ&m(SvyDtY>Q z9PdxL1Uqp5HOlkwzqk_TtyONjr1>^!a{S-&8tijbesZ0zHylqhY+i31F2gxE?tSIu z_&XeVP5bQYl^0!?e=}@;zp~ws1JafI;)^%|_t>C3y-xjX9DGam*r+@KC*ykjGxoc! z{tF+dpNlhaC2o_UJoS$H-x)T~w*ucGx7<}8^P&0y_<@h)6dZwl8@9Ul_dkE&DE#ur z>LNN`aAKBnZ+FdC z;-m-UiJvL=dq{TsT=y#xhZr_rKbbfmm*H18EBE!#{I9s8xjZRbd5BF8+oJtB_>5t5 ze<41&RrYM9{?ISvbew^mxM_}Z@7C(?!(ljaoAN|_9@lwseqSmNeN;Y&-P_3#+m%P+ z?{Lmz%KPUkw|mR$umgL1rMv=iqoi1jFX}h2u0FjSF!cZo5nU0vv`*@EmOEqT_vw{csfy#!u&KUkYA; z-MVW25Dvs{->M&v`{O)36IbH>xU8G@wfRoh?`xN*V#gEm7Q^?xUhyI9#C5m~PyAke z_a`-E!kJN9@r{`_E%99Q331Md3GbJpKS@<1%c2TKjtM)qEsgg0t{Z zZ0oIlnT5ZB^|_i4T=K>MN%o7W%ENB$1SJ|oxB&&6%_YrY&0!BzMx z?AcfIS8*clbU?>T!=ntF&od7%!o@fnm*Qr{>bnJMe<;qxD{){y<&`*~zdZb)jvtL@ z7&ecefHQI00QL9aB76?l;;=)S_X$#eGfu=uaX$7wtiJa^_1`jV-hY35h&&v(b*dkY zC*e5!87{!pICqftcR8Z@Dm)7NJga;mcHqx(D!y#kJiiM3)KS^l=`FKFMRr_{IOEL@Mhe^p)$_vAlzky3f$u&4`v^?XC`nH$l)@NmZybOoo2P>4jMX0|P z=i}k$l>5G-yaGG$yx*0l<2HZDm3RxT$Mx9$s`gE+RKI$RyaoqG%EhjHtZYB8=Wib; zhZ{DZe=y#Plkk!Y%JXo~i*h->j6=t3Ut*Q=B>d=~asmDpyF1h$dP%uA&cI=~;brB) z6V*SBB`s`5&_0as7b zz8?Q5_nItc;WT{5u=#$RGF5r^YjQ4*!cLrR*nD2~_yT!&jOIJlDo?^8xBz#&uDlwb zz_w|cPrRYrAG_a_tMFbNFUY;!U^;C*IM#XPo-o@5({=H|)R@|5I*zQ++Q>i+lG!34enN z@W=+rYjF(@nxpwe4V6dWUvM%W&`5duTk2=vpha?5H|4Q-F^*iL{JdfFex%`+_o<(U zrx`Z$Qk;#m*K7VXuEnhzs~?`OJPgOBsvLw*gre<)k6%H#1GoQu65P+o<% zVgHXb|Kx+pL-7(E`?2zChRx@Z`Hei&L$1Nso6Dhj%J;R9Q}IHZT!DjI$$>l6KiXPO z$7?<15**b==V#lg{%IVHLmpAzvq<^IwzAtk`IZ+sp43i`#G4+IlksV9IS;pKFIV9i z9b}LF+JDSP_Q4*Vh-E{roc%5B&G){X$&d1?T z%1->^Q?hrl_C@%~@z~m3`!jL6Ve@&HV`mT9a!~XC>nYoC+g@@w9`UrCju-dV{yN+> zK=wbx{lgLX{XWXm@R(<`FCSO+m9q|OerZ2)>^DHJ$6o}=zE1Uh2Fc<0qi5x0+~YYp z7at!i7vT{hay@nql|7DV|A66g0A3v`N8xkN%kkKEgq(@9!sI;MdZg@rRQn%#N%tob z?=oyYuUOo8l$`GJXt@d>!1Z|F%gV!k(*7e6ayDM{ijG%;A9_`}wM6~VV`M*E94Uw6 z*5l-496esnz+XD(AJe`)6Lh?6Jb9w>0^IO5*?L@kJN9uoN_iZ&J^YLQq6aMLr%o=a5kPjRe1rnPLu2L{OPjC3GMr5h8&J3 z&(!(l;s2GOY$}gG^idUYG-!N=`Kdi_KdZd` zJoS_CD>xN*oUgnP7vU;AZGrNL3hldwQ}Mz?<;D2Hg|h9O`k&!IT#w`Ms71QI$UoFy zX4t$w?@D>>VmS;K;AH$>l5!{h8(S`DzSR=tRk$y9UQ|90hgHe%<05<__;i5X_1C}YT#e1>WzskofS00E@;u`$o3gub1 z)c*=c+?L0uC@;pBu%%x4yp_rW@I$NQB)kr1;H$X!j^^K3t>^3Avh}_HURjqa$KsSV zvJ=Owl|5|g2dtAFxY>HS0DqP)dp@lG+zoOV9c3M?2`-erTua(UR5l6J)`~o56OP`@L@R`M;wt8@NY-uEZnz5F2Nrj zlPhuUaoO5e$4e}gy>X+HavW~XSILJO*s)ysAC?7|10O?W4GjL+_hfz z4c5NJceKy@Il1p$ITT+rY`(r6_}l;FG`zsl^4{ws507df*WhjqW!qrwugAeSvyt)` z{DPZYj!$9R5Y5Njr#uwj#p!rsW95bT2Cl>5O8o7*2W3+i|F4g=6oRBR0d1*dn znVgRc@W4lvSL1`&Yq|Olv{N3LBENv6SIVE_l+|*J$J9@HPu`F7@LX@@mH5fWW!oC{ z&*5OauD$X&d<_S$RsW3+%5&Gr?R?}4oZUwMKHh7+@-iHQzj{k~0Zw4P9Q$?DK5M$> zSK<5&`9B=>k^E^Vz2BtaONPz&mpuG@XSoDl#g>mXKfqUcZl?SXuD~yJQSSUy`BGeg zJ-RCQ$WlHEhkY)u$B~=mD>#0OJhq$WW51AF*yT)o0GHr|CzM-q)c1Q*_QU6~0|!4v zzD@mqu>(i=DbM&)`2*c$Cyv4K-zfL)p*$PU!)ZH}e}${?DO`_lVfS6?`}fqoKs?j1 z`TZ~*?i5Kv_;s9*7aKP3hxZTaZwruP@$o)fKOXmtY%5g1z_58g z!f?C3%9HTFxDfmFQ||FU%@6A@N8?TdlsLnhY!;6tMJp$%C^1gKNc(p z;rpM{d>pn8mNRhMA?oL1_Yk=nU&odr?LReCxi1bJCWqrsa5R2oxbh6V8t39`xC{>u zRlf%JeqMIlr{lMMLFXTVA044Q2mgc%arZFwt8m{J<$(R#*Lb8HiW9H{C%vRR55FHS zTMuY{)F>U_AOD48@aWOXtMGOlP^@|Pmz9U&@z{a4;~2aqLj6=+i;Hl?E6U4ou3_`_ zZa=8w<-V#s2!A(5c?#|qsXP;VkCn@Dqj9qRkoN7s4*dFf?MuXG44Yps+4xxp`*1q; zJgj|Ja0uQ#LHz{0a-#NUxcr)&?9_Zl6gl28N%Ix>lgYC6i25sDmjm#eXwApqxl`mc zy!;LIvvK@Xxe`x~k?ZjAX|nfG9WP+I?2jLv!TDqFSmovTXT#?6tHEbx%0WMA-_}`j zIR0j~oQ?O#$(9oJ-+fd2eX;i(*?|*rIgWaZ`D2=&6tBJw$G*)x4xcM$;DC4JYJ3@c zAJ@K*5|jtw8S~^g95i1}!*g*q-iGsV6)whJ3p8JfM`O32b^M(;8rR@-+%-}2#W)Q+ zPHO&V!{+k|{6!wJQ2oR*xd3P5fJMrkcrLESCvp0(njgGa{UUrAr~RhX<7>IYs_e;Y2lEMLdL)pGPo^~E=b zgRg0R!aC)3_~G~E=vw8U<4inYz49{r3--CL{%h&V1M$~52HQ3$kH4+{Lc`|QOWJ?( zMeJemy!ZF@Asdy4;oXMK?;ptxlsEW5&ckK65--Y7Zf&Uk(;vzS_yEqsj*paA<2oGB zNb^Y_D-Xjz<3!vmQ+doo>RUgNGw@DagvV}DUWv`$duv`_x`*bce=55-m#^R;9G9g$ z9^b-6uKY9Q<@hUXZJ~V)K35*mUVagm;3L@5LHVPb^*l=Pe8cAXMs-xa7sulU*~*jf zWL%B67&f23rIY3_kbC3Dw`krUkHSHC8!pB7ZB;+USNq1|vTpKm>~5FWf1!Q=ekwl8^*9Gl_(A=` zVVXC8@2YuyHF!j!95-C~Ih=)i|4+F!RQV#q=GUh;K0qFXoBpVNI3A20_y|tLoA;_; zh{KEIDqN4UG2g+sCZC|_@QDfS)5`4~2zXVe6_&rfnG zUX5)NmEXYOcx;LKsdx>xzNY>`9Do}f<9K)=PQqJp4!(*@@WkVqPma?5rMM7(k8P8b z|ABq6+s~T!$9-@V{t~C)$4k{O!lQ9H{s0F|*72_3Ox*K?<`bqUe+}EF%lmQR3_0|q zo>vWi)3Et`JYtm}!XY^97v=Fd5vR>o{}v8zxDby&t-J=KYApU*T-rzfyS_eiH|+*1pR)`#t&V^V(mBEf+LzU8DQ}4qPig zby0a$n*5z%^ZGs4$yMY5cu*DRi;v(;-0)B3{_8bA00*VZ2{?3v{4I|9K<;o!^Oe|v zJu{R$aXM~xS$!vt#ql4hUuW37o^0HqTK!@?7h677zu^_-e%K#peyaQf?EbkN_?Pxa z;3bC5=NW@L{Vf;b$+&il=8xdGt#XqZ^|SE|Y}=;1)m0rY3P%|>j~9=d{UbYZD6ZPB z`FtFmE8oN!`1Na=_xeitRvd;Os#RWshhVp_)jw(2yx$Su$hPb1$KZ7A+@<^suEFj% z)c4L;-W`YISvV43!8PBi|He(t*MBEhVfO-gQk`N^`L&&Gakvi*?qMTX7i>v33iyHB|T_rak~<#9L>e{0yB zufq>F*1YwI`lE0HuE802Ula9xj;jB*IG?6+GJdp~>`|h8I}XMJ zt;*x^E}Vmd9#HPYO&^rQk7-{iF2{==QXX|&c^eNo9p_>v?$%tn1Ja7nk7%t+lTj=i&Nt z?YoY>Ps`ms)wkncvG-Z!3)?8Sos;d4$d2FTGMw{=ytu9Mx=Q&eFFE*vybqUG$rBz` z9(P%8*G?|1mbc>y{J>-E$G33$74Fr_6@M!q+(AyNk^hIQuF7FP z%H99L9p!A7JINu}lt0>;efSbC#PfWWSKz5#m_x}E~{Q&KY!0jyhd`A*~jl2qP z!R`$;f90Mn7GLZaq~k~77w$RH;@e35G@O9Ta0zZRQ0G&R&EK15UXQPv=I7#Y`~!Wz z`;^}|i1#DxYuKDG!7t*B#_BKmqLIGexXY>ca^wB(e%VPs1$TT_=VxuIe9AprEXg>J zJmnGPZo%r8;y#AW_s_Jp%E#goeE6>AUT*bL-ryZM5-((54nD+u#G~q8BTvN3f70`; z#S6CTdV|}k|MYV@za%^xyFI4-I~Y>i!4fr*R~no2=ijmVjNqZ><azZEd7vp>!JWQ`2 zC;n@l`aYf2f5o_d^ZhUYZ^TjfG)~1&3{$@zzk{QFwQrwc^YxwCMYaxCKM%i%i}40* zx2u0&sQPI*4Cmtyu=>y0 zBlgweyV!G(@&PaF{)9a%&ogYk{-W@=I3CyG^5@ha6QO?aV0jbH#g(`ecY1~X5cO9Z zHlI%}-i_;UJ$-A4`T?(M-WyNDcKjud$2GVf_ZXvj|DoEq3`gT1aTdOfOYz7^&DY`2 zuyvUBUBJP(-B|S#@o1cj*Ws+;n!kwiaf@-9w}&c^#tys(C*eDW&HGvKy!w5{YrX`} z#+5i1hlHu$+@XFJ9*sR-RQ^8p$0uEV+;4)8Zyl-r6dZ;>H*CJX((nTl<$T-;`@E$2 zNjMuX!DaYI91*U5!`HO03_pcqM=5_3`;3;$a239RJzrKnE{gNRIXF5(xyK~srFa&0 zdqw#!m&eHUI0ipGS@$auzhT(CKbbfK=ivjm5Z}QOk=oz$b^YxmI zHT!opWdDiUpVvfxzKz3=U6PaWN?iDw`a3wDB})Di+iW59zz6itS{g1-$lPBThI2|{cuK6sy1efA}vD;+rkD8&rKi-0~@D*%*UHwk6 zIv;QRiedBl1mWd49Oq#N?mScdR6GT{M{EC1oQAL9Z2agf9X}7hW!OA^F+Pmza4ima zL;HKqRzDNJZrHrPd3YUpDgGa>!WVEY4vEvgxT)IzH4ciA+otjJ(lq&&k(q{+8xLXUThT09x zeihEc);a2X&r=?YH{)#l)O?+9InKnsZ)yIa1)7h;3k;jrmy3VHW%$`d^{cV@dt=S# z=N+$oCk&hO{`jedawJ}7*zCvRa-4-bEK;72*Wzk?0{gtJ<2|@oeFt{^{Xi-nLSBLA zW3RcI-+@E%pd{@}#z$}lj##4HiT7jwcetPLDv!aVaTfj>hb5@rY^nND_(hzHH{dc{ zf!*e5zEiU118@wE!+AIv*J8_j&6~d$*L)tHcqIABvOTSHBn^#~#bH@1ga|-ImLtI1nGl4m>(t{Uls~ zt8l*!%Dq=;-*W7hB3n1=dIIoVoP;kJHm|P)hkd~Huhje&?2jMJP(K8R;{?3Xu=#$R zim&2)SN}uJJ8?R;tkUtyu?-LYh~wcUI1zu33-DE3jXQpMpU&bD5G`|rCMgT+pPH{JOQWU z4D9*7=6}Y1xLda7qwqwWk2hei^_oA56YL^CQv5yk%~1Xa4#aM`nh(K!a6JAJXX3}d zQojt3#cKv;RRF?8+`USZCaQ*yj|4expPQdfA z6Mv5@a3FtQQH#??X`jdE+V>jgX+go+3mXgp<(lR=HkxBIan#@Ph?DA9;&s@wMtQ?ulqdcpzl|-|v4?o*b ze_vLGXOU;uYQ7vh@uR0SAALjl^M=jmU5dy3D*N74KIJz#3AZfQd^rxlmOAy{#3A@I z9Qd#D-wd0_i^b2J*1iHf%CMPN;PcpeOY@!2s2_&M8aDgMxQILhr=L|`j}t32?{QoE zhMbcF@d})V!+z)daH~J$8hjSJ)oWiyrE)vAo|hx=d>n%>;xydug8GH{Wn7B0u=^by z?+W(99WQD=7{7=k@k$(v_v3VIsnWa?cgJ3Lb-an#53ez7-v3~nhm-L|`Wd+OpW2^` zgKzdnq+#=X193G@#(n=$ zo`IL(T-@@Sa!Vuacj64(v{uI}!o9K0P5mhBi&x`7{0$DlGp=i23_gQ1@rWDB^YAWQ zhOc1jeL8-}o9cVx7Y&>DBMvvNQ=W`388-7gJnvuS#kkKcxgKA~!Hspi$lJsrEOuJbdrdCA)q;F7}jNKOcLykzGF@r()O7 z#}(N1^ReF}>brg(4#uvZhaK4U-}mG2%bZU<&cl^n+BdYRp1=R2a;o8b@87s%GdTml zx>ui9s(MWQEbQ(rkD>2{U4I@6#~+`3MLCRg9m&nDBKcM56;GWp$S@nnE0340e@Iu4p`FamiznDA& zH+oR}bFmMu!AlL_n;))u*XIc$Lgmx+V{q(Reg2>nyFTwxi(Rh=+w+=tecr-FzGLb>bpAAwze zK8eAuuZKkJ`g+K~uGe2Kp2PXu!?gb_4#%B5biMI-J@$K1{Q?|~Yj6SfY|iTk_rc|O zI<}6~zCW-(9^FFoF?a<|!X>x@w{NL_$V=K6jeSPT>DcoX{F}ai7QHGrwrRc+Uq7wf zYmD;lzsrHRZ>1cDCo><5PvRPU!c(75@`=>G9&P1F?D~9p0{;KcBjb_uD{%09z5mqW zHV^Ck)5dE5YMhS`8aBV4Y~z%7Y$a!omzQDt1o^6A^ZhSwqCBRxoPiJHT-?u7dGu@Q z&&28YA}+*Z+NfWLS7VPT&ELh**!K~Rk4NGXoPZOeHNO?-;$Lw&wzt*3;3?|AievFI zoQ}W51^7uX&L5A#{%>esDo&4)_hQ>L`3?@oogZZ%4#uT3)L&@We12ZBa<;3F%W%|8 z-*!r&aUBI5WMMv!q!~<{)cD;Y4;UbG=3@*cKapZFCJB-utEnI?KpP#p^P`^tT?mwP|!?5e~^GVqC`T6Kn z&AUE7Uy5CypO1V``48-?!Pc&PzgVL@z_9sz9BXCQzeg*;?~!|_DL;WDaI0>bPh6+G zKMsCh-hu1a%Qm}?pSMAtfP**6uAfI!KajsMa`XHu@L#w#LwU0&l-oX**9_73&n)aq zUV%e!V5a)tW4BFm`zN)}`Kdev7iP&ZxB~x;vp-k<>QkDJ&6XGA3Y>G#7E3MumAqi9 z`nL_6-w%AgklXlaUli_t&&J=E;#Umc`~H!m{yO?K_&9yrHsz0Z*SoN$<#-VPey|?9z8<^|sQ)7U7+i<5vFr1+#dtWMuk|d}{9G^n zd$?%4376t6oWJ#;`d2ysDBNqw!xj0S7#z z`J`i-UxqzP<+gp5N1u{&aLE~YV4#lYUMat7*gXG0yq&z_yz-y1_XW9IKg~Pwk2thS zd6WLilW;#=fEO)tyLY^5yxhpm;|Khy`Qb~HC*iMg4j#B%c_DWFdrY58ns@zs%vkLD z_n1leH|EpvgcaJCgI#~VD8#Nmk9u6z{tr{skH*Jv4tD+dwh%WSp!-pcN8;RS?Q?y9 zbK-4lwBPTF@+oWOU|fkKaL+X58F=tIITt%u$wl}Jj$et-;e@|+yk0>%-=G@#m|^qz zxLuPo1}aa)_Cd1yb>-h+Z~W-9%G2>s9CJhcr8o;;z(qHecMjI^z3Sw7hRv^+aJ&Z> z{Hy#f&b%c@Kc{{fK7{>mEAKs6c}Bgw0sGvM?;E1r{jTh7*t{PJ_-&kr=e(oe2V9MF z$gTfr{s^|?G(KMwitie^d3_E%K15EypW}SoW~lN?d<=V7+TQ!`O@oFh55Wrzo9Ca7 zM-5k=+(7*UxCr+NRo|nba{KeLt&wbbL5{^E4V&kmiJOj))9zD0%&>WUCr%=-z(;UM z6ZIbs)4bhXUXFusB~HVgUR1vjPr%jqGiWAS;I0e6t%kcqRgKrwX_x0IK``e6?LvX0!d*5Gh0(lO0{d`=A z50RJRh|${TY1Mw$&(|^dck)DRjZnV?-!N<*zY<5k!oCNz?;H-olV4Ro9RFt6yuMWY z+!(n6zZEIlAJo259E9D*F^~I?mus+>L&x)cNb_&vP`nc-;u@TXdrr`NF@6nud1&9q z*bjS5)bXQn^Vc*V++6)7IH!eNhf`b1{h~AkX^!UeumjiNG#uSo`_AGN{LEXro%?&FfFY z9sZBK`;W_W{{R2qEQDT!5JCtcv>CF6SO_765Y<-OnVqXtn>LMRjZE7@n^=g2Ovr>@ zgb?D@ixA7p5JI-lXoT>29_Rh`?8mXj`=9TB-!7NK#r1eRoex_CG`QN0%u-94~uqM_>KLIB==@Uym0U zJMH)2!`3N3FkbatyiD;hyz_E730LECe9Zq;z6&Sg;ImZULY#=}K2d%K{s~v&iRJ2V zBYp^noum5pzD@n{Pmuj@mt*mL*n_9sp?DSExk7HiZMYL(y+U!nb5;KiE9GFk3P>_VukvTyt^62#3r@!S zu2Q@R-;7&vFAh#reN(Hb4?kq=9RCyX2I3`n@;%D0!z+!Q{AO&Q$8_L;dzIgby*Ts& zwg0ak?LSet{aZN&U$Q~2z%S!EeA!0D{V!B~IXDsD+N*f|#ftydl%pqd^3)|T=BPX2Hw3|pawlyYZx2+P_-yEAb@! z9m!><)a>> z{%hnlxCWp9xZa)M6n>bev zep2;i;8a|Qn~a_DP=+sED+d><{Hr($ANiEx9=z;0eqU>z@?Rw0iH~Vee&T$^dvNS^ z@R-Sn>ZDJNtJrKK|cw3tnsN ztdCCoujk~dg(^R>L+8ud8|B-GH{poql^<84csWkP{kRh6Hz~h)vGV_iBW{*sUr_%7 zOXatWo&Lq+V_sCe@D|1IH+JIHc-NQYPMn7)Em8hgxaw9ps#*E1_yJs3rg$d~S}G6X zLA>|NDj&T}@#C=v&%#}JIZj@#{PC}7c}j1WXW}Y6VC>sI_?B1Y_&b!pPm9Vou9WXE zcJjOMUa!fCcPd_i3oGRha5diRb>(;9D{v2f7>C}a@?RJ`<0~15ydisW8ZO4WuG9VF z3Ou+%ODbKZeEa)It=RrPlHWaw|8}?D4~fN* zU#UOI_?wUPd@vW=_e08Uyj$@aJU?hB-}1NMKYmnw-FU)Ja=^W6KLdy3uW=HN%2ItL zIBihnYw(A^DBg{~^4Gt|?th=^&-+mEaD2h@|MK-O4$t0J`33kB9ABgIiQ6e&i*Leh z_!-=XKgF>Rs{BFQt9&8;1b5)`S^vFw6;6Ig<^O~0aMDI?f4_$nPvQA*7``6I;ZYK_Xr?J1YxxA&5J@Esv?*rUq-`YqL$fg}DS7vj73RenaD@_!4J3vuTDauW`| zTjRM0uf{Qtsr*+s5kGK%%2(r0!sIr*_d&AX<0_wXupEKk4VPnZ(4lexKL0Se6la{G z^;?g}PnFl>&u|~UX0?_lMkt`GpTEo`V0v_4v4l6z{|{u-}s^ zUlO7IC*W5Om(%bsN5~EM&G)o_2CP;26_JWZ;fkZ=V!ZS$Eq?`0I$H5se8DmDAWn{w zlb%xjn=e)QBHWTJx8b#y$)OF(Uw*k9g%@8zdAx0kTyFDm4PJDm;{ABxRdW2(^atl+ zzcj@=@IjyI{od$jl%IhU@Mq+w;i>5=Ux255rt<4?ANyY| z$NgLNt-{GTYnI|w_yjNI@x3_eIhEgbw&F>61unv;=PF)~-@{3}=T-k+ zd5U}SW&PSdb$Ai(!t>j7eDiBk`JO3SKfUC_}%DFiFG`R}jJ5_GS z6Hk{1@Ox*-fiJ55^W)_>+;*0nj88d7F2>6fd-s?g+@g=qY z>_u`7-tJ<#&H55Kv|0IY;3)jsrHYr}|0c`p@h+Fk{x7TiC0EE1xHUyizO0OO zd+c{=q z`?lg2-$;Epqg&^<;&&9UZ&ZD4cpdS8cEw-+x8h#>>pm)9hPQuP$AdaNP_Fg{amR-$ zpZu=s`(d42kApvw2k{yl`=0X4ZdZL3c*Q$vuMaUV|l zRdN4MR6hPU*^B)LU%#8Qg}? z*-r6(y!Q@rz~`#32FKxJc2wMhAH}tJ{7#B@<5%C){vG~>>g#?{%OCWmd`Gh!juT#y zJ$T)#as^I%O>V{;UYGmvvQ{~?TlJs(mK=ru^B>uRlm9Ch;g8>zYw(nIxgFp0uH23L z-;)EsQhUW6au^=}p zfxq}nPQV$T%enZ~FXS2=-Yqxc`CpOWqxvuWMsC69cd@^GtN2gEWAONIm0yNCa5es7 zgW~=8w~cbb2Gy7Hom_yo{a$XybvS6F@~`|s@eJIE%kYbRidW;AKgwPB+n?lqJbSYo z-K+Z32jmKz^s8Kp-~CNqkB=CXL%w7E{3!>0FaP^5ISwa$r}deE@5Uwg_+G_pa02}S zs>SyEPfgf z+wT(xZ&rWo_lYC0{eF5pw%<=L#xMR(`*;HXK3D@@h5de3{r3Cu!PtJkeG+cCQ`c`v zIITm+_W~TeCP>#Wexbhim#c|);p?8){iUdJia&tU@X<|*ugA5x55JGYwo&=%FDSnX ze?oip_@EEeKfm$HKNC0MBHWH&#$o=-{}mVG{Xf+6g9?0=vGaVO0axItZB_n1I1T@X z1GZCq&vhyviKpS3AjQ`hJI^~jyUOAYQ*;YL;-s!-+rGc4%_b&WnlY#q6TcgKjgos%J0>w z^%H|H!u@+IUSaI4pNxHFyZyVd_cT4voD{0K-M$&vj=vUc$6xGz%74yRzn@DPIN&gO9Ztb}{!jHKMksy(PB~nz#QsOfU*Zlt z;bX0zNs)@@8av}P7dH`aIZE+v;#HGnyFC-8$aZ^{Vmlscu^kVs*lzET7?ro%+k=O` z|Alv2ul{x7blh{2%0Fl9Z11*{<;}!PPLZd4qIm47aw!fyO@0MW!oL|i>mvnU`l;-_ zT=@;y?+V$Dry9JDcnAK~=BFtCfX`H46i&g#_#T{mmGbTPm&);fiFaW;Uj0**Z^vsf zzJu{zf$j0K1>56gY?{jdLH$YCe!s4%K=HG>)c-DQpGSqxQG6-!Slo`wu|2;xVf+2Y zz_}`KpHD{MA8ma&^mDbJh7)lCo@VSD4|p~4#A{W*{r4m@a4Y#GcoXg^RQ^6+sJ`TR zatbcT_uwwP9!Jbq{vKbdd<4XfhFzq|*$G=?pcjGE-k3ZEFirewk zjC;usS)sTcPm$PezXWWzU&%`4+wIqagT7IJI`K(3^iJg$;Hpab1sr#mykn2b2j4B9 zk26-uc6kbMzKJ{gMf)u_B(|Hb$o`qz%X z!)XsH|L||MJXMd%m*O^j3-+&5+#U~Wu{|EQVS9WW#P;}D_?XJu<6{}N$HyjYkB`xh zEB|TQPr%*A&c8=nj_vhR;9BL|>)%Kmu|fF>IM3J_kEOT?7d)-<_Wgni+)um@hiz2( z;%Ag^-#=(>lV|%?dh_k4F(sRnc9{W8nSK=;g$49~oireww z#ddr(VLQGCupK`kFRHv9KOWpldyV*aT=cT?59`(XhH>fCun5xb6+*+wXsOw91j+tNtEr_t%iO6rW8z65obnvE5$-KUIDs z@h1EuPU%wo_#f0>M7KPnPcFdAHp$Jn`A0eQE9KYxBp2en`{fpVp0RU0@%vi&Hxr+P z$8T1?7vG8-@jX8)K8T6R8<(Q4CfBCj@F0R~8 zuEdXRFW2EG0_1M|&!#Cpf_<8LAyXyPe*jb)f z9D20Mr{Dx!hl_ACe$?10-+|k3*r4kFll)2esAE)rJiZtw;bLQ_zFPcW+=O$YRKEBR z)&DlV`2}j}UaRLsRqWm=cIj+EIF^bpXZBLTB@fzGSUhVC0vf{!1^07D`-;Pso6RyNx z;5vN9DXPzZTh&*MLvUuS;^p{FV`uxX#|NCMc*u4tpN(Vjo5sHV4R3pzT#BzScD8pD zZpD50xT%Ts34&Ct)vMWbE{( z8QagR-MDzR;{JQ8zT30qXuK>(PQgoa<#Igd8o34EoG1J3rTT8lmm~3w1#%)@I7cqQ z_Vafmwx7Q{vHg4<5u*C-=j%e8HCOAS72Eq+UD)2w3fV{H?ftA|yxf#`)|VIC`?=NF z-Y;&%t>mxAKjFv&RKNW_w_0rP_w-}?`)(m&%HQW&wI73HapQrCUx6zQlCzDS`!{Xa z-oL4vtavN=ZTJ^FfDbHGdy!L=Z|}dP;VVqsslO20``w-x@_9a4f?ub;4s4%C2254{ zM(Rt(7wxI{!%E^5x7V*NIBuT$7k;|pOO2iWWSk+d_qo`w>P&h2`P%-Scp?stSNvL> zh+oE)IQ%-*A8?`a=NLQVVf`ht-F|_W%8wI|!aw6;Jhe#W8&Z^SzhC5cm2AJy6N>G4 zDZ;ZU--_-2(LP<}?f%h+?frt-48`sKUWD!bQ-$sR(~Irzzr|##yd9s_*go%W!S?=S zKeqQLb7!c$ecoMy?fuCHZ0}D-%~bvyW_g|Kk2oB-KrXYshzBOKfJJ>u{x z-uKAB_I-~+Y~S~&#P)rUMr_~rXv6k>k6vuw_Xzi@Klb~4aoB#pEE(JH9~NT!{liLZ z-xq1b_IYF*w(pOG&Q^Q&{Sgng@B0*C`##A4w(paKWUIV=pClUF@6RP;`~A5VY`;Gj zlB4qW`;K00zdu=m?e`~}a%pdSy)QC|?e{5zu2I~6pE5pAw%^Aq#rAwwi|zOE+HkpV zfAjMj#2*_w$HRf^RNv0mb9^q6&&Rpg9?zR_8S&5s%6||0-yqxf9U_Y5eQr?wh1foi z=*8y|4_v7HA{>ifwO*w7=ePv#QLOqsixs!W`!YPy#GT_&6P`wX+s(?i$J@|S`3>U9 z*q$#Nust5P<8P_I5AVBB{fW9o^$k7WxK*~#Lk6*Z-Vt4mHDo z`D}jgf3@6BJf=qe*4P<;ZTPqn)i+S9_<6YS5jopu^E??Z!-M#39KA;QJ1tiK!yc87 z#FKCWj>BG@jF(~$US;gNe!y@0;^zIQ$5j8eHz}U>glw-@L+WLFy_)!>Y_C_#u{~ec z;8RR}&h`yhtNaBx1V4u(@Xt6JAA7UPm*E`Th1cLoPpSTIa1uVaROJisRk#9QZ|tm( z7HpqSb>e4;58#bByg}_9c8kgv;6&_wR`Hv0S)*KsgP)T>#^Fu!E=yEj1wIM;zo2*? z?#FlG=w`*+jh*$Kf$j091Ka(-;}zxG{kIR>=cSRaD!z&O6Y%mho&QU)Jzvyfdwdwg z_ITuJQGND!Q-kgP-h%D%KK3=`+v7{7uHr{@sWhaK-1u zx6}LKZC}XW5%0tMEm!%dFBLxvC*maD2P^AV{Ht>QJp+95ZSwlB6kmixzLxFvUnI7l z7mD!rD^$J%-$eVJ8&v*5T;40U;I{ANy0cV%pilnE_J5N+u3XDki;u*9KP!F}_Ww;@ zY~wrZ@4J7#76;=u&sBR7*#3T0WT5i9$S=daxEt?woB9*v1Fw+gb6+xEWu9 zdvPhtAAFwjOHJGvPqDZK7vddnSNq=cm47()B+4_7*Yd?(AfI94PJOxf8eE5~a1U z<1~E0-O4Y(vv56b#65WYD&=>0RezMR)4$Hyvi%r9K`niLukJ0v-cm8@aG)Q3b6hDbPKLF z%i}C>aDmEyu~47KBk(80W3c~e+CGVR4_txm{i#}P?_YIbd%r4fj@q;Lt17U)U)7E6 z{i*?M?@tBJRe5`VBMhH%?|EgfCV+i~K}0OG~j2bKk8=MU#pM`GxrV zOZa`-Ta}+cJQv@OoA88(RX(Up`FS`Te~Sz7C6}rGDtvgY%Gcw#D-`!zs`?%x9*mEF zMEM2y8QhGIT|UN6G-db}KOH2rhVw>9|CIyvkPmA?dg@J+ZLKZ_eyD8F%) z##;ye!Ni^8dB{q|r#>cU;1BOnei^p^9%(gx=RU=|@%K3LPStm#sn6+uEPeueD;0ki z58f^RLi>|e$xl75{)AP@E1!^y@VWJ>e*iyh>@3fudz3%nNyXFfTgU17TjafpCz-gD zUxb^FSG*p7aDv=|A0xjXFIubmqwiCFkx!|<4E!8!#K$x!KcHIqAL2>)`lnUigHL%z zF2{k-s(cN87O%(C8Wr!u{{NOk?pJ%MI1V@AWIX;kwO5Dj`Ew9oPdw-W)ff0Y{l!ag z1KzetasSoIUxJhIbGR6v@Phi=hCjz$c+rchFSYH!u z#GUcr!EX?+z`Orf@g`h?`*4e~vpgYnYOjlU61Klj?!or=$s2Iw+p0gfUgZ}@==kFI zr2G)^Wc(Yh!I!+F@*Q{s4q2=6Cr7HjSe(_a{3P6iYw>eY%J+Xt<*$8L`5`!ABK6^m zj+K+}o0DV@eunZz_&Z#W!{1Z=-S`R|(xCQl#|ijF+>8Ihp-(IS;P+KuJWj)fxC#e7 zqx@zZgM0CMd{l?(3w&1j7vN~T414ff*soFf-{VNU&j+fn4PSu=@j@K&Z~BJ|@h{l# zImLrNRDEGM7B}OCxDP*!L!VdquZ?}j3%vU}xwuL3Q*iYQ^3oHveM4WAvnI=l_!HcR z3r%@v{|b9a`BgXpe?k=Uk7y5vek@P@MCEhWlkczJ^Y8dve$d37?Kz0;zsE4?3&p2Q;(8N* zOMT6FpHEf32j7SzzEt@>?7``uDL<@R@fA1`@7SeyAzpy%@sqd}|A~9C{rnjImFkcA zT=iAsr*QJuihqMk@w6|LUynb=J$RQd75Do_<)`6r{18sTdvz;6xJUVAI0pZP3vj|$ z%CE#ra62CNwc@4Us=gvzk2m8U9RH2-12@n8WbJL4-CzlWRf_#Tx{-l+2X;c`3~ zH{nZhFP@Dh%Geq25#Osl zd%q$H+xr#O*xs*bz-Lmv6{lnWA5`DTfO1!yR}H z_S>ZLU*br7+*JKuYBKJ@b=clN8Nl}bN#KvF?~XW?55tpAmkY4Hf6|2Q{gZb5pFefK zt{dC?CzF0s{rmN@eAqtk&E2ec4)J#UBJRe!e5dkNKP!I7n`vF{JX`}p@O691G>H2Kc@D8lynSS3!P zz83rxj`&OE?fOZ>n~1N+NB!jV$9dFvfbV%@lCjfX9A1i>aVz;9xQ}?qIF&!LU-d=e zq5IYNJQH{7@5b}V586iMSNdG+myCbMML2k~>hHlxKAZPP$E$oT@oInhQ{sI%;%Aj_ z*-r6UKAX=o+sn@yJN@g$zhX~-;>Z7@crCW~zq)o%{ALq(j(7doUXLX0sJPu9i?O}m z--+%0{`j4gZ}0C{V*7cz4i7!A!Py;pezG3h`xn81s?R=eiNK$bABpXFNx=4bQ!BRb zXZGM*58{19Y@ZK?{!8uI)CSX9;)9SUz6~HTeLnJu)Q7$*;D!UdL#qe>ybkI3iX%aAMtwp z@+Q?ExtHqu9v9(9IDWKY`}{m6MENHS==f5G^NpS3Nj1KDFD+jqw$C5iuzh~lh3)e@ zzr9tzeSQ~)?en`y*ghXk!uI)K8NQqTHSMSR8tC63-uqYeH*9~!kHbX=$mijD?7`i5 zK8_Ak{)5KO@i_EA`6c2hxD$I1Qv7FJjd%Y|{pr9*;(&vdpMX8M64!+*-i!kek@x#u z^~K-?*oz;){)a06WgK*vJb6&%V{rj4!tJ;lANU97BRt#K84rOGs_$VOhdXgG-r-M` zugAAx|HD<@?yt#s|G$*)#ks~#d&PJ;uEPU(J-*0qFJFGh5vu<_T#UPno$XnQ_Z_GF zT3m>`a2pOiQuT#xqx=M%h8yq-W2gRB+(NtuZ^DCkukorcAX4?u$D#N`T#S$QSAGR9 z!L|5(+<^VIRsMQ>6!t$#?Ol!|@j{%8YjFvF2iN02aKO>3@8Ip!-Xwe#&c#)@8n45h zc!%v(KKK~bHwDMxBAkq$!7aEKcjB-B)z^#9#RGUg4vbQJ_WB|OR}+uK+wY+IlJL2> z5I5nd399dN?7@5NsPawtB;1a#!t3$vIB=rs+jb|FpM>XPFJ6O7@b|b2#|El={IROf zULS@ZFW*Ew5!>s<_{oaf>&0qpuNQ-+C~mK})3CjMtjG5Hu?5@f$4+do7yGfjUJQs) z{m;<9Ks@CWU&Up3-`!MSHC~9D@Ugqo-_up!6Sxu=2P@u#H{$R!lz-_S z^!H3TVo$j*UM|N~XUqHUrT(_zvy7eNZ!cbr!_QIv(IJW_;pw>dT*a&Lzi0)^kT%vsY{qzbvabLx| zvHkquf2s2A^=uNpkbDoe*S|&Bem-l)-}(Aye%}Lczpwh=hjVdAvfBF)N8*!1mEVo8 z!~T~k|6Lq{PufrU(fDDUi+9~$@n$^L*x7%|FIRnqxEVi=`|u|?@(SheZ~)^SpNK=Q zRD3orOqG}53VaVPNK^a?9G@<~f`g~Y>u>`876(jMe8(`BCqq5~2WHAw;xK$2uE4c8 zXom9N#^Lx&T#4=WZl9_A0}fRC-S`R|nx*&x9EI=4iB~KB6z;_zVZT|5|7Gm#pTRim zAh{6R@n4T?iAQ=>e%FK5zo6N2JPyc~7vpgJ3Xa8o;VPekPr!wE7OupraTERwci}@1 zQUCpN)PAzDGaiHSG8}V_;>|cMPu}ZL<#*=GGjLgfd@pXsoyN}ki@siQ|HI^}8|2A8 z`}su|%d?D~{&?^T9JWyLI-HDO^_4I7E5}{LoA53XsxRP1m7i+t^rr^f^K&~+BR+_4 zwdEJ7{7X0r+s~I3*nYn3!uIoJKepo~phWc@bGSZlm*6jOC${&K!xt;x-cOFkR~)7C z33w1!V|zcj2iyC}gV-K_gKkp&_Ie}@?;NSmyAd}l{yoc|f_FSz>$mq7#gD^*x5^jb zc03zrlqtU2*x4T5<#Idm*mBu!pUT_iosUp^EjS!^;mJ7Y4&~?Kz7_IaxM8LIjIq;x zJN^t0;(#L+kGNC$SK~zdCeFY|L@GbDQu*_66#f(^;!}@OekrcOo%lUtXMf1JTlI}U zS`Mj_C*z=d+48t_x~td$@0|UdfbgKV0l8HSAF*T z=pKB*1nr-tID`CJe7mtTeqx(czKVDXewgwD*xug?c|rO1{+0*Z_vagNEAlhN4-Pz5`8D`hV`q6g@I2xJZK}`S z?@sxz`~mSI95_k!1;4F$B#y=Q{&p9(_e&$+QNFz&nvCuJmtt)1k5*uNf3ySJ`{Uv5 zs?XjpEyebJX%)8jXX|mtySjhai6_1%_hNgz_j_0M$G)$4B2L3q_^1xW>+xdTf^YtS z_HYdje^2$7n)T;wk7)cF4*Np!y^mvjekEUoo3Q;n(Dseux0tvyKDw~I-y7PaxIG^i zV|zYs!}fgKg&(25ejIqb>QDYw_07UX_)T1c!%t9tBVLGeH>mt`xEz0jD{*`@vGtFYu*!tzVe$`E3dA!H?nb;}q}2r{Qg5 zRR2O8g{$yIc-L)Iz5t)Ri+nd;i<@vS?!xBy-9!EN63@d6 z@oxJnZu{FEDi19WUP1oX*zT|2V7q)h*e>6<*e>4&Z2P|v+vV%UwRU;1J$`(TpC$eS zw#(m#?fTn_Yuzq|4Wv0c96{Z+qRzJ=JX-y5;*?;>p1 zUkSGBZ!xy(`zCC+&&}AbuTpH+*DcsC&l3DD>*H2zw{IElBHoDoPSO7QAG|+aa)6fi zRD1_c!&P`8ehAm#dOWl}@GHav!c_kk_+IQ6tN!eBkm8|u#=-I_I5=ER#kGgZH(|dB z*|zU@xNOJ6IBetFxZ>ln-M;>={B2$N+hIGNws$$mReo1j`Q5PHpM$a8pBs*5dD(s? zQL-JMi}41IHvtnAe~|SNh?{Z9af*M8lVapwalvV_T|eKPFWdFkgYEeH))n92@vg#g+x~CDc76VcZTmlAyFd10yFNB!yZwH~cK`YX?{%ui+W@xv>#x}EufJh?J@h-a z`{N+C*FS$?yMO|c04`93f zSG)3Suw9=IVmp2wa+QA=+woV6ZGRrYc08@YcDy}`?Rcugc04_XZGRufcKM#bcK@o! zwm(l|+n=?r@=v+)8(jHMyW-Ed%0KJMZ^S#Crv0S}AAr~6Xk2pP=;Oz}$#MemP&^Aq z;~Q}TuENu>-Cn<4sru~t`yJc$F^KK<{sY_n<4;^q{eNLQp8c*;{dRvIhwb*<2HWj9 z9^2~|e{9Fcw%G2!+hIF?x5sw>FU9|*e@n1EUfnxQ{j>Z3eb^pPs z>Q6O38kb+M`ljMe?8V32p!glQ_eS|8eA*)U8$28DdWPD&7oUXNaV9>rMCDiF3$R_j zBK(?(JKMh)e@T89_B&JU_2K=n-(uAtk8|)fIA*Eh_u)18P5e3DjQ3xr{Db4wUJ5=J zzlDqOxaG>X%M*?5_Bs(iNq!7&$5pQK-S`LMU*n_CQh!3r)m}D^#gE}-xEELBZO>Nu zCVVJv!}fUBh3)zCb8PqbFR(qne2MM;-;Gb9{;%*w_-i~Le|{U=2k*05eiH}R$UorQ z@LuO=dBPr4{8U_z?eTieLyFtu^P|{a57c3Mym}1V&tykw&Up%gT*d7n^@t4$BfPb~^VOxJUw)KC7ZGB(k z-4nFFd+=d6_T|z2js8ZqvDltZPsMh7 zo`&uCn2PQ8kHdC*pN{SM{0wZz)0x?e%d2w%5n!Vtajj z9=6xV=i@1Ck3?**Z|6kZHuiqnz+vOdHZT>dc-f!^7_I^Xn z<0^0W?}B>SuKzjMuKxi%%jtiBpI`F0LwxINAs)bY+W0n#KZYCeD>!7l;_GlB{vLPY zZO&JF(f-Qc!+2-Yel0%I@s8&E$EPVi88_l9o$@B$j`MN-ROK(l1NeSidAj1y-QSAlAD;{p_{x^<1UH$;K)R~>s z{PpA7hh%@#w$py=GqUsDKF1-?%CXq{u$+toAC<4c?Q7&4am$l(1@>DjKY^2}?-g7} z{)afOUishQ65`{{3Um6`NBjHYB9`xHT>rSrpN?xYxAiT55)POvXXEZXxdfMa<-2fW zj{G?GWXZ4CeCq!aPnxIrW*kO*m+|U8^?w;>auITXDr= z+5B9UZ~gR7mm6_-y4-;Srpe#oD%#)1H0!M2O3LqLJyZD;aR|! zFAiXRynqua{{_yV`~Z%iKl_+woc`6ZJSX7rG_{|I*G zMez@DH|yscTtR)m;aZzU2+@lA-(|@QhvNS_xg^1 z&cHN(hvMW9J-M;=@VK%(^ z3&oL_%ad^1mGT8RZM+${=C2SpY$M-}i~Z$iaS#3&H+`@EZNR<#@^3i)CwUKZ?cnq; zWI#R?SCD@qZum>_3vt<>awhI1z5w?UUykd3SN=md;t#nAmkr7tIO!Mp8yrS`f8j*R zhx|+Z_tO3Z98Z26uECe!5a+;T{$}IWC*{Ss?J0Q`E?r=D1oQVQu39d4;Eo&RZroBL z|AC8^$UE<>{ua-Z55gX2M>l`bIMjSE+W9*lCz$U|JAWRVf4aOFcbo4SJAe1%c>EGh zrhF%EnW6mOaiIBLvh#P4ISe@Cp~rj=*ZDgOm#52faBZr*3WsFMuUfB`KgV4c$U6k7 z{??1-i8wk%z8se)%L}o0x?F?X9+X>g$3=1!FlRN>JUMDBv#M|TtMD#6{Q3!NF=j>{>Yz$Fct; zSu_4;<6PQXf*bQxz7~hEJg?y(`tvz1o~`@=T<@G1&EM{Os6RdU7+hMe_*7g{AzzFW zR>(7P#U1i|o6r8g497bsTJyIC$KENwf%})rpW-_DyBV*4K=I%`)!%A-0*=35@k_Bk z>#G2VFI0RvPGUUN;uQM(BJNnG{135rzHEMe$G87?Gk(q2n|-ckeFg0$du~(y!8qY| z*}M*?;|J}TkIO#yvi{QXde(P7?x*}sID_^70B&XdzJz1S=szC3Pu`5f@0LSC)P4-d z<7gaukK*U!WVY8#9L;#Hz+tx>;M=|rR&^xye}?t zJ_wkoXGv{w(L?QsTup`a8v!R~&!0yicf>&wr&n5tre!aLsLsPscr!FT|~PDZUg3 z-XS;O@CvyDN8T>~ge%G4Z9ny=nE0_cyDJ2pFwlt-TTNpo88QDXQ+HMPWhkOOTZO48z=0qeCKOIPWc-8_ZrUdSNuyHLHY4v zehH2x z|6bgErSjjx>r>?4aRNRvg6%b3@iTEssyq`{tkHPA7FRzaFU7TWavg52l3>_sSpR zhI{1Axceb__ruknH0~Eg;g*LLKOeVJKFj8pD_)8dmdKCcXy=2a`TH1m-zNWti|&vQ zK0@txFOyHljd#f&++Hd##~ruIjW~I!{1uL=ly^8%^`|VBC*a@}^5wX0rFTX@SP?JUobR#l^S=Cl)FH72Jv2 zaS{FmM_sG@UhC`S0i1$&JX-y4DpY(Q+)epN+_6yc7+jANa2cMCbFWkWJRHvQEXD)0 ze>-lwLHRYf*SRn;e^22-maheuQ~m=SP5a;CIO_Wy4-gMHM$22UNcHc7%Wjm9!V&mn z>_`5^c!2dY6Bp24K3+dh_1%IaS)RLb8GaU5Q~otv&hMqZgWLJN)lY4CyxE%Huihz2 z%h!ny!v3GBKd0bCd?k+QRJ;K9d@SFJt3H%#a69oAao_(G{}>mpllyVXNAj){)W5pD z&4r!$I|TRLul?mjoXGw6b8y!J<Rd)cX5VS^=-fnIkNvm z^)He5LAYYJ;wR(aIr0^_j^C@e4)^l=6nEoV%0G|0@j9GFecK$X_Uq@X{zGtkk(`X1 zuag(x+_`csF1}Xoz~zPVuef@iyzeBn7m_DW!Cux^GOongxCJl7-HqCQt8m6&c z_nTkBh4_8!#a|nb^Yh!rH#p3H`d!}cxY6-FT|U<3sV-mQa-Pd&E((f!}m@YGxm@7#^)BDy@|9D~XLK{A znkmgp>1LW{rs-zNFjJ1@T4bgYGc7jLO=h~;Or>VJ#Y{`gbgP-l z%(T=@%gnUgOyy>}%}lqO=?*hhm}!NXR+{NfGgX@DE;HS2rd4LDGSfX~y4OtinW@@L z_nYYfGp#mLjhP-a(?e!@*i5x%dc;g?%=D<4>df?*nI1RO6K1M6)01XeYo@2n)L^Ek z&9uNw#b#P)Ca0gznCbst*Z<$FYv)W8=9lW3mYSYkkm^mJmoujzbw*}-!JNFz)Pi}r znW-}~3sSSwXJ@8nW&C4aex^5bdO=QJYF74)oP2k>Q`5+*w@C1$=cnf8WnP!-$b@n*H-77zNb2E4mXyOnO~5XGjDi?vx+j(3(~ioGqeb! zLz%O43tZ*Bnb|W7JfqX*;i4`5fN{CL00wzbznGuPQi=`$B!}d*okAz zj2<=5>&=;N>deVDV`cjE%>4WrbJ*NepPQSRJ*tD#y_xBGri){Z63~<44UpGiP|yXO8NBggS@-?DQ||8nMJXN+B0US_U0 zeR}3>vn7WIox8>S>3LbX1zXI`oarl;o0pTDnOBgNxy6F8;ZkSJ$)3JtaP%%lkLQ>H zn415$HIF>%jjA;}CvW!F##632Jf~}@k6LlA{ZzfkGedLK;^vw0lb7!*=$mDS*r<+> zo|xtwFEInWIqmes2*@(ObPHfzhBYPbe(R=zVVoaRRL zd^lr_oz6LcZFP_G1-G(CIk7SKC?~MR&g0Ddn_a*OkF^W<=8rg(+m%+3I@^pXv%mO; z;pi1_&eU7qJ)8>varbbNw%k2@bN_Y_I~iNuJ$ym4DTdEL({sG$OziCC>E2wAPItre zrg`URm<`XGnU|TV6aMhLyi6U&HOHHkt&0^gzaS@9L%|i!EHsCC6&%`zTMW_R$ml_t zk(Yk088bQgnW?$yoMbg`&a|xQsRcQ{?ctl_J4mFCID?FsJMz3gVz#qBh7ZWD!01!$ zh~O3{@)5ByPUj<{qYoA%0?q~-UdrKt=1yUux0>MFCT0yf>%zTeoHl0X%r#e;TaRBe zC*3qz;9Ij>tz?W9L%YLG($MgXkv03~&M;?<)M<0FycxQJNgcj08WkF`K}XHc&&exL z8I3w$&!^VPP+L2bm`Ehbpyq9A|xs54gD+<#27!zQ~RXHK5^aBDsSZM90}{!_#B-npjo zeJtPFa{T>LD(W%gYHqsuRQC^k8p_-H`mhzw%FJ^W_b{N|;gKPDwy8puh=6ll3 zO^Ux?33LCCi#e3{Pm4J>_5Ze*bIrW~?X6o`%+V)?tu4i3pys z+WE$6b5w$FIkeTr%4P5To6tX0;5+6!<9e(rhW4|+4RY#tj%-8gGSy>;J+vc^U39Fa9y+v-E;4E#`%XCod!4xeUmfsZUx%JsS}ox+mf4jFaLFkPLG@lwaVSQnqM; z3t0EA@7yZe;`5i9_Jzi{7#jQHU~88JBMytheH!B`!FTc>b)@pm8M@cw>(kJz;m@)| z^W9^?$sIiwd~-&P1!s@KwXQnqNJ!8cEAE&cUqvnS6tSt*TYsWd^vtr0~=5D2$ zIoVrOWFFgWu~<6kIS*h)oE?U5O4(aYTkLW}0cS}vGH0aE@#>f|6fif}%<5Kuhh~o6 zJ=6DMGfGNY??W|;d1y7BI0%*vcMTsGTW8Vpr5G;)UK zm<>Df|6Mz(Q`?+e^W;Z|O^0*S&0R26Z|>>oCYH9XZ>XiuGk0)(HM*j{+sV$A;8?+- zex>H}e9cvQI3a(o9>5JHI2D@*gj+Pbl?FB2n^{ocUJ75t-Mlk%izai;Nz#P>fl8ct;sC>}r1K&_BE*n_@ggwKsqGR6o?Gt%Os} zMz@>HmEz6GnKg&InZxzly9K_b_M|&U)Dhc;Dn=&#b2TiUyQ{X6YqJVG!ygjzeaDxv zD|PymUQl2T&-%>kuF;84OE-^;%}ra^LXQmTY2WZ7kBp`IdNad31esD!gm#^nJ7ne~w7H@l zaW8&!r@UD+^^ktLxdP>($LNfF=SifwCP|;|?v}H!jp+37{>h;6?Vzsb@WXZc_Eh&{ z_~G!-nPG;xGiIOnyEe~Ije7jFhuDQ5(HoWslbL>t0UM^j64F z=Gb+)lHB{5?if$^=t2I8?dX9FhAsb&VXHV=SF2@vQ?pI!2sY*p-Hp zSQ%Tbh!rrpKjxCl;~OXD9)78MdyldHKbgH9g;q-@K9U z0c@Gb%>cW)T-6XA+RU!7dE%CuZeF=Cm%KXmJCD=1QkD5Yl4TZW%c{(S64TA>Y`sTh zo)6`DhtG??2A$*2&^t1A5zMuj)`agco?&+V;oA*PPG&*6Z#|kG<;@#4R(+x2%N}3C zP^UA^Q){!{oQ-T>Z}_{|=u^#DnZD&7x++!AhMFiG9K?vXvSn%aD0kX&m2tYGPxGd@bMwZo=B?zK z5nR9u@r@8(=%Z6(RBp~ZGt$kAPV?NC-M$8f-cA{#@u8T>)NKKEPWNJb*XX{^j_`wo9 zx7w=tgl!HDS-F3oF*7e`&OfA>n?c$6&dWQ0Q`4M$j~e@jRgpWC=$z=xvrzNa+18i9 zN&cq}IywJ`9y+VbdBXpXt1bW9%uI6w;~(?J8jQY8H)065w$+G;-8imUzJ+zo8(O%L z^M_WWZ+(v$8Ct>a=oXEPT7@IBUF&Q_Wb{h%1vql~o}Xmp=S(>6#EFxflff3j5pSAN z#@Xvfe8?L8l!_d4ve>fLEnayVaRX?}m-?JrNxFSBMod>Sx#e?{h4Ut>R*3J=!p${bX!z!uLwj?L|93S%^6=?oj6Q7IIkVIC zTE~#H^xVMObqmhU9zC#~xn{i$b$Y})bl$CSZfTeuc_?gNq%-ek4s+x^I;SdgpdP+Q z#|)L>J~8v04^`ZebLI@)yt6P@(AmRl-3hx^k$C}gZdT5m;f~uGuDsDlf2aD9?K<9a zeb^i1LyMU|Z??HiHP?ye39Ivp_0WshzVg}jCg<=auddO|o6ovgDf%w+eE-XxL(SHe z+=$`fd!jyKu0D%xkv#J5`__V66dg6Ph8xN(%$z=lo1Y`T*VSg z){@+P_TGQ6D2kFuQzVO|WV@dJd=WVyM<4-$w5#v!)!nuUATlyCGBT!&uzlbv4RW%2 zxu0<^MCtf3o56tzjpU~9JFo6HGRHXc8Ml8&KXs?g`+|#t|#{pf-e!*U1`x&jWvnr)>5PX%E zqv{pCX7=i&eWLXee`se#tKdCNm(vY24_tbfKCNKfR)Bq(Z8mT=n&~P>Nc+04d^~lz*VkrJe8w%bIE1%f=jPli$D4J`ciycAxHQV z$9VO>kXZZ$_niJup?>-E&*I;7isIk&YVq52_W|y8{6-#&p~z;$L;PO66X{d@GX0xg zEbLc4aH{if9LxRyb@}}Yr>6Yed^V!cO7O{zh~}8zaDwZdNO6|GixIA2R%#$uA{R^l z+n5<4OYb_!+C%Zb3Pud)oE+zi($@7apiJ=|w>2J$4`hZS)0JJGcz?K@?TSw(g+~-3 zWmNfd{^#8z%#1H|J&S+)^L6oQCTMg${Z{-reIc&atM>VI$Fu)fic5^7e$8JfU_M>` z_x~`g8yP^lJF{PbIe}U*mco@&+#WeF5+>6=3D@;EjEqR0Z(D)uJ zfeT_w+zkSmzt6zy_kT|}@KeBzi~uqIr1W(BvD)IDNBOVE>5Bd(M}5Q%7hv(YhAi08 z?>PN24*tN0^#62+ik9OM*kOdHDRR8tuup%iSM)xvrSMQM)0fE$u%bUn*TkQcY0ZCu zu*IKD≶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%0D@_=woVwZ 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�IV$jr2BHiV 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�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%0AjBGu}s=`mMX8JwkkE?D=xGk@&O) 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/liblzma.5.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/liblzma.5.dylib new file mode 100755 index 0000000000000000000000000000000000000000..9d6dba97c49cb8f4f729b321f2c896cbe2d21031 GIT binary patch literal 323280 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libopenjp2.2.5.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libopenjp2.2.5.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..906a87d5c9d07cdbb70115bfa87bd6a984f0918b GIT binary patch literal 665760 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

`L;ExWKobo#_r{?>~)e=jRvBls(S*G)MX+v|PZ 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libpng16.16.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libpng16.16.dylib new file mode 100755 index 0000000000000000000000000000000000000000..a20cc1e728a85dcb963cce827ebc4bd4e01ffde4 GIT binary patch literal 344928 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�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

o|Y}? zZ+Jxbbnw6v!smfKzZL!|IQc2zyTEzR2zP=zo)dl@y#58@55c`J3cHs|`~xow9|>-L zMR-1V2L1GnKP$is_X=+W_rEUu6L8-f!p-37H-(=Er|lDdN4tY3ER*!qgEPQsZ;5^b zxDtF7co+Bqa2NOw;5l!L|9#+U@TcHbaQt$Kzvdm$9|i6Q&jVlbuDG8CPTDVA3~mH( z2j}&P`*q;{_l55Q=X@yqG`Qs>;cjsDzlGleH-h7GB)!&vxE}*92A>Mv`Kh>PgBN}- zd;xfOLV`NJKLPIp-w3XqAntd9>n9062A(rn_)p+U@T=go6mkCuoO^_@YlWnLBlvLe zhNHy&WbmTt!l#3)j}u-6-g$zs7u=L4Tm?ROqVSdA11Agb0N2eHz8hRQN4NuA@GapN z!PV))`utk^9pN|Oz7xD3ydzWGzXGR!S2*PdlK+7-h39~)vxKw3HMznYzWt`#l?*IX|g1oz({d=)tLCgIz`={F1C2d)J_0p16G4xD+5==Xp- zZWI1Hc*8G+-vTH8TDTuvcbD+z;N*LRC+14|WZx^C3f_62@M++T`-RU0w}MxK(;g7_ zwVFGH%fWSj60QL+`m^xO;Jj|(W^mHqgdYO8ye8ZQ4(}EI7udgFco1Chp75b7C4YnO z3m*rr|F`gbaPe2dOTY``$Ep5hJve28upiuTyl^!*=>*{$!3V&<2G?eb`y*iMEaAU_ zcZ2)DU0!kj4BWm+*t1IVGs7o51)L5(9_%j>_jK@v&BAAZ>n;#J3*395@VVd~zi=tI zxI#DtZmAT$6kHn=z7E_G68E*AbDxCxxR zn##vxS(#Uedj>cgybhcT4uLm8gz>k100#CbA(sMI7 z1N1$Ym5J@|ca1vqJq#9s?O9lQ_h1ADHL_-+8t0zUy>27VV@4xW}T;ok~g27U^B z0r*w$jo>f9zXKn2wZ#7^_y^!Q1rq*`!G+*^z&`_bg6{&q2L3HL@mdML2Ye{_Bk-}{ z__Y$>soUnlVwYQA3h0`O14L2wKB67WOd>%mWg?*#7# zcYwPO8?XA)z2E`xyWj~a;{Fx*NbvM?B>$&@zXQ$!7l7A;H-THhesIcE3IAH~;oyhB zr-A;)fotfc3s;91~1!P(%)!Fk|6gA2j$gTvss z4U(QK!AF62fKLTCftP{Xz#GBOg13SP!S&$rsgnLy@X_Euf=>g#4n7n71$Yhkupdc! zi@~RYw}O{~uL2i>8^Bw@_kwQ({|@{xxC`6~ehd5t_}}0!!Ewh){!Tn!(l-;~@G9^R!JC*9Eo;%U5`Pf99(*~t z5_|)=7JLV|=MC|HA2{(N;dadjgm-~6!F#}^;D3PE|3~zir+p^;FSz%BKi1)WF799H z@W2y_B!3-);(io(8oxY?J|}~7z~2TpftP^$z`5YWFU9{l<_VV7;HE$HDPf*y(c_oG z+rS;*tHHa#cYyOeqJIor0RBCAJ@`5B2C$prJj7*Lt)J0F8}EZN!AF79J`wkmz+v3) zn+I;OWPUIUyy$Du)8&B*KPOJyDSE~IF5w`!_##e;Wz~WYoTAXW9Xu;TxD8wn_h-O^ zb7cJ71x`(r@ZJNL&ZHgsd`4f+@0>3r{sh`*ZUY|)t{o@y5hsJgCoAt(2DomL#J3DQ zZMN__a5If-_!9*8(YTsF{IeR4FO9|({AmIgfIGn3?iBZzw0okYrx&~sd;shRCs4LI z{2K5P;L1lNyqVyIG_K|kKeo>L#v>&CYrqE<2=imf>|Q&LcIZr9OisK2s1nu{);KuQ&ui%5r#s62}WSW=Y&qQj59RA=5 z!pDR6!2bep7s?|GTmbh1a1Gc8ZU^&iO%A^mzh~szjLgY?`a_=w!P71feiobq=G#)N z@2sSXNFTl}!rTw$X2#r$_>KXu&y?~x73_!mB5)g?ALVIy_TP906%2hgYj->k%G2oV z-uE4G=V@@}MT>>+02d&pc3L6i?qQ!)>xP(tX#(?ZJK zBl=sw1(^SR09;x~JM`%QCnCH*fz!b~;70V1AAo1fR^BZ)bxRyyFWe6WPXiwV-UU7l zoR%%+kqaKc^L2i3{hbp2rQlh=6}}0au|v2OTsoN&MxR~aou>-F0`A6q?CW69R&jqH z-1{FXFN=m5oS)>+gn3$nxd41RI0Jk>xCUGUuDo21$1lLyTZJD4@8*g}pJ%|mLFr%q z22SRVl|K8yt+m2DEaLRcxj=XV4P%%GxT4YLc<|0?!VAHrhYPRL`l-U3z{S6k<52~! z+b`+620ZP2iiAFQY5$!H=}o&5e@=*bu#_6wy|C!+K zYb1ZCgKK^!TmYW&bK%Y40`O13+pZONek&`7-vMq0_rD|Qc^usPU*YG${#S%w1#jyY z-Va{1O!EIFxC8zB#3YHY2ji*Zz|}Y&^TBOXB>&67X+h~f&I320|1JkxOC`Rm!8N}W zz72d3zh8O?JPYHCKY};XeHs3AgOd^dJK*);1K>WeYm($A_1EJ6aPTgS&t`**GbKNZ z!S&!Df)}B`326U66n!;#BgRwLg9lMxo50P-iv9_3!7;*r2K#3S)7wtf@%9`oJP59v zE32sM!_&PXgmAHQhF2MNUpw=HQ?kRME!u7v-rSJ*hR@-{vF|K!F%w$=55S$4oTld z9W#9%g!`hYqJIwD+bjGpaN8e*;|`VdhjF~7f_K6HEO63^qF)TI2LBM8c(S-(3eJ5( z_-1ey+E*(${X3HXXTfz9(*L{yZVL&&3vR{xGzP)DFdm;WMbh7}nJO85P6MYuAn|8` z)4=)Qh2Ro!b*cEj0^Hmx{%;1)I868+a4VQzhOO%N!W40T5nK=_`FjH#&Jy>Jz`cuw zEeeO*NBttAvF#InEThN~eZiRa}IK55$Uk=XhmGjBH;DOJDUj%1@ z`@qR%lt}s8gbIwN0ubjwC`Agm|{?ox8%r~3~ z9y}1Q5|9fHBffLN?HG@hfx8gi7H|Xj3h+j7J-G9)ay)(wPR4lPF>nU-e*lLEB|Y6> z>jzRk`@ulfrSTu;|aT2ESzRUW56K^HiR;|1X5?^8KH|Ho+vzP9md=UF<6?t(g#gO0?cQSWE`$GOaKFKW z1}7XD9sUf1GYnp7aG}8=gKG_LGWaorI}Lu#;C~yOKoiK$@;Th#IR-B_c%8u)2;0Xe zVDL7BFBPUF$mbe^cNlz+!H*gIg28VJ+v(YF@V^cI+~BVbj-MXg9wr%ln8DKwKGxt9 z4L-%-41*UMoNaKf!RHu!zQLsi2MoTIN{)Ye$UiUSDWyjG-a+4A()ZW&y_3Fo(YKkt zchmPC`rb=l{<$FkMDTw4@|}#xy z|DP-4RI8Aek(--dqL#D+@UnHXyTEB*VB4#<%*$XGUT;ka*&yrF0q4&%+~?1OJ1<}gKGlOJVNv2$=){33bvws3K0G*)mE2dv`);B_(7VqOOG`ZErb zT22GZOTEdiEF~vP0XQv=WTU9(hUJ`Ct zqXHK#zg*p^a;9Gtk@WMMzhz}N27>R~eg`-}4@6>WwQO04{c2hpoA_kH)S$vfY<3rIVS=~#8MykjvZ`z{PdW-g_Oiq8YxSRM;`*vMW?@Q+*QOmT6 zLM?OXSgtK%Rm+$}FtU7G#71irU>UcFEnh9?7FnUqbcqzEN)ErYJR;$By^MI-WQZb* zx5201=k!F2Vg_`WSnV-_k-D*rR%Mn2gAhtZvAmjIP_2s>*;Vh5kH)zOb%dq!L>#qz zo-!@>h3Vb%_EK)zmgTqCUW=IY8f>=3Uhhh!9JPl+bfjEUWGy!Bn-+br7lN~G{Caf_ zd_2{vYub>n7i6;ydR;c#K#LXleUa7IMzHGz+oGMFZJv_NEzpl8Z%hwV1$Z$5S+h-t z0;4S8rj5}H-f62|_D*wT@jGR~TA_N0H>VAYy*W)-_RVSH1>l^FrQn>VNX_TvQq($b z)X3+HH>WAXF!54wDj-`#mUR)6y%d}+Qmem35wDeH8*Fe{8_atB zHz2q4VjW9lB{=2ExS^=`q%o8^KPiyuih=?A#EG zt@3dO^s;jzqwdnVc#~}$cEH4)tC?vs4Kr9`CDvYX3~n6O$VrTi%V-qqSeVXE#n90f ztL;KX=A9;cML9bRRvT%sO?H*k!A2*Gb!>^2d8Mo!k$bmB`?D9gvJ>HScdi5mL1eW* z7>p(VlvRfs>4cpYeUPb{nCD^J6d6OaX~;@+5{u8V;!d}a zU9hw)k6JZmbqQ9|5naSA>*|j*!U_lOqbQ zlX?X^6}H2mGtH(*ebb~}*H-9Nu^gk&wY+?!V{tnb^jcbO);YpEM-TC&3~V$;eCN$iA%qyF$eOE|owMUEC7b*|Y z3*U(?Ysf-!u=7+pK@;@Rs$7x9@5DOv%34JQv#wq!D7i{jYXFLG9vs{2%fUp;&GF$>gCrFeU&Wd0 z%ZZj6iCvU@iq!p=@JV09c{y5CPW)>F zwxqbo3PNFX6k#e?wi9REdxQX3h>oi1h|Jbyr`C8c;cgC$k-I6 zGL~bM6!0j(*))x1<%Wnj)DbnKIDUhb=5$}nr#HLr1)F&mCE^TzSPONPyz64ayt33Fe>s^Y(X^IHd zN|++x-H5|xJ(N)4l{-5Ofrzx+S6)Ob(n%-`v@)Fybe;k@*4Gr*h(XQfsEDZ3aCA+e zNK_PBWQ95j#c7HXI+w4rr4D11Se2|SVrOe3wkT<2?K@j(o1%n{h4E}<#1@fmjb2++ zw9!T-uG&(F#qSDf*C)&06&4nHL%jBUVK7`lC0$rldSNJhVPUa1xRsXYCWAWgyd#H( z1t4xW4y2OQ6sk}Mr^MzkUFS0tmUzqj>^)>#HdlFrbTP&zS}!@s6@hkxR13s6%`R3@ zZ|4mM%B;doA)hx`R7yJ+`+_tlr)zPMUrj<6`%3)0mLp|U?WoHoSZ4`Zpq@8!F!bP$nrBwA2N;uU>s@}eeEmmP!1tP?biV*vV5QG@YLMn8t z@PbO;=DG6E3K2dD{hq=hAA6=k8)LPHNLSEs0OO1+`Naydo$3OPYKUX{&K$}6pi zEddXcaVZQlAC&s-6-9;N06A0P+v!x*E#MCXLzUhlI^-(3Y@|c#r8MZM*>q7AEs7h~ zc~YU6SrX%r98smzEkGius#N7!81~Y_*gB5k4ou+l8ZvBngqR^AU=TVuXMQNQ{{o1ZYf2=Th0?l&Sw*~ zM-%B*;TF4rsj{$&xBH7pR<)^c6AisM)jV65El06{A`6xHg3GEZioYn0;}Ux~W! zq3&2%g{uN|61cGD;<@x|GB@rzlWW5nfSoAz#{u@@ZgJLG?<-OTty! z5cY27{=gg5nc=an8qF-(E|UVvOTN0{BDZv?`unN1QNqZ;MNu{&nkRbZB_-@xt_K}=JtUb`n=YU`quF#rgsY`hNIiKew>h~uDG0~~q*X{ouy#t`PQQCag9a{wbc z=5HF=bq%*)bqq&SQ8|~YPH=?i^FyOJJE9m(<}2o=JwhfTVT>Z8RPsqBW)P#PBo&ye zayB?s(9y{lNriNbo`C~L=9ndgGZ9HQl&h0E|n~1`X#WK8L$HzJqMA{M%8huRGEx+FqKFJ7*iE1`5Y8~V<(D38dar^ z4~I2cqHIy@pkg0ymGEy=TA8scwFJhw94-A3RqPC8D)9)R`HI(g`NC+FAyIxXmSTjn zg=!JL;*m}oDp{&)b)0n7xs^wtmA+ycrtxds* z!qD9+FHPRigF?lNi;LxKP3LhM3QC!*<4IZjk|WtiAHmCoWX{TJaQ~X2t{3Ss0(@?6ATGMQdh!PU*XZ> z(&aFkMqjg+L|wBFiE?qMsEnrchEGn_rm_-TfDQ4umSzd)nv`loFzCh89z#TYA{)(J zHTO{ks$(2Y!DT+0yXtsG6U01d(shj%ggzcau1tp%h}{ePUyzO#vpMD(5@GCkXw*4c z4CKt?QimjW=&kG_(W28DtwljHN~4WjcZ?LiE_ka@@=14aBfYG>zqG2zUsg2+jvqdMC{SJbR)%`#gvlr63n4OUp`eSrTPTe=jv_2lO zTeA*1h;|U=LpKt;7mCpubRgfL8pP~~kg%xq=n;ac-^UZ1t-QrB#M`V&J*xbh_ii zwb~cZYm3hNlbILRb~ESdNO{kw;-^X?&*nc?GT;V zNAgWsDE3u`OZk^S)X7FiHg|y?TXg6{93*&$c@t8ngN($VwesAvBnM{7*o87=J91u& zXe?*@k&rW3pD)=Ezb(kqP zkxVMrj0`&>(`DX>E^|k6nKz=Jc_aFnJEEVt@WWY=-+npsLU(flLH=2X>SNW-p{hzc zG;}ANXZHD^(C!v>bofT!g+4Ly-lna}wJfxPo)dK3I8!q=syajpLt>VCXIlBxE)7FB z7Q1Og47$FC(4HdALs!_5Tt>1lUaValwb=}8h|}>BoSl`U&+$uMIDxokGq$_IMMC#%~eJkI# z+D{GG7E1JxX93uePnZ1AJ9Wk7`hKp8OWh_e^lj5q_sSShckk%glaSoy=KJy7Gzvq3 zsvzH}Vgor~g`28M=x(u?Ll>4+!p!*)BOQfu+cT%bane;7Iq5P+PP$BvlP;q= z>FRU6sO_^Zqti)g^_dmgD0B=B*xBi3pLr!v^>~AtC6Q-u9o7Om14WE$_(6fSm2!KO zPR%T|vp^4bD+hIJawHcunKF_iPu9qM@o0*50e-w^BtSBOYfO-CLDa-nVR2w9 z%|`K^_+r#Gn%J@>hk5eh#=Q|x$N#&)X=2Iy=TqQ(-S65ur1P7-Cv8=2-% zX;ZN{9+R>4bhI5$ztBL3Z}qDz7T{?WTdEp1H(Ez@?A?A+##V;RCtj*5Y!j&~!cy*5 zp~GHEtx%iofN*$>NVoFj9S&XeA!K1$1x|GE>?^MfZ!birpxZj!RLhR?WOo)rtiy)G z@}Ys)>F44pay)P}d@0ygXBluUlLk$XiaSf3pJ#GBiDbtmr806&id1^Ti=$eE>5hM4 z89lmELEU#CusQO`A3b%HTeW3XfLb2^(7kGl-6?28K3`7g?n^X6s@u^jF>#-xEy|zn zy2PJQls_>!{b7_YKJ4yJ(9uD|K(XMuNDSO{;MzwFk}!T^o-!Bt5x(q`DT78faG@c* zPQ3Wy2?}zvf0~c|h%a`rea&59L_T+c1Ve$$#k&D`yF5q}m6EvSRn*#ff@xVfwLUy9 zx4n>`Mr6U<1TDDDoZw{ni1UK6N}rZRfbzS|ym3=h7bioYPtC zjE+Jlbk-Qc==ws2yr6w1P&Ig-(h}$~uROBOwTmFD?1e&?3Kjc!nNF^Q|v%#LK87R=6L?qXbc|c9xWr$4~0}P)j~Pe{ag7>a4?ibUk%AMAuD+L!^m1jFCnaWz-GHVdUPIN6|b3X(nOCjO3$IG3Q4VGi*K0U!WZ%&ji!^! zx6>q!yeK1LQtzD*qkd0XmN zjd-<_g_k!(or)a(>~uiqoO#wVQ-h(QcDBz_+Tb`**`~<3N}E>F1ekQQ^iz`JVl~>* zZqef{dJv%OVw%$R`ssyCRWv-K$q|~w9?r}&VZ+*K2sx~sUhp!UokpX>n!TGg)8$~q zDVr*bFX*EObfXd!F-IpTVy6h`sL8t&oaJTP90jIrk(m$MYjkzc!svq?WmSo%Vw4Qh z4iZRvJUFGC(H{SF(T)P`ihpfj*yM5{M8B8IQQkPH2yt)`;vh>ZDQp!7mxH8$_mBkM zMH+ZFDiKlz)eQ(c5n_uJS|$>0k#u%A$V!qwZTSp(pl>)z1|83XY-)hqtRD z#~@4fA5H_y)SWCIQOPx=+<#&Rwn+-*@fkcwLERPg?q!u!4e7U>c&3I% zZhT*slWOW#2RXk~vg|+?SV6e~5+!5>-dm&;QbO!OKeb(nXL};vq8`GfPKXAFQB@0X zcyZK)D2oKNJQ$GN(AfYfr{A${@#T7ho2gR_RBbL*=Lda)<|Hkqr;;j)3j(SXtU`Ke zjH5L$McM(8qeCQ$N+B^FGTrSFId-Gkg9zo&s0f{19yvN(?4C`X0r-eIP6#S14(3De zK-Eb)n2);yqfai5^Ga1k**5&n9xrm?d7QFs>ZD~`xajPH!VhzN#iwpB+Ef%Q3iwJ& z=n#yc*;-1|JLAi@r!L&2h;cojqRwya{P9BWCuFI zhx8nD!~@Mcshkr(Zu9_+OgSC| z`9}WiXIB1id;A8)=zQ2MDpgU>yxA`L5fnM^*k);o^neB55~G>l(5dR?Sh+WJA@$LG zWotjFV*BA|Ce%5L&fj5QlvzTbmpzPeZnRO(W44aQ*PA#}tB`-E%?Y6?=n9|gr~$3~ z-f|0X$gProgf13J4IZDd17njBKBrj{M-R`~Le=#R|MEmzQ&}1a2h{Hiqo32T1=_sC z`2dFPT1G`^JYf*!X5O;59gFFg-+u4*!jPIe_Eyl)j&5qoJxM-TQTH!TE#^zY!lkQM zjC|+J4tc~|YmR=7HTHld%BN$r5@jc~QRej002*@1Xr&hrkl~P=k zm#7*hcGR&9BOo!)pBH6z%(ff$VWS)_ZxX3wZJrsan1@7a6odp}j}`5daP{L{@}#wG zR8#4ckm$1#TZbMGwwf6cp_u}<+SmC}aT&@;n$|gF&iQetdAKA+O>aBJLsIITOt*zm zv*1xy!@o|cnqIMmiiS=uN4xV-D>CiqJijaNL!4=pA(O%}f`RU$@Hf+yels0SYJH>d zXvQ^$&N*-Vjii{C`$k&K)J1EDR(d%=k=upQ`skvMc2lFW$YG0iv}+Jju6gp-GmBkXdkG|MiUe1(ALNmTHgJ~ug#<<9_=LQX*nYUx&`QYsfgY= zt!8-AV!ObG_!_~(aJhB_W@OTK8JbV+G=h(zRfdu(Q&B1jk@RY_1jG{wwi_1>*Clb1 zIgTNYdU_+u!JdVPvO2BDn~lR$Z<*-(fQVS z<2Qgs-ntnTkDUozMnyR~@}e%@oO3@>LVJED%E~k6Re1G4l!Nniej_+UnRW5=+{1#% znN?*E6Hn|E2I!I1VxK?krSV_5l-`@=U@k7MIyCz@O!gfvc6jW=e$k?lY1C`eh%<{+}O^7d}S3arPZpzwOG$YNMd1^tRFW*SoWm!kiDm?a@RcW+O>p2~f zzzY}Ab_!{T4}aTo(_$*J*3+G|U61`ot%*ljscwr_9s35K@w@&{dv_63XS1yV7et7Rm-5C9`ver z(*Is$XKnhg%VXn#%J8C0P_D4RaQBRXm(Qz>yTX?arsZ;9fry_ zc*Q-*pEbw^e8RbS%~&hPG~(Rf+01E6&ks|voK5aXpLpz1{xwws-kUej)Ep8DM%hTm z50nHcfMdGMo}3;p!ObJCjmY$6{C~U{@l%5xNSi8NxCk1vSZW-a3+eflVmJL$YMpR0 zS%!++5StXQyH8Z!nv#n^!u#s%Cjo=)kUaw*x?|l+cs!FYZh7dsZ6!)0dfTqkOXv$A z>~|*K9Ts<51mTG{w@B#sQsPeuqL-dNKd!t+ne|_z`9m$si0Cae^4%NB4Yvl=rqA~% zUTqz{eDPOeSVyusJ>I-<``tSBgphQyj8y zJ@b(fZt$3UQxZ1=(MMr3T;kDMPMV`t@YGJr(F_dd$(ZtQ+L6-rgBo8m6$STDbWOQN zpK47DXDHWtHD_>)YEtS|H3nErs6Jn|fG_&XaiW+wb|gKS8M3^I7HO4B*D;s4O~;W> zmksV@ZN{J+Y6sk#L&m*BZ5L-`TW9ZhNqscLv&G7*8L?+(C#u&ytmYScoxw|9gQ*BM z(~2rIXfa5Ts`>L{YlA9MDt~=3yCL$31}nLD?X2I3@Kvkhf8x6mnK6s*ToZ%MIEbeA z#F}q1K$Qnq@N=j)@IDDA>ymBQiE1R|J5IP9n3!u(yY^qPjI|+Q*cSL5(o6K3EhNMd zIuo%P&4Zc*_o4_-<|X7Ou}Jxc%T*%W&t3M)b$Th^$QnBe(e)f8d6?i(tB_7xg;HO5 zY>K`Pg-Tzg5q_HQkRHFkn{?`gXwI7IiQBwk zc-!=B=NKEnwwK7%yn|^G%}@zea`&SQ0sWcuK&;=5s-QGn`w)(07GcG2a1q{ZAQ9#6 zbH&>Il69^SI6o>}&}eleqkI@qeL@4m%!DBxj&|g_A~Laf6CuptWIlFb?pZtlD=guf ze@T^OzKqTAAe}G0I{utT^q9RoBP*Q5Xyn`=rMQI$&69%(gH24}|2SsJhm$0wi|is` zkf-!LRXW}_=Dh91C4@&C z)@2-H|GqKkedHQ4y@k3EEt5av8YgQ zUyN;}E8!x1TyeWLH(^CM_%z*-h16>*7>s<+&vC2HNC{or5X;;n1^?Pc$+$k0U5B@4 z4Exq$8nFk^EpZA%HxB{FinwrK-&0`VK7R%R7kGWUw75|w8Z+$ zKI7S<{4w0Q-KeK%ccSv#yR3?E`CAjNZLnKLFWr0x1Xl$u<_77G@dP8cstEJ1V;McH z;on@d%`k>%2j3hTnF~7ty%E?b{f|_g-t+h@@e^8!by5dZSleV>+qZ>|L*%7H5?M`D zM7&iH6{omQjvx6cnSMMz6oso!S}L)Hv}(YPV7O7n_dDmUh>T$Ttwlf zWG3mEO}?`H(1bPHq5u|+${!dJLI*ctgCwuHLw;(}LOM+`v+%z=#CRTrBebrCAgs%m z9t4V|Nc3bE{zF(`%2-bK*#aAzYNhXu)OPXH7QNh48~RF$cbk0og$W1zt*Pm_*K~os zs?9J1(FsOTer&(RHX?MICb$|qQ8!FRc}*)cGS;I?q;u%mKqr+}m#YQ-Btw>H?Nh}M zo<>aE%S9(v2^Fe)LVh2?aw>7pa(NW-Y986z>m=(^pl$ss(=c9yJMO~dxmQz~DcX(% z1tM7rrTJIC;9y8n15W8r$qWK`&l75khZVSf{_lj{%V@3g-rOgWluJ15yFJmT0_8Bq zT~wY7@BUKkJ0w`lctIT0Z;|YzN{mPr0(pv2=Ki?e;lkXa@R?UP61hYS#<(xX3oRlx zoky+|fLLyLi#(n>uygG|$O@@(wr7oa0jCpY&UP+1Ticx_??m%CP_KxU;B8QDdjCvr zwj4E*7WDeUvN+bx<4>WHCa_V>$Q#46P;ye@y@y-FYaH<`yg1?#P#oXuMT0kflq17m z)}_AsRw%F=k_`3p+b@I0-$ltgBpNiYQQLz(pPu3 zNW;QO)05FUoTBT99H1#O<<`WsJJs;r-8lz!Z@CsR-e*HSK zdYyWG5_I$FF*7$sg~Qw~b_P2Ok8llbN)yMv9$~(g1lfi_27%gCP&i*Nw6|4?2#qjj zIXJ_IgdC#C3`y)PYKg_<2pjwyrj$%_Lo`4eghSNCE!s<2jMBRD9p%3DR+tSYja0cv z5=5-8=~0)lL59V|fuWr^VASPEu8N2^dHz?=V5a&p=n%I3P`Cyjcz z_7h8qv1dl4KLIHsETdPi>%{y0*aBmT0b1cjS{#~k1Pwgev{qVJ+go?7mWlkz!O=Vs z^M2H(TN^FBDU{6*X6Vy*e>g3Mhrv;%A(r4~+T?ni#!~X>I^5b8G$R-WV$v0{4WEpf zaA-7CCk9d-C{2U;{Vh7*A#|o#xibRYQgy1HHOD%>TOPG3*^%H5u{A}>tNTOcA5?h+ z?6v0aaHYMA_>fpvir$JRDTrD<{y0g0L2O)}R$*QZ@A1!J(s6h=dSe#f+rAQ&y~kTs z2v+^-Ik8)5Pf70<>jdYY8rJva7^NULU#E1|SJ6sDgfB$DKGmh^p4Wkjj7%wjR5%Lk z13^rhfXD1b1W))+4vwQW#nPDu6&2YKZTOY9uiFn!EQ8U(ExXm&l;X|F!=(MnhET*; zZ6E0>FKf_!8oVoL9QaAMq<2V(^@si1gMAmUixT&Z0?Tit-%3!g~e__1W24w?H%owaLM28&JM z8~Z$JB`*G}os(j%Ep90{WX%SI&DS#SE<(XQNJK&shQuOe-$&Vu1N_Pb=Z4?NB5aF9 zt8v>oSNnLDp^GQgNd{i_NDu-wLOStGYNHcR1y(koIxJQo7k=A;EmaOub03NMH5k)V zMAh^^Y`w^CIWl7+>$1W);$7-OU;c7!VNRyiAirbIC~|oG#(4Jr7N5I*IK8d;H3Hw2 z`NP-lxGA$Sw!~Xf$Rx7CXow--{s+mMNFlnEF!tE@n=PG%*hi)Pi&riZqr=C?mZaM| zUpP);{yY!%pZpzx8PXk#kbG<=SF<NpFm)ucYQjQl z;8G`Pn#2u07bE))XvBE7N>gDoC5zm8#z#Ycq+1D+d}|iPt;Mishnz*7R=#)m=k0Yb zkFt=*$6;4r5LXmsn_BbX)y7Lc(zdJa@6bqLuiy96Tth_cgtbJN>BOrz z5mevb==&68&!1njv;Eq=#Yn#)rYpC0bWW}Y?I|3Jp_9ljU~P$B_%=)_Vc401I#|uj zDJW2x=n)6*VXj3GE-Dog8Fs7^Fqx^;D|$cw(tgH@@lxf{4e^*L_L}`DdSs@fP2=M> zaRIhUR6{bo{c`2?lM5;Xa+XD<50w}PWi!OnhlYdcgRrh<@hdv6PXqU8@Ax}&Z5x*= z^7=aJW}Lirx;EMdM@}ot=#iHDqY~!%>9A_$uJ|uM8~XLOP(Ia{=Tup7kV#hT4T~Vx zfJ;i)LicuuKsxrN==7VNZ-NLIoXbW9RLq6-3vt_D2D!=r{cdI>b zQm+1?rw5S@C*7!a|E`y}%C)jyEqfEWb0;K?=-|edi2LuECTQTy@Hr2*t3xC&$ItpD zt7#5l&I8Ob0sg_I`3?*1YSrI&=c*r(|7zoAbq%vr} zWkXv=Wj07T#OFFHgb6OLZnDr&5_Bc~v|@-VpJ>;Vjj)Mec-Z1y@h$ti;Z~zuW$Mk4 zv?U^c+OL{$BO6o8t0c8|IR`_`FeFuG$j1fm6?|>az+Lwt)OJ>byR`qW!5@m39PsV~ zDH(yWx}I%MPg` zfeu4j#~(rOSP-}UWZ}@h?H-CNEjF-uaku#DqemG%F60LVGbVR&! zEBKXN-R~BnH4J9E9qOG6o>d7l#9po-P)-c$pBM`>wfb-8?{3)bvRmy)VC8ZiIHrQ5 z89quzG1s~hB}4WaX||WGvg{1ti{TiNVFSQ3?IB`=P!=+s6D*6 zUqitqoF^?;_P~l*qfkPy8&9ZDJQ=%oTkwg<$xSCeKYx*t6Q-x~$=rVlNI4F~DLgQ;lxQ0|GZ8${tZxCWu8n6S zPPcxM^w=LmRz*iREt*&+J@{m2&ERI61b@&ti9yyeRlDn|Oy|N?sb+%ylU3?KoOj1- z)@llg0gf3RdQ%3rQ-lqUuORGg$Ce0R zJMHv(IrYx;HJkYZQ}ofdj z1t==;R$bTWzE$~G*6TP99$I$8Elf?>!l>xLzxg!yc!w@`M9W69l>T4mQR7s}MyWV; z_0X%KvGE%S>ff4{el5bS-F*n-EGG1twyYJhPdW6bX6pq%9I`U3>Cy;iGyJR?yxOPA z2;D%?d(3$|hPizHm29w6W;<|57Yp*Y(2kWku*5E$2~v2n;#UR5F;9wPXx$5V`x90& z7Mjn$F*P6}1Y1DuFOR=aulk9L3Na7=cKFdT_bcIKX8KR-3qp?gR?0&yt{9fgh`Zcr zW~ohXl}MNcIx6v@0QrTL{UWD}Ya9`wpS34MlfgP9s?5e?MV3^1+I_--M|hLa5tRq$ z5zoaNe+)h$68FlEpzw+c?B+b$+Jt#V_Z-DXCQaQxIg0lw!0l}RB)Bf2pl6#lWQrQ( zCwWF@j(?4G!4I0dn0q!2fE^5RAGWbJA2l3|HEz(KSp|9Z8uG|@zY^hTF4z| z=7DSr%z1Wv4*g}9oB6ORv<~;R$xJ9Z@9vL(9;>&{U4GUz$^Cfb@k`PiV~ImX(ZP8o zh&`67<`+45$J#i_)FG=k0_n1*`@=g4S_r+A?0Exp1xww|5cy1veFBJSyf@;Tg`=Z2 zeY&N>{cto^*VHzQ@5{)XDf}pznlrnz-9HKUzq0QCO|T!=Q2$jU{fDR-7zP9Y0YCr{ z00aO5KmZT`1ONd*01yBK00BS%5C8-K0YCr{00aO5KmZT`1ONd*01yBK00BS%5C8-K z0YCr{00aO5KmZT`1ONd*01yBK00BS%5C8-K0YCr{00aO5KmZT`1ONd*01yBK00BS% Q5C8-K0YCr{_{+vgGR_9;s3y=rT1dwr6^<&n&-RDnMo$$ z#oOM`{d|6Zkk992pR-@rUTf{O*Is+=J^y<0$X`;G(iDFwJn1}zqm=r4HCCcj9?xov zQuXz9^A^?_QN#cFrBuRS>^qq#d8o?xtFK>q@9LGY4}y{PJ$0#>_V~X`DW&9_W{3Wg zlz-?$%0IYr)shDXqej-}vY2q)YV=Gg`A)1)kJU%tjX$%#dhfkUSKRvmF(d0+Z8huj z#_E&r#QM}3@ZG)q{s)ITJhHy-B(uKm-(um4kh0s>xkDaVSW9*-ukaT zuz1T<%IoLea&xW8eQ|#C#0re~mOAB; zW`u+5>+f4WM1^zLmrGvbkNOhf5~#<=k|cl*Bj`FDzT6l*o>&?APOL8$Js3zoTj43Q zpM%j#?J@DCJh8YD-|>FNd8WR8>Eika*DPDId};lPl@FY=zV3Jv)RzdCjMIX68ex6? zJ&RW^9*P(VUv~_i)iD6%JF&i@lIB}|{gMZVM(dgVZTOkl-|xrxO-jZ4ChxIfC$Gkz z&|%rK<@XPL3mxKLO6dp8`uuSLL{cJrBkL17RPxl! zlK7L@c#3?d@pyQIpNx3j#+yw|yMDpkX}8W_Fm38RYnJ+!JUESi58u0F#nd@w1euJ# z2}=2|Fy2O~Lc&7Y_ZZ*izXtiXD7C{fO7(*)UX8Y1Ngbtpbg<<5QEK6JN;!zXHCFC3 zGRbp0-&N#Eq;o9GU{E=Cl)8HGYv?7PSLsvZFH$$XS2cY~*VHMq7yR(ujw^{PdovE4_l72fd3QSg~f+ zLsPF9jvpys!ZTQ2O#%y=nzrh}2c(=lwQC++dGE5R6^SJo!+sa#r2MqyD^^Zh{J^r= zGcRAV%D40$gBZli-(@@k?^8PXhXLKOZ^5tpT@?F%eA6g(>m5eag?|??Z~+4sFmM3_ z7cg)E0~auG0RtB>Z~+4sFmM3_7cg)E0~auG0RtB>Z~+4sFmM3_7cg)E0~auG0RtB> zZ~+4sFmM3_7cg*6419Xa{|TL5r-e?>Rl#Fc6;|)fi#9iD?dn6dyx~uqu3h=Yyy&l# z+U+0hiB?Zk?VY1lwA-2)_L8UNjpXR*b>*Q?Z`s$i$6EjHz-!uDrllNId{q@$+ z@jH`9OQ!ym(CN*ZS-c5_L=F(n8=+yG^5bXyAj@7{Y zo~CwZKj(?)4o{@gre>b7WIDR7x#5G>obY0oYHt{)W)4`go9ts%owT8kRkQv$FpyKI z{54v>zs5!X8tC7SQvga1@R9&mpQ))|A88(NC$h)3qsny5C-m{Ww z^>HdvmaLk+qg7o2p^H%R6`WSh`_ok2$x$l$+Z6SdbF&I|Tb<#ea(~Umd8!?^gSQXz z-Jhn~bEn1H9j8w3sQCFcYHr&#U5|o`=ah+$G&OVMC@G&CK4i@ccTZ65KBY2`k5Un- zKhNrqtUWX@>ZLFF$tu_bz4i5;ZP&Eu9S=bVeGGLafxi^hT%D}y)>+2~{@pS@&^u|? z*n&dquU%`r{Q}!TYd-al4}U-#N-KN!IQbVt*OSEICy}|%nits4BlX!XODsD+R@OOK z_7wHKE9L((P>1hJrnKDz@AN~@J+!?T7^E-l4{7b+rOw<@s=0h%pl-hyDwR;W^%xd`Eyy$nS z=WJu@A=-+Mscn)6I?A}Z5nj|Md3-K-uFR_UbqOLyJib6im#ntZw5(PP!CFF#$r?S<*~ z4#yQ*=&;pZt-Dg(dWk>ca8-n!Cy!&Sib_7c1ik@JZ-5`iHU5a(?dY&&s%Wp(QEj_M zMY^qeSjL@)JQ7M<_FU@GJyG}N_70madF|DQK821m|{DS4J2h zJcis5d9lx;cDLF+5ihdgTfeJtw?13$wyY`0n8@>?H7ooFYj*g)S*m@Hu4W$Oy_>k! zi{V@Hw_bL=yLY1IJ~TrGKbWY3*Lk&e{I|$g?rwNgxutDs*D=a$7ZaI&V_KSLgPlGUu4$-sA|C(>nAGkuix+WnC-p#|eb z2S2{z8+=VymWLdd+d6u!w(7JPEt;-0Y2hnQaW`J&k2GB-w6J$HWvHmosPQTl$pSt% z{cpU^AJH$hcX+dfPWEc=bt-~qRHmfk4VKwsRmJlUOf|-&+xJjOF}zfDy8fLll$AaT zPQFN%N?iuLPJg7)?uokGdWY98?b)imP8InWezQN~*|u=K^g}DoX|Z+KlT>=udaZUc zVH08X`sX`z(glAu)#=o=&h76{Rn5IK+MK;2b7r(|KQ$w;Jvw8Hv*YuYcPgzp0j1>! zX3@6D+n@Th_8lh&b~jw5q7AeyWvv!fxB9Co?uQ>p3h62*U}KDXpVdNZz|SMa7J8PCeEV;B`PXoR{1Tvlwadf zyF^})er=rRcQDV4oI~~0A^vE9KmHf+w*Y(MTv-SWG#-`Y*=0#B-!&ms+f|sPcB!O_ zU6$NE*XkwUn)ZuYExQWG`i<{a#-FtBN@b29O~%@PryiYpq>oZhVjn(bE;e)lkLOgO zN1f{C`(~xucPKT}L;H#S@WR^-@P#2~7#oY>`AvLpCcNj{9`{%2djm3c@oeG=HxqiF z^|Gg~w@5`;ur1jc37jebJ$=IrVxy_kO+#OOrgYs8Vo^UhaUsL`D$_tDI z)0s;}4g$ZsXuq>+)TWv;&EDvTj~cS6|2pa?+)OBN%lKLBH2dOy(HujY`F8odB|g$G zS+D0$qi*4qM11HMsoM(DRI~5&KwVVE26DKbw%g#VO7h0}#`YtRul{n?Jkh4=q~DWc z{r1xD0N;=C-2xtVy}Z@wD7nEc@5^rwEP9{tm$!dok;8MN5!XyyfdyH0$K#8(B3C}S zG_^z1uMZViw7#+6Zb70XPx|`uZF`H-I$RUdI*xq3(^;l0eFq75X_{SgK|@XJ z>*2dg)9nMAt?9@=neXpwV+Y^MEJN>UCFP-4HFfmJsCd4i_q4H|Xkwb+Kuc0}E!2DX zxlU)ArfLKqRa#nc+ls z_vU8UEp<8;$eO|#@P52nXgYlceVA;DF|xKyWq2)0)I{8b=OBi zol|cWok;p0rvFvz!}j9&jV1Q=_WY{#*4oC3q)5|Ou8*{kj=ZdET5^4)QL`5}Z7}1W zm$*%_xbMaCF^70}Ue8=+FYaQlnGUb&*P>JYU2d&Q)2juB&E)BQ=J6Wewc!W!^`Q>^ z^u6y0JnoJmc%J`!psumv`oZ>#PYu*Ht$*G=d45xgW4$B43HX|pBn^WnOqnzCY>MTH z!B-s1)8()&2e2H=W^*?1Tps^;fu-34KPQRvt$73=qv%wnFz14=U^gQ)?zfv9X zJzLKFZELbK_H&H-SR+`}%vDP)LHm7LyAF@Z+$cILy89e+jL)V13fd`W&G9eBddK$z zvz`+_?{s?KfQSAvFiYz9{ztxB^nruu&2y2P=6g1C?eIE$7L~at#k0#hAt|V7{%adH zee;?z##$oCEM zJw(25BuDo_Gsey!e!S1#Wytb+@Yyq})#?4EiWGv=k$si1GcY%q_2C%SYh%G-I=IXL zr{kbmX6UpvIVj`EwZP++wZ_w%bNcfipBHtH_1E}1RjIE)EA@5q6j%s(3ao@Y1xbWF z1<8aw1u29)1)~Ug3UnS@sjr@=ljnV&0z2P4ojmXJ6gc?i>EwBzry!MYo=%?kQ%hS| zYY6Z7-lwiksZW*S-<{d}d-alUuGa56ruuyks{Y1KJvd)e(Y`VMn(87|+W5ZtE$=PJ z=-!-8XBga6Wo_9Ww&wJ2* zeb1|q`?C%2^ya9jZ=xOyS@ZgBM;>`6v^l%qc69wa-icbU=Q&%*_ly?wPPFi@^KRkY z%KIqZt-L4kp2B+)@5#I;^PbFm3hzn0r|>?CcWcP|3}L>C+VAn#%wB8Ci(>^U5*??a z&(iO?(^Bw&@x2is&3+on* zZ{G{o$oJN0%R5J^N5mzk29De~B91;EnL8rRM!vG)alZtoTi1{7ICAyy_{YG_3tH-d zBXfqwZzcZ7j1h5Z)H`i>+)bL)%Un5mc>J<>{G{RWkHzCB4v*gzk1rS=|7JWse|Y?3 z&{p8yWxcCEjEBZw_+_>k982!bya865dGoFyVcKPZEBe@Sg~uBm52F&k0Wu{*f@Jobnpw z2`3TWNq8gS!-V${K1uj>!ha%sj_@~xKPNmv_(#H=3d&m|-f4uB2+IiP5Z*#~BVj$^ zorKE??;~s>e3nM=FY zh_`?+hj1Fpq(ciTIhS#u*I*IuzY`(Kz=5}M3h=x2=fI6P6A zUs`RRs5eK8wt`b{0U>2{Z9!?Jte?TXj;<;A52N$97I`8}l9};5`%}~`<2`vnX{S{k z4O#E(Kb+%<=0K}bZOirobXb?Qb$joYnF;nHbH2R_yWBWr;Zt|#bjVs(f85NYYcl8L z8gufZhcB+p-K>HS+EuV+lRDaf4!yte!PQS&^gw0H#kFD=@nah*V6Icxi$ot6yOHQ& z^0*$Gxlrn|AU9-={|Mc%@-efW|K!~Zj`V9irM<7ID@A|l#qQ$LR0Lh&ZErq2(gBV0 zc{)_&Dey9GRBBM>16N=;tOsLuuM;UM7>9YF0(j96_pg0;bp&|5jSrXjzLtmw(^eMm zM+55!=|_X~hkiUQ-?4u5JZkns+KKn&4+8(AW_|y`yWqbI{P%+YJgsf}$pTNLcbq5s zigi)H4n11$);q@K&5h{u7L>;6lEZjgxGC0`ric5ZRvY#cn}K_s?;Y>22?^d>E>;ih z0WPDSdc8wwdayFfU(;gI8}-d*`T6mBXj^C)$BC3_xj6R$*3WgVMp=7M_k7DJ>)L3R z_4#8k#L7Os`L2FxxAlAF!hg3N!^T!`)tj~)7^v$)Rx0?n%es)ze{I+1h5b5o^dU!V zHe@5R!gEByP^u$6j$gz9sT{nK_TnV*NPVyCu@KL92Byt%_vA zUp*Ua`L^bZYKvX-qOK|PqCL-RA=edz&sjq5B-Wh2Vr?;Ll-s51UlCpq8-?g;FPt8D za{q>`j?X40g<7$V_e@q%?;%g*c)besZpiNFbzt+zRx=;jxe+^hxyZ|=#%y%I|De9R zRiypIhIcxcPrkz(uEW0~SH0nlk@gG~TsKjrm(Eq`GREJ?RCTM+14EX~z#Pp}`kTKD z%=G@w6Ioq>Zix=ySf88Uv*2@g(F+y`E>Hd^Bls)D|GLUBC)0LRo2^Qt8{t zfQt0ZMdw3)#$oSjnz`^K{X1^-6Fc~Qp2#7-KL~gtVw;q{#PjZNoVoDe<{LwYz{Lkr z2A)1?HRo@2I((qL(V{Hw*)L`|TPP-;`^k{Y2#lKv?VcYVIwBRSc`(HWo z+hwn$S<et8W5^$9$8|3PTkzR3W#jfT0Q)!i}yH^YjVy5v1A z)XO-@gf=so&n3Qx`C9S=Q@ZbMvESI58rVDANFG`5`;b{~+IFWhFF+qRZMxa(kZ~^W zQU`1Px80d4+G5RX>V0OrvzWa}_^G-;vp3c4ZFQC{fS1@GLoe99*^<+ABqoyu&;O@? z;7NhKkUaj;*lhjm#b`NA%b52YS^rFiJ|B_372QhK9J|sz(W>c=jy~QS(^Rw({e3dF zx~lb#j^}~L$eZPfZi&4I(p6OIF9tqrvb&2FdotAN(QF;k<_Y#=+JGqy`CGi&AL+B& z!z0_iMoD4yOQTI>W;S;AWhx_S;#j+Y0IHZcmg+>aXl8jy4&gqv;QS_ zBKD9pw{5J7=+I5%oUG}E9*MM2%m)|8=ruA;14n}MH;|`2R?3}rb{zWS^`R5iyaPhF zLgcU)9BSkAz;~8o+l78g%L#bF+1}B*u?M(K;-O_c{^?l!W5kP|AhPrI-%nrYW}Yt7 z^uB|%C41WE(gk`a-n=ZX4^;T4uaNRG|1O4?Dl$~N^f6wq?YBeqite_MHqT~TcU|I% zwt`P-SMcO#pQ!Z#_KUE&*r=CrTGP_#F!po2je*GPr!P0`h;H-;(E*-@-&%HRk;W%d zf|cauoO|TQ+$jtQD&l@V)d|EfUcB=N#7hXN#`7Y0Y#)_m+O_ zrTkd>(SV&i(XM9Huli?88};bFTi8Q(UyF@ivpcG!jUQ0w2I4e_!_9XS_KY&k(d66P z=JbWNhz~tY>_Rt*?S#BCcUQCDE;7gmY>gF`VAD&N2bX@u6FD-PMTLvQMY}rPJAvrAk#&x}zao zm6lzln!A64efxW=Ienks*?f^Iy+2Qt!h^x4BIH!MI?4h4IyZaR<-VSh<}IGcbbJIp zf(Fe?c(-VdvcIV2qL&_XmSMLk+(TWgl>)k|TLMh=!1Nk0Suc6b`Jra1Zc#~1oA+#X z)&on?k2V{y6#>)YWK~*}q#TPiRmwg~^Fd%L_%877+vr3dm5SYV@g1JX(o+Mo%1)`~ z=|7@9MSJ^bkGh& zzaJs9n}M|m+zp3l>AuD8jeSfiOm-S<#jms5pF>6y}42?6!kU55j{83~+kUaXpz{|21 z(@kF81^rHqYVHLu?llFqvgYZwwi&kl0jmZ3q=hwrm9;<;Yl39f2KcV58--0-{8vm{ zf59)1Z!!3)ksaRxrbh(6q#?U#x2%&7S%d8p9HE~7HDHXj);msIG? z-ZuAaOZk>}9iEu*mH61q3>OjaPFL-Ptc$P^~+nFO`?-CuhZ7ib$dIvmmxE-J36a~cQ6OvvVL;M6)lf!8~uAzuDpR< zv0E6|$#zFQ@KybT)h71-y6S!X+i{B0VFWgO%*+yM%>T08|DG7D$ zf8ASRJGTBE_V?eJ${f85d)MfXA9?2+6^=;T4UWiG@b*n`wtu?b(faM==r73AS~M10 zOIo0HdvesrzPX-e3mD(uOOAG8Uzas~kM*0|Tk$*c*wkC%-|#QXw042(#Z1-i-!PAL zc2@XR;#%zZ7VVtEnAyYr!p3V_nHOb0+`n_)=?14d-EuQ_-s$ic{W-nvM)>^(_ej`x)ND zTBM~|ix|Ez7W=N%o01JbB*Tvhz3HI|7QV9$zowoss{P>!;-{1oPI0UDI&>}Rqx5ZT zbl^$!h?%QXRCMK^7+1_)-X&UuOIk7|PWY3ns-i8VNqNE1i%I5Q%vtv)HfwJkztc+p zlNj&#tj*QfkFbP$tmxKC9UZ4_+CG5&Tj1`ts$DyPWh2ia=Ff@c?Db877l21>S2Cxb zUN?`rt_PQMLj#*N1Ao6FzkjC+9wZ$d_({Rfj=v1-Zry~f-YIaNy<8lpn-`lnRi_8e zi_?_`PT^7Ddi}(}ldBAzW*Ohxz$rdQ2996E4{iuYvL4S0dk1lJCj8y_D-4&@_zQYG zQ9rVQwNON7U0Q)Jnzxws6k|?wl!j+L(Z2)kh97vMUy=~mehf@zUrkwk`(iCq_J_RC zP;6Z2>2-^NdEH+Io@}V_M1KOz@jCtJRN`}TYWY9IpBj8>0msAX#vFR|bM|WsTk#=G6{ zZhr#rE~igX1J8K|o=buGq=9E=_)hTL4=)ZFyeNKgdEwFE`7`+S^ZT{Pv42+4PuFUZ za`U?74&N%$P#-3v)<0~7um;Au-x{1v&E>F6o&10U}eKg@jUo6BDIr`D8k3gJocBymsM)$Y%%N#T14k6A~B zClU68D@ogjzI5E09R7R4E_~6%$1*(G6M6nQe45B7d2r0xy#@cPKE}=AX)4moo>EVl ziirN1OFsnv_!qrRe`@I0+cI_rNSARoK;8k$IEiaTC+uPWDc zWJ@2iWpYfmSnaz`<>L#qS>(%jgC;4^=re3$pCJn#nm8n9emPpT9~-5j4^EVEF)rLU zNwq)1cgx4-m=xKu)2iBgu$_AE)*?M(175C0R&UcHYwB}CtDe*%z0Y_;YbQEGJ*+#$ zKHP&nV&%l#P|q~JJB>2z-Q|b6@rgXWZay@rgf=%qqZ^>rJm`Bpa>A6eiMSG6ct`Yq zW32y${R1zH?Rwxf_15Wi?0s)mL7~OKfC_=X2(l~k2y*81I%N23%8)_l8#i}B2R}F! zSzb;k^2w%TP2#U9%Tvug)>dbuykDf6@6uQU=a@bnA}0sOC*zGZ@hlhlyo?nu>7n_}|^Lm-nAF<{h@KP`9)&n`{DXo^AfPT6x=zMeK z6J~w*)KYH&I4(ra9tQ`n0AHdl^7AI-7%)yE&)P+qp+~+lF0_YwM1CG(emX|FZ$fQI z#|Gp59`qwGwgc=j`3Ho*{@D_rhlXTq;y9N%OvaD&+t)uZ>ouXV)ylX|fmcSsGdjFu zgNN*lYX`ci#qh0`b*X;u^o3%7?!hK4el0zMduXtmKG{m~r$jE7v&QybRvVh7=?7jd zR!8^YVp6I~n%D#$N9lt{6Hfk!< zNBgr`?=Kd&e*&X<7A~$OGTRdxC$L8z0XvL59)AQcZ-D1a9(N(`2 z9jY{7QW5FbUi?zHb1t(7`;Hfx-c!riT&p6k@oHvm4m7z$?Uwo)DoA6$q>XnUum~KD zQ)@$&z#=wb?{*oJ!2Rs#&>sa)3GK{@*JO$5Nmg_o7q|O{$qs- z_JaSCbQR1?0VjuLov$~so~n!Y;UyitbFx`hbiB}_KqPF~1ME$W@K^Yy^2m72Zg0Ia z(vfp8CD^qE-|~a?tDS3ntGn?PP*!{@QwT>9+6f(mj3@EeKgwLX16yqub?nDarR~nV z4)-6R33S0;cfbcdq&+w5`_LlCV7shY>caHp%bLEWl`@CGz0}#mddjRjGko;;z?1$< zOt`TRq<4MAG1&J5{R8w*V8{$F1jmYeucoMo7aFaCey@W|;g25VgFfA~-AMi&pAI}J z<6=*?nzi^(@I$u9kF4->&{XuF2MLAGyrijQ{6EvmckLXl?b?xo|7SA(pLzIyma>O* zm5M&S#jg@%J}OQoBc16 zqs+Nc{oj(KE9r~KBN>OtBGyB;fY9BCT=MN49WwAK<51+=zvK7MKA$lz`QGu~K;8ex zcLQ`=GWs^RhHO3kIrw=4{17MeyB$7Q18&_DD?&M%t*-%D6ra=Z)2$QOME?+eeCjK# zS5rh6QsJ45iz4QFvHPxS)Y@17Ky(IKqsX2~PWY1B#YQRe9~&j`zE3~mW9H<^fhRp< z)J(yBQH%zh1!yj3ZZl*e^W5g&4AePEllJ5NDSUgNE<}Ig^pdse?sz)%+kPePHoM*T7UTjZF`XWJ9UQ;G8y#uvM+3j3IN7 z*9N~Jb9yFqI$LX`&za#nid1_$`90{|o!Q7k_#E&e@$!0b~A(m)-HsKwU|kZ->!=`5=J~zoM>R zOPzvy@d-F+wrL|yeC0>3(LCgzfv%5jeYcbe@m+vE*Nfdt^tl4`Igi%nEXZUY7v7Wg z8*>Qjy1Ghqxk~aFx*X%ri>&h*{LJ{mKf+#)Y>>Ee^0UT^R1mT@ zH{|c#yxWr5BjP)WdTiMFgvR(^?rtIO9!UpAvij-QLp!FaHU=`N56Au%CQ! z7^t&O+Lb;l+BN)!DbqDDu-m3#Z*ybEW6y7~)J=PC>Rux6z%ie9116gZlhJ;jCnD`D zd~2jGS-?r*ZIv?CHI7D8C#t3v~T5IqJsVQw*&Rv$k-9|1##Mjp)jr zr&Ulxf9c}vpatKmv$b&teXdMahAlaCxf!~?kM9Rp35(n+++hs~9LMkc-{6Zgov}5c z{{3>d%!{s2`C8~*Cp42a;itEhgVWaxyMo|++<16>s>prQo-Vc$@0IX7^fu=-aE9y^ z`@467&?n2`oe=l;9bVtST(Lt~p;ZzzOQxL^+QW{%4qJrPT(9Iyd+=f=W2rTTa})T$ z%eW6&H`cf=-S4E`Ijt8H&s_5v^N5A(a0LvlGW-I z*psoh?3k!#z6`C5^2n1)>Rov?b|m(Cdf=-^Xt&kMzAXF9oyDrTi@B&Q)_$1w=U@7| z^Yu|`jvhPDaq`Jdr>q?$ua~@+&sXjHCzyEmvexplPop!hc}M#r+0gOzlPymm^8$sy zyY0JnQWbL&XaV7ja=WM1sf(>L%PQrv~?#1rQY6gz%wZ+w0KLon>9CU zAo2H*b9}kD82W1_@#HT8kC~#+=7#b4F!uLzIp5NQ-AQ!!Jl-477eBCM1@_y=2e5y@ z%jOwZv#!j+x^(LDXP`5)7W^QE{25v2&421H&ibUQnfvDr;k&j{wXZ!sYEHu>bbR3M zO38A3u+J6Ht^S&>MRLYcMMt)Kn0ofG#@c_IS&t7sWFOj?OBxrOahK%HTibiP`R>MF z(mN?7^b~Vc9ynMDUD~0`c4V7Dn~6#8HfU41t{?+@IX+A++wg0Nim$ln$ZdaK|4teB zJv_%>(^rh0I(^G_!SyVg9(WqtiqPxBFU9y1yPeoOboN-zMXM-hm8HH!dTquJ=g}GX zof-YjG-xLD`XPNqkDmD%G+5Z8jq3ttp;6C7lU_OU9;2f(M!U^psA~>ml=b(!c0C|< ziq3t=@N3GY?!2(n{SPc&n&k^@Xt7LEg7OCbwpe} zLv-9s+u~a!^*o9_&!nUDE6Zqm4R!1g+0qoNgK=~P^f|q*5*c?RvhD_C-aKUA_2`J$ z|L2-^y+plCWNia`livpSEycsn28ul|QGSaZ&ZU@J&>K?n{1N;3a(5Md{@Eq=4wWiv znu^fkj2qm(4DbpsHP*~9=7UPkVfSFi?6s=M+c&bmPkLPL$L)b%B&TH#823@R`$2fF z7#I%2SM!0R5;(@|{z%TH<2&ZlW>uxxX7w6he{N5CC@&Ko1bR2xRl3;q=D)nnIO}=v zhbr_4Ytjj+<)Qz?23LqaMgJl)PEEhGyzn2PcZ19^>~D(Q_ZT+NE!KQT%NTPH{@V_f zehm723cW)UZt#8Cst2y-5uVY3>qLsq`EOf5S#1ZT4dynZe&HcGi~b?@;6E^bNIOw{ zV;U@F?;a-pU0{t8FXz+Wx7eE|GcR{t>5pjC-F4ZmZq8eAHvxWPtO^Vr|O# z{QNwOnRM55n+s-Jpy9XSlC2_7C z`0NWkkz(Y=n~eJ~I)g)et~AGiK5XAs=x9eKRYTL%l3U$3sWitfE!BaKm4kB})vs!! zo0g<+bsmAD%{RlfEBI)s#QXrAa&4cigpc^TvCe)xC)EWKkiI>Zrlnva3u6MV0a zT1SVi*`AWSA4#gc#NsLaTI%?WuPJNsC6}p^U7FSYak4t9q34b<;2IOSn|gk!Sp!wf zi}jkNiFHn08@kM^*Q(|Td2`q9XU-R$Q66{d418_%a3M5Tz;t@uUPC858*Sm8umV2{ z{LF#I{piL8<4n7K!6fFHoKELV&L!GzDtBk4gSWd(yuA+IiUn_)pF02qZ&`zQdmh~{ zb=Ix!kj3V3$M7}5gcL#*UzwIz%>kphm|3{atqZ6Ia2dpv={fosGi1)>o zGGn0zK4o9_1KN;2=>_PJ_|;hGcO~oFcwSf1jD;UMJrUC$lgaor%LwnAcsP?s&b6k= z1}DPv0l{&IW?qA3&^G9ZKXUTEaqyzZYh@Y*kPo4bj zgsfef4{~O~0dE!H!_ng`U+VyNqa0^T1=jZ|*KWx(^2%KoCd_B9m4vsy=)MITJT7aI z1K8{1elDU1vJX+i9$k$KKGGR~>;bq7b3IXhrNr37%d%!UerItydYMDZG-uNh&SDhd zm)VNUn~x91X5{CRLR&}XLakkNi-wDhxiylbX>8J_4GDKlHjWuc?1T%sR}#4>@PlIF?IY zS%EfW+?ITQ&8W3g*}(R~bO8GW=?xMHRkH_$$^<=IlaK+W3qnlrx|NHZLDLi ze-OQ82W1msJOG`_&_B8ugY{*x^Efg2={j`fLMwa1aX%9on}Rc0uS!2mUx%~r^~uWJ)CYexh zIbMw~zDIC8f-ZJoX$9s|=w{0WPR5w%o9dlA);gH;I$5jq;Oo$bo)(9-kTUT(K>yX1 z%zX}Hk4M`509{Pl6P@gf#^Sl=g82OzImpx!WToitI&+fPH{A3me*Xk}SN2Q5-5&8P zWlUL^BN~vKqTk%jyn4@QPek+?S^sWezg6ZB@d*`K(F2c)j?-hF$-H}YA+myb^w@;_4w;w#5#Ju6h2ZZ1d@A&jwkzRxSs#6QhCh<4 zJdskyh4>Sgc;vheIQy#6kKFus>4%BOyl|MfL_EGqy$)m#Yl5hMVtz+CYvH+N=(O;v z%mX41WbJqvZKgs;vF)@%>(65H8ar!U=2m}1-Q`VmU z-m`P@qv+##9@#smZ@}>Lo3(bCQ{}se@7MVDvj;BU8~IMYg*}9X^q-Jkn2>&&Z&Qac z%m0|~J^4fBKjT~G`gr}%^WBh;euQt4Px16;_-3zRu>C*q-SwRy{s=oB@NHtAa^k~q z<-XEJY0^P8H@aahYl??48f)|#tcY;#s~w?_Eyr`%eAT(0KsiKfevA_JuL zk+zI`Ee^DrY0K_fwt87{QsfBs%U4O?Mf$GwyX-g3UskdUpWtOvB`tecnw0qg=WhOO z{n*+x=AHMoism0of82Thl}V9Lv>e9|MzfFduGT#ErEfULZupV?*7+++KGu{&+CNJD z(>J_mZ@#N}^@`a^k>;zCBFnGinZ2*{o7x!1C-kG>FH*K`u@q%jnZ|`ZU;1V^ZV_f%X3X8mucGFmXE)uPYup z2drz8A}g-jSGrXj>v;SuI9+maOdCh!WaK8~f` zGJko=$MC}PZ%A79urw*x122q$7Yg8muIb-&dY?$*p28eQ!LPMu{l#xM_4Qr$%K6?B z@3$phISQ!TM&0i9A-nG`-)i6Xq=@%>NvuQ9F8gHPFg`whe-q>H!+}|*yfnw$yTtj4 z6W_UbzPE_$CQkN4;&Hzq&hv+XSyPaoHfyHiFyo~RSllmeF<_az)EpDO`M#2+PmB%v z7&8R}!207Y&YPB-X##UdU}ntN(DxI|OF8kQ_c3N{*6d+vQieMV@@?R0G-F0^wSRh> z(`GftOBuLwgDV3k)Z=9=`4}I%HI6S6Mx$-UjF&Ov$6vymk&ZtzccRp!n|GZ&5&M2S z_MMRt^wnepi^wDS&V}P1WUa1qE(E`1U8yz3I%)G4`A=$L*Hfl{>w#6~*#z;`a#^Qv zPoj$E6slnE6)HGheC!?mnyY?j;t;zj{#e-Sp^fj(@g1&tsio^UOX%v@7-`{*ZR3OJ zPc8GJvww__+t;zBV#BQ*t7guArl#~WbO9TBoZHeryOlNY7UpWhpNDzFzRJ_zYA0{n zp5JXjkE$%%zpd4xqV9t#UG_g^UY-sQ2rO;r6I~m!^X;75YbEbTR$H;-($}}wqXQm7 zuMb%`_s2SKSJ5vxtDSa0>XCVRK5>_)?^(1f`J$SsMQ=LWw6toQRYiWydY<3=L?%0$ z_5sW6=W9yc$^Emp0Am0ciSM&u=coq8Ex_0ajC#=r_zwfS4cJ>)qwOUB3l>N9G6VKE24Q!_`hRr6Q2(XhlnsZdXEOC*TPU_)`Udsb zo6x`N!qn45JxxWgQ;);Ifft&Iji-_LO5Ts7H&laXLc{e({lLqdqtF1&UsG%DPPO>jS^N;Meyh_+?FMsq0u(#Kl^9_B%}mPw4PO z7d+7x z)@}t?z4)%RUb-J1(G4DXevn6A-_Dtd16yM}QXT7$S-^$PH6L9RxV6TNa?r-7gW!xjN%#s#3f_-@;e+zF5%yIrcJg3vy1l)~U zYU$_bjDqL3Im7vO)9iEe?Th&CVefmJJ4l|;xidv*>P}7#t`eIM@u|>3Y_qaX=;b~b z*F5!#*lqJTW7Q)*P^?o~#~qEbKhj;!-CpdUA^VX#axQ&Juot_0p0>19d?jR`DAG8) zg!@v1?`No^9@arWZhWZZR7{RwFE0LDaer|F?!C9jS^qH|m8`E@Th2{`HtweUYvjsr z!99Y_GwbpLl? z1uowRSS!v0tIP-Db1e5!3d}!0AIzNn|NjfjcLB3E2J`mw!OR^A|5GrBtiyR?6E=)< z@k9oA?j1Ee|322y=gN;$i@`&8kLX(;^M(&TYJ`vEoVYvBQ|fN98M2bQaG6UF49=xf z2Kh+lk)gSC0dn%O*j&1mxzrt-OTUxI^YDyK9}e%K^T0a`cz+8`tTCF*8Ugn(-cSFZ zqsdI)Ki> zUCzvR%rm$3AbVHD`nWT({c(T$Tsv}pmA2lYtz$7cZ^3>tQV%>t+_}bR(-Li%4!BRs z59)41cy+~aIX`Lmc$#pYx-o2<<3F+Q=t3jg+>A|Fa4GuXWN<0^;AHf{`RIfBu{vr- z)FHa3FOxOE2HRQn&&I(%4C$Yua|+$i6KX^U9jSW?E{Exg$*DtkSD{n5G}Gr#!eenA z09%!;QT|pvV0=Qq_NOx+oJR-q4eE?%t}8x62mT`7Sn}<^O$RtOfB5*U!ba1$;q3GN z`C$Aa_;&sc^S;n@!zokty*>iY!`UXBXOkW0;_>*nj`Ly@yy#|JqwiF+FCu3njJ3pK z+H|oeF8f*C>~Pm)o9kcB2SumA z!^hw|@6L?i5p-Hx5wes$o#HeVbihMhMUD=8mL)nl$afxLmKJneMED)TBEn0pLC2+* z=#+~r!BjWl(}b5>qK@f2vv^8*uH`A`na4Aq=O#@p+BGE9Azo@V1Ad!cAF)7 z;`bGyce#7@1W!NXB$s&m?Uv}P=-E5CC+qkeYluD2x8;oKDbAY8+G!DM_R_Db;CFf6 zeN+Wc@Z|DdKT#bmL{}ACfasw9rgbHI8m}&qHGa!9?wer#o<-cY3FU5m#F}ja{ByoF zTN3rjTu=s|$okB;AuHbcCY3fc<^^dd5%zM@q+g=1#`DZ3Pxpxaxvcqttjj&6|D8Uj{15hV zBK>FuMg@$Cu%E4ef2m|&x@m}h`0Cdg{k!YG*S}v<@Bb7H2m1$%iLgumYGS&f*!zDD z3=My_N5qFMPS1T3_x9w{FOmnI1~~__;{mai#qZ5u4FCGs&rot#zDnAql$D1&^OY96 zFJJA7`-ICrhLkOgg^50K5~r=*So8XA<~jFn>TE$j&?~2{5SzX?g?0C>>}x4}=VIrL z*prU5yrf0^-#72f_zCBc%znvP`k}i(q`d2y=?mMRGxN1EpX1Bbw*%OF@o)Cfb|L$I zvJcUwUs{5@KzwQiTRJ)UV-2z*Aqvz)QNSNe=UUA)iIUdDfN=5NB~!3OTv_*iz|Yr zxX*O106h-!{@FmxF0o*yE=ix*x#i-FT5Ymhu?*&SG^gb8(>$%+Q-?iim#TDbQd6X-mIN8sA3RY^`(_XMJMbw#Qt9}3c(-ej*7*DPw8-Qu zl)LQIX!qn(W870tjdf4{Q96(2Za@c7oWGO4>=-@eyA2Z8{&IeMz*HT`JE^f$P zk;iuv-*A;yD*5EQUcRpz`u>u9Z(=;#hsxX`agWLvH_O!Uy#v46`1j3{zGW!Aif@r^ z1}wC(Rno7t47OP@BK>QUK6@zrsuAgrNcvSn=~s?OUn%L=4W$<+r0=EurIKDTls;iZ z`aP079Q_}ZZ>TZpC;0lEeBWVyFXsDQ`Cc?c-?!!aD=L!618)*nn7|XS^SvY1cd64M zI9f7P$KDa?R!RTrP1&75gCo-4k@OA7Q0^`3qTk*cbKT>j@0?+AdbwXOkuENMI9<&=GxdUe?|EZXCYT3y9!&_7%^mg484_bovV_K-)`I{%FS#!oD{fmPV(8`!rg z~t)4YLhk0i~ftKC(-lo>=rvI4SA(0!th&EoP?7OskVjuVMj$zF~ z`Eq<`bk3}~ZZXfSnRiZPhttXbs>NyS|H!<*p1V#&&Qx-z-7MgV^M57z3>iS4HqL>I z{jH01AABkEoyarO5AodoYKF{{Imlwl!GEC+;cFM?-6XA*NBFujmi|-H2dqh)2eWe~ z!ok^yRL)4GaaLk9=fTEse}&b!TTOgI3XsP=H&0v0J_tUI&i>ridC{zefk@t{tU&gU zI7jzMmFy4C)UjR285@1og3?yOtyPs4d{9s_7|&hht;}6I<uQdfY_2Ks$w>~|6VK-&u{D9=ormdb2_N>vr0_ z*~qh(N7MM`*~qh(N3-zFvyo>nk7nhYXCu#E>l$$Lw(!a4|C$t%eX4=wDq>?zuK%5_ z!&W{q$f2r`%jzl3Oj8;92lXZ62~V(ZCchWhL*Mk^SmU=Na==eNymcJkzQdf0S!1;a zTCFOB{l^RoK07@xRYb+l>=@^DiWI1@E}@qZh~9b`jw3cg%(hwAFBXAgbV#kKVg)oe%h ziw}hO1a9GdK6h3M?yJCoPJBVCYHsAclDl4|{lm2XV2f5;OWT~QDi*l-jesE-IM-^z zkjZ(B%)x#M3`UWSk)?h2ooRafkO&9esnZSDn6 zhrh%b9QyY8B=+6upMySCy%;e17vQ~d?-pkt{clVgKSTOiP2b$4OFx@i{NEVM6x2ZYW-mr7s|{J36hb^e1z3(6S-!O_*EOPldF4uQ)!%+ij)D`WW- zeA2Zkf!5XRV~P(d@xn7b&}l6;n}67(1vmZXyRkaQ!87>&CE!8ojLQarYrIx4qif$# zy}i{YFH1k-ye$2Q^YZ*LCY{g5&j$Yj*FRV+!PboN#XWO@D}iR2(5%&&QtRUpnwkC1 zKLb9KM&-s>mHWg5Uhjrcwg0fm5|pti<=Xh335`UK9^)C=M;RMk6=of+G5W;&WQ@aD zpA7n3&A5R!LL-wt)}YWvXmrgWeatrGJkZ(b^Ql1}vpwM}q0LF5&DEaBcMZB&gPY!M zAEe7jc#)Ge(oc~Gp?&3pYTBFF)6>JQLU-c!;Gy3 z2MbE<%vJK6RN+PTjy}d~b(S?UKhGMey8T-<_=7Yq7JWps>% zVi)(odW%i{O6P~SA^Gyq+s4iEQI6;c*I^>g}1ik?~d(p1A1 zA@vHc6$U4N89n=S9HzcleNW^6^7p_bG;8IqWhtxwaOw&vBX=fB{Ql3)_^uzB@$ou6 z-cQq1_tTTR+Qer?{Aqq`NvnRr z@YPE_(1RaV+2{CEl76Y^i1>sZj`;~%#O{SpSWnDP@G$j>pP-ZxKf&J7Dsr~AmcVoJ zdor>vDV(dd_pD_N?lt^*4&|!4pKNH@ zCUUIq%~^r$QT)yh_mUU4WE=iC@qTVf=x3?*%zpM_yPy7Q1@zMFY_$}g((TSt*;CqX>zm2wDAJsow)}@I!6T9d6 zadswbg6H4H@b)qH0elDCeLM!gHQF%ocV?Mq*c*$(?PWir$C?U{cuThO2#gC~!p zll%Z#a2Q#z=(qP9vOst}aa>x?(+4?wE3p2FvG>ow`=^AlC;laFzJ zu{S)0-|RN`h7SzN5~0x)X!NN8*SK&id&D|>#9R4|WUr=I2N)lH6J(Frj{D1yj5)@6 z^m*Ln^(S;JkueLu#9Sux1N{)bSvbuc!ve(@k^G}w!Nc@xWb2j{w z<6~Ir-z{GR+Tj^8)pZu-x}v3vfz(c@$HZ0B?1 z`swUcPiYq8lDU1h7o0T4=4Zi)$Te?ler}A-&t7mM^Rqb)$A!zlhYwuDefYiP8#xX~ z`tVB~=NgCN<&hQxi`-x>L z_-&+fl@WjVk$$%p@}CXvYJ<2vwQpr4WHa~bdZ*?caar0)+W z^!-~C*zeQspmcapz%5N=a;3fwDVec$IXX)b*~ z8}8O`lp#bb^@!Px!Q`|)I)f-do@HKe>|Zd zBBOfoVVQ-D>P1FnbN=F0?rF2YgNH3y)$Az_p1+X#tI?mW;Ddv(>63Y15c6ZHik-c< zGe*ny#-tpozN@73GLeFQgkDZMk zzXHaUF@D=gKW$@&!)Y0FZa7!bwr||<{7W*zk^(R`xH%F39gQ z%#^k7?dV$ayBhKO&R5TYwFNU?;r^53oYj7c{k${i%o^w1bk04aA4_DNauzzvZ)OU= zepog%?hbD_OL=tIPsr<_A38j#7yU}+ONYWPf37j`uZeYv9K#Q^?HqofTL#CO=?5x2 zI5Rd5&{5MrrCsp@6+gc!{QS6!rW$-2^1OG13_o-p8GcEO?p=wn;pe*rKgp4_m+{#) z2-nc~-vcZ%K82Td@a~G~5OU5P+fcO|xP0gk=fX={Lfgfh=LyGrG?Dej8LxVH?GQTE zkbF1w7r}|lZ6e=WV{IntEmE$DcKw&NL_x{^hx>OF+Y^C_@QjX4+Wl1 z^h1%e=l%6o>{dzGulRkCb^I>SW-TaZxDRoj{2)4zqVM9%Q6H< zr|U|84HwC_%QEGsu&LH@=JxGXJClMtm}{>f{nbac{&vn#c{4Ufld3 zasNMgTK1_Zzp)dI->VkCPtyY*B;rBfe}ms*5ZMyUORe0(+JSAuFg$5e< zOQNkp@FMjX`1`#0%Sx%!mxDj<8E_wFO;MR>?746?9Cts;-IW=pZSo*v&Fkcydowr6`*zc=dpW$?W5X-nXuiL3l6UryCBBh& z_dz{~ZS<(z^CEW3Z_y9$v$y&R`Av0cTgJ=I80U(0#r5Wn3ullsTw zi}sV(a$k`>TxT!|`)yWO#$_=y(YfdB^_w~8d65=zTe*J-|AH#y=V5%h*q3t@av$n^ z;^n=FcMIi&ejj4v`3*Spw2FN@D=huUroKJgneY&ND{cWrs3ZNeTWevgfN zA4Tr5kLiV%_tUP*(;|5rlY%)#S|tBcEt30mQn27#+}{jOAivXn@V)H4%w^t_y^D?9 zS#k~aX3{5VLu6F{by~ZVJKO5n2NBz^{#|~R1div?eJf>ehC9l`0u%e7_H^}DJwDzd`={`m29vp$rp)T-+X;V9 z##f_7OYNJ_dw~3Q&gV?A@>`*rBQQD3Q}Wo}`jY20hlAh5l;2%Fx)_-t=d6Xd)u#jO zIdHcJ@4XMvCiBle#!ul~7xz)Rie2aj8amH!Yv66*%mH@xL!-aB?DtOm7mjwbAN7;h z7QP~Uvg7E$tT(Carq4D!@jNj8iMu)W%=7$IeP5sUu{ABck@q6r)z=n})?7uS_ipS= z`DsWQ@+ebp_mI?RrSny=u+tUyFQ= z@_RldPgct~HTm`t;$UT7ur{H#mgb?REagRyp-llSj4Z%Y1y z&^k`%$ngoIhH~?~~Z!o!8ekzEYN~rVB2Ay|(xj`F&Zj)=kLw_mm982zh;wvsO~5BEmT5V}DRD#3x@%YVIvVhO*BowDZ$P**h0l?qY23pk8G7?(saX1I312Qon2E z>K&ZR5!|;iPs*OxXV{Dc?|HP{J}!wn3v!ElCaP$E8GD4I)LT9L?vj4wktcfCm%xAa zrPgiOb@<(v7x@i&*PnUE=R>=ZJy7QGuAdiw`FMeficAx}m;f%N->Z?G<6`}b_gQH9 z|JZx;xTub7f&boamfmPUaRU?(7rJrZNi;TS6hW_wn#EZJ$pW^*n9OA2xB!X3C-x_SU>QD^mYS@}R58J#Sab#s1iXhPQRyuMBCqo%i`z!z9j3oZ~>O#~i4% z{1Q4U=gp_5@%}h8MszJ=l6lLAZwD~G$heR@XyV7>%lUq6Xn-c?4{CI!X22P7JvtQB z_UgK4Tj70`+J^f!XnXG4sGYoTlV+l%x1{*!t7o)Q&-(C*>>9 z(GsiKV>X%_EO)w?t6kjp?*64dSBofP1~&cL!dh@8aCn|RpC-S*-*v#u49s@SHkVgD zu3X-wq31>48y{n>zOMg`z)U%Cbdt)uhD*on9=UAHo{`04_Ku9BA1SzOob;)9%o`(@ zk9l+CiZS~}J~rm9kwx@pBmLP+e~#(#`-wk5{6XRyZW4cp__v8aO#C}H#&>kpuIQFr zdqcS$QwSe(lkl;G-+7bpafFY*Nq8#Z6K)coMtJ&7!Y2|w=_cVC;gfF?K85h9Hwn)m zeA-RIrxQNohVVFG8V5{cfvJoW6XRs%TVv|wZczd>Yh^>5?|0gKzu)Hjk8QsH(&qbU zo9~ltzE8FJZf^5^uFdzSZN4wH`TnBKck9>Rjc(pKXhRodoSq)9w0vP!*2&oPkJZ!T zk=V+=od z-57@6rZay1W49VQYhf%mGln1SX(=~7pJ!H9fjiamgmCsF*d~;5D`~jj)shB} zWPwN8Pkc;>vFo>1n)i1Fhy>w6%G%t9~MW4e}mr!YoKc^dCp3(r>igU-_uUmEQQ zS?pR{i*1n?Y3Jbu^XlFi71r+EuCBFKgVlOQwK*kCZO_BcXtZ08C$5=(l_qOfIy#^eRo8+F_8p@C;#NBk zl6oYaBkt?8yOF1K;|(W2pYP}Y#pa6WS+(Wo&A(_Jx}W>!lEy-OXMEX%<;+2coHOj4 zKP&a~A5z%Pf4xtT{GxL^5qY2NQ;-WyMu$0vsT|Y8Qm^qtQ}P3lH6x|1U)^e|2^tCw&eEmBECh} zDb^tNM`iygx_5Htq!W7+c?Te>2AjL@P2`PI?A=O<|3`KO+S|~jd0ga zYS|;`g#Yw}Qnu3&;V#J&un%U;DA*b|k{?wo* zTGA#Y>iLkBS##-^(9~JbM$Qzbi)}N@fe|Cb20Hup@X^L-cVaJPI&z4N*O9FVJWtC$ z)~>Xx0_NUv*{SAiu(D3le9rj1WOcRl08X=h5HP=SFm|}Z1LiNKeRrt=Q#*ho!EY6^ z)?4BCY0{*c1E#8rRi5rae^gZlcZ}N|c?o!kKFxk$(oyMXZ3I^W8(qgb{6?6>BU5Y( z6VokVV$xxfpu+@xYt{s%{%&9*=SwxTyS1G%{{(&`{g3%b)!zna`l~8$6+~R0ek*iV z@HU4wO1^CV(dWF{mqvp!xD$PmG(RUzC#93sU+x_AUri&O14L$HI`GpGX70(FxWChA zG^HoRMMs&ytH{*NZ&pP9k+v`vkhOG9k1?9vrVV%htRVqeF?)EQ&tvo7YFBGjeC_rVgocL!1cFS;^G2$Un4>pVTvnhuZQv8 zfFr^+!XI`}-T@=6i?nUS8|bTqqep#B_(8ijJoCEn587exM08StG|u}MtyMw-G;5(!COW5?>gd``b?LTJ@urb145}u)HzS*(&FjLd)sk zbfIhL!CQnLnB?4wd7l7pcdL2dp8iTX0vjpU!+dCDtx7URr;A)SMvZW%(XT3Kj|my9 ze@#3bq^$c4+(|uxubbgH6*`d+stnx^&1k|Q^Kae&+;RwK?b7f4$R3Kk8L7DGkOtRs*O$AN zD_=s}UlN@2-b!;ay7!gz`Sb%nTiXoJ=vGZ086Wdhv&UPXt2UGRW>a4&^(B*UmfEQ~ z6B%x+W%1uKPmBJyrRMZQi`RO{EAxu;5)W_TG-T%Hewj&qrM~(kUnO=`#!=r~+O`ni z3@l_#WDOXe3tuC&C%8HpMUYFt6IYT z@%>h%#=NGm{xPKaMp9z3x+7+AI0LMp@qn|!P|SMdqbxVaMp#)x^X;f zNLE02V=!_r_?0SSm%6%3>oV&0ZF(rjM=OWNS;}*1L)-dusK2qdu{zh^hTehIjl*SL zecg^0_5+`B7V-sh4w;uvb@f&XY@MDuL?Dxn3)`<>%mbz9LppSZYll&5Dyq~%YEb)(hj=6L3eaB#i~WC#{2P?PTlzLAbv*+mCJ z`YSy9A^6U}u&4T_G}{I#(+gUS^AC})$;li6{xaT7aZ%2PsIy>J!2G$4lY;gE^PSd;KmNsbN*HYpv{ia{e;*XRd13l|uFtqtz&P8f%Td-#`b1^XBOV=)dfR7hY+N^30*0 zRaW?6qwFyzTrm=!o4;u7s%1)9Gi9RFUo#1w$B3V z$K7wWPM^eBl)YFHIC3ho|FG1gF3x;qkuhvoTo|$h)=?*Xy{TyblLy%oA58`~q)nf< zn7x5X>jR&87Cy6(y+I*+gIf4|;S&o)j=>m^eG0Ux#eh9?kaK`=R zmz{=79fEg%`Q2G#g|CGsHzbBwJvqyj%W1xS1#82w{R?8+iG6fuPEMUOH=)i>!R@8lFu#sY~+Pfj+9poPat|dPRdJ#CuqdxiFdycStIqzz5Ty2XHB&E znl%nMt+(?2=6D~!@N4i0jh>A!{DK2sp$1+d5nf?V&x4WXKRK_`@Po)#&oB;UjY@!C znO)AN<Qn@%sD@=BjtPf_iw%*{*Ug)i9S>3QWx*ND)qN3ozn|~y?fx26|VY~ ztREKO8-Kv*v7lpRqn$12U@SoXypX-1q%k8yJPE9`_d7h7*;^N2A3)NE_~x*gdwlL! zRz|L5?Ht^dw>uwjwG3Aa>zkHXqt2oy{tWc@m*~trqIR}o?`Qr=`0%Fw2FDrb2C}Sr zD`PK#aMRS9awRJOy-azZT5O<1)^wnrN5hnLl5ZC<9*I6qf>oJnn!4kfv~ngb>E}sW zD{lfY$K*{dnJcr5#^z(pfhOQ@T5OIoEMD@Y$h(izr%Bk>l=<2e?5gj)+i~^H%!GOU z@6pppTiWwBEn_&x?yCRE0Dj}UlzSeL4Pmcx1`Z)HjQJL|RvA>SWxknD^X2?N_M46DmrH)G)R#OicfP;*uGP)%SV4EM z+5tev?$sZo11n?fC&)~f292whvw$BAkuwCZuHxH#>-y9(mI)Jm>ivZ2`qRGuH~81} zr}>X#Z13{r&*J-cd}lJZax_`TnNPm4FSOv@&sv|3;NN>zaHHON>eaMzmT+VIF4k5( z4f6csd=~~O4w1EY$N6=3XMW!LwDMK!&<}y#KYAB!m(8m;91+0Sh#Ro*?q(N;hyEZ z#KoNvDSyAf9KMpZyx!bZnK~LBPlsND8yZV2jI$sDaag>tNnKY{P{l>954IkcZo#zSZH5I zXkUWTF>{+0i({mnB9gEs2^*;yyf241%PHZtuGgg1e`Og=j$SIJ4<}h}C0j?_O zOJhf62m)Sx4}OU?)k-_BAg7XV_{RFk+~MVQ24s%V!j7Ezeu?bys3F>Yx~nq%Nn^+K z!hK%bRd+KkPXhB2{tbQQoDw>V{Ptv&QZKfQE-{zc5ZOH@WXCa>};pK4Yy$uYGy~?L{^+-^O=)-sTdT zJSGx6AnO-bGSW}mqiTeH2#tOkIQipE_xHa?zn?p(u-?sl{meMnnap{T^hL&iz7{M= zezK`1xw`q~ak*K%m%G$qD);A4&F+6sF}A%Vy__FP`bOS^EVZk*2XY>N z`jRARPc-5xdFL~#CLZ7a#^+m%^Zm4K<1{UKyRe3i z9yvp6TW30a_3wdS1N&~-`?LpUL+|pg-@|==6@2Ca;Cm2UTWQm0#u06B?X|yVDoB3v z0Jv^wgX>1}eT`#py8YmIKQgid;P^D_e;W0*#dE5&|2;0ot{2Z;uEBE!daE*i)1f^x zv6CV5R?Y>nZ#b2^44pjivQP5woln9y$k}v6&4qAf-ArQ#&pP_g+qhGq&-2efXD$OT zp|3I?q}&qbIpNs&2JBg>oU?fE5AxpA+Py@0 zv51;Kp}YO>$kP1rHNJTN|MUEdjVTj6iQ1t8zPVG)2Eu;%=h!--#k=)2tCN1`qMUG9 zCrXGDUIgBf{fL*x@!G)ZSo6oh+y@C#h7JN2qSJ6}?~0MfmKkb~EmN_}-KnOC{3|J^ za~NkKlc6QZ@1!0#c=+YL4qcc0%3iUt*Qq9pv`eJUPOcHIg$Z@QR^O8z=Z={Y#(VYb z3E*9a$epwkYgAeyfw%C`<$q491CHUs`_D9%W8;%|iW!@uX~!Jq*F9o0 zDa|V*_4sfRKwBjYzFTCSEpwP3Y1~yw>*87~cC?(xQ%tJGnv=%91bIpUZ%7|Nrjav- zb4tzeBcYFRyrWgEIi|?>NWKLI@sw*;qR}bpVwE$ZGsu!emXOLDsIs?Dht~9AE?Y>$ zet7DvQHp-f*J89m{*(y9%F^dATDw5Cd5}w`%bDL<_`Yq(O0U`5BU_NYG&We8W5K&a zWFOGRd&ytI9SHuX%D>b(mvo|+FZd`1A2RN8kl)TGESj->D_dRuw<4ODGtReD>k@X~ zeYrDxC@b^QrW(o$kfW>|xbhj`SI_yQdpP#_ID2)|hv^;IW0@Xg?*cu4jdh`fz1*r5 zh4o{2KcaB9?4vqCC*&-rW6c#C`WTd1!q`&W+!JW;rGp6zb1r-D!HFKe=&iF>i5yF9 z?-p6#CGyIBoVoYR}0nZuf`~4r+`5#vOon{$#MAdkANljW8Rbd334Y7-uJzB+{>%n8&g-ccUD~q zyr%f9BlR&|mH9o)uAj00m|nv8ts+e&adNMaI`r|~NV){hGOvJ>e`LGrqA?g79znX@ zD!IodwC%F*F53&}676pXZ$mw=E6NUZM0Ht${Qopkc{OS82XJ{AA>M z=Yu$>7{t7|R~fiJ0=fpTbeejt@yd|`HLO|goFj{}NPp0u8D0>NjrsP<^ecnVal1)- zH?VG}v45V$eW_&b;4e&9F3hH%lK%wZf4X}7zQ(xcE##HM=| zb2M!{|DU=ZmH+$rcP`poK5KF2-?HF&Cxj?N)8bu8Gt-r_lt6XbPd;zmu}$VEZ8^YM z%uBcl^wC+eGQ(o2*6~(I|0G_M zLm60wEc3;lO8DUg1#26SAIBK1T;o=zPo|z$)#i?cj(fk&?p@HCg+_bx7-*Viw0kB$ z=Bhhu3~{zHe!g#9|I8+J*)vy=9SaN%@Hg9O`$^V%Y4btqwa^|JYl2U)Ihaejlb^Lt zKhayMPbZDPZQSQ`yO7H|+0&iet5km&tT?>9MO4iNc=aXcTc5rFUncx$f?C*amSSpd z?9DzAy#5J%RI%rj^;p(fQy_LN8HZvwub>le8el`=1Tvmu)Y)PTuQ~CGQg(8atd+7C z@b01JQ@(<2Y1tE|04K(y{*J*c-W`}tyD};FAK8ZT&YR5-O(cH>aL$46nM5CVGLH&@ zpZDABj^%qb@UI2_3ymSo*=Hm!#G?V*GuYfZ>Vxev9kwAlY-a=8dx32Zay)qpVJ~O+ zemKp9E`1?7DsA8bZ$JIlq%TOM|4s0*zP_KN?;p15yTE15Df-^hI;8mpSM?cSdM|Wr zSYzv}f1IsU|3^PVbtAm_{$9rFLrYAKRAZ-xqutf&B+8aKAaFTNe`m2TQt6k>gVXd` z{*Te-S4fAB%B#AbW+8f-h3IJ(qNk}8juJkOcVu5hAM?nq?(JUUuD#gK`V@L6HhM(A z@UqcR)Z@!SrKk2ZW*o^w|r#lPnDLIG2H*9ub0>lTF^kMk7>_g7C?8C(G z*oQsH3tN{3vM&pRmk)=hZwGJR9v(k}eOU*1s=%^K@G%$RV=iMC?+SCf<+{23MLc)% z<2jc=CR7F8X@uwhE&K9gW4v?y?{9nOdM0x{lewPBT+d{#XEN6_Wv(wouZ6UY<2e&y zukdL$Hu`3n94+4qto{<6KjaMcP3ep|`0J*@N{c=Qk@KLlTYrMO{d6GYn!eAV57X(( zH2Rc5-=?xpnF1f@)g$-Qg4SgLM=stSO4=~`8%}=%u$j-@?qH=_<}Ug>^*i@=t=saX zas=M;241oN8?nb|TVpzVWA}cLeQpne~?Bl+&GvUuNsqaMS1jlh;_UIod z2OWC}6MDUzG4E}EM9nd5$;!S~bQ%w`~ZCJ4B@%(y=$j8 zy-REc085zaWWehG8yI4XiHnYxr4nJ_ezTO1Y z^uqrXKH(I+=|vxpa0U8z3I6{#W03ovWWB-(?|-G?oB4sA=S6)!78JbE9^fWxXrX?$&U-%K zFH_3$m)o{XSr4V$P69vhtDh%Cd+lyLLc8Q#<1T!WKYq0^gZidY?-cM3KepG)k2SJp z>u@Prs_#dYqU9r%BKD_6>{E-_vlbPOtm59`>*zu>-pxLh^;%@ha_{dBXuvV}nv3yY zulXZ^S(Ot$85&<{aD8=bukz(Z^0Zx#zYjktZLLH$B70>S)A{6+F!{fY@Any7ZSzd_ z<$0U%RK@6hf8zCu$O`tvau*JJRF<7>zRik3e|HDDxrH?D({D){iv?Ra?k4g{dWT}X znr5e>wn-DHr%^~FcyBeT@XspnGk`C~`d&qUb4u_vY`V*l$^N1Q`Ju=MMRu9{h*F;# z>>bY~&nG)9=%pp%W+f=|(~3$WbBk6+T1=ORHw9lFUeb|#$i+SA;ix*>_WXvLomD zaEF|s>it4S)`jsTvQ{&$fIiCknE#)9Jo=cpY5iZe?kJ$nf``2GR^Fa#tGfbx^|>y4 zo)V|aA@zxDGl%rEq|MYlhde6{-0R@n|6ou@YdW?vC2kIK{?X=DZYT1<+_mUu2X(k1 zuIYseY@X@5fEgkym2wLx&pWrj)}isYLvY|hhqKYBI!A{o^Or)K_CQbQ_j~tIP73G9 z^8JRC`I9AUm5&1QkAG~;w;bD<(fwm3f6Rw!e({Hfe1w-ZXBZ;^q(lF*%#DpL7w1MR zusahr(BL4&R_(`?o8_ii=CN{U2#|;8^U_Hpp zotOyPCop=P`{_?~RoeZkZ)nsfi#rc~Vw7o`e4kq!Htk&3&g~AXq0Um?pV`*e7FCKZ z;nJ>Q?GACDy^pHYJ7|Xq{m@Kg&wW%^{c7O8v&A?+m9wk9=uL5NHAD8Ve%w1_vBSr^ z#>t$Ib-z!U9M2dS%NSVB7!Z5K&Au_8H{0S_JqR^7B`;C&B4M;O$dz`Y<^BI(z{CJ+zE&uV|;h=_&HaI2io%7qkb# z=_znIzS|4hspubRhejIgHdPsZXk?I`{^48fb9LWtpZi7dFws4F5IpGdt--_Q(*MW6 zgQPq2cmBb{W8mS?NW1+EV_+_LAb!#zA0CpK8$u@q7k*f@#YZjg8~iKqaf~z1Z^Fkc z=B*VP$eQNNW?eEfE`a|a3;jzpH$>XFQ|fluqTJvUy`3b5`=oI=!LY|qV)qrGkE>E&5(=={p9&Qf<$mz%Sc zPmyRW)jLY=7|sZ-W^ul-NaAC!78>2FJR(d$0WS%RMryLfjByhSoR z<(qo_ZEcuVHuTkX0Zw2$p%8lNw__^sh~dmS=V0G^o;>7DlZ(tk^pfF&r&qn-s^@E> zJqgPLTN=-M|0Pet%0P60y?S-}e;NOgZT`2AKB3KjHSvx%|FwZF`<-q6UkYr|($Vvy z{$p=?+hXFKZhu=}yF-m=PW=76rg(LpjI{>dpBRnr!OsC^O{^Erd5hL2&R@K?PfNl3 zrSlf9<(#~sU-zXM$39X*rHvbAB&^>9osjRndVMctJmY7A>YjLw*KEU8nu~5m9lV_v^Hw&Jaxd!}RuduGpwu^7Uf@G;qNB7+H;hDl=Ame z{sGGWtKRS5(}rrTb43+x+No`&?-t5!!rzbUK>5RB25K{b!2;YbaIfPo&2A^~(1x>C z1CP9pOO=V|ij=YnHMBXIdw1wBH1FbW>jmyyoX1sPh#B5r4QmJkr{PMNC*I&n>cKmq z%WX=#EsN|?57?sH?F$>@e11_-)V@Vw)3T$Z2WLks?KUkkMmIF|5B8#H;wF24y>XHroprgBv-Ql=RYmCvyQ?;N>rx!ae<$n99R0EPj6=chd`x z?;5q?qg|s6Ir(3XQ4}pjQMDd?FXww4elh=V@x2c}W%_{0*|_5A36raFfIc(5Vs}zC2e2y%dE?19P>r`#Xftw`SY0J0^4oevDfd~=eS4o#c8UX7w3ZL%?oZ>v-J1bc*kx;4C`JY>xl5g5~uilp>K(-O9|NKHM2gB zCf#w_TeG)it(zKy-i_RU_ow&gmwYmAbRL>9G26#K&j%M~@L(y#P7%D4@W?{f(p0q! z{^$bw=F^kazm8PljpN{r`oO#NfgkPz?=n&M;azm!ZZE}8R*znjcAGElAz#`vzO*)Y z>124WYsw`|FBd;0aM!3l!WZdbl#Q#Hx ze(6fGElN(BgpOsEYQj#l*=kyBnDz;FT1<=WQ6_Y)a)>jlX6!jztPbKFgqvfLHw0R( z4(`rg4Ra~z+1e-rM>;)!rc!^kPUVLqEMY$!k%(T>T>$yO?H9Yo*BWwX`68o8?iE6kN`VcPptR^+d8lWUuNt>tIt#1d0SnUHyYa^{m zN$O*;Url?Cw$$QmHYF*vP)!O^)Fe|7eWg!&JB#@*de2 zZItWp=M8JF^Okd6P!4woiA84!K zMEXkGbAYW$4gI>WrApHNK>pkGwMqI3JQD;aZTj!U=d2NC@MU2vu|ET!79T#%UVMT_ zJFw_azu-f{&(W_i;G*M``t`mG4rymYV3^fSy%PoBjKxwl%nF}t4MP_*jQ6nJ)a|D2 zrTC@zq2MMIxP{R_D}5Dw%Q%<|u1W=Vq_NQ-8*uGIcuAn(+J{&ABY4fBUH-9d0;emb z-@rD3apZ^7HT|SNR@&BwzN}{K*2a z0~>dSv27lrm_09|V|@6yI(71qStC9Pf82U_@r#zDto4U^=UY1xGvdWSUp%(`Ziqil zyxA9j;U@7Hh-Yok%cq_j@~cYHi{ZX_>bW64koXS1cjVu+Hot*a}kl>SYko^9c!*T#n{Ne*NjY4As4r=bXau?fPb2+!z)kqsEF zrtP(qp#h_}!&igXTFXxAsHKicz-TpX*W-cF4e`KeHEq}9fzb`|z-Tov(&MS;hInAK znzrll)N?~TFj@_a^myvIAs!g521a^3_1q8-j7q;FjAYD%fY_XS#(K-cP@f=HZwM?wAsWuE@e95pHtNYYbv(M^fd570v84OlkO`n zeO-(7``n?F@Yr3m>cnS_uXiN49OP0l7dUPi*TZ$oIK8b^1&&1e(1*HZeJ!PJQg;b$%T+CD4#FIS zVGqs1zQlT~dYqL74)zrFR^+gKaFcMQYKR;AQt72LN@o@z-*?aO%#20G9QU!(-w=?{ z-xwWdSGwA?fPfMGi}{{}TsIJZV-H*2mXH8@aq*UZvajnoGU5Bm*e(5xgcsIT+Q$-C zM7m z6t5jlk&|*>Hs3MO6Dc^FxHxRuT(wX7YSNXCngkD0YQ4VSHt;bCdHQPR(~G359i_3x zt+t*u_HoLYK?UWN4qP26bIw9PCXptMvP^-itf%Qy+SNX-;w=la)0Av=DseWwAF`)p zeZRV=Jc+E!jJ=06XtNn7`p2#!*OdebXOEf29uuCSEEakEhK~*TVjE+2NI~s=9rkP+ zhdlj3+#1|VxP8doPvOG4#d1y(t7SxQ)c*E*aQ?&5o3u~y*CB8C41Wi*htKgpU~hj3 z*ZHmilap}!irLc_zoLb$cvTy?Vu!Y`_%;4t=f95sdTmeihP;!wfNmS|QbI=8c8}hm zb?_}tb8uz&!g-< zxC+(STv?QSB?lTRcYWe;DY&_uamks6oN1lqZqO&3@1H~G;iJIaBcBHb`vMXszqP)S zbBNm~zYxLs()tbBcHnej`iRNzM%k)vCjxBXF>>20yO1(eCM|+n%#E90CTM=d?c$e-pMOuzgs{MC&>1 z6+F>lvNgP$(taRsz@6(b)mjQnY~8{JpXsU$-X`)7k#YHCADj`?Ag`^lpnqXq=W?WB zV@ow*yNCNR`&lc%g?kQg*a`d+@o9%{tF&3>dECLsGmPgz+6TQ4FIGYrd+3!TlL?`{ zcGd-1Bi>PMmj3tT*PUZNJdx9P#9?f6)N&_krxN0J(GK+Q=N!k+WBvGC_RG+V=YQ1q zo@2oG1o|Z>8LuC5CcBG$natzXy>gE`5czr#a`s^MY$o<@X3nH7=nxpngf7XuTM2!! zeMo+}YbbWzuFy|;`>T_wu-*}opv%)ya0$Z}%7`?x)pKIJQtwjPgTA9wUm2s+-`0t{ zvfM!^;BK{t`#BS^yOm>%bkB1t)8}v}#zFraz@RVkALKXb%?7JQ-a|Y)SgEg7J6UV# zXC8MtOL1=QXQm|{j6BPI>Ke|07I2UJ6ZArkLQk8yV?Kg3QJ0py|32${33zTCtX4+? zy99JT8spiM0K2B%@V3yN#zZwK=ZE84L~m5yr8$AV-bv0TWN+JuF76EO=YC)?d9L(M zb+mAollxWSjf2to$BwPs2{5S@kx2~+o>|x?ReEqwhrVKK;XSc0`&*02(}F#_4TcEM zUR=U>SKT+&FLo=W-gSm3&#y^83wtbLo2bgti8jc;saf75|D1NpTVR4) zysIPnmSVf(tA%Oca00kY1*hY|?Kt#t?nFPsP?ibabAdPSWHx6()8zhKBEFPynlci> zgByF!z+d)*Q**KNEO+Ir4>~<^Uw)WsXz-sIWsbmR@6TP1Ebw7s%wu;pQuKEdxaU*= zZddarxQz95d<$cpca5I6;5o|}<&I@cSgD&iq2Hli4gKkR&%C z+VFOpHnbY9ZNoO&u*25|vEgZkj>y@u6COoup*o=vtrqHM9yeE*2AzTaqJuHjPP%uv z=QRa)m^lqUU_s7oJ;(n+^2+~d)#8-=%x|4XY~<~z9gIa8kAf$eOQ(^Co~PUklq>xV zLDnhnc&7$>=hR@{Y|Ev-Cgw_$p*`!cGPMuzyv*GeY&)k%ViqL8(um zeP_@?{{q^c%eZ&+O?|(5LGERX8fp1HcNr^;o!p=8Ss!U(OjQ~z%nyqv%hcJk)L=?) z;e7BCZ;Hh-7tZS6U1}PUE46ZuejBu0^t%0UXy%@~j18HK1uAng-a9AHaOb>~zI-uW z!lT@N7;RwwI2m^`cRrpWbkTnfDK>1PYLGYSaY1^VcRqRT+eBdlq|-OftzFD5`1kjk zfZIWXxxsC;rccB+RPCIcx)*`b6S!JnREk4azkZ2MTGpY<;H16K zD9REW{}E<$!ygUGyBiGc!9#n`t>|QtFU(DNhxx~uum8@s z&Tp~yB_KO6nM@utGXEIW+-xdZ`Am~Bwgx$$XY_pK!e097{3_-BRMxh%K#M0$HF(lO z;JwIG;N!`v;A=)-;4U6>i+QWxxsz%1+%abc6rg84zNLDVW;4lWhLv#$Pl+MF*0_3*J@y4ID=Vq`@@xgj9^W@vWTKIkRs*=!A(P6%q zHp*D^!+clPw}W{Y@O_#-KZ2Wq8-gn%Y!EPi8a~*dg`xeH&5)?f7c%WBLAZ3Q&!=mdK$sEWIch%nCCAs!3#@=>Z8BXRxhHp6C8vU_Hx^2;BbYq{yo~evHYlr)}qHTM%(uiYjb}nTOu-W^3M!?dlhNICuXGao!!AiyTn{=R&Le zIG+H{`+)O4qe2GvT^u;AZ&#y^_jx|N&w}Qi^vyrB;5`_;2YB(m^v>SvjRBky2P>2P z`elOuwz!`^Vb8W{=pYQitpo2566~GylvwnRpZ0o!(}RbTfv&X`PH6 zaxKl4H8R<}XIoEb@y*u7>(|d<=(DVovPQ<~^wHXk?YJA($Un82$KSL@#t!h(=6Ke^ zwrk^f=5#OIn>Se_MJJ|#^4rRpMVER%^VECS!25=}=>1K2wzs~&UDalPD|=g6pT}J6 z0}m-_BXoNoe!VW)XG#3B&%Zf-?`OA;U%Eu>^R%xqV$;N5uB@FE@cABimxTR8JdUyO z*5+L^bJ?Se#!kR8!u|XH_`lt{Y-wBeg>R0pI(Kcn0zWSD3E{=Pw$s|z{0Fw_q%3hg z|0?O**QoIRV(Uk2X^9ODf7>g8iL_nh+|u?Y(mH8>8ts>Tj=%l>@~ZygEidl6@}wR9 zG6f!ze*ftk+v+c8^Pjxs2#(~O99t4s+f+!K+KvHbO&=ZCVvq4=XAS!w?{m+mE4^uQ zeL97)*tSS*_J*0qcy$RaKHuz6s!ykQ!y>(>Tq#HLk*?-7Z(pPzjcA$x?_pmq|65h7(>>N}o4Clg_Dgx3TVL(7Uyn-kB!#cA(6&VQ z-~wc~%}-ZE&gHv8Rh!T9Jx>j>Soohs+-d$RR7FpNOk=p%t-(mM3RaB(n4~f&<2kys3V=cSR)U|KLOZz4+Ma!-wdS-GGlZ|KG=l$ir`j58j&b92UK? z|9+etX@ip^|7D!~=>PXPIr6W-Ndt6Qr+#Y4=r}+Hp!SO z_zvr7$aQd(wZIQc(QiJ(Iow(H{wct5%q`&Ph3`Lx<5J)#_Xz!Pto#Nz9-uD*ga0;I z3NI#nj&Gj(=ULyn0!ROeuDb2aHJRr!&uj*p^(^zeZ{Q@0;8J)WnT!1bH9g)t4^6&# zDD%ASJe2uzlX=KK+>ci)dj5W%%Rdh}_wV0#dx0Yh{gEPcM!KU%@gg$Lz35voF8hhj z$KyW;o0gB;j)TUyk@KgYoAJcVqv)O-p7Hq1c=SxNqhsycIdc!N2iUWVH}}gHT@k`+ z(P7w3S#gAk4vFZG#1(I{_eBR|fZUO!kI=XDS~b+V6S=wvJ+Yhdfp60{;RCOy0rJj9 z8uaEkGBbZax3=l0&>G>Tm7cx7FTRQ|edi8p|9JFAr0nVqwjXEx z{ojcGs9!04_o#``tiCtszKC9nJIn4Y1rDo$1NuBp`gT(u_`CEyUF;M4_-a3n^**ZB zt2A9`Z38rRF8zF*KEH#0$>C9x(Ls6K`Uz+DhY9!UpgbO#2hM-BIBeQGYX9`}q&qii ziuG{d6V~hDln?H=b0%?K9grSw2yYj5$5ixG*I3UR`#Zyybe`4n5;Pu`ijQ#l9q)yBm^T_BOZ7iw=V1bI{KT^2X*Z@|w^gh>@|3?ufqs zSj=0}L$LqNJrvsjSIc?y6?}RTWulXdjm73z=tTdV+!5h@c#{hr`x9em&1lY9)7fM7 z+dpqa77vcZtKF-BpA8uVchWLK=-(&wPx>f(Ljz%B7TKcu+e4#%wV+?! zdz&G>FsSr z=keT;ikXwqcN9HF+52p#pHfEydIDA#=MiyU{sWl2x1KohL$IZ9pQ4n>KIbg^oXPaN zl{Nl6`=9Nco6b`0dUz}6I-d~sZn!dBcs=fW4Mu6JSrS4eGdO+Y6-IvN<+?4Sq5HeEe+j$(yM>@SKW^U8IzE zzoWBeR33b;aoY@ro{o}n->R`-%r>^>TE~eUF2QE zf8}DOd@p(97a7YRAUuOGDOb{+Bs_@!SmJ_-8_#!qx6axr*9QArt_|9_lnwSRd^s-K<8oSfO{YA@r9T}IhzUfoKtNLVc6$? z^EYwkd7sOecc;sc_W-zibJv!Bdva zFJ&z2`reG+iN5hGdM7gPFW&uobZpe>b8`N&I=Sw27wq@NVQ;Q0Z>OoV>Q|OLZwe=2V`q`eYmS*$aIg_j};A(Cy;=DZA$#_WIn3@UXViCVPX7Q{hj~ zEw<`&DU5c78A8*`#J?@PJnZk8@5lVzI6v&YikVYrU#Re>zB%@1^s8i!S#M{K`RYnR zS48I4o5V?-1E?>6yN$EdfaVL#v1I0$$Y75#pL!Y;%O*X}*nFP2(MpIOK1&VN(~eeb z%_m3~15bOL_??t-5K;d$ep+p=0`GPJ!`RAp2Aq4 z&6rPNoOfrOZ}5e0^o7fu>q)rG=PX~`Y+u|M;^K)b@`cMBma=5-_8`2tI5zaY;@HWX z@WjWA)Uo?ftgk_Tf^*F-G?=Mz`R9g#SF_bUf}9 zWArV?=*NuD6uvj|og&}S&)d7NP`*UFc$*T-Tez&xM;WijKWUwQAGi}7hC?4`so^>e z)busMOB*Y7+8C;bAB8pwy%d~$0xk+jFSw~p5Ly{#nTP+j8fxi_uhUHQpQP+A)KTc8 zm!ZJIPcQpHM}=md2S;)bS8Tf+M^C4RExEQ=gsWC)mQJhiw*cR@_(DG)#us?crYwPH zHgL@r+6Ha>5wOjMuH6TXybpglX`UqPKIq(X(%p|gj&!dQcK_m_@^Pel0RIjCr+|}< zzA}ZTKFohMarYA!Po8!9zp=cBuk2-nZzk*w@n-eB40RjU%iZEAUxU zwD<5|#(x;UJ^qh|ZPcdY);Y865zZ{_UDlGJ{O{nu1OMBdarO+pAL3iqm?O-GHO@G# z7vbaZ_i+Z_E2wB>K!jQwY+Jf5PEpIkQqZ%(rnJnDO6;T`__vs0=XhtZ?Rsy6ZWPJ; zfxhu;#HLo;bw99Oa&2&=tM*+VY+k}|JATVXcGe1kg{=Fs4$In~0xV>09RnN!fPt*7 zn@G2rG(CVzAYp4IoOCk&Buro>V^84P6JDT4H{k^yd@h_cfrQCeG>~>9e8YL#AnU)t z{}gja)^}O|rGDWPrjhR$Wl8u0{GTAd@EbzYsqg|P@n!vAf%CVGw%Chl=Y6zu8QV_ov!c3GY=dE%cn%jMhLv%26BDpV{!CPs) zOB#^`AC0XL$SPs`U3S;A$O-^iS-_p1VD4 z-r2$7*wbi--I(_CF3*ZU*SiCF?O0vGnbOwVWbYo}tiYazU#|N!Yr5>M=b=AoLGSJQ z^CAryhx3|nRX=M=C(JLm+^HJ$Gr-3Oh>RDVW&AmE9*FPeTy_qwqK#dK&l$6F7MO`$ zj$@+>N4c=gaqRZOQQM}h%n&>ri|w`k*zm$p@~y`8T3`D{X-2SfqP9yTW z7yni>;?@q?l(!ta5h($;+HAdt&nxTwL`1niBmGyvrc`Uf3|{sm0+x z99_wsqYc`z<-gU6hE(P$C?N`H|+CHyGFhA z><(=}#}WDA>$%HB*joOl@;`|G4E`VH{~`WACC|hBr|~}xI5;V1+VWTOwiLgdmtFi4 zy!Q6I&)-k3-Ol;#eC|c99r9A%sv+C+!h&u?N9?xzSBAZ!Z5hV>ANsf@dXDz+%-Fn# zyFG-C)*$rCoZ3U!{^^UJ))x9;LkH`A%2_jHOWqb>vuW5SEt`DV*f-mP4ZUpAY-JBS zhBV8;fxvzvYoQl@_Y>a}SohNA0JD3tfWZ^4+7r)i(&E-{(iGfYzO#LJ6&R=By8G~Z z40!Lw^`z`6xH9^%*4K{Djk`usPu_-M8}xn&p5wr;x8C{mW1wE|7VzD^+eRH9FM|)2 za+ZpX6B#4Jz&H66@D>N&WLyknJY{}$BwEnS>Od7#!7x4Hx`m@*@ofBo%w@L;+d}pLZ7g#? zka?ZPydFnfZ|1bj`zeNA>*p}9rxIpiPG{h+Vm?p9pToSJj-STdogv}O-MjE>n7?=9 zf59AHzufiZf8w4qDjEum+D`l`{AVjRX#auh_UuNji8<$B9Q~DX`Fmi#66ajLNo#m) zleTTh);xFMZTWv4^838MelIrfuQ78qch^3I*W{%Ueqcy-p5xxwJV)2LTAGAY*I#3L zYk6INuieqLw>Am?IW<6AsVdqk%CCzH(-NP3N!!M^n>t%7Ue=na?`XwKn(5h>wN}Do z7y}i{cjl!o-_dT z0rmd1Vuv=Gc_VfB`&vQWUq1Gl_Mf<_A-~J}UGQ!Be;?-WYmWB2m;}Oqo420u)?qvI zymjYj>j{^B{yygSn$-1d%uems@nPDd=rs%Plng&7XKpUe4&<(6B2MnJ%UN44I+MsD z%4!)8FESSTGY+PJ_Y2qs$OP9acwP#Qv%&9JaJwA5J`YYGxaqi4i$bDKEiz4e zYKcAS^Vk{I*RaR&$0b42b{fLmpARmJJlf7R|MNjlMGobT`%jiAQ9G8Hrmb6|M!nj7 zy7e<9BK;|Y!TK8ME0EcK_DWggPSXEj(7MPW=sB{FiaHfL&HAYlX#Fv1T9qL8DatG$ z&0~Wei|mcQ>_F}b_|N*1(KG&R@?EU4Gq_JRy}BuW8f$L`Yw*;0=Wd@e&u{Df|HW(b z8rJ4D-(_u9KJ0mQZI0tx)=ybGWo?%AQ(tGl!`fVQqUSBwW?A=TZI-oP*8P9=+T6%m zY+;SEsu8Ts9kj#zhp>*xdVRCCxso-p2$%oAyf!C)=e0Tb>e?*pvaHYl4|``GA61b( z`rF-Ey3+~SKtlFFkR${QlC6ad%_@X&0|XUuA%IID&;daO*@A{OFoNJR8g^L%G$4xx zWeF|}ZVZmfFu(Chz=c%-K_QOF`<{DmhX%vA%*^k-dGGhf`P8X<>(+8^Rh>GgPMz9E zJCDXy=UmI1&;O~DyZ6G)>L}nTU^5_mS9r1TXW`o?;KjX}s{-KBeS{YauO@tl=l_Yk z`E@Ve{MrAfytyaiSa|b1#`3kiS@^0qZyxzp^PlC-YZ$x2n^PFO!kdM^d-LWU|Bbx) zy?S}G0&iyRVDRS4@Zq)KR(Q1V$@k#Ti|Ny;@MbIgdIosW)YYzm@aGfoWjp-Yvqtdd z!QN{GZ=Nk{1S>pwc+6^zZ+dvM@MYo8!k4AoUGU{az$ftKOJ2O$n+JRIW^bM?yjgg1 zB|Q0m5zdI)p+>_0e=ToT=?hQN4>t1O>*LKY@^72-U%T;7>*LK2{{r4T8s0n_-uyJY zd34j;;JM*FA2xXNWO(yAgExP8^ZdxR@aFmdF5b+2MW@@@;n{)k?jYpm2FT4g{`I7z`C$2`K7Y+*Ei|1^BO{torg&XZ$^H;ia(z* zWM`3;g*UF_U+6s7$K8>&b}Iixk6YZrlk@mTgIHsWtgJsr?q#hdYwV>fnpcRttUouo zXM5yjp06Tr{kfva$xjo{qhHLSUpxaYyk6wvSHML+mi*#hWNlz6%@G;7mggQh*%#UP zEHd(|N~n51sygR2YSa5q8@?g9=2EKtib=}-M~FOJH)e-mQeMCrJ>4MLKVM` zYE8@PoLv=57%NNE@xTC}rUkOY!X;`d&>0lk59@Vtm= zo7Fjt-}Tu0KAFDWRhsU0xmnZi13p70y&rjNc=|fmY}VBxFV2oBMD8n5_r=_#$%ji~ z;?*fJH>!V%S)n#SE^?BeM~=QfeUtXhCPR*%l3wNVWeq)2WKm?!kk~=$QsnEd(4Z6a z=!@JLgpbb8f~#|!$cCFlMx@?j7p_tj>f4_=L3nR2apAFR7B5$m!E-?7(yAT=*T-x-Q-fHFL8b5U!9YNoD&8-M}0kVa$n@+)yNZ- zncVKH$u`3b*wy33xUsjg_D=J=AI|)D!`IjDDh{(vIm$)D3 z1f=2nBoq*tf4(8}$D<2LKo=sizh0-&M!CAoFLG~4Y+E%wc8MAf9!|J~JUsugc^0xi z|9*u>A3~Zi`PW98rdjA+cz>;&97>uL+OV2)Od=;I7;{9C;Nqzm*9gq1bNxX z7?$z6hVd=_P=t?mCKNu3Um>+VS^3P2pXbNdla-%?H*NzW8D~+9vuwZt{t3?(5>^l& zkDNRJxR<`PnEqBoSZVY-;aQXU2R(q4sV^e4zNqmS!3 zU0sy9Qx%zAjoASo9HCZ#S0FdX!homhX8Ge0QL&6q^vuETj0G> zz}ocJT<^ziSGT9X>Kec}9uHj1ta8<6ZgZW2zdFd<5jR1NAdHABR>#M+RA-V;1o=;j zt5W;NwO1YBF>%|}HOR@wIxY?rU(_BsIUYG#Wa9vlm3=wmZ?crjS=>D0$-u9bm2X8x zZVN2<6|(Zf_>22Bvho;Y>z|XAAI#9~y3S6~WaKM%!5nXG-Ms`l)|0AKqv1;aLVB&XqX+VmN1W##>H4eGMNL-l+3Soe$53PwH`<53hq? zUXKqC8d^UePT=`+#{6_Zbk*|+h2OWTTw-Ec_L!Nv1G0*%Ypxd!mbb z2RwKJa2F7{Xo=dpVzcT7evizU%Xs=T<5|YE$c!6}aV&iJJUn>))GcZ-dfMmGH^6__ zyM*_i21F;kF>|BKoe58d2Q7v7>U?vodNC%OIr~Pn8vYv+w^8FS!7?Y4k7wTAl)1^( z7e3n;J}Y|cLDWU~Mn}pOUfTd(8;`E@DUTi-U8+ZqdJY~umh|Po3fj?0fNvG_sltE4 zXwyOFy)g2+NGN(dJ9q>#qc34Lp_#CXbmr;HT+b2uPG8{~ODMYWAnK}2U+WS+ys2!J z+8>z3`k)*hEW9^@xuq$3S9B;JB;}xMbqu}jcuvk5VuTSMt--U<293q>;c4Q zV)KN~R_CqvleW3WTl=BgjVFyqZ=V34*4wM=?WJDf)awNNcgdgtb$&tTt_8G5cxYPIM%Pww&p*_8 z>LZ-z&eYaY3s@)YK;Q1mzo{VXNQKito>`z(f5tL zlIB&?bQ%(%E-`p;$A6Ls3-1&jEP7@S5586=-kv-@EjR%VkxdUTZ_^xnryA>#48ZL%#4od&nB^{a5ZGNBn=hhkWOt z|9AF~BmW!skkdkbo+n>VF24AG;U4lfc;o+xJ>_05M@IMj^Rn@rEBnao5!Wvp&$+UX z{9E>rJBxi+5OQ+^r4!?E#dsM&b6tVdTp&tv1|^UvFOT}M9N z50BpO&7VDbYS9bVe3MvFbCYh*r3l`#G^ZmvF419YGP1vq+auSC&RX=^qPJc`ScA=$ z#6@SVr!~6+(OJtg(O2uwOqz~*0nap>GXK&XkFNSzo{8*TMff}*va-~v`fKWeu3B{0 z-Zoug$Mt37uGn$;s%FJcJ&KOmf=$;MWFp-BsNW(FZ|4rL9cF)Zr`b@JAh8W5MWT* zO0_GHIen$-NBA^%dA^YTvTM4bPd$UYY{6zn?2`sXA9WpWTbeT+{q=5Sq65fXe%K3H z&{c_yq+t7FCY_|M2Bs~1MO_lT%JtUbSJYL&QIYF_J;2{$hqxY~{H{O?V0l@UdI0Dc z{jKY9%75Chd+L_8($y6?Ps-9|yNA_1dA&t^Iq?<5SAt7B-y%MZxU}~uGRT+2{gLUv zEL-VnLHI@43fHZKpK+GsLBb)yk{ztx0@(=Uz$f)Ys~#TQUa^^9d>EoUf*%?#cLl0NkJdU(DDY32tZHjv_2)+&)BD zj81Db;d$sG`_B){J7nxf2-h-ZA0?ErdhvtAirO!f;OCKt??N7ydjPj<`e_sTX+`}M z{E&n^7d^G;t3^lM19*q=cGA$*$eu|qa%C|v99{LC#T!+Xa08*(T8gep_JP0R{VsG; zA`kxwd?$NBqMv#fo3Po0?}%<2-Bhvckxbp-vZ9+_6jSW7Pu--Z0&dc8(Co)DOAf^h zbItP2EE&q4N|9l!C3`E@m=ZNPW(2ll=%eX-I|Qh2F?&oEgcB(D9^h5v-xq-7m~`ad z*U)!g(L?``xt)B{)k~S!Zz22c@X~enh^a*WP1SVW6GTQv<`$iI5%Tz5=&ip8mp$U0 zajVsP;wsf0%_7vtfP3S%HMj@gb7IRi#jxcny~dVn1b*@GJ*@dusbmiKw&ePnQusWnKgjeel={nAaX$i<>oETb$zvN)71~2 zS^#hDi;wI+*md=W=jOwERdm+9MqKXftKA_j_p4v4v;O|UV7?3C`%rjtn9h@PeyX=# z^)KYfzrWeAyC&4^t_g)7BQsyclYhKMXYIXrT(@uBtW+D{p1ot8zgo0CW8t~Ndp&$u z_%G-AHQlu6s5Lw8V4e5MezA<*(oOJLdufj7!#%uMo;&3^eA=5Q$IG*Nc(O(G*655m zv&&quyZsUWj_z^ju7@dRjV~{R-!3wn)xYs>G4~_RG%M;DONctbVpc~pCyZxq7y|E> zJ>(+xkaO85Zi&wNJ@7v;=1YLiz+p=l_XFs$=kV_Lg!_0VbHV}m!z1vbUO)q2&(x*p ztyjACz*CRB(aGH)6a6(~dS7&vYo*t_AVY_}GUlS|;IyUc97BI~L*~n_1L&xO;vR8j zVuyMFo$6Wi@MD>8ZeYw`Wd4%U1EX2p< zpy+JXjL*%SpZwT*igm(+So<=**GiNSSEd3uGh@HSZ*OWg*ykbC7+y2o;}0^fg^vqA z7d|fhJdA(u;pOS{jqCC9i_o_TG?MW@V18o73-Ij;jLnJMak~@zZ`xhA*nfZ@1Ha6> z9gCO3AD5~&#);TDRMP)N$G!F%JM11YYhCZKmMaz@o$z|=!j0-Fc>65+fgPAZpAh@& z%Zwk{w-y`da%`4T-Se3Qh$v59ep}m z{TsUPdv9x&UqK(Oh;#6bLp{W^MezUe36bh2%_7yi3|_w!pTuIfUHxl#eLZ&DpY!Z0 zUeEcce=V=~3;)Nw-iB?r&g(t={oAmZu&p=To^s%!n1TZVQDGmM8>Vc9|9g18N!z3D z3(xKY@9quH&xhwR~EAFW>Xm&$YP?KcT7k1Whf~pZ$Kj z9=2*@u56ubscf0yQ^_~Ag{Sqpa8Dp-!gjA-6({GxOx)jMqAh0HWT9<7tVevgzr~OH zTTJs_3+Mg=f6j#AXW(0lzjil!E%&&5hdg`%`>l(dZ;Hg{NF{eF9QRjh+fQ)L{}8C* zE|SCCcOdtPe1_lD&$-*;n7^}D&KgEoqRYEmlyIx5Nr08RR^&d43%~;I4v;$m#P`36 zGl7@JccU&{sZ$r~)|onX;vSNY+(TlzipER6(%Ut%9vb&Jb%n-BpI)Ky+xa?;XN}SQ zecCtcVc=JKn9@qA9M;mL(SOeUdYGDQsvN#p$6J4;hZ>FXvzlVixcb=DG*%57pKfPj zU1(-~XhA3AGvd2Dd}*6s%ERvO@pxFbg_Dy%oDf_vIyNrsJmCVu`Q~u@ zM-%)t{9D4UJlkS!Xx|eZS8x>gQt`7-XD$6;Y*5r6ql2T4Dk1ix6T&zL5gIkRZ*bI} zJm082Jln&w>G+3u0LbM|Lh%tX1)ny9%=o6^-w!0Tbi+?Xpq2Xvtk^Z0G`q%B@Wq_@ z6aOkIzEvh0&+#Xtoeh+G7{ouQ*g=YK(62iiwvB|EZKK3F6UZ8M-1!yh-TdpS(rr=6|{PH+#Tkj32!_u|m#`@1J=n@6R)xdHwv_lr#di z;s;&)p+5qi1zZ6CmixNy@N=+!idQ2DBUn$#^Ksw~@GRCL4g=4gUZpmp~pMWu_IvsbQJrw0B9(C=ef{O_RfbvL++qche_Wi6#6~b zH?czZ18By7ok{aw_ci__{tP`gQ094Px?zfG-gkrtfw|D~17Lsv^k@eiqW#-o=NPZP z#IsAlB;Zrtb>R69LZMxoX&cr3(_d91{T(G0JX-{v_X0hDWNb>Tz-6AxcPXS<%kxt} zG0&x(NmF;K#YTKK&vNDY)K}FRQ&+1)r&g-D{Firu*}!YlU(^0m_#FxP3rQz=NP6*& z{~hnQ02#dV^pOkGx8oC^yWj+-tx*q5Tg$)Np>D>uG=sHI1n^h>@7;idfBOS4_SvOs zBf{JGj|YK201nnN5x`dd;~M^5kbmovjD;)IRKf_tztRT=0N+bmU;;4q+2!Q3oP1W2 z&r0%Hsm>*j#|Zln-VB5TTgcN+o(q6Sf!l%J>`l$(On(OWT=sTGg1b%TdE#sTFh1+0 zpDamc9y}PAnZQ|a=_}Wcxj_2L zjoW}v=_`vRU8|lZ?LP2N$>VE6xhvyn**f*Tsc!Xs`bH9cst5g}0U-V5 zSwcxKbA{AH%6N=t*}yhH<^`Ecq@PMZIxx+x4wzo4-Zga>{b9W}ul#{N^h3ombt0jh zH{LFX|hz3e}|G{U=6U1d~V_U zhSRsWvdNJWY_GVd^Sye5TFQ&b@x6_h|*6B1u8wuS(}9so3xK0`@TvR?}DaF%Rx06n-MS zm-aFu2^pxmV%w_;^%D(#L%zq>uX%N*^Cdzm>k-CPn7O;5B`j2m3MaJwrdd z1CTx-|F{Z#9N^&_f1pokeSlED$!t2L2dx;9c}7;Un__nUf@q%t_Ms zWe#eDjL~=6YwGRvlWd@hKJpzfpZVx^{_$AgBjyA7Z<+K1nRD(WtmXO3z$5(gJAp9z zOk3WKCf(B}=cQNJAK8k&<^bP{o!+Kto3#IUewx^fbzsk;HTQmWD0!-BsQMH|T*X~*2P91H{&H5{a^_8r%0$Fp3uk3%c z)|&P&T5Daq&MM%J7 z(>5-yz}A0gRm#K$1-UV?VJ#>66%-Su#>5u9P5%m_Z;hB36ea7F9vQZ%navwS^`c)T zn}Y1g6T=Eh=v&1TgQH65Te+_d-F7J+6tSM#4Ey+bm*|~rn-C)b2qHKJU z%Uy7x+P%6w@4>Sk_)+vc>%p`0`Q2E%cST0(!n(IJ>)%f3MLTldRbRg!Z?LpwAZBq1~#9As|L6M79Ho|vfQzq@N!-}}Mktc;Am77Y?BilL$CI*Os8 z=sI*CyJprXrZr(chw^Uk6y~~PWynqaSB8{~BYceT1)u_aVW)Ub3hn*o+EF@TYg_)0k)-2r*C$>EO|=a z&XLV2irHVNlf6h7F=tD#0RSgzr)Uio3ovH}a6;GwQ9hsgYCZ z>z&wtA8ZYcdYsGZI+Jb)=?0Rn6Y20DI%;s*Ml-gs*ywW#OYG)5M{LegU$cbfF{Ik3fWomf3T@~ZR#CS0yCt61QP~wB^>&rOu zLtgZ+yxiIEgBfGv9*SqL!0Ib^B|GOAF>fU|Q9kHUshoX+HPnf7rcJ|cd-|K?iSN9S z%)M+a*@JlpIV~k9;DugInA_Nw;gail9q_$(+>pQI9GcwUo2=NmH`eo9_u-Puvn&2y zbRRD2jY<}N4+Ct3JvfKM?e0qKFcQF% z*#~S&*n|B){at|D=F^~DzFEpQ;?u#YePeTrUk8yD#IHjiLh3Ye2L(3I$kY!l#bU3-dM+#!QkOK9xpiiAzFEYvk#)>FSx&s zmkMqv%@LooHnZ^PMPzE*Vw-h-xc?OuOVDZ{ImJF?&QVjEP+7u zoUMRy*c0>zMDH!IR@QeqL_P((UcPD5%ca!Mr1O_dA(; z_Oq^%_15ONA?lYst8*?bUa5W-(@dR2=&=j_^498{;)N^OLs^OZ`Jj3ac~1h?U>iJV z>JHZibfSM0-xGvtmhM9%H*<|D`=xm?F4n}Y)m-ZEHD&h7bgN?HKRUKO>)B!IJ25Hh zmz}F~T$J~BK=h;`ygNkuzGnVwO*tj#FM|n(vaj$NG&%>Z9$ECFI;7%7bsYQm$FTiA z$exHlZA}9Tus?q#eVgVlzdxEacw6-x=MpYZriuH= zLf99mA-_NJtT*W;?XxlM)hhOT^lwJ;O&aeuySDLsGzmQBlUTR?j_0~hjyp16 zQT2LHLf`v4*7)t!lhIY`bSaN|2E?vXo5yWd&w#%ew^5x84Qlf_*PqZttpYxqE_K&^ z)NIC&hhD}=_EOTQUwiJ_+o=8xdfh|X*!U)DA?Z72Ez!=kEk~#9+5gebQbe~`{n&pv zY`N84TBxW#?7X*^2J(F;|{V(iOUu19j5c|~Mu}^)O z{p1_id%hi;v6m+*Q3u%5-a5$=^|9PYVCcm&FsiPXec&cd3+-@mvhR+taZy1dfH{*xuwb8bGRwcK8HM9{5$$W@yX3| zBNs!jwQb5H?a);Ap>p|W$qBi3;UjYQa!=BWJy-`*VDWLv8%X-0ZDvN=pf5al-ue7n z;mO_L&0Wz+cVUg&8J^t<-rbQk?p|&E!J2l>oA{?ak3K{0Nk84rhxfju^MkkhbAH@P z9ya)TK;?`vu?5yqF%K=tM*ryH=?U=k!^+vu66G$>&L8%IkK3$0uHxPJ|I>7>I`5V{ z-*w&{hptt0tGVbdJ-j;(ed{Tnxta>^=AI$K9`Nwv2};)b;}f512@lLO_+Z#poo{Er zOND1^JQ^M)=Szi8i>_{1pw2TBw=}De^QQ8TzT~;bH`7S+DB<56=20N;tzo|Vn*2LZuIx+BhJU_I*{!kRanYXB@VoE>8o7> z;C%z8?{wYES)o+&Z$h|(`bpiM%d9fa%}%6#IXuVz6wjZ}eAPJ9GZ7o59Lj8=-lUzS zZK19woX{*py$hS<=Yfd$5H%SZ45a;kC0>KxB7wRuGwdVJW>&h|z*pPE>i*7_8Rz~k z!3*`e59a^SX7=BgQO+gozLUALbD_V+g)*#8Qa+As^R_b8rxl^EljS$78chf{~(vMg|AC#VRQZ1ILH;>!tOdunwl0t zt|?h2*PtwmYhiGxt7De0%amnvEs6`}ygF&Jf?TCHg}SD62z5;i4tGt83wIUX6z&?- zA>4IOa3j~fagAKgn;N+~c4*{^32x$wjcejkZffE(b!g(s36668E-uOye^Znzp+l7G zQgDpx$G8|*%}p_`!yRH=g+3X(T+Jww|QS?5-N0%CW zH1R*2kA^_!^ZB{(z#j0??(ooC;f>wkkzL`TUCAC)^Z{^RB2$F7l&iF?b( zJ>Z2RAJ2pjihNuNAJllSzn6T>H@`$amUE;|@~H8*x`l6Rz7XNjSINhZULzkLBknC9 zOWa#NmbkZkEOBr7SmGY}Sa6SgEVxHL7ThBr3+|DR1^39u$H6`FvEUy0Sa6SgEVxHL z7W_K$v8)>=A`?$SCLRd>cks*L-tut(e6%I-S8RZ*0FQi}3Xe;Lrv|}Kf(X}7U8X(> zTq_^1gV)LW!7cn-_%<*%MwgFw81nI_*T~1Gh?fAHV;)p5k++s-DU`50NZXP%dQ%)Lm(Ck**`O`BPf z0nk+V2)^1i`B?afM?RLbSO4AeadkcNv8DOHRzCi{As_cJi*&2_A zM~VL6C-QMST|Sn7bd`Ke9=}9Bma~f<`S>R2FY>X-+TQZnIhhg)d=&uTdL^eK5iN&E-G#pEx#;Tq1zMI*n8o$KAvuc=MJMJ8K@zr@*w zjQqEl4XTQayutAIa^+lpyOwP3#vhz-9Gw+%rE9)}y&j06SWYceuk$)Wz zy}pbreCy|AB?`q1n1E#~`m@X+5XBmZoDG`+FGM}J9ukdc43KEF{${!ieg zzePs=Pt!GTGF{=NKc{PcQ>kCq9Af@uy!3x`&2o3g|LB_kGj+`tbj`l#n*F_W%@%ac zc680Y=$ie}H3u2GX1k$lMo)~Mxey)mCI4V_&Hm_`?dY0=(KQDdy5?YX%@%aczUZ36 z(KY*{Yqq0n4oBBanyg@S&Ee>p!_hT2Lf6~~U2`LJ&5h7CH%8ao7+rH?bj^*?HAkUq zjzZTQg|0aYU2_b&<`{I%G3c6O&^5=QYmP(L9EYws?w`^%U(dIPw=8<~UhPl$XfO5; zi{YWVzB$<7r6Iy!W(~Hzk9_e$ZhD7>(}qjxuS2rM%OI+s=v5C@Wx+N zANb_Y*5?=MnoqG8D|@e^?@vZwFMGG*J4@^gTd_YacQLFtHL(8)9lPA!v5R}mziK-> z@(}x|UvcMj5VRb@-e51%i+tZe+qZ2HwU&L`ImW*22xIS8_6aAm?|X9dY;E87UD>yV zw%6OYbt7kWFa@!1JNwGM?QhaGzw#4XtnVN6MOW>I&f1@STWjUzCp3Gk0_(%E55?zs z?cIj5cY9Vj+c`^Q(@r1e$=#<>4vbSkP&4aq#Q1u_dhm_{j>6p>gifvKp9-a>@%@NsNCA57xAIK(b@gW^x5&XduGeMB8L8Q9`bFoS?!l%Ib%@DVP4wB_ekT4_HsR-E9_O^5!QaYMe6Muj z`3r;#i7)2)^Y|(KGOnw8WW_4=47%(tgjqlX;0Jz^ZAE7)8rp_bDb2oT5-kk%s z0!yjuVeH--v9DVKUd=b1%9gqwDBJ1!FV2Jh=-er#=7u4^8*p=!$>bSY=HMJjb z8#KFJtH&*zBe|vIIC_Jo8OvPFGjxC3;!}G?^drdq4|5J9Lv4WnkWSI9sf+jvZLK~_ z{*T}%v?;dfUHMLYp0>&G$f>$NnEUaa@>x6lxKpm|z2C-u?lQ{mW2E<#wIX^H<+M@D zXp8up8CAB#HNR|wYdPigBagm(djz{CDZeXyrb{gMj80ps_NG7V@yRUtAnPSnmybt6 z7woBc_YJg@JH-xCW;ba5K^A^gp|zgw0o4y5rfIxCOFFr?^b&jja|g$0{rQ{DdG5K4 ziKp@47jR!o`Jz?odF-qfP@m!8eSsT*Z{vEnABN7;fhVAIcj)~-uu}Rj zb)3&Wg7jIj`3j=$??;bz`PIE!UH7gr@BYHOFX`+0cdP2&S$VgYcdO{fD;X2|`>l2F z8}a^Q-tUqA%2@NCw!}4;P?@&D)thJMI^ff0+Gf|DvR7T<&`0{Z^uhgE8x6m{WB9k} z>PPfZxxZ{A`4!Md7F^XoN2~L(+1tavlKylK8^qDjVle*a&k=56U*vh7kKMVTS(4Q3UZIl0_@O?FB=KV;2kg$fd-7>`1Ewf~I)+)m~h_lamBB#r(ejub7j==M#_7cZ@Usc&3w3rG5sd_bT#t0F=MCU6X1T* zH&@@HZ!RF+H2e>gU6pS8PtwgN-F?*W3F=&^EY3U48Lf^V%KfX}c67QOz?;|sJa>&9 zfY{NAO_#SFoyXsc_uA|zw)X|_hXwG4t?-2J@b@D21!7Mp_5fl}cZX&V5U8!sE@DqN zHle@0i6z*6%VfWTI7>+JMfUDH;P<6}+vg&;p`Ul)_vHe5g{)?G*dH}D?pcd1-7WZi zxoq|;zOZ?^mi7*O#JDGhqvPmhA7N@}-=^6CG{O$xnaGIX=&;6?#wmBOw%Ns6rDfal z$l@U7=ANuq#3rB>_5gQiHUa+!>cpDosyeZz(d_FuuOfBH6)B zcK_P-o9fWlZ#F{BZa({`>$muEtcQ&Cn^SPsZ<;;0;H=rS^_$?V(PUjG_5xR}yCJ0M!?Q#)XKL_`muU`Dv#{AdJie>DQ^ihrYiZ63!q7!K)iA=_ z;1_AYHh6IjYoiZ=k60^-4cQBXW6_t3znAkvZ0_-dvQGND#p-r4C$|H_(R*)!=NAB% zT6A$wm{zHl10y&GnV+HGWw;qzZQ+OW<2JaW%jCIkqrS!P%`zrtgR5tT+x1!&zP8Za zSFx5WWUVzGA0My96e8Ppb{AG`P`?5?k*C$DtCceUvT%dC7Tza!CRS5-JI_uw^T+4k z232hM;v_BgzJdJ8XwM!%)^D;dTuj)7y?{?*kGK-1FL8xTTkEQtw%T(z!_573AOW&9AqBR>Pz#)z}x+H>0!QXXx&= zXRI&r*D{4Oeh&amz@NpBO#%K#4q#KC5&ep4nzjzUrQO$(KQhC^ryn4X8&$vQ>)_K( z@gv85GDdwK&8RYL)CZ}%@wxvc?~kw-^(bdeF9L6H-t#Fv720Nk8n~k1ck(n@+=bzP6UjDhaJy z`;BESm#tQnt->xw)?o3(vB}I3pW#_0zQ+1e)_kFHZPfncv4S(Ve<1JXtS3JZe?@Vm z$5%=j{&h_FsVSo^ZSZf@p7$?c19*gQx=^lf#w)BlvkZTS_fbwF&#PRa@bxgt(s}xQ ztQQmcJ{~^(l2%s8?alH-$S;zAB4a6Zy)*Ajc%HjI8|LgbI7pXui=3e_c?SB>C5+UOH!Swl}8 z9I7^?FP~#A`MV*Z&?=pC{{H#t_|$ote|s=`tNJK1k&LGTqu-8U?CAcOMw7m++Kw{k z$F>9CtR9AbZKH2dKjPa*_^yEO^tJ0P`QtJ;gU=Xt#OZ6-bo@e%CQV4}E$SHhX(RAm z)F+?+vz~t-XCs#yPqv$^^x&!3^c?k2BJ+BlYS)*ELzbUWC=eE&J+ zB#`cP@(@3olE-a)d-$sFHeB;vB4y)ulD;h8^do&KZJlVWCwK3we?8eHNXc6COV*S1 zoXa@Mv#ZvV_!Rp0tS9}#|M7a#hFz(?p7gBOg2H3M+>P!?xqxq>3-}f~X||_`?onG; zvYu?k+EUh)Zfr9|A0}(vs(-N79e2%I_m#S}?oaDh%vx9UYWiCD7uHSmYuBtV4}Ytl z-+1%4t}p93zwyh~mww^e`jYQ|+4|C^uP^!kp7o_?O*tzxCM>s6&y?a(F$Kl8sIZ|X zTS@@`;kT?aKfj=_GY87ue?D@C*_<*kUK!Pyvqs7Iz6r2e(chU)#!qp6zgkiH4aC3C z5zds#x#m0Q;}Xibb2&GAGJ8hf;fdUvhfdVS{l~4lI;;M4Pe{T39BaY87$xj9=Tr9O zaEAMqz^Hu*T|)Ow3@K1K_bO*zm*Oi)&b!)1OnB-9`8Zh*4kNFQgtN%66JdZdw{L)X z$wP8(Ba!(_){tMcXlnRVF>wY;Su-uh>7LuQqx)vRw32Y(yiZ!m$G}$j(*j^L&=(Lt zhZled=5U8VTq1L9BIn_F2ke2*9R)(b+W>tz*E||n0Bi+5UV#4@ApDtS>dgY2cMb>6 z<2T@AU?u00rvoE_K0vxrpKqwk2f&Skeboo>wIF_G#D7S~?~QZ(7cTdk@oikD`1z1K z##5BQ@^WbV6*O5wyGKBirG!G`Kx<(6GVo^5A_&?9L7Nwe3td*kHLaKyvwPhcqr5h; z&1g$A_0P2V955QZFR+LC^(YWRo7w;$(55rMNZQZ`xN+Kxsy}d+eD(u=O?}mF`uXXX zOqcXJJHO$48nTM?p<=H-wA|B&e8m@cKwUpNMn6jBEOH9q-JfnV`qN4Nqo+?D_v%wF z*9oPs%31hg=y@Mu zIrNnC@OJ2EhmH>zbUfOSwEPP>1OGMk>itD^&IcV2<)ve5n!!3IlQn)8YnT4S?<78e z_+7*&029F{@oW_D9^(9J0pI{4famZVu?_eT_y&0D*%j($;IBaTGb_|kd|;;oqo=LJ zH^oY|KmF%X;29tTcnSYAFVTOB={r;Kp&&jWO7T@RLy5>r;chiM^xh!yqtTD#zBM~% zpuh4BE)U{7RcriroTgt1ZB9XpDYRF{?&E~Bp~Vw~a$mh?%!wZ(=~rI{Hm%s$@lc>Y zZ3<^Cr_;elyzpx**^y)`u{JY6~bi2`yWIpipqnVuH^PZnt)0b{KJ1{%#@W5=n zFWG<6myq3m(wD^Ny3irPqW7i2ghD@|m(Wjq`3U{Qmro#lDUiM-{(R({>1NW_)0f6T z%ZKSFkI-Kpt*0-w=UEQ#en*-%|Hi(g`FyFTF9p(<)_e7(RQggN^U}3_NoXT99z=U( zTn#3aaV6udzP>c=`vk2o-AbDZy!z4&;2}KwXZlh{qc5G$--#bUQ{|=3%Dn1FT4=uT zp0(HSKVjy>E&8_|qNgb`J8NZ3RWpa-V^{lb7JaQpbETGkp~dB&_P{40d~r)PXY<7` zpc6kM)53NC2+C+ZFKd~CufmS(wY|Q2JQuLHR-D_C0-d#g;*8`_^i8%2$uFE}6kHx) z3MkJVIyAe+M@gq2_igFp+*a&+F{@2OXKeuMfOop4ypa3X!i%kZoVDx5Hr48I$Yd{m zhq1DraXr!${H{W}(_NJpP7hM%^&t<=75ClUyn1X0MH!XQZ_0qC?Uk^B`0MMOHZL-v zz4NIl;|7f#7-$;RDXlaz_s+p%lT9XjGG|9m+⪼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 I|M9^80&IXmo&W#< literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpdemux.2.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpdemux.2.dylib new file mode 100755 index 0000000000000000000000000000000000000000..0d62f055a9f53dec9da87fd0914d2032f0f1dc63 GIT binary patch literal 69872 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 VAP5Kof`A|(2nYg#!2byX{{@O@PnQ4y literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpmux.3.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libwebpmux.3.dylib new file mode 100755 index 0000000000000000000000000000000000000000..56eff7602ace7bdd88862c54352e484afca6b9e0 GIT binary patch literal 105920 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libxcb.1.1.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libxcb.1.1.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..4f943599e735d61123679658b1dbacc5510a5f0f GIT binary patch literal 277696 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 Lz6bt)df@*6Jdf$~ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libz.1.3.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libz.1.3.dylib new file mode 100755 index 0000000000000000000000000000000000000000..1d8fb504db6f0e35e61f6aa8f78891d0b177c7a4 GIT binary patch literal 174784 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 ( + tuple[ + str, + int, + tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]], + Image.Image, + ] + | None +): + # skip to STARTCHAR + while True: + s = f.readline() + if not s: + return None + if s[:9] == b"STARTCHAR": + break + id = s[9:].strip().decode("ascii") + + # load symbol properties + props = {} + while True: + s = f.readline() + if not s or s[:6] == b"BITMAP": + break + i = s.find(b" ") + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") + + # load bitmap + bitmap = bytearray() + while True: + s = f.readline() + if not s or s[:7] == b"ENDCHAR": + break + bitmap += s[:-1] + + # The word BBX + # followed by the width in x (BBw), height in y (BBh), + # and x and y displacement (BBxoff0, BByoff0) + # of the lower left corner from the origin of the character. + width, height, x_disp, y_disp = (int(p) for p in props["BBX"].split()) + + # The word DWIDTH + # followed by the width in x and y of the character in device pixels. + dwx, dwy = (int(p) for p in props["DWIDTH"].split()) + + bbox = ( + (dwx, dwy), + (x_disp, -y_disp - height, width + x_disp, -y_disp), + (0, 0, width, height), + ) + + try: + im = Image.frombytes("1", (width, height), bitmap, "hex", "1") + except ValueError: + # deal with zero-width characters + im = Image.new("1", (width, height)) + + return id, int(props["ENCODING"]), bbox, im + + +class BdfFontFile(FontFile.FontFile): + """Font file plugin for the X11 BDF format.""" + + def __init__(self, fp: BinaryIO): + super().__init__() + + s = fp.readline() + if s[:13] != b"STARTFONT 2.1": + msg = "not a valid BDF file" + raise SyntaxError(msg) + + props = {} + comments = [] + + while True: + s = fp.readline() + if not s or s[:13] == b"ENDPROPERTIES": + break + i = s.find(b" ") + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") + if s[:i] in [b"COMMENT", b"COPYRIGHT"]: + if s.find(b"LogicalFontDescription") < 0: + comments.append(s[i + 1 : -1].decode("ascii")) + + while True: + c = bdf_char(fp) + if not c: + break + id, ch, (xy, dst, src), im = c + if 0 <= ch < len(self.glyph): + self.glyph[ch] = xy, dst, src, im diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/BlpImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/BlpImagePlugin.py new file mode 100644 index 00000000..b8f38b78 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/BlpImagePlugin.py @@ -0,0 +1,475 @@ +""" +Blizzard Mipmap Format (.blp) +Jerome Leclanche + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: + https://creativecommons.org/publicdomain/zero/1.0/ + +BLP1 files, used mostly in Warcraft III, are not fully supported. +All types of BLP2 files used in World of Warcraft are supported. + +The BLP file structure consists of a header, up to 16 mipmaps of the +texture + +Texture sizes must be powers of two, though the two dimensions do +not have to be equal; 512x256 is valid, but 512x200 is not. +The first mipmap (mipmap #0) is the full size image; each subsequent +mipmap halves both dimensions. The final mipmap should be 1x1. + +BLP files come in many different flavours: +* JPEG-compressed (type == 0) - only supported for BLP1. +* RAW images (type == 1, encoding == 1). Each mipmap is stored as an + array of 8-bit values, one per pixel, left to right, top to bottom. + Each value is an index to the palette. +* DXT-compressed (type == 1, encoding == 2): +- DXT1 compression is used if alpha_encoding == 0. + - An additional alpha bit is used if alpha_depth == 1. + - DXT3 compression is used if alpha_encoding == 1. + - DXT5 compression is used if alpha_encoding == 7. +""" +from __future__ import annotations + +import os +import struct +from enum import IntEnum +from io import BytesIO + +from . import Image, ImageFile + + +class Format(IntEnum): + JPEG = 0 + + +class Encoding(IntEnum): + UNCOMPRESSED = 1 + DXT = 2 + UNCOMPRESSED_RAW_BGRA = 3 + + +class AlphaEncoding(IntEnum): + DXT1 = 0 + DXT3 = 1 + DXT5 = 7 + + +def unpack_565(i): + return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3 + + +def decode_dxt1(data, alpha=False): + """ + input: one "row" of data (i.e. will produce 4*width pixels) + """ + + blocks = len(data) // 8 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block in range(blocks): + # Decode next 8-byte block. + idx = block * 8 + color0, color1, bits = struct.unpack_from("> 2 + + a = 0xFF + if control == 0: + r, g, b = r0, g0, b0 + elif control == 1: + r, g, b = r1, g1, b1 + elif control == 2: + if color0 > color1: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + else: + r = (r0 + r1) // 2 + g = (g0 + g1) // 2 + b = (b0 + b1) // 2 + elif control == 3: + if color0 > color1: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + else: + r, g, b, a = 0, 0, 0, 0 + + if alpha: + ret[j].extend([r, g, b, a]) + else: + ret[j].extend([r, g, b]) + + return ret + + +def decode_dxt3(data): + """ + input: one "row" of data (i.e. will produce 4*width pixels) + """ + + blocks = len(data) // 16 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block in range(blocks): + idx = block * 16 + block = data[idx : idx + 16] + # Decode next 16-byte block. + bits = struct.unpack_from("<8B", block) + color0, color1 = struct.unpack_from(">= 4 + else: + high = True + a &= 0xF + a *= 17 # We get a value between 0 and 15 + + color_code = (code >> 2 * (4 * j + i)) & 0x03 + + if color_code == 0: + r, g, b = r0, g0, b0 + elif color_code == 1: + r, g, b = r1, g1, b1 + elif color_code == 2: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + elif color_code == 3: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + + ret[j].extend([r, g, b, a]) + + return ret + + +def decode_dxt5(data): + """ + input: one "row" of data (i.e. will produce 4 * width pixels) + """ + + blocks = len(data) // 16 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block in range(blocks): + idx = block * 16 + block = data[idx : idx + 16] + # Decode next 16-byte block. + a0, a1 = struct.unpack_from("> alphacode_index) & 0x07 + elif alphacode_index == 15: + alphacode = (alphacode2 >> 15) | ((alphacode1 << 1) & 0x06) + else: # alphacode_index >= 18 and alphacode_index <= 45 + alphacode = (alphacode1 >> (alphacode_index - 16)) & 0x07 + + if alphacode == 0: + a = a0 + elif alphacode == 1: + a = a1 + elif a0 > a1: + a = ((8 - alphacode) * a0 + (alphacode - 1) * a1) // 7 + elif alphacode == 6: + a = 0 + elif alphacode == 7: + a = 255 + else: + a = ((6 - alphacode) * a0 + (alphacode - 1) * a1) // 5 + + color_code = (code >> 2 * (4 * j + i)) & 0x03 + + if color_code == 0: + r, g, b = r0, g0, b0 + elif color_code == 1: + r, g, b = r1, g1, b1 + elif color_code == 2: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + elif color_code == 3: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + + ret[j].extend([r, g, b, a]) + + return ret + + +class BLPFormatError(NotImplementedError): + pass + + +def _accept(prefix): + return prefix[:4] in (b"BLP1", b"BLP2") + + +class BlpImageFile(ImageFile.ImageFile): + """ + Blizzard Mipmap Format + """ + + format = "BLP" + format_description = "Blizzard Mipmap Format" + + def _open(self): + self.magic = self.fp.read(4) + + self.fp.seek(5, os.SEEK_CUR) + (self._blp_alpha_depth,) = struct.unpack(" mode, rawmode + 1: ("P", "P;1"), + 4: ("P", "P;4"), + 8: ("P", "P"), + 16: ("RGB", "BGR;15"), + 24: ("RGB", "BGR"), + 32: ("RGB", "BGRX"), +} + + +def _accept(prefix): + return prefix[:2] == b"BM" + + +def _dib_accept(prefix): + return i32(prefix) in [12, 40, 64, 108, 124] + + +# ============================================================================= +# Image plugin for the Windows BMP format. +# ============================================================================= +class BmpImageFile(ImageFile.ImageFile): + """Image plugin for the Windows Bitmap format (BMP)""" + + # ------------------------------------------------------------- Description + format_description = "Windows Bitmap" + format = "BMP" + + # -------------------------------------------------- BMP Compression values + COMPRESSIONS = {"RAW": 0, "RLE8": 1, "RLE4": 2, "BITFIELDS": 3, "JPEG": 4, "PNG": 5} + for k, v in COMPRESSIONS.items(): + vars()[k] = v + + def _bitmap(self, header=0, offset=0): + """Read relevant info about the BMP""" + read, seek = self.fp.read, self.fp.seek + if header: + seek(header) + # read bmp header size @offset 14 (this is part of the header size) + file_info = {"header_size": i32(read(4)), "direction": -1} + + # -------------------- If requested, read header at a specific position + # read the rest of the bmp header, without its size + header_data = ImageFile._safe_read(self.fp, file_info["header_size"] - 4) + + # -------------------------------------------------- IBM OS/2 Bitmap v1 + # ----- This format has different offsets because of width/height types + if file_info["header_size"] == 12: + file_info["width"] = i16(header_data, 0) + file_info["height"] = i16(header_data, 2) + file_info["planes"] = i16(header_data, 4) + file_info["bits"] = i16(header_data, 6) + file_info["compression"] = self.RAW + file_info["palette_padding"] = 3 + + # --------------------------------------------- Windows Bitmap v2 to v5 + # v3, OS/2 v2, v4, v5 + elif file_info["header_size"] in (40, 64, 108, 124): + file_info["y_flip"] = header_data[7] == 0xFF + file_info["direction"] = 1 if file_info["y_flip"] else -1 + file_info["width"] = i32(header_data, 0) + file_info["height"] = ( + i32(header_data, 4) + if not file_info["y_flip"] + else 2**32 - i32(header_data, 4) + ) + file_info["planes"] = i16(header_data, 8) + file_info["bits"] = i16(header_data, 10) + file_info["compression"] = i32(header_data, 12) + # byte size of pixel data + file_info["data_size"] = i32(header_data, 16) + file_info["pixels_per_meter"] = ( + i32(header_data, 20), + i32(header_data, 24), + ) + file_info["colors"] = i32(header_data, 28) + file_info["palette_padding"] = 4 + self.info["dpi"] = tuple(x / 39.3701 for x in file_info["pixels_per_meter"]) + if file_info["compression"] == self.BITFIELDS: + if len(header_data) >= 52: + for idx, mask in enumerate( + ["r_mask", "g_mask", "b_mask", "a_mask"] + ): + file_info[mask] = i32(header_data, 36 + idx * 4) + else: + # 40 byte headers only have the three components in the + # bitfields masks, ref: + # https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx + # See also + # https://github.com/python-pillow/Pillow/issues/1293 + # There is a 4th component in the RGBQuad, in the alpha + # location, but it is listed as a reserved component, + # and it is not generally an alpha channel + file_info["a_mask"] = 0x0 + for mask in ["r_mask", "g_mask", "b_mask"]: + file_info[mask] = i32(read(4)) + file_info["rgb_mask"] = ( + file_info["r_mask"], + file_info["g_mask"], + file_info["b_mask"], + ) + file_info["rgba_mask"] = ( + file_info["r_mask"], + file_info["g_mask"], + file_info["b_mask"], + file_info["a_mask"], + ) + else: + msg = f"Unsupported BMP header type ({file_info['header_size']})" + raise OSError(msg) + + # ------------------ Special case : header is reported 40, which + # ---------------------- is shorter than real size for bpp >= 16 + self._size = file_info["width"], file_info["height"] + + # ------- If color count was not found in the header, compute from bits + file_info["colors"] = ( + file_info["colors"] + if file_info.get("colors", 0) + else (1 << file_info["bits"]) + ) + if offset == 14 + file_info["header_size"] and file_info["bits"] <= 8: + offset += 4 * file_info["colors"] + + # ---------------------- Check bit depth for unusual unsupported values + self._mode, raw_mode = BIT2MODE.get(file_info["bits"], (None, None)) + if self.mode is None: + msg = f"Unsupported BMP pixel depth ({file_info['bits']})" + raise OSError(msg) + + # ---------------- Process BMP with Bitfields compression (not palette) + decoder_name = "raw" + if file_info["compression"] == self.BITFIELDS: + SUPPORTED = { + 32: [ + (0xFF0000, 0xFF00, 0xFF, 0x0), + (0xFF000000, 0xFF0000, 0xFF00, 0x0), + (0xFF000000, 0xFF0000, 0xFF00, 0xFF), + (0xFF, 0xFF00, 0xFF0000, 0xFF000000), + (0xFF0000, 0xFF00, 0xFF, 0xFF000000), + (0x0, 0x0, 0x0, 0x0), + ], + 24: [(0xFF0000, 0xFF00, 0xFF)], + 16: [(0xF800, 0x7E0, 0x1F), (0x7C00, 0x3E0, 0x1F)], + } + MASK_MODES = { + (32, (0xFF0000, 0xFF00, 0xFF, 0x0)): "BGRX", + (32, (0xFF000000, 0xFF0000, 0xFF00, 0x0)): "XBGR", + (32, (0xFF000000, 0xFF0000, 0xFF00, 0xFF)): "ABGR", + (32, (0xFF, 0xFF00, 0xFF0000, 0xFF000000)): "RGBA", + (32, (0xFF0000, 0xFF00, 0xFF, 0xFF000000)): "BGRA", + (32, (0x0, 0x0, 0x0, 0x0)): "BGRA", + (24, (0xFF0000, 0xFF00, 0xFF)): "BGR", + (16, (0xF800, 0x7E0, 0x1F)): "BGR;16", + (16, (0x7C00, 0x3E0, 0x1F)): "BGR;15", + } + if file_info["bits"] in SUPPORTED: + if ( + file_info["bits"] == 32 + and file_info["rgba_mask"] in SUPPORTED[file_info["bits"]] + ): + raw_mode = MASK_MODES[(file_info["bits"], file_info["rgba_mask"])] + self._mode = "RGBA" if "A" in raw_mode else self.mode + elif ( + file_info["bits"] in (24, 16) + and file_info["rgb_mask"] in SUPPORTED[file_info["bits"]] + ): + raw_mode = MASK_MODES[(file_info["bits"], file_info["rgb_mask"])] + else: + msg = "Unsupported BMP bitfields layout" + raise OSError(msg) + else: + msg = "Unsupported BMP bitfields layout" + raise OSError(msg) + elif file_info["compression"] == self.RAW: + if file_info["bits"] == 32 and header == 22: # 32-bit .cur offset + raw_mode, self._mode = "BGRA", "RGBA" + elif file_info["compression"] in (self.RLE8, self.RLE4): + decoder_name = "bmp_rle" + else: + msg = f"Unsupported BMP compression ({file_info['compression']})" + raise OSError(msg) + + # --------------- Once the header is processed, process the palette/LUT + if self.mode == "P": # Paletted for 1, 4 and 8 bit images + # ---------------------------------------------------- 1-bit images + if not (0 < file_info["colors"] <= 65536): + msg = f"Unsupported BMP Palette size ({file_info['colors']})" + raise OSError(msg) + else: + padding = file_info["palette_padding"] + palette = read(padding * file_info["colors"]) + grayscale = True + indices = ( + (0, 255) + if file_info["colors"] == 2 + else list(range(file_info["colors"])) + ) + + # ----------------- Check if grayscale and ignore palette if so + for ind, val in enumerate(indices): + rgb = palette[ind * padding : ind * padding + 3] + if rgb != o8(val) * 3: + grayscale = False + + # ------- If all colors are gray, white or black, ditch palette + if grayscale: + self._mode = "1" if file_info["colors"] == 2 else "L" + raw_mode = self.mode + else: + self._mode = "P" + self.palette = ImagePalette.raw( + "BGRX" if padding == 4 else "BGR", palette + ) + + # ---------------------------- Finally set the tile data for the plugin + self.info["compression"] = file_info["compression"] + args = [raw_mode] + if decoder_name == "bmp_rle": + args.append(file_info["compression"] == self.RLE4) + else: + args.append(((file_info["width"] * file_info["bits"] + 31) >> 3) & (~3)) + args.append(file_info["direction"]) + self.tile = [ + ( + decoder_name, + (0, 0, file_info["width"], file_info["height"]), + offset or self.fp.tell(), + tuple(args), + ) + ] + + def _open(self): + """Open file, check magic number and read header""" + # read 14 bytes: magic number, filesize, reserved, header final offset + head_data = self.fp.read(14) + # choke if the file does not have the required magic bytes + if not _accept(head_data): + msg = "Not a BMP file" + raise SyntaxError(msg) + # read the start position of the BMP image data (u32) + offset = i32(head_data, 10) + # load bitmap information (offset=raster info) + self._bitmap(offset=offset) + + +class BmpRleDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer): + rle4 = self.args[1] + data = bytearray() + x = 0 + while len(data) < self.state.xsize * self.state.ysize: + pixels = self.fd.read(1) + byte = self.fd.read(1) + if not pixels or not byte: + break + num_pixels = pixels[0] + if num_pixels: + # encoded mode + if x + num_pixels > self.state.xsize: + # Too much data for row + num_pixels = max(0, self.state.xsize - x) + if rle4: + first_pixel = o8(byte[0] >> 4) + second_pixel = o8(byte[0] & 0x0F) + for index in range(num_pixels): + if index % 2 == 0: + data += first_pixel + else: + data += second_pixel + else: + data += byte * num_pixels + x += num_pixels + else: + if byte[0] == 0: + # end of line + while len(data) % self.state.xsize != 0: + data += b"\x00" + x = 0 + elif byte[0] == 1: + # end of bitmap + break + elif byte[0] == 2: + # delta + bytes_read = self.fd.read(2) + if len(bytes_read) < 2: + break + right, up = self.fd.read(2) + data += b"\x00" * (right + up * self.state.xsize) + x = len(data) % self.state.xsize + else: + # absolute mode + if rle4: + # 2 pixels per byte + byte_count = byte[0] // 2 + bytes_read = self.fd.read(byte_count) + for byte_read in bytes_read: + data += o8(byte_read >> 4) + data += o8(byte_read & 0x0F) + else: + byte_count = byte[0] + bytes_read = self.fd.read(byte_count) + data += bytes_read + if len(bytes_read) < byte_count: + break + x += byte[0] + + # align to 16-bit word boundary + if self.fd.tell() % 2 != 0: + self.fd.seek(1, os.SEEK_CUR) + rawmode = "L" if self.mode == "L" else "P" + self.set_as_raw(bytes(data), (rawmode, 0, self.args[-1])) + return -1, 0 + + +# ============================================================================= +# Image plugin for the DIB format (BMP alias) +# ============================================================================= +class DibImageFile(BmpImageFile): + format = "DIB" + format_description = "Windows Bitmap" + + def _open(self): + self._bitmap() + + +# +# -------------------------------------------------------------------- +# Write BMP file + + +SAVE = { + "1": ("1", 1, 2), + "L": ("L", 8, 256), + "P": ("P", 8, 256), + "RGB": ("BGR", 24, 0), + "RGBA": ("BGRA", 32, 0), +} + + +def _dib_save(im, fp, filename): + _save(im, fp, filename, False) + + +def _save(im, fp, filename, bitmap_header=True): + try: + rawmode, bits, colors = SAVE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as BMP" + raise OSError(msg) from e + + info = im.encoderinfo + + dpi = info.get("dpi", (96, 96)) + + # 1 meter == 39.3701 inches + ppm = tuple(int(x * 39.3701 + 0.5) for x in dpi) + + stride = ((im.size[0] * bits + 7) // 8 + 3) & (~3) + header = 40 # or 64 for OS/2 version 2 + image = stride * im.size[1] + + if im.mode == "1": + palette = b"".join(o8(i) * 4 for i in (0, 255)) + elif im.mode == "L": + palette = b"".join(o8(i) * 4 for i in range(256)) + elif im.mode == "P": + palette = im.im.getpalette("RGB", "BGRX") + colors = len(palette) // 4 + else: + palette = None + + # bitmap header + if bitmap_header: + offset = 14 + header + colors * 4 + file_size = offset + image + if file_size > 2**32 - 1: + msg = "File size is too large for the BMP format" + raise ValueError(msg) + fp.write( + b"BM" # file type (magic) + + o32(file_size) # file size + + o32(0) # reserved + + o32(offset) # image data offset + ) + + # bitmap info header + fp.write( + o32(header) # info header size + + o32(im.size[0]) # width + + o32(im.size[1]) # height + + o16(1) # planes + + o16(bits) # depth + + o32(0) # compression (0=uncompressed) + + o32(image) # size of bitmap + + o32(ppm[0]) # resolution + + o32(ppm[1]) # resolution + + o32(colors) # colors used + + o32(colors) # colors important + ) + + fp.write(b"\0" * (header - 40)) # padding (for OS/2 format) + + if palette: + fp.write(palette) + + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))]) + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(BmpImageFile.format, BmpImageFile, _accept) +Image.register_save(BmpImageFile.format, _save) + +Image.register_extension(BmpImageFile.format, ".bmp") + +Image.register_mime(BmpImageFile.format, "image/bmp") + +Image.register_decoder("bmp_rle", BmpRleDecoder) + +Image.register_open(DibImageFile.format, DibImageFile, _dib_accept) +Image.register_save(DibImageFile.format, _dib_save) + +Image.register_extension(DibImageFile.format, ".dib") + +Image.register_mime(DibImageFile.format, "image/bmp") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/BufrStubImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/BufrStubImagePlugin.py new file mode 100644 index 00000000..60f3ec25 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/BufrStubImagePlugin.py @@ -0,0 +1,74 @@ +# +# The Python Imaging Library +# $Id$ +# +# BUFR stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler): + """ + Install application-specific BUFR image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix): + return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC" + + +class BufrStubImageFile(ImageFile.StubImageFile): + format = "BUFR" + format_description = "BUFR" + + def _open(self): + offset = self.fp.tell() + + if not _accept(self.fp.read(4)): + msg = "Not a BUFR file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr(_handler, "save"): + msg = "BUFR save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept) +Image.register_save(BufrStubImageFile.format, _save) + +Image.register_extension(BufrStubImageFile.format, ".bufr") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ContainerIO.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ContainerIO.py new file mode 100644 index 00000000..0035296a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ContainerIO.py @@ -0,0 +1,121 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a class to read from a container file +# +# History: +# 1995-06-18 fl Created +# 1995-09-07 fl Added readline(), readlines() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from typing import IO, AnyStr, Generic, Literal + + +class ContainerIO(Generic[AnyStr]): + """ + A file object that provides read access to a part of an existing + file (for example a TAR file). + """ + + def __init__(self, file: IO[AnyStr], offset: int, length: int) -> None: + """ + Create file object. + + :param file: Existing file. + :param offset: Start of region, in bytes. + :param length: Size of region, in bytes. + """ + self.fh: IO[AnyStr] = file + self.pos = 0 + self.offset = offset + self.length = length + self.fh.seek(offset) + + ## + # Always false. + + def isatty(self) -> bool: + return False + + def seek(self, offset: int, mode: Literal[0, 1, 2] = io.SEEK_SET) -> None: + """ + Move file pointer. + + :param offset: Offset in bytes. + :param mode: Starting position. Use 0 for beginning of region, 1 + for current offset, and 2 for end of region. You cannot move + the pointer outside the defined region. + """ + if mode == 1: + self.pos = self.pos + offset + elif mode == 2: + self.pos = self.length + offset + else: + self.pos = offset + # clamp + self.pos = max(0, min(self.pos, self.length)) + self.fh.seek(self.offset + self.pos) + + def tell(self) -> int: + """ + Get current file pointer. + + :returns: Offset from start of region, in bytes. + """ + return self.pos + + def read(self, n: int = 0) -> AnyStr: + """ + Read data. + + :param n: Number of bytes to read. If omitted or zero, + read until end of region. + :returns: An 8-bit string. + """ + if n: + n = min(n, self.length - self.pos) + else: + n = self.length - self.pos + if not n: # EOF + return b"" if "b" in self.fh.mode else "" # type: ignore[return-value] + self.pos = self.pos + n + return self.fh.read(n) + + def readline(self) -> AnyStr: + """ + Read a line of text. + + :returns: An 8-bit string. + """ + s: AnyStr = b"" if "b" in self.fh.mode else "" # type: ignore[assignment] + newline_character = b"\n" if "b" in self.fh.mode else "\n" + while True: + c = self.read(1) + if not c: + break + s = s + c + if c == newline_character: + break + return s + + def readlines(self) -> list[AnyStr]: + """ + Read multiple lines of text. + + :returns: A list of 8-bit strings. + """ + lines = [] + while True: + s = self.readline() + if not s: + break + lines.append(s) + return lines diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/CurImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/CurImagePlugin.py new file mode 100644 index 00000000..5fb2b019 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/CurImagePlugin.py @@ -0,0 +1,75 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Cursor support for PIL +# +# notes: +# uses BmpImagePlugin.py to read the bitmap data. +# +# history: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import BmpImagePlugin, Image +from ._binary import i16le as i16 +from ._binary import i32le as i32 + +# +# -------------------------------------------------------------------- + + +def _accept(prefix): + return prefix[:4] == b"\0\0\2\0" + + +## +# Image plugin for Windows Cursor files. + + +class CurImageFile(BmpImagePlugin.BmpImageFile): + format = "CUR" + format_description = "Windows Cursor" + + def _open(self): + offset = self.fp.tell() + + # check magic + s = self.fp.read(6) + if not _accept(s): + msg = "not a CUR file" + raise SyntaxError(msg) + + # pick the largest cursor in the file + m = b"" + for i in range(i16(s, 4)): + s = self.fp.read(16) + if not m: + m = s + elif s[0] > m[0] and s[1] > m[1]: + m = s + if not m: + msg = "No cursors were found" + raise TypeError(msg) + + # load as bitmap + self._bitmap(i32(m, 12) + offset) + + # patch up the bitmap height + self._size = self.size[0], self.size[1] // 2 + d, e, o, a = self.tile[0] + self.tile[0] = d, (0, 0) + self.size, o, a + + +# +# -------------------------------------------------------------------- + +Image.register_open(CurImageFile.format, CurImageFile, _accept) + +Image.register_extension(CurImageFile.format, ".cur") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/DcxImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/DcxImagePlugin.py new file mode 100644 index 00000000..f7344df4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/DcxImagePlugin.py @@ -0,0 +1,80 @@ +# +# The Python Imaging Library. +# $Id$ +# +# DCX file handling +# +# DCX is a container file format defined by Intel, commonly used +# for fax applications. Each DCX file consists of a directory +# (a list of file offsets) followed by a set of (usually 1-bit) +# PCX files. +# +# History: +# 1995-09-09 fl Created +# 1996-03-20 fl Properly derived from PcxImageFile. +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2002-07-30 fl Fixed file handling +# +# Copyright (c) 1997-98 by Secret Labs AB. +# Copyright (c) 1995-96 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image +from ._binary import i32le as i32 +from .PcxImagePlugin import PcxImageFile + +MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? + + +def _accept(prefix): + return len(prefix) >= 4 and i32(prefix) == MAGIC + + +## +# Image plugin for the Intel DCX format. + + +class DcxImageFile(PcxImageFile): + format = "DCX" + format_description = "Intel DCX" + _close_exclusive_fp_after_loading = False + + def _open(self): + # Header + s = self.fp.read(4) + if not _accept(s): + msg = "not a DCX file" + raise SyntaxError(msg) + + # Component directory + self._offset = [] + for i in range(1024): + offset = i32(self.fp.read(4)) + if not offset: + break + self._offset.append(offset) + + self._fp = self.fp + self.frame = None + self.n_frames = len(self._offset) + self.is_animated = self.n_frames > 1 + self.seek(0) + + def seek(self, frame): + if not self._seek_check(frame): + return + self.frame = frame + self.fp = self._fp + self.fp.seek(self._offset[frame]) + PcxImageFile._open(self) + + def tell(self): + return self.frame + + +Image.register_open(DcxImageFile.format, DcxImageFile, _accept) + +Image.register_extension(DcxImageFile.format, ".dcx") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/DdsImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/DdsImagePlugin.py new file mode 100644 index 00000000..eb4c8f55 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/DdsImagePlugin.py @@ -0,0 +1,566 @@ +""" +A Pillow loader for .dds files (S3TC-compressed aka DXTC) +Jerome Leclanche + +Documentation: +https://web.archive.org/web/20170802060935/http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_compression_s3tc.txt + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: +https://creativecommons.org/publicdomain/zero/1.0/ +""" +from __future__ import annotations + +import io +import struct +import sys +from enum import IntEnum, IntFlag + +from . import Image, ImageFile, ImagePalette +from ._binary import i32le as i32 +from ._binary import o8 +from ._binary import o32le as o32 + +# Magic ("DDS ") +DDS_MAGIC = 0x20534444 + + +# DDS flags +class DDSD(IntFlag): + CAPS = 0x1 + HEIGHT = 0x2 + WIDTH = 0x4 + PITCH = 0x8 + PIXELFORMAT = 0x1000 + MIPMAPCOUNT = 0x20000 + LINEARSIZE = 0x80000 + DEPTH = 0x800000 + + +# DDS caps +class DDSCAPS(IntFlag): + COMPLEX = 0x8 + TEXTURE = 0x1000 + MIPMAP = 0x400000 + + +class DDSCAPS2(IntFlag): + CUBEMAP = 0x200 + CUBEMAP_POSITIVEX = 0x400 + CUBEMAP_NEGATIVEX = 0x800 + CUBEMAP_POSITIVEY = 0x1000 + CUBEMAP_NEGATIVEY = 0x2000 + CUBEMAP_POSITIVEZ = 0x4000 + CUBEMAP_NEGATIVEZ = 0x8000 + VOLUME = 0x200000 + + +# Pixel Format +class DDPF(IntFlag): + ALPHAPIXELS = 0x1 + ALPHA = 0x2 + FOURCC = 0x4 + PALETTEINDEXED8 = 0x20 + RGB = 0x40 + LUMINANCE = 0x20000 + + +# dxgiformat.h +class DXGI_FORMAT(IntEnum): + UNKNOWN = 0 + R32G32B32A32_TYPELESS = 1 + R32G32B32A32_FLOAT = 2 + R32G32B32A32_UINT = 3 + R32G32B32A32_SINT = 4 + R32G32B32_TYPELESS = 5 + R32G32B32_FLOAT = 6 + R32G32B32_UINT = 7 + R32G32B32_SINT = 8 + R16G16B16A16_TYPELESS = 9 + R16G16B16A16_FLOAT = 10 + R16G16B16A16_UNORM = 11 + R16G16B16A16_UINT = 12 + R16G16B16A16_SNORM = 13 + R16G16B16A16_SINT = 14 + R32G32_TYPELESS = 15 + R32G32_FLOAT = 16 + R32G32_UINT = 17 + R32G32_SINT = 18 + R32G8X24_TYPELESS = 19 + D32_FLOAT_S8X24_UINT = 20 + R32_FLOAT_X8X24_TYPELESS = 21 + X32_TYPELESS_G8X24_UINT = 22 + R10G10B10A2_TYPELESS = 23 + R10G10B10A2_UNORM = 24 + R10G10B10A2_UINT = 25 + R11G11B10_FLOAT = 26 + R8G8B8A8_TYPELESS = 27 + R8G8B8A8_UNORM = 28 + R8G8B8A8_UNORM_SRGB = 29 + R8G8B8A8_UINT = 30 + R8G8B8A8_SNORM = 31 + R8G8B8A8_SINT = 32 + R16G16_TYPELESS = 33 + R16G16_FLOAT = 34 + R16G16_UNORM = 35 + R16G16_UINT = 36 + R16G16_SNORM = 37 + R16G16_SINT = 38 + R32_TYPELESS = 39 + D32_FLOAT = 40 + R32_FLOAT = 41 + R32_UINT = 42 + R32_SINT = 43 + R24G8_TYPELESS = 44 + D24_UNORM_S8_UINT = 45 + R24_UNORM_X8_TYPELESS = 46 + X24_TYPELESS_G8_UINT = 47 + R8G8_TYPELESS = 48 + R8G8_UNORM = 49 + R8G8_UINT = 50 + R8G8_SNORM = 51 + R8G8_SINT = 52 + R16_TYPELESS = 53 + R16_FLOAT = 54 + D16_UNORM = 55 + R16_UNORM = 56 + R16_UINT = 57 + R16_SNORM = 58 + R16_SINT = 59 + R8_TYPELESS = 60 + R8_UNORM = 61 + R8_UINT = 62 + R8_SNORM = 63 + R8_SINT = 64 + A8_UNORM = 65 + R1_UNORM = 66 + R9G9B9E5_SHAREDEXP = 67 + R8G8_B8G8_UNORM = 68 + G8R8_G8B8_UNORM = 69 + BC1_TYPELESS = 70 + BC1_UNORM = 71 + BC1_UNORM_SRGB = 72 + BC2_TYPELESS = 73 + BC2_UNORM = 74 + BC2_UNORM_SRGB = 75 + BC3_TYPELESS = 76 + BC3_UNORM = 77 + BC3_UNORM_SRGB = 78 + BC4_TYPELESS = 79 + BC4_UNORM = 80 + BC4_SNORM = 81 + BC5_TYPELESS = 82 + BC5_UNORM = 83 + BC5_SNORM = 84 + B5G6R5_UNORM = 85 + B5G5R5A1_UNORM = 86 + B8G8R8A8_UNORM = 87 + B8G8R8X8_UNORM = 88 + R10G10B10_XR_BIAS_A2_UNORM = 89 + B8G8R8A8_TYPELESS = 90 + B8G8R8A8_UNORM_SRGB = 91 + B8G8R8X8_TYPELESS = 92 + B8G8R8X8_UNORM_SRGB = 93 + BC6H_TYPELESS = 94 + BC6H_UF16 = 95 + BC6H_SF16 = 96 + BC7_TYPELESS = 97 + BC7_UNORM = 98 + BC7_UNORM_SRGB = 99 + AYUV = 100 + Y410 = 101 + Y416 = 102 + NV12 = 103 + P010 = 104 + P016 = 105 + OPAQUE_420 = 106 + YUY2 = 107 + Y210 = 108 + Y216 = 109 + NV11 = 110 + AI44 = 111 + IA44 = 112 + P8 = 113 + A8P8 = 114 + B4G4R4A4_UNORM = 115 + P208 = 130 + V208 = 131 + V408 = 132 + SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189 + SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190 + + +class D3DFMT(IntEnum): + UNKNOWN = 0 + R8G8B8 = 20 + A8R8G8B8 = 21 + X8R8G8B8 = 22 + R5G6B5 = 23 + X1R5G5B5 = 24 + A1R5G5B5 = 25 + A4R4G4B4 = 26 + R3G3B2 = 27 + A8 = 28 + A8R3G3B2 = 29 + X4R4G4B4 = 30 + A2B10G10R10 = 31 + A8B8G8R8 = 32 + X8B8G8R8 = 33 + G16R16 = 34 + A2R10G10B10 = 35 + A16B16G16R16 = 36 + A8P8 = 40 + P8 = 41 + L8 = 50 + A8L8 = 51 + A4L4 = 52 + V8U8 = 60 + L6V5U5 = 61 + X8L8V8U8 = 62 + Q8W8V8U8 = 63 + V16U16 = 64 + A2W10V10U10 = 67 + D16_LOCKABLE = 70 + D32 = 71 + D15S1 = 73 + D24S8 = 75 + D24X8 = 77 + D24X4S4 = 79 + D16 = 80 + D32F_LOCKABLE = 82 + D24FS8 = 83 + D32_LOCKABLE = 84 + S8_LOCKABLE = 85 + L16 = 81 + VERTEXDATA = 100 + INDEX16 = 101 + INDEX32 = 102 + Q16W16V16U16 = 110 + R16F = 111 + G16R16F = 112 + A16B16G16R16F = 113 + R32F = 114 + G32R32F = 115 + A32B32G32R32F = 116 + CxV8U8 = 117 + A1 = 118 + A2B10G10R10_XR_BIAS = 119 + BINARYBUFFER = 199 + + UYVY = i32(b"UYVY") + R8G8_B8G8 = i32(b"RGBG") + YUY2 = i32(b"YUY2") + G8R8_G8B8 = i32(b"GRGB") + DXT1 = i32(b"DXT1") + DXT2 = i32(b"DXT2") + DXT3 = i32(b"DXT3") + DXT4 = i32(b"DXT4") + DXT5 = i32(b"DXT5") + DX10 = i32(b"DX10") + BC4S = i32(b"BC4S") + BC4U = i32(b"BC4U") + BC5S = i32(b"BC5S") + BC5U = i32(b"BC5U") + ATI1 = i32(b"ATI1") + ATI2 = i32(b"ATI2") + MULTI2_ARGB8 = i32(b"MET1") + + +# Backward compatibility layer +module = sys.modules[__name__] +for item in DDSD: + setattr(module, "DDSD_" + item.name, item.value) +for item in DDSCAPS: + setattr(module, "DDSCAPS_" + item.name, item.value) +for item in DDSCAPS2: + setattr(module, "DDSCAPS2_" + item.name, item.value) +for item in DDPF: + setattr(module, "DDPF_" + item.name, item.value) + +DDS_FOURCC = DDPF.FOURCC +DDS_RGB = DDPF.RGB +DDS_RGBA = DDPF.RGB | DDPF.ALPHAPIXELS +DDS_LUMINANCE = DDPF.LUMINANCE +DDS_LUMINANCEA = DDPF.LUMINANCE | DDPF.ALPHAPIXELS +DDS_ALPHA = DDPF.ALPHA +DDS_PAL8 = DDPF.PALETTEINDEXED8 + +DDS_HEADER_FLAGS_TEXTURE = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT +DDS_HEADER_FLAGS_MIPMAP = DDSD.MIPMAPCOUNT +DDS_HEADER_FLAGS_VOLUME = DDSD.DEPTH +DDS_HEADER_FLAGS_PITCH = DDSD.PITCH +DDS_HEADER_FLAGS_LINEARSIZE = DDSD.LINEARSIZE + +DDS_HEIGHT = DDSD.HEIGHT +DDS_WIDTH = DDSD.WIDTH + +DDS_SURFACE_FLAGS_TEXTURE = DDSCAPS.TEXTURE +DDS_SURFACE_FLAGS_MIPMAP = DDSCAPS.COMPLEX | DDSCAPS.MIPMAP +DDS_SURFACE_FLAGS_CUBEMAP = DDSCAPS.COMPLEX + +DDS_CUBEMAP_POSITIVEX = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEX +DDS_CUBEMAP_NEGATIVEX = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEX +DDS_CUBEMAP_POSITIVEY = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEY +DDS_CUBEMAP_NEGATIVEY = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEY +DDS_CUBEMAP_POSITIVEZ = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEZ +DDS_CUBEMAP_NEGATIVEZ = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEZ + +DXT1_FOURCC = D3DFMT.DXT1 +DXT3_FOURCC = D3DFMT.DXT3 +DXT5_FOURCC = D3DFMT.DXT5 + +DXGI_FORMAT_R8G8B8A8_TYPELESS = DXGI_FORMAT.R8G8B8A8_TYPELESS +DXGI_FORMAT_R8G8B8A8_UNORM = DXGI_FORMAT.R8G8B8A8_UNORM +DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = DXGI_FORMAT.R8G8B8A8_UNORM_SRGB +DXGI_FORMAT_BC5_TYPELESS = DXGI_FORMAT.BC5_TYPELESS +DXGI_FORMAT_BC5_UNORM = DXGI_FORMAT.BC5_UNORM +DXGI_FORMAT_BC5_SNORM = DXGI_FORMAT.BC5_SNORM +DXGI_FORMAT_BC6H_UF16 = DXGI_FORMAT.BC6H_UF16 +DXGI_FORMAT_BC6H_SF16 = DXGI_FORMAT.BC6H_SF16 +DXGI_FORMAT_BC7_TYPELESS = DXGI_FORMAT.BC7_TYPELESS +DXGI_FORMAT_BC7_UNORM = DXGI_FORMAT.BC7_UNORM +DXGI_FORMAT_BC7_UNORM_SRGB = DXGI_FORMAT.BC7_UNORM_SRGB + + +class DdsImageFile(ImageFile.ImageFile): + format = "DDS" + format_description = "DirectDraw Surface" + + def _open(self): + if not _accept(self.fp.read(4)): + msg = "not a DDS file" + raise SyntaxError(msg) + (header_size,) = struct.unpack("> (offset + 1) << (offset + 1) == mask: + offset += 1 + mask_offsets.append(offset) + mask_totals.append(mask >> offset) + + data = bytearray() + bytecount = bitcount // 8 + while len(data) < self.state.xsize * self.state.ysize * len(masks): + value = int.from_bytes(self.fd.read(bytecount), "little") + for i, mask in enumerate(masks): + masked_value = value & mask + # Remove the zero padding, and scale it to 8 bits + data += o8( + int(((masked_value >> mask_offsets[i]) / mask_totals[i]) * 255) + ) + self.set_as_raw(bytes(data)) + return -1, 0 + + +def _save(im, fp, filename): + if im.mode not in ("RGB", "RGBA", "L", "LA"): + msg = f"cannot write mode {im.mode} as DDS" + raise OSError(msg) + + alpha = im.mode[-1] == "A" + if im.mode[0] == "L": + pixel_flags = DDPF.LUMINANCE + rawmode = im.mode + if alpha: + rgba_mask = [0x000000FF, 0x000000FF, 0x000000FF] + else: + rgba_mask = [0xFF000000, 0xFF000000, 0xFF000000] + else: + pixel_flags = DDPF.RGB + rawmode = im.mode[::-1] + rgba_mask = [0x00FF0000, 0x0000FF00, 0x000000FF] + + if alpha: + r, g, b, a = im.split() + im = Image.merge("RGBA", (a, r, g, b)) + if alpha: + pixel_flags |= DDPF.ALPHAPIXELS + rgba_mask.append(0xFF000000 if alpha else 0) + + flags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PITCH | DDSD.PIXELFORMAT + bitcount = len(im.getbands()) * 8 + pitch = (im.width * bitcount + 7) // 8 + + fp.write( + o32(DDS_MAGIC) + + struct.pack( + "<7I", + 124, # header size + flags, # flags + im.height, + im.width, + pitch, + 0, # depth + 0, # mipmaps + ) + + struct.pack("11I", *((0,) * 11)) # reserved + # pfsize, pfflags, fourcc, bitcount + + struct.pack("<4I", 32, pixel_flags, 0, bitcount) + + struct.pack("<4I", *rgba_mask) # dwRGBABitMask + + struct.pack("<5I", DDSCAPS.TEXTURE, 0, 0, 0, 0) + ) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))] + ) + + +def _accept(prefix): + return prefix[:4] == b"DDS " + + +Image.register_open(DdsImageFile.format, DdsImageFile, _accept) +Image.register_decoder("dds_rgb", DdsRgbDecoder) +Image.register_save(DdsImageFile.format, _save) +Image.register_extension(DdsImageFile.format, ".dds") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/EpsImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/EpsImagePlugin.py new file mode 100644 index 00000000..d2e60aa0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/EpsImagePlugin.py @@ -0,0 +1,478 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EPS file handling +# +# History: +# 1995-09-01 fl Created (0.1) +# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2) +# 1996-08-22 fl Don't choke on floating point BoundingBox values +# 1996-08-23 fl Handle files from Macintosh (0.3) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5) +# 2014-05-07 e Handling of EPS with binary preview and fixed resolution +# resizing +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import re +import subprocess +import sys +import tempfile + +from . import Image, ImageFile +from ._binary import i32le as i32 +from ._deprecate import deprecate + +# -------------------------------------------------------------------- + + +split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$") +field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$") + +gs_binary = None +gs_windows_binary = None + + +def has_ghostscript(): + global gs_binary, gs_windows_binary + if gs_binary is None: + if sys.platform.startswith("win"): + if gs_windows_binary is None: + import shutil + + for binary in ("gswin32c", "gswin64c", "gs"): + if shutil.which(binary) is not None: + gs_windows_binary = binary + break + else: + gs_windows_binary = False + gs_binary = gs_windows_binary + else: + try: + subprocess.check_call(["gs", "--version"], stdout=subprocess.DEVNULL) + gs_binary = "gs" + except OSError: + gs_binary = False + return gs_binary is not False + + +def Ghostscript(tile, size, fp, scale=1, transparency=False): + """Render an image using Ghostscript""" + global gs_binary + if not has_ghostscript(): + msg = "Unable to locate Ghostscript on paths" + raise OSError(msg) + + # Unpack decoder tile + decoder, tile, offset, data = tile[0] + length, bbox = data + + # Hack to support hi-res rendering + scale = int(scale) or 1 + width = size[0] * scale + height = size[1] * scale + # resolution is dependent on bbox and size + res_x = 72.0 * width / (bbox[2] - bbox[0]) + res_y = 72.0 * height / (bbox[3] - bbox[1]) + + out_fd, outfile = tempfile.mkstemp() + os.close(out_fd) + + infile_temp = None + if hasattr(fp, "name") and os.path.exists(fp.name): + infile = fp.name + else: + in_fd, infile_temp = tempfile.mkstemp() + os.close(in_fd) + infile = infile_temp + + # Ignore length and offset! + # Ghostscript can read it + # Copy whole file to read in Ghostscript + with open(infile_temp, "wb") as f: + # fetch length of fp + fp.seek(0, io.SEEK_END) + fsize = fp.tell() + # ensure start position + # go back + fp.seek(0) + lengthfile = fsize + while lengthfile > 0: + s = fp.read(min(lengthfile, 100 * 1024)) + if not s: + break + lengthfile -= len(s) + f.write(s) + + device = "pngalpha" if transparency else "ppmraw" + + # Build Ghostscript command + command = [ + gs_binary, + "-q", # quiet mode + f"-g{width:d}x{height:d}", # set output geometry (pixels) + f"-r{res_x:f}x{res_y:f}", # set input DPI (dots per inch) + "-dBATCH", # exit after processing + "-dNOPAUSE", # don't pause between pages + "-dSAFER", # safe mode + f"-sDEVICE={device}", + f"-sOutputFile={outfile}", # output file + # adjust for image origin + "-c", + f"{-bbox[0]} {-bbox[1]} translate", + "-f", + infile, # input file + # showpage (see https://bugs.ghostscript.com/show_bug.cgi?id=698272) + "-c", + "showpage", + ] + + # push data through Ghostscript + try: + startupinfo = None + if sys.platform.startswith("win"): + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + subprocess.check_call(command, startupinfo=startupinfo) + out_im = Image.open(outfile) + out_im.load() + finally: + try: + os.unlink(outfile) + if infile_temp: + os.unlink(infile_temp) + except OSError: + pass + + im = out_im.im.copy() + out_im.close() + return im + + +class PSFile: + """ + Wrapper for bytesio object that treats either CR or LF as end of line. + This class is no longer used internally, but kept for backwards compatibility. + """ + + def __init__(self, fp): + deprecate( + "PSFile", + 11, + action="If you need the functionality of this class " + "you will need to implement it yourself.", + ) + self.fp = fp + self.char = None + + def seek(self, offset, whence=io.SEEK_SET): + self.char = None + self.fp.seek(offset, whence) + + def readline(self): + s = [self.char or b""] + self.char = None + + c = self.fp.read(1) + while (c not in b"\r\n") and len(c): + s.append(c) + c = self.fp.read(1) + + self.char = self.fp.read(1) + # line endings can be 1 or 2 of \r \n, in either order + if self.char in b"\r\n": + self.char = None + + return b"".join(s).decode("latin-1") + + +def _accept(prefix): + return prefix[:4] == b"%!PS" or (len(prefix) >= 4 and i32(prefix) == 0xC6D3D0C5) + + +## +# Image plugin for Encapsulated PostScript. This plugin supports only +# a few variants of this format. + + +class EpsImageFile(ImageFile.ImageFile): + """EPS File Parser for the Python Imaging Library""" + + format = "EPS" + format_description = "Encapsulated Postscript" + + mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"} + + def _open(self): + (length, offset) = self._find_offset(self.fp) + + # go to offset - start of "%!PS" + self.fp.seek(offset) + + self._mode = "RGB" + self._size = None + + byte_arr = bytearray(255) + bytes_mv = memoryview(byte_arr) + bytes_read = 0 + reading_header_comments = True + reading_trailer_comments = False + trailer_reached = False + + def check_required_header_comments(): + if "PS-Adobe" not in self.info: + msg = 'EPS header missing "%!PS-Adobe" comment' + raise SyntaxError(msg) + if "BoundingBox" not in self.info: + msg = 'EPS header missing "%%BoundingBox" comment' + raise SyntaxError(msg) + + def _read_comment(s): + nonlocal reading_trailer_comments + try: + m = split.match(s) + except re.error as e: + msg = "not an EPS file" + raise SyntaxError(msg) from e + + if m: + k, v = m.group(1, 2) + self.info[k] = v + if k == "BoundingBox": + if v == "(atend)": + reading_trailer_comments = True + elif not self._size or ( + trailer_reached and reading_trailer_comments + ): + try: + # Note: The DSC spec says that BoundingBox + # fields should be integers, but some drivers + # put floating point values there anyway. + box = [int(float(i)) for i in v.split()] + self._size = box[2] - box[0], box[3] - box[1] + self.tile = [ + ("eps", (0, 0) + self.size, offset, (length, box)) + ] + except Exception: + pass + return True + + while True: + byte = self.fp.read(1) + if byte == b"": + # if we didn't read a byte we must be at the end of the file + if bytes_read == 0: + break + elif byte in b"\r\n": + # if we read a line ending character, ignore it and parse what + # we have already read. if we haven't read any other characters, + # continue reading + if bytes_read == 0: + continue + else: + # ASCII/hexadecimal lines in an EPS file must not exceed + # 255 characters, not including line ending characters + if bytes_read >= 255: + # only enforce this for lines starting with a "%", + # otherwise assume it's binary data + if byte_arr[0] == ord("%"): + msg = "not an EPS file" + raise SyntaxError(msg) + else: + if reading_header_comments: + check_required_header_comments() + reading_header_comments = False + # reset bytes_read so we can keep reading + # data until the end of the line + bytes_read = 0 + byte_arr[bytes_read] = byte[0] + bytes_read += 1 + continue + + if reading_header_comments: + # Load EPS header + + # if this line doesn't start with a "%", + # or does start with "%%EndComments", + # then we've reached the end of the header/comments + if byte_arr[0] != ord("%") or bytes_mv[:13] == b"%%EndComments": + check_required_header_comments() + reading_header_comments = False + continue + + s = str(bytes_mv[:bytes_read], "latin-1") + if not _read_comment(s): + m = field.match(s) + if m: + k = m.group(1) + if k[:8] == "PS-Adobe": + self.info["PS-Adobe"] = k[9:] + else: + self.info[k] = "" + elif s[0] == "%": + # handle non-DSC PostScript comments that some + # tools mistakenly put in the Comments section + pass + else: + msg = "bad EPS header" + raise OSError(msg) + elif bytes_mv[:11] == b"%ImageData:": + # Check for an "ImageData" descriptor + # https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577413_pgfId-1035096 + + # Values: + # columns + # rows + # bit depth (1 or 8) + # mode (1: L, 2: LAB, 3: RGB, 4: CMYK) + # number of padding channels + # block size (number of bytes per row per channel) + # binary/ascii (1: binary, 2: ascii) + # data start identifier (the image data follows after a single line + # consisting only of this quoted value) + image_data_values = byte_arr[11:bytes_read].split(None, 7) + columns, rows, bit_depth, mode_id = ( + int(value) for value in image_data_values[:4] + ) + + if bit_depth == 1: + self._mode = "1" + elif bit_depth == 8: + try: + self._mode = self.mode_map[mode_id] + except ValueError: + break + else: + break + + self._size = columns, rows + return + elif trailer_reached and reading_trailer_comments: + # Load EPS trailer + + # if this line starts with "%%EOF", + # then we've reached the end of the file + if bytes_mv[:5] == b"%%EOF": + break + + s = str(bytes_mv[:bytes_read], "latin-1") + _read_comment(s) + elif bytes_mv[:9] == b"%%Trailer": + trailer_reached = True + bytes_read = 0 + + check_required_header_comments() + + if not self._size: + msg = "cannot determine EPS bounding box" + raise OSError(msg) + + def _find_offset(self, fp): + s = fp.read(4) + + if s == b"%!PS": + # for HEAD without binary preview + fp.seek(0, io.SEEK_END) + length = fp.tell() + offset = 0 + elif i32(s) == 0xC6D3D0C5: + # FIX for: Some EPS file not handled correctly / issue #302 + # EPS can contain binary data + # or start directly with latin coding + # more info see: + # https://web.archive.org/web/20160528181353/http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf + s = fp.read(8) + offset = i32(s) + length = i32(s, 4) + else: + msg = "not an EPS file" + raise SyntaxError(msg) + + return length, offset + + def load(self, scale=1, transparency=False): + # Load EPS via Ghostscript + if self.tile: + self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency) + self._mode = self.im.mode + self._size = self.im.size + self.tile = [] + return Image.Image.load(self) + + def load_seek(self, *args, **kwargs): + # we can't incrementally load, so force ImageFile.parser to + # use our custom load method by defining this method. + pass + + +# -------------------------------------------------------------------- + + +def _save(im, fp, filename, eps=1): + """EPS Writer for the Python Imaging Library.""" + + # make sure image data is available + im.load() + + # determine PostScript image mode + if im.mode == "L": + operator = (8, 1, b"image") + elif im.mode == "RGB": + operator = (8, 3, b"false 3 colorimage") + elif im.mode == "CMYK": + operator = (8, 4, b"false 4 colorimage") + else: + msg = "image mode is not supported" + raise ValueError(msg) + + if eps: + # write EPS header + fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") + fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") + # fp.write("%%CreationDate: %s"...) + fp.write(b"%%%%BoundingBox: 0 0 %d %d\n" % im.size) + fp.write(b"%%Pages: 1\n") + fp.write(b"%%EndComments\n") + fp.write(b"%%Page: 1 1\n") + fp.write(b"%%ImageData: %d %d " % im.size) + fp.write(b'%d %d 0 1 1 "%s"\n' % operator) + + # image header + fp.write(b"gsave\n") + fp.write(b"10 dict begin\n") + fp.write(b"/buf %d string def\n" % (im.size[0] * operator[1])) + fp.write(b"%d %d scale\n" % im.size) + fp.write(b"%d %d 8\n" % im.size) # <= bits + fp.write(b"[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])) + fp.write(b"{ currentfile buf readhexstring pop } bind\n") + fp.write(operator[2] + b"\n") + if hasattr(fp, "flush"): + fp.flush() + + ImageFile._save(im, fp, [("eps", (0, 0) + im.size, 0, None)]) + + fp.write(b"\n%%%%EndBinary\n") + fp.write(b"grestore end\n") + if hasattr(fp, "flush"): + fp.flush() + + +# -------------------------------------------------------------------- + + +Image.register_open(EpsImageFile.format, EpsImageFile, _accept) + +Image.register_save(EpsImageFile.format, _save) + +Image.register_extensions(EpsImageFile.format, [".ps", ".eps"]) + +Image.register_mime(EpsImageFile.format, "application/postscript") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ExifTags.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ExifTags.py new file mode 100644 index 00000000..60a4d977 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ExifTags.py @@ -0,0 +1,381 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EXIF tags +# +# Copyright (c) 2003 by Secret Labs AB +# +# See the README file for information on usage and redistribution. +# + +""" +This module provides constants and clear-text names for various +well-known EXIF tags. +""" +from __future__ import annotations + +from enum import IntEnum + + +class Base(IntEnum): + # possibly incomplete + InteropIndex = 0x0001 + ProcessingSoftware = 0x000B + NewSubfileType = 0x00FE + SubfileType = 0x00FF + ImageWidth = 0x0100 + ImageLength = 0x0101 + BitsPerSample = 0x0102 + Compression = 0x0103 + PhotometricInterpretation = 0x0106 + Thresholding = 0x0107 + CellWidth = 0x0108 + CellLength = 0x0109 + FillOrder = 0x010A + DocumentName = 0x010D + ImageDescription = 0x010E + Make = 0x010F + Model = 0x0110 + StripOffsets = 0x0111 + Orientation = 0x0112 + SamplesPerPixel = 0x0115 + RowsPerStrip = 0x0116 + StripByteCounts = 0x0117 + MinSampleValue = 0x0118 + MaxSampleValue = 0x0119 + XResolution = 0x011A + YResolution = 0x011B + PlanarConfiguration = 0x011C + PageName = 0x011D + FreeOffsets = 0x0120 + FreeByteCounts = 0x0121 + GrayResponseUnit = 0x0122 + GrayResponseCurve = 0x0123 + T4Options = 0x0124 + T6Options = 0x0125 + ResolutionUnit = 0x0128 + PageNumber = 0x0129 + TransferFunction = 0x012D + Software = 0x0131 + DateTime = 0x0132 + Artist = 0x013B + HostComputer = 0x013C + Predictor = 0x013D + WhitePoint = 0x013E + PrimaryChromaticities = 0x013F + ColorMap = 0x0140 + HalftoneHints = 0x0141 + TileWidth = 0x0142 + TileLength = 0x0143 + TileOffsets = 0x0144 + TileByteCounts = 0x0145 + SubIFDs = 0x014A + InkSet = 0x014C + InkNames = 0x014D + NumberOfInks = 0x014E + DotRange = 0x0150 + TargetPrinter = 0x0151 + ExtraSamples = 0x0152 + SampleFormat = 0x0153 + SMinSampleValue = 0x0154 + SMaxSampleValue = 0x0155 + TransferRange = 0x0156 + ClipPath = 0x0157 + XClipPathUnits = 0x0158 + YClipPathUnits = 0x0159 + Indexed = 0x015A + JPEGTables = 0x015B + OPIProxy = 0x015F + JPEGProc = 0x0200 + JpegIFOffset = 0x0201 + JpegIFByteCount = 0x0202 + JpegRestartInterval = 0x0203 + JpegLosslessPredictors = 0x0205 + JpegPointTransforms = 0x0206 + JpegQTables = 0x0207 + JpegDCTables = 0x0208 + JpegACTables = 0x0209 + YCbCrCoefficients = 0x0211 + YCbCrSubSampling = 0x0212 + YCbCrPositioning = 0x0213 + ReferenceBlackWhite = 0x0214 + XMLPacket = 0x02BC + RelatedImageFileFormat = 0x1000 + RelatedImageWidth = 0x1001 + RelatedImageLength = 0x1002 + Rating = 0x4746 + RatingPercent = 0x4749 + ImageID = 0x800D + CFARepeatPatternDim = 0x828D + BatteryLevel = 0x828F + Copyright = 0x8298 + ExposureTime = 0x829A + FNumber = 0x829D + IPTCNAA = 0x83BB + ImageResources = 0x8649 + ExifOffset = 0x8769 + InterColorProfile = 0x8773 + ExposureProgram = 0x8822 + SpectralSensitivity = 0x8824 + GPSInfo = 0x8825 + ISOSpeedRatings = 0x8827 + OECF = 0x8828 + Interlace = 0x8829 + TimeZoneOffset = 0x882A + SelfTimerMode = 0x882B + SensitivityType = 0x8830 + StandardOutputSensitivity = 0x8831 + RecommendedExposureIndex = 0x8832 + ISOSpeed = 0x8833 + ISOSpeedLatitudeyyy = 0x8834 + ISOSpeedLatitudezzz = 0x8835 + ExifVersion = 0x9000 + DateTimeOriginal = 0x9003 + DateTimeDigitized = 0x9004 + OffsetTime = 0x9010 + OffsetTimeOriginal = 0x9011 + OffsetTimeDigitized = 0x9012 + ComponentsConfiguration = 0x9101 + CompressedBitsPerPixel = 0x9102 + ShutterSpeedValue = 0x9201 + ApertureValue = 0x9202 + BrightnessValue = 0x9203 + ExposureBiasValue = 0x9204 + MaxApertureValue = 0x9205 + SubjectDistance = 0x9206 + MeteringMode = 0x9207 + LightSource = 0x9208 + Flash = 0x9209 + FocalLength = 0x920A + Noise = 0x920D + ImageNumber = 0x9211 + SecurityClassification = 0x9212 + ImageHistory = 0x9213 + TIFFEPStandardID = 0x9216 + MakerNote = 0x927C + UserComment = 0x9286 + SubsecTime = 0x9290 + SubsecTimeOriginal = 0x9291 + SubsecTimeDigitized = 0x9292 + AmbientTemperature = 0x9400 + Humidity = 0x9401 + Pressure = 0x9402 + WaterDepth = 0x9403 + Acceleration = 0x9404 + CameraElevationAngle = 0x9405 + XPTitle = 0x9C9B + XPComment = 0x9C9C + XPAuthor = 0x9C9D + XPKeywords = 0x9C9E + XPSubject = 0x9C9F + FlashPixVersion = 0xA000 + ColorSpace = 0xA001 + ExifImageWidth = 0xA002 + ExifImageHeight = 0xA003 + RelatedSoundFile = 0xA004 + ExifInteroperabilityOffset = 0xA005 + FlashEnergy = 0xA20B + SpatialFrequencyResponse = 0xA20C + FocalPlaneXResolution = 0xA20E + FocalPlaneYResolution = 0xA20F + FocalPlaneResolutionUnit = 0xA210 + SubjectLocation = 0xA214 + ExposureIndex = 0xA215 + SensingMethod = 0xA217 + FileSource = 0xA300 + SceneType = 0xA301 + CFAPattern = 0xA302 + CustomRendered = 0xA401 + ExposureMode = 0xA402 + WhiteBalance = 0xA403 + DigitalZoomRatio = 0xA404 + FocalLengthIn35mmFilm = 0xA405 + SceneCaptureType = 0xA406 + GainControl = 0xA407 + Contrast = 0xA408 + Saturation = 0xA409 + Sharpness = 0xA40A + DeviceSettingDescription = 0xA40B + SubjectDistanceRange = 0xA40C + ImageUniqueID = 0xA420 + CameraOwnerName = 0xA430 + BodySerialNumber = 0xA431 + LensSpecification = 0xA432 + LensMake = 0xA433 + LensModel = 0xA434 + LensSerialNumber = 0xA435 + CompositeImage = 0xA460 + CompositeImageCount = 0xA461 + CompositeImageExposureTimes = 0xA462 + Gamma = 0xA500 + PrintImageMatching = 0xC4A5 + DNGVersion = 0xC612 + DNGBackwardVersion = 0xC613 + UniqueCameraModel = 0xC614 + LocalizedCameraModel = 0xC615 + CFAPlaneColor = 0xC616 + CFALayout = 0xC617 + LinearizationTable = 0xC618 + BlackLevelRepeatDim = 0xC619 + BlackLevel = 0xC61A + BlackLevelDeltaH = 0xC61B + BlackLevelDeltaV = 0xC61C + WhiteLevel = 0xC61D + DefaultScale = 0xC61E + DefaultCropOrigin = 0xC61F + DefaultCropSize = 0xC620 + ColorMatrix1 = 0xC621 + ColorMatrix2 = 0xC622 + CameraCalibration1 = 0xC623 + CameraCalibration2 = 0xC624 + ReductionMatrix1 = 0xC625 + ReductionMatrix2 = 0xC626 + AnalogBalance = 0xC627 + AsShotNeutral = 0xC628 + AsShotWhiteXY = 0xC629 + BaselineExposure = 0xC62A + BaselineNoise = 0xC62B + BaselineSharpness = 0xC62C + BayerGreenSplit = 0xC62D + LinearResponseLimit = 0xC62E + CameraSerialNumber = 0xC62F + LensInfo = 0xC630 + ChromaBlurRadius = 0xC631 + AntiAliasStrength = 0xC632 + ShadowScale = 0xC633 + DNGPrivateData = 0xC634 + MakerNoteSafety = 0xC635 + CalibrationIlluminant1 = 0xC65A + CalibrationIlluminant2 = 0xC65B + BestQualityScale = 0xC65C + RawDataUniqueID = 0xC65D + OriginalRawFileName = 0xC68B + OriginalRawFileData = 0xC68C + ActiveArea = 0xC68D + MaskedAreas = 0xC68E + AsShotICCProfile = 0xC68F + AsShotPreProfileMatrix = 0xC690 + CurrentICCProfile = 0xC691 + CurrentPreProfileMatrix = 0xC692 + ColorimetricReference = 0xC6BF + CameraCalibrationSignature = 0xC6F3 + ProfileCalibrationSignature = 0xC6F4 + AsShotProfileName = 0xC6F6 + NoiseReductionApplied = 0xC6F7 + ProfileName = 0xC6F8 + ProfileHueSatMapDims = 0xC6F9 + ProfileHueSatMapData1 = 0xC6FA + ProfileHueSatMapData2 = 0xC6FB + ProfileToneCurve = 0xC6FC + ProfileEmbedPolicy = 0xC6FD + ProfileCopyright = 0xC6FE + ForwardMatrix1 = 0xC714 + ForwardMatrix2 = 0xC715 + PreviewApplicationName = 0xC716 + PreviewApplicationVersion = 0xC717 + PreviewSettingsName = 0xC718 + PreviewSettingsDigest = 0xC719 + PreviewColorSpace = 0xC71A + PreviewDateTime = 0xC71B + RawImageDigest = 0xC71C + OriginalRawFileDigest = 0xC71D + SubTileBlockSize = 0xC71E + RowInterleaveFactor = 0xC71F + ProfileLookTableDims = 0xC725 + ProfileLookTableData = 0xC726 + OpcodeList1 = 0xC740 + OpcodeList2 = 0xC741 + OpcodeList3 = 0xC74E + NoiseProfile = 0xC761 + + +"""Maps EXIF tags to tag names.""" +TAGS = { + **{i.value: i.name for i in Base}, + 0x920C: "SpatialFrequencyResponse", + 0x9214: "SubjectLocation", + 0x9215: "ExposureIndex", + 0x828E: "CFAPattern", + 0x920B: "FlashEnergy", + 0x9216: "TIFF/EPStandardID", +} + + +class GPS(IntEnum): + GPSVersionID = 0 + GPSLatitudeRef = 1 + GPSLatitude = 2 + GPSLongitudeRef = 3 + GPSLongitude = 4 + GPSAltitudeRef = 5 + GPSAltitude = 6 + GPSTimeStamp = 7 + GPSSatellites = 8 + GPSStatus = 9 + GPSMeasureMode = 10 + GPSDOP = 11 + GPSSpeedRef = 12 + GPSSpeed = 13 + GPSTrackRef = 14 + GPSTrack = 15 + GPSImgDirectionRef = 16 + GPSImgDirection = 17 + GPSMapDatum = 18 + GPSDestLatitudeRef = 19 + GPSDestLatitude = 20 + GPSDestLongitudeRef = 21 + GPSDestLongitude = 22 + GPSDestBearingRef = 23 + GPSDestBearing = 24 + GPSDestDistanceRef = 25 + GPSDestDistance = 26 + GPSProcessingMethod = 27 + GPSAreaInformation = 28 + GPSDateStamp = 29 + GPSDifferential = 30 + GPSHPositioningError = 31 + + +"""Maps EXIF GPS tags to tag names.""" +GPSTAGS = {i.value: i.name for i in GPS} + + +class Interop(IntEnum): + InteropIndex = 1 + InteropVersion = 2 + RelatedImageFileFormat = 4096 + RelatedImageWidth = 4097 + RleatedImageHeight = 4098 + + +class IFD(IntEnum): + Exif = 34665 + GPSInfo = 34853 + Makernote = 37500 + Interop = 40965 + IFD1 = -1 + + +class LightSource(IntEnum): + Unknown = 0 + Daylight = 1 + Fluorescent = 2 + Tungsten = 3 + Flash = 4 + Fine = 9 + Cloudy = 10 + Shade = 11 + DaylightFluorescent = 12 + DayWhiteFluorescent = 13 + CoolWhiteFluorescent = 14 + WhiteFluorescent = 15 + StandardLightA = 17 + StandardLightB = 18 + StandardLightC = 19 + D55 = 20 + D65 = 21 + D75 = 22 + D50 = 23 + ISO = 24 + Other = 255 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/FitsImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/FitsImagePlugin.py new file mode 100644 index 00000000..7dce2d60 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/FitsImagePlugin.py @@ -0,0 +1,72 @@ +# +# The Python Imaging Library +# $Id$ +# +# FITS file handling +# +# Copyright (c) 1998-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math + +from . import Image, ImageFile + + +def _accept(prefix): + return prefix[:6] == b"SIMPLE" + + +class FitsImageFile(ImageFile.ImageFile): + format = "FITS" + format_description = "FITS" + + def _open(self): + headers = {} + while True: + header = self.fp.read(80) + if not header: + msg = "Truncated FITS file" + raise OSError(msg) + keyword = header[:8].strip() + if keyword == b"END": + break + value = header[8:].split(b"/")[0].strip() + if value.startswith(b"="): + value = value[1:].strip() + if not headers and (not _accept(keyword) or value != b"T"): + msg = "Not a FITS file" + raise SyntaxError(msg) + headers[keyword] = value + + naxis = int(headers[b"NAXIS"]) + if naxis == 0: + msg = "No image data" + raise ValueError(msg) + elif naxis == 1: + self._size = 1, int(headers[b"NAXIS1"]) + else: + self._size = int(headers[b"NAXIS1"]), int(headers[b"NAXIS2"]) + + number_of_bits = int(headers[b"BITPIX"]) + if number_of_bits == 8: + self._mode = "L" + elif number_of_bits == 16: + self._mode = "I" + elif number_of_bits == 32: + self._mode = "I" + elif number_of_bits in (-32, -64): + self._mode = "F" + + offset = math.ceil(self.fp.tell() / 2880) * 2880 + self.tile = [("raw", (0, 0) + self.size, offset, (self.mode, 0, -1))] + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(FitsImageFile.format, FitsImageFile, _accept) + +Image.register_extensions(FitsImageFile.format, [".fit", ".fits"]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/FliImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/FliImagePlugin.py new file mode 100644 index 00000000..9769761f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/FliImagePlugin.py @@ -0,0 +1,173 @@ +# +# The Python Imaging Library. +# $Id$ +# +# FLI/FLC file handling. +# +# History: +# 95-09-01 fl Created +# 97-01-03 fl Fixed parser, setup decoder tile +# 98-07-15 fl Renamed offset attribute to avoid name clash +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import i32le as i32 +from ._binary import o8 + +# +# decoder + + +def _accept(prefix): + return ( + len(prefix) >= 6 + and i16(prefix, 4) in [0xAF11, 0xAF12] + and i16(prefix, 14) in [0, 3] # flags + ) + + +## +# Image plugin for the FLI/FLC animation format. Use the seek +# method to load individual frames. + + +class FliImageFile(ImageFile.ImageFile): + format = "FLI" + format_description = "Autodesk FLI/FLC Animation" + _close_exclusive_fp_after_loading = False + + def _open(self): + # HEAD + s = self.fp.read(128) + if not (_accept(s) and s[20:22] == b"\x00\x00"): + msg = "not an FLI/FLC file" + raise SyntaxError(msg) + + # frames + self.n_frames = i16(s, 6) + self.is_animated = self.n_frames > 1 + + # image characteristics + self._mode = "P" + self._size = i16(s, 8), i16(s, 10) + + # animation speed + duration = i32(s, 16) + magic = i16(s, 4) + if magic == 0xAF11: + duration = (duration * 1000) // 70 + self.info["duration"] = duration + + # look for palette + palette = [(a, a, a) for a in range(256)] + + s = self.fp.read(16) + + self.__offset = 128 + + if i16(s, 4) == 0xF100: + # prefix chunk; ignore it + self.__offset = self.__offset + i32(s) + s = self.fp.read(16) + + if i16(s, 4) == 0xF1FA: + # look for palette chunk + number_of_subchunks = i16(s, 6) + chunk_size = None + for _ in range(number_of_subchunks): + if chunk_size is not None: + self.fp.seek(chunk_size - 6, os.SEEK_CUR) + s = self.fp.read(6) + chunk_type = i16(s, 4) + if chunk_type in (4, 11): + self._palette(palette, 2 if chunk_type == 11 else 0) + break + chunk_size = i32(s) + if not chunk_size: + break + + palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette] + self.palette = ImagePalette.raw("RGB", b"".join(palette)) + + # set things up to decode first frame + self.__frame = -1 + self._fp = self.fp + self.__rewind = self.fp.tell() + self.seek(0) + + def _palette(self, palette, shift): + # load palette + + i = 0 + for e in range(i16(self.fp.read(2))): + s = self.fp.read(2) + i = i + s[0] + n = s[1] + if n == 0: + n = 256 + s = self.fp.read(n * 3) + for n in range(0, len(s), 3): + r = s[n] << shift + g = s[n + 1] << shift + b = s[n + 2] << shift + palette[i] = (r, g, b) + i += 1 + + def seek(self, frame): + if not self._seek_check(frame): + return + if frame < self.__frame: + self._seek(0) + + for f in range(self.__frame + 1, frame + 1): + self._seek(f) + + def _seek(self, frame): + if frame == 0: + self.__frame = -1 + self._fp.seek(self.__rewind) + self.__offset = 128 + else: + # ensure that the previous frame was loaded + self.load() + + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + self.__frame = frame + + # move to next frame + self.fp = self._fp + self.fp.seek(self.__offset) + + s = self.fp.read(4) + if not s: + msg = "missing frame size" + raise EOFError(msg) + + framesize = i32(s) + + self.decodermaxblock = framesize + self.tile = [("fli", (0, 0) + self.size, self.__offset, None)] + + self.__offset += framesize + + def tell(self): + return self.__frame + + +# +# registry + +Image.register_open(FliImageFile.format, FliImageFile, _accept) + +Image.register_extensions(FliImageFile.format, [".fli", ".flc"]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/FontFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/FontFile.py new file mode 100644 index 00000000..3ec1ae81 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/FontFile.py @@ -0,0 +1,136 @@ +# +# The Python Imaging Library +# $Id$ +# +# base class for raster font file parsers +# +# history: +# 1997-06-05 fl created +# 1997-08-19 fl restrict image width +# +# Copyright (c) 1997-1998 by Secret Labs AB +# Copyright (c) 1997-1998 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +from typing import BinaryIO + +from . import Image, _binary + +WIDTH = 800 + + +def puti16( + fp: BinaryIO, values: tuple[int, int, int, int, int, int, int, int, int, int] +) -> None: + """Write network order (big-endian) 16-bit sequence""" + for v in values: + if v < 0: + v += 65536 + fp.write(_binary.o16be(v)) + + +class FontFile: + """Base class for raster font file handlers.""" + + bitmap: Image.Image | None = None + + def __init__(self) -> None: + self.info: dict[bytes, bytes | int] = {} + self.glyph: list[ + tuple[ + tuple[int, int], + tuple[int, int, int, int], + tuple[int, int, int, int], + Image.Image, + ] + | None + ] = [None] * 256 + + def __getitem__( + self, ix: int + ) -> ( + tuple[ + tuple[int, int], + tuple[int, int, int, int], + tuple[int, int, int, int], + Image.Image, + ] + | None + ): + return self.glyph[ix] + + def compile(self) -> None: + """Create metrics and bitmap""" + + if self.bitmap: + return + + # create bitmap large enough to hold all data + h = w = maxwidth = 0 + lines = 1 + for glyph in self.glyph: + if glyph: + d, dst, src, im = glyph + h = max(h, src[3] - src[1]) + w = w + (src[2] - src[0]) + if w > WIDTH: + lines += 1 + w = src[2] - src[0] + maxwidth = max(maxwidth, w) + + xsize = maxwidth + ysize = lines * h + + if xsize == 0 and ysize == 0: + return + + self.ysize = h + + # paste glyphs into bitmap + self.bitmap = Image.new("1", (xsize, ysize)) + self.metrics: list[ + tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]] + | None + ] = [None] * 256 + x = y = 0 + for i in range(256): + glyph = self[i] + if glyph: + d, dst, src, im = glyph + xx = src[2] - src[0] + x0, y0 = x, y + x = x + xx + if x > WIDTH: + x, y = 0, y + h + x0, y0 = x, y + x = xx + s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0 + self.bitmap.paste(im.crop(src), s) + self.metrics[i] = d, dst, s + + def save(self, filename: str) -> None: + """Save font""" + + self.compile() + + # font data + if not self.bitmap: + msg = "No bitmap created" + raise ValueError(msg) + self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG") + + # font metrics + with open(os.path.splitext(filename)[0] + ".pil", "wb") as fp: + fp.write(b"PILfont\n") + fp.write(f";;;;;;{self.ysize};\n".encode("ascii")) # HACK!!! + fp.write(b"DATA\n") + for id in range(256): + m = self.metrics[id] + if not m: + puti16(fp, (0,) * 10) + else: + puti16(fp, m[0] + m[1] + m[2]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/FpxImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/FpxImagePlugin.py new file mode 100644 index 00000000..75680a94 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/FpxImagePlugin.py @@ -0,0 +1,255 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library. +# $Id$ +# +# FlashPix support for PIL +# +# History: +# 97-01-25 fl Created (reads uncompressed RGB images only) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import olefile + +from . import Image, ImageFile +from ._binary import i32le as i32 + +# we map from colour field tuples to (mode, rawmode) descriptors +MODES = { + # opacity + (0x00007FFE,): ("A", "L"), + # monochrome + (0x00010000,): ("L", "L"), + (0x00018000, 0x00017FFE): ("RGBA", "LA"), + # photo YCC + (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"), + (0x00028000, 0x00028001, 0x00028002, 0x00027FFE): ("RGBA", "YCCA;P"), + # standard RGB (NIFRGB) + (0x00030000, 0x00030001, 0x00030002): ("RGB", "RGB"), + (0x00038000, 0x00038001, 0x00038002, 0x00037FFE): ("RGBA", "RGBA"), +} + + +# +# -------------------------------------------------------------------- + + +def _accept(prefix): + return prefix[:8] == olefile.MAGIC + + +## +# Image plugin for the FlashPix images. + + +class FpxImageFile(ImageFile.ImageFile): + format = "FPX" + format_description = "FlashPix" + + def _open(self): + # + # read the OLE directory and see if this is a likely + # to be a FlashPix file + + try: + self.ole = olefile.OleFileIO(self.fp) + except OSError as e: + msg = "not an FPX file; invalid OLE file" + raise SyntaxError(msg) from e + + if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": + msg = "not an FPX file; bad root CLSID" + raise SyntaxError(msg) + + self._open_index(1) + + def _open_index(self, index=1): + # + # get the Image Contents Property Set + + prop = self.ole.getproperties( + [f"Data Object Store {index:06d}", "\005Image Contents"] + ) + + # size (highest resolution) + + self._size = prop[0x1000002], prop[0x1000003] + + size = max(self.size) + i = 1 + while size > 64: + size = size / 2 + i += 1 + self.maxid = i - 1 + + # mode. instead of using a single field for this, flashpix + # requires you to specify the mode for each channel in each + # resolution subimage, and leaves it to the decoder to make + # sure that they all match. for now, we'll cheat and assume + # that this is always the case. + + id = self.maxid << 16 + + s = prop[0x2000002 | id] + + bands = i32(s, 4) + if bands > 4: + msg = "Invalid number of bands" + raise OSError(msg) + + # note: for now, we ignore the "uncalibrated" flag + colors = tuple(i32(s, 8 + i * 4) & 0x7FFFFFFF for i in range(bands)) + + self._mode, self.rawmode = MODES[colors] + + # load JPEG tables, if any + self.jpeg = {} + for i in range(256): + id = 0x3000001 | (i << 16) + if id in prop: + self.jpeg[i] = prop[id] + + self._open_subimage(1, self.maxid) + + def _open_subimage(self, index=1, subimage=0): + # + # setup tile descriptors for a given subimage + + stream = [ + f"Data Object Store {index:06d}", + f"Resolution {subimage:04d}", + "Subimage 0000 Header", + ] + + fp = self.ole.openstream(stream) + + # skip prefix + fp.read(28) + + # header stream + s = fp.read(36) + + size = i32(s, 4), i32(s, 8) + # tilecount = i32(s, 12) + tilesize = i32(s, 16), i32(s, 20) + # channels = i32(s, 24) + offset = i32(s, 28) + length = i32(s, 32) + + if size != self.size: + msg = "subimage mismatch" + raise OSError(msg) + + # get tile descriptors + fp.seek(28 + offset) + s = fp.read(i32(s, 12) * length) + + x = y = 0 + xsize, ysize = size + xtile, ytile = tilesize + self.tile = [] + + for i in range(0, len(s), length): + x1 = min(xsize, x + xtile) + y1 = min(ysize, y + ytile) + + compression = i32(s, i + 8) + + if compression == 0: + self.tile.append( + ( + "raw", + (x, y, x1, y1), + i32(s, i) + 28, + (self.rawmode,), + ) + ) + + elif compression == 1: + # FIXME: the fill decoder is not implemented + self.tile.append( + ( + "fill", + (x, y, x1, y1), + i32(s, i) + 28, + (self.rawmode, s[12:16]), + ) + ) + + elif compression == 2: + internal_color_conversion = s[14] + jpeg_tables = s[15] + rawmode = self.rawmode + + if internal_color_conversion: + # The image is stored as usual (usually YCbCr). + if rawmode == "RGBA": + # For "RGBA", data is stored as YCbCrA based on + # negative RGB. The following trick works around + # this problem : + jpegmode, rawmode = "YCbCrK", "CMYK" + else: + jpegmode = None # let the decoder decide + + else: + # The image is stored as defined by rawmode + jpegmode = rawmode + + self.tile.append( + ( + "jpeg", + (x, y, x1, y1), + i32(s, i) + 28, + (rawmode, jpegmode), + ) + ) + + # FIXME: jpeg tables are tile dependent; the prefix + # data must be placed in the tile descriptor itself! + + if jpeg_tables: + self.tile_prefix = self.jpeg[jpeg_tables] + + else: + msg = "unknown/invalid compression" + raise OSError(msg) + + x = x + xtile + if x >= xsize: + x, y = 0, y + ytile + if y >= ysize: + break # isn't really required + + self.stream = stream + self._fp = self.fp + self.fp = None + + def load(self): + if not self.fp: + self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) + + return ImageFile.ImageFile.load(self) + + def close(self): + self.ole.close() + super().close() + + def __exit__(self, *args): + self.ole.close() + super().__exit__() + + +# +# -------------------------------------------------------------------- + + +Image.register_open(FpxImageFile.format, FpxImageFile, _accept) + +Image.register_extension(FpxImageFile.format, ".fpx") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/FtexImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/FtexImagePlugin.py new file mode 100644 index 00000000..d5513a56 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/FtexImagePlugin.py @@ -0,0 +1,114 @@ +""" +A Pillow loader for .ftc and .ftu files (FTEX) +Jerome Leclanche + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: + https://creativecommons.org/publicdomain/zero/1.0/ + +Independence War 2: Edge Of Chaos - Texture File Format - 16 October 2001 + +The textures used for 3D objects in Independence War 2: Edge Of Chaos are in a +packed custom format called FTEX. This file format uses file extensions FTC +and FTU. +* FTC files are compressed textures (using standard texture compression). +* FTU files are not compressed. +Texture File Format +The FTC and FTU texture files both use the same format. This +has the following structure: +{header} +{format_directory} +{data} +Where: +{header} = { + u32:magic, + u32:version, + u32:width, + u32:height, + u32:mipmap_count, + u32:format_count +} + +* The "magic" number is "FTEX". +* "width" and "height" are the dimensions of the texture. +* "mipmap_count" is the number of mipmaps in the texture. +* "format_count" is the number of texture formats (different versions of the +same texture) in this file. + +{format_directory} = format_count * { u32:format, u32:where } + +The format value is 0 for DXT1 compressed textures and 1 for 24-bit RGB +uncompressed textures. +The texture data for a format starts at the position "where" in the file. + +Each set of texture data in the file has the following structure: +{data} = format_count * { u32:mipmap_size, mipmap_size * { u8 } } +* "mipmap_size" is the number of bytes in that mip level. For compressed +textures this is the size of the texture data compressed with DXT1. For 24 bit +uncompressed textures, this is 3 * width * height. Following this are the image +bytes for that mipmap level. + +Note: All data is stored in little-Endian (Intel) byte order. +""" +from __future__ import annotations + +import struct +from enum import IntEnum +from io import BytesIO + +from . import Image, ImageFile + +MAGIC = b"FTEX" + + +class Format(IntEnum): + DXT1 = 0 + UNCOMPRESSED = 1 + + +class FtexImageFile(ImageFile.ImageFile): + format = "FTEX" + format_description = "Texture File Format (IW2:EOC)" + + def _open(self): + if not _accept(self.fp.read(4)): + msg = "not an FTEX file" + raise SyntaxError(msg) + struct.unpack("= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2) + + +## +# Image plugin for the GIMP brush format. + + +class GbrImageFile(ImageFile.ImageFile): + format = "GBR" + format_description = "GIMP brush file" + + def _open(self): + header_size = i32(self.fp.read(4)) + if header_size < 20: + msg = "not a GIMP brush" + raise SyntaxError(msg) + version = i32(self.fp.read(4)) + if version not in (1, 2): + msg = f"Unsupported GIMP brush version: {version}" + raise SyntaxError(msg) + + width = i32(self.fp.read(4)) + height = i32(self.fp.read(4)) + color_depth = i32(self.fp.read(4)) + if width <= 0 or height <= 0: + msg = "not a GIMP brush" + raise SyntaxError(msg) + if color_depth not in (1, 4): + msg = f"Unsupported GIMP brush color depth: {color_depth}" + raise SyntaxError(msg) + + if version == 1: + comment_length = header_size - 20 + else: + comment_length = header_size - 28 + magic_number = self.fp.read(4) + if magic_number != b"GIMP": + msg = "not a GIMP brush, bad magic number" + raise SyntaxError(msg) + self.info["spacing"] = i32(self.fp.read(4)) + + comment = self.fp.read(comment_length)[:-1] + + if color_depth == 1: + self._mode = "L" + else: + self._mode = "RGBA" + + self._size = width, height + + self.info["comment"] = comment + + # Image might not be small + Image._decompression_bomb_check(self.size) + + # Data is an uncompressed block of w * h * bytes/pixel + self._data_size = width * height * color_depth + + def load(self): + if not self.im: + self.im = Image.core.new(self.mode, self.size) + self.frombytes(self.fp.read(self._data_size)) + return Image.Image.load(self) + + +# +# registry + + +Image.register_open(GbrImageFile.format, GbrImageFile, _accept) +Image.register_extension(GbrImageFile.format, ".gbr") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/GdImageFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/GdImageFile.py new file mode 100644 index 00000000..d84876eb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/GdImageFile.py @@ -0,0 +1,97 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GD file handling +# +# History: +# 1996-04-12 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + + +""" +.. note:: + This format cannot be automatically recognized, so the + class is not registered for use with :py:func:`PIL.Image.open()`. To open a + gd file, use the :py:func:`PIL.GdImageFile.open()` function instead. + +.. warning:: + THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This + implementation is provided for convenience and demonstrational + purposes only. +""" +from __future__ import annotations + +from . import ImageFile, ImagePalette, UnidentifiedImageError +from ._binary import i16be as i16 +from ._binary import i32be as i32 + + +class GdImageFile(ImageFile.ImageFile): + """ + Image plugin for the GD uncompressed format. Note that this format + is not supported by the standard :py:func:`PIL.Image.open()` function. To use + this plugin, you have to import the :py:mod:`PIL.GdImageFile` module and + use the :py:func:`PIL.GdImageFile.open()` function. + """ + + format = "GD" + format_description = "GD uncompressed images" + + def _open(self): + # Header + s = self.fp.read(1037) + + if i16(s) not in [65534, 65535]: + msg = "Not a valid GD 2.x .gd file" + raise SyntaxError(msg) + + self._mode = "L" # FIXME: "P" + self._size = i16(s, 2), i16(s, 4) + + true_color = s[6] + true_color_offset = 2 if true_color else 0 + + # transparency index + tindex = i32(s, 7 + true_color_offset) + if tindex < 256: + self.info["transparency"] = tindex + + self.palette = ImagePalette.raw( + "XBGR", s[7 + true_color_offset + 4 : 7 + true_color_offset + 4 + 256 * 4] + ) + + self.tile = [ + ( + "raw", + (0, 0) + self.size, + 7 + true_color_offset + 4 + 256 * 4, + ("L", 0, 1), + ) + ] + + +def open(fp, mode="r"): + """ + Load texture from a GD image file. + + :param fp: GD file name, or an opened file handle. + :param mode: Optional mode. In this version, if the mode argument + is given, it must be "r". + :returns: An image instance. + :raises OSError: If the image could not be read. + """ + if mode != "r": + msg = "bad mode" + raise ValueError(msg) + + try: + return GdImageFile(fp) + except SyntaxError as e: + msg = "cannot identify this image file" + raise UnidentifiedImageError(msg) from e diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/GifImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/GifImagePlugin.py new file mode 100644 index 00000000..57d87078 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/GifImagePlugin.py @@ -0,0 +1,1097 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GIF file handling +# +# History: +# 1995-09-01 fl Created +# 1996-12-14 fl Added interlace support +# 1996-12-30 fl Added animation support +# 1997-01-05 fl Added write support, fixed local colour map bug +# 1997-02-23 fl Make sure to load raster data in getdata() +# 1997-07-05 fl Support external decoder (0.4) +# 1998-07-09 fl Handle all modes when saving (0.5) +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6) +# 2001-04-17 fl Added palette optimization (0.7) +# 2002-06-06 fl Added transparency support for save (0.8) +# 2004-02-24 fl Disable interlacing for small images +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import math +import os +import subprocess +from enum import IntEnum + +from . import ( + Image, + ImageChops, + ImageFile, + ImageMath, + ImageOps, + ImagePalette, + ImageSequence, +) +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + + +class LoadingStrategy(IntEnum): + """.. versionadded:: 9.1.0""" + + RGB_AFTER_FIRST = 0 + RGB_AFTER_DIFFERENT_PALETTE_ONLY = 1 + RGB_ALWAYS = 2 + + +#: .. versionadded:: 9.1.0 +LOADING_STRATEGY = LoadingStrategy.RGB_AFTER_FIRST + +# -------------------------------------------------------------------- +# Identify/read GIF files + + +def _accept(prefix): + return prefix[:6] in [b"GIF87a", b"GIF89a"] + + +## +# Image plugin for GIF images. This plugin supports both GIF87 and +# GIF89 images. + + +class GifImageFile(ImageFile.ImageFile): + format = "GIF" + format_description = "Compuserve GIF" + _close_exclusive_fp_after_loading = False + + global_palette = None + + def data(self): + s = self.fp.read(1) + if s and s[0]: + return self.fp.read(s[0]) + return None + + def _is_palette_needed(self, p): + for i in range(0, len(p), 3): + if not (i // 3 == p[i] == p[i + 1] == p[i + 2]): + return True + return False + + def _open(self): + # Screen + s = self.fp.read(13) + if not _accept(s): + msg = "not a GIF file" + raise SyntaxError(msg) + + self.info["version"] = s[:6] + self._size = i16(s, 6), i16(s, 8) + self.tile = [] + flags = s[10] + bits = (flags & 7) + 1 + + if flags & 128: + # get global palette + self.info["background"] = s[11] + # check if palette contains colour indices + p = self.fp.read(3 << bits) + if self._is_palette_needed(p): + p = ImagePalette.raw("RGB", p) + self.global_palette = self.palette = p + + self._fp = self.fp # FIXME: hack + self.__rewind = self.fp.tell() + self._n_frames = None + self._is_animated = None + self._seek(0) # get ready to read first frame + + @property + def n_frames(self): + if self._n_frames is None: + current = self.tell() + try: + while True: + self._seek(self.tell() + 1, False) + except EOFError: + self._n_frames = self.tell() + 1 + self.seek(current) + return self._n_frames + + @property + def is_animated(self): + if self._is_animated is None: + if self._n_frames is not None: + self._is_animated = self._n_frames != 1 + else: + current = self.tell() + if current: + self._is_animated = True + else: + try: + self._seek(1, False) + self._is_animated = True + except EOFError: + self._is_animated = False + + self.seek(current) + return self._is_animated + + def seek(self, frame): + if not self._seek_check(frame): + return + if frame < self.__frame: + self.im = None + self._seek(0) + + last_frame = self.__frame + for f in range(self.__frame + 1, frame + 1): + try: + self._seek(f) + except EOFError as e: + self.seek(last_frame) + msg = "no more images in GIF file" + raise EOFError(msg) from e + + def _seek(self, frame, update_image=True): + if frame == 0: + # rewind + self.__offset = 0 + self.dispose = None + self.__frame = -1 + self._fp.seek(self.__rewind) + self.disposal_method = 0 + if "comment" in self.info: + del self.info["comment"] + else: + # ensure that the previous frame was loaded + if self.tile and update_image: + self.load() + + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + + self.fp = self._fp + if self.__offset: + # backup to last frame + self.fp.seek(self.__offset) + while self.data(): + pass + self.__offset = 0 + + s = self.fp.read(1) + if not s or s == b";": + msg = "no more images in GIF file" + raise EOFError(msg) + + palette = None + + info = {} + frame_transparency = None + interlace = None + frame_dispose_extent = None + while True: + if not s: + s = self.fp.read(1) + if not s or s == b";": + break + + elif s == b"!": + # + # extensions + # + s = self.fp.read(1) + block = self.data() + if s[0] == 249: + # + # graphic control extension + # + flags = block[0] + if flags & 1: + frame_transparency = block[3] + info["duration"] = i16(block, 1) * 10 + + # disposal method - find the value of bits 4 - 6 + dispose_bits = 0b00011100 & flags + dispose_bits = dispose_bits >> 2 + if dispose_bits: + # only set the dispose if it is not + # unspecified. I'm not sure if this is + # correct, but it seems to prevent the last + # frame from looking odd for some animations + self.disposal_method = dispose_bits + elif s[0] == 254: + # + # comment extension + # + comment = b"" + + # Read this comment block + while block: + comment += block + block = self.data() + + if "comment" in info: + # If multiple comment blocks in frame, separate with \n + info["comment"] += b"\n" + comment + else: + info["comment"] = comment + s = None + continue + elif s[0] == 255 and frame == 0: + # + # application extension + # + info["extension"] = block, self.fp.tell() + if block[:11] == b"NETSCAPE2.0": + block = self.data() + if len(block) >= 3 and block[0] == 1: + self.info["loop"] = i16(block, 1) + while self.data(): + pass + + elif s == b",": + # + # local image + # + s = self.fp.read(9) + + # extent + x0, y0 = i16(s, 0), i16(s, 2) + x1, y1 = x0 + i16(s, 4), y0 + i16(s, 6) + if (x1 > self.size[0] or y1 > self.size[1]) and update_image: + self._size = max(x1, self.size[0]), max(y1, self.size[1]) + Image._decompression_bomb_check(self._size) + frame_dispose_extent = x0, y0, x1, y1 + flags = s[8] + + interlace = (flags & 64) != 0 + + if flags & 128: + bits = (flags & 7) + 1 + p = self.fp.read(3 << bits) + if self._is_palette_needed(p): + palette = ImagePalette.raw("RGB", p) + else: + palette = False + + # image data + bits = self.fp.read(1)[0] + self.__offset = self.fp.tell() + break + s = None + + if interlace is None: + msg = "image not found in GIF frame" + raise EOFError(msg) + + self.__frame = frame + if not update_image: + return + + self.tile = [] + + if self.dispose: + self.im.paste(self.dispose, self.dispose_extent) + + self._frame_palette = palette if palette is not None else self.global_palette + self._frame_transparency = frame_transparency + if frame == 0: + if self._frame_palette: + if LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS: + self._mode = "RGBA" if frame_transparency is not None else "RGB" + else: + self._mode = "P" + else: + self._mode = "L" + + if not palette and self.global_palette: + from copy import copy + + palette = copy(self.global_palette) + self.palette = palette + else: + if self.mode == "P": + if ( + LOADING_STRATEGY != LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY + or palette + ): + self.pyaccess = None + if "transparency" in self.info: + self.im.putpalettealpha(self.info["transparency"], 0) + self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG) + self._mode = "RGBA" + del self.info["transparency"] + else: + self._mode = "RGB" + self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG) + + def _rgb(color): + if self._frame_palette: + if color * 3 + 3 > len(self._frame_palette.palette): + color = 0 + color = tuple(self._frame_palette.palette[color * 3 : color * 3 + 3]) + else: + color = (color, color, color) + return color + + self.dispose_extent = frame_dispose_extent + try: + if self.disposal_method < 2: + # do not dispose or none specified + self.dispose = None + elif self.disposal_method == 2: + # replace with background colour + + # only dispose the extent in this frame + x0, y0, x1, y1 = self.dispose_extent + dispose_size = (x1 - x0, y1 - y0) + + Image._decompression_bomb_check(dispose_size) + + # by convention, attempt to use transparency first + dispose_mode = "P" + color = self.info.get("transparency", frame_transparency) + if color is not None: + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGBA" + color = _rgb(color) + (0,) + else: + color = self.info.get("background", 0) + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGB" + color = _rgb(color) + self.dispose = Image.core.fill(dispose_mode, dispose_size, color) + else: + # replace with previous contents + if self.im is not None: + # only dispose the extent in this frame + self.dispose = self._crop(self.im, self.dispose_extent) + elif frame_transparency is not None: + x0, y0, x1, y1 = self.dispose_extent + dispose_size = (x1 - x0, y1 - y0) + + Image._decompression_bomb_check(dispose_size) + dispose_mode = "P" + color = frame_transparency + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGBA" + color = _rgb(frame_transparency) + (0,) + self.dispose = Image.core.fill(dispose_mode, dispose_size, color) + except AttributeError: + pass + + if interlace is not None: + transparency = -1 + if frame_transparency is not None: + if frame == 0: + if LOADING_STRATEGY != LoadingStrategy.RGB_ALWAYS: + self.info["transparency"] = frame_transparency + elif self.mode not in ("RGB", "RGBA"): + transparency = frame_transparency + self.tile = [ + ( + "gif", + (x0, y0, x1, y1), + self.__offset, + (bits, interlace, transparency), + ) + ] + + if info.get("comment"): + self.info["comment"] = info["comment"] + for k in ["duration", "extension"]: + if k in info: + self.info[k] = info[k] + elif k in self.info: + del self.info[k] + + def load_prepare(self): + temp_mode = "P" if self._frame_palette else "L" + self._prev_im = None + if self.__frame == 0: + if self._frame_transparency is not None: + self.im = Image.core.fill( + temp_mode, self.size, self._frame_transparency + ) + elif self.mode in ("RGB", "RGBA"): + self._prev_im = self.im + if self._frame_palette: + self.im = Image.core.fill("P", self.size, self._frame_transparency or 0) + self.im.putpalette(*self._frame_palette.getdata()) + else: + self.im = None + self._mode = temp_mode + self._frame_palette = None + + super().load_prepare() + + def load_end(self): + if self.__frame == 0: + if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS: + if self._frame_transparency is not None: + self.im.putpalettealpha(self._frame_transparency, 0) + self._mode = "RGBA" + else: + self._mode = "RGB" + self.im = self.im.convert(self.mode, Image.Dither.FLOYDSTEINBERG) + return + if not self._prev_im: + return + if self._frame_transparency is not None: + self.im.putpalettealpha(self._frame_transparency, 0) + frame_im = self.im.convert("RGBA") + else: + frame_im = self.im.convert("RGB") + frame_im = self._crop(frame_im, self.dispose_extent) + + self.im = self._prev_im + self._mode = self.im.mode + if frame_im.mode == "RGBA": + self.im.paste(frame_im, self.dispose_extent, frame_im) + else: + self.im.paste(frame_im, self.dispose_extent) + + def tell(self): + return self.__frame + + +# -------------------------------------------------------------------- +# Write GIF files + + +RAWMODE = {"1": "L", "L": "L", "P": "P"} + + +def _normalize_mode(im): + """ + Takes an image (or frame), returns an image in a mode that is appropriate + for saving in a Gif. + + It may return the original image, or it may return an image converted to + palette or 'L' mode. + + :param im: Image object + :returns: Image object + """ + if im.mode in RAWMODE: + im.load() + return im + if Image.getmodebase(im.mode) == "RGB": + im = im.convert("P", palette=Image.Palette.ADAPTIVE) + if im.palette.mode == "RGBA": + for rgba in im.palette.colors: + if rgba[3] == 0: + im.info["transparency"] = im.palette.colors[rgba] + break + return im + return im.convert("L") + + +def _normalize_palette(im, palette, info): + """ + Normalizes the palette for image. + - Sets the palette to the incoming palette, if provided. + - Ensures that there's a palette for L mode images + - Optimizes the palette if necessary/desired. + + :param im: Image object + :param palette: bytes object containing the source palette, or .... + :param info: encoderinfo + :returns: Image object + """ + source_palette = None + if palette: + # a bytes palette + if isinstance(palette, (bytes, bytearray, list)): + source_palette = bytearray(palette[:768]) + if isinstance(palette, ImagePalette.ImagePalette): + source_palette = bytearray(palette.palette) + + if im.mode == "P": + if not source_palette: + source_palette = im.im.getpalette("RGB")[:768] + else: # L-mode + if not source_palette: + source_palette = bytearray(i // 3 for i in range(768)) + im.palette = ImagePalette.ImagePalette("RGB", palette=source_palette) + + if palette: + used_palette_colors = [] + for i in range(0, len(source_palette), 3): + source_color = tuple(source_palette[i : i + 3]) + index = im.palette.colors.get(source_color) + if index in used_palette_colors: + index = None + used_palette_colors.append(index) + for i, index in enumerate(used_palette_colors): + if index is None: + for j in range(len(used_palette_colors)): + if j not in used_palette_colors: + used_palette_colors[i] = j + break + im = im.remap_palette(used_palette_colors) + else: + used_palette_colors = _get_optimize(im, info) + if used_palette_colors is not None: + im = im.remap_palette(used_palette_colors, source_palette) + if "transparency" in info: + try: + info["transparency"] = used_palette_colors.index( + info["transparency"] + ) + except ValueError: + del info["transparency"] + return im + + im.palette.palette = source_palette + return im + + +def _write_single_frame(im, fp, palette): + im_out = _normalize_mode(im) + for k, v in im_out.info.items(): + im.encoderinfo.setdefault(k, v) + im_out = _normalize_palette(im_out, palette, im.encoderinfo) + + for s in _get_global_header(im_out, im.encoderinfo): + fp.write(s) + + # local image header + flags = 0 + if get_interlace(im): + flags = flags | 64 + _write_local_header(fp, im, (0, 0), flags) + + im_out.encoderconfig = (8, get_interlace(im)) + ImageFile._save(im_out, fp, [("gif", (0, 0) + im.size, 0, RAWMODE[im_out.mode])]) + + fp.write(b"\0") # end of image data + + +def _getbbox(base_im, im_frame): + if _get_palette_bytes(im_frame) != _get_palette_bytes(base_im): + im_frame = im_frame.convert("RGBA") + base_im = base_im.convert("RGBA") + delta = ImageChops.subtract_modulo(im_frame, base_im) + return delta, delta.getbbox(alpha_only=False) + + +def _write_multiple_frames(im, fp, palette): + duration = im.encoderinfo.get("duration") + disposal = im.encoderinfo.get("disposal", im.info.get("disposal")) + + im_frames = [] + previous_im = None + frame_count = 0 + background_im = None + for imSequence in itertools.chain([im], im.encoderinfo.get("append_images", [])): + for im_frame in ImageSequence.Iterator(imSequence): + # a copy is required here since seek can still mutate the image + im_frame = _normalize_mode(im_frame.copy()) + if frame_count == 0: + for k, v in im_frame.info.items(): + if k == "transparency": + continue + im.encoderinfo.setdefault(k, v) + + encoderinfo = im.encoderinfo.copy() + if "transparency" in im_frame.info: + encoderinfo.setdefault("transparency", im_frame.info["transparency"]) + im_frame = _normalize_palette(im_frame, palette, encoderinfo) + if isinstance(duration, (list, tuple)): + encoderinfo["duration"] = duration[frame_count] + elif duration is None and "duration" in im_frame.info: + encoderinfo["duration"] = im_frame.info["duration"] + if isinstance(disposal, (list, tuple)): + encoderinfo["disposal"] = disposal[frame_count] + frame_count += 1 + + diff_frame = None + if im_frames: + # delta frame + delta, bbox = _getbbox(previous_im, im_frame) + if not bbox: + # This frame is identical to the previous frame + if encoderinfo.get("duration"): + im_frames[-1]["encoderinfo"]["duration"] += encoderinfo[ + "duration" + ] + continue + if encoderinfo.get("disposal") == 2: + if background_im is None: + color = im.encoderinfo.get( + "transparency", im.info.get("transparency", (0, 0, 0)) + ) + background = _get_background(im_frame, color) + background_im = Image.new("P", im_frame.size, background) + background_im.putpalette(im_frames[0]["im"].palette) + delta, bbox = _getbbox(background_im, im_frame) + if encoderinfo.get("optimize") and im_frame.mode != "1": + if "transparency" not in encoderinfo: + try: + encoderinfo[ + "transparency" + ] = im_frame.palette._new_color_index(im_frame) + except ValueError: + pass + if "transparency" in encoderinfo: + # When the delta is zero, fill the image with transparency + diff_frame = im_frame.copy() + fill = Image.new( + "P", diff_frame.size, encoderinfo["transparency"] + ) + if delta.mode == "RGBA": + r, g, b, a = delta.split() + mask = ImageMath.eval( + "convert(max(max(max(r, g), b), a) * 255, '1')", + r=r, + g=g, + b=b, + a=a, + ) + else: + if delta.mode == "P": + # Convert to L without considering palette + delta_l = Image.new("L", delta.size) + delta_l.putdata(delta.getdata()) + delta = delta_l + mask = ImageMath.eval("convert(im * 255, '1')", im=delta) + diff_frame.paste(fill, mask=ImageOps.invert(mask)) + else: + bbox = None + previous_im = im_frame + im_frames.append( + {"im": diff_frame or im_frame, "bbox": bbox, "encoderinfo": encoderinfo} + ) + + if len(im_frames) == 1: + if "duration" in im.encoderinfo: + # Since multiple frames will not be written, use the combined duration + im.encoderinfo["duration"] = im_frames[0]["encoderinfo"]["duration"] + return + + for frame_data in im_frames: + im_frame = frame_data["im"] + if not frame_data["bbox"]: + # global header + for s in _get_global_header(im_frame, frame_data["encoderinfo"]): + fp.write(s) + offset = (0, 0) + else: + # compress difference + if not palette: + frame_data["encoderinfo"]["include_color_table"] = True + + im_frame = im_frame.crop(frame_data["bbox"]) + offset = frame_data["bbox"][:2] + _write_frame_data(fp, im_frame, offset, frame_data["encoderinfo"]) + return True + + +def _save_all(im, fp, filename): + _save(im, fp, filename, save_all=True) + + +def _save(im, fp, filename, save_all=False): + # header + if "palette" in im.encoderinfo or "palette" in im.info: + palette = im.encoderinfo.get("palette", im.info.get("palette")) + else: + palette = None + im.encoderinfo.setdefault("optimize", True) + + if not save_all or not _write_multiple_frames(im, fp, palette): + _write_single_frame(im, fp, palette) + + fp.write(b";") # end of file + + if hasattr(fp, "flush"): + fp.flush() + + +def get_interlace(im): + interlace = im.encoderinfo.get("interlace", 1) + + # workaround for @PIL153 + if min(im.size) < 16: + interlace = 0 + + return interlace + + +def _write_local_header(fp, im, offset, flags): + try: + transparency = im.encoderinfo["transparency"] + except KeyError: + transparency = None + + if "duration" in im.encoderinfo: + duration = int(im.encoderinfo["duration"] / 10) + else: + duration = 0 + + disposal = int(im.encoderinfo.get("disposal", 0)) + + if transparency is not None or duration != 0 or disposal: + packed_flag = 1 if transparency is not None else 0 + packed_flag |= disposal << 2 + + fp.write( + b"!" + + o8(249) # extension intro + + o8(4) # length + + o8(packed_flag) # packed fields + + o16(duration) # duration + + o8(transparency or 0) # transparency index + + o8(0) + ) + + include_color_table = im.encoderinfo.get("include_color_table") + if include_color_table: + palette_bytes = _get_palette_bytes(im) + color_table_size = _get_color_table_size(palette_bytes) + if color_table_size: + flags = flags | 128 # local color table flag + flags = flags | color_table_size + + fp.write( + b"," + + o16(offset[0]) # offset + + o16(offset[1]) + + o16(im.size[0]) # size + + o16(im.size[1]) + + o8(flags) # flags + ) + if include_color_table and color_table_size: + fp.write(_get_header_palette(palette_bytes)) + fp.write(o8(8)) # bits + + +def _save_netpbm(im, fp, filename): + # Unused by default. + # To use, uncomment the register_save call at the end of the file. + # + # If you need real GIF compression and/or RGB quantization, you + # can use the external NETPBM/PBMPLUS utilities. See comments + # below for information on how to enable this. + tempfile = im._dump() + + try: + with open(filename, "wb") as f: + if im.mode != "RGB": + subprocess.check_call( + ["ppmtogif", tempfile], stdout=f, stderr=subprocess.DEVNULL + ) + else: + # Pipe ppmquant output into ppmtogif + # "ppmquant 256 %s | ppmtogif > %s" % (tempfile, filename) + quant_cmd = ["ppmquant", "256", tempfile] + togif_cmd = ["ppmtogif"] + quant_proc = subprocess.Popen( + quant_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL + ) + togif_proc = subprocess.Popen( + togif_cmd, + stdin=quant_proc.stdout, + stdout=f, + stderr=subprocess.DEVNULL, + ) + + # Allow ppmquant to receive SIGPIPE if ppmtogif exits + quant_proc.stdout.close() + + retcode = quant_proc.wait() + if retcode: + raise subprocess.CalledProcessError(retcode, quant_cmd) + + retcode = togif_proc.wait() + if retcode: + raise subprocess.CalledProcessError(retcode, togif_cmd) + finally: + try: + os.unlink(tempfile) + except OSError: + pass + + +# Force optimization so that we can test performance against +# cases where it took lots of memory and time previously. +_FORCE_OPTIMIZE = False + + +def _get_optimize(im, info): + """ + Palette optimization is a potentially expensive operation. + + This function determines if the palette should be optimized using + some heuristics, then returns the list of palette entries in use. + + :param im: Image object + :param info: encoderinfo + :returns: list of indexes of palette entries in use, or None + """ + if im.mode in ("P", "L") and info and info.get("optimize"): + # Potentially expensive operation. + + # The palette saves 3 bytes per color not used, but palette + # lengths are restricted to 3*(2**N) bytes. Max saving would + # be 768 -> 6 bytes if we went all the way down to 2 colors. + # * If we're over 128 colors, we can't save any space. + # * If there aren't any holes, it's not worth collapsing. + # * If we have a 'large' image, the palette is in the noise. + + # create the new palette if not every color is used + optimise = _FORCE_OPTIMIZE or im.mode == "L" + if optimise or im.width * im.height < 512 * 512: + # check which colors are used + used_palette_colors = [] + for i, count in enumerate(im.histogram()): + if count: + used_palette_colors.append(i) + + if optimise or max(used_palette_colors) >= len(used_palette_colors): + return used_palette_colors + + num_palette_colors = len(im.palette.palette) // Image.getmodebands( + im.palette.mode + ) + current_palette_size = 1 << (num_palette_colors - 1).bit_length() + if ( + # check that the palette would become smaller when saved + len(used_palette_colors) <= current_palette_size // 2 + # check that the palette is not already the smallest possible size + and current_palette_size > 2 + ): + return used_palette_colors + + +def _get_color_table_size(palette_bytes): + # calculate the palette size for the header + if not palette_bytes: + return 0 + elif len(palette_bytes) < 9: + return 1 + else: + return math.ceil(math.log(len(palette_bytes) // 3, 2)) - 1 + + +def _get_header_palette(palette_bytes): + """ + Returns the palette, null padded to the next power of 2 (*3) bytes + suitable for direct inclusion in the GIF header + + :param palette_bytes: Unpadded palette bytes, in RGBRGB form + :returns: Null padded palette + """ + color_table_size = _get_color_table_size(palette_bytes) + + # add the missing amount of bytes + # the palette has to be 2< 0: + palette_bytes += o8(0) * 3 * actual_target_size_diff + return palette_bytes + + +def _get_palette_bytes(im): + """ + Gets the palette for inclusion in the gif header + + :param im: Image object + :returns: Bytes, len<=768 suitable for inclusion in gif header + """ + return im.palette.palette if im.palette else b"" + + +def _get_background(im, info_background): + background = 0 + if info_background: + if isinstance(info_background, tuple): + # WebPImagePlugin stores an RGBA value in info["background"] + # So it must be converted to the same format as GifImagePlugin's + # info["background"] - a global color table index + try: + background = im.palette.getcolor(info_background, im) + except ValueError as e: + if str(e) not in ( + # If all 256 colors are in use, + # then there is no need for the background color + "cannot allocate more than 256 colors", + # Ignore non-opaque WebP background + "cannot add non-opaque RGBA color to RGB palette", + ): + raise + else: + background = info_background + return background + + +def _get_global_header(im, info): + """Return a list of strings representing a GIF header""" + + # Header Block + # https://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp + + version = b"87a" + if im.info.get("version") == b"89a" or ( + info + and ( + "transparency" in info + or info.get("loop") is not None + or info.get("duration") + or info.get("comment") + ) + ): + version = b"89a" + + background = _get_background(im, info.get("background")) + + palette_bytes = _get_palette_bytes(im) + color_table_size = _get_color_table_size(palette_bytes) + + header = [ + b"GIF" # signature + + version # version + + o16(im.size[0]) # canvas width + + o16(im.size[1]), # canvas height + # Logical Screen Descriptor + # size of global color table + global color table flag + o8(color_table_size + 128), # packed fields + # background + reserved/aspect + o8(background) + o8(0), + # Global Color Table + _get_header_palette(palette_bytes), + ] + if info.get("loop") is not None: + header.append( + b"!" + + o8(255) # extension intro + + o8(11) + + b"NETSCAPE2.0" + + o8(3) + + o8(1) + + o16(info["loop"]) # number of loops + + o8(0) + ) + if info.get("comment"): + comment_block = b"!" + o8(254) # extension intro + + comment = info["comment"] + if isinstance(comment, str): + comment = comment.encode() + for i in range(0, len(comment), 255): + subblock = comment[i : i + 255] + comment_block += o8(len(subblock)) + subblock + + comment_block += o8(0) + header.append(comment_block) + return header + + +def _write_frame_data(fp, im_frame, offset, params): + try: + im_frame.encoderinfo = params + + # local image header + _write_local_header(fp, im_frame, offset, 0) + + ImageFile._save( + im_frame, fp, [("gif", (0, 0) + im_frame.size, 0, RAWMODE[im_frame.mode])] + ) + + fp.write(b"\0") # end of image data + finally: + del im_frame.encoderinfo + + +# -------------------------------------------------------------------- +# Legacy GIF utilities + + +def getheader(im, palette=None, info=None): + """ + Legacy Method to get Gif data from image. + + Warning:: May modify image data. + + :param im: Image object + :param palette: bytes object containing the source palette, or .... + :param info: encoderinfo + :returns: tuple of(list of header items, optimized palette) + + """ + used_palette_colors = _get_optimize(im, info) + + if info is None: + info = {} + + if "background" not in info and "background" in im.info: + info["background"] = im.info["background"] + + im_mod = _normalize_palette(im, palette, info) + im.palette = im_mod.palette + im.im = im_mod.im + header = _get_global_header(im, info) + + return header, used_palette_colors + + +def getdata(im, offset=(0, 0), **params): + """ + Legacy Method + + Return a list of strings representing this image. + The first string is a local image header, the rest contains + encoded image data. + + To specify duration, add the time in milliseconds, + e.g. ``getdata(im_frame, duration=1000)`` + + :param im: Image object + :param offset: Tuple of (x, y) pixels. Defaults to (0, 0) + :param \\**params: e.g. duration or other encoder info parameters + :returns: List of bytes containing GIF encoded frame data + + """ + + class Collector: + data = [] + + def write(self, data): + self.data.append(data) + + im.load() # make sure raster data is available + + fp = Collector() + + _write_frame_data(fp, im, offset, params) + + return fp.data + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GifImageFile.format, GifImageFile, _accept) +Image.register_save(GifImageFile.format, _save) +Image.register_save_all(GifImageFile.format, _save_all) +Image.register_extension(GifImageFile.format, ".gif") +Image.register_mime(GifImageFile.format, "image/gif") + +# +# Uncomment the following line if you wish to use NETPBM/PBMPLUS +# instead of the built-in "uncompressed" GIF encoder + +# Image.register_save(GifImageFile.format, _save_netpbm) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/GimpGradientFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/GimpGradientFile.py new file mode 100644 index 00000000..2d8c78ea --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/GimpGradientFile.py @@ -0,0 +1,137 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read (and render) GIMP gradient files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +""" +Stuff to translate curve segments to palette values (derived from +the corresponding code in GIMP, written by Federico Mena Quintero. +See the GIMP distribution for more information.) +""" +from __future__ import annotations + +from math import log, pi, sin, sqrt + +from ._binary import o8 + +EPSILON = 1e-10 +"""""" # Enable auto-doc for data member + + +def linear(middle, pos): + if pos <= middle: + if middle < EPSILON: + return 0.0 + else: + return 0.5 * pos / middle + else: + pos = pos - middle + middle = 1.0 - middle + if middle < EPSILON: + return 1.0 + else: + return 0.5 + 0.5 * pos / middle + + +def curved(middle, pos): + return pos ** (log(0.5) / log(max(middle, EPSILON))) + + +def sine(middle, pos): + return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 + + +def sphere_increasing(middle, pos): + return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) + + +def sphere_decreasing(middle, pos): + return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) + + +SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing] +"""""" # Enable auto-doc for data member + + +class GradientFile: + gradient = None + + def getpalette(self, entries=256): + palette = [] + + ix = 0 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + for i in range(entries): + x = i / (entries - 1) + + while x1 < x: + ix += 1 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + w = x1 - x0 + + if w < EPSILON: + scale = segment(0.5, 0.5) + else: + scale = segment((xm - x0) / w, (x - x0) / w) + + # expand to RGBA + r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5)) + g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5)) + b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5)) + a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5)) + + # add to palette + palette.append(r + g + b + a) + + return b"".join(palette), "RGBA" + + +class GimpGradientFile(GradientFile): + """File handler for GIMP's gradient format.""" + + def __init__(self, fp): + if fp.readline()[:13] != b"GIMP Gradient": + msg = "not a GIMP gradient file" + raise SyntaxError(msg) + + line = fp.readline() + + # GIMP 1.2 gradient files don't contain a name, but GIMP 1.3 files do + if line.startswith(b"Name: "): + line = fp.readline().strip() + + count = int(line) + + gradient = [] + + for i in range(count): + s = fp.readline().split() + w = [float(x) for x in s[:11]] + + x0, x1 = w[0], w[2] + xm = w[1] + rgb0 = w[3:7] + rgb1 = w[7:11] + + segment = SEGMENTS[int(s[11])] + cspace = int(s[12]) + + if cspace != 0: + msg = "cannot handle HSV colour space" + raise OSError(msg) + + gradient.append((x0, x1, xm, rgb0, rgb1, segment)) + + self.gradient = gradient diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/GimpPaletteFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/GimpPaletteFile.py new file mode 100644 index 00000000..a3109eba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/GimpPaletteFile.py @@ -0,0 +1,57 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read GIMP palette files +# +# History: +# 1997-08-23 fl Created +# 2004-09-07 fl Support GIMP 2.0 palette files. +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1997-2004. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from ._binary import o8 + + +class GimpPaletteFile: + """File handler for GIMP's palette format.""" + + rawmode = "RGB" + + def __init__(self, fp): + self.palette = [o8(i) * 3 for i in range(256)] + + if fp.readline()[:12] != b"GIMP Palette": + msg = "not a GIMP palette file" + raise SyntaxError(msg) + + for i in range(256): + s = fp.readline() + if not s: + break + + # skip fields and comment lines + if re.match(rb"\w+:|#", s): + continue + if len(s) > 100: + msg = "bad palette file" + raise SyntaxError(msg) + + v = tuple(map(int, s.split()[:3])) + if len(v) != 3: + msg = "bad palette entry" + raise ValueError(msg) + + self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2]) + + self.palette = b"".join(self.palette) + + def getpalette(self): + return self.palette, self.rawmode diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/GribStubImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/GribStubImagePlugin.py new file mode 100644 index 00000000..f8106800 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/GribStubImagePlugin.py @@ -0,0 +1,74 @@ +# +# The Python Imaging Library +# $Id$ +# +# GRIB stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler): + """ + Install application-specific GRIB image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix): + return prefix[:4] == b"GRIB" and prefix[7] == 1 + + +class GribStubImageFile(ImageFile.StubImageFile): + format = "GRIB" + format_description = "GRIB" + + def _open(self): + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + msg = "Not a GRIB file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr(_handler, "save"): + msg = "GRIB save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept) +Image.register_save(GribStubImageFile.format, _save) + +Image.register_extension(GribStubImageFile.format, ".grib") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/Hdf5StubImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/Hdf5StubImagePlugin.py new file mode 100644 index 00000000..65409e26 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/Hdf5StubImagePlugin.py @@ -0,0 +1,74 @@ +# +# The Python Imaging Library +# $Id$ +# +# HDF5 stub adapter +# +# Copyright (c) 2000-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler): + """ + Install application-specific HDF5 image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix): + return prefix[:8] == b"\x89HDF\r\n\x1a\n" + + +class HDF5StubImageFile(ImageFile.StubImageFile): + format = "HDF5" + format_description = "HDF5" + + def _open(self): + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + msg = "Not an HDF file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr(_handler, "save"): + msg = "HDF5 save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept) +Image.register_save(HDF5StubImageFile.format, _save) + +Image.register_extensions(HDF5StubImageFile.format, [".h5", ".hdf"]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/IcnsImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/IcnsImagePlugin.py new file mode 100644 index 00000000..d877b4ec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/IcnsImagePlugin.py @@ -0,0 +1,400 @@ +# +# The Python Imaging Library. +# $Id$ +# +# macOS icns file decoder, based on icns.py by Bob Ippolito. +# +# history: +# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies. +# 2020-04-04 Allow saving on all operating systems. +# +# Copyright (c) 2004 by Bob Ippolito. +# Copyright (c) 2004 by Secret Labs. +# Copyright (c) 2004 by Fredrik Lundh. +# Copyright (c) 2014 by Alastair Houghton. +# Copyright (c) 2020 by Pan Jing. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import struct +import sys + +from . import Image, ImageFile, PngImagePlugin, features + +enable_jpeg2k = features.check_codec("jpg_2000") +if enable_jpeg2k: + from . import Jpeg2KImagePlugin + +MAGIC = b"icns" +HEADERSIZE = 8 + + +def nextheader(fobj): + return struct.unpack(">4sI", fobj.read(HEADERSIZE)) + + +def read_32t(fobj, start_length, size): + # The 128x128 icon seems to have an extra header for some reason. + (start, length) = start_length + fobj.seek(start) + sig = fobj.read(4) + if sig != b"\x00\x00\x00\x00": + msg = "Unknown signature, expecting 0x00000000" + raise SyntaxError(msg) + return read_32(fobj, (start + 4, length - 4), size) + + +def read_32(fobj, start_length, size): + """ + Read a 32bit RGB icon resource. Seems to be either uncompressed or + an RLE packbits-like scheme. + """ + (start, length) = start_length + fobj.seek(start) + pixel_size = (size[0] * size[2], size[1] * size[2]) + sizesq = pixel_size[0] * pixel_size[1] + if length == sizesq * 3: + # uncompressed ("RGBRGBGB") + indata = fobj.read(length) + im = Image.frombuffer("RGB", pixel_size, indata, "raw", "RGB", 0, 1) + else: + # decode image + im = Image.new("RGB", pixel_size, None) + for band_ix in range(3): + data = [] + bytesleft = sizesq + while bytesleft > 0: + byte = fobj.read(1) + if not byte: + break + byte = byte[0] + if byte & 0x80: + blocksize = byte - 125 + byte = fobj.read(1) + for i in range(blocksize): + data.append(byte) + else: + blocksize = byte + 1 + data.append(fobj.read(blocksize)) + bytesleft -= blocksize + if bytesleft <= 0: + break + if bytesleft != 0: + msg = f"Error reading channel [{repr(bytesleft)} left]" + raise SyntaxError(msg) + band = Image.frombuffer("L", pixel_size, b"".join(data), "raw", "L", 0, 1) + im.im.putband(band.im, band_ix) + return {"RGB": im} + + +def read_mk(fobj, start_length, size): + # Alpha masks seem to be uncompressed + start = start_length[0] + fobj.seek(start) + pixel_size = (size[0] * size[2], size[1] * size[2]) + sizesq = pixel_size[0] * pixel_size[1] + band = Image.frombuffer("L", pixel_size, fobj.read(sizesq), "raw", "L", 0, 1) + return {"A": band} + + +def read_png_or_jpeg2000(fobj, start_length, size): + (start, length) = start_length + fobj.seek(start) + sig = fobj.read(12) + if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a": + fobj.seek(start) + im = PngImagePlugin.PngImageFile(fobj) + Image._decompression_bomb_check(im.size) + return {"RGBA": im} + elif ( + sig[:4] == b"\xff\x4f\xff\x51" + or sig[:4] == b"\x0d\x0a\x87\x0a" + or sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" + ): + if not enable_jpeg2k: + msg = ( + "Unsupported icon subimage format (rebuild PIL " + "with JPEG 2000 support to fix this)" + ) + raise ValueError(msg) + # j2k, jpc or j2c + fobj.seek(start) + jp2kstream = fobj.read(length) + f = io.BytesIO(jp2kstream) + im = Jpeg2KImagePlugin.Jpeg2KImageFile(f) + Image._decompression_bomb_check(im.size) + if im.mode != "RGBA": + im = im.convert("RGBA") + return {"RGBA": im} + else: + msg = "Unsupported icon subimage format" + raise ValueError(msg) + + +class IcnsFile: + SIZES = { + (512, 512, 2): [(b"ic10", read_png_or_jpeg2000)], + (512, 512, 1): [(b"ic09", read_png_or_jpeg2000)], + (256, 256, 2): [(b"ic14", read_png_or_jpeg2000)], + (256, 256, 1): [(b"ic08", read_png_or_jpeg2000)], + (128, 128, 2): [(b"ic13", read_png_or_jpeg2000)], + (128, 128, 1): [ + (b"ic07", read_png_or_jpeg2000), + (b"it32", read_32t), + (b"t8mk", read_mk), + ], + (64, 64, 1): [(b"icp6", read_png_or_jpeg2000)], + (32, 32, 2): [(b"ic12", read_png_or_jpeg2000)], + (48, 48, 1): [(b"ih32", read_32), (b"h8mk", read_mk)], + (32, 32, 1): [ + (b"icp5", read_png_or_jpeg2000), + (b"il32", read_32), + (b"l8mk", read_mk), + ], + (16, 16, 2): [(b"ic11", read_png_or_jpeg2000)], + (16, 16, 1): [ + (b"icp4", read_png_or_jpeg2000), + (b"is32", read_32), + (b"s8mk", read_mk), + ], + } + + def __init__(self, fobj): + """ + fobj is a file-like object as an icns resource + """ + # signature : (start, length) + self.dct = dct = {} + self.fobj = fobj + sig, filesize = nextheader(fobj) + if not _accept(sig): + msg = "not an icns file" + raise SyntaxError(msg) + i = HEADERSIZE + while i < filesize: + sig, blocksize = nextheader(fobj) + if blocksize <= 0: + msg = "invalid block header" + raise SyntaxError(msg) + i += HEADERSIZE + blocksize -= HEADERSIZE + dct[sig] = (i, blocksize) + fobj.seek(blocksize, io.SEEK_CUR) + i += blocksize + + def itersizes(self): + sizes = [] + for size, fmts in self.SIZES.items(): + for fmt, reader in fmts: + if fmt in self.dct: + sizes.append(size) + break + return sizes + + def bestsize(self): + sizes = self.itersizes() + if not sizes: + msg = "No 32bit icon resources found" + raise SyntaxError(msg) + return max(sizes) + + def dataforsize(self, size): + """ + Get an icon resource as {channel: array}. Note that + the arrays are bottom-up like windows bitmaps and will likely + need to be flipped or transposed in some way. + """ + dct = {} + for code, reader in self.SIZES[size]: + desc = self.dct.get(code) + if desc is not None: + dct.update(reader(self.fobj, desc, size)) + return dct + + def getimage(self, size=None): + if size is None: + size = self.bestsize() + if len(size) == 2: + size = (size[0], size[1], 1) + channels = self.dataforsize(size) + + im = channels.get("RGBA", None) + if im: + return im + + im = channels.get("RGB").copy() + try: + im.putalpha(channels["A"]) + except KeyError: + pass + return im + + +## +# Image plugin for Mac OS icons. + + +class IcnsImageFile(ImageFile.ImageFile): + """ + PIL image support for Mac OS .icns files. + Chooses the best resolution, but will possibly load + a different size image if you mutate the size attribute + before calling 'load'. + + The info dictionary has a key 'sizes' that is a list + of sizes that the icns file has. + """ + + format = "ICNS" + format_description = "Mac OS icns resource" + + def _open(self): + self.icns = IcnsFile(self.fp) + self._mode = "RGBA" + self.info["sizes"] = self.icns.itersizes() + self.best_size = self.icns.bestsize() + self.size = ( + self.best_size[0] * self.best_size[2], + self.best_size[1] * self.best_size[2], + ) + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + info_size = value + if info_size not in self.info["sizes"] and len(info_size) == 2: + info_size = (info_size[0], info_size[1], 1) + if ( + info_size not in self.info["sizes"] + and len(info_size) == 3 + and info_size[2] == 1 + ): + simple_sizes = [ + (size[0] * size[2], size[1] * size[2]) for size in self.info["sizes"] + ] + if value in simple_sizes: + info_size = self.info["sizes"][simple_sizes.index(value)] + if info_size not in self.info["sizes"]: + msg = "This is not one of the allowed sizes of this image" + raise ValueError(msg) + self._size = value + + def load(self): + if len(self.size) == 3: + self.best_size = self.size + self.size = ( + self.best_size[0] * self.best_size[2], + self.best_size[1] * self.best_size[2], + ) + + px = Image.Image.load(self) + if self.im is not None and self.im.size == self.size: + # Already loaded + return px + self.load_prepare() + # This is likely NOT the best way to do it, but whatever. + im = self.icns.getimage(self.best_size) + + # If this is a PNG or JPEG 2000, it won't be loaded yet + px = im.load() + + self.im = im.im + self._mode = im.mode + self.size = im.size + + return px + + +def _save(im, fp, filename): + """ + Saves the image as a series of PNG files, + that are then combined into a .icns file. + """ + if hasattr(fp, "flush"): + fp.flush() + + sizes = { + b"ic07": 128, + b"ic08": 256, + b"ic09": 512, + b"ic10": 1024, + b"ic11": 32, + b"ic12": 64, + b"ic13": 256, + b"ic14": 512, + } + provided_images = {im.width: im for im in im.encoderinfo.get("append_images", [])} + size_streams = {} + for size in set(sizes.values()): + image = ( + provided_images[size] + if size in provided_images + else im.resize((size, size)) + ) + + temp = io.BytesIO() + image.save(temp, "png") + size_streams[size] = temp.getvalue() + + entries = [] + for type, size in sizes.items(): + stream = size_streams[size] + entries.append( + {"type": type, "size": HEADERSIZE + len(stream), "stream": stream} + ) + + # Header + fp.write(MAGIC) + file_length = HEADERSIZE # Header + file_length += HEADERSIZE + 8 * len(entries) # TOC + file_length += sum(entry["size"] for entry in entries) + fp.write(struct.pack(">i", file_length)) + + # TOC + fp.write(b"TOC ") + fp.write(struct.pack(">i", HEADERSIZE + len(entries) * HEADERSIZE)) + for entry in entries: + fp.write(entry["type"]) + fp.write(struct.pack(">i", entry["size"])) + + # Data + for entry in entries: + fp.write(entry["type"]) + fp.write(struct.pack(">i", entry["size"])) + fp.write(entry["stream"]) + + if hasattr(fp, "flush"): + fp.flush() + + +def _accept(prefix): + return prefix[:4] == MAGIC + + +Image.register_open(IcnsImageFile.format, IcnsImageFile, _accept) +Image.register_extension(IcnsImageFile.format, ".icns") + +Image.register_save(IcnsImageFile.format, _save) +Image.register_mime(IcnsImageFile.format, "image/icns") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 IcnsImagePlugin.py [file]") + sys.exit() + + with open(sys.argv[1], "rb") as fp: + imf = IcnsImageFile(fp) + for size in imf.info["sizes"]: + width, height, scale = imf.size = size + imf.save(f"out-{width}-{height}-{scale}.png") + with Image.open(sys.argv[1]) as im: + im.save("out.png") + if sys.platform == "windows": + os.startfile("out.png") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/IcoImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/IcoImagePlugin.py new file mode 100644 index 00000000..1b22f864 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/IcoImagePlugin.py @@ -0,0 +1,356 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Icon support for PIL +# +# History: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +# This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis +# . +# https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki +# +# Icon format references: +# * https://en.wikipedia.org/wiki/ICO_(file_format) +# * https://msdn.microsoft.com/en-us/library/ms997538.aspx +from __future__ import annotations + +import warnings +from io import BytesIO +from math import ceil, log + +from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin +from ._binary import i16le as i16 +from ._binary import i32le as i32 +from ._binary import o8 +from ._binary import o16le as o16 +from ._binary import o32le as o32 + +# +# -------------------------------------------------------------------- + +_MAGIC = b"\0\0\1\0" + + +def _save(im, fp, filename): + fp.write(_MAGIC) # (2+2) + bmp = im.encoderinfo.get("bitmap_format") == "bmp" + sizes = im.encoderinfo.get( + "sizes", + [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)], + ) + frames = [] + provided_ims = [im] + im.encoderinfo.get("append_images", []) + width, height = im.size + for size in sorted(set(sizes)): + if size[0] > width or size[1] > height or size[0] > 256 or size[1] > 256: + continue + + for provided_im in provided_ims: + if provided_im.size != size: + continue + frames.append(provided_im) + if bmp: + bits = BmpImagePlugin.SAVE[provided_im.mode][1] + bits_used = [bits] + for other_im in provided_ims: + if other_im.size != size: + continue + bits = BmpImagePlugin.SAVE[other_im.mode][1] + if bits not in bits_used: + # Another image has been supplied for this size + # with a different bit depth + frames.append(other_im) + bits_used.append(bits) + break + else: + # TODO: invent a more convenient method for proportional scalings + frame = provided_im.copy() + frame.thumbnail(size, Image.Resampling.LANCZOS, reducing_gap=None) + frames.append(frame) + fp.write(o16(len(frames))) # idCount(2) + offset = fp.tell() + len(frames) * 16 + for frame in frames: + width, height = frame.size + # 0 means 256 + fp.write(o8(width if width < 256 else 0)) # bWidth(1) + fp.write(o8(height if height < 256 else 0)) # bHeight(1) + + bits, colors = BmpImagePlugin.SAVE[frame.mode][1:] if bmp else (32, 0) + fp.write(o8(colors)) # bColorCount(1) + fp.write(b"\0") # bReserved(1) + fp.write(b"\0\0") # wPlanes(2) + fp.write(o16(bits)) # wBitCount(2) + + image_io = BytesIO() + if bmp: + frame.save(image_io, "dib") + + if bits != 32: + and_mask = Image.new("1", size) + ImageFile._save( + and_mask, image_io, [("raw", (0, 0) + size, 0, ("1", 0, -1))] + ) + else: + frame.save(image_io, "png") + image_io.seek(0) + image_bytes = image_io.read() + if bmp: + image_bytes = image_bytes[:8] + o32(height * 2) + image_bytes[12:] + bytes_len = len(image_bytes) + fp.write(o32(bytes_len)) # dwBytesInRes(4) + fp.write(o32(offset)) # dwImageOffset(4) + current = fp.tell() + fp.seek(offset) + fp.write(image_bytes) + offset = offset + bytes_len + fp.seek(current) + + +def _accept(prefix): + return prefix[:4] == _MAGIC + + +class IcoFile: + def __init__(self, buf): + """ + Parse image from file-like object containing ico file data + """ + + # check magic + s = buf.read(6) + if not _accept(s): + msg = "not an ICO file" + raise SyntaxError(msg) + + self.buf = buf + self.entry = [] + + # Number of items in file + self.nb_items = i16(s, 4) + + # Get headers for each item + for i in range(self.nb_items): + s = buf.read(16) + + icon_header = { + "width": s[0], + "height": s[1], + "nb_color": s[2], # No. of colors in image (0 if >=8bpp) + "reserved": s[3], + "planes": i16(s, 4), + "bpp": i16(s, 6), + "size": i32(s, 8), + "offset": i32(s, 12), + } + + # See Wikipedia + for j in ("width", "height"): + if not icon_header[j]: + icon_header[j] = 256 + + # See Wikipedia notes about color depth. + # We need this just to differ images with equal sizes + icon_header["color_depth"] = ( + icon_header["bpp"] + or ( + icon_header["nb_color"] != 0 + and ceil(log(icon_header["nb_color"], 2)) + ) + or 256 + ) + + icon_header["dim"] = (icon_header["width"], icon_header["height"]) + icon_header["square"] = icon_header["width"] * icon_header["height"] + + self.entry.append(icon_header) + + self.entry = sorted(self.entry, key=lambda x: x["color_depth"]) + # ICO images are usually squares + self.entry = sorted(self.entry, key=lambda x: x["square"], reverse=True) + + def sizes(self): + """ + Get a list of all available icon sizes and color depths. + """ + return {(h["width"], h["height"]) for h in self.entry} + + def getentryindex(self, size, bpp=False): + for i, h in enumerate(self.entry): + if size == h["dim"] and (bpp is False or bpp == h["color_depth"]): + return i + return 0 + + def getimage(self, size, bpp=False): + """ + Get an image from the icon + """ + return self.frame(self.getentryindex(size, bpp)) + + def frame(self, idx): + """ + Get an image from frame idx + """ + + header = self.entry[idx] + + self.buf.seek(header["offset"]) + data = self.buf.read(8) + self.buf.seek(header["offset"]) + + if data[:8] == PngImagePlugin._MAGIC: + # png frame + im = PngImagePlugin.PngImageFile(self.buf) + Image._decompression_bomb_check(im.size) + else: + # XOR + AND mask bmp frame + im = BmpImagePlugin.DibImageFile(self.buf) + Image._decompression_bomb_check(im.size) + + # change tile dimension to only encompass XOR image + im._size = (im.size[0], int(im.size[1] / 2)) + d, e, o, a = im.tile[0] + im.tile[0] = d, (0, 0) + im.size, o, a + + # figure out where AND mask image starts + bpp = header["bpp"] + if 32 == bpp: + # 32-bit color depth icon image allows semitransparent areas + # PIL's DIB format ignores transparency bits, recover them. + # The DIB is packed in BGRX byte order where X is the alpha + # channel. + + # Back up to start of bmp data + self.buf.seek(o) + # extract every 4th byte (eg. 3,7,11,15,...) + alpha_bytes = self.buf.read(im.size[0] * im.size[1] * 4)[3::4] + + # convert to an 8bpp grayscale image + mask = Image.frombuffer( + "L", # 8bpp + im.size, # (w, h) + alpha_bytes, # source chars + "raw", # raw decoder + ("L", 0, -1), # 8bpp inverted, unpadded, reversed + ) + else: + # get AND image from end of bitmap + w = im.size[0] + if (w % 32) > 0: + # bitmap row data is aligned to word boundaries + w += 32 - (im.size[0] % 32) + + # the total mask data is + # padded row size * height / bits per char + + total_bytes = int((w * im.size[1]) / 8) + and_mask_offset = header["offset"] + header["size"] - total_bytes + + self.buf.seek(and_mask_offset) + mask_data = self.buf.read(total_bytes) + + # convert raw data to image + mask = Image.frombuffer( + "1", # 1 bpp + im.size, # (w, h) + mask_data, # source chars + "raw", # raw decoder + ("1;I", int(w / 8), -1), # 1bpp inverted, padded, reversed + ) + + # now we have two images, im is XOR image and mask is AND image + + # apply mask image as alpha channel + im = im.convert("RGBA") + im.putalpha(mask) + + return im + + +## +# Image plugin for Windows Icon files. + + +class IcoImageFile(ImageFile.ImageFile): + """ + PIL read-only image support for Microsoft Windows .ico files. + + By default the largest resolution image in the file will be loaded. This + can be changed by altering the 'size' attribute before calling 'load'. + + The info dictionary has a key 'sizes' that is a list of the sizes available + in the icon file. + + Handles classic, XP and Vista icon formats. + + When saving, PNG compression is used. Support for this was only added in + Windows Vista. If you are unable to view the icon in Windows, convert the + image to "RGBA" mode before saving. + + This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis + . + https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki + """ + + format = "ICO" + format_description = "Windows Icon" + + def _open(self): + self.ico = IcoFile(self.fp) + self.info["sizes"] = self.ico.sizes() + self.size = self.ico.entry[0]["dim"] + self.load() + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + if value not in self.info["sizes"]: + msg = "This is not one of the allowed sizes of this image" + raise ValueError(msg) + self._size = value + + def load(self): + if self.im is not None and self.im.size == self.size: + # Already loaded + return Image.Image.load(self) + im = self.ico.getimage(self.size) + # if tile is PNG, it won't really be loaded yet + im.load() + self.im = im.im + self.pyaccess = None + self._mode = im.mode + if im.size != self.size: + warnings.warn("Image was not the expected size") + + index = self.ico.getentryindex(self.size) + sizes = list(self.info["sizes"]) + sizes[index] = im.size + self.info["sizes"] = set(sizes) + + self.size = im.size + + def load_seek(self): + # Flag the ImageFile.Parser so that it + # just does all the decode at the end. + pass + + +# +# -------------------------------------------------------------------- + + +Image.register_open(IcoImageFile.format, IcoImageFile, _accept) +Image.register_save(IcoImageFile.format, _save) +Image.register_extension(IcoImageFile.format, ".ico") + +Image.register_mime(IcoImageFile.format, "image/x-icon") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImImagePlugin.py new file mode 100644 index 00000000..97d726a8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImImagePlugin.py @@ -0,0 +1,371 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IFUNC IM file handling for PIL +# +# history: +# 1995-09-01 fl Created. +# 1997-01-03 fl Save palette images +# 1997-01-08 fl Added sequence support +# 1997-01-23 fl Added P and RGB save support +# 1997-05-31 fl Read floating point images +# 1997-06-22 fl Save floating point images +# 1997-08-27 fl Read and save 1-bit images +# 1998-06-25 fl Added support for RGB+LUT images +# 1998-07-02 fl Added support for YCC images +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 1998-12-29 fl Added I;16 support +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# 2003-09-26 fl Added LA/PA support +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +import re + +from . import Image, ImageFile, ImagePalette + +# -------------------------------------------------------------------- +# Standard tags + +COMMENT = "Comment" +DATE = "Date" +EQUIPMENT = "Digitalization equipment" +FRAMES = "File size (no of images)" +LUT = "Lut" +NAME = "Name" +SCALE = "Scale (x,y)" +SIZE = "Image size (x*y)" +MODE = "Image type" + +TAGS = { + COMMENT: 0, + DATE: 0, + EQUIPMENT: 0, + FRAMES: 0, + LUT: 0, + NAME: 0, + SCALE: 0, + SIZE: 0, + MODE: 0, +} + +OPEN = { + # ifunc93/p3cfunc formats + "0 1 image": ("1", "1"), + "L 1 image": ("1", "1"), + "Greyscale image": ("L", "L"), + "Grayscale image": ("L", "L"), + "RGB image": ("RGB", "RGB;L"), + "RLB image": ("RGB", "RLB"), + "RYB image": ("RGB", "RLB"), + "B1 image": ("1", "1"), + "B2 image": ("P", "P;2"), + "B4 image": ("P", "P;4"), + "X 24 image": ("RGB", "RGB"), + "L 32 S image": ("I", "I;32"), + "L 32 F image": ("F", "F;32"), + # old p3cfunc formats + "RGB3 image": ("RGB", "RGB;T"), + "RYB3 image": ("RGB", "RYB;T"), + # extensions + "LA image": ("LA", "LA;L"), + "PA image": ("LA", "PA;L"), + "RGBA image": ("RGBA", "RGBA;L"), + "RGBX image": ("RGBX", "RGBX;L"), + "CMYK image": ("CMYK", "CMYK;L"), + "YCC image": ("YCbCr", "YCbCr;L"), +} + +# ifunc95 extensions +for i in ["8", "8S", "16", "16S", "32", "32F"]: + OPEN[f"L {i} image"] = ("F", f"F;{i}") + OPEN[f"L*{i} image"] = ("F", f"F;{i}") +for i in ["16", "16L", "16B"]: + OPEN[f"L {i} image"] = (f"I;{i}", f"I;{i}") + OPEN[f"L*{i} image"] = (f"I;{i}", f"I;{i}") +for i in ["32S"]: + OPEN[f"L {i} image"] = ("I", f"I;{i}") + OPEN[f"L*{i} image"] = ("I", f"I;{i}") +for i in range(2, 33): + OPEN[f"L*{i} image"] = ("F", f"F;{i}") + + +# -------------------------------------------------------------------- +# Read IM directory + +split = re.compile(rb"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$") + + +def number(s): + try: + return int(s) + except ValueError: + return float(s) + + +## +# Image plugin for the IFUNC IM file format. + + +class ImImageFile(ImageFile.ImageFile): + format = "IM" + format_description = "IFUNC Image Memory" + _close_exclusive_fp_after_loading = False + + def _open(self): + # Quick rejection: if there's not an LF among the first + # 100 bytes, this is (probably) not a text header. + + if b"\n" not in self.fp.read(100): + msg = "not an IM file" + raise SyntaxError(msg) + self.fp.seek(0) + + n = 0 + + # Default values + self.info[MODE] = "L" + self.info[SIZE] = (512, 512) + self.info[FRAMES] = 1 + + self.rawmode = "L" + + while True: + s = self.fp.read(1) + + # Some versions of IFUNC uses \n\r instead of \r\n... + if s == b"\r": + continue + + if not s or s == b"\0" or s == b"\x1A": + break + + # FIXME: this may read whole file if not a text file + s = s + self.fp.readline() + + if len(s) > 100: + msg = "not an IM file" + raise SyntaxError(msg) + + if s[-2:] == b"\r\n": + s = s[:-2] + elif s[-1:] == b"\n": + s = s[:-1] + + try: + m = split.match(s) + except re.error as e: + msg = "not an IM file" + raise SyntaxError(msg) from e + + if m: + k, v = m.group(1, 2) + + # Don't know if this is the correct encoding, + # but a decent guess (I guess) + k = k.decode("latin-1", "replace") + v = v.decode("latin-1", "replace") + + # Convert value as appropriate + if k in [FRAMES, SCALE, SIZE]: + v = v.replace("*", ",") + v = tuple(map(number, v.split(","))) + if len(v) == 1: + v = v[0] + elif k == MODE and v in OPEN: + v, self.rawmode = OPEN[v] + + # Add to dictionary. Note that COMMENT tags are + # combined into a list of strings. + if k == COMMENT: + if k in self.info: + self.info[k].append(v) + else: + self.info[k] = [v] + else: + self.info[k] = v + + if k in TAGS: + n += 1 + + else: + msg = "Syntax error in IM header: " + s.decode("ascii", "replace") + raise SyntaxError(msg) + + if not n: + msg = "Not an IM file" + raise SyntaxError(msg) + + # Basic attributes + self._size = self.info[SIZE] + self._mode = self.info[MODE] + + # Skip forward to start of image data + while s and s[:1] != b"\x1A": + s = self.fp.read(1) + if not s: + msg = "File truncated" + raise SyntaxError(msg) + + if LUT in self.info: + # convert lookup table to palette or lut attribute + palette = self.fp.read(768) + greyscale = 1 # greyscale palette + linear = 1 # linear greyscale palette + for i in range(256): + if palette[i] == palette[i + 256] == palette[i + 512]: + if palette[i] != i: + linear = 0 + else: + greyscale = 0 + if self.mode in ["L", "LA", "P", "PA"]: + if greyscale: + if not linear: + self.lut = list(palette[:256]) + else: + if self.mode in ["L", "P"]: + self._mode = self.rawmode = "P" + elif self.mode in ["LA", "PA"]: + self._mode = "PA" + self.rawmode = "PA;L" + self.palette = ImagePalette.raw("RGB;L", palette) + elif self.mode == "RGB": + if not greyscale or not linear: + self.lut = list(palette) + + self.frame = 0 + + self.__offset = offs = self.fp.tell() + + self._fp = self.fp # FIXME: hack + + if self.rawmode[:2] == "F;": + # ifunc95 formats + try: + # use bit decoder (if necessary) + bits = int(self.rawmode[2:]) + if bits not in [8, 16, 32]: + self.tile = [("bit", (0, 0) + self.size, offs, (bits, 8, 3, 0, -1))] + return + except ValueError: + pass + + if self.rawmode in ["RGB;T", "RYB;T"]: + # Old LabEye/3PC files. Would be very surprised if anyone + # ever stumbled upon such a file ;-) + size = self.size[0] * self.size[1] + self.tile = [ + ("raw", (0, 0) + self.size, offs, ("G", 0, -1)), + ("raw", (0, 0) + self.size, offs + size, ("R", 0, -1)), + ("raw", (0, 0) + self.size, offs + 2 * size, ("B", 0, -1)), + ] + else: + # LabEye/IFUNC files + self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))] + + @property + def n_frames(self): + return self.info[FRAMES] + + @property + def is_animated(self): + return self.info[FRAMES] > 1 + + def seek(self, frame): + if not self._seek_check(frame): + return + + self.frame = frame + + if self.mode == "1": + bits = 1 + else: + bits = 8 * len(self.mode) + + size = ((self.size[0] * bits + 7) // 8) * self.size[1] + offs = self.__offset + frame * size + + self.fp = self._fp + + self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))] + + def tell(self): + return self.frame + + +# +# -------------------------------------------------------------------- +# Save IM files + + +SAVE = { + # mode: (im type, raw mode) + "1": ("0 1", "1"), + "L": ("Greyscale", "L"), + "LA": ("LA", "LA;L"), + "P": ("Greyscale", "P"), + "PA": ("LA", "PA;L"), + "I": ("L 32S", "I;32S"), + "I;16": ("L 16", "I;16"), + "I;16L": ("L 16L", "I;16L"), + "I;16B": ("L 16B", "I;16B"), + "F": ("L 32F", "F;32F"), + "RGB": ("RGB", "RGB;L"), + "RGBA": ("RGBA", "RGBA;L"), + "RGBX": ("RGBX", "RGBX;L"), + "CMYK": ("CMYK", "CMYK;L"), + "YCbCr": ("YCC", "YCbCr;L"), +} + + +def _save(im, fp, filename): + try: + image_type, rawmode = SAVE[im.mode] + except KeyError as e: + msg = f"Cannot save {im.mode} images as IM" + raise ValueError(msg) from e + + frames = im.encoderinfo.get("frames", 1) + + fp.write(f"Image type: {image_type} image\r\n".encode("ascii")) + if filename: + # Each line must be 100 characters or less, + # or: SyntaxError("not an IM file") + # 8 characters are used for "Name: " and "\r\n" + # Keep just the filename, ditch the potentially overlong path + name, ext = os.path.splitext(os.path.basename(filename)) + name = "".join([name[: 92 - len(ext)], ext]) + + fp.write(f"Name: {name}\r\n".encode("ascii")) + fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii")) + fp.write(f"File size (no of images): {frames}\r\n".encode("ascii")) + if im.mode in ["P", "PA"]: + fp.write(b"Lut: 1\r\n") + fp.write(b"\000" * (511 - fp.tell()) + b"\032") + if im.mode in ["P", "PA"]: + im_palette = im.im.getpalette("RGB", "RGB;L") + colors = len(im_palette) // 3 + palette = b"" + for i in range(3): + palette += im_palette[colors * i : colors * (i + 1)] + palette += b"\x00" * (256 - colors) + fp.write(palette) # 768 bytes + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))]) + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(ImImageFile.format, ImImageFile) +Image.register_save(ImImageFile.format, _save) + +Image.register_extension(ImImageFile.format, ".im") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/Image.py b/dbdpy-env/lib/python3.9/site-packages/PIL/Image.py new file mode 100644 index 00000000..1bba9aad --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/Image.py @@ -0,0 +1,3944 @@ +# +# The Python Imaging Library. +# $Id$ +# +# the Image class wrapper +# +# partial release history: +# 1995-09-09 fl Created +# 1996-03-11 fl PIL release 0.0 (proof of concept) +# 1996-04-30 fl PIL release 0.1b1 +# 1999-07-28 fl PIL release 1.0 final +# 2000-06-07 fl PIL release 1.1 +# 2000-10-20 fl PIL release 1.1.1 +# 2001-05-07 fl PIL release 1.1.2 +# 2002-03-15 fl PIL release 1.1.3 +# 2003-05-10 fl PIL release 1.1.4 +# 2005-03-28 fl PIL release 1.1.5 +# 2006-12-02 fl PIL release 1.1.6 +# 2009-11-15 fl PIL release 1.1.7 +# +# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-2009 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +import atexit +import builtins +import io +import logging +import math +import os +import re +import struct +import sys +import tempfile +import warnings +from collections.abc import Callable, MutableMapping +from enum import IntEnum +from pathlib import Path + +try: + from defusedxml import ElementTree +except ImportError: + ElementTree = None + +# VERSION was removed in Pillow 6.0.0. +# PILLOW_VERSION was removed in Pillow 9.0.0. +# Use __version__ instead. +from . import ( + ExifTags, + ImageMode, + TiffTags, + UnidentifiedImageError, + __version__, + _plugins, +) +from ._binary import i32le, o32be, o32le +from ._util import DeferredError, is_path + +logger = logging.getLogger(__name__) + + +class DecompressionBombWarning(RuntimeWarning): + pass + + +class DecompressionBombError(Exception): + pass + + +# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image +MAX_IMAGE_PIXELS = int(1024 * 1024 * 1024 // 4 // 3) + + +try: + # If the _imaging C module is not present, Pillow will not load. + # Note that other modules should not refer to _imaging directly; + # import Image and use the Image.core variable instead. + # Also note that Image.core is not a publicly documented interface, + # and should be considered private and subject to change. + from . import _imaging as core + + if __version__ != getattr(core, "PILLOW_VERSION", None): + msg = ( + "The _imaging extension was built for another version of Pillow or PIL:\n" + f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n" + f"Pillow version: {__version__}" + ) + raise ImportError(msg) + +except ImportError as v: + core = DeferredError.new(ImportError("The _imaging C module is not installed.")) + # Explanations for ways that we know we might have an import error + if str(v).startswith("Module use of python"): + # The _imaging C module is present, but not compiled for + # the right version (windows only). Print a warning, if + # possible. + warnings.warn( + "The _imaging extension was built for another version of Python.", + RuntimeWarning, + ) + elif str(v).startswith("The _imaging extension"): + warnings.warn(str(v), RuntimeWarning) + # Fail here anyway. Don't let people run with a mostly broken Pillow. + # see docs/porting.rst + raise + + +USE_CFFI_ACCESS = False +try: + import cffi +except ImportError: + cffi = None + + +def isImageType(t): + """ + Checks if an object is an image object. + + .. warning:: + + This function is for internal use only. + + :param t: object to check if it's an image + :returns: True if the object is an image + """ + return hasattr(t, "im") + + +# +# Constants + + +# transpose +class Transpose(IntEnum): + FLIP_LEFT_RIGHT = 0 + FLIP_TOP_BOTTOM = 1 + ROTATE_90 = 2 + ROTATE_180 = 3 + ROTATE_270 = 4 + TRANSPOSE = 5 + TRANSVERSE = 6 + + +# transforms (also defined in Imaging.h) +class Transform(IntEnum): + AFFINE = 0 + EXTENT = 1 + PERSPECTIVE = 2 + QUAD = 3 + MESH = 4 + + +# resampling filters (also defined in Imaging.h) +class Resampling(IntEnum): + NEAREST = 0 + BOX = 4 + BILINEAR = 2 + HAMMING = 5 + BICUBIC = 3 + LANCZOS = 1 + + +_filters_support = { + Resampling.BOX: 0.5, + Resampling.BILINEAR: 1.0, + Resampling.HAMMING: 1.0, + Resampling.BICUBIC: 2.0, + Resampling.LANCZOS: 3.0, +} + + +# dithers +class Dither(IntEnum): + NONE = 0 + ORDERED = 1 # Not yet implemented + RASTERIZE = 2 # Not yet implemented + FLOYDSTEINBERG = 3 # default + + +# palettes/quantizers +class Palette(IntEnum): + WEB = 0 + ADAPTIVE = 1 + + +class Quantize(IntEnum): + MEDIANCUT = 0 + MAXCOVERAGE = 1 + FASTOCTREE = 2 + LIBIMAGEQUANT = 3 + + +module = sys.modules[__name__] +for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize): + for item in enum: + setattr(module, item.name, item.value) + + +if hasattr(core, "DEFAULT_STRATEGY"): + DEFAULT_STRATEGY = core.DEFAULT_STRATEGY + FILTERED = core.FILTERED + HUFFMAN_ONLY = core.HUFFMAN_ONLY + RLE = core.RLE + FIXED = core.FIXED + + +# -------------------------------------------------------------------- +# Registries + +ID = [] +OPEN = {} +MIME = {} +SAVE = {} +SAVE_ALL = {} +EXTENSION = {} +DECODERS = {} +ENCODERS = {} + +# -------------------------------------------------------------------- +# Modes + +_ENDIAN = "<" if sys.byteorder == "little" else ">" + + +def _conv_type_shape(im): + m = ImageMode.getmode(im.mode) + shape = (im.height, im.width) + extra = len(m.bands) + if extra != 1: + shape += (extra,) + return shape, m.typestr + + +MODES = ["1", "CMYK", "F", "HSV", "I", "L", "LAB", "P", "RGB", "RGBA", "RGBX", "YCbCr"] + +# raw modes that may be memory mapped. NOTE: if you change this, you +# may have to modify the stride calculation in map.c too! +_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B") + + +def getmodebase(mode): + """ + Gets the "base" mode for given mode. This function returns "L" for + images that contain grayscale data, and "RGB" for images that + contain color data. + + :param mode: Input mode. + :returns: "L" or "RGB". + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).basemode + + +def getmodetype(mode): + """ + Gets the storage type mode. Given a mode, this function returns a + single-layer mode suitable for storing individual bands. + + :param mode: Input mode. + :returns: "L", "I", or "F". + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).basetype + + +def getmodebandnames(mode): + """ + Gets a list of individual band names. Given a mode, this function returns + a tuple containing the names of individual bands (use + :py:method:`~PIL.Image.getmodetype` to get the mode used to store each + individual band. + + :param mode: Input mode. + :returns: A tuple containing band names. The length of the tuple + gives the number of bands in an image of the given mode. + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).bands + + +def getmodebands(mode): + """ + Gets the number of individual bands for this mode. + + :param mode: Input mode. + :returns: The number of bands in this mode. + :exception KeyError: If the input mode was not a standard mode. + """ + return len(ImageMode.getmode(mode).bands) + + +# -------------------------------------------------------------------- +# Helpers + +_initialized = 0 + + +def preinit(): + """ + Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers. + + It is called when opening or saving images. + """ + + global _initialized + if _initialized >= 1: + return + + try: + from . import BmpImagePlugin + + assert BmpImagePlugin + except ImportError: + pass + try: + from . import GifImagePlugin + + assert GifImagePlugin + except ImportError: + pass + try: + from . import JpegImagePlugin + + assert JpegImagePlugin + except ImportError: + pass + try: + from . import PpmImagePlugin + + assert PpmImagePlugin + except ImportError: + pass + try: + from . import PngImagePlugin + + assert PngImagePlugin + except ImportError: + pass + + _initialized = 1 + + +def init(): + """ + Explicitly initializes the Python Imaging Library. This function + loads all available file format drivers. + + It is called when opening or saving images if :py:meth:`~preinit()` is + insufficient, and by :py:meth:`~PIL.features.pilinfo`. + """ + + global _initialized + if _initialized >= 2: + return 0 + + parent_name = __name__.rpartition(".")[0] + for plugin in _plugins: + try: + logger.debug("Importing %s", plugin) + __import__(f"{parent_name}.{plugin}", globals(), locals(), []) + except ImportError as e: + logger.debug("Image: failed to import %s: %s", plugin, e) + + if OPEN or SAVE: + _initialized = 2 + return 1 + + +# -------------------------------------------------------------------- +# Codec factories (used by tobytes/frombytes and ImageFile.load) + + +def _getdecoder(mode, decoder_name, args, extra=()): + # tweak arguments + if args is None: + args = () + elif not isinstance(args, tuple): + args = (args,) + + try: + decoder = DECODERS[decoder_name] + except KeyError: + pass + else: + return decoder(mode, *args + extra) + + try: + # get decoder + decoder = getattr(core, decoder_name + "_decoder") + except AttributeError as e: + msg = f"decoder {decoder_name} not available" + raise OSError(msg) from e + return decoder(mode, *args + extra) + + +def _getencoder(mode, encoder_name, args, extra=()): + # tweak arguments + if args is None: + args = () + elif not isinstance(args, tuple): + args = (args,) + + try: + encoder = ENCODERS[encoder_name] + except KeyError: + pass + else: + return encoder(mode, *args + extra) + + try: + # get encoder + encoder = getattr(core, encoder_name + "_encoder") + except AttributeError as e: + msg = f"encoder {encoder_name} not available" + raise OSError(msg) from e + return encoder(mode, *args + extra) + + +# -------------------------------------------------------------------- +# Simple expression analyzer + + +class _E: + def __init__(self, scale, offset): + self.scale = scale + self.offset = offset + + def __neg__(self): + return _E(-self.scale, -self.offset) + + def __add__(self, other): + if isinstance(other, _E): + return _E(self.scale + other.scale, self.offset + other.offset) + return _E(self.scale, self.offset + other) + + __radd__ = __add__ + + def __sub__(self, other): + return self + -other + + def __rsub__(self, other): + return other + -self + + def __mul__(self, other): + if isinstance(other, _E): + return NotImplemented + return _E(self.scale * other, self.offset * other) + + __rmul__ = __mul__ + + def __truediv__(self, other): + if isinstance(other, _E): + return NotImplemented + return _E(self.scale / other, self.offset / other) + + +def _getscaleoffset(expr): + a = expr(_E(1, 0)) + return (a.scale, a.offset) if isinstance(a, _E) else (0, a) + + +# -------------------------------------------------------------------- +# Implementation wrapper + + +class Image: + """ + This class represents an image object. To create + :py:class:`~PIL.Image.Image` objects, use the appropriate factory + functions. There's hardly ever any reason to call the Image constructor + directly. + + * :py:func:`~PIL.Image.open` + * :py:func:`~PIL.Image.new` + * :py:func:`~PIL.Image.frombytes` + """ + + format: str | None = None + format_description: str | None = None + _close_exclusive_fp_after_loading = True + + def __init__(self): + # FIXME: take "new" parameters / other image? + # FIXME: turn mode and size into delegating properties? + self.im = None + self._mode = "" + self._size = (0, 0) + self.palette = None + self.info = {} + self.readonly = 0 + self.pyaccess = None + self._exif = None + + @property + def width(self): + return self.size[0] + + @property + def height(self): + return self.size[1] + + @property + def size(self): + return self._size + + @property + def mode(self): + return self._mode + + def _new(self, im): + new = Image() + new.im = im + new._mode = im.mode + new._size = im.size + if im.mode in ("P", "PA"): + if self.palette: + new.palette = self.palette.copy() + else: + from . import ImagePalette + + new.palette = ImagePalette.ImagePalette() + new.info = self.info.copy() + return new + + # Context manager support + def __enter__(self): + return self + + def _close_fp(self): + if getattr(self, "_fp", False): + if self._fp != self.fp: + self._fp.close() + self._fp = DeferredError(ValueError("Operation on closed image")) + if self.fp: + self.fp.close() + + def __exit__(self, *args): + if hasattr(self, "fp"): + if getattr(self, "_exclusive_fp", False): + self._close_fp() + self.fp = None + + def close(self): + """ + Closes the file pointer, if possible. + + This operation will destroy the image core and release its memory. + The image data will be unusable afterward. + + This function is required to close images that have multiple frames or + have not had their file read and closed by the + :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for + more information. + """ + if hasattr(self, "fp"): + try: + self._close_fp() + self.fp = None + except Exception as msg: + logger.debug("Error closing: %s", msg) + + if getattr(self, "map", None): + self.map = None + + # Instead of simply setting to None, we're setting up a + # deferred error that will better explain that the core image + # object is gone. + self.im = DeferredError(ValueError("Operation on closed image")) + + def _copy(self): + self.load() + self.im = self.im.copy() + self.pyaccess = None + self.readonly = 0 + + def _ensure_mutable(self): + if self.readonly: + self._copy() + else: + self.load() + + def _dump(self, file=None, format=None, **options): + suffix = "" + if format: + suffix = "." + format + + if not file: + f, filename = tempfile.mkstemp(suffix) + os.close(f) + else: + filename = file + if not filename.endswith(suffix): + filename = filename + suffix + + self.load() + + if not format or format == "PPM": + self.im.save_ppm(filename) + else: + self.save(filename, format, **options) + + return filename + + def __eq__(self, other): + return ( + self.__class__ is other.__class__ + and self.mode == other.mode + and self.size == other.size + and self.info == other.info + and self.getpalette() == other.getpalette() + and self.tobytes() == other.tobytes() + ) + + def __repr__(self): + return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % ( + self.__class__.__module__, + self.__class__.__name__, + self.mode, + self.size[0], + self.size[1], + id(self), + ) + + def _repr_pretty_(self, p, cycle): + """IPython plain text display support""" + + # Same as __repr__ but without unpredictable id(self), + # to keep Jupyter notebook `text/plain` output stable. + p.text( + "<%s.%s image mode=%s size=%dx%d>" + % ( + self.__class__.__module__, + self.__class__.__name__, + self.mode, + self.size[0], + self.size[1], + ) + ) + + def _repr_image(self, image_format, **kwargs): + """Helper function for iPython display hook. + + :param image_format: Image format. + :returns: image as bytes, saved into the given format. + """ + b = io.BytesIO() + try: + self.save(b, image_format, **kwargs) + except Exception: + return None + return b.getvalue() + + def _repr_png_(self): + """iPython display hook support for PNG format. + + :returns: PNG version of the image as bytes + """ + return self._repr_image("PNG", compress_level=1) + + def _repr_jpeg_(self): + """iPython display hook support for JPEG format. + + :returns: JPEG version of the image as bytes + """ + return self._repr_image("JPEG") + + @property + def __array_interface__(self): + # numpy array interface support + new = {"version": 3} + try: + if self.mode == "1": + # Binary images need to be extended from bits to bytes + # See: https://github.com/python-pillow/Pillow/issues/350 + new["data"] = self.tobytes("raw", "L") + else: + new["data"] = self.tobytes() + except Exception as e: + if not isinstance(e, (MemoryError, RecursionError)): + try: + import numpy + from packaging.version import parse as parse_version + except ImportError: + pass + else: + if parse_version(numpy.__version__) < parse_version("1.23"): + warnings.warn(e) + raise + new["shape"], new["typestr"] = _conv_type_shape(self) + return new + + def __getstate__(self): + im_data = self.tobytes() # load image first + return [self.info, self.mode, self.size, self.getpalette(), im_data] + + def __setstate__(self, state): + Image.__init__(self) + info, mode, size, palette, data = state + self.info = info + self._mode = mode + self._size = size + self.im = core.new(mode, size) + if mode in ("L", "LA", "P", "PA") and palette: + self.putpalette(palette) + self.frombytes(data) + + def tobytes(self, encoder_name="raw", *args): + """ + Return image as a bytes object. + + .. warning:: + + This method returns the raw image data from the internal + storage. For compressed image data (e.g. PNG, JPEG) use + :meth:`~.save`, with a BytesIO parameter for in-memory + data. + + :param encoder_name: What encoder to use. The default is to + use the standard "raw" encoder. + + A list of C encoders can be seen under + codecs section of the function array in + :file:`_imaging.c`. Python encoders are + registered within the relevant plugins. + :param args: Extra arguments to the encoder. + :returns: A :py:class:`bytes` object. + """ + + # may pass tuple instead of argument list + if len(args) == 1 and isinstance(args[0], tuple): + args = args[0] + + if encoder_name == "raw" and args == (): + args = self.mode + + self.load() + + if self.width == 0 or self.height == 0: + return b"" + + # unpack data + e = _getencoder(self.mode, encoder_name, args) + e.setimage(self.im) + + bufsize = max(65536, self.size[0] * 4) # see RawEncode.c + + output = [] + while True: + bytes_consumed, errcode, data = e.encode(bufsize) + output.append(data) + if errcode: + break + if errcode < 0: + msg = f"encoder error {errcode} in tobytes" + raise RuntimeError(msg) + + return b"".join(output) + + def tobitmap(self, name="image"): + """ + Returns the image converted to an X11 bitmap. + + .. note:: This method only works for mode "1" images. + + :param name: The name prefix to use for the bitmap variables. + :returns: A string containing an X11 bitmap. + :raises ValueError: If the mode is not "1" + """ + + self.load() + if self.mode != "1": + msg = "not a bitmap" + raise ValueError(msg) + data = self.tobytes("xbm") + return b"".join( + [ + f"#define {name}_width {self.size[0]}\n".encode("ascii"), + f"#define {name}_height {self.size[1]}\n".encode("ascii"), + f"static char {name}_bits[] = {{\n".encode("ascii"), + data, + b"};", + ] + ) + + def frombytes(self, data, decoder_name="raw", *args): + """ + Loads this image with pixel data from a bytes object. + + This method is similar to the :py:func:`~PIL.Image.frombytes` function, + but loads data into this image instead of creating a new image object. + """ + + if self.width == 0 or self.height == 0: + return + + # may pass tuple instead of argument list + if len(args) == 1 and isinstance(args[0], tuple): + args = args[0] + + # default format + if decoder_name == "raw" and args == (): + args = self.mode + + # unpack data + d = _getdecoder(self.mode, decoder_name, args) + d.setimage(self.im) + s = d.decode(data) + + if s[0] >= 0: + msg = "not enough image data" + raise ValueError(msg) + if s[1] != 0: + msg = "cannot decode image data" + raise ValueError(msg) + + def load(self): + """ + Allocates storage for the image and loads the pixel data. In + normal cases, you don't need to call this method, since the + Image class automatically loads an opened image when it is + accessed for the first time. + + If the file associated with the image was opened by Pillow, then this + method will close it. The exception to this is if the image has + multiple frames, in which case the file will be left open for seek + operations. See :ref:`file-handling` for more information. + + :returns: An image access object. + :rtype: :ref:`PixelAccess` or :py:class:`PIL.PyAccess` + """ + if self.im is not None and self.palette and self.palette.dirty: + # realize palette + mode, arr = self.palette.getdata() + self.im.putpalette(mode, arr) + self.palette.dirty = 0 + self.palette.rawmode = None + if "transparency" in self.info and mode in ("LA", "PA"): + if isinstance(self.info["transparency"], int): + self.im.putpalettealpha(self.info["transparency"], 0) + else: + self.im.putpalettealphas(self.info["transparency"]) + self.palette.mode = "RGBA" + else: + palette_mode = "RGBA" if mode.startswith("RGBA") else "RGB" + self.palette.mode = palette_mode + self.palette.palette = self.im.getpalette(palette_mode, palette_mode) + + if self.im is not None: + if cffi and USE_CFFI_ACCESS: + if self.pyaccess: + return self.pyaccess + from . import PyAccess + + self.pyaccess = PyAccess.new(self, self.readonly) + if self.pyaccess: + return self.pyaccess + return self.im.pixel_access(self.readonly) + + def verify(self): + """ + Verifies the contents of a file. For data read from a file, this + method attempts to determine if the file is broken, without + actually decoding the image data. If this method finds any + problems, it raises suitable exceptions. If you need to load + the image after using this method, you must reopen the image + file. + """ + pass + + def convert( + self, mode=None, matrix=None, dither=None, palette=Palette.WEB, colors=256 + ): + """ + Returns a converted copy of this image. For the "P" mode, this + method translates pixels through the palette. If mode is + omitted, a mode is chosen so that all information in the image + and the palette can be represented without a palette. + + The current version supports all possible conversions between + "L", "RGB" and "CMYK". The ``matrix`` argument only supports "L" + and "RGB". + + When translating a color image to grayscale (mode "L"), + the library uses the ITU-R 601-2 luma transform:: + + L = R * 299/1000 + G * 587/1000 + B * 114/1000 + + The default method of converting a grayscale ("L") or "RGB" + image into a bilevel (mode "1") image uses Floyd-Steinberg + dither to approximate the original image luminosity levels. If + dither is ``None``, all values larger than 127 are set to 255 (white), + all other values to 0 (black). To use other thresholds, use the + :py:meth:`~PIL.Image.Image.point` method. + + When converting from "RGBA" to "P" without a ``matrix`` argument, + this passes the operation to :py:meth:`~PIL.Image.Image.quantize`, + and ``dither`` and ``palette`` are ignored. + + When converting from "PA", if an "RGBA" palette is present, the alpha + channel from the image will be used instead of the values from the palette. + + :param mode: The requested mode. See: :ref:`concept-modes`. + :param matrix: An optional conversion matrix. If given, this + should be 4- or 12-tuple containing floating point values. + :param dither: Dithering method, used when converting from + mode "RGB" to "P" or from "RGB" or "L" to "1". + Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` + (default). Note that this is not used when ``matrix`` is supplied. + :param palette: Palette to use when converting from mode "RGB" + to "P". Available palettes are :data:`Palette.WEB` or + :data:`Palette.ADAPTIVE`. + :param colors: Number of colors to use for the :data:`Palette.ADAPTIVE` + palette. Defaults to 256. + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + self.load() + + has_transparency = "transparency" in self.info + if not mode and self.mode == "P": + # determine default mode + if self.palette: + mode = self.palette.mode + else: + mode = "RGB" + if mode == "RGB" and has_transparency: + mode = "RGBA" + if not mode or (mode == self.mode and not matrix): + return self.copy() + + if matrix: + # matrix conversion + if mode not in ("L", "RGB"): + msg = "illegal conversion" + raise ValueError(msg) + im = self.im.convert_matrix(mode, matrix) + new_im = self._new(im) + if has_transparency and self.im.bands == 3: + transparency = new_im.info["transparency"] + + def convert_transparency(m, v): + v = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * 0.5 + return max(0, min(255, int(v))) + + if mode == "L": + transparency = convert_transparency(matrix, transparency) + elif len(mode) == 3: + transparency = tuple( + convert_transparency(matrix[i * 4 : i * 4 + 4], transparency) + for i in range(0, len(transparency)) + ) + new_im.info["transparency"] = transparency + return new_im + + if mode == "P" and self.mode == "RGBA": + return self.quantize(colors) + + trns = None + delete_trns = False + # transparency handling + if has_transparency: + if (self.mode in ("1", "L", "I") and mode in ("LA", "RGBA")) or ( + self.mode == "RGB" and mode == "RGBA" + ): + # Use transparent conversion to promote from transparent + # color to an alpha channel. + new_im = self._new( + self.im.convert_transparent(mode, self.info["transparency"]) + ) + del new_im.info["transparency"] + return new_im + elif self.mode in ("L", "RGB", "P") and mode in ("L", "RGB", "P"): + t = self.info["transparency"] + if isinstance(t, bytes): + # Dragons. This can't be represented by a single color + warnings.warn( + "Palette images with Transparency expressed in bytes should be " + "converted to RGBA images" + ) + delete_trns = True + else: + # get the new transparency color. + # use existing conversions + trns_im = new(self.mode, (1, 1)) + if self.mode == "P": + trns_im.putpalette(self.palette) + if isinstance(t, tuple): + err = "Couldn't allocate a palette color for transparency" + try: + t = trns_im.palette.getcolor(t, self) + except ValueError as e: + if str(e) == "cannot allocate more than 256 colors": + # If all 256 colors are in use, + # then there is no need for transparency + t = None + else: + raise ValueError(err) from e + if t is None: + trns = None + else: + trns_im.putpixel((0, 0), t) + + if mode in ("L", "RGB"): + trns_im = trns_im.convert(mode) + else: + # can't just retrieve the palette number, got to do it + # after quantization. + trns_im = trns_im.convert("RGB") + trns = trns_im.getpixel((0, 0)) + + elif self.mode == "P" and mode in ("LA", "PA", "RGBA"): + t = self.info["transparency"] + delete_trns = True + + if isinstance(t, bytes): + self.im.putpalettealphas(t) + elif isinstance(t, int): + self.im.putpalettealpha(t, 0) + else: + msg = "Transparency for P mode should be bytes or int" + raise ValueError(msg) + + if mode == "P" and palette == Palette.ADAPTIVE: + im = self.im.quantize(colors) + new_im = self._new(im) + from . import ImagePalette + + new_im.palette = ImagePalette.ImagePalette( + "RGB", new_im.im.getpalette("RGB") + ) + if delete_trns: + # This could possibly happen if we requantize to fewer colors. + # The transparency would be totally off in that case. + del new_im.info["transparency"] + if trns is not None: + try: + new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im) + except Exception: + # if we can't make a transparent color, don't leave the old + # transparency hanging around to mess us up. + del new_im.info["transparency"] + warnings.warn("Couldn't allocate palette entry for transparency") + return new_im + + if "LAB" in (self.mode, mode): + other_mode = mode if self.mode == "LAB" else self.mode + if other_mode in ("RGB", "RGBA", "RGBX"): + from . import ImageCms + + srgb = ImageCms.createProfile("sRGB") + lab = ImageCms.createProfile("LAB") + profiles = [lab, srgb] if self.mode == "LAB" else [srgb, lab] + transform = ImageCms.buildTransform( + profiles[0], profiles[1], self.mode, mode + ) + return transform.apply(self) + + # colorspace conversion + if dither is None: + dither = Dither.FLOYDSTEINBERG + + try: + im = self.im.convert(mode, dither) + except ValueError: + try: + # normalize source image and try again + modebase = getmodebase(self.mode) + if modebase == self.mode: + raise + im = self.im.convert(modebase) + im = im.convert(mode, dither) + except KeyError as e: + msg = "illegal conversion" + raise ValueError(msg) from e + + new_im = self._new(im) + if mode == "P" and palette != Palette.ADAPTIVE: + from . import ImagePalette + + new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB")) + if delete_trns: + # crash fail if we leave a bytes transparency in an rgb/l mode. + del new_im.info["transparency"] + if trns is not None: + if new_im.mode == "P": + try: + new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im) + except ValueError as e: + del new_im.info["transparency"] + if str(e) != "cannot allocate more than 256 colors": + # If all 256 colors are in use, + # then there is no need for transparency + warnings.warn( + "Couldn't allocate palette entry for transparency" + ) + else: + new_im.info["transparency"] = trns + return new_im + + def quantize( + self, + colors=256, + method=None, + kmeans=0, + palette=None, + dither=Dither.FLOYDSTEINBERG, + ): + """ + Convert the image to 'P' mode with the specified number + of colors. + + :param colors: The desired number of colors, <= 256 + :param method: :data:`Quantize.MEDIANCUT` (median cut), + :data:`Quantize.MAXCOVERAGE` (maximum coverage), + :data:`Quantize.FASTOCTREE` (fast octree), + :data:`Quantize.LIBIMAGEQUANT` (libimagequant; check support + using :py:func:`PIL.features.check_feature` with + ``feature="libimagequant"``). + + By default, :data:`Quantize.MEDIANCUT` will be used. + + The exception to this is RGBA images. :data:`Quantize.MEDIANCUT` + and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so + :data:`Quantize.FASTOCTREE` is used by default instead. + :param kmeans: Integer + :param palette: Quantize to the palette of given + :py:class:`PIL.Image.Image`. + :param dither: Dithering method, used when converting from + mode "RGB" to "P" or from "RGB" or "L" to "1". + Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` + (default). + :returns: A new image + """ + + self.load() + + if method is None: + # defaults: + method = Quantize.MEDIANCUT + if self.mode == "RGBA": + method = Quantize.FASTOCTREE + + if self.mode == "RGBA" and method not in ( + Quantize.FASTOCTREE, + Quantize.LIBIMAGEQUANT, + ): + # Caller specified an invalid mode. + msg = ( + "Fast Octree (method == 2) and libimagequant (method == 3) " + "are the only valid methods for quantizing RGBA images" + ) + raise ValueError(msg) + + if palette: + # use palette from reference image + palette.load() + if palette.mode != "P": + msg = "bad mode for palette image" + raise ValueError(msg) + if self.mode not in {"RGB", "L"}: + msg = "only RGB or L mode images can be quantized to a palette" + raise ValueError(msg) + im = self.im.convert("P", dither, palette.im) + new_im = self._new(im) + new_im.palette = palette.palette.copy() + return new_im + + im = self._new(self.im.quantize(colors, method, kmeans)) + + from . import ImagePalette + + mode = im.im.getpalettemode() + palette = im.im.getpalette(mode, mode)[: colors * len(mode)] + im.palette = ImagePalette.ImagePalette(mode, palette) + + return im + + def copy(self) -> Image: + """ + Copies this image. Use this method if you wish to paste things + into an image, but still retain the original. + + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + self.load() + return self._new(self.im.copy()) + + __copy__ = copy + + def crop(self, box=None) -> Image: + """ + Returns a rectangular region from this image. The box is a + 4-tuple defining the left, upper, right, and lower pixel + coordinate. See :ref:`coordinate-system`. + + Note: Prior to Pillow 3.4.0, this was a lazy operation. + + :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if box is None: + return self.copy() + + if box[2] < box[0]: + msg = "Coordinate 'right' is less than 'left'" + raise ValueError(msg) + elif box[3] < box[1]: + msg = "Coordinate 'lower' is less than 'upper'" + raise ValueError(msg) + + self.load() + return self._new(self._crop(self.im, box)) + + def _crop(self, im, box): + """ + Returns a rectangular region from the core image object im. + + This is equivalent to calling im.crop((x0, y0, x1, y1)), but + includes additional sanity checks. + + :param im: a core image object + :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. + :returns: A core image object. + """ + + x0, y0, x1, y1 = map(int, map(round, box)) + + absolute_values = (abs(x1 - x0), abs(y1 - y0)) + + _decompression_bomb_check(absolute_values) + + return im.crop((x0, y0, x1, y1)) + + def draft(self, mode, size): + """ + Configures the image file loader so it returns a version of the + image that as closely as possible matches the given mode and + size. For example, you can use this method to convert a color + JPEG to grayscale while loading it. + + If any changes are made, returns a tuple with the chosen ``mode`` and + ``box`` with coordinates of the original image within the altered one. + + Note that this method modifies the :py:class:`~PIL.Image.Image` object + in place. If the image has already been loaded, this method has no + effect. + + Note: This method is not implemented for most images. It is + currently implemented only for JPEG and MPO images. + + :param mode: The requested mode. + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + """ + pass + + def _expand(self, xmargin, ymargin=None): + if ymargin is None: + ymargin = xmargin + self.load() + return self._new(self.im.expand(xmargin, ymargin)) + + def filter(self, filter): + """ + Filters this image using the given filter. For a list of + available filters, see the :py:mod:`~PIL.ImageFilter` module. + + :param filter: Filter kernel. + :returns: An :py:class:`~PIL.Image.Image` object.""" + + from . import ImageFilter + + self.load() + + if isinstance(filter, Callable): + filter = filter() + if not hasattr(filter, "filter"): + msg = "filter argument should be ImageFilter.Filter instance or class" + raise TypeError(msg) + + multiband = isinstance(filter, ImageFilter.MultibandFilter) + if self.im.bands == 1 or multiband: + return self._new(filter.filter(self.im)) + + ims = [ + self._new(filter.filter(self.im.getband(c))) for c in range(self.im.bands) + ] + return merge(self.mode, ims) + + def getbands(self): + """ + Returns a tuple containing the name of each band in this image. + For example, ``getbands`` on an RGB image returns ("R", "G", "B"). + + :returns: A tuple containing band names. + :rtype: tuple + """ + return ImageMode.getmode(self.mode).bands + + def getbbox(self, *, alpha_only=True): + """ + Calculates the bounding box of the non-zero regions in the + image. + + :param alpha_only: Optional flag, defaulting to ``True``. + If ``True`` and the image has an alpha channel, trim transparent pixels. + Otherwise, trim pixels when all channels are zero. + Keyword-only argument. + :returns: The bounding box is returned as a 4-tuple defining the + left, upper, right, and lower pixel coordinate. See + :ref:`coordinate-system`. If the image is completely empty, this + method returns None. + + """ + + self.load() + return self.im.getbbox(alpha_only) + + def getcolors(self, maxcolors=256): + """ + Returns a list of colors used in this image. + + The colors will be in the image's mode. For example, an RGB image will + return a tuple of (red, green, blue) color values, and a P image will + return the index of the color in the palette. + + :param maxcolors: Maximum number of colors. If this number is + exceeded, this method returns None. The default limit is + 256 colors. + :returns: An unsorted list of (count, pixel) values. + """ + + self.load() + if self.mode in ("1", "L", "P"): + h = self.im.histogram() + out = [(h[i], i) for i in range(256) if h[i]] + if len(out) > maxcolors: + return None + return out + return self.im.getcolors(maxcolors) + + def getdata(self, band=None): + """ + Returns the contents of this image as a sequence object + containing pixel values. The sequence object is flattened, so + that values for line one follow directly after the values of + line zero, and so on. + + Note that the sequence object returned by this method is an + internal PIL data type, which only supports certain sequence + operations. To convert it to an ordinary sequence (e.g. for + printing), use ``list(im.getdata())``. + + :param band: What band to return. The default is to return + all bands. To return a single band, pass in the index + value (e.g. 0 to get the "R" band from an "RGB" image). + :returns: A sequence-like object. + """ + + self.load() + if band is not None: + return self.im.getband(band) + return self.im # could be abused + + def getextrema(self): + """ + Gets the minimum and maximum pixel values for each band in + the image. + + :returns: For a single-band image, a 2-tuple containing the + minimum and maximum pixel value. For a multi-band image, + a tuple containing one 2-tuple for each band. + """ + + self.load() + if self.im.bands > 1: + return tuple(self.im.getband(i).getextrema() for i in range(self.im.bands)) + return self.im.getextrema() + + def _getxmp(self, xmp_tags): + def get_name(tag): + return re.sub("^{[^}]+}", "", tag) + + def get_value(element): + value = {get_name(k): v for k, v in element.attrib.items()} + children = list(element) + if children: + for child in children: + name = get_name(child.tag) + child_value = get_value(child) + if name in value: + if not isinstance(value[name], list): + value[name] = [value[name]] + value[name].append(child_value) + else: + value[name] = child_value + elif value: + if element.text: + value["text"] = element.text + else: + return element.text + return value + + if ElementTree is None: + warnings.warn("XMP data cannot be read without defusedxml dependency") + return {} + else: + root = ElementTree.fromstring(xmp_tags) + return {get_name(root.tag): get_value(root)} + + def getexif(self): + """ + Gets EXIF data from the image. + + :returns: an :py:class:`~PIL.Image.Exif` object. + """ + if self._exif is None: + self._exif = Exif() + self._exif._loaded = False + elif self._exif._loaded: + return self._exif + self._exif._loaded = True + + exif_info = self.info.get("exif") + if exif_info is None: + if "Raw profile type exif" in self.info: + exif_info = bytes.fromhex( + "".join(self.info["Raw profile type exif"].split("\n")[3:]) + ) + elif hasattr(self, "tag_v2"): + self._exif.bigtiff = self.tag_v2._bigtiff + self._exif.endian = self.tag_v2._endian + self._exif.load_from_fp(self.fp, self.tag_v2._offset) + if exif_info is not None: + self._exif.load(exif_info) + + # XMP tags + if ExifTags.Base.Orientation not in self._exif: + xmp_tags = self.info.get("XML:com.adobe.xmp") + if xmp_tags: + match = re.search(r'tiff:Orientation(="|>)([0-9])', xmp_tags) + if match: + self._exif[ExifTags.Base.Orientation] = int(match[2]) + + return self._exif + + def _reload_exif(self): + if self._exif is None or not self._exif._loaded: + return + self._exif._loaded = False + self.getexif() + + def get_child_images(self): + child_images = [] + exif = self.getexif() + ifds = [] + if ExifTags.Base.SubIFDs in exif: + subifd_offsets = exif[ExifTags.Base.SubIFDs] + if subifd_offsets: + if not isinstance(subifd_offsets, tuple): + subifd_offsets = (subifd_offsets,) + for subifd_offset in subifd_offsets: + ifds.append((exif._get_ifd_dict(subifd_offset), subifd_offset)) + ifd1 = exif.get_ifd(ExifTags.IFD.IFD1) + if ifd1 and ifd1.get(513): + ifds.append((ifd1, exif._info.next)) + + offset = None + for ifd, ifd_offset in ifds: + current_offset = self.fp.tell() + if offset is None: + offset = current_offset + + fp = self.fp + thumbnail_offset = ifd.get(513) + if thumbnail_offset is not None: + try: + thumbnail_offset += self._exif_offset + except AttributeError: + pass + self.fp.seek(thumbnail_offset) + data = self.fp.read(ifd.get(514)) + fp = io.BytesIO(data) + + with open(fp) as im: + if thumbnail_offset is None: + im._frame_pos = [ifd_offset] + im._seek(0) + im.load() + child_images.append(im) + + if offset is not None: + self.fp.seek(offset) + return child_images + + def getim(self): + """ + Returns a capsule that points to the internal image memory. + + :returns: A capsule object. + """ + + self.load() + return self.im.ptr + + def getpalette(self, rawmode="RGB"): + """ + Returns the image palette as a list. + + :param rawmode: The mode in which to return the palette. ``None`` will + return the palette in its current mode. + + .. versionadded:: 9.1.0 + + :returns: A list of color values [r, g, b, ...], or None if the + image has no palette. + """ + + self.load() + try: + mode = self.im.getpalettemode() + except ValueError: + return None # no palette + if rawmode is None: + rawmode = mode + return list(self.im.getpalette(mode, rawmode)) + + @property + def has_transparency_data(self) -> bool: + """ + Determine if an image has transparency data, whether in the form of an + alpha channel, a palette with an alpha channel, or a "transparency" key + in the info dictionary. + + Note the image might still appear solid, if all of the values shown + within are opaque. + + :returns: A boolean. + """ + return ( + self.mode in ("LA", "La", "PA", "RGBA", "RGBa") + or (self.mode == "P" and self.palette.mode.endswith("A")) + or "transparency" in self.info + ) + + def apply_transparency(self): + """ + If a P mode image has a "transparency" key in the info dictionary, + remove the key and instead apply the transparency to the palette. + Otherwise, the image is unchanged. + """ + if self.mode != "P" or "transparency" not in self.info: + return + + from . import ImagePalette + + palette = self.getpalette("RGBA") + transparency = self.info["transparency"] + if isinstance(transparency, bytes): + for i, alpha in enumerate(transparency): + palette[i * 4 + 3] = alpha + else: + palette[transparency * 4 + 3] = 0 + self.palette = ImagePalette.ImagePalette("RGBA", bytes(palette)) + self.palette.dirty = 1 + + del self.info["transparency"] + + def getpixel(self, xy): + """ + Returns the pixel value at a given position. + + :param xy: The coordinate, given as (x, y). See + :ref:`coordinate-system`. + :returns: The pixel value. If the image is a multi-layer image, + this method returns a tuple. + """ + + self.load() + if self.pyaccess: + return self.pyaccess.getpixel(xy) + return self.im.getpixel(tuple(xy)) + + def getprojection(self): + """ + Get projection to x and y axes + + :returns: Two sequences, indicating where there are non-zero + pixels along the X-axis and the Y-axis, respectively. + """ + + self.load() + x, y = self.im.getprojection() + return list(x), list(y) + + def histogram(self, mask=None, extrema=None): + """ + Returns a histogram for the image. The histogram is returned as a + list of pixel counts, one for each pixel value in the source + image. Counts are grouped into 256 bins for each band, even if + the image has more than 8 bits per band. If the image has more + than one band, the histograms for all bands are concatenated (for + example, the histogram for an "RGB" image contains 768 values). + + A bilevel image (mode "1") is treated as a grayscale ("L") image + by this method. + + If a mask is provided, the method returns a histogram for those + parts of the image where the mask image is non-zero. The mask + image must have the same size as the image, and be either a + bi-level image (mode "1") or a grayscale image ("L"). + + :param mask: An optional mask. + :param extrema: An optional tuple of manually-specified extrema. + :returns: A list containing pixel counts. + """ + self.load() + if mask: + mask.load() + return self.im.histogram((0, 0), mask.im) + if self.mode in ("I", "F"): + if extrema is None: + extrema = self.getextrema() + return self.im.histogram(extrema) + return self.im.histogram() + + def entropy(self, mask=None, extrema=None): + """ + Calculates and returns the entropy for the image. + + A bilevel image (mode "1") is treated as a grayscale ("L") + image by this method. + + If a mask is provided, the method employs the histogram for + those parts of the image where the mask image is non-zero. + The mask image must have the same size as the image, and be + either a bi-level image (mode "1") or a grayscale image ("L"). + + :param mask: An optional mask. + :param extrema: An optional tuple of manually-specified extrema. + :returns: A float value representing the image entropy + """ + self.load() + if mask: + mask.load() + return self.im.entropy((0, 0), mask.im) + if self.mode in ("I", "F"): + if extrema is None: + extrema = self.getextrema() + return self.im.entropy(extrema) + return self.im.entropy() + + def paste(self, im, box=None, mask=None) -> None: + """ + Pastes another image into this image. The box argument is either + a 2-tuple giving the upper left corner, a 4-tuple defining the + left, upper, right, and lower pixel coordinate, or None (same as + (0, 0)). See :ref:`coordinate-system`. If a 4-tuple is given, the size + of the pasted image must match the size of the region. + + If the modes don't match, the pasted image is converted to the mode of + this image (see the :py:meth:`~PIL.Image.Image.convert` method for + details). + + Instead of an image, the source can be a integer or tuple + containing pixel values. The method then fills the region + with the given color. When creating RGB images, you can + also use color strings as supported by the ImageColor module. + + If a mask is given, this method updates only the regions + indicated by the mask. You can use either "1", "L", "LA", "RGBA" + or "RGBa" images (if present, the alpha band is used as mask). + Where the mask is 255, the given image is copied as is. Where + the mask is 0, the current value is preserved. Intermediate + values will mix the two images together, including their alpha + channels if they have them. + + See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to + combine images with respect to their alpha channels. + + :param im: Source image or pixel value (integer or tuple). + :param box: An optional 4-tuple giving the region to paste into. + If a 2-tuple is used instead, it's treated as the upper left + corner. If omitted or None, the source is pasted into the + upper left corner. + + If an image is given as the second argument and there is no + third, the box defaults to (0, 0), and the second argument + is interpreted as a mask image. + :param mask: An optional mask image. + """ + + if isImageType(box) and mask is None: + # abbreviated paste(im, mask) syntax + mask = box + box = None + + if box is None: + box = (0, 0) + + if len(box) == 2: + # upper left corner given; get size from image or mask + if isImageType(im): + size = im.size + elif isImageType(mask): + size = mask.size + else: + # FIXME: use self.size here? + msg = "cannot determine region size; use 4-item box" + raise ValueError(msg) + box += (box[0] + size[0], box[1] + size[1]) + + if isinstance(im, str): + from . import ImageColor + + im = ImageColor.getcolor(im, self.mode) + + elif isImageType(im): + im.load() + if self.mode != im.mode: + if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"): + # should use an adapter for this! + im = im.convert(self.mode) + im = im.im + + self._ensure_mutable() + + if mask: + mask.load() + self.im.paste(im, box, mask.im) + else: + self.im.paste(im, box) + + def alpha_composite(self, im, dest=(0, 0), source=(0, 0)): + """'In-place' analog of Image.alpha_composite. Composites an image + onto this image. + + :param im: image to composite over this one + :param dest: Optional 2 tuple (left, top) specifying the upper + left corner in this (destination) image. + :param source: Optional 2 (left, top) tuple for the upper left + corner in the overlay source image, or 4 tuple (left, top, right, + bottom) for the bounds of the source rectangle + + Performance Note: Not currently implemented in-place in the core layer. + """ + + if not isinstance(source, (list, tuple)): + msg = "Source must be a tuple" + raise ValueError(msg) + if not isinstance(dest, (list, tuple)): + msg = "Destination must be a tuple" + raise ValueError(msg) + if len(source) not in (2, 4): + msg = "Source must be a 2 or 4-tuple" + raise ValueError(msg) + if not len(dest) == 2: + msg = "Destination must be a 2-tuple" + raise ValueError(msg) + if min(source) < 0: + msg = "Source must be non-negative" + raise ValueError(msg) + + if len(source) == 2: + source = source + im.size + + # over image, crop if it's not the whole thing. + if source == (0, 0) + im.size: + overlay = im + else: + overlay = im.crop(source) + + # target for the paste + box = dest + (dest[0] + overlay.width, dest[1] + overlay.height) + + # destination image. don't copy if we're using the whole image. + if box == (0, 0) + self.size: + background = self + else: + background = self.crop(box) + + result = alpha_composite(background, overlay) + self.paste(result, box) + + def point(self, lut, mode=None): + """ + Maps this image through a lookup table or function. + + :param lut: A lookup table, containing 256 (or 65536 if + self.mode=="I" and mode == "L") values per band in the + image. A function can be used instead, it should take a + single argument. The function is called once for each + possible pixel value, and the resulting table is applied to + all bands of the image. + + It may also be an :py:class:`~PIL.Image.ImagePointHandler` + object:: + + class Example(Image.ImagePointHandler): + def point(self, data): + # Return result + :param mode: Output mode (default is same as input). In the + current version, this can only be used if the source image + has mode "L" or "P", and the output has mode "1" or the + source image mode is "I" and the output mode is "L". + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + self.load() + + if isinstance(lut, ImagePointHandler): + return lut.point(self) + + if callable(lut): + # if it isn't a list, it should be a function + if self.mode in ("I", "I;16", "F"): + # check if the function can be used with point_transform + # UNDONE wiredfool -- I think this prevents us from ever doing + # a gamma function point transform on > 8bit images. + scale, offset = _getscaleoffset(lut) + return self._new(self.im.point_transform(scale, offset)) + # for other modes, convert the function to a table + lut = [lut(i) for i in range(256)] * self.im.bands + + if self.mode == "F": + # FIXME: _imaging returns a confusing error message for this case + msg = "point operation not supported for this mode" + raise ValueError(msg) + + if mode != "F": + lut = [round(i) for i in lut] + return self._new(self.im.point(lut, mode)) + + def putalpha(self, alpha): + """ + Adds or replaces the alpha layer in this image. If the image + does not have an alpha layer, it's converted to "LA" or "RGBA". + The new layer must be either "L" or "1". + + :param alpha: The new alpha layer. This can either be an "L" or "1" + image having the same size as this image, or an integer or + other color value. + """ + + self._ensure_mutable() + + if self.mode not in ("LA", "PA", "RGBA"): + # attempt to promote self to a matching alpha mode + try: + mode = getmodebase(self.mode) + "A" + try: + self.im.setmode(mode) + except (AttributeError, ValueError) as e: + # do things the hard way + im = self.im.convert(mode) + if im.mode not in ("LA", "PA", "RGBA"): + msg = "alpha channel could not be added" + raise ValueError(msg) from e # sanity check + self.im = im + self.pyaccess = None + self._mode = self.im.mode + except KeyError as e: + msg = "illegal image mode" + raise ValueError(msg) from e + + if self.mode in ("LA", "PA"): + band = 1 + else: + band = 3 + + if isImageType(alpha): + # alpha layer + if alpha.mode not in ("1", "L"): + msg = "illegal image mode" + raise ValueError(msg) + alpha.load() + if alpha.mode == "1": + alpha = alpha.convert("L") + else: + # constant alpha + try: + self.im.fillband(band, alpha) + except (AttributeError, ValueError): + # do things the hard way + alpha = new("L", self.size, alpha) + else: + return + + self.im.putband(alpha.im, band) + + def putdata(self, data, scale=1.0, offset=0.0): + """ + Copies pixel data from a flattened sequence object into the image. The + values should start at the upper left corner (0, 0), continue to the + end of the line, followed directly by the first value of the second + line, and so on. Data will be read until either the image or the + sequence ends. The scale and offset values are used to adjust the + sequence values: **pixel = value*scale + offset**. + + :param data: A flattened sequence object. + :param scale: An optional scale value. The default is 1.0. + :param offset: An optional offset value. The default is 0.0. + """ + + self._ensure_mutable() + + self.im.putdata(data, scale, offset) + + def putpalette(self, data, rawmode="RGB"): + """ + Attaches a palette to this image. The image must be a "P", "PA", "L" + or "LA" image. + + The palette sequence must contain at most 256 colors, made up of one + integer value for each channel in the raw mode. + For example, if the raw mode is "RGB", then it can contain at most 768 + values, made up of red, green and blue values for the corresponding pixel + index in the 256 colors. + If the raw mode is "RGBA", then it can contain at most 1024 values, + containing red, green, blue and alpha values. + + Alternatively, an 8-bit string may be used instead of an integer sequence. + + :param data: A palette sequence (either a list or a string). + :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", or a mode + that can be transformed to "RGB" or "RGBA" (e.g. "R", "BGR;15", "RGBA;L"). + """ + from . import ImagePalette + + if self.mode not in ("L", "LA", "P", "PA"): + msg = "illegal image mode" + raise ValueError(msg) + if isinstance(data, ImagePalette.ImagePalette): + palette = ImagePalette.raw(data.rawmode, data.palette) + else: + if not isinstance(data, bytes): + data = bytes(data) + palette = ImagePalette.raw(rawmode, data) + self._mode = "PA" if "A" in self.mode else "P" + self.palette = palette + self.palette.mode = "RGB" + self.load() # install new palette + + def putpixel(self, xy, value): + """ + Modifies the pixel at the given position. The color is given as + a single numerical value for single-band images, and a tuple for + multi-band images. In addition to this, RGB and RGBA tuples are + accepted for P and PA images. + + Note that this method is relatively slow. For more extensive changes, + use :py:meth:`~PIL.Image.Image.paste` or the :py:mod:`~PIL.ImageDraw` + module instead. + + See: + + * :py:meth:`~PIL.Image.Image.paste` + * :py:meth:`~PIL.Image.Image.putdata` + * :py:mod:`~PIL.ImageDraw` + + :param xy: The pixel coordinate, given as (x, y). See + :ref:`coordinate-system`. + :param value: The pixel value. + """ + + if self.readonly: + self._copy() + self.load() + + if self.pyaccess: + return self.pyaccess.putpixel(xy, value) + + if ( + self.mode in ("P", "PA") + and isinstance(value, (list, tuple)) + and len(value) in [3, 4] + ): + # RGB or RGBA value for a P or PA image + if self.mode == "PA": + alpha = value[3] if len(value) == 4 else 255 + value = value[:3] + value = self.palette.getcolor(value, self) + if self.mode == "PA": + value = (value, alpha) + return self.im.putpixel(xy, value) + + def remap_palette(self, dest_map, source_palette=None): + """ + Rewrites the image to reorder the palette. + + :param dest_map: A list of indexes into the original palette. + e.g. ``[1,0]`` would swap a two item palette, and ``list(range(256))`` + is the identity transform. + :param source_palette: Bytes or None. + :returns: An :py:class:`~PIL.Image.Image` object. + + """ + from . import ImagePalette + + if self.mode not in ("L", "P"): + msg = "illegal image mode" + raise ValueError(msg) + + bands = 3 + palette_mode = "RGB" + if source_palette is None: + if self.mode == "P": + self.load() + palette_mode = self.im.getpalettemode() + if palette_mode == "RGBA": + bands = 4 + source_palette = self.im.getpalette(palette_mode, palette_mode) + else: # L-mode + source_palette = bytearray(i // 3 for i in range(768)) + + palette_bytes = b"" + new_positions = [0] * 256 + + # pick only the used colors from the palette + for i, oldPosition in enumerate(dest_map): + palette_bytes += source_palette[ + oldPosition * bands : oldPosition * bands + bands + ] + new_positions[oldPosition] = i + + # replace the palette color id of all pixel with the new id + + # Palette images are [0..255], mapped through a 1 or 3 + # byte/color map. We need to remap the whole image + # from palette 1 to palette 2. New_positions is + # an array of indexes into palette 1. Palette 2 is + # palette 1 with any holes removed. + + # We're going to leverage the convert mechanism to use the + # C code to remap the image from palette 1 to palette 2, + # by forcing the source image into 'L' mode and adding a + # mapping 'L' mode palette, then converting back to 'L' + # sans palette thus converting the image bytes, then + # assigning the optimized RGB palette. + + # perf reference, 9500x4000 gif, w/~135 colors + # 14 sec prepatch, 1 sec postpatch with optimization forced. + + mapping_palette = bytearray(new_positions) + + m_im = self.copy() + m_im._mode = "P" + + m_im.palette = ImagePalette.ImagePalette( + palette_mode, palette=mapping_palette * bands + ) + # possibly set palette dirty, then + # m_im.putpalette(mapping_palette, 'L') # converts to 'P' + # or just force it. + # UNDONE -- this is part of the general issue with palettes + m_im.im.putpalette(palette_mode + ";L", m_im.palette.tobytes()) + + m_im = m_im.convert("L") + + m_im.putpalette(palette_bytes, palette_mode) + m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes) + + if "transparency" in self.info: + try: + m_im.info["transparency"] = dest_map.index(self.info["transparency"]) + except ValueError: + if "transparency" in m_im.info: + del m_im.info["transparency"] + + return m_im + + def _get_safe_box(self, size, resample, box): + """Expands the box so it includes adjacent pixels + that may be used by resampling with the given resampling filter. + """ + filter_support = _filters_support[resample] - 0.5 + scale_x = (box[2] - box[0]) / size[0] + scale_y = (box[3] - box[1]) / size[1] + support_x = filter_support * scale_x + support_y = filter_support * scale_y + + return ( + max(0, int(box[0] - support_x)), + max(0, int(box[1] - support_y)), + min(self.size[0], math.ceil(box[2] + support_x)), + min(self.size[1], math.ceil(box[3] + support_y)), + ) + + def resize(self, size, resample=None, box=None, reducing_gap=None): + """ + Returns a resized copy of this image. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param resample: An optional resampling filter. This can be + one of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, + :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, + :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. + If the image has mode "1" or "P", it is always set to + :py:data:`Resampling.NEAREST`. If the image mode specifies a number + of bits, such as "I;16", then the default filter is + :py:data:`Resampling.NEAREST`. Otherwise, the default filter is + :py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`. + :param box: An optional 4-tuple of floats providing + the source image region to be scaled. + The values must be within (0, 0, width, height) rectangle. + If omitted or None, the entire source is used. + :param reducing_gap: Apply optimization by resizing the image + in two steps. First, reducing the image by integer times + using :py:meth:`~PIL.Image.Image.reduce`. + Second, resizing using regular resampling. The last step + changes size no less than by ``reducing_gap`` times. + ``reducing_gap`` may be None (no first step is performed) + or should be greater than 1.0. The bigger ``reducing_gap``, + the closer the result to the fair resampling. + The smaller ``reducing_gap``, the faster resizing. + With ``reducing_gap`` greater or equal to 3.0, the result is + indistinguishable from fair resampling in most cases. + The default value is None (no optimization). + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if resample is None: + type_special = ";" in self.mode + resample = Resampling.NEAREST if type_special else Resampling.BICUBIC + elif resample not in ( + Resampling.NEAREST, + Resampling.BILINEAR, + Resampling.BICUBIC, + Resampling.LANCZOS, + Resampling.BOX, + Resampling.HAMMING, + ): + msg = f"Unknown resampling filter ({resample})." + + filters = [ + f"{filter[1]} ({filter[0]})" + for filter in ( + (Resampling.NEAREST, "Image.Resampling.NEAREST"), + (Resampling.LANCZOS, "Image.Resampling.LANCZOS"), + (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), + (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), + (Resampling.BOX, "Image.Resampling.BOX"), + (Resampling.HAMMING, "Image.Resampling.HAMMING"), + ) + ] + msg += " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] + raise ValueError(msg) + + if reducing_gap is not None and reducing_gap < 1.0: + msg = "reducing_gap must be 1.0 or greater" + raise ValueError(msg) + + size = tuple(size) + + self.load() + if box is None: + box = (0, 0) + self.size + else: + box = tuple(box) + + if self.size == size and box == (0, 0) + self.size: + return self.copy() + + if self.mode in ("1", "P"): + resample = Resampling.NEAREST + + if self.mode in ["LA", "RGBA"] and resample != Resampling.NEAREST: + im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + im = im.resize(size, resample, box) + return im.convert(self.mode) + + self.load() + + if reducing_gap is not None and resample != Resampling.NEAREST: + factor_x = int((box[2] - box[0]) / size[0] / reducing_gap) or 1 + factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1 + if factor_x > 1 or factor_y > 1: + reduce_box = self._get_safe_box(size, resample, box) + factor = (factor_x, factor_y) + if callable(self.reduce): + self = self.reduce(factor, box=reduce_box) + else: + self = Image.reduce(self, factor, box=reduce_box) + box = ( + (box[0] - reduce_box[0]) / factor_x, + (box[1] - reduce_box[1]) / factor_y, + (box[2] - reduce_box[0]) / factor_x, + (box[3] - reduce_box[1]) / factor_y, + ) + + return self._new(self.im.resize(size, resample, box)) + + def reduce(self, factor, box=None): + """ + Returns a copy of the image reduced ``factor`` times. + If the size of the image is not dividable by ``factor``, + the resulting size will be rounded up. + + :param factor: A greater than 0 integer or tuple of two integers + for width and height separately. + :param box: An optional 4-tuple of ints providing + the source image region to be reduced. + The values must be within ``(0, 0, width, height)`` rectangle. + If omitted or ``None``, the entire source is used. + """ + if not isinstance(factor, (list, tuple)): + factor = (factor, factor) + + if box is None: + box = (0, 0) + self.size + else: + box = tuple(box) + + if factor == (1, 1) and box == (0, 0) + self.size: + return self.copy() + + if self.mode in ["LA", "RGBA"]: + im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + im = im.reduce(factor, box) + return im.convert(self.mode) + + self.load() + + return self._new(self.im.reduce(factor, box)) + + def rotate( + self, + angle, + resample=Resampling.NEAREST, + expand=0, + center=None, + translate=None, + fillcolor=None, + ): + """ + Returns a rotated copy of this image. This method returns a + copy of this image, rotated the given number of degrees counter + clockwise around its centre. + + :param angle: In degrees counter clockwise. + :param resample: An optional resampling filter. This can be + one of :py:data:`Resampling.NEAREST` (use nearest neighbour), + :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 + environment), or :py:data:`Resampling.BICUBIC` (cubic spline + interpolation in a 4x4 environment). If omitted, or if the image has + mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. + See :ref:`concept-filters`. + :param expand: Optional expansion flag. If true, expands the output + image to make it large enough to hold the entire rotated image. + If false or omitted, make the output image the same size as the + input image. Note that the expand flag assumes rotation around + the center and no translation. + :param center: Optional center of rotation (a 2-tuple). Origin is + the upper left corner. Default is the center of the image. + :param translate: An optional post-rotate translation (a 2-tuple). + :param fillcolor: An optional color for area outside the rotated image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + angle = angle % 360.0 + + # Fast paths regardless of filter, as long as we're not + # translating or changing the center. + if not (center or translate): + if angle == 0: + return self.copy() + if angle == 180: + return self.transpose(Transpose.ROTATE_180) + if angle in (90, 270) and (expand or self.width == self.height): + return self.transpose( + Transpose.ROTATE_90 if angle == 90 else Transpose.ROTATE_270 + ) + + # Calculate the affine matrix. Note that this is the reverse + # transformation (from destination image to source) because we + # want to interpolate the (discrete) destination pixel from + # the local area around the (floating) source pixel. + + # The matrix we actually want (note that it operates from the right): + # (1, 0, tx) (1, 0, cx) ( cos a, sin a, 0) (1, 0, -cx) + # (0, 1, ty) * (0, 1, cy) * (-sin a, cos a, 0) * (0, 1, -cy) + # (0, 0, 1) (0, 0, 1) ( 0, 0, 1) (0, 0, 1) + + # The reverse matrix is thus: + # (1, 0, cx) ( cos -a, sin -a, 0) (1, 0, -cx) (1, 0, -tx) + # (0, 1, cy) * (-sin -a, cos -a, 0) * (0, 1, -cy) * (0, 1, -ty) + # (0, 0, 1) ( 0, 0, 1) (0, 0, 1) (0, 0, 1) + + # In any case, the final translation may be updated at the end to + # compensate for the expand flag. + + w, h = self.size + + if translate is None: + post_trans = (0, 0) + else: + post_trans = translate + if center is None: + # FIXME These should be rounded to ints? + rotn_center = (w / 2.0, h / 2.0) + else: + rotn_center = center + + angle = -math.radians(angle) + matrix = [ + round(math.cos(angle), 15), + round(math.sin(angle), 15), + 0.0, + round(-math.sin(angle), 15), + round(math.cos(angle), 15), + 0.0, + ] + + def transform(x, y, matrix): + (a, b, c, d, e, f) = matrix + return a * x + b * y + c, d * x + e * y + f + + matrix[2], matrix[5] = transform( + -rotn_center[0] - post_trans[0], -rotn_center[1] - post_trans[1], matrix + ) + matrix[2] += rotn_center[0] + matrix[5] += rotn_center[1] + + if expand: + # calculate output size + xx = [] + yy = [] + for x, y in ((0, 0), (w, 0), (w, h), (0, h)): + x, y = transform(x, y, matrix) + xx.append(x) + yy.append(y) + nw = math.ceil(max(xx)) - math.floor(min(xx)) + nh = math.ceil(max(yy)) - math.floor(min(yy)) + + # We multiply a translation matrix from the right. Because of its + # special form, this is the same as taking the image of the + # translation vector as new translation vector. + matrix[2], matrix[5] = transform(-(nw - w) / 2.0, -(nh - h) / 2.0, matrix) + w, h = nw, nh + + return self.transform( + (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor + ) + + def save(self, fp, format=None, **params) -> None: + """ + Saves this image under the given filename. If no format is + specified, the format to use is determined from the filename + extension, if possible. + + Keyword options can be used to provide additional instructions + to the writer. If a writer doesn't recognise an option, it is + silently ignored. The available options are described in the + :doc:`image format documentation + <../handbook/image-file-formats>` for each writer. + + You can use a file object instead of a filename. In this case, + you must always specify the format. The file object must + implement the ``seek``, ``tell``, and ``write`` + methods, and be opened in binary mode. + + :param fp: A filename (string), pathlib.Path object or file object. + :param format: Optional format override. If omitted, the + format to use is determined from the filename extension. + If a file object was used instead of a filename, this + parameter should always be used. + :param params: Extra parameters to the image writer. + :returns: None + :exception ValueError: If the output format could not be determined + from the file name. Use the format option to solve this. + :exception OSError: If the file could not be written. The file + may have been created, and may contain partial data. + """ + + filename = "" + open_fp = False + if isinstance(fp, Path): + filename = str(fp) + open_fp = True + elif is_path(fp): + filename = fp + open_fp = True + elif fp == sys.stdout: + try: + fp = sys.stdout.buffer + except AttributeError: + pass + if not filename and hasattr(fp, "name") and is_path(fp.name): + # only set the name for metadata purposes + filename = fp.name + + # may mutate self! + self._ensure_mutable() + + save_all = params.pop("save_all", False) + self.encoderinfo = params + self.encoderconfig = () + + preinit() + + ext = os.path.splitext(filename)[1].lower() + + if not format: + if ext not in EXTENSION: + init() + try: + format = EXTENSION[ext] + except KeyError as e: + msg = f"unknown file extension: {ext}" + raise ValueError(msg) from e + + if format.upper() not in SAVE: + init() + if save_all: + save_handler = SAVE_ALL[format.upper()] + else: + save_handler = SAVE[format.upper()] + + created = False + if open_fp: + created = not os.path.exists(filename) + if params.get("append", False): + # Open also for reading ("+"), because TIFF save_all + # writer needs to go back and edit the written data. + fp = builtins.open(filename, "r+b") + else: + fp = builtins.open(filename, "w+b") + + try: + save_handler(self, fp, filename) + except Exception: + if open_fp: + fp.close() + if created: + try: + os.remove(filename) + except PermissionError: + pass + raise + if open_fp: + fp.close() + + def seek(self, frame) -> Image: + """ + Seeks to the given frame in this sequence file. If you seek + beyond the end of the sequence, the method raises an + ``EOFError`` exception. When a sequence file is opened, the + library automatically seeks to frame 0. + + See :py:meth:`~PIL.Image.Image.tell`. + + If defined, :attr:`~PIL.Image.Image.n_frames` refers to the + number of available frames. + + :param frame: Frame number, starting at 0. + :exception EOFError: If the call attempts to seek beyond the end + of the sequence. + """ + + # overridden by file handlers + if frame != 0: + msg = "no more images in file" + raise EOFError(msg) + + def show(self, title=None): + """ + Displays this image. This method is mainly intended for debugging purposes. + + This method calls :py:func:`PIL.ImageShow.show` internally. You can use + :py:func:`PIL.ImageShow.register` to override its default behaviour. + + The image is first saved to a temporary file. By default, it will be in + PNG format. + + On Unix, the image is then opened using the **xdg-open**, **display**, + **gm**, **eog** or **xv** utility, depending on which one can be found. + + On macOS, the image is opened with the native Preview application. + + On Windows, the image is opened with the standard PNG display utility. + + :param title: Optional title to use for the image window, where possible. + """ + + _show(self, title=title) + + def split(self): + """ + Split this image into individual bands. This method returns a + tuple of individual image bands from an image. For example, + splitting an "RGB" image creates three new images each + containing a copy of one of the original bands (red, green, + blue). + + If you need only one band, :py:meth:`~PIL.Image.Image.getchannel` + method can be more convenient and faster. + + :returns: A tuple containing bands. + """ + + self.load() + if self.im.bands == 1: + ims = [self.copy()] + else: + ims = map(self._new, self.im.split()) + return tuple(ims) + + def getchannel(self, channel): + """ + Returns an image containing a single channel of the source image. + + :param channel: What channel to return. Could be index + (0 for "R" channel of "RGB") or channel name + ("A" for alpha channel of "RGBA"). + :returns: An image in "L" mode. + + .. versionadded:: 4.3.0 + """ + self.load() + + if isinstance(channel, str): + try: + channel = self.getbands().index(channel) + except ValueError as e: + msg = f'The image has no channel "{channel}"' + raise ValueError(msg) from e + + return self._new(self.im.getband(channel)) + + def tell(self) -> int: + """ + Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`. + + If defined, :attr:`~PIL.Image.Image.n_frames` refers to the + number of available frames. + + :returns: Frame number, starting with 0. + """ + return 0 + + def thumbnail(self, size, resample=Resampling.BICUBIC, reducing_gap=2.0): + """ + Make this image into a thumbnail. This method modifies the + image to contain a thumbnail version of itself, no larger than + the given size. This method calculates an appropriate thumbnail + size to preserve the aspect of the image, calls the + :py:meth:`~PIL.Image.Image.draft` method to configure the file reader + (where applicable), and finally resizes the image. + + Note that this function modifies the :py:class:`~PIL.Image.Image` + object in place. If you need to use the full resolution image as well, + apply this method to a :py:meth:`~PIL.Image.Image.copy` of the original + image. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param resample: Optional resampling filter. This can be one + of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, + :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, + :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. + If omitted, it defaults to :py:data:`Resampling.BICUBIC`. + (was :py:data:`Resampling.NEAREST` prior to version 2.5.0). + See: :ref:`concept-filters`. + :param reducing_gap: Apply optimization by resizing the image + in two steps. First, reducing the image by integer times + using :py:meth:`~PIL.Image.Image.reduce` or + :py:meth:`~PIL.Image.Image.draft` for JPEG images. + Second, resizing using regular resampling. The last step + changes size no less than by ``reducing_gap`` times. + ``reducing_gap`` may be None (no first step is performed) + or should be greater than 1.0. The bigger ``reducing_gap``, + the closer the result to the fair resampling. + The smaller ``reducing_gap``, the faster resizing. + With ``reducing_gap`` greater or equal to 3.0, the result is + indistinguishable from fair resampling in most cases. + The default value is 2.0 (very close to fair resampling + while still being faster in many cases). + :returns: None + """ + + provided_size = tuple(map(math.floor, size)) + + def preserve_aspect_ratio(): + def round_aspect(number, key): + return max(min(math.floor(number), math.ceil(number), key=key), 1) + + x, y = provided_size + if x >= self.width and y >= self.height: + return + + aspect = self.width / self.height + if x / y >= aspect: + x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y)) + else: + y = round_aspect( + x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n) + ) + return x, y + + box = None + if reducing_gap is not None: + size = preserve_aspect_ratio() + if size is None: + return + + res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) + if res is not None: + box = res[1] + if box is None: + self.load() + + # load() may have changed the size of the image + size = preserve_aspect_ratio() + if size is None: + return + + if self.size != size: + im = self.resize(size, resample, box=box, reducing_gap=reducing_gap) + + self.im = im.im + self._size = size + self._mode = self.im.mode + + self.readonly = 0 + self.pyaccess = None + + # FIXME: the different transform methods need further explanation + # instead of bloating the method docs, add a separate chapter. + def transform( + self, + size, + method, + data=None, + resample=Resampling.NEAREST, + fill=1, + fillcolor=None, + ) -> Image: + """ + Transforms this image. This method creates a new image with the + given size, and the same mode as the original, and copies data + to the new image using the given transform. + + :param size: The output size in pixels, as a 2-tuple: + (width, height). + :param method: The transformation method. This is one of + :py:data:`Transform.EXTENT` (cut out a rectangular subregion), + :py:data:`Transform.AFFINE` (affine transform), + :py:data:`Transform.PERSPECTIVE` (perspective transform), + :py:data:`Transform.QUAD` (map a quadrilateral to a rectangle), or + :py:data:`Transform.MESH` (map a number of source quadrilaterals + in one operation). + + It may also be an :py:class:`~PIL.Image.ImageTransformHandler` + object:: + + class Example(Image.ImageTransformHandler): + def transform(self, size, data, resample, fill=1): + # Return result + + It may also be an object with a ``method.getdata`` method + that returns a tuple supplying new ``method`` and ``data`` values:: + + class Example: + def getdata(self): + method = Image.Transform.EXTENT + data = (0, 0, 100, 100) + return method, data + :param data: Extra data to the transformation method. + :param resample: Optional resampling filter. It can be one of + :py:data:`Resampling.NEAREST` (use nearest neighbour), + :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 + environment), or :py:data:`Resampling.BICUBIC` (cubic spline + interpolation in a 4x4 environment). If omitted, or if the image + has mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. + See: :ref:`concept-filters`. + :param fill: If ``method`` is an + :py:class:`~PIL.Image.ImageTransformHandler` object, this is one of + the arguments passed to it. Otherwise, it is unused. + :param fillcolor: Optional fill color for the area outside the + transform in the output image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if self.mode in ("LA", "RGBA") and resample != Resampling.NEAREST: + return ( + self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + .transform(size, method, data, resample, fill, fillcolor) + .convert(self.mode) + ) + + if isinstance(method, ImageTransformHandler): + return method.transform(size, self, resample=resample, fill=fill) + + if hasattr(method, "getdata"): + # compatibility w. old-style transform objects + method, data = method.getdata() + + if data is None: + msg = "missing method data" + raise ValueError(msg) + + im = new(self.mode, size, fillcolor) + if self.mode == "P" and self.palette: + im.palette = self.palette.copy() + im.info = self.info.copy() + if method == Transform.MESH: + # list of quads + for box, quad in data: + im.__transformer( + box, self, Transform.QUAD, quad, resample, fillcolor is None + ) + else: + im.__transformer( + (0, 0) + size, self, method, data, resample, fillcolor is None + ) + + return im + + def __transformer( + self, box, image, method, data, resample=Resampling.NEAREST, fill=1 + ): + w = box[2] - box[0] + h = box[3] - box[1] + + if method == Transform.AFFINE: + data = data[:6] + + elif method == Transform.EXTENT: + # convert extent to an affine transform + x0, y0, x1, y1 = data + xs = (x1 - x0) / w + ys = (y1 - y0) / h + method = Transform.AFFINE + data = (xs, 0, x0, 0, ys, y0) + + elif method == Transform.PERSPECTIVE: + data = data[:8] + + elif method == Transform.QUAD: + # quadrilateral warp. data specifies the four corners + # given as NW, SW, SE, and NE. + nw = data[:2] + sw = data[2:4] + se = data[4:6] + ne = data[6:8] + x0, y0 = nw + As = 1.0 / w + At = 1.0 / h + data = ( + x0, + (ne[0] - x0) * As, + (sw[0] - x0) * At, + (se[0] - sw[0] - ne[0] + x0) * As * At, + y0, + (ne[1] - y0) * As, + (sw[1] - y0) * At, + (se[1] - sw[1] - ne[1] + y0) * As * At, + ) + + else: + msg = "unknown transformation method" + raise ValueError(msg) + + if resample not in ( + Resampling.NEAREST, + Resampling.BILINEAR, + Resampling.BICUBIC, + ): + if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS): + msg = { + Resampling.BOX: "Image.Resampling.BOX", + Resampling.HAMMING: "Image.Resampling.HAMMING", + Resampling.LANCZOS: "Image.Resampling.LANCZOS", + }[resample] + f" ({resample}) cannot be used." + else: + msg = f"Unknown resampling filter ({resample})." + + filters = [ + f"{filter[1]} ({filter[0]})" + for filter in ( + (Resampling.NEAREST, "Image.Resampling.NEAREST"), + (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), + (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), + ) + ] + msg += " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] + raise ValueError(msg) + + image.load() + + self.load() + + if image.mode in ("1", "P"): + resample = Resampling.NEAREST + + self.im.transform2(box, image.im, method, data, resample, fill) + + def transpose(self, method): + """ + Transpose image (flip or rotate in 90 degree steps) + + :param method: One of :py:data:`Transpose.FLIP_LEFT_RIGHT`, + :py:data:`Transpose.FLIP_TOP_BOTTOM`, :py:data:`Transpose.ROTATE_90`, + :py:data:`Transpose.ROTATE_180`, :py:data:`Transpose.ROTATE_270`, + :py:data:`Transpose.TRANSPOSE` or :py:data:`Transpose.TRANSVERSE`. + :returns: Returns a flipped or rotated copy of this image. + """ + + self.load() + return self._new(self.im.transpose(method)) + + def effect_spread(self, distance): + """ + Randomly spread pixels in an image. + + :param distance: Distance to spread pixels. + """ + self.load() + return self._new(self.im.effect_spread(distance)) + + def toqimage(self): + """Returns a QImage copy of this image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.toqimage(self) + + def toqpixmap(self): + """Returns a QPixmap copy of this image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.toqpixmap(self) + + +# -------------------------------------------------------------------- +# Abstract handlers. + + +class ImagePointHandler: + """ + Used as a mixin by point transforms + (for use with :py:meth:`~PIL.Image.Image.point`) + """ + + pass + + +class ImageTransformHandler: + """ + Used as a mixin by geometry transforms + (for use with :py:meth:`~PIL.Image.Image.transform`) + """ + + pass + + +# -------------------------------------------------------------------- +# Factories + +# +# Debugging + + +def _wedge(): + """Create grayscale wedge (for debugging only)""" + + return Image()._new(core.wedge("L")) + + +def _check_size(size): + """ + Common check to enforce type and sanity check on size tuples + + :param size: Should be a 2 tuple of (width, height) + :returns: True, or raises a ValueError + """ + + if not isinstance(size, (list, tuple)): + msg = "Size must be a tuple" + raise ValueError(msg) + if len(size) != 2: + msg = "Size must be a tuple of length 2" + raise ValueError(msg) + if size[0] < 0 or size[1] < 0: + msg = "Width and height must be >= 0" + raise ValueError(msg) + + return True + + +def new(mode, size, color=0) -> Image: + """ + Creates a new image with the given mode and size. + + :param mode: The mode to use for the new image. See: + :ref:`concept-modes`. + :param size: A 2-tuple, containing (width, height) in pixels. + :param color: What color to use for the image. Default is black. + If given, this should be a single integer or floating point value + for single-band modes, and a tuple for multi-band modes (one value + per band). When creating RGB or HSV images, you can also use color + strings as supported by the ImageColor module. If the color is + None, the image is not initialised. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + _check_size(size) + + if color is None: + # don't initialize + return Image()._new(core.new(mode, size)) + + if isinstance(color, str): + # css3-style specifier + + from . import ImageColor + + color = ImageColor.getcolor(color, mode) + + im = Image() + if mode == "P" and isinstance(color, (list, tuple)) and len(color) in [3, 4]: + # RGB or RGBA value for a P image + from . import ImagePalette + + im.palette = ImagePalette.ImagePalette() + color = im.palette.getcolor(color) + return im._new(core.fill(mode, size, color)) + + +def frombytes(mode, size, data, decoder_name="raw", *args) -> Image: + """ + Creates a copy of an image memory from pixel data in a buffer. + + In its simplest form, this function takes three arguments + (mode, size, and unpacked pixel data). + + You can also use any pixel decoder supported by PIL. For more + information on available decoders, see the section + :ref:`Writing Your Own File Codec `. + + Note that this function decodes pixel data only, not entire images. + If you have an entire image in a string, wrap it in a + :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load + it. + + :param mode: The image mode. See: :ref:`concept-modes`. + :param size: The image size. + :param data: A byte buffer containing raw data for the given mode. + :param decoder_name: What decoder to use. + :param args: Additional parameters for the given decoder. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + _check_size(size) + + im = new(mode, size) + if im.width != 0 and im.height != 0: + # may pass tuple instead of argument list + if len(args) == 1 and isinstance(args[0], tuple): + args = args[0] + + if decoder_name == "raw" and args == (): + args = mode + + im.frombytes(data, decoder_name, args) + return im + + +def frombuffer(mode, size, data, decoder_name="raw", *args): + """ + Creates an image memory referencing pixel data in a byte buffer. + + This function is similar to :py:func:`~PIL.Image.frombytes`, but uses data + in the byte buffer, where possible. This means that changes to the + original buffer object are reflected in this image). Not all modes can + share memory; supported modes include "L", "RGBX", "RGBA", and "CMYK". + + Note that this function decodes pixel data only, not entire images. + If you have an entire image file in a string, wrap it in a + :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it. + + In the current version, the default parameters used for the "raw" decoder + differs from that used for :py:func:`~PIL.Image.frombytes`. This is a + bug, and will probably be fixed in a future release. The current release + issues a warning if you do this; to disable the warning, you should provide + the full set of parameters. See below for details. + + :param mode: The image mode. See: :ref:`concept-modes`. + :param size: The image size. + :param data: A bytes or other buffer object containing raw + data for the given mode. + :param decoder_name: What decoder to use. + :param args: Additional parameters for the given decoder. For the + default encoder ("raw"), it's recommended that you provide the + full set of parameters:: + + frombuffer(mode, size, data, "raw", mode, 0, 1) + + :returns: An :py:class:`~PIL.Image.Image` object. + + .. versionadded:: 1.1.4 + """ + + _check_size(size) + + # may pass tuple instead of argument list + if len(args) == 1 and isinstance(args[0], tuple): + args = args[0] + + if decoder_name == "raw": + if args == (): + args = mode, 0, 1 + if args[0] in _MAPMODES: + im = new(mode, (0, 0)) + im = im._new(core.map_buffer(data, size, decoder_name, 0, args)) + if mode == "P": + from . import ImagePalette + + im.palette = ImagePalette.ImagePalette("RGB", im.im.getpalette("RGB")) + im.readonly = 1 + return im + + return frombytes(mode, size, data, decoder_name, args) + + +def fromarray(obj, mode=None): + """ + Creates an image memory from an object exporting the array interface + (using the buffer protocol):: + + from PIL import Image + import numpy as np + a = np.zeros((5, 5)) + im = Image.fromarray(a) + + If ``obj`` is not contiguous, then the ``tobytes`` method is called + and :py:func:`~PIL.Image.frombuffer` is used. + + In the case of NumPy, be aware that Pillow modes do not always correspond + to NumPy dtypes. Pillow modes only offer 1-bit pixels, 8-bit pixels, + 32-bit signed integer pixels, and 32-bit floating point pixels. + + Pillow images can also be converted to arrays:: + + from PIL import Image + import numpy as np + im = Image.open("hopper.jpg") + a = np.asarray(im) + + When converting Pillow images to arrays however, only pixel values are + transferred. This means that P and PA mode images will lose their palette. + + :param obj: Object with array interface + :param mode: Optional mode to use when reading ``obj``. Will be determined from + type if ``None``. + + This will not be used to convert the data after reading, but will be used to + change how the data is read:: + + from PIL import Image + import numpy as np + a = np.full((1, 1), 300) + im = Image.fromarray(a, mode="L") + im.getpixel((0, 0)) # 44 + im = Image.fromarray(a, mode="RGB") + im.getpixel((0, 0)) # (44, 1, 0) + + See: :ref:`concept-modes` for general information about modes. + :returns: An image object. + + .. versionadded:: 1.1.6 + """ + arr = obj.__array_interface__ + shape = arr["shape"] + ndim = len(shape) + strides = arr.get("strides", None) + if mode is None: + try: + typekey = (1, 1) + shape[2:], arr["typestr"] + except KeyError as e: + msg = "Cannot handle this data type" + raise TypeError(msg) from e + try: + mode, rawmode = _fromarray_typemap[typekey] + except KeyError as e: + typekey_shape, typestr = typekey + msg = f"Cannot handle this data type: {typekey_shape}, {typestr}" + raise TypeError(msg) from e + else: + rawmode = mode + if mode in ["1", "L", "I", "P", "F"]: + ndmax = 2 + elif mode == "RGB": + ndmax = 3 + else: + ndmax = 4 + if ndim > ndmax: + msg = f"Too many dimensions: {ndim} > {ndmax}." + raise ValueError(msg) + + size = 1 if ndim == 1 else shape[1], shape[0] + if strides is not None: + if hasattr(obj, "tobytes"): + obj = obj.tobytes() + else: + obj = obj.tostring() + + return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) + + +def fromqimage(im): + """Creates an image instance from a QImage image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.fromqimage(im) + + +def fromqpixmap(im): + """Creates an image instance from a QPixmap image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.fromqpixmap(im) + + +_fromarray_typemap = { + # (shape, typestr) => mode, rawmode + # first two members of shape are set to one + ((1, 1), "|b1"): ("1", "1;8"), + ((1, 1), "|u1"): ("L", "L"), + ((1, 1), "|i1"): ("I", "I;8"), + ((1, 1), "u2"): ("I", "I;16B"), + ((1, 1), "i2"): ("I", "I;16BS"), + ((1, 1), "u4"): ("I", "I;32B"), + ((1, 1), "i4"): ("I", "I;32BS"), + ((1, 1), "f4"): ("F", "F;32BF"), + ((1, 1), "f8"): ("F", "F;64BF"), + ((1, 1, 2), "|u1"): ("LA", "LA"), + ((1, 1, 3), "|u1"): ("RGB", "RGB"), + ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), + # shortcuts: + ((1, 1), _ENDIAN + "i4"): ("I", "I"), + ((1, 1), _ENDIAN + "f4"): ("F", "F"), +} + + +def _decompression_bomb_check(size): + if MAX_IMAGE_PIXELS is None: + return + + pixels = max(1, size[0]) * max(1, size[1]) + + if pixels > 2 * MAX_IMAGE_PIXELS: + msg = ( + f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} " + "pixels, could be decompression bomb DOS attack." + ) + raise DecompressionBombError(msg) + + if pixels > MAX_IMAGE_PIXELS: + warnings.warn( + f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, " + "could be decompression bomb DOS attack.", + DecompressionBombWarning, + ) + + +def open(fp, mode="r", formats=None) -> Image: + """ + Opens and identifies the given image file. + + This is a lazy operation; this function identifies the file, but + the file remains open and the actual image data is not read from + the file until you try to process the data (or call the + :py:meth:`~PIL.Image.Image.load` method). See + :py:func:`~PIL.Image.new`. See :ref:`file-handling`. + + :param fp: A filename (string), pathlib.Path object or a file object. + The file object must implement ``file.read``, + ``file.seek``, and ``file.tell`` methods, + and be opened in binary mode. The file object will also seek to zero + before reading. + :param mode: The mode. If given, this argument must be "r". + :param formats: A list or tuple of formats to attempt to load the file in. + This can be used to restrict the set of formats checked. + Pass ``None`` to try all supported formats. You can print the set of + available formats by running ``python3 -m PIL`` or using + the :py:func:`PIL.features.pilinfo` function. + :returns: An :py:class:`~PIL.Image.Image` object. + :exception FileNotFoundError: If the file cannot be found. + :exception PIL.UnidentifiedImageError: If the image cannot be opened and + identified. + :exception ValueError: If the ``mode`` is not "r", or if a ``StringIO`` + instance is used for ``fp``. + :exception TypeError: If ``formats`` is not ``None``, a list or a tuple. + """ + + if mode != "r": + msg = f"bad mode {repr(mode)}" + raise ValueError(msg) + elif isinstance(fp, io.StringIO): + msg = ( + "StringIO cannot be used to open an image. " + "Binary data must be used instead." + ) + raise ValueError(msg) + + if formats is None: + formats = ID + elif not isinstance(formats, (list, tuple)): + msg = "formats must be a list or tuple" + raise TypeError(msg) + + exclusive_fp = False + filename = "" + if isinstance(fp, Path): + filename = str(fp.resolve()) + elif is_path(fp): + filename = fp + + if filename: + fp = builtins.open(filename, "rb") + exclusive_fp = True + + try: + fp.seek(0) + except (AttributeError, io.UnsupportedOperation): + fp = io.BytesIO(fp.read()) + exclusive_fp = True + + prefix = fp.read(16) + + preinit() + + accept_warnings = [] + + def _open_core(fp, filename, prefix, formats): + for i in formats: + i = i.upper() + if i not in OPEN: + init() + try: + factory, accept = OPEN[i] + result = not accept or accept(prefix) + if type(result) in [str, bytes]: + accept_warnings.append(result) + elif result: + fp.seek(0) + im = factory(fp, filename) + _decompression_bomb_check(im.size) + return im + except (SyntaxError, IndexError, TypeError, struct.error): + # Leave disabled by default, spams the logs with image + # opening failures that are entirely expected. + # logger.debug("", exc_info=True) + continue + except BaseException: + if exclusive_fp: + fp.close() + raise + return None + + im = _open_core(fp, filename, prefix, formats) + + if im is None and formats is ID: + checked_formats = formats.copy() + if init(): + im = _open_core( + fp, + filename, + prefix, + tuple(format for format in formats if format not in checked_formats), + ) + + if im: + im._exclusive_fp = exclusive_fp + return im + + if exclusive_fp: + fp.close() + for message in accept_warnings: + warnings.warn(message) + msg = "cannot identify image file %r" % (filename if filename else fp) + raise UnidentifiedImageError(msg) + + +# +# Image processing. + + +def alpha_composite(im1, im2): + """ + Alpha composite im2 over im1. + + :param im1: The first image. Must have mode RGBA. + :param im2: The second image. Must have mode RGBA, and the same size as + the first image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + im1.load() + im2.load() + return im1._new(core.alpha_composite(im1.im, im2.im)) + + +def blend(im1, im2, alpha): + """ + Creates a new image by interpolating between two input images, using + a constant alpha:: + + out = image1 * (1.0 - alpha) + image2 * alpha + + :param im1: The first image. + :param im2: The second image. Must have the same mode and size as + the first image. + :param alpha: The interpolation alpha factor. If alpha is 0.0, a + copy of the first image is returned. If alpha is 1.0, a copy of + the second image is returned. There are no restrictions on the + alpha value. If necessary, the result is clipped to fit into + the allowed output range. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + im1.load() + im2.load() + return im1._new(core.blend(im1.im, im2.im, alpha)) + + +def composite(image1, image2, mask): + """ + Create composite image by blending images using a transparency mask. + + :param image1: The first image. + :param image2: The second image. Must have the same mode and + size as the first image. + :param mask: A mask image. This image can have mode + "1", "L", or "RGBA", and must have the same size as the + other two images. + """ + + image = image2.copy() + image.paste(image1, None, mask) + return image + + +def eval(image, *args): + """ + Applies the function (which should take one argument) to each pixel + in the given image. If the image has more than one band, the same + function is applied to each band. Note that the function is + evaluated once for each possible pixel value, so you cannot use + random components or other generators. + + :param image: The input image. + :param function: A function object, taking one integer argument. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + return image.point(args[0]) + + +def merge(mode, bands): + """ + Merge a set of single band images into a new multiband image. + + :param mode: The mode to use for the output image. See: + :ref:`concept-modes`. + :param bands: A sequence containing one single-band image for + each band in the output image. All bands must have the + same size. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if getmodebands(mode) != len(bands) or "*" in mode: + msg = "wrong number of bands" + raise ValueError(msg) + for band in bands[1:]: + if band.mode != getmodetype(mode): + msg = "mode mismatch" + raise ValueError(msg) + if band.size != bands[0].size: + msg = "size mismatch" + raise ValueError(msg) + for band in bands: + band.load() + return bands[0]._new(core.merge(mode, *[b.im for b in bands])) + + +# -------------------------------------------------------------------- +# Plugin registry + + +def register_open(id, factory, accept=None) -> None: + """ + Register an image file plugin. This function should not be used + in application code. + + :param id: An image format identifier. + :param factory: An image file factory method. + :param accept: An optional function that can be used to quickly + reject images having another format. + """ + id = id.upper() + if id not in ID: + ID.append(id) + OPEN[id] = factory, accept + + +def register_mime(id, mimetype): + """ + Registers an image MIME type by populating ``Image.MIME``. This function + should not be used in application code. + + ``Image.MIME`` provides a mapping from image format identifiers to mime + formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can + provide a different result for specific images. + + :param id: An image format identifier. + :param mimetype: The image MIME type for this format. + """ + MIME[id.upper()] = mimetype + + +def register_save(id, driver): + """ + Registers an image save function. This function should not be + used in application code. + + :param id: An image format identifier. + :param driver: A function to save images in this format. + """ + SAVE[id.upper()] = driver + + +def register_save_all(id, driver): + """ + Registers an image function to save all the frames + of a multiframe format. This function should not be + used in application code. + + :param id: An image format identifier. + :param driver: A function to save images in this format. + """ + SAVE_ALL[id.upper()] = driver + + +def register_extension(id, extension) -> None: + """ + Registers an image extension. This function should not be + used in application code. + + :param id: An image format identifier. + :param extension: An extension used for this format. + """ + EXTENSION[extension.lower()] = id.upper() + + +def register_extensions(id, extensions): + """ + Registers image extensions. This function should not be + used in application code. + + :param id: An image format identifier. + :param extensions: A list of extensions used for this format. + """ + for extension in extensions: + register_extension(id, extension) + + +def registered_extensions(): + """ + Returns a dictionary containing all file extensions belonging + to registered plugins + """ + init() + return EXTENSION + + +def register_decoder(name, decoder): + """ + Registers an image decoder. This function should not be + used in application code. + + :param name: The name of the decoder + :param decoder: A callable(mode, args) that returns an + ImageFile.PyDecoder object + + .. versionadded:: 4.1.0 + """ + DECODERS[name] = decoder + + +def register_encoder(name, encoder): + """ + Registers an image encoder. This function should not be + used in application code. + + :param name: The name of the encoder + :param encoder: A callable(mode, args) that returns an + ImageFile.PyEncoder object + + .. versionadded:: 4.1.0 + """ + ENCODERS[name] = encoder + + +# -------------------------------------------------------------------- +# Simple display support. + + +def _show(image, **options): + from . import ImageShow + + ImageShow.show(image, **options) + + +# -------------------------------------------------------------------- +# Effects + + +def effect_mandelbrot(size, extent, quality): + """ + Generate a Mandelbrot set covering the given extent. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param extent: The extent to cover, as a 4-tuple: + (x0, y0, x1, y1). + :param quality: Quality. + """ + return Image()._new(core.effect_mandelbrot(size, extent, quality)) + + +def effect_noise(size, sigma): + """ + Generate Gaussian noise centered around 128. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param sigma: Standard deviation of noise. + """ + return Image()._new(core.effect_noise(size, sigma)) + + +def linear_gradient(mode): + """ + Generate 256x256 linear gradient from black to white, top to bottom. + + :param mode: Input mode. + """ + return Image()._new(core.linear_gradient(mode)) + + +def radial_gradient(mode): + """ + Generate 256x256 radial gradient from black to white, centre to edge. + + :param mode: Input mode. + """ + return Image()._new(core.radial_gradient(mode)) + + +# -------------------------------------------------------------------- +# Resources + + +def _apply_env_variables(env=None): + if env is None: + env = os.environ + + for var_name, setter in [ + ("PILLOW_ALIGNMENT", core.set_alignment), + ("PILLOW_BLOCK_SIZE", core.set_block_size), + ("PILLOW_BLOCKS_MAX", core.set_blocks_max), + ]: + if var_name not in env: + continue + + var = env[var_name].lower() + + units = 1 + for postfix, mul in [("k", 1024), ("m", 1024 * 1024)]: + if var.endswith(postfix): + units = mul + var = var[: -len(postfix)] + + try: + var = int(var) * units + except ValueError: + warnings.warn(f"{var_name} is not int") + continue + + try: + setter(var) + except ValueError as e: + warnings.warn(f"{var_name}: {e}") + + +_apply_env_variables() +atexit.register(core.clear_cache) + + +class Exif(MutableMapping): + """ + This class provides read and write access to EXIF image data:: + + from PIL import Image + im = Image.open("exif.png") + exif = im.getexif() # Returns an instance of this class + + Information can be read and written, iterated over or deleted:: + + print(exif[274]) # 1 + exif[274] = 2 + for k, v in exif.items(): + print("Tag", k, "Value", v) # Tag 274 Value 2 + del exif[274] + + To access information beyond IFD0, :py:meth:`~PIL.Image.Exif.get_ifd` + returns a dictionary:: + + from PIL import ExifTags + im = Image.open("exif_gps.jpg") + exif = im.getexif() + gps_ifd = exif.get_ifd(ExifTags.IFD.GPSInfo) + print(gps_ifd) + + Other IFDs include ``ExifTags.IFD.Exif``, ``ExifTags.IFD.Makernote``, + ``ExifTags.IFD.Interop`` and ``ExifTags.IFD.IFD1``. + + :py:mod:`~PIL.ExifTags` also has enum classes to provide names for data:: + + print(exif[ExifTags.Base.Software]) # PIL + print(gps_ifd[ExifTags.GPS.GPSDateStamp]) # 1999:99:99 99:99:99 + """ + + endian = None + bigtiff = False + + def __init__(self): + self._data = {} + self._hidden_data = {} + self._ifds = {} + self._info = None + self._loaded_exif = None + + def _fixup(self, value): + try: + if len(value) == 1 and isinstance(value, tuple): + return value[0] + except Exception: + pass + return value + + def _fixup_dict(self, src_dict): + # Helper function + # returns a dict with any single item tuples/lists as individual values + return {k: self._fixup(v) for k, v in src_dict.items()} + + def _get_ifd_dict(self, offset): + try: + # an offset pointer to the location of the nested embedded IFD. + # It should be a long, but may be corrupted. + self.fp.seek(offset) + except (KeyError, TypeError): + pass + else: + from . import TiffImagePlugin + + info = TiffImagePlugin.ImageFileDirectory_v2(self.head) + info.load(self.fp) + return self._fixup_dict(info) + + def _get_head(self): + version = b"\x2B" if self.bigtiff else b"\x2A" + if self.endian == "<": + head = b"II" + version + b"\x00" + o32le(8) + else: + head = b"MM\x00" + version + o32be(8) + if self.bigtiff: + head += o32le(8) if self.endian == "<" else o32be(8) + head += b"\x00\x00\x00\x00" + return head + + def load(self, data): + # Extract EXIF information. This is highly experimental, + # and is likely to be replaced with something better in a future + # version. + + # The EXIF record consists of a TIFF file embedded in a JPEG + # application marker (!). + if data == self._loaded_exif: + return + self._loaded_exif = data + self._data.clear() + self._hidden_data.clear() + self._ifds.clear() + if data and data.startswith(b"Exif\x00\x00"): + data = data[6:] + if not data: + self._info = None + return + + self.fp = io.BytesIO(data) + self.head = self.fp.read(8) + # process dictionary + from . import TiffImagePlugin + + self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) + self.endian = self._info._endian + self.fp.seek(self._info.next) + self._info.load(self.fp) + + def load_from_fp(self, fp, offset=None): + self._loaded_exif = None + self._data.clear() + self._hidden_data.clear() + self._ifds.clear() + + # process dictionary + from . import TiffImagePlugin + + self.fp = fp + if offset is not None: + self.head = self._get_head() + else: + self.head = self.fp.read(8) + self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) + if self.endian is None: + self.endian = self._info._endian + if offset is None: + offset = self._info.next + self.fp.tell() + self.fp.seek(offset) + self._info.load(self.fp) + + def _get_merged_dict(self): + merged_dict = dict(self) + + # get EXIF extension + if ExifTags.IFD.Exif in self: + ifd = self._get_ifd_dict(self[ExifTags.IFD.Exif]) + if ifd: + merged_dict.update(ifd) + + # GPS + if ExifTags.IFD.GPSInfo in self: + merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict( + self[ExifTags.IFD.GPSInfo] + ) + + return merged_dict + + def tobytes(self, offset=8): + from . import TiffImagePlugin + + head = self._get_head() + ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) + for tag, value in self.items(): + if tag in [ + ExifTags.IFD.Exif, + ExifTags.IFD.GPSInfo, + ] and not isinstance(value, dict): + value = self.get_ifd(tag) + if ( + tag == ExifTags.IFD.Exif + and ExifTags.IFD.Interop in value + and not isinstance(value[ExifTags.IFD.Interop], dict) + ): + value = value.copy() + value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop) + ifd[tag] = value + return b"Exif\x00\x00" + head + ifd.tobytes(offset) + + def get_ifd(self, tag): + if tag not in self._ifds: + if tag == ExifTags.IFD.IFD1: + if self._info is not None and self._info.next != 0: + self._ifds[tag] = self._get_ifd_dict(self._info.next) + elif tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]: + offset = self._hidden_data.get(tag, self.get(tag)) + if offset is not None: + self._ifds[tag] = self._get_ifd_dict(offset) + elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.Makernote]: + if ExifTags.IFD.Exif not in self._ifds: + self.get_ifd(ExifTags.IFD.Exif) + tag_data = self._ifds[ExifTags.IFD.Exif][tag] + if tag == ExifTags.IFD.Makernote: + from .TiffImagePlugin import ImageFileDirectory_v2 + + if tag_data[:8] == b"FUJIFILM": + ifd_offset = i32le(tag_data, 8) + ifd_data = tag_data[ifd_offset:] + + makernote = {} + for i in range(0, struct.unpack(" 4: + (offset,) = struct.unpack("H", tag_data[:2])[0]): + ifd_tag, typ, count, data = struct.unpack( + ">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2] + ) + if ifd_tag == 0x1101: + # CameraInfo + (offset,) = struct.unpack(">L", data) + self.fp.seek(offset) + + camerainfo = {"ModelID": self.fp.read(4)} + + self.fp.read(4) + # Seconds since 2000 + camerainfo["TimeStamp"] = i32le(self.fp.read(12)) + + self.fp.read(4) + camerainfo["InternalSerialNumber"] = self.fp.read(4) + + self.fp.read(12) + parallax = self.fp.read(4) + handler = ImageFileDirectory_v2._load_dispatch[ + TiffTags.FLOAT + ][1] + camerainfo["Parallax"] = handler( + ImageFileDirectory_v2(), parallax, False + ) + + self.fp.read(4) + camerainfo["Category"] = self.fp.read(2) + + makernote = {0x1101: dict(self._fixup_dict(camerainfo))} + self._ifds[tag] = makernote + else: + # Interop + self._ifds[tag] = self._get_ifd_dict(tag_data) + ifd = self._ifds.get(tag, {}) + if tag == ExifTags.IFD.Exif and self._hidden_data: + ifd = { + k: v + for (k, v) in ifd.items() + if k not in (ExifTags.IFD.Interop, ExifTags.IFD.Makernote) + } + return ifd + + def hide_offsets(self): + for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo): + if tag in self: + self._hidden_data[tag] = self[tag] + del self[tag] + + def __str__(self): + if self._info is not None: + # Load all keys into self._data + for tag in self._info: + self[tag] + + return str(self._data) + + def __len__(self): + keys = set(self._data) + if self._info is not None: + keys.update(self._info) + return len(keys) + + def __getitem__(self, tag): + if self._info is not None and tag not in self._data and tag in self._info: + self._data[tag] = self._fixup(self._info[tag]) + del self._info[tag] + return self._data[tag] + + def __contains__(self, tag): + return tag in self._data or (self._info is not None and tag in self._info) + + def __setitem__(self, tag, value): + if self._info is not None and tag in self._info: + del self._info[tag] + self._data[tag] = value + + def __delitem__(self, tag): + if self._info is not None and tag in self._info: + del self._info[tag] + else: + del self._data[tag] + + def __iter__(self): + keys = set(self._data) + if self._info is not None: + keys.update(self._info) + return iter(keys) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageChops.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageChops.py new file mode 100644 index 00000000..29a5c995 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageChops.py @@ -0,0 +1,311 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard channel operations +# +# History: +# 1996-03-24 fl Created +# 1996-08-13 fl Added logical operations (for "1" images) +# 2000-10-12 fl Added offset method (from Image.py) +# +# Copyright (c) 1997-2000 by Secret Labs AB +# Copyright (c) 1996-2000 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +from . import Image + + +def constant(image: Image.Image, value: int) -> Image.Image: + """Fill a channel with a given gray level. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.new("L", image.size, value) + + +def duplicate(image: Image.Image) -> Image.Image: + """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return image.copy() + + +def invert(image: Image.Image) -> Image.Image: + """ + Invert an image (channel). :: + + out = MAX - image + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image.load() + return image._new(image.im.chop_invert()) + + +def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Compares the two images, pixel by pixel, and returns a new image containing + the lighter values. :: + + out = max(image1, image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_lighter(image2.im)) + + +def darker(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Compares the two images, pixel by pixel, and returns a new image containing + the darker values. :: + + out = min(image1, image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_darker(image2.im)) + + +def difference(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Returns the absolute value of the pixel-by-pixel difference between the two + images. :: + + out = abs(image1 - image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_difference(image2.im)) + + +def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other. + + If you multiply an image with a solid black image, the result is black. If + you multiply with a solid white image, the image is unaffected. :: + + out = image1 * image2 / MAX + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_multiply(image2.im)) + + +def screen(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two inverted images on top of each other. :: + + out = MAX - ((MAX - image1) * (MAX - image2) / MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_screen(image2.im)) + + +def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Soft Light algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_soft_light(image2.im)) + + +def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Hard Light algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_hard_light(image2.im)) + + +def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Overlay algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_overlay(image2.im)) + + +def add( + image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 +) -> Image.Image: + """ + Adds two images, dividing the result by scale and adding the + offset. If omitted, scale defaults to 1.0, and offset to 0.0. :: + + out = ((image1 + image2) / scale + offset) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_add(image2.im, scale, offset)) + + +def subtract( + image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 +) -> Image.Image: + """ + Subtracts two images, dividing the result by scale and adding the offset. + If omitted, scale defaults to 1.0, and offset to 0.0. :: + + out = ((image1 - image2) / scale + offset) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) + + +def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Add two images, without clipping the result. :: + + out = ((image1 + image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_add_modulo(image2.im)) + + +def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Subtract two images, without clipping the result. :: + + out = ((image1 - image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract_modulo(image2.im)) + + +def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical AND between two images. + + Both of the images must have mode "1". If you would like to perform a + logical AND on an image with a mode other than "1", try + :py:meth:`~PIL.ImageChops.multiply` instead, using a black-and-white mask + as the second image. :: + + out = ((image1 and image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_and(image2.im)) + + +def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical OR between two images. + + Both of the images must have mode "1". :: + + out = ((image1 or image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_or(image2.im)) + + +def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical XOR between two images. + + Both of the images must have mode "1". :: + + out = ((bool(image1) != bool(image2)) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_xor(image2.im)) + + +def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image: + """Blend images using constant transparency weight. Alias for + :py:func:`PIL.Image.blend`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.blend(image1, image2, alpha) + + +def composite( + image1: Image.Image, image2: Image.Image, mask: Image.Image +) -> Image.Image: + """Create composite using transparency mask. Alias for + :py:func:`PIL.Image.composite`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.composite(image1, image2, mask) + + +def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image: + """Returns a copy of the image where data has been offset by the given + distances. Data wraps around the edges. If ``yoffset`` is omitted, it + is assumed to be equal to ``xoffset``. + + :param image: Input image. + :param xoffset: The horizontal distance. + :param yoffset: The vertical distance. If omitted, both + distances are set to the same value. + :rtype: :py:class:`~PIL.Image.Image` + """ + + if yoffset is None: + yoffset = xoffset + image.load() + return image._new(image.im.offset(xoffset, yoffset)) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageCms.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageCms.py new file mode 100644 index 00000000..643fce83 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageCms.py @@ -0,0 +1,1007 @@ +# The Python Imaging Library. +# $Id$ + +# Optional color management support, based on Kevin Cazabon's PyCMS +# library. + +# History: + +# 2009-03-08 fl Added to PIL. + +# Copyright (C) 2002-2003 Kevin Cazabon +# Copyright (c) 2009 by Fredrik Lundh +# Copyright (c) 2013 by Eric Soroos + +# See the README file for information on usage and redistribution. See +# below for the original description. +from __future__ import annotations + +import sys +from enum import IntEnum + +from . import Image + +try: + from . import _imagingcms +except ImportError as ex: + # Allow error import for doc purposes, but error out when accessing + # anything in core. + from ._util import DeferredError + + _imagingcms = DeferredError.new(ex) + +DESCRIPTION = """ +pyCMS + + a Python / PIL interface to the littleCMS ICC Color Management System + Copyright (C) 2002-2003 Kevin Cazabon + kevin@cazabon.com + https://www.cazabon.com + + pyCMS home page: https://www.cazabon.com/pyCMS + littleCMS home page: https://www.littlecms.com + (littleCMS is Copyright (C) 1998-2001 Marti Maria) + + Originally released under LGPL. Graciously donated to PIL in + March 2009, for distribution under the standard PIL license + + The pyCMS.py module provides a "clean" interface between Python/PIL and + pyCMSdll, taking care of some of the more complex handling of the direct + pyCMSdll functions, as well as error-checking and making sure that all + relevant data is kept together. + + While it is possible to call pyCMSdll functions directly, it's not highly + recommended. + + Version History: + + 1.0.0 pil Oct 2013 Port to LCMS 2. + + 0.1.0 pil mod March 10, 2009 + + Renamed display profile to proof profile. The proof + profile is the profile of the device that is being + simulated, not the profile of the device which is + actually used to display/print the final simulation + (that'd be the output profile) - also see LCMSAPI.txt + input colorspace -> using 'renderingIntent' -> proof + colorspace -> using 'proofRenderingIntent' -> output + colorspace + + Added LCMS FLAGS support. + Added FLAGS["SOFTPROOFING"] as default flag for + buildProofTransform (otherwise the proof profile/intent + would be ignored). + + 0.1.0 pil March 2009 - added to PIL, as PIL.ImageCms + + 0.0.2 alpha Jan 6, 2002 + + Added try/except statements around type() checks of + potential CObjects... Python won't let you use type() + on them, and raises a TypeError (stupid, if you ask + me!) + + Added buildProofTransformFromOpenProfiles() function. + Additional fixes in DLL, see DLL code for details. + + 0.0.1 alpha first public release, Dec. 26, 2002 + + Known to-do list with current version (of Python interface, not pyCMSdll): + + none + +""" + +VERSION = "1.0.0 pil" + +# --------------------------------------------------------------------. + +core = _imagingcms + +# +# intent/direction values + + +class Intent(IntEnum): + PERCEPTUAL = 0 + RELATIVE_COLORIMETRIC = 1 + SATURATION = 2 + ABSOLUTE_COLORIMETRIC = 3 + + +class Direction(IntEnum): + INPUT = 0 + OUTPUT = 1 + PROOF = 2 + + +# +# flags + +FLAGS = { + "MATRIXINPUT": 1, + "MATRIXOUTPUT": 2, + "MATRIXONLY": (1 | 2), + "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot + # Don't create prelinearization tables on precalculated transforms + # (internal use): + "NOPRELINEARIZATION": 16, + "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink) + "NOTCACHE": 64, # Inhibit 1-pixel cache + "NOTPRECALC": 256, + "NULLTRANSFORM": 512, # Don't transform anyway + "HIGHRESPRECALC": 1024, # Use more memory to give better accuracy + "LOWRESPRECALC": 2048, # Use less memory to minimize resources + "WHITEBLACKCOMPENSATION": 8192, + "BLACKPOINTCOMPENSATION": 8192, + "GAMUTCHECK": 4096, # Out of Gamut alarm + "SOFTPROOFING": 16384, # Do softproofing + "PRESERVEBLACK": 32768, # Black preservation + "NODEFAULTRESOURCEDEF": 16777216, # CRD special + "GRIDPOINTS": lambda n: (n & 0xFF) << 16, # Gridpoints +} + +_MAX_FLAG = 0 +for flag in FLAGS.values(): + if isinstance(flag, int): + _MAX_FLAG = _MAX_FLAG | flag + + +# --------------------------------------------------------------------. +# Experimental PIL-level API +# --------------------------------------------------------------------. + +## +# Profile. + + +class ImageCmsProfile: + def __init__(self, profile): + """ + :param profile: Either a string representing a filename, + a file like object containing a profile or a + low-level profile object + + """ + + if isinstance(profile, str): + if sys.platform == "win32": + profile_bytes_path = profile.encode() + try: + profile_bytes_path.decode("ascii") + except UnicodeDecodeError: + with open(profile, "rb") as f: + self._set(core.profile_frombytes(f.read())) + return + self._set(core.profile_open(profile), profile) + elif hasattr(profile, "read"): + self._set(core.profile_frombytes(profile.read())) + elif isinstance(profile, _imagingcms.CmsProfile): + self._set(profile) + else: + msg = "Invalid type for Profile" + raise TypeError(msg) + + def _set(self, profile, filename=None): + self.profile = profile + self.filename = filename + self.product_name = None # profile.product_name + self.product_info = None # profile.product_info + + def tobytes(self): + """ + Returns the profile in a format suitable for embedding in + saved images. + + :returns: a bytes object containing the ICC profile. + """ + + return core.profile_tobytes(self.profile) + + +class ImageCmsTransform(Image.ImagePointHandler): + + """ + Transform. This can be used with the procedural API, or with the standard + :py:func:`~PIL.Image.Image.point` method. + + Will return the output profile in the ``output.info['icc_profile']``. + """ + + def __init__( + self, + input, + output, + input_mode, + output_mode, + intent=Intent.PERCEPTUAL, + proof=None, + proof_intent=Intent.ABSOLUTE_COLORIMETRIC, + flags=0, + ): + if proof is None: + self.transform = core.buildTransform( + input.profile, output.profile, input_mode, output_mode, intent, flags + ) + else: + self.transform = core.buildProofTransform( + input.profile, + output.profile, + proof.profile, + input_mode, + output_mode, + intent, + proof_intent, + flags, + ) + # Note: inputMode and outputMode are for pyCMS compatibility only + self.input_mode = self.inputMode = input_mode + self.output_mode = self.outputMode = output_mode + + self.output_profile = output + + def point(self, im): + return self.apply(im) + + def apply(self, im, imOut=None): + im.load() + if imOut is None: + imOut = Image.new(self.output_mode, im.size, None) + self.transform.apply(im.im.id, imOut.im.id) + imOut.info["icc_profile"] = self.output_profile.tobytes() + return imOut + + def apply_in_place(self, im): + im.load() + if im.mode != self.output_mode: + msg = "mode mismatch" + raise ValueError(msg) # wrong output mode + self.transform.apply(im.im.id, im.im.id) + im.info["icc_profile"] = self.output_profile.tobytes() + return im + + +def get_display_profile(handle=None): + """ + (experimental) Fetches the profile for the current display device. + + :returns: ``None`` if the profile is not known. + """ + + if sys.platform != "win32": + return None + + from . import ImageWin + + if isinstance(handle, ImageWin.HDC): + profile = core.get_display_profile_win32(handle, 1) + else: + profile = core.get_display_profile_win32(handle or 0) + if profile is None: + return None + return ImageCmsProfile(profile) + + +# --------------------------------------------------------------------. +# pyCMS compatible layer +# --------------------------------------------------------------------. + + +class PyCMSError(Exception): + + """(pyCMS) Exception class. + This is used for all errors in the pyCMS API.""" + + pass + + +def profileToProfile( + im, + inputProfile, + outputProfile, + renderingIntent=Intent.PERCEPTUAL, + outputMode=None, + inPlace=False, + flags=0, +): + """ + (pyCMS) Applies an ICC transformation to a given image, mapping from + ``inputProfile`` to ``outputProfile``. + + If the input or output profiles specified are not valid filenames, a + :exc:`PyCMSError` will be raised. If ``inPlace`` is ``True`` and + ``outputMode != im.mode``, a :exc:`PyCMSError` will be raised. + If an error occurs during application of the profiles, + a :exc:`PyCMSError` will be raised. + If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS), + a :exc:`PyCMSError` will be raised. + + This function applies an ICC transformation to im from ``inputProfile``'s + color space to ``outputProfile``'s color space using the specified rendering + intent to decide how to handle out-of-gamut colors. + + ``outputMode`` can be used to specify that a color mode conversion is to + be done using these profiles, but the specified profiles must be able + to handle that mode. I.e., if converting im from RGB to CMYK using + profiles, the input profile must handle RGB data, and the output + profile must handle CMYK data. + + :param im: An open :py:class:`~PIL.Image.Image` object (i.e. Image.new(...) + or Image.open(...), etc.) + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this image, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + profile you wish to use for this image, or a profile object + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param outputMode: A valid PIL mode for the output image (i.e. "RGB", + "CMYK", etc.). Note: if rendering the image "inPlace", outputMode + MUST be the same mode as the input, or omitted completely. If + omitted, the outputMode will be the same as the mode of the input + image (im.mode) + :param inPlace: Boolean. If ``True``, the original image is modified in-place, + and ``None`` is returned. If ``False`` (default), a new + :py:class:`~PIL.Image.Image` object is returned with the transform applied. + :param flags: Integer (0-...) specifying additional flags + :returns: Either None or a new :py:class:`~PIL.Image.Image` object, depending on + the value of ``inPlace`` + :exception PyCMSError: + """ + + if outputMode is None: + outputMode = im.mode + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = f"flags must be an integer between 0 and {_MAX_FLAG}" + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + transform = ImageCmsTransform( + inputProfile, + outputProfile, + im.mode, + outputMode, + renderingIntent, + flags=flags, + ) + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + return imOut + + +def getOpenProfile(profileFilename): + """ + (pyCMS) Opens an ICC profile file. + + The PyCMSProfile object can be passed back into pyCMS for use in creating + transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). + + If ``profileFilename`` is not a valid filename for an ICC profile, + a :exc:`PyCMSError` will be raised. + + :param profileFilename: String, as a valid filename path to the ICC profile + you wish to open, or a file-like object. + :returns: A CmsProfile class object. + :exception PyCMSError: + """ + + try: + return ImageCmsProfile(profileFilename) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def buildTransform( + inputProfile, + outputProfile, + inMode, + outMode, + renderingIntent=Intent.PERCEPTUAL, + flags=0, +): + """ + (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the + ``outputProfile``. Use applyTransform to apply the transform to a given + image. + + If the input or output profiles specified are not valid filenames, a + :exc:`PyCMSError` will be raised. If an error occurs during creation + of the transform, a :exc:`PyCMSError` will be raised. + + If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` + (or by pyCMS), a :exc:`PyCMSError` will be raised. + + This function builds and returns an ICC transform from the ``inputProfile`` + to the ``outputProfile`` using the ``renderingIntent`` to determine what to do + with out-of-gamut colors. It will ONLY work for converting images that + are in ``inMode`` to images that are in ``outMode`` color format (PIL mode, + i.e. "RGB", "RGBA", "CMYK", etc.). + + Building the transform is a fair part of the overhead in + ImageCms.profileToProfile(), so if you're planning on converting multiple + images using the same input/output settings, this can save you time. + Once you have a transform object, it can be used with + ImageCms.applyProfile() to convert images without the need to re-compute + the lookup table for the transform. + + The reason pyCMS returns a class object rather than a handle directly + to the transform is that it needs to keep track of the PIL input/output + modes that the transform is meant for. These attributes are stored in + the ``inMode`` and ``outMode`` attributes of the object (which can be + manually overridden if you really want to, but I don't know of any + time that would be of use, or would even work). + + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + profile you wish to use for this transform, or a profile object + :param inMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param outMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param flags: Integer (0-...) specifying additional flags + :returns: A CmsTransform class object. + :exception PyCMSError: + """ + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = "flags must be an integer between 0 and %s" + _MAX_FLAG + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + return ImageCmsTransform( + inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags + ) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def buildProofTransform( + inputProfile, + outputProfile, + proofProfile, + inMode, + outMode, + renderingIntent=Intent.PERCEPTUAL, + proofRenderingIntent=Intent.ABSOLUTE_COLORIMETRIC, + flags=FLAGS["SOFTPROOFING"], +): + """ + (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the + ``outputProfile``, but tries to simulate the result that would be + obtained on the ``proofProfile`` device. + + If the input, output, or proof profiles specified are not valid + filenames, a :exc:`PyCMSError` will be raised. + + If an error occurs during creation of the transform, + a :exc:`PyCMSError` will be raised. + + If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` + (or by pyCMS), a :exc:`PyCMSError` will be raised. + + This function builds and returns an ICC transform from the ``inputProfile`` + to the ``outputProfile``, but tries to simulate the result that would be + obtained on the ``proofProfile`` device using ``renderingIntent`` and + ``proofRenderingIntent`` to determine what to do with out-of-gamut + colors. This is known as "soft-proofing". It will ONLY work for + converting images that are in ``inMode`` to images that are in outMode + color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.). + + Usage of the resulting transform object is exactly the same as with + ImageCms.buildTransform(). + + Proof profiling is generally used when using an output device to get a + good idea of what the final printed/displayed image would look like on + the ``proofProfile`` device when it's quicker and easier to use the + output device for judging color. Generally, this means that the + output device is a monitor, or a dye-sub printer (etc.), and the simulated + device is something more expensive, complicated, or time consuming + (making it difficult to make a real print for color judgement purposes). + + Soft-proofing basically functions by adjusting the colors on the + output device to match the colors of the device being simulated. However, + when the simulated device has a much wider gamut than the output + device, you may obtain marginal results. + + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + (monitor, usually) profile you wish to use for this transform, or a + profile object + :param proofProfile: String, as a valid filename path to the ICC proof + profile you wish to use for this transform, or a profile object + :param inMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param outMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the input->proof (simulated) transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param proofRenderingIntent: Integer (0-3) specifying the rendering intent + you wish to use for proof->output transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param flags: Integer (0-...) specifying additional flags + :returns: A CmsTransform class object. + :exception PyCMSError: + """ + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = "flags must be an integer between 0 and %s" + _MAX_FLAG + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + if not isinstance(proofProfile, ImageCmsProfile): + proofProfile = ImageCmsProfile(proofProfile) + return ImageCmsTransform( + inputProfile, + outputProfile, + inMode, + outMode, + renderingIntent, + proofProfile, + proofRenderingIntent, + flags, + ) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +buildTransformFromOpenProfiles = buildTransform +buildProofTransformFromOpenProfiles = buildProofTransform + + +def applyTransform(im, transform, inPlace=False): + """ + (pyCMS) Applies a transform to a given image. + + If ``im.mode != transform.inMode``, a :exc:`PyCMSError` is raised. + + If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a + :exc:`PyCMSError` is raised. + + If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not + supported by pyCMSdll or the profiles you used for the transform, a + :exc:`PyCMSError` is raised. + + If an error occurs while the transform is being applied, + a :exc:`PyCMSError` is raised. + + This function applies a pre-calculated transform (from + ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) + to an image. The transform can be used for multiple images, saving + considerable calculation time if doing the same conversion multiple times. + + If you want to modify im in-place instead of receiving a new image as + the return value, set ``inPlace`` to ``True``. This can only be done if + ``transform.inMode`` and ``transform.outMode`` are the same, because we can't + change the mode in-place (the buffer sizes for some modes are + different). The default behavior is to return a new :py:class:`~PIL.Image.Image` + object of the same dimensions in mode ``transform.outMode``. + + :param im: An :py:class:`~PIL.Image.Image` object, and im.mode must be the same + as the ``inMode`` supported by the transform. + :param transform: A valid CmsTransform class object + :param inPlace: Bool. If ``True``, ``im`` is modified in place and ``None`` is + returned, if ``False``, a new :py:class:`~PIL.Image.Image` object with the + transform applied is returned (and ``im`` is not changed). The default is + ``False``. + :returns: Either ``None``, or a new :py:class:`~PIL.Image.Image` object, + depending on the value of ``inPlace``. The profile will be returned in + the image's ``info['icc_profile']``. + :exception PyCMSError: + """ + + try: + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (TypeError, ValueError) as v: + raise PyCMSError(v) from v + + return imOut + + +def createProfile(colorSpace, colorTemp=-1): + """ + (pyCMS) Creates a profile. + + If colorSpace not in ``["LAB", "XYZ", "sRGB"]``, + a :exc:`PyCMSError` is raised. + + If using LAB and ``colorTemp`` is not a positive integer, + a :exc:`PyCMSError` is raised. + + If an error occurs while creating the profile, + a :exc:`PyCMSError` is raised. + + Use this function to create common profiles on-the-fly instead of + having to supply a profile on disk and knowing the path to it. It + returns a normal CmsProfile object that can be passed to + ImageCms.buildTransformFromOpenProfiles() to create a transform to apply + to images. + + :param colorSpace: String, the color space of the profile you wish to + create. + Currently only "LAB", "XYZ", and "sRGB" are supported. + :param colorTemp: Positive integer for the white point for the profile, in + degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for D50 + illuminant if omitted (5000k). colorTemp is ONLY applied to LAB + profiles, and is ignored for XYZ and sRGB. + :returns: A CmsProfile class object + :exception PyCMSError: + """ + + if colorSpace not in ["LAB", "XYZ", "sRGB"]: + msg = ( + f"Color space not supported for on-the-fly profile creation ({colorSpace})" + ) + raise PyCMSError(msg) + + if colorSpace == "LAB": + try: + colorTemp = float(colorTemp) + except (TypeError, ValueError) as e: + msg = f'Color temperature must be numeric, "{colorTemp}" not valid' + raise PyCMSError(msg) from e + + try: + return core.createProfile(colorSpace, colorTemp) + except (TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileName(profile): + """ + + (pyCMS) Gets the internal product name for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, + a :exc:`PyCMSError` is raised If an error occurs while trying + to obtain the name tag, a :exc:`PyCMSError` is raised. + + Use this function to obtain the INTERNAL name of the profile (stored + in an ICC tag in the profile itself), usually the one used when the + profile was originally created. Sometimes this tag also contains + additional information supplied by the creator. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal name of the profile as stored + in an ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # do it in python, not c. + # // name was "%s - %s" (model, manufacturer) || Description , + # // but if the Model and Manufacturer were the same or the model + # // was long, Just the model, in 1.x + model = profile.profile.model + manufacturer = profile.profile.manufacturer + + if not (model or manufacturer): + return (profile.profile.profile_description or "") + "\n" + if not manufacturer or len(model) > 30: + return model + "\n" + return f"{model} - {manufacturer}\n" + + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileInfo(profile): + """ + (pyCMS) Gets the internal product information for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, + a :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the info tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + info tag. This often contains details about the profile, and how it + was created, as supplied by the creator. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # add an extra newline to preserve pyCMS compatibility + # Python, not C. the white point bits weren't working well, + # so skipping. + # info was description \r\n\r\n copyright \r\n\r\n K007 tag \r\n\r\n whitepoint + description = profile.profile.profile_description + cpright = profile.profile.copyright + elements = [element for element in (description, cpright) if element] + return "\r\n\r\n".join(elements) + "\r\n\r\n" + + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileCopyright(profile): + """ + (pyCMS) Gets the copyright for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the copyright tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + copyright tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.copyright or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileManufacturer(profile): + """ + (pyCMS) Gets the manufacturer for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the manufacturer tag, a + :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + manufacturer tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.manufacturer or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileModel(profile): + """ + (pyCMS) Gets the model for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the model tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + model tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.model or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileDescription(profile): + """ + (pyCMS) Gets the description for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the description tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + description tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in an + ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.profile_description or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getDefaultIntent(profile): + """ + (pyCMS) Gets the default intent name for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the default intent, a + :exc:`PyCMSError` is raised. + + Use this function to determine the default (and usually best optimized) + rendering intent for this profile. Most profiles support multiple + rendering intents, but are intended mostly for one type of conversion. + If you wish to use a different intent than returned, use + ImageCms.isIntentSupported() to verify it will work first. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: Integer 0-3 specifying the default rendering intent for this + profile. + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return profile.profile.rendering_intent + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def isIntentSupported(profile, intent, direction): + """ + (pyCMS) Checks if a given intent is supported. + + Use this function to verify that you can use your desired + ``intent`` with ``profile``, and that ``profile`` can be used for the + input/output/proof profile as you desire. + + Some profiles are created specifically for one "direction", can cannot + be used for others. Some profiles can only be used for certain + rendering intents, so it's best to either verify this before trying + to create a transform with them (using this function), or catch the + potential :exc:`PyCMSError` that will occur if they don't + support the modes you select. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :param intent: Integer (0-3) specifying the rendering intent you wish to + use with this profile + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param direction: Integer specifying if the profile is to be used for + input, output, or proof + + INPUT = 0 (or use ImageCms.Direction.INPUT) + OUTPUT = 1 (or use ImageCms.Direction.OUTPUT) + PROOF = 2 (or use ImageCms.Direction.PROOF) + + :returns: 1 if the intent/direction are supported, -1 if they are not. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # FIXME: I get different results for the same data w. different + # compilers. Bug in LittleCMS or in the binding? + if profile.profile.is_intent_supported(intent, direction): + return 1 + else: + return -1 + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def versions(): + """ + (pyCMS) Fetches versions. + """ + + return VERSION, core.littlecms_version, sys.version.split()[0], Image.__version__ diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageColor.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageColor.py new file mode 100644 index 00000000..ad59b066 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageColor.py @@ -0,0 +1,317 @@ +# +# The Python Imaging Library +# $Id$ +# +# map CSS3-style colour description strings to RGB +# +# History: +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-15 fl Added RGBA support +# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2 +# 2004-07-19 fl Fixed gray/grey spelling issues +# 2009-03-05 fl Fixed rounding error in grayscale calculation +# +# Copyright (c) 2002-2004 by Secret Labs AB +# Copyright (c) 2002-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re +from functools import lru_cache + +from . import Image + + +@lru_cache +def getrgb(color): + """ + Convert a color string to an RGB or RGBA tuple. If the string cannot be + parsed, this function raises a :py:exc:`ValueError` exception. + + .. versionadded:: 1.1.4 + + :param color: A color string + :return: ``(red, green, blue[, alpha])`` + """ + if len(color) > 100: + msg = "color specifier is too long" + raise ValueError(msg) + color = color.lower() + + rgb = colormap.get(color, None) + if rgb: + if isinstance(rgb, tuple): + return rgb + colormap[color] = rgb = getrgb(rgb) + return rgb + + # check for known string formats + if re.match("#[a-f0-9]{3}$", color): + return int(color[1] * 2, 16), int(color[2] * 2, 16), int(color[3] * 2, 16) + + if re.match("#[a-f0-9]{4}$", color): + return ( + int(color[1] * 2, 16), + int(color[2] * 2, 16), + int(color[3] * 2, 16), + int(color[4] * 2, 16), + ) + + if re.match("#[a-f0-9]{6}$", color): + return int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16) + + if re.match("#[a-f0-9]{8}$", color): + return ( + int(color[1:3], 16), + int(color[3:5], 16), + int(color[5:7], 16), + int(color[7:9], 16), + ) + + m = re.match(r"rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) + if m: + return int(m.group(1)), int(m.group(2)), int(m.group(3)) + + m = re.match(r"rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) + if m: + return ( + int((int(m.group(1)) * 255) / 100.0 + 0.5), + int((int(m.group(2)) * 255) / 100.0 + 0.5), + int((int(m.group(3)) * 255) / 100.0 + 0.5), + ) + + m = re.match( + r"hsl\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color + ) + if m: + from colorsys import hls_to_rgb + + rgb = hls_to_rgb( + float(m.group(1)) / 360.0, + float(m.group(3)) / 100.0, + float(m.group(2)) / 100.0, + ) + return ( + int(rgb[0] * 255 + 0.5), + int(rgb[1] * 255 + 0.5), + int(rgb[2] * 255 + 0.5), + ) + + m = re.match( + r"hs[bv]\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color + ) + if m: + from colorsys import hsv_to_rgb + + rgb = hsv_to_rgb( + float(m.group(1)) / 360.0, + float(m.group(2)) / 100.0, + float(m.group(3)) / 100.0, + ) + return ( + int(rgb[0] * 255 + 0.5), + int(rgb[1] * 255 + 0.5), + int(rgb[2] * 255 + 0.5), + ) + + m = re.match(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) + if m: + return int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)) + msg = f"unknown color specifier: {repr(color)}" + raise ValueError(msg) + + +@lru_cache +def getcolor(color, mode): + """ + Same as :py:func:`~PIL.ImageColor.getrgb` for most modes. However, if + ``mode`` is HSV, converts the RGB value to a HSV value, or if ``mode`` is + not color or a palette image, converts the RGB value to a grayscale value. + If the string cannot be parsed, this function raises a :py:exc:`ValueError` + exception. + + .. versionadded:: 1.1.4 + + :param color: A color string + :param mode: Convert result to this mode + :return: ``(graylevel[, alpha]) or (red, green, blue[, alpha])`` + """ + # same as getrgb, but converts the result to the given mode + color, alpha = getrgb(color), 255 + if len(color) == 4: + color, alpha = color[:3], color[3] + + if mode == "HSV": + from colorsys import rgb_to_hsv + + r, g, b = color + h, s, v = rgb_to_hsv(r / 255, g / 255, b / 255) + return int(h * 255), int(s * 255), int(v * 255) + elif Image.getmodebase(mode) == "L": + r, g, b = color + # ITU-R Recommendation 601-2 for nonlinear RGB + # scaled to 24 bits to match the convert's implementation. + color = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16 + if mode[-1] == "A": + return color, alpha + else: + if mode[-1] == "A": + return color + (alpha,) + return color + + +colormap = { + # X11 colour table from https://drafts.csswg.org/css-color-4/, with + # gray/grey spelling issues fixed. This is a superset of HTML 4.0 + # colour names used in CSS 1. + "aliceblue": "#f0f8ff", + "antiquewhite": "#faebd7", + "aqua": "#00ffff", + "aquamarine": "#7fffd4", + "azure": "#f0ffff", + "beige": "#f5f5dc", + "bisque": "#ffe4c4", + "black": "#000000", + "blanchedalmond": "#ffebcd", + "blue": "#0000ff", + "blueviolet": "#8a2be2", + "brown": "#a52a2a", + "burlywood": "#deb887", + "cadetblue": "#5f9ea0", + "chartreuse": "#7fff00", + "chocolate": "#d2691e", + "coral": "#ff7f50", + "cornflowerblue": "#6495ed", + "cornsilk": "#fff8dc", + "crimson": "#dc143c", + "cyan": "#00ffff", + "darkblue": "#00008b", + "darkcyan": "#008b8b", + "darkgoldenrod": "#b8860b", + "darkgray": "#a9a9a9", + "darkgrey": "#a9a9a9", + "darkgreen": "#006400", + "darkkhaki": "#bdb76b", + "darkmagenta": "#8b008b", + "darkolivegreen": "#556b2f", + "darkorange": "#ff8c00", + "darkorchid": "#9932cc", + "darkred": "#8b0000", + "darksalmon": "#e9967a", + "darkseagreen": "#8fbc8f", + "darkslateblue": "#483d8b", + "darkslategray": "#2f4f4f", + "darkslategrey": "#2f4f4f", + "darkturquoise": "#00ced1", + "darkviolet": "#9400d3", + "deeppink": "#ff1493", + "deepskyblue": "#00bfff", + "dimgray": "#696969", + "dimgrey": "#696969", + "dodgerblue": "#1e90ff", + "firebrick": "#b22222", + "floralwhite": "#fffaf0", + "forestgreen": "#228b22", + "fuchsia": "#ff00ff", + "gainsboro": "#dcdcdc", + "ghostwhite": "#f8f8ff", + "gold": "#ffd700", + "goldenrod": "#daa520", + "gray": "#808080", + "grey": "#808080", + "green": "#008000", + "greenyellow": "#adff2f", + "honeydew": "#f0fff0", + "hotpink": "#ff69b4", + "indianred": "#cd5c5c", + "indigo": "#4b0082", + "ivory": "#fffff0", + "khaki": "#f0e68c", + "lavender": "#e6e6fa", + "lavenderblush": "#fff0f5", + "lawngreen": "#7cfc00", + "lemonchiffon": "#fffacd", + "lightblue": "#add8e6", + "lightcoral": "#f08080", + "lightcyan": "#e0ffff", + "lightgoldenrodyellow": "#fafad2", + "lightgreen": "#90ee90", + "lightgray": "#d3d3d3", + "lightgrey": "#d3d3d3", + "lightpink": "#ffb6c1", + "lightsalmon": "#ffa07a", + "lightseagreen": "#20b2aa", + "lightskyblue": "#87cefa", + "lightslategray": "#778899", + "lightslategrey": "#778899", + "lightsteelblue": "#b0c4de", + "lightyellow": "#ffffe0", + "lime": "#00ff00", + "limegreen": "#32cd32", + "linen": "#faf0e6", + "magenta": "#ff00ff", + "maroon": "#800000", + "mediumaquamarine": "#66cdaa", + "mediumblue": "#0000cd", + "mediumorchid": "#ba55d3", + "mediumpurple": "#9370db", + "mediumseagreen": "#3cb371", + "mediumslateblue": "#7b68ee", + "mediumspringgreen": "#00fa9a", + "mediumturquoise": "#48d1cc", + "mediumvioletred": "#c71585", + "midnightblue": "#191970", + "mintcream": "#f5fffa", + "mistyrose": "#ffe4e1", + "moccasin": "#ffe4b5", + "navajowhite": "#ffdead", + "navy": "#000080", + "oldlace": "#fdf5e6", + "olive": "#808000", + "olivedrab": "#6b8e23", + "orange": "#ffa500", + "orangered": "#ff4500", + "orchid": "#da70d6", + "palegoldenrod": "#eee8aa", + "palegreen": "#98fb98", + "paleturquoise": "#afeeee", + "palevioletred": "#db7093", + "papayawhip": "#ffefd5", + "peachpuff": "#ffdab9", + "peru": "#cd853f", + "pink": "#ffc0cb", + "plum": "#dda0dd", + "powderblue": "#b0e0e6", + "purple": "#800080", + "rebeccapurple": "#663399", + "red": "#ff0000", + "rosybrown": "#bc8f8f", + "royalblue": "#4169e1", + "saddlebrown": "#8b4513", + "salmon": "#fa8072", + "sandybrown": "#f4a460", + "seagreen": "#2e8b57", + "seashell": "#fff5ee", + "sienna": "#a0522d", + "silver": "#c0c0c0", + "skyblue": "#87ceeb", + "slateblue": "#6a5acd", + "slategray": "#708090", + "slategrey": "#708090", + "snow": "#fffafa", + "springgreen": "#00ff7f", + "steelblue": "#4682b4", + "tan": "#d2b48c", + "teal": "#008080", + "thistle": "#d8bfd8", + "tomato": "#ff6347", + "turquoise": "#40e0d0", + "violet": "#ee82ee", + "wheat": "#f5deb3", + "white": "#ffffff", + "whitesmoke": "#f5f5f5", + "yellow": "#ffff00", + "yellowgreen": "#9acd32", +} diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw.py new file mode 100644 index 00000000..84665f54 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw.py @@ -0,0 +1,1065 @@ +# +# The Python Imaging Library +# $Id$ +# +# drawing interface operations +# +# History: +# 1996-04-13 fl Created (experimental) +# 1996-08-07 fl Filled polygons, ellipses. +# 1996-08-13 fl Added text support +# 1998-06-28 fl Handle I and F images +# 1998-12-29 fl Added arc; use arc primitive to draw ellipses +# 1999-01-10 fl Added shape stuff (experimental) +# 1999-02-06 fl Added bitmap support +# 1999-02-11 fl Changed all primitives to take options +# 1999-02-20 fl Fixed backwards compatibility +# 2000-10-12 fl Copy on write, when necessary +# 2001-02-18 fl Use default ink for bitmap/text also in fill mode +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing +# 2002-12-11 fl Refactored low-level drawing API (work in progress) +# 2004-08-26 fl Made Draw() a factory function, added getdraw() support +# 2004-09-04 fl Added width support to line primitive +# 2004-09-10 fl Added font mode handling +# 2006-06-19 fl Added font bearing support (getmask2) +# +# Copyright (c) 1997-2006 by Secret Labs AB +# Copyright (c) 1996-2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math +import numbers +import struct + +from . import Image, ImageColor + +""" +A simple 2D drawing interface for PIL images. +

+Application code should use the Draw factory, instead of +directly. +""" + + +class ImageDraw: + font = None + + def __init__(self, im, mode=None): + """ + Create a drawing instance. + + :param im: The image to draw in. + :param mode: Optional mode to use for color values. For RGB + images, this argument can be RGB or RGBA (to blend the + drawing into the image). For all other modes, this argument + must be the same as the image mode. If omitted, the mode + defaults to the mode of the image. + """ + im.load() + if im.readonly: + im._copy() # make it writeable + blend = 0 + if mode is None: + mode = im.mode + if mode != im.mode: + if mode == "RGBA" and im.mode == "RGB": + blend = 1 + else: + msg = "mode mismatch" + raise ValueError(msg) + if mode == "P": + self.palette = im.palette + else: + self.palette = None + self._image = im + self.im = im.im + self.draw = Image.core.draw(self.im, blend) + self.mode = mode + if mode in ("I", "F"): + self.ink = self.draw.draw_ink(1) + else: + self.ink = self.draw.draw_ink(-1) + if mode in ("1", "P", "I", "F"): + # FIXME: fix Fill2 to properly support matte for I+F images + self.fontmode = "1" + else: + self.fontmode = "L" # aliasing is okay for other modes + self.fill = False + + def getfont(self): + """ + Get the current default font. + + To set the default font for this ImageDraw instance:: + + from PIL import ImageDraw, ImageFont + draw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + + To set the default font for all future ImageDraw instances:: + + from PIL import ImageDraw, ImageFont + ImageDraw.ImageDraw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + + If the current default font is ``None``, + it is initialized with ``ImageFont.load_default()``. + + :returns: An image font.""" + if not self.font: + # FIXME: should add a font repository + from . import ImageFont + + self.font = ImageFont.load_default() + return self.font + + def _getfont(self, font_size): + if font_size is not None: + from . import ImageFont + + font = ImageFont.load_default(font_size) + else: + font = self.getfont() + return font + + def _getink(self, ink, fill=None): + if ink is None and fill is None: + if self.fill: + fill = self.ink + else: + ink = self.ink + else: + if ink is not None: + if isinstance(ink, str): + ink = ImageColor.getcolor(ink, self.mode) + if self.palette and not isinstance(ink, numbers.Number): + ink = self.palette.getcolor(ink, self._image) + ink = self.draw.draw_ink(ink) + if fill is not None: + if isinstance(fill, str): + fill = ImageColor.getcolor(fill, self.mode) + if self.palette and not isinstance(fill, numbers.Number): + fill = self.palette.getcolor(fill, self._image) + fill = self.draw.draw_ink(fill) + return ink, fill + + def arc(self, xy, start, end, fill=None, width=1): + """Draw an arc.""" + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_arc(xy, start, end, ink, width) + + def bitmap(self, xy, bitmap, fill=None): + """Draw a bitmap.""" + bitmap.load() + ink, fill = self._getink(fill) + if ink is None: + ink = fill + if ink is not None: + self.draw.draw_bitmap(xy, bitmap.im, ink) + + def chord(self, xy, start, end, fill=None, outline=None, width=1): + """Draw a chord.""" + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_chord(xy, start, end, fill, 1) + if ink is not None and ink != fill and width != 0: + self.draw.draw_chord(xy, start, end, ink, 0, width) + + def ellipse(self, xy, fill=None, outline=None, width=1): + """Draw an ellipse.""" + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_ellipse(xy, fill, 1) + if ink is not None and ink != fill and width != 0: + self.draw.draw_ellipse(xy, ink, 0, width) + + def line(self, xy, fill=None, width=0, joint=None): + """Draw a line, or a connected sequence of line segments.""" + ink = self._getink(fill)[0] + if ink is not None: + self.draw.draw_lines(xy, ink, width) + if joint == "curve" and width > 4: + if not isinstance(xy[0], (list, tuple)): + xy = [tuple(xy[i : i + 2]) for i in range(0, len(xy), 2)] + for i in range(1, len(xy) - 1): + point = xy[i] + angles = [ + math.degrees(math.atan2(end[0] - start[0], start[1] - end[1])) + % 360 + for start, end in ((xy[i - 1], point), (point, xy[i + 1])) + ] + if angles[0] == angles[1]: + # This is a straight line, so no joint is required + continue + + def coord_at_angle(coord, angle): + x, y = coord + angle -= 90 + distance = width / 2 - 1 + return tuple( + p + (math.floor(p_d) if p_d > 0 else math.ceil(p_d)) + for p, p_d in ( + (x, distance * math.cos(math.radians(angle))), + (y, distance * math.sin(math.radians(angle))), + ) + ) + + flipped = ( + angles[1] > angles[0] and angles[1] - 180 > angles[0] + ) or (angles[1] < angles[0] and angles[1] + 180 > angles[0]) + coords = [ + (point[0] - width / 2 + 1, point[1] - width / 2 + 1), + (point[0] + width / 2 - 1, point[1] + width / 2 - 1), + ] + if flipped: + start, end = (angles[1] + 90, angles[0] + 90) + else: + start, end = (angles[0] - 90, angles[1] - 90) + self.pieslice(coords, start - 90, end - 90, fill) + + if width > 8: + # Cover potential gaps between the line and the joint + if flipped: + gap_coords = [ + coord_at_angle(point, angles[0] + 90), + point, + coord_at_angle(point, angles[1] + 90), + ] + else: + gap_coords = [ + coord_at_angle(point, angles[0] - 90), + point, + coord_at_angle(point, angles[1] - 90), + ] + self.line(gap_coords, fill, width=3) + + def shape(self, shape, fill=None, outline=None): + """(Experimental) Draw a shape.""" + shape.close() + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_outline(shape, fill, 1) + if ink is not None and ink != fill: + self.draw.draw_outline(shape, ink, 0) + + def pieslice(self, xy, start, end, fill=None, outline=None, width=1): + """Draw a pieslice.""" + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_pieslice(xy, start, end, fill, 1) + if ink is not None and ink != fill and width != 0: + self.draw.draw_pieslice(xy, start, end, ink, 0, width) + + def point(self, xy, fill=None): + """Draw one or more individual pixels.""" + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_points(xy, ink) + + def polygon(self, xy, fill=None, outline=None, width=1): + """Draw a polygon.""" + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_polygon(xy, fill, 1) + if ink is not None and ink != fill and width != 0: + if width == 1: + self.draw.draw_polygon(xy, ink, 0, width) + else: + # To avoid expanding the polygon outwards, + # use the fill as a mask + mask = Image.new("1", self.im.size) + mask_ink = self._getink(1)[0] + + fill_im = mask.copy() + draw = Draw(fill_im) + draw.draw.draw_polygon(xy, mask_ink, 1) + + ink_im = mask.copy() + draw = Draw(ink_im) + width = width * 2 - 1 + draw.draw.draw_polygon(xy, mask_ink, 0, width) + + mask.paste(ink_im, mask=fill_im) + + im = Image.new(self.mode, self.im.size) + draw = Draw(im) + draw.draw.draw_polygon(xy, ink, 0, width) + self.im.paste(im.im, (0, 0) + im.size, mask.im) + + def regular_polygon( + self, bounding_circle, n_sides, rotation=0, fill=None, outline=None, width=1 + ): + """Draw a regular polygon.""" + xy = _compute_regular_polygon_vertices(bounding_circle, n_sides, rotation) + self.polygon(xy, fill, outline, width) + + def rectangle(self, xy, fill=None, outline=None, width=1): + """Draw a rectangle.""" + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_rectangle(xy, fill, 1) + if ink is not None and ink != fill and width != 0: + self.draw.draw_rectangle(xy, ink, 0, width) + + def rounded_rectangle( + self, xy, radius=0, fill=None, outline=None, width=1, *, corners=None + ): + """Draw a rounded rectangle.""" + if isinstance(xy[0], (list, tuple)): + (x0, y0), (x1, y1) = xy + else: + x0, y0, x1, y1 = xy + if x1 < x0: + msg = "x1 must be greater than or equal to x0" + raise ValueError(msg) + if y1 < y0: + msg = "y1 must be greater than or equal to y0" + raise ValueError(msg) + if corners is None: + corners = (True, True, True, True) + + d = radius * 2 + + full_x, full_y = False, False + if all(corners): + full_x = d >= x1 - x0 - 1 + if full_x: + # The two left and two right corners are joined + d = x1 - x0 + full_y = d >= y1 - y0 - 1 + if full_y: + # The two top and two bottom corners are joined + d = y1 - y0 + if full_x and full_y: + # If all corners are joined, that is a circle + return self.ellipse(xy, fill, outline, width) + + if d == 0 or not any(corners): + # If the corners have no curve, + # or there are no corners, + # that is a rectangle + return self.rectangle(xy, fill, outline, width) + + r = d // 2 + ink, fill = self._getink(outline, fill) + + def draw_corners(pieslice): + if full_x: + # Draw top and bottom halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 180, 360), + ((x0, y1 - d, x0 + d, y1), 0, 180), + ) + elif full_y: + # Draw left and right halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 90, 270), + ((x1 - d, y0, x1, y0 + d), 270, 90), + ) + else: + # Draw four separate corners + parts = [] + for i, part in enumerate( + ( + ((x0, y0, x0 + d, y0 + d), 180, 270), + ((x1 - d, y0, x1, y0 + d), 270, 360), + ((x1 - d, y1 - d, x1, y1), 0, 90), + ((x0, y1 - d, x0 + d, y1), 90, 180), + ) + ): + if corners[i]: + parts.append(part) + for part in parts: + if pieslice: + self.draw.draw_pieslice(*(part + (fill, 1))) + else: + self.draw.draw_arc(*(part + (ink, width))) + + if fill is not None: + draw_corners(True) + + if full_x: + self.draw.draw_rectangle((x0, y0 + r + 1, x1, y1 - r - 1), fill, 1) + else: + self.draw.draw_rectangle((x0 + r + 1, y0, x1 - r - 1, y1), fill, 1) + if not full_x and not full_y: + left = [x0, y0, x0 + r, y1] + if corners[0]: + left[1] += r + 1 + if corners[3]: + left[3] -= r + 1 + self.draw.draw_rectangle(left, fill, 1) + + right = [x1 - r, y0, x1, y1] + if corners[1]: + right[1] += r + 1 + if corners[2]: + right[3] -= r + 1 + self.draw.draw_rectangle(right, fill, 1) + if ink is not None and ink != fill and width != 0: + draw_corners(False) + + if not full_x: + top = [x0, y0, x1, y0 + width - 1] + if corners[0]: + top[0] += r + 1 + if corners[1]: + top[2] -= r + 1 + self.draw.draw_rectangle(top, ink, 1) + + bottom = [x0, y1 - width + 1, x1, y1] + if corners[3]: + bottom[0] += r + 1 + if corners[2]: + bottom[2] -= r + 1 + self.draw.draw_rectangle(bottom, ink, 1) + if not full_y: + left = [x0, y0, x0 + width - 1, y1] + if corners[0]: + left[1] += r + 1 + if corners[3]: + left[3] -= r + 1 + self.draw.draw_rectangle(left, ink, 1) + + right = [x1 - width + 1, y0, x1, y1] + if corners[1]: + right[1] += r + 1 + if corners[2]: + right[3] -= r + 1 + self.draw.draw_rectangle(right, ink, 1) + + def _multiline_check(self, text): + split_character = "\n" if isinstance(text, str) else b"\n" + + return split_character in text + + def _multiline_split(self, text): + split_character = "\n" if isinstance(text, str) else b"\n" + + return text.split(split_character) + + def _multiline_spacing(self, font, spacing, stroke_width): + return ( + self.textbbox((0, 0), "A", font, stroke_width=stroke_width)[3] + + stroke_width + + spacing + ) + + def text( + self, + xy, + text, + fill=None, + font=None, + anchor=None, + spacing=4, + align="left", + direction=None, + features=None, + language=None, + stroke_width=0, + stroke_fill=None, + embedded_color=False, + *args, + **kwargs, + ): + """Draw text.""" + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(kwargs.get("font_size")) + + if self._multiline_check(text): + return self.multiline_text( + xy, + text, + fill, + font, + anchor, + spacing, + align, + direction, + features, + language, + stroke_width, + stroke_fill, + embedded_color, + ) + + def getink(fill): + ink, fill = self._getink(fill) + if ink is None: + return fill + return ink + + def draw_text(ink, stroke_width=0, stroke_offset=None): + mode = self.fontmode + if stroke_width == 0 and embedded_color: + mode = "RGBA" + coord = [] + start = [] + for i in range(2): + coord.append(int(xy[i])) + start.append(math.modf(xy[i])[0]) + try: + mask, offset = font.getmask2( + text, + mode, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + anchor=anchor, + ink=ink, + start=start, + *args, + **kwargs, + ) + coord = coord[0] + offset[0], coord[1] + offset[1] + except AttributeError: + try: + mask = font.getmask( + text, + mode, + direction, + features, + language, + stroke_width, + anchor, + ink, + start=start, + *args, + **kwargs, + ) + except TypeError: + mask = font.getmask(text) + if stroke_offset: + coord = coord[0] + stroke_offset[0], coord[1] + stroke_offset[1] + if mode == "RGBA": + # font.getmask2(mode="RGBA") returns color in RGB bands and mask in A + # extract mask and set text alpha + color, mask = mask, mask.getband(3) + ink_alpha = struct.pack("i", ink)[3] + color.fillband(3, ink_alpha) + x, y = coord + self.im.paste(color, (x, y, x + mask.size[0], y + mask.size[1]), mask) + else: + self.draw.draw_bitmap(coord, mask, ink) + + ink = getink(fill) + if ink is not None: + stroke_ink = None + if stroke_width: + stroke_ink = getink(stroke_fill) if stroke_fill is not None else ink + + if stroke_ink is not None: + # Draw stroked text + draw_text(stroke_ink, stroke_width) + + # Draw normal text + draw_text(ink, 0) + else: + # Only draw normal text + draw_text(ink) + + def multiline_text( + self, + xy, + text, + fill=None, + font=None, + anchor=None, + spacing=4, + align="left", + direction=None, + features=None, + language=None, + stroke_width=0, + stroke_fill=None, + embedded_color=False, + *, + font_size=None, + ): + if direction == "ttb": + msg = "ttb direction is unsupported for multiline text" + raise ValueError(msg) + + if anchor is None: + anchor = "la" + elif len(anchor) != 2: + msg = "anchor must be a 2 character string" + raise ValueError(msg) + elif anchor[1] in "tb": + msg = "anchor not supported for multiline text" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + widths = [] + max_width = 0 + lines = self._multiline_split(text) + line_spacing = self._multiline_spacing(font, spacing, stroke_width) + for line in lines: + line_width = self.textlength( + line, font, direction=direction, features=features, language=language + ) + widths.append(line_width) + max_width = max(max_width, line_width) + + top = xy[1] + if anchor[1] == "m": + top -= (len(lines) - 1) * line_spacing / 2.0 + elif anchor[1] == "d": + top -= (len(lines) - 1) * line_spacing + + for idx, line in enumerate(lines): + left = xy[0] + width_difference = max_width - widths[idx] + + # first align left by anchor + if anchor[0] == "m": + left -= width_difference / 2.0 + elif anchor[0] == "r": + left -= width_difference + + # then align by align parameter + if align == "left": + pass + elif align == "center": + left += width_difference / 2.0 + elif align == "right": + left += width_difference + else: + msg = 'align must be "left", "center" or "right"' + raise ValueError(msg) + + self.text( + (left, top), + line, + fill, + font, + anchor, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + stroke_fill=stroke_fill, + embedded_color=embedded_color, + ) + top += line_spacing + + def textlength( + self, + text, + font=None, + direction=None, + features=None, + language=None, + embedded_color=False, + *, + font_size=None, + ): + """Get the length of a given string, in pixels with 1/64 precision.""" + if self._multiline_check(text): + msg = "can't measure length of multiline text" + raise ValueError(msg) + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + mode = "RGBA" if embedded_color else self.fontmode + return font.getlength(text, mode, direction, features, language) + + def textbbox( + self, + xy, + text, + font=None, + anchor=None, + spacing=4, + align="left", + direction=None, + features=None, + language=None, + stroke_width=0, + embedded_color=False, + *, + font_size=None, + ): + """Get the bounding box of a given string, in pixels.""" + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + if self._multiline_check(text): + return self.multiline_textbbox( + xy, + text, + font, + anchor, + spacing, + align, + direction, + features, + language, + stroke_width, + embedded_color, + ) + + mode = "RGBA" if embedded_color else self.fontmode + bbox = font.getbbox( + text, mode, direction, features, language, stroke_width, anchor + ) + return bbox[0] + xy[0], bbox[1] + xy[1], bbox[2] + xy[0], bbox[3] + xy[1] + + def multiline_textbbox( + self, + xy, + text, + font=None, + anchor=None, + spacing=4, + align="left", + direction=None, + features=None, + language=None, + stroke_width=0, + embedded_color=False, + *, + font_size=None, + ): + if direction == "ttb": + msg = "ttb direction is unsupported for multiline text" + raise ValueError(msg) + + if anchor is None: + anchor = "la" + elif len(anchor) != 2: + msg = "anchor must be a 2 character string" + raise ValueError(msg) + elif anchor[1] in "tb": + msg = "anchor not supported for multiline text" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + widths = [] + max_width = 0 + lines = self._multiline_split(text) + line_spacing = self._multiline_spacing(font, spacing, stroke_width) + for line in lines: + line_width = self.textlength( + line, + font, + direction=direction, + features=features, + language=language, + embedded_color=embedded_color, + ) + widths.append(line_width) + max_width = max(max_width, line_width) + + top = xy[1] + if anchor[1] == "m": + top -= (len(lines) - 1) * line_spacing / 2.0 + elif anchor[1] == "d": + top -= (len(lines) - 1) * line_spacing + + bbox = None + + for idx, line in enumerate(lines): + left = xy[0] + width_difference = max_width - widths[idx] + + # first align left by anchor + if anchor[0] == "m": + left -= width_difference / 2.0 + elif anchor[0] == "r": + left -= width_difference + + # then align by align parameter + if align == "left": + pass + elif align == "center": + left += width_difference / 2.0 + elif align == "right": + left += width_difference + else: + msg = 'align must be "left", "center" or "right"' + raise ValueError(msg) + + bbox_line = self.textbbox( + (left, top), + line, + font, + anchor, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + embedded_color=embedded_color, + ) + if bbox is None: + bbox = bbox_line + else: + bbox = ( + min(bbox[0], bbox_line[0]), + min(bbox[1], bbox_line[1]), + max(bbox[2], bbox_line[2]), + max(bbox[3], bbox_line[3]), + ) + + top += line_spacing + + if bbox is None: + return xy[0], xy[1], xy[0], xy[1] + return bbox + + +def Draw(im, mode=None): + """ + A simple 2D drawing interface for PIL images. + + :param im: The image to draw in. + :param mode: Optional mode to use for color values. For RGB + images, this argument can be RGB or RGBA (to blend the + drawing into the image). For all other modes, this argument + must be the same as the image mode. If omitted, the mode + defaults to the mode of the image. + """ + try: + return im.getdraw(mode) + except AttributeError: + return ImageDraw(im, mode) + + +# experimental access to the outline API +try: + Outline = Image.core.outline +except AttributeError: + Outline = None + + +def getdraw(im=None, hints=None): + """ + (Experimental) A more advanced 2D drawing interface for PIL images, + based on the WCK interface. + + :param im: The image to draw in. + :param hints: An optional list of hints. + :returns: A (drawing context, drawing resource factory) tuple. + """ + # FIXME: this needs more work! + # FIXME: come up with a better 'hints' scheme. + handler = None + if not hints or "nicest" in hints: + try: + from . import _imagingagg as handler + except ImportError: + pass + if handler is None: + from . import ImageDraw2 as handler + if im: + im = handler.Draw(im) + return im, handler + + +def floodfill(image, xy, value, border=None, thresh=0): + """ + (experimental) Fills a bounded region with a given color. + + :param image: Target image. + :param xy: Seed position (a 2-item coordinate tuple). See + :ref:`coordinate-system`. + :param value: Fill color. + :param border: Optional border value. If given, the region consists of + pixels with a color different from the border color. If not given, + the region consists of pixels having the same color as the seed + pixel. + :param thresh: Optional threshold value which specifies a maximum + tolerable difference of a pixel value from the 'background' in + order for it to be replaced. Useful for filling regions of + non-homogeneous, but similar, colors. + """ + # based on an implementation by Eric S. Raymond + # amended by yo1995 @20180806 + pixel = image.load() + x, y = xy + try: + background = pixel[x, y] + if _color_diff(value, background) <= thresh: + return # seed point already has fill color + pixel[x, y] = value + except (ValueError, IndexError): + return # seed point outside image + edge = {(x, y)} + # use a set to keep record of current and previous edge pixels + # to reduce memory consumption + full_edge = set() + while edge: + new_edge = set() + for x, y in edge: # 4 adjacent method + for s, t in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)): + # If already processed, or if a coordinate is negative, skip + if (s, t) in full_edge or s < 0 or t < 0: + continue + try: + p = pixel[s, t] + except (ValueError, IndexError): + pass + else: + full_edge.add((s, t)) + if border is None: + fill = _color_diff(p, background) <= thresh + else: + fill = p not in (value, border) + if fill: + pixel[s, t] = value + new_edge.add((s, t)) + full_edge = edge # discard pixels processed + edge = new_edge + + +def _compute_regular_polygon_vertices(bounding_circle, n_sides, rotation): + """ + Generate a list of vertices for a 2D regular polygon. + + :param bounding_circle: The bounding circle is a tuple defined + by a point and radius. The polygon is inscribed in this circle. + (e.g. ``bounding_circle=(x, y, r)`` or ``((x, y), r)``) + :param n_sides: Number of sides + (e.g. ``n_sides=3`` for a triangle, ``6`` for a hexagon) + :param rotation: Apply an arbitrary rotation to the polygon + (e.g. ``rotation=90``, applies a 90 degree rotation) + :return: List of regular polygon vertices + (e.g. ``[(25, 50), (50, 50), (50, 25), (25, 25)]``) + + How are the vertices computed? + 1. Compute the following variables + - theta: Angle between the apothem & the nearest polygon vertex + - side_length: Length of each polygon edge + - centroid: Center of bounding circle (1st, 2nd elements of bounding_circle) + - polygon_radius: Polygon radius (last element of bounding_circle) + - angles: Location of each polygon vertex in polar grid + (e.g. A square with 0 degree rotation => [225.0, 315.0, 45.0, 135.0]) + + 2. For each angle in angles, get the polygon vertex at that angle + The vertex is computed using the equation below. + X= xcos(φ) + ysin(φ) + Y= −xsin(φ) + ycos(φ) + + Note: + φ = angle in degrees + x = 0 + y = polygon_radius + + The formula above assumes rotation around the origin. + In our case, we are rotating around the centroid. + To account for this, we use the formula below + X = xcos(φ) + ysin(φ) + centroid_x + Y = −xsin(φ) + ycos(φ) + centroid_y + """ + # 1. Error Handling + # 1.1 Check `n_sides` has an appropriate value + if not isinstance(n_sides, int): + msg = "n_sides should be an int" + raise TypeError(msg) + if n_sides < 3: + msg = "n_sides should be an int > 2" + raise ValueError(msg) + + # 1.2 Check `bounding_circle` has an appropriate value + if not isinstance(bounding_circle, (list, tuple)): + msg = "bounding_circle should be a tuple" + raise TypeError(msg) + + if len(bounding_circle) == 3: + *centroid, polygon_radius = bounding_circle + elif len(bounding_circle) == 2: + centroid, polygon_radius = bounding_circle + else: + msg = ( + "bounding_circle should contain 2D coordinates " + "and a radius (e.g. (x, y, r) or ((x, y), r) )" + ) + raise ValueError(msg) + + if not all(isinstance(i, (int, float)) for i in (*centroid, polygon_radius)): + msg = "bounding_circle should only contain numeric data" + raise ValueError(msg) + + if not len(centroid) == 2: + msg = "bounding_circle centre should contain 2D coordinates (e.g. (x, y))" + raise ValueError(msg) + + if polygon_radius <= 0: + msg = "bounding_circle radius should be > 0" + raise ValueError(msg) + + # 1.3 Check `rotation` has an appropriate value + if not isinstance(rotation, (int, float)): + msg = "rotation should be an int or float" + raise ValueError(msg) + + # 2. Define Helper Functions + def _apply_rotation(point, degrees, centroid): + return ( + round( + point[0] * math.cos(math.radians(360 - degrees)) + - point[1] * math.sin(math.radians(360 - degrees)) + + centroid[0], + 2, + ), + round( + point[1] * math.cos(math.radians(360 - degrees)) + + point[0] * math.sin(math.radians(360 - degrees)) + + centroid[1], + 2, + ), + ) + + def _compute_polygon_vertex(centroid, polygon_radius, angle): + start_point = [polygon_radius, 0] + return _apply_rotation(start_point, angle, centroid) + + def _get_angles(n_sides, rotation): + angles = [] + degrees = 360 / n_sides + # Start with the bottom left polygon vertex + current_angle = (270 - 0.5 * degrees) + rotation + for _ in range(0, n_sides): + angles.append(current_angle) + current_angle += degrees + if current_angle > 360: + current_angle -= 360 + return angles + + # 3. Variable Declarations + angles = _get_angles(n_sides, rotation) + + # 4. Compute Vertices + return [ + _compute_polygon_vertex(centroid, polygon_radius, angle) for angle in angles + ] + + +def _color_diff(color1, color2): + """ + Uses 1-norm distance to calculate difference between two values. + """ + if isinstance(color2, tuple): + return sum(abs(color1[i] - color2[i]) for i in range(0, len(color2))) + else: + return abs(color1 - color2) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw2.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw2.py new file mode 100644 index 00000000..35ee5834 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw2.py @@ -0,0 +1,193 @@ +# +# The Python Imaging Library +# $Id$ +# +# WCK-style drawing interface operations +# +# History: +# 2003-12-07 fl created +# 2005-05-15 fl updated; added to PIL as ImageDraw2 +# 2005-05-15 fl added text support +# 2005-05-20 fl added arc/chord/pieslice support +# +# Copyright (c) 2003-2005 by Secret Labs AB +# Copyright (c) 2003-2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +""" +(Experimental) WCK-style drawing interface operations + +.. seealso:: :py:mod:`PIL.ImageDraw` +""" +from __future__ import annotations + +from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath + + +class Pen: + """Stores an outline color and width.""" + + def __init__(self, color, width=1, opacity=255): + self.color = ImageColor.getrgb(color) + self.width = width + + +class Brush: + """Stores a fill color""" + + def __init__(self, color, opacity=255): + self.color = ImageColor.getrgb(color) + + +class Font: + """Stores a TrueType font and color""" + + def __init__(self, color, file, size=12): + # FIXME: add support for bitmap fonts + self.color = ImageColor.getrgb(color) + self.font = ImageFont.truetype(file, size) + + +class Draw: + """ + (Experimental) WCK-style drawing interface + """ + + def __init__(self, image, size=None, color=None): + if not hasattr(image, "im"): + image = Image.new(image, size, color) + self.draw = ImageDraw.Draw(image) + self.image = image + self.transform = None + + def flush(self): + return self.image + + def render(self, op, xy, pen, brush=None): + # handle color arguments + outline = fill = None + width = 1 + if isinstance(pen, Pen): + outline = pen.color + width = pen.width + elif isinstance(brush, Pen): + outline = brush.color + width = brush.width + if isinstance(brush, Brush): + fill = brush.color + elif isinstance(pen, Brush): + fill = pen.color + # handle transformation + if self.transform: + xy = ImagePath.Path(xy) + xy.transform(self.transform) + # render the item + if op == "line": + self.draw.line(xy, fill=outline, width=width) + else: + getattr(self.draw, op)(xy, fill=fill, outline=outline) + + def settransform(self, offset): + """Sets a transformation offset.""" + (xoffset, yoffset) = offset + self.transform = (1, 0, xoffset, 0, 1, yoffset) + + def arc(self, xy, start, end, *options): + """ + Draws an arc (a portion of a circle outline) between the start and end + angles, inside the given bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.arc` + """ + self.render("arc", xy, start, end, *options) + + def chord(self, xy, start, end, *options): + """ + Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points + with a straight line. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord` + """ + self.render("chord", xy, start, end, *options) + + def ellipse(self, xy, *options): + """ + Draws an ellipse inside the given bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.ellipse` + """ + self.render("ellipse", xy, *options) + + def line(self, xy, *options): + """ + Draws a line between the coordinates in the ``xy`` list. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.line` + """ + self.render("line", xy, *options) + + def pieslice(self, xy, start, end, *options): + """ + Same as arc, but also draws straight lines between the end points and the + center of the bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.pieslice` + """ + self.render("pieslice", xy, start, end, *options) + + def polygon(self, xy, *options): + """ + Draws a polygon. + + The polygon outline consists of straight lines between the given + coordinates, plus a straight line between the last and the first + coordinate. + + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.polygon` + """ + self.render("polygon", xy, *options) + + def rectangle(self, xy, *options): + """ + Draws a rectangle. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.rectangle` + """ + self.render("rectangle", xy, *options) + + def text(self, xy, text, font): + """ + Draws the string at the given position. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.text` + """ + if self.transform: + xy = ImagePath.Path(xy) + xy.transform(self.transform) + self.draw.text(xy, text, font=font.font, fill=font.color) + + def textbbox(self, xy, text, font): + """ + Returns bounding box (in pixels) of given text. + + :return: ``(left, top, right, bottom)`` bounding box + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textbbox` + """ + if self.transform: + xy = ImagePath.Path(xy) + xy.transform(self.transform) + return self.draw.textbbox(xy, text, font=font.font) + + def textlength(self, text, font): + """ + Returns length (in pixels) of given text. + This is the amount by which following text should be offset. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textlength` + """ + return self.draw.textlength(text, font=font.font) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageEnhance.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageEnhance.py new file mode 100644 index 00000000..93a50d2a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageEnhance.py @@ -0,0 +1,104 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image enhancement classes +# +# For a background, see "Image Processing By Interpolation and +# Extrapolation", Paul Haeberli and Douglas Voorhies. Available +# at http://www.graficaobscura.com/interp/index.html +# +# History: +# 1996-03-23 fl Created +# 2009-06-16 fl Fixed mean calculation +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFilter, ImageStat + + +class _Enhance: + def enhance(self, factor): + """ + Returns an enhanced image. + + :param factor: A floating point value controlling the enhancement. + Factor 1.0 always returns a copy of the original image, + lower factors mean less color (brightness, contrast, + etc), and higher values more. There are no restrictions + on this value. + :rtype: :py:class:`~PIL.Image.Image` + """ + return Image.blend(self.degenerate, self.image, factor) + + +class Color(_Enhance): + """Adjust image color balance. + + This class can be used to adjust the colour balance of an image, in + a manner similar to the controls on a colour TV set. An enhancement + factor of 0.0 gives a black and white image. A factor of 1.0 gives + the original image. + """ + + def __init__(self, image): + self.image = image + self.intermediate_mode = "L" + if "A" in image.getbands(): + self.intermediate_mode = "LA" + + self.degenerate = image.convert(self.intermediate_mode).convert(image.mode) + + +class Contrast(_Enhance): + """Adjust image contrast. + + This class can be used to control the contrast of an image, similar + to the contrast control on a TV set. An enhancement factor of 0.0 + gives a solid gray image. A factor of 1.0 gives the original image. + """ + + def __init__(self, image): + self.image = image + mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5) + self.degenerate = Image.new("L", image.size, mean).convert(image.mode) + + if "A" in image.getbands(): + self.degenerate.putalpha(image.getchannel("A")) + + +class Brightness(_Enhance): + """Adjust image brightness. + + This class can be used to control the brightness of an image. An + enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the + original image. + """ + + def __init__(self, image): + self.image = image + self.degenerate = Image.new(image.mode, image.size, 0) + + if "A" in image.getbands(): + self.degenerate.putalpha(image.getchannel("A")) + + +class Sharpness(_Enhance): + """Adjust image sharpness. + + This class can be used to adjust the sharpness of an image. An + enhancement factor of 0.0 gives a blurred image, a factor of 1.0 gives the + original image, and a factor of 2.0 gives a sharpened image. + """ + + def __init__(self, image): + self.image = image + self.degenerate = image.filter(ImageFilter.SMOOTH) + + if "A" in image.getbands(): + self.degenerate.putalpha(image.getchannel("A")) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFile.py new file mode 100644 index 00000000..0923979a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFile.py @@ -0,0 +1,795 @@ +# +# The Python Imaging Library. +# $Id$ +# +# base class for image file handlers +# +# history: +# 1995-09-09 fl Created +# 1996-03-11 fl Fixed load mechanism. +# 1996-04-15 fl Added pcx/xbm decoders. +# 1996-04-30 fl Added encoders. +# 1996-12-14 fl Added load helpers +# 1997-01-11 fl Use encode_to_file where possible +# 1997-08-27 fl Flush output in _save +# 1998-03-05 fl Use memory mapping for some modes +# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B" +# 1999-05-31 fl Added image parser +# 2000-10-12 fl Set readonly flag on memory-mapped images +# 2002-03-20 fl Use better messages for common decoder errors +# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available +# 2003-10-30 fl Added StubImageFile class +# 2004-02-25 fl Made incremental parser more robust +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import itertools +import struct +import sys +from typing import Any, NamedTuple + +from . import Image +from ._deprecate import deprecate +from ._util import is_path + +MAXBLOCK = 65536 + +SAFEBLOCK = 1024 * 1024 + +LOAD_TRUNCATED_IMAGES = False +"""Whether or not to load truncated image files. User code may change this.""" + +ERRORS = { + -1: "image buffer overrun error", + -2: "decoding error", + -3: "unknown error", + -8: "bad configuration", + -9: "out of memory error", +} +""" +Dict of known error codes returned from :meth:`.PyDecoder.decode`, +:meth:`.PyEncoder.encode` :meth:`.PyEncoder.encode_to_pyfd` and +:meth:`.PyEncoder.encode_to_file`. +""" + + +# +# -------------------------------------------------------------------- +# Helpers + + +def _get_oserror(error, *, encoder): + try: + msg = Image.core.getcodecstatus(error) + except AttributeError: + msg = ERRORS.get(error) + if not msg: + msg = f"{'encoder' if encoder else 'decoder'} error {error}" + msg += f" when {'writing' if encoder else 'reading'} image file" + return OSError(msg) + + +def raise_oserror(error): + deprecate( + "raise_oserror", + 12, + action="It is only useful for translating error codes returned by a codec's " + "decode() method, which ImageFile already does automatically.", + ) + raise _get_oserror(error, encoder=False) + + +def _tilesort(t): + # sort on offset + return t[2] + + +class _Tile(NamedTuple): + encoder_name: str + extents: tuple[int, int, int, int] + offset: int + args: tuple[Any, ...] | str | None + + +# +# -------------------------------------------------------------------- +# ImageFile base class + + +class ImageFile(Image.Image): + """Base class for image file format handlers.""" + + def __init__(self, fp=None, filename=None): + super().__init__() + + self._min_frame = 0 + + self.custom_mimetype = None + + self.tile = None + """ A list of tile descriptors, or ``None`` """ + + self.readonly = 1 # until we know better + + self.decoderconfig = () + self.decodermaxblock = MAXBLOCK + + if is_path(fp): + # filename + self.fp = open(fp, "rb") + self.filename = fp + self._exclusive_fp = True + else: + # stream + self.fp = fp + self.filename = filename + # can be overridden + self._exclusive_fp = None + + try: + try: + self._open() + except ( + IndexError, # end of data + TypeError, # end of data (ord) + KeyError, # unsupported mode + EOFError, # got header but not the first frame + struct.error, + ) as v: + raise SyntaxError(v) from v + + if not self.mode or self.size[0] <= 0 or self.size[1] <= 0: + msg = "not identified by this driver" + raise SyntaxError(msg) + except BaseException: + # close the file only if we have opened it this constructor + if self._exclusive_fp: + self.fp.close() + raise + + def get_format_mimetype(self): + if self.custom_mimetype: + return self.custom_mimetype + if self.format is not None: + return Image.MIME.get(self.format.upper()) + + def __setstate__(self, state): + self.tile = [] + super().__setstate__(state) + + def verify(self): + """Check file integrity""" + + # raise exception if something's wrong. must be called + # directly after open, and closes file when finished. + if self._exclusive_fp: + self.fp.close() + self.fp = None + + def load(self): + """Load image data based on tile list""" + + if self.tile is None: + msg = "cannot load this image" + raise OSError(msg) + + pixel = Image.Image.load(self) + if not self.tile: + return pixel + + self.map = None + use_mmap = self.filename and len(self.tile) == 1 + # As of pypy 2.1.0, memory mapping was failing here. + use_mmap = use_mmap and not hasattr(sys, "pypy_version_info") + + readonly = 0 + + # look for read/seek overrides + try: + read = self.load_read + # don't use mmap if there are custom read/seek functions + use_mmap = False + except AttributeError: + read = self.fp.read + + try: + seek = self.load_seek + use_mmap = False + except AttributeError: + seek = self.fp.seek + + if use_mmap: + # try memory mapping + decoder_name, extents, offset, args = self.tile[0] + if isinstance(args, str): + args = (args, 0, 1) + if ( + decoder_name == "raw" + and len(args) >= 3 + and args[0] == self.mode + and args[0] in Image._MAPMODES + ): + try: + # use mmap, if possible + import mmap + + with open(self.filename) as fp: + self.map = mmap.mmap(fp.fileno(), 0, access=mmap.ACCESS_READ) + if offset + self.size[1] * args[1] > self.map.size(): + msg = "buffer is not large enough" + raise OSError(msg) + self.im = Image.core.map_buffer( + self.map, self.size, decoder_name, offset, args + ) + readonly = 1 + # After trashing self.im, + # we might need to reload the palette data. + if self.palette: + self.palette.dirty = 1 + except (AttributeError, OSError, ImportError): + self.map = None + + self.load_prepare() + err_code = -3 # initialize to unknown error + if not self.map: + # sort tiles in file order + self.tile.sort(key=_tilesort) + + try: + # FIXME: This is a hack to handle TIFF's JpegTables tag. + prefix = self.tile_prefix + except AttributeError: + prefix = b"" + + # Remove consecutive duplicates that only differ by their offset + self.tile = [ + list(tiles)[-1] + for _, tiles in itertools.groupby( + self.tile, lambda tile: (tile[0], tile[1], tile[3]) + ) + ] + for decoder_name, extents, offset, args in self.tile: + seek(offset) + decoder = Image._getdecoder( + self.mode, decoder_name, args, self.decoderconfig + ) + try: + decoder.setimage(self.im, extents) + if decoder.pulls_fd: + decoder.setfd(self.fp) + err_code = decoder.decode(b"")[1] + else: + b = prefix + while True: + try: + s = read(self.decodermaxblock) + except (IndexError, struct.error) as e: + # truncated png/gif + if LOAD_TRUNCATED_IMAGES: + break + else: + msg = "image file is truncated" + raise OSError(msg) from e + + if not s: # truncated jpeg + if LOAD_TRUNCATED_IMAGES: + break + else: + msg = ( + "image file is truncated " + f"({len(b)} bytes not processed)" + ) + raise OSError(msg) + + b = b + s + n, err_code = decoder.decode(b) + if n < 0: + break + b = b[n:] + finally: + # Need to cleanup here to prevent leaks + decoder.cleanup() + + self.tile = [] + self.readonly = readonly + + self.load_end() + + if self._exclusive_fp and self._close_exclusive_fp_after_loading: + self.fp.close() + self.fp = None + + if not self.map and not LOAD_TRUNCATED_IMAGES and err_code < 0: + # still raised if decoder fails to return anything + raise _get_oserror(err_code, encoder=False) + + return Image.Image.load(self) + + def load_prepare(self): + # create image memory if necessary + if not self.im or self.im.mode != self.mode or self.im.size != self.size: + self.im = Image.core.new(self.mode, self.size) + # create palette (optional) + if self.mode == "P": + Image.Image.load(self) + + def load_end(self): + # may be overridden + pass + + # may be defined for contained formats + # def load_seek(self, pos): + # pass + + # may be defined for blocked formats (e.g. PNG) + # def load_read(self, bytes): + # pass + + def _seek_check(self, frame): + if ( + frame < self._min_frame + # Only check upper limit on frames if additional seek operations + # are not required to do so + or ( + not (hasattr(self, "_n_frames") and self._n_frames is None) + and frame >= self.n_frames + self._min_frame + ) + ): + msg = "attempt to seek outside sequence" + raise EOFError(msg) + + return self.tell() != frame + + +class StubImageFile(ImageFile): + """ + Base class for stub image loaders. + + A stub loader is an image loader that can identify files of a + certain format, but relies on external code to load the file. + """ + + def _open(self): + msg = "StubImageFile subclass must implement _open" + raise NotImplementedError(msg) + + def load(self): + loader = self._load() + if loader is None: + msg = f"cannot find loader for this {self.format} file" + raise OSError(msg) + image = loader.load(self) + assert image is not None + # become the other object (!) + self.__class__ = image.__class__ + self.__dict__ = image.__dict__ + return image.load() + + def _load(self): + """(Hook) Find actual image loader.""" + msg = "StubImageFile subclass must implement _load" + raise NotImplementedError(msg) + + +class Parser: + """ + Incremental image parser. This class implements the standard + feed/close consumer interface. + """ + + incremental = None + image = None + data = None + decoder = None + offset = 0 + finished = 0 + + def reset(self): + """ + (Consumer) Reset the parser. Note that you can only call this + method immediately after you've created a parser; parser + instances cannot be reused. + """ + assert self.data is None, "cannot reuse parsers" + + def feed(self, data): + """ + (Consumer) Feed data to the parser. + + :param data: A string buffer. + :exception OSError: If the parser failed to parse the image file. + """ + # collect data + + if self.finished: + return + + if self.data is None: + self.data = data + else: + self.data = self.data + data + + # parse what we have + if self.decoder: + if self.offset > 0: + # skip header + skip = min(len(self.data), self.offset) + self.data = self.data[skip:] + self.offset = self.offset - skip + if self.offset > 0 or not self.data: + return + + n, e = self.decoder.decode(self.data) + + if n < 0: + # end of stream + self.data = None + self.finished = 1 + if e < 0: + # decoding error + self.image = None + raise _get_oserror(e, encoder=False) + else: + # end of image + return + self.data = self.data[n:] + + elif self.image: + # if we end up here with no decoder, this file cannot + # be incrementally parsed. wait until we've gotten all + # available data + pass + + else: + # attempt to open this file + try: + with io.BytesIO(self.data) as fp: + im = Image.open(fp) + except OSError: + pass # not enough data + else: + flag = hasattr(im, "load_seek") or hasattr(im, "load_read") + if flag or len(im.tile) != 1: + # custom load code, or multiple tiles + self.decode = None + else: + # initialize decoder + im.load_prepare() + d, e, o, a = im.tile[0] + im.tile = [] + self.decoder = Image._getdecoder(im.mode, d, a, im.decoderconfig) + self.decoder.setimage(im.im, e) + + # calculate decoder offset + self.offset = o + if self.offset <= len(self.data): + self.data = self.data[self.offset :] + self.offset = 0 + + self.image = im + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def close(self): + """ + (Consumer) Close the stream. + + :returns: An image object. + :exception OSError: If the parser failed to parse the image file either + because it cannot be identified or cannot be + decoded. + """ + # finish decoding + if self.decoder: + # get rid of what's left in the buffers + self.feed(b"") + self.data = self.decoder = None + if not self.finished: + msg = "image was incomplete" + raise OSError(msg) + if not self.image: + msg = "cannot parse this image" + raise OSError(msg) + if self.data: + # incremental parsing not possible; reopen the file + # not that we have all data + with io.BytesIO(self.data) as fp: + try: + self.image = Image.open(fp) + finally: + self.image.load() + return self.image + + +# -------------------------------------------------------------------- + + +def _save(im, fp, tile, bufsize=0): + """Helper to save image based on tile list + + :param im: Image object. + :param fp: File object. + :param tile: Tile list. + :param bufsize: Optional buffer size + """ + + im.load() + if not hasattr(im, "encoderconfig"): + im.encoderconfig = () + tile.sort(key=_tilesort) + # FIXME: make MAXBLOCK a configuration parameter + # It would be great if we could have the encoder specify what it needs + # But, it would need at least the image size in most cases. RawEncode is + # a tricky case. + bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c + try: + fh = fp.fileno() + fp.flush() + _encode_tile(im, fp, tile, bufsize, fh) + except (AttributeError, io.UnsupportedOperation) as exc: + _encode_tile(im, fp, tile, bufsize, None, exc) + if hasattr(fp, "flush"): + fp.flush() + + +def _encode_tile(im, fp, tile: list[_Tile], bufsize, fh, exc=None): + for encoder_name, extents, offset, args in tile: + if offset > 0: + fp.seek(offset) + encoder = Image._getencoder(im.mode, encoder_name, args, im.encoderconfig) + try: + encoder.setimage(im.im, extents) + if encoder.pushes_fd: + encoder.setfd(fp) + errcode = encoder.encode_to_pyfd()[1] + else: + if exc: + # compress to Python file-compatible object + while True: + errcode, data = encoder.encode(bufsize)[1:] + fp.write(data) + if errcode: + break + else: + # slight speedup: compress to real file object + errcode = encoder.encode_to_file(fh, bufsize) + if errcode < 0: + raise _get_oserror(errcode, encoder=True) from exc + finally: + encoder.cleanup() + + +def _safe_read(fp, size): + """ + Reads large blocks in a safe way. Unlike fp.read(n), this function + doesn't trust the user. If the requested size is larger than + SAFEBLOCK, the file is read block by block. + + :param fp: File handle. Must implement a read method. + :param size: Number of bytes to read. + :returns: A string containing size bytes of data. + + Raises an OSError if the file is truncated and the read cannot be completed + + """ + if size <= 0: + return b"" + if size <= SAFEBLOCK: + data = fp.read(size) + if len(data) < size: + msg = "Truncated File Read" + raise OSError(msg) + return data + data = [] + remaining_size = size + while remaining_size > 0: + block = fp.read(min(remaining_size, SAFEBLOCK)) + if not block: + break + data.append(block) + remaining_size -= len(block) + if sum(len(d) for d in data) < size: + msg = "Truncated File Read" + raise OSError(msg) + return b"".join(data) + + +class PyCodecState: + def __init__(self): + self.xsize = 0 + self.ysize = 0 + self.xoff = 0 + self.yoff = 0 + + def extents(self): + return self.xoff, self.yoff, self.xoff + self.xsize, self.yoff + self.ysize + + +class PyCodec: + def __init__(self, mode, *args): + self.im = None + self.state = PyCodecState() + self.fd = None + self.mode = mode + self.init(args) + + def init(self, args): + """ + Override to perform codec specific initialization + + :param args: Array of args items from the tile entry + :returns: None + """ + self.args = args + + def cleanup(self): + """ + Override to perform codec specific cleanup + + :returns: None + """ + pass + + def setfd(self, fd): + """ + Called from ImageFile to set the Python file-like object + + :param fd: A Python file-like object + :returns: None + """ + self.fd = fd + + def setimage(self, im, extents=None): + """ + Called from ImageFile to set the core output image for the codec + + :param im: A core image object + :param extents: a 4 tuple of (x0, y0, x1, y1) defining the rectangle + for this tile + :returns: None + """ + + # following c code + self.im = im + + if extents: + (x0, y0, x1, y1) = extents + else: + (x0, y0, x1, y1) = (0, 0, 0, 0) + + if x0 == 0 and x1 == 0: + self.state.xsize, self.state.ysize = self.im.size + else: + self.state.xoff = x0 + self.state.yoff = y0 + self.state.xsize = x1 - x0 + self.state.ysize = y1 - y0 + + if self.state.xsize <= 0 or self.state.ysize <= 0: + msg = "Size cannot be negative" + raise ValueError(msg) + + if ( + self.state.xsize + self.state.xoff > self.im.size[0] + or self.state.ysize + self.state.yoff > self.im.size[1] + ): + msg = "Tile cannot extend outside image" + raise ValueError(msg) + + +class PyDecoder(PyCodec): + """ + Python implementation of a format decoder. Override this class and + add the decoding logic in the :meth:`decode` method. + + See :ref:`Writing Your Own File Codec in Python` + """ + + _pulls_fd = False + + @property + def pulls_fd(self): + return self._pulls_fd + + def decode(self, buffer): + """ + Override to perform the decoding process. + + :param buffer: A bytes object with the data to be decoded. + :returns: A tuple of ``(bytes consumed, errcode)``. + If finished with decoding return -1 for the bytes consumed. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + msg = "unavailable in base decoder" + raise NotImplementedError(msg) + + def set_as_raw(self, data, rawmode=None): + """ + Convenience method to set the internal image from a stream of raw data + + :param data: Bytes to be set + :param rawmode: The rawmode to be used for the decoder. + If not specified, it will default to the mode of the image + :returns: None + """ + + if not rawmode: + rawmode = self.mode + d = Image._getdecoder(self.mode, "raw", rawmode) + d.setimage(self.im, self.state.extents()) + s = d.decode(data) + + if s[0] >= 0: + msg = "not enough image data" + raise ValueError(msg) + if s[1] != 0: + msg = "cannot decode image data" + raise ValueError(msg) + + +class PyEncoder(PyCodec): + """ + Python implementation of a format encoder. Override this class and + add the decoding logic in the :meth:`encode` method. + + See :ref:`Writing Your Own File Codec in Python` + """ + + _pushes_fd = False + + @property + def pushes_fd(self): + return self._pushes_fd + + def encode(self, bufsize): + """ + Override to perform the encoding process. + + :param bufsize: Buffer size. + :returns: A tuple of ``(bytes encoded, errcode, bytes)``. + If finished with encoding return 1 for the error code. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + msg = "unavailable in base encoder" + raise NotImplementedError(msg) + + def encode_to_pyfd(self): + """ + If ``pushes_fd`` is ``True``, then this method will be used, + and ``encode()`` will only be called once. + + :returns: A tuple of ``(bytes consumed, errcode)``. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + if not self.pushes_fd: + return 0, -8 # bad configuration + bytes_consumed, errcode, data = self.encode(0) + if data: + self.fd.write(data) + return bytes_consumed, errcode + + def encode_to_file(self, fh, bufsize): + """ + :param fh: File handle. + :param bufsize: Buffer size. + + :returns: If finished successfully, return 0. + Otherwise, return an error code. Err codes are from + :data:`.ImageFile.ERRORS`. + """ + errcode = 0 + while errcode == 0: + status, errcode, buf = self.encode(bufsize) + if status > 0: + fh.write(buf[status:]) + return errcode diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFilter.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFilter.py new file mode 100644 index 00000000..035b83c4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFilter.py @@ -0,0 +1,568 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard filters +# +# History: +# 1995-11-27 fl Created +# 2002-06-08 fl Added rank and mode filters +# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2002 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import functools + + +class Filter: + pass + + +class MultibandFilter(Filter): + pass + + +class BuiltinFilter(MultibandFilter): + def filter(self, image): + if image.mode == "P": + msg = "cannot filter palette images" + raise ValueError(msg) + return image.filter(*self.filterargs) + + +class Kernel(BuiltinFilter): + """ + Create a convolution kernel. The current version only + supports 3x3 and 5x5 integer and floating point kernels. + + In the current version, kernels can only be applied to + "L" and "RGB" images. + + :param size: Kernel size, given as (width, height). In the current + version, this must be (3,3) or (5,5). + :param kernel: A sequence containing kernel weights. The kernel will + be flipped vertically before being applied to the image. + :param scale: Scale factor. If given, the result for each pixel is + divided by this value. The default is the sum of the + kernel weights. + :param offset: Offset. If given, this value is added to the result, + after it has been divided by the scale factor. + """ + + name = "Kernel" + + def __init__(self, size, kernel, scale=None, offset=0): + if scale is None: + # default scale is sum of kernel + scale = functools.reduce(lambda a, b: a + b, kernel) + if size[0] * size[1] != len(kernel): + msg = "not enough coefficients in kernel" + raise ValueError(msg) + self.filterargs = size, scale, offset, kernel + + +class RankFilter(Filter): + """ + Create a rank filter. The rank filter sorts all pixels in + a window of the given size, and returns the ``rank``'th value. + + :param size: The kernel size, in pixels. + :param rank: What pixel value to pick. Use 0 for a min filter, + ``size * size / 2`` for a median filter, ``size * size - 1`` + for a max filter, etc. + """ + + name = "Rank" + + def __init__(self, size, rank): + self.size = size + self.rank = rank + + def filter(self, image): + if image.mode == "P": + msg = "cannot filter palette images" + raise ValueError(msg) + image = image.expand(self.size // 2, self.size // 2) + return image.rankfilter(self.size, self.rank) + + +class MedianFilter(RankFilter): + """ + Create a median filter. Picks the median pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Median" + + def __init__(self, size=3): + self.size = size + self.rank = size * size // 2 + + +class MinFilter(RankFilter): + """ + Create a min filter. Picks the lowest pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Min" + + def __init__(self, size=3): + self.size = size + self.rank = 0 + + +class MaxFilter(RankFilter): + """ + Create a max filter. Picks the largest pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Max" + + def __init__(self, size=3): + self.size = size + self.rank = size * size - 1 + + +class ModeFilter(Filter): + """ + Create a mode filter. Picks the most frequent pixel value in a box with the + given size. Pixel values that occur only once or twice are ignored; if no + pixel value occurs more than twice, the original pixel value is preserved. + + :param size: The kernel size, in pixels. + """ + + name = "Mode" + + def __init__(self, size=3): + self.size = size + + def filter(self, image): + return image.modefilter(self.size) + + +class GaussianBlur(MultibandFilter): + """Blurs the image with a sequence of extended box filters, which + approximates a Gaussian kernel. For details on accuracy see + + + :param radius: Standard deviation of the Gaussian kernel. Either a sequence of two + numbers for x and y, or a single number for both. + """ + + name = "GaussianBlur" + + def __init__(self, radius=2): + self.radius = radius + + def filter(self, image): + xy = self.radius + if not isinstance(xy, (tuple, list)): + xy = (xy, xy) + if xy == (0, 0): + return image.copy() + return image.gaussian_blur(xy) + + +class BoxBlur(MultibandFilter): + """Blurs the image by setting each pixel to the average value of the pixels + in a square box extending radius pixels in each direction. + Supports float radius of arbitrary size. Uses an optimized implementation + which runs in linear time relative to the size of the image + for any radius value. + + :param radius: Size of the box in a direction. Either a sequence of two numbers for + x and y, or a single number for both. + + Radius 0 does not blur, returns an identical image. + Radius 1 takes 1 pixel in each direction, i.e. 9 pixels in total. + """ + + name = "BoxBlur" + + def __init__(self, radius): + xy = radius + if not isinstance(xy, (tuple, list)): + xy = (xy, xy) + if xy[0] < 0 or xy[1] < 0: + msg = "radius must be >= 0" + raise ValueError(msg) + self.radius = radius + + def filter(self, image): + xy = self.radius + if not isinstance(xy, (tuple, list)): + xy = (xy, xy) + if xy == (0, 0): + return image.copy() + return image.box_blur(xy) + + +class UnsharpMask(MultibandFilter): + """Unsharp mask filter. + + See Wikipedia's entry on `digital unsharp masking`_ for an explanation of + the parameters. + + :param radius: Blur Radius + :param percent: Unsharp strength, in percent + :param threshold: Threshold controls the minimum brightness change that + will be sharpened + + .. _digital unsharp masking: https://en.wikipedia.org/wiki/Unsharp_masking#Digital_unsharp_masking + + """ + + name = "UnsharpMask" + + def __init__(self, radius=2, percent=150, threshold=3): + self.radius = radius + self.percent = percent + self.threshold = threshold + + def filter(self, image): + return image.unsharp_mask(self.radius, self.percent, self.threshold) + + +class BLUR(BuiltinFilter): + name = "Blur" + # fmt: off + filterargs = (5, 5), 16, 0, ( + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, + ) + # fmt: on + + +class CONTOUR(BuiltinFilter): + name = "Contour" + # fmt: off + filterargs = (3, 3), 1, 255, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1, + ) + # fmt: on + + +class DETAIL(BuiltinFilter): + name = "Detail" + # fmt: off + filterargs = (3, 3), 6, 0, ( + 0, -1, 0, + -1, 10, -1, + 0, -1, 0, + ) + # fmt: on + + +class EDGE_ENHANCE(BuiltinFilter): + name = "Edge-enhance" + # fmt: off + filterargs = (3, 3), 2, 0, ( + -1, -1, -1, + -1, 10, -1, + -1, -1, -1, + ) + # fmt: on + + +class EDGE_ENHANCE_MORE(BuiltinFilter): + name = "Edge-enhance More" + # fmt: off + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 9, -1, + -1, -1, -1, + ) + # fmt: on + + +class EMBOSS(BuiltinFilter): + name = "Emboss" + # fmt: off + filterargs = (3, 3), 1, 128, ( + -1, 0, 0, + 0, 1, 0, + 0, 0, 0, + ) + # fmt: on + + +class FIND_EDGES(BuiltinFilter): + name = "Find Edges" + # fmt: off + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1, + ) + # fmt: on + + +class SHARPEN(BuiltinFilter): + name = "Sharpen" + # fmt: off + filterargs = (3, 3), 16, 0, ( + -2, -2, -2, + -2, 32, -2, + -2, -2, -2, + ) + # fmt: on + + +class SMOOTH(BuiltinFilter): + name = "Smooth" + # fmt: off + filterargs = (3, 3), 13, 0, ( + 1, 1, 1, + 1, 5, 1, + 1, 1, 1, + ) + # fmt: on + + +class SMOOTH_MORE(BuiltinFilter): + name = "Smooth More" + # fmt: off + filterargs = (5, 5), 100, 0, ( + 1, 1, 1, 1, 1, + 1, 5, 5, 5, 1, + 1, 5, 44, 5, 1, + 1, 5, 5, 5, 1, + 1, 1, 1, 1, 1, + ) + # fmt: on + + +class Color3DLUT(MultibandFilter): + """Three-dimensional color lookup table. + + Transforms 3-channel pixels using the values of the channels as coordinates + in the 3D lookup table and interpolating the nearest elements. + + This method allows you to apply almost any color transformation + in constant time by using pre-calculated decimated tables. + + .. versionadded:: 5.2.0 + + :param size: Size of the table. One int or tuple of (int, int, int). + Minimal size in any dimension is 2, maximum is 65. + :param table: Flat lookup table. A list of ``channels * size**3`` + float elements or a list of ``size**3`` channels-sized + tuples with floats. Channels are changed first, + then first dimension, then second, then third. + Value 0.0 corresponds lowest value of output, 1.0 highest. + :param channels: Number of channels in the table. Could be 3 or 4. + Default is 3. + :param target_mode: A mode for the result image. Should have not less + than ``channels`` channels. Default is ``None``, + which means that mode wouldn't be changed. + """ + + name = "Color 3D LUT" + + def __init__(self, size, table, channels=3, target_mode=None, **kwargs): + if channels not in (3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + self.size = size = self._check_size(size) + self.channels = channels + self.mode = target_mode + + # Hidden flag `_copy_table=False` could be used to avoid extra copying + # of the table if the table is specially made for the constructor. + copy_table = kwargs.get("_copy_table", True) + items = size[0] * size[1] * size[2] + wrong_size = False + + numpy = None + if hasattr(table, "shape"): + try: + import numpy + except ImportError: + pass + + if numpy and isinstance(table, numpy.ndarray): + if copy_table: + table = table.copy() + + if table.shape in [ + (items * channels,), + (items, channels), + (size[2], size[1], size[0], channels), + ]: + table = table.reshape(items * channels) + else: + wrong_size = True + + else: + if copy_table: + table = list(table) + + # Convert to a flat list + if table and isinstance(table[0], (list, tuple)): + table, raw_table = [], table + for pixel in raw_table: + if len(pixel) != channels: + msg = ( + "The elements of the table should " + f"have a length of {channels}." + ) + raise ValueError(msg) + table.extend(pixel) + + if wrong_size or len(table) != items * channels: + msg = ( + "The table should have either channels * size**3 float items " + "or size**3 items of channels-sized tuples with floats. " + f"Table should be: {channels}x{size[0]}x{size[1]}x{size[2]}. " + f"Actual length: {len(table)}" + ) + raise ValueError(msg) + self.table = table + + @staticmethod + def _check_size(size): + try: + _, _, _ = size + except ValueError as e: + msg = "Size should be either an integer or a tuple of three integers." + raise ValueError(msg) from e + except TypeError: + size = (size, size, size) + size = [int(x) for x in size] + for size_1d in size: + if not 2 <= size_1d <= 65: + msg = "Size should be in [2, 65] range." + raise ValueError(msg) + return size + + @classmethod + def generate(cls, size, callback, channels=3, target_mode=None): + """Generates new LUT using provided callback. + + :param size: Size of the table. Passed to the constructor. + :param callback: Function with three parameters which correspond + three color channels. Will be called ``size**3`` + times with values from 0.0 to 1.0 and should return + a tuple with ``channels`` elements. + :param channels: The number of channels which should return callback. + :param target_mode: Passed to the constructor of the resulting + lookup table. + """ + size_1d, size_2d, size_3d = cls._check_size(size) + if channels not in (3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + + table = [0] * (size_1d * size_2d * size_3d * channels) + idx_out = 0 + for b in range(size_3d): + for g in range(size_2d): + for r in range(size_1d): + table[idx_out : idx_out + channels] = callback( + r / (size_1d - 1), g / (size_2d - 1), b / (size_3d - 1) + ) + idx_out += channels + + return cls( + (size_1d, size_2d, size_3d), + table, + channels=channels, + target_mode=target_mode, + _copy_table=False, + ) + + def transform(self, callback, with_normals=False, channels=None, target_mode=None): + """Transforms the table values using provided callback and returns + a new LUT with altered values. + + :param callback: A function which takes old lookup table values + and returns a new set of values. The number + of arguments which function should take is + ``self.channels`` or ``3 + self.channels`` + if ``with_normals`` flag is set. + Should return a tuple of ``self.channels`` or + ``channels`` elements if it is set. + :param with_normals: If true, ``callback`` will be called with + coordinates in the color cube as the first + three arguments. Otherwise, ``callback`` + will be called only with actual color values. + :param channels: The number of channels in the resulting lookup table. + :param target_mode: Passed to the constructor of the resulting + lookup table. + """ + if channels not in (None, 3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + ch_in = self.channels + ch_out = channels or ch_in + size_1d, size_2d, size_3d = self.size + + table = [0] * (size_1d * size_2d * size_3d * ch_out) + idx_in = 0 + idx_out = 0 + for b in range(size_3d): + for g in range(size_2d): + for r in range(size_1d): + values = self.table[idx_in : idx_in + ch_in] + if with_normals: + values = callback( + r / (size_1d - 1), + g / (size_2d - 1), + b / (size_3d - 1), + *values, + ) + else: + values = callback(*values) + table[idx_out : idx_out + ch_out] = values + idx_in += ch_in + idx_out += ch_out + + return type(self)( + self.size, + table, + channels=ch_out, + target_mode=target_mode or self.mode, + _copy_table=False, + ) + + def __repr__(self): + r = [ + f"{self.__class__.__name__} from {self.table.__class__.__name__}", + "size={:d}x{:d}x{:d}".format(*self.size), + f"channels={self.channels:d}", + ] + if self.mode: + r.append(f"target_mode={self.mode}") + return "<{}>".format(" ".join(r)) + + def filter(self, image): + from . import Image + + return image.color_lut_3d( + self.mode or image.mode, + Image.Resampling.BILINEAR, + self.channels, + self.size[0], + self.size[1], + self.size[2], + self.table, + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFont.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFont.py new file mode 100644 index 00000000..8213d030 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFont.py @@ -0,0 +1,1264 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIL raster font management +# +# History: +# 1996-08-07 fl created (experimental) +# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3 +# 1999-02-06 fl rewrote most font management stuff in C +# 1999-03-17 fl take pth files into account in load_path (from Richard Jones) +# 2001-02-17 fl added freetype support +# 2001-05-09 fl added TransposedFont wrapper class +# 2002-03-04 fl make sure we have a "L" or "1" font +# 2002-12-04 fl skip non-directory entries in the system path +# 2003-04-29 fl add embedded default font +# 2003-09-27 fl added support for truetype charmap encodings +# +# Todo: +# Adapt to PILFONT2 format (16-bit fonts, compressed, single file) +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +import base64 +import os +import sys +import warnings +from enum import IntEnum +from io import BytesIO +from pathlib import Path +from typing import BinaryIO + +from . import Image +from ._util import is_directory, is_path + + +class Layout(IntEnum): + BASIC = 0 + RAQM = 1 + + +MAX_STRING_LENGTH = 1_000_000 + + +try: + from . import _imagingft as core +except ImportError as ex: + from ._util import DeferredError + + core = DeferredError.new(ex) + + +def _string_length_check(text): + if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH: + msg = "too many characters in string" + raise ValueError(msg) + + +# FIXME: add support for pilfont2 format (see FontFile.py) + +# -------------------------------------------------------------------- +# Font metrics format: +# "PILfont" LF +# fontdescriptor LF +# (optional) key=value... LF +# "DATA" LF +# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox) +# +# To place a character, cut out srcbox and paste at dstbox, +# relative to the character position. Then move the character +# position according to dx, dy. +# -------------------------------------------------------------------- + + +class ImageFont: + """PIL font wrapper""" + + def _load_pilfont(self, filename): + with open(filename, "rb") as fp: + image = None + for ext in (".png", ".gif", ".pbm"): + if image: + image.close() + try: + fullname = os.path.splitext(filename)[0] + ext + image = Image.open(fullname) + except Exception: + pass + else: + if image and image.mode in ("1", "L"): + break + else: + if image: + image.close() + msg = "cannot find glyph data file" + raise OSError(msg) + + self.file = fullname + + self._load_pilfont_data(fp, image) + image.close() + + def _load_pilfont_data(self, file, image): + # read PILfont header + if file.readline() != b"PILfont\n": + msg = "Not a PILfont file" + raise SyntaxError(msg) + file.readline().split(b";") + self.info = [] # FIXME: should be a dictionary + while True: + s = file.readline() + if not s or s == b"DATA\n": + break + self.info.append(s) + + # read PILfont metrics + data = file.read(256 * 20) + + # check image + if image.mode not in ("1", "L"): + msg = "invalid font image mode" + raise TypeError(msg) + + image.load() + + self.font = Image.core.font(image.im, data) + + def getmask(self, text, mode="", *args, **kwargs): + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :return: An internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module. + """ + _string_length_check(text) + Image._decompression_bomb_check(self.font.getsize(text)) + return self.font.getmask(text, mode) + + def getbbox(self, text, *args, **kwargs): + """ + Returns bounding box (in pixels) of given text. + + .. versionadded:: 9.2.0 + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + :return: ``(left, top, right, bottom)`` bounding box + """ + _string_length_check(text) + width, height = self.font.getsize(text) + return 0, 0, width, height + + def getlength(self, text, *args, **kwargs): + """ + Returns length (in pixels) of given text. + This is the amount by which following text should be offset. + + .. versionadded:: 9.2.0 + """ + _string_length_check(text) + width, height = self.font.getsize(text) + return width + + +## +# Wrapper for FreeType fonts. Application code should use the +# truetype factory function to create font objects. + + +class FreeTypeFont: + """FreeType font wrapper (requires _imagingft service)""" + + def __init__( + self, + font: bytes | str | Path | BinaryIO | None = None, + size: float = 10, + index: int = 0, + encoding: str = "", + layout_engine: Layout | None = None, + ) -> None: + # FIXME: use service provider instead + + if size <= 0: + msg = "font size must be greater than 0" + raise ValueError(msg) + + self.path = font + self.size = size + self.index = index + self.encoding = encoding + + if layout_engine not in (Layout.BASIC, Layout.RAQM): + layout_engine = Layout.BASIC + if core.HAVE_RAQM: + layout_engine = Layout.RAQM + elif layout_engine == Layout.RAQM and not core.HAVE_RAQM: + warnings.warn( + "Raqm layout was requested, but Raqm is not available. " + "Falling back to basic layout." + ) + layout_engine = Layout.BASIC + + self.layout_engine = layout_engine + + def load_from_bytes(f): + self.font_bytes = f.read() + self.font = core.getfont( + "", size, index, encoding, self.font_bytes, layout_engine + ) + + if is_path(font): + if isinstance(font, Path): + font = str(font) + if sys.platform == "win32": + font_bytes_path = font if isinstance(font, bytes) else font.encode() + try: + font_bytes_path.decode("ascii") + except UnicodeDecodeError: + # FreeType cannot load fonts with non-ASCII characters on Windows + # So load it into memory first + with open(font, "rb") as f: + load_from_bytes(f) + return + self.font = core.getfont( + font, size, index, encoding, layout_engine=layout_engine + ) + else: + load_from_bytes(font) + + def __getstate__(self): + return [self.path, self.size, self.index, self.encoding, self.layout_engine] + + def __setstate__(self, state): + path, size, index, encoding, layout_engine = state + self.__init__(path, size, index, encoding, layout_engine) + + def getname(self): + """ + :return: A tuple of the font family (e.g. Helvetica) and the font style + (e.g. Bold) + """ + return self.font.family, self.font.style + + def getmetrics(self): + """ + :return: A tuple of the font ascent (the distance from the baseline to + the highest outline point) and descent (the distance from the + baseline to the lowest outline point, a negative value) + """ + return self.font.ascent, self.font.descent + + def getlength(self, text, mode="", direction=None, features=None, language=None): + """ + Returns length (in pixels with 1/64 precision) of given text when rendered + in font with provided direction, features, and language. + + This is the amount by which following text should be offset. + Text bounding box may extend past the length in some fonts, + e.g. when using italics or accents. + + The result is returned as a float; it is a whole number if using basic layout. + + Note that the sum of two lengths may not equal the length of a concatenated + string due to kerning. If you need to adjust for kerning, include the following + character and subtract its length. + + For example, instead of :: + + hello = font.getlength("Hello") + world = font.getlength("World") + hello_world = hello + world # not adjusted for kerning + assert hello_world == font.getlength("HelloWorld") # may fail + + use :: + + hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning + world = font.getlength("World") + hello_world = hello + world # adjusted for kerning + assert hello_world == font.getlength("HelloWorld") # True + + or disable kerning with (requires libraqm) :: + + hello = draw.textlength("Hello", font, features=["-kern"]) + world = draw.textlength("World", font, features=["-kern"]) + hello_world = hello + world # kerning is disabled, no need to adjust + assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"]) + + .. versionadded:: 8.0.0 + + :param text: Text to measure. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + :return: Either width for horizontal text, or height for vertical text. + """ + _string_length_check(text) + return self.font.getlength(text, mode, direction, features, language) / 64 + + def getbbox( + self, + text, + mode="", + direction=None, + features=None, + language=None, + stroke_width=0, + anchor=None, + ): + """ + Returns bounding box (in pixels) of given text relative to given anchor + when rendered in font with provided direction, features, and language. + + Use :py:meth:`getlength()` to get the offset of following text with + 1/64 pixel precision. The bounding box includes extra margins for + some fonts, e.g. italics or accents. + + .. versionadded:: 8.0.0 + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + :param stroke_width: The width of the text stroke. + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + :return: ``(left, top, right, bottom)`` bounding box + """ + _string_length_check(text) + size, offset = self.font.getsize( + text, mode, direction, features, language, anchor + ) + left, top = offset[0] - stroke_width, offset[1] - stroke_width + width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width + return left, top, left + width, top + height + + def getmask( + self, + text, + mode="", + direction=None, + features=None, + language=None, + stroke_width=0, + anchor=None, + ink=0, + start=None, + ): + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. If the font has embedded color data, the bitmap + should have mode ``RGBA``. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + .. versionadded:: 6.0.0 + + :param stroke_width: The width of the text stroke. + + .. versionadded:: 6.2.0 + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + .. versionadded:: 8.0.0 + + :param ink: Foreground ink for rendering in RGBA mode. + + .. versionadded:: 8.0.0 + + :param start: Tuple of horizontal and vertical offset, as text may render + differently when starting at fractional coordinates. + + .. versionadded:: 9.4.0 + + :return: An internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module. + """ + return self.getmask2( + text, + mode, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + anchor=anchor, + ink=ink, + start=start, + )[0] + + def getmask2( + self, + text, + mode="", + direction=None, + features=None, + language=None, + stroke_width=0, + anchor=None, + ink=0, + start=None, + *args, + **kwargs, + ): + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. If the font has embedded color data, the bitmap + should have mode ``RGBA``. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + .. versionadded:: 6.0.0 + + :param stroke_width: The width of the text stroke. + + .. versionadded:: 6.2.0 + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + .. versionadded:: 8.0.0 + + :param ink: Foreground ink for rendering in RGBA mode. + + .. versionadded:: 8.0.0 + + :param start: Tuple of horizontal and vertical offset, as text may render + differently when starting at fractional coordinates. + + .. versionadded:: 9.4.0 + + :return: A tuple of an internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module, and the text offset, the + gap between the starting coordinate and the first marking + """ + _string_length_check(text) + if start is None: + start = (0, 0) + im = None + size = None + + def fill(width, height): + nonlocal im, size + + size = (width, height) + if Image.MAX_IMAGE_PIXELS is not None: + pixels = max(1, width) * max(1, height) + if pixels > 2 * Image.MAX_IMAGE_PIXELS: + return + + im = Image.core.fill("RGBA" if mode == "RGBA" else "L", size) + return im + + offset = self.font.render( + text, + fill, + mode, + direction, + features, + language, + stroke_width, + anchor, + ink, + start[0], + start[1], + ) + Image._decompression_bomb_check(size) + return im, offset + + def font_variant( + self, font=None, size=None, index=None, encoding=None, layout_engine=None + ): + """ + Create a copy of this FreeTypeFont object, + using any specified arguments to override the settings. + + Parameters are identical to the parameters used to initialize this + object. + + :return: A FreeTypeFont object. + """ + if font is None: + try: + font = BytesIO(self.font_bytes) + except AttributeError: + font = self.path + return FreeTypeFont( + font=font, + size=self.size if size is None else size, + index=self.index if index is None else index, + encoding=self.encoding if encoding is None else encoding, + layout_engine=layout_engine or self.layout_engine, + ) + + def get_variation_names(self): + """ + :returns: A list of the named styles in a variation font. + :exception OSError: If the font is not a variation font. + """ + try: + names = self.font.getvarnames() + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + return [name.replace(b"\x00", b"") for name in names] + + def set_variation_by_name(self, name): + """ + :param name: The name of the style. + :exception OSError: If the font is not a variation font. + """ + names = self.get_variation_names() + if not isinstance(name, bytes): + name = name.encode() + index = names.index(name) + 1 + + if index == getattr(self, "_last_variation_index", None): + # When the same name is set twice in a row, + # there is an 'unknown freetype error' + # https://savannah.nongnu.org/bugs/?56186 + return + self._last_variation_index = index + + self.font.setvarname(index) + + def get_variation_axes(self): + """ + :returns: A list of the axes in a variation font. + :exception OSError: If the font is not a variation font. + """ + try: + axes = self.font.getvaraxes() + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + for axis in axes: + axis["name"] = axis["name"].replace(b"\x00", b"") + return axes + + def set_variation_by_axes(self, axes): + """ + :param axes: A list of values for each axis. + :exception OSError: If the font is not a variation font. + """ + try: + self.font.setvaraxes(axes) + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + + +class TransposedFont: + """Wrapper for writing rotated or mirrored text""" + + def __init__(self, font, orientation=None): + """ + Wrapper that creates a transposed font from any existing font + object. + + :param font: A font object. + :param orientation: An optional orientation. If given, this should + be one of Image.Transpose.FLIP_LEFT_RIGHT, Image.Transpose.FLIP_TOP_BOTTOM, + Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or + Image.Transpose.ROTATE_270. + """ + self.font = font + self.orientation = orientation # any 'transpose' argument, or None + + def getmask(self, text, mode="", *args, **kwargs): + im = self.font.getmask(text, mode, *args, **kwargs) + if self.orientation is not None: + return im.transpose(self.orientation) + return im + + def getbbox(self, text, *args, **kwargs): + # TransposedFont doesn't support getmask2, move top-left point to (0, 0) + # this has no effect on ImageFont and simulates anchor="lt" for FreeTypeFont + left, top, right, bottom = self.font.getbbox(text, *args, **kwargs) + width = right - left + height = bottom - top + if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): + return 0, 0, height, width + return 0, 0, width, height + + def getlength(self, text, *args, **kwargs): + if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): + msg = "text length is undefined for text rotated by 90 or 270 degrees" + raise ValueError(msg) + return self.font.getlength(text, *args, **kwargs) + + +def load(filename): + """ + Load a font file. This function loads a font object from the given + bitmap font file, and returns the corresponding font object. + + :param filename: Name of font file. + :return: A font object. + :exception OSError: If the file could not be read. + """ + f = ImageFont() + f._load_pilfont(filename) + return f + + +def truetype(font=None, size=10, index=0, encoding="", layout_engine=None): + """ + Load a TrueType or OpenType font from a file or file-like object, + and create a font object. + This function loads a font object from the given file or file-like + object, and creates a font object for a font of the given size. + + Pillow uses FreeType to open font files. On Windows, be aware that FreeType + will keep the file open as long as the FreeTypeFont object exists. Windows + limits the number of files that can be open in C at once to 512, so if many + fonts are opened simultaneously and that limit is approached, an + ``OSError`` may be thrown, reporting that FreeType "cannot open resource". + A workaround would be to copy the file(s) into memory, and open that instead. + + This function requires the _imagingft service. + + :param font: A filename or file-like object containing a TrueType font. + If the file is not found in this filename, the loader may also + search in other directories, such as the :file:`fonts/` + directory on Windows or :file:`/Library/Fonts/`, + :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on + macOS. + + :param size: The requested size, in pixels. + :param index: Which font face to load (default is first available face). + :param encoding: Which font encoding to use (default is Unicode). Possible + encodings include (see the FreeType documentation for more + information): + + * "unic" (Unicode) + * "symb" (Microsoft Symbol) + * "ADOB" (Adobe Standard) + * "ADBE" (Adobe Expert) + * "ADBC" (Adobe Custom) + * "armn" (Apple Roman) + * "sjis" (Shift JIS) + * "gb " (PRC) + * "big5" + * "wans" (Extended Wansung) + * "joha" (Johab) + * "lat1" (Latin-1) + + This specifies the character set to use. It does not alter the + encoding of any text provided in subsequent operations. + :param layout_engine: Which layout engine to use, if available: + :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`. + If it is available, Raqm layout will be used by default. + Otherwise, basic layout will be used. + + Raqm layout is recommended for all non-English text. If Raqm layout + is not required, basic layout will have better performance. + + You can check support for Raqm layout using + :py:func:`PIL.features.check_feature` with ``feature="raqm"``. + + .. versionadded:: 4.2.0 + :return: A font object. + :exception OSError: If the file could not be read. + :exception ValueError: If the font size is not greater than zero. + """ + + def freetype(font): + return FreeTypeFont(font, size, index, encoding, layout_engine) + + try: + return freetype(font) + except OSError: + if not is_path(font): + raise + ttf_filename = os.path.basename(font) + + dirs = [] + if sys.platform == "win32": + # check the windows font repository + # NOTE: must use uppercase WINDIR, to work around bugs in + # 1.5.2's os.environ.get() + windir = os.environ.get("WINDIR") + if windir: + dirs.append(os.path.join(windir, "fonts")) + elif sys.platform in ("linux", "linux2"): + lindirs = os.environ.get("XDG_DATA_DIRS") + if not lindirs: + # According to the freedesktop spec, XDG_DATA_DIRS should + # default to /usr/share + lindirs = "/usr/share" + dirs += [os.path.join(lindir, "fonts") for lindir in lindirs.split(":")] + elif sys.platform == "darwin": + dirs += [ + "/Library/Fonts", + "/System/Library/Fonts", + os.path.expanduser("~/Library/Fonts"), + ] + + ext = os.path.splitext(ttf_filename)[1] + first_font_with_a_different_extension = None + for directory in dirs: + for walkroot, walkdir, walkfilenames in os.walk(directory): + for walkfilename in walkfilenames: + if ext and walkfilename == ttf_filename: + return freetype(os.path.join(walkroot, walkfilename)) + elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename: + fontpath = os.path.join(walkroot, walkfilename) + if os.path.splitext(fontpath)[1] == ".ttf": + return freetype(fontpath) + if not ext and first_font_with_a_different_extension is None: + first_font_with_a_different_extension = fontpath + if first_font_with_a_different_extension: + return freetype(first_font_with_a_different_extension) + raise + + +def load_path(filename): + """ + Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a + bitmap font along the Python path. + + :param filename: Name of font file. + :return: A font object. + :exception OSError: If the file could not be read. + """ + for directory in sys.path: + if is_directory(directory): + if not isinstance(filename, str): + filename = filename.decode("utf-8") + try: + return load(os.path.join(directory, filename)) + except OSError: + pass + msg = "cannot find font file" + raise OSError(msg) + + +def load_default(size=None): + """If FreeType support is available, load a version of Aileron Regular, + https://dotcolon.net/font/aileron, with a more limited character set. + + Otherwise, load a "better than nothing" font. + + .. versionadded:: 1.1.4 + + :param size: The font size of Aileron Regular. + + .. versionadded:: 10.1.0 + + :return: A font object. + """ + if core.__class__.__name__ == "module" or size is not None: + f = truetype( + BytesIO( + base64.b64decode( + b""" +AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA +AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA +MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh +tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk +OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ +2r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ +AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI +BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA +AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ +AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk +QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB +kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC +ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA +EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg +JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y +AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q +AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq +QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// +//4/+5/7j/tP+y/7D/reBR4E/gR+A14CzfTwVxAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT +FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT +U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA +AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 +ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO +AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ +gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG +oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz +qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA +DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA +P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA +LfAAMABwAAEyMnMxcjJzOmRgpagkYKWgHl+vr6AAAAAAIARgAAAf4CsgAbAB8AAAEHMxUjByM3Iwc +jNyM1MzcjNTM3MwczNzMHMxUrAQczAZgdZXEvOi9bLzovWmYdZXEvOi9bLzovWp9bHlsBn4w429vb +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 +EQQ/BCQvEjQCFQZWFSEWQv40AcxCDiUblhP9uSEAAAAAAAAWAQ4AAQAAAAAAAAATACgAAQAAAAAAA +QAHAEwAAQAAAAAAAgAHAGQAAQAAAAAAAwAaAKIAAQAAAAAABAAHAM0AAQAAAAAABQA8AU8AAQAAAA +AABgAPAawAAQAAAAAACAALAdQAAQAAAAAACQALAfgAAQAAAAAACwAXAjQAAQAAAAAADAAXAnwAAwA +BBAkAAAAmAAAAAwABBAkAAQAOADwAAwABBAkAAgAOAFQAAwABBAkAAwA0AGwAAwABBAkABAAOAL0A +AwABBAkABQB4ANUAAwABBAkABgAeAYwAAwABBAkACAAWAbwAAwABBAkACQAWAeAAAwABBAkACwAuA +gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm +lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV +ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy +AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA +HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg +B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk +AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 +ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA +HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 +JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB +odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs +AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA +AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB +QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA +xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A +TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A +LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA +AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ +ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG +AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE +AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE +kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ +PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA +AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA +AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAD/sv+4/+z/7v/MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAD/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9T/6AAAAAD/8QAA +ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD +/4gAA//AAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/OAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/ZAAD/egAA/1kAAAAA/5D/rgAAAAAAAAAAAA +AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAD/8AAA/7b/8P+wAAD/8P/E/98AAAAA/8P/+P/0//oAAAAAAAAAAAAA//gA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/w//C/9MAAP/SAAD/9wAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA +BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA +AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ +ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA +gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC +YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA +AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== +""" + ) + ), + 10 if size is None else size, + layout_engine=Layout.BASIC, + ) + else: + f = ImageFont() + f._load_pilfont_data( + # courB08 + BytesIO( + base64.b64decode( + b""" +UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA +BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL +AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA +AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB +ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A +BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB +//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA +AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH +AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA +ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv +AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/ +/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 +AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA +AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG +AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA +BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA +AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA +2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF +AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// ++gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA +////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA +BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv +AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA +AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA +AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA +BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// +//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA +AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF +AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB +mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn +AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA +AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 +AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA +Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB +//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA +AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ +AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC +DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ +AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/ ++wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5 +AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/ +///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG +AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA +BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA +Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC +eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG +AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// ++gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA +////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA +BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT +AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A +AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA +Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA +Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// +//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA +AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ +AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA +LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 +AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA +AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 +AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA +AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG +AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA +EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK +AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA +pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG +AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// ++QAGAAIAzgAKANUAEw== +""" + ) + ), + Image.open( + BytesIO( + base64.b64decode( + b""" +iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u +Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9 +M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g +LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F +IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA +Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 +NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx +in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 +SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY +AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt +y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG +ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY +lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H +/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 +AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 +c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ +/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw +pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv +oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR +evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA +AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v// +Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR +w7IkEbzhVQAAAABJRU5ErkJggg== +""" + ) + ) + ), + ) + return f diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageGrab.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageGrab.py new file mode 100644 index 00000000..a4993d3d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageGrab.py @@ -0,0 +1,178 @@ +# +# The Python Imaging Library +# $Id$ +# +# screen grabber +# +# History: +# 2001-04-26 fl created +# 2001-09-17 fl use builtin driver, if present +# 2002-11-19 fl added grabclipboard support +# +# Copyright (c) 2001-2002 by Secret Labs AB +# Copyright (c) 2001-2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import shutil +import subprocess +import sys +import tempfile + +from . import Image + + +def grab(bbox=None, include_layered_windows=False, all_screens=False, xdisplay=None): + if xdisplay is None: + if sys.platform == "darwin": + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + args = ["screencapture"] + if bbox: + left, top, right, bottom = bbox + args += ["-R", f"{left},{top},{right-left},{bottom-top}"] + subprocess.call(args + ["-x", filepath]) + im = Image.open(filepath) + im.load() + os.unlink(filepath) + if bbox: + im_resized = im.resize((right - left, bottom - top)) + im.close() + return im_resized + return im + elif sys.platform == "win32": + offset, size, data = Image.core.grabscreen_win32( + include_layered_windows, all_screens + ) + im = Image.frombytes( + "RGB", + size, + data, + # RGB, 32-bit line padding, origin lower left corner + "raw", + "BGR", + (size[0] * 3 + 3) & -4, + -1, + ) + if bbox: + x0, y0 = offset + left, top, right, bottom = bbox + im = im.crop((left - x0, top - y0, right - x0, bottom - y0)) + return im + try: + if not Image.core.HAVE_XCB: + msg = "Pillow was built without XCB support" + raise OSError(msg) + size, data = Image.core.grabscreen_x11(xdisplay) + except OSError: + if ( + xdisplay is None + and sys.platform not in ("darwin", "win32") + and shutil.which("gnome-screenshot") + ): + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + subprocess.call(["gnome-screenshot", "-f", filepath]) + im = Image.open(filepath) + im.load() + os.unlink(filepath) + if bbox: + im_cropped = im.crop(bbox) + im.close() + return im_cropped + return im + else: + raise + else: + im = Image.frombytes("RGB", size, data, "raw", "BGRX", size[0] * 4, 1) + if bbox: + im = im.crop(bbox) + return im + + +def grabclipboard(): + if sys.platform == "darwin": + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + commands = [ + 'set theFile to (open for access POSIX file "' + + filepath + + '" with write permission)', + "try", + " write (the clipboard as «class PNGf») to theFile", + "end try", + "close access theFile", + ] + script = ["osascript"] + for command in commands: + script += ["-e", command] + subprocess.call(script) + + im = None + if os.stat(filepath).st_size != 0: + im = Image.open(filepath) + im.load() + os.unlink(filepath) + return im + elif sys.platform == "win32": + fmt, data = Image.core.grabclipboard_win32() + if fmt == "file": # CF_HDROP + import struct + + o = struct.unpack_from("I", data)[0] + if data[16] != 0: + files = data[o:].decode("utf-16le").split("\0") + else: + files = data[o:].decode("mbcs").split("\0") + return files[: files.index("")] + if isinstance(data, bytes): + data = io.BytesIO(data) + if fmt == "png": + from . import PngImagePlugin + + return PngImagePlugin.PngImageFile(data) + elif fmt == "DIB": + from . import BmpImagePlugin + + return BmpImagePlugin.DibImageFile(data) + return None + else: + if os.getenv("WAYLAND_DISPLAY"): + session_type = "wayland" + elif os.getenv("DISPLAY"): + session_type = "x11" + else: # Session type check failed + session_type = None + + if shutil.which("wl-paste") and session_type in ("wayland", None): + output = subprocess.check_output(["wl-paste", "-l"]).decode() + mimetypes = output.splitlines() + if "image/png" in mimetypes: + mimetype = "image/png" + elif mimetypes: + mimetype = mimetypes[0] + else: + mimetype = None + + args = ["wl-paste"] + if mimetype: + args.extend(["-t", mimetype]) + elif shutil.which("xclip") and session_type in ("x11", None): + args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"] + else: + msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux" + raise NotImplementedError(msg) + + p = subprocess.run(args, capture_output=True) + err = p.stderr + if err: + msg = f"{args[0]} error: {err.strip().decode()}" + raise ChildProcessError(msg) + data = io.BytesIO(p.stdout) + im = Image.open(data) + im.load() + return im diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMath.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMath.py new file mode 100644 index 00000000..b77f4bce --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMath.py @@ -0,0 +1,265 @@ +# +# The Python Imaging Library +# $Id$ +# +# a simple math add-on for the Python Imaging Library +# +# History: +# 1999-02-15 fl Original PIL Plus release +# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 +# 2005-09-12 fl Fixed int() and float() for Python 2.4.1 +# +# Copyright (c) 1999-2005 by Secret Labs AB +# Copyright (c) 2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import builtins + +from . import Image, _imagingmath + + +class _Operand: + """Wraps an image operand, providing standard operators""" + + def __init__(self, im): + self.im = im + + def __fixup(self, im1): + # convert image to suitable mode + if isinstance(im1, _Operand): + # argument was an image. + if im1.im.mode in ("1", "L"): + return im1.im.convert("I") + elif im1.im.mode in ("I", "F"): + return im1.im + else: + msg = f"unsupported mode: {im1.im.mode}" + raise ValueError(msg) + else: + # argument was a constant + if isinstance(im1, (int, float)) and self.im.mode in ("1", "L", "I"): + return Image.new("I", self.im.size, im1) + else: + return Image.new("F", self.im.size, im1) + + def apply(self, op, im1, im2=None, mode=None): + im1 = self.__fixup(im1) + if im2 is None: + # unary operation + out = Image.new(mode or im1.mode, im1.size, None) + im1.load() + try: + op = getattr(_imagingmath, op + "_" + im1.mode) + except AttributeError as e: + msg = f"bad operand type for '{op}'" + raise TypeError(msg) from e + _imagingmath.unop(op, out.im.id, im1.im.id) + else: + # binary operation + im2 = self.__fixup(im2) + if im1.mode != im2.mode: + # convert both arguments to floating point + if im1.mode != "F": + im1 = im1.convert("F") + if im2.mode != "F": + im2 = im2.convert("F") + if im1.size != im2.size: + # crop both arguments to a common size + size = (min(im1.size[0], im2.size[0]), min(im1.size[1], im2.size[1])) + if im1.size != size: + im1 = im1.crop((0, 0) + size) + if im2.size != size: + im2 = im2.crop((0, 0) + size) + out = Image.new(mode or im1.mode, im1.size, None) + im1.load() + im2.load() + try: + op = getattr(_imagingmath, op + "_" + im1.mode) + except AttributeError as e: + msg = f"bad operand type for '{op}'" + raise TypeError(msg) from e + _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id) + return _Operand(out) + + # unary operators + def __bool__(self): + # an image is "true" if it contains at least one non-zero pixel + return self.im.getbbox() is not None + + def __abs__(self): + return self.apply("abs", self) + + def __pos__(self): + return self + + def __neg__(self): + return self.apply("neg", self) + + # binary operators + def __add__(self, other): + return self.apply("add", self, other) + + def __radd__(self, other): + return self.apply("add", other, self) + + def __sub__(self, other): + return self.apply("sub", self, other) + + def __rsub__(self, other): + return self.apply("sub", other, self) + + def __mul__(self, other): + return self.apply("mul", self, other) + + def __rmul__(self, other): + return self.apply("mul", other, self) + + def __truediv__(self, other): + return self.apply("div", self, other) + + def __rtruediv__(self, other): + return self.apply("div", other, self) + + def __mod__(self, other): + return self.apply("mod", self, other) + + def __rmod__(self, other): + return self.apply("mod", other, self) + + def __pow__(self, other): + return self.apply("pow", self, other) + + def __rpow__(self, other): + return self.apply("pow", other, self) + + # bitwise + def __invert__(self): + return self.apply("invert", self) + + def __and__(self, other): + return self.apply("and", self, other) + + def __rand__(self, other): + return self.apply("and", other, self) + + def __or__(self, other): + return self.apply("or", self, other) + + def __ror__(self, other): + return self.apply("or", other, self) + + def __xor__(self, other): + return self.apply("xor", self, other) + + def __rxor__(self, other): + return self.apply("xor", other, self) + + def __lshift__(self, other): + return self.apply("lshift", self, other) + + def __rshift__(self, other): + return self.apply("rshift", self, other) + + # logical + def __eq__(self, other): + return self.apply("eq", self, other) + + def __ne__(self, other): + return self.apply("ne", self, other) + + def __lt__(self, other): + return self.apply("lt", self, other) + + def __le__(self, other): + return self.apply("le", self, other) + + def __gt__(self, other): + return self.apply("gt", self, other) + + def __ge__(self, other): + return self.apply("ge", self, other) + + +# conversions +def imagemath_int(self): + return _Operand(self.im.convert("I")) + + +def imagemath_float(self): + return _Operand(self.im.convert("F")) + + +# logical +def imagemath_equal(self, other): + return self.apply("eq", self, other, mode="I") + + +def imagemath_notequal(self, other): + return self.apply("ne", self, other, mode="I") + + +def imagemath_min(self, other): + return self.apply("min", self, other) + + +def imagemath_max(self, other): + return self.apply("max", self, other) + + +def imagemath_convert(self, mode): + return _Operand(self.im.convert(mode)) + + +ops = {} +for k, v in list(globals().items()): + if k[:10] == "imagemath_": + ops[k[10:]] = v + + +def eval(expression, _dict={}, **kw): + """ + Evaluates an image expression. + + :param expression: A string containing a Python-style expression. + :param options: Values to add to the evaluation context. You + can either use a dictionary, or one or more keyword + arguments. + :return: The evaluated expression. This is usually an image object, but can + also be an integer, a floating point value, or a pixel tuple, + depending on the expression. + """ + + # build execution namespace + args = ops.copy() + for k in list(_dict.keys()) + list(kw.keys()): + if "__" in k or hasattr(builtins, k): + msg = f"'{k}' not allowed" + raise ValueError(msg) + + args.update(_dict) + args.update(kw) + for k, v in args.items(): + if hasattr(v, "im"): + args[k] = _Operand(v) + + compiled_code = compile(expression, "", "eval") + + def scan(code): + for const in code.co_consts: + if type(const) is type(compiled_code): + scan(const) + + for name in code.co_names: + if name not in args and name != "abs": + msg = f"'{name}' not allowed" + raise ValueError(msg) + + scan(compiled_code) + out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args) + try: + return out.im + except AttributeError: + return out diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMode.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMode.py new file mode 100644 index 00000000..0b31f608 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMode.py @@ -0,0 +1,96 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard mode descriptors +# +# History: +# 2006-03-20 fl Added +# +# Copyright (c) 2006 by Secret Labs AB. +# Copyright (c) 2006 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys +from functools import lru_cache + + +class ModeDescriptor: + """Wrapper for mode strings.""" + + def __init__( + self, + mode: str, + bands: tuple[str, ...], + basemode: str, + basetype: str, + typestr: str, + ) -> None: + self.mode = mode + self.bands = bands + self.basemode = basemode + self.basetype = basetype + self.typestr = typestr + + def __str__(self) -> str: + return self.mode + + +@lru_cache +def getmode(mode: str) -> ModeDescriptor: + """Gets a mode descriptor for the given mode.""" + # initialize mode cache + endian = "<" if sys.byteorder == "little" else ">" + + modes = { + # core modes + # Bits need to be extended to bytes + "1": ("L", "L", ("1",), "|b1"), + "L": ("L", "L", ("L",), "|u1"), + "I": ("L", "I", ("I",), endian + "i4"), + "F": ("L", "F", ("F",), endian + "f4"), + "P": ("P", "L", ("P",), "|u1"), + "RGB": ("RGB", "L", ("R", "G", "B"), "|u1"), + "RGBX": ("RGB", "L", ("R", "G", "B", "X"), "|u1"), + "RGBA": ("RGB", "L", ("R", "G", "B", "A"), "|u1"), + "CMYK": ("RGB", "L", ("C", "M", "Y", "K"), "|u1"), + "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr"), "|u1"), + # UNDONE - unsigned |u1i1i1 + "LAB": ("RGB", "L", ("L", "A", "B"), "|u1"), + "HSV": ("RGB", "L", ("H", "S", "V"), "|u1"), + # extra experimental modes + "RGBa": ("RGB", "L", ("R", "G", "B", "a"), "|u1"), + "BGR;15": ("RGB", "L", ("B", "G", "R"), "|u1"), + "BGR;16": ("RGB", "L", ("B", "G", "R"), "|u1"), + "BGR;24": ("RGB", "L", ("B", "G", "R"), "|u1"), + "LA": ("L", "L", ("L", "A"), "|u1"), + "La": ("L", "L", ("L", "a"), "|u1"), + "PA": ("RGB", "L", ("P", "A"), "|u1"), + } + if mode in modes: + base_mode, base_type, bands, type_str = modes[mode] + return ModeDescriptor(mode, bands, base_mode, base_type, type_str) + + mapping_modes = { + # I;16 == I;16L, and I;32 == I;32L + "I;16": "u2", + "I;16BS": ">i2", + "I;16N": endian + "u2", + "I;16NS": endian + "i2", + "I;32": "u4", + "I;32L": "i4", + "I;32LS": " +from __future__ import annotations + +import re + +from . import Image, _imagingmorph + +LUT_SIZE = 1 << 9 + +# fmt: off +ROTATION_MATRIX = [ + 6, 3, 0, + 7, 4, 1, + 8, 5, 2, +] +MIRROR_MATRIX = [ + 2, 1, 0, + 5, 4, 3, + 8, 7, 6, +] +# fmt: on + + +class LutBuilder: + """A class for building a MorphLut from a descriptive language + + The input patterns is a list of a strings sequences like these:: + + 4:(... + .1. + 111)->1 + + (whitespaces including linebreaks are ignored). The option 4 + describes a series of symmetry operations (in this case a + 4-rotation), the pattern is described by: + + - . or X - Ignore + - 1 - Pixel is on + - 0 - Pixel is off + + The result of the operation is described after "->" string. + + The default is to return the current pixel value, which is + returned if no other match is found. + + Operations: + + - 4 - 4 way rotation + - N - Negate + - 1 - Dummy op for no other operation (an op must always be given) + - M - Mirroring + + Example:: + + lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) + lut = lb.build_lut() + + """ + + def __init__(self, patterns=None, op_name=None): + if patterns is not None: + self.patterns = patterns + else: + self.patterns = [] + self.lut = None + if op_name is not None: + known_patterns = { + "corner": ["1:(... ... ...)->0", "4:(00. 01. ...)->1"], + "dilation4": ["4:(... .0. .1.)->1"], + "dilation8": ["4:(... .0. .1.)->1", "4:(... .0. ..1)->1"], + "erosion4": ["4:(... .1. .0.)->0"], + "erosion8": ["4:(... .1. .0.)->0", "4:(... .1. ..0)->0"], + "edge": [ + "1:(... ... ...)->0", + "4:(.0. .1. ...)->1", + "4:(01. .1. ...)->1", + ], + } + if op_name not in known_patterns: + msg = "Unknown pattern " + op_name + "!" + raise Exception(msg) + + self.patterns = known_patterns[op_name] + + def add_patterns(self, patterns): + self.patterns += patterns + + def build_default_lut(self): + symbols = [0, 1] + m = 1 << 4 # pos of current pixel + self.lut = bytearray(symbols[(i & m) > 0] for i in range(LUT_SIZE)) + + def get_lut(self): + return self.lut + + def _string_permute(self, pattern, permutation): + """string_permute takes a pattern and a permutation and returns the + string permuted according to the permutation list. + """ + assert len(permutation) == 9 + return "".join(pattern[p] for p in permutation) + + def _pattern_permute(self, basic_pattern, options, basic_result): + """pattern_permute takes a basic pattern and its result and clones + the pattern according to the modifications described in the $options + parameter. It returns a list of all cloned patterns.""" + patterns = [(basic_pattern, basic_result)] + + # rotations + if "4" in options: + res = patterns[-1][1] + for i in range(4): + patterns.append( + (self._string_permute(patterns[-1][0], ROTATION_MATRIX), res) + ) + # mirror + if "M" in options: + n = len(patterns) + for pattern, res in patterns[:n]: + patterns.append((self._string_permute(pattern, MIRROR_MATRIX), res)) + + # negate + if "N" in options: + n = len(patterns) + for pattern, res in patterns[:n]: + # Swap 0 and 1 + pattern = pattern.replace("0", "Z").replace("1", "0").replace("Z", "1") + res = 1 - int(res) + patterns.append((pattern, res)) + + return patterns + + def build_lut(self): + """Compile all patterns into a morphology lut. + + TBD :Build based on (file) morphlut:modify_lut + """ + self.build_default_lut() + patterns = [] + + # Parse and create symmetries of the patterns strings + for p in self.patterns: + m = re.search(r"(\w*):?\s*\((.+?)\)\s*->\s*(\d)", p.replace("\n", "")) + if not m: + msg = 'Syntax error in pattern "' + p + '"' + raise Exception(msg) + options = m.group(1) + pattern = m.group(2) + result = int(m.group(3)) + + # Get rid of spaces + pattern = pattern.replace(" ", "").replace("\n", "") + + patterns += self._pattern_permute(pattern, options, result) + + # compile the patterns into regular expressions for speed + for i, pattern in enumerate(patterns): + p = pattern[0].replace(".", "X").replace("X", "[01]") + p = re.compile(p) + patterns[i] = (p, pattern[1]) + + # Step through table and find patterns that match. + # Note that all the patterns are searched. The last one + # caught overrides + for i in range(LUT_SIZE): + # Build the bit pattern + bitpattern = bin(i)[2:] + bitpattern = ("0" * (9 - len(bitpattern)) + bitpattern)[::-1] + + for p, r in patterns: + if p.match(bitpattern): + self.lut[i] = [0, 1][r] + + return self.lut + + +class MorphOp: + """A class for binary morphological operators""" + + def __init__(self, lut=None, op_name=None, patterns=None): + """Create a binary morphological operator""" + self.lut = lut + if op_name is not None: + self.lut = LutBuilder(op_name=op_name).build_lut() + elif patterns is not None: + self.lut = LutBuilder(patterns=patterns).build_lut() + + def apply(self, image): + """Run a single morphological operation on an image + + Returns a tuple of the number of changed pixels and the + morphed image""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + outimage = Image.new(image.mode, image.size, None) + count = _imagingmorph.apply(bytes(self.lut), image.im.id, outimage.im.id) + return count, outimage + + def match(self, image): + """Get a list of coordinates matching the morphological operation on + an image. + + Returns a list of tuples of (x,y) coordinates + of all matching pixels. See :ref:`coordinate-system`.""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + return _imagingmorph.match(bytes(self.lut), image.im.id) + + def get_on_pixels(self, image): + """Get a list of all turned on pixels in a binary image + + Returns a list of tuples of (x,y) coordinates + of all matching pixels. See :ref:`coordinate-system`.""" + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + return _imagingmorph.get_on_pixels(image.im.id) + + def load_lut(self, filename): + """Load an operator from an mrl file""" + with open(filename, "rb") as f: + self.lut = bytearray(f.read()) + + if len(self.lut) != LUT_SIZE: + self.lut = None + msg = "Wrong size operator file!" + raise Exception(msg) + + def save_lut(self, filename): + """Save an operator to an mrl file""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + with open(filename, "wb") as f: + f.write(self.lut) + + def set_lut(self, lut): + """Set the lut from an external source""" + self.lut = lut diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageOps.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageOps.py new file mode 100644 index 00000000..a9e626b2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageOps.py @@ -0,0 +1,655 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard image operations +# +# History: +# 2001-10-20 fl Created +# 2001-10-23 fl Added autocontrast operator +# 2001-12-18 fl Added Kevin's fit operator +# 2004-03-14 fl Fixed potential division by zero in equalize +# 2005-05-05 fl Fixed equalize for low number of values +# +# Copyright (c) 2001-2004 by Secret Labs AB +# Copyright (c) 2001-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import functools +import operator +import re + +from . import ExifTags, Image, ImagePalette + +# +# helpers + + +def _border(border): + if isinstance(border, tuple): + if len(border) == 2: + left, top = right, bottom = border + elif len(border) == 4: + left, top, right, bottom = border + else: + left = top = right = bottom = border + return left, top, right, bottom + + +def _color(color, mode): + if isinstance(color, str): + from . import ImageColor + + color = ImageColor.getcolor(color, mode) + return color + + +def _lut(image, lut): + if image.mode == "P": + # FIXME: apply to lookup table, not image data + msg = "mode P support coming soon" + raise NotImplementedError(msg) + elif image.mode in ("L", "RGB"): + if image.mode == "RGB" and len(lut) == 256: + lut = lut + lut + lut + return image.point(lut) + else: + msg = f"not supported for mode {image.mode}" + raise OSError(msg) + + +# +# actions + + +def autocontrast(image, cutoff=0, ignore=None, mask=None, preserve_tone=False): + """ + Maximize (normalize) image contrast. This function calculates a + histogram of the input image (or mask region), removes ``cutoff`` percent of the + lightest and darkest pixels from the histogram, and remaps the image + so that the darkest pixel becomes black (0), and the lightest + becomes white (255). + + :param image: The image to process. + :param cutoff: The percent to cut off from the histogram on the low and + high ends. Either a tuple of (low, high), or a single + number for both. + :param ignore: The background pixel value (use None for no background). + :param mask: Histogram used in contrast operation is computed using pixels + within the mask. If no mask is given the entire image is used + for histogram computation. + :param preserve_tone: Preserve image tone in Photoshop-like style autocontrast. + + .. versionadded:: 8.2.0 + + :return: An image. + """ + if preserve_tone: + histogram = image.convert("L").histogram(mask) + else: + histogram = image.histogram(mask) + + lut = [] + for layer in range(0, len(histogram), 256): + h = histogram[layer : layer + 256] + if ignore is not None: + # get rid of outliers + try: + h[ignore] = 0 + except TypeError: + # assume sequence + for ix in ignore: + h[ix] = 0 + if cutoff: + # cut off pixels from both ends of the histogram + if not isinstance(cutoff, tuple): + cutoff = (cutoff, cutoff) + # get number of pixels + n = 0 + for ix in range(256): + n = n + h[ix] + # remove cutoff% pixels from the low end + cut = n * cutoff[0] // 100 + for lo in range(256): + if cut > h[lo]: + cut = cut - h[lo] + h[lo] = 0 + else: + h[lo] -= cut + cut = 0 + if cut <= 0: + break + # remove cutoff% samples from the high end + cut = n * cutoff[1] // 100 + for hi in range(255, -1, -1): + if cut > h[hi]: + cut = cut - h[hi] + h[hi] = 0 + else: + h[hi] -= cut + cut = 0 + if cut <= 0: + break + # find lowest/highest samples after preprocessing + for lo in range(256): + if h[lo]: + break + for hi in range(255, -1, -1): + if h[hi]: + break + if hi <= lo: + # don't bother + lut.extend(list(range(256))) + else: + scale = 255.0 / (hi - lo) + offset = -lo * scale + for ix in range(256): + ix = int(ix * scale + offset) + if ix < 0: + ix = 0 + elif ix > 255: + ix = 255 + lut.append(ix) + return _lut(image, lut) + + +def colorize(image, black, white, mid=None, blackpoint=0, whitepoint=255, midpoint=127): + """ + Colorize grayscale image. + This function calculates a color wedge which maps all black pixels in + the source image to the first color and all white pixels to the + second color. If ``mid`` is specified, it uses three-color mapping. + The ``black`` and ``white`` arguments should be RGB tuples or color names; + optionally you can use three-color mapping by also specifying ``mid``. + Mapping positions for any of the colors can be specified + (e.g. ``blackpoint``), where these parameters are the integer + value corresponding to where the corresponding color should be mapped. + These parameters must have logical order, such that + ``blackpoint <= midpoint <= whitepoint`` (if ``mid`` is specified). + + :param image: The image to colorize. + :param black: The color to use for black input pixels. + :param white: The color to use for white input pixels. + :param mid: The color to use for midtone input pixels. + :param blackpoint: an int value [0, 255] for the black mapping. + :param whitepoint: an int value [0, 255] for the white mapping. + :param midpoint: an int value [0, 255] for the midtone mapping. + :return: An image. + """ + + # Initial asserts + assert image.mode == "L" + if mid is None: + assert 0 <= blackpoint <= whitepoint <= 255 + else: + assert 0 <= blackpoint <= midpoint <= whitepoint <= 255 + + # Define colors from arguments + black = _color(black, "RGB") + white = _color(white, "RGB") + if mid is not None: + mid = _color(mid, "RGB") + + # Empty lists for the mapping + red = [] + green = [] + blue = [] + + # Create the low-end values + for i in range(0, blackpoint): + red.append(black[0]) + green.append(black[1]) + blue.append(black[2]) + + # Create the mapping (2-color) + if mid is None: + range_map = range(0, whitepoint - blackpoint) + + for i in range_map: + red.append(black[0] + i * (white[0] - black[0]) // len(range_map)) + green.append(black[1] + i * (white[1] - black[1]) // len(range_map)) + blue.append(black[2] + i * (white[2] - black[2]) // len(range_map)) + + # Create the mapping (3-color) + else: + range_map1 = range(0, midpoint - blackpoint) + range_map2 = range(0, whitepoint - midpoint) + + for i in range_map1: + red.append(black[0] + i * (mid[0] - black[0]) // len(range_map1)) + green.append(black[1] + i * (mid[1] - black[1]) // len(range_map1)) + blue.append(black[2] + i * (mid[2] - black[2]) // len(range_map1)) + for i in range_map2: + red.append(mid[0] + i * (white[0] - mid[0]) // len(range_map2)) + green.append(mid[1] + i * (white[1] - mid[1]) // len(range_map2)) + blue.append(mid[2] + i * (white[2] - mid[2]) // len(range_map2)) + + # Create the high-end values + for i in range(0, 256 - whitepoint): + red.append(white[0]) + green.append(white[1]) + blue.append(white[2]) + + # Return converted image + image = image.convert("RGB") + return _lut(image, red + green + blue) + + +def contain(image, size, method=Image.Resampling.BICUBIC): + """ + Returns a resized version of the image, set to the maximum width and height + within the requested size, while maintaining the original aspect ratio. + + :param image: The image to resize. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :return: An image. + """ + + im_ratio = image.width / image.height + dest_ratio = size[0] / size[1] + + if im_ratio != dest_ratio: + if im_ratio > dest_ratio: + new_height = round(image.height / image.width * size[0]) + if new_height != size[1]: + size = (size[0], new_height) + else: + new_width = round(image.width / image.height * size[1]) + if new_width != size[0]: + size = (new_width, size[1]) + return image.resize(size, resample=method) + + +def cover(image, size, method=Image.Resampling.BICUBIC): + """ + Returns a resized version of the image, so that the requested size is + covered, while maintaining the original aspect ratio. + + :param image: The image to resize. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :return: An image. + """ + + im_ratio = image.width / image.height + dest_ratio = size[0] / size[1] + + if im_ratio != dest_ratio: + if im_ratio < dest_ratio: + new_height = round(image.height / image.width * size[0]) + if new_height != size[1]: + size = (size[0], new_height) + else: + new_width = round(image.width / image.height * size[1]) + if new_width != size[0]: + size = (new_width, size[1]) + return image.resize(size, resample=method) + + +def pad(image, size, method=Image.Resampling.BICUBIC, color=None, centering=(0.5, 0.5)): + """ + Returns a resized and padded version of the image, expanded to fill the + requested aspect ratio and size. + + :param image: The image to resize and crop. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :param color: The background color of the padded image. + :param centering: Control the position of the original image within the + padded version. + + (0.5, 0.5) will keep the image centered + (0, 0) will keep the image aligned to the top left + (1, 1) will keep the image aligned to the bottom + right + :return: An image. + """ + + resized = contain(image, size, method) + if resized.size == size: + out = resized + else: + out = Image.new(image.mode, size, color) + if resized.palette: + out.putpalette(resized.getpalette()) + if resized.width != size[0]: + x = round((size[0] - resized.width) * max(0, min(centering[0], 1))) + out.paste(resized, (x, 0)) + else: + y = round((size[1] - resized.height) * max(0, min(centering[1], 1))) + out.paste(resized, (0, y)) + return out + + +def crop(image, border=0): + """ + Remove border from image. The same amount of pixels are removed + from all four sides. This function works on all image modes. + + .. seealso:: :py:meth:`~PIL.Image.Image.crop` + + :param image: The image to crop. + :param border: The number of pixels to remove. + :return: An image. + """ + left, top, right, bottom = _border(border) + return image.crop((left, top, image.size[0] - right, image.size[1] - bottom)) + + +def scale(image, factor, resample=Image.Resampling.BICUBIC): + """ + Returns a rescaled image by a specific factor given in parameter. + A factor greater than 1 expands the image, between 0 and 1 contracts the + image. + + :param image: The image to rescale. + :param factor: The expansion factor, as a float. + :param resample: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + if factor == 1: + return image.copy() + elif factor <= 0: + msg = "the factor must be greater than 0" + raise ValueError(msg) + else: + size = (round(factor * image.width), round(factor * image.height)) + return image.resize(size, resample) + + +def deform(image, deformer, resample=Image.Resampling.BILINEAR): + """ + Deform the image. + + :param image: The image to deform. + :param deformer: A deformer object. Any object that implements a + ``getmesh`` method can be used. + :param resample: An optional resampling filter. Same values possible as + in the PIL.Image.transform function. + :return: An image. + """ + return image.transform( + image.size, Image.Transform.MESH, deformer.getmesh(image), resample + ) + + +def equalize(image, mask=None): + """ + Equalize the image histogram. This function applies a non-linear + mapping to the input image, in order to create a uniform + distribution of grayscale values in the output image. + + :param image: The image to equalize. + :param mask: An optional mask. If given, only the pixels selected by + the mask are included in the analysis. + :return: An image. + """ + if image.mode == "P": + image = image.convert("RGB") + h = image.histogram(mask) + lut = [] + for b in range(0, len(h), 256): + histo = [_f for _f in h[b : b + 256] if _f] + if len(histo) <= 1: + lut.extend(list(range(256))) + else: + step = (functools.reduce(operator.add, histo) - histo[-1]) // 255 + if not step: + lut.extend(list(range(256))) + else: + n = step // 2 + for i in range(256): + lut.append(n // step) + n = n + h[i + b] + return _lut(image, lut) + + +def expand(image, border=0, fill=0): + """ + Add border to the image + + :param image: The image to expand. + :param border: Border width, in pixels. + :param fill: Pixel fill value (a color value). Default is 0 (black). + :return: An image. + """ + left, top, right, bottom = _border(border) + width = left + image.size[0] + right + height = top + image.size[1] + bottom + color = _color(fill, image.mode) + if image.palette: + palette = ImagePalette.ImagePalette(palette=image.getpalette()) + if isinstance(color, tuple): + color = palette.getcolor(color) + else: + palette = None + out = Image.new(image.mode, (width, height), color) + if palette: + out.putpalette(palette.palette) + out.paste(image, (left, top)) + return out + + +def fit(image, size, method=Image.Resampling.BICUBIC, bleed=0.0, centering=(0.5, 0.5)): + """ + Returns a resized and cropped version of the image, cropped to the + requested aspect ratio and size. + + This function was contributed by Kevin Cazabon. + + :param image: The image to resize and crop. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :param bleed: Remove a border around the outside of the image from all + four edges. The value is a decimal percentage (use 0.01 for + one percent). The default value is 0 (no border). + Cannot be greater than or equal to 0.5. + :param centering: Control the cropping position. Use (0.5, 0.5) for + center cropping (e.g. if cropping the width, take 50% off + of the left side, and therefore 50% off the right side). + (0.0, 0.0) will crop from the top left corner (i.e. if + cropping the width, take all of the crop off of the right + side, and if cropping the height, take all of it off the + bottom). (1.0, 0.0) will crop from the bottom left + corner, etc. (i.e. if cropping the width, take all of the + crop off the left side, and if cropping the height take + none from the top, and therefore all off the bottom). + :return: An image. + """ + + # by Kevin Cazabon, Feb 17/2000 + # kevin@cazabon.com + # https://www.cazabon.com + + # ensure centering is mutable + centering = list(centering) + + if not 0.0 <= centering[0] <= 1.0: + centering[0] = 0.5 + if not 0.0 <= centering[1] <= 1.0: + centering[1] = 0.5 + + if not 0.0 <= bleed < 0.5: + bleed = 0.0 + + # calculate the area to use for resizing and cropping, subtracting + # the 'bleed' around the edges + + # number of pixels to trim off on Top and Bottom, Left and Right + bleed_pixels = (bleed * image.size[0], bleed * image.size[1]) + + live_size = ( + image.size[0] - bleed_pixels[0] * 2, + image.size[1] - bleed_pixels[1] * 2, + ) + + # calculate the aspect ratio of the live_size + live_size_ratio = live_size[0] / live_size[1] + + # calculate the aspect ratio of the output image + output_ratio = size[0] / size[1] + + # figure out if the sides or top/bottom will be cropped off + if live_size_ratio == output_ratio: + # live_size is already the needed ratio + crop_width = live_size[0] + crop_height = live_size[1] + elif live_size_ratio >= output_ratio: + # live_size is wider than what's needed, crop the sides + crop_width = output_ratio * live_size[1] + crop_height = live_size[1] + else: + # live_size is taller than what's needed, crop the top and bottom + crop_width = live_size[0] + crop_height = live_size[0] / output_ratio + + # make the crop + crop_left = bleed_pixels[0] + (live_size[0] - crop_width) * centering[0] + crop_top = bleed_pixels[1] + (live_size[1] - crop_height) * centering[1] + + crop = (crop_left, crop_top, crop_left + crop_width, crop_top + crop_height) + + # resize the image and return it + return image.resize(size, method, box=crop) + + +def flip(image): + """ + Flip the image vertically (top to bottom). + + :param image: The image to flip. + :return: An image. + """ + return image.transpose(Image.Transpose.FLIP_TOP_BOTTOM) + + +def grayscale(image): + """ + Convert the image to grayscale. + + :param image: The image to convert. + :return: An image. + """ + return image.convert("L") + + +def invert(image): + """ + Invert (negate) the image. + + :param image: The image to invert. + :return: An image. + """ + lut = list(range(255, -1, -1)) + return image.point(lut) if image.mode == "1" else _lut(image, lut) + + +def mirror(image): + """ + Flip image horizontally (left to right). + + :param image: The image to mirror. + :return: An image. + """ + return image.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + + +def posterize(image, bits): + """ + Reduce the number of bits for each color channel. + + :param image: The image to posterize. + :param bits: The number of bits to keep for each channel (1-8). + :return: An image. + """ + mask = ~(2 ** (8 - bits) - 1) + lut = [i & mask for i in range(256)] + return _lut(image, lut) + + +def solarize(image, threshold=128): + """ + Invert all pixel values above a threshold. + + :param image: The image to solarize. + :param threshold: All pixels above this grayscale level are inverted. + :return: An image. + """ + lut = [] + for i in range(256): + if i < threshold: + lut.append(i) + else: + lut.append(255 - i) + return _lut(image, lut) + + +def exif_transpose(image, *, in_place=False): + """ + If an image has an EXIF Orientation tag, other than 1, transpose the image + accordingly, and remove the orientation data. + + :param image: The image to transpose. + :param in_place: Boolean. Keyword-only argument. + If ``True``, the original image is modified in-place, and ``None`` is returned. + If ``False`` (default), a new :py:class:`~PIL.Image.Image` object is returned + with the transposition applied. If there is no transposition, a copy of the + image will be returned. + """ + image.load() + image_exif = image.getexif() + orientation = image_exif.get(ExifTags.Base.Orientation) + method = { + 2: Image.Transpose.FLIP_LEFT_RIGHT, + 3: Image.Transpose.ROTATE_180, + 4: Image.Transpose.FLIP_TOP_BOTTOM, + 5: Image.Transpose.TRANSPOSE, + 6: Image.Transpose.ROTATE_270, + 7: Image.Transpose.TRANSVERSE, + 8: Image.Transpose.ROTATE_90, + }.get(orientation) + if method is not None: + transposed_image = image.transpose(method) + if in_place: + image.im = transposed_image.im + image.pyaccess = None + image._size = transposed_image._size + exif_image = image if in_place else transposed_image + + exif = exif_image.getexif() + if ExifTags.Base.Orientation in exif: + del exif[ExifTags.Base.Orientation] + if "exif" in exif_image.info: + exif_image.info["exif"] = exif.tobytes() + elif "Raw profile type exif" in exif_image.info: + exif_image.info["Raw profile type exif"] = exif.tobytes().hex() + elif "XML:com.adobe.xmp" in exif_image.info: + for pattern in ( + r'tiff:Orientation="([0-9])"', + r"([0-9])", + ): + exif_image.info["XML:com.adobe.xmp"] = re.sub( + pattern, "", exif_image.info["XML:com.adobe.xmp"] + ) + if not in_place: + return transposed_image + elif not in_place: + return image.copy() diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePalette.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePalette.py new file mode 100644 index 00000000..fbcfa309 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePalette.py @@ -0,0 +1,262 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image palette object +# +# History: +# 1996-03-11 fl Rewritten. +# 1997-01-03 fl Up and running. +# 1997-08-23 fl Added load hack +# 2001-04-16 fl Fixed randint shadow bug in random() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import array + +from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile + + +class ImagePalette: + """ + Color palette for palette mapped images + + :param mode: The mode to use for the palette. See: + :ref:`concept-modes`. Defaults to "RGB" + :param palette: An optional palette. If given, it must be a bytearray, + an array or a list of ints between 0-255. The list must consist of + all channels for one color followed by the next color (e.g. RGBRGBRGB). + Defaults to an empty palette. + """ + + def __init__(self, mode="RGB", palette=None): + self.mode = mode + self.rawmode = None # if set, palette contains raw data + self.palette = palette or bytearray() + self.dirty = None + + @property + def palette(self): + return self._palette + + @palette.setter + def palette(self, palette): + self._colors = None + self._palette = palette + + @property + def colors(self): + if self._colors is None: + mode_len = len(self.mode) + self._colors = {} + for i in range(0, len(self.palette), mode_len): + color = tuple(self.palette[i : i + mode_len]) + if color in self._colors: + continue + self._colors[color] = i // mode_len + return self._colors + + @colors.setter + def colors(self, colors): + self._colors = colors + + def copy(self): + new = ImagePalette() + + new.mode = self.mode + new.rawmode = self.rawmode + if self.palette is not None: + new.palette = self.palette[:] + new.dirty = self.dirty + + return new + + def getdata(self): + """ + Get palette contents in format suitable for the low-level + ``im.putpalette`` primitive. + + .. warning:: This method is experimental. + """ + if self.rawmode: + return self.rawmode, self.palette + return self.mode, self.tobytes() + + def tobytes(self): + """Convert palette to bytes. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(self.palette, bytes): + return self.palette + arr = array.array("B", self.palette) + return arr.tobytes() + + # Declare tostring as an alias for tobytes + tostring = tobytes + + def _new_color_index(self, image=None, e=None): + if not isinstance(self.palette, bytearray): + self._palette = bytearray(self.palette) + index = len(self.palette) // 3 + special_colors = () + if image: + special_colors = ( + image.info.get("background"), + image.info.get("transparency"), + ) + while index in special_colors: + index += 1 + if index >= 256: + if image: + # Search for an unused index + for i, count in reversed(list(enumerate(image.histogram()))): + if count == 0 and i not in special_colors: + index = i + break + if index >= 256: + msg = "cannot allocate more than 256 colors" + raise ValueError(msg) from e + return index + + def getcolor(self, color, image=None): + """Given an rgb tuple, allocate palette entry. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(color, tuple): + if self.mode == "RGB": + if len(color) == 4: + if color[3] != 255: + msg = "cannot add non-opaque RGBA color to RGB palette" + raise ValueError(msg) + color = color[:3] + elif self.mode == "RGBA": + if len(color) == 3: + color += (255,) + try: + return self.colors[color] + except KeyError as e: + # allocate new color slot + index = self._new_color_index(image, e) + self.colors[color] = index + if index * 3 < len(self.palette): + self._palette = ( + self.palette[: index * 3] + + bytes(color) + + self.palette[index * 3 + 3 :] + ) + else: + self._palette += bytes(color) + self.dirty = 1 + return index + else: + msg = f"unknown color specifier: {repr(color)}" + raise ValueError(msg) + + def save(self, fp): + """Save palette to text file. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(fp, str): + fp = open(fp, "w") + fp.write("# Palette\n") + fp.write(f"# Mode: {self.mode}\n") + for i in range(256): + fp.write(f"{i}") + for j in range(i * len(self.mode), (i + 1) * len(self.mode)): + try: + fp.write(f" {self.palette[j]}") + except IndexError: + fp.write(" 0") + fp.write("\n") + fp.close() + + +# -------------------------------------------------------------------- +# Internal + + +def raw(rawmode, data): + palette = ImagePalette() + palette.rawmode = rawmode + palette.palette = data + palette.dirty = 1 + return palette + + +# -------------------------------------------------------------------- +# Factories + + +def make_linear_lut(black, white): + if black == 0: + return [white * i // 255 for i in range(256)] + + msg = "unavailable when black is non-zero" + raise NotImplementedError(msg) # FIXME + + +def make_gamma_lut(exp): + return [int(((i / 255.0) ** exp) * 255.0 + 0.5) for i in range(256)] + + +def negative(mode="RGB"): + palette = list(range(256 * len(mode))) + palette.reverse() + return ImagePalette(mode, [i // len(mode) for i in palette]) + + +def random(mode="RGB"): + from random import randint + + palette = [randint(0, 255) for _ in range(256 * len(mode))] + return ImagePalette(mode, palette) + + +def sepia(white="#fff0c0"): + bands = [make_linear_lut(0, band) for band in ImageColor.getrgb(white)] + return ImagePalette("RGB", [bands[i % 3][i // 3] for i in range(256 * 3)]) + + +def wedge(mode="RGB"): + palette = list(range(256 * len(mode))) + return ImagePalette(mode, [i // len(mode) for i in palette]) + + +def load(filename): + # FIXME: supports GIMP gradients only + + with open(filename, "rb") as fp: + for paletteHandler in [ + GimpPaletteFile.GimpPaletteFile, + GimpGradientFile.GimpGradientFile, + PaletteFile.PaletteFile, + ]: + try: + fp.seek(0) + lut = paletteHandler(fp).getpalette() + if lut: + break + except (SyntaxError, ValueError): + pass + else: + msg = "cannot load palette" + raise OSError(msg) + + return lut # data, rawmode diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePath.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePath.py new file mode 100644 index 00000000..77e8a609 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePath.py @@ -0,0 +1,20 @@ +# +# The Python Imaging Library +# $Id$ +# +# path interface +# +# History: +# 1996-11-04 fl Created +# 2002-04-14 fl Added documentation stub class +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image + +Path = Image.core.path diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageQt.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageQt.py new file mode 100644 index 00000000..6377c750 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageQt.py @@ -0,0 +1,197 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a simple Qt image interface. +# +# history: +# 2006-06-03 fl: created +# 2006-06-04 fl: inherit from QImage instead of wrapping it +# 2006-06-05 fl: removed toimage helper; move string support to ImageQt +# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com) +# +# Copyright (c) 2006 by Secret Labs AB +# Copyright (c) 2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys +from io import BytesIO + +from . import Image +from ._util import is_path + +qt_versions = [ + ["6", "PyQt6"], + ["side6", "PySide6"], +] + +# If a version has already been imported, attempt it first +qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True) +for qt_version, qt_module in qt_versions: + try: + if qt_module == "PyQt6": + from PyQt6.QtCore import QBuffer, QIODevice + from PyQt6.QtGui import QImage, QPixmap, qRgba + elif qt_module == "PySide6": + from PySide6.QtCore import QBuffer, QIODevice + from PySide6.QtGui import QImage, QPixmap, qRgba + except (ImportError, RuntimeError): + continue + qt_is_installed = True + break +else: + qt_is_installed = False + qt_version = None + + +def rgb(r, g, b, a=255): + """(Internal) Turns an RGB color into a Qt compatible color integer.""" + # use qRgb to pack the colors, and then turn the resulting long + # into a negative integer with the same bitpattern. + return qRgba(r, g, b, a) & 0xFFFFFFFF + + +def fromqimage(im): + """ + :param im: QImage or PIL ImageQt object + """ + buffer = QBuffer() + if qt_version == "6": + try: + qt_openmode = QIODevice.OpenModeFlag + except AttributeError: + qt_openmode = QIODevice.OpenMode + else: + qt_openmode = QIODevice + buffer.open(qt_openmode.ReadWrite) + # preserve alpha channel with png + # otherwise ppm is more friendly with Image.open + if im.hasAlphaChannel(): + im.save(buffer, "png") + else: + im.save(buffer, "ppm") + + b = BytesIO() + b.write(buffer.data()) + buffer.close() + b.seek(0) + + return Image.open(b) + + +def fromqpixmap(im): + return fromqimage(im) + + +def align8to32(bytes, width, mode): + """ + converts each scanline of data from 8 bit to 32 bit aligned + """ + + bits_per_pixel = {"1": 1, "L": 8, "P": 8, "I;16": 16}[mode] + + # calculate bytes per line and the extra padding if needed + bits_per_line = bits_per_pixel * width + full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8) + bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0) + + extra_padding = -bytes_per_line % 4 + + # already 32 bit aligned by luck + if not extra_padding: + return bytes + + new_data = [ + bytes[i * bytes_per_line : (i + 1) * bytes_per_line] + b"\x00" * extra_padding + for i in range(len(bytes) // bytes_per_line) + ] + + return b"".join(new_data) + + +def _toqclass_helper(im): + data = None + colortable = None + exclusive_fp = False + + # handle filename, if given instead of image name + if hasattr(im, "toUtf8"): + # FIXME - is this really the best way to do this? + im = str(im.toUtf8(), "utf-8") + if is_path(im): + im = Image.open(im) + exclusive_fp = True + + qt_format = QImage.Format if qt_version == "6" else QImage + if im.mode == "1": + format = qt_format.Format_Mono + elif im.mode == "L": + format = qt_format.Format_Indexed8 + colortable = [rgb(i, i, i) for i in range(256)] + elif im.mode == "P": + format = qt_format.Format_Indexed8 + palette = im.getpalette() + colortable = [rgb(*palette[i : i + 3]) for i in range(0, len(palette), 3)] + elif im.mode == "RGB": + # Populate the 4th channel with 255 + im = im.convert("RGBA") + + data = im.tobytes("raw", "BGRA") + format = qt_format.Format_RGB32 + elif im.mode == "RGBA": + data = im.tobytes("raw", "BGRA") + format = qt_format.Format_ARGB32 + elif im.mode == "I;16" and hasattr(qt_format, "Format_Grayscale16"): # Qt 5.13+ + im = im.point(lambda i: i * 256) + + format = qt_format.Format_Grayscale16 + else: + if exclusive_fp: + im.close() + msg = f"unsupported image mode {repr(im.mode)}" + raise ValueError(msg) + + size = im.size + __data = data or align8to32(im.tobytes(), size[0], im.mode) + if exclusive_fp: + im.close() + return {"data": __data, "size": size, "format": format, "colortable": colortable} + + +if qt_is_installed: + + class ImageQt(QImage): + def __init__(self, im): + """ + An PIL image wrapper for Qt. This is a subclass of PyQt's QImage + class. + + :param im: A PIL Image object, or a file name (given either as + Python string or a PyQt string object). + """ + im_data = _toqclass_helper(im) + # must keep a reference, or Qt will crash! + # All QImage constructors that take data operate on an existing + # buffer, so this buffer has to hang on for the life of the image. + # Fixes https://github.com/python-pillow/Pillow/issues/1370 + self.__data = im_data["data"] + super().__init__( + self.__data, + im_data["size"][0], + im_data["size"][1], + im_data["format"], + ) + if im_data["colortable"]: + self.setColorTable(im_data["colortable"]) + + +def toqimage(im): + return ImageQt(im) + + +def toqpixmap(im): + qimage = toqimage(im) + return QPixmap.fromImage(qimage) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageSequence.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageSequence.py new file mode 100644 index 00000000..2c185027 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageSequence.py @@ -0,0 +1,86 @@ +# +# The Python Imaging Library. +# $Id$ +# +# sequence support classes +# +# history: +# 1997-02-20 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +from __future__ import annotations + +from typing import Callable + +from . import Image + + +class Iterator: + """ + This class implements an iterator object that can be used to loop + over an image sequence. + + You can use the ``[]`` operator to access elements by index. This operator + will raise an :py:exc:`IndexError` if you try to access a nonexistent + frame. + + :param im: An image object. + """ + + def __init__(self, im: Image.Image): + if not hasattr(im, "seek"): + msg = "im must have seek method" + raise AttributeError(msg) + self.im = im + self.position = getattr(self.im, "_min_frame", 0) + + def __getitem__(self, ix: int) -> Image.Image: + try: + self.im.seek(ix) + return self.im + except EOFError as e: + msg = "end of sequence" + raise IndexError(msg) from e + + def __iter__(self) -> Iterator: + return self + + def __next__(self) -> Image.Image: + try: + self.im.seek(self.position) + self.position += 1 + return self.im + except EOFError as e: + msg = "end of sequence" + raise StopIteration(msg) from e + + +def all_frames( + im: Image.Image | list[Image.Image], + func: Callable[[Image.Image], Image.Image] | None = None, +) -> list[Image.Image]: + """ + Applies a given function to all frames in an image or a list of images. + The frames are returned as a list of separate images. + + :param im: An image, or a list of images. + :param func: The function to apply to all of the image frames. + :returns: A list of images. + """ + if not isinstance(im, list): + im = [im] + + ims = [] + for imSequence in im: + current = imSequence.tell() + + ims += [im_frame.copy() for im_frame in Iterator(imSequence)] + + imSequence.seek(current) + return [func(im) for im in ims] if func else ims diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageShow.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageShow.py new file mode 100644 index 00000000..fad3e098 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageShow.py @@ -0,0 +1,326 @@ +# +# The Python Imaging Library. +# $Id$ +# +# im.show() drivers +# +# History: +# 2008-04-06 fl Created +# +# Copyright (c) Secret Labs AB 2008. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +import shutil +import subprocess +import sys +from shlex import quote + +from . import Image + +_viewers = [] + + +def register(viewer, order=1): + """ + The :py:func:`register` function is used to register additional viewers:: + + from PIL import ImageShow + ImageShow.register(MyViewer()) # MyViewer will be used as a last resort + ImageShow.register(MySecondViewer(), 0) # MySecondViewer will be prioritised + ImageShow.register(ImageShow.XVViewer(), 0) # XVViewer will be prioritised + + :param viewer: The viewer to be registered. + :param order: + Zero or a negative integer to prepend this viewer to the list, + a positive integer to append it. + """ + try: + if issubclass(viewer, Viewer): + viewer = viewer() + except TypeError: + pass # raised if viewer wasn't a class + if order > 0: + _viewers.append(viewer) + else: + _viewers.insert(0, viewer) + + +def show(image, title=None, **options): + r""" + Display a given image. + + :param image: An image object. + :param title: Optional title. Not all viewers can display the title. + :param \**options: Additional viewer options. + :returns: ``True`` if a suitable viewer was found, ``False`` otherwise. + """ + for viewer in _viewers: + if viewer.show(image, title=title, **options): + return True + return False + + +class Viewer: + """Base class for viewers.""" + + # main api + + def show(self, image, **options): + """ + The main function for displaying an image. + Converts the given image to the target format and displays it. + """ + + if not ( + image.mode in ("1", "RGBA") + or (self.format == "PNG" and image.mode in ("I;16", "LA")) + ): + base = Image.getmodebase(image.mode) + if image.mode != base: + image = image.convert(base) + + return self.show_image(image, **options) + + # hook methods + + format = None + """The format to convert the image into.""" + options = {} + """Additional options used to convert the image.""" + + def get_format(self, image): + """Return format name, or ``None`` to save as PGM/PPM.""" + return self.format + + def get_command(self, file, **options): + """ + Returns the command used to display the file. + Not implemented in the base class. + """ + msg = "unavailable in base viewer" + raise NotImplementedError(msg) + + def save_image(self, image): + """Save to temporary file and return filename.""" + return image._dump(format=self.get_format(image), **self.options) + + def show_image(self, image, **options): + """Display the given image.""" + return self.show_file(self.save_image(image), **options) + + def show_file(self, path, **options): + """ + Display given file. + """ + os.system(self.get_command(path, **options)) # nosec + return 1 + + +# -------------------------------------------------------------------- + + +class WindowsViewer(Viewer): + """The default viewer on Windows is the default system application for PNG files.""" + + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + def get_command(self, file, **options): + return ( + f'start "Pillow" /WAIT "{file}" ' + "&& ping -n 4 127.0.0.1 >NUL " + f'&& del /f "{file}"' + ) + + +if sys.platform == "win32": + register(WindowsViewer) + + +class MacViewer(Viewer): + """The default viewer on macOS using ``Preview.app``.""" + + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + def get_command(self, file, **options): + # on darwin open returns immediately resulting in the temp + # file removal while app is opening + command = "open -a Preview.app" + command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&" + return command + + def show_file(self, path, **options): + """ + Display given file. + """ + subprocess.call(["open", "-a", "Preview.app", path]) + executable = sys.executable or shutil.which("python3") + if executable: + subprocess.Popen( + [ + executable, + "-c", + "import os, sys, time; time.sleep(20); os.remove(sys.argv[1])", + path, + ] + ) + return 1 + + +if sys.platform == "darwin": + register(MacViewer) + + +class UnixViewer(Viewer): + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + def get_command(self, file, **options): + command = self.get_command_ex(file, **options)[0] + return f"({command} {quote(file)}" + + +class XDGViewer(UnixViewer): + """ + The freedesktop.org ``xdg-open`` command. + """ + + def get_command_ex(self, file, **options): + command = executable = "xdg-open" + return command, executable + + def show_file(self, path, **options): + """ + Display given file. + """ + subprocess.Popen(["xdg-open", path]) + return 1 + + +class DisplayViewer(UnixViewer): + """ + The ImageMagick ``display`` command. + This viewer supports the ``title`` parameter. + """ + + def get_command_ex(self, file, title=None, **options): + command = executable = "display" + if title: + command += f" -title {quote(title)}" + return command, executable + + def show_file(self, path, **options): + """ + Display given file. + """ + args = ["display"] + title = options.get("title") + if title: + args += ["-title", title] + args.append(path) + + subprocess.Popen(args) + return 1 + + +class GmDisplayViewer(UnixViewer): + """The GraphicsMagick ``gm display`` command.""" + + def get_command_ex(self, file, **options): + executable = "gm" + command = "gm display" + return command, executable + + def show_file(self, path, **options): + """ + Display given file. + """ + subprocess.Popen(["gm", "display", path]) + return 1 + + +class EogViewer(UnixViewer): + """The GNOME Image Viewer ``eog`` command.""" + + def get_command_ex(self, file, **options): + executable = "eog" + command = "eog -n" + return command, executable + + def show_file(self, path, **options): + """ + Display given file. + """ + subprocess.Popen(["eog", "-n", path]) + return 1 + + +class XVViewer(UnixViewer): + """ + The X Viewer ``xv`` command. + This viewer supports the ``title`` parameter. + """ + + def get_command_ex(self, file, title=None, **options): + # note: xv is pretty outdated. most modern systems have + # imagemagick's display command instead. + command = executable = "xv" + if title: + command += f" -name {quote(title)}" + return command, executable + + def show_file(self, path, **options): + """ + Display given file. + """ + args = ["xv"] + title = options.get("title") + if title: + args += ["-name", title] + args.append(path) + + subprocess.Popen(args) + return 1 + + +if sys.platform not in ("win32", "darwin"): # unixoids + if shutil.which("xdg-open"): + register(XDGViewer) + if shutil.which("display"): + register(DisplayViewer) + if shutil.which("gm"): + register(GmDisplayViewer) + if shutil.which("eog"): + register(EogViewer) + if shutil.which("xv"): + register(XVViewer) + + +class IPythonViewer(Viewer): + """The viewer for IPython frontends.""" + + def show_image(self, image, **options): + ipython_display(image) + return 1 + + +try: + from IPython.display import display as ipython_display +except ImportError: + pass +else: + register(IPythonViewer) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 ImageShow.py imagefile [title]") + sys.exit() + + with Image.open(sys.argv[1]) as im: + print(show(im, *sys.argv[2:])) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageStat.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageStat.py new file mode 100644 index 00000000..13864e59 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageStat.py @@ -0,0 +1,129 @@ +# +# The Python Imaging Library. +# $Id$ +# +# global image statistics +# +# History: +# 1996-04-05 fl Created +# 1997-05-21 fl Added mask; added rms, var, stddev attributes +# 1997-08-05 fl Added median +# 1998-07-05 hk Fixed integer overflow error +# +# Notes: +# This class shows how to implement delayed evaluation of attributes. +# To get a certain value, simply access the corresponding attribute. +# The __getattr__ dispatcher takes care of the rest. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math + + +class Stat: + def __init__(self, image_or_list, mask=None): + try: + if mask: + self.h = image_or_list.histogram(mask) + else: + self.h = image_or_list.histogram() + except AttributeError: + self.h = image_or_list # assume it to be a histogram list + if not isinstance(self.h, list): + msg = "first argument must be image or list" + raise TypeError(msg) + self.bands = list(range(len(self.h) // 256)) + + def __getattr__(self, id): + """Calculate missing attribute""" + if id[:4] == "_get": + raise AttributeError(id) + # calculate missing attribute + v = getattr(self, "_get" + id)() + setattr(self, id, v) + return v + + def _getextrema(self): + """Get min/max values for each band in the image""" + + def minmax(histogram): + res_min, res_max = 255, 0 + for i in range(256): + if histogram[i]: + res_min = i + break + for i in range(255, -1, -1): + if histogram[i]: + res_max = i + break + return res_min, res_max + + return [minmax(self.h[i:]) for i in range(0, len(self.h), 256)] + + def _getcount(self): + """Get total number of pixels in each layer""" + return [sum(self.h[i : i + 256]) for i in range(0, len(self.h), 256)] + + def _getsum(self): + """Get sum of all pixels in each layer""" + + v = [] + for i in range(0, len(self.h), 256): + layer_sum = 0.0 + for j in range(256): + layer_sum += j * self.h[i + j] + v.append(layer_sum) + return v + + def _getsum2(self): + """Get squared sum of all pixels in each layer""" + + v = [] + for i in range(0, len(self.h), 256): + sum2 = 0.0 + for j in range(256): + sum2 += (j**2) * float(self.h[i + j]) + v.append(sum2) + return v + + def _getmean(self): + """Get average pixel level for each layer""" + return [self.sum[i] / self.count[i] for i in self.bands] + + def _getmedian(self): + """Get median pixel level for each layer""" + + v = [] + for i in self.bands: + s = 0 + half = self.count[i] // 2 + b = i * 256 + for j in range(256): + s = s + self.h[b + j] + if s > half: + break + v.append(j) + return v + + def _getrms(self): + """Get RMS for each layer""" + return [math.sqrt(self.sum2[i] / self.count[i]) for i in self.bands] + + def _getvar(self): + """Get variance for each layer""" + return [ + (self.sum2[i] - (self.sum[i] ** 2.0) / self.count[i]) / self.count[i] + for i in self.bands + ] + + def _getstddev(self): + """Get standard deviation for each layer""" + return [math.sqrt(self.var[i]) for i in self.bands] + + +Global = Stat # compatibility diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTk.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTk.py new file mode 100644 index 00000000..10b2cc69 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTk.py @@ -0,0 +1,284 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Tk display interface +# +# History: +# 96-04-08 fl Created +# 96-09-06 fl Added getimage method +# 96-11-01 fl Rewritten, removed image attribute and crop method +# 97-05-09 fl Use PyImagingPaste method instead of image type +# 97-05-12 fl Minor tweaks to match the IFUNC95 interface +# 97-05-17 fl Support the "pilbitmap" booster patch +# 97-06-05 fl Added file= and data= argument to image constructors +# 98-03-09 fl Added width and height methods to Image classes +# 98-07-02 fl Use default mode for "P" images without palette attribute +# 98-07-02 fl Explicitly destroy Tkinter image objects +# 99-07-24 fl Support multiple Tk interpreters (from Greg Couch) +# 99-07-26 fl Automatically hook into Tkinter (if possible) +# 99-08-15 fl Hook uses _imagingtk instead of _imaging +# +# Copyright (c) 1997-1999 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import tkinter +from io import BytesIO + +from . import Image + +# -------------------------------------------------------------------- +# Check for Tkinter interface hooks + +_pilbitmap_ok = None + + +def _pilbitmap_check(): + global _pilbitmap_ok + if _pilbitmap_ok is None: + try: + im = Image.new("1", (1, 1)) + tkinter.BitmapImage(data=f"PIL:{im.im.id}") + _pilbitmap_ok = 1 + except tkinter.TclError: + _pilbitmap_ok = 0 + return _pilbitmap_ok + + +def _get_image_from_kw(kw): + source = None + if "file" in kw: + source = kw.pop("file") + elif "data" in kw: + source = BytesIO(kw.pop("data")) + if source: + return Image.open(source) + + +def _pyimagingtkcall(command, photo, id): + tk = photo.tk + try: + tk.call(command, photo, id) + except tkinter.TclError: + # activate Tkinter hook + # may raise an error if it cannot attach to Tkinter + from . import _imagingtk + + _imagingtk.tkinit(tk.interpaddr()) + tk.call(command, photo, id) + + +# -------------------------------------------------------------------- +# PhotoImage + + +class PhotoImage: + """ + A Tkinter-compatible photo image. This can be used + everywhere Tkinter expects an image object. If the image is an RGBA + image, pixels having alpha 0 are treated as transparent. + + The constructor takes either a PIL image, or a mode and a size. + Alternatively, you can use the ``file`` or ``data`` options to initialize + the photo image object. + + :param image: Either a PIL image, or a mode string. If a mode string is + used, a size must also be given. + :param size: If the first argument is a mode string, this defines the size + of the image. + :keyword file: A filename to load the image from (using + ``Image.open(file)``). + :keyword data: An 8-bit string containing image data (as loaded from an + image file). + """ + + def __init__(self, image=None, size=None, **kw): + # Tk compatibility: file or data + if image is None: + image = _get_image_from_kw(kw) + + if hasattr(image, "mode") and hasattr(image, "size"): + # got an image instead of a mode + mode = image.mode + if mode == "P": + # palette mapped data + image.apply_transparency() + image.load() + try: + mode = image.palette.mode + except AttributeError: + mode = "RGB" # default + size = image.size + kw["width"], kw["height"] = size + else: + mode = image + image = None + + if mode not in ["1", "L", "RGB", "RGBA"]: + mode = Image.getmodebase(mode) + + self.__mode = mode + self.__size = size + self.__photo = tkinter.PhotoImage(**kw) + self.tk = self.__photo.tk + if image: + self.paste(image) + + def __del__(self): + name = self.__photo.name + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except Exception: + pass # ignore internal errors + + def __str__(self): + """ + Get the Tkinter photo image identifier. This method is automatically + called by Tkinter whenever a PhotoImage object is passed to a Tkinter + method. + + :return: A Tkinter photo image identifier (a string). + """ + return str(self.__photo) + + def width(self): + """ + Get the width of the image. + + :return: The width, in pixels. + """ + return self.__size[0] + + def height(self): + """ + Get the height of the image. + + :return: The height, in pixels. + """ + return self.__size[1] + + def paste(self, im): + """ + Paste a PIL image into the photo image. Note that this can + be very slow if the photo image is displayed. + + :param im: A PIL image. The size must match the target region. If the + mode does not match, the image is converted to the mode of + the bitmap image. + """ + # convert to blittable + im.load() + image = im.im + if image.isblock() and im.mode == self.__mode: + block = image + else: + block = image.new_block(self.__mode, im.size) + image.convert2(block, image) # convert directly between buffers + + _pyimagingtkcall("PyImagingPhoto", self.__photo, block.id) + + +# -------------------------------------------------------------------- +# BitmapImage + + +class BitmapImage: + """ + A Tkinter-compatible bitmap image. This can be used everywhere Tkinter + expects an image object. + + The given image must have mode "1". Pixels having value 0 are treated as + transparent. Options, if any, are passed on to Tkinter. The most commonly + used option is ``foreground``, which is used to specify the color for the + non-transparent parts. See the Tkinter documentation for information on + how to specify colours. + + :param image: A PIL image. + """ + + def __init__(self, image=None, **kw): + # Tk compatibility: file or data + if image is None: + image = _get_image_from_kw(kw) + + self.__mode = image.mode + self.__size = image.size + + if _pilbitmap_check(): + # fast way (requires the pilbitmap booster patch) + image.load() + kw["data"] = f"PIL:{image.im.id}" + self.__im = image # must keep a reference + else: + # slow but safe way + kw["data"] = image.tobitmap() + self.__photo = tkinter.BitmapImage(**kw) + + def __del__(self): + name = self.__photo.name + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except Exception: + pass # ignore internal errors + + def width(self): + """ + Get the width of the image. + + :return: The width, in pixels. + """ + return self.__size[0] + + def height(self): + """ + Get the height of the image. + + :return: The height, in pixels. + """ + return self.__size[1] + + def __str__(self): + """ + Get the Tkinter bitmap image identifier. This method is automatically + called by Tkinter whenever a BitmapImage object is passed to a Tkinter + method. + + :return: A Tkinter bitmap image identifier (a string). + """ + return str(self.__photo) + + +def getimage(photo): + """Copies the contents of a PhotoImage to a PIL image memory.""" + im = Image.new("RGBA", (photo.width(), photo.height())) + block = im.im + + _pyimagingtkcall("PyImagingPhotoGet", photo, block.id) + + return im + + +def _show(image, title): + """Helper for the Image.show method.""" + + class UI(tkinter.Label): + def __init__(self, master, im): + if im.mode == "1": + self.image = BitmapImage(im, foreground="white", master=master) + else: + self.image = PhotoImage(im, master=master) + super().__init__(master, image=self.image, bg="black", bd=0) + + if not tkinter._default_root: + msg = "tkinter not initialized" + raise OSError(msg) + top = tkinter.Toplevel() + if title: + top.title(title) + UI(top, image).pack() diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTransform.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTransform.py new file mode 100644 index 00000000..84c81f18 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTransform.py @@ -0,0 +1,112 @@ +# +# The Python Imaging Library. +# $Id$ +# +# transform wrappers +# +# History: +# 2002-04-08 fl Created +# +# Copyright (c) 2002 by Secret Labs AB +# Copyright (c) 2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from typing import Sequence + +from . import Image + + +class Transform(Image.ImageTransformHandler): + method: Image.Transform + + def __init__(self, data: Sequence[int]) -> None: + self.data = data + + def getdata(self) -> tuple[int, Sequence[int]]: + return self.method, self.data + + def transform( + self, + size: tuple[int, int], + image: Image.Image, + **options: dict[str, str | int | tuple[int, ...] | list[int]], + ) -> Image.Image: + # can be overridden + method, data = self.getdata() + return image.transform(size, method, data, **options) + + +class AffineTransform(Transform): + """ + Define an affine image transform. + + This function takes a 6-tuple (a, b, c, d, e, f) which contain the first + two rows from an affine transform matrix. For each pixel (x, y) in the + output image, the new value is taken from a position (a x + b y + c, + d x + e y + f) in the input image, rounded to nearest pixel. + + This function can be used to scale, translate, rotate, and shear the + original image. + + See :py:meth:`~PIL.Image.Image.transform` + + :param matrix: A 6-tuple (a, b, c, d, e, f) containing the first two rows + from an affine transform matrix. + """ + + method = Image.Transform.AFFINE + + +class ExtentTransform(Transform): + """ + Define a transform to extract a subregion from an image. + + Maps a rectangle (defined by two corners) from the image to a rectangle of + the given size. The resulting image will contain data sampled from between + the corners, such that (x0, y0) in the input image will end up at (0,0) in + the output image, and (x1, y1) at size. + + This method can be used to crop, stretch, shrink, or mirror an arbitrary + rectangle in the current image. It is slightly slower than crop, but about + as fast as a corresponding resize operation. + + See :py:meth:`~PIL.Image.Image.transform` + + :param bbox: A 4-tuple (x0, y0, x1, y1) which specifies two points in the + input image's coordinate system. See :ref:`coordinate-system`. + """ + + method = Image.Transform.EXTENT + + +class QuadTransform(Transform): + """ + Define a quad image transform. + + Maps a quadrilateral (a region defined by four corners) from the image to a + rectangle of the given size. + + See :py:meth:`~PIL.Image.Image.transform` + + :param xy: An 8-tuple (x0, y0, x1, y1, x2, y2, x3, y3) which contain the + upper left, lower left, lower right, and upper right corner of the + source quadrilateral. + """ + + method = Image.Transform.QUAD + + +class MeshTransform(Transform): + """ + Define a mesh image transform. A mesh transform consists of one or more + individual quad transforms. + + See :py:meth:`~PIL.Image.Image.transform` + + :param data: A list of (bbox, quad) tuples. + """ + + method = Image.Transform.MESH diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImageWin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageWin.py new file mode 100644 index 00000000..75910d2d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImageWin.py @@ -0,0 +1,231 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Windows DIB display interface +# +# History: +# 1996-05-20 fl Created +# 1996-09-20 fl Fixed subregion exposure +# 1997-09-21 fl Added draw primitive (for tzPrint) +# 2003-05-21 fl Added experimental Window/ImageWindow classes +# 2003-09-05 fl Added fromstring/tostring methods +# +# Copyright (c) Secret Labs AB 1997-2003. +# Copyright (c) Fredrik Lundh 1996-2003. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image + + +class HDC: + """ + Wraps an HDC integer. The resulting object can be passed to the + :py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose` + methods. + """ + + def __init__(self, dc): + self.dc = dc + + def __int__(self): + return self.dc + + +class HWND: + """ + Wraps an HWND integer. The resulting object can be passed to the + :py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose` + methods, instead of a DC. + """ + + def __init__(self, wnd): + self.wnd = wnd + + def __int__(self): + return self.wnd + + +class Dib: + """ + A Windows bitmap with the given mode and size. The mode can be one of "1", + "L", "P", or "RGB". + + If the display requires a palette, this constructor creates a suitable + palette and associates it with the image. For an "L" image, 128 graylevels + are allocated. For an "RGB" image, a 6x6x6 colour cube is used, together + with 20 graylevels. + + To make sure that palettes work properly under Windows, you must call the + ``palette`` method upon certain events from Windows. + + :param image: Either a PIL image, or a mode string. If a mode string is + used, a size must also be given. The mode can be one of "1", + "L", "P", or "RGB". + :param size: If the first argument is a mode string, this + defines the size of the image. + """ + + def __init__(self, image, size=None): + if hasattr(image, "mode") and hasattr(image, "size"): + mode = image.mode + size = image.size + else: + mode = image + image = None + if mode not in ["1", "L", "P", "RGB"]: + mode = Image.getmodebase(mode) + self.image = Image.core.display(mode, size) + self.mode = mode + self.size = size + if image: + self.paste(image) + + def expose(self, handle): + """ + Copy the bitmap contents to a device context. + + :param handle: Device context (HDC), cast to a Python integer, or an + HDC or HWND instance. In PythonWin, you can use + ``CDC.GetHandleAttrib()`` to get a suitable handle. + """ + if isinstance(handle, HWND): + dc = self.image.getdc(handle) + try: + result = self.image.expose(dc) + finally: + self.image.releasedc(handle, dc) + else: + result = self.image.expose(handle) + return result + + def draw(self, handle, dst, src=None): + """ + Same as expose, but allows you to specify where to draw the image, and + what part of it to draw. + + The destination and source areas are given as 4-tuple rectangles. If + the source is omitted, the entire image is copied. If the source and + the destination have different sizes, the image is resized as + necessary. + """ + if not src: + src = (0, 0) + self.size + if isinstance(handle, HWND): + dc = self.image.getdc(handle) + try: + result = self.image.draw(dc, dst, src) + finally: + self.image.releasedc(handle, dc) + else: + result = self.image.draw(handle, dst, src) + return result + + def query_palette(self, handle): + """ + Installs the palette associated with the image in the given device + context. + + This method should be called upon **QUERYNEWPALETTE** and + **PALETTECHANGED** events from Windows. If this method returns a + non-zero value, one or more display palette entries were changed, and + the image should be redrawn. + + :param handle: Device context (HDC), cast to a Python integer, or an + HDC or HWND instance. + :return: A true value if one or more entries were changed (this + indicates that the image should be redrawn). + """ + if isinstance(handle, HWND): + handle = self.image.getdc(handle) + try: + result = self.image.query_palette(handle) + finally: + self.image.releasedc(handle, handle) + else: + result = self.image.query_palette(handle) + return result + + def paste(self, im, box=None): + """ + Paste a PIL image into the bitmap image. + + :param im: A PIL image. The size must match the target region. + If the mode does not match, the image is converted to the + mode of the bitmap image. + :param box: A 4-tuple defining the left, upper, right, and + lower pixel coordinate. See :ref:`coordinate-system`. If + None is given instead of a tuple, all of the image is + assumed. + """ + im.load() + if self.mode != im.mode: + im = im.convert(self.mode) + if box: + self.image.paste(im.im, box) + else: + self.image.paste(im.im) + + def frombytes(self, buffer): + """ + Load display memory contents from byte data. + + :param buffer: A buffer containing display data (usually + data returned from :py:func:`~PIL.ImageWin.Dib.tobytes`) + """ + return self.image.frombytes(buffer) + + def tobytes(self): + """ + Copy display memory contents to bytes object. + + :return: A bytes object containing display data. + """ + return self.image.tobytes() + + +class Window: + """Create a Window with the given title size.""" + + def __init__(self, title="PIL", width=None, height=None): + self.hwnd = Image.core.createwindow( + title, self.__dispatcher, width or 0, height or 0 + ) + + def __dispatcher(self, action, *args): + return getattr(self, "ui_handle_" + action)(*args) + + def ui_handle_clear(self, dc, x0, y0, x1, y1): + pass + + def ui_handle_damage(self, x0, y0, x1, y1): + pass + + def ui_handle_destroy(self): + pass + + def ui_handle_repair(self, dc, x0, y0, x1, y1): + pass + + def ui_handle_resize(self, width, height): + pass + + def mainloop(self): + Image.core.eventloop() + + +class ImageWindow(Window): + """Create an image window which displays the given image.""" + + def __init__(self, image, title="PIL"): + if not isinstance(image, Dib): + image = Dib(image) + self.image = image + width, height = image.size + super().__init__(title, width=width, height=height) + + def ui_handle_repair(self, dc, x0, y0, x1, y1): + self.image.draw(dc, (x0, y0, x1, y1)) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/ImtImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/ImtImagePlugin.py new file mode 100644 index 00000000..7469c592 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/ImtImagePlugin.py @@ -0,0 +1,101 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IM Tools support for PIL +# +# history: +# 1996-05-27 fl Created (read 8-bit images only) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from . import Image, ImageFile + +# +# -------------------------------------------------------------------- + +field = re.compile(rb"([a-z]*) ([^ \r\n]*)") + + +## +# Image plugin for IM Tools images. + + +class ImtImageFile(ImageFile.ImageFile): + format = "IMT" + format_description = "IM Tools" + + def _open(self): + # Quick rejection: if there's not a LF among the first + # 100 bytes, this is (probably) not a text header. + + buffer = self.fp.read(100) + if b"\n" not in buffer: + msg = "not an IM file" + raise SyntaxError(msg) + + xsize = ysize = 0 + + while True: + if buffer: + s = buffer[:1] + buffer = buffer[1:] + else: + s = self.fp.read(1) + if not s: + break + + if s == b"\x0C": + # image data begins + self.tile = [ + ( + "raw", + (0, 0) + self.size, + self.fp.tell() - len(buffer), + (self.mode, 0, 1), + ) + ] + + break + + else: + # read key/value pair + if b"\n" not in buffer: + buffer += self.fp.read(100) + lines = buffer.split(b"\n") + s += lines.pop(0) + buffer = b"\n".join(lines) + if len(s) == 1 or len(s) > 100: + break + if s[0] == ord(b"*"): + continue # comment + + m = field.match(s) + if not m: + break + k, v = m.group(1, 2) + if k == b"width": + xsize = int(v) + self._size = xsize, ysize + elif k == b"height": + ysize = int(v) + self._size = xsize, ysize + elif k == b"pixel" and v == b"n8": + self._mode = "L" + + +# +# -------------------------------------------------------------------- + +Image.register_open(ImtImageFile.format, ImtImageFile) + +# +# no extension registered (".im" is simply too common) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/IptcImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/IptcImagePlugin.py new file mode 100644 index 00000000..40960943 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/IptcImagePlugin.py @@ -0,0 +1,235 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IPTC/NAA file handling +# +# history: +# 1995-10-01 fl Created +# 1998-03-09 fl Cleaned up and added to PIL +# 2002-06-18 fl Added getiptcinfo helper +# +# Copyright (c) Secret Labs AB 1997-2002. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from io import BytesIO +from typing import Sequence + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._deprecate import deprecate + +COMPRESSION = {1: "raw", 5: "jpeg"} + + +def __getattr__(name: str) -> bytes: + if name == "PAD": + deprecate("IptcImagePlugin.PAD", 12) + return b"\0\0\0\0" + msg = f"module '{__name__}' has no attribute '{name}'" + raise AttributeError(msg) + + +# +# Helpers + + +def _i(c: bytes) -> int: + return i32((b"\0\0\0\0" + c)[-4:]) + + +def _i8(c: int | bytes) -> int: + return c if isinstance(c, int) else c[0] + + +def i(c: bytes) -> int: + """.. deprecated:: 10.2.0""" + deprecate("IptcImagePlugin.i", 12) + return _i(c) + + +def dump(c: Sequence[int | bytes]) -> None: + """.. deprecated:: 10.2.0""" + deprecate("IptcImagePlugin.dump", 12) + for i in c: + print("%02x" % _i8(i), end=" ") + print() + + +## +# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields +# from TIFF and JPEG files, use the getiptcinfo function. + + +class IptcImageFile(ImageFile.ImageFile): + format = "IPTC" + format_description = "IPTC/NAA" + + def getint(self, key: tuple[int, int]) -> int: + return _i(self.info[key]) + + def field(self) -> tuple[tuple[int, int] | None, int]: + # + # get a IPTC field header + s = self.fp.read(5) + if not s.strip(b"\x00"): + return None, 0 + + tag = s[1], s[2] + + # syntax + if s[0] != 0x1C or tag[0] not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 240]: + msg = "invalid IPTC/NAA file" + raise SyntaxError(msg) + + # field size + size = s[3] + if size > 132: + msg = "illegal field length in IPTC/NAA file" + raise OSError(msg) + elif size == 128: + size = 0 + elif size > 128: + size = _i(self.fp.read(size - 128)) + else: + size = i16(s, 3) + + return tag, size + + def _open(self) -> None: + # load descriptive fields + while True: + offset = self.fp.tell() + tag, size = self.field() + if not tag or tag == (8, 10): + break + if size: + tagdata = self.fp.read(size) + else: + tagdata = None + if tag in self.info: + if isinstance(self.info[tag], list): + self.info[tag].append(tagdata) + else: + self.info[tag] = [self.info[tag], tagdata] + else: + self.info[tag] = tagdata + + # mode + layers = self.info[(3, 60)][0] + component = self.info[(3, 60)][1] + if (3, 65) in self.info: + id = self.info[(3, 65)][0] - 1 + else: + id = 0 + if layers == 1 and not component: + self._mode = "L" + elif layers == 3 and component: + self._mode = "RGB"[id] + elif layers == 4 and component: + self._mode = "CMYK"[id] + + # size + self._size = self.getint((3, 20)), self.getint((3, 30)) + + # compression + try: + compression = COMPRESSION[self.getint((3, 120))] + except KeyError as e: + msg = "Unknown IPTC image compression" + raise OSError(msg) from e + + # tile + if tag == (8, 10): + self.tile = [("iptc", (0, 0) + self.size, offset, compression)] + + def load(self): + if len(self.tile) != 1 or self.tile[0][0] != "iptc": + return ImageFile.ImageFile.load(self) + + offset, compression = self.tile[0][2:] + + self.fp.seek(offset) + + # Copy image data to temporary file + o = BytesIO() + if compression == "raw": + # To simplify access to the extracted file, + # prepend a PPM header + o.write(b"P5\n%d %d\n255\n" % self.size) + while True: + type, size = self.field() + if type != (8, 10): + break + while size > 0: + s = self.fp.read(min(size, 8192)) + if not s: + break + o.write(s) + size -= len(s) + + with Image.open(o) as _im: + _im.load() + self.im = _im.im + + +Image.register_open(IptcImageFile.format, IptcImageFile) + +Image.register_extension(IptcImageFile.format, ".iim") + + +def getiptcinfo(im): + """ + Get IPTC information from TIFF, JPEG, or IPTC file. + + :param im: An image containing IPTC data. + :returns: A dictionary containing IPTC information, or None if + no IPTC information block was found. + """ + from . import JpegImagePlugin, TiffImagePlugin + + data = None + + if isinstance(im, IptcImageFile): + # return info dictionary right away + return im.info + + elif isinstance(im, JpegImagePlugin.JpegImageFile): + # extract the IPTC/NAA resource + photoshop = im.info.get("photoshop") + if photoshop: + data = photoshop.get(0x0404) + + elif isinstance(im, TiffImagePlugin.TiffImageFile): + # get raw data from the IPTC/NAA tag (PhotoShop tags the data + # as 4-byte integers, so we cannot use the get method...) + try: + data = im.tag.tagdata[TiffImagePlugin.IPTC_NAA_CHUNK] + except (AttributeError, KeyError): + pass + + if data is None: + return None # no properties + + # create an IptcImagePlugin object without initializing it + class FakeImage: + pass + + im = FakeImage() + im.__class__ = IptcImageFile + + # parse the IPTC information chunk + im.info = {} + im.fp = BytesIO(data) + + try: + im._open() + except (IndexError, KeyError): + pass # expected failure + + return im.info diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/Jpeg2KImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/Jpeg2KImagePlugin.py new file mode 100644 index 00000000..4b778a0d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/Jpeg2KImagePlugin.py @@ -0,0 +1,398 @@ +# +# The Python Imaging Library +# $Id$ +# +# JPEG2000 file handling +# +# History: +# 2014-03-12 ajh Created +# 2021-06-30 rogermb Extract dpi information from the 'resc' header box +# +# Copyright (c) 2014 Coriolis Systems Limited +# Copyright (c) 2014 Alastair Houghton +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import struct + +from . import Image, ImageFile, _binary + + +class BoxReader: + """ + A small helper class to read fields stored in JPEG2000 header boxes + and to easily step into and read sub-boxes. + """ + + def __init__(self, fp, length=-1): + self.fp = fp + self.has_length = length >= 0 + self.length = length + self.remaining_in_box = -1 + + def _can_read(self, num_bytes): + if self.has_length and self.fp.tell() + num_bytes > self.length: + # Outside box: ensure we don't read past the known file length + return False + if self.remaining_in_box >= 0: + # Inside box contents: ensure read does not go past box boundaries + return num_bytes <= self.remaining_in_box + else: + return True # No length known, just read + + def _read_bytes(self, num_bytes): + if not self._can_read(num_bytes): + msg = "Not enough data in header" + raise SyntaxError(msg) + + data = self.fp.read(num_bytes) + if len(data) < num_bytes: + msg = f"Expected to read {num_bytes} bytes but only got {len(data)}." + raise OSError(msg) + + if self.remaining_in_box > 0: + self.remaining_in_box -= num_bytes + return data + + def read_fields(self, field_format): + size = struct.calcsize(field_format) + data = self._read_bytes(size) + return struct.unpack(field_format, data) + + def read_boxes(self): + size = self.remaining_in_box + data = self._read_bytes(size) + return BoxReader(io.BytesIO(data), size) + + def has_next_box(self): + if self.has_length: + return self.fp.tell() + self.remaining_in_box < self.length + else: + return True + + def next_box_type(self): + # Skip the rest of the box if it has not been read + if self.remaining_in_box > 0: + self.fp.seek(self.remaining_in_box, os.SEEK_CUR) + self.remaining_in_box = -1 + + # Read the length and type of the next box + lbox, tbox = self.read_fields(">I4s") + if lbox == 1: + lbox = self.read_fields(">Q")[0] + hlen = 16 + else: + hlen = 8 + + if lbox < hlen or not self._can_read(lbox - hlen): + msg = "Invalid header length" + raise SyntaxError(msg) + + self.remaining_in_box = lbox - hlen + return tbox + + +def _parse_codestream(fp): + """Parse the JPEG 2000 codestream to extract the size and component + count from the SIZ marker segment, returning a PIL (size, mode) tuple.""" + + hdr = fp.read(2) + lsiz = _binary.i16be(hdr) + siz = hdr + fp.read(lsiz - 2) + lsiz, rsiz, xsiz, ysiz, xosiz, yosiz, _, _, _, _, csiz = struct.unpack_from( + ">HHIIIIIIIIH", siz + ) + ssiz = [None] * csiz + xrsiz = [None] * csiz + yrsiz = [None] * csiz + for i in range(csiz): + ssiz[i], xrsiz[i], yrsiz[i] = struct.unpack_from(">BBB", siz, 36 + 3 * i) + + size = (xsiz - xosiz, ysiz - yosiz) + if csiz == 1: + if (yrsiz[0] & 0x7F) > 8: + mode = "I;16" + else: + mode = "L" + elif csiz == 2: + mode = "LA" + elif csiz == 3: + mode = "RGB" + elif csiz == 4: + mode = "RGBA" + else: + mode = None + + return size, mode + + +def _res_to_dpi(num, denom, exp): + """Convert JPEG2000's (numerator, denominator, exponent-base-10) resolution, + calculated as (num / denom) * 10^exp and stored in dots per meter, + to floating-point dots per inch.""" + if denom != 0: + return (254 * num * (10**exp)) / (10000 * denom) + + +def _parse_jp2_header(fp): + """Parse the JP2 header box to extract size, component count, + color space information, and optionally DPI information, + returning a (size, mode, mimetype, dpi) tuple.""" + + # Find the JP2 header box + reader = BoxReader(fp) + header = None + mimetype = None + while reader.has_next_box(): + tbox = reader.next_box_type() + + if tbox == b"jp2h": + header = reader.read_boxes() + break + elif tbox == b"ftyp": + if reader.read_fields(">4s")[0] == b"jpx ": + mimetype = "image/jpx" + + size = None + mode = None + bpc = None + nc = None + dpi = None # 2-tuple of DPI info, or None + + while header.has_next_box(): + tbox = header.next_box_type() + + if tbox == b"ihdr": + height, width, nc, bpc = header.read_fields(">IIHB") + size = (width, height) + if nc == 1 and (bpc & 0x7F) > 8: + mode = "I;16" + elif nc == 1: + mode = "L" + elif nc == 2: + mode = "LA" + elif nc == 3: + mode = "RGB" + elif nc == 4: + mode = "RGBA" + elif tbox == b"res ": + res = header.read_boxes() + while res.has_next_box(): + tres = res.next_box_type() + if tres == b"resc": + vrcn, vrcd, hrcn, hrcd, vrce, hrce = res.read_fields(">HHHHBB") + hres = _res_to_dpi(hrcn, hrcd, hrce) + vres = _res_to_dpi(vrcn, vrcd, vrce) + if hres is not None and vres is not None: + dpi = (hres, vres) + break + + if size is None or mode is None: + msg = "Malformed JP2 header" + raise SyntaxError(msg) + + return size, mode, mimetype, dpi + + +## +# Image plugin for JPEG2000 images. + + +class Jpeg2KImageFile(ImageFile.ImageFile): + format = "JPEG2000" + format_description = "JPEG 2000 (ISO 15444)" + + def _open(self): + sig = self.fp.read(4) + if sig == b"\xff\x4f\xff\x51": + self.codec = "j2k" + self._size, self._mode = _parse_codestream(self.fp) + else: + sig = sig + self.fp.read(8) + + if sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a": + self.codec = "jp2" + header = _parse_jp2_header(self.fp) + self._size, self._mode, self.custom_mimetype, dpi = header + if dpi is not None: + self.info["dpi"] = dpi + if self.fp.read(12).endswith(b"jp2c\xff\x4f\xff\x51"): + self._parse_comment() + else: + msg = "not a JPEG 2000 file" + raise SyntaxError(msg) + + if self.size is None or self.mode is None: + msg = "unable to determine size/mode" + raise SyntaxError(msg) + + self._reduce = 0 + self.layers = 0 + + fd = -1 + length = -1 + + try: + fd = self.fp.fileno() + length = os.fstat(fd).st_size + except Exception: + fd = -1 + try: + pos = self.fp.tell() + self.fp.seek(0, io.SEEK_END) + length = self.fp.tell() + self.fp.seek(pos) + except Exception: + length = -1 + + self.tile = [ + ( + "jpeg2k", + (0, 0) + self.size, + 0, + (self.codec, self._reduce, self.layers, fd, length), + ) + ] + + def _parse_comment(self): + hdr = self.fp.read(2) + length = _binary.i16be(hdr) + self.fp.seek(length - 2, os.SEEK_CUR) + + while True: + marker = self.fp.read(2) + if not marker: + break + typ = marker[1] + if typ in (0x90, 0xD9): + # Start of tile or end of codestream + break + hdr = self.fp.read(2) + length = _binary.i16be(hdr) + if typ == 0x64: + # Comment + self.info["comment"] = self.fp.read(length - 2)[2:] + break + else: + self.fp.seek(length - 2, os.SEEK_CUR) + + @property + def reduce(self): + # https://github.com/python-pillow/Pillow/issues/4343 found that the + # new Image 'reduce' method was shadowed by this plugin's 'reduce' + # property. This attempts to allow for both scenarios + return self._reduce or super().reduce + + @reduce.setter + def reduce(self, value): + self._reduce = value + + def load(self): + if self.tile and self._reduce: + power = 1 << self._reduce + adjust = power >> 1 + self._size = ( + int((self.size[0] + adjust) / power), + int((self.size[1] + adjust) / power), + ) + + # Update the reduce and layers settings + t = self.tile[0] + t3 = (t[3][0], self._reduce, self.layers, t[3][3], t[3][4]) + self.tile = [(t[0], (0, 0) + self.size, t[2], t3)] + + return ImageFile.ImageFile.load(self) + + +def _accept(prefix): + return ( + prefix[:4] == b"\xff\x4f\xff\x51" + or prefix[:12] == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" + ) + + +# ------------------------------------------------------------ +# Save support + + +def _save(im, fp, filename): + # Get the keyword arguments + info = im.encoderinfo + + if filename.endswith(".j2k") or info.get("no_jp2", False): + kind = "j2k" + else: + kind = "jp2" + + offset = info.get("offset", None) + tile_offset = info.get("tile_offset", None) + tile_size = info.get("tile_size", None) + quality_mode = info.get("quality_mode", "rates") + quality_layers = info.get("quality_layers", None) + if quality_layers is not None and not ( + isinstance(quality_layers, (list, tuple)) + and all( + isinstance(quality_layer, (int, float)) for quality_layer in quality_layers + ) + ): + msg = "quality_layers must be a sequence of numbers" + raise ValueError(msg) + + num_resolutions = info.get("num_resolutions", 0) + cblk_size = info.get("codeblock_size", None) + precinct_size = info.get("precinct_size", None) + irreversible = info.get("irreversible", False) + progression = info.get("progression", "LRCP") + cinema_mode = info.get("cinema_mode", "no") + mct = info.get("mct", 0) + signed = info.get("signed", False) + comment = info.get("comment") + if isinstance(comment, str): + comment = comment.encode() + plt = info.get("plt", False) + + fd = -1 + if hasattr(fp, "fileno"): + try: + fd = fp.fileno() + except Exception: + fd = -1 + + im.encoderconfig = ( + offset, + tile_offset, + tile_size, + quality_mode, + quality_layers, + num_resolutions, + cblk_size, + precinct_size, + irreversible, + progression, + cinema_mode, + mct, + signed, + fd, + comment, + plt, + ) + + ImageFile._save(im, fp, [("jpeg2k", (0, 0) + im.size, 0, kind)]) + + +# ------------------------------------------------------------ +# Registry stuff + + +Image.register_open(Jpeg2KImageFile.format, Jpeg2KImageFile, _accept) +Image.register_save(Jpeg2KImageFile.format, _save) + +Image.register_extensions( + Jpeg2KImageFile.format, [".jp2", ".j2k", ".jpc", ".jpf", ".jpx", ".j2c"] +) + +Image.register_mime(Jpeg2KImageFile.format, "image/jp2") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/JpegImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/JpegImagePlugin.py new file mode 100644 index 00000000..81b8749a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/JpegImagePlugin.py @@ -0,0 +1,868 @@ +# +# The Python Imaging Library. +# $Id$ +# +# JPEG (JFIF) file handling +# +# See "Digital Compression and Coding of Continuous-Tone Still Images, +# Part 1, Requirements and Guidelines" (CCITT T.81 / ISO 10918-1) +# +# History: +# 1995-09-09 fl Created +# 1995-09-13 fl Added full parser +# 1996-03-25 fl Added hack to use the IJG command line utilities +# 1996-05-05 fl Workaround Photoshop 2.5 CMYK polarity bug +# 1996-05-28 fl Added draft support, JFIF version (0.1) +# 1996-12-30 fl Added encoder options, added progression property (0.2) +# 1997-08-27 fl Save mode 1 images as BW (0.3) +# 1998-07-12 fl Added YCbCr to draft and save methods (0.4) +# 1998-10-19 fl Don't hang on files using 16-bit DQT's (0.4.1) +# 2001-04-16 fl Extract DPI settings from JFIF files (0.4.2) +# 2002-07-01 fl Skip pad bytes before markers; identify Exif files (0.4.3) +# 2003-04-25 fl Added experimental EXIF decoder (0.5) +# 2003-06-06 fl Added experimental EXIF GPSinfo decoder +# 2003-09-13 fl Extract COM markers +# 2009-09-06 fl Added icc_profile support (from Florian Hoech) +# 2009-03-06 fl Changed CMYK handling; always use Adobe polarity (0.6) +# 2009-03-08 fl Added subsampling support (from Justin Huff). +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import array +import io +import math +import os +import struct +import subprocess +import sys +import tempfile +import warnings + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from ._binary import o16be as o16 +from .JpegPresets import presets + +# +# Parser + + +def Skip(self, marker): + n = i16(self.fp.read(2)) - 2 + ImageFile._safe_read(self.fp, n) + + +def APP(self, marker): + # + # Application marker. Store these in the APP dictionary. + # Also look for well-known application markers. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + + app = "APP%d" % (marker & 15) + + self.app[app] = s # compatibility + self.applist.append((app, s)) + + if marker == 0xFFE0 and s[:4] == b"JFIF": + # extract JFIF information + self.info["jfif"] = version = i16(s, 5) # version + self.info["jfif_version"] = divmod(version, 256) + # extract JFIF properties + try: + jfif_unit = s[7] + jfif_density = i16(s, 8), i16(s, 10) + except Exception: + pass + else: + if jfif_unit == 1: + self.info["dpi"] = jfif_density + self.info["jfif_unit"] = jfif_unit + self.info["jfif_density"] = jfif_density + elif marker == 0xFFE1 and s[:6] == b"Exif\0\0": + # extract EXIF information + if "exif" in self.info: + self.info["exif"] += s[6:] + else: + self.info["exif"] = s + self._exif_offset = self.fp.tell() - n + 6 + elif marker == 0xFFE2 and s[:5] == b"FPXR\0": + # extract FlashPix information (incomplete) + self.info["flashpix"] = s # FIXME: value will change + elif marker == 0xFFE2 and s[:12] == b"ICC_PROFILE\0": + # Since an ICC profile can be larger than the maximum size of + # a JPEG marker (64K), we need provisions to split it into + # multiple markers. The format defined by the ICC specifies + # one or more APP2 markers containing the following data: + # Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + # Marker sequence number 1, 2, etc (1 byte) + # Number of markers Total of APP2's used (1 byte) + # Profile data (remainder of APP2 data) + # Decoders should use the marker sequence numbers to + # reassemble the profile, rather than assuming that the APP2 + # markers appear in the correct sequence. + self.icclist.append(s) + elif marker == 0xFFED and s[:14] == b"Photoshop 3.0\x00": + # parse the image resource block + offset = 14 + photoshop = self.info.setdefault("photoshop", {}) + while s[offset : offset + 4] == b"8BIM": + try: + offset += 4 + # resource code + code = i16(s, offset) + offset += 2 + # resource name (usually empty) + name_len = s[offset] + # name = s[offset+1:offset+1+name_len] + offset += 1 + name_len + offset += offset & 1 # align + # resource data block + size = i32(s, offset) + offset += 4 + data = s[offset : offset + size] + if code == 0x03ED: # ResolutionInfo + data = { + "XResolution": i32(data, 0) / 65536, + "DisplayedUnitsX": i16(data, 4), + "YResolution": i32(data, 8) / 65536, + "DisplayedUnitsY": i16(data, 12), + } + photoshop[code] = data + offset += size + offset += offset & 1 # align + except struct.error: + break # insufficient data + + elif marker == 0xFFEE and s[:5] == b"Adobe": + self.info["adobe"] = i16(s, 5) + # extract Adobe custom properties + try: + adobe_transform = s[11] + except IndexError: + pass + else: + self.info["adobe_transform"] = adobe_transform + elif marker == 0xFFE2 and s[:4] == b"MPF\0": + # extract MPO information + self.info["mp"] = s[4:] + # offset is current location minus buffer size + # plus constant header size + self.info["mpoffset"] = self.fp.tell() - n + 4 + + # If DPI isn't in JPEG header, fetch from EXIF + if "dpi" not in self.info and "exif" in self.info: + try: + exif = self.getexif() + resolution_unit = exif[0x0128] + x_resolution = exif[0x011A] + try: + dpi = float(x_resolution[0]) / x_resolution[1] + except TypeError: + dpi = x_resolution + if math.isnan(dpi): + msg = "DPI is not a number" + raise ValueError(msg) + if resolution_unit == 3: # cm + # 1 dpcm = 2.54 dpi + dpi *= 2.54 + self.info["dpi"] = dpi, dpi + except ( + struct.error, + KeyError, + SyntaxError, + TypeError, + ValueError, + ZeroDivisionError, + ): + # struct.error for truncated EXIF + # KeyError for dpi not included + # SyntaxError for invalid/unreadable EXIF + # ValueError or TypeError for dpi being an invalid float + # ZeroDivisionError for invalid dpi rational value + self.info["dpi"] = 72, 72 + + +def COM(self, marker): + # + # Comment marker. Store these in the APP dictionary. + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + + self.info["comment"] = s + self.app["COM"] = s # compatibility + self.applist.append(("COM", s)) + + +def SOF(self, marker): + # + # Start of frame marker. Defines the size and mode of the + # image. JPEG is colour blind, so we use some simple + # heuristics to map the number of layers to an appropriate + # mode. Note that this could be made a bit brighter, by + # looking for JFIF and Adobe APP markers. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + self._size = i16(s, 3), i16(s, 1) + + self.bits = s[0] + if self.bits != 8: + msg = f"cannot handle {self.bits}-bit layers" + raise SyntaxError(msg) + + self.layers = s[5] + if self.layers == 1: + self._mode = "L" + elif self.layers == 3: + self._mode = "RGB" + elif self.layers == 4: + self._mode = "CMYK" + else: + msg = f"cannot handle {self.layers}-layer images" + raise SyntaxError(msg) + + if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]: + self.info["progressive"] = self.info["progression"] = 1 + + if self.icclist: + # fixup icc profile + self.icclist.sort() # sort by sequence number + if self.icclist[0][13] == len(self.icclist): + profile = [p[14:] for p in self.icclist] + icc_profile = b"".join(profile) + else: + icc_profile = None # wrong number of fragments + self.info["icc_profile"] = icc_profile + self.icclist = [] + + for i in range(6, len(s), 3): + t = s[i : i + 3] + # 4-tuples: id, vsamp, hsamp, qtable + self.layer.append((t[0], t[1] // 16, t[1] & 15, t[2])) + + +def DQT(self, marker): + # + # Define quantization table. Note that there might be more + # than one table in each marker. + + # FIXME: The quantization tables can be used to estimate the + # compression quality. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + while len(s): + v = s[0] + precision = 1 if (v // 16 == 0) else 2 # in bytes + qt_length = 1 + precision * 64 + if len(s) < qt_length: + msg = "bad quantization table marker" + raise SyntaxError(msg) + data = array.array("B" if precision == 1 else "H", s[1:qt_length]) + if sys.byteorder == "little" and precision > 1: + data.byteswap() # the values are always big-endian + self.quantization[v & 15] = [data[i] for i in zigzag_index] + s = s[qt_length:] + + +# +# JPEG marker table + +MARKER = { + 0xFFC0: ("SOF0", "Baseline DCT", SOF), + 0xFFC1: ("SOF1", "Extended Sequential DCT", SOF), + 0xFFC2: ("SOF2", "Progressive DCT", SOF), + 0xFFC3: ("SOF3", "Spatial lossless", SOF), + 0xFFC4: ("DHT", "Define Huffman table", Skip), + 0xFFC5: ("SOF5", "Differential sequential DCT", SOF), + 0xFFC6: ("SOF6", "Differential progressive DCT", SOF), + 0xFFC7: ("SOF7", "Differential spatial", SOF), + 0xFFC8: ("JPG", "Extension", None), + 0xFFC9: ("SOF9", "Extended sequential DCT (AC)", SOF), + 0xFFCA: ("SOF10", "Progressive DCT (AC)", SOF), + 0xFFCB: ("SOF11", "Spatial lossless DCT (AC)", SOF), + 0xFFCC: ("DAC", "Define arithmetic coding conditioning", Skip), + 0xFFCD: ("SOF13", "Differential sequential DCT (AC)", SOF), + 0xFFCE: ("SOF14", "Differential progressive DCT (AC)", SOF), + 0xFFCF: ("SOF15", "Differential spatial (AC)", SOF), + 0xFFD0: ("RST0", "Restart 0", None), + 0xFFD1: ("RST1", "Restart 1", None), + 0xFFD2: ("RST2", "Restart 2", None), + 0xFFD3: ("RST3", "Restart 3", None), + 0xFFD4: ("RST4", "Restart 4", None), + 0xFFD5: ("RST5", "Restart 5", None), + 0xFFD6: ("RST6", "Restart 6", None), + 0xFFD7: ("RST7", "Restart 7", None), + 0xFFD8: ("SOI", "Start of image", None), + 0xFFD9: ("EOI", "End of image", None), + 0xFFDA: ("SOS", "Start of scan", Skip), + 0xFFDB: ("DQT", "Define quantization table", DQT), + 0xFFDC: ("DNL", "Define number of lines", Skip), + 0xFFDD: ("DRI", "Define restart interval", Skip), + 0xFFDE: ("DHP", "Define hierarchical progression", SOF), + 0xFFDF: ("EXP", "Expand reference component", Skip), + 0xFFE0: ("APP0", "Application segment 0", APP), + 0xFFE1: ("APP1", "Application segment 1", APP), + 0xFFE2: ("APP2", "Application segment 2", APP), + 0xFFE3: ("APP3", "Application segment 3", APP), + 0xFFE4: ("APP4", "Application segment 4", APP), + 0xFFE5: ("APP5", "Application segment 5", APP), + 0xFFE6: ("APP6", "Application segment 6", APP), + 0xFFE7: ("APP7", "Application segment 7", APP), + 0xFFE8: ("APP8", "Application segment 8", APP), + 0xFFE9: ("APP9", "Application segment 9", APP), + 0xFFEA: ("APP10", "Application segment 10", APP), + 0xFFEB: ("APP11", "Application segment 11", APP), + 0xFFEC: ("APP12", "Application segment 12", APP), + 0xFFED: ("APP13", "Application segment 13", APP), + 0xFFEE: ("APP14", "Application segment 14", APP), + 0xFFEF: ("APP15", "Application segment 15", APP), + 0xFFF0: ("JPG0", "Extension 0", None), + 0xFFF1: ("JPG1", "Extension 1", None), + 0xFFF2: ("JPG2", "Extension 2", None), + 0xFFF3: ("JPG3", "Extension 3", None), + 0xFFF4: ("JPG4", "Extension 4", None), + 0xFFF5: ("JPG5", "Extension 5", None), + 0xFFF6: ("JPG6", "Extension 6", None), + 0xFFF7: ("JPG7", "Extension 7", None), + 0xFFF8: ("JPG8", "Extension 8", None), + 0xFFF9: ("JPG9", "Extension 9", None), + 0xFFFA: ("JPG10", "Extension 10", None), + 0xFFFB: ("JPG11", "Extension 11", None), + 0xFFFC: ("JPG12", "Extension 12", None), + 0xFFFD: ("JPG13", "Extension 13", None), + 0xFFFE: ("COM", "Comment", COM), +} + + +def _accept(prefix): + # Magic number was taken from https://en.wikipedia.org/wiki/JPEG + return prefix[:3] == b"\xFF\xD8\xFF" + + +## +# Image plugin for JPEG and JFIF images. + + +class JpegImageFile(ImageFile.ImageFile): + format = "JPEG" + format_description = "JPEG (ISO 10918)" + + def _open(self): + s = self.fp.read(3) + + if not _accept(s): + msg = "not a JPEG file" + raise SyntaxError(msg) + s = b"\xFF" + + # Create attributes + self.bits = self.layers = 0 + + # JPEG specifics (internal) + self.layer = [] + self.huffman_dc = {} + self.huffman_ac = {} + self.quantization = {} + self.app = {} # compatibility + self.applist = [] + self.icclist = [] + + while True: + i = s[0] + if i == 0xFF: + s = s + self.fp.read(1) + i = i16(s) + else: + # Skip non-0xFF junk + s = self.fp.read(1) + continue + + if i in MARKER: + name, description, handler = MARKER[i] + if handler is not None: + handler(self, i) + if i == 0xFFDA: # start of scan + rawmode = self.mode + if self.mode == "CMYK": + rawmode = "CMYK;I" # assume adobe conventions + self.tile = [("jpeg", (0, 0) + self.size, 0, (rawmode, ""))] + # self.__offset = self.fp.tell() + break + s = self.fp.read(1) + elif i in {0, 0xFFFF}: + # padded marker or junk; move on + s = b"\xff" + elif i == 0xFF00: # Skip extraneous data (escaped 0xFF) + s = self.fp.read(1) + else: + msg = "no marker found" + raise SyntaxError(msg) + + def load_read(self, read_bytes): + """ + internal: read more image data + For premature EOF and LOAD_TRUNCATED_IMAGES adds EOI marker + so libjpeg can finish decoding + """ + s = self.fp.read(read_bytes) + + if not s and ImageFile.LOAD_TRUNCATED_IMAGES and not hasattr(self, "_ended"): + # Premature EOF. + # Pretend file is finished adding EOI marker + self._ended = True + return b"\xFF\xD9" + + return s + + def draft(self, mode, size): + if len(self.tile) != 1: + return + + # Protect from second call + if self.decoderconfig: + return + + d, e, o, a = self.tile[0] + scale = 1 + original_size = self.size + + if a[0] == "RGB" and mode in ["L", "YCbCr"]: + self._mode = mode + a = mode, "" + + if size: + scale = min(self.size[0] // size[0], self.size[1] // size[1]) + for s in [8, 4, 2, 1]: + if scale >= s: + break + e = ( + e[0], + e[1], + (e[2] - e[0] + s - 1) // s + e[0], + (e[3] - e[1] + s - 1) // s + e[1], + ) + self._size = ((self.size[0] + s - 1) // s, (self.size[1] + s - 1) // s) + scale = s + + self.tile = [(d, e, o, a)] + self.decoderconfig = (scale, 0) + + box = (0, 0, original_size[0] / scale, original_size[1] / scale) + return self.mode, box + + def load_djpeg(self): + # ALTERNATIVE: handle JPEGs via the IJG command line utilities + + f, path = tempfile.mkstemp() + os.close(f) + if os.path.exists(self.filename): + subprocess.check_call(["djpeg", "-outfile", path, self.filename]) + else: + try: + os.unlink(path) + except OSError: + pass + + msg = "Invalid Filename" + raise ValueError(msg) + + try: + with Image.open(path) as _im: + _im.load() + self.im = _im.im + finally: + try: + os.unlink(path) + except OSError: + pass + + self._mode = self.im.mode + self._size = self.im.size + + self.tile = [] + + def _getexif(self): + return _getexif(self) + + def _getmp(self): + return _getmp(self) + + def getxmp(self): + """ + Returns a dictionary containing the XMP tags. + Requires defusedxml to be installed. + + :returns: XMP tags in a dictionary. + """ + + for segment, content in self.applist: + if segment == "APP1": + marker, xmp_tags = content.split(b"\x00")[:2] + if marker == b"http://ns.adobe.com/xap/1.0/": + return self._getxmp(xmp_tags) + return {} + + +def _getexif(self): + if "exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + +def _getmp(self): + # Extract MP information. This method was inspired by the "highly + # experimental" _getexif version that's been in use for years now, + # itself based on the ImageFileDirectory class in the TIFF plugin. + + # The MP record essentially consists of a TIFF file embedded in a JPEG + # application marker. + try: + data = self.info["mp"] + except KeyError: + return None + file_contents = io.BytesIO(data) + head = file_contents.read(8) + endianness = ">" if head[:4] == b"\x4d\x4d\x00\x2a" else "<" + # process dictionary + from . import TiffImagePlugin + + try: + info = TiffImagePlugin.ImageFileDirectory_v2(head) + file_contents.seek(info.next) + info.load(file_contents) + mp = dict(info) + except Exception as e: + msg = "malformed MP Index (unreadable directory)" + raise SyntaxError(msg) from e + # it's an error not to have a number of images + try: + quant = mp[0xB001] + except KeyError as e: + msg = "malformed MP Index (no number of images)" + raise SyntaxError(msg) from e + # get MP entries + mpentries = [] + try: + rawmpentries = mp[0xB002] + for entrynum in range(0, quant): + unpackedentry = struct.unpack_from( + f"{endianness}LLLHH", rawmpentries, entrynum * 16 + ) + labels = ("Attribute", "Size", "DataOffset", "EntryNo1", "EntryNo2") + mpentry = dict(zip(labels, unpackedentry)) + mpentryattr = { + "DependentParentImageFlag": bool(mpentry["Attribute"] & (1 << 31)), + "DependentChildImageFlag": bool(mpentry["Attribute"] & (1 << 30)), + "RepresentativeImageFlag": bool(mpentry["Attribute"] & (1 << 29)), + "Reserved": (mpentry["Attribute"] & (3 << 27)) >> 27, + "ImageDataFormat": (mpentry["Attribute"] & (7 << 24)) >> 24, + "MPType": mpentry["Attribute"] & 0x00FFFFFF, + } + if mpentryattr["ImageDataFormat"] == 0: + mpentryattr["ImageDataFormat"] = "JPEG" + else: + msg = "unsupported picture format in MPO" + raise SyntaxError(msg) + mptypemap = { + 0x000000: "Undefined", + 0x010001: "Large Thumbnail (VGA Equivalent)", + 0x010002: "Large Thumbnail (Full HD Equivalent)", + 0x020001: "Multi-Frame Image (Panorama)", + 0x020002: "Multi-Frame Image: (Disparity)", + 0x020003: "Multi-Frame Image: (Multi-Angle)", + 0x030000: "Baseline MP Primary Image", + } + mpentryattr["MPType"] = mptypemap.get(mpentryattr["MPType"], "Unknown") + mpentry["Attribute"] = mpentryattr + mpentries.append(mpentry) + mp[0xB002] = mpentries + except KeyError as e: + msg = "malformed MP Index (bad MP Entry)" + raise SyntaxError(msg) from e + # Next we should try and parse the individual image unique ID list; + # we don't because I've never seen this actually used in a real MPO + # file and so can't test it. + return mp + + +# -------------------------------------------------------------------- +# stuff to save JPEG files + +RAWMODE = { + "1": "L", + "L": "L", + "RGB": "RGB", + "RGBX": "RGB", + "CMYK": "CMYK;I", # assume adobe conventions + "YCbCr": "YCbCr", +} + +# fmt: off +zigzag_index = ( + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63, +) + +samplings = { + (1, 1, 1, 1, 1, 1): 0, + (2, 1, 1, 1, 1, 1): 1, + (2, 2, 1, 1, 1, 1): 2, +} +# fmt: on + + +def get_sampling(im): + # There's no subsampling when images have only 1 layer + # (grayscale images) or when they are CMYK (4 layers), + # so set subsampling to the default value. + # + # NOTE: currently Pillow can't encode JPEG to YCCK format. + # If YCCK support is added in the future, subsampling code will have + # to be updated (here and in JpegEncode.c) to deal with 4 layers. + if not hasattr(im, "layers") or im.layers in (1, 4): + return -1 + sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3] + return samplings.get(sampling, -1) + + +def _save(im, fp, filename): + if im.width == 0 or im.height == 0: + msg = "cannot write empty image as JPEG" + raise ValueError(msg) + + try: + rawmode = RAWMODE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as JPEG" + raise OSError(msg) from e + + info = im.encoderinfo + + dpi = [round(x) for x in info.get("dpi", (0, 0))] + + quality = info.get("quality", -1) + subsampling = info.get("subsampling", -1) + qtables = info.get("qtables") + + if quality == "keep": + quality = -1 + subsampling = "keep" + qtables = "keep" + elif quality in presets: + preset = presets[quality] + quality = -1 + subsampling = preset.get("subsampling", -1) + qtables = preset.get("quantization") + elif not isinstance(quality, int): + msg = "Invalid quality setting" + raise ValueError(msg) + else: + if subsampling in presets: + subsampling = presets[subsampling].get("subsampling", -1) + if isinstance(qtables, str) and qtables in presets: + qtables = presets[qtables].get("quantization") + + if subsampling == "4:4:4": + subsampling = 0 + elif subsampling == "4:2:2": + subsampling = 1 + elif subsampling == "4:2:0": + subsampling = 2 + elif subsampling == "4:1:1": + # For compatibility. Before Pillow 4.3, 4:1:1 actually meant 4:2:0. + # Set 4:2:0 if someone is still using that value. + subsampling = 2 + elif subsampling == "keep": + if im.format != "JPEG": + msg = "Cannot use 'keep' when original image is not a JPEG" + raise ValueError(msg) + subsampling = get_sampling(im) + + def validate_qtables(qtables): + if qtables is None: + return qtables + if isinstance(qtables, str): + try: + lines = [ + int(num) + for line in qtables.splitlines() + for num in line.split("#", 1)[0].split() + ] + except ValueError as e: + msg = "Invalid quantization table" + raise ValueError(msg) from e + else: + qtables = [lines[s : s + 64] for s in range(0, len(lines), 64)] + if isinstance(qtables, (tuple, list, dict)): + if isinstance(qtables, dict): + qtables = [ + qtables[key] for key in range(len(qtables)) if key in qtables + ] + elif isinstance(qtables, tuple): + qtables = list(qtables) + if not (0 < len(qtables) < 5): + msg = "None or too many quantization tables" + raise ValueError(msg) + for idx, table in enumerate(qtables): + try: + if len(table) != 64: + msg = "Invalid quantization table" + raise TypeError(msg) + table = array.array("H", table) + except TypeError as e: + msg = "Invalid quantization table" + raise ValueError(msg) from e + else: + qtables[idx] = list(table) + return qtables + + if qtables == "keep": + if im.format != "JPEG": + msg = "Cannot use 'keep' when original image is not a JPEG" + raise ValueError(msg) + qtables = getattr(im, "quantization", None) + qtables = validate_qtables(qtables) + + extra = info.get("extra", b"") + + MAX_BYTES_IN_MARKER = 65533 + icc_profile = info.get("icc_profile") + if icc_profile: + ICC_OVERHEAD_LEN = 14 + MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN + markers = [] + while icc_profile: + markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER]) + icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:] + i = 1 + for marker in markers: + size = o16(2 + ICC_OVERHEAD_LEN + len(marker)) + extra += ( + b"\xFF\xE2" + + size + + b"ICC_PROFILE\0" + + o8(i) + + o8(len(markers)) + + marker + ) + i += 1 + + comment = info.get("comment", im.info.get("comment")) + + # "progressive" is the official name, but older documentation + # says "progression" + # FIXME: issue a warning if the wrong form is used (post-1.1.7) + progressive = info.get("progressive", False) or info.get("progression", False) + + optimize = info.get("optimize", False) + + exif = info.get("exif", b"") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + if len(exif) > MAX_BYTES_IN_MARKER: + msg = "EXIF data is too long" + raise ValueError(msg) + + # get keyword arguments + im.encoderconfig = ( + quality, + progressive, + info.get("smooth", 0), + optimize, + info.get("keep_rgb", False), + info.get("streamtype", 0), + dpi[0], + dpi[1], + subsampling, + info.get("restart_marker_blocks", 0), + info.get("restart_marker_rows", 0), + qtables, + comment, + extra, + exif, + ) + + # if we optimize, libjpeg needs a buffer big enough to hold the whole image + # in a shot. Guessing on the size, at im.size bytes. (raw pixel size is + # channels*size, this is a value that's been used in a django patch. + # https://github.com/matthewwithanm/django-imagekit/issues/50 + bufsize = 0 + if optimize or progressive: + # CMYK can be bigger + if im.mode == "CMYK": + bufsize = 4 * im.size[0] * im.size[1] + # keep sets quality to -1, but the actual value may be high. + elif quality >= 95 or quality == -1: + bufsize = 2 * im.size[0] * im.size[1] + else: + bufsize = im.size[0] * im.size[1] + if exif: + bufsize += len(exif) + 5 + if extra: + bufsize += len(extra) + 1 + else: + # The EXIF info needs to be written as one block, + APP1, + one spare byte. + # Ensure that our buffer is big enough. Same with the icc_profile block. + bufsize = max(bufsize, len(exif) + 5, len(extra) + 1) + + ImageFile._save(im, fp, [("jpeg", (0, 0) + im.size, 0, rawmode)], bufsize) + + +def _save_cjpeg(im, fp, filename): + # ALTERNATIVE: handle JPEGs via the IJG command line utilities. + tempfile = im._dump() + subprocess.check_call(["cjpeg", "-outfile", filename, tempfile]) + try: + os.unlink(tempfile) + except OSError: + pass + + +## +# Factory for making JPEG and MPO instances +def jpeg_factory(fp=None, filename=None): + im = JpegImageFile(fp, filename) + try: + mpheader = im._getmp() + if mpheader[45057] > 1: + # It's actually an MPO + from .MpoImagePlugin import MpoImageFile + + # Don't reload everything, just convert it. + im = MpoImageFile.adopt(im, mpheader) + except (TypeError, IndexError): + # It is really a JPEG + pass + except SyntaxError: + warnings.warn( + "Image appears to be a malformed MPO file, it will be " + "interpreted as a base JPEG file" + ) + return im + + +# --------------------------------------------------------------------- +# Registry stuff + +Image.register_open(JpegImageFile.format, jpeg_factory, _accept) +Image.register_save(JpegImageFile.format, _save) + +Image.register_extensions(JpegImageFile.format, [".jfif", ".jpe", ".jpg", ".jpeg"]) + +Image.register_mime(JpegImageFile.format, "image/jpeg") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/JpegPresets.py b/dbdpy-env/lib/python3.9/site-packages/PIL/JpegPresets.py new file mode 100644 index 00000000..9ecfdb25 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/JpegPresets.py @@ -0,0 +1,241 @@ +""" +JPEG quality settings equivalent to the Photoshop settings. +Can be used when saving JPEG files. + +The following presets are available by default: +``web_low``, ``web_medium``, ``web_high``, ``web_very_high``, ``web_maximum``, +``low``, ``medium``, ``high``, ``maximum``. +More presets can be added to the :py:data:`presets` dict if needed. + +To apply the preset, specify:: + + quality="preset_name" + +To apply only the quantization table:: + + qtables="preset_name" + +To apply only the subsampling setting:: + + subsampling="preset_name" + +Example:: + + im.save("image_name.jpg", quality="web_high") + +Subsampling +----------- + +Subsampling is the practice of encoding images by implementing less resolution +for chroma information than for luma information. +(ref.: https://en.wikipedia.org/wiki/Chroma_subsampling) + +Possible subsampling values are 0, 1 and 2 that correspond to 4:4:4, 4:2:2 and +4:2:0. + +You can get the subsampling of a JPEG with the +:func:`.JpegImagePlugin.get_sampling` function. + +In JPEG compressed data a JPEG marker is used instead of an EXIF tag. +(ref.: https://exiv2.org/tags.html) + + +Quantization tables +------------------- + +They are values use by the DCT (Discrete cosine transform) to remove +*unnecessary* information from the image (the lossy part of the compression). +(ref.: https://en.wikipedia.org/wiki/Quantization_matrix#Quantization_matrices, +https://en.wikipedia.org/wiki/JPEG#Quantization) + +You can get the quantization tables of a JPEG with:: + + im.quantization + +This will return a dict with a number of lists. You can pass this dict +directly as the qtables argument when saving a JPEG. + +The quantization table format in presets is a list with sublists. These formats +are interchangeable. + +Libjpeg ref.: +https://web.archive.org/web/20120328125543/http://www.jpegcameras.com/libjpeg/libjpeg-3.html + +""" +from __future__ import annotations + +# fmt: off +presets = { + 'web_low': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [20, 16, 25, 39, 50, 46, 62, 68, + 16, 18, 23, 38, 38, 53, 65, 68, + 25, 23, 31, 38, 53, 65, 68, 68, + 39, 38, 38, 53, 65, 68, 68, 68, + 50, 38, 53, 65, 68, 68, 68, 68, + 46, 53, 65, 68, 68, 68, 68, 68, + 62, 65, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68], + [21, 25, 32, 38, 54, 68, 68, 68, + 25, 28, 24, 38, 54, 68, 68, 68, + 32, 24, 32, 43, 66, 68, 68, 68, + 38, 38, 43, 53, 68, 68, 68, 68, + 54, 54, 66, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68] + ]}, + 'web_medium': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [16, 11, 11, 16, 23, 27, 31, 30, + 11, 12, 12, 15, 20, 23, 23, 30, + 11, 12, 13, 16, 23, 26, 35, 47, + 16, 15, 16, 23, 26, 37, 47, 64, + 23, 20, 23, 26, 39, 51, 64, 64, + 27, 23, 26, 37, 51, 64, 64, 64, + 31, 23, 35, 47, 64, 64, 64, 64, + 30, 30, 47, 64, 64, 64, 64, 64], + [17, 15, 17, 21, 20, 26, 38, 48, + 15, 19, 18, 17, 20, 26, 35, 43, + 17, 18, 20, 22, 26, 30, 46, 53, + 21, 17, 22, 28, 30, 39, 53, 64, + 20, 20, 26, 30, 39, 48, 64, 64, + 26, 26, 30, 39, 48, 63, 64, 64, + 38, 35, 46, 53, 64, 64, 64, 64, + 48, 43, 53, 64, 64, 64, 64, 64] + ]}, + 'web_high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [6, 4, 4, 6, 9, 11, 12, 16, + 4, 5, 5, 6, 8, 10, 12, 12, + 4, 5, 5, 6, 10, 12, 14, 19, + 6, 6, 6, 11, 12, 15, 19, 28, + 9, 8, 10, 12, 16, 20, 27, 31, + 11, 10, 12, 15, 20, 27, 31, 31, + 12, 12, 14, 19, 27, 31, 31, 31, + 16, 12, 19, 28, 31, 31, 31, 31], + [7, 7, 13, 24, 26, 31, 31, 31, + 7, 12, 16, 21, 31, 31, 31, 31, + 13, 16, 17, 31, 31, 31, 31, 31, + 24, 21, 31, 31, 31, 31, 31, 31, + 26, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31] + ]}, + 'web_very_high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 4, 5, 7, 9, + 2, 2, 2, 4, 5, 7, 9, 12, + 3, 3, 4, 5, 8, 10, 12, 12, + 4, 4, 5, 7, 10, 12, 12, 12, + 5, 5, 7, 9, 12, 12, 12, 12, + 6, 6, 9, 12, 12, 12, 12, 12], + [3, 3, 5, 9, 13, 15, 15, 15, + 3, 4, 6, 11, 14, 12, 12, 12, + 5, 6, 9, 14, 12, 12, 12, 12, + 9, 11, 14, 12, 12, 12, 12, 12, + 13, 14, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'web_maximum': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 2, 2, + 1, 1, 1, 1, 1, 2, 2, 3, + 1, 1, 1, 1, 2, 2, 3, 3, + 1, 1, 1, 2, 2, 3, 3, 3, + 1, 1, 2, 2, 3, 3, 3, 3], + [1, 1, 1, 2, 2, 3, 3, 3, + 1, 1, 1, 2, 3, 3, 3, 3, + 1, 1, 1, 3, 3, 3, 3, 3, + 2, 2, 3, 3, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3] + ]}, + 'low': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [18, 14, 14, 21, 30, 35, 34, 17, + 14, 16, 16, 19, 26, 23, 12, 12, + 14, 16, 17, 21, 23, 12, 12, 12, + 21, 19, 21, 23, 12, 12, 12, 12, + 30, 26, 23, 12, 12, 12, 12, 12, + 35, 23, 12, 12, 12, 12, 12, 12, + 34, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12], + [20, 19, 22, 27, 20, 20, 17, 17, + 19, 25, 23, 14, 14, 12, 12, 12, + 22, 23, 14, 14, 12, 12, 12, 12, + 27, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'medium': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [12, 8, 8, 12, 17, 21, 24, 17, + 8, 9, 9, 11, 15, 19, 12, 12, + 8, 9, 10, 12, 19, 12, 12, 12, + 12, 11, 12, 21, 12, 12, 12, 12, + 17, 15, 19, 12, 12, 12, 12, 12, + 21, 19, 12, 12, 12, 12, 12, 12, + 24, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12], + [13, 11, 13, 16, 20, 20, 17, 17, + 11, 14, 14, 14, 14, 12, 12, 12, + 13, 14, 14, 14, 12, 12, 12, 12, + 16, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [6, 4, 4, 6, 9, 11, 12, 16, + 4, 5, 5, 6, 8, 10, 12, 12, + 4, 5, 5, 6, 10, 12, 12, 12, + 6, 6, 6, 11, 12, 12, 12, 12, + 9, 8, 10, 12, 12, 12, 12, 12, + 11, 10, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 16, 12, 12, 12, 12, 12, 12, 12], + [7, 7, 13, 24, 20, 20, 17, 17, + 7, 12, 16, 14, 14, 12, 12, 12, + 13, 16, 14, 14, 12, 12, 12, 12, + 24, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'maximum': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 4, 5, 7, 9, + 2, 2, 2, 4, 5, 7, 9, 12, + 3, 3, 4, 5, 8, 10, 12, 12, + 4, 4, 5, 7, 10, 12, 12, 12, + 5, 5, 7, 9, 12, 12, 12, 12, + 6, 6, 9, 12, 12, 12, 12, 12], + [3, 3, 5, 9, 13, 15, 15, 15, + 3, 4, 6, 10, 14, 12, 12, 12, + 5, 6, 9, 14, 12, 12, 12, 12, + 9, 10, 14, 12, 12, 12, 12, 12, + 13, 14, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12] + ]}, +} +# fmt: on diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/McIdasImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/McIdasImagePlugin.py new file mode 100644 index 00000000..9a85c0d1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/McIdasImagePlugin.py @@ -0,0 +1,76 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Basic McIdas support for PIL +# +# History: +# 1997-05-05 fl Created (8-bit images only) +# 2009-03-08 fl Added 16/32-bit support. +# +# Thanks to Richard Jones and Craig Swank for specs and samples. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import struct + +from . import Image, ImageFile + + +def _accept(s): + return s[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04" + + +## +# Image plugin for McIdas area images. + + +class McIdasImageFile(ImageFile.ImageFile): + format = "MCIDAS" + format_description = "McIdas area file" + + def _open(self): + # parse area file directory + s = self.fp.read(256) + if not _accept(s) or len(s) != 256: + msg = "not an McIdas area file" + raise SyntaxError(msg) + + self.area_descriptor_raw = s + self.area_descriptor = w = [0] + list(struct.unpack("!64i", s)) + + # get mode + if w[11] == 1: + mode = rawmode = "L" + elif w[11] == 2: + # FIXME: add memory map support + mode = "I" + rawmode = "I;16B" + elif w[11] == 4: + # FIXME: add memory map support + mode = "I" + rawmode = "I;32B" + else: + msg = "unsupported McIdas format" + raise SyntaxError(msg) + + self._mode = mode + self._size = w[10], w[9] + + offset = w[34] + w[15] + stride = w[15] + w[10] * w[11] * w[14] + + self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride, 1))] + + +# -------------------------------------------------------------------- +# registry + +Image.register_open(McIdasImageFile.format, McIdasImageFile, _accept) + +# no default extension diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/MicImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/MicImagePlugin.py new file mode 100644 index 00000000..f4529d9a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/MicImagePlugin.py @@ -0,0 +1,107 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Microsoft Image Composer support for PIL +# +# Notes: +# uses TiffImagePlugin.py to read the actual image streams +# +# History: +# 97-01-20 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import olefile + +from . import Image, TiffImagePlugin + +# +# -------------------------------------------------------------------- + + +def _accept(prefix): + return prefix[:8] == olefile.MAGIC + + +## +# Image plugin for Microsoft's Image Composer file format. + + +class MicImageFile(TiffImagePlugin.TiffImageFile): + format = "MIC" + format_description = "Microsoft Image Composer" + _close_exclusive_fp_after_loading = False + + def _open(self): + # read the OLE directory and see if this is a likely + # to be a Microsoft Image Composer file + + try: + self.ole = olefile.OleFileIO(self.fp) + except OSError as e: + msg = "not an MIC file; invalid OLE file" + raise SyntaxError(msg) from e + + # find ACI subfiles with Image members (maybe not the + # best way to identify MIC files, but what the... ;-) + + self.images = [ + path + for path in self.ole.listdir() + if path[1:] and path[0][-4:] == ".ACI" and path[1] == "Image" + ] + + # if we didn't find any images, this is probably not + # an MIC file. + if not self.images: + msg = "not an MIC file; no image entries" + raise SyntaxError(msg) + + self.frame = None + self._n_frames = len(self.images) + self.is_animated = self._n_frames > 1 + + self.__fp = self.fp + self.seek(0) + + def seek(self, frame): + if not self._seek_check(frame): + return + try: + filename = self.images[frame] + except IndexError as e: + msg = "no such frame" + raise EOFError(msg) from e + + self.fp = self.ole.openstream(filename) + + TiffImagePlugin.TiffImageFile._open(self) + + self.frame = frame + + def tell(self): + return self.frame + + def close(self): + self.__fp.close() + self.ole.close() + super().close() + + def __exit__(self, *args): + self.__fp.close() + self.ole.close() + super().__exit__() + + +# +# -------------------------------------------------------------------- + +Image.register_open(MicImageFile.format, MicImageFile, _accept) + +Image.register_extension(MicImageFile.format, ".mic") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/MpegImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/MpegImagePlugin.py new file mode 100644 index 00000000..f4e598ca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/MpegImagePlugin.py @@ -0,0 +1,82 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MPEG file handling +# +# History: +# 95-09-09 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i8 + +# +# Bitstream parser + + +class BitStream: + def __init__(self, fp): + self.fp = fp + self.bits = 0 + self.bitbuffer = 0 + + def next(self): + return i8(self.fp.read(1)) + + def peek(self, bits): + while self.bits < bits: + c = self.next() + if c < 0: + self.bits = 0 + continue + self.bitbuffer = (self.bitbuffer << 8) + c + self.bits += 8 + return self.bitbuffer >> (self.bits - bits) & (1 << bits) - 1 + + def skip(self, bits): + while self.bits < bits: + self.bitbuffer = (self.bitbuffer << 8) + i8(self.fp.read(1)) + self.bits += 8 + self.bits = self.bits - bits + + def read(self, bits): + v = self.peek(bits) + self.bits = self.bits - bits + return v + + +## +# Image plugin for MPEG streams. This plugin can identify a stream, +# but it cannot read it. + + +class MpegImageFile(ImageFile.ImageFile): + format = "MPEG" + format_description = "MPEG" + + def _open(self): + s = BitStream(self.fp) + + if s.read(32) != 0x1B3: + msg = "not an MPEG file" + raise SyntaxError(msg) + + self._mode = "RGB" + self._size = s.read(12), s.read(12) + + +# -------------------------------------------------------------------- +# Registry stuff + +Image.register_open(MpegImageFile.format, MpegImageFile) + +Image.register_extensions(MpegImageFile.format, [".mpg", ".mpeg"]) + +Image.register_mime(MpegImageFile.format, "video/mpeg") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/MpoImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/MpoImagePlugin.py new file mode 100644 index 00000000..199a1009 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/MpoImagePlugin.py @@ -0,0 +1,195 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MPO file handling +# +# See "Multi-Picture Format" (CIPA DC-007-Translation 2009, Standard of the +# Camera & Imaging Products Association) +# +# The multi-picture object combines multiple JPEG images (with a modified EXIF +# data format) into a single file. While it can theoretically be used much like +# a GIF animation, it is commonly used to represent 3D photographs and is (as +# of this writing) the most commonly used format by 3D cameras. +# +# History: +# 2014-03-13 Feneric Created +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import os +import struct + +from . import ( + ExifTags, + Image, + ImageFile, + ImageSequence, + JpegImagePlugin, + TiffImagePlugin, +) +from ._binary import i16be as i16 +from ._binary import o32le + + +def _save(im, fp, filename): + JpegImagePlugin._save(im, fp, filename) + + +def _save_all(im, fp, filename): + append_images = im.encoderinfo.get("append_images", []) + if not append_images: + try: + animated = im.is_animated + except AttributeError: + animated = False + if not animated: + _save(im, fp, filename) + return + + mpf_offset = 28 + offsets = [] + for imSequence in itertools.chain([im], append_images): + for im_frame in ImageSequence.Iterator(imSequence): + if not offsets: + # APP2 marker + im_frame.encoderinfo["extra"] = ( + b"\xFF\xE2" + struct.pack(">H", 6 + 82) + b"MPF\0" + b" " * 82 + ) + exif = im_frame.encoderinfo.get("exif") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + im_frame.encoderinfo["exif"] = exif + if exif: + mpf_offset += 4 + len(exif) + + JpegImagePlugin._save(im_frame, fp, filename) + offsets.append(fp.tell()) + else: + im_frame.save(fp, "JPEG") + offsets.append(fp.tell() - offsets[-1]) + + ifd = TiffImagePlugin.ImageFileDirectory_v2() + ifd[0xB000] = b"0100" + ifd[0xB001] = len(offsets) + + mpentries = b"" + data_offset = 0 + for i, size in enumerate(offsets): + if i == 0: + mptype = 0x030000 # Baseline MP Primary Image + else: + mptype = 0x000000 # Undefined + mpentries += struct.pack(" 1 + self._fp = self.fp # FIXME: hack + self._fp.seek(self.__mpoffsets[0]) # get ready to read first frame + self.__frame = 0 + self.offset = 0 + # for now we can only handle reading and individual frame extraction + self.readonly = 1 + + def load_seek(self, pos): + self._fp.seek(pos) + + def seek(self, frame): + if not self._seek_check(frame): + return + self.fp = self._fp + self.offset = self.__mpoffsets[frame] + + self.fp.seek(self.offset + 2) # skip SOI marker + segment = self.fp.read(2) + if not segment: + msg = "No data found for frame" + raise ValueError(msg) + self._size = self._initial_size + if i16(segment) == 0xFFE1: # APP1 + n = i16(self.fp.read(2)) - 2 + self.info["exif"] = ImageFile._safe_read(self.fp, n) + self._reload_exif() + + mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"] + if mptype.startswith("Large Thumbnail"): + exif = self.getexif().get_ifd(ExifTags.IFD.Exif) + if 40962 in exif and 40963 in exif: + self._size = (exif[40962], exif[40963]) + elif "exif" in self.info: + del self.info["exif"] + self._reload_exif() + + self.tile = [("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))] + self.__frame = frame + + def tell(self): + return self.__frame + + @staticmethod + def adopt(jpeg_instance, mpheader=None): + """ + Transform the instance of JpegImageFile into + an instance of MpoImageFile. + After the call, the JpegImageFile is extended + to be an MpoImageFile. + + This is essentially useful when opening a JPEG + file that reveals itself as an MPO, to avoid + double call to _open. + """ + jpeg_instance.__class__ = MpoImageFile + jpeg_instance._after_jpeg_open(mpheader) + return jpeg_instance + + +# --------------------------------------------------------------------- +# Registry stuff + +# Note that since MPO shares a factory with JPEG, we do not need to do a +# separate registration for it here. +# Image.register_open(MpoImageFile.format, +# JpegImagePlugin.jpeg_factory, _accept) +Image.register_save(MpoImageFile.format, _save) +Image.register_save_all(MpoImageFile.format, _save_all) + +Image.register_extension(MpoImageFile.format, ".mpo") + +Image.register_mime(MpoImageFile.format, "image/mpo") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/MspImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/MspImagePlugin.py new file mode 100644 index 00000000..77dac65b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/MspImagePlugin.py @@ -0,0 +1,195 @@ +# +# The Python Imaging Library. +# +# MSP file handling +# +# This is the format used by the Paint program in Windows 1 and 2. +# +# History: +# 95-09-05 fl Created +# 97-01-03 fl Read/write MSP images +# 17-02-21 es Fixed RLE interpretation +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-97. +# Copyright (c) Eric Soroos 2017. +# +# See the README file for information on usage and redistribution. +# +# More info on this format: https://archive.org/details/gg243631 +# Page 313: +# Figure 205. Windows Paint Version 1: "DanM" Format +# Figure 206. Windows Paint Version 2: "LinS" Format. Used in Windows V2.03 +# +# See also: https://www.fileformat.info/format/mspaint/egff.htm +from __future__ import annotations + +import io +import struct + +from . import Image, ImageFile +from ._binary import i16le as i16 +from ._binary import o16le as o16 + +# +# read MSP files + + +def _accept(prefix): + return prefix[:4] in [b"DanM", b"LinS"] + + +## +# Image plugin for Windows MSP images. This plugin supports both +# uncompressed (Windows 1.0). + + +class MspImageFile(ImageFile.ImageFile): + format = "MSP" + format_description = "Windows Paint" + + def _open(self): + # Header + s = self.fp.read(32) + if not _accept(s): + msg = "not an MSP file" + raise SyntaxError(msg) + + # Header checksum + checksum = 0 + for i in range(0, 32, 2): + checksum = checksum ^ i16(s, i) + if checksum != 0: + msg = "bad MSP checksum" + raise SyntaxError(msg) + + self._mode = "1" + self._size = i16(s, 4), i16(s, 6) + + if s[:4] == b"DanM": + self.tile = [("raw", (0, 0) + self.size, 32, ("1", 0, 1))] + else: + self.tile = [("MSP", (0, 0) + self.size, 32, None)] + + +class MspDecoder(ImageFile.PyDecoder): + # The algo for the MSP decoder is from + # https://www.fileformat.info/format/mspaint/egff.htm + # cc-by-attribution -- That page references is taken from the + # Encyclopedia of Graphics File Formats and is licensed by + # O'Reilly under the Creative Common/Attribution license + # + # For RLE encoded files, the 32byte header is followed by a scan + # line map, encoded as one 16bit word of encoded byte length per + # line. + # + # NOTE: the encoded length of the line can be 0. This was not + # handled in the previous version of this encoder, and there's no + # mention of how to handle it in the documentation. From the few + # examples I've seen, I've assumed that it is a fill of the + # background color, in this case, white. + # + # + # Pseudocode of the decoder: + # Read a BYTE value as the RunType + # If the RunType value is zero + # Read next byte as the RunCount + # Read the next byte as the RunValue + # Write the RunValue byte RunCount times + # If the RunType value is non-zero + # Use this value as the RunCount + # Read and write the next RunCount bytes literally + # + # e.g.: + # 0x00 03 ff 05 00 01 02 03 04 + # would yield the bytes: + # 0xff ff ff 00 01 02 03 04 + # + # which are then interpreted as a bit packed mode '1' image + + _pulls_fd = True + + def decode(self, buffer): + img = io.BytesIO() + blank_line = bytearray((0xFF,) * ((self.state.xsize + 7) // 8)) + try: + self.fd.seek(32) + rowmap = struct.unpack_from( + f"<{self.state.ysize}H", self.fd.read(self.state.ysize * 2) + ) + except struct.error as e: + msg = "Truncated MSP file in row map" + raise OSError(msg) from e + + for x, rowlen in enumerate(rowmap): + try: + if rowlen == 0: + img.write(blank_line) + continue + row = self.fd.read(rowlen) + if len(row) != rowlen: + msg = f"Truncated MSP file, expected {rowlen} bytes on row {x}" + raise OSError(msg) + idx = 0 + while idx < rowlen: + runtype = row[idx] + idx += 1 + if runtype == 0: + (runcount, runval) = struct.unpack_from("Bc", row, idx) + img.write(runval * runcount) + idx += 2 + else: + runcount = runtype + img.write(row[idx : idx + runcount]) + idx += runcount + + except struct.error as e: + msg = f"Corrupted MSP file in row {x}" + raise OSError(msg) from e + + self.set_as_raw(img.getvalue(), ("1", 0, 1)) + + return -1, 0 + + +Image.register_decoder("MSP", MspDecoder) + + +# +# write MSP files (uncompressed only) + + +def _save(im, fp, filename): + if im.mode != "1": + msg = f"cannot write mode {im.mode} as MSP" + raise OSError(msg) + + # create MSP header + header = [0] * 16 + + header[0], header[1] = i16(b"Da"), i16(b"nM") # version 1 + header[2], header[3] = im.size + header[4], header[5] = 1, 1 + header[6], header[7] = 1, 1 + header[8], header[9] = im.size + + checksum = 0 + for h in header: + checksum = checksum ^ h + header[12] = checksum # FIXME: is this the right field? + + # header + for h in header: + fp.write(o16(h)) + + # image body + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 32, ("1", 0, 1))]) + + +# +# registry + +Image.register_open(MspImageFile.format, MspImageFile, _accept) +Image.register_save(MspImageFile.format, _save) + +Image.register_extension(MspImageFile.format, ".msp") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PSDraw.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PSDraw.py new file mode 100644 index 00000000..848fc2f7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PSDraw.py @@ -0,0 +1,230 @@ +# +# The Python Imaging Library +# $Id$ +# +# Simple PostScript graphics interface +# +# History: +# 1996-04-20 fl Created +# 1999-01-10 fl Added gsave/grestore to image method +# 2005-05-04 fl Fixed floating point issue in image (from Eric Etheridge) +# +# Copyright (c) 1997-2005 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys + +from . import EpsImagePlugin + +## +# Simple PostScript graphics interface. + + +class PSDraw: + """ + Sets up printing to the given file. If ``fp`` is omitted, + ``sys.stdout.buffer`` or ``sys.stdout`` is assumed. + """ + + def __init__(self, fp=None): + if not fp: + try: + fp = sys.stdout.buffer + except AttributeError: + fp = sys.stdout + self.fp = fp + + def begin_document(self, id=None): + """Set up printing of a document. (Write PostScript DSC header.)""" + # FIXME: incomplete + self.fp.write( + b"%!PS-Adobe-3.0\n" + b"save\n" + b"/showpage { } def\n" + b"%%EndComments\n" + b"%%BeginDocument\n" + ) + # self.fp.write(ERROR_PS) # debugging! + self.fp.write(EDROFF_PS) + self.fp.write(VDI_PS) + self.fp.write(b"%%EndProlog\n") + self.isofont = {} + + def end_document(self): + """Ends printing. (Write PostScript DSC footer.)""" + self.fp.write(b"%%EndDocument\nrestore showpage\n%%End\n") + if hasattr(self.fp, "flush"): + self.fp.flush() + + def setfont(self, font, size): + """ + Selects which font to use. + + :param font: A PostScript font name + :param size: Size in points. + """ + font = bytes(font, "UTF-8") + if font not in self.isofont: + # reencode font + self.fp.write(b"/PSDraw-%s ISOLatin1Encoding /%s E\n" % (font, font)) + self.isofont[font] = 1 + # rough + self.fp.write(b"/F0 %d /PSDraw-%s F\n" % (size, font)) + + def line(self, xy0, xy1): + """ + Draws a line between the two points. Coordinates are given in + PostScript point coordinates (72 points per inch, (0, 0) is the lower + left corner of the page). + """ + self.fp.write(b"%d %d %d %d Vl\n" % (*xy0, *xy1)) + + def rectangle(self, box): + """ + Draws a rectangle. + + :param box: A tuple of four integers, specifying left, bottom, width and + height. + """ + self.fp.write(b"%d %d M 0 %d %d Vr\n" % box) + + def text(self, xy, text): + """ + Draws text at the given position. You must use + :py:meth:`~PIL.PSDraw.PSDraw.setfont` before calling this method. + """ + text = bytes(text, "UTF-8") + text = b"\\(".join(text.split(b"(")) + text = b"\\)".join(text.split(b")")) + xy += (text,) + self.fp.write(b"%d %d M (%s) S\n" % xy) + + def image(self, box, im, dpi=None): + """Draw a PIL image, centered in the given box.""" + # default resolution depends on mode + if not dpi: + if im.mode == "1": + dpi = 200 # fax + else: + dpi = 100 # grayscale + # image size (on paper) + x = im.size[0] * 72 / dpi + y = im.size[1] * 72 / dpi + # max allowed size + xmax = float(box[2] - box[0]) + ymax = float(box[3] - box[1]) + if x > xmax: + y = y * xmax / x + x = xmax + if y > ymax: + x = x * ymax / y + y = ymax + dx = (xmax - x) / 2 + box[0] + dy = (ymax - y) / 2 + box[1] + self.fp.write(b"gsave\n%f %f translate\n" % (dx, dy)) + if (x, y) != im.size: + # EpsImagePlugin._save prints the image at (0,0,xsize,ysize) + sx = x / im.size[0] + sy = y / im.size[1] + self.fp.write(b"%f %f scale\n" % (sx, sy)) + EpsImagePlugin._save(im, self.fp, None, 0) + self.fp.write(b"\ngrestore\n") + + +# -------------------------------------------------------------------- +# PostScript driver + +# +# EDROFF.PS -- PostScript driver for Edroff 2 +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + + +EDROFF_PS = b"""\ +/S { show } bind def +/P { moveto show } bind def +/M { moveto } bind def +/X { 0 rmoveto } bind def +/Y { 0 exch rmoveto } bind def +/E { findfont + dup maxlength dict begin + { + 1 index /FID ne { def } { pop pop } ifelse + } forall + /Encoding exch def + dup /FontName exch def + currentdict end definefont pop +} bind def +/F { findfont exch scalefont dup setfont + [ exch /setfont cvx ] cvx bind def +} bind def +""" + +# +# VDI.PS -- PostScript driver for VDI meta commands +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + +VDI_PS = b"""\ +/Vm { moveto } bind def +/Va { newpath arcn stroke } bind def +/Vl { moveto lineto stroke } bind def +/Vc { newpath 0 360 arc closepath } bind def +/Vr { exch dup 0 rlineto + exch dup 0 exch rlineto + exch neg 0 rlineto + 0 exch neg rlineto + setgray fill } bind def +/Tm matrix def +/Ve { Tm currentmatrix pop + translate scale newpath 0 0 .5 0 360 arc closepath + Tm setmatrix +} bind def +/Vf { currentgray exch setgray fill setgray } bind def +""" + +# +# ERROR.PS -- Error handler +# +# History: +# 89-11-21 fl: created (pslist 1.10) +# + +ERROR_PS = b"""\ +/landscape false def +/errorBUF 200 string def +/errorNL { currentpoint 10 sub exch pop 72 exch moveto } def +errordict begin /handleerror { + initmatrix /Courier findfont 10 scalefont setfont + newpath 72 720 moveto $error begin /newerror false def + (PostScript Error) show errorNL errorNL + (Error: ) show + /errorname load errorBUF cvs show errorNL errorNL + (Command: ) show + /command load dup type /stringtype ne { errorBUF cvs } if show + errorNL errorNL + (VMstatus: ) show + vmstatus errorBUF cvs show ( bytes available, ) show + errorBUF cvs show ( bytes used at level ) show + errorBUF cvs show errorNL errorNL + (Operand stargck: ) show errorNL /ostargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall errorNL + (Execution stargck: ) show errorNL /estargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall + end showpage +} def end +""" diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PaletteFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PaletteFile.py new file mode 100644 index 00000000..dc317540 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PaletteFile.py @@ -0,0 +1,52 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read simple, teragon-style palette files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from ._binary import o8 + + +class PaletteFile: + """File handler for Teragon-style palette files.""" + + rawmode = "RGB" + + def __init__(self, fp): + self.palette = [(i, i, i) for i in range(256)] + + while True: + s = fp.readline() + + if not s: + break + if s[:1] == b"#": + continue + if len(s) > 100: + msg = "bad palette file" + raise SyntaxError(msg) + + v = [int(x) for x in s.split()] + try: + [i, r, g, b] = v + except ValueError: + [i, r] = v + g = b = r + + if 0 <= i <= 255: + self.palette[i] = o8(r) + o8(g) + o8(b) + + self.palette = b"".join(self.palette) + + def getpalette(self): + return self.palette, self.rawmode diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PalmImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PalmImagePlugin.py new file mode 100644 index 00000000..65be7fef --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PalmImagePlugin.py @@ -0,0 +1,226 @@ +# +# The Python Imaging Library. +# $Id$ +# + +## +# Image plugin for Palm pixmap images (output only). +## +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import o8 +from ._binary import o16be as o16b + +# fmt: off +_Palm8BitColormapValues = ( + (255, 255, 255), (255, 204, 255), (255, 153, 255), (255, 102, 255), + (255, 51, 255), (255, 0, 255), (255, 255, 204), (255, 204, 204), + (255, 153, 204), (255, 102, 204), (255, 51, 204), (255, 0, 204), + (255, 255, 153), (255, 204, 153), (255, 153, 153), (255, 102, 153), + (255, 51, 153), (255, 0, 153), (204, 255, 255), (204, 204, 255), + (204, 153, 255), (204, 102, 255), (204, 51, 255), (204, 0, 255), + (204, 255, 204), (204, 204, 204), (204, 153, 204), (204, 102, 204), + (204, 51, 204), (204, 0, 204), (204, 255, 153), (204, 204, 153), + (204, 153, 153), (204, 102, 153), (204, 51, 153), (204, 0, 153), + (153, 255, 255), (153, 204, 255), (153, 153, 255), (153, 102, 255), + (153, 51, 255), (153, 0, 255), (153, 255, 204), (153, 204, 204), + (153, 153, 204), (153, 102, 204), (153, 51, 204), (153, 0, 204), + (153, 255, 153), (153, 204, 153), (153, 153, 153), (153, 102, 153), + (153, 51, 153), (153, 0, 153), (102, 255, 255), (102, 204, 255), + (102, 153, 255), (102, 102, 255), (102, 51, 255), (102, 0, 255), + (102, 255, 204), (102, 204, 204), (102, 153, 204), (102, 102, 204), + (102, 51, 204), (102, 0, 204), (102, 255, 153), (102, 204, 153), + (102, 153, 153), (102, 102, 153), (102, 51, 153), (102, 0, 153), + (51, 255, 255), (51, 204, 255), (51, 153, 255), (51, 102, 255), + (51, 51, 255), (51, 0, 255), (51, 255, 204), (51, 204, 204), + (51, 153, 204), (51, 102, 204), (51, 51, 204), (51, 0, 204), + (51, 255, 153), (51, 204, 153), (51, 153, 153), (51, 102, 153), + (51, 51, 153), (51, 0, 153), (0, 255, 255), (0, 204, 255), + (0, 153, 255), (0, 102, 255), (0, 51, 255), (0, 0, 255), + (0, 255, 204), (0, 204, 204), (0, 153, 204), (0, 102, 204), + (0, 51, 204), (0, 0, 204), (0, 255, 153), (0, 204, 153), + (0, 153, 153), (0, 102, 153), (0, 51, 153), (0, 0, 153), + (255, 255, 102), (255, 204, 102), (255, 153, 102), (255, 102, 102), + (255, 51, 102), (255, 0, 102), (255, 255, 51), (255, 204, 51), + (255, 153, 51), (255, 102, 51), (255, 51, 51), (255, 0, 51), + (255, 255, 0), (255, 204, 0), (255, 153, 0), (255, 102, 0), + (255, 51, 0), (255, 0, 0), (204, 255, 102), (204, 204, 102), + (204, 153, 102), (204, 102, 102), (204, 51, 102), (204, 0, 102), + (204, 255, 51), (204, 204, 51), (204, 153, 51), (204, 102, 51), + (204, 51, 51), (204, 0, 51), (204, 255, 0), (204, 204, 0), + (204, 153, 0), (204, 102, 0), (204, 51, 0), (204, 0, 0), + (153, 255, 102), (153, 204, 102), (153, 153, 102), (153, 102, 102), + (153, 51, 102), (153, 0, 102), (153, 255, 51), (153, 204, 51), + (153, 153, 51), (153, 102, 51), (153, 51, 51), (153, 0, 51), + (153, 255, 0), (153, 204, 0), (153, 153, 0), (153, 102, 0), + (153, 51, 0), (153, 0, 0), (102, 255, 102), (102, 204, 102), + (102, 153, 102), (102, 102, 102), (102, 51, 102), (102, 0, 102), + (102, 255, 51), (102, 204, 51), (102, 153, 51), (102, 102, 51), + (102, 51, 51), (102, 0, 51), (102, 255, 0), (102, 204, 0), + (102, 153, 0), (102, 102, 0), (102, 51, 0), (102, 0, 0), + (51, 255, 102), (51, 204, 102), (51, 153, 102), (51, 102, 102), + (51, 51, 102), (51, 0, 102), (51, 255, 51), (51, 204, 51), + (51, 153, 51), (51, 102, 51), (51, 51, 51), (51, 0, 51), + (51, 255, 0), (51, 204, 0), (51, 153, 0), (51, 102, 0), + (51, 51, 0), (51, 0, 0), (0, 255, 102), (0, 204, 102), + (0, 153, 102), (0, 102, 102), (0, 51, 102), (0, 0, 102), + (0, 255, 51), (0, 204, 51), (0, 153, 51), (0, 102, 51), + (0, 51, 51), (0, 0, 51), (0, 255, 0), (0, 204, 0), + (0, 153, 0), (0, 102, 0), (0, 51, 0), (17, 17, 17), + (34, 34, 34), (68, 68, 68), (85, 85, 85), (119, 119, 119), + (136, 136, 136), (170, 170, 170), (187, 187, 187), (221, 221, 221), + (238, 238, 238), (192, 192, 192), (128, 0, 0), (128, 0, 128), + (0, 128, 0), (0, 128, 128), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)) +# fmt: on + + +# so build a prototype image to be used for palette resampling +def build_prototype_image(): + image = Image.new("L", (1, len(_Palm8BitColormapValues))) + image.putdata(list(range(len(_Palm8BitColormapValues)))) + palettedata = () + for colormapValue in _Palm8BitColormapValues: + palettedata += colormapValue + palettedata += (0, 0, 0) * (256 - len(_Palm8BitColormapValues)) + image.putpalette(palettedata) + return image + + +Palm8BitColormapImage = build_prototype_image() + +# OK, we now have in Palm8BitColormapImage, +# a "P"-mode image with the right palette +# +# -------------------------------------------------------------------- + +_FLAGS = {"custom-colormap": 0x4000, "is-compressed": 0x8000, "has-transparent": 0x2000} + +_COMPRESSION_TYPES = {"none": 0xFF, "rle": 0x01, "scanline": 0x00} + + +# +# -------------------------------------------------------------------- + +## +# (Internal) Image save plugin for the Palm format. + + +def _save(im, fp, filename): + if im.mode == "P": + # we assume this is a color Palm image with the standard colormap, + # unless the "info" dict has a "custom-colormap" field + + rawmode = "P" + bpp = 8 + version = 1 + + elif im.mode == "L": + if im.encoderinfo.get("bpp") in (1, 2, 4): + # this is 8-bit grayscale, so we shift it to get the high-order bits, + # and invert it because + # Palm does grayscale from white (0) to black (1) + bpp = im.encoderinfo["bpp"] + im = im.point( + lambda x, shift=8 - bpp, maxval=(1 << bpp) - 1: maxval - (x >> shift) + ) + elif im.info.get("bpp") in (1, 2, 4): + # here we assume that even though the inherent mode is 8-bit grayscale, + # only the lower bpp bits are significant. + # We invert them to match the Palm. + bpp = im.info["bpp"] + im = im.point(lambda x, maxval=(1 << bpp) - 1: maxval - (x & maxval)) + else: + msg = f"cannot write mode {im.mode} as Palm" + raise OSError(msg) + + # we ignore the palette here + im.mode = "P" + rawmode = "P;" + str(bpp) + version = 1 + + elif im.mode == "1": + # monochrome -- write it inverted, as is the Palm standard + rawmode = "1;I" + bpp = 1 + version = 0 + + else: + msg = f"cannot write mode {im.mode} as Palm" + raise OSError(msg) + + # + # make sure image data is available + im.load() + + # write header + + cols = im.size[0] + rows = im.size[1] + + rowbytes = int((cols + (16 // bpp - 1)) / (16 // bpp)) * 2 + transparent_index = 0 + compression_type = _COMPRESSION_TYPES["none"] + + flags = 0 + if im.mode == "P" and "custom-colormap" in im.info: + flags = flags & _FLAGS["custom-colormap"] + colormapsize = 4 * 256 + 2 + colormapmode = im.palette.mode + colormap = im.getdata().getpalette() + else: + colormapsize = 0 + + if "offset" in im.info: + offset = (rowbytes * rows + 16 + 3 + colormapsize) // 4 + else: + offset = 0 + + fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) + fp.write(o8(bpp)) + fp.write(o8(version)) + fp.write(o16b(offset)) + fp.write(o8(transparent_index)) + fp.write(o8(compression_type)) + fp.write(o16b(0)) # reserved by Palm + + # now write colormap if necessary + + if colormapsize > 0: + fp.write(o16b(256)) + for i in range(256): + fp.write(o8(i)) + if colormapmode == "RGB": + fp.write( + o8(colormap[3 * i]) + + o8(colormap[3 * i + 1]) + + o8(colormap[3 * i + 2]) + ) + elif colormapmode == "RGBA": + fp.write( + o8(colormap[4 * i]) + + o8(colormap[4 * i + 1]) + + o8(colormap[4 * i + 2]) + ) + + # now convert data to raw form + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))]) + + if hasattr(fp, "flush"): + fp.flush() + + +# +# -------------------------------------------------------------------- + +Image.register_save("Palm", _save) + +Image.register_extension("Palm", ".palm") + +Image.register_mime("Palm", "image/palm") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PcdImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PcdImagePlugin.py new file mode 100644 index 00000000..a0515b30 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PcdImagePlugin.py @@ -0,0 +1,62 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCD file handling +# +# History: +# 96-05-10 fl Created +# 96-05-27 fl Added draft mode (128x192, 256x384) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile + +## +# Image plugin for PhotoCD images. This plugin only reads the 768x512 +# image from the file; higher resolutions are encoded in a proprietary +# encoding. + + +class PcdImageFile(ImageFile.ImageFile): + format = "PCD" + format_description = "Kodak PhotoCD" + + def _open(self): + # rough + self.fp.seek(2048) + s = self.fp.read(2048) + + if s[:4] != b"PCD_": + msg = "not a PCD file" + raise SyntaxError(msg) + + orientation = s[1538] & 3 + self.tile_post_rotate = None + if orientation == 1: + self.tile_post_rotate = 90 + elif orientation == 3: + self.tile_post_rotate = -90 + + self._mode = "RGB" + self._size = 768, 512 # FIXME: not correct for rotated images! + self.tile = [("pcd", (0, 0) + self.size, 96 * 2048, None)] + + def load_end(self): + if self.tile_post_rotate: + # Handle rotated PCDs + self.im = self.im.rotate(self.tile_post_rotate) + self._size = self.im.size + + +# +# registry + +Image.register_open(PcdImageFile.format, PcdImageFile) + +Image.register_extension(PcdImageFile.format, ".pcd") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PcfFontFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PcfFontFile.py new file mode 100644 index 00000000..0d1968b1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PcfFontFile.py @@ -0,0 +1,254 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library +# $Id$ +# +# portable compiled font file parser +# +# history: +# 1997-08-19 fl created +# 2003-09-13 fl fixed loading of unicode fonts +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1997-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from typing import BinaryIO, Callable + +from . import FontFile, Image +from ._binary import i8 +from ._binary import i16be as b16 +from ._binary import i16le as l16 +from ._binary import i32be as b32 +from ._binary import i32le as l32 + +# -------------------------------------------------------------------- +# declarations + +PCF_MAGIC = 0x70636601 # "\x01fcp" + +PCF_PROPERTIES = 1 << 0 +PCF_ACCELERATORS = 1 << 1 +PCF_METRICS = 1 << 2 +PCF_BITMAPS = 1 << 3 +PCF_INK_METRICS = 1 << 4 +PCF_BDF_ENCODINGS = 1 << 5 +PCF_SWIDTHS = 1 << 6 +PCF_GLYPH_NAMES = 1 << 7 +PCF_BDF_ACCELERATORS = 1 << 8 + +BYTES_PER_ROW: list[Callable[[int], int]] = [ + lambda bits: ((bits + 7) >> 3), + lambda bits: ((bits + 15) >> 3) & ~1, + lambda bits: ((bits + 31) >> 3) & ~3, + lambda bits: ((bits + 63) >> 3) & ~7, +] + + +def sz(s: bytes, o: int) -> bytes: + return s[o : s.index(b"\0", o)] + + +class PcfFontFile(FontFile.FontFile): + """Font file plugin for the X11 PCF format.""" + + name = "name" + + def __init__(self, fp: BinaryIO, charset_encoding: str = "iso8859-1"): + self.charset_encoding = charset_encoding + + magic = l32(fp.read(4)) + if magic != PCF_MAGIC: + msg = "not a PCF file" + raise SyntaxError(msg) + + super().__init__() + + count = l32(fp.read(4)) + self.toc = {} + for i in range(count): + type = l32(fp.read(4)) + self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4)) + + self.fp = fp + + self.info = self._load_properties() + + metrics = self._load_metrics() + bitmaps = self._load_bitmaps(metrics) + encoding = self._load_encoding() + + # + # create glyph structure + + for ch, ix in enumerate(encoding): + if ix is not None: + ( + xsize, + ysize, + left, + right, + width, + ascent, + descent, + attributes, + ) = metrics[ix] + self.glyph[ch] = ( + (width, 0), + (left, descent - ysize, xsize + left, descent), + (0, 0, xsize, ysize), + bitmaps[ix], + ) + + def _getformat( + self, tag: int + ) -> tuple[BinaryIO, int, Callable[[bytes], int], Callable[[bytes], int]]: + format, size, offset = self.toc[tag] + + fp = self.fp + fp.seek(offset) + + format = l32(fp.read(4)) + + if format & 4: + i16, i32 = b16, b32 + else: + i16, i32 = l16, l32 + + return fp, format, i16, i32 + + def _load_properties(self) -> dict[bytes, bytes | int]: + # + # font properties + + properties = {} + + fp, format, i16, i32 = self._getformat(PCF_PROPERTIES) + + nprops = i32(fp.read(4)) + + # read property description + p = [(i32(fp.read(4)), i8(fp.read(1)), i32(fp.read(4))) for _ in range(nprops)] + + if nprops & 3: + fp.seek(4 - (nprops & 3), io.SEEK_CUR) # pad + + data = fp.read(i32(fp.read(4))) + + for k, s, v in p: + property_value: bytes | int = sz(data, v) if s else v + properties[sz(data, k)] = property_value + + return properties + + def _load_metrics(self) -> list[tuple[int, int, int, int, int, int, int, int]]: + # + # font metrics + + metrics: list[tuple[int, int, int, int, int, int, int, int]] = [] + + fp, format, i16, i32 = self._getformat(PCF_METRICS) + + append = metrics.append + + if (format & 0xFF00) == 0x100: + # "compressed" metrics + for i in range(i16(fp.read(2))): + left = i8(fp.read(1)) - 128 + right = i8(fp.read(1)) - 128 + width = i8(fp.read(1)) - 128 + ascent = i8(fp.read(1)) - 128 + descent = i8(fp.read(1)) - 128 + xsize = right - left + ysize = ascent + descent + append((xsize, ysize, left, right, width, ascent, descent, 0)) + + else: + # "jumbo" metrics + for i in range(i32(fp.read(4))): + left = i16(fp.read(2)) + right = i16(fp.read(2)) + width = i16(fp.read(2)) + ascent = i16(fp.read(2)) + descent = i16(fp.read(2)) + attributes = i16(fp.read(2)) + xsize = right - left + ysize = ascent + descent + append((xsize, ysize, left, right, width, ascent, descent, attributes)) + + return metrics + + def _load_bitmaps( + self, metrics: list[tuple[int, int, int, int, int, int, int, int]] + ) -> list[Image.Image]: + # + # bitmap data + + fp, format, i16, i32 = self._getformat(PCF_BITMAPS) + + nbitmaps = i32(fp.read(4)) + + if nbitmaps != len(metrics): + msg = "Wrong number of bitmaps" + raise OSError(msg) + + offsets = [i32(fp.read(4)) for _ in range(nbitmaps)] + + bitmap_sizes = [i32(fp.read(4)) for _ in range(4)] + + # byteorder = format & 4 # non-zero => MSB + bitorder = format & 8 # non-zero => MSB + padindex = format & 3 + + bitmapsize = bitmap_sizes[padindex] + offsets.append(bitmapsize) + + data = fp.read(bitmapsize) + + pad = BYTES_PER_ROW[padindex] + mode = "1;R" + if bitorder: + mode = "1" + + bitmaps = [] + for i in range(nbitmaps): + xsize, ysize = metrics[i][:2] + b, e = offsets[i : i + 2] + bitmaps.append( + Image.frombytes("1", (xsize, ysize), data[b:e], "raw", mode, pad(xsize)) + ) + + return bitmaps + + def _load_encoding(self) -> list[int | None]: + fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS) + + first_col, last_col = i16(fp.read(2)), i16(fp.read(2)) + first_row, last_row = i16(fp.read(2)), i16(fp.read(2)) + + i16(fp.read(2)) # default + + nencoding = (last_col - first_col + 1) * (last_row - first_row + 1) + + # map character code to bitmap index + encoding: list[int | None] = [None] * min(256, nencoding) + + encoding_offsets = [i16(fp.read(2)) for _ in range(nencoding)] + + for i in range(first_col, len(encoding)): + try: + encoding_offset = encoding_offsets[ + ord(bytearray([i]).decode(self.charset_encoding)) + ] + if encoding_offset != 0xFFFF: + encoding[i] = encoding_offset + except UnicodeDecodeError: + # character is not supported in selected encoding + pass + + return encoding diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PcxImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PcxImagePlugin.py new file mode 100644 index 00000000..98ecefd0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PcxImagePlugin.py @@ -0,0 +1,222 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCX file handling +# +# This format was originally used by ZSoft's popular PaintBrush +# program for the IBM PC. It is also supported by many MS-DOS and +# Windows applications, including the Windows PaintBrush program in +# Windows 3. +# +# history: +# 1995-09-01 fl Created +# 1996-05-20 fl Fixed RGB support +# 1997-01-03 fl Fixed 2-bit and 4-bit support +# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1) +# 1999-02-07 fl Added write support +# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust +# 2002-07-30 fl Seek from to current position, not beginning of file +# 2003-06-03 fl Extract DPI settings (info["dpi"]) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import logging + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + +logger = logging.getLogger(__name__) + + +def _accept(prefix): + return prefix[0] == 10 and prefix[1] in [0, 2, 3, 5] + + +## +# Image plugin for Paintbrush images. + + +class PcxImageFile(ImageFile.ImageFile): + format = "PCX" + format_description = "Paintbrush" + + def _open(self): + # header + s = self.fp.read(128) + if not _accept(s): + msg = "not a PCX file" + raise SyntaxError(msg) + + # image + bbox = i16(s, 4), i16(s, 6), i16(s, 8) + 1, i16(s, 10) + 1 + if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]: + msg = "bad PCX image size" + raise SyntaxError(msg) + logger.debug("BBox: %s %s %s %s", *bbox) + + # format + version = s[1] + bits = s[3] + planes = s[65] + provided_stride = i16(s, 66) + logger.debug( + "PCX version %s, bits %s, planes %s, stride %s", + version, + bits, + planes, + provided_stride, + ) + + self.info["dpi"] = i16(s, 12), i16(s, 14) + + if bits == 1 and planes == 1: + mode = rawmode = "1" + + elif bits == 1 and planes in (2, 4): + mode = "P" + rawmode = "P;%dL" % planes + self.palette = ImagePalette.raw("RGB", s[16:64]) + + elif version == 5 and bits == 8 and planes == 1: + mode = rawmode = "L" + # FIXME: hey, this doesn't work with the incremental loader !!! + self.fp.seek(-769, io.SEEK_END) + s = self.fp.read(769) + if len(s) == 769 and s[0] == 12: + # check if the palette is linear grayscale + for i in range(256): + if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3: + mode = rawmode = "P" + break + if mode == "P": + self.palette = ImagePalette.raw("RGB", s[1:]) + self.fp.seek(128) + + elif version == 5 and bits == 8 and planes == 3: + mode = "RGB" + rawmode = "RGB;L" + + else: + msg = "unknown PCX mode" + raise OSError(msg) + + self._mode = mode + self._size = bbox[2] - bbox[0], bbox[3] - bbox[1] + + # Don't trust the passed in stride. + # Calculate the approximate position for ourselves. + # CVE-2020-35653 + stride = (self._size[0] * bits + 7) // 8 + + # While the specification states that this must be even, + # not all images follow this + if provided_stride != stride: + stride += stride % 2 + + bbox = (0, 0) + self.size + logger.debug("size: %sx%s", *self.size) + + self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))] + + +# -------------------------------------------------------------------- +# save PCX files + + +SAVE = { + # mode: (version, bits, planes, raw mode) + "1": (2, 1, 1, "1"), + "L": (5, 8, 1, "L"), + "P": (5, 8, 1, "P"), + "RGB": (5, 8, 3, "RGB;L"), +} + + +def _save(im, fp, filename): + try: + version, bits, planes, rawmode = SAVE[im.mode] + except KeyError as e: + msg = f"Cannot save {im.mode} images as PCX" + raise ValueError(msg) from e + + # bytes per plane + stride = (im.size[0] * bits + 7) // 8 + # stride should be even + stride += stride % 2 + # Stride needs to be kept in sync with the PcxEncode.c version. + # Ideally it should be passed in in the state, but the bytes value + # gets overwritten. + + logger.debug( + "PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d", + im.size[0], + bits, + stride, + ) + + # under windows, we could determine the current screen size with + # "Image.core.display_mode()[1]", but I think that's overkill... + + screen = im.size + + dpi = 100, 100 + + # PCX header + fp.write( + o8(10) + + o8(version) + + o8(1) + + o8(bits) + + o16(0) + + o16(0) + + o16(im.size[0] - 1) + + o16(im.size[1] - 1) + + o16(dpi[0]) + + o16(dpi[1]) + + b"\0" * 24 + + b"\xFF" * 24 + + b"\0" + + o8(planes) + + o16(stride) + + o16(1) + + o16(screen[0]) + + o16(screen[1]) + + b"\0" * 54 + ) + + assert fp.tell() == 128 + + ImageFile._save(im, fp, [("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))]) + + if im.mode == "P": + # colour palette + fp.write(o8(12)) + palette = im.im.getpalette("RGB", "RGB") + palette += b"\x00" * (768 - len(palette)) + fp.write(palette) # 768 bytes + elif im.mode == "L": + # grayscale palette + fp.write(o8(12)) + for i in range(256): + fp.write(o8(i) * 3) + + +# -------------------------------------------------------------------- +# registry + + +Image.register_open(PcxImageFile.format, PcxImageFile, _accept) +Image.register_save(PcxImageFile.format, _save) + +Image.register_extension(PcxImageFile.format, ".pcx") + +Image.register_mime(PcxImageFile.format, "image/x-pcx") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PdfImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PdfImagePlugin.py new file mode 100644 index 00000000..3506aadc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PdfImagePlugin.py @@ -0,0 +1,303 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PDF (Acrobat) file handling +# +# History: +# 1996-07-16 fl Created +# 1997-01-18 fl Fixed header +# 2004-02-21 fl Fixes for 1/L/CMYK images, etc. +# 2004-02-24 fl Fixes for 1 and P images. +# +# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996-1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +# Image plugin for PDF images (output only). +## +from __future__ import annotations + +import io +import math +import os +import time + +from . import Image, ImageFile, ImageSequence, PdfParser, __version__, features + +# +# -------------------------------------------------------------------- + +# object ids: +# 1. catalogue +# 2. pages +# 3. image +# 4. page +# 5. page contents + + +def _save_all(im, fp, filename): + _save(im, fp, filename, save_all=True) + + +## +# (Internal) Image save plugin for the PDF format. + + +def _write_image(im, filename, existing_pdf, image_refs): + # FIXME: Should replace ASCIIHexDecode with RunLengthDecode + # (packbits) or LZWDecode (tiff/lzw compression). Note that + # PDF 1.2 also supports Flatedecode (zip compression). + + params = None + decode = None + + # + # Get image characteristics + + width, height = im.size + + dict_obj = {"BitsPerComponent": 8} + if im.mode == "1": + if features.check("libtiff"): + filter = "CCITTFaxDecode" + dict_obj["BitsPerComponent"] = 1 + params = PdfParser.PdfArray( + [ + PdfParser.PdfDict( + { + "K": -1, + "BlackIs1": True, + "Columns": width, + "Rows": height, + } + ) + ] + ) + else: + filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray") + procset = "ImageB" # grayscale + elif im.mode == "L": + filter = "DCTDecode" + # params = f"<< /Predictor 15 /Columns {width-2} >>" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray") + procset = "ImageB" # grayscale + elif im.mode == "LA": + filter = "JPXDecode" + # params = f"<< /Predictor 15 /Columns {width-2} >>" + procset = "ImageB" # grayscale + dict_obj["SMaskInData"] = 1 + elif im.mode == "P": + filter = "ASCIIHexDecode" + palette = im.getpalette() + dict_obj["ColorSpace"] = [ + PdfParser.PdfName("Indexed"), + PdfParser.PdfName("DeviceRGB"), + len(palette) // 3 - 1, + PdfParser.PdfBinary(palette), + ] + procset = "ImageI" # indexed color + + if "transparency" in im.info: + smask = im.convert("LA").getchannel("A") + smask.encoderinfo = {} + + image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0] + dict_obj["SMask"] = image_ref + elif im.mode == "RGB": + filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB") + procset = "ImageC" # color images + elif im.mode == "RGBA": + filter = "JPXDecode" + procset = "ImageC" # color images + dict_obj["SMaskInData"] = 1 + elif im.mode == "CMYK": + filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceCMYK") + procset = "ImageC" # color images + decode = [1, 0, 1, 0, 1, 0, 1, 0] + else: + msg = f"cannot save mode {im.mode}" + raise ValueError(msg) + + # + # image + + op = io.BytesIO() + + if filter == "ASCIIHexDecode": + ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)]) + elif filter == "CCITTFaxDecode": + im.save( + op, + "TIFF", + compression="group4", + # use a single strip + strip_size=math.ceil(width / 8) * height, + ) + elif filter == "DCTDecode": + Image.SAVE["JPEG"](im, op, filename) + elif filter == "JPXDecode": + del dict_obj["BitsPerComponent"] + Image.SAVE["JPEG2000"](im, op, filename) + else: + msg = f"unsupported PDF filter ({filter})" + raise ValueError(msg) + + stream = op.getvalue() + if filter == "CCITTFaxDecode": + stream = stream[8:] + filter = PdfParser.PdfArray([PdfParser.PdfName(filter)]) + else: + filter = PdfParser.PdfName(filter) + + image_ref = image_refs.pop(0) + existing_pdf.write_obj( + image_ref, + stream=stream, + Type=PdfParser.PdfName("XObject"), + Subtype=PdfParser.PdfName("Image"), + Width=width, # * 72.0 / x_resolution, + Height=height, # * 72.0 / y_resolution, + Filter=filter, + Decode=decode, + DecodeParms=params, + **dict_obj, + ) + + return image_ref, procset + + +def _save(im, fp, filename, save_all=False): + is_appending = im.encoderinfo.get("append", False) + if is_appending: + existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="r+b") + else: + existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b") + + dpi = im.encoderinfo.get("dpi") + if dpi: + x_resolution = dpi[0] + y_resolution = dpi[1] + else: + x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0) + + info = { + "title": None + if is_appending + else os.path.splitext(os.path.basename(filename))[0], + "author": None, + "subject": None, + "keywords": None, + "creator": None, + "producer": None, + "creationDate": None if is_appending else time.gmtime(), + "modDate": None if is_appending else time.gmtime(), + } + for k, default in info.items(): + v = im.encoderinfo.get(k) if k in im.encoderinfo else default + if v: + existing_pdf.info[k[0].upper() + k[1:]] = v + + # + # make sure image data is available + im.load() + + existing_pdf.start_writing() + existing_pdf.write_header() + existing_pdf.write_comment(f"created by Pillow {__version__} PDF driver") + + # + # pages + ims = [im] + if save_all: + append_images = im.encoderinfo.get("append_images", []) + for append_im in append_images: + append_im.encoderinfo = im.encoderinfo.copy() + ims.append(append_im) + number_of_pages = 0 + image_refs = [] + page_refs = [] + contents_refs = [] + for im in ims: + im_number_of_pages = 1 + if save_all: + try: + im_number_of_pages = im.n_frames + except AttributeError: + # Image format does not have n_frames. + # It is a single frame image + pass + number_of_pages += im_number_of_pages + for i in range(im_number_of_pages): + image_refs.append(existing_pdf.next_object_id(0)) + if im.mode == "P" and "transparency" in im.info: + image_refs.append(existing_pdf.next_object_id(0)) + + page_refs.append(existing_pdf.next_object_id(0)) + contents_refs.append(existing_pdf.next_object_id(0)) + existing_pdf.pages.append(page_refs[-1]) + + # + # catalog and list of pages + existing_pdf.write_catalog() + + page_number = 0 + for im_sequence in ims: + im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence] + for im in im_pages: + image_ref, procset = _write_image(im, filename, existing_pdf, image_refs) + + # + # page + + existing_pdf.write_page( + page_refs[page_number], + Resources=PdfParser.PdfDict( + ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)], + XObject=PdfParser.PdfDict(image=image_ref), + ), + MediaBox=[ + 0, + 0, + im.width * 72.0 / x_resolution, + im.height * 72.0 / y_resolution, + ], + Contents=contents_refs[page_number], + ) + + # + # page contents + + page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % ( + im.width * 72.0 / x_resolution, + im.height * 72.0 / y_resolution, + ) + + existing_pdf.write_obj(contents_refs[page_number], stream=page_contents) + + page_number += 1 + + # + # trailer + existing_pdf.write_xref_and_trailer() + if hasattr(fp, "flush"): + fp.flush() + existing_pdf.close() + + +# +# -------------------------------------------------------------------- + + +Image.register_save("PDF", _save) +Image.register_save_all("PDF", _save_all) + +Image.register_extension("PDF", ".pdf") + +Image.register_mime("PDF", "application/pdf") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PdfParser.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PdfParser.py new file mode 100644 index 00000000..01446000 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PdfParser.py @@ -0,0 +1,998 @@ +from __future__ import annotations + +import calendar +import codecs +import collections +import mmap +import os +import re +import time +import zlib + + +# see 7.9.2.2 Text String Type on page 86 and D.3 PDFDocEncoding Character Set +# on page 656 +def encode_text(s): + return codecs.BOM_UTF16_BE + s.encode("utf_16_be") + + +PDFDocEncoding = { + 0x16: "\u0017", + 0x18: "\u02D8", + 0x19: "\u02C7", + 0x1A: "\u02C6", + 0x1B: "\u02D9", + 0x1C: "\u02DD", + 0x1D: "\u02DB", + 0x1E: "\u02DA", + 0x1F: "\u02DC", + 0x80: "\u2022", + 0x81: "\u2020", + 0x82: "\u2021", + 0x83: "\u2026", + 0x84: "\u2014", + 0x85: "\u2013", + 0x86: "\u0192", + 0x87: "\u2044", + 0x88: "\u2039", + 0x89: "\u203A", + 0x8A: "\u2212", + 0x8B: "\u2030", + 0x8C: "\u201E", + 0x8D: "\u201C", + 0x8E: "\u201D", + 0x8F: "\u2018", + 0x90: "\u2019", + 0x91: "\u201A", + 0x92: "\u2122", + 0x93: "\uFB01", + 0x94: "\uFB02", + 0x95: "\u0141", + 0x96: "\u0152", + 0x97: "\u0160", + 0x98: "\u0178", + 0x99: "\u017D", + 0x9A: "\u0131", + 0x9B: "\u0142", + 0x9C: "\u0153", + 0x9D: "\u0161", + 0x9E: "\u017E", + 0xA0: "\u20AC", +} + + +def decode_text(b): + if b[: len(codecs.BOM_UTF16_BE)] == codecs.BOM_UTF16_BE: + return b[len(codecs.BOM_UTF16_BE) :].decode("utf_16_be") + else: + return "".join(PDFDocEncoding.get(byte, chr(byte)) for byte in b) + + +class PdfFormatError(RuntimeError): + """An error that probably indicates a syntactic or semantic error in the + PDF file structure""" + + pass + + +def check_format_condition(condition, error_message): + if not condition: + raise PdfFormatError(error_message) + + +class IndirectReference( + collections.namedtuple("IndirectReferenceTuple", ["object_id", "generation"]) +): + def __str__(self): + return f"{self.object_id} {self.generation} R" + + def __bytes__(self): + return self.__str__().encode("us-ascii") + + def __eq__(self, other): + return ( + other.__class__ is self.__class__ + and other.object_id == self.object_id + and other.generation == self.generation + ) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.object_id, self.generation)) + + +class IndirectObjectDef(IndirectReference): + def __str__(self): + return f"{self.object_id} {self.generation} obj" + + +class XrefTable: + def __init__(self): + self.existing_entries = {} # object ID => (offset, generation) + self.new_entries = {} # object ID => (offset, generation) + self.deleted_entries = {0: 65536} # object ID => generation + self.reading_finished = False + + def __setitem__(self, key, value): + if self.reading_finished: + self.new_entries[key] = value + else: + self.existing_entries[key] = value + if key in self.deleted_entries: + del self.deleted_entries[key] + + def __getitem__(self, key): + try: + return self.new_entries[key] + except KeyError: + return self.existing_entries[key] + + def __delitem__(self, key): + if key in self.new_entries: + generation = self.new_entries[key][1] + 1 + del self.new_entries[key] + self.deleted_entries[key] = generation + elif key in self.existing_entries: + generation = self.existing_entries[key][1] + 1 + self.deleted_entries[key] = generation + elif key in self.deleted_entries: + generation = self.deleted_entries[key] + else: + msg = ( + "object ID " + str(key) + " cannot be deleted because it doesn't exist" + ) + raise IndexError(msg) + + def __contains__(self, key): + return key in self.existing_entries or key in self.new_entries + + def __len__(self): + return len( + set(self.existing_entries.keys()) + | set(self.new_entries.keys()) + | set(self.deleted_entries.keys()) + ) + + def keys(self): + return ( + set(self.existing_entries.keys()) - set(self.deleted_entries.keys()) + ) | set(self.new_entries.keys()) + + def write(self, f): + keys = sorted(set(self.new_entries.keys()) | set(self.deleted_entries.keys())) + deleted_keys = sorted(set(self.deleted_entries.keys())) + startxref = f.tell() + f.write(b"xref\n") + while keys: + # find a contiguous sequence of object IDs + prev = None + for index, key in enumerate(keys): + if prev is None or prev + 1 == key: + prev = key + else: + contiguous_keys = keys[:index] + keys = keys[index:] + break + else: + contiguous_keys = keys + keys = None + f.write(b"%d %d\n" % (contiguous_keys[0], len(contiguous_keys))) + for object_id in contiguous_keys: + if object_id in self.new_entries: + f.write(b"%010d %05d n \n" % self.new_entries[object_id]) + else: + this_deleted_object_id = deleted_keys.pop(0) + check_format_condition( + object_id == this_deleted_object_id, + f"expected the next deleted object ID to be {object_id}, " + f"instead found {this_deleted_object_id}", + ) + try: + next_in_linked_list = deleted_keys[0] + except IndexError: + next_in_linked_list = 0 + f.write( + b"%010d %05d f \n" + % (next_in_linked_list, self.deleted_entries[object_id]) + ) + return startxref + + +class PdfName: + def __init__(self, name): + if isinstance(name, PdfName): + self.name = name.name + elif isinstance(name, bytes): + self.name = name + else: + self.name = name.encode("us-ascii") + + def name_as_str(self): + return self.name.decode("us-ascii") + + def __eq__(self, other): + return ( + isinstance(other, PdfName) and other.name == self.name + ) or other == self.name + + def __hash__(self): + return hash(self.name) + + def __repr__(self): + return f"PdfName({repr(self.name)})" + + @classmethod + def from_pdf_stream(cls, data): + return cls(PdfParser.interpret_name(data)) + + allowed_chars = set(range(33, 127)) - {ord(c) for c in "#%/()<>[]{}"} + + def __bytes__(self): + result = bytearray(b"/") + for b in self.name: + if b in self.allowed_chars: + result.append(b) + else: + result.extend(b"#%02X" % b) + return bytes(result) + + +class PdfArray(list): + def __bytes__(self): + return b"[ " + b" ".join(pdf_repr(x) for x in self) + b" ]" + + +class PdfDict(collections.UserDict): + def __setattr__(self, key, value): + if key == "data": + collections.UserDict.__setattr__(self, key, value) + else: + self[key.encode("us-ascii")] = value + + def __getattr__(self, key): + try: + value = self[key.encode("us-ascii")] + except KeyError as e: + raise AttributeError(key) from e + if isinstance(value, bytes): + value = decode_text(value) + if key.endswith("Date"): + if value.startswith("D:"): + value = value[2:] + + relationship = "Z" + if len(value) > 17: + relationship = value[14] + offset = int(value[15:17]) * 60 + if len(value) > 20: + offset += int(value[18:20]) + + format = "%Y%m%d%H%M%S"[: len(value) - 2] + value = time.strptime(value[: len(format) + 2], format) + if relationship in ["+", "-"]: + offset *= 60 + if relationship == "+": + offset *= -1 + value = time.gmtime(calendar.timegm(value) + offset) + return value + + def __bytes__(self): + out = bytearray(b"<<") + for key, value in self.items(): + if value is None: + continue + value = pdf_repr(value) + out.extend(b"\n") + out.extend(bytes(PdfName(key))) + out.extend(b" ") + out.extend(value) + out.extend(b"\n>>") + return bytes(out) + + +class PdfBinary: + def __init__(self, data): + self.data = data + + def __bytes__(self): + return b"<%s>" % b"".join(b"%02X" % b for b in self.data) + + +class PdfStream: + def __init__(self, dictionary, buf): + self.dictionary = dictionary + self.buf = buf + + def decode(self): + try: + filter = self.dictionary.Filter + except AttributeError: + return self.buf + if filter == b"FlateDecode": + try: + expected_length = self.dictionary.DL + except AttributeError: + expected_length = self.dictionary.Length + return zlib.decompress(self.buf, bufsize=int(expected_length)) + else: + msg = f"stream filter {repr(self.dictionary.Filter)} unknown/unsupported" + raise NotImplementedError(msg) + + +def pdf_repr(x): + if x is True: + return b"true" + elif x is False: + return b"false" + elif x is None: + return b"null" + elif isinstance(x, (PdfName, PdfDict, PdfArray, PdfBinary)): + return bytes(x) + elif isinstance(x, (int, float)): + return str(x).encode("us-ascii") + elif isinstance(x, time.struct_time): + return b"(D:" + time.strftime("%Y%m%d%H%M%SZ", x).encode("us-ascii") + b")" + elif isinstance(x, dict): + return bytes(PdfDict(x)) + elif isinstance(x, list): + return bytes(PdfArray(x)) + elif isinstance(x, str): + return pdf_repr(encode_text(x)) + elif isinstance(x, bytes): + # XXX escape more chars? handle binary garbage + x = x.replace(b"\\", b"\\\\") + x = x.replace(b"(", b"\\(") + x = x.replace(b")", b"\\)") + return b"(" + x + b")" + else: + return bytes(x) + + +class PdfParser: + """Based on + https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf + Supports PDF up to 1.4 + """ + + def __init__(self, filename=None, f=None, buf=None, start_offset=0, mode="rb"): + if buf and f: + msg = "specify buf or f or filename, but not both buf and f" + raise RuntimeError(msg) + self.filename = filename + self.buf = buf + self.f = f + self.start_offset = start_offset + self.should_close_buf = False + self.should_close_file = False + if filename is not None and f is None: + self.f = f = open(filename, mode) + self.should_close_file = True + if f is not None: + self.buf = buf = self.get_buf_from_file(f) + self.should_close_buf = True + if not filename and hasattr(f, "name"): + self.filename = f.name + self.cached_objects = {} + if buf: + self.read_pdf_info() + else: + self.file_size_total = self.file_size_this = 0 + self.root = PdfDict() + self.root_ref = None + self.info = PdfDict() + self.info_ref = None + self.page_tree_root = {} + self.pages = [] + self.orig_pages = [] + self.pages_ref = None + self.last_xref_section_offset = None + self.trailer_dict = {} + self.xref_table = XrefTable() + self.xref_table.reading_finished = True + if f: + self.seek_end() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.close() + return False # do not suppress exceptions + + def start_writing(self): + self.close_buf() + self.seek_end() + + def close_buf(self): + try: + self.buf.close() + except AttributeError: + pass + self.buf = None + + def close(self): + if self.should_close_buf: + self.close_buf() + if self.f is not None and self.should_close_file: + self.f.close() + self.f = None + + def seek_end(self): + self.f.seek(0, os.SEEK_END) + + def write_header(self): + self.f.write(b"%PDF-1.4\n") + + def write_comment(self, s): + self.f.write(f"% {s}\n".encode()) + + def write_catalog(self): + self.del_root() + self.root_ref = self.next_object_id(self.f.tell()) + self.pages_ref = self.next_object_id(0) + self.rewrite_pages() + self.write_obj(self.root_ref, Type=PdfName(b"Catalog"), Pages=self.pages_ref) + self.write_obj( + self.pages_ref, + Type=PdfName(b"Pages"), + Count=len(self.pages), + Kids=self.pages, + ) + return self.root_ref + + def rewrite_pages(self): + pages_tree_nodes_to_delete = [] + for i, page_ref in enumerate(self.orig_pages): + page_info = self.cached_objects[page_ref] + del self.xref_table[page_ref.object_id] + pages_tree_nodes_to_delete.append(page_info[PdfName(b"Parent")]) + if page_ref not in self.pages: + # the page has been deleted + continue + # make dict keys into strings for passing to write_page + stringified_page_info = {} + for key, value in page_info.items(): + # key should be a PdfName + stringified_page_info[key.name_as_str()] = value + stringified_page_info["Parent"] = self.pages_ref + new_page_ref = self.write_page(None, **stringified_page_info) + for j, cur_page_ref in enumerate(self.pages): + if cur_page_ref == page_ref: + # replace the page reference with the new one + self.pages[j] = new_page_ref + # delete redundant Pages tree nodes from xref table + for pages_tree_node_ref in pages_tree_nodes_to_delete: + while pages_tree_node_ref: + pages_tree_node = self.cached_objects[pages_tree_node_ref] + if pages_tree_node_ref.object_id in self.xref_table: + del self.xref_table[pages_tree_node_ref.object_id] + pages_tree_node_ref = pages_tree_node.get(b"Parent", None) + self.orig_pages = [] + + def write_xref_and_trailer(self, new_root_ref=None): + if new_root_ref: + self.del_root() + self.root_ref = new_root_ref + if self.info: + self.info_ref = self.write_obj(None, self.info) + start_xref = self.xref_table.write(self.f) + num_entries = len(self.xref_table) + trailer_dict = {b"Root": self.root_ref, b"Size": num_entries} + if self.last_xref_section_offset is not None: + trailer_dict[b"Prev"] = self.last_xref_section_offset + if self.info: + trailer_dict[b"Info"] = self.info_ref + self.last_xref_section_offset = start_xref + self.f.write( + b"trailer\n" + + bytes(PdfDict(trailer_dict)) + + b"\nstartxref\n%d\n%%%%EOF" % start_xref + ) + + def write_page(self, ref, *objs, **dict_obj): + if isinstance(ref, int): + ref = self.pages[ref] + if "Type" not in dict_obj: + dict_obj["Type"] = PdfName(b"Page") + if "Parent" not in dict_obj: + dict_obj["Parent"] = self.pages_ref + return self.write_obj(ref, *objs, **dict_obj) + + def write_obj(self, ref, *objs, **dict_obj): + f = self.f + if ref is None: + ref = self.next_object_id(f.tell()) + else: + self.xref_table[ref.object_id] = (f.tell(), ref.generation) + f.write(bytes(IndirectObjectDef(*ref))) + stream = dict_obj.pop("stream", None) + if stream is not None: + dict_obj["Length"] = len(stream) + if dict_obj: + f.write(pdf_repr(dict_obj)) + for obj in objs: + f.write(pdf_repr(obj)) + if stream is not None: + f.write(b"stream\n") + f.write(stream) + f.write(b"\nendstream\n") + f.write(b"endobj\n") + return ref + + def del_root(self): + if self.root_ref is None: + return + del self.xref_table[self.root_ref.object_id] + del self.xref_table[self.root[b"Pages"].object_id] + + @staticmethod + def get_buf_from_file(f): + if hasattr(f, "getbuffer"): + return f.getbuffer() + elif hasattr(f, "getvalue"): + return f.getvalue() + else: + try: + return mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) + except ValueError: # cannot mmap an empty file + return b"" + + def read_pdf_info(self): + self.file_size_total = len(self.buf) + self.file_size_this = self.file_size_total - self.start_offset + self.read_trailer() + self.root_ref = self.trailer_dict[b"Root"] + self.info_ref = self.trailer_dict.get(b"Info", None) + self.root = PdfDict(self.read_indirect(self.root_ref)) + if self.info_ref is None: + self.info = PdfDict() + else: + self.info = PdfDict(self.read_indirect(self.info_ref)) + check_format_condition(b"Type" in self.root, "/Type missing in Root") + check_format_condition( + self.root[b"Type"] == b"Catalog", "/Type in Root is not /Catalog" + ) + check_format_condition(b"Pages" in self.root, "/Pages missing in Root") + check_format_condition( + isinstance(self.root[b"Pages"], IndirectReference), + "/Pages in Root is not an indirect reference", + ) + self.pages_ref = self.root[b"Pages"] + self.page_tree_root = self.read_indirect(self.pages_ref) + self.pages = self.linearize_page_tree(self.page_tree_root) + # save the original list of page references + # in case the user modifies, adds or deletes some pages + # and we need to rewrite the pages and their list + self.orig_pages = self.pages[:] + + def next_object_id(self, offset=None): + try: + # TODO: support reuse of deleted objects + reference = IndirectReference(max(self.xref_table.keys()) + 1, 0) + except ValueError: + reference = IndirectReference(1, 0) + if offset is not None: + self.xref_table[reference.object_id] = (offset, 0) + return reference + + delimiter = rb"[][()<>{}/%]" + delimiter_or_ws = rb"[][()<>{}/%\000\011\012\014\015\040]" + whitespace = rb"[\000\011\012\014\015\040]" + whitespace_or_hex = rb"[\000\011\012\014\015\0400-9a-fA-F]" + whitespace_optional = whitespace + b"*" + whitespace_mandatory = whitespace + b"+" + # No "\012" aka "\n" or "\015" aka "\r": + whitespace_optional_no_nl = rb"[\000\011\014\040]*" + newline_only = rb"[\r\n]+" + newline = whitespace_optional_no_nl + newline_only + whitespace_optional_no_nl + re_trailer_end = re.compile( + whitespace_mandatory + + rb"trailer" + + whitespace_optional + + rb"<<(.*>>)" + + newline + + rb"startxref" + + newline + + rb"([0-9]+)" + + newline + + rb"%%EOF" + + whitespace_optional + + rb"$", + re.DOTALL, + ) + re_trailer_prev = re.compile( + whitespace_optional + + rb"trailer" + + whitespace_optional + + rb"<<(.*?>>)" + + newline + + rb"startxref" + + newline + + rb"([0-9]+)" + + newline + + rb"%%EOF" + + whitespace_optional, + re.DOTALL, + ) + + def read_trailer(self): + search_start_offset = len(self.buf) - 16384 + if search_start_offset < self.start_offset: + search_start_offset = self.start_offset + m = self.re_trailer_end.search(self.buf, search_start_offset) + check_format_condition(m, "trailer end not found") + # make sure we found the LAST trailer + last_match = m + while m: + last_match = m + m = self.re_trailer_end.search(self.buf, m.start() + 16) + if not m: + m = last_match + trailer_data = m.group(1) + self.last_xref_section_offset = int(m.group(2)) + self.trailer_dict = self.interpret_trailer(trailer_data) + self.xref_table = XrefTable() + self.read_xref_table(xref_section_offset=self.last_xref_section_offset) + if b"Prev" in self.trailer_dict: + self.read_prev_trailer(self.trailer_dict[b"Prev"]) + + def read_prev_trailer(self, xref_section_offset): + trailer_offset = self.read_xref_table(xref_section_offset=xref_section_offset) + m = self.re_trailer_prev.search( + self.buf[trailer_offset : trailer_offset + 16384] + ) + check_format_condition(m, "previous trailer not found") + trailer_data = m.group(1) + check_format_condition( + int(m.group(2)) == xref_section_offset, + "xref section offset in previous trailer doesn't match what was expected", + ) + trailer_dict = self.interpret_trailer(trailer_data) + if b"Prev" in trailer_dict: + self.read_prev_trailer(trailer_dict[b"Prev"]) + + re_whitespace_optional = re.compile(whitespace_optional) + re_name = re.compile( + whitespace_optional + + rb"/([!-$&'*-.0-;=?-Z\\^-z|~]+)(?=" + + delimiter_or_ws + + rb")" + ) + re_dict_start = re.compile(whitespace_optional + rb"<<") + re_dict_end = re.compile(whitespace_optional + rb">>" + whitespace_optional) + + @classmethod + def interpret_trailer(cls, trailer_data): + trailer = {} + offset = 0 + while True: + m = cls.re_name.match(trailer_data, offset) + if not m: + m = cls.re_dict_end.match(trailer_data, offset) + check_format_condition( + m and m.end() == len(trailer_data), + "name not found in trailer, remaining data: " + + repr(trailer_data[offset:]), + ) + break + key = cls.interpret_name(m.group(1)) + value, offset = cls.get_value(trailer_data, m.end()) + trailer[key] = value + check_format_condition( + b"Size" in trailer and isinstance(trailer[b"Size"], int), + "/Size not in trailer or not an integer", + ) + check_format_condition( + b"Root" in trailer and isinstance(trailer[b"Root"], IndirectReference), + "/Root not in trailer or not an indirect reference", + ) + return trailer + + re_hashes_in_name = re.compile(rb"([^#]*)(#([0-9a-fA-F]{2}))?") + + @classmethod + def interpret_name(cls, raw, as_text=False): + name = b"" + for m in cls.re_hashes_in_name.finditer(raw): + if m.group(3): + name += m.group(1) + bytearray.fromhex(m.group(3).decode("us-ascii")) + else: + name += m.group(1) + if as_text: + return name.decode("utf-8") + else: + return bytes(name) + + re_null = re.compile(whitespace_optional + rb"null(?=" + delimiter_or_ws + rb")") + re_true = re.compile(whitespace_optional + rb"true(?=" + delimiter_or_ws + rb")") + re_false = re.compile(whitespace_optional + rb"false(?=" + delimiter_or_ws + rb")") + re_int = re.compile( + whitespace_optional + rb"([-+]?[0-9]+)(?=" + delimiter_or_ws + rb")" + ) + re_real = re.compile( + whitespace_optional + + rb"([-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+))(?=" + + delimiter_or_ws + + rb")" + ) + re_array_start = re.compile(whitespace_optional + rb"\[") + re_array_end = re.compile(whitespace_optional + rb"]") + re_string_hex = re.compile( + whitespace_optional + rb"<(" + whitespace_or_hex + rb"*)>" + ) + re_string_lit = re.compile(whitespace_optional + rb"\(") + re_indirect_reference = re.compile( + whitespace_optional + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"R(?=" + + delimiter_or_ws + + rb")" + ) + re_indirect_def_start = re.compile( + whitespace_optional + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"obj(?=" + + delimiter_or_ws + + rb")" + ) + re_indirect_def_end = re.compile( + whitespace_optional + rb"endobj(?=" + delimiter_or_ws + rb")" + ) + re_comment = re.compile( + rb"(" + whitespace_optional + rb"%[^\r\n]*" + newline + rb")*" + ) + re_stream_start = re.compile(whitespace_optional + rb"stream\r?\n") + re_stream_end = re.compile( + whitespace_optional + rb"endstream(?=" + delimiter_or_ws + rb")" + ) + + @classmethod + def get_value(cls, data, offset, expect_indirect=None, max_nesting=-1): + if max_nesting == 0: + return None, None + m = cls.re_comment.match(data, offset) + if m: + offset = m.end() + m = cls.re_indirect_def_start.match(data, offset) + if m: + check_format_condition( + int(m.group(1)) > 0, + "indirect object definition: object ID must be greater than 0", + ) + check_format_condition( + int(m.group(2)) >= 0, + "indirect object definition: generation must be non-negative", + ) + check_format_condition( + expect_indirect is None + or expect_indirect + == IndirectReference(int(m.group(1)), int(m.group(2))), + "indirect object definition different than expected", + ) + object, offset = cls.get_value(data, m.end(), max_nesting=max_nesting - 1) + if offset is None: + return object, None + m = cls.re_indirect_def_end.match(data, offset) + check_format_condition(m, "indirect object definition end not found") + return object, m.end() + check_format_condition( + not expect_indirect, "indirect object definition not found" + ) + m = cls.re_indirect_reference.match(data, offset) + if m: + check_format_condition( + int(m.group(1)) > 0, + "indirect object reference: object ID must be greater than 0", + ) + check_format_condition( + int(m.group(2)) >= 0, + "indirect object reference: generation must be non-negative", + ) + return IndirectReference(int(m.group(1)), int(m.group(2))), m.end() + m = cls.re_dict_start.match(data, offset) + if m: + offset = m.end() + result = {} + m = cls.re_dict_end.match(data, offset) + while not m: + key, offset = cls.get_value(data, offset, max_nesting=max_nesting - 1) + if offset is None: + return result, None + value, offset = cls.get_value(data, offset, max_nesting=max_nesting - 1) + result[key] = value + if offset is None: + return result, None + m = cls.re_dict_end.match(data, offset) + offset = m.end() + m = cls.re_stream_start.match(data, offset) + if m: + try: + stream_len = int(result[b"Length"]) + except (TypeError, KeyError, ValueError) as e: + msg = "bad or missing Length in stream dict (%r)" % result.get( + b"Length", None + ) + raise PdfFormatError(msg) from e + stream_data = data[m.end() : m.end() + stream_len] + m = cls.re_stream_end.match(data, m.end() + stream_len) + check_format_condition(m, "stream end not found") + offset = m.end() + result = PdfStream(PdfDict(result), stream_data) + else: + result = PdfDict(result) + return result, offset + m = cls.re_array_start.match(data, offset) + if m: + offset = m.end() + result = [] + m = cls.re_array_end.match(data, offset) + while not m: + value, offset = cls.get_value(data, offset, max_nesting=max_nesting - 1) + result.append(value) + if offset is None: + return result, None + m = cls.re_array_end.match(data, offset) + return result, m.end() + m = cls.re_null.match(data, offset) + if m: + return None, m.end() + m = cls.re_true.match(data, offset) + if m: + return True, m.end() + m = cls.re_false.match(data, offset) + if m: + return False, m.end() + m = cls.re_name.match(data, offset) + if m: + return PdfName(cls.interpret_name(m.group(1))), m.end() + m = cls.re_int.match(data, offset) + if m: + return int(m.group(1)), m.end() + m = cls.re_real.match(data, offset) + if m: + # XXX Decimal instead of float??? + return float(m.group(1)), m.end() + m = cls.re_string_hex.match(data, offset) + if m: + # filter out whitespace + hex_string = bytearray( + b for b in m.group(1) if b in b"0123456789abcdefABCDEF" + ) + if len(hex_string) % 2 == 1: + # append a 0 if the length is not even - yes, at the end + hex_string.append(ord(b"0")) + return bytearray.fromhex(hex_string.decode("us-ascii")), m.end() + m = cls.re_string_lit.match(data, offset) + if m: + return cls.get_literal_string(data, m.end()) + # return None, offset # fallback (only for debugging) + msg = "unrecognized object: " + repr(data[offset : offset + 32]) + raise PdfFormatError(msg) + + re_lit_str_token = re.compile( + rb"(\\[nrtbf()\\])|(\\[0-9]{1,3})|(\\(\r\n|\r|\n))|(\r\n|\r|\n)|(\()|(\))" + ) + escaped_chars = { + b"n": b"\n", + b"r": b"\r", + b"t": b"\t", + b"b": b"\b", + b"f": b"\f", + b"(": b"(", + b")": b")", + b"\\": b"\\", + ord(b"n"): b"\n", + ord(b"r"): b"\r", + ord(b"t"): b"\t", + ord(b"b"): b"\b", + ord(b"f"): b"\f", + ord(b"("): b"(", + ord(b")"): b")", + ord(b"\\"): b"\\", + } + + @classmethod + def get_literal_string(cls, data, offset): + nesting_depth = 0 + result = bytearray() + for m in cls.re_lit_str_token.finditer(data, offset): + result.extend(data[offset : m.start()]) + if m.group(1): + result.extend(cls.escaped_chars[m.group(1)[1]]) + elif m.group(2): + result.append(int(m.group(2)[1:], 8)) + elif m.group(3): + pass + elif m.group(5): + result.extend(b"\n") + elif m.group(6): + result.extend(b"(") + nesting_depth += 1 + elif m.group(7): + if nesting_depth == 0: + return bytes(result), m.end() + result.extend(b")") + nesting_depth -= 1 + offset = m.end() + msg = "unfinished literal string" + raise PdfFormatError(msg) + + re_xref_section_start = re.compile(whitespace_optional + rb"xref" + newline) + re_xref_subsection_start = re.compile( + whitespace_optional + + rb"([0-9]+)" + + whitespace_mandatory + + rb"([0-9]+)" + + whitespace_optional + + newline_only + ) + re_xref_entry = re.compile(rb"([0-9]{10}) ([0-9]{5}) ([fn])( \r| \n|\r\n)") + + def read_xref_table(self, xref_section_offset): + subsection_found = False + m = self.re_xref_section_start.match( + self.buf, xref_section_offset + self.start_offset + ) + check_format_condition(m, "xref section start not found") + offset = m.end() + while True: + m = self.re_xref_subsection_start.match(self.buf, offset) + if not m: + check_format_condition( + subsection_found, "xref subsection start not found" + ) + break + subsection_found = True + offset = m.end() + first_object = int(m.group(1)) + num_objects = int(m.group(2)) + for i in range(first_object, first_object + num_objects): + m = self.re_xref_entry.match(self.buf, offset) + check_format_condition(m, "xref entry not found") + offset = m.end() + is_free = m.group(3) == b"f" + if not is_free: + generation = int(m.group(2)) + new_entry = (int(m.group(1)), generation) + if i not in self.xref_table: + self.xref_table[i] = new_entry + return offset + + def read_indirect(self, ref, max_nesting=-1): + offset, generation = self.xref_table[ref[0]] + check_format_condition( + generation == ref[1], + f"expected to find generation {ref[1]} for object ID {ref[0]} in xref " + f"table, instead found generation {generation} at offset {offset}", + ) + value = self.get_value( + self.buf, + offset + self.start_offset, + expect_indirect=IndirectReference(*ref), + max_nesting=max_nesting, + )[0] + self.cached_objects[ref] = value + return value + + def linearize_page_tree(self, node=None): + if node is None: + node = self.page_tree_root + check_format_condition( + node[b"Type"] == b"Pages", "/Type of page tree node is not /Pages" + ) + pages = [] + for kid in node[b"Kids"]: + kid_object = self.read_indirect(kid) + if kid_object[b"Type"] == b"Page": + pages.append(kid) + else: + pages.extend(self.linearize_page_tree(node=kid_object)) + return pages diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PixarImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PixarImagePlugin.py new file mode 100644 index 00000000..af866feb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PixarImagePlugin.py @@ -0,0 +1,70 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIXAR raster support for PIL +# +# history: +# 97-01-29 fl Created +# +# notes: +# This is incomplete; it is based on a few samples created with +# Photoshop 2.5 and 3.0, and a summary description provided by +# Greg Coats . Hopefully, "L" and +# "RGBA" support will be added in future versions. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i16le as i16 + +# +# helpers + + +def _accept(prefix): + return prefix[:4] == b"\200\350\000\000" + + +## +# Image plugin for PIXAR raster images. + + +class PixarImageFile(ImageFile.ImageFile): + format = "PIXAR" + format_description = "PIXAR raster image" + + def _open(self): + # assuming a 4-byte magic label + s = self.fp.read(4) + if not _accept(s): + msg = "not a PIXAR file" + raise SyntaxError(msg) + + # read rest of header + s = s + self.fp.read(508) + + self._size = i16(s, 418), i16(s, 416) + + # get channel/depth descriptions + mode = i16(s, 424), i16(s, 426) + + if mode == (14, 2): + self._mode = "RGB" + # FIXME: to be continued... + + # create tile descriptor (assuming "dumped") + self.tile = [("raw", (0, 0) + self.size, 1024, (self.mode, 0, 1))] + + +# +# -------------------------------------------------------------------- + +Image.register_open(PixarImageFile.format, PixarImageFile, _accept) + +Image.register_extension(PixarImageFile.format, ".pxr") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PngImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PngImagePlugin.py new file mode 100644 index 00000000..e4ed9388 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PngImagePlugin.py @@ -0,0 +1,1460 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PNG support code +# +# See "PNG (Portable Network Graphics) Specification, version 1.0; +# W3C Recommendation", 1996-10-01, Thomas Boutell (ed.). +# +# history: +# 1996-05-06 fl Created (couldn't resist it) +# 1996-12-14 fl Upgraded, added read and verify support (0.2) +# 1996-12-15 fl Separate PNG stream parser +# 1996-12-29 fl Added write support, added getchunks +# 1996-12-30 fl Eliminated circular references in decoder (0.3) +# 1998-07-12 fl Read/write 16-bit images as mode I (0.4) +# 2001-02-08 fl Added transparency support (from Zircon) (0.5) +# 2001-04-16 fl Don't close data source in "open" method (0.6) +# 2004-02-24 fl Don't even pretend to support interlaced files (0.7) +# 2004-08-31 fl Do basic sanity check on chunk identifiers (0.8) +# 2004-09-20 fl Added PngInfo chunk container +# 2004-12-18 fl Added DPI read support (based on code by Niki Spahiev) +# 2008-08-13 fl Added tRNS support for RGB images +# 2009-03-06 fl Support for preserving ICC profiles (by Florian Hoech) +# 2009-03-08 fl Added zTXT support (from Lowell Alleman) +# 2009-03-29 fl Read interlaced PNG files (from Conrado Porto Lopes Gouvua) +# +# Copyright (c) 1997-2009 by Secret Labs AB +# Copyright (c) 1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import logging +import re +import struct +import warnings +import zlib +from enum import IntEnum + +from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from ._binary import o16be as o16 +from ._binary import o32be as o32 + +logger = logging.getLogger(__name__) + +is_cid = re.compile(rb"\w\w\w\w").match + + +_MAGIC = b"\211PNG\r\n\032\n" + + +_MODES = { + # supported bits/color combinations, and corresponding modes/rawmodes + # Grayscale + (1, 0): ("1", "1"), + (2, 0): ("L", "L;2"), + (4, 0): ("L", "L;4"), + (8, 0): ("L", "L"), + (16, 0): ("I", "I;16B"), + # Truecolour + (8, 2): ("RGB", "RGB"), + (16, 2): ("RGB", "RGB;16B"), + # Indexed-colour + (1, 3): ("P", "P;1"), + (2, 3): ("P", "P;2"), + (4, 3): ("P", "P;4"), + (8, 3): ("P", "P"), + # Grayscale with alpha + (8, 4): ("LA", "LA"), + (16, 4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available + # Truecolour with alpha + (8, 6): ("RGBA", "RGBA"), + (16, 6): ("RGBA", "RGBA;16B"), +} + + +_simple_palette = re.compile(b"^\xff*\x00\xff*$") + +MAX_TEXT_CHUNK = ImageFile.SAFEBLOCK +""" +Maximum decompressed size for a iTXt or zTXt chunk. +Eliminates decompression bombs where compressed chunks can expand 1000x. +See :ref:`Text in PNG File Format`. +""" +MAX_TEXT_MEMORY = 64 * MAX_TEXT_CHUNK +""" +Set the maximum total text chunk size. +See :ref:`Text in PNG File Format`. +""" + + +# APNG frame disposal modes +class Disposal(IntEnum): + OP_NONE = 0 + """ + No disposal is done on this frame before rendering the next frame. + See :ref:`Saving APNG sequences`. + """ + OP_BACKGROUND = 1 + """ + This frame’s modified region is cleared to fully transparent black before rendering + the next frame. + See :ref:`Saving APNG sequences`. + """ + OP_PREVIOUS = 2 + """ + This frame’s modified region is reverted to the previous frame’s contents before + rendering the next frame. + See :ref:`Saving APNG sequences`. + """ + + +# APNG frame blend modes +class Blend(IntEnum): + OP_SOURCE = 0 + """ + All color components of this frame, including alpha, overwrite the previous output + image contents. + See :ref:`Saving APNG sequences`. + """ + OP_OVER = 1 + """ + This frame should be alpha composited with the previous output image contents. + See :ref:`Saving APNG sequences`. + """ + + +def _safe_zlib_decompress(s): + dobj = zlib.decompressobj() + plaintext = dobj.decompress(s, MAX_TEXT_CHUNK) + if dobj.unconsumed_tail: + msg = "Decompressed Data Too Large" + raise ValueError(msg) + return plaintext + + +def _crc32(data, seed=0): + return zlib.crc32(data, seed) & 0xFFFFFFFF + + +# -------------------------------------------------------------------- +# Support classes. Suitable for PNG and related formats like MNG etc. + + +class ChunkStream: + def __init__(self, fp): + self.fp = fp + self.queue = [] + + def read(self): + """Fetch a new chunk. Returns header information.""" + cid = None + + if self.queue: + cid, pos, length = self.queue.pop() + self.fp.seek(pos) + else: + s = self.fp.read(8) + cid = s[4:] + pos = self.fp.tell() + length = i32(s) + + if not is_cid(cid): + if not ImageFile.LOAD_TRUNCATED_IMAGES: + msg = f"broken PNG file (chunk {repr(cid)})" + raise SyntaxError(msg) + + return cid, pos, length + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def close(self): + self.queue = self.fp = None + + def push(self, cid, pos, length): + self.queue.append((cid, pos, length)) + + def call(self, cid, pos, length): + """Call the appropriate chunk handler""" + + logger.debug("STREAM %r %s %s", cid, pos, length) + return getattr(self, "chunk_" + cid.decode("ascii"))(pos, length) + + def crc(self, cid, data): + """Read and verify checksum""" + + # Skip CRC checks for ancillary chunks if allowed to load truncated + # images + # 5th byte of first char is 1 [specs, section 5.4] + if ImageFile.LOAD_TRUNCATED_IMAGES and (cid[0] >> 5 & 1): + self.crc_skip(cid, data) + return + + try: + crc1 = _crc32(data, _crc32(cid)) + crc2 = i32(self.fp.read(4)) + if crc1 != crc2: + msg = f"broken PNG file (bad header checksum in {repr(cid)})" + raise SyntaxError(msg) + except struct.error as e: + msg = f"broken PNG file (incomplete checksum in {repr(cid)})" + raise SyntaxError(msg) from e + + def crc_skip(self, cid, data): + """Read checksum""" + + self.fp.read(4) + + def verify(self, endchunk=b"IEND"): + # Simple approach; just calculate checksum for all remaining + # blocks. Must be called directly after open. + + cids = [] + + while True: + try: + cid, pos, length = self.read() + except struct.error as e: + msg = "truncated PNG file" + raise OSError(msg) from e + + if cid == endchunk: + break + self.crc(cid, ImageFile._safe_read(self.fp, length)) + cids.append(cid) + + return cids + + +class iTXt(str): + """ + Subclass of string to allow iTXt chunks to look like strings while + keeping their extra information + + """ + + @staticmethod + def __new__(cls, text, lang=None, tkey=None): + """ + :param cls: the class to use when creating the instance + :param text: value for this key + :param lang: language code + :param tkey: UTF-8 version of the key name + """ + + self = str.__new__(cls, text) + self.lang = lang + self.tkey = tkey + return self + + +class PngInfo: + """ + PNG chunk container (for use with save(pnginfo=)) + + """ + + def __init__(self): + self.chunks = [] + + def add(self, cid, data, after_idat=False): + """Appends an arbitrary chunk. Use with caution. + + :param cid: a byte string, 4 bytes long. + :param data: a byte string of the encoded data + :param after_idat: for use with private chunks. Whether the chunk + should be written after IDAT + + """ + + chunk = [cid, data] + if after_idat: + chunk.append(True) + self.chunks.append(tuple(chunk)) + + def add_itxt(self, key, value, lang="", tkey="", zip=False): + """Appends an iTXt chunk. + + :param key: latin-1 encodable text key name + :param value: value for this key + :param lang: language code + :param tkey: UTF-8 version of the key name + :param zip: compression flag + + """ + + if not isinstance(key, bytes): + key = key.encode("latin-1", "strict") + if not isinstance(value, bytes): + value = value.encode("utf-8", "strict") + if not isinstance(lang, bytes): + lang = lang.encode("utf-8", "strict") + if not isinstance(tkey, bytes): + tkey = tkey.encode("utf-8", "strict") + + if zip: + self.add( + b"iTXt", + key + b"\0\x01\0" + lang + b"\0" + tkey + b"\0" + zlib.compress(value), + ) + else: + self.add(b"iTXt", key + b"\0\0\0" + lang + b"\0" + tkey + b"\0" + value) + + def add_text(self, key, value, zip=False): + """Appends a text chunk. + + :param key: latin-1 encodable text key name + :param value: value for this key, text or an + :py:class:`PIL.PngImagePlugin.iTXt` instance + :param zip: compression flag + + """ + if isinstance(value, iTXt): + return self.add_itxt(key, value, value.lang, value.tkey, zip=zip) + + # The tEXt chunk stores latin-1 text + if not isinstance(value, bytes): + try: + value = value.encode("latin-1", "strict") + except UnicodeError: + return self.add_itxt(key, value, zip=zip) + + if not isinstance(key, bytes): + key = key.encode("latin-1", "strict") + + if zip: + self.add(b"zTXt", key + b"\0\0" + zlib.compress(value)) + else: + self.add(b"tEXt", key + b"\0" + value) + + +# -------------------------------------------------------------------- +# PNG image stream (IHDR/IEND) + + +class PngStream(ChunkStream): + def __init__(self, fp): + super().__init__(fp) + + # local copies of Image attributes + self.im_info = {} + self.im_text = {} + self.im_size = (0, 0) + self.im_mode = None + self.im_tile = None + self.im_palette = None + self.im_custom_mimetype = None + self.im_n_frames = None + self._seq_num = None + self.rewind_state = None + + self.text_memory = 0 + + def check_text_memory(self, chunklen): + self.text_memory += chunklen + if self.text_memory > MAX_TEXT_MEMORY: + msg = ( + "Too much memory used in text chunks: " + f"{self.text_memory}>MAX_TEXT_MEMORY" + ) + raise ValueError(msg) + + def save_rewind(self): + self.rewind_state = { + "info": self.im_info.copy(), + "tile": self.im_tile, + "seq_num": self._seq_num, + } + + def rewind(self): + self.im_info = self.rewind_state["info"] + self.im_tile = self.rewind_state["tile"] + self._seq_num = self.rewind_state["seq_num"] + + def chunk_iCCP(self, pos, length): + # ICC profile + s = ImageFile._safe_read(self.fp, length) + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + i = s.find(b"\0") + logger.debug("iCCP profile name %r", s[:i]) + logger.debug("Compression method %s", s[i]) + comp_method = s[i] + if comp_method != 0: + msg = f"Unknown compression method {comp_method} in iCCP chunk" + raise SyntaxError(msg) + try: + icc_profile = _safe_zlib_decompress(s[i + 2 :]) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + icc_profile = None + else: + raise + except zlib.error: + icc_profile = None # FIXME + self.im_info["icc_profile"] = icc_profile + return s + + def chunk_IHDR(self, pos, length): + # image header + s = ImageFile._safe_read(self.fp, length) + if length < 13: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated IHDR chunk" + raise ValueError(msg) + self.im_size = i32(s, 0), i32(s, 4) + try: + self.im_mode, self.im_rawmode = _MODES[(s[8], s[9])] + except Exception: + pass + if s[12]: + self.im_info["interlace"] = 1 + if s[11]: + msg = "unknown filter category" + raise SyntaxError(msg) + return s + + def chunk_IDAT(self, pos, length): + # image data + if "bbox" in self.im_info: + tile = [("zip", self.im_info["bbox"], pos, self.im_rawmode)] + else: + if self.im_n_frames is not None: + self.im_info["default_image"] = True + tile = [("zip", (0, 0) + self.im_size, pos, self.im_rawmode)] + self.im_tile = tile + self.im_idat = length + msg = "image data found" + raise EOFError(msg) + + def chunk_IEND(self, pos, length): + msg = "end of PNG image" + raise EOFError(msg) + + def chunk_PLTE(self, pos, length): + # palette + s = ImageFile._safe_read(self.fp, length) + if self.im_mode == "P": + self.im_palette = "RGB", s + return s + + def chunk_tRNS(self, pos, length): + # transparency + s = ImageFile._safe_read(self.fp, length) + if self.im_mode == "P": + if _simple_palette.match(s): + # tRNS contains only one full-transparent entry, + # other entries are full opaque + i = s.find(b"\0") + if i >= 0: + self.im_info["transparency"] = i + else: + # otherwise, we have a byte string with one alpha value + # for each palette entry + self.im_info["transparency"] = s + elif self.im_mode in ("1", "L", "I"): + self.im_info["transparency"] = i16(s) + elif self.im_mode == "RGB": + self.im_info["transparency"] = i16(s), i16(s, 2), i16(s, 4) + return s + + def chunk_gAMA(self, pos, length): + # gamma setting + s = ImageFile._safe_read(self.fp, length) + self.im_info["gamma"] = i32(s) / 100000.0 + return s + + def chunk_cHRM(self, pos, length): + # chromaticity, 8 unsigned ints, actual value is scaled by 100,000 + # WP x,y, Red x,y, Green x,y Blue x,y + + s = ImageFile._safe_read(self.fp, length) + raw_vals = struct.unpack(">%dI" % (len(s) // 4), s) + self.im_info["chromaticity"] = tuple(elt / 100000.0 for elt in raw_vals) + return s + + def chunk_sRGB(self, pos, length): + # srgb rendering intent, 1 byte + # 0 perceptual + # 1 relative colorimetric + # 2 saturation + # 3 absolute colorimetric + + s = ImageFile._safe_read(self.fp, length) + if length < 1: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated sRGB chunk" + raise ValueError(msg) + self.im_info["srgb"] = s[0] + return s + + def chunk_pHYs(self, pos, length): + # pixels per unit + s = ImageFile._safe_read(self.fp, length) + if length < 9: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated pHYs chunk" + raise ValueError(msg) + px, py = i32(s, 0), i32(s, 4) + unit = s[8] + if unit == 1: # meter + dpi = px * 0.0254, py * 0.0254 + self.im_info["dpi"] = dpi + elif unit == 0: + self.im_info["aspect"] = px, py + return s + + def chunk_tEXt(self, pos, length): + # text + s = ImageFile._safe_read(self.fp, length) + try: + k, v = s.split(b"\0", 1) + except ValueError: + # fallback for broken tEXt tags + k = s + v = b"" + if k: + k = k.decode("latin-1", "strict") + v_str = v.decode("latin-1", "replace") + + self.im_info[k] = v if k == "exif" else v_str + self.im_text[k] = v_str + self.check_text_memory(len(v_str)) + + return s + + def chunk_zTXt(self, pos, length): + # compressed text + s = ImageFile._safe_read(self.fp, length) + try: + k, v = s.split(b"\0", 1) + except ValueError: + k = s + v = b"" + if v: + comp_method = v[0] + else: + comp_method = 0 + if comp_method != 0: + msg = f"Unknown compression method {comp_method} in zTXt chunk" + raise SyntaxError(msg) + try: + v = _safe_zlib_decompress(v[1:]) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + v = b"" + else: + raise + except zlib.error: + v = b"" + + if k: + k = k.decode("latin-1", "strict") + v = v.decode("latin-1", "replace") + + self.im_info[k] = self.im_text[k] = v + self.check_text_memory(len(v)) + + return s + + def chunk_iTXt(self, pos, length): + # international text + r = s = ImageFile._safe_read(self.fp, length) + try: + k, r = r.split(b"\0", 1) + except ValueError: + return s + if len(r) < 2: + return s + cf, cm, r = r[0], r[1], r[2:] + try: + lang, tk, v = r.split(b"\0", 2) + except ValueError: + return s + if cf != 0: + if cm == 0: + try: + v = _safe_zlib_decompress(v) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + else: + raise + except zlib.error: + return s + else: + return s + try: + k = k.decode("latin-1", "strict") + lang = lang.decode("utf-8", "strict") + tk = tk.decode("utf-8", "strict") + v = v.decode("utf-8", "strict") + except UnicodeError: + return s + + self.im_info[k] = self.im_text[k] = iTXt(v, lang, tk) + self.check_text_memory(len(v)) + + return s + + def chunk_eXIf(self, pos, length): + s = ImageFile._safe_read(self.fp, length) + self.im_info["exif"] = b"Exif\x00\x00" + s + return s + + # APNG chunks + def chunk_acTL(self, pos, length): + s = ImageFile._safe_read(self.fp, length) + if length < 8: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "APNG contains truncated acTL chunk" + raise ValueError(msg) + if self.im_n_frames is not None: + self.im_n_frames = None + warnings.warn("Invalid APNG, will use default PNG image if possible") + return s + n_frames = i32(s) + if n_frames == 0 or n_frames > 0x80000000: + warnings.warn("Invalid APNG, will use default PNG image if possible") + return s + self.im_n_frames = n_frames + self.im_info["loop"] = i32(s, 4) + self.im_custom_mimetype = "image/apng" + return s + + def chunk_fcTL(self, pos, length): + s = ImageFile._safe_read(self.fp, length) + if length < 26: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "APNG contains truncated fcTL chunk" + raise ValueError(msg) + seq = i32(s) + if (self._seq_num is None and seq != 0) or ( + self._seq_num is not None and self._seq_num != seq - 1 + ): + msg = "APNG contains frame sequence errors" + raise SyntaxError(msg) + self._seq_num = seq + width, height = i32(s, 4), i32(s, 8) + px, py = i32(s, 12), i32(s, 16) + im_w, im_h = self.im_size + if px + width > im_w or py + height > im_h: + msg = "APNG contains invalid frames" + raise SyntaxError(msg) + self.im_info["bbox"] = (px, py, px + width, py + height) + delay_num, delay_den = i16(s, 20), i16(s, 22) + if delay_den == 0: + delay_den = 100 + self.im_info["duration"] = float(delay_num) / float(delay_den) * 1000 + self.im_info["disposal"] = s[24] + self.im_info["blend"] = s[25] + return s + + def chunk_fdAT(self, pos, length): + if length < 4: + if ImageFile.LOAD_TRUNCATED_IMAGES: + s = ImageFile._safe_read(self.fp, length) + return s + msg = "APNG contains truncated fDAT chunk" + raise ValueError(msg) + s = ImageFile._safe_read(self.fp, 4) + seq = i32(s) + if self._seq_num != seq - 1: + msg = "APNG contains frame sequence errors" + raise SyntaxError(msg) + self._seq_num = seq + return self.chunk_IDAT(pos + 4, length - 4) + + +# -------------------------------------------------------------------- +# PNG reader + + +def _accept(prefix): + return prefix[:8] == _MAGIC + + +## +# Image plugin for PNG images. + + +class PngImageFile(ImageFile.ImageFile): + format = "PNG" + format_description = "Portable network graphics" + + def _open(self): + if not _accept(self.fp.read(8)): + msg = "not a PNG file" + raise SyntaxError(msg) + self._fp = self.fp + self.__frame = 0 + + # + # Parse headers up to the first IDAT or fDAT chunk + + self.private_chunks = [] + self.png = PngStream(self.fp) + + while True: + # + # get next chunk + + cid, pos, length = self.png.read() + + try: + s = self.png.call(cid, pos, length) + except EOFError: + break + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + s = ImageFile._safe_read(self.fp, length) + if cid[1:2].islower(): + self.private_chunks.append((cid, s)) + + self.png.crc(cid, s) + + # + # Copy relevant attributes from the PngStream. An alternative + # would be to let the PngStream class modify these attributes + # directly, but that introduces circular references which are + # difficult to break if things go wrong in the decoder... + # (believe me, I've tried ;-) + + self._mode = self.png.im_mode + self._size = self.png.im_size + self.info = self.png.im_info + self._text = None + self.tile = self.png.im_tile + self.custom_mimetype = self.png.im_custom_mimetype + self.n_frames = self.png.im_n_frames or 1 + self.default_image = self.info.get("default_image", False) + + if self.png.im_palette: + rawmode, data = self.png.im_palette + self.palette = ImagePalette.raw(rawmode, data) + + if cid == b"fdAT": + self.__prepare_idat = length - 4 + else: + self.__prepare_idat = length # used by load_prepare() + + if self.png.im_n_frames is not None: + self._close_exclusive_fp_after_loading = False + self.png.save_rewind() + self.__rewind_idat = self.__prepare_idat + self.__rewind = self._fp.tell() + if self.default_image: + # IDAT chunk contains default image and not first animation frame + self.n_frames += 1 + self._seek(0) + self.is_animated = self.n_frames > 1 + + @property + def text(self): + # experimental + if self._text is None: + # iTxt, tEXt and zTXt chunks may appear at the end of the file + # So load the file to ensure that they are read + if self.is_animated: + frame = self.__frame + # for APNG, seek to the final frame before loading + self.seek(self.n_frames - 1) + self.load() + if self.is_animated: + self.seek(frame) + return self._text + + def verify(self): + """Verify PNG file""" + + if self.fp is None: + msg = "verify must be called directly after open" + raise RuntimeError(msg) + + # back up to beginning of IDAT block + self.fp.seek(self.tile[0][2] - 8) + + self.png.verify() + self.png.close() + + if self._exclusive_fp: + self.fp.close() + self.fp = None + + def seek(self, frame): + if not self._seek_check(frame): + return + if frame < self.__frame: + self._seek(0, True) + + last_frame = self.__frame + for f in range(self.__frame + 1, frame + 1): + try: + self._seek(f) + except EOFError as e: + self.seek(last_frame) + msg = "no more images in APNG file" + raise EOFError(msg) from e + + def _seek(self, frame, rewind=False): + if frame == 0: + if rewind: + self._fp.seek(self.__rewind) + self.png.rewind() + self.__prepare_idat = self.__rewind_idat + self.im = None + if self.pyaccess: + self.pyaccess = None + self.info = self.png.im_info + self.tile = self.png.im_tile + self.fp = self._fp + self._prev_im = None + self.dispose = None + self.default_image = self.info.get("default_image", False) + self.dispose_op = self.info.get("disposal") + self.blend_op = self.info.get("blend") + self.dispose_extent = self.info.get("bbox") + self.__frame = 0 + else: + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + + # ensure previous frame was loaded + self.load() + + if self.dispose: + self.im.paste(self.dispose, self.dispose_extent) + self._prev_im = self.im.copy() + + self.fp = self._fp + + # advance to the next frame + if self.__prepare_idat: + ImageFile._safe_read(self.fp, self.__prepare_idat) + self.__prepare_idat = 0 + frame_start = False + while True: + self.fp.read(4) # CRC + + try: + cid, pos, length = self.png.read() + except (struct.error, SyntaxError): + break + + if cid == b"IEND": + msg = "No more images in APNG file" + raise EOFError(msg) + if cid == b"fcTL": + if frame_start: + # there must be at least one fdAT chunk between fcTL chunks + msg = "APNG missing frame data" + raise SyntaxError(msg) + frame_start = True + + try: + self.png.call(cid, pos, length) + except UnicodeDecodeError: + break + except EOFError: + if cid == b"fdAT": + length -= 4 + if frame_start: + self.__prepare_idat = length + break + ImageFile._safe_read(self.fp, length) + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + ImageFile._safe_read(self.fp, length) + + self.__frame = frame + self.tile = self.png.im_tile + self.dispose_op = self.info.get("disposal") + self.blend_op = self.info.get("blend") + self.dispose_extent = self.info.get("bbox") + + if not self.tile: + msg = "image not found in APNG frame" + raise EOFError(msg) + + # setup frame disposal (actual disposal done when needed in the next _seek()) + if self._prev_im is None and self.dispose_op == Disposal.OP_PREVIOUS: + self.dispose_op = Disposal.OP_BACKGROUND + + if self.dispose_op == Disposal.OP_PREVIOUS: + self.dispose = self._prev_im.copy() + self.dispose = self._crop(self.dispose, self.dispose_extent) + elif self.dispose_op == Disposal.OP_BACKGROUND: + self.dispose = Image.core.fill(self.mode, self.size) + self.dispose = self._crop(self.dispose, self.dispose_extent) + else: + self.dispose = None + + def tell(self): + return self.__frame + + def load_prepare(self): + """internal: prepare to read PNG file""" + + if self.info.get("interlace"): + self.decoderconfig = self.decoderconfig + (1,) + + self.__idat = self.__prepare_idat # used by load_read() + ImageFile.ImageFile.load_prepare(self) + + def load_read(self, read_bytes): + """internal: read more image data""" + + while self.__idat == 0: + # end of chunk, skip forward to next one + + self.fp.read(4) # CRC + + cid, pos, length = self.png.read() + + if cid not in [b"IDAT", b"DDAT", b"fdAT"]: + self.png.push(cid, pos, length) + return b"" + + if cid == b"fdAT": + try: + self.png.call(cid, pos, length) + except EOFError: + pass + self.__idat = length - 4 # sequence_num has already been read + else: + self.__idat = length # empty chunks are allowed + + # read more data from this chunk + if read_bytes <= 0: + read_bytes = self.__idat + else: + read_bytes = min(read_bytes, self.__idat) + + self.__idat = self.__idat - read_bytes + + return self.fp.read(read_bytes) + + def load_end(self): + """internal: finished reading image data""" + if self.__idat != 0: + self.fp.read(self.__idat) + while True: + self.fp.read(4) # CRC + + try: + cid, pos, length = self.png.read() + except (struct.error, SyntaxError): + break + + if cid == b"IEND": + break + elif cid == b"fcTL" and self.is_animated: + # start of the next frame, stop reading + self.__prepare_idat = 0 + self.png.push(cid, pos, length) + break + + try: + self.png.call(cid, pos, length) + except UnicodeDecodeError: + break + except EOFError: + if cid == b"fdAT": + length -= 4 + ImageFile._safe_read(self.fp, length) + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + s = ImageFile._safe_read(self.fp, length) + if cid[1:2].islower(): + self.private_chunks.append((cid, s, True)) + self._text = self.png.im_text + if not self.is_animated: + self.png.close() + self.png = None + else: + if self._prev_im and self.blend_op == Blend.OP_OVER: + updated = self._crop(self.im, self.dispose_extent) + if self.im.mode == "RGB" and "transparency" in self.info: + mask = updated.convert_transparent( + "RGBA", self.info["transparency"] + ) + else: + mask = updated.convert("RGBA") + self._prev_im.paste(updated, self.dispose_extent, mask) + self.im = self._prev_im + if self.pyaccess: + self.pyaccess = None + + def _getexif(self): + if "exif" not in self.info: + self.load() + if "exif" not in self.info and "Raw profile type exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + def getexif(self): + if "exif" not in self.info: + self.load() + + return super().getexif() + + def getxmp(self): + """ + Returns a dictionary containing the XMP tags. + Requires defusedxml to be installed. + + :returns: XMP tags in a dictionary. + """ + return ( + self._getxmp(self.info["XML:com.adobe.xmp"]) + if "XML:com.adobe.xmp" in self.info + else {} + ) + + +# -------------------------------------------------------------------- +# PNG writer + +_OUTMODES = { + # supported PIL modes, and corresponding rawmodes/bits/color combinations + "1": ("1", b"\x01\x00"), + "L;1": ("L;1", b"\x01\x00"), + "L;2": ("L;2", b"\x02\x00"), + "L;4": ("L;4", b"\x04\x00"), + "L": ("L", b"\x08\x00"), + "LA": ("LA", b"\x08\x04"), + "I": ("I;16B", b"\x10\x00"), + "I;16": ("I;16B", b"\x10\x00"), + "I;16B": ("I;16B", b"\x10\x00"), + "P;1": ("P;1", b"\x01\x03"), + "P;2": ("P;2", b"\x02\x03"), + "P;4": ("P;4", b"\x04\x03"), + "P": ("P", b"\x08\x03"), + "RGB": ("RGB", b"\x08\x02"), + "RGBA": ("RGBA", b"\x08\x06"), +} + + +def putchunk(fp, cid, *data): + """Write a PNG chunk (including CRC field)""" + + data = b"".join(data) + + fp.write(o32(len(data)) + cid) + fp.write(data) + crc = _crc32(data, _crc32(cid)) + fp.write(o32(crc)) + + +class _idat: + # wrap output from the encoder in IDAT chunks + + def __init__(self, fp, chunk): + self.fp = fp + self.chunk = chunk + + def write(self, data): + self.chunk(self.fp, b"IDAT", data) + + +class _fdat: + # wrap encoder output in fdAT chunks + + def __init__(self, fp, chunk, seq_num): + self.fp = fp + self.chunk = chunk + self.seq_num = seq_num + + def write(self, data): + self.chunk(self.fp, b"fdAT", o32(self.seq_num), data) + self.seq_num += 1 + + +def _write_multiple_frames(im, fp, chunk, rawmode, default_image, append_images): + duration = im.encoderinfo.get("duration", im.info.get("duration", 0)) + loop = im.encoderinfo.get("loop", im.info.get("loop", 0)) + disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE)) + blend = im.encoderinfo.get("blend", im.info.get("blend", Blend.OP_SOURCE)) + + if default_image: + chain = itertools.chain(append_images) + else: + chain = itertools.chain([im], append_images) + + im_frames = [] + frame_count = 0 + for im_seq in chain: + for im_frame in ImageSequence.Iterator(im_seq): + if im_frame.mode == rawmode: + im_frame = im_frame.copy() + else: + im_frame = im_frame.convert(rawmode) + encoderinfo = im.encoderinfo.copy() + if isinstance(duration, (list, tuple)): + encoderinfo["duration"] = duration[frame_count] + if isinstance(disposal, (list, tuple)): + encoderinfo["disposal"] = disposal[frame_count] + if isinstance(blend, (list, tuple)): + encoderinfo["blend"] = blend[frame_count] + frame_count += 1 + + if im_frames: + previous = im_frames[-1] + prev_disposal = previous["encoderinfo"].get("disposal") + prev_blend = previous["encoderinfo"].get("blend") + if prev_disposal == Disposal.OP_PREVIOUS and len(im_frames) < 2: + prev_disposal = Disposal.OP_BACKGROUND + + if prev_disposal == Disposal.OP_BACKGROUND: + base_im = previous["im"].copy() + dispose = Image.core.fill("RGBA", im.size, (0, 0, 0, 0)) + bbox = previous["bbox"] + if bbox: + dispose = dispose.crop(bbox) + else: + bbox = (0, 0) + im.size + base_im.paste(dispose, bbox) + elif prev_disposal == Disposal.OP_PREVIOUS: + base_im = im_frames[-2]["im"] + else: + base_im = previous["im"] + delta = ImageChops.subtract_modulo( + im_frame.convert("RGBA"), base_im.convert("RGBA") + ) + bbox = delta.getbbox(alpha_only=False) + if ( + not bbox + and prev_disposal == encoderinfo.get("disposal") + and prev_blend == encoderinfo.get("blend") + ): + previous["encoderinfo"]["duration"] += encoderinfo.get( + "duration", duration + ) + continue + else: + bbox = None + if "duration" not in encoderinfo: + encoderinfo["duration"] = duration + im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) + + if len(im_frames) == 1 and not default_image: + return im_frames[0]["im"] + + # animation control + chunk( + fp, + b"acTL", + o32(len(im_frames)), # 0: num_frames + o32(loop), # 4: num_plays + ) + + # default image IDAT (if it exists) + if default_image: + if im.mode != rawmode: + im = im.convert(rawmode) + ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)]) + + seq_num = 0 + for frame, frame_data in enumerate(im_frames): + im_frame = frame_data["im"] + if not frame_data["bbox"]: + bbox = (0, 0) + im_frame.size + else: + bbox = frame_data["bbox"] + im_frame = im_frame.crop(bbox) + size = im_frame.size + encoderinfo = frame_data["encoderinfo"] + frame_duration = int(round(encoderinfo["duration"])) + frame_disposal = encoderinfo.get("disposal", disposal) + frame_blend = encoderinfo.get("blend", blend) + # frame control + chunk( + fp, + b"fcTL", + o32(seq_num), # sequence_number + o32(size[0]), # width + o32(size[1]), # height + o32(bbox[0]), # x_offset + o32(bbox[1]), # y_offset + o16(frame_duration), # delay_numerator + o16(1000), # delay_denominator + o8(frame_disposal), # dispose_op + o8(frame_blend), # blend_op + ) + seq_num += 1 + # frame data + if frame == 0 and not default_image: + # first frame must be in IDAT chunks for backwards compatibility + ImageFile._save( + im_frame, + _idat(fp, chunk), + [("zip", (0, 0) + im_frame.size, 0, rawmode)], + ) + else: + fdat_chunks = _fdat(fp, chunk, seq_num) + ImageFile._save( + im_frame, + fdat_chunks, + [("zip", (0, 0) + im_frame.size, 0, rawmode)], + ) + seq_num = fdat_chunks.seq_num + + +def _save_all(im, fp, filename): + _save(im, fp, filename, save_all=True) + + +def _save(im, fp, filename, chunk=putchunk, save_all=False): + # save an image to disk (called by the save method) + + if save_all: + default_image = im.encoderinfo.get( + "default_image", im.info.get("default_image") + ) + modes = set() + append_images = im.encoderinfo.get("append_images", []) + for im_seq in itertools.chain([im], append_images): + for im_frame in ImageSequence.Iterator(im_seq): + modes.add(im_frame.mode) + for mode in ("RGBA", "RGB", "P"): + if mode in modes: + break + else: + mode = modes.pop() + else: + mode = im.mode + + if mode == "P": + # + # attempt to minimize storage requirements for palette images + if "bits" in im.encoderinfo: + # number of bits specified by user + colors = min(1 << im.encoderinfo["bits"], 256) + else: + # check palette contents + if im.palette: + colors = max(min(len(im.palette.getdata()[1]) // 3, 256), 1) + else: + colors = 256 + + if colors <= 16: + if colors <= 2: + bits = 1 + elif colors <= 4: + bits = 2 + else: + bits = 4 + mode = f"{mode};{bits}" + + # encoder options + im.encoderconfig = ( + im.encoderinfo.get("optimize", False), + im.encoderinfo.get("compress_level", -1), + im.encoderinfo.get("compress_type", -1), + im.encoderinfo.get("dictionary", b""), + ) + + # get the corresponding PNG mode + try: + rawmode, mode = _OUTMODES[mode] + except KeyError as e: + msg = f"cannot write mode {mode} as PNG" + raise OSError(msg) from e + + # + # write minimal PNG file + + fp.write(_MAGIC) + + chunk( + fp, + b"IHDR", + o32(im.size[0]), # 0: size + o32(im.size[1]), + mode, # 8: depth/type + b"\0", # 10: compression + b"\0", # 11: filter category + b"\0", # 12: interlace flag + ) + + chunks = [b"cHRM", b"gAMA", b"sBIT", b"sRGB", b"tIME"] + + icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile")) + if icc: + # ICC profile + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + name = b"ICC Profile" + data = name + b"\0\0" + zlib.compress(icc) + chunk(fp, b"iCCP", data) + + # You must either have sRGB or iCCP. + # Disallow sRGB chunks when an iCCP-chunk has been emitted. + chunks.remove(b"sRGB") + + info = im.encoderinfo.get("pnginfo") + if info: + chunks_multiple_allowed = [b"sPLT", b"iTXt", b"tEXt", b"zTXt"] + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) + elif cid in chunks_multiple_allowed: + chunk(fp, cid, data) + elif cid[1:2].islower(): + # Private chunk + after_idat = info_chunk[2:3] + if not after_idat: + chunk(fp, cid, data) + + if im.mode == "P": + palette_byte_number = colors * 3 + palette_bytes = im.im.getpalette("RGB")[:palette_byte_number] + while len(palette_bytes) < palette_byte_number: + palette_bytes += b"\0" + chunk(fp, b"PLTE", palette_bytes) + + transparency = im.encoderinfo.get("transparency", im.info.get("transparency", None)) + + if transparency or transparency == 0: + if im.mode == "P": + # limit to actual palette size + alpha_bytes = colors + if isinstance(transparency, bytes): + chunk(fp, b"tRNS", transparency[:alpha_bytes]) + else: + transparency = max(0, min(255, transparency)) + alpha = b"\xFF" * transparency + b"\0" + chunk(fp, b"tRNS", alpha[:alpha_bytes]) + elif im.mode in ("1", "L", "I"): + transparency = max(0, min(65535, transparency)) + chunk(fp, b"tRNS", o16(transparency)) + elif im.mode == "RGB": + red, green, blue = transparency + chunk(fp, b"tRNS", o16(red) + o16(green) + o16(blue)) + else: + if "transparency" in im.encoderinfo: + # don't bother with transparency if it's an RGBA + # and it's in the info dict. It's probably just stale. + msg = "cannot use transparency for this mode" + raise OSError(msg) + else: + if im.mode == "P" and im.im.getpalettemode() == "RGBA": + alpha = im.im.getpalette("RGBA", "A") + alpha_bytes = colors + chunk(fp, b"tRNS", alpha[:alpha_bytes]) + + dpi = im.encoderinfo.get("dpi") + if dpi: + chunk( + fp, + b"pHYs", + o32(int(dpi[0] / 0.0254 + 0.5)), + o32(int(dpi[1] / 0.0254 + 0.5)), + b"\x01", + ) + + if info: + chunks = [b"bKGD", b"hIST"] + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) + + exif = im.encoderinfo.get("exif") + if exif: + if isinstance(exif, Image.Exif): + exif = exif.tobytes(8) + if exif.startswith(b"Exif\x00\x00"): + exif = exif[6:] + chunk(fp, b"eXIf", exif) + + if save_all: + im = _write_multiple_frames( + im, fp, chunk, rawmode, default_image, append_images + ) + if im: + ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)]) + + if info: + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid[1:2].islower(): + # Private chunk + after_idat = info_chunk[2:3] + if after_idat: + chunk(fp, cid, data) + + chunk(fp, b"IEND", b"") + + if hasattr(fp, "flush"): + fp.flush() + + +# -------------------------------------------------------------------- +# PNG chunk converter + + +def getchunks(im, **params): + """Return a list of PNG chunks representing this image.""" + + class collector: + data = [] + + def write(self, data): + pass + + def append(self, chunk): + self.data.append(chunk) + + def append(fp, cid, *data): + data = b"".join(data) + crc = o32(_crc32(data, _crc32(cid))) + fp.append((cid, data, crc)) + + fp = collector() + + try: + im.encoderinfo = params + _save(im, fp, None, append) + finally: + del im.encoderinfo + + return fp.data + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(PngImageFile.format, PngImageFile, _accept) +Image.register_save(PngImageFile.format, _save) +Image.register_save_all(PngImageFile.format, _save_all) + +Image.register_extensions(PngImageFile.format, [".png", ".apng"]) + +Image.register_mime(PngImageFile.format, "image/png") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PpmImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PpmImagePlugin.py new file mode 100644 index 00000000..25dbfa5b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PpmImagePlugin.py @@ -0,0 +1,344 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PPM support for PIL +# +# History: +# 96-03-24 fl Created +# 98-03-06 fl Write RGBA images (as RGB, that is) +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import o8 +from ._binary import o32le as o32 + +# +# -------------------------------------------------------------------- + +b_whitespace = b"\x20\x09\x0a\x0b\x0c\x0d" + +MODES = { + # standard + b"P1": "1", + b"P2": "L", + b"P3": "RGB", + b"P4": "1", + b"P5": "L", + b"P6": "RGB", + # extensions + b"P0CMYK": "CMYK", + # PIL extensions (for test purposes only) + b"PyP": "P", + b"PyRGBA": "RGBA", + b"PyCMYK": "CMYK", +} + + +def _accept(prefix): + return prefix[0:1] == b"P" and prefix[1] in b"0123456y" + + +## +# Image plugin for PBM, PGM, and PPM images. + + +class PpmImageFile(ImageFile.ImageFile): + format = "PPM" + format_description = "Pbmplus image" + + def _read_magic(self): + magic = b"" + # read until whitespace or longest available magic number + for _ in range(6): + c = self.fp.read(1) + if not c or c in b_whitespace: + break + magic += c + return magic + + def _read_token(self): + token = b"" + while len(token) <= 10: # read until next whitespace or limit of 10 characters + c = self.fp.read(1) + if not c: + break + elif c in b_whitespace: # token ended + if not token: + # skip whitespace at start + continue + break + elif c == b"#": + # ignores rest of the line; stops at CR, LF or EOF + while self.fp.read(1) not in b"\r\n": + pass + continue + token += c + if not token: + # Token was not even 1 byte + msg = "Reached EOF while reading header" + raise ValueError(msg) + elif len(token) > 10: + msg = f"Token too long in file header: {token.decode()}" + raise ValueError(msg) + return token + + def _open(self): + magic_number = self._read_magic() + try: + mode = MODES[magic_number] + except KeyError: + msg = "not a PPM file" + raise SyntaxError(msg) + + if magic_number in (b"P1", b"P4"): + self.custom_mimetype = "image/x-portable-bitmap" + elif magic_number in (b"P2", b"P5"): + self.custom_mimetype = "image/x-portable-graymap" + elif magic_number in (b"P3", b"P6"): + self.custom_mimetype = "image/x-portable-pixmap" + + maxval = None + decoder_name = "raw" + if magic_number in (b"P1", b"P2", b"P3"): + decoder_name = "ppm_plain" + for ix in range(3): + token = int(self._read_token()) + if ix == 0: # token is the x size + xsize = token + elif ix == 1: # token is the y size + ysize = token + if mode == "1": + self._mode = "1" + rawmode = "1;I" + break + else: + self._mode = rawmode = mode + elif ix == 2: # token is maxval + maxval = token + if not 0 < maxval < 65536: + msg = "maxval must be greater than 0 and less than 65536" + raise ValueError(msg) + if maxval > 255 and mode == "L": + self._mode = "I" + + if decoder_name != "ppm_plain": + # If maxval matches a bit depth, use the raw decoder directly + if maxval == 65535 and mode == "L": + rawmode = "I;16B" + elif maxval != 255: + decoder_name = "ppm" + + args = (rawmode, 0, 1) if decoder_name == "raw" else (rawmode, maxval) + self._size = xsize, ysize + self.tile = [(decoder_name, (0, 0, xsize, ysize), self.fp.tell(), args)] + + +# +# -------------------------------------------------------------------- + + +class PpmPlainDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def _read_block(self): + return self.fd.read(ImageFile.SAFEBLOCK) + + def _find_comment_end(self, block, start=0): + a = block.find(b"\n", start) + b = block.find(b"\r", start) + return min(a, b) if a * b > 0 else max(a, b) # lowest nonnegative index (or -1) + + def _ignore_comments(self, block): + if self._comment_spans: + # Finish current comment + while block: + comment_end = self._find_comment_end(block) + if comment_end != -1: + # Comment ends in this block + # Delete tail of comment + block = block[comment_end + 1 :] + break + else: + # Comment spans whole block + # So read the next block, looking for the end + block = self._read_block() + + # Search for any further comments + self._comment_spans = False + while True: + comment_start = block.find(b"#") + if comment_start == -1: + # No comment found + break + comment_end = self._find_comment_end(block, comment_start) + if comment_end != -1: + # Comment ends in this block + # Delete comment + block = block[:comment_start] + block[comment_end + 1 :] + else: + # Comment continues to next block(s) + block = block[:comment_start] + self._comment_spans = True + break + return block + + def _decode_bitonal(self): + """ + This is a separate method because in the plain PBM format, all data tokens are + exactly one byte, so the inter-token whitespace is optional. + """ + data = bytearray() + total_bytes = self.state.xsize * self.state.ysize + + while len(data) != total_bytes: + block = self._read_block() # read next block + if not block: + # eof + break + + block = self._ignore_comments(block) + + tokens = b"".join(block.split()) + for token in tokens: + if token not in (48, 49): + msg = b"Invalid token for this mode: %s" % bytes([token]) + raise ValueError(msg) + data = (data + tokens)[:total_bytes] + invert = bytes.maketrans(b"01", b"\xFF\x00") + return data.translate(invert) + + def _decode_blocks(self, maxval): + data = bytearray() + max_len = 10 + out_byte_count = 4 if self.mode == "I" else 1 + out_max = 65535 if self.mode == "I" else 255 + bands = Image.getmodebands(self.mode) + total_bytes = self.state.xsize * self.state.ysize * bands * out_byte_count + + half_token = False + while len(data) != total_bytes: + block = self._read_block() # read next block + if not block: + if half_token: + block = bytearray(b" ") # flush half_token + else: + # eof + break + + block = self._ignore_comments(block) + + if half_token: + block = half_token + block # stitch half_token to new block + half_token = False + + tokens = block.split() + + if block and not block[-1:].isspace(): # block might split token + half_token = tokens.pop() # save half token for later + if len(half_token) > max_len: # prevent buildup of half_token + msg = ( + b"Token too long found in data: %s" % half_token[: max_len + 1] + ) + raise ValueError(msg) + + for token in tokens: + if len(token) > max_len: + msg = b"Token too long found in data: %s" % token[: max_len + 1] + raise ValueError(msg) + value = int(token) + if value > maxval: + msg = f"Channel value too large for this mode: {value}" + raise ValueError(msg) + value = round(value / maxval * out_max) + data += o32(value) if self.mode == "I" else o8(value) + if len(data) == total_bytes: # finished! + break + return data + + def decode(self, buffer): + self._comment_spans = False + if self.mode == "1": + data = self._decode_bitonal() + rawmode = "1;8" + else: + maxval = self.args[-1] + data = self._decode_blocks(maxval) + rawmode = "I;32" if self.mode == "I" else self.mode + self.set_as_raw(bytes(data), rawmode) + return -1, 0 + + +class PpmDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer): + data = bytearray() + maxval = self.args[-1] + in_byte_count = 1 if maxval < 256 else 2 + out_byte_count = 4 if self.mode == "I" else 1 + out_max = 65535 if self.mode == "I" else 255 + bands = Image.getmodebands(self.mode) + while len(data) < self.state.xsize * self.state.ysize * bands * out_byte_count: + pixels = self.fd.read(in_byte_count * bands) + if len(pixels) < in_byte_count * bands: + # eof + break + for b in range(bands): + value = ( + pixels[b] if in_byte_count == 1 else i16(pixels, b * in_byte_count) + ) + value = min(out_max, round(value / maxval * out_max)) + data += o32(value) if self.mode == "I" else o8(value) + rawmode = "I;32" if self.mode == "I" else self.mode + self.set_as_raw(bytes(data), rawmode) + return -1, 0 + + +# +# -------------------------------------------------------------------- + + +def _save(im, fp, filename): + if im.mode == "1": + rawmode, head = "1;I", b"P4" + elif im.mode == "L": + rawmode, head = "L", b"P5" + elif im.mode == "I": + rawmode, head = "I;16B", b"P5" + elif im.mode in ("RGB", "RGBA"): + rawmode, head = "RGB", b"P6" + else: + msg = f"cannot write mode {im.mode} as PPM" + raise OSError(msg) + fp.write(head + b"\n%d %d\n" % im.size) + if head == b"P6": + fp.write(b"255\n") + elif head == b"P5": + if rawmode == "L": + fp.write(b"255\n") + else: + fp.write(b"65535\n") + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))]) + + +# +# -------------------------------------------------------------------- + + +Image.register_open(PpmImageFile.format, PpmImageFile, _accept) +Image.register_save(PpmImageFile.format, _save) + +Image.register_decoder("ppm", PpmDecoder) +Image.register_decoder("ppm_plain", PpmPlainDecoder) + +Image.register_extensions(PpmImageFile.format, [".pbm", ".pgm", ".ppm", ".pnm"]) + +Image.register_mime(PpmImageFile.format, "image/x-portable-anymap") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PsdImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PsdImagePlugin.py new file mode 100644 index 00000000..5cff5641 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PsdImagePlugin.py @@ -0,0 +1,307 @@ +# +# The Python Imaging Library +# $Id$ +# +# Adobe PSD 2.5/3.0 file handling +# +# History: +# 1995-09-01 fl Created +# 1997-01-03 fl Read most PSD images +# 1997-01-18 fl Fixed P and CMYK support +# 2001-10-21 fl Added seek/tell support (for layers) +# +# Copyright (c) 1997-2001 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io + +from . import Image, ImageFile, ImagePalette +from ._binary import i8 +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import si16be as si16 + +MODES = { + # (photoshop mode, bits) -> (pil mode, required channels) + (0, 1): ("1", 1), + (0, 8): ("L", 1), + (1, 8): ("L", 1), + (2, 8): ("P", 1), + (3, 8): ("RGB", 3), + (4, 8): ("CMYK", 4), + (7, 8): ("L", 1), # FIXME: multilayer + (8, 8): ("L", 1), # duotone + (9, 8): ("LAB", 3), +} + + +# --------------------------------------------------------------------. +# read PSD images + + +def _accept(prefix): + return prefix[:4] == b"8BPS" + + +## +# Image plugin for Photoshop images. + + +class PsdImageFile(ImageFile.ImageFile): + format = "PSD" + format_description = "Adobe Photoshop" + _close_exclusive_fp_after_loading = False + + def _open(self): + read = self.fp.read + + # + # header + + s = read(26) + if not _accept(s) or i16(s, 4) != 1: + msg = "not a PSD file" + raise SyntaxError(msg) + + psd_bits = i16(s, 22) + psd_channels = i16(s, 12) + psd_mode = i16(s, 24) + + mode, channels = MODES[(psd_mode, psd_bits)] + + if channels > psd_channels: + msg = "not enough channels" + raise OSError(msg) + if mode == "RGB" and psd_channels == 4: + mode = "RGBA" + channels = 4 + + self._mode = mode + self._size = i32(s, 18), i32(s, 14) + + # + # color mode data + + size = i32(read(4)) + if size: + data = read(size) + if mode == "P" and size == 768: + self.palette = ImagePalette.raw("RGB;L", data) + + # + # image resources + + self.resources = [] + + size = i32(read(4)) + if size: + # load resources + end = self.fp.tell() + size + while self.fp.tell() < end: + read(4) # signature + id = i16(read(2)) + name = read(i8(read(1))) + if not (len(name) & 1): + read(1) # padding + data = read(i32(read(4))) + if len(data) & 1: + read(1) # padding + self.resources.append((id, name, data)) + if id == 1039: # ICC profile + self.info["icc_profile"] = data + + # + # layer and mask information + + self.layers = [] + + size = i32(read(4)) + if size: + end = self.fp.tell() + size + size = i32(read(4)) + if size: + _layer_data = io.BytesIO(ImageFile._safe_read(self.fp, size)) + self.layers = _layerinfo(_layer_data, size) + self.fp.seek(end) + self.n_frames = len(self.layers) + self.is_animated = self.n_frames > 1 + + # + # image descriptor + + self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels) + + # keep the file open + self._fp = self.fp + self.frame = 1 + self._min_frame = 1 + + def seek(self, layer): + if not self._seek_check(layer): + return + + # seek to given layer (1..max) + try: + name, mode, bbox, tile = self.layers[layer - 1] + self._mode = mode + self.tile = tile + self.frame = layer + self.fp = self._fp + return name, bbox + except IndexError as e: + msg = "no such layer" + raise EOFError(msg) from e + + def tell(self): + # return layer number (0=image, 1..max=layers) + return self.frame + + +def _layerinfo(fp, ct_bytes): + # read layerinfo block + layers = [] + + def read(size): + return ImageFile._safe_read(fp, size) + + ct = si16(read(2)) + + # sanity check + if ct_bytes < (abs(ct) * 20): + msg = "Layer block too short for number of layers requested" + raise SyntaxError(msg) + + for _ in range(abs(ct)): + # bounding box + y0 = i32(read(4)) + x0 = i32(read(4)) + y1 = i32(read(4)) + x1 = i32(read(4)) + + # image info + mode = [] + ct_types = i16(read(2)) + types = list(range(ct_types)) + if len(types) > 4: + fp.seek(len(types) * 6 + 12, io.SEEK_CUR) + size = i32(read(4)) + fp.seek(size, io.SEEK_CUR) + continue + + for _ in types: + type = i16(read(2)) + + if type == 65535: + m = "A" + else: + m = "RGBA"[type] + + mode.append(m) + read(4) # size + + # figure out the image mode + mode.sort() + if mode == ["R"]: + mode = "L" + elif mode == ["B", "G", "R"]: + mode = "RGB" + elif mode == ["A", "B", "G", "R"]: + mode = "RGBA" + else: + mode = None # unknown + + # skip over blend flags and extra information + read(12) # filler + name = "" + size = i32(read(4)) # length of the extra data field + if size: + data_end = fp.tell() + size + + length = i32(read(4)) + if length: + fp.seek(length - 16, io.SEEK_CUR) + + length = i32(read(4)) + if length: + fp.seek(length, io.SEEK_CUR) + + length = i8(read(1)) + if length: + # Don't know the proper encoding, + # Latin-1 should be a good guess + name = read(length).decode("latin-1", "replace") + + fp.seek(data_end) + layers.append((name, mode, (x0, y0, x1, y1))) + + # get tiles + for i, (name, mode, bbox) in enumerate(layers): + tile = [] + for m in mode: + t = _maketile(fp, m, bbox, 1) + if t: + tile.extend(t) + layers[i] = name, mode, bbox, tile + + return layers + + +def _maketile(file, mode, bbox, channels): + tile = None + read = file.read + + compression = i16(read(2)) + + xsize = bbox[2] - bbox[0] + ysize = bbox[3] - bbox[1] + + offset = file.tell() + + if compression == 0: + # + # raw compression + tile = [] + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer += ";I" + tile.append(("raw", bbox, offset, layer)) + offset = offset + xsize * ysize + + elif compression == 1: + # + # packbits compression + i = 0 + tile = [] + bytecount = read(channels * ysize * 2) + offset = file.tell() + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer += ";I" + tile.append(("packbits", bbox, offset, layer)) + for y in range(ysize): + offset = offset + i16(bytecount, i) + i += 2 + + file.seek(offset) + + if offset & 1: + read(1) # padding + + return tile + + +# -------------------------------------------------------------------- +# registry + + +Image.register_open(PsdImageFile.format, PsdImageFile, _accept) + +Image.register_extension(PsdImageFile.format, ".psd") + +Image.register_mime(PsdImageFile.format, "image/vnd.adobe.photoshop") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/PyAccess.py b/dbdpy-env/lib/python3.9/site-packages/PIL/PyAccess.py new file mode 100644 index 00000000..07bb712d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/PyAccess.py @@ -0,0 +1,364 @@ +# +# The Python Imaging Library +# Pillow fork +# +# Python implementation of the PixelAccess Object +# +# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-2009 by Fredrik Lundh. +# Copyright (c) 2013 Eric Soroos +# +# See the README file for information on usage and redistribution +# + +# Notes: +# +# * Implements the pixel access object following Access.c +# * Taking only the tuple form, which is used from python. +# * Fill.c uses the integer form, but it's still going to use the old +# Access.c implementation. +# +from __future__ import annotations + +import logging +import sys + +from ._deprecate import deprecate + +try: + from cffi import FFI + + defs = """ + struct Pixel_RGBA { + unsigned char r,g,b,a; + }; + struct Pixel_I16 { + unsigned char l,r; + }; + """ + ffi = FFI() + ffi.cdef(defs) +except ImportError as ex: + # Allow error import for doc purposes, but error out when accessing + # anything in core. + from ._util import DeferredError + + FFI = ffi = DeferredError.new(ex) + +logger = logging.getLogger(__name__) + + +class PyAccess: + def __init__(self, img, readonly=False): + deprecate("PyAccess", 11) + vals = dict(img.im.unsafe_ptrs) + self.readonly = readonly + self.image8 = ffi.cast("unsigned char **", vals["image8"]) + self.image32 = ffi.cast("int **", vals["image32"]) + self.image = ffi.cast("unsigned char **", vals["image"]) + self.xsize, self.ysize = img.im.size + self._img = img + + # Keep pointer to im object to prevent dereferencing. + self._im = img.im + if self._im.mode in ("P", "PA"): + self._palette = img.palette + + # Debugging is polluting test traces, only useful here + # when hacking on PyAccess + # logger.debug("%s", vals) + self._post_init() + + def _post_init(self): + pass + + def __setitem__(self, xy, color): + """ + Modifies the pixel at x,y. The color is given as a single + numerical value for single band images, and a tuple for + multi-band images + + :param xy: The pixel coordinate, given as (x, y). See + :ref:`coordinate-system`. + :param color: The pixel value. + """ + if self.readonly: + msg = "Attempt to putpixel a read only image" + raise ValueError(msg) + (x, y) = xy + if x < 0: + x = self.xsize + x + if y < 0: + y = self.ysize + y + (x, y) = self.check_xy((x, y)) + + if ( + self._im.mode in ("P", "PA") + and isinstance(color, (list, tuple)) + and len(color) in [3, 4] + ): + # RGB or RGBA value for a P or PA image + if self._im.mode == "PA": + alpha = color[3] if len(color) == 4 else 255 + color = color[:3] + color = self._palette.getcolor(color, self._img) + if self._im.mode == "PA": + color = (color, alpha) + + return self.set_pixel(x, y, color) + + def __getitem__(self, xy): + """ + Returns the pixel at x,y. The pixel is returned as a single + value for single band images or a tuple for multiple band + images + + :param xy: The pixel coordinate, given as (x, y). See + :ref:`coordinate-system`. + :returns: a pixel value for single band images, a tuple of + pixel values for multiband images. + """ + (x, y) = xy + if x < 0: + x = self.xsize + x + if y < 0: + y = self.ysize + y + (x, y) = self.check_xy((x, y)) + return self.get_pixel(x, y) + + putpixel = __setitem__ + getpixel = __getitem__ + + def check_xy(self, xy): + (x, y) = xy + if not (0 <= x < self.xsize and 0 <= y < self.ysize): + msg = "pixel location out of range" + raise ValueError(msg) + return xy + + +class _PyAccess32_2(PyAccess): + """PA, LA, stored in first and last bytes of a 32 bit word""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32) + + def get_pixel(self, x, y): + pixel = self.pixels[y][x] + return pixel.r, pixel.a + + def set_pixel(self, x, y, color): + pixel = self.pixels[y][x] + # tuple + pixel.r = min(color[0], 255) + pixel.a = min(color[1], 255) + + +class _PyAccess32_3(PyAccess): + """RGB and friends, stored in the first three bytes of a 32 bit word""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32) + + def get_pixel(self, x, y): + pixel = self.pixels[y][x] + return pixel.r, pixel.g, pixel.b + + def set_pixel(self, x, y, color): + pixel = self.pixels[y][x] + # tuple + pixel.r = min(color[0], 255) + pixel.g = min(color[1], 255) + pixel.b = min(color[2], 255) + pixel.a = 255 + + +class _PyAccess32_4(PyAccess): + """RGBA etc, all 4 bytes of a 32 bit word""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32) + + def get_pixel(self, x, y): + pixel = self.pixels[y][x] + return pixel.r, pixel.g, pixel.b, pixel.a + + def set_pixel(self, x, y, color): + pixel = self.pixels[y][x] + # tuple + pixel.r = min(color[0], 255) + pixel.g = min(color[1], 255) + pixel.b = min(color[2], 255) + pixel.a = min(color[3], 255) + + +class _PyAccess8(PyAccess): + """1, L, P, 8 bit images stored as uint8""" + + def _post_init(self, *args, **kwargs): + self.pixels = self.image8 + + def get_pixel(self, x, y): + return self.pixels[y][x] + + def set_pixel(self, x, y, color): + try: + # integer + self.pixels[y][x] = min(color, 255) + except TypeError: + # tuple + self.pixels[y][x] = min(color[0], 255) + + +class _PyAccessI16_N(PyAccess): + """I;16 access, native bitendian without conversion""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("unsigned short **", self.image) + + def get_pixel(self, x, y): + return self.pixels[y][x] + + def set_pixel(self, x, y, color): + try: + # integer + self.pixels[y][x] = min(color, 65535) + except TypeError: + # tuple + self.pixels[y][x] = min(color[0], 65535) + + +class _PyAccessI16_L(PyAccess): + """I;16L access, with conversion""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("struct Pixel_I16 **", self.image) + + def get_pixel(self, x, y): + pixel = self.pixels[y][x] + return pixel.l + pixel.r * 256 + + def set_pixel(self, x, y, color): + pixel = self.pixels[y][x] + try: + color = min(color, 65535) + except TypeError: + color = min(color[0], 65535) + + pixel.l = color & 0xFF + pixel.r = color >> 8 + + +class _PyAccessI16_B(PyAccess): + """I;16B access, with conversion""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("struct Pixel_I16 **", self.image) + + def get_pixel(self, x, y): + pixel = self.pixels[y][x] + return pixel.l * 256 + pixel.r + + def set_pixel(self, x, y, color): + pixel = self.pixels[y][x] + try: + color = min(color, 65535) + except Exception: + color = min(color[0], 65535) + + pixel.l = color >> 8 + pixel.r = color & 0xFF + + +class _PyAccessI32_N(PyAccess): + """Signed Int32 access, native endian""" + + def _post_init(self, *args, **kwargs): + self.pixels = self.image32 + + def get_pixel(self, x, y): + return self.pixels[y][x] + + def set_pixel(self, x, y, color): + self.pixels[y][x] = color + + +class _PyAccessI32_Swap(PyAccess): + """I;32L/B access, with byteswapping conversion""" + + def _post_init(self, *args, **kwargs): + self.pixels = self.image32 + + def reverse(self, i): + orig = ffi.new("int *", i) + chars = ffi.cast("unsigned char *", orig) + chars[0], chars[1], chars[2], chars[3] = chars[3], chars[2], chars[1], chars[0] + return ffi.cast("int *", chars)[0] + + def get_pixel(self, x, y): + return self.reverse(self.pixels[y][x]) + + def set_pixel(self, x, y, color): + self.pixels[y][x] = self.reverse(color) + + +class _PyAccessF(PyAccess): + """32 bit float access""" + + def _post_init(self, *args, **kwargs): + self.pixels = ffi.cast("float **", self.image32) + + def get_pixel(self, x, y): + return self.pixels[y][x] + + def set_pixel(self, x, y, color): + try: + # not a tuple + self.pixels[y][x] = color + except TypeError: + # tuple + self.pixels[y][x] = color[0] + + +mode_map = { + "1": _PyAccess8, + "L": _PyAccess8, + "P": _PyAccess8, + "I;16N": _PyAccessI16_N, + "LA": _PyAccess32_2, + "La": _PyAccess32_2, + "PA": _PyAccess32_2, + "RGB": _PyAccess32_3, + "LAB": _PyAccess32_3, + "HSV": _PyAccess32_3, + "YCbCr": _PyAccess32_3, + "RGBA": _PyAccess32_4, + "RGBa": _PyAccess32_4, + "RGBX": _PyAccess32_4, + "CMYK": _PyAccess32_4, + "F": _PyAccessF, + "I": _PyAccessI32_N, +} + +if sys.byteorder == "little": + mode_map["I;16"] = _PyAccessI16_N + mode_map["I;16L"] = _PyAccessI16_N + mode_map["I;16B"] = _PyAccessI16_B + + mode_map["I;32L"] = _PyAccessI32_N + mode_map["I;32B"] = _PyAccessI32_Swap +else: + mode_map["I;16"] = _PyAccessI16_L + mode_map["I;16L"] = _PyAccessI16_L + mode_map["I;16B"] = _PyAccessI16_N + + mode_map["I;32L"] = _PyAccessI32_Swap + mode_map["I;32B"] = _PyAccessI32_N + + +def new(img, readonly=False): + access_type = mode_map.get(img.mode, None) + if not access_type: + logger.debug("PyAccess Not Implemented: %s", img.mode) + return None + return access_type(img, readonly) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/QoiImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/QoiImagePlugin.py new file mode 100644 index 00000000..a7b9d4a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/QoiImagePlugin.py @@ -0,0 +1,106 @@ +# +# The Python Imaging Library. +# +# QOI support for PIL +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os + +from . import Image, ImageFile +from ._binary import i32be as i32 +from ._binary import o8 + + +def _accept(prefix): + return prefix[:4] == b"qoif" + + +class QoiImageFile(ImageFile.ImageFile): + format = "QOI" + format_description = "Quite OK Image" + + def _open(self): + if not _accept(self.fp.read(4)): + msg = "not a QOI file" + raise SyntaxError(msg) + + self._size = tuple(i32(self.fp.read(4)) for i in range(2)) + + channels = self.fp.read(1)[0] + self._mode = "RGB" if channels == 3 else "RGBA" + + self.fp.seek(1, os.SEEK_CUR) # colorspace + self.tile = [("qoi", (0, 0) + self._size, self.fp.tell(), None)] + + +class QoiDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def _add_to_previous_pixels(self, value): + self._previous_pixel = value + + r, g, b, a = value + hash_value = (r * 3 + g * 5 + b * 7 + a * 11) % 64 + self._previously_seen_pixels[hash_value] = value + + def decode(self, buffer): + self._previously_seen_pixels = {} + self._previous_pixel = None + self._add_to_previous_pixels(b"".join(o8(i) for i in (0, 0, 0, 255))) + + data = bytearray() + bands = Image.getmodebands(self.mode) + while len(data) < self.state.xsize * self.state.ysize * bands: + byte = self.fd.read(1)[0] + if byte == 0b11111110: # QOI_OP_RGB + value = self.fd.read(3) + self._previous_pixel[3:] + elif byte == 0b11111111: # QOI_OP_RGBA + value = self.fd.read(4) + else: + op = byte >> 6 + if op == 0: # QOI_OP_INDEX + op_index = byte & 0b00111111 + value = self._previously_seen_pixels.get(op_index, (0, 0, 0, 0)) + elif op == 1: # QOI_OP_DIFF + value = ( + (self._previous_pixel[0] + ((byte & 0b00110000) >> 4) - 2) + % 256, + (self._previous_pixel[1] + ((byte & 0b00001100) >> 2) - 2) + % 256, + (self._previous_pixel[2] + (byte & 0b00000011) - 2) % 256, + ) + value += (self._previous_pixel[3],) + elif op == 2: # QOI_OP_LUMA + second_byte = self.fd.read(1)[0] + diff_green = (byte & 0b00111111) - 32 + diff_red = ((second_byte & 0b11110000) >> 4) - 8 + diff_blue = (second_byte & 0b00001111) - 8 + + value = tuple( + (self._previous_pixel[i] + diff_green + diff) % 256 + for i, diff in enumerate((diff_red, 0, diff_blue)) + ) + value += (self._previous_pixel[3],) + elif op == 3: # QOI_OP_RUN + run_length = (byte & 0b00111111) + 1 + value = self._previous_pixel + if bands == 3: + value = value[:3] + data += value * run_length + continue + value = b"".join(o8(i) for i in value) + self._add_to_previous_pixels(value) + + if bands == 3: + value = value[:3] + data += value + self.set_as_raw(bytes(data)) + return -1, 0 + + +Image.register_open(QoiImageFile.format, QoiImageFile, _accept) +Image.register_decoder("qoi", QoiDecoder) +Image.register_extension(QoiImageFile.format, ".qoi") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/SgiImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/SgiImagePlugin.py new file mode 100644 index 00000000..f9a10f61 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/SgiImagePlugin.py @@ -0,0 +1,231 @@ +# +# The Python Imaging Library. +# $Id$ +# +# SGI image file handling +# +# See "The SGI Image File Format (Draft version 0.97)", Paul Haeberli. +# +# +# +# History: +# 2017-22-07 mb Add RLE decompression +# 2016-16-10 mb Add save method without compression +# 1995-09-10 fl Created +# +# Copyright (c) 2016 by Mickael Bonfill. +# Copyright (c) 2008 by Karsten Hiddemann. +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1995 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +import struct + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import o8 + + +def _accept(prefix): + return len(prefix) >= 2 and i16(prefix) == 474 + + +MODES = { + (1, 1, 1): "L", + (1, 2, 1): "L", + (2, 1, 1): "L;16B", + (2, 2, 1): "L;16B", + (1, 3, 3): "RGB", + (2, 3, 3): "RGB;16B", + (1, 3, 4): "RGBA", + (2, 3, 4): "RGBA;16B", +} + + +## +# Image plugin for SGI images. +class SgiImageFile(ImageFile.ImageFile): + format = "SGI" + format_description = "SGI Image File Format" + + def _open(self): + # HEAD + headlen = 512 + s = self.fp.read(headlen) + + if not _accept(s): + msg = "Not an SGI image file" + raise ValueError(msg) + + # compression : verbatim or RLE + compression = s[2] + + # bpc : 1 or 2 bytes (8bits or 16bits) + bpc = s[3] + + # dimension : 1, 2 or 3 (depending on xsize, ysize and zsize) + dimension = i16(s, 4) + + # xsize : width + xsize = i16(s, 6) + + # ysize : height + ysize = i16(s, 8) + + # zsize : channels count + zsize = i16(s, 10) + + # layout + layout = bpc, dimension, zsize + + # determine mode from bits/zsize + rawmode = "" + try: + rawmode = MODES[layout] + except KeyError: + pass + + if rawmode == "": + msg = "Unsupported SGI image mode" + raise ValueError(msg) + + self._size = xsize, ysize + self._mode = rawmode.split(";")[0] + if self.mode == "RGB": + self.custom_mimetype = "image/rgb" + + # orientation -1 : scanlines begins at the bottom-left corner + orientation = -1 + + # decoder info + if compression == 0: + pagesize = xsize * ysize * bpc + if bpc == 2: + self.tile = [ + ("SGI16", (0, 0) + self.size, headlen, (self.mode, 0, orientation)) + ] + else: + self.tile = [] + offset = headlen + for layer in self.mode: + self.tile.append( + ("raw", (0, 0) + self.size, offset, (layer, 0, orientation)) + ) + offset += pagesize + elif compression == 1: + self.tile = [ + ("sgi_rle", (0, 0) + self.size, headlen, (rawmode, orientation, bpc)) + ] + + +def _save(im, fp, filename): + if im.mode not in {"RGB", "RGBA", "L"}: + msg = "Unsupported SGI image mode" + raise ValueError(msg) + + # Get the keyword arguments + info = im.encoderinfo + + # Byte-per-pixel precision, 1 = 8bits per pixel + bpc = info.get("bpc", 1) + + if bpc not in (1, 2): + msg = "Unsupported number of bytes per pixel" + raise ValueError(msg) + + # Flip the image, since the origin of SGI file is the bottom-left corner + orientation = -1 + # Define the file as SGI File Format + magic_number = 474 + # Run-Length Encoding Compression - Unsupported at this time + rle = 0 + + # Number of dimensions (x,y,z) + dim = 3 + # X Dimension = width / Y Dimension = height + x, y = im.size + if im.mode == "L" and y == 1: + dim = 1 + elif im.mode == "L": + dim = 2 + # Z Dimension: Number of channels + z = len(im.mode) + + if dim in {1, 2}: + z = 1 + + # assert we've got the right number of bands. + if len(im.getbands()) != z: + msg = f"incorrect number of bands in SGI write: {z} vs {len(im.getbands())}" + raise ValueError(msg) + + # Minimum Byte value + pinmin = 0 + # Maximum Byte value (255 = 8bits per pixel) + pinmax = 255 + # Image name (79 characters max, truncated below in write) + img_name = os.path.splitext(os.path.basename(filename))[0] + img_name = img_name.encode("ascii", "ignore") + # Standard representation of pixel in the file + colormap = 0 + fp.write(struct.pack(">h", magic_number)) + fp.write(o8(rle)) + fp.write(o8(bpc)) + fp.write(struct.pack(">H", dim)) + fp.write(struct.pack(">H", x)) + fp.write(struct.pack(">H", y)) + fp.write(struct.pack(">H", z)) + fp.write(struct.pack(">l", pinmin)) + fp.write(struct.pack(">l", pinmax)) + fp.write(struct.pack("4s", b"")) # dummy + fp.write(struct.pack("79s", img_name)) # truncates to 79 chars + fp.write(struct.pack("s", b"")) # force null byte after img_name + fp.write(struct.pack(">l", colormap)) + fp.write(struct.pack("404s", b"")) # dummy + + rawmode = "L" + if bpc == 2: + rawmode = "L;16B" + + for channel in im.split(): + fp.write(channel.tobytes("raw", rawmode, 0, orientation)) + + if hasattr(fp, "flush"): + fp.flush() + + +class SGI16Decoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer): + rawmode, stride, orientation = self.args + pagesize = self.state.xsize * self.state.ysize + zsize = len(self.mode) + self.fd.seek(512) + + for band in range(zsize): + channel = Image.new("L", (self.state.xsize, self.state.ysize)) + channel.frombytes( + self.fd.read(2 * pagesize), "raw", "L;16B", stride, orientation + ) + self.im.putband(channel.im, band) + + return -1, 0 + + +# +# registry + + +Image.register_decoder("SGI16", SGI16Decoder) +Image.register_open(SgiImageFile.format, SgiImageFile, _accept) +Image.register_save(SgiImageFile.format, _save) +Image.register_mime(SgiImageFile.format, "image/sgi") + +Image.register_extensions(SgiImageFile.format, [".bw", ".rgb", ".rgba", ".sgi"]) + +# End of file diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/SpiderImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/SpiderImagePlugin.py new file mode 100644 index 00000000..86582fb1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/SpiderImagePlugin.py @@ -0,0 +1,318 @@ +# +# The Python Imaging Library. +# +# SPIDER image file handling +# +# History: +# 2004-08-02 Created BB +# 2006-03-02 added save method +# 2006-03-13 added support for stack images +# +# Copyright (c) 2004 by Health Research Inc. (HRI) RENSSELAER, NY 12144. +# Copyright (c) 2004 by William Baxter. +# Copyright (c) 2004 by Secret Labs AB. +# Copyright (c) 2004 by Fredrik Lundh. +# + +## +# Image plugin for the Spider image format. This format is used +# by the SPIDER software, in processing image data from electron +# microscopy and tomography. +## + +# +# SpiderImagePlugin.py +# +# The Spider image format is used by SPIDER software, in processing +# image data from electron microscopy and tomography. +# +# Spider home page: +# https://spider.wadsworth.org/spider_doc/spider/docs/spider.html +# +# Details about the Spider image format: +# https://spider.wadsworth.org/spider_doc/spider/docs/image_doc.html +# +from __future__ import annotations + +import os +import struct +import sys + +from . import Image, ImageFile + + +def isInt(f): + try: + i = int(f) + if f - i == 0: + return 1 + else: + return 0 + except (ValueError, OverflowError): + return 0 + + +iforms = [1, 3, -11, -12, -21, -22] + + +# There is no magic number to identify Spider files, so just check a +# series of header locations to see if they have reasonable values. +# Returns no. of bytes in the header, if it is a valid Spider header, +# otherwise returns 0 + + +def isSpiderHeader(t): + h = (99,) + t # add 1 value so can use spider header index start=1 + # header values 1,2,5,12,13,22,23 should be integers + for i in [1, 2, 5, 12, 13, 22, 23]: + if not isInt(h[i]): + return 0 + # check iform + iform = int(h[5]) + if iform not in iforms: + return 0 + # check other header values + labrec = int(h[13]) # no. records in file header + labbyt = int(h[22]) # total no. of bytes in header + lenbyt = int(h[23]) # record length in bytes + if labbyt != (labrec * lenbyt): + return 0 + # looks like a valid header + return labbyt + + +def isSpiderImage(filename): + with open(filename, "rb") as fp: + f = fp.read(92) # read 23 * 4 bytes + t = struct.unpack(">23f", f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + t = struct.unpack("<23f", f) # little-endian + hdrlen = isSpiderHeader(t) + return hdrlen + + +class SpiderImageFile(ImageFile.ImageFile): + format = "SPIDER" + format_description = "Spider 2D image" + _close_exclusive_fp_after_loading = False + + def _open(self): + # check header + n = 27 * 4 # read 27 float values + f = self.fp.read(n) + + try: + self.bigendian = 1 + t = struct.unpack(">27f", f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + self.bigendian = 0 + t = struct.unpack("<27f", f) # little-endian + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + msg = "not a valid Spider file" + raise SyntaxError(msg) + except struct.error as e: + msg = "not a valid Spider file" + raise SyntaxError(msg) from e + + h = (99,) + t # add 1 value : spider header index starts at 1 + iform = int(h[5]) + if iform != 1: + msg = "not a Spider 2D image" + raise SyntaxError(msg) + + self._size = int(h[12]), int(h[2]) # size in pixels (width, height) + self.istack = int(h[24]) + self.imgnumber = int(h[27]) + + if self.istack == 0 and self.imgnumber == 0: + # stk=0, img=0: a regular 2D image + offset = hdrlen + self._nimages = 1 + elif self.istack > 0 and self.imgnumber == 0: + # stk>0, img=0: Opening the stack for the first time + self.imgbytes = int(h[12]) * int(h[2]) * 4 + self.hdrlen = hdrlen + self._nimages = int(h[26]) + # Point to the first image in the stack + offset = hdrlen * 2 + self.imgnumber = 1 + elif self.istack == 0 and self.imgnumber > 0: + # stk=0, img>0: an image within the stack + offset = hdrlen + self.stkoffset + self.istack = 2 # So Image knows it's still a stack + else: + msg = "inconsistent stack header values" + raise SyntaxError(msg) + + if self.bigendian: + self.rawmode = "F;32BF" + else: + self.rawmode = "F;32F" + self._mode = "F" + + self.tile = [("raw", (0, 0) + self.size, offset, (self.rawmode, 0, 1))] + self._fp = self.fp # FIXME: hack + + @property + def n_frames(self): + return self._nimages + + @property + def is_animated(self): + return self._nimages > 1 + + # 1st image index is zero (although SPIDER imgnumber starts at 1) + def tell(self): + if self.imgnumber < 1: + return 0 + else: + return self.imgnumber - 1 + + def seek(self, frame): + if self.istack == 0: + msg = "attempt to seek in a non-stack file" + raise EOFError(msg) + if not self._seek_check(frame): + return + self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes) + self.fp = self._fp + self.fp.seek(self.stkoffset) + self._open() + + # returns a byte image after rescaling to 0..255 + def convert2byte(self, depth=255): + (minimum, maximum) = self.getextrema() + m = 1 + if maximum != minimum: + m = depth / (maximum - minimum) + b = -m * minimum + return self.point(lambda i, m=m, b=b: i * m + b).convert("L") + + # returns a ImageTk.PhotoImage object, after rescaling to 0..255 + def tkPhotoImage(self): + from . import ImageTk + + return ImageTk.PhotoImage(self.convert2byte(), palette=256) + + +# -------------------------------------------------------------------- +# Image series + + +# given a list of filenames, return a list of images +def loadImageSeries(filelist=None): + """create a list of :py:class:`~PIL.Image.Image` objects for use in a montage""" + if filelist is None or len(filelist) < 1: + return + + imglist = [] + for img in filelist: + if not os.path.exists(img): + print(f"unable to find {img}") + continue + try: + with Image.open(img) as im: + im = im.convert2byte() + except Exception: + if not isSpiderImage(img): + print(img + " is not a Spider image file") + continue + im.info["filename"] = img + imglist.append(im) + return imglist + + +# -------------------------------------------------------------------- +# For saving images in Spider format + + +def makeSpiderHeader(im): + nsam, nrow = im.size + lenbyt = nsam * 4 # There are labrec records in the header + labrec = int(1024 / lenbyt) + if 1024 % lenbyt != 0: + labrec += 1 + labbyt = labrec * lenbyt + nvalues = int(labbyt / 4) + if nvalues < 23: + return [] + + hdr = [0.0] * nvalues + + # NB these are Fortran indices + hdr[1] = 1.0 # nslice (=1 for an image) + hdr[2] = float(nrow) # number of rows per slice + hdr[3] = float(nrow) # number of records in the image + hdr[5] = 1.0 # iform for 2D image + hdr[12] = float(nsam) # number of pixels per line + hdr[13] = float(labrec) # number of records in file header + hdr[22] = float(labbyt) # total number of bytes in header + hdr[23] = float(lenbyt) # record length in bytes + + # adjust for Fortran indexing + hdr = hdr[1:] + hdr.append(0.0) + # pack binary data into a string + return [struct.pack("f", v) for v in hdr] + + +def _save(im, fp, filename): + if im.mode[0] != "F": + im = im.convert("F") + + hdr = makeSpiderHeader(im) + if len(hdr) < 256: + msg = "Error creating Spider header" + raise OSError(msg) + + # write the SPIDER header + fp.writelines(hdr) + + rawmode = "F;32NF" # 32-bit native floating point + ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))]) + + +def _save_spider(im, fp, filename): + # get the filename extension and register it with Image + ext = os.path.splitext(filename)[1] + Image.register_extension(SpiderImageFile.format, ext) + _save(im, fp, filename) + + +# -------------------------------------------------------------------- + + +Image.register_open(SpiderImageFile.format, SpiderImageFile) +Image.register_save(SpiderImageFile.format, _save_spider) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 SpiderImagePlugin.py [infile] [outfile]") + sys.exit() + + filename = sys.argv[1] + if not isSpiderImage(filename): + print("input image must be in Spider format") + sys.exit() + + with Image.open(filename) as im: + print("image: " + str(im)) + print("format: " + str(im.format)) + print("size: " + str(im.size)) + print("mode: " + str(im.mode)) + print("max, min: ", end=" ") + print(im.getextrema()) + + if len(sys.argv) > 2: + outfile = sys.argv[2] + + # perform some image operation + im = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + print( + f"saving a flipped version of {os.path.basename(filename)} " + f"as {outfile} " + ) + im.save(outfile, SpiderImageFile.format) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/SunImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/SunImagePlugin.py new file mode 100644 index 00000000..11ce3dfe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/SunImagePlugin.py @@ -0,0 +1,139 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Sun image file handling +# +# History: +# 1995-09-10 fl Created +# 1996-05-28 fl Fixed 32-bit alignment +# 1998-12-29 fl Import ImagePalette module +# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault) +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995-1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile, ImagePalette +from ._binary import i32be as i32 + + +def _accept(prefix): + return len(prefix) >= 4 and i32(prefix) == 0x59A66A95 + + +## +# Image plugin for Sun raster files. + + +class SunImageFile(ImageFile.ImageFile): + format = "SUN" + format_description = "Sun Raster File" + + def _open(self): + # The Sun Raster file header is 32 bytes in length + # and has the following format: + + # typedef struct _SunRaster + # { + # DWORD MagicNumber; /* Magic (identification) number */ + # DWORD Width; /* Width of image in pixels */ + # DWORD Height; /* Height of image in pixels */ + # DWORD Depth; /* Number of bits per pixel */ + # DWORD Length; /* Size of image data in bytes */ + # DWORD Type; /* Type of raster file */ + # DWORD ColorMapType; /* Type of color map */ + # DWORD ColorMapLength; /* Size of the color map in bytes */ + # } SUNRASTER; + + # HEAD + s = self.fp.read(32) + if not _accept(s): + msg = "not an SUN raster file" + raise SyntaxError(msg) + + offset = 32 + + self._size = i32(s, 4), i32(s, 8) + + depth = i32(s, 12) + # data_length = i32(s, 16) # unreliable, ignore. + file_type = i32(s, 20) + palette_type = i32(s, 24) # 0: None, 1: RGB, 2: Raw/arbitrary + palette_length = i32(s, 28) + + if depth == 1: + self._mode, rawmode = "1", "1;I" + elif depth == 4: + self._mode, rawmode = "L", "L;4" + elif depth == 8: + self._mode = rawmode = "L" + elif depth == 24: + if file_type == 3: + self._mode, rawmode = "RGB", "RGB" + else: + self._mode, rawmode = "RGB", "BGR" + elif depth == 32: + if file_type == 3: + self._mode, rawmode = "RGB", "RGBX" + else: + self._mode, rawmode = "RGB", "BGRX" + else: + msg = "Unsupported Mode/Bit Depth" + raise SyntaxError(msg) + + if palette_length: + if palette_length > 1024: + msg = "Unsupported Color Palette Length" + raise SyntaxError(msg) + + if palette_type != 1: + msg = "Unsupported Palette Type" + raise SyntaxError(msg) + + offset = offset + palette_length + self.palette = ImagePalette.raw("RGB;L", self.fp.read(palette_length)) + if self.mode == "L": + self._mode = "P" + rawmode = rawmode.replace("L", "P") + + # 16 bit boundaries on stride + stride = ((self.size[0] * depth + 15) // 16) * 2 + + # file type: Type is the version (or flavor) of the bitmap + # file. The following values are typically found in the Type + # field: + # 0000h Old + # 0001h Standard + # 0002h Byte-encoded + # 0003h RGB format + # 0004h TIFF format + # 0005h IFF format + # FFFFh Experimental + + # Old and standard are the same, except for the length tag. + # byte-encoded is run-length-encoded + # RGB looks similar to standard, but RGB byte order + # TIFF and IFF mean that they were converted from T/IFF + # Experimental means that it's something else. + # (https://www.fileformat.info/format/sunraster/egff.htm) + + if file_type in (0, 1, 3, 4, 5): + self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride))] + elif file_type == 2: + self.tile = [("sun_rle", (0, 0) + self.size, offset, rawmode)] + else: + msg = "Unsupported Sun Raster file type" + raise SyntaxError(msg) + + +# +# registry + + +Image.register_open(SunImageFile.format, SunImageFile, _accept) + +Image.register_extension(SunImageFile.format, ".ras") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/TarIO.py b/dbdpy-env/lib/python3.9/site-packages/PIL/TarIO.py new file mode 100644 index 00000000..7470663b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/TarIO.py @@ -0,0 +1,73 @@ +# +# The Python Imaging Library. +# $Id$ +# +# read files from within a tar file +# +# History: +# 95-06-18 fl Created +# 96-05-28 fl Open files in binary mode +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-96. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from types import TracebackType + +from . import ContainerIO + + +class TarIO(ContainerIO.ContainerIO[bytes]): + """A file object that provides read access to a given member of a TAR file.""" + + def __init__(self, tarfile: str, file: str) -> None: + """ + Create file object. + + :param tarfile: Name of TAR file. + :param file: Name of member file. + """ + self.fh = open(tarfile, "rb") + + while True: + s = self.fh.read(512) + if len(s) != 512: + msg = "unexpected end of tar file" + raise OSError(msg) + + name = s[:100].decode("utf-8") + i = name.find("\0") + if i == 0: + msg = "cannot find subfile" + raise OSError(msg) + if i > 0: + name = name[:i] + + size = int(s[124:135], 8) + + if file == name: + break + + self.fh.seek((size + 511) & (~511), io.SEEK_CUR) + + # Open region + super().__init__(self.fh, self.fh.tell(), size) + + # Context manager support + def __enter__(self) -> TarIO: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.close() + + def close(self) -> None: + self.fh.close() diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/TgaImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/TgaImagePlugin.py new file mode 100644 index 00000000..65c7484f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/TgaImagePlugin.py @@ -0,0 +1,255 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TGA file handling +# +# History: +# 95-09-01 fl created (reads 24-bit files only) +# 97-01-04 fl support more TGA versions, including compressed images +# 98-07-04 fl fixed orientation and alpha layer bugs +# 98-09-11 fl fixed orientation for runlength decoder +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import warnings + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + +# +# -------------------------------------------------------------------- +# Read RGA file + + +MODES = { + # map imagetype/depth to rawmode + (1, 8): "P", + (3, 1): "1", + (3, 8): "L", + (3, 16): "LA", + (2, 16): "BGR;5", + (2, 24): "BGR", + (2, 32): "BGRA", +} + + +## +# Image plugin for Targa files. + + +class TgaImageFile(ImageFile.ImageFile): + format = "TGA" + format_description = "Targa" + + def _open(self): + # process header + s = self.fp.read(18) + + id_len = s[0] + + colormaptype = s[1] + imagetype = s[2] + + depth = s[16] + + flags = s[17] + + self._size = i16(s, 12), i16(s, 14) + + # validate header fields + if ( + colormaptype not in (0, 1) + or self.size[0] <= 0 + or self.size[1] <= 0 + or depth not in (1, 8, 16, 24, 32) + ): + msg = "not a TGA file" + raise SyntaxError(msg) + + # image mode + if imagetype in (3, 11): + self._mode = "L" + if depth == 1: + self._mode = "1" # ??? + elif depth == 16: + self._mode = "LA" + elif imagetype in (1, 9): + self._mode = "P" + elif imagetype in (2, 10): + self._mode = "RGB" + if depth == 32: + self._mode = "RGBA" + else: + msg = "unknown TGA mode" + raise SyntaxError(msg) + + # orientation + orientation = flags & 0x30 + self._flip_horizontally = orientation in [0x10, 0x30] + if orientation in [0x20, 0x30]: + orientation = 1 + elif orientation in [0, 0x10]: + orientation = -1 + else: + msg = "unknown TGA orientation" + raise SyntaxError(msg) + + self.info["orientation"] = orientation + + if imagetype & 8: + self.info["compression"] = "tga_rle" + + if id_len: + self.info["id_section"] = self.fp.read(id_len) + + if colormaptype: + # read palette + start, size, mapdepth = i16(s, 3), i16(s, 5), s[7] + if mapdepth == 16: + self.palette = ImagePalette.raw( + "BGR;15", b"\0" * 2 * start + self.fp.read(2 * size) + ) + elif mapdepth == 24: + self.palette = ImagePalette.raw( + "BGR", b"\0" * 3 * start + self.fp.read(3 * size) + ) + elif mapdepth == 32: + self.palette = ImagePalette.raw( + "BGRA", b"\0" * 4 * start + self.fp.read(4 * size) + ) + + # setup tile descriptor + try: + rawmode = MODES[(imagetype & 7, depth)] + if imagetype & 8: + # compressed + self.tile = [ + ( + "tga_rle", + (0, 0) + self.size, + self.fp.tell(), + (rawmode, orientation, depth), + ) + ] + else: + self.tile = [ + ( + "raw", + (0, 0) + self.size, + self.fp.tell(), + (rawmode, 0, orientation), + ) + ] + except KeyError: + pass # cannot decode + + def load_end(self): + if self._flip_horizontally: + self.im = self.im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + + +# +# -------------------------------------------------------------------- +# Write TGA file + + +SAVE = { + "1": ("1", 1, 0, 3), + "L": ("L", 8, 0, 3), + "LA": ("LA", 16, 0, 3), + "P": ("P", 8, 1, 1), + "RGB": ("BGR", 24, 0, 2), + "RGBA": ("BGRA", 32, 0, 2), +} + + +def _save(im, fp, filename): + try: + rawmode, bits, colormaptype, imagetype = SAVE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as TGA" + raise OSError(msg) from e + + if "rle" in im.encoderinfo: + rle = im.encoderinfo["rle"] + else: + compression = im.encoderinfo.get("compression", im.info.get("compression")) + rle = compression == "tga_rle" + if rle: + imagetype += 8 + + id_section = im.encoderinfo.get("id_section", im.info.get("id_section", "")) + id_len = len(id_section) + if id_len > 255: + id_len = 255 + id_section = id_section[:255] + warnings.warn("id_section has been trimmed to 255 characters") + + if colormaptype: + palette = im.im.getpalette("RGB", "BGR") + colormaplength, colormapentry = len(palette) // 3, 24 + else: + colormaplength, colormapentry = 0, 0 + + if im.mode in ("LA", "RGBA"): + flags = 8 + else: + flags = 0 + + orientation = im.encoderinfo.get("orientation", im.info.get("orientation", -1)) + if orientation > 0: + flags = flags | 0x20 + + fp.write( + o8(id_len) + + o8(colormaptype) + + o8(imagetype) + + o16(0) # colormapfirst + + o16(colormaplength) + + o8(colormapentry) + + o16(0) + + o16(0) + + o16(im.size[0]) + + o16(im.size[1]) + + o8(bits) + + o8(flags) + ) + + if id_section: + fp.write(id_section) + + if colormaptype: + fp.write(palette) + + if rle: + ImageFile._save( + im, fp, [("tga_rle", (0, 0) + im.size, 0, (rawmode, orientation))] + ) + else: + ImageFile._save( + im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))] + ) + + # write targa version 2 footer + fp.write(b"\000" * 8 + b"TRUEVISION-XFILE." + b"\000") + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(TgaImageFile.format, TgaImageFile) +Image.register_save(TgaImageFile.format, _save) + +Image.register_extensions(TgaImageFile.format, [".tga", ".icb", ".vda", ".vst"]) + +Image.register_mime(TgaImageFile.format, "image/x-tga") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/TiffImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/TiffImagePlugin.py new file mode 100644 index 00000000..e20d4d5e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/TiffImagePlugin.py @@ -0,0 +1,2159 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF file handling +# +# TIFF is a flexible, if somewhat aged, image file format originally +# defined by Aldus. Although TIFF supports a wide variety of pixel +# layouts and compression methods, the name doesn't really stand for +# "thousands of incompatible file formats," it just feels that way. +# +# To read TIFF data from a stream, the stream must be seekable. For +# progressive decoding, make sure to use TIFF files where the tag +# directory is placed first in the file. +# +# History: +# 1995-09-01 fl Created +# 1996-05-04 fl Handle JPEGTABLES tag +# 1996-05-18 fl Fixed COLORMAP support +# 1997-01-05 fl Fixed PREDICTOR support +# 1997-08-27 fl Added support for rational tags (from Perry Stoll) +# 1998-01-10 fl Fixed seek/tell (from Jan Blom) +# 1998-07-15 fl Use private names for internal variables +# 1999-06-13 fl Rewritten for PIL 1.0 (1.0) +# 2000-10-11 fl Additional fixes for Python 2.0 (1.1) +# 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2) +# 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3) +# 2001-12-18 fl Added workaround for broken Matrox library +# 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart) +# 2003-05-19 fl Check FILLORDER tag +# 2003-09-26 fl Added RGBa support +# 2004-02-24 fl Added DPI support; fixed rational write support +# 2005-02-07 fl Added workaround for broken Corel Draw 10 files +# 2006-01-09 fl Added support for float/double tags (from Russell Nelson) +# +# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import itertools +import logging +import math +import os +import struct +import warnings +from collections.abc import MutableMapping +from fractions import Fraction +from numbers import Number, Rational + +from . import ExifTags, Image, ImageFile, ImageOps, ImagePalette, TiffTags +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from .TiffTags import TYPES + +logger = logging.getLogger(__name__) + +# Set these to true to force use of libtiff for reading or writing. +READ_LIBTIFF = False +WRITE_LIBTIFF = False +IFD_LEGACY_API = True +STRIP_SIZE = 65536 + +II = b"II" # little-endian (Intel style) +MM = b"MM" # big-endian (Motorola style) + +# +# -------------------------------------------------------------------- +# Read TIFF files + +# a few tag names, just to make the code below a bit more readable +IMAGEWIDTH = 256 +IMAGELENGTH = 257 +BITSPERSAMPLE = 258 +COMPRESSION = 259 +PHOTOMETRIC_INTERPRETATION = 262 +FILLORDER = 266 +IMAGEDESCRIPTION = 270 +STRIPOFFSETS = 273 +SAMPLESPERPIXEL = 277 +ROWSPERSTRIP = 278 +STRIPBYTECOUNTS = 279 +X_RESOLUTION = 282 +Y_RESOLUTION = 283 +PLANAR_CONFIGURATION = 284 +RESOLUTION_UNIT = 296 +TRANSFERFUNCTION = 301 +SOFTWARE = 305 +DATE_TIME = 306 +ARTIST = 315 +PREDICTOR = 317 +COLORMAP = 320 +TILEWIDTH = 322 +TILELENGTH = 323 +TILEOFFSETS = 324 +TILEBYTECOUNTS = 325 +SUBIFD = 330 +EXTRASAMPLES = 338 +SAMPLEFORMAT = 339 +JPEGTABLES = 347 +YCBCRSUBSAMPLING = 530 +REFERENCEBLACKWHITE = 532 +COPYRIGHT = 33432 +IPTC_NAA_CHUNK = 33723 # newsphoto properties +PHOTOSHOP_CHUNK = 34377 # photoshop properties +ICCPROFILE = 34675 +EXIFIFD = 34665 +XMP = 700 +JPEGQUALITY = 65537 # pseudo-tag by libtiff + +# https://github.com/imagej/ImageJA/blob/master/src/main/java/ij/io/TiffDecoder.java +IMAGEJ_META_DATA_BYTE_COUNTS = 50838 +IMAGEJ_META_DATA = 50839 + +COMPRESSION_INFO = { + # Compression => pil compression name + 1: "raw", + 2: "tiff_ccitt", + 3: "group3", + 4: "group4", + 5: "tiff_lzw", + 6: "tiff_jpeg", # obsolete + 7: "jpeg", + 8: "tiff_adobe_deflate", + 32771: "tiff_raw_16", # 16-bit padding + 32773: "packbits", + 32809: "tiff_thunderscan", + 32946: "tiff_deflate", + 34676: "tiff_sgilog", + 34677: "tiff_sgilog24", + 34925: "lzma", + 50000: "zstd", + 50001: "webp", +} + +COMPRESSION_INFO_REV = {v: k for k, v in COMPRESSION_INFO.items()} + +OPEN_INFO = { + # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample, + # ExtraSamples) => mode, rawmode + (II, 0, (1,), 1, (1,), ()): ("1", "1;I"), + (MM, 0, (1,), 1, (1,), ()): ("1", "1;I"), + (II, 0, (1,), 2, (1,), ()): ("1", "1;IR"), + (MM, 0, (1,), 2, (1,), ()): ("1", "1;IR"), + (II, 1, (1,), 1, (1,), ()): ("1", "1"), + (MM, 1, (1,), 1, (1,), ()): ("1", "1"), + (II, 1, (1,), 2, (1,), ()): ("1", "1;R"), + (MM, 1, (1,), 2, (1,), ()): ("1", "1;R"), + (II, 0, (1,), 1, (2,), ()): ("L", "L;2I"), + (MM, 0, (1,), 1, (2,), ()): ("L", "L;2I"), + (II, 0, (1,), 2, (2,), ()): ("L", "L;2IR"), + (MM, 0, (1,), 2, (2,), ()): ("L", "L;2IR"), + (II, 1, (1,), 1, (2,), ()): ("L", "L;2"), + (MM, 1, (1,), 1, (2,), ()): ("L", "L;2"), + (II, 1, (1,), 2, (2,), ()): ("L", "L;2R"), + (MM, 1, (1,), 2, (2,), ()): ("L", "L;2R"), + (II, 0, (1,), 1, (4,), ()): ("L", "L;4I"), + (MM, 0, (1,), 1, (4,), ()): ("L", "L;4I"), + (II, 0, (1,), 2, (4,), ()): ("L", "L;4IR"), + (MM, 0, (1,), 2, (4,), ()): ("L", "L;4IR"), + (II, 1, (1,), 1, (4,), ()): ("L", "L;4"), + (MM, 1, (1,), 1, (4,), ()): ("L", "L;4"), + (II, 1, (1,), 2, (4,), ()): ("L", "L;4R"), + (MM, 1, (1,), 2, (4,), ()): ("L", "L;4R"), + (II, 0, (1,), 1, (8,), ()): ("L", "L;I"), + (MM, 0, (1,), 1, (8,), ()): ("L", "L;I"), + (II, 0, (1,), 2, (8,), ()): ("L", "L;IR"), + (MM, 0, (1,), 2, (8,), ()): ("L", "L;IR"), + (II, 1, (1,), 1, (8,), ()): ("L", "L"), + (MM, 1, (1,), 1, (8,), ()): ("L", "L"), + (II, 1, (2,), 1, (8,), ()): ("L", "L"), + (MM, 1, (2,), 1, (8,), ()): ("L", "L"), + (II, 1, (1,), 2, (8,), ()): ("L", "L;R"), + (MM, 1, (1,), 2, (8,), ()): ("L", "L;R"), + (II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"), + (II, 0, (1,), 1, (16,), ()): ("I;16", "I;16"), + (II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"), + (MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"), + (II, 1, (1,), 2, (16,), ()): ("I;16", "I;16R"), + (II, 1, (2,), 1, (16,), ()): ("I", "I;16S"), + (MM, 1, (2,), 1, (16,), ()): ("I", "I;16BS"), + (II, 0, (3,), 1, (32,), ()): ("F", "F;32F"), + (MM, 0, (3,), 1, (32,), ()): ("F", "F;32BF"), + (II, 1, (1,), 1, (32,), ()): ("I", "I;32N"), + (II, 1, (2,), 1, (32,), ()): ("I", "I;32S"), + (MM, 1, (2,), 1, (32,), ()): ("I", "I;32BS"), + (II, 1, (3,), 1, (32,), ()): ("F", "F;32F"), + (MM, 1, (3,), 1, (32,), ()): ("F", "F;32BF"), + (II, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"), + (MM, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"), + (II, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"), + (MM, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"), + (II, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"), + (MM, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"), + (II, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples + (MM, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples + (II, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGBX", "RGBXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGBX", "RGBXX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGBX", "RGBXXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGBX", "RGBXXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (MM, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (II, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16L"), + (MM, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGBX", "RGBX;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGBX", "RGBX;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16B"), + (II, 3, (1,), 1, (1,), ()): ("P", "P;1"), + (MM, 3, (1,), 1, (1,), ()): ("P", "P;1"), + (II, 3, (1,), 2, (1,), ()): ("P", "P;1R"), + (MM, 3, (1,), 2, (1,), ()): ("P", "P;1R"), + (II, 3, (1,), 1, (2,), ()): ("P", "P;2"), + (MM, 3, (1,), 1, (2,), ()): ("P", "P;2"), + (II, 3, (1,), 2, (2,), ()): ("P", "P;2R"), + (MM, 3, (1,), 2, (2,), ()): ("P", "P;2R"), + (II, 3, (1,), 1, (4,), ()): ("P", "P;4"), + (MM, 3, (1,), 1, (4,), ()): ("P", "P;4"), + (II, 3, (1,), 2, (4,), ()): ("P", "P;4R"), + (MM, 3, (1,), 2, (4,), ()): ("P", "P;4R"), + (II, 3, (1,), 1, (8,), ()): ("P", "P"), + (MM, 3, (1,), 1, (8,), ()): ("P", "P"), + (II, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"), + (MM, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"), + (II, 3, (1,), 2, (8,), ()): ("P", "P;R"), + (MM, 3, (1,), 2, (8,), ()): ("P", "P;R"), + (II, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), + (MM, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), + (II, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"), + (MM, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"), + (II, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"), + (MM, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"), + (II, 5, (1,), 1, (16, 16, 16, 16), ()): ("CMYK", "CMYK;16L"), + (II, 6, (1,), 1, (8,), ()): ("L", "L"), + (MM, 6, (1,), 1, (8,), ()): ("L", "L"), + # JPEG compressed images handled by LibTiff and auto-converted to RGBX + # Minimal Baseline TIFF requires YCbCr images to have 3 SamplesPerPixel + (II, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"), + (MM, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"), + (II, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"), + (MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"), +} + +MAX_SAMPLESPERPIXEL = max(len(key_tp[4]) for key_tp in OPEN_INFO) + +PREFIXES = [ + b"MM\x00\x2A", # Valid TIFF header with big-endian byte order + b"II\x2A\x00", # Valid TIFF header with little-endian byte order + b"MM\x2A\x00", # Invalid TIFF header, assume big-endian + b"II\x00\x2A", # Invalid TIFF header, assume little-endian + b"MM\x00\x2B", # BigTIFF with big-endian byte order + b"II\x2B\x00", # BigTIFF with little-endian byte order +] + + +def _accept(prefix): + return prefix[:4] in PREFIXES + + +def _limit_rational(val, max_val): + inv = abs(val) > 1 + n_d = IFDRational(1 / val if inv else val).limit_rational(max_val) + return n_d[::-1] if inv else n_d + + +def _limit_signed_rational(val, max_val, min_val): + frac = Fraction(val) + n_d = frac.numerator, frac.denominator + + if min(n_d) < min_val: + n_d = _limit_rational(val, abs(min_val)) + + if max(n_d) > max_val: + val = Fraction(*n_d) + n_d = _limit_rational(val, max_val) + + return n_d + + +## +# Wrapper for TIFF IFDs. + +_load_dispatch = {} +_write_dispatch = {} + + +class IFDRational(Rational): + """Implements a rational class where 0/0 is a legal value to match + the in the wild use of exif rationals. + + e.g., DigitalZoomRatio - 0.00/0.00 indicates that no digital zoom was used + """ + + """ If the denominator is 0, store this as a float('nan'), otherwise store + as a fractions.Fraction(). Delegate as appropriate + + """ + + __slots__ = ("_numerator", "_denominator", "_val") + + def __init__(self, value, denominator=1): + """ + :param value: either an integer numerator, a + float/rational/other number, or an IFDRational + :param denominator: Optional integer denominator + """ + if isinstance(value, IFDRational): + self._numerator = value.numerator + self._denominator = value.denominator + self._val = value._val + return + + if isinstance(value, Fraction): + self._numerator = value.numerator + self._denominator = value.denominator + else: + self._numerator = value + self._denominator = denominator + + if denominator == 0: + self._val = float("nan") + elif denominator == 1: + self._val = Fraction(value) + else: + self._val = Fraction(value, denominator) + + @property + def numerator(self): + return self._numerator + + @property + def denominator(self): + return self._denominator + + def limit_rational(self, max_denominator): + """ + + :param max_denominator: Integer, the maximum denominator value + :returns: Tuple of (numerator, denominator) + """ + + if self.denominator == 0: + return self.numerator, self.denominator + + f = self._val.limit_denominator(max_denominator) + return f.numerator, f.denominator + + def __repr__(self): + return str(float(self._val)) + + def __hash__(self): + return self._val.__hash__() + + def __eq__(self, other): + val = self._val + if isinstance(other, IFDRational): + other = other._val + if isinstance(other, float): + val = float(val) + return val == other + + def __getstate__(self): + return [self._val, self._numerator, self._denominator] + + def __setstate__(self, state): + IFDRational.__init__(self, 0) + _val, _numerator, _denominator = state + self._val = _val + self._numerator = _numerator + self._denominator = _denominator + + def _delegate(op): + def delegate(self, *args): + return getattr(self._val, op)(*args) + + return delegate + + """ a = ['add','radd', 'sub', 'rsub', 'mul', 'rmul', + 'truediv', 'rtruediv', 'floordiv', 'rfloordiv', + 'mod','rmod', 'pow','rpow', 'pos', 'neg', + 'abs', 'trunc', 'lt', 'gt', 'le', 'ge', 'bool', + 'ceil', 'floor', 'round'] + print("\n".join("__%s__ = _delegate('__%s__')" % (s,s) for s in a)) + """ + + __add__ = _delegate("__add__") + __radd__ = _delegate("__radd__") + __sub__ = _delegate("__sub__") + __rsub__ = _delegate("__rsub__") + __mul__ = _delegate("__mul__") + __rmul__ = _delegate("__rmul__") + __truediv__ = _delegate("__truediv__") + __rtruediv__ = _delegate("__rtruediv__") + __floordiv__ = _delegate("__floordiv__") + __rfloordiv__ = _delegate("__rfloordiv__") + __mod__ = _delegate("__mod__") + __rmod__ = _delegate("__rmod__") + __pow__ = _delegate("__pow__") + __rpow__ = _delegate("__rpow__") + __pos__ = _delegate("__pos__") + __neg__ = _delegate("__neg__") + __abs__ = _delegate("__abs__") + __trunc__ = _delegate("__trunc__") + __lt__ = _delegate("__lt__") + __gt__ = _delegate("__gt__") + __le__ = _delegate("__le__") + __ge__ = _delegate("__ge__") + __bool__ = _delegate("__bool__") + __ceil__ = _delegate("__ceil__") + __floor__ = _delegate("__floor__") + __round__ = _delegate("__round__") + # Python >= 3.11 + if hasattr(Fraction, "__int__"): + __int__ = _delegate("__int__") + + +class ImageFileDirectory_v2(MutableMapping): + """This class represents a TIFF tag directory. To speed things up, we + don't decode tags unless they're asked for. + + Exposes a dictionary interface of the tags in the directory:: + + ifd = ImageFileDirectory_v2() + ifd[key] = 'Some Data' + ifd.tagtype[key] = TiffTags.ASCII + print(ifd[key]) + 'Some Data' + + Individual values are returned as the strings or numbers, sequences are + returned as tuples of the values. + + The tiff metadata type of each item is stored in a dictionary of + tag types in + :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype`. The types + are read from a tiff file, guessed from the type added, or added + manually. + + Data Structures: + + * ``self.tagtype = {}`` + + * Key: numerical TIFF tag number + * Value: integer corresponding to the data type from + :py:data:`.TiffTags.TYPES` + + .. versionadded:: 3.0.0 + + 'Internal' data structures: + + * ``self._tags_v2 = {}`` + + * Key: numerical TIFF tag number + * Value: decoded data, as tuple for multiple values + + * ``self._tagdata = {}`` + + * Key: numerical TIFF tag number + * Value: undecoded byte string from file + + * ``self._tags_v1 = {}`` + + * Key: numerical TIFF tag number + * Value: decoded data in the v1 format + + Tags will be found in the private attributes ``self._tagdata``, and in + ``self._tags_v2`` once decoded. + + ``self.legacy_api`` is a value for internal use, and shouldn't be changed + from outside code. In cooperation with + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`, if ``legacy_api`` + is true, then decoded tags will be populated into both ``_tags_v1`` and + ``_tags_v2``. ``_tags_v2`` will be used if this IFD is used in the TIFF + save routine. Tags should be read from ``_tags_v1`` if + ``legacy_api == true``. + + """ + + def __init__(self, ifh=b"II\052\0\0\0\0\0", prefix=None, group=None): + """Initialize an ImageFileDirectory. + + To construct an ImageFileDirectory from a real file, pass the 8-byte + magic header to the constructor. To only set the endianness, pass it + as the 'prefix' keyword argument. + + :param ifh: One of the accepted magic headers (cf. PREFIXES); also sets + endianness. + :param prefix: Override the endianness of the file. + """ + if not _accept(ifh): + msg = f"not a TIFF file (header {repr(ifh)} not valid)" + raise SyntaxError(msg) + self._prefix = prefix if prefix is not None else ifh[:2] + if self._prefix == MM: + self._endian = ">" + elif self._prefix == II: + self._endian = "<" + else: + msg = "not a TIFF IFD" + raise SyntaxError(msg) + self._bigtiff = ifh[2] == 43 + self.group = group + self.tagtype = {} + """ Dictionary of tag types """ + self.reset() + (self.next,) = ( + self._unpack("Q", ifh[8:]) if self._bigtiff else self._unpack("L", ifh[4:]) + ) + self._legacy_api = False + + prefix = property(lambda self: self._prefix) + offset = property(lambda self: self._offset) + legacy_api = property(lambda self: self._legacy_api) + + @legacy_api.setter + def legacy_api(self, value): + msg = "Not allowing setting of legacy api" + raise Exception(msg) + + def reset(self): + self._tags_v1 = {} # will remain empty if legacy_api is false + self._tags_v2 = {} # main tag storage + self._tagdata = {} + self.tagtype = {} # added 2008-06-05 by Florian Hoech + self._next = None + self._offset = None + + def __str__(self): + return str(dict(self)) + + def named(self): + """ + :returns: dict of name|key: value + + Returns the complete tag dictionary, with named tags where possible. + """ + return { + TiffTags.lookup(code, self.group).name: value + for code, value in self.items() + } + + def __len__(self): + return len(set(self._tagdata) | set(self._tags_v2)) + + def __getitem__(self, tag): + if tag not in self._tags_v2: # unpack on the fly + data = self._tagdata[tag] + typ = self.tagtype[tag] + size, handler = self._load_dispatch[typ] + self[tag] = handler(self, data, self.legacy_api) # check type + val = self._tags_v2[tag] + if self.legacy_api and not isinstance(val, (tuple, bytes)): + val = (val,) + return val + + def __contains__(self, tag): + return tag in self._tags_v2 or tag in self._tagdata + + def __setitem__(self, tag, value): + self._setitem(tag, value, self.legacy_api) + + def _setitem(self, tag, value, legacy_api): + basetypes = (Number, bytes, str) + + info = TiffTags.lookup(tag, self.group) + values = [value] if isinstance(value, basetypes) else value + + if tag not in self.tagtype: + if info.type: + self.tagtype[tag] = info.type + else: + self.tagtype[tag] = TiffTags.UNDEFINED + if all(isinstance(v, IFDRational) for v in values): + self.tagtype[tag] = ( + TiffTags.RATIONAL + if all(v >= 0 for v in values) + else TiffTags.SIGNED_RATIONAL + ) + elif all(isinstance(v, int) for v in values): + if all(0 <= v < 2**16 for v in values): + self.tagtype[tag] = TiffTags.SHORT + elif all(-(2**15) < v < 2**15 for v in values): + self.tagtype[tag] = TiffTags.SIGNED_SHORT + else: + self.tagtype[tag] = ( + TiffTags.LONG + if all(v >= 0 for v in values) + else TiffTags.SIGNED_LONG + ) + elif all(isinstance(v, float) for v in values): + self.tagtype[tag] = TiffTags.DOUBLE + elif all(isinstance(v, str) for v in values): + self.tagtype[tag] = TiffTags.ASCII + elif all(isinstance(v, bytes) for v in values): + self.tagtype[tag] = TiffTags.BYTE + + if self.tagtype[tag] == TiffTags.UNDEFINED: + values = [ + v.encode("ascii", "replace") if isinstance(v, str) else v + for v in values + ] + elif self.tagtype[tag] == TiffTags.RATIONAL: + values = [float(v) if isinstance(v, int) else v for v in values] + + is_ifd = self.tagtype[tag] == TiffTags.LONG and isinstance(values, dict) + if not is_ifd: + values = tuple(info.cvt_enum(value) for value in values) + + dest = self._tags_v1 if legacy_api else self._tags_v2 + + # Three branches: + # Spec'd length == 1, Actual length 1, store as element + # Spec'd length == 1, Actual > 1, Warn and truncate. Formerly barfed. + # No Spec, Actual length 1, Formerly (<4.2) returned a 1 element tuple. + # Don't mess with the legacy api, since it's frozen. + if not is_ifd and ( + (info.length == 1) + or self.tagtype[tag] == TiffTags.BYTE + or (info.length is None and len(values) == 1 and not legacy_api) + ): + # Don't mess with the legacy api, since it's frozen. + if legacy_api and self.tagtype[tag] in [ + TiffTags.RATIONAL, + TiffTags.SIGNED_RATIONAL, + ]: # rationals + values = (values,) + try: + (dest[tag],) = values + except ValueError: + # We've got a builtin tag with 1 expected entry + warnings.warn( + f"Metadata Warning, tag {tag} had too many entries: " + f"{len(values)}, expected 1" + ) + dest[tag] = values[0] + + else: + # Spec'd length > 1 or undefined + # Unspec'd, and length > 1 + dest[tag] = values + + def __delitem__(self, tag): + self._tags_v2.pop(tag, None) + self._tags_v1.pop(tag, None) + self._tagdata.pop(tag, None) + + def __iter__(self): + return iter(set(self._tagdata) | set(self._tags_v2)) + + def _unpack(self, fmt, data): + return struct.unpack(self._endian + fmt, data) + + def _pack(self, fmt, *values): + return struct.pack(self._endian + fmt, *values) + + def _register_loader(idx, size): + def decorator(func): + from .TiffTags import TYPES + + if func.__name__.startswith("load_"): + TYPES[idx] = func.__name__[5:].replace("_", " ") + _load_dispatch[idx] = size, func # noqa: F821 + return func + + return decorator + + def _register_writer(idx): + def decorator(func): + _write_dispatch[idx] = func # noqa: F821 + return func + + return decorator + + def _register_basic(idx_fmt_name): + from .TiffTags import TYPES + + idx, fmt, name = idx_fmt_name + TYPES[idx] = name + size = struct.calcsize("=" + fmt) + _load_dispatch[idx] = ( # noqa: F821 + size, + lambda self, data, legacy_api=True: ( + self._unpack(f"{len(data) // size}{fmt}", data) + ), + ) + _write_dispatch[idx] = lambda self, *values: ( # noqa: F821 + b"".join(self._pack(fmt, value) for value in values) + ) + + list( + map( + _register_basic, + [ + (TiffTags.SHORT, "H", "short"), + (TiffTags.LONG, "L", "long"), + (TiffTags.SIGNED_BYTE, "b", "signed byte"), + (TiffTags.SIGNED_SHORT, "h", "signed short"), + (TiffTags.SIGNED_LONG, "l", "signed long"), + (TiffTags.FLOAT, "f", "float"), + (TiffTags.DOUBLE, "d", "double"), + (TiffTags.IFD, "L", "long"), + (TiffTags.LONG8, "Q", "long8"), + ], + ) + ) + + @_register_loader(1, 1) # Basic type, except for the legacy API. + def load_byte(self, data, legacy_api=True): + return data + + @_register_writer(1) # Basic type, except for the legacy API. + def write_byte(self, data): + if isinstance(data, IFDRational): + data = int(data) + if isinstance(data, int): + data = bytes((data,)) + return data + + @_register_loader(2, 1) + def load_string(self, data, legacy_api=True): + if data.endswith(b"\0"): + data = data[:-1] + return data.decode("latin-1", "replace") + + @_register_writer(2) + def write_string(self, value): + # remerge of https://github.com/python-pillow/Pillow/pull/1416 + if isinstance(value, int): + value = str(value) + if not isinstance(value, bytes): + value = value.encode("ascii", "replace") + return value + b"\0" + + @_register_loader(5, 8) + def load_rational(self, data, legacy_api=True): + vals = self._unpack(f"{len(data) // 4}L", data) + + def combine(a, b): + return (a, b) if legacy_api else IFDRational(a, b) + + return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) + + @_register_writer(5) + def write_rational(self, *values): + return b"".join( + self._pack("2L", *_limit_rational(frac, 2**32 - 1)) for frac in values + ) + + @_register_loader(7, 1) + def load_undefined(self, data, legacy_api=True): + return data + + @_register_writer(7) + def write_undefined(self, value): + if isinstance(value, int): + value = str(value).encode("ascii", "replace") + return value + + @_register_loader(10, 8) + def load_signed_rational(self, data, legacy_api=True): + vals = self._unpack(f"{len(data) // 4}l", data) + + def combine(a, b): + return (a, b) if legacy_api else IFDRational(a, b) + + return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) + + @_register_writer(10) + def write_signed_rational(self, *values): + return b"".join( + self._pack("2l", *_limit_signed_rational(frac, 2**31 - 1, -(2**31))) + for frac in values + ) + + def _ensure_read(self, fp, size): + ret = fp.read(size) + if len(ret) != size: + msg = ( + "Corrupt EXIF data. " + f"Expecting to read {size} bytes but only got {len(ret)}. " + ) + raise OSError(msg) + return ret + + def load(self, fp): + self.reset() + self._offset = fp.tell() + + try: + tag_count = ( + self._unpack("Q", self._ensure_read(fp, 8)) + if self._bigtiff + else self._unpack("H", self._ensure_read(fp, 2)) + )[0] + for i in range(tag_count): + tag, typ, count, data = ( + self._unpack("HHQ8s", self._ensure_read(fp, 20)) + if self._bigtiff + else self._unpack("HHL4s", self._ensure_read(fp, 12)) + ) + + tagname = TiffTags.lookup(tag, self.group).name + typname = TYPES.get(typ, "unknown") + msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})" + + try: + unit_size, handler = self._load_dispatch[typ] + except KeyError: + logger.debug("%s - unsupported type %s", msg, typ) + continue # ignore unsupported type + size = count * unit_size + if size > (8 if self._bigtiff else 4): + here = fp.tell() + (offset,) = self._unpack("Q" if self._bigtiff else "L", data) + msg += f" Tag Location: {here} - Data Location: {offset}" + fp.seek(offset) + data = ImageFile._safe_read(fp, size) + fp.seek(here) + else: + data = data[:size] + + if len(data) != size: + warnings.warn( + "Possibly corrupt EXIF data. " + f"Expecting to read {size} bytes but only got {len(data)}." + f" Skipping tag {tag}" + ) + logger.debug(msg) + continue + + if not data: + logger.debug(msg) + continue + + self._tagdata[tag] = data + self.tagtype[tag] = typ + + msg += " - value: " + ( + "" % size if size > 32 else repr(data) + ) + logger.debug(msg) + + (self.next,) = ( + self._unpack("Q", self._ensure_read(fp, 8)) + if self._bigtiff + else self._unpack("L", self._ensure_read(fp, 4)) + ) + except OSError as msg: + warnings.warn(str(msg)) + return + + def tobytes(self, offset=0): + # FIXME What about tagdata? + result = self._pack("H", len(self._tags_v2)) + + entries = [] + offset = offset + len(result) + len(self._tags_v2) * 12 + 4 + stripoffsets = None + + # pass 1: convert tags to binary format + # always write tags in ascending order + for tag, value in sorted(self._tags_v2.items()): + if tag == STRIPOFFSETS: + stripoffsets = len(entries) + typ = self.tagtype.get(tag) + logger.debug("Tag %s, Type: %s, Value: %s", tag, typ, repr(value)) + is_ifd = typ == TiffTags.LONG and isinstance(value, dict) + if is_ifd: + if self._endian == "<": + ifh = b"II\x2A\x00\x08\x00\x00\x00" + else: + ifh = b"MM\x00\x2A\x00\x00\x00\x08" + ifd = ImageFileDirectory_v2(ifh, group=tag) + values = self._tags_v2[tag] + for ifd_tag, ifd_value in values.items(): + ifd[ifd_tag] = ifd_value + data = ifd.tobytes(offset) + else: + values = value if isinstance(value, tuple) else (value,) + data = self._write_dispatch[typ](self, *values) + + tagname = TiffTags.lookup(tag, self.group).name + typname = "ifd" if is_ifd else TYPES.get(typ, "unknown") + msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})" + msg += " - value: " + ( + "" % len(data) if len(data) >= 16 else str(values) + ) + logger.debug(msg) + + # count is sum of lengths for string and arbitrary data + if is_ifd: + count = 1 + elif typ in [TiffTags.BYTE, TiffTags.ASCII, TiffTags.UNDEFINED]: + count = len(data) + else: + count = len(values) + # figure out if data fits into the entry + if len(data) <= 4: + entries.append((tag, typ, count, data.ljust(4, b"\0"), b"")) + else: + entries.append((tag, typ, count, self._pack("L", offset), data)) + offset += (len(data) + 1) // 2 * 2 # pad to word + + # update strip offset data to point beyond auxiliary data + if stripoffsets is not None: + tag, typ, count, value, data = entries[stripoffsets] + if data: + msg = "multistrip support not yet implemented" + raise NotImplementedError(msg) + value = self._pack("L", self._unpack("L", value)[0] + offset) + entries[stripoffsets] = tag, typ, count, value, data + + # pass 2: write entries to file + for tag, typ, count, value, data in entries: + logger.debug("%s %s %s %s %s", tag, typ, count, repr(value), repr(data)) + result += self._pack("HHL4s", tag, typ, count, value) + + # -- overwrite here for multi-page -- + result += b"\0\0\0\0" # end of entries + + # pass 3: write auxiliary data to file + for tag, typ, count, value, data in entries: + result += data + if len(data) & 1: + result += b"\0" + + return result + + def save(self, fp): + if fp.tell() == 0: # skip TIFF header on subsequent pages + # tiff header -- PIL always starts the first IFD at offset 8 + fp.write(self._prefix + self._pack("HL", 42, 8)) + + offset = fp.tell() + result = self.tobytes(offset) + fp.write(result) + return offset + len(result) + + +ImageFileDirectory_v2._load_dispatch = _load_dispatch +ImageFileDirectory_v2._write_dispatch = _write_dispatch +for idx, name in TYPES.items(): + name = name.replace(" ", "_") + setattr(ImageFileDirectory_v2, "load_" + name, _load_dispatch[idx][1]) + setattr(ImageFileDirectory_v2, "write_" + name, _write_dispatch[idx]) +del _load_dispatch, _write_dispatch, idx, name + + +# Legacy ImageFileDirectory support. +class ImageFileDirectory_v1(ImageFileDirectory_v2): + """This class represents the **legacy** interface to a TIFF tag directory. + + Exposes a dictionary interface of the tags in the directory:: + + ifd = ImageFileDirectory_v1() + ifd[key] = 'Some Data' + ifd.tagtype[key] = TiffTags.ASCII + print(ifd[key]) + ('Some Data',) + + Also contains a dictionary of tag types as read from the tiff image file, + :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v1.tagtype`. + + Values are returned as a tuple. + + .. deprecated:: 3.0.0 + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._legacy_api = True + + tags = property(lambda self: self._tags_v1) + tagdata = property(lambda self: self._tagdata) + + # defined in ImageFileDirectory_v2 + tagtype: dict + """Dictionary of tag types""" + + @classmethod + def from_v2(cls, original): + """Returns an + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + instance with the same data as is contained in the original + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + instance. + + :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + + """ + + ifd = cls(prefix=original.prefix) + ifd._tagdata = original._tagdata + ifd.tagtype = original.tagtype + ifd.next = original.next # an indicator for multipage tiffs + return ifd + + def to_v2(self): + """Returns an + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + instance with the same data as is contained in the original + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + instance. + + :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + + """ + + ifd = ImageFileDirectory_v2(prefix=self.prefix) + ifd._tagdata = dict(self._tagdata) + ifd.tagtype = dict(self.tagtype) + ifd._tags_v2 = dict(self._tags_v2) + return ifd + + def __contains__(self, tag): + return tag in self._tags_v1 or tag in self._tagdata + + def __len__(self): + return len(set(self._tagdata) | set(self._tags_v1)) + + def __iter__(self): + return iter(set(self._tagdata) | set(self._tags_v1)) + + def __setitem__(self, tag, value): + for legacy_api in (False, True): + self._setitem(tag, value, legacy_api) + + def __getitem__(self, tag): + if tag not in self._tags_v1: # unpack on the fly + data = self._tagdata[tag] + typ = self.tagtype[tag] + size, handler = self._load_dispatch[typ] + for legacy in (False, True): + self._setitem(tag, handler(self, data, legacy), legacy) + val = self._tags_v1[tag] + if not isinstance(val, (tuple, bytes)): + val = (val,) + return val + + +# undone -- switch this pointer when IFD_LEGACY_API == False +ImageFileDirectory = ImageFileDirectory_v1 + + +## +# Image plugin for TIFF files. + + +class TiffImageFile(ImageFile.ImageFile): + format = "TIFF" + format_description = "Adobe TIFF" + _close_exclusive_fp_after_loading = False + + def __init__(self, fp=None, filename=None): + self.tag_v2 = None + """ Image file directory (tag dictionary) """ + + self.tag = None + """ Legacy tag entries """ + + super().__init__(fp, filename) + + def _open(self): + """Open the first image in a TIFF file""" + + # Header + ifh = self.fp.read(8) + if ifh[2] == 43: + ifh += self.fp.read(8) + + self.tag_v2 = ImageFileDirectory_v2(ifh) + + # legacy IFD entries will be filled in later + self.ifd = None + + # setup frame pointers + self.__first = self.__next = self.tag_v2.next + self.__frame = -1 + self._fp = self.fp + self._frame_pos = [] + self._n_frames = None + + logger.debug("*** TiffImageFile._open ***") + logger.debug("- __first: %s", self.__first) + logger.debug("- ifh: %s", repr(ifh)) # Use repr to avoid str(bytes) + + # and load the first frame + self._seek(0) + + @property + def n_frames(self): + if self._n_frames is None: + current = self.tell() + self._seek(len(self._frame_pos)) + while self._n_frames is None: + self._seek(self.tell() + 1) + self.seek(current) + return self._n_frames + + def seek(self, frame): + """Select a given frame as current image""" + if not self._seek_check(frame): + return + self._seek(frame) + # Create a new core image object on second and + # subsequent frames in the image. Image may be + # different size/mode. + Image._decompression_bomb_check(self.size) + self.im = Image.core.new(self.mode, self.size) + + def _seek(self, frame): + self.fp = self._fp + + # reset buffered io handle in case fp + # was passed to libtiff, invalidating the buffer + self.fp.tell() + + while len(self._frame_pos) <= frame: + if not self.__next: + msg = "no more images in TIFF file" + raise EOFError(msg) + logger.debug( + "Seeking to frame %s, on frame %s, __next %s, location: %s", + frame, + self.__frame, + self.__next, + self.fp.tell(), + ) + self.fp.seek(self.__next) + self._frame_pos.append(self.__next) + logger.debug("Loading tags, location: %s", self.fp.tell()) + self.tag_v2.load(self.fp) + if self.tag_v2.next in self._frame_pos: + # This IFD has already been processed + # Declare this to be the end of the image + self.__next = 0 + else: + self.__next = self.tag_v2.next + if self.__next == 0: + self._n_frames = frame + 1 + if len(self._frame_pos) == 1: + self.is_animated = self.__next != 0 + self.__frame += 1 + self.fp.seek(self._frame_pos[frame]) + self.tag_v2.load(self.fp) + self._reload_exif() + # fill the legacy tag/ifd entries + self.tag = self.ifd = ImageFileDirectory_v1.from_v2(self.tag_v2) + self.__frame = frame + self._setup() + + def tell(self): + """Return the current frame number""" + return self.__frame + + def getxmp(self): + """ + Returns a dictionary containing the XMP tags. + Requires defusedxml to be installed. + + :returns: XMP tags in a dictionary. + """ + return self._getxmp(self.tag_v2[XMP]) if XMP in self.tag_v2 else {} + + def get_photoshop_blocks(self): + """ + Returns a dictionary of Photoshop "Image Resource Blocks". + The keys are the image resource ID. For more information, see + https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037727 + + :returns: Photoshop "Image Resource Blocks" in a dictionary. + """ + blocks = {} + val = self.tag_v2.get(ExifTags.Base.ImageResources) + if val: + while val[:4] == b"8BIM": + id = i16(val[4:6]) + n = math.ceil((val[6] + 1) / 2) * 2 + size = i32(val[6 + n : 10 + n]) + data = val[10 + n : 10 + n + size] + blocks[id] = {"data": data} + + val = val[math.ceil((10 + n + size) / 2) * 2 :] + return blocks + + def load(self): + if self.tile and self.use_load_libtiff: + return self._load_libtiff() + return super().load() + + def load_end(self): + # allow closing if we're on the first frame, there's no next + # This is the ImageFile.load path only, libtiff specific below. + if not self.is_animated: + self._close_exclusive_fp_after_loading = True + + # reset buffered io handle in case fp + # was passed to libtiff, invalidating the buffer + self.fp.tell() + + # load IFD data from fp before it is closed + exif = self.getexif() + for key in TiffTags.TAGS_V2_GROUPS: + if key not in exif: + continue + exif.get_ifd(key) + + ImageOps.exif_transpose(self, in_place=True) + if ExifTags.Base.Orientation in self.tag_v2: + del self.tag_v2[ExifTags.Base.Orientation] + + def _load_libtiff(self): + """Overload method triggered when we detect a compressed tiff + Calls out to libtiff""" + + Image.Image.load(self) + + self.load_prepare() + + if not len(self.tile) == 1: + msg = "Not exactly one tile" + raise OSError(msg) + + # (self._compression, (extents tuple), + # 0, (rawmode, self._compression, fp)) + extents = self.tile[0][1] + args = list(self.tile[0][3]) + + # To be nice on memory footprint, if there's a + # file descriptor, use that instead of reading + # into a string in python. + try: + fp = hasattr(self.fp, "fileno") and self.fp.fileno() + # flush the file descriptor, prevents error on pypy 2.4+ + # should also eliminate the need for fp.tell + # in _seek + if hasattr(self.fp, "flush"): + self.fp.flush() + except OSError: + # io.BytesIO have a fileno, but returns an OSError if + # it doesn't use a file descriptor. + fp = False + + if fp: + args[2] = fp + + decoder = Image._getdecoder( + self.mode, "libtiff", tuple(args), self.decoderconfig + ) + try: + decoder.setimage(self.im, extents) + except ValueError as e: + msg = "Couldn't set the image" + raise OSError(msg) from e + + close_self_fp = self._exclusive_fp and not self.is_animated + if hasattr(self.fp, "getvalue"): + # We've got a stringio like thing passed in. Yay for all in memory. + # The decoder needs the entire file in one shot, so there's not + # a lot we can do here other than give it the entire file. + # unless we could do something like get the address of the + # underlying string for stringio. + # + # Rearranging for supporting byteio items, since they have a fileno + # that returns an OSError if there's no underlying fp. Easier to + # deal with here by reordering. + logger.debug("have getvalue. just sending in a string from getvalue") + n, err = decoder.decode(self.fp.getvalue()) + elif fp: + # we've got a actual file on disk, pass in the fp. + logger.debug("have fileno, calling fileno version of the decoder.") + if not close_self_fp: + self.fp.seek(0) + # 4 bytes, otherwise the trace might error out + n, err = decoder.decode(b"fpfp") + else: + # we have something else. + logger.debug("don't have fileno or getvalue. just reading") + self.fp.seek(0) + # UNDONE -- so much for that buffer size thing. + n, err = decoder.decode(self.fp.read()) + + self.tile = [] + self.readonly = 0 + + self.load_end() + + if close_self_fp: + self.fp.close() + self.fp = None # might be shared + + if err < 0: + raise OSError(err) + + return Image.Image.load(self) + + def _setup(self): + """Setup this image object based on current tags""" + + if 0xBC01 in self.tag_v2: + msg = "Windows Media Photo files not yet supported" + raise OSError(msg) + + # extract relevant tags + self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)] + self._planar_configuration = self.tag_v2.get(PLANAR_CONFIGURATION, 1) + + # photometric is a required tag, but not everyone is reading + # the specification + photo = self.tag_v2.get(PHOTOMETRIC_INTERPRETATION, 0) + + # old style jpeg compression images most certainly are YCbCr + if self._compression == "tiff_jpeg": + photo = 6 + + fillorder = self.tag_v2.get(FILLORDER, 1) + + logger.debug("*** Summary ***") + logger.debug("- compression: %s", self._compression) + logger.debug("- photometric_interpretation: %s", photo) + logger.debug("- planar_configuration: %s", self._planar_configuration) + logger.debug("- fill_order: %s", fillorder) + logger.debug("- YCbCr subsampling: %s", self.tag.get(YCBCRSUBSAMPLING)) + + # size + xsize = int(self.tag_v2.get(IMAGEWIDTH)) + ysize = int(self.tag_v2.get(IMAGELENGTH)) + self._size = xsize, ysize + + logger.debug("- size: %s", self.size) + + sample_format = self.tag_v2.get(SAMPLEFORMAT, (1,)) + if len(sample_format) > 1 and max(sample_format) == min(sample_format) == 1: + # SAMPLEFORMAT is properly per band, so an RGB image will + # be (1,1,1). But, we don't support per band pixel types, + # and anything more than one band is a uint8. So, just + # take the first element. Revisit this if adding support + # for more exotic images. + sample_format = (1,) + + bps_tuple = self.tag_v2.get(BITSPERSAMPLE, (1,)) + extra_tuple = self.tag_v2.get(EXTRASAMPLES, ()) + if photo in (2, 6, 8): # RGB, YCbCr, LAB + bps_count = 3 + elif photo == 5: # CMYK + bps_count = 4 + else: + bps_count = 1 + bps_count += len(extra_tuple) + bps_actual_count = len(bps_tuple) + samples_per_pixel = self.tag_v2.get( + SAMPLESPERPIXEL, + 3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1, + ) + + if samples_per_pixel > MAX_SAMPLESPERPIXEL: + # DOS check, samples_per_pixel can be a Long, and we extend the tuple below + logger.error( + "More samples per pixel than can be decoded: %s", samples_per_pixel + ) + msg = "Invalid value for samples per pixel" + raise SyntaxError(msg) + + if samples_per_pixel < bps_actual_count: + # If a file has more values in bps_tuple than expected, + # remove the excess. + bps_tuple = bps_tuple[:samples_per_pixel] + elif samples_per_pixel > bps_actual_count and bps_actual_count == 1: + # If a file has only one value in bps_tuple, when it should have more, + # presume it is the same number of bits for all of the samples. + bps_tuple = bps_tuple * samples_per_pixel + + if len(bps_tuple) != samples_per_pixel: + msg = "unknown data organization" + raise SyntaxError(msg) + + # mode: check photometric interpretation and bits per pixel + key = ( + self.tag_v2.prefix, + photo, + sample_format, + fillorder, + bps_tuple, + extra_tuple, + ) + logger.debug("format key: %s", key) + try: + self._mode, rawmode = OPEN_INFO[key] + except KeyError as e: + logger.debug("- unsupported format") + msg = "unknown pixel mode" + raise SyntaxError(msg) from e + + logger.debug("- raw mode: %s", rawmode) + logger.debug("- pil mode: %s", self.mode) + + self.info["compression"] = self._compression + + xres = self.tag_v2.get(X_RESOLUTION, 1) + yres = self.tag_v2.get(Y_RESOLUTION, 1) + + if xres and yres: + resunit = self.tag_v2.get(RESOLUTION_UNIT) + if resunit == 2: # dots per inch + self.info["dpi"] = (xres, yres) + elif resunit == 3: # dots per centimeter. convert to dpi + self.info["dpi"] = (xres * 2.54, yres * 2.54) + elif resunit is None: # used to default to 1, but now 2) + self.info["dpi"] = (xres, yres) + # For backward compatibility, + # we also preserve the old behavior + self.info["resolution"] = xres, yres + else: # No absolute unit of measurement + self.info["resolution"] = xres, yres + + # build tile descriptors + x = y = layer = 0 + self.tile = [] + self.use_load_libtiff = READ_LIBTIFF or self._compression != "raw" + if self.use_load_libtiff: + # Decoder expects entire file as one tile. + # There's a buffer size limit in load (64k) + # so large g4 images will fail if we use that + # function. + # + # Setup the one tile for the whole image, then + # use the _load_libtiff function. + + # libtiff handles the fillmode for us, so 1;IR should + # actually be 1;I. Including the R double reverses the + # bits, so stripes of the image are reversed. See + # https://github.com/python-pillow/Pillow/issues/279 + if fillorder == 2: + # Replace fillorder with fillorder=1 + key = key[:3] + (1,) + key[4:] + logger.debug("format key: %s", key) + # this should always work, since all the + # fillorder==2 modes have a corresponding + # fillorder=1 mode + self._mode, rawmode = OPEN_INFO[key] + # libtiff always returns the bytes in native order. + # we're expecting image byte order. So, if the rawmode + # contains I;16, we need to convert from native to image + # byte order. + if rawmode == "I;16": + rawmode = "I;16N" + if ";16B" in rawmode: + rawmode = rawmode.replace(";16B", ";16N") + if ";16L" in rawmode: + rawmode = rawmode.replace(";16L", ";16N") + + # YCbCr images with new jpeg compression with pixels in one plane + # unpacked straight into RGB values + if ( + photo == 6 + and self._compression == "jpeg" + and self._planar_configuration == 1 + ): + rawmode = "RGB" + + # Offset in the tile tuple is 0, we go from 0,0 to + # w,h, and we only do this once -- eds + a = (rawmode, self._compression, False, self.tag_v2.offset) + self.tile.append(("libtiff", (0, 0, xsize, ysize), 0, a)) + + elif STRIPOFFSETS in self.tag_v2 or TILEOFFSETS in self.tag_v2: + # striped image + if STRIPOFFSETS in self.tag_v2: + offsets = self.tag_v2[STRIPOFFSETS] + h = self.tag_v2.get(ROWSPERSTRIP, ysize) + w = self.size[0] + else: + # tiled image + offsets = self.tag_v2[TILEOFFSETS] + w = self.tag_v2.get(TILEWIDTH) + h = self.tag_v2.get(TILELENGTH) + + for offset in offsets: + if x + w > xsize: + stride = w * sum(bps_tuple) / 8 # bytes per line + else: + stride = 0 + + tile_rawmode = rawmode + if self._planar_configuration == 2: + # each band on it's own layer + tile_rawmode = rawmode[layer] + # adjust stride width accordingly + stride /= bps_count + + a = (tile_rawmode, int(stride), 1) + self.tile.append( + ( + self._compression, + (x, y, min(x + w, xsize), min(y + h, ysize)), + offset, + a, + ) + ) + x = x + w + if x >= self.size[0]: + x, y = 0, y + h + if y >= self.size[1]: + x = y = 0 + layer += 1 + else: + logger.debug("- unsupported data organization") + msg = "unknown data organization" + raise SyntaxError(msg) + + # Fix up info. + if ICCPROFILE in self.tag_v2: + self.info["icc_profile"] = self.tag_v2[ICCPROFILE] + + # fixup palette descriptor + + if self.mode in ["P", "PA"]: + palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]] + self.palette = ImagePalette.raw("RGB;L", b"".join(palette)) + + +# +# -------------------------------------------------------------------- +# Write TIFF files + +# little endian is default except for image modes with +# explicit big endian byte-order + +SAVE_INFO = { + # mode => rawmode, byteorder, photometrics, + # sampleformat, bitspersample, extra + "1": ("1", II, 1, 1, (1,), None), + "L": ("L", II, 1, 1, (8,), None), + "LA": ("LA", II, 1, 1, (8, 8), 2), + "P": ("P", II, 3, 1, (8,), None), + "PA": ("PA", II, 3, 1, (8, 8), 2), + "I": ("I;32S", II, 1, 2, (32,), None), + "I;16": ("I;16", II, 1, 1, (16,), None), + "I;16S": ("I;16S", II, 1, 2, (16,), None), + "F": ("F;32F", II, 1, 3, (32,), None), + "RGB": ("RGB", II, 2, 1, (8, 8, 8), None), + "RGBX": ("RGBX", II, 2, 1, (8, 8, 8, 8), 0), + "RGBA": ("RGBA", II, 2, 1, (8, 8, 8, 8), 2), + "CMYK": ("CMYK", II, 5, 1, (8, 8, 8, 8), None), + "YCbCr": ("YCbCr", II, 6, 1, (8, 8, 8), None), + "LAB": ("LAB", II, 8, 1, (8, 8, 8), None), + "I;32BS": ("I;32BS", MM, 1, 2, (32,), None), + "I;16B": ("I;16B", MM, 1, 1, (16,), None), + "I;16BS": ("I;16BS", MM, 1, 2, (16,), None), + "F;32BF": ("F;32BF", MM, 1, 3, (32,), None), +} + + +def _save(im, fp, filename): + try: + rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as TIFF" + raise OSError(msg) from e + + ifd = ImageFileDirectory_v2(prefix=prefix) + + encoderinfo = im.encoderinfo + encoderconfig = im.encoderconfig + try: + compression = encoderinfo["compression"] + except KeyError: + compression = im.info.get("compression") + if isinstance(compression, int): + # compression value may be from BMP. Ignore it + compression = None + if compression is None: + compression = "raw" + elif compression == "tiff_jpeg": + # OJPEG is obsolete, so use new-style JPEG compression instead + compression = "jpeg" + elif compression == "tiff_deflate": + compression = "tiff_adobe_deflate" + + libtiff = WRITE_LIBTIFF or compression != "raw" + + # required for color libtiff images + ifd[PLANAR_CONFIGURATION] = 1 + + ifd[IMAGEWIDTH] = im.size[0] + ifd[IMAGELENGTH] = im.size[1] + + # write any arbitrary tags passed in as an ImageFileDirectory + if "tiffinfo" in encoderinfo: + info = encoderinfo["tiffinfo"] + elif "exif" in encoderinfo: + info = encoderinfo["exif"] + if isinstance(info, bytes): + exif = Image.Exif() + exif.load(info) + info = exif + else: + info = {} + logger.debug("Tiffinfo Keys: %s", list(info)) + if isinstance(info, ImageFileDirectory_v1): + info = info.to_v2() + for key in info: + if isinstance(info, Image.Exif) and key in TiffTags.TAGS_V2_GROUPS: + ifd[key] = info.get_ifd(key) + else: + ifd[key] = info.get(key) + try: + ifd.tagtype[key] = info.tagtype[key] + except Exception: + pass # might not be an IFD. Might not have populated type + + # additions written by Greg Couch, gregc@cgl.ucsf.edu + # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com + if hasattr(im, "tag_v2"): + # preserve tags from original TIFF image file + for key in ( + RESOLUTION_UNIT, + X_RESOLUTION, + Y_RESOLUTION, + IPTC_NAA_CHUNK, + PHOTOSHOP_CHUNK, + XMP, + ): + if key in im.tag_v2: + ifd[key] = im.tag_v2[key] + ifd.tagtype[key] = im.tag_v2.tagtype[key] + + # preserve ICC profile (should also work when saving other formats + # which support profiles as TIFF) -- 2008-06-06 Florian Hoech + icc = encoderinfo.get("icc_profile", im.info.get("icc_profile")) + if icc: + ifd[ICCPROFILE] = icc + + for key, name in [ + (IMAGEDESCRIPTION, "description"), + (X_RESOLUTION, "resolution"), + (Y_RESOLUTION, "resolution"), + (X_RESOLUTION, "x_resolution"), + (Y_RESOLUTION, "y_resolution"), + (RESOLUTION_UNIT, "resolution_unit"), + (SOFTWARE, "software"), + (DATE_TIME, "date_time"), + (ARTIST, "artist"), + (COPYRIGHT, "copyright"), + ]: + if name in encoderinfo: + ifd[key] = encoderinfo[name] + + dpi = encoderinfo.get("dpi") + if dpi: + ifd[RESOLUTION_UNIT] = 2 + ifd[X_RESOLUTION] = dpi[0] + ifd[Y_RESOLUTION] = dpi[1] + + if bits != (1,): + ifd[BITSPERSAMPLE] = bits + if len(bits) != 1: + ifd[SAMPLESPERPIXEL] = len(bits) + if extra is not None: + ifd[EXTRASAMPLES] = extra + if format != 1: + ifd[SAMPLEFORMAT] = format + + if PHOTOMETRIC_INTERPRETATION not in ifd: + ifd[PHOTOMETRIC_INTERPRETATION] = photo + elif im.mode in ("1", "L") and ifd[PHOTOMETRIC_INTERPRETATION] == 0: + if im.mode == "1": + inverted_im = im.copy() + px = inverted_im.load() + for y in range(inverted_im.height): + for x in range(inverted_im.width): + px[x, y] = 0 if px[x, y] == 255 else 255 + im = inverted_im + else: + im = ImageOps.invert(im) + + if im.mode in ["P", "PA"]: + lut = im.im.getpalette("RGB", "RGB;L") + colormap = [] + colors = len(lut) // 3 + for i in range(3): + colormap += [v * 256 for v in lut[colors * i : colors * (i + 1)]] + colormap += [0] * (256 - colors) + ifd[COLORMAP] = colormap + # data orientation + w, h = ifd[IMAGEWIDTH], ifd[IMAGELENGTH] + stride = len(bits) * ((w * bits[0] + 7) // 8) + if ROWSPERSTRIP not in ifd: + # aim for given strip size (64 KB by default) when using libtiff writer + if libtiff: + im_strip_size = encoderinfo.get("strip_size", STRIP_SIZE) + rows_per_strip = 1 if stride == 0 else min(im_strip_size // stride, h) + # JPEG encoder expects multiple of 8 rows + if compression == "jpeg": + rows_per_strip = min(((rows_per_strip + 7) // 8) * 8, h) + else: + rows_per_strip = h + if rows_per_strip == 0: + rows_per_strip = 1 + ifd[ROWSPERSTRIP] = rows_per_strip + strip_byte_counts = 1 if stride == 0 else stride * ifd[ROWSPERSTRIP] + strips_per_image = (h + ifd[ROWSPERSTRIP] - 1) // ifd[ROWSPERSTRIP] + if strip_byte_counts >= 2**16: + ifd.tagtype[STRIPBYTECOUNTS] = TiffTags.LONG + ifd[STRIPBYTECOUNTS] = (strip_byte_counts,) * (strips_per_image - 1) + ( + stride * h - strip_byte_counts * (strips_per_image - 1), + ) + ifd[STRIPOFFSETS] = tuple( + range(0, strip_byte_counts * strips_per_image, strip_byte_counts) + ) # this is adjusted by IFD writer + # no compression by default: + ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression, 1) + + if im.mode == "YCbCr": + for tag, value in { + YCBCRSUBSAMPLING: (1, 1), + REFERENCEBLACKWHITE: (0, 255, 128, 255, 128, 255), + }.items(): + ifd.setdefault(tag, value) + + blocklist = [TILEWIDTH, TILELENGTH, TILEOFFSETS, TILEBYTECOUNTS] + if libtiff: + if "quality" in encoderinfo: + quality = encoderinfo["quality"] + if not isinstance(quality, int) or quality < 0 or quality > 100: + msg = "Invalid quality setting" + raise ValueError(msg) + if compression != "jpeg": + msg = "quality setting only supported for 'jpeg' compression" + raise ValueError(msg) + ifd[JPEGQUALITY] = quality + + logger.debug("Saving using libtiff encoder") + logger.debug("Items: %s", sorted(ifd.items())) + _fp = 0 + if hasattr(fp, "fileno"): + try: + fp.seek(0) + _fp = os.dup(fp.fileno()) + except io.UnsupportedOperation: + pass + + # optional types for non core tags + types = {} + # STRIPOFFSETS and STRIPBYTECOUNTS are added by the library + # based on the data in the strip. + # The other tags expect arrays with a certain length (fixed or depending on + # BITSPERSAMPLE, etc), passing arrays with a different length will result in + # segfaults. Block these tags until we add extra validation. + # SUBIFD may also cause a segfault. + blocklist += [ + REFERENCEBLACKWHITE, + STRIPBYTECOUNTS, + STRIPOFFSETS, + TRANSFERFUNCTION, + SUBIFD, + ] + + # bits per sample is a single short in the tiff directory, not a list. + atts = {BITSPERSAMPLE: bits[0]} + # Merge the ones that we have with (optional) more bits from + # the original file, e.g x,y resolution so that we can + # save(load('')) == original file. + legacy_ifd = {} + if hasattr(im, "tag"): + legacy_ifd = im.tag.to_v2() + + # SAMPLEFORMAT is determined by the image format and should not be copied + # from legacy_ifd. + supplied_tags = {**getattr(im, "tag_v2", {}), **legacy_ifd} + if SAMPLEFORMAT in supplied_tags: + del supplied_tags[SAMPLEFORMAT] + + for tag, value in itertools.chain(ifd.items(), supplied_tags.items()): + # Libtiff can only process certain core items without adding + # them to the custom dictionary. + # Custom items are supported for int, float, unicode, string and byte + # values. Other types and tuples require a tagtype. + if tag not in TiffTags.LIBTIFF_CORE: + if not getattr(Image.core, "libtiff_support_custom_tags", False): + continue + + if tag in ifd.tagtype: + types[tag] = ifd.tagtype[tag] + elif not (isinstance(value, (int, float, str, bytes))): + continue + else: + type = TiffTags.lookup(tag).type + if type: + types[tag] = type + if tag not in atts and tag not in blocklist: + if isinstance(value, str): + atts[tag] = value.encode("ascii", "replace") + b"\0" + elif isinstance(value, IFDRational): + atts[tag] = float(value) + else: + atts[tag] = value + + if SAMPLEFORMAT in atts and len(atts[SAMPLEFORMAT]) == 1: + atts[SAMPLEFORMAT] = atts[SAMPLEFORMAT][0] + + logger.debug("Converted items: %s", sorted(atts.items())) + + # libtiff always expects the bytes in native order. + # we're storing image byte order. So, if the rawmode + # contains I;16, we need to convert from native to image + # byte order. + if im.mode in ("I;16B", "I;16"): + rawmode = "I;16N" + + # Pass tags as sorted list so that the tags are set in a fixed order. + # This is required by libtiff for some tags. For example, the JPEGQUALITY + # pseudo tag requires that the COMPRESS tag was already set. + tags = list(atts.items()) + tags.sort() + a = (rawmode, compression, _fp, filename, tags, types) + e = Image._getencoder(im.mode, "libtiff", a, encoderconfig) + e.setimage(im.im, (0, 0) + im.size) + while True: + # undone, change to self.decodermaxblock: + errcode, data = e.encode(16 * 1024)[1:] + if not _fp: + fp.write(data) + if errcode: + break + if _fp: + try: + os.close(_fp) + except OSError: + pass + if errcode < 0: + msg = f"encoder error {errcode} when writing image file" + raise OSError(msg) + + else: + for tag in blocklist: + del ifd[tag] + offset = ifd.save(fp) + + ImageFile._save( + im, fp, [("raw", (0, 0) + im.size, offset, (rawmode, stride, 1))] + ) + + # -- helper for multi-page save -- + if "_debug_multipage" in encoderinfo: + # just to access o32 and o16 (using correct byte order) + im._debug_multipage = ifd + + +class AppendingTiffWriter: + fieldSizes = [ + 0, # None + 1, # byte + 1, # ascii + 2, # short + 4, # long + 8, # rational + 1, # sbyte + 1, # undefined + 2, # sshort + 4, # slong + 8, # srational + 4, # float + 8, # double + 4, # ifd + 2, # unicode + 4, # complex + 8, # long8 + ] + + Tags = { + 273, # StripOffsets + 288, # FreeOffsets + 324, # TileOffsets + 519, # JPEGQTables + 520, # JPEGDCTables + 521, # JPEGACTables + } + + def __init__(self, fn, new=False): + if hasattr(fn, "read"): + self.f = fn + self.close_fp = False + else: + self.name = fn + self.close_fp = True + try: + self.f = open(fn, "w+b" if new else "r+b") + except OSError: + self.f = open(fn, "w+b") + self.beginning = self.f.tell() + self.setup() + + def setup(self): + # Reset everything. + self.f.seek(self.beginning, os.SEEK_SET) + + self.whereToWriteNewIFDOffset = None + self.offsetOfNewPage = 0 + + self.IIMM = iimm = self.f.read(4) + if not iimm: + # empty file - first page + self.isFirst = True + return + + self.isFirst = False + if iimm == b"II\x2a\x00": + self.setEndian("<") + elif iimm == b"MM\x00\x2a": + self.setEndian(">") + else: + msg = "Invalid TIFF file header" + raise RuntimeError(msg) + + self.skipIFDs() + self.goToEnd() + + def finalize(self): + if self.isFirst: + return + + # fix offsets + self.f.seek(self.offsetOfNewPage) + + iimm = self.f.read(4) + if not iimm: + # Make it easy to finish a frame without committing to a new one. + return + + if iimm != self.IIMM: + msg = "IIMM of new page doesn't match IIMM of first page" + raise RuntimeError(msg) + + ifd_offset = self.readLong() + ifd_offset += self.offsetOfNewPage + self.f.seek(self.whereToWriteNewIFDOffset) + self.writeLong(ifd_offset) + self.f.seek(ifd_offset) + self.fixIFD() + + def newFrame(self): + # Call this to finish a frame. + self.finalize() + self.setup() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + if self.close_fp: + self.close() + return False + + def tell(self): + return self.f.tell() - self.offsetOfNewPage + + def seek(self, offset, whence=io.SEEK_SET): + if whence == os.SEEK_SET: + offset += self.offsetOfNewPage + + self.f.seek(offset, whence) + return self.tell() + + def goToEnd(self): + self.f.seek(0, os.SEEK_END) + pos = self.f.tell() + + # pad to 16 byte boundary + pad_bytes = 16 - pos % 16 + if 0 < pad_bytes < 16: + self.f.write(bytes(pad_bytes)) + self.offsetOfNewPage = self.f.tell() + + def setEndian(self, endian): + self.endian = endian + self.longFmt = self.endian + "L" + self.shortFmt = self.endian + "H" + self.tagFormat = self.endian + "HHL" + + def skipIFDs(self): + while True: + ifd_offset = self.readLong() + if ifd_offset == 0: + self.whereToWriteNewIFDOffset = self.f.tell() - 4 + break + + self.f.seek(ifd_offset) + num_tags = self.readShort() + self.f.seek(num_tags * 12, os.SEEK_CUR) + + def write(self, data): + return self.f.write(data) + + def readShort(self): + (value,) = struct.unpack(self.shortFmt, self.f.read(2)) + return value + + def readLong(self): + (value,) = struct.unpack(self.longFmt, self.f.read(4)) + return value + + def rewriteLastShortToLong(self, value): + self.f.seek(-2, os.SEEK_CUR) + bytes_written = self.f.write(struct.pack(self.longFmt, value)) + if bytes_written is not None and bytes_written != 4: + msg = f"wrote only {bytes_written} bytes but wanted 4" + raise RuntimeError(msg) + + def rewriteLastShort(self, value): + self.f.seek(-2, os.SEEK_CUR) + bytes_written = self.f.write(struct.pack(self.shortFmt, value)) + if bytes_written is not None and bytes_written != 2: + msg = f"wrote only {bytes_written} bytes but wanted 2" + raise RuntimeError(msg) + + def rewriteLastLong(self, value): + self.f.seek(-4, os.SEEK_CUR) + bytes_written = self.f.write(struct.pack(self.longFmt, value)) + if bytes_written is not None and bytes_written != 4: + msg = f"wrote only {bytes_written} bytes but wanted 4" + raise RuntimeError(msg) + + def writeShort(self, value): + bytes_written = self.f.write(struct.pack(self.shortFmt, value)) + if bytes_written is not None and bytes_written != 2: + msg = f"wrote only {bytes_written} bytes but wanted 2" + raise RuntimeError(msg) + + def writeLong(self, value): + bytes_written = self.f.write(struct.pack(self.longFmt, value)) + if bytes_written is not None and bytes_written != 4: + msg = f"wrote only {bytes_written} bytes but wanted 4" + raise RuntimeError(msg) + + def close(self): + self.finalize() + self.f.close() + + def fixIFD(self): + num_tags = self.readShort() + + for i in range(num_tags): + tag, field_type, count = struct.unpack(self.tagFormat, self.f.read(8)) + + field_size = self.fieldSizes[field_type] + total_size = field_size * count + is_local = total_size <= 4 + if not is_local: + offset = self.readLong() + offset += self.offsetOfNewPage + self.rewriteLastLong(offset) + + if tag in self.Tags: + cur_pos = self.f.tell() + + if is_local: + self.fixOffsets( + count, isShort=(field_size == 2), isLong=(field_size == 4) + ) + self.f.seek(cur_pos + 4) + else: + self.f.seek(offset) + self.fixOffsets( + count, isShort=(field_size == 2), isLong=(field_size == 4) + ) + self.f.seek(cur_pos) + + offset = cur_pos = None + + elif is_local: + # skip the locally stored value that is not an offset + self.f.seek(4, os.SEEK_CUR) + + def fixOffsets(self, count, isShort=False, isLong=False): + if not isShort and not isLong: + msg = "offset is neither short nor long" + raise RuntimeError(msg) + + for i in range(count): + offset = self.readShort() if isShort else self.readLong() + offset += self.offsetOfNewPage + if isShort and offset >= 65536: + # offset is now too large - we must convert shorts to longs + if count != 1: + msg = "not implemented" + raise RuntimeError(msg) # XXX TODO + + # simple case - the offset is just one and therefore it is + # local (not referenced with another offset) + self.rewriteLastShortToLong(offset) + self.f.seek(-10, os.SEEK_CUR) + self.writeShort(TiffTags.LONG) # rewrite the type to LONG + self.f.seek(8, os.SEEK_CUR) + elif isShort: + self.rewriteLastShort(offset) + else: + self.rewriteLastLong(offset) + + +def _save_all(im, fp, filename): + encoderinfo = im.encoderinfo.copy() + encoderconfig = im.encoderconfig + append_images = list(encoderinfo.get("append_images", [])) + if not hasattr(im, "n_frames") and not append_images: + return _save(im, fp, filename) + + cur_idx = im.tell() + try: + with AppendingTiffWriter(fp) as tf: + for ims in [im] + append_images: + ims.encoderinfo = encoderinfo + ims.encoderconfig = encoderconfig + if not hasattr(ims, "n_frames"): + nfr = 1 + else: + nfr = ims.n_frames + + for idx in range(nfr): + ims.seek(idx) + ims.load() + _save(ims, tf, filename) + tf.newFrame() + finally: + im.seek(cur_idx) + + +# +# -------------------------------------------------------------------- +# Register + +Image.register_open(TiffImageFile.format, TiffImageFile, _accept) +Image.register_save(TiffImageFile.format, _save) +Image.register_save_all(TiffImageFile.format, _save_all) + +Image.register_extensions(TiffImageFile.format, [".tif", ".tiff"]) + +Image.register_mime(TiffImageFile.format, "image/tiff") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/TiffTags.py b/dbdpy-env/lib/python3.9/site-packages/PIL/TiffTags.py new file mode 100644 index 00000000..88ff2f4f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/TiffTags.py @@ -0,0 +1,545 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF tags +# +# This module provides clear-text names for various well-known +# TIFF tags. the TIFF codec works just fine without it. +# +# Copyright (c) Secret Labs AB 1999. +# +# See the README file for information on usage and redistribution. +# + +## +# This module provides constants and clear-text names for various +# well-known TIFF tags. +## +from __future__ import annotations + +from collections import namedtuple + + +class TagInfo(namedtuple("_TagInfo", "value name type length enum")): + __slots__ = [] + + def __new__(cls, value=None, name="unknown", type=None, length=None, enum=None): + return super().__new__(cls, value, name, type, length, enum or {}) + + def cvt_enum(self, value): + # Using get will call hash(value), which can be expensive + # for some types (e.g. Fraction). Since self.enum is rarely + # used, it's usually better to test it first. + return self.enum.get(value, value) if self.enum else value + + +def lookup(tag, group=None): + """ + :param tag: Integer tag number + :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in + + .. versionadded:: 8.3.0 + + :returns: Taginfo namedtuple, From the ``TAGS_V2`` info if possible, + otherwise just populating the value and name from ``TAGS``. + If the tag is not recognized, "unknown" is returned for the name + + """ + + if group is not None: + info = TAGS_V2_GROUPS[group].get(tag) if group in TAGS_V2_GROUPS else None + else: + info = TAGS_V2.get(tag) + return info or TagInfo(tag, TAGS.get(tag, "unknown")) + + +## +# Map tag numbers to tag info. +# +# id: (Name, Type, Length[, enum_values]) +# +# The length here differs from the length in the tiff spec. For +# numbers, the tiff spec is for the number of fields returned. We +# agree here. For string-like types, the tiff spec uses the length of +# field in bytes. In Pillow, we are using the number of expected +# fields, in general 1 for string-like types. + + +BYTE = 1 +ASCII = 2 +SHORT = 3 +LONG = 4 +RATIONAL = 5 +SIGNED_BYTE = 6 +UNDEFINED = 7 +SIGNED_SHORT = 8 +SIGNED_LONG = 9 +SIGNED_RATIONAL = 10 +FLOAT = 11 +DOUBLE = 12 +IFD = 13 +LONG8 = 16 + +TAGS_V2 = { + 254: ("NewSubfileType", LONG, 1), + 255: ("SubfileType", SHORT, 1), + 256: ("ImageWidth", LONG, 1), + 257: ("ImageLength", LONG, 1), + 258: ("BitsPerSample", SHORT, 0), + 259: ( + "Compression", + SHORT, + 1, + { + "Uncompressed": 1, + "CCITT 1d": 2, + "Group 3 Fax": 3, + "Group 4 Fax": 4, + "LZW": 5, + "JPEG": 6, + "PackBits": 32773, + }, + ), + 262: ( + "PhotometricInterpretation", + SHORT, + 1, + { + "WhiteIsZero": 0, + "BlackIsZero": 1, + "RGB": 2, + "RGB Palette": 3, + "Transparency Mask": 4, + "CMYK": 5, + "YCbCr": 6, + "CieLAB": 8, + "CFA": 32803, # TIFF/EP, Adobe DNG + "LinearRaw": 32892, # Adobe DNG + }, + ), + 263: ("Threshholding", SHORT, 1), + 264: ("CellWidth", SHORT, 1), + 265: ("CellLength", SHORT, 1), + 266: ("FillOrder", SHORT, 1), + 269: ("DocumentName", ASCII, 1), + 270: ("ImageDescription", ASCII, 1), + 271: ("Make", ASCII, 1), + 272: ("Model", ASCII, 1), + 273: ("StripOffsets", LONG, 0), + 274: ("Orientation", SHORT, 1), + 277: ("SamplesPerPixel", SHORT, 1), + 278: ("RowsPerStrip", LONG, 1), + 279: ("StripByteCounts", LONG, 0), + 280: ("MinSampleValue", SHORT, 0), + 281: ("MaxSampleValue", SHORT, 0), + 282: ("XResolution", RATIONAL, 1), + 283: ("YResolution", RATIONAL, 1), + 284: ("PlanarConfiguration", SHORT, 1, {"Contiguous": 1, "Separate": 2}), + 285: ("PageName", ASCII, 1), + 286: ("XPosition", RATIONAL, 1), + 287: ("YPosition", RATIONAL, 1), + 288: ("FreeOffsets", LONG, 1), + 289: ("FreeByteCounts", LONG, 1), + 290: ("GrayResponseUnit", SHORT, 1), + 291: ("GrayResponseCurve", SHORT, 0), + 292: ("T4Options", LONG, 1), + 293: ("T6Options", LONG, 1), + 296: ("ResolutionUnit", SHORT, 1, {"none": 1, "inch": 2, "cm": 3}), + 297: ("PageNumber", SHORT, 2), + 301: ("TransferFunction", SHORT, 0), + 305: ("Software", ASCII, 1), + 306: ("DateTime", ASCII, 1), + 315: ("Artist", ASCII, 1), + 316: ("HostComputer", ASCII, 1), + 317: ("Predictor", SHORT, 1, {"none": 1, "Horizontal Differencing": 2}), + 318: ("WhitePoint", RATIONAL, 2), + 319: ("PrimaryChromaticities", RATIONAL, 6), + 320: ("ColorMap", SHORT, 0), + 321: ("HalftoneHints", SHORT, 2), + 322: ("TileWidth", LONG, 1), + 323: ("TileLength", LONG, 1), + 324: ("TileOffsets", LONG, 0), + 325: ("TileByteCounts", LONG, 0), + 330: ("SubIFDs", LONG, 0), + 332: ("InkSet", SHORT, 1), + 333: ("InkNames", ASCII, 1), + 334: ("NumberOfInks", SHORT, 1), + 336: ("DotRange", SHORT, 0), + 337: ("TargetPrinter", ASCII, 1), + 338: ("ExtraSamples", SHORT, 0), + 339: ("SampleFormat", SHORT, 0), + 340: ("SMinSampleValue", DOUBLE, 0), + 341: ("SMaxSampleValue", DOUBLE, 0), + 342: ("TransferRange", SHORT, 6), + 347: ("JPEGTables", UNDEFINED, 1), + # obsolete JPEG tags + 512: ("JPEGProc", SHORT, 1), + 513: ("JPEGInterchangeFormat", LONG, 1), + 514: ("JPEGInterchangeFormatLength", LONG, 1), + 515: ("JPEGRestartInterval", SHORT, 1), + 517: ("JPEGLosslessPredictors", SHORT, 0), + 518: ("JPEGPointTransforms", SHORT, 0), + 519: ("JPEGQTables", LONG, 0), + 520: ("JPEGDCTables", LONG, 0), + 521: ("JPEGACTables", LONG, 0), + 529: ("YCbCrCoefficients", RATIONAL, 3), + 530: ("YCbCrSubSampling", SHORT, 2), + 531: ("YCbCrPositioning", SHORT, 1), + 532: ("ReferenceBlackWhite", RATIONAL, 6), + 700: ("XMP", BYTE, 0), + 33432: ("Copyright", ASCII, 1), + 33723: ("IptcNaaInfo", UNDEFINED, 1), + 34377: ("PhotoshopInfo", BYTE, 0), + # FIXME add more tags here + 34665: ("ExifIFD", LONG, 1), + 34675: ("ICCProfile", UNDEFINED, 1), + 34853: ("GPSInfoIFD", LONG, 1), + 36864: ("ExifVersion", UNDEFINED, 1), + 37724: ("ImageSourceData", UNDEFINED, 1), + 40965: ("InteroperabilityIFD", LONG, 1), + 41730: ("CFAPattern", UNDEFINED, 1), + # MPInfo + 45056: ("MPFVersion", UNDEFINED, 1), + 45057: ("NumberOfImages", LONG, 1), + 45058: ("MPEntry", UNDEFINED, 1), + 45059: ("ImageUIDList", UNDEFINED, 0), # UNDONE, check + 45060: ("TotalFrames", LONG, 1), + 45313: ("MPIndividualNum", LONG, 1), + 45569: ("PanOrientation", LONG, 1), + 45570: ("PanOverlap_H", RATIONAL, 1), + 45571: ("PanOverlap_V", RATIONAL, 1), + 45572: ("BaseViewpointNum", LONG, 1), + 45573: ("ConvergenceAngle", SIGNED_RATIONAL, 1), + 45574: ("BaselineLength", RATIONAL, 1), + 45575: ("VerticalDivergence", SIGNED_RATIONAL, 1), + 45576: ("AxisDistance_X", SIGNED_RATIONAL, 1), + 45577: ("AxisDistance_Y", SIGNED_RATIONAL, 1), + 45578: ("AxisDistance_Z", SIGNED_RATIONAL, 1), + 45579: ("YawAngle", SIGNED_RATIONAL, 1), + 45580: ("PitchAngle", SIGNED_RATIONAL, 1), + 45581: ("RollAngle", SIGNED_RATIONAL, 1), + 40960: ("FlashPixVersion", UNDEFINED, 1), + 50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}), + 50780: ("BestQualityScale", RATIONAL, 1), + 50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one + 50839: ("ImageJMetaData", UNDEFINED, 1), # see Issue #2006 +} +TAGS_V2_GROUPS = { + # ExifIFD + 34665: { + 36864: ("ExifVersion", UNDEFINED, 1), + 40960: ("FlashPixVersion", UNDEFINED, 1), + 40965: ("InteroperabilityIFD", LONG, 1), + 41730: ("CFAPattern", UNDEFINED, 1), + }, + # GPSInfoIFD + 34853: { + 0: ("GPSVersionID", BYTE, 4), + 1: ("GPSLatitudeRef", ASCII, 2), + 2: ("GPSLatitude", RATIONAL, 3), + 3: ("GPSLongitudeRef", ASCII, 2), + 4: ("GPSLongitude", RATIONAL, 3), + 5: ("GPSAltitudeRef", BYTE, 1), + 6: ("GPSAltitude", RATIONAL, 1), + 7: ("GPSTimeStamp", RATIONAL, 3), + 8: ("GPSSatellites", ASCII, 0), + 9: ("GPSStatus", ASCII, 2), + 10: ("GPSMeasureMode", ASCII, 2), + 11: ("GPSDOP", RATIONAL, 1), + 12: ("GPSSpeedRef", ASCII, 2), + 13: ("GPSSpeed", RATIONAL, 1), + 14: ("GPSTrackRef", ASCII, 2), + 15: ("GPSTrack", RATIONAL, 1), + 16: ("GPSImgDirectionRef", ASCII, 2), + 17: ("GPSImgDirection", RATIONAL, 1), + 18: ("GPSMapDatum", ASCII, 0), + 19: ("GPSDestLatitudeRef", ASCII, 2), + 20: ("GPSDestLatitude", RATIONAL, 3), + 21: ("GPSDestLongitudeRef", ASCII, 2), + 22: ("GPSDestLongitude", RATIONAL, 3), + 23: ("GPSDestBearingRef", ASCII, 2), + 24: ("GPSDestBearing", RATIONAL, 1), + 25: ("GPSDestDistanceRef", ASCII, 2), + 26: ("GPSDestDistance", RATIONAL, 1), + 27: ("GPSProcessingMethod", UNDEFINED, 0), + 28: ("GPSAreaInformation", UNDEFINED, 0), + 29: ("GPSDateStamp", ASCII, 11), + 30: ("GPSDifferential", SHORT, 1), + }, + # InteroperabilityIFD + 40965: {1: ("InteropIndex", ASCII, 1), 2: ("InteropVersion", UNDEFINED, 1)}, +} + +# Legacy Tags structure +# these tags aren't included above, but were in the previous versions +TAGS = { + 347: "JPEGTables", + 700: "XMP", + # Additional Exif Info + 32932: "Wang Annotation", + 33434: "ExposureTime", + 33437: "FNumber", + 33445: "MD FileTag", + 33446: "MD ScalePixel", + 33447: "MD ColorTable", + 33448: "MD LabName", + 33449: "MD SampleInfo", + 33450: "MD PrepDate", + 33451: "MD PrepTime", + 33452: "MD FileUnits", + 33550: "ModelPixelScaleTag", + 33723: "IptcNaaInfo", + 33918: "INGR Packet Data Tag", + 33919: "INGR Flag Registers", + 33920: "IrasB Transformation Matrix", + 33922: "ModelTiepointTag", + 34264: "ModelTransformationTag", + 34377: "PhotoshopInfo", + 34735: "GeoKeyDirectoryTag", + 34736: "GeoDoubleParamsTag", + 34737: "GeoAsciiParamsTag", + 34850: "ExposureProgram", + 34852: "SpectralSensitivity", + 34855: "ISOSpeedRatings", + 34856: "OECF", + 34864: "SensitivityType", + 34865: "StandardOutputSensitivity", + 34866: "RecommendedExposureIndex", + 34867: "ISOSpeed", + 34868: "ISOSpeedLatitudeyyy", + 34869: "ISOSpeedLatitudezzz", + 34908: "HylaFAX FaxRecvParams", + 34909: "HylaFAX FaxSubAddress", + 34910: "HylaFAX FaxRecvTime", + 36864: "ExifVersion", + 36867: "DateTimeOriginal", + 36868: "DateTimeDigitized", + 37121: "ComponentsConfiguration", + 37122: "CompressedBitsPerPixel", + 37724: "ImageSourceData", + 37377: "ShutterSpeedValue", + 37378: "ApertureValue", + 37379: "BrightnessValue", + 37380: "ExposureBiasValue", + 37381: "MaxApertureValue", + 37382: "SubjectDistance", + 37383: "MeteringMode", + 37384: "LightSource", + 37385: "Flash", + 37386: "FocalLength", + 37396: "SubjectArea", + 37500: "MakerNote", + 37510: "UserComment", + 37520: "SubSec", + 37521: "SubSecTimeOriginal", + 37522: "SubsecTimeDigitized", + 40960: "FlashPixVersion", + 40961: "ColorSpace", + 40962: "PixelXDimension", + 40963: "PixelYDimension", + 40964: "RelatedSoundFile", + 40965: "InteroperabilityIFD", + 41483: "FlashEnergy", + 41484: "SpatialFrequencyResponse", + 41486: "FocalPlaneXResolution", + 41487: "FocalPlaneYResolution", + 41488: "FocalPlaneResolutionUnit", + 41492: "SubjectLocation", + 41493: "ExposureIndex", + 41495: "SensingMethod", + 41728: "FileSource", + 41729: "SceneType", + 41730: "CFAPattern", + 41985: "CustomRendered", + 41986: "ExposureMode", + 41987: "WhiteBalance", + 41988: "DigitalZoomRatio", + 41989: "FocalLengthIn35mmFilm", + 41990: "SceneCaptureType", + 41991: "GainControl", + 41992: "Contrast", + 41993: "Saturation", + 41994: "Sharpness", + 41995: "DeviceSettingDescription", + 41996: "SubjectDistanceRange", + 42016: "ImageUniqueID", + 42032: "CameraOwnerName", + 42033: "BodySerialNumber", + 42034: "LensSpecification", + 42035: "LensMake", + 42036: "LensModel", + 42037: "LensSerialNumber", + 42112: "GDAL_METADATA", + 42113: "GDAL_NODATA", + 42240: "Gamma", + 50215: "Oce Scanjob Description", + 50216: "Oce Application Selector", + 50217: "Oce Identification Number", + 50218: "Oce ImageLogic Characteristics", + # Adobe DNG + 50706: "DNGVersion", + 50707: "DNGBackwardVersion", + 50708: "UniqueCameraModel", + 50709: "LocalizedCameraModel", + 50710: "CFAPlaneColor", + 50711: "CFALayout", + 50712: "LinearizationTable", + 50713: "BlackLevelRepeatDim", + 50714: "BlackLevel", + 50715: "BlackLevelDeltaH", + 50716: "BlackLevelDeltaV", + 50717: "WhiteLevel", + 50718: "DefaultScale", + 50719: "DefaultCropOrigin", + 50720: "DefaultCropSize", + 50721: "ColorMatrix1", + 50722: "ColorMatrix2", + 50723: "CameraCalibration1", + 50724: "CameraCalibration2", + 50725: "ReductionMatrix1", + 50726: "ReductionMatrix2", + 50727: "AnalogBalance", + 50728: "AsShotNeutral", + 50729: "AsShotWhiteXY", + 50730: "BaselineExposure", + 50731: "BaselineNoise", + 50732: "BaselineSharpness", + 50733: "BayerGreenSplit", + 50734: "LinearResponseLimit", + 50735: "CameraSerialNumber", + 50736: "LensInfo", + 50737: "ChromaBlurRadius", + 50738: "AntiAliasStrength", + 50740: "DNGPrivateData", + 50778: "CalibrationIlluminant1", + 50779: "CalibrationIlluminant2", + 50784: "Alias Layer Metadata", +} + + +def _populate(): + for k, v in TAGS_V2.items(): + # Populate legacy structure. + TAGS[k] = v[0] + if len(v) == 4: + for sk, sv in v[3].items(): + TAGS[(k, sv)] = sk + + TAGS_V2[k] = TagInfo(k, *v) + + for tags in TAGS_V2_GROUPS.values(): + for k, v in tags.items(): + tags[k] = TagInfo(k, *v) + + +_populate() +## +# Map type numbers to type names -- defined in ImageFileDirectory. + +TYPES = {} + +# +# These tags are handled by default in libtiff, without +# adding to the custom dictionary. From tif_dir.c, searching for +# case TIFFTAG in the _TIFFVSetField function: +# Line: item. +# 148: case TIFFTAG_SUBFILETYPE: +# 151: case TIFFTAG_IMAGEWIDTH: +# 154: case TIFFTAG_IMAGELENGTH: +# 157: case TIFFTAG_BITSPERSAMPLE: +# 181: case TIFFTAG_COMPRESSION: +# 202: case TIFFTAG_PHOTOMETRIC: +# 205: case TIFFTAG_THRESHHOLDING: +# 208: case TIFFTAG_FILLORDER: +# 214: case TIFFTAG_ORIENTATION: +# 221: case TIFFTAG_SAMPLESPERPIXEL: +# 228: case TIFFTAG_ROWSPERSTRIP: +# 238: case TIFFTAG_MINSAMPLEVALUE: +# 241: case TIFFTAG_MAXSAMPLEVALUE: +# 244: case TIFFTAG_SMINSAMPLEVALUE: +# 247: case TIFFTAG_SMAXSAMPLEVALUE: +# 250: case TIFFTAG_XRESOLUTION: +# 256: case TIFFTAG_YRESOLUTION: +# 262: case TIFFTAG_PLANARCONFIG: +# 268: case TIFFTAG_XPOSITION: +# 271: case TIFFTAG_YPOSITION: +# 274: case TIFFTAG_RESOLUTIONUNIT: +# 280: case TIFFTAG_PAGENUMBER: +# 284: case TIFFTAG_HALFTONEHINTS: +# 288: case TIFFTAG_COLORMAP: +# 294: case TIFFTAG_EXTRASAMPLES: +# 298: case TIFFTAG_MATTEING: +# 305: case TIFFTAG_TILEWIDTH: +# 316: case TIFFTAG_TILELENGTH: +# 327: case TIFFTAG_TILEDEPTH: +# 333: case TIFFTAG_DATATYPE: +# 344: case TIFFTAG_SAMPLEFORMAT: +# 361: case TIFFTAG_IMAGEDEPTH: +# 364: case TIFFTAG_SUBIFD: +# 376: case TIFFTAG_YCBCRPOSITIONING: +# 379: case TIFFTAG_YCBCRSUBSAMPLING: +# 383: case TIFFTAG_TRANSFERFUNCTION: +# 389: case TIFFTAG_REFERENCEBLACKWHITE: +# 393: case TIFFTAG_INKNAMES: + +# Following pseudo-tags are also handled by default in libtiff: +# TIFFTAG_JPEGQUALITY 65537 + +# some of these are not in our TAGS_V2 dict and were included from tiff.h + +# This list also exists in encode.c +LIBTIFF_CORE = { + 255, + 256, + 257, + 258, + 259, + 262, + 263, + 266, + 274, + 277, + 278, + 280, + 281, + 340, + 341, + 282, + 283, + 284, + 286, + 287, + 296, + 297, + 321, + 320, + 338, + 32995, + 322, + 323, + 32998, + 32996, + 339, + 32997, + 330, + 531, + 530, + 301, + 532, + 333, + # as above + 269, # this has been in our tests forever, and works + 65537, +} + +LIBTIFF_CORE.remove(255) # We don't have support for subfiletypes +LIBTIFF_CORE.remove(322) # We don't have support for writing tiled images with libtiff +LIBTIFF_CORE.remove(323) # Tiled images +LIBTIFF_CORE.remove(333) # Ink Names either + +# Note to advanced users: There may be combinations of these +# parameters and values that when added properly, will work and +# produce valid tiff images that may work in your application. +# It is safe to add and remove tags from this set from Pillow's point +# of view so long as you test against libtiff. diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/WalImageFile.py b/dbdpy-env/lib/python3.9/site-packages/PIL/WalImageFile.py new file mode 100644 index 00000000..c5bf3e04 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/WalImageFile.py @@ -0,0 +1,124 @@ +# +# The Python Imaging Library. +# $Id$ +# +# WAL file handling +# +# History: +# 2003-04-23 fl created +# +# Copyright (c) 2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +""" +This reader is based on the specification available from: +https://www.flipcode.com/archives/Quake_2_BSP_File_Format.shtml +and has been tested with a few sample files found using google. + +.. note:: + This format cannot be automatically recognized, so the reader + is not registered for use with :py:func:`PIL.Image.open()`. + To open a WAL file, use the :py:func:`PIL.WalImageFile.open()` function instead. +""" +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i32le as i32 + + +class WalImageFile(ImageFile.ImageFile): + format = "WAL" + format_description = "Quake2 Texture" + + def _open(self): + self._mode = "P" + + # read header fields + header = self.fp.read(32 + 24 + 32 + 12) + self._size = i32(header, 32), i32(header, 36) + Image._decompression_bomb_check(self.size) + + # load pixel data + offset = i32(header, 40) + self.fp.seek(offset) + + # strings are null-terminated + self.info["name"] = header[:32].split(b"\0", 1)[0] + next_name = header[56 : 56 + 32].split(b"\0", 1)[0] + if next_name: + self.info["next_name"] = next_name + + def load(self): + if not self.im: + self.im = Image.core.new(self.mode, self.size) + self.frombytes(self.fp.read(self.size[0] * self.size[1])) + self.putpalette(quake2palette) + return Image.Image.load(self) + + +def open(filename): + """ + Load texture from a Quake2 WAL texture file. + + By default, a Quake2 standard palette is attached to the texture. + To override the palette, use the :py:func:`PIL.Image.Image.putpalette()` method. + + :param filename: WAL file name, or an opened file handle. + :returns: An image instance. + """ + return WalImageFile(filename) + + +quake2palette = ( + # default palette taken from piffo 0.93 by Hans Häggström + b"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e" + b"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f" + b"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c" + b"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b" + b"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10" + b"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07" + b"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f" + b"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16" + b"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d" + b"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31" + b"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28" + b"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07" + b"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27" + b"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b" + b"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01" + b"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21" + b"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14" + b"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07" + b"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14" + b"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f" + b"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34" + b"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d" + b"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14" + b"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01" + b"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24" + b"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10" + b"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01" + b"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27" + b"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c" + b"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a" + b"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26" + b"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d" + b"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01" + b"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20" + b"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17" + b"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07" + b"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25" + b"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c" + b"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01" + b"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23" + b"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f" + b"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b" + b"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37" + b"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b" + b"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01" + b"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10" + b"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b" + b"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20" +) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/WebPImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/WebPImagePlugin.py new file mode 100644 index 00000000..59556206 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/WebPImagePlugin.py @@ -0,0 +1,366 @@ +from __future__ import annotations + +from io import BytesIO + +from . import Image, ImageFile + +try: + from . import _webp + + SUPPORTED = True +except ImportError: + SUPPORTED = False + + +_VALID_WEBP_MODES = {"RGBX": True, "RGBA": True, "RGB": True} + +_VALID_WEBP_LEGACY_MODES = {"RGB": True, "RGBA": True} + +_VP8_MODES_BY_IDENTIFIER = { + b"VP8 ": "RGB", + b"VP8X": "RGBA", + b"VP8L": "RGBA", # lossless +} + + +def _accept(prefix): + is_riff_file_format = prefix[:4] == b"RIFF" + is_webp_file = prefix[8:12] == b"WEBP" + is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER + + if is_riff_file_format and is_webp_file and is_valid_vp8_mode: + if not SUPPORTED: + return ( + "image file could not be identified because WEBP support not installed" + ) + return True + + +class WebPImageFile(ImageFile.ImageFile): + format = "WEBP" + format_description = "WebP image" + __loaded = 0 + __logical_frame = 0 + + def _open(self): + if not _webp.HAVE_WEBPANIM: + # Legacy mode + data, width, height, self._mode, icc_profile, exif = _webp.WebPDecode( + self.fp.read() + ) + if icc_profile: + self.info["icc_profile"] = icc_profile + if exif: + self.info["exif"] = exif + self._size = width, height + self.fp = BytesIO(data) + self.tile = [("raw", (0, 0) + self.size, 0, self.mode)] + self.n_frames = 1 + self.is_animated = False + return + + # Use the newer AnimDecoder API to parse the (possibly) animated file, + # and access muxed chunks like ICC/EXIF/XMP. + self._decoder = _webp.WebPAnimDecoder(self.fp.read()) + + # Get info from decoder + width, height, loop_count, bgcolor, frame_count, mode = self._decoder.get_info() + self._size = width, height + self.info["loop"] = loop_count + bg_a, bg_r, bg_g, bg_b = ( + (bgcolor >> 24) & 0xFF, + (bgcolor >> 16) & 0xFF, + (bgcolor >> 8) & 0xFF, + bgcolor & 0xFF, + ) + self.info["background"] = (bg_r, bg_g, bg_b, bg_a) + self.n_frames = frame_count + self.is_animated = self.n_frames > 1 + self._mode = "RGB" if mode == "RGBX" else mode + self.rawmode = mode + self.tile = [] + + # Attempt to read ICC / EXIF / XMP chunks from file + icc_profile = self._decoder.get_chunk("ICCP") + exif = self._decoder.get_chunk("EXIF") + xmp = self._decoder.get_chunk("XMP ") + if icc_profile: + self.info["icc_profile"] = icc_profile + if exif: + self.info["exif"] = exif + if xmp: + self.info["xmp"] = xmp + + # Initialize seek state + self._reset(reset=False) + + def _getexif(self): + if "exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + def getxmp(self): + """ + Returns a dictionary containing the XMP tags. + Requires defusedxml to be installed. + + :returns: XMP tags in a dictionary. + """ + return self._getxmp(self.info["xmp"]) if "xmp" in self.info else {} + + def seek(self, frame): + if not self._seek_check(frame): + return + + # Set logical frame to requested position + self.__logical_frame = frame + + def _reset(self, reset=True): + if reset: + self._decoder.reset() + self.__physical_frame = 0 + self.__loaded = -1 + self.__timestamp = 0 + + def _get_next(self): + # Get next frame + ret = self._decoder.get_next() + self.__physical_frame += 1 + + # Check if an error occurred + if ret is None: + self._reset() # Reset just to be safe + self.seek(0) + msg = "failed to decode next frame in WebP file" + raise EOFError(msg) + + # Compute duration + data, timestamp = ret + duration = timestamp - self.__timestamp + self.__timestamp = timestamp + + # libwebp gives frame end, adjust to start of frame + timestamp -= duration + return data, timestamp, duration + + def _seek(self, frame): + if self.__physical_frame == frame: + return # Nothing to do + if frame < self.__physical_frame: + self._reset() # Rewind to beginning + while self.__physical_frame < frame: + self._get_next() # Advance to the requested frame + + def load(self): + if _webp.HAVE_WEBPANIM: + if self.__loaded != self.__logical_frame: + self._seek(self.__logical_frame) + + # We need to load the image data for this frame + data, timestamp, duration = self._get_next() + self.info["timestamp"] = timestamp + self.info["duration"] = duration + self.__loaded = self.__logical_frame + + # Set tile + if self.fp and self._exclusive_fp: + self.fp.close() + self.fp = BytesIO(data) + self.tile = [("raw", (0, 0) + self.size, 0, self.rawmode)] + + return super().load() + + def load_seek(self, pos): + pass + + def tell(self): + if not _webp.HAVE_WEBPANIM: + return super().tell() + + return self.__logical_frame + + +def _save_all(im, fp, filename): + encoderinfo = im.encoderinfo.copy() + append_images = list(encoderinfo.get("append_images", [])) + + # If total frame count is 1, then save using the legacy API, which + # will preserve non-alpha modes + total = 0 + for ims in [im] + append_images: + total += getattr(ims, "n_frames", 1) + if total == 1: + _save(im, fp, filename) + return + + background = (0, 0, 0, 0) + if "background" in encoderinfo: + background = encoderinfo["background"] + elif "background" in im.info: + background = im.info["background"] + if isinstance(background, int): + # GifImagePlugin stores a global color table index in + # info["background"]. So it must be converted to an RGBA value + palette = im.getpalette() + if palette: + r, g, b = palette[background * 3 : (background + 1) * 3] + background = (r, g, b, 255) + else: + background = (background, background, background, 255) + + duration = im.encoderinfo.get("duration", im.info.get("duration", 0)) + loop = im.encoderinfo.get("loop", 0) + minimize_size = im.encoderinfo.get("minimize_size", False) + kmin = im.encoderinfo.get("kmin", None) + kmax = im.encoderinfo.get("kmax", None) + allow_mixed = im.encoderinfo.get("allow_mixed", False) + verbose = False + lossless = im.encoderinfo.get("lossless", False) + quality = im.encoderinfo.get("quality", 80) + method = im.encoderinfo.get("method", 0) + icc_profile = im.encoderinfo.get("icc_profile") or "" + exif = im.encoderinfo.get("exif", "") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + xmp = im.encoderinfo.get("xmp", "") + if allow_mixed: + lossless = False + + # Sensible keyframe defaults are from gif2webp.c script + if kmin is None: + kmin = 9 if lossless else 3 + if kmax is None: + kmax = 17 if lossless else 5 + + # Validate background color + if ( + not isinstance(background, (list, tuple)) + or len(background) != 4 + or not all(0 <= v < 256 for v in background) + ): + msg = f"Background color is not an RGBA tuple clamped to (0-255): {background}" + raise OSError(msg) + + # Convert to packed uint + bg_r, bg_g, bg_b, bg_a = background + background = (bg_a << 24) | (bg_r << 16) | (bg_g << 8) | (bg_b << 0) + + # Setup the WebP animation encoder + enc = _webp.WebPAnimEncoder( + im.size[0], + im.size[1], + background, + loop, + minimize_size, + kmin, + kmax, + allow_mixed, + verbose, + ) + + # Add each frame + frame_idx = 0 + timestamp = 0 + cur_idx = im.tell() + try: + for ims in [im] + append_images: + # Get # of frames in this image + nfr = getattr(ims, "n_frames", 1) + + for idx in range(nfr): + ims.seek(idx) + ims.load() + + # Make sure image mode is supported + frame = ims + rawmode = ims.mode + if ims.mode not in _VALID_WEBP_MODES: + alpha = ( + "A" in ims.mode + or "a" in ims.mode + or (ims.mode == "P" and "A" in ims.im.getpalettemode()) + ) + rawmode = "RGBA" if alpha else "RGB" + frame = ims.convert(rawmode) + + if rawmode == "RGB": + # For faster conversion, use RGBX + rawmode = "RGBX" + + # Append the frame to the animation encoder + enc.add( + frame.tobytes("raw", rawmode), + round(timestamp), + frame.size[0], + frame.size[1], + rawmode, + lossless, + quality, + method, + ) + + # Update timestamp and frame index + if isinstance(duration, (list, tuple)): + timestamp += duration[frame_idx] + else: + timestamp += duration + frame_idx += 1 + + finally: + im.seek(cur_idx) + + # Force encoder to flush frames + enc.add(None, round(timestamp), 0, 0, "", lossless, quality, 0) + + # Get the final output from the encoder + data = enc.assemble(icc_profile, exif, xmp) + if data is None: + msg = "cannot write file as WebP (encoder returned None)" + raise OSError(msg) + + fp.write(data) + + +def _save(im, fp, filename): + lossless = im.encoderinfo.get("lossless", False) + quality = im.encoderinfo.get("quality", 80) + icc_profile = im.encoderinfo.get("icc_profile") or "" + exif = im.encoderinfo.get("exif", b"") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + if exif.startswith(b"Exif\x00\x00"): + exif = exif[6:] + xmp = im.encoderinfo.get("xmp", "") + method = im.encoderinfo.get("method", 4) + exact = 1 if im.encoderinfo.get("exact") else 0 + + if im.mode not in _VALID_WEBP_LEGACY_MODES: + im = im.convert("RGBA" if im.has_transparency_data else "RGB") + + data = _webp.WebPEncode( + im.tobytes(), + im.size[0], + im.size[1], + lossless, + float(quality), + im.mode, + icc_profile, + method, + exact, + exif, + xmp, + ) + if data is None: + msg = "cannot write file as WebP (encoder returned None)" + raise OSError(msg) + + fp.write(data) + + +Image.register_open(WebPImageFile.format, WebPImageFile, _accept) +if SUPPORTED: + Image.register_save(WebPImageFile.format, _save) + if _webp.HAVE_WEBPANIM: + Image.register_save_all(WebPImageFile.format, _save_all) + Image.register_extension(WebPImageFile.format, ".webp") + Image.register_mime(WebPImageFile.format, "image/webp") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/WmfImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/WmfImagePlugin.py new file mode 100644 index 00000000..b5b8c69b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/WmfImagePlugin.py @@ -0,0 +1,179 @@ +# +# The Python Imaging Library +# $Id$ +# +# WMF stub codec +# +# history: +# 1996-12-14 fl Created +# 2004-02-22 fl Turned into a stub driver +# 2004-02-23 fl Added EMF support +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +# WMF/EMF reference documentation: +# https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-WMF/[MS-WMF].pdf +# http://wvware.sourceforge.net/caolan/index.html +# http://wvware.sourceforge.net/caolan/ora-wmf.html +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i16le as word +from ._binary import si16le as short +from ._binary import si32le as _long + +_handler = None + + +def register_handler(handler): + """ + Install application-specific WMF image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +if hasattr(Image.core, "drawwmf"): + # install default handler (windows only) + + class WmfHandler: + def open(self, im): + im._mode = "RGB" + self.bbox = im.info["wmf_bbox"] + + def load(self, im): + im.fp.seek(0) # rewind + return Image.frombytes( + "RGB", + im.size, + Image.core.drawwmf(im.fp.read(), im.size, self.bbox), + "raw", + "BGR", + (im.size[0] * 3 + 3) & -4, + -1, + ) + + register_handler(WmfHandler()) + +# +# -------------------------------------------------------------------- +# Read WMF file + + +def _accept(prefix): + return ( + prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or prefix[:4] == b"\x01\x00\x00\x00" + ) + + +## +# Image plugin for Windows metafiles. + + +class WmfStubImageFile(ImageFile.StubImageFile): + format = "WMF" + format_description = "Windows Metafile" + + def _open(self): + self._inch = None + + # check placable header + s = self.fp.read(80) + + if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00": + # placeable windows metafile + + # get units per inch + self._inch = word(s, 14) + + # get bounding box + x0 = short(s, 6) + y0 = short(s, 8) + x1 = short(s, 10) + y1 = short(s, 12) + + # normalize size to 72 dots per inch + self.info["dpi"] = 72 + size = ( + (x1 - x0) * self.info["dpi"] // self._inch, + (y1 - y0) * self.info["dpi"] // self._inch, + ) + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + # sanity check (standard metafile header) + if s[22:26] != b"\x01\x00\t\x00": + msg = "Unsupported WMF file format" + raise SyntaxError(msg) + + elif s[:4] == b"\x01\x00\x00\x00" and s[40:44] == b" EMF": + # enhanced metafile + + # get bounding box + x0 = _long(s, 8) + y0 = _long(s, 12) + x1 = _long(s, 16) + y1 = _long(s, 20) + + # get frame (in 0.01 millimeter units) + frame = _long(s, 24), _long(s, 28), _long(s, 32), _long(s, 36) + + size = x1 - x0, y1 - y0 + + # calculate dots per inch from bbox and frame + xdpi = 2540.0 * (x1 - y0) / (frame[2] - frame[0]) + ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + if xdpi == ydpi: + self.info["dpi"] = xdpi + else: + self.info["dpi"] = xdpi, ydpi + + else: + msg = "Unsupported file format" + raise SyntaxError(msg) + + self._mode = "RGB" + self._size = size + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + def load(self, dpi=None): + if dpi is not None and self._inch is not None: + self.info["dpi"] = dpi + x0, y0, x1, y1 = self.info["wmf_bbox"] + self._size = ( + (x1 - x0) * self.info["dpi"] // self._inch, + (y1 - y0) * self.info["dpi"] // self._inch, + ) + return super().load() + + +def _save(im, fp, filename): + if _handler is None or not hasattr(_handler, "save"): + msg = "WMF save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# +# -------------------------------------------------------------------- +# Registry stuff + + +Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept) +Image.register_save(WmfStubImageFile.format, _save) + +Image.register_extensions(WmfStubImageFile.format, [".wmf", ".emf"]) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/XVThumbImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/XVThumbImagePlugin.py new file mode 100644 index 00000000..47ba1c54 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/XVThumbImagePlugin.py @@ -0,0 +1,79 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XV Thumbnail file handler by Charles E. "Gene" Cash +# (gcash@magicnet.net) +# +# see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV, +# available from ftp://ftp.cis.upenn.edu/pub/xv/ +# +# history: +# 98-08-15 cec created (b/w only) +# 98-12-09 cec added color palette +# 98-12-28 fl added to PIL (with only a few very minor modifications) +# +# To do: +# FIXME: make save work (this requires quantization support) +# +from __future__ import annotations + +from . import Image, ImageFile, ImagePalette +from ._binary import o8 + +_MAGIC = b"P7 332" + +# standard color palette for thumbnails (RGB332) +PALETTE = b"" +for r in range(8): + for g in range(8): + for b in range(4): + PALETTE = PALETTE + ( + o8((r * 255) // 7) + o8((g * 255) // 7) + o8((b * 255) // 3) + ) + + +def _accept(prefix): + return prefix[:6] == _MAGIC + + +## +# Image plugin for XV thumbnail images. + + +class XVThumbImageFile(ImageFile.ImageFile): + format = "XVThumb" + format_description = "XV thumbnail image" + + def _open(self): + # check magic + if not _accept(self.fp.read(6)): + msg = "not an XV thumbnail file" + raise SyntaxError(msg) + + # Skip to beginning of next line + self.fp.readline() + + # skip info comments + while True: + s = self.fp.readline() + if not s: + msg = "Unexpected EOF reading XV thumbnail file" + raise SyntaxError(msg) + if s[0] != 35: # ie. when not a comment: '#' + break + + # parse header line (already read) + s = s.strip().split() + + self._mode = "P" + self._size = int(s[0]), int(s[1]) + + self.palette = ImagePalette.raw("RGB", PALETTE) + + self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0, 1))] + + +# -------------------------------------------------------------------- + +Image.register_open(XVThumbImageFile.format, XVThumbImageFile, _accept) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/XbmImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/XbmImagePlugin.py new file mode 100644 index 00000000..566acbfe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/XbmImagePlugin.py @@ -0,0 +1,95 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XBM File handling +# +# History: +# 1995-09-08 fl Created +# 1996-11-01 fl Added save support +# 1997-07-07 fl Made header parser more tolerant +# 1997-07-22 fl Fixed yet another parser bug +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog) +# 2004-02-24 fl Allow some whitespace before first #define +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from . import Image, ImageFile + +# XBM header +xbm_head = re.compile( + rb"\s*#define[ \t]+.*_width[ \t]+(?P[0-9]+)[\r\n]+" + b"#define[ \t]+.*_height[ \t]+(?P[0-9]+)[\r\n]+" + b"(?P" + b"#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+" + b"#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+" + b")?" + rb"[\000-\377]*_bits\[]" +) + + +def _accept(prefix): + return prefix.lstrip()[:7] == b"#define" + + +## +# Image plugin for X11 bitmaps. + + +class XbmImageFile(ImageFile.ImageFile): + format = "XBM" + format_description = "X11 Bitmap" + + def _open(self): + m = xbm_head.match(self.fp.read(512)) + + if not m: + msg = "not a XBM file" + raise SyntaxError(msg) + + xsize = int(m.group("width")) + ysize = int(m.group("height")) + + if m.group("hotspot"): + self.info["hotspot"] = (int(m.group("xhot")), int(m.group("yhot"))) + + self._mode = "1" + self._size = xsize, ysize + + self.tile = [("xbm", (0, 0) + self.size, m.end(), None)] + + +def _save(im, fp, filename): + if im.mode != "1": + msg = f"cannot write mode {im.mode} as XBM" + raise OSError(msg) + + fp.write(f"#define im_width {im.size[0]}\n".encode("ascii")) + fp.write(f"#define im_height {im.size[1]}\n".encode("ascii")) + + hotspot = im.encoderinfo.get("hotspot") + if hotspot: + fp.write(f"#define im_x_hot {hotspot[0]}\n".encode("ascii")) + fp.write(f"#define im_y_hot {hotspot[1]}\n".encode("ascii")) + + fp.write(b"static char im_bits[] = {\n") + + ImageFile._save(im, fp, [("xbm", (0, 0) + im.size, 0, None)]) + + fp.write(b"};\n") + + +Image.register_open(XbmImageFile.format, XbmImageFile, _accept) +Image.register_save(XbmImageFile.format, _save) + +Image.register_extension(XbmImageFile.format, ".xbm") + +Image.register_mime(XbmImageFile.format, "image/xbm") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/XpmImagePlugin.py b/dbdpy-env/lib/python3.9/site-packages/PIL/XpmImagePlugin.py new file mode 100644 index 00000000..bf73c9be --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/XpmImagePlugin.py @@ -0,0 +1,128 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XPM File handling +# +# History: +# 1996-12-29 fl Created +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from . import Image, ImageFile, ImagePalette +from ._binary import o8 + +# XPM header +xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)') + + +def _accept(prefix): + return prefix[:9] == b"/* XPM */" + + +## +# Image plugin for X11 pixel maps. + + +class XpmImageFile(ImageFile.ImageFile): + format = "XPM" + format_description = "X11 Pixel Map" + + def _open(self): + if not _accept(self.fp.read(9)): + msg = "not an XPM file" + raise SyntaxError(msg) + + # skip forward to next string + while True: + s = self.fp.readline() + if not s: + msg = "broken XPM file" + raise SyntaxError(msg) + m = xpm_head.match(s) + if m: + break + + self._size = int(m.group(1)), int(m.group(2)) + + pal = int(m.group(3)) + bpp = int(m.group(4)) + + if pal > 256 or bpp != 1: + msg = "cannot read this XPM file" + raise ValueError(msg) + + # + # load palette description + + palette = [b"\0\0\0"] * 256 + + for _ in range(pal): + s = self.fp.readline() + if s[-2:] == b"\r\n": + s = s[:-2] + elif s[-1:] in b"\r\n": + s = s[:-1] + + c = s[1] + s = s[2:-2].split() + + for i in range(0, len(s), 2): + if s[i] == b"c": + # process colour key + rgb = s[i + 1] + if rgb == b"None": + self.info["transparency"] = c + elif rgb[:1] == b"#": + # FIXME: handle colour names (see ImagePalette.py) + rgb = int(rgb[1:], 16) + palette[c] = ( + o8((rgb >> 16) & 255) + o8((rgb >> 8) & 255) + o8(rgb & 255) + ) + else: + # unknown colour + msg = "cannot read this XPM file" + raise ValueError(msg) + break + + else: + # missing colour key + msg = "cannot read this XPM file" + raise ValueError(msg) + + self._mode = "P" + self.palette = ImagePalette.raw("RGB", b"".join(palette)) + + self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), ("P", 0, 1))] + + def load_read(self, bytes): + # + # load all image data in one chunk + + xsize, ysize = self.size + + s = [None] * ysize + + for i in range(ysize): + s[i] = self.fp.readline()[1 : xsize + 1].ljust(xsize) + + return b"".join(s) + + +# +# Registry + + +Image.register_open(XpmImageFile.format, XpmImageFile, _accept) + +Image.register_extension(XpmImageFile.format, ".xpm") + +Image.register_mime(XpmImageFile.format, "image/xpm") diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/__init__.py b/dbdpy-env/lib/python3.9/site-packages/PIL/__init__.py new file mode 100644 index 00000000..3fcac864 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/__init__.py @@ -0,0 +1,85 @@ +"""Pillow (Fork of the Python Imaging Library) + +Pillow is the friendly PIL fork by Jeffrey A. Clark (Alex) and contributors. + https://github.com/python-pillow/Pillow/ + +Pillow is forked from PIL 1.1.7. + +PIL is the Python Imaging Library by Fredrik Lundh and contributors. +Copyright (c) 1999 by Secret Labs AB. + +Use PIL.__version__ for this Pillow version. + +;-) +""" +from __future__ import annotations + +from . import _version + +# VERSION was removed in Pillow 6.0.0. +# PILLOW_VERSION was removed in Pillow 9.0.0. +# Use __version__ instead. +__version__ = _version.__version__ +del _version + + +_plugins = [ + "BlpImagePlugin", + "BmpImagePlugin", + "BufrStubImagePlugin", + "CurImagePlugin", + "DcxImagePlugin", + "DdsImagePlugin", + "EpsImagePlugin", + "FitsImagePlugin", + "FliImagePlugin", + "FpxImagePlugin", + "FtexImagePlugin", + "GbrImagePlugin", + "GifImagePlugin", + "GribStubImagePlugin", + "Hdf5StubImagePlugin", + "IcnsImagePlugin", + "IcoImagePlugin", + "ImImagePlugin", + "ImtImagePlugin", + "IptcImagePlugin", + "JpegImagePlugin", + "Jpeg2KImagePlugin", + "McIdasImagePlugin", + "MicImagePlugin", + "MpegImagePlugin", + "MpoImagePlugin", + "MspImagePlugin", + "PalmImagePlugin", + "PcdImagePlugin", + "PcxImagePlugin", + "PdfImagePlugin", + "PixarImagePlugin", + "PngImagePlugin", + "PpmImagePlugin", + "PsdImagePlugin", + "QoiImagePlugin", + "SgiImagePlugin", + "SpiderImagePlugin", + "SunImagePlugin", + "TgaImagePlugin", + "TiffImagePlugin", + "WebPImagePlugin", + "WmfImagePlugin", + "XbmImagePlugin", + "XpmImagePlugin", + "XVThumbImagePlugin", +] + + +class UnidentifiedImageError(OSError): + """ + Raised in :py:meth:`PIL.Image.open` if an image cannot be opened and identified. + + If a PNG image raises this error, setting :data:`.ImageFile.LOAD_TRUNCATED_IMAGES` + to true may allow the image to be opened after all. The setting will ignore missing + data and checksum failures. + """ + + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/__main__.py b/dbdpy-env/lib/python3.9/site-packages/PIL/__main__.py new file mode 100644 index 00000000..94378992 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/__main__.py @@ -0,0 +1,5 @@ +from __future__ import annotations + +from .features import pilinfo + +pilinfo() diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_binary.py b/dbdpy-env/lib/python3.9/site-packages/PIL/_binary.py new file mode 100644 index 00000000..0a07e8d0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/_binary.py @@ -0,0 +1,102 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Binary input/output support routines. +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1995-2003 by Fredrik Lundh +# Copyright (c) 2012 by Brian Crowell +# +# See the README file for information on usage and redistribution. +# + + +"""Binary input/output support routines.""" +from __future__ import annotations + +from struct import pack, unpack_from + + +def i8(c: bytes) -> int: + return c[0] + + +def o8(i: int) -> bytes: + return bytes((i & 255,)) + + +# Input, le = little endian, be = big endian +def i16le(c: bytes, o: int = 0) -> int: + """ + Converts a 2-bytes (16 bits) string to an unsigned integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 2-bytes (16 bits) string to a signed integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 2-bytes (16 bits) string to a signed integer, big endian. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(">h", c, o)[0] + + +def i32le(c: bytes, o: int = 0) -> int: + """ + Converts a 4-bytes (32 bits) string to an unsigned integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 4-bytes (32 bits) string to a signed integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + return unpack_from(">H", c, o)[0] + + +def i32be(c: bytes, o: int = 0) -> int: + return unpack_from(">I", c, o)[0] + + +# Output, le = little endian, be = big endian +def o16le(i: int) -> bytes: + return pack(" bytes: + return pack(" bytes: + return pack(">H", i) + + +def o32be(i: int) -> bytes: + return pack(">I", i) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_deprecate.py b/dbdpy-env/lib/python3.9/site-packages/PIL/_deprecate.py new file mode 100644 index 00000000..33a0e07b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/_deprecate.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +import warnings + +from . import __version__ + + +def deprecate( + deprecated: str, + when: int | None, + replacement: str | None = None, + *, + action: str | None = None, + plural: bool = False, +) -> None: + """ + Deprecations helper. + + :param deprecated: Name of thing to be deprecated. + :param when: Pillow major version to be removed in. + :param replacement: Name of replacement. + :param action: Instead of "replacement", give a custom call to action + e.g. "Upgrade to new thing". + :param plural: if the deprecated thing is plural, needing "are" instead of "is". + + Usually of the form: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd). + Use [replacement] instead." + + You can leave out the replacement sentence: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd)" + + Or with another call to action: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd). + [action]." + """ + + is_ = "are" if plural else "is" + + if when is None: + removed = "a future version" + elif when <= int(__version__.split(".")[0]): + msg = f"{deprecated} {is_} deprecated and should be removed." + raise RuntimeError(msg) + elif when == 11: + removed = "Pillow 11 (2024-10-15)" + elif when == 12: + removed = "Pillow 12 (2025-10-15)" + else: + msg = f"Unknown removal version: {when}. Update {__name__}?" + raise ValueError(msg) + + if replacement and action: + msg = "Use only one of 'replacement' and 'action'" + raise ValueError(msg) + + if replacement: + action = f". Use {replacement} instead." + elif action: + action = f". {action.rstrip('.')}." + else: + action = "" + + warnings.warn( + f"{deprecated} {is_} deprecated and will be removed in {removed}{action}", + DeprecationWarning, + stacklevel=3, + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imaging.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_imaging.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..29a170168533042af6beb69fc6b712ccfa6f0a07 GIT binary patch literal 560624 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�A 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 JfWUtg_yPGD|B3(r literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingcms.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingcms.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..47a79770c35f79d51188f7907eb41f97c7824b25 GIT binary patch literal 99424 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 Y5HJuh5HJuh5HJuh5HJw Any: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..9051adf88e82815d9f63e799061aa149addc84f4 GIT binary patch literal 117776 zcmeFa3tW^{{y%=68NeApZUQ2x4B95BDc-Sc8NdsQq5>w{R>J@TGXgU(Gn8lrq_rqo zl6KSmtx#LbOj){W!EU=k^=&D;c&WDCZU3UyI!G7I8(22K_vd-ezyo5t`@Q^Muiy7I zQ-||8m*<@Gd7sbuoX@#Dj~`zB>W4ta1csjqE(ET{kFkd-0>4pk@e0Otx|{{MIbzhn zKWzhpjE8*@O%6qgKb_8QSZn72c!SG(DOpN8QY85lMz#GvA6C;JpyzG&%6wa2)Zp^& ze?dy>^pSiD%ga;o^1!?JlgiT>4W;D)KafG28kX9$a3| zUa7oJ$zv2AP#%x>csgBy&2BZBi+RN0@@DRn5_*SAz9;N?esI}3U8VUxleti5G8b8p zX>fUohomQu@B%12xC~F(nADLE;+wB?!ElC-oTl73q8FJo=o=V2v+@J3~XO6o~K{D8JJ->h1de_6%;H zRw=d5}y z{NhstwgQ-~%@CLoLP~N{%4lQG)ytj0GTW1%GG+;>nFhcq)83jyy}BmunQ* z-}*xRL<~r(r{>(&g7hUb|HC=w>YNvQ9{zSZ;xuq57C+P~3>Rq;D`BQ`B4TMAd48nd z2q!9w+Rg+jIfiLVE&4)(RadUJ8>dbwtSU9-+os}Ak=09zv0WShx1iT1%5%415MZk-I7XdES6FdMNHa#KoOaCd%_s`-iIgCe+A~=1KW|SW?PFmehImC;#PD0B;l1$iluju>wMB73iFSlL>yWkx^?o#{Z2gJ; zva69+`Hg!(|D62VEtdT^q}ko>k?u6*(aWp-Au|Dxzd*+|rLy7BhA};dHbnQhXRu!P z1lC)L{%Ve1)Z5|94p1AKzgFg|1#PbjvU+wrIiGZIO^Qbj=uODJBoBi z-5;bjbxmcC4NE+-EjUjq73go3(}A`$D%s4&OeyVUgz^1_10?e#@4JJ99@h+QZ(SH` zZQ5{mPv-<}Z>ulPZL6SeyOW+d&+}8e8W}r?m#o7hR5e)?)$D!(J=#P*dYTLR`mAO|pK-TYLy+C=(uue|s0|O+wzz$Cf*O9Z=zTe!TMNN$Amkpuf*3qnx+-u^qj@q?+32 z!wxp5Ww$_YRk)y^)fHp1m$1exe__mwY6YuE58V{476PZoDp|#Cp>@%X8&>voqAyaO zmH3>=`EY>`e3Kwtg?beN%c8b5ZCKIs>W1tdR{^lG!Hs8*e{5GaoY|mkI8E}d9Oe8% z8RPU-u^lzy92V)UM4RxXgk$KthHL8=pg-rMU(?XPsp#hv$M=@En`us?Hmj;)vzd@T z_T)F(Kg6}&G&Zhn+*l!AKlaoa?H^KqtqD&3RDVxgeE!%OZ0*>S-TiqO@|--4F!ID9 z4~4^#=i>6w37zY;y%(~XL%&Pn?-yuKEQ{`L^J6*eJNJS1oxHD-Suf#y6*#8C?<`=w zSAk2qQkoCbm7e)9TEv;!+jTl-b%;{-P+ukC4vF`Xd z^tBQWpUXM+XSDC?RMy+`8`es4>O#N9zz>Hb*>(M%wW@@%(_M#HE6K*?<*fJ5<5)xQ z9M*doa?tCiZ9TcBI^onIZR>L=OFM(jGAg12RJAPBq#PBH0H2=oUkY7N`_8Q8}t-$t}4Frcs*$l7*;}r1qzy(?`_>#0udh;rn((yP!`;2qOYq z{@T_UAtvBTK5O{IkDX8X-kpQ7-|7z@sE-`rFB!H<*VNSsCSg-_S21g?k7Z$Mr7ECH zsm{;{*lIrFsQ=*38BKGMYau>Ox;qySkw3sJ-|`Pk7gFFy1Dx*_3|vF>UJ-Av|CS7V!Q^ZR^Vd%g_nKOWtkY5`B0Sn;C#-zO2`_ZV@5_w&0m9cxH<* zGT=*PV8&NUma*r78vmgCwcCU3W3#`(oVXWmB^>E?*0wvEA)c||48ezmo-Du^Kzo`t zJk|0n+NctQ`V!2YTi~h%MM-KT%bDzU&v_$8+qxU!cYko_oJ8AC`m>pD#A`*8|cZ|yk*zuq$JI9!mlw-6d&AdN6=A$gXn1N|ClCq7(Ni*&r5pyBaFUE%F zY~!*6YxyJr@wSm+sqN0^F}?Ds@vZ&!@Su=~Fqz554c#g6IEL{}^PN-oaW z5p4rzwgXWuVI3niq@3pP_mqrfii?}2`aEg=Xdu`}^wQGinZENCf`w7~%z z1iUQ(Pbhn35&G+Gl)uPW1bKje)jjJjw5`^iemtdPyjcGk=($B5aYbVg239p=bJ=pu&kd^Qd12#m)%g(|@H7;AN5oEeF(XRS+oS%YhiwpS;px@$ji z=a7zQX43qpy$V|udf^`t(0j?yuS}YAF}8XyK(}6mO`QUJw+VI7d^Hh1*^T$Wr+KXl zwmR7&i+_;p)AmN++{<{5=3I{r?Ak5Os~#KJxO?EdI z;U=@B567b|G&go)OsXbpdyT+_3CW*On2na~-3`b?m{A&Gwjcb$IFf7v@c#nB#NW5@ z_g#~CG1f@+=T4XASHQ(vR^^59Biiw#oIjzQpH9 zUUvJF1IzYc*zv?b4AY+&SoS}|P_=F#hILg^xVBK@?HKsp3waaqT`Q%vFO$~yhml5o z>fzV37ST8Kx7E|mx@`m7soM7MwX?%Mu$}2VoT8K3*^IW#1hx;Ot!~(IJvtR^S~YB2 zf2>uo_I^{*K+E(WQi6K(yd+qzOmQ zo@St#L*RW*`wpL=&bDD}<|T{;+Mj5j?^%~bI2S>#Xnwi~d;c}%&wExQy*ACWHW}$m z=INJV)1OS0c<5A)bk61RR}lZ{t-;wO+r$@@G4coZ!AQ_#>vcYs=Jk-l>HQmij`>_T>bSs;(l~wL zI6L~A)9mOejN8*F?{lnWdVHk)ughK(E8!p`V8Q^1UN6o+9BNm z+{LxMV|-P@i<8zSoSiB-T)?bzsl?xQJb$BS+#3|=Ge49y3}vd&XKJi3<$X2}edgn! z{^~NIzhco}=%cO?@TqUc^S%O4XWx|iO263CA1Y@F>h6SXe-XTYMC-&kp0sf1XGo*I zx`MuXRe4v>Y^2A{_ViVx^CO;q34KyK%hOkp&JTF}8N^dR%|XA2&!eAc?LCb8DH#1U z9{mJtrG5&>8ZpATUm@)|UI~ZIg|)tf=VI`l4h$9n&xHbZbEs19T2M*{nN z>=}?=!#eO7+8s`Gqlz6|0Qw>57*86$8y8NtRUjN}?<_T(@$!R@5AS3RUqgOh5$SwLO?*EA~4{UQQFpt3jcsEK^?HCR%rMjl$~#fjZ}~HC2%tZ|A1>YLNgK& z{?Yn@!GQWxr22O#{4+fD{~p-Zz_xi6{0VYA|NUA*}U-u0dQR)~qAZmp#)Z872GsiXRJgD)&u1h2|3Uxu*B|LTKLTY6Y!=pmp@$TaC2@TJ zO8Xl2$WYH;kxq6R?Ufj1duh@>_Xy`Elu0=HElR}sAk7zf{E!#&vmQDOdE_$mBHG@l;QI@?kfA8v{?(EU<&EU_!RmqSj~h8u z`z8C}WiB@n7{i47)2QRJ*e4OrFF}(G)daHxmBFIS9E1H9F7?+)%o#Dxe;^NJrvb9l ztqo#1V&AJ_SNdT+I8MDQs!Qt_4OtkKplxkK-nMXd;5(G*a_`PkDOL5@vpTQZ_w-J7 zZN>J_kluqd=%n*vza%Mh6++FoqjKv|?ryQ%Uy9}K9aL`ojQ(<)qNH*k`H^x@A??*m zZgKyxU*@BnGZ7D4Zhk1;1AJT^!cOHru;XtYXwxBNMmpY+R%T7 zkdAS+2;*xZ#@PalxB1wo#5hco#^F#rtm8a%ZkKpC1RiMZCK-{eu!?4{6r@FZV=Kz{-!7&uOr zpoBNAxe8Fnwe>^eO!ej=??Ab^ao##Lm!FFY@jU8LluvxLq7Euc#nVrollu7)8c+XZ z4(w45bM`9zu=etGey8+tUQsHYS8+CZ5#x^LDk`_`Uf-yA%#C&9w5_qetfC$Eog23O zANg7aeQ=BS_v^c(Y$b zJv;xvaW~TP@GRVcWSlFB=T38jv;7rx?i4%&^L9nNusPZl%Ub(*7c{eJZQ1b#bfS$p zI>tdC1h8J5F@!DRZAkCoZTO3#oZ9p*>cLtE=e!ZP8}Z{hn(W#u)UK=U1D^oL+3?9; zpl45F{yK&9BjAN>L7LAFBk$Z0Hv2nq{YiOZoC?%M=US_M!Fw2+y>kTC-S10ybSk5r zCiG?J2sSfC7DwZ;2663wQY2EFDW48;8pKh!`CEyn_QO&+PRKOPCxKYoBw&r5K0a`l zTFqK%Uq1G3MFQcq9`iZriS(WcvyGsmu^%nTMs)X{EAE^Q$gw(9k)5o@9yR(g88VIe zFsDO^pW_OEjuD`zOzV>Hb@6bQJg#cp+DOEy6#e-^340;h>cafpg=gc1x}EeazA=7% zJf0W#!v^QCTGxX0z{DEh&VcJlU`#xY29JxYNAF^$gceFW6{~F>jdWTwPT3&+dvIMde)6sitaVISXD$Y|U04g?{HY-Uc`~q%DaME591DFxeN^{_)JOW) zCB2lww6zjhxMJQV=VmG9Nc_Tsw0D!?c!m5t0e0; zAznbaBJQX!zEjE{cUWrE?MRP9I<3c2;M3WQ9zMzU3)oA+`fWC~({(~2=_TAjX!@N; zCPz9a0QZ`c?gOL~RakeD9>m#&I2Y3TP4$5G@o0=~&l)ZYbF@ww)vd+c=NZFwOf{!N z5mm3!vj%+QKD-0x`l{ih>KWwCGiRp{!#Jn9pi{4)E}@1sC_-r68R5j*c}Js)&32*B z>CTZ0I;08n8_j<=<5tY54#;m|* z6FpZAJQQs9NyrO@4+lc#hC%;9R=S`A9ngVTcXlrZMx+Cmk*ou|j*p~zh5gc4J;e8y zRXjdrztmT)H)zi#$fQ`#F{zxCSETmu8I(WeW8yi|*@gVS8IKv#Y_x&*l)gw~t)19s`$w$cI5mg0em+d$D1^*JL#FBcc{CjDbJ2d&sQ@-}t%fyR z!Tf$1`w17&r{6)(s*1GN*uX+(;@JqeM%)EDHC||-v2_ahnz6^z_2L2t&im`T z_s@42;U~Ax>z;=?E}<>4?K8R~_HB=@M?UOf)pxz<>$r-!MAv>>_nqy#qBkMV^&20@ z1@w1v`|R!+`<}!dj5~YwqU@*w)^K@|w)G;?uueYTi8Df>*PTN;miA(af5L(AAY4?x zmin~oIY}p6oP%>l?7foCCLKrT-ciCPtcjzX?Ib5E?5{<@c11roN7A~uZSKV&%uD-( zikcAEEAMdspiog8&T>wmtd19+j8;7$j37K8L_5}MCEPCoGn*9BU4WtRe&hyte-Av9f#*Enc?o#M zw$B3QPYl3Z*M2MT-r0wDGWul(+C^Be;#kXZt_9Api$wk3{((W9%2;A(fY(&f`*c zN^*cbm>stvO|?&089N5@fV(b>r*V4&=k}9K#-t@`$RWm!7H9W$$_U)6U=^z8>%_js zzuzL>`w?|I?^pG(wz&xp3oDbCv5IEg)0;R&Di8nEQpi%1DXByqSl@*)n1}MZAh!uC z;YRh(v(YHi1$m))N(I@a@{%_R6>XSvl8*`%8r-o=hTOHoekHkk2XdDHxubg`H{%&m zk2XuZ!;b4s*&^w=dEixp^5{+#?Kv~J7bm4SwkRVqzJmSolE7M*Do12|h5baLn-!`I zBm8(FIwKwawe|h?1$%Uhp`X&R)?b9RqjbJN_YS%t7kxa9(e~nBb_st6xFkS7d@f6y z_>(l~1^;>)cL~pL+L>@I<+#Vr_$%_!Jj)`av%sGPOFVTxs~E6eqPtLHK47PXExMfN zYit@ip9(mukQd{#fn8g;Jreopc`+VsrTEU6y2Byz__+T3{<3&BOXF_bV)K?Tw z{YCL@0z25YsXu-;k7tN)+$72I4CJS0rt-8-%-QWc?H0t*x;F=P*W5g;w{zU0USYHJ z+|5W!M?6ayM(2eGuogS0Rx!~&+l0I(POFhFKDSAd&LlHuB#nAKlNTG4uuV%{_%R@oCJRjV$&P zlDBK?4`DwB@)L~nVzf68b;qMD6>I?ZIkT{unt80I7VaUq4R9Ob9-havkIcKazFlkw z_CBcHt*{9~={YL*^6EdJz5RP%ZOB7?#`9HBzDA69&)(AI)o+SrnWCXLfQvB<_6XX7 zIse!!v`1sI_vE3BQ^T>3h%{Qap2G8#pVqfzlTaRpbA?`vw>+$!UH~@4L*7FV&C7eJ z7OrNVeWJD(_cssPr)Ya;D%ruj>Du03B46G(ZSPL_5{A-#7q#gL$UW^#Y)9Hf=*(3= zxDV8PlH$;!El(ki)-I^?z(LS-zgWD}&GXK>)}MEaEU%O2h5kD*7$?F=9rfcFH2sSh z7{M#)@jBoIy?3A)?jp|P81}BH{We*f9tOSJpY>h>52kSo9Jr(1TYa;y180G~)juU& z*^deJ?@+pc+D^1nYUYbiN?b*u@9#=6%y)hc?d{A&yqP-{4Uu%(H2S@co zE)S5L#A2@`A2LJt18Gk3#~#Y0lR^W|EyGAozEb)-t81frs%xX+M#GKmDHTSwlnOC$ zW8h+2@@hx*@wxrzY#k2UWXn)F0!4tp@o9_lHUqF7|~gBD}tOoZxs#p`Cjca`7e35^1g6 zjWI-FvX8c?gR;wfwR87Gu&|dR!e^AJJ#_R8GxBbQGn>pwIR6gYA_Prbx`4Hm2*c}3 z1?}A3uvx~1=3K=(vOxixWXl*fVr%G_utV+23N7&8I(&54p;~2yfIiqVJX}^!^o&fD zTL#w!S>LLT2|FYxE1Dn|TSB9=ryzbA9IZcZfqxqQVu2k_xR$yddp^*`D(nwQ`>!X^ zH*fQ?`2Vtu-SyujWB<;W&&PRn2W0HkACa-mXjf<8P%;+5Weh&X{G$qORX1enW!$?U z89VFVnDu4##;mVsUmWpR&xTuI@9j~u2JDwMyew#|PKffeN|c{dus=V%orQgXI|m=Y zKXECzq7G}@ua(1{M{d!s4aI$hX+LFQ$(Mt%zG69FKj4=gax)7%7ZEw*NNC86pj2(B znaW4mF31bj^_4Qn`2}c`Om?2VT76uSpK#|2@HXdvf$Y4G{gi)2Khb<6B(YXHv!!>( zhO!YlL!`4ARS4dNz<%om=%PyK_D$GZGGXs+7Van{V(g!TE}4ve7WD)CX>i|QFZ`@B z)EN*qCM+~)bXbUgOjxW!S+Ol*%g*G7lodyWZ9A)>8(xI}4c6h^g8Fc^5YhbxbjLZA zxe|ILfCV>sKDMY`iLxbwgMut@j!%Mn_ zM|VzB1k_Jb1RgHAma?77Ci^52vWfL?!(Nn4b20A89HaS%(z~D99lc5jI840F0B=*# zj&H!*B$U4ej&v09_BH429Q50H=(TU4v)s^GmWX2q*GVFv9Q1Y^{1(*fZe~ogF zfHx|ec>5a96K*ea-iWUdI7;sVZ`sICvQdq>T!Ar0Hd_bAPaWoBvPU{GCkdDnt&kxH zJ%hfWv}DYoc<&_VEbLyIC#a0U_Qxd5-D`k%V8n>}Eh$37SIPiqjez&Egt2g}wG#_IRHz!#L=2VX6ZLHJ(oBLliWdECZ|2O}a`d_lWZ`}W?ZWsDLT~Hm4ctE?q`G>sYSf7W{J}dTq za{l-8oVVY2Gw!y8sOo2~Vh-2_4SC~y9Hc|&J_gCq;_;FUB@3!<+V_y3t9s6^i}Bv= z;PrtTy3v8Y6ZdhkPH=&~0GXq+vDrBDW2Q=Ro%FOn+d*S#glSd}t!dsz_%d`b#o>mzVua4#47pwdJwtN65<2KS^cvYy zkHTS5nML)TgS}1j^JM634RrQ2=R5t0gP^PWYqwIZLuVH;~jPy38lU!rp_b~A`4!o@ZZ-eI};_VyG zTPS#AgXSaRjpn0d=Q^*syTmV-A7pN|5;+cMNe zn0m1M20Gg<1eSa#Yz1b)^})dGJb0tBiML?PM^yGJoHybt6pqr*g13CMgZe#LP;@5% zXOhp;(A}FLHwYilF;#ae!e^D^oT~&?{T;6L$2F#VMVb2!XDyU(hH17abBU0-OOQE= z!y5hQC*m6Y-hW%>$R5C5q64%pcAz|3$2|*PXuhGl6x3d_C&cw!oY3$ku-6NtTlB(M zIM%9$^4`}i7;Jw1|b z8uuRAz6o{7W&5-!+dcziy8yCX+9%s;vHvR|+l52QwpyICaUOb@uqN3K8A7&+$8R`~ zB-_eCvQ0c*FWagCvQ0dCWSjOYsXmhJU@qHK$3WSZFuh*3RoBTjl|7Vf)40vYxTXDP z9b{V#yy?!wn~-r8rHXYkq+EyFh|inr`VCO(Qzi!{IwwNaWdR1T6*U0Rd zIK<^)Pt1jTy=2qWLGRNT83h*r`8f<-MPuYF`0av>mcoWDgAH2(8@3uYY)RzyowQD` zSJsQVJ_A0Toh?OQ?G{FLKZJhBKsmRdeF4x}6gL(;z@9ipdfBZU)lD{g9du+D+7OR= zs~}5(kfq6k>aK@wB)LNWlw>HM66?u8J(9gXN*o_c@f_8)h3iMEhje5$>LnS%+27%K z;M%2(oJjjQ)k^n7 zZrynTbKElcTd=qBC}ie@5F_%v73Emamf>g%#S!1smLQSu7?E$98@h2OHWBr%2j7`! z|CB*>zYo4iR~*8ew+wt!JzG)F9?T1eP%h02kJ8vfU60D1+w-8^aRH3+~v@PlfbWM-I55J?*3oKT}FIr#CaC{pBuDxiN(5%)-F2mzgb+n z_}9M+eDVE(?r|8Ow022En`rHVe@8yN9=uYW0oVup7`$50W-9+f)Jq9sAG{fJ6wbU!%(=Ckb zegk~I%=rvL8^)mxRQGsUTjcF{dtud zcgP;DPIw;QFla>mw12Ka9oN=he-Hk9OKRU;cxngPtUva>h{gz+-ULm0lkDVsW%~)U zA-jpdez5&UvgBC<|9krhk$v{tQ2Pn5qQCz0`w5X^f8BULAyV8=xP$K}&|b+@@b=%g zpCIj((3m9NXiSpc_3S6mUda^5(tmD0LE0<%8qZVN*Y77ph_=Zp*d`tsbl_Y&R*38_ zfKPI!!q~)nAKh=@O!*4lRiDEetx2U1WsU0Go%I*@A?wxgwOO|!?mJse)@|_VZqw_K z%S$+y-mQ!j@AZC6>m!+5y6GO#55s0t9IL8qq5MMC{VlzS*Z$z1Ddt5y#zM(g7)xql zQ~=$>^NG82oloe`*O84$`+>2wtfB^VY^|cgCp34R9`~HYHb+F%j~K&RPxQ(CjlYpW zeD@%q7Ht&D2kxV}(|lk<1i*#}#M$6*oDl}$>@65)v>`a#^J!pr@Uu7AvURJZvyjCa zc3>j*F#O@uIW^h7wXj`i9Xay-tyy!Hy=WbUv3w`qqg4T`dx3G=nz`awUJHFNcY|~v zT7fZd1U})wArRmG(8dlE&tHgk!B$`>OM|jvr?HAo?8|Fo7m4Y^kWOdo5mz3>o@j(q zjd0rvY0OfXz9Z6!Jt8_kjUC1+y4BFtXdBIaDmcvjS?X%-cAA4HO?@nD(()IrWs@X( zMY_iw?tEbw?%Sg6p63D;xElodqJ4-w>_Z%hRMm$*n$nW22q>AaPPz3Y`Y2g3Ql#l_ z6WJ_ZVh*{0b`t&-;B(qKV@n+Nt;M@{c%M3!2_;Lxmy!tq)p)lr|JNI$Q|}i>{Q58X zEqG_X#D#L6MY&qM*G+lfN0{DSs`g>i>c4a6KnKsEcDaS9ZruOK`3CoOzJ~h*d6ut@ z4V!|ytNYfO(Z=8sEz&>W{d5@V7~2hBEy z6*oa=$Kx)rs#ab9Zlt=N&P|r+S%U|=K=jjO^wU?>dB3GQM=Hz}$a56mRyay`8g4<| znYfoq`+;wTE?p-;Rz5J-)qjBZ=rUmgUqn50_KACRI77vIsqpQ$;!aYKbRX3S{ERq9 zWRR&xk(QUj4$z&f*gWRA4Qa7jHaC~*#kY`fC%BdFE!84E0eQ*h^n`zcFv$dkX?>6H zEA61Wg}6J6GrgK)m!JnefqM-O=b06az<#$M6VG?z$4Pf3Rq&|}+J_5AWhVLd>Ofhw_Z*M>xNLe-%1o{b=C*4Rhcw z*)cj(ABldTwE)R=Gs?IOzD|U(URQRCV+ZuyZtT@w#ob%VR};;0DyL|B@p9jRX0+Wn zh4tbcm)=7UGKX;@Yy-v)R!(HScc7k+5&z7Zk-NSJA9cYgNhZiZtiY^ws7K{n7ma(p z74HxpLS3}OA9rzZ*Z3mVDy9H7dk3D|^r*HaUQh*KoUX)PPAi?;#z&~?)sQns5ab6s zi{4%Q417_)KgoLL5WjRr{CC8?hBNFs1-=V|JFN!D?7NUl2fjxGSq?SgyD!Z*vjpN5 z_o|Q5eQLC=Vi~?`A=ZPotiiim6R|&>i+Wb09^4)7%|YExlu75fq%$WY{uadJjuULe zsO}nJ^}0qOZ3Oxt7p+D&&f#drNY7-L>;C4BG1I#Q=p zb?1L2VLK7nE>Qx%{{pt1KZ0!)+BX!o>HkS==cByA*e*bv2U{cfA$&c2o(8swz?S;? z4&)Q(E%dW|oT$#Y56%|#WVDlP3!@eH&(Y^=@V+d`Va~oy(f46I-G}!zpT@Uz#P@9> zLmK3{f_F1JvBu29Si4MiNf7QnLuZM)Crq30wHOB-7Nl(rME#W4h_TZJxm87|>jlWG zlE=r^H_XSP@95X>-6OHyFTx9d0szu%>{lOaI_|ijewm29=cI)HFN;!Pv={eR9URyRm)$SHhFrjOqtu(^yo z{r@U9-SWH~8{$h39AGOwPG{j=s2}=prB12tu0?zTbP!>uLK^uLrm?zYRn)E}&~xpn5j`e#`$>{&U0xlzjYWpAODNpJ7ZI%{cJVH6V2skv3}8lAG-5%^2{(x z0(coeT$QQ*>i)+Sh&zktyP@lSLHodk!1=+2!VQC)KDsGW@7q2vYn@=8zGb>O>rRb1 z`vuih`wJmcpLjtt_2Ag?nLA$4Sa!g-y%1u#7jd6}&U!&*S&ckB2uHnS^BXT`rf$5L$u?ffTms%| zVdt`q=Q5w$cph=5k@kki_r4BsFc>P{Km@o9r?L+9O*@!DS8*FKML9bSz? z+hI!{!=D3q4*~BCUw>bf)|PFU8!)l$IGC!b{{(Z}len*GoGsnwdyOtX zPYvz}<=x@ucmn0oyto?gEs*_6^WrCX_vi|qhn*tMi?<^`%`up>C(`^SAm4Pv(K)Fn zJPl#o-<)Ye9W*y4L`2pnfcMR~Z`cicYH6*mWpeG*@*eZkJRSa95Y7Q7Yovlzdp zhbgBHKUb6W>)}3_N?CX);`d?gB&|s!yS2eA=N8zyFE2}JnS$?iSunq!fV_~74ng_I zFWy@`QdRvpjs5f3-|NI0z;C1W`#;TWoN@+pYU0cnri8qp32s1riDUE4Z*P1q=n=%d zjkJ}Bv%)PLTVeJa`y2CrZ2Tf~nm;=)KpvmR7~Dr=P!ZIfhw=J>5OVk%bx8fW1=^O_ zRBc7gtSviZ6`G2?X*KW_6)WI}DnjdNJ$e$)e*ipg)bB>v3`X4XyaP^-lLpujR(iCF z@W47fi|$T&@My!{&LrSb3OpeDGs}R-?l@NQ5b&UV09x1Igy$Zuc;N9@Qg9Ctn4H6! zR|%i=B4PB8G1X<~7Q9jVHt-<~&TyPUW;cpBO@luTcx9mtH;=ZOC%`4bO@n&_y6H4@ zl+PodXa3}oFET^ML6>37QU`2KAU?kOJLqYkQn8MvKD(N<(W zv3ci*7>5{NqTZtQIm!4?;{!VX0Go&JU*KE_cjphNFuv+w?}dR!74G1x5U0i(JXsLB z>!1t#eYLHNVW&`7jj#%HwJH>Q5?Eu=oIOHT&&VfxFgQ({5UdCe(4|c6)=ta3nu@*CJt$|(N_-m;Wz=H5^*-bkcGa<$@U72B zQTKa_p!zMSI|$!X#9lD$U#b2w?A7hXT$L#F%n81;b=Nn@6M}sgT2HuP8__&U{`K`P zz4`{)O7$K>o$aWTz5_@567oAS^i7AW#s49`Bk(20IO&UO*tMh^-x1rP&LA9I%D{=# zKXgWwjy6%BAv{x!wQe2ylnA}6 z)4B8{v_q6B_$oEd#h|Zr&{rSMdUU5w&{VuK?J@X@iZ$?;;yJ7rL_I%^cvpjW=-fc) zT;iYRxLZ&T&2d!bbMWady+;R=ZTgFp>avE#Z$k5u6MEDLGK(a=V^4`iuR-4hu)xP zXkV1>jKjX!F$3SIip4tnB;*#dB;ErUeD5kA@zoeR8no54ZfsZ=^aI}CtiTyrP7Tp` zUJE)F-;4dRa;n3m?=j#z^c7uL`@*K47#r9}`&UQy)3H(gG~G=Y+@>4N8I2e>7jWN& z-Y=lJLLbyKN7RR~-LN;5MLLn}wbemv4(Y{Dxn4Xf4AhH%LRhXB-$t19q6>P_pJ`i{ z3DE(E@Ll?4*vF=I(j1gc`cenmc**mdqn8ZZ96&m=Nxat)QSuV}iO?xJ0r!<)M@;kwK-k4sp;LE5H!;lbYw!%l zLW8G0w;(^=k-9Qrcl1#0X@o6>^V^cm=PgxJvI}C-=G2Ss z0dv_B0^T*fwmVD>K2^)Y!(waGDm0@OuT$aK#i&~|txha&vF}4-p5$407nWoK zX^Z3DiC)7tW&zhVHIOHUXQ=Mj1lG4#AB+5*%1vS!?_h5}**Co;9nZ1|sa#c66w0m1 zdKYoA?|)r@o^nHyMpOn!n5CYO=$a8Jxu&&!PykZBb}iwUjBsm{A4_j zvLt>{z7c(yj6S9J$kmxo;5(6!>(T#5Y#-r9XO-h=@0&m0hVO~|8Rb!5g}jINZ56TN zImo%g{qzwTy;nwWlhNfedWDQml+htF`W$^bfY)_IM(>r;+hlaPj9ww56J>OWj6U~{ ztb7^0S4MA>(d9CFg^W&=(IGPWT!*ZD8NF9VZfB zD5FDU^trcW<;&>3GJ2bgE|<|OWOSm84w2F4-jtOuqxZ__Z8ExCMz4_3i84AwMxT2_ zR=$khE2Fo`=yDmoLPjUb=nxrwu3c8XjNU7wx5?;o8NEVAC(7s$8GWuzR=$khE2Fo` z=yDmoLPjUb=nxrw?vSi}8NF9VZ7RjqoYOe}40m!m8#L~gie;jX@V|1JzAy6?r~sIJMN&vQBf z^e{~J6n`^l*Z?9u9&{3?HK3PqdJO0_oEGo@aGJg!{sO0Qs2u(#r$a%X;WT}xAq)#Q zsw)8WbWW>4ujVwehL>?#0eUm&efy+$`_C;pBz~89?=wuCFQ^=P*PG!-^kvZaeuYTW zoel6T(&s=g;Ph9Z(Pv`(Ss*)AU`3|HJ8%p!ac_?rr>u(|-f~8K*x5eUa1j z?+}CuQu)U~PvrE6pwl@09_Twc{SIh5r{4y>mD6-)(#+{L(0}CgA3z`D^zT4_#p%~T zM*uLw;Q;8VoZbg|5vN}Ut>^TMpsP9E4ElLaKM(p3oPHMcN1Ueb*LHLIm!KJp395^1 z$I+a|Uhc?QoZb$4Ij6UQuHf`m&`)uCGw1`HrgQ1{IK2_{mz;*}iEn2}bv+1r3a8hD zUdHLQpx1D^67(icTR}H*+5-A*PM3l{#c300AGK6|5$KyZT>yGMr?Dm&c_*ju23^VN zJ3;T{^lH$50J7!pp^_ah?#<|5>^Q@jLnFc6~TY=M1L$k z7?XfsG`)Nf%_g(SlVc}OR;$&M<-ebx494Q&65!^+K`*hN!`%(H9_|6S7vX*n7o}lr z6x?XIF>rI?ZiQ1NGNy*}hYNrUgc}YQ1Q!e!0v8Gw4i^Cz2{#fh3T_l!G+YcEM3P|$ zfH%g>7LCDbwOCn!-fXtmHI{ONSz|TWES1&*1FJNbm@W62HASXUgQm!0Ez{dszSUBK zJQT%D=6m&}rb5j^tHF>{Rc_GSYp~i(7Befe6jtI99@Lm@8oR}!DYe|!_lVwFTv=u? z+fj$9ti04fw4qQ_WYF6ytp-mmc6~mo;Z<6SifjhE=020%XfkW0B)!$DuhQsCODzR@ zJ8IV0OzR9%WvIcx%1kz!$y}_F8q^mow}Mfty{fM{#ido{Mvci_Xjt19S76jz^#yi= zRa0OoBrt51<>eMDHIrvA(--&Q!U41zP=-~5Cfax|j++N7OQpTkWbVhVz*1Ijv6<`! zDLW&e%Jk+c4Vbjs`WjPiT5Bj3x$BF{zGIQ5&{815*jIf18bg6yW7L}qWgS#%%D3vR zD05&m@1{YqMfw86;G80?gYror*h(QbgHi~&GJW}V(fR_TftUkq*1?H3yVamC^ThU{ zAT`m}4~t=~-C!mmvoS!au@q^_3}qH;75b;tWTVcph!6~rXsPf%kB|ML!u##YPMYBMnjMG01yATvkIdp<)Ft1q6S8 z8!Y9bSQFAkhWj+00cm44yS|`A(^nPc>JR1X3;VLNLesq_>IzMMm1dp6YU#tmYA8aL zW~h)NOQpF`Q)tMqECx1WjZ)Nt%=rs>j0VHmu+~seDUD!J5Wt}b-~0s&v-^q_n_|_Q zF|hmd7g(S<*4m{(Z;|s}RB0{{i!3x0iRhBh^huV<3^Ay@K124x%p52?GfE`wqv0xq z87)@RIz;PB0lJ4j}=%dOA9qLrvQ5hpVUiz)!eA1gKD}#HZE2RAsrfvRkK+1Md>10f?_IyNZJje zxOt|4e3P9xLOS~0RAOMHKaCbki495zBZ-=tZ@|=sNrp+Hs}n~G^F71cY9)V%DRl&qYE%QJH(04W17 z^9WqtkdfJo?_4ls&eY|rGUqSOT$H*z_qz17^pvdZ>te;4De1bD1(|8fsjTY~Qd6%l zT#Vzav4u2n`1t5kU(`pQZV-92N%=%nY>*AE=7z|pGhvbiPDOTBY_QX?WMp~}w2USt z2o%lP&^4Aqf|GLSsPAp8R9}S|LT51Jc_<=19xH^FfCP9HZNK5dCrE}W?l;@2#+$_k zGHEuan#H={qv~S2kz(%ETd5T`PV3i#gy`^SPKvS1m*2l`-STy&bxVtimfy0j3hWAwEGPaXCebMQe1V z8vEk=qf4PgD=`iCCmGh3!*BpXG&%sJ)n3XfjVviSeejYL%H6n>w9*HYV;Uq6_w%~(N{I%c;&>DzOYayb|*Iq`wJ0yChm%0 zc-moj>d0p4OXuuM{XaMsJ*Si8PL{HwYMG%-mua}KFOK@p4jeS%+|tL$WQ_+oVwqa! zFw?E#72G zAjcCZo=acVcv!Nqn=8v0rZ#;gN-fi`6~p4dFtO#VPg{AqO^5%S4b3A{77y8KDu6!CxN z>7?m8&+;HW<&Fiqtdy0@m`E+mTAaFg{$eQrb+j;b)tz@rlH_@!$ZEIr=@gHeIzX;$p%1FND4+* zYPi=>YSTgI$n(IwE-0bl24Mt}ytOduXgbi@EjpUyAyR!wJWNSES6>pUZ@&SWmKu!2%kG1xBFGb2%j^atG9S>lvw_#aC@aSe!NE3PKvAJwA>{K%*EA$izN z@WJ_%57vo3c&FP3Yet`!k{MfyL~;+jK-nak){=p2466}KWx_@U{&5Ol=9})z6g{C# zxG9qP6h<*c)M(~AdJGecu}pCjHq~5{nb0_evDc@d8MNUxl_@VKBL5u5lIAdF9_pKy z$`qwb7^_*r6rbWN`{{Qvw)ZaP^O2q@KhI}ADg(8GVR!C-<~RJ1RBjmeM{<8O_v5(# zKU2H6R4)Qv1iT1%5%415MZk-I7XdE9zv0WShx1iT1%5%415MZk-I7XdEaC3-|A$4+r9B1F${dn%r#w=Lm;0}Czk~Z9ale!MUvj^P`#!wf5blrWemwVQ za$n2+rQFZuej)eExqm$tyz`;FXxiTf?w59ItrasMXnCvtxt_tUvAao_)UCVj*e zKl)ZA{ch)B{(TUZ#l!UN5Be4Hu;)V@RvyOpX~kbX57YNX==VGi<2xhb?^PbgXGX=} zdpwL!c#6Nj@Gw5hDgG|T;Nb^(7~kd< zf4}142p)c!ha-9TZ5|dsu8X*jc{qxvyLec`!`FB?j)zC=mxysZJduaT^RSkOZ{pz` z9+ti?it*3GH}mv|cz6O2Kf}ZH9a8$e%EO6LkiEyl(|GvrJgnv6^E{lw!)_j4$-}`1 zBqEE4$MJAB56|Y|93Ec6!>f4s9v;Rwp~c^QJiMBRALHR%9)6C8^LY4G9@g{lVII!s z;m>%ufQP^2;c^}hJSY)0JUoGiYk7D!4?o1i={&rFhgb9PMjkfs@WVW8<>5zocmogr zf`^~r;W{2}=HX2|`~eSd=Hb8ca6J!y#lu^8SoNwzY~|sbdH7KtUc|$X@vx4ExAE{J zJlw#;&-3u(Jlw*=+j;nJJiLR4m9I&}6FfYgho9u(pYrfiJe<$NPxEjk4?n}hkMi(N z9)6yOck%FhJp4-@{*s63yVUd>*&_MBl025k!;L(=l!u#mIFE;)<>4wGevXH0c=*>m z{7W9*%fqko@ID?s!oz&nvoCm<4|3b z(@S~!kyTQ`K7-0%%hN-0hfd$X)8G2Jls>rpM|pY&zB5I?!Rb=$jsI%@Af+8Cxp5v! zS;X`8{F8jkcs@<(kC&Ij^CkV0e0TADEB;Bo0-n$KPx7td`PTlEd=)%j-9O3q<6QQq zy11O4=l*5xf6skij~sB{^W?wUpC9vbJkPoLFJ1kwm2jh6nY=xodDv6_>wLU;!vFvI zgGbQ6S99GUJnH;!#QDEht~a+A0WShx1iT1%5%415MZk-I7XdE9zv0WShx1iT1%5%415MZk-I z7XdECW!M1rKml?_|RvzCMxjb9S*cXviX||in z41;2Gs>%mP-Jvh7l*cVBwdn0S$|zN-TWBgZWLMejhO+sFB7J44eSx{aQfM+4Q#u-| z%e0sc*>-DXft_s|fhe8Lt}iIj6&Oo&#g%$%A@UVgl@=npGGCW(G8Y=GOnkM|%0jie zg*m!Zlf6t|u1m9+?=@Ia2(zjNB+N$z6dN)icCpzc=8ckKDU)uYzCg^Wk;N@4ttvOt zaDuPXx~~&Na|1MD?-~JmtnA)MG%-Zy+5|U+!g(i z*+pi%E>mA7HZ6CEc(9J{qDu4nQ**3(v#rQtEu(lNk0)MqVp~%!Vk^t#3Frk&iCD{8 zd3272Lrf*r2vQQkr(0+>7^JRd);gZB)Rb@4TdQ<;7_2sv#Z1p^^CVgHg}Od4p60Qc zhWq+}Zm1so0E` zSgeq5z1?7=T%US!iQpm^m&VRP@qmG{y9PyrO^QCpqwhcqEmqxt&g~Jz5ua+Yl%hv0 zWlJqIxX@J!F@C-YO!3m|WKk%2F-9dioy*}iDG_6yfGyLD6+hh{nQ4)_gvxI0k6vC- zP-(RqFix4Zxj!1k_ZPiaikFl_ifz87GQU*ButiE(YC?ZNE~!COPMa*6H@!m^#hXq! zkML;ltV^+ZSpRfDY_<(OtrOYllqJZqa!K)EP!wt^`CNb0GJR>OrGO%Pc%-GUveckU zvl`IN(qPI!W%k$Te%+Wxi*rx}?qLdW7 z-P#XhUDV3V+9FHHGUyAdsOmN;a+TQx z^=tr^tJ1P(rdi6x#E$C{a~3A`x9iBjWCFHdf{Y{vm(8zlp5Jc2?c%mnkiUVT2N}Si88QP3R}tz zqVjB!g0?DYU{I)tOG}4Om{w=Rq*z%5U8mC*7V0YPMKeTsJTfq?K$KLf{nLR7h0ugn zi`dDX15=8jV2i~G!(=Y9h`P*mqa5WHn~6XabDg_BSE<2VY!_$Io`H#0gH2L!HNFFQ zL9DLOWX0Ivb4cCw=|!dbVzI()*Qc4x_nK@bC>esTXus&(tL9%(g+92=^jx zh;$4}BUoTy73%tUKf-f(SQ*^3PY0({@r9BlMyPc1bemBRHBnSqDvGF!$J+J9g9|*z zlPbBQD8l%$=?0bBGbmHB!ECVVOCj}kLov)xs=3Bb>Typ&{b<+m6qs{lLdbyL<_GaF z>l->xi$OzKfuyAxDF{LLDC=elqn8Sdl4altmWh*l3lBmz(H!~-I_9rrFI6+9Tu~(& zI670Az8KSEk)8P#*>wi8rfqDRRbNr2W4HUTjz@f$58HSFFN*uq@DqEP3kjQ3zm!(Q|8 zVV|Es<%&`R43GlIn89qfu>*oM+&>b0nCmkEO>Fx+{jF(HfVaMJrGup|)zT@5Bi+V! zE6Pz2Mx~|nUPGa52tKa>pZgRj;CPc|%=@1cla6Sx7Zy zX(0&#!NnGs);@k+7;?p8&efi)9Os90@UVAOvk3qpR|shR@bH`sxA~Co51Vc zi5E(>Lo?-lC%T}Hrh}ug5iB1t%X>IJW0v<&L|<;|%X=s~GJn$6=o5*tPu;1}SOzc;V4eoR*c;LmZtnSUlLo(`UY zx73W+>}0g+*UaU$D>z>1{vh<$7)vXX58E z>QnqG)c)Ik(#!RK1?z=rd!!$%^tPY$(qCN5dSTJm^NX2?sr|N}^wPidWxcTIL-Yj; zeURSvlV19xTUakl^{M@7s{OW~^wNLb#(H7V@8B2z5!3c=tKNsLDAcO z(o6q%FYARxFYn(Gz3nHx*PpUpxFx;qC%yE)8(1$a`grU&EyU?oePYr}f4!6S!sMs; zYrX9!z4Y&mtQT%cZ~I9vtQV&GkPkI@ji&-x$`Veg# z3o&h9{Ewi10y%hDr}!nsZ!7*>@wcxGUtf~qv5KiZcKmbUx8whW;`LyP|7bNn=FKrX z(7J<(zc8(z;y28=z5TcS6u&L3@4$Lt(RWmO+fVui)?dqdVbRk$PYZoe{B1w!PZYUs zCzbWWRG-?v%eXzg?I(S0v8gbe^}?dBp)XkIgSKz`N#Co)bvu(;FHH4m`#EZSu>GW8 zS!VS4tQQvjAf>ncq(4w@^!Kq|SoAvnwx9GTSig$(!lJKL+qeCsuc|cL{{`!XMX%>q zwx9Hu%`^H2)(eZi#<;!s+kVooW_=Uug+*Vc+Hd;b z7CnmHg*e@+PfYrrtY6N0Ve-@YpMiNNEySd^{iLs2?Yf;OST8L4Vl}_B{iHv`FFxJE zdSTJ)@zM5^-dSt5zn}HOqMv5mUi)o7>8G*&L)Ht6K2aS%+fRD=Js9Bd1)$zCeq_3|dwd35tdSTJ)`IYS_{XW)@WWBKHb^L8V z>6=)8C+meppWwF6-+$Xrdinia#(H7VSJ4+N^pS4WUyl0SLjLdVwZzu%?FM4ZcjWgl z>Fx2B!WxG{`F)A%P8`jz`1g4N`=!6@&n)9l8ncY2Q>g(6KOSY4@!}a~>A&_c z%XmaLB5C_FzJAOs<6SfYPJS6buVR+|tS_^ipF^4De92&z^REz$)!{$0EKppdn8rc7 z{z2E8d`ZyW*D=A5?r?@oB{&{0|K5{cW$fi{f62hbo?+I7@M*;>C*BDBi62 z-xR;5_1B!-l|y!fu8QgWUof4!adL0yYvh3N{*+ z1{(vTdD~dnIM{gD1lUB_B-m8g9k4rLnXn(jvS8C;*)W>3<-%sbX2SAd`LJ2A*{}jw zA#4t;2v!XH39JNG2Ac~jhusCMfK|e1u5&N!KG=NN0@y;>BG~;fnsYt?dl2>zY%#1F z_AqP-Y$tIj9o`TiFCc|!n z(Y!1JHU;)0*fdxv>~7dR*we7!SpM%mmej*0I7nL3X#|;m8Ug-FjWmL0X#=J>JNz&D zTxkBRZ$L5&47mvyk}%`{Vc&Q1ANc)(7XHw0Dm2ehFy)-7V4!)nf+_bi77SC?g7=#WmNy~nLpRP=0;d#nbq7#(eGCwn!5Gj8q z?^wXjMW(V#CLvP=m3?fAth8e)Q2EBDs9B=16t|FJ?7HpLV!MD+7j2%1Tsz`sS;Xk5 z!qbOQ;N=a=cc`s|VU${#!c1O@Fte8%%#2mwcu~GF71)m`Fq=S|#}2qio=sp3doqE` zD8)5QV?C9CDk|;RDhnM>KzgD@G z_^V3&qb_Tvx~5c8eIdET(;|OO25|E_oT5vPmUDhBuY1&~A&_N)`Kfy zPp!ClzF{TiITp$J^^$$@#m(}?C#CngW26%?q1P(pOkS(Rn+W)+z%$Viy8}M*`zUwU zs_naE_-^LrY+Xxa(sZqYQf$Ca!cz{DoT>_&4a9zHX=VOs9A3^@p|r9{$+vE~optLL zw3u#ddnpiRGD7QSiQ5!E!ItVv%fb?2!yL3GNvS1=l}k&glW3_-l3tr<&)VK*X|uM| zii}E>l?>U;LX#Tn<-|%dtow;9So);&*JjUGQ9du_vf`XH!R6E5B|KF_&tMrBD$>&x zKFP`BR)x1bt7HzIUBXFbm1I?T1&BCT;TopE)S#Ia4uG2-n>n2x^r7s|=|vTpS$O6L z58~ueKCZXsEIciNV_KMBP^k(_%PR4}NqEJq(rjeQszO{$5lZuN^JnJisuh{V#dusL ze5I9<3T5tXX0avt)AMukp)+6H+-aIx=HdyF9Crr`a?5iIN;8osoLy8{j0bVT>f-sT z?AbWwC{4E1t6^q^be!%&;_l3ntm3@f!dw$HJdfpMnhJET`cC|wnC)a1XW@rK4xYHf z!xh%_G}3H187DL9WV&ZeaY=qT61stO8k_uo6OF>$vb>@k>&W1sBIA~nV{%Jo=H}d5 zP&7TOpcyBp_D_|T$|YjX^JGEyib0ztB;m1XA&%jd!UE{KWDCf>c0)mvB{@c1KzZ3* z&G%7A>4=&G5?&suJ$?UR^sGt>9;zx%F3idLLO-=5VlvPsLuWu5v=5dtfB=s4XLaVmcTomz_EB2Ev zVKhJJ6VT6mLw$mEKj53ajQ*Pe+}`GqMC(>HyRwX{9i9L~JI zXD9jpwAZkrPWPNr9Qya~cxc^?xZA+-q)&eGi9z2V@+PpRYNR_~G%su6Hj8~n#howc zTQAfHTXR)+BeXu5*m0{`xDiJ+|EF$VMH+#v0lLNeN7UwK^KEy(WiI7{I~Sn)Dj0{o z0*Y3I=YRYPUMTfl#t8Qejp`DU5_hxmL&SgT$><{A2E&}yy@B9LWd!x^jrr~T24*?# zCS+O=aUMeVdC$KS+u%4MJPqOftu7JY@pr7~&mG*Whc5)gXgmbZGSjV%E>CZD}Ro&x-y|AeRFQRxfM%eM%8YekUnd{i+jHN zv!rte`)|1F=FcDW*3!b4Qy)E0H00E+hjSW+Pq|~uN4M>t`oJsCEb27;{#U2;=<~zp zy8d$hmgh2xe*eLYhS1^0#@SJ0Gh)7)S3mFW2afDsGNQWY#;^1Do%Ph8X6{&f{Km(VN34vwvDL|hLszb9OxeA?sCV?#uO9pUyX{VG?tJpz zMSTV)zFU3cj^b{;rmelb%igrhV#lR#o4xq8$t(ID**2udlKN-2e|luevM!0;_BOrp z#oKMRrXDIBA3f>f?gO87`CX5ydp54_|77F9Gu6e1N7bJ1)OpgQ8^4&f=+iL`8H=vD z`~JAp6AxGQJ=|tN#`Vjey6m%a4|V%;Lvm?N;^G&&UzmD)%U=#`8}i4wYo_*}GVpNR z?(ZBu)%nGrKlir&Ra;&iQTEZ=P|}(&Gc$4*6-T>nb*+t?zX6nhP0)7kcd9dCyI!o}Auy z&B)8IshhTR#iaHVv&v)N_}P$uy)b@4MnV5S-~8-{dtOO9aPr)-=PSQ1zJIH~)oXP< zUwY$~ZqAqu>sFn8{`{XWX7627d3MpE5x+{mcuU-_zjggzr{7d`?vugo4%YTes@~gS z{k^Rp8#!?Jbx-#`_115X$L)Ck%I=Sq-~Q_k-;*8FB@)_tSWnv!?+Y!}+R z?Bcj5caEQ&e01=|8?ITga>omoSD)?~x4d=y#PXiUS~qob{`AW}hla&n*MC{pvo)<( z%{x1J)WbcF#XL2C*7hT_MtA=Bj^2F>k6nHJrlzaMytwY#_4RkhHvU6n&ERdB^G1H_ z&b7~exNh%rb?@ckqNdB+y=c$B<35#zKWPU`5P={9K?H&b1Q7@#5JVt|KoEf-0zm|V z2m}!bA`nC%h(Hj5AOb-If(Qf=2qF+fAc#N^fgl1w1cC?z5eOm>L?DPj5P={9K?H&b z1Q7@#5JVt|KoEf-0zm|V2m}!bA`nC%h(Hj5AOb-If(Qf=2qF+fAc#N^fgl1w1cC?z Z5eOm>L?DPj5P={9K?H&b{2z(He*@uu*opuE literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.pyi b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.pyi new file mode 100644 index 00000000..b0235555 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingft.pyi @@ -0,0 +1,5 @@ +from __future__ import annotations + +from typing import Any + +def __getattr__(name: str) -> Any: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingmath.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingmath.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..e28bcae67179665680c28ec02bbc9ab0998d528d GIT binary patch literal 72222 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingtk.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_imagingtk.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..a4392ca7097f278b1028dfbac0638674e3f8cf93 GIT binary patch literal 52636 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 (3, 10): + from typing import TypeGuard +else: + try: + from typing_extensions import TypeGuard + except ImportError: + from typing import Any + + class TypeGuard: # type: ignore[no-redef] + def __class_getitem__(cls, item: Any) -> type[bool]: + return bool + + +__all__ = ["TypeGuard"] diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_util.py b/dbdpy-env/lib/python3.9/site-packages/PIL/_util.py new file mode 100644 index 00000000..13f369cc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/_util.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +import os +from pathlib import Path +from typing import Any, NoReturn + +from ._typing import TypeGuard + + +def is_path(f: Any) -> TypeGuard[bytes | str | Path]: + return isinstance(f, (bytes, str, Path)) + + +def is_directory(f: Any) -> TypeGuard[bytes | str | Path]: + """Checks if an object is a string, and that it points to a directory.""" + return is_path(f) and os.path.isdir(f) + + +class DeferredError: + def __init__(self, ex: BaseException): + self.ex = ex + + def __getattr__(self, elt: str) -> NoReturn: + raise self.ex + + @staticmethod + def new(ex: BaseException) -> Any: + """ + Creates an object that raises the wrapped exception ``ex`` when used, + and casts it to :py:obj:`~typing.Any` type. + """ + return DeferredError(ex) diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_version.py b/dbdpy-env/lib/python3.9/site-packages/PIL/_version.py new file mode 100644 index 00000000..1018b96b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/PIL/_version.py @@ -0,0 +1,4 @@ +# Master version for Pillow +from __future__ import annotations + +__version__ = "10.2.0" diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/_webp.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/PIL/_webp.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..eb7d6ded61214b63bb69ced97def46fc11b8ac87 GIT binary patch literal 76864 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.5.6 for python 3.2/3.3 (older versions fail +to find the magic string, so _ARGCOMPLETE env. var is never set, and +this does not need special code). + +Function try_argcomplete(parser) should be called directly before +the call to ArgumentParser.parse_args(). + +The filescompleter is what you normally would use on the positional +arguments specification, in order to get "dirname/" after "dirn" +instead of the default "dirname ": + + optparser.add_argument(Config._file_or_dir, nargs='*').completer=filescompleter + +Other, application specific, completers should go in the file +doing the add_argument calls as they need to be specified as .completer +attributes as well. (If argcomplete is not installed, the function the +attribute points to will not be used). + +SPEEDUP +======= + +The generic argcomplete script for bash-completion +(/etc/bash_completion.d/python-argcomplete.sh) +uses a python program to determine startup script generated by pip. +You can speed up completion somewhat by changing this script to include + # PYTHON_ARGCOMPLETE_OK +so the python-argcomplete-check-easy-install-script does not +need to be called to find the entry point of the code and see if that is +marked with PYTHON_ARGCOMPLETE_OK. + +INSTALL/DEBUGGING +================= + +To include this support in another application that has setup.py generated +scripts: + +- Add the line: + # PYTHON_ARGCOMPLETE_OK + near the top of the main python entry point. + +- Include in the file calling parse_args(): + from _argcomplete import try_argcomplete, filescompleter + Call try_argcomplete just before parse_args(), and optionally add + filescompleter to the positional arguments' add_argument(). + +If things do not work right away: + +- Switch on argcomplete debugging with (also helpful when doing custom + completers): + export _ARC_DEBUG=1 + +- Run: + python-argcomplete-check-easy-install-script $(which appname) + echo $? + will echo 0 if the magic line has been found, 1 if not. + +- Sometimes it helps to find early on errors using: + _ARGCOMPLETE=1 _ARC_DEBUG=1 appname + which should throw a KeyError: 'COMPLINE' (which is properly set by the + global argcomplete script). +""" +import argparse +import os +import sys +from glob import glob +from typing import Any +from typing import List +from typing import Optional + + +class FastFilesCompleter: + """Fast file completer class.""" + + def __init__(self, directories: bool = True) -> None: + self.directories = directories + + def __call__(self, prefix: str, **kwargs: Any) -> List[str]: + # Only called on non option completions. + if os.sep in prefix[1:]: + prefix_dir = len(os.path.dirname(prefix) + os.sep) + else: + prefix_dir = 0 + completion = [] + globbed = [] + if "*" not in prefix and "?" not in prefix: + # We are on unix, otherwise no bash. + if not prefix or prefix[-1] == os.sep: + globbed.extend(glob(prefix + ".*")) + prefix += "*" + globbed.extend(glob(prefix)) + for x in sorted(globbed): + if os.path.isdir(x): + x += "/" + # Append stripping the prefix (like bash, not like compgen). + completion.append(x[prefix_dir:]) + return completion + + +if os.environ.get("_ARGCOMPLETE"): + try: + import argcomplete.completers + except ImportError: + sys.exit(-1) + filescompleter: Optional[FastFilesCompleter] = FastFilesCompleter() + + def try_argcomplete(parser: argparse.ArgumentParser) -> None: + argcomplete.autocomplete(parser, always_complete_options=False) + +else: + + def try_argcomplete(parser: argparse.ArgumentParser) -> None: + pass + + filescompleter = None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/__init__.py new file mode 100644 index 00000000..511d0dde --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/__init__.py @@ -0,0 +1,22 @@ +"""Python inspection/code generation API.""" +from .code import Code +from .code import ExceptionInfo +from .code import filter_traceback +from .code import Frame +from .code import getfslineno +from .code import Traceback +from .code import TracebackEntry +from .source import getrawcode +from .source import Source + +__all__ = [ + "Code", + "ExceptionInfo", + "filter_traceback", + "Frame", + "getfslineno", + "getrawcode", + "Traceback", + "TracebackEntry", + "Source", +] diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/code.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/code.py new file mode 100644 index 00000000..9b051332 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/code.py @@ -0,0 +1,1337 @@ +import ast +import dataclasses +import inspect +import os +import re +import sys +import traceback +from inspect import CO_VARARGS +from inspect import CO_VARKEYWORDS +from io import StringIO +from pathlib import Path +from traceback import format_exception_only +from types import CodeType +from types import FrameType +from types import TracebackType +from typing import Any +from typing import Callable +from typing import ClassVar +from typing import Dict +from typing import Generic +from typing import Iterable +from typing import List +from typing import Mapping +from typing import Optional +from typing import overload +from typing import Pattern +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +import pluggy + +import _pytest +from _pytest._code.source import findsource +from _pytest._code.source import getrawcode +from _pytest._code.source import getstatementrange_ast +from _pytest._code.source import Source +from _pytest._io import TerminalWriter +from _pytest._io.saferepr import safeformat +from _pytest._io.saferepr import saferepr +from _pytest.compat import final +from _pytest.compat import get_real_func +from _pytest.deprecated import check_ispytest +from _pytest.pathlib import absolutepath +from _pytest.pathlib import bestrelpath + +if TYPE_CHECKING: + from typing_extensions import Final + from typing_extensions import Literal + from typing_extensions import SupportsIndex + + _TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] + +if sys.version_info[:2] < (3, 11): + from exceptiongroup import BaseExceptionGroup + + +class Code: + """Wrapper around Python code objects.""" + + __slots__ = ("raw",) + + def __init__(self, obj: CodeType) -> None: + self.raw = obj + + @classmethod + def from_function(cls, obj: object) -> "Code": + return cls(getrawcode(obj)) + + def __eq__(self, other): + return self.raw == other.raw + + # Ignore type because of https://github.com/python/mypy/issues/4266. + __hash__ = None # type: ignore + + @property + def firstlineno(self) -> int: + return self.raw.co_firstlineno - 1 + + @property + def name(self) -> str: + return self.raw.co_name + + @property + def path(self) -> Union[Path, str]: + """Return a path object pointing to source code, or an ``str`` in + case of ``OSError`` / non-existing file.""" + if not self.raw.co_filename: + return "" + try: + p = absolutepath(self.raw.co_filename) + # maybe don't try this checking + if not p.exists(): + raise OSError("path check failed.") + return p + except OSError: + # XXX maybe try harder like the weird logic + # in the standard lib [linecache.updatecache] does? + return self.raw.co_filename + + @property + def fullsource(self) -> Optional["Source"]: + """Return a _pytest._code.Source object for the full source file of the code.""" + full, _ = findsource(self.raw) + return full + + def source(self) -> "Source": + """Return a _pytest._code.Source object for the code object's source only.""" + # return source only for that part of code + return Source(self.raw) + + def getargs(self, var: bool = False) -> Tuple[str, ...]: + """Return a tuple with the argument names for the code object. + + If 'var' is set True also return the names of the variable and + keyword arguments when present. + """ + # Handy shortcut for getting args. + raw = self.raw + argcount = raw.co_argcount + if var: + argcount += raw.co_flags & CO_VARARGS + argcount += raw.co_flags & CO_VARKEYWORDS + return raw.co_varnames[:argcount] + + +class Frame: + """Wrapper around a Python frame holding f_locals and f_globals + in which expressions can be evaluated.""" + + __slots__ = ("raw",) + + def __init__(self, frame: FrameType) -> None: + self.raw = frame + + @property + def lineno(self) -> int: + return self.raw.f_lineno - 1 + + @property + def f_globals(self) -> Dict[str, Any]: + return self.raw.f_globals + + @property + def f_locals(self) -> Dict[str, Any]: + return self.raw.f_locals + + @property + def code(self) -> Code: + return Code(self.raw.f_code) + + @property + def statement(self) -> "Source": + """Statement this frame is at.""" + if self.code.fullsource is None: + return Source("") + return self.code.fullsource.getstatement(self.lineno) + + def eval(self, code, **vars): + """Evaluate 'code' in the frame. + + 'vars' are optional additional local variables. + + Returns the result of the evaluation. + """ + f_locals = self.f_locals.copy() + f_locals.update(vars) + return eval(code, self.f_globals, f_locals) + + def repr(self, object: object) -> str: + """Return a 'safe' (non-recursive, one-line) string repr for 'object'.""" + return saferepr(object) + + def getargs(self, var: bool = False): + """Return a list of tuples (name, value) for all arguments. + + If 'var' is set True, also include the variable and keyword arguments + when present. + """ + retval = [] + for arg in self.code.getargs(var): + try: + retval.append((arg, self.f_locals[arg])) + except KeyError: + pass # this can occur when using Psyco + return retval + + +class TracebackEntry: + """A single entry in a Traceback.""" + + __slots__ = ("_rawentry", "_repr_style") + + def __init__( + self, + rawentry: TracebackType, + repr_style: Optional['Literal["short", "long"]'] = None, + ) -> None: + self._rawentry: "Final" = rawentry + self._repr_style: "Final" = repr_style + + def with_repr_style( + self, repr_style: Optional['Literal["short", "long"]'] + ) -> "TracebackEntry": + return TracebackEntry(self._rawentry, repr_style) + + @property + def lineno(self) -> int: + return self._rawentry.tb_lineno - 1 + + @property + def frame(self) -> Frame: + return Frame(self._rawentry.tb_frame) + + @property + def relline(self) -> int: + return self.lineno - self.frame.code.firstlineno + + def __repr__(self) -> str: + return "" % (self.frame.code.path, self.lineno + 1) + + @property + def statement(self) -> "Source": + """_pytest._code.Source object for the current statement.""" + source = self.frame.code.fullsource + assert source is not None + return source.getstatement(self.lineno) + + @property + def path(self) -> Union[Path, str]: + """Path to the source code.""" + return self.frame.code.path + + @property + def locals(self) -> Dict[str, Any]: + """Locals of underlying frame.""" + return self.frame.f_locals + + def getfirstlinesource(self) -> int: + return self.frame.code.firstlineno + + def getsource( + self, astcache: Optional[Dict[Union[str, Path], ast.AST]] = None + ) -> Optional["Source"]: + """Return failing source code.""" + # we use the passed in astcache to not reparse asttrees + # within exception info printing + source = self.frame.code.fullsource + if source is None: + return None + key = astnode = None + if astcache is not None: + key = self.frame.code.path + if key is not None: + astnode = astcache.get(key, None) + start = self.getfirstlinesource() + try: + astnode, _, end = getstatementrange_ast( + self.lineno, source, astnode=astnode + ) + except SyntaxError: + end = self.lineno + 1 + else: + if key is not None and astcache is not None: + astcache[key] = astnode + return source[start:end] + + source = property(getsource) + + def ishidden(self, excinfo: Optional["ExceptionInfo[BaseException]"]) -> bool: + """Return True if the current frame has a var __tracebackhide__ + resolving to True. + + If __tracebackhide__ is a callable, it gets called with the + ExceptionInfo instance and can decide whether to hide the traceback. + + Mostly for internal use. + """ + tbh: Union[ + bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool] + ] = False + for maybe_ns_dct in (self.frame.f_locals, self.frame.f_globals): + # in normal cases, f_locals and f_globals are dictionaries + # however via `exec(...)` / `eval(...)` they can be other types + # (even incorrect types!). + # as such, we suppress all exceptions while accessing __tracebackhide__ + try: + tbh = maybe_ns_dct["__tracebackhide__"] + except Exception: + pass + else: + break + if tbh and callable(tbh): + return tbh(excinfo) + return tbh + + def __str__(self) -> str: + name = self.frame.code.name + try: + line = str(self.statement).lstrip() + except KeyboardInterrupt: + raise + except BaseException: + line = "???" + # This output does not quite match Python's repr for traceback entries, + # but changing it to do so would break certain plugins. See + # https://github.com/pytest-dev/pytest/pull/7535/ for details. + return " File %r:%d in %s\n %s\n" % ( + str(self.path), + self.lineno + 1, + name, + line, + ) + + @property + def name(self) -> str: + """co_name of underlying code.""" + return self.frame.code.raw.co_name + + +class Traceback(List[TracebackEntry]): + """Traceback objects encapsulate and offer higher level access to Traceback entries.""" + + def __init__( + self, + tb: Union[TracebackType, Iterable[TracebackEntry]], + ) -> None: + """Initialize from given python traceback object and ExceptionInfo.""" + if isinstance(tb, TracebackType): + + def f(cur: TracebackType) -> Iterable[TracebackEntry]: + cur_: Optional[TracebackType] = cur + while cur_ is not None: + yield TracebackEntry(cur_) + cur_ = cur_.tb_next + + super().__init__(f(tb)) + else: + super().__init__(tb) + + def cut( + self, + path: Optional[Union["os.PathLike[str]", str]] = None, + lineno: Optional[int] = None, + firstlineno: Optional[int] = None, + excludepath: Optional["os.PathLike[str]"] = None, + ) -> "Traceback": + """Return a Traceback instance wrapping part of this Traceback. + + By providing any combination of path, lineno and firstlineno, the + first frame to start the to-be-returned traceback is determined. + + This allows cutting the first part of a Traceback instance e.g. + for formatting reasons (removing some uninteresting bits that deal + with handling of the exception/traceback). + """ + path_ = None if path is None else os.fspath(path) + excludepath_ = None if excludepath is None else os.fspath(excludepath) + for x in self: + code = x.frame.code + codepath = code.path + if path is not None and str(codepath) != path_: + continue + if ( + excludepath is not None + and isinstance(codepath, Path) + and excludepath_ in (str(p) for p in codepath.parents) # type: ignore[operator] + ): + continue + if lineno is not None and x.lineno != lineno: + continue + if firstlineno is not None and x.frame.code.firstlineno != firstlineno: + continue + return Traceback(x._rawentry) + return self + + @overload + def __getitem__(self, key: "SupportsIndex") -> TracebackEntry: + ... + + @overload + def __getitem__(self, key: slice) -> "Traceback": + ... + + def __getitem__( + self, key: Union["SupportsIndex", slice] + ) -> Union[TracebackEntry, "Traceback"]: + if isinstance(key, slice): + return self.__class__(super().__getitem__(key)) + else: + return super().__getitem__(key) + + def filter( + self, + # TODO(py38): change to positional only. + _excinfo_or_fn: Union[ + "ExceptionInfo[BaseException]", + Callable[[TracebackEntry], bool], + ], + ) -> "Traceback": + """Return a Traceback instance with certain items removed. + + If the filter is an `ExceptionInfo`, removes all the ``TracebackEntry``s + which are hidden (see ishidden() above). + + Otherwise, the filter is a function that gets a single argument, a + ``TracebackEntry`` instance, and should return True when the item should + be added to the ``Traceback``, False when not. + """ + if isinstance(_excinfo_or_fn, ExceptionInfo): + fn = lambda x: not x.ishidden(_excinfo_or_fn) # noqa: E731 + else: + fn = _excinfo_or_fn + return Traceback(filter(fn, self)) + + def recursionindex(self) -> Optional[int]: + """Return the index of the frame/TracebackEntry where recursion originates if + appropriate, None if no recursion occurred.""" + cache: Dict[Tuple[Any, int, int], List[Dict[str, Any]]] = {} + for i, entry in enumerate(self): + # id for the code.raw is needed to work around + # the strange metaprogramming in the decorator lib from pypi + # which generates code objects that have hash/value equality + # XXX needs a test + key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno + # print "checking for recursion at", key + values = cache.setdefault(key, []) + if values: + f = entry.frame + loc = f.f_locals + for otherloc in values: + if otherloc == loc: + return i + values.append(entry.frame.f_locals) + return None + + +E = TypeVar("E", bound=BaseException, covariant=True) + + +@final +@dataclasses.dataclass +class ExceptionInfo(Generic[E]): + """Wraps sys.exc_info() objects and offers help for navigating the traceback.""" + + _assert_start_repr: ClassVar = "AssertionError('assert " + + _excinfo: Optional[Tuple[Type["E"], "E", TracebackType]] + _striptext: str + _traceback: Optional[Traceback] + + def __init__( + self, + excinfo: Optional[Tuple[Type["E"], "E", TracebackType]], + striptext: str = "", + traceback: Optional[Traceback] = None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._excinfo = excinfo + self._striptext = striptext + self._traceback = traceback + + @classmethod + def from_exception( + cls, + # Ignoring error: "Cannot use a covariant type variable as a parameter". + # This is OK to ignore because this class is (conceptually) readonly. + # See https://github.com/python/mypy/issues/7049. + exception: E, # type: ignore[misc] + exprinfo: Optional[str] = None, + ) -> "ExceptionInfo[E]": + """Return an ExceptionInfo for an existing exception. + + The exception must have a non-``None`` ``__traceback__`` attribute, + otherwise this function fails with an assertion error. This means that + the exception must have been raised, or added a traceback with the + :py:meth:`~BaseException.with_traceback()` method. + + :param exprinfo: + A text string helping to determine if we should strip + ``AssertionError`` from the output. Defaults to the exception + message/``__str__()``. + + .. versionadded:: 7.4 + """ + assert ( + exception.__traceback__ + ), "Exceptions passed to ExcInfo.from_exception(...) must have a non-None __traceback__." + exc_info = (type(exception), exception, exception.__traceback__) + return cls.from_exc_info(exc_info, exprinfo) + + @classmethod + def from_exc_info( + cls, + exc_info: Tuple[Type[E], E, TracebackType], + exprinfo: Optional[str] = None, + ) -> "ExceptionInfo[E]": + """Like :func:`from_exception`, but using old-style exc_info tuple.""" + _striptext = "" + if exprinfo is None and isinstance(exc_info[1], AssertionError): + exprinfo = getattr(exc_info[1], "msg", None) + if exprinfo is None: + exprinfo = saferepr(exc_info[1]) + if exprinfo and exprinfo.startswith(cls._assert_start_repr): + _striptext = "AssertionError: " + + return cls(exc_info, _striptext, _ispytest=True) + + @classmethod + def from_current( + cls, exprinfo: Optional[str] = None + ) -> "ExceptionInfo[BaseException]": + """Return an ExceptionInfo matching the current traceback. + + .. warning:: + + Experimental API + + :param exprinfo: + A text string helping to determine if we should strip + ``AssertionError`` from the output. Defaults to the exception + message/``__str__()``. + """ + tup = sys.exc_info() + assert tup[0] is not None, "no current exception" + assert tup[1] is not None, "no current exception" + assert tup[2] is not None, "no current exception" + exc_info = (tup[0], tup[1], tup[2]) + return ExceptionInfo.from_exc_info(exc_info, exprinfo) + + @classmethod + def for_later(cls) -> "ExceptionInfo[E]": + """Return an unfilled ExceptionInfo.""" + return cls(None, _ispytest=True) + + def fill_unfilled(self, exc_info: Tuple[Type[E], E, TracebackType]) -> None: + """Fill an unfilled ExceptionInfo created with ``for_later()``.""" + assert self._excinfo is None, "ExceptionInfo was already filled" + self._excinfo = exc_info + + @property + def type(self) -> Type[E]: + """The exception class.""" + assert ( + self._excinfo is not None + ), ".type can only be used after the context manager exits" + return self._excinfo[0] + + @property + def value(self) -> E: + """The exception value.""" + assert ( + self._excinfo is not None + ), ".value can only be used after the context manager exits" + return self._excinfo[1] + + @property + def tb(self) -> TracebackType: + """The exception raw traceback.""" + assert ( + self._excinfo is not None + ), ".tb can only be used after the context manager exits" + return self._excinfo[2] + + @property + def typename(self) -> str: + """The type name of the exception.""" + assert ( + self._excinfo is not None + ), ".typename can only be used after the context manager exits" + return self.type.__name__ + + @property + def traceback(self) -> Traceback: + """The traceback.""" + if self._traceback is None: + self._traceback = Traceback(self.tb) + return self._traceback + + @traceback.setter + def traceback(self, value: Traceback) -> None: + self._traceback = value + + def __repr__(self) -> str: + if self._excinfo is None: + return "" + return "<{} {} tblen={}>".format( + self.__class__.__name__, saferepr(self._excinfo[1]), len(self.traceback) + ) + + def exconly(self, tryshort: bool = False) -> str: + """Return the exception as a string. + + When 'tryshort' resolves to True, and the exception is an + AssertionError, only the actual exception part of the exception + representation is returned (so 'AssertionError: ' is removed from + the beginning). + """ + lines = format_exception_only(self.type, self.value) + text = "".join(lines) + text = text.rstrip() + if tryshort: + if text.startswith(self._striptext): + text = text[len(self._striptext) :] + return text + + def errisinstance( + self, exc: Union[Type[BaseException], Tuple[Type[BaseException], ...]] + ) -> bool: + """Return True if the exception is an instance of exc. + + Consider using ``isinstance(excinfo.value, exc)`` instead. + """ + return isinstance(self.value, exc) + + def _getreprcrash(self) -> Optional["ReprFileLocation"]: + # Find last non-hidden traceback entry that led to the exception of the + # traceback, or None if all hidden. + for i in range(-1, -len(self.traceback) - 1, -1): + entry = self.traceback[i] + if not entry.ishidden(self): + path, lineno = entry.frame.code.raw.co_filename, entry.lineno + exconly = self.exconly(tryshort=True) + return ReprFileLocation(path, lineno + 1, exconly) + return None + + def getrepr( + self, + showlocals: bool = False, + style: "_TracebackStyle" = "long", + abspath: bool = False, + tbfilter: Union[ + bool, Callable[["ExceptionInfo[BaseException]"], Traceback] + ] = True, + funcargs: bool = False, + truncate_locals: bool = True, + chain: bool = True, + ) -> Union["ReprExceptionInfo", "ExceptionChainRepr"]: + """Return str()able representation of this exception info. + + :param bool showlocals: + Show locals per traceback entry. + Ignored if ``style=="native"``. + + :param str style: + long|short|line|no|native|value traceback style. + + :param bool abspath: + If paths should be changed to absolute or left unchanged. + + :param tbfilter: + A filter for traceback entries. + + * If false, don't hide any entries. + * If true, hide internal entries and entries that contain a local + variable ``__tracebackhide__ = True``. + * If a callable, delegates the filtering to the callable. + + Ignored if ``style`` is ``"native"``. + + :param bool funcargs: + Show fixtures ("funcargs" for legacy purposes) per traceback entry. + + :param bool truncate_locals: + With ``showlocals==True``, make sure locals can be safely represented as strings. + + :param bool chain: + If chained exceptions in Python 3 should be shown. + + .. versionchanged:: 3.9 + + Added the ``chain`` parameter. + """ + if style == "native": + return ReprExceptionInfo( + reprtraceback=ReprTracebackNative( + traceback.format_exception( + self.type, + self.value, + self.traceback[0]._rawentry if self.traceback else None, + ) + ), + reprcrash=self._getreprcrash(), + ) + + fmt = FormattedExcinfo( + showlocals=showlocals, + style=style, + abspath=abspath, + tbfilter=tbfilter, + funcargs=funcargs, + truncate_locals=truncate_locals, + chain=chain, + ) + return fmt.repr_excinfo(self) + + def match(self, regexp: Union[str, Pattern[str]]) -> "Literal[True]": + """Check whether the regular expression `regexp` matches the string + representation of the exception using :func:`python:re.search`. + + If it matches `True` is returned, otherwise an `AssertionError` is raised. + """ + __tracebackhide__ = True + value = str(self.value) + msg = f"Regex pattern did not match.\n Regex: {regexp!r}\n Input: {value!r}" + if regexp == value: + msg += "\n Did you mean to `re.escape()` the regex?" + assert re.search(regexp, value), msg + # Return True to allow for "assert excinfo.match()". + return True + + +@dataclasses.dataclass +class FormattedExcinfo: + """Presenting information about failing Functions and Generators.""" + + # for traceback entries + flow_marker: ClassVar = ">" + fail_marker: ClassVar = "E" + + showlocals: bool = False + style: "_TracebackStyle" = "long" + abspath: bool = True + tbfilter: Union[bool, Callable[[ExceptionInfo[BaseException]], Traceback]] = True + funcargs: bool = False + truncate_locals: bool = True + chain: bool = True + astcache: Dict[Union[str, Path], ast.AST] = dataclasses.field( + default_factory=dict, init=False, repr=False + ) + + def _getindent(self, source: "Source") -> int: + # Figure out indent for the given source. + try: + s = str(source.getstatement(len(source) - 1)) + except KeyboardInterrupt: + raise + except BaseException: + try: + s = str(source[-1]) + except KeyboardInterrupt: + raise + except BaseException: + return 0 + return 4 + (len(s) - len(s.lstrip())) + + def _getentrysource(self, entry: TracebackEntry) -> Optional["Source"]: + source = entry.getsource(self.astcache) + if source is not None: + source = source.deindent() + return source + + def repr_args(self, entry: TracebackEntry) -> Optional["ReprFuncArgs"]: + if self.funcargs: + args = [] + for argname, argvalue in entry.frame.getargs(var=True): + args.append((argname, saferepr(argvalue))) + return ReprFuncArgs(args) + return None + + def get_source( + self, + source: Optional["Source"], + line_index: int = -1, + excinfo: Optional[ExceptionInfo[BaseException]] = None, + short: bool = False, + ) -> List[str]: + """Return formatted and marked up source lines.""" + lines = [] + if source is not None and line_index < 0: + line_index += len(source) + if source is None or line_index >= len(source.lines) or line_index < 0: + # `line_index` could still be outside `range(len(source.lines))` if + # we're processing AST with pathological position attributes. + source = Source("???") + line_index = 0 + space_prefix = " " + if short: + lines.append(space_prefix + source.lines[line_index].strip()) + else: + for line in source.lines[:line_index]: + lines.append(space_prefix + line) + lines.append(self.flow_marker + " " + source.lines[line_index]) + for line in source.lines[line_index + 1 :]: + lines.append(space_prefix + line) + if excinfo is not None: + indent = 4 if short else self._getindent(source) + lines.extend(self.get_exconly(excinfo, indent=indent, markall=True)) + return lines + + def get_exconly( + self, + excinfo: ExceptionInfo[BaseException], + indent: int = 4, + markall: bool = False, + ) -> List[str]: + lines = [] + indentstr = " " * indent + # Get the real exception information out. + exlines = excinfo.exconly(tryshort=True).split("\n") + failindent = self.fail_marker + indentstr[1:] + for line in exlines: + lines.append(failindent + line) + if not markall: + failindent = indentstr + return lines + + def repr_locals(self, locals: Mapping[str, object]) -> Optional["ReprLocals"]: + if self.showlocals: + lines = [] + keys = [loc for loc in locals if loc[0] != "@"] + keys.sort() + for name in keys: + value = locals[name] + if name == "__builtins__": + lines.append("__builtins__ = ") + else: + # This formatting could all be handled by the + # _repr() function, which is only reprlib.Repr in + # disguise, so is very configurable. + if self.truncate_locals: + str_repr = saferepr(value) + else: + str_repr = safeformat(value) + # if len(str_repr) < 70 or not isinstance(value, (list, tuple, dict)): + lines.append(f"{name:<10} = {str_repr}") + # else: + # self._line("%-10s =\\" % (name,)) + # # XXX + # pprint.pprint(value, stream=self.excinfowriter) + return ReprLocals(lines) + return None + + def repr_traceback_entry( + self, + entry: Optional[TracebackEntry], + excinfo: Optional[ExceptionInfo[BaseException]] = None, + ) -> "ReprEntry": + lines: List[str] = [] + style = ( + entry._repr_style + if entry is not None and entry._repr_style is not None + else self.style + ) + if style in ("short", "long") and entry is not None: + source = self._getentrysource(entry) + if source is None: + source = Source("???") + line_index = 0 + else: + line_index = entry.lineno - entry.getfirstlinesource() + short = style == "short" + reprargs = self.repr_args(entry) if not short else None + s = self.get_source(source, line_index, excinfo, short=short) + lines.extend(s) + if short: + message = "in %s" % (entry.name) + else: + message = excinfo and excinfo.typename or "" + entry_path = entry.path + path = self._makepath(entry_path) + reprfileloc = ReprFileLocation(path, entry.lineno + 1, message) + localsrepr = self.repr_locals(entry.locals) + return ReprEntry(lines, reprargs, localsrepr, reprfileloc, style) + elif style == "value": + if excinfo: + lines.extend(str(excinfo.value).split("\n")) + return ReprEntry(lines, None, None, None, style) + else: + if excinfo: + lines.extend(self.get_exconly(excinfo, indent=4)) + return ReprEntry(lines, None, None, None, style) + + def _makepath(self, path: Union[Path, str]) -> str: + if not self.abspath and isinstance(path, Path): + try: + np = bestrelpath(Path.cwd(), path) + except OSError: + return str(path) + if len(np) < len(str(path)): + return np + return str(path) + + def repr_traceback(self, excinfo: ExceptionInfo[BaseException]) -> "ReprTraceback": + traceback = excinfo.traceback + if callable(self.tbfilter): + traceback = self.tbfilter(excinfo) + elif self.tbfilter: + traceback = traceback.filter(excinfo) + + if isinstance(excinfo.value, RecursionError): + traceback, extraline = self._truncate_recursive_traceback(traceback) + else: + extraline = None + + if not traceback: + if extraline is None: + extraline = "All traceback entries are hidden. Pass `--full-trace` to see hidden and internal frames." + entries = [self.repr_traceback_entry(None, excinfo)] + return ReprTraceback(entries, extraline, style=self.style) + + last = traceback[-1] + if self.style == "value": + entries = [self.repr_traceback_entry(last, excinfo)] + return ReprTraceback(entries, None, style=self.style) + + entries = [ + self.repr_traceback_entry(entry, excinfo if last == entry else None) + for entry in traceback + ] + return ReprTraceback(entries, extraline, style=self.style) + + def _truncate_recursive_traceback( + self, traceback: Traceback + ) -> Tuple[Traceback, Optional[str]]: + """Truncate the given recursive traceback trying to find the starting + point of the recursion. + + The detection is done by going through each traceback entry and + finding the point in which the locals of the frame are equal to the + locals of a previous frame (see ``recursionindex()``). + + Handle the situation where the recursion process might raise an + exception (for example comparing numpy arrays using equality raises a + TypeError), in which case we do our best to warn the user of the + error and show a limited traceback. + """ + try: + recursionindex = traceback.recursionindex() + except Exception as e: + max_frames = 10 + extraline: Optional[str] = ( + "!!! Recursion error detected, but an error occurred locating the origin of recursion.\n" + " The following exception happened when comparing locals in the stack frame:\n" + " {exc_type}: {exc_msg}\n" + " Displaying first and last {max_frames} stack frames out of {total}." + ).format( + exc_type=type(e).__name__, + exc_msg=str(e), + max_frames=max_frames, + total=len(traceback), + ) + # Type ignored because adding two instances of a List subtype + # currently incorrectly has type List instead of the subtype. + traceback = traceback[:max_frames] + traceback[-max_frames:] # type: ignore + else: + if recursionindex is not None: + extraline = "!!! Recursion detected (same locals & position)" + traceback = traceback[: recursionindex + 1] + else: + extraline = None + + return traceback, extraline + + def repr_excinfo( + self, excinfo: ExceptionInfo[BaseException] + ) -> "ExceptionChainRepr": + repr_chain: List[ + Tuple[ReprTraceback, Optional[ReprFileLocation], Optional[str]] + ] = [] + e: Optional[BaseException] = excinfo.value + excinfo_: Optional[ExceptionInfo[BaseException]] = excinfo + descr = None + seen: Set[int] = set() + while e is not None and id(e) not in seen: + seen.add(id(e)) + + if excinfo_: + # Fall back to native traceback as a temporary workaround until + # full support for exception groups added to ExceptionInfo. + # See https://github.com/pytest-dev/pytest/issues/9159 + if isinstance(e, BaseExceptionGroup): + reprtraceback: Union[ + ReprTracebackNative, ReprTraceback + ] = ReprTracebackNative( + traceback.format_exception( + type(excinfo_.value), + excinfo_.value, + excinfo_.traceback[0]._rawentry, + ) + ) + else: + reprtraceback = self.repr_traceback(excinfo_) + reprcrash = excinfo_._getreprcrash() + else: + # Fallback to native repr if the exception doesn't have a traceback: + # ExceptionInfo objects require a full traceback to work. + reprtraceback = ReprTracebackNative( + traceback.format_exception(type(e), e, None) + ) + reprcrash = None + repr_chain += [(reprtraceback, reprcrash, descr)] + + if e.__cause__ is not None and self.chain: + e = e.__cause__ + excinfo_ = ExceptionInfo.from_exception(e) if e.__traceback__ else None + descr = "The above exception was the direct cause of the following exception:" + elif ( + e.__context__ is not None and not e.__suppress_context__ and self.chain + ): + e = e.__context__ + excinfo_ = ExceptionInfo.from_exception(e) if e.__traceback__ else None + descr = "During handling of the above exception, another exception occurred:" + else: + e = None + repr_chain.reverse() + return ExceptionChainRepr(repr_chain) + + +@dataclasses.dataclass(eq=False) +class TerminalRepr: + def __str__(self) -> str: + # FYI this is called from pytest-xdist's serialization of exception + # information. + io = StringIO() + tw = TerminalWriter(file=io) + self.toterminal(tw) + return io.getvalue().strip() + + def __repr__(self) -> str: + return f"<{self.__class__} instance at {id(self):0x}>" + + def toterminal(self, tw: TerminalWriter) -> None: + raise NotImplementedError() + + +# This class is abstract -- only subclasses are instantiated. +@dataclasses.dataclass(eq=False) +class ExceptionRepr(TerminalRepr): + # Provided by subclasses. + reprtraceback: "ReprTraceback" + reprcrash: Optional["ReprFileLocation"] + sections: List[Tuple[str, str, str]] = dataclasses.field( + init=False, default_factory=list + ) + + def addsection(self, name: str, content: str, sep: str = "-") -> None: + self.sections.append((name, content, sep)) + + def toterminal(self, tw: TerminalWriter) -> None: + for name, content, sep in self.sections: + tw.sep(sep, name) + tw.line(content) + + +@dataclasses.dataclass(eq=False) +class ExceptionChainRepr(ExceptionRepr): + chain: Sequence[Tuple["ReprTraceback", Optional["ReprFileLocation"], Optional[str]]] + + def __init__( + self, + chain: Sequence[ + Tuple["ReprTraceback", Optional["ReprFileLocation"], Optional[str]] + ], + ) -> None: + # reprcrash and reprtraceback of the outermost (the newest) exception + # in the chain. + super().__init__( + reprtraceback=chain[-1][0], + reprcrash=chain[-1][1], + ) + self.chain = chain + + def toterminal(self, tw: TerminalWriter) -> None: + for element in self.chain: + element[0].toterminal(tw) + if element[2] is not None: + tw.line("") + tw.line(element[2], yellow=True) + super().toterminal(tw) + + +@dataclasses.dataclass(eq=False) +class ReprExceptionInfo(ExceptionRepr): + reprtraceback: "ReprTraceback" + reprcrash: Optional["ReprFileLocation"] + + def toterminal(self, tw: TerminalWriter) -> None: + self.reprtraceback.toterminal(tw) + super().toterminal(tw) + + +@dataclasses.dataclass(eq=False) +class ReprTraceback(TerminalRepr): + reprentries: Sequence[Union["ReprEntry", "ReprEntryNative"]] + extraline: Optional[str] + style: "_TracebackStyle" + + entrysep: ClassVar = "_ " + + def toterminal(self, tw: TerminalWriter) -> None: + # The entries might have different styles. + for i, entry in enumerate(self.reprentries): + if entry.style == "long": + tw.line("") + entry.toterminal(tw) + if i < len(self.reprentries) - 1: + next_entry = self.reprentries[i + 1] + if ( + entry.style == "long" + or entry.style == "short" + and next_entry.style == "long" + ): + tw.sep(self.entrysep) + + if self.extraline: + tw.line(self.extraline) + + +class ReprTracebackNative(ReprTraceback): + def __init__(self, tblines: Sequence[str]) -> None: + self.reprentries = [ReprEntryNative(tblines)] + self.extraline = None + self.style = "native" + + +@dataclasses.dataclass(eq=False) +class ReprEntryNative(TerminalRepr): + lines: Sequence[str] + + style: ClassVar["_TracebackStyle"] = "native" + + def toterminal(self, tw: TerminalWriter) -> None: + tw.write("".join(self.lines)) + + +@dataclasses.dataclass(eq=False) +class ReprEntry(TerminalRepr): + lines: Sequence[str] + reprfuncargs: Optional["ReprFuncArgs"] + reprlocals: Optional["ReprLocals"] + reprfileloc: Optional["ReprFileLocation"] + style: "_TracebackStyle" + + def _write_entry_lines(self, tw: TerminalWriter) -> None: + """Write the source code portions of a list of traceback entries with syntax highlighting. + + Usually entries are lines like these: + + " x = 1" + "> assert x == 2" + "E assert 1 == 2" + + This function takes care of rendering the "source" portions of it (the lines without + the "E" prefix) using syntax highlighting, taking care to not highlighting the ">" + character, as doing so might break line continuations. + """ + + if not self.lines: + return + + # separate indents and source lines that are not failures: we want to + # highlight the code but not the indentation, which may contain markers + # such as "> assert 0" + fail_marker = f"{FormattedExcinfo.fail_marker} " + indent_size = len(fail_marker) + indents: List[str] = [] + source_lines: List[str] = [] + failure_lines: List[str] = [] + for index, line in enumerate(self.lines): + is_failure_line = line.startswith(fail_marker) + if is_failure_line: + # from this point on all lines are considered part of the failure + failure_lines.extend(self.lines[index:]) + break + else: + if self.style == "value": + source_lines.append(line) + else: + indents.append(line[:indent_size]) + source_lines.append(line[indent_size:]) + + tw._write_source(source_lines, indents) + + # failure lines are always completely red and bold + for line in failure_lines: + tw.line(line, bold=True, red=True) + + def toterminal(self, tw: TerminalWriter) -> None: + if self.style == "short": + if self.reprfileloc: + self.reprfileloc.toterminal(tw) + self._write_entry_lines(tw) + if self.reprlocals: + self.reprlocals.toterminal(tw, indent=" " * 8) + return + + if self.reprfuncargs: + self.reprfuncargs.toterminal(tw) + + self._write_entry_lines(tw) + + if self.reprlocals: + tw.line("") + self.reprlocals.toterminal(tw) + if self.reprfileloc: + if self.lines: + tw.line("") + self.reprfileloc.toterminal(tw) + + def __str__(self) -> str: + return "{}\n{}\n{}".format( + "\n".join(self.lines), self.reprlocals, self.reprfileloc + ) + + +@dataclasses.dataclass(eq=False) +class ReprFileLocation(TerminalRepr): + path: str + lineno: int + message: str + + def __post_init__(self) -> None: + self.path = str(self.path) + + def toterminal(self, tw: TerminalWriter) -> None: + # Filename and lineno output for each entry, using an output format + # that most editors understand. + msg = self.message + i = msg.find("\n") + if i != -1: + msg = msg[:i] + tw.write(self.path, bold=True, red=True) + tw.line(f":{self.lineno}: {msg}") + + +@dataclasses.dataclass(eq=False) +class ReprLocals(TerminalRepr): + lines: Sequence[str] + + def toterminal(self, tw: TerminalWriter, indent="") -> None: + for line in self.lines: + tw.line(indent + line) + + +@dataclasses.dataclass(eq=False) +class ReprFuncArgs(TerminalRepr): + args: Sequence[Tuple[str, object]] + + def toterminal(self, tw: TerminalWriter) -> None: + if self.args: + linesofar = "" + for name, value in self.args: + ns = f"{name} = {value}" + if len(ns) + len(linesofar) + 2 > tw.fullwidth: + if linesofar: + tw.line(linesofar) + linesofar = ns + else: + if linesofar: + linesofar += ", " + ns + else: + linesofar = ns + if linesofar: + tw.line(linesofar) + tw.line("") + + +def getfslineno(obj: object) -> Tuple[Union[str, Path], int]: + """Return source location (path, lineno) for the given object. + + If the source cannot be determined return ("", -1). + + The line number is 0-based. + """ + # xxx let decorators etc specify a sane ordering + # NOTE: this used to be done in _pytest.compat.getfslineno, initially added + # in 6ec13a2b9. It ("place_as") appears to be something very custom. + obj = get_real_func(obj) + if hasattr(obj, "place_as"): + obj = obj.place_as # type: ignore[attr-defined] + + try: + code = Code.from_function(obj) + except TypeError: + try: + fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type] + except TypeError: + return "", -1 + + fspath = fn and absolutepath(fn) or "" + lineno = -1 + if fspath: + try: + _, lineno = findsource(obj) + except OSError: + pass + return fspath, lineno + + return code.path, code.firstlineno + + +# Relative paths that we use to filter traceback entries from appearing to the user; +# see filter_traceback. +# note: if we need to add more paths than what we have now we should probably use a list +# for better maintenance. + +_PLUGGY_DIR = Path(pluggy.__file__.rstrip("oc")) +# pluggy is either a package or a single module depending on the version +if _PLUGGY_DIR.name == "__init__.py": + _PLUGGY_DIR = _PLUGGY_DIR.parent +_PYTEST_DIR = Path(_pytest.__file__).parent + + +def filter_traceback(entry: TracebackEntry) -> bool: + """Return True if a TracebackEntry instance should be included in tracebacks. + + We hide traceback entries of: + + * dynamically generated code (no code to show up for it); + * internal traceback from pytest or its internal libraries, py and pluggy. + """ + # entry.path might sometimes return a str object when the entry + # points to dynamically generated code. + # See https://bitbucket.org/pytest-dev/py/issues/71. + raw_filename = entry.frame.code.raw.co_filename + is_generated = "<" in raw_filename and ">" in raw_filename + if is_generated: + return False + + # entry.path might point to a non-existing file, in which case it will + # also return a str object. See #1133. + p = Path(entry.path) + + parents = p.parents + if _PLUGGY_DIR in parents: + return False + if _PYTEST_DIR in parents: + return False + + return True diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/source.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/source.py new file mode 100644 index 00000000..208cfb80 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/source.py @@ -0,0 +1,217 @@ +import ast +import inspect +import textwrap +import tokenize +import types +import warnings +from bisect import bisect_right +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Optional +from typing import overload +from typing import Tuple +from typing import Union + + +class Source: + """An immutable object holding a source code fragment. + + When using Source(...), the source lines are deindented. + """ + + def __init__(self, obj: object = None) -> None: + if not obj: + self.lines: List[str] = [] + elif isinstance(obj, Source): + self.lines = obj.lines + elif isinstance(obj, (tuple, list)): + self.lines = deindent(x.rstrip("\n") for x in obj) + elif isinstance(obj, str): + self.lines = deindent(obj.split("\n")) + else: + try: + rawcode = getrawcode(obj) + src = inspect.getsource(rawcode) + except TypeError: + src = inspect.getsource(obj) # type: ignore[arg-type] + self.lines = deindent(src.split("\n")) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Source): + return NotImplemented + return self.lines == other.lines + + # Ignore type because of https://github.com/python/mypy/issues/4266. + __hash__ = None # type: ignore + + @overload + def __getitem__(self, key: int) -> str: + ... + + @overload + def __getitem__(self, key: slice) -> "Source": + ... + + def __getitem__(self, key: Union[int, slice]) -> Union[str, "Source"]: + if isinstance(key, int): + return self.lines[key] + else: + if key.step not in (None, 1): + raise IndexError("cannot slice a Source with a step") + newsource = Source() + newsource.lines = self.lines[key.start : key.stop] + return newsource + + def __iter__(self) -> Iterator[str]: + return iter(self.lines) + + def __len__(self) -> int: + return len(self.lines) + + def strip(self) -> "Source": + """Return new Source object with trailing and leading blank lines removed.""" + start, end = 0, len(self) + while start < end and not self.lines[start].strip(): + start += 1 + while end > start and not self.lines[end - 1].strip(): + end -= 1 + source = Source() + source.lines[:] = self.lines[start:end] + return source + + def indent(self, indent: str = " " * 4) -> "Source": + """Return a copy of the source object with all lines indented by the + given indent-string.""" + newsource = Source() + newsource.lines = [(indent + line) for line in self.lines] + return newsource + + def getstatement(self, lineno: int) -> "Source": + """Return Source statement which contains the given linenumber + (counted from 0).""" + start, end = self.getstatementrange(lineno) + return self[start:end] + + def getstatementrange(self, lineno: int) -> Tuple[int, int]: + """Return (start, end) tuple which spans the minimal statement region + which containing the given lineno.""" + if not (0 <= lineno < len(self)): + raise IndexError("lineno out of range") + ast, start, end = getstatementrange_ast(lineno, self) + return start, end + + def deindent(self) -> "Source": + """Return a new Source object deindented.""" + newsource = Source() + newsource.lines[:] = deindent(self.lines) + return newsource + + def __str__(self) -> str: + return "\n".join(self.lines) + + +# +# helper functions +# + + +def findsource(obj) -> Tuple[Optional[Source], int]: + try: + sourcelines, lineno = inspect.findsource(obj) + except Exception: + return None, -1 + source = Source() + source.lines = [line.rstrip() for line in sourcelines] + return source, lineno + + +def getrawcode(obj: object, trycall: bool = True) -> types.CodeType: + """Return code object for given function.""" + try: + return obj.__code__ # type: ignore[attr-defined,no-any-return] + except AttributeError: + pass + if trycall: + call = getattr(obj, "__call__", None) + if call and not isinstance(obj, type): + return getrawcode(call, trycall=False) + raise TypeError(f"could not get code object for {obj!r}") + + +def deindent(lines: Iterable[str]) -> List[str]: + return textwrap.dedent("\n".join(lines)).splitlines() + + +def get_statement_startend2(lineno: int, node: ast.AST) -> Tuple[int, Optional[int]]: + # Flatten all statements and except handlers into one lineno-list. + # AST's line numbers start indexing at 1. + values: List[int] = [] + for x in ast.walk(node): + if isinstance(x, (ast.stmt, ast.ExceptHandler)): + # Before Python 3.8, the lineno of a decorated class or function pointed at the decorator. + # Since Python 3.8, the lineno points to the class/def, so need to include the decorators. + if isinstance(x, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): + for d in x.decorator_list: + values.append(d.lineno - 1) + values.append(x.lineno - 1) + for name in ("finalbody", "orelse"): + val: Optional[List[ast.stmt]] = getattr(x, name, None) + if val: + # Treat the finally/orelse part as its own statement. + values.append(val[0].lineno - 1 - 1) + values.sort() + insert_index = bisect_right(values, lineno) + start = values[insert_index - 1] + if insert_index >= len(values): + end = None + else: + end = values[insert_index] + return start, end + + +def getstatementrange_ast( + lineno: int, + source: Source, + assertion: bool = False, + astnode: Optional[ast.AST] = None, +) -> Tuple[ast.AST, int, int]: + if astnode is None: + content = str(source) + # See #4260: + # Don't produce duplicate warnings when compiling source to find AST. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + astnode = ast.parse(content, "source", "exec") + + start, end = get_statement_startend2(lineno, astnode) + # We need to correct the end: + # - ast-parsing strips comments + # - there might be empty lines + # - we might have lesser indented code blocks at the end + if end is None: + end = len(source.lines) + + if end > start + 1: + # Make sure we don't span differently indented code blocks + # by using the BlockFinder helper used which inspect.getsource() uses itself. + block_finder = inspect.BlockFinder() + # If we start with an indented line, put blockfinder to "started" mode. + block_finder.started = source.lines[start][0].isspace() + it = ((x + "\n") for x in source.lines[start:end]) + try: + for tok in tokenize.generate_tokens(lambda: next(it)): + block_finder.tokeneater(*tok) + except (inspect.EndOfBlock, IndentationError): + end = block_finder.last + start + except Exception: + pass + + # The end might still point to a comment or empty line, correct it. + while end: + line = source.lines[end - 1].lstrip() + if line.startswith("#") or not line: + end -= 1 + else: + break + return astnode, start, end diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/__init__.py new file mode 100644 index 00000000..db001e91 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/__init__.py @@ -0,0 +1,8 @@ +from .terminalwriter import get_terminal_width +from .terminalwriter import TerminalWriter + + +__all__ = [ + "TerminalWriter", + "get_terminal_width", +] diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/saferepr.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/saferepr.py new file mode 100644 index 00000000..c7018722 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/saferepr.py @@ -0,0 +1,180 @@ +import pprint +import reprlib +from typing import Any +from typing import Dict +from typing import IO +from typing import Optional + + +def _try_repr_or_str(obj: object) -> str: + try: + return repr(obj) + except (KeyboardInterrupt, SystemExit): + raise + except BaseException: + return f'{type(obj).__name__}("{obj}")' + + +def _format_repr_exception(exc: BaseException, obj: object) -> str: + try: + exc_info = _try_repr_or_str(exc) + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as exc: + exc_info = f"unpresentable exception ({_try_repr_or_str(exc)})" + return "<[{} raised in repr()] {} object at 0x{:x}>".format( + exc_info, type(obj).__name__, id(obj) + ) + + +def _ellipsize(s: str, maxsize: int) -> str: + if len(s) > maxsize: + i = max(0, (maxsize - 3) // 2) + j = max(0, maxsize - 3 - i) + return s[:i] + "..." + s[len(s) - j :] + return s + + +class SafeRepr(reprlib.Repr): + """ + repr.Repr that limits the resulting size of repr() and includes + information on exceptions raised during the call. + """ + + def __init__(self, maxsize: Optional[int], use_ascii: bool = False) -> None: + """ + :param maxsize: + If not None, will truncate the resulting repr to that specific size, using ellipsis + somewhere in the middle to hide the extra text. + If None, will not impose any size limits on the returning repr. + """ + super().__init__() + # ``maxstring`` is used by the superclass, and needs to be an int; using a + # very large number in case maxsize is None, meaning we want to disable + # truncation. + self.maxstring = maxsize if maxsize is not None else 1_000_000_000 + self.maxsize = maxsize + self.use_ascii = use_ascii + + def repr(self, x: object) -> str: + try: + if self.use_ascii: + s = ascii(x) + else: + s = super().repr(x) + + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as exc: + s = _format_repr_exception(exc, x) + if self.maxsize is not None: + s = _ellipsize(s, self.maxsize) + return s + + def repr_instance(self, x: object, level: int) -> str: + try: + s = repr(x) + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as exc: + s = _format_repr_exception(exc, x) + if self.maxsize is not None: + s = _ellipsize(s, self.maxsize) + return s + + +def safeformat(obj: object) -> str: + """Return a pretty printed string for the given object. + + Failing __repr__ functions of user instances will be represented + with a short exception info. + """ + try: + return pprint.pformat(obj) + except Exception as exc: + return _format_repr_exception(exc, obj) + + +# Maximum size of overall repr of objects to display during assertion errors. +DEFAULT_REPR_MAX_SIZE = 240 + + +def saferepr( + obj: object, maxsize: Optional[int] = DEFAULT_REPR_MAX_SIZE, use_ascii: bool = False +) -> str: + """Return a size-limited safe repr-string for the given object. + + Failing __repr__ functions of user instances will be represented + with a short exception info and 'saferepr' generally takes + care to never raise exceptions itself. + + This function is a wrapper around the Repr/reprlib functionality of the + stdlib. + """ + + return SafeRepr(maxsize, use_ascii).repr(obj) + + +def saferepr_unlimited(obj: object, use_ascii: bool = True) -> str: + """Return an unlimited-size safe repr-string for the given object. + + As with saferepr, failing __repr__ functions of user instances + will be represented with a short exception info. + + This function is a wrapper around simple repr. + + Note: a cleaner solution would be to alter ``saferepr``this way + when maxsize=None, but that might affect some other code. + """ + try: + if use_ascii: + return ascii(obj) + return repr(obj) + except Exception as exc: + return _format_repr_exception(exc, obj) + + +class AlwaysDispatchingPrettyPrinter(pprint.PrettyPrinter): + """PrettyPrinter that always dispatches (regardless of width).""" + + def _format( + self, + object: object, + stream: IO[str], + indent: int, + allowance: int, + context: Dict[int, Any], + level: int, + ) -> None: + # Type ignored because _dispatch is private. + p = self._dispatch.get(type(object).__repr__, None) # type: ignore[attr-defined] + + objid = id(object) + if objid in context or p is None: + # Type ignored because _format is private. + super()._format( # type: ignore[misc] + object, + stream, + indent, + allowance, + context, + level, + ) + return + + context[objid] = 1 + p(self, object, stream, indent, allowance, context, level + 1) + del context[objid] + + +def _pformat_dispatch( + object: object, + indent: int = 1, + width: int = 80, + depth: Optional[int] = None, + *, + compact: bool = False, +) -> str: + return AlwaysDispatchingPrettyPrinter( + indent=indent, width=width, depth=depth, compact=compact + ).pformat(object) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/terminalwriter.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/terminalwriter.py new file mode 100644 index 00000000..379035d8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/terminalwriter.py @@ -0,0 +1,233 @@ +"""Helper functions for writing to terminals and files.""" +import os +import shutil +import sys +from typing import Optional +from typing import Sequence +from typing import TextIO + +from .wcwidth import wcswidth +from _pytest.compat import final + + +# This code was initially copied from py 1.8.1, file _io/terminalwriter.py. + + +def get_terminal_width() -> int: + width, _ = shutil.get_terminal_size(fallback=(80, 24)) + + # The Windows get_terminal_size may be bogus, let's sanify a bit. + if width < 40: + width = 80 + + return width + + +def should_do_markup(file: TextIO) -> bool: + if os.environ.get("PY_COLORS") == "1": + return True + if os.environ.get("PY_COLORS") == "0": + return False + if "NO_COLOR" in os.environ: + return False + if "FORCE_COLOR" in os.environ: + return True + return ( + hasattr(file, "isatty") and file.isatty() and os.environ.get("TERM") != "dumb" + ) + + +@final +class TerminalWriter: + _esctable = dict( + black=30, + red=31, + green=32, + yellow=33, + blue=34, + purple=35, + cyan=36, + white=37, + Black=40, + Red=41, + Green=42, + Yellow=43, + Blue=44, + Purple=45, + Cyan=46, + White=47, + bold=1, + light=2, + blink=5, + invert=7, + ) + + def __init__(self, file: Optional[TextIO] = None) -> None: + if file is None: + file = sys.stdout + if hasattr(file, "isatty") and file.isatty() and sys.platform == "win32": + try: + import colorama + except ImportError: + pass + else: + file = colorama.AnsiToWin32(file).stream + assert file is not None + self._file = file + self.hasmarkup = should_do_markup(file) + self._current_line = "" + self._terminal_width: Optional[int] = None + self.code_highlight = True + + @property + def fullwidth(self) -> int: + if self._terminal_width is not None: + return self._terminal_width + return get_terminal_width() + + @fullwidth.setter + def fullwidth(self, value: int) -> None: + self._terminal_width = value + + @property + def width_of_current_line(self) -> int: + """Return an estimate of the width so far in the current line.""" + return wcswidth(self._current_line) + + def markup(self, text: str, **markup: bool) -> str: + for name in markup: + if name not in self._esctable: + raise ValueError(f"unknown markup: {name!r}") + if self.hasmarkup: + esc = [self._esctable[name] for name, on in markup.items() if on] + if esc: + text = "".join("\x1b[%sm" % cod for cod in esc) + text + "\x1b[0m" + return text + + def sep( + self, + sepchar: str, + title: Optional[str] = None, + fullwidth: Optional[int] = None, + **markup: bool, + ) -> None: + if fullwidth is None: + fullwidth = self.fullwidth + # The goal is to have the line be as long as possible + # under the condition that len(line) <= fullwidth. + if sys.platform == "win32": + # If we print in the last column on windows we are on a + # new line but there is no way to verify/neutralize this + # (we may not know the exact line width). + # So let's be defensive to avoid empty lines in the output. + fullwidth -= 1 + if title is not None: + # we want 2 + 2*len(fill) + len(title) <= fullwidth + # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth + # 2*len(sepchar)*N <= fullwidth - len(title) - 2 + # N <= (fullwidth - len(title) - 2) // (2*len(sepchar)) + N = max((fullwidth - len(title) - 2) // (2 * len(sepchar)), 1) + fill = sepchar * N + line = f"{fill} {title} {fill}" + else: + # we want len(sepchar)*N <= fullwidth + # i.e. N <= fullwidth // len(sepchar) + line = sepchar * (fullwidth // len(sepchar)) + # In some situations there is room for an extra sepchar at the right, + # in particular if we consider that with a sepchar like "_ " the + # trailing space is not important at the end of the line. + if len(line) + len(sepchar.rstrip()) <= fullwidth: + line += sepchar.rstrip() + + self.line(line, **markup) + + def write(self, msg: str, *, flush: bool = False, **markup: bool) -> None: + if msg: + current_line = msg.rsplit("\n", 1)[-1] + if "\n" in msg: + self._current_line = current_line + else: + self._current_line += current_line + + msg = self.markup(msg, **markup) + + try: + self._file.write(msg) + except UnicodeEncodeError: + # Some environments don't support printing general Unicode + # strings, due to misconfiguration or otherwise; in that case, + # print the string escaped to ASCII. + # When the Unicode situation improves we should consider + # letting the error propagate instead of masking it (see #7475 + # for one brief attempt). + msg = msg.encode("unicode-escape").decode("ascii") + self._file.write(msg) + + if flush: + self.flush() + + def line(self, s: str = "", **markup: bool) -> None: + self.write(s, **markup) + self.write("\n") + + def flush(self) -> None: + self._file.flush() + + def _write_source(self, lines: Sequence[str], indents: Sequence[str] = ()) -> None: + """Write lines of source code possibly highlighted. + + Keeping this private for now because the API is clunky. We should discuss how + to evolve the terminal writer so we can have more precise color support, for example + being able to write part of a line in one color and the rest in another, and so on. + """ + if indents and len(indents) != len(lines): + raise ValueError( + "indents size ({}) should have same size as lines ({})".format( + len(indents), len(lines) + ) + ) + if not indents: + indents = [""] * len(lines) + source = "\n".join(lines) + new_lines = self._highlight(source).splitlines() + for indent, new_line in zip(indents, new_lines): + self.line(indent + new_line) + + def _highlight(self, source: str) -> str: + """Highlight the given source code if we have markup support.""" + from _pytest.config.exceptions import UsageError + + if not self.hasmarkup or not self.code_highlight: + return source + try: + from pygments.formatters.terminal import TerminalFormatter + from pygments.lexers.python import PythonLexer + from pygments import highlight + import pygments.util + except ImportError: + return source + else: + try: + highlighted: str = highlight( + source, + PythonLexer(), + TerminalFormatter( + bg=os.getenv("PYTEST_THEME_MODE", "dark"), + style=os.getenv("PYTEST_THEME"), + ), + ) + return highlighted + except pygments.util.ClassNotFound: + raise UsageError( + "PYTEST_THEME environment variable had an invalid value: '{}'. " + "Only valid pygment styles are allowed.".format( + os.getenv("PYTEST_THEME") + ) + ) + except pygments.util.OptionError: + raise UsageError( + "PYTEST_THEME_MODE environment variable had an invalid value: '{}'. " + "The only allowed values are 'dark' and 'light'.".format( + os.getenv("PYTEST_THEME_MODE") + ) + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/wcwidth.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/wcwidth.py new file mode 100644 index 00000000..e5c7bf4d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/wcwidth.py @@ -0,0 +1,55 @@ +import unicodedata +from functools import lru_cache + + +@lru_cache(100) +def wcwidth(c: str) -> int: + """Determine how many columns are needed to display a character in a terminal. + + Returns -1 if the character is not printable. + Returns 0, 1 or 2 for other characters. + """ + o = ord(c) + + # ASCII fast path. + if 0x20 <= o < 0x07F: + return 1 + + # Some Cf/Zp/Zl characters which should be zero-width. + if ( + o == 0x0000 + or 0x200B <= o <= 0x200F + or 0x2028 <= o <= 0x202E + or 0x2060 <= o <= 0x2063 + ): + return 0 + + category = unicodedata.category(c) + + # Control characters. + if category == "Cc": + return -1 + + # Combining characters with zero width. + if category in ("Me", "Mn"): + return 0 + + # Full/Wide east asian characters. + if unicodedata.east_asian_width(c) in ("F", "W"): + return 2 + + return 1 + + +def wcswidth(s: str) -> int: + """Determine how many columns are needed to display a string in a terminal. + + Returns -1 if the string contains non-printable characters. + """ + width = 0 + for c in unicodedata.normalize("NFC", s): + wc = wcwidth(c) + if wc < 0: + return -1 + width += wc + return width diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/error.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/error.py new file mode 100644 index 00000000..0b8f2d53 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/error.py @@ -0,0 +1,109 @@ +"""create errno-specific classes for IO or os calls.""" +from __future__ import annotations + +import errno +import os +import sys +from typing import Callable +from typing import TYPE_CHECKING +from typing import TypeVar + +if TYPE_CHECKING: + from typing_extensions import ParamSpec + + P = ParamSpec("P") + +R = TypeVar("R") + + +class Error(EnvironmentError): + def __repr__(self) -> str: + return "{}.{} {!r}: {} ".format( + self.__class__.__module__, + self.__class__.__name__, + self.__class__.__doc__, + " ".join(map(str, self.args)), + # repr(self.args) + ) + + def __str__(self) -> str: + s = "[{}]: {}".format( + self.__class__.__doc__, + " ".join(map(str, self.args)), + ) + return s + + +_winerrnomap = { + 2: errno.ENOENT, + 3: errno.ENOENT, + 17: errno.EEXIST, + 18: errno.EXDEV, + 13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailiable + 22: errno.ENOTDIR, + 20: errno.ENOTDIR, + 267: errno.ENOTDIR, + 5: errno.EACCES, # anything better? +} + + +class ErrorMaker: + """lazily provides Exception classes for each possible POSIX errno + (as defined per the 'errno' module). All such instances + subclass EnvironmentError. + """ + + _errno2class: dict[int, type[Error]] = {} + + def __getattr__(self, name: str) -> type[Error]: + if name[0] == "_": + raise AttributeError(name) + eno = getattr(errno, name) + cls = self._geterrnoclass(eno) + setattr(self, name, cls) + return cls + + def _geterrnoclass(self, eno: int) -> type[Error]: + try: + return self._errno2class[eno] + except KeyError: + clsname = errno.errorcode.get(eno, "UnknownErrno%d" % (eno,)) + errorcls = type( + clsname, + (Error,), + {"__module__": "py.error", "__doc__": os.strerror(eno)}, + ) + self._errno2class[eno] = errorcls + return errorcls + + def checked_call( + self, func: Callable[P, R], *args: P.args, **kwargs: P.kwargs + ) -> R: + """Call a function and raise an errno-exception if applicable.""" + __tracebackhide__ = True + try: + return func(*args, **kwargs) + except Error: + raise + except OSError as value: + if not hasattr(value, "errno"): + raise + errno = value.errno + if sys.platform == "win32": + try: + cls = self._geterrnoclass(_winerrnomap[errno]) + except KeyError: + raise value + else: + # we are not on Windows, or we got a proper OSError + cls = self._geterrnoclass(errno) + + raise cls(f"{func.__name__}{args!r}") + + +_error_maker = ErrorMaker() +checked_call = _error_maker.checked_call + + +def __getattr__(attr: str) -> type[Error]: + return getattr(_error_maker, attr) # type: ignore[no-any-return] diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/path.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/path.py new file mode 100644 index 00000000..73a070d1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/path.py @@ -0,0 +1,1475 @@ +"""local path implementation.""" +from __future__ import annotations + +import atexit +import fnmatch +import importlib.util +import io +import os +import posixpath +import sys +import uuid +import warnings +from contextlib import contextmanager +from os.path import abspath +from os.path import dirname +from os.path import exists +from os.path import isabs +from os.path import isdir +from os.path import isfile +from os.path import islink +from os.path import normpath +from stat import S_ISDIR +from stat import S_ISLNK +from stat import S_ISREG +from typing import Any +from typing import Callable +from typing import cast +from typing import overload +from typing import TYPE_CHECKING + +from . import error + +if TYPE_CHECKING: + from typing import Literal + +# Moved from local.py. +iswin32 = sys.platform == "win32" or (getattr(os, "_name", False) == "nt") + + +class Checkers: + _depend_on_existence = "exists", "link", "dir", "file" + + def __init__(self, path): + self.path = path + + def dotfile(self): + return self.path.basename.startswith(".") + + def ext(self, arg): + if not arg.startswith("."): + arg = "." + arg + return self.path.ext == arg + + def basename(self, arg): + return self.path.basename == arg + + def basestarts(self, arg): + return self.path.basename.startswith(arg) + + def relto(self, arg): + return self.path.relto(arg) + + def fnmatch(self, arg): + return self.path.fnmatch(arg) + + def endswith(self, arg): + return str(self.path).endswith(arg) + + def _evaluate(self, kw): + from .._code.source import getrawcode + + for name, value in kw.items(): + invert = False + meth = None + try: + meth = getattr(self, name) + except AttributeError: + if name[:3] == "not": + invert = True + try: + meth = getattr(self, name[3:]) + except AttributeError: + pass + if meth is None: + raise TypeError(f"no {name!r} checker available for {self.path!r}") + try: + if getrawcode(meth).co_argcount > 1: + if (not meth(value)) ^ invert: + return False + else: + if bool(value) ^ bool(meth()) ^ invert: + return False + except (error.ENOENT, error.ENOTDIR, error.EBUSY): + # EBUSY feels not entirely correct, + # but its kind of necessary since ENOMEDIUM + # is not accessible in python + for name in self._depend_on_existence: + if name in kw: + if kw.get(name): + return False + name = "not" + name + if name in kw: + if not kw.get(name): + return False + return True + + _statcache: Stat + + def _stat(self) -> Stat: + try: + return self._statcache + except AttributeError: + try: + self._statcache = self.path.stat() + except error.ELOOP: + self._statcache = self.path.lstat() + return self._statcache + + def dir(self): + return S_ISDIR(self._stat().mode) + + def file(self): + return S_ISREG(self._stat().mode) + + def exists(self): + return self._stat() + + def link(self): + st = self.path.lstat() + return S_ISLNK(st.mode) + + +class NeverRaised(Exception): + pass + + +class Visitor: + def __init__(self, fil, rec, ignore, bf, sort): + if isinstance(fil, str): + fil = FNMatcher(fil) + if isinstance(rec, str): + self.rec: Callable[[LocalPath], bool] = FNMatcher(rec) + elif not hasattr(rec, "__call__") and rec: + self.rec = lambda path: True + else: + self.rec = rec + self.fil = fil + self.ignore = ignore + self.breadthfirst = bf + self.optsort = cast(Callable[[Any], Any], sorted) if sort else (lambda x: x) + + def gen(self, path): + try: + entries = path.listdir() + except self.ignore: + return + rec = self.rec + dirs = self.optsort( + [p for p in entries if p.check(dir=1) and (rec is None or rec(p))] + ) + if not self.breadthfirst: + for subdir in dirs: + for p in self.gen(subdir): + yield p + for p in self.optsort(entries): + if self.fil is None or self.fil(p): + yield p + if self.breadthfirst: + for subdir in dirs: + for p in self.gen(subdir): + yield p + + +class FNMatcher: + def __init__(self, pattern): + self.pattern = pattern + + def __call__(self, path): + pattern = self.pattern + + if ( + pattern.find(path.sep) == -1 + and iswin32 + and pattern.find(posixpath.sep) != -1 + ): + # Running on Windows, the pattern has no Windows path separators, + # and the pattern has one or more Posix path separators. Replace + # the Posix path separators with the Windows path separator. + pattern = pattern.replace(posixpath.sep, path.sep) + + if pattern.find(path.sep) == -1: + name = path.basename + else: + name = str(path) # path.strpath # XXX svn? + if not os.path.isabs(pattern): + pattern = "*" + path.sep + pattern + return fnmatch.fnmatch(name, pattern) + + +def map_as_list(func, iter): + return list(map(func, iter)) + + +class Stat: + if TYPE_CHECKING: + + @property + def size(self) -> int: + ... + + @property + def mtime(self) -> float: + ... + + def __getattr__(self, name: str) -> Any: + return getattr(self._osstatresult, "st_" + name) + + def __init__(self, path, osstatresult): + self.path = path + self._osstatresult = osstatresult + + @property + def owner(self): + if iswin32: + raise NotImplementedError("XXX win32") + import pwd + + entry = error.checked_call(pwd.getpwuid, self.uid) # type:ignore[attr-defined] + return entry[0] + + @property + def group(self): + """Return group name of file.""" + if iswin32: + raise NotImplementedError("XXX win32") + import grp + + entry = error.checked_call(grp.getgrgid, self.gid) # type:ignore[attr-defined] + return entry[0] + + def isdir(self): + return S_ISDIR(self._osstatresult.st_mode) + + def isfile(self): + return S_ISREG(self._osstatresult.st_mode) + + def islink(self): + self.path.lstat() + return S_ISLNK(self._osstatresult.st_mode) + + +def getuserid(user): + import pwd + + if not isinstance(user, int): + user = pwd.getpwnam(user)[2] # type:ignore[attr-defined] + return user + + +def getgroupid(group): + import grp + + if not isinstance(group, int): + group = grp.getgrnam(group)[2] # type:ignore[attr-defined] + return group + + +class LocalPath: + """Object oriented interface to os.path and other local filesystem + related information. + """ + + class ImportMismatchError(ImportError): + """raised on pyimport() if there is a mismatch of __file__'s""" + + sep = os.sep + + def __init__(self, path=None, expanduser=False): + """Initialize and return a local Path instance. + + Path can be relative to the current directory. + If path is None it defaults to the current working directory. + If expanduser is True, tilde-expansion is performed. + Note that Path instances always carry an absolute path. + Note also that passing in a local path object will simply return + the exact same path object. Use new() to get a new copy. + """ + if path is None: + self.strpath = error.checked_call(os.getcwd) + else: + try: + path = os.fspath(path) + except TypeError: + raise ValueError( + "can only pass None, Path instances " + "or non-empty strings to LocalPath" + ) + if expanduser: + path = os.path.expanduser(path) + self.strpath = abspath(path) + + if sys.platform != "win32": + + def chown(self, user, group, rec=0): + """Change ownership to the given user and group. + user and group may be specified by a number or + by a name. if rec is True change ownership + recursively. + """ + uid = getuserid(user) + gid = getgroupid(group) + if rec: + for x in self.visit(rec=lambda x: x.check(link=0)): + if x.check(link=0): + error.checked_call(os.chown, str(x), uid, gid) + error.checked_call(os.chown, str(self), uid, gid) + + def readlink(self) -> str: + """Return value of a symbolic link.""" + # https://github.com/python/mypy/issues/12278 + return error.checked_call(os.readlink, self.strpath) # type: ignore[arg-type,return-value] + + def mklinkto(self, oldname): + """Posix style hard link to another name.""" + error.checked_call(os.link, str(oldname), str(self)) + + def mksymlinkto(self, value, absolute=1): + """Create a symbolic link with the given value (pointing to another name).""" + if absolute: + error.checked_call(os.symlink, str(value), self.strpath) + else: + base = self.common(value) + # with posix local paths '/' is always a common base + relsource = self.__class__(value).relto(base) + reldest = self.relto(base) + n = reldest.count(self.sep) + target = self.sep.join(("..",) * n + (relsource,)) + error.checked_call(os.symlink, target, self.strpath) + + def __div__(self, other): + return self.join(os.fspath(other)) + + __truediv__ = __div__ # py3k + + @property + def basename(self): + """Basename part of path.""" + return self._getbyspec("basename")[0] + + @property + def dirname(self): + """Dirname part of path.""" + return self._getbyspec("dirname")[0] + + @property + def purebasename(self): + """Pure base name of the path.""" + return self._getbyspec("purebasename")[0] + + @property + def ext(self): + """Extension of the path (including the '.').""" + return self._getbyspec("ext")[0] + + def read_binary(self): + """Read and return a bytestring from reading the path.""" + with self.open("rb") as f: + return f.read() + + def read_text(self, encoding): + """Read and return a Unicode string from reading the path.""" + with self.open("r", encoding=encoding) as f: + return f.read() + + def read(self, mode="r"): + """Read and return a bytestring from reading the path.""" + with self.open(mode) as f: + return f.read() + + def readlines(self, cr=1): + """Read and return a list of lines from the path. if cr is False, the + newline will be removed from the end of each line.""" + mode = "r" + + if not cr: + content = self.read(mode) + return content.split("\n") + else: + f = self.open(mode) + try: + return f.readlines() + finally: + f.close() + + def load(self): + """(deprecated) return object unpickled from self.read()""" + f = self.open("rb") + try: + import pickle + + return error.checked_call(pickle.load, f) + finally: + f.close() + + def move(self, target): + """Move this path to target.""" + if target.relto(self): + raise error.EINVAL(target, "cannot move path into a subdirectory of itself") + try: + self.rename(target) + except error.EXDEV: # invalid cross-device link + self.copy(target) + self.remove() + + def fnmatch(self, pattern): + """Return true if the basename/fullname matches the glob-'pattern'. + + valid pattern characters:: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any char not in seq + + If the pattern contains a path-separator then the full path + is used for pattern matching and a '*' is prepended to the + pattern. + + if the pattern doesn't contain a path-separator the pattern + is only matched against the basename. + """ + return FNMatcher(pattern)(self) + + def relto(self, relpath): + """Return a string which is the relative part of the path + to the given 'relpath'. + """ + if not isinstance(relpath, (str, LocalPath)): + raise TypeError(f"{relpath!r}: not a string or path object") + strrelpath = str(relpath) + if strrelpath and strrelpath[-1] != self.sep: + strrelpath += self.sep + # assert strrelpath[-1] == self.sep + # assert strrelpath[-2] != self.sep + strself = self.strpath + if sys.platform == "win32" or getattr(os, "_name", None) == "nt": + if os.path.normcase(strself).startswith(os.path.normcase(strrelpath)): + return strself[len(strrelpath) :] + elif strself.startswith(strrelpath): + return strself[len(strrelpath) :] + return "" + + def ensure_dir(self, *args): + """Ensure the path joined with args is a directory.""" + return self.ensure(*args, **{"dir": True}) + + def bestrelpath(self, dest): + """Return a string which is a relative path from self + (assumed to be a directory) to dest such that + self.join(bestrelpath) == dest and if not such + path can be determined return dest. + """ + try: + if self == dest: + return os.curdir + base = self.common(dest) + if not base: # can be the case on windows + return str(dest) + self2base = self.relto(base) + reldest = dest.relto(base) + if self2base: + n = self2base.count(self.sep) + 1 + else: + n = 0 + lst = [os.pardir] * n + if reldest: + lst.append(reldest) + target = dest.sep.join(lst) + return target + except AttributeError: + return str(dest) + + def exists(self): + return self.check() + + def isdir(self): + return self.check(dir=1) + + def isfile(self): + return self.check(file=1) + + def parts(self, reverse=False): + """Return a root-first list of all ancestor directories + plus the path itself. + """ + current = self + lst = [self] + while 1: + last = current + current = current.dirpath() + if last == current: + break + lst.append(current) + if not reverse: + lst.reverse() + return lst + + def common(self, other): + """Return the common part shared with the other path + or None if there is no common part. + """ + last = None + for x, y in zip(self.parts(), other.parts()): + if x != y: + return last + last = x + return last + + def __add__(self, other): + """Return new path object with 'other' added to the basename""" + return self.new(basename=self.basename + str(other)) + + def visit(self, fil=None, rec=None, ignore=NeverRaised, bf=False, sort=False): + """Yields all paths below the current one + + fil is a filter (glob pattern or callable), if not matching the + path will not be yielded, defaulting to None (everything is + returned) + + rec is a filter (glob pattern or callable) that controls whether + a node is descended, defaulting to None + + ignore is an Exception class that is ignoredwhen calling dirlist() + on any of the paths (by default, all exceptions are reported) + + bf if True will cause a breadthfirst search instead of the + default depthfirst. Default: False + + sort if True will sort entries within each directory level. + """ + yield from Visitor(fil, rec, ignore, bf, sort).gen(self) + + def _sortlist(self, res, sort): + if sort: + if hasattr(sort, "__call__"): + warnings.warn( + DeprecationWarning( + "listdir(sort=callable) is deprecated and breaks on python3" + ), + stacklevel=3, + ) + res.sort(sort) + else: + res.sort() + + def __fspath__(self): + return self.strpath + + def __hash__(self): + s = self.strpath + if iswin32: + s = s.lower() + return hash(s) + + def __eq__(self, other): + s1 = os.fspath(self) + try: + s2 = os.fspath(other) + except TypeError: + return False + if iswin32: + s1 = s1.lower() + try: + s2 = s2.lower() + except AttributeError: + return False + return s1 == s2 + + def __ne__(self, other): + return not (self == other) + + def __lt__(self, other): + return os.fspath(self) < os.fspath(other) + + def __gt__(self, other): + return os.fspath(self) > os.fspath(other) + + def samefile(self, other): + """Return True if 'other' references the same file as 'self'.""" + other = os.fspath(other) + if not isabs(other): + other = abspath(other) + if self == other: + return True + if not hasattr(os.path, "samefile"): + return False + return error.checked_call(os.path.samefile, self.strpath, other) + + def remove(self, rec=1, ignore_errors=False): + """Remove a file or directory (or a directory tree if rec=1). + if ignore_errors is True, errors while removing directories will + be ignored. + """ + if self.check(dir=1, link=0): + if rec: + # force remove of readonly files on windows + if iswin32: + self.chmod(0o700, rec=1) + import shutil + + error.checked_call( + shutil.rmtree, self.strpath, ignore_errors=ignore_errors + ) + else: + error.checked_call(os.rmdir, self.strpath) + else: + if iswin32: + self.chmod(0o700) + error.checked_call(os.remove, self.strpath) + + def computehash(self, hashtype="md5", chunksize=524288): + """Return hexdigest of hashvalue for this file.""" + try: + try: + import hashlib as mod + except ImportError: + if hashtype == "sha1": + hashtype = "sha" + mod = __import__(hashtype) + hash = getattr(mod, hashtype)() + except (AttributeError, ImportError): + raise ValueError(f"Don't know how to compute {hashtype!r} hash") + f = self.open("rb") + try: + while 1: + buf = f.read(chunksize) + if not buf: + return hash.hexdigest() + hash.update(buf) + finally: + f.close() + + def new(self, **kw): + """Create a modified version of this path. + the following keyword arguments modify various path parts:: + + a:/some/path/to/a/file.ext + xx drive + xxxxxxxxxxxxxxxxx dirname + xxxxxxxx basename + xxxx purebasename + xxx ext + """ + obj = object.__new__(self.__class__) + if not kw: + obj.strpath = self.strpath + return obj + drive, dirname, basename, purebasename, ext = self._getbyspec( + "drive,dirname,basename,purebasename,ext" + ) + if "basename" in kw: + if "purebasename" in kw or "ext" in kw: + raise ValueError("invalid specification %r" % kw) + else: + pb = kw.setdefault("purebasename", purebasename) + try: + ext = kw["ext"] + except KeyError: + pass + else: + if ext and not ext.startswith("."): + ext = "." + ext + kw["basename"] = pb + ext + + if "dirname" in kw and not kw["dirname"]: + kw["dirname"] = drive + else: + kw.setdefault("dirname", dirname) + kw.setdefault("sep", self.sep) + obj.strpath = normpath("%(dirname)s%(sep)s%(basename)s" % kw) + return obj + + def _getbyspec(self, spec: str) -> list[str]: + """See new for what 'spec' can be.""" + res = [] + parts = self.strpath.split(self.sep) + + args = filter(None, spec.split(",")) + for name in args: + if name == "drive": + res.append(parts[0]) + elif name == "dirname": + res.append(self.sep.join(parts[:-1])) + else: + basename = parts[-1] + if name == "basename": + res.append(basename) + else: + i = basename.rfind(".") + if i == -1: + purebasename, ext = basename, "" + else: + purebasename, ext = basename[:i], basename[i:] + if name == "purebasename": + res.append(purebasename) + elif name == "ext": + res.append(ext) + else: + raise ValueError("invalid part specification %r" % name) + return res + + def dirpath(self, *args, **kwargs): + """Return the directory path joined with any given path arguments.""" + if not kwargs: + path = object.__new__(self.__class__) + path.strpath = dirname(self.strpath) + if args: + path = path.join(*args) + return path + return self.new(basename="").join(*args, **kwargs) + + def join(self, *args: os.PathLike[str], abs: bool = False) -> LocalPath: + """Return a new path by appending all 'args' as path + components. if abs=1 is used restart from root if any + of the args is an absolute path. + """ + sep = self.sep + strargs = [os.fspath(arg) for arg in args] + strpath = self.strpath + if abs: + newargs: list[str] = [] + for arg in reversed(strargs): + if isabs(arg): + strpath = arg + strargs = newargs + break + newargs.insert(0, arg) + # special case for when we have e.g. strpath == "/" + actual_sep = "" if strpath.endswith(sep) else sep + for arg in strargs: + arg = arg.strip(sep) + if iswin32: + # allow unix style paths even on windows. + arg = arg.strip("/") + arg = arg.replace("/", sep) + strpath = strpath + actual_sep + arg + actual_sep = sep + obj = object.__new__(self.__class__) + obj.strpath = normpath(strpath) + return obj + + def open(self, mode="r", ensure=False, encoding=None): + """Return an opened file with the given mode. + + If ensure is True, create parent directories if needed. + """ + if ensure: + self.dirpath().ensure(dir=1) + if encoding: + return error.checked_call(io.open, self.strpath, mode, encoding=encoding) + return error.checked_call(open, self.strpath, mode) + + def _fastjoin(self, name): + child = object.__new__(self.__class__) + child.strpath = self.strpath + self.sep + name + return child + + def islink(self): + return islink(self.strpath) + + def check(self, **kw): + """Check a path for existence and properties. + + Without arguments, return True if the path exists, otherwise False. + + valid checkers:: + + file=1 # is a file + file=0 # is not a file (may not even exist) + dir=1 # is a dir + link=1 # is a link + exists=1 # exists + + You can specify multiple checker definitions, for example:: + + path.check(file=1, link=1) # a link pointing to a file + """ + if not kw: + return exists(self.strpath) + if len(kw) == 1: + if "dir" in kw: + return not kw["dir"] ^ isdir(self.strpath) + if "file" in kw: + return not kw["file"] ^ isfile(self.strpath) + if not kw: + kw = {"exists": 1} + return Checkers(self)._evaluate(kw) + + _patternchars = set("*?[" + os.sep) + + def listdir(self, fil=None, sort=None): + """List directory contents, possibly filter by the given fil func + and possibly sorted. + """ + if fil is None and sort is None: + names = error.checked_call(os.listdir, self.strpath) + return map_as_list(self._fastjoin, names) + if isinstance(fil, str): + if not self._patternchars.intersection(fil): + child = self._fastjoin(fil) + if exists(child.strpath): + return [child] + return [] + fil = FNMatcher(fil) + names = error.checked_call(os.listdir, self.strpath) + res = [] + for name in names: + child = self._fastjoin(name) + if fil is None or fil(child): + res.append(child) + self._sortlist(res, sort) + return res + + def size(self) -> int: + """Return size of the underlying file object""" + return self.stat().size + + def mtime(self) -> float: + """Return last modification time of the path.""" + return self.stat().mtime + + def copy(self, target, mode=False, stat=False): + """Copy path to target. + + If mode is True, will copy copy permission from path to target. + If stat is True, copy permission, last modification + time, last access time, and flags from path to target. + """ + if self.check(file=1): + if target.check(dir=1): + target = target.join(self.basename) + assert self != target + copychunked(self, target) + if mode: + copymode(self.strpath, target.strpath) + if stat: + copystat(self, target) + else: + + def rec(p): + return p.check(link=0) + + for x in self.visit(rec=rec): + relpath = x.relto(self) + newx = target.join(relpath) + newx.dirpath().ensure(dir=1) + if x.check(link=1): + newx.mksymlinkto(x.readlink()) + continue + elif x.check(file=1): + copychunked(x, newx) + elif x.check(dir=1): + newx.ensure(dir=1) + if mode: + copymode(x.strpath, newx.strpath) + if stat: + copystat(x, newx) + + def rename(self, target): + """Rename this path to target.""" + target = os.fspath(target) + return error.checked_call(os.rename, self.strpath, target) + + def dump(self, obj, bin=1): + """Pickle object into path location""" + f = self.open("wb") + import pickle + + try: + error.checked_call(pickle.dump, obj, f, bin) + finally: + f.close() + + def mkdir(self, *args): + """Create & return the directory joined with args.""" + p = self.join(*args) + error.checked_call(os.mkdir, os.fspath(p)) + return p + + def write_binary(self, data, ensure=False): + """Write binary data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + with self.open("wb") as f: + f.write(data) + + def write_text(self, data, encoding, ensure=False): + """Write text data into path using the specified encoding. + If ensure is True create missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + with self.open("w", encoding=encoding) as f: + f.write(data) + + def write(self, data, mode="w", ensure=False): + """Write data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + if "b" in mode: + if not isinstance(data, bytes): + raise ValueError("can only process bytes") + else: + if not isinstance(data, str): + if not isinstance(data, bytes): + data = str(data) + else: + data = data.decode(sys.getdefaultencoding()) + f = self.open(mode) + try: + f.write(data) + finally: + f.close() + + def _ensuredirs(self): + parent = self.dirpath() + if parent == self: + return self + if parent.check(dir=0): + parent._ensuredirs() + if self.check(dir=0): + try: + self.mkdir() + except error.EEXIST: + # race condition: file/dir created by another thread/process. + # complain if it is not a dir + if self.check(dir=0): + raise + return self + + def ensure(self, *args, **kwargs): + """Ensure that an args-joined path exists (by default as + a file). if you specify a keyword argument 'dir=True' + then the path is forced to be a directory path. + """ + p = self.join(*args) + if kwargs.get("dir", 0): + return p._ensuredirs() + else: + p.dirpath()._ensuredirs() + if not p.check(file=1): + p.open("wb").close() + return p + + @overload + def stat(self, raising: Literal[True] = ...) -> Stat: + ... + + @overload + def stat(self, raising: Literal[False]) -> Stat | None: + ... + + def stat(self, raising: bool = True) -> Stat | None: + """Return an os.stat() tuple.""" + if raising: + return Stat(self, error.checked_call(os.stat, self.strpath)) + try: + return Stat(self, os.stat(self.strpath)) + except KeyboardInterrupt: + raise + except Exception: + return None + + def lstat(self) -> Stat: + """Return an os.lstat() tuple.""" + return Stat(self, error.checked_call(os.lstat, self.strpath)) + + def setmtime(self, mtime=None): + """Set modification time for the given path. if 'mtime' is None + (the default) then the file's mtime is set to current time. + + Note that the resolution for 'mtime' is platform dependent. + """ + if mtime is None: + return error.checked_call(os.utime, self.strpath, mtime) + try: + return error.checked_call(os.utime, self.strpath, (-1, mtime)) + except error.EINVAL: + return error.checked_call(os.utime, self.strpath, (self.atime(), mtime)) + + def chdir(self): + """Change directory to self and return old current directory""" + try: + old = self.__class__() + except error.ENOENT: + old = None + error.checked_call(os.chdir, self.strpath) + return old + + @contextmanager + def as_cwd(self): + """ + Return a context manager, which changes to the path's dir during the + managed "with" context. + On __enter__ it returns the old dir, which might be ``None``. + """ + old = self.chdir() + try: + yield old + finally: + if old is not None: + old.chdir() + + def realpath(self): + """Return a new path which contains no symbolic links.""" + return self.__class__(os.path.realpath(self.strpath)) + + def atime(self): + """Return last access time of the path.""" + return self.stat().atime + + def __repr__(self): + return "local(%r)" % self.strpath + + def __str__(self): + """Return string representation of the Path.""" + return self.strpath + + def chmod(self, mode, rec=0): + """Change permissions to the given mode. If mode is an + integer it directly encodes the os-specific modes. + if rec is True perform recursively. + """ + if not isinstance(mode, int): + raise TypeError(f"mode {mode!r} must be an integer") + if rec: + for x in self.visit(rec=rec): + error.checked_call(os.chmod, str(x), mode) + error.checked_call(os.chmod, self.strpath, mode) + + def pypkgpath(self): + """Return the Python package path by looking for the last + directory upwards which still contains an __init__.py. + Return None if a pkgpath can not be determined. + """ + pkgpath = None + for parent in self.parts(reverse=True): + if parent.isdir(): + if not parent.join("__init__.py").exists(): + break + if not isimportable(parent.basename): + break + pkgpath = parent + return pkgpath + + def _ensuresyspath(self, ensuremode, path): + if ensuremode: + s = str(path) + if ensuremode == "append": + if s not in sys.path: + sys.path.append(s) + else: + if s != sys.path[0]: + sys.path.insert(0, s) + + def pyimport(self, modname=None, ensuresyspath=True): + """Return path as an imported python module. + + If modname is None, look for the containing package + and construct an according module name. + The module will be put/looked up in sys.modules. + if ensuresyspath is True then the root dir for importing + the file (taking __init__.py files into account) will + be prepended to sys.path if it isn't there already. + If ensuresyspath=="append" the root dir will be appended + if it isn't already contained in sys.path. + if ensuresyspath is False no modification of syspath happens. + + Special value of ensuresyspath=="importlib" is intended + purely for using in pytest, it is capable only of importing + separate .py files outside packages, e.g. for test suite + without any __init__.py file. It effectively allows having + same-named test modules in different places and offers + mild opt-in via this option. Note that it works only in + recent versions of python. + """ + if not self.check(): + raise error.ENOENT(self) + + if ensuresyspath == "importlib": + if modname is None: + modname = self.purebasename + spec = importlib.util.spec_from_file_location(modname, str(self)) + if spec is None or spec.loader is None: + raise ImportError( + f"Can't find module {modname} at location {str(self)}" + ) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + pkgpath = None + if modname is None: + pkgpath = self.pypkgpath() + if pkgpath is not None: + pkgroot = pkgpath.dirpath() + names = self.new(ext="").relto(pkgroot).split(self.sep) + if names[-1] == "__init__": + names.pop() + modname = ".".join(names) + else: + pkgroot = self.dirpath() + modname = self.purebasename + + self._ensuresyspath(ensuresyspath, pkgroot) + __import__(modname) + mod = sys.modules[modname] + if self.basename == "__init__.py": + return mod # we don't check anything as we might + # be in a namespace package ... too icky to check + modfile = mod.__file__ + assert modfile is not None + if modfile[-4:] in (".pyc", ".pyo"): + modfile = modfile[:-1] + elif modfile.endswith("$py.class"): + modfile = modfile[:-9] + ".py" + if modfile.endswith(os.sep + "__init__.py"): + if self.basename != "__init__.py": + modfile = modfile[:-12] + try: + issame = self.samefile(modfile) + except error.ENOENT: + issame = False + if not issame: + ignore = os.getenv("PY_IGNORE_IMPORTMISMATCH") + if ignore != "1": + raise self.ImportMismatchError(modname, modfile, self) + return mod + else: + try: + return sys.modules[modname] + except KeyError: + # we have a custom modname, do a pseudo-import + import types + + mod = types.ModuleType(modname) + mod.__file__ = str(self) + sys.modules[modname] = mod + try: + with open(str(self), "rb") as f: + exec(f.read(), mod.__dict__) + except BaseException: + del sys.modules[modname] + raise + return mod + + def sysexec(self, *argv: os.PathLike[str], **popen_opts: Any) -> str: + """Return stdout text from executing a system child process, + where the 'self' path points to executable. + The process is directly invoked and not through a system shell. + """ + from subprocess import Popen, PIPE + + popen_opts.pop("stdout", None) + popen_opts.pop("stderr", None) + proc = Popen( + [str(self)] + [str(arg) for arg in argv], + **popen_opts, + stdout=PIPE, + stderr=PIPE, + ) + stdout: str | bytes + stdout, stderr = proc.communicate() + ret = proc.wait() + if isinstance(stdout, bytes): + stdout = stdout.decode(sys.getdefaultencoding()) + if ret != 0: + if isinstance(stderr, bytes): + stderr = stderr.decode(sys.getdefaultencoding()) + raise RuntimeError( + ret, + ret, + str(self), + stdout, + stderr, + ) + return stdout + + @classmethod + def sysfind(cls, name, checker=None, paths=None): + """Return a path object found by looking at the systems + underlying PATH specification. If the checker is not None + it will be invoked to filter matching paths. If a binary + cannot be found, None is returned + Note: This is probably not working on plain win32 systems + but may work on cygwin. + """ + if isabs(name): + p = local(name) + if p.check(file=1): + return p + else: + if paths is None: + if iswin32: + paths = os.environ["Path"].split(";") + if "" not in paths and "." not in paths: + paths.append(".") + try: + systemroot = os.environ["SYSTEMROOT"] + except KeyError: + pass + else: + paths = [ + path.replace("%SystemRoot%", systemroot) for path in paths + ] + else: + paths = os.environ["PATH"].split(":") + tryadd = [] + if iswin32: + tryadd += os.environ["PATHEXT"].split(os.pathsep) + tryadd.append("") + + for x in paths: + for addext in tryadd: + p = local(x).join(name, abs=True) + addext + try: + if p.check(file=1): + if checker: + if not checker(p): + continue + return p + except error.EACCES: + pass + return None + + @classmethod + def _gethomedir(cls): + try: + x = os.environ["HOME"] + except KeyError: + try: + x = os.environ["HOMEDRIVE"] + os.environ["HOMEPATH"] + except KeyError: + return None + return cls(x) + + # """ + # special class constructors for local filesystem paths + # """ + @classmethod + def get_temproot(cls): + """Return the system's temporary directory + (where tempfiles are usually created in) + """ + import tempfile + + return local(tempfile.gettempdir()) + + @classmethod + def mkdtemp(cls, rootdir=None): + """Return a Path object pointing to a fresh new temporary directory + (which we created ourself). + """ + import tempfile + + if rootdir is None: + rootdir = cls.get_temproot() + return cls(error.checked_call(tempfile.mkdtemp, dir=str(rootdir))) + + @classmethod + def make_numbered_dir( + cls, prefix="session-", rootdir=None, keep=3, lock_timeout=172800 + ): # two days + """Return unique directory with a number greater than the current + maximum one. The number is assumed to start directly after prefix. + if keep is true directories with a number less than (maxnum-keep) + will be removed. If .lock files are used (lock_timeout non-zero), + algorithm is multi-process safe. + """ + if rootdir is None: + rootdir = cls.get_temproot() + + nprefix = prefix.lower() + + def parse_num(path): + """Parse the number out of a path (if it matches the prefix)""" + nbasename = path.basename.lower() + if nbasename.startswith(nprefix): + try: + return int(nbasename[len(nprefix) :]) + except ValueError: + pass + + def create_lockfile(path): + """Exclusively create lockfile. Throws when failed""" + mypid = os.getpid() + lockfile = path.join(".lock") + if hasattr(lockfile, "mksymlinkto"): + lockfile.mksymlinkto(str(mypid)) + else: + fd = error.checked_call( + os.open, str(lockfile), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644 + ) + with os.fdopen(fd, "w") as f: + f.write(str(mypid)) + return lockfile + + def atexit_remove_lockfile(lockfile): + """Ensure lockfile is removed at process exit""" + mypid = os.getpid() + + def try_remove_lockfile(): + # in a fork() situation, only the last process should + # remove the .lock, otherwise the other processes run the + # risk of seeing their temporary dir disappear. For now + # we remove the .lock in the parent only (i.e. we assume + # that the children finish before the parent). + if os.getpid() != mypid: + return + try: + lockfile.remove() + except error.Error: + pass + + atexit.register(try_remove_lockfile) + + # compute the maximum number currently in use with the prefix + lastmax = None + while True: + maxnum = -1 + for path in rootdir.listdir(): + num = parse_num(path) + if num is not None: + maxnum = max(maxnum, num) + + # make the new directory + try: + udir = rootdir.mkdir(prefix + str(maxnum + 1)) + if lock_timeout: + lockfile = create_lockfile(udir) + atexit_remove_lockfile(lockfile) + except (error.EEXIST, error.ENOENT, error.EBUSY): + # race condition (1): another thread/process created the dir + # in the meantime - try again + # race condition (2): another thread/process spuriously acquired + # lock treating empty directory as candidate + # for removal - try again + # race condition (3): another thread/process tried to create the lock at + # the same time (happened in Python 3.3 on Windows) + # https://ci.appveyor.com/project/pytestbot/py/build/1.0.21/job/ffi85j4c0lqwsfwa + if lastmax == maxnum: + raise + lastmax = maxnum + continue + break + + def get_mtime(path): + """Read file modification time""" + try: + return path.lstat().mtime + except error.Error: + pass + + garbage_prefix = prefix + "garbage-" + + def is_garbage(path): + """Check if path denotes directory scheduled for removal""" + bn = path.basename + return bn.startswith(garbage_prefix) + + # prune old directories + udir_time = get_mtime(udir) + if keep and udir_time: + for path in rootdir.listdir(): + num = parse_num(path) + if num is not None and num <= (maxnum - keep): + try: + # try acquiring lock to remove directory as exclusive user + if lock_timeout: + create_lockfile(path) + except (error.EEXIST, error.ENOENT, error.EBUSY): + path_time = get_mtime(path) + if not path_time: + # assume directory doesn't exist now + continue + if abs(udir_time - path_time) < lock_timeout: + # assume directory with lockfile exists + # and lock timeout hasn't expired yet + continue + + # path dir locked for exclusive use + # and scheduled for removal to avoid another thread/process + # treating it as a new directory or removal candidate + garbage_path = rootdir.join(garbage_prefix + str(uuid.uuid4())) + try: + path.rename(garbage_path) + garbage_path.remove(rec=1) + except KeyboardInterrupt: + raise + except Exception: # this might be error.Error, WindowsError ... + pass + if is_garbage(path): + try: + path.remove(rec=1) + except KeyboardInterrupt: + raise + except Exception: # this might be error.Error, WindowsError ... + pass + + # make link... + try: + username = os.environ["USER"] # linux, et al + except KeyError: + try: + username = os.environ["USERNAME"] # windows + except KeyError: + username = "current" + + src = str(udir) + dest = src[: src.rfind("-")] + "-" + username + try: + os.unlink(dest) + except OSError: + pass + try: + os.symlink(src, dest) + except (OSError, AttributeError, NotImplementedError): + pass + + return udir + + +def copymode(src, dest): + """Copy permission from src to dst.""" + import shutil + + shutil.copymode(src, dest) + + +def copystat(src, dest): + """Copy permission, last modification time, + last access time, and flags from src to dst.""" + import shutil + + shutil.copystat(str(src), str(dest)) + + +def copychunked(src, dest): + chunksize = 524288 # half a meg of bytes + fsrc = src.open("rb") + try: + fdest = dest.open("wb") + try: + while 1: + buf = fsrc.read(chunksize) + if not buf: + break + fdest.write(buf) + finally: + fdest.close() + finally: + fsrc.close() + + +def isimportable(name): + if name and (name[0].isalpha() or name[0] == "_"): + name = name.replace("_", "") + return not name or name.isalnum() + + +local = LocalPath diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/_version.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/_version.py new file mode 100644 index 00000000..458d0659 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '7.4.4' +__version_tuple__ = version_tuple = (7, 4, 4) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/__init__.py new file mode 100644 index 00000000..a46e5813 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/__init__.py @@ -0,0 +1,181 @@ +"""Support for presenting detailed information in failing assertions.""" +import sys +from typing import Any +from typing import Generator +from typing import List +from typing import Optional +from typing import TYPE_CHECKING + +from _pytest.assertion import rewrite +from _pytest.assertion import truncate +from _pytest.assertion import util +from _pytest.assertion.rewrite import assertstate_key +from _pytest.config import Config +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.nodes import Item + +if TYPE_CHECKING: + from _pytest.main import Session + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("debugconfig") + group.addoption( + "--assert", + action="store", + dest="assertmode", + choices=("rewrite", "plain"), + default="rewrite", + metavar="MODE", + help=( + "Control assertion debugging tools.\n" + "'plain' performs no assertion debugging.\n" + "'rewrite' (the default) rewrites assert statements in test modules" + " on import to provide assert expression information." + ), + ) + parser.addini( + "enable_assertion_pass_hook", + type="bool", + default=False, + help="Enables the pytest_assertion_pass hook. " + "Make sure to delete any previously generated pyc cache files.", + ) + + +def register_assert_rewrite(*names: str) -> None: + """Register one or more module names to be rewritten on import. + + This function will make sure that this module or all modules inside + the package will get their assert statements rewritten. + Thus you should make sure to call this before the module is + actually imported, usually in your __init__.py if you are a plugin + using a package. + + :param names: The module names to register. + """ + for name in names: + if not isinstance(name, str): + msg = "expected module names as *args, got {0} instead" # type: ignore[unreachable] + raise TypeError(msg.format(repr(names))) + for hook in sys.meta_path: + if isinstance(hook, rewrite.AssertionRewritingHook): + importhook = hook + break + else: + # TODO(typing): Add a protocol for mark_rewrite() and use it + # for importhook and for PytestPluginManager.rewrite_hook. + importhook = DummyRewriteHook() # type: ignore + importhook.mark_rewrite(*names) + + +class DummyRewriteHook: + """A no-op import hook for when rewriting is disabled.""" + + def mark_rewrite(self, *names: str) -> None: + pass + + +class AssertionState: + """State for the assertion plugin.""" + + def __init__(self, config: Config, mode) -> None: + self.mode = mode + self.trace = config.trace.root.get("assertion") + self.hook: Optional[rewrite.AssertionRewritingHook] = None + + +def install_importhook(config: Config) -> rewrite.AssertionRewritingHook: + """Try to install the rewrite hook, raise SystemError if it fails.""" + config.stash[assertstate_key] = AssertionState(config, "rewrite") + config.stash[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config) + sys.meta_path.insert(0, hook) + config.stash[assertstate_key].trace("installed rewrite import hook") + + def undo() -> None: + hook = config.stash[assertstate_key].hook + if hook is not None and hook in sys.meta_path: + sys.meta_path.remove(hook) + + config.add_cleanup(undo) + return hook + + +def pytest_collection(session: "Session") -> None: + # This hook is only called when test modules are collected + # so for example not in the managing process of pytest-xdist + # (which does not collect test modules). + assertstate = session.config.stash.get(assertstate_key, None) + if assertstate: + if assertstate.hook is not None: + assertstate.hook.set_session(session) + + +@hookimpl(tryfirst=True, hookwrapper=True) +def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: + """Setup the pytest_assertrepr_compare and pytest_assertion_pass hooks. + + The rewrite module will use util._reprcompare if it exists to use custom + reporting via the pytest_assertrepr_compare hook. This sets up this custom + comparison for the test. + """ + + ihook = item.ihook + + def callbinrepr(op, left: object, right: object) -> Optional[str]: + """Call the pytest_assertrepr_compare hook and prepare the result. + + This uses the first result from the hook and then ensures the + following: + * Overly verbose explanations are truncated unless configured otherwise + (eg. if running in verbose mode). + * Embedded newlines are escaped to help util.format_explanation() + later. + * If the rewrite mode is used embedded %-characters are replaced + to protect later % formatting. + + The result can be formatted by util.format_explanation() for + pretty printing. + """ + hook_result = ihook.pytest_assertrepr_compare( + config=item.config, op=op, left=left, right=right + ) + for new_expl in hook_result: + if new_expl: + new_expl = truncate.truncate_if_required(new_expl, item) + new_expl = [line.replace("\n", "\\n") for line in new_expl] + res = "\n~".join(new_expl) + if item.config.getvalue("assertmode") == "rewrite": + res = res.replace("%", "%%") + return res + return None + + saved_assert_hooks = util._reprcompare, util._assertion_pass + util._reprcompare = callbinrepr + util._config = item.config + + if ihook.pytest_assertion_pass.get_hookimpls(): + + def call_assertion_pass_hook(lineno: int, orig: str, expl: str) -> None: + ihook.pytest_assertion_pass(item=item, lineno=lineno, orig=orig, expl=expl) + + util._assertion_pass = call_assertion_pass_hook + + yield + + util._reprcompare, util._assertion_pass = saved_assert_hooks + util._config = None + + +def pytest_sessionfinish(session: "Session") -> None: + assertstate = session.config.stash.get(assertstate_key, None) + if assertstate: + if assertstate.hook is not None: + assertstate.hook.set_session(None) + + +def pytest_assertrepr_compare( + config: Config, op: str, left: Any, right: Any +) -> Optional[List[str]]: + return util.assertrepr_compare(config=config, op=op, left=left, right=right) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/rewrite.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/rewrite.py new file mode 100644 index 00000000..d1974bb3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/rewrite.py @@ -0,0 +1,1217 @@ +"""Rewrite assertion AST to produce nice error messages.""" +import ast +import errno +import functools +import importlib.abc +import importlib.machinery +import importlib.util +import io +import itertools +import marshal +import os +import struct +import sys +import tokenize +import types +from collections import defaultdict +from pathlib import Path +from pathlib import PurePath +from typing import Callable +from typing import Dict +from typing import IO +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Optional +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE +from _pytest._io.saferepr import saferepr +from _pytest._version import version +from _pytest.assertion import util +from _pytest.assertion.util import ( # noqa: F401 + format_explanation as _format_explanation, +) +from _pytest.config import Config +from _pytest.main import Session +from _pytest.pathlib import absolutepath +from _pytest.pathlib import fnmatch_ex +from _pytest.stash import StashKey + +if TYPE_CHECKING: + from _pytest.assertion import AssertionState + +if sys.version_info >= (3, 8): + namedExpr = ast.NamedExpr + astNameConstant = ast.Constant + astStr = ast.Constant + astNum = ast.Constant +else: + namedExpr = ast.Expr + astNameConstant = ast.NameConstant + astStr = ast.Str + astNum = ast.Num + + +class Sentinel: + pass + + +assertstate_key = StashKey["AssertionState"]() + +# pytest caches rewritten pycs in pycache dirs +PYTEST_TAG = f"{sys.implementation.cache_tag}-pytest-{version}" +PYC_EXT = ".py" + (__debug__ and "c" or "o") +PYC_TAIL = "." + PYTEST_TAG + PYC_EXT + +# Special marker that denotes we have just left a scope definition +_SCOPE_END_MARKER = Sentinel() + + +class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader): + """PEP302/PEP451 import hook which rewrites asserts.""" + + def __init__(self, config: Config) -> None: + self.config = config + try: + self.fnpats = config.getini("python_files") + except ValueError: + self.fnpats = ["test_*.py", "*_test.py"] + self.session: Optional[Session] = None + self._rewritten_names: Dict[str, Path] = {} + self._must_rewrite: Set[str] = set() + # flag to guard against trying to rewrite a pyc file while we are already writing another pyc file, + # which might result in infinite recursion (#3506) + self._writing_pyc = False + self._basenames_to_check_rewrite = {"conftest"} + self._marked_for_rewrite_cache: Dict[str, bool] = {} + self._session_paths_checked = False + + def set_session(self, session: Optional[Session]) -> None: + self.session = session + self._session_paths_checked = False + + # Indirection so we can mock calls to find_spec originated from the hook during testing + _find_spec = importlib.machinery.PathFinder.find_spec + + def find_spec( + self, + name: str, + path: Optional[Sequence[Union[str, bytes]]] = None, + target: Optional[types.ModuleType] = None, + ) -> Optional[importlib.machinery.ModuleSpec]: + if self._writing_pyc: + return None + state = self.config.stash[assertstate_key] + if self._early_rewrite_bailout(name, state): + return None + state.trace("find_module called for: %s" % name) + + # Type ignored because mypy is confused about the `self` binding here. + spec = self._find_spec(name, path) # type: ignore + if ( + # the import machinery could not find a file to import + spec is None + # this is a namespace package (without `__init__.py`) + # there's nothing to rewrite there + or spec.origin is None + # we can only rewrite source files + or not isinstance(spec.loader, importlib.machinery.SourceFileLoader) + # if the file doesn't exist, we can't rewrite it + or not os.path.exists(spec.origin) + ): + return None + else: + fn = spec.origin + + if not self._should_rewrite(name, fn, state): + return None + + return importlib.util.spec_from_file_location( + name, + fn, + loader=self, + submodule_search_locations=spec.submodule_search_locations, + ) + + def create_module( + self, spec: importlib.machinery.ModuleSpec + ) -> Optional[types.ModuleType]: + return None # default behaviour is fine + + def exec_module(self, module: types.ModuleType) -> None: + assert module.__spec__ is not None + assert module.__spec__.origin is not None + fn = Path(module.__spec__.origin) + state = self.config.stash[assertstate_key] + + self._rewritten_names[module.__name__] = fn + + # The requested module looks like a test file, so rewrite it. This is + # the most magical part of the process: load the source, rewrite the + # asserts, and load the rewritten source. We also cache the rewritten + # module code in a special pyc. We must be aware of the possibility of + # concurrent pytest processes rewriting and loading pycs. To avoid + # tricky race conditions, we maintain the following invariant: The + # cached pyc is always a complete, valid pyc. Operations on it must be + # atomic. POSIX's atomic rename comes in handy. + write = not sys.dont_write_bytecode + cache_dir = get_cache_dir(fn) + if write: + ok = try_makedirs(cache_dir) + if not ok: + write = False + state.trace(f"read only directory: {cache_dir}") + + cache_name = fn.name[:-3] + PYC_TAIL + pyc = cache_dir / cache_name + # Notice that even if we're in a read-only directory, I'm going + # to check for a cached pyc. This may not be optimal... + co = _read_pyc(fn, pyc, state.trace) + if co is None: + state.trace(f"rewriting {fn!r}") + source_stat, co = _rewrite_test(fn, self.config) + if write: + self._writing_pyc = True + try: + _write_pyc(state, co, source_stat, pyc) + finally: + self._writing_pyc = False + else: + state.trace(f"found cached rewritten pyc for {fn}") + exec(co, module.__dict__) + + def _early_rewrite_bailout(self, name: str, state: "AssertionState") -> bool: + """A fast way to get out of rewriting modules. + + Profiling has shown that the call to PathFinder.find_spec (inside of + the find_spec from this class) is a major slowdown, so, this method + tries to filter what we're sure won't be rewritten before getting to + it. + """ + if self.session is not None and not self._session_paths_checked: + self._session_paths_checked = True + for initial_path in self.session._initialpaths: + # Make something as c:/projects/my_project/path.py -> + # ['c:', 'projects', 'my_project', 'path.py'] + parts = str(initial_path).split(os.sep) + # add 'path' to basenames to be checked. + self._basenames_to_check_rewrite.add(os.path.splitext(parts[-1])[0]) + + # Note: conftest already by default in _basenames_to_check_rewrite. + parts = name.split(".") + if parts[-1] in self._basenames_to_check_rewrite: + return False + + # For matching the name it must be as if it was a filename. + path = PurePath(*parts).with_suffix(".py") + + for pat in self.fnpats: + # if the pattern contains subdirectories ("tests/**.py" for example) we can't bail out based + # on the name alone because we need to match against the full path + if os.path.dirname(pat): + return False + if fnmatch_ex(pat, path): + return False + + if self._is_marked_for_rewrite(name, state): + return False + + state.trace(f"early skip of rewriting module: {name}") + return True + + def _should_rewrite(self, name: str, fn: str, state: "AssertionState") -> bool: + # always rewrite conftest files + if os.path.basename(fn) == "conftest.py": + state.trace(f"rewriting conftest file: {fn!r}") + return True + + if self.session is not None: + if self.session.isinitpath(absolutepath(fn)): + state.trace(f"matched test file (was specified on cmdline): {fn!r}") + return True + + # modules not passed explicitly on the command line are only + # rewritten if they match the naming convention for test files + fn_path = PurePath(fn) + for pat in self.fnpats: + if fnmatch_ex(pat, fn_path): + state.trace(f"matched test file {fn!r}") + return True + + return self._is_marked_for_rewrite(name, state) + + def _is_marked_for_rewrite(self, name: str, state: "AssertionState") -> bool: + try: + return self._marked_for_rewrite_cache[name] + except KeyError: + for marked in self._must_rewrite: + if name == marked or name.startswith(marked + "."): + state.trace(f"matched marked file {name!r} (from {marked!r})") + self._marked_for_rewrite_cache[name] = True + return True + + self._marked_for_rewrite_cache[name] = False + return False + + def mark_rewrite(self, *names: str) -> None: + """Mark import names as needing to be rewritten. + + The named module or package as well as any nested modules will + be rewritten on import. + """ + already_imported = ( + set(names).intersection(sys.modules).difference(self._rewritten_names) + ) + for name in already_imported: + mod = sys.modules[name] + if not AssertionRewriter.is_rewrite_disabled( + mod.__doc__ or "" + ) and not isinstance(mod.__loader__, type(self)): + self._warn_already_imported(name) + self._must_rewrite.update(names) + self._marked_for_rewrite_cache.clear() + + def _warn_already_imported(self, name: str) -> None: + from _pytest.warning_types import PytestAssertRewriteWarning + + self.config.issue_config_time_warning( + PytestAssertRewriteWarning( + "Module already imported so cannot be rewritten: %s" % name + ), + stacklevel=5, + ) + + def get_data(self, pathname: Union[str, bytes]) -> bytes: + """Optional PEP302 get_data API.""" + with open(pathname, "rb") as f: + return f.read() + + if sys.version_info >= (3, 10): + if sys.version_info >= (3, 12): + from importlib.resources.abc import TraversableResources + else: + from importlib.abc import TraversableResources + + def get_resource_reader(self, name: str) -> TraversableResources: # type: ignore + if sys.version_info < (3, 11): + from importlib.readers import FileReader + else: + from importlib.resources.readers import FileReader + + return FileReader( # type:ignore[no-any-return] + types.SimpleNamespace(path=self._rewritten_names[name]) + ) + + +def _write_pyc_fp( + fp: IO[bytes], source_stat: os.stat_result, co: types.CodeType +) -> None: + # Technically, we don't have to have the same pyc format as + # (C)Python, since these "pycs" should never be seen by builtin + # import. However, there's little reason to deviate. + fp.write(importlib.util.MAGIC_NUMBER) + # https://www.python.org/dev/peps/pep-0552/ + flags = b"\x00\x00\x00\x00" + fp.write(flags) + # as of now, bytecode header expects 32-bit numbers for size and mtime (#4903) + mtime = int(source_stat.st_mtime) & 0xFFFFFFFF + size = source_stat.st_size & 0xFFFFFFFF + # " bool: + proc_pyc = f"{pyc}.{os.getpid()}" + try: + with open(proc_pyc, "wb") as fp: + _write_pyc_fp(fp, source_stat, co) + except OSError as e: + state.trace(f"error writing pyc file at {proc_pyc}: errno={e.errno}") + return False + + try: + os.replace(proc_pyc, pyc) + except OSError as e: + state.trace(f"error writing pyc file at {pyc}: {e}") + # we ignore any failure to write the cache file + # there are many reasons, permission-denied, pycache dir being a + # file etc. + return False + return True + + +def _rewrite_test(fn: Path, config: Config) -> Tuple[os.stat_result, types.CodeType]: + """Read and rewrite *fn* and return the code object.""" + stat = os.stat(fn) + source = fn.read_bytes() + strfn = str(fn) + tree = ast.parse(source, filename=strfn) + rewrite_asserts(tree, source, strfn, config) + co = compile(tree, strfn, "exec", dont_inherit=True) + return stat, co + + +def _read_pyc( + source: Path, pyc: Path, trace: Callable[[str], None] = lambda x: None +) -> Optional[types.CodeType]: + """Possibly read a pytest pyc containing rewritten code. + + Return rewritten code if successful or None if not. + """ + try: + fp = open(pyc, "rb") + except OSError: + return None + with fp: + try: + stat_result = os.stat(source) + mtime = int(stat_result.st_mtime) + size = stat_result.st_size + data = fp.read(16) + except OSError as e: + trace(f"_read_pyc({source}): OSError {e}") + return None + # Check for invalid or out of date pyc file. + if len(data) != (16): + trace("_read_pyc(%s): invalid pyc (too short)" % source) + return None + if data[:4] != importlib.util.MAGIC_NUMBER: + trace("_read_pyc(%s): invalid pyc (bad magic number)" % source) + return None + if data[4:8] != b"\x00\x00\x00\x00": + trace("_read_pyc(%s): invalid pyc (unsupported flags)" % source) + return None + mtime_data = data[8:12] + if int.from_bytes(mtime_data, "little") != mtime & 0xFFFFFFFF: + trace("_read_pyc(%s): out of date" % source) + return None + size_data = data[12:16] + if int.from_bytes(size_data, "little") != size & 0xFFFFFFFF: + trace("_read_pyc(%s): invalid pyc (incorrect size)" % source) + return None + try: + co = marshal.load(fp) + except Exception as e: + trace(f"_read_pyc({source}): marshal.load error {e}") + return None + if not isinstance(co, types.CodeType): + trace("_read_pyc(%s): not a code object" % source) + return None + return co + + +def rewrite_asserts( + mod: ast.Module, + source: bytes, + module_path: Optional[str] = None, + config: Optional[Config] = None, +) -> None: + """Rewrite the assert statements in mod.""" + AssertionRewriter(module_path, config, source).run(mod) + + +def _saferepr(obj: object) -> str: + r"""Get a safe repr of an object for assertion error messages. + + The assertion formatting (util.format_explanation()) requires + newlines to be escaped since they are a special character for it. + Normally assertion.util.format_explanation() does this but for a + custom repr it is possible to contain one of the special escape + sequences, especially '\n{' and '\n}' are likely to be present in + JSON reprs. + """ + maxsize = _get_maxsize_for_saferepr(util._config) + return saferepr(obj, maxsize=maxsize).replace("\n", "\\n") + + +def _get_maxsize_for_saferepr(config: Optional[Config]) -> Optional[int]: + """Get `maxsize` configuration for saferepr based on the given config object.""" + verbosity = config.getoption("verbose") if config is not None else 0 + if verbosity >= 2: + return None + if verbosity >= 1: + return DEFAULT_REPR_MAX_SIZE * 10 + return DEFAULT_REPR_MAX_SIZE + + +def _format_assertmsg(obj: object) -> str: + r"""Format the custom assertion message given. + + For strings this simply replaces newlines with '\n~' so that + util.format_explanation() will preserve them instead of escaping + newlines. For other objects saferepr() is used first. + """ + # reprlib appears to have a bug which means that if a string + # contains a newline it gets escaped, however if an object has a + # .__repr__() which contains newlines it does not get escaped. + # However in either case we want to preserve the newline. + replaces = [("\n", "\n~"), ("%", "%%")] + if not isinstance(obj, str): + obj = saferepr(obj) + replaces.append(("\\n", "\n~")) + + for r1, r2 in replaces: + obj = obj.replace(r1, r2) + + return obj + + +def _should_repr_global_name(obj: object) -> bool: + if callable(obj): + return False + + try: + return not hasattr(obj, "__name__") + except Exception: + return True + + +def _format_boolop(explanations: Iterable[str], is_or: bool) -> str: + explanation = "(" + (is_or and " or " or " and ").join(explanations) + ")" + return explanation.replace("%", "%%") + + +def _call_reprcompare( + ops: Sequence[str], + results: Sequence[bool], + expls: Sequence[str], + each_obj: Sequence[object], +) -> str: + for i, res, expl in zip(range(len(ops)), results, expls): + try: + done = not res + except Exception: + done = True + if done: + break + if util._reprcompare is not None: + custom = util._reprcompare(ops[i], each_obj[i], each_obj[i + 1]) + if custom is not None: + return custom + return expl + + +def _call_assertion_pass(lineno: int, orig: str, expl: str) -> None: + if util._assertion_pass is not None: + util._assertion_pass(lineno, orig, expl) + + +def _check_if_assertion_pass_impl() -> bool: + """Check if any plugins implement the pytest_assertion_pass hook + in order not to generate explanation unnecessarily (might be expensive).""" + return True if util._assertion_pass else False + + +UNARY_MAP = {ast.Not: "not %s", ast.Invert: "~%s", ast.USub: "-%s", ast.UAdd: "+%s"} + +BINOP_MAP = { + ast.BitOr: "|", + ast.BitXor: "^", + ast.BitAnd: "&", + ast.LShift: "<<", + ast.RShift: ">>", + ast.Add: "+", + ast.Sub: "-", + ast.Mult: "*", + ast.Div: "/", + ast.FloorDiv: "//", + ast.Mod: "%%", # escaped for string formatting + ast.Eq: "==", + ast.NotEq: "!=", + ast.Lt: "<", + ast.LtE: "<=", + ast.Gt: ">", + ast.GtE: ">=", + ast.Pow: "**", + ast.Is: "is", + ast.IsNot: "is not", + ast.In: "in", + ast.NotIn: "not in", + ast.MatMult: "@", +} + + +def traverse_node(node: ast.AST) -> Iterator[ast.AST]: + """Recursively yield node and all its children in depth-first order.""" + yield node + for child in ast.iter_child_nodes(node): + yield from traverse_node(child) + + +@functools.lru_cache(maxsize=1) +def _get_assertion_exprs(src: bytes) -> Dict[int, str]: + """Return a mapping from {lineno: "assertion test expression"}.""" + ret: Dict[int, str] = {} + + depth = 0 + lines: List[str] = [] + assert_lineno: Optional[int] = None + seen_lines: Set[int] = set() + + def _write_and_reset() -> None: + nonlocal depth, lines, assert_lineno, seen_lines + assert assert_lineno is not None + ret[assert_lineno] = "".join(lines).rstrip().rstrip("\\") + depth = 0 + lines = [] + assert_lineno = None + seen_lines = set() + + tokens = tokenize.tokenize(io.BytesIO(src).readline) + for tp, source, (lineno, offset), _, line in tokens: + if tp == tokenize.NAME and source == "assert": + assert_lineno = lineno + elif assert_lineno is not None: + # keep track of depth for the assert-message `,` lookup + if tp == tokenize.OP and source in "([{": + depth += 1 + elif tp == tokenize.OP and source in ")]}": + depth -= 1 + + if not lines: + lines.append(line[offset:]) + seen_lines.add(lineno) + # a non-nested comma separates the expression from the message + elif depth == 0 and tp == tokenize.OP and source == ",": + # one line assert with message + if lineno in seen_lines and len(lines) == 1: + offset_in_trimmed = offset + len(lines[-1]) - len(line) + lines[-1] = lines[-1][:offset_in_trimmed] + # multi-line assert with message + elif lineno in seen_lines: + lines[-1] = lines[-1][:offset] + # multi line assert with escapd newline before message + else: + lines.append(line[:offset]) + _write_and_reset() + elif tp in {tokenize.NEWLINE, tokenize.ENDMARKER}: + _write_and_reset() + elif lines and lineno not in seen_lines: + lines.append(line) + seen_lines.add(lineno) + + return ret + + +def _get_ast_constant_value(value: astStr) -> object: + if sys.version_info >= (3, 8): + return value.value + else: + return value.s + + +class AssertionRewriter(ast.NodeVisitor): + """Assertion rewriting implementation. + + The main entrypoint is to call .run() with an ast.Module instance, + this will then find all the assert statements and rewrite them to + provide intermediate values and a detailed assertion error. See + http://pybites.blogspot.be/2011/07/behind-scenes-of-pytests-new-assertion.html + for an overview of how this works. + + The entry point here is .run() which will iterate over all the + statements in an ast.Module and for each ast.Assert statement it + finds call .visit() with it. Then .visit_Assert() takes over and + is responsible for creating new ast statements to replace the + original assert statement: it rewrites the test of an assertion + to provide intermediate values and replace it with an if statement + which raises an assertion error with a detailed explanation in + case the expression is false and calls pytest_assertion_pass hook + if expression is true. + + For this .visit_Assert() uses the visitor pattern to visit all the + AST nodes of the ast.Assert.test field, each visit call returning + an AST node and the corresponding explanation string. During this + state is kept in several instance attributes: + + :statements: All the AST statements which will replace the assert + statement. + + :variables: This is populated by .variable() with each variable + used by the statements so that they can all be set to None at + the end of the statements. + + :variable_counter: Counter to create new unique variables needed + by statements. Variables are created using .variable() and + have the form of "@py_assert0". + + :expl_stmts: The AST statements which will be executed to get + data from the assertion. This is the code which will construct + the detailed assertion message that is used in the AssertionError + or for the pytest_assertion_pass hook. + + :explanation_specifiers: A dict filled by .explanation_param() + with %-formatting placeholders and their corresponding + expressions to use in the building of an assertion message. + This is used by .pop_format_context() to build a message. + + :stack: A stack of the explanation_specifiers dicts maintained by + .push_format_context() and .pop_format_context() which allows + to build another %-formatted string while already building one. + + :scope: A tuple containing the current scope used for variables_overwrite. + + :variables_overwrite: A dict filled with references to variables + that change value within an assert. This happens when a variable is + reassigned with the walrus operator + + This state, except the variables_overwrite, is reset on every new assert + statement visited and used by the other visitors. + """ + + def __init__( + self, module_path: Optional[str], config: Optional[Config], source: bytes + ) -> None: + super().__init__() + self.module_path = module_path + self.config = config + if config is not None: + self.enable_assertion_pass_hook = config.getini( + "enable_assertion_pass_hook" + ) + else: + self.enable_assertion_pass_hook = False + self.source = source + self.scope: tuple[ast.AST, ...] = () + self.variables_overwrite: defaultdict[ + tuple[ast.AST, ...], Dict[str, str] + ] = defaultdict(dict) + + def run(self, mod: ast.Module) -> None: + """Find all assert statements in *mod* and rewrite them.""" + if not mod.body: + # Nothing to do. + return + + # We'll insert some special imports at the top of the module, but after any + # docstrings and __future__ imports, so first figure out where that is. + doc = getattr(mod, "docstring", None) + expect_docstring = doc is None + if doc is not None and self.is_rewrite_disabled(doc): + return + pos = 0 + item = None + for item in mod.body: + if ( + expect_docstring + and isinstance(item, ast.Expr) + and isinstance(item.value, astStr) + and isinstance(_get_ast_constant_value(item.value), str) + ): + doc = _get_ast_constant_value(item.value) + assert isinstance(doc, str) + if self.is_rewrite_disabled(doc): + return + expect_docstring = False + elif ( + isinstance(item, ast.ImportFrom) + and item.level == 0 + and item.module == "__future__" + ): + pass + else: + break + pos += 1 + # Special case: for a decorated function, set the lineno to that of the + # first decorator, not the `def`. Issue #4984. + if isinstance(item, ast.FunctionDef) and item.decorator_list: + lineno = item.decorator_list[0].lineno + else: + lineno = item.lineno + # Now actually insert the special imports. + if sys.version_info >= (3, 10): + aliases = [ + ast.alias("builtins", "@py_builtins", lineno=lineno, col_offset=0), + ast.alias( + "_pytest.assertion.rewrite", + "@pytest_ar", + lineno=lineno, + col_offset=0, + ), + ] + else: + aliases = [ + ast.alias("builtins", "@py_builtins"), + ast.alias("_pytest.assertion.rewrite", "@pytest_ar"), + ] + imports = [ + ast.Import([alias], lineno=lineno, col_offset=0) for alias in aliases + ] + mod.body[pos:pos] = imports + + # Collect asserts. + self.scope = (mod,) + nodes: List[Union[ast.AST, Sentinel]] = [mod] + while nodes: + node = nodes.pop() + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)): + self.scope = tuple((*self.scope, node)) + nodes.append(_SCOPE_END_MARKER) + if node == _SCOPE_END_MARKER: + self.scope = self.scope[:-1] + continue + assert isinstance(node, ast.AST) + for name, field in ast.iter_fields(node): + if isinstance(field, list): + new: List[ast.AST] = [] + for i, child in enumerate(field): + if isinstance(child, ast.Assert): + # Transform assert. + new.extend(self.visit(child)) + else: + new.append(child) + if isinstance(child, ast.AST): + nodes.append(child) + setattr(node, name, new) + elif ( + isinstance(field, ast.AST) + # Don't recurse into expressions as they can't contain + # asserts. + and not isinstance(field, ast.expr) + ): + nodes.append(field) + + @staticmethod + def is_rewrite_disabled(docstring: str) -> bool: + return "PYTEST_DONT_REWRITE" in docstring + + def variable(self) -> str: + """Get a new variable.""" + # Use a character invalid in python identifiers to avoid clashing. + name = "@py_assert" + str(next(self.variable_counter)) + self.variables.append(name) + return name + + def assign(self, expr: ast.expr) -> ast.Name: + """Give *expr* a name.""" + name = self.variable() + self.statements.append(ast.Assign([ast.Name(name, ast.Store())], expr)) + return ast.Name(name, ast.Load()) + + def display(self, expr: ast.expr) -> ast.expr: + """Call saferepr on the expression.""" + return self.helper("_saferepr", expr) + + def helper(self, name: str, *args: ast.expr) -> ast.expr: + """Call a helper in this module.""" + py_name = ast.Name("@pytest_ar", ast.Load()) + attr = ast.Attribute(py_name, name, ast.Load()) + return ast.Call(attr, list(args), []) + + def builtin(self, name: str) -> ast.Attribute: + """Return the builtin called *name*.""" + builtin_name = ast.Name("@py_builtins", ast.Load()) + return ast.Attribute(builtin_name, name, ast.Load()) + + def explanation_param(self, expr: ast.expr) -> str: + """Return a new named %-formatting placeholder for expr. + + This creates a %-formatting placeholder for expr in the + current formatting context, e.g. ``%(py0)s``. The placeholder + and expr are placed in the current format context so that it + can be used on the next call to .pop_format_context(). + """ + specifier = "py" + str(next(self.variable_counter)) + self.explanation_specifiers[specifier] = expr + return "%(" + specifier + ")s" + + def push_format_context(self) -> None: + """Create a new formatting context. + + The format context is used for when an explanation wants to + have a variable value formatted in the assertion message. In + this case the value required can be added using + .explanation_param(). Finally .pop_format_context() is used + to format a string of %-formatted values as added by + .explanation_param(). + """ + self.explanation_specifiers: Dict[str, ast.expr] = {} + self.stack.append(self.explanation_specifiers) + + def pop_format_context(self, expl_expr: ast.expr) -> ast.Name: + """Format the %-formatted string with current format context. + + The expl_expr should be an str ast.expr instance constructed from + the %-placeholders created by .explanation_param(). This will + add the required code to format said string to .expl_stmts and + return the ast.Name instance of the formatted string. + """ + current = self.stack.pop() + if self.stack: + self.explanation_specifiers = self.stack[-1] + keys = [astStr(key) for key in current.keys()] + format_dict = ast.Dict(keys, list(current.values())) + form = ast.BinOp(expl_expr, ast.Mod(), format_dict) + name = "@py_format" + str(next(self.variable_counter)) + if self.enable_assertion_pass_hook: + self.format_variables.append(name) + self.expl_stmts.append(ast.Assign([ast.Name(name, ast.Store())], form)) + return ast.Name(name, ast.Load()) + + def generic_visit(self, node: ast.AST) -> Tuple[ast.Name, str]: + """Handle expressions we don't have custom code for.""" + assert isinstance(node, ast.expr) + res = self.assign(node) + return res, self.explanation_param(self.display(res)) + + def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]: + """Return the AST statements to replace the ast.Assert instance. + + This rewrites the test of an assertion to provide + intermediate values and replace it with an if statement which + raises an assertion error with a detailed explanation in case + the expression is false. + """ + if isinstance(assert_.test, ast.Tuple) and len(assert_.test.elts) >= 1: + from _pytest.warning_types import PytestAssertRewriteWarning + import warnings + + # TODO: This assert should not be needed. + assert self.module_path is not None + warnings.warn_explicit( + PytestAssertRewriteWarning( + "assertion is always true, perhaps remove parentheses?" + ), + category=None, + filename=self.module_path, + lineno=assert_.lineno, + ) + + self.statements: List[ast.stmt] = [] + self.variables: List[str] = [] + self.variable_counter = itertools.count() + + if self.enable_assertion_pass_hook: + self.format_variables: List[str] = [] + + self.stack: List[Dict[str, ast.expr]] = [] + self.expl_stmts: List[ast.stmt] = [] + self.push_format_context() + # Rewrite assert into a bunch of statements. + top_condition, explanation = self.visit(assert_.test) + + negation = ast.UnaryOp(ast.Not(), top_condition) + + if self.enable_assertion_pass_hook: # Experimental pytest_assertion_pass hook + msg = self.pop_format_context(astStr(explanation)) + + # Failed + if assert_.msg: + assertmsg = self.helper("_format_assertmsg", assert_.msg) + gluestr = "\n>assert " + else: + assertmsg = astStr("") + gluestr = "assert " + err_explanation = ast.BinOp(astStr(gluestr), ast.Add(), msg) + err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation) + err_name = ast.Name("AssertionError", ast.Load()) + fmt = self.helper("_format_explanation", err_msg) + exc = ast.Call(err_name, [fmt], []) + raise_ = ast.Raise(exc, None) + statements_fail = [] + statements_fail.extend(self.expl_stmts) + statements_fail.append(raise_) + + # Passed + fmt_pass = self.helper("_format_explanation", msg) + orig = _get_assertion_exprs(self.source)[assert_.lineno] + hook_call_pass = ast.Expr( + self.helper( + "_call_assertion_pass", + astNum(assert_.lineno), + astStr(orig), + fmt_pass, + ) + ) + # If any hooks implement assert_pass hook + hook_impl_test = ast.If( + self.helper("_check_if_assertion_pass_impl"), + self.expl_stmts + [hook_call_pass], + [], + ) + statements_pass = [hook_impl_test] + + # Test for assertion condition + main_test = ast.If(negation, statements_fail, statements_pass) + self.statements.append(main_test) + if self.format_variables: + variables = [ + ast.Name(name, ast.Store()) for name in self.format_variables + ] + clear_format = ast.Assign(variables, astNameConstant(None)) + self.statements.append(clear_format) + + else: # Original assertion rewriting + # Create failure message. + body = self.expl_stmts + self.statements.append(ast.If(negation, body, [])) + if assert_.msg: + assertmsg = self.helper("_format_assertmsg", assert_.msg) + explanation = "\n>assert " + explanation + else: + assertmsg = astStr("") + explanation = "assert " + explanation + template = ast.BinOp(assertmsg, ast.Add(), astStr(explanation)) + msg = self.pop_format_context(template) + fmt = self.helper("_format_explanation", msg) + err_name = ast.Name("AssertionError", ast.Load()) + exc = ast.Call(err_name, [fmt], []) + raise_ = ast.Raise(exc, None) + + body.append(raise_) + + # Clear temporary variables by setting them to None. + if self.variables: + variables = [ast.Name(name, ast.Store()) for name in self.variables] + clear = ast.Assign(variables, astNameConstant(None)) + self.statements.append(clear) + # Fix locations (line numbers/column offsets). + for stmt in self.statements: + for node in traverse_node(stmt): + ast.copy_location(node, assert_) + return self.statements + + def visit_NamedExpr(self, name: namedExpr) -> Tuple[namedExpr, str]: + # This method handles the 'walrus operator' repr of the target + # name if it's a local variable or _should_repr_global_name() + # thinks it's acceptable. + locs = ast.Call(self.builtin("locals"), [], []) + target_id = name.target.id # type: ignore[attr-defined] + inlocs = ast.Compare(astStr(target_id), [ast.In()], [locs]) + dorepr = self.helper("_should_repr_global_name", name) + test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) + expr = ast.IfExp(test, self.display(name), astStr(target_id)) + return name, self.explanation_param(expr) + + def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]: + # Display the repr of the name if it's a local variable or + # _should_repr_global_name() thinks it's acceptable. + locs = ast.Call(self.builtin("locals"), [], []) + inlocs = ast.Compare(astStr(name.id), [ast.In()], [locs]) + dorepr = self.helper("_should_repr_global_name", name) + test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) + expr = ast.IfExp(test, self.display(name), astStr(name.id)) + return name, self.explanation_param(expr) + + def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]: + res_var = self.variable() + expl_list = self.assign(ast.List([], ast.Load())) + app = ast.Attribute(expl_list, "append", ast.Load()) + is_or = int(isinstance(boolop.op, ast.Or)) + body = save = self.statements + fail_save = self.expl_stmts + levels = len(boolop.values) - 1 + self.push_format_context() + # Process each operand, short-circuiting if needed. + for i, v in enumerate(boolop.values): + if i: + fail_inner: List[ast.stmt] = [] + # cond is set in a prior loop iteration below + self.expl_stmts.append(ast.If(cond, fail_inner, [])) # noqa + self.expl_stmts = fail_inner + # Check if the left operand is a namedExpr and the value has already been visited + if ( + isinstance(v, ast.Compare) + and isinstance(v.left, namedExpr) + and v.left.target.id + in [ + ast_expr.id + for ast_expr in boolop.values[:i] + if hasattr(ast_expr, "id") + ] + ): + pytest_temp = self.variable() + self.variables_overwrite[self.scope][ + v.left.target.id + ] = v.left # type:ignore[assignment] + v.left.target.id = pytest_temp + self.push_format_context() + res, expl = self.visit(v) + body.append(ast.Assign([ast.Name(res_var, ast.Store())], res)) + expl_format = self.pop_format_context(astStr(expl)) + call = ast.Call(app, [expl_format], []) + self.expl_stmts.append(ast.Expr(call)) + if i < levels: + cond: ast.expr = res + if is_or: + cond = ast.UnaryOp(ast.Not(), cond) + inner: List[ast.stmt] = [] + self.statements.append(ast.If(cond, inner, [])) + self.statements = body = inner + self.statements = save + self.expl_stmts = fail_save + expl_template = self.helper("_format_boolop", expl_list, astNum(is_or)) + expl = self.pop_format_context(expl_template) + return ast.Name(res_var, ast.Load()), self.explanation_param(expl) + + def visit_UnaryOp(self, unary: ast.UnaryOp) -> Tuple[ast.Name, str]: + pattern = UNARY_MAP[unary.op.__class__] + operand_res, operand_expl = self.visit(unary.operand) + res = self.assign(ast.UnaryOp(unary.op, operand_res)) + return res, pattern % (operand_expl,) + + def visit_BinOp(self, binop: ast.BinOp) -> Tuple[ast.Name, str]: + symbol = BINOP_MAP[binop.op.__class__] + left_expr, left_expl = self.visit(binop.left) + right_expr, right_expl = self.visit(binop.right) + explanation = f"({left_expl} {symbol} {right_expl})" + res = self.assign(ast.BinOp(left_expr, binop.op, right_expr)) + return res, explanation + + def visit_Call(self, call: ast.Call) -> Tuple[ast.Name, str]: + new_func, func_expl = self.visit(call.func) + arg_expls = [] + new_args = [] + new_kwargs = [] + for arg in call.args: + if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite.get( + self.scope, {} + ): + arg = self.variables_overwrite[self.scope][ + arg.id + ] # type:ignore[assignment] + res, expl = self.visit(arg) + arg_expls.append(expl) + new_args.append(res) + for keyword in call.keywords: + if isinstance( + keyword.value, ast.Name + ) and keyword.value.id in self.variables_overwrite.get(self.scope, {}): + keyword.value = self.variables_overwrite[self.scope][ + keyword.value.id + ] # type:ignore[assignment] + res, expl = self.visit(keyword.value) + new_kwargs.append(ast.keyword(keyword.arg, res)) + if keyword.arg: + arg_expls.append(keyword.arg + "=" + expl) + else: # **args have `arg` keywords with an .arg of None + arg_expls.append("**" + expl) + + expl = "{}({})".format(func_expl, ", ".join(arg_expls)) + new_call = ast.Call(new_func, new_args, new_kwargs) + res = self.assign(new_call) + res_expl = self.explanation_param(self.display(res)) + outer_expl = f"{res_expl}\n{{{res_expl} = {expl}\n}}" + return res, outer_expl + + def visit_Starred(self, starred: ast.Starred) -> Tuple[ast.Starred, str]: + # A Starred node can appear in a function call. + res, expl = self.visit(starred.value) + new_starred = ast.Starred(res, starred.ctx) + return new_starred, "*" + expl + + def visit_Attribute(self, attr: ast.Attribute) -> Tuple[ast.Name, str]: + if not isinstance(attr.ctx, ast.Load): + return self.generic_visit(attr) + value, value_expl = self.visit(attr.value) + res = self.assign(ast.Attribute(value, attr.attr, ast.Load())) + res_expl = self.explanation_param(self.display(res)) + pat = "%s\n{%s = %s.%s\n}" + expl = pat % (res_expl, res_expl, value_expl, attr.attr) + return res, expl + + def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]: + self.push_format_context() + # We first check if we have overwritten a variable in the previous assert + if isinstance( + comp.left, ast.Name + ) and comp.left.id in self.variables_overwrite.get(self.scope, {}): + comp.left = self.variables_overwrite[self.scope][ + comp.left.id + ] # type:ignore[assignment] + if isinstance(comp.left, namedExpr): + self.variables_overwrite[self.scope][ + comp.left.target.id + ] = comp.left # type:ignore[assignment] + left_res, left_expl = self.visit(comp.left) + if isinstance(comp.left, (ast.Compare, ast.BoolOp)): + left_expl = f"({left_expl})" + res_variables = [self.variable() for i in range(len(comp.ops))] + load_names = [ast.Name(v, ast.Load()) for v in res_variables] + store_names = [ast.Name(v, ast.Store()) for v in res_variables] + it = zip(range(len(comp.ops)), comp.ops, comp.comparators) + expls = [] + syms = [] + results = [left_res] + for i, op, next_operand in it: + if ( + isinstance(next_operand, namedExpr) + and isinstance(left_res, ast.Name) + and next_operand.target.id == left_res.id + ): + next_operand.target.id = self.variable() + self.variables_overwrite[self.scope][ + left_res.id + ] = next_operand # type:ignore[assignment] + next_res, next_expl = self.visit(next_operand) + if isinstance(next_operand, (ast.Compare, ast.BoolOp)): + next_expl = f"({next_expl})" + results.append(next_res) + sym = BINOP_MAP[op.__class__] + syms.append(astStr(sym)) + expl = f"{left_expl} {sym} {next_expl}" + expls.append(astStr(expl)) + res_expr = ast.Compare(left_res, [op], [next_res]) + self.statements.append(ast.Assign([store_names[i]], res_expr)) + left_res, left_expl = next_res, next_expl + # Use pytest.assertion.util._reprcompare if that's available. + expl_call = self.helper( + "_call_reprcompare", + ast.Tuple(syms, ast.Load()), + ast.Tuple(load_names, ast.Load()), + ast.Tuple(expls, ast.Load()), + ast.Tuple(results, ast.Load()), + ) + if len(comp.ops) > 1: + res: ast.expr = ast.BoolOp(ast.And(), load_names) + else: + res = load_names[0] + + return res, self.explanation_param(self.pop_format_context(expl_call)) + + +def try_makedirs(cache_dir: Path) -> bool: + """Attempt to create the given directory and sub-directories exist. + + Returns True if successful or if it already exists. + """ + try: + os.makedirs(cache_dir, exist_ok=True) + except (FileNotFoundError, NotADirectoryError, FileExistsError): + # One of the path components was not a directory: + # - we're in a zip file + # - it is a file + return False + except PermissionError: + return False + except OSError as e: + # as of now, EROFS doesn't have an equivalent OSError-subclass + if e.errno == errno.EROFS: + return False + raise + return True + + +def get_cache_dir(file_path: Path) -> Path: + """Return the cache directory to write .pyc files for the given .py file path.""" + if sys.version_info >= (3, 8) and sys.pycache_prefix: + # given: + # prefix = '/tmp/pycs' + # path = '/home/user/proj/test_app.py' + # we want: + # '/tmp/pycs/home/user/proj' + return Path(sys.pycache_prefix) / Path(*file_path.parts[1:-1]) + else: + # classic pycache directory + return file_path.parent / "__pycache__" diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/truncate.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/truncate.py new file mode 100644 index 00000000..dfd6f65d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/truncate.py @@ -0,0 +1,115 @@ +"""Utilities for truncating assertion output. + +Current default behaviour is to truncate assertion explanations at +~8 terminal lines, unless running in "-vv" mode or running on CI. +""" +from typing import List +from typing import Optional + +from _pytest.assertion import util +from _pytest.nodes import Item + + +DEFAULT_MAX_LINES = 8 +DEFAULT_MAX_CHARS = 8 * 80 +USAGE_MSG = "use '-vv' to show" + + +def truncate_if_required( + explanation: List[str], item: Item, max_length: Optional[int] = None +) -> List[str]: + """Truncate this assertion explanation if the given test item is eligible.""" + if _should_truncate_item(item): + return _truncate_explanation(explanation) + return explanation + + +def _should_truncate_item(item: Item) -> bool: + """Whether or not this test item is eligible for truncation.""" + verbose = item.config.option.verbose + return verbose < 2 and not util.running_on_ci() + + +def _truncate_explanation( + input_lines: List[str], + max_lines: Optional[int] = None, + max_chars: Optional[int] = None, +) -> List[str]: + """Truncate given list of strings that makes up the assertion explanation. + + Truncates to either 8 lines, or 640 characters - whichever the input reaches + first, taking the truncation explanation into account. The remaining lines + will be replaced by a usage message. + """ + if max_lines is None: + max_lines = DEFAULT_MAX_LINES + if max_chars is None: + max_chars = DEFAULT_MAX_CHARS + + # Check if truncation required + input_char_count = len("".join(input_lines)) + # The length of the truncation explanation depends on the number of lines + # removed but is at least 68 characters: + # The real value is + # 64 (for the base message: + # '...\n...Full output truncated (1 line hidden), use '-vv' to show")' + # ) + # + 1 (for plural) + # + int(math.log10(len(input_lines) - max_lines)) (number of hidden line, at least 1) + # + 3 for the '...' added to the truncated line + # But if there's more than 100 lines it's very likely that we're going to + # truncate, so we don't need the exact value using log10. + tolerable_max_chars = ( + max_chars + 70 # 64 + 1 (for plural) + 2 (for '99') + 3 for '...' + ) + # The truncation explanation add two lines to the output + tolerable_max_lines = max_lines + 2 + if ( + len(input_lines) <= tolerable_max_lines + and input_char_count <= tolerable_max_chars + ): + return input_lines + # Truncate first to max_lines, and then truncate to max_chars if necessary + truncated_explanation = input_lines[:max_lines] + truncated_char = True + # We reevaluate the need to truncate chars following removal of some lines + if len("".join(truncated_explanation)) > tolerable_max_chars: + truncated_explanation = _truncate_by_char_count( + truncated_explanation, max_chars + ) + else: + truncated_char = False + + truncated_line_count = len(input_lines) - len(truncated_explanation) + if truncated_explanation[-1]: + # Add ellipsis and take into account part-truncated final line + truncated_explanation[-1] = truncated_explanation[-1] + "..." + if truncated_char: + # It's possible that we did not remove any char from this line + truncated_line_count += 1 + else: + # Add proper ellipsis when we were able to fit a full line exactly + truncated_explanation[-1] = "..." + return truncated_explanation + [ + "", + f"...Full output truncated ({truncated_line_count} line" + f"{'' if truncated_line_count == 1 else 's'} hidden), {USAGE_MSG}", + ] + + +def _truncate_by_char_count(input_lines: List[str], max_chars: int) -> List[str]: + # Find point at which input length exceeds total allowed length + iterated_char_count = 0 + for iterated_index, input_line in enumerate(input_lines): + if iterated_char_count + len(input_line) > max_chars: + break + iterated_char_count += len(input_line) + + # Create truncated explanation with modified final line + truncated_result = input_lines[:iterated_index] + final_line = input_lines[iterated_index] + if final_line: + final_line_truncate_point = max_chars - iterated_char_count + final_line = final_line[:final_line_truncate_point] + truncated_result.append(final_line) + return truncated_result diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/util.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/util.py new file mode 100644 index 00000000..39ca5403 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/util.py @@ -0,0 +1,522 @@ +"""Utilities for assertion debugging.""" +import collections.abc +import os +import pprint +from typing import AbstractSet +from typing import Any +from typing import Callable +from typing import Iterable +from typing import List +from typing import Mapping +from typing import Optional +from typing import Sequence +from unicodedata import normalize + +import _pytest._code +from _pytest import outcomes +from _pytest._io.saferepr import _pformat_dispatch +from _pytest._io.saferepr import saferepr +from _pytest._io.saferepr import saferepr_unlimited +from _pytest.config import Config + +# The _reprcompare attribute on the util module is used by the new assertion +# interpretation code and assertion rewriter to detect this plugin was +# loaded and in turn call the hooks defined here as part of the +# DebugInterpreter. +_reprcompare: Optional[Callable[[str, object, object], Optional[str]]] = None + +# Works similarly as _reprcompare attribute. Is populated with the hook call +# when pytest_runtest_setup is called. +_assertion_pass: Optional[Callable[[int, str, str], None]] = None + +# Config object which is assigned during pytest_runtest_protocol. +_config: Optional[Config] = None + + +def format_explanation(explanation: str) -> str: + r"""Format an explanation. + + Normally all embedded newlines are escaped, however there are + three exceptions: \n{, \n} and \n~. The first two are intended + cover nested explanations, see function and attribute explanations + for examples (.visit_Call(), visit_Attribute()). The last one is + for when one explanation needs to span multiple lines, e.g. when + displaying diffs. + """ + lines = _split_explanation(explanation) + result = _format_lines(lines) + return "\n".join(result) + + +def _split_explanation(explanation: str) -> List[str]: + r"""Return a list of individual lines in the explanation. + + This will return a list of lines split on '\n{', '\n}' and '\n~'. + Any other newlines will be escaped and appear in the line as the + literal '\n' characters. + """ + raw_lines = (explanation or "").split("\n") + lines = [raw_lines[0]] + for values in raw_lines[1:]: + if values and values[0] in ["{", "}", "~", ">"]: + lines.append(values) + else: + lines[-1] += "\\n" + values + return lines + + +def _format_lines(lines: Sequence[str]) -> List[str]: + """Format the individual lines. + + This will replace the '{', '}' and '~' characters of our mini formatting + language with the proper 'where ...', 'and ...' and ' + ...' text, taking + care of indentation along the way. + + Return a list of formatted lines. + """ + result = list(lines[:1]) + stack = [0] + stackcnt = [0] + for line in lines[1:]: + if line.startswith("{"): + if stackcnt[-1]: + s = "and " + else: + s = "where " + stack.append(len(result)) + stackcnt[-1] += 1 + stackcnt.append(0) + result.append(" +" + " " * (len(stack) - 1) + s + line[1:]) + elif line.startswith("}"): + stack.pop() + stackcnt.pop() + result[stack[-1]] += line[1:] + else: + assert line[0] in ["~", ">"] + stack[-1] += 1 + indent = len(stack) if line.startswith("~") else len(stack) - 1 + result.append(" " * indent + line[1:]) + assert len(stack) == 1 + return result + + +def issequence(x: Any) -> bool: + return isinstance(x, collections.abc.Sequence) and not isinstance(x, str) + + +def istext(x: Any) -> bool: + return isinstance(x, str) + + +def isdict(x: Any) -> bool: + return isinstance(x, dict) + + +def isset(x: Any) -> bool: + return isinstance(x, (set, frozenset)) + + +def isnamedtuple(obj: Any) -> bool: + return isinstance(obj, tuple) and getattr(obj, "_fields", None) is not None + + +def isdatacls(obj: Any) -> bool: + return getattr(obj, "__dataclass_fields__", None) is not None + + +def isattrs(obj: Any) -> bool: + return getattr(obj, "__attrs_attrs__", None) is not None + + +def isiterable(obj: Any) -> bool: + try: + iter(obj) + return not istext(obj) + except Exception: + return False + + +def has_default_eq( + obj: object, +) -> bool: + """Check if an instance of an object contains the default eq + + First, we check if the object's __eq__ attribute has __code__, + if so, we check the equally of the method code filename (__code__.co_filename) + to the default one generated by the dataclass and attr module + for dataclasses the default co_filename is , for attrs class, the __eq__ should contain "attrs eq generated" + """ + # inspired from https://github.com/willmcgugan/rich/blob/07d51ffc1aee6f16bd2e5a25b4e82850fb9ed778/rich/pretty.py#L68 + if hasattr(obj.__eq__, "__code__") and hasattr(obj.__eq__.__code__, "co_filename"): + code_filename = obj.__eq__.__code__.co_filename + + if isattrs(obj): + return "attrs generated eq" in code_filename + + return code_filename == "" # data class + return True + + +def assertrepr_compare( + config, op: str, left: Any, right: Any, use_ascii: bool = False +) -> Optional[List[str]]: + """Return specialised explanations for some operators/operands.""" + verbose = config.getoption("verbose") + + # Strings which normalize equal are often hard to distinguish when printed; use ascii() to make this easier. + # See issue #3246. + use_ascii = ( + isinstance(left, str) + and isinstance(right, str) + and normalize("NFD", left) == normalize("NFD", right) + ) + + if verbose > 1: + left_repr = saferepr_unlimited(left, use_ascii=use_ascii) + right_repr = saferepr_unlimited(right, use_ascii=use_ascii) + else: + # XXX: "15 chars indentation" is wrong + # ("E AssertionError: assert "); should use term width. + maxsize = ( + 80 - 15 - len(op) - 2 + ) // 2 # 15 chars indentation, 1 space around op + + left_repr = saferepr(left, maxsize=maxsize, use_ascii=use_ascii) + right_repr = saferepr(right, maxsize=maxsize, use_ascii=use_ascii) + + summary = f"{left_repr} {op} {right_repr}" + + explanation = None + try: + if op == "==": + explanation = _compare_eq_any(left, right, verbose) + elif op == "not in": + if istext(left) and istext(right): + explanation = _notin_text(left, right, verbose) + except outcomes.Exit: + raise + except Exception: + explanation = [ + "(pytest_assertion plugin: representation of details failed: {}.".format( + _pytest._code.ExceptionInfo.from_current()._getreprcrash() + ), + " Probably an object has a faulty __repr__.)", + ] + + if not explanation: + return None + + return [summary] + explanation + + +def _compare_eq_any(left: Any, right: Any, verbose: int = 0) -> List[str]: + explanation = [] + if istext(left) and istext(right): + explanation = _diff_text(left, right, verbose) + else: + from _pytest.python_api import ApproxBase + + if isinstance(left, ApproxBase) or isinstance(right, ApproxBase): + # Although the common order should be obtained == expected, this ensures both ways + approx_side = left if isinstance(left, ApproxBase) else right + other_side = right if isinstance(left, ApproxBase) else left + + explanation = approx_side._repr_compare(other_side) + elif type(left) == type(right) and ( + isdatacls(left) or isattrs(left) or isnamedtuple(left) + ): + # Note: unlike dataclasses/attrs, namedtuples compare only the + # field values, not the type or field names. But this branch + # intentionally only handles the same-type case, which was often + # used in older code bases before dataclasses/attrs were available. + explanation = _compare_eq_cls(left, right, verbose) + elif issequence(left) and issequence(right): + explanation = _compare_eq_sequence(left, right, verbose) + elif isset(left) and isset(right): + explanation = _compare_eq_set(left, right, verbose) + elif isdict(left) and isdict(right): + explanation = _compare_eq_dict(left, right, verbose) + + if isiterable(left) and isiterable(right): + expl = _compare_eq_iterable(left, right, verbose) + explanation.extend(expl) + + return explanation + + +def _diff_text(left: str, right: str, verbose: int = 0) -> List[str]: + """Return the explanation for the diff between text. + + Unless --verbose is used this will skip leading and trailing + characters which are identical to keep the diff minimal. + """ + from difflib import ndiff + + explanation: List[str] = [] + + if verbose < 1: + i = 0 # just in case left or right has zero length + for i in range(min(len(left), len(right))): + if left[i] != right[i]: + break + if i > 42: + i -= 10 # Provide some context + explanation = [ + "Skipping %s identical leading characters in diff, use -v to show" % i + ] + left = left[i:] + right = right[i:] + if len(left) == len(right): + for i in range(len(left)): + if left[-i] != right[-i]: + break + if i > 42: + i -= 10 # Provide some context + explanation += [ + "Skipping {} identical trailing " + "characters in diff, use -v to show".format(i) + ] + left = left[:-i] + right = right[:-i] + keepends = True + if left.isspace() or right.isspace(): + left = repr(str(left)) + right = repr(str(right)) + explanation += ["Strings contain only whitespace, escaping them using repr()"] + # "right" is the expected base against which we compare "left", + # see https://github.com/pytest-dev/pytest/issues/3333 + explanation += [ + line.strip("\n") + for line in ndiff(right.splitlines(keepends), left.splitlines(keepends)) + ] + return explanation + + +def _surrounding_parens_on_own_lines(lines: List[str]) -> None: + """Move opening/closing parenthesis/bracket to own lines.""" + opening = lines[0][:1] + if opening in ["(", "[", "{"]: + lines[0] = " " + lines[0][1:] + lines[:] = [opening] + lines + closing = lines[-1][-1:] + if closing in [")", "]", "}"]: + lines[-1] = lines[-1][:-1] + "," + lines[:] = lines + [closing] + + +def _compare_eq_iterable( + left: Iterable[Any], right: Iterable[Any], verbose: int = 0 +) -> List[str]: + if verbose <= 0 and not running_on_ci(): + return ["Use -v to get more diff"] + # dynamic import to speedup pytest + import difflib + + left_formatting = pprint.pformat(left).splitlines() + right_formatting = pprint.pformat(right).splitlines() + + # Re-format for different output lengths. + lines_left = len(left_formatting) + lines_right = len(right_formatting) + if lines_left != lines_right: + left_formatting = _pformat_dispatch(left).splitlines() + right_formatting = _pformat_dispatch(right).splitlines() + + if lines_left > 1 or lines_right > 1: + _surrounding_parens_on_own_lines(left_formatting) + _surrounding_parens_on_own_lines(right_formatting) + + explanation = ["Full diff:"] + # "right" is the expected base against which we compare "left", + # see https://github.com/pytest-dev/pytest/issues/3333 + explanation.extend( + line.rstrip() for line in difflib.ndiff(right_formatting, left_formatting) + ) + return explanation + + +def _compare_eq_sequence( + left: Sequence[Any], right: Sequence[Any], verbose: int = 0 +) -> List[str]: + comparing_bytes = isinstance(left, bytes) and isinstance(right, bytes) + explanation: List[str] = [] + len_left = len(left) + len_right = len(right) + for i in range(min(len_left, len_right)): + if left[i] != right[i]: + if comparing_bytes: + # when comparing bytes, we want to see their ascii representation + # instead of their numeric values (#5260) + # using a slice gives us the ascii representation: + # >>> s = b'foo' + # >>> s[0] + # 102 + # >>> s[0:1] + # b'f' + left_value = left[i : i + 1] + right_value = right[i : i + 1] + else: + left_value = left[i] + right_value = right[i] + + explanation += [f"At index {i} diff: {left_value!r} != {right_value!r}"] + break + + if comparing_bytes: + # when comparing bytes, it doesn't help to show the "sides contain one or more + # items" longer explanation, so skip it + + return explanation + + len_diff = len_left - len_right + if len_diff: + if len_diff > 0: + dir_with_more = "Left" + extra = saferepr(left[len_right]) + else: + len_diff = 0 - len_diff + dir_with_more = "Right" + extra = saferepr(right[len_left]) + + if len_diff == 1: + explanation += [f"{dir_with_more} contains one more item: {extra}"] + else: + explanation += [ + "%s contains %d more items, first extra item: %s" + % (dir_with_more, len_diff, extra) + ] + return explanation + + +def _compare_eq_set( + left: AbstractSet[Any], right: AbstractSet[Any], verbose: int = 0 +) -> List[str]: + explanation = [] + diff_left = left - right + diff_right = right - left + if diff_left: + explanation.append("Extra items in the left set:") + for item in diff_left: + explanation.append(saferepr(item)) + if diff_right: + explanation.append("Extra items in the right set:") + for item in diff_right: + explanation.append(saferepr(item)) + return explanation + + +def _compare_eq_dict( + left: Mapping[Any, Any], right: Mapping[Any, Any], verbose: int = 0 +) -> List[str]: + explanation: List[str] = [] + set_left = set(left) + set_right = set(right) + common = set_left.intersection(set_right) + same = {k: left[k] for k in common if left[k] == right[k]} + if same and verbose < 2: + explanation += ["Omitting %s identical items, use -vv to show" % len(same)] + elif same: + explanation += ["Common items:"] + explanation += pprint.pformat(same).splitlines() + diff = {k for k in common if left[k] != right[k]} + if diff: + explanation += ["Differing items:"] + for k in diff: + explanation += [saferepr({k: left[k]}) + " != " + saferepr({k: right[k]})] + extra_left = set_left - set_right + len_extra_left = len(extra_left) + if len_extra_left: + explanation.append( + "Left contains %d more item%s:" + % (len_extra_left, "" if len_extra_left == 1 else "s") + ) + explanation.extend( + pprint.pformat({k: left[k] for k in extra_left}).splitlines() + ) + extra_right = set_right - set_left + len_extra_right = len(extra_right) + if len_extra_right: + explanation.append( + "Right contains %d more item%s:" + % (len_extra_right, "" if len_extra_right == 1 else "s") + ) + explanation.extend( + pprint.pformat({k: right[k] for k in extra_right}).splitlines() + ) + return explanation + + +def _compare_eq_cls(left: Any, right: Any, verbose: int) -> List[str]: + if not has_default_eq(left): + return [] + if isdatacls(left): + import dataclasses + + all_fields = dataclasses.fields(left) + fields_to_check = [info.name for info in all_fields if info.compare] + elif isattrs(left): + all_fields = left.__attrs_attrs__ + fields_to_check = [field.name for field in all_fields if getattr(field, "eq")] + elif isnamedtuple(left): + fields_to_check = left._fields + else: + assert False + + indent = " " + same = [] + diff = [] + for field in fields_to_check: + if getattr(left, field) == getattr(right, field): + same.append(field) + else: + diff.append(field) + + explanation = [] + if same or diff: + explanation += [""] + if same and verbose < 2: + explanation.append("Omitting %s identical items, use -vv to show" % len(same)) + elif same: + explanation += ["Matching attributes:"] + explanation += pprint.pformat(same).splitlines() + if diff: + explanation += ["Differing attributes:"] + explanation += pprint.pformat(diff).splitlines() + for field in diff: + field_left = getattr(left, field) + field_right = getattr(right, field) + explanation += [ + "", + "Drill down into differing attribute %s:" % field, + ("%s%s: %r != %r") % (indent, field, field_left, field_right), + ] + explanation += [ + indent + line + for line in _compare_eq_any(field_left, field_right, verbose) + ] + return explanation + + +def _notin_text(term: str, text: str, verbose: int = 0) -> List[str]: + index = text.find(term) + head = text[:index] + tail = text[index + len(term) :] + correct_text = head + tail + diff = _diff_text(text, correct_text, verbose) + newdiff = ["%s is contained here:" % saferepr(term, maxsize=42)] + for line in diff: + if line.startswith("Skipping"): + continue + if line.startswith("- "): + continue + if line.startswith("+ "): + newdiff.append(" " + line[2:]) + else: + newdiff.append(line) + return newdiff + + +def running_on_ci() -> bool: + """Check if we're currently running on a CI system.""" + env_vars = ["CI", "BUILD_NUMBER"] + return any(var in os.environ for var in env_vars) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/cacheprovider.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/cacheprovider.py new file mode 100644 index 00000000..1ecb8650 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/cacheprovider.py @@ -0,0 +1,602 @@ +"""Implementation of the cache provider.""" +# This plugin was not named "cache" to avoid conflicts with the external +# pytest-cache version. +import dataclasses +import json +import os +from pathlib import Path +from typing import Dict +from typing import Generator +from typing import Iterable +from typing import List +from typing import Optional +from typing import Set +from typing import Union + +from .pathlib import resolve_from_str +from .pathlib import rm_rf +from .reports import CollectReport +from _pytest import nodes +from _pytest._io import TerminalWriter +from _pytest.compat import final +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.main import Session +from _pytest.nodes import File +from _pytest.python import Package +from _pytest.reports import TestReport + +README_CONTENT = """\ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. +""" + +CACHEDIR_TAG_CONTENT = b"""\ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html +""" + + +@final +@dataclasses.dataclass +class Cache: + """Instance of the `cache` fixture.""" + + _cachedir: Path = dataclasses.field(repr=False) + _config: Config = dataclasses.field(repr=False) + + # Sub-directory under cache-dir for directories created by `mkdir()`. + _CACHE_PREFIX_DIRS = "d" + + # Sub-directory under cache-dir for values created by `set()`. + _CACHE_PREFIX_VALUES = "v" + + def __init__( + self, cachedir: Path, config: Config, *, _ispytest: bool = False + ) -> None: + check_ispytest(_ispytest) + self._cachedir = cachedir + self._config = config + + @classmethod + def for_config(cls, config: Config, *, _ispytest: bool = False) -> "Cache": + """Create the Cache instance for a Config. + + :meta private: + """ + check_ispytest(_ispytest) + cachedir = cls.cache_dir_from_config(config, _ispytest=True) + if config.getoption("cacheclear") and cachedir.is_dir(): + cls.clear_cache(cachedir, _ispytest=True) + return cls(cachedir, config, _ispytest=True) + + @classmethod + def clear_cache(cls, cachedir: Path, _ispytest: bool = False) -> None: + """Clear the sub-directories used to hold cached directories and values. + + :meta private: + """ + check_ispytest(_ispytest) + for prefix in (cls._CACHE_PREFIX_DIRS, cls._CACHE_PREFIX_VALUES): + d = cachedir / prefix + if d.is_dir(): + rm_rf(d) + + @staticmethod + def cache_dir_from_config(config: Config, *, _ispytest: bool = False) -> Path: + """Get the path to the cache directory for a Config. + + :meta private: + """ + check_ispytest(_ispytest) + return resolve_from_str(config.getini("cache_dir"), config.rootpath) + + def warn(self, fmt: str, *, _ispytest: bool = False, **args: object) -> None: + """Issue a cache warning. + + :meta private: + """ + check_ispytest(_ispytest) + import warnings + from _pytest.warning_types import PytestCacheWarning + + warnings.warn( + PytestCacheWarning(fmt.format(**args) if args else fmt), + self._config.hook, + stacklevel=3, + ) + + def mkdir(self, name: str) -> Path: + """Return a directory path object with the given name. + + If the directory does not yet exist, it will be created. You can use + it to manage files to e.g. store/retrieve database dumps across test + sessions. + + .. versionadded:: 7.0 + + :param name: + Must be a string not containing a ``/`` separator. + Make sure the name contains your plugin or application + identifiers to prevent clashes with other cache users. + """ + path = Path(name) + if len(path.parts) > 1: + raise ValueError("name is not allowed to contain path separators") + res = self._cachedir.joinpath(self._CACHE_PREFIX_DIRS, path) + res.mkdir(exist_ok=True, parents=True) + return res + + def _getvaluepath(self, key: str) -> Path: + return self._cachedir.joinpath(self._CACHE_PREFIX_VALUES, Path(key)) + + def get(self, key: str, default): + """Return the cached value for the given key. + + If no value was yet cached or the value cannot be read, the specified + default is returned. + + :param key: + Must be a ``/`` separated value. Usually the first + name is the name of your plugin or your application. + :param default: + The value to return in case of a cache-miss or invalid cache value. + """ + path = self._getvaluepath(key) + try: + with path.open("r", encoding="UTF-8") as f: + return json.load(f) + except (ValueError, OSError): + return default + + def set(self, key: str, value: object) -> None: + """Save value for the given key. + + :param key: + Must be a ``/`` separated value. Usually the first + name is the name of your plugin or your application. + :param value: + Must be of any combination of basic python types, + including nested types like lists of dictionaries. + """ + path = self._getvaluepath(key) + try: + if path.parent.is_dir(): + cache_dir_exists_already = True + else: + cache_dir_exists_already = self._cachedir.exists() + path.parent.mkdir(exist_ok=True, parents=True) + except OSError as exc: + self.warn( + f"could not create cache path {path}: {exc}", + _ispytest=True, + ) + return + if not cache_dir_exists_already: + self._ensure_supporting_files() + data = json.dumps(value, ensure_ascii=False, indent=2) + try: + f = path.open("w", encoding="UTF-8") + except OSError as exc: + self.warn( + f"cache could not write path {path}: {exc}", + _ispytest=True, + ) + else: + with f: + f.write(data) + + def _ensure_supporting_files(self) -> None: + """Create supporting files in the cache dir that are not really part of the cache.""" + readme_path = self._cachedir / "README.md" + readme_path.write_text(README_CONTENT, encoding="UTF-8") + + gitignore_path = self._cachedir.joinpath(".gitignore") + msg = "# Created by pytest automatically.\n*\n" + gitignore_path.write_text(msg, encoding="UTF-8") + + cachedir_tag_path = self._cachedir.joinpath("CACHEDIR.TAG") + cachedir_tag_path.write_bytes(CACHEDIR_TAG_CONTENT) + + +class LFPluginCollWrapper: + def __init__(self, lfplugin: "LFPlugin") -> None: + self.lfplugin = lfplugin + self._collected_at_least_one_failure = False + + @hookimpl(hookwrapper=True) + def pytest_make_collect_report(self, collector: nodes.Collector): + if isinstance(collector, (Session, Package)): + out = yield + res: CollectReport = out.get_result() + + # Sort any lf-paths to the beginning. + lf_paths = self.lfplugin._last_failed_paths + + # Use stable sort to priorize last failed. + def sort_key(node: Union[nodes.Item, nodes.Collector]) -> bool: + # Package.path is the __init__.py file, we need the directory. + if isinstance(node, Package): + path = node.path.parent + else: + path = node.path + return path in lf_paths + + res.result = sorted( + res.result, + key=sort_key, + reverse=True, + ) + return + + elif isinstance(collector, File): + if collector.path in self.lfplugin._last_failed_paths: + out = yield + res = out.get_result() + result = res.result + lastfailed = self.lfplugin.lastfailed + + # Only filter with known failures. + if not self._collected_at_least_one_failure: + if not any(x.nodeid in lastfailed for x in result): + return + self.lfplugin.config.pluginmanager.register( + LFPluginCollSkipfiles(self.lfplugin), "lfplugin-collskip" + ) + self._collected_at_least_one_failure = True + + session = collector.session + result[:] = [ + x + for x in result + if x.nodeid in lastfailed + # Include any passed arguments (not trivial to filter). + or session.isinitpath(x.path) + # Keep all sub-collectors. + or isinstance(x, nodes.Collector) + ] + return + yield + + +class LFPluginCollSkipfiles: + def __init__(self, lfplugin: "LFPlugin") -> None: + self.lfplugin = lfplugin + + @hookimpl + def pytest_make_collect_report( + self, collector: nodes.Collector + ) -> Optional[CollectReport]: + # Packages are Files, but we only want to skip test-bearing Files, + # so don't filter Packages. + if isinstance(collector, File) and not isinstance(collector, Package): + if collector.path not in self.lfplugin._last_failed_paths: + self.lfplugin._skipped_files += 1 + + return CollectReport( + collector.nodeid, "passed", longrepr=None, result=[] + ) + return None + + +class LFPlugin: + """Plugin which implements the --lf (run last-failing) option.""" + + def __init__(self, config: Config) -> None: + self.config = config + active_keys = "lf", "failedfirst" + self.active = any(config.getoption(key) for key in active_keys) + assert config.cache + self.lastfailed: Dict[str, bool] = config.cache.get("cache/lastfailed", {}) + self._previously_failed_count: Optional[int] = None + self._report_status: Optional[str] = None + self._skipped_files = 0 # count skipped files during collection due to --lf + + if config.getoption("lf"): + self._last_failed_paths = self.get_last_failed_paths() + config.pluginmanager.register( + LFPluginCollWrapper(self), "lfplugin-collwrapper" + ) + + def get_last_failed_paths(self) -> Set[Path]: + """Return a set with all Paths of the previously failed nodeids and + their parents.""" + rootpath = self.config.rootpath + result = set() + for nodeid in self.lastfailed: + path = rootpath / nodeid.split("::")[0] + result.add(path) + result.update(path.parents) + return {x for x in result if x.exists()} + + def pytest_report_collectionfinish(self) -> Optional[str]: + if self.active and self.config.getoption("verbose") >= 0: + return "run-last-failure: %s" % self._report_status + return None + + def pytest_runtest_logreport(self, report: TestReport) -> None: + if (report.when == "call" and report.passed) or report.skipped: + self.lastfailed.pop(report.nodeid, None) + elif report.failed: + self.lastfailed[report.nodeid] = True + + def pytest_collectreport(self, report: CollectReport) -> None: + passed = report.outcome in ("passed", "skipped") + if passed: + if report.nodeid in self.lastfailed: + self.lastfailed.pop(report.nodeid) + self.lastfailed.update((item.nodeid, True) for item in report.result) + else: + self.lastfailed[report.nodeid] = True + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_collection_modifyitems( + self, config: Config, items: List[nodes.Item] + ) -> Generator[None, None, None]: + yield + + if not self.active: + return + + if self.lastfailed: + previously_failed = [] + previously_passed = [] + for item in items: + if item.nodeid in self.lastfailed: + previously_failed.append(item) + else: + previously_passed.append(item) + self._previously_failed_count = len(previously_failed) + + if not previously_failed: + # Running a subset of all tests with recorded failures + # only outside of it. + self._report_status = "%d known failures not in selected tests" % ( + len(self.lastfailed), + ) + else: + if self.config.getoption("lf"): + items[:] = previously_failed + config.hook.pytest_deselected(items=previously_passed) + else: # --failedfirst + items[:] = previously_failed + previously_passed + + noun = "failure" if self._previously_failed_count == 1 else "failures" + suffix = " first" if self.config.getoption("failedfirst") else "" + self._report_status = "rerun previous {count} {noun}{suffix}".format( + count=self._previously_failed_count, suffix=suffix, noun=noun + ) + + if self._skipped_files > 0: + files_noun = "file" if self._skipped_files == 1 else "files" + self._report_status += " (skipped {files} {files_noun})".format( + files=self._skipped_files, files_noun=files_noun + ) + else: + self._report_status = "no previously failed tests, " + if self.config.getoption("last_failed_no_failures") == "none": + self._report_status += "deselecting all items." + config.hook.pytest_deselected(items=items[:]) + items[:] = [] + else: + self._report_status += "not deselecting items." + + def pytest_sessionfinish(self, session: Session) -> None: + config = self.config + if config.getoption("cacheshow") or hasattr(config, "workerinput"): + return + + assert config.cache is not None + saved_lastfailed = config.cache.get("cache/lastfailed", {}) + if saved_lastfailed != self.lastfailed: + config.cache.set("cache/lastfailed", self.lastfailed) + + +class NFPlugin: + """Plugin which implements the --nf (run new-first) option.""" + + def __init__(self, config: Config) -> None: + self.config = config + self.active = config.option.newfirst + assert config.cache is not None + self.cached_nodeids = set(config.cache.get("cache/nodeids", [])) + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_collection_modifyitems( + self, items: List[nodes.Item] + ) -> Generator[None, None, None]: + yield + + if self.active: + new_items: Dict[str, nodes.Item] = {} + other_items: Dict[str, nodes.Item] = {} + for item in items: + if item.nodeid not in self.cached_nodeids: + new_items[item.nodeid] = item + else: + other_items[item.nodeid] = item + + items[:] = self._get_increasing_order( + new_items.values() + ) + self._get_increasing_order(other_items.values()) + self.cached_nodeids.update(new_items) + else: + self.cached_nodeids.update(item.nodeid for item in items) + + def _get_increasing_order(self, items: Iterable[nodes.Item]) -> List[nodes.Item]: + return sorted(items, key=lambda item: item.path.stat().st_mtime, reverse=True) # type: ignore[no-any-return] + + def pytest_sessionfinish(self) -> None: + config = self.config + if config.getoption("cacheshow") or hasattr(config, "workerinput"): + return + + if config.getoption("collectonly"): + return + + assert config.cache is not None + config.cache.set("cache/nodeids", sorted(self.cached_nodeids)) + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group.addoption( + "--lf", + "--last-failed", + action="store_true", + dest="lf", + help="Rerun only the tests that failed " + "at the last run (or all if none failed)", + ) + group.addoption( + "--ff", + "--failed-first", + action="store_true", + dest="failedfirst", + help="Run all tests, but run the last failures first. " + "This may re-order tests and thus lead to " + "repeated fixture setup/teardown.", + ) + group.addoption( + "--nf", + "--new-first", + action="store_true", + dest="newfirst", + help="Run tests from new files first, then the rest of the tests " + "sorted by file mtime", + ) + group.addoption( + "--cache-show", + action="append", + nargs="?", + dest="cacheshow", + help=( + "Show cache contents, don't perform collection or tests. " + "Optional argument: glob (default: '*')." + ), + ) + group.addoption( + "--cache-clear", + action="store_true", + dest="cacheclear", + help="Remove all cache contents at start of test run", + ) + cache_dir_default = ".pytest_cache" + if "TOX_ENV_DIR" in os.environ: + cache_dir_default = os.path.join(os.environ["TOX_ENV_DIR"], cache_dir_default) + parser.addini("cache_dir", default=cache_dir_default, help="Cache directory path") + group.addoption( + "--lfnf", + "--last-failed-no-failures", + action="store", + dest="last_failed_no_failures", + choices=("all", "none"), + default="all", + help="With ``--lf``, determines whether to execute tests when there " + "are no previously (known) failures or when no " + "cached ``lastfailed`` data was found. " + "``all`` (the default) runs the full test suite again. " + "``none`` just emits a message about no known failures and exits successfully.", + ) + + +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + if config.option.cacheshow and not config.option.help: + from _pytest.main import wrap_session + + return wrap_session(config, cacheshow) + return None + + +@hookimpl(tryfirst=True) +def pytest_configure(config: Config) -> None: + config.cache = Cache.for_config(config, _ispytest=True) + config.pluginmanager.register(LFPlugin(config), "lfplugin") + config.pluginmanager.register(NFPlugin(config), "nfplugin") + + +@fixture +def cache(request: FixtureRequest) -> Cache: + """Return a cache object that can persist state between testing sessions. + + cache.get(key, default) + cache.set(key, value) + + Keys must be ``/`` separated strings, where the first part is usually the + name of your plugin or application to avoid clashes with other cache users. + + Values can be any object handled by the json stdlib module. + """ + assert request.config.cache is not None + return request.config.cache + + +def pytest_report_header(config: Config) -> Optional[str]: + """Display cachedir with --cache-show and if non-default.""" + if config.option.verbose > 0 or config.getini("cache_dir") != ".pytest_cache": + assert config.cache is not None + cachedir = config.cache._cachedir + # TODO: evaluate generating upward relative paths + # starting with .., ../.. if sensible + + try: + displaypath = cachedir.relative_to(config.rootpath) + except ValueError: + displaypath = cachedir + return f"cachedir: {displaypath}" + return None + + +def cacheshow(config: Config, session: Session) -> int: + from pprint import pformat + + assert config.cache is not None + + tw = TerminalWriter() + tw.line("cachedir: " + str(config.cache._cachedir)) + if not config.cache._cachedir.is_dir(): + tw.line("cache is empty") + return 0 + + glob = config.option.cacheshow[0] + if glob is None: + glob = "*" + + dummy = object() + basedir = config.cache._cachedir + vdir = basedir / Cache._CACHE_PREFIX_VALUES + tw.sep("-", "cache values for %r" % glob) + for valpath in sorted(x for x in vdir.rglob(glob) if x.is_file()): + key = str(valpath.relative_to(vdir)) + val = config.cache.get(key, dummy) + if val is dummy: + tw.line("%s contains unreadable content, will be ignored" % key) + else: + tw.line("%s contains:" % key) + for line in pformat(val).splitlines(): + tw.line(" " + line) + + ddir = basedir / Cache._CACHE_PREFIX_DIRS + if ddir.is_dir(): + contents = sorted(ddir.rglob(glob)) + tw.sep("-", "cache directories for %r" % glob) + for p in contents: + # if p.is_dir(): + # print("%s/" % p.relative_to(basedir)) + if p.is_file(): + key = str(p.relative_to(basedir)) + tw.line(f"{key} is a file of length {p.stat().st_size:d}") + return 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/capture.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/capture.py new file mode 100644 index 00000000..a8ca0869 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/capture.py @@ -0,0 +1,1082 @@ +"""Per-test stdout/stderr capturing mechanism.""" +import abc +import collections +import contextlib +import io +import os +import sys +from io import UnsupportedOperation +from tempfile import TemporaryFile +from types import TracebackType +from typing import Any +from typing import AnyStr +from typing import BinaryIO +from typing import Generator +from typing import Generic +from typing import Iterable +from typing import Iterator +from typing import List +from typing import NamedTuple +from typing import Optional +from typing import TextIO +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +from _pytest.compat import final +from _pytest.config import Config +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import SubRequest +from _pytest.nodes import Collector +from _pytest.nodes import File +from _pytest.nodes import Item + +if TYPE_CHECKING: + from typing_extensions import Final + from typing_extensions import Literal + + _CaptureMethod = Literal["fd", "sys", "no", "tee-sys"] + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group._addoption( + "--capture", + action="store", + default="fd", + metavar="method", + choices=["fd", "sys", "no", "tee-sys"], + help="Per-test capturing method: one of fd|sys|no|tee-sys", + ) + group._addoption( + "-s", + action="store_const", + const="no", + dest="capture", + help="Shortcut for --capture=no", + ) + + +def _colorama_workaround() -> None: + """Ensure colorama is imported so that it attaches to the correct stdio + handles on Windows. + + colorama uses the terminal on import time. So if something does the + first import of colorama while I/O capture is active, colorama will + fail in various ways. + """ + if sys.platform.startswith("win32"): + try: + import colorama # noqa: F401 + except ImportError: + pass + + +def _windowsconsoleio_workaround(stream: TextIO) -> None: + """Workaround for Windows Unicode console handling. + + Python 3.6 implemented Unicode console handling for Windows. This works + by reading/writing to the raw console handle using + ``{Read,Write}ConsoleW``. + + The problem is that we are going to ``dup2`` over the stdio file + descriptors when doing ``FDCapture`` and this will ``CloseHandle`` the + handles used by Python to write to the console. Though there is still some + weirdness and the console handle seems to only be closed randomly and not + on the first call to ``CloseHandle``, or maybe it gets reopened with the + same handle value when we suspend capturing. + + The workaround in this case will reopen stdio with a different fd which + also means a different handle by replicating the logic in + "Py_lifecycle.c:initstdio/create_stdio". + + :param stream: + In practice ``sys.stdout`` or ``sys.stderr``, but given + here as parameter for unittesting purposes. + + See https://github.com/pytest-dev/py/issues/103. + """ + if not sys.platform.startswith("win32") or hasattr(sys, "pypy_version_info"): + return + + # Bail out if ``stream`` doesn't seem like a proper ``io`` stream (#2666). + if not hasattr(stream, "buffer"): # type: ignore[unreachable] + return + + buffered = hasattr(stream.buffer, "raw") + raw_stdout = stream.buffer.raw if buffered else stream.buffer # type: ignore[attr-defined] + + if not isinstance(raw_stdout, io._WindowsConsoleIO): # type: ignore[attr-defined] + return + + def _reopen_stdio(f, mode): + if not buffered and mode[0] == "w": + buffering = 0 + else: + buffering = -1 + + return io.TextIOWrapper( + open(os.dup(f.fileno()), mode, buffering), + f.encoding, + f.errors, + f.newlines, + f.line_buffering, + ) + + sys.stdin = _reopen_stdio(sys.stdin, "rb") + sys.stdout = _reopen_stdio(sys.stdout, "wb") + sys.stderr = _reopen_stdio(sys.stderr, "wb") + + +@hookimpl(hookwrapper=True) +def pytest_load_initial_conftests(early_config: Config): + ns = early_config.known_args_namespace + if ns.capture == "fd": + _windowsconsoleio_workaround(sys.stdout) + _colorama_workaround() + pluginmanager = early_config.pluginmanager + capman = CaptureManager(ns.capture) + pluginmanager.register(capman, "capturemanager") + + # Make sure that capturemanager is properly reset at final shutdown. + early_config.add_cleanup(capman.stop_global_capturing) + + # Finally trigger conftest loading but while capturing (issue #93). + capman.start_global_capturing() + outcome = yield + capman.suspend_global_capture() + if outcome.excinfo is not None: + out, err = capman.read_global_capture() + sys.stdout.write(out) + sys.stderr.write(err) + + +# IO Helpers. + + +class EncodedFile(io.TextIOWrapper): + __slots__ = () + + @property + def name(self) -> str: + # Ensure that file.name is a string. Workaround for a Python bug + # fixed in >=3.7.4: https://bugs.python.org/issue36015 + return repr(self.buffer) + + @property + def mode(self) -> str: + # TextIOWrapper doesn't expose a mode, but at least some of our + # tests check it. + return self.buffer.mode.replace("b", "") + + +class CaptureIO(io.TextIOWrapper): + def __init__(self) -> None: + super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) + + def getvalue(self) -> str: + assert isinstance(self.buffer, io.BytesIO) + return self.buffer.getvalue().decode("UTF-8") + + +class TeeCaptureIO(CaptureIO): + def __init__(self, other: TextIO) -> None: + self._other = other + super().__init__() + + def write(self, s: str) -> int: + super().write(s) + return self._other.write(s) + + +class DontReadFromInput(TextIO): + @property + def encoding(self) -> str: + return sys.__stdin__.encoding + + def read(self, size: int = -1) -> str: + raise OSError( + "pytest: reading from stdin while output is captured! Consider using `-s`." + ) + + readline = read + + def __next__(self) -> str: + return self.readline() + + def readlines(self, hint: Optional[int] = -1) -> List[str]: + raise OSError( + "pytest: reading from stdin while output is captured! Consider using `-s`." + ) + + def __iter__(self) -> Iterator[str]: + return self + + def fileno(self) -> int: + raise UnsupportedOperation("redirected stdin is pseudofile, has no fileno()") + + def flush(self) -> None: + raise UnsupportedOperation("redirected stdin is pseudofile, has no flush()") + + def isatty(self) -> bool: + return False + + def close(self) -> None: + pass + + def readable(self) -> bool: + return False + + def seek(self, offset: int, whence: int = 0) -> int: + raise UnsupportedOperation("redirected stdin is pseudofile, has no seek(int)") + + def seekable(self) -> bool: + return False + + def tell(self) -> int: + raise UnsupportedOperation("redirected stdin is pseudofile, has no tell()") + + def truncate(self, size: Optional[int] = None) -> int: + raise UnsupportedOperation("cannot truncate stdin") + + def write(self, data: str) -> int: + raise UnsupportedOperation("cannot write to stdin") + + def writelines(self, lines: Iterable[str]) -> None: + raise UnsupportedOperation("Cannot write to stdin") + + def writable(self) -> bool: + return False + + def __enter__(self) -> "DontReadFromInput": + return self + + def __exit__( + self, + type: Optional[Type[BaseException]], + value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + pass + + @property + def buffer(self) -> BinaryIO: + # The str/bytes doesn't actually matter in this type, so OK to fake. + return self # type: ignore[return-value] + + +# Capture classes. + + +class CaptureBase(abc.ABC, Generic[AnyStr]): + EMPTY_BUFFER: AnyStr + + @abc.abstractmethod + def __init__(self, fd: int) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def start(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def done(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def suspend(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def resume(self) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def writeorg(self, data: AnyStr) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def snap(self) -> AnyStr: + raise NotImplementedError() + + +patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"} + + +class NoCapture(CaptureBase[str]): + EMPTY_BUFFER = "" + + def __init__(self, fd: int) -> None: + pass + + def start(self) -> None: + pass + + def done(self) -> None: + pass + + def suspend(self) -> None: + pass + + def resume(self) -> None: + pass + + def snap(self) -> str: + return "" + + def writeorg(self, data: str) -> None: + pass + + +class SysCaptureBase(CaptureBase[AnyStr]): + def __init__( + self, fd: int, tmpfile: Optional[TextIO] = None, *, tee: bool = False + ) -> None: + name = patchsysdict[fd] + self._old: TextIO = getattr(sys, name) + self.name = name + if tmpfile is None: + if name == "stdin": + tmpfile = DontReadFromInput() + else: + tmpfile = CaptureIO() if not tee else TeeCaptureIO(self._old) + self.tmpfile = tmpfile + self._state = "initialized" + + def repr(self, class_name: str) -> str: + return "<{} {} _old={} _state={!r} tmpfile={!r}>".format( + class_name, + self.name, + hasattr(self, "_old") and repr(self._old) or "", + self._state, + self.tmpfile, + ) + + def __repr__(self) -> str: + return "<{} {} _old={} _state={!r} tmpfile={!r}>".format( + self.__class__.__name__, + self.name, + hasattr(self, "_old") and repr(self._old) or "", + self._state, + self.tmpfile, + ) + + def _assert_state(self, op: str, states: Tuple[str, ...]) -> None: + assert ( + self._state in states + ), "cannot {} in state {!r}: expected one of {}".format( + op, self._state, ", ".join(states) + ) + + def start(self) -> None: + self._assert_state("start", ("initialized",)) + setattr(sys, self.name, self.tmpfile) + self._state = "started" + + def done(self) -> None: + self._assert_state("done", ("initialized", "started", "suspended", "done")) + if self._state == "done": + return + setattr(sys, self.name, self._old) + del self._old + self.tmpfile.close() + self._state = "done" + + def suspend(self) -> None: + self._assert_state("suspend", ("started", "suspended")) + setattr(sys, self.name, self._old) + self._state = "suspended" + + def resume(self) -> None: + self._assert_state("resume", ("started", "suspended")) + if self._state == "started": + return + setattr(sys, self.name, self.tmpfile) + self._state = "started" + + +class SysCaptureBinary(SysCaptureBase[bytes]): + EMPTY_BUFFER = b"" + + def snap(self) -> bytes: + self._assert_state("snap", ("started", "suspended")) + self.tmpfile.seek(0) + res = self.tmpfile.buffer.read() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def writeorg(self, data: bytes) -> None: + self._assert_state("writeorg", ("started", "suspended")) + self._old.flush() + self._old.buffer.write(data) + self._old.buffer.flush() + + +class SysCapture(SysCaptureBase[str]): + EMPTY_BUFFER = "" + + def snap(self) -> str: + self._assert_state("snap", ("started", "suspended")) + assert isinstance(self.tmpfile, CaptureIO) + res = self.tmpfile.getvalue() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def writeorg(self, data: str) -> None: + self._assert_state("writeorg", ("started", "suspended")) + self._old.write(data) + self._old.flush() + + +class FDCaptureBase(CaptureBase[AnyStr]): + def __init__(self, targetfd: int) -> None: + self.targetfd = targetfd + + try: + os.fstat(targetfd) + except OSError: + # FD capturing is conceptually simple -- create a temporary file, + # redirect the FD to it, redirect back when done. But when the + # target FD is invalid it throws a wrench into this lovely scheme. + # + # Tests themselves shouldn't care if the FD is valid, FD capturing + # should work regardless of external circumstances. So falling back + # to just sys capturing is not a good option. + # + # Further complications are the need to support suspend() and the + # possibility of FD reuse (e.g. the tmpfile getting the very same + # target FD). The following approach is robust, I believe. + self.targetfd_invalid: Optional[int] = os.open(os.devnull, os.O_RDWR) + os.dup2(self.targetfd_invalid, targetfd) + else: + self.targetfd_invalid = None + self.targetfd_save = os.dup(targetfd) + + if targetfd == 0: + self.tmpfile = open(os.devnull, encoding="utf-8") + self.syscapture: CaptureBase[str] = SysCapture(targetfd) + else: + self.tmpfile = EncodedFile( + TemporaryFile(buffering=0), + encoding="utf-8", + errors="replace", + newline="", + write_through=True, + ) + if targetfd in patchsysdict: + self.syscapture = SysCapture(targetfd, self.tmpfile) + else: + self.syscapture = NoCapture(targetfd) + + self._state = "initialized" + + def __repr__(self) -> str: + return "<{} {} oldfd={} _state={!r} tmpfile={!r}>".format( + self.__class__.__name__, + self.targetfd, + self.targetfd_save, + self._state, + self.tmpfile, + ) + + def _assert_state(self, op: str, states: Tuple[str, ...]) -> None: + assert ( + self._state in states + ), "cannot {} in state {!r}: expected one of {}".format( + op, self._state, ", ".join(states) + ) + + def start(self) -> None: + """Start capturing on targetfd using memorized tmpfile.""" + self._assert_state("start", ("initialized",)) + os.dup2(self.tmpfile.fileno(), self.targetfd) + self.syscapture.start() + self._state = "started" + + def done(self) -> None: + """Stop capturing, restore streams, return original capture file, + seeked to position zero.""" + self._assert_state("done", ("initialized", "started", "suspended", "done")) + if self._state == "done": + return + os.dup2(self.targetfd_save, self.targetfd) + os.close(self.targetfd_save) + if self.targetfd_invalid is not None: + if self.targetfd_invalid != self.targetfd: + os.close(self.targetfd) + os.close(self.targetfd_invalid) + self.syscapture.done() + self.tmpfile.close() + self._state = "done" + + def suspend(self) -> None: + self._assert_state("suspend", ("started", "suspended")) + if self._state == "suspended": + return + self.syscapture.suspend() + os.dup2(self.targetfd_save, self.targetfd) + self._state = "suspended" + + def resume(self) -> None: + self._assert_state("resume", ("started", "suspended")) + if self._state == "started": + return + self.syscapture.resume() + os.dup2(self.tmpfile.fileno(), self.targetfd) + self._state = "started" + + +class FDCaptureBinary(FDCaptureBase[bytes]): + """Capture IO to/from a given OS-level file descriptor. + + snap() produces `bytes`. + """ + + EMPTY_BUFFER = b"" + + def snap(self) -> bytes: + self._assert_state("snap", ("started", "suspended")) + self.tmpfile.seek(0) + res = self.tmpfile.buffer.read() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def writeorg(self, data: bytes) -> None: + """Write to original file descriptor.""" + self._assert_state("writeorg", ("started", "suspended")) + os.write(self.targetfd_save, data) + + +class FDCapture(FDCaptureBase[str]): + """Capture IO to/from a given OS-level file descriptor. + + snap() produces text. + """ + + EMPTY_BUFFER = "" + + def snap(self) -> str: + self._assert_state("snap", ("started", "suspended")) + self.tmpfile.seek(0) + res = self.tmpfile.read() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def writeorg(self, data: str) -> None: + """Write to original file descriptor.""" + self._assert_state("writeorg", ("started", "suspended")) + # XXX use encoding of original stream + os.write(self.targetfd_save, data.encode("utf-8")) + + +# MultiCapture + + +# Generic NamedTuple only supported since Python 3.11. +if sys.version_info >= (3, 11) or TYPE_CHECKING: + + @final + class CaptureResult(NamedTuple, Generic[AnyStr]): + """The result of :method:`CaptureFixture.readouterr`.""" + + out: AnyStr + err: AnyStr + +else: + + class CaptureResult( + collections.namedtuple("CaptureResult", ["out", "err"]), Generic[AnyStr] + ): + """The result of :method:`CaptureFixture.readouterr`.""" + + __slots__ = () + + +class MultiCapture(Generic[AnyStr]): + _state = None + _in_suspended = False + + def __init__( + self, + in_: Optional[CaptureBase[AnyStr]], + out: Optional[CaptureBase[AnyStr]], + err: Optional[CaptureBase[AnyStr]], + ) -> None: + self.in_: Optional[CaptureBase[AnyStr]] = in_ + self.out: Optional[CaptureBase[AnyStr]] = out + self.err: Optional[CaptureBase[AnyStr]] = err + + def __repr__(self) -> str: + return "".format( + self.out, + self.err, + self.in_, + self._state, + self._in_suspended, + ) + + def start_capturing(self) -> None: + self._state = "started" + if self.in_: + self.in_.start() + if self.out: + self.out.start() + if self.err: + self.err.start() + + def pop_outerr_to_orig(self) -> Tuple[AnyStr, AnyStr]: + """Pop current snapshot out/err capture and flush to orig streams.""" + out, err = self.readouterr() + if out: + assert self.out is not None + self.out.writeorg(out) + if err: + assert self.err is not None + self.err.writeorg(err) + return out, err + + def suspend_capturing(self, in_: bool = False) -> None: + self._state = "suspended" + if self.out: + self.out.suspend() + if self.err: + self.err.suspend() + if in_ and self.in_: + self.in_.suspend() + self._in_suspended = True + + def resume_capturing(self) -> None: + self._state = "started" + if self.out: + self.out.resume() + if self.err: + self.err.resume() + if self._in_suspended: + assert self.in_ is not None + self.in_.resume() + self._in_suspended = False + + def stop_capturing(self) -> None: + """Stop capturing and reset capturing streams.""" + if self._state == "stopped": + raise ValueError("was already stopped") + self._state = "stopped" + if self.out: + self.out.done() + if self.err: + self.err.done() + if self.in_: + self.in_.done() + + def is_started(self) -> bool: + """Whether actively capturing -- not suspended or stopped.""" + return self._state == "started" + + def readouterr(self) -> CaptureResult[AnyStr]: + out = self.out.snap() if self.out else "" + err = self.err.snap() if self.err else "" + # TODO: This type error is real, need to fix. + return CaptureResult(out, err) # type: ignore[arg-type] + + +def _get_multicapture(method: "_CaptureMethod") -> MultiCapture[str]: + if method == "fd": + return MultiCapture(in_=FDCapture(0), out=FDCapture(1), err=FDCapture(2)) + elif method == "sys": + return MultiCapture(in_=SysCapture(0), out=SysCapture(1), err=SysCapture(2)) + elif method == "no": + return MultiCapture(in_=None, out=None, err=None) + elif method == "tee-sys": + return MultiCapture( + in_=None, out=SysCapture(1, tee=True), err=SysCapture(2, tee=True) + ) + raise ValueError(f"unknown capturing method: {method!r}") + + +# CaptureManager and CaptureFixture + + +class CaptureManager: + """The capture plugin. + + Manages that the appropriate capture method is enabled/disabled during + collection and each test phase (setup, call, teardown). After each of + those points, the captured output is obtained and attached to the + collection/runtest report. + + There are two levels of capture: + + * global: enabled by default and can be suppressed by the ``-s`` + option. This is always enabled/disabled during collection and each test + phase. + + * fixture: when a test function or one of its fixture depend on the + ``capsys`` or ``capfd`` fixtures. In this case special handling is + needed to ensure the fixtures take precedence over the global capture. + """ + + def __init__(self, method: "_CaptureMethod") -> None: + self._method: Final = method + self._global_capturing: Optional[MultiCapture[str]] = None + self._capture_fixture: Optional[CaptureFixture[Any]] = None + + def __repr__(self) -> str: + return "".format( + self._method, self._global_capturing, self._capture_fixture + ) + + def is_capturing(self) -> Union[str, bool]: + if self.is_globally_capturing(): + return "global" + if self._capture_fixture: + return "fixture %s" % self._capture_fixture.request.fixturename + return False + + # Global capturing control + + def is_globally_capturing(self) -> bool: + return self._method != "no" + + def start_global_capturing(self) -> None: + assert self._global_capturing is None + self._global_capturing = _get_multicapture(self._method) + self._global_capturing.start_capturing() + + def stop_global_capturing(self) -> None: + if self._global_capturing is not None: + self._global_capturing.pop_outerr_to_orig() + self._global_capturing.stop_capturing() + self._global_capturing = None + + def resume_global_capture(self) -> None: + # During teardown of the python process, and on rare occasions, capture + # attributes can be `None` while trying to resume global capture. + if self._global_capturing is not None: + self._global_capturing.resume_capturing() + + def suspend_global_capture(self, in_: bool = False) -> None: + if self._global_capturing is not None: + self._global_capturing.suspend_capturing(in_=in_) + + def suspend(self, in_: bool = False) -> None: + # Need to undo local capsys-et-al if it exists before disabling global capture. + self.suspend_fixture() + self.suspend_global_capture(in_) + + def resume(self) -> None: + self.resume_global_capture() + self.resume_fixture() + + def read_global_capture(self) -> CaptureResult[str]: + assert self._global_capturing is not None + return self._global_capturing.readouterr() + + # Fixture Control + + def set_fixture(self, capture_fixture: "CaptureFixture[Any]") -> None: + if self._capture_fixture: + current_fixture = self._capture_fixture.request.fixturename + requested_fixture = capture_fixture.request.fixturename + capture_fixture.request.raiseerror( + "cannot use {} and {} at the same time".format( + requested_fixture, current_fixture + ) + ) + self._capture_fixture = capture_fixture + + def unset_fixture(self) -> None: + self._capture_fixture = None + + def activate_fixture(self) -> None: + """If the current item is using ``capsys`` or ``capfd``, activate + them so they take precedence over the global capture.""" + if self._capture_fixture: + self._capture_fixture._start() + + def deactivate_fixture(self) -> None: + """Deactivate the ``capsys`` or ``capfd`` fixture of this item, if any.""" + if self._capture_fixture: + self._capture_fixture.close() + + def suspend_fixture(self) -> None: + if self._capture_fixture: + self._capture_fixture._suspend() + + def resume_fixture(self) -> None: + if self._capture_fixture: + self._capture_fixture._resume() + + # Helper context managers + + @contextlib.contextmanager + def global_and_fixture_disabled(self) -> Generator[None, None, None]: + """Context manager to temporarily disable global and current fixture capturing.""" + do_fixture = self._capture_fixture and self._capture_fixture._is_started() + if do_fixture: + self.suspend_fixture() + do_global = self._global_capturing and self._global_capturing.is_started() + if do_global: + self.suspend_global_capture() + try: + yield + finally: + if do_global: + self.resume_global_capture() + if do_fixture: + self.resume_fixture() + + @contextlib.contextmanager + def item_capture(self, when: str, item: Item) -> Generator[None, None, None]: + self.resume_global_capture() + self.activate_fixture() + try: + yield + finally: + self.deactivate_fixture() + self.suspend_global_capture(in_=False) + + out, err = self.read_global_capture() + item.add_report_section(when, "stdout", out) + item.add_report_section(when, "stderr", err) + + # Hooks + + @hookimpl(hookwrapper=True) + def pytest_make_collect_report(self, collector: Collector): + if isinstance(collector, File): + self.resume_global_capture() + outcome = yield + self.suspend_global_capture() + out, err = self.read_global_capture() + rep = outcome.get_result() + if out: + rep.sections.append(("Captured stdout", out)) + if err: + rep.sections.append(("Captured stderr", err)) + else: + yield + + @hookimpl(hookwrapper=True) + def pytest_runtest_setup(self, item: Item) -> Generator[None, None, None]: + with self.item_capture("setup", item): + yield + + @hookimpl(hookwrapper=True) + def pytest_runtest_call(self, item: Item) -> Generator[None, None, None]: + with self.item_capture("call", item): + yield + + @hookimpl(hookwrapper=True) + def pytest_runtest_teardown(self, item: Item) -> Generator[None, None, None]: + with self.item_capture("teardown", item): + yield + + @hookimpl(tryfirst=True) + def pytest_keyboard_interrupt(self) -> None: + self.stop_global_capturing() + + @hookimpl(tryfirst=True) + def pytest_internalerror(self) -> None: + self.stop_global_capturing() + + +class CaptureFixture(Generic[AnyStr]): + """Object returned by the :fixture:`capsys`, :fixture:`capsysbinary`, + :fixture:`capfd` and :fixture:`capfdbinary` fixtures.""" + + def __init__( + self, + captureclass: Type[CaptureBase[AnyStr]], + request: SubRequest, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self.captureclass: Type[CaptureBase[AnyStr]] = captureclass + self.request = request + self._capture: Optional[MultiCapture[AnyStr]] = None + self._captured_out: AnyStr = self.captureclass.EMPTY_BUFFER + self._captured_err: AnyStr = self.captureclass.EMPTY_BUFFER + + def _start(self) -> None: + if self._capture is None: + self._capture = MultiCapture( + in_=None, + out=self.captureclass(1), + err=self.captureclass(2), + ) + self._capture.start_capturing() + + def close(self) -> None: + if self._capture is not None: + out, err = self._capture.pop_outerr_to_orig() + self._captured_out += out + self._captured_err += err + self._capture.stop_capturing() + self._capture = None + + def readouterr(self) -> CaptureResult[AnyStr]: + """Read and return the captured output so far, resetting the internal + buffer. + + :returns: + The captured content as a namedtuple with ``out`` and ``err`` + string attributes. + """ + captured_out, captured_err = self._captured_out, self._captured_err + if self._capture is not None: + out, err = self._capture.readouterr() + captured_out += out + captured_err += err + self._captured_out = self.captureclass.EMPTY_BUFFER + self._captured_err = self.captureclass.EMPTY_BUFFER + return CaptureResult(captured_out, captured_err) + + def _suspend(self) -> None: + """Suspend this fixture's own capturing temporarily.""" + if self._capture is not None: + self._capture.suspend_capturing() + + def _resume(self) -> None: + """Resume this fixture's own capturing temporarily.""" + if self._capture is not None: + self._capture.resume_capturing() + + def _is_started(self) -> bool: + """Whether actively capturing -- not disabled or closed.""" + if self._capture is not None: + return self._capture.is_started() + return False + + @contextlib.contextmanager + def disabled(self) -> Generator[None, None, None]: + """Temporarily disable capturing while inside the ``with`` block.""" + capmanager: CaptureManager = self.request.config.pluginmanager.getplugin( + "capturemanager" + ) + with capmanager.global_and_fixture_disabled(): + yield + + +# The fixtures. + + +@fixture +def capsys(request: SubRequest) -> Generator[CaptureFixture[str], None, None]: + r"""Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``. + + The captured output is made available via ``capsys.readouterr()`` method + calls, which return a ``(out, err)`` namedtuple. + ``out`` and ``err`` will be ``text`` objects. + + Returns an instance of :class:`CaptureFixture[str] `. + + Example: + + .. code-block:: python + + def test_output(capsys): + print("hello") + captured = capsys.readouterr() + assert captured.out == "hello\n" + """ + capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager") + capture_fixture = CaptureFixture(SysCapture, request, _ispytest=True) + capman.set_fixture(capture_fixture) + capture_fixture._start() + yield capture_fixture + capture_fixture.close() + capman.unset_fixture() + + +@fixture +def capsysbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, None]: + r"""Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``. + + The captured output is made available via ``capsysbinary.readouterr()`` + method calls, which return a ``(out, err)`` namedtuple. + ``out`` and ``err`` will be ``bytes`` objects. + + Returns an instance of :class:`CaptureFixture[bytes] `. + + Example: + + .. code-block:: python + + def test_output(capsysbinary): + print("hello") + captured = capsysbinary.readouterr() + assert captured.out == b"hello\n" + """ + capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager") + capture_fixture = CaptureFixture(SysCaptureBinary, request, _ispytest=True) + capman.set_fixture(capture_fixture) + capture_fixture._start() + yield capture_fixture + capture_fixture.close() + capman.unset_fixture() + + +@fixture +def capfd(request: SubRequest) -> Generator[CaptureFixture[str], None, None]: + r"""Enable text capturing of writes to file descriptors ``1`` and ``2``. + + The captured output is made available via ``capfd.readouterr()`` method + calls, which return a ``(out, err)`` namedtuple. + ``out`` and ``err`` will be ``text`` objects. + + Returns an instance of :class:`CaptureFixture[str] `. + + Example: + + .. code-block:: python + + def test_system_echo(capfd): + os.system('echo "hello"') + captured = capfd.readouterr() + assert captured.out == "hello\n" + """ + capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager") + capture_fixture = CaptureFixture(FDCapture, request, _ispytest=True) + capman.set_fixture(capture_fixture) + capture_fixture._start() + yield capture_fixture + capture_fixture.close() + capman.unset_fixture() + + +@fixture +def capfdbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, None]: + r"""Enable bytes capturing of writes to file descriptors ``1`` and ``2``. + + The captured output is made available via ``capfd.readouterr()`` method + calls, which return a ``(out, err)`` namedtuple. + ``out`` and ``err`` will be ``byte`` objects. + + Returns an instance of :class:`CaptureFixture[bytes] `. + + Example: + + .. code-block:: python + + def test_system_echo(capfdbinary): + os.system('echo "hello"') + captured = capfdbinary.readouterr() + assert captured.out == b"hello\n" + + """ + capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager") + capture_fixture = CaptureFixture(FDCaptureBinary, request, _ispytest=True) + capman.set_fixture(capture_fixture) + capture_fixture._start() + yield capture_fixture + capture_fixture.close() + capman.unset_fixture() diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/compat.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/compat.py new file mode 100644 index 00000000..1d0add73 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/compat.py @@ -0,0 +1,435 @@ +"""Python version compatibility code.""" +from __future__ import annotations + +import dataclasses +import enum +import functools +import inspect +import os +import sys +from inspect import Parameter +from inspect import signature +from pathlib import Path +from typing import Any +from typing import Callable +from typing import Generic +from typing import NoReturn +from typing import TYPE_CHECKING +from typing import TypeVar + +import py + +# fmt: off +# Workaround for https://github.com/sphinx-doc/sphinx/issues/10351. +# If `overload` is imported from `compat` instead of from `typing`, +# Sphinx doesn't recognize it as `overload` and the API docs for +# overloaded functions look good again. But type checkers handle +# it fine. +# fmt: on +if True: + from typing import overload as overload + +if TYPE_CHECKING: + from typing_extensions import Final + + +_T = TypeVar("_T") +_S = TypeVar("_S") + +#: constant to prepare valuing pylib path replacements/lazy proxies later on +# intended for removal in pytest 8.0 or 9.0 + +# fmt: off +# intentional space to create a fake difference for the verification +LEGACY_PATH = py.path. local +# fmt: on + + +def legacy_path(path: str | os.PathLike[str]) -> LEGACY_PATH: + """Internal wrapper to prepare lazy proxies for legacy_path instances""" + return LEGACY_PATH(path) + + +# fmt: off +# Singleton type for NOTSET, as described in: +# https://www.python.org/dev/peps/pep-0484/#support-for-singleton-types-in-unions +class NotSetType(enum.Enum): + token = 0 +NOTSET: Final = NotSetType.token # noqa: E305 +# fmt: on + +if sys.version_info >= (3, 8): + import importlib.metadata + + importlib_metadata = importlib.metadata +else: + import importlib_metadata as importlib_metadata # noqa: F401 + + +def _format_args(func: Callable[..., Any]) -> str: + return str(signature(func)) + + +def is_generator(func: object) -> bool: + genfunc = inspect.isgeneratorfunction(func) + return genfunc and not iscoroutinefunction(func) + + +def iscoroutinefunction(func: object) -> bool: + """Return True if func is a coroutine function (a function defined with async + def syntax, and doesn't contain yield), or a function decorated with + @asyncio.coroutine. + + Note: copied and modified from Python 3.5's builtin couroutines.py to avoid + importing asyncio directly, which in turns also initializes the "logging" + module as a side-effect (see issue #8). + """ + return inspect.iscoroutinefunction(func) or getattr(func, "_is_coroutine", False) + + +def is_async_function(func: object) -> bool: + """Return True if the given function seems to be an async function or + an async generator.""" + return iscoroutinefunction(func) or inspect.isasyncgenfunction(func) + + +def getlocation(function, curdir: str | None = None) -> str: + function = get_real_func(function) + fn = Path(inspect.getfile(function)) + lineno = function.__code__.co_firstlineno + if curdir is not None: + try: + relfn = fn.relative_to(curdir) + except ValueError: + pass + else: + return "%s:%d" % (relfn, lineno + 1) + return "%s:%d" % (fn, lineno + 1) + + +def num_mock_patch_args(function) -> int: + """Return number of arguments used up by mock arguments (if any).""" + patchings = getattr(function, "patchings", None) + if not patchings: + return 0 + + mock_sentinel = getattr(sys.modules.get("mock"), "DEFAULT", object()) + ut_mock_sentinel = getattr(sys.modules.get("unittest.mock"), "DEFAULT", object()) + + return len( + [ + p + for p in patchings + if not p.attribute_name + and (p.new is mock_sentinel or p.new is ut_mock_sentinel) + ] + ) + + +def getfuncargnames( + function: Callable[..., Any], + *, + name: str = "", + is_method: bool = False, + cls: type | None = None, +) -> tuple[str, ...]: + """Return the names of a function's mandatory arguments. + + Should return the names of all function arguments that: + * Aren't bound to an instance or type as in instance or class methods. + * Don't have default values. + * Aren't bound with functools.partial. + * Aren't replaced with mocks. + + The is_method and cls arguments indicate that the function should + be treated as a bound method even though it's not unless, only in + the case of cls, the function is a static method. + + The name parameter should be the original name in which the function was collected. + """ + # TODO(RonnyPfannschmidt): This function should be refactored when we + # revisit fixtures. The fixture mechanism should ask the node for + # the fixture names, and not try to obtain directly from the + # function object well after collection has occurred. + + # The parameters attribute of a Signature object contains an + # ordered mapping of parameter names to Parameter instances. This + # creates a tuple of the names of the parameters that don't have + # defaults. + try: + parameters = signature(function).parameters + except (ValueError, TypeError) as e: + from _pytest.outcomes import fail + + fail( + f"Could not determine arguments of {function!r}: {e}", + pytrace=False, + ) + + arg_names = tuple( + p.name + for p in parameters.values() + if ( + p.kind is Parameter.POSITIONAL_OR_KEYWORD + or p.kind is Parameter.KEYWORD_ONLY + ) + and p.default is Parameter.empty + ) + if not name: + name = function.__name__ + + # If this function should be treated as a bound method even though + # it's passed as an unbound method or function, remove the first + # parameter name. + if is_method or ( + # Not using `getattr` because we don't want to resolve the staticmethod. + # Not using `cls.__dict__` because we want to check the entire MRO. + cls + and not isinstance( + inspect.getattr_static(cls, name, default=None), staticmethod + ) + ): + arg_names = arg_names[1:] + # Remove any names that will be replaced with mocks. + if hasattr(function, "__wrapped__"): + arg_names = arg_names[num_mock_patch_args(function) :] + return arg_names + + +def get_default_arg_names(function: Callable[..., Any]) -> tuple[str, ...]: + # Note: this code intentionally mirrors the code at the beginning of + # getfuncargnames, to get the arguments which were excluded from its result + # because they had default values. + return tuple( + p.name + for p in signature(function).parameters.values() + if p.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) + and p.default is not Parameter.empty + ) + + +_non_printable_ascii_translate_table = { + i: f"\\x{i:02x}" for i in range(128) if i not in range(32, 127) +} +_non_printable_ascii_translate_table.update( + {ord("\t"): "\\t", ord("\r"): "\\r", ord("\n"): "\\n"} +) + + +def _translate_non_printable(s: str) -> str: + return s.translate(_non_printable_ascii_translate_table) + + +STRING_TYPES = bytes, str + + +def _bytes_to_ascii(val: bytes) -> str: + return val.decode("ascii", "backslashreplace") + + +def ascii_escaped(val: bytes | str) -> str: + r"""If val is pure ASCII, return it as an str, otherwise, escape + bytes objects into a sequence of escaped bytes: + + b'\xc3\xb4\xc5\xd6' -> r'\xc3\xb4\xc5\xd6' + + and escapes unicode objects into a sequence of escaped unicode + ids, e.g.: + + r'4\nV\U00043efa\x0eMXWB\x1e\u3028\u15fd\xcd\U0007d944' + + Note: + The obvious "v.decode('unicode-escape')" will return + valid UTF-8 unicode if it finds them in bytes, but we + want to return escaped bytes for any byte, even if they match + a UTF-8 string. + """ + if isinstance(val, bytes): + ret = _bytes_to_ascii(val) + else: + ret = val.encode("unicode_escape").decode("ascii") + return _translate_non_printable(ret) + + +@dataclasses.dataclass +class _PytestWrapper: + """Dummy wrapper around a function object for internal use only. + + Used to correctly unwrap the underlying function object when we are + creating fixtures, because we wrap the function object ourselves with a + decorator to issue warnings when the fixture function is called directly. + """ + + obj: Any + + +def get_real_func(obj): + """Get the real function object of the (possibly) wrapped object by + functools.wraps or functools.partial.""" + start_obj = obj + for i in range(100): + # __pytest_wrapped__ is set by @pytest.fixture when wrapping the fixture function + # to trigger a warning if it gets called directly instead of by pytest: we don't + # want to unwrap further than this otherwise we lose useful wrappings like @mock.patch (#3774) + new_obj = getattr(obj, "__pytest_wrapped__", None) + if isinstance(new_obj, _PytestWrapper): + obj = new_obj.obj + break + new_obj = getattr(obj, "__wrapped__", None) + if new_obj is None: + break + obj = new_obj + else: + from _pytest._io.saferepr import saferepr + + raise ValueError( + ("could not find real function of {start}\nstopped at {current}").format( + start=saferepr(start_obj), current=saferepr(obj) + ) + ) + if isinstance(obj, functools.partial): + obj = obj.func + return obj + + +def get_real_method(obj, holder): + """Attempt to obtain the real function object that might be wrapping + ``obj``, while at the same time returning a bound method to ``holder`` if + the original object was a bound method.""" + try: + is_method = hasattr(obj, "__func__") + obj = get_real_func(obj) + except Exception: # pragma: no cover + return obj + if is_method and hasattr(obj, "__get__") and callable(obj.__get__): + obj = obj.__get__(holder) + return obj + + +def getimfunc(func): + try: + return func.__func__ + except AttributeError: + return func + + +def safe_getattr(object: Any, name: str, default: Any) -> Any: + """Like getattr but return default upon any Exception or any OutcomeException. + + Attribute access can potentially fail for 'evil' Python objects. + See issue #214. + It catches OutcomeException because of #2490 (issue #580), new outcomes + are derived from BaseException instead of Exception (for more details + check #2707). + """ + from _pytest.outcomes import TEST_OUTCOME + + try: + return getattr(object, name, default) + except TEST_OUTCOME: + return default + + +def safe_isclass(obj: object) -> bool: + """Ignore any exception via isinstance on Python 3.""" + try: + return inspect.isclass(obj) + except Exception: + return False + + +if TYPE_CHECKING: + if sys.version_info >= (3, 8): + from typing import final as final + else: + from typing_extensions import final as final +elif sys.version_info >= (3, 8): + from typing import final as final +else: + + def final(f): + return f + + +if sys.version_info >= (3, 8): + from functools import cached_property as cached_property +else: + + class cached_property(Generic[_S, _T]): + __slots__ = ("func", "__doc__") + + def __init__(self, func: Callable[[_S], _T]) -> None: + self.func = func + self.__doc__ = func.__doc__ + + @overload + def __get__( + self, instance: None, owner: type[_S] | None = ... + ) -> cached_property[_S, _T]: + ... + + @overload + def __get__(self, instance: _S, owner: type[_S] | None = ...) -> _T: + ... + + def __get__(self, instance, owner=None): + if instance is None: + return self + value = instance.__dict__[self.func.__name__] = self.func(instance) + return value + + +def get_user_id() -> int | None: + """Return the current process's real user id or None if it could not be + determined. + + :return: The user id or None if it could not be determined. + """ + # mypy follows the version and platform checking expectation of PEP 484: + # https://mypy.readthedocs.io/en/stable/common_issues.html?highlight=platform#python-version-and-system-platform-checks + # Containment checks are too complex for mypy v1.5.0 and cause failure. + if sys.platform == "win32" or sys.platform == "emscripten": + # win32 does not have a getuid() function. + # Emscripten has a return 0 stub. + return None + else: + # On other platforms, a return value of -1 is assumed to indicate that + # the current process's real user id could not be determined. + ERROR = -1 + uid = os.getuid() + return uid if uid != ERROR else None + + +# Perform exhaustiveness checking. +# +# Consider this example: +# +# MyUnion = Union[int, str] +# +# def handle(x: MyUnion) -> int { +# if isinstance(x, int): +# return 1 +# elif isinstance(x, str): +# return 2 +# else: +# raise Exception('unreachable') +# +# Now suppose we add a new variant: +# +# MyUnion = Union[int, str, bytes] +# +# After doing this, we must remember ourselves to go and update the handle +# function to handle the new variant. +# +# With `assert_never` we can do better: +# +# // raise Exception('unreachable') +# return assert_never(x) +# +# Now, if we forget to handle the new variant, the type-checker will emit a +# compile-time error, instead of the runtime error we would have gotten +# previously. +# +# This also work for Enums (if you use `is` to compare) and Literals. +def assert_never(value: NoReturn) -> NoReturn: + assert False, f"Unhandled value: {value} ({type(value).__name__})" diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/config/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/__init__.py new file mode 100644 index 00000000..e3990d17 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/__init__.py @@ -0,0 +1,1816 @@ +"""Command line options, ini-file and conftest.py processing.""" +import argparse +import collections.abc +import copy +import dataclasses +import enum +import glob +import inspect +import os +import re +import shlex +import sys +import types +import warnings +from functools import lru_cache +from pathlib import Path +from textwrap import dedent +from types import FunctionType +from types import TracebackType +from typing import Any +from typing import Callable +from typing import cast +from typing import Dict +from typing import Generator +from typing import IO +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Optional +from typing import Sequence +from typing import Set +from typing import TextIO +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +from pluggy import HookimplMarker +from pluggy import HookspecMarker +from pluggy import PluginManager + +import _pytest._code +import _pytest.deprecated +import _pytest.hookspec +from .exceptions import PrintHelp as PrintHelp +from .exceptions import UsageError as UsageError +from .findpaths import determine_setup +from _pytest._code import ExceptionInfo +from _pytest._code import filter_traceback +from _pytest._io import TerminalWriter +from _pytest.compat import final +from _pytest.compat import importlib_metadata # type: ignore[attr-defined] +from _pytest.outcomes import fail +from _pytest.outcomes import Skipped +from _pytest.pathlib import absolutepath +from _pytest.pathlib import bestrelpath +from _pytest.pathlib import import_path +from _pytest.pathlib import ImportMode +from _pytest.pathlib import resolve_package_path +from _pytest.pathlib import safe_exists +from _pytest.stash import Stash +from _pytest.warning_types import PytestConfigWarning +from _pytest.warning_types import warn_explicit_for + +if TYPE_CHECKING: + from _pytest._code.code import _TracebackStyle + from _pytest.terminal import TerminalReporter + from .argparsing import Argument + + +_PluggyPlugin = object +"""A type to represent plugin objects. + +Plugins can be any namespace, so we can't narrow it down much, but we use an +alias to make the intent clear. + +Ideally this type would be provided by pluggy itself. +""" + + +hookimpl = HookimplMarker("pytest") +hookspec = HookspecMarker("pytest") + + +@final +class ExitCode(enum.IntEnum): + """Encodes the valid exit codes by pytest. + + Currently users and plugins may supply other exit codes as well. + + .. versionadded:: 5.0 + """ + + #: Tests passed. + OK = 0 + #: Tests failed. + TESTS_FAILED = 1 + #: pytest was interrupted. + INTERRUPTED = 2 + #: An internal error got in the way. + INTERNAL_ERROR = 3 + #: pytest was misused. + USAGE_ERROR = 4 + #: pytest couldn't find tests. + NO_TESTS_COLLECTED = 5 + + +class ConftestImportFailure(Exception): + def __init__( + self, + path: Path, + excinfo: Tuple[Type[Exception], Exception, TracebackType], + ) -> None: + super().__init__(path, excinfo) + self.path = path + self.excinfo = excinfo + + def __str__(self) -> str: + return "{}: {} (from {})".format( + self.excinfo[0].__name__, self.excinfo[1], self.path + ) + + +def filter_traceback_for_conftest_import_failure( + entry: _pytest._code.TracebackEntry, +) -> bool: + """Filter tracebacks entries which point to pytest internals or importlib. + + Make a special case for importlib because we use it to import test modules and conftest files + in _pytest.pathlib.import_path. + """ + return filter_traceback(entry) and "importlib" not in str(entry.path).split(os.sep) + + +def main( + args: Optional[Union[List[str], "os.PathLike[str]"]] = None, + plugins: Optional[Sequence[Union[str, _PluggyPlugin]]] = None, +) -> Union[int, ExitCode]: + """Perform an in-process test run. + + :param args: + List of command line arguments. If `None` or not given, defaults to reading + arguments directly from the process command line (:data:`sys.argv`). + :param plugins: List of plugin objects to be auto-registered during initialization. + + :returns: An exit code. + """ + try: + try: + config = _prepareconfig(args, plugins) + except ConftestImportFailure as e: + exc_info = ExceptionInfo.from_exc_info(e.excinfo) + tw = TerminalWriter(sys.stderr) + tw.line(f"ImportError while loading conftest '{e.path}'.", red=True) + exc_info.traceback = exc_info.traceback.filter( + filter_traceback_for_conftest_import_failure + ) + exc_repr = ( + exc_info.getrepr(style="short", chain=False) + if exc_info.traceback + else exc_info.exconly() + ) + formatted_tb = str(exc_repr) + for line in formatted_tb.splitlines(): + tw.line(line.rstrip(), red=True) + return ExitCode.USAGE_ERROR + else: + try: + ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main( + config=config + ) + try: + return ExitCode(ret) + except ValueError: + return ret + finally: + config._ensure_unconfigure() + except UsageError as e: + tw = TerminalWriter(sys.stderr) + for msg in e.args: + tw.line(f"ERROR: {msg}\n", red=True) + return ExitCode.USAGE_ERROR + + +def console_main() -> int: + """The CLI entry point of pytest. + + This function is not meant for programmable use; use `main()` instead. + """ + # https://docs.python.org/3/library/signal.html#note-on-sigpipe + try: + code = main() + sys.stdout.flush() + return code + except BrokenPipeError: + # Python flushes standard streams on exit; redirect remaining output + # to devnull to avoid another BrokenPipeError at shutdown + devnull = os.open(os.devnull, os.O_WRONLY) + os.dup2(devnull, sys.stdout.fileno()) + return 1 # Python exits with error code 1 on EPIPE + + +class cmdline: # compatibility namespace + main = staticmethod(main) + + +def filename_arg(path: str, optname: str) -> str: + """Argparse type validator for filename arguments. + + :path: Path of filename. + :optname: Name of the option. + """ + if os.path.isdir(path): + raise UsageError(f"{optname} must be a filename, given: {path}") + return path + + +def directory_arg(path: str, optname: str) -> str: + """Argparse type validator for directory arguments. + + :path: Path of directory. + :optname: Name of the option. + """ + if not os.path.isdir(path): + raise UsageError(f"{optname} must be a directory, given: {path}") + return path + + +# Plugins that cannot be disabled via "-p no:X" currently. +essential_plugins = ( + "mark", + "main", + "runner", + "fixtures", + "helpconfig", # Provides -p. +) + +default_plugins = essential_plugins + ( + "python", + "terminal", + "debugging", + "unittest", + "capture", + "skipping", + "legacypath", + "tmpdir", + "monkeypatch", + "recwarn", + "pastebin", + "nose", + "assertion", + "junitxml", + "doctest", + "cacheprovider", + "freeze_support", + "setuponly", + "setupplan", + "stepwise", + "warnings", + "logging", + "reports", + "python_path", + *(["unraisableexception", "threadexception"] if sys.version_info >= (3, 8) else []), + "faulthandler", +) + +builtin_plugins = set(default_plugins) +builtin_plugins.add("pytester") +builtin_plugins.add("pytester_assertions") + + +def get_config( + args: Optional[List[str]] = None, + plugins: Optional[Sequence[Union[str, _PluggyPlugin]]] = None, +) -> "Config": + # subsequent calls to main will create a fresh instance + pluginmanager = PytestPluginManager() + config = Config( + pluginmanager, + invocation_params=Config.InvocationParams( + args=args or (), + plugins=plugins, + dir=Path.cwd(), + ), + ) + + if args is not None: + # Handle any "-p no:plugin" args. + pluginmanager.consider_preparse(args, exclude_only=True) + + for spec in default_plugins: + pluginmanager.import_plugin(spec) + + return config + + +def get_plugin_manager() -> "PytestPluginManager": + """Obtain a new instance of the + :py:class:`pytest.PytestPluginManager`, with default plugins + already loaded. + + This function can be used by integration with other tools, like hooking + into pytest to run tests into an IDE. + """ + return get_config().pluginmanager + + +def _prepareconfig( + args: Optional[Union[List[str], "os.PathLike[str]"]] = None, + plugins: Optional[Sequence[Union[str, _PluggyPlugin]]] = None, +) -> "Config": + if args is None: + args = sys.argv[1:] + elif isinstance(args, os.PathLike): + args = [os.fspath(args)] + elif not isinstance(args, list): + msg = ( # type:ignore[unreachable] + "`args` parameter expected to be a list of strings, got: {!r} (type: {})" + ) + raise TypeError(msg.format(args, type(args))) + + config = get_config(args, plugins) + pluginmanager = config.pluginmanager + try: + if plugins: + for plugin in plugins: + if isinstance(plugin, str): + pluginmanager.consider_pluginarg(plugin) + else: + pluginmanager.register(plugin) + config = pluginmanager.hook.pytest_cmdline_parse( + pluginmanager=pluginmanager, args=args + ) + return config + except BaseException: + config._ensure_unconfigure() + raise + + +def _get_directory(path: Path) -> Path: + """Get the directory of a path - itself if already a directory.""" + if path.is_file(): + return path.parent + else: + return path + + +def _get_legacy_hook_marks( + method: Any, + hook_type: str, + opt_names: Tuple[str, ...], +) -> Dict[str, bool]: + if TYPE_CHECKING: + # abuse typeguard from importlib to avoid massive method type union thats lacking a alias + assert inspect.isroutine(method) + known_marks: set[str] = {m.name for m in getattr(method, "pytestmark", [])} + must_warn: list[str] = [] + opts: dict[str, bool] = {} + for opt_name in opt_names: + opt_attr = getattr(method, opt_name, AttributeError) + if opt_attr is not AttributeError: + must_warn.append(f"{opt_name}={opt_attr}") + opts[opt_name] = True + elif opt_name in known_marks: + must_warn.append(f"{opt_name}=True") + opts[opt_name] = True + else: + opts[opt_name] = False + if must_warn: + hook_opts = ", ".join(must_warn) + message = _pytest.deprecated.HOOK_LEGACY_MARKING.format( + type=hook_type, + fullname=method.__qualname__, + hook_opts=hook_opts, + ) + warn_explicit_for(cast(FunctionType, method), message) + return opts + + +@final +class PytestPluginManager(PluginManager): + """A :py:class:`pluggy.PluginManager ` with + additional pytest-specific functionality: + + * Loading plugins from the command line, ``PYTEST_PLUGINS`` env variable and + ``pytest_plugins`` global variables found in plugins being loaded. + * ``conftest.py`` loading during start-up. + """ + + def __init__(self) -> None: + import _pytest.assertion + + super().__init__("pytest") + + # -- State related to local conftest plugins. + # All loaded conftest modules. + self._conftest_plugins: Set[types.ModuleType] = set() + # All conftest modules applicable for a directory. + # This includes the directory's own conftest modules as well + # as those of its parent directories. + self._dirpath2confmods: Dict[Path, List[types.ModuleType]] = {} + # Cutoff directory above which conftests are no longer discovered. + self._confcutdir: Optional[Path] = None + # If set, conftest loading is skipped. + self._noconftest = False + + # _getconftestmodules()'s call to _get_directory() causes a stat + # storm when it's called potentially thousands of times in a test + # session (#9478), often with the same path, so cache it. + self._get_directory = lru_cache(256)(_get_directory) + + self._duplicatepaths: Set[Path] = set() + + # plugins that were explicitly skipped with pytest.skip + # list of (module name, skip reason) + # previously we would issue a warning when a plugin was skipped, but + # since we refactored warnings as first citizens of Config, they are + # just stored here to be used later. + self.skipped_plugins: List[Tuple[str, str]] = [] + + self.add_hookspecs(_pytest.hookspec) + self.register(self) + if os.environ.get("PYTEST_DEBUG"): + err: IO[str] = sys.stderr + encoding: str = getattr(err, "encoding", "utf8") + try: + err = open( + os.dup(err.fileno()), + mode=err.mode, + buffering=1, + encoding=encoding, + ) + except Exception: + pass + self.trace.root.setwriter(err.write) + self.enable_tracing() + + # Config._consider_importhook will set a real object if required. + self.rewrite_hook = _pytest.assertion.DummyRewriteHook() + # Used to know when we are importing conftests after the pytest_configure stage. + self._configured = False + + def parse_hookimpl_opts(self, plugin: _PluggyPlugin, name: str): + # pytest hooks are always prefixed with "pytest_", + # so we avoid accessing possibly non-readable attributes + # (see issue #1073). + if not name.startswith("pytest_"): + return None + # Ignore names which can not be hooks. + if name == "pytest_plugins": + return None + + opts = super().parse_hookimpl_opts(plugin, name) + if opts is not None: + return opts + + method = getattr(plugin, name) + # Consider only actual functions for hooks (#3775). + if not inspect.isroutine(method): + return None + # Collect unmarked hooks as long as they have the `pytest_' prefix. + return _get_legacy_hook_marks( # type: ignore[return-value] + method, "impl", ("tryfirst", "trylast", "optionalhook", "hookwrapper") + ) + + def parse_hookspec_opts(self, module_or_class, name: str): + opts = super().parse_hookspec_opts(module_or_class, name) + if opts is None: + method = getattr(module_or_class, name) + if name.startswith("pytest_"): + opts = _get_legacy_hook_marks( # type: ignore[assignment] + method, + "spec", + ("firstresult", "historic"), + ) + return opts + + def register( + self, plugin: _PluggyPlugin, name: Optional[str] = None + ) -> Optional[str]: + if name in _pytest.deprecated.DEPRECATED_EXTERNAL_PLUGINS: + warnings.warn( + PytestConfigWarning( + "{} plugin has been merged into the core, " + "please remove it from your requirements.".format( + name.replace("_", "-") + ) + ) + ) + return None + ret: Optional[str] = super().register(plugin, name) + if ret: + self.hook.pytest_plugin_registered.call_historic( + kwargs=dict(plugin=plugin, manager=self) + ) + + if isinstance(plugin, types.ModuleType): + self.consider_module(plugin) + return ret + + def getplugin(self, name: str): + # Support deprecated naming because plugins (xdist e.g.) use it. + plugin: Optional[_PluggyPlugin] = self.get_plugin(name) + return plugin + + def hasplugin(self, name: str) -> bool: + """Return whether a plugin with the given name is registered.""" + return bool(self.get_plugin(name)) + + def pytest_configure(self, config: "Config") -> None: + """:meta private:""" + # XXX now that the pluginmanager exposes hookimpl(tryfirst...) + # we should remove tryfirst/trylast as markers. + config.addinivalue_line( + "markers", + "tryfirst: mark a hook implementation function such that the " + "plugin machinery will try to call it first/as early as possible. " + "DEPRECATED, use @pytest.hookimpl(tryfirst=True) instead.", + ) + config.addinivalue_line( + "markers", + "trylast: mark a hook implementation function such that the " + "plugin machinery will try to call it last/as late as possible. " + "DEPRECATED, use @pytest.hookimpl(trylast=True) instead.", + ) + self._configured = True + + # + # Internal API for local conftest plugin handling. + # + def _set_initial_conftests( + self, + args: Sequence[Union[str, Path]], + pyargs: bool, + noconftest: bool, + rootpath: Path, + confcutdir: Optional[Path], + importmode: Union[ImportMode, str], + ) -> None: + """Load initial conftest files given a preparsed "namespace". + + As conftest files may add their own command line options which have + arguments ('--my-opt somepath') we might get some false positives. + All builtin and 3rd party plugins will have been loaded, however, so + common options will not confuse our logic here. + """ + current = Path.cwd() + self._confcutdir = absolutepath(current / confcutdir) if confcutdir else None + self._noconftest = noconftest + self._using_pyargs = pyargs + foundanchor = False + for intitial_path in args: + path = str(intitial_path) + # remove node-id syntax + i = path.find("::") + if i != -1: + path = path[:i] + anchor = absolutepath(current / path) + + # Ensure we do not break if what appears to be an anchor + # is in fact a very long option (#10169, #11394). + if safe_exists(anchor): + self._try_load_conftest(anchor, importmode, rootpath) + foundanchor = True + if not foundanchor: + self._try_load_conftest(current, importmode, rootpath) + + def _is_in_confcutdir(self, path: Path) -> bool: + """Whether a path is within the confcutdir. + + When false, should not load conftest. + """ + if self._confcutdir is None: + return True + return path not in self._confcutdir.parents + + def _try_load_conftest( + self, anchor: Path, importmode: Union[str, ImportMode], rootpath: Path + ) -> None: + self._getconftestmodules(anchor, importmode, rootpath) + # let's also consider test* subdirs + if anchor.is_dir(): + for x in anchor.glob("test*"): + if x.is_dir(): + self._getconftestmodules(x, importmode, rootpath) + + def _getconftestmodules( + self, path: Path, importmode: Union[str, ImportMode], rootpath: Path + ) -> Sequence[types.ModuleType]: + if self._noconftest: + return [] + + directory = self._get_directory(path) + + # Optimization: avoid repeated searches in the same directory. + # Assumes always called with same importmode and rootpath. + existing_clist = self._dirpath2confmods.get(directory) + if existing_clist is not None: + return existing_clist + + # XXX these days we may rather want to use config.rootpath + # and allow users to opt into looking into the rootdir parent + # directories instead of requiring to specify confcutdir. + clist = [] + for parent in reversed((directory, *directory.parents)): + if self._is_in_confcutdir(parent): + conftestpath = parent / "conftest.py" + if conftestpath.is_file(): + mod = self._importconftest(conftestpath, importmode, rootpath) + clist.append(mod) + self._dirpath2confmods[directory] = clist + return clist + + def _rget_with_confmod( + self, + name: str, + path: Path, + importmode: Union[str, ImportMode], + rootpath: Path, + ) -> Tuple[types.ModuleType, Any]: + modules = self._getconftestmodules(path, importmode, rootpath=rootpath) + for mod in reversed(modules): + try: + return mod, getattr(mod, name) + except AttributeError: + continue + raise KeyError(name) + + def _importconftest( + self, conftestpath: Path, importmode: Union[str, ImportMode], rootpath: Path + ) -> types.ModuleType: + existing = self.get_plugin(str(conftestpath)) + if existing is not None: + return cast(types.ModuleType, existing) + + pkgpath = resolve_package_path(conftestpath) + if pkgpath is None: + _ensure_removed_sysmodule(conftestpath.stem) + + try: + mod = import_path(conftestpath, mode=importmode, root=rootpath) + except Exception as e: + assert e.__traceback__ is not None + exc_info = (type(e), e, e.__traceback__) + raise ConftestImportFailure(conftestpath, exc_info) from e + + self._check_non_top_pytest_plugins(mod, conftestpath) + + self._conftest_plugins.add(mod) + dirpath = conftestpath.parent + if dirpath in self._dirpath2confmods: + for path, mods in self._dirpath2confmods.items(): + if dirpath in path.parents or path == dirpath: + assert mod not in mods + mods.append(mod) + self.trace(f"loading conftestmodule {mod!r}") + self.consider_conftest(mod) + return mod + + def _check_non_top_pytest_plugins( + self, + mod: types.ModuleType, + conftestpath: Path, + ) -> None: + if ( + hasattr(mod, "pytest_plugins") + and self._configured + and not self._using_pyargs + ): + msg = ( + "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported:\n" + "It affects the entire test suite instead of just below the conftest as expected.\n" + " {}\n" + "Please move it to a top level conftest file at the rootdir:\n" + " {}\n" + "For more information, visit:\n" + " https://docs.pytest.org/en/stable/deprecations.html#pytest-plugins-in-non-top-level-conftest-files" + ) + fail(msg.format(conftestpath, self._confcutdir), pytrace=False) + + # + # API for bootstrapping plugin loading + # + # + + def consider_preparse( + self, args: Sequence[str], *, exclude_only: bool = False + ) -> None: + """:meta private:""" + i = 0 + n = len(args) + while i < n: + opt = args[i] + i += 1 + if isinstance(opt, str): + if opt == "-p": + try: + parg = args[i] + except IndexError: + return + i += 1 + elif opt.startswith("-p"): + parg = opt[2:] + else: + continue + parg = parg.strip() + if exclude_only and not parg.startswith("no:"): + continue + self.consider_pluginarg(parg) + + def consider_pluginarg(self, arg: str) -> None: + """:meta private:""" + if arg.startswith("no:"): + name = arg[3:] + if name in essential_plugins: + raise UsageError("plugin %s cannot be disabled" % name) + + # PR #4304: remove stepwise if cacheprovider is blocked. + if name == "cacheprovider": + self.set_blocked("stepwise") + self.set_blocked("pytest_stepwise") + + self.set_blocked(name) + if not name.startswith("pytest_"): + self.set_blocked("pytest_" + name) + else: + name = arg + # Unblock the plugin. None indicates that it has been blocked. + # There is no interface with pluggy for this. + if self._name2plugin.get(name, -1) is None: + del self._name2plugin[name] + if not name.startswith("pytest_"): + if self._name2plugin.get("pytest_" + name, -1) is None: + del self._name2plugin["pytest_" + name] + self.import_plugin(arg, consider_entry_points=True) + + def consider_conftest(self, conftestmodule: types.ModuleType) -> None: + """:meta private:""" + self.register(conftestmodule, name=conftestmodule.__file__) + + def consider_env(self) -> None: + """:meta private:""" + self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS")) + + def consider_module(self, mod: types.ModuleType) -> None: + """:meta private:""" + self._import_plugin_specs(getattr(mod, "pytest_plugins", [])) + + def _import_plugin_specs( + self, spec: Union[None, types.ModuleType, str, Sequence[str]] + ) -> None: + plugins = _get_plugin_specs_as_list(spec) + for import_spec in plugins: + self.import_plugin(import_spec) + + def import_plugin(self, modname: str, consider_entry_points: bool = False) -> None: + """Import a plugin with ``modname``. + + If ``consider_entry_points`` is True, entry point names are also + considered to find a plugin. + """ + # Most often modname refers to builtin modules, e.g. "pytester", + # "terminal" or "capture". Those plugins are registered under their + # basename for historic purposes but must be imported with the + # _pytest prefix. + assert isinstance(modname, str), ( + "module name as text required, got %r" % modname + ) + if self.is_blocked(modname) or self.get_plugin(modname) is not None: + return + + importspec = "_pytest." + modname if modname in builtin_plugins else modname + self.rewrite_hook.mark_rewrite(importspec) + + if consider_entry_points: + loaded = self.load_setuptools_entrypoints("pytest11", name=modname) + if loaded: + return + + try: + __import__(importspec) + except ImportError as e: + raise ImportError( + f'Error importing plugin "{modname}": {e.args[0]}' + ).with_traceback(e.__traceback__) from e + + except Skipped as e: + self.skipped_plugins.append((modname, e.msg or "")) + else: + mod = sys.modules[importspec] + self.register(mod, modname) + + +def _get_plugin_specs_as_list( + specs: Union[None, types.ModuleType, str, Sequence[str]] +) -> List[str]: + """Parse a plugins specification into a list of plugin names.""" + # None means empty. + if specs is None: + return [] + # Workaround for #3899 - a submodule which happens to be called "pytest_plugins". + if isinstance(specs, types.ModuleType): + return [] + # Comma-separated list. + if isinstance(specs, str): + return specs.split(",") if specs else [] + # Direct specification. + if isinstance(specs, collections.abc.Sequence): + return list(specs) + raise UsageError( + "Plugins may be specified as a sequence or a ','-separated string of plugin names. Got: %r" + % specs + ) + + +def _ensure_removed_sysmodule(modname: str) -> None: + try: + del sys.modules[modname] + except KeyError: + pass + + +class Notset: + def __repr__(self): + return "" + + +notset = Notset() + + +def _iter_rewritable_modules(package_files: Iterable[str]) -> Iterator[str]: + """Given an iterable of file names in a source distribution, return the "names" that should + be marked for assertion rewrite. + + For example the package "pytest_mock/__init__.py" should be added as "pytest_mock" in + the assertion rewrite mechanism. + + This function has to deal with dist-info based distributions and egg based distributions + (which are still very much in use for "editable" installs). + + Here are the file names as seen in a dist-info based distribution: + + pytest_mock/__init__.py + pytest_mock/_version.py + pytest_mock/plugin.py + pytest_mock.egg-info/PKG-INFO + + Here are the file names as seen in an egg based distribution: + + src/pytest_mock/__init__.py + src/pytest_mock/_version.py + src/pytest_mock/plugin.py + src/pytest_mock.egg-info/PKG-INFO + LICENSE + setup.py + + We have to take in account those two distribution flavors in order to determine which + names should be considered for assertion rewriting. + + More information: + https://github.com/pytest-dev/pytest-mock/issues/167 + """ + package_files = list(package_files) + seen_some = False + for fn in package_files: + is_simple_module = "/" not in fn and fn.endswith(".py") + is_package = fn.count("/") == 1 and fn.endswith("__init__.py") + if is_simple_module: + module_name, _ = os.path.splitext(fn) + # we ignore "setup.py" at the root of the distribution + # as well as editable installation finder modules made by setuptools + if module_name != "setup" and not module_name.startswith("__editable__"): + seen_some = True + yield module_name + elif is_package: + package_name = os.path.dirname(fn) + seen_some = True + yield package_name + + if not seen_some: + # At this point we did not find any packages or modules suitable for assertion + # rewriting, so we try again by stripping the first path component (to account for + # "src" based source trees for example). + # This approach lets us have the common case continue to be fast, as egg-distributions + # are rarer. + new_package_files = [] + for fn in package_files: + parts = fn.split("/") + new_fn = "/".join(parts[1:]) + if new_fn: + new_package_files.append(new_fn) + if new_package_files: + yield from _iter_rewritable_modules(new_package_files) + + +@final +class Config: + """Access to configuration values, pluginmanager and plugin hooks. + + :param PytestPluginManager pluginmanager: + A pytest PluginManager. + + :param InvocationParams invocation_params: + Object containing parameters regarding the :func:`pytest.main` + invocation. + """ + + @final + @dataclasses.dataclass(frozen=True) + class InvocationParams: + """Holds parameters passed during :func:`pytest.main`. + + The object attributes are read-only. + + .. versionadded:: 5.1 + + .. note:: + + Note that the environment variable ``PYTEST_ADDOPTS`` and the ``addopts`` + ini option are handled by pytest, not being included in the ``args`` attribute. + + Plugins accessing ``InvocationParams`` must be aware of that. + """ + + args: Tuple[str, ...] + """The command-line arguments as passed to :func:`pytest.main`.""" + plugins: Optional[Sequence[Union[str, _PluggyPlugin]]] + """Extra plugins, might be `None`.""" + dir: Path + """The directory from which :func:`pytest.main` was invoked.""" + + def __init__( + self, + *, + args: Iterable[str], + plugins: Optional[Sequence[Union[str, _PluggyPlugin]]], + dir: Path, + ) -> None: + object.__setattr__(self, "args", tuple(args)) + object.__setattr__(self, "plugins", plugins) + object.__setattr__(self, "dir", dir) + + class ArgsSource(enum.Enum): + """Indicates the source of the test arguments. + + .. versionadded:: 7.2 + """ + + #: Command line arguments. + ARGS = enum.auto() + #: Invocation directory. + INCOVATION_DIR = enum.auto() + #: 'testpaths' configuration value. + TESTPATHS = enum.auto() + + def __init__( + self, + pluginmanager: PytestPluginManager, + *, + invocation_params: Optional[InvocationParams] = None, + ) -> None: + from .argparsing import Parser, FILE_OR_DIR + + if invocation_params is None: + invocation_params = self.InvocationParams( + args=(), plugins=None, dir=Path.cwd() + ) + + self.option = argparse.Namespace() + """Access to command line option as attributes. + + :type: argparse.Namespace + """ + + self.invocation_params = invocation_params + """The parameters with which pytest was invoked. + + :type: InvocationParams + """ + + _a = FILE_OR_DIR + self._parser = Parser( + usage=f"%(prog)s [options] [{_a}] [{_a}] [...]", + processopt=self._processopt, + _ispytest=True, + ) + self.pluginmanager = pluginmanager + """The plugin manager handles plugin registration and hook invocation. + + :type: PytestPluginManager + """ + + self.stash = Stash() + """A place where plugins can store information on the config for their + own use. + + :type: Stash + """ + # Deprecated alias. Was never public. Can be removed in a few releases. + self._store = self.stash + + from .compat import PathAwareHookProxy + + self.trace = self.pluginmanager.trace.root.get("config") + self.hook = PathAwareHookProxy(self.pluginmanager.hook) + self._inicache: Dict[str, Any] = {} + self._override_ini: Sequence[str] = () + self._opt2dest: Dict[str, str] = {} + self._cleanup: List[Callable[[], None]] = [] + self.pluginmanager.register(self, "pytestconfig") + self._configured = False + self.hook.pytest_addoption.call_historic( + kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager) + ) + self.args_source = Config.ArgsSource.ARGS + self.args: List[str] = [] + + if TYPE_CHECKING: + from _pytest.cacheprovider import Cache + + self.cache: Optional[Cache] = None + + @property + def rootpath(self) -> Path: + """The path to the :ref:`rootdir `. + + :type: pathlib.Path + + .. versionadded:: 6.1 + """ + return self._rootpath + + @property + def inipath(self) -> Optional[Path]: + """The path to the :ref:`configfile `. + + :type: Optional[pathlib.Path] + + .. versionadded:: 6.1 + """ + return self._inipath + + def add_cleanup(self, func: Callable[[], None]) -> None: + """Add a function to be called when the config object gets out of + use (usually coinciding with pytest_unconfigure).""" + self._cleanup.append(func) + + def _do_configure(self) -> None: + assert not self._configured + self._configured = True + with warnings.catch_warnings(): + warnings.simplefilter("default") + self.hook.pytest_configure.call_historic(kwargs=dict(config=self)) + + def _ensure_unconfigure(self) -> None: + if self._configured: + self._configured = False + self.hook.pytest_unconfigure(config=self) + self.hook.pytest_configure._call_history = [] + while self._cleanup: + fin = self._cleanup.pop() + fin() + + def get_terminal_writer(self) -> TerminalWriter: + terminalreporter: Optional[TerminalReporter] = self.pluginmanager.get_plugin( + "terminalreporter" + ) + assert terminalreporter is not None + return terminalreporter._tw + + def pytest_cmdline_parse( + self, pluginmanager: PytestPluginManager, args: List[str] + ) -> "Config": + try: + self.parse(args) + except UsageError: + # Handle --version and --help here in a minimal fashion. + # This gets done via helpconfig normally, but its + # pytest_cmdline_main is not called in case of errors. + if getattr(self.option, "version", False) or "--version" in args: + from _pytest.helpconfig import showversion + + showversion(self) + elif ( + getattr(self.option, "help", False) or "--help" in args or "-h" in args + ): + self._parser._getparser().print_help() + sys.stdout.write( + "\nNOTE: displaying only minimal help due to UsageError.\n\n" + ) + + raise + + return self + + def notify_exception( + self, + excinfo: ExceptionInfo[BaseException], + option: Optional[argparse.Namespace] = None, + ) -> None: + if option and getattr(option, "fulltrace", False): + style: _TracebackStyle = "long" + else: + style = "native" + excrepr = excinfo.getrepr( + funcargs=True, showlocals=getattr(option, "showlocals", False), style=style + ) + res = self.hook.pytest_internalerror(excrepr=excrepr, excinfo=excinfo) + if not any(res): + for line in str(excrepr).split("\n"): + sys.stderr.write("INTERNALERROR> %s\n" % line) + sys.stderr.flush() + + def cwd_relative_nodeid(self, nodeid: str) -> str: + # nodeid's are relative to the rootpath, compute relative to cwd. + if self.invocation_params.dir != self.rootpath: + fullpath = self.rootpath / nodeid + nodeid = bestrelpath(self.invocation_params.dir, fullpath) + return nodeid + + @classmethod + def fromdictargs(cls, option_dict, args) -> "Config": + """Constructor usable for subprocesses.""" + config = get_config(args) + config.option.__dict__.update(option_dict) + config.parse(args, addopts=False) + for x in config.option.plugins: + config.pluginmanager.consider_pluginarg(x) + return config + + def _processopt(self, opt: "Argument") -> None: + for name in opt._short_opts + opt._long_opts: + self._opt2dest[name] = opt.dest + + if hasattr(opt, "default"): + if not hasattr(self.option, opt.dest): + setattr(self.option, opt.dest, opt.default) + + @hookimpl(trylast=True) + def pytest_load_initial_conftests(self, early_config: "Config") -> None: + # We haven't fully parsed the command line arguments yet, so + # early_config.args it not set yet. But we need it for + # discovering the initial conftests. So "pre-run" the logic here. + # It will be done for real in `parse()`. + args, args_source = early_config._decide_args( + args=early_config.known_args_namespace.file_or_dir, + pyargs=early_config.known_args_namespace.pyargs, + testpaths=early_config.getini("testpaths"), + invocation_dir=early_config.invocation_params.dir, + rootpath=early_config.rootpath, + warn=False, + ) + self.pluginmanager._set_initial_conftests( + args=args, + pyargs=early_config.known_args_namespace.pyargs, + noconftest=early_config.known_args_namespace.noconftest, + rootpath=early_config.rootpath, + confcutdir=early_config.known_args_namespace.confcutdir, + importmode=early_config.known_args_namespace.importmode, + ) + + def _initini(self, args: Sequence[str]) -> None: + ns, unknown_args = self._parser.parse_known_and_unknown_args( + args, namespace=copy.copy(self.option) + ) + rootpath, inipath, inicfg = determine_setup( + ns.inifilename, + ns.file_or_dir + unknown_args, + rootdir_cmd_arg=ns.rootdir or None, + config=self, + ) + self._rootpath = rootpath + self._inipath = inipath + self.inicfg = inicfg + self._parser.extra_info["rootdir"] = str(self.rootpath) + self._parser.extra_info["inifile"] = str(self.inipath) + self._parser.addini("addopts", "Extra command line options", "args") + self._parser.addini("minversion", "Minimally required pytest version") + self._parser.addini( + "required_plugins", + "Plugins that must be present for pytest to run", + type="args", + default=[], + ) + self._override_ini = ns.override_ini or () + + def _consider_importhook(self, args: Sequence[str]) -> None: + """Install the PEP 302 import hook if using assertion rewriting. + + Needs to parse the --assert= option from the commandline + and find all the installed plugins to mark them for rewriting + by the importhook. + """ + ns, unknown_args = self._parser.parse_known_and_unknown_args(args) + mode = getattr(ns, "assertmode", "plain") + if mode == "rewrite": + import _pytest.assertion + + try: + hook = _pytest.assertion.install_importhook(self) + except SystemError: + mode = "plain" + else: + self._mark_plugins_for_rewrite(hook) + self._warn_about_missing_assertion(mode) + + def _mark_plugins_for_rewrite(self, hook) -> None: + """Given an importhook, mark for rewrite any top-level + modules or packages in the distribution package for + all pytest plugins.""" + self.pluginmanager.rewrite_hook = hook + + if os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"): + # We don't autoload from setuptools entry points, no need to continue. + return + + package_files = ( + str(file) + for dist in importlib_metadata.distributions() + if any(ep.group == "pytest11" for ep in dist.entry_points) + for file in dist.files or [] + ) + + for name in _iter_rewritable_modules(package_files): + hook.mark_rewrite(name) + + def _validate_args(self, args: List[str], via: str) -> List[str]: + """Validate known args.""" + self._parser._config_source_hint = via # type: ignore + try: + self._parser.parse_known_and_unknown_args( + args, namespace=copy.copy(self.option) + ) + finally: + del self._parser._config_source_hint # type: ignore + + return args + + def _decide_args( + self, + *, + args: List[str], + pyargs: List[str], + testpaths: List[str], + invocation_dir: Path, + rootpath: Path, + warn: bool, + ) -> Tuple[List[str], ArgsSource]: + """Decide the args (initial paths/nodeids) to use given the relevant inputs. + + :param warn: Whether can issue warnings. + """ + if args: + source = Config.ArgsSource.ARGS + result = args + else: + if invocation_dir == rootpath: + source = Config.ArgsSource.TESTPATHS + if pyargs: + result = testpaths + else: + result = [] + for path in testpaths: + result.extend(sorted(glob.iglob(path, recursive=True))) + if testpaths and not result: + if warn: + warning_text = ( + "No files were found in testpaths; " + "consider removing or adjusting your testpaths configuration. " + "Searching recursively from the current directory instead." + ) + self.issue_config_time_warning( + PytestConfigWarning(warning_text), stacklevel=3 + ) + else: + result = [] + if not result: + source = Config.ArgsSource.INCOVATION_DIR + result = [str(invocation_dir)] + return result, source + + def _preparse(self, args: List[str], addopts: bool = True) -> None: + if addopts: + env_addopts = os.environ.get("PYTEST_ADDOPTS", "") + if len(env_addopts): + args[:] = ( + self._validate_args(shlex.split(env_addopts), "via PYTEST_ADDOPTS") + + args + ) + self._initini(args) + if addopts: + args[:] = ( + self._validate_args(self.getini("addopts"), "via addopts config") + args + ) + + self.known_args_namespace = self._parser.parse_known_args( + args, namespace=copy.copy(self.option) + ) + self._checkversion() + self._consider_importhook(args) + self.pluginmanager.consider_preparse(args, exclude_only=False) + if not os.environ.get("PYTEST_DISABLE_PLUGIN_AUTOLOAD"): + # Don't autoload from setuptools entry point. Only explicitly specified + # plugins are going to be loaded. + self.pluginmanager.load_setuptools_entrypoints("pytest11") + self.pluginmanager.consider_env() + + self.known_args_namespace = self._parser.parse_known_args( + args, namespace=copy.copy(self.known_args_namespace) + ) + + self._validate_plugins() + self._warn_about_skipped_plugins() + + if self.known_args_namespace.strict: + self.issue_config_time_warning( + _pytest.deprecated.STRICT_OPTION, stacklevel=2 + ) + + if self.known_args_namespace.confcutdir is None: + if self.inipath is not None: + confcutdir = str(self.inipath.parent) + else: + confcutdir = str(self.rootpath) + self.known_args_namespace.confcutdir = confcutdir + try: + self.hook.pytest_load_initial_conftests( + early_config=self, args=args, parser=self._parser + ) + except ConftestImportFailure as e: + if self.known_args_namespace.help or self.known_args_namespace.version: + # we don't want to prevent --help/--version to work + # so just let is pass and print a warning at the end + self.issue_config_time_warning( + PytestConfigWarning(f"could not load initial conftests: {e.path}"), + stacklevel=2, + ) + else: + raise + + @hookimpl(hookwrapper=True) + def pytest_collection(self) -> Generator[None, None, None]: + # Validate invalid ini keys after collection is done so we take in account + # options added by late-loading conftest files. + yield + self._validate_config_options() + + def _checkversion(self) -> None: + import pytest + + minver = self.inicfg.get("minversion", None) + if minver: + # Imported lazily to improve start-up time. + from packaging.version import Version + + if not isinstance(minver, str): + raise pytest.UsageError( + "%s: 'minversion' must be a single value" % self.inipath + ) + + if Version(minver) > Version(pytest.__version__): + raise pytest.UsageError( + "%s: 'minversion' requires pytest-%s, actual pytest-%s'" + % ( + self.inipath, + minver, + pytest.__version__, + ) + ) + + def _validate_config_options(self) -> None: + for key in sorted(self._get_unknown_ini_keys()): + self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") + + def _validate_plugins(self) -> None: + required_plugins = sorted(self.getini("required_plugins")) + if not required_plugins: + return + + # Imported lazily to improve start-up time. + from packaging.version import Version + from packaging.requirements import InvalidRequirement, Requirement + + plugin_info = self.pluginmanager.list_plugin_distinfo() + plugin_dist_info = {dist.project_name: dist.version for _, dist in plugin_info} + + missing_plugins = [] + for required_plugin in required_plugins: + try: + req = Requirement(required_plugin) + except InvalidRequirement: + missing_plugins.append(required_plugin) + continue + + if req.name not in plugin_dist_info: + missing_plugins.append(required_plugin) + elif not req.specifier.contains( + Version(plugin_dist_info[req.name]), prereleases=True + ): + missing_plugins.append(required_plugin) + + if missing_plugins: + raise UsageError( + "Missing required plugins: {}".format(", ".join(missing_plugins)), + ) + + def _warn_or_fail_if_strict(self, message: str) -> None: + if self.known_args_namespace.strict_config: + raise UsageError(message) + + self.issue_config_time_warning(PytestConfigWarning(message), stacklevel=3) + + def _get_unknown_ini_keys(self) -> List[str]: + parser_inicfg = self._parser._inidict + return [name for name in self.inicfg if name not in parser_inicfg] + + def parse(self, args: List[str], addopts: bool = True) -> None: + # Parse given cmdline arguments into this config object. + assert ( + self.args == [] + ), "can only parse cmdline args at most once per Config object" + self.hook.pytest_addhooks.call_historic( + kwargs=dict(pluginmanager=self.pluginmanager) + ) + self._preparse(args, addopts=addopts) + # XXX deprecated hook: + self.hook.pytest_cmdline_preparse(config=self, args=args) + self._parser.after_preparse = True # type: ignore + try: + args = self._parser.parse_setoption( + args, self.option, namespace=self.option + ) + self.args, self.args_source = self._decide_args( + args=args, + pyargs=self.known_args_namespace.pyargs, + testpaths=self.getini("testpaths"), + invocation_dir=self.invocation_params.dir, + rootpath=self.rootpath, + warn=True, + ) + except PrintHelp: + pass + + def issue_config_time_warning(self, warning: Warning, stacklevel: int) -> None: + """Issue and handle a warning during the "configure" stage. + + During ``pytest_configure`` we can't capture warnings using the ``catch_warnings_for_item`` + function because it is not possible to have hookwrappers around ``pytest_configure``. + + This function is mainly intended for plugins that need to issue warnings during + ``pytest_configure`` (or similar stages). + + :param warning: The warning instance. + :param stacklevel: stacklevel forwarded to warnings.warn. + """ + if self.pluginmanager.is_blocked("warnings"): + return + + cmdline_filters = self.known_args_namespace.pythonwarnings or [] + config_filters = self.getini("filterwarnings") + + with warnings.catch_warnings(record=True) as records: + warnings.simplefilter("always", type(warning)) + apply_warning_filters(config_filters, cmdline_filters) + warnings.warn(warning, stacklevel=stacklevel) + + if records: + frame = sys._getframe(stacklevel - 1) + location = frame.f_code.co_filename, frame.f_lineno, frame.f_code.co_name + self.hook.pytest_warning_recorded.call_historic( + kwargs=dict( + warning_message=records[0], + when="config", + nodeid="", + location=location, + ) + ) + + def addinivalue_line(self, name: str, line: str) -> None: + """Add a line to an ini-file option. The option must have been + declared but might not yet be set in which case the line becomes + the first line in its value.""" + x = self.getini(name) + assert isinstance(x, list) + x.append(line) # modifies the cached list inline + + def getini(self, name: str): + """Return configuration value from an :ref:`ini file `. + + If the specified name hasn't been registered through a prior + :func:`parser.addini ` call (usually from a + plugin), a ValueError is raised. + """ + try: + return self._inicache[name] + except KeyError: + self._inicache[name] = val = self._getini(name) + return val + + # Meant for easy monkeypatching by legacypath plugin. + # Can be inlined back (with no cover removed) once legacypath is gone. + def _getini_unknown_type(self, name: str, type: str, value: Union[str, List[str]]): + msg = f"unknown configuration type: {type}" + raise ValueError(msg, value) # pragma: no cover + + def _getini(self, name: str): + try: + description, type, default = self._parser._inidict[name] + except KeyError as e: + raise ValueError(f"unknown configuration value: {name!r}") from e + override_value = self._get_override_ini_value(name) + if override_value is None: + try: + value = self.inicfg[name] + except KeyError: + if default is not None: + return default + if type is None: + return "" + return [] + else: + value = override_value + # Coerce the values based on types. + # + # Note: some coercions are only required if we are reading from .ini files, because + # the file format doesn't contain type information, but when reading from toml we will + # get either str or list of str values (see _parse_ini_config_from_pyproject_toml). + # For example: + # + # ini: + # a_line_list = "tests acceptance" + # in this case, we need to split the string to obtain a list of strings. + # + # toml: + # a_line_list = ["tests", "acceptance"] + # in this case, we already have a list ready to use. + # + if type == "paths": + # TODO: This assert is probably not valid in all cases. + assert self.inipath is not None + dp = self.inipath.parent + input_values = shlex.split(value) if isinstance(value, str) else value + return [dp / x for x in input_values] + elif type == "args": + return shlex.split(value) if isinstance(value, str) else value + elif type == "linelist": + if isinstance(value, str): + return [t for t in map(lambda x: x.strip(), value.split("\n")) if t] + else: + return value + elif type == "bool": + return _strtobool(str(value).strip()) + elif type == "string": + return value + elif type is None: + return value + else: + return self._getini_unknown_type(name, type, value) + + def _getconftest_pathlist( + self, name: str, path: Path, rootpath: Path + ) -> Optional[List[Path]]: + try: + mod, relroots = self.pluginmanager._rget_with_confmod( + name, path, self.getoption("importmode"), rootpath + ) + except KeyError: + return None + assert mod.__file__ is not None + modpath = Path(mod.__file__).parent + values: List[Path] = [] + for relroot in relroots: + if isinstance(relroot, os.PathLike): + relroot = Path(relroot) + else: + relroot = relroot.replace("/", os.sep) + relroot = absolutepath(modpath / relroot) + values.append(relroot) + return values + + def _get_override_ini_value(self, name: str) -> Optional[str]: + value = None + # override_ini is a list of "ini=value" options. + # Always use the last item if multiple values are set for same ini-name, + # e.g. -o foo=bar1 -o foo=bar2 will set foo to bar2. + for ini_config in self._override_ini: + try: + key, user_ini_value = ini_config.split("=", 1) + except ValueError as e: + raise UsageError( + "-o/--override-ini expects option=value style (got: {!r}).".format( + ini_config + ) + ) from e + else: + if key == name: + value = user_ini_value + return value + + def getoption(self, name: str, default=notset, skip: bool = False): + """Return command line option value. + + :param name: Name of the option. You may also specify + the literal ``--OPT`` option instead of the "dest" option name. + :param default: Default value if no option of that name exists. + :param skip: If True, raise pytest.skip if option does not exists + or has a None value. + """ + name = self._opt2dest.get(name, name) + try: + val = getattr(self.option, name) + if val is None and skip: + raise AttributeError(name) + return val + except AttributeError as e: + if default is not notset: + return default + if skip: + import pytest + + pytest.skip(f"no {name!r} option found") + raise ValueError(f"no option named {name!r}") from e + + def getvalue(self, name: str, path=None): + """Deprecated, use getoption() instead.""" + return self.getoption(name) + + def getvalueorskip(self, name: str, path=None): + """Deprecated, use getoption(skip=True) instead.""" + return self.getoption(name, skip=True) + + def _warn_about_missing_assertion(self, mode: str) -> None: + if not _assertion_supported(): + if mode == "plain": + warning_text = ( + "ASSERTIONS ARE NOT EXECUTED" + " and FAILING TESTS WILL PASS. Are you" + " using python -O?" + ) + else: + warning_text = ( + "assertions not in test modules or" + " plugins will be ignored" + " because assert statements are not executed " + "by the underlying Python interpreter " + "(are you using python -O?)\n" + ) + self.issue_config_time_warning( + PytestConfigWarning(warning_text), + stacklevel=3, + ) + + def _warn_about_skipped_plugins(self) -> None: + for module_name, msg in self.pluginmanager.skipped_plugins: + self.issue_config_time_warning( + PytestConfigWarning(f"skipped plugin {module_name!r}: {msg}"), + stacklevel=2, + ) + + +def _assertion_supported() -> bool: + try: + assert False + except AssertionError: + return True + else: + return False # type: ignore[unreachable] + + +def create_terminal_writer( + config: Config, file: Optional[TextIO] = None +) -> TerminalWriter: + """Create a TerminalWriter instance configured according to the options + in the config object. + + Every code which requires a TerminalWriter object and has access to a + config object should use this function. + """ + tw = TerminalWriter(file=file) + + if config.option.color == "yes": + tw.hasmarkup = True + elif config.option.color == "no": + tw.hasmarkup = False + + if config.option.code_highlight == "yes": + tw.code_highlight = True + elif config.option.code_highlight == "no": + tw.code_highlight = False + + return tw + + +def _strtobool(val: str) -> bool: + """Convert a string representation of truth to True or False. + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + + .. note:: Copied from distutils.util. + """ + val = val.lower() + if val in ("y", "yes", "t", "true", "on", "1"): + return True + elif val in ("n", "no", "f", "false", "off", "0"): + return False + else: + raise ValueError(f"invalid truth value {val!r}") + + +@lru_cache(maxsize=50) +def parse_warning_filter( + arg: str, *, escape: bool +) -> Tuple["warnings._ActionKind", str, Type[Warning], str, int]: + """Parse a warnings filter string. + + This is copied from warnings._setoption with the following changes: + + * Does not apply the filter. + * Escaping is optional. + * Raises UsageError so we get nice error messages on failure. + """ + __tracebackhide__ = True + error_template = dedent( + f"""\ + while parsing the following warning configuration: + + {arg} + + This error occurred: + + {{error}} + """ + ) + + parts = arg.split(":") + if len(parts) > 5: + doc_url = ( + "https://docs.python.org/3/library/warnings.html#describing-warning-filters" + ) + error = dedent( + f"""\ + Too many fields ({len(parts)}), expected at most 5 separated by colons: + + action:message:category:module:line + + For more information please consult: {doc_url} + """ + ) + raise UsageError(error_template.format(error=error)) + + while len(parts) < 5: + parts.append("") + action_, message, category_, module, lineno_ = (s.strip() for s in parts) + try: + action: "warnings._ActionKind" = warnings._getaction(action_) # type: ignore[attr-defined] + except warnings._OptionError as e: + raise UsageError(error_template.format(error=str(e))) + try: + category: Type[Warning] = _resolve_warning_category(category_) + except Exception: + exc_info = ExceptionInfo.from_current() + exception_text = exc_info.getrepr(style="native") + raise UsageError(error_template.format(error=exception_text)) + if message and escape: + message = re.escape(message) + if module and escape: + module = re.escape(module) + r"\Z" + if lineno_: + try: + lineno = int(lineno_) + if lineno < 0: + raise ValueError("number is negative") + except ValueError as e: + raise UsageError( + error_template.format(error=f"invalid lineno {lineno_!r}: {e}") + ) + else: + lineno = 0 + return action, message, category, module, lineno + + +def _resolve_warning_category(category: str) -> Type[Warning]: + """ + Copied from warnings._getcategory, but changed so it lets exceptions (specially ImportErrors) + propagate so we can get access to their tracebacks (#9218). + """ + __tracebackhide__ = True + if not category: + return Warning + + if "." not in category: + import builtins as m + + klass = category + else: + module, _, klass = category.rpartition(".") + m = __import__(module, None, None, [klass]) + cat = getattr(m, klass) + if not issubclass(cat, Warning): + raise UsageError(f"{cat} is not a Warning subclass") + return cast(Type[Warning], cat) + + +def apply_warning_filters( + config_filters: Iterable[str], cmdline_filters: Iterable[str] +) -> None: + """Applies pytest-configured filters to the warnings module""" + # Filters should have this precedence: cmdline options, config. + # Filters should be applied in the inverse order of precedence. + for arg in config_filters: + warnings.filterwarnings(*parse_warning_filter(arg, escape=False)) + + for arg in cmdline_filters: + warnings.filterwarnings(*parse_warning_filter(arg, escape=True)) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/config/argparsing.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/argparsing.py new file mode 100644 index 00000000..d3f01916 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/argparsing.py @@ -0,0 +1,551 @@ +import argparse +import os +import sys +import warnings +from gettext import gettext +from typing import Any +from typing import Callable +from typing import cast +from typing import Dict +from typing import List +from typing import Mapping +from typing import NoReturn +from typing import Optional +from typing import Sequence +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +import _pytest._io +from _pytest.compat import final +from _pytest.config.exceptions import UsageError +from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT +from _pytest.deprecated import ARGUMENT_TYPE_STR +from _pytest.deprecated import ARGUMENT_TYPE_STR_CHOICE +from _pytest.deprecated import check_ispytest + +if TYPE_CHECKING: + from typing_extensions import Literal + +FILE_OR_DIR = "file_or_dir" + + +@final +class Parser: + """Parser for command line arguments and ini-file values. + + :ivar extra_info: Dict of generic param -> value to display in case + there's an error processing the command line arguments. + """ + + prog: Optional[str] = None + + def __init__( + self, + usage: Optional[str] = None, + processopt: Optional[Callable[["Argument"], None]] = None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._anonymous = OptionGroup("Custom options", parser=self, _ispytest=True) + self._groups: List[OptionGroup] = [] + self._processopt = processopt + self._usage = usage + self._inidict: Dict[str, Tuple[str, Optional[str], Any]] = {} + self._ininames: List[str] = [] + self.extra_info: Dict[str, Any] = {} + + def processoption(self, option: "Argument") -> None: + if self._processopt: + if option.dest: + self._processopt(option) + + def getgroup( + self, name: str, description: str = "", after: Optional[str] = None + ) -> "OptionGroup": + """Get (or create) a named option Group. + + :param name: Name of the option group. + :param description: Long description for --help output. + :param after: Name of another group, used for ordering --help output. + :returns: The option group. + + The returned group object has an ``addoption`` method with the same + signature as :func:`parser.addoption ` but + will be shown in the respective group in the output of + ``pytest --help``. + """ + for group in self._groups: + if group.name == name: + return group + group = OptionGroup(name, description, parser=self, _ispytest=True) + i = 0 + for i, grp in enumerate(self._groups): + if grp.name == after: + break + self._groups.insert(i + 1, group) + return group + + def addoption(self, *opts: str, **attrs: Any) -> None: + """Register a command line option. + + :param opts: + Option names, can be short or long options. + :param attrs: + Same attributes as the argparse library's :py:func:`add_argument() + ` function accepts. + + After command line parsing, options are available on the pytest config + object via ``config.option.NAME`` where ``NAME`` is usually set + by passing a ``dest`` attribute, for example + ``addoption("--long", dest="NAME", ...)``. + """ + self._anonymous.addoption(*opts, **attrs) + + def parse( + self, + args: Sequence[Union[str, "os.PathLike[str]"]], + namespace: Optional[argparse.Namespace] = None, + ) -> argparse.Namespace: + from _pytest._argcomplete import try_argcomplete + + self.optparser = self._getparser() + try_argcomplete(self.optparser) + strargs = [os.fspath(x) for x in args] + return self.optparser.parse_args(strargs, namespace=namespace) + + def _getparser(self) -> "MyOptionParser": + from _pytest._argcomplete import filescompleter + + optparser = MyOptionParser(self, self.extra_info, prog=self.prog) + groups = self._groups + [self._anonymous] + for group in groups: + if group.options: + desc = group.description or group.name + arggroup = optparser.add_argument_group(desc) + for option in group.options: + n = option.names() + a = option.attrs() + arggroup.add_argument(*n, **a) + file_or_dir_arg = optparser.add_argument(FILE_OR_DIR, nargs="*") + # bash like autocompletion for dirs (appending '/') + # Type ignored because typeshed doesn't know about argcomplete. + file_or_dir_arg.completer = filescompleter # type: ignore + return optparser + + def parse_setoption( + self, + args: Sequence[Union[str, "os.PathLike[str]"]], + option: argparse.Namespace, + namespace: Optional[argparse.Namespace] = None, + ) -> List[str]: + parsedoption = self.parse(args, namespace=namespace) + for name, value in parsedoption.__dict__.items(): + setattr(option, name, value) + return cast(List[str], getattr(parsedoption, FILE_OR_DIR)) + + def parse_known_args( + self, + args: Sequence[Union[str, "os.PathLike[str]"]], + namespace: Optional[argparse.Namespace] = None, + ) -> argparse.Namespace: + """Parse the known arguments at this point. + + :returns: An argparse namespace object. + """ + return self.parse_known_and_unknown_args(args, namespace=namespace)[0] + + def parse_known_and_unknown_args( + self, + args: Sequence[Union[str, "os.PathLike[str]"]], + namespace: Optional[argparse.Namespace] = None, + ) -> Tuple[argparse.Namespace, List[str]]: + """Parse the known arguments at this point, and also return the + remaining unknown arguments. + + :returns: + A tuple containing an argparse namespace object for the known + arguments, and a list of the unknown arguments. + """ + optparser = self._getparser() + strargs = [os.fspath(x) for x in args] + return optparser.parse_known_args(strargs, namespace=namespace) + + def addini( + self, + name: str, + help: str, + type: Optional[ + "Literal['string', 'paths', 'pathlist', 'args', 'linelist', 'bool']" + ] = None, + default: Any = None, + ) -> None: + """Register an ini-file option. + + :param name: + Name of the ini-variable. + :param type: + Type of the variable. Can be: + + * ``string``: a string + * ``bool``: a boolean + * ``args``: a list of strings, separated as in a shell + * ``linelist``: a list of strings, separated by line breaks + * ``paths``: a list of :class:`pathlib.Path`, separated as in a shell + * ``pathlist``: a list of ``py.path``, separated as in a shell + + .. versionadded:: 7.0 + The ``paths`` variable type. + + Defaults to ``string`` if ``None`` or not passed. + :param default: + Default value if no ini-file option exists but is queried. + + The value of ini-variables can be retrieved via a call to + :py:func:`config.getini(name) `. + """ + assert type in (None, "string", "paths", "pathlist", "args", "linelist", "bool") + self._inidict[name] = (help, type, default) + self._ininames.append(name) + + +class ArgumentError(Exception): + """Raised if an Argument instance is created with invalid or + inconsistent arguments.""" + + def __init__(self, msg: str, option: Union["Argument", str]) -> None: + self.msg = msg + self.option_id = str(option) + + def __str__(self) -> str: + if self.option_id: + return f"option {self.option_id}: {self.msg}" + else: + return self.msg + + +class Argument: + """Class that mimics the necessary behaviour of optparse.Option. + + It's currently a least effort implementation and ignoring choices + and integer prefixes. + + https://docs.python.org/3/library/optparse.html#optparse-standard-option-types + """ + + _typ_map = {"int": int, "string": str, "float": float, "complex": complex} + + def __init__(self, *names: str, **attrs: Any) -> None: + """Store params in private vars for use in add_argument.""" + self._attrs = attrs + self._short_opts: List[str] = [] + self._long_opts: List[str] = [] + if "%default" in (attrs.get("help") or ""): + warnings.warn(ARGUMENT_PERCENT_DEFAULT, stacklevel=3) + try: + typ = attrs["type"] + except KeyError: + pass + else: + # This might raise a keyerror as well, don't want to catch that. + if isinstance(typ, str): + if typ == "choice": + warnings.warn( + ARGUMENT_TYPE_STR_CHOICE.format(typ=typ, names=names), + stacklevel=4, + ) + # argparse expects a type here take it from + # the type of the first element + attrs["type"] = type(attrs["choices"][0]) + else: + warnings.warn( + ARGUMENT_TYPE_STR.format(typ=typ, names=names), stacklevel=4 + ) + attrs["type"] = Argument._typ_map[typ] + # Used in test_parseopt -> test_parse_defaultgetter. + self.type = attrs["type"] + else: + self.type = typ + try: + # Attribute existence is tested in Config._processopt. + self.default = attrs["default"] + except KeyError: + pass + self._set_opt_strings(names) + dest: Optional[str] = attrs.get("dest") + if dest: + self.dest = dest + elif self._long_opts: + self.dest = self._long_opts[0][2:].replace("-", "_") + else: + try: + self.dest = self._short_opts[0][1:] + except IndexError as e: + self.dest = "???" # Needed for the error repr. + raise ArgumentError("need a long or short option", self) from e + + def names(self) -> List[str]: + return self._short_opts + self._long_opts + + def attrs(self) -> Mapping[str, Any]: + # Update any attributes set by processopt. + attrs = "default dest help".split() + attrs.append(self.dest) + for attr in attrs: + try: + self._attrs[attr] = getattr(self, attr) + except AttributeError: + pass + if self._attrs.get("help"): + a = self._attrs["help"] + a = a.replace("%default", "%(default)s") + # a = a.replace('%prog', '%(prog)s') + self._attrs["help"] = a + return self._attrs + + def _set_opt_strings(self, opts: Sequence[str]) -> None: + """Directly from optparse. + + Might not be necessary as this is passed to argparse later on. + """ + for opt in opts: + if len(opt) < 2: + raise ArgumentError( + "invalid option string %r: " + "must be at least two characters long" % opt, + self, + ) + elif len(opt) == 2: + if not (opt[0] == "-" and opt[1] != "-"): + raise ArgumentError( + "invalid short option string %r: " + "must be of the form -x, (x any non-dash char)" % opt, + self, + ) + self._short_opts.append(opt) + else: + if not (opt[0:2] == "--" and opt[2] != "-"): + raise ArgumentError( + "invalid long option string %r: " + "must start with --, followed by non-dash" % opt, + self, + ) + self._long_opts.append(opt) + + def __repr__(self) -> str: + args: List[str] = [] + if self._short_opts: + args += ["_short_opts: " + repr(self._short_opts)] + if self._long_opts: + args += ["_long_opts: " + repr(self._long_opts)] + args += ["dest: " + repr(self.dest)] + if hasattr(self, "type"): + args += ["type: " + repr(self.type)] + if hasattr(self, "default"): + args += ["default: " + repr(self.default)] + return "Argument({})".format(", ".join(args)) + + +class OptionGroup: + """A group of options shown in its own section.""" + + def __init__( + self, + name: str, + description: str = "", + parser: Optional[Parser] = None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self.name = name + self.description = description + self.options: List[Argument] = [] + self.parser = parser + + def addoption(self, *opts: str, **attrs: Any) -> None: + """Add an option to this group. + + If a shortened version of a long option is specified, it will + be suppressed in the help. ``addoption('--twowords', '--two-words')`` + results in help showing ``--two-words`` only, but ``--twowords`` gets + accepted **and** the automatic destination is in ``args.twowords``. + + :param opts: + Option names, can be short or long options. + :param attrs: + Same attributes as the argparse library's :py:func:`add_argument() + ` function accepts. + """ + conflict = set(opts).intersection( + name for opt in self.options for name in opt.names() + ) + if conflict: + raise ValueError("option names %s already added" % conflict) + option = Argument(*opts, **attrs) + self._addoption_instance(option, shortupper=False) + + def _addoption(self, *opts: str, **attrs: Any) -> None: + option = Argument(*opts, **attrs) + self._addoption_instance(option, shortupper=True) + + def _addoption_instance(self, option: "Argument", shortupper: bool = False) -> None: + if not shortupper: + for opt in option._short_opts: + if opt[0] == "-" and opt[1].islower(): + raise ValueError("lowercase shortoptions reserved") + if self.parser: + self.parser.processoption(option) + self.options.append(option) + + +class MyOptionParser(argparse.ArgumentParser): + def __init__( + self, + parser: Parser, + extra_info: Optional[Dict[str, Any]] = None, + prog: Optional[str] = None, + ) -> None: + self._parser = parser + super().__init__( + prog=prog, + usage=parser._usage, + add_help=False, + formatter_class=DropShorterLongHelpFormatter, + allow_abbrev=False, + ) + # extra_info is a dict of (param -> value) to display if there's + # an usage error to provide more contextual information to the user. + self.extra_info = extra_info if extra_info else {} + + def error(self, message: str) -> NoReturn: + """Transform argparse error message into UsageError.""" + msg = f"{self.prog}: error: {message}" + + if hasattr(self._parser, "_config_source_hint"): + # Type ignored because the attribute is set dynamically. + msg = f"{msg} ({self._parser._config_source_hint})" # type: ignore + + raise UsageError(self.format_usage() + msg) + + # Type ignored because typeshed has a very complex type in the superclass. + def parse_args( # type: ignore + self, + args: Optional[Sequence[str]] = None, + namespace: Optional[argparse.Namespace] = None, + ) -> argparse.Namespace: + """Allow splitting of positional arguments.""" + parsed, unrecognized = self.parse_known_args(args, namespace) + if unrecognized: + for arg in unrecognized: + if arg and arg[0] == "-": + lines = ["unrecognized arguments: %s" % (" ".join(unrecognized))] + for k, v in sorted(self.extra_info.items()): + lines.append(f" {k}: {v}") + self.error("\n".join(lines)) + getattr(parsed, FILE_OR_DIR).extend(unrecognized) + return parsed + + if sys.version_info[:2] < (3, 9): # pragma: no cover + # Backport of https://github.com/python/cpython/pull/14316 so we can + # disable long --argument abbreviations without breaking short flags. + def _parse_optional( + self, arg_string: str + ) -> Optional[Tuple[Optional[argparse.Action], str, Optional[str]]]: + if not arg_string: + return None + if not arg_string[0] in self.prefix_chars: + return None + if arg_string in self._option_string_actions: + action = self._option_string_actions[arg_string] + return action, arg_string, None + if len(arg_string) == 1: + return None + if "=" in arg_string: + option_string, explicit_arg = arg_string.split("=", 1) + if option_string in self._option_string_actions: + action = self._option_string_actions[option_string] + return action, option_string, explicit_arg + if self.allow_abbrev or not arg_string.startswith("--"): + option_tuples = self._get_option_tuples(arg_string) + if len(option_tuples) > 1: + msg = gettext( + "ambiguous option: %(option)s could match %(matches)s" + ) + options = ", ".join(option for _, option, _ in option_tuples) + self.error(msg % {"option": arg_string, "matches": options}) + elif len(option_tuples) == 1: + (option_tuple,) = option_tuples + return option_tuple + if self._negative_number_matcher.match(arg_string): + if not self._has_negative_number_optionals: + return None + if " " in arg_string: + return None + return None, arg_string, None + + +class DropShorterLongHelpFormatter(argparse.HelpFormatter): + """Shorten help for long options that differ only in extra hyphens. + + - Collapse **long** options that are the same except for extra hyphens. + - Shortcut if there are only two options and one of them is a short one. + - Cache result on the action object as this is called at least 2 times. + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + # Use more accurate terminal width. + if "width" not in kwargs: + kwargs["width"] = _pytest._io.get_terminal_width() + super().__init__(*args, **kwargs) + + def _format_action_invocation(self, action: argparse.Action) -> str: + orgstr = super()._format_action_invocation(action) + if orgstr and orgstr[0] != "-": # only optional arguments + return orgstr + res: Optional[str] = getattr(action, "_formatted_action_invocation", None) + if res: + return res + options = orgstr.split(", ") + if len(options) == 2 and (len(options[0]) == 2 or len(options[1]) == 2): + # a shortcut for '-h, --help' or '--abc', '-a' + action._formatted_action_invocation = orgstr # type: ignore + return orgstr + return_list = [] + short_long: Dict[str, str] = {} + for option in options: + if len(option) == 2 or option[2] == " ": + continue + if not option.startswith("--"): + raise ArgumentError( + 'long optional argument without "--": [%s]' % (option), option + ) + xxoption = option[2:] + shortened = xxoption.replace("-", "") + if shortened not in short_long or len(short_long[shortened]) < len( + xxoption + ): + short_long[shortened] = xxoption + # now short_long has been filled out to the longest with dashes + # **and** we keep the right option ordering from add_argument + for option in options: + if len(option) == 2 or option[2] == " ": + return_list.append(option) + if option[2:] == short_long.get(option.replace("-", "")): + return_list.append(option.replace(" ", "=", 1)) + formatted_action_invocation = ", ".join(return_list) + action._formatted_action_invocation = formatted_action_invocation # type: ignore + return formatted_action_invocation + + def _split_lines(self, text, width): + """Wrap lines after splitting on original newlines. + + This allows to have explicit line breaks in the help text. + """ + import textwrap + + lines = [] + for line in text.splitlines(): + lines.extend(textwrap.wrap(line.strip(), width)) + return lines diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/config/compat.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/compat.py new file mode 100644 index 00000000..5bd922a4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/compat.py @@ -0,0 +1,70 @@ +import functools +import warnings +from pathlib import Path +from typing import Optional + +from ..compat import LEGACY_PATH +from ..compat import legacy_path +from ..deprecated import HOOK_LEGACY_PATH_ARG +from _pytest.nodes import _check_path + +# hookname: (Path, LEGACY_PATH) +imply_paths_hooks = { + "pytest_ignore_collect": ("collection_path", "path"), + "pytest_collect_file": ("file_path", "path"), + "pytest_pycollect_makemodule": ("module_path", "path"), + "pytest_report_header": ("start_path", "startdir"), + "pytest_report_collectionfinish": ("start_path", "startdir"), +} + + +class PathAwareHookProxy: + """ + this helper wraps around hook callers + until pluggy supports fixingcalls, this one will do + + it currently doesn't return full hook caller proxies for fixed hooks, + this may have to be changed later depending on bugs + """ + + def __init__(self, hook_caller): + self.__hook_caller = hook_caller + + def __dir__(self): + return dir(self.__hook_caller) + + def __getattr__(self, key, _wraps=functools.wraps): + hook = getattr(self.__hook_caller, key) + if key not in imply_paths_hooks: + self.__dict__[key] = hook + return hook + else: + path_var, fspath_var = imply_paths_hooks[key] + + @_wraps(hook) + def fixed_hook(**kw): + path_value: Optional[Path] = kw.pop(path_var, None) + fspath_value: Optional[LEGACY_PATH] = kw.pop(fspath_var, None) + if fspath_value is not None: + warnings.warn( + HOOK_LEGACY_PATH_ARG.format( + pylib_path_arg=fspath_var, pathlib_path_arg=path_var + ), + stacklevel=2, + ) + if path_value is not None: + if fspath_value is not None: + _check_path(path_value, fspath_value) + else: + fspath_value = legacy_path(path_value) + else: + assert fspath_value is not None + path_value = Path(fspath_value) + + kw[path_var] = path_value + kw[fspath_var] = fspath_value + return hook(**kw) + + fixed_hook.__name__ = key + self.__dict__[key] = fixed_hook + return fixed_hook diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/config/exceptions.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/exceptions.py new file mode 100644 index 00000000..4f1320e7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/exceptions.py @@ -0,0 +1,11 @@ +from _pytest.compat import final + + +@final +class UsageError(Exception): + """Error in pytest usage or invocation.""" + + +class PrintHelp(Exception): + """Raised when pytest should print its help to skip the rest of the + argument parsing and validation.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/config/findpaths.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/findpaths.py new file mode 100644 index 00000000..02674ffa --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/config/findpaths.py @@ -0,0 +1,218 @@ +import os +import sys +from pathlib import Path +from typing import Dict +from typing import Iterable +from typing import List +from typing import Optional +from typing import Sequence +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +import iniconfig + +from .exceptions import UsageError +from _pytest.outcomes import fail +from _pytest.pathlib import absolutepath +from _pytest.pathlib import commonpath +from _pytest.pathlib import safe_exists + +if TYPE_CHECKING: + from . import Config + + +def _parse_ini_config(path: Path) -> iniconfig.IniConfig: + """Parse the given generic '.ini' file using legacy IniConfig parser, returning + the parsed object. + + Raise UsageError if the file cannot be parsed. + """ + try: + return iniconfig.IniConfig(str(path)) + except iniconfig.ParseError as exc: + raise UsageError(str(exc)) from exc + + +def load_config_dict_from_file( + filepath: Path, +) -> Optional[Dict[str, Union[str, List[str]]]]: + """Load pytest configuration from the given file path, if supported. + + Return None if the file does not contain valid pytest configuration. + """ + + # Configuration from ini files are obtained from the [pytest] section, if present. + if filepath.suffix == ".ini": + iniconfig = _parse_ini_config(filepath) + + if "pytest" in iniconfig: + return dict(iniconfig["pytest"].items()) + else: + # "pytest.ini" files are always the source of configuration, even if empty. + if filepath.name == "pytest.ini": + return {} + + # '.cfg' files are considered if they contain a "[tool:pytest]" section. + elif filepath.suffix == ".cfg": + iniconfig = _parse_ini_config(filepath) + + if "tool:pytest" in iniconfig.sections: + return dict(iniconfig["tool:pytest"].items()) + elif "pytest" in iniconfig.sections: + # If a setup.cfg contains a "[pytest]" section, we raise a failure to indicate users that + # plain "[pytest]" sections in setup.cfg files is no longer supported (#3086). + fail(CFG_PYTEST_SECTION.format(filename="setup.cfg"), pytrace=False) + + # '.toml' files are considered if they contain a [tool.pytest.ini_options] table. + elif filepath.suffix == ".toml": + if sys.version_info >= (3, 11): + import tomllib + else: + import tomli as tomllib + + toml_text = filepath.read_text(encoding="utf-8") + try: + config = tomllib.loads(toml_text) + except tomllib.TOMLDecodeError as exc: + raise UsageError(f"{filepath}: {exc}") from exc + + result = config.get("tool", {}).get("pytest", {}).get("ini_options", None) + if result is not None: + # TOML supports richer data types than ini files (strings, arrays, floats, ints, etc), + # however we need to convert all scalar values to str for compatibility with the rest + # of the configuration system, which expects strings only. + def make_scalar(v: object) -> Union[str, List[str]]: + return v if isinstance(v, list) else str(v) + + return {k: make_scalar(v) for k, v in result.items()} + + return None + + +def locate_config( + args: Iterable[Path], +) -> Tuple[Optional[Path], Optional[Path], Dict[str, Union[str, List[str]]]]: + """Search in the list of arguments for a valid ini-file for pytest, + and return a tuple of (rootdir, inifile, cfg-dict).""" + config_names = [ + "pytest.ini", + ".pytest.ini", + "pyproject.toml", + "tox.ini", + "setup.cfg", + ] + args = [x for x in args if not str(x).startswith("-")] + if not args: + args = [Path.cwd()] + for arg in args: + argpath = absolutepath(arg) + for base in (argpath, *argpath.parents): + for config_name in config_names: + p = base / config_name + if p.is_file(): + ini_config = load_config_dict_from_file(p) + if ini_config is not None: + return base, p, ini_config + return None, None, {} + + +def get_common_ancestor(paths: Iterable[Path]) -> Path: + common_ancestor: Optional[Path] = None + for path in paths: + if not path.exists(): + continue + if common_ancestor is None: + common_ancestor = path + else: + if common_ancestor in path.parents or path == common_ancestor: + continue + elif path in common_ancestor.parents: + common_ancestor = path + else: + shared = commonpath(path, common_ancestor) + if shared is not None: + common_ancestor = shared + if common_ancestor is None: + common_ancestor = Path.cwd() + elif common_ancestor.is_file(): + common_ancestor = common_ancestor.parent + return common_ancestor + + +def get_dirs_from_args(args: Iterable[str]) -> List[Path]: + def is_option(x: str) -> bool: + return x.startswith("-") + + def get_file_part_from_node_id(x: str) -> str: + return x.split("::")[0] + + def get_dir_from_path(path: Path) -> Path: + if path.is_dir(): + return path + return path.parent + + # These look like paths but may not exist + possible_paths = ( + absolutepath(get_file_part_from_node_id(arg)) + for arg in args + if not is_option(arg) + ) + + return [get_dir_from_path(path) for path in possible_paths if safe_exists(path)] + + +CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead." + + +def determine_setup( + inifile: Optional[str], + args: Sequence[str], + rootdir_cmd_arg: Optional[str] = None, + config: Optional["Config"] = None, +) -> Tuple[Path, Optional[Path], Dict[str, Union[str, List[str]]]]: + rootdir = None + dirs = get_dirs_from_args(args) + if inifile: + inipath_ = absolutepath(inifile) + inipath: Optional[Path] = inipath_ + inicfg = load_config_dict_from_file(inipath_) or {} + if rootdir_cmd_arg is None: + rootdir = inipath_.parent + else: + ancestor = get_common_ancestor(dirs) + rootdir, inipath, inicfg = locate_config([ancestor]) + if rootdir is None and rootdir_cmd_arg is None: + for possible_rootdir in (ancestor, *ancestor.parents): + if (possible_rootdir / "setup.py").is_file(): + rootdir = possible_rootdir + break + else: + if dirs != [ancestor]: + rootdir, inipath, inicfg = locate_config(dirs) + if rootdir is None: + if config is not None: + cwd = config.invocation_params.dir + else: + cwd = Path.cwd() + rootdir = get_common_ancestor([cwd, ancestor]) + if is_fs_root(rootdir): + rootdir = ancestor + if rootdir_cmd_arg: + rootdir = absolutepath(os.path.expandvars(rootdir_cmd_arg)) + if not rootdir.is_dir(): + raise UsageError( + "Directory '{}' not found. Check your '--rootdir' option.".format( + rootdir + ) + ) + assert rootdir is not None + return rootdir, inipath, inicfg or {} + + +def is_fs_root(p: Path) -> bool: + r""" + Return True if the given path is pointing to the root of the + file system ("/" on Unix and "C:\\" on Windows for example). + """ + return os.path.splitdrive(str(p))[1] == os.sep diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/debugging.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/debugging.py new file mode 100644 index 00000000..a3f80802 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/debugging.py @@ -0,0 +1,391 @@ +"""Interactive debugging with PDB, the Python Debugger.""" +import argparse +import functools +import sys +import types +import unittest +from typing import Any +from typing import Callable +from typing import Generator +from typing import List +from typing import Optional +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +from _pytest import outcomes +from _pytest._code import ExceptionInfo +from _pytest.config import Config +from _pytest.config import ConftestImportFailure +from _pytest.config import hookimpl +from _pytest.config import PytestPluginManager +from _pytest.config.argparsing import Parser +from _pytest.config.exceptions import UsageError +from _pytest.nodes import Node +from _pytest.reports import BaseReport + +if TYPE_CHECKING: + from _pytest.capture import CaptureManager + from _pytest.runner import CallInfo + + +def _validate_usepdb_cls(value: str) -> Tuple[str, str]: + """Validate syntax of --pdbcls option.""" + try: + modname, classname = value.split(":") + except ValueError as e: + raise argparse.ArgumentTypeError( + f"{value!r} is not in the format 'modname:classname'" + ) from e + return (modname, classname) + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group._addoption( + "--pdb", + dest="usepdb", + action="store_true", + help="Start the interactive Python debugger on errors or KeyboardInterrupt", + ) + group._addoption( + "--pdbcls", + dest="usepdb_cls", + metavar="modulename:classname", + type=_validate_usepdb_cls, + help="Specify a custom interactive Python debugger for use with --pdb." + "For example: --pdbcls=IPython.terminal.debugger:TerminalPdb", + ) + group._addoption( + "--trace", + dest="trace", + action="store_true", + help="Immediately break when running each test", + ) + + +def pytest_configure(config: Config) -> None: + import pdb + + if config.getvalue("trace"): + config.pluginmanager.register(PdbTrace(), "pdbtrace") + if config.getvalue("usepdb"): + config.pluginmanager.register(PdbInvoke(), "pdbinvoke") + + pytestPDB._saved.append( + (pdb.set_trace, pytestPDB._pluginmanager, pytestPDB._config) + ) + pdb.set_trace = pytestPDB.set_trace + pytestPDB._pluginmanager = config.pluginmanager + pytestPDB._config = config + + # NOTE: not using pytest_unconfigure, since it might get called although + # pytest_configure was not (if another plugin raises UsageError). + def fin() -> None: + ( + pdb.set_trace, + pytestPDB._pluginmanager, + pytestPDB._config, + ) = pytestPDB._saved.pop() + + config.add_cleanup(fin) + + +class pytestPDB: + """Pseudo PDB that defers to the real pdb.""" + + _pluginmanager: Optional[PytestPluginManager] = None + _config: Optional[Config] = None + _saved: List[ + Tuple[Callable[..., None], Optional[PytestPluginManager], Optional[Config]] + ] = [] + _recursive_debug = 0 + _wrapped_pdb_cls: Optional[Tuple[Type[Any], Type[Any]]] = None + + @classmethod + def _is_capturing(cls, capman: Optional["CaptureManager"]) -> Union[str, bool]: + if capman: + return capman.is_capturing() + return False + + @classmethod + def _import_pdb_cls(cls, capman: Optional["CaptureManager"]): + if not cls._config: + import pdb + + # Happens when using pytest.set_trace outside of a test. + return pdb.Pdb + + usepdb_cls = cls._config.getvalue("usepdb_cls") + + if cls._wrapped_pdb_cls and cls._wrapped_pdb_cls[0] == usepdb_cls: + return cls._wrapped_pdb_cls[1] + + if usepdb_cls: + modname, classname = usepdb_cls + + try: + __import__(modname) + mod = sys.modules[modname] + + # Handle --pdbcls=pdb:pdb.Pdb (useful e.g. with pdbpp). + parts = classname.split(".") + pdb_cls = getattr(mod, parts[0]) + for part in parts[1:]: + pdb_cls = getattr(pdb_cls, part) + except Exception as exc: + value = ":".join((modname, classname)) + raise UsageError( + f"--pdbcls: could not import {value!r}: {exc}" + ) from exc + else: + import pdb + + pdb_cls = pdb.Pdb + + wrapped_cls = cls._get_pdb_wrapper_class(pdb_cls, capman) + cls._wrapped_pdb_cls = (usepdb_cls, wrapped_cls) + return wrapped_cls + + @classmethod + def _get_pdb_wrapper_class(cls, pdb_cls, capman: Optional["CaptureManager"]): + import _pytest.config + + # Type ignored because mypy doesn't support "dynamic" + # inheritance like this. + class PytestPdbWrapper(pdb_cls): # type: ignore[valid-type,misc] + _pytest_capman = capman + _continued = False + + def do_debug(self, arg): + cls._recursive_debug += 1 + ret = super().do_debug(arg) + cls._recursive_debug -= 1 + return ret + + def do_continue(self, arg): + ret = super().do_continue(arg) + if cls._recursive_debug == 0: + assert cls._config is not None + tw = _pytest.config.create_terminal_writer(cls._config) + tw.line() + + capman = self._pytest_capman + capturing = pytestPDB._is_capturing(capman) + if capturing: + if capturing == "global": + tw.sep(">", "PDB continue (IO-capturing resumed)") + else: + tw.sep( + ">", + "PDB continue (IO-capturing resumed for %s)" + % capturing, + ) + assert capman is not None + capman.resume() + else: + tw.sep(">", "PDB continue") + assert cls._pluginmanager is not None + cls._pluginmanager.hook.pytest_leave_pdb(config=cls._config, pdb=self) + self._continued = True + return ret + + do_c = do_cont = do_continue + + def do_quit(self, arg): + """Raise Exit outcome when quit command is used in pdb. + + This is a bit of a hack - it would be better if BdbQuit + could be handled, but this would require to wrap the + whole pytest run, and adjust the report etc. + """ + ret = super().do_quit(arg) + + if cls._recursive_debug == 0: + outcomes.exit("Quitting debugger") + + return ret + + do_q = do_quit + do_exit = do_quit + + def setup(self, f, tb): + """Suspend on setup(). + + Needed after do_continue resumed, and entering another + breakpoint again. + """ + ret = super().setup(f, tb) + if not ret and self._continued: + # pdb.setup() returns True if the command wants to exit + # from the interaction: do not suspend capturing then. + if self._pytest_capman: + self._pytest_capman.suspend_global_capture(in_=True) + return ret + + def get_stack(self, f, t): + stack, i = super().get_stack(f, t) + if f is None: + # Find last non-hidden frame. + i = max(0, len(stack) - 1) + while i and stack[i][0].f_locals.get("__tracebackhide__", False): + i -= 1 + return stack, i + + return PytestPdbWrapper + + @classmethod + def _init_pdb(cls, method, *args, **kwargs): + """Initialize PDB debugging, dropping any IO capturing.""" + import _pytest.config + + if cls._pluginmanager is None: + capman: Optional[CaptureManager] = None + else: + capman = cls._pluginmanager.getplugin("capturemanager") + if capman: + capman.suspend(in_=True) + + if cls._config: + tw = _pytest.config.create_terminal_writer(cls._config) + tw.line() + + if cls._recursive_debug == 0: + # Handle header similar to pdb.set_trace in py37+. + header = kwargs.pop("header", None) + if header is not None: + tw.sep(">", header) + else: + capturing = cls._is_capturing(capman) + if capturing == "global": + tw.sep(">", f"PDB {method} (IO-capturing turned off)") + elif capturing: + tw.sep( + ">", + "PDB %s (IO-capturing turned off for %s)" + % (method, capturing), + ) + else: + tw.sep(">", f"PDB {method}") + + _pdb = cls._import_pdb_cls(capman)(**kwargs) + + if cls._pluginmanager: + cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb) + return _pdb + + @classmethod + def set_trace(cls, *args, **kwargs) -> None: + """Invoke debugging via ``Pdb.set_trace``, dropping any IO capturing.""" + frame = sys._getframe().f_back + _pdb = cls._init_pdb("set_trace", *args, **kwargs) + _pdb.set_trace(frame) + + +class PdbInvoke: + def pytest_exception_interact( + self, node: Node, call: "CallInfo[Any]", report: BaseReport + ) -> None: + capman = node.config.pluginmanager.getplugin("capturemanager") + if capman: + capman.suspend_global_capture(in_=True) + out, err = capman.read_global_capture() + sys.stdout.write(out) + sys.stdout.write(err) + assert call.excinfo is not None + + if not isinstance(call.excinfo.value, unittest.SkipTest): + _enter_pdb(node, call.excinfo, report) + + def pytest_internalerror(self, excinfo: ExceptionInfo[BaseException]) -> None: + tb = _postmortem_traceback(excinfo) + post_mortem(tb) + + +class PdbTrace: + @hookimpl(hookwrapper=True) + def pytest_pyfunc_call(self, pyfuncitem) -> Generator[None, None, None]: + wrap_pytest_function_for_tracing(pyfuncitem) + yield + + +def wrap_pytest_function_for_tracing(pyfuncitem): + """Change the Python function object of the given Function item by a + wrapper which actually enters pdb before calling the python function + itself, effectively leaving the user in the pdb prompt in the first + statement of the function.""" + _pdb = pytestPDB._init_pdb("runcall") + testfunction = pyfuncitem.obj + + # we can't just return `partial(pdb.runcall, testfunction)` because (on + # python < 3.7.4) runcall's first param is `func`, which means we'd get + # an exception if one of the kwargs to testfunction was called `func`. + @functools.wraps(testfunction) + def wrapper(*args, **kwargs): + func = functools.partial(testfunction, *args, **kwargs) + _pdb.runcall(func) + + pyfuncitem.obj = wrapper + + +def maybe_wrap_pytest_function_for_tracing(pyfuncitem): + """Wrap the given pytestfunct item for tracing support if --trace was given in + the command line.""" + if pyfuncitem.config.getvalue("trace"): + wrap_pytest_function_for_tracing(pyfuncitem) + + +def _enter_pdb( + node: Node, excinfo: ExceptionInfo[BaseException], rep: BaseReport +) -> BaseReport: + # XXX we re-use the TerminalReporter's terminalwriter + # because this seems to avoid some encoding related troubles + # for not completely clear reasons. + tw = node.config.pluginmanager.getplugin("terminalreporter")._tw + tw.line() + + showcapture = node.config.option.showcapture + + for sectionname, content in ( + ("stdout", rep.capstdout), + ("stderr", rep.capstderr), + ("log", rep.caplog), + ): + if showcapture in (sectionname, "all") and content: + tw.sep(">", "captured " + sectionname) + if content[-1:] == "\n": + content = content[:-1] + tw.line(content) + + tw.sep(">", "traceback") + rep.toterminal(tw) + tw.sep(">", "entering PDB") + tb = _postmortem_traceback(excinfo) + rep._pdbshown = True # type: ignore[attr-defined] + post_mortem(tb) + return rep + + +def _postmortem_traceback(excinfo: ExceptionInfo[BaseException]) -> types.TracebackType: + from doctest import UnexpectedException + + if isinstance(excinfo.value, UnexpectedException): + # A doctest.UnexpectedException is not useful for post_mortem. + # Use the underlying exception instead: + return excinfo.value.exc_info[2] + elif isinstance(excinfo.value, ConftestImportFailure): + # A config.ConftestImportFailure is not useful for post_mortem. + # Use the underlying exception instead: + return excinfo.value.excinfo[2] + else: + assert excinfo._excinfo is not None + return excinfo._excinfo[2] + + +def post_mortem(t: types.TracebackType) -> None: + p = pytestPDB._init_pdb("post_mortem") + p.reset() + p.interaction(None, t) + if p.quitting: + outcomes.exit("Quitting debugger") diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/deprecated.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/deprecated.py new file mode 100644 index 00000000..b9c10df7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/deprecated.py @@ -0,0 +1,146 @@ +"""Deprecation messages and bits of code used elsewhere in the codebase that +is planned to be removed in the next pytest release. + +Keeping it in a central location makes it easy to track what is deprecated and should +be removed when the time comes. + +All constants defined in this module should be either instances of +:class:`PytestWarning`, or :class:`UnformattedWarning` +in case of warnings which need to format their messages. +""" +from warnings import warn + +from _pytest.warning_types import PytestDeprecationWarning +from _pytest.warning_types import PytestRemovedIn8Warning +from _pytest.warning_types import UnformattedWarning + +# set of plugins which have been integrated into the core; we use this list to ignore +# them during registration to avoid conflicts +DEPRECATED_EXTERNAL_PLUGINS = { + "pytest_catchlog", + "pytest_capturelog", + "pytest_faulthandler", +} + +NOSE_SUPPORT = UnformattedWarning( + PytestRemovedIn8Warning, + "Support for nose tests is deprecated and will be removed in a future release.\n" + "{nodeid} is using nose method: `{method}` ({stage})\n" + "See docs: https://docs.pytest.org/en/stable/deprecations.html#support-for-tests-written-for-nose", +) + +NOSE_SUPPORT_METHOD = UnformattedWarning( + PytestRemovedIn8Warning, + "Support for nose tests is deprecated and will be removed in a future release.\n" + "{nodeid} is using nose-specific method: `{method}(self)`\n" + "To remove this warning, rename it to `{method}_method(self)`\n" + "See docs: https://docs.pytest.org/en/stable/deprecations.html#support-for-tests-written-for-nose", +) + + +# This can be* removed pytest 8, but it's harmless and common, so no rush to remove. +# * If you're in the future: "could have been". +YIELD_FIXTURE = PytestDeprecationWarning( + "@pytest.yield_fixture is deprecated.\n" + "Use @pytest.fixture instead; they are the same." +) + +WARNING_CMDLINE_PREPARSE_HOOK = PytestRemovedIn8Warning( + "The pytest_cmdline_preparse hook is deprecated and will be removed in a future release. \n" + "Please use pytest_load_initial_conftests hook instead." +) + +FSCOLLECTOR_GETHOOKPROXY_ISINITPATH = PytestRemovedIn8Warning( + "The gethookproxy() and isinitpath() methods of FSCollector and Package are deprecated; " + "use self.session.gethookproxy() and self.session.isinitpath() instead. " +) + +STRICT_OPTION = PytestRemovedIn8Warning( + "The --strict option is deprecated, use --strict-markers instead." +) + +# This deprecation is never really meant to be removed. +PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.") + +ARGUMENT_PERCENT_DEFAULT = PytestRemovedIn8Warning( + 'pytest now uses argparse. "%default" should be changed to "%(default)s"', +) + +ARGUMENT_TYPE_STR_CHOICE = UnformattedWarning( + PytestRemovedIn8Warning, + "`type` argument to addoption() is the string {typ!r}." + " For choices this is optional and can be omitted, " + " but when supplied should be a type (for example `str` or `int`)." + " (options: {names})", +) + +ARGUMENT_TYPE_STR = UnformattedWarning( + PytestRemovedIn8Warning, + "`type` argument to addoption() is the string {typ!r}, " + " but when supplied should be a type (for example `str` or `int`)." + " (options: {names})", +) + + +HOOK_LEGACY_PATH_ARG = UnformattedWarning( + PytestRemovedIn8Warning, + "The ({pylib_path_arg}: py.path.local) argument is deprecated, please use ({pathlib_path_arg}: pathlib.Path)\n" + "see https://docs.pytest.org/en/latest/deprecations.html" + "#py-path-local-arguments-for-hooks-replaced-with-pathlib-path", +) + +NODE_CTOR_FSPATH_ARG = UnformattedWarning( + PytestRemovedIn8Warning, + "The (fspath: py.path.local) argument to {node_type_name} is deprecated. " + "Please use the (path: pathlib.Path) argument instead.\n" + "See https://docs.pytest.org/en/latest/deprecations.html" + "#fspath-argument-for-node-constructors-replaced-with-pathlib-path", +) + +WARNS_NONE_ARG = PytestRemovedIn8Warning( + "Passing None has been deprecated.\n" + "See https://docs.pytest.org/en/latest/how-to/capture-warnings.html" + "#additional-use-cases-of-warnings-in-tests" + " for alternatives in common use cases." +) + +KEYWORD_MSG_ARG = UnformattedWarning( + PytestRemovedIn8Warning, + "pytest.{func}(msg=...) is now deprecated, use pytest.{func}(reason=...) instead", +) + +INSTANCE_COLLECTOR = PytestRemovedIn8Warning( + "The pytest.Instance collector type is deprecated and is no longer used. " + "See https://docs.pytest.org/en/latest/deprecations.html#the-pytest-instance-collector", +) +HOOK_LEGACY_MARKING = UnformattedWarning( + PytestDeprecationWarning, + "The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n" + "Please use the pytest.hook{type}({hook_opts}) decorator instead\n" + " to configure the hooks.\n" + " See https://docs.pytest.org/en/latest/deprecations.html" + "#configuring-hook-specs-impls-using-markers", +) + +# You want to make some `__init__` or function "private". +# +# def my_private_function(some, args): +# ... +# +# Do this: +# +# def my_private_function(some, args, *, _ispytest: bool = False): +# check_ispytest(_ispytest) +# ... +# +# Change all internal/allowed calls to +# +# my_private_function(some, args, _ispytest=True) +# +# All other calls will get the default _ispytest=False and trigger +# the warning (possibly error in the future). + + +def check_ispytest(ispytest: bool) -> None: + if not ispytest: + warn(PRIVATE, stacklevel=3) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/doctest.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/doctest.py new file mode 100644 index 00000000..ca41a98e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/doctest.py @@ -0,0 +1,771 @@ +"""Discover and run doctests in modules and test files.""" +import bdb +import functools +import inspect +import os +import platform +import sys +import traceback +import types +import warnings +from contextlib import contextmanager +from pathlib import Path +from typing import Any +from typing import Callable +from typing import Dict +from typing import Generator +from typing import Iterable +from typing import List +from typing import Optional +from typing import Pattern +from typing import Sequence +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +from _pytest import outcomes +from _pytest._code.code import ExceptionInfo +from _pytest._code.code import ReprFileLocation +from _pytest._code.code import TerminalRepr +from _pytest._io import TerminalWriter +from _pytest.compat import safe_getattr +from _pytest.config import Config +from _pytest.config.argparsing import Parser +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.outcomes import OutcomeException +from _pytest.outcomes import skip +from _pytest.pathlib import fnmatch_ex +from _pytest.pathlib import import_path +from _pytest.python import Module +from _pytest.python_api import approx +from _pytest.warning_types import PytestWarning + +if TYPE_CHECKING: + import doctest + +DOCTEST_REPORT_CHOICE_NONE = "none" +DOCTEST_REPORT_CHOICE_CDIFF = "cdiff" +DOCTEST_REPORT_CHOICE_NDIFF = "ndiff" +DOCTEST_REPORT_CHOICE_UDIFF = "udiff" +DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE = "only_first_failure" + +DOCTEST_REPORT_CHOICES = ( + DOCTEST_REPORT_CHOICE_NONE, + DOCTEST_REPORT_CHOICE_CDIFF, + DOCTEST_REPORT_CHOICE_NDIFF, + DOCTEST_REPORT_CHOICE_UDIFF, + DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE, +) + +# Lazy definition of runner class +RUNNER_CLASS = None +# Lazy definition of output checker class +CHECKER_CLASS: Optional[Type["doctest.OutputChecker"]] = None + + +def pytest_addoption(parser: Parser) -> None: + parser.addini( + "doctest_optionflags", + "Option flags for doctests", + type="args", + default=["ELLIPSIS"], + ) + parser.addini( + "doctest_encoding", "Encoding used for doctest files", default="utf-8" + ) + group = parser.getgroup("collect") + group.addoption( + "--doctest-modules", + action="store_true", + default=False, + help="Run doctests in all .py modules", + dest="doctestmodules", + ) + group.addoption( + "--doctest-report", + type=str.lower, + default="udiff", + help="Choose another output format for diffs on doctest failure", + choices=DOCTEST_REPORT_CHOICES, + dest="doctestreport", + ) + group.addoption( + "--doctest-glob", + action="append", + default=[], + metavar="pat", + help="Doctests file matching pattern, default: test*.txt", + dest="doctestglob", + ) + group.addoption( + "--doctest-ignore-import-errors", + action="store_true", + default=False, + help="Ignore doctest ImportErrors", + dest="doctest_ignore_import_errors", + ) + group.addoption( + "--doctest-continue-on-failure", + action="store_true", + default=False, + help="For a given doctest, continue to run after the first failure", + dest="doctest_continue_on_failure", + ) + + +def pytest_unconfigure() -> None: + global RUNNER_CLASS + + RUNNER_CLASS = None + + +def pytest_collect_file( + file_path: Path, + parent: Collector, +) -> Optional[Union["DoctestModule", "DoctestTextfile"]]: + config = parent.config + if file_path.suffix == ".py": + if config.option.doctestmodules and not any( + (_is_setup_py(file_path), _is_main_py(file_path)) + ): + mod: DoctestModule = DoctestModule.from_parent(parent, path=file_path) + return mod + elif _is_doctest(config, file_path, parent): + txt: DoctestTextfile = DoctestTextfile.from_parent(parent, path=file_path) + return txt + return None + + +def _is_setup_py(path: Path) -> bool: + if path.name != "setup.py": + return False + contents = path.read_bytes() + return b"setuptools" in contents or b"distutils" in contents + + +def _is_doctest(config: Config, path: Path, parent: Collector) -> bool: + if path.suffix in (".txt", ".rst") and parent.session.isinitpath(path): + return True + globs = config.getoption("doctestglob") or ["test*.txt"] + return any(fnmatch_ex(glob, path) for glob in globs) + + +def _is_main_py(path: Path) -> bool: + return path.name == "__main__.py" + + +class ReprFailDoctest(TerminalRepr): + def __init__( + self, reprlocation_lines: Sequence[Tuple[ReprFileLocation, Sequence[str]]] + ) -> None: + self.reprlocation_lines = reprlocation_lines + + def toterminal(self, tw: TerminalWriter) -> None: + for reprlocation, lines in self.reprlocation_lines: + for line in lines: + tw.line(line) + reprlocation.toterminal(tw) + + +class MultipleDoctestFailures(Exception): + def __init__(self, failures: Sequence["doctest.DocTestFailure"]) -> None: + super().__init__() + self.failures = failures + + +def _init_runner_class() -> Type["doctest.DocTestRunner"]: + import doctest + + class PytestDoctestRunner(doctest.DebugRunner): + """Runner to collect failures. + + Note that the out variable in this case is a list instead of a + stdout-like object. + """ + + def __init__( + self, + checker: Optional["doctest.OutputChecker"] = None, + verbose: Optional[bool] = None, + optionflags: int = 0, + continue_on_failure: bool = True, + ) -> None: + super().__init__(checker=checker, verbose=verbose, optionflags=optionflags) + self.continue_on_failure = continue_on_failure + + def report_failure( + self, + out, + test: "doctest.DocTest", + example: "doctest.Example", + got: str, + ) -> None: + failure = doctest.DocTestFailure(test, example, got) + if self.continue_on_failure: + out.append(failure) + else: + raise failure + + def report_unexpected_exception( + self, + out, + test: "doctest.DocTest", + example: "doctest.Example", + exc_info: Tuple[Type[BaseException], BaseException, types.TracebackType], + ) -> None: + if isinstance(exc_info[1], OutcomeException): + raise exc_info[1] + if isinstance(exc_info[1], bdb.BdbQuit): + outcomes.exit("Quitting debugger") + failure = doctest.UnexpectedException(test, example, exc_info) + if self.continue_on_failure: + out.append(failure) + else: + raise failure + + return PytestDoctestRunner + + +def _get_runner( + checker: Optional["doctest.OutputChecker"] = None, + verbose: Optional[bool] = None, + optionflags: int = 0, + continue_on_failure: bool = True, +) -> "doctest.DocTestRunner": + # We need this in order to do a lazy import on doctest + global RUNNER_CLASS + if RUNNER_CLASS is None: + RUNNER_CLASS = _init_runner_class() + # Type ignored because the continue_on_failure argument is only defined on + # PytestDoctestRunner, which is lazily defined so can't be used as a type. + return RUNNER_CLASS( # type: ignore + checker=checker, + verbose=verbose, + optionflags=optionflags, + continue_on_failure=continue_on_failure, + ) + + +class DoctestItem(Item): + def __init__( + self, + name: str, + parent: "Union[DoctestTextfile, DoctestModule]", + runner: Optional["doctest.DocTestRunner"] = None, + dtest: Optional["doctest.DocTest"] = None, + ) -> None: + super().__init__(name, parent) + self.runner = runner + self.dtest = dtest + self.obj = None + self.fixture_request: Optional[FixtureRequest] = None + + @classmethod + def from_parent( # type: ignore + cls, + parent: "Union[DoctestTextfile, DoctestModule]", + *, + name: str, + runner: "doctest.DocTestRunner", + dtest: "doctest.DocTest", + ): + # incompatible signature due to imposed limits on subclass + """The public named constructor.""" + return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest) + + def setup(self) -> None: + if self.dtest is not None: + self.fixture_request = _setup_fixtures(self) + globs = dict(getfixture=self.fixture_request.getfixturevalue) + for name, value in self.fixture_request.getfixturevalue( + "doctest_namespace" + ).items(): + globs[name] = value + self.dtest.globs.update(globs) + + def runtest(self) -> None: + assert self.dtest is not None + assert self.runner is not None + _check_all_skipped(self.dtest) + self._disable_output_capturing_for_darwin() + failures: List["doctest.DocTestFailure"] = [] + # Type ignored because we change the type of `out` from what + # doctest expects. + self.runner.run(self.dtest, out=failures) # type: ignore[arg-type] + if failures: + raise MultipleDoctestFailures(failures) + + def _disable_output_capturing_for_darwin(self) -> None: + """Disable output capturing. Otherwise, stdout is lost to doctest (#985).""" + if platform.system() != "Darwin": + return + capman = self.config.pluginmanager.getplugin("capturemanager") + if capman: + capman.suspend_global_capture(in_=True) + out, err = capman.read_global_capture() + sys.stdout.write(out) + sys.stderr.write(err) + + # TODO: Type ignored -- breaks Liskov Substitution. + def repr_failure( # type: ignore[override] + self, + excinfo: ExceptionInfo[BaseException], + ) -> Union[str, TerminalRepr]: + import doctest + + failures: Optional[ + Sequence[Union[doctest.DocTestFailure, doctest.UnexpectedException]] + ] = None + if isinstance( + excinfo.value, (doctest.DocTestFailure, doctest.UnexpectedException) + ): + failures = [excinfo.value] + elif isinstance(excinfo.value, MultipleDoctestFailures): + failures = excinfo.value.failures + + if failures is None: + return super().repr_failure(excinfo) + + reprlocation_lines = [] + for failure in failures: + example = failure.example + test = failure.test + filename = test.filename + if test.lineno is None: + lineno = None + else: + lineno = test.lineno + example.lineno + 1 + message = type(failure).__name__ + # TODO: ReprFileLocation doesn't expect a None lineno. + reprlocation = ReprFileLocation(filename, lineno, message) # type: ignore[arg-type] + checker = _get_checker() + report_choice = _get_report_choice(self.config.getoption("doctestreport")) + if lineno is not None: + assert failure.test.docstring is not None + lines = failure.test.docstring.splitlines(False) + # add line numbers to the left of the error message + assert test.lineno is not None + lines = [ + "%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines) + ] + # trim docstring error lines to 10 + lines = lines[max(example.lineno - 9, 0) : example.lineno + 1] + else: + lines = [ + "EXAMPLE LOCATION UNKNOWN, not showing all tests of that example" + ] + indent = ">>>" + for line in example.source.splitlines(): + lines.append(f"??? {indent} {line}") + indent = "..." + if isinstance(failure, doctest.DocTestFailure): + lines += checker.output_difference( + example, failure.got, report_choice + ).split("\n") + else: + inner_excinfo = ExceptionInfo.from_exc_info(failure.exc_info) + lines += ["UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value)] + lines += [ + x.strip("\n") for x in traceback.format_exception(*failure.exc_info) + ] + reprlocation_lines.append((reprlocation, lines)) + return ReprFailDoctest(reprlocation_lines) + + def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]: + assert self.dtest is not None + return self.path, self.dtest.lineno, "[doctest] %s" % self.name + + +def _get_flag_lookup() -> Dict[str, int]: + import doctest + + return dict( + DONT_ACCEPT_TRUE_FOR_1=doctest.DONT_ACCEPT_TRUE_FOR_1, + DONT_ACCEPT_BLANKLINE=doctest.DONT_ACCEPT_BLANKLINE, + NORMALIZE_WHITESPACE=doctest.NORMALIZE_WHITESPACE, + ELLIPSIS=doctest.ELLIPSIS, + IGNORE_EXCEPTION_DETAIL=doctest.IGNORE_EXCEPTION_DETAIL, + COMPARISON_FLAGS=doctest.COMPARISON_FLAGS, + ALLOW_UNICODE=_get_allow_unicode_flag(), + ALLOW_BYTES=_get_allow_bytes_flag(), + NUMBER=_get_number_flag(), + ) + + +def get_optionflags(parent): + optionflags_str = parent.config.getini("doctest_optionflags") + flag_lookup_table = _get_flag_lookup() + flag_acc = 0 + for flag in optionflags_str: + flag_acc |= flag_lookup_table[flag] + return flag_acc + + +def _get_continue_on_failure(config): + continue_on_failure = config.getvalue("doctest_continue_on_failure") + if continue_on_failure: + # We need to turn off this if we use pdb since we should stop at + # the first failure. + if config.getvalue("usepdb"): + continue_on_failure = False + return continue_on_failure + + +class DoctestTextfile(Module): + obj = None + + def collect(self) -> Iterable[DoctestItem]: + import doctest + + # Inspired by doctest.testfile; ideally we would use it directly, + # but it doesn't support passing a custom checker. + encoding = self.config.getini("doctest_encoding") + text = self.path.read_text(encoding) + filename = str(self.path) + name = self.path.name + globs = {"__name__": "__main__"} + + optionflags = get_optionflags(self) + + runner = _get_runner( + verbose=False, + optionflags=optionflags, + checker=_get_checker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + + parser = doctest.DocTestParser() + test = parser.get_doctest(text, globs, name, filename, 0) + if test.examples: + yield DoctestItem.from_parent( + self, name=test.name, runner=runner, dtest=test + ) + + +def _check_all_skipped(test: "doctest.DocTest") -> None: + """Raise pytest.skip() if all examples in the given DocTest have the SKIP + option set.""" + import doctest + + all_skipped = all(x.options.get(doctest.SKIP, False) for x in test.examples) + if all_skipped: + skip("all tests skipped by +SKIP option") + + +def _is_mocked(obj: object) -> bool: + """Return if an object is possibly a mock object by checking the + existence of a highly improbable attribute.""" + return ( + safe_getattr(obj, "pytest_mock_example_attribute_that_shouldnt_exist", None) + is not None + ) + + +@contextmanager +def _patch_unwrap_mock_aware() -> Generator[None, None, None]: + """Context manager which replaces ``inspect.unwrap`` with a version + that's aware of mock objects and doesn't recurse into them.""" + real_unwrap = inspect.unwrap + + def _mock_aware_unwrap( + func: Callable[..., Any], *, stop: Optional[Callable[[Any], Any]] = None + ) -> Any: + try: + if stop is None or stop is _is_mocked: + return real_unwrap(func, stop=_is_mocked) + _stop = stop + return real_unwrap(func, stop=lambda obj: _is_mocked(obj) or _stop(func)) + except Exception as e: + warnings.warn( + "Got %r when unwrapping %r. This is usually caused " + "by a violation of Python's object protocol; see e.g. " + "https://github.com/pytest-dev/pytest/issues/5080" % (e, func), + PytestWarning, + ) + raise + + inspect.unwrap = _mock_aware_unwrap + try: + yield + finally: + inspect.unwrap = real_unwrap + + +class DoctestModule(Module): + def collect(self) -> Iterable[DoctestItem]: + import doctest + + class MockAwareDocTestFinder(doctest.DocTestFinder): + """A hackish doctest finder that overrides stdlib internals to fix a stdlib bug. + + https://github.com/pytest-dev/pytest/issues/3456 + https://bugs.python.org/issue25532 + """ + + def _find_lineno(self, obj, source_lines): + """Doctest code does not take into account `@property`, this + is a hackish way to fix it. https://bugs.python.org/issue17446 + + Wrapped Doctests will need to be unwrapped so the correct + line number is returned. This will be reported upstream. #8796 + """ + if isinstance(obj, property): + obj = getattr(obj, "fget", obj) + + if hasattr(obj, "__wrapped__"): + # Get the main obj in case of it being wrapped + obj = inspect.unwrap(obj) + + # Type ignored because this is a private function. + return super()._find_lineno( # type:ignore[misc] + obj, + source_lines, + ) + + def _find( + self, tests, obj, name, module, source_lines, globs, seen + ) -> None: + if _is_mocked(obj): + return + with _patch_unwrap_mock_aware(): + # Type ignored because this is a private function. + super()._find( # type:ignore[misc] + tests, obj, name, module, source_lines, globs, seen + ) + + if sys.version_info < (3, 13): + + def _from_module(self, module, object): + """`cached_property` objects are never considered a part + of the 'current module'. As such they are skipped by doctest. + Here we override `_from_module` to check the underlying + function instead. https://github.com/python/cpython/issues/107995 + """ + if hasattr(functools, "cached_property") and isinstance( + object, functools.cached_property + ): + object = object.func + + # Type ignored because this is a private function. + return super()._from_module(module, object) # type: ignore[misc] + + else: # pragma: no cover + pass + + if self.path.name == "conftest.py": + module = self.config.pluginmanager._importconftest( + self.path, + self.config.getoption("importmode"), + rootpath=self.config.rootpath, + ) + else: + try: + module = import_path( + self.path, + root=self.config.rootpath, + mode=self.config.getoption("importmode"), + ) + except ImportError: + if self.config.getvalue("doctest_ignore_import_errors"): + skip("unable to import module %r" % self.path) + else: + raise + # Uses internal doctest module parsing mechanism. + finder = MockAwareDocTestFinder() + optionflags = get_optionflags(self) + runner = _get_runner( + verbose=False, + optionflags=optionflags, + checker=_get_checker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + + for test in finder.find(module, module.__name__): + if test.examples: # skip empty doctests + yield DoctestItem.from_parent( + self, name=test.name, runner=runner, dtest=test + ) + + +def _setup_fixtures(doctest_item: DoctestItem) -> FixtureRequest: + """Used by DoctestTextfile and DoctestItem to setup fixture information.""" + + def func() -> None: + pass + + doctest_item.funcargs = {} # type: ignore[attr-defined] + fm = doctest_item.session._fixturemanager + doctest_item._fixtureinfo = fm.getfixtureinfo( # type: ignore[attr-defined] + node=doctest_item, func=func, cls=None, funcargs=False + ) + fixture_request = FixtureRequest(doctest_item, _ispytest=True) + fixture_request._fillfixtures() + return fixture_request + + +def _init_checker_class() -> Type["doctest.OutputChecker"]: + import doctest + import re + + class LiteralsOutputChecker(doctest.OutputChecker): + # Based on doctest_nose_plugin.py from the nltk project + # (https://github.com/nltk/nltk) and on the "numtest" doctest extension + # by Sebastien Boisgerault (https://github.com/boisgera/numtest). + + _unicode_literal_re = re.compile(r"(\W|^)[uU]([rR]?[\'\"])", re.UNICODE) + _bytes_literal_re = re.compile(r"(\W|^)[bB]([rR]?[\'\"])", re.UNICODE) + _number_re = re.compile( + r""" + (?P + (?P + (?P [+-]?\d*)\.(?P\d+) + | + (?P [+-]?\d+)\. + ) + (?: + [Ee] + (?P [+-]?\d+) + )? + | + (?P [+-]?\d+) + (?: + [Ee] + (?P [+-]?\d+) + ) + ) + """, + re.VERBOSE, + ) + + def check_output(self, want: str, got: str, optionflags: int) -> bool: + if super().check_output(want, got, optionflags): + return True + + allow_unicode = optionflags & _get_allow_unicode_flag() + allow_bytes = optionflags & _get_allow_bytes_flag() + allow_number = optionflags & _get_number_flag() + + if not allow_unicode and not allow_bytes and not allow_number: + return False + + def remove_prefixes(regex: Pattern[str], txt: str) -> str: + return re.sub(regex, r"\1\2", txt) + + if allow_unicode: + want = remove_prefixes(self._unicode_literal_re, want) + got = remove_prefixes(self._unicode_literal_re, got) + + if allow_bytes: + want = remove_prefixes(self._bytes_literal_re, want) + got = remove_prefixes(self._bytes_literal_re, got) + + if allow_number: + got = self._remove_unwanted_precision(want, got) + + return super().check_output(want, got, optionflags) + + def _remove_unwanted_precision(self, want: str, got: str) -> str: + wants = list(self._number_re.finditer(want)) + gots = list(self._number_re.finditer(got)) + if len(wants) != len(gots): + return got + offset = 0 + for w, g in zip(wants, gots): + fraction: Optional[str] = w.group("fraction") + exponent: Optional[str] = w.group("exponent1") + if exponent is None: + exponent = w.group("exponent2") + precision = 0 if fraction is None else len(fraction) + if exponent is not None: + precision -= int(exponent) + if float(w.group()) == approx(float(g.group()), abs=10**-precision): + # They're close enough. Replace the text we actually + # got with the text we want, so that it will match when we + # check the string literally. + got = ( + got[: g.start() + offset] + w.group() + got[g.end() + offset :] + ) + offset += w.end() - w.start() - (g.end() - g.start()) + return got + + return LiteralsOutputChecker + + +def _get_checker() -> "doctest.OutputChecker": + """Return a doctest.OutputChecker subclass that supports some + additional options: + + * ALLOW_UNICODE and ALLOW_BYTES options to ignore u'' and b'' + prefixes (respectively) in string literals. Useful when the same + doctest should run in Python 2 and Python 3. + + * NUMBER to ignore floating-point differences smaller than the + precision of the literal number in the doctest. + + An inner class is used to avoid importing "doctest" at the module + level. + """ + global CHECKER_CLASS + if CHECKER_CLASS is None: + CHECKER_CLASS = _init_checker_class() + return CHECKER_CLASS() + + +def _get_allow_unicode_flag() -> int: + """Register and return the ALLOW_UNICODE flag.""" + import doctest + + return doctest.register_optionflag("ALLOW_UNICODE") + + +def _get_allow_bytes_flag() -> int: + """Register and return the ALLOW_BYTES flag.""" + import doctest + + return doctest.register_optionflag("ALLOW_BYTES") + + +def _get_number_flag() -> int: + """Register and return the NUMBER flag.""" + import doctest + + return doctest.register_optionflag("NUMBER") + + +def _get_report_choice(key: str) -> int: + """Return the actual `doctest` module flag value. + + We want to do it as late as possible to avoid importing `doctest` and all + its dependencies when parsing options, as it adds overhead and breaks tests. + """ + import doctest + + return { + DOCTEST_REPORT_CHOICE_UDIFF: doctest.REPORT_UDIFF, + DOCTEST_REPORT_CHOICE_CDIFF: doctest.REPORT_CDIFF, + DOCTEST_REPORT_CHOICE_NDIFF: doctest.REPORT_NDIFF, + DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE: doctest.REPORT_ONLY_FIRST_FAILURE, + DOCTEST_REPORT_CHOICE_NONE: 0, + }[key] + + +@fixture(scope="session") +def doctest_namespace() -> Dict[str, Any]: + """Fixture that returns a :py:class:`dict` that will be injected into the + namespace of doctests. + + Usually this fixture is used in conjunction with another ``autouse`` fixture: + + .. code-block:: python + + @pytest.fixture(autouse=True) + def add_np(doctest_namespace): + doctest_namespace["np"] = numpy + + For more details: :ref:`doctest_namespace`. + """ + return dict() diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/faulthandler.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/faulthandler.py new file mode 100644 index 00000000..d8c7e9fd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/faulthandler.py @@ -0,0 +1,102 @@ +import os +import sys +from typing import Generator + +import pytest +from _pytest.config import Config +from _pytest.config.argparsing import Parser +from _pytest.nodes import Item +from _pytest.stash import StashKey + + +fault_handler_original_stderr_fd_key = StashKey[int]() +fault_handler_stderr_fd_key = StashKey[int]() + + +def pytest_addoption(parser: Parser) -> None: + help = ( + "Dump the traceback of all threads if a test takes " + "more than TIMEOUT seconds to finish" + ) + parser.addini("faulthandler_timeout", help, default=0.0) + + +def pytest_configure(config: Config) -> None: + import faulthandler + + # at teardown we want to restore the original faulthandler fileno + # but faulthandler has no api to return the original fileno + # so here we stash the stderr fileno to be used at teardown + # sys.stderr and sys.__stderr__ may be closed or patched during the session + # so we can't rely on their values being good at that point (#11572). + stderr_fileno = get_stderr_fileno() + if faulthandler.is_enabled(): + config.stash[fault_handler_original_stderr_fd_key] = stderr_fileno + config.stash[fault_handler_stderr_fd_key] = os.dup(stderr_fileno) + faulthandler.enable(file=config.stash[fault_handler_stderr_fd_key]) + + +def pytest_unconfigure(config: Config) -> None: + import faulthandler + + faulthandler.disable() + # Close the dup file installed during pytest_configure. + if fault_handler_stderr_fd_key in config.stash: + os.close(config.stash[fault_handler_stderr_fd_key]) + del config.stash[fault_handler_stderr_fd_key] + # Re-enable the faulthandler if it was originally enabled. + if fault_handler_original_stderr_fd_key in config.stash: + faulthandler.enable(config.stash[fault_handler_original_stderr_fd_key]) + del config.stash[fault_handler_original_stderr_fd_key] + + +def get_stderr_fileno() -> int: + try: + fileno = sys.stderr.fileno() + # The Twisted Logger will return an invalid file descriptor since it is not backed + # by an FD. So, let's also forward this to the same code path as with pytest-xdist. + if fileno == -1: + raise AttributeError() + return fileno + except (AttributeError, ValueError): + # pytest-xdist monkeypatches sys.stderr with an object that is not an actual file. + # https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors + # This is potentially dangerous, but the best we can do. + return sys.__stderr__.fileno() + + +def get_timeout_config_value(config: Config) -> float: + return float(config.getini("faulthandler_timeout") or 0.0) + + +@pytest.hookimpl(hookwrapper=True, trylast=True) +def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: + timeout = get_timeout_config_value(item.config) + if timeout > 0: + import faulthandler + + stderr = item.config.stash[fault_handler_stderr_fd_key] + faulthandler.dump_traceback_later(timeout, file=stderr) + try: + yield + finally: + faulthandler.cancel_dump_traceback_later() + else: + yield + + +@pytest.hookimpl(tryfirst=True) +def pytest_enter_pdb() -> None: + """Cancel any traceback dumping due to timeout before entering pdb.""" + import faulthandler + + faulthandler.cancel_dump_traceback_later() + + +@pytest.hookimpl(tryfirst=True) +def pytest_exception_interact() -> None: + """Cancel any traceback dumping due to an interactive exception being + raised.""" + import faulthandler + + faulthandler.cancel_dump_traceback_later() diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/fixtures.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/fixtures.py new file mode 100644 index 00000000..0462504e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/fixtures.py @@ -0,0 +1,1713 @@ +import dataclasses +import functools +import inspect +import os +import sys +import warnings +from collections import defaultdict +from collections import deque +from contextlib import suppress +from pathlib import Path +from types import TracebackType +from typing import Any +from typing import Callable +from typing import cast +from typing import Dict +from typing import Generator +from typing import Generic +from typing import Iterable +from typing import Iterator +from typing import List +from typing import MutableMapping +from typing import NoReturn +from typing import Optional +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +import _pytest +from _pytest import nodes +from _pytest._code import getfslineno +from _pytest._code.code import FormattedExcinfo +from _pytest._code.code import TerminalRepr +from _pytest._io import TerminalWriter +from _pytest.compat import _format_args +from _pytest.compat import _PytestWrapper +from _pytest.compat import assert_never +from _pytest.compat import final +from _pytest.compat import get_real_func +from _pytest.compat import get_real_method +from _pytest.compat import getfuncargnames +from _pytest.compat import getimfunc +from _pytest.compat import getlocation +from _pytest.compat import is_generator +from _pytest.compat import NOTSET +from _pytest.compat import NotSetType +from _pytest.compat import overload +from _pytest.compat import safe_getattr +from _pytest.config import _PluggyPlugin +from _pytest.config import Config +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.deprecated import YIELD_FIXTURE +from _pytest.mark import Mark +from _pytest.mark import ParameterSet +from _pytest.mark.structures import MarkDecorator +from _pytest.outcomes import fail +from _pytest.outcomes import skip +from _pytest.outcomes import TEST_OUTCOME +from _pytest.pathlib import absolutepath +from _pytest.pathlib import bestrelpath +from _pytest.scope import HIGH_SCOPES +from _pytest.scope import Scope +from _pytest.stash import StashKey + + +if TYPE_CHECKING: + from typing import Deque + + from _pytest.scope import _ScopeName + from _pytest.main import Session + from _pytest.python import CallSpec2 + from _pytest.python import Metafunc + + +# The value of the fixture -- return/yield of the fixture function (type variable). +FixtureValue = TypeVar("FixtureValue") +# The type of the fixture function (type variable). +FixtureFunction = TypeVar("FixtureFunction", bound=Callable[..., object]) +# The type of a fixture function (type alias generic in fixture value). +_FixtureFunc = Union[ + Callable[..., FixtureValue], Callable[..., Generator[FixtureValue, None, None]] +] +# The type of FixtureDef.cached_result (type alias generic in fixture value). +_FixtureCachedResult = Union[ + Tuple[ + # The result. + FixtureValue, + # Cache key. + object, + None, + ], + Tuple[ + None, + # Cache key. + object, + # Exc info if raised. + Tuple[Type[BaseException], BaseException, TracebackType], + ], +] + + +@dataclasses.dataclass(frozen=True) +class PseudoFixtureDef(Generic[FixtureValue]): + cached_result: "_FixtureCachedResult[FixtureValue]" + _scope: Scope + + +def pytest_sessionstart(session: "Session") -> None: + session._fixturemanager = FixtureManager(session) + + +def get_scope_package( + node: nodes.Item, + fixturedef: "FixtureDef[object]", +) -> Optional[Union[nodes.Item, nodes.Collector]]: + from _pytest.python import Package + + current: Optional[Union[nodes.Item, nodes.Collector]] = node + fixture_package_name = "{}/{}".format(fixturedef.baseid, "__init__.py") + while current and ( + not isinstance(current, Package) or fixture_package_name != current.nodeid + ): + current = current.parent # type: ignore[assignment] + if current is None: + return node.session + return current + + +def get_scope_node( + node: nodes.Node, scope: Scope +) -> Optional[Union[nodes.Item, nodes.Collector]]: + import _pytest.python + + if scope is Scope.Function: + return node.getparent(nodes.Item) + elif scope is Scope.Class: + return node.getparent(_pytest.python.Class) + elif scope is Scope.Module: + return node.getparent(_pytest.python.Module) + elif scope is Scope.Package: + return node.getparent(_pytest.python.Package) + elif scope is Scope.Session: + return node.getparent(_pytest.main.Session) + else: + assert_never(scope) + + +# Used for storing artificial fixturedefs for direct parametrization. +name2pseudofixturedef_key = StashKey[Dict[str, "FixtureDef[Any]"]]() + + +def add_funcarg_pseudo_fixture_def( + collector: nodes.Collector, metafunc: "Metafunc", fixturemanager: "FixtureManager" +) -> None: + # This function will transform all collected calls to functions + # if they use direct funcargs (i.e. direct parametrization) + # because we want later test execution to be able to rely on + # an existing FixtureDef structure for all arguments. + # XXX we can probably avoid this algorithm if we modify CallSpec2 + # to directly care for creating the fixturedefs within its methods. + if not metafunc._calls[0].funcargs: + # This function call does not have direct parametrization. + return + # Collect funcargs of all callspecs into a list of values. + arg2params: Dict[str, List[object]] = {} + arg2scope: Dict[str, Scope] = {} + for callspec in metafunc._calls: + for argname, argvalue in callspec.funcargs.items(): + assert argname not in callspec.params + callspec.params[argname] = argvalue + arg2params_list = arg2params.setdefault(argname, []) + callspec.indices[argname] = len(arg2params_list) + arg2params_list.append(argvalue) + if argname not in arg2scope: + scope = callspec._arg2scope.get(argname, Scope.Function) + arg2scope[argname] = scope + callspec.funcargs.clear() + + # Register artificial FixtureDef's so that later at test execution + # time we can rely on a proper FixtureDef to exist for fixture setup. + arg2fixturedefs = metafunc._arg2fixturedefs + for argname, valuelist in arg2params.items(): + # If we have a scope that is higher than function, we need + # to make sure we only ever create an according fixturedef on + # a per-scope basis. We thus store and cache the fixturedef on the + # node related to the scope. + scope = arg2scope[argname] + node = None + if scope is not Scope.Function: + node = get_scope_node(collector, scope) + if node is None: + assert scope is Scope.Class and isinstance( + collector, _pytest.python.Module + ) + # Use module-level collector for class-scope (for now). + node = collector + if node is None: + name2pseudofixturedef = None + else: + default: Dict[str, FixtureDef[Any]] = {} + name2pseudofixturedef = node.stash.setdefault( + name2pseudofixturedef_key, default + ) + if name2pseudofixturedef is not None and argname in name2pseudofixturedef: + arg2fixturedefs[argname] = [name2pseudofixturedef[argname]] + else: + fixturedef = FixtureDef( + fixturemanager=fixturemanager, + baseid="", + argname=argname, + func=get_direct_param_fixture_func, + scope=arg2scope[argname], + params=valuelist, + unittest=False, + ids=None, + ) + arg2fixturedefs[argname] = [fixturedef] + if name2pseudofixturedef is not None: + name2pseudofixturedef[argname] = fixturedef + + +def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]: + """Return fixturemarker or None if it doesn't exist or raised + exceptions.""" + return cast( + Optional[FixtureFunctionMarker], + safe_getattr(obj, "_pytestfixturefunction", None), + ) + + +# Parametrized fixture key, helper alias for code below. +_Key = Tuple[object, ...] + + +def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_Key]: + """Return list of keys for all parametrized arguments which match + the specified scope.""" + assert scope is not Scope.Function + try: + callspec = item.callspec # type: ignore[attr-defined] + except AttributeError: + pass + else: + cs: CallSpec2 = callspec + # cs.indices.items() is random order of argnames. Need to + # sort this so that different calls to + # get_parametrized_fixture_keys will be deterministic. + for argname, param_index in sorted(cs.indices.items()): + if cs._arg2scope[argname] != scope: + continue + if scope is Scope.Session: + key: _Key = (argname, param_index) + elif scope is Scope.Package: + key = (argname, param_index, item.path.parent) + elif scope is Scope.Module: + key = (argname, param_index, item.path) + elif scope is Scope.Class: + item_cls = item.cls # type: ignore[attr-defined] + key = (argname, param_index, item.path, item_cls) + else: + assert_never(scope) + yield key + + +# Algorithm for sorting on a per-parametrized resource setup basis. +# It is called for Session scope first and performs sorting +# down to the lower scopes such as to minimize number of "high scope" +# setups and teardowns. + + +def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]: + argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]] = {} + items_by_argkey: Dict[Scope, Dict[_Key, Deque[nodes.Item]]] = {} + for scope in HIGH_SCOPES: + d: Dict[nodes.Item, Dict[_Key, None]] = {} + argkeys_cache[scope] = d + item_d: Dict[_Key, Deque[nodes.Item]] = defaultdict(deque) + items_by_argkey[scope] = item_d + for item in items: + keys = dict.fromkeys(get_parametrized_fixture_keys(item, scope), None) + if keys: + d[item] = keys + for key in keys: + item_d[key].append(item) + items_dict = dict.fromkeys(items, None) + return list( + reorder_items_atscope(items_dict, argkeys_cache, items_by_argkey, Scope.Session) + ) + + +def fix_cache_order( + item: nodes.Item, + argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]], + items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]], +) -> None: + for scope in HIGH_SCOPES: + for key in argkeys_cache[scope].get(item, []): + items_by_argkey[scope][key].appendleft(item) + + +def reorder_items_atscope( + items: Dict[nodes.Item, None], + argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]], + items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]], + scope: Scope, +) -> Dict[nodes.Item, None]: + if scope is Scope.Function or len(items) < 3: + return items + ignore: Set[Optional[_Key]] = set() + items_deque = deque(items) + items_done: Dict[nodes.Item, None] = {} + scoped_items_by_argkey = items_by_argkey[scope] + scoped_argkeys_cache = argkeys_cache[scope] + while items_deque: + no_argkey_group: Dict[nodes.Item, None] = {} + slicing_argkey = None + while items_deque: + item = items_deque.popleft() + if item in items_done or item in no_argkey_group: + continue + argkeys = dict.fromkeys( + (k for k in scoped_argkeys_cache.get(item, []) if k not in ignore), None + ) + if not argkeys: + no_argkey_group[item] = None + else: + slicing_argkey, _ = argkeys.popitem() + # We don't have to remove relevant items from later in the + # deque because they'll just be ignored. + matching_items = [ + i for i in scoped_items_by_argkey[slicing_argkey] if i in items + ] + for i in reversed(matching_items): + fix_cache_order(i, argkeys_cache, items_by_argkey) + items_deque.appendleft(i) + break + if no_argkey_group: + no_argkey_group = reorder_items_atscope( + no_argkey_group, argkeys_cache, items_by_argkey, scope.next_lower() + ) + for item in no_argkey_group: + items_done[item] = None + ignore.add(slicing_argkey) + return items_done + + +def get_direct_param_fixture_func(request: "FixtureRequest") -> Any: + return request.param + + +@dataclasses.dataclass +class FuncFixtureInfo: + __slots__ = ("argnames", "initialnames", "names_closure", "name2fixturedefs") + + # Original function argument names. + argnames: Tuple[str, ...] + # Argnames that function immediately requires. These include argnames + + # fixture names specified via usefixtures and via autouse=True in fixture + # definitions. + initialnames: Tuple[str, ...] + names_closure: List[str] + name2fixturedefs: Dict[str, Sequence["FixtureDef[Any]"]] + + def prune_dependency_tree(self) -> None: + """Recompute names_closure from initialnames and name2fixturedefs. + + Can only reduce names_closure, which means that the new closure will + always be a subset of the old one. The order is preserved. + + This method is needed because direct parametrization may shadow some + of the fixtures that were included in the originally built dependency + tree. In this way the dependency tree can get pruned, and the closure + of argnames may get reduced. + """ + closure: Set[str] = set() + working_set = set(self.initialnames) + while working_set: + argname = working_set.pop() + # Argname may be smth not included in the original names_closure, + # in which case we ignore it. This currently happens with pseudo + # FixtureDefs which wrap 'get_direct_param_fixture_func(request)'. + # So they introduce the new dependency 'request' which might have + # been missing in the original tree (closure). + if argname not in closure and argname in self.names_closure: + closure.add(argname) + if argname in self.name2fixturedefs: + working_set.update(self.name2fixturedefs[argname][-1].argnames) + + self.names_closure[:] = sorted(closure, key=self.names_closure.index) + + +class FixtureRequest: + """A request for a fixture from a test or fixture function. + + A request object gives access to the requesting test context and has + an optional ``param`` attribute in case the fixture is parametrized + indirectly. + """ + + def __init__(self, pyfuncitem, *, _ispytest: bool = False) -> None: + check_ispytest(_ispytest) + self._pyfuncitem = pyfuncitem + #: Fixture for which this request is being performed. + self.fixturename: Optional[str] = None + self._scope = Scope.Function + self._fixture_defs: Dict[str, FixtureDef[Any]] = {} + fixtureinfo: FuncFixtureInfo = pyfuncitem._fixtureinfo + self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy() + self._arg2index: Dict[str, int] = {} + self._fixturemanager: FixtureManager = pyfuncitem.session._fixturemanager + # Notes on the type of `param`: + # -`request.param` is only defined in parametrized fixtures, and will raise + # AttributeError otherwise. Python typing has no notion of "undefined", so + # this cannot be reflected in the type. + # - Technically `param` is only (possibly) defined on SubRequest, not + # FixtureRequest, but the typing of that is still in flux so this cheats. + # - In the future we might consider using a generic for the param type, but + # for now just using Any. + self.param: Any + + @property + def scope(self) -> "_ScopeName": + """Scope string, one of "function", "class", "module", "package", "session".""" + return self._scope.value + + @property + def fixturenames(self) -> List[str]: + """Names of all active fixtures in this request.""" + result = list(self._pyfuncitem._fixtureinfo.names_closure) + result.extend(set(self._fixture_defs).difference(result)) + return result + + @property + def node(self): + """Underlying collection node (depends on current request scope).""" + scope = self._scope + if scope is Scope.Function: + # This might also be a non-function Item despite its attribute name. + node: Optional[Union[nodes.Item, nodes.Collector]] = self._pyfuncitem + elif scope is Scope.Package: + # FIXME: _fixturedef is not defined on FixtureRequest (this class), + # but on FixtureRequest (a subclass). + node = get_scope_package(self._pyfuncitem, self._fixturedef) # type: ignore[attr-defined] + else: + node = get_scope_node(self._pyfuncitem, scope) + if node is None and scope is Scope.Class: + # Fallback to function item itself. + node = self._pyfuncitem + assert node, 'Could not obtain a node for scope "{}" for function {!r}'.format( + scope, self._pyfuncitem + ) + return node + + def _getnextfixturedef(self, argname: str) -> "FixtureDef[Any]": + fixturedefs = self._arg2fixturedefs.get(argname, None) + if fixturedefs is None: + # We arrive here because of a dynamic call to + # getfixturevalue(argname) usage which was naturally + # not known at parsing/collection time. + assert self._pyfuncitem.parent is not None + parentid = self._pyfuncitem.parent.nodeid + fixturedefs = self._fixturemanager.getfixturedefs(argname, parentid) + # TODO: Fix this type ignore. Either add assert or adjust types. + # Can this be None here? + self._arg2fixturedefs[argname] = fixturedefs # type: ignore[assignment] + # fixturedefs list is immutable so we maintain a decreasing index. + index = self._arg2index.get(argname, 0) - 1 + if fixturedefs is None or (-index > len(fixturedefs)): + raise FixtureLookupError(argname, self) + self._arg2index[argname] = index + return fixturedefs[index] + + @property + def config(self) -> Config: + """The pytest config object associated with this request.""" + return self._pyfuncitem.config # type: ignore[no-any-return] + + @property + def function(self): + """Test function object if the request has a per-function scope.""" + if self.scope != "function": + raise AttributeError( + f"function not available in {self.scope}-scoped context" + ) + return self._pyfuncitem.obj + + @property + def cls(self): + """Class (can be None) where the test function was collected.""" + if self.scope not in ("class", "function"): + raise AttributeError(f"cls not available in {self.scope}-scoped context") + clscol = self._pyfuncitem.getparent(_pytest.python.Class) + if clscol: + return clscol.obj + + @property + def instance(self): + """Instance (can be None) on which test function was collected.""" + # unittest support hack, see _pytest.unittest.TestCaseFunction. + try: + return self._pyfuncitem._testcase + except AttributeError: + function = getattr(self, "function", None) + return getattr(function, "__self__", None) + + @property + def module(self): + """Python module object where the test function was collected.""" + if self.scope not in ("function", "class", "module"): + raise AttributeError(f"module not available in {self.scope}-scoped context") + return self._pyfuncitem.getparent(_pytest.python.Module).obj + + @property + def path(self) -> Path: + """Path where the test function was collected.""" + if self.scope not in ("function", "class", "module", "package"): + raise AttributeError(f"path not available in {self.scope}-scoped context") + # TODO: Remove ignore once _pyfuncitem is properly typed. + return self._pyfuncitem.path # type: ignore + + @property + def keywords(self) -> MutableMapping[str, Any]: + """Keywords/markers dictionary for the underlying node.""" + node: nodes.Node = self.node + return node.keywords + + @property + def session(self) -> "Session": + """Pytest session object.""" + return self._pyfuncitem.session # type: ignore[no-any-return] + + def addfinalizer(self, finalizer: Callable[[], object]) -> None: + """Add finalizer/teardown function to be called without arguments after + the last test within the requesting test context finished execution.""" + # XXX usually this method is shadowed by fixturedef specific ones. + self.node.addfinalizer(finalizer) + + def applymarker(self, marker: Union[str, MarkDecorator]) -> None: + """Apply a marker to a single test function invocation. + + This method is useful if you don't want to have a keyword/marker + on all function invocations. + + :param marker: + An object created by a call to ``pytest.mark.NAME(...)``. + """ + self.node.add_marker(marker) + + def raiseerror(self, msg: Optional[str]) -> NoReturn: + """Raise a FixtureLookupError exception. + + :param msg: + An optional custom error message. + """ + raise self._fixturemanager.FixtureLookupError(None, self, msg) + + def _fillfixtures(self) -> None: + item = self._pyfuncitem + fixturenames = getattr(item, "fixturenames", self.fixturenames) + for argname in fixturenames: + if argname not in item.funcargs: + item.funcargs[argname] = self.getfixturevalue(argname) + + def getfixturevalue(self, argname: str) -> Any: + """Dynamically run a named fixture function. + + Declaring fixtures via function argument is recommended where possible. + But if you can only decide whether to use another fixture at test + setup time, you may use this function to retrieve it inside a fixture + or test function body. + + This method can be used during the test setup phase or the test run + phase, but during the test teardown phase a fixture's value may not + be available. + + :param argname: + The fixture name. + :raises pytest.FixtureLookupError: + If the given fixture could not be found. + """ + fixturedef = self._get_active_fixturedef(argname) + assert fixturedef.cached_result is not None, ( + f'The fixture value for "{argname}" is not available. ' + "This can happen when the fixture has already been torn down." + ) + return fixturedef.cached_result[0] + + def _get_active_fixturedef( + self, argname: str + ) -> Union["FixtureDef[object]", PseudoFixtureDef[object]]: + try: + return self._fixture_defs[argname] + except KeyError: + try: + fixturedef = self._getnextfixturedef(argname) + except FixtureLookupError: + if argname == "request": + cached_result = (self, [0], None) + return PseudoFixtureDef(cached_result, Scope.Function) + raise + # Remove indent to prevent the python3 exception + # from leaking into the call. + self._compute_fixture_value(fixturedef) + self._fixture_defs[argname] = fixturedef + return fixturedef + + def _get_fixturestack(self) -> List["FixtureDef[Any]"]: + current = self + values: List[FixtureDef[Any]] = [] + while isinstance(current, SubRequest): + values.append(current._fixturedef) # type: ignore[has-type] + current = current._parent_request + values.reverse() + return values + + def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None: + """Create a SubRequest based on "self" and call the execute method + of the given FixtureDef object. + + This will force the FixtureDef object to throw away any previous + results and compute a new fixture value, which will be stored into + the FixtureDef object itself. + """ + # prepare a subrequest object before calling fixture function + # (latter managed by fixturedef) + argname = fixturedef.argname + funcitem = self._pyfuncitem + scope = fixturedef._scope + try: + callspec = funcitem.callspec + except AttributeError: + callspec = None + if callspec is not None and argname in callspec.params: + param = callspec.params[argname] + param_index = callspec.indices[argname] + # If a parametrize invocation set a scope it will override + # the static scope defined with the fixture function. + with suppress(KeyError): + scope = callspec._arg2scope[argname] + else: + param = NOTSET + param_index = 0 + has_params = fixturedef.params is not None + fixtures_not_supported = getattr(funcitem, "nofuncargs", False) + if has_params and fixtures_not_supported: + msg = ( + "{name} does not support fixtures, maybe unittest.TestCase subclass?\n" + "Node id: {nodeid}\n" + "Function type: {typename}" + ).format( + name=funcitem.name, + nodeid=funcitem.nodeid, + typename=type(funcitem).__name__, + ) + fail(msg, pytrace=False) + if has_params: + frame = inspect.stack()[3] + frameinfo = inspect.getframeinfo(frame[0]) + source_path = absolutepath(frameinfo.filename) + source_lineno = frameinfo.lineno + try: + source_path_str = str( + source_path.relative_to(funcitem.config.rootpath) + ) + except ValueError: + source_path_str = str(source_path) + msg = ( + "The requested fixture has no parameter defined for test:\n" + " {}\n\n" + "Requested fixture '{}' defined in:\n{}" + "\n\nRequested here:\n{}:{}".format( + funcitem.nodeid, + fixturedef.argname, + getlocation(fixturedef.func, funcitem.config.rootpath), + source_path_str, + source_lineno, + ) + ) + fail(msg, pytrace=False) + + subrequest = SubRequest( + self, scope, param, param_index, fixturedef, _ispytest=True + ) + + # Check if a higher-level scoped fixture accesses a lower level one. + subrequest._check_scope(argname, self._scope, scope) + try: + # Call the fixture function. + fixturedef.execute(request=subrequest) + finally: + self._schedule_finalizers(fixturedef, subrequest) + + def _schedule_finalizers( + self, fixturedef: "FixtureDef[object]", subrequest: "SubRequest" + ) -> None: + # If fixture function failed it might have registered finalizers. + subrequest.node.addfinalizer(lambda: fixturedef.finish(request=subrequest)) + + def _check_scope( + self, + argname: str, + invoking_scope: Scope, + requested_scope: Scope, + ) -> None: + if argname == "request": + return + if invoking_scope > requested_scope: + # Try to report something helpful. + text = "\n".join(self._factorytraceback()) + fail( + f"ScopeMismatch: You tried to access the {requested_scope.value} scoped " + f"fixture {argname} with a {invoking_scope.value} scoped request object, " + f"involved factories:\n{text}", + pytrace=False, + ) + + def _factorytraceback(self) -> List[str]: + lines = [] + for fixturedef in self._get_fixturestack(): + factory = fixturedef.func + fs, lineno = getfslineno(factory) + if isinstance(fs, Path): + session: Session = self._pyfuncitem.session + p = bestrelpath(session.path, fs) + else: + p = fs + args = _format_args(factory) + lines.append("%s:%d: def %s%s" % (p, lineno + 1, factory.__name__, args)) + return lines + + def __repr__(self) -> str: + return "" % (self.node) + + +@final +class SubRequest(FixtureRequest): + """A sub request for handling getting a fixture from a test function/fixture.""" + + def __init__( + self, + request: "FixtureRequest", + scope: Scope, + param: Any, + param_index: int, + fixturedef: "FixtureDef[object]", + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._parent_request = request + self.fixturename = fixturedef.argname + if param is not NOTSET: + self.param = param + self.param_index = param_index + self._scope = scope + self._fixturedef = fixturedef + self._pyfuncitem = request._pyfuncitem + self._fixture_defs = request._fixture_defs + self._arg2fixturedefs = request._arg2fixturedefs + self._arg2index = request._arg2index + self._fixturemanager = request._fixturemanager + + def __repr__(self) -> str: + return f"" + + def addfinalizer(self, finalizer: Callable[[], object]) -> None: + """Add finalizer/teardown function to be called without arguments after + the last test within the requesting test context finished execution.""" + self._fixturedef.addfinalizer(finalizer) + + def _schedule_finalizers( + self, fixturedef: "FixtureDef[object]", subrequest: "SubRequest" + ) -> None: + # If the executing fixturedef was not explicitly requested in the argument list (via + # getfixturevalue inside the fixture call) then ensure this fixture def will be finished + # first. + if fixturedef.argname not in self.fixturenames: + fixturedef.addfinalizer( + functools.partial(self._fixturedef.finish, request=self) + ) + super()._schedule_finalizers(fixturedef, subrequest) + + +@final +class FixtureLookupError(LookupError): + """Could not return a requested fixture (missing or invalid).""" + + def __init__( + self, argname: Optional[str], request: FixtureRequest, msg: Optional[str] = None + ) -> None: + self.argname = argname + self.request = request + self.fixturestack = request._get_fixturestack() + self.msg = msg + + def formatrepr(self) -> "FixtureLookupErrorRepr": + tblines: List[str] = [] + addline = tblines.append + stack = [self.request._pyfuncitem.obj] + stack.extend(map(lambda x: x.func, self.fixturestack)) + msg = self.msg + if msg is not None: + # The last fixture raise an error, let's present + # it at the requesting side. + stack = stack[:-1] + for function in stack: + fspath, lineno = getfslineno(function) + try: + lines, _ = inspect.getsourcelines(get_real_func(function)) + except (OSError, IndexError, TypeError): + error_msg = "file %s, line %s: source code not available" + addline(error_msg % (fspath, lineno + 1)) + else: + addline(f"file {fspath}, line {lineno + 1}") + for i, line in enumerate(lines): + line = line.rstrip() + addline(" " + line) + if line.lstrip().startswith("def"): + break + + if msg is None: + fm = self.request._fixturemanager + available = set() + parentid = self.request._pyfuncitem.parent.nodeid + for name, fixturedefs in fm._arg2fixturedefs.items(): + faclist = list(fm._matchfactories(fixturedefs, parentid)) + if faclist: + available.add(name) + if self.argname in available: + msg = " recursive dependency involving fixture '{}' detected".format( + self.argname + ) + else: + msg = f"fixture '{self.argname}' not found" + msg += "\n available fixtures: {}".format(", ".join(sorted(available))) + msg += "\n use 'pytest --fixtures [testpath]' for help on them." + + return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname) + + +class FixtureLookupErrorRepr(TerminalRepr): + def __init__( + self, + filename: Union[str, "os.PathLike[str]"], + firstlineno: int, + tblines: Sequence[str], + errorstring: str, + argname: Optional[str], + ) -> None: + self.tblines = tblines + self.errorstring = errorstring + self.filename = filename + self.firstlineno = firstlineno + self.argname = argname + + def toterminal(self, tw: TerminalWriter) -> None: + # tw.line("FixtureLookupError: %s" %(self.argname), red=True) + for tbline in self.tblines: + tw.line(tbline.rstrip()) + lines = self.errorstring.split("\n") + if lines: + tw.line( + f"{FormattedExcinfo.fail_marker} {lines[0].strip()}", + red=True, + ) + for line in lines[1:]: + tw.line( + f"{FormattedExcinfo.flow_marker} {line.strip()}", + red=True, + ) + tw.line() + tw.line("%s:%d" % (os.fspath(self.filename), self.firstlineno + 1)) + + +def fail_fixturefunc(fixturefunc, msg: str) -> NoReturn: + fs, lineno = getfslineno(fixturefunc) + location = f"{fs}:{lineno + 1}" + source = _pytest._code.Source(fixturefunc) + fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False) + + +def call_fixture_func( + fixturefunc: "_FixtureFunc[FixtureValue]", request: FixtureRequest, kwargs +) -> FixtureValue: + if is_generator(fixturefunc): + fixturefunc = cast( + Callable[..., Generator[FixtureValue, None, None]], fixturefunc + ) + generator = fixturefunc(**kwargs) + try: + fixture_result = next(generator) + except StopIteration: + raise ValueError(f"{request.fixturename} did not yield a value") from None + finalizer = functools.partial(_teardown_yield_fixture, fixturefunc, generator) + request.addfinalizer(finalizer) + else: + fixturefunc = cast(Callable[..., FixtureValue], fixturefunc) + fixture_result = fixturefunc(**kwargs) + return fixture_result + + +def _teardown_yield_fixture(fixturefunc, it) -> None: + """Execute the teardown of a fixture function by advancing the iterator + after the yield and ensure the iteration ends (if not it means there is + more than one yield in the function).""" + try: + next(it) + except StopIteration: + pass + else: + fail_fixturefunc(fixturefunc, "fixture function has more than one 'yield'") + + +def _eval_scope_callable( + scope_callable: "Callable[[str, Config], _ScopeName]", + fixture_name: str, + config: Config, +) -> "_ScopeName": + try: + # Type ignored because there is no typing mechanism to specify + # keyword arguments, currently. + result = scope_callable(fixture_name=fixture_name, config=config) # type: ignore[call-arg] + except Exception as e: + raise TypeError( + "Error evaluating {} while defining fixture '{}'.\n" + "Expected a function with the signature (*, fixture_name, config)".format( + scope_callable, fixture_name + ) + ) from e + if not isinstance(result, str): + fail( + "Expected {} to return a 'str' while defining fixture '{}', but it returned:\n" + "{!r}".format(scope_callable, fixture_name, result), + pytrace=False, + ) + return result + + +@final +class FixtureDef(Generic[FixtureValue]): + """A container for a fixture definition.""" + + def __init__( + self, + fixturemanager: "FixtureManager", + baseid: Optional[str], + argname: str, + func: "_FixtureFunc[FixtureValue]", + scope: Union[Scope, "_ScopeName", Callable[[str, Config], "_ScopeName"], None], + params: Optional[Sequence[object]], + unittest: bool = False, + ids: Optional[ + Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]] + ] = None, + ) -> None: + self._fixturemanager = fixturemanager + # The "base" node ID for the fixture. + # + # This is a node ID prefix. A fixture is only available to a node (e.g. + # a `Function` item) if the fixture's baseid is a parent of the node's + # nodeid (see the `iterparentnodeids` function for what constitutes a + # "parent" and a "prefix" in this context). + # + # For a fixture found in a Collector's object (e.g. a `Module`s module, + # a `Class`'s class), the baseid is the Collector's nodeid. + # + # For a fixture found in a conftest plugin, the baseid is the conftest's + # directory path relative to the rootdir. + # + # For other plugins, the baseid is the empty string (always matches). + self.baseid = baseid or "" + # Whether the fixture was found from a node or a conftest in the + # collection tree. Will be false for fixtures defined in non-conftest + # plugins. + self.has_location = baseid is not None + # The fixture factory function. + self.func = func + # The name by which the fixture may be requested. + self.argname = argname + if scope is None: + scope = Scope.Function + elif callable(scope): + scope = _eval_scope_callable(scope, argname, fixturemanager.config) + if isinstance(scope, str): + scope = Scope.from_user( + scope, descr=f"Fixture '{func.__name__}'", where=baseid + ) + self._scope = scope + # If the fixture is directly parametrized, the parameter values. + self.params: Optional[Sequence[object]] = params + # If the fixture is directly parametrized, a tuple of explicit IDs to + # assign to the parameter values, or a callable to generate an ID given + # a parameter value. + self.ids = ids + # The names requested by the fixtures. + self.argnames = getfuncargnames(func, name=argname, is_method=unittest) + # Whether the fixture was collected from a unittest TestCase class. + # Note that it really only makes sense to define autouse fixtures in + # unittest TestCases. + self.unittest = unittest + # If the fixture was executed, the current value of the fixture. + # Can change if the fixture is executed with different parameters. + self.cached_result: Optional[_FixtureCachedResult[FixtureValue]] = None + self._finalizers: List[Callable[[], object]] = [] + + @property + def scope(self) -> "_ScopeName": + """Scope string, one of "function", "class", "module", "package", "session".""" + return self._scope.value + + def addfinalizer(self, finalizer: Callable[[], object]) -> None: + self._finalizers.append(finalizer) + + def finish(self, request: SubRequest) -> None: + exc = None + try: + while self._finalizers: + try: + func = self._finalizers.pop() + func() + except BaseException as e: + # XXX Only first exception will be seen by user, + # ideally all should be reported. + if exc is None: + exc = e + if exc: + raise exc + finally: + ihook = request.node.ihook + ihook.pytest_fixture_post_finalizer(fixturedef=self, request=request) + # Even if finalization fails, we invalidate the cached fixture + # value and remove all finalizers because they may be bound methods + # which will keep instances alive. + self.cached_result = None + self._finalizers = [] + + def execute(self, request: SubRequest) -> FixtureValue: + # Get required arguments and register our own finish() + # with their finalization. + for argname in self.argnames: + fixturedef = request._get_active_fixturedef(argname) + if argname != "request": + # PseudoFixtureDef is only for "request". + assert isinstance(fixturedef, FixtureDef) + fixturedef.addfinalizer(functools.partial(self.finish, request=request)) + + my_cache_key = self.cache_key(request) + if self.cached_result is not None: + # note: comparison with `==` can fail (or be expensive) for e.g. + # numpy arrays (#6497). + cache_key = self.cached_result[1] + if my_cache_key is cache_key: + if self.cached_result[2] is not None: + _, val, tb = self.cached_result[2] + raise val.with_traceback(tb) + else: + result = self.cached_result[0] + return result + # We have a previous but differently parametrized fixture instance + # so we need to tear it down before creating a new one. + self.finish(request) + assert self.cached_result is None + + ihook = request.node.ihook + result = ihook.pytest_fixture_setup(fixturedef=self, request=request) + return result + + def cache_key(self, request: SubRequest) -> object: + return request.param_index if not hasattr(request, "param") else request.param + + def __repr__(self) -> str: + return "".format( + self.argname, self.scope, self.baseid + ) + + +def resolve_fixture_function( + fixturedef: FixtureDef[FixtureValue], request: FixtureRequest +) -> "_FixtureFunc[FixtureValue]": + """Get the actual callable that can be called to obtain the fixture + value, dealing with unittest-specific instances and bound methods.""" + fixturefunc = fixturedef.func + if fixturedef.unittest: + if request.instance is not None: + # Bind the unbound method to the TestCase instance. + fixturefunc = fixturedef.func.__get__(request.instance) # type: ignore[union-attr] + else: + # The fixture function needs to be bound to the actual + # request.instance so that code working with "fixturedef" behaves + # as expected. + if request.instance is not None: + # Handle the case where fixture is defined not in a test class, but some other class + # (for example a plugin class with a fixture), see #2270. + if hasattr(fixturefunc, "__self__") and not isinstance( + request.instance, fixturefunc.__self__.__class__ # type: ignore[union-attr] + ): + return fixturefunc + fixturefunc = getimfunc(fixturedef.func) + if fixturefunc != fixturedef.func: + fixturefunc = fixturefunc.__get__(request.instance) # type: ignore[union-attr] + return fixturefunc + + +def pytest_fixture_setup( + fixturedef: FixtureDef[FixtureValue], request: SubRequest +) -> FixtureValue: + """Execution of fixture setup.""" + kwargs = {} + for argname in fixturedef.argnames: + fixdef = request._get_active_fixturedef(argname) + assert fixdef.cached_result is not None + result, arg_cache_key, exc = fixdef.cached_result + request._check_scope(argname, request._scope, fixdef._scope) + kwargs[argname] = result + + fixturefunc = resolve_fixture_function(fixturedef, request) + my_cache_key = fixturedef.cache_key(request) + try: + result = call_fixture_func(fixturefunc, request, kwargs) + except TEST_OUTCOME: + exc_info = sys.exc_info() + assert exc_info[0] is not None + if isinstance( + exc_info[1], skip.Exception + ) and not fixturefunc.__name__.startswith("xunit_setup"): + exc_info[1]._use_item_location = True # type: ignore[attr-defined] + fixturedef.cached_result = (None, my_cache_key, exc_info) + raise + fixturedef.cached_result = (result, my_cache_key, None) + return result + + +def _ensure_immutable_ids( + ids: Optional[Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]] +) -> Optional[Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]]]: + if ids is None: + return None + if callable(ids): + return ids + return tuple(ids) + + +def _params_converter( + params: Optional[Iterable[object]], +) -> Optional[Tuple[object, ...]]: + return tuple(params) if params is not None else None + + +def wrap_function_to_error_out_if_called_directly( + function: FixtureFunction, + fixture_marker: "FixtureFunctionMarker", +) -> FixtureFunction: + """Wrap the given fixture function so we can raise an error about it being called directly, + instead of used as an argument in a test function.""" + message = ( + 'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n' + "but are created automatically when test functions request them as parameters.\n" + "See https://docs.pytest.org/en/stable/explanation/fixtures.html for more information about fixtures, and\n" + "https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly about how to update your code." + ).format(name=fixture_marker.name or function.__name__) + + @functools.wraps(function) + def result(*args, **kwargs): + fail(message, pytrace=False) + + # Keep reference to the original function in our own custom attribute so we don't unwrap + # further than this point and lose useful wrappings like @mock.patch (#3774). + result.__pytest_wrapped__ = _PytestWrapper(function) # type: ignore[attr-defined] + + return cast(FixtureFunction, result) + + +@final +@dataclasses.dataclass(frozen=True) +class FixtureFunctionMarker: + scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" + params: Optional[Tuple[object, ...]] + autouse: bool = False + ids: Optional[ + Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]] + ] = None + name: Optional[str] = None + + _ispytest: dataclasses.InitVar[bool] = False + + def __post_init__(self, _ispytest: bool) -> None: + check_ispytest(_ispytest) + + def __call__(self, function: FixtureFunction) -> FixtureFunction: + if inspect.isclass(function): + raise ValueError("class fixtures not supported (maybe in the future)") + + if getattr(function, "_pytestfixturefunction", False): + raise ValueError( + "fixture is being applied more than once to the same function" + ) + + function = wrap_function_to_error_out_if_called_directly(function, self) + + name = self.name or function.__name__ + if name == "request": + location = getlocation(function) + fail( + "'request' is a reserved word for fixtures, use another name:\n {}".format( + location + ), + pytrace=False, + ) + + # Type ignored because https://github.com/python/mypy/issues/2087. + function._pytestfixturefunction = self # type: ignore[attr-defined] + return function + + +@overload +def fixture( + fixture_function: FixtureFunction, + *, + scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ..., + params: Optional[Iterable[object]] = ..., + autouse: bool = ..., + ids: Optional[ + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] + ] = ..., + name: Optional[str] = ..., +) -> FixtureFunction: + ... + + +@overload +def fixture( # noqa: F811 + fixture_function: None = ..., + *, + scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ..., + params: Optional[Iterable[object]] = ..., + autouse: bool = ..., + ids: Optional[ + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] + ] = ..., + name: Optional[str] = None, +) -> FixtureFunctionMarker: + ... + + +def fixture( # noqa: F811 + fixture_function: Optional[FixtureFunction] = None, + *, + scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function", + params: Optional[Iterable[object]] = None, + autouse: bool = False, + ids: Optional[ + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] + ] = None, + name: Optional[str] = None, +) -> Union[FixtureFunctionMarker, FixtureFunction]: + """Decorator to mark a fixture factory function. + + This decorator can be used, with or without parameters, to define a + fixture function. + + The name of the fixture function can later be referenced to cause its + invocation ahead of running tests: test modules or classes can use the + ``pytest.mark.usefixtures(fixturename)`` marker. + + Test functions can directly use fixture names as input arguments in which + case the fixture instance returned from the fixture function will be + injected. + + Fixtures can provide their values to test functions using ``return`` or + ``yield`` statements. When using ``yield`` the code block after the + ``yield`` statement is executed as teardown code regardless of the test + outcome, and must yield exactly once. + + :param scope: + The scope for which this fixture is shared; one of ``"function"`` + (default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``. + + This parameter may also be a callable which receives ``(fixture_name, config)`` + as parameters, and must return a ``str`` with one of the values mentioned above. + + See :ref:`dynamic scope` in the docs for more information. + + :param params: + An optional list of parameters which will cause multiple invocations + of the fixture function and all of the tests using it. The current + parameter is available in ``request.param``. + + :param autouse: + If True, the fixture func is activated for all tests that can see it. + If False (the default), an explicit reference is needed to activate + the fixture. + + :param ids: + Sequence of ids each corresponding to the params so that they are + part of the test id. If no ids are provided they will be generated + automatically from the params. + + :param name: + The name of the fixture. This defaults to the name of the decorated + function. If a fixture is used in the same module in which it is + defined, the function name of the fixture will be shadowed by the + function arg that requests the fixture; one way to resolve this is to + name the decorated function ``fixture_`` and then use + ``@pytest.fixture(name='')``. + """ + fixture_marker = FixtureFunctionMarker( + scope=scope, + params=tuple(params) if params is not None else None, + autouse=autouse, + ids=None if ids is None else ids if callable(ids) else tuple(ids), + name=name, + _ispytest=True, + ) + + # Direct decoration. + if fixture_function: + return fixture_marker(fixture_function) + + return fixture_marker + + +def yield_fixture( + fixture_function=None, + *args, + scope="function", + params=None, + autouse=False, + ids=None, + name=None, +): + """(Return a) decorator to mark a yield-fixture factory function. + + .. deprecated:: 3.0 + Use :py:func:`pytest.fixture` directly instead. + """ + warnings.warn(YIELD_FIXTURE, stacklevel=2) + return fixture( + fixture_function, + *args, + scope=scope, + params=params, + autouse=autouse, + ids=ids, + name=name, + ) + + +@fixture(scope="session") +def pytestconfig(request: FixtureRequest) -> Config: + """Session-scoped fixture that returns the session's :class:`pytest.Config` + object. + + Example:: + + def test_foo(pytestconfig): + if pytestconfig.getoption("verbose") > 0: + ... + + """ + return request.config + + +def pytest_addoption(parser: Parser) -> None: + parser.addini( + "usefixtures", + type="args", + default=[], + help="List of default fixtures to be used with this project", + ) + + +class FixtureManager: + """pytest fixture definitions and information is stored and managed + from this class. + + During collection fm.parsefactories() is called multiple times to parse + fixture function definitions into FixtureDef objects and internal + data structures. + + During collection of test functions, metafunc-mechanics instantiate + a FuncFixtureInfo object which is cached per node/func-name. + This FuncFixtureInfo object is later retrieved by Function nodes + which themselves offer a fixturenames attribute. + + The FuncFixtureInfo object holds information about fixtures and FixtureDefs + relevant for a particular function. An initial list of fixtures is + assembled like this: + + - ini-defined usefixtures + - autouse-marked fixtures along the collection chain up from the function + - usefixtures markers at module/class/function level + - test function funcargs + + Subsequently the funcfixtureinfo.fixturenames attribute is computed + as the closure of the fixtures needed to setup the initial fixtures, + i.e. fixtures needed by fixture functions themselves are appended + to the fixturenames list. + + Upon the test-setup phases all fixturenames are instantiated, retrieved + by a lookup of their FuncFixtureInfo. + """ + + FixtureLookupError = FixtureLookupError + FixtureLookupErrorRepr = FixtureLookupErrorRepr + + def __init__(self, session: "Session") -> None: + self.session = session + self.config: Config = session.config + self._arg2fixturedefs: Dict[str, List[FixtureDef[Any]]] = {} + self._holderobjseen: Set[object] = set() + # A mapping from a nodeid to a list of autouse fixtures it defines. + self._nodeid_autousenames: Dict[str, List[str]] = { + "": self.config.getini("usefixtures"), + } + session.config.pluginmanager.register(self, "funcmanage") + + def _get_direct_parametrize_args(self, node: nodes.Node) -> List[str]: + """Return all direct parametrization arguments of a node, so we don't + mistake them for fixtures. + + Check https://github.com/pytest-dev/pytest/issues/5036. + + These things are done later as well when dealing with parametrization + so this could be improved. + """ + parametrize_argnames: List[str] = [] + for marker in node.iter_markers(name="parametrize"): + if not marker.kwargs.get("indirect", False): + p_argnames, _ = ParameterSet._parse_parametrize_args( + *marker.args, **marker.kwargs + ) + parametrize_argnames.extend(p_argnames) + + return parametrize_argnames + + def getfixtureinfo( + self, node: nodes.Node, func, cls, funcargs: bool = True + ) -> FuncFixtureInfo: + if funcargs and not getattr(node, "nofuncargs", False): + argnames = getfuncargnames(func, name=node.name, cls=cls) + else: + argnames = () + + usefixtures = tuple( + arg for mark in node.iter_markers(name="usefixtures") for arg in mark.args + ) + initialnames = usefixtures + argnames + fm = node.session._fixturemanager + initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure( + initialnames, node, ignore_args=self._get_direct_parametrize_args(node) + ) + return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs) + + def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None: + nodeid = None + try: + p = absolutepath(plugin.__file__) # type: ignore[attr-defined] + except AttributeError: + pass + else: + # Construct the base nodeid which is later used to check + # what fixtures are visible for particular tests (as denoted + # by their test id). + if p.name.startswith("conftest.py"): + try: + nodeid = str(p.parent.relative_to(self.config.rootpath)) + except ValueError: + nodeid = "" + if nodeid == ".": + nodeid = "" + if os.sep != nodes.SEP: + nodeid = nodeid.replace(os.sep, nodes.SEP) + + self.parsefactories(plugin, nodeid) + + def _getautousenames(self, nodeid: str) -> Iterator[str]: + """Return the names of autouse fixtures applicable to nodeid.""" + for parentnodeid in nodes.iterparentnodeids(nodeid): + basenames = self._nodeid_autousenames.get(parentnodeid) + if basenames: + yield from basenames + + def getfixtureclosure( + self, + fixturenames: Tuple[str, ...], + parentnode: nodes.Node, + ignore_args: Sequence[str] = (), + ) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef[Any]]]]: + # Collect the closure of all fixtures, starting with the given + # fixturenames as the initial set. As we have to visit all + # factory definitions anyway, we also return an arg2fixturedefs + # mapping so that the caller can reuse it and does not have + # to re-discover fixturedefs again for each fixturename + # (discovering matching fixtures for a given name/node is expensive). + + parentid = parentnode.nodeid + fixturenames_closure = list(self._getautousenames(parentid)) + + def merge(otherlist: Iterable[str]) -> None: + for arg in otherlist: + if arg not in fixturenames_closure: + fixturenames_closure.append(arg) + + merge(fixturenames) + + # At this point, fixturenames_closure contains what we call "initialnames", + # which is a set of fixturenames the function immediately requests. We + # need to return it as well, so save this. + initialnames = tuple(fixturenames_closure) + + arg2fixturedefs: Dict[str, Sequence[FixtureDef[Any]]] = {} + lastlen = -1 + while lastlen != len(fixturenames_closure): + lastlen = len(fixturenames_closure) + for argname in fixturenames_closure: + if argname in ignore_args: + continue + if argname in arg2fixturedefs: + continue + fixturedefs = self.getfixturedefs(argname, parentid) + if fixturedefs: + arg2fixturedefs[argname] = fixturedefs + merge(fixturedefs[-1].argnames) + + def sort_by_scope(arg_name: str) -> Scope: + try: + fixturedefs = arg2fixturedefs[arg_name] + except KeyError: + return Scope.Function + else: + return fixturedefs[-1]._scope + + fixturenames_closure.sort(key=sort_by_scope, reverse=True) + return initialnames, fixturenames_closure, arg2fixturedefs + + def pytest_generate_tests(self, metafunc: "Metafunc") -> None: + """Generate new tests based on parametrized fixtures used by the given metafunc""" + + def get_parametrize_mark_argnames(mark: Mark) -> Sequence[str]: + args, _ = ParameterSet._parse_parametrize_args(*mark.args, **mark.kwargs) + return args + + for argname in metafunc.fixturenames: + # Get the FixtureDefs for the argname. + fixture_defs = metafunc._arg2fixturedefs.get(argname) + if not fixture_defs: + # Will raise FixtureLookupError at setup time if not parametrized somewhere + # else (e.g @pytest.mark.parametrize) + continue + + # If the test itself parametrizes using this argname, give it + # precedence. + if any( + argname in get_parametrize_mark_argnames(mark) + for mark in metafunc.definition.iter_markers("parametrize") + ): + continue + + # In the common case we only look at the fixture def with the + # closest scope (last in the list). But if the fixture overrides + # another fixture, while requesting the super fixture, keep going + # in case the super fixture is parametrized (#1953). + for fixturedef in reversed(fixture_defs): + # Fixture is parametrized, apply it and stop. + if fixturedef.params is not None: + metafunc.parametrize( + argname, + fixturedef.params, + indirect=True, + scope=fixturedef.scope, + ids=fixturedef.ids, + ) + break + + # Not requesting the overridden super fixture, stop. + if argname not in fixturedef.argnames: + break + + # Try next super fixture, if any. + + def pytest_collection_modifyitems(self, items: List[nodes.Item]) -> None: + # Separate parametrized setups. + items[:] = reorder_items(items) + + @overload + def parsefactories( + self, + node_or_obj: nodes.Node, + *, + unittest: bool = ..., + ) -> None: + raise NotImplementedError() + + @overload + def parsefactories( # noqa: F811 + self, + node_or_obj: object, + nodeid: Optional[str], + *, + unittest: bool = ..., + ) -> None: + raise NotImplementedError() + + def parsefactories( # noqa: F811 + self, + node_or_obj: Union[nodes.Node, object], + nodeid: Union[str, NotSetType, None] = NOTSET, + *, + unittest: bool = False, + ) -> None: + """Collect fixtures from a collection node or object. + + Found fixtures are parsed into `FixtureDef`s and saved. + + If `node_or_object` is a collection node (with an underlying Python + object), the node's object is traversed and the node's nodeid is used to + determine the fixtures' visibilty. `nodeid` must not be specified in + this case. + + If `node_or_object` is an object (e.g. a plugin), the object is + traversed and the given `nodeid` is used to determine the fixtures' + visibility. `nodeid` must be specified in this case; None and "" mean + total visibility. + """ + if nodeid is not NOTSET: + holderobj = node_or_obj + else: + assert isinstance(node_or_obj, nodes.Node) + holderobj = cast(object, node_or_obj.obj) # type: ignore[attr-defined] + assert isinstance(node_or_obj.nodeid, str) + nodeid = node_or_obj.nodeid + if holderobj in self._holderobjseen: + return + + self._holderobjseen.add(holderobj) + autousenames = [] + for name in dir(holderobj): + # ugly workaround for one of the fspath deprecated property of node + # todo: safely generalize + if isinstance(holderobj, nodes.Node) and name == "fspath": + continue + + # The attribute can be an arbitrary descriptor, so the attribute + # access below can raise. safe_getatt() ignores such exceptions. + obj = safe_getattr(holderobj, name, None) + marker = getfixturemarker(obj) + if not isinstance(marker, FixtureFunctionMarker): + # Magic globals with __getattr__ might have got us a wrong + # fixture attribute. + continue + + if marker.name: + name = marker.name + + # During fixture definition we wrap the original fixture function + # to issue a warning if called directly, so here we unwrap it in + # order to not emit the warning when pytest itself calls the + # fixture function. + obj = get_real_method(obj, holderobj) + + fixture_def = FixtureDef( + fixturemanager=self, + baseid=nodeid, + argname=name, + func=obj, + scope=marker.scope, + params=marker.params, + unittest=unittest, + ids=marker.ids, + ) + + faclist = self._arg2fixturedefs.setdefault(name, []) + if fixture_def.has_location: + faclist.append(fixture_def) + else: + # fixturedefs with no location are at the front + # so this inserts the current fixturedef after the + # existing fixturedefs from external plugins but + # before the fixturedefs provided in conftests. + i = len([f for f in faclist if not f.has_location]) + faclist.insert(i, fixture_def) + if marker.autouse: + autousenames.append(name) + + if autousenames: + self._nodeid_autousenames.setdefault(nodeid or "", []).extend(autousenames) + + def getfixturedefs( + self, argname: str, nodeid: str + ) -> Optional[Sequence[FixtureDef[Any]]]: + """Get a list of fixtures which are applicable to the given node id. + + :param str argname: Name of the fixture to search for. + :param str nodeid: Full node id of the requesting test. + :rtype: Sequence[FixtureDef] + """ + try: + fixturedefs = self._arg2fixturedefs[argname] + except KeyError: + return None + return tuple(self._matchfactories(fixturedefs, nodeid)) + + def _matchfactories( + self, fixturedefs: Iterable[FixtureDef[Any]], nodeid: str + ) -> Iterator[FixtureDef[Any]]: + parentnodeids = set(nodes.iterparentnodeids(nodeid)) + for fixturedef in fixturedefs: + if fixturedef.baseid in parentnodeids: + yield fixturedef diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/freeze_support.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/freeze_support.py new file mode 100644 index 00000000..9f8ea231 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/freeze_support.py @@ -0,0 +1,44 @@ +"""Provides a function to report all internal modules for using freezing +tools.""" +import types +from typing import Iterator +from typing import List +from typing import Union + + +def freeze_includes() -> List[str]: + """Return a list of module names used by pytest that should be + included by cx_freeze.""" + import _pytest + + result = list(_iter_all_modules(_pytest)) + return result + + +def _iter_all_modules( + package: Union[str, types.ModuleType], + prefix: str = "", +) -> Iterator[str]: + """Iterate over the names of all modules that can be found in the given + package, recursively. + + >>> import _pytest + >>> list(_iter_all_modules(_pytest)) + ['_pytest._argcomplete', '_pytest._code.code', ...] + """ + import os + import pkgutil + + if isinstance(package, str): + path = package + else: + # Type ignored because typeshed doesn't define ModuleType.__path__ + # (only defined on packages). + package_path = package.__path__ # type: ignore[attr-defined] + path, prefix = package_path[0], package.__name__ + "." + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + "."): + yield prefix + m + else: + yield prefix + name diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/helpconfig.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/helpconfig.py new file mode 100644 index 00000000..ea16c438 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/helpconfig.py @@ -0,0 +1,270 @@ +"""Version info, help messages, tracing configuration.""" +import os +import sys +from argparse import Action +from typing import List +from typing import Optional +from typing import Union + +import pytest +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import PrintHelp +from _pytest.config.argparsing import Parser +from _pytest.terminal import TerminalReporter + + +class HelpAction(Action): + """An argparse Action that will raise an exception in order to skip the + rest of the argument parsing when --help is passed. + + This prevents argparse from quitting due to missing required arguments + when any are defined, for example by ``pytest_addoption``. + This is similar to the way that the builtin argparse --help option is + implemented by raising SystemExit. + """ + + def __init__(self, option_strings, dest=None, default=False, help=None): + super().__init__( + option_strings=option_strings, + dest=dest, + const=True, + default=default, + nargs=0, + help=help, + ) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, self.const) + + # We should only skip the rest of the parsing after preparse is done. + if getattr(parser._parser, "after_preparse", False): + raise PrintHelp + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("debugconfig") + group.addoption( + "--version", + "-V", + action="count", + default=0, + dest="version", + help="Display pytest version and information about plugins. " + "When given twice, also display information about plugins.", + ) + group._addoption( + "-h", + "--help", + action=HelpAction, + dest="help", + help="Show help message and configuration info", + ) + group._addoption( + "-p", + action="append", + dest="plugins", + default=[], + metavar="name", + help="Early-load given plugin module name or entry point (multi-allowed). " + "To avoid loading of plugins, use the `no:` prefix, e.g. " + "`no:doctest`.", + ) + group.addoption( + "--traceconfig", + "--trace-config", + action="store_true", + default=False, + help="Trace considerations of conftest.py files", + ) + group.addoption( + "--debug", + action="store", + nargs="?", + const="pytestdebug.log", + dest="debug", + metavar="DEBUG_FILE_NAME", + help="Store internal tracing debug information in this log file. " + "This file is opened with 'w' and truncated as a result, care advised. " + "Default: pytestdebug.log.", + ) + group._addoption( + "-o", + "--override-ini", + dest="override_ini", + action="append", + help='Override ini option with "option=value" style, ' + "e.g. `-o xfail_strict=True -o cache_dir=cache`.", + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_cmdline_parse(): + outcome = yield + config: Config = outcome.get_result() + + if config.option.debug: + # --debug | --debug was provided. + path = config.option.debug + debugfile = open(path, "w", encoding="utf-8") + debugfile.write( + "versions pytest-%s, " + "python-%s\ncwd=%s\nargs=%s\n\n" + % ( + pytest.__version__, + ".".join(map(str, sys.version_info)), + os.getcwd(), + config.invocation_params.args, + ) + ) + config.trace.root.setwriter(debugfile.write) + undo_tracing = config.pluginmanager.enable_tracing() + sys.stderr.write("writing pytest debug information to %s\n" % path) + + def unset_tracing() -> None: + debugfile.close() + sys.stderr.write("wrote pytest debug information to %s\n" % debugfile.name) + config.trace.root.setwriter(None) + undo_tracing() + + config.add_cleanup(unset_tracing) + + +def showversion(config: Config) -> None: + if config.option.version > 1: + sys.stdout.write( + "This is pytest version {}, imported from {}\n".format( + pytest.__version__, pytest.__file__ + ) + ) + plugininfo = getpluginversioninfo(config) + if plugininfo: + for line in plugininfo: + sys.stdout.write(line + "\n") + else: + sys.stdout.write(f"pytest {pytest.__version__}\n") + + +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + if config.option.version > 0: + showversion(config) + return 0 + elif config.option.help: + config._do_configure() + showhelp(config) + config._ensure_unconfigure() + return 0 + return None + + +def showhelp(config: Config) -> None: + import textwrap + + reporter: Optional[TerminalReporter] = config.pluginmanager.get_plugin( + "terminalreporter" + ) + assert reporter is not None + tw = reporter._tw + tw.write(config._parser.optparser.format_help()) + tw.line() + tw.line( + "[pytest] ini-options in the first " + "pytest.ini|tox.ini|setup.cfg|pyproject.toml file found:" + ) + tw.line() + + columns = tw.fullwidth # costly call + indent_len = 24 # based on argparse's max_help_position=24 + indent = " " * indent_len + for name in config._parser._ininames: + help, type, default = config._parser._inidict[name] + if type is None: + type = "string" + if help is None: + raise TypeError(f"help argument cannot be None for {name}") + spec = f"{name} ({type}):" + tw.write(" %s" % spec) + spec_len = len(spec) + if spec_len > (indent_len - 3): + # Display help starting at a new line. + tw.line() + helplines = textwrap.wrap( + help, + columns, + initial_indent=indent, + subsequent_indent=indent, + break_on_hyphens=False, + ) + + for line in helplines: + tw.line(line) + else: + # Display help starting after the spec, following lines indented. + tw.write(" " * (indent_len - spec_len - 2)) + wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False) + + if wrapped: + tw.line(wrapped[0]) + for line in wrapped[1:]: + tw.line(indent + line) + + tw.line() + tw.line("Environment variables:") + vars = [ + ("PYTEST_ADDOPTS", "Extra command line options"), + ("PYTEST_PLUGINS", "Comma-separated plugins to load during startup"), + ("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "Set to disable plugin auto-loading"), + ("PYTEST_DEBUG", "Set to enable debug tracing of pytest's internals"), + ] + for name, help in vars: + tw.line(f" {name:<24} {help}") + tw.line() + tw.line() + + tw.line("to see available markers type: pytest --markers") + tw.line("to see available fixtures type: pytest --fixtures") + tw.line( + "(shown according to specified file_or_dir or current dir " + "if not specified; fixtures with leading '_' are only shown " + "with the '-v' option" + ) + + for warningreport in reporter.stats.get("warnings", []): + tw.line("warning : " + warningreport.message, red=True) + return + + +conftest_options = [("pytest_plugins", "list of plugin names to load")] + + +def getpluginversioninfo(config: Config) -> List[str]: + lines = [] + plugininfo = config.pluginmanager.list_plugin_distinfo() + if plugininfo: + lines.append("setuptools registered plugins:") + for plugin, dist in plugininfo: + loc = getattr(plugin, "__file__", repr(plugin)) + content = f"{dist.project_name}-{dist.version} at {loc}" + lines.append(" " + content) + return lines + + +def pytest_report_header(config: Config) -> List[str]: + lines = [] + if config.option.debug or config.option.traceconfig: + lines.append(f"using: pytest-{pytest.__version__}") + + verinfo = getpluginversioninfo(config) + if verinfo: + lines.extend(verinfo) + + if config.option.traceconfig: + lines.append("active plugins:") + items = config.pluginmanager.list_name_plugin() + for name, plugin in items: + if hasattr(plugin, "__file__"): + r = plugin.__file__ + else: + r = repr(plugin) + lines.append(f" {name:<20}: {r}") + return lines diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/hookspec.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/hookspec.py new file mode 100644 index 00000000..1f7c368f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/hookspec.py @@ -0,0 +1,979 @@ +"""Hook specifications for pytest plugins which are invoked by pytest itself +and by builtin plugins.""" +from pathlib import Path +from typing import Any +from typing import Dict +from typing import List +from typing import Mapping +from typing import Optional +from typing import Sequence +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +from pluggy import HookspecMarker + +from _pytest.deprecated import WARNING_CMDLINE_PREPARSE_HOOK + +if TYPE_CHECKING: + import pdb + import warnings + from typing_extensions import Literal + + from _pytest._code.code import ExceptionRepr + from _pytest._code.code import ExceptionInfo + from _pytest.config import Config + from _pytest.config import ExitCode + from _pytest.config import PytestPluginManager + from _pytest.config import _PluggyPlugin + from _pytest.config.argparsing import Parser + from _pytest.fixtures import FixtureDef + from _pytest.fixtures import SubRequest + from _pytest.main import Session + from _pytest.nodes import Collector + from _pytest.nodes import Item + from _pytest.outcomes import Exit + from _pytest.python import Class + from _pytest.python import Function + from _pytest.python import Metafunc + from _pytest.python import Module + from _pytest.reports import CollectReport + from _pytest.reports import TestReport + from _pytest.runner import CallInfo + from _pytest.terminal import TerminalReporter + from _pytest.terminal import TestShortLogReport + from _pytest.compat import LEGACY_PATH + + +hookspec = HookspecMarker("pytest") + +# ------------------------------------------------------------------------- +# Initialization hooks called for every plugin +# ------------------------------------------------------------------------- + + +@hookspec(historic=True) +def pytest_addhooks(pluginmanager: "PytestPluginManager") -> None: + """Called at plugin registration time to allow adding new hooks via a call to + ``pluginmanager.add_hookspecs(module_or_class, prefix)``. + + :param pytest.PytestPluginManager pluginmanager: The pytest plugin manager. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True) +def pytest_plugin_registered( + plugin: "_PluggyPlugin", manager: "PytestPluginManager" +) -> None: + """A new pytest plugin got registered. + + :param plugin: The plugin module or instance. + :param pytest.PytestPluginManager manager: pytest plugin manager. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True) +def pytest_addoption(parser: "Parser", pluginmanager: "PytestPluginManager") -> None: + """Register argparse-style options and ini-style config values, + called once at the beginning of a test run. + + .. note:: + + This function should be implemented only in plugins or ``conftest.py`` + files situated at the tests root directory due to how pytest + :ref:`discovers plugins during startup `. + + :param pytest.Parser parser: + To add command line options, call + :py:func:`parser.addoption(...) `. + To add ini-file values call :py:func:`parser.addini(...) + `. + + :param pytest.PytestPluginManager pluginmanager: + The pytest plugin manager, which can be used to install :py:func:`hookspec`'s + or :py:func:`hookimpl`'s and allow one plugin to call another plugin's hooks + to change how command line options are added. + + Options can later be accessed through the + :py:class:`config ` object, respectively: + + - :py:func:`config.getoption(name) ` to + retrieve the value of a command line option. + + - :py:func:`config.getini(name) ` to retrieve + a value read from an ini-style file. + + The config object is passed around on many internal objects via the ``.config`` + attribute or can be retrieved as the ``pytestconfig`` fixture. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True) +def pytest_configure(config: "Config") -> None: + """Allow plugins and conftest files to perform initial configuration. + + This hook is called for every plugin and initial conftest file + after command line options have been parsed. + + After that, the hook is called for other conftest files as they are + imported. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + + :param pytest.Config config: The pytest config object. + """ + + +# ------------------------------------------------------------------------- +# Bootstrapping hooks called for plugins registered early enough: +# internal and 3rd party plugins. +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_cmdline_parse( + pluginmanager: "PytestPluginManager", args: List[str] +) -> Optional["Config"]: + """Return an initialized :class:`~pytest.Config`, parsing the specified args. + + Stops at first non-None result, see :ref:`firstresult`. + + .. note:: + This hook will only be called for plugin classes passed to the + ``plugins`` arg when using `pytest.main`_ to perform an in-process + test run. + + :param pluginmanager: The pytest plugin manager. + :param args: List of arguments passed on the command line. + :returns: A pytest config object. + """ + + +@hookspec(warn_on_impl=WARNING_CMDLINE_PREPARSE_HOOK) +def pytest_cmdline_preparse(config: "Config", args: List[str]) -> None: + """(**Deprecated**) modify command line arguments before option parsing. + + This hook is considered deprecated and will be removed in a future pytest version. Consider + using :hook:`pytest_load_initial_conftests` instead. + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + :param config: The pytest config object. + :param args: Arguments passed on the command line. + """ + + +@hookspec(firstresult=True) +def pytest_cmdline_main(config: "Config") -> Optional[Union["ExitCode", int]]: + """Called for performing the main command line action. The default + implementation will invoke the configure hooks and runtest_mainloop. + + Stops at first non-None result, see :ref:`firstresult`. + + :param config: The pytest config object. + :returns: The exit code. + """ + + +def pytest_load_initial_conftests( + early_config: "Config", parser: "Parser", args: List[str] +) -> None: + """Called to implement the loading of initial conftest files ahead + of command line option parsing. + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + :param early_config: The pytest config object. + :param args: Arguments passed on the command line. + :param parser: To add command line options. + """ + + +# ------------------------------------------------------------------------- +# collection hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_collection(session: "Session") -> Optional[object]: + """Perform the collection phase for the given session. + + Stops at first non-None result, see :ref:`firstresult`. + The return value is not used, but only stops further processing. + + The default collection phase is this (see individual hooks for full details): + + 1. Starting from ``session`` as the initial collector: + + 1. ``pytest_collectstart(collector)`` + 2. ``report = pytest_make_collect_report(collector)`` + 3. ``pytest_exception_interact(collector, call, report)`` if an interactive exception occurred + 4. For each collected node: + + 1. If an item, ``pytest_itemcollected(item)`` + 2. If a collector, recurse into it. + + 5. ``pytest_collectreport(report)`` + + 2. ``pytest_collection_modifyitems(session, config, items)`` + + 1. ``pytest_deselected(items)`` for any deselected items (may be called multiple times) + + 3. ``pytest_collection_finish(session)`` + 4. Set ``session.items`` to the list of collected items + 5. Set ``session.testscollected`` to the number of collected items + + You can implement this hook to only perform some action before collection, + for example the terminal plugin uses it to start displaying the collection + counter (and returns `None`). + + :param session: The pytest session object. + """ + + +def pytest_collection_modifyitems( + session: "Session", config: "Config", items: List["Item"] +) -> None: + """Called after collection has been performed. May filter or re-order + the items in-place. + + :param session: The pytest session object. + :param config: The pytest config object. + :param items: List of item objects. + """ + + +def pytest_collection_finish(session: "Session") -> None: + """Called after collection has been performed and modified. + + :param session: The pytest session object. + """ + + +@hookspec(firstresult=True) +def pytest_ignore_collect( + collection_path: Path, path: "LEGACY_PATH", config: "Config" +) -> Optional[bool]: + """Return True to prevent considering this path for collection. + + This hook is consulted for all files and directories prior to calling + more specific hooks. + + Stops at first non-None result, see :ref:`firstresult`. + + :param collection_path: The path to analyze. + :param path: The path to analyze (deprecated). + :param config: The pytest config object. + + .. versionchanged:: 7.0.0 + The ``collection_path`` parameter was added as a :class:`pathlib.Path` + equivalent of the ``path`` parameter. The ``path`` parameter + has been deprecated. + """ + + +def pytest_collect_file( + file_path: Path, path: "LEGACY_PATH", parent: "Collector" +) -> "Optional[Collector]": + """Create a :class:`~pytest.Collector` for the given path, or None if not relevant. + + The new node needs to have the specified ``parent`` as a parent. + + :param file_path: The path to analyze. + :param path: The path to collect (deprecated). + + .. versionchanged:: 7.0.0 + The ``file_path`` parameter was added as a :class:`pathlib.Path` + equivalent of the ``path`` parameter. The ``path`` parameter + has been deprecated. + """ + + +# logging hooks for collection + + +def pytest_collectstart(collector: "Collector") -> None: + """Collector starts collecting. + + :param collector: + The collector. + """ + + +def pytest_itemcollected(item: "Item") -> None: + """We just collected a test item. + + :param item: + The item. + """ + + +def pytest_collectreport(report: "CollectReport") -> None: + """Collector finished collecting. + + :param report: + The collect report. + """ + + +def pytest_deselected(items: Sequence["Item"]) -> None: + """Called for deselected test items, e.g. by keyword. + + May be called multiple times. + + :param items: + The items. + """ + + +@hookspec(firstresult=True) +def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectReport]": + """Perform :func:`collector.collect() ` and return + a :class:`~pytest.CollectReport`. + + Stops at first non-None result, see :ref:`firstresult`. + + :param collector: + The collector. + """ + + +# ------------------------------------------------------------------------- +# Python test function related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_pycollect_makemodule( + module_path: Path, path: "LEGACY_PATH", parent +) -> Optional["Module"]: + """Return a :class:`pytest.Module` collector or None for the given path. + + This hook will be called for each matching test module path. + The :hook:`pytest_collect_file` hook needs to be used if you want to + create test modules for files that do not match as a test module. + + Stops at first non-None result, see :ref:`firstresult`. + + :param module_path: The path of the module to collect. + :param path: The path of the module to collect (deprecated). + + .. versionchanged:: 7.0.0 + The ``module_path`` parameter was added as a :class:`pathlib.Path` + equivalent of the ``path`` parameter. + + The ``path`` parameter has been deprecated in favor of ``fspath``. + """ + + +@hookspec(firstresult=True) +def pytest_pycollect_makeitem( + collector: Union["Module", "Class"], name: str, obj: object +) -> Union[None, "Item", "Collector", List[Union["Item", "Collector"]]]: + """Return a custom item/collector for a Python object in a module, or None. + + Stops at first non-None result, see :ref:`firstresult`. + + :param collector: + The module/class collector. + :param name: + The name of the object in the module/class. + :param obj: + The object. + :returns: + The created items/collectors. + """ + + +@hookspec(firstresult=True) +def pytest_pyfunc_call(pyfuncitem: "Function") -> Optional[object]: + """Call underlying test function. + + Stops at first non-None result, see :ref:`firstresult`. + + :param pyfuncitem: + The function item. + """ + + +def pytest_generate_tests(metafunc: "Metafunc") -> None: + """Generate (multiple) parametrized calls to a test function. + + :param metafunc: + The :class:`~pytest.Metafunc` helper for the test function. + """ + + +@hookspec(firstresult=True) +def pytest_make_parametrize_id( + config: "Config", val: object, argname: str +) -> Optional[str]: + """Return a user-friendly string representation of the given ``val`` + that will be used by @pytest.mark.parametrize calls, or None if the hook + doesn't know about ``val``. + + The parameter name is available as ``argname``, if required. + + Stops at first non-None result, see :ref:`firstresult`. + + :param config: The pytest config object. + :param val: The parametrized value. + :param str argname: The automatic parameter name produced by pytest. + """ + + +# ------------------------------------------------------------------------- +# runtest related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_runtestloop(session: "Session") -> Optional[object]: + """Perform the main runtest loop (after collection finished). + + The default hook implementation performs the runtest protocol for all items + collected in the session (``session.items``), unless the collection failed + or the ``collectonly`` pytest option is set. + + If at any point :py:func:`pytest.exit` is called, the loop is + terminated immediately. + + If at any point ``session.shouldfail`` or ``session.shouldstop`` are set, the + loop is terminated after the runtest protocol for the current item is finished. + + :param session: The pytest session object. + + Stops at first non-None result, see :ref:`firstresult`. + The return value is not used, but only stops further processing. + """ + + +@hookspec(firstresult=True) +def pytest_runtest_protocol( + item: "Item", nextitem: "Optional[Item]" +) -> Optional[object]: + """Perform the runtest protocol for a single test item. + + The default runtest protocol is this (see individual hooks for full details): + + - ``pytest_runtest_logstart(nodeid, location)`` + + - Setup phase: + - ``call = pytest_runtest_setup(item)`` (wrapped in ``CallInfo(when="setup")``) + - ``report = pytest_runtest_makereport(item, call)`` + - ``pytest_runtest_logreport(report)`` + - ``pytest_exception_interact(call, report)`` if an interactive exception occurred + + - Call phase, if the the setup passed and the ``setuponly`` pytest option is not set: + - ``call = pytest_runtest_call(item)`` (wrapped in ``CallInfo(when="call")``) + - ``report = pytest_runtest_makereport(item, call)`` + - ``pytest_runtest_logreport(report)`` + - ``pytest_exception_interact(call, report)`` if an interactive exception occurred + + - Teardown phase: + - ``call = pytest_runtest_teardown(item, nextitem)`` (wrapped in ``CallInfo(when="teardown")``) + - ``report = pytest_runtest_makereport(item, call)`` + - ``pytest_runtest_logreport(report)`` + - ``pytest_exception_interact(call, report)`` if an interactive exception occurred + + - ``pytest_runtest_logfinish(nodeid, location)`` + + :param item: Test item for which the runtest protocol is performed. + :param nextitem: The scheduled-to-be-next test item (or None if this is the end my friend). + + Stops at first non-None result, see :ref:`firstresult`. + The return value is not used, but only stops further processing. + """ + + +def pytest_runtest_logstart( + nodeid: str, location: Tuple[str, Optional[int], str] +) -> None: + """Called at the start of running the runtest protocol for a single item. + + See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. + + :param nodeid: Full node ID of the item. + :param location: A tuple of ``(filename, lineno, testname)`` + where ``filename`` is a file path relative to ``config.rootpath`` + and ``lineno`` is 0-based. + """ + + +def pytest_runtest_logfinish( + nodeid: str, location: Tuple[str, Optional[int], str] +) -> None: + """Called at the end of running the runtest protocol for a single item. + + See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. + + :param nodeid: Full node ID of the item. + :param location: A tuple of ``(filename, lineno, testname)`` + where ``filename`` is a file path relative to ``config.rootpath`` + and ``lineno`` is 0-based. + """ + + +def pytest_runtest_setup(item: "Item") -> None: + """Called to perform the setup phase for a test item. + + The default implementation runs ``setup()`` on ``item`` and all of its + parents (which haven't been setup yet). This includes obtaining the + values of fixtures required by the item (which haven't been obtained + yet). + + :param item: + The item. + """ + + +def pytest_runtest_call(item: "Item") -> None: + """Called to run the test for test item (the call phase). + + The default implementation calls ``item.runtest()``. + + :param item: + The item. + """ + + +def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None: + """Called to perform the teardown phase for a test item. + + The default implementation runs the finalizers and calls ``teardown()`` + on ``item`` and all of its parents (which need to be torn down). This + includes running the teardown phase of fixtures required by the item (if + they go out of scope). + + :param item: + The item. + :param nextitem: + The scheduled-to-be-next test item (None if no further test item is + scheduled). This argument is used to perform exact teardowns, i.e. + calling just enough finalizers so that nextitem only needs to call + setup functions. + """ + + +@hookspec(firstresult=True) +def pytest_runtest_makereport( + item: "Item", call: "CallInfo[None]" +) -> Optional["TestReport"]: + """Called to create a :class:`~pytest.TestReport` for each of + the setup, call and teardown runtest phases of a test item. + + See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. + + :param item: The item. + :param call: The :class:`~pytest.CallInfo` for the phase. + + Stops at first non-None result, see :ref:`firstresult`. + """ + + +def pytest_runtest_logreport(report: "TestReport") -> None: + """Process the :class:`~pytest.TestReport` produced for each + of the setup, call and teardown runtest phases of an item. + + See :hook:`pytest_runtest_protocol` for a description of the runtest protocol. + """ + + +@hookspec(firstresult=True) +def pytest_report_to_serializable( + config: "Config", + report: Union["CollectReport", "TestReport"], +) -> Optional[Dict[str, Any]]: + """Serialize the given report object into a data structure suitable for + sending over the wire, e.g. converted to JSON. + + :param config: The pytest config object. + :param report: The report. + """ + + +@hookspec(firstresult=True) +def pytest_report_from_serializable( + config: "Config", + data: Dict[str, Any], +) -> Optional[Union["CollectReport", "TestReport"]]: + """Restore a report object previously serialized with + :hook:`pytest_report_to_serializable`. + + :param config: The pytest config object. + """ + + +# ------------------------------------------------------------------------- +# Fixture related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_fixture_setup( + fixturedef: "FixtureDef[Any]", request: "SubRequest" +) -> Optional[object]: + """Perform fixture setup execution. + + :param fixturdef: + The fixture definition object. + :param request: + The fixture request object. + :returns: + The return value of the call to the fixture function. + + Stops at first non-None result, see :ref:`firstresult`. + + .. note:: + If the fixture function returns None, other implementations of + this hook function will continue to be called, according to the + behavior of the :ref:`firstresult` option. + """ + + +def pytest_fixture_post_finalizer( + fixturedef: "FixtureDef[Any]", request: "SubRequest" +) -> None: + """Called after fixture teardown, but before the cache is cleared, so + the fixture result ``fixturedef.cached_result`` is still available (not + ``None``). + + :param fixturdef: + The fixture definition object. + :param request: + The fixture request object. + """ + + +# ------------------------------------------------------------------------- +# test session related hooks +# ------------------------------------------------------------------------- + + +def pytest_sessionstart(session: "Session") -> None: + """Called after the ``Session`` object has been created and before performing collection + and entering the run test loop. + + :param session: The pytest session object. + """ + + +def pytest_sessionfinish( + session: "Session", + exitstatus: Union[int, "ExitCode"], +) -> None: + """Called after whole test run finished, right before returning the exit status to the system. + + :param session: The pytest session object. + :param exitstatus: The status which pytest will return to the system. + """ + + +def pytest_unconfigure(config: "Config") -> None: + """Called before test process is exited. + + :param config: The pytest config object. + """ + + +# ------------------------------------------------------------------------- +# hooks for customizing the assert methods +# ------------------------------------------------------------------------- + + +def pytest_assertrepr_compare( + config: "Config", op: str, left: object, right: object +) -> Optional[List[str]]: + """Return explanation for comparisons in failing assert expressions. + + Return None for no custom explanation, otherwise return a list + of strings. The strings will be joined by newlines but any newlines + *in* a string will be escaped. Note that all but the first line will + be indented slightly, the intention is for the first line to be a summary. + + :param config: The pytest config object. + :param op: The operator, e.g. `"=="`, `"!="`, `"not in"`. + :param left: The left operand. + :param right: The right operand. + """ + + +def pytest_assertion_pass(item: "Item", lineno: int, orig: str, expl: str) -> None: + """Called whenever an assertion passes. + + .. versionadded:: 5.0 + + Use this hook to do some processing after a passing assertion. + The original assertion information is available in the `orig` string + and the pytest introspected assertion information is available in the + `expl` string. + + This hook must be explicitly enabled by the ``enable_assertion_pass_hook`` + ini-file option: + + .. code-block:: ini + + [pytest] + enable_assertion_pass_hook=true + + You need to **clean the .pyc** files in your project directory and interpreter libraries + when enabling this option, as assertions will require to be re-written. + + :param item: pytest item object of current test. + :param lineno: Line number of the assert statement. + :param orig: String with the original assertion. + :param expl: String with the assert explanation. + """ + + +# ------------------------------------------------------------------------- +# Hooks for influencing reporting (invoked from _pytest_terminal). +# ------------------------------------------------------------------------- + + +def pytest_report_header( # type:ignore[empty-body] + config: "Config", start_path: Path, startdir: "LEGACY_PATH" +) -> Union[str, List[str]]: + """Return a string or list of strings to be displayed as header info for terminal reporting. + + :param config: The pytest config object. + :param start_path: The starting dir. + :param startdir: The starting dir (deprecated). + + .. note:: + + Lines returned by a plugin are displayed before those of plugins which + ran before it. + If you want to have your line(s) displayed first, use + :ref:`trylast=True `. + + .. note:: + + This function should be implemented only in plugins or ``conftest.py`` + files situated at the tests root directory due to how pytest + :ref:`discovers plugins during startup `. + + .. versionchanged:: 7.0.0 + The ``start_path`` parameter was added as a :class:`pathlib.Path` + equivalent of the ``startdir`` parameter. The ``startdir`` parameter + has been deprecated. + """ + + +def pytest_report_collectionfinish( # type:ignore[empty-body] + config: "Config", + start_path: Path, + startdir: "LEGACY_PATH", + items: Sequence["Item"], +) -> Union[str, List[str]]: + """Return a string or list of strings to be displayed after collection + has finished successfully. + + These strings will be displayed after the standard "collected X items" message. + + .. versionadded:: 3.2 + + :param config: The pytest config object. + :param start_path: The starting dir. + :param startdir: The starting dir (deprecated). + :param items: List of pytest items that are going to be executed; this list should not be modified. + + .. note:: + + Lines returned by a plugin are displayed before those of plugins which + ran before it. + If you want to have your line(s) displayed first, use + :ref:`trylast=True `. + + .. versionchanged:: 7.0.0 + The ``start_path`` parameter was added as a :class:`pathlib.Path` + equivalent of the ``startdir`` parameter. The ``startdir`` parameter + has been deprecated. + """ + + +@hookspec(firstresult=True) +def pytest_report_teststatus( # type:ignore[empty-body] + report: Union["CollectReport", "TestReport"], config: "Config" +) -> "TestShortLogReport | Tuple[str, str, Union[str, Tuple[str, Mapping[str, bool]]]]": + """Return result-category, shortletter and verbose word for status + reporting. + + The result-category is a category in which to count the result, for + example "passed", "skipped", "error" or the empty string. + + The shortletter is shown as testing progresses, for example ".", "s", + "E" or the empty string. + + The verbose word is shown as testing progresses in verbose mode, for + example "PASSED", "SKIPPED", "ERROR" or the empty string. + + pytest may style these implicitly according to the report outcome. + To provide explicit styling, return a tuple for the verbose word, + for example ``"rerun", "R", ("RERUN", {"yellow": True})``. + + :param report: The report object whose status is to be returned. + :param config: The pytest config object. + :returns: The test status. + + Stops at first non-None result, see :ref:`firstresult`. + """ + + +def pytest_terminal_summary( + terminalreporter: "TerminalReporter", + exitstatus: "ExitCode", + config: "Config", +) -> None: + """Add a section to terminal summary reporting. + + :param terminalreporter: The internal terminal reporter object. + :param exitstatus: The exit status that will be reported back to the OS. + :param config: The pytest config object. + + .. versionadded:: 4.2 + The ``config`` parameter. + """ + + +@hookspec(historic=True) +def pytest_warning_recorded( + warning_message: "warnings.WarningMessage", + when: "Literal['config', 'collect', 'runtest']", + nodeid: str, + location: Optional[Tuple[str, int, str]], +) -> None: + """Process a warning captured by the internal pytest warnings plugin. + + :param warning_message: + The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains + the same attributes as the parameters of :py:func:`warnings.showwarning`. + + :param when: + Indicates when the warning was captured. Possible values: + + * ``"config"``: during pytest configuration/initialization stage. + * ``"collect"``: during test collection. + * ``"runtest"``: during test execution. + + :param nodeid: + Full id of the item. + + :param location: + When available, holds information about the execution context of the captured + warning (filename, linenumber, function). ``function`` evaluates to + when the execution context is at the module level. + + .. versionadded:: 6.0 + """ + + +# ------------------------------------------------------------------------- +# Hooks for influencing skipping +# ------------------------------------------------------------------------- + + +def pytest_markeval_namespace( # type:ignore[empty-body] + config: "Config", +) -> Dict[str, Any]: + """Called when constructing the globals dictionary used for + evaluating string conditions in xfail/skipif markers. + + This is useful when the condition for a marker requires + objects that are expensive or impossible to obtain during + collection time, which is required by normal boolean + conditions. + + .. versionadded:: 6.2 + + :param config: The pytest config object. + :returns: A dictionary of additional globals to add. + """ + + +# ------------------------------------------------------------------------- +# error handling and internal debugging hooks +# ------------------------------------------------------------------------- + + +def pytest_internalerror( + excrepr: "ExceptionRepr", + excinfo: "ExceptionInfo[BaseException]", +) -> Optional[bool]: + """Called for internal errors. + + Return True to suppress the fallback handling of printing an + INTERNALERROR message directly to sys.stderr. + + :param excrepr: The exception repr object. + :param excinfo: The exception info. + """ + + +def pytest_keyboard_interrupt( + excinfo: "ExceptionInfo[Union[KeyboardInterrupt, Exit]]", +) -> None: + """Called for keyboard interrupt. + + :param excinfo: The exception info. + """ + + +def pytest_exception_interact( + node: Union["Item", "Collector"], + call: "CallInfo[Any]", + report: Union["CollectReport", "TestReport"], +) -> None: + """Called when an exception was raised which can potentially be + interactively handled. + + May be called during collection (see :hook:`pytest_make_collect_report`), + in which case ``report`` is a :class:`CollectReport`. + + May be called during runtest of an item (see :hook:`pytest_runtest_protocol`), + in which case ``report`` is a :class:`TestReport`. + + This hook is not called if the exception that was raised is an internal + exception like ``skip.Exception``. + + :param node: + The item or collector. + :param call: + The call information. Contains the exception. + :param report: + The collection or test report. + """ + + +def pytest_enter_pdb(config: "Config", pdb: "pdb.Pdb") -> None: + """Called upon pdb.set_trace(). + + Can be used by plugins to take special action just before the python + debugger enters interactive mode. + + :param config: The pytest config object. + :param pdb: The Pdb instance. + """ + + +def pytest_leave_pdb(config: "Config", pdb: "pdb.Pdb") -> None: + """Called when leaving pdb (e.g. with continue after pdb.set_trace()). + + Can be used by plugins to take special action just after the python + debugger leaves interactive mode. + + :param config: The pytest config object. + :param pdb: The Pdb instance. + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/junitxml.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/junitxml.py new file mode 100644 index 00000000..9ee35b84 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/junitxml.py @@ -0,0 +1,700 @@ +"""Report test results in JUnit-XML format, for use with Jenkins and build +integration servers. + +Based on initial code from Ross Lawley. + +Output conforms to +https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd +""" +import functools +import os +import platform +import re +import xml.etree.ElementTree as ET +from datetime import datetime +from typing import Callable +from typing import Dict +from typing import List +from typing import Match +from typing import Optional +from typing import Tuple +from typing import Union + +import pytest +from _pytest import nodes +from _pytest import timing +from _pytest._code.code import ExceptionRepr +from _pytest._code.code import ReprFileLocation +from _pytest.config import Config +from _pytest.config import filename_arg +from _pytest.config.argparsing import Parser +from _pytest.fixtures import FixtureRequest +from _pytest.reports import TestReport +from _pytest.stash import StashKey +from _pytest.terminal import TerminalReporter + + +xml_key = StashKey["LogXML"]() + + +def bin_xml_escape(arg: object) -> str: + r"""Visually escape invalid XML characters. + + For example, transforms + 'hello\aworld\b' + into + 'hello#x07world#x08' + Note that the #xABs are *not* XML escapes - missing the ampersand «. + The idea is to escape visually for the user rather than for XML itself. + """ + + def repl(matchobj: Match[str]) -> str: + i = ord(matchobj.group()) + if i <= 0xFF: + return "#x%02X" % i + else: + return "#x%04X" % i + + # The spec range of valid chars is: + # Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + # For an unknown(?) reason, we disallow #x7F (DEL) as well. + illegal_xml_re = ( + "[^\u0009\u000A\u000D\u0020-\u007E\u0080-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]" + ) + return re.sub(illegal_xml_re, repl, str(arg)) + + +def merge_family(left, right) -> None: + result = {} + for kl, vl in left.items(): + for kr, vr in right.items(): + if not isinstance(vl, list): + raise TypeError(type(vl)) + result[kl] = vl + vr + left.update(result) + + +families = {} +families["_base"] = {"testcase": ["classname", "name"]} +families["_base_legacy"] = {"testcase": ["file", "line", "url"]} + +# xUnit 1.x inherits legacy attributes. +families["xunit1"] = families["_base"].copy() +merge_family(families["xunit1"], families["_base_legacy"]) + +# xUnit 2.x uses strict base attributes. +families["xunit2"] = families["_base"] + + +class _NodeReporter: + def __init__(self, nodeid: Union[str, TestReport], xml: "LogXML") -> None: + self.id = nodeid + self.xml = xml + self.add_stats = self.xml.add_stats + self.family = self.xml.family + self.duration = 0.0 + self.properties: List[Tuple[str, str]] = [] + self.nodes: List[ET.Element] = [] + self.attrs: Dict[str, str] = {} + + def append(self, node: ET.Element) -> None: + self.xml.add_stats(node.tag) + self.nodes.append(node) + + def add_property(self, name: str, value: object) -> None: + self.properties.append((str(name), bin_xml_escape(value))) + + def add_attribute(self, name: str, value: object) -> None: + self.attrs[str(name)] = bin_xml_escape(value) + + def make_properties_node(self) -> Optional[ET.Element]: + """Return a Junit node containing custom properties, if any.""" + if self.properties: + properties = ET.Element("properties") + for name, value in self.properties: + properties.append(ET.Element("property", name=name, value=value)) + return properties + return None + + def record_testreport(self, testreport: TestReport) -> None: + names = mangle_test_address(testreport.nodeid) + existing_attrs = self.attrs + classnames = names[:-1] + if self.xml.prefix: + classnames.insert(0, self.xml.prefix) + attrs: Dict[str, str] = { + "classname": ".".join(classnames), + "name": bin_xml_escape(names[-1]), + "file": testreport.location[0], + } + if testreport.location[1] is not None: + attrs["line"] = str(testreport.location[1]) + if hasattr(testreport, "url"): + attrs["url"] = testreport.url + self.attrs = attrs + self.attrs.update(existing_attrs) # Restore any user-defined attributes. + + # Preserve legacy testcase behavior. + if self.family == "xunit1": + return + + # Filter out attributes not permitted by this test family. + # Including custom attributes because they are not valid here. + temp_attrs = {} + for key in self.attrs.keys(): + if key in families[self.family]["testcase"]: + temp_attrs[key] = self.attrs[key] + self.attrs = temp_attrs + + def to_xml(self) -> ET.Element: + testcase = ET.Element("testcase", self.attrs, time="%.3f" % self.duration) + properties = self.make_properties_node() + if properties is not None: + testcase.append(properties) + testcase.extend(self.nodes) + return testcase + + def _add_simple(self, tag: str, message: str, data: Optional[str] = None) -> None: + node = ET.Element(tag, message=message) + node.text = bin_xml_escape(data) + self.append(node) + + def write_captured_output(self, report: TestReport) -> None: + if not self.xml.log_passing_tests and report.passed: + return + + content_out = report.capstdout + content_log = report.caplog + content_err = report.capstderr + if self.xml.logging == "no": + return + content_all = "" + if self.xml.logging in ["log", "all"]: + content_all = self._prepare_content(content_log, " Captured Log ") + if self.xml.logging in ["system-out", "out-err", "all"]: + content_all += self._prepare_content(content_out, " Captured Out ") + self._write_content(report, content_all, "system-out") + content_all = "" + if self.xml.logging in ["system-err", "out-err", "all"]: + content_all += self._prepare_content(content_err, " Captured Err ") + self._write_content(report, content_all, "system-err") + content_all = "" + if content_all: + self._write_content(report, content_all, "system-out") + + def _prepare_content(self, content: str, header: str) -> str: + return "\n".join([header.center(80, "-"), content, ""]) + + def _write_content(self, report: TestReport, content: str, jheader: str) -> None: + tag = ET.Element(jheader) + tag.text = bin_xml_escape(content) + self.append(tag) + + def append_pass(self, report: TestReport) -> None: + self.add_stats("passed") + + def append_failure(self, report: TestReport) -> None: + # msg = str(report.longrepr.reprtraceback.extraline) + if hasattr(report, "wasxfail"): + self._add_simple("skipped", "xfail-marked test passes unexpectedly") + else: + assert report.longrepr is not None + reprcrash: Optional[ReprFileLocation] = getattr( + report.longrepr, "reprcrash", None + ) + if reprcrash is not None: + message = reprcrash.message + else: + message = str(report.longrepr) + message = bin_xml_escape(message) + self._add_simple("failure", message, str(report.longrepr)) + + def append_collect_error(self, report: TestReport) -> None: + # msg = str(report.longrepr.reprtraceback.extraline) + assert report.longrepr is not None + self._add_simple("error", "collection failure", str(report.longrepr)) + + def append_collect_skipped(self, report: TestReport) -> None: + self._add_simple("skipped", "collection skipped", str(report.longrepr)) + + def append_error(self, report: TestReport) -> None: + assert report.longrepr is not None + reprcrash: Optional[ReprFileLocation] = getattr( + report.longrepr, "reprcrash", None + ) + if reprcrash is not None: + reason = reprcrash.message + else: + reason = str(report.longrepr) + + if report.when == "teardown": + msg = f'failed on teardown with "{reason}"' + else: + msg = f'failed on setup with "{reason}"' + self._add_simple("error", bin_xml_escape(msg), str(report.longrepr)) + + def append_skipped(self, report: TestReport) -> None: + if hasattr(report, "wasxfail"): + xfailreason = report.wasxfail + if xfailreason.startswith("reason: "): + xfailreason = xfailreason[8:] + xfailreason = bin_xml_escape(xfailreason) + skipped = ET.Element("skipped", type="pytest.xfail", message=xfailreason) + self.append(skipped) + else: + assert isinstance(report.longrepr, tuple) + filename, lineno, skipreason = report.longrepr + if skipreason.startswith("Skipped: "): + skipreason = skipreason[9:] + details = f"{filename}:{lineno}: {skipreason}" + + skipped = ET.Element("skipped", type="pytest.skip", message=skipreason) + skipped.text = bin_xml_escape(details) + self.append(skipped) + self.write_captured_output(report) + + def finalize(self) -> None: + data = self.to_xml() + self.__dict__.clear() + # Type ignored because mypy doesn't like overriding a method. + # Also the return value doesn't match... + self.to_xml = lambda: data # type: ignore[assignment] + + +def _warn_incompatibility_with_xunit2( + request: FixtureRequest, fixture_name: str +) -> None: + """Emit a PytestWarning about the given fixture being incompatible with newer xunit revisions.""" + from _pytest.warning_types import PytestWarning + + xml = request.config.stash.get(xml_key, None) + if xml is not None and xml.family not in ("xunit1", "legacy"): + request.node.warn( + PytestWarning( + "{fixture_name} is incompatible with junit_family '{family}' (use 'legacy' or 'xunit1')".format( + fixture_name=fixture_name, family=xml.family + ) + ) + ) + + +@pytest.fixture +def record_property(request: FixtureRequest) -> Callable[[str, object], None]: + """Add extra properties to the calling test. + + User properties become part of the test report and are available to the + configured reporters, like JUnit XML. + + The fixture is callable with ``name, value``. The value is automatically + XML-encoded. + + Example:: + + def test_function(record_property): + record_property("example_key", 1) + """ + _warn_incompatibility_with_xunit2(request, "record_property") + + def append_property(name: str, value: object) -> None: + request.node.user_properties.append((name, value)) + + return append_property + + +@pytest.fixture +def record_xml_attribute(request: FixtureRequest) -> Callable[[str, object], None]: + """Add extra xml attributes to the tag for the calling test. + + The fixture is callable with ``name, value``. The value is + automatically XML-encoded. + """ + from _pytest.warning_types import PytestExperimentalApiWarning + + request.node.warn( + PytestExperimentalApiWarning("record_xml_attribute is an experimental feature") + ) + + _warn_incompatibility_with_xunit2(request, "record_xml_attribute") + + # Declare noop + def add_attr_noop(name: str, value: object) -> None: + pass + + attr_func = add_attr_noop + + xml = request.config.stash.get(xml_key, None) + if xml is not None: + node_reporter = xml.node_reporter(request.node.nodeid) + attr_func = node_reporter.add_attribute + + return attr_func + + +def _check_record_param_type(param: str, v: str) -> None: + """Used by record_testsuite_property to check that the given parameter name is of the proper + type.""" + __tracebackhide__ = True + if not isinstance(v, str): + msg = "{param} parameter needs to be a string, but {g} given" # type: ignore[unreachable] + raise TypeError(msg.format(param=param, g=type(v).__name__)) + + +@pytest.fixture(scope="session") +def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object], None]: + """Record a new ```` tag as child of the root ````. + + This is suitable to writing global information regarding the entire test + suite, and is compatible with ``xunit2`` JUnit family. + + This is a ``session``-scoped fixture which is called with ``(name, value)``. Example: + + .. code-block:: python + + def test_foo(record_testsuite_property): + record_testsuite_property("ARCH", "PPC") + record_testsuite_property("STORAGE_TYPE", "CEPH") + + :param name: + The property name. + :param value: + The property value. Will be converted to a string. + + .. warning:: + + Currently this fixture **does not work** with the + `pytest-xdist `__ plugin. See + :issue:`7767` for details. + """ + + __tracebackhide__ = True + + def record_func(name: str, value: object) -> None: + """No-op function in case --junit-xml was not passed in the command-line.""" + __tracebackhide__ = True + _check_record_param_type("name", name) + + xml = request.config.stash.get(xml_key, None) + if xml is not None: + record_func = xml.add_global_property # noqa + return record_func + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("terminal reporting") + group.addoption( + "--junitxml", + "--junit-xml", + action="store", + dest="xmlpath", + metavar="path", + type=functools.partial(filename_arg, optname="--junitxml"), + default=None, + help="Create junit-xml style report file at given path", + ) + group.addoption( + "--junitprefix", + "--junit-prefix", + action="store", + metavar="str", + default=None, + help="Prepend prefix to classnames in junit-xml output", + ) + parser.addini( + "junit_suite_name", "Test suite name for JUnit report", default="pytest" + ) + parser.addini( + "junit_logging", + "Write captured log messages to JUnit report: " + "one of no|log|system-out|system-err|out-err|all", + default="no", + ) + parser.addini( + "junit_log_passing_tests", + "Capture log information for passing tests to JUnit report: ", + type="bool", + default=True, + ) + parser.addini( + "junit_duration_report", + "Duration time to report: one of total|call", + default="total", + ) # choices=['total', 'call']) + parser.addini( + "junit_family", + "Emit XML for schema: one of legacy|xunit1|xunit2", + default="xunit2", + ) + + +def pytest_configure(config: Config) -> None: + xmlpath = config.option.xmlpath + # Prevent opening xmllog on worker nodes (xdist). + if xmlpath and not hasattr(config, "workerinput"): + junit_family = config.getini("junit_family") + config.stash[xml_key] = LogXML( + xmlpath, + config.option.junitprefix, + config.getini("junit_suite_name"), + config.getini("junit_logging"), + config.getini("junit_duration_report"), + junit_family, + config.getini("junit_log_passing_tests"), + ) + config.pluginmanager.register(config.stash[xml_key]) + + +def pytest_unconfigure(config: Config) -> None: + xml = config.stash.get(xml_key, None) + if xml: + del config.stash[xml_key] + config.pluginmanager.unregister(xml) + + +def mangle_test_address(address: str) -> List[str]: + path, possible_open_bracket, params = address.partition("[") + names = path.split("::") + # Convert file path to dotted path. + names[0] = names[0].replace(nodes.SEP, ".") + names[0] = re.sub(r"\.py$", "", names[0]) + # Put any params back. + names[-1] += possible_open_bracket + params + return names + + +class LogXML: + def __init__( + self, + logfile, + prefix: Optional[str], + suite_name: str = "pytest", + logging: str = "no", + report_duration: str = "total", + family="xunit1", + log_passing_tests: bool = True, + ) -> None: + logfile = os.path.expanduser(os.path.expandvars(logfile)) + self.logfile = os.path.normpath(os.path.abspath(logfile)) + self.prefix = prefix + self.suite_name = suite_name + self.logging = logging + self.log_passing_tests = log_passing_tests + self.report_duration = report_duration + self.family = family + self.stats: Dict[str, int] = dict.fromkeys( + ["error", "passed", "failure", "skipped"], 0 + ) + self.node_reporters: Dict[ + Tuple[Union[str, TestReport], object], _NodeReporter + ] = {} + self.node_reporters_ordered: List[_NodeReporter] = [] + self.global_properties: List[Tuple[str, str]] = [] + + # List of reports that failed on call but teardown is pending. + self.open_reports: List[TestReport] = [] + self.cnt_double_fail_tests = 0 + + # Replaces convenience family with real family. + if self.family == "legacy": + self.family = "xunit1" + + def finalize(self, report: TestReport) -> None: + nodeid = getattr(report, "nodeid", report) + # Local hack to handle xdist report order. + workernode = getattr(report, "node", None) + reporter = self.node_reporters.pop((nodeid, workernode)) + + for propname, propvalue in report.user_properties: + reporter.add_property(propname, str(propvalue)) + + if reporter is not None: + reporter.finalize() + + def node_reporter(self, report: Union[TestReport, str]) -> _NodeReporter: + nodeid: Union[str, TestReport] = getattr(report, "nodeid", report) + # Local hack to handle xdist report order. + workernode = getattr(report, "node", None) + + key = nodeid, workernode + + if key in self.node_reporters: + # TODO: breaks for --dist=each + return self.node_reporters[key] + + reporter = _NodeReporter(nodeid, self) + + self.node_reporters[key] = reporter + self.node_reporters_ordered.append(reporter) + + return reporter + + def add_stats(self, key: str) -> None: + if key in self.stats: + self.stats[key] += 1 + + def _opentestcase(self, report: TestReport) -> _NodeReporter: + reporter = self.node_reporter(report) + reporter.record_testreport(report) + return reporter + + def pytest_runtest_logreport(self, report: TestReport) -> None: + """Handle a setup/call/teardown report, generating the appropriate + XML tags as necessary. + + Note: due to plugins like xdist, this hook may be called in interlaced + order with reports from other nodes. For example: + + Usual call order: + -> setup node1 + -> call node1 + -> teardown node1 + -> setup node2 + -> call node2 + -> teardown node2 + + Possible call order in xdist: + -> setup node1 + -> call node1 + -> setup node2 + -> call node2 + -> teardown node2 + -> teardown node1 + """ + close_report = None + if report.passed: + if report.when == "call": # ignore setup/teardown + reporter = self._opentestcase(report) + reporter.append_pass(report) + elif report.failed: + if report.when == "teardown": + # The following vars are needed when xdist plugin is used. + report_wid = getattr(report, "worker_id", None) + report_ii = getattr(report, "item_index", None) + close_report = next( + ( + rep + for rep in self.open_reports + if ( + rep.nodeid == report.nodeid + and getattr(rep, "item_index", None) == report_ii + and getattr(rep, "worker_id", None) == report_wid + ) + ), + None, + ) + if close_report: + # We need to open new testcase in case we have failure in + # call and error in teardown in order to follow junit + # schema. + self.finalize(close_report) + self.cnt_double_fail_tests += 1 + reporter = self._opentestcase(report) + if report.when == "call": + reporter.append_failure(report) + self.open_reports.append(report) + if not self.log_passing_tests: + reporter.write_captured_output(report) + else: + reporter.append_error(report) + elif report.skipped: + reporter = self._opentestcase(report) + reporter.append_skipped(report) + self.update_testcase_duration(report) + if report.when == "teardown": + reporter = self._opentestcase(report) + reporter.write_captured_output(report) + + self.finalize(report) + report_wid = getattr(report, "worker_id", None) + report_ii = getattr(report, "item_index", None) + close_report = next( + ( + rep + for rep in self.open_reports + if ( + rep.nodeid == report.nodeid + and getattr(rep, "item_index", None) == report_ii + and getattr(rep, "worker_id", None) == report_wid + ) + ), + None, + ) + if close_report: + self.open_reports.remove(close_report) + + def update_testcase_duration(self, report: TestReport) -> None: + """Accumulate total duration for nodeid from given report and update + the Junit.testcase with the new total if already created.""" + if self.report_duration == "total" or report.when == self.report_duration: + reporter = self.node_reporter(report) + reporter.duration += getattr(report, "duration", 0.0) + + def pytest_collectreport(self, report: TestReport) -> None: + if not report.passed: + reporter = self._opentestcase(report) + if report.failed: + reporter.append_collect_error(report) + else: + reporter.append_collect_skipped(report) + + def pytest_internalerror(self, excrepr: ExceptionRepr) -> None: + reporter = self.node_reporter("internal") + reporter.attrs.update(classname="pytest", name="internal") + reporter._add_simple("error", "internal error", str(excrepr)) + + def pytest_sessionstart(self) -> None: + self.suite_start_time = timing.time() + + def pytest_sessionfinish(self) -> None: + dirname = os.path.dirname(os.path.abspath(self.logfile)) + # exist_ok avoids filesystem race conditions between checking path existence and requesting creation + os.makedirs(dirname, exist_ok=True) + + with open(self.logfile, "w", encoding="utf-8") as logfile: + suite_stop_time = timing.time() + suite_time_delta = suite_stop_time - self.suite_start_time + + numtests = ( + self.stats["passed"] + + self.stats["failure"] + + self.stats["skipped"] + + self.stats["error"] + - self.cnt_double_fail_tests + ) + logfile.write('') + + suite_node = ET.Element( + "testsuite", + name=self.suite_name, + errors=str(self.stats["error"]), + failures=str(self.stats["failure"]), + skipped=str(self.stats["skipped"]), + tests=str(numtests), + time="%.3f" % suite_time_delta, + timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(), + hostname=platform.node(), + ) + global_properties = self._get_global_properties_node() + if global_properties is not None: + suite_node.append(global_properties) + for node_reporter in self.node_reporters_ordered: + suite_node.append(node_reporter.to_xml()) + testsuites = ET.Element("testsuites") + testsuites.append(suite_node) + logfile.write(ET.tostring(testsuites, encoding="unicode")) + + def pytest_terminal_summary(self, terminalreporter: TerminalReporter) -> None: + terminalreporter.write_sep("-", f"generated xml file: {self.logfile}") + + def add_global_property(self, name: str, value: object) -> None: + __tracebackhide__ = True + _check_record_param_type("name", name) + self.global_properties.append((name, bin_xml_escape(value))) + + def _get_global_properties_node(self) -> Optional[ET.Element]: + """Return a Junit node containing custom properties, if any.""" + if self.global_properties: + properties = ET.Element("properties") + for name, value in self.global_properties: + properties.append(ET.Element("property", name=name, value=value)) + return properties + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/legacypath.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/legacypath.py new file mode 100644 index 00000000..af1d0c07 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/legacypath.py @@ -0,0 +1,479 @@ +"""Add backward compatibility support for the legacy py path type.""" +import dataclasses +import shlex +import subprocess +from pathlib import Path +from typing import List +from typing import Optional +from typing import TYPE_CHECKING +from typing import Union + +from iniconfig import SectionWrapper + +from _pytest.cacheprovider import Cache +from _pytest.compat import final +from _pytest.compat import LEGACY_PATH +from _pytest.compat import legacy_path +from _pytest.config import Config +from _pytest.config import hookimpl +from _pytest.config import PytestPluginManager +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.main import Session +from _pytest.monkeypatch import MonkeyPatch +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.nodes import Node +from _pytest.pytester import HookRecorder +from _pytest.pytester import Pytester +from _pytest.pytester import RunResult +from _pytest.terminal import TerminalReporter +from _pytest.tmpdir import TempPathFactory + +if TYPE_CHECKING: + from typing_extensions import Final + + import pexpect + + +@final +class Testdir: + """ + Similar to :class:`Pytester`, but this class works with legacy legacy_path objects instead. + + All methods just forward to an internal :class:`Pytester` instance, converting results + to `legacy_path` objects as necessary. + """ + + __test__ = False + + CLOSE_STDIN: "Final" = Pytester.CLOSE_STDIN + TimeoutExpired: "Final" = Pytester.TimeoutExpired + + def __init__(self, pytester: Pytester, *, _ispytest: bool = False) -> None: + check_ispytest(_ispytest) + self._pytester = pytester + + @property + def tmpdir(self) -> LEGACY_PATH: + """Temporary directory where tests are executed.""" + return legacy_path(self._pytester.path) + + @property + def test_tmproot(self) -> LEGACY_PATH: + return legacy_path(self._pytester._test_tmproot) + + @property + def request(self): + return self._pytester._request + + @property + def plugins(self): + return self._pytester.plugins + + @plugins.setter + def plugins(self, plugins): + self._pytester.plugins = plugins + + @property + def monkeypatch(self) -> MonkeyPatch: + return self._pytester._monkeypatch + + def make_hook_recorder(self, pluginmanager) -> HookRecorder: + """See :meth:`Pytester.make_hook_recorder`.""" + return self._pytester.make_hook_recorder(pluginmanager) + + def chdir(self) -> None: + """See :meth:`Pytester.chdir`.""" + return self._pytester.chdir() + + def finalize(self) -> None: + """See :meth:`Pytester._finalize`.""" + return self._pytester._finalize() + + def makefile(self, ext, *args, **kwargs) -> LEGACY_PATH: + """See :meth:`Pytester.makefile`.""" + if ext and not ext.startswith("."): + # pytester.makefile is going to throw a ValueError in a way that + # testdir.makefile did not, because + # pathlib.Path is stricter suffixes than py.path + # This ext arguments is likely user error, but since testdir has + # allowed this, we will prepend "." as a workaround to avoid breaking + # testdir usage that worked before + ext = "." + ext + return legacy_path(self._pytester.makefile(ext, *args, **kwargs)) + + def makeconftest(self, source) -> LEGACY_PATH: + """See :meth:`Pytester.makeconftest`.""" + return legacy_path(self._pytester.makeconftest(source)) + + def makeini(self, source) -> LEGACY_PATH: + """See :meth:`Pytester.makeini`.""" + return legacy_path(self._pytester.makeini(source)) + + def getinicfg(self, source: str) -> SectionWrapper: + """See :meth:`Pytester.getinicfg`.""" + return self._pytester.getinicfg(source) + + def makepyprojecttoml(self, source) -> LEGACY_PATH: + """See :meth:`Pytester.makepyprojecttoml`.""" + return legacy_path(self._pytester.makepyprojecttoml(source)) + + def makepyfile(self, *args, **kwargs) -> LEGACY_PATH: + """See :meth:`Pytester.makepyfile`.""" + return legacy_path(self._pytester.makepyfile(*args, **kwargs)) + + def maketxtfile(self, *args, **kwargs) -> LEGACY_PATH: + """See :meth:`Pytester.maketxtfile`.""" + return legacy_path(self._pytester.maketxtfile(*args, **kwargs)) + + def syspathinsert(self, path=None) -> None: + """See :meth:`Pytester.syspathinsert`.""" + return self._pytester.syspathinsert(path) + + def mkdir(self, name) -> LEGACY_PATH: + """See :meth:`Pytester.mkdir`.""" + return legacy_path(self._pytester.mkdir(name)) + + def mkpydir(self, name) -> LEGACY_PATH: + """See :meth:`Pytester.mkpydir`.""" + return legacy_path(self._pytester.mkpydir(name)) + + def copy_example(self, name=None) -> LEGACY_PATH: + """See :meth:`Pytester.copy_example`.""" + return legacy_path(self._pytester.copy_example(name)) + + def getnode(self, config: Config, arg) -> Optional[Union[Item, Collector]]: + """See :meth:`Pytester.getnode`.""" + return self._pytester.getnode(config, arg) + + def getpathnode(self, path): + """See :meth:`Pytester.getpathnode`.""" + return self._pytester.getpathnode(path) + + def genitems(self, colitems: List[Union[Item, Collector]]) -> List[Item]: + """See :meth:`Pytester.genitems`.""" + return self._pytester.genitems(colitems) + + def runitem(self, source): + """See :meth:`Pytester.runitem`.""" + return self._pytester.runitem(source) + + def inline_runsource(self, source, *cmdlineargs): + """See :meth:`Pytester.inline_runsource`.""" + return self._pytester.inline_runsource(source, *cmdlineargs) + + def inline_genitems(self, *args): + """See :meth:`Pytester.inline_genitems`.""" + return self._pytester.inline_genitems(*args) + + def inline_run(self, *args, plugins=(), no_reraise_ctrlc: bool = False): + """See :meth:`Pytester.inline_run`.""" + return self._pytester.inline_run( + *args, plugins=plugins, no_reraise_ctrlc=no_reraise_ctrlc + ) + + def runpytest_inprocess(self, *args, **kwargs) -> RunResult: + """See :meth:`Pytester.runpytest_inprocess`.""" + return self._pytester.runpytest_inprocess(*args, **kwargs) + + def runpytest(self, *args, **kwargs) -> RunResult: + """See :meth:`Pytester.runpytest`.""" + return self._pytester.runpytest(*args, **kwargs) + + def parseconfig(self, *args) -> Config: + """See :meth:`Pytester.parseconfig`.""" + return self._pytester.parseconfig(*args) + + def parseconfigure(self, *args) -> Config: + """See :meth:`Pytester.parseconfigure`.""" + return self._pytester.parseconfigure(*args) + + def getitem(self, source, funcname="test_func"): + """See :meth:`Pytester.getitem`.""" + return self._pytester.getitem(source, funcname) + + def getitems(self, source): + """See :meth:`Pytester.getitems`.""" + return self._pytester.getitems(source) + + def getmodulecol(self, source, configargs=(), withinit=False): + """See :meth:`Pytester.getmodulecol`.""" + return self._pytester.getmodulecol( + source, configargs=configargs, withinit=withinit + ) + + def collect_by_name( + self, modcol: Collector, name: str + ) -> Optional[Union[Item, Collector]]: + """See :meth:`Pytester.collect_by_name`.""" + return self._pytester.collect_by_name(modcol, name) + + def popen( + self, + cmdargs, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=CLOSE_STDIN, + **kw, + ): + """See :meth:`Pytester.popen`.""" + return self._pytester.popen(cmdargs, stdout, stderr, stdin, **kw) + + def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN) -> RunResult: + """See :meth:`Pytester.run`.""" + return self._pytester.run(*cmdargs, timeout=timeout, stdin=stdin) + + def runpython(self, script) -> RunResult: + """See :meth:`Pytester.runpython`.""" + return self._pytester.runpython(script) + + def runpython_c(self, command): + """See :meth:`Pytester.runpython_c`.""" + return self._pytester.runpython_c(command) + + def runpytest_subprocess(self, *args, timeout=None) -> RunResult: + """See :meth:`Pytester.runpytest_subprocess`.""" + return self._pytester.runpytest_subprocess(*args, timeout=timeout) + + def spawn_pytest( + self, string: str, expect_timeout: float = 10.0 + ) -> "pexpect.spawn": + """See :meth:`Pytester.spawn_pytest`.""" + return self._pytester.spawn_pytest(string, expect_timeout=expect_timeout) + + def spawn(self, cmd: str, expect_timeout: float = 10.0) -> "pexpect.spawn": + """See :meth:`Pytester.spawn`.""" + return self._pytester.spawn(cmd, expect_timeout=expect_timeout) + + def __repr__(self) -> str: + return f"" + + def __str__(self) -> str: + return str(self.tmpdir) + + +class LegacyTestdirPlugin: + @staticmethod + @fixture + def testdir(pytester: Pytester) -> Testdir: + """ + Identical to :fixture:`pytester`, and provides an instance whose methods return + legacy ``LEGACY_PATH`` objects instead when applicable. + + New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`. + """ + return Testdir(pytester, _ispytest=True) + + +@final +@dataclasses.dataclass +class TempdirFactory: + """Backward compatibility wrapper that implements :class:`py.path.local` + for :class:`TempPathFactory`. + + .. note:: + These days, it is preferred to use ``tmp_path_factory``. + + :ref:`About the tmpdir and tmpdir_factory fixtures`. + + """ + + _tmppath_factory: TempPathFactory + + def __init__( + self, tmppath_factory: TempPathFactory, *, _ispytest: bool = False + ) -> None: + check_ispytest(_ispytest) + self._tmppath_factory = tmppath_factory + + def mktemp(self, basename: str, numbered: bool = True) -> LEGACY_PATH: + """Same as :meth:`TempPathFactory.mktemp`, but returns a :class:`py.path.local` object.""" + return legacy_path(self._tmppath_factory.mktemp(basename, numbered).resolve()) + + def getbasetemp(self) -> LEGACY_PATH: + """Same as :meth:`TempPathFactory.getbasetemp`, but returns a :class:`py.path.local` object.""" + return legacy_path(self._tmppath_factory.getbasetemp().resolve()) + + +class LegacyTmpdirPlugin: + @staticmethod + @fixture(scope="session") + def tmpdir_factory(request: FixtureRequest) -> TempdirFactory: + """Return a :class:`pytest.TempdirFactory` instance for the test session.""" + # Set dynamically by pytest_configure(). + return request.config._tmpdirhandler # type: ignore + + @staticmethod + @fixture + def tmpdir(tmp_path: Path) -> LEGACY_PATH: + """Return a temporary directory path object which is unique to each test + function invocation, created as a sub directory of the base temporary + directory. + + By default, a new base temporary directory is created each test session, + and old bases are removed after 3 sessions, to aid in debugging. If + ``--basetemp`` is used then it is cleared each session. See :ref:`base + temporary directory`. + + The returned object is a `legacy_path`_ object. + + .. note:: + These days, it is preferred to use ``tmp_path``. + + :ref:`About the tmpdir and tmpdir_factory fixtures`. + + .. _legacy_path: https://py.readthedocs.io/en/latest/path.html + """ + return legacy_path(tmp_path) + + +def Cache_makedir(self: Cache, name: str) -> LEGACY_PATH: + """Return a directory path object with the given name. + + Same as :func:`mkdir`, but returns a legacy py path instance. + """ + return legacy_path(self.mkdir(name)) + + +def FixtureRequest_fspath(self: FixtureRequest) -> LEGACY_PATH: + """(deprecated) The file system path of the test module which collected this test.""" + return legacy_path(self.path) + + +def TerminalReporter_startdir(self: TerminalReporter) -> LEGACY_PATH: + """The directory from which pytest was invoked. + + Prefer to use ``startpath`` which is a :class:`pathlib.Path`. + + :type: LEGACY_PATH + """ + return legacy_path(self.startpath) + + +def Config_invocation_dir(self: Config) -> LEGACY_PATH: + """The directory from which pytest was invoked. + + Prefer to use :attr:`invocation_params.dir `, + which is a :class:`pathlib.Path`. + + :type: LEGACY_PATH + """ + return legacy_path(str(self.invocation_params.dir)) + + +def Config_rootdir(self: Config) -> LEGACY_PATH: + """The path to the :ref:`rootdir `. + + Prefer to use :attr:`rootpath`, which is a :class:`pathlib.Path`. + + :type: LEGACY_PATH + """ + return legacy_path(str(self.rootpath)) + + +def Config_inifile(self: Config) -> Optional[LEGACY_PATH]: + """The path to the :ref:`configfile `. + + Prefer to use :attr:`inipath`, which is a :class:`pathlib.Path`. + + :type: Optional[LEGACY_PATH] + """ + return legacy_path(str(self.inipath)) if self.inipath else None + + +def Session_stardir(self: Session) -> LEGACY_PATH: + """The path from which pytest was invoked. + + Prefer to use ``startpath`` which is a :class:`pathlib.Path`. + + :type: LEGACY_PATH + """ + return legacy_path(self.startpath) + + +def Config__getini_unknown_type( + self, name: str, type: str, value: Union[str, List[str]] +): + if type == "pathlist": + # TODO: This assert is probably not valid in all cases. + assert self.inipath is not None + dp = self.inipath.parent + input_values = shlex.split(value) if isinstance(value, str) else value + return [legacy_path(str(dp / x)) for x in input_values] + else: + raise ValueError(f"unknown configuration type: {type}", value) + + +def Node_fspath(self: Node) -> LEGACY_PATH: + """(deprecated) returns a legacy_path copy of self.path""" + return legacy_path(self.path) + + +def Node_fspath_set(self: Node, value: LEGACY_PATH) -> None: + self.path = Path(value) + + +@hookimpl(tryfirst=True) +def pytest_load_initial_conftests(early_config: Config) -> None: + """Monkeypatch legacy path attributes in several classes, as early as possible.""" + mp = MonkeyPatch() + early_config.add_cleanup(mp.undo) + + # Add Cache.makedir(). + mp.setattr(Cache, "makedir", Cache_makedir, raising=False) + + # Add FixtureRequest.fspath property. + mp.setattr(FixtureRequest, "fspath", property(FixtureRequest_fspath), raising=False) + + # Add TerminalReporter.startdir property. + mp.setattr( + TerminalReporter, "startdir", property(TerminalReporter_startdir), raising=False + ) + + # Add Config.{invocation_dir,rootdir,inifile} properties. + mp.setattr(Config, "invocation_dir", property(Config_invocation_dir), raising=False) + mp.setattr(Config, "rootdir", property(Config_rootdir), raising=False) + mp.setattr(Config, "inifile", property(Config_inifile), raising=False) + + # Add Session.startdir property. + mp.setattr(Session, "startdir", property(Session_stardir), raising=False) + + # Add pathlist configuration type. + mp.setattr(Config, "_getini_unknown_type", Config__getini_unknown_type) + + # Add Node.fspath property. + mp.setattr(Node, "fspath", property(Node_fspath, Node_fspath_set), raising=False) + + +@hookimpl +def pytest_configure(config: Config) -> None: + """Installs the LegacyTmpdirPlugin if the ``tmpdir`` plugin is also installed.""" + if config.pluginmanager.has_plugin("tmpdir"): + mp = MonkeyPatch() + config.add_cleanup(mp.undo) + # Create TmpdirFactory and attach it to the config object. + # + # This is to comply with existing plugins which expect the handler to be + # available at pytest_configure time, but ideally should be moved entirely + # to the tmpdir_factory session fixture. + try: + tmp_path_factory = config._tmp_path_factory # type: ignore[attr-defined] + except AttributeError: + # tmpdir plugin is blocked. + pass + else: + _tmpdirhandler = TempdirFactory(tmp_path_factory, _ispytest=True) + mp.setattr(config, "_tmpdirhandler", _tmpdirhandler, raising=False) + + config.pluginmanager.register(LegacyTmpdirPlugin, "legacypath-tmpdir") + + +@hookimpl +def pytest_plugin_registered(plugin: object, manager: PytestPluginManager) -> None: + # pytester is not loaded by default and is commonly loaded from a conftest, + # so checking for it in `pytest_configure` is not enough. + is_pytester = plugin is manager.get_plugin("pytester") + if is_pytester and not manager.is_registered(LegacyTestdirPlugin): + manager.register(LegacyTestdirPlugin, "legacypath-pytester") diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/logging.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/logging.py new file mode 100644 index 00000000..9f2f1c79 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/logging.py @@ -0,0 +1,920 @@ +"""Access and control log capturing.""" +import io +import logging +import os +import re +from contextlib import contextmanager +from contextlib import nullcontext +from datetime import datetime +from datetime import timedelta +from datetime import timezone +from io import StringIO +from logging import LogRecord +from pathlib import Path +from typing import AbstractSet +from typing import Dict +from typing import Generator +from typing import List +from typing import Mapping +from typing import Optional +from typing import Tuple +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +from _pytest import nodes +from _pytest._io import TerminalWriter +from _pytest.capture import CaptureManager +from _pytest.compat import final +from _pytest.config import _strtobool +from _pytest.config import Config +from _pytest.config import create_terminal_writer +from _pytest.config import hookimpl +from _pytest.config import UsageError +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.main import Session +from _pytest.stash import StashKey +from _pytest.terminal import TerminalReporter + +if TYPE_CHECKING: + logging_StreamHandler = logging.StreamHandler[StringIO] + + from typing_extensions import Literal +else: + logging_StreamHandler = logging.StreamHandler + +DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s" +DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S" +_ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]+m") +caplog_handler_key = StashKey["LogCaptureHandler"]() +caplog_records_key = StashKey[Dict[str, List[logging.LogRecord]]]() + + +def _remove_ansi_escape_sequences(text: str) -> str: + return _ANSI_ESCAPE_SEQ.sub("", text) + + +class DatetimeFormatter(logging.Formatter): + """A logging formatter which formats record with + :func:`datetime.datetime.strftime` formatter instead of + :func:`time.strftime` in case of microseconds in format string. + """ + + def formatTime(self, record: LogRecord, datefmt=None) -> str: + if datefmt and "%f" in datefmt: + ct = self.converter(record.created) + tz = timezone(timedelta(seconds=ct.tm_gmtoff), ct.tm_zone) + # Construct `datetime.datetime` object from `struct_time` + # and msecs information from `record` + dt = datetime(*ct[0:6], microsecond=round(record.msecs * 1000), tzinfo=tz) + return dt.strftime(datefmt) + # Use `logging.Formatter` for non-microsecond formats + return super().formatTime(record, datefmt) + + +class ColoredLevelFormatter(DatetimeFormatter): + """A logging formatter which colorizes the %(levelname)..s part of the + log format passed to __init__.""" + + LOGLEVEL_COLOROPTS: Mapping[int, AbstractSet[str]] = { + logging.CRITICAL: {"red"}, + logging.ERROR: {"red", "bold"}, + logging.WARNING: {"yellow"}, + logging.WARN: {"yellow"}, + logging.INFO: {"green"}, + logging.DEBUG: {"purple"}, + logging.NOTSET: set(), + } + LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*(?:\.\d+)?s)") + + def __init__(self, terminalwriter: TerminalWriter, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + self._terminalwriter = terminalwriter + self._original_fmt = self._style._fmt + self._level_to_fmt_mapping: Dict[int, str] = {} + + for level, color_opts in self.LOGLEVEL_COLOROPTS.items(): + self.add_color_level(level, *color_opts) + + def add_color_level(self, level: int, *color_opts: str) -> None: + """Add or update color opts for a log level. + + :param level: + Log level to apply a style to, e.g. ``logging.INFO``. + :param color_opts: + ANSI escape sequence color options. Capitalized colors indicates + background color, i.e. ``'green', 'Yellow', 'bold'`` will give bold + green text on yellow background. + + .. warning:: + This is an experimental API. + """ + + assert self._fmt is not None + levelname_fmt_match = self.LEVELNAME_FMT_REGEX.search(self._fmt) + if not levelname_fmt_match: + return + levelname_fmt = levelname_fmt_match.group() + + formatted_levelname = levelname_fmt % {"levelname": logging.getLevelName(level)} + + # add ANSI escape sequences around the formatted levelname + color_kwargs = {name: True for name in color_opts} + colorized_formatted_levelname = self._terminalwriter.markup( + formatted_levelname, **color_kwargs + ) + self._level_to_fmt_mapping[level] = self.LEVELNAME_FMT_REGEX.sub( + colorized_formatted_levelname, self._fmt + ) + + def format(self, record: logging.LogRecord) -> str: + fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt) + self._style._fmt = fmt + return super().format(record) + + +class PercentStyleMultiline(logging.PercentStyle): + """A logging style with special support for multiline messages. + + If the message of a record consists of multiple lines, this style + formats the message as if each line were logged separately. + """ + + def __init__(self, fmt: str, auto_indent: Union[int, str, bool, None]) -> None: + super().__init__(fmt) + self._auto_indent = self._get_auto_indent(auto_indent) + + @staticmethod + def _get_auto_indent(auto_indent_option: Union[int, str, bool, None]) -> int: + """Determine the current auto indentation setting. + + Specify auto indent behavior (on/off/fixed) by passing in + extra={"auto_indent": [value]} to the call to logging.log() or + using a --log-auto-indent [value] command line or the + log_auto_indent [value] config option. + + Default behavior is auto-indent off. + + Using the string "True" or "on" or the boolean True as the value + turns auto indent on, using the string "False" or "off" or the + boolean False or the int 0 turns it off, and specifying a + positive integer fixes the indentation position to the value + specified. + + Any other values for the option are invalid, and will silently be + converted to the default. + + :param None|bool|int|str auto_indent_option: + User specified option for indentation from command line, config + or extra kwarg. Accepts int, bool or str. str option accepts the + same range of values as boolean config options, as well as + positive integers represented in str form. + + :returns: + Indentation value, which can be + -1 (automatically determine indentation) or + 0 (auto-indent turned off) or + >0 (explicitly set indentation position). + """ + + if auto_indent_option is None: + return 0 + elif isinstance(auto_indent_option, bool): + if auto_indent_option: + return -1 + else: + return 0 + elif isinstance(auto_indent_option, int): + return int(auto_indent_option) + elif isinstance(auto_indent_option, str): + try: + return int(auto_indent_option) + except ValueError: + pass + try: + if _strtobool(auto_indent_option): + return -1 + except ValueError: + return 0 + + return 0 + + def format(self, record: logging.LogRecord) -> str: + if "\n" in record.message: + if hasattr(record, "auto_indent"): + # Passed in from the "extra={}" kwarg on the call to logging.log(). + auto_indent = self._get_auto_indent(record.auto_indent) # type: ignore[attr-defined] + else: + auto_indent = self._auto_indent + + if auto_indent: + lines = record.message.splitlines() + formatted = self._fmt % {**record.__dict__, "message": lines[0]} + + if auto_indent < 0: + indentation = _remove_ansi_escape_sequences(formatted).find( + lines[0] + ) + else: + # Optimizes logging by allowing a fixed indentation. + indentation = auto_indent + lines[0] = formatted + return ("\n" + " " * indentation).join(lines) + return self._fmt % record.__dict__ + + +def get_option_ini(config: Config, *names: str): + for name in names: + ret = config.getoption(name) # 'default' arg won't work as expected + if ret is None: + ret = config.getini(name) + if ret: + return ret + + +def pytest_addoption(parser: Parser) -> None: + """Add options to control log capturing.""" + group = parser.getgroup("logging") + + def add_option_ini(option, dest, default=None, type=None, **kwargs): + parser.addini( + dest, default=default, type=type, help="Default value for " + option + ) + group.addoption(option, dest=dest, **kwargs) + + add_option_ini( + "--log-level", + dest="log_level", + default=None, + metavar="LEVEL", + help=( + "Level of messages to catch/display." + " Not set by default, so it depends on the root/parent log handler's" + ' effective level, where it is "WARNING" by default.' + ), + ) + add_option_ini( + "--log-format", + dest="log_format", + default=DEFAULT_LOG_FORMAT, + help="Log format used by the logging module", + ) + add_option_ini( + "--log-date-format", + dest="log_date_format", + default=DEFAULT_LOG_DATE_FORMAT, + help="Log date format used by the logging module", + ) + parser.addini( + "log_cli", + default=False, + type="bool", + help='Enable log display during test run (also known as "live logging")', + ) + add_option_ini( + "--log-cli-level", dest="log_cli_level", default=None, help="CLI logging level" + ) + add_option_ini( + "--log-cli-format", + dest="log_cli_format", + default=None, + help="Log format used by the logging module", + ) + add_option_ini( + "--log-cli-date-format", + dest="log_cli_date_format", + default=None, + help="Log date format used by the logging module", + ) + add_option_ini( + "--log-file", + dest="log_file", + default=None, + help="Path to a file when logging will be written to", + ) + add_option_ini( + "--log-file-level", + dest="log_file_level", + default=None, + help="Log file logging level", + ) + add_option_ini( + "--log-file-format", + dest="log_file_format", + default=DEFAULT_LOG_FORMAT, + help="Log format used by the logging module", + ) + add_option_ini( + "--log-file-date-format", + dest="log_file_date_format", + default=DEFAULT_LOG_DATE_FORMAT, + help="Log date format used by the logging module", + ) + add_option_ini( + "--log-auto-indent", + dest="log_auto_indent", + default=None, + help="Auto-indent multiline messages passed to the logging module. Accepts true|on, false|off or an integer.", + ) + group.addoption( + "--log-disable", + action="append", + default=[], + dest="logger_disable", + help="Disable a logger by name. Can be passed multiple times.", + ) + + +_HandlerType = TypeVar("_HandlerType", bound=logging.Handler) + + +# Not using @contextmanager for performance reasons. +class catching_logs: + """Context manager that prepares the whole logging machinery properly.""" + + __slots__ = ("handler", "level", "orig_level") + + def __init__(self, handler: _HandlerType, level: Optional[int] = None) -> None: + self.handler = handler + self.level = level + + def __enter__(self): + root_logger = logging.getLogger() + if self.level is not None: + self.handler.setLevel(self.level) + root_logger.addHandler(self.handler) + if self.level is not None: + self.orig_level = root_logger.level + root_logger.setLevel(min(self.orig_level, self.level)) + return self.handler + + def __exit__(self, type, value, traceback): + root_logger = logging.getLogger() + if self.level is not None: + root_logger.setLevel(self.orig_level) + root_logger.removeHandler(self.handler) + + +class LogCaptureHandler(logging_StreamHandler): + """A logging handler that stores log records and the log text.""" + + def __init__(self) -> None: + """Create a new log handler.""" + super().__init__(StringIO()) + self.records: List[logging.LogRecord] = [] + + def emit(self, record: logging.LogRecord) -> None: + """Keep the log records in a list in addition to the log text.""" + self.records.append(record) + super().emit(record) + + def reset(self) -> None: + self.records = [] + self.stream = StringIO() + + def clear(self) -> None: + self.records.clear() + self.stream = StringIO() + + def handleError(self, record: logging.LogRecord) -> None: + if logging.raiseExceptions: + # Fail the test if the log message is bad (emit failed). + # The default behavior of logging is to print "Logging error" + # to stderr with the call stack and some extra details. + # pytest wants to make such mistakes visible during testing. + raise + + +@final +class LogCaptureFixture: + """Provides access and control of log capturing.""" + + def __init__(self, item: nodes.Node, *, _ispytest: bool = False) -> None: + check_ispytest(_ispytest) + self._item = item + self._initial_handler_level: Optional[int] = None + # Dict of log name -> log level. + self._initial_logger_levels: Dict[Optional[str], int] = {} + self._initial_disabled_logging_level: Optional[int] = None + + def _finalize(self) -> None: + """Finalize the fixture. + + This restores the log levels and the disabled logging levels changed by :meth:`set_level`. + """ + # Restore log levels. + if self._initial_handler_level is not None: + self.handler.setLevel(self._initial_handler_level) + for logger_name, level in self._initial_logger_levels.items(): + logger = logging.getLogger(logger_name) + logger.setLevel(level) + # Disable logging at the original disabled logging level. + if self._initial_disabled_logging_level is not None: + logging.disable(self._initial_disabled_logging_level) + self._initial_disabled_logging_level = None + + @property + def handler(self) -> LogCaptureHandler: + """Get the logging handler used by the fixture.""" + return self._item.stash[caplog_handler_key] + + def get_records( + self, when: "Literal['setup', 'call', 'teardown']" + ) -> List[logging.LogRecord]: + """Get the logging records for one of the possible test phases. + + :param when: + Which test phase to obtain the records from. + Valid values are: "setup", "call" and "teardown". + + :returns: The list of captured records at the given stage. + + .. versionadded:: 3.4 + """ + return self._item.stash[caplog_records_key].get(when, []) + + @property + def text(self) -> str: + """The formatted log text.""" + return _remove_ansi_escape_sequences(self.handler.stream.getvalue()) + + @property + def records(self) -> List[logging.LogRecord]: + """The list of log records.""" + return self.handler.records + + @property + def record_tuples(self) -> List[Tuple[str, int, str]]: + """A list of a stripped down version of log records intended + for use in assertion comparison. + + The format of the tuple is: + + (logger_name, log_level, message) + """ + return [(r.name, r.levelno, r.getMessage()) for r in self.records] + + @property + def messages(self) -> List[str]: + """A list of format-interpolated log messages. + + Unlike 'records', which contains the format string and parameters for + interpolation, log messages in this list are all interpolated. + + Unlike 'text', which contains the output from the handler, log + messages in this list are unadorned with levels, timestamps, etc, + making exact comparisons more reliable. + + Note that traceback or stack info (from :func:`logging.exception` or + the `exc_info` or `stack_info` arguments to the logging functions) is + not included, as this is added by the formatter in the handler. + + .. versionadded:: 3.7 + """ + return [r.getMessage() for r in self.records] + + def clear(self) -> None: + """Reset the list of log records and the captured log text.""" + self.handler.clear() + + def _force_enable_logging( + self, level: Union[int, str], logger_obj: logging.Logger + ) -> int: + """Enable the desired logging level if the global level was disabled via ``logging.disabled``. + + Only enables logging levels greater than or equal to the requested ``level``. + + Does nothing if the desired ``level`` wasn't disabled. + + :param level: + The logger level caplog should capture. + All logging is enabled if a non-standard logging level string is supplied. + Valid level strings are in :data:`logging._nameToLevel`. + :param logger_obj: The logger object to check. + + :return: The original disabled logging level. + """ + original_disable_level: int = logger_obj.manager.disable # type: ignore[attr-defined] + + if isinstance(level, str): + # Try to translate the level string to an int for `logging.disable()` + level = logging.getLevelName(level) + + if not isinstance(level, int): + # The level provided was not valid, so just un-disable all logging. + logging.disable(logging.NOTSET) + elif not logger_obj.isEnabledFor(level): + # Each level is `10` away from other levels. + # https://docs.python.org/3/library/logging.html#logging-levels + disable_level = max(level - 10, logging.NOTSET) + logging.disable(disable_level) + + return original_disable_level + + def set_level(self, level: Union[int, str], logger: Optional[str] = None) -> None: + """Set the threshold level of a logger for the duration of a test. + + Logging messages which are less severe than this level will not be captured. + + .. versionchanged:: 3.4 + The levels of the loggers changed by this function will be + restored to their initial values at the end of the test. + + Will enable the requested logging level if it was disabled via :meth:`logging.disable`. + + :param level: The level. + :param logger: The logger to update. If not given, the root logger. + """ + logger_obj = logging.getLogger(logger) + # Save the original log-level to restore it during teardown. + self._initial_logger_levels.setdefault(logger, logger_obj.level) + logger_obj.setLevel(level) + if self._initial_handler_level is None: + self._initial_handler_level = self.handler.level + self.handler.setLevel(level) + initial_disabled_logging_level = self._force_enable_logging(level, logger_obj) + if self._initial_disabled_logging_level is None: + self._initial_disabled_logging_level = initial_disabled_logging_level + + @contextmanager + def at_level( + self, level: Union[int, str], logger: Optional[str] = None + ) -> Generator[None, None, None]: + """Context manager that sets the level for capturing of logs. After + the end of the 'with' statement the level is restored to its original + value. + + Will enable the requested logging level if it was disabled via :meth:`logging.disable`. + + :param level: The level. + :param logger: The logger to update. If not given, the root logger. + """ + logger_obj = logging.getLogger(logger) + orig_level = logger_obj.level + logger_obj.setLevel(level) + handler_orig_level = self.handler.level + self.handler.setLevel(level) + original_disable_level = self._force_enable_logging(level, logger_obj) + try: + yield + finally: + logger_obj.setLevel(orig_level) + self.handler.setLevel(handler_orig_level) + logging.disable(original_disable_level) + + +@fixture +def caplog(request: FixtureRequest) -> Generator[LogCaptureFixture, None, None]: + """Access and control log capturing. + + Captured logs are available through the following properties/methods:: + + * caplog.messages -> list of format-interpolated log messages + * caplog.text -> string containing formatted log output + * caplog.records -> list of logging.LogRecord instances + * caplog.record_tuples -> list of (logger_name, level, message) tuples + * caplog.clear() -> clear captured records and formatted log output string + """ + result = LogCaptureFixture(request.node, _ispytest=True) + yield result + result._finalize() + + +def get_log_level_for_setting(config: Config, *setting_names: str) -> Optional[int]: + for setting_name in setting_names: + log_level = config.getoption(setting_name) + if log_level is None: + log_level = config.getini(setting_name) + if log_level: + break + else: + return None + + if isinstance(log_level, str): + log_level = log_level.upper() + try: + return int(getattr(logging, log_level, log_level)) + except ValueError as e: + # Python logging does not recognise this as a logging level + raise UsageError( + "'{}' is not recognized as a logging level name for " + "'{}'. Please consider passing the " + "logging level num instead.".format(log_level, setting_name) + ) from e + + +# run after terminalreporter/capturemanager are configured +@hookimpl(trylast=True) +def pytest_configure(config: Config) -> None: + config.pluginmanager.register(LoggingPlugin(config), "logging-plugin") + + +class LoggingPlugin: + """Attaches to the logging module and captures log messages for each test.""" + + def __init__(self, config: Config) -> None: + """Create a new plugin to capture log messages. + + The formatter can be safely shared across all handlers so + create a single one for the entire test session here. + """ + self._config = config + + # Report logging. + self.formatter = self._create_formatter( + get_option_ini(config, "log_format"), + get_option_ini(config, "log_date_format"), + get_option_ini(config, "log_auto_indent"), + ) + self.log_level = get_log_level_for_setting(config, "log_level") + self.caplog_handler = LogCaptureHandler() + self.caplog_handler.setFormatter(self.formatter) + self.report_handler = LogCaptureHandler() + self.report_handler.setFormatter(self.formatter) + + # File logging. + self.log_file_level = get_log_level_for_setting(config, "log_file_level") + log_file = get_option_ini(config, "log_file") or os.devnull + if log_file != os.devnull: + directory = os.path.dirname(os.path.abspath(log_file)) + if not os.path.isdir(directory): + os.makedirs(directory) + + self.log_file_handler = _FileHandler(log_file, mode="w", encoding="UTF-8") + log_file_format = get_option_ini(config, "log_file_format", "log_format") + log_file_date_format = get_option_ini( + config, "log_file_date_format", "log_date_format" + ) + + log_file_formatter = DatetimeFormatter( + log_file_format, datefmt=log_file_date_format + ) + self.log_file_handler.setFormatter(log_file_formatter) + + # CLI/live logging. + self.log_cli_level = get_log_level_for_setting( + config, "log_cli_level", "log_level" + ) + if self._log_cli_enabled(): + terminal_reporter = config.pluginmanager.get_plugin("terminalreporter") + # Guaranteed by `_log_cli_enabled()`. + assert terminal_reporter is not None + capture_manager = config.pluginmanager.get_plugin("capturemanager") + # if capturemanager plugin is disabled, live logging still works. + self.log_cli_handler: Union[ + _LiveLoggingStreamHandler, _LiveLoggingNullHandler + ] = _LiveLoggingStreamHandler(terminal_reporter, capture_manager) + else: + self.log_cli_handler = _LiveLoggingNullHandler() + log_cli_formatter = self._create_formatter( + get_option_ini(config, "log_cli_format", "log_format"), + get_option_ini(config, "log_cli_date_format", "log_date_format"), + get_option_ini(config, "log_auto_indent"), + ) + self.log_cli_handler.setFormatter(log_cli_formatter) + self._disable_loggers(loggers_to_disable=config.option.logger_disable) + + def _disable_loggers(self, loggers_to_disable: List[str]) -> None: + if not loggers_to_disable: + return + + for name in loggers_to_disable: + logger = logging.getLogger(name) + logger.disabled = True + + def _create_formatter(self, log_format, log_date_format, auto_indent): + # Color option doesn't exist if terminal plugin is disabled. + color = getattr(self._config.option, "color", "no") + if color != "no" and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search( + log_format + ): + formatter: logging.Formatter = ColoredLevelFormatter( + create_terminal_writer(self._config), log_format, log_date_format + ) + else: + formatter = DatetimeFormatter(log_format, log_date_format) + + formatter._style = PercentStyleMultiline( + formatter._style._fmt, auto_indent=auto_indent + ) + + return formatter + + def set_log_path(self, fname: str) -> None: + """Set the filename parameter for Logging.FileHandler(). + + Creates parent directory if it does not exist. + + .. warning:: + This is an experimental API. + """ + fpath = Path(fname) + + if not fpath.is_absolute(): + fpath = self._config.rootpath / fpath + + if not fpath.parent.exists(): + fpath.parent.mkdir(exist_ok=True, parents=True) + + # https://github.com/python/mypy/issues/11193 + stream: io.TextIOWrapper = fpath.open(mode="w", encoding="UTF-8") # type: ignore[assignment] + old_stream = self.log_file_handler.setStream(stream) + if old_stream: + old_stream.close() + + def _log_cli_enabled(self): + """Return whether live logging is enabled.""" + enabled = self._config.getoption( + "--log-cli-level" + ) is not None or self._config.getini("log_cli") + if not enabled: + return False + + terminal_reporter = self._config.pluginmanager.get_plugin("terminalreporter") + if terminal_reporter is None: + # terminal reporter is disabled e.g. by pytest-xdist. + return False + + return True + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_sessionstart(self) -> Generator[None, None, None]: + self.log_cli_handler.set_when("sessionstart") + + with catching_logs(self.log_cli_handler, level=self.log_cli_level): + with catching_logs(self.log_file_handler, level=self.log_file_level): + yield + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_collection(self) -> Generator[None, None, None]: + self.log_cli_handler.set_when("collection") + + with catching_logs(self.log_cli_handler, level=self.log_cli_level): + with catching_logs(self.log_file_handler, level=self.log_file_level): + yield + + @hookimpl(hookwrapper=True) + def pytest_runtestloop(self, session: Session) -> Generator[None, None, None]: + if session.config.option.collectonly: + yield + return + + if self._log_cli_enabled() and self._config.getoption("verbose") < 1: + # The verbose flag is needed to avoid messy test progress output. + self._config.option.verbose = 1 + + with catching_logs(self.log_cli_handler, level=self.log_cli_level): + with catching_logs(self.log_file_handler, level=self.log_file_level): + yield # Run all the tests. + + @hookimpl + def pytest_runtest_logstart(self) -> None: + self.log_cli_handler.reset() + self.log_cli_handler.set_when("start") + + @hookimpl + def pytest_runtest_logreport(self) -> None: + self.log_cli_handler.set_when("logreport") + + def _runtest_for(self, item: nodes.Item, when: str) -> Generator[None, None, None]: + """Implement the internals of the pytest_runtest_xxx() hooks.""" + with catching_logs( + self.caplog_handler, + level=self.log_level, + ) as caplog_handler, catching_logs( + self.report_handler, + level=self.log_level, + ) as report_handler: + caplog_handler.reset() + report_handler.reset() + item.stash[caplog_records_key][when] = caplog_handler.records + item.stash[caplog_handler_key] = caplog_handler + + yield + + log = report_handler.stream.getvalue().strip() + item.add_report_section(when, "log", log) + + @hookimpl(hookwrapper=True) + def pytest_runtest_setup(self, item: nodes.Item) -> Generator[None, None, None]: + self.log_cli_handler.set_when("setup") + + empty: Dict[str, List[logging.LogRecord]] = {} + item.stash[caplog_records_key] = empty + yield from self._runtest_for(item, "setup") + + @hookimpl(hookwrapper=True) + def pytest_runtest_call(self, item: nodes.Item) -> Generator[None, None, None]: + self.log_cli_handler.set_when("call") + + yield from self._runtest_for(item, "call") + + @hookimpl(hookwrapper=True) + def pytest_runtest_teardown(self, item: nodes.Item) -> Generator[None, None, None]: + self.log_cli_handler.set_when("teardown") + + yield from self._runtest_for(item, "teardown") + del item.stash[caplog_records_key] + del item.stash[caplog_handler_key] + + @hookimpl + def pytest_runtest_logfinish(self) -> None: + self.log_cli_handler.set_when("finish") + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_sessionfinish(self) -> Generator[None, None, None]: + self.log_cli_handler.set_when("sessionfinish") + + with catching_logs(self.log_cli_handler, level=self.log_cli_level): + with catching_logs(self.log_file_handler, level=self.log_file_level): + yield + + @hookimpl + def pytest_unconfigure(self) -> None: + # Close the FileHandler explicitly. + # (logging.shutdown might have lost the weakref?!) + self.log_file_handler.close() + + +class _FileHandler(logging.FileHandler): + """A logging FileHandler with pytest tweaks.""" + + def handleError(self, record: logging.LogRecord) -> None: + # Handled by LogCaptureHandler. + pass + + +class _LiveLoggingStreamHandler(logging_StreamHandler): + """A logging StreamHandler used by the live logging feature: it will + write a newline before the first log message in each test. + + During live logging we must also explicitly disable stdout/stderr + capturing otherwise it will get captured and won't appear in the + terminal. + """ + + # Officially stream needs to be a IO[str], but TerminalReporter + # isn't. So force it. + stream: TerminalReporter = None # type: ignore + + def __init__( + self, + terminal_reporter: TerminalReporter, + capture_manager: Optional[CaptureManager], + ) -> None: + super().__init__(stream=terminal_reporter) # type: ignore[arg-type] + self.capture_manager = capture_manager + self.reset() + self.set_when(None) + self._test_outcome_written = False + + def reset(self) -> None: + """Reset the handler; should be called before the start of each test.""" + self._first_record_emitted = False + + def set_when(self, when: Optional[str]) -> None: + """Prepare for the given test phase (setup/call/teardown).""" + self._when = when + self._section_name_shown = False + if when == "start": + self._test_outcome_written = False + + def emit(self, record: logging.LogRecord) -> None: + ctx_manager = ( + self.capture_manager.global_and_fixture_disabled() + if self.capture_manager + else nullcontext() + ) + with ctx_manager: + if not self._first_record_emitted: + self.stream.write("\n") + self._first_record_emitted = True + elif self._when in ("teardown", "finish"): + if not self._test_outcome_written: + self._test_outcome_written = True + self.stream.write("\n") + if not self._section_name_shown and self._when: + self.stream.section("live log " + self._when, sep="-", bold=True) + self._section_name_shown = True + super().emit(record) + + def handleError(self, record: logging.LogRecord) -> None: + # Handled by LogCaptureHandler. + pass + + +class _LiveLoggingNullHandler(logging.NullHandler): + """A logging handler used when live logging is disabled.""" + + def reset(self) -> None: + pass + + def set_when(self, when: str) -> None: + pass + + def handleError(self, record: logging.LogRecord) -> None: + # Handled by LogCaptureHandler. + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/main.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/main.py new file mode 100644 index 00000000..ea89a63f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/main.py @@ -0,0 +1,913 @@ +"""Core implementation of the testing process: init, session, runtest loop.""" +import argparse +import dataclasses +import fnmatch +import functools +import importlib +import os +import sys +from pathlib import Path +from typing import Callable +from typing import Dict +from typing import FrozenSet +from typing import Iterator +from typing import List +from typing import Optional +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +import _pytest._code +from _pytest import nodes +from _pytest.compat import final +from _pytest.compat import overload +from _pytest.config import Config +from _pytest.config import directory_arg +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config import PytestPluginManager +from _pytest.config import UsageError +from _pytest.config.argparsing import Parser +from _pytest.fixtures import FixtureManager +from _pytest.outcomes import exit +from _pytest.pathlib import absolutepath +from _pytest.pathlib import bestrelpath +from _pytest.pathlib import fnmatch_ex +from _pytest.pathlib import safe_exists +from _pytest.pathlib import visit +from _pytest.reports import CollectReport +from _pytest.reports import TestReport +from _pytest.runner import collect_one_node +from _pytest.runner import SetupState + + +if TYPE_CHECKING: + from typing_extensions import Literal + + +def pytest_addoption(parser: Parser) -> None: + parser.addini( + "norecursedirs", + "Directory patterns to avoid for recursion", + type="args", + default=[ + "*.egg", + ".*", + "_darcs", + "build", + "CVS", + "dist", + "node_modules", + "venv", + "{arch}", + ], + ) + parser.addini( + "testpaths", + "Directories to search for tests when no files or directories are given on the " + "command line", + type="args", + default=[], + ) + group = parser.getgroup("general", "Running and selection options") + group._addoption( + "-x", + "--exitfirst", + action="store_const", + dest="maxfail", + const=1, + help="Exit instantly on first error or failed test", + ) + group = parser.getgroup("pytest-warnings") + group.addoption( + "-W", + "--pythonwarnings", + action="append", + help="Set which warnings to report, see -W option of Python itself", + ) + parser.addini( + "filterwarnings", + type="linelist", + help="Each line specifies a pattern for " + "warnings.filterwarnings. " + "Processed after -W/--pythonwarnings.", + ) + group._addoption( + "--maxfail", + metavar="num", + action="store", + type=int, + dest="maxfail", + default=0, + help="Exit after first num failures or errors", + ) + group._addoption( + "--strict-config", + action="store_true", + help="Any warnings encountered while parsing the `pytest` section of the " + "configuration file raise errors", + ) + group._addoption( + "--strict-markers", + action="store_true", + help="Markers not registered in the `markers` section of the configuration " + "file raise errors", + ) + group._addoption( + "--strict", + action="store_true", + help="(Deprecated) alias to --strict-markers", + ) + group._addoption( + "-c", + "--config-file", + metavar="FILE", + type=str, + dest="inifilename", + help="Load configuration from `FILE` instead of trying to locate one of the " + "implicit configuration files.", + ) + group._addoption( + "--continue-on-collection-errors", + action="store_true", + default=False, + dest="continue_on_collection_errors", + help="Force test execution even if collection errors occur", + ) + group._addoption( + "--rootdir", + action="store", + dest="rootdir", + help="Define root directory for tests. Can be relative path: 'root_dir', './root_dir', " + "'root_dir/another_dir/'; absolute path: '/home/user/root_dir'; path with variables: " + "'$HOME/root_dir'.", + ) + + group = parser.getgroup("collect", "collection") + group.addoption( + "--collectonly", + "--collect-only", + "--co", + action="store_true", + help="Only collect tests, don't execute them", + ) + group.addoption( + "--pyargs", + action="store_true", + help="Try to interpret all arguments as Python packages", + ) + group.addoption( + "--ignore", + action="append", + metavar="path", + help="Ignore path during collection (multi-allowed)", + ) + group.addoption( + "--ignore-glob", + action="append", + metavar="path", + help="Ignore path pattern during collection (multi-allowed)", + ) + group.addoption( + "--deselect", + action="append", + metavar="nodeid_prefix", + help="Deselect item (via node id prefix) during collection (multi-allowed)", + ) + group.addoption( + "--confcutdir", + dest="confcutdir", + default=None, + metavar="dir", + type=functools.partial(directory_arg, optname="--confcutdir"), + help="Only load conftest.py's relative to specified dir", + ) + group.addoption( + "--noconftest", + action="store_true", + dest="noconftest", + default=False, + help="Don't load any conftest.py files", + ) + group.addoption( + "--keepduplicates", + "--keep-duplicates", + action="store_true", + dest="keepduplicates", + default=False, + help="Keep duplicate tests", + ) + group.addoption( + "--collect-in-virtualenv", + action="store_true", + dest="collect_in_virtualenv", + default=False, + help="Don't ignore tests in a local virtualenv directory", + ) + group.addoption( + "--import-mode", + default="prepend", + choices=["prepend", "append", "importlib"], + dest="importmode", + help="Prepend/append to sys.path when importing test modules and conftest " + "files. Default: prepend.", + ) + + group = parser.getgroup("debugconfig", "test session debugging and configuration") + group.addoption( + "--basetemp", + dest="basetemp", + default=None, + type=validate_basetemp, + metavar="dir", + help=( + "Base temporary directory for this test run. " + "(Warning: this directory is removed if it exists.)" + ), + ) + + +def validate_basetemp(path: str) -> str: + # GH 7119 + msg = "basetemp must not be empty, the current working directory or any parent directory of it" + + # empty path + if not path: + raise argparse.ArgumentTypeError(msg) + + def is_ancestor(base: Path, query: Path) -> bool: + """Return whether query is an ancestor of base.""" + if base == query: + return True + return query in base.parents + + # check if path is an ancestor of cwd + if is_ancestor(Path.cwd(), Path(path).absolute()): + raise argparse.ArgumentTypeError(msg) + + # check symlinks for ancestors + if is_ancestor(Path.cwd().resolve(), Path(path).resolve()): + raise argparse.ArgumentTypeError(msg) + + return path + + +def wrap_session( + config: Config, doit: Callable[[Config, "Session"], Optional[Union[int, ExitCode]]] +) -> Union[int, ExitCode]: + """Skeleton command line program.""" + session = Session.from_config(config) + session.exitstatus = ExitCode.OK + initstate = 0 + try: + try: + config._do_configure() + initstate = 1 + config.hook.pytest_sessionstart(session=session) + initstate = 2 + session.exitstatus = doit(config, session) or 0 + except UsageError: + session.exitstatus = ExitCode.USAGE_ERROR + raise + except Failed: + session.exitstatus = ExitCode.TESTS_FAILED + except (KeyboardInterrupt, exit.Exception): + excinfo = _pytest._code.ExceptionInfo.from_current() + exitstatus: Union[int, ExitCode] = ExitCode.INTERRUPTED + if isinstance(excinfo.value, exit.Exception): + if excinfo.value.returncode is not None: + exitstatus = excinfo.value.returncode + if initstate < 2: + sys.stderr.write(f"{excinfo.typename}: {excinfo.value.msg}\n") + config.hook.pytest_keyboard_interrupt(excinfo=excinfo) + session.exitstatus = exitstatus + except BaseException: + session.exitstatus = ExitCode.INTERNAL_ERROR + excinfo = _pytest._code.ExceptionInfo.from_current() + try: + config.notify_exception(excinfo, config.option) + except exit.Exception as exc: + if exc.returncode is not None: + session.exitstatus = exc.returncode + sys.stderr.write(f"{type(exc).__name__}: {exc}\n") + else: + if isinstance(excinfo.value, SystemExit): + sys.stderr.write("mainloop: caught unexpected SystemExit!\n") + + finally: + # Explicitly break reference cycle. + excinfo = None # type: ignore + os.chdir(session.startpath) + if initstate >= 2: + try: + config.hook.pytest_sessionfinish( + session=session, exitstatus=session.exitstatus + ) + except exit.Exception as exc: + if exc.returncode is not None: + session.exitstatus = exc.returncode + sys.stderr.write(f"{type(exc).__name__}: {exc}\n") + config._ensure_unconfigure() + return session.exitstatus + + +def pytest_cmdline_main(config: Config) -> Union[int, ExitCode]: + return wrap_session(config, _main) + + +def _main(config: Config, session: "Session") -> Optional[Union[int, ExitCode]]: + """Default command line protocol for initialization, session, + running tests and reporting.""" + config.hook.pytest_collection(session=session) + config.hook.pytest_runtestloop(session=session) + + if session.testsfailed: + return ExitCode.TESTS_FAILED + elif session.testscollected == 0: + return ExitCode.NO_TESTS_COLLECTED + return None + + +def pytest_collection(session: "Session") -> None: + session.perform_collect() + + +def pytest_runtestloop(session: "Session") -> bool: + if session.testsfailed and not session.config.option.continue_on_collection_errors: + raise session.Interrupted( + "%d error%s during collection" + % (session.testsfailed, "s" if session.testsfailed != 1 else "") + ) + + if session.config.option.collectonly: + return True + + for i, item in enumerate(session.items): + nextitem = session.items[i + 1] if i + 1 < len(session.items) else None + item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) + if session.shouldfail: + raise session.Failed(session.shouldfail) + if session.shouldstop: + raise session.Interrupted(session.shouldstop) + return True + + +def _in_venv(path: Path) -> bool: + """Attempt to detect if ``path`` is the root of a Virtual Environment by + checking for the existence of the appropriate activate script.""" + bindir = path.joinpath("Scripts" if sys.platform.startswith("win") else "bin") + try: + if not bindir.is_dir(): + return False + except OSError: + return False + activates = ( + "activate", + "activate.csh", + "activate.fish", + "Activate", + "Activate.bat", + "Activate.ps1", + ) + return any(fname.name in activates for fname in bindir.iterdir()) + + +def pytest_ignore_collect(collection_path: Path, config: Config) -> Optional[bool]: + ignore_paths = config._getconftest_pathlist( + "collect_ignore", path=collection_path.parent, rootpath=config.rootpath + ) + ignore_paths = ignore_paths or [] + excludeopt = config.getoption("ignore") + if excludeopt: + ignore_paths.extend(absolutepath(x) for x in excludeopt) + + if collection_path in ignore_paths: + return True + + ignore_globs = config._getconftest_pathlist( + "collect_ignore_glob", path=collection_path.parent, rootpath=config.rootpath + ) + ignore_globs = ignore_globs or [] + excludeglobopt = config.getoption("ignore_glob") + if excludeglobopt: + ignore_globs.extend(absolutepath(x) for x in excludeglobopt) + + if any(fnmatch.fnmatch(str(collection_path), str(glob)) for glob in ignore_globs): + return True + + allow_in_venv = config.getoption("collect_in_virtualenv") + if not allow_in_venv and _in_venv(collection_path): + return True + + if collection_path.is_dir(): + norecursepatterns = config.getini("norecursedirs") + if any(fnmatch_ex(pat, collection_path) for pat in norecursepatterns): + return True + + return None + + +def pytest_collection_modifyitems(items: List[nodes.Item], config: Config) -> None: + deselect_prefixes = tuple(config.getoption("deselect") or []) + if not deselect_prefixes: + return + + remaining = [] + deselected = [] + for colitem in items: + if colitem.nodeid.startswith(deselect_prefixes): + deselected.append(colitem) + else: + remaining.append(colitem) + + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +class FSHookProxy: + def __init__(self, pm: PytestPluginManager, remove_mods) -> None: + self.pm = pm + self.remove_mods = remove_mods + + def __getattr__(self, name: str): + x = self.pm.subset_hook_caller(name, remove_plugins=self.remove_mods) + self.__dict__[name] = x + return x + + +class Interrupted(KeyboardInterrupt): + """Signals that the test run was interrupted.""" + + __module__ = "builtins" # For py3. + + +class Failed(Exception): + """Signals a stop as failed test run.""" + + +@dataclasses.dataclass +class _bestrelpath_cache(Dict[Path, str]): + __slots__ = ("path",) + + path: Path + + def __missing__(self, path: Path) -> str: + r = bestrelpath(self.path, path) + self[path] = r + return r + + +@final +class Session(nodes.FSCollector): + """The root of the collection tree. + + ``Session`` collects the initial paths given as arguments to pytest. + """ + + Interrupted = Interrupted + Failed = Failed + # Set on the session by runner.pytest_sessionstart. + _setupstate: SetupState + # Set on the session by fixtures.pytest_sessionstart. + _fixturemanager: FixtureManager + exitstatus: Union[int, ExitCode] + + def __init__(self, config: Config) -> None: + super().__init__( + path=config.rootpath, + fspath=None, + parent=None, + config=config, + session=self, + nodeid="", + ) + self.testsfailed = 0 + self.testscollected = 0 + self.shouldstop: Union[bool, str] = False + self.shouldfail: Union[bool, str] = False + self.trace = config.trace.root.get("collection") + self._initialpaths: FrozenSet[Path] = frozenset() + + self._bestrelpathcache: Dict[Path, str] = _bestrelpath_cache(config.rootpath) + + self.config.pluginmanager.register(self, name="session") + + @classmethod + def from_config(cls, config: Config) -> "Session": + session: Session = cls._create(config=config) + return session + + def __repr__(self) -> str: + return "<%s %s exitstatus=%r testsfailed=%d testscollected=%d>" % ( + self.__class__.__name__, + self.name, + getattr(self, "exitstatus", ""), + self.testsfailed, + self.testscollected, + ) + + @property + def startpath(self) -> Path: + """The path from which pytest was invoked. + + .. versionadded:: 7.0.0 + """ + return self.config.invocation_params.dir + + def _node_location_to_relpath(self, node_path: Path) -> str: + # bestrelpath is a quite slow function. + return self._bestrelpathcache[node_path] + + @hookimpl(tryfirst=True) + def pytest_collectstart(self) -> None: + if self.shouldfail: + raise self.Failed(self.shouldfail) + if self.shouldstop: + raise self.Interrupted(self.shouldstop) + + @hookimpl(tryfirst=True) + def pytest_runtest_logreport( + self, report: Union[TestReport, CollectReport] + ) -> None: + if report.failed and not hasattr(report, "wasxfail"): + self.testsfailed += 1 + maxfail = self.config.getvalue("maxfail") + if maxfail and self.testsfailed >= maxfail: + self.shouldfail = "stopping after %d failures" % (self.testsfailed) + + pytest_collectreport = pytest_runtest_logreport + + def isinitpath(self, path: Union[str, "os.PathLike[str]"]) -> bool: + # Optimization: Path(Path(...)) is much slower than isinstance. + path_ = path if isinstance(path, Path) else Path(path) + return path_ in self._initialpaths + + def gethookproxy(self, fspath: "os.PathLike[str]"): + # Optimization: Path(Path(...)) is much slower than isinstance. + path = fspath if isinstance(fspath, Path) else Path(fspath) + pm = self.config.pluginmanager + # Check if we have the common case of running + # hooks with all conftest.py files. + my_conftestmodules = pm._getconftestmodules( + path, + self.config.getoption("importmode"), + rootpath=self.config.rootpath, + ) + remove_mods = pm._conftest_plugins.difference(my_conftestmodules) + if remove_mods: + # One or more conftests are not in use at this fspath. + from .config.compat import PathAwareHookProxy + + proxy = PathAwareHookProxy(FSHookProxy(pm, remove_mods)) + else: + # All plugins are active for this fspath. + proxy = self.config.hook + return proxy + + def _recurse(self, direntry: "os.DirEntry[str]") -> bool: + if direntry.name == "__pycache__": + return False + fspath = Path(direntry.path) + ihook = self.gethookproxy(fspath.parent) + if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config): + return False + return True + + def _collectfile( + self, fspath: Path, handle_dupes: bool = True + ) -> Sequence[nodes.Collector]: + assert ( + fspath.is_file() + ), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format( + fspath, fspath.is_dir(), fspath.exists(), fspath.is_symlink() + ) + ihook = self.gethookproxy(fspath) + if not self.isinitpath(fspath): + if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config): + return () + + if handle_dupes: + keepduplicates = self.config.getoption("keepduplicates") + if not keepduplicates: + duplicate_paths = self.config.pluginmanager._duplicatepaths + if fspath in duplicate_paths: + return () + else: + duplicate_paths.add(fspath) + + return ihook.pytest_collect_file(file_path=fspath, parent=self) # type: ignore[no-any-return] + + @overload + def perform_collect( + self, args: Optional[Sequence[str]] = ..., genitems: "Literal[True]" = ... + ) -> Sequence[nodes.Item]: + ... + + @overload + def perform_collect( # noqa: F811 + self, args: Optional[Sequence[str]] = ..., genitems: bool = ... + ) -> Sequence[Union[nodes.Item, nodes.Collector]]: + ... + + def perform_collect( # noqa: F811 + self, args: Optional[Sequence[str]] = None, genitems: bool = True + ) -> Sequence[Union[nodes.Item, nodes.Collector]]: + """Perform the collection phase for this session. + + This is called by the default :hook:`pytest_collection` hook + implementation; see the documentation of this hook for more details. + For testing purposes, it may also be called directly on a fresh + ``Session``. + + This function normally recursively expands any collectors collected + from the session to their items, and only items are returned. For + testing purposes, this may be suppressed by passing ``genitems=False``, + in which case the return value contains these collectors unexpanded, + and ``session.items`` is empty. + """ + if args is None: + args = self.config.args + + self.trace("perform_collect", self, args) + self.trace.root.indent += 1 + + self._notfound: List[Tuple[str, Sequence[nodes.Collector]]] = [] + self._initial_parts: List[Tuple[Path, List[str]]] = [] + self.items: List[nodes.Item] = [] + + hook = self.config.hook + + items: Sequence[Union[nodes.Item, nodes.Collector]] = self.items + try: + initialpaths: List[Path] = [] + for arg in args: + fspath, parts = resolve_collection_argument( + self.config.invocation_params.dir, + arg, + as_pypath=self.config.option.pyargs, + ) + self._initial_parts.append((fspath, parts)) + initialpaths.append(fspath) + self._initialpaths = frozenset(initialpaths) + rep = collect_one_node(self) + self.ihook.pytest_collectreport(report=rep) + self.trace.root.indent -= 1 + if self._notfound: + errors = [] + for arg, collectors in self._notfound: + if collectors: + errors.append( + f"not found: {arg}\n(no name {arg!r} in any of {collectors!r})" + ) + else: + errors.append(f"found no collectors for {arg}") + + raise UsageError(*errors) + if not genitems: + items = rep.result + else: + if rep.passed: + for node in rep.result: + self.items.extend(self.genitems(node)) + + self.config.pluginmanager.check_pending() + hook.pytest_collection_modifyitems( + session=self, config=self.config, items=items + ) + finally: + hook.pytest_collection_finish(session=self) + + self.testscollected = len(items) + return items + + def collect(self) -> Iterator[Union[nodes.Item, nodes.Collector]]: + from _pytest.python import Package + + # Keep track of any collected nodes in here, so we don't duplicate fixtures. + node_cache1: Dict[Path, Sequence[nodes.Collector]] = {} + node_cache2: Dict[Tuple[Type[nodes.Collector], Path], nodes.Collector] = {} + + # Keep track of any collected collectors in matchnodes paths, so they + # are not collected more than once. + matchnodes_cache: Dict[Tuple[Type[nodes.Collector], str], CollectReport] = {} + + # Directories of pkgs with dunder-init files. + pkg_roots: Dict[Path, Package] = {} + + for argpath, names in self._initial_parts: + self.trace("processing argument", (argpath, names)) + self.trace.root.indent += 1 + + # Start with a Session root, and delve to argpath item (dir or file) + # and stack all Packages found on the way. + # No point in finding packages when collecting doctests. + if not self.config.getoption("doctestmodules", False): + pm = self.config.pluginmanager + for parent in (argpath, *argpath.parents): + if not pm._is_in_confcutdir(argpath): + break + + if parent.is_dir(): + pkginit = parent / "__init__.py" + if pkginit.is_file() and pkginit not in node_cache1: + col = self._collectfile(pkginit, handle_dupes=False) + if col: + if isinstance(col[0], Package): + pkg_roots[parent] = col[0] + node_cache1[col[0].path] = [col[0]] + + # If it's a directory argument, recurse and look for any Subpackages. + # Let the Package collector deal with subnodes, don't collect here. + if argpath.is_dir(): + assert not names, f"invalid arg {(argpath, names)!r}" + + seen_dirs: Set[Path] = set() + for direntry in visit(argpath, self._recurse): + if not direntry.is_file(): + continue + + path = Path(direntry.path) + dirpath = path.parent + + if dirpath not in seen_dirs: + # Collect packages first. + seen_dirs.add(dirpath) + pkginit = dirpath / "__init__.py" + if pkginit.exists(): + for x in self._collectfile(pkginit): + yield x + if isinstance(x, Package): + pkg_roots[dirpath] = x + if dirpath in pkg_roots: + # Do not collect packages here. + continue + + for x in self._collectfile(path): + key2 = (type(x), x.path) + if key2 in node_cache2: + yield node_cache2[key2] + else: + node_cache2[key2] = x + yield x + else: + assert argpath.is_file() + + if argpath in node_cache1: + col = node_cache1[argpath] + else: + collect_root = pkg_roots.get(argpath.parent, self) + col = collect_root._collectfile(argpath, handle_dupes=False) + if col: + node_cache1[argpath] = col + + matching = [] + work: List[ + Tuple[Sequence[Union[nodes.Item, nodes.Collector]], Sequence[str]] + ] = [(col, names)] + while work: + self.trace("matchnodes", col, names) + self.trace.root.indent += 1 + + matchnodes, matchnames = work.pop() + for node in matchnodes: + if not matchnames: + matching.append(node) + continue + if not isinstance(node, nodes.Collector): + continue + key = (type(node), node.nodeid) + if key in matchnodes_cache: + rep = matchnodes_cache[key] + else: + rep = collect_one_node(node) + matchnodes_cache[key] = rep + if rep.passed: + submatchnodes = [] + for r in rep.result: + # TODO: Remove parametrized workaround once collection structure contains + # parametrization. + if ( + r.name == matchnames[0] + or r.name.split("[")[0] == matchnames[0] + ): + submatchnodes.append(r) + if submatchnodes: + work.append((submatchnodes, matchnames[1:])) + else: + # Report collection failures here to avoid failing to run some test + # specified in the command line because the module could not be + # imported (#134). + node.ihook.pytest_collectreport(report=rep) + + self.trace("matchnodes finished -> ", len(matching), "nodes") + self.trace.root.indent -= 1 + + if not matching: + report_arg = "::".join((str(argpath), *names)) + self._notfound.append((report_arg, col)) + continue + + # If __init__.py was the only file requested, then the matched + # node will be the corresponding Package (by default), and the + # first yielded item will be the __init__ Module itself, so + # just use that. If this special case isn't taken, then all the + # files in the package will be yielded. + if argpath.name == "__init__.py" and isinstance(matching[0], Package): + try: + yield next(iter(matching[0].collect())) + except StopIteration: + # The package collects nothing with only an __init__.py + # file in it, which gets ignored by the default + # "python_files" option. + pass + continue + + yield from matching + + self.trace.root.indent -= 1 + + def genitems( + self, node: Union[nodes.Item, nodes.Collector] + ) -> Iterator[nodes.Item]: + self.trace("genitems", node) + if isinstance(node, nodes.Item): + node.ihook.pytest_itemcollected(item=node) + yield node + else: + assert isinstance(node, nodes.Collector) + rep = collect_one_node(node) + if rep.passed: + for subnode in rep.result: + yield from self.genitems(subnode) + node.ihook.pytest_collectreport(report=rep) + + +def search_pypath(module_name: str) -> str: + """Search sys.path for the given a dotted module name, and return its file system path.""" + try: + spec = importlib.util.find_spec(module_name) + # AttributeError: looks like package module, but actually filename + # ImportError: module does not exist + # ValueError: not a module name + except (AttributeError, ImportError, ValueError): + return module_name + if spec is None or spec.origin is None or spec.origin == "namespace": + return module_name + elif spec.submodule_search_locations: + return os.path.dirname(spec.origin) + else: + return spec.origin + + +def resolve_collection_argument( + invocation_path: Path, arg: str, *, as_pypath: bool = False +) -> Tuple[Path, List[str]]: + """Parse path arguments optionally containing selection parts and return (fspath, names). + + Command-line arguments can point to files and/or directories, and optionally contain + parts for specific tests selection, for example: + + "pkg/tests/test_foo.py::TestClass::test_foo" + + This function ensures the path exists, and returns a tuple: + + (Path("/full/path/to/pkg/tests/test_foo.py"), ["TestClass", "test_foo"]) + + When as_pypath is True, expects that the command-line argument actually contains + module paths instead of file-system paths: + + "pkg.tests.test_foo::TestClass::test_foo" + + In which case we search sys.path for a matching module, and then return the *path* to the + found module. + + If the path doesn't exist, raise UsageError. + If the path is a directory and selection parts are present, raise UsageError. + """ + base, squacket, rest = str(arg).partition("[") + strpath, *parts = base.split("::") + if parts: + parts[-1] = f"{parts[-1]}{squacket}{rest}" + if as_pypath: + strpath = search_pypath(strpath) + fspath = invocation_path / strpath + fspath = absolutepath(fspath) + if not safe_exists(fspath): + msg = ( + "module or package not found: {arg} (missing __init__.py?)" + if as_pypath + else "file or directory not found: {arg}" + ) + raise UsageError(msg.format(arg=arg)) + if parts and fspath.is_dir(): + msg = ( + "package argument cannot contain :: selection parts: {arg}" + if as_pypath + else "directory argument cannot contain :: selection parts: {arg}" + ) + raise UsageError(msg.format(arg=arg)) + return fspath, parts diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/__init__.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/__init__.py new file mode 100644 index 00000000..de46b4c8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/__init__.py @@ -0,0 +1,269 @@ +"""Generic mechanism for marking and selecting python functions.""" +import dataclasses +from typing import AbstractSet +from typing import Collection +from typing import List +from typing import Optional +from typing import TYPE_CHECKING +from typing import Union + +from .expression import Expression +from .expression import ParseError +from .structures import EMPTY_PARAMETERSET_OPTION +from .structures import get_empty_parameterset_mark +from .structures import Mark +from .structures import MARK_GEN +from .structures import MarkDecorator +from .structures import MarkGenerator +from .structures import ParameterSet +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config import UsageError +from _pytest.config.argparsing import Parser +from _pytest.stash import StashKey + +if TYPE_CHECKING: + from _pytest.nodes import Item + + +__all__ = [ + "MARK_GEN", + "Mark", + "MarkDecorator", + "MarkGenerator", + "ParameterSet", + "get_empty_parameterset_mark", +] + + +old_mark_config_key = StashKey[Optional[Config]]() + + +def param( + *values: object, + marks: Union[MarkDecorator, Collection[Union[MarkDecorator, Mark]]] = (), + id: Optional[str] = None, +) -> ParameterSet: + """Specify a parameter in `pytest.mark.parametrize`_ calls or + :ref:`parametrized fixtures `. + + .. code-block:: python + + @pytest.mark.parametrize( + "test_input,expected", + [ + ("3+5", 8), + pytest.param("6*9", 42, marks=pytest.mark.xfail), + ], + ) + def test_eval(test_input, expected): + assert eval(test_input) == expected + + :param values: Variable args of the values of the parameter set, in order. + :param marks: A single mark or a list of marks to be applied to this parameter set. + :param id: The id to attribute to this parameter set. + """ + return ParameterSet.param(*values, marks=marks, id=id) + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group._addoption( + "-k", + action="store", + dest="keyword", + default="", + metavar="EXPRESSION", + help="Only run tests which match the given substring expression. " + "An expression is a Python evaluatable expression " + "where all names are substring-matched against test names " + "and their parent classes. Example: -k 'test_method or test_" + "other' matches all test functions and classes whose name " + "contains 'test_method' or 'test_other', while -k 'not test_method' " + "matches those that don't contain 'test_method' in their names. " + "-k 'not test_method and not test_other' will eliminate the matches. " + "Additionally keywords are matched to classes and functions " + "containing extra names in their 'extra_keyword_matches' set, " + "as well as functions which have names assigned directly to them. " + "The matching is case-insensitive.", + ) + + group._addoption( + "-m", + action="store", + dest="markexpr", + default="", + metavar="MARKEXPR", + help="Only run tests matching given mark expression. " + "For example: -m 'mark1 and not mark2'.", + ) + + group.addoption( + "--markers", + action="store_true", + help="show markers (builtin, plugin and per-project ones).", + ) + + parser.addini("markers", "Markers for test functions", "linelist") + parser.addini(EMPTY_PARAMETERSET_OPTION, "Default marker for empty parametersets") + + +@hookimpl(tryfirst=True) +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + import _pytest.config + + if config.option.markers: + config._do_configure() + tw = _pytest.config.create_terminal_writer(config) + for line in config.getini("markers"): + parts = line.split(":", 1) + name = parts[0] + rest = parts[1] if len(parts) == 2 else "" + tw.write("@pytest.mark.%s:" % name, bold=True) + tw.line(rest) + tw.line() + config._ensure_unconfigure() + return 0 + + return None + + +@dataclasses.dataclass +class KeywordMatcher: + """A matcher for keywords. + + Given a list of names, matches any substring of one of these names. The + string inclusion check is case-insensitive. + + Will match on the name of colitem, including the names of its parents. + Only matches names of items which are either a :class:`Class` or a + :class:`Function`. + + Additionally, matches on names in the 'extra_keyword_matches' set of + any item, as well as names directly assigned to test functions. + """ + + __slots__ = ("_names",) + + _names: AbstractSet[str] + + @classmethod + def from_item(cls, item: "Item") -> "KeywordMatcher": + mapped_names = set() + + # Add the names of the current item and any parent items. + import pytest + + for node in item.listchain(): + if not isinstance(node, pytest.Session): + mapped_names.add(node.name) + + # Add the names added as extra keywords to current or parent items. + mapped_names.update(item.listextrakeywords()) + + # Add the names attached to the current function through direct assignment. + function_obj = getattr(item, "function", None) + if function_obj: + mapped_names.update(function_obj.__dict__) + + # Add the markers to the keywords as we no longer handle them correctly. + mapped_names.update(mark.name for mark in item.iter_markers()) + + return cls(mapped_names) + + def __call__(self, subname: str) -> bool: + subname = subname.lower() + names = (name.lower() for name in self._names) + + for name in names: + if subname in name: + return True + return False + + +def deselect_by_keyword(items: "List[Item]", config: Config) -> None: + keywordexpr = config.option.keyword.lstrip() + if not keywordexpr: + return + + expr = _parse_expression(keywordexpr, "Wrong expression passed to '-k'") + + remaining = [] + deselected = [] + for colitem in items: + if not expr.evaluate(KeywordMatcher.from_item(colitem)): + deselected.append(colitem) + else: + remaining.append(colitem) + + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +@dataclasses.dataclass +class MarkMatcher: + """A matcher for markers which are present. + + Tries to match on any marker names, attached to the given colitem. + """ + + __slots__ = ("own_mark_names",) + + own_mark_names: AbstractSet[str] + + @classmethod + def from_item(cls, item: "Item") -> "MarkMatcher": + mark_names = {mark.name for mark in item.iter_markers()} + return cls(mark_names) + + def __call__(self, name: str) -> bool: + return name in self.own_mark_names + + +def deselect_by_mark(items: "List[Item]", config: Config) -> None: + matchexpr = config.option.markexpr + if not matchexpr: + return + + expr = _parse_expression(matchexpr, "Wrong expression passed to '-m'") + remaining: List[Item] = [] + deselected: List[Item] = [] + for item in items: + if expr.evaluate(MarkMatcher.from_item(item)): + remaining.append(item) + else: + deselected.append(item) + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +def _parse_expression(expr: str, exc_message: str) -> Expression: + try: + return Expression.compile(expr) + except ParseError as e: + raise UsageError(f"{exc_message}: {expr}: {e}") from None + + +def pytest_collection_modifyitems(items: "List[Item]", config: Config) -> None: + deselect_by_keyword(items, config) + deselect_by_mark(items, config) + + +def pytest_configure(config: Config) -> None: + config.stash[old_mark_config_key] = MARK_GEN._config + MARK_GEN._config = config + + empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION) + + if empty_parameterset not in ("skip", "xfail", "fail_at_collect", None, ""): + raise UsageError( + "{!s} must be one of skip, xfail or fail_at_collect" + " but it is {!r}".format(EMPTY_PARAMETERSET_OPTION, empty_parameterset) + ) + + +def pytest_unconfigure(config: Config) -> None: + MARK_GEN._config = config.stash.get(old_mark_config_key, None) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/expression.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/expression.py new file mode 100644 index 00000000..9287bcee --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/expression.py @@ -0,0 +1,228 @@ +r"""Evaluate match expressions, as used by `-k` and `-m`. + +The grammar is: + +expression: expr? EOF +expr: and_expr ('or' and_expr)* +and_expr: not_expr ('and' not_expr)* +not_expr: 'not' not_expr | '(' expr ')' | ident +ident: (\w|:|\+|-|\.|\[|\]|\\|/)+ + +The semantics are: + +- Empty expression evaluates to False. +- ident evaluates to True of False according to a provided matcher function. +- or/and/not evaluate according to the usual boolean semantics. +""" +import ast +import dataclasses +import enum +import re +import sys +import types +from typing import Callable +from typing import Iterator +from typing import Mapping +from typing import NoReturn +from typing import Optional +from typing import Sequence + +if sys.version_info >= (3, 8): + astNameConstant = ast.Constant +else: + astNameConstant = ast.NameConstant + + +__all__ = [ + "Expression", + "ParseError", +] + + +class TokenType(enum.Enum): + LPAREN = "left parenthesis" + RPAREN = "right parenthesis" + OR = "or" + AND = "and" + NOT = "not" + IDENT = "identifier" + EOF = "end of input" + + +@dataclasses.dataclass(frozen=True) +class Token: + __slots__ = ("type", "value", "pos") + type: TokenType + value: str + pos: int + + +class ParseError(Exception): + """The expression contains invalid syntax. + + :param column: The column in the line where the error occurred (1-based). + :param message: A description of the error. + """ + + def __init__(self, column: int, message: str) -> None: + self.column = column + self.message = message + + def __str__(self) -> str: + return f"at column {self.column}: {self.message}" + + +class Scanner: + __slots__ = ("tokens", "current") + + def __init__(self, input: str) -> None: + self.tokens = self.lex(input) + self.current = next(self.tokens) + + def lex(self, input: str) -> Iterator[Token]: + pos = 0 + while pos < len(input): + if input[pos] in (" ", "\t"): + pos += 1 + elif input[pos] == "(": + yield Token(TokenType.LPAREN, "(", pos) + pos += 1 + elif input[pos] == ")": + yield Token(TokenType.RPAREN, ")", pos) + pos += 1 + else: + match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\|/)+", input[pos:]) + if match: + value = match.group(0) + if value == "or": + yield Token(TokenType.OR, value, pos) + elif value == "and": + yield Token(TokenType.AND, value, pos) + elif value == "not": + yield Token(TokenType.NOT, value, pos) + else: + yield Token(TokenType.IDENT, value, pos) + pos += len(value) + else: + raise ParseError( + pos + 1, + f'unexpected character "{input[pos]}"', + ) + yield Token(TokenType.EOF, "", pos) + + def accept(self, type: TokenType, *, reject: bool = False) -> Optional[Token]: + if self.current.type is type: + token = self.current + if token.type is not TokenType.EOF: + self.current = next(self.tokens) + return token + if reject: + self.reject((type,)) + return None + + def reject(self, expected: Sequence[TokenType]) -> NoReturn: + raise ParseError( + self.current.pos + 1, + "expected {}; got {}".format( + " OR ".join(type.value for type in expected), + self.current.type.value, + ), + ) + + +# True, False and None are legal match expression identifiers, +# but illegal as Python identifiers. To fix this, this prefix +# is added to identifiers in the conversion to Python AST. +IDENT_PREFIX = "$" + + +def expression(s: Scanner) -> ast.Expression: + if s.accept(TokenType.EOF): + ret: ast.expr = astNameConstant(False) + else: + ret = expr(s) + s.accept(TokenType.EOF, reject=True) + return ast.fix_missing_locations(ast.Expression(ret)) + + +def expr(s: Scanner) -> ast.expr: + ret = and_expr(s) + while s.accept(TokenType.OR): + rhs = and_expr(s) + ret = ast.BoolOp(ast.Or(), [ret, rhs]) + return ret + + +def and_expr(s: Scanner) -> ast.expr: + ret = not_expr(s) + while s.accept(TokenType.AND): + rhs = not_expr(s) + ret = ast.BoolOp(ast.And(), [ret, rhs]) + return ret + + +def not_expr(s: Scanner) -> ast.expr: + if s.accept(TokenType.NOT): + return ast.UnaryOp(ast.Not(), not_expr(s)) + if s.accept(TokenType.LPAREN): + ret = expr(s) + s.accept(TokenType.RPAREN, reject=True) + return ret + ident = s.accept(TokenType.IDENT) + if ident: + return ast.Name(IDENT_PREFIX + ident.value, ast.Load()) + s.reject((TokenType.NOT, TokenType.LPAREN, TokenType.IDENT)) + + +class MatcherAdapter(Mapping[str, bool]): + """Adapts a matcher function to a locals mapping as required by eval().""" + + def __init__(self, matcher: Callable[[str], bool]) -> None: + self.matcher = matcher + + def __getitem__(self, key: str) -> bool: + return self.matcher(key[len(IDENT_PREFIX) :]) + + def __iter__(self) -> Iterator[str]: + raise NotImplementedError() + + def __len__(self) -> int: + raise NotImplementedError() + + +class Expression: + """A compiled match expression as used by -k and -m. + + The expression can be evaluated against different matchers. + """ + + __slots__ = ("code",) + + def __init__(self, code: types.CodeType) -> None: + self.code = code + + @classmethod + def compile(self, input: str) -> "Expression": + """Compile a match expression. + + :param input: The input expression - one line. + """ + astexpr = expression(Scanner(input)) + code: types.CodeType = compile( + astexpr, + filename="", + mode="eval", + ) + return Expression(code) + + def evaluate(self, matcher: Callable[[str], bool]) -> bool: + """Evaluate the match expression. + + :param matcher: + Given an identifier, should return whether it matches or not. + Should be prepared to handle arbitrary strings as input. + + :returns: Whether the expression matches or not. + """ + ret: bool = eval(self.code, {"__builtins__": {}}, MatcherAdapter(matcher)) + return ret diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/structures.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/structures.py new file mode 100644 index 00000000..55620f04 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/structures.py @@ -0,0 +1,618 @@ +import collections.abc +import dataclasses +import inspect +import warnings +from typing import Any +from typing import Callable +from typing import Collection +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Mapping +from typing import MutableMapping +from typing import NamedTuple +from typing import Optional +from typing import overload +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +from .._code import getfslineno +from ..compat import ascii_escaped +from ..compat import final +from ..compat import NOTSET +from ..compat import NotSetType +from _pytest.config import Config +from _pytest.deprecated import check_ispytest +from _pytest.outcomes import fail +from _pytest.warning_types import PytestUnknownMarkWarning + +if TYPE_CHECKING: + from ..nodes import Node + + +EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark" + + +def istestfunc(func) -> bool: + return callable(func) and getattr(func, "__name__", "") != "" + + +def get_empty_parameterset_mark( + config: Config, argnames: Sequence[str], func +) -> "MarkDecorator": + from ..nodes import Collector + + fs, lineno = getfslineno(func) + reason = "got empty parameter set %r, function %s at %s:%d" % ( + argnames, + func.__name__, + fs, + lineno, + ) + + requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION) + if requested_mark in ("", None, "skip"): + mark = MARK_GEN.skip(reason=reason) + elif requested_mark == "xfail": + mark = MARK_GEN.xfail(reason=reason, run=False) + elif requested_mark == "fail_at_collect": + f_name = func.__name__ + _, lineno = getfslineno(func) + raise Collector.CollectError( + "Empty parameter set in '%s' at line %d" % (f_name, lineno + 1) + ) + else: + raise LookupError(requested_mark) + return mark + + +class ParameterSet(NamedTuple): + values: Sequence[Union[object, NotSetType]] + marks: Collection[Union["MarkDecorator", "Mark"]] + id: Optional[str] + + @classmethod + def param( + cls, + *values: object, + marks: Union["MarkDecorator", Collection[Union["MarkDecorator", "Mark"]]] = (), + id: Optional[str] = None, + ) -> "ParameterSet": + if isinstance(marks, MarkDecorator): + marks = (marks,) + else: + assert isinstance(marks, collections.abc.Collection) + + if id is not None: + if not isinstance(id, str): + raise TypeError(f"Expected id to be a string, got {type(id)}: {id!r}") + id = ascii_escaped(id) + return cls(values, marks, id) + + @classmethod + def extract_from( + cls, + parameterset: Union["ParameterSet", Sequence[object], object], + force_tuple: bool = False, + ) -> "ParameterSet": + """Extract from an object or objects. + + :param parameterset: + A legacy style parameterset that may or may not be a tuple, + and may or may not be wrapped into a mess of mark objects. + + :param force_tuple: + Enforce tuple wrapping so single argument tuple values + don't get decomposed and break tests. + """ + + if isinstance(parameterset, cls): + return parameterset + if force_tuple: + return cls.param(parameterset) + else: + # TODO: Refactor to fix this type-ignore. Currently the following + # passes type-checking but crashes: + # + # @pytest.mark.parametrize(('x', 'y'), [1, 2]) + # def test_foo(x, y): pass + return cls(parameterset, marks=[], id=None) # type: ignore[arg-type] + + @staticmethod + def _parse_parametrize_args( + argnames: Union[str, Sequence[str]], + argvalues: Iterable[Union["ParameterSet", Sequence[object], object]], + *args, + **kwargs, + ) -> Tuple[Sequence[str], bool]: + if isinstance(argnames, str): + argnames = [x.strip() for x in argnames.split(",") if x.strip()] + force_tuple = len(argnames) == 1 + else: + force_tuple = False + return argnames, force_tuple + + @staticmethod + def _parse_parametrize_parameters( + argvalues: Iterable[Union["ParameterSet", Sequence[object], object]], + force_tuple: bool, + ) -> List["ParameterSet"]: + return [ + ParameterSet.extract_from(x, force_tuple=force_tuple) for x in argvalues + ] + + @classmethod + def _for_parametrize( + cls, + argnames: Union[str, Sequence[str]], + argvalues: Iterable[Union["ParameterSet", Sequence[object], object]], + func, + config: Config, + nodeid: str, + ) -> Tuple[Sequence[str], List["ParameterSet"]]: + argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues) + parameters = cls._parse_parametrize_parameters(argvalues, force_tuple) + del argvalues + + if parameters: + # Check all parameter sets have the correct number of values. + for param in parameters: + if len(param.values) != len(argnames): + msg = ( + '{nodeid}: in "parametrize" the number of names ({names_len}):\n' + " {names}\n" + "must be equal to the number of values ({values_len}):\n" + " {values}" + ) + fail( + msg.format( + nodeid=nodeid, + values=param.values, + names=argnames, + names_len=len(argnames), + values_len=len(param.values), + ), + pytrace=False, + ) + else: + # Empty parameter set (likely computed at runtime): create a single + # parameter set with NOTSET values, with the "empty parameter set" mark applied to it. + mark = get_empty_parameterset_mark(config, argnames, func) + parameters.append( + ParameterSet(values=(NOTSET,) * len(argnames), marks=[mark], id=None) + ) + return argnames, parameters + + +@final +@dataclasses.dataclass(frozen=True) +class Mark: + """A pytest mark.""" + + #: Name of the mark. + name: str + #: Positional arguments of the mark decorator. + args: Tuple[Any, ...] + #: Keyword arguments of the mark decorator. + kwargs: Mapping[str, Any] + + #: Source Mark for ids with parametrize Marks. + _param_ids_from: Optional["Mark"] = dataclasses.field(default=None, repr=False) + #: Resolved/generated ids with parametrize Marks. + _param_ids_generated: Optional[Sequence[str]] = dataclasses.field( + default=None, repr=False + ) + + def __init__( + self, + name: str, + args: Tuple[Any, ...], + kwargs: Mapping[str, Any], + param_ids_from: Optional["Mark"] = None, + param_ids_generated: Optional[Sequence[str]] = None, + *, + _ispytest: bool = False, + ) -> None: + """:meta private:""" + check_ispytest(_ispytest) + # Weirdness to bypass frozen=True. + object.__setattr__(self, "name", name) + object.__setattr__(self, "args", args) + object.__setattr__(self, "kwargs", kwargs) + object.__setattr__(self, "_param_ids_from", param_ids_from) + object.__setattr__(self, "_param_ids_generated", param_ids_generated) + + def _has_param_ids(self) -> bool: + return "ids" in self.kwargs or len(self.args) >= 4 + + def combined_with(self, other: "Mark") -> "Mark": + """Return a new Mark which is a combination of this + Mark and another Mark. + + Combines by appending args and merging kwargs. + + :param Mark other: The mark to combine with. + :rtype: Mark + """ + assert self.name == other.name + + # Remember source of ids with parametrize Marks. + param_ids_from: Optional[Mark] = None + if self.name == "parametrize": + if other._has_param_ids(): + param_ids_from = other + elif self._has_param_ids(): + param_ids_from = self + + return Mark( + self.name, + self.args + other.args, + dict(self.kwargs, **other.kwargs), + param_ids_from=param_ids_from, + _ispytest=True, + ) + + +# A generic parameter designating an object to which a Mark may +# be applied -- a test function (callable) or class. +# Note: a lambda is not allowed, but this can't be represented. +Markable = TypeVar("Markable", bound=Union[Callable[..., object], type]) + + +@dataclasses.dataclass +class MarkDecorator: + """A decorator for applying a mark on test functions and classes. + + ``MarkDecorators`` are created with ``pytest.mark``:: + + mark1 = pytest.mark.NAME # Simple MarkDecorator + mark2 = pytest.mark.NAME(name1=value) # Parametrized MarkDecorator + + and can then be applied as decorators to test functions:: + + @mark2 + def test_function(): + pass + + When a ``MarkDecorator`` is called, it does the following: + + 1. If called with a single class as its only positional argument and no + additional keyword arguments, it attaches the mark to the class so it + gets applied automatically to all test cases found in that class. + + 2. If called with a single function as its only positional argument and + no additional keyword arguments, it attaches the mark to the function, + containing all the arguments already stored internally in the + ``MarkDecorator``. + + 3. When called in any other case, it returns a new ``MarkDecorator`` + instance with the original ``MarkDecorator``'s content updated with + the arguments passed to this call. + + Note: The rules above prevent a ``MarkDecorator`` from storing only a + single function or class reference as its positional argument with no + additional keyword or positional arguments. You can work around this by + using `with_args()`. + """ + + mark: Mark + + def __init__(self, mark: Mark, *, _ispytest: bool = False) -> None: + """:meta private:""" + check_ispytest(_ispytest) + self.mark = mark + + @property + def name(self) -> str: + """Alias for mark.name.""" + return self.mark.name + + @property + def args(self) -> Tuple[Any, ...]: + """Alias for mark.args.""" + return self.mark.args + + @property + def kwargs(self) -> Mapping[str, Any]: + """Alias for mark.kwargs.""" + return self.mark.kwargs + + @property + def markname(self) -> str: + """:meta private:""" + return self.name # for backward-compat (2.4.1 had this attr) + + def with_args(self, *args: object, **kwargs: object) -> "MarkDecorator": + """Return a MarkDecorator with extra arguments added. + + Unlike calling the MarkDecorator, with_args() can be used even + if the sole argument is a callable/class. + """ + mark = Mark(self.name, args, kwargs, _ispytest=True) + return MarkDecorator(self.mark.combined_with(mark), _ispytest=True) + + # Type ignored because the overloads overlap with an incompatible + # return type. Not much we can do about that. Thankfully mypy picks + # the first match so it works out even if we break the rules. + @overload + def __call__(self, arg: Markable) -> Markable: # type: ignore[misc] + pass + + @overload + def __call__(self, *args: object, **kwargs: object) -> "MarkDecorator": + pass + + def __call__(self, *args: object, **kwargs: object): + """Call the MarkDecorator.""" + if args and not kwargs: + func = args[0] + is_class = inspect.isclass(func) + if len(args) == 1 and (istestfunc(func) or is_class): + store_mark(func, self.mark) + return func + return self.with_args(*args, **kwargs) + + +def get_unpacked_marks( + obj: Union[object, type], + *, + consider_mro: bool = True, +) -> List[Mark]: + """Obtain the unpacked marks that are stored on an object. + + If obj is a class and consider_mro is true, return marks applied to + this class and all of its super-classes in MRO order. If consider_mro + is false, only return marks applied directly to this class. + """ + if isinstance(obj, type): + if not consider_mro: + mark_lists = [obj.__dict__.get("pytestmark", [])] + else: + mark_lists = [ + x.__dict__.get("pytestmark", []) for x in reversed(obj.__mro__) + ] + mark_list = [] + for item in mark_lists: + if isinstance(item, list): + mark_list.extend(item) + else: + mark_list.append(item) + else: + mark_attribute = getattr(obj, "pytestmark", []) + if isinstance(mark_attribute, list): + mark_list = mark_attribute + else: + mark_list = [mark_attribute] + return list(normalize_mark_list(mark_list)) + + +def normalize_mark_list( + mark_list: Iterable[Union[Mark, MarkDecorator]] +) -> Iterable[Mark]: + """ + Normalize an iterable of Mark or MarkDecorator objects into a list of marks + by retrieving the `mark` attribute on MarkDecorator instances. + + :param mark_list: marks to normalize + :returns: A new list of the extracted Mark objects + """ + for mark in mark_list: + mark_obj = getattr(mark, "mark", mark) + if not isinstance(mark_obj, Mark): + raise TypeError(f"got {repr(mark_obj)} instead of Mark") + yield mark_obj + + +def store_mark(obj, mark: Mark) -> None: + """Store a Mark on an object. + + This is used to implement the Mark declarations/decorators correctly. + """ + assert isinstance(mark, Mark), mark + # Always reassign name to avoid updating pytestmark in a reference that + # was only borrowed. + obj.pytestmark = [*get_unpacked_marks(obj, consider_mro=False), mark] + + +# Typing for builtin pytest marks. This is cheating; it gives builtin marks +# special privilege, and breaks modularity. But practicality beats purity... +if TYPE_CHECKING: + from _pytest.scope import _ScopeName + + class _SkipMarkDecorator(MarkDecorator): + @overload # type: ignore[override,misc,no-overload-impl] + def __call__(self, arg: Markable) -> Markable: + ... + + @overload + def __call__(self, reason: str = ...) -> "MarkDecorator": + ... + + class _SkipifMarkDecorator(MarkDecorator): + def __call__( # type: ignore[override] + self, + condition: Union[str, bool] = ..., + *conditions: Union[str, bool], + reason: str = ..., + ) -> MarkDecorator: + ... + + class _XfailMarkDecorator(MarkDecorator): + @overload # type: ignore[override,misc,no-overload-impl] + def __call__(self, arg: Markable) -> Markable: + ... + + @overload + def __call__( + self, + condition: Union[str, bool] = ..., + *conditions: Union[str, bool], + reason: str = ..., + run: bool = ..., + raises: Union[Type[BaseException], Tuple[Type[BaseException], ...]] = ..., + strict: bool = ..., + ) -> MarkDecorator: + ... + + class _ParametrizeMarkDecorator(MarkDecorator): + def __call__( # type: ignore[override] + self, + argnames: Union[str, Sequence[str]], + argvalues: Iterable[Union[ParameterSet, Sequence[object], object]], + *, + indirect: Union[bool, Sequence[str]] = ..., + ids: Optional[ + Union[ + Iterable[Union[None, str, float, int, bool]], + Callable[[Any], Optional[object]], + ] + ] = ..., + scope: Optional[_ScopeName] = ..., + ) -> MarkDecorator: + ... + + class _UsefixturesMarkDecorator(MarkDecorator): + def __call__(self, *fixtures: str) -> MarkDecorator: # type: ignore[override] + ... + + class _FilterwarningsMarkDecorator(MarkDecorator): + def __call__(self, *filters: str) -> MarkDecorator: # type: ignore[override] + ... + + +@final +class MarkGenerator: + """Factory for :class:`MarkDecorator` objects - exposed as + a ``pytest.mark`` singleton instance. + + Example:: + + import pytest + + @pytest.mark.slowtest + def test_function(): + pass + + applies a 'slowtest' :class:`Mark` on ``test_function``. + """ + + # See TYPE_CHECKING above. + if TYPE_CHECKING: + skip: _SkipMarkDecorator + skipif: _SkipifMarkDecorator + xfail: _XfailMarkDecorator + parametrize: _ParametrizeMarkDecorator + usefixtures: _UsefixturesMarkDecorator + filterwarnings: _FilterwarningsMarkDecorator + + def __init__(self, *, _ispytest: bool = False) -> None: + check_ispytest(_ispytest) + self._config: Optional[Config] = None + self._markers: Set[str] = set() + + def __getattr__(self, name: str) -> MarkDecorator: + """Generate a new :class:`MarkDecorator` with the given name.""" + if name[0] == "_": + raise AttributeError("Marker name must NOT start with underscore") + + if self._config is not None: + # We store a set of markers as a performance optimisation - if a mark + # name is in the set we definitely know it, but a mark may be known and + # not in the set. We therefore start by updating the set! + if name not in self._markers: + for line in self._config.getini("markers"): + # example lines: "skipif(condition): skip the given test if..." + # or "hypothesis: tests which use Hypothesis", so to get the + # marker name we split on both `:` and `(`. + marker = line.split(":")[0].split("(")[0].strip() + self._markers.add(marker) + + # If the name is not in the set of known marks after updating, + # then it really is time to issue a warning or an error. + if name not in self._markers: + if self._config.option.strict_markers or self._config.option.strict: + fail( + f"{name!r} not found in `markers` configuration option", + pytrace=False, + ) + + # Raise a specific error for common misspellings of "parametrize". + if name in ["parameterize", "parametrise", "parameterise"]: + __tracebackhide__ = True + fail(f"Unknown '{name}' mark, did you mean 'parametrize'?") + + warnings.warn( + "Unknown pytest.mark.%s - is this a typo? You can register " + "custom marks to avoid this warning - for details, see " + "https://docs.pytest.org/en/stable/how-to/mark.html" % name, + PytestUnknownMarkWarning, + 2, + ) + + return MarkDecorator(Mark(name, (), {}, _ispytest=True), _ispytest=True) + + +MARK_GEN = MarkGenerator(_ispytest=True) + + +@final +class NodeKeywords(MutableMapping[str, Any]): + __slots__ = ("node", "parent", "_markers") + + def __init__(self, node: "Node") -> None: + self.node = node + self.parent = node.parent + self._markers = {node.name: True} + + def __getitem__(self, key: str) -> Any: + try: + return self._markers[key] + except KeyError: + if self.parent is None: + raise + return self.parent.keywords[key] + + def __setitem__(self, key: str, value: Any) -> None: + self._markers[key] = value + + # Note: we could've avoided explicitly implementing some of the methods + # below and use the collections.abc fallback, but that would be slow. + + def __contains__(self, key: object) -> bool: + return ( + key in self._markers + or self.parent is not None + and key in self.parent.keywords + ) + + def update( # type: ignore[override] + self, + other: Union[Mapping[str, Any], Iterable[Tuple[str, Any]]] = (), + **kwds: Any, + ) -> None: + self._markers.update(other) + self._markers.update(kwds) + + def __delitem__(self, key: str) -> None: + raise ValueError("cannot delete key in keywords dict") + + def __iter__(self) -> Iterator[str]: + # Doesn't need to be fast. + yield from self._markers + if self.parent is not None: + for keyword in self.parent.keywords: + # self._marks and self.parent.keywords can have duplicates. + if keyword not in self._markers: + yield keyword + + def __len__(self) -> int: + # Doesn't need to be fast. + return sum(1 for keyword in self) + + def __repr__(self) -> str: + return f"" diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/monkeypatch.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/monkeypatch.py new file mode 100644 index 00000000..9e51ff33 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/monkeypatch.py @@ -0,0 +1,421 @@ +"""Monkeypatching and mocking functionality.""" +import os +import re +import sys +import warnings +from contextlib import contextmanager +from typing import Any +from typing import Generator +from typing import List +from typing import Mapping +from typing import MutableMapping +from typing import Optional +from typing import overload +from typing import Tuple +from typing import TypeVar +from typing import Union + +from _pytest.compat import final +from _pytest.fixtures import fixture +from _pytest.warning_types import PytestWarning + +RE_IMPORT_ERROR_NAME = re.compile(r"^No module named (.*)$") + + +K = TypeVar("K") +V = TypeVar("V") + + +@fixture +def monkeypatch() -> Generator["MonkeyPatch", None, None]: + """A convenient fixture for monkey-patching. + + The fixture provides these methods to modify objects, dictionaries, or + :data:`os.environ`: + + * :meth:`monkeypatch.setattr(obj, name, value, raising=True) ` + * :meth:`monkeypatch.delattr(obj, name, raising=True) ` + * :meth:`monkeypatch.setitem(mapping, name, value) ` + * :meth:`monkeypatch.delitem(obj, name, raising=True) ` + * :meth:`monkeypatch.setenv(name, value, prepend=None) ` + * :meth:`monkeypatch.delenv(name, raising=True) ` + * :meth:`monkeypatch.syspath_prepend(path) ` + * :meth:`monkeypatch.chdir(path) ` + * :meth:`monkeypatch.context() ` + + All modifications will be undone after the requesting test function or + fixture has finished. The ``raising`` parameter determines if a :class:`KeyError` + or :class:`AttributeError` will be raised if the set/deletion operation does not have the + specified target. + + To undo modifications done by the fixture in a contained scope, + use :meth:`context() `. + """ + mpatch = MonkeyPatch() + yield mpatch + mpatch.undo() + + +def resolve(name: str) -> object: + # Simplified from zope.dottedname. + parts = name.split(".") + + used = parts.pop(0) + found: object = __import__(used) + for part in parts: + used += "." + part + try: + found = getattr(found, part) + except AttributeError: + pass + else: + continue + # We use explicit un-nesting of the handling block in order + # to avoid nested exceptions. + try: + __import__(used) + except ImportError as ex: + expected = str(ex).split()[-1] + if expected == used: + raise + else: + raise ImportError(f"import error in {used}: {ex}") from ex + found = annotated_getattr(found, part, used) + return found + + +def annotated_getattr(obj: object, name: str, ann: str) -> object: + try: + obj = getattr(obj, name) + except AttributeError as e: + raise AttributeError( + "{!r} object at {} has no attribute {!r}".format( + type(obj).__name__, ann, name + ) + ) from e + return obj + + +def derive_importpath(import_path: str, raising: bool) -> Tuple[str, object]: + if not isinstance(import_path, str) or "." not in import_path: + raise TypeError(f"must be absolute import path string, not {import_path!r}") + module, attr = import_path.rsplit(".", 1) + target = resolve(module) + if raising: + annotated_getattr(target, attr, ann=module) + return attr, target + + +class Notset: + def __repr__(self) -> str: + return "" + + +notset = Notset() + + +@final +class MonkeyPatch: + """Helper to conveniently monkeypatch attributes/items/environment + variables/syspath. + + Returned by the :fixture:`monkeypatch` fixture. + + .. versionchanged:: 6.2 + Can now also be used directly as `pytest.MonkeyPatch()`, for when + the fixture is not available. In this case, use + :meth:`with MonkeyPatch.context() as mp: ` or remember to call + :meth:`undo` explicitly. + """ + + def __init__(self) -> None: + self._setattr: List[Tuple[object, str, object]] = [] + self._setitem: List[Tuple[Mapping[Any, Any], object, object]] = [] + self._cwd: Optional[str] = None + self._savesyspath: Optional[List[str]] = None + + @classmethod + @contextmanager + def context(cls) -> Generator["MonkeyPatch", None, None]: + """Context manager that returns a new :class:`MonkeyPatch` object + which undoes any patching done inside the ``with`` block upon exit. + + Example: + + .. code-block:: python + + import functools + + + def test_partial(monkeypatch): + with monkeypatch.context() as m: + m.setattr(functools, "partial", 3) + + Useful in situations where it is desired to undo some patches before the test ends, + such as mocking ``stdlib`` functions that might break pytest itself if mocked (for examples + of this see :issue:`3290`). + """ + m = cls() + try: + yield m + finally: + m.undo() + + @overload + def setattr( + self, + target: str, + name: object, + value: Notset = ..., + raising: bool = ..., + ) -> None: + ... + + @overload + def setattr( + self, + target: object, + name: str, + value: object, + raising: bool = ..., + ) -> None: + ... + + def setattr( + self, + target: Union[str, object], + name: Union[object, str], + value: object = notset, + raising: bool = True, + ) -> None: + """ + Set attribute value on target, memorizing the old value. + + For example: + + .. code-block:: python + + import os + + monkeypatch.setattr(os, "getcwd", lambda: "/") + + The code above replaces the :func:`os.getcwd` function by a ``lambda`` which + always returns ``"/"``. + + For convenience, you can specify a string as ``target`` which + will be interpreted as a dotted import path, with the last part + being the attribute name: + + .. code-block:: python + + monkeypatch.setattr("os.getcwd", lambda: "/") + + Raises :class:`AttributeError` if the attribute does not exist, unless + ``raising`` is set to False. + + **Where to patch** + + ``monkeypatch.setattr`` works by (temporarily) changing the object that a name points to with another one. + There can be many names pointing to any individual object, so for patching to work you must ensure + that you patch the name used by the system under test. + + See the section :ref:`Where to patch ` in the :mod:`unittest.mock` + docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but + applies to ``monkeypatch.setattr`` as well. + """ + __tracebackhide__ = True + import inspect + + if isinstance(value, Notset): + if not isinstance(target, str): + raise TypeError( + "use setattr(target, name, value) or " + "setattr(target, value) with target being a dotted " + "import string" + ) + value = name + name, target = derive_importpath(target, raising) + else: + if not isinstance(name, str): + raise TypeError( + "use setattr(target, name, value) with name being a string or " + "setattr(target, value) with target being a dotted " + "import string" + ) + + oldval = getattr(target, name, notset) + if raising and oldval is notset: + raise AttributeError(f"{target!r} has no attribute {name!r}") + + # avoid class descriptors like staticmethod/classmethod + if inspect.isclass(target): + oldval = target.__dict__.get(name, notset) + self._setattr.append((target, name, oldval)) + setattr(target, name, value) + + def delattr( + self, + target: Union[object, str], + name: Union[str, Notset] = notset, + raising: bool = True, + ) -> None: + """Delete attribute ``name`` from ``target``. + + If no ``name`` is specified and ``target`` is a string + it will be interpreted as a dotted import path with the + last part being the attribute name. + + Raises AttributeError it the attribute does not exist, unless + ``raising`` is set to False. + """ + __tracebackhide__ = True + import inspect + + if isinstance(name, Notset): + if not isinstance(target, str): + raise TypeError( + "use delattr(target, name) or " + "delattr(target) with target being a dotted " + "import string" + ) + name, target = derive_importpath(target, raising) + + if not hasattr(target, name): + if raising: + raise AttributeError(name) + else: + oldval = getattr(target, name, notset) + # Avoid class descriptors like staticmethod/classmethod. + if inspect.isclass(target): + oldval = target.__dict__.get(name, notset) + self._setattr.append((target, name, oldval)) + delattr(target, name) + + def setitem(self, dic: Mapping[K, V], name: K, value: V) -> None: + """Set dictionary entry ``name`` to value.""" + self._setitem.append((dic, name, dic.get(name, notset))) + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + dic[name] = value # type: ignore[index] + + def delitem(self, dic: Mapping[K, V], name: K, raising: bool = True) -> None: + """Delete ``name`` from dict. + + Raises ``KeyError`` if it doesn't exist, unless ``raising`` is set to + False. + """ + if name not in dic: + if raising: + raise KeyError(name) + else: + self._setitem.append((dic, name, dic.get(name, notset))) + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + del dic[name] # type: ignore[attr-defined] + + def setenv(self, name: str, value: str, prepend: Optional[str] = None) -> None: + """Set environment variable ``name`` to ``value``. + + If ``prepend`` is a character, read the current environment variable + value and prepend the ``value`` adjoined with the ``prepend`` + character. + """ + if not isinstance(value, str): + warnings.warn( # type: ignore[unreachable] + PytestWarning( + "Value of environment variable {name} type should be str, but got " + "{value!r} (type: {type}); converted to str implicitly".format( + name=name, value=value, type=type(value).__name__ + ) + ), + stacklevel=2, + ) + value = str(value) + if prepend and name in os.environ: + value = value + prepend + os.environ[name] + self.setitem(os.environ, name, value) + + def delenv(self, name: str, raising: bool = True) -> None: + """Delete ``name`` from the environment. + + Raises ``KeyError`` if it does not exist, unless ``raising`` is set to + False. + """ + environ: MutableMapping[str, str] = os.environ + self.delitem(environ, name, raising=raising) + + def syspath_prepend(self, path) -> None: + """Prepend ``path`` to ``sys.path`` list of import locations.""" + + if self._savesyspath is None: + self._savesyspath = sys.path[:] + sys.path.insert(0, str(path)) + + # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171 + # this is only needed when pkg_resources was already loaded by the namespace package + if "pkg_resources" in sys.modules: + from pkg_resources import fixup_namespace_packages + + fixup_namespace_packages(str(path)) + + # A call to syspathinsert() usually means that the caller wants to + # import some dynamically created files, thus with python3 we + # invalidate its import caches. + # This is especially important when any namespace package is in use, + # since then the mtime based FileFinder cache (that gets created in + # this case already) gets not invalidated when writing the new files + # quickly afterwards. + from importlib import invalidate_caches + + invalidate_caches() + + def chdir(self, path: Union[str, "os.PathLike[str]"]) -> None: + """Change the current working directory to the specified path. + + :param path: + The path to change into. + """ + if self._cwd is None: + self._cwd = os.getcwd() + os.chdir(path) + + def undo(self) -> None: + """Undo previous changes. + + This call consumes the undo stack. Calling it a second time has no + effect unless you do more monkeypatching after the undo call. + + There is generally no need to call `undo()`, since it is + called automatically during tear-down. + + .. note:: + The same `monkeypatch` fixture is used across a + single test function invocation. If `monkeypatch` is used both by + the test function itself and one of the test fixtures, + calling `undo()` will undo all of the changes made in + both functions. + + Prefer to use :meth:`context() ` instead. + """ + for obj, name, value in reversed(self._setattr): + if value is not notset: + setattr(obj, name, value) + else: + delattr(obj, name) + self._setattr[:] = [] + for dictionary, key, value in reversed(self._setitem): + if value is notset: + try: + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + del dictionary[key] # type: ignore[attr-defined] + except KeyError: + pass # Was already deleted, so we have the desired state. + else: + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + dictionary[key] = value # type: ignore[index] + self._setitem[:] = [] + if self._savesyspath is not None: + sys.path[:] = self._savesyspath + self._savesyspath = None + + if self._cwd is not None: + os.chdir(self._cwd) + self._cwd = None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/nodes.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/nodes.py new file mode 100644 index 00000000..a5313cb7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/nodes.py @@ -0,0 +1,783 @@ +import os +import warnings +from inspect import signature +from pathlib import Path +from typing import Any +from typing import Callable +from typing import cast +from typing import Iterable +from typing import Iterator +from typing import List +from typing import MutableMapping +from typing import Optional +from typing import overload +from typing import Set +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +import _pytest._code +from _pytest._code import getfslineno +from _pytest._code.code import ExceptionInfo +from _pytest._code.code import TerminalRepr +from _pytest._code.code import Traceback +from _pytest.compat import cached_property +from _pytest.compat import LEGACY_PATH +from _pytest.config import Config +from _pytest.config import ConftestImportFailure +from _pytest.deprecated import FSCOLLECTOR_GETHOOKPROXY_ISINITPATH +from _pytest.deprecated import NODE_CTOR_FSPATH_ARG +from _pytest.mark.structures import Mark +from _pytest.mark.structures import MarkDecorator +from _pytest.mark.structures import NodeKeywords +from _pytest.outcomes import fail +from _pytest.pathlib import absolutepath +from _pytest.pathlib import commonpath +from _pytest.stash import Stash +from _pytest.warning_types import PytestWarning + +if TYPE_CHECKING: + # Imported here due to circular import. + from _pytest.main import Session + from _pytest._code.code import _TracebackStyle + + +SEP = "/" + +tracebackcutdir = Path(_pytest.__file__).parent + + +def iterparentnodeids(nodeid: str) -> Iterator[str]: + """Return the parent node IDs of a given node ID, inclusive. + + For the node ID + + "testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source" + + the result would be + + "" + "testing" + "testing/code" + "testing/code/test_excinfo.py" + "testing/code/test_excinfo.py::TestFormattedExcinfo" + "testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source" + + Note that / components are only considered until the first ::. + """ + pos = 0 + first_colons: Optional[int] = nodeid.find("::") + if first_colons == -1: + first_colons = None + # The root Session node - always present. + yield "" + # Eagerly consume SEP parts until first colons. + while True: + at = nodeid.find(SEP, pos, first_colons) + if at == -1: + break + if at > 0: + yield nodeid[:at] + pos = at + len(SEP) + # Eagerly consume :: parts. + while True: + at = nodeid.find("::", pos) + if at == -1: + break + if at > 0: + yield nodeid[:at] + pos = at + len("::") + # The node ID itself. + if nodeid: + yield nodeid + + +def _check_path(path: Path, fspath: LEGACY_PATH) -> None: + if Path(fspath) != path: + raise ValueError( + f"Path({fspath!r}) != {path!r}\n" + "if both path and fspath are given they need to be equal" + ) + + +def _imply_path( + node_type: Type["Node"], + path: Optional[Path], + fspath: Optional[LEGACY_PATH], +) -> Path: + if fspath is not None: + warnings.warn( + NODE_CTOR_FSPATH_ARG.format( + node_type_name=node_type.__name__, + ), + stacklevel=6, + ) + if path is not None: + if fspath is not None: + _check_path(path, fspath) + return path + else: + assert fspath is not None + return Path(fspath) + + +_NodeType = TypeVar("_NodeType", bound="Node") + + +class NodeMeta(type): + def __call__(self, *k, **kw): + msg = ( + "Direct construction of {name} has been deprecated, please use {name}.from_parent.\n" + "See " + "https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent" + " for more details." + ).format(name=f"{self.__module__}.{self.__name__}") + fail(msg, pytrace=False) + + def _create(self, *k, **kw): + try: + return super().__call__(*k, **kw) + except TypeError: + sig = signature(getattr(self, "__init__")) + known_kw = {k: v for k, v in kw.items() if k in sig.parameters} + from .warning_types import PytestDeprecationWarning + + warnings.warn( + PytestDeprecationWarning( + f"{self} is not using a cooperative constructor and only takes {set(known_kw)}.\n" + "See https://docs.pytest.org/en/stable/deprecations.html" + "#constructors-of-custom-pytest-node-subclasses-should-take-kwargs " + "for more details." + ) + ) + + return super().__call__(*k, **known_kw) + + +class Node(metaclass=NodeMeta): + r"""Base class of :class:`Collector` and :class:`Item`, the components of + the test collection tree. + + ``Collector``\'s are the internal nodes of the tree, and ``Item``\'s are the + leaf nodes. + """ + + # Implemented in the legacypath plugin. + #: A ``LEGACY_PATH`` copy of the :attr:`path` attribute. Intended for usage + #: for methods not migrated to ``pathlib.Path`` yet, such as + #: :meth:`Item.reportinfo`. Will be deprecated in a future release, prefer + #: using :attr:`path` instead. + fspath: LEGACY_PATH + + # Use __slots__ to make attribute access faster. + # Note that __dict__ is still available. + __slots__ = ( + "name", + "parent", + "config", + "session", + "path", + "_nodeid", + "_store", + "__dict__", + ) + + def __init__( + self, + name: str, + parent: "Optional[Node]" = None, + config: Optional[Config] = None, + session: "Optional[Session]" = None, + fspath: Optional[LEGACY_PATH] = None, + path: Optional[Path] = None, + nodeid: Optional[str] = None, + ) -> None: + #: A unique name within the scope of the parent node. + self.name: str = name + + #: The parent collector node. + self.parent = parent + + if config: + #: The pytest config object. + self.config: Config = config + else: + if not parent: + raise TypeError("config or parent must be provided") + self.config = parent.config + + if session: + #: The pytest session this node is part of. + self.session: Session = session + else: + if not parent: + raise TypeError("session or parent must be provided") + self.session = parent.session + + if path is None and fspath is None: + path = getattr(parent, "path", None) + #: Filesystem path where this node was collected from (can be None). + self.path: Path = _imply_path(type(self), path, fspath=fspath) + + # The explicit annotation is to avoid publicly exposing NodeKeywords. + #: Keywords/markers collected from all scopes. + self.keywords: MutableMapping[str, Any] = NodeKeywords(self) + + #: The marker objects belonging to this node. + self.own_markers: List[Mark] = [] + + #: Allow adding of extra keywords to use for matching. + self.extra_keyword_matches: Set[str] = set() + + if nodeid is not None: + assert "::()" not in nodeid + self._nodeid = nodeid + else: + if not self.parent: + raise TypeError("nodeid or parent must be provided") + self._nodeid = self.parent.nodeid + "::" + self.name + + #: A place where plugins can store information on the node for their + #: own use. + self.stash: Stash = Stash() + # Deprecated alias. Was never public. Can be removed in a few releases. + self._store = self.stash + + @classmethod + def from_parent(cls, parent: "Node", **kw): + """Public constructor for Nodes. + + This indirection got introduced in order to enable removing + the fragile logic from the node constructors. + + Subclasses can use ``super().from_parent(...)`` when overriding the + construction. + + :param parent: The parent node of this Node. + """ + if "config" in kw: + raise TypeError("config is not a valid argument for from_parent") + if "session" in kw: + raise TypeError("session is not a valid argument for from_parent") + return cls._create(parent=parent, **kw) + + @property + def ihook(self): + """fspath-sensitive hook proxy used to call pytest hooks.""" + return self.session.gethookproxy(self.path) + + def __repr__(self) -> str: + return "<{} {}>".format(self.__class__.__name__, getattr(self, "name", None)) + + def warn(self, warning: Warning) -> None: + """Issue a warning for this Node. + + Warnings will be displayed after the test session, unless explicitly suppressed. + + :param Warning warning: + The warning instance to issue. + + :raises ValueError: If ``warning`` instance is not a subclass of Warning. + + Example usage: + + .. code-block:: python + + node.warn(PytestWarning("some message")) + node.warn(UserWarning("some message")) + + .. versionchanged:: 6.2 + Any subclass of :class:`Warning` is now accepted, rather than only + :class:`PytestWarning ` subclasses. + """ + # enforce type checks here to avoid getting a generic type error later otherwise. + if not isinstance(warning, Warning): + raise ValueError( + "warning must be an instance of Warning or subclass, got {!r}".format( + warning + ) + ) + path, lineno = get_fslocation_from_item(self) + assert lineno is not None + warnings.warn_explicit( + warning, + category=None, + filename=str(path), + lineno=lineno + 1, + ) + + # Methods for ordering nodes. + + @property + def nodeid(self) -> str: + """A ::-separated string denoting its collection tree address.""" + return self._nodeid + + def __hash__(self) -> int: + return hash(self._nodeid) + + def setup(self) -> None: + pass + + def teardown(self) -> None: + pass + + def listchain(self) -> List["Node"]: + """Return list of all parent collectors up to self, starting from + the root of collection tree. + + :returns: The nodes. + """ + chain = [] + item: Optional[Node] = self + while item is not None: + chain.append(item) + item = item.parent + chain.reverse() + return chain + + def add_marker( + self, marker: Union[str, MarkDecorator], append: bool = True + ) -> None: + """Dynamically add a marker object to the node. + + :param marker: + The marker. + :param append: + Whether to append the marker, or prepend it. + """ + from _pytest.mark import MARK_GEN + + if isinstance(marker, MarkDecorator): + marker_ = marker + elif isinstance(marker, str): + marker_ = getattr(MARK_GEN, marker) + else: + raise ValueError("is not a string or pytest.mark.* Marker") + self.keywords[marker_.name] = marker_ + if append: + self.own_markers.append(marker_.mark) + else: + self.own_markers.insert(0, marker_.mark) + + def iter_markers(self, name: Optional[str] = None) -> Iterator[Mark]: + """Iterate over all markers of the node. + + :param name: If given, filter the results by the name attribute. + :returns: An iterator of the markers of the node. + """ + return (x[1] for x in self.iter_markers_with_node(name=name)) + + def iter_markers_with_node( + self, name: Optional[str] = None + ) -> Iterator[Tuple["Node", Mark]]: + """Iterate over all markers of the node. + + :param name: If given, filter the results by the name attribute. + :returns: An iterator of (node, mark) tuples. + """ + for node in reversed(self.listchain()): + for mark in node.own_markers: + if name is None or getattr(mark, "name", None) == name: + yield node, mark + + @overload + def get_closest_marker(self, name: str) -> Optional[Mark]: + ... + + @overload + def get_closest_marker(self, name: str, default: Mark) -> Mark: + ... + + def get_closest_marker( + self, name: str, default: Optional[Mark] = None + ) -> Optional[Mark]: + """Return the first marker matching the name, from closest (for + example function) to farther level (for example module level). + + :param default: Fallback return value if no marker was found. + :param name: Name to filter by. + """ + return next(self.iter_markers(name=name), default) + + def listextrakeywords(self) -> Set[str]: + """Return a set of all extra keywords in self and any parents.""" + extra_keywords: Set[str] = set() + for item in self.listchain(): + extra_keywords.update(item.extra_keyword_matches) + return extra_keywords + + def listnames(self) -> List[str]: + return [x.name for x in self.listchain()] + + def addfinalizer(self, fin: Callable[[], object]) -> None: + """Register a function to be called without arguments when this node is + finalized. + + This method can only be called when this node is active + in a setup chain, for example during self.setup(). + """ + self.session._setupstate.addfinalizer(fin, self) + + def getparent(self, cls: Type[_NodeType]) -> Optional[_NodeType]: + """Get the next parent node (including self) which is an instance of + the given class. + + :param cls: The node class to search for. + :returns: The node, if found. + """ + current: Optional[Node] = self + while current and not isinstance(current, cls): + current = current.parent + assert current is None or isinstance(current, cls) + return current + + def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback: + return excinfo.traceback + + def _repr_failure_py( + self, + excinfo: ExceptionInfo[BaseException], + style: "Optional[_TracebackStyle]" = None, + ) -> TerminalRepr: + from _pytest.fixtures import FixtureLookupError + + if isinstance(excinfo.value, ConftestImportFailure): + excinfo = ExceptionInfo.from_exc_info(excinfo.value.excinfo) + if isinstance(excinfo.value, fail.Exception): + if not excinfo.value.pytrace: + style = "value" + if isinstance(excinfo.value, FixtureLookupError): + return excinfo.value.formatrepr() + + tbfilter: Union[bool, Callable[[ExceptionInfo[BaseException]], Traceback]] + if self.config.getoption("fulltrace", False): + style = "long" + tbfilter = False + else: + tbfilter = self._traceback_filter + if style == "auto": + style = "long" + # XXX should excinfo.getrepr record all data and toterminal() process it? + if style is None: + if self.config.getoption("tbstyle", "auto") == "short": + style = "short" + else: + style = "long" + + if self.config.getoption("verbose", 0) > 1: + truncate_locals = False + else: + truncate_locals = True + + # excinfo.getrepr() formats paths relative to the CWD if `abspath` is False. + # It is possible for a fixture/test to change the CWD while this code runs, which + # would then result in the user seeing confusing paths in the failure message. + # To fix this, if the CWD changed, always display the full absolute path. + # It will be better to just always display paths relative to invocation_dir, but + # this requires a lot of plumbing (#6428). + try: + abspath = Path(os.getcwd()) != self.config.invocation_params.dir + except OSError: + abspath = True + + return excinfo.getrepr( + funcargs=True, + abspath=abspath, + showlocals=self.config.getoption("showlocals", False), + style=style, + tbfilter=tbfilter, + truncate_locals=truncate_locals, + ) + + def repr_failure( + self, + excinfo: ExceptionInfo[BaseException], + style: "Optional[_TracebackStyle]" = None, + ) -> Union[str, TerminalRepr]: + """Return a representation of a collection or test failure. + + .. seealso:: :ref:`non-python tests` + + :param excinfo: Exception information for the failure. + """ + return self._repr_failure_py(excinfo, style) + + +def get_fslocation_from_item(node: "Node") -> Tuple[Union[str, Path], Optional[int]]: + """Try to extract the actual location from a node, depending on available attributes: + + * "location": a pair (path, lineno) + * "obj": a Python object that the node wraps. + * "fspath": just a path + + :rtype: A tuple of (str|Path, int) with filename and 0-based line number. + """ + # See Item.location. + location: Optional[Tuple[str, Optional[int], str]] = getattr(node, "location", None) + if location is not None: + return location[:2] + obj = getattr(node, "obj", None) + if obj is not None: + return getfslineno(obj) + return getattr(node, "fspath", "unknown location"), -1 + + +class Collector(Node): + """Base class of all collectors. + + Collector create children through `collect()` and thus iteratively build + the collection tree. + """ + + class CollectError(Exception): + """An error during collection, contains a custom message.""" + + def collect(self) -> Iterable[Union["Item", "Collector"]]: + """Collect children (items and collectors) for this collector.""" + raise NotImplementedError("abstract") + + # TODO: This omits the style= parameter which breaks Liskov Substitution. + def repr_failure( # type: ignore[override] + self, excinfo: ExceptionInfo[BaseException] + ) -> Union[str, TerminalRepr]: + """Return a representation of a collection failure. + + :param excinfo: Exception information for the failure. + """ + if isinstance(excinfo.value, self.CollectError) and not self.config.getoption( + "fulltrace", False + ): + exc = excinfo.value + return str(exc.args[0]) + + # Respect explicit tbstyle option, but default to "short" + # (_repr_failure_py uses "long" with "fulltrace" option always). + tbstyle = self.config.getoption("tbstyle", "auto") + if tbstyle == "auto": + tbstyle = "short" + + return self._repr_failure_py(excinfo, style=tbstyle) + + def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback: + if hasattr(self, "path"): + traceback = excinfo.traceback + ntraceback = traceback.cut(path=self.path) + if ntraceback == traceback: + ntraceback = ntraceback.cut(excludepath=tracebackcutdir) + return ntraceback.filter(excinfo) + return excinfo.traceback + + +def _check_initialpaths_for_relpath(session: "Session", path: Path) -> Optional[str]: + for initial_path in session._initialpaths: + if commonpath(path, initial_path) == initial_path: + rel = str(path.relative_to(initial_path)) + return "" if rel == "." else rel + return None + + +class FSCollector(Collector): + """Base class for filesystem collectors.""" + + def __init__( + self, + fspath: Optional[LEGACY_PATH] = None, + path_or_parent: Optional[Union[Path, Node]] = None, + path: Optional[Path] = None, + name: Optional[str] = None, + parent: Optional[Node] = None, + config: Optional[Config] = None, + session: Optional["Session"] = None, + nodeid: Optional[str] = None, + ) -> None: + if path_or_parent: + if isinstance(path_or_parent, Node): + assert parent is None + parent = cast(FSCollector, path_or_parent) + elif isinstance(path_or_parent, Path): + assert path is None + path = path_or_parent + + path = _imply_path(type(self), path, fspath=fspath) + if name is None: + name = path.name + if parent is not None and parent.path != path: + try: + rel = path.relative_to(parent.path) + except ValueError: + pass + else: + name = str(rel) + name = name.replace(os.sep, SEP) + self.path = path + + if session is None: + assert parent is not None + session = parent.session + + if nodeid is None: + try: + nodeid = str(self.path.relative_to(session.config.rootpath)) + except ValueError: + nodeid = _check_initialpaths_for_relpath(session, path) + + if nodeid and os.sep != SEP: + nodeid = nodeid.replace(os.sep, SEP) + + super().__init__( + name=name, + parent=parent, + config=config, + session=session, + nodeid=nodeid, + path=path, + ) + + @classmethod + def from_parent( + cls, + parent, + *, + fspath: Optional[LEGACY_PATH] = None, + path: Optional[Path] = None, + **kw, + ): + """The public constructor.""" + return super().from_parent(parent=parent, fspath=fspath, path=path, **kw) + + def gethookproxy(self, fspath: "os.PathLike[str]"): + warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) + return self.session.gethookproxy(fspath) + + def isinitpath(self, path: Union[str, "os.PathLike[str]"]) -> bool: + warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) + return self.session.isinitpath(path) + + +class File(FSCollector): + """Base class for collecting tests from a file. + + :ref:`non-python tests`. + """ + + +class Item(Node): + """Base class of all test invocation items. + + Note that for a single function there might be multiple test invocation items. + """ + + nextitem = None + + def __init__( + self, + name, + parent=None, + config: Optional[Config] = None, + session: Optional["Session"] = None, + nodeid: Optional[str] = None, + **kw, + ) -> None: + # The first two arguments are intentionally passed positionally, + # to keep plugins who define a node type which inherits from + # (pytest.Item, pytest.File) working (see issue #8435). + # They can be made kwargs when the deprecation above is done. + super().__init__( + name, + parent, + config=config, + session=session, + nodeid=nodeid, + **kw, + ) + self._report_sections: List[Tuple[str, str, str]] = [] + + #: A list of tuples (name, value) that holds user defined properties + #: for this test. + self.user_properties: List[Tuple[str, object]] = [] + + self._check_item_and_collector_diamond_inheritance() + + def _check_item_and_collector_diamond_inheritance(self) -> None: + """ + Check if the current type inherits from both File and Collector + at the same time, emitting a warning accordingly (#8447). + """ + cls = type(self) + + # We inject an attribute in the type to avoid issuing this warning + # for the same class more than once, which is not helpful. + # It is a hack, but was deemed acceptable in order to avoid + # flooding the user in the common case. + attr_name = "_pytest_diamond_inheritance_warning_shown" + if getattr(cls, attr_name, False): + return + setattr(cls, attr_name, True) + + problems = ", ".join( + base.__name__ for base in cls.__bases__ if issubclass(base, Collector) + ) + if problems: + warnings.warn( + f"{cls.__name__} is an Item subclass and should not be a collector, " + f"however its bases {problems} are collectors.\n" + "Please split the Collectors and the Item into separate node types.\n" + "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n" + "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/", + PytestWarning, + ) + + def runtest(self) -> None: + """Run the test case for this item. + + Must be implemented by subclasses. + + .. seealso:: :ref:`non-python tests` + """ + raise NotImplementedError("runtest must be implemented by Item subclass") + + def add_report_section(self, when: str, key: str, content: str) -> None: + """Add a new report section, similar to what's done internally to add + stdout and stderr captured output:: + + item.add_report_section("call", "stdout", "report section contents") + + :param str when: + One of the possible capture states, ``"setup"``, ``"call"``, ``"teardown"``. + :param str key: + Name of the section, can be customized at will. Pytest uses ``"stdout"`` and + ``"stderr"`` internally. + :param str content: + The full contents as a string. + """ + if content: + self._report_sections.append((when, key, content)) + + def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]: + """Get location information for this item for test reports. + + Returns a tuple with three elements: + + - The path of the test (default ``self.path``) + - The 0-based line number of the test (default ``None``) + - A name of the test to be shown (default ``""``) + + .. seealso:: :ref:`non-python tests` + """ + return self.path, None, "" + + @cached_property + def location(self) -> Tuple[str, Optional[int], str]: + """ + Returns a tuple of ``(relfspath, lineno, testname)`` for this item + where ``relfspath`` is file path relative to ``config.rootpath`` + and lineno is a 0-based line number. + """ + location = self.reportinfo() + path = absolutepath(os.fspath(location[0])) + relfspath = self.session._node_location_to_relpath(path) + assert type(location[2]) is str + return (relfspath, location[1], location[2]) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/nose.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/nose.py new file mode 100644 index 00000000..273bd045 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/nose.py @@ -0,0 +1,50 @@ +"""Run testsuites written for nose.""" +import warnings + +from _pytest.config import hookimpl +from _pytest.deprecated import NOSE_SUPPORT +from _pytest.fixtures import getfixturemarker +from _pytest.nodes import Item +from _pytest.python import Function +from _pytest.unittest import TestCaseFunction + + +@hookimpl(trylast=True) +def pytest_runtest_setup(item: Item) -> None: + if not isinstance(item, Function): + return + # Don't do nose style setup/teardown on direct unittest style classes. + if isinstance(item, TestCaseFunction): + return + + # Capture the narrowed type of item for the teardown closure, + # see https://github.com/python/mypy/issues/2608 + func = item + + call_optional(func.obj, "setup", func.nodeid) + func.addfinalizer(lambda: call_optional(func.obj, "teardown", func.nodeid)) + + # NOTE: Module- and class-level fixtures are handled in python.py + # with `pluginmanager.has_plugin("nose")` checks. + # It would have been nicer to implement them outside of core, but + # it's not straightforward. + + +def call_optional(obj: object, name: str, nodeid: str) -> bool: + method = getattr(obj, name, None) + if method is None: + return False + is_fixture = getfixturemarker(method) is not None + if is_fixture: + return False + if not callable(method): + return False + # Warn about deprecation of this plugin. + method_name = getattr(method, "__name__", str(method)) + warnings.warn( + NOSE_SUPPORT.format(nodeid=nodeid, method=method_name, stage=name), stacklevel=2 + ) + # If there are any problems allow the exception to raise rather than + # silently ignoring it. + method() + return True diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/outcomes.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/outcomes.py new file mode 100644 index 00000000..53c3e151 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/outcomes.py @@ -0,0 +1,311 @@ +"""Exception classes and constants handling test outcomes as well as +functions creating them.""" +import sys +import warnings +from typing import Any +from typing import Callable +from typing import cast +from typing import NoReturn +from typing import Optional +from typing import Type +from typing import TypeVar + +from _pytest.deprecated import KEYWORD_MSG_ARG + +TYPE_CHECKING = False # Avoid circular import through compat. + +if TYPE_CHECKING: + from typing_extensions import Protocol +else: + # typing.Protocol is only available starting from Python 3.8. It is also + # available from typing_extensions, but we don't want a runtime dependency + # on that. So use a dummy runtime implementation. + from typing import Generic + + Protocol = Generic + + +class OutcomeException(BaseException): + """OutcomeException and its subclass instances indicate and contain info + about test and collection outcomes.""" + + def __init__(self, msg: Optional[str] = None, pytrace: bool = True) -> None: + if msg is not None and not isinstance(msg, str): + error_msg = ( # type: ignore[unreachable] + "{} expected string as 'msg' parameter, got '{}' instead.\n" + "Perhaps you meant to use a mark?" + ) + raise TypeError(error_msg.format(type(self).__name__, type(msg).__name__)) + super().__init__(msg) + self.msg = msg + self.pytrace = pytrace + + def __repr__(self) -> str: + if self.msg is not None: + return self.msg + return f"<{self.__class__.__name__} instance>" + + __str__ = __repr__ + + +TEST_OUTCOME = (OutcomeException, Exception) + + +class Skipped(OutcomeException): + # XXX hackish: on 3k we fake to live in the builtins + # in order to have Skipped exception printing shorter/nicer + __module__ = "builtins" + + def __init__( + self, + msg: Optional[str] = None, + pytrace: bool = True, + allow_module_level: bool = False, + *, + _use_item_location: bool = False, + ) -> None: + super().__init__(msg=msg, pytrace=pytrace) + self.allow_module_level = allow_module_level + # If true, the skip location is reported as the item's location, + # instead of the place that raises the exception/calls skip(). + self._use_item_location = _use_item_location + + +class Failed(OutcomeException): + """Raised from an explicit call to pytest.fail().""" + + __module__ = "builtins" + + +class Exit(Exception): + """Raised for immediate program exits (no tracebacks/summaries).""" + + def __init__( + self, msg: str = "unknown reason", returncode: Optional[int] = None + ) -> None: + self.msg = msg + self.returncode = returncode + super().__init__(msg) + + +# Elaborate hack to work around https://github.com/python/mypy/issues/2087. +# Ideally would just be `exit.Exception = Exit` etc. + +_F = TypeVar("_F", bound=Callable[..., object]) +_ET = TypeVar("_ET", bound=Type[BaseException]) + + +class _WithException(Protocol[_F, _ET]): + Exception: _ET + __call__: _F + + +def _with_exception(exception_type: _ET) -> Callable[[_F], _WithException[_F, _ET]]: + def decorate(func: _F) -> _WithException[_F, _ET]: + func_with_exception = cast(_WithException[_F, _ET], func) + func_with_exception.Exception = exception_type + return func_with_exception + + return decorate + + +# Exposed helper methods. + + +@_with_exception(Exit) +def exit( + reason: str = "", returncode: Optional[int] = None, *, msg: Optional[str] = None +) -> NoReturn: + """Exit testing process. + + :param reason: + The message to show as the reason for exiting pytest. reason has a default value + only because `msg` is deprecated. + + :param returncode: + Return code to be used when exiting pytest. None means the same as ``0`` (no error), same as :func:`sys.exit`. + + :param msg: + Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead. + """ + __tracebackhide__ = True + from _pytest.config import UsageError + + if reason and msg: + raise UsageError( + "cannot pass reason and msg to exit(), `msg` is deprecated, use `reason`." + ) + if not reason: + if msg is None: + raise UsageError("exit() requires a reason argument") + warnings.warn(KEYWORD_MSG_ARG.format(func="exit"), stacklevel=2) + reason = msg + raise Exit(reason, returncode) + + +@_with_exception(Skipped) +def skip( + reason: str = "", *, allow_module_level: bool = False, msg: Optional[str] = None +) -> NoReturn: + """Skip an executing test with the given message. + + This function should be called only during testing (setup, call or teardown) or + during collection by using the ``allow_module_level`` flag. This function can + be called in doctests as well. + + :param reason: + The message to show the user as reason for the skip. + + :param allow_module_level: + Allows this function to be called at module level. + Raising the skip exception at module level will stop + the execution of the module and prevent the collection of all tests in the module, + even those defined before the `skip` call. + + Defaults to False. + + :param msg: + Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead. + + .. note:: + It is better to use the :ref:`pytest.mark.skipif ref` marker when + possible to declare a test to be skipped under certain conditions + like mismatching platforms or dependencies. + Similarly, use the ``# doctest: +SKIP`` directive (see :py:data:`doctest.SKIP`) + to skip a doctest statically. + """ + __tracebackhide__ = True + reason = _resolve_msg_to_reason("skip", reason, msg) + raise Skipped(msg=reason, allow_module_level=allow_module_level) + + +@_with_exception(Failed) +def fail(reason: str = "", pytrace: bool = True, msg: Optional[str] = None) -> NoReturn: + """Explicitly fail an executing test with the given message. + + :param reason: + The message to show the user as reason for the failure. + + :param pytrace: + If False, msg represents the full failure information and no + python traceback will be reported. + + :param msg: + Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead. + """ + __tracebackhide__ = True + reason = _resolve_msg_to_reason("fail", reason, msg) + raise Failed(msg=reason, pytrace=pytrace) + + +def _resolve_msg_to_reason( + func_name: str, reason: str, msg: Optional[str] = None +) -> str: + """ + Handles converting the deprecated msg parameter if provided into + reason, raising a deprecation warning. This function will be removed + when the optional msg argument is removed from here in future. + + :param str func_name: + The name of the offending function, this is formatted into the deprecation message. + + :param str reason: + The reason= passed into either pytest.fail() or pytest.skip() + + :param str msg: + The msg= passed into either pytest.fail() or pytest.skip(). This will + be converted into reason if it is provided to allow pytest.skip(msg=) or + pytest.fail(msg=) to continue working in the interim period. + + :returns: + The value to use as reason. + + """ + __tracebackhide__ = True + if msg is not None: + if reason: + from pytest import UsageError + + raise UsageError( + f"Passing both ``reason`` and ``msg`` to pytest.{func_name}(...) is not permitted." + ) + warnings.warn(KEYWORD_MSG_ARG.format(func=func_name), stacklevel=3) + reason = msg + return reason + + +class XFailed(Failed): + """Raised from an explicit call to pytest.xfail().""" + + +@_with_exception(XFailed) +def xfail(reason: str = "") -> NoReturn: + """Imperatively xfail an executing test or setup function with the given reason. + + This function should be called only during testing (setup, call or teardown). + + :param reason: + The message to show the user as reason for the xfail. + + .. note:: + It is better to use the :ref:`pytest.mark.xfail ref` marker when + possible to declare a test to be xfailed under certain conditions + like known bugs or missing features. + """ + __tracebackhide__ = True + raise XFailed(reason) + + +def importorskip( + modname: str, minversion: Optional[str] = None, reason: Optional[str] = None +) -> Any: + """Import and return the requested module ``modname``, or skip the + current test if the module cannot be imported. + + :param modname: + The name of the module to import. + :param minversion: + If given, the imported module's ``__version__`` attribute must be at + least this minimal version, otherwise the test is still skipped. + :param reason: + If given, this reason is shown as the message when the module cannot + be imported. + + :returns: + The imported module. This should be assigned to its canonical name. + + Example:: + + docutils = pytest.importorskip("docutils") + """ + import warnings + + __tracebackhide__ = True + compile(modname, "", "eval") # to catch syntaxerrors + + with warnings.catch_warnings(): + # Make sure to ignore ImportWarnings that might happen because + # of existing directories with the same name we're trying to + # import but without a __init__.py file. + warnings.simplefilter("ignore") + try: + __import__(modname) + except ImportError as exc: + if reason is None: + reason = f"could not import {modname!r}: {exc}" + raise Skipped(reason, allow_module_level=True) from None + mod = sys.modules[modname] + if minversion is None: + return mod + verattr = getattr(mod, "__version__", None) + if minversion is not None: + # Imported lazily to improve start-up time. + from packaging.version import Version + + if verattr is None or Version(verattr) < Version(minversion): + raise Skipped( + "module %r has __version__ %r, required is: %r" + % (modname, verattr, minversion), + allow_module_level=True, + ) + return mod diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/pastebin.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/pastebin.py new file mode 100644 index 00000000..22c7a622 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/pastebin.py @@ -0,0 +1,110 @@ +"""Submit failure or test session information to a pastebin service.""" +import tempfile +from io import StringIO +from typing import IO +from typing import Union + +import pytest +from _pytest.config import Config +from _pytest.config import create_terminal_writer +from _pytest.config.argparsing import Parser +from _pytest.stash import StashKey +from _pytest.terminal import TerminalReporter + + +pastebinfile_key = StashKey[IO[bytes]]() + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("terminal reporting") + group._addoption( + "--pastebin", + metavar="mode", + action="store", + dest="pastebin", + default=None, + choices=["failed", "all"], + help="Send failed|all info to bpaste.net pastebin service", + ) + + +@pytest.hookimpl(trylast=True) +def pytest_configure(config: Config) -> None: + if config.option.pastebin == "all": + tr = config.pluginmanager.getplugin("terminalreporter") + # If no terminal reporter plugin is present, nothing we can do here; + # this can happen when this function executes in a worker node + # when using pytest-xdist, for example. + if tr is not None: + # pastebin file will be UTF-8 encoded binary file. + config.stash[pastebinfile_key] = tempfile.TemporaryFile("w+b") + oldwrite = tr._tw.write + + def tee_write(s, **kwargs): + oldwrite(s, **kwargs) + if isinstance(s, str): + s = s.encode("utf-8") + config.stash[pastebinfile_key].write(s) + + tr._tw.write = tee_write + + +def pytest_unconfigure(config: Config) -> None: + if pastebinfile_key in config.stash: + pastebinfile = config.stash[pastebinfile_key] + # Get terminal contents and delete file. + pastebinfile.seek(0) + sessionlog = pastebinfile.read() + pastebinfile.close() + del config.stash[pastebinfile_key] + # Undo our patching in the terminal reporter. + tr = config.pluginmanager.getplugin("terminalreporter") + del tr._tw.__dict__["write"] + # Write summary. + tr.write_sep("=", "Sending information to Paste Service") + pastebinurl = create_new_paste(sessionlog) + tr.write_line("pastebin session-log: %s\n" % pastebinurl) + + +def create_new_paste(contents: Union[str, bytes]) -> str: + """Create a new paste using the bpaste.net service. + + :contents: Paste contents string. + :returns: URL to the pasted contents, or an error message. + """ + import re + from urllib.request import urlopen + from urllib.parse import urlencode + + params = {"code": contents, "lexer": "text", "expiry": "1week"} + url = "https://bpa.st" + try: + response: str = ( + urlopen(url, data=urlencode(params).encode("ascii")).read().decode("utf-8") + ) + except OSError as exc_info: # urllib errors + return "bad response: %s" % exc_info + m = re.search(r'href="/raw/(\w+)"', response) + if m: + return f"{url}/show/{m.group(1)}" + else: + return "bad response: invalid format ('" + response + "')" + + +def pytest_terminal_summary(terminalreporter: TerminalReporter) -> None: + if terminalreporter.config.option.pastebin != "failed": + return + if "failed" in terminalreporter.stats: + terminalreporter.write_sep("=", "Sending information to Paste Service") + for rep in terminalreporter.stats["failed"]: + try: + msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc + except AttributeError: + msg = terminalreporter._getfailureheadline(rep) + file = StringIO() + tw = create_terminal_writer(terminalreporter.config, file) + rep.toterminal(tw) + s = file.getvalue() + assert len(s) + pastebinurl = create_new_paste(s) + terminalreporter.write_line(f"{msg} --> {pastebinurl}") diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/pathlib.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/pathlib.py new file mode 100644 index 00000000..c2f8535f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/pathlib.py @@ -0,0 +1,804 @@ +import atexit +import contextlib +import fnmatch +import importlib.util +import itertools +import os +import shutil +import sys +import types +import uuid +import warnings +from enum import Enum +from errno import EBADF +from errno import ELOOP +from errno import ENOENT +from errno import ENOTDIR +from functools import partial +from os.path import expanduser +from os.path import expandvars +from os.path import isabs +from os.path import sep +from pathlib import Path +from pathlib import PurePath +from posixpath import sep as posix_sep +from types import ModuleType +from typing import Callable +from typing import Dict +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Optional +from typing import Set +from typing import Tuple +from typing import Type +from typing import TypeVar +from typing import Union + +from _pytest.compat import assert_never +from _pytest.outcomes import skip +from _pytest.warning_types import PytestWarning + +LOCK_TIMEOUT = 60 * 60 * 24 * 3 + + +_AnyPurePath = TypeVar("_AnyPurePath", bound=PurePath) + +# The following function, variables and comments were +# copied from cpython 3.9 Lib/pathlib.py file. + +# EBADF - guard against macOS `stat` throwing EBADF +_IGNORED_ERRORS = (ENOENT, ENOTDIR, EBADF, ELOOP) + +_IGNORED_WINERRORS = ( + 21, # ERROR_NOT_READY - drive exists but is not accessible + 1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself +) + + +def _ignore_error(exception): + return ( + getattr(exception, "errno", None) in _IGNORED_ERRORS + or getattr(exception, "winerror", None) in _IGNORED_WINERRORS + ) + + +def get_lock_path(path: _AnyPurePath) -> _AnyPurePath: + return path.joinpath(".lock") + + +def on_rm_rf_error( + func, + path: str, + excinfo: Union[ + BaseException, + Tuple[Type[BaseException], BaseException, Optional[types.TracebackType]], + ], + *, + start_path: Path, +) -> bool: + """Handle known read-only errors during rmtree. + + The returned value is used only by our own tests. + """ + if isinstance(excinfo, BaseException): + exc = excinfo + else: + exc = excinfo[1] + + # Another process removed the file in the middle of the "rm_rf" (xdist for example). + # More context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018 + if isinstance(exc, FileNotFoundError): + return False + + if not isinstance(exc, PermissionError): + warnings.warn( + PytestWarning(f"(rm_rf) error removing {path}\n{type(exc)}: {exc}") + ) + return False + + if func not in (os.rmdir, os.remove, os.unlink): + if func not in (os.open,): + warnings.warn( + PytestWarning( + "(rm_rf) unknown function {} when removing {}:\n{}: {}".format( + func, path, type(exc), exc + ) + ) + ) + return False + + # Chmod + retry. + import stat + + def chmod_rw(p: str) -> None: + mode = os.stat(p).st_mode + os.chmod(p, mode | stat.S_IRUSR | stat.S_IWUSR) + + # For files, we need to recursively go upwards in the directories to + # ensure they all are also writable. + p = Path(path) + if p.is_file(): + for parent in p.parents: + chmod_rw(str(parent)) + # Stop when we reach the original path passed to rm_rf. + if parent == start_path: + break + chmod_rw(str(path)) + + func(path) + return True + + +def ensure_extended_length_path(path: Path) -> Path: + """Get the extended-length version of a path (Windows). + + On Windows, by default, the maximum length of a path (MAX_PATH) is 260 + characters, and operations on paths longer than that fail. But it is possible + to overcome this by converting the path to "extended-length" form before + performing the operation: + https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation + + On Windows, this function returns the extended-length absolute version of path. + On other platforms it returns path unchanged. + """ + if sys.platform.startswith("win32"): + path = path.resolve() + path = Path(get_extended_length_path_str(str(path))) + return path + + +def get_extended_length_path_str(path: str) -> str: + """Convert a path to a Windows extended length path.""" + long_path_prefix = "\\\\?\\" + unc_long_path_prefix = "\\\\?\\UNC\\" + if path.startswith((long_path_prefix, unc_long_path_prefix)): + return path + # UNC + if path.startswith("\\\\"): + return unc_long_path_prefix + path[2:] + return long_path_prefix + path + + +def rm_rf(path: Path) -> None: + """Remove the path contents recursively, even if some elements + are read-only.""" + path = ensure_extended_length_path(path) + onerror = partial(on_rm_rf_error, start_path=path) + if sys.version_info >= (3, 12): + shutil.rmtree(str(path), onexc=onerror) + else: + shutil.rmtree(str(path), onerror=onerror) + + +def find_prefixed(root: Path, prefix: str) -> Iterator[Path]: + """Find all elements in root that begin with the prefix, case insensitive.""" + l_prefix = prefix.lower() + for x in root.iterdir(): + if x.name.lower().startswith(l_prefix): + yield x + + +def extract_suffixes(iter: Iterable[PurePath], prefix: str) -> Iterator[str]: + """Return the parts of the paths following the prefix. + + :param iter: Iterator over path names. + :param prefix: Expected prefix of the path names. + """ + p_len = len(prefix) + for p in iter: + yield p.name[p_len:] + + +def find_suffixes(root: Path, prefix: str) -> Iterator[str]: + """Combine find_prefixes and extract_suffixes.""" + return extract_suffixes(find_prefixed(root, prefix), prefix) + + +def parse_num(maybe_num) -> int: + """Parse number path suffixes, returns -1 on error.""" + try: + return int(maybe_num) + except ValueError: + return -1 + + +def _force_symlink( + root: Path, target: Union[str, PurePath], link_to: Union[str, Path] +) -> None: + """Helper to create the current symlink. + + It's full of race conditions that are reasonably OK to ignore + for the context of best effort linking to the latest test run. + + The presumption being that in case of much parallelism + the inaccuracy is going to be acceptable. + """ + current_symlink = root.joinpath(target) + try: + current_symlink.unlink() + except OSError: + pass + try: + current_symlink.symlink_to(link_to) + except Exception: + pass + + +def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path: + """Create a directory with an increased number as suffix for the given prefix.""" + for i in range(10): + # try up to 10 times to create the folder + max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) + new_number = max_existing + 1 + new_path = root.joinpath(f"{prefix}{new_number}") + try: + new_path.mkdir(mode=mode) + except Exception: + pass + else: + _force_symlink(root, prefix + "current", new_path) + return new_path + else: + raise OSError( + "could not create numbered dir with prefix " + "{prefix} in {root} after 10 tries".format(prefix=prefix, root=root) + ) + + +def create_cleanup_lock(p: Path) -> Path: + """Create a lock to prevent premature folder cleanup.""" + lock_path = get_lock_path(p) + try: + fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644) + except FileExistsError as e: + raise OSError(f"cannot create lockfile in {p}") from e + else: + pid = os.getpid() + spid = str(pid).encode() + os.write(fd, spid) + os.close(fd) + if not lock_path.is_file(): + raise OSError("lock path got renamed after successful creation") + return lock_path + + +def register_cleanup_lock_removal(lock_path: Path, register=atexit.register): + """Register a cleanup function for removing a lock, by default on atexit.""" + pid = os.getpid() + + def cleanup_on_exit(lock_path: Path = lock_path, original_pid: int = pid) -> None: + current_pid = os.getpid() + if current_pid != original_pid: + # fork + return + try: + lock_path.unlink() + except OSError: + pass + + return register(cleanup_on_exit) + + +def maybe_delete_a_numbered_dir(path: Path) -> None: + """Remove a numbered directory if its lock can be obtained and it does + not seem to be in use.""" + path = ensure_extended_length_path(path) + lock_path = None + try: + lock_path = create_cleanup_lock(path) + parent = path.parent + + garbage = parent.joinpath(f"garbage-{uuid.uuid4()}") + path.rename(garbage) + rm_rf(garbage) + except OSError: + # known races: + # * other process did a cleanup at the same time + # * deletable folder was found + # * process cwd (Windows) + return + finally: + # If we created the lock, ensure we remove it even if we failed + # to properly remove the numbered dir. + if lock_path is not None: + try: + lock_path.unlink() + except OSError: + pass + + +def ensure_deletable(path: Path, consider_lock_dead_if_created_before: float) -> bool: + """Check if `path` is deletable based on whether the lock file is expired.""" + if path.is_symlink(): + return False + lock = get_lock_path(path) + try: + if not lock.is_file(): + return True + except OSError: + # we might not have access to the lock file at all, in this case assume + # we don't have access to the entire directory (#7491). + return False + try: + lock_time = lock.stat().st_mtime + except Exception: + return False + else: + if lock_time < consider_lock_dead_if_created_before: + # We want to ignore any errors while trying to remove the lock such as: + # - PermissionDenied, like the file permissions have changed since the lock creation; + # - FileNotFoundError, in case another pytest process got here first; + # and any other cause of failure. + with contextlib.suppress(OSError): + lock.unlink() + return True + return False + + +def try_cleanup(path: Path, consider_lock_dead_if_created_before: float) -> None: + """Try to cleanup a folder if we can ensure it's deletable.""" + if ensure_deletable(path, consider_lock_dead_if_created_before): + maybe_delete_a_numbered_dir(path) + + +def cleanup_candidates(root: Path, prefix: str, keep: int) -> Iterator[Path]: + """List candidates for numbered directories to be removed - follows py.path.""" + max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) + max_delete = max_existing - keep + paths = find_prefixed(root, prefix) + paths, paths2 = itertools.tee(paths) + numbers = map(parse_num, extract_suffixes(paths2, prefix)) + for path, number in zip(paths, numbers): + if number <= max_delete: + yield path + + +def cleanup_dead_symlinks(root: Path): + for left_dir in root.iterdir(): + if left_dir.is_symlink(): + if not left_dir.resolve().exists(): + left_dir.unlink() + + +def cleanup_numbered_dir( + root: Path, prefix: str, keep: int, consider_lock_dead_if_created_before: float +) -> None: + """Cleanup for lock driven numbered directories.""" + if not root.exists(): + return + for path in cleanup_candidates(root, prefix, keep): + try_cleanup(path, consider_lock_dead_if_created_before) + for path in root.glob("garbage-*"): + try_cleanup(path, consider_lock_dead_if_created_before) + + cleanup_dead_symlinks(root) + + +def make_numbered_dir_with_cleanup( + root: Path, + prefix: str, + keep: int, + lock_timeout: float, + mode: int, +) -> Path: + """Create a numbered dir with a cleanup lock and remove old ones.""" + e = None + for i in range(10): + try: + p = make_numbered_dir(root, prefix, mode) + # Only lock the current dir when keep is not 0 + if keep != 0: + lock_path = create_cleanup_lock(p) + register_cleanup_lock_removal(lock_path) + except Exception as exc: + e = exc + else: + consider_lock_dead_if_created_before = p.stat().st_mtime - lock_timeout + # Register a cleanup for program exit + atexit.register( + cleanup_numbered_dir, + root, + prefix, + keep, + consider_lock_dead_if_created_before, + ) + return p + assert e is not None + raise e + + +def resolve_from_str(input: str, rootpath: Path) -> Path: + input = expanduser(input) + input = expandvars(input) + if isabs(input): + return Path(input) + else: + return rootpath.joinpath(input) + + +def fnmatch_ex(pattern: str, path: Union[str, "os.PathLike[str]"]) -> bool: + """A port of FNMatcher from py.path.common which works with PurePath() instances. + + The difference between this algorithm and PurePath.match() is that the + latter matches "**" glob expressions for each part of the path, while + this algorithm uses the whole path instead. + + For example: + "tests/foo/bar/doc/test_foo.py" matches pattern "tests/**/doc/test*.py" + with this algorithm, but not with PurePath.match(). + + This algorithm was ported to keep backward-compatibility with existing + settings which assume paths match according this logic. + + References: + * https://bugs.python.org/issue29249 + * https://bugs.python.org/issue34731 + """ + path = PurePath(path) + iswin32 = sys.platform.startswith("win") + + if iswin32 and sep not in pattern and posix_sep in pattern: + # Running on Windows, the pattern has no Windows path separators, + # and the pattern has one or more Posix path separators. Replace + # the Posix path separators with the Windows path separator. + pattern = pattern.replace(posix_sep, sep) + + if sep not in pattern: + name = path.name + else: + name = str(path) + if path.is_absolute() and not os.path.isabs(pattern): + pattern = f"*{os.sep}{pattern}" + return fnmatch.fnmatch(name, pattern) + + +def parts(s: str) -> Set[str]: + parts = s.split(sep) + return {sep.join(parts[: i + 1]) or sep for i in range(len(parts))} + + +def symlink_or_skip(src, dst, **kwargs): + """Make a symlink, or skip the test in case symlinks are not supported.""" + try: + os.symlink(str(src), str(dst), **kwargs) + except OSError as e: + skip(f"symlinks not supported: {e}") + + +class ImportMode(Enum): + """Possible values for `mode` parameter of `import_path`.""" + + prepend = "prepend" + append = "append" + importlib = "importlib" + + +class ImportPathMismatchError(ImportError): + """Raised on import_path() if there is a mismatch of __file__'s. + + This can happen when `import_path` is called multiple times with different filenames that has + the same basename but reside in packages + (for example "/tests1/test_foo.py" and "/tests2/test_foo.py"). + """ + + +def import_path( + p: Union[str, "os.PathLike[str]"], + *, + mode: Union[str, ImportMode] = ImportMode.prepend, + root: Path, +) -> ModuleType: + """Import and return a module from the given path, which can be a file (a module) or + a directory (a package). + + The import mechanism used is controlled by the `mode` parameter: + + * `mode == ImportMode.prepend`: the directory containing the module (or package, taking + `__init__.py` files into account) will be put at the *start* of `sys.path` before + being imported with `importlib.import_module`. + + * `mode == ImportMode.append`: same as `prepend`, but the directory will be appended + to the end of `sys.path`, if not already in `sys.path`. + + * `mode == ImportMode.importlib`: uses more fine control mechanisms provided by `importlib` + to import the module, which avoids having to muck with `sys.path` at all. It effectively + allows having same-named test modules in different places. + + :param root: + Used as an anchor when mode == ImportMode.importlib to obtain + a unique name for the module being imported so it can safely be stored + into ``sys.modules``. + + :raises ImportPathMismatchError: + If after importing the given `path` and the module `__file__` + are different. Only raised in `prepend` and `append` modes. + """ + mode = ImportMode(mode) + + path = Path(p) + + if not path.exists(): + raise ImportError(path) + + if mode is ImportMode.importlib: + module_name = module_name_from_path(path, root) + with contextlib.suppress(KeyError): + return sys.modules[module_name] + + for meta_importer in sys.meta_path: + spec = meta_importer.find_spec(module_name, [str(path.parent)]) + if spec is not None: + break + else: + spec = importlib.util.spec_from_file_location(module_name, str(path)) + + if spec is None: + raise ImportError(f"Can't find module {module_name} at location {path}") + mod = importlib.util.module_from_spec(spec) + sys.modules[module_name] = mod + spec.loader.exec_module(mod) # type: ignore[union-attr] + insert_missing_modules(sys.modules, module_name) + return mod + + pkg_path = resolve_package_path(path) + if pkg_path is not None: + pkg_root = pkg_path.parent + names = list(path.with_suffix("").relative_to(pkg_root).parts) + if names[-1] == "__init__": + names.pop() + module_name = ".".join(names) + else: + pkg_root = path.parent + module_name = path.stem + + # Change sys.path permanently: restoring it at the end of this function would cause surprising + # problems because of delayed imports: for example, a conftest.py file imported by this function + # might have local imports, which would fail at runtime if we restored sys.path. + if mode is ImportMode.append: + if str(pkg_root) not in sys.path: + sys.path.append(str(pkg_root)) + elif mode is ImportMode.prepend: + if str(pkg_root) != sys.path[0]: + sys.path.insert(0, str(pkg_root)) + else: + assert_never(mode) + + importlib.import_module(module_name) + + mod = sys.modules[module_name] + if path.name == "__init__.py": + return mod + + ignore = os.environ.get("PY_IGNORE_IMPORTMISMATCH", "") + if ignore != "1": + module_file = mod.__file__ + if module_file is None: + raise ImportPathMismatchError(module_name, module_file, path) + + if module_file.endswith((".pyc", ".pyo")): + module_file = module_file[:-1] + if module_file.endswith(os.sep + "__init__.py"): + module_file = module_file[: -(len(os.sep + "__init__.py"))] + + try: + is_same = _is_same(str(path), module_file) + except FileNotFoundError: + is_same = False + + if not is_same: + raise ImportPathMismatchError(module_name, module_file, path) + + return mod + + +# Implement a special _is_same function on Windows which returns True if the two filenames +# compare equal, to circumvent os.path.samefile returning False for mounts in UNC (#7678). +if sys.platform.startswith("win"): + + def _is_same(f1: str, f2: str) -> bool: + return Path(f1) == Path(f2) or os.path.samefile(f1, f2) + +else: + + def _is_same(f1: str, f2: str) -> bool: + return os.path.samefile(f1, f2) + + +def module_name_from_path(path: Path, root: Path) -> str: + """ + Return a dotted module name based on the given path, anchored on root. + + For example: path="projects/src/tests/test_foo.py" and root="/projects", the + resulting module name will be "src.tests.test_foo". + """ + path = path.with_suffix("") + try: + relative_path = path.relative_to(root) + except ValueError: + # If we can't get a relative path to root, use the full path, except + # for the first part ("d:\\" or "/" depending on the platform, for example). + path_parts = path.parts[1:] + else: + # Use the parts for the relative path to the root path. + path_parts = relative_path.parts + + # Module name for packages do not contain the __init__ file, unless + # the `__init__.py` file is at the root. + if len(path_parts) >= 2 and path_parts[-1] == "__init__": + path_parts = path_parts[:-1] + + return ".".join(path_parts) + + +def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> None: + """ + Used by ``import_path`` to create intermediate modules when using mode=importlib. + + When we want to import a module as "src.tests.test_foo" for example, we need + to create empty modules "src" and "src.tests" after inserting "src.tests.test_foo", + otherwise "src.tests.test_foo" is not importable by ``__import__``. + """ + module_parts = module_name.split(".") + child_module: Union[ModuleType, None] = None + module: Union[ModuleType, None] = None + child_name: str = "" + while module_name: + if module_name not in modules: + try: + # If sys.meta_path is empty, calling import_module will issue + # a warning and raise ModuleNotFoundError. To avoid the + # warning, we check sys.meta_path explicitly and raise the error + # ourselves to fall back to creating a dummy module. + if not sys.meta_path: + raise ModuleNotFoundError + module = importlib.import_module(module_name) + except ModuleNotFoundError: + module = ModuleType( + module_name, + doc="Empty module created by pytest's importmode=importlib.", + ) + else: + module = modules[module_name] + if child_module: + # Add child attribute to the parent that can reference the child + # modules. + if not hasattr(module, child_name): + setattr(module, child_name, child_module) + modules[module_name] = module + # Keep track of the child module while moving up the tree. + child_module, child_name = module, module_name.rpartition(".")[-1] + module_parts.pop(-1) + module_name = ".".join(module_parts) + + +def resolve_package_path(path: Path) -> Optional[Path]: + """Return the Python package path by looking for the last + directory upwards which still contains an __init__.py. + + Returns None if it can not be determined. + """ + result = None + for parent in itertools.chain((path,), path.parents): + if parent.is_dir(): + if not parent.joinpath("__init__.py").is_file(): + break + if not parent.name.isidentifier(): + break + result = parent + return result + + +def scandir(path: Union[str, "os.PathLike[str]"]) -> List["os.DirEntry[str]"]: + """Scan a directory recursively, in breadth-first order. + + The returned entries are sorted. + """ + entries = [] + with os.scandir(path) as s: + # Skip entries with symlink loops and other brokenness, so the caller + # doesn't have to deal with it. + for entry in s: + try: + entry.is_file() + except OSError as err: + if _ignore_error(err): + continue + raise + entries.append(entry) + entries.sort(key=lambda entry: entry.name) + return entries + + +def visit( + path: Union[str, "os.PathLike[str]"], recurse: Callable[["os.DirEntry[str]"], bool] +) -> Iterator["os.DirEntry[str]"]: + """Walk a directory recursively, in breadth-first order. + + The `recurse` predicate determines whether a directory is recursed. + + Entries at each directory level are sorted. + """ + entries = scandir(path) + yield from entries + for entry in entries: + if entry.is_dir() and recurse(entry): + yield from visit(entry.path, recurse) + + +def absolutepath(path: Union[Path, str]) -> Path: + """Convert a path to an absolute path using os.path.abspath. + + Prefer this over Path.resolve() (see #6523). + Prefer this over Path.absolute() (not public, doesn't normalize). + """ + return Path(os.path.abspath(str(path))) + + +def commonpath(path1: Path, path2: Path) -> Optional[Path]: + """Return the common part shared with the other path, or None if there is + no common part. + + If one path is relative and one is absolute, returns None. + """ + try: + return Path(os.path.commonpath((str(path1), str(path2)))) + except ValueError: + return None + + +def bestrelpath(directory: Path, dest: Path) -> str: + """Return a string which is a relative path from directory to dest such + that directory/bestrelpath == dest. + + The paths must be either both absolute or both relative. + + If no such path can be determined, returns dest. + """ + assert isinstance(directory, Path) + assert isinstance(dest, Path) + if dest == directory: + return os.curdir + # Find the longest common directory. + base = commonpath(directory, dest) + # Can be the case on Windows for two absolute paths on different drives. + # Can be the case for two relative paths without common prefix. + # Can be the case for a relative path and an absolute path. + if not base: + return str(dest) + reldirectory = directory.relative_to(base) + reldest = dest.relative_to(base) + return os.path.join( + # Back from directory to base. + *([os.pardir] * len(reldirectory.parts)), + # Forward from base to dest. + *reldest.parts, + ) + + +# Originates from py. path.local.copy(), with siginficant trims and adjustments. +# TODO(py38): Replace with shutil.copytree(..., symlinks=True, dirs_exist_ok=True) +def copytree(source: Path, target: Path) -> None: + """Recursively copy a source directory to target.""" + assert source.is_dir() + for entry in visit(source, recurse=lambda entry: not entry.is_symlink()): + x = Path(entry) + relpath = x.relative_to(source) + newx = target / relpath + newx.parent.mkdir(exist_ok=True) + if x.is_symlink(): + newx.symlink_to(os.readlink(x)) + elif x.is_file(): + shutil.copyfile(x, newx) + elif x.is_dir(): + newx.mkdir(exist_ok=True) + + +def safe_exists(p: Path) -> bool: + """Like Path.exists(), but account for input arguments that might be too long (#11394).""" + try: + return p.exists() + except (ValueError, OSError): + # ValueError: stat: path too long for Windows + # OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect + return False diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/py.typed b/dbdpy-env/lib/python3.9/site-packages/_pytest/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester.py new file mode 100644 index 00000000..0771065e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester.py @@ -0,0 +1,1789 @@ +"""(Disabled by default) support for testing pytest and pytest plugins. + +PYTEST_DONT_REWRITE +""" +import collections.abc +import contextlib +import gc +import importlib +import locale +import os +import platform +import re +import shutil +import subprocess +import sys +import traceback +from fnmatch import fnmatch +from io import StringIO +from pathlib import Path +from typing import Any +from typing import Callable +from typing import Dict +from typing import Generator +from typing import IO +from typing import Iterable +from typing import List +from typing import Optional +from typing import overload +from typing import Sequence +from typing import TextIO +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union +from weakref import WeakKeyDictionary + +from iniconfig import IniConfig +from iniconfig import SectionWrapper + +from _pytest import timing +from _pytest._code import Source +from _pytest.capture import _get_multicapture +from _pytest.compat import final +from _pytest.compat import NOTSET +from _pytest.compat import NotSetType +from _pytest.config import _PluggyPlugin +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config import main +from _pytest.config import PytestPluginManager +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.main import Session +from _pytest.monkeypatch import MonkeyPatch +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.outcomes import fail +from _pytest.outcomes import importorskip +from _pytest.outcomes import skip +from _pytest.pathlib import bestrelpath +from _pytest.pathlib import copytree +from _pytest.pathlib import make_numbered_dir +from _pytest.reports import CollectReport +from _pytest.reports import TestReport +from _pytest.tmpdir import TempPathFactory +from _pytest.warning_types import PytestWarning + + +if TYPE_CHECKING: + from typing_extensions import Final + from typing_extensions import Literal + + import pexpect + + +pytest_plugins = ["pytester_assertions"] + + +IGNORE_PAM = [ # filenames added when obtaining details about the current user + "/var/lib/sss/mc/passwd" +] + + +def pytest_addoption(parser: Parser) -> None: + parser.addoption( + "--lsof", + action="store_true", + dest="lsof", + default=False, + help="Run FD checks if lsof is available", + ) + + parser.addoption( + "--runpytest", + default="inprocess", + dest="runpytest", + choices=("inprocess", "subprocess"), + help=( + "Run pytest sub runs in tests using an 'inprocess' " + "or 'subprocess' (python -m main) method" + ), + ) + + parser.addini( + "pytester_example_dir", help="Directory to take the pytester example files from" + ) + + +def pytest_configure(config: Config) -> None: + if config.getvalue("lsof"): + checker = LsofFdLeakChecker() + if checker.matching_platform(): + config.pluginmanager.register(checker) + + config.addinivalue_line( + "markers", + "pytester_example_path(*path_segments): join the given path " + "segments to `pytester_example_dir` for this test.", + ) + + +class LsofFdLeakChecker: + def get_open_files(self) -> List[Tuple[str, str]]: + out = subprocess.run( + ("lsof", "-Ffn0", "-p", str(os.getpid())), + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + check=True, + text=True, + encoding=locale.getpreferredencoding(False), + ).stdout + + def isopen(line: str) -> bool: + return line.startswith("f") and ( + "deleted" not in line + and "mem" not in line + and "txt" not in line + and "cwd" not in line + ) + + open_files = [] + + for line in out.split("\n"): + if isopen(line): + fields = line.split("\0") + fd = fields[0][1:] + filename = fields[1][1:] + if filename in IGNORE_PAM: + continue + if filename.startswith("/"): + open_files.append((fd, filename)) + + return open_files + + def matching_platform(self) -> bool: + try: + subprocess.run(("lsof", "-v"), check=True) + except (OSError, subprocess.CalledProcessError): + return False + else: + return True + + @hookimpl(hookwrapper=True, tryfirst=True) + def pytest_runtest_protocol(self, item: Item) -> Generator[None, None, None]: + lines1 = self.get_open_files() + yield + if hasattr(sys, "pypy_version_info"): + gc.collect() + lines2 = self.get_open_files() + + new_fds = {t[0] for t in lines2} - {t[0] for t in lines1} + leaked_files = [t for t in lines2 if t[0] in new_fds] + if leaked_files: + error = [ + "***** %s FD leakage detected" % len(leaked_files), + *(str(f) for f in leaked_files), + "*** Before:", + *(str(f) for f in lines1), + "*** After:", + *(str(f) for f in lines2), + "***** %s FD leakage detected" % len(leaked_files), + "*** function %s:%s: %s " % item.location, + "See issue #2366", + ] + item.warn(PytestWarning("\n".join(error))) + + +# used at least by pytest-xdist plugin + + +@fixture +def _pytest(request: FixtureRequest) -> "PytestArg": + """Return a helper which offers a gethookrecorder(hook) method which + returns a HookRecorder instance which helps to make assertions about called + hooks.""" + return PytestArg(request) + + +class PytestArg: + def __init__(self, request: FixtureRequest) -> None: + self._request = request + + def gethookrecorder(self, hook) -> "HookRecorder": + hookrecorder = HookRecorder(hook._pm) + self._request.addfinalizer(hookrecorder.finish_recording) + return hookrecorder + + +def get_public_names(values: Iterable[str]) -> List[str]: + """Only return names from iterator values without a leading underscore.""" + return [x for x in values if x[0] != "_"] + + +@final +class RecordedHookCall: + """A recorded call to a hook. + + The arguments to the hook call are set as attributes. + For example: + + .. code-block:: python + + calls = hook_recorder.getcalls("pytest_runtest_setup") + # Suppose pytest_runtest_setup was called once with `item=an_item`. + assert calls[0].item is an_item + """ + + def __init__(self, name: str, kwargs) -> None: + self.__dict__.update(kwargs) + self._name = name + + def __repr__(self) -> str: + d = self.__dict__.copy() + del d["_name"] + return f"" + + if TYPE_CHECKING: + # The class has undetermined attributes, this tells mypy about it. + def __getattr__(self, key: str): + ... + + +@final +class HookRecorder: + """Record all hooks called in a plugin manager. + + Hook recorders are created by :class:`Pytester`. + + This wraps all the hook calls in the plugin manager, recording each call + before propagating the normal calls. + """ + + def __init__( + self, pluginmanager: PytestPluginManager, *, _ispytest: bool = False + ) -> None: + check_ispytest(_ispytest) + + self._pluginmanager = pluginmanager + self.calls: List[RecordedHookCall] = [] + self.ret: Optional[Union[int, ExitCode]] = None + + def before(hook_name: str, hook_impls, kwargs) -> None: + self.calls.append(RecordedHookCall(hook_name, kwargs)) + + def after(outcome, hook_name: str, hook_impls, kwargs) -> None: + pass + + self._undo_wrapping = pluginmanager.add_hookcall_monitoring(before, after) + + def finish_recording(self) -> None: + self._undo_wrapping() + + def getcalls(self, names: Union[str, Iterable[str]]) -> List[RecordedHookCall]: + """Get all recorded calls to hooks with the given names (or name).""" + if isinstance(names, str): + names = names.split() + return [call for call in self.calls if call._name in names] + + def assert_contains(self, entries: Sequence[Tuple[str, str]]) -> None: + __tracebackhide__ = True + i = 0 + entries = list(entries) + backlocals = sys._getframe(1).f_locals + while entries: + name, check = entries.pop(0) + for ind, call in enumerate(self.calls[i:]): + if call._name == name: + print("NAMEMATCH", name, call) + if eval(check, backlocals, call.__dict__): + print("CHECKERMATCH", repr(check), "->", call) + else: + print("NOCHECKERMATCH", repr(check), "-", call) + continue + i += ind + 1 + break + print("NONAMEMATCH", name, "with", call) + else: + fail(f"could not find {name!r} check {check!r}") + + def popcall(self, name: str) -> RecordedHookCall: + __tracebackhide__ = True + for i, call in enumerate(self.calls): + if call._name == name: + del self.calls[i] + return call + lines = [f"could not find call {name!r}, in:"] + lines.extend([" %s" % x for x in self.calls]) + fail("\n".join(lines)) + + def getcall(self, name: str) -> RecordedHookCall: + values = self.getcalls(name) + assert len(values) == 1, (name, values) + return values[0] + + # functionality for test reports + + @overload + def getreports( + self, + names: "Literal['pytest_collectreport']", + ) -> Sequence[CollectReport]: + ... + + @overload + def getreports( + self, + names: "Literal['pytest_runtest_logreport']", + ) -> Sequence[TestReport]: + ... + + @overload + def getreports( + self, + names: Union[str, Iterable[str]] = ( + "pytest_collectreport", + "pytest_runtest_logreport", + ), + ) -> Sequence[Union[CollectReport, TestReport]]: + ... + + def getreports( + self, + names: Union[str, Iterable[str]] = ( + "pytest_collectreport", + "pytest_runtest_logreport", + ), + ) -> Sequence[Union[CollectReport, TestReport]]: + return [x.report for x in self.getcalls(names)] + + def matchreport( + self, + inamepart: str = "", + names: Union[str, Iterable[str]] = ( + "pytest_runtest_logreport", + "pytest_collectreport", + ), + when: Optional[str] = None, + ) -> Union[CollectReport, TestReport]: + """Return a testreport whose dotted import path matches.""" + values = [] + for rep in self.getreports(names=names): + if not when and rep.when != "call" and rep.passed: + # setup/teardown passing reports - let's ignore those + continue + if when and rep.when != when: + continue + if not inamepart or inamepart in rep.nodeid.split("::"): + values.append(rep) + if not values: + raise ValueError( + "could not find test report matching %r: " + "no test reports at all!" % (inamepart,) + ) + if len(values) > 1: + raise ValueError( + "found 2 or more testreports matching {!r}: {}".format( + inamepart, values + ) + ) + return values[0] + + @overload + def getfailures( + self, + names: "Literal['pytest_collectreport']", + ) -> Sequence[CollectReport]: + ... + + @overload + def getfailures( + self, + names: "Literal['pytest_runtest_logreport']", + ) -> Sequence[TestReport]: + ... + + @overload + def getfailures( + self, + names: Union[str, Iterable[str]] = ( + "pytest_collectreport", + "pytest_runtest_logreport", + ), + ) -> Sequence[Union[CollectReport, TestReport]]: + ... + + def getfailures( + self, + names: Union[str, Iterable[str]] = ( + "pytest_collectreport", + "pytest_runtest_logreport", + ), + ) -> Sequence[Union[CollectReport, TestReport]]: + return [rep for rep in self.getreports(names) if rep.failed] + + def getfailedcollections(self) -> Sequence[CollectReport]: + return self.getfailures("pytest_collectreport") + + def listoutcomes( + self, + ) -> Tuple[ + Sequence[TestReport], + Sequence[Union[CollectReport, TestReport]], + Sequence[Union[CollectReport, TestReport]], + ]: + passed = [] + skipped = [] + failed = [] + for rep in self.getreports( + ("pytest_collectreport", "pytest_runtest_logreport") + ): + if rep.passed: + if rep.when == "call": + assert isinstance(rep, TestReport) + passed.append(rep) + elif rep.skipped: + skipped.append(rep) + else: + assert rep.failed, f"Unexpected outcome: {rep!r}" + failed.append(rep) + return passed, skipped, failed + + def countoutcomes(self) -> List[int]: + return [len(x) for x in self.listoutcomes()] + + def assertoutcome(self, passed: int = 0, skipped: int = 0, failed: int = 0) -> None: + __tracebackhide__ = True + from _pytest.pytester_assertions import assertoutcome + + outcomes = self.listoutcomes() + assertoutcome( + outcomes, + passed=passed, + skipped=skipped, + failed=failed, + ) + + def clear(self) -> None: + self.calls[:] = [] + + +@fixture +def linecomp() -> "LineComp": + """A :class: `LineComp` instance for checking that an input linearly + contains a sequence of strings.""" + return LineComp() + + +@fixture(name="LineMatcher") +def LineMatcher_fixture(request: FixtureRequest) -> Type["LineMatcher"]: + """A reference to the :class: `LineMatcher`. + + This is instantiable with a list of lines (without their trailing newlines). + This is useful for testing large texts, such as the output of commands. + """ + return LineMatcher + + +@fixture +def pytester( + request: FixtureRequest, tmp_path_factory: TempPathFactory, monkeypatch: MonkeyPatch +) -> "Pytester": + """ + Facilities to write tests/configuration files, execute pytest in isolation, and match + against expected output, perfect for black-box testing of pytest plugins. + + It attempts to isolate the test run from external factors as much as possible, modifying + the current working directory to ``path`` and environment variables during initialization. + + It is particularly useful for testing plugins. It is similar to the :fixture:`tmp_path` + fixture but provides methods which aid in testing pytest itself. + """ + return Pytester(request, tmp_path_factory, monkeypatch, _ispytest=True) + + +@fixture +def _sys_snapshot() -> Generator[None, None, None]: + snappaths = SysPathsSnapshot() + snapmods = SysModulesSnapshot() + yield + snapmods.restore() + snappaths.restore() + + +@fixture +def _config_for_test() -> Generator[Config, None, None]: + from _pytest.config import get_config + + config = get_config() + yield config + config._ensure_unconfigure() # cleanup, e.g. capman closing tmpfiles. + + +# Regex to match the session duration string in the summary: "74.34s". +rex_session_duration = re.compile(r"\d+\.\d\ds") +# Regex to match all the counts and phrases in the summary line: "34 passed, 111 skipped". +rex_outcome = re.compile(r"(\d+) (\w+)") + + +@final +class RunResult: + """The result of running a command from :class:`~pytest.Pytester`.""" + + def __init__( + self, + ret: Union[int, ExitCode], + outlines: List[str], + errlines: List[str], + duration: float, + ) -> None: + try: + self.ret: Union[int, ExitCode] = ExitCode(ret) + """The return value.""" + except ValueError: + self.ret = ret + self.outlines = outlines + """List of lines captured from stdout.""" + self.errlines = errlines + """List of lines captured from stderr.""" + self.stdout = LineMatcher(outlines) + """:class:`~pytest.LineMatcher` of stdout. + + Use e.g. :func:`str(stdout) ` to reconstruct stdout, or the commonly used + :func:`stdout.fnmatch_lines() ` method. + """ + self.stderr = LineMatcher(errlines) + """:class:`~pytest.LineMatcher` of stderr.""" + self.duration = duration + """Duration in seconds.""" + + def __repr__(self) -> str: + return ( + "" + % (self.ret, len(self.stdout.lines), len(self.stderr.lines), self.duration) + ) + + def parseoutcomes(self) -> Dict[str, int]: + """Return a dictionary of outcome noun -> count from parsing the terminal + output that the test process produced. + + The returned nouns will always be in plural form:: + + ======= 1 failed, 1 passed, 1 warning, 1 error in 0.13s ==== + + Will return ``{"failed": 1, "passed": 1, "warnings": 1, "errors": 1}``. + """ + return self.parse_summary_nouns(self.outlines) + + @classmethod + def parse_summary_nouns(cls, lines) -> Dict[str, int]: + """Extract the nouns from a pytest terminal summary line. + + It always returns the plural noun for consistency:: + + ======= 1 failed, 1 passed, 1 warning, 1 error in 0.13s ==== + + Will return ``{"failed": 1, "passed": 1, "warnings": 1, "errors": 1}``. + """ + for line in reversed(lines): + if rex_session_duration.search(line): + outcomes = rex_outcome.findall(line) + ret = {noun: int(count) for (count, noun) in outcomes} + break + else: + raise ValueError("Pytest terminal summary report not found") + + to_plural = { + "warning": "warnings", + "error": "errors", + } + return {to_plural.get(k, k): v for k, v in ret.items()} + + def assert_outcomes( + self, + passed: int = 0, + skipped: int = 0, + failed: int = 0, + errors: int = 0, + xpassed: int = 0, + xfailed: int = 0, + warnings: Optional[int] = None, + deselected: Optional[int] = None, + ) -> None: + """ + Assert that the specified outcomes appear with the respective + numbers (0 means it didn't occur) in the text output from a test run. + + ``warnings`` and ``deselected`` are only checked if not None. + """ + __tracebackhide__ = True + from _pytest.pytester_assertions import assert_outcomes + + outcomes = self.parseoutcomes() + assert_outcomes( + outcomes, + passed=passed, + skipped=skipped, + failed=failed, + errors=errors, + xpassed=xpassed, + xfailed=xfailed, + warnings=warnings, + deselected=deselected, + ) + + +class CwdSnapshot: + def __init__(self) -> None: + self.__saved = os.getcwd() + + def restore(self) -> None: + os.chdir(self.__saved) + + +class SysModulesSnapshot: + def __init__(self, preserve: Optional[Callable[[str], bool]] = None) -> None: + self.__preserve = preserve + self.__saved = dict(sys.modules) + + def restore(self) -> None: + if self.__preserve: + self.__saved.update( + (k, m) for k, m in sys.modules.items() if self.__preserve(k) + ) + sys.modules.clear() + sys.modules.update(self.__saved) + + +class SysPathsSnapshot: + def __init__(self) -> None: + self.__saved = list(sys.path), list(sys.meta_path) + + def restore(self) -> None: + sys.path[:], sys.meta_path[:] = self.__saved + + +@final +class Pytester: + """ + Facilities to write tests/configuration files, execute pytest in isolation, and match + against expected output, perfect for black-box testing of pytest plugins. + + It attempts to isolate the test run from external factors as much as possible, modifying + the current working directory to :attr:`path` and environment variables during initialization. + """ + + __test__ = False + + CLOSE_STDIN: "Final" = NOTSET + + class TimeoutExpired(Exception): + pass + + def __init__( + self, + request: FixtureRequest, + tmp_path_factory: TempPathFactory, + monkeypatch: MonkeyPatch, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._request = request + self._mod_collections: WeakKeyDictionary[ + Collector, List[Union[Item, Collector]] + ] = WeakKeyDictionary() + if request.function: + name: str = request.function.__name__ + else: + name = request.node.name + self._name = name + self._path: Path = tmp_path_factory.mktemp(name, numbered=True) + #: A list of plugins to use with :py:meth:`parseconfig` and + #: :py:meth:`runpytest`. Initially this is an empty list but plugins can + #: be added to the list. The type of items to add to the list depends on + #: the method using them so refer to them for details. + self.plugins: List[Union[str, _PluggyPlugin]] = [] + self._cwd_snapshot = CwdSnapshot() + self._sys_path_snapshot = SysPathsSnapshot() + self._sys_modules_snapshot = self.__take_sys_modules_snapshot() + self.chdir() + self._request.addfinalizer(self._finalize) + self._method = self._request.config.getoption("--runpytest") + self._test_tmproot = tmp_path_factory.mktemp(f"tmp-{name}", numbered=True) + + self._monkeypatch = mp = monkeypatch + mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self._test_tmproot)) + # Ensure no unexpected caching via tox. + mp.delenv("TOX_ENV_DIR", raising=False) + # Discard outer pytest options. + mp.delenv("PYTEST_ADDOPTS", raising=False) + # Ensure no user config is used. + tmphome = str(self.path) + mp.setenv("HOME", tmphome) + mp.setenv("USERPROFILE", tmphome) + # Do not use colors for inner runs by default. + mp.setenv("PY_COLORS", "0") + + @property + def path(self) -> Path: + """Temporary directory path used to create files/run tests from, etc.""" + return self._path + + def __repr__(self) -> str: + return f"" + + def _finalize(self) -> None: + """ + Clean up global state artifacts. + + Some methods modify the global interpreter state and this tries to + clean this up. It does not remove the temporary directory however so + it can be looked at after the test run has finished. + """ + self._sys_modules_snapshot.restore() + self._sys_path_snapshot.restore() + self._cwd_snapshot.restore() + + def __take_sys_modules_snapshot(self) -> SysModulesSnapshot: + # Some zope modules used by twisted-related tests keep internal state + # and can't be deleted; we had some trouble in the past with + # `zope.interface` for example. + # + # Preserve readline due to https://bugs.python.org/issue41033. + # pexpect issues a SIGWINCH. + def preserve_module(name): + return name.startswith(("zope", "readline")) + + return SysModulesSnapshot(preserve=preserve_module) + + def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder: + """Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`.""" + pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True) # type: ignore[attr-defined] + self._request.addfinalizer(reprec.finish_recording) + return reprec + + def chdir(self) -> None: + """Cd into the temporary directory. + + This is done automatically upon instantiation. + """ + os.chdir(self.path) + + def _makefile( + self, + ext: str, + lines: Sequence[Union[Any, bytes]], + files: Dict[str, str], + encoding: str = "utf-8", + ) -> Path: + items = list(files.items()) + + if ext and not ext.startswith("."): + raise ValueError( + f"pytester.makefile expects a file extension, try .{ext} instead of {ext}" + ) + + def to_text(s: Union[Any, bytes]) -> str: + return s.decode(encoding) if isinstance(s, bytes) else str(s) + + if lines: + source = "\n".join(to_text(x) for x in lines) + basename = self._name + items.insert(0, (basename, source)) + + ret = None + for basename, value in items: + p = self.path.joinpath(basename).with_suffix(ext) + p.parent.mkdir(parents=True, exist_ok=True) + source_ = Source(value) + source = "\n".join(to_text(line) for line in source_.lines) + p.write_text(source.strip(), encoding=encoding) + if ret is None: + ret = p + assert ret is not None + return ret + + def makefile(self, ext: str, *args: str, **kwargs: str) -> Path: + r"""Create new text file(s) in the test directory. + + :param ext: + The extension the file(s) should use, including the dot, e.g. `.py`. + :param args: + All args are treated as strings and joined using newlines. + The result is written as contents to the file. The name of the + file is based on the test function requesting this fixture. + :param kwargs: + Each keyword is the name of a file, while the value of it will + be written as contents of the file. + :returns: + The first created file. + + Examples: + + .. code-block:: python + + pytester.makefile(".txt", "line1", "line2") + + pytester.makefile(".ini", pytest="[pytest]\naddopts=-rs\n") + + To create binary files, use :meth:`pathlib.Path.write_bytes` directly: + + .. code-block:: python + + filename = pytester.path.joinpath("foo.bin") + filename.write_bytes(b"...") + """ + return self._makefile(ext, args, kwargs) + + def makeconftest(self, source: str) -> Path: + """Write a contest.py file. + + :param source: The contents. + :returns: The conftest.py file. + """ + return self.makepyfile(conftest=source) + + def makeini(self, source: str) -> Path: + """Write a tox.ini file. + + :param source: The contents. + :returns: The tox.ini file. + """ + return self.makefile(".ini", tox=source) + + def getinicfg(self, source: str) -> SectionWrapper: + """Return the pytest section from the tox.ini config file.""" + p = self.makeini(source) + return IniConfig(str(p))["pytest"] + + def makepyprojecttoml(self, source: str) -> Path: + """Write a pyproject.toml file. + + :param source: The contents. + :returns: The pyproject.ini file. + + .. versionadded:: 6.0 + """ + return self.makefile(".toml", pyproject=source) + + def makepyfile(self, *args, **kwargs) -> Path: + r"""Shortcut for .makefile() with a .py extension. + + Defaults to the test name with a '.py' extension, e.g test_foobar.py, overwriting + existing files. + + Examples: + + .. code-block:: python + + def test_something(pytester): + # Initial file is created test_something.py. + pytester.makepyfile("foobar") + # To create multiple files, pass kwargs accordingly. + pytester.makepyfile(custom="foobar") + # At this point, both 'test_something.py' & 'custom.py' exist in the test directory. + + """ + return self._makefile(".py", args, kwargs) + + def maketxtfile(self, *args, **kwargs) -> Path: + r"""Shortcut for .makefile() with a .txt extension. + + Defaults to the test name with a '.txt' extension, e.g test_foobar.txt, overwriting + existing files. + + Examples: + + .. code-block:: python + + def test_something(pytester): + # Initial file is created test_something.txt. + pytester.maketxtfile("foobar") + # To create multiple files, pass kwargs accordingly. + pytester.maketxtfile(custom="foobar") + # At this point, both 'test_something.txt' & 'custom.txt' exist in the test directory. + + """ + return self._makefile(".txt", args, kwargs) + + def syspathinsert( + self, path: Optional[Union[str, "os.PathLike[str]"]] = None + ) -> None: + """Prepend a directory to sys.path, defaults to :attr:`path`. + + This is undone automatically when this object dies at the end of each + test. + + :param path: + The path. + """ + if path is None: + path = self.path + + self._monkeypatch.syspath_prepend(str(path)) + + def mkdir(self, name: Union[str, "os.PathLike[str]"]) -> Path: + """Create a new (sub)directory. + + :param name: + The name of the directory, relative to the pytester path. + :returns: + The created directory. + """ + p = self.path / name + p.mkdir() + return p + + def mkpydir(self, name: Union[str, "os.PathLike[str]"]) -> Path: + """Create a new python package. + + This creates a (sub)directory with an empty ``__init__.py`` file so it + gets recognised as a Python package. + """ + p = self.path / name + p.mkdir() + p.joinpath("__init__.py").touch() + return p + + def copy_example(self, name: Optional[str] = None) -> Path: + """Copy file from project's directory into the testdir. + + :param name: + The name of the file to copy. + :return: + Path to the copied directory (inside ``self.path``). + """ + example_dir_ = self._request.config.getini("pytester_example_dir") + if example_dir_ is None: + raise ValueError("pytester_example_dir is unset, can't copy examples") + example_dir: Path = self._request.config.rootpath / example_dir_ + + for extra_element in self._request.node.iter_markers("pytester_example_path"): + assert extra_element.args + example_dir = example_dir.joinpath(*extra_element.args) + + if name is None: + func_name = self._name + maybe_dir = example_dir / func_name + maybe_file = example_dir / (func_name + ".py") + + if maybe_dir.is_dir(): + example_path = maybe_dir + elif maybe_file.is_file(): + example_path = maybe_file + else: + raise LookupError( + f"{func_name} can't be found as module or package in {example_dir}" + ) + else: + example_path = example_dir.joinpath(name) + + if example_path.is_dir() and not example_path.joinpath("__init__.py").is_file(): + copytree(example_path, self.path) + return self.path + elif example_path.is_file(): + result = self.path.joinpath(example_path.name) + shutil.copy(example_path, result) + return result + else: + raise LookupError( + f'example "{example_path}" is not found as a file or directory' + ) + + def getnode( + self, config: Config, arg: Union[str, "os.PathLike[str]"] + ) -> Union[Collector, Item]: + """Get the collection node of a file. + + :param config: + A pytest config. + See :py:meth:`parseconfig` and :py:meth:`parseconfigure` for creating it. + :param arg: + Path to the file. + :returns: + The node. + """ + session = Session.from_config(config) + assert "::" not in str(arg) + p = Path(os.path.abspath(arg)) + config.hook.pytest_sessionstart(session=session) + res = session.perform_collect([str(p)], genitems=False)[0] + config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK) + return res + + def getpathnode( + self, path: Union[str, "os.PathLike[str]"] + ) -> Union[Collector, Item]: + """Return the collection node of a file. + + This is like :py:meth:`getnode` but uses :py:meth:`parseconfigure` to + create the (configured) pytest Config instance. + + :param path: + Path to the file. + :returns: + The node. + """ + path = Path(path) + config = self.parseconfigure(path) + session = Session.from_config(config) + x = bestrelpath(session.path, path) + config.hook.pytest_sessionstart(session=session) + res = session.perform_collect([x], genitems=False)[0] + config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK) + return res + + def genitems(self, colitems: Sequence[Union[Item, Collector]]) -> List[Item]: + """Generate all test items from a collection node. + + This recurses into the collection node and returns a list of all the + test items contained within. + + :param colitems: + The collection nodes. + :returns: + The collected items. + """ + session = colitems[0].session + result: List[Item] = [] + for colitem in colitems: + result.extend(session.genitems(colitem)) + return result + + def runitem(self, source: str) -> Any: + """Run the "test_func" Item. + + The calling test instance (class containing the test method) must + provide a ``.getrunner()`` method which should return a runner which + can run the test protocol for a single item, e.g. + :py:func:`_pytest.runner.runtestprotocol`. + """ + # used from runner functional tests + item = self.getitem(source) + # the test class where we are called from wants to provide the runner + testclassinstance = self._request.instance + runner = testclassinstance.getrunner() + return runner(item) + + def inline_runsource(self, source: str, *cmdlineargs) -> HookRecorder: + """Run a test module in process using ``pytest.main()``. + + This run writes "source" into a temporary file and runs + ``pytest.main()`` on it, returning a :py:class:`HookRecorder` instance + for the result. + + :param source: The source code of the test module. + :param cmdlineargs: Any extra command line arguments to use. + """ + p = self.makepyfile(source) + values = list(cmdlineargs) + [p] + return self.inline_run(*values) + + def inline_genitems(self, *args) -> Tuple[List[Item], HookRecorder]: + """Run ``pytest.main(['--collect-only'])`` in-process. + + Runs the :py:func:`pytest.main` function to run all of pytest inside + the test process itself like :py:meth:`inline_run`, but returns a + tuple of the collected items and a :py:class:`HookRecorder` instance. + """ + rec = self.inline_run("--collect-only", *args) + items = [x.item for x in rec.getcalls("pytest_itemcollected")] + return items, rec + + def inline_run( + self, + *args: Union[str, "os.PathLike[str]"], + plugins=(), + no_reraise_ctrlc: bool = False, + ) -> HookRecorder: + """Run ``pytest.main()`` in-process, returning a HookRecorder. + + Runs the :py:func:`pytest.main` function to run all of pytest inside + the test process itself. This means it can return a + :py:class:`HookRecorder` instance which gives more detailed results + from that run than can be done by matching stdout/stderr from + :py:meth:`runpytest`. + + :param args: + Command line arguments to pass to :py:func:`pytest.main`. + :param plugins: + Extra plugin instances the ``pytest.main()`` instance should use. + :param no_reraise_ctrlc: + Typically we reraise keyboard interrupts from the child run. If + True, the KeyboardInterrupt exception is captured. + """ + # (maybe a cpython bug?) the importlib cache sometimes isn't updated + # properly between file creation and inline_run (especially if imports + # are interspersed with file creation) + importlib.invalidate_caches() + + plugins = list(plugins) + finalizers = [] + try: + # Any sys.module or sys.path changes done while running pytest + # inline should be reverted after the test run completes to avoid + # clashing with later inline tests run within the same pytest test, + # e.g. just because they use matching test module names. + finalizers.append(self.__take_sys_modules_snapshot().restore) + finalizers.append(SysPathsSnapshot().restore) + + # Important note: + # - our tests should not leave any other references/registrations + # laying around other than possibly loaded test modules + # referenced from sys.modules, as nothing will clean those up + # automatically + + rec = [] + + class Collect: + def pytest_configure(x, config: Config) -> None: + rec.append(self.make_hook_recorder(config.pluginmanager)) + + plugins.append(Collect()) + ret = main([str(x) for x in args], plugins=plugins) + if len(rec) == 1: + reprec = rec.pop() + else: + + class reprec: # type: ignore + pass + + reprec.ret = ret + + # Typically we reraise keyboard interrupts from the child run + # because it's our user requesting interruption of the testing. + if ret == ExitCode.INTERRUPTED and not no_reraise_ctrlc: + calls = reprec.getcalls("pytest_keyboard_interrupt") + if calls and calls[-1].excinfo.type == KeyboardInterrupt: + raise KeyboardInterrupt() + return reprec + finally: + for finalizer in finalizers: + finalizer() + + def runpytest_inprocess( + self, *args: Union[str, "os.PathLike[str]"], **kwargs: Any + ) -> RunResult: + """Return result of running pytest in-process, providing a similar + interface to what self.runpytest() provides.""" + syspathinsert = kwargs.pop("syspathinsert", False) + + if syspathinsert: + self.syspathinsert() + now = timing.time() + capture = _get_multicapture("sys") + capture.start_capturing() + try: + try: + reprec = self.inline_run(*args, **kwargs) + except SystemExit as e: + ret = e.args[0] + try: + ret = ExitCode(e.args[0]) + except ValueError: + pass + + class reprec: # type: ignore + ret = ret + + except Exception: + traceback.print_exc() + + class reprec: # type: ignore + ret = ExitCode(3) + + finally: + out, err = capture.readouterr() + capture.stop_capturing() + sys.stdout.write(out) + sys.stderr.write(err) + + assert reprec.ret is not None + res = RunResult( + reprec.ret, out.splitlines(), err.splitlines(), timing.time() - now + ) + res.reprec = reprec # type: ignore + return res + + def runpytest( + self, *args: Union[str, "os.PathLike[str]"], **kwargs: Any + ) -> RunResult: + """Run pytest inline or in a subprocess, depending on the command line + option "--runpytest" and return a :py:class:`~pytest.RunResult`.""" + new_args = self._ensure_basetemp(args) + if self._method == "inprocess": + return self.runpytest_inprocess(*new_args, **kwargs) + elif self._method == "subprocess": + return self.runpytest_subprocess(*new_args, **kwargs) + raise RuntimeError(f"Unrecognized runpytest option: {self._method}") + + def _ensure_basetemp( + self, args: Sequence[Union[str, "os.PathLike[str]"]] + ) -> List[Union[str, "os.PathLike[str]"]]: + new_args = list(args) + for x in new_args: + if str(x).startswith("--basetemp"): + break + else: + new_args.append("--basetemp=%s" % self.path.parent.joinpath("basetemp")) + return new_args + + def parseconfig(self, *args: Union[str, "os.PathLike[str]"]) -> Config: + """Return a new pytest :class:`pytest.Config` instance from given + commandline args. + + This invokes the pytest bootstrapping code in _pytest.config to create a + new :py:class:`pytest.PytestPluginManager` and call the + :hook:`pytest_cmdline_parse` hook to create a new :class:`pytest.Config` + instance. + + If :attr:`plugins` has been populated they should be plugin modules + to be registered with the plugin manager. + """ + import _pytest.config + + new_args = self._ensure_basetemp(args) + new_args = [str(x) for x in new_args] + + config = _pytest.config._prepareconfig(new_args, self.plugins) # type: ignore[arg-type] + # we don't know what the test will do with this half-setup config + # object and thus we make sure it gets unconfigured properly in any + # case (otherwise capturing could still be active, for example) + self._request.addfinalizer(config._ensure_unconfigure) + return config + + def parseconfigure(self, *args: Union[str, "os.PathLike[str]"]) -> Config: + """Return a new pytest configured Config instance. + + Returns a new :py:class:`pytest.Config` instance like + :py:meth:`parseconfig`, but also calls the :hook:`pytest_configure` + hook. + """ + config = self.parseconfig(*args) + config._do_configure() + return config + + def getitem( + self, source: Union[str, "os.PathLike[str]"], funcname: str = "test_func" + ) -> Item: + """Return the test item for a test function. + + Writes the source to a python file and runs pytest's collection on + the resulting module, returning the test item for the requested + function name. + + :param source: + The module source. + :param funcname: + The name of the test function for which to return a test item. + :returns: + The test item. + """ + items = self.getitems(source) + for item in items: + if item.name == funcname: + return item + assert 0, "{!r} item not found in module:\n{}\nitems: {}".format( + funcname, source, items + ) + + def getitems(self, source: Union[str, "os.PathLike[str]"]) -> List[Item]: + """Return all test items collected from the module. + + Writes the source to a Python file and runs pytest's collection on + the resulting module, returning all test items contained within. + """ + modcol = self.getmodulecol(source) + return self.genitems([modcol]) + + def getmodulecol( + self, + source: Union[str, "os.PathLike[str]"], + configargs=(), + *, + withinit: bool = False, + ): + """Return the module collection node for ``source``. + + Writes ``source`` to a file using :py:meth:`makepyfile` and then + runs the pytest collection on it, returning the collection node for the + test module. + + :param source: + The source code of the module to collect. + + :param configargs: + Any extra arguments to pass to :py:meth:`parseconfigure`. + + :param withinit: + Whether to also write an ``__init__.py`` file to the same + directory to ensure it is a package. + """ + if isinstance(source, os.PathLike): + path = self.path.joinpath(source) + assert not withinit, "not supported for paths" + else: + kw = {self._name: str(source)} + path = self.makepyfile(**kw) + if withinit: + self.makepyfile(__init__="#") + self.config = config = self.parseconfigure(path, *configargs) + return self.getnode(config, path) + + def collect_by_name( + self, modcol: Collector, name: str + ) -> Optional[Union[Item, Collector]]: + """Return the collection node for name from the module collection. + + Searches a module collection node for a collection node matching the + given name. + + :param modcol: A module collection node; see :py:meth:`getmodulecol`. + :param name: The name of the node to return. + """ + if modcol not in self._mod_collections: + self._mod_collections[modcol] = list(modcol.collect()) + for colitem in self._mod_collections[modcol]: + if colitem.name == name: + return colitem + return None + + def popen( + self, + cmdargs: Sequence[Union[str, "os.PathLike[str]"]], + stdout: Union[int, TextIO] = subprocess.PIPE, + stderr: Union[int, TextIO] = subprocess.PIPE, + stdin: Union[NotSetType, bytes, IO[Any], int] = CLOSE_STDIN, + **kw, + ): + """Invoke :py:class:`subprocess.Popen`. + + Calls :py:class:`subprocess.Popen` making sure the current working + directory is in ``PYTHONPATH``. + + You probably want to use :py:meth:`run` instead. + """ + env = os.environ.copy() + env["PYTHONPATH"] = os.pathsep.join( + filter(None, [os.getcwd(), env.get("PYTHONPATH", "")]) + ) + kw["env"] = env + + if stdin is self.CLOSE_STDIN: + kw["stdin"] = subprocess.PIPE + elif isinstance(stdin, bytes): + kw["stdin"] = subprocess.PIPE + else: + kw["stdin"] = stdin + + popen = subprocess.Popen(cmdargs, stdout=stdout, stderr=stderr, **kw) + if stdin is self.CLOSE_STDIN: + assert popen.stdin is not None + popen.stdin.close() + elif isinstance(stdin, bytes): + assert popen.stdin is not None + popen.stdin.write(stdin) + + return popen + + def run( + self, + *cmdargs: Union[str, "os.PathLike[str]"], + timeout: Optional[float] = None, + stdin: Union[NotSetType, bytes, IO[Any], int] = CLOSE_STDIN, + ) -> RunResult: + """Run a command with arguments. + + Run a process using :py:class:`subprocess.Popen` saving the stdout and + stderr. + + :param cmdargs: + The sequence of arguments to pass to :py:class:`subprocess.Popen`, + with path-like objects being converted to :py:class:`str` + automatically. + :param timeout: + The period in seconds after which to timeout and raise + :py:class:`Pytester.TimeoutExpired`. + :param stdin: + Optional standard input. + + - If it is :py:attr:`CLOSE_STDIN` (Default), then this method calls + :py:class:`subprocess.Popen` with ``stdin=subprocess.PIPE``, and + the standard input is closed immediately after the new command is + started. + + - If it is of type :py:class:`bytes`, these bytes are sent to the + standard input of the command. + + - Otherwise, it is passed through to :py:class:`subprocess.Popen`. + For further information in this case, consult the document of the + ``stdin`` parameter in :py:class:`subprocess.Popen`. + :returns: + The result. + """ + __tracebackhide__ = True + + cmdargs = tuple(os.fspath(arg) for arg in cmdargs) + p1 = self.path.joinpath("stdout") + p2 = self.path.joinpath("stderr") + print("running:", *cmdargs) + print(" in:", Path.cwd()) + + with p1.open("w", encoding="utf8") as f1, p2.open("w", encoding="utf8") as f2: + now = timing.time() + popen = self.popen( + cmdargs, + stdin=stdin, + stdout=f1, + stderr=f2, + close_fds=(sys.platform != "win32"), + ) + if popen.stdin is not None: + popen.stdin.close() + + def handle_timeout() -> None: + __tracebackhide__ = True + + timeout_message = ( + "{seconds} second timeout expired running:" + " {command}".format(seconds=timeout, command=cmdargs) + ) + + popen.kill() + popen.wait() + raise self.TimeoutExpired(timeout_message) + + if timeout is None: + ret = popen.wait() + else: + try: + ret = popen.wait(timeout) + except subprocess.TimeoutExpired: + handle_timeout() + + with p1.open(encoding="utf8") as f1, p2.open(encoding="utf8") as f2: + out = f1.read().splitlines() + err = f2.read().splitlines() + + self._dump_lines(out, sys.stdout) + self._dump_lines(err, sys.stderr) + + with contextlib.suppress(ValueError): + ret = ExitCode(ret) + return RunResult(ret, out, err, timing.time() - now) + + def _dump_lines(self, lines, fp): + try: + for line in lines: + print(line, file=fp) + except UnicodeEncodeError: + print(f"couldn't print to {fp} because of encoding") + + def _getpytestargs(self) -> Tuple[str, ...]: + return sys.executable, "-mpytest" + + def runpython(self, script: "os.PathLike[str]") -> RunResult: + """Run a python script using sys.executable as interpreter.""" + return self.run(sys.executable, script) + + def runpython_c(self, command: str) -> RunResult: + """Run ``python -c "command"``.""" + return self.run(sys.executable, "-c", command) + + def runpytest_subprocess( + self, *args: Union[str, "os.PathLike[str]"], timeout: Optional[float] = None + ) -> RunResult: + """Run pytest as a subprocess with given arguments. + + Any plugins added to the :py:attr:`plugins` list will be added using the + ``-p`` command line option. Additionally ``--basetemp`` is used to put + any temporary files and directories in a numbered directory prefixed + with "runpytest-" to not conflict with the normal numbered pytest + location for temporary files and directories. + + :param args: + The sequence of arguments to pass to the pytest subprocess. + :param timeout: + The period in seconds after which to timeout and raise + :py:class:`Pytester.TimeoutExpired`. + :returns: + The result. + """ + __tracebackhide__ = True + p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700) + args = ("--basetemp=%s" % p,) + args + plugins = [x for x in self.plugins if isinstance(x, str)] + if plugins: + args = ("-p", plugins[0]) + args + args = self._getpytestargs() + args + return self.run(*args, timeout=timeout) + + def spawn_pytest( + self, string: str, expect_timeout: float = 10.0 + ) -> "pexpect.spawn": + """Run pytest using pexpect. + + This makes sure to use the right pytest and sets up the temporary + directory locations. + + The pexpect child is returned. + """ + basetemp = self.path / "temp-pexpect" + basetemp.mkdir(mode=0o700) + invoke = " ".join(map(str, self._getpytestargs())) + cmd = f"{invoke} --basetemp={basetemp} {string}" + return self.spawn(cmd, expect_timeout=expect_timeout) + + def spawn(self, cmd: str, expect_timeout: float = 10.0) -> "pexpect.spawn": + """Run a command using pexpect. + + The pexpect child is returned. + """ + pexpect = importorskip("pexpect", "3.0") + if hasattr(sys, "pypy_version_info") and "64" in platform.machine(): + skip("pypy-64 bit not supported") + if not hasattr(pexpect, "spawn"): + skip("pexpect.spawn not available") + logfile = self.path.joinpath("spawn.out").open("wb") + + child = pexpect.spawn(cmd, logfile=logfile, timeout=expect_timeout) + self._request.addfinalizer(logfile.close) + return child + + +class LineComp: + def __init__(self) -> None: + self.stringio = StringIO() + """:class:`python:io.StringIO()` instance used for input.""" + + def assert_contains_lines(self, lines2: Sequence[str]) -> None: + """Assert that ``lines2`` are contained (linearly) in :attr:`stringio`'s value. + + Lines are matched using :func:`LineMatcher.fnmatch_lines `. + """ + __tracebackhide__ = True + val = self.stringio.getvalue() + self.stringio.truncate(0) + self.stringio.seek(0) + lines1 = val.split("\n") + LineMatcher(lines1).fnmatch_lines(lines2) + + +class LineMatcher: + """Flexible matching of text. + + This is a convenience class to test large texts like the output of + commands. + + The constructor takes a list of lines without their trailing newlines, i.e. + ``text.splitlines()``. + """ + + def __init__(self, lines: List[str]) -> None: + self.lines = lines + self._log_output: List[str] = [] + + def __str__(self) -> str: + """Return the entire original text. + + .. versionadded:: 6.2 + You can use :meth:`str` in older versions. + """ + return "\n".join(self.lines) + + def _getlines(self, lines2: Union[str, Sequence[str], Source]) -> Sequence[str]: + if isinstance(lines2, str): + lines2 = Source(lines2) + if isinstance(lines2, Source): + lines2 = lines2.strip().lines + return lines2 + + def fnmatch_lines_random(self, lines2: Sequence[str]) -> None: + """Check lines exist in the output in any order (using :func:`python:fnmatch.fnmatch`).""" + __tracebackhide__ = True + self._match_lines_random(lines2, fnmatch) + + def re_match_lines_random(self, lines2: Sequence[str]) -> None: + """Check lines exist in the output in any order (using :func:`python:re.match`).""" + __tracebackhide__ = True + self._match_lines_random(lines2, lambda name, pat: bool(re.match(pat, name))) + + def _match_lines_random( + self, lines2: Sequence[str], match_func: Callable[[str, str], bool] + ) -> None: + __tracebackhide__ = True + lines2 = self._getlines(lines2) + for line in lines2: + for x in self.lines: + if line == x or match_func(x, line): + self._log("matched: ", repr(line)) + break + else: + msg = "line %r not found in output" % line + self._log(msg) + self._fail(msg) + + def get_lines_after(self, fnline: str) -> Sequence[str]: + """Return all lines following the given line in the text. + + The given line can contain glob wildcards. + """ + for i, line in enumerate(self.lines): + if fnline == line or fnmatch(line, fnline): + return self.lines[i + 1 :] + raise ValueError("line %r not found in output" % fnline) + + def _log(self, *args) -> None: + self._log_output.append(" ".join(str(x) for x in args)) + + @property + def _log_text(self) -> str: + return "\n".join(self._log_output) + + def fnmatch_lines( + self, lines2: Sequence[str], *, consecutive: bool = False + ) -> None: + """Check lines exist in the output (using :func:`python:fnmatch.fnmatch`). + + The argument is a list of lines which have to match and can use glob + wildcards. If they do not match a pytest.fail() is called. The + matches and non-matches are also shown as part of the error message. + + :param lines2: String patterns to match. + :param consecutive: Match lines consecutively? + """ + __tracebackhide__ = True + self._match_lines(lines2, fnmatch, "fnmatch", consecutive=consecutive) + + def re_match_lines( + self, lines2: Sequence[str], *, consecutive: bool = False + ) -> None: + """Check lines exist in the output (using :func:`python:re.match`). + + The argument is a list of lines which have to match using ``re.match``. + If they do not match a pytest.fail() is called. + + The matches and non-matches are also shown as part of the error message. + + :param lines2: string patterns to match. + :param consecutive: match lines consecutively? + """ + __tracebackhide__ = True + self._match_lines( + lines2, + lambda name, pat: bool(re.match(pat, name)), + "re.match", + consecutive=consecutive, + ) + + def _match_lines( + self, + lines2: Sequence[str], + match_func: Callable[[str, str], bool], + match_nickname: str, + *, + consecutive: bool = False, + ) -> None: + """Underlying implementation of ``fnmatch_lines`` and ``re_match_lines``. + + :param Sequence[str] lines2: + List of string patterns to match. The actual format depends on + ``match_func``. + :param match_func: + A callable ``match_func(line, pattern)`` where line is the + captured line from stdout/stderr and pattern is the matching + pattern. + :param str match_nickname: + The nickname for the match function that will be logged to stdout + when a match occurs. + :param consecutive: + Match lines consecutively? + """ + if not isinstance(lines2, collections.abc.Sequence): + raise TypeError(f"invalid type for lines2: {type(lines2).__name__}") + lines2 = self._getlines(lines2) + lines1 = self.lines[:] + extralines = [] + __tracebackhide__ = True + wnick = len(match_nickname) + 1 + started = False + for line in lines2: + nomatchprinted = False + while lines1: + nextline = lines1.pop(0) + if line == nextline: + self._log("exact match:", repr(line)) + started = True + break + elif match_func(nextline, line): + self._log("%s:" % match_nickname, repr(line)) + self._log( + "{:>{width}}".format("with:", width=wnick), repr(nextline) + ) + started = True + break + else: + if consecutive and started: + msg = f"no consecutive match: {line!r}" + self._log(msg) + self._log( + "{:>{width}}".format("with:", width=wnick), repr(nextline) + ) + self._fail(msg) + if not nomatchprinted: + self._log( + "{:>{width}}".format("nomatch:", width=wnick), repr(line) + ) + nomatchprinted = True + self._log("{:>{width}}".format("and:", width=wnick), repr(nextline)) + extralines.append(nextline) + else: + msg = f"remains unmatched: {line!r}" + self._log(msg) + self._fail(msg) + self._log_output = [] + + def no_fnmatch_line(self, pat: str) -> None: + """Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``. + + :param str pat: The pattern to match lines. + """ + __tracebackhide__ = True + self._no_match_line(pat, fnmatch, "fnmatch") + + def no_re_match_line(self, pat: str) -> None: + """Ensure captured lines do not match the given pattern, using ``re.match``. + + :param str pat: The regular expression to match lines. + """ + __tracebackhide__ = True + self._no_match_line( + pat, lambda name, pat: bool(re.match(pat, name)), "re.match" + ) + + def _no_match_line( + self, pat: str, match_func: Callable[[str, str], bool], match_nickname: str + ) -> None: + """Ensure captured lines does not have a the given pattern, using ``fnmatch.fnmatch``. + + :param str pat: The pattern to match lines. + """ + __tracebackhide__ = True + nomatch_printed = False + wnick = len(match_nickname) + 1 + for line in self.lines: + if match_func(line, pat): + msg = f"{match_nickname}: {pat!r}" + self._log(msg) + self._log("{:>{width}}".format("with:", width=wnick), repr(line)) + self._fail(msg) + else: + if not nomatch_printed: + self._log("{:>{width}}".format("nomatch:", width=wnick), repr(pat)) + nomatch_printed = True + self._log("{:>{width}}".format("and:", width=wnick), repr(line)) + self._log_output = [] + + def _fail(self, msg: str) -> None: + __tracebackhide__ = True + log_text = self._log_text + self._log_output = [] + fail(log_text) + + def str(self) -> str: + """Return the entire original text.""" + return str(self) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester_assertions.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester_assertions.py new file mode 100644 index 00000000..657e4db5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester_assertions.py @@ -0,0 +1,75 @@ +"""Helper plugin for pytester; should not be loaded on its own.""" +# This plugin contains assertions used by pytester. pytester cannot +# contain them itself, since it is imported by the `pytest` module, +# hence cannot be subject to assertion rewriting, which requires a +# module to not be already imported. +from typing import Dict +from typing import Optional +from typing import Sequence +from typing import Tuple +from typing import Union + +from _pytest.reports import CollectReport +from _pytest.reports import TestReport + + +def assertoutcome( + outcomes: Tuple[ + Sequence[TestReport], + Sequence[Union[CollectReport, TestReport]], + Sequence[Union[CollectReport, TestReport]], + ], + passed: int = 0, + skipped: int = 0, + failed: int = 0, +) -> None: + __tracebackhide__ = True + + realpassed, realskipped, realfailed = outcomes + obtained = { + "passed": len(realpassed), + "skipped": len(realskipped), + "failed": len(realfailed), + } + expected = {"passed": passed, "skipped": skipped, "failed": failed} + assert obtained == expected, outcomes + + +def assert_outcomes( + outcomes: Dict[str, int], + passed: int = 0, + skipped: int = 0, + failed: int = 0, + errors: int = 0, + xpassed: int = 0, + xfailed: int = 0, + warnings: Optional[int] = None, + deselected: Optional[int] = None, +) -> None: + """Assert that the specified outcomes appear with the respective + numbers (0 means it didn't occur) in the text output from a test run.""" + __tracebackhide__ = True + + obtained = { + "passed": outcomes.get("passed", 0), + "skipped": outcomes.get("skipped", 0), + "failed": outcomes.get("failed", 0), + "errors": outcomes.get("errors", 0), + "xpassed": outcomes.get("xpassed", 0), + "xfailed": outcomes.get("xfailed", 0), + } + expected = { + "passed": passed, + "skipped": skipped, + "failed": failed, + "errors": errors, + "xpassed": xpassed, + "xfailed": xfailed, + } + if warnings is not None: + obtained["warnings"] = outcomes.get("warnings", 0) + expected["warnings"] = warnings + if deselected is not None: + obtained["deselected"] = outcomes.get("deselected", 0) + expected["deselected"] = deselected + assert obtained == expected diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/python.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/python.py new file mode 100644 index 00000000..5f8be5d9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/python.py @@ -0,0 +1,1843 @@ +"""Python test discovery, setup and run of test functions.""" +import dataclasses +import enum +import fnmatch +import inspect +import itertools +import os +import sys +import types +import warnings +from collections import Counter +from collections import defaultdict +from functools import partial +from pathlib import Path +from typing import Any +from typing import Callable +from typing import Dict +from typing import Generator +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Mapping +from typing import Optional +from typing import Pattern +from typing import Sequence +from typing import Set +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +import _pytest +from _pytest import fixtures +from _pytest import nodes +from _pytest._code import filter_traceback +from _pytest._code import getfslineno +from _pytest._code.code import ExceptionInfo +from _pytest._code.code import TerminalRepr +from _pytest._code.code import Traceback +from _pytest._io import TerminalWriter +from _pytest._io.saferepr import saferepr +from _pytest.compat import ascii_escaped +from _pytest.compat import assert_never +from _pytest.compat import final +from _pytest.compat import get_default_arg_names +from _pytest.compat import get_real_func +from _pytest.compat import getimfunc +from _pytest.compat import getlocation +from _pytest.compat import is_async_function +from _pytest.compat import is_generator +from _pytest.compat import LEGACY_PATH +from _pytest.compat import NOTSET +from _pytest.compat import safe_getattr +from _pytest.compat import safe_isclass +from _pytest.compat import STRING_TYPES +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.deprecated import INSTANCE_COLLECTOR +from _pytest.deprecated import NOSE_SUPPORT_METHOD +from _pytest.fixtures import FuncFixtureInfo +from _pytest.main import Session +from _pytest.mark import MARK_GEN +from _pytest.mark import ParameterSet +from _pytest.mark.structures import get_unpacked_marks +from _pytest.mark.structures import Mark +from _pytest.mark.structures import MarkDecorator +from _pytest.mark.structures import normalize_mark_list +from _pytest.outcomes import fail +from _pytest.outcomes import skip +from _pytest.pathlib import bestrelpath +from _pytest.pathlib import fnmatch_ex +from _pytest.pathlib import import_path +from _pytest.pathlib import ImportPathMismatchError +from _pytest.pathlib import parts +from _pytest.pathlib import visit +from _pytest.scope import Scope +from _pytest.warning_types import PytestCollectionWarning +from _pytest.warning_types import PytestReturnNotNoneWarning +from _pytest.warning_types import PytestUnhandledCoroutineWarning + +if TYPE_CHECKING: + from typing_extensions import Literal + + from _pytest.scope import _ScopeName + + +_PYTEST_DIR = Path(_pytest.__file__).parent + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group.addoption( + "--fixtures", + "--funcargs", + action="store_true", + dest="showfixtures", + default=False, + help="Show available fixtures, sorted by plugin appearance " + "(fixtures with leading '_' are only shown with '-v')", + ) + group.addoption( + "--fixtures-per-test", + action="store_true", + dest="show_fixtures_per_test", + default=False, + help="Show fixtures per test", + ) + parser.addini( + "python_files", + type="args", + # NOTE: default is also used in AssertionRewritingHook. + default=["test_*.py", "*_test.py"], + help="Glob-style file patterns for Python test module discovery", + ) + parser.addini( + "python_classes", + type="args", + default=["Test"], + help="Prefixes or glob names for Python test class discovery", + ) + parser.addini( + "python_functions", + type="args", + default=["test"], + help="Prefixes or glob names for Python test function and method discovery", + ) + parser.addini( + "disable_test_id_escaping_and_forfeit_all_rights_to_community_support", + type="bool", + default=False, + help="Disable string escape non-ASCII characters, might cause unwanted " + "side effects(use at your own risk)", + ) + + +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + if config.option.showfixtures: + showfixtures(config) + return 0 + if config.option.show_fixtures_per_test: + show_fixtures_per_test(config) + return 0 + return None + + +def pytest_generate_tests(metafunc: "Metafunc") -> None: + for marker in metafunc.definition.iter_markers(name="parametrize"): + metafunc.parametrize(*marker.args, **marker.kwargs, _param_mark=marker) + + +def pytest_configure(config: Config) -> None: + config.addinivalue_line( + "markers", + "parametrize(argnames, argvalues): call a test function multiple " + "times passing in different arguments in turn. argvalues generally " + "needs to be a list of values if argnames specifies only one name " + "or a list of tuples of values if argnames specifies multiple names. " + "Example: @parametrize('arg1', [1,2]) would lead to two calls of the " + "decorated test function, one with arg1=1 and another with arg1=2." + "see https://docs.pytest.org/en/stable/how-to/parametrize.html for more info " + "and examples.", + ) + config.addinivalue_line( + "markers", + "usefixtures(fixturename1, fixturename2, ...): mark tests as needing " + "all of the specified fixtures. see " + "https://docs.pytest.org/en/stable/explanation/fixtures.html#usefixtures ", + ) + + +def async_warn_and_skip(nodeid: str) -> None: + msg = "async def functions are not natively supported and have been skipped.\n" + msg += ( + "You need to install a suitable plugin for your async framework, for example:\n" + ) + msg += " - anyio\n" + msg += " - pytest-asyncio\n" + msg += " - pytest-tornasync\n" + msg += " - pytest-trio\n" + msg += " - pytest-twisted" + warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid))) + skip(reason="async def function and no async plugin installed (see warnings)") + + +@hookimpl(trylast=True) +def pytest_pyfunc_call(pyfuncitem: "Function") -> Optional[object]: + testfunction = pyfuncitem.obj + if is_async_function(testfunction): + async_warn_and_skip(pyfuncitem.nodeid) + funcargs = pyfuncitem.funcargs + testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} + result = testfunction(**testargs) + if hasattr(result, "__await__") or hasattr(result, "__aiter__"): + async_warn_and_skip(pyfuncitem.nodeid) + elif result is not None: + warnings.warn( + PytestReturnNotNoneWarning( + f"Expected None, but {pyfuncitem.nodeid} returned {result!r}, which will be an error in a " + "future version of pytest. Did you mean to use `assert` instead of `return`?" + ) + ) + return True + + +def pytest_collect_file(file_path: Path, parent: nodes.Collector) -> Optional["Module"]: + if file_path.suffix == ".py": + if not parent.session.isinitpath(file_path): + if not path_matches_patterns( + file_path, parent.config.getini("python_files") + ["__init__.py"] + ): + return None + ihook = parent.session.gethookproxy(file_path) + module: Module = ihook.pytest_pycollect_makemodule( + module_path=file_path, parent=parent + ) + return module + return None + + +def path_matches_patterns(path: Path, patterns: Iterable[str]) -> bool: + """Return whether path matches any of the patterns in the list of globs given.""" + return any(fnmatch_ex(pattern, path) for pattern in patterns) + + +def pytest_pycollect_makemodule(module_path: Path, parent) -> "Module": + if module_path.name == "__init__.py": + pkg: Package = Package.from_parent(parent, path=module_path) + return pkg + mod: Module = Module.from_parent(parent, path=module_path) + return mod + + +@hookimpl(trylast=True) +def pytest_pycollect_makeitem( + collector: Union["Module", "Class"], name: str, obj: object +) -> Union[None, nodes.Item, nodes.Collector, List[Union[nodes.Item, nodes.Collector]]]: + assert isinstance(collector, (Class, Module)), type(collector) + # Nothing was collected elsewhere, let's do it here. + if safe_isclass(obj): + if collector.istestclass(obj, name): + klass: Class = Class.from_parent(collector, name=name, obj=obj) + return klass + elif collector.istestfunction(obj, name): + # mock seems to store unbound methods (issue473), normalize it. + obj = getattr(obj, "__func__", obj) + # We need to try and unwrap the function if it's a functools.partial + # or a functools.wrapped. + # We mustn't if it's been wrapped with mock.patch (python 2 only). + if not (inspect.isfunction(obj) or inspect.isfunction(get_real_func(obj))): + filename, lineno = getfslineno(obj) + warnings.warn_explicit( + message=PytestCollectionWarning( + "cannot collect %r because it is not a function." % name + ), + category=None, + filename=str(filename), + lineno=lineno + 1, + ) + elif getattr(obj, "__test__", True): + if is_generator(obj): + res: Function = Function.from_parent(collector, name=name) + reason = "yield tests were removed in pytest 4.0 - {name} will be ignored".format( + name=name + ) + res.add_marker(MARK_GEN.xfail(run=False, reason=reason)) + res.warn(PytestCollectionWarning(reason)) + return res + else: + return list(collector._genfunctions(name, obj)) + return None + + +class PyobjMixin(nodes.Node): + """this mix-in inherits from Node to carry over the typing information + + as its intended to always mix in before a node + its position in the mro is unaffected""" + + _ALLOW_MARKERS = True + + @property + def module(self): + """Python module object this node was collected from (can be None).""" + node = self.getparent(Module) + return node.obj if node is not None else None + + @property + def cls(self): + """Python class object this node was collected from (can be None).""" + node = self.getparent(Class) + return node.obj if node is not None else None + + @property + def instance(self): + """Python instance object the function is bound to. + + Returns None if not a test method, e.g. for a standalone test function, + a staticmethod, a class or a module. + """ + node = self.getparent(Function) + return getattr(node.obj, "__self__", None) if node is not None else None + + @property + def obj(self): + """Underlying Python object.""" + obj = getattr(self, "_obj", None) + if obj is None: + self._obj = obj = self._getobj() + # XXX evil hack + # used to avoid Function marker duplication + if self._ALLOW_MARKERS: + self.own_markers.extend(get_unpacked_marks(self.obj)) + # This assumes that `obj` is called before there is a chance + # to add custom keys to `self.keywords`, so no fear of overriding. + self.keywords.update((mark.name, mark) for mark in self.own_markers) + return obj + + @obj.setter + def obj(self, value): + self._obj = value + + def _getobj(self): + """Get the underlying Python object. May be overwritten by subclasses.""" + # TODO: Improve the type of `parent` such that assert/ignore aren't needed. + assert self.parent is not None + obj = self.parent.obj # type: ignore[attr-defined] + return getattr(obj, self.name) + + def getmodpath(self, stopatmodule: bool = True, includemodule: bool = False) -> str: + """Return Python path relative to the containing module.""" + chain = self.listchain() + chain.reverse() + parts = [] + for node in chain: + name = node.name + if isinstance(node, Module): + name = os.path.splitext(name)[0] + if stopatmodule: + if includemodule: + parts.append(name) + break + parts.append(name) + parts.reverse() + return ".".join(parts) + + def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]: + # XXX caching? + obj = self.obj + compat_co_firstlineno = getattr(obj, "compat_co_firstlineno", None) + if isinstance(compat_co_firstlineno, int): + # nose compatibility + file_path = sys.modules[obj.__module__].__file__ + assert file_path is not None + if file_path.endswith(".pyc"): + file_path = file_path[:-1] + path: Union["os.PathLike[str]", str] = file_path + lineno = compat_co_firstlineno + else: + path, lineno = getfslineno(obj) + modpath = self.getmodpath() + assert isinstance(lineno, int) + return path, lineno, modpath + + +# As an optimization, these builtin attribute names are pre-ignored when +# iterating over an object during collection -- the pytest_pycollect_makeitem +# hook is not called for them. +# fmt: off +class _EmptyClass: pass # noqa: E701 +IGNORED_ATTRIBUTES = frozenset.union( # noqa: E305 + frozenset(), + # Module. + dir(types.ModuleType("empty_module")), + # Some extra module attributes the above doesn't catch. + {"__builtins__", "__file__", "__cached__"}, + # Class. + dir(_EmptyClass), + # Instance. + dir(_EmptyClass()), +) +del _EmptyClass +# fmt: on + + +class PyCollector(PyobjMixin, nodes.Collector): + def funcnamefilter(self, name: str) -> bool: + return self._matches_prefix_or_glob_option("python_functions", name) + + def isnosetest(self, obj: object) -> bool: + """Look for the __test__ attribute, which is applied by the + @nose.tools.istest decorator. + """ + # We explicitly check for "is True" here to not mistakenly treat + # classes with a custom __getattr__ returning something truthy (like a + # function) as test classes. + return safe_getattr(obj, "__test__", False) is True + + def classnamefilter(self, name: str) -> bool: + return self._matches_prefix_or_glob_option("python_classes", name) + + def istestfunction(self, obj: object, name: str) -> bool: + if self.funcnamefilter(name) or self.isnosetest(obj): + if isinstance(obj, (staticmethod, classmethod)): + # staticmethods and classmethods need to be unwrapped. + obj = safe_getattr(obj, "__func__", False) + return callable(obj) and fixtures.getfixturemarker(obj) is None + else: + return False + + def istestclass(self, obj: object, name: str) -> bool: + return self.classnamefilter(name) or self.isnosetest(obj) + + def _matches_prefix_or_glob_option(self, option_name: str, name: str) -> bool: + """Check if the given name matches the prefix or glob-pattern defined + in ini configuration.""" + for option in self.config.getini(option_name): + if name.startswith(option): + return True + # Check that name looks like a glob-string before calling fnmatch + # because this is called for every name in each collected module, + # and fnmatch is somewhat expensive to call. + elif ("*" in option or "?" in option or "[" in option) and fnmatch.fnmatch( + name, option + ): + return True + return False + + def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]: + if not getattr(self.obj, "__test__", True): + return [] + + # Avoid random getattrs and peek in the __dict__ instead. + dicts = [getattr(self.obj, "__dict__", {})] + if isinstance(self.obj, type): + for basecls in self.obj.__mro__: + dicts.append(basecls.__dict__) + + # In each class, nodes should be definition ordered. + # __dict__ is definition ordered. + seen: Set[str] = set() + dict_values: List[List[Union[nodes.Item, nodes.Collector]]] = [] + ihook = self.ihook + for dic in dicts: + values: List[Union[nodes.Item, nodes.Collector]] = [] + # Note: seems like the dict can change during iteration - + # be careful not to remove the list() without consideration. + for name, obj in list(dic.items()): + if name in IGNORED_ATTRIBUTES: + continue + if name in seen: + continue + seen.add(name) + res = ihook.pytest_pycollect_makeitem( + collector=self, name=name, obj=obj + ) + if res is None: + continue + elif isinstance(res, list): + values.extend(res) + else: + values.append(res) + dict_values.append(values) + + # Between classes in the class hierarchy, reverse-MRO order -- nodes + # inherited from base classes should come before subclasses. + result = [] + for values in reversed(dict_values): + result.extend(values) + return result + + def _genfunctions(self, name: str, funcobj) -> Iterator["Function"]: + modulecol = self.getparent(Module) + assert modulecol is not None + module = modulecol.obj + clscol = self.getparent(Class) + cls = clscol and clscol.obj or None + + definition = FunctionDefinition.from_parent(self, name=name, callobj=funcobj) + fixtureinfo = definition._fixtureinfo + + # pytest_generate_tests impls call metafunc.parametrize() which fills + # metafunc._calls, the outcome of the hook. + metafunc = Metafunc( + definition=definition, + fixtureinfo=fixtureinfo, + config=self.config, + cls=cls, + module=module, + _ispytest=True, + ) + methods = [] + if hasattr(module, "pytest_generate_tests"): + methods.append(module.pytest_generate_tests) + if cls is not None and hasattr(cls, "pytest_generate_tests"): + methods.append(cls().pytest_generate_tests) + self.ihook.pytest_generate_tests.call_extra(methods, dict(metafunc=metafunc)) + + if not metafunc._calls: + yield Function.from_parent(self, name=name, fixtureinfo=fixtureinfo) + else: + # Add funcargs() as fixturedefs to fixtureinfo.arg2fixturedefs. + fm = self.session._fixturemanager + fixtures.add_funcarg_pseudo_fixture_def(self, metafunc, fm) + + # Add_funcarg_pseudo_fixture_def may have shadowed some fixtures + # with direct parametrization, so make sure we update what the + # function really needs. + fixtureinfo.prune_dependency_tree() + + for callspec in metafunc._calls: + subname = f"{name}[{callspec.id}]" + yield Function.from_parent( + self, + name=subname, + callspec=callspec, + fixtureinfo=fixtureinfo, + keywords={callspec.id: True}, + originalname=name, + ) + + +class Module(nodes.File, PyCollector): + """Collector for test classes and functions in a Python module.""" + + def _getobj(self): + return self._importtestmodule() + + def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]: + self._inject_setup_module_fixture() + self._inject_setup_function_fixture() + self.session._fixturemanager.parsefactories(self) + return super().collect() + + def _inject_setup_module_fixture(self) -> None: + """Inject a hidden autouse, module scoped fixture into the collected module object + that invokes setUpModule/tearDownModule if either or both are available. + + Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with + other fixtures (#517). + """ + has_nose = self.config.pluginmanager.has_plugin("nose") + setup_module = _get_first_non_fixture_func( + self.obj, ("setUpModule", "setup_module") + ) + if setup_module is None and has_nose: + # The name "setup" is too common - only treat as fixture if callable. + setup_module = _get_first_non_fixture_func(self.obj, ("setup",)) + if not callable(setup_module): + setup_module = None + teardown_module = _get_first_non_fixture_func( + self.obj, ("tearDownModule", "teardown_module") + ) + if teardown_module is None and has_nose: + teardown_module = _get_first_non_fixture_func(self.obj, ("teardown",)) + # Same as "setup" above - only treat as fixture if callable. + if not callable(teardown_module): + teardown_module = None + + if setup_module is None and teardown_module is None: + return + + @fixtures.fixture( + autouse=True, + scope="module", + # Use a unique name to speed up lookup. + name=f"_xunit_setup_module_fixture_{self.obj.__name__}", + ) + def xunit_setup_module_fixture(request) -> Generator[None, None, None]: + if setup_module is not None: + _call_with_optional_argument(setup_module, request.module) + yield + if teardown_module is not None: + _call_with_optional_argument(teardown_module, request.module) + + self.obj.__pytest_setup_module = xunit_setup_module_fixture + + def _inject_setup_function_fixture(self) -> None: + """Inject a hidden autouse, function scoped fixture into the collected module object + that invokes setup_function/teardown_function if either or both are available. + + Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with + other fixtures (#517). + """ + setup_function = _get_first_non_fixture_func(self.obj, ("setup_function",)) + teardown_function = _get_first_non_fixture_func( + self.obj, ("teardown_function",) + ) + if setup_function is None and teardown_function is None: + return + + @fixtures.fixture( + autouse=True, + scope="function", + # Use a unique name to speed up lookup. + name=f"_xunit_setup_function_fixture_{self.obj.__name__}", + ) + def xunit_setup_function_fixture(request) -> Generator[None, None, None]: + if request.instance is not None: + # in this case we are bound to an instance, so we need to let + # setup_method handle this + yield + return + if setup_function is not None: + _call_with_optional_argument(setup_function, request.function) + yield + if teardown_function is not None: + _call_with_optional_argument(teardown_function, request.function) + + self.obj.__pytest_setup_function = xunit_setup_function_fixture + + def _importtestmodule(self): + # We assume we are only called once per module. + importmode = self.config.getoption("--import-mode") + try: + mod = import_path(self.path, mode=importmode, root=self.config.rootpath) + except SyntaxError as e: + raise self.CollectError( + ExceptionInfo.from_current().getrepr(style="short") + ) from e + except ImportPathMismatchError as e: + raise self.CollectError( + "import file mismatch:\n" + "imported module %r has this __file__ attribute:\n" + " %s\n" + "which is not the same as the test file we want to collect:\n" + " %s\n" + "HINT: remove __pycache__ / .pyc files and/or use a " + "unique basename for your test file modules" % e.args + ) from e + except ImportError as e: + exc_info = ExceptionInfo.from_current() + if self.config.getoption("verbose") < 2: + exc_info.traceback = exc_info.traceback.filter(filter_traceback) + exc_repr = ( + exc_info.getrepr(style="short") + if exc_info.traceback + else exc_info.exconly() + ) + formatted_tb = str(exc_repr) + raise self.CollectError( + "ImportError while importing test module '{path}'.\n" + "Hint: make sure your test modules/packages have valid Python names.\n" + "Traceback:\n" + "{traceback}".format(path=self.path, traceback=formatted_tb) + ) from e + except skip.Exception as e: + if e.allow_module_level: + raise + raise self.CollectError( + "Using pytest.skip outside of a test will skip the entire module. " + "If that's your intention, pass `allow_module_level=True`. " + "If you want to skip a specific test or an entire class, " + "use the @pytest.mark.skip or @pytest.mark.skipif decorators." + ) from e + self.config.pluginmanager.consider_module(mod) + return mod + + +class Package(Module): + """Collector for files and directories in a Python packages -- directories + with an `__init__.py` file.""" + + def __init__( + self, + fspath: Optional[LEGACY_PATH], + parent: nodes.Collector, + # NOTE: following args are unused: + config=None, + session=None, + nodeid=None, + path: Optional[Path] = None, + ) -> None: + # NOTE: Could be just the following, but kept as-is for compat. + # nodes.FSCollector.__init__(self, fspath, parent=parent) + session = parent.session + nodes.FSCollector.__init__( + self, + fspath=fspath, + path=path, + parent=parent, + config=config, + session=session, + nodeid=nodeid, + ) + self.name = self.path.parent.name + + def setup(self) -> None: + # Not using fixtures to call setup_module here because autouse fixtures + # from packages are not called automatically (#4085). + setup_module = _get_first_non_fixture_func( + self.obj, ("setUpModule", "setup_module") + ) + if setup_module is not None: + _call_with_optional_argument(setup_module, self.obj) + + teardown_module = _get_first_non_fixture_func( + self.obj, ("tearDownModule", "teardown_module") + ) + if teardown_module is not None: + func = partial(_call_with_optional_argument, teardown_module, self.obj) + self.addfinalizer(func) + + def _recurse(self, direntry: "os.DirEntry[str]") -> bool: + if direntry.name == "__pycache__": + return False + fspath = Path(direntry.path) + ihook = self.session.gethookproxy(fspath.parent) + if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config): + return False + return True + + def _collectfile( + self, fspath: Path, handle_dupes: bool = True + ) -> Sequence[nodes.Collector]: + assert ( + fspath.is_file() + ), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format( + fspath, fspath.is_dir(), fspath.exists(), fspath.is_symlink() + ) + ihook = self.session.gethookproxy(fspath) + if not self.session.isinitpath(fspath): + if ihook.pytest_ignore_collect(collection_path=fspath, config=self.config): + return () + + if handle_dupes: + keepduplicates = self.config.getoption("keepduplicates") + if not keepduplicates: + duplicate_paths = self.config.pluginmanager._duplicatepaths + if fspath in duplicate_paths: + return () + else: + duplicate_paths.add(fspath) + + return ihook.pytest_collect_file(file_path=fspath, parent=self) # type: ignore[no-any-return] + + def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]: + this_path = self.path.parent + + # Always collect the __init__ first. + if path_matches_patterns(self.path, self.config.getini("python_files")): + yield Module.from_parent(self, path=self.path) + + pkg_prefixes: Set[Path] = set() + for direntry in visit(str(this_path), recurse=self._recurse): + path = Path(direntry.path) + + # We will visit our own __init__.py file, in which case we skip it. + if direntry.is_file(): + if direntry.name == "__init__.py" and path.parent == this_path: + continue + + parts_ = parts(direntry.path) + if any( + str(pkg_prefix) in parts_ and pkg_prefix / "__init__.py" != path + for pkg_prefix in pkg_prefixes + ): + continue + + if direntry.is_file(): + yield from self._collectfile(path) + elif not direntry.is_dir(): + # Broken symlink or invalid/missing file. + continue + elif path.joinpath("__init__.py").is_file(): + pkg_prefixes.add(path) + + +def _call_with_optional_argument(func, arg) -> None: + """Call the given function with the given argument if func accepts one argument, otherwise + calls func without arguments.""" + arg_count = func.__code__.co_argcount + if inspect.ismethod(func): + arg_count -= 1 + if arg_count: + func(arg) + else: + func() + + +def _get_first_non_fixture_func(obj: object, names: Iterable[str]) -> Optional[object]: + """Return the attribute from the given object to be used as a setup/teardown + xunit-style function, but only if not marked as a fixture to avoid calling it twice. + """ + for name in names: + meth: Optional[object] = getattr(obj, name, None) + if meth is not None and fixtures.getfixturemarker(meth) is None: + return meth + return None + + +class Class(PyCollector): + """Collector for test methods (and nested classes) in a Python class.""" + + @classmethod + def from_parent(cls, parent, *, name, obj=None, **kw): + """The public constructor.""" + return super().from_parent(name=name, parent=parent, **kw) + + def newinstance(self): + return self.obj() + + def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]: + if not safe_getattr(self.obj, "__test__", True): + return [] + if hasinit(self.obj): + assert self.parent is not None + self.warn( + PytestCollectionWarning( + "cannot collect test class %r because it has a " + "__init__ constructor (from: %s)" + % (self.obj.__name__, self.parent.nodeid) + ) + ) + return [] + elif hasnew(self.obj): + assert self.parent is not None + self.warn( + PytestCollectionWarning( + "cannot collect test class %r because it has a " + "__new__ constructor (from: %s)" + % (self.obj.__name__, self.parent.nodeid) + ) + ) + return [] + + self._inject_setup_class_fixture() + self._inject_setup_method_fixture() + + self.session._fixturemanager.parsefactories(self.newinstance(), self.nodeid) + + return super().collect() + + def _inject_setup_class_fixture(self) -> None: + """Inject a hidden autouse, class scoped fixture into the collected class object + that invokes setup_class/teardown_class if either or both are available. + + Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with + other fixtures (#517). + """ + setup_class = _get_first_non_fixture_func(self.obj, ("setup_class",)) + teardown_class = _get_first_non_fixture_func(self.obj, ("teardown_class",)) + if setup_class is None and teardown_class is None: + return + + @fixtures.fixture( + autouse=True, + scope="class", + # Use a unique name to speed up lookup. + name=f"_xunit_setup_class_fixture_{self.obj.__qualname__}", + ) + def xunit_setup_class_fixture(cls) -> Generator[None, None, None]: + if setup_class is not None: + func = getimfunc(setup_class) + _call_with_optional_argument(func, self.obj) + yield + if teardown_class is not None: + func = getimfunc(teardown_class) + _call_with_optional_argument(func, self.obj) + + self.obj.__pytest_setup_class = xunit_setup_class_fixture + + def _inject_setup_method_fixture(self) -> None: + """Inject a hidden autouse, function scoped fixture into the collected class object + that invokes setup_method/teardown_method if either or both are available. + + Using a fixture to invoke these methods ensures we play nicely and unsurprisingly with + other fixtures (#517). + """ + has_nose = self.config.pluginmanager.has_plugin("nose") + setup_name = "setup_method" + setup_method = _get_first_non_fixture_func(self.obj, (setup_name,)) + emit_nose_setup_warning = False + if setup_method is None and has_nose: + setup_name = "setup" + emit_nose_setup_warning = True + setup_method = _get_first_non_fixture_func(self.obj, (setup_name,)) + teardown_name = "teardown_method" + teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,)) + emit_nose_teardown_warning = False + if teardown_method is None and has_nose: + teardown_name = "teardown" + emit_nose_teardown_warning = True + teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,)) + if setup_method is None and teardown_method is None: + return + + @fixtures.fixture( + autouse=True, + scope="function", + # Use a unique name to speed up lookup. + name=f"_xunit_setup_method_fixture_{self.obj.__qualname__}", + ) + def xunit_setup_method_fixture(self, request) -> Generator[None, None, None]: + method = request.function + if setup_method is not None: + func = getattr(self, setup_name) + _call_with_optional_argument(func, method) + if emit_nose_setup_warning: + warnings.warn( + NOSE_SUPPORT_METHOD.format( + nodeid=request.node.nodeid, method="setup" + ), + stacklevel=2, + ) + yield + if teardown_method is not None: + func = getattr(self, teardown_name) + _call_with_optional_argument(func, method) + if emit_nose_teardown_warning: + warnings.warn( + NOSE_SUPPORT_METHOD.format( + nodeid=request.node.nodeid, method="teardown" + ), + stacklevel=2, + ) + + self.obj.__pytest_setup_method = xunit_setup_method_fixture + + +class InstanceDummy: + """Instance used to be a node type between Class and Function. It has been + removed in pytest 7.0. Some plugins exist which reference `pytest.Instance` + only to ignore it; this dummy class keeps them working. This will be removed + in pytest 8.""" + + +def __getattr__(name: str) -> object: + if name == "Instance": + warnings.warn(INSTANCE_COLLECTOR, 2) + return InstanceDummy + raise AttributeError(f"module {__name__} has no attribute {name}") + + +def hasinit(obj: object) -> bool: + init: object = getattr(obj, "__init__", None) + if init: + return init != object.__init__ + return False + + +def hasnew(obj: object) -> bool: + new: object = getattr(obj, "__new__", None) + if new: + return new != object.__new__ + return False + + +@final +@dataclasses.dataclass(frozen=True) +class IdMaker: + """Make IDs for a parametrization.""" + + __slots__ = ( + "argnames", + "parametersets", + "idfn", + "ids", + "config", + "nodeid", + "func_name", + ) + + # The argnames of the parametrization. + argnames: Sequence[str] + # The ParameterSets of the parametrization. + parametersets: Sequence[ParameterSet] + # Optionally, a user-provided callable to make IDs for parameters in a + # ParameterSet. + idfn: Optional[Callable[[Any], Optional[object]]] + # Optionally, explicit IDs for ParameterSets by index. + ids: Optional[Sequence[Optional[object]]] + # Optionally, the pytest config. + # Used for controlling ASCII escaping, and for calling the + # :hook:`pytest_make_parametrize_id` hook. + config: Optional[Config] + # Optionally, the ID of the node being parametrized. + # Used only for clearer error messages. + nodeid: Optional[str] + # Optionally, the ID of the function being parametrized. + # Used only for clearer error messages. + func_name: Optional[str] + + def make_unique_parameterset_ids(self) -> List[str]: + """Make a unique identifier for each ParameterSet, that may be used to + identify the parametrization in a node ID. + + Format is -...-[counter], where prm_x_token is + - user-provided id, if given + - else an id derived from the value, applicable for certain types + - else + The counter suffix is appended only in case a string wouldn't be unique + otherwise. + """ + resolved_ids = list(self._resolve_ids()) + # All IDs must be unique! + if len(resolved_ids) != len(set(resolved_ids)): + # Record the number of occurrences of each ID. + id_counts = Counter(resolved_ids) + # Map the ID to its next suffix. + id_suffixes: Dict[str, int] = defaultdict(int) + # Suffix non-unique IDs to make them unique. + for index, id in enumerate(resolved_ids): + if id_counts[id] > 1: + resolved_ids[index] = f"{id}{id_suffixes[id]}" + id_suffixes[id] += 1 + return resolved_ids + + def _resolve_ids(self) -> Iterable[str]: + """Resolve IDs for all ParameterSets (may contain duplicates).""" + for idx, parameterset in enumerate(self.parametersets): + if parameterset.id is not None: + # ID provided directly - pytest.param(..., id="...") + yield parameterset.id + elif self.ids and idx < len(self.ids) and self.ids[idx] is not None: + # ID provided in the IDs list - parametrize(..., ids=[...]). + yield self._idval_from_value_required(self.ids[idx], idx) + else: + # ID not provided - generate it. + yield "-".join( + self._idval(val, argname, idx) + for val, argname in zip(parameterset.values, self.argnames) + ) + + def _idval(self, val: object, argname: str, idx: int) -> str: + """Make an ID for a parameter in a ParameterSet.""" + idval = self._idval_from_function(val, argname, idx) + if idval is not None: + return idval + idval = self._idval_from_hook(val, argname) + if idval is not None: + return idval + idval = self._idval_from_value(val) + if idval is not None: + return idval + return self._idval_from_argname(argname, idx) + + def _idval_from_function( + self, val: object, argname: str, idx: int + ) -> Optional[str]: + """Try to make an ID for a parameter in a ParameterSet using the + user-provided id callable, if given.""" + if self.idfn is None: + return None + try: + id = self.idfn(val) + except Exception as e: + prefix = f"{self.nodeid}: " if self.nodeid is not None else "" + msg = "error raised while trying to determine id of parameter '{}' at position {}" + msg = prefix + msg.format(argname, idx) + raise ValueError(msg) from e + if id is None: + return None + return self._idval_from_value(id) + + def _idval_from_hook(self, val: object, argname: str) -> Optional[str]: + """Try to make an ID for a parameter in a ParameterSet by calling the + :hook:`pytest_make_parametrize_id` hook.""" + if self.config: + id: Optional[str] = self.config.hook.pytest_make_parametrize_id( + config=self.config, val=val, argname=argname + ) + return id + return None + + def _idval_from_value(self, val: object) -> Optional[str]: + """Try to make an ID for a parameter in a ParameterSet from its value, + if the value type is supported.""" + if isinstance(val, STRING_TYPES): + return _ascii_escaped_by_config(val, self.config) + elif val is None or isinstance(val, (float, int, bool, complex)): + return str(val) + elif isinstance(val, Pattern): + return ascii_escaped(val.pattern) + elif val is NOTSET: + # Fallback to default. Note that NOTSET is an enum.Enum. + pass + elif isinstance(val, enum.Enum): + return str(val) + elif isinstance(getattr(val, "__name__", None), str): + # Name of a class, function, module, etc. + name: str = getattr(val, "__name__") + return name + return None + + def _idval_from_value_required(self, val: object, idx: int) -> str: + """Like _idval_from_value(), but fails if the type is not supported.""" + id = self._idval_from_value(val) + if id is not None: + return id + + # Fail. + if self.func_name is not None: + prefix = f"In {self.func_name}: " + elif self.nodeid is not None: + prefix = f"In {self.nodeid}: " + else: + prefix = "" + msg = ( + f"{prefix}ids contains unsupported value {saferepr(val)} (type: {type(val)!r}) at index {idx}. " + "Supported types are: str, bytes, int, float, complex, bool, enum, regex or anything with a __name__." + ) + fail(msg, pytrace=False) + + @staticmethod + def _idval_from_argname(argname: str, idx: int) -> str: + """Make an ID for a parameter in a ParameterSet from the argument name + and the index of the ParameterSet.""" + return str(argname) + str(idx) + + +@final +@dataclasses.dataclass(frozen=True) +class CallSpec2: + """A planned parameterized invocation of a test function. + + Calculated during collection for a given test function's Metafunc. + Once collection is over, each callspec is turned into a single Item + and stored in item.callspec. + """ + + # arg name -> arg value which will be passed to the parametrized test + # function (direct parameterization). + funcargs: Dict[str, object] = dataclasses.field(default_factory=dict) + # arg name -> arg value which will be passed to a fixture of the same name + # (indirect parametrization). + params: Dict[str, object] = dataclasses.field(default_factory=dict) + # arg name -> arg index. + indices: Dict[str, int] = dataclasses.field(default_factory=dict) + # Used for sorting parametrized resources. + _arg2scope: Dict[str, Scope] = dataclasses.field(default_factory=dict) + # Parts which will be added to the item's name in `[..]` separated by "-". + _idlist: List[str] = dataclasses.field(default_factory=list) + # Marks which will be applied to the item. + marks: List[Mark] = dataclasses.field(default_factory=list) + + def setmulti( + self, + *, + valtypes: Mapping[str, "Literal['params', 'funcargs']"], + argnames: Iterable[str], + valset: Iterable[object], + id: str, + marks: Iterable[Union[Mark, MarkDecorator]], + scope: Scope, + param_index: int, + ) -> "CallSpec2": + funcargs = self.funcargs.copy() + params = self.params.copy() + indices = self.indices.copy() + arg2scope = self._arg2scope.copy() + for arg, val in zip(argnames, valset): + if arg in params or arg in funcargs: + raise ValueError(f"duplicate parametrization of {arg!r}") + valtype_for_arg = valtypes[arg] + if valtype_for_arg == "params": + params[arg] = val + elif valtype_for_arg == "funcargs": + funcargs[arg] = val + else: + assert_never(valtype_for_arg) + indices[arg] = param_index + arg2scope[arg] = scope + return CallSpec2( + funcargs=funcargs, + params=params, + indices=indices, + _arg2scope=arg2scope, + _idlist=[*self._idlist, id], + marks=[*self.marks, *normalize_mark_list(marks)], + ) + + def getparam(self, name: str) -> object: + try: + return self.params[name] + except KeyError as e: + raise ValueError(name) from e + + @property + def id(self) -> str: + return "-".join(self._idlist) + + +@final +class Metafunc: + """Objects passed to the :hook:`pytest_generate_tests` hook. + + They help to inspect a test function and to generate tests according to + test configuration or values specified in the class or module where a + test function is defined. + """ + + def __init__( + self, + definition: "FunctionDefinition", + fixtureinfo: fixtures.FuncFixtureInfo, + config: Config, + cls=None, + module=None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + + #: Access to the underlying :class:`_pytest.python.FunctionDefinition`. + self.definition = definition + + #: Access to the :class:`pytest.Config` object for the test session. + self.config = config + + #: The module object where the test function is defined in. + self.module = module + + #: Underlying Python test function. + self.function = definition.obj + + #: Set of fixture names required by the test function. + self.fixturenames = fixtureinfo.names_closure + + #: Class object where the test function is defined in or ``None``. + self.cls = cls + + self._arg2fixturedefs = fixtureinfo.name2fixturedefs + + # Result of parametrize(). + self._calls: List[CallSpec2] = [] + + def parametrize( + self, + argnames: Union[str, Sequence[str]], + argvalues: Iterable[Union[ParameterSet, Sequence[object], object]], + indirect: Union[bool, Sequence[str]] = False, + ids: Optional[ + Union[Iterable[Optional[object]], Callable[[Any], Optional[object]]] + ] = None, + scope: "Optional[_ScopeName]" = None, + *, + _param_mark: Optional[Mark] = None, + ) -> None: + """Add new invocations to the underlying test function using the list + of argvalues for the given argnames. Parametrization is performed + during the collection phase. If you need to setup expensive resources + see about setting indirect to do it rather than at test setup time. + + Can be called multiple times per test function (but only on different + argument names), in which case each call parametrizes all previous + parametrizations, e.g. + + :: + + unparametrized: t + parametrize ["x", "y"]: t[x], t[y] + parametrize [1, 2]: t[x-1], t[x-2], t[y-1], t[y-2] + + :param argnames: + A comma-separated string denoting one or more argument names, or + a list/tuple of argument strings. + + :param argvalues: + The list of argvalues determines how often a test is invoked with + different argument values. + + If only one argname was specified argvalues is a list of values. + If N argnames were specified, argvalues must be a list of + N-tuples, where each tuple-element specifies a value for its + respective argname. + + :param indirect: + A list of arguments' names (subset of argnames) or a boolean. + If True the list contains all names from the argnames. Each + argvalue corresponding to an argname in this list will + be passed as request.param to its respective argname fixture + function so that it can perform more expensive setups during the + setup phase of a test rather than at collection time. + + :param ids: + Sequence of (or generator for) ids for ``argvalues``, + or a callable to return part of the id for each argvalue. + + With sequences (and generators like ``itertools.count()``) the + returned ids should be of type ``string``, ``int``, ``float``, + ``bool``, or ``None``. + They are mapped to the corresponding index in ``argvalues``. + ``None`` means to use the auto-generated id. + + If it is a callable it will be called for each entry in + ``argvalues``, and the return value is used as part of the + auto-generated id for the whole set (where parts are joined with + dashes ("-")). + This is useful to provide more specific ids for certain items, e.g. + dates. Returning ``None`` will use an auto-generated id. + + If no ids are provided they will be generated automatically from + the argvalues. + + :param scope: + If specified it denotes the scope of the parameters. + The scope is used for grouping tests by parameter instances. + It will also override any fixture-function defined scope, allowing + to set a dynamic scope using test context or configuration. + """ + argnames, parametersets = ParameterSet._for_parametrize( + argnames, + argvalues, + self.function, + self.config, + nodeid=self.definition.nodeid, + ) + del argvalues + + if "request" in argnames: + fail( + "'request' is a reserved name and cannot be used in @pytest.mark.parametrize", + pytrace=False, + ) + + if scope is not None: + scope_ = Scope.from_user( + scope, descr=f"parametrize() call in {self.function.__name__}" + ) + else: + scope_ = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect) + + self._validate_if_using_arg_names(argnames, indirect) + + arg_values_types = self._resolve_arg_value_types(argnames, indirect) + + # Use any already (possibly) generated ids with parametrize Marks. + if _param_mark and _param_mark._param_ids_from: + generated_ids = _param_mark._param_ids_from._param_ids_generated + if generated_ids is not None: + ids = generated_ids + + ids = self._resolve_parameter_set_ids( + argnames, ids, parametersets, nodeid=self.definition.nodeid + ) + + # Store used (possibly generated) ids with parametrize Marks. + if _param_mark and _param_mark._param_ids_from and generated_ids is None: + object.__setattr__(_param_mark._param_ids_from, "_param_ids_generated", ids) + + # Create the new calls: if we are parametrize() multiple times (by applying the decorator + # more than once) then we accumulate those calls generating the cartesian product + # of all calls. + newcalls = [] + for callspec in self._calls or [CallSpec2()]: + for param_index, (param_id, param_set) in enumerate( + zip(ids, parametersets) + ): + newcallspec = callspec.setmulti( + valtypes=arg_values_types, + argnames=argnames, + valset=param_set.values, + id=param_id, + marks=param_set.marks, + scope=scope_, + param_index=param_index, + ) + newcalls.append(newcallspec) + self._calls = newcalls + + def _resolve_parameter_set_ids( + self, + argnames: Sequence[str], + ids: Optional[ + Union[Iterable[Optional[object]], Callable[[Any], Optional[object]]] + ], + parametersets: Sequence[ParameterSet], + nodeid: str, + ) -> List[str]: + """Resolve the actual ids for the given parameter sets. + + :param argnames: + Argument names passed to ``parametrize()``. + :param ids: + The `ids` parameter of the ``parametrize()`` call (see docs). + :param parametersets: + The parameter sets, each containing a set of values corresponding + to ``argnames``. + :param nodeid str: + The nodeid of the definition item that generated this + parametrization. + :returns: + List with ids for each parameter set given. + """ + if ids is None: + idfn = None + ids_ = None + elif callable(ids): + idfn = ids + ids_ = None + else: + idfn = None + ids_ = self._validate_ids(ids, parametersets, self.function.__name__) + id_maker = IdMaker( + argnames, + parametersets, + idfn, + ids_, + self.config, + nodeid=nodeid, + func_name=self.function.__name__, + ) + return id_maker.make_unique_parameterset_ids() + + def _validate_ids( + self, + ids: Iterable[Optional[object]], + parametersets: Sequence[ParameterSet], + func_name: str, + ) -> List[Optional[object]]: + try: + num_ids = len(ids) # type: ignore[arg-type] + except TypeError: + try: + iter(ids) + except TypeError as e: + raise TypeError("ids must be a callable or an iterable") from e + num_ids = len(parametersets) + + # num_ids == 0 is a special case: https://github.com/pytest-dev/pytest/issues/1849 + if num_ids != len(parametersets) and num_ids != 0: + msg = "In {}: {} parameter sets specified, with different number of ids: {}" + fail(msg.format(func_name, len(parametersets), num_ids), pytrace=False) + + return list(itertools.islice(ids, num_ids)) + + def _resolve_arg_value_types( + self, + argnames: Sequence[str], + indirect: Union[bool, Sequence[str]], + ) -> Dict[str, "Literal['params', 'funcargs']"]: + """Resolve if each parametrized argument must be considered a + parameter to a fixture or a "funcarg" to the function, based on the + ``indirect`` parameter of the parametrized() call. + + :param List[str] argnames: List of argument names passed to ``parametrize()``. + :param indirect: Same as the ``indirect`` parameter of ``parametrize()``. + :rtype: Dict[str, str] + A dict mapping each arg name to either: + * "params" if the argname should be the parameter of a fixture of the same name. + * "funcargs" if the argname should be a parameter to the parametrized test function. + """ + if isinstance(indirect, bool): + valtypes: Dict[str, Literal["params", "funcargs"]] = dict.fromkeys( + argnames, "params" if indirect else "funcargs" + ) + elif isinstance(indirect, Sequence): + valtypes = dict.fromkeys(argnames, "funcargs") + for arg in indirect: + if arg not in argnames: + fail( + "In {}: indirect fixture '{}' doesn't exist".format( + self.function.__name__, arg + ), + pytrace=False, + ) + valtypes[arg] = "params" + else: + fail( + "In {func}: expected Sequence or boolean for indirect, got {type}".format( + type=type(indirect).__name__, func=self.function.__name__ + ), + pytrace=False, + ) + return valtypes + + def _validate_if_using_arg_names( + self, + argnames: Sequence[str], + indirect: Union[bool, Sequence[str]], + ) -> None: + """Check if all argnames are being used, by default values, or directly/indirectly. + + :param List[str] argnames: List of argument names passed to ``parametrize()``. + :param indirect: Same as the ``indirect`` parameter of ``parametrize()``. + :raises ValueError: If validation fails. + """ + default_arg_names = set(get_default_arg_names(self.function)) + func_name = self.function.__name__ + for arg in argnames: + if arg not in self.fixturenames: + if arg in default_arg_names: + fail( + "In {}: function already takes an argument '{}' with a default value".format( + func_name, arg + ), + pytrace=False, + ) + else: + if isinstance(indirect, Sequence): + name = "fixture" if arg in indirect else "argument" + else: + name = "fixture" if indirect else "argument" + fail( + f"In {func_name}: function uses no {name} '{arg}'", + pytrace=False, + ) + + +def _find_parametrized_scope( + argnames: Sequence[str], + arg2fixturedefs: Mapping[str, Sequence[fixtures.FixtureDef[object]]], + indirect: Union[bool, Sequence[str]], +) -> Scope: + """Find the most appropriate scope for a parametrized call based on its arguments. + + When there's at least one direct argument, always use "function" scope. + + When a test function is parametrized and all its arguments are indirect + (e.g. fixtures), return the most narrow scope based on the fixtures used. + + Related to issue #1832, based on code posted by @Kingdread. + """ + if isinstance(indirect, Sequence): + all_arguments_are_fixtures = len(indirect) == len(argnames) + else: + all_arguments_are_fixtures = bool(indirect) + + if all_arguments_are_fixtures: + fixturedefs = arg2fixturedefs or {} + used_scopes = [ + fixturedef[0]._scope + for name, fixturedef in fixturedefs.items() + if name in argnames + ] + # Takes the most narrow scope from used fixtures. + return min(used_scopes, default=Scope.Function) + + return Scope.Function + + +def _ascii_escaped_by_config(val: Union[str, bytes], config: Optional[Config]) -> str: + if config is None: + escape_option = False + else: + escape_option = config.getini( + "disable_test_id_escaping_and_forfeit_all_rights_to_community_support" + ) + # TODO: If escaping is turned off and the user passes bytes, + # will return a bytes. For now we ignore this but the + # code *probably* doesn't handle this case. + return val if escape_option else ascii_escaped(val) # type: ignore + + +def _pretty_fixture_path(func) -> str: + cwd = Path.cwd() + loc = Path(getlocation(func, str(cwd))) + prefix = Path("...", "_pytest") + try: + return str(prefix / loc.relative_to(_PYTEST_DIR)) + except ValueError: + return bestrelpath(cwd, loc) + + +def show_fixtures_per_test(config): + from _pytest.main import wrap_session + + return wrap_session(config, _show_fixtures_per_test) + + +def _show_fixtures_per_test(config: Config, session: Session) -> None: + import _pytest.config + + session.perform_collect() + curdir = Path.cwd() + tw = _pytest.config.create_terminal_writer(config) + verbose = config.getvalue("verbose") + + def get_best_relpath(func) -> str: + loc = getlocation(func, str(curdir)) + return bestrelpath(curdir, Path(loc)) + + def write_fixture(fixture_def: fixtures.FixtureDef[object]) -> None: + argname = fixture_def.argname + if verbose <= 0 and argname.startswith("_"): + return + prettypath = _pretty_fixture_path(fixture_def.func) + tw.write(f"{argname}", green=True) + tw.write(f" -- {prettypath}", yellow=True) + tw.write("\n") + fixture_doc = inspect.getdoc(fixture_def.func) + if fixture_doc: + write_docstring( + tw, fixture_doc.split("\n\n")[0] if verbose <= 0 else fixture_doc + ) + else: + tw.line(" no docstring available", red=True) + + def write_item(item: nodes.Item) -> None: + # Not all items have _fixtureinfo attribute. + info: Optional[FuncFixtureInfo] = getattr(item, "_fixtureinfo", None) + if info is None or not info.name2fixturedefs: + # This test item does not use any fixtures. + return + tw.line() + tw.sep("-", f"fixtures used by {item.name}") + # TODO: Fix this type ignore. + tw.sep("-", f"({get_best_relpath(item.function)})") # type: ignore[attr-defined] + # dict key not used in loop but needed for sorting. + for _, fixturedefs in sorted(info.name2fixturedefs.items()): + assert fixturedefs is not None + if not fixturedefs: + continue + # Last item is expected to be the one used by the test item. + write_fixture(fixturedefs[-1]) + + for session_item in session.items: + write_item(session_item) + + +def showfixtures(config: Config) -> Union[int, ExitCode]: + from _pytest.main import wrap_session + + return wrap_session(config, _showfixtures_main) + + +def _showfixtures_main(config: Config, session: Session) -> None: + import _pytest.config + + session.perform_collect() + curdir = Path.cwd() + tw = _pytest.config.create_terminal_writer(config) + verbose = config.getvalue("verbose") + + fm = session._fixturemanager + + available = [] + seen: Set[Tuple[str, str]] = set() + + for argname, fixturedefs in fm._arg2fixturedefs.items(): + assert fixturedefs is not None + if not fixturedefs: + continue + for fixturedef in fixturedefs: + loc = getlocation(fixturedef.func, str(curdir)) + if (fixturedef.argname, loc) in seen: + continue + seen.add((fixturedef.argname, loc)) + available.append( + ( + len(fixturedef.baseid), + fixturedef.func.__module__, + _pretty_fixture_path(fixturedef.func), + fixturedef.argname, + fixturedef, + ) + ) + + available.sort() + currentmodule = None + for baseid, module, prettypath, argname, fixturedef in available: + if currentmodule != module: + if not module.startswith("_pytest."): + tw.line() + tw.sep("-", f"fixtures defined from {module}") + currentmodule = module + if verbose <= 0 and argname.startswith("_"): + continue + tw.write(f"{argname}", green=True) + if fixturedef.scope != "function": + tw.write(" [%s scope]" % fixturedef.scope, cyan=True) + tw.write(f" -- {prettypath}", yellow=True) + tw.write("\n") + doc = inspect.getdoc(fixturedef.func) + if doc: + write_docstring(tw, doc.split("\n\n")[0] if verbose <= 0 else doc) + else: + tw.line(" no docstring available", red=True) + tw.line() + + +def write_docstring(tw: TerminalWriter, doc: str, indent: str = " ") -> None: + for line in doc.split("\n"): + tw.line(indent + line) + + +class Function(PyobjMixin, nodes.Item): + """Item responsible for setting up and executing a Python test function. + + :param name: + The full function name, including any decorations like those + added by parametrization (``my_func[my_param]``). + :param parent: + The parent Node. + :param config: + The pytest Config object. + :param callspec: + If given, this is function has been parametrized and the callspec contains + meta information about the parametrization. + :param callobj: + If given, the object which will be called when the Function is invoked, + otherwise the callobj will be obtained from ``parent`` using ``originalname``. + :param keywords: + Keywords bound to the function object for "-k" matching. + :param session: + The pytest Session object. + :param fixtureinfo: + Fixture information already resolved at this fixture node.. + :param originalname: + The attribute name to use for accessing the underlying function object. + Defaults to ``name``. Set this if name is different from the original name, + for example when it contains decorations like those added by parametrization + (``my_func[my_param]``). + """ + + # Disable since functions handle it themselves. + _ALLOW_MARKERS = False + + def __init__( + self, + name: str, + parent, + config: Optional[Config] = None, + callspec: Optional[CallSpec2] = None, + callobj=NOTSET, + keywords: Optional[Mapping[str, Any]] = None, + session: Optional[Session] = None, + fixtureinfo: Optional[FuncFixtureInfo] = None, + originalname: Optional[str] = None, + ) -> None: + super().__init__(name, parent, config=config, session=session) + + if callobj is not NOTSET: + self.obj = callobj + + #: Original function name, without any decorations (for example + #: parametrization adds a ``"[...]"`` suffix to function names), used to access + #: the underlying function object from ``parent`` (in case ``callobj`` is not given + #: explicitly). + #: + #: .. versionadded:: 3.0 + self.originalname = originalname or name + + # Note: when FunctionDefinition is introduced, we should change ``originalname`` + # to a readonly property that returns FunctionDefinition.name. + + self.own_markers.extend(get_unpacked_marks(self.obj)) + if callspec: + self.callspec = callspec + self.own_markers.extend(callspec.marks) + + # todo: this is a hell of a hack + # https://github.com/pytest-dev/pytest/issues/4569 + # Note: the order of the updates is important here; indicates what + # takes priority (ctor argument over function attributes over markers). + # Take own_markers only; NodeKeywords handles parent traversal on its own. + self.keywords.update((mark.name, mark) for mark in self.own_markers) + self.keywords.update(self.obj.__dict__) + if keywords: + self.keywords.update(keywords) + + if fixtureinfo is None: + fixtureinfo = self.session._fixturemanager.getfixtureinfo( + self, self.obj, self.cls, funcargs=True + ) + self._fixtureinfo: FuncFixtureInfo = fixtureinfo + self.fixturenames = fixtureinfo.names_closure + self._initrequest() + + @classmethod + def from_parent(cls, parent, **kw): # todo: determine sound type limitations + """The public constructor.""" + return super().from_parent(parent=parent, **kw) + + def _initrequest(self) -> None: + self.funcargs: Dict[str, object] = {} + self._request = fixtures.FixtureRequest(self, _ispytest=True) + + @property + def function(self): + """Underlying python 'function' object.""" + return getimfunc(self.obj) + + def _getobj(self): + assert self.parent is not None + if isinstance(self.parent, Class): + # Each Function gets a fresh class instance. + parent_obj = self.parent.newinstance() + else: + parent_obj = self.parent.obj # type: ignore[attr-defined] + return getattr(parent_obj, self.originalname) + + @property + def _pyfuncitem(self): + """(compatonly) for code expecting pytest-2.2 style request objects.""" + return self + + def runtest(self) -> None: + """Execute the underlying test function.""" + self.ihook.pytest_pyfunc_call(pyfuncitem=self) + + def setup(self) -> None: + self._request._fillfixtures() + + def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback: + if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False): + code = _pytest._code.Code.from_function(get_real_func(self.obj)) + path, firstlineno = code.path, code.firstlineno + traceback = excinfo.traceback + ntraceback = traceback.cut(path=path, firstlineno=firstlineno) + if ntraceback == traceback: + ntraceback = ntraceback.cut(path=path) + if ntraceback == traceback: + ntraceback = ntraceback.filter(filter_traceback) + if not ntraceback: + ntraceback = traceback + ntraceback = ntraceback.filter(excinfo) + + # issue364: mark all but first and last frames to + # only show a single-line message for each frame. + if self.config.getoption("tbstyle", "auto") == "auto": + if len(ntraceback) > 2: + ntraceback = Traceback( + entry + if i == 0 or i == len(ntraceback) - 1 + else entry.with_repr_style("short") + for i, entry in enumerate(ntraceback) + ) + + return ntraceback + return excinfo.traceback + + # TODO: Type ignored -- breaks Liskov Substitution. + def repr_failure( # type: ignore[override] + self, + excinfo: ExceptionInfo[BaseException], + ) -> Union[str, TerminalRepr]: + style = self.config.getoption("tbstyle", "auto") + if style == "auto": + style = "long" + return self._repr_failure_py(excinfo, style=style) + + +class FunctionDefinition(Function): + """This class is a stop gap solution until we evolve to have actual function + definition nodes and manage to get rid of ``metafunc``.""" + + def runtest(self) -> None: + raise RuntimeError("function definitions are not supposed to be run as tests") + + setup = runtest diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/python_api.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/python_api.py new file mode 100644 index 00000000..18335610 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/python_api.py @@ -0,0 +1,996 @@ +import math +import pprint +from collections.abc import Collection +from collections.abc import Sized +from decimal import Decimal +from numbers import Complex +from types import TracebackType +from typing import Any +from typing import Callable +from typing import cast +from typing import ContextManager +from typing import List +from typing import Mapping +from typing import Optional +from typing import Pattern +from typing import Sequence +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +if TYPE_CHECKING: + from numpy import ndarray + + +import _pytest._code +from _pytest.compat import final +from _pytest.compat import STRING_TYPES +from _pytest.compat import overload +from _pytest.outcomes import fail + + +def _non_numeric_type_error(value, at: Optional[str]) -> TypeError: + at_str = f" at {at}" if at else "" + return TypeError( + "cannot make approximate comparisons to non-numeric values: {!r} {}".format( + value, at_str + ) + ) + + +def _compare_approx( + full_object: object, + message_data: Sequence[Tuple[str, str, str]], + number_of_elements: int, + different_ids: Sequence[object], + max_abs_diff: float, + max_rel_diff: float, +) -> List[str]: + message_list = list(message_data) + message_list.insert(0, ("Index", "Obtained", "Expected")) + max_sizes = [0, 0, 0] + for index, obtained, expected in message_list: + max_sizes[0] = max(max_sizes[0], len(index)) + max_sizes[1] = max(max_sizes[1], len(obtained)) + max_sizes[2] = max(max_sizes[2], len(expected)) + explanation = [ + f"comparison failed. Mismatched elements: {len(different_ids)} / {number_of_elements}:", + f"Max absolute difference: {max_abs_diff}", + f"Max relative difference: {max_rel_diff}", + ] + [ + f"{indexes:<{max_sizes[0]}} | {obtained:<{max_sizes[1]}} | {expected:<{max_sizes[2]}}" + for indexes, obtained, expected in message_list + ] + return explanation + + +# builtin pytest.approx helper + + +class ApproxBase: + """Provide shared utilities for making approximate comparisons between + numbers or sequences of numbers.""" + + # Tell numpy to use our `__eq__` operator instead of its. + __array_ufunc__ = None + __array_priority__ = 100 + + def __init__(self, expected, rel=None, abs=None, nan_ok: bool = False) -> None: + __tracebackhide__ = True + self.expected = expected + self.abs = abs + self.rel = rel + self.nan_ok = nan_ok + self._check_type() + + def __repr__(self) -> str: + raise NotImplementedError + + def _repr_compare(self, other_side: Any) -> List[str]: + return [ + "comparison failed", + f"Obtained: {other_side}", + f"Expected: {self}", + ] + + def __eq__(self, actual) -> bool: + return all( + a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual) + ) + + def __bool__(self): + __tracebackhide__ = True + raise AssertionError( + "approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`?" + ) + + # Ignore type because of https://github.com/python/mypy/issues/4266. + __hash__ = None # type: ignore + + def __ne__(self, actual) -> bool: + return not (actual == self) + + def _approx_scalar(self, x) -> "ApproxScalar": + if isinstance(x, Decimal): + return ApproxDecimal(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok) + return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok) + + def _yield_comparisons(self, actual): + """Yield all the pairs of numbers to be compared. + + This is used to implement the `__eq__` method. + """ + raise NotImplementedError + + def _check_type(self) -> None: + """Raise a TypeError if the expected value is not a valid type.""" + # This is only a concern if the expected value is a sequence. In every + # other case, the approx() function ensures that the expected value has + # a numeric type. For this reason, the default is to do nothing. The + # classes that deal with sequences should reimplement this method to + # raise if there are any non-numeric elements in the sequence. + + +def _recursive_sequence_map(f, x): + """Recursively map a function over a sequence of arbitrary depth""" + if isinstance(x, (list, tuple)): + seq_type = type(x) + return seq_type(_recursive_sequence_map(f, xi) for xi in x) + else: + return f(x) + + +class ApproxNumpy(ApproxBase): + """Perform approximate comparisons where the expected value is numpy array.""" + + def __repr__(self) -> str: + list_scalars = _recursive_sequence_map( + self._approx_scalar, self.expected.tolist() + ) + return f"approx({list_scalars!r})" + + def _repr_compare(self, other_side: "ndarray") -> List[str]: + import itertools + import math + + def get_value_from_nested_list( + nested_list: List[Any], nd_index: Tuple[Any, ...] + ) -> Any: + """ + Helper function to get the value out of a nested list, given an n-dimensional index. + This mimics numpy's indexing, but for raw nested python lists. + """ + value: Any = nested_list + for i in nd_index: + value = value[i] + return value + + np_array_shape = self.expected.shape + approx_side_as_seq = _recursive_sequence_map( + self._approx_scalar, self.expected.tolist() + ) + + if np_array_shape != other_side.shape: + return [ + "Impossible to compare arrays with different shapes.", + f"Shapes: {np_array_shape} and {other_side.shape}", + ] + + number_of_elements = self.expected.size + max_abs_diff = -math.inf + max_rel_diff = -math.inf + different_ids = [] + for index in itertools.product(*(range(i) for i in np_array_shape)): + approx_value = get_value_from_nested_list(approx_side_as_seq, index) + other_value = get_value_from_nested_list(other_side, index) + if approx_value != other_value: + abs_diff = abs(approx_value.expected - other_value) + max_abs_diff = max(max_abs_diff, abs_diff) + if other_value == 0.0: + max_rel_diff = math.inf + else: + max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value)) + different_ids.append(index) + + message_data = [ + ( + str(index), + str(get_value_from_nested_list(other_side, index)), + str(get_value_from_nested_list(approx_side_as_seq, index)), + ) + for index in different_ids + ] + return _compare_approx( + self.expected, + message_data, + number_of_elements, + different_ids, + max_abs_diff, + max_rel_diff, + ) + + def __eq__(self, actual) -> bool: + import numpy as np + + # self.expected is supposed to always be an array here. + + if not np.isscalar(actual): + try: + actual = np.asarray(actual) + except Exception as e: + raise TypeError(f"cannot compare '{actual}' to numpy.ndarray") from e + + if not np.isscalar(actual) and actual.shape != self.expected.shape: + return False + + return super().__eq__(actual) + + def _yield_comparisons(self, actual): + import numpy as np + + # `actual` can either be a numpy array or a scalar, it is treated in + # `__eq__` before being passed to `ApproxBase.__eq__`, which is the + # only method that calls this one. + + if np.isscalar(actual): + for i in np.ndindex(self.expected.shape): + yield actual, self.expected[i].item() + else: + for i in np.ndindex(self.expected.shape): + yield actual[i].item(), self.expected[i].item() + + +class ApproxMapping(ApproxBase): + """Perform approximate comparisons where the expected value is a mapping + with numeric values (the keys can be anything).""" + + def __repr__(self) -> str: + return "approx({!r})".format( + {k: self._approx_scalar(v) for k, v in self.expected.items()} + ) + + def _repr_compare(self, other_side: Mapping[object, float]) -> List[str]: + import math + + approx_side_as_map = { + k: self._approx_scalar(v) for k, v in self.expected.items() + } + + number_of_elements = len(approx_side_as_map) + max_abs_diff = -math.inf + max_rel_diff = -math.inf + different_ids = [] + for (approx_key, approx_value), other_value in zip( + approx_side_as_map.items(), other_side.values() + ): + if approx_value != other_value: + if approx_value.expected is not None and other_value is not None: + max_abs_diff = max( + max_abs_diff, abs(approx_value.expected - other_value) + ) + if approx_value.expected == 0.0: + max_rel_diff = math.inf + else: + max_rel_diff = max( + max_rel_diff, + abs( + (approx_value.expected - other_value) + / approx_value.expected + ), + ) + different_ids.append(approx_key) + + message_data = [ + (str(key), str(other_side[key]), str(approx_side_as_map[key])) + for key in different_ids + ] + + return _compare_approx( + self.expected, + message_data, + number_of_elements, + different_ids, + max_abs_diff, + max_rel_diff, + ) + + def __eq__(self, actual) -> bool: + try: + if set(actual.keys()) != set(self.expected.keys()): + return False + except AttributeError: + return False + + return super().__eq__(actual) + + def _yield_comparisons(self, actual): + for k in self.expected.keys(): + yield actual[k], self.expected[k] + + def _check_type(self) -> None: + __tracebackhide__ = True + for key, value in self.expected.items(): + if isinstance(value, type(self.expected)): + msg = "pytest.approx() does not support nested dictionaries: key={!r} value={!r}\n full mapping={}" + raise TypeError(msg.format(key, value, pprint.pformat(self.expected))) + + +class ApproxSequenceLike(ApproxBase): + """Perform approximate comparisons where the expected value is a sequence of numbers.""" + + def __repr__(self) -> str: + seq_type = type(self.expected) + if seq_type not in (tuple, list): + seq_type = list + return "approx({!r})".format( + seq_type(self._approx_scalar(x) for x in self.expected) + ) + + def _repr_compare(self, other_side: Sequence[float]) -> List[str]: + import math + + if len(self.expected) != len(other_side): + return [ + "Impossible to compare lists with different sizes.", + f"Lengths: {len(self.expected)} and {len(other_side)}", + ] + + approx_side_as_map = _recursive_sequence_map(self._approx_scalar, self.expected) + + number_of_elements = len(approx_side_as_map) + max_abs_diff = -math.inf + max_rel_diff = -math.inf + different_ids = [] + for i, (approx_value, other_value) in enumerate( + zip(approx_side_as_map, other_side) + ): + if approx_value != other_value: + abs_diff = abs(approx_value.expected - other_value) + max_abs_diff = max(max_abs_diff, abs_diff) + if other_value == 0.0: + max_rel_diff = math.inf + else: + max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value)) + different_ids.append(i) + + message_data = [ + (str(i), str(other_side[i]), str(approx_side_as_map[i])) + for i in different_ids + ] + + return _compare_approx( + self.expected, + message_data, + number_of_elements, + different_ids, + max_abs_diff, + max_rel_diff, + ) + + def __eq__(self, actual) -> bool: + try: + if len(actual) != len(self.expected): + return False + except TypeError: + return False + return super().__eq__(actual) + + def _yield_comparisons(self, actual): + return zip(actual, self.expected) + + def _check_type(self) -> None: + __tracebackhide__ = True + for index, x in enumerate(self.expected): + if isinstance(x, type(self.expected)): + msg = "pytest.approx() does not support nested data structures: {!r} at index {}\n full sequence: {}" + raise TypeError(msg.format(x, index, pprint.pformat(self.expected))) + + +class ApproxScalar(ApproxBase): + """Perform approximate comparisons where the expected value is a single number.""" + + # Using Real should be better than this Union, but not possible yet: + # https://github.com/python/typeshed/pull/3108 + DEFAULT_ABSOLUTE_TOLERANCE: Union[float, Decimal] = 1e-12 + DEFAULT_RELATIVE_TOLERANCE: Union[float, Decimal] = 1e-6 + + def __repr__(self) -> str: + """Return a string communicating both the expected value and the + tolerance for the comparison being made. + + For example, ``1.0 ± 1e-6``, ``(3+4j) ± 5e-6 ∠ ±180°``. + """ + # Don't show a tolerance for values that aren't compared using + # tolerances, i.e. non-numerics and infinities. Need to call abs to + # handle complex numbers, e.g. (inf + 1j). + if (not isinstance(self.expected, (Complex, Decimal))) or math.isinf( + abs(self.expected) # type: ignore[arg-type] + ): + return str(self.expected) + + # If a sensible tolerance can't be calculated, self.tolerance will + # raise a ValueError. In this case, display '???'. + try: + vetted_tolerance = f"{self.tolerance:.1e}" + if ( + isinstance(self.expected, Complex) + and self.expected.imag + and not math.isinf(self.tolerance) + ): + vetted_tolerance += " ∠ ±180°" + except ValueError: + vetted_tolerance = "???" + + return f"{self.expected} ± {vetted_tolerance}" + + def __eq__(self, actual) -> bool: + """Return whether the given value is equal to the expected value + within the pre-specified tolerance.""" + asarray = _as_numpy_array(actual) + if asarray is not None: + # Call ``__eq__()`` manually to prevent infinite-recursion with + # numpy<1.13. See #3748. + return all(self.__eq__(a) for a in asarray.flat) + + # Short-circuit exact equality. + if actual == self.expected: + return True + + # If either type is non-numeric, fall back to strict equality. + # NB: we need Complex, rather than just Number, to ensure that __abs__, + # __sub__, and __float__ are defined. + if not ( + isinstance(self.expected, (Complex, Decimal)) + and isinstance(actual, (Complex, Decimal)) + ): + return False + + # Allow the user to control whether NaNs are considered equal to each + # other or not. The abs() calls are for compatibility with complex + # numbers. + if math.isnan(abs(self.expected)): # type: ignore[arg-type] + return self.nan_ok and math.isnan(abs(actual)) # type: ignore[arg-type] + + # Infinity shouldn't be approximately equal to anything but itself, but + # if there's a relative tolerance, it will be infinite and infinity + # will seem approximately equal to everything. The equal-to-itself + # case would have been short circuited above, so here we can just + # return false if the expected value is infinite. The abs() call is + # for compatibility with complex numbers. + if math.isinf(abs(self.expected)): # type: ignore[arg-type] + return False + + # Return true if the two numbers are within the tolerance. + result: bool = abs(self.expected - actual) <= self.tolerance + return result + + # Ignore type because of https://github.com/python/mypy/issues/4266. + __hash__ = None # type: ignore + + @property + def tolerance(self): + """Return the tolerance for the comparison. + + This could be either an absolute tolerance or a relative tolerance, + depending on what the user specified or which would be larger. + """ + + def set_default(x, default): + return x if x is not None else default + + # Figure out what the absolute tolerance should be. ``self.abs`` is + # either None or a value specified by the user. + absolute_tolerance = set_default(self.abs, self.DEFAULT_ABSOLUTE_TOLERANCE) + + if absolute_tolerance < 0: + raise ValueError( + f"absolute tolerance can't be negative: {absolute_tolerance}" + ) + if math.isnan(absolute_tolerance): + raise ValueError("absolute tolerance can't be NaN.") + + # If the user specified an absolute tolerance but not a relative one, + # just return the absolute tolerance. + if self.rel is None: + if self.abs is not None: + return absolute_tolerance + + # Figure out what the relative tolerance should be. ``self.rel`` is + # either None or a value specified by the user. This is done after + # we've made sure the user didn't ask for an absolute tolerance only, + # because we don't want to raise errors about the relative tolerance if + # we aren't even going to use it. + relative_tolerance = set_default( + self.rel, self.DEFAULT_RELATIVE_TOLERANCE + ) * abs(self.expected) + + if relative_tolerance < 0: + raise ValueError( + f"relative tolerance can't be negative: {relative_tolerance}" + ) + if math.isnan(relative_tolerance): + raise ValueError("relative tolerance can't be NaN.") + + # Return the larger of the relative and absolute tolerances. + return max(relative_tolerance, absolute_tolerance) + + +class ApproxDecimal(ApproxScalar): + """Perform approximate comparisons where the expected value is a Decimal.""" + + DEFAULT_ABSOLUTE_TOLERANCE = Decimal("1e-12") + DEFAULT_RELATIVE_TOLERANCE = Decimal("1e-6") + + +def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: + """Assert that two numbers (or two ordered sequences of numbers) are equal to each other + within some tolerance. + + Due to the :doc:`python:tutorial/floatingpoint`, numbers that we + would intuitively expect to be equal are not always so:: + + >>> 0.1 + 0.2 == 0.3 + False + + This problem is commonly encountered when writing tests, e.g. when making + sure that floating-point values are what you expect them to be. One way to + deal with this problem is to assert that two floating-point numbers are + equal to within some appropriate tolerance:: + + >>> abs((0.1 + 0.2) - 0.3) < 1e-6 + True + + However, comparisons like this are tedious to write and difficult to + understand. Furthermore, absolute comparisons like the one above are + usually discouraged because there's no tolerance that works well for all + situations. ``1e-6`` is good for numbers around ``1``, but too small for + very big numbers and too big for very small ones. It's better to express + the tolerance as a fraction of the expected value, but relative comparisons + like that are even more difficult to write correctly and concisely. + + The ``approx`` class performs floating-point comparisons using a syntax + that's as intuitive as possible:: + + >>> from pytest import approx + >>> 0.1 + 0.2 == approx(0.3) + True + + The same syntax also works for ordered sequences of numbers:: + + >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6)) + True + + ``numpy`` arrays:: + + >>> import numpy as np # doctest: +SKIP + >>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) # doctest: +SKIP + True + + And for a ``numpy`` array against a scalar:: + + >>> import numpy as np # doctest: +SKIP + >>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP + True + + Only ordered sequences are supported, because ``approx`` needs + to infer the relative position of the sequences without ambiguity. This means + ``sets`` and other unordered sequences are not supported. + + Finally, dictionary *values* can also be compared:: + + >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6}) + True + + The comparison will be true if both mappings have the same keys and their + respective values match the expected tolerances. + + **Tolerances** + + By default, ``approx`` considers numbers within a relative tolerance of + ``1e-6`` (i.e. one part in a million) of its expected value to be equal. + This treatment would lead to surprising results if the expected value was + ``0.0``, because nothing but ``0.0`` itself is relatively close to ``0.0``. + To handle this case less surprisingly, ``approx`` also considers numbers + within an absolute tolerance of ``1e-12`` of its expected value to be + equal. Infinity and NaN are special cases. Infinity is only considered + equal to itself, regardless of the relative tolerance. NaN is not + considered equal to anything by default, but you can make it be equal to + itself by setting the ``nan_ok`` argument to True. (This is meant to + facilitate comparing arrays that use NaN to mean "no data".) + + Both the relative and absolute tolerances can be changed by passing + arguments to the ``approx`` constructor:: + + >>> 1.0001 == approx(1) + False + >>> 1.0001 == approx(1, rel=1e-3) + True + >>> 1.0001 == approx(1, abs=1e-3) + True + + If you specify ``abs`` but not ``rel``, the comparison will not consider + the relative tolerance at all. In other words, two numbers that are within + the default relative tolerance of ``1e-6`` will still be considered unequal + if they exceed the specified absolute tolerance. If you specify both + ``abs`` and ``rel``, the numbers will be considered equal if either + tolerance is met:: + + >>> 1 + 1e-8 == approx(1) + True + >>> 1 + 1e-8 == approx(1, abs=1e-12) + False + >>> 1 + 1e-8 == approx(1, rel=1e-6, abs=1e-12) + True + + You can also use ``approx`` to compare nonnumeric types, or dicts and + sequences containing nonnumeric types, in which case it falls back to + strict equality. This can be useful for comparing dicts and sequences that + can contain optional values:: + + >>> {"required": 1.0000005, "optional": None} == approx({"required": 1, "optional": None}) + True + >>> [None, 1.0000005] == approx([None,1]) + True + >>> ["foo", 1.0000005] == approx([None,1]) + False + + If you're thinking about using ``approx``, then you might want to know how + it compares to other good ways of comparing floating-point numbers. All of + these algorithms are based on relative and absolute tolerances and should + agree for the most part, but they do have meaningful differences: + + - ``math.isclose(a, b, rel_tol=1e-9, abs_tol=0.0)``: True if the relative + tolerance is met w.r.t. either ``a`` or ``b`` or if the absolute + tolerance is met. Because the relative tolerance is calculated w.r.t. + both ``a`` and ``b``, this test is symmetric (i.e. neither ``a`` nor + ``b`` is a "reference value"). You have to specify an absolute tolerance + if you want to compare to ``0.0`` because there is no tolerance by + default. More information: :py:func:`math.isclose`. + + - ``numpy.isclose(a, b, rtol=1e-5, atol=1e-8)``: True if the difference + between ``a`` and ``b`` is less that the sum of the relative tolerance + w.r.t. ``b`` and the absolute tolerance. Because the relative tolerance + is only calculated w.r.t. ``b``, this test is asymmetric and you can + think of ``b`` as the reference value. Support for comparing sequences + is provided by :py:func:`numpy.allclose`. More information: + :std:doc:`numpy:reference/generated/numpy.isclose`. + + - ``unittest.TestCase.assertAlmostEqual(a, b)``: True if ``a`` and ``b`` + are within an absolute tolerance of ``1e-7``. No relative tolerance is + considered , so this function is not appropriate for very large or very + small numbers. Also, it's only available in subclasses of ``unittest.TestCase`` + and it's ugly because it doesn't follow PEP8. More information: + :py:meth:`unittest.TestCase.assertAlmostEqual`. + + - ``a == pytest.approx(b, rel=1e-6, abs=1e-12)``: True if the relative + tolerance is met w.r.t. ``b`` or if the absolute tolerance is met. + Because the relative tolerance is only calculated w.r.t. ``b``, this test + is asymmetric and you can think of ``b`` as the reference value. In the + special case that you explicitly specify an absolute tolerance but not a + relative tolerance, only the absolute tolerance is considered. + + .. note:: + + ``approx`` can handle numpy arrays, but we recommend the + specialised test helpers in :std:doc:`numpy:reference/routines.testing` + if you need support for comparisons, NaNs, or ULP-based tolerances. + + To match strings using regex, you can use + `Matches `_ + from the + `re_assert package `_. + + .. warning:: + + .. versionchanged:: 3.2 + + In order to avoid inconsistent behavior, :py:exc:`TypeError` is + raised for ``>``, ``>=``, ``<`` and ``<=`` comparisons. + The example below illustrates the problem:: + + assert approx(0.1) > 0.1 + 1e-10 # calls approx(0.1).__gt__(0.1 + 1e-10) + assert 0.1 + 1e-10 > approx(0.1) # calls approx(0.1).__lt__(0.1 + 1e-10) + + In the second example one expects ``approx(0.1).__le__(0.1 + 1e-10)`` + to be called. But instead, ``approx(0.1).__lt__(0.1 + 1e-10)`` is used to + comparison. This is because the call hierarchy of rich comparisons + follows a fixed behavior. More information: :py:meth:`object.__ge__` + + .. versionchanged:: 3.7.1 + ``approx`` raises ``TypeError`` when it encounters a dict value or + sequence element of nonnumeric type. + + .. versionchanged:: 6.1.0 + ``approx`` falls back to strict equality for nonnumeric types instead + of raising ``TypeError``. + """ + + # Delegate the comparison to a class that knows how to deal with the type + # of the expected value (e.g. int, float, list, dict, numpy.array, etc). + # + # The primary responsibility of these classes is to implement ``__eq__()`` + # and ``__repr__()``. The former is used to actually check if some + # "actual" value is equivalent to the given expected value within the + # allowed tolerance. The latter is used to show the user the expected + # value and tolerance, in the case that a test failed. + # + # The actual logic for making approximate comparisons can be found in + # ApproxScalar, which is used to compare individual numbers. All of the + # other Approx classes eventually delegate to this class. The ApproxBase + # class provides some convenient methods and overloads, but isn't really + # essential. + + __tracebackhide__ = True + + if isinstance(expected, Decimal): + cls: Type[ApproxBase] = ApproxDecimal + elif isinstance(expected, Mapping): + cls = ApproxMapping + elif _is_numpy_array(expected): + expected = _as_numpy_array(expected) + cls = ApproxNumpy + elif ( + hasattr(expected, "__getitem__") + and isinstance(expected, Sized) + # Type ignored because the error is wrong -- not unreachable. + and not isinstance(expected, STRING_TYPES) # type: ignore[unreachable] + ): + cls = ApproxSequenceLike + elif ( + isinstance(expected, Collection) + # Type ignored because the error is wrong -- not unreachable. + and not isinstance(expected, STRING_TYPES) # type: ignore[unreachable] + ): + msg = f"pytest.approx() only supports ordered sequences, but got: {repr(expected)}" + raise TypeError(msg) + else: + cls = ApproxScalar + + return cls(expected, rel, abs, nan_ok) + + +def _is_numpy_array(obj: object) -> bool: + """ + Return true if the given object is implicitly convertible to ndarray, + and numpy is already imported. + """ + return _as_numpy_array(obj) is not None + + +def _as_numpy_array(obj: object) -> Optional["ndarray"]: + """ + Return an ndarray if the given object is implicitly convertible to ndarray, + and numpy is already imported, otherwise None. + """ + import sys + + np: Any = sys.modules.get("numpy") + if np is not None: + # avoid infinite recursion on numpy scalars, which have __array__ + if np.isscalar(obj): + return None + elif isinstance(obj, np.ndarray): + return obj + elif hasattr(obj, "__array__") or hasattr("obj", "__array_interface__"): + return np.asarray(obj) + return None + + +# builtin pytest.raises helper + +E = TypeVar("E", bound=BaseException) + + +@overload +def raises( + expected_exception: Union[Type[E], Tuple[Type[E], ...]], + *, + match: Optional[Union[str, Pattern[str]]] = ..., +) -> "RaisesContext[E]": + ... + + +@overload +def raises( # noqa: F811 + expected_exception: Union[Type[E], Tuple[Type[E], ...]], + func: Callable[..., Any], + *args: Any, + **kwargs: Any, +) -> _pytest._code.ExceptionInfo[E]: + ... + + +def raises( # noqa: F811 + expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any +) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]: + r"""Assert that a code block/function call raises an exception. + + :param typing.Type[E] | typing.Tuple[typing.Type[E], ...] expected_exception: + The expected exception type, or a tuple if one of multiple possible + exception types are expected. + :kwparam str | typing.Pattern[str] | None match: + If specified, a string containing a regular expression, + or a regular expression object, that is tested against the string + representation of the exception using :func:`re.search`. + + To match a literal string that may contain :ref:`special characters + `, the pattern can first be escaped with :func:`re.escape`. + + (This is only used when :py:func:`pytest.raises` is used as a context manager, + and passed through to the function otherwise. + When using :py:func:`pytest.raises` as a function, you can use: + ``pytest.raises(Exc, func, match="passed on").match("my pattern")``.) + + .. currentmodule:: _pytest._code + + Use ``pytest.raises`` as a context manager, which will capture the exception of the given + type:: + + >>> import pytest + >>> with pytest.raises(ZeroDivisionError): + ... 1/0 + + If the code block does not raise the expected exception (``ZeroDivisionError`` in the example + above), or no exception at all, the check will fail instead. + + You can also use the keyword argument ``match`` to assert that the + exception matches a text or regex:: + + >>> with pytest.raises(ValueError, match='must be 0 or None'): + ... raise ValueError("value must be 0 or None") + + >>> with pytest.raises(ValueError, match=r'must be \d+$'): + ... raise ValueError("value must be 42") + + The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the + details of the captured exception:: + + >>> with pytest.raises(ValueError) as exc_info: + ... raise ValueError("value must be 42") + >>> assert exc_info.type is ValueError + >>> assert exc_info.value.args[0] == "value must be 42" + + .. note:: + + When using ``pytest.raises`` as a context manager, it's worthwhile to + note that normal context manager rules apply and that the exception + raised *must* be the final line in the scope of the context manager. + Lines of code after that, within the scope of the context manager will + not be executed. For example:: + + >>> value = 15 + >>> with pytest.raises(ValueError) as exc_info: + ... if value > 10: + ... raise ValueError("value must be <= 10") + ... assert exc_info.type is ValueError # this will not execute + + Instead, the following approach must be taken (note the difference in + scope):: + + >>> with pytest.raises(ValueError) as exc_info: + ... if value > 10: + ... raise ValueError("value must be <= 10") + ... + >>> assert exc_info.type is ValueError + + **Using with** ``pytest.mark.parametrize`` + + When using :ref:`pytest.mark.parametrize ref` + it is possible to parametrize tests such that + some runs raise an exception and others do not. + + See :ref:`parametrizing_conditional_raising` for an example. + + **Legacy form** + + It is possible to specify a callable by passing a to-be-called lambda:: + + >>> raises(ZeroDivisionError, lambda: 1/0) + + + or you can specify an arbitrary callable with arguments:: + + >>> def f(x): return 1/x + ... + >>> raises(ZeroDivisionError, f, 0) + + >>> raises(ZeroDivisionError, f, x=0) + + + The form above is fully supported but discouraged for new code because the + context manager form is regarded as more readable and less error-prone. + + .. note:: + Similar to caught exception objects in Python, explicitly clearing + local references to returned ``ExceptionInfo`` objects can + help the Python interpreter speed up its garbage collection. + + Clearing those references breaks a reference cycle + (``ExceptionInfo`` --> caught exception --> frame stack raising + the exception --> current frame stack --> local variables --> + ``ExceptionInfo``) which makes Python keep all objects referenced + from that cycle (including all local variables in the current + frame) alive until the next cyclic garbage collection run. + More detailed information can be found in the official Python + documentation for :ref:`the try statement `. + """ + __tracebackhide__ = True + + if not expected_exception: + raise ValueError( + f"Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. " + f"Raising exceptions is already understood as failing the test, so you don't need " + f"any special code to say 'this should never raise an exception'." + ) + if isinstance(expected_exception, type): + expected_exceptions: Tuple[Type[E], ...] = (expected_exception,) + else: + expected_exceptions = expected_exception + for exc in expected_exceptions: + if not isinstance(exc, type) or not issubclass(exc, BaseException): + msg = "expected exception must be a BaseException type, not {}" # type: ignore[unreachable] + not_a = exc.__name__ if isinstance(exc, type) else type(exc).__name__ + raise TypeError(msg.format(not_a)) + + message = f"DID NOT RAISE {expected_exception}" + + if not args: + match: Optional[Union[str, Pattern[str]]] = kwargs.pop("match", None) + if kwargs: + msg = "Unexpected keyword arguments passed to pytest.raises: " + msg += ", ".join(sorted(kwargs)) + msg += "\nUse context-manager form instead?" + raise TypeError(msg) + return RaisesContext(expected_exception, message, match) + else: + func = args[0] + if not callable(func): + raise TypeError(f"{func!r} object (type: {type(func)}) must be callable") + try: + func(*args[1:], **kwargs) + except expected_exception as e: + return _pytest._code.ExceptionInfo.from_exception(e) + fail(message) + + +# This doesn't work with mypy for now. Use fail.Exception instead. +raises.Exception = fail.Exception # type: ignore + + +@final +class RaisesContext(ContextManager[_pytest._code.ExceptionInfo[E]]): + def __init__( + self, + expected_exception: Union[Type[E], Tuple[Type[E], ...]], + message: str, + match_expr: Optional[Union[str, Pattern[str]]] = None, + ) -> None: + self.expected_exception = expected_exception + self.message = message + self.match_expr = match_expr + self.excinfo: Optional[_pytest._code.ExceptionInfo[E]] = None + + def __enter__(self) -> _pytest._code.ExceptionInfo[E]: + self.excinfo = _pytest._code.ExceptionInfo.for_later() + return self.excinfo + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> bool: + __tracebackhide__ = True + if exc_type is None: + fail(self.message) + assert self.excinfo is not None + if not issubclass(exc_type, self.expected_exception): + return False + # Cast to narrow the exception type now that it's verified. + exc_info = cast(Tuple[Type[E], E, TracebackType], (exc_type, exc_val, exc_tb)) + self.excinfo.fill_unfilled(exc_info) + if self.match_expr is not None: + self.excinfo.match(self.match_expr) + return True diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/python_path.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/python_path.py new file mode 100644 index 00000000..cceabbca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/python_path.py @@ -0,0 +1,24 @@ +import sys + +import pytest +from pytest import Config +from pytest import Parser + + +def pytest_addoption(parser: Parser) -> None: + parser.addini("pythonpath", type="paths", help="Add paths to sys.path", default=[]) + + +@pytest.hookimpl(tryfirst=True) +def pytest_load_initial_conftests(early_config: Config) -> None: + # `pythonpath = a b` will set `sys.path` to `[a, b, x, y, z, ...]` + for path in reversed(early_config.getini("pythonpath")): + sys.path.insert(0, str(path)) + + +@pytest.hookimpl(trylast=True) +def pytest_unconfigure(config: Config) -> None: + for path in config.getini("pythonpath"): + path_str = str(path) + if path_str in sys.path: + sys.path.remove(path_str) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/recwarn.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/recwarn.py new file mode 100644 index 00000000..d76ea020 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/recwarn.py @@ -0,0 +1,313 @@ +"""Record warnings during test function execution.""" +import re +import warnings +from pprint import pformat +from types import TracebackType +from typing import Any +from typing import Callable +from typing import Generator +from typing import Iterator +from typing import List +from typing import Optional +from typing import Pattern +from typing import Tuple +from typing import Type +from typing import TypeVar +from typing import Union + +from _pytest.compat import final +from _pytest.compat import overload +from _pytest.deprecated import check_ispytest +from _pytest.deprecated import WARNS_NONE_ARG +from _pytest.fixtures import fixture +from _pytest.outcomes import fail + + +T = TypeVar("T") + + +@fixture +def recwarn() -> Generator["WarningsRecorder", None, None]: + """Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions. + + See https://docs.pytest.org/en/latest/how-to/capture-warnings.html for information + on warning categories. + """ + wrec = WarningsRecorder(_ispytest=True) + with wrec: + warnings.simplefilter("default") + yield wrec + + +@overload +def deprecated_call( + *, match: Optional[Union[str, Pattern[str]]] = ... +) -> "WarningsRecorder": + ... + + +@overload +def deprecated_call( # noqa: F811 + func: Callable[..., T], *args: Any, **kwargs: Any +) -> T: + ... + + +def deprecated_call( # noqa: F811 + func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any +) -> Union["WarningsRecorder", Any]: + """Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``. + + This function can be used as a context manager:: + + >>> import warnings + >>> def api_call_v2(): + ... warnings.warn('use v3 of this api', DeprecationWarning) + ... return 200 + + >>> import pytest + >>> with pytest.deprecated_call(): + ... assert api_call_v2() == 200 + + It can also be used by passing a function and ``*args`` and ``**kwargs``, + in which case it will ensure calling ``func(*args, **kwargs)`` produces one of + the warnings types above. The return value is the return value of the function. + + In the context manager form you may use the keyword argument ``match`` to assert + that the warning matches a text or regex. + + The context manager produces a list of :class:`warnings.WarningMessage` objects, + one for each warning raised. + """ + __tracebackhide__ = True + if func is not None: + args = (func,) + args + return warns((DeprecationWarning, PendingDeprecationWarning), *args, **kwargs) + + +@overload +def warns( + expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = ..., + *, + match: Optional[Union[str, Pattern[str]]] = ..., +) -> "WarningsChecker": + ... + + +@overload +def warns( # noqa: F811 + expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]], + func: Callable[..., T], + *args: Any, + **kwargs: Any, +) -> T: + ... + + +def warns( # noqa: F811 + expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning, + *args: Any, + match: Optional[Union[str, Pattern[str]]] = None, + **kwargs: Any, +) -> Union["WarningsChecker", Any]: + r"""Assert that code raises a particular class of warning. + + Specifically, the parameter ``expected_warning`` can be a warning class or sequence + of warning classes, and the code inside the ``with`` block must issue at least one + warning of that class or classes. + + This helper produces a list of :class:`warnings.WarningMessage` objects, one for + each warning raised (regardless of whether it is an ``expected_warning`` or not). + + This function can be used as a context manager, which will capture all the raised + warnings inside it:: + + >>> import pytest + >>> with pytest.warns(RuntimeWarning): + ... warnings.warn("my warning", RuntimeWarning) + + In the context manager form you may use the keyword argument ``match`` to assert + that the warning matches a text or regex:: + + >>> with pytest.warns(UserWarning, match='must be 0 or None'): + ... warnings.warn("value must be 0 or None", UserWarning) + + >>> with pytest.warns(UserWarning, match=r'must be \d+$'): + ... warnings.warn("value must be 42", UserWarning) + + >>> with pytest.warns(UserWarning, match=r'must be \d+$'): + ... warnings.warn("this is not here", UserWarning) + Traceback (most recent call last): + ... + Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted... + + **Using with** ``pytest.mark.parametrize`` + + When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests + such that some runs raise a warning and others do not. + + This could be achieved in the same way as with exceptions, see + :ref:`parametrizing_conditional_raising` for an example. + + """ + __tracebackhide__ = True + if not args: + if kwargs: + argnames = ", ".join(sorted(kwargs)) + raise TypeError( + f"Unexpected keyword arguments passed to pytest.warns: {argnames}" + "\nUse context-manager form instead?" + ) + return WarningsChecker(expected_warning, match_expr=match, _ispytest=True) + else: + func = args[0] + if not callable(func): + raise TypeError(f"{func!r} object (type: {type(func)}) must be callable") + with WarningsChecker(expected_warning, _ispytest=True): + return func(*args[1:], **kwargs) + + +class WarningsRecorder(warnings.catch_warnings): # type:ignore[type-arg] + """A context manager to record raised warnings. + + Each recorded warning is an instance of :class:`warnings.WarningMessage`. + + Adapted from `warnings.catch_warnings`. + + .. note:: + ``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated + differently; see :ref:`ensuring_function_triggers`. + + """ + + def __init__(self, *, _ispytest: bool = False) -> None: + check_ispytest(_ispytest) + # Type ignored due to the way typeshed handles warnings.catch_warnings. + super().__init__(record=True) # type: ignore[call-arg] + self._entered = False + self._list: List[warnings.WarningMessage] = [] + + @property + def list(self) -> List["warnings.WarningMessage"]: + """The list of recorded warnings.""" + return self._list + + def __getitem__(self, i: int) -> "warnings.WarningMessage": + """Get a recorded warning by index.""" + return self._list[i] + + def __iter__(self) -> Iterator["warnings.WarningMessage"]: + """Iterate through the recorded warnings.""" + return iter(self._list) + + def __len__(self) -> int: + """The number of recorded warnings.""" + return len(self._list) + + def pop(self, cls: Type[Warning] = Warning) -> "warnings.WarningMessage": + """Pop the first recorded warning, raise exception if not exists.""" + for i, w in enumerate(self._list): + if issubclass(w.category, cls): + return self._list.pop(i) + __tracebackhide__ = True + raise AssertionError(f"{cls!r} not found in warning list") + + def clear(self) -> None: + """Clear the list of recorded warnings.""" + self._list[:] = [] + + # Type ignored because it doesn't exactly warnings.catch_warnings.__enter__ + # -- it returns a List but we only emulate one. + def __enter__(self) -> "WarningsRecorder": # type: ignore + if self._entered: + __tracebackhide__ = True + raise RuntimeError(f"Cannot enter {self!r} twice") + _list = super().__enter__() + # record=True means it's None. + assert _list is not None + self._list = _list + warnings.simplefilter("always") + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + if not self._entered: + __tracebackhide__ = True + raise RuntimeError(f"Cannot exit {self!r} without entering first") + + super().__exit__(exc_type, exc_val, exc_tb) + + # Built-in catch_warnings does not reset entered state so we do it + # manually here for this context manager to become reusable. + self._entered = False + + +@final +class WarningsChecker(WarningsRecorder): + def __init__( + self, + expected_warning: Optional[ + Union[Type[Warning], Tuple[Type[Warning], ...]] + ] = Warning, + match_expr: Optional[Union[str, Pattern[str]]] = None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + super().__init__(_ispytest=True) + + msg = "exceptions must be derived from Warning, not %s" + if expected_warning is None: + warnings.warn(WARNS_NONE_ARG, stacklevel=4) + expected_warning_tup = None + elif isinstance(expected_warning, tuple): + for exc in expected_warning: + if not issubclass(exc, Warning): + raise TypeError(msg % type(exc)) + expected_warning_tup = expected_warning + elif issubclass(expected_warning, Warning): + expected_warning_tup = (expected_warning,) + else: + raise TypeError(msg % type(expected_warning)) + + self.expected_warning = expected_warning_tup + self.match_expr = match_expr + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + super().__exit__(exc_type, exc_val, exc_tb) + + __tracebackhide__ = True + + def found_str(): + return pformat([record.message for record in self], indent=2) + + # only check if we're not currently handling an exception + if exc_type is None and exc_val is None and exc_tb is None: + if self.expected_warning is not None: + if not any(issubclass(r.category, self.expected_warning) for r in self): + __tracebackhide__ = True + fail( + f"DID NOT WARN. No warnings of type {self.expected_warning} were emitted.\n" + f"The list of emitted warnings is: {found_str()}." + ) + elif self.match_expr is not None: + for r in self: + if issubclass(r.category, self.expected_warning): + if re.compile(self.match_expr).search(str(r.message)): + break + else: + fail( + f"""\ +DID NOT WARN. No warnings of type {self.expected_warning} matching the regex were emitted. + Regex: {self.match_expr} + Emitted warnings: {found_str()}""" + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/reports.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/reports.py new file mode 100644 index 00000000..74e8794b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/reports.py @@ -0,0 +1,622 @@ +import dataclasses +import os +from io import StringIO +from pprint import pprint +from typing import Any +from typing import cast +from typing import Dict +from typing import Iterable +from typing import Iterator +from typing import List +from typing import Mapping +from typing import NoReturn +from typing import Optional +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +from _pytest._code.code import ExceptionChainRepr +from _pytest._code.code import ExceptionInfo +from _pytest._code.code import ExceptionRepr +from _pytest._code.code import ReprEntry +from _pytest._code.code import ReprEntryNative +from _pytest._code.code import ReprExceptionInfo +from _pytest._code.code import ReprFileLocation +from _pytest._code.code import ReprFuncArgs +from _pytest._code.code import ReprLocals +from _pytest._code.code import ReprTraceback +from _pytest._code.code import TerminalRepr +from _pytest._io import TerminalWriter +from _pytest.compat import final +from _pytest.config import Config +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.outcomes import skip + +if TYPE_CHECKING: + from typing_extensions import Literal + + from _pytest.runner import CallInfo + + +def getworkerinfoline(node): + try: + return node._workerinfocache + except AttributeError: + d = node.workerinfo + ver = "%s.%s.%s" % d["version_info"][:3] + node._workerinfocache = s = "[{}] {} -- Python {} {}".format( + d["id"], d["sysplatform"], ver, d["executable"] + ) + return s + + +_R = TypeVar("_R", bound="BaseReport") + + +class BaseReport: + when: Optional[str] + location: Optional[Tuple[str, Optional[int], str]] + longrepr: Union[ + None, ExceptionInfo[BaseException], Tuple[str, int, str], str, TerminalRepr + ] + sections: List[Tuple[str, str]] + nodeid: str + outcome: "Literal['passed', 'failed', 'skipped']" + + def __init__(self, **kw: Any) -> None: + self.__dict__.update(kw) + + if TYPE_CHECKING: + # Can have arbitrary fields given to __init__(). + def __getattr__(self, key: str) -> Any: + ... + + def toterminal(self, out: TerminalWriter) -> None: + if hasattr(self, "node"): + worker_info = getworkerinfoline(self.node) + if worker_info: + out.line(worker_info) + + longrepr = self.longrepr + if longrepr is None: + return + + if hasattr(longrepr, "toterminal"): + longrepr_terminal = cast(TerminalRepr, longrepr) + longrepr_terminal.toterminal(out) + else: + try: + s = str(longrepr) + except UnicodeEncodeError: + s = "" + out.line(s) + + def get_sections(self, prefix: str) -> Iterator[Tuple[str, str]]: + for name, content in self.sections: + if name.startswith(prefix): + yield prefix, content + + @property + def longreprtext(self) -> str: + """Read-only property that returns the full string representation of + ``longrepr``. + + .. versionadded:: 3.0 + """ + file = StringIO() + tw = TerminalWriter(file) + tw.hasmarkup = False + self.toterminal(tw) + exc = file.getvalue() + return exc.strip() + + @property + def caplog(self) -> str: + """Return captured log lines, if log capturing is enabled. + + .. versionadded:: 3.5 + """ + return "\n".join( + content for (prefix, content) in self.get_sections("Captured log") + ) + + @property + def capstdout(self) -> str: + """Return captured text from stdout, if capturing is enabled. + + .. versionadded:: 3.0 + """ + return "".join( + content for (prefix, content) in self.get_sections("Captured stdout") + ) + + @property + def capstderr(self) -> str: + """Return captured text from stderr, if capturing is enabled. + + .. versionadded:: 3.0 + """ + return "".join( + content for (prefix, content) in self.get_sections("Captured stderr") + ) + + @property + def passed(self) -> bool: + """Whether the outcome is passed.""" + return self.outcome == "passed" + + @property + def failed(self) -> bool: + """Whether the outcome is failed.""" + return self.outcome == "failed" + + @property + def skipped(self) -> bool: + """Whether the outcome is skipped.""" + return self.outcome == "skipped" + + @property + def fspath(self) -> str: + """The path portion of the reported node, as a string.""" + return self.nodeid.split("::")[0] + + @property + def count_towards_summary(self) -> bool: + """**Experimental** Whether this report should be counted towards the + totals shown at the end of the test session: "1 passed, 1 failure, etc". + + .. note:: + + This function is considered **experimental**, so beware that it is subject to changes + even in patch releases. + """ + return True + + @property + def head_line(self) -> Optional[str]: + """**Experimental** The head line shown with longrepr output for this + report, more commonly during traceback representation during + failures:: + + ________ Test.foo ________ + + + In the example above, the head_line is "Test.foo". + + .. note:: + + This function is considered **experimental**, so beware that it is subject to changes + even in patch releases. + """ + if self.location is not None: + fspath, lineno, domain = self.location + return domain + return None + + def _get_verbose_word(self, config: Config): + _category, _short, verbose = config.hook.pytest_report_teststatus( + report=self, config=config + ) + return verbose + + def _to_json(self) -> Dict[str, Any]: + """Return the contents of this report as a dict of builtin entries, + suitable for serialization. + + This was originally the serialize_report() function from xdist (ca03269). + + Experimental method. + """ + return _report_to_json(self) + + @classmethod + def _from_json(cls: Type[_R], reportdict: Dict[str, object]) -> _R: + """Create either a TestReport or CollectReport, depending on the calling class. + + It is the callers responsibility to know which class to pass here. + + This was originally the serialize_report() function from xdist (ca03269). + + Experimental method. + """ + kwargs = _report_kwargs_from_json(reportdict) + return cls(**kwargs) + + +def _report_unserialization_failure( + type_name: str, report_class: Type[BaseReport], reportdict +) -> NoReturn: + url = "https://github.com/pytest-dev/pytest/issues" + stream = StringIO() + pprint("-" * 100, stream=stream) + pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream) + pprint("report_name: %s" % report_class, stream=stream) + pprint(reportdict, stream=stream) + pprint("Please report this bug at %s" % url, stream=stream) + pprint("-" * 100, stream=stream) + raise RuntimeError(stream.getvalue()) + + +@final +class TestReport(BaseReport): + """Basic test report object (also used for setup and teardown calls if + they fail). + + Reports can contain arbitrary extra attributes. + """ + + __test__ = False + + def __init__( + self, + nodeid: str, + location: Tuple[str, Optional[int], str], + keywords: Mapping[str, Any], + outcome: "Literal['passed', 'failed', 'skipped']", + longrepr: Union[ + None, ExceptionInfo[BaseException], Tuple[str, int, str], str, TerminalRepr + ], + when: "Literal['setup', 'call', 'teardown']", + sections: Iterable[Tuple[str, str]] = (), + duration: float = 0, + start: float = 0, + stop: float = 0, + user_properties: Optional[Iterable[Tuple[str, object]]] = None, + **extra, + ) -> None: + #: Normalized collection nodeid. + self.nodeid = nodeid + + #: A (filesystempath, lineno, domaininfo) tuple indicating the + #: actual location of a test item - it might be different from the + #: collected one e.g. if a method is inherited from a different module. + #: The filesystempath may be relative to ``config.rootdir``. + #: The line number is 0-based. + self.location: Tuple[str, Optional[int], str] = location + + #: A name -> value dictionary containing all keywords and + #: markers associated with a test invocation. + self.keywords: Mapping[str, Any] = keywords + + #: Test outcome, always one of "passed", "failed", "skipped". + self.outcome = outcome + + #: None or a failure representation. + self.longrepr = longrepr + + #: One of 'setup', 'call', 'teardown' to indicate runtest phase. + self.when = when + + #: User properties is a list of tuples (name, value) that holds user + #: defined properties of the test. + self.user_properties = list(user_properties or []) + + #: Tuples of str ``(heading, content)`` with extra information + #: for the test report. Used by pytest to add text captured + #: from ``stdout``, ``stderr``, and intercepted logging events. May + #: be used by other plugins to add arbitrary information to reports. + self.sections = list(sections) + + #: Time it took to run just the test. + self.duration: float = duration + + #: The system time when the call started, in seconds since the epoch. + self.start: float = start + #: The system time when the call ended, in seconds since the epoch. + self.stop: float = stop + + self.__dict__.update(extra) + + def __repr__(self) -> str: + return "<{} {!r} when={!r} outcome={!r}>".format( + self.__class__.__name__, self.nodeid, self.when, self.outcome + ) + + @classmethod + def from_item_and_call(cls, item: Item, call: "CallInfo[None]") -> "TestReport": + """Create and fill a TestReport with standard item and call info. + + :param item: The item. + :param call: The call info. + """ + when = call.when + # Remove "collect" from the Literal type -- only for collection calls. + assert when != "collect" + duration = call.duration + start = call.start + stop = call.stop + keywords = {x: 1 for x in item.keywords} + excinfo = call.excinfo + sections = [] + if not call.excinfo: + outcome: Literal["passed", "failed", "skipped"] = "passed" + longrepr: Union[ + None, + ExceptionInfo[BaseException], + Tuple[str, int, str], + str, + TerminalRepr, + ] = None + else: + if not isinstance(excinfo, ExceptionInfo): + outcome = "failed" + longrepr = excinfo + elif isinstance(excinfo.value, skip.Exception): + outcome = "skipped" + r = excinfo._getreprcrash() + assert ( + r is not None + ), "There should always be a traceback entry for skipping a test." + if excinfo.value._use_item_location: + path, line = item.reportinfo()[:2] + assert line is not None + longrepr = os.fspath(path), line + 1, r.message + else: + longrepr = (str(r.path), r.lineno, r.message) + else: + outcome = "failed" + if call.when == "call": + longrepr = item.repr_failure(excinfo) + else: # exception in setup or teardown + longrepr = item._repr_failure_py( + excinfo, style=item.config.getoption("tbstyle", "auto") + ) + for rwhen, key, content in item._report_sections: + sections.append((f"Captured {key} {rwhen}", content)) + return cls( + item.nodeid, + item.location, + keywords, + outcome, + longrepr, + when, + sections, + duration, + start, + stop, + user_properties=item.user_properties, + ) + + +@final +class CollectReport(BaseReport): + """Collection report object. + + Reports can contain arbitrary extra attributes. + """ + + when = "collect" + + def __init__( + self, + nodeid: str, + outcome: "Literal['passed', 'failed', 'skipped']", + longrepr: Union[ + None, ExceptionInfo[BaseException], Tuple[str, int, str], str, TerminalRepr + ], + result: Optional[List[Union[Item, Collector]]], + sections: Iterable[Tuple[str, str]] = (), + **extra, + ) -> None: + #: Normalized collection nodeid. + self.nodeid = nodeid + + #: Test outcome, always one of "passed", "failed", "skipped". + self.outcome = outcome + + #: None or a failure representation. + self.longrepr = longrepr + + #: The collected items and collection nodes. + self.result = result or [] + + #: Tuples of str ``(heading, content)`` with extra information + #: for the test report. Used by pytest to add text captured + #: from ``stdout``, ``stderr``, and intercepted logging events. May + #: be used by other plugins to add arbitrary information to reports. + self.sections = list(sections) + + self.__dict__.update(extra) + + @property + def location( # type:ignore[override] + self, + ) -> Optional[Tuple[str, Optional[int], str]]: + return (self.fspath, None, self.fspath) + + def __repr__(self) -> str: + return "".format( + self.nodeid, len(self.result), self.outcome + ) + + +class CollectErrorRepr(TerminalRepr): + def __init__(self, msg: str) -> None: + self.longrepr = msg + + def toterminal(self, out: TerminalWriter) -> None: + out.line(self.longrepr, red=True) + + +def pytest_report_to_serializable( + report: Union[CollectReport, TestReport] +) -> Optional[Dict[str, Any]]: + if isinstance(report, (TestReport, CollectReport)): + data = report._to_json() + data["$report_type"] = report.__class__.__name__ + return data + # TODO: Check if this is actually reachable. + return None # type: ignore[unreachable] + + +def pytest_report_from_serializable( + data: Dict[str, Any], +) -> Optional[Union[CollectReport, TestReport]]: + if "$report_type" in data: + if data["$report_type"] == "TestReport": + return TestReport._from_json(data) + elif data["$report_type"] == "CollectReport": + return CollectReport._from_json(data) + assert False, "Unknown report_type unserialize data: {}".format( + data["$report_type"] + ) + return None + + +def _report_to_json(report: BaseReport) -> Dict[str, Any]: + """Return the contents of this report as a dict of builtin entries, + suitable for serialization. + + This was originally the serialize_report() function from xdist (ca03269). + """ + + def serialize_repr_entry( + entry: Union[ReprEntry, ReprEntryNative] + ) -> Dict[str, Any]: + data = dataclasses.asdict(entry) + for key, value in data.items(): + if hasattr(value, "__dict__"): + data[key] = dataclasses.asdict(value) + entry_data = {"type": type(entry).__name__, "data": data} + return entry_data + + def serialize_repr_traceback(reprtraceback: ReprTraceback) -> Dict[str, Any]: + result = dataclasses.asdict(reprtraceback) + result["reprentries"] = [ + serialize_repr_entry(x) for x in reprtraceback.reprentries + ] + return result + + def serialize_repr_crash( + reprcrash: Optional[ReprFileLocation], + ) -> Optional[Dict[str, Any]]: + if reprcrash is not None: + return dataclasses.asdict(reprcrash) + else: + return None + + def serialize_exception_longrepr(rep: BaseReport) -> Dict[str, Any]: + assert rep.longrepr is not None + # TODO: Investigate whether the duck typing is really necessary here. + longrepr = cast(ExceptionRepr, rep.longrepr) + result: Dict[str, Any] = { + "reprcrash": serialize_repr_crash(longrepr.reprcrash), + "reprtraceback": serialize_repr_traceback(longrepr.reprtraceback), + "sections": longrepr.sections, + } + if isinstance(longrepr, ExceptionChainRepr): + result["chain"] = [] + for repr_traceback, repr_crash, description in longrepr.chain: + result["chain"].append( + ( + serialize_repr_traceback(repr_traceback), + serialize_repr_crash(repr_crash), + description, + ) + ) + else: + result["chain"] = None + return result + + d = report.__dict__.copy() + if hasattr(report.longrepr, "toterminal"): + if hasattr(report.longrepr, "reprtraceback") and hasattr( + report.longrepr, "reprcrash" + ): + d["longrepr"] = serialize_exception_longrepr(report) + else: + d["longrepr"] = str(report.longrepr) + else: + d["longrepr"] = report.longrepr + for name in d: + if isinstance(d[name], os.PathLike): + d[name] = os.fspath(d[name]) + elif name == "result": + d[name] = None # for now + return d + + +def _report_kwargs_from_json(reportdict: Dict[str, Any]) -> Dict[str, Any]: + """Return **kwargs that can be used to construct a TestReport or + CollectReport instance. + + This was originally the serialize_report() function from xdist (ca03269). + """ + + def deserialize_repr_entry(entry_data): + data = entry_data["data"] + entry_type = entry_data["type"] + if entry_type == "ReprEntry": + reprfuncargs = None + reprfileloc = None + reprlocals = None + if data["reprfuncargs"]: + reprfuncargs = ReprFuncArgs(**data["reprfuncargs"]) + if data["reprfileloc"]: + reprfileloc = ReprFileLocation(**data["reprfileloc"]) + if data["reprlocals"]: + reprlocals = ReprLocals(data["reprlocals"]["lines"]) + + reprentry: Union[ReprEntry, ReprEntryNative] = ReprEntry( + lines=data["lines"], + reprfuncargs=reprfuncargs, + reprlocals=reprlocals, + reprfileloc=reprfileloc, + style=data["style"], + ) + elif entry_type == "ReprEntryNative": + reprentry = ReprEntryNative(data["lines"]) + else: + _report_unserialization_failure(entry_type, TestReport, reportdict) + return reprentry + + def deserialize_repr_traceback(repr_traceback_dict): + repr_traceback_dict["reprentries"] = [ + deserialize_repr_entry(x) for x in repr_traceback_dict["reprentries"] + ] + return ReprTraceback(**repr_traceback_dict) + + def deserialize_repr_crash(repr_crash_dict: Optional[Dict[str, Any]]): + if repr_crash_dict is not None: + return ReprFileLocation(**repr_crash_dict) + else: + return None + + if ( + reportdict["longrepr"] + and "reprcrash" in reportdict["longrepr"] + and "reprtraceback" in reportdict["longrepr"] + ): + reprtraceback = deserialize_repr_traceback( + reportdict["longrepr"]["reprtraceback"] + ) + reprcrash = deserialize_repr_crash(reportdict["longrepr"]["reprcrash"]) + if reportdict["longrepr"]["chain"]: + chain = [] + for repr_traceback_data, repr_crash_data, description in reportdict[ + "longrepr" + ]["chain"]: + chain.append( + ( + deserialize_repr_traceback(repr_traceback_data), + deserialize_repr_crash(repr_crash_data), + description, + ) + ) + exception_info: Union[ + ExceptionChainRepr, ReprExceptionInfo + ] = ExceptionChainRepr(chain) + else: + exception_info = ReprExceptionInfo( + reprtraceback=reprtraceback, + reprcrash=reprcrash, + ) + + for section in reportdict["longrepr"]["sections"]: + exception_info.addsection(*section) + reportdict["longrepr"] = exception_info + + return reportdict diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/runner.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/runner.py new file mode 100644 index 00000000..f861c05a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/runner.py @@ -0,0 +1,551 @@ +"""Basic collect and runtest protocol implementations.""" +import bdb +import dataclasses +import os +import sys +from typing import Callable +from typing import cast +from typing import Dict +from typing import Generic +from typing import List +from typing import Optional +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +from .reports import BaseReport +from .reports import CollectErrorRepr +from .reports import CollectReport +from .reports import TestReport +from _pytest import timing +from _pytest._code.code import ExceptionChainRepr +from _pytest._code.code import ExceptionInfo +from _pytest._code.code import TerminalRepr +from _pytest.compat import final +from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.nodes import Node +from _pytest.outcomes import Exit +from _pytest.outcomes import OutcomeException +from _pytest.outcomes import Skipped +from _pytest.outcomes import TEST_OUTCOME + +if sys.version_info[:2] < (3, 11): + from exceptiongroup import BaseExceptionGroup + +if TYPE_CHECKING: + from typing_extensions import Literal + + from _pytest.main import Session + from _pytest.terminal import TerminalReporter + +# +# pytest plugin hooks. + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("terminal reporting", "Reporting", after="general") + group.addoption( + "--durations", + action="store", + type=int, + default=None, + metavar="N", + help="Show N slowest setup/test durations (N=0 for all)", + ) + group.addoption( + "--durations-min", + action="store", + type=float, + default=0.005, + metavar="N", + help="Minimal duration in seconds for inclusion in slowest list. " + "Default: 0.005.", + ) + + +def pytest_terminal_summary(terminalreporter: "TerminalReporter") -> None: + durations = terminalreporter.config.option.durations + durations_min = terminalreporter.config.option.durations_min + verbose = terminalreporter.config.getvalue("verbose") + if durations is None: + return + tr = terminalreporter + dlist = [] + for replist in tr.stats.values(): + for rep in replist: + if hasattr(rep, "duration"): + dlist.append(rep) + if not dlist: + return + dlist.sort(key=lambda x: x.duration, reverse=True) # type: ignore[no-any-return] + if not durations: + tr.write_sep("=", "slowest durations") + else: + tr.write_sep("=", "slowest %s durations" % durations) + dlist = dlist[:durations] + + for i, rep in enumerate(dlist): + if verbose < 2 and rep.duration < durations_min: + tr.write_line("") + tr.write_line( + "(%s durations < %gs hidden. Use -vv to show these durations.)" + % (len(dlist) - i, durations_min) + ) + break + tr.write_line(f"{rep.duration:02.2f}s {rep.when:<8} {rep.nodeid}") + + +def pytest_sessionstart(session: "Session") -> None: + session._setupstate = SetupState() + + +def pytest_sessionfinish(session: "Session") -> None: + session._setupstate.teardown_exact(None) + + +def pytest_runtest_protocol(item: Item, nextitem: Optional[Item]) -> bool: + ihook = item.ihook + ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location) + runtestprotocol(item, nextitem=nextitem) + ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location) + return True + + +def runtestprotocol( + item: Item, log: bool = True, nextitem: Optional[Item] = None +) -> List[TestReport]: + hasrequest = hasattr(item, "_request") + if hasrequest and not item._request: # type: ignore[attr-defined] + # This only happens if the item is re-run, as is done by + # pytest-rerunfailures. + item._initrequest() # type: ignore[attr-defined] + rep = call_and_report(item, "setup", log) + reports = [rep] + if rep.passed: + if item.config.getoption("setupshow", False): + show_test_item(item) + if not item.config.getoption("setuponly", False): + reports.append(call_and_report(item, "call", log)) + reports.append(call_and_report(item, "teardown", log, nextitem=nextitem)) + # After all teardown hooks have been called + # want funcargs and request info to go away. + if hasrequest: + item._request = False # type: ignore[attr-defined] + item.funcargs = None # type: ignore[attr-defined] + return reports + + +def show_test_item(item: Item) -> None: + """Show test function, parameters and the fixtures of the test item.""" + tw = item.config.get_terminal_writer() + tw.line() + tw.write(" " * 8) + tw.write(item.nodeid) + used_fixtures = sorted(getattr(item, "fixturenames", [])) + if used_fixtures: + tw.write(" (fixtures used: {})".format(", ".join(used_fixtures))) + tw.flush() + + +def pytest_runtest_setup(item: Item) -> None: + _update_current_test_var(item, "setup") + item.session._setupstate.setup(item) + + +def pytest_runtest_call(item: Item) -> None: + _update_current_test_var(item, "call") + try: + del sys.last_type + del sys.last_value + del sys.last_traceback + except AttributeError: + pass + try: + item.runtest() + except Exception as e: + # Store trace info to allow postmortem debugging + sys.last_type = type(e) + sys.last_value = e + assert e.__traceback__ is not None + # Skip *this* frame + sys.last_traceback = e.__traceback__.tb_next + raise e + + +def pytest_runtest_teardown(item: Item, nextitem: Optional[Item]) -> None: + _update_current_test_var(item, "teardown") + item.session._setupstate.teardown_exact(nextitem) + _update_current_test_var(item, None) + + +def _update_current_test_var( + item: Item, when: Optional["Literal['setup', 'call', 'teardown']"] +) -> None: + """Update :envvar:`PYTEST_CURRENT_TEST` to reflect the current item and stage. + + If ``when`` is None, delete ``PYTEST_CURRENT_TEST`` from the environment. + """ + var_name = "PYTEST_CURRENT_TEST" + if when: + value = f"{item.nodeid} ({when})" + # don't allow null bytes on environment variables (see #2644, #2957) + value = value.replace("\x00", "(null)") + os.environ[var_name] = value + else: + os.environ.pop(var_name) + + +def pytest_report_teststatus(report: BaseReport) -> Optional[Tuple[str, str, str]]: + if report.when in ("setup", "teardown"): + if report.failed: + # category, shortletter, verbose-word + return "error", "E", "ERROR" + elif report.skipped: + return "skipped", "s", "SKIPPED" + else: + return "", "", "" + return None + + +# +# Implementation + + +def call_and_report( + item: Item, when: "Literal['setup', 'call', 'teardown']", log: bool = True, **kwds +) -> TestReport: + call = call_runtest_hook(item, when, **kwds) + hook = item.ihook + report: TestReport = hook.pytest_runtest_makereport(item=item, call=call) + if log: + hook.pytest_runtest_logreport(report=report) + if check_interactive_exception(call, report): + hook.pytest_exception_interact(node=item, call=call, report=report) + return report + + +def check_interactive_exception(call: "CallInfo[object]", report: BaseReport) -> bool: + """Check whether the call raised an exception that should be reported as + interactive.""" + if call.excinfo is None: + # Didn't raise. + return False + if hasattr(report, "wasxfail"): + # Exception was expected. + return False + if isinstance(call.excinfo.value, (Skipped, bdb.BdbQuit)): + # Special control flow exception. + return False + return True + + +def call_runtest_hook( + item: Item, when: "Literal['setup', 'call', 'teardown']", **kwds +) -> "CallInfo[None]": + if when == "setup": + ihook: Callable[..., None] = item.ihook.pytest_runtest_setup + elif when == "call": + ihook = item.ihook.pytest_runtest_call + elif when == "teardown": + ihook = item.ihook.pytest_runtest_teardown + else: + assert False, f"Unhandled runtest hook case: {when}" + reraise: Tuple[Type[BaseException], ...] = (Exit,) + if not item.config.getoption("usepdb", False): + reraise += (KeyboardInterrupt,) + return CallInfo.from_call( + lambda: ihook(item=item, **kwds), when=when, reraise=reraise + ) + + +TResult = TypeVar("TResult", covariant=True) + + +@final +@dataclasses.dataclass +class CallInfo(Generic[TResult]): + """Result/Exception info of a function invocation.""" + + _result: Optional[TResult] + #: The captured exception of the call, if it raised. + excinfo: Optional[ExceptionInfo[BaseException]] + #: The system time when the call started, in seconds since the epoch. + start: float + #: The system time when the call ended, in seconds since the epoch. + stop: float + #: The call duration, in seconds. + duration: float + #: The context of invocation: "collect", "setup", "call" or "teardown". + when: "Literal['collect', 'setup', 'call', 'teardown']" + + def __init__( + self, + result: Optional[TResult], + excinfo: Optional[ExceptionInfo[BaseException]], + start: float, + stop: float, + duration: float, + when: "Literal['collect', 'setup', 'call', 'teardown']", + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._result = result + self.excinfo = excinfo + self.start = start + self.stop = stop + self.duration = duration + self.when = when + + @property + def result(self) -> TResult: + """The return value of the call, if it didn't raise. + + Can only be accessed if excinfo is None. + """ + if self.excinfo is not None: + raise AttributeError(f"{self!r} has no valid result") + # The cast is safe because an exception wasn't raised, hence + # _result has the expected function return type (which may be + # None, that's why a cast and not an assert). + return cast(TResult, self._result) + + @classmethod + def from_call( + cls, + func: "Callable[[], TResult]", + when: "Literal['collect', 'setup', 'call', 'teardown']", + reraise: Optional[ + Union[Type[BaseException], Tuple[Type[BaseException], ...]] + ] = None, + ) -> "CallInfo[TResult]": + """Call func, wrapping the result in a CallInfo. + + :param func: + The function to call. Called without arguments. + :param when: + The phase in which the function is called. + :param reraise: + Exception or exceptions that shall propagate if raised by the + function, instead of being wrapped in the CallInfo. + """ + excinfo = None + start = timing.time() + precise_start = timing.perf_counter() + try: + result: Optional[TResult] = func() + except BaseException: + excinfo = ExceptionInfo.from_current() + if reraise is not None and isinstance(excinfo.value, reraise): + raise + result = None + # use the perf counter + precise_stop = timing.perf_counter() + duration = precise_stop - precise_start + stop = timing.time() + return cls( + start=start, + stop=stop, + duration=duration, + when=when, + result=result, + excinfo=excinfo, + _ispytest=True, + ) + + def __repr__(self) -> str: + if self.excinfo is None: + return f"" + return f"" + + +def pytest_runtest_makereport(item: Item, call: CallInfo[None]) -> TestReport: + return TestReport.from_item_and_call(item, call) + + +def pytest_make_collect_report(collector: Collector) -> CollectReport: + call = CallInfo.from_call(lambda: list(collector.collect()), "collect") + longrepr: Union[None, Tuple[str, int, str], str, TerminalRepr] = None + if not call.excinfo: + outcome: Literal["passed", "skipped", "failed"] = "passed" + else: + skip_exceptions = [Skipped] + unittest = sys.modules.get("unittest") + if unittest is not None: + # Type ignored because unittest is loaded dynamically. + skip_exceptions.append(unittest.SkipTest) # type: ignore + if isinstance(call.excinfo.value, tuple(skip_exceptions)): + outcome = "skipped" + r_ = collector._repr_failure_py(call.excinfo, "line") + assert isinstance(r_, ExceptionChainRepr), repr(r_) + r = r_.reprcrash + assert r + longrepr = (str(r.path), r.lineno, r.message) + else: + outcome = "failed" + errorinfo = collector.repr_failure(call.excinfo) + if not hasattr(errorinfo, "toterminal"): + assert isinstance(errorinfo, str) + errorinfo = CollectErrorRepr(errorinfo) + longrepr = errorinfo + result = call.result if not call.excinfo else None + rep = CollectReport(collector.nodeid, outcome, longrepr, result) + rep.call = call # type: ignore # see collect_one_node + return rep + + +class SetupState: + """Shared state for setting up/tearing down test items or collectors + in a session. + + Suppose we have a collection tree as follows: + + + + + + + + The SetupState maintains a stack. The stack starts out empty: + + [] + + During the setup phase of item1, setup(item1) is called. What it does + is: + + push session to stack, run session.setup() + push mod1 to stack, run mod1.setup() + push item1 to stack, run item1.setup() + + The stack is: + + [session, mod1, item1] + + While the stack is in this shape, it is allowed to add finalizers to + each of session, mod1, item1 using addfinalizer(). + + During the teardown phase of item1, teardown_exact(item2) is called, + where item2 is the next item to item1. What it does is: + + pop item1 from stack, run its teardowns + pop mod1 from stack, run its teardowns + + mod1 was popped because it ended its purpose with item1. The stack is: + + [session] + + During the setup phase of item2, setup(item2) is called. What it does + is: + + push mod2 to stack, run mod2.setup() + push item2 to stack, run item2.setup() + + Stack: + + [session, mod2, item2] + + During the teardown phase of item2, teardown_exact(None) is called, + because item2 is the last item. What it does is: + + pop item2 from stack, run its teardowns + pop mod2 from stack, run its teardowns + pop session from stack, run its teardowns + + Stack: + + [] + + The end! + """ + + def __init__(self) -> None: + # The stack is in the dict insertion order. + self.stack: Dict[ + Node, + Tuple[ + # Node's finalizers. + List[Callable[[], object]], + # Node's exception, if its setup raised. + Optional[Union[OutcomeException, Exception]], + ], + ] = {} + + def setup(self, item: Item) -> None: + """Setup objects along the collector chain to the item.""" + needed_collectors = item.listchain() + + # If a collector fails its setup, fail its entire subtree of items. + # The setup is not retried for each item - the same exception is used. + for col, (finalizers, exc) in self.stack.items(): + assert col in needed_collectors, "previous item was not torn down properly" + if exc: + raise exc + + for col in needed_collectors[len(self.stack) :]: + assert col not in self.stack + # Push onto the stack. + self.stack[col] = ([col.teardown], None) + try: + col.setup() + except TEST_OUTCOME as exc: + self.stack[col] = (self.stack[col][0], exc) + raise exc + + def addfinalizer(self, finalizer: Callable[[], object], node: Node) -> None: + """Attach a finalizer to the given node. + + The node must be currently active in the stack. + """ + assert node and not isinstance(node, tuple) + assert callable(finalizer) + assert node in self.stack, (node, self.stack) + self.stack[node][0].append(finalizer) + + def teardown_exact(self, nextitem: Optional[Item]) -> None: + """Teardown the current stack up until reaching nodes that nextitem + also descends from. + + When nextitem is None (meaning we're at the last item), the entire + stack is torn down. + """ + needed_collectors = nextitem and nextitem.listchain() or [] + exceptions: List[BaseException] = [] + while self.stack: + if list(self.stack.keys()) == needed_collectors[: len(self.stack)]: + break + node, (finalizers, _) = self.stack.popitem() + these_exceptions = [] + while finalizers: + fin = finalizers.pop() + try: + fin() + except TEST_OUTCOME as e: + these_exceptions.append(e) + + if len(these_exceptions) == 1: + exceptions.extend(these_exceptions) + elif these_exceptions: + msg = f"errors while tearing down {node!r}" + exceptions.append(BaseExceptionGroup(msg, these_exceptions[::-1])) + + if len(exceptions) == 1: + raise exceptions[0] + elif exceptions: + raise BaseExceptionGroup("errors during test teardown", exceptions[::-1]) + if nextitem is None: + assert not self.stack + + +def collect_one_node(collector: Collector) -> CollectReport: + ihook = collector.ihook + ihook.pytest_collectstart(collector=collector) + rep: CollectReport = ihook.pytest_make_collect_report(collector=collector) + call = rep.__dict__.pop("call", None) + if call and check_interactive_exception(call, rep): + ihook.pytest_exception_interact(node=collector, call=call, report=rep) + return rep diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/scope.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/scope.py new file mode 100644 index 00000000..7a746fb9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/scope.py @@ -0,0 +1,91 @@ +""" +Scope definition and related utilities. + +Those are defined here, instead of in the 'fixtures' module because +their use is spread across many other pytest modules, and centralizing it in 'fixtures' +would cause circular references. + +Also this makes the module light to import, as it should. +""" +from enum import Enum +from functools import total_ordering +from typing import Optional +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing_extensions import Literal + + _ScopeName = Literal["session", "package", "module", "class", "function"] + + +@total_ordering +class Scope(Enum): + """ + Represents one of the possible fixture scopes in pytest. + + Scopes are ordered from lower to higher, that is: + + ->>> higher ->>> + + Function < Class < Module < Package < Session + + <<<- lower <<<- + """ + + # Scopes need to be listed from lower to higher. + Function: "_ScopeName" = "function" + Class: "_ScopeName" = "class" + Module: "_ScopeName" = "module" + Package: "_ScopeName" = "package" + Session: "_ScopeName" = "session" + + def next_lower(self) -> "Scope": + """Return the next lower scope.""" + index = _SCOPE_INDICES[self] + if index == 0: + raise ValueError(f"{self} is the lower-most scope") + return _ALL_SCOPES[index - 1] + + def next_higher(self) -> "Scope": + """Return the next higher scope.""" + index = _SCOPE_INDICES[self] + if index == len(_SCOPE_INDICES) - 1: + raise ValueError(f"{self} is the upper-most scope") + return _ALL_SCOPES[index + 1] + + def __lt__(self, other: "Scope") -> bool: + self_index = _SCOPE_INDICES[self] + other_index = _SCOPE_INDICES[other] + return self_index < other_index + + @classmethod + def from_user( + cls, scope_name: "_ScopeName", descr: str, where: Optional[str] = None + ) -> "Scope": + """ + Given a scope name from the user, return the equivalent Scope enum. Should be used + whenever we want to convert a user provided scope name to its enum object. + + If the scope name is invalid, construct a user friendly message and call pytest.fail. + """ + from _pytest.outcomes import fail + + try: + # Holding this reference is necessary for mypy at the moment. + scope = Scope(scope_name) + except ValueError: + fail( + "{} {}got an unexpected scope value '{}'".format( + descr, f"from {where} " if where else "", scope_name + ), + pytrace=False, + ) + return scope + + +_ALL_SCOPES = list(Scope) +_SCOPE_INDICES = {scope: index for index, scope in enumerate(_ALL_SCOPES)} + + +# Ordered list of scopes which can contain many tests (in practice all except Function). +HIGH_SCOPES = [x for x in Scope if x is not Scope.Function] diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/setuponly.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/setuponly.py new file mode 100644 index 00000000..583590d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/setuponly.py @@ -0,0 +1,97 @@ +from typing import Generator +from typing import Optional +from typing import Union + +import pytest +from _pytest._io.saferepr import saferepr +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config.argparsing import Parser +from _pytest.fixtures import FixtureDef +from _pytest.fixtures import SubRequest +from _pytest.scope import Scope + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("debugconfig") + group.addoption( + "--setuponly", + "--setup-only", + action="store_true", + help="Only setup fixtures, do not execute tests", + ) + group.addoption( + "--setupshow", + "--setup-show", + action="store_true", + help="Show setup of fixtures while executing tests", + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_fixture_setup( + fixturedef: FixtureDef[object], request: SubRequest +) -> Generator[None, None, None]: + yield + if request.config.option.setupshow: + if hasattr(request, "param"): + # Save the fixture parameter so ._show_fixture_action() can + # display it now and during the teardown (in .finish()). + if fixturedef.ids: + if callable(fixturedef.ids): + param = fixturedef.ids(request.param) + else: + param = fixturedef.ids[request.param_index] + else: + param = request.param + fixturedef.cached_param = param # type: ignore[attr-defined] + _show_fixture_action(fixturedef, "SETUP") + + +def pytest_fixture_post_finalizer(fixturedef: FixtureDef[object]) -> None: + if fixturedef.cached_result is not None: + config = fixturedef._fixturemanager.config + if config.option.setupshow: + _show_fixture_action(fixturedef, "TEARDOWN") + if hasattr(fixturedef, "cached_param"): + del fixturedef.cached_param # type: ignore[attr-defined] + + +def _show_fixture_action(fixturedef: FixtureDef[object], msg: str) -> None: + config = fixturedef._fixturemanager.config + capman = config.pluginmanager.getplugin("capturemanager") + if capman: + capman.suspend_global_capture() + + tw = config.get_terminal_writer() + tw.line() + # Use smaller indentation the higher the scope: Session = 0, Package = 1, etc. + scope_indent = list(reversed(Scope)).index(fixturedef._scope) + tw.write(" " * 2 * scope_indent) + tw.write( + "{step} {scope} {fixture}".format( + step=msg.ljust(8), # align the output to TEARDOWN + scope=fixturedef.scope[0].upper(), + fixture=fixturedef.argname, + ) + ) + + if msg == "SETUP": + deps = sorted(arg for arg in fixturedef.argnames if arg != "request") + if deps: + tw.write(" (fixtures used: {})".format(", ".join(deps))) + + if hasattr(fixturedef, "cached_param"): + tw.write(f"[{saferepr(fixturedef.cached_param, maxsize=42)}]") # type: ignore[attr-defined] + + tw.flush() + + if capman: + capman.resume_global_capture() + + +@pytest.hookimpl(tryfirst=True) +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + if config.option.setuponly: + config.option.setupshow = True + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/setupplan.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/setupplan.py new file mode 100644 index 00000000..1a4ebdd9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/setupplan.py @@ -0,0 +1,40 @@ +from typing import Optional +from typing import Union + +import pytest +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config.argparsing import Parser +from _pytest.fixtures import FixtureDef +from _pytest.fixtures import SubRequest + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("debugconfig") + group.addoption( + "--setupplan", + "--setup-plan", + action="store_true", + help="Show what fixtures and tests would be executed but " + "don't execute anything", + ) + + +@pytest.hookimpl(tryfirst=True) +def pytest_fixture_setup( + fixturedef: FixtureDef[object], request: SubRequest +) -> Optional[object]: + # Will return a dummy fixture if the setuponly option is provided. + if request.config.option.setupplan: + my_cache_key = fixturedef.cache_key(request) + fixturedef.cached_result = (None, my_cache_key, None) + return fixturedef.cached_result + return None + + +@pytest.hookimpl(tryfirst=True) +def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: + if config.option.setupplan: + config.option.setuponly = True + config.option.setupshow = True + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/skipping.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/skipping.py new file mode 100644 index 00000000..26ce7375 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/skipping.py @@ -0,0 +1,297 @@ +"""Support for skip/xfail functions and markers.""" +import dataclasses +import os +import platform +import sys +import traceback +from collections.abc import Mapping +from typing import Generator +from typing import Optional +from typing import Tuple +from typing import Type + +from _pytest.config import Config +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.mark.structures import Mark +from _pytest.nodes import Item +from _pytest.outcomes import fail +from _pytest.outcomes import skip +from _pytest.outcomes import xfail +from _pytest.reports import BaseReport +from _pytest.runner import CallInfo +from _pytest.stash import StashKey + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group.addoption( + "--runxfail", + action="store_true", + dest="runxfail", + default=False, + help="Report the results of xfail tests as if they were not marked", + ) + + parser.addini( + "xfail_strict", + "Default for the strict parameter of xfail " + "markers when not given explicitly (default: False)", + default=False, + type="bool", + ) + + +def pytest_configure(config: Config) -> None: + if config.option.runxfail: + # yay a hack + import pytest + + old = pytest.xfail + config.add_cleanup(lambda: setattr(pytest, "xfail", old)) + + def nop(*args, **kwargs): + pass + + nop.Exception = xfail.Exception # type: ignore[attr-defined] + setattr(pytest, "xfail", nop) + + config.addinivalue_line( + "markers", + "skip(reason=None): skip the given test function with an optional reason. " + 'Example: skip(reason="no way of currently testing this") skips the ' + "test.", + ) + config.addinivalue_line( + "markers", + "skipif(condition, ..., *, reason=...): " + "skip the given test function if any of the conditions evaluate to True. " + "Example: skipif(sys.platform == 'win32') skips the test if we are on the win32 platform. " + "See https://docs.pytest.org/en/stable/reference/reference.html#pytest-mark-skipif", + ) + config.addinivalue_line( + "markers", + "xfail(condition, ..., *, reason=..., run=True, raises=None, strict=xfail_strict): " + "mark the test function as an expected failure if any of the conditions " + "evaluate to True. Optionally specify a reason for better reporting " + "and run=False if you don't even want to execute the test function. " + "If only specific exception(s) are expected, you can list them in " + "raises, and if the test fails in other ways, it will be reported as " + "a true failure. See https://docs.pytest.org/en/stable/reference/reference.html#pytest-mark-xfail", + ) + + +def evaluate_condition(item: Item, mark: Mark, condition: object) -> Tuple[bool, str]: + """Evaluate a single skipif/xfail condition. + + If an old-style string condition is given, it is eval()'d, otherwise the + condition is bool()'d. If this fails, an appropriately formatted pytest.fail + is raised. + + Returns (result, reason). The reason is only relevant if the result is True. + """ + # String condition. + if isinstance(condition, str): + globals_ = { + "os": os, + "sys": sys, + "platform": platform, + "config": item.config, + } + for dictionary in reversed( + item.ihook.pytest_markeval_namespace(config=item.config) + ): + if not isinstance(dictionary, Mapping): + raise ValueError( + "pytest_markeval_namespace() needs to return a dict, got {!r}".format( + dictionary + ) + ) + globals_.update(dictionary) + if hasattr(item, "obj"): + globals_.update(item.obj.__globals__) # type: ignore[attr-defined] + try: + filename = f"<{mark.name} condition>" + condition_code = compile(condition, filename, "eval") + result = eval(condition_code, globals_) + except SyntaxError as exc: + msglines = [ + "Error evaluating %r condition" % mark.name, + " " + condition, + " " + " " * (exc.offset or 0) + "^", + "SyntaxError: invalid syntax", + ] + fail("\n".join(msglines), pytrace=False) + except Exception as exc: + msglines = [ + "Error evaluating %r condition" % mark.name, + " " + condition, + *traceback.format_exception_only(type(exc), exc), + ] + fail("\n".join(msglines), pytrace=False) + + # Boolean condition. + else: + try: + result = bool(condition) + except Exception as exc: + msglines = [ + "Error evaluating %r condition as a boolean" % mark.name, + *traceback.format_exception_only(type(exc), exc), + ] + fail("\n".join(msglines), pytrace=False) + + reason = mark.kwargs.get("reason", None) + if reason is None: + if isinstance(condition, str): + reason = "condition: " + condition + else: + # XXX better be checked at collection time + msg = ( + "Error evaluating %r: " % mark.name + + "you need to specify reason=STRING when using booleans as conditions." + ) + fail(msg, pytrace=False) + + return result, reason + + +@dataclasses.dataclass(frozen=True) +class Skip: + """The result of evaluate_skip_marks().""" + + reason: str = "unconditional skip" + + +def evaluate_skip_marks(item: Item) -> Optional[Skip]: + """Evaluate skip and skipif marks on item, returning Skip if triggered.""" + for mark in item.iter_markers(name="skipif"): + if "condition" not in mark.kwargs: + conditions = mark.args + else: + conditions = (mark.kwargs["condition"],) + + # Unconditional. + if not conditions: + reason = mark.kwargs.get("reason", "") + return Skip(reason) + + # If any of the conditions are true. + for condition in conditions: + result, reason = evaluate_condition(item, mark, condition) + if result: + return Skip(reason) + + for mark in item.iter_markers(name="skip"): + try: + return Skip(*mark.args, **mark.kwargs) + except TypeError as e: + raise TypeError(str(e) + " - maybe you meant pytest.mark.skipif?") from None + + return None + + +@dataclasses.dataclass(frozen=True) +class Xfail: + """The result of evaluate_xfail_marks().""" + + __slots__ = ("reason", "run", "strict", "raises") + + reason: str + run: bool + strict: bool + raises: Optional[Tuple[Type[BaseException], ...]] + + +def evaluate_xfail_marks(item: Item) -> Optional[Xfail]: + """Evaluate xfail marks on item, returning Xfail if triggered.""" + for mark in item.iter_markers(name="xfail"): + run = mark.kwargs.get("run", True) + strict = mark.kwargs.get("strict", item.config.getini("xfail_strict")) + raises = mark.kwargs.get("raises", None) + if "condition" not in mark.kwargs: + conditions = mark.args + else: + conditions = (mark.kwargs["condition"],) + + # Unconditional. + if not conditions: + reason = mark.kwargs.get("reason", "") + return Xfail(reason, run, strict, raises) + + # If any of the conditions are true. + for condition in conditions: + result, reason = evaluate_condition(item, mark, condition) + if result: + return Xfail(reason, run, strict, raises) + + return None + + +# Saves the xfail mark evaluation. Can be refreshed during call if None. +xfailed_key = StashKey[Optional[Xfail]]() + + +@hookimpl(tryfirst=True) +def pytest_runtest_setup(item: Item) -> None: + skipped = evaluate_skip_marks(item) + if skipped: + raise skip.Exception(skipped.reason, _use_item_location=True) + + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) + if xfailed and not item.config.option.runxfail and not xfailed.run: + xfail("[NOTRUN] " + xfailed.reason) + + +@hookimpl(hookwrapper=True) +def pytest_runtest_call(item: Item) -> Generator[None, None, None]: + xfailed = item.stash.get(xfailed_key, None) + if xfailed is None: + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) + + if xfailed and not item.config.option.runxfail and not xfailed.run: + xfail("[NOTRUN] " + xfailed.reason) + + yield + + # The test run may have added an xfail mark dynamically. + xfailed = item.stash.get(xfailed_key, None) + if xfailed is None: + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) + + +@hookimpl(hookwrapper=True) +def pytest_runtest_makereport(item: Item, call: CallInfo[None]): + outcome = yield + rep = outcome.get_result() + xfailed = item.stash.get(xfailed_key, None) + if item.config.option.runxfail: + pass # don't interfere + elif call.excinfo and isinstance(call.excinfo.value, xfail.Exception): + assert call.excinfo.value.msg is not None + rep.wasxfail = "reason: " + call.excinfo.value.msg + rep.outcome = "skipped" + elif not rep.skipped and xfailed: + if call.excinfo: + raises = xfailed.raises + if raises is not None and not isinstance(call.excinfo.value, raises): + rep.outcome = "failed" + else: + rep.outcome = "skipped" + rep.wasxfail = xfailed.reason + elif call.when == "call": + if xfailed.strict: + rep.outcome = "failed" + rep.longrepr = "[XPASS(strict)] " + xfailed.reason + else: + rep.outcome = "passed" + rep.wasxfail = xfailed.reason + + +def pytest_report_teststatus(report: BaseReport) -> Optional[Tuple[str, str, str]]: + if hasattr(report, "wasxfail"): + if report.skipped: + return "xfailed", "x", "XFAIL" + elif report.passed: + return "xpassed", "X", "XPASS" + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/stash.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/stash.py new file mode 100644 index 00000000..e61d75b9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/stash.py @@ -0,0 +1,112 @@ +from typing import Any +from typing import cast +from typing import Dict +from typing import Generic +from typing import TypeVar +from typing import Union + + +__all__ = ["Stash", "StashKey"] + + +T = TypeVar("T") +D = TypeVar("D") + + +class StashKey(Generic[T]): + """``StashKey`` is an object used as a key to a :class:`Stash`. + + A ``StashKey`` is associated with the type ``T`` of the value of the key. + + A ``StashKey`` is unique and cannot conflict with another key. + """ + + __slots__ = () + + +class Stash: + r"""``Stash`` is a type-safe heterogeneous mutable mapping that + allows keys and value types to be defined separately from + where it (the ``Stash``) is created. + + Usually you will be given an object which has a ``Stash``, for example + :class:`~pytest.Config` or a :class:`~_pytest.nodes.Node`: + + .. code-block:: python + + stash: Stash = some_object.stash + + If a module or plugin wants to store data in this ``Stash``, it creates + :class:`StashKey`\s for its keys (at the module level): + + .. code-block:: python + + # At the top-level of the module + some_str_key = StashKey[str]() + some_bool_key = StashKey[bool]() + + To store information: + + .. code-block:: python + + # Value type must match the key. + stash[some_str_key] = "value" + stash[some_bool_key] = True + + To retrieve the information: + + .. code-block:: python + + # The static type of some_str is str. + some_str = stash[some_str_key] + # The static type of some_bool is bool. + some_bool = stash[some_bool_key] + """ + + __slots__ = ("_storage",) + + def __init__(self) -> None: + self._storage: Dict[StashKey[Any], object] = {} + + def __setitem__(self, key: StashKey[T], value: T) -> None: + """Set a value for key.""" + self._storage[key] = value + + def __getitem__(self, key: StashKey[T]) -> T: + """Get the value for key. + + Raises ``KeyError`` if the key wasn't set before. + """ + return cast(T, self._storage[key]) + + def get(self, key: StashKey[T], default: D) -> Union[T, D]: + """Get the value for key, or return default if the key wasn't set + before.""" + try: + return self[key] + except KeyError: + return default + + def setdefault(self, key: StashKey[T], default: T) -> T: + """Return the value of key if already set, otherwise set the value + of key to default and return default.""" + try: + return self[key] + except KeyError: + self[key] = default + return default + + def __delitem__(self, key: StashKey[T]) -> None: + """Delete the value for key. + + Raises ``KeyError`` if the key wasn't set before. + """ + del self._storage[key] + + def __contains__(self, key: StashKey[T]) -> bool: + """Return whether key was set.""" + return key in self._storage + + def __len__(self) -> int: + """Return how many items exist in the stash.""" + return len(self._storage) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/stepwise.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/stepwise.py new file mode 100644 index 00000000..74ad9dbd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/stepwise.py @@ -0,0 +1,130 @@ +from typing import List +from typing import Optional +from typing import TYPE_CHECKING + +import pytest +from _pytest import nodes +from _pytest.config import Config +from _pytest.config.argparsing import Parser +from _pytest.main import Session +from _pytest.reports import TestReport + +if TYPE_CHECKING: + from _pytest.cacheprovider import Cache + +STEPWISE_CACHE_DIR = "cache/stepwise" + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("general") + group.addoption( + "--sw", + "--stepwise", + action="store_true", + default=False, + dest="stepwise", + help="Exit on test failure and continue from last failing test next time", + ) + group.addoption( + "--sw-skip", + "--stepwise-skip", + action="store_true", + default=False, + dest="stepwise_skip", + help="Ignore the first failing test but stop on the next failing test. " + "Implicitly enables --stepwise.", + ) + + +@pytest.hookimpl +def pytest_configure(config: Config) -> None: + if config.option.stepwise_skip: + # allow --stepwise-skip to work on it's own merits. + config.option.stepwise = True + if config.getoption("stepwise"): + config.pluginmanager.register(StepwisePlugin(config), "stepwiseplugin") + + +def pytest_sessionfinish(session: Session) -> None: + if not session.config.getoption("stepwise"): + assert session.config.cache is not None + if hasattr(session.config, "workerinput"): + # Do not update cache if this process is a xdist worker to prevent + # race conditions (#10641). + return + # Clear the list of failing tests if the plugin is not active. + session.config.cache.set(STEPWISE_CACHE_DIR, []) + + +class StepwisePlugin: + def __init__(self, config: Config) -> None: + self.config = config + self.session: Optional[Session] = None + self.report_status = "" + assert config.cache is not None + self.cache: Cache = config.cache + self.lastfailed: Optional[str] = self.cache.get(STEPWISE_CACHE_DIR, None) + self.skip: bool = config.getoption("stepwise_skip") + + def pytest_sessionstart(self, session: Session) -> None: + self.session = session + + def pytest_collection_modifyitems( + self, config: Config, items: List[nodes.Item] + ) -> None: + if not self.lastfailed: + self.report_status = "no previously failed tests, not skipping." + return + + # check all item nodes until we find a match on last failed + failed_index = None + for index, item in enumerate(items): + if item.nodeid == self.lastfailed: + failed_index = index + break + + # If the previously failed test was not found among the test items, + # do not skip any tests. + if failed_index is None: + self.report_status = "previously failed test not found, not skipping." + else: + self.report_status = f"skipping {failed_index} already passed items." + deselected = items[:failed_index] + del items[:failed_index] + config.hook.pytest_deselected(items=deselected) + + def pytest_runtest_logreport(self, report: TestReport) -> None: + if report.failed: + if self.skip: + # Remove test from the failed ones (if it exists) and unset the skip option + # to make sure the following tests will not be skipped. + if report.nodeid == self.lastfailed: + self.lastfailed = None + + self.skip = False + else: + # Mark test as the last failing and interrupt the test session. + self.lastfailed = report.nodeid + assert self.session is not None + self.session.shouldstop = ( + "Test failed, continuing from this test next run." + ) + + else: + # If the test was actually run and did pass. + if report.when == "call": + # Remove test from the failed ones, if exists. + if report.nodeid == self.lastfailed: + self.lastfailed = None + + def pytest_report_collectionfinish(self) -> Optional[str]: + if self.config.getoption("verbose") >= 0 and self.report_status: + return f"stepwise: {self.report_status}" + return None + + def pytest_sessionfinish(self) -> None: + if hasattr(self.config, "workerinput"): + # Do not update cache if this process is a xdist worker to prevent + # race conditions (#10641). + return + self.cache.set(STEPWISE_CACHE_DIR, self.lastfailed) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/terminal.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/terminal.py new file mode 100644 index 00000000..b0cdb58c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/terminal.py @@ -0,0 +1,1481 @@ +"""Terminal reporting of the full testing process. + +This is a good source for looking at the various reporting hooks. +""" +import argparse +import dataclasses +import datetime +import inspect +import platform +import sys +import textwrap +import warnings +from collections import Counter +from functools import partial +from pathlib import Path +from typing import Any +from typing import Callable +from typing import cast +from typing import ClassVar +from typing import Dict +from typing import Generator +from typing import List +from typing import Mapping +from typing import NamedTuple +from typing import Optional +from typing import Sequence +from typing import Set +from typing import TextIO +from typing import Tuple +from typing import TYPE_CHECKING +from typing import Union + +import pluggy + +import _pytest._version +from _pytest import nodes +from _pytest import timing +from _pytest._code import ExceptionInfo +from _pytest._code.code import ExceptionRepr +from _pytest._io import TerminalWriter +from _pytest._io.wcwidth import wcswidth +from _pytest.assertion.util import running_on_ci +from _pytest.compat import final +from _pytest.config import _PluggyPlugin +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config.argparsing import Parser +from _pytest.nodes import Item +from _pytest.nodes import Node +from _pytest.pathlib import absolutepath +from _pytest.pathlib import bestrelpath +from _pytest.reports import BaseReport +from _pytest.reports import CollectReport +from _pytest.reports import TestReport + +if TYPE_CHECKING: + from typing_extensions import Literal + + from _pytest.main import Session + + +REPORT_COLLECTING_RESOLUTION = 0.5 + +KNOWN_TYPES = ( + "failed", + "passed", + "skipped", + "deselected", + "xfailed", + "xpassed", + "warnings", + "error", +) + +_REPORTCHARS_DEFAULT = "fE" + + +class MoreQuietAction(argparse.Action): + """A modified copy of the argparse count action which counts down and updates + the legacy quiet attribute at the same time. + + Used to unify verbosity handling. + """ + + def __init__( + self, + option_strings: Sequence[str], + dest: str, + default: object = None, + required: bool = False, + help: Optional[str] = None, + ) -> None: + super().__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + default=default, + required=required, + help=help, + ) + + def __call__( + self, + parser: argparse.ArgumentParser, + namespace: argparse.Namespace, + values: Union[str, Sequence[object], None], + option_string: Optional[str] = None, + ) -> None: + new_count = getattr(namespace, self.dest, 0) - 1 + setattr(namespace, self.dest, new_count) + # todo Deprecate config.quiet + namespace.quiet = getattr(namespace, "quiet", 0) + 1 + + +class TestShortLogReport(NamedTuple): + """Used to store the test status result category, shortletter and verbose word. + For example ``"rerun", "R", ("RERUN", {"yellow": True})``. + + :ivar category: + The class of result, for example ``“passed”``, ``“skipped”``, ``“error”``, or the empty string. + + :ivar letter: + The short letter shown as testing progresses, for example ``"."``, ``"s"``, ``"E"``, or the empty string. + + :ivar word: + Verbose word is shown as testing progresses in verbose mode, for example ``"PASSED"``, ``"SKIPPED"``, + ``"ERROR"``, or the empty string. + """ + + category: str + letter: str + word: Union[str, Tuple[str, Mapping[str, bool]]] + + +def pytest_addoption(parser: Parser) -> None: + group = parser.getgroup("terminal reporting", "Reporting", after="general") + group._addoption( + "-v", + "--verbose", + action="count", + default=0, + dest="verbose", + help="Increase verbosity", + ) + group._addoption( + "--no-header", + action="store_true", + default=False, + dest="no_header", + help="Disable header", + ) + group._addoption( + "--no-summary", + action="store_true", + default=False, + dest="no_summary", + help="Disable summary", + ) + group._addoption( + "-q", + "--quiet", + action=MoreQuietAction, + default=0, + dest="verbose", + help="Decrease verbosity", + ) + group._addoption( + "--verbosity", + dest="verbose", + type=int, + default=0, + help="Set verbosity. Default: 0.", + ) + group._addoption( + "-r", + action="store", + dest="reportchars", + default=_REPORTCHARS_DEFAULT, + metavar="chars", + help="Show extra test summary info as specified by chars: (f)ailed, " + "(E)rror, (s)kipped, (x)failed, (X)passed, " + "(p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll. " + "(w)arnings are enabled by default (see --disable-warnings), " + "'N' can be used to reset the list. (default: 'fE').", + ) + group._addoption( + "--disable-warnings", + "--disable-pytest-warnings", + default=False, + dest="disable_warnings", + action="store_true", + help="Disable warnings summary", + ) + group._addoption( + "-l", + "--showlocals", + action="store_true", + dest="showlocals", + default=False, + help="Show locals in tracebacks (disabled by default)", + ) + group._addoption( + "--no-showlocals", + action="store_false", + dest="showlocals", + help="Hide locals in tracebacks (negate --showlocals passed through addopts)", + ) + group._addoption( + "--tb", + metavar="style", + action="store", + dest="tbstyle", + default="auto", + choices=["auto", "long", "short", "no", "line", "native"], + help="Traceback print mode (auto/long/short/line/native/no)", + ) + group._addoption( + "--show-capture", + action="store", + dest="showcapture", + choices=["no", "stdout", "stderr", "log", "all"], + default="all", + help="Controls how captured stdout/stderr/log is shown on failed tests. " + "Default: all.", + ) + group._addoption( + "--fulltrace", + "--full-trace", + action="store_true", + default=False, + help="Don't cut any tracebacks (default is to cut)", + ) + group._addoption( + "--color", + metavar="color", + action="store", + dest="color", + default="auto", + choices=["yes", "no", "auto"], + help="Color terminal output (yes/no/auto)", + ) + group._addoption( + "--code-highlight", + default="yes", + choices=["yes", "no"], + help="Whether code should be highlighted (only if --color is also enabled). " + "Default: yes.", + ) + + parser.addini( + "console_output_style", + help='Console output: "classic", or with additional progress information ' + '("progress" (percentage) | "count" | "progress-even-when-capture-no" (forces ' + "progress even when capture=no)", + default="progress", + ) + + +def pytest_configure(config: Config) -> None: + reporter = TerminalReporter(config, sys.stdout) + config.pluginmanager.register(reporter, "terminalreporter") + if config.option.debug or config.option.traceconfig: + + def mywriter(tags, args): + msg = " ".join(map(str, args)) + reporter.write_line("[traceconfig] " + msg) + + config.trace.root.setprocessor("pytest:config", mywriter) + + +def getreportopt(config: Config) -> str: + reportchars: str = config.option.reportchars + + old_aliases = {"F", "S"} + reportopts = "" + for char in reportchars: + if char in old_aliases: + char = char.lower() + if char == "a": + reportopts = "sxXEf" + elif char == "A": + reportopts = "PpsxXEf" + elif char == "N": + reportopts = "" + elif char not in reportopts: + reportopts += char + + if not config.option.disable_warnings and "w" not in reportopts: + reportopts = "w" + reportopts + elif config.option.disable_warnings and "w" in reportopts: + reportopts = reportopts.replace("w", "") + + return reportopts + + +@hookimpl(trylast=True) # after _pytest.runner +def pytest_report_teststatus(report: BaseReport) -> Tuple[str, str, str]: + letter = "F" + if report.passed: + letter = "." + elif report.skipped: + letter = "s" + + outcome: str = report.outcome + if report.when in ("collect", "setup", "teardown") and outcome == "failed": + outcome = "error" + letter = "E" + + return outcome, letter, outcome.upper() + + +@dataclasses.dataclass +class WarningReport: + """Simple structure to hold warnings information captured by ``pytest_warning_recorded``. + + :ivar str message: + User friendly message about the warning. + :ivar str|None nodeid: + nodeid that generated the warning (see ``get_location``). + :ivar tuple fslocation: + File system location of the source of the warning (see ``get_location``). + """ + + message: str + nodeid: Optional[str] = None + fslocation: Optional[Tuple[str, int]] = None + + count_towards_summary: ClassVar = True + + def get_location(self, config: Config) -> Optional[str]: + """Return the more user-friendly information about the location of a warning, or None.""" + if self.nodeid: + return self.nodeid + if self.fslocation: + filename, linenum = self.fslocation + relpath = bestrelpath(config.invocation_params.dir, absolutepath(filename)) + return f"{relpath}:{linenum}" + return None + + +@final +class TerminalReporter: + def __init__(self, config: Config, file: Optional[TextIO] = None) -> None: + import _pytest.config + + self.config = config + self._numcollected = 0 + self._session: Optional[Session] = None + self._showfspath: Optional[bool] = None + + self.stats: Dict[str, List[Any]] = {} + self._main_color: Optional[str] = None + self._known_types: Optional[List[str]] = None + self.startpath = config.invocation_params.dir + if file is None: + file = sys.stdout + self._tw = _pytest.config.create_terminal_writer(config, file) + self._screen_width = self._tw.fullwidth + self.currentfspath: Union[None, Path, str, int] = None + self.reportchars = getreportopt(config) + self.hasmarkup = self._tw.hasmarkup + self.isatty = file.isatty() + self._progress_nodeids_reported: Set[str] = set() + self._show_progress_info = self._determine_show_progress_info() + self._collect_report_last_write: Optional[float] = None + self._already_displayed_warnings: Optional[int] = None + self._keyboardinterrupt_memo: Optional[ExceptionRepr] = None + + def _determine_show_progress_info(self) -> "Literal['progress', 'count', False]": + """Return whether we should display progress information based on the current config.""" + # do not show progress if we are not capturing output (#3038) unless explicitly + # overridden by progress-even-when-capture-no + if ( + self.config.getoption("capture", "no") == "no" + and self.config.getini("console_output_style") + != "progress-even-when-capture-no" + ): + return False + # do not show progress if we are showing fixture setup/teardown + if self.config.getoption("setupshow", False): + return False + cfg: str = self.config.getini("console_output_style") + if cfg == "progress" or cfg == "progress-even-when-capture-no": + return "progress" + elif cfg == "count": + return "count" + else: + return False + + @property + def verbosity(self) -> int: + verbosity: int = self.config.option.verbose + return verbosity + + @property + def showheader(self) -> bool: + return self.verbosity >= 0 + + @property + def no_header(self) -> bool: + return bool(self.config.option.no_header) + + @property + def no_summary(self) -> bool: + return bool(self.config.option.no_summary) + + @property + def showfspath(self) -> bool: + if self._showfspath is None: + return self.verbosity >= 0 + return self._showfspath + + @showfspath.setter + def showfspath(self, value: Optional[bool]) -> None: + self._showfspath = value + + @property + def showlongtestinfo(self) -> bool: + return self.verbosity > 0 + + def hasopt(self, char: str) -> bool: + char = {"xfailed": "x", "skipped": "s"}.get(char, char) + return char in self.reportchars + + def write_fspath_result(self, nodeid: str, res, **markup: bool) -> None: + fspath = self.config.rootpath / nodeid.split("::")[0] + if self.currentfspath is None or fspath != self.currentfspath: + if self.currentfspath is not None and self._show_progress_info: + self._write_progress_information_filling_space() + self.currentfspath = fspath + relfspath = bestrelpath(self.startpath, fspath) + self._tw.line() + self._tw.write(relfspath + " ") + self._tw.write(res, flush=True, **markup) + + def write_ensure_prefix(self, prefix: str, extra: str = "", **kwargs) -> None: + if self.currentfspath != prefix: + self._tw.line() + self.currentfspath = prefix + self._tw.write(prefix) + if extra: + self._tw.write(extra, **kwargs) + self.currentfspath = -2 + + def ensure_newline(self) -> None: + if self.currentfspath: + self._tw.line() + self.currentfspath = None + + def wrap_write( + self, + content: str, + *, + flush: bool = False, + margin: int = 8, + line_sep: str = "\n", + **markup: bool, + ) -> None: + """Wrap message with margin for progress info.""" + width_of_current_line = self._tw.width_of_current_line + wrapped = line_sep.join( + textwrap.wrap( + " " * width_of_current_line + content, + width=self._screen_width - margin, + drop_whitespace=True, + replace_whitespace=False, + ), + ) + wrapped = wrapped[width_of_current_line:] + self._tw.write(wrapped, flush=flush, **markup) + + def write(self, content: str, *, flush: bool = False, **markup: bool) -> None: + self._tw.write(content, flush=flush, **markup) + + def flush(self) -> None: + self._tw.flush() + + def write_line(self, line: Union[str, bytes], **markup: bool) -> None: + if not isinstance(line, str): + line = str(line, errors="replace") + self.ensure_newline() + self._tw.line(line, **markup) + + def rewrite(self, line: str, **markup: bool) -> None: + """Rewinds the terminal cursor to the beginning and writes the given line. + + :param erase: + If True, will also add spaces until the full terminal width to ensure + previous lines are properly erased. + + The rest of the keyword arguments are markup instructions. + """ + erase = markup.pop("erase", False) + if erase: + fill_count = self._tw.fullwidth - len(line) - 1 + fill = " " * fill_count + else: + fill = "" + line = str(line) + self._tw.write("\r" + line + fill, **markup) + + def write_sep( + self, + sep: str, + title: Optional[str] = None, + fullwidth: Optional[int] = None, + **markup: bool, + ) -> None: + self.ensure_newline() + self._tw.sep(sep, title, fullwidth, **markup) + + def section(self, title: str, sep: str = "=", **kw: bool) -> None: + self._tw.sep(sep, title, **kw) + + def line(self, msg: str, **kw: bool) -> None: + self._tw.line(msg, **kw) + + def _add_stats(self, category: str, items: Sequence[Any]) -> None: + set_main_color = category not in self.stats + self.stats.setdefault(category, []).extend(items) + if set_main_color: + self._set_main_color() + + def pytest_internalerror(self, excrepr: ExceptionRepr) -> bool: + for line in str(excrepr).split("\n"): + self.write_line("INTERNALERROR> " + line) + return True + + def pytest_warning_recorded( + self, + warning_message: warnings.WarningMessage, + nodeid: str, + ) -> None: + from _pytest.warnings import warning_record_to_str + + fslocation = warning_message.filename, warning_message.lineno + message = warning_record_to_str(warning_message) + + warning_report = WarningReport( + fslocation=fslocation, message=message, nodeid=nodeid + ) + self._add_stats("warnings", [warning_report]) + + def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None: + if self.config.option.traceconfig: + msg = f"PLUGIN registered: {plugin}" + # XXX This event may happen during setup/teardown time + # which unfortunately captures our output here + # which garbles our output if we use self.write_line. + self.write_line(msg) + + def pytest_deselected(self, items: Sequence[Item]) -> None: + self._add_stats("deselected", items) + + def pytest_runtest_logstart( + self, nodeid: str, location: Tuple[str, Optional[int], str] + ) -> None: + # Ensure that the path is printed before the + # 1st test of a module starts running. + if self.showlongtestinfo: + line = self._locationline(nodeid, *location) + self.write_ensure_prefix(line, "") + self.flush() + elif self.showfspath: + self.write_fspath_result(nodeid, "") + self.flush() + + def pytest_runtest_logreport(self, report: TestReport) -> None: + self._tests_ran = True + rep = report + + res = TestShortLogReport( + *self.config.hook.pytest_report_teststatus(report=rep, config=self.config) + ) + category, letter, word = res.category, res.letter, res.word + if not isinstance(word, tuple): + markup = None + else: + word, markup = word + self._add_stats(category, [rep]) + if not letter and not word: + # Probably passed setup/teardown. + return + running_xdist = hasattr(rep, "node") + if markup is None: + was_xfail = hasattr(report, "wasxfail") + if rep.passed and not was_xfail: + markup = {"green": True} + elif rep.passed and was_xfail: + markup = {"yellow": True} + elif rep.failed: + markup = {"red": True} + elif rep.skipped: + markup = {"yellow": True} + else: + markup = {} + if self.verbosity <= 0: + self._tw.write(letter, **markup) + else: + self._progress_nodeids_reported.add(rep.nodeid) + line = self._locationline(rep.nodeid, *rep.location) + if not running_xdist: + self.write_ensure_prefix(line, word, **markup) + if rep.skipped or hasattr(report, "wasxfail"): + reason = _get_raw_skip_reason(rep) + if self.config.option.verbose < 2: + available_width = ( + (self._tw.fullwidth - self._tw.width_of_current_line) + - len(" [100%]") + - 1 + ) + formatted_reason = _format_trimmed( + " ({})", reason, available_width + ) + else: + formatted_reason = f" ({reason})" + + if reason and formatted_reason is not None: + self.wrap_write(formatted_reason) + if self._show_progress_info: + self._write_progress_information_filling_space() + else: + self.ensure_newline() + self._tw.write("[%s]" % rep.node.gateway.id) + if self._show_progress_info: + self._tw.write( + self._get_progress_information_message() + " ", cyan=True + ) + else: + self._tw.write(" ") + self._tw.write(word, **markup) + self._tw.write(" " + line) + self.currentfspath = -2 + self.flush() + + @property + def _is_last_item(self) -> bool: + assert self._session is not None + return len(self._progress_nodeids_reported) == self._session.testscollected + + def pytest_runtest_logfinish(self, nodeid: str) -> None: + assert self._session + if self.verbosity <= 0 and self._show_progress_info: + if self._show_progress_info == "count": + num_tests = self._session.testscollected + progress_length = len(f" [{num_tests}/{num_tests}]") + else: + progress_length = len(" [100%]") + + self._progress_nodeids_reported.add(nodeid) + + if self._is_last_item: + self._write_progress_information_filling_space() + else: + main_color, _ = self._get_main_color() + w = self._width_of_current_line + past_edge = w + progress_length + 1 >= self._screen_width + if past_edge: + msg = self._get_progress_information_message() + self._tw.write(msg + "\n", **{main_color: True}) + + def _get_progress_information_message(self) -> str: + assert self._session + collected = self._session.testscollected + if self._show_progress_info == "count": + if collected: + progress = self._progress_nodeids_reported + counter_format = f"{{:{len(str(collected))}d}}" + format_string = f" [{counter_format}/{{}}]" + return format_string.format(len(progress), collected) + return f" [ {collected} / {collected} ]" + else: + if collected: + return " [{:3d}%]".format( + len(self._progress_nodeids_reported) * 100 // collected + ) + return " [100%]" + + def _write_progress_information_filling_space(self) -> None: + color, _ = self._get_main_color() + msg = self._get_progress_information_message() + w = self._width_of_current_line + fill = self._tw.fullwidth - w - 1 + self.write(msg.rjust(fill), flush=True, **{color: True}) + + @property + def _width_of_current_line(self) -> int: + """Return the width of the current line.""" + return self._tw.width_of_current_line + + def pytest_collection(self) -> None: + if self.isatty: + if self.config.option.verbose >= 0: + self.write("collecting ... ", flush=True, bold=True) + self._collect_report_last_write = timing.time() + elif self.config.option.verbose >= 1: + self.write("collecting ... ", flush=True, bold=True) + + def pytest_collectreport(self, report: CollectReport) -> None: + if report.failed: + self._add_stats("error", [report]) + elif report.skipped: + self._add_stats("skipped", [report]) + items = [x for x in report.result if isinstance(x, Item)] + self._numcollected += len(items) + if self.isatty: + self.report_collect() + + def report_collect(self, final: bool = False) -> None: + if self.config.option.verbose < 0: + return + + if not final: + # Only write "collecting" report every 0.5s. + t = timing.time() + if ( + self._collect_report_last_write is not None + and self._collect_report_last_write > t - REPORT_COLLECTING_RESOLUTION + ): + return + self._collect_report_last_write = t + + errors = len(self.stats.get("error", [])) + skipped = len(self.stats.get("skipped", [])) + deselected = len(self.stats.get("deselected", [])) + selected = self._numcollected - deselected + line = "collected " if final else "collecting " + line += ( + str(self._numcollected) + " item" + ("" if self._numcollected == 1 else "s") + ) + if errors: + line += " / %d error%s" % (errors, "s" if errors != 1 else "") + if deselected: + line += " / %d deselected" % deselected + if skipped: + line += " / %d skipped" % skipped + if self._numcollected > selected: + line += " / %d selected" % selected + if self.isatty: + self.rewrite(line, bold=True, erase=True) + if final: + self.write("\n") + else: + self.write_line(line) + + @hookimpl(trylast=True) + def pytest_sessionstart(self, session: "Session") -> None: + self._session = session + self._sessionstarttime = timing.time() + if not self.showheader: + return + self.write_sep("=", "test session starts", bold=True) + verinfo = platform.python_version() + if not self.no_header: + msg = f"platform {sys.platform} -- Python {verinfo}" + pypy_version_info = getattr(sys, "pypy_version_info", None) + if pypy_version_info: + verinfo = ".".join(map(str, pypy_version_info[:3])) + msg += f"[pypy-{verinfo}-{pypy_version_info[3]}]" + msg += ", pytest-{}, pluggy-{}".format( + _pytest._version.version, pluggy.__version__ + ) + if ( + self.verbosity > 0 + or self.config.option.debug + or getattr(self.config.option, "pastebin", None) + ): + msg += " -- " + str(sys.executable) + self.write_line(msg) + lines = self.config.hook.pytest_report_header( + config=self.config, start_path=self.startpath + ) + self._write_report_lines_from_hooks(lines) + + def _write_report_lines_from_hooks( + self, lines: Sequence[Union[str, Sequence[str]]] + ) -> None: + for line_or_lines in reversed(lines): + if isinstance(line_or_lines, str): + self.write_line(line_or_lines) + else: + for line in line_or_lines: + self.write_line(line) + + def pytest_report_header(self, config: Config) -> List[str]: + result = [f"rootdir: {config.rootpath}"] + + if config.inipath: + result.append("configfile: " + bestrelpath(config.rootpath, config.inipath)) + + if config.args_source == Config.ArgsSource.TESTPATHS: + testpaths: List[str] = config.getini("testpaths") + result.append("testpaths: {}".format(", ".join(testpaths))) + + plugininfo = config.pluginmanager.list_plugin_distinfo() + if plugininfo: + result.append("plugins: %s" % ", ".join(_plugin_nameversions(plugininfo))) + return result + + def pytest_collection_finish(self, session: "Session") -> None: + self.report_collect(True) + + lines = self.config.hook.pytest_report_collectionfinish( + config=self.config, + start_path=self.startpath, + items=session.items, + ) + self._write_report_lines_from_hooks(lines) + + if self.config.getoption("collectonly"): + if session.items: + if self.config.option.verbose > -1: + self._tw.line("") + self._printcollecteditems(session.items) + + failed = self.stats.get("failed") + if failed: + self._tw.sep("!", "collection failures") + for rep in failed: + rep.toterminal(self._tw) + + def _printcollecteditems(self, items: Sequence[Item]) -> None: + if self.config.option.verbose < 0: + if self.config.option.verbose < -1: + counts = Counter(item.nodeid.split("::", 1)[0] for item in items) + for name, count in sorted(counts.items()): + self._tw.line("%s: %d" % (name, count)) + else: + for item in items: + self._tw.line(item.nodeid) + return + stack: List[Node] = [] + indent = "" + for item in items: + needed_collectors = item.listchain()[1:] # strip root node + while stack: + if stack == needed_collectors[: len(stack)]: + break + stack.pop() + for col in needed_collectors[len(stack) :]: + stack.append(col) + indent = (len(stack) - 1) * " " + self._tw.line(f"{indent}{col}") + if self.config.option.verbose >= 1: + obj = getattr(col, "obj", None) + doc = inspect.getdoc(obj) if obj else None + if doc: + for line in doc.splitlines(): + self._tw.line("{}{}".format(indent + " ", line)) + + @hookimpl(hookwrapper=True) + def pytest_sessionfinish( + self, session: "Session", exitstatus: Union[int, ExitCode] + ): + outcome = yield + outcome.get_result() + self._tw.line("") + summary_exit_codes = ( + ExitCode.OK, + ExitCode.TESTS_FAILED, + ExitCode.INTERRUPTED, + ExitCode.USAGE_ERROR, + ExitCode.NO_TESTS_COLLECTED, + ) + if exitstatus in summary_exit_codes and not self.no_summary: + self.config.hook.pytest_terminal_summary( + terminalreporter=self, exitstatus=exitstatus, config=self.config + ) + if session.shouldfail: + self.write_sep("!", str(session.shouldfail), red=True) + if exitstatus == ExitCode.INTERRUPTED: + self._report_keyboardinterrupt() + self._keyboardinterrupt_memo = None + elif session.shouldstop: + self.write_sep("!", str(session.shouldstop), red=True) + self.summary_stats() + + @hookimpl(hookwrapper=True) + def pytest_terminal_summary(self) -> Generator[None, None, None]: + self.summary_errors() + self.summary_failures() + self.summary_warnings() + self.summary_passes() + yield + self.short_test_summary() + # Display any extra warnings from teardown here (if any). + self.summary_warnings() + + def pytest_keyboard_interrupt(self, excinfo: ExceptionInfo[BaseException]) -> None: + self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True) + + def pytest_unconfigure(self) -> None: + if self._keyboardinterrupt_memo is not None: + self._report_keyboardinterrupt() + + def _report_keyboardinterrupt(self) -> None: + excrepr = self._keyboardinterrupt_memo + assert excrepr is not None + assert excrepr.reprcrash is not None + msg = excrepr.reprcrash.message + self.write_sep("!", msg) + if "KeyboardInterrupt" in msg: + if self.config.option.fulltrace: + excrepr.toterminal(self._tw) + else: + excrepr.reprcrash.toterminal(self._tw) + self._tw.line( + "(to show a full traceback on KeyboardInterrupt use --full-trace)", + yellow=True, + ) + + def _locationline( + self, nodeid: str, fspath: str, lineno: Optional[int], domain: str + ) -> str: + def mkrel(nodeid: str) -> str: + line = self.config.cwd_relative_nodeid(nodeid) + if domain and line.endswith(domain): + line = line[: -len(domain)] + values = domain.split("[") + values[0] = values[0].replace(".", "::") # don't replace '.' in params + line += "[".join(values) + return line + + # collect_fspath comes from testid which has a "/"-normalized path. + if fspath: + res = mkrel(nodeid) + if self.verbosity >= 2 and nodeid.split("::")[0] != fspath.replace( + "\\", nodes.SEP + ): + res += " <- " + bestrelpath(self.startpath, Path(fspath)) + else: + res = "[location]" + return res + " " + + def _getfailureheadline(self, rep): + head_line = rep.head_line + if head_line: + return head_line + return "test session" # XXX? + + def _getcrashline(self, rep): + try: + return str(rep.longrepr.reprcrash) + except AttributeError: + try: + return str(rep.longrepr)[:50] + except AttributeError: + return "" + + # + # Summaries for sessionfinish. + # + def getreports(self, name: str): + return [x for x in self.stats.get(name, ()) if not hasattr(x, "_pdbshown")] + + def summary_warnings(self) -> None: + if self.hasopt("w"): + all_warnings: Optional[List[WarningReport]] = self.stats.get("warnings") + if not all_warnings: + return + + final = self._already_displayed_warnings is not None + if final: + warning_reports = all_warnings[self._already_displayed_warnings :] + else: + warning_reports = all_warnings + self._already_displayed_warnings = len(warning_reports) + if not warning_reports: + return + + reports_grouped_by_message: Dict[str, List[WarningReport]] = {} + for wr in warning_reports: + reports_grouped_by_message.setdefault(wr.message, []).append(wr) + + def collapsed_location_report(reports: List[WarningReport]) -> str: + locations = [] + for w in reports: + location = w.get_location(self.config) + if location: + locations.append(location) + + if len(locations) < 10: + return "\n".join(map(str, locations)) + + counts_by_filename = Counter( + str(loc).split("::", 1)[0] for loc in locations + ) + return "\n".join( + "{}: {} warning{}".format(k, v, "s" if v > 1 else "") + for k, v in counts_by_filename.items() + ) + + title = "warnings summary (final)" if final else "warnings summary" + self.write_sep("=", title, yellow=True, bold=False) + for message, message_reports in reports_grouped_by_message.items(): + maybe_location = collapsed_location_report(message_reports) + if maybe_location: + self._tw.line(maybe_location) + lines = message.splitlines() + indented = "\n".join(" " + x for x in lines) + message = indented.rstrip() + else: + message = message.rstrip() + self._tw.line(message) + self._tw.line() + self._tw.line( + "-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html" + ) + + def summary_passes(self) -> None: + if self.config.option.tbstyle != "no": + if self.hasopt("P"): + reports: List[TestReport] = self.getreports("passed") + if not reports: + return + self.write_sep("=", "PASSES") + for rep in reports: + if rep.sections: + msg = self._getfailureheadline(rep) + self.write_sep("_", msg, green=True, bold=True) + self._outrep_summary(rep) + self._handle_teardown_sections(rep.nodeid) + + def _get_teardown_reports(self, nodeid: str) -> List[TestReport]: + reports = self.getreports("") + return [ + report + for report in reports + if report.when == "teardown" and report.nodeid == nodeid + ] + + def _handle_teardown_sections(self, nodeid: str) -> None: + for report in self._get_teardown_reports(nodeid): + self.print_teardown_sections(report) + + def print_teardown_sections(self, rep: TestReport) -> None: + showcapture = self.config.option.showcapture + if showcapture == "no": + return + for secname, content in rep.sections: + if showcapture != "all" and showcapture not in secname: + continue + if "teardown" in secname: + self._tw.sep("-", secname) + if content[-1:] == "\n": + content = content[:-1] + self._tw.line(content) + + def summary_failures(self) -> None: + if self.config.option.tbstyle != "no": + reports: List[BaseReport] = self.getreports("failed") + if not reports: + return + self.write_sep("=", "FAILURES") + if self.config.option.tbstyle == "line": + for rep in reports: + line = self._getcrashline(rep) + self.write_line(line) + else: + for rep in reports: + msg = self._getfailureheadline(rep) + self.write_sep("_", msg, red=True, bold=True) + self._outrep_summary(rep) + self._handle_teardown_sections(rep.nodeid) + + def summary_errors(self) -> None: + if self.config.option.tbstyle != "no": + reports: List[BaseReport] = self.getreports("error") + if not reports: + return + self.write_sep("=", "ERRORS") + for rep in self.stats["error"]: + msg = self._getfailureheadline(rep) + if rep.when == "collect": + msg = "ERROR collecting " + msg + else: + msg = f"ERROR at {rep.when} of {msg}" + self.write_sep("_", msg, red=True, bold=True) + self._outrep_summary(rep) + + def _outrep_summary(self, rep: BaseReport) -> None: + rep.toterminal(self._tw) + showcapture = self.config.option.showcapture + if showcapture == "no": + return + for secname, content in rep.sections: + if showcapture != "all" and showcapture not in secname: + continue + self._tw.sep("-", secname) + if content[-1:] == "\n": + content = content[:-1] + self._tw.line(content) + + def summary_stats(self) -> None: + if self.verbosity < -1: + return + + session_duration = timing.time() - self._sessionstarttime + (parts, main_color) = self.build_summary_stats_line() + line_parts = [] + + display_sep = self.verbosity >= 0 + if display_sep: + fullwidth = self._tw.fullwidth + for text, markup in parts: + with_markup = self._tw.markup(text, **markup) + if display_sep: + fullwidth += len(with_markup) - len(text) + line_parts.append(with_markup) + msg = ", ".join(line_parts) + + main_markup = {main_color: True} + duration = f" in {format_session_duration(session_duration)}" + duration_with_markup = self._tw.markup(duration, **main_markup) + if display_sep: + fullwidth += len(duration_with_markup) - len(duration) + msg += duration_with_markup + + if display_sep: + markup_for_end_sep = self._tw.markup("", **main_markup) + if markup_for_end_sep.endswith("\x1b[0m"): + markup_for_end_sep = markup_for_end_sep[:-4] + fullwidth += len(markup_for_end_sep) + msg += markup_for_end_sep + + if display_sep: + self.write_sep("=", msg, fullwidth=fullwidth, **main_markup) + else: + self.write_line(msg, **main_markup) + + def short_test_summary(self) -> None: + if not self.reportchars: + return + + def show_simple(lines: List[str], *, stat: str) -> None: + failed = self.stats.get(stat, []) + if not failed: + return + config = self.config + for rep in failed: + color = _color_for_type.get(stat, _color_for_type_default) + line = _get_line_with_reprcrash_message( + config, rep, self._tw, {color: True} + ) + lines.append(line) + + def show_xfailed(lines: List[str]) -> None: + xfailed = self.stats.get("xfailed", []) + for rep in xfailed: + verbose_word = rep._get_verbose_word(self.config) + markup_word = self._tw.markup( + verbose_word, **{_color_for_type["warnings"]: True} + ) + nodeid = _get_node_id_with_markup(self._tw, self.config, rep) + line = f"{markup_word} {nodeid}" + reason = rep.wasxfail + if reason: + line += " - " + str(reason) + + lines.append(line) + + def show_xpassed(lines: List[str]) -> None: + xpassed = self.stats.get("xpassed", []) + for rep in xpassed: + verbose_word = rep._get_verbose_word(self.config) + markup_word = self._tw.markup( + verbose_word, **{_color_for_type["warnings"]: True} + ) + nodeid = _get_node_id_with_markup(self._tw, self.config, rep) + reason = rep.wasxfail + lines.append(f"{markup_word} {nodeid} {reason}") + + def show_skipped(lines: List[str]) -> None: + skipped: List[CollectReport] = self.stats.get("skipped", []) + fskips = _folded_skips(self.startpath, skipped) if skipped else [] + if not fskips: + return + verbose_word = skipped[0]._get_verbose_word(self.config) + markup_word = self._tw.markup( + verbose_word, **{_color_for_type["warnings"]: True} + ) + prefix = "Skipped: " + for num, fspath, lineno, reason in fskips: + if reason.startswith(prefix): + reason = reason[len(prefix) :] + if lineno is not None: + lines.append( + "%s [%d] %s:%d: %s" % (markup_word, num, fspath, lineno, reason) + ) + else: + lines.append("%s [%d] %s: %s" % (markup_word, num, fspath, reason)) + + REPORTCHAR_ACTIONS: Mapping[str, Callable[[List[str]], None]] = { + "x": show_xfailed, + "X": show_xpassed, + "f": partial(show_simple, stat="failed"), + "s": show_skipped, + "p": partial(show_simple, stat="passed"), + "E": partial(show_simple, stat="error"), + } + + lines: List[str] = [] + for char in self.reportchars: + action = REPORTCHAR_ACTIONS.get(char) + if action: # skipping e.g. "P" (passed with output) here. + action(lines) + + if lines: + self.write_sep("=", "short test summary info", cyan=True, bold=True) + for line in lines: + self.write_line(line) + + def _get_main_color(self) -> Tuple[str, List[str]]: + if self._main_color is None or self._known_types is None or self._is_last_item: + self._set_main_color() + assert self._main_color + assert self._known_types + return self._main_color, self._known_types + + def _determine_main_color(self, unknown_type_seen: bool) -> str: + stats = self.stats + if "failed" in stats or "error" in stats: + main_color = "red" + elif "warnings" in stats or "xpassed" in stats or unknown_type_seen: + main_color = "yellow" + elif "passed" in stats or not self._is_last_item: + main_color = "green" + else: + main_color = "yellow" + return main_color + + def _set_main_color(self) -> None: + unknown_types: List[str] = [] + for found_type in self.stats.keys(): + if found_type: # setup/teardown reports have an empty key, ignore them + if found_type not in KNOWN_TYPES and found_type not in unknown_types: + unknown_types.append(found_type) + self._known_types = list(KNOWN_TYPES) + unknown_types + self._main_color = self._determine_main_color(bool(unknown_types)) + + def build_summary_stats_line(self) -> Tuple[List[Tuple[str, Dict[str, bool]]], str]: + """ + Build the parts used in the last summary stats line. + + The summary stats line is the line shown at the end, "=== 12 passed, 2 errors in Xs===". + + This function builds a list of the "parts" that make up for the text in that line, in + the example above it would be: + + [ + ("12 passed", {"green": True}), + ("2 errors", {"red": True} + ] + + That last dict for each line is a "markup dictionary", used by TerminalWriter to + color output. + + The final color of the line is also determined by this function, and is the second + element of the returned tuple. + """ + if self.config.getoption("collectonly"): + return self._build_collect_only_summary_stats_line() + else: + return self._build_normal_summary_stats_line() + + def _get_reports_to_display(self, key: str) -> List[Any]: + """Get test/collection reports for the given status key, such as `passed` or `error`.""" + reports = self.stats.get(key, []) + return [x for x in reports if getattr(x, "count_towards_summary", True)] + + def _build_normal_summary_stats_line( + self, + ) -> Tuple[List[Tuple[str, Dict[str, bool]]], str]: + main_color, known_types = self._get_main_color() + parts = [] + + for key in known_types: + reports = self._get_reports_to_display(key) + if reports: + count = len(reports) + color = _color_for_type.get(key, _color_for_type_default) + markup = {color: True, "bold": color == main_color} + parts.append(("%d %s" % pluralize(count, key), markup)) + + if not parts: + parts = [("no tests ran", {_color_for_type_default: True})] + + return parts, main_color + + def _build_collect_only_summary_stats_line( + self, + ) -> Tuple[List[Tuple[str, Dict[str, bool]]], str]: + deselected = len(self._get_reports_to_display("deselected")) + errors = len(self._get_reports_to_display("error")) + + if self._numcollected == 0: + parts = [("no tests collected", {"yellow": True})] + main_color = "yellow" + + elif deselected == 0: + main_color = "green" + collected_output = "%d %s collected" % pluralize(self._numcollected, "test") + parts = [(collected_output, {main_color: True})] + else: + all_tests_were_deselected = self._numcollected == deselected + if all_tests_were_deselected: + main_color = "yellow" + collected_output = f"no tests collected ({deselected} deselected)" + else: + main_color = "green" + selected = self._numcollected - deselected + collected_output = f"{selected}/{self._numcollected} tests collected ({deselected} deselected)" + + parts = [(collected_output, {main_color: True})] + + if errors: + main_color = _color_for_type["error"] + parts += [("%d %s" % pluralize(errors, "error"), {main_color: True})] + + return parts, main_color + + +def _get_node_id_with_markup(tw: TerminalWriter, config: Config, rep: BaseReport): + nodeid = config.cwd_relative_nodeid(rep.nodeid) + path, *parts = nodeid.split("::") + if parts: + parts_markup = tw.markup("::".join(parts), bold=True) + return path + "::" + parts_markup + else: + return path + + +def _format_trimmed(format: str, msg: str, available_width: int) -> Optional[str]: + """Format msg into format, ellipsizing it if doesn't fit in available_width. + + Returns None if even the ellipsis can't fit. + """ + # Only use the first line. + i = msg.find("\n") + if i != -1: + msg = msg[:i] + + ellipsis = "..." + format_width = wcswidth(format.format("")) + if format_width + len(ellipsis) > available_width: + return None + + if format_width + wcswidth(msg) > available_width: + available_width -= len(ellipsis) + msg = msg[:available_width] + while format_width + wcswidth(msg) > available_width: + msg = msg[:-1] + msg += ellipsis + + return format.format(msg) + + +def _get_line_with_reprcrash_message( + config: Config, rep: BaseReport, tw: TerminalWriter, word_markup: Dict[str, bool] +) -> str: + """Get summary line for a report, trying to add reprcrash message.""" + verbose_word = rep._get_verbose_word(config) + word = tw.markup(verbose_word, **word_markup) + node = _get_node_id_with_markup(tw, config, rep) + + line = f"{word} {node}" + line_width = wcswidth(line) + + try: + # Type ignored intentionally -- possible AttributeError expected. + msg = rep.longrepr.reprcrash.message # type: ignore[union-attr] + except AttributeError: + pass + else: + if not running_on_ci(): + available_width = tw.fullwidth - line_width + msg = _format_trimmed(" - {}", msg, available_width) + else: + msg = f" - {msg}" + if msg is not None: + line += msg + + return line + + +def _folded_skips( + startpath: Path, + skipped: Sequence[CollectReport], +) -> List[Tuple[int, str, Optional[int], str]]: + d: Dict[Tuple[str, Optional[int], str], List[CollectReport]] = {} + for event in skipped: + assert event.longrepr is not None + assert isinstance(event.longrepr, tuple), (event, event.longrepr) + assert len(event.longrepr) == 3, (event, event.longrepr) + fspath, lineno, reason = event.longrepr + # For consistency, report all fspaths in relative form. + fspath = bestrelpath(startpath, Path(fspath)) + keywords = getattr(event, "keywords", {}) + # Folding reports with global pytestmark variable. + # This is a workaround, because for now we cannot identify the scope of a skip marker + # TODO: Revisit after marks scope would be fixed. + if ( + event.when == "setup" + and "skip" in keywords + and "pytestmark" not in keywords + ): + key: Tuple[str, Optional[int], str] = (fspath, None, reason) + else: + key = (fspath, lineno, reason) + d.setdefault(key, []).append(event) + values: List[Tuple[int, str, Optional[int], str]] = [] + for key, events in d.items(): + values.append((len(events), *key)) + return values + + +_color_for_type = { + "failed": "red", + "error": "red", + "warnings": "yellow", + "passed": "green", +} +_color_for_type_default = "yellow" + + +def pluralize(count: int, noun: str) -> Tuple[int, str]: + # No need to pluralize words such as `failed` or `passed`. + if noun not in ["error", "warnings", "test"]: + return count, noun + + # The `warnings` key is plural. To avoid API breakage, we keep it that way but + # set it to singular here so we can determine plurality in the same way as we do + # for `error`. + noun = noun.replace("warnings", "warning") + + return count, noun + "s" if count != 1 else noun + + +def _plugin_nameversions(plugininfo) -> List[str]: + values: List[str] = [] + for plugin, dist in plugininfo: + # Gets us name and version! + name = "{dist.project_name}-{dist.version}".format(dist=dist) + # Questionable convenience, but it keeps things short. + if name.startswith("pytest-"): + name = name[7:] + # We decided to print python package names they can have more than one plugin. + if name not in values: + values.append(name) + return values + + +def format_session_duration(seconds: float) -> str: + """Format the given seconds in a human readable manner to show in the final summary.""" + if seconds < 60: + return f"{seconds:.2f}s" + else: + dt = datetime.timedelta(seconds=int(seconds)) + return f"{seconds:.2f}s ({dt})" + + +def _get_raw_skip_reason(report: TestReport) -> str: + """Get the reason string of a skip/xfail/xpass test report. + + The string is just the part given by the user. + """ + if hasattr(report, "wasxfail"): + reason = cast(str, report.wasxfail) + if reason.startswith("reason: "): + reason = reason[len("reason: ") :] + return reason + else: + assert report.skipped + assert isinstance(report.longrepr, tuple) + _, _, reason = report.longrepr + if reason.startswith("Skipped: "): + reason = reason[len("Skipped: ") :] + elif reason == "Skipped": + reason = "" + return reason diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/threadexception.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/threadexception.py new file mode 100644 index 00000000..43341e73 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/threadexception.py @@ -0,0 +1,88 @@ +import threading +import traceback +import warnings +from types import TracebackType +from typing import Any +from typing import Callable +from typing import Generator +from typing import Optional +from typing import Type + +import pytest + + +# Copied from cpython/Lib/test/support/threading_helper.py, with modifications. +class catch_threading_exception: + """Context manager catching threading.Thread exception using + threading.excepthook. + + Storing exc_value using a custom hook can create a reference cycle. The + reference cycle is broken explicitly when the context manager exits. + + Storing thread using a custom hook can resurrect it if it is set to an + object which is being finalized. Exiting the context manager clears the + stored object. + + Usage: + with threading_helper.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + # check the thread exception: use cm.args + ... + # cm.args attribute no longer exists at this point + # (to break a reference cycle) + """ + + def __init__(self) -> None: + self.args: Optional["threading.ExceptHookArgs"] = None + self._old_hook: Optional[Callable[["threading.ExceptHookArgs"], Any]] = None + + def _hook(self, args: "threading.ExceptHookArgs") -> None: + self.args = args + + def __enter__(self) -> "catch_threading_exception": + self._old_hook = threading.excepthook + threading.excepthook = self._hook + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + assert self._old_hook is not None + threading.excepthook = self._old_hook + self._old_hook = None + del self.args + + +def thread_exception_runtest_hook() -> Generator[None, None, None]: + with catch_threading_exception() as cm: + yield + if cm.args: + thread_name = "" if cm.args.thread is None else cm.args.thread.name + msg = f"Exception in thread {thread_name}\n\n" + msg += "".join( + traceback.format_exception( + cm.args.exc_type, + cm.args.exc_value, + cm.args.exc_traceback, + ) + ) + warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg)) + + +@pytest.hookimpl(hookwrapper=True, trylast=True) +def pytest_runtest_setup() -> Generator[None, None, None]: + yield from thread_exception_runtest_hook() + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_call() -> Generator[None, None, None]: + yield from thread_exception_runtest_hook() + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_teardown() -> Generator[None, None, None]: + yield from thread_exception_runtest_hook() diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/timing.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/timing.py new file mode 100644 index 00000000..925163a5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/timing.py @@ -0,0 +1,12 @@ +"""Indirection for time functions. + +We intentionally grab some "time" functions internally to avoid tests mocking "time" to affect +pytest runtime information (issue #185). + +Fixture "mock_timing" also interacts with this module for pytest's own tests. +""" +from time import perf_counter +from time import sleep +from time import time + +__all__ = ["perf_counter", "sleep", "time"] diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/tmpdir.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/tmpdir.py new file mode 100644 index 00000000..3cc2bace --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/tmpdir.py @@ -0,0 +1,324 @@ +"""Support for providing temporary directories to test functions.""" +import dataclasses +import os +import re +import tempfile +from pathlib import Path +from shutil import rmtree +from typing import Any +from typing import Dict +from typing import Generator +from typing import Optional +from typing import TYPE_CHECKING +from typing import Union + +from _pytest.nodes import Item +from _pytest.reports import CollectReport +from _pytest.stash import StashKey + +if TYPE_CHECKING: + from typing_extensions import Literal + + RetentionType = Literal["all", "failed", "none"] + + +from _pytest.config.argparsing import Parser + +from .pathlib import LOCK_TIMEOUT +from .pathlib import make_numbered_dir +from .pathlib import make_numbered_dir_with_cleanup +from .pathlib import rm_rf +from .pathlib import cleanup_dead_symlinks +from _pytest.compat import final, get_user_id +from _pytest.config import Config +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.deprecated import check_ispytest +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch + +tmppath_result_key = StashKey[Dict[str, bool]]() + + +@final +@dataclasses.dataclass +class TempPathFactory: + """Factory for temporary directories under the common base temp directory. + + The base directory can be configured using the ``--basetemp`` option. + """ + + _given_basetemp: Optional[Path] + # pluggy TagTracerSub, not currently exposed, so Any. + _trace: Any + _basetemp: Optional[Path] + _retention_count: int + _retention_policy: "RetentionType" + + def __init__( + self, + given_basetemp: Optional[Path], + retention_count: int, + retention_policy: "RetentionType", + trace, + basetemp: Optional[Path] = None, + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + if given_basetemp is None: + self._given_basetemp = None + else: + # Use os.path.abspath() to get absolute path instead of resolve() as it + # does not work the same in all platforms (see #4427). + # Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012). + self._given_basetemp = Path(os.path.abspath(str(given_basetemp))) + self._trace = trace + self._retention_count = retention_count + self._retention_policy = retention_policy + self._basetemp = basetemp + + @classmethod + def from_config( + cls, + config: Config, + *, + _ispytest: bool = False, + ) -> "TempPathFactory": + """Create a factory according to pytest configuration. + + :meta private: + """ + check_ispytest(_ispytest) + count = int(config.getini("tmp_path_retention_count")) + if count < 0: + raise ValueError( + f"tmp_path_retention_count must be >= 0. Current input: {count}." + ) + + policy = config.getini("tmp_path_retention_policy") + if policy not in ("all", "failed", "none"): + raise ValueError( + f"tmp_path_retention_policy must be either all, failed, none. Current input: {policy}." + ) + + return cls( + given_basetemp=config.option.basetemp, + trace=config.trace.get("tmpdir"), + retention_count=count, + retention_policy=policy, + _ispytest=True, + ) + + def _ensure_relative_to_basetemp(self, basename: str) -> str: + basename = os.path.normpath(basename) + if (self.getbasetemp() / basename).resolve().parent != self.getbasetemp(): + raise ValueError(f"{basename} is not a normalized and relative path") + return basename + + def mktemp(self, basename: str, numbered: bool = True) -> Path: + """Create a new temporary directory managed by the factory. + + :param basename: + Directory base name, must be a relative path. + + :param numbered: + If ``True``, ensure the directory is unique by adding a numbered + suffix greater than any existing one: ``basename="foo-"`` and ``numbered=True`` + means that this function will create directories named ``"foo-0"``, + ``"foo-1"``, ``"foo-2"`` and so on. + + :returns: + The path to the new directory. + """ + basename = self._ensure_relative_to_basetemp(basename) + if not numbered: + p = self.getbasetemp().joinpath(basename) + p.mkdir(mode=0o700) + else: + p = make_numbered_dir(root=self.getbasetemp(), prefix=basename, mode=0o700) + self._trace("mktemp", p) + return p + + def getbasetemp(self) -> Path: + """Return the base temporary directory, creating it if needed. + + :returns: + The base temporary directory. + """ + if self._basetemp is not None: + return self._basetemp + + if self._given_basetemp is not None: + basetemp = self._given_basetemp + if basetemp.exists(): + rm_rf(basetemp) + basetemp.mkdir(mode=0o700) + basetemp = basetemp.resolve() + else: + from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT") + temproot = Path(from_env or tempfile.gettempdir()).resolve() + user = get_user() or "unknown" + # use a sub-directory in the temproot to speed-up + # make_numbered_dir() call + rootdir = temproot.joinpath(f"pytest-of-{user}") + try: + rootdir.mkdir(mode=0o700, exist_ok=True) + except OSError: + # getuser() likely returned illegal characters for the platform, use unknown back off mechanism + rootdir = temproot.joinpath("pytest-of-unknown") + rootdir.mkdir(mode=0o700, exist_ok=True) + # Because we use exist_ok=True with a predictable name, make sure + # we are the owners, to prevent any funny business (on unix, where + # temproot is usually shared). + # Also, to keep things private, fixup any world-readable temp + # rootdir's permissions. Historically 0o755 was used, so we can't + # just error out on this, at least for a while. + uid = get_user_id() + if uid is not None: + rootdir_stat = rootdir.stat() + if rootdir_stat.st_uid != uid: + raise OSError( + f"The temporary directory {rootdir} is not owned by the current user. " + "Fix this and try again." + ) + if (rootdir_stat.st_mode & 0o077) != 0: + os.chmod(rootdir, rootdir_stat.st_mode & ~0o077) + keep = self._retention_count + if self._retention_policy == "none": + keep = 0 + basetemp = make_numbered_dir_with_cleanup( + prefix="pytest-", + root=rootdir, + keep=keep, + lock_timeout=LOCK_TIMEOUT, + mode=0o700, + ) + assert basetemp is not None, basetemp + self._basetemp = basetemp + self._trace("new basetemp", basetemp) + return basetemp + + +def get_user() -> Optional[str]: + """Return the current user name, or None if getuser() does not work + in the current environment (see #1010).""" + try: + # In some exotic environments, getpass may not be importable. + import getpass + + return getpass.getuser() + except (ImportError, KeyError): + return None + + +def pytest_configure(config: Config) -> None: + """Create a TempPathFactory and attach it to the config object. + + This is to comply with existing plugins which expect the handler to be + available at pytest_configure time, but ideally should be moved entirely + to the tmp_path_factory session fixture. + """ + mp = MonkeyPatch() + config.add_cleanup(mp.undo) + _tmp_path_factory = TempPathFactory.from_config(config, _ispytest=True) + mp.setattr(config, "_tmp_path_factory", _tmp_path_factory, raising=False) + + +def pytest_addoption(parser: Parser) -> None: + parser.addini( + "tmp_path_retention_count", + help="How many sessions should we keep the `tmp_path` directories, according to `tmp_path_retention_policy`.", + default=3, + ) + + parser.addini( + "tmp_path_retention_policy", + help="Controls which directories created by the `tmp_path` fixture are kept around, based on test outcome. " + "(all/failed/none)", + default="all", + ) + + +@fixture(scope="session") +def tmp_path_factory(request: FixtureRequest) -> TempPathFactory: + """Return a :class:`pytest.TempPathFactory` instance for the test session.""" + # Set dynamically by pytest_configure() above. + return request.config._tmp_path_factory # type: ignore + + +def _mk_tmp(request: FixtureRequest, factory: TempPathFactory) -> Path: + name = request.node.name + name = re.sub(r"[\W]", "_", name) + MAXVAL = 30 + name = name[:MAXVAL] + return factory.mktemp(name, numbered=True) + + +@fixture +def tmp_path( + request: FixtureRequest, tmp_path_factory: TempPathFactory +) -> Generator[Path, None, None]: + """Return a temporary directory path object which is unique to each test + function invocation, created as a sub directory of the base temporary + directory. + + By default, a new base temporary directory is created each test session, + and old bases are removed after 3 sessions, to aid in debugging. + This behavior can be configured with :confval:`tmp_path_retention_count` and + :confval:`tmp_path_retention_policy`. + If ``--basetemp`` is used then it is cleared each session. See :ref:`base + temporary directory`. + + The returned object is a :class:`pathlib.Path` object. + """ + + path = _mk_tmp(request, tmp_path_factory) + yield path + + # Remove the tmpdir if the policy is "failed" and the test passed. + tmp_path_factory: TempPathFactory = request.session.config._tmp_path_factory # type: ignore + policy = tmp_path_factory._retention_policy + result_dict = request.node.stash[tmppath_result_key] + + if policy == "failed" and result_dict.get("call", True): + # We do a "best effort" to remove files, but it might not be possible due to some leaked resource, + # permissions, etc, in which case we ignore it. + rmtree(path, ignore_errors=True) + + del request.node.stash[tmppath_result_key] + + +def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]): + """After each session, remove base directory if all the tests passed, + the policy is "failed", and the basetemp is not specified by a user. + """ + tmp_path_factory: TempPathFactory = session.config._tmp_path_factory + basetemp = tmp_path_factory._basetemp + if basetemp is None: + return + + policy = tmp_path_factory._retention_policy + if ( + exitstatus == 0 + and policy == "failed" + and tmp_path_factory._given_basetemp is None + ): + if basetemp.is_dir(): + # We do a "best effort" to remove files, but it might not be possible due to some leaked resource, + # permissions, etc, in which case we ignore it. + rmtree(basetemp, ignore_errors=True) + + # Remove dead symlinks. + if basetemp.is_dir(): + cleanup_dead_symlinks(basetemp) + + +@hookimpl(tryfirst=True, hookwrapper=True) +def pytest_runtest_makereport(item: Item, call): + outcome = yield + result: CollectReport = outcome.get_result() + + empty: Dict[str, bool] = {} + item.stash.setdefault(tmppath_result_key, empty)[result.when] = result.passed diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/unittest.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/unittest.py new file mode 100644 index 00000000..d42a12a3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/unittest.py @@ -0,0 +1,421 @@ +"""Discover and run std-library "unittest" style tests.""" +import sys +import traceback +import types +from typing import Any +from typing import Callable +from typing import Generator +from typing import Iterable +from typing import List +from typing import Optional +from typing import Tuple +from typing import Type +from typing import TYPE_CHECKING +from typing import Union + +import _pytest._code +import pytest +from _pytest.compat import getimfunc +from _pytest.compat import is_async_function +from _pytest.config import hookimpl +from _pytest.fixtures import FixtureRequest +from _pytest.nodes import Collector +from _pytest.nodes import Item +from _pytest.outcomes import exit +from _pytest.outcomes import fail +from _pytest.outcomes import skip +from _pytest.outcomes import xfail +from _pytest.python import Class +from _pytest.python import Function +from _pytest.python import Module +from _pytest.runner import CallInfo +from _pytest.scope import Scope + +if TYPE_CHECKING: + import unittest + import twisted.trial.unittest + + _SysExcInfoType = Union[ + Tuple[Type[BaseException], BaseException, types.TracebackType], + Tuple[None, None, None], + ] + + +def pytest_pycollect_makeitem( + collector: Union[Module, Class], name: str, obj: object +) -> Optional["UnitTestCase"]: + # Has unittest been imported and is obj a subclass of its TestCase? + try: + ut = sys.modules["unittest"] + # Type ignored because `ut` is an opaque module. + if not issubclass(obj, ut.TestCase): # type: ignore + return None + except Exception: + return None + # Yes, so let's collect it. + item: UnitTestCase = UnitTestCase.from_parent(collector, name=name, obj=obj) + return item + + +class UnitTestCase(Class): + # Marker for fixturemanger.getfixtureinfo() + # to declare that our children do not support funcargs. + nofuncargs = True + + def collect(self) -> Iterable[Union[Item, Collector]]: + from unittest import TestLoader + + cls = self.obj + if not getattr(cls, "__test__", True): + return + + skipped = _is_skipped(cls) + if not skipped: + self._inject_setup_teardown_fixtures(cls) + self._inject_setup_class_fixture() + + self.session._fixturemanager.parsefactories(self, unittest=True) + loader = TestLoader() + foundsomething = False + for name in loader.getTestCaseNames(self.obj): + x = getattr(self.obj, name) + if not getattr(x, "__test__", True): + continue + funcobj = getimfunc(x) + yield TestCaseFunction.from_parent(self, name=name, callobj=funcobj) + foundsomething = True + + if not foundsomething: + runtest = getattr(self.obj, "runTest", None) + if runtest is not None: + ut = sys.modules.get("twisted.trial.unittest", None) + # Type ignored because `ut` is an opaque module. + if ut is None or runtest != ut.TestCase.runTest: # type: ignore + yield TestCaseFunction.from_parent(self, name="runTest") + + def _inject_setup_teardown_fixtures(self, cls: type) -> None: + """Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding + teardown functions (#517).""" + class_fixture = _make_xunit_fixture( + cls, + "setUpClass", + "tearDownClass", + "doClassCleanups", + scope=Scope.Class, + pass_self=False, + ) + if class_fixture: + cls.__pytest_class_setup = class_fixture # type: ignore[attr-defined] + + method_fixture = _make_xunit_fixture( + cls, + "setup_method", + "teardown_method", + None, + scope=Scope.Function, + pass_self=True, + ) + if method_fixture: + cls.__pytest_method_setup = method_fixture # type: ignore[attr-defined] + + +def _make_xunit_fixture( + obj: type, + setup_name: str, + teardown_name: str, + cleanup_name: Optional[str], + scope: Scope, + pass_self: bool, +): + setup = getattr(obj, setup_name, None) + teardown = getattr(obj, teardown_name, None) + if setup is None and teardown is None: + return None + + if cleanup_name: + cleanup = getattr(obj, cleanup_name, lambda *args: None) + else: + + def cleanup(*args): + pass + + @pytest.fixture( + scope=scope.value, + autouse=True, + # Use a unique name to speed up lookup. + name=f"_unittest_{setup_name}_fixture_{obj.__qualname__}", + ) + def fixture(self, request: FixtureRequest) -> Generator[None, None, None]: + if _is_skipped(self): + reason = self.__unittest_skip_why__ + raise pytest.skip.Exception(reason, _use_item_location=True) + if setup is not None: + try: + if pass_self: + setup(self, request.function) + else: + setup() + # unittest does not call the cleanup function for every BaseException, so we + # follow this here. + except Exception: + if pass_self: + cleanup(self) + else: + cleanup() + + raise + yield + try: + if teardown is not None: + if pass_self: + teardown(self, request.function) + else: + teardown() + finally: + if pass_self: + cleanup(self) + else: + cleanup() + + return fixture + + +class TestCaseFunction(Function): + nofuncargs = True + _excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None + _testcase: Optional["unittest.TestCase"] = None + + def _getobj(self): + assert self.parent is not None + # Unlike a regular Function in a Class, where `item.obj` returns + # a *bound* method (attached to an instance), TestCaseFunction's + # `obj` returns an *unbound* method (not attached to an instance). + # This inconsistency is probably not desirable, but needs some + # consideration before changing. + return getattr(self.parent.obj, self.originalname) # type: ignore[attr-defined] + + def setup(self) -> None: + # A bound method to be called during teardown() if set (see 'runtest()'). + self._explicit_tearDown: Optional[Callable[[], None]] = None + assert self.parent is not None + self._testcase = self.parent.obj(self.name) # type: ignore[attr-defined] + self._obj = getattr(self._testcase, self.name) + if hasattr(self, "_request"): + self._request._fillfixtures() + + def teardown(self) -> None: + if self._explicit_tearDown is not None: + self._explicit_tearDown() + self._explicit_tearDown = None + self._testcase = None + self._obj = None + + def startTest(self, testcase: "unittest.TestCase") -> None: + pass + + def _addexcinfo(self, rawexcinfo: "_SysExcInfoType") -> None: + # Unwrap potential exception info (see twisted trial support below). + rawexcinfo = getattr(rawexcinfo, "_rawexcinfo", rawexcinfo) + try: + excinfo = _pytest._code.ExceptionInfo[BaseException].from_exc_info(rawexcinfo) # type: ignore[arg-type] + # Invoke the attributes to trigger storing the traceback + # trial causes some issue there. + excinfo.value + excinfo.traceback + except TypeError: + try: + try: + values = traceback.format_exception(*rawexcinfo) + values.insert( + 0, + "NOTE: Incompatible Exception Representation, " + "displaying natively:\n\n", + ) + fail("".join(values), pytrace=False) + except (fail.Exception, KeyboardInterrupt): + raise + except BaseException: + fail( + "ERROR: Unknown Incompatible Exception " + "representation:\n%r" % (rawexcinfo,), + pytrace=False, + ) + except KeyboardInterrupt: + raise + except fail.Exception: + excinfo = _pytest._code.ExceptionInfo.from_current() + self.__dict__.setdefault("_excinfo", []).append(excinfo) + + def addError( + self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + ) -> None: + try: + if isinstance(rawexcinfo[1], exit.Exception): + exit(rawexcinfo[1].msg) + except TypeError: + pass + self._addexcinfo(rawexcinfo) + + def addFailure( + self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + ) -> None: + self._addexcinfo(rawexcinfo) + + def addSkip(self, testcase: "unittest.TestCase", reason: str) -> None: + try: + raise pytest.skip.Exception(reason, _use_item_location=True) + except skip.Exception: + self._addexcinfo(sys.exc_info()) + + def addExpectedFailure( + self, + testcase: "unittest.TestCase", + rawexcinfo: "_SysExcInfoType", + reason: str = "", + ) -> None: + try: + xfail(str(reason)) + except xfail.Exception: + self._addexcinfo(sys.exc_info()) + + def addUnexpectedSuccess( + self, + testcase: "unittest.TestCase", + reason: Optional["twisted.trial.unittest.Todo"] = None, + ) -> None: + msg = "Unexpected success" + if reason: + msg += f": {reason.reason}" + # Preserve unittest behaviour - fail the test. Explicitly not an XPASS. + try: + fail(msg, pytrace=False) + except fail.Exception: + self._addexcinfo(sys.exc_info()) + + def addSuccess(self, testcase: "unittest.TestCase") -> None: + pass + + def stopTest(self, testcase: "unittest.TestCase") -> None: + pass + + def addDuration(self, testcase: "unittest.TestCase", elapsed: float) -> None: + pass + + def runtest(self) -> None: + from _pytest.debugging import maybe_wrap_pytest_function_for_tracing + + assert self._testcase is not None + + maybe_wrap_pytest_function_for_tracing(self) + + # Let the unittest framework handle async functions. + if is_async_function(self.obj): + # Type ignored because self acts as the TestResult, but is not actually one. + self._testcase(result=self) # type: ignore[arg-type] + else: + # When --pdb is given, we want to postpone calling tearDown() otherwise + # when entering the pdb prompt, tearDown() would have probably cleaned up + # instance variables, which makes it difficult to debug. + # Arguably we could always postpone tearDown(), but this changes the moment where the + # TestCase instance interacts with the results object, so better to only do it + # when absolutely needed. + # We need to consider if the test itself is skipped, or the whole class. + assert isinstance(self.parent, UnitTestCase) + skipped = _is_skipped(self.obj) or _is_skipped(self.parent.obj) + if self.config.getoption("usepdb") and not skipped: + self._explicit_tearDown = self._testcase.tearDown + setattr(self._testcase, "tearDown", lambda *args: None) + + # We need to update the actual bound method with self.obj, because + # wrap_pytest_function_for_tracing replaces self.obj by a wrapper. + setattr(self._testcase, self.name, self.obj) + try: + self._testcase(result=self) # type: ignore[arg-type] + finally: + delattr(self._testcase, self.name) + + def _traceback_filter( + self, excinfo: _pytest._code.ExceptionInfo[BaseException] + ) -> _pytest._code.Traceback: + traceback = super()._traceback_filter(excinfo) + ntraceback = traceback.filter( + lambda x: not x.frame.f_globals.get("__unittest"), + ) + if not ntraceback: + ntraceback = traceback + return ntraceback + + +@hookimpl(tryfirst=True) +def pytest_runtest_makereport(item: Item, call: CallInfo[None]) -> None: + if isinstance(item, TestCaseFunction): + if item._excinfo: + call.excinfo = item._excinfo.pop(0) + try: + del call.result + except AttributeError: + pass + + # Convert unittest.SkipTest to pytest.skip. + # This is actually only needed for nose, which reuses unittest.SkipTest for + # its own nose.SkipTest. For unittest TestCases, SkipTest is already + # handled internally, and doesn't reach here. + unittest = sys.modules.get("unittest") + if ( + unittest + and call.excinfo + and isinstance(call.excinfo.value, unittest.SkipTest) # type: ignore[attr-defined] + ): + excinfo = call.excinfo + call2 = CallInfo[None].from_call( + lambda: pytest.skip(str(excinfo.value)), call.when + ) + call.excinfo = call2.excinfo + + +# Twisted trial support. + + +@hookimpl(hookwrapper=True) +def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: + if isinstance(item, TestCaseFunction) and "twisted.trial.unittest" in sys.modules: + ut: Any = sys.modules["twisted.python.failure"] + Failure__init__ = ut.Failure.__init__ + check_testcase_implements_trial_reporter() + + def excstore( + self, exc_value=None, exc_type=None, exc_tb=None, captureVars=None + ): + if exc_value is None: + self._rawexcinfo = sys.exc_info() + else: + if exc_type is None: + exc_type = type(exc_value) + self._rawexcinfo = (exc_type, exc_value, exc_tb) + try: + Failure__init__( + self, exc_value, exc_type, exc_tb, captureVars=captureVars + ) + except TypeError: + Failure__init__(self, exc_value, exc_type, exc_tb) + + ut.Failure.__init__ = excstore + yield + ut.Failure.__init__ = Failure__init__ + else: + yield + + +def check_testcase_implements_trial_reporter(done: List[int] = []) -> None: + if done: + return + from zope.interface import classImplements + from twisted.trial.itrial import IReporter + + classImplements(TestCaseFunction, IReporter) + done.append(1) + + +def _is_skipped(obj) -> bool: + """Return True if the given object has been marked with @unittest.skip.""" + return bool(getattr(obj, "__unittest_skip__", False)) diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/unraisableexception.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/unraisableexception.py new file mode 100644 index 00000000..fcb5d823 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/unraisableexception.py @@ -0,0 +1,93 @@ +import sys +import traceback +import warnings +from types import TracebackType +from typing import Any +from typing import Callable +from typing import Generator +from typing import Optional +from typing import Type + +import pytest + + +# Copied from cpython/Lib/test/support/__init__.py, with modifications. +class catch_unraisable_exception: + """Context manager catching unraisable exception using sys.unraisablehook. + + Storing the exception value (cm.unraisable.exc_value) creates a reference + cycle. The reference cycle is broken explicitly when the context manager + exits. + + Storing the object (cm.unraisable.object) can resurrect it if it is set to + an object which is being finalized. Exiting the context manager clears the + stored object. + + Usage: + with catch_unraisable_exception() as cm: + # code creating an "unraisable exception" + ... + # check the unraisable exception: use cm.unraisable + ... + # cm.unraisable attribute no longer exists at this point + # (to break a reference cycle) + """ + + def __init__(self) -> None: + self.unraisable: Optional["sys.UnraisableHookArgs"] = None + self._old_hook: Optional[Callable[["sys.UnraisableHookArgs"], Any]] = None + + def _hook(self, unraisable: "sys.UnraisableHookArgs") -> None: + # Storing unraisable.object can resurrect an object which is being + # finalized. Storing unraisable.exc_value creates a reference cycle. + self.unraisable = unraisable + + def __enter__(self) -> "catch_unraisable_exception": + self._old_hook = sys.unraisablehook + sys.unraisablehook = self._hook + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + assert self._old_hook is not None + sys.unraisablehook = self._old_hook + self._old_hook = None + del self.unraisable + + +def unraisable_exception_runtest_hook() -> Generator[None, None, None]: + with catch_unraisable_exception() as cm: + yield + if cm.unraisable: + if cm.unraisable.err_msg is not None: + err_msg = cm.unraisable.err_msg + else: + err_msg = "Exception ignored in" + msg = f"{err_msg}: {cm.unraisable.object!r}\n\n" + msg += "".join( + traceback.format_exception( + cm.unraisable.exc_type, + cm.unraisable.exc_value, + cm.unraisable.exc_traceback, + ) + ) + warnings.warn(pytest.PytestUnraisableExceptionWarning(msg)) + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_setup() -> Generator[None, None, None]: + yield from unraisable_exception_runtest_hook() + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_call() -> Generator[None, None, None]: + yield from unraisable_exception_runtest_hook() + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_teardown() -> Generator[None, None, None]: + yield from unraisable_exception_runtest_hook() diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/warning_types.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/warning_types.py new file mode 100644 index 00000000..bd5f4187 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/warning_types.py @@ -0,0 +1,170 @@ +import dataclasses +import inspect +import warnings +from types import FunctionType +from typing import Any +from typing import Generic +from typing import Type +from typing import TypeVar + +from _pytest.compat import final + + +class PytestWarning(UserWarning): + """Base class for all warnings emitted by pytest.""" + + __module__ = "pytest" + + +@final +class PytestAssertRewriteWarning(PytestWarning): + """Warning emitted by the pytest assert rewrite module.""" + + __module__ = "pytest" + + +@final +class PytestCacheWarning(PytestWarning): + """Warning emitted by the cache plugin in various situations.""" + + __module__ = "pytest" + + +@final +class PytestConfigWarning(PytestWarning): + """Warning emitted for configuration issues.""" + + __module__ = "pytest" + + +@final +class PytestCollectionWarning(PytestWarning): + """Warning emitted when pytest is not able to collect a file or symbol in a module.""" + + __module__ = "pytest" + + +class PytestDeprecationWarning(PytestWarning, DeprecationWarning): + """Warning class for features that will be removed in a future version.""" + + __module__ = "pytest" + + +class PytestRemovedIn8Warning(PytestDeprecationWarning): + """Warning class for features that will be removed in pytest 8.""" + + __module__ = "pytest" + + +class PytestReturnNotNoneWarning(PytestRemovedIn8Warning): + """Warning emitted when a test function is returning value other than None.""" + + __module__ = "pytest" + + +@final +class PytestExperimentalApiWarning(PytestWarning, FutureWarning): + """Warning category used to denote experiments in pytest. + + Use sparingly as the API might change or even be removed completely in a + future version. + """ + + __module__ = "pytest" + + @classmethod + def simple(cls, apiname: str) -> "PytestExperimentalApiWarning": + return cls( + "{apiname} is an experimental api that may change over time".format( + apiname=apiname + ) + ) + + +@final +class PytestUnhandledCoroutineWarning(PytestReturnNotNoneWarning): + """Warning emitted for an unhandled coroutine. + + A coroutine was encountered when collecting test functions, but was not + handled by any async-aware plugin. + Coroutine test functions are not natively supported. + """ + + __module__ = "pytest" + + +@final +class PytestUnknownMarkWarning(PytestWarning): + """Warning emitted on use of unknown markers. + + See :ref:`mark` for details. + """ + + __module__ = "pytest" + + +@final +class PytestUnraisableExceptionWarning(PytestWarning): + """An unraisable exception was reported. + + Unraisable exceptions are exceptions raised in :meth:`__del__ ` + implementations and similar situations when the exception cannot be raised + as normal. + """ + + __module__ = "pytest" + + +@final +class PytestUnhandledThreadExceptionWarning(PytestWarning): + """An unhandled exception occurred in a :class:`~threading.Thread`. + + Such exceptions don't propagate normally. + """ + + __module__ = "pytest" + + +_W = TypeVar("_W", bound=PytestWarning) + + +@final +@dataclasses.dataclass +class UnformattedWarning(Generic[_W]): + """A warning meant to be formatted during runtime. + + This is used to hold warnings that need to format their message at runtime, + as opposed to a direct message. + """ + + category: Type["_W"] + template: str + + def format(self, **kwargs: Any) -> _W: + """Return an instance of the warning category, formatted with given kwargs.""" + return self.category(self.template.format(**kwargs)) + + +def warn_explicit_for(method: FunctionType, message: PytestWarning) -> None: + """ + Issue the warning :param:`message` for the definition of the given :param:`method` + + this helps to log warnings for functions defined prior to finding an issue with them + (like hook wrappers being marked in a legacy mechanism) + """ + lineno = method.__code__.co_firstlineno + filename = inspect.getfile(method) + module = method.__module__ + mod_globals = method.__globals__ + try: + warnings.warn_explicit( + message, + type(message), + filename=filename, + module=module, + registry=mod_globals.setdefault("__warningregistry__", {}), + lineno=lineno, + ) + except Warning as w: + # If warnings are errors (e.g. -Werror), location information gets lost, so we add it to the message. + raise type(w)(f"{w}\n at {filename}:{lineno}") from None diff --git a/dbdpy-env/lib/python3.9/site-packages/_pytest/warnings.py b/dbdpy-env/lib/python3.9/site-packages/_pytest/warnings.py new file mode 100644 index 00000000..4aaa9445 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/_pytest/warnings.py @@ -0,0 +1,148 @@ +import sys +import warnings +from contextlib import contextmanager +from typing import Generator +from typing import Optional +from typing import TYPE_CHECKING + +import pytest +from _pytest.config import apply_warning_filters +from _pytest.config import Config +from _pytest.config import parse_warning_filter +from _pytest.main import Session +from _pytest.nodes import Item +from _pytest.terminal import TerminalReporter + +if TYPE_CHECKING: + from typing_extensions import Literal + + +def pytest_configure(config: Config) -> None: + config.addinivalue_line( + "markers", + "filterwarnings(warning): add a warning filter to the given test. " + "see https://docs.pytest.org/en/stable/how-to/capture-warnings.html#pytest-mark-filterwarnings ", + ) + + +@contextmanager +def catch_warnings_for_item( + config: Config, + ihook, + when: "Literal['config', 'collect', 'runtest']", + item: Optional[Item], +) -> Generator[None, None, None]: + """Context manager that catches warnings generated in the contained execution block. + + ``item`` can be None if we are not in the context of an item execution. + + Each warning captured triggers the ``pytest_warning_recorded`` hook. + """ + config_filters = config.getini("filterwarnings") + cmdline_filters = config.known_args_namespace.pythonwarnings or [] + with warnings.catch_warnings(record=True) as log: + # mypy can't infer that record=True means log is not None; help it. + assert log is not None + + if not sys.warnoptions: + # If user is not explicitly configuring warning filters, show deprecation warnings by default (#2908). + warnings.filterwarnings("always", category=DeprecationWarning) + warnings.filterwarnings("always", category=PendingDeprecationWarning) + + apply_warning_filters(config_filters, cmdline_filters) + + # apply filters from "filterwarnings" marks + nodeid = "" if item is None else item.nodeid + if item is not None: + for mark in item.iter_markers(name="filterwarnings"): + for arg in mark.args: + warnings.filterwarnings(*parse_warning_filter(arg, escape=False)) + + yield + + for warning_message in log: + ihook.pytest_warning_recorded.call_historic( + kwargs=dict( + warning_message=warning_message, + nodeid=nodeid, + when=when, + location=None, + ) + ) + + +def warning_record_to_str(warning_message: warnings.WarningMessage) -> str: + """Convert a warnings.WarningMessage to a string.""" + warn_msg = warning_message.message + msg = warnings.formatwarning( + str(warn_msg), + warning_message.category, + warning_message.filename, + warning_message.lineno, + warning_message.line, + ) + if warning_message.source is not None: + try: + import tracemalloc + except ImportError: + pass + else: + tb = tracemalloc.get_object_traceback(warning_message.source) + if tb is not None: + formatted_tb = "\n".join(tb.format()) + # Use a leading new line to better separate the (large) output + # from the traceback to the previous warning text. + msg += f"\nObject allocated at:\n{formatted_tb}" + else: + # No need for a leading new line. + url = "https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings" + msg += "Enable tracemalloc to get traceback where the object was allocated.\n" + msg += f"See {url} for more info." + return msg + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: + with catch_warnings_for_item( + config=item.config, ihook=item.ihook, when="runtest", item=item + ): + yield + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_collection(session: Session) -> Generator[None, None, None]: + config = session.config + with catch_warnings_for_item( + config=config, ihook=config.hook, when="collect", item=None + ): + yield + + +@pytest.hookimpl(hookwrapper=True) +def pytest_terminal_summary( + terminalreporter: TerminalReporter, +) -> Generator[None, None, None]: + config = terminalreporter.config + with catch_warnings_for_item( + config=config, ihook=config.hook, when="config", item=None + ): + yield + + +@pytest.hookimpl(hookwrapper=True) +def pytest_sessionfinish(session: Session) -> Generator[None, None, None]: + config = session.config + with catch_warnings_for_item( + config=config, ihook=config.hook, when="config", item=None + ): + yield + + +@pytest.hookimpl(hookwrapper=True) +def pytest_load_initial_conftests( + early_config: "Config", +) -> Generator[None, None, None]: + with catch_warnings_for_item( + config=early_config, ihook=early_config.hook, when="config", item=None + ): + yield diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/METADATA new file mode 100644 index 00000000..cfa850ae --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/METADATA @@ -0,0 +1,1871 @@ +Metadata-Version: 2.1 +Name: black +Version: 23.12.1 +Summary: The uncompromising code formatter. +Project-URL: Changelog, https://github.com/psf/black/blob/main/CHANGES.md +Project-URL: Homepage, https://github.com/psf/black +Author-email: Łukasz Langa +License: MIT +License-File: AUTHORS.md +License-File: LICENSE +Keywords: automation,autopep8,formatter,gofmt,pyfmt,rustfmt,yapf +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance +Requires-Python: >=3.8 +Requires-Dist: click>=8.0.0 +Requires-Dist: mypy-extensions>=0.4.3 +Requires-Dist: packaging>=22.0 +Requires-Dist: pathspec>=0.9.0 +Requires-Dist: platformdirs>=2 +Requires-Dist: tomli>=1.1.0; python_version < '3.11' +Requires-Dist: typing-extensions>=4.0.1; python_version < '3.11' +Provides-Extra: colorama +Requires-Dist: colorama>=0.4.3; extra == 'colorama' +Provides-Extra: d +Requires-Dist: aiohttp!=3.9.0,>=3.7.4; (sys_platform == 'win32' and implementation_name == 'pypy') and extra == 'd' +Requires-Dist: aiohttp>=3.7.4; (sys_platform != 'win32' or implementation_name != 'pypy') and extra == 'd' +Provides-Extra: jupyter +Requires-Dist: ipython>=7.8.0; extra == 'jupyter' +Requires-Dist: tokenize-rt>=3.2.0; extra == 'jupyter' +Provides-Extra: uvloop +Requires-Dist: uvloop>=0.15.2; extra == 'uvloop' +Description-Content-Type: text/markdown + +[![Black Logo](https://raw.githubusercontent.com/psf/black/main/docs/_static/logo2-readme.png)](https://black.readthedocs.io/en/stable/) + +

The Uncompromising Code Formatter

+ +

+Actions Status +Documentation Status +Coverage Status +License: MIT +PyPI +Downloads +conda-forge +Code style: black +

+ +> “Any color you like.” + +_Black_ is the uncompromising Python code formatter. By using it, you agree to cede +control over minutiae of hand-formatting. In return, _Black_ gives you speed, +determinism, and freedom from `pycodestyle` nagging about formatting. You will save time +and mental energy for more important matters. + +Blackened code looks the same regardless of the project you're reading. Formatting +becomes transparent after a while and you can focus on the content instead. + +_Black_ makes code review faster by producing the smallest diffs possible. + +Try it out now using the [Black Playground](https://black.vercel.app). Watch the +[PyCon 2019 talk](https://youtu.be/esZLCuWs_2Y) to learn more. + +--- + +**[Read the documentation on ReadTheDocs!](https://black.readthedocs.io/en/stable)** + +--- + +## Installation and usage + +### Installation + +_Black_ can be installed by running `pip install black`. It requires Python 3.8+ to run. +If you want to format Jupyter Notebooks, install with `pip install "black[jupyter]"`. + +If you can't wait for the latest _hotness_ and want to install from GitHub, use: + +`pip install git+https://github.com/psf/black` + +### Usage + +To get started right away with sensible defaults: + +```sh +black {source_file_or_directory} +``` + +You can run _Black_ as a package if running it as a script doesn't work: + +```sh +python -m black {source_file_or_directory} +``` + +Further information can be found in our docs: + +- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html) + +_Black_ is already [successfully used](https://github.com/psf/black#used-by) by many +projects, small and big. _Black_ has a comprehensive test suite, with efficient parallel +tests, and our own auto formatting and parallel Continuous Integration runner. Now that +we have become stable, you should not expect large formatting changes in the future. +Stylistic changes will mostly be responses to bug reports and support for new Python +syntax. For more information please refer to +[The Black Code Style](https://black.readthedocs.io/en/stable/the_black_code_style/index.html). + +Also, as a safety measure which slows down processing, _Black_ will check that the +reformatted code still produces a valid AST that is effectively equivalent to the +original (see the +[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#ast-before-and-after-formatting) +section for details). If you're feeling confident, use `--fast`. + +## The _Black_ code style + +_Black_ is a PEP 8 compliant opinionated formatter. _Black_ reformats entire files in +place. Style configuration options are deliberately limited and rarely added. It doesn't +take previous formatting into account (see +[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism) +for exceptions). + +Our documentation covers the current _Black_ code style, but planned changes to it are +also documented. They're both worth taking a look at: + +- [The _Black_ Code Style: Current style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html) +- [The _Black_ Code Style: Future style](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html) + +Changes to the _Black_ code style are bound by the Stability Policy: + +- [The _Black_ Code Style: Stability Policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy) + +Please refer to this document before submitting an issue. What seems like a bug might be +intended behaviour. + +### Pragmatism + +Early versions of _Black_ used to be absolutist in some respects. They took after its +initial author. This was fine at the time as it made the implementation simpler and +there were not many users anyway. Not many edge cases were reported. As a mature tool, +_Black_ does make some exceptions to rules it otherwise holds. + +- [The _Black_ code style: Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism) + +Please refer to this document before submitting an issue just like with the document +above. What seems like a bug might be intended behaviour. + +## Configuration + +_Black_ is able to read project-specific default values for its command line options +from a `pyproject.toml` file. This is especially useful for specifying custom +`--include` and `--exclude`/`--force-exclude`/`--extend-exclude` patterns for your +project. + +You can find more details in our documentation: + +- [The basics: Configuration via a file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file) + +And if you're looking for more general configuration documentation: + +- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html) + +**Pro-tip**: If you're asking yourself "Do I need to configure anything?" the answer is +"No". _Black_ is all about sensible defaults. Applying those defaults will have your +code in compliance with many other _Black_ formatted projects. + +## Used by + +The following notable open-source projects trust _Black_ with enforcing a consistent +code style: pytest, tox, Pyramid, Django, Django Channels, Hypothesis, attrs, +SQLAlchemy, Poetry, PyPA applications (Warehouse, Bandersnatch, Pipenv, virtualenv), +pandas, Pillow, Twisted, LocalStack, every Datadog Agent Integration, Home Assistant, +Zulip, Kedro, OpenOA, FLORIS, ORBIT, WOMBAT, and many more. + +The following organizations use _Black_: Facebook, Dropbox, KeepTruckin, Lyft, Mozilla, +Quora, Duolingo, QuantumBlack, Tesla, Archer Aviation. + +Are we missing anyone? Let us know. + +## Testimonials + +**Mike Bayer**, [author of `SQLAlchemy`](https://www.sqlalchemy.org/): + +> I can't think of any single tool in my entire programming career that has given me a +> bigger productivity increase by its introduction. I can now do refactorings in about +> 1% of the keystrokes that it would have taken me previously when we had no way for +> code to format itself. + +**Dusty Phillips**, +[writer](https://smile.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=dusty+phillips): + +> _Black_ is opinionated so you don't have to be. + +**Hynek Schlawack**, [creator of `attrs`](https://www.attrs.org/), core developer of +Twisted and CPython: + +> An auto-formatter that doesn't suck is all I want for Xmas! + +**Carl Meyer**, [Django](https://www.djangoproject.com/) core developer: + +> At least the name is good. + +**Kenneth Reitz**, creator of [`requests`](https://requests.readthedocs.io/en/latest/) +and [`pipenv`](https://readthedocs.org/projects/pipenv/): + +> This vastly improves the formatting of our code. Thanks a ton! + +## Show your style + +Use the badge in your project's README.md: + +```md +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +``` + +Using the badge in README.rst: + +``` +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black +``` + +Looks like this: +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +## License + +MIT + +## Contributing + +Welcome! Happy to see you willing to make the project better. You can get started by +reading this: + +- [Contributing: The basics](https://black.readthedocs.io/en/latest/contributing/the_basics.html) + +You can also take a look at the rest of the contributing docs or talk with the +developers: + +- [Contributing documentation](https://black.readthedocs.io/en/latest/contributing/index.html) +- [Chat on Discord](https://discord.gg/RtVdv86PrH) + +## Change log + +The log has become rather long. It moved to its own file. + +See [CHANGES](https://black.readthedocs.io/en/latest/change_log.html). + +## Authors + +The author list is quite long nowadays, so it lives in its own file. + +See [AUTHORS.md](./AUTHORS.md) + +## Code of Conduct + +Everyone participating in the _Black_ project, and in particular in the issue tracker, +pull requests, and social media activity, is expected to treat other people with respect +and more generally to follow the guidelines articulated in the +[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/). + +At the same time, humor is encouraged. In fact, basic familiarity with Monty Python's +Flying Circus is expected. We are not savages. + +And if you _really_ need to slap somebody, do it with a fish while dancing. +# Change Log + +## 23.12.1 + +### Packaging + +- Fixed a bug that included dependencies from the `d` extra by default (#4108) + +## 23.12.0 + +### Highlights + +It's almost 2024, which means it's time for a new edition of _Black_'s stable style! +Together with this release, we'll put out an alpha release 24.1a1 showcasing the draft +2024 stable style, which we'll finalize in the January release. Please try it out and +[share your feedback](https://github.com/psf/black/issues/4042). + +This release (23.12.0) will still produce the 2023 style. Most but not all of the +changes in `--preview` mode will be in the 2024 stable style. + +### Stable style + +- Fix bug where `# fmt: off` automatically dedents when used with the `--line-ranges` + option, even when it is not within the specified line range. (#4084) +- Fix feature detection for parenthesized context managers (#4104) + +### Preview style + +- Prefer more equal signs before a break when splitting chained assignments (#4010) +- Standalone form feed characters at the module level are no longer removed (#4021) +- Additional cases of immediately nested tuples, lists, and dictionaries are now + indented less (#4012) +- Allow empty lines at the beginning of all blocks, except immediately before a + docstring (#4060) +- Fix crash in preview mode when using a short `--line-length` (#4086) +- Keep suites consisting of only an ellipsis on their own lines if they are not + functions or class definitions (#4066) (#4103) + +### Configuration + +- `--line-ranges` now skips _Black_'s internal stability check in `--safe` mode. This + avoids a crash on rare inputs that have many unformatted same-content lines. (#4034) + +### Packaging + +- Upgrade to mypy 1.7.1 (#4049) (#4069) +- Faster compiled wheels are now available for CPython 3.12 (#4070) + +### Integrations + +- Enable 3.12 CI (#4035) +- Build docker images in parallel (#4054) +- Build docker images with 3.12 (#4055) + +## 23.11.0 + +### Highlights + +- Support formatting ranges of lines with the new `--line-ranges` command-line option + (#4020) + +### Stable style + +- Fix crash on formatting bytes strings that look like docstrings (#4003) +- Fix crash when whitespace followed a backslash before newline in a docstring (#4008) +- Fix standalone comments inside complex blocks crashing Black (#4016) +- Fix crash on formatting code like `await (a ** b)` (#3994) +- No longer treat leading f-strings as docstrings. This matches Python's behaviour and + fixes a crash (#4019) + +### Preview style + +- Multiline dicts and lists that are the sole argument to a function are now indented + less (#3964) +- Multiline unpacked dicts and lists as the sole argument to a function are now also + indented less (#3992) +- In f-string debug expressions, quote types that are visible in the final string are + now preserved (#4005) +- Fix a bug where long `case` blocks were not split into multiple lines. Also enable + general trailing comma rules on `case` blocks (#4024) +- Keep requiring two empty lines between module-level docstring and first function or + class definition (#4028) +- Add support for single-line format skip with other comments on the same line (#3959) + +### Configuration + +- Consistently apply force exclusion logic before resolving symlinks (#4015) +- Fix a bug in the matching of absolute path names in `--include` (#3976) + +### Performance + +- Fix mypyc builds on arm64 on macOS (#4017) + +### Integrations + +- Black's pre-commit integration will now run only on git hooks appropriate for a code + formatter (#3940) + +## 23.10.1 + +### Highlights + +- Maintenance release to get a fix out for GitHub Action edge case (#3957) + +### Preview style + +- Fix merging implicit multiline strings that have inline comments (#3956) +- Allow empty first line after block open before a comment or compound statement (#3967) + +### Packaging + +- Change Dockerfile to hatch + compile black (#3965) + +### Integrations + +- The summary output for GitHub workflows is now suppressible using the `summary` + parameter. (#3958) +- Fix the action failing when Black check doesn't pass (#3957) + +### Documentation + +- It is known Windows documentation CI is broken + https://github.com/psf/black/issues/3968 + +## 23.10.0 + +### Stable style + +- Fix comments getting removed from inside parenthesized strings (#3909) + +### Preview style + +- Fix long lines with power operators getting split before the line length (#3942) +- Long type hints are now wrapped in parentheses and properly indented when split across + multiple lines (#3899) +- Magic trailing commas are now respected in return types. (#3916) +- Require one empty line after module-level docstrings. (#3932) +- Treat raw triple-quoted strings as docstrings (#3947) + +### Configuration + +- Fix cache versioning logic when `BLACK_CACHE_DIR` is set (#3937) + +### Parser + +- Fix bug where attributes named `type` were not accepted inside `match` statements + (#3950) +- Add support for PEP 695 type aliases containing lambdas and other unusual expressions + (#3949) + +### Output + +- Black no longer attempts to provide special errors for attempting to format Python 2 + code (#3933) +- Black will more consistently print stacktraces on internal errors in verbose mode + (#3938) + +### Integrations + +- The action output displayed in the job summary is now wrapped in Markdown (#3914) + +## 23.9.1 + +Due to various issues, the previous release (23.9.0) did not include compiled mypyc +wheels, which make Black significantly faster. These issues have now been fixed, and +this release should come with compiled wheels once again. + +There will be no wheels for Python 3.12 due to a bug in mypyc. We will provide 3.12 +wheels in a future release as soon as the mypyc bug is fixed. + +### Packaging + +- Upgrade to mypy 1.5.1 (#3864) + +### Performance + +- Store raw tuples instead of NamedTuples in Black's cache, improving performance and + decreasing the size of the cache (#3877) + +## 23.9.0 + +### Preview style + +- More concise formatting for dummy implementations (#3796) +- In stub files, add a blank line between a statement with a body (e.g an + `if sys.version_info > (3, x):`) and a function definition on the same level (#3862) +- Fix a bug whereby spaces were removed from walrus operators within subscript(#3823) + +### Configuration + +- Black now applies exclusion and ignore logic before resolving symlinks (#3846) + +### Performance + +- Avoid importing `IPython` if notebook cells do not contain magics (#3782) +- Improve caching by comparing file hashes as fallback for mtime and size (#3821) + +### _Blackd_ + +- Fix an issue in `blackd` with single character input (#3558) + +### Integrations + +- Black now has an + [official pre-commit mirror](https://github.com/psf/black-pre-commit-mirror). Swapping + `https://github.com/psf/black` to `https://github.com/psf/black-pre-commit-mirror` in + your `.pre-commit-config.yaml` will make Black about 2x faster (#3828) +- The `.black.env` folder specified by `ENV_PATH` will now be removed on the completion + of the GitHub Action (#3759) + +## 23.7.0 + +### Highlights + +- Runtime support for Python 3.7 has been removed. Formatting 3.7 code will still be + supported until further notice (#3765) + +### Stable style + +- Fix a bug where an illegal trailing comma was added to return type annotations using + PEP 604 unions (#3735) +- Fix several bugs and crashes where comments in stub files were removed or mishandled + under some circumstances (#3745) +- Fix a crash with multi-line magic comments like `type: ignore` within parentheses + (#3740) +- Fix error in AST validation when _Black_ removes trailing whitespace in a type comment + (#3773) + +### Preview style + +- Implicitly concatenated strings used as function args are no longer wrapped inside + parentheses (#3640) +- Remove blank lines between a class definition and its docstring (#3692) + +### Configuration + +- The `--workers` argument to _Black_ can now be specified via the `BLACK_NUM_WORKERS` + environment variable (#3743) +- `.pytest_cache`, `.ruff_cache` and `.vscode` are now excluded by default (#3691) +- Fix _Black_ not honouring `pyproject.toml` settings when running `--stdin-filename` + and the `pyproject.toml` found isn't in the current working directory (#3719) +- _Black_ will now error if `exclude` and `extend-exclude` have invalid data types in + `pyproject.toml`, instead of silently doing the wrong thing (#3764) + +### Packaging + +- Upgrade mypyc from 0.991 to 1.3 (#3697) +- Remove patching of Click that mitigated errors on Python 3.6 with `LANG=C` (#3768) + +### Parser + +- Add support for the new PEP 695 syntax in Python 3.12 (#3703) + +### Performance + +- Speed up _Black_ significantly when the cache is full (#3751) +- Avoid importing `IPython` in a case where we wouldn't need it (#3748) + +### Output + +- Use aware UTC datetimes internally, avoids deprecation warning on Python 3.12 (#3728) +- Change verbose logging to exactly mirror _Black_'s logic for source discovery (#3749) + +### _Blackd_ + +- The `blackd` argument parser now shows the default values for options in their help + text (#3712) + +### Integrations + +- Black is now tested with + [`PYTHONWARNDEFAULTENCODING = 1`](https://docs.python.org/3/library/io.html#io-encoding-warning) + (#3763) +- Update GitHub Action to display black output in the job summary (#3688) + +### Documentation + +- Add a CITATION.cff file to the root of the repository, containing metadata on how to + cite this software (#3723) +- Update the _classes_ and _exceptions_ documentation in Developer reference to match + the latest code base (#3755) + +## 23.3.0 + +### Highlights + +This release fixes a longstanding confusing behavior in Black's GitHub action, where the +version of the action did not determine the version of Black being run (issue #3382). In +addition, there is a small bug fix around imports and a number of improvements to the +preview style. + +Please try out the +[preview style](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html#preview-style) +with `black --preview` and tell us your feedback. All changes in the preview style are +expected to become part of Black's stable style in January 2024. + +### Stable style + +- Import lines with `# fmt: skip` and `# fmt: off` no longer have an extra blank line + added when they are right after another import line (#3610) + +### Preview style + +- Add trailing commas to collection literals even if there's a comment after the last + entry (#3393) +- `async def`, `async for`, and `async with` statements are now formatted consistently + compared to their non-async version. (#3609) +- `with` statements that contain two context managers will be consistently wrapped in + parentheses (#3589) +- Let string splitters respect [East Asian Width](https://www.unicode.org/reports/tr11/) + (#3445) +- Now long string literals can be split after East Asian commas and periods (`、` U+3001 + IDEOGRAPHIC COMMA, `。` U+3002 IDEOGRAPHIC FULL STOP, & `,` U+FF0C FULLWIDTH COMMA) + besides before spaces (#3445) +- For stubs, enforce one blank line after a nested class with a body other than just + `...` (#3564) +- Improve handling of multiline strings by changing line split behavior (#1879) + +### Parser + +- Added support for formatting files with invalid type comments (#3594) + +### Integrations + +- Update GitHub Action to use the version of Black equivalent to action's version if + version input is not specified (#3543) +- Fix missing Python binary path in autoload script for vim (#3508) + +### Documentation + +- Document that only the most recent release is supported for security issues; + vulnerabilities should be reported through Tidelift (#3612) + +## 23.1.0 + +### Highlights + +This is the first release of 2023, and following our +[stability policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy), +it comes with a number of improvements to our stable style, including improvements to +empty line handling, removal of redundant parentheses in several contexts, and output +that highlights implicitly concatenated strings better. + +There are also many changes to the preview style; try out `black --preview` and give us +feedback to help us set the stable style for next year. + +In addition to style changes, Black now automatically infers the supported Python +versions from your `pyproject.toml` file, removing the need to set Black's target +versions separately. + +### Stable style + +- Introduce the 2023 stable style, which incorporates most aspects of last year's + preview style (#3418). Specific changes: + - Enforce empty lines before classes and functions with sticky leading comments + (#3302) (22.12.0) + - Reformat empty and whitespace-only files as either an empty file (if no newline is + present) or as a single newline character (if a newline is present) (#3348) + (22.12.0) + - Implicitly concatenated strings used as function args are now wrapped inside + parentheses (#3307) (22.12.0) + - Correctly handle trailing commas that are inside a line's leading non-nested parens + (#3370) (22.12.0) + - `--skip-string-normalization` / `-S` now prevents docstring prefixes from being + normalized as expected (#3168) (since 22.8.0) + - When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from + subscript expressions with more than 1 element (#3209) (22.8.0) + - Implicitly concatenated strings inside a list, set, or tuple are now wrapped inside + parentheses (#3162) (22.8.0) + - Fix a string merging/split issue when a comment is present in the middle of + implicitly concatenated strings on its own line (#3227) (22.8.0) + - Docstring quotes are no longer moved if it would violate the line length limit + (#3044, #3430) (22.6.0) + - Parentheses around return annotations are now managed (#2990) (22.6.0) + - Remove unnecessary parentheses around awaited objects (#2991) (22.6.0) + - Remove unnecessary parentheses in `with` statements (#2926) (22.6.0) + - Remove trailing newlines after code block open (#3035) (22.6.0) + - Code cell separators `#%%` are now standardised to `# %%` (#2919) (22.3.0) + - Remove unnecessary parentheses from `except` statements (#2939) (22.3.0) + - Remove unnecessary parentheses from tuple unpacking in `for` loops (#2945) (22.3.0) + - Avoid magic-trailing-comma in single-element subscripts (#2942) (22.3.0) +- Fix a crash when a colon line is marked between `# fmt: off` and `# fmt: on` (#3439) + +### Preview style + +- Format hex codes in unicode escape sequences in string literals (#2916) +- Add parentheses around `if`-`else` expressions (#2278) +- Improve performance on large expressions that contain many strings (#3467) +- Fix a crash in preview style with assert + parenthesized string (#3415) +- Fix crashes in preview style with walrus operators used in function return annotations + and except clauses (#3423) +- Fix a crash in preview advanced string processing where mixed implicitly concatenated + regular and f-strings start with an empty span (#3463) +- Fix a crash in preview advanced string processing where a standalone comment is placed + before a dict's value (#3469) +- Fix an issue where extra empty lines are added when a decorator has `# fmt: skip` + applied or there is a standalone comment between decorators (#3470) +- Do not put the closing quotes in a docstring on a separate line, even if the line is + too long (#3430) +- Long values in dict literals are now wrapped in parentheses; correspondingly + unnecessary parentheses around short values in dict literals are now removed; long + string lambda values are now wrapped in parentheses (#3440) +- Fix two crashes in preview style involving edge cases with docstrings (#3451) +- Exclude string type annotations from improved string processing; fix crash when the + return type annotation is stringified and spans across multiple lines (#3462) +- Wrap multiple context managers in parentheses when targeting Python 3.9+ (#3489) +- Fix several crashes in preview style with walrus operators used in `with` statements + or tuples (#3473) +- Fix an invalid quote escaping bug in f-string expressions where it produced invalid + code. Implicitly concatenated f-strings with different quotes can now be merged or + quote-normalized by changing the quotes used in expressions. (#3509) +- Fix crash on `await (yield)` when Black is compiled with mypyc (#3533) + +### Configuration + +- Black now tries to infer its `--target-version` from the project metadata specified in + `pyproject.toml` (#3219) + +### Packaging + +- Upgrade mypyc from `0.971` to `0.991` so mypycified _Black_ can be built on armv7 + (#3380) + - This also fixes some crashes while using compiled Black with a debug build of + CPython +- Drop specific support for the `tomli` requirement on 3.11 alpha releases, working + around a bug that would cause the requirement not to be installed on any non-final + Python releases (#3448) +- Black now depends on `packaging` version `22.0` or later. This is required for new + functionality that needs to parse part of the project metadata (#3219) + +### Output + +- Calling `black --help` multiple times will return the same help contents each time + (#3516) +- Verbose logging now shows the values of `pyproject.toml` configuration variables + (#3392) +- Fix false symlink detection messages in verbose output due to using an incorrect + relative path to the project root (#3385) + +### Integrations + +- Move 3.11 CI to normal flow now that all dependencies support 3.11 (#3446) +- Docker: Add new `latest_prerelease` tag automation to follow latest black alpha + release on docker images (#3465) + +### Documentation + +- Expand `vim-plug` installation instructions to offer more explicit options (#3468) + +## 22.12.0 + +### Preview style + +- Enforce empty lines before classes and functions with sticky leading comments (#3302) +- Reformat empty and whitespace-only files as either an empty file (if no newline is + present) or as a single newline character (if a newline is present) (#3348) +- Implicitly concatenated strings used as function args are now wrapped inside + parentheses (#3307) +- For assignment statements, prefer splitting the right hand side if the left hand side + fits on a single line (#3368) +- Correctly handle trailing commas that are inside a line's leading non-nested parens + (#3370) + +### Configuration + +- Fix incorrectly applied `.gitignore` rules by considering the `.gitignore` location + and the relative path to the target file (#3338) +- Fix incorrectly ignoring `.gitignore` presence when more than one source directory is + specified (#3336) + +### Parser + +- Parsing support has been added for walruses inside generator expression that are + passed as function args (for example, + `any(match := my_re.match(text) for text in texts)`) (#3327). + +### Integrations + +- Vim plugin: Optionally allow using the system installation of Black via + `let g:black_use_virtualenv = 0`(#3309) + +## 22.10.0 + +### Highlights + +- Runtime support for Python 3.6 has been removed. Formatting 3.6 code will still be + supported until further notice. + +### Stable style + +- Fix a crash when `# fmt: on` is used on a different block level than `# fmt: off` + (#3281) + +### Preview style + +- Fix a crash when formatting some dicts with parenthesis-wrapped long string keys + (#3262) + +### Configuration + +- `.ipynb_checkpoints` directories are now excluded by default (#3293) +- Add `--skip-source-first-line` / `-x` option to ignore the first line of source code + while formatting (#3299) + +### Packaging + +- Executables made with PyInstaller will no longer crash when formatting several files + at once on macOS. Native x86-64 executables for macOS are available once again. + (#3275) +- Hatchling is now used as the build backend. This will not have any effect for users + who install Black with its wheels from PyPI. (#3233) +- Faster compiled wheels are now available for CPython 3.11 (#3276) + +### _Blackd_ + +- Windows style (CRLF) newlines will be preserved (#3257). + +### Integrations + +- Vim plugin: add flag (`g:black_preview`) to enable/disable the preview style (#3246) +- Update GitHub Action to support formatting of Jupyter Notebook files via a `jupyter` + option (#3282) +- Update GitHub Action to support use of version specifiers (e.g. `<23`) for Black + version (#3265) + +## 22.8.0 + +### Highlights + +- Python 3.11 is now supported, except for _blackd_ as aiohttp does not support 3.11 as + of publishing (#3234) +- This is the last release that supports running _Black_ on Python 3.6 (formatting 3.6 + code will continue to be supported until further notice) +- Reword the stability policy to say that we may, in rare cases, make changes that + affect code that was not previously formatted by _Black_ (#3155) + +### Stable style + +- Fix an infinite loop when using `# fmt: on/off` in the middle of an expression or code + block (#3158) +- Fix incorrect handling of `# fmt: skip` on colon (`:`) lines (#3148) +- Comments are no longer deleted when a line had spaces removed around power operators + (#2874) + +### Preview style + +- Single-character closing docstring quotes are no longer moved to their own line as + this is invalid. This was a bug introduced in version 22.6.0. (#3166) +- `--skip-string-normalization` / `-S` now prevents docstring prefixes from being + normalized as expected (#3168) +- When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from + subscript expressions with more than 1 element (#3209) +- Implicitly concatenated strings inside a list, set, or tuple are now wrapped inside + parentheses (#3162) +- Fix a string merging/split issue when a comment is present in the middle of implicitly + concatenated strings on its own line (#3227) + +### _Blackd_ + +- `blackd` now supports enabling the preview style via the `X-Preview` header (#3217) + +### Configuration + +- Black now uses the presence of debug f-strings to detect target version (#3215) +- Fix misdetection of project root and verbose logging of sources in cases involving + `--stdin-filename` (#3216) +- Immediate `.gitignore` files in source directories given on the command line are now + also respected, previously only `.gitignore` files in the project root and + automatically discovered directories were respected (#3237) + +### Documentation + +- Recommend using BlackConnect in IntelliJ IDEs (#3150) + +### Integrations + +- Vim plugin: prefix messages with `Black: ` so it's clear they come from Black (#3194) +- Docker: changed to a /opt/venv installation + added to PATH to be available to + non-root users (#3202) + +### Output + +- Change from deprecated `asyncio.get_event_loop()` to create our event loop which + removes DeprecationWarning (#3164) +- Remove logging from internal `blib2to3` library since it regularly emits error logs + about failed caching that can and should be ignored (#3193) + +### Parser + +- Type comments are now included in the AST equivalence check consistently so accidental + deletion raises an error. Though type comments can't be tracked when running on PyPy + 3.7 due to standard library limitations. (#2874) + +### Performance + +- Reduce Black's startup time when formatting a single file by 15-30% (#3211) + +## 22.6.0 + +### Style + +- Fix unstable formatting involving `#fmt: skip` and `# fmt:skip` comments (notice the + lack of spaces) (#2970) + +### Preview style + +- Docstring quotes are no longer moved if it would violate the line length limit (#3044) +- Parentheses around return annotations are now managed (#2990) +- Remove unnecessary parentheses around awaited objects (#2991) +- Remove unnecessary parentheses in `with` statements (#2926) +- Remove trailing newlines after code block open (#3035) + +### Integrations + +- Add `scripts/migrate-black.py` script to ease introduction of Black to a Git project + (#3038) + +### Output + +- Output Python version and implementation as part of `--version` flag (#2997) + +### Packaging + +- Use `tomli` instead of `tomllib` on Python 3.11 builds where `tomllib` is not + available (#2987) + +### Parser + +- [PEP 654](https://peps.python.org/pep-0654/#except) syntax (for example, + `except *ExceptionGroup:`) is now supported (#3016) +- [PEP 646](https://peps.python.org/pep-0646) syntax (for example, + `Array[Batch, *Shape]` or `def fn(*args: *T) -> None`) is now supported (#3071) + +### Vim Plugin + +- Fix `strtobool` function. It didn't parse true/on/false/off. (#3025) + +## 22.3.0 + +### Preview style + +- Code cell separators `#%%` are now standardised to `# %%` (#2919) +- Remove unnecessary parentheses from `except` statements (#2939) +- Remove unnecessary parentheses from tuple unpacking in `for` loops (#2945) +- Avoid magic-trailing-comma in single-element subscripts (#2942) + +### Configuration + +- Do not format `__pypackages__` directories by default (#2836) +- Add support for specifying stable version with `--required-version` (#2832). +- Avoid crashing when the user has no homedir (#2814) +- Avoid crashing when md5 is not available (#2905) +- Fix handling of directory junctions on Windows (#2904) + +### Documentation + +- Update pylint config documentation (#2931) + +### Integrations + +- Move test to disable plugin in Vim/Neovim, which speeds up loading (#2896) + +### Output + +- In verbose mode, log when _Black_ is using user-level config (#2861) + +### Packaging + +- Fix Black to work with Click 8.1.0 (#2966) +- On Python 3.11 and newer, use the standard library's `tomllib` instead of `tomli` + (#2903) +- `black-primer`, the deprecated internal devtool, has been removed and copied to a + [separate repository](https://github.com/cooperlees/black-primer) (#2924) + +### Parser + +- Black can now parse starred expressions in the target of `for` and `async for` + statements, e.g `for item in *items_1, *items_2: pass` (#2879). + +## 22.1.0 + +At long last, _Black_ is no longer a beta product! This is the first non-beta release +and the first release covered by our new +[stability policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy). + +### Highlights + +- **Remove Python 2 support** (#2740) +- Introduce the `--preview` flag (#2752) + +### Style + +- Deprecate `--experimental-string-processing` and move the functionality under + `--preview` (#2789) +- For stubs, one blank line between class attributes and methods is now kept if there's + at least one pre-existing blank line (#2736) +- Black now normalizes string prefix order (#2297) +- Remove spaces around power operators if both operands are simple (#2726) +- Work around bug that causes unstable formatting in some cases in the presence of the + magic trailing comma (#2807) +- Use parentheses for attribute access on decimal float and int literals (#2799) +- Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex + literals (#2799) +- Treat blank lines in stubs the same inside top-level `if` statements (#2820) +- Fix unstable formatting with semicolons and arithmetic expressions (#2817) +- Fix unstable formatting around magic trailing comma (#2572) + +### Parser + +- Fix mapping cases that contain as-expressions, like `case {"key": 1 | 2 as password}` + (#2686) +- Fix cases that contain multiple top-level as-expressions, like `case 1 as a, 2 as b` + (#2716) +- Fix call patterns that contain as-expressions with keyword arguments, like + `case Foo(bar=baz as quux)` (#2749) +- Tuple unpacking on `return` and `yield` constructs now implies 3.8+ (#2700) +- Unparenthesized tuples on annotated assignments (e.g + `values: Tuple[int, ...] = 1, 2, 3`) now implies 3.8+ (#2708) +- Fix handling of standalone `match()` or `case()` when there is a trailing newline or a + comment inside of the parentheses. (#2760) +- `from __future__ import annotations` statement now implies Python 3.7+ (#2690) + +### Performance + +- Speed-up the new backtracking parser about 4X in general (enabled when + `--target-version` is set to 3.10 and higher). (#2728) +- _Black_ is now compiled with [mypyc](https://github.com/mypyc/mypyc) for an overall 2x + speed-up. 64-bit Windows, MacOS, and Linux (not including musl) are supported. (#1009, + #2431) + +### Configuration + +- Do not accept bare carriage return line endings in pyproject.toml (#2408) +- Add configuration option (`python-cell-magics`) to format cells with custom magics in + Jupyter Notebooks (#2744) +- Allow setting custom cache directory on all platforms with environment variable + `BLACK_CACHE_DIR` (#2739). +- Enable Python 3.10+ by default, without any extra need to specify + `--target-version=py310`. (#2758) +- Make passing `SRC` or `--code` mandatory and mutually exclusive (#2804) + +### Output + +- Improve error message for invalid regular expression (#2678) +- Improve error message when parsing fails during AST safety check by embedding the + underlying SyntaxError (#2693) +- No longer color diff headers white as it's unreadable in light themed terminals + (#2691) +- Text coloring added in the final statistics (#2712) +- Verbose mode also now describes how a project root was discovered and which paths will + be formatted. (#2526) + +### Packaging + +- All upper version bounds on dependencies have been removed (#2718) +- `typing-extensions` is no longer a required dependency in Python 3.10+ (#2772) +- Set `click` lower bound to `8.0.0` (#2791) + +### Integrations + +- Update GitHub action to support containerized runs (#2748) + +### Documentation + +- Change protocol in pip installation instructions to `https://` (#2761) +- Change HTML theme to Furo primarily for its responsive design and mobile support + (#2793) +- Deprecate the `black-primer` tool (#2809) +- Document Python support policy (#2819) + +## 21.12b0 + +### _Black_ + +- Fix determination of f-string expression spans (#2654) +- Fix bad formatting of error messages about EOF in multi-line statements (#2343) +- Functions and classes in blocks now have more consistent surrounding spacing (#2472) + +#### Jupyter Notebook support + +- Cell magics are now only processed if they are known Python cell magics. Earlier, all + cell magics were tokenized, leading to possible indentation errors e.g. with + `%%writefile`. (#2630) +- Fix assignment to environment variables in Jupyter Notebooks (#2642) + +#### Python 3.10 support + +- Point users to using `--target-version py310` if we detect 3.10-only syntax (#2668) +- Fix `match` statements with open sequence subjects, like `match a, b:` or + `match a, *b:` (#2639) (#2659) +- Fix `match`/`case` statements that contain `match`/`case` soft keywords multiple + times, like `match re.match()` (#2661) +- Fix `case` statements with an inline body (#2665) +- Fix styling of starred expressions inside `match` subject (#2667) +- Fix parser error location on invalid syntax in a `match` statement (#2649) +- Fix Python 3.10 support on platforms without ProcessPoolExecutor (#2631) +- Improve parsing performance on code that uses `match` under `--target-version py310` + up to ~50% (#2670) + +### Packaging + +- Remove dependency on `regex` (#2644) (#2663) + +## 21.11b1 + +### _Black_ + +- Bumped regex version minimum to 2021.4.4 to fix Pattern class usage (#2621) + +## 21.11b0 + +### _Black_ + +- Warn about Python 2 deprecation in more cases by improving Python 2 only syntax + detection (#2592) +- Add experimental PyPy support (#2559) +- Add partial support for the match statement. As it's experimental, it's only enabled + when `--target-version py310` is explicitly specified (#2586) +- Add support for parenthesized with (#2586) +- Declare support for Python 3.10 for running Black (#2562) + +### Integrations + +- Fixed vim plugin with Python 3.10 by removing deprecated distutils import (#2610) +- The vim plugin now parses `skip_magic_trailing_comma` from pyproject.toml (#2613) + +## 21.10b0 + +### _Black_ + +- Document stability policy, that will apply for non-beta releases (#2529) +- Add new `--workers` parameter (#2514) +- Fixed feature detection for positional-only arguments in lambdas (#2532) +- Bumped typed-ast version minimum to 1.4.3 for 3.10 compatibility (#2519) +- Fixed a Python 3.10 compatibility issue where the loop argument was still being passed + even though it has been removed (#2580) +- Deprecate Python 2 formatting support (#2523) + +### _Blackd_ + +- Remove dependency on aiohttp-cors (#2500) +- Bump required aiohttp version to 3.7.4 (#2509) + +### _Black-Primer_ + +- Add primer support for --projects (#2555) +- Print primer summary after individual failures (#2570) + +### Integrations + +- Allow to pass `target_version` in the vim plugin (#1319) +- Install build tools in docker file and use multi-stage build to keep the image size + down (#2582) + +## 21.9b0 + +### Packaging + +- Fix missing modules in self-contained binaries (#2466) +- Fix missing toml extra used during installation (#2475) + +## 21.8b0 + +### _Black_ + +- Add support for formatting Jupyter Notebook files (#2357) +- Move from `appdirs` dependency to `platformdirs` (#2375) +- Present a more user-friendly error if .gitignore is invalid (#2414) +- The failsafe for accidentally added backslashes in f-string expressions has been + hardened to handle more edge cases during quote normalization (#2437) +- Avoid changing a function return type annotation's type to a tuple by adding a + trailing comma (#2384) +- Parsing support has been added for unparenthesized walruses in set literals, set + comprehensions, and indices (#2447). +- Pin `setuptools-scm` build-time dependency version (#2457) +- Exclude typing-extensions version 3.10.0.1 due to it being broken on Python 3.10 + (#2460) + +### _Blackd_ + +- Replace sys.exit(-1) with raise ImportError as it plays more nicely with tools that + scan installed packages (#2440) + +### Integrations + +- The provided pre-commit hooks no longer specify `language_version` to avoid overriding + `default_language_version` (#2430) + +## 21.7b0 + +### _Black_ + +- Configuration files using TOML features higher than spec v0.5.0 are now supported + (#2301) +- Add primer support and test for code piped into black via STDIN (#2315) +- Fix internal error when `FORCE_OPTIONAL_PARENTHESES` feature is enabled (#2332) +- Accept empty stdin (#2346) +- Provide a more useful error when parsing fails during AST safety checks (#2304) + +### Docker + +- Add new `latest_release` tag automation to follow latest black release on docker + images (#2374) + +### Integrations + +- The vim plugin now searches upwards from the directory containing the current buffer + instead of the current working directory for pyproject.toml. (#1871) +- The vim plugin now reads the correct string normalization option in pyproject.toml + (#1869) +- The vim plugin no longer crashes Black when there's boolean values in pyproject.toml + (#1869) + +## 21.6b0 + +### _Black_ + +- Fix failure caused by `fmt: skip` and indentation (#2281) +- Account for += assignment when deciding whether to split string (#2312) +- Correct max string length calculation when there are string operators (#2292) +- Fixed option usage when using the `--code` flag (#2259) +- Do not call `uvloop.install()` when _Black_ is used as a library (#2303) +- Added `--required-version` option to require a specific version to be running (#2300) +- Fix incorrect custom breakpoint indices when string group contains fake f-strings + (#2311) +- Fix regression where `R` prefixes would be lowercased for docstrings (#2285) +- Fix handling of named escapes (`\N{...}`) when `--experimental-string-processing` is + used (#2319) + +### Integrations + +- The official Black action now supports choosing what version to use, and supports the + major 3 OSes. (#1940) + +## 21.5b2 + +### _Black_ + +- A space is no longer inserted into empty docstrings (#2249) +- Fix handling of .gitignore files containing non-ASCII characters on Windows (#2229) +- Respect `.gitignore` files in all levels, not only `root/.gitignore` file (apply + `.gitignore` rules like `git` does) (#2225) +- Restored compatibility with Click 8.0 on Python 3.6 when LANG=C used (#2227) +- Add extra uvloop install + import support if in python env (#2258) +- Fix --experimental-string-processing crash when matching parens are not found (#2283) +- Make sure to split lines that start with a string operator (#2286) +- Fix regular expression that black uses to identify f-expressions (#2287) + +### _Blackd_ + +- Add a lower bound for the `aiohttp-cors` dependency. Only 0.4.0 or higher is + supported. (#2231) + +### Packaging + +- Release self-contained x86_64 MacOS binaries as part of the GitHub release pipeline + (#2198) +- Always build binaries with the latest available Python (#2260) + +### Documentation + +- Add discussion of magic comments to FAQ page (#2272) +- `--experimental-string-processing` will be enabled by default in the future (#2273) +- Fix typos discovered by codespell (#2228) +- Fix Vim plugin installation instructions. (#2235) +- Add new Frequently Asked Questions page (#2247) +- Fix encoding + symlink issues preventing proper build on Windows (#2262) + +## 21.5b1 + +### _Black_ + +- Refactor `src/black/__init__.py` into many files (#2206) + +### Documentation + +- Replaced all remaining references to the + [`master`](https://github.com/psf/black/tree/main) branch with the + [`main`](https://github.com/psf/black/tree/main) branch. Some additional changes in + the source code were also made. (#2210) +- Significantly reorganized the documentation to make much more sense. Check them out by + heading over to [the stable docs on RTD](https://black.readthedocs.io/en/stable/). + (#2174) + +## 21.5b0 + +### _Black_ + +- Set `--pyi` mode if `--stdin-filename` ends in `.pyi` (#2169) +- Stop detecting target version as Python 3.9+ with pre-PEP-614 decorators that are + being called but with no arguments (#2182) + +### _Black-Primer_ + +- Add `--no-diff` to black-primer to suppress formatting changes (#2187) + +## 21.4b2 + +### _Black_ + +- Fix crash if the user configuration directory is inaccessible. (#2158) + +- Clarify + [circumstances](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism) + in which _Black_ may change the AST (#2159) + +- Allow `.gitignore` rules to be overridden by specifying `exclude` in `pyproject.toml` + or on the command line. (#2170) + +### _Packaging_ + +- Install `primer.json` (used by `black-primer` by default) with black. (#2154) + +## 21.4b1 + +### _Black_ + +- Fix crash on docstrings ending with "\\ ". (#2142) + +- Fix crash when atypical whitespace is cleaned out of dostrings (#2120) + +- Reflect the `--skip-magic-trailing-comma` and `--experimental-string-processing` flags + in the name of the cache file. Without this fix, changes in these flags would not take + effect if the cache had already been populated. (#2131) + +- Don't remove necessary parentheses from assignment expression containing assert / + return statements. (#2143) + +### _Packaging_ + +- Bump pathspec to >= 0.8.1 to solve invalid .gitignore exclusion handling + +## 21.4b0 + +### _Black_ + +- Fixed a rare but annoying formatting instability created by the combination of + optional trailing commas inserted by `Black` and optional parentheses looking at + pre-existing "magic" trailing commas. This fixes issue #1629 and all of its many many + duplicates. (#2126) + +- `Black` now processes one-line docstrings by stripping leading and trailing spaces, + and adding a padding space when needed to break up """". (#1740) + +- `Black` now cleans up leading non-breaking spaces in comments (#2092) + +- `Black` now respects `--skip-string-normalization` when normalizing multiline + docstring quotes (#1637) + +- `Black` no longer removes all empty lines between non-function code and decorators + when formatting typing stubs. Now `Black` enforces a single empty line. (#1646) + +- `Black` no longer adds an incorrect space after a parenthesized assignment expression + in if/while statements (#1655) + +- Added `--skip-magic-trailing-comma` / `-C` to avoid using trailing commas as a reason + to split lines (#1824) + +- fixed a crash when PWD=/ on POSIX (#1631) + +- fixed "I/O operation on closed file" when using --diff (#1664) + +- Prevent coloured diff output being interleaved with multiple files (#1673) + +- Added support for PEP 614 relaxed decorator syntax on python 3.9 (#1711) + +- Added parsing support for unparenthesized tuples and yield expressions in annotated + assignments (#1835) + +- added `--extend-exclude` argument (PR #2005) + +- speed up caching by avoiding pathlib (#1950) + +- `--diff` correctly indicates when a file doesn't end in a newline (#1662) + +- Added `--stdin-filename` argument to allow stdin to respect `--force-exclude` rules + (#1780) + +- Lines ending with `fmt: skip` will now be not formatted (#1800) + +- PR #2053: Black no longer relies on typed-ast for Python 3.8 and higher + +- PR #2053: Python 2 support is now optional, install with + `python3 -m pip install black[python2]` to maintain support. + +- Exclude `venv` directory by default (#1683) + +- Fixed "Black produced code that is not equivalent to the source" when formatting + Python 2 docstrings (#2037) + +### _Packaging_ + +- Self-contained native _Black_ binaries are now provided for releases via GitHub + Releases (#1743) + +## 20.8b1 + +### _Packaging_ + +- explicitly depend on Click 7.1.2 or newer as `Black` no longer works with versions + older than 7.0 + +## 20.8b0 + +### _Black_ + +- re-implemented support for explicit trailing commas: now it works consistently within + any bracket pair, including nested structures (#1288 and duplicates) + +- `Black` now reindents docstrings when reindenting code around it (#1053) + +- `Black` now shows colored diffs (#1266) + +- `Black` is now packaged using 'py3' tagged wheels (#1388) + +- `Black` now supports Python 3.8 code, e.g. star expressions in return statements + (#1121) + +- `Black` no longer normalizes capital R-string prefixes as those have a + community-accepted meaning (#1244) + +- `Black` now uses exit code 2 when specified configuration file doesn't exit (#1361) + +- `Black` now works on AWS Lambda (#1141) + +- added `--force-exclude` argument (#1032) + +- removed deprecated `--py36` option (#1236) + +- fixed `--diff` output when EOF is encountered (#526) + +- fixed `# fmt: off` handling around decorators (#560) + +- fixed unstable formatting with some `# type: ignore` comments (#1113) + +- fixed invalid removal on organizing brackets followed by indexing (#1575) + +- introduced `black-primer`, a CI tool that allows us to run regression tests against + existing open source users of Black (#1402) + +- introduced property-based fuzzing to our test suite based on Hypothesis and + Hypothersmith (#1566) + +- implemented experimental and disabled by default long string rewrapping (#1132), + hidden under a `--experimental-string-processing` flag while it's being worked on; + this is an undocumented and unsupported feature, you lose Internet points for + depending on it (#1609) + +### Vim plugin + +- prefer virtualenv packages over global packages (#1383) + +## 19.10b0 + +- added support for PEP 572 assignment expressions (#711) + +- added support for PEP 570 positional-only arguments (#943) + +- added support for async generators (#593) + +- added support for pre-splitting collections by putting an explicit trailing comma + inside (#826) + +- added `black -c` as a way to format code passed from the command line (#761) + +- --safe now works with Python 2 code (#840) + +- fixed grammar selection for Python 2-specific code (#765) + +- fixed feature detection for trailing commas in function definitions and call sites + (#763) + +- `# fmt: off`/`# fmt: on` comment pairs placed multiple times within the same block of + code now behave correctly (#1005) + +- _Black_ no longer crashes on Windows machines with more than 61 cores (#838) + +- _Black_ no longer crashes on standalone comments prepended with a backslash (#767) + +- _Black_ no longer crashes on `from` ... `import` blocks with comments (#829) + +- _Black_ no longer crashes on Python 3.7 on some platform configurations (#494) + +- _Black_ no longer fails on comments in from-imports (#671) + +- _Black_ no longer fails when the file starts with a backslash (#922) + +- _Black_ no longer merges regular comments with type comments (#1027) + +- _Black_ no longer splits long lines that contain type comments (#997) + +- removed unnecessary parentheses around `yield` expressions (#834) + +- added parentheses around long tuples in unpacking assignments (#832) + +- added parentheses around complex powers when they are prefixed by a unary operator + (#646) + +- fixed bug that led _Black_ format some code with a line length target of 1 (#762) + +- _Black_ no longer introduces quotes in f-string subexpressions on string boundaries + (#863) + +- if _Black_ puts parenthesis around a single expression, it moves comments to the + wrapped expression instead of after the brackets (#872) + +- `blackd` now returns the version of _Black_ in the response headers (#1013) + +- `blackd` can now output the diff of formats on source code when the `X-Diff` header is + provided (#969) + +## 19.3b0 + +- new option `--target-version` to control which Python versions _Black_-formatted code + should target (#618) + +- deprecated `--py36` (use `--target-version=py36` instead) (#724) + +- _Black_ no longer normalizes numeric literals to include `_` separators (#696) + +- long `del` statements are now split into multiple lines (#698) + +- type comments are no longer mangled in function signatures + +- improved performance of formatting deeply nested data structures (#509) + +- _Black_ now properly formats multiple files in parallel on Windows (#632) + +- _Black_ now creates cache files atomically which allows it to be used in parallel + pipelines (like `xargs -P8`) (#673) + +- _Black_ now correctly indents comments in files that were previously formatted with + tabs (#262) + +- `blackd` now supports CORS (#622) + +## 18.9b0 + +- numeric literals are now formatted by _Black_ (#452, #461, #464, #469): + + - numeric literals are normalized to include `_` separators on Python 3.6+ code + + - added `--skip-numeric-underscore-normalization` to disable the above behavior and + leave numeric underscores as they were in the input + + - code with `_` in numeric literals is recognized as Python 3.6+ + + - most letters in numeric literals are lowercased (e.g., in `1e10`, `0x01`) + + - hexadecimal digits are always uppercased (e.g. `0xBADC0DE`) + +- added `blackd`, see + [its documentation](https://github.com/psf/black/blob/18.9b0/README.md#blackd) for + more info (#349) + +- adjacent string literals are now correctly split into multiple lines (#463) + +- trailing comma is now added to single imports that don't fit on a line (#250) + +- cache is now populated when `--check` is successful for a file which speeds up + consecutive checks of properly formatted unmodified files (#448) + +- whitespace at the beginning of the file is now removed (#399) + +- fixed mangling [pweave](http://mpastell.com/pweave/) and + [Spyder IDE](https://www.spyder-ide.org/) special comments (#532) + +- fixed unstable formatting when unpacking big tuples (#267) + +- fixed parsing of `__future__` imports with renames (#389) + +- fixed scope of `# fmt: off` when directly preceding `yield` and other nodes (#385) + +- fixed formatting of lambda expressions with default arguments (#468) + +- fixed `async for` statements: _Black_ no longer breaks them into separate lines (#372) + +- note: the Vim plugin stopped registering `,=` as a default chord as it turned out to + be a bad idea (#415) + +## 18.6b4 + +- hotfix: don't freeze when multiple comments directly precede `# fmt: off` (#371) + +## 18.6b3 + +- typing stub files (`.pyi`) now have blank lines added after constants (#340) + +- `# fmt: off` and `# fmt: on` are now much more dependable: + + - they now work also within bracket pairs (#329) + + - they now correctly work across function/class boundaries (#335) + + - they now work when an indentation block starts with empty lines or misaligned + comments (#334) + +- made Click not fail on invalid environments; note that Click is right but the + likelihood we'll need to access non-ASCII file paths when dealing with Python source + code is low (#277) + +- fixed improper formatting of f-strings with quotes inside interpolated expressions + (#322) + +- fixed unnecessary slowdown when long list literals where found in a file + +- fixed unnecessary slowdown on AST nodes with very many siblings + +- fixed cannibalizing backslashes during string normalization + +- fixed a crash due to symbolic links pointing outside of the project directory (#338) + +## 18.6b2 + +- added `--config` (#65) + +- added `-h` equivalent to `--help` (#316) + +- fixed improper unmodified file caching when `-S` was used + +- fixed extra space in string unpacking (#305) + +- fixed formatting of empty triple quoted strings (#313) + +- fixed unnecessary slowdown in comment placement calculation on lines without comments + +## 18.6b1 + +- hotfix: don't output human-facing information on stdout (#299) + +- hotfix: don't output cake emoji on non-zero return code (#300) + +## 18.6b0 + +- added `--include` and `--exclude` (#270) + +- added `--skip-string-normalization` (#118) + +- added `--verbose` (#283) + +- the header output in `--diff` now actually conforms to the unified diff spec + +- fixed long trivial assignments being wrapped in unnecessary parentheses (#273) + +- fixed unnecessary parentheses when a line contained multiline strings (#232) + +- fixed stdin handling not working correctly if an old version of Click was used (#276) + +- _Black_ now preserves line endings when formatting a file in place (#258) + +## 18.5b1 + +- added `--pyi` (#249) + +- added `--py36` (#249) + +- Python grammar pickle caches are stored with the formatting caches, making _Black_ + work in environments where site-packages is not user-writable (#192) + +- _Black_ now enforces a PEP 257 empty line after a class-level docstring (and/or + fields) and the first method + +- fixed invalid code produced when standalone comments were present in a trailer that + was omitted from line splitting on a large expression (#237) + +- fixed optional parentheses being removed within `# fmt: off` sections (#224) + +- fixed invalid code produced when stars in very long imports were incorrectly wrapped + in optional parentheses (#234) + +- fixed unstable formatting when inline comments were moved around in a trailer that was + omitted from line splitting on a large expression (#238) + +- fixed extra empty line between a class declaration and the first method if no class + docstring or fields are present (#219) + +- fixed extra empty line between a function signature and an inner function or inner + class (#196) + +## 18.5b0 + +- call chains are now formatted according to the + [fluent interfaces](https://en.wikipedia.org/wiki/Fluent_interface) style (#67) + +- data structure literals (tuples, lists, dictionaries, and sets) are now also always + exploded like imports when they don't fit in a single line (#152) + +- slices are now formatted according to PEP 8 (#178) + +- parentheses are now also managed automatically on the right-hand side of assignments + and return statements (#140) + +- math operators now use their respective priorities for delimiting multiline + expressions (#148) + +- optional parentheses are now omitted on expressions that start or end with a bracket + and only contain a single operator (#177) + +- empty parentheses in a class definition are now removed (#145, #180) + +- string prefixes are now standardized to lowercase and `u` is removed on Python 3.6+ + only code and Python 2.7+ code with the `unicode_literals` future import (#188, #198, + #199) + +- typing stub files (`.pyi`) are now formatted in a style that is consistent with PEP + 484 (#207, #210) + +- progress when reformatting many files is now reported incrementally + +- fixed trailers (content with brackets) being unnecessarily exploded into their own + lines after a dedented closing bracket (#119) + +- fixed an invalid trailing comma sometimes left in imports (#185) + +- fixed non-deterministic formatting when multiple pairs of removable parentheses were + used (#183) + +- fixed multiline strings being unnecessarily wrapped in optional parentheses in long + assignments (#215) + +- fixed not splitting long from-imports with only a single name + +- fixed Python 3.6+ file discovery by also looking at function calls with unpacking. + This fixed non-deterministic formatting if trailing commas where used both in function + signatures with stars and function calls with stars but the former would be + reformatted to a single line. + +- fixed crash on dealing with optional parentheses (#193) + +- fixed "is", "is not", "in", and "not in" not considered operators for splitting + purposes + +- fixed crash when dead symlinks where encountered + +## 18.4a4 + +- don't populate the cache on `--check` (#175) + +## 18.4a3 + +- added a "cache"; files already reformatted that haven't changed on disk won't be + reformatted again (#109) + +- `--check` and `--diff` are no longer mutually exclusive (#149) + +- generalized star expression handling, including double stars; this fixes + multiplication making expressions "unsafe" for trailing commas (#132) + +- _Black_ no longer enforces putting empty lines behind control flow statements (#90) + +- _Black_ now splits imports like "Mode 3 + trailing comma" of isort (#127) + +- fixed comment indentation when a standalone comment closes a block (#16, #32) + +- fixed standalone comments receiving extra empty lines if immediately preceding a + class, def, or decorator (#56, #154) + +- fixed `--diff` not showing entire path (#130) + +- fixed parsing of complex expressions after star and double stars in function calls + (#2) + +- fixed invalid splitting on comma in lambda arguments (#133) + +- fixed missing splits of ternary expressions (#141) + +## 18.4a2 + +- fixed parsing of unaligned standalone comments (#99, #112) + +- fixed placement of dictionary unpacking inside dictionary literals (#111) + +- Vim plugin now works on Windows, too + +- fixed unstable formatting when encountering unnecessarily escaped quotes in a string + (#120) + +## 18.4a1 + +- added `--quiet` (#78) + +- added automatic parentheses management (#4) + +- added [pre-commit](https://pre-commit.com) integration (#103, #104) + +- fixed reporting on `--check` with multiple files (#101, #102) + +- fixed removing backslash escapes from raw strings (#100, #105) + +## 18.4a0 + +- added `--diff` (#87) + +- add line breaks before all delimiters, except in cases like commas, to better comply + with PEP 8 (#73) + +- standardize string literals to use double quotes (almost) everywhere (#75) + +- fixed handling of standalone comments within nested bracketed expressions; _Black_ + will no longer produce super long lines or put all standalone comments at the end of + the expression (#22) + +- fixed 18.3a4 regression: don't crash and burn on empty lines with trailing whitespace + (#80) + +- fixed 18.3a4 regression: `# yapf: disable` usage as trailing comment would cause + _Black_ to not emit the rest of the file (#95) + +- when CTRL+C is pressed while formatting many files, _Black_ no longer freaks out with + a flurry of asyncio-related exceptions + +- only allow up to two empty lines on module level and only single empty lines within + functions (#74) + +## 18.3a4 + +- `# fmt: off` and `# fmt: on` are implemented (#5) + +- automatic detection of deprecated Python 2 forms of print statements and exec + statements in the formatted file (#49) + +- use proper spaces for complex expressions in default values of typed function + arguments (#60) + +- only return exit code 1 when --check is used (#50) + +- don't remove single trailing commas from square bracket indexing (#59) + +- don't omit whitespace if the previous factor leaf wasn't a math operator (#55) + +- omit extra space in kwarg unpacking if it's the first argument (#46) + +- omit extra space in + [Sphinx auto-attribute comments](http://www.sphinx-doc.org/en/stable/ext/autodoc.html#directive-autoattribute) + (#68) + +## 18.3a3 + +- don't remove single empty lines outside of bracketed expressions (#19) + +- added ability to pipe formatting from stdin to stdin (#25) + +- restored ability to format code with legacy usage of `async` as a name (#20, #42) + +- even better handling of numpy-style array indexing (#33, again) + +## 18.3a2 + +- changed positioning of binary operators to occur at beginning of lines instead of at + the end, following + [a recent change to PEP 8](https://github.com/python/peps/commit/c59c4376ad233a62ca4b3a6060c81368bd21e85b) + (#21) + +- ignore empty bracket pairs while splitting. This avoids very weirdly looking + formattings (#34, #35) + +- remove a trailing comma if there is a single argument to a call + +- if top level functions were separated by a comment, don't put four empty lines after + the upper function + +- fixed unstable formatting of newlines with imports + +- fixed unintentional folding of post scriptum standalone comments into last statement + if it was a simple statement (#18, #28) + +- fixed missing space in numpy-style array indexing (#33) + +- fixed spurious space after star-based unary expressions (#31) + +## 18.3a1 + +- added `--check` + +- only put trailing commas in function signatures and calls if it's safe to do so. If + the file is Python 3.6+ it's always safe, otherwise only safe if there are no `*args` + or `**kwargs` used in the signature or call. (#8) + +- fixed invalid spacing of dots in relative imports (#6, #13) + +- fixed invalid splitting after comma on unpacked variables in for-loops (#23) + +- fixed spurious space in parenthesized set expressions (#7) + +- fixed spurious space after opening parentheses and in default arguments (#14, #17) + +- fixed spurious space after unary operators when the operand was a complex expression + (#15) + +## 18.3a0 + +- first published version, Happy 🍰 Day 2018! + +- alpha quality + +- date-versioned (see: ) diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/RECORD new file mode 100644 index 00000000..120b849f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/RECORD @@ -0,0 +1,121 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_black_version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/__main__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/_width_table.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/brackets.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/cache.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/comments.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/concurrency.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/const.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/debug.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/files.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/linegen.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/lines.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/mode.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/nodes.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/numerics.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/output.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/parsing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/ranges.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/report.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/rusty.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/strings.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/black/trans.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blackd/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blackd/__main__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blackd/middlewares.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/conv.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/grammar.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/parse.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/token.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/blib2to3/pytree.cpython-39.pyc,, +../../../bin/black,sha256=lzSFz-OrlQMttdZe8nUqxrKsVjzJs9kFNceycRcrl6A,255 +../../../bin/blackd,sha256=RlzFi3FwZGAZ4geVXzICCbY-nv_Ct6ohodMaqC66-eM,256 +629853fdff261ed89b74__mypyc.cpython-39-darwin.so,sha256=DVhLM3Qo07G9xahnsigctWvKxWKrCEvoLJJ5f5e0QLo,3757901 +_black_version.py,sha256=d4NlDZh2CYyujROCjZ2C5HCEywF6U4dWZKsVWOSg9FI,20 +black-23.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +black-23.12.1.dist-info/METADATA,sha256=1Ww6b43o8GWWNB_DD2K8TrV0NKngwCZ8DLgd1ORkWFs,68986 +black-23.12.1.dist-info/RECORD,, +black-23.12.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +black-23.12.1.dist-info/WHEEL,sha256=Exg9AjH5erRjzY276KGujv3zCTU-YNqsk_j-t9wkess,103 +black-23.12.1.dist-info/entry_points.txt,sha256=qBIyywHwGRkJj7kieq86kqf77rz3qGC4Joj36lHnxwc,78 +black-23.12.1.dist-info/licenses/AUTHORS.md,sha256=8drxTtCp41j9z9NFJ9U37R1m9qL0zwTMELvgHFFkwao,8092 +black-23.12.1.dist-info/licenses/LICENSE,sha256=nAQo8MO0d5hQz1vZbhGqqK_HLUqG1KNiI9erouWNbgA,1080 +black/__init__.cpython-39-darwin.so,sha256=2LsUYDVbyrMgKxVilOm-clhpblX3CO01NWRLdnq3wg8,50138 +black/__init__.py,sha256=yB5SaPC3t9R7bATnnD2sdyPIks34Roakk2EiJ-00taM,50074 +black/__main__.py,sha256=mogeA4o9zt4w-ufKvaQjSEhtSgQkcMVLK9ChvdB5wH8,47 +black/_width_table.cpython-39-darwin.so,sha256=rPfmRW0dz1Xekwj8qJ7ZidUXzITKNmHmm30ySRCpC1A,50142 +black/_width_table.py,sha256=2lSnE4s_nVXXfIj9hP2qWASqX8I003WxBM5xPnelDrQ,10761 +black/brackets.cpython-39-darwin.so,sha256=rAf1W7E4cFk74smLAPJ0coaArJu2GocG-APDtITV2No,50138 +black/brackets.py,sha256=pIavHXe4tm7mLWMhfqXRiLI52-8XI9b3szyBF3kR0Mk,12474 +black/cache.cpython-39-darwin.so,sha256=b9sHHFtep77roo2vx2mqty4jD4L5-hy01K7oOPsNDDY,50135 +black/cache.py,sha256=p2oJ1pPUrlGhYZtGovdT9UWbkF5f18EyXjU1Ef1Nbks,4579 +black/comments.cpython-39-darwin.so,sha256=qFtZXM2cE2rEzGCMSQUz8SLWP2l54wxbsKwtmLXY8JE,50138 +black/comments.py,sha256=O4mcLYzeM-lNccdifrxVbCP3hdRRQVqlWMzEkXzbd_0,15816 +black/concurrency.py,sha256=oyFRSg5wisTi2dNLKig6Cm7R2uHWVwkfLbI6pCZRNCo,6410 +black/const.cpython-39-darwin.so,sha256=YTUE7F9bNJgn3UqNlMfKn-6j05pN2t77bZ5rPfhDNwo,50135 +black/const.py,sha256=U7cDnhWljmrieOtPBUdO2Vcz69J_VXB6-Br94wuCVuo,321 +black/debug.py,sha256=HmpJna5KhwLpgQkqEGR2FX6GRmJ2tFh4Jl6X2aMR3ak,1906 +black/files.py,sha256=m_FTnA6cTrQGIGz8YGrWctxTacy4GdmX4ySvma3MkCs,13853 +black/handle_ipynb_magics.cpython-39-darwin.so,sha256=iwWhIl3WI8hby7L6mYFflR4wWfw2IxWtI9laV4NqoQY,50165 +black/handle_ipynb_magics.py,sha256=eAULCQCmQRbgluSRu5jFQNtILMpXnjZWNoOVQLiaEJ8,13364 +black/linegen.cpython-39-darwin.so,sha256=eC8ZCmagpw9b31AH7U8w3JruHrEGlkLQrw3HUaAy5e8,50137 +black/linegen.py,sha256=Ku5qtkwCdmc2EaeDHusMzhLorYM3CcAdJl0gBTaRKPM,67673 +black/lines.cpython-39-darwin.so,sha256=ojc1U_0nG3Ti7wV03qkX1vH_IN2kMvRvsYRDdHxtmGk,50135 +black/lines.py,sha256=AGM0Plc5O4rnSbCEnmBMlYlJKMPVkIjlS_fSVpCGm8A,40778 +black/mode.cpython-39-darwin.so,sha256=6Qivu8-M1ot2SuFNlcfzrxPz9NmDAY3yiNF_QW3Y-A4,50118 +black/mode.py,sha256=StOUYD4kmtk6UK6Sa3iIFh_LTsm1wnuRFA9uCPC4mnY,8408 +black/nodes.cpython-39-darwin.so,sha256=UME34y2n4IjoQ4wmeukeWgaI46jp9oBwzTu6HjGl_eU,50135 +black/nodes.py,sha256=mpocQXHW5N_4jG2fj7Oq_R8_tR3h90zYffNXnErZhko,28273 +black/numerics.cpython-39-darwin.so,sha256=T_gnyH5kLctRcHzgfAi9g96c9Brygfa4OTZo4rwDR5E,50138 +black/numerics.py,sha256=xRGnTSdMVbTaA9IGechc8JM-cIuJGCc326s71hkXJIw,1655 +black/output.py,sha256=hhk6746lZBMbGuJ1VLgjl_Jrn7Yvb24ZBFaCfpO_ijM,3939 +black/parsing.cpython-39-darwin.so,sha256=kKHZaOS8uf_K0GUclcwDu06juZFFM9Vt-LjfCQiLfxw,50137 +black/parsing.py,sha256=yu6lioYFJNrmhaP2FCYJZnxo8vbVq1JvOKjjSt7keC0,7336 +black/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +black/ranges.cpython-39-darwin.so,sha256=0-Xx6_KbRWItUlZ8cVUpvKukldc4yElKFHdXthxv9ck,50136 +black/ranges.py,sha256=DbBqPEyqR1m3AEUn0rd4cS_kHHr13gx5mucn_5RpMLM,18874 +black/report.py,sha256=igkNi8iR5FqSa1sXddS-HnoqW7Cq7PveCmFCfd-pN6w,3452 +black/rusty.cpython-39-darwin.so,sha256=OY1Cbvc2K4UJP6h_yUnh8ELkDVcPiFPhr98Hf6wzxK8,50135 +black/rusty.py,sha256=4LKo3KTUWYZ2cN6QKmwwZVbsCNt2fpu5lzue2V-uxIA,557 +black/strings.cpython-39-darwin.so,sha256=b-BJ0f1N46xiztCpt6asfyfOah-DQH5fj69Ziv95JNM,50137 +black/strings.py,sha256=Ra4sHKZWmNGLA7QIYH4e6EApGn40Bt-7ipbwsbMoGz8,11098 +black/trans.cpython-39-darwin.so,sha256=1rxuu0c9S0e_ak1MEmkENpt-DXFtf9jDx94xMjQp7TE,50135 +black/trans.py,sha256=Ul5pjpjEGEgoAzrmartJIaSSSJhzfxNxNQOGUQqPySs,92609 +blackd/__init__.py,sha256=i_Hf0Q6R8TpsZ_5MVA36D9CXW8ecFTNNM-Hn46179pE,8148 +blackd/__main__.py,sha256=L4xAcDh1K5zb6SsJB102AewW2G13P9-w2RiEwuFj8WA,37 +blackd/middlewares.py,sha256=QS7cs86Ojuaqh64dGneimhJ-f30rDI646c27ts4Dwh0,1585 +blib2to3/Grammar.txt,sha256=qUL_B_u7lqX-83Bas6u8Ckw8q4ea-cQS3Jlv3_i0hrI,11351 +blib2to3/LICENSE,sha256=V4mIG4rrnJH1g19bt8q-hKD-zUuyvi9UyeaVenjseZ0,12762 +blib2to3/PatternGrammar.txt,sha256=7lul2ztnIqDi--JWDrwciD5yMo75w7TaHHxdHMZJvOM,793 +blib2to3/README,sha256=QYZYIfb1NXTTYqDV4kn8oRcNG_qlTFYH1sr3V1h65ko,1074 +blib2to3/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8 +blib2to3/pgen2/__init__.py,sha256=hY6w9QUzvTvRb-MoFfd_q_7ZLt6IUHC2yxWCfsZupQA,143 +blib2to3/pgen2/conv.cpython-39-darwin.so,sha256=dmHnZiiDCHlF-sZnoBwGet0M1Mgz7tQdEvpLsGFPS98,50118 +blib2to3/pgen2/conv.py,sha256=vH8a_gkalWRNxuNPRxkoigw8_UobdHHSw-PyUcUuH8I,9587 +blib2to3/pgen2/driver.cpython-39-darwin.so,sha256=jqpk9idhNMtjuO1yPLt7JRospQCBS66Ra_1GmMsjUAI,50136 +blib2to3/pgen2/driver.py,sha256=HloDYPfu8iVKAvZi-8aknr5T6xJgimBUNv9AbS4qFu8,10631 +blib2to3/pgen2/grammar.cpython-39-darwin.so,sha256=ABu53zu1yU_sd_610KwJASXUDFK37n3A98fpEJmW6XU,50137 +blib2to3/pgen2/grammar.py,sha256=WQBX_vZFq8RNVNPX49J8oNdwXeWhXhizUu5vPwD0ZVM,6858 +blib2to3/pgen2/literals.cpython-39-darwin.so,sha256=DTNxw_IhVOAvJ5htOgfjqk_r_gRvdQcInuumn_NLHqU,50138 +blib2to3/pgen2/literals.py,sha256=_LyRryELzqarFkW3OAEZzZ-yppCTm9g0mjqqQ2XygKE,1614 +blib2to3/pgen2/parse.cpython-39-darwin.so,sha256=rdxduLT0PXCW_Kup-5OWaxWTNyPNqoQj3MQwkohiPMk,50135 +blib2to3/pgen2/parse.py,sha256=ufCEykU-ujdLEei9o1z5fl5ohkGpid4FVRegwe0WhMA,15657 +blib2to3/pgen2/pgen.cpython-39-darwin.so,sha256=2eWhkUIW08anzo0DHtk5ehnbPv1RrXf4IM5ShWXWm6M,50118 +blib2to3/pgen2/pgen.py,sha256=iQH8W999TKUT5AhuOpW38ZynwSACkVNV-I6z8kyQozY,15428 +blib2to3/pgen2/token.cpython-39-darwin.so,sha256=tRftN7uktMC9w4xwH5MzzJn8Iy8o8bt5UG8sSfAyENo,50135 +blib2to3/pgen2/token.py,sha256=iT30kH8_qqhvxuzyUpiIiO3SGxuxqopZBBg-s1x8Vzo,1805 +blib2to3/pgen2/tokenize.cpython-39-darwin.so,sha256=r01MN4EiC-N4bmI8XWZw7BXH07mtNW2JcyTUqhUgl0k,50138 +blib2to3/pgen2/tokenize.py,sha256=BAqfjwwY_9OwlD3gBVMOPpp2tm_eIoOkxqdIiEGLhkk,23006 +blib2to3/pygram.cpython-39-darwin.so,sha256=byINnphaBoohJ32hbUMFKxuoFSm09Q1UBH0vyhr3Klk,50136 +blib2to3/pygram.py,sha256=7C4ciX12W3SKWNI9WkTQRhoXMJkROSk1GMS18snC51o,4810 +blib2to3/pytree.cpython-39-darwin.so,sha256=8wdDCQdIwa9zOjrD3MmHLKOxzjvvZe0u3DOqfkdrxf8,50136 +blib2to3/pytree.py,sha256=dedSbfx56FTkyTOA1A-I4eTVyDuZ0VRZ_eq0H5HmgLc,32569 diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/WHEEL new file mode 100644 index 00000000..6b0f5537 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.20.0 +Root-Is-Purelib: false +Tag: cp39-cp39-macosx_11_0_arm64 diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/entry_points.txt b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/entry_points.txt new file mode 100644 index 00000000..d0bf9079 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +black = black:patched_main +blackd = blackd:patched_main [d] diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/AUTHORS.md b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/AUTHORS.md new file mode 100644 index 00000000..e0511bb9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/AUTHORS.md @@ -0,0 +1,196 @@ +# Authors + +Glued together by [Łukasz Langa](mailto:lukasz@langa.pl). + +Maintained with: + +- [Carol Willing](mailto:carolcode@willingconsulting.com) +- [Carl Meyer](mailto:carl@oddbird.net) +- [Jelle Zijlstra](mailto:jelle.zijlstra@gmail.com) +- [Mika Naylor](mailto:mail@autophagy.io) +- [Zsolt Dollenstein](mailto:zsol.zsol@gmail.com) +- [Cooper Lees](mailto:me@cooperlees.com) +- [Richard Si](mailto:sichard26@gmail.com) +- [Felix Hildén](mailto:felix.hilden@gmail.com) +- [Batuhan Taskaya](mailto:batuhan@python.org) +- [Shantanu Jain](mailto:hauntsaninja@gmail.com) + +Multiple contributions by: + +- [Abdur-Rahmaan Janhangeer](mailto:arj.python@gmail.com) +- [Adam Johnson](mailto:me@adamj.eu) +- [Adam Williamson](mailto:adamw@happyassassin.net) +- [Alexander Huynh](mailto:ahrex-gh-psf-black@e.sc) +- [Alexandr Artemyev](mailto:mogost@gmail.com) +- [Alex Vandiver](mailto:github@chmrr.net) +- [Allan Simon](mailto:allan.simon@supinfo.com) +- Anders-Petter Ljungquist +- [Amethyst Reese](mailto:amy@n7.gg) +- [Andrew Thorp](mailto:andrew.thorp.dev@gmail.com) +- [Andrew Zhou](mailto:andrewfzhou@gmail.com) +- [Andrey](mailto:dyuuus@yandex.ru) +- [Andy Freeland](mailto:andy@andyfreeland.net) +- [Anthony Sottile](mailto:asottile@umich.edu) +- [Antonio Ossa Guerra](mailto:aaossa+black@uc.cl) +- [Arjaan Buijk](mailto:arjaan.buijk@gmail.com) +- [Arnav Borbornah](mailto:arnavborborah11@gmail.com) +- [Artem Malyshev](mailto:proofit404@gmail.com) +- [Asger Hautop Drewsen](mailto:asgerdrewsen@gmail.com) +- [Augie Fackler](mailto:raf@durin42.com) +- [Aviskar KC](mailto:aviskarkc10@gmail.com) +- Batuhan Taşkaya +- [Benjamin Wohlwend](mailto:bw@piquadrat.ch) +- [Benjamin Woodruff](mailto:github@benjam.info) +- [Bharat Raghunathan](mailto:bharatraghunthan9767@gmail.com) +- [Brandt Bucher](mailto:brandtbucher@gmail.com) +- [Brett Cannon](mailto:brett@python.org) +- [Bryan Bugyi](mailto:bryan.bugyi@rutgers.edu) +- [Bryan Forbes](mailto:bryan@reigndropsfall.net) +- [Calum Lind](mailto:calumlind@gmail.com) +- [Charles](mailto:peacech@gmail.com) +- Charles Reid +- [Christian Clauss](mailto:cclauss@bluewin.ch) +- [Christian Heimes](mailto:christian@python.org) +- [Chuck Wooters](mailto:chuck.wooters@microsoft.com) +- [Chris Rose](mailto:offline@offby1.net) +- Codey Oxley +- [Cong](mailto:congusbongus@gmail.com) +- [Cooper Ry Lees](mailto:me@cooperlees.com) +- [Dan Davison](mailto:dandavison7@gmail.com) +- [Daniel Hahler](mailto:github@thequod.de) +- [Daniel M. Capella](mailto:polycitizen@gmail.com) +- Daniele Esposti +- [David Hotham](mailto:david.hotham@metaswitch.com) +- [David Lukes](mailto:dafydd.lukes@gmail.com) +- [David Szotten](mailto:davidszotten@gmail.com) +- [Denis Laxalde](mailto:denis@laxalde.org) +- [Douglas Thor](mailto:dthor@transphormusa.com) +- dylanjblack +- [Eli Treuherz](mailto:eli@treuherz.com) +- [Emil Hessman](mailto:emil@hessman.se) +- [Felix Kohlgrüber](mailto:felix.kohlgrueber@gmail.com) +- [Florent Thiery](mailto:fthiery@gmail.com) +- Francisco +- [Giacomo Tagliabue](mailto:giacomo.tag@gmail.com) +- [Greg Gandenberger](mailto:ggandenberger@shoprunner.com) +- [Gregory P. Smith](mailto:greg@krypto.org) +- Gustavo Camargo +- hauntsaninja +- [Hadi Alqattan](mailto:alqattanhadizaki@gmail.com) +- [Hassan Abouelela](mailto:hassan@hassanamr.com) +- [Heaford](mailto:dan@heaford.com) +- [Hugo Barrera](mailto::hugo@barrera.io) +- Hugo van Kemenade +- [Hynek Schlawack](mailto:hs@ox.cx) +- [Ionite](mailto:dev@ionite.io) +- [Ivan Katanić](mailto:ivan.katanic@gmail.com) +- [Jakub Kadlubiec](mailto:jakub.kadlubiec@skyscanner.net) +- [Jakub Warczarek](mailto:jakub.warczarek@gmail.com) +- [Jan Hnátek](mailto:jan.hnatek@gmail.com) +- [Jason Fried](mailto:me@jasonfried.info) +- [Jason Friedland](mailto:jason@friedland.id.au) +- [jgirardet](mailto:ijkl@netc.fr) +- Jim Brännlund +- [Jimmy Jia](mailto:tesrin@gmail.com) +- [Joe Antonakakis](mailto:jma353@cornell.edu) +- [Jon Dufresne](mailto:jon.dufresne@gmail.com) +- [Jonas Obrist](mailto:ojiidotch@gmail.com) +- [Jonty Wareing](mailto:jonty@jonty.co.uk) +- [Jose Nazario](mailto:jose.monkey.org@gmail.com) +- [Joseph Larson](mailto:larson.joseph@gmail.com) +- [Josh Bode](mailto:joshbode@fastmail.com) +- [Josh Holland](mailto:anowlcalledjosh@gmail.com) +- [Joshua Cannon](mailto:joshdcannon@gmail.com) +- [José Padilla](mailto:jpadilla@webapplicate.com) +- [Juan Luis Cano Rodríguez](mailto:hello@juanlu.space) +- [kaiix](mailto:kvn.hou@gmail.com) +- [Katie McLaughlin](mailto:katie@glasnt.com) +- Katrin Leinweber +- [Keith Smiley](mailto:keithbsmiley@gmail.com) +- [Kenyon Ralph](mailto:kenyon@kenyonralph.com) +- [Kevin Kirsche](mailto:Kev.Kirsche+GitHub@gmail.com) +- [Kyle Hausmann](mailto:kyle.hausmann@gmail.com) +- [Kyle Sunden](mailto:sunden@wisc.edu) +- Lawrence Chan +- [Linus Groh](mailto:mail@linusgroh.de) +- [Loren Carvalho](mailto:comradeloren@gmail.com) +- [Luka Sterbic](mailto:luka.sterbic@gmail.com) +- [LukasDrude](mailto:mail@lukas-drude.de) +- Mahmoud Hossam +- Mariatta +- [Matt VanEseltine](mailto:vaneseltine@gmail.com) +- [Matthew Clapp](mailto:itsayellow+dev@gmail.com) +- [Matthew Walster](mailto:matthew@walster.org) +- Max Smolens +- [Michael Aquilina](mailto:michaelaquilina@gmail.com) +- [Michael Flaxman](mailto:michael.flaxman@gmail.com) +- [Michael J. Sullivan](mailto:sully@msully.net) +- [Michael McClimon](mailto:michael@mcclimon.org) +- [Miguel Gaiowski](mailto:miggaiowski@gmail.com) +- [Mike](mailto:roshi@fedoraproject.org) +- [mikehoyio](mailto:mikehoy@gmail.com) +- [Min ho Kim](mailto:minho42@gmail.com) +- [Miroslav Shubernetskiy](mailto:miroslav@miki725.com) +- MomIsBestFriend +- [Nathan Goldbaum](mailto:ngoldbau@illinois.edu) +- [Nathan Hunt](mailto:neighthan.hunt@gmail.com) +- [Neraste](mailto:neraste.herr10@gmail.com) +- [Nikolaus Waxweiler](mailto:madigens@gmail.com) +- [Ofek Lev](mailto:ofekmeister@gmail.com) +- [Osaetin Daniel](mailto:osaetindaniel@gmail.com) +- [otstrel](mailto:otstrel@gmail.com) +- [Pablo Galindo](mailto:Pablogsal@gmail.com) +- [Paul Ganssle](mailto:p.ganssle@gmail.com) +- [Paul Meinhardt](mailto:mnhrdt@gmail.com) +- [Peter Bengtsson](mailto:mail@peterbe.com) +- [Peter Grayson](mailto:pete@jpgrayson.net) +- [Peter Stensmyr](mailto:peter.stensmyr@gmail.com) +- pmacosta +- [Quentin Pradet](mailto:quentin@pradet.me) +- [Ralf Schmitt](mailto:ralf@systemexit.de) +- [Ramón Valles](mailto:mroutis@protonmail.com) +- [Richard Fearn](mailto:richardfearn@gmail.com) +- [Rishikesh Jha](mailto:rishijha424@gmail.com) +- [Rupert Bedford](mailto:rupert@rupertb.com) +- Russell Davis +- [Sagi Shadur](mailto:saroad2@gmail.com) +- [Rémi Verschelde](mailto:rverschelde@gmail.com) +- [Sami Salonen](mailto:sakki@iki.fi) +- [Samuel Cormier-Iijima](mailto:samuel@cormier-iijima.com) +- [Sanket Dasgupta](mailto:sanketdasgupta@gmail.com) +- Sergi +- [Scott Stevenson](mailto:scott@stevenson.io) +- Shantanu +- [shaoran](mailto:shaoran@sakuranohana.org) +- [Shinya Fujino](mailto:shf0811@gmail.com) +- springstan +- [Stavros Korokithakis](mailto:hi@stavros.io) +- [Stephen Rosen](mailto:sirosen@globus.org) +- [Steven M. Vascellaro](mailto:S.Vascellaro@gmail.com) +- [Sunil Kapil](mailto:snlkapil@gmail.com) +- [Sébastien Eustace](mailto:sebastien.eustace@gmail.com) +- [Tal Amuyal](mailto:TalAmuyal@gmail.com) +- [Terrance](mailto:git@terrance.allofti.me) +- [Thom Lu](mailto:thomas.c.lu@gmail.com) +- [Thomas Grainger](mailto:tagrain@gmail.com) +- [Tim Gates](mailto:tim.gates@iress.com) +- [Tim Swast](mailto:swast@google.com) +- [Timo](mailto:timo_tk@hotmail.com) +- Toby Fleming +- [Tom Christie](mailto:tom@tomchristie.com) +- [Tony Narlock](mailto:tony@git-pull.com) +- [Tsuyoshi Hombashi](mailto:tsuyoshi.hombashi@gmail.com) +- [Tushar Chandra](mailto:tusharchandra2018@u.northwestern.edu) +- [Tzu-ping Chung](mailto:uranusjr@gmail.com) +- [Utsav Shah](mailto:ukshah2@illinois.edu) +- utsav-dbx +- vezeli +- [Ville Skyttä](mailto:ville.skytta@iki.fi) +- [Vishwas B Sharma](mailto:sharma.vishwas88@gmail.com) +- [Vlad Emelianov](mailto:volshebnyi@gmail.com) +- [williamfzc](mailto:178894043@qq.com) +- [wouter bolsterlee](mailto:wouter@bolsterl.ee) +- Yazdan +- [Yngve Høiseth](mailto:yngve@hoiseth.net) +- [Yurii Karabas](mailto:1998uriyyo@gmail.com) +- [Zac Hatfield-Dodds](mailto:zac@zhd.dev) diff --git a/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/LICENSE b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/LICENSE new file mode 100644 index 00000000..7a9b891f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black-23.12.1.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Łukasz Langa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/black/__init__.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/__init__.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..4b5c94015ede717e18a90a518b05ee980e3c2dd6 GIT binary patch literal 50138 zcmeI*Uu;uV90%}UZ#$^6jUtoGs97aMbdiE=;1(5%3}GlRV1^|=oV07l8t&TC-T{>% zLxTzUpd^GqVuK@$l?fn?0z@7{B_wg^1!#e5Gr zJ?D4My}xtr=eE2Z`1Z!1H_M4U#Kq6GlIx(4XuAw>d4TIrJgZdeqPA9hsQ4pX9FmU9 zc-XCSg;G|0lO;W;l;&%i=Zv4y^Aa1nZ#O>bEew^)THVp?$WUp%s`<{;G<}7{h57tC zA3wWYoP4S?Zl>cI9x2V&pz}SWua~$mAKkLQ_NPe-$Fg_#yTv{&4WsH zCpRXNF_lPmr0lr(eSE6(Ezt=iF4~`)ShwkDqvdU;x^ zd|?7ym0FuBc&)e1C*Li*gq{0!MB}(4`P?G=8szHi%N^ymSNFrZEs5QIxzDVW8By6> zS2Sg+w3WGSzG|IL@)z!7JdgX_Ic}ATMXbo^K`%dtG; ztm8zRxShbYg{u^I4Y^j9Ep(9i!V=*7B~NL2kOyR)abNmQ9zET-^JDK@FNY4k`t)ob z3v!h;>{UG#cHe$HPrbL6N9B9v7WsWPaFtxLAEN2}*NTT`c4sp)%|uk{>Ri@}cZHq{ z#c~|k7ty2KNS?iU$K`Py%X3S4n5)e9^Zsj{#4?Nm0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*#k7Xm|@j~yKH(ys756sQS$f2bqc9X4pdPvPtSGP=xXVz2X&&DNlv_fYSu>3mJl zLjyybj~^haIm72OcL)8>{W4!8@$m3bKHmDBT$A^zGwwQkXxLtd&(QwoIv2`D^Hh|q zGm+y9zR`I;OnS>Y@(eBGjW#lB&Pab&K|i4Td{(xapQ}n-5zcDln{D3MH9Dr!dB z*E#2BACkqn6t;4dRnE@Wb1U_JeJ))3a>lltUqpbbE_XWG>t2Hv0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZafiV_v|6lti{qF>{=yr^kMS2K800Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*yv1SUPq6JCGi?3=3AWN<;KUgjO#eAg)xT|B=suaag|a*bi6-kP`MM{?K3=bf%}A^ z_H@qbOeJU3HO`1dG8+@gP&P%``4zsL+8X-x-jm!$%l`usoj3X_~+i#wavd>8@Tb|gizN@ zJ72F~+SRhf9P9Outh~>ptIzIv{^!R|1wZ?H?wV`y4|;rk(+ "WriteBack": + if check and not diff: + return cls.CHECK + + if diff and color: + return cls.COLOR_DIFF + + return cls.DIFF if diff else cls.YES + + +# Legacy name, left for integrations. +FileMode = Mode + + +def read_pyproject_toml( + ctx: click.Context, param: click.Parameter, value: Optional[str] +) -> Optional[str]: + """Inject Black configuration from "pyproject.toml" into defaults in `ctx`. + + Returns the path to a successfully found and read configuration file, None + otherwise. + """ + if not value: + value = find_pyproject_toml( + ctx.params.get("src", ()), ctx.params.get("stdin_filename", None) + ) + if value is None: + return None + + try: + config = parse_pyproject_toml(value) + except (OSError, ValueError) as e: + raise click.FileError( + filename=value, hint=f"Error reading configuration file: {e}" + ) from None + + if not config: + return None + else: + # Sanitize the values to be Click friendly. For more information please see: + # https://github.com/psf/black/issues/1458 + # https://github.com/pallets/click/issues/1567 + config = { + k: str(v) if not isinstance(v, (list, dict)) else v + for k, v in config.items() + } + + target_version = config.get("target_version") + if target_version is not None and not isinstance(target_version, list): + raise click.BadOptionUsage( + "target-version", "Config key target-version must be a list" + ) + + exclude = config.get("exclude") + if exclude is not None and not isinstance(exclude, str): + raise click.BadOptionUsage("exclude", "Config key exclude must be a string") + + extend_exclude = config.get("extend_exclude") + if extend_exclude is not None and not isinstance(extend_exclude, str): + raise click.BadOptionUsage( + "extend-exclude", "Config key extend-exclude must be a string" + ) + + line_ranges = config.get("line_ranges") + if line_ranges is not None: + raise click.BadOptionUsage( + "line-ranges", "Cannot use line-ranges in the pyproject.toml file." + ) + + default_map: Dict[str, Any] = {} + if ctx.default_map: + default_map.update(ctx.default_map) + default_map.update(config) + + ctx.default_map = default_map + return value + + +def target_version_option_callback( + c: click.Context, p: Union[click.Option, click.Parameter], v: Tuple[str, ...] +) -> List[TargetVersion]: + """Compute the target versions from a --target-version flag. + + This is its own function because mypy couldn't infer the type correctly + when it was a lambda, causing mypyc trouble. + """ + return [TargetVersion[val.upper()] for val in v] + + +def re_compile_maybe_verbose(regex: str) -> Pattern[str]: + """Compile a regular expression string in `regex`. + + If it contains newlines, use verbose mode. + """ + if "\n" in regex: + regex = "(?x)" + regex + compiled: Pattern[str] = re.compile(regex) + return compiled + + +def validate_regex( + ctx: click.Context, + param: click.Parameter, + value: Optional[str], +) -> Optional[Pattern[str]]: + try: + return re_compile_maybe_verbose(value) if value is not None else None + except re.error as e: + raise click.BadParameter(f"Not a valid regular expression: {e}") from None + + +@click.command( + context_settings={"help_option_names": ["-h", "--help"]}, + # While Click does set this field automatically using the docstring, mypyc + # (annoyingly) strips 'em so we need to set it here too. + help="The uncompromising code formatter.", +) +@click.option("-c", "--code", type=str, help="Format the code passed in as a string.") +@click.option( + "-l", + "--line-length", + type=int, + default=DEFAULT_LINE_LENGTH, + help="How many characters per line to allow.", + show_default=True, +) +@click.option( + "-t", + "--target-version", + type=click.Choice([v.name.lower() for v in TargetVersion]), + callback=target_version_option_callback, + multiple=True, + help=( + "Python versions that should be supported by Black's output. You should" + " include all versions that your code supports. By default, Black will infer" + " target versions from the project metadata in pyproject.toml. If this does" + " not yield conclusive results, Black will use per-file auto-detection." + ), +) +@click.option( + "--pyi", + is_flag=True, + help=( + "Format all input files like typing stubs regardless of file extension. This" + " is useful when piping source on standard input." + ), +) +@click.option( + "--ipynb", + is_flag=True, + help=( + "Format all input files like Jupyter Notebooks regardless of file extension." + "This is useful when piping source on standard input." + ), +) +@click.option( + "--python-cell-magics", + multiple=True, + help=( + "When processing Jupyter Notebooks, add the given magic to the list" + f" of known python-magics ({', '.join(sorted(PYTHON_CELL_MAGICS))})." + " Useful for formatting cells with custom python magics." + ), + default=[], +) +@click.option( + "-x", + "--skip-source-first-line", + is_flag=True, + help="Skip the first line of the source code.", +) +@click.option( + "-S", + "--skip-string-normalization", + is_flag=True, + help="Don't normalize string quotes or prefixes.", +) +@click.option( + "-C", + "--skip-magic-trailing-comma", + is_flag=True, + help="Don't use trailing commas as a reason to split lines.", +) +@click.option( + "--experimental-string-processing", + is_flag=True, + hidden=True, + help="(DEPRECATED and now included in --preview) Normalize string literals.", +) +@click.option( + "--preview", + is_flag=True, + help=( + "Enable potentially disruptive style changes that may be added to Black's main" + " functionality in the next major release." + ), +) +@click.option( + "--check", + is_flag=True, + help=( + "Don't write the files back, just return the status. Return code 0 means" + " nothing would change. Return code 1 means some files would be reformatted." + " Return code 123 means there was an internal error." + ), +) +@click.option( + "--diff", + is_flag=True, + help=( + "Don't write the files back, just output a diff to indicate what changes" + " Black would've made. They are printed to stdout so capturing them is simple." + ), +) +@click.option( + "--color/--no-color", + is_flag=True, + help="Show (or do not show) colored diff. Only applies when --diff is given.", +) +@click.option( + "--line-ranges", + multiple=True, + metavar="START-END", + help=( + "When specified, Black will try its best to only format these lines. This" + " option can be specified multiple times, and a union of the lines will be" + " formatted. Each range must be specified as two integers connected by a `-`:" + " `-`. The `` and `` integer indices are 1-based and" + " inclusive on both ends." + ), + default=(), +) +@click.option( + "--fast/--safe", + is_flag=True, + help=( + "By default, Black performs an AST safety check after formatting your code." + " The --fast flag turns off this check and the --safe flag explicitly enables" + " it. [default: --safe]" + ), +) +@click.option( + "--required-version", + type=str, + help=( + "Require a specific version of Black to be running. This is useful for" + " ensuring that all contributors to your project are using the same" + " version, because different versions of Black may format code a little" + " differently. This option can be set in a configuration file for consistent" + " results across environments." + ), +) +@click.option( + "--exclude", + type=str, + callback=validate_regex, + help=( + "A regular expression that matches files and directories that should be" + " excluded on recursive searches. An empty value means no paths are excluded." + " Use forward slashes for directories on all platforms (Windows, too)." + " By default, Black also ignores all paths listed in .gitignore. Changing this" + f" value will override all default exclusions. [default: {DEFAULT_EXCLUDES}]" + ), + show_default=False, +) +@click.option( + "--extend-exclude", + type=str, + callback=validate_regex, + help=( + "Like --exclude, but adds additional files and directories on top of the" + " default values instead of overriding them." + ), +) +@click.option( + "--force-exclude", + type=str, + callback=validate_regex, + help=( + "Like --exclude, but files and directories matching this regex will be excluded" + " even when they are passed explicitly as arguments. This is useful when" + " invoking Black programmatically on changed files, such as in a pre-commit" + " hook or editor plugin." + ), +) +@click.option( + "--stdin-filename", + type=str, + is_eager=True, + help=( + "The name of the file when passing it through stdin. Useful to make sure Black" + " will respect the --force-exclude option on some editors that rely on using" + " stdin." + ), +) +@click.option( + "--include", + type=str, + default=DEFAULT_INCLUDES, + callback=validate_regex, + help=( + "A regular expression that matches files and directories that should be" + " included on recursive searches. An empty value means all files are included" + " regardless of the name. Use forward slashes for directories on all platforms" + " (Windows, too). Overrides all exclusions, including from .gitignore and" + " command line options." + ), + show_default=True, +) +@click.option( + "-W", + "--workers", + type=click.IntRange(min=1), + default=None, + help=( + "When Black formats multiple files, it may use a process pool to speed up" + " formatting. This option controls the number of parallel workers. This can" + " also be specified via the BLACK_NUM_WORKERS environment variable. Defaults" + " to the number of CPUs in the system." + ), +) +@click.option( + "-q", + "--quiet", + is_flag=True, + help=( + "Stop emitting all non-critical output. Error messages will still be emitted" + " (which can silenced by 2>/dev/null)." + ), +) +@click.option( + "-v", + "--verbose", + is_flag=True, + help=( + "Emit messages about files that were not changed or were ignored due to" + " exclusion patterns. If Black is using a configuration file, a message" + " detailing which one it is using will be emitted." + ), +) +@click.version_option( + version=__version__, + message=( + f"%(prog)s, %(version)s (compiled: {'yes' if COMPILED else 'no'})\n" + f"Python ({platform.python_implementation()}) {platform.python_version()}" + ), +) +@click.argument( + "src", + nargs=-1, + type=click.Path( + exists=True, file_okay=True, dir_okay=True, readable=True, allow_dash=True + ), + is_eager=True, + metavar="SRC ...", +) +@click.option( + "--config", + type=click.Path( + exists=True, + file_okay=True, + dir_okay=False, + readable=True, + allow_dash=False, + path_type=str, + ), + is_eager=True, + callback=read_pyproject_toml, + help="Read configuration options from a configuration file.", +) +@click.pass_context +def main( # noqa: C901 + ctx: click.Context, + code: Optional[str], + line_length: int, + target_version: List[TargetVersion], + check: bool, + diff: bool, + line_ranges: Sequence[str], + color: bool, + fast: bool, + pyi: bool, + ipynb: bool, + python_cell_magics: Sequence[str], + skip_source_first_line: bool, + skip_string_normalization: bool, + skip_magic_trailing_comma: bool, + experimental_string_processing: bool, + preview: bool, + quiet: bool, + verbose: bool, + required_version: Optional[str], + include: Pattern[str], + exclude: Optional[Pattern[str]], + extend_exclude: Optional[Pattern[str]], + force_exclude: Optional[Pattern[str]], + stdin_filename: Optional[str], + workers: Optional[int], + src: Tuple[str, ...], + config: Optional[str], +) -> None: + """The uncompromising code formatter.""" + ctx.ensure_object(dict) + + if src and code is not None: + out( + main.get_usage(ctx) + + "\n\n'SRC' and 'code' cannot be passed simultaneously." + ) + ctx.exit(1) + if not src and code is None: + out(main.get_usage(ctx) + "\n\nOne of 'SRC' or 'code' is required.") + ctx.exit(1) + + root, method = ( + find_project_root(src, stdin_filename) if code is None else (None, None) + ) + ctx.obj["root"] = root + + if verbose: + if root: + out( + f"Identified `{root}` as project root containing a {method}.", + fg="blue", + ) + + if config: + config_source = ctx.get_parameter_source("config") + user_level_config = str(find_user_pyproject_toml()) + if config == user_level_config: + out( + "Using configuration from user-level config at " + f"'{user_level_config}'.", + fg="blue", + ) + elif config_source in ( + ParameterSource.DEFAULT, + ParameterSource.DEFAULT_MAP, + ): + out("Using configuration from project root.", fg="blue") + else: + out(f"Using configuration in '{config}'.", fg="blue") + if ctx.default_map: + for param, value in ctx.default_map.items(): + out(f"{param}: {value}") + + error_msg = "Oh no! 💥 💔 💥" + if ( + required_version + and required_version != __version__ + and required_version != __version__.split(".")[0] + ): + err( + f"{error_msg} The required version `{required_version}` does not match" + f" the running version `{__version__}`!" + ) + ctx.exit(1) + if ipynb and pyi: + err("Cannot pass both `pyi` and `ipynb` flags!") + ctx.exit(1) + + write_back = WriteBack.from_configuration(check=check, diff=diff, color=color) + if target_version: + versions = set(target_version) + else: + # We'll autodetect later. + versions = set() + mode = Mode( + target_versions=versions, + line_length=line_length, + is_pyi=pyi, + is_ipynb=ipynb, + skip_source_first_line=skip_source_first_line, + string_normalization=not skip_string_normalization, + magic_trailing_comma=not skip_magic_trailing_comma, + experimental_string_processing=experimental_string_processing, + preview=preview, + python_cell_magics=set(python_cell_magics), + ) + + lines: List[Tuple[int, int]] = [] + if line_ranges: + if ipynb: + err("Cannot use --line-ranges with ipynb files.") + ctx.exit(1) + + try: + lines = parse_line_ranges(line_ranges) + except ValueError as e: + err(str(e)) + ctx.exit(1) + + if code is not None: + # Run in quiet mode by default with -c; the extra output isn't useful. + # You can still pass -v to get verbose output. + quiet = True + + report = Report(check=check, diff=diff, quiet=quiet, verbose=verbose) + + if code is not None: + reformat_code( + content=code, + fast=fast, + write_back=write_back, + mode=mode, + report=report, + lines=lines, + ) + else: + assert root is not None # root is only None if code is not None + try: + sources = get_sources( + root=root, + src=src, + quiet=quiet, + verbose=verbose, + include=include, + exclude=exclude, + extend_exclude=extend_exclude, + force_exclude=force_exclude, + report=report, + stdin_filename=stdin_filename, + ) + except GitWildMatchPatternError: + ctx.exit(1) + + path_empty( + sources, + "No Python files are present to be formatted. Nothing to do 😴", + quiet, + verbose, + ctx, + ) + + if len(sources) == 1: + reformat_one( + src=sources.pop(), + fast=fast, + write_back=write_back, + mode=mode, + report=report, + lines=lines, + ) + else: + from black.concurrency import reformat_many + + if lines: + err("Cannot use --line-ranges to format multiple files.") + ctx.exit(1) + reformat_many( + sources=sources, + fast=fast, + write_back=write_back, + mode=mode, + report=report, + workers=workers, + ) + + if verbose or not quiet: + if code is None and (verbose or report.change_count or report.failure_count): + out() + out(error_msg if report.return_code else "All done! ✨ 🍰 ✨") + if code is None: + click.echo(str(report), err=True) + ctx.exit(report.return_code) + + +def get_sources( + *, + root: Path, + src: Tuple[str, ...], + quiet: bool, + verbose: bool, + include: Pattern[str], + exclude: Optional[Pattern[str]], + extend_exclude: Optional[Pattern[str]], + force_exclude: Optional[Pattern[str]], + report: "Report", + stdin_filename: Optional[str], +) -> Set[Path]: + """Compute the set of files to be formatted.""" + sources: Set[Path] = set() + + using_default_exclude = exclude is None + exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES) if exclude is None else exclude + gitignore: Optional[Dict[Path, PathSpec]] = None + root_gitignore = get_gitignore(root) + + for s in src: + if s == "-" and stdin_filename: + path = Path(stdin_filename) + is_stdin = True + else: + path = Path(s) + is_stdin = False + + # Compare the logic here to the logic in `gen_python_files`. + if is_stdin or path.is_file(): + root_relative_path = path.absolute().relative_to(root).as_posix() + + root_relative_path = "/" + root_relative_path + + # Hard-exclude any files that matches the `--force-exclude` regex. + if path_is_excluded(root_relative_path, force_exclude): + report.path_ignored( + path, "matches the --force-exclude regular expression" + ) + continue + + normalized_path: Optional[str] = normalize_path_maybe_ignore( + path, root, report + ) + if normalized_path is None: + if verbose: + out(f'Skipping invalid source: "{normalized_path}"', fg="red") + continue + + if is_stdin: + path = Path(f"{STDIN_PLACEHOLDER}{str(path)}") + + if path.suffix == ".ipynb" and not jupyter_dependencies_are_installed( + warn=verbose or not quiet + ): + continue + + if verbose: + out(f'Found input source: "{normalized_path}"', fg="blue") + sources.add(path) + elif path.is_dir(): + path = root / (path.resolve().relative_to(root)) + if verbose: + out(f'Found input source directory: "{path}"', fg="blue") + + if using_default_exclude: + gitignore = { + root: root_gitignore, + path: get_gitignore(path), + } + sources.update( + gen_python_files( + path.iterdir(), + root, + include, + exclude, + extend_exclude, + force_exclude, + report, + gitignore, + verbose=verbose, + quiet=quiet, + ) + ) + elif s == "-": + if verbose: + out("Found input source stdin", fg="blue") + sources.add(path) + else: + err(f"invalid path: {s}") + + return sources + + +def path_empty( + src: Sized, msg: str, quiet: bool, verbose: bool, ctx: click.Context +) -> None: + """ + Exit if there is no `src` provided for formatting + """ + if not src: + if verbose or not quiet: + out(msg) + ctx.exit(0) + + +def reformat_code( + content: str, + fast: bool, + write_back: WriteBack, + mode: Mode, + report: Report, + *, + lines: Collection[Tuple[int, int]] = (), +) -> None: + """ + Reformat and print out `content` without spawning child processes. + Similar to `reformat_one`, but for string content. + + `fast`, `write_back`, and `mode` options are passed to + :func:`format_file_in_place` or :func:`format_stdin_to_stdout`. + """ + path = Path("") + try: + changed = Changed.NO + if format_stdin_to_stdout( + content=content, fast=fast, write_back=write_back, mode=mode, lines=lines + ): + changed = Changed.YES + report.done(path, changed) + except Exception as exc: + if report.verbose: + traceback.print_exc() + report.failed(path, str(exc)) + + +# diff-shades depends on being to monkeypatch this function to operate. I know it's +# not ideal, but this shouldn't cause any issues ... hopefully. ~ichard26 +@mypyc_attr(patchable=True) +def reformat_one( + src: Path, + fast: bool, + write_back: WriteBack, + mode: Mode, + report: "Report", + *, + lines: Collection[Tuple[int, int]] = (), +) -> None: + """Reformat a single file under `src` without spawning child processes. + + `fast`, `write_back`, and `mode` options are passed to + :func:`format_file_in_place` or :func:`format_stdin_to_stdout`. + """ + try: + changed = Changed.NO + + if str(src) == "-": + is_stdin = True + elif str(src).startswith(STDIN_PLACEHOLDER): + is_stdin = True + # Use the original name again in case we want to print something + # to the user + src = Path(str(src)[len(STDIN_PLACEHOLDER) :]) + else: + is_stdin = False + + if is_stdin: + if src.suffix == ".pyi": + mode = replace(mode, is_pyi=True) + elif src.suffix == ".ipynb": + mode = replace(mode, is_ipynb=True) + if format_stdin_to_stdout( + fast=fast, write_back=write_back, mode=mode, lines=lines + ): + changed = Changed.YES + else: + cache = Cache.read(mode) + if write_back not in (WriteBack.DIFF, WriteBack.COLOR_DIFF): + if not cache.is_changed(src): + changed = Changed.CACHED + if changed is not Changed.CACHED and format_file_in_place( + src, fast=fast, write_back=write_back, mode=mode, lines=lines + ): + changed = Changed.YES + if (write_back is WriteBack.YES and changed is not Changed.CACHED) or ( + write_back is WriteBack.CHECK and changed is Changed.NO + ): + cache.write([src]) + report.done(src, changed) + except Exception as exc: + if report.verbose: + traceback.print_exc() + report.failed(src, str(exc)) + + +def format_file_in_place( + src: Path, + fast: bool, + mode: Mode, + write_back: WriteBack = WriteBack.NO, + lock: Any = None, # multiprocessing.Manager().Lock() is some crazy proxy + *, + lines: Collection[Tuple[int, int]] = (), +) -> bool: + """Format file under `src` path. Return True if changed. + + If `write_back` is DIFF, write a diff to stdout. If it is YES, write reformatted + code to the file. + `mode` and `fast` options are passed to :func:`format_file_contents`. + """ + if src.suffix == ".pyi": + mode = replace(mode, is_pyi=True) + elif src.suffix == ".ipynb": + mode = replace(mode, is_ipynb=True) + + then = datetime.fromtimestamp(src.stat().st_mtime, timezone.utc) + header = b"" + with open(src, "rb") as buf: + if mode.skip_source_first_line: + header = buf.readline() + src_contents, encoding, newline = decode_bytes(buf.read()) + try: + dst_contents = format_file_contents( + src_contents, fast=fast, mode=mode, lines=lines + ) + except NothingChanged: + return False + except JSONDecodeError: + raise ValueError( + f"File '{src}' cannot be parsed as valid Jupyter notebook." + ) from None + src_contents = header.decode(encoding) + src_contents + dst_contents = header.decode(encoding) + dst_contents + + if write_back == WriteBack.YES: + with open(src, "w", encoding=encoding, newline=newline) as f: + f.write(dst_contents) + elif write_back in (WriteBack.DIFF, WriteBack.COLOR_DIFF): + now = datetime.now(timezone.utc) + src_name = f"{src}\t{then}" + dst_name = f"{src}\t{now}" + if mode.is_ipynb: + diff_contents = ipynb_diff(src_contents, dst_contents, src_name, dst_name) + else: + diff_contents = diff(src_contents, dst_contents, src_name, dst_name) + + if write_back == WriteBack.COLOR_DIFF: + diff_contents = color_diff(diff_contents) + + with lock or nullcontext(): + f = io.TextIOWrapper( + sys.stdout.buffer, + encoding=encoding, + newline=newline, + write_through=True, + ) + f = wrap_stream_for_windows(f) + f.write(diff_contents) + f.detach() + + return True + + +def format_stdin_to_stdout( + fast: bool, + *, + content: Optional[str] = None, + write_back: WriteBack = WriteBack.NO, + mode: Mode, + lines: Collection[Tuple[int, int]] = (), +) -> bool: + """Format file on stdin. Return True if changed. + + If content is None, it's read from sys.stdin. + + If `write_back` is YES, write reformatted code back to stdout. If it is DIFF, + write a diff to stdout. The `mode` argument is passed to + :func:`format_file_contents`. + """ + then = datetime.now(timezone.utc) + + if content is None: + src, encoding, newline = decode_bytes(sys.stdin.buffer.read()) + else: + src, encoding, newline = content, "utf-8", "" + + dst = src + try: + dst = format_file_contents(src, fast=fast, mode=mode, lines=lines) + return True + + except NothingChanged: + return False + + finally: + f = io.TextIOWrapper( + sys.stdout.buffer, encoding=encoding, newline=newline, write_through=True + ) + if write_back == WriteBack.YES: + # Make sure there's a newline after the content + if dst and dst[-1] != "\n": + dst += "\n" + f.write(dst) + elif write_back in (WriteBack.DIFF, WriteBack.COLOR_DIFF): + now = datetime.now(timezone.utc) + src_name = f"STDIN\t{then}" + dst_name = f"STDOUT\t{now}" + d = diff(src, dst, src_name, dst_name) + if write_back == WriteBack.COLOR_DIFF: + d = color_diff(d) + f = wrap_stream_for_windows(f) + f.write(d) + f.detach() + + +def check_stability_and_equivalence( + src_contents: str, + dst_contents: str, + *, + mode: Mode, + lines: Collection[Tuple[int, int]] = (), +) -> None: + """Perform stability and equivalence checks. + + Raise AssertionError if source and destination contents are not + equivalent, or if a second pass of the formatter would format the + content differently. + """ + assert_equivalent(src_contents, dst_contents) + assert_stable(src_contents, dst_contents, mode=mode, lines=lines) + + +def format_file_contents( + src_contents: str, + *, + fast: bool, + mode: Mode, + lines: Collection[Tuple[int, int]] = (), +) -> FileContent: + """Reformat contents of a file and return new contents. + + If `fast` is False, additionally confirm that the reformatted code is + valid by calling :func:`assert_equivalent` and :func:`assert_stable` on it. + `mode` is passed to :func:`format_str`. + """ + if mode.is_ipynb: + dst_contents = format_ipynb_string(src_contents, fast=fast, mode=mode) + else: + dst_contents = format_str(src_contents, mode=mode, lines=lines) + if src_contents == dst_contents: + raise NothingChanged + + if not fast and not mode.is_ipynb: + # Jupyter notebooks will already have been checked above. + check_stability_and_equivalence( + src_contents, dst_contents, mode=mode, lines=lines + ) + return dst_contents + + +def validate_cell(src: str, mode: Mode) -> None: + """Check that cell does not already contain TransformerManager transformations, + or non-Python cell magics, which might cause tokenizer_rt to break because of + indentations. + + If a cell contains ``!ls``, then it'll be transformed to + ``get_ipython().system('ls')``. However, if the cell originally contained + ``get_ipython().system('ls')``, then it would get transformed in the same way: + + >>> TransformerManager().transform_cell("get_ipython().system('ls')") + "get_ipython().system('ls')\n" + >>> TransformerManager().transform_cell("!ls") + "get_ipython().system('ls')\n" + + Due to the impossibility of safely roundtripping in such situations, cells + containing transformed magics will be ignored. + """ + if any(transformed_magic in src for transformed_magic in TRANSFORMED_MAGICS): + raise NothingChanged + if ( + src[:2] == "%%" + and src.split()[0][2:] not in PYTHON_CELL_MAGICS | mode.python_cell_magics + ): + raise NothingChanged + + +def format_cell(src: str, *, fast: bool, mode: Mode) -> str: + """Format code in given cell of Jupyter notebook. + + General idea is: + + - if cell has trailing semicolon, remove it; + - if cell has IPython magics, mask them; + - format cell; + - reinstate IPython magics; + - reinstate trailing semicolon (if originally present); + - strip trailing newlines. + + Cells with syntax errors will not be processed, as they + could potentially be automagics or multi-line magics, which + are currently not supported. + """ + validate_cell(src, mode) + src_without_trailing_semicolon, has_trailing_semicolon = remove_trailing_semicolon( + src + ) + try: + masked_src, replacements = mask_cell(src_without_trailing_semicolon) + except SyntaxError: + raise NothingChanged from None + masked_dst = format_str(masked_src, mode=mode) + if not fast: + check_stability_and_equivalence(masked_src, masked_dst, mode=mode) + dst_without_trailing_semicolon = unmask_cell(masked_dst, replacements) + dst = put_trailing_semicolon_back( + dst_without_trailing_semicolon, has_trailing_semicolon + ) + dst = dst.rstrip("\n") + if dst == src: + raise NothingChanged from None + return dst + + +def validate_metadata(nb: MutableMapping[str, Any]) -> None: + """If notebook is marked as non-Python, don't format it. + + All notebook metadata fields are optional, see + https://nbformat.readthedocs.io/en/latest/format_description.html. So + if a notebook has empty metadata, we will try to parse it anyway. + """ + language = nb.get("metadata", {}).get("language_info", {}).get("name", None) + if language is not None and language != "python": + raise NothingChanged from None + + +def format_ipynb_string(src_contents: str, *, fast: bool, mode: Mode) -> FileContent: + """Format Jupyter notebook. + + Operate cell-by-cell, only on code cells, only for Python notebooks. + If the ``.ipynb`` originally had a trailing newline, it'll be preserved. + """ + if not src_contents: + raise NothingChanged + + trailing_newline = src_contents[-1] == "\n" + modified = False + nb = json.loads(src_contents) + validate_metadata(nb) + for cell in nb["cells"]: + if cell.get("cell_type", None) == "code": + try: + src = "".join(cell["source"]) + dst = format_cell(src, fast=fast, mode=mode) + except NothingChanged: + pass + else: + cell["source"] = dst.splitlines(keepends=True) + modified = True + if modified: + dst_contents = json.dumps(nb, indent=1, ensure_ascii=False) + if trailing_newline: + dst_contents = dst_contents + "\n" + return dst_contents + else: + raise NothingChanged + + +def format_str( + src_contents: str, *, mode: Mode, lines: Collection[Tuple[int, int]] = () +) -> str: + """Reformat a string and return new contents. + + `mode` determines formatting options, such as how many characters per line are + allowed. Example: + + >>> import black + >>> print(black.format_str("def f(arg:str='')->None:...", mode=black.Mode())) + def f(arg: str = "") -> None: + ... + + A more complex example: + + >>> print( + ... black.format_str( + ... "def f(arg:str='')->None: hey", + ... mode=black.Mode( + ... target_versions={black.TargetVersion.PY36}, + ... line_length=10, + ... string_normalization=False, + ... is_pyi=False, + ... ), + ... ), + ... ) + def f( + arg: str = '', + ) -> None: + hey + + """ + dst_contents = _format_str_once(src_contents, mode=mode, lines=lines) + # Forced second pass to work around optional trailing commas (becoming + # forced trailing commas on pass 2) interacting differently with optional + # parentheses. Admittedly ugly. + if src_contents != dst_contents: + if lines: + lines = adjusted_lines(lines, src_contents, dst_contents) + return _format_str_once(dst_contents, mode=mode, lines=lines) + return dst_contents + + +def _format_str_once( + src_contents: str, *, mode: Mode, lines: Collection[Tuple[int, int]] = () +) -> str: + src_node = lib2to3_parse(src_contents.lstrip(), mode.target_versions) + dst_blocks: List[LinesBlock] = [] + if mode.target_versions: + versions = mode.target_versions + else: + future_imports = get_future_imports(src_node) + versions = detect_target_versions(src_node, future_imports=future_imports) + + context_manager_features = { + feature + for feature in {Feature.PARENTHESIZED_CONTEXT_MANAGERS} + if supports_feature(versions, feature) + } + normalize_fmt_off(src_node, mode, lines) + if lines: + # This should be called after normalize_fmt_off. + convert_unchanged_lines(src_node, lines) + + line_generator = LineGenerator(mode=mode, features=context_manager_features) + elt = EmptyLineTracker(mode=mode) + split_line_features = { + feature + for feature in {Feature.TRAILING_COMMA_IN_CALL, Feature.TRAILING_COMMA_IN_DEF} + if supports_feature(versions, feature) + } + block: Optional[LinesBlock] = None + for current_line in line_generator.visit(src_node): + block = elt.maybe_empty_lines(current_line) + dst_blocks.append(block) + for line in transform_line( + current_line, mode=mode, features=split_line_features + ): + block.content_lines.append(str(line)) + if dst_blocks: + dst_blocks[-1].after = 0 + dst_contents = [] + for block in dst_blocks: + dst_contents.extend(block.all_lines()) + if not dst_contents: + # Use decode_bytes to retrieve the correct source newline (CRLF or LF), + # and check if normalized_content has more than one line + normalized_content, _, newline = decode_bytes(src_contents.encode("utf-8")) + if "\n" in normalized_content: + return newline + return "" + return "".join(dst_contents) + + +def decode_bytes(src: bytes) -> Tuple[FileContent, Encoding, NewLine]: + """Return a tuple of (decoded_contents, encoding, newline). + + `newline` is either CRLF or LF but `decoded_contents` is decoded with + universal newlines (i.e. only contains LF). + """ + srcbuf = io.BytesIO(src) + encoding, lines = tokenize.detect_encoding(srcbuf.readline) + if not lines: + return "", encoding, "\n" + + newline = "\r\n" if b"\r\n" == lines[0][-2:] else "\n" + srcbuf.seek(0) + with io.TextIOWrapper(srcbuf, encoding) as tiow: + return tiow.read(), encoding, newline + + +def get_features_used( # noqa: C901 + node: Node, *, future_imports: Optional[Set[str]] = None +) -> Set[Feature]: + """Return a set of (relatively) new Python features used in this file. + + Currently looking for: + - f-strings; + - self-documenting expressions in f-strings (f"{x=}"); + - underscores in numeric literals; + - trailing commas after * or ** in function signatures and calls; + - positional only arguments in function signatures and lambdas; + - assignment expression; + - relaxed decorator syntax; + - usage of __future__ flags (annotations); + - print / exec statements; + - parenthesized context managers; + - match statements; + - except* clause; + - variadic generics; + """ + features: Set[Feature] = set() + if future_imports: + features |= { + FUTURE_FLAG_TO_FEATURE[future_import] + for future_import in future_imports + if future_import in FUTURE_FLAG_TO_FEATURE + } + + for n in node.pre_order(): + if is_string_token(n): + value_head = n.value[:2] + if value_head in {'f"', 'F"', "f'", "F'", "rf", "fr", "RF", "FR"}: + features.add(Feature.F_STRINGS) + if Feature.DEBUG_F_STRINGS not in features: + for span_beg, span_end in iter_fexpr_spans(n.value): + if n.value[span_beg : span_end - 1].rstrip().endswith("="): + features.add(Feature.DEBUG_F_STRINGS) + break + + elif is_number_token(n): + if "_" in n.value: + features.add(Feature.NUMERIC_UNDERSCORES) + + elif n.type == token.SLASH: + if n.parent and n.parent.type in { + syms.typedargslist, + syms.arglist, + syms.varargslist, + }: + features.add(Feature.POS_ONLY_ARGUMENTS) + + elif n.type == token.COLONEQUAL: + features.add(Feature.ASSIGNMENT_EXPRESSIONS) + + elif n.type == syms.decorator: + if len(n.children) > 1 and not is_simple_decorator_expression( + n.children[1] + ): + features.add(Feature.RELAXED_DECORATORS) + + elif ( + n.type in {syms.typedargslist, syms.arglist} + and n.children + and n.children[-1].type == token.COMMA + ): + if n.type == syms.typedargslist: + feature = Feature.TRAILING_COMMA_IN_DEF + else: + feature = Feature.TRAILING_COMMA_IN_CALL + + for ch in n.children: + if ch.type in STARS: + features.add(feature) + + if ch.type == syms.argument: + for argch in ch.children: + if argch.type in STARS: + features.add(feature) + + elif ( + n.type in {syms.return_stmt, syms.yield_expr} + and len(n.children) >= 2 + and n.children[1].type == syms.testlist_star_expr + and any(child.type == syms.star_expr for child in n.children[1].children) + ): + features.add(Feature.UNPACKING_ON_FLOW) + + elif ( + n.type == syms.annassign + and len(n.children) >= 4 + and n.children[3].type == syms.testlist_star_expr + ): + features.add(Feature.ANN_ASSIGN_EXTENDED_RHS) + + elif ( + n.type == syms.with_stmt + and len(n.children) > 2 + and n.children[1].type == syms.atom + ): + atom_children = n.children[1].children + if ( + len(atom_children) == 3 + and atom_children[0].type == token.LPAR + and _contains_asexpr(atom_children[1]) + and atom_children[2].type == token.RPAR + ): + features.add(Feature.PARENTHESIZED_CONTEXT_MANAGERS) + + elif n.type == syms.match_stmt: + features.add(Feature.PATTERN_MATCHING) + + elif ( + n.type == syms.except_clause + and len(n.children) >= 2 + and n.children[1].type == token.STAR + ): + features.add(Feature.EXCEPT_STAR) + + elif n.type in {syms.subscriptlist, syms.trailer} and any( + child.type == syms.star_expr for child in n.children + ): + features.add(Feature.VARIADIC_GENERICS) + + elif ( + n.type == syms.tname_star + and len(n.children) == 3 + and n.children[2].type == syms.star_expr + ): + features.add(Feature.VARIADIC_GENERICS) + + elif n.type in (syms.type_stmt, syms.typeparams): + features.add(Feature.TYPE_PARAMS) + + return features + + +def _contains_asexpr(node: Union[Node, Leaf]) -> bool: + """Return True if `node` contains an as-pattern.""" + if node.type == syms.asexpr_test: + return True + elif node.type == syms.atom: + if ( + len(node.children) == 3 + and node.children[0].type == token.LPAR + and node.children[2].type == token.RPAR + ): + return _contains_asexpr(node.children[1]) + elif node.type == syms.testlist_gexp: + return any(_contains_asexpr(child) for child in node.children) + return False + + +def detect_target_versions( + node: Node, *, future_imports: Optional[Set[str]] = None +) -> Set[TargetVersion]: + """Detect the version to target based on the nodes used.""" + features = get_features_used(node, future_imports=future_imports) + return { + version for version in TargetVersion if features <= VERSION_TO_FEATURES[version] + } + + +def get_future_imports(node: Node) -> Set[str]: + """Return a set of __future__ imports in the file.""" + imports: Set[str] = set() + + def get_imports_from_children(children: List[LN]) -> Generator[str, None, None]: + for child in children: + if isinstance(child, Leaf): + if child.type == token.NAME: + yield child.value + + elif child.type == syms.import_as_name: + orig_name = child.children[0] + assert isinstance(orig_name, Leaf), "Invalid syntax parsing imports" + assert orig_name.type == token.NAME, "Invalid syntax parsing imports" + yield orig_name.value + + elif child.type == syms.import_as_names: + yield from get_imports_from_children(child.children) + + else: + raise AssertionError("Invalid syntax parsing imports") + + for child in node.children: + if child.type != syms.simple_stmt: + break + + first_child = child.children[0] + if isinstance(first_child, Leaf): + # Continue looking if we see a docstring; otherwise stop. + if ( + len(child.children) == 2 + and first_child.type == token.STRING + and child.children[1].type == token.NEWLINE + ): + continue + + break + + elif first_child.type == syms.import_from: + module_name = first_child.children[1] + if not isinstance(module_name, Leaf) or module_name.value != "__future__": + break + + imports |= set(get_imports_from_children(first_child.children[3:])) + else: + break + + return imports + + +def assert_equivalent(src: str, dst: str) -> None: + """Raise AssertionError if `src` and `dst` aren't equivalent.""" + try: + src_ast = parse_ast(src) + except Exception as exc: + raise AssertionError( + "cannot use --safe with this file; failed to parse source file AST: " + f"{exc}\n" + "This could be caused by running Black with an older Python version " + "that does not support new syntax used in your source file." + ) from exc + + try: + dst_ast = parse_ast(dst) + except Exception as exc: + log = dump_to_file("".join(traceback.format_tb(exc.__traceback__)), dst) + raise AssertionError( + f"INTERNAL ERROR: Black produced invalid code: {exc}. " + "Please report a bug on https://github.com/psf/black/issues. " + f"This invalid output might be helpful: {log}" + ) from None + + src_ast_str = "\n".join(stringify_ast(src_ast)) + dst_ast_str = "\n".join(stringify_ast(dst_ast)) + if src_ast_str != dst_ast_str: + log = dump_to_file(diff(src_ast_str, dst_ast_str, "src", "dst")) + raise AssertionError( + "INTERNAL ERROR: Black produced code that is not equivalent to the" + " source. Please report a bug on " + f"https://github.com/psf/black/issues. This diff might be helpful: {log}" + ) from None + + +def assert_stable( + src: str, dst: str, mode: Mode, *, lines: Collection[Tuple[int, int]] = () +) -> None: + """Raise AssertionError if `dst` reformats differently the second time.""" + if lines: + # Formatting specified lines requires `adjusted_lines` to map original lines + # to the formatted lines before re-formatting the previously formatted result. + # Due to less-ideal diff algorithm, some edge cases produce incorrect new line + # ranges. Hence for now, we skip the stable check. + # See https://github.com/psf/black/issues/4033 for context. + return + # We shouldn't call format_str() here, because that formats the string + # twice and may hide a bug where we bounce back and forth between two + # versions. + newdst = _format_str_once(dst, mode=mode, lines=lines) + if dst != newdst: + log = dump_to_file( + str(mode), + diff(src, dst, "source", "first pass"), + diff(dst, newdst, "first pass", "second pass"), + ) + raise AssertionError( + "INTERNAL ERROR: Black produced different code on the second pass of the" + " formatter. Please report a bug on https://github.com/psf/black/issues." + f" This diff might be helpful: {log}" + ) from None + + +@contextmanager +def nullcontext() -> Iterator[None]: + """Return an empty context manager. + + To be used like `nullcontext` in Python 3.7. + """ + yield + + +def patched_main() -> None: + # PyInstaller patches multiprocessing to need freeze_support() even in non-Windows + # environments so just assume we always need to call it if frozen. + if getattr(sys, "frozen", False): + from multiprocessing import freeze_support + + freeze_support() + + main() + + +if __name__ == "__main__": + patched_main() diff --git a/dbdpy-env/lib/python3.9/site-packages/black/__main__.py b/dbdpy-env/lib/python3.9/site-packages/black/__main__.py new file mode 100644 index 00000000..19b810b5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/__main__.py @@ -0,0 +1,3 @@ +from black import patched_main + +patched_main() diff --git a/dbdpy-env/lib/python3.9/site-packages/black/_width_table.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/_width_table.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..a8e5d3ae2a44ea0922d9bd684434b18cd9bf59d6 GIT binary patch literal 50142 zcmeI*ZERCj7zgmD?YdRjVCWJCVpdUM5E*Y9+l*o5Wnl|CUbdJ;#glfoWer_B+B;_f z<1it{7~@Qcfyf7BiAsWTAp<31=t2aeiGs@Tm5>+>d?1m;4?-OCdG0-TYm30AeK7f- zUoLXx^FcF)R!G9l`?xmsqvxwd<6~m)FXO@#M$|L zIv>BgRqTAKGaTytt>8I5nz>+|y&I^QNe@5DOH&CP>K z^~8IlaYIGpk%SfJejlIcd`&um#5w1466;pJ*S%boTC=ikrCPndrPcm+1A4)2S`SZ4 zl^>W=u1al5WPPo-%_l!wRteb8>xc@uBl(;n=eo?*K9@7fZJ+K3bek7D=W^azsaQ~@ z(p{lMOm&;d+vY3R=_G&lIf{6^z?tJ#DI;hGCkFD*SKepOIqxZPcD{)x?Vh}+d{;_6 z+1#?OaZR)HyOpu$DWF>&U)0IOU8+;&u*_l!GWPGUkK6Hg;$c6>vQH!yjedoOSiurt?dA z%+FQ!AmUwJC05^hJy*470guYhl~d&RvyQ9elJgMF<3B4dTGW$DE{a7%Qd`q0Gu&0R zs>(=nWG$k(+(@3i8QW#Pj^(|jJjhk%2l@O}c48SufdB*`009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=|4V_<9VZWsdg!gdJycrZ_ncowv?t)EAs+><`@D3G@4#N?E1GS7J@2BvP4jq- z-$g^CJBB|Xsun0x#_`+1qKka%qDDBni?R@P)ZYQ))xF9}=w@SWNJ+~<;aB2P)) zKGQh9R4_5mmq%~eN8aIVk-MGT6(iCg%(Vv$MHM$!_H;tK6NhmX@nm-wT(%+_5d@CrhoTIk@xHUTXn9 zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5SV-c=l`{@*8fgGK(~{>Gj@Og z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG|A5tu%QTBScdV5DP)N|`+&6^h1< zaFRA|qkc-#ih$aXULEXC^~A!exvM*oG-cdpjoYyvekx(`8ksERNq$PL2?t}bL z=9kJ{b2Ib8&mL=9@a`ACHSGHE<-8?w>w;z3H{b z-oM*?!*|csZGLB8{qZ9;M*qoGKOUcQer#WB(|a3--}vgpo@tT0JwMs=pI<3Fac@zk z_mw|7|32{PLj(Q44tza2@Xy-X_?)c=hmX`w_Wp;y92k82>7tfvkM0{;UK>4jblsWC SS5MEF5t!}$>&&V0ng0R;Z9C@x literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/_width_table.py b/dbdpy-env/lib/python3.9/site-packages/black/_width_table.py new file mode 100644 index 00000000..f3304e48 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/_width_table.py @@ -0,0 +1,478 @@ +# Generated by make_width_table.py +# wcwidth 0.2.6 +# Unicode 15.0.0 +from typing import Final, List, Tuple + +WIDTH_TABLE: Final[List[Tuple[int, int, int]]] = [ + (0, 0, 0), + (1, 31, -1), + (127, 159, -1), + (768, 879, 0), + (1155, 1161, 0), + (1425, 1469, 0), + (1471, 1471, 0), + (1473, 1474, 0), + (1476, 1477, 0), + (1479, 1479, 0), + (1552, 1562, 0), + (1611, 1631, 0), + (1648, 1648, 0), + (1750, 1756, 0), + (1759, 1764, 0), + (1767, 1768, 0), + (1770, 1773, 0), + (1809, 1809, 0), + (1840, 1866, 0), + (1958, 1968, 0), + (2027, 2035, 0), + (2045, 2045, 0), + (2070, 2073, 0), + (2075, 2083, 0), + (2085, 2087, 0), + (2089, 2093, 0), + (2137, 2139, 0), + (2200, 2207, 0), + (2250, 2273, 0), + (2275, 2306, 0), + (2362, 2362, 0), + (2364, 2364, 0), + (2369, 2376, 0), + (2381, 2381, 0), + (2385, 2391, 0), + (2402, 2403, 0), + (2433, 2433, 0), + (2492, 2492, 0), + (2497, 2500, 0), + (2509, 2509, 0), + (2530, 2531, 0), + (2558, 2558, 0), + (2561, 2562, 0), + (2620, 2620, 0), + (2625, 2626, 0), + (2631, 2632, 0), + (2635, 2637, 0), + (2641, 2641, 0), + (2672, 2673, 0), + (2677, 2677, 0), + (2689, 2690, 0), + (2748, 2748, 0), + (2753, 2757, 0), + (2759, 2760, 0), + (2765, 2765, 0), + (2786, 2787, 0), + (2810, 2815, 0), + (2817, 2817, 0), + (2876, 2876, 0), + (2879, 2879, 0), + (2881, 2884, 0), + (2893, 2893, 0), + (2901, 2902, 0), + (2914, 2915, 0), + (2946, 2946, 0), + (3008, 3008, 0), + (3021, 3021, 0), + (3072, 3072, 0), + (3076, 3076, 0), + (3132, 3132, 0), + (3134, 3136, 0), + (3142, 3144, 0), + (3146, 3149, 0), + (3157, 3158, 0), + (3170, 3171, 0), + (3201, 3201, 0), + (3260, 3260, 0), + (3263, 3263, 0), + (3270, 3270, 0), + (3276, 3277, 0), + (3298, 3299, 0), + (3328, 3329, 0), + (3387, 3388, 0), + (3393, 3396, 0), + (3405, 3405, 0), + (3426, 3427, 0), + (3457, 3457, 0), + (3530, 3530, 0), + (3538, 3540, 0), + (3542, 3542, 0), + (3633, 3633, 0), + (3636, 3642, 0), + (3655, 3662, 0), + (3761, 3761, 0), + (3764, 3772, 0), + (3784, 3790, 0), + (3864, 3865, 0), + (3893, 3893, 0), + (3895, 3895, 0), + (3897, 3897, 0), + (3953, 3966, 0), + (3968, 3972, 0), + (3974, 3975, 0), + (3981, 3991, 0), + (3993, 4028, 0), + (4038, 4038, 0), + (4141, 4144, 0), + (4146, 4151, 0), + (4153, 4154, 0), + (4157, 4158, 0), + (4184, 4185, 0), + (4190, 4192, 0), + (4209, 4212, 0), + (4226, 4226, 0), + (4229, 4230, 0), + (4237, 4237, 0), + (4253, 4253, 0), + (4352, 4447, 2), + (4957, 4959, 0), + (5906, 5908, 0), + (5938, 5939, 0), + (5970, 5971, 0), + (6002, 6003, 0), + (6068, 6069, 0), + (6071, 6077, 0), + (6086, 6086, 0), + (6089, 6099, 0), + (6109, 6109, 0), + (6155, 6157, 0), + (6159, 6159, 0), + (6277, 6278, 0), + (6313, 6313, 0), + (6432, 6434, 0), + (6439, 6440, 0), + (6450, 6450, 0), + (6457, 6459, 0), + (6679, 6680, 0), + (6683, 6683, 0), + (6742, 6742, 0), + (6744, 6750, 0), + (6752, 6752, 0), + (6754, 6754, 0), + (6757, 6764, 0), + (6771, 6780, 0), + (6783, 6783, 0), + (6832, 6862, 0), + (6912, 6915, 0), + (6964, 6964, 0), + (6966, 6970, 0), + (6972, 6972, 0), + (6978, 6978, 0), + (7019, 7027, 0), + (7040, 7041, 0), + (7074, 7077, 0), + (7080, 7081, 0), + (7083, 7085, 0), + (7142, 7142, 0), + (7144, 7145, 0), + (7149, 7149, 0), + (7151, 7153, 0), + (7212, 7219, 0), + (7222, 7223, 0), + (7376, 7378, 0), + (7380, 7392, 0), + (7394, 7400, 0), + (7405, 7405, 0), + (7412, 7412, 0), + (7416, 7417, 0), + (7616, 7679, 0), + (8203, 8207, 0), + (8232, 8238, 0), + (8288, 8291, 0), + (8400, 8432, 0), + (8986, 8987, 2), + (9001, 9002, 2), + (9193, 9196, 2), + (9200, 9200, 2), + (9203, 9203, 2), + (9725, 9726, 2), + (9748, 9749, 2), + (9800, 9811, 2), + (9855, 9855, 2), + (9875, 9875, 2), + (9889, 9889, 2), + (9898, 9899, 2), + (9917, 9918, 2), + (9924, 9925, 2), + (9934, 9934, 2), + (9940, 9940, 2), + (9962, 9962, 2), + (9970, 9971, 2), + (9973, 9973, 2), + (9978, 9978, 2), + (9981, 9981, 2), + (9989, 9989, 2), + (9994, 9995, 2), + (10024, 10024, 2), + (10060, 10060, 2), + (10062, 10062, 2), + (10067, 10069, 2), + (10071, 10071, 2), + (10133, 10135, 2), + (10160, 10160, 2), + (10175, 10175, 2), + (11035, 11036, 2), + (11088, 11088, 2), + (11093, 11093, 2), + (11503, 11505, 0), + (11647, 11647, 0), + (11744, 11775, 0), + (11904, 11929, 2), + (11931, 12019, 2), + (12032, 12245, 2), + (12272, 12283, 2), + (12288, 12329, 2), + (12330, 12333, 0), + (12334, 12350, 2), + (12353, 12438, 2), + (12441, 12442, 0), + (12443, 12543, 2), + (12549, 12591, 2), + (12593, 12686, 2), + (12688, 12771, 2), + (12784, 12830, 2), + (12832, 12871, 2), + (12880, 19903, 2), + (19968, 42124, 2), + (42128, 42182, 2), + (42607, 42610, 0), + (42612, 42621, 0), + (42654, 42655, 0), + (42736, 42737, 0), + (43010, 43010, 0), + (43014, 43014, 0), + (43019, 43019, 0), + (43045, 43046, 0), + (43052, 43052, 0), + (43204, 43205, 0), + (43232, 43249, 0), + (43263, 43263, 0), + (43302, 43309, 0), + (43335, 43345, 0), + (43360, 43388, 2), + (43392, 43394, 0), + (43443, 43443, 0), + (43446, 43449, 0), + (43452, 43453, 0), + (43493, 43493, 0), + (43561, 43566, 0), + (43569, 43570, 0), + (43573, 43574, 0), + (43587, 43587, 0), + (43596, 43596, 0), + (43644, 43644, 0), + (43696, 43696, 0), + (43698, 43700, 0), + (43703, 43704, 0), + (43710, 43711, 0), + (43713, 43713, 0), + (43756, 43757, 0), + (43766, 43766, 0), + (44005, 44005, 0), + (44008, 44008, 0), + (44013, 44013, 0), + (44032, 55203, 2), + (63744, 64255, 2), + (64286, 64286, 0), + (65024, 65039, 0), + (65040, 65049, 2), + (65056, 65071, 0), + (65072, 65106, 2), + (65108, 65126, 2), + (65128, 65131, 2), + (65281, 65376, 2), + (65504, 65510, 2), + (66045, 66045, 0), + (66272, 66272, 0), + (66422, 66426, 0), + (68097, 68099, 0), + (68101, 68102, 0), + (68108, 68111, 0), + (68152, 68154, 0), + (68159, 68159, 0), + (68325, 68326, 0), + (68900, 68903, 0), + (69291, 69292, 0), + (69373, 69375, 0), + (69446, 69456, 0), + (69506, 69509, 0), + (69633, 69633, 0), + (69688, 69702, 0), + (69744, 69744, 0), + (69747, 69748, 0), + (69759, 69761, 0), + (69811, 69814, 0), + (69817, 69818, 0), + (69826, 69826, 0), + (69888, 69890, 0), + (69927, 69931, 0), + (69933, 69940, 0), + (70003, 70003, 0), + (70016, 70017, 0), + (70070, 70078, 0), + (70089, 70092, 0), + (70095, 70095, 0), + (70191, 70193, 0), + (70196, 70196, 0), + (70198, 70199, 0), + (70206, 70206, 0), + (70209, 70209, 0), + (70367, 70367, 0), + (70371, 70378, 0), + (70400, 70401, 0), + (70459, 70460, 0), + (70464, 70464, 0), + (70502, 70508, 0), + (70512, 70516, 0), + (70712, 70719, 0), + (70722, 70724, 0), + (70726, 70726, 0), + (70750, 70750, 0), + (70835, 70840, 0), + (70842, 70842, 0), + (70847, 70848, 0), + (70850, 70851, 0), + (71090, 71093, 0), + (71100, 71101, 0), + (71103, 71104, 0), + (71132, 71133, 0), + (71219, 71226, 0), + (71229, 71229, 0), + (71231, 71232, 0), + (71339, 71339, 0), + (71341, 71341, 0), + (71344, 71349, 0), + (71351, 71351, 0), + (71453, 71455, 0), + (71458, 71461, 0), + (71463, 71467, 0), + (71727, 71735, 0), + (71737, 71738, 0), + (71995, 71996, 0), + (71998, 71998, 0), + (72003, 72003, 0), + (72148, 72151, 0), + (72154, 72155, 0), + (72160, 72160, 0), + (72193, 72202, 0), + (72243, 72248, 0), + (72251, 72254, 0), + (72263, 72263, 0), + (72273, 72278, 0), + (72281, 72283, 0), + (72330, 72342, 0), + (72344, 72345, 0), + (72752, 72758, 0), + (72760, 72765, 0), + (72767, 72767, 0), + (72850, 72871, 0), + (72874, 72880, 0), + (72882, 72883, 0), + (72885, 72886, 0), + (73009, 73014, 0), + (73018, 73018, 0), + (73020, 73021, 0), + (73023, 73029, 0), + (73031, 73031, 0), + (73104, 73105, 0), + (73109, 73109, 0), + (73111, 73111, 0), + (73459, 73460, 0), + (73472, 73473, 0), + (73526, 73530, 0), + (73536, 73536, 0), + (73538, 73538, 0), + (78912, 78912, 0), + (78919, 78933, 0), + (92912, 92916, 0), + (92976, 92982, 0), + (94031, 94031, 0), + (94095, 94098, 0), + (94176, 94179, 2), + (94180, 94180, 0), + (94192, 94193, 2), + (94208, 100343, 2), + (100352, 101589, 2), + (101632, 101640, 2), + (110576, 110579, 2), + (110581, 110587, 2), + (110589, 110590, 2), + (110592, 110882, 2), + (110898, 110898, 2), + (110928, 110930, 2), + (110933, 110933, 2), + (110948, 110951, 2), + (110960, 111355, 2), + (113821, 113822, 0), + (118528, 118573, 0), + (118576, 118598, 0), + (119143, 119145, 0), + (119163, 119170, 0), + (119173, 119179, 0), + (119210, 119213, 0), + (119362, 119364, 0), + (121344, 121398, 0), + (121403, 121452, 0), + (121461, 121461, 0), + (121476, 121476, 0), + (121499, 121503, 0), + (121505, 121519, 0), + (122880, 122886, 0), + (122888, 122904, 0), + (122907, 122913, 0), + (122915, 122916, 0), + (122918, 122922, 0), + (123023, 123023, 0), + (123184, 123190, 0), + (123566, 123566, 0), + (123628, 123631, 0), + (124140, 124143, 0), + (125136, 125142, 0), + (125252, 125258, 0), + (126980, 126980, 2), + (127183, 127183, 2), + (127374, 127374, 2), + (127377, 127386, 2), + (127488, 127490, 2), + (127504, 127547, 2), + (127552, 127560, 2), + (127568, 127569, 2), + (127584, 127589, 2), + (127744, 127776, 2), + (127789, 127797, 2), + (127799, 127868, 2), + (127870, 127891, 2), + (127904, 127946, 2), + (127951, 127955, 2), + (127968, 127984, 2), + (127988, 127988, 2), + (127992, 128062, 2), + (128064, 128064, 2), + (128066, 128252, 2), + (128255, 128317, 2), + (128331, 128334, 2), + (128336, 128359, 2), + (128378, 128378, 2), + (128405, 128406, 2), + (128420, 128420, 2), + (128507, 128591, 2), + (128640, 128709, 2), + (128716, 128716, 2), + (128720, 128722, 2), + (128725, 128727, 2), + (128732, 128735, 2), + (128747, 128748, 2), + (128756, 128764, 2), + (128992, 129003, 2), + (129008, 129008, 2), + (129292, 129338, 2), + (129340, 129349, 2), + (129351, 129535, 2), + (129648, 129660, 2), + (129664, 129672, 2), + (129680, 129725, 2), + (129727, 129733, 2), + (129742, 129755, 2), + (129760, 129768, 2), + (129776, 129784, 2), + (131072, 196605, 2), + (196608, 262141, 2), + (917760, 917999, 0), +] diff --git a/dbdpy-env/lib/python3.9/site-packages/black/brackets.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/brackets.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..edd9246d0dff4844bab7dfe0f6852c6f86552508 GIT binary patch literal 50138 zcmeI*TWnNC7zglgFKxHj!d7doQRs#MjR@sZF2xwSNE;|}ZTF$khjF*NrJHVdm)%ov zrN+JxLr{WAW11MCZ$hGm7)$^~7Gu0bjT8hGywsQ&l$Z#_M4CYTzH{cZyNke6A58v} z%+7o>bH17L+qQ25UyuHItBlA&Ts&N-a=q*(+9d;A9_IQT&ngvYZV#A4`5*rLkaS$c z!*-PwN*R&o4e42>Fkiz;Yy6C!m)NQMX5*&*+)$~s(HlyS4;AL~G+I-$^a_b{^LcbW zes{B2`BYaVmW-r$q%hw+o$pD#UgF$*bldql(ncy8->TOa=Ihe=HtKmh)?t2b9#pC~ zz9SkBt7yD4VaEC2$1$C6txh0u-udjrx|Q#BkgHNns{*Uk>P;KltZ&z^7u=zB@w8O= zf$?%xYHK3rYrSJW`Pnjy-+Eq0RLmX8XBRowWv``v}b>FYsg4jNn{mx3of-0Tq z2_<4GX{7F$uUe;*{JG~S;c>S;$E{M~pb?xHC_Gdzh=srq2ij4HL5$9!C6 z4xQEv9l*K;g!&E-+~xw4D=el~EGTyh?wTK==*pas3@)Ph(vB(*J*HX=QBPt}Dp z9GQz~4mXl#Fl)Iyrek?;Dbu;i{1HC?Tr05*qd))x5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa zf&Z<*&7G$X-*nMy{!;SR_+01fi3a>mI_e?+4NnnW<$JI<_?l+Gr{^8i-&)ISd=5H# zbLZ(pL^T)qPUe8mV?8hPH4=}Fy~j6F&&rytOI@({;fuoNK74QXKld3an#faLu+KD( zN8A(he1Y_~edHaElsMbTS#v@9`*Qk8-RJwU)%;$S@})_i^Hj>cRO#~-(#oaW-%{)} z&-vGyQ->vww}{M~%NDO_SX$p1?(AH=Y*8fKup+d4iBdh8WTu1eGFKOkM-3H<1v|Qx zQlS*L5kqdh%l+9$xk|}x5gywv3%{BFt-K(#wx+6xKYF%`!&pg_(zAm%v=Fh1fqUwG#Bqul197IDat@r^Q zH|Tg4$2@(@nk8CR5N{}mpRr&+Nc0}WK=>%OXx!ycwNAo{tTCXfRu>aGCE`9Xb z8uzUy?%y-=!@=*YlG--}vkCX9KOt)irb0 z?Y{Ek%-YS3>FN{bcGj%_a@{Z60uR13+52Ce;rM%SL2}AK)gL9_9D0BH8{U^o_qSc& OwRg|SYo)I)|LtF@EHsM% literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/brackets.py b/dbdpy-env/lib/python3.9/site-packages/black/brackets.py new file mode 100644 index 00000000..3020cc0d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/brackets.py @@ -0,0 +1,382 @@ +"""Builds on top of nodes.py to track brackets.""" + +from dataclasses import dataclass, field +from typing import Dict, Final, Iterable, List, Optional, Sequence, Set, Tuple, Union + +from black.nodes import ( + BRACKET, + CLOSING_BRACKETS, + COMPARATORS, + LOGIC_OPERATORS, + MATH_OPERATORS, + OPENING_BRACKETS, + UNPACKING_PARENTS, + VARARGS_PARENTS, + is_vararg, + syms, +) +from blib2to3.pgen2 import token +from blib2to3.pytree import Leaf, Node + +# types +LN = Union[Leaf, Node] +Depth = int +LeafID = int +NodeType = int +Priority = int + + +COMPREHENSION_PRIORITY: Final = 20 +COMMA_PRIORITY: Final = 18 +TERNARY_PRIORITY: Final = 16 +LOGIC_PRIORITY: Final = 14 +STRING_PRIORITY: Final = 12 +COMPARATOR_PRIORITY: Final = 10 +MATH_PRIORITIES: Final = { + token.VBAR: 9, + token.CIRCUMFLEX: 8, + token.AMPER: 7, + token.LEFTSHIFT: 6, + token.RIGHTSHIFT: 6, + token.PLUS: 5, + token.MINUS: 5, + token.STAR: 4, + token.SLASH: 4, + token.DOUBLESLASH: 4, + token.PERCENT: 4, + token.AT: 4, + token.TILDE: 3, + token.DOUBLESTAR: 2, +} +DOT_PRIORITY: Final = 1 + + +class BracketMatchError(Exception): + """Raised when an opening bracket is unable to be matched to a closing bracket.""" + + +@dataclass +class BracketTracker: + """Keeps track of brackets on a line.""" + + depth: int = 0 + bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = field(default_factory=dict) + delimiters: Dict[LeafID, Priority] = field(default_factory=dict) + previous: Optional[Leaf] = None + _for_loop_depths: List[int] = field(default_factory=list) + _lambda_argument_depths: List[int] = field(default_factory=list) + invisible: List[Leaf] = field(default_factory=list) + + def mark(self, leaf: Leaf) -> None: + """Mark `leaf` with bracket-related metadata. Keep track of delimiters. + + All leaves receive an int `bracket_depth` field that stores how deep + within brackets a given leaf is. 0 means there are no enclosing brackets + that started on this line. + + If a leaf is itself a closing bracket and there is a matching opening + bracket earlier, it receives an `opening_bracket` field with which it forms a + pair. This is a one-directional link to avoid reference cycles. Closing + bracket without opening happens on lines continued from previous + breaks, e.g. `) -> "ReturnType":` as part of a funcdef where we place + the return type annotation on its own line of the previous closing RPAR. + + If a leaf is a delimiter (a token on which Black can split the line if + needed) and it's on depth 0, its `id()` is stored in the tracker's + `delimiters` field. + """ + if leaf.type == token.COMMENT: + return + + if ( + self.depth == 0 + and leaf.type in CLOSING_BRACKETS + and (self.depth, leaf.type) not in self.bracket_match + ): + return + + self.maybe_decrement_after_for_loop_variable(leaf) + self.maybe_decrement_after_lambda_arguments(leaf) + if leaf.type in CLOSING_BRACKETS: + self.depth -= 1 + try: + opening_bracket = self.bracket_match.pop((self.depth, leaf.type)) + except KeyError as e: + raise BracketMatchError( + "Unable to match a closing bracket to the following opening" + f" bracket: {leaf}" + ) from e + leaf.opening_bracket = opening_bracket + if not leaf.value: + self.invisible.append(leaf) + leaf.bracket_depth = self.depth + if self.depth == 0: + delim = is_split_before_delimiter(leaf, self.previous) + if delim and self.previous is not None: + self.delimiters[id(self.previous)] = delim + else: + delim = is_split_after_delimiter(leaf, self.previous) + if delim: + self.delimiters[id(leaf)] = delim + if leaf.type in OPENING_BRACKETS: + self.bracket_match[self.depth, BRACKET[leaf.type]] = leaf + self.depth += 1 + if not leaf.value: + self.invisible.append(leaf) + self.previous = leaf + self.maybe_increment_lambda_arguments(leaf) + self.maybe_increment_for_loop_variable(leaf) + + def any_open_for_or_lambda(self) -> bool: + """Return True if there is an open for or lambda expression on the line. + + See maybe_increment_for_loop_variable and maybe_increment_lambda_arguments + for details.""" + return bool(self._for_loop_depths or self._lambda_argument_depths) + + def any_open_brackets(self) -> bool: + """Return True if there is an yet unmatched open bracket on the line.""" + return bool(self.bracket_match) + + def max_delimiter_priority(self, exclude: Iterable[LeafID] = ()) -> Priority: + """Return the highest priority of a delimiter found on the line. + + Values are consistent with what `is_split_*_delimiter()` return. + Raises ValueError on no delimiters. + """ + return max(v for k, v in self.delimiters.items() if k not in exclude) + + def delimiter_count_with_priority(self, priority: Priority = 0) -> int: + """Return the number of delimiters with the given `priority`. + + If no `priority` is passed, defaults to max priority on the line. + """ + if not self.delimiters: + return 0 + + priority = priority or self.max_delimiter_priority() + return sum(1 for p in self.delimiters.values() if p == priority) + + def maybe_increment_for_loop_variable(self, leaf: Leaf) -> bool: + """In a for loop, or comprehension, the variables are often unpacks. + + To avoid splitting on the comma in this situation, increase the depth of + tokens between `for` and `in`. + """ + if leaf.type == token.NAME and leaf.value == "for": + self.depth += 1 + self._for_loop_depths.append(self.depth) + return True + + return False + + def maybe_decrement_after_for_loop_variable(self, leaf: Leaf) -> bool: + """See `maybe_increment_for_loop_variable` above for explanation.""" + if ( + self._for_loop_depths + and self._for_loop_depths[-1] == self.depth + and leaf.type == token.NAME + and leaf.value == "in" + ): + self.depth -= 1 + self._for_loop_depths.pop() + return True + + return False + + def maybe_increment_lambda_arguments(self, leaf: Leaf) -> bool: + """In a lambda expression, there might be more than one argument. + + To avoid splitting on the comma in this situation, increase the depth of + tokens between `lambda` and `:`. + """ + if leaf.type == token.NAME and leaf.value == "lambda": + self.depth += 1 + self._lambda_argument_depths.append(self.depth) + return True + + return False + + def maybe_decrement_after_lambda_arguments(self, leaf: Leaf) -> bool: + """See `maybe_increment_lambda_arguments` above for explanation.""" + if ( + self._lambda_argument_depths + and self._lambda_argument_depths[-1] == self.depth + and leaf.type == token.COLON + ): + self.depth -= 1 + self._lambda_argument_depths.pop() + return True + + return False + + def get_open_lsqb(self) -> Optional[Leaf]: + """Return the most recent opening square bracket (if any).""" + return self.bracket_match.get((self.depth - 1, token.RSQB)) + + +def is_split_after_delimiter(leaf: Leaf, previous: Optional[Leaf] = None) -> Priority: + """Return the priority of the `leaf` delimiter, given a line break after it. + + The delimiter priorities returned here are from those delimiters that would + cause a line break after themselves. + + Higher numbers are higher priority. + """ + if leaf.type == token.COMMA: + return COMMA_PRIORITY + + return 0 + + +def is_split_before_delimiter(leaf: Leaf, previous: Optional[Leaf] = None) -> Priority: + """Return the priority of the `leaf` delimiter, given a line break before it. + + The delimiter priorities returned here are from those delimiters that would + cause a line break before themselves. + + Higher numbers are higher priority. + """ + if is_vararg(leaf, within=VARARGS_PARENTS | UNPACKING_PARENTS): + # * and ** might also be MATH_OPERATORS but in this case they are not. + # Don't treat them as a delimiter. + return 0 + + if ( + leaf.type == token.DOT + and leaf.parent + and leaf.parent.type not in {syms.import_from, syms.dotted_name} + and (previous is None or previous.type in CLOSING_BRACKETS) + ): + return DOT_PRIORITY + + if ( + leaf.type in MATH_OPERATORS + and leaf.parent + and leaf.parent.type not in {syms.factor, syms.star_expr} + ): + return MATH_PRIORITIES[leaf.type] + + if leaf.type in COMPARATORS: + return COMPARATOR_PRIORITY + + if ( + leaf.type == token.STRING + and previous is not None + and previous.type == token.STRING + ): + return STRING_PRIORITY + + if leaf.type not in {token.NAME, token.ASYNC}: + return 0 + + if ( + leaf.value == "for" + and leaf.parent + and leaf.parent.type in {syms.comp_for, syms.old_comp_for} + or leaf.type == token.ASYNC + ): + if ( + not isinstance(leaf.prev_sibling, Leaf) + or leaf.prev_sibling.value != "async" + ): + return COMPREHENSION_PRIORITY + + if ( + leaf.value == "if" + and leaf.parent + and leaf.parent.type in {syms.comp_if, syms.old_comp_if} + ): + return COMPREHENSION_PRIORITY + + if leaf.value in {"if", "else"} and leaf.parent and leaf.parent.type == syms.test: + return TERNARY_PRIORITY + + if leaf.value == "is": + return COMPARATOR_PRIORITY + + if ( + leaf.value == "in" + and leaf.parent + and leaf.parent.type in {syms.comp_op, syms.comparison} + and not ( + previous is not None + and previous.type == token.NAME + and previous.value == "not" + ) + ): + return COMPARATOR_PRIORITY + + if ( + leaf.value == "not" + and leaf.parent + and leaf.parent.type == syms.comp_op + and not ( + previous is not None + and previous.type == token.NAME + and previous.value == "is" + ) + ): + return COMPARATOR_PRIORITY + + if leaf.value in LOGIC_OPERATORS and leaf.parent: + return LOGIC_PRIORITY + + return 0 + + +def max_delimiter_priority_in_atom(node: LN) -> Priority: + """Return maximum delimiter priority inside `node`. + + This is specific to atoms with contents contained in a pair of parentheses. + If `node` isn't an atom or there are no enclosing parentheses, returns 0. + """ + if node.type != syms.atom: + return 0 + + first = node.children[0] + last = node.children[-1] + if not (first.type == token.LPAR and last.type == token.RPAR): + return 0 + + bt = BracketTracker() + for c in node.children[1:-1]: + if isinstance(c, Leaf): + bt.mark(c) + else: + for leaf in c.leaves(): + bt.mark(leaf) + try: + return bt.max_delimiter_priority() + + except ValueError: + return 0 + + +def get_leaves_inside_matching_brackets(leaves: Sequence[Leaf]) -> Set[LeafID]: + """Return leaves that are inside matching brackets. + + The input `leaves` can have non-matching brackets at the head or tail parts. + Matching brackets are included. + """ + try: + # Start with the first opening bracket and ignore closing brackets before. + start_index = next( + i for i, l in enumerate(leaves) if l.type in OPENING_BRACKETS + ) + except StopIteration: + return set() + bracket_stack = [] + ids = set() + for i in range(start_index, len(leaves)): + leaf = leaves[i] + if leaf.type in OPENING_BRACKETS: + bracket_stack.append((BRACKET[leaf.type], i)) + if leaf.type in CLOSING_BRACKETS: + if bracket_stack and leaf.type == bracket_stack[-1][0]: + _, start = bracket_stack.pop() + for j in range(start, i + 1): + ids.add(id(leaves[j])) + else: + break + return ids diff --git a/dbdpy-env/lib/python3.9/site-packages/black/cache.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/cache.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..863185f067d8c4ff5dcccfe4fadaed4a091fce5c GIT binary patch literal 50135 zcmeI*Uu+ab90%~<{b@Pn3T>#dMzkj(G-xTME!f5e4{0L>g(_9cgN*mD+=c7ydAkKp zYHUm}F(wLz7z_{kK-5MQBA5_GTOKs>U=$JyF{Tpq0TYQBLJTO>-*0!ey*mV+`e5=M zGB@*^+5OGzXYY8M^t&tPuLX%b#3jIW7T0rrq8&28u0=Oy;)zTNm~s4!H@v<9N)m@GCN7wByW?H#aW|O|YG+$chTchXQSck>Ac~Gf= z%+^#Uu2Pvk!;XvJ#}S=xl};dW(f-`Tx|R33hpSQ@D|%L_mFw27ciwJTUvPug$J0{f z3scEesZB<~YrSDU`EJ=I?A)&-D(8;mbBpZj99L&w?kKlIx*yhUN$l>+eP*T75oPB4 zqefa~t=tXs)#!ARzi=Njc--&KajR53VnwC~O7~YYE%R8WQG!wD_Z#4L@|k!z#IdZCBio|yQQkF}nZYes!)%w2~M3)}1P+1dYG=S#v**TXrwY4s7?u+;JH7#3`h_|*yA8b*oKcCIV=q7UwsZ7dJ(R3uX zSt%8Z#F7c;{OnxW1ed~AjO%bj?Rj@xy7AICg> z&6y=?E{Ru{#LqY}-{KS>H-4^VT+6u@#vD?J+~=6wzB}MN1xF=VGHL3dS6-k z>>C|jPu2cfzwqbk&pi*V>8?7v-`Huk-Rl17p6~psDY9?nXYH@|r;m4D{5w#7W%WOc zpI$a+=E+0%dbTurrhEMr8?DNY;XgL4^?&%@>EYfxFCM)8P;2e1hA+q7N!E`q8vhqi CvMWsh literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/cache.py b/dbdpy-env/lib/python3.9/site-packages/black/cache.py new file mode 100644 index 00000000..6baa096b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/cache.py @@ -0,0 +1,143 @@ +"""Caching of formatted files with feature-based invalidation.""" + +import hashlib +import os +import pickle +import sys +import tempfile +from dataclasses import dataclass, field +from pathlib import Path +from typing import Dict, Iterable, NamedTuple, Set, Tuple + +from platformdirs import user_cache_dir + +from _black_version import version as __version__ +from black.mode import Mode + +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self + + +class FileData(NamedTuple): + st_mtime: float + st_size: int + hash: str + + +def get_cache_dir() -> Path: + """Get the cache directory used by black. + + Users can customize this directory on all systems using `BLACK_CACHE_DIR` + environment variable. By default, the cache directory is the user cache directory + under the black application. + + This result is immediately set to a constant `black.cache.CACHE_DIR` as to avoid + repeated calls. + """ + # NOTE: Function mostly exists as a clean way to test getting the cache directory. + default_cache_dir = user_cache_dir("black") + cache_dir = Path(os.environ.get("BLACK_CACHE_DIR", default_cache_dir)) + cache_dir = cache_dir / __version__ + return cache_dir + + +CACHE_DIR = get_cache_dir() + + +def get_cache_file(mode: Mode) -> Path: + return CACHE_DIR / f"cache.{mode.get_cache_key()}.pickle" + + +@dataclass +class Cache: + mode: Mode + cache_file: Path + file_data: Dict[str, FileData] = field(default_factory=dict) + + @classmethod + def read(cls, mode: Mode) -> Self: + """Read the cache if it exists and is well formed. + + If it is not well formed, the call to write later should + resolve the issue. + """ + cache_file = get_cache_file(mode) + if not cache_file.exists(): + return cls(mode, cache_file) + + with cache_file.open("rb") as fobj: + try: + data: Dict[str, Tuple[float, int, str]] = pickle.load(fobj) + file_data = {k: FileData(*v) for k, v in data.items()} + except (pickle.UnpicklingError, ValueError, IndexError): + return cls(mode, cache_file) + + return cls(mode, cache_file, file_data) + + @staticmethod + def hash_digest(path: Path) -> str: + """Return hash digest for path.""" + + data = path.read_bytes() + return hashlib.sha256(data).hexdigest() + + @staticmethod + def get_file_data(path: Path) -> FileData: + """Return file data for path.""" + + stat = path.stat() + hash = Cache.hash_digest(path) + return FileData(stat.st_mtime, stat.st_size, hash) + + def is_changed(self, source: Path) -> bool: + """Check if source has changed compared to cached version.""" + res_src = source.resolve() + old = self.file_data.get(str(res_src)) + if old is None: + return True + + st = res_src.stat() + if st.st_size != old.st_size: + return True + if int(st.st_mtime) != int(old.st_mtime): + new_hash = Cache.hash_digest(res_src) + if new_hash != old.hash: + return True + return False + + def filtered_cached(self, sources: Iterable[Path]) -> Tuple[Set[Path], Set[Path]]: + """Split an iterable of paths in `sources` into two sets. + + The first contains paths of files that modified on disk or are not in the + cache. The other contains paths to non-modified files. + """ + changed: Set[Path] = set() + done: Set[Path] = set() + for src in sources: + if self.is_changed(src): + changed.add(src) + else: + done.add(src) + return changed, done + + def write(self, sources: Iterable[Path]) -> None: + """Update the cache file data and write a new cache file.""" + self.file_data.update( + **{str(src.resolve()): Cache.get_file_data(src) for src in sources} + ) + try: + CACHE_DIR.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile( + dir=str(self.cache_file.parent), delete=False + ) as f: + # We store raw tuples in the cache because pickling NamedTuples + # doesn't work with mypyc on Python 3.8, and because it's faster. + data: Dict[str, Tuple[float, int, str]] = { + k: (*v,) for k, v in self.file_data.items() + } + pickle.dump(data, f, protocol=4) + os.replace(f.name, self.cache_file) + except OSError: + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/black/comments.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/comments.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..9843e523c6d583e57618249d3ec34e665484f154 GIT binary patch literal 50138 zcmeI*U2IfE6bJCLcUxFO3)@gliI}bpp-P}2w74V)ixf+dk3yT+=)<^QrJL>-ySKp7 z8v8<&_#he{h#{mVAmC@CXo|+r#%SVK1PKL6Fc4oLDuGAPQqQ?}Zo9h(JoUlkKgsOO znVEZL?r+<^4g7rjuRCQ#F5=?hI)m%g5~4jaz-2bq3p}e-+uHUvYpC!eP#BVqOL^F- zvO*~{y33TFU5fMhSK8yJ^}NJ}?psX>_2q|3WzFtTc6_KfpJ$alHCL~YI6t39=i_&` zik(k&M&s#dhDVC?EztQ^==Bok=cBvM7tWfQSaO?QU!1Q~=i8*`omhv3xp`2j?&Qu` zGNNM1j+7M_ejkH6-#VQ@;)3%ziFGUA>jADxHLh-3t=4Sb)M|gb0lnZJt(&K%$`6c} zt5Vxid0*>2^U2SaRRZ?&I-)7uk$g^(b6w?XpUWBLwoms1x-E*Gb2;y=xs`Cp$t^3I0btj7o6ZCb)(KCZF{ z5%20MxBAxWx$52Xc~pL`oFc!Uey);B&O=noe^y+ys5_fk6pw|Zw&t>CG*S0VT_nem zwTR|%BY6%C*)C7$Sl(O8qg-WvfX_eQPAtPH5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG|g ze=9KBbL#l0o8AmeBX70OeQqhy{(wOzJQTR)DW#iy5B3&c(`@tUc^CCra77o8aG z89qi-J;HY~_xn8d^D}f%L9@Xu-H0g7mO1YOReZE3k*}(lRQw-~z zH=0fzmptB5vT`n4vfSUWv?J2dv1Hkk(TIO}=&5?861j9PO!t|qizQ>G3dMurE~QjB zl}JRBrrdg$`?GVnO382KDy!U`ujf|kG<`2z`f|s%jGy#cPjhhptG(6&d_VvK5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1RyZ^0?z+y@7MoMK%;Iae`o9f0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00IzzfFn>*L#@)U2t;!6h{~GXAr*=xBhd_P*-rZ? zLn{NSCATJ+&UVM6syUHPWlS0OSmSoAhc~7oyhbLyJjqX~#%M4ePlb7iTpTwiW2T}C zH}$_vWGEGrSW#Ixl}JRBW|nH*G}vn$ZLqh~YPu28DL z=q`Vytf6!!wj*dpWpggKe=8eeyZPL8&Rof3%wjxD2A|xph<5ONJ69>?M8g9pjuCd(XwMUSGF&!O;iJm*+-q zTyLmoy!5gE`^cfQbB4d{KbKhHZ9I8td-Lh9vj-pa{AACs`u*gKZClf8s^_iW`^Tl4 z+Ll$>sxQv=RB!lk{gv%)4}CP*`*(f%{*{^|iMQHsuiMr1Q^W4h&mDZ@&}g&qPs9G} Juibcc_P-$4Gyebp literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/comments.py b/dbdpy-env/lib/python3.9/site-packages/black/comments.py new file mode 100644 index 00000000..25413121 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/comments.py @@ -0,0 +1,412 @@ +import re +from dataclasses import dataclass +from functools import lru_cache +from typing import Collection, Final, Iterator, List, Optional, Tuple, Union + +from black.mode import Mode, Preview +from black.nodes import ( + CLOSING_BRACKETS, + STANDALONE_COMMENT, + WHITESPACE, + container_of, + first_leaf_of, + make_simple_prefix, + preceding_leaf, + syms, +) +from blib2to3.pgen2 import token +from blib2to3.pytree import Leaf, Node + +# types +LN = Union[Leaf, Node] + +FMT_OFF: Final = {"# fmt: off", "# fmt:off", "# yapf: disable"} +FMT_SKIP: Final = {"# fmt: skip", "# fmt:skip"} +FMT_ON: Final = {"# fmt: on", "# fmt:on", "# yapf: enable"} + +COMMENT_EXCEPTIONS = " !:#'" +_COMMENT_PREFIX = "# " +_COMMENT_LIST_SEPARATOR = ";" + + +@dataclass +class ProtoComment: + """Describes a piece of syntax that is a comment. + + It's not a :class:`blib2to3.pytree.Leaf` so that: + + * it can be cached (`Leaf` objects should not be reused more than once as + they store their lineno, column, prefix, and parent information); + * `newlines` and `consumed` fields are kept separate from the `value`. This + simplifies handling of special marker comments like ``# fmt: off/on``. + """ + + type: int # token.COMMENT or STANDALONE_COMMENT + value: str # content of the comment + newlines: int # how many newlines before the comment + consumed: int # how many characters of the original leaf's prefix did we consume + form_feed: bool # is there a form feed before the comment + + +def generate_comments(leaf: LN) -> Iterator[Leaf]: + """Clean the prefix of the `leaf` and generate comments from it, if any. + + Comments in lib2to3 are shoved into the whitespace prefix. This happens + in `pgen2/driver.py:Driver.parse_tokens()`. This was a brilliant implementation + move because it does away with modifying the grammar to include all the + possible places in which comments can be placed. + + The sad consequence for us though is that comments don't "belong" anywhere. + This is why this function generates simple parentless Leaf objects for + comments. We simply don't know what the correct parent should be. + + No matter though, we can live without this. We really only need to + differentiate between inline and standalone comments. The latter don't + share the line with any code. + + Inline comments are emitted as regular token.COMMENT leaves. Standalone + are emitted with a fake STANDALONE_COMMENT token identifier. + """ + total_consumed = 0 + for pc in list_comments(leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER): + total_consumed = pc.consumed + prefix = make_simple_prefix(pc.newlines, pc.form_feed) + yield Leaf(pc.type, pc.value, prefix=prefix) + normalize_trailing_prefix(leaf, total_consumed) + + +@lru_cache(maxsize=4096) +def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]: + """Return a list of :class:`ProtoComment` objects parsed from the given `prefix`.""" + result: List[ProtoComment] = [] + if not prefix or "#" not in prefix: + return result + + consumed = 0 + nlines = 0 + ignored_lines = 0 + form_feed = False + for index, full_line in enumerate(re.split("\r?\n", prefix)): + consumed += len(full_line) + 1 # adding the length of the split '\n' + line = full_line.lstrip() + if not line: + nlines += 1 + if "\f" in full_line: + form_feed = True + if not line.startswith("#"): + # Escaped newlines outside of a comment are not really newlines at + # all. We treat a single-line comment following an escaped newline + # as a simple trailing comment. + if line.endswith("\\"): + ignored_lines += 1 + continue + + if index == ignored_lines and not is_endmarker: + comment_type = token.COMMENT # simple trailing comment + else: + comment_type = STANDALONE_COMMENT + comment = make_comment(line) + result.append( + ProtoComment( + type=comment_type, + value=comment, + newlines=nlines, + consumed=consumed, + form_feed=form_feed, + ) + ) + form_feed = False + nlines = 0 + return result + + +def normalize_trailing_prefix(leaf: LN, total_consumed: int) -> None: + """Normalize the prefix that's left over after generating comments. + + Note: don't use backslashes for formatting or you'll lose your voting rights. + """ + remainder = leaf.prefix[total_consumed:] + if "\\" not in remainder: + nl_count = remainder.count("\n") + form_feed = "\f" in remainder and remainder.endswith("\n") + leaf.prefix = make_simple_prefix(nl_count, form_feed) + return + + leaf.prefix = "" + + +def make_comment(content: str) -> str: + """Return a consistently formatted comment from the given `content` string. + + All comments (except for "##", "#!", "#:", '#'") should have a single + space between the hash sign and the content. + + If `content` didn't start with a hash sign, one is provided. + """ + content = content.rstrip() + if not content: + return "#" + + if content[0] == "#": + content = content[1:] + NON_BREAKING_SPACE = " " + if ( + content + and content[0] == NON_BREAKING_SPACE + and not content.lstrip().startswith("type:") + ): + content = " " + content[1:] # Replace NBSP by a simple space + if content and content[0] not in COMMENT_EXCEPTIONS: + content = " " + content + return "#" + content + + +def normalize_fmt_off( + node: Node, mode: Mode, lines: Collection[Tuple[int, int]] +) -> None: + """Convert content between `# fmt: off`/`# fmt: on` into standalone comments.""" + try_again = True + while try_again: + try_again = convert_one_fmt_off_pair(node, mode, lines) + + +def convert_one_fmt_off_pair( + node: Node, mode: Mode, lines: Collection[Tuple[int, int]] +) -> bool: + """Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment. + + Returns True if a pair was converted. + """ + for leaf in node.leaves(): + previous_consumed = 0 + for comment in list_comments(leaf.prefix, is_endmarker=False): + should_pass_fmt = comment.value in FMT_OFF or _contains_fmt_skip_comment( + comment.value, mode + ) + if not should_pass_fmt: + previous_consumed = comment.consumed + continue + # We only want standalone comments. If there's no previous leaf or + # the previous leaf is indentation, it's a standalone comment in + # disguise. + if should_pass_fmt and comment.type != STANDALONE_COMMENT: + prev = preceding_leaf(leaf) + if prev: + if comment.value in FMT_OFF and prev.type not in WHITESPACE: + continue + if ( + _contains_fmt_skip_comment(comment.value, mode) + and prev.type in WHITESPACE + ): + continue + + ignored_nodes = list(generate_ignored_nodes(leaf, comment, mode)) + if not ignored_nodes: + continue + + first = ignored_nodes[0] # Can be a container node with the `leaf`. + parent = first.parent + prefix = first.prefix + if comment.value in FMT_OFF: + first.prefix = prefix[comment.consumed :] + if _contains_fmt_skip_comment(comment.value, mode): + first.prefix = "" + standalone_comment_prefix = prefix + else: + standalone_comment_prefix = ( + prefix[:previous_consumed] + "\n" * comment.newlines + ) + hidden_value = "".join(str(n) for n in ignored_nodes) + comment_lineno = leaf.lineno - comment.newlines + if comment.value in FMT_OFF: + fmt_off_prefix = "" + if len(lines) > 0 and not any( + comment_lineno >= line[0] and comment_lineno <= line[1] + for line in lines + ): + # keeping indentation of comment by preserving original whitespaces. + fmt_off_prefix = prefix.split(comment.value)[0] + if "\n" in fmt_off_prefix: + fmt_off_prefix = fmt_off_prefix.split("\n")[-1] + standalone_comment_prefix += fmt_off_prefix + hidden_value = comment.value + "\n" + hidden_value + if _contains_fmt_skip_comment(comment.value, mode): + hidden_value += " " + comment.value + if hidden_value.endswith("\n"): + # That happens when one of the `ignored_nodes` ended with a NEWLINE + # leaf (possibly followed by a DEDENT). + hidden_value = hidden_value[:-1] + first_idx: Optional[int] = None + for ignored in ignored_nodes: + index = ignored.remove() + if first_idx is None: + first_idx = index + assert parent is not None, "INTERNAL ERROR: fmt: on/off handling (1)" + assert first_idx is not None, "INTERNAL ERROR: fmt: on/off handling (2)" + parent.insert_child( + first_idx, + Leaf( + STANDALONE_COMMENT, + hidden_value, + prefix=standalone_comment_prefix, + fmt_pass_converted_first_leaf=first_leaf_of(first), + ), + ) + return True + + return False + + +def generate_ignored_nodes( + leaf: Leaf, comment: ProtoComment, mode: Mode +) -> Iterator[LN]: + """Starting from the container of `leaf`, generate all leaves until `# fmt: on`. + + If comment is skip, returns leaf only. + Stops at the end of the block. + """ + if _contains_fmt_skip_comment(comment.value, mode): + yield from _generate_ignored_nodes_from_fmt_skip(leaf, comment) + return + container: Optional[LN] = container_of(leaf) + while container is not None and container.type != token.ENDMARKER: + if is_fmt_on(container): + return + + # fix for fmt: on in children + if children_contains_fmt_on(container): + for index, child in enumerate(container.children): + if isinstance(child, Leaf) and is_fmt_on(child): + if child.type in CLOSING_BRACKETS: + # This means `# fmt: on` is placed at a different bracket level + # than `# fmt: off`. This is an invalid use, but as a courtesy, + # we include this closing bracket in the ignored nodes. + # The alternative is to fail the formatting. + yield child + return + if ( + child.type == token.INDENT + and index < len(container.children) - 1 + and children_contains_fmt_on(container.children[index + 1]) + ): + # This means `# fmt: on` is placed right after an indentation + # level, and we shouldn't swallow the previous INDENT token. + return + if children_contains_fmt_on(child): + return + yield child + else: + if container.type == token.DEDENT and container.next_sibling is None: + # This can happen when there is no matching `# fmt: on` comment at the + # same level as `# fmt: on`. We need to keep this DEDENT. + return + yield container + container = container.next_sibling + + +def _generate_ignored_nodes_from_fmt_skip( + leaf: Leaf, comment: ProtoComment +) -> Iterator[LN]: + """Generate all leaves that should be ignored by the `# fmt: skip` from `leaf`.""" + prev_sibling = leaf.prev_sibling + parent = leaf.parent + # Need to properly format the leaf prefix to compare it to comment.value, + # which is also formatted + comments = list_comments(leaf.prefix, is_endmarker=False) + if not comments or comment.value != comments[0].value: + return + if prev_sibling is not None: + leaf.prefix = "" + siblings = [prev_sibling] + while "\n" not in prev_sibling.prefix and prev_sibling.prev_sibling is not None: + prev_sibling = prev_sibling.prev_sibling + siblings.insert(0, prev_sibling) + yield from siblings + elif ( + parent is not None and parent.type == syms.suite and leaf.type == token.NEWLINE + ): + # The `# fmt: skip` is on the colon line of the if/while/def/class/... + # statements. The ignored nodes should be previous siblings of the + # parent suite node. + leaf.prefix = "" + ignored_nodes: List[LN] = [] + parent_sibling = parent.prev_sibling + while parent_sibling is not None and parent_sibling.type != syms.suite: + ignored_nodes.insert(0, parent_sibling) + parent_sibling = parent_sibling.prev_sibling + # Special case for `async_stmt` where the ASYNC token is on the + # grandparent node. + grandparent = parent.parent + if ( + grandparent is not None + and grandparent.prev_sibling is not None + and grandparent.prev_sibling.type == token.ASYNC + ): + ignored_nodes.insert(0, grandparent.prev_sibling) + yield from iter(ignored_nodes) + + +def is_fmt_on(container: LN) -> bool: + """Determine whether formatting is switched on within a container. + Determined by whether the last `# fmt:` comment is `on` or `off`. + """ + fmt_on = False + for comment in list_comments(container.prefix, is_endmarker=False): + if comment.value in FMT_ON: + fmt_on = True + elif comment.value in FMT_OFF: + fmt_on = False + return fmt_on + + +def children_contains_fmt_on(container: LN) -> bool: + """Determine if children have formatting switched on.""" + for child in container.children: + leaf = first_leaf_of(child) + if leaf is not None and is_fmt_on(leaf): + return True + + return False + + +def contains_pragma_comment(comment_list: List[Leaf]) -> bool: + """ + Returns: + True iff one of the comments in @comment_list is a pragma used by one + of the more common static analysis tools for python (e.g. mypy, flake8, + pylint). + """ + for comment in comment_list: + if comment.value.startswith(("# type:", "# noqa", "# pylint:")): + return True + + return False + + +def _contains_fmt_skip_comment(comment_line: str, mode: Mode) -> bool: + """ + Checks if the given comment contains FMT_SKIP alone or paired with other comments. + Matching styles: + # fmt:skip <-- single comment + # noqa:XXX # fmt:skip # a nice line <-- multiple comments (Preview) + # pylint:XXX; fmt:skip <-- list of comments (; separated, Preview) + """ + semantic_comment_blocks = ( + [ + comment_line, + *[ + _COMMENT_PREFIX + comment.strip() + for comment in comment_line.split(_COMMENT_PREFIX)[1:] + ], + *[ + _COMMENT_PREFIX + comment.strip() + for comment in comment_line.strip(_COMMENT_PREFIX).split( + _COMMENT_LIST_SEPARATOR + ) + ], + ] + if Preview.single_line_format_skip_with_multiple_comments in mode + else [comment_line] + ) + + return any(comment in FMT_SKIP for comment in semantic_comment_blocks) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/concurrency.py b/dbdpy-env/lib/python3.9/site-packages/black/concurrency.py new file mode 100644 index 00000000..ff0a8f5f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/concurrency.py @@ -0,0 +1,190 @@ +""" +Formatting many files at once via multiprocessing. Contains entrypoint and utilities. + +NOTE: this module is only imported if we need to format several files at once. +""" + +import asyncio +import logging +import os +import signal +import sys +import traceback +from concurrent.futures import Executor, ProcessPoolExecutor, ThreadPoolExecutor +from multiprocessing import Manager +from pathlib import Path +from typing import Any, Iterable, Optional, Set + +from mypy_extensions import mypyc_attr + +from black import WriteBack, format_file_in_place +from black.cache import Cache +from black.mode import Mode +from black.output import err +from black.report import Changed, Report + + +def maybe_install_uvloop() -> None: + """If our environment has uvloop installed we use it. + + This is called only from command-line entry points to avoid + interfering with the parent process if Black is used as a library. + """ + try: + import uvloop + + uvloop.install() + except ImportError: + pass + + +def cancel(tasks: Iterable["asyncio.Future[Any]"]) -> None: + """asyncio signal handler that cancels all `tasks` and reports to stderr.""" + err("Aborted!") + for task in tasks: + task.cancel() + + +def shutdown(loop: asyncio.AbstractEventLoop) -> None: + """Cancel all pending tasks on `loop`, wait for them, and close the loop.""" + try: + # This part is borrowed from asyncio/runners.py in Python 3.7b2. + to_cancel = [task for task in asyncio.all_tasks(loop) if not task.done()] + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True)) + finally: + # `concurrent.futures.Future` objects cannot be cancelled once they + # are already running. There might be some when the `shutdown()` happened. + # Silence their logger's spew about the event loop being closed. + cf_logger = logging.getLogger("concurrent.futures") + cf_logger.setLevel(logging.CRITICAL) + loop.close() + + +# diff-shades depends on being to monkeypatch this function to operate. I know it's +# not ideal, but this shouldn't cause any issues ... hopefully. ~ichard26 +@mypyc_attr(patchable=True) +def reformat_many( + sources: Set[Path], + fast: bool, + write_back: WriteBack, + mode: Mode, + report: Report, + workers: Optional[int], +) -> None: + """Reformat multiple files using a ProcessPoolExecutor.""" + maybe_install_uvloop() + + executor: Executor + if workers is None: + workers = int(os.environ.get("BLACK_NUM_WORKERS", 0)) + workers = workers or os.cpu_count() or 1 + if sys.platform == "win32": + # Work around https://bugs.python.org/issue26903 + workers = min(workers, 60) + try: + executor = ProcessPoolExecutor(max_workers=workers) + except (ImportError, NotImplementedError, OSError): + # we arrive here if the underlying system does not support multi-processing + # like in AWS Lambda or Termux, in which case we gracefully fallback to + # a ThreadPoolExecutor with just a single worker (more workers would not do us + # any good due to the Global Interpreter Lock) + executor = ThreadPoolExecutor(max_workers=1) + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + loop.run_until_complete( + schedule_formatting( + sources=sources, + fast=fast, + write_back=write_back, + mode=mode, + report=report, + loop=loop, + executor=executor, + ) + ) + finally: + try: + shutdown(loop) + finally: + asyncio.set_event_loop(None) + if executor is not None: + executor.shutdown() + + +async def schedule_formatting( + sources: Set[Path], + fast: bool, + write_back: WriteBack, + mode: Mode, + report: "Report", + loop: asyncio.AbstractEventLoop, + executor: "Executor", +) -> None: + """Run formatting of `sources` in parallel using the provided `executor`. + + (Use ProcessPoolExecutors for actual parallelism.) + + `write_back`, `fast`, and `mode` options are passed to + :func:`format_file_in_place`. + """ + cache = Cache.read(mode) + if write_back not in (WriteBack.DIFF, WriteBack.COLOR_DIFF): + sources, cached = cache.filtered_cached(sources) + for src in sorted(cached): + report.done(src, Changed.CACHED) + if not sources: + return + + cancelled = [] + sources_to_cache = [] + lock = None + if write_back in (WriteBack.DIFF, WriteBack.COLOR_DIFF): + # For diff output, we need locks to ensure we don't interleave output + # from different processes. + manager = Manager() + lock = manager.Lock() + tasks = { + asyncio.ensure_future( + loop.run_in_executor( + executor, format_file_in_place, src, fast, mode, write_back, lock + ) + ): src + for src in sorted(sources) + } + pending = tasks.keys() + try: + loop.add_signal_handler(signal.SIGINT, cancel, pending) + loop.add_signal_handler(signal.SIGTERM, cancel, pending) + except NotImplementedError: + # There are no good alternatives for these on Windows. + pass + while pending: + done, _ = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) + for task in done: + src = tasks.pop(task) + if task.cancelled(): + cancelled.append(task) + elif exc := task.exception(): + if report.verbose: + traceback.print_exception(type(exc), exc, exc.__traceback__) + report.failed(src, str(exc)) + else: + changed = Changed.YES if task.result() else Changed.NO + # If the file was written back or was successfully checked as + # well-formatted, store this information in the cache. + if write_back is WriteBack.YES or ( + write_back is WriteBack.CHECK and changed is Changed.NO + ): + sources_to_cache.append(src) + report.done(src, changed) + if cancelled: + await asyncio.gather(*cancelled, return_exceptions=True) + if sources_to_cache: + cache.write(sources_to_cache) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/const.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/const.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..443dcbaa500e431695027927afa3b310673f9129 GIT binary patch literal 50135 zcmeI*Pi$0090%~IY6S(D2PQp7!ngxHAV~Ouj>A zXMQvDelzd0Ew@R(9{J-=8Igy$__9~Z4 z-6|`TvSNEI={co1U-L?5{2M(lv7!5Raeh9!=X{Z@l}RLb==H_5 z6UnGbB;zSNF8n^u=zQyR0*MRG=O)&ze6I(&Dz#=+`zp11bK5rO+YRak_i4R6EmeMC zD!D4PBbE2H-Z!88Y}qB~Jg*}v<&NZYi=1nit8*@Ql-pk259+okcF*O$vr=YAWpiEO zl&R8I=Dzu=bvntPe~w8!?sMn3RVo^?LgNF)=d12@=G^y`I6vR`lTJ_GQ@$&uHnz5H zXj#+h{%#FA^Ayyrj<4xt;x5%Kb6BQcf=eV*#$R zhrO$(-0s`2=UME1nn&g5$}RHyxsAe0H-RC>9)%;#n^2JG?^Hj;*RO$0I(yArgUsP(? z=e)7@{D9=S;Uha|Q^T^QOB&|!F&h@zGI@i-_cja@cpQyUmnK8Jj@DLqd>BKX1+^pl-9P{)Y zXO^h3C|+L_zv#sLh*P}W__&sEE#;aYb4USl-(&3f?tt?a92H^7yv@ffohGsxhR8~l$b%e8~6lyagACjthQIpM=TgJTQq z7pjY-b5>_6xu9{`f@mnSJCUr*rl@UE)seLWN0tx#ZvOVg^-E9OZg}bE1G8ssopbPg zGuM}EI=1hllO3r`zs3iB*Dhb)X>9H&x!ZHP=hgi`e)iV7H|Kxwu=&47uS}hP>*lec z>Bn9ldHK-tt55Fh?|HAh|I2H`lbg=WRu6lAqUT#KHiQnZKHL0um-%_i&42u*BkON3 ze4%N^lq;uZd3M!%CVKyhU(Qy|+-)3x_lNag&HM9>?QK_AY&`Sf$MNm+KRs2u>Ey+K E0c~V0VE_OC literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/const.py b/dbdpy-env/lib/python3.9/site-packages/black/const.py new file mode 100644 index 00000000..ee466679 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/const.py @@ -0,0 +1,4 @@ +DEFAULT_LINE_LENGTH = 88 +DEFAULT_EXCLUDES = r"/(\.direnv|\.eggs|\.git|\.hg|\.ipynb_checkpoints|\.mypy_cache|\.nox|\.pytest_cache|\.ruff_cache|\.tox|\.svn|\.venv|\.vscode|__pypackages__|_build|buck-out|build|dist|venv)/" # noqa: B950 +DEFAULT_INCLUDES = r"(\.pyi?|\.ipynb)$" +STDIN_PLACEHOLDER = "__BLACK_STDIN_FILENAME__" diff --git a/dbdpy-env/lib/python3.9/site-packages/black/debug.py b/dbdpy-env/lib/python3.9/site-packages/black/debug.py new file mode 100644 index 00000000..cebc4876 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/debug.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass, field +from typing import Any, Iterator, List, TypeVar, Union + +from black.nodes import Visitor +from black.output import out +from black.parsing import lib2to3_parse +from blib2to3.pgen2 import token +from blib2to3.pytree import Leaf, Node, type_repr + +LN = Union[Leaf, Node] +T = TypeVar("T") + + +@dataclass +class DebugVisitor(Visitor[T]): + tree_depth: int = 0 + list_output: List[str] = field(default_factory=list) + print_output: bool = True + + def out(self, message: str, *args: Any, **kwargs: Any) -> None: + self.list_output.append(message) + if self.print_output: + out(message, *args, **kwargs) + + def visit_default(self, node: LN) -> Iterator[T]: + indent = " " * (2 * self.tree_depth) + if isinstance(node, Node): + _type = type_repr(node.type) + self.out(f"{indent}{_type}", fg="yellow") + self.tree_depth += 1 + for child in node.children: + yield from self.visit(child) + + self.tree_depth -= 1 + self.out(f"{indent}/{_type}", fg="yellow", bold=False) + else: + _type = token.tok_name.get(node.type, str(node.type)) + self.out(f"{indent}{_type}", fg="blue", nl=False) + if node.prefix: + # We don't have to handle prefixes for `Node` objects since + # that delegates to the first child anyway. + self.out(f" {node.prefix!r}", fg="green", bold=False, nl=False) + self.out(f" {node.value!r}", fg="blue", bold=False) + + @classmethod + def show(cls, code: Union[str, Leaf, Node]) -> None: + """Pretty-print the lib2to3 AST of a given string of `code`. + + Convenience method for debugging. + """ + v: DebugVisitor[None] = DebugVisitor() + if isinstance(code, str): + code = lib2to3_parse(code) + list(v.visit(code)) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/files.py b/dbdpy-env/lib/python3.9/site-packages/black/files.py new file mode 100644 index 00000000..858303ca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/files.py @@ -0,0 +1,411 @@ +import io +import os +import sys +from functools import lru_cache +from pathlib import Path +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterable, + Iterator, + List, + Optional, + Pattern, + Sequence, + Tuple, + Union, +) + +from mypy_extensions import mypyc_attr +from packaging.specifiers import InvalidSpecifier, Specifier, SpecifierSet +from packaging.version import InvalidVersion, Version +from pathspec import PathSpec +from pathspec.patterns.gitwildmatch import GitWildMatchPatternError + +if sys.version_info >= (3, 11): + try: + import tomllib + except ImportError: + # Help users on older alphas + if not TYPE_CHECKING: + import tomli as tomllib +else: + import tomli as tomllib + +from black.handle_ipynb_magics import jupyter_dependencies_are_installed +from black.mode import TargetVersion +from black.output import err +from black.report import Report + +if TYPE_CHECKING: + import colorama # noqa: F401 + + +@lru_cache +def find_project_root( + srcs: Sequence[str], stdin_filename: Optional[str] = None +) -> Tuple[Path, str]: + """Return a directory containing .git, .hg, or pyproject.toml. + + That directory will be a common parent of all files and directories + passed in `srcs`. + + If no directory in the tree contains a marker that would specify it's the + project root, the root of the file system is returned. + + Returns a two-tuple with the first element as the project root path and + the second element as a string describing the method by which the + project root was discovered. + """ + if stdin_filename is not None: + srcs = tuple(stdin_filename if s == "-" else s for s in srcs) + if not srcs: + srcs = [str(Path.cwd().resolve())] + + path_srcs = [Path(Path.cwd(), src).resolve() for src in srcs] + + # A list of lists of parents for each 'src'. 'src' is included as a + # "parent" of itself if it is a directory + src_parents = [ + list(path.parents) + ([path] if path.is_dir() else []) for path in path_srcs + ] + + common_base = max( + set.intersection(*(set(parents) for parents in src_parents)), + key=lambda path: path.parts, + ) + + for directory in (common_base, *common_base.parents): + if (directory / ".git").exists(): + return directory, ".git directory" + + if (directory / ".hg").is_dir(): + return directory, ".hg directory" + + if (directory / "pyproject.toml").is_file(): + return directory, "pyproject.toml" + + return directory, "file system root" + + +def find_pyproject_toml( + path_search_start: Tuple[str, ...], stdin_filename: Optional[str] = None +) -> Optional[str]: + """Find the absolute filepath to a pyproject.toml if it exists""" + path_project_root, _ = find_project_root(path_search_start, stdin_filename) + path_pyproject_toml = path_project_root / "pyproject.toml" + if path_pyproject_toml.is_file(): + return str(path_pyproject_toml) + + try: + path_user_pyproject_toml = find_user_pyproject_toml() + return ( + str(path_user_pyproject_toml) + if path_user_pyproject_toml.is_file() + else None + ) + except (PermissionError, RuntimeError) as e: + # We do not have access to the user-level config directory, so ignore it. + err(f"Ignoring user configuration directory due to {e!r}") + return None + + +@mypyc_attr(patchable=True) +def parse_pyproject_toml(path_config: str) -> Dict[str, Any]: + """Parse a pyproject toml file, pulling out relevant parts for Black. + + If parsing fails, will raise a tomllib.TOMLDecodeError. + """ + with open(path_config, "rb") as f: + pyproject_toml = tomllib.load(f) + config: Dict[str, Any] = pyproject_toml.get("tool", {}).get("black", {}) + config = {k.replace("--", "").replace("-", "_"): v for k, v in config.items()} + + if "target_version" not in config: + inferred_target_version = infer_target_version(pyproject_toml) + if inferred_target_version is not None: + config["target_version"] = [v.name.lower() for v in inferred_target_version] + + return config + + +def infer_target_version( + pyproject_toml: Dict[str, Any] +) -> Optional[List[TargetVersion]]: + """Infer Black's target version from the project metadata in pyproject.toml. + + Supports the PyPA standard format (PEP 621): + https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#requires-python + + If the target version cannot be inferred, returns None. + """ + project_metadata = pyproject_toml.get("project", {}) + requires_python = project_metadata.get("requires-python", None) + if requires_python is not None: + try: + return parse_req_python_version(requires_python) + except InvalidVersion: + pass + try: + return parse_req_python_specifier(requires_python) + except (InvalidSpecifier, InvalidVersion): + pass + + return None + + +def parse_req_python_version(requires_python: str) -> Optional[List[TargetVersion]]: + """Parse a version string (i.e. ``"3.7"``) to a list of TargetVersion. + + If parsing fails, will raise a packaging.version.InvalidVersion error. + If the parsed version cannot be mapped to a valid TargetVersion, returns None. + """ + version = Version(requires_python) + if version.release[0] != 3: + return None + try: + return [TargetVersion(version.release[1])] + except (IndexError, ValueError): + return None + + +def parse_req_python_specifier(requires_python: str) -> Optional[List[TargetVersion]]: + """Parse a specifier string (i.e. ``">=3.7,<3.10"``) to a list of TargetVersion. + + If parsing fails, will raise a packaging.specifiers.InvalidSpecifier error. + If the parsed specifier cannot be mapped to a valid TargetVersion, returns None. + """ + specifier_set = strip_specifier_set(SpecifierSet(requires_python)) + if not specifier_set: + return None + + target_version_map = {f"3.{v.value}": v for v in TargetVersion} + compatible_versions: List[str] = list(specifier_set.filter(target_version_map)) + if compatible_versions: + return [target_version_map[v] for v in compatible_versions] + return None + + +def strip_specifier_set(specifier_set: SpecifierSet) -> SpecifierSet: + """Strip minor versions for some specifiers in the specifier set. + + For background on version specifiers, see PEP 440: + https://peps.python.org/pep-0440/#version-specifiers + """ + specifiers = [] + for s in specifier_set: + if "*" in str(s): + specifiers.append(s) + elif s.operator in ["~=", "==", ">=", "==="]: + version = Version(s.version) + stripped = Specifier(f"{s.operator}{version.major}.{version.minor}") + specifiers.append(stripped) + elif s.operator == ">": + version = Version(s.version) + if len(version.release) > 2: + s = Specifier(f">={version.major}.{version.minor}") + specifiers.append(s) + else: + specifiers.append(s) + + return SpecifierSet(",".join(str(s) for s in specifiers)) + + +@lru_cache +def find_user_pyproject_toml() -> Path: + r"""Return the path to the top-level user configuration for black. + + This looks for ~\.black on Windows and ~/.config/black on Linux and other + Unix systems. + + May raise: + - RuntimeError: if the current user has no homedir + - PermissionError: if the current process cannot access the user's homedir + """ + if sys.platform == "win32": + # Windows + user_config_path = Path.home() / ".black" + else: + config_root = os.environ.get("XDG_CONFIG_HOME", "~/.config") + user_config_path = Path(config_root).expanduser() / "black" + return user_config_path.resolve() + + +@lru_cache +def get_gitignore(root: Path) -> PathSpec: + """Return a PathSpec matching gitignore content if present.""" + gitignore = root / ".gitignore" + lines: List[str] = [] + if gitignore.is_file(): + with gitignore.open(encoding="utf-8") as gf: + lines = gf.readlines() + try: + return PathSpec.from_lines("gitwildmatch", lines) + except GitWildMatchPatternError as e: + err(f"Could not parse {gitignore}: {e}") + raise + + +def normalize_path_maybe_ignore( + path: Path, + root: Path, + report: Optional[Report] = None, +) -> Optional[str]: + """Normalize `path`. May return `None` if `path` was ignored. + + `report` is where "path ignored" output goes. + """ + try: + abspath = path if path.is_absolute() else Path.cwd() / path + normalized_path = abspath.resolve() + try: + root_relative_path = normalized_path.relative_to(root).as_posix() + except ValueError: + if report: + report.path_ignored( + path, f"is a symbolic link that points outside {root}" + ) + return None + + except OSError as e: + if report: + report.path_ignored(path, f"cannot be read because {e}") + return None + + return root_relative_path + + +def _path_is_ignored( + root_relative_path: str, + root: Path, + gitignore_dict: Dict[Path, PathSpec], +) -> bool: + path = root / root_relative_path + # Note that this logic is sensitive to the ordering of gitignore_dict. Callers must + # ensure that gitignore_dict is ordered from least specific to most specific. + for gitignore_path, pattern in gitignore_dict.items(): + try: + relative_path = path.relative_to(gitignore_path).as_posix() + except ValueError: + break + if pattern.match_file(relative_path): + return True + return False + + +def path_is_excluded( + normalized_path: str, + pattern: Optional[Pattern[str]], +) -> bool: + match = pattern.search(normalized_path) if pattern else None + return bool(match and match.group(0)) + + +def gen_python_files( + paths: Iterable[Path], + root: Path, + include: Pattern[str], + exclude: Pattern[str], + extend_exclude: Optional[Pattern[str]], + force_exclude: Optional[Pattern[str]], + report: Report, + gitignore_dict: Optional[Dict[Path, PathSpec]], + *, + verbose: bool, + quiet: bool, +) -> Iterator[Path]: + """Generate all files under `path` whose paths are not excluded by the + `exclude_regex`, `extend_exclude`, or `force_exclude` regexes, + but are included by the `include` regex. + + Symbolic links pointing outside of the `root` directory are ignored. + + `report` is where output about exclusions goes. + """ + + assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}" + for child in paths: + root_relative_path = child.absolute().relative_to(root).as_posix() + + # First ignore files matching .gitignore, if passed + if gitignore_dict and _path_is_ignored( + root_relative_path, root, gitignore_dict + ): + report.path_ignored(child, "matches a .gitignore file content") + continue + + # Then ignore with `--exclude` `--extend-exclude` and `--force-exclude` options. + root_relative_path = "/" + root_relative_path + if child.is_dir(): + root_relative_path += "/" + + if path_is_excluded(root_relative_path, exclude): + report.path_ignored(child, "matches the --exclude regular expression") + continue + + if path_is_excluded(root_relative_path, extend_exclude): + report.path_ignored( + child, "matches the --extend-exclude regular expression" + ) + continue + + if path_is_excluded(root_relative_path, force_exclude): + report.path_ignored(child, "matches the --force-exclude regular expression") + continue + + normalized_path = normalize_path_maybe_ignore(child, root, report) + if normalized_path is None: + continue + + if child.is_dir(): + # If gitignore is None, gitignore usage is disabled, while a Falsey + # gitignore is when the directory doesn't have a .gitignore file. + if gitignore_dict is not None: + new_gitignore_dict = { + **gitignore_dict, + root / child: get_gitignore(child), + } + else: + new_gitignore_dict = None + yield from gen_python_files( + child.iterdir(), + root, + include, + exclude, + extend_exclude, + force_exclude, + report, + new_gitignore_dict, + verbose=verbose, + quiet=quiet, + ) + + elif child.is_file(): + if child.suffix == ".ipynb" and not jupyter_dependencies_are_installed( + warn=verbose or not quiet + ): + continue + include_match = include.search(root_relative_path) if include else True + if include_match: + yield child + + +def wrap_stream_for_windows( + f: io.TextIOWrapper, +) -> Union[io.TextIOWrapper, "colorama.AnsiToWin32"]: + """ + Wrap stream with colorama's wrap_stream so colors are shown on Windows. + + If `colorama` is unavailable, the original stream is returned unmodified. + Otherwise, the `wrap_stream()` function determines whether the stream needs + to be wrapped for a Windows environment and will accordingly either return + an `AnsiToWin32` wrapper or the original stream. + """ + try: + from colorama.initialise import wrap_stream + except ImportError: + return f + else: + # Set `strip=False` to avoid needing to modify test_express_diff_with_color. + return wrap_stream(f, convert=None, strip=False, autoreset=False, wrap=True) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..848495419868806ec7ffb21c51befce4d794148a GIT binary patch literal 50165 zcmeI*TWnNC7zglgcUxG)7TVa562&f!Krp39X`uwDTcMGLON;bjH74WU+8)_GyY6m* z70}WI1JMVGO*AGLZwZ$`qKJu+7`BNq#%Q=GR52P7HR6K_n5cnR>i3;9r`=s{Pkk`? zPcohPX6Afn=671&CY-+h#|X7v}To ze0+AR*!fgnES`#`d89O-{}FrLO1mM63-i%U`-^0r3-JrSm&_)S9;LHnqBQ<7WHo2K0j4v>u+8 zD!(w5T$Sog7JSy*=9Awos|4)lbwpFRBl(;n`?}24-j_4V?SSqFbXyWT`*O~#R6L|I zxkNY_SE+3Jw)tvwI>}$SkEuLf=FD-cR5X+gO$?OouV%oWbIvJoVZMnc?Vg-dzLiqz zJ2tLsU(@0IZRPEG3g}kHf9Yi6F4ZY@Ec37gdHe6z%kB7?c-YUeyr+-b7H-8y<_~c! zXKWcJ+RN=Uu3cQEIPZ|P^4dZNnJ+9g{Ji8TE%)(&yl2`R-_?1Ul_N(ZyXyvb?K|1X zV}7pk4(qM13af7&&(-94h)3o3$|>^qDf^aOvLB-P{LhMu7WHS+i{eID>gHS~8%s1i z+7QigWG$k3+(@3c^0vzY9m~0;%;qZddES4somhrZAOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX?}|4LwV$Em}k9@-zchbn9Rp7TqHh5~Ln;ibSeZ#iA%yRX;yYG$`z&%0>g@%g;Q z@1hf87*r~&kCsj^X&ZUjZTbh^jM0l{3RC5$ZJ})}?p3KYKq{DTS?EWtF@0P25Ty)%W0~FL!Kx{DCUD z>T;*6z0Ml65P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2u!ko^Z(k{>;FH# zMYoguTBL^n1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG{#K%lCQHcMC)i00x^ zmC5#pRoF12u{3RZmR_MWwFXpIZgnV?>5s=$MXJy=LjoYyv-jIy)8kwx*Nq$PL ziG||vWQ2#v#c_veWEE9;XlNIaTPZ_gMZUg}8Rg_gDrbgOBGhX{GSujyqdSRfpS9bq z{BydOsAj+l$<56S7tv6w9p9_tdL1v~n5S>pvqWtraj+zg*)cz27Y{dOT+6vm;aV7T zNPcq8Gky$b;8v&Mxe`KIZDAJU6|vp)NtCjNQfXsrC@Wj0>p%JOY}w3RXYbWK#ysvh zAFhkrUh47~Ws&y)TB!LMh$d~Cz_ e`>Wd*9IxwI>`A)YbL&#cgL_tt%sOzT$@L$2gGYz} literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.py b/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.py new file mode 100644 index 00000000..5b2847cb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/handle_ipynb_magics.py @@ -0,0 +1,452 @@ +"""Functions to process IPython magics with.""" + +import ast +import collections +import dataclasses +import secrets +import sys +from functools import lru_cache +from importlib.util import find_spec +from typing import Dict, List, Optional, Tuple + +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +from black.output import out +from black.report import NothingChanged + +TRANSFORMED_MAGICS = frozenset(( + "get_ipython().run_cell_magic", + "get_ipython().system", + "get_ipython().getoutput", + "get_ipython().run_line_magic", +)) +TOKENS_TO_IGNORE = frozenset(( + "ENDMARKER", + "NL", + "NEWLINE", + "COMMENT", + "DEDENT", + "UNIMPORTANT_WS", + "ESCAPED_NL", +)) +PYTHON_CELL_MAGICS = frozenset(( + "capture", + "prun", + "pypy", + "python", + "python3", + "time", + "timeit", +)) +TOKEN_HEX = secrets.token_hex + + +@dataclasses.dataclass(frozen=True) +class Replacement: + mask: str + src: str + + +@lru_cache +def jupyter_dependencies_are_installed(*, warn: bool) -> bool: + installed = ( + find_spec("tokenize_rt") is not None and find_spec("IPython") is not None + ) + if not installed and warn: + msg = ( + "Skipping .ipynb files as Jupyter dependencies are not installed.\n" + 'You can fix this by running ``pip install "black[jupyter]"``' + ) + out(msg) + return installed + + +def remove_trailing_semicolon(src: str) -> Tuple[str, bool]: + """Remove trailing semicolon from Jupyter notebook cell. + + For example, + + fig, ax = plt.subplots() + ax.plot(x_data, y_data); # plot data + + would become + + fig, ax = plt.subplots() + ax.plot(x_data, y_data) # plot data + + Mirrors the logic in `quiet` from `IPython.core.displayhook`, but uses + ``tokenize_rt`` so that round-tripping works fine. + """ + from tokenize_rt import reversed_enumerate, src_to_tokens, tokens_to_src + + tokens = src_to_tokens(src) + trailing_semicolon = False + for idx, token in reversed_enumerate(tokens): + if token.name in TOKENS_TO_IGNORE: + continue + if token.name == "OP" and token.src == ";": + del tokens[idx] + trailing_semicolon = True + break + if not trailing_semicolon: + return src, False + return tokens_to_src(tokens), True + + +def put_trailing_semicolon_back(src: str, has_trailing_semicolon: bool) -> str: + """Put trailing semicolon back if cell originally had it. + + Mirrors the logic in `quiet` from `IPython.core.displayhook`, but uses + ``tokenize_rt`` so that round-tripping works fine. + """ + if not has_trailing_semicolon: + return src + from tokenize_rt import reversed_enumerate, src_to_tokens, tokens_to_src + + tokens = src_to_tokens(src) + for idx, token in reversed_enumerate(tokens): + if token.name in TOKENS_TO_IGNORE: + continue + tokens[idx] = token._replace(src=token.src + ";") + break + else: # pragma: nocover + raise AssertionError( + "INTERNAL ERROR: Was not able to reinstate trailing semicolon. " + "Please report a bug on https://github.com/psf/black/issues. " + ) from None + return str(tokens_to_src(tokens)) + + +def mask_cell(src: str) -> Tuple[str, List[Replacement]]: + """Mask IPython magics so content becomes parseable Python code. + + For example, + + %matplotlib inline + 'foo' + + becomes + + "25716f358c32750e" + 'foo' + + The replacements are returned, along with the transformed code. + """ + replacements: List[Replacement] = [] + try: + ast.parse(src) + except SyntaxError: + # Might have IPython magics, will process below. + pass + else: + # Syntax is fine, nothing to mask, early return. + return src, replacements + + from IPython.core.inputtransformer2 import TransformerManager + + transformer_manager = TransformerManager() + transformed = transformer_manager.transform_cell(src) + transformed, cell_magic_replacements = replace_cell_magics(transformed) + replacements += cell_magic_replacements + transformed = transformer_manager.transform_cell(transformed) + transformed, magic_replacements = replace_magics(transformed) + if len(transformed.splitlines()) != len(src.splitlines()): + # Multi-line magic, not supported. + raise NothingChanged + replacements += magic_replacements + return transformed, replacements + + +def get_token(src: str, magic: str) -> str: + """Return randomly generated token to mask IPython magic with. + + For example, if 'magic' was `%matplotlib inline`, then a possible + token to mask it with would be `"43fdd17f7e5ddc83"`. The token + will be the same length as the magic, and we make sure that it was + not already present anywhere else in the cell. + """ + assert magic + nbytes = max(len(magic) // 2 - 1, 1) + token = TOKEN_HEX(nbytes) + counter = 0 + while token in src: + token = TOKEN_HEX(nbytes) + counter += 1 + if counter > 100: + raise AssertionError( + "INTERNAL ERROR: Black was not able to replace IPython magic. " + "Please report a bug on https://github.com/psf/black/issues. " + f"The magic might be helpful: {magic}" + ) from None + if len(token) + 2 < len(magic): + token = f"{token}." + return f'"{token}"' + + +def replace_cell_magics(src: str) -> Tuple[str, List[Replacement]]: + """Replace cell magic with token. + + Note that 'src' will already have been processed by IPython's + TransformerManager().transform_cell. + + Example, + + get_ipython().run_cell_magic('t', '-n1', 'ls =!ls\\n') + + becomes + + "a794." + ls =!ls + + The replacement, along with the transformed code, is returned. + """ + replacements: List[Replacement] = [] + + tree = ast.parse(src) + + cell_magic_finder = CellMagicFinder() + cell_magic_finder.visit(tree) + if cell_magic_finder.cell_magic is None: + return src, replacements + header = cell_magic_finder.cell_magic.header + mask = get_token(src, header) + replacements.append(Replacement(mask=mask, src=header)) + return f"{mask}\n{cell_magic_finder.cell_magic.body}", replacements + + +def replace_magics(src: str) -> Tuple[str, List[Replacement]]: + """Replace magics within body of cell. + + Note that 'src' will already have been processed by IPython's + TransformerManager().transform_cell. + + Example, this + + get_ipython().run_line_magic('matplotlib', 'inline') + 'foo' + + becomes + + "5e67db56d490fd39" + 'foo' + + The replacement, along with the transformed code, are returned. + """ + replacements = [] + magic_finder = MagicFinder() + magic_finder.visit(ast.parse(src)) + new_srcs = [] + for i, line in enumerate(src.splitlines(), start=1): + if i in magic_finder.magics: + offsets_and_magics = magic_finder.magics[i] + if len(offsets_and_magics) != 1: # pragma: nocover + raise AssertionError( + f"Expecting one magic per line, got: {offsets_and_magics}\n" + "Please report a bug on https://github.com/psf/black/issues." + ) + col_offset, magic = ( + offsets_and_magics[0].col_offset, + offsets_and_magics[0].magic, + ) + mask = get_token(src, magic) + replacements.append(Replacement(mask=mask, src=magic)) + line = line[:col_offset] + mask + new_srcs.append(line) + return "\n".join(new_srcs), replacements + + +def unmask_cell(src: str, replacements: List[Replacement]) -> str: + """Remove replacements from cell. + + For example + + "9b20" + foo = bar + + becomes + + %%time + foo = bar + """ + for replacement in replacements: + src = src.replace(replacement.mask, replacement.src) + return src + + +def _is_ipython_magic(node: ast.expr) -> TypeGuard[ast.Attribute]: + """Check if attribute is IPython magic. + + Note that the source of the abstract syntax tree + will already have been processed by IPython's + TransformerManager().transform_cell. + """ + return ( + isinstance(node, ast.Attribute) + and isinstance(node.value, ast.Call) + and isinstance(node.value.func, ast.Name) + and node.value.func.id == "get_ipython" + ) + + +def _get_str_args(args: List[ast.expr]) -> List[str]: + str_args = [] + for arg in args: + assert isinstance(arg, ast.Str) + str_args.append(arg.s) + return str_args + + +@dataclasses.dataclass(frozen=True) +class CellMagic: + name: str + params: Optional[str] + body: str + + @property + def header(self) -> str: + if self.params: + return f"%%{self.name} {self.params}" + return f"%%{self.name}" + + +# ast.NodeVisitor + dataclass = breakage under mypyc. +class CellMagicFinder(ast.NodeVisitor): + """Find cell magics. + + Note that the source of the abstract syntax tree + will already have been processed by IPython's + TransformerManager().transform_cell. + + For example, + + %%time\n + foo() + + would have been transformed to + + get_ipython().run_cell_magic('time', '', 'foo()\\n') + + and we look for instances of the latter. + """ + + def __init__(self, cell_magic: Optional[CellMagic] = None) -> None: + self.cell_magic = cell_magic + + def visit_Expr(self, node: ast.Expr) -> None: + """Find cell magic, extract header and body.""" + if ( + isinstance(node.value, ast.Call) + and _is_ipython_magic(node.value.func) + and node.value.func.attr == "run_cell_magic" + ): + args = _get_str_args(node.value.args) + self.cell_magic = CellMagic(name=args[0], params=args[1], body=args[2]) + self.generic_visit(node) + + +@dataclasses.dataclass(frozen=True) +class OffsetAndMagic: + col_offset: int + magic: str + + +# Unsurprisingly, subclassing ast.NodeVisitor means we can't use dataclasses here +# as mypyc will generate broken code. +class MagicFinder(ast.NodeVisitor): + """Visit cell to look for get_ipython calls. + + Note that the source of the abstract syntax tree + will already have been processed by IPython's + TransformerManager().transform_cell. + + For example, + + %matplotlib inline + + would have been transformed to + + get_ipython().run_line_magic('matplotlib', 'inline') + + and we look for instances of the latter (and likewise for other + types of magics). + """ + + def __init__(self) -> None: + self.magics: Dict[int, List[OffsetAndMagic]] = collections.defaultdict(list) + + def visit_Assign(self, node: ast.Assign) -> None: + """Look for system assign magics. + + For example, + + black_version = !black --version + env = %env var + + would have been (respectively) transformed to + + black_version = get_ipython().getoutput('black --version') + env = get_ipython().run_line_magic('env', 'var') + + and we look for instances of any of the latter. + """ + if isinstance(node.value, ast.Call) and _is_ipython_magic(node.value.func): + args = _get_str_args(node.value.args) + if node.value.func.attr == "getoutput": + src = f"!{args[0]}" + elif node.value.func.attr == "run_line_magic": + src = f"%{args[0]}" + if args[1]: + src += f" {args[1]}" + else: + raise AssertionError( + f"Unexpected IPython magic {node.value.func.attr!r} found. " + "Please report a bug on https://github.com/psf/black/issues." + ) from None + self.magics[node.value.lineno].append( + OffsetAndMagic(node.value.col_offset, src) + ) + self.generic_visit(node) + + def visit_Expr(self, node: ast.Expr) -> None: + """Look for magics in body of cell. + + For examples, + + !ls + !!ls + ?ls + ??ls + + would (respectively) get transformed to + + get_ipython().system('ls') + get_ipython().getoutput('ls') + get_ipython().run_line_magic('pinfo', 'ls') + get_ipython().run_line_magic('pinfo2', 'ls') + + and we look for instances of any of the latter. + """ + if isinstance(node.value, ast.Call) and _is_ipython_magic(node.value.func): + args = _get_str_args(node.value.args) + if node.value.func.attr == "run_line_magic": + if args[0] == "pinfo": + src = f"?{args[1]}" + elif args[0] == "pinfo2": + src = f"??{args[1]}" + else: + src = f"%{args[0]}" + if args[1]: + src += f" {args[1]}" + elif node.value.func.attr == "system": + src = f"!{args[0]}" + elif node.value.func.attr == "getoutput": + src = f"!!{args[0]}" + else: + raise NothingChanged # unsupported magic. + self.magics[node.value.lineno].append( + OffsetAndMagic(node.value.col_offset, src) + ) + self.generic_visit(node) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/linegen.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/linegen.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..f010512fbd92cb8645ff0078b537d15c778c6cf8 GIT binary patch literal 50137 zcmeI*U2IfE6bJCLyDcnIplBgW&~!xtsgxGWheeStQX+-&*)`S=GVXS7+Y8&f%kHhX zwuZ(84AB@=VuLgM^}>x=Vs>U^v8ycg@RFgFh>)opDt zt%NeI_LLJBejkT*zU4ZB#0BT`66;pJ*WFx|YFrXsqL!{%-Qs?`5xw9#ZGfkx$`4FA zSEV{qd0*>w^U2SaQzGv3I-*hBk$hf}bDiVrp358MwomsXx-E*mb9wKqR5GTrxvqFB zsnT}ly7@vno#f9y$7mie@#eTyDiO0|!vn?V3-!5k-g`=%pKtg{w_QaZcZPJ>R^*-8?EkS6-3d&w8$sOU^?ylmA-rQEhiNQ=2s7Qd@Fa+vuu!uqKh? z$XP@)xRE@&2V9pb9m{)5xr3|BALR2_xrt>M1p*L&00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf z{BH#=_w?_-9H5sYW2n3`9QbZ7(XNP}4h1Q4F<43$_#W&vdQ@e`j7lt^0gGHpK5$AzzyGIZuV$OO-xfA+4Ct{dJ@K z&N=^lsDHoYDK8}_=YqP0_4DVpC)(TV7TjYb>KDfEou^b+E}d(m8_d<1mT9YaGS;?9 z@s(!NGCB-P_Luv!w@Zghek)g589P7#0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bc52~3Pn|Fwu}dzaW~e(t5OMGBa`Jk$xo?9BbH32+IWb395-2} zt!QF^_B>1ESIU%FQCZToj1I%1838)n>z?dzZ>Q7Q$e-hbM4>)++|SJfAJLx0ZhV`L z>ven=$2@(-oh6!I6gL;ekGe5G;+6n6C0t9nj^dghb4X$G-ec(a-hlTO92arP3J0zb zs(|Pkex;nDbjExtW*f4%luN&q4X|AmcfB)L@EEiBCy}2|?&m*5-CSF_N*PCV73n}vS!a+I6D!`Y%#5xY>L$DJN|j?iCY6bZ|?o@!tuKEM^AK& zf9b%1ho^ovcAxK+@XmL(zWrWn>Wkmn2THy_d2*9~O>61Z-b205Z2Rfc7nbj+-g~q8 zDTDocAL(E7R_m;dRqrov*zn}avs)vd-~Yz(4bi`roNajVX3vlGe8aCFKOSA5URpV0 z#g5;9o;GuBLpJouw>_23U#~c`IXdaxk>3AU?WRRjL%x>YQ}-p0&T6jy>M`G{SGV6e O=hFG@ZT{-X$NmNR^D5u~ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/linegen.py b/dbdpy-env/lib/python3.9/site-packages/black/linegen.py new file mode 100644 index 00000000..245be235 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/linegen.py @@ -0,0 +1,1738 @@ +""" +Generating lines of code. +""" + +import re +import sys +from dataclasses import replace +from enum import Enum, auto +from functools import partial, wraps +from typing import Collection, Iterator, List, Optional, Set, Union, cast + +from black.brackets import ( + COMMA_PRIORITY, + DOT_PRIORITY, + get_leaves_inside_matching_brackets, + max_delimiter_priority_in_atom, +) +from black.comments import FMT_OFF, generate_comments, list_comments +from black.lines import ( + Line, + RHSResult, + append_leaves, + can_be_split, + can_omit_invisible_parens, + is_line_short_enough, + line_to_string, +) +from black.mode import Feature, Mode, Preview +from black.nodes import ( + ASSIGNMENTS, + BRACKETS, + CLOSING_BRACKETS, + OPENING_BRACKETS, + RARROW, + STANDALONE_COMMENT, + STATEMENT, + WHITESPACE, + Visitor, + ensure_visible, + is_arith_like, + is_async_stmt_or_funcdef, + is_atom_with_invisible_parens, + is_docstring, + is_empty_tuple, + is_function_or_class, + is_lpar_token, + is_multiline_string, + is_name_token, + is_one_sequence_between, + is_one_tuple, + is_rpar_token, + is_stub_body, + is_stub_suite, + is_tuple_containing_walrus, + is_type_ignore_comment_string, + is_vararg, + is_walrus_assignment, + is_yield, + syms, + wrap_in_parentheses, +) +from black.numerics import normalize_numeric_literal +from black.strings import ( + fix_docstring, + get_string_prefix, + normalize_string_prefix, + normalize_string_quotes, + normalize_unicode_escape_sequences, +) +from black.trans import ( + CannotTransform, + StringMerger, + StringParenStripper, + StringParenWrapper, + StringSplitter, + Transformer, + hug_power_op, +) +from blib2to3.pgen2 import token +from blib2to3.pytree import Leaf, Node + +# types +LeafID = int +LN = Union[Leaf, Node] + + +class CannotSplit(CannotTransform): + """A readable split that fits the allotted line length is impossible.""" + + +# This isn't a dataclass because @dataclass + Generic breaks mypyc. +# See also https://github.com/mypyc/mypyc/issues/827. +class LineGenerator(Visitor[Line]): + """Generates reformatted Line objects. Empty lines are not emitted. + + Note: destroys the tree it's visiting by mutating prefixes of its leaves + in ways that will no longer stringify to valid Python code on the tree. + """ + + def __init__(self, mode: Mode, features: Collection[Feature]) -> None: + self.mode = mode + self.features = features + self.current_line: Line + self.__post_init__() + + def line(self, indent: int = 0) -> Iterator[Line]: + """Generate a line. + + If the line is empty, only emit if it makes sense. + If the line is too long, split it first and then generate. + + If any lines were generated, set up a new current_line. + """ + if not self.current_line: + self.current_line.depth += indent + return # Line is empty, don't emit. Creating a new one unnecessary. + + if ( + Preview.improved_async_statements_handling in self.mode + and len(self.current_line.leaves) == 1 + and is_async_stmt_or_funcdef(self.current_line.leaves[0]) + ): + # Special case for async def/for/with statements. `visit_async_stmt` + # adds an `ASYNC` leaf then visits the child def/for/with statement + # nodes. Line yields from those nodes shouldn't treat the former + # `ASYNC` leaf as a complete line. + return + + complete_line = self.current_line + self.current_line = Line(mode=self.mode, depth=complete_line.depth + indent) + yield complete_line + + def visit_default(self, node: LN) -> Iterator[Line]: + """Default `visit_*()` implementation. Recurses to children of `node`.""" + if isinstance(node, Leaf): + any_open_brackets = self.current_line.bracket_tracker.any_open_brackets() + for comment in generate_comments(node): + if any_open_brackets: + # any comment within brackets is subject to splitting + self.current_line.append(comment) + elif comment.type == token.COMMENT: + # regular trailing comment + self.current_line.append(comment) + yield from self.line() + + else: + # regular standalone comment + yield from self.line() + + self.current_line.append(comment) + yield from self.line() + + if any_open_brackets: + node.prefix = "" + if self.mode.string_normalization and node.type == token.STRING: + node.value = normalize_string_prefix(node.value) + node.value = normalize_string_quotes(node.value) + if node.type == token.NUMBER: + normalize_numeric_literal(node) + if node.type not in WHITESPACE: + self.current_line.append(node) + yield from super().visit_default(node) + + def visit_test(self, node: Node) -> Iterator[Line]: + """Visit an `x if y else z` test""" + + if Preview.parenthesize_conditional_expressions in self.mode: + already_parenthesized = ( + node.prev_sibling and node.prev_sibling.type == token.LPAR + ) + + if not already_parenthesized: + lpar = Leaf(token.LPAR, "") + rpar = Leaf(token.RPAR, "") + node.insert_child(0, lpar) + node.append_child(rpar) + + yield from self.visit_default(node) + + def visit_INDENT(self, node: Leaf) -> Iterator[Line]: + """Increase indentation level, maybe yield a line.""" + # In blib2to3 INDENT never holds comments. + yield from self.line(+1) + yield from self.visit_default(node) + + def visit_DEDENT(self, node: Leaf) -> Iterator[Line]: + """Decrease indentation level, maybe yield a line.""" + # The current line might still wait for trailing comments. At DEDENT time + # there won't be any (they would be prefixes on the preceding NEWLINE). + # Emit the line then. + yield from self.line() + + # While DEDENT has no value, its prefix may contain standalone comments + # that belong to the current indentation level. Get 'em. + yield from self.visit_default(node) + + # Finally, emit the dedent. + yield from self.line(-1) + + def visit_stmt( + self, node: Node, keywords: Set[str], parens: Set[str] + ) -> Iterator[Line]: + """Visit a statement. + + This implementation is shared for `if`, `while`, `for`, `try`, `except`, + `def`, `with`, `class`, `assert`, and assignments. + + The relevant Python language `keywords` for a given statement will be + NAME leaves within it. This methods puts those on a separate line. + + `parens` holds a set of string leaf values immediately after which + invisible parens should be put. + """ + normalize_invisible_parens( + node, parens_after=parens, mode=self.mode, features=self.features + ) + for child in node.children: + if is_name_token(child) and child.value in keywords: + yield from self.line() + + yield from self.visit(child) + + def visit_typeparams(self, node: Node) -> Iterator[Line]: + yield from self.visit_default(node) + node.children[0].prefix = "" + + def visit_typevartuple(self, node: Node) -> Iterator[Line]: + yield from self.visit_default(node) + node.children[1].prefix = "" + + def visit_paramspec(self, node: Node) -> Iterator[Line]: + yield from self.visit_default(node) + node.children[1].prefix = "" + + def visit_dictsetmaker(self, node: Node) -> Iterator[Line]: + if Preview.wrap_long_dict_values_in_parens in self.mode: + for i, child in enumerate(node.children): + if i == 0: + continue + if node.children[i - 1].type == token.COLON: + if child.type == syms.atom and child.children[0].type == token.LPAR: + if maybe_make_parens_invisible_in_atom( + child, + parent=node, + remove_brackets_around_comma=False, + ): + wrap_in_parentheses(node, child, visible=False) + else: + wrap_in_parentheses(node, child, visible=False) + yield from self.visit_default(node) + + def visit_funcdef(self, node: Node) -> Iterator[Line]: + """Visit function definition.""" + yield from self.line() + + # Remove redundant brackets around return type annotation. + is_return_annotation = False + for child in node.children: + if child.type == token.RARROW: + is_return_annotation = True + elif is_return_annotation: + if child.type == syms.atom and child.children[0].type == token.LPAR: + if maybe_make_parens_invisible_in_atom( + child, + parent=node, + remove_brackets_around_comma=False, + ): + wrap_in_parentheses(node, child, visible=False) + else: + wrap_in_parentheses(node, child, visible=False) + is_return_annotation = False + + for child in node.children: + yield from self.visit(child) + + def visit_match_case(self, node: Node) -> Iterator[Line]: + """Visit either a match or case statement.""" + normalize_invisible_parens( + node, parens_after=set(), mode=self.mode, features=self.features + ) + + yield from self.line() + for child in node.children: + yield from self.visit(child) + + def visit_suite(self, node: Node) -> Iterator[Line]: + """Visit a suite.""" + if ( + self.mode.is_pyi or Preview.dummy_implementations in self.mode + ) and is_stub_suite(node, self.mode): + yield from self.visit(node.children[2]) + else: + yield from self.visit_default(node) + + def visit_simple_stmt(self, node: Node) -> Iterator[Line]: + """Visit a statement without nested statements.""" + prev_type: Optional[int] = None + for child in node.children: + if (prev_type is None or prev_type == token.SEMI) and is_arith_like(child): + wrap_in_parentheses(node, child, visible=False) + prev_type = child.type + + if node.parent and node.parent.type in STATEMENT: + if Preview.dummy_implementations in self.mode: + condition = is_function_or_class(node.parent) + else: + condition = self.mode.is_pyi + if condition and is_stub_body(node): + yield from self.visit_default(node) + else: + yield from self.line(+1) + yield from self.visit_default(node) + yield from self.line(-1) + + else: + if ( + not (self.mode.is_pyi or Preview.dummy_implementations in self.mode) + or not node.parent + or not is_stub_suite(node.parent, self.mode) + ): + yield from self.line() + yield from self.visit_default(node) + + def visit_async_stmt(self, node: Node) -> Iterator[Line]: + """Visit `async def`, `async for`, `async with`.""" + yield from self.line() + + children = iter(node.children) + for child in children: + yield from self.visit(child) + + if child.type == token.ASYNC or child.type == STANDALONE_COMMENT: + # STANDALONE_COMMENT happens when `# fmt: skip` is applied on the async + # line. + break + + internal_stmt = next(children) + if Preview.improved_async_statements_handling in self.mode: + yield from self.visit(internal_stmt) + else: + for child in internal_stmt.children: + yield from self.visit(child) + + def visit_decorators(self, node: Node) -> Iterator[Line]: + """Visit decorators.""" + for child in node.children: + yield from self.line() + yield from self.visit(child) + + def visit_power(self, node: Node) -> Iterator[Line]: + for idx, leaf in enumerate(node.children[:-1]): + next_leaf = node.children[idx + 1] + + if not isinstance(leaf, Leaf): + continue + + value = leaf.value.lower() + if ( + leaf.type == token.NUMBER + and next_leaf.type == syms.trailer + # Ensure that we are in an attribute trailer + and next_leaf.children[0].type == token.DOT + # It shouldn't wrap hexadecimal, binary and octal literals + and not value.startswith(("0x", "0b", "0o")) + # It shouldn't wrap complex literals + and "j" not in value + ): + wrap_in_parentheses(node, leaf) + + remove_await_parens(node) + + yield from self.visit_default(node) + + def visit_SEMI(self, leaf: Leaf) -> Iterator[Line]: + """Remove a semicolon and put the other statement on a separate line.""" + yield from self.line() + + def visit_ENDMARKER(self, leaf: Leaf) -> Iterator[Line]: + """End of file. Process outstanding comments and end with a newline.""" + yield from self.visit_default(leaf) + yield from self.line() + + def visit_STANDALONE_COMMENT(self, leaf: Leaf) -> Iterator[Line]: + if not self.current_line.bracket_tracker.any_open_brackets(): + yield from self.line() + yield from self.visit_default(leaf) + + def visit_factor(self, node: Node) -> Iterator[Line]: + """Force parentheses between a unary op and a binary power: + + -2 ** 8 -> -(2 ** 8) + """ + _operator, operand = node.children + if ( + operand.type == syms.power + and len(operand.children) == 3 + and operand.children[1].type == token.DOUBLESTAR + ): + lpar = Leaf(token.LPAR, "(") + rpar = Leaf(token.RPAR, ")") + index = operand.remove() or 0 + node.insert_child(index, Node(syms.atom, [lpar, operand, rpar])) + yield from self.visit_default(node) + + def visit_tname(self, node: Node) -> Iterator[Line]: + """ + Add potential parentheses around types in function parameter lists to be made + into real parentheses in case the type hint is too long to fit on a line + Examples: + def foo(a: int, b: float = 7): ... + + -> + + def foo(a: (int), b: (float) = 7): ... + """ + if Preview.parenthesize_long_type_hints in self.mode: + assert len(node.children) == 3 + if maybe_make_parens_invisible_in_atom(node.children[2], parent=node): + wrap_in_parentheses(node, node.children[2], visible=False) + + yield from self.visit_default(node) + + def visit_STRING(self, leaf: Leaf) -> Iterator[Line]: + if Preview.hex_codes_in_unicode_sequences in self.mode: + normalize_unicode_escape_sequences(leaf) + + if is_docstring(leaf) and not re.search(r"\\\s*\n", leaf.value): + # We're ignoring docstrings with backslash newline escapes because changing + # indentation of those changes the AST representation of the code. + if self.mode.string_normalization: + docstring = normalize_string_prefix(leaf.value) + # visit_default() does handle string normalization for us, but + # since this method acts differently depending on quote style (ex. + # see padding logic below), there's a possibility for unstable + # formatting as visit_default() is called *after*. To avoid a + # situation where this function formats a docstring differently on + # the second pass, normalize it early. + docstring = normalize_string_quotes(docstring) + else: + docstring = leaf.value + prefix = get_string_prefix(docstring) + docstring = docstring[len(prefix) :] # Remove the prefix + quote_char = docstring[0] + # A natural way to remove the outer quotes is to do: + # docstring = docstring.strip(quote_char) + # but that breaks on """""x""" (which is '""x'). + # So we actually need to remove the first character and the next two + # characters but only if they are the same as the first. + quote_len = 1 if docstring[1] != quote_char else 3 + docstring = docstring[quote_len:-quote_len] + docstring_started_empty = not docstring + indent = " " * 4 * self.current_line.depth + + if is_multiline_string(leaf): + docstring = fix_docstring(docstring, indent) + else: + docstring = docstring.strip() + + has_trailing_backslash = False + if docstring: + # Add some padding if the docstring starts / ends with a quote mark. + if docstring[0] == quote_char: + docstring = " " + docstring + if docstring[-1] == quote_char: + docstring += " " + if docstring[-1] == "\\": + backslash_count = len(docstring) - len(docstring.rstrip("\\")) + if backslash_count % 2: + # Odd number of tailing backslashes, add some padding to + # avoid escaping the closing string quote. + docstring += " " + has_trailing_backslash = True + elif not docstring_started_empty: + docstring = " " + + # We could enforce triple quotes at this point. + quote = quote_char * quote_len + + # It's invalid to put closing single-character quotes on a new line. + if self.mode and quote_len == 3: + # We need to find the length of the last line of the docstring + # to find if we can add the closing quotes to the line without + # exceeding the maximum line length. + # If docstring is one line, we don't put the closing quotes on a + # separate line because it looks ugly (#3320). + lines = docstring.splitlines() + last_line_length = len(lines[-1]) if docstring else 0 + + # If adding closing quotes would cause the last line to exceed + # the maximum line length then put a line break before the + # closing quotes + if ( + len(lines) > 1 + and last_line_length + quote_len > self.mode.line_length + and len(indent) + quote_len <= self.mode.line_length + and not has_trailing_backslash + ): + leaf.value = prefix + quote + docstring + "\n" + indent + quote + else: + leaf.value = prefix + quote + docstring + quote + else: + leaf.value = prefix + quote + docstring + quote + + yield from self.visit_default(leaf) + + def __post_init__(self) -> None: + """You are in a twisty little maze of passages.""" + self.current_line = Line(mode=self.mode) + + v = self.visit_stmt + Ø: Set[str] = set() + self.visit_assert_stmt = partial(v, keywords={"assert"}, parens={"assert", ","}) + self.visit_if_stmt = partial( + v, keywords={"if", "else", "elif"}, parens={"if", "elif"} + ) + self.visit_while_stmt = partial(v, keywords={"while", "else"}, parens={"while"}) + self.visit_for_stmt = partial(v, keywords={"for", "else"}, parens={"for", "in"}) + self.visit_try_stmt = partial( + v, keywords={"try", "except", "else", "finally"}, parens=Ø + ) + self.visit_except_clause = partial(v, keywords={"except"}, parens={"except"}) + self.visit_with_stmt = partial(v, keywords={"with"}, parens={"with"}) + self.visit_classdef = partial(v, keywords={"class"}, parens=Ø) + + # When this is moved out of preview, add ":" directly to ASSIGNMENTS in nodes.py + if Preview.parenthesize_long_type_hints in self.mode: + assignments = ASSIGNMENTS | {":"} + else: + assignments = ASSIGNMENTS + self.visit_expr_stmt = partial(v, keywords=Ø, parens=assignments) + + self.visit_return_stmt = partial(v, keywords={"return"}, parens={"return"}) + self.visit_import_from = partial(v, keywords=Ø, parens={"import"}) + self.visit_del_stmt = partial(v, keywords=Ø, parens={"del"}) + self.visit_async_funcdef = self.visit_async_stmt + self.visit_decorated = self.visit_decorators + + # PEP 634 + self.visit_match_stmt = self.visit_match_case + self.visit_case_block = self.visit_match_case + + +def _hugging_power_ops_line_to_string( + line: Line, + features: Collection[Feature], + mode: Mode, +) -> Optional[str]: + try: + return line_to_string(next(hug_power_op(line, features, mode))) + except CannotTransform: + return None + + +def transform_line( + line: Line, mode: Mode, features: Collection[Feature] = () +) -> Iterator[Line]: + """Transform a `line`, potentially splitting it into many lines. + + They should fit in the allotted `line_length` but might not be able to. + + `features` are syntactical features that may be used in the output. + """ + if line.is_comment: + yield line + return + + line_str = line_to_string(line) + + # We need the line string when power operators are hugging to determine if we should + # split the line. Default to line_str, if no power operator are present on the line. + line_str_hugging_power_ops = ( + (_hugging_power_ops_line_to_string(line, features, mode) or line_str) + if Preview.fix_power_op_line_length in mode + else line_str + ) + + ll = mode.line_length + sn = mode.string_normalization + string_merge = StringMerger(ll, sn) + string_paren_strip = StringParenStripper(ll, sn) + string_split = StringSplitter(ll, sn) + string_paren_wrap = StringParenWrapper(ll, sn) + + transformers: List[Transformer] + if ( + not line.contains_uncollapsable_type_comments() + and not line.should_split_rhs + and not line.magic_trailing_comma + and ( + is_line_short_enough(line, mode=mode, line_str=line_str_hugging_power_ops) + or line.contains_unsplittable_type_ignore() + ) + and not (line.inside_brackets and line.contains_standalone_comments()) + and not line.contains_implicit_multiline_string_with_comments() + ): + # Only apply basic string preprocessing, since lines shouldn't be split here. + if Preview.string_processing in mode: + transformers = [string_merge, string_paren_strip] + else: + transformers = [] + elif line.is_def and not should_split_funcdef_with_rhs(line, mode): + transformers = [left_hand_split] + else: + + def _rhs( + self: object, line: Line, features: Collection[Feature], mode: Mode + ) -> Iterator[Line]: + """Wraps calls to `right_hand_split`. + + The calls increasingly `omit` right-hand trailers (bracket pairs with + content), meaning the trailers get glued together to split on another + bracket pair instead. + """ + for omit in generate_trailers_to_omit(line, mode.line_length): + lines = list(right_hand_split(line, mode, features, omit=omit)) + # Note: this check is only able to figure out if the first line of the + # *current* transformation fits in the line length. This is true only + # for simple cases. All others require running more transforms via + # `transform_line()`. This check doesn't know if those would succeed. + if is_line_short_enough(lines[0], mode=mode): + yield from lines + return + + # All splits failed, best effort split with no omits. + # This mostly happens to multiline strings that are by definition + # reported as not fitting a single line, as well as lines that contain + # trailing commas (those have to be exploded). + yield from right_hand_split(line, mode, features=features) + + # HACK: nested functions (like _rhs) compiled by mypyc don't retain their + # __name__ attribute which is needed in `run_transformer` further down. + # Unfortunately a nested class breaks mypyc too. So a class must be created + # via type ... https://github.com/mypyc/mypyc/issues/884 + rhs = type("rhs", (), {"__call__": _rhs})() + + if Preview.string_processing in mode: + if line.inside_brackets: + transformers = [ + string_merge, + string_paren_strip, + string_split, + delimiter_split, + standalone_comment_split, + string_paren_wrap, + rhs, + ] + else: + transformers = [ + string_merge, + string_paren_strip, + string_split, + string_paren_wrap, + rhs, + ] + else: + if line.inside_brackets: + transformers = [delimiter_split, standalone_comment_split, rhs] + else: + transformers = [rhs] + # It's always safe to attempt hugging of power operations and pretty much every line + # could match. + transformers.append(hug_power_op) + + for transform in transformers: + # We are accumulating lines in `result` because we might want to abort + # mission and return the original line in the end, or attempt a different + # split altogether. + try: + result = run_transformer(line, transform, mode, features, line_str=line_str) + except CannotTransform: + continue + else: + yield from result + break + + else: + yield line + + +def should_split_funcdef_with_rhs(line: Line, mode: Mode) -> bool: + """If a funcdef has a magic trailing comma in the return type, then we should first + split the line with rhs to respect the comma. + """ + if Preview.respect_magic_trailing_comma_in_return_type not in mode: + return False + + return_type_leaves: List[Leaf] = [] + in_return_type = False + + for leaf in line.leaves: + if leaf.type == token.COLON: + in_return_type = False + if in_return_type: + return_type_leaves.append(leaf) + if leaf.type == token.RARROW: + in_return_type = True + + # using `bracket_split_build_line` will mess with whitespace, so we duplicate a + # couple lines from it. + result = Line(mode=line.mode, depth=line.depth) + leaves_to_track = get_leaves_inside_matching_brackets(return_type_leaves) + for leaf in return_type_leaves: + result.append( + leaf, + preformatted=True, + track_bracket=id(leaf) in leaves_to_track, + ) + + # we could also return true if the line is too long, and the return type is longer + # than the param list. Or if `should_split_rhs` returns True. + return result.magic_trailing_comma is not None + + +class _BracketSplitComponent(Enum): + head = auto() + body = auto() + tail = auto() + + +def left_hand_split( + line: Line, _features: Collection[Feature], mode: Mode +) -> Iterator[Line]: + """Split line into many lines, starting with the first matching bracket pair. + + Note: this usually looks weird, only use this for function definitions. + Prefer RHS otherwise. This is why this function is not symmetrical with + :func:`right_hand_split` which also handles optional parentheses. + """ + tail_leaves: List[Leaf] = [] + body_leaves: List[Leaf] = [] + head_leaves: List[Leaf] = [] + current_leaves = head_leaves + matching_bracket: Optional[Leaf] = None + for leaf in line.leaves: + if ( + current_leaves is body_leaves + and leaf.type in CLOSING_BRACKETS + and leaf.opening_bracket is matching_bracket + and isinstance(matching_bracket, Leaf) + ): + ensure_visible(leaf) + ensure_visible(matching_bracket) + current_leaves = tail_leaves if body_leaves else head_leaves + current_leaves.append(leaf) + if current_leaves is head_leaves: + if leaf.type in OPENING_BRACKETS: + matching_bracket = leaf + current_leaves = body_leaves + if not matching_bracket or not tail_leaves: + raise CannotSplit("No brackets found") + + head = bracket_split_build_line( + head_leaves, line, matching_bracket, component=_BracketSplitComponent.head + ) + body = bracket_split_build_line( + body_leaves, line, matching_bracket, component=_BracketSplitComponent.body + ) + tail = bracket_split_build_line( + tail_leaves, line, matching_bracket, component=_BracketSplitComponent.tail + ) + bracket_split_succeeded_or_raise(head, body, tail) + for result in (head, body, tail): + if result: + yield result + + +def right_hand_split( + line: Line, + mode: Mode, + features: Collection[Feature] = (), + omit: Collection[LeafID] = (), +) -> Iterator[Line]: + """Split line into many lines, starting with the last matching bracket pair. + + If the split was by optional parentheses, attempt splitting without them, too. + `omit` is a collection of closing bracket IDs that shouldn't be considered for + this split. + + Note: running this function modifies `bracket_depth` on the leaves of `line`. + """ + rhs_result = _first_right_hand_split(line, omit=omit) + yield from _maybe_split_omitting_optional_parens( + rhs_result, line, mode, features=features, omit=omit + ) + + +def _first_right_hand_split( + line: Line, + omit: Collection[LeafID] = (), +) -> RHSResult: + """Split the line into head, body, tail starting with the last bracket pair. + + Note: this function should not have side effects. It's relied upon by + _maybe_split_omitting_optional_parens to get an opinion whether to prefer + splitting on the right side of an assignment statement. + """ + tail_leaves: List[Leaf] = [] + body_leaves: List[Leaf] = [] + head_leaves: List[Leaf] = [] + current_leaves = tail_leaves + opening_bracket: Optional[Leaf] = None + closing_bracket: Optional[Leaf] = None + for leaf in reversed(line.leaves): + if current_leaves is body_leaves: + if leaf is opening_bracket: + current_leaves = head_leaves if body_leaves else tail_leaves + current_leaves.append(leaf) + if current_leaves is tail_leaves: + if leaf.type in CLOSING_BRACKETS and id(leaf) not in omit: + opening_bracket = leaf.opening_bracket + closing_bracket = leaf + current_leaves = body_leaves + if not (opening_bracket and closing_bracket and head_leaves): + # If there is no opening or closing_bracket that means the split failed and + # all content is in the tail. Otherwise, if `head_leaves` are empty, it means + # the matching `opening_bracket` wasn't available on `line` anymore. + raise CannotSplit("No brackets found") + + tail_leaves.reverse() + body_leaves.reverse() + head_leaves.reverse() + + body: Optional[Line] = None + if ( + Preview.hug_parens_with_braces_and_square_brackets in line.mode + and tail_leaves[0].value + and tail_leaves[0].opening_bracket is head_leaves[-1] + ): + inner_body_leaves = list(body_leaves) + hugged_opening_leaves: List[Leaf] = [] + hugged_closing_leaves: List[Leaf] = [] + is_unpacking = body_leaves[0].type in [token.STAR, token.DOUBLESTAR] + unpacking_offset: int = 1 if is_unpacking else 0 + while ( + len(inner_body_leaves) >= 2 + unpacking_offset + and inner_body_leaves[-1].type in CLOSING_BRACKETS + and inner_body_leaves[-1].opening_bracket + is inner_body_leaves[unpacking_offset] + ): + if unpacking_offset: + hugged_opening_leaves.append(inner_body_leaves.pop(0)) + unpacking_offset = 0 + hugged_opening_leaves.append(inner_body_leaves.pop(0)) + hugged_closing_leaves.insert(0, inner_body_leaves.pop()) + + if hugged_opening_leaves and inner_body_leaves: + inner_body = bracket_split_build_line( + inner_body_leaves, + line, + hugged_opening_leaves[-1], + component=_BracketSplitComponent.body, + ) + if ( + line.mode.magic_trailing_comma + and inner_body_leaves[-1].type == token.COMMA + ): + should_hug = True + else: + line_length = line.mode.line_length - sum( + len(str(leaf)) + for leaf in hugged_opening_leaves + hugged_closing_leaves + ) + if is_line_short_enough( + inner_body, mode=replace(line.mode, line_length=line_length) + ): + # Do not hug if it fits on a single line. + should_hug = False + else: + should_hug = True + if should_hug: + body_leaves = inner_body_leaves + head_leaves.extend(hugged_opening_leaves) + tail_leaves = hugged_closing_leaves + tail_leaves + body = inner_body # No need to re-calculate the body again later. + + head = bracket_split_build_line( + head_leaves, line, opening_bracket, component=_BracketSplitComponent.head + ) + if body is None: + body = bracket_split_build_line( + body_leaves, line, opening_bracket, component=_BracketSplitComponent.body + ) + tail = bracket_split_build_line( + tail_leaves, line, opening_bracket, component=_BracketSplitComponent.tail + ) + bracket_split_succeeded_or_raise(head, body, tail) + return RHSResult(head, body, tail, opening_bracket, closing_bracket) + + +def _maybe_split_omitting_optional_parens( + rhs: RHSResult, + line: Line, + mode: Mode, + features: Collection[Feature] = (), + omit: Collection[LeafID] = (), +) -> Iterator[Line]: + if ( + Feature.FORCE_OPTIONAL_PARENTHESES not in features + # the opening bracket is an optional paren + and rhs.opening_bracket.type == token.LPAR + and not rhs.opening_bracket.value + # the closing bracket is an optional paren + and rhs.closing_bracket.type == token.RPAR + and not rhs.closing_bracket.value + # it's not an import (optional parens are the only thing we can split on + # in this case; attempting a split without them is a waste of time) + and not line.is_import + # and we can actually remove the parens + and can_omit_invisible_parens(rhs, mode.line_length) + ): + omit = {id(rhs.closing_bracket), *omit} + try: + # The RHSResult Omitting Optional Parens. + rhs_oop = _first_right_hand_split(line, omit=omit) + prefer_splitting_rhs_mode = ( + Preview.prefer_splitting_right_hand_side_of_assignments in line.mode + ) + is_split_right_after_equal = ( + len(rhs.head.leaves) >= 2 and rhs.head.leaves[-2].type == token.EQUAL + ) + rhs_head_contains_brackets = any( + leaf.type in BRACKETS for leaf in rhs.head.leaves[:-1] + ) + # the -1 is for the ending optional paren + rhs_head_short_enough = is_line_short_enough( + rhs.head, mode=replace(mode, line_length=mode.line_length - 1) + ) + rhs_head_explode_blocked_by_magic_trailing_comma = ( + rhs.head.magic_trailing_comma is None + ) + if ( + not ( + prefer_splitting_rhs_mode + and is_split_right_after_equal + and rhs_head_contains_brackets + and rhs_head_short_enough + and rhs_head_explode_blocked_by_magic_trailing_comma + ) + # the omit optional parens split is preferred by some other reason + or _prefer_split_rhs_oop_over_rhs(rhs_oop, rhs, mode) + ): + yield from _maybe_split_omitting_optional_parens( + rhs_oop, line, mode, features=features, omit=omit + ) + return + + except CannotSplit as e: + # For chained assignments we want to use the previous successful split + if line.is_chained_assignment: + pass + + elif not can_be_split(rhs.body) and not is_line_short_enough( + rhs.body, mode=mode + ): + raise CannotSplit( + "Splitting failed, body is still too long and can't be split." + ) from e + + elif ( + rhs.head.contains_multiline_strings() + or rhs.tail.contains_multiline_strings() + ): + raise CannotSplit( + "The current optional pair of parentheses is bound to fail to" + " satisfy the splitting algorithm because the head or the tail" + " contains multiline strings which by definition never fit one" + " line." + ) from e + + ensure_visible(rhs.opening_bracket) + ensure_visible(rhs.closing_bracket) + for result in (rhs.head, rhs.body, rhs.tail): + if result: + yield result + + +def _prefer_split_rhs_oop_over_rhs( + rhs_oop: RHSResult, rhs: RHSResult, mode: Mode +) -> bool: + """ + Returns whether we should prefer the result from a split omitting optional parens + (rhs_oop) over the original (rhs). + """ + # If we have multiple targets, we prefer more `=`s on the head vs pushing them to + # the body + rhs_head_equal_count = [leaf.type for leaf in rhs.head.leaves].count(token.EQUAL) + rhs_oop_head_equal_count = [leaf.type for leaf in rhs_oop.head.leaves].count( + token.EQUAL + ) + if rhs_head_equal_count > 1 and rhs_head_equal_count > rhs_oop_head_equal_count: + return False + + has_closing_bracket_after_assign = False + for leaf in reversed(rhs_oop.head.leaves): + if leaf.type == token.EQUAL: + break + if leaf.type in CLOSING_BRACKETS: + has_closing_bracket_after_assign = True + break + return ( + # contains matching brackets after the `=` (done by checking there is a + # closing bracket) + has_closing_bracket_after_assign + or ( + # the split is actually from inside the optional parens (done by checking + # the first line still contains the `=`) + any(leaf.type == token.EQUAL for leaf in rhs_oop.head.leaves) + # the first line is short enough + and is_line_short_enough(rhs_oop.head, mode=mode) + ) + # contains unsplittable type ignore + or rhs_oop.head.contains_unsplittable_type_ignore() + or rhs_oop.body.contains_unsplittable_type_ignore() + or rhs_oop.tail.contains_unsplittable_type_ignore() + ) + + +def bracket_split_succeeded_or_raise(head: Line, body: Line, tail: Line) -> None: + """Raise :exc:`CannotSplit` if the last left- or right-hand split failed. + + Do nothing otherwise. + + A left- or right-hand split is based on a pair of brackets. Content before + (and including) the opening bracket is left on one line, content inside the + brackets is put on a separate line, and finally content starting with and + following the closing bracket is put on a separate line. + + Those are called `head`, `body`, and `tail`, respectively. If the split + produced the same line (all content in `head`) or ended up with an empty `body` + and the `tail` is just the closing bracket, then it's considered failed. + """ + tail_len = len(str(tail).strip()) + if not body: + if tail_len == 0: + raise CannotSplit("Splitting brackets produced the same line") + + elif tail_len < 3: + raise CannotSplit( + f"Splitting brackets on an empty body to save {tail_len} characters is" + " not worth it" + ) + + +def bracket_split_build_line( + leaves: List[Leaf], + original: Line, + opening_bracket: Leaf, + *, + component: _BracketSplitComponent, +) -> Line: + """Return a new line with given `leaves` and respective comments from `original`. + + If it's the head component, brackets will be tracked so trailing commas are + respected. + + If it's the body component, the result line is one-indented inside brackets and as + such has its first leaf's prefix normalized and a trailing comma added when + expected. + """ + result = Line(mode=original.mode, depth=original.depth) + if component is _BracketSplitComponent.body: + result.inside_brackets = True + result.depth += 1 + if leaves: + # Ensure a trailing comma for imports and standalone function arguments, but + # be careful not to add one after any comments or within type annotations. + no_commas = ( + original.is_def + and opening_bracket.value == "(" + and not any(leaf.type == token.COMMA for leaf in leaves) + # In particular, don't add one within a parenthesized return annotation. + # Unfortunately the indicator we're in a return annotation (RARROW) may + # be defined directly in the parent node, the parent of the parent ... + # and so on depending on how complex the return annotation is. + # This isn't perfect and there's some false negatives but they are in + # contexts were a comma is actually fine. + and not any( + node.prev_sibling.type == RARROW + for node in ( + leaves[0].parent, + getattr(leaves[0].parent, "parent", None), + ) + if isinstance(node, Node) and isinstance(node.prev_sibling, Leaf) + ) + # Except the false negatives above for PEP 604 unions where we + # can't add the comma. + and not ( + leaves[0].parent + and leaves[0].parent.next_sibling + and leaves[0].parent.next_sibling.type == token.VBAR + ) + ) + + if original.is_import or no_commas: + for i in range(len(leaves) - 1, -1, -1): + if leaves[i].type == STANDALONE_COMMENT: + continue + + if leaves[i].type != token.COMMA: + new_comma = Leaf(token.COMMA, ",") + leaves.insert(i + 1, new_comma) + break + + leaves_to_track: Set[LeafID] = set() + if component is _BracketSplitComponent.head: + leaves_to_track = get_leaves_inside_matching_brackets(leaves) + # Populate the line + for leaf in leaves: + result.append( + leaf, + preformatted=True, + track_bracket=id(leaf) in leaves_to_track, + ) + for comment_after in original.comments_after(leaf): + result.append(comment_after, preformatted=True) + if component is _BracketSplitComponent.body and should_split_line( + result, opening_bracket + ): + result.should_split_rhs = True + return result + + +def dont_increase_indentation(split_func: Transformer) -> Transformer: + """Normalize prefix of the first leaf in every line returned by `split_func`. + + This is a decorator over relevant split functions. + """ + + @wraps(split_func) + def split_wrapper( + line: Line, features: Collection[Feature], mode: Mode + ) -> Iterator[Line]: + for split_line in split_func(line, features, mode): + split_line.leaves[0].prefix = "" + yield split_line + + return split_wrapper + + +def _get_last_non_comment_leaf(line: Line) -> Optional[int]: + for leaf_idx in range(len(line.leaves) - 1, 0, -1): + if line.leaves[leaf_idx].type != STANDALONE_COMMENT: + return leaf_idx + return None + + +def _safe_add_trailing_comma(safe: bool, delimiter_priority: int, line: Line) -> Line: + if ( + safe + and delimiter_priority == COMMA_PRIORITY + and line.leaves[-1].type != token.COMMA + and line.leaves[-1].type != STANDALONE_COMMENT + ): + new_comma = Leaf(token.COMMA, ",") + line.append(new_comma) + return line + + +@dont_increase_indentation +def delimiter_split( + line: Line, features: Collection[Feature], mode: Mode +) -> Iterator[Line]: + """Split according to delimiters of the highest priority. + + If the appropriate Features are given, the split will add trailing commas + also in function signatures and calls that contain `*` and `**`. + """ + try: + last_leaf = line.leaves[-1] + except IndexError: + raise CannotSplit("Line empty") from None + + bt = line.bracket_tracker + try: + delimiter_priority = bt.max_delimiter_priority(exclude={id(last_leaf)}) + except ValueError: + raise CannotSplit("No delimiters found") from None + + if delimiter_priority == DOT_PRIORITY: + if bt.delimiter_count_with_priority(delimiter_priority) == 1: + raise CannotSplit("Splitting a single attribute from its owner looks wrong") + + current_line = Line( + mode=line.mode, depth=line.depth, inside_brackets=line.inside_brackets + ) + lowest_depth = sys.maxsize + trailing_comma_safe = True + + def append_to_line(leaf: Leaf) -> Iterator[Line]: + """Append `leaf` to current line or to new line if appending impossible.""" + nonlocal current_line + try: + current_line.append_safe(leaf, preformatted=True) + except ValueError: + yield current_line + + current_line = Line( + mode=line.mode, depth=line.depth, inside_brackets=line.inside_brackets + ) + current_line.append(leaf) + + last_non_comment_leaf = _get_last_non_comment_leaf(line) + for leaf_idx, leaf in enumerate(line.leaves): + yield from append_to_line(leaf) + + for comment_after in line.comments_after(leaf): + yield from append_to_line(comment_after) + + lowest_depth = min(lowest_depth, leaf.bracket_depth) + if leaf.bracket_depth == lowest_depth: + if is_vararg(leaf, within={syms.typedargslist}): + trailing_comma_safe = ( + trailing_comma_safe and Feature.TRAILING_COMMA_IN_DEF in features + ) + elif is_vararg(leaf, within={syms.arglist, syms.argument}): + trailing_comma_safe = ( + trailing_comma_safe and Feature.TRAILING_COMMA_IN_CALL in features + ) + + if ( + Preview.add_trailing_comma_consistently in mode + and last_leaf.type == STANDALONE_COMMENT + and leaf_idx == last_non_comment_leaf + ): + current_line = _safe_add_trailing_comma( + trailing_comma_safe, delimiter_priority, current_line + ) + + leaf_priority = bt.delimiters.get(id(leaf)) + if leaf_priority == delimiter_priority: + yield current_line + + current_line = Line( + mode=line.mode, depth=line.depth, inside_brackets=line.inside_brackets + ) + if current_line: + current_line = _safe_add_trailing_comma( + trailing_comma_safe, delimiter_priority, current_line + ) + yield current_line + + +@dont_increase_indentation +def standalone_comment_split( + line: Line, features: Collection[Feature], mode: Mode +) -> Iterator[Line]: + """Split standalone comments from the rest of the line.""" + if not line.contains_standalone_comments(): + raise CannotSplit("Line does not have any standalone comments") + + current_line = Line( + mode=line.mode, depth=line.depth, inside_brackets=line.inside_brackets + ) + + def append_to_line(leaf: Leaf) -> Iterator[Line]: + """Append `leaf` to current line or to new line if appending impossible.""" + nonlocal current_line + try: + current_line.append_safe(leaf, preformatted=True) + except ValueError: + yield current_line + + current_line = Line( + line.mode, depth=line.depth, inside_brackets=line.inside_brackets + ) + current_line.append(leaf) + + for leaf in line.leaves: + yield from append_to_line(leaf) + + for comment_after in line.comments_after(leaf): + yield from append_to_line(comment_after) + + if current_line: + yield current_line + + +def normalize_invisible_parens( # noqa: C901 + node: Node, parens_after: Set[str], *, mode: Mode, features: Collection[Feature] +) -> None: + """Make existing optional parentheses invisible or create new ones. + + `parens_after` is a set of string leaf values immediately after which parens + should be put. + + Standardizes on visible parentheses for single-element tuples, and keeps + existing visible parentheses for other tuples and generator expressions. + """ + for pc in list_comments(node.prefix, is_endmarker=False): + if pc.value in FMT_OFF: + # This `node` has a prefix with `# fmt: off`, don't mess with parens. + return + + # The multiple context managers grammar has a different pattern, thus this is + # separate from the for-loop below. This possibly wraps them in invisible parens, + # and later will be removed in remove_with_parens when needed. + if node.type == syms.with_stmt: + _maybe_wrap_cms_in_parens(node, mode, features) + + check_lpar = False + for index, child in enumerate(list(node.children)): + # Fixes a bug where invisible parens are not properly stripped from + # assignment statements that contain type annotations. + if isinstance(child, Node) and child.type == syms.annassign: + normalize_invisible_parens( + child, parens_after=parens_after, mode=mode, features=features + ) + + # Fixes a bug where invisible parens are not properly wrapped around + # case blocks. + if ( + isinstance(child, Node) + and child.type == syms.case_block + and Preview.long_case_block_line_splitting in mode + ): + normalize_invisible_parens( + child, parens_after={"case"}, mode=mode, features=features + ) + + # Add parentheses around long tuple unpacking in assignments. + if ( + index == 0 + and isinstance(child, Node) + and child.type == syms.testlist_star_expr + ): + check_lpar = True + + if check_lpar: + if ( + child.type == syms.atom + and node.type == syms.for_stmt + and isinstance(child.prev_sibling, Leaf) + and child.prev_sibling.type == token.NAME + and child.prev_sibling.value == "for" + ): + if maybe_make_parens_invisible_in_atom( + child, + parent=node, + remove_brackets_around_comma=True, + ): + wrap_in_parentheses(node, child, visible=False) + elif isinstance(child, Node) and node.type == syms.with_stmt: + remove_with_parens(child, node) + elif child.type == syms.atom: + if maybe_make_parens_invisible_in_atom( + child, + parent=node, + ): + wrap_in_parentheses(node, child, visible=False) + elif is_one_tuple(child): + wrap_in_parentheses(node, child, visible=True) + elif node.type == syms.import_from: + _normalize_import_from(node, child, index) + break + elif ( + index == 1 + and child.type == token.STAR + and node.type == syms.except_clause + ): + # In except* (PEP 654), the star is actually part of + # of the keyword. So we need to skip the insertion of + # invisible parentheses to work more precisely. + continue + + elif ( + isinstance(child, Leaf) + and child.next_sibling is not None + and child.next_sibling.type == token.COLON + and child.value == "case" + and Preview.long_case_block_line_splitting in mode + ): + # A special patch for "case case:" scenario, the second occurrence + # of case will be not parsed as a Python keyword. + break + + elif not (isinstance(child, Leaf) and is_multiline_string(child)): + wrap_in_parentheses(node, child, visible=False) + + comma_check = child.type == token.COMMA + + check_lpar = isinstance(child, Leaf) and ( + child.value in parens_after or comma_check + ) + + +def _normalize_import_from(parent: Node, child: LN, index: int) -> None: + # "import from" nodes store parentheses directly as part of + # the statement + if is_lpar_token(child): + assert is_rpar_token(parent.children[-1]) + # make parentheses invisible + child.value = "" + parent.children[-1].value = "" + elif child.type != token.STAR: + # insert invisible parentheses + parent.insert_child(index, Leaf(token.LPAR, "")) + parent.append_child(Leaf(token.RPAR, "")) + + +def remove_await_parens(node: Node) -> None: + if node.children[0].type == token.AWAIT and len(node.children) > 1: + if ( + node.children[1].type == syms.atom + and node.children[1].children[0].type == token.LPAR + ): + if maybe_make_parens_invisible_in_atom( + node.children[1], + parent=node, + remove_brackets_around_comma=True, + ): + wrap_in_parentheses(node, node.children[1], visible=False) + + # Since await is an expression we shouldn't remove + # brackets in cases where this would change + # the AST due to operator precedence. + # Therefore we only aim to remove brackets around + # power nodes that aren't also await expressions themselves. + # https://peps.python.org/pep-0492/#updated-operator-precedence-table + # N.B. We've still removed any redundant nested brackets though :) + opening_bracket = cast(Leaf, node.children[1].children[0]) + closing_bracket = cast(Leaf, node.children[1].children[-1]) + bracket_contents = node.children[1].children[1] + if isinstance(bracket_contents, Node) and ( + bracket_contents.type != syms.power + or bracket_contents.children[0].type == token.AWAIT + or any( + isinstance(child, Leaf) and child.type == token.DOUBLESTAR + for child in bracket_contents.children + ) + ): + ensure_visible(opening_bracket) + ensure_visible(closing_bracket) + + +def _maybe_wrap_cms_in_parens( + node: Node, mode: Mode, features: Collection[Feature] +) -> None: + """When enabled and safe, wrap the multiple context managers in invisible parens. + + It is only safe when `features` contain Feature.PARENTHESIZED_CONTEXT_MANAGERS. + """ + if ( + Feature.PARENTHESIZED_CONTEXT_MANAGERS not in features + or Preview.wrap_multiple_context_managers_in_parens not in mode + or len(node.children) <= 2 + # If it's an atom, it's already wrapped in parens. + or node.children[1].type == syms.atom + ): + return + colon_index: Optional[int] = None + for i in range(2, len(node.children)): + if node.children[i].type == token.COLON: + colon_index = i + break + if colon_index is not None: + lpar = Leaf(token.LPAR, "") + rpar = Leaf(token.RPAR, "") + context_managers = node.children[1:colon_index] + for child in context_managers: + child.remove() + # After wrapping, the with_stmt will look like this: + # with_stmt + # NAME 'with' + # atom + # LPAR '' + # testlist_gexp + # ... <-- context_managers + # /testlist_gexp + # RPAR '' + # /atom + # COLON ':' + new_child = Node( + syms.atom, [lpar, Node(syms.testlist_gexp, context_managers), rpar] + ) + node.insert_child(1, new_child) + + +def remove_with_parens(node: Node, parent: Node) -> None: + """Recursively hide optional parens in `with` statements.""" + # Removing all unnecessary parentheses in with statements in one pass is a tad + # complex as different variations of bracketed statements result in pretty + # different parse trees: + # + # with (open("file")) as f: # this is an asexpr_test + # ... + # + # with (open("file") as f): # this is an atom containing an + # ... # asexpr_test + # + # with (open("file")) as f, (open("file")) as f: # this is asexpr_test, COMMA, + # ... # asexpr_test + # + # with (open("file") as f, open("file") as f): # an atom containing a + # ... # testlist_gexp which then + # # contains multiple asexpr_test(s) + if node.type == syms.atom: + if maybe_make_parens_invisible_in_atom( + node, + parent=parent, + remove_brackets_around_comma=True, + ): + wrap_in_parentheses(parent, node, visible=False) + if isinstance(node.children[1], Node): + remove_with_parens(node.children[1], node) + elif node.type == syms.testlist_gexp: + for child in node.children: + if isinstance(child, Node): + remove_with_parens(child, node) + elif node.type == syms.asexpr_test and not any( + leaf.type == token.COLONEQUAL for leaf in node.leaves() + ): + if maybe_make_parens_invisible_in_atom( + node.children[0], + parent=node, + remove_brackets_around_comma=True, + ): + wrap_in_parentheses(node, node.children[0], visible=False) + + +def maybe_make_parens_invisible_in_atom( + node: LN, + parent: LN, + remove_brackets_around_comma: bool = False, +) -> bool: + """If it's safe, make the parens in the atom `node` invisible, recursively. + Additionally, remove repeated, adjacent invisible parens from the atom `node` + as they are redundant. + + Returns whether the node should itself be wrapped in invisible parentheses. + """ + if ( + node.type not in (syms.atom, syms.expr) + or is_empty_tuple(node) + or is_one_tuple(node) + or (is_yield(node) and parent.type != syms.expr_stmt) + or ( + # This condition tries to prevent removing non-optional brackets + # around a tuple, however, can be a bit overzealous so we provide + # and option to skip this check for `for` and `with` statements. + not remove_brackets_around_comma + and max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY + ) + or is_tuple_containing_walrus(node) + ): + return False + + if is_walrus_assignment(node): + if parent.type in [ + syms.annassign, + syms.expr_stmt, + syms.assert_stmt, + syms.return_stmt, + syms.except_clause, + syms.funcdef, + syms.with_stmt, + syms.tname, + # these ones aren't useful to end users, but they do please fuzzers + syms.for_stmt, + syms.del_stmt, + syms.for_stmt, + ]: + return False + + first = node.children[0] + last = node.children[-1] + if is_lpar_token(first) and is_rpar_token(last): + middle = node.children[1] + # make parentheses invisible + if ( + # If the prefix of `middle` includes a type comment with + # ignore annotation, then we do not remove the parentheses + not is_type_ignore_comment_string(middle.prefix.strip()) + ): + first.value = "" + last.value = "" + maybe_make_parens_invisible_in_atom( + middle, + parent=parent, + remove_brackets_around_comma=remove_brackets_around_comma, + ) + + if is_atom_with_invisible_parens(middle): + # Strip the invisible parens from `middle` by replacing + # it with the child in-between the invisible parens + middle.replace(middle.children[1]) + + return False + + return True + + +def should_split_line(line: Line, opening_bracket: Leaf) -> bool: + """Should `line` be immediately split with `delimiter_split()` after RHS?""" + + if not (opening_bracket.parent and opening_bracket.value in "[{("): + return False + + # We're essentially checking if the body is delimited by commas and there's more + # than one of them (we're excluding the trailing comma and if the delimiter priority + # is still commas, that means there's more). + exclude = set() + trailing_comma = False + try: + last_leaf = line.leaves[-1] + if last_leaf.type == token.COMMA: + trailing_comma = True + exclude.add(id(last_leaf)) + max_priority = line.bracket_tracker.max_delimiter_priority(exclude=exclude) + except (IndexError, ValueError): + return False + + return max_priority == COMMA_PRIORITY and ( + (line.mode.magic_trailing_comma and trailing_comma) + # always explode imports + or opening_bracket.parent.type in {syms.atom, syms.import_from} + ) + + +def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[LeafID]]: + """Generate sets of closing bracket IDs that should be omitted in a RHS. + + Brackets can be omitted if the entire trailer up to and including + a preceding closing bracket fits in one line. + + Yielded sets are cumulative (contain results of previous yields, too). First + set is empty, unless the line should explode, in which case bracket pairs until + the one that needs to explode are omitted. + """ + + omit: Set[LeafID] = set() + if not line.magic_trailing_comma: + yield omit + + length = 4 * line.depth + opening_bracket: Optional[Leaf] = None + closing_bracket: Optional[Leaf] = None + inner_brackets: Set[LeafID] = set() + for index, leaf, leaf_length in line.enumerate_with_length(reversed=True): + length += leaf_length + if length > line_length: + break + + has_inline_comment = leaf_length > len(leaf.value) + len(leaf.prefix) + if leaf.type == STANDALONE_COMMENT or has_inline_comment: + break + + if opening_bracket: + if leaf is opening_bracket: + opening_bracket = None + elif leaf.type in CLOSING_BRACKETS: + prev = line.leaves[index - 1] if index > 0 else None + if ( + prev + and prev.type == token.COMMA + and leaf.opening_bracket is not None + and not is_one_sequence_between( + leaf.opening_bracket, leaf, line.leaves + ) + ): + # Never omit bracket pairs with trailing commas. + # We need to explode on those. + break + + inner_brackets.add(id(leaf)) + elif leaf.type in CLOSING_BRACKETS: + prev = line.leaves[index - 1] if index > 0 else None + if prev and prev.type in OPENING_BRACKETS: + # Empty brackets would fail a split so treat them as "inner" + # brackets (e.g. only add them to the `omit` set if another + # pair of brackets was good enough. + inner_brackets.add(id(leaf)) + continue + + if closing_bracket: + omit.add(id(closing_bracket)) + omit.update(inner_brackets) + inner_brackets.clear() + yield omit + + if ( + prev + and prev.type == token.COMMA + and leaf.opening_bracket is not None + and not is_one_sequence_between(leaf.opening_bracket, leaf, line.leaves) + ): + # Never omit bracket pairs with trailing commas. + # We need to explode on those. + break + + if leaf.value: + opening_bracket = leaf.opening_bracket + closing_bracket = leaf + + +def run_transformer( + line: Line, + transform: Transformer, + mode: Mode, + features: Collection[Feature], + *, + line_str: str = "", +) -> List[Line]: + if not line_str: + line_str = line_to_string(line) + result: List[Line] = [] + for transformed_line in transform(line, features, mode): + if str(transformed_line).strip("\n") == line_str: + raise CannotTransform("Line transformer returned an unchanged result") + + result.extend(transform_line(transformed_line, mode=mode, features=features)) + + features_set = set(features) + if ( + Feature.FORCE_OPTIONAL_PARENTHESES in features_set + or transform.__class__.__name__ != "rhs" + or not line.bracket_tracker.invisible + or any(bracket.value for bracket in line.bracket_tracker.invisible) + or line.contains_multiline_strings() + or result[0].contains_uncollapsable_type_comments() + or result[0].contains_unsplittable_type_ignore() + or is_line_short_enough(result[0], mode=mode) + # If any leaves have no parents (which _can_ occur since + # `transform(line)` potentially destroys the line's underlying node + # structure), then we can't proceed. Doing so would cause the below + # call to `append_leaves()` to fail. + or any(leaf.parent is None for leaf in line.leaves) + ): + return result + + line_copy = line.clone() + append_leaves(line_copy, line, line.leaves) + features_fop = features_set | {Feature.FORCE_OPTIONAL_PARENTHESES} + second_opinion = run_transformer( + line_copy, transform, mode, features_fop, line_str=line_str + ) + if all(is_line_short_enough(ln, mode=mode) for ln in second_opinion): + result = second_opinion + return result diff --git a/dbdpy-env/lib/python3.9/site-packages/black/lines.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/lines.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..89b0d308a0d675c93a27489c45cc980bd262d9a0 GIT binary patch literal 50135 zcmeI*U2IfE6bJCLA1zDTLJ2jg3UtM4BZ0QGfRI#JELBS7L)vH)6DPafZF|G^?z(#m zT`AB9c`zml5t2qFN`g_MCPXSR1jE)uBfcOc7UBn~#s~U9f-%N`0-kg4+;(>nc zA|7_DtWe5|4Or51N@2dH)z0{LdR}6$?%R!@hH^ut(pG;YJvmgEuXK$wRjpS@oSQG8 z^YOde#mT37WAS7x#Uq9J>UF**yHgfTHW8RtTRs`-Rk&)PA2YB-LjBn>LtiJzrO))C*O&OgB;5~z1+$=@sauWIF@&; zA0-;#wuI{zu2S4RWUXwQ>mc*FrJSFaJcZ>!9*}(|2KF2_tDe}fFY{B$mnVKb*uY~! zuCj-{tEbHF+pp(Y=3B(0@^j@D`TbnURdUIBh-&!16%W<*r&D!tBOS@!kKXXn{?JS+uL}CUZzMVp^3q6vLe~OC^gG{$y~bBHJA!)NLql6@cumkl zBR6)Aen?a`#`iK01Ov|VGG8U}ty`b*wbt{pChJpU?mm23*xrZl&i>~<<3&?>$_n-=h0`N4ApRt3tjw>2sb6xtl6|zD8QHocl|Q zz4ke;K7IPA<@VDY-2G~=y#OB&fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafOuxY7-?exDe!Om{e`o9f0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00IzzfGaR(A+<|?PAHm*M^)PDkEn=YMq?>@_9fa! zDOw#;TQbezWV$~dQ>}f;M9Px!fIaTSdU#_Z%4=k@oG1AywJsKp#}i#VL>`V?O~X<& z$45tY5qXs|Bvw=!H_TX?s(o~7&^_0w!Ct#7pR)o)l|#;qmz&uhq9d!Fc&?6{bo>y< zJblxdC2A~)Hx$IrJ25}v6dyN!u0>pnx#q?kQjpyDm^{8a;JgJ#1z0j~v*k180o{hL zls%M88Qa5FOm=q4^-HB$wyWXDJ#z(*F^hLDdHLjC{zsJN+R0T)8PVvmpqEOW@Lr#x z$p!Wc)pjK_R&T;w(zt3#G@RODn6>Eyjcw%2>6d;i^K^@|Smesl8T@!`L|-I+ None: + """Add a new `leaf` to the end of the line. + + Unless `preformatted` is True, the `leaf` will receive a new consistent + whitespace prefix and metadata applied by :class:`BracketTracker`. + Trailing commas are maybe removed, unpacked for loop variables are + demoted from being delimiters. + + Inline comments are put aside. + """ + has_value = leaf.type in BRACKETS or bool(leaf.value.strip()) + if not has_value: + return + + if token.COLON == leaf.type and self.is_class_paren_empty: + del self.leaves[-2:] + if self.leaves and not preformatted: + # Note: at this point leaf.prefix should be empty except for + # imports, for which we only preserve newlines. + leaf.prefix += whitespace( + leaf, + complex_subscript=self.is_complex_subscript(leaf), + mode=self.mode, + ) + if self.inside_brackets or not preformatted or track_bracket: + self.bracket_tracker.mark(leaf) + if self.mode.magic_trailing_comma: + if self.has_magic_trailing_comma(leaf): + self.magic_trailing_comma = leaf + elif self.has_magic_trailing_comma(leaf, ensure_removable=True): + self.remove_trailing_comma() + if not self.append_comment(leaf): + self.leaves.append(leaf) + + def append_safe(self, leaf: Leaf, preformatted: bool = False) -> None: + """Like :func:`append()` but disallow invalid standalone comment structure. + + Raises ValueError when any `leaf` is appended after a standalone comment + or when a standalone comment is not the first leaf on the line. + """ + if ( + self.bracket_tracker.depth == 0 + or self.bracket_tracker.any_open_for_or_lambda() + ): + if self.is_comment: + raise ValueError("cannot append to standalone comments") + + if self.leaves and leaf.type == STANDALONE_COMMENT: + raise ValueError( + "cannot append standalone comments to a populated line" + ) + + self.append(leaf, preformatted=preformatted) + + @property + def is_comment(self) -> bool: + """Is this line a standalone comment?""" + return len(self.leaves) == 1 and self.leaves[0].type == STANDALONE_COMMENT + + @property + def is_decorator(self) -> bool: + """Is this line a decorator?""" + return bool(self) and self.leaves[0].type == token.AT + + @property + def is_import(self) -> bool: + """Is this an import line?""" + return bool(self) and is_import(self.leaves[0]) + + @property + def is_with_or_async_with_stmt(self) -> bool: + """Is this a with_stmt line?""" + return bool(self) and is_with_or_async_with_stmt(self.leaves[0]) + + @property + def is_class(self) -> bool: + """Is this line a class definition?""" + return ( + bool(self) + and self.leaves[0].type == token.NAME + and self.leaves[0].value == "class" + ) + + @property + def is_stub_class(self) -> bool: + """Is this line a class definition with a body consisting only of "..."?""" + return self.is_class and self.leaves[-3:] == [ + Leaf(token.DOT, ".") for _ in range(3) + ] + + @property + def is_def(self) -> bool: + """Is this a function definition? (Also returns True for async defs.)""" + try: + first_leaf = self.leaves[0] + except IndexError: + return False + + try: + second_leaf: Optional[Leaf] = self.leaves[1] + except IndexError: + second_leaf = None + return (first_leaf.type == token.NAME and first_leaf.value == "def") or ( + first_leaf.type == token.ASYNC + and second_leaf is not None + and second_leaf.type == token.NAME + and second_leaf.value == "def" + ) + + @property + def is_stub_def(self) -> bool: + """Is this line a function definition with a body consisting only of "..."?""" + return self.is_def and self.leaves[-4:] == [Leaf(token.COLON, ":")] + [ + Leaf(token.DOT, ".") for _ in range(3) + ] + + @property + def is_class_paren_empty(self) -> bool: + """Is this a class with no base classes but using parentheses? + + Those are unnecessary and should be removed. + """ + return ( + bool(self) + and len(self.leaves) == 4 + and self.is_class + and self.leaves[2].type == token.LPAR + and self.leaves[2].value == "(" + and self.leaves[3].type == token.RPAR + and self.leaves[3].value == ")" + ) + + @property + def is_triple_quoted_string(self) -> bool: + """Is the line a triple quoted string?""" + if not self or self.leaves[0].type != token.STRING: + return False + value = self.leaves[0].value + if value.startswith(('"""', "'''")): + return True + if Preview.accept_raw_docstrings in self.mode and value.startswith( + ("r'''", 'r"""', "R'''", 'R"""') + ): + return True + return False + + @property + def is_chained_assignment(self) -> bool: + """Is the line a chained assignment""" + return [leaf.type for leaf in self.leaves].count(token.EQUAL) > 1 + + @property + def opens_block(self) -> bool: + """Does this line open a new level of indentation.""" + if len(self.leaves) == 0: + return False + return self.leaves[-1].type == token.COLON + + def is_fmt_pass_converted( + self, *, first_leaf_matches: Optional[Callable[[Leaf], bool]] = None + ) -> bool: + """Is this line converted from fmt off/skip code? + + If first_leaf_matches is not None, it only returns True if the first + leaf of converted code matches. + """ + if len(self.leaves) != 1: + return False + leaf = self.leaves[0] + if ( + leaf.type != STANDALONE_COMMENT + or leaf.fmt_pass_converted_first_leaf is None + ): + return False + return first_leaf_matches is None or first_leaf_matches( + leaf.fmt_pass_converted_first_leaf + ) + + def contains_standalone_comments(self) -> bool: + """If so, needs to be split before emitting.""" + for leaf in self.leaves: + if leaf.type == STANDALONE_COMMENT: + return True + + return False + + def contains_implicit_multiline_string_with_comments(self) -> bool: + """Chck if we have an implicit multiline string with comments on the line""" + for leaf_type, leaf_group_iterator in itertools.groupby( + self.leaves, lambda leaf: leaf.type + ): + if leaf_type != token.STRING: + continue + leaf_list = list(leaf_group_iterator) + if len(leaf_list) == 1: + continue + for leaf in leaf_list: + if self.comments_after(leaf): + return True + return False + + def contains_uncollapsable_type_comments(self) -> bool: + ignored_ids = set() + try: + last_leaf = self.leaves[-1] + ignored_ids.add(id(last_leaf)) + if last_leaf.type == token.COMMA or ( + last_leaf.type == token.RPAR and not last_leaf.value + ): + # When trailing commas or optional parens are inserted by Black for + # consistency, comments after the previous last element are not moved + # (they don't have to, rendering will still be correct). So we ignore + # trailing commas and invisible. + last_leaf = self.leaves[-2] + ignored_ids.add(id(last_leaf)) + except IndexError: + return False + + # A type comment is uncollapsable if it is attached to a leaf + # that isn't at the end of the line (since that could cause it + # to get associated to a different argument) or if there are + # comments before it (since that could cause it to get hidden + # behind a comment. + comment_seen = False + for leaf_id, comments in self.comments.items(): + for comment in comments: + if is_type_comment(comment): + if comment_seen or ( + not is_type_ignore_comment(comment) + and leaf_id not in ignored_ids + ): + return True + + comment_seen = True + + return False + + def contains_unsplittable_type_ignore(self) -> bool: + if not self.leaves: + return False + + # If a 'type: ignore' is attached to the end of a line, we + # can't split the line, because we can't know which of the + # subexpressions the ignore was meant to apply to. + # + # We only want this to apply to actual physical lines from the + # original source, though: we don't want the presence of a + # 'type: ignore' at the end of a multiline expression to + # justify pushing it all onto one line. Thus we + # (unfortunately) need to check the actual source lines and + # only report an unsplittable 'type: ignore' if this line was + # one line in the original code. + + # Grab the first and last line numbers, skipping generated leaves + first_line = next((leaf.lineno for leaf in self.leaves if leaf.lineno != 0), 0) + last_line = next( + (leaf.lineno for leaf in reversed(self.leaves) if leaf.lineno != 0), 0 + ) + + if first_line == last_line: + # We look at the last two leaves since a comma or an + # invisible paren could have been added at the end of the + # line. + for node in self.leaves[-2:]: + for comment in self.comments.get(id(node), []): + if is_type_ignore_comment(comment): + return True + + return False + + def contains_multiline_strings(self) -> bool: + return any(is_multiline_string(leaf) for leaf in self.leaves) + + def has_magic_trailing_comma( + self, closing: Leaf, ensure_removable: bool = False + ) -> bool: + """Return True if we have a magic trailing comma, that is when: + - there's a trailing comma here + - it's not a one-tuple + - it's not a single-element subscript + Additionally, if ensure_removable: + - it's not from square bracket indexing + (specifically, single-element square bracket indexing) + """ + if not ( + closing.type in CLOSING_BRACKETS + and self.leaves + and self.leaves[-1].type == token.COMMA + ): + return False + + if closing.type == token.RBRACE: + return True + + if closing.type == token.RSQB: + if ( + closing.parent is not None + and closing.parent.type == syms.trailer + and closing.opening_bracket is not None + and is_one_sequence_between( + closing.opening_bracket, + closing, + self.leaves, + brackets=(token.LSQB, token.RSQB), + ) + ): + return False + + return True + + if self.is_import: + return True + + if closing.opening_bracket is not None and not is_one_sequence_between( + closing.opening_bracket, closing, self.leaves + ): + return True + + return False + + def append_comment(self, comment: Leaf) -> bool: + """Add an inline or standalone comment to the line.""" + if ( + comment.type == STANDALONE_COMMENT + and self.bracket_tracker.any_open_brackets() + ): + comment.prefix = "" + return False + + if comment.type != token.COMMENT: + return False + + if not self.leaves: + comment.type = STANDALONE_COMMENT + comment.prefix = "" + return False + + last_leaf = self.leaves[-1] + if ( + last_leaf.type == token.RPAR + and not last_leaf.value + and last_leaf.parent + and len(list(last_leaf.parent.leaves())) <= 3 + and not is_type_comment(comment) + ): + # Comments on an optional parens wrapping a single leaf should belong to + # the wrapped node except if it's a type comment. Pinning the comment like + # this avoids unstable formatting caused by comment migration. + if len(self.leaves) < 2: + comment.type = STANDALONE_COMMENT + comment.prefix = "" + return False + + last_leaf = self.leaves[-2] + self.comments.setdefault(id(last_leaf), []).append(comment) + return True + + def comments_after(self, leaf: Leaf) -> List[Leaf]: + """Generate comments that should appear directly after `leaf`.""" + return self.comments.get(id(leaf), []) + + def remove_trailing_comma(self) -> None: + """Remove the trailing comma and moves the comments attached to it.""" + trailing_comma = self.leaves.pop() + trailing_comma_comments = self.comments.pop(id(trailing_comma), []) + self.comments.setdefault(id(self.leaves[-1]), []).extend( + trailing_comma_comments + ) + + def is_complex_subscript(self, leaf: Leaf) -> bool: + """Return True iff `leaf` is part of a slice with non-trivial exprs.""" + open_lsqb = self.bracket_tracker.get_open_lsqb() + if open_lsqb is None: + return False + + subscript_start = open_lsqb.next_sibling + + if isinstance(subscript_start, Node): + if subscript_start.type == syms.listmaker: + return False + + if subscript_start.type == syms.subscriptlist: + subscript_start = child_towards(subscript_start, leaf) + return subscript_start is not None and any( + n.type in TEST_DESCENDANTS for n in subscript_start.pre_order() + ) + + def enumerate_with_length( + self, reversed: bool = False + ) -> Iterator[Tuple[Index, Leaf, int]]: + """Return an enumeration of leaves with their length. + + Stops prematurely on multiline strings and standalone comments. + """ + op = cast( + Callable[[Sequence[Leaf]], Iterator[Tuple[Index, Leaf]]], + enumerate_reversed if reversed else enumerate, + ) + for index, leaf in op(self.leaves): + length = len(leaf.prefix) + len(leaf.value) + if "\n" in leaf.value: + return # Multiline strings, we can't continue. + + for comment in self.comments_after(leaf): + length += len(comment.value) + + yield index, leaf, length + + def clone(self) -> "Line": + return Line( + mode=self.mode, + depth=self.depth, + inside_brackets=self.inside_brackets, + should_split_rhs=self.should_split_rhs, + magic_trailing_comma=self.magic_trailing_comma, + ) + + def __str__(self) -> str: + """Render the line.""" + if not self: + return "\n" + + indent = " " * self.depth + leaves = iter(self.leaves) + first = next(leaves) + res = f"{first.prefix}{indent}{first.value}" + for leaf in leaves: + res += str(leaf) + for comment in itertools.chain.from_iterable(self.comments.values()): + res += str(comment) + + return res + "\n" + + def __bool__(self) -> bool: + """Return True if the line has leaves or comments.""" + return bool(self.leaves or self.comments) + + +@dataclass +class RHSResult: + """Intermediate split result from a right hand split.""" + + head: Line + body: Line + tail: Line + opening_bracket: Leaf + closing_bracket: Leaf + + +@dataclass +class LinesBlock: + """Class that holds information about a block of formatted lines. + + This is introduced so that the EmptyLineTracker can look behind the standalone + comments and adjust their empty lines for class or def lines. + """ + + mode: Mode + previous_block: Optional["LinesBlock"] + original_line: Line + before: int = 0 + content_lines: List[str] = field(default_factory=list) + after: int = 0 + form_feed: bool = False + + def all_lines(self) -> List[str]: + empty_line = str(Line(mode=self.mode)) + prefix = make_simple_prefix(self.before, self.form_feed, empty_line) + return [prefix] + self.content_lines + [empty_line * self.after] + + +@dataclass +class EmptyLineTracker: + """Provides a stateful method that returns the number of potential extra + empty lines needed before and after the currently processed line. + + Note: this tracker works on lines that haven't been split yet. It assumes + the prefix of the first leaf consists of optional newlines. Those newlines + are consumed by `maybe_empty_lines()` and included in the computation. + """ + + mode: Mode + previous_line: Optional[Line] = None + previous_block: Optional[LinesBlock] = None + previous_defs: List[Line] = field(default_factory=list) + semantic_leading_comment: Optional[LinesBlock] = None + + def maybe_empty_lines(self, current_line: Line) -> LinesBlock: + """Return the number of extra empty lines before and after the `current_line`. + + This is for separating `def`, `async def` and `class` with extra empty + lines (two on module-level). + """ + form_feed = ( + Preview.allow_form_feeds in self.mode + and current_line.depth == 0 + and bool(current_line.leaves) + and "\f\n" in current_line.leaves[0].prefix + ) + before, after = self._maybe_empty_lines(current_line) + previous_after = self.previous_block.after if self.previous_block else 0 + before = ( + # Black should not insert empty lines at the beginning + # of the file + 0 + if self.previous_line is None + else before - previous_after + ) + if ( + Preview.module_docstring_newlines in current_line.mode + and self.previous_block + and self.previous_block.previous_block is None + and len(self.previous_block.original_line.leaves) == 1 + and self.previous_block.original_line.is_triple_quoted_string + and not (current_line.is_class or current_line.is_def) + ): + before = 1 + + block = LinesBlock( + mode=self.mode, + previous_block=self.previous_block, + original_line=current_line, + before=before, + after=after, + form_feed=form_feed, + ) + + # Maintain the semantic_leading_comment state. + if current_line.is_comment: + if self.previous_line is None or ( + not self.previous_line.is_decorator + # `or before` means this comment already has an empty line before + and (not self.previous_line.is_comment or before) + and (self.semantic_leading_comment is None or before) + ): + self.semantic_leading_comment = block + # `or before` means this decorator already has an empty line before + elif not current_line.is_decorator or before: + self.semantic_leading_comment = None + + self.previous_line = current_line + self.previous_block = block + return block + + def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: + max_allowed = 1 + if current_line.depth == 0: + max_allowed = 1 if self.mode.is_pyi else 2 + if current_line.leaves: + # Consume the first leaf's extra newlines. + first_leaf = current_line.leaves[0] + before = first_leaf.prefix.count("\n") + before = min(before, max_allowed) + first_leaf.prefix = "" + else: + before = 0 + + user_had_newline = bool(before) + depth = current_line.depth + + previous_def = None + while self.previous_defs and self.previous_defs[-1].depth >= depth: + previous_def = self.previous_defs.pop() + + if previous_def is not None: + assert self.previous_line is not None + if self.mode.is_pyi: + if depth and not current_line.is_def and self.previous_line.is_def: + # Empty lines between attributes and methods should be preserved. + before = 1 if user_had_newline else 0 + elif ( + Preview.blank_line_after_nested_stub_class in self.mode + and previous_def.is_class + and not previous_def.is_stub_class + ): + before = 1 + elif depth: + before = 0 + else: + before = 1 + else: + if depth: + before = 1 + elif ( + not depth + and previous_def.depth + and current_line.leaves[-1].type == token.COLON + and ( + current_line.leaves[0].value + not in ("with", "try", "for", "while", "if", "match") + ) + ): + # We shouldn't add two newlines between an indented function and + # a dependent non-indented clause. This is to avoid issues with + # conditional function definitions that are technically top-level + # and therefore get two trailing newlines, but look weird and + # inconsistent when they're followed by elif, else, etc. This is + # worse because these functions only get *one* preceding newline + # already. + before = 1 + else: + before = 2 + + if current_line.is_decorator or current_line.is_def or current_line.is_class: + return self._maybe_empty_lines_for_class_or_def( + current_line, before, user_had_newline + ) + + if ( + self.previous_line + and self.previous_line.is_import + and not current_line.is_import + and not current_line.is_fmt_pass_converted(first_leaf_matches=is_import) + and depth == self.previous_line.depth + ): + return (before or 1), 0 + + if ( + self.previous_line + and self.previous_line.is_class + and current_line.is_triple_quoted_string + ): + if Preview.no_blank_line_before_class_docstring in current_line.mode: + return 0, 1 + return before, 1 + + # In preview mode, always allow blank lines, except right before a function + # docstring + is_empty_first_line_ok = ( + Preview.allow_empty_first_line_in_block in current_line.mode + and ( + not is_docstring(current_line.leaves[0]) + or ( + self.previous_line + and self.previous_line.leaves[0] + and self.previous_line.leaves[0].parent + and not is_funcdef(self.previous_line.leaves[0].parent) + ) + ) + ) + + if ( + self.previous_line + and self.previous_line.opens_block + and not is_empty_first_line_ok + ): + return 0, 0 + return before, 0 + + def _maybe_empty_lines_for_class_or_def( # noqa: C901 + self, current_line: Line, before: int, user_had_newline: bool + ) -> Tuple[int, int]: + if not current_line.is_decorator: + self.previous_defs.append(current_line) + if self.previous_line is None: + # Don't insert empty lines before the first line in the file. + return 0, 0 + + if self.previous_line.is_decorator: + if self.mode.is_pyi and current_line.is_stub_class: + # Insert an empty line after a decorated stub class + return 0, 1 + + return 0, 0 + + if self.previous_line.depth < current_line.depth and ( + self.previous_line.is_class or self.previous_line.is_def + ): + return 0, 0 + + comment_to_add_newlines: Optional[LinesBlock] = None + if ( + self.previous_line.is_comment + and self.previous_line.depth == current_line.depth + and before == 0 + ): + slc = self.semantic_leading_comment + if ( + slc is not None + and slc.previous_block is not None + and not slc.previous_block.original_line.is_class + and not slc.previous_block.original_line.opens_block + and slc.before <= 1 + ): + comment_to_add_newlines = slc + else: + return 0, 0 + + if self.mode.is_pyi: + if current_line.is_class or self.previous_line.is_class: + if self.previous_line.depth < current_line.depth: + newlines = 0 + elif self.previous_line.depth > current_line.depth: + newlines = 1 + elif current_line.is_stub_class and self.previous_line.is_stub_class: + # No blank line between classes with an empty body + newlines = 0 + else: + newlines = 1 + # Remove case `self.previous_line.depth > current_line.depth` below when + # this becomes stable. + # + # Don't inspect the previous line if it's part of the body of the previous + # statement in the same level, we always want a blank line if there's + # something with a body preceding. + elif ( + Preview.blank_line_between_nested_and_def_stub_file in current_line.mode + and self.previous_line.depth > current_line.depth + ): + newlines = 1 + elif ( + current_line.is_def or current_line.is_decorator + ) and not self.previous_line.is_def: + if current_line.depth: + # In classes empty lines between attributes and methods should + # be preserved. + newlines = min(1, before) + else: + # Blank line between a block of functions (maybe with preceding + # decorators) and a block of non-functions + newlines = 1 + elif self.previous_line.depth > current_line.depth: + newlines = 1 + else: + newlines = 0 + else: + newlines = 1 if current_line.depth else 2 + # If a user has left no space after a dummy implementation, don't insert + # new lines. This is useful for instance for @overload or Protocols. + if ( + Preview.dummy_implementations in self.mode + and self.previous_line.is_stub_def + and not user_had_newline + ): + newlines = 0 + if comment_to_add_newlines is not None: + previous_block = comment_to_add_newlines.previous_block + if previous_block is not None: + comment_to_add_newlines.before = ( + max(comment_to_add_newlines.before, newlines) - previous_block.after + ) + newlines = 0 + return newlines, 0 + + +def enumerate_reversed(sequence: Sequence[T]) -> Iterator[Tuple[Index, T]]: + """Like `reversed(enumerate(sequence))` if that were possible.""" + index = len(sequence) - 1 + for element in reversed(sequence): + yield (index, element) + index -= 1 + + +def append_leaves( + new_line: Line, old_line: Line, leaves: List[Leaf], preformatted: bool = False +) -> None: + """ + Append leaves (taken from @old_line) to @new_line, making sure to fix the + underlying Node structure where appropriate. + + All of the leaves in @leaves are duplicated. The duplicates are then + appended to @new_line and used to replace their originals in the underlying + Node structure. Any comments attached to the old leaves are reattached to + the new leaves. + + Pre-conditions: + set(@leaves) is a subset of set(@old_line.leaves). + """ + for old_leaf in leaves: + new_leaf = Leaf(old_leaf.type, old_leaf.value) + replace_child(old_leaf, new_leaf) + new_line.append(new_leaf, preformatted=preformatted) + + for comment_leaf in old_line.comments_after(old_leaf): + new_line.append(comment_leaf, preformatted=True) + + +def is_line_short_enough( # noqa: C901 + line: Line, *, mode: Mode, line_str: str = "" +) -> bool: + """For non-multiline strings, return True if `line` is no longer than `line_length`. + For multiline strings, looks at the context around `line` to determine + if it should be inlined or split up. + Uses the provided `line_str` rendering, if any, otherwise computes a new one. + """ + if not line_str: + line_str = line_to_string(line) + + width = str_width if Preview.respect_east_asian_width in mode else len + + if Preview.multiline_string_handling not in mode: + return ( + width(line_str) <= mode.line_length + and "\n" not in line_str # multiline strings + and not line.contains_standalone_comments() + ) + + if line.contains_standalone_comments(): + return False + if "\n" not in line_str: + # No multiline strings (MLS) present + return width(line_str) <= mode.line_length + + first, *_, last = line_str.split("\n") + if width(first) > mode.line_length or width(last) > mode.line_length: + return False + + # Traverse the AST to examine the context of the multiline string (MLS), + # tracking aspects such as depth and comma existence, + # to determine whether to split the MLS or keep it together. + # Depth (which is based on the existing bracket_depth concept) + # is needed to determine nesting level of the MLS. + # Includes special case for trailing commas. + commas: List[int] = [] # tracks number of commas per depth level + multiline_string: Optional[Leaf] = None + # store the leaves that contain parts of the MLS + multiline_string_contexts: List[LN] = [] + + max_level_to_update: Union[int, float] = math.inf # track the depth of the MLS + for i, leaf in enumerate(line.leaves): + if max_level_to_update == math.inf: + had_comma: Optional[int] = None + if leaf.bracket_depth + 1 > len(commas): + commas.append(0) + elif leaf.bracket_depth + 1 < len(commas): + had_comma = commas.pop() + if ( + had_comma is not None + and multiline_string is not None + and multiline_string.bracket_depth == leaf.bracket_depth + 1 + ): + # Have left the level with the MLS, stop tracking commas + max_level_to_update = leaf.bracket_depth + if had_comma > 0: + # MLS was in parens with at least one comma - force split + return False + + if leaf.bracket_depth <= max_level_to_update and leaf.type == token.COMMA: + # Ignore non-nested trailing comma + # directly after MLS/MLS-containing expression + ignore_ctxs: List[Optional[LN]] = [None] + ignore_ctxs += multiline_string_contexts + if not (leaf.prev_sibling in ignore_ctxs and i == len(line.leaves) - 1): + commas[leaf.bracket_depth] += 1 + if max_level_to_update != math.inf: + max_level_to_update = min(max_level_to_update, leaf.bracket_depth) + + if is_multiline_string(leaf): + if len(multiline_string_contexts) > 0: + # >1 multiline string cannot fit on a single line - force split + return False + multiline_string = leaf + ctx: LN = leaf + # fetch the leaf components of the MLS in the AST + while str(ctx) in line_str: + multiline_string_contexts.append(ctx) + if ctx.parent is None: + break + ctx = ctx.parent + + # May not have a triple-quoted multiline string at all, + # in case of a regular string with embedded newlines and line continuations + if len(multiline_string_contexts) == 0: + return True + + return all(val == 0 for val in commas) + + +def can_be_split(line: Line) -> bool: + """Return False if the line cannot be split *for sure*. + + This is not an exhaustive search but a cheap heuristic that we can use to + avoid some unfortunate formattings (mostly around wrapping unsplittable code + in unnecessary parentheses). + """ + leaves = line.leaves + if len(leaves) < 2: + return False + + if leaves[0].type == token.STRING and leaves[1].type == token.DOT: + call_count = 0 + dot_count = 0 + next = leaves[-1] + for leaf in leaves[-2::-1]: + if leaf.type in OPENING_BRACKETS: + if next.type not in CLOSING_BRACKETS: + return False + + call_count += 1 + elif leaf.type == token.DOT: + dot_count += 1 + elif leaf.type == token.NAME: + if not (next.type == token.DOT or next.type in OPENING_BRACKETS): + return False + + elif leaf.type not in CLOSING_BRACKETS: + return False + + if dot_count > 1 and call_count > 1: + return False + + return True + + +def can_omit_invisible_parens( + rhs: RHSResult, + line_length: int, +) -> bool: + """Does `rhs.body` have a shape safe to reformat without optional parens around it? + + Returns True for only a subset of potentially nice looking formattings but + the point is to not return false positives that end up producing lines that + are too long. + """ + line = rhs.body + + # We need optional parens in order to split standalone comments to their own lines + # if there are no nested parens around the standalone comments + closing_bracket: Optional[Leaf] = None + for leaf in reversed(line.leaves): + if closing_bracket and leaf is closing_bracket.opening_bracket: + closing_bracket = None + if leaf.type == STANDALONE_COMMENT and not closing_bracket: + return False + if ( + not closing_bracket + and leaf.type in CLOSING_BRACKETS + and leaf.opening_bracket in line.leaves + and leaf.value + ): + closing_bracket = leaf + + bt = line.bracket_tracker + if not bt.delimiters: + # Without delimiters the optional parentheses are useless. + return True + + max_priority = bt.max_delimiter_priority() + delimiter_count = bt.delimiter_count_with_priority(max_priority) + if delimiter_count > 1: + # With more than one delimiter of a kind the optional parentheses read better. + return False + + if delimiter_count == 1: + if ( + Preview.wrap_multiple_context_managers_in_parens in line.mode + and max_priority == COMMA_PRIORITY + and rhs.head.is_with_or_async_with_stmt + ): + # For two context manager with statements, the optional parentheses read + # better. In this case, `rhs.body` is the context managers part of + # the with statement. `rhs.head` is the `with (` part on the previous + # line. + return False + # Otherwise it may also read better, but we don't do it today and requires + # careful considerations for all possible cases. See + # https://github.com/psf/black/issues/2156. + + if max_priority == DOT_PRIORITY: + # A single stranded method call doesn't require optional parentheses. + return True + + assert len(line.leaves) >= 2, "Stranded delimiter" + + # With a single delimiter, omit if the expression starts or ends with + # a bracket. + first = line.leaves[0] + second = line.leaves[1] + if first.type in OPENING_BRACKETS and second.type not in CLOSING_BRACKETS: + if _can_omit_opening_paren(line, first=first, line_length=line_length): + return True + + # Note: we are not returning False here because a line might have *both* + # a leading opening bracket and a trailing closing bracket. If the + # opening bracket doesn't match our rule, maybe the closing will. + + penultimate = line.leaves[-2] + last = line.leaves[-1] + + if ( + last.type == token.RPAR + or last.type == token.RBRACE + or ( + # don't use indexing for omitting optional parentheses; + # it looks weird + last.type == token.RSQB + and last.parent + and last.parent.type != syms.trailer + ) + ): + if penultimate.type in OPENING_BRACKETS: + # Empty brackets don't help. + return False + + if is_multiline_string(first): + # Additional wrapping of a multiline string in this situation is + # unnecessary. + return True + + if _can_omit_closing_paren(line, last=last, line_length=line_length): + return True + + return False + + +def _can_omit_opening_paren(line: Line, *, first: Leaf, line_length: int) -> bool: + """See `can_omit_invisible_parens`.""" + remainder = False + length = 4 * line.depth + _index = -1 + for _index, leaf, leaf_length in line.enumerate_with_length(): + if leaf.type in CLOSING_BRACKETS and leaf.opening_bracket is first: + remainder = True + if remainder: + length += leaf_length + if length > line_length: + break + + if leaf.type in OPENING_BRACKETS: + # There are brackets we can further split on. + remainder = False + + else: + # checked the entire string and line length wasn't exceeded + if len(line.leaves) == _index + 1: + return True + + return False + + +def _can_omit_closing_paren(line: Line, *, last: Leaf, line_length: int) -> bool: + """See `can_omit_invisible_parens`.""" + length = 4 * line.depth + seen_other_brackets = False + for _index, leaf, leaf_length in line.enumerate_with_length(): + length += leaf_length + if leaf is last.opening_bracket: + if seen_other_brackets or length <= line_length: + return True + + elif leaf.type in OPENING_BRACKETS: + # There are brackets we can further split on. + seen_other_brackets = True + + return False + + +def line_to_string(line: Line) -> str: + """Returns the string representation of @line. + + WARNING: This is known to be computationally expensive. + """ + return str(line).strip("\n") diff --git a/dbdpy-env/lib/python3.9/site-packages/black/mode.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/mode.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..700bb96c03c2974666c8a3d85d5501bd6b0bb7d0 GIT binary patch literal 50118 zcmeI*Uu;uV90%}U|7;Z5V3R!zMb{u1pt8XjlbHdX+X6#{DGSc{aMG?FYv|hA-m+C@ zoQZ@OBN+)3Bq1SY5s8`@94ZFFc!0zw1Y{T=2u3kzVzR}jp=17j_ny18#lh1aOui?a zp7T5B+}}C((~Y;2UApt<-2x&9aq)1S&-J#OXs--#S;X~6o>i)~sjbx<%Kq?Whos{? z9=5BjP|67P7}B#!Zoaw=*7)~&USg;2n~j_LGDD@3Mk3ns1y~LUM=$`YnCyhinx>K*u%@@)6w&-~~)?s#T9#kq7 z?G8tSDje;InQ`{_@r};6StpP<>wI=%-OBfRn5$Ba^{w@)VcXX2*0<}^3ub6tJS|mz zV2ZdZwKJCSwa%DNezwfwv!2%x<#R{!*+tHEo2zv$dz9Ng-S_D>C$`UJzq3*ize=XN z0dY ztL$O!>L@h(=Ic4CT~G3;{9M^Zem~c7m0WTjqGkNwii0Xs$wXx&9FV#_oisvS70*=! z(;S(LsGJ+g(?4vvtkAK%x0J`Y%KR}tf4P-dhEX5@0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfWZG+U}Dd?6B8~v;G0WDWnR~{HADw}P8#x%Z`_kdV|*8OoUdxOdiA`6`d(hfYrGB` zn%Hyx6QZ&azL$B>>#?4f`7((oCr|OU)+@4R*ri77efYAlxewo+{m*@F=1u1*%-LrF z$2Z;6^L&Z)o_*vU`sX;?$XPZb{dh*dMfdrRY$?B2iF|R==R75HH&yz4jkIJf_gCjT z&2x@!I(I_yjJnCpSyNTJZta?mU`Iz)&FWBaU2Wi*YNfi;@pL=gXRaa~4I3&D@we|% zygU{R@g8!2b}?5enXO!9mAmuR+)6Ff_rj$wcWevz$s+S<4(@-o*Ia-P2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1ZH1g>hIdye?MNgv%fQTfB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafK)@C#UP9ZYU+fE}BSDokQUMhRM}wgRz4SWuQ-U`5 zR7<+SA5W$tA=TU!k0lHl_n6~WtcPEW1$m837V#uMr5Z#2NF>(IL*(GNIT|(;6}xEg zO(LgKVTlzLbj5-pdcs9#dih_cd96=<0FH+GS zPaB=F=*l&p{ffHD#U~H^_SN-Y zK7Z@8lWnn!zjq9~uV22r%ek#BZ?bo&_l> bool: + return all(feature in VERSION_TO_FEATURES[version] for version in target_versions) + + +class Preview(Enum): + """Individual preview style features.""" + + add_trailing_comma_consistently = auto() + blank_line_after_nested_stub_class = auto() + blank_line_between_nested_and_def_stub_file = auto() + hex_codes_in_unicode_sequences = auto() + improved_async_statements_handling = auto() + multiline_string_handling = auto() + no_blank_line_before_class_docstring = auto() + prefer_splitting_right_hand_side_of_assignments = auto() + # NOTE: string_processing requires wrap_long_dict_values_in_parens + # for https://github.com/psf/black/issues/3117 to be fixed. + string_processing = auto() + parenthesize_conditional_expressions = auto() + parenthesize_long_type_hints = auto() + respect_magic_trailing_comma_in_return_type = auto() + skip_magic_trailing_comma_in_subscript = auto() + wrap_long_dict_values_in_parens = auto() + wrap_multiple_context_managers_in_parens = auto() + dummy_implementations = auto() + walrus_subscript = auto() + module_docstring_newlines = auto() + accept_raw_docstrings = auto() + fix_power_op_line_length = auto() + hug_parens_with_braces_and_square_brackets = auto() + allow_empty_first_line_in_block = auto() + single_line_format_skip_with_multiple_comments = auto() + long_case_block_line_splitting = auto() + allow_form_feeds = auto() + respect_east_asian_width = auto() + + +class Deprecated(UserWarning): + """Visible deprecation warning.""" + + +@dataclass +class Mode: + target_versions: Set[TargetVersion] = field(default_factory=set) + line_length: int = DEFAULT_LINE_LENGTH + string_normalization: bool = True + is_pyi: bool = False + is_ipynb: bool = False + skip_source_first_line: bool = False + magic_trailing_comma: bool = True + experimental_string_processing: bool = False + python_cell_magics: Set[str] = field(default_factory=set) + preview: bool = False + + def __post_init__(self) -> None: + if self.experimental_string_processing: + warn( + "`experimental string processing` has been included in `preview`" + " and deprecated. Use `preview` instead.", + Deprecated, + ) + + def __contains__(self, feature: Preview) -> bool: + """ + Provide `Preview.FEATURE in Mode` syntax that mirrors the ``preview`` flag. + + The argument is not checked and features are not differentiated. + They only exist to make development easier by clarifying intent. + """ + if feature is Preview.string_processing: + return self.preview or self.experimental_string_processing + return self.preview + + def get_cache_key(self) -> str: + if self.target_versions: + version_str = ",".join( + str(version.value) + for version in sorted(self.target_versions, key=attrgetter("value")) + ) + else: + version_str = "-" + parts = [ + version_str, + str(self.line_length), + str(int(self.string_normalization)), + str(int(self.is_pyi)), + str(int(self.is_ipynb)), + str(int(self.skip_source_first_line)), + str(int(self.magic_trailing_comma)), + str(int(self.experimental_string_processing)), + str(int(self.preview)), + sha256((",".join(sorted(self.python_cell_magics))).encode()).hexdigest(), + ] + return ".".join(parts) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/nodes.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/nodes.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..2f97849c6b095eaea388eefedcdb7bc4ed7a2587 GIT binary patch literal 50135 zcmeI*U2IfE6bJCLA1!NWp|wpcsoE{6HehK>zXa33A`~eoAJS-F%w)HBOINnL>+UUO zp~Pwe@e2cyD3KS9O%#QMAWc*%ZB5jeNU#{e_<+2az=H`!5uI)TJl=W`P4R=(GRT$Nh2qGN?xxnccg``ZoZ1-EHEJS|mz zV2ZdZwI!bMwca+L{A^hzU_Y-T%IA*cbBdhn5?A|N&M3Eox*yPOPVAh^d1s}fL6u7P zhT>6`Fq5~*dC;&HDt$E{LE&LnPne}8@4PQ4Qk`#F|PYIgYbyo&~(uI4p< z7oE7ibNnNsigSD~^MK!HKQHqY65qTz%-34a%9=5cI_K=emxZl;`0ng~?sGA3I!|HF zK65#~=$)SDOQg5#Bk!eZC`G#_v@sU!3$gPpRBZl|El1Ep6uh z;(WJt&MQxh9+o^;ykzBUX;`|Xxv|^m?rvyV95$9L4L#bVRBt+w?xH)))kb0wQ-z|z zuB}R`SlkHnwRgEcdp}nxnXO!9mAmsz+)6Ff_rj$wcWevz$s+4%4(@!l*IIxN2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1ZG}f>hIb+e?MNgGru!-fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafK)?|wo==;lUmP&fQA4H7zK{wYYE5l@;j?z6`2SPwrHH+YRq7V#uMrB;Q5(P+Gjhsecodn{rq zD)!LOE+V&55s4KQ#NtLcMO7Xe8F0=uGSFjn<#UdYsBF-ladR`*MKrX`j!Sghs^dzI zdHRMuOVpSXug!^{wPSw7E*@^YT=Tf*bIpu7BtJRtF?D=rzBtI~L}DF!Ak6H&#rRpIR^+9=v*d^&?v*KJi=~ F`4<=REwlgt literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/nodes.py b/dbdpy-env/lib/python3.9/site-packages/black/nodes.py new file mode 100644 index 00000000..a4f555b4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/nodes.py @@ -0,0 +1,982 @@ +""" +blib2to3 Node/Leaf transformation-related utility functions. +""" + +import sys +from typing import Final, Generic, Iterator, List, Optional, Set, Tuple, TypeVar, Union + +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +from mypy_extensions import mypyc_attr + +from black.cache import CACHE_DIR +from black.mode import Mode, Preview +from black.strings import get_string_prefix, has_triple_quotes +from blib2to3 import pygram +from blib2to3.pgen2 import token +from blib2to3.pytree import NL, Leaf, Node, type_repr + +pygram.initialize(CACHE_DIR) +syms: Final = pygram.python_symbols + + +# types +T = TypeVar("T") +LN = Union[Leaf, Node] +LeafID = int +NodeType = int + + +WHITESPACE: Final = {token.DEDENT, token.INDENT, token.NEWLINE} +STATEMENT: Final = { + syms.if_stmt, + syms.while_stmt, + syms.for_stmt, + syms.try_stmt, + syms.except_clause, + syms.with_stmt, + syms.funcdef, + syms.classdef, + syms.match_stmt, + syms.case_block, +} +STANDALONE_COMMENT: Final = 153 +token.tok_name[STANDALONE_COMMENT] = "STANDALONE_COMMENT" +LOGIC_OPERATORS: Final = {"and", "or"} +COMPARATORS: Final = { + token.LESS, + token.GREATER, + token.EQEQUAL, + token.NOTEQUAL, + token.LESSEQUAL, + token.GREATEREQUAL, +} +MATH_OPERATORS: Final = { + token.VBAR, + token.CIRCUMFLEX, + token.AMPER, + token.LEFTSHIFT, + token.RIGHTSHIFT, + token.PLUS, + token.MINUS, + token.STAR, + token.SLASH, + token.DOUBLESLASH, + token.PERCENT, + token.AT, + token.TILDE, + token.DOUBLESTAR, +} +STARS: Final = {token.STAR, token.DOUBLESTAR} +VARARGS_SPECIALS: Final = STARS | {token.SLASH} +VARARGS_PARENTS: Final = { + syms.arglist, + syms.argument, # double star in arglist + syms.trailer, # single argument to call + syms.typedargslist, + syms.varargslist, # lambdas +} +UNPACKING_PARENTS: Final = { + syms.atom, # single element of a list or set literal + syms.dictsetmaker, + syms.listmaker, + syms.testlist_gexp, + syms.testlist_star_expr, + syms.subject_expr, + syms.pattern, +} +TEST_DESCENDANTS: Final = { + syms.test, + syms.lambdef, + syms.or_test, + syms.and_test, + syms.not_test, + syms.comparison, + syms.star_expr, + syms.expr, + syms.xor_expr, + syms.and_expr, + syms.shift_expr, + syms.arith_expr, + syms.trailer, + syms.term, + syms.power, +} +TYPED_NAMES: Final = {syms.tname, syms.tname_star} +ASSIGNMENTS: Final = { + "=", + "+=", + "-=", + "*=", + "@=", + "/=", + "%=", + "&=", + "|=", + "^=", + "<<=", + ">>=", + "**=", + "//=", +} + +IMPLICIT_TUPLE: Final = {syms.testlist, syms.testlist_star_expr, syms.exprlist} +BRACKET: Final = { + token.LPAR: token.RPAR, + token.LSQB: token.RSQB, + token.LBRACE: token.RBRACE, +} +OPENING_BRACKETS: Final = set(BRACKET.keys()) +CLOSING_BRACKETS: Final = set(BRACKET.values()) +BRACKETS: Final = OPENING_BRACKETS | CLOSING_BRACKETS +ALWAYS_NO_SPACE: Final = CLOSING_BRACKETS | {token.COMMA, STANDALONE_COMMENT} + +RARROW = 55 + + +@mypyc_attr(allow_interpreted_subclasses=True) +class Visitor(Generic[T]): + """Basic lib2to3 visitor that yields things of type `T` on `visit()`.""" + + def visit(self, node: LN) -> Iterator[T]: + """Main method to visit `node` and its children. + + It tries to find a `visit_*()` method for the given `node.type`, like + `visit_simple_stmt` for Node objects or `visit_INDENT` for Leaf objects. + If no dedicated `visit_*()` method is found, chooses `visit_default()` + instead. + + Then yields objects of type `T` from the selected visitor. + """ + if node.type < 256: + name = token.tok_name[node.type] + else: + name = str(type_repr(node.type)) + # We explicitly branch on whether a visitor exists (instead of + # using self.visit_default as the default arg to getattr) in order + # to save needing to create a bound method object and so mypyc can + # generate a native call to visit_default. + visitf = getattr(self, f"visit_{name}", None) + if visitf: + yield from visitf(node) + else: + yield from self.visit_default(node) + + def visit_default(self, node: LN) -> Iterator[T]: + """Default `visit_*()` implementation. Recurses to children of `node`.""" + if isinstance(node, Node): + for child in node.children: + yield from self.visit(child) + + +def whitespace(leaf: Leaf, *, complex_subscript: bool, mode: Mode) -> str: # noqa: C901 + """Return whitespace prefix if needed for the given `leaf`. + + `complex_subscript` signals whether the given leaf is part of a subscription + which has non-trivial arguments, like arithmetic expressions or function calls. + """ + NO: Final[str] = "" + SPACE: Final[str] = " " + DOUBLESPACE: Final[str] = " " + t = leaf.type + p = leaf.parent + v = leaf.value + if t in ALWAYS_NO_SPACE: + return NO + + if t == token.COMMENT: + return DOUBLESPACE + + assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}" + if t == token.COLON and p.type not in { + syms.subscript, + syms.subscriptlist, + syms.sliceop, + }: + return NO + + prev = leaf.prev_sibling + if not prev: + prevp = preceding_leaf(p) + if not prevp or prevp.type in OPENING_BRACKETS: + return NO + + if t == token.COLON: + if prevp.type == token.COLON: + return NO + + elif prevp.type != token.COMMA and not complex_subscript: + return NO + + return SPACE + + if prevp.type == token.EQUAL: + if prevp.parent: + if prevp.parent.type in { + syms.arglist, + syms.argument, + syms.parameters, + syms.varargslist, + }: + return NO + + elif prevp.parent.type == syms.typedargslist: + # A bit hacky: if the equal sign has whitespace, it means we + # previously found it's a typed argument. So, we're using + # that, too. + return prevp.prefix + + elif ( + prevp.type == token.STAR + and parent_type(prevp) == syms.star_expr + and parent_type(prevp.parent) == syms.subscriptlist + ): + # No space between typevar tuples. + return NO + + elif prevp.type in VARARGS_SPECIALS: + if is_vararg(prevp, within=VARARGS_PARENTS | UNPACKING_PARENTS): + return NO + + elif prevp.type == token.COLON: + if prevp.parent and prevp.parent.type in {syms.subscript, syms.sliceop}: + return SPACE if complex_subscript else NO + + elif ( + prevp.parent + and prevp.parent.type == syms.factor + and prevp.type in MATH_OPERATORS + ): + return NO + + elif prevp.type == token.AT and p.parent and p.parent.type == syms.decorator: + # no space in decorators + return NO + + elif prev.type in OPENING_BRACKETS: + return NO + + if p.type in {syms.parameters, syms.arglist}: + # untyped function signatures or calls + if not prev or prev.type != token.COMMA: + return NO + + elif p.type == syms.varargslist: + # lambdas + if prev and prev.type != token.COMMA: + return NO + + elif p.type == syms.typedargslist: + # typed function signatures + if not prev: + return NO + + if t == token.EQUAL: + if prev.type not in TYPED_NAMES: + return NO + + elif prev.type == token.EQUAL: + # A bit hacky: if the equal sign has whitespace, it means we + # previously found it's a typed argument. So, we're using that, too. + return prev.prefix + + elif prev.type != token.COMMA: + return NO + + elif p.type in TYPED_NAMES: + # type names + if not prev: + prevp = preceding_leaf(p) + if not prevp or prevp.type != token.COMMA: + return NO + + elif p.type == syms.trailer: + # attributes and calls + if t == token.LPAR or t == token.RPAR: + return NO + + if not prev: + if t == token.DOT or t == token.LSQB: + return NO + + elif prev.type != token.COMMA: + return NO + + elif p.type == syms.argument: + # single argument + if t == token.EQUAL: + return NO + + if not prev: + prevp = preceding_leaf(p) + if not prevp or prevp.type == token.LPAR: + return NO + + elif prev.type in {token.EQUAL} | VARARGS_SPECIALS: + return NO + + elif p.type == syms.decorator: + # decorators + return NO + + elif p.type == syms.dotted_name: + if prev: + return NO + + prevp = preceding_leaf(p) + if not prevp or prevp.type == token.AT or prevp.type == token.DOT: + return NO + + elif p.type == syms.classdef: + if t == token.LPAR: + return NO + + if prev and prev.type == token.LPAR: + return NO + + elif p.type in {syms.subscript, syms.sliceop}: + # indexing + if not prev: + assert p.parent is not None, "subscripts are always parented" + if p.parent.type == syms.subscriptlist: + return SPACE + + return NO + + elif Preview.walrus_subscript in mode and ( + t == token.COLONEQUAL or prev.type == token.COLONEQUAL + ): + return SPACE + + elif not complex_subscript: + return NO + + elif p.type == syms.atom: + if prev and t == token.DOT: + # dots, but not the first one. + return NO + + elif p.type == syms.dictsetmaker: + # dict unpacking + if prev and prev.type == token.DOUBLESTAR: + return NO + + elif p.type in {syms.factor, syms.star_expr}: + # unary ops + if not prev: + prevp = preceding_leaf(p) + if not prevp or prevp.type in OPENING_BRACKETS: + return NO + + prevp_parent = prevp.parent + assert prevp_parent is not None + if prevp.type == token.COLON and prevp_parent.type in { + syms.subscript, + syms.sliceop, + }: + return NO + + elif prevp.type == token.EQUAL and prevp_parent.type == syms.argument: + return NO + + elif t in {token.NAME, token.NUMBER, token.STRING}: + return NO + + elif p.type == syms.import_from: + if t == token.DOT: + if prev and prev.type == token.DOT: + return NO + + elif t == token.NAME: + if v == "import": + return SPACE + + if prev and prev.type == token.DOT: + return NO + + elif p.type == syms.sliceop: + return NO + + elif p.type == syms.except_clause: + if t == token.STAR: + return NO + + return SPACE + + +def make_simple_prefix(nl_count: int, form_feed: bool, empty_line: str = "\n") -> str: + """Generate a normalized prefix string.""" + if form_feed: + return (empty_line * (nl_count - 1)) + "\f" + empty_line + return empty_line * nl_count + + +def preceding_leaf(node: Optional[LN]) -> Optional[Leaf]: + """Return the first leaf that precedes `node`, if any.""" + while node: + res = node.prev_sibling + if res: + if isinstance(res, Leaf): + return res + + try: + return list(res.leaves())[-1] + + except IndexError: + return None + + node = node.parent + return None + + +def prev_siblings_are(node: Optional[LN], tokens: List[Optional[NodeType]]) -> bool: + """Return if the `node` and its previous siblings match types against the provided + list of tokens; the provided `node`has its type matched against the last element in + the list. `None` can be used as the first element to declare that the start of the + list is anchored at the start of its parent's children.""" + if not tokens: + return True + if tokens[-1] is None: + return node is None + if not node: + return False + if node.type != tokens[-1]: + return False + return prev_siblings_are(node.prev_sibling, tokens[:-1]) + + +def parent_type(node: Optional[LN]) -> Optional[NodeType]: + """ + Returns: + @node.parent.type, if @node is not None and has a parent. + OR + None, otherwise. + """ + if node is None or node.parent is None: + return None + + return node.parent.type + + +def child_towards(ancestor: Node, descendant: LN) -> Optional[LN]: + """Return the child of `ancestor` that contains `descendant`.""" + node: Optional[LN] = descendant + while node and node.parent != ancestor: + node = node.parent + return node + + +def replace_child(old_child: LN, new_child: LN) -> None: + """ + Side Effects: + * If @old_child.parent is set, replace @old_child with @new_child in + @old_child's underlying Node structure. + OR + * Otherwise, this function does nothing. + """ + parent = old_child.parent + if not parent: + return + + child_idx = old_child.remove() + if child_idx is not None: + parent.insert_child(child_idx, new_child) + + +def container_of(leaf: Leaf) -> LN: + """Return `leaf` or one of its ancestors that is the topmost container of it. + + By "container" we mean a node where `leaf` is the very first child. + """ + same_prefix = leaf.prefix + container: LN = leaf + while container: + parent = container.parent + if parent is None: + break + + if parent.children[0].prefix != same_prefix: + break + + if parent.type == syms.file_input: + break + + if parent.prev_sibling is not None and parent.prev_sibling.type in BRACKETS: + break + + container = parent + return container + + +def first_leaf_of(node: LN) -> Optional[Leaf]: + """Returns the first leaf of the node tree.""" + if isinstance(node, Leaf): + return node + if node.children: + return first_leaf_of(node.children[0]) + else: + return None + + +def is_arith_like(node: LN) -> bool: + """Whether node is an arithmetic or a binary arithmetic expression""" + return node.type in { + syms.arith_expr, + syms.shift_expr, + syms.xor_expr, + syms.and_expr, + } + + +def is_docstring(leaf: Leaf) -> bool: + if leaf.type != token.STRING: + return False + + prefix = get_string_prefix(leaf.value) + if set(prefix).intersection("bBfF"): + return False + + if prev_siblings_are( + leaf.parent, [None, token.NEWLINE, token.INDENT, syms.simple_stmt] + ): + return True + + # Multiline docstring on the same line as the `def`. + if prev_siblings_are(leaf.parent, [syms.parameters, token.COLON, syms.simple_stmt]): + # `syms.parameters` is only used in funcdefs and async_funcdefs in the Python + # grammar. We're safe to return True without further checks. + return True + + return False + + +def is_empty_tuple(node: LN) -> bool: + """Return True if `node` holds an empty tuple.""" + return ( + node.type == syms.atom + and len(node.children) == 2 + and node.children[0].type == token.LPAR + and node.children[1].type == token.RPAR + ) + + +def is_one_tuple(node: LN) -> bool: + """Return True if `node` holds a tuple with one element, with or without parens.""" + if node.type == syms.atom: + gexp = unwrap_singleton_parenthesis(node) + if gexp is None or gexp.type != syms.testlist_gexp: + return False + + return len(gexp.children) == 2 and gexp.children[1].type == token.COMMA + + return ( + node.type in IMPLICIT_TUPLE + and len(node.children) == 2 + and node.children[1].type == token.COMMA + ) + + +def is_tuple_containing_walrus(node: LN) -> bool: + """Return True if `node` holds a tuple that contains a walrus operator.""" + if node.type != syms.atom: + return False + gexp = unwrap_singleton_parenthesis(node) + if gexp is None or gexp.type != syms.testlist_gexp: + return False + + return any(child.type == syms.namedexpr_test for child in gexp.children) + + +def is_one_sequence_between( + opening: Leaf, + closing: Leaf, + leaves: List[Leaf], + brackets: Tuple[int, int] = (token.LPAR, token.RPAR), +) -> bool: + """Return True if content between `opening` and `closing` is a one-sequence.""" + if (opening.type, closing.type) != brackets: + return False + + depth = closing.bracket_depth + 1 + for _opening_index, leaf in enumerate(leaves): + if leaf is opening: + break + + else: + raise LookupError("Opening paren not found in `leaves`") + + commas = 0 + _opening_index += 1 + for leaf in leaves[_opening_index:]: + if leaf is closing: + break + + bracket_depth = leaf.bracket_depth + if bracket_depth == depth and leaf.type == token.COMMA: + commas += 1 + if leaf.parent and leaf.parent.type in { + syms.arglist, + syms.typedargslist, + }: + commas += 1 + break + + return commas < 2 + + +def is_walrus_assignment(node: LN) -> bool: + """Return True iff `node` is of the shape ( test := test )""" + inner = unwrap_singleton_parenthesis(node) + return inner is not None and inner.type == syms.namedexpr_test + + +def is_simple_decorator_trailer(node: LN, last: bool = False) -> bool: + """Return True iff `node` is a trailer valid in a simple decorator""" + return node.type == syms.trailer and ( + ( + len(node.children) == 2 + and node.children[0].type == token.DOT + and node.children[1].type == token.NAME + ) + # last trailer can be an argument-less parentheses pair + or ( + last + and len(node.children) == 2 + and node.children[0].type == token.LPAR + and node.children[1].type == token.RPAR + ) + # last trailer can be arguments + or ( + last + and len(node.children) == 3 + and node.children[0].type == token.LPAR + # and node.children[1].type == syms.argument + and node.children[2].type == token.RPAR + ) + ) + + +def is_simple_decorator_expression(node: LN) -> bool: + """Return True iff `node` could be a 'dotted name' decorator + + This function takes the node of the 'namedexpr_test' of the new decorator + grammar and test if it would be valid under the old decorator grammar. + + The old grammar was: decorator: @ dotted_name [arguments] NEWLINE + The new grammar is : decorator: @ namedexpr_test NEWLINE + """ + if node.type == token.NAME: + return True + if node.type == syms.power: + if node.children: + return ( + node.children[0].type == token.NAME + and all(map(is_simple_decorator_trailer, node.children[1:-1])) + and ( + len(node.children) < 2 + or is_simple_decorator_trailer(node.children[-1], last=True) + ) + ) + return False + + +def is_yield(node: LN) -> bool: + """Return True if `node` holds a `yield` or `yield from` expression.""" + if node.type == syms.yield_expr: + return True + + if is_name_token(node) and node.value == "yield": + return True + + if node.type != syms.atom: + return False + + if len(node.children) != 3: + return False + + lpar, expr, rpar = node.children + if lpar.type == token.LPAR and rpar.type == token.RPAR: + return is_yield(expr) + + return False + + +def is_vararg(leaf: Leaf, within: Set[NodeType]) -> bool: + """Return True if `leaf` is a star or double star in a vararg or kwarg. + + If `within` includes VARARGS_PARENTS, this applies to function signatures. + If `within` includes UNPACKING_PARENTS, it applies to right hand-side + extended iterable unpacking (PEP 3132) and additional unpacking + generalizations (PEP 448). + """ + if leaf.type not in VARARGS_SPECIALS or not leaf.parent: + return False + + p = leaf.parent + if p.type == syms.star_expr: + # Star expressions are also used as assignment targets in extended + # iterable unpacking (PEP 3132). See what its parent is instead. + if not p.parent: + return False + + p = p.parent + + return p.type in within + + +def is_multiline_string(leaf: Leaf) -> bool: + """Return True if `leaf` is a multiline string that actually spans many lines.""" + return has_triple_quotes(leaf.value) and "\n" in leaf.value + + +def is_funcdef(node: Node) -> bool: + return node.type == syms.funcdef + + +def is_function_or_class(node: Node) -> bool: + return node.type in {syms.funcdef, syms.classdef, syms.async_funcdef} + + +def is_stub_suite(node: Node, mode: Mode) -> bool: + """Return True if `node` is a suite with a stub body.""" + if ( + node.parent is not None + and Preview.dummy_implementations in mode + and not is_function_or_class(node.parent) + ): + return False + + # If there is a comment, we want to keep it. + if node.prefix.strip(): + return False + + if ( + len(node.children) != 4 + or node.children[0].type != token.NEWLINE + or node.children[1].type != token.INDENT + or node.children[3].type != token.DEDENT + ): + return False + + if node.children[3].prefix.strip(): + return False + + return is_stub_body(node.children[2]) + + +def is_stub_body(node: LN) -> bool: + """Return True if `node` is a simple statement containing an ellipsis.""" + if not isinstance(node, Node) or node.type != syms.simple_stmt: + return False + + if len(node.children) != 2: + return False + + child = node.children[0] + return ( + not child.prefix.strip() + and child.type == syms.atom + and len(child.children) == 3 + and all(leaf == Leaf(token.DOT, ".") for leaf in child.children) + ) + + +def is_atom_with_invisible_parens(node: LN) -> bool: + """Given a `LN`, determines whether it's an atom `node` with invisible + parens. Useful in dedupe-ing and normalizing parens. + """ + if isinstance(node, Leaf) or node.type != syms.atom: + return False + + first, last = node.children[0], node.children[-1] + return ( + isinstance(first, Leaf) + and first.type == token.LPAR + and first.value == "" + and isinstance(last, Leaf) + and last.type == token.RPAR + and last.value == "" + ) + + +def is_empty_par(leaf: Leaf) -> bool: + return is_empty_lpar(leaf) or is_empty_rpar(leaf) + + +def is_empty_lpar(leaf: Leaf) -> bool: + return leaf.type == token.LPAR and leaf.value == "" + + +def is_empty_rpar(leaf: Leaf) -> bool: + return leaf.type == token.RPAR and leaf.value == "" + + +def is_import(leaf: Leaf) -> bool: + """Return True if the given leaf starts an import statement.""" + p = leaf.parent + t = leaf.type + v = leaf.value + return bool( + t == token.NAME + and ( + (v == "import" and p and p.type == syms.import_name) + or (v == "from" and p and p.type == syms.import_from) + ) + ) + + +def is_with_or_async_with_stmt(leaf: Leaf) -> bool: + """Return True if the given leaf starts a with or async with statement.""" + return bool( + leaf.type == token.NAME + and leaf.value == "with" + and leaf.parent + and leaf.parent.type == syms.with_stmt + ) or bool( + leaf.type == token.ASYNC + and leaf.next_sibling + and leaf.next_sibling.type == syms.with_stmt + ) + + +def is_async_stmt_or_funcdef(leaf: Leaf) -> bool: + """Return True if the given leaf starts an async def/for/with statement. + + Note that `async def` can be either an `async_stmt` or `async_funcdef`, + the latter is used when it has decorators. + """ + return bool( + leaf.type == token.ASYNC + and leaf.parent + and leaf.parent.type in {syms.async_stmt, syms.async_funcdef} + ) + + +def is_type_comment(leaf: Leaf) -> bool: + """Return True if the given leaf is a type comment. This function should only + be used for general type comments (excluding ignore annotations, which should + use `is_type_ignore_comment`). Note that general type comments are no longer + used in modern version of Python, this function may be deprecated in the future.""" + t = leaf.type + v = leaf.value + return t in {token.COMMENT, STANDALONE_COMMENT} and v.startswith("# type:") + + +def is_type_ignore_comment(leaf: Leaf) -> bool: + """Return True if the given leaf is a type comment with ignore annotation.""" + t = leaf.type + v = leaf.value + return t in {token.COMMENT, STANDALONE_COMMENT} and is_type_ignore_comment_string(v) + + +def is_type_ignore_comment_string(value: str) -> bool: + """Return True if the given string match with type comment with + ignore annotation.""" + return value.startswith("# type: ignore") + + +def wrap_in_parentheses(parent: Node, child: LN, *, visible: bool = True) -> None: + """Wrap `child` in parentheses. + + This replaces `child` with an atom holding the parentheses and the old + child. That requires moving the prefix. + + If `visible` is False, the leaves will be valueless (and thus invisible). + """ + lpar = Leaf(token.LPAR, "(" if visible else "") + rpar = Leaf(token.RPAR, ")" if visible else "") + prefix = child.prefix + child.prefix = "" + index = child.remove() or 0 + new_child = Node(syms.atom, [lpar, child, rpar]) + new_child.prefix = prefix + parent.insert_child(index, new_child) + + +def unwrap_singleton_parenthesis(node: LN) -> Optional[LN]: + """Returns `wrapped` if `node` is of the shape ( wrapped ). + + Parenthesis can be optional. Returns None otherwise""" + if len(node.children) != 3: + return None + + lpar, wrapped, rpar = node.children + if not (lpar.type == token.LPAR and rpar.type == token.RPAR): + return None + + return wrapped + + +def ensure_visible(leaf: Leaf) -> None: + """Make sure parentheses are visible. + + They could be invisible as part of some statements (see + :func:`normalize_invisible_parens` and :func:`visit_import_from`). + """ + if leaf.type == token.LPAR: + leaf.value = "(" + elif leaf.type == token.RPAR: + leaf.value = ")" + + +def is_name_token(nl: NL) -> TypeGuard[Leaf]: + return nl.type == token.NAME + + +def is_lpar_token(nl: NL) -> TypeGuard[Leaf]: + return nl.type == token.LPAR + + +def is_rpar_token(nl: NL) -> TypeGuard[Leaf]: + return nl.type == token.RPAR + + +def is_string_token(nl: NL) -> TypeGuard[Leaf]: + return nl.type == token.STRING + + +def is_number_token(nl: NL) -> TypeGuard[Leaf]: + return nl.type == token.NUMBER + + +def is_part_of_annotation(leaf: Leaf) -> bool: + """Returns whether this leaf is part of type annotations.""" + ancestor = leaf.parent + while ancestor is not None: + if ancestor.prev_sibling and ancestor.prev_sibling.type == token.RARROW: + return True + if ancestor.parent and ancestor.parent.type == syms.tname: + return True + ancestor = ancestor.parent + return False + + +def first_leaf(node: LN) -> Optional[Leaf]: + """Returns the first leaf of the ancestor node.""" + if isinstance(node, Leaf): + return node + elif not node.children: + return None + else: + return first_leaf(node.children[0]) + + +def last_leaf(node: LN) -> Optional[Leaf]: + """Returns the last leaf of the ancestor node.""" + if isinstance(node, Leaf): + return node + elif not node.children: + return None + else: + return last_leaf(node.children[-1]) + + +def furthest_ancestor_with_last_leaf(leaf: Leaf) -> LN: + """Returns the furthest ancestor that has this leaf node as the last leaf.""" + node: LN = leaf + while node.parent and node.parent.children and node is node.parent.children[-1]: + node = node.parent + return node diff --git a/dbdpy-env/lib/python3.9/site-packages/black/numerics.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/numerics.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..03f655ca78e0c91d90502538b2e038274d44eb1c GIT binary patch literal 50138 zcmeI*U2IfE6bJCLcUxGbg+(i=AEX;XXe3ae6ex*l7b$^OC=}MD(TB-?mELr_yX@Wt zS4wOQ#Nbyj5JQY1Xfy~4sagY)7}^JY!T=J$U^Ezfs4=1@Bm^ShIrq+OcNc-DKA8L` znVmT^bI;8EZQHkj(>MRPT|wj_E(&?UVs7k8%BhXO#-A>G+$$rGk!+TOKj-A-IP&(VW?Er%0;rHL#6qA&Cb*;y+Y!`d_J9z z-`y@wKGhvhq~jSLDa|)m=X+YOm$)z=-F3cb*2X0j_~$Hm{rah-3qP9Sm7`P{_1mG5;QSEX8(hnA}q>)JOu-)>MZxJT>dX{qu9 zrc}Y#de40Fvt^f{^Sq8|0(T^zTjX3LT%B{dquloEeo(h1v3oA}os~+2RW{!n zNhMU;%G@(wwN5Ab3(ql;$IIL~Zk39Kt?<}D>G`VrojLbCB`(Z2_N3F3_muBSsWq+b z&#r7~b$_>poOufBR>zlgGI5vcmYFQGK!PFX_t(em=sWRnfMeOGn_F2YJ~DrRV|m8~ z!w&6a?yu)6#oa^J%C?0LGGAEy{Ji8TEl==(?6W)8zViB>g~7pp5|3Xwa_VS3j|I5O z9z?vWr_%1*ujgs-&f!t{xpIsAel~KITyh?wTK==*q4~LNW`4qqNZpvvTJhexXX;{k zj_gG=n;XfqZ^&_ZO2_ivQf6?K`2jxv94E01qd))x5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa zf&Z<*t!*a{-SX1g!Aaz=33$&hBH9}?XwXN&8@_V-oA1Hi;A@(pfS&hI|Aty#6Y$XB zt!={}6V+VcJDGa}KIeIvuaWr9oiF)D>i4o{$g3{6`|w3!dmp|x`=9$igk6>FIgCmH7<)RZBVK=pUy|=K67g{@p=mAmr|+)ACK?}bZW?$}oFlYaYY4(@-o*Is}R2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1jb*${eSHn^}iF)qTBJ`89P7#0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bc53QU_x8>K%j7|SPODr@B;Dq<#M@eFlr zrrngGrl4A%UlC4cbBVZW?M1A90G8n=-EDTqkfXj5(wLx$iN0e0N~2K!#xdFkudSMQp8@Imv( zdg}Y5-#ql5uRHYC(&sAoT|b=OJL$)!{p}6c{`_pvzv@BHkN14@m9Jh1ZAh=EnccSQ z_n&6gu5Zp(pE$RzX3eR#Up9vxJv!d|@8~)4@Rqi!^BqUN`0(hNPj-E9^*iq?vD4nQ NI}VThx~J#ee*proG4}uf literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/numerics.py b/dbdpy-env/lib/python3.9/site-packages/black/numerics.py new file mode 100644 index 00000000..3040de06 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/numerics.py @@ -0,0 +1,61 @@ +""" +Formatting numeric literals. +""" + +from blib2to3.pytree import Leaf + + +def format_hex(text: str) -> str: + """ + Formats a hexadecimal string like "0x12B3" + """ + before, after = text[:2], text[2:] + return f"{before}{after.upper()}" + + +def format_scientific_notation(text: str) -> str: + """Formats a numeric string utilizing scientific notation""" + before, after = text.split("e") + sign = "" + if after.startswith("-"): + after = after[1:] + sign = "-" + elif after.startswith("+"): + after = after[1:] + before = format_float_or_int_string(before) + return f"{before}e{sign}{after}" + + +def format_complex_number(text: str) -> str: + """Formats a complex string like `10j`""" + number = text[:-1] + suffix = text[-1] + return f"{format_float_or_int_string(number)}{suffix}" + + +def format_float_or_int_string(text: str) -> str: + """Formats a float string like "1.0".""" + if "." not in text: + return text + + before, after = text.split(".") + return f"{before or 0}.{after or 0}" + + +def normalize_numeric_literal(leaf: Leaf) -> None: + """Normalizes numeric (float, int, and complex) literals. + + All letters used in the representation are normalized to lowercase.""" + text = leaf.value.lower() + if text.startswith(("0o", "0b")): + # Leave octal and binary literals alone. + pass + elif text.startswith("0x"): + text = format_hex(text) + elif "e" in text: + text = format_scientific_notation(text) + elif text.endswith("j"): + text = format_complex_number(text) + else: + text = format_float_or_int_string(text) + leaf.value = text diff --git a/dbdpy-env/lib/python3.9/site-packages/black/output.py b/dbdpy-env/lib/python3.9/site-packages/black/output.py new file mode 100644 index 00000000..7c7dd0fe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/output.py @@ -0,0 +1,122 @@ +"""Nice output for Black. + +The double calls are for patching purposes in tests. +""" + +import json +import re +import tempfile +from typing import Any, List, Optional + +from click import echo, style +from mypy_extensions import mypyc_attr + + +@mypyc_attr(patchable=True) +def _out(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None: + if message is not None: + if "bold" not in styles: + styles["bold"] = True + message = style(message, **styles) + echo(message, nl=nl, err=True) + + +@mypyc_attr(patchable=True) +def _err(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None: + if message is not None: + if "fg" not in styles: + styles["fg"] = "red" + message = style(message, **styles) + echo(message, nl=nl, err=True) + + +@mypyc_attr(patchable=True) +def out(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None: + _out(message, nl=nl, **styles) + + +def err(message: Optional[str] = None, nl: bool = True, **styles: Any) -> None: + _err(message, nl=nl, **styles) + + +def ipynb_diff(a: str, b: str, a_name: str, b_name: str) -> str: + """Return a unified diff string between each cell in notebooks `a` and `b`.""" + a_nb = json.loads(a) + b_nb = json.loads(b) + diff_lines = [ + diff( + "".join(a_nb["cells"][cell_number]["source"]) + "\n", + "".join(b_nb["cells"][cell_number]["source"]) + "\n", + f"{a_name}:cell_{cell_number}", + f"{b_name}:cell_{cell_number}", + ) + for cell_number, cell in enumerate(a_nb["cells"]) + if cell["cell_type"] == "code" + ] + return "".join(diff_lines) + + +_line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))") + + +def _splitlines_no_ff(source: str) -> List[str]: + """Split a string into lines ignoring form feed and other chars. + + This mimics how the Python parser splits source code. + + A simplified version of the function with the same name in Lib/ast.py + """ + result = [match[0] for match in _line_pattern.finditer(source)] + if result[-1] == "": + result.pop(-1) + return result + + +def diff(a: str, b: str, a_name: str, b_name: str) -> str: + """Return a unified diff string between strings `a` and `b`.""" + import difflib + + a_lines = _splitlines_no_ff(a) + b_lines = _splitlines_no_ff(b) + diff_lines = [] + for line in difflib.unified_diff( + a_lines, b_lines, fromfile=a_name, tofile=b_name, n=5 + ): + # Work around https://bugs.python.org/issue2142 + # See: + # https://www.gnu.org/software/diffutils/manual/html_node/Incomplete-Lines.html + if line[-1] == "\n": + diff_lines.append(line) + else: + diff_lines.append(line + "\n") + diff_lines.append("\\ No newline at end of file\n") + return "".join(diff_lines) + + +def color_diff(contents: str) -> str: + """Inject the ANSI color codes to the diff.""" + lines = contents.split("\n") + for i, line in enumerate(lines): + if line.startswith("+++") or line.startswith("---"): + line = "\033[1m" + line + "\033[0m" # bold, reset + elif line.startswith("@@"): + line = "\033[36m" + line + "\033[0m" # cyan, reset + elif line.startswith("+"): + line = "\033[32m" + line + "\033[0m" # green, reset + elif line.startswith("-"): + line = "\033[31m" + line + "\033[0m" # red, reset + lines[i] = line + return "\n".join(lines) + + +@mypyc_attr(patchable=True) +def dump_to_file(*output: str, ensure_final_newline: bool = True) -> str: + """Dump `output` to a temporary file. Return path to the file.""" + with tempfile.NamedTemporaryFile( + mode="w", prefix="blk_", suffix=".log", delete=False, encoding="utf8" + ) as f: + for lines in output: + f.write(lines) + if ensure_final_newline and lines and lines[-1] != "\n": + f.write("\n") + return f.name diff --git a/dbdpy-env/lib/python3.9/site-packages/black/parsing.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/parsing.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..32d97ca1cf8ede31fbc7febeac17bb0bebfd7b3c GIT binary patch literal 50137 zcmeI*Uu;uV90%}UZ&y}ygH4B-5wnVhIRgV3gFzIED{;f|e=+kC>wiN?PV%)tEp?mc&Fi@?(!OumPl zo%1{A^moqv+>W;cUkv|pvxLY+T)bQ-aUCim+93m69_0EJ&nnfrw5`<|%Kzcd4@t)! z9(Jm%P|A$FYD&*8h4~s5+2dd8d5I0(x0)jA%?*`Go0(90bf_?&cd5>JhM`rM0lZm@jr%Yp+*%A!czrS8?N1us@eH_a^UEIn#@sasHj^!C= zpRj4~<^C$JQk*?xt!$g?AoIDUj6W}V3d=)0Ap0C$z5n@hv+A}Ub60o9cU}Ev4v+b` z${s|#tE<%NTaV|O>wbbq<$L86`TcC*D!Jr5MAiJ)ii>7t(y3XoXh`bXY}$-;*FIAl z&T?ceqUqd7o_zzhOO1}@xurbJRpt-z`D^UNGK>NN2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00jQG0ynlCKX}7Ud;Alrtjgy;Uq`gpZ&1IN{MWr6`kn8=Ugv9?tv)^PqTV&tyvFCE z{u^6Pyh~Jdf$wDQ^?B{j%Y2o@BO{0TM(SBvGvHPioPGGBu(c20oBhvyE_=rElosqW znd8evWAl80^p<_(84eX2ZDdqkkpAwRep2`OerzQ_SB1PZ>2sb6xtA(^zCv12&;8XC z4C|b~J$wA1{300Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fIyBw`7~N9VYxq?jfGX(%!E`Z8V^TOw0a}$ zrW7smt5w;?U^1PFMO1TlGLbT6+-r^7u^wKY2=f}5EaOT3lnO+Gu~?#=hsecob3AG) zDtA-gYea@pQHd3mB!j7RG~P+m-E^eKKHQO>E~~Sie@^leRrcEB1~-#kM170w_^E^cm$xO%uw;F=qANIr6&WAymWfb$d_7jVf63oaij zkLVVDrL3W3D*8&$jL6wV`3x$t z!@K?Tk1o&;RNJ1+nq7(b%(?|L!@<<1XuLL^p!dAz2X`(!y>Rok$eWivr6WIH{riD8 z+NK`Zv+l+FGV3qZf3WrakJ=K0KXnWgT|9GUgR!#BGt$%Fvw6qYpX_SdIpe_H<^#oE z&-RxeA8ahYC-BedPq+17+`PR>J@WDJ>!(ik9j+U?+vmr7e(?`SUus>GY^<8TZ0EIa zr&X_7oUS}}ZcA0m=gYp|*gECI@!tQ`v9mMYGOk?tbLg{^OXt7y^ST!AuVR;=I|LFS{e6usK literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/parsing.py b/dbdpy-env/lib/python3.9/site-packages/black/parsing.py new file mode 100644 index 00000000..178a7ef1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/parsing.py @@ -0,0 +1,216 @@ +""" +Parse Python code and perform AST validation. +""" + +import ast +import sys +from typing import Iterable, Iterator, List, Set, Tuple + +from black.mode import VERSION_TO_FEATURES, Feature, TargetVersion, supports_feature +from black.nodes import syms +from blib2to3 import pygram +from blib2to3.pgen2 import driver +from blib2to3.pgen2.grammar import Grammar +from blib2to3.pgen2.parse import ParseError +from blib2to3.pgen2.tokenize import TokenError +from blib2to3.pytree import Leaf, Node + + +class InvalidInput(ValueError): + """Raised when input source code fails all parse attempts.""" + + +def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]: + if not target_versions: + # No target_version specified, so try all grammars. + return [ + # Python 3.7-3.9 + pygram.python_grammar_async_keywords, + # Python 3.0-3.6 + pygram.python_grammar, + # Python 3.10+ + pygram.python_grammar_soft_keywords, + ] + + grammars = [] + # If we have to parse both, try to parse async as a keyword first + if not supports_feature( + target_versions, Feature.ASYNC_IDENTIFIERS + ) and not supports_feature(target_versions, Feature.PATTERN_MATCHING): + # Python 3.7-3.9 + grammars.append(pygram.python_grammar_async_keywords) + if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS): + # Python 3.0-3.6 + grammars.append(pygram.python_grammar) + if any(Feature.PATTERN_MATCHING in VERSION_TO_FEATURES[v] for v in target_versions): + # Python 3.10+ + grammars.append(pygram.python_grammar_soft_keywords) + + # At least one of the above branches must have been taken, because every Python + # version has exactly one of the two 'ASYNC_*' flags + return grammars + + +def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node: + """Given a string with source, return the lib2to3 Node.""" + if not src_txt.endswith("\n"): + src_txt += "\n" + + grammars = get_grammars(set(target_versions)) + errors = {} + for grammar in grammars: + drv = driver.Driver(grammar) + try: + result = drv.parse_string(src_txt, True) + break + + except ParseError as pe: + lineno, column = pe.context[1] + lines = src_txt.splitlines() + try: + faulty_line = lines[lineno - 1] + except IndexError: + faulty_line = "" + errors[grammar.version] = InvalidInput( + f"Cannot parse: {lineno}:{column}: {faulty_line}" + ) + + except TokenError as te: + # In edge cases these are raised; and typically don't have a "faulty_line". + lineno, column = te.args[1] + errors[grammar.version] = InvalidInput( + f"Cannot parse: {lineno}:{column}: {te.args[0]}" + ) + + else: + # Choose the latest version when raising the actual parsing error. + assert len(errors) >= 1 + exc = errors[max(errors)] + raise exc from None + + if isinstance(result, Leaf): + result = Node(syms.file_input, [result]) + return result + + +def matches_grammar(src_txt: str, grammar: Grammar) -> bool: + drv = driver.Driver(grammar) + try: + drv.parse_string(src_txt, True) + except (ParseError, TokenError, IndentationError): + return False + else: + return True + + +def lib2to3_unparse(node: Node) -> str: + """Given a lib2to3 node, return its string representation.""" + code = str(node) + return code + + +def parse_single_version( + src: str, version: Tuple[int, int], *, type_comments: bool +) -> ast.AST: + filename = "" + return ast.parse( + src, filename, feature_version=version, type_comments=type_comments + ) + + +def parse_ast(src: str) -> ast.AST: + # TODO: support Python 4+ ;) + versions = [(3, minor) for minor in range(3, sys.version_info[1] + 1)] + + first_error = "" + for version in sorted(versions, reverse=True): + try: + return parse_single_version(src, version, type_comments=True) + except SyntaxError as e: + if not first_error: + first_error = str(e) + + # Try to parse without type comments + for version in sorted(versions, reverse=True): + try: + return parse_single_version(src, version, type_comments=False) + except SyntaxError: + pass + + raise SyntaxError(first_error) + + +def _normalize(lineend: str, value: str) -> str: + # To normalize, we strip any leading and trailing space from + # each line... + stripped: List[str] = [i.strip() for i in value.splitlines()] + normalized = lineend.join(stripped) + # ...and remove any blank lines at the beginning and end of + # the whole string + return normalized.strip() + + +def stringify_ast(node: ast.AST, depth: int = 0) -> Iterator[str]: + """Simple visitor generating strings to compare ASTs by content.""" + + if ( + isinstance(node, ast.Constant) + and isinstance(node.value, str) + and node.kind == "u" + ): + # It's a quirk of history that we strip the u prefix over here. We used to + # rewrite the AST nodes for Python version compatibility and we never copied + # over the kind + node.kind = None + + yield f"{' ' * depth}{node.__class__.__name__}(" + + for field in sorted(node._fields): # noqa: F402 + # TypeIgnore has only one field 'lineno' which breaks this comparison + if isinstance(node, ast.TypeIgnore): + break + + try: + value: object = getattr(node, field) + except AttributeError: + continue + + yield f"{' ' * (depth + 1)}{field}=" + + if isinstance(value, list): + for item in value: + # Ignore nested tuples within del statements, because we may insert + # parentheses and they change the AST. + if ( + field == "targets" + and isinstance(node, ast.Delete) + and isinstance(item, ast.Tuple) + ): + for elt in item.elts: + yield from stringify_ast(elt, depth + 2) + + elif isinstance(item, ast.AST): + yield from stringify_ast(item, depth + 2) + + elif isinstance(value, ast.AST): + yield from stringify_ast(value, depth + 2) + + else: + normalized: object + if ( + isinstance(node, ast.Constant) + and field == "value" + and isinstance(value, str) + ): + # Constant strings may be indented across newlines, if they are + # docstrings; fold spaces after newlines when comparing. Similarly, + # trailing and leading space may be removed. + normalized = _normalize("\n", value) + elif field == "type_comment" and isinstance(value, str): + # Trailing whitespace in type comments is removed. + normalized = value.rstrip() + else: + normalized = value + yield f"{' ' * (depth + 2)}{normalized!r}, # {value.__class__.__name__}" + + yield f"{' ' * depth}) # /{node.__class__.__name__}" diff --git a/dbdpy-env/lib/python3.9/site-packages/black/py.typed b/dbdpy-env/lib/python3.9/site-packages/black/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/black/ranges.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/ranges.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..03c8e129948903e4d0cd7e70b894caa0108f67d1 GIT binary patch literal 50136 zcmeI*U2IfE6bJCLA1zDRLMsiHD0G9$hmp3l1tB)DKpQ9^RH&wjF_Ycyw!LAyyYAis zYin#wFd-!6otrwnkJ$@MbND%IT3(rgXoegtzv(s2O~ zJ5^RFWkz?H(z8o`zPjc1_)mIXVz=&FjhA|}L#5JYS2#U7l%LPP!k&6kuaG!9pHJuG zceje2Pjy6N$!Lm4^7B>ce06%g#M$}izVo%F&6E*u*X#51#dN+6dfth3n46mimFkLb zH{uax#M=^9ocn#8)cMxx1QO?*&q=IX`Cj*PRjPhv^GdaP)5b0Kw;R+8#%Vn~EmeMC zin%J)p2+%I$IT}{TUH6$&+CW^xg+_UBIg?9YM;v)<+fM%gSyR&opU+wtW+$d(wWY1 zBBqjNYTSHfI-TUtKF1^;_d0XjDisNtp|OGd^Og15bIyB8oSkp%NxLWSDc_Y+8yYvR zZ>Vo{ez*GVc?#-Q$Cq_7ahK|pIV@8pLBIX`>*IFxop?CFvFy{qt*jFtnLo&}ykpf_ zq8;2$;o8JiinE8Tm2I;fWInqT^YfA?zdXhRvd_85l{0M@t2Z3Ex_{mJn$tV0c`U$H z_ONz!6m%Z=pO-*3At(6PL?lv!M5{wSY+zMWWxQ6K;T2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z!2ep{Zg=0|yB>NkIGKve1D=aDMEinnI_{(3Enfls$#-FI@m0;{fSz|z@8)^DCg7su zce~GiLR5ZfB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOL}h7a0A!_Rimr*X_jbj2$2V0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izj1WM-67U`D+Bbiu4rOmFe3LEiAG(|7GN_#0q z%Y&*ZvpSSacg3Qru``)SnKJIP#_d=SKc9&38ksESNq$PzM?9Ikx**85wA!m=$|vkR{a`X{MQpJ9=(0x!^9u!-aL5a1Apz{ z%;IaiHosr<;%9Fh`LZSP?X|Xk@6YGYZ*^~KDH!QF-t*edD_`$kyX%>cA2x5CnsH;+ z+k1XE`Bv48HIIDsT=&hsW3Q|_(0bt0O|wgXoBQ&^o}cLXhHt7vhgP4e+tV5QzTxlN zzQW;kcPd|6GJVR0W3ye`s$3Jj|GS^Rb8g List[Tuple[int, int]]: + lines: List[Tuple[int, int]] = [] + for lines_str in line_ranges: + parts = lines_str.split("-") + if len(parts) != 2: + raise ValueError( + "Incorrect --line-ranges format, expect 'START-END', found" + f" {lines_str!r}" + ) + try: + start = int(parts[0]) + end = int(parts[1]) + except ValueError: + raise ValueError( + "Incorrect --line-ranges value, expect integer ranges, found" + f" {lines_str!r}" + ) from None + else: + lines.append((start, end)) + return lines + + +def is_valid_line_range(lines: Tuple[int, int]) -> bool: + """Returns whether the line range is valid.""" + return not lines or lines[0] <= lines[1] + + +def adjusted_lines( + lines: Collection[Tuple[int, int]], + original_source: str, + modified_source: str, +) -> List[Tuple[int, int]]: + """Returns the adjusted line ranges based on edits from the original code. + + This computes the new line ranges by diffing original_source and + modified_source, and adjust each range based on how the range overlaps with + the diffs. + + Note the diff can contain lines outside of the original line ranges. This can + happen when the formatting has to be done in adjacent to maintain consistent + local results. For example: + + 1. def my_func(arg1, arg2, + 2. arg3,): + 3. pass + + If it restricts to line 2-2, it can't simply reformat line 2, it also has + to reformat line 1: + + 1. def my_func( + 2. arg1, + 3. arg2, + 4. arg3, + 5. ): + 6. pass + + In this case, we will expand the line ranges to also include the whole diff + block. + + Args: + lines: a collection of line ranges. + original_source: the original source. + modified_source: the modified source. + """ + lines_mappings = _calculate_lines_mappings(original_source, modified_source) + + new_lines = [] + # Keep an index of the current search. Since the lines and lines_mappings are + # sorted, this makes the search complexity linear. + current_mapping_index = 0 + for start, end in sorted(lines): + start_mapping_index = _find_lines_mapping_index( + start, + lines_mappings, + current_mapping_index, + ) + end_mapping_index = _find_lines_mapping_index( + end, + lines_mappings, + start_mapping_index, + ) + current_mapping_index = start_mapping_index + if start_mapping_index >= len(lines_mappings) or end_mapping_index >= len( + lines_mappings + ): + # Protect against invalid inputs. + continue + start_mapping = lines_mappings[start_mapping_index] + end_mapping = lines_mappings[end_mapping_index] + if start_mapping.is_changed_block: + # When the line falls into a changed block, expands to the whole block. + new_start = start_mapping.modified_start + else: + new_start = ( + start - start_mapping.original_start + start_mapping.modified_start + ) + if end_mapping.is_changed_block: + # When the line falls into a changed block, expands to the whole block. + new_end = end_mapping.modified_end + else: + new_end = end - end_mapping.original_start + end_mapping.modified_start + new_range = (new_start, new_end) + if is_valid_line_range(new_range): + new_lines.append(new_range) + return new_lines + + +def convert_unchanged_lines(src_node: Node, lines: Collection[Tuple[int, int]]) -> None: + """Converts unchanged lines to STANDALONE_COMMENT. + + The idea is similar to how `# fmt: on/off` is implemented. It also converts the + nodes between those markers as a single `STANDALONE_COMMENT` leaf node with + the unformatted code as its value. `STANDALONE_COMMENT` is a "fake" token + that will be formatted as-is with its prefix normalized. + + Here we perform two passes: + + 1. Visit the top-level statements, and convert them to a single + `STANDALONE_COMMENT` when unchanged. This speeds up formatting when some + of the top-level statements aren't changed. + 2. Convert unchanged "unwrapped lines" to `STANDALONE_COMMENT` nodes line by + line. "unwrapped lines" are divided by the `NEWLINE` token. e.g. a + multi-line statement is *one* "unwrapped line" that ends with `NEWLINE`, + even though this statement itself can span multiple lines, and the + tokenizer only sees the last '\n' as the `NEWLINE` token. + + NOTE: During pass (2), comment prefixes and indentations are ALWAYS + normalized even when the lines aren't changed. This is fixable by moving + more formatting to pass (1). However, it's hard to get it correct when + incorrect indentations are used. So we defer this to future optimizations. + """ + lines_set: Set[int] = set() + for start, end in lines: + lines_set.update(range(start, end + 1)) + visitor = _TopLevelStatementsVisitor(lines_set) + _ = list(visitor.visit(src_node)) # Consume all results. + _convert_unchanged_line_by_line(src_node, lines_set) + + +def _contains_standalone_comment(node: LN) -> bool: + if isinstance(node, Leaf): + return node.type == STANDALONE_COMMENT + else: + for child in node.children: + if _contains_standalone_comment(child): + return True + return False + + +class _TopLevelStatementsVisitor(Visitor[None]): + """ + A node visitor that converts unchanged top-level statements to + STANDALONE_COMMENT. + + This is used in addition to _convert_unchanged_line_by_line, to + speed up formatting when there are unchanged top-level + classes/functions/statements. + """ + + def __init__(self, lines_set: Set[int]): + self._lines_set = lines_set + + def visit_simple_stmt(self, node: Node) -> Iterator[None]: + # This is only called for top-level statements, since `visit_suite` + # won't visit its children nodes. + yield from [] + newline_leaf = last_leaf(node) + if not newline_leaf: + return + assert ( + newline_leaf.type == NEWLINE + ), f"Unexpectedly found leaf.type={newline_leaf.type}" + # We need to find the furthest ancestor with the NEWLINE as the last + # leaf, since a `suite` can simply be a `simple_stmt` when it puts + # its body on the same line. Example: `if cond: pass`. + ancestor = furthest_ancestor_with_last_leaf(newline_leaf) + if not _get_line_range(ancestor).intersection(self._lines_set): + _convert_node_to_standalone_comment(ancestor) + + def visit_suite(self, node: Node) -> Iterator[None]: + yield from [] + # If there is a STANDALONE_COMMENT node, it means parts of the node tree + # have fmt on/off/skip markers. Those STANDALONE_COMMENT nodes can't + # be simply converted by calling str(node). So we just don't convert + # here. + if _contains_standalone_comment(node): + return + # Find the semantic parent of this suite. For `async_stmt` and + # `async_funcdef`, the ASYNC token is defined on a separate level by the + # grammar. + semantic_parent = node.parent + if semantic_parent is not None: + if ( + semantic_parent.prev_sibling is not None + and semantic_parent.prev_sibling.type == ASYNC + ): + semantic_parent = semantic_parent.parent + if semantic_parent is not None and not _get_line_range( + semantic_parent + ).intersection(self._lines_set): + _convert_node_to_standalone_comment(semantic_parent) + + +def _convert_unchanged_line_by_line(node: Node, lines_set: Set[int]) -> None: + """Converts unchanged to STANDALONE_COMMENT line by line.""" + for leaf in node.leaves(): + if leaf.type != NEWLINE: + # We only consider "unwrapped lines", which are divided by the NEWLINE + # token. + continue + if leaf.parent and leaf.parent.type == syms.match_stmt: + # The `suite` node is defined as: + # match_stmt: "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT + # Here we need to check `subject_expr`. The `case_block+` will be + # checked by their own NEWLINEs. + nodes_to_ignore: List[LN] = [] + prev_sibling = leaf.prev_sibling + while prev_sibling: + nodes_to_ignore.insert(0, prev_sibling) + prev_sibling = prev_sibling.prev_sibling + if not _get_line_range(nodes_to_ignore).intersection(lines_set): + _convert_nodes_to_standalone_comment(nodes_to_ignore, newline=leaf) + elif leaf.parent and leaf.parent.type == syms.suite: + # The `suite` node is defined as: + # suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT + # We will check `simple_stmt` and `stmt+` separately against the lines set + parent_sibling = leaf.parent.prev_sibling + nodes_to_ignore = [] + while parent_sibling and not parent_sibling.type == syms.suite: + # NOTE: Multiple suite nodes can exist as siblings in e.g. `if_stmt`. + nodes_to_ignore.insert(0, parent_sibling) + parent_sibling = parent_sibling.prev_sibling + # Special case for `async_stmt` and `async_funcdef` where the ASYNC + # token is on the grandparent node. + grandparent = leaf.parent.parent + if ( + grandparent is not None + and grandparent.prev_sibling is not None + and grandparent.prev_sibling.type == ASYNC + ): + nodes_to_ignore.insert(0, grandparent.prev_sibling) + if not _get_line_range(nodes_to_ignore).intersection(lines_set): + _convert_nodes_to_standalone_comment(nodes_to_ignore, newline=leaf) + else: + ancestor = furthest_ancestor_with_last_leaf(leaf) + # Consider multiple decorators as a whole block, as their + # newlines have different behaviors than the rest of the grammar. + if ( + ancestor.type == syms.decorator + and ancestor.parent + and ancestor.parent.type == syms.decorators + ): + ancestor = ancestor.parent + if not _get_line_range(ancestor).intersection(lines_set): + _convert_node_to_standalone_comment(ancestor) + + +def _convert_node_to_standalone_comment(node: LN) -> None: + """Convert node to STANDALONE_COMMENT by modifying the tree inline.""" + parent = node.parent + if not parent: + return + first = first_leaf(node) + last = last_leaf(node) + if not first or not last: + return + if first is last: + # This can happen on the following edge cases: + # 1. A block of `# fmt: off/on` code except the `# fmt: on` is placed + # on the end of the last line instead of on a new line. + # 2. A single backslash on its own line followed by a comment line. + # Ideally we don't want to format them when not requested, but fixing + # isn't easy. These cases are also badly formatted code, so it isn't + # too bad we reformat them. + return + # The prefix contains comments and indentation whitespaces. They are + # reformatted accordingly to the correct indentation level. + # This also means the indentation will be changed on the unchanged lines, and + # this is actually required to not break incremental reformatting. + prefix = first.prefix + first.prefix = "" + index = node.remove() + if index is not None: + # Remove the '\n', as STANDALONE_COMMENT will have '\n' appended when + # generating the formatted code. + value = str(node)[:-1] + parent.insert_child( + index, + Leaf( + STANDALONE_COMMENT, + value, + prefix=prefix, + fmt_pass_converted_first_leaf=first, + ), + ) + + +def _convert_nodes_to_standalone_comment(nodes: Sequence[LN], *, newline: Leaf) -> None: + """Convert nodes to STANDALONE_COMMENT by modifying the tree inline.""" + if not nodes: + return + parent = nodes[0].parent + first = first_leaf(nodes[0]) + if not parent or not first: + return + prefix = first.prefix + first.prefix = "" + value = "".join(str(node) for node in nodes) + # The prefix comment on the NEWLINE leaf is the trailing comment of the statement. + if newline.prefix: + value += newline.prefix + newline.prefix = "" + index = nodes[0].remove() + for node in nodes[1:]: + node.remove() + if index is not None: + parent.insert_child( + index, + Leaf( + STANDALONE_COMMENT, + value, + prefix=prefix, + fmt_pass_converted_first_leaf=first, + ), + ) + + +def _leaf_line_end(leaf: Leaf) -> int: + """Returns the line number of the leaf node's last line.""" + if leaf.type == NEWLINE: + return leaf.lineno + else: + # Leaf nodes like multiline strings can occupy multiple lines. + return leaf.lineno + str(leaf).count("\n") + + +def _get_line_range(node_or_nodes: Union[LN, List[LN]]) -> Set[int]: + """Returns the line range of this node or list of nodes.""" + if isinstance(node_or_nodes, list): + nodes = node_or_nodes + if not nodes: + return set() + first = first_leaf(nodes[0]) + last = last_leaf(nodes[-1]) + if first and last: + line_start = first.lineno + line_end = _leaf_line_end(last) + return set(range(line_start, line_end + 1)) + else: + return set() + else: + node = node_or_nodes + if isinstance(node, Leaf): + return set(range(node.lineno, _leaf_line_end(node) + 1)) + else: + first = first_leaf(node) + last = last_leaf(node) + if first and last: + return set(range(first.lineno, _leaf_line_end(last) + 1)) + else: + return set() + + +@dataclass +class _LinesMapping: + """1-based lines mapping from original source to modified source. + + Lines [original_start, original_end] from original source + are mapped to [modified_start, modified_end]. + + The ranges are inclusive on both ends. + """ + + original_start: int + original_end: int + modified_start: int + modified_end: int + # Whether this range corresponds to a changed block, or an unchanged block. + is_changed_block: bool + + +def _calculate_lines_mappings( + original_source: str, + modified_source: str, +) -> Sequence[_LinesMapping]: + """Returns a sequence of _LinesMapping by diffing the sources. + + For example, given the following diff: + import re + - def func(arg1, + - arg2, arg3): + + def func(arg1, arg2, arg3): + pass + It returns the following mappings: + original -> modified + (1, 1) -> (1, 1), is_changed_block=False (the "import re" line) + (2, 3) -> (2, 2), is_changed_block=True (the diff) + (4, 4) -> (3, 3), is_changed_block=False (the "pass" line) + + You can think of this visually as if it brings up a side-by-side diff, and tries + to map the line ranges from the left side to the right side: + + (1, 1)->(1, 1) 1. import re 1. import re + (2, 3)->(2, 2) 2. def func(arg1, 2. def func(arg1, arg2, arg3): + 3. arg2, arg3): + (4, 4)->(3, 3) 4. pass 3. pass + + Args: + original_source: the original source. + modified_source: the modified source. + """ + matcher = difflib.SequenceMatcher( + None, + original_source.splitlines(keepends=True), + modified_source.splitlines(keepends=True), + ) + matching_blocks = matcher.get_matching_blocks() + lines_mappings: List[_LinesMapping] = [] + # matching_blocks is a sequence of "same block of code ranges", see + # https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.get_matching_blocks + # Each block corresponds to a _LinesMapping with is_changed_block=False, + # and the ranges between two blocks corresponds to a _LinesMapping with + # is_changed_block=True, + # NOTE: matching_blocks is 0-based, but _LinesMapping is 1-based. + for i, block in enumerate(matching_blocks): + if i == 0: + if block.a != 0 or block.b != 0: + lines_mappings.append( + _LinesMapping( + original_start=1, + original_end=block.a, + modified_start=1, + modified_end=block.b, + is_changed_block=False, + ) + ) + else: + previous_block = matching_blocks[i - 1] + lines_mappings.append( + _LinesMapping( + original_start=previous_block.a + previous_block.size + 1, + original_end=block.a, + modified_start=previous_block.b + previous_block.size + 1, + modified_end=block.b, + is_changed_block=True, + ) + ) + if i < len(matching_blocks) - 1: + lines_mappings.append( + _LinesMapping( + original_start=block.a + 1, + original_end=block.a + block.size, + modified_start=block.b + 1, + modified_end=block.b + block.size, + is_changed_block=False, + ) + ) + return lines_mappings + + +def _find_lines_mapping_index( + original_line: int, + lines_mappings: Sequence[_LinesMapping], + start_index: int, +) -> int: + """Returns the original index of the lines mappings for the original line.""" + index = start_index + while index < len(lines_mappings): + mapping = lines_mappings[index] + if ( + mapping.original_start <= original_line + and original_line <= mapping.original_end + ): + return index + index += 1 + return index diff --git a/dbdpy-env/lib/python3.9/site-packages/black/report.py b/dbdpy-env/lib/python3.9/site-packages/black/report.py new file mode 100644 index 00000000..89899f2f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/report.py @@ -0,0 +1,107 @@ +""" +Summarize Black runs to users. +""" + +from dataclasses import dataclass +from enum import Enum +from pathlib import Path + +from click import style + +from black.output import err, out + + +class Changed(Enum): + NO = 0 + CACHED = 1 + YES = 2 + + +class NothingChanged(UserWarning): + """Raised when reformatted code is the same as source.""" + + +@dataclass +class Report: + """Provides a reformatting counter. Can be rendered with `str(report)`.""" + + check: bool = False + diff: bool = False + quiet: bool = False + verbose: bool = False + change_count: int = 0 + same_count: int = 0 + failure_count: int = 0 + + def done(self, src: Path, changed: Changed) -> None: + """Increment the counter for successful reformatting. Write out a message.""" + if changed is Changed.YES: + reformatted = "would reformat" if self.check or self.diff else "reformatted" + if self.verbose or not self.quiet: + out(f"{reformatted} {src}") + self.change_count += 1 + else: + if self.verbose: + if changed is Changed.NO: + msg = f"{src} already well formatted, good job." + else: + msg = f"{src} wasn't modified on disk since last run." + out(msg, bold=False) + self.same_count += 1 + + def failed(self, src: Path, message: str) -> None: + """Increment the counter for failed reformatting. Write out a message.""" + err(f"error: cannot format {src}: {message}") + self.failure_count += 1 + + def path_ignored(self, path: Path, message: str) -> None: + if self.verbose: + out(f"{path} ignored: {message}", bold=False) + + @property + def return_code(self) -> int: + """Return the exit code that the app should use. + + This considers the current state of changed files and failures: + - if there were any failures, return 123; + - if any files were changed and --check is being used, return 1; + - otherwise return 0. + """ + # According to http://tldp.org/LDP/abs/html/exitcodes.html starting with + # 126 we have special return codes reserved by the shell. + if self.failure_count: + return 123 + + elif self.change_count and self.check: + return 1 + + return 0 + + def __str__(self) -> str: + """Render a color report of the current state. + + Use `click.unstyle` to remove colors. + """ + if self.check or self.diff: + reformatted = "would be reformatted" + unchanged = "would be left unchanged" + failed = "would fail to reformat" + else: + reformatted = "reformatted" + unchanged = "left unchanged" + failed = "failed to reformat" + report = [] + if self.change_count: + s = "s" if self.change_count > 1 else "" + report.append( + style(f"{self.change_count} file{s} ", bold=True, fg="blue") + + style(f"{reformatted}", bold=True) + ) + + if self.same_count: + s = "s" if self.same_count > 1 else "" + report.append(style(f"{self.same_count} file{s} ", fg="blue") + unchanged) + if self.failure_count: + s = "s" if self.failure_count > 1 else "" + report.append(style(f"{self.failure_count} file{s} {failed}", fg="red")) + return ", ".join(report) + "." diff --git a/dbdpy-env/lib/python3.9/site-packages/black/rusty.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/rusty.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..c36afd15d1d516942affc981fa273ff72a938963 GIT binary patch literal 50135 zcmeI*Uu;uV90%}U|7=v~V8}>jR8|RLim<m*OZLleL8UT@ zU9m(&#S+~~E6#r(U+H`sbpna=_U9zlt-RO6T$NhCwqvbYw{=Uq{dR-;f(Nu7o|Y^bK-CC<$^eW%@%=ahG))GIAp zHZ`wraeiAv_B;i3tK+LWnYc@J%3_wOkzmOF{rb3_dL|wYa4hTea4Xk|kIWz8Se~(F zn5d82Ib7SgN^#bZYh~G72bs?;rF_5SDJ)O&fUGm`o#?Z}IC&unh96Q-s$72Dm zvWB&)tHkPCkLOzHS;nLCy>g2DJ{!17F4+%JCI7eLqUwy1u8zmTQrokJ8SSllxhj(7 z$hwG@awB;T57{oy=~$jy%F|qB{uJ-O(oQVHC=h@E1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z;D0SJvFF_J2@f3%K1QV#0ng=nqC-J9o$*m{%vVHz@>$q1KC0Of(DN=Dc(szR3ApIY z#Gc_}L={)~T;`#G&%R&gD+spx|6J#K(R7}Yf_3I` zeBC=e&xc6wTSuPZz$|wsxht+nKb6yO(|tZ8Th7l_CNECVa z+UKne=Z;IBTVAqquC8lrSXJL0>F%yuT^o%wG=^VTsZ?(^mF=R3%vHq_F;j)(p{^ZD zsdUCLv-bJfr(_dca$7mdDre_cax1k&p9`11oU!%u3n}HQ%fpWLI@h3u00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U=TDNpiUYJD^mk0-l$h+G`EBx0tb`5qeF zOXOB6Cb1%aI%AkwTH>Lz{m$0T_V-v_`JC$`Dj%?C+}zA_5e=@f;{`fy((yAK^YlG? zmZ-iUZY_vkw`0D=E*@^YT#L9CbIpx8qyRb3F|~bXz5MZ=)l>UjD6i;gTKOmR29% zzi{)LC*MBtMQ8H+-@AvrS4T#6xVLr|P4=JZ-@WhJH}7uTzx?Az%|Abuyfgd#vwzi6 zB(;C!jn9ThkA7(M{V~~4)$YD@fLeDmLTeZ}Lg|5U%W zdcmC0(~Dd?Yg{wEeyjh&vYVf_-MRhaoZYv#|1j&L4d<7;wmm+(=VHaBTi2H-{sjes BF3A7@ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/black/rusty.py b/dbdpy-env/lib/python3.9/site-packages/black/rusty.py new file mode 100644 index 00000000..ebd4c052 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/black/rusty.py @@ -0,0 +1,28 @@ +"""An error-handling model influenced by that used by the Rust programming language + +See https://doc.rust-lang.org/book/ch09-00-error-handling.html. +""" + +from typing import Generic, TypeVar, Union + +T = TypeVar("T") +E = TypeVar("E", bound=Exception) + + +class Ok(Generic[T]): + def __init__(self, value: T) -> None: + self._value = value + + def ok(self) -> T: + return self._value + + +class Err(Generic[E]): + def __init__(self, e: E) -> None: + self._e = e + + def err(self) -> E: + return self._e + + +Result = Union[Ok[T], Err[E]] diff --git a/dbdpy-env/lib/python3.9/site-packages/black/strings.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/strings.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..a76cf50fe79a36e3d281fbaee8e0975ce8e77d13 GIT binary patch literal 50137 zcmeI*Uu;uV90%}U+jT2pgH1*sC#>A6$?O35}OM53) zW}Jzbpow8-4}`=xVpK?+nTl~DxDgY>g9)N>{z)((i4OlH=z|Id=I?j!xm()_Jng~c zd&t>2zjIE1=iJZjcsp?J`foRji5$em!*w3li2|YnGQj0-uHW#iQh^Qa0dpw#hd(zY z9lLqhuChWYBl4snJ*(vBYglWIf3D{xcIv*_6i{Dws8rhM38klo^7DDtSyPMk3W>Ax zd2~L0cC%RdR97UHjHGxZKi^WF??Js@;_Q4h<9r=yBNdJB((Ci{b?JOt^}HSHFgG_3 zD%BI;7mbHiG~Ssoly{}n zmX>V~Z)k3@f49c0dGhO4$KUE?;x5%LRV=eyf-&p&*Te19Gx4yOW7(&RTUjSQGC#<% zJmc~+7VTW_w{ewX?;&et+iVA!&n~6>dC8Ms7V&`W^WKr6>ZR_wk)w~laIEp2E5=G5 z^Kz9vhGKuR^3~km zUg$K>d3EFHamiEaCNpRK%EpG(t2)D-oh$2CM8XY?p*3|%b!U>94!X^pFB*>;DijNL z>``(>U2c?{m)_<6>^)qiWVdpaRqoE$aVvF>z85Zixno<*FQt^LF1NedYp+2I0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izzz$^>c|F3<6{&xbJbvw)3B0U5k009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY<+0%cXSQ^GQTI1>x2w9yk%p=dlDNzwMb zbcj;4*00(!O~GWkCl*mH-N{7Cka3SWZpC_dYa+~RWU`be`BSPn5{$(X9Xv!1j$7hU zLs6NF2A?K!DixJjQE}QxMdQ2DRPCaXUh8lpyZ{7W%cHR zzg(!QX\\+)(?P" + r"(u(?P[a-fA-F0-9]{4}))" # Character with 16-bit hex value xxxx + r"|(U(?P[a-fA-F0-9]{8}))" # Character with 32-bit hex value xxxxxxxx + r"|(x(?P[a-fA-F0-9]{2}))" # Character with hex value hh + r"|(N\{(?P[a-zA-Z0-9 \-]{2,})\})" # Character named name in the Unicode database + r")", + re.VERBOSE, +) + + +def sub_twice(regex: Pattern[str], replacement: str, original: str) -> str: + """Replace `regex` with `replacement` twice on `original`. + + This is used by string normalization to perform replaces on + overlapping matches. + """ + return regex.sub(replacement, regex.sub(replacement, original)) + + +def has_triple_quotes(string: str) -> bool: + """ + Returns: + True iff @string starts with three quotation characters. + """ + raw_string = string.lstrip(STRING_PREFIX_CHARS) + return raw_string[:3] in {'"""', "'''"} + + +def lines_with_leading_tabs_expanded(s: str) -> List[str]: + """ + Splits string into lines and expands only leading tabs (following the normal + Python rules) + """ + lines = [] + for line in s.splitlines(): + # Find the index of the first non-whitespace character after a string of + # whitespace that includes at least one tab + match = FIRST_NON_WHITESPACE_RE.match(line) + if match: + first_non_whitespace_idx = match.start(1) + + lines.append( + line[:first_non_whitespace_idx].expandtabs() + + line[first_non_whitespace_idx:] + ) + else: + lines.append(line) + return lines + + +def fix_docstring(docstring: str, prefix: str) -> str: + # https://www.python.org/dev/peps/pep-0257/#handling-docstring-indentation + if not docstring: + return "" + lines = lines_with_leading_tabs_expanded(docstring) + # Determine minimum indentation (first line doesn't count): + indent = sys.maxsize + for line in lines[1:]: + stripped = line.lstrip() + if stripped: + indent = min(indent, len(line) - len(stripped)) + # Remove indentation (first line is special): + trimmed = [lines[0].strip()] + if indent < sys.maxsize: + last_line_idx = len(lines) - 2 + for i, line in enumerate(lines[1:]): + stripped_line = line[indent:].rstrip() + if stripped_line or i == last_line_idx: + trimmed.append(prefix + stripped_line) + else: + trimmed.append("") + return "\n".join(trimmed) + + +def get_string_prefix(string: str) -> str: + """ + Pre-conditions: + * assert_is_leaf_string(@string) + + Returns: + @string's prefix (e.g. '', 'r', 'f', or 'rf'). + """ + assert_is_leaf_string(string) + + prefix = "" + prefix_idx = 0 + while string[prefix_idx] in STRING_PREFIX_CHARS: + prefix += string[prefix_idx] + prefix_idx += 1 + + return prefix + + +def assert_is_leaf_string(string: str) -> None: + """ + Checks the pre-condition that @string has the format that you would expect + of `leaf.value` where `leaf` is some Leaf such that `leaf.type == + token.STRING`. A more precise description of the pre-conditions that are + checked are listed below. + + Pre-conditions: + * @string starts with either ', ", ', or " where + `set()` is some subset of `set(STRING_PREFIX_CHARS)`. + * @string ends with a quote character (' or "). + + Raises: + AssertionError(...) if the pre-conditions listed above are not + satisfied. + """ + dquote_idx = string.find('"') + squote_idx = string.find("'") + if -1 in [dquote_idx, squote_idx]: + quote_idx = max(dquote_idx, squote_idx) + else: + quote_idx = min(squote_idx, dquote_idx) + + assert ( + 0 <= quote_idx < len(string) - 1 + ), f"{string!r} is missing a starting quote character (' or \")." + assert string[-1] in ( + "'", + '"', + ), f"{string!r} is missing an ending quote character (' or \")." + assert set(string[:quote_idx]).issubset( + set(STRING_PREFIX_CHARS) + ), f"{set(string[:quote_idx])} is NOT a subset of {set(STRING_PREFIX_CHARS)}." + + +def normalize_string_prefix(s: str) -> str: + """Make all string prefixes lowercase.""" + match = STRING_PREFIX_RE.match(s) + assert match is not None, f"failed to match string {s!r}" + orig_prefix = match.group(1) + new_prefix = ( + orig_prefix.replace("F", "f") + .replace("B", "b") + .replace("U", "") + .replace("u", "") + ) + + # Python syntax guarantees max 2 prefixes and that one of them is "r" + if len(new_prefix) == 2 and "r" != new_prefix[0].lower(): + new_prefix = new_prefix[::-1] + return f"{new_prefix}{match.group(2)}" + + +# Re(gex) does actually cache patterns internally but this still improves +# performance on a long list literal of strings by 5-9% since lru_cache's +# caching overhead is much lower. +@lru_cache(maxsize=64) +def _cached_compile(pattern: str) -> Pattern[str]: + return re.compile(pattern) + + +def normalize_string_quotes(s: str) -> str: + """Prefer double quotes but only if it doesn't cause more escaping. + + Adds or removes backslashes as appropriate. Doesn't parse and fix + strings nested in f-strings. + """ + value = s.lstrip(STRING_PREFIX_CHARS) + if value[:3] == '"""': + return s + + elif value[:3] == "'''": + orig_quote = "'''" + new_quote = '"""' + elif value[0] == '"': + orig_quote = '"' + new_quote = "'" + else: + orig_quote = "'" + new_quote = '"' + first_quote_pos = s.find(orig_quote) + if first_quote_pos == -1: + return s # There's an internal error + + prefix = s[:first_quote_pos] + unescaped_new_quote = _cached_compile(rf"(([^\\]|^)(\\\\)*){new_quote}") + escaped_new_quote = _cached_compile(rf"([^\\]|^)\\((?:\\\\)*){new_quote}") + escaped_orig_quote = _cached_compile(rf"([^\\]|^)\\((?:\\\\)*){orig_quote}") + body = s[first_quote_pos + len(orig_quote) : -len(orig_quote)] + if "r" in prefix.casefold(): + if unescaped_new_quote.search(body): + # There's at least one unescaped new_quote in this raw string + # so converting is impossible + return s + + # Do not introduce or remove backslashes in raw strings + new_body = body + else: + # remove unnecessary escapes + new_body = sub_twice(escaped_new_quote, rf"\1\2{new_quote}", body) + if body != new_body: + # Consider the string without unnecessary escapes as the original + body = new_body + s = f"{prefix}{orig_quote}{body}{orig_quote}" + new_body = sub_twice(escaped_orig_quote, rf"\1\2{orig_quote}", new_body) + new_body = sub_twice(unescaped_new_quote, rf"\1\\{new_quote}", new_body) + if "f" in prefix.casefold(): + matches = re.findall( + r""" + (?:(? orig_escape_count: + return s # Do not introduce more escaping + + if new_escape_count == orig_escape_count and orig_quote == '"': + return s # Prefer double quotes + + return f"{prefix}{new_quote}{new_body}{new_quote}" + + +def normalize_unicode_escape_sequences(leaf: Leaf) -> None: + """Replace hex codes in Unicode escape sequences with lowercase representation.""" + text = leaf.value + prefix = get_string_prefix(text) + if "r" in prefix.lower(): + return + + def replace(m: Match[str]) -> str: + groups = m.groupdict() + back_slashes = groups["backslashes"] + + if len(back_slashes) % 2 == 0: + return back_slashes + groups["body"] + + if groups["u"]: + # \u + return back_slashes + "u" + groups["u"].lower() + elif groups["U"]: + # \U + return back_slashes + "U" + groups["U"].lower() + elif groups["x"]: + # \x + return back_slashes + "x" + groups["x"].lower() + else: + assert groups["N"], f"Unexpected match: {m}" + # \N{} + return back_slashes + "N{" + groups["N"].upper() + "}" + + leaf.value = re.sub(UNICODE_ESCAPE_RE, replace, text) + + +@lru_cache(maxsize=4096) +def char_width(char: str) -> int: + """Return the width of a single character as it would be displayed in a + terminal or editor (which respects Unicode East Asian Width). + + Full width characters are counted as 2, while half width characters are + counted as 1. Also control characters are counted as 0. + """ + table = WIDTH_TABLE + codepoint = ord(char) + highest = len(table) - 1 + lowest = 0 + idx = highest // 2 + while True: + start_codepoint, end_codepoint, width = table[idx] + if codepoint < start_codepoint: + highest = idx - 1 + elif codepoint > end_codepoint: + lowest = idx + 1 + else: + return 0 if width < 0 else width + if highest < lowest: + break + idx = (highest + lowest) // 2 + return 1 + + +def str_width(line_str: str) -> int: + """Return the width of `line_str` as it would be displayed in a terminal + or editor (which respects Unicode East Asian Width). + + You could utilize this function to determine, for example, if a string + is too wide to display in a terminal or editor. + """ + if line_str.isascii(): + # Fast path for a line consisting of only ASCII characters + return len(line_str) + return sum(map(char_width, line_str)) + + +def count_chars_in_width(line_str: str, max_width: int) -> int: + """Count the number of characters in `line_str` that would fit in a + terminal or editor of `max_width` (which respects Unicode East Asian + Width). + """ + total_width = 0 + for i, char in enumerate(line_str): + width = char_width(char) + if width + total_width > max_width: + return i + total_width += width + return len(line_str) diff --git a/dbdpy-env/lib/python3.9/site-packages/black/trans.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/black/trans.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..aa8dd95b5f3c8d538386670de96226ffae74b139 GIT binary patch literal 50135 zcmeI*U2IfE6bJCLA1$l2(58JTLG6mf1|x0h2SRM>(hs4awAx1d0+ZeDmac4fm%F#X zN(qey6VZ@1AzEHglP21z36UBA5l>HIN4oSy( zJnU3ip_CcfYf8^9x%nCz?eTMZUShZITaA~7GDD?O=0GSlHwFD*y~LUM=$7;Kq)a0k-=Wv%=8NfkTlBmW>o7Yv4=Obf z-xH08RW#n4u;T3R<5Qh)lTILU*7=;ox|Q#Bl&exL8@e{A=Ju_f_O~0*3vSbTcv`Cb zz!Y&+YDXgDYrSng`Ps5cz=M*{D6|VNVoKbFvbU&cmoY*;+^Ug}ef-05n z4<%wMX&Sf9SEkcR{>*bM;&HDt$E{M~pc$MW$UR@#kUi(Tr^K20=AX2C@}BZtDfLv_ z)-A0qZO-r3q&-go-Rk&~PA2YBow9;uswJ4Te}8@4&b<>4`#F|<`nZ*K;v@5Kb1d&z zeVS-5w~M)UaFychA!}vZOb40IEJggh-Ai9o=138ey*G%zn|;4N-jAMQ3e0E;-ad7lu;FnhNO0;Q)Z;UvZ*qh z=Ezz^4|5}VMkj5TRXUdUmU2H=nLp0wudox#FbV`9009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5cppU%cO z;%oFqFwWQB<^Jq_T%}~Ta+Ou?&ew4(wNT#+m%iMwE#N1Mtfx7+^VME!0X`rA0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00IzLc!9aUYw!I1c-=1i&e#D05P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1RwwbN1%8GbxOZD5KhO!DrF9YR45t`M+|yq7Y&m^ zjRDn>ZVo0>1F?u|>rW;OQ^tMPxE<@^rxRgbBa=lu$xo@4NH7*l^zab5IBttaO-02X z8rx6gRw^p7q5{(h##6M?LnjBFbDbRQv%2!R#79&%WY4&{S?VGhYqaAM9XIIsL5_L) zraenkn-g!&iJ!M)e#9;wZoFLcxaM=sj5#DfIqxxdd}qLZ3yyNIWZq)SX37G(1z#y^ zC}~7@2hE7=Y?tdl7fiBU1xL=AOL>f0+$H4Zle_sJQHpCfS1E-=r;q#HRA7g9`wYx2 zuwJOLCz&?;67kiw>sN<^#-3=rGL@j@)vI-1K7K5J$NkPIr5E-t6GS;EM-;{NlAuuRi+j-RAS(eDbALhZ=el zZ}nX^r(bEBogOVYG-bSgAX$3$#J7j5@Amvc&$phb363>?-f*}-cDD7ee|-7ZH{Ymw zZf(ip3nw0M?XGq$^!`V0w1nRIreyrwy;X&0ULI&VR Err[CannotTransform]: + """(T)ransform Err + + Convenience function used when working with the TResult type. + """ + cant_transform = CannotTransform(err_msg) + return Err(cant_transform) + + +def hug_power_op( + line: Line, features: Collection[Feature], mode: Mode +) -> Iterator[Line]: + """A transformer which normalizes spacing around power operators.""" + + # Performance optimization to avoid unnecessary Leaf clones and other ops. + for leaf in line.leaves: + if leaf.type == token.DOUBLESTAR: + break + else: + raise CannotTransform("No doublestar token was found in the line.") + + def is_simple_lookup(index: int, step: Literal[1, -1]) -> bool: + # Brackets and parentheses indicate calls, subscripts, etc. ... + # basically stuff that doesn't count as "simple". Only a NAME lookup + # or dotted lookup (eg. NAME.NAME) is OK. + if step == -1: + disallowed = {token.RPAR, token.RSQB} + else: + disallowed = {token.LPAR, token.LSQB} + + while 0 <= index < len(line.leaves): + current = line.leaves[index] + if current.type in disallowed: + return False + if current.type not in {token.NAME, token.DOT} or current.value == "for": + # If the current token isn't disallowed, we'll assume this is simple as + # only the disallowed tokens are semantically attached to this lookup + # expression we're checking. Also, stop early if we hit the 'for' bit + # of a comprehension. + return True + + index += step + + return True + + def is_simple_operand(index: int, kind: Literal["base", "exponent"]) -> bool: + # An operand is considered "simple" if's a NAME, a numeric CONSTANT, a simple + # lookup (see above), with or without a preceding unary operator. + start = line.leaves[index] + if start.type in {token.NAME, token.NUMBER}: + return is_simple_lookup(index, step=(1 if kind == "exponent" else -1)) + + if start.type in {token.PLUS, token.MINUS, token.TILDE}: + if line.leaves[index + 1].type in {token.NAME, token.NUMBER}: + # step is always one as bases with a preceding unary op will be checked + # for simplicity starting from the next token (so it'll hit the check + # above). + return is_simple_lookup(index + 1, step=1) + + return False + + new_line = line.clone() + should_hug = False + for idx, leaf in enumerate(line.leaves): + new_leaf = leaf.clone() + if should_hug: + new_leaf.prefix = "" + should_hug = False + + should_hug = ( + (0 < idx < len(line.leaves) - 1) + and leaf.type == token.DOUBLESTAR + and is_simple_operand(idx - 1, kind="base") + and line.leaves[idx - 1].value != "lambda" + and is_simple_operand(idx + 1, kind="exponent") + ) + if should_hug: + new_leaf.prefix = "" + + # We have to be careful to make a new line properly: + # - bracket related metadata must be maintained (handled by Line.append) + # - comments need to copied over, updating the leaf IDs they're attached to + new_line.append(new_leaf, preformatted=True) + for comment_leaf in line.comments_after(leaf): + new_line.append(comment_leaf, preformatted=True) + + yield new_line + + +class StringTransformer(ABC): + """ + An implementation of the Transformer protocol that relies on its + subclasses overriding the template methods `do_match(...)` and + `do_transform(...)`. + + This Transformer works exclusively on strings (for example, by merging + or splitting them). + + The following sections can be found among the docstrings of each concrete + StringTransformer subclass. + + Requirements: + Which requirements must be met of the given Line for this + StringTransformer to be applied? + + Transformations: + If the given Line meets all of the above requirements, which string + transformations can you expect to be applied to it by this + StringTransformer? + + Collaborations: + What contractual agreements does this StringTransformer have with other + StringTransfomers? Such collaborations should be eliminated/minimized + as much as possible. + """ + + __name__: Final = "StringTransformer" + + # Ideally this would be a dataclass, but unfortunately mypyc breaks when used with + # `abc.ABC`. + def __init__(self, line_length: int, normalize_strings: bool) -> None: + self.line_length = line_length + self.normalize_strings = normalize_strings + + @abstractmethod + def do_match(self, line: Line) -> TMatchResult: + """ + Returns: + * Ok(string_indices) such that for each index, `line.leaves[index]` + is our target string if a match was able to be made. For + transformers that don't result in more lines (e.g. StringMerger, + StringParenStripper), multiple matches and transforms are done at + once to reduce the complexity. + OR + * Err(CannotTransform), if no match could be made. + """ + + @abstractmethod + def do_transform( + self, line: Line, string_indices: List[int] + ) -> Iterator[TResult[Line]]: + """ + Yields: + * Ok(new_line) where new_line is the new transformed line. + OR + * Err(CannotTransform) if the transformation failed for some reason. The + `do_match(...)` template method should usually be used to reject + the form of the given Line, but in some cases it is difficult to + know whether or not a Line meets the StringTransformer's + requirements until the transformation is already midway. + + Side Effects: + This method should NOT mutate @line directly, but it MAY mutate the + Line's underlying Node structure. (WARNING: If the underlying Node + structure IS altered, then this method should NOT be allowed to + yield an CannotTransform after that point.) + """ + + def __call__( + self, line: Line, _features: Collection[Feature], _mode: Mode + ) -> Iterator[Line]: + """ + StringTransformer instances have a call signature that mirrors that of + the Transformer type. + + Raises: + CannotTransform(...) if the concrete StringTransformer class is unable + to transform @line. + """ + # Optimization to avoid calling `self.do_match(...)` when the line does + # not contain any string. + if not any(leaf.type == token.STRING for leaf in line.leaves): + raise CannotTransform("There are no strings in this line.") + + match_result = self.do_match(line) + + if isinstance(match_result, Err): + cant_transform = match_result.err() + raise CannotTransform( + f"The string transformer {self.__class__.__name__} does not recognize" + " this line as one that it can transform." + ) from cant_transform + + string_indices = match_result.ok() + + for line_result in self.do_transform(line, string_indices): + if isinstance(line_result, Err): + cant_transform = line_result.err() + raise CannotTransform( + "StringTransformer failed while attempting to transform string." + ) from cant_transform + line = line_result.ok() + yield line + + +@dataclass +class CustomSplit: + """A custom (i.e. manual) string split. + + A single CustomSplit instance represents a single substring. + + Examples: + Consider the following string: + ``` + "Hi there friend." + " This is a custom" + f" string {split}." + ``` + + This string will correspond to the following three CustomSplit instances: + ``` + CustomSplit(False, 16) + CustomSplit(False, 17) + CustomSplit(True, 16) + ``` + """ + + has_prefix: bool + break_idx: int + + +@trait +class CustomSplitMapMixin: + """ + This mixin class is used to map merged strings to a sequence of + CustomSplits, which will then be used to re-split the strings iff none of + the resultant substrings go over the configured max line length. + """ + + _Key: ClassVar = Tuple[StringID, str] + _CUSTOM_SPLIT_MAP: ClassVar[Dict[_Key, Tuple[CustomSplit, ...]]] = defaultdict( + tuple + ) + + @staticmethod + def _get_key(string: str) -> "CustomSplitMapMixin._Key": + """ + Returns: + A unique identifier that is used internally to map @string to a + group of custom splits. + """ + return (id(string), string) + + def add_custom_splits( + self, string: str, custom_splits: Iterable[CustomSplit] + ) -> None: + """Custom Split Map Setter Method + + Side Effects: + Adds a mapping from @string to the custom splits @custom_splits. + """ + key = self._get_key(string) + self._CUSTOM_SPLIT_MAP[key] = tuple(custom_splits) + + def pop_custom_splits(self, string: str) -> List[CustomSplit]: + """Custom Split Map Getter Method + + Returns: + * A list of the custom splits that are mapped to @string, if any + exist. + OR + * [], otherwise. + + Side Effects: + Deletes the mapping between @string and its associated custom + splits (which are returned to the caller). + """ + key = self._get_key(string) + + custom_splits = self._CUSTOM_SPLIT_MAP[key] + del self._CUSTOM_SPLIT_MAP[key] + + return list(custom_splits) + + def has_custom_splits(self, string: str) -> bool: + """ + Returns: + True iff @string is associated with a set of custom splits. + """ + key = self._get_key(string) + return key in self._CUSTOM_SPLIT_MAP + + +class StringMerger(StringTransformer, CustomSplitMapMixin): + """StringTransformer that merges strings together. + + Requirements: + (A) The line contains adjacent strings such that ALL of the validation checks + listed in StringMerger._validate_msg(...)'s docstring pass. + OR + (B) The line contains a string which uses line continuation backslashes. + + Transformations: + Depending on which of the two requirements above where met, either: + + (A) The string group associated with the target string is merged. + OR + (B) All line-continuation backslashes are removed from the target string. + + Collaborations: + StringMerger provides custom split information to StringSplitter. + """ + + def do_match(self, line: Line) -> TMatchResult: + LL = line.leaves + + is_valid_index = is_valid_index_factory(LL) + + string_indices = [] + idx = 0 + while is_valid_index(idx): + leaf = LL[idx] + if ( + leaf.type == token.STRING + and is_valid_index(idx + 1) + and LL[idx + 1].type == token.STRING + ): + # Let's check if the string group contains an inline comment + # If we have a comment inline, we don't merge the strings + contains_comment = False + i = idx + while is_valid_index(i): + if LL[i].type != token.STRING: + break + if line.comments_after(LL[i]): + contains_comment = True + break + i += 1 + + if not is_part_of_annotation(leaf) and not contains_comment: + string_indices.append(idx) + + # Advance to the next non-STRING leaf. + idx += 2 + while is_valid_index(idx) and LL[idx].type == token.STRING: + idx += 1 + + elif leaf.type == token.STRING and "\\\n" in leaf.value: + string_indices.append(idx) + # Advance to the next non-STRING leaf. + idx += 1 + while is_valid_index(idx) and LL[idx].type == token.STRING: + idx += 1 + + else: + idx += 1 + + if string_indices: + return Ok(string_indices) + else: + return TErr("This line has no strings that need merging.") + + def do_transform( + self, line: Line, string_indices: List[int] + ) -> Iterator[TResult[Line]]: + new_line = line + + rblc_result = self._remove_backslash_line_continuation_chars( + new_line, string_indices + ) + if isinstance(rblc_result, Ok): + new_line = rblc_result.ok() + + msg_result = self._merge_string_group(new_line, string_indices) + if isinstance(msg_result, Ok): + new_line = msg_result.ok() + + if isinstance(rblc_result, Err) and isinstance(msg_result, Err): + msg_cant_transform = msg_result.err() + rblc_cant_transform = rblc_result.err() + cant_transform = CannotTransform( + "StringMerger failed to merge any strings in this line." + ) + + # Chain the errors together using `__cause__`. + msg_cant_transform.__cause__ = rblc_cant_transform + cant_transform.__cause__ = msg_cant_transform + + yield Err(cant_transform) + else: + yield Ok(new_line) + + @staticmethod + def _remove_backslash_line_continuation_chars( + line: Line, string_indices: List[int] + ) -> TResult[Line]: + """ + Merge strings that were split across multiple lines using + line-continuation backslashes. + + Returns: + Ok(new_line), if @line contains backslash line-continuation + characters. + OR + Err(CannotTransform), otherwise. + """ + LL = line.leaves + + indices_to_transform = [] + for string_idx in string_indices: + string_leaf = LL[string_idx] + if ( + string_leaf.type == token.STRING + and "\\\n" in string_leaf.value + and not has_triple_quotes(string_leaf.value) + ): + indices_to_transform.append(string_idx) + + if not indices_to_transform: + return TErr( + "Found no string leaves that contain backslash line continuation" + " characters." + ) + + new_line = line.clone() + new_line.comments = line.comments.copy() + append_leaves(new_line, line, LL) + + for string_idx in indices_to_transform: + new_string_leaf = new_line.leaves[string_idx] + new_string_leaf.value = new_string_leaf.value.replace("\\\n", "") + + return Ok(new_line) + + def _merge_string_group( + self, line: Line, string_indices: List[int] + ) -> TResult[Line]: + """ + Merges string groups (i.e. set of adjacent strings). + + Each index from `string_indices` designates one string group's first + leaf in `line.leaves`. + + Returns: + Ok(new_line), if ALL of the validation checks found in + _validate_msg(...) pass. + OR + Err(CannotTransform), otherwise. + """ + LL = line.leaves + + is_valid_index = is_valid_index_factory(LL) + + # A dict of {string_idx: tuple[num_of_strings, string_leaf]}. + merged_string_idx_dict: Dict[int, Tuple[int, Leaf]] = {} + for string_idx in string_indices: + vresult = self._validate_msg(line, string_idx) + if isinstance(vresult, Err): + continue + merged_string_idx_dict[string_idx] = self._merge_one_string_group( + LL, string_idx, is_valid_index + ) + + if not merged_string_idx_dict: + return TErr("No string group is merged") + + # Build the final line ('new_line') that this method will later return. + new_line = line.clone() + previous_merged_string_idx = -1 + previous_merged_num_of_strings = -1 + for i, leaf in enumerate(LL): + if i in merged_string_idx_dict: + previous_merged_string_idx = i + previous_merged_num_of_strings, string_leaf = merged_string_idx_dict[i] + new_line.append(string_leaf) + + if ( + previous_merged_string_idx + <= i + < previous_merged_string_idx + previous_merged_num_of_strings + ): + for comment_leaf in line.comments_after(LL[i]): + new_line.append(comment_leaf, preformatted=True) + continue + + append_leaves(new_line, line, [leaf]) + + return Ok(new_line) + + def _merge_one_string_group( + self, LL: List[Leaf], string_idx: int, is_valid_index: Callable[[int], bool] + ) -> Tuple[int, Leaf]: + """ + Merges one string group where the first string in the group is + `LL[string_idx]`. + + Returns: + A tuple of `(num_of_strings, leaf)` where `num_of_strings` is the + number of strings merged and `leaf` is the newly merged string + to be replaced in the new line. + """ + # If the string group is wrapped inside an Atom node, we must make sure + # to later replace that Atom with our new (merged) string leaf. + atom_node = LL[string_idx].parent + + # We will place BREAK_MARK in between every two substrings that we + # merge. We will then later go through our final result and use the + # various instances of BREAK_MARK we find to add the right values to + # the custom split map. + BREAK_MARK = "@@@@@ BLACK BREAKPOINT MARKER @@@@@" + + QUOTE = LL[string_idx].value[-1] + + def make_naked(string: str, string_prefix: str) -> str: + """Strip @string (i.e. make it a "naked" string) + + Pre-conditions: + * assert_is_leaf_string(@string) + + Returns: + A string that is identical to @string except that + @string_prefix has been stripped, the surrounding QUOTE + characters have been removed, and any remaining QUOTE + characters have been escaped. + """ + assert_is_leaf_string(string) + if "f" in string_prefix: + f_expressions = ( + string[span[0] + 1 : span[1] - 1] # +-1 to get rid of curly braces + for span in iter_fexpr_spans(string) + ) + debug_expressions_contain_visible_quotes = any( + re.search(r".*[\'\"].*(?= 0 + ), "Logic error while filling the custom string breakpoint cache." + + temp_string = temp_string[mark_idx + len(BREAK_MARK) :] + breakpoint_idx = mark_idx + (len(prefix) if has_prefix else 0) + 1 + custom_splits.append(CustomSplit(has_prefix, breakpoint_idx)) + + string_leaf = Leaf(token.STRING, S_leaf.value.replace(BREAK_MARK, "")) + + if atom_node is not None: + # If not all children of the atom node are merged (this can happen + # when there is a standalone comment in the middle) ... + if non_string_idx - string_idx < len(atom_node.children): + # We need to replace the old STRING leaves with the new string leaf. + first_child_idx = LL[string_idx].remove() + for idx in range(string_idx + 1, non_string_idx): + LL[idx].remove() + if first_child_idx is not None: + atom_node.insert_child(first_child_idx, string_leaf) + else: + # Else replace the atom node with the new string leaf. + replace_child(atom_node, string_leaf) + + self.add_custom_splits(string_leaf.value, custom_splits) + return num_of_strings, string_leaf + + @staticmethod + def _validate_msg(line: Line, string_idx: int) -> TResult[None]: + """Validate (M)erge (S)tring (G)roup + + Transform-time string validation logic for _merge_string_group(...). + + Returns: + * Ok(None), if ALL validation checks (listed below) pass. + OR + * Err(CannotTransform), if any of the following are true: + - The target string group does not contain ANY stand-alone comments. + - The target string is not in a string group (i.e. it has no + adjacent strings). + - The string group has more than one inline comment. + - The string group has an inline comment that appears to be a pragma. + - The set of all string prefixes in the string group is of + length greater than one and is not equal to {"", "f"}. + - The string group consists of raw strings. + - The string group is stringified type annotations. We don't want to + process stringified type annotations since pyright doesn't support + them spanning multiple string values. (NOTE: mypy, pytype, pyre do + support them, so we can change if pyright also gains support in the + future. See https://github.com/microsoft/pyright/issues/4359.) + """ + # We first check for "inner" stand-alone comments (i.e. stand-alone + # comments that have a string leaf before them AND after them). + for inc in [1, -1]: + i = string_idx + found_sa_comment = False + is_valid_index = is_valid_index_factory(line.leaves) + while is_valid_index(i) and line.leaves[i].type in [ + token.STRING, + STANDALONE_COMMENT, + ]: + if line.leaves[i].type == STANDALONE_COMMENT: + found_sa_comment = True + elif found_sa_comment: + return TErr( + "StringMerger does NOT merge string groups which contain " + "stand-alone comments." + ) + + i += inc + + num_of_inline_string_comments = 0 + set_of_prefixes = set() + num_of_strings = 0 + for leaf in line.leaves[string_idx:]: + if leaf.type != token.STRING: + # If the string group is trailed by a comma, we count the + # comments trailing the comma to be one of the string group's + # comments. + if leaf.type == token.COMMA and id(leaf) in line.comments: + num_of_inline_string_comments += 1 + break + + if has_triple_quotes(leaf.value): + return TErr("StringMerger does NOT merge multiline strings.") + + num_of_strings += 1 + prefix = get_string_prefix(leaf.value).lower() + if "r" in prefix: + return TErr("StringMerger does NOT merge raw strings.") + + set_of_prefixes.add(prefix) + + if id(leaf) in line.comments: + num_of_inline_string_comments += 1 + if contains_pragma_comment(line.comments[id(leaf)]): + return TErr("Cannot merge strings which have pragma comments.") + + if num_of_strings < 2: + return TErr( + f"Not enough strings to merge (num_of_strings={num_of_strings})." + ) + + if num_of_inline_string_comments > 1: + return TErr( + f"Too many inline string comments ({num_of_inline_string_comments})." + ) + + if len(set_of_prefixes) > 1 and set_of_prefixes != {"", "f"}: + return TErr(f"Too many different prefixes ({set_of_prefixes}).") + + return Ok(None) + + +class StringParenStripper(StringTransformer): + """StringTransformer that strips surrounding parentheses from strings. + + Requirements: + The line contains a string which is surrounded by parentheses and: + - The target string is NOT the only argument to a function call. + - The target string is NOT a "pointless" string. + - If the target string contains a PERCENT, the brackets are not + preceded or followed by an operator with higher precedence than + PERCENT. + + Transformations: + The parentheses mentioned in the 'Requirements' section are stripped. + + Collaborations: + StringParenStripper has its own inherent usefulness, but it is also + relied on to clean up the parentheses created by StringParenWrapper (in + the event that they are no longer needed). + """ + + def do_match(self, line: Line) -> TMatchResult: + LL = line.leaves + + is_valid_index = is_valid_index_factory(LL) + + string_indices = [] + + idx = -1 + while True: + idx += 1 + if idx >= len(LL): + break + leaf = LL[idx] + + # Should be a string... + if leaf.type != token.STRING: + continue + + # If this is a "pointless" string... + if ( + leaf.parent + and leaf.parent.parent + and leaf.parent.parent.type == syms.simple_stmt + ): + continue + + # Should be preceded by a non-empty LPAR... + if ( + not is_valid_index(idx - 1) + or LL[idx - 1].type != token.LPAR + or is_empty_lpar(LL[idx - 1]) + ): + continue + + # That LPAR should NOT be preceded by a function name or a closing + # bracket (which could be a function which returns a function or a + # list/dictionary that contains a function)... + if is_valid_index(idx - 2) and ( + LL[idx - 2].type == token.NAME or LL[idx - 2].type in CLOSING_BRACKETS + ): + continue + + string_idx = idx + + # Skip the string trailer, if one exists. + string_parser = StringParser() + next_idx = string_parser.parse(LL, string_idx) + + # if the leaves in the parsed string include a PERCENT, we need to + # make sure the initial LPAR is NOT preceded by an operator with + # higher or equal precedence to PERCENT + if is_valid_index(idx - 2): + # mypy can't quite follow unless we name this + before_lpar = LL[idx - 2] + if token.PERCENT in {leaf.type for leaf in LL[idx - 1 : next_idx]} and ( + ( + before_lpar.type + in { + token.STAR, + token.AT, + token.SLASH, + token.DOUBLESLASH, + token.PERCENT, + token.TILDE, + token.DOUBLESTAR, + token.AWAIT, + token.LSQB, + token.LPAR, + } + ) + or ( + # only unary PLUS/MINUS + before_lpar.parent + and before_lpar.parent.type == syms.factor + and (before_lpar.type in {token.PLUS, token.MINUS}) + ) + ): + continue + + # Should be followed by a non-empty RPAR... + if ( + is_valid_index(next_idx) + and LL[next_idx].type == token.RPAR + and not is_empty_rpar(LL[next_idx]) + ): + # That RPAR should NOT be followed by anything with higher + # precedence than PERCENT + if is_valid_index(next_idx + 1) and LL[next_idx + 1].type in { + token.DOUBLESTAR, + token.LSQB, + token.LPAR, + token.DOT, + }: + continue + + string_indices.append(string_idx) + idx = string_idx + while idx < len(LL) - 1 and LL[idx + 1].type == token.STRING: + idx += 1 + + if string_indices: + return Ok(string_indices) + return TErr("This line has no strings wrapped in parens.") + + def do_transform( + self, line: Line, string_indices: List[int] + ) -> Iterator[TResult[Line]]: + LL = line.leaves + + string_and_rpar_indices: List[int] = [] + for string_idx in string_indices: + string_parser = StringParser() + rpar_idx = string_parser.parse(LL, string_idx) + + should_transform = True + for leaf in (LL[string_idx - 1], LL[rpar_idx]): + if line.comments_after(leaf): + # Should not strip parentheses which have comments attached + # to them. + should_transform = False + break + if should_transform: + string_and_rpar_indices.extend((string_idx, rpar_idx)) + + if string_and_rpar_indices: + yield Ok(self._transform_to_new_line(line, string_and_rpar_indices)) + else: + yield Err( + CannotTransform("All string groups have comments attached to them.") + ) + + def _transform_to_new_line( + self, line: Line, string_and_rpar_indices: List[int] + ) -> Line: + LL = line.leaves + + new_line = line.clone() + new_line.comments = line.comments.copy() + + previous_idx = -1 + # We need to sort the indices, since string_idx and its matching + # rpar_idx may not come in order, e.g. in + # `("outer" % ("inner".join(items)))`, the "inner" string's + # string_idx is smaller than "outer" string's rpar_idx. + for idx in sorted(string_and_rpar_indices): + leaf = LL[idx] + lpar_or_rpar_idx = idx - 1 if leaf.type == token.STRING else idx + append_leaves(new_line, line, LL[previous_idx + 1 : lpar_or_rpar_idx]) + if leaf.type == token.STRING: + string_leaf = Leaf(token.STRING, LL[idx].value) + LL[lpar_or_rpar_idx].remove() # Remove lpar. + replace_child(LL[idx], string_leaf) + new_line.append(string_leaf) + # replace comments + old_comments = new_line.comments.pop(id(LL[idx]), []) + new_line.comments.setdefault(id(string_leaf), []).extend(old_comments) + else: + LL[lpar_or_rpar_idx].remove() # This is a rpar. + + previous_idx = idx + + # Append the leaves after the last idx: + append_leaves(new_line, line, LL[idx + 1 :]) + + return new_line + + +class BaseStringSplitter(StringTransformer): + """ + Abstract class for StringTransformers which transform a Line's strings by splitting + them or placing them on their own lines where necessary to avoid going over + the configured line length. + + Requirements: + * The target string value is responsible for the line going over the + line length limit. It follows that after all of black's other line + split methods have been exhausted, this line (or one of the resulting + lines after all line splits are performed) would still be over the + line_length limit unless we split this string. + AND + + * The target string is NOT a "pointless" string (i.e. a string that has + no parent or siblings). + AND + + * The target string is not followed by an inline comment that appears + to be a pragma. + AND + + * The target string is not a multiline (i.e. triple-quote) string. + """ + + STRING_OPERATORS: Final = [ + token.EQEQUAL, + token.GREATER, + token.GREATEREQUAL, + token.LESS, + token.LESSEQUAL, + token.NOTEQUAL, + token.PERCENT, + token.PLUS, + token.STAR, + ] + + @abstractmethod + def do_splitter_match(self, line: Line) -> TMatchResult: + """ + BaseStringSplitter asks its clients to override this method instead of + `StringTransformer.do_match(...)`. + + Follows the same protocol as `StringTransformer.do_match(...)`. + + Refer to `help(StringTransformer.do_match)` for more information. + """ + + def do_match(self, line: Line) -> TMatchResult: + match_result = self.do_splitter_match(line) + if isinstance(match_result, Err): + return match_result + + string_indices = match_result.ok() + assert len(string_indices) == 1, ( + f"{self.__class__.__name__} should only find one match at a time, found" + f" {len(string_indices)}" + ) + string_idx = string_indices[0] + vresult = self._validate(line, string_idx) + if isinstance(vresult, Err): + return vresult + + return match_result + + def _validate(self, line: Line, string_idx: int) -> TResult[None]: + """ + Checks that @line meets all of the requirements listed in this classes' + docstring. Refer to `help(BaseStringSplitter)` for a detailed + description of those requirements. + + Returns: + * Ok(None), if ALL of the requirements are met. + OR + * Err(CannotTransform), if ANY of the requirements are NOT met. + """ + LL = line.leaves + + string_leaf = LL[string_idx] + + max_string_length = self._get_max_string_length(line, string_idx) + if len(string_leaf.value) <= max_string_length: + return TErr( + "The string itself is not what is causing this line to be too long." + ) + + if not string_leaf.parent or [L.type for L in string_leaf.parent.children] == [ + token.STRING, + token.NEWLINE, + ]: + return TErr( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + + if id(line.leaves[string_idx]) in line.comments and contains_pragma_comment( + line.comments[id(line.leaves[string_idx])] + ): + return TErr( + "Line appears to end with an inline pragma comment. Splitting the line" + " could modify the pragma's behavior." + ) + + if has_triple_quotes(string_leaf.value): + return TErr("We cannot split multiline strings.") + + return Ok(None) + + def _get_max_string_length(self, line: Line, string_idx: int) -> int: + """ + Calculates the max string length used when attempting to determine + whether or not the target string is responsible for causing the line to + go over the line length limit. + + WARNING: This method is tightly coupled to both StringSplitter and + (especially) StringParenWrapper. There is probably a better way to + accomplish what is being done here. + + Returns: + max_string_length: such that `line.leaves[string_idx].value > + max_string_length` implies that the target string IS responsible + for causing this line to exceed the line length limit. + """ + LL = line.leaves + + is_valid_index = is_valid_index_factory(LL) + + # We use the shorthand "WMA4" in comments to abbreviate "We must + # account for". When giving examples, we use STRING to mean some/any + # valid string. + # + # Finally, we use the following convenience variables: + # + # P: The leaf that is before the target string leaf. + # N: The leaf that is after the target string leaf. + # NN: The leaf that is after N. + + # WMA4 the whitespace at the beginning of the line. + offset = line.depth * 4 + + if is_valid_index(string_idx - 1): + p_idx = string_idx - 1 + if ( + LL[string_idx - 1].type == token.LPAR + and LL[string_idx - 1].value == "" + and string_idx >= 2 + ): + # If the previous leaf is an empty LPAR placeholder, we should skip it. + p_idx -= 1 + + P = LL[p_idx] + if P.type in self.STRING_OPERATORS: + # WMA4 a space and a string operator (e.g. `+ STRING` or `== STRING`). + offset += len(str(P)) + 1 + + if P.type == token.COMMA: + # WMA4 a space, a comma, and a closing bracket [e.g. `), STRING`]. + offset += 3 + + if P.type in [token.COLON, token.EQUAL, token.PLUSEQUAL, token.NAME]: + # This conditional branch is meant to handle dictionary keys, + # variable assignments, 'return STRING' statement lines, and + # 'else STRING' ternary expression lines. + + # WMA4 a single space. + offset += 1 + + # WMA4 the lengths of any leaves that came before that space, + # but after any closing bracket before that space. + for leaf in reversed(LL[: p_idx + 1]): + offset += len(str(leaf)) + if leaf.type in CLOSING_BRACKETS: + break + + if is_valid_index(string_idx + 1): + N = LL[string_idx + 1] + if N.type == token.RPAR and N.value == "" and len(LL) > string_idx + 2: + # If the next leaf is an empty RPAR placeholder, we should skip it. + N = LL[string_idx + 2] + + if N.type == token.COMMA: + # WMA4 a single comma at the end of the string (e.g `STRING,`). + offset += 1 + + if is_valid_index(string_idx + 2): + NN = LL[string_idx + 2] + + if N.type == token.DOT and NN.type == token.NAME: + # This conditional branch is meant to handle method calls invoked + # off of a string literal up to and including the LPAR character. + + # WMA4 the '.' character. + offset += 1 + + if ( + is_valid_index(string_idx + 3) + and LL[string_idx + 3].type == token.LPAR + ): + # WMA4 the left parenthesis character. + offset += 1 + + # WMA4 the length of the method's name. + offset += len(NN.value) + + has_comments = False + for comment_leaf in line.comments_after(LL[string_idx]): + if not has_comments: + has_comments = True + # WMA4 two spaces before the '#' character. + offset += 2 + + # WMA4 the length of the inline comment. + offset += len(comment_leaf.value) + + max_string_length = count_chars_in_width(str(line), self.line_length - offset) + return max_string_length + + @staticmethod + def _prefer_paren_wrap_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the "prefer paren wrap" statement + requirements listed in the 'Requirements' section of the StringParenWrapper + class's docstring. + OR + None, otherwise. + """ + # The line must start with a string. + if LL[0].type != token.STRING: + return None + + matching_nodes = [ + syms.listmaker, + syms.dictsetmaker, + syms.testlist_gexp, + ] + # If the string is an immediate child of a list/set/tuple literal... + if ( + parent_type(LL[0]) in matching_nodes + or parent_type(LL[0].parent) in matching_nodes + ): + # And the string is surrounded by commas (or is the first/last child)... + prev_sibling = LL[0].prev_sibling + next_sibling = LL[0].next_sibling + if ( + not prev_sibling + and not next_sibling + and parent_type(LL[0]) == syms.atom + ): + # If it's an atom string, we need to check the parent atom's siblings. + parent = LL[0].parent + assert parent is not None # For type checkers. + prev_sibling = parent.prev_sibling + next_sibling = parent.next_sibling + if (not prev_sibling or prev_sibling.type == token.COMMA) and ( + not next_sibling or next_sibling.type == token.COMMA + ): + return 0 + + return None + + +def iter_fexpr_spans(s: str) -> Iterator[Tuple[int, int]]: + """ + Yields spans corresponding to expressions in a given f-string. + Spans are half-open ranges (left inclusive, right exclusive). + Assumes the input string is a valid f-string, but will not crash if the input + string is invalid. + """ + stack: List[int] = [] # our curly paren stack + i = 0 + while i < len(s): + if s[i] == "{": + # if we're in a string part of the f-string, ignore escaped curly braces + if not stack and i + 1 < len(s) and s[i + 1] == "{": + i += 2 + continue + stack.append(i) + i += 1 + continue + + if s[i] == "}": + if not stack: + i += 1 + continue + j = stack.pop() + # we've made it back out of the expression! yield the span + if not stack: + yield (j, i + 1) + i += 1 + continue + + # if we're in an expression part of the f-string, fast forward through strings + # note that backslashes are not legal in the expression portion of f-strings + if stack: + delim = None + if s[i : i + 3] in ("'''", '"""'): + delim = s[i : i + 3] + elif s[i] in ("'", '"'): + delim = s[i] + if delim: + i += len(delim) + while i < len(s) and s[i : i + len(delim)] != delim: + i += 1 + i += len(delim) + continue + i += 1 + + +def fstring_contains_expr(s: str) -> bool: + return any(iter_fexpr_spans(s)) + + +def _toggle_fexpr_quotes(fstring: str, old_quote: str) -> str: + """ + Toggles quotes used in f-string expressions that are `old_quote`. + + f-string expressions can't contain backslashes, so we need to toggle the + quotes if the f-string itself will end up using the same quote. We can + simply toggle without escaping because, quotes can't be reused in f-string + expressions. They will fail to parse. + + NOTE: If PEP 701 is accepted, above statement will no longer be true. + Though if quotes can be reused, we can simply reuse them without updates or + escaping, once Black figures out how to parse the new grammar. + """ + new_quote = "'" if old_quote == '"' else '"' + parts = [] + previous_index = 0 + for start, end in iter_fexpr_spans(fstring): + parts.append(fstring[previous_index:start]) + parts.append(fstring[start:end].replace(old_quote, new_quote)) + previous_index = end + parts.append(fstring[previous_index:]) + return "".join(parts) + + +class StringSplitter(BaseStringSplitter, CustomSplitMapMixin): + """ + StringTransformer that splits "atom" strings (i.e. strings which exist on + lines by themselves). + + Requirements: + * The line consists ONLY of a single string (possibly prefixed by a + string operator [e.g. '+' or '==']), MAYBE a string trailer, and MAYBE + a trailing comma. + AND + * All of the requirements listed in BaseStringSplitter's docstring. + + Transformations: + The string mentioned in the 'Requirements' section is split into as + many substrings as necessary to adhere to the configured line length. + + In the final set of substrings, no substring should be smaller than + MIN_SUBSTR_SIZE characters. + + The string will ONLY be split on spaces (i.e. each new substring should + start with a space). Note that the string will NOT be split on a space + which is escaped with a backslash. + + If the string is an f-string, it will NOT be split in the middle of an + f-expression (e.g. in f"FooBar: {foo() if x else bar()}", {foo() if x + else bar()} is an f-expression). + + If the string that is being split has an associated set of custom split + records and those custom splits will NOT result in any line going over + the configured line length, those custom splits are used. Otherwise the + string is split as late as possible (from left-to-right) while still + adhering to the transformation rules listed above. + + Collaborations: + StringSplitter relies on StringMerger to construct the appropriate + CustomSplit objects and add them to the custom split map. + """ + + MIN_SUBSTR_SIZE: Final = 6 + + def do_splitter_match(self, line: Line) -> TMatchResult: + LL = line.leaves + + if self._prefer_paren_wrap_match(LL) is not None: + return TErr("Line needs to be wrapped in parens first.") + + is_valid_index = is_valid_index_factory(LL) + + idx = 0 + + # The first two leaves MAY be the 'not in' keywords... + if ( + is_valid_index(idx) + and is_valid_index(idx + 1) + and [LL[idx].type, LL[idx + 1].type] == [token.NAME, token.NAME] + and str(LL[idx]) + str(LL[idx + 1]) == "not in" + ): + idx += 2 + # Else the first leaf MAY be a string operator symbol or the 'in' keyword... + elif is_valid_index(idx) and ( + LL[idx].type in self.STRING_OPERATORS + or LL[idx].type == token.NAME + and str(LL[idx]) == "in" + ): + idx += 1 + + # The next/first leaf MAY be an empty LPAR... + if is_valid_index(idx) and is_empty_lpar(LL[idx]): + idx += 1 + + # The next/first leaf MUST be a string... + if not is_valid_index(idx) or LL[idx].type != token.STRING: + return TErr("Line does not start with a string.") + + string_idx = idx + + # Skip the string trailer, if one exists. + string_parser = StringParser() + idx = string_parser.parse(LL, string_idx) + + # That string MAY be followed by an empty RPAR... + if is_valid_index(idx) and is_empty_rpar(LL[idx]): + idx += 1 + + # That string / empty RPAR leaf MAY be followed by a comma... + if is_valid_index(idx) and LL[idx].type == token.COMMA: + idx += 1 + + # But no more leaves are allowed... + if is_valid_index(idx): + return TErr("This line does not end with a string.") + + return Ok([string_idx]) + + def do_transform( + self, line: Line, string_indices: List[int] + ) -> Iterator[TResult[Line]]: + LL = line.leaves + assert len(string_indices) == 1, ( + f"{self.__class__.__name__} should only find one match at a time, found" + f" {len(string_indices)}" + ) + string_idx = string_indices[0] + + QUOTE = LL[string_idx].value[-1] + + is_valid_index = is_valid_index_factory(LL) + insert_str_child = insert_str_child_factory(LL[string_idx]) + + prefix = get_string_prefix(LL[string_idx].value).lower() + + # We MAY choose to drop the 'f' prefix from substrings that don't + # contain any f-expressions, but ONLY if the original f-string + # contains at least one f-expression. Otherwise, we will alter the AST + # of the program. + drop_pointless_f_prefix = ("f" in prefix) and fstring_contains_expr( + LL[string_idx].value + ) + + first_string_line = True + + string_op_leaves = self._get_string_operator_leaves(LL) + string_op_leaves_length = ( + sum(len(str(prefix_leaf)) for prefix_leaf in string_op_leaves) + 1 + if string_op_leaves + else 0 + ) + + def maybe_append_string_operators(new_line: Line) -> None: + """ + Side Effects: + If @line starts with a string operator and this is the first + line we are constructing, this function appends the string + operator to @new_line and replaces the old string operator leaf + in the node structure. Otherwise this function does nothing. + """ + maybe_prefix_leaves = string_op_leaves if first_string_line else [] + for i, prefix_leaf in enumerate(maybe_prefix_leaves): + replace_child(LL[i], prefix_leaf) + new_line.append(prefix_leaf) + + ends_with_comma = ( + is_valid_index(string_idx + 1) and LL[string_idx + 1].type == token.COMMA + ) + + def max_last_string_column() -> int: + """ + Returns: + The max allowed width of the string value used for the last + line we will construct. Note that this value means the width + rather than the number of characters (e.g., many East Asian + characters expand to two columns). + """ + result = self.line_length + result -= line.depth * 4 + result -= 1 if ends_with_comma else 0 + result -= string_op_leaves_length + return result + + # --- Calculate Max Break Width (for string value) + # We start with the line length limit + max_break_width = self.line_length + # The last index of a string of length N is N-1. + max_break_width -= 1 + # Leading whitespace is not present in the string value (e.g. Leaf.value). + max_break_width -= line.depth * 4 + if max_break_width < 0: + yield TErr( + f"Unable to split {LL[string_idx].value} at such high of a line depth:" + f" {line.depth}" + ) + return + + # Check if StringMerger registered any custom splits. + custom_splits = self.pop_custom_splits(LL[string_idx].value) + # We use them ONLY if none of them would produce lines that exceed the + # line limit. + use_custom_breakpoints = bool( + custom_splits + and all(csplit.break_idx <= max_break_width for csplit in custom_splits) + ) + + # Temporary storage for the remaining chunk of the string line that + # can't fit onto the line currently being constructed. + rest_value = LL[string_idx].value + + def more_splits_should_be_made() -> bool: + """ + Returns: + True iff `rest_value` (the remaining string value from the last + split), should be split again. + """ + if use_custom_breakpoints: + return len(custom_splits) > 1 + else: + return str_width(rest_value) > max_last_string_column() + + string_line_results: List[Ok[Line]] = [] + while more_splits_should_be_made(): + if use_custom_breakpoints: + # Custom User Split (manual) + csplit = custom_splits.pop(0) + break_idx = csplit.break_idx + else: + # Algorithmic Split (automatic) + max_bidx = ( + count_chars_in_width(rest_value, max_break_width) + - string_op_leaves_length + ) + maybe_break_idx = self._get_break_idx(rest_value, max_bidx) + if maybe_break_idx is None: + # If we are unable to algorithmically determine a good split + # and this string has custom splits registered to it, we + # fall back to using them--which means we have to start + # over from the beginning. + if custom_splits: + rest_value = LL[string_idx].value + string_line_results = [] + first_string_line = True + use_custom_breakpoints = True + continue + + # Otherwise, we stop splitting here. + break + + break_idx = maybe_break_idx + + # --- Construct `next_value` + next_value = rest_value[:break_idx] + QUOTE + + # HACK: The following 'if' statement is a hack to fix the custom + # breakpoint index in the case of either: (a) substrings that were + # f-strings but will have the 'f' prefix removed OR (b) substrings + # that were not f-strings but will now become f-strings because of + # redundant use of the 'f' prefix (i.e. none of the substrings + # contain f-expressions but one or more of them had the 'f' prefix + # anyway; in which case, we will prepend 'f' to _all_ substrings). + # + # There is probably a better way to accomplish what is being done + # here... + # + # If this substring is an f-string, we _could_ remove the 'f' + # prefix, and the current custom split did NOT originally use a + # prefix... + if ( + use_custom_breakpoints + and not csplit.has_prefix + and ( + # `next_value == prefix + QUOTE` happens when the custom + # split is an empty string. + next_value == prefix + QUOTE + or next_value != self._normalize_f_string(next_value, prefix) + ) + ): + # Then `csplit.break_idx` will be off by one after removing + # the 'f' prefix. + break_idx += 1 + next_value = rest_value[:break_idx] + QUOTE + + if drop_pointless_f_prefix: + next_value = self._normalize_f_string(next_value, prefix) + + # --- Construct `next_leaf` + next_leaf = Leaf(token.STRING, next_value) + insert_str_child(next_leaf) + self._maybe_normalize_string_quotes(next_leaf) + + # --- Construct `next_line` + next_line = line.clone() + maybe_append_string_operators(next_line) + next_line.append(next_leaf) + string_line_results.append(Ok(next_line)) + + rest_value = prefix + QUOTE + rest_value[break_idx:] + first_string_line = False + + yield from string_line_results + + if drop_pointless_f_prefix: + rest_value = self._normalize_f_string(rest_value, prefix) + + rest_leaf = Leaf(token.STRING, rest_value) + insert_str_child(rest_leaf) + + # NOTE: I could not find a test case that verifies that the following + # line is actually necessary, but it seems to be. Otherwise we risk + # not normalizing the last substring, right? + self._maybe_normalize_string_quotes(rest_leaf) + + last_line = line.clone() + maybe_append_string_operators(last_line) + + # If there are any leaves to the right of the target string... + if is_valid_index(string_idx + 1): + # We use `temp_value` here to determine how long the last line + # would be if we were to append all the leaves to the right of the + # target string to the last string line. + temp_value = rest_value + for leaf in LL[string_idx + 1 :]: + temp_value += str(leaf) + if leaf.type == token.LPAR: + break + + # Try to fit them all on the same line with the last substring... + if ( + str_width(temp_value) <= max_last_string_column() + or LL[string_idx + 1].type == token.COMMA + ): + last_line.append(rest_leaf) + append_leaves(last_line, line, LL[string_idx + 1 :]) + yield Ok(last_line) + # Otherwise, place the last substring on one line and everything + # else on a line below that... + else: + last_line.append(rest_leaf) + yield Ok(last_line) + + non_string_line = line.clone() + append_leaves(non_string_line, line, LL[string_idx + 1 :]) + yield Ok(non_string_line) + # Else the target string was the last leaf... + else: + last_line.append(rest_leaf) + last_line.comments = line.comments.copy() + yield Ok(last_line) + + def _iter_nameescape_slices(self, string: str) -> Iterator[Tuple[Index, Index]]: + """ + Yields: + All ranges of @string which, if @string were to be split there, + would result in the splitting of an \\N{...} expression (which is NOT + allowed). + """ + # True - the previous backslash was unescaped + # False - the previous backslash was escaped *or* there was no backslash + previous_was_unescaped_backslash = False + it = iter(enumerate(string)) + for idx, c in it: + if c == "\\": + previous_was_unescaped_backslash = not previous_was_unescaped_backslash + continue + if not previous_was_unescaped_backslash or c != "N": + previous_was_unescaped_backslash = False + continue + previous_was_unescaped_backslash = False + + begin = idx - 1 # the position of backslash before \N{...} + for idx, c in it: + if c == "}": + end = idx + break + else: + # malformed nameescape expression? + # should have been detected by AST parsing earlier... + raise RuntimeError(f"{self.__class__.__name__} LOGIC ERROR!") + yield begin, end + + def _iter_fexpr_slices(self, string: str) -> Iterator[Tuple[Index, Index]]: + """ + Yields: + All ranges of @string which, if @string were to be split there, + would result in the splitting of an f-expression (which is NOT + allowed). + """ + if "f" not in get_string_prefix(string).lower(): + return + yield from iter_fexpr_spans(string) + + def _get_illegal_split_indices(self, string: str) -> Set[Index]: + illegal_indices: Set[Index] = set() + iterators = [ + self._iter_fexpr_slices(string), + self._iter_nameescape_slices(string), + ] + for it in iterators: + for begin, end in it: + illegal_indices.update(range(begin, end + 1)) + return illegal_indices + + def _get_break_idx(self, string: str, max_break_idx: int) -> Optional[int]: + """ + This method contains the algorithm that StringSplitter uses to + determine which character to split each string at. + + Args: + @string: The substring that we are attempting to split. + @max_break_idx: The ideal break index. We will return this value if it + meets all the necessary conditions. In the likely event that it + doesn't we will try to find the closest index BELOW @max_break_idx + that does. If that fails, we will expand our search by also + considering all valid indices ABOVE @max_break_idx. + + Pre-Conditions: + * assert_is_leaf_string(@string) + * 0 <= @max_break_idx < len(@string) + + Returns: + break_idx, if an index is able to be found that meets all of the + conditions listed in the 'Transformations' section of this classes' + docstring. + OR + None, otherwise. + """ + is_valid_index = is_valid_index_factory(string) + + assert is_valid_index(max_break_idx) + assert_is_leaf_string(string) + + _illegal_split_indices = self._get_illegal_split_indices(string) + + def breaks_unsplittable_expression(i: Index) -> bool: + """ + Returns: + True iff returning @i would result in the splitting of an + unsplittable expression (which is NOT allowed). + """ + return i in _illegal_split_indices + + def passes_all_checks(i: Index) -> bool: + """ + Returns: + True iff ALL of the conditions listed in the 'Transformations' + section of this classes' docstring would be be met by returning @i. + """ + is_space = string[i] == " " + is_split_safe = is_valid_index(i - 1) and string[i - 1] in SPLIT_SAFE_CHARS + + is_not_escaped = True + j = i - 1 + while is_valid_index(j) and string[j] == "\\": + is_not_escaped = not is_not_escaped + j -= 1 + + is_big_enough = ( + len(string[i:]) >= self.MIN_SUBSTR_SIZE + and len(string[:i]) >= self.MIN_SUBSTR_SIZE + ) + return ( + (is_space or is_split_safe) + and is_not_escaped + and is_big_enough + and not breaks_unsplittable_expression(i) + ) + + # First, we check all indices BELOW @max_break_idx. + break_idx = max_break_idx + while is_valid_index(break_idx - 1) and not passes_all_checks(break_idx): + break_idx -= 1 + + if not passes_all_checks(break_idx): + # If that fails, we check all indices ABOVE @max_break_idx. + # + # If we are able to find a valid index here, the next line is going + # to be longer than the specified line length, but it's probably + # better than doing nothing at all. + break_idx = max_break_idx + 1 + while is_valid_index(break_idx + 1) and not passes_all_checks(break_idx): + break_idx += 1 + + if not is_valid_index(break_idx) or not passes_all_checks(break_idx): + return None + + return break_idx + + def _maybe_normalize_string_quotes(self, leaf: Leaf) -> None: + if self.normalize_strings: + leaf.value = normalize_string_quotes(leaf.value) + + def _normalize_f_string(self, string: str, prefix: str) -> str: + """ + Pre-Conditions: + * assert_is_leaf_string(@string) + + Returns: + * If @string is an f-string that contains no f-expressions, we + return a string identical to @string except that the 'f' prefix + has been stripped and all double braces (i.e. '{{' or '}}') have + been normalized (i.e. turned into '{' or '}'). + OR + * Otherwise, we return @string. + """ + assert_is_leaf_string(string) + + if "f" in prefix and not fstring_contains_expr(string): + new_prefix = prefix.replace("f", "") + + temp = string[len(prefix) :] + temp = re.sub(r"\{\{", "{", temp) + temp = re.sub(r"\}\}", "}", temp) + new_string = temp + + return f"{new_prefix}{new_string}" + else: + return string + + def _get_string_operator_leaves(self, leaves: Iterable[Leaf]) -> List[Leaf]: + LL = list(leaves) + + string_op_leaves = [] + i = 0 + while LL[i].type in self.STRING_OPERATORS + [token.NAME]: + prefix_leaf = Leaf(LL[i].type, str(LL[i]).strip()) + string_op_leaves.append(prefix_leaf) + i += 1 + return string_op_leaves + + +class StringParenWrapper(BaseStringSplitter, CustomSplitMapMixin): + """ + StringTransformer that wraps strings in parens and then splits at the LPAR. + + Requirements: + All of the requirements listed in BaseStringSplitter's docstring in + addition to the requirements listed below: + + * The line is a return/yield statement, which returns/yields a string. + OR + * The line is part of a ternary expression (e.g. `x = y if cond else + z`) such that the line starts with `else `, where is + some string. + OR + * The line is an assert statement, which ends with a string. + OR + * The line is an assignment statement (e.g. `x = ` or `x += + `) such that the variable is being assigned the value of some + string. + OR + * The line is a dictionary key assignment where some valid key is being + assigned the value of some string. + OR + * The line is an lambda expression and the value is a string. + OR + * The line starts with an "atom" string that prefers to be wrapped in + parens. It's preferred to be wrapped when it's is an immediate child of + a list/set/tuple literal, AND the string is surrounded by commas (or is + the first/last child). + + Transformations: + The chosen string is wrapped in parentheses and then split at the LPAR. + + We then have one line which ends with an LPAR and another line that + starts with the chosen string. The latter line is then split again at + the RPAR. This results in the RPAR (and possibly a trailing comma) + being placed on its own line. + + NOTE: If any leaves exist to the right of the chosen string (except + for a trailing comma, which would be placed after the RPAR), those + leaves are placed inside the parentheses. In effect, the chosen + string is not necessarily being "wrapped" by parentheses. We can, + however, count on the LPAR being placed directly before the chosen + string. + + In other words, StringParenWrapper creates "atom" strings. These + can then be split again by StringSplitter, if necessary. + + Collaborations: + In the event that a string line split by StringParenWrapper is + changed such that it no longer needs to be given its own line, + StringParenWrapper relies on StringParenStripper to clean up the + parentheses it created. + + For "atom" strings that prefers to be wrapped in parens, it requires + StringSplitter to hold the split until the string is wrapped in parens. + """ + + def do_splitter_match(self, line: Line) -> TMatchResult: + LL = line.leaves + + if line.leaves[-1].type in OPENING_BRACKETS: + return TErr( + "Cannot wrap parens around a line that ends in an opening bracket." + ) + + string_idx = ( + self._return_match(LL) + or self._else_match(LL) + or self._assert_match(LL) + or self._assign_match(LL) + or self._dict_or_lambda_match(LL) + or self._prefer_paren_wrap_match(LL) + ) + + if string_idx is not None: + string_value = line.leaves[string_idx].value + # If the string has neither spaces nor East Asian stops... + if not any( + char == " " or char in SPLIT_SAFE_CHARS for char in string_value + ): + # And will still violate the line length limit when split... + max_string_width = self.line_length - ((line.depth + 1) * 4) + if str_width(string_value) > max_string_width: + # And has no associated custom splits... + if not self.has_custom_splits(string_value): + # Then we should NOT put this string on its own line. + return TErr( + "We do not wrap long strings in parentheses when the" + " resultant line would still be over the specified line" + " length and can't be split further by StringSplitter." + ) + return Ok([string_idx]) + + return TErr("This line does not contain any non-atomic strings.") + + @staticmethod + def _return_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the return/yield statement + requirements listed in the 'Requirements' section of this classes' + docstring. + OR + None, otherwise. + """ + # If this line is apart of a return/yield statement and the first leaf + # contains either the "return" or "yield" keywords... + if parent_type(LL[0]) in [syms.return_stmt, syms.yield_expr] and LL[ + 0 + ].value in ["return", "yield"]: + is_valid_index = is_valid_index_factory(LL) + + idx = 2 if is_valid_index(1) and is_empty_par(LL[1]) else 1 + # The next visible leaf MUST contain a string... + if is_valid_index(idx) and LL[idx].type == token.STRING: + return idx + + return None + + @staticmethod + def _else_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the ternary expression + requirements listed in the 'Requirements' section of this classes' + docstring. + OR + None, otherwise. + """ + # If this line is apart of a ternary expression and the first leaf + # contains the "else" keyword... + if ( + parent_type(LL[0]) == syms.test + and LL[0].type == token.NAME + and LL[0].value == "else" + ): + is_valid_index = is_valid_index_factory(LL) + + idx = 2 if is_valid_index(1) and is_empty_par(LL[1]) else 1 + # The next visible leaf MUST contain a string... + if is_valid_index(idx) and LL[idx].type == token.STRING: + return idx + + return None + + @staticmethod + def _assert_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the assert statement + requirements listed in the 'Requirements' section of this classes' + docstring. + OR + None, otherwise. + """ + # If this line is apart of an assert statement and the first leaf + # contains the "assert" keyword... + if parent_type(LL[0]) == syms.assert_stmt and LL[0].value == "assert": + is_valid_index = is_valid_index_factory(LL) + + for i, leaf in enumerate(LL): + # We MUST find a comma... + if leaf.type == token.COMMA: + idx = i + 2 if is_empty_par(LL[i + 1]) else i + 1 + + # That comma MUST be followed by a string... + if is_valid_index(idx) and LL[idx].type == token.STRING: + string_idx = idx + + # Skip the string trailer, if one exists. + string_parser = StringParser() + idx = string_parser.parse(LL, string_idx) + + # But no more leaves are allowed... + if not is_valid_index(idx): + return string_idx + + return None + + @staticmethod + def _assign_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the assignment statement + requirements listed in the 'Requirements' section of this classes' + docstring. + OR + None, otherwise. + """ + # If this line is apart of an expression statement or is a function + # argument AND the first leaf contains a variable name... + if ( + parent_type(LL[0]) in [syms.expr_stmt, syms.argument, syms.power] + and LL[0].type == token.NAME + ): + is_valid_index = is_valid_index_factory(LL) + + for i, leaf in enumerate(LL): + # We MUST find either an '=' or '+=' symbol... + if leaf.type in [token.EQUAL, token.PLUSEQUAL]: + idx = i + 2 if is_empty_par(LL[i + 1]) else i + 1 + + # That symbol MUST be followed by a string... + if is_valid_index(idx) and LL[idx].type == token.STRING: + string_idx = idx + + # Skip the string trailer, if one exists. + string_parser = StringParser() + idx = string_parser.parse(LL, string_idx) + + # The next leaf MAY be a comma iff this line is apart + # of a function argument... + if ( + parent_type(LL[0]) == syms.argument + and is_valid_index(idx) + and LL[idx].type == token.COMMA + ): + idx += 1 + + # But no more leaves are allowed... + if not is_valid_index(idx): + return string_idx + + return None + + @staticmethod + def _dict_or_lambda_match(LL: List[Leaf]) -> Optional[int]: + """ + Returns: + string_idx such that @LL[string_idx] is equal to our target (i.e. + matched) string, if this line matches the dictionary key assignment + statement or lambda expression requirements listed in the + 'Requirements' section of this classes' docstring. + OR + None, otherwise. + """ + # If this line is a part of a dictionary key assignment or lambda expression... + parent_types = [parent_type(LL[0]), parent_type(LL[0].parent)] + if syms.dictsetmaker in parent_types or syms.lambdef in parent_types: + is_valid_index = is_valid_index_factory(LL) + + for i, leaf in enumerate(LL): + # We MUST find a colon, it can either be dict's or lambda's colon... + if leaf.type == token.COLON and i < len(LL) - 1: + idx = i + 2 if is_empty_par(LL[i + 1]) else i + 1 + + # That colon MUST be followed by a string... + if is_valid_index(idx) and LL[idx].type == token.STRING: + string_idx = idx + + # Skip the string trailer, if one exists. + string_parser = StringParser() + idx = string_parser.parse(LL, string_idx) + + # That string MAY be followed by a comma... + if is_valid_index(idx) and LL[idx].type == token.COMMA: + idx += 1 + + # But no more leaves are allowed... + if not is_valid_index(idx): + return string_idx + + return None + + def do_transform( + self, line: Line, string_indices: List[int] + ) -> Iterator[TResult[Line]]: + LL = line.leaves + assert len(string_indices) == 1, ( + f"{self.__class__.__name__} should only find one match at a time, found" + f" {len(string_indices)}" + ) + string_idx = string_indices[0] + + is_valid_index = is_valid_index_factory(LL) + insert_str_child = insert_str_child_factory(LL[string_idx]) + + comma_idx = -1 + ends_with_comma = False + if LL[comma_idx].type == token.COMMA: + ends_with_comma = True + + leaves_to_steal_comments_from = [LL[string_idx]] + if ends_with_comma: + leaves_to_steal_comments_from.append(LL[comma_idx]) + + # --- First Line + first_line = line.clone() + left_leaves = LL[:string_idx] + + # We have to remember to account for (possibly invisible) LPAR and RPAR + # leaves that already wrapped the target string. If these leaves do + # exist, we will replace them with our own LPAR and RPAR leaves. + old_parens_exist = False + if left_leaves and left_leaves[-1].type == token.LPAR: + old_parens_exist = True + leaves_to_steal_comments_from.append(left_leaves[-1]) + left_leaves.pop() + + append_leaves(first_line, line, left_leaves) + + lpar_leaf = Leaf(token.LPAR, "(") + if old_parens_exist: + replace_child(LL[string_idx - 1], lpar_leaf) + else: + insert_str_child(lpar_leaf) + first_line.append(lpar_leaf) + + # We throw inline comments that were originally to the right of the + # target string to the top line. They will now be shown to the right of + # the LPAR. + for leaf in leaves_to_steal_comments_from: + for comment_leaf in line.comments_after(leaf): + first_line.append(comment_leaf, preformatted=True) + + yield Ok(first_line) + + # --- Middle (String) Line + # We only need to yield one (possibly too long) string line, since the + # `StringSplitter` will break it down further if necessary. + string_value = LL[string_idx].value + string_line = Line( + mode=line.mode, + depth=line.depth + 1, + inside_brackets=True, + should_split_rhs=line.should_split_rhs, + magic_trailing_comma=line.magic_trailing_comma, + ) + string_leaf = Leaf(token.STRING, string_value) + insert_str_child(string_leaf) + string_line.append(string_leaf) + + old_rpar_leaf = None + if is_valid_index(string_idx + 1): + right_leaves = LL[string_idx + 1 :] + if ends_with_comma: + right_leaves.pop() + + if old_parens_exist: + assert right_leaves and right_leaves[-1].type == token.RPAR, ( + "Apparently, old parentheses do NOT exist?!" + f" (left_leaves={left_leaves}, right_leaves={right_leaves})" + ) + old_rpar_leaf = right_leaves.pop() + elif right_leaves and right_leaves[-1].type == token.RPAR: + # Special case for lambda expressions as dict's value, e.g.: + # my_dict = { + # "key": lambda x: f"formatted: {x}, + # } + # After wrapping the dict's value with parentheses, the string is + # followed by a RPAR but its opening bracket is lambda's, not + # the string's: + # "key": (lambda x: f"formatted: {x}), + opening_bracket = right_leaves[-1].opening_bracket + if opening_bracket is not None and opening_bracket in left_leaves: + index = left_leaves.index(opening_bracket) + if ( + index > 0 + and index < len(left_leaves) - 1 + and left_leaves[index - 1].type == token.COLON + and left_leaves[index + 1].value == "lambda" + ): + right_leaves.pop() + + append_leaves(string_line, line, right_leaves) + + yield Ok(string_line) + + # --- Last Line + last_line = line.clone() + last_line.bracket_tracker = first_line.bracket_tracker + + new_rpar_leaf = Leaf(token.RPAR, ")") + if old_rpar_leaf is not None: + replace_child(old_rpar_leaf, new_rpar_leaf) + else: + insert_str_child(new_rpar_leaf) + last_line.append(new_rpar_leaf) + + # If the target string ended with a comma, we place this comma to the + # right of the RPAR on the last line. + if ends_with_comma: + comma_leaf = Leaf(token.COMMA, ",") + replace_child(LL[comma_idx], comma_leaf) + last_line.append(comma_leaf) + + yield Ok(last_line) + + +class StringParser: + """ + A state machine that aids in parsing a string's "trailer", which can be + either non-existent, an old-style formatting sequence (e.g. `% varX` or `% + (varX, varY)`), or a method-call / attribute access (e.g. `.format(varX, + varY)`). + + NOTE: A new StringParser object MUST be instantiated for each string + trailer we need to parse. + + Examples: + We shall assume that `line` equals the `Line` object that corresponds + to the following line of python code: + ``` + x = "Some {}.".format("String") + some_other_string + ``` + + Furthermore, we will assume that `string_idx` is some index such that: + ``` + assert line.leaves[string_idx].value == "Some {}." + ``` + + The following code snippet then holds: + ``` + string_parser = StringParser() + idx = string_parser.parse(line.leaves, string_idx) + assert line.leaves[idx].type == token.PLUS + ``` + """ + + DEFAULT_TOKEN: Final = 20210605 + + # String Parser States + START: Final = 1 + DOT: Final = 2 + NAME: Final = 3 + PERCENT: Final = 4 + SINGLE_FMT_ARG: Final = 5 + LPAR: Final = 6 + RPAR: Final = 7 + DONE: Final = 8 + + # Lookup Table for Next State + _goto: Final[Dict[Tuple[ParserState, NodeType], ParserState]] = { + # A string trailer may start with '.' OR '%'. + (START, token.DOT): DOT, + (START, token.PERCENT): PERCENT, + (START, DEFAULT_TOKEN): DONE, + # A '.' MUST be followed by an attribute or method name. + (DOT, token.NAME): NAME, + # A method name MUST be followed by an '(', whereas an attribute name + # is the last symbol in the string trailer. + (NAME, token.LPAR): LPAR, + (NAME, DEFAULT_TOKEN): DONE, + # A '%' symbol can be followed by an '(' or a single argument (e.g. a + # string or variable name). + (PERCENT, token.LPAR): LPAR, + (PERCENT, DEFAULT_TOKEN): SINGLE_FMT_ARG, + # If a '%' symbol is followed by a single argument, that argument is + # the last leaf in the string trailer. + (SINGLE_FMT_ARG, DEFAULT_TOKEN): DONE, + # If present, a ')' symbol is the last symbol in a string trailer. + # (NOTE: LPARS and nested RPARS are not included in this lookup table, + # since they are treated as a special case by the parsing logic in this + # classes' implementation.) + (RPAR, DEFAULT_TOKEN): DONE, + } + + def __init__(self) -> None: + self._state = self.START + self._unmatched_lpars = 0 + + def parse(self, leaves: List[Leaf], string_idx: int) -> int: + """ + Pre-conditions: + * @leaves[@string_idx].type == token.STRING + + Returns: + The index directly after the last leaf which is apart of the string + trailer, if a "trailer" exists. + OR + @string_idx + 1, if no string "trailer" exists. + """ + assert leaves[string_idx].type == token.STRING + + idx = string_idx + 1 + while idx < len(leaves) and self._next_state(leaves[idx]): + idx += 1 + return idx + + def _next_state(self, leaf: Leaf) -> bool: + """ + Pre-conditions: + * On the first call to this function, @leaf MUST be the leaf that + was directly after the string leaf in question (e.g. if our target + string is `line.leaves[i]` then the first call to this method must + be `line.leaves[i + 1]`). + * On the next call to this function, the leaf parameter passed in + MUST be the leaf directly following @leaf. + + Returns: + True iff @leaf is apart of the string's trailer. + """ + # We ignore empty LPAR or RPAR leaves. + if is_empty_par(leaf): + return True + + next_token = leaf.type + if next_token == token.LPAR: + self._unmatched_lpars += 1 + + current_state = self._state + + # The LPAR parser state is a special case. We will return True until we + # find the matching RPAR token. + if current_state == self.LPAR: + if next_token == token.RPAR: + self._unmatched_lpars -= 1 + if self._unmatched_lpars == 0: + self._state = self.RPAR + # Otherwise, we use a lookup table to determine the next state. + else: + # If the lookup table matches the current state to the next + # token, we use the lookup table. + if (current_state, next_token) in self._goto: + self._state = self._goto[current_state, next_token] + else: + # Otherwise, we check if a the current state was assigned a + # default. + if (current_state, self.DEFAULT_TOKEN) in self._goto: + self._state = self._goto[current_state, self.DEFAULT_TOKEN] + # If no default has been assigned, then this parser has a logic + # error. + else: + raise RuntimeError(f"{self.__class__.__name__} LOGIC ERROR!") + + if self._state == self.DONE: + return False + + return True + + +def insert_str_child_factory(string_leaf: Leaf) -> Callable[[LN], None]: + """ + Factory for a convenience function that is used to orphan @string_leaf + and then insert multiple new leaves into the same part of the node + structure that @string_leaf had originally occupied. + + Examples: + Let `string_leaf = Leaf(token.STRING, '"foo"')` and `N = + string_leaf.parent`. Assume the node `N` has the following + original structure: + + Node( + expr_stmt, [ + Leaf(NAME, 'x'), + Leaf(EQUAL, '='), + Leaf(STRING, '"foo"'), + ] + ) + + We then run the code snippet shown below. + ``` + insert_str_child = insert_str_child_factory(string_leaf) + + lpar = Leaf(token.LPAR, '(') + insert_str_child(lpar) + + bar = Leaf(token.STRING, '"bar"') + insert_str_child(bar) + + rpar = Leaf(token.RPAR, ')') + insert_str_child(rpar) + ``` + + After which point, it follows that `string_leaf.parent is None` and + the node `N` now has the following structure: + + Node( + expr_stmt, [ + Leaf(NAME, 'x'), + Leaf(EQUAL, '='), + Leaf(LPAR, '('), + Leaf(STRING, '"bar"'), + Leaf(RPAR, ')'), + ] + ) + """ + string_parent = string_leaf.parent + string_child_idx = string_leaf.remove() + + def insert_str_child(child: LN) -> None: + nonlocal string_child_idx + + assert string_parent is not None + assert string_child_idx is not None + + string_parent.insert_child(string_child_idx, child) + string_child_idx += 1 + + return insert_str_child + + +def is_valid_index_factory(seq: Sequence[Any]) -> Callable[[int], bool]: + """ + Examples: + ``` + my_list = [1, 2, 3] + + is_valid_index = is_valid_index_factory(my_list) + + assert is_valid_index(0) + assert is_valid_index(2) + + assert not is_valid_index(3) + assert not is_valid_index(-1) + ``` + """ + + def is_valid_index(idx: int) -> bool: + """ + Returns: + True iff @idx is positive AND seq[@idx] does NOT raise an + IndexError. + """ + return 0 <= idx < len(seq) + + return is_valid_index diff --git a/dbdpy-env/lib/python3.9/site-packages/blackd/__init__.py b/dbdpy-env/lib/python3.9/site-packages/blackd/__init__.py new file mode 100644 index 00000000..6b0f3d33 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blackd/__init__.py @@ -0,0 +1,233 @@ +import asyncio +import logging +from concurrent.futures import Executor, ProcessPoolExecutor +from datetime import datetime, timezone +from functools import partial +from multiprocessing import freeze_support +from typing import Set, Tuple + +try: + from aiohttp import web + + from .middlewares import cors +except ImportError as ie: + raise ImportError( + f"aiohttp dependency is not installed: {ie}. " + + "Please re-install black with the '[d]' extra install " + + "to obtain aiohttp_cors: `pip install black[d]`" + ) from None + +import click + +import black +from _black_version import version as __version__ +from black.concurrency import maybe_install_uvloop + +# This is used internally by tests to shut down the server prematurely +_stop_signal = asyncio.Event() + +# Request headers +PROTOCOL_VERSION_HEADER = "X-Protocol-Version" +LINE_LENGTH_HEADER = "X-Line-Length" +PYTHON_VARIANT_HEADER = "X-Python-Variant" +SKIP_SOURCE_FIRST_LINE = "X-Skip-Source-First-Line" +SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization" +SKIP_MAGIC_TRAILING_COMMA = "X-Skip-Magic-Trailing-Comma" +PREVIEW = "X-Preview" +FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe" +DIFF_HEADER = "X-Diff" + +BLACK_HEADERS = [ + PROTOCOL_VERSION_HEADER, + LINE_LENGTH_HEADER, + PYTHON_VARIANT_HEADER, + SKIP_SOURCE_FIRST_LINE, + SKIP_STRING_NORMALIZATION_HEADER, + SKIP_MAGIC_TRAILING_COMMA, + PREVIEW, + FAST_OR_SAFE_HEADER, + DIFF_HEADER, +] + +# Response headers +BLACK_VERSION_HEADER = "X-Black-Version" + + +class InvalidVariantHeader(Exception): + pass + + +@click.command(context_settings={"help_option_names": ["-h", "--help"]}) +@click.option( + "--bind-host", + type=str, + help="Address to bind the server to.", + default="localhost", + show_default=True, +) +@click.option( + "--bind-port", type=int, help="Port to listen on", default=45484, show_default=True +) +@click.version_option(version=black.__version__) +def main(bind_host: str, bind_port: int) -> None: + logging.basicConfig(level=logging.INFO) + app = make_app() + ver = black.__version__ + black.out(f"blackd version {ver} listening on {bind_host} port {bind_port}") + web.run_app(app, host=bind_host, port=bind_port, handle_signals=True, print=None) + + +def make_app() -> web.Application: + app = web.Application( + middlewares=[cors(allow_headers=(*BLACK_HEADERS, "Content-Type"))] + ) + executor = ProcessPoolExecutor() + app.add_routes([web.post("/", partial(handle, executor=executor))]) + return app + + +async def handle(request: web.Request, executor: Executor) -> web.Response: + headers = {BLACK_VERSION_HEADER: __version__} + try: + if request.headers.get(PROTOCOL_VERSION_HEADER, "1") != "1": + return web.Response( + status=501, text="This server only supports protocol version 1" + ) + try: + line_length = int( + request.headers.get(LINE_LENGTH_HEADER, black.DEFAULT_LINE_LENGTH) + ) + except ValueError: + return web.Response(status=400, text="Invalid line length header value") + + if PYTHON_VARIANT_HEADER in request.headers: + value = request.headers[PYTHON_VARIANT_HEADER] + try: + pyi, versions = parse_python_variant_header(value) + except InvalidVariantHeader as e: + return web.Response( + status=400, + text=f"Invalid value for {PYTHON_VARIANT_HEADER}: {e.args[0]}", + ) + else: + pyi = False + versions = set() + + skip_string_normalization = bool( + request.headers.get(SKIP_STRING_NORMALIZATION_HEADER, False) + ) + skip_magic_trailing_comma = bool( + request.headers.get(SKIP_MAGIC_TRAILING_COMMA, False) + ) + skip_source_first_line = bool( + request.headers.get(SKIP_SOURCE_FIRST_LINE, False) + ) + preview = bool(request.headers.get(PREVIEW, False)) + fast = False + if request.headers.get(FAST_OR_SAFE_HEADER, "safe") == "fast": + fast = True + mode = black.FileMode( + target_versions=versions, + is_pyi=pyi, + line_length=line_length, + skip_source_first_line=skip_source_first_line, + string_normalization=not skip_string_normalization, + magic_trailing_comma=not skip_magic_trailing_comma, + preview=preview, + ) + req_bytes = await request.content.read() + charset = request.charset if request.charset is not None else "utf8" + req_str = req_bytes.decode(charset) + then = datetime.now(timezone.utc) + + header = "" + if skip_source_first_line: + first_newline_position: int = req_str.find("\n") + 1 + header = req_str[:first_newline_position] + req_str = req_str[first_newline_position:] + + loop = asyncio.get_event_loop() + formatted_str = await loop.run_in_executor( + executor, partial(black.format_file_contents, req_str, fast=fast, mode=mode) + ) + + # Preserve CRLF line endings + nl = req_str.find("\n") + if nl > 0 and req_str[nl - 1] == "\r": + formatted_str = formatted_str.replace("\n", "\r\n") + # If, after swapping line endings, nothing changed, then say so + if formatted_str == req_str: + raise black.NothingChanged + + # Put the source first line back + req_str = header + req_str + formatted_str = header + formatted_str + + # Only output the diff in the HTTP response + only_diff = bool(request.headers.get(DIFF_HEADER, False)) + if only_diff: + now = datetime.now(timezone.utc) + src_name = f"In\t{then}" + dst_name = f"Out\t{now}" + loop = asyncio.get_event_loop() + formatted_str = await loop.run_in_executor( + executor, + partial(black.diff, req_str, formatted_str, src_name, dst_name), + ) + + return web.Response( + content_type=request.content_type, + charset=charset, + headers=headers, + text=formatted_str, + ) + except black.NothingChanged: + return web.Response(status=204, headers=headers) + except black.InvalidInput as e: + return web.Response(status=400, headers=headers, text=str(e)) + except Exception as e: + logging.exception("Exception during handling a request") + return web.Response(status=500, headers=headers, text=str(e)) + + +def parse_python_variant_header(value: str) -> Tuple[bool, Set[black.TargetVersion]]: + if value == "pyi": + return True, set() + else: + versions = set() + for version in value.split(","): + if version.startswith("py"): + version = version[len("py") :] + if "." in version: + major_str, *rest = version.split(".") + else: + major_str = version[0] + rest = [version[1:]] if len(version) > 1 else [] + try: + major = int(major_str) + if major not in (2, 3): + raise InvalidVariantHeader("major version must be 2 or 3") + if len(rest) > 0: + minor = int(rest[0]) + if major == 2: + raise InvalidVariantHeader("Python 2 is not supported") + else: + # Default to lowest supported minor version. + minor = 7 if major == 2 else 3 + version_str = f"PY{major}{minor}" + if major == 3 and not hasattr(black.TargetVersion, version_str): + raise InvalidVariantHeader(f"3.{minor} is not supported") + versions.add(black.TargetVersion[version_str]) + except (KeyError, ValueError): + raise InvalidVariantHeader("expected e.g. '3.7', 'py3.5'") from None + return False, versions + + +def patched_main() -> None: + maybe_install_uvloop() + freeze_support() + main() + + +if __name__ == "__main__": + patched_main() diff --git a/dbdpy-env/lib/python3.9/site-packages/blackd/__main__.py b/dbdpy-env/lib/python3.9/site-packages/blackd/__main__.py new file mode 100644 index 00000000..b5a4b137 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blackd/__main__.py @@ -0,0 +1,3 @@ +import blackd + +blackd.patched_main() diff --git a/dbdpy-env/lib/python3.9/site-packages/blackd/middlewares.py b/dbdpy-env/lib/python3.9/site-packages/blackd/middlewares.py new file mode 100644 index 00000000..370e0ae2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blackd/middlewares.py @@ -0,0 +1,45 @@ +from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, TypeVar + +from aiohttp.web_request import Request +from aiohttp.web_response import StreamResponse + +if TYPE_CHECKING: + F = TypeVar("F", bound=Callable[..., Any]) + middleware: Callable[[F], F] +else: + try: + from aiohttp.web_middlewares import middleware + except ImportError: + # @middleware is deprecated and its behaviour is the default since aiohttp 4.0 + # so if it doesn't exist anymore, define a no-op for forward compatibility. + middleware = lambda x: x # noqa: E731 + +Handler = Callable[[Request], Awaitable[StreamResponse]] +Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]] + + +def cors(allow_headers: Iterable[str]) -> Middleware: + @middleware + async def impl(request: Request, handler: Handler) -> StreamResponse: + is_options = request.method == "OPTIONS" + is_preflight = is_options and "Access-Control-Request-Method" in request.headers + if is_preflight: + resp = StreamResponse() + else: + resp = await handler(request) + + origin = request.headers.get("Origin") + if not origin: + return resp + + resp.headers["Access-Control-Allow-Origin"] = "*" + resp.headers["Access-Control-Expose-Headers"] = "*" + if is_options: + resp.headers["Access-Control-Allow-Headers"] = ", ".join(allow_headers) + resp.headers["Access-Control-Allow-Methods"] = ", ".join( + ("OPTIONS", "POST") + ) + + return resp + + return impl diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/Grammar.txt b/dbdpy-env/lib/python3.9/site-packages/blib2to3/Grammar.txt new file mode 100644 index 00000000..5db78723 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/Grammar.txt @@ -0,0 +1,256 @@ +# Grammar for 2to3. This grammar supports Python 2.x and 3.x. + +# NOTE WELL: You should also follow all the steps listed at +# https://devguide.python.org/grammar/ + +# Start symbols for the grammar: +# file_input is a module or sequence of commands read from an input file; +# single_input is a single interactive statement; +# eval_input is the input for the eval() and input() functions. +# NB: compound_stmt in single_input is followed by extra NEWLINE! +file_input: (NEWLINE | stmt)* ENDMARKER +single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +eval_input: testlist NEWLINE* ENDMARKER + +typevar: NAME [':' expr] +paramspec: '**' NAME +typevartuple: '*' NAME +typeparam: typevar | paramspec | typevartuple +typeparams: '[' typeparam (',' typeparam)* [','] ']' + +decorator: '@' namedexpr_test NEWLINE +decorators: decorator+ +decorated: decorators (classdef | funcdef | async_funcdef) +async_funcdef: ASYNC funcdef +funcdef: 'def' NAME [typeparams] parameters ['->' test] ':' suite +parameters: '(' [typedargslist] ')' + +# The following definition for typedarglist is equivalent to this set of rules: +# +# arguments = argument (',' argument)* +# argument = tfpdef ['=' test] +# kwargs = '**' tname [','] +# args = '*' [tname_star] +# kwonly_kwargs = (',' argument)* [',' [kwargs]] +# args_kwonly_kwargs = args kwonly_kwargs | kwargs +# poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] +# typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs +# typedarglist = arguments ',' '/' [',' [typedargslist_no_posonly]])|(typedargslist_no_posonly)" +# +# It needs to be fully expanded to allow our LL(1) parser to work on it. + +typedargslist: tfpdef ['=' test] (',' tfpdef ['=' test])* ',' '/' [ + ',' [((tfpdef ['=' test] ',')* ('*' [tname_star] (',' tname ['=' test])* + [',' ['**' tname [',']]] | '**' tname [',']) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])] + ] | ((tfpdef ['=' test] ',')* ('*' [tname_star] (',' tname ['=' test])* + [',' ['**' tname [',']]] | '**' tname [',']) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) + +tname: NAME [':' test] +tname_star: NAME [':' (test|star_expr)] +tfpdef: tname | '(' tfplist ')' +tfplist: tfpdef (',' tfpdef)* [','] + +# The following definition for varargslist is equivalent to this set of rules: +# +# arguments = argument (',' argument )* +# argument = vfpdef ['=' test] +# kwargs = '**' vname [','] +# args = '*' [vname] +# kwonly_kwargs = (',' argument )* [',' [kwargs]] +# args_kwonly_kwargs = args kwonly_kwargs | kwargs +# poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] +# vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs +# varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | (vararglist_no_posonly) +# +# It needs to be fully expanded to allow our LL(1) parser to work on it. + +varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ + ((vfpdef ['=' test] ',')* ('*' [vname] (',' vname ['=' test])* + [',' ['**' vname [',']]] | '**' vname [',']) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + ]] | ((vfpdef ['=' test] ',')* + ('*' [vname] (',' vname ['=' test])* [',' ['**' vname [',']]]| '**' vname [',']) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + +vname: NAME +vfpdef: vname | '(' vfplist ')' +vfplist: vfpdef (',' vfpdef)* [','] + +stmt: simple_stmt | compound_stmt +simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE +small_stmt: (type_stmt | expr_stmt | del_stmt | pass_stmt | flow_stmt | + import_stmt | global_stmt | assert_stmt) +expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +annassign: ':' test ['=' (yield_expr|testlist_star_expr)] +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '>>=' | '**=' | '//=') +# For normal and annotated assignments, additional restrictions enforced by the interpreter +del_stmt: 'del' exprlist +pass_stmt: 'pass' +flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt +break_stmt: 'break' +continue_stmt: 'continue' +return_stmt: 'return' [testlist_star_expr] +yield_stmt: yield_expr +raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] +import_stmt: import_name | import_from +import_name: 'import' dotted_as_names +import_from: ('from' ('.'* dotted_name | '.'+) + 'import' ('*' | '(' import_as_names ')' | import_as_names)) +import_as_name: NAME ['as' NAME] +dotted_as_name: dotted_name ['as' NAME] +import_as_names: import_as_name (',' import_as_name)* [','] +dotted_as_names: dotted_as_name (',' dotted_as_name)* +dotted_name: NAME ('.' NAME)* +global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* +assert_stmt: 'assert' test [',' test] +type_stmt: "type" NAME [typeparams] '=' test + +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt | match_stmt +async_stmt: ASYNC (funcdef | with_stmt | for_stmt) +if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite] +while_stmt: 'while' namedexpr_test ':' suite ['else' ':' suite] +for_stmt: 'for' exprlist 'in' testlist_star_expr ':' suite ['else' ':' suite] +try_stmt: ('try' ':' suite + ((except_clause ':' suite)+ + ['else' ':' suite] + ['finally' ':' suite] | + 'finally' ':' suite)) +with_stmt: 'with' asexpr_test (',' asexpr_test)* ':' suite + +# NB compile.c makes sure that the default except clause is last +except_clause: 'except' ['*'] [test [(',' | 'as') test]] +suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT + +# Backward compatibility cruft to support: +# [ x for x in lambda: True, lambda: False if x() ] +# even while also allowing: +# lambda x: 5 if x else 2 +# (But not a mix of the two) +testlist_safe: old_test [(',' old_test)+ [',']] +old_test: or_test | old_lambdef +old_lambdef: 'lambda' [varargslist] ':' old_test + +namedexpr_test: asexpr_test [':=' asexpr_test] + +# This is actually not a real rule, though since the parser is very +# limited in terms of the strategy about match/case rules, we are inserting +# a virtual case ( as ) as a valid expression. Unless a better +# approach is thought, the only side effect of this seem to be just allowing +# more stuff to be parser (which would fail on the ast). +asexpr_test: test ['as' test] + +test: or_test ['if' or_test 'else' test] | lambdef +or_test: and_test ('or' and_test)* +and_test: not_test ('and' not_test)* +not_test: 'not' not_test | comparison +comparison: expr (comp_op expr)* +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr +expr: xor_expr ('|' xor_expr)* +xor_expr: and_expr ('^' and_expr)* +and_expr: shift_expr ('&' shift_expr)* +shift_expr: arith_expr (('<<'|'>>') arith_expr)* +arith_expr: term (('+'|'-') term)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* +factor: ('+'|'-'|'~') factor | power +power: [AWAIT] atom trailer* ['**' factor] +atom: ('(' [yield_expr|testlist_gexp] ')' | + '[' [listmaker] ']' | + '{' [dictsetmaker] '}' | + '`' testlist1 '`' | + NAME | NUMBER | STRING+ | '.' '.' '.') +listmaker: (namedexpr_test|star_expr) ( old_comp_for | (',' (namedexpr_test|star_expr))* [','] ) +testlist_gexp: (namedexpr_test|star_expr) ( old_comp_for | (',' (namedexpr_test|star_expr))* [','] ) +lambdef: 'lambda' [varargslist] ':' test +trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME +subscriptlist: (subscript|star_expr) (',' (subscript|star_expr))* [','] +subscript: test [':=' test] | [test] ':' [test] [sliceop] +sliceop: ':' [test] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] +testlist: test (',' test)* [','] +dictsetmaker: ( ((test ':' asexpr_test | '**' expr) + (comp_for | (',' (test ':' asexpr_test | '**' expr))* [','])) | + ((test [':=' test] | star_expr) + (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) + +classdef: 'class' NAME [typeparams] ['(' [arglist] ')'] ':' suite + +arglist: argument (',' argument)* [','] + +# "test '=' test" is really "keyword '=' test", but we have no such token. +# These need to be in a single rule to avoid grammar that is ambiguous +# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr, +# we explicitly match '*' here, too, to give it proper precedence. +# Illegal combinations and orderings are blocked in ast.c: +# multiple (test comp_for) arguments are blocked; keyword unpackings +# that precede iterable unpackings are blocked; etc. +argument: ( test [comp_for] | + test ':=' test [comp_for] | + test 'as' test | + test '=' asexpr_test | + '**' test | + '*' test ) + +comp_iter: comp_for | comp_if +comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter] +comp_if: 'if' old_test [comp_iter] + +# As noted above, testlist_safe extends the syntax allowed in list +# comprehensions and generators. We can't use it indiscriminately in all +# derivations using a comp_for-like pattern because the testlist_safe derivation +# contains comma which clashes with trailing comma in arglist. +# +# This was an issue because the parser would not follow the correct derivation +# when parsing syntactically valid Python code. Since testlist_safe was created +# specifically to handle list comprehensions and generator expressions enclosed +# with parentheses, it's safe to only use it in those. That avoids the issue; we +# can parse code like set(x for x in [],). +# +# The syntax supported by this set of rules is not a valid Python 3 syntax, +# hence the prefix "old". +# +# See https://bugs.python.org/issue27494 +old_comp_iter: old_comp_for | old_comp_if +old_comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [old_comp_iter] +old_comp_if: 'if' old_test [old_comp_iter] + +testlist1: test (',' test)* + +# not used in grammar, but may appear in "node" passed from Parser to Compiler +encoding_decl: NAME + +yield_expr: 'yield' [yield_arg] +yield_arg: 'from' test | testlist_star_expr + + +# 3.10 match statement definition + +# PS: normally the grammar is much much more restricted, but +# at this moment for not trying to bother much with encoding the +# exact same DSL in a LL(1) parser, we will just accept an expression +# and let the ast.parse() step of the safe mode to reject invalid +# grammar. + +# The reason why it is more restricted is that, patterns are some +# sort of a DSL (more advanced than our LHS on assignments, but +# still in a very limited python subset). They are not really +# expressions, but who cares. If we can parse them, that is enough +# to reformat them. + +match_stmt: "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT + +# This is more permissive than the actual version. For example it +# accepts `match *something:`, even though single-item starred expressions +# are forbidden. +subject_expr: (namedexpr_test|star_expr) (',' (namedexpr_test|star_expr))* [','] + +# cases +case_block: "case" patterns [guard] ':' suite +guard: 'if' namedexpr_test +patterns: pattern (',' pattern)* [','] +pattern: (expr|star_expr) ['as' expr] diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/LICENSE b/dbdpy-env/lib/python3.9/site-packages/blib2to3/LICENSE new file mode 100644 index 00000000..ef8df069 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/LICENSE @@ -0,0 +1,254 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see https://opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All +Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/PatternGrammar.txt b/dbdpy-env/lib/python3.9/site-packages/blib2to3/PatternGrammar.txt new file mode 100644 index 00000000..36bf8148 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/PatternGrammar.txt @@ -0,0 +1,28 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# A grammar to describe tree matching patterns. +# Not shown here: +# - 'TOKEN' stands for any token (leaf node) +# - 'any' stands for any node (leaf or interior) +# With 'any' we can still specify the sub-structure. + +# The start symbol is 'Matcher'. + +Matcher: Alternatives ENDMARKER + +Alternatives: Alternative ('|' Alternative)* + +Alternative: (Unit | NegatedUnit)+ + +Unit: [NAME '='] ( STRING [Repeater] + | NAME [Details] [Repeater] + | '(' Alternatives ')' [Repeater] + | '[' Alternatives ']' + ) + +NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') + +Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' + +Details: '<' Alternatives '>' diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/README b/dbdpy-env/lib/python3.9/site-packages/blib2to3/README new file mode 100644 index 00000000..38b04158 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/README @@ -0,0 +1,24 @@ +A subset of lib2to3 taken from Python 3.7.0b2. Commit hash: +9c17e3a1987004b8bcfbe423953aad84493a7984 + +Reasons for forking: + +- consistent handling of f-strings for users of Python < 3.6.2 +- backport of BPO-33064 that fixes parsing files with trailing commas after \*args and + \*\*kwargs +- backport of GH-6143 that restores the ability to reformat legacy usage of `async` +- support all types of string literals +- better ability to debug (better reprs) +- INDENT and DEDENT don't hold whitespace and comment prefixes +- ability to Cythonize + +Change Log: + +- Changes default logger used by Driver +- Backported the following upstream parser changes: + - "bpo-42381: Allow walrus in set literals and set comprehensions (GH-23332)" + https://github.com/python/cpython/commit/cae60187cf7a7b26281d012e1952fafe4e2e97e9 + - "bpo-42316: Allow unparenthesized walrus operator in indexes (GH-23317)" + https://github.com/python/cpython/commit/b0aba1fcdc3da952698d99aec2334faa79a8b68c +- Tweaks to help mypyc compile faster code (including inlining type information, + "Final-ing", etc.) diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/__init__.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/__init__.py new file mode 100644 index 00000000..1bb8bf6d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/__init__.py @@ -0,0 +1 @@ +# empty diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/__init__.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/__init__.py new file mode 100644 index 00000000..af390484 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""The pgen2 package.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/conv.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/conv.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..10908ad3a96b8ab8b5cb1fd7394caeca2cc29599 GIT binary patch literal 50118 zcmeI*U2IfE6bJCLciXar0xk5R2DB@Xf+D4~1&a{a%4Z`&l`4HP<9@YW-0m*Bx4;6` zlE?#UlqNh>j0vd^ih!bNjW5CihQx^BQ~Y>Pq7QeemMUME z60S3ylcL4olf#+?_(5?7dUg=Di!jZ{^5cA{grpybIx;0oSkp@PP-@1Dep?DRgJ5k zTDG*&`E6zFdGhI2$0u|$ahK|pDJ)YhLB{_5dbk~WCLZ>3EbFv$JA+&Ck@;SZ$z{dd-M3g@qMdS)bN;> ztE^$I>KbeHt;ciKxgX_G`Cd6iexLPRC70}nXgdG3;-cA|spRZvBp`KdI%S4Cs-CP0 zr8%-LqDpQg&#sK^@`#S*xurbFRp$5d{wwXoGK>NN2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00jPb0)tzR>>G4bk8d=URCwLr))MXZ8Px9~-*rzR{l({Buk-QDX0M)iQTMac`5Lc_ z`Ukfj{eYeFZ-YCTr3>UGd6FX z@f=?)7@p^Yqj#($&v12=(LzSW1?iv8>L1d5J{Mcg&s8QbOZuFrOwOZ9pO21~&EWU-#Bu`TzSvlv`%&(tY+Zt+Zt(i9`9IBrmc)U)jj&vd&qSW4sGK$>3(Zi>P;z z9Z%G8wT`_U^YkrymZ&B#Zp@3Hw`0D=E^clLxE69P;+h?ENM3UGKeTOUz}h_rc}6mA zY31tVxZGi`lr@w{MmGA*Ft2;#r{WA-RdUzaYZ;F*hcST+-mziPBzeAttCX=sNB4RS zDz?M>efowjkO!#>CemhmJT|L#{;ZHcxhWE>O2uh_jP-v`Jo4(!Ta!x9N6KGb_4DMz z4_|3Gran3L_iH^Xdk(&G;M11)iOa2-g740pdC6GQQh0k?|F$hVe*EI~l{+7M|9_[] = { + {, }, + ... + }; + - followed by a state array, of the form: + static state states_[] = { + {, arcs__}, + ... + }; + + """ + try: + f = open(filename) + except OSError as err: + print(f"Can't open {filename}: {err}") + return False + # The code below essentially uses f's iterator-ness! + lineno = 0 + + # Expect the two #include lines + lineno, line = lineno + 1, next(f) + assert line == '#include "pgenheaders.h"\n', (lineno, line) + lineno, line = lineno + 1, next(f) + assert line == '#include "grammar.h"\n', (lineno, line) + + # Parse the state definitions + lineno, line = lineno + 1, next(f) + allarcs = {} + states = [] + while line.startswith("static arc "): + while line.startswith("static arc "): + mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", line) + assert mo, (lineno, line) + n, m, k = list(map(int, mo.groups())) + arcs = [] + for _ in range(k): + lineno, line = lineno + 1, next(f) + mo = re.match(r"\s+{(\d+), (\d+)},$", line) + assert mo, (lineno, line) + i, j = list(map(int, mo.groups())) + arcs.append((i, j)) + lineno, line = lineno + 1, next(f) + assert line == "};\n", (lineno, line) + allarcs[(n, m)] = arcs + lineno, line = lineno + 1, next(f) + mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) + assert mo, (lineno, line) + s, t = list(map(int, mo.groups())) + assert s == len(states), (lineno, line) + state = [] + for _ in range(t): + lineno, line = lineno + 1, next(f) + mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) + assert mo, (lineno, line) + k, n, m = list(map(int, mo.groups())) + arcs = allarcs[n, m] + assert k == len(arcs), (lineno, line) + state.append(arcs) + states.append(state) + lineno, line = lineno + 1, next(f) + assert line == "};\n", (lineno, line) + lineno, line = lineno + 1, next(f) + self.states = states + + # Parse the dfas + dfas = {} + mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) + assert mo, (lineno, line) + ndfas = int(mo.group(1)) + for i in range(ndfas): + lineno, line = lineno + 1, next(f) + mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', line) + assert mo, (lineno, line) + symbol = mo.group(2) + number, x, y, z = list(map(int, mo.group(1, 3, 4, 5))) + assert self.symbol2number[symbol] == number, (lineno, line) + assert self.number2symbol[number] == symbol, (lineno, line) + assert x == 0, (lineno, line) + state = states[z] + assert y == len(state), (lineno, line) + lineno, line = lineno + 1, next(f) + mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) + assert mo, (lineno, line) + first = {} + rawbitset = eval(mo.group(1)) + for i, c in enumerate(rawbitset): + byte = ord(c) + for j in range(8): + if byte & (1 << j): + first[i * 8 + j] = 1 + dfas[number] = (state, first) + lineno, line = lineno + 1, next(f) + assert line == "};\n", (lineno, line) + self.dfas = dfas + + # Parse the labels + labels = [] + lineno, line = lineno + 1, next(f) + mo = re.match(r"static label labels\[(\d+)\] = {$", line) + assert mo, (lineno, line) + nlabels = int(mo.group(1)) + for i in range(nlabels): + lineno, line = lineno + 1, next(f) + mo = re.match(r'\s+{(\d+), (0|"\w+")},$', line) + assert mo, (lineno, line) + x, y = mo.groups() + x = int(x) + if y == "0": + y = None + else: + y = eval(y) + labels.append((x, y)) + lineno, line = lineno + 1, next(f) + assert line == "};\n", (lineno, line) + self.labels = labels + + # Parse the grammar struct + lineno, line = lineno + 1, next(f) + assert line == "grammar _PyParser_Grammar = {\n", (lineno, line) + lineno, line = lineno + 1, next(f) + mo = re.match(r"\s+(\d+),$", line) + assert mo, (lineno, line) + ndfas = int(mo.group(1)) + assert ndfas == len(self.dfas) + lineno, line = lineno + 1, next(f) + assert line == "\tdfas,\n", (lineno, line) + lineno, line = lineno + 1, next(f) + mo = re.match(r"\s+{(\d+), labels},$", line) + assert mo, (lineno, line) + nlabels = int(mo.group(1)) + assert nlabels == len(self.labels), (lineno, line) + lineno, line = lineno + 1, next(f) + mo = re.match(r"\s+(\d+)$", line) + assert mo, (lineno, line) + start = int(mo.group(1)) + assert start in self.number2symbol, (lineno, line) + self.start = start + lineno, line = lineno + 1, next(f) + assert line == "};\n", (lineno, line) + try: + lineno, line = lineno + 1, next(f) + except StopIteration: + pass + else: + assert 0, (lineno, line) + + def finish_off(self): + """Create additional useful structures. (Internal).""" + self.keywords = {} # map from keyword strings to arc labels + self.tokens = {} # map from numeric token values to arc labels + for ilabel, (type, value) in enumerate(self.labels): + if type == token.NAME and value is not None: + self.keywords[value] = ilabel + elif value is None: + self.tokens[type] = ilabel diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..a7e867f266ec01ea14d92410050ab3e81d0f2260 GIT binary patch literal 50136 zcmeI*U2IfE6bJCLA1zBP&`J|)gmi7FphBr_`IO+6k3dCem8u(K9Cy3h_J-~5vU>|G zlvolmqKN{5P~!`UiHZ?vv_uo4ERYyK!-oNjiH0YGBocg4KwCWL-ns4WBJk7)lmC#} znKLu@%-r9$ybYYZ{`+tVk&C$axK8AH(Mz;l2DseIb&zM3YF!>|wTALP0{J27xQK_H zDl3#Sqnk|W*`+XF?P7cUl%AK^t@~EvrQY07skGT0PLB)~=A*~#scFs%j&t+*bUuD} ztJwKeXEc_Krg)?<-!z?XkzOxxZa%u{d~InnWyCx5`oerK>U_`Yc_-Fker_IAsyn{X zh)0wWZ%cGE&g|Vhuk4fIzh~b6kAHg|kNLUE z9@eg|30B{FJy(P0As&^VE2qfs=X|b`OU^?yo&Q>K(d_PYYIe*BOI@2uo6)YCB{h)@ zN7f>GfE&rvm$h9U)Umv`l&M^0zMs!O!%i&2C=h@E1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z;D0ADwB_i5ArI{ejHl8{zvpZ{(Vl>t27DB_<}0E<`2OoPzMk3Y*YhsweQG+d@w;eX zXv?wpi7L2#$mq7dPde{J?fmZ4_^?r_Tl@o|GCeFqR~7P3ig@A z@dfYbJYO8WX&-rqE92Zja#x;{{;8aPzwYzB*b08Ha{02P&w0w_KC1Nj>S*~K?(Zsg zTj#v8;^+a%(^5oM&bf69=Fh2bkF>Yf&3z;qnZF=BuR*DJ_R7+-QD4Fh#MO9N*GLbT6+-Hs3u^wKXi0~SjEagdlN-c|qVzERU z50Q)Grnq4$D)Ug^RwB1jhQx|WA}M17Z&>Z2{vLg>{+>>&XYl7lA5lfGJ>lkNl8dNs zu^ms=ajlN4IOgeLdzPr7AYN4v2kn?2v5SWrFV`Zj#awe^4#`i>dyE|48PIRRVS$z` zu-x*U@`P^ESIQbnGEK;g%GOr7{!2-g?PhS`oVlFGn8jUAZa%r2{}7p6<<+E2AUf9X zcT`cUG)i0P838gj~@tSmke%-eF_~z(_S?#fXM`A zOP8vTG*idquc~?%9@&5Jr4K(2CcgZwJ?s7P^yzi(=3vo{o`Igt+kg7}^_4qjzIUhj zXI?Je-SJm_^}{=!p0Vw6@bOQ#>^)ok&GCEA*ZB@zeQx!VJ3T+v^ViFlesJQ4t()#1 z|L8(rcFOth{~Y+PrSa`I4xVgmUcc>&kH&icLqi=qpZC7O0*p P48~4mF6}-X?A-S+PB%A# literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.py new file mode 100644 index 00000000..be398443 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/driver.py @@ -0,0 +1,316 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# Modifications: +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Parser driver. + +This provides a high-level interface to parse a file into a syntax tree. + +""" + +__author__ = "Guido van Rossum " + +__all__ = ["Driver", "load_grammar"] + +# Python imports +import io +import logging +import os +import pkgutil +import sys +from contextlib import contextmanager +from dataclasses import dataclass, field +from logging import Logger +from typing import IO, Any, Iterable, Iterator, List, Optional, Tuple, Union, cast + +from blib2to3.pgen2.grammar import Grammar +from blib2to3.pgen2.tokenize import GoodTokenInfo +from blib2to3.pytree import NL + +# Pgen imports +from . import grammar, parse, pgen, token, tokenize + +Path = Union[str, "os.PathLike[str]"] + + +@dataclass +class ReleaseRange: + start: int + end: Optional[int] = None + tokens: List[Any] = field(default_factory=list) + + def lock(self) -> None: + total_eaten = len(self.tokens) + self.end = self.start + total_eaten + + +class TokenProxy: + def __init__(self, generator: Any) -> None: + self._tokens = generator + self._counter = 0 + self._release_ranges: List[ReleaseRange] = [] + + @contextmanager + def release(self) -> Iterator["TokenProxy"]: + release_range = ReleaseRange(self._counter) + self._release_ranges.append(release_range) + try: + yield self + finally: + # Lock the last release range to the final position that + # has been eaten. + release_range.lock() + + def eat(self, point: int) -> Any: + eaten_tokens = self._release_ranges[-1].tokens + if point < len(eaten_tokens): + return eaten_tokens[point] + else: + while point >= len(eaten_tokens): + token = next(self._tokens) + eaten_tokens.append(token) + return token + + def __iter__(self) -> "TokenProxy": + return self + + def __next__(self) -> Any: + # If the current position is already compromised (looked up) + # return the eaten token, if not just go further on the given + # token producer. + for release_range in self._release_ranges: + assert release_range.end is not None + + start, end = release_range.start, release_range.end + if start <= self._counter < end: + token = release_range.tokens[self._counter - start] + break + else: + token = next(self._tokens) + self._counter += 1 + return token + + def can_advance(self, to: int) -> bool: + # Try to eat, fail if it can't. The eat operation is cached + # so there won't be any additional cost of eating here + try: + self.eat(to) + except StopIteration: + return False + else: + return True + + +class Driver: + def __init__(self, grammar: Grammar, logger: Optional[Logger] = None) -> None: + self.grammar = grammar + if logger is None: + logger = logging.getLogger(__name__) + self.logger = logger + + def parse_tokens(self, tokens: Iterable[GoodTokenInfo], debug: bool = False) -> NL: + """Parse a series of tokens and return the syntax tree.""" + # XXX Move the prefix computation into a wrapper around tokenize. + proxy = TokenProxy(tokens) + + p = parse.Parser(self.grammar) + p.setup(proxy=proxy) + + lineno = 1 + column = 0 + indent_columns: List[int] = [] + type = value = start = end = line_text = None + prefix = "" + + for quintuple in proxy: + type, value, start, end, line_text = quintuple + if start != (lineno, column): + assert (lineno, column) <= start, ((lineno, column), start) + s_lineno, s_column = start + if lineno < s_lineno: + prefix += "\n" * (s_lineno - lineno) + lineno = s_lineno + column = 0 + if column < s_column: + prefix += line_text[column:s_column] + column = s_column + if type in (tokenize.COMMENT, tokenize.NL): + prefix += value + lineno, column = end + if value.endswith("\n"): + lineno += 1 + column = 0 + continue + if type == token.OP: + type = grammar.opmap[value] + if debug: + assert type is not None + self.logger.debug( + "%s %r (prefix=%r)", token.tok_name[type], value, prefix + ) + if type == token.INDENT: + indent_columns.append(len(value)) + _prefix = prefix + value + prefix = "" + value = "" + elif type == token.DEDENT: + _indent_col = indent_columns.pop() + prefix, _prefix = self._partially_consume_prefix(prefix, _indent_col) + if p.addtoken(cast(int, type), value, (prefix, start)): + if debug: + self.logger.debug("Stop.") + break + prefix = "" + if type in {token.INDENT, token.DEDENT}: + prefix = _prefix + lineno, column = end + if value.endswith("\n"): + lineno += 1 + column = 0 + else: + # We never broke out -- EOF is too soon (how can this happen???) + assert start is not None + raise parse.ParseError("incomplete input", type, value, (prefix, start)) + assert p.rootnode is not None + return p.rootnode + + def parse_stream_raw(self, stream: IO[str], debug: bool = False) -> NL: + """Parse a stream and return the syntax tree.""" + tokens = tokenize.generate_tokens(stream.readline, grammar=self.grammar) + return self.parse_tokens(tokens, debug) + + def parse_stream(self, stream: IO[str], debug: bool = False) -> NL: + """Parse a stream and return the syntax tree.""" + return self.parse_stream_raw(stream, debug) + + def parse_file( + self, filename: Path, encoding: Optional[str] = None, debug: bool = False + ) -> NL: + """Parse a file and return the syntax tree.""" + with open(filename, encoding=encoding) as stream: + return self.parse_stream(stream, debug) + + def parse_string(self, text: str, debug: bool = False) -> NL: + """Parse a string and return the syntax tree.""" + tokens = tokenize.generate_tokens( + io.StringIO(text).readline, grammar=self.grammar + ) + return self.parse_tokens(tokens, debug) + + def _partially_consume_prefix(self, prefix: str, column: int) -> Tuple[str, str]: + lines: List[str] = [] + current_line = "" + current_column = 0 + wait_for_nl = False + for char in prefix: + current_line += char + if wait_for_nl: + if char == "\n": + if current_line.strip() and current_column < column: + res = "".join(lines) + return res, prefix[len(res) :] + + lines.append(current_line) + current_line = "" + current_column = 0 + wait_for_nl = False + elif char in " \t": + current_column += 1 + elif char == "\n": + # unexpected empty line + current_column = 0 + elif char == "\f": + current_column = 0 + else: + # indent is finished + wait_for_nl = True + return "".join(lines), current_line + + +def _generate_pickle_name(gt: Path, cache_dir: Optional[Path] = None) -> str: + head, tail = os.path.splitext(gt) + if tail == ".txt": + tail = "" + name = head + tail + ".".join(map(str, sys.version_info)) + ".pickle" + if cache_dir: + return os.path.join(cache_dir, os.path.basename(name)) + else: + return name + + +def load_grammar( + gt: str = "Grammar.txt", + gp: Optional[str] = None, + save: bool = True, + force: bool = False, + logger: Optional[Logger] = None, +) -> Grammar: + """Load the grammar (maybe from a pickle).""" + if logger is None: + logger = logging.getLogger(__name__) + gp = _generate_pickle_name(gt) if gp is None else gp + if force or not _newer(gp, gt): + g: grammar.Grammar = pgen.generate_grammar(gt) + if save: + try: + g.dump(gp) + except OSError: + # Ignore error, caching is not vital. + pass + else: + g = grammar.Grammar() + g.load(gp) + return g + + +def _newer(a: str, b: str) -> bool: + """Inquire whether file a was written since file b.""" + if not os.path.exists(a): + return False + if not os.path.exists(b): + return True + return os.path.getmtime(a) >= os.path.getmtime(b) + + +def load_packaged_grammar( + package: str, grammar_source: str, cache_dir: Optional[Path] = None +) -> grammar.Grammar: + """Normally, loads a pickled grammar by doing + pkgutil.get_data(package, pickled_grammar) + where *pickled_grammar* is computed from *grammar_source* by adding the + Python version and using a ``.pickle`` extension. + + However, if *grammar_source* is an extant file, load_grammar(grammar_source) + is called instead. This facilitates using a packaged grammar file when needed + but preserves load_grammar's automatic regeneration behavior when possible. + + """ + if os.path.isfile(grammar_source): + gp = _generate_pickle_name(grammar_source, cache_dir) if cache_dir else None + return load_grammar(grammar_source, gp=gp) + pickled_name = _generate_pickle_name(os.path.basename(grammar_source), cache_dir) + data = pkgutil.get_data(package, pickled_name) + assert data is not None + g = grammar.Grammar() + g.loads(data) + return g + + +def main(*args: str) -> bool: + """Main program, when run as a script: produce grammar pickle files. + + Calls load_grammar for each argument, a path to a grammar text file. + """ + if not args: + args = tuple(sys.argv[1:]) + logging.basicConfig(level=logging.INFO, stream=sys.stdout, format="%(message)s") + for gt in args: + load_grammar(gt, save=True, force=True) + return True + + +if __name__ == "__main__": + sys.exit(int(not main())) diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/grammar.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/grammar.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..923917798280e21dde79dcbbc83260eab4bb1871 GIT binary patch literal 50137 zcmeI*Uu@G=6bJCrc4H-OFm%9F%o;=pL`vNT42Gi#sZIL^k5$`=k>hAcHK9c66((nl}e>Efz z8^z40dP0#zD9Izm`R3_-tMqz_^YhU?=j%+Rli^smUSFK=b)Cs;15D;4ppR5luj zM^qx6yl=j0olf%SpQDV&ORPC=l?wXP{)vI&^HukobJlxGoS$#vNwX*KDc_Y+n_4z+ zT(`Ex`rXQz^W@d7jxXwD;x5%Hb6LhCLC*aBb#goYPCV@5SoZ1RR@RA+%zwzSyrXBt zqR8@e%2Qlreu&S%&`d1DC=h@E1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z;D0A@d(Y_;w;goIJC!PHT#jGshz@)0H0&hrO=l@x=licW`FduDOV8V=f6D@1B`m?ObIn=1N4_^>A_Tl@o|GCel(uq73Mf*(W z_)^KlJYO8WXCHZoYh`vH*=t6ne?G52r2Bj?wwm9oO1>=VbDk=>k1Bn>I$E`q`-i63 zjdNam@$?DF(^g7G&SkYL8kW{|1-rUxmpvB>HmnFNuU9IXO=LUi0dwwfESy#WzRp^k zj@K!r65XL#Ew|lCe>Cb(8h2*r$bq=zw{n$L?#|b9E7hj&g-c)V*p~B?mB!N?Josv_ zu>czZ0-Zx0Am! zc7Ol`AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tdFRm@${yr9Zx<4OS$z&d5-NCa@RU@6^}8CeJ0uYD}Jp-rf6t|Ms2r z2cA9tu=%U+?rrV+aZgR)VBh None: + self.symbol2number: Dict[str, int] = {} + self.number2symbol: Dict[int, str] = {} + self.states: List[DFA] = [] + self.dfas: Dict[int, DFAS] = {} + self.labels: List[Label] = [(0, "EMPTY")] + self.keywords: Dict[str, int] = {} + self.soft_keywords: Dict[str, int] = {} + self.tokens: Dict[int, int] = {} + self.symbol2label: Dict[str, int] = {} + self.version: Tuple[int, int] = (0, 0) + self.start = 256 + # Python 3.7+ parses async as a keyword, not an identifier + self.async_keywords = False + + def dump(self, filename: Path) -> None: + """Dump the grammar tables to a pickle file.""" + + # mypyc generates objects that don't have a __dict__, but they + # do have __getstate__ methods that will return an equivalent + # dictionary + if hasattr(self, "__dict__"): + d = self.__dict__ + else: + d = self.__getstate__() # type: ignore + + with tempfile.NamedTemporaryFile( + dir=os.path.dirname(filename), delete=False + ) as f: + pickle.dump(d, f, pickle.HIGHEST_PROTOCOL) + os.replace(f.name, filename) + + def _update(self, attrs: Dict[str, Any]) -> None: + for k, v in attrs.items(): + setattr(self, k, v) + + def load(self, filename: Path) -> None: + """Load the grammar tables from a pickle file.""" + with open(filename, "rb") as f: + d = pickle.load(f) + self._update(d) + + def loads(self, pkl: bytes) -> None: + """Load the grammar tables from a pickle bytes object.""" + self._update(pickle.loads(pkl)) + + def copy(self: _P) -> _P: + """ + Copy the grammar. + """ + new = self.__class__() + for dict_attr in ( + "symbol2number", + "number2symbol", + "dfas", + "keywords", + "soft_keywords", + "tokens", + "symbol2label", + ): + setattr(new, dict_attr, getattr(self, dict_attr).copy()) + new.labels = self.labels[:] + new.states = self.states[:] + new.start = self.start + new.version = self.version + new.async_keywords = self.async_keywords + return new + + def report(self) -> None: + """Dump the grammar tables to standard output, for debugging.""" + from pprint import pprint + + print("s2n") + pprint(self.symbol2number) + print("n2s") + pprint(self.number2symbol) + print("states") + pprint(self.states) + print("dfas") + pprint(self.dfas) + print("labels") + pprint(self.labels) + print("start", self.start) + + +# Map from operator to number (since tokenize doesn't do this) + +opmap_raw = """ +( LPAR +) RPAR +[ LSQB +] RSQB +: COLON +, COMMA +; SEMI ++ PLUS +- MINUS +* STAR +/ SLASH +| VBAR +& AMPER +< LESS +> GREATER += EQUAL +. DOT +% PERCENT +` BACKQUOTE +{ LBRACE +} RBRACE +@ AT +@= ATEQUAL +== EQEQUAL +!= NOTEQUAL +<> NOTEQUAL +<= LESSEQUAL +>= GREATEREQUAL +~ TILDE +^ CIRCUMFLEX +<< LEFTSHIFT +>> RIGHTSHIFT +** DOUBLESTAR ++= PLUSEQUAL +-= MINEQUAL +*= STAREQUAL +/= SLASHEQUAL +%= PERCENTEQUAL +&= AMPEREQUAL +|= VBAREQUAL +^= CIRCUMFLEXEQUAL +<<= LEFTSHIFTEQUAL +>>= RIGHTSHIFTEQUAL +**= DOUBLESTAREQUAL +// DOUBLESLASH +//= DOUBLESLASHEQUAL +-> RARROW +:= COLONEQUAL +""" + +opmap = {} +for line in opmap_raw.splitlines(): + if line: + op, name = line.split() + opmap[op] = getattr(token, name) diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..6695f7a4300afbc9557d5f205f77154815c2849b GIT binary patch literal 50138 zcmeI*U2IfE6bJCLAEm3bv`9mWXu7Egu_+6-P)kDaA`oemQfwb8F-~^7x9!Sycip`O zSE}>{QQ<+8YLFN4Noz2o)<|lUttN!{ARmcnKnw{+5ivqcG!P1&bMM@CcM*8%gUNrA z>CBm#duHzMw!BR^a^;U}Wkeq065u+6>p4Hsb{XI@hwBeKt5nCD&JKI1@P|s#u~sX~%`%Zov&-?1vhDZJS|mz zVJf*Q)sxKotT)Xkzgu=Ooac2!)3_t~+#=^X$JIHPJId{#?i;!-irsU$@2pfjtTNfY zNHVTcR{Ey-s&zWapMQ>09{0O*+$t3fTj9xp;`3DxI&@=2#B?voGGI5vcmRgosEJ4os`wehA@lHG(Q2**4!n=JQJ>KQDQT%Um9ieSUm%)wkzEO}*QDF4WS>(M$u61-Z%| zM7*n~-0s`2=UL*b<5Bs&a*O_s%68_Baf=eRteV|i~W_i~l_{e1p9C$S8pKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwx` z|CPY_)`P?2K6>4_gDPu+zV8}|h72!_1jx7?D4|Py_w_Pg&Fl#3c@GUfv4GbEJv1`D zb?iN&niG5vb0`>ao|pL=iLYP(ly9LPmo+(`I^piamxJwn_^#}K?sKMOGEaHYJ{26F z@lVe4rO_Mqk$0#Jcst2kb3*zTODFqBb)WCVR`YvR$%m3Y=c$srsM6htHZ?43UfS3l?e1=9deDqEFN-|1M5(@PD%(Z3m3cWle}166X>%u z3J=lH3MZbW<9Z#>jNVL&u>5Z#m=>_ z)W3VX`Oyn?JKmap{@B&_yAQwocW!GpZJU4c>pv_03jMn4!?!Dr-tPISo}csnrPId~ zpAXHRO*L(`*ABmUZco+yPw(v;{^pk>JB^L^&0V*9q^Y&< T_fua!^TyeWbq5CD*}3aq5YId} literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.py new file mode 100644 index 00000000..53c0b8ac --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/literals.py @@ -0,0 +1,66 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Safely evaluate Python string literals without using eval().""" + +import re +from typing import Dict, Match + +simple_escapes: Dict[str, str] = { + "a": "\a", + "b": "\b", + "f": "\f", + "n": "\n", + "r": "\r", + "t": "\t", + "v": "\v", + "'": "'", + '"': '"', + "\\": "\\", +} + + +def escape(m: Match[str]) -> str: + all, tail = m.group(0, 1) + assert all.startswith("\\") + esc = simple_escapes.get(tail) + if esc is not None: + return esc + if tail.startswith("x"): + hexes = tail[1:] + if len(hexes) < 2: + raise ValueError("invalid hex string escape ('\\%s')" % tail) + try: + i = int(hexes, 16) + except ValueError: + raise ValueError("invalid hex string escape ('\\%s')" % tail) from None + else: + try: + i = int(tail, 8) + except ValueError: + raise ValueError("invalid octal string escape ('\\%s')" % tail) from None + return chr(i) + + +def evalString(s: str) -> str: + assert s.startswith("'") or s.startswith('"'), repr(s[:1]) + q = s[0] + if s[:3] == q * 3: + q = q * 3 + assert s.endswith(q), repr(s[-len(q) :]) + assert len(s) >= 2 * len(q) + s = s[len(q) : -len(q)] + return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) + + +def test() -> None: + for i in range(256): + c = chr(i) + s = repr(c) + e = evalString(s) + if e != c: + print(i, c, s, e) + + +if __name__ == "__main__": + test() diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/parse.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/parse.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..bc1b4049ea488424c4102bab0dd2883341d22805 GIT binary patch literal 50135 zcmeI*Uu;uV90%}U|3L`@I@rTdbcGO>85v_6{}e|jLzsWYbQ72OaBSCG*4VYBy#p#k zW(ZMYLPYnlgclPNbt-0(naG3CMdO2!3?zUWqr^mmCL|Dp2_yr5zkAQ!+9L3@2b1q1 zr|106Irn$Y{dD8)!1#^JH_M1z#Kq5bF4s$5q60F(Wg*uecvh*-OLke9zrTKNC*O&OgB;5~J>1GV@sas=IhJ>< z8zb7y?QE{?T%|aB$XeO9&_U)4OMsu3Jf-D+9*}*u>=;)c?{9qK^-CKrT)jMAQ_o{T zuCj-$&N^82}#tK^dN5LNSED=u2mm(8q5#3NEWa#_>pt$n;U zn&Ze?M9a95JVSZgrAEi{-clamD)S?J{%Sk145L5*0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z0D=FVz{H-D!xJ7l9GXRes-Wjw1JPi}O{0DaUHALwD&K#-&etXY1J70SnxKnD zC-#heNK|#6?_v%H{r2-RUnTLaTc7h)*6(Fa-lNVt`|t%}YahNZ`=9$<^iAcNQ?k!I zjxTzr=K132ZTrYOT$$7Op>kLW(%i>>7Ms*o>B`kbdi?xRYduZ~u%;{M?o zZtI*^HlG}pJncTRa;~mlw{}%SEEy|m#>*5Li*{_G;IQVLtS$|`r~8@ZM0()YrpFL!Lq_{o6vGzWLT+G{Pq z2LvDh0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Pr5;QYV#b^6~4Sg+gZ-x)hV z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_;0Tm2p$_SnhoZSeRAtS+h>FCM zQ6odo?x43QLro#op4%8sXZsR{YVA#@GNz3Ct#Lcn!_TCmyhbJiJjqX~79*TUq`G;C zTpYJ1=SW#IzoXHxr)I%fv&bdbVd#tW}&h-;j4%jnpZsxg&hMMen zfsX5RyqII2zG=@AHI&3pmc%dEF+XA#4>w+}KCUyk7RDS>kev6JJiaqvzXeAnSTb+1 z6*Cn9-G;A}HI&Z8cZN+vcDBonU&``qSIv=g<_aET7WV>j^U2-(hbYUni>s75L}MdC zHX#q!@A|saAsFLS({B!%d+Fw-Y*aSak;H?Z1szQ*tPdg z3`c!yer@jVxPIm0vB1%NpB(E-ee-85@4ay5%**brUA|lWqy4WO`02|xw;X)IYlRT?@T+O>IVg|H^H@|8}tDoo~kue0Hzrr+fZJ#m0}mI=grG{8^7a z;?FPo@zg(~-?cX%IdpWqdFzhXPJBAu`-cyGefGXnubz8j;P1Z<&Tp=HKC NL: + assert node[3] is not None + return Node(type=node[0], children=node[3], context=node[2]) + + +# A placeholder node, used when parser is backtracking. +DUMMY_NODE = (-1, None, None, None) + + +def stack_copy( + stack: List[Tuple[DFAS, int, RawNode]] +) -> List[Tuple[DFAS, int, RawNode]]: + """Nodeless stack copy.""" + return [(dfa, label, DUMMY_NODE) for dfa, label, _ in stack] + + +class Recorder: + def __init__(self, parser: "Parser", ilabels: List[int], context: Context) -> None: + self.parser = parser + self._ilabels = ilabels + self.context = context # not really matter + + self._dead_ilabels: Set[int] = set() + self._start_point = self.parser.stack + self._points = {ilabel: stack_copy(self._start_point) for ilabel in ilabels} + + @property + def ilabels(self) -> Set[int]: + return self._dead_ilabels.symmetric_difference(self._ilabels) + + @contextmanager + def switch_to(self, ilabel: int) -> Iterator[None]: + with self.backtrack(): + self.parser.stack = self._points[ilabel] + try: + yield + except ParseError: + self._dead_ilabels.add(ilabel) + finally: + self.parser.stack = self._start_point + + @contextmanager + def backtrack(self) -> Iterator[None]: + """ + Use the node-level invariant ones for basic parsing operations (push/pop/shift). + These still will operate on the stack; but they won't create any new nodes, or + modify the contents of any other existing nodes. + + This saves us a ton of time when we are backtracking, since we + want to restore to the initial state as quick as possible, which + can only be done by having as little mutatations as possible. + """ + is_backtracking = self.parser.is_backtracking + try: + self.parser.is_backtracking = True + yield + finally: + self.parser.is_backtracking = is_backtracking + + def add_token(self, tok_type: int, tok_val: str, raw: bool = False) -> None: + func: Callable[..., Any] + if raw: + func = self.parser._addtoken + else: + func = self.parser.addtoken + + for ilabel in self.ilabels: + with self.switch_to(ilabel): + args = [tok_type, tok_val, self.context] + if raw: + args.insert(0, ilabel) + func(*args) + + def determine_route( + self, value: Optional[str] = None, force: bool = False + ) -> Optional[int]: + alive_ilabels = self.ilabels + if len(alive_ilabels) == 0: + *_, most_successful_ilabel = self._dead_ilabels + raise ParseError("bad input", most_successful_ilabel, value, self.context) + + ilabel, *rest = alive_ilabels + if force or not rest: + return ilabel + else: + return None + + +class ParseError(Exception): + """Exception to signal the parser is stuck.""" + + def __init__( + self, msg: str, type: Optional[int], value: Optional[str], context: Context + ) -> None: + Exception.__init__( + self, f"{msg}: type={type!r}, value={value!r}, context={context!r}" + ) + self.msg = msg + self.type = type + self.value = value + self.context = context + + +class Parser: + """Parser engine. + + The proper usage sequence is: + + p = Parser(grammar, [converter]) # create instance + p.setup([start]) # prepare for parsing + : + if p.addtoken(...): # parse a token; may raise ParseError + break + root = p.rootnode # root of abstract syntax tree + + A Parser instance may be reused by calling setup() repeatedly. + + A Parser instance contains state pertaining to the current token + sequence, and should not be used concurrently by different threads + to parse separate token sequences. + + See driver.py for how to get input tokens by tokenizing a file or + string. + + Parsing is complete when addtoken() returns True; the root of the + abstract syntax tree can then be retrieved from the rootnode + instance variable. When a syntax error occurs, addtoken() raises + the ParseError exception. There is no error recovery; the parser + cannot be used after a syntax error was reported (but it can be + reinitialized by calling setup()). + + """ + + def __init__(self, grammar: Grammar, convert: Optional[Convert] = None) -> None: + """Constructor. + + The grammar argument is a grammar.Grammar instance; see the + grammar module for more information. + + The parser is not ready yet for parsing; you must call the + setup() method to get it started. + + The optional convert argument is a function mapping concrete + syntax tree nodes to abstract syntax tree nodes. If not + given, no conversion is done and the syntax tree produced is + the concrete syntax tree. If given, it must be a function of + two arguments, the first being the grammar (a grammar.Grammar + instance), and the second being the concrete syntax tree node + to be converted. The syntax tree is converted from the bottom + up. + + **post-note: the convert argument is ignored since for Black's + usage, convert will always be blib2to3.pytree.convert. Allowing + this to be dynamic hurts mypyc's ability to use early binding. + These docs are left for historical and informational value. + + A concrete syntax tree node is a (type, value, context, nodes) + tuple, where type is the node type (a token or symbol number), + value is None for symbols and a string for tokens, context is + None or an opaque value used for error reporting (typically a + (lineno, offset) pair), and nodes is a list of children for + symbols, and None for tokens. + + An abstract syntax tree node may be anything; this is entirely + up to the converter function. + + """ + self.grammar = grammar + # See note in docstring above. TL;DR this is ignored. + self.convert = convert or lam_sub + self.is_backtracking = False + self.last_token: Optional[int] = None + + def setup(self, proxy: "TokenProxy", start: Optional[int] = None) -> None: + """Prepare for parsing. + + This *must* be called before starting to parse. + + The optional argument is an alternative start symbol; it + defaults to the grammar's start symbol. + + You can use a Parser instance to parse any number of programs; + each time you call setup() the parser is reset to an initial + state determined by the (implicit or explicit) start symbol. + + """ + if start is None: + start = self.grammar.start + # Each stack entry is a tuple: (dfa, state, node). + # A node is a tuple: (type, value, context, children), + # where children is a list of nodes or None, and context may be None. + newnode: RawNode = (start, None, None, []) + stackentry = (self.grammar.dfas[start], 0, newnode) + self.stack: List[Tuple[DFAS, int, RawNode]] = [stackentry] + self.rootnode: Optional[NL] = None + self.used_names: Set[str] = set() + self.proxy = proxy + self.last_token = None + + def addtoken(self, type: int, value: str, context: Context) -> bool: + """Add a token; return True iff this is the end of the program.""" + # Map from token to label + ilabels = self.classify(type, value, context) + assert len(ilabels) >= 1 + + # If we have only one state to advance, we'll directly + # take it as is. + if len(ilabels) == 1: + [ilabel] = ilabels + return self._addtoken(ilabel, type, value, context) + + # If there are multiple states which we can advance (only + # happen under soft-keywords), then we will try all of them + # in parallel and as soon as one state can reach further than + # the rest, we'll choose that one. This is a pretty hacky + # and hopefully temporary algorithm. + # + # For a more detailed explanation, check out this post: + # https://tree.science/what-the-backtracking.html + + with self.proxy.release() as proxy: + counter, force = 0, False + recorder = Recorder(self, ilabels, context) + recorder.add_token(type, value, raw=True) + + next_token_value = value + while recorder.determine_route(next_token_value) is None: + if not proxy.can_advance(counter): + force = True + break + + next_token_type, next_token_value, *_ = proxy.eat(counter) + if next_token_type in (tokenize.COMMENT, tokenize.NL): + counter += 1 + continue + + if next_token_type == tokenize.OP: + next_token_type = grammar.opmap[next_token_value] + + recorder.add_token(next_token_type, next_token_value) + counter += 1 + + ilabel = cast(int, recorder.determine_route(next_token_value, force=force)) + assert ilabel is not None + + return self._addtoken(ilabel, type, value, context) + + def _addtoken(self, ilabel: int, type: int, value: str, context: Context) -> bool: + # Loop until the token is shifted; may raise exceptions + while True: + dfa, state, node = self.stack[-1] + states, first = dfa + arcs = states[state] + # Look for a state with this label + for i, newstate in arcs: + t = self.grammar.labels[i][0] + if t >= 256: + # See if it's a symbol and if we're in its first set + itsdfa = self.grammar.dfas[t] + itsstates, itsfirst = itsdfa + if ilabel in itsfirst: + # Push a symbol + self.push(t, itsdfa, newstate, context) + break # To continue the outer while loop + + elif ilabel == i: + # Look it up in the list of labels + # Shift a token; we're done with it + self.shift(type, value, newstate, context) + # Pop while we are in an accept-only state + state = newstate + while states[state] == [(0, state)]: + self.pop() + if not self.stack: + # Done parsing! + return True + dfa, state, node = self.stack[-1] + states, first = dfa + # Done with this token + self.last_token = type + return False + + else: + if (0, state) in arcs: + # An accepting state, pop it and try something else + self.pop() + if not self.stack: + # Done parsing, but another token is input + raise ParseError("too much input", type, value, context) + else: + # No success finding a transition + raise ParseError("bad input", type, value, context) + + def classify(self, type: int, value: str, context: Context) -> List[int]: + """Turn a token into a label. (Internal) + + Depending on whether the value is a soft-keyword or not, + this function may return multiple labels to choose from.""" + if type == token.NAME: + # Keep a listing of all used names + self.used_names.add(value) + # Check for reserved words + if value in self.grammar.keywords: + return [self.grammar.keywords[value]] + elif value in self.grammar.soft_keywords: + assert type in self.grammar.tokens + # Current soft keywords (match, case, type) can only appear at the + # beginning of a statement. So as a shortcut, don't try to treat them + # like keywords in any other context. + # ('_' is also a soft keyword in the real grammar, but for our grammar + # it's just an expression, so we don't need to treat it specially.) + if self.last_token not in ( + None, + token.INDENT, + token.DEDENT, + token.NEWLINE, + token.SEMI, + token.COLON, + ): + return [self.grammar.tokens[type]] + return [ + self.grammar.tokens[type], + self.grammar.soft_keywords[value], + ] + + ilabel = self.grammar.tokens.get(type) + if ilabel is None: + raise ParseError("bad token", type, value, context) + return [ilabel] + + def shift(self, type: int, value: str, newstate: int, context: Context) -> None: + """Shift a token. (Internal)""" + if self.is_backtracking: + dfa, state, _ = self.stack[-1] + self.stack[-1] = (dfa, newstate, DUMMY_NODE) + else: + dfa, state, node = self.stack[-1] + rawnode: RawNode = (type, value, context, None) + newnode = convert(self.grammar, rawnode) + assert node[-1] is not None + node[-1].append(newnode) + self.stack[-1] = (dfa, newstate, node) + + def push(self, type: int, newdfa: DFAS, newstate: int, context: Context) -> None: + """Push a nonterminal. (Internal)""" + if self.is_backtracking: + dfa, state, _ = self.stack[-1] + self.stack[-1] = (dfa, newstate, DUMMY_NODE) + self.stack.append((newdfa, 0, DUMMY_NODE)) + else: + dfa, state, node = self.stack[-1] + newnode: RawNode = (type, None, context, []) + self.stack[-1] = (dfa, newstate, node) + self.stack.append((newdfa, 0, newnode)) + + def pop(self) -> None: + """Pop a nonterminal. (Internal)""" + if self.is_backtracking: + self.stack.pop() + else: + popdfa, popstate, popnode = self.stack.pop() + newnode = convert(self.grammar, popnode) + if self.stack: + dfa, state, node = self.stack[-1] + assert node[-1] is not None + node[-1].append(newnode) + else: + self.rootnode = newnode + self.rootnode.used_names = self.used_names diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..d3c3751621d8a7bab673864c0d7feb3263afef2d GIT binary patch literal 50118 zcmeI*Uu;uV90%}UZ`ZBF0UORRB4!N|{umjv8@MUKP9U%-W4fVx&>Y*f+ZwyJw0E!y z#PNU$F(_NWEHN>}7l#p@IucEQm5`th5Mr&EUs6Ih<3{Wmw8-&;#sBI*0r};L-`+p{E&3) z;bEuB6-t?rK2v&jDa=>1+8#fv=Os3D-)f4eKQ~k=ZT5!JlS761=ox!zp>qYtx%s?0 zA3wWQ?0l*_5=%x>JW`l%q0YBTUoUZPKDuLn9ceQajd$tm3-i6E^KI7iPOQWH+&rjM zZ+u%c9#+wKXTpl}-^W)v-v*sP;=KJiiFGUQb%?7{Ya81d)tXJst@hgu=nL-Bx_Mfv zd|}GCD%F+9d98QNC*Lir1nm2DM8({Zd`^*lUEyl)%NgaiU-tvLEr^|cInS(AEU40% zo=_sDl4k0z`6_if$)CHA5*{yd=D1ZV95jPd1BLsm?6>Ef=ae`%-_)IUPo7iWl~T_) zH9xm*ZIkoc%G&c3(5;S7>15(A)hP>DrbdFS{rmNDJNZmJ?BiJ0>E?C`x8fu7LmbO9 zE;&Ke$L#}LTewPb){tvu*<1&i&n;fQU-A@|hj~EO8GEnM)xB%wfg^*PyOz&woag5; zA6Hq!TGchv>RXTJs&hZaqw>9Siu^w7xk@hC57A=&YsE#&d()}qv1mwYYbI?*da9qT z4re&BE}});NS=LJ+hwVa<+-Ii!d2!E^8OduiDeiC0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009X6?*t~cj~$wD(?DPbl~wuNKhzTK4;VD+rN9lZhyLR8uQ&L3W}8pXyQu%g#e9v= zMWYkjPYe@PUEs5r`+Z*fewnY5`1b81e3bQjxhCsY7o2tYfUva=pO^j5buM|P^2{t) zXEw)|il*lI;OHIe$TM6kG1|$fx*+|tIsFmc=X0@@{9G0CvZT*>D&#z>^!ey$#R~2Z z6dTq)udN?DBzamqWaV7xZ>V2U+Zpcc^sjs(60UCuJz1wzPbQh^pnJ?!N8?dbh4?tD z-%QjhrIKBdxL>!j4>>o@63r%DC4Ww_`oLF%jl#WU`DW`7X6K5{$(X9Xv!X zj+^39Q&G8_hISGeN<}4BRGRFH#OYBtjqKn*-PYE+_;Z$*sIuP*$>3(Ti)d)I9Y3h! z8XfyM=ILAZERnw;ZYqdhvSYr*E^cm$xO%u2bIpx8Bp*5ZpWL=HVC|lR0wbBWwDNWG zT<$Pe${I?hqFaMzgx4Mar8LV{i@59TwSvc(!FcB4wKTr}&fznSo3`va{^@kDfBy5~Yv%?o$D02>HuBK=^~J+u^F80bx}bjU@NXqw I9yne5FO45EVE_OC literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.py new file mode 100644 index 00000000..3ece9bb4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/pgen.py @@ -0,0 +1,428 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +import os +from typing import ( + IO, + Any, + Dict, + Iterator, + List, + NoReturn, + Optional, + Sequence, + Tuple, + Union, +) + +from blib2to3.pgen2 import grammar, token, tokenize +from blib2to3.pgen2.tokenize import GoodTokenInfo + +Path = Union[str, "os.PathLike[str]"] + + +class PgenGrammar(grammar.Grammar): + pass + + +class ParserGenerator: + filename: Path + stream: IO[str] + generator: Iterator[GoodTokenInfo] + first: Dict[str, Optional[Dict[str, int]]] + + def __init__(self, filename: Path, stream: Optional[IO[str]] = None) -> None: + close_stream = None + if stream is None: + stream = open(filename, encoding="utf-8") + close_stream = stream.close + self.filename = filename + self.stream = stream + self.generator = tokenize.generate_tokens(stream.readline) + self.gettoken() # Initialize lookahead + self.dfas, self.startsymbol = self.parse() + if close_stream is not None: + close_stream() + self.first = {} # map from symbol name to set of tokens + self.addfirstsets() + + def make_grammar(self) -> PgenGrammar: + c = PgenGrammar() + names = list(self.dfas.keys()) + names.sort() + names.remove(self.startsymbol) + names.insert(0, self.startsymbol) + for name in names: + i = 256 + len(c.symbol2number) + c.symbol2number[name] = i + c.number2symbol[i] = name + for name in names: + dfa = self.dfas[name] + states = [] + for state in dfa: + arcs = [] + for label, next in sorted(state.arcs.items()): + arcs.append((self.make_label(c, label), dfa.index(next))) + if state.isfinal: + arcs.append((0, dfa.index(state))) + states.append(arcs) + c.states.append(states) + c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) + c.start = c.symbol2number[self.startsymbol] + return c + + def make_first(self, c: PgenGrammar, name: str) -> Dict[int, int]: + rawfirst = self.first[name] + assert rawfirst is not None + first = {} + for label in sorted(rawfirst): + ilabel = self.make_label(c, label) + ##assert ilabel not in first # XXX failed on <> ... != + first[ilabel] = 1 + return first + + def make_label(self, c: PgenGrammar, label: str) -> int: + # XXX Maybe this should be a method on a subclass of converter? + ilabel = len(c.labels) + if label[0].isalpha(): + # Either a symbol name or a named token + if label in c.symbol2number: + # A symbol name (a non-terminal) + if label in c.symbol2label: + return c.symbol2label[label] + else: + c.labels.append((c.symbol2number[label], None)) + c.symbol2label[label] = ilabel + return ilabel + else: + # A named token (NAME, NUMBER, STRING) + itoken = getattr(token, label, None) + assert isinstance(itoken, int), label + assert itoken in token.tok_name, label + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + else: + # Either a keyword or an operator + assert label[0] in ('"', "'"), label + value = eval(label) + if value[0].isalpha(): + if label[0] == '"': + keywords = c.soft_keywords + else: + keywords = c.keywords + + # A keyword + if value in keywords: + return keywords[value] + else: + c.labels.append((token.NAME, value)) + keywords[value] = ilabel + return ilabel + else: + # An operator (any non-numeric token) + itoken = grammar.opmap[value] # Fails if unknown token + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + + def addfirstsets(self) -> None: + names = list(self.dfas.keys()) + names.sort() + for name in names: + if name not in self.first: + self.calcfirst(name) + # print name, self.first[name].keys() + + def calcfirst(self, name: str) -> None: + dfa = self.dfas[name] + self.first[name] = None # dummy to detect left recursion + state = dfa[0] + totalset: Dict[str, int] = {} + overlapcheck = {} + for label in state.arcs: + if label in self.dfas: + if label in self.first: + fset = self.first[label] + if fset is None: + raise ValueError("recursion for rule %r" % name) + else: + self.calcfirst(label) + fset = self.first[label] + assert fset is not None + totalset.update(fset) + overlapcheck[label] = fset + else: + totalset[label] = 1 + overlapcheck[label] = {label: 1} + inverse: Dict[str, str] = {} + for label, itsfirst in overlapcheck.items(): + for symbol in itsfirst: + if symbol in inverse: + raise ValueError( + "rule %s is ambiguous; %s is in the first sets of %s as well" + " as %s" % (name, symbol, label, inverse[symbol]) + ) + inverse[symbol] = label + self.first[name] = totalset + + def parse(self) -> Tuple[Dict[str, List["DFAState"]], str]: + dfas = {} + startsymbol: Optional[str] = None + # MSTART: (NEWLINE | RULE)* ENDMARKER + while self.type != token.ENDMARKER: + while self.type == token.NEWLINE: + self.gettoken() + # RULE: NAME ':' RHS NEWLINE + name = self.expect(token.NAME) + self.expect(token.OP, ":") + a, z = self.parse_rhs() + self.expect(token.NEWLINE) + # self.dump_nfa(name, a, z) + dfa = self.make_dfa(a, z) + # self.dump_dfa(name, dfa) + # oldlen = len(dfa) + self.simplify_dfa(dfa) + # newlen = len(dfa) + dfas[name] = dfa + # print name, oldlen, newlen + if startsymbol is None: + startsymbol = name + assert startsymbol is not None + return dfas, startsymbol + + def make_dfa(self, start: "NFAState", finish: "NFAState") -> List["DFAState"]: + # To turn an NFA into a DFA, we define the states of the DFA + # to correspond to *sets* of states of the NFA. Then do some + # state reduction. Let's represent sets as dicts with 1 for + # values. + assert isinstance(start, NFAState) + assert isinstance(finish, NFAState) + + def closure(state: NFAState) -> Dict[NFAState, int]: + base: Dict[NFAState, int] = {} + addclosure(state, base) + return base + + def addclosure(state: NFAState, base: Dict[NFAState, int]) -> None: + assert isinstance(state, NFAState) + if state in base: + return + base[state] = 1 + for label, next in state.arcs: + if label is None: + addclosure(next, base) + + states = [DFAState(closure(start), finish)] + for state in states: # NB states grows while we're iterating + arcs: Dict[str, Dict[NFAState, int]] = {} + for nfastate in state.nfaset: + for label, next in nfastate.arcs: + if label is not None: + addclosure(next, arcs.setdefault(label, {})) + for label, nfaset in sorted(arcs.items()): + for st in states: + if st.nfaset == nfaset: + break + else: + st = DFAState(nfaset, finish) + states.append(st) + state.addarc(st, label) + return states # List of DFAState instances; first one is start + + def dump_nfa(self, name: str, start: "NFAState", finish: "NFAState") -> None: + print("Dump of NFA for", name) + todo = [start] + for i, state in enumerate(todo): + print(" State", i, state is finish and "(final)" or "") + for label, next in state.arcs: + if next in todo: + j = todo.index(next) + else: + j = len(todo) + todo.append(next) + if label is None: + print(" -> %d" % j) + else: + print(" %s -> %d" % (label, j)) + + def dump_dfa(self, name: str, dfa: Sequence["DFAState"]) -> None: + print("Dump of DFA for", name) + for i, state in enumerate(dfa): + print(" State", i, state.isfinal and "(final)" or "") + for label, next in sorted(state.arcs.items()): + print(" %s -> %d" % (label, dfa.index(next))) + + def simplify_dfa(self, dfa: List["DFAState"]) -> None: + # This is not theoretically optimal, but works well enough. + # Algorithm: repeatedly look for two states that have the same + # set of arcs (same labels pointing to the same nodes) and + # unify them, until things stop changing. + + # dfa is a list of DFAState instances + changes = True + while changes: + changes = False + for i, state_i in enumerate(dfa): + for j in range(i + 1, len(dfa)): + state_j = dfa[j] + if state_i == state_j: + # print " unify", i, j + del dfa[j] + for state in dfa: + state.unifystate(state_j, state_i) + changes = True + break + + def parse_rhs(self) -> Tuple["NFAState", "NFAState"]: + # RHS: ALT ('|' ALT)* + a, z = self.parse_alt() + if self.value != "|": + return a, z + else: + aa = NFAState() + zz = NFAState() + aa.addarc(a) + z.addarc(zz) + while self.value == "|": + self.gettoken() + a, z = self.parse_alt() + aa.addarc(a) + z.addarc(zz) + return aa, zz + + def parse_alt(self) -> Tuple["NFAState", "NFAState"]: + # ALT: ITEM+ + a, b = self.parse_item() + while self.value in ("(", "[") or self.type in (token.NAME, token.STRING): + c, d = self.parse_item() + b.addarc(c) + b = d + return a, b + + def parse_item(self) -> Tuple["NFAState", "NFAState"]: + # ITEM: '[' RHS ']' | ATOM ['+' | '*'] + if self.value == "[": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, "]") + a.addarc(z) + return a, z + else: + a, z = self.parse_atom() + value = self.value + if value not in ("+", "*"): + return a, z + self.gettoken() + z.addarc(a) + if value == "+": + return a, z + else: + return a, a + + def parse_atom(self) -> Tuple["NFAState", "NFAState"]: + # ATOM: '(' RHS ')' | NAME | STRING + if self.value == "(": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, ")") + return a, z + elif self.type in (token.NAME, token.STRING): + a = NFAState() + z = NFAState() + a.addarc(z, self.value) + self.gettoken() + return a, z + else: + self.raise_error( + "expected (...) or NAME or STRING, got %s/%s", self.type, self.value + ) + raise AssertionError + + def expect(self, type: int, value: Optional[Any] = None) -> str: + if self.type != type or (value is not None and self.value != value): + self.raise_error( + "expected %s/%s, got %s/%s", type, value, self.type, self.value + ) + value = self.value + self.gettoken() + return value + + def gettoken(self) -> None: + tup = next(self.generator) + while tup[0] in (tokenize.COMMENT, tokenize.NL): + tup = next(self.generator) + self.type, self.value, self.begin, self.end, self.line = tup + # print token.tok_name[self.type], repr(self.value) + + def raise_error(self, msg: str, *args: Any) -> NoReturn: + if args: + try: + msg = msg % args + except Exception: + msg = " ".join([msg] + list(map(str, args))) + raise SyntaxError(msg, (self.filename, self.end[0], self.end[1], self.line)) + + +class NFAState: + arcs: List[Tuple[Optional[str], "NFAState"]] + + def __init__(self) -> None: + self.arcs = [] # list of (label, NFAState) pairs + + def addarc(self, next: "NFAState", label: Optional[str] = None) -> None: + assert label is None or isinstance(label, str) + assert isinstance(next, NFAState) + self.arcs.append((label, next)) + + +class DFAState: + nfaset: Dict[NFAState, Any] + isfinal: bool + arcs: Dict[str, "DFAState"] + + def __init__(self, nfaset: Dict[NFAState, Any], final: NFAState) -> None: + assert isinstance(nfaset, dict) + assert isinstance(next(iter(nfaset)), NFAState) + assert isinstance(final, NFAState) + self.nfaset = nfaset + self.isfinal = final in nfaset + self.arcs = {} # map from label to DFAState + + def addarc(self, next: "DFAState", label: str) -> None: + assert isinstance(label, str) + assert label not in self.arcs + assert isinstance(next, DFAState) + self.arcs[label] = next + + def unifystate(self, old: "DFAState", new: "DFAState") -> None: + for label, next in self.arcs.items(): + if next is old: + self.arcs[label] = new + + def __eq__(self, other: Any) -> bool: + # Equality test -- ignore the nfaset instance variable + assert isinstance(other, DFAState) + if self.isfinal != other.isfinal: + return False + # Can't just return self.arcs == other.arcs, because that + # would invoke this method recursively, with cycles... + if len(self.arcs) != len(other.arcs): + return False + for label, next in self.arcs.items(): + if next is not other.arcs.get(label): + return False + return True + + __hash__: Any = None # For Py3 compatibility. + + +def generate_grammar(filename: Path = "Grammar.txt") -> PgenGrammar: + p = ParserGenerator(filename) + return p.make_grammar() diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/token.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/token.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..60deb7f9361abe2780356f9f1d19db839f66612b GIT binary patch literal 50135 zcmeI*e{54#6bJCrb{i!O7_vX6qN@X4SY(V1a1#QZ8nvWH2Z_e@uB>Dw9=lM=d9p3JD*qQ z<9D};olo@`k+_lIk^Fq~biU3=bX<;tXuhBN4P50+}P2mnp)Sk+uyEVFStSL;c2Pz z15?6PsSUBLul0uc*&O0j=38-YM zFBprcxS6NN2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00jPb0#~;j+JDtUL;k5$QttEoP)D@e@1{{N`7e75=@Q?6z0B7$JA8WHMT1XN@*1Cu zMz3x;{2o#HDZY!j+vl~Pm-%vu$HqS9tE?wvO~#{6Is5PhVQU}0FZ-YSoGYBjGd*vg znH--hn3(5_qu1>t?{IO7yOZ4Ir=))@tDn|=z871@?^P;amh?GKsoY1EK3^RzUBdmL zBDZzUiw_^#FL~Mu$;!F3wxNDWU3aLvyLRa!BUIlId|%Ak009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY=cz^n>tm;Nk&C>05*q}d-- z!EiKWB(x0m#A#eo^f+C(?vA0 z!j5O_xJJkKaLm)!>{+6^y!es4c)cC-BX;p{Q^2*5YZ2G%m_zcB^B&{JcLwaY;3yAE z<}J2drW~N_@RhQL;)(FH0n?D3?Q-QzafaVd#$8*S bool: + return x < NT_OFFSET + + +def ISNONTERMINAL(x: int) -> bool: + return x >= NT_OFFSET + + +def ISEOF(x: int) -> bool: + return x == ENDMARKER diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..3672bbf83033a79d7d2c1f834bba69aebe4b0679 GIT binary patch literal 50138 zcmeI*U2IfE6bJCLAB8ovP_$`ElypPT#-xiFdmke;3!}TYgRjPS)OS3(c`w_|wNyh~| z>{eN!lx4hTNzWz;HPk~ljb-FCj#w3RaBTlD(;d@t#IoAtaK>o7Mr4=U9a z-)6?6%8a)q>^S%P_*~~(qZ3G+b3Qk*ZsmLJqp4dYn1;JtfZ0H~FN~llPSGN~vcW z*R5T>s?q)38gk|-q+1=I*U7|Ps$1r<%pwVfoZsI7w-fKg!$FQ^pLT9#o%qQ72OP^g zE;{AV&fxwAu2S4RWUXwQ?I82nrI??WJo)889*}*OY@2)fQgX>iUu6Hlhlk$luHmsD zSJ{Jzcl8w6ef#x1b-qd-m7goO$nR$ZSIH&kA*$d%D;`?dl};^;nGva*GHJ``tbVFG zn&HS^M2~PIdHRMNmq&Fh?=596SDEkU^H(~FWf%nl5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SNrB1V(oZ9vt=2p3r?%TpslOP)pPs^3w4Dg>D84=sMqhy~$TIn}d4ZLp{${@S329 zj*sp*^$Ah=FyF)M4F;U&WxibE@$mt^g?dib4EfZsyANLuw)f$?vj4fy<$}pPMS1(o z;`p+Ea-J`Z-nNgtLvg^{Lf-OW>0g^Z**~NEd?&Vy->XEvDCu*a61j^ieZDqYvY7jy zP4n94y!Q0qLCKRWAUkJ$&C-U&wQbS1wwn6KjA+Bs$dWpxIy1>kE8S(T+Kii)itts| z8Y@w&luB+f;x*h_i4G%fZa3sCa)0(A>2S$zZra4FMYXVTgXoq+fQ?F z_p8130(?LK0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZ~^#bnywXf3uKfXb? zQ@=BIfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafK)@B4J&!g?e|9LEiA7b~ z>WZj{8IKw%+W0EHO(|LyQX4WW!^w14%utP;$wbPM@qj(<#Co_X5#=>9Si678$m5%3g%+q7eEKz-4+>{r;=*0YpQ+(X`xfXDp#x*mC$Hej7 zfr+=^fjlo+V$0=9z=uU$C$-iN?ty>*CyJ^ z^DSJZ6cL^34|=K43Gek8npohzP<3lEW3?yZ3u>1xh=xyjR z-&(V~>f?LOclyshUjM|29beBF`0f3&pZ9%#wRcVb;ulK$Qzx$sU+jGOUe8bU{G3DA zFP@8^=q)X!@(uIGzIlCQf62o|w>Dn*d;PJ{n_vDq)%)KVJaXjQfsW_i8LRMCjvr88 WJRkikdHUV^cklb?*k5~tulx(PZ$L@_ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.py new file mode 100644 index 00000000..b04b18ba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pgen2/tokenize.py @@ -0,0 +1,698 @@ +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. +# All rights reserved. + +# mypy: allow-untyped-defs, allow-untyped-calls + +"""Tokenization help for Python programs. + +generate_tokens(readline) is a generator that breaks a stream of +text into Python tokens. It accepts a readline-like method which is called +repeatedly to get the next line of input (or "" for EOF). It generates +5-tuples with these members: + + the token type (see token.py) + the token (a string) + the starting (row, column) indices of the token (a 2-tuple of ints) + the ending (row, column) indices of the token (a 2-tuple of ints) + the original line (string) + +It is designed to match the working of the Python tokenizer exactly, except +that it produces COMMENT tokens for comments and gives type OP for all +operators + +Older entry points + tokenize_loop(readline, tokeneater) + tokenize(readline, tokeneater=printtoken) +are the same, except instead of generating tokens, tokeneater is a callback +function to which the 5 fields described above are passed as 5 arguments, +each time a new token is found.""" + +import sys +from typing import ( + Callable, + Final, + Iterable, + Iterator, + List, + Optional, + Pattern, + Set, + Tuple, + Union, +) + +from blib2to3.pgen2.grammar import Grammar +from blib2to3.pgen2.token import ( + ASYNC, + AWAIT, + COMMENT, + DEDENT, + ENDMARKER, + ERRORTOKEN, + INDENT, + NAME, + NEWLINE, + NL, + NUMBER, + OP, + STRING, + tok_name, +) + +__author__ = "Ka-Ping Yee " +__credits__ = "GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro" + +import re +from codecs import BOM_UTF8, lookup + +from . import token + +__all__ = [x for x in dir(token) if x[0] != "_"] + [ + "tokenize", + "generate_tokens", + "untokenize", +] +del token + + +def group(*choices: str) -> str: + return "(" + "|".join(choices) + ")" + + +def any(*choices: str) -> str: + return group(*choices) + "*" + + +def maybe(*choices: str) -> str: + return group(*choices) + "?" + + +def _combinations(*l: str) -> Set[str]: + return {x + y for x in l for y in l + ("",) if x.casefold() != y.casefold()} + + +Whitespace = r"[ \f\t]*" +Comment = r"#[^\r\n]*" +Ignore = Whitespace + any(r"\\\r?\n" + Whitespace) + maybe(Comment) +Name = ( # this is invalid but it's fine because Name comes after Number in all groups + r"[^\s#\(\)\[\]\{\}+\-*/!@$%^&=|;:'\",\.<>/?`~\\]+" +) + +Binnumber = r"0[bB]_?[01]+(?:_[01]+)*" +Hexnumber = r"0[xX]_?[\da-fA-F]+(?:_[\da-fA-F]+)*[lL]?" +Octnumber = r"0[oO]?_?[0-7]+(?:_[0-7]+)*[lL]?" +Decnumber = group(r"[1-9]\d*(?:_\d+)*[lL]?", "0[lL]?") +Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) +Exponent = r"[eE][-+]?\d+(?:_\d+)*" +Pointfloat = group(r"\d+(?:_\d+)*\.(?:\d+(?:_\d+)*)?", r"\.\d+(?:_\d+)*") + maybe( + Exponent +) +Expfloat = r"\d+(?:_\d+)*" + Exponent +Floatnumber = group(Pointfloat, Expfloat) +Imagnumber = group(r"\d+(?:_\d+)*[jJ]", Floatnumber + r"[jJ]") +Number = group(Imagnumber, Floatnumber, Intnumber) + +# Tail end of ' string. +Single = r"[^'\\]*(?:\\.[^'\\]*)*'" +# Tail end of " string. +Double = r'[^"\\]*(?:\\.[^"\\]*)*"' +# Tail end of ''' string. +Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" +# Tail end of """ string. +Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' +_litprefix = r"(?:[uUrRbBfF]|[rR][fFbB]|[fFbBuU][rR])?" +Triple = group(_litprefix + "'''", _litprefix + '"""') +# Single-line ' or " string. +String = group( + _litprefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'", + _litprefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"', +) + +# Because of leftmost-then-longest match semantics, be sure to put the +# longest operators first (e.g., if = came before ==, == would get +# recognized as two instances of =). +Operator = group( + r"\*\*=?", + r">>=?", + r"<<=?", + r"<>", + r"!=", + r"//=?", + r"->", + r"[+\-*/%&@|^=<>:]=?", + r"~", +) + +Bracket = "[][(){}]" +Special = group(r"\r?\n", r"[:;.,`@]") +Funny = group(Operator, Bracket, Special) + +# First (or only) line of ' or " string. +ContStr = group( + _litprefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*" + group("'", r"\\\r?\n"), + _litprefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' + group('"', r"\\\r?\n"), +) +PseudoExtras = group(r"\\\r?\n", Comment, Triple) +PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) + +pseudoprog: Final = re.compile(PseudoToken, re.UNICODE) +single3prog = re.compile(Single3) +double3prog = re.compile(Double3) + +_strprefixes = ( + _combinations("r", "R", "f", "F") + | _combinations("r", "R", "b", "B") + | {"u", "U", "ur", "uR", "Ur", "UR"} +) + +endprogs: Final = { + "'": re.compile(Single), + '"': re.compile(Double), + "'''": single3prog, + '"""': double3prog, + **{f"{prefix}'''": single3prog for prefix in _strprefixes}, + **{f'{prefix}"""': double3prog for prefix in _strprefixes}, +} + +triple_quoted: Final = ( + {"'''", '"""'} + | {f"{prefix}'''" for prefix in _strprefixes} + | {f'{prefix}"""' for prefix in _strprefixes} +) +single_quoted: Final = ( + {"'", '"'} + | {f"{prefix}'" for prefix in _strprefixes} + | {f'{prefix}"' for prefix in _strprefixes} +) + +tabsize = 8 + + +class TokenError(Exception): + pass + + +class StopTokenizing(Exception): + pass + + +Coord = Tuple[int, int] + + +def printtoken( + type: int, token: str, srow_col: Coord, erow_col: Coord, line: str +) -> None: # for testing + (srow, scol) = srow_col + (erow, ecol) = erow_col + print( + "%d,%d-%d,%d:\t%s\t%s" % (srow, scol, erow, ecol, tok_name[type], repr(token)) + ) + + +TokenEater = Callable[[int, str, Coord, Coord, str], None] + + +def tokenize(readline: Callable[[], str], tokeneater: TokenEater = printtoken) -> None: + """ + The tokenize() function accepts two parameters: one representing the + input stream, and one providing an output mechanism for tokenize(). + + The first parameter, readline, must be a callable object which provides + the same interface as the readline() method of built-in file objects. + Each call to the function should return one line of input as a string. + + The second parameter, tokeneater, must also be a callable object. It is + called once for each token, with five arguments, corresponding to the + tuples generated by generate_tokens(). + """ + try: + tokenize_loop(readline, tokeneater) + except StopTokenizing: + pass + + +# backwards compatible interface +def tokenize_loop(readline: Callable[[], str], tokeneater: TokenEater) -> None: + for token_info in generate_tokens(readline): + tokeneater(*token_info) + + +GoodTokenInfo = Tuple[int, str, Coord, Coord, str] +TokenInfo = Union[Tuple[int, str], GoodTokenInfo] + + +class Untokenizer: + tokens: List[str] + prev_row: int + prev_col: int + + def __init__(self) -> None: + self.tokens = [] + self.prev_row = 1 + self.prev_col = 0 + + def add_whitespace(self, start: Coord) -> None: + row, col = start + assert row <= self.prev_row + col_offset = col - self.prev_col + if col_offset: + self.tokens.append(" " * col_offset) + + def untokenize(self, iterable: Iterable[TokenInfo]) -> str: + for t in iterable: + if len(t) == 2: + self.compat(t, iterable) + break + tok_type, token, start, end, line = t + self.add_whitespace(start) + self.tokens.append(token) + self.prev_row, self.prev_col = end + if tok_type in (NEWLINE, NL): + self.prev_row += 1 + self.prev_col = 0 + return "".join(self.tokens) + + def compat(self, token: Tuple[int, str], iterable: Iterable[TokenInfo]) -> None: + startline = False + indents = [] + toks_append = self.tokens.append + toknum, tokval = token + if toknum in (NAME, NUMBER): + tokval += " " + if toknum in (NEWLINE, NL): + startline = True + for tok in iterable: + toknum, tokval = tok[:2] + + if toknum in (NAME, NUMBER, ASYNC, AWAIT): + tokval += " " + + if toknum == INDENT: + indents.append(tokval) + continue + elif toknum == DEDENT: + indents.pop() + continue + elif toknum in (NEWLINE, NL): + startline = True + elif startline and indents: + toks_append(indents[-1]) + startline = False + toks_append(tokval) + + +cookie_re = re.compile(r"^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)", re.ASCII) +blank_re = re.compile(rb"^[ \t\f]*(?:[#\r\n]|$)", re.ASCII) + + +def _get_normal_name(orig_enc: str) -> str: + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or enc.startswith( + ("latin-1-", "iso-8859-1-", "iso-latin-1-") + ): + return "iso-8859-1" + return orig_enc + + +def detect_encoding(readline: Callable[[], bytes]) -> Tuple[str, List[bytes]]: + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read + in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, but + disagree, a SyntaxError will be raised. If the encoding cookie is an invalid + charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + bom_found = False + encoding = None + default = "utf-8" + + def read_or_stop() -> bytes: + try: + return readline() + except StopIteration: + return b"" + + def find_cookie(line: bytes) -> Optional[str]: + try: + line_string = line.decode("ascii") + except UnicodeDecodeError: + return None + match = cookie_re.match(line_string) + if not match: + return None + encoding = _get_normal_name(match.group(1)) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + raise SyntaxError("unknown encoding: " + encoding) + + if bom_found: + if codec.name != "utf-8": + # This behaviour mimics the Python interpreter + raise SyntaxError("encoding problem: utf-8") + encoding += "-sig" + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = "utf-8-sig" + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + if not blank_re.match(first): + return default, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + + +def untokenize(iterable: Iterable[TokenInfo]) -> str: + """Transform tokens back into Python source code. + + Each element returned by the iterable must be a token sequence + with at least two elements, a token number and token value. If + only two tokens are passed, the resulting output is poor. + + Round-trip invariant for full input: + Untokenized source will match input source exactly + + Round-trip invariant for limited input: + # Output text will tokenize the back to the input + t1 = [tok[:2] for tok in generate_tokens(f.readline)] + newcode = untokenize(t1) + readline = iter(newcode.splitlines(1)).next + t2 = [tok[:2] for tokin generate_tokens(readline)] + assert t1 == t2 + """ + ut = Untokenizer() + return ut.untokenize(iterable) + + +def generate_tokens( + readline: Callable[[], str], grammar: Optional[Grammar] = None +) -> Iterator[GoodTokenInfo]: + """ + The generate_tokens() generator requires one argument, readline, which + must be a callable object which provides the same interface as the + readline() method of built-in file objects. Each call to the function + should return one line of input as a string. Alternately, readline + can be a callable function terminating with StopIteration: + readline = open(myfile).next # Example of alternate readline + + The generator produces 5-tuples with these members: the token type; the + token string; a 2-tuple (srow, scol) of ints specifying the row and + column where the token begins in the source; a 2-tuple (erow, ecol) of + ints specifying the row and column where the token ends in the source; + and the line on which the token was found. The line passed is the + logical line; continuation lines are included. + """ + lnum = parenlev = continued = 0 + numchars: Final[str] = "0123456789" + contstr, needcont = "", 0 + contline: Optional[str] = None + indents = [0] + + # If we know we're parsing 3.7+, we can unconditionally parse `async` and + # `await` as keywords. + async_keywords = False if grammar is None else grammar.async_keywords + # 'stashed' and 'async_*' are used for async/await parsing + stashed: Optional[GoodTokenInfo] = None + async_def = False + async_def_indent = 0 + async_def_nl = False + + strstart: Tuple[int, int] + endprog: Pattern[str] + + while 1: # loop over lines in stream + try: + line = readline() + except StopIteration: + line = "" + lnum += 1 + pos, max = 0, len(line) + + if contstr: # continued string + assert contline is not None + if not line: + raise TokenError("EOF in multi-line string", strstart) + endmatch = endprog.match(line) + if endmatch: + pos = end = endmatch.end(0) + yield ( + STRING, + contstr + line[:end], + strstart, + (lnum, end), + contline + line, + ) + contstr, needcont = "", 0 + contline = None + elif needcont and line[-2:] != "\\\n" and line[-3:] != "\\\r\n": + yield ( + ERRORTOKEN, + contstr + line, + strstart, + (lnum, len(line)), + contline, + ) + contstr = "" + contline = None + continue + else: + contstr = contstr + line + contline = contline + line + continue + + elif parenlev == 0 and not continued: # new statement + if not line: + break + column = 0 + while pos < max: # measure leading whitespace + if line[pos] == " ": + column += 1 + elif line[pos] == "\t": + column = (column // tabsize + 1) * tabsize + elif line[pos] == "\f": + column = 0 + else: + break + pos += 1 + if pos == max: + break + + if stashed: + yield stashed + stashed = None + + if line[pos] in "\r\n": # skip blank lines + yield (NL, line[pos:], (lnum, pos), (lnum, len(line)), line) + continue + + if line[pos] == "#": # skip comments + comment_token = line[pos:].rstrip("\r\n") + nl_pos = pos + len(comment_token) + yield ( + COMMENT, + comment_token, + (lnum, pos), + (lnum, nl_pos), + line, + ) + yield (NL, line[nl_pos:], (lnum, nl_pos), (lnum, len(line)), line) + continue + + if column > indents[-1]: # count indents + indents.append(column) + yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) + + while column < indents[-1]: # count dedents + if column not in indents: + raise IndentationError( + "unindent does not match any outer indentation level", + ("", lnum, pos, line), + ) + indents = indents[:-1] + + if async_def and async_def_indent >= indents[-1]: + async_def = False + async_def_nl = False + async_def_indent = 0 + + yield (DEDENT, "", (lnum, pos), (lnum, pos), line) + + if async_def and async_def_nl and async_def_indent >= indents[-1]: + async_def = False + async_def_nl = False + async_def_indent = 0 + + else: # continued statement + if not line: + raise TokenError("EOF in multi-line statement", (lnum, 0)) + continued = 0 + + while pos < max: + pseudomatch = pseudoprog.match(line, pos) + if pseudomatch: # scan for tokens + start, end = pseudomatch.span(1) + spos, epos, pos = (lnum, start), (lnum, end), end + token, initial = line[start:end], line[start] + + if initial in numchars or ( + initial == "." and token != "." + ): # ordinary number + yield (NUMBER, token, spos, epos, line) + elif initial in "\r\n": + newline = NEWLINE + if parenlev > 0: + newline = NL + elif async_def: + async_def_nl = True + if stashed: + yield stashed + stashed = None + yield (newline, token, spos, epos, line) + + elif initial == "#": + assert not token.endswith("\n") + if stashed: + yield stashed + stashed = None + yield (COMMENT, token, spos, epos, line) + elif token in triple_quoted: + endprog = endprogs[token] + endmatch = endprog.match(line, pos) + if endmatch: # all on one line + pos = endmatch.end(0) + token = line[start:pos] + if stashed: + yield stashed + stashed = None + yield (STRING, token, spos, (lnum, pos), line) + else: + strstart = (lnum, start) # multiple lines + contstr = line[start:] + contline = line + break + elif ( + initial in single_quoted + or token[:2] in single_quoted + or token[:3] in single_quoted + ): + if token[-1] == "\n": # continued string + strstart = (lnum, start) + maybe_endprog = ( + endprogs.get(initial) + or endprogs.get(token[1]) + or endprogs.get(token[2]) + ) + assert ( + maybe_endprog is not None + ), f"endprog not found for {token}" + endprog = maybe_endprog + contstr, needcont = line[start:], 1 + contline = line + break + else: # ordinary string + if stashed: + yield stashed + stashed = None + yield (STRING, token, spos, epos, line) + elif initial.isidentifier(): # ordinary name + if token in ("async", "await"): + if async_keywords or async_def: + yield ( + ASYNC if token == "async" else AWAIT, + token, + spos, + epos, + line, + ) + continue + + tok = (NAME, token, spos, epos, line) + if token == "async" and not stashed: + stashed = tok + continue + + if token in ("def", "for"): + if stashed and stashed[0] == NAME and stashed[1] == "async": + if token == "def": + async_def = True + async_def_indent = indents[-1] + + yield ( + ASYNC, + stashed[1], + stashed[2], + stashed[3], + stashed[4], + ) + stashed = None + + if stashed: + yield stashed + stashed = None + + yield tok + elif initial == "\\": # continued stmt + # This yield is new; needed for better idempotency: + if stashed: + yield stashed + stashed = None + yield (NL, token, spos, (lnum, pos), line) + continued = 1 + else: + if initial in "([{": + parenlev += 1 + elif initial in ")]}": + parenlev -= 1 + if stashed: + yield stashed + stashed = None + yield (OP, token, spos, epos, line) + else: + yield (ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos + 1), line) + pos += 1 + + if stashed: + yield stashed + stashed = None + + for _indent in indents[1:]: # pop remaining indent levels + yield (DEDENT, "", (lnum, 0), (lnum, 0), "") + yield (ENDMARKER, "", (lnum, 0), (lnum, 0), "") + + +if __name__ == "__main__": # testing + if len(sys.argv) > 1: + tokenize(open(sys.argv[1]).readline) + else: + tokenize(sys.stdin.readline) diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..6814ab6f9982be78fa355ba6ee7a9dae2675ee14 GIT binary patch literal 50136 zcmeI*Uu;uV90%}U+Z9UKV3U!IplP!R3=`*BfmBM`W4c7Q)dR}6u?wd^!4d#YQrH$TDdSa+BpJ$CV^{`$cac(}3 z&d1Mg7Av3Xj>M9Y6ps|ar>JFK_s*9-2_x_DZu zd|^ttD%F+9d98QNC*Liz_^r?Dh^BEz^4Uesb)BnqE_;;QLEZQ3wjj38Wk0i0v7kz4 zdP0eqN*bxV=Bv=@B!BKXrt^4_J;$w5;h+(m94I_r#h^83Kc~dG`6fSU_2fC_T`9Gt zdF$r&P0jZ2R@Ry)zixGWMJE$?sdlMkndK5>t>0e{w-e9A!#<8>pKfkto%qQ7Fvs$Y z%g+(@aXXW18&@gz97`S)vh z%*R#sFn4v7n0@o{9CfZocvQYuc9GxDdaja7&O@|_|5|a-vfgxRSu7fox+9Y|B0bgX zs>2zM%tf@28_9DxYq>1eu{^hwhq%i82%o>oN-V=D5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG|ge=9K7fA-jzi(d85pi-~T^+hewA-|JOddPp%o$ciGUY7pBoPJXG`F?B#KUcZDH0g7ma=Di(eZE3kzJmMP zra8@X{4#Fk3m8-0BcfO8WsWbGwaOuk(+hTqxrCfEn*VSHo4O$35 z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*!hSit^&?d$cw6VRmFDc%<8Apijg zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5XccItE3$gmifb(SXiZv-jE7K*1C}nAgZ;DNpjJR8u4vizPaEh#VX@ z$D@X#G8YZ+A#y4el~_@6GSig`_RsizeO9X-;Ty|KNj|K*)!&mOq+{n@d<23p=* NFnqdJ&1rhA<6np@FV+A6 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.py b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.py new file mode 100644 index 00000000..2b43b4c1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pygram.py @@ -0,0 +1,200 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Export the Python grammar and symbols.""" + +# Python imports +import os +from typing import Union + +# Local imports +from .pgen2 import driver +from .pgen2.grammar import Grammar + +# Moved into initialize because mypyc can't handle __file__ (XXX bug) +# # The grammar file +# _GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") +# _PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), +# "PatternGrammar.txt") + + +class Symbols: + def __init__(self, grammar: Grammar) -> None: + """Initializer. + + Creates an attribute for each grammar symbol (nonterminal), + whose value is the symbol's type (an int >= 256). + """ + for name, symbol in grammar.symbol2number.items(): + setattr(self, name, symbol) + + +class _python_symbols(Symbols): + and_expr: int + and_test: int + annassign: int + arglist: int + argument: int + arith_expr: int + asexpr_test: int + assert_stmt: int + async_funcdef: int + async_stmt: int + atom: int + augassign: int + break_stmt: int + case_block: int + classdef: int + comp_for: int + comp_if: int + comp_iter: int + comp_op: int + comparison: int + compound_stmt: int + continue_stmt: int + decorated: int + decorator: int + decorators: int + del_stmt: int + dictsetmaker: int + dotted_as_name: int + dotted_as_names: int + dotted_name: int + encoding_decl: int + eval_input: int + except_clause: int + expr: int + expr_stmt: int + exprlist: int + factor: int + file_input: int + flow_stmt: int + for_stmt: int + funcdef: int + global_stmt: int + guard: int + if_stmt: int + import_as_name: int + import_as_names: int + import_from: int + import_name: int + import_stmt: int + lambdef: int + listmaker: int + match_stmt: int + namedexpr_test: int + not_test: int + old_comp_for: int + old_comp_if: int + old_comp_iter: int + old_lambdef: int + old_test: int + or_test: int + parameters: int + paramspec: int + pass_stmt: int + pattern: int + patterns: int + power: int + raise_stmt: int + return_stmt: int + shift_expr: int + simple_stmt: int + single_input: int + sliceop: int + small_stmt: int + subject_expr: int + star_expr: int + stmt: int + subscript: int + subscriptlist: int + suite: int + term: int + test: int + testlist: int + testlist1: int + testlist_gexp: int + testlist_safe: int + testlist_star_expr: int + tfpdef: int + tfplist: int + tname: int + tname_star: int + trailer: int + try_stmt: int + type_stmt: int + typedargslist: int + typeparam: int + typeparams: int + typevar: int + typevartuple: int + varargslist: int + vfpdef: int + vfplist: int + vname: int + while_stmt: int + with_stmt: int + xor_expr: int + yield_arg: int + yield_expr: int + yield_stmt: int + + +class _pattern_symbols(Symbols): + Alternative: int + Alternatives: int + Details: int + Matcher: int + NegatedUnit: int + Repeater: int + Unit: int + + +python_grammar: Grammar +python_grammar_async_keywords: Grammar +python_grammar_soft_keywords: Grammar +pattern_grammar: Grammar +python_symbols: _python_symbols +pattern_symbols: _pattern_symbols + + +def initialize(cache_dir: Union[str, "os.PathLike[str]", None] = None) -> None: + global python_grammar + global python_grammar_async_keywords + global python_grammar_soft_keywords + global python_symbols + global pattern_grammar + global pattern_symbols + + # The grammar file + _GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") + _PATTERN_GRAMMAR_FILE = os.path.join( + os.path.dirname(__file__), "PatternGrammar.txt" + ) + + python_grammar = driver.load_packaged_grammar("blib2to3", _GRAMMAR_FILE, cache_dir) + assert "print" not in python_grammar.keywords + assert "exec" not in python_grammar.keywords + + soft_keywords = python_grammar.soft_keywords.copy() + python_grammar.soft_keywords.clear() + + python_symbols = _python_symbols(python_grammar) + + # Python 3.0-3.6 + python_grammar.version = (3, 0) + + # Python 3.7+ + python_grammar_async_keywords = python_grammar.copy() + python_grammar_async_keywords.async_keywords = True + python_grammar_async_keywords.version = (3, 7) + + # Python 3.10+ + python_grammar_soft_keywords = python_grammar_async_keywords.copy() + python_grammar_soft_keywords.soft_keywords = soft_keywords + python_grammar_soft_keywords.version = (3, 10) + + pattern_grammar = driver.load_packaged_grammar( + "blib2to3", _PATTERN_GRAMMAR_FILE, cache_dir + ) + pattern_symbols = _pattern_symbols(pattern_grammar) diff --git a/dbdpy-env/lib/python3.9/site-packages/blib2to3/pytree.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/blib2to3/pytree.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..4aa1063c2fe14cda43b75e31c165359d7f08f018 GIT binary patch literal 50136 zcmeI*Uu;uV90%}U+ieuxpo5W25n316n1O-&gCiPNWC&x(_|uprNKV@Ijx}~|>AeFg zGd3o~Ec$@SqC6?_1!j~i29rsmj0a6jjDkcY8VtsSj2NQ62?^luckj7dTLhl=VDdfW z?3~{@r@wRV=XSgu`2N<7JC#Hp;^OBzkLy$!(GeNo@)+04JgZb>Q*Xo`D*h2J4oS!5 zJnU9kp_FADvZUvf(tPdfo$>Q}UShBA+f5ne3qz$$Yba(;50&QgcQ{ka^a_a!^Z9i? zes;S!`P6`s%otf7Db2T1=X*}Cm$)z=-E+P^)5<1N`}F$Kd;>aPkDhm99Tw;2L8XRL z2NS8dN~HSJc3k{ECUm|nI)TJR=W`S5R^IC|u1a-oh-^?Bd$#X(-fmbgxKHcjX{qvs z32;?vU%KG6-Z!6ox9k#jKCdIH;Ev>Ti=1nUt8*@Ql-s=Shjm*LyXSJBS*c`HnYqDO zI;k>N_P+UQbvnskc#b(dUgpkmt5iH{MP~*|&sUpw=G^C$xG>+$C!L-=r@Skrwsmdq z-qhLU{%%b=^Ay&tjxXzE;x5%Kbu6<+f=TE1*U#@TG_VHLFNlffIlyJO3Pv%kbOP~`@S-3)@u+;S+#LD|`I+=(`-JLTnW3cJ@rg)Ac zdlA)hBYBQZIxdYmmgknTgsaSt^Z8deiDeiC0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009X6 zZv}22K09{XNAHB^QXm-e{n$b@8urp@KZS4l%js{v2YZvRX+}bN-b49a4ZJ4gq0_ey zpF2quyu^1hM?-$+^D-Zl`0m}$_)6;!vS!k!F1h>gMPYj%zBl`y`&=!b$x~Ib&wP%r zmd(ub1=4%=k!Kj6GKuRnl|q5tnk|B z{A=^sG077sCp+ib=5_6DE&cKS{^qq$8}asav1eM98q8&Kee{62rbH@XsTf~tZMM=a zN~uiF${L1qfA$GE2$#ZEuCmJA`BrYF&eiwAr7w4EEBU1axa#tttG(_Tv=D#*1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SL^pfcyX2x9fi=pi{TAye-m000Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_P#{oUN4q7g4##uJxH7Gwn2IG*aU)AR_tR0z z()zI4k=q!}m_tcJbq!|HSxd(K_P7)4;TO|!UL%tMp5#xdP9vI3ru%q^JREnW5|*NB zA02;<$g5OBVnvmioRu{UTJEEXVSToV;Q_ms;GgsSM74Qm!pqHk57F`UPP|aZ?K-aG zn5XYJvqY^Wad%1F>%{yKr}(%j<66$Of@@*SA%)0&j_KpO1NtdAEYXq$wp+1NkP-;GVgL$C$-iLtZ|)m;Vr1T; Union[str, int]: + global _type_reprs + if not _type_reprs: + from .pygram import python_symbols + + # printing tokens is possible but not as useful + # from .pgen2 import token // token.__dict__.items(): + for name in dir(python_symbols): + val = getattr(python_symbols, name) + if type(val) == int: + _type_reprs[val] = name + return _type_reprs.setdefault(type_num, type_num) + + +_P = TypeVar("_P", bound="Base") + +NL = Union["Node", "Leaf"] +Context = Tuple[str, Tuple[int, int]] +RawNode = Tuple[int, Optional[str], Optional[Context], Optional[List[NL]]] + + +class Base: + """ + Abstract base class for Node and Leaf. + + This provides some default functionality and boilerplate using the + template pattern. + + A node may be a subnode of at most one parent. + """ + + # Default values for instance variables + type: int # int: token number (< 256) or symbol number (>= 256) + parent: Optional["Node"] = None # Parent node pointer, or None + children: List[NL] # List of subnodes + was_changed: bool = False + was_checked: bool = False + + def __new__(cls, *args, **kwds): + """Constructor that prevents Base from being instantiated.""" + assert cls is not Base, "Cannot instantiate Base" + return object.__new__(cls) + + def __eq__(self, other: Any) -> bool: + """ + Compare two nodes for equality. + + This calls the method _eq(). + """ + if self.__class__ is not other.__class__: + return NotImplemented + return self._eq(other) + + @property + def prefix(self) -> str: + raise NotImplementedError + + def _eq(self: _P, other: _P) -> bool: + """ + Compare two nodes for equality. + + This is called by __eq__ and __ne__. It is only called if the two nodes + have the same type. This must be implemented by the concrete subclass. + Nodes should be considered equal if they have the same structure, + ignoring the prefix string and other context information. + """ + raise NotImplementedError + + def __deepcopy__(self: _P, memo: Any) -> _P: + return self.clone() + + def clone(self: _P) -> _P: + """ + Return a cloned (deep) copy of self. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def post_order(self) -> Iterator[NL]: + """ + Return a post-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def pre_order(self) -> Iterator[NL]: + """ + Return a pre-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def replace(self, new: Union[NL, List[NL]]) -> None: + """Replace this node with a new one in the parent.""" + assert self.parent is not None, str(self) + assert new is not None + if not isinstance(new, list): + new = [new] + l_children = [] + found = False + for ch in self.parent.children: + if ch is self: + assert not found, (self.parent.children, self, new) + if new is not None: + l_children.extend(new) + found = True + else: + l_children.append(ch) + assert found, (self.children, self, new) + self.parent.children = l_children + self.parent.changed() + self.parent.invalidate_sibling_maps() + for x in new: + x.parent = self.parent + self.parent = None + + def get_lineno(self) -> Optional[int]: + """Return the line number which generated the invocant node.""" + node = self + while not isinstance(node, Leaf): + if not node.children: + return None + node = node.children[0] + return node.lineno + + def changed(self) -> None: + if self.was_changed: + return + if self.parent: + self.parent.changed() + self.was_changed = True + + def remove(self) -> Optional[int]: + """ + Remove the node from the tree. Returns the position of the node in its + parent's children before it was removed. + """ + if self.parent: + for i, node in enumerate(self.parent.children): + if node is self: + del self.parent.children[i] + self.parent.changed() + self.parent.invalidate_sibling_maps() + self.parent = None + return i + return None + + @property + def next_sibling(self) -> Optional[NL]: + """ + The node immediately following the invocant in their parent's children + list. If the invocant does not have a next sibling, it is None + """ + if self.parent is None: + return None + + if self.parent.next_sibling_map is None: + self.parent.update_sibling_maps() + assert self.parent.next_sibling_map is not None + return self.parent.next_sibling_map[id(self)] + + @property + def prev_sibling(self) -> Optional[NL]: + """ + The node immediately preceding the invocant in their parent's children + list. If the invocant does not have a previous sibling, it is None. + """ + if self.parent is None: + return None + + if self.parent.prev_sibling_map is None: + self.parent.update_sibling_maps() + assert self.parent.prev_sibling_map is not None + return self.parent.prev_sibling_map[id(self)] + + def leaves(self) -> Iterator["Leaf"]: + for child in self.children: + yield from child.leaves() + + def depth(self) -> int: + if self.parent is None: + return 0 + return 1 + self.parent.depth() + + def get_suffix(self) -> str: + """ + Return the string immediately following the invocant node. This is + effectively equivalent to node.next_sibling.prefix + """ + next_sib = self.next_sibling + if next_sib is None: + return "" + prefix = next_sib.prefix + return prefix + + +class Node(Base): + """Concrete implementation for interior nodes.""" + + fixers_applied: Optional[List[Any]] + used_names: Optional[Set[str]] + + def __init__( + self, + type: int, + children: List[NL], + context: Optional[Any] = None, + prefix: Optional[str] = None, + fixers_applied: Optional[List[Any]] = None, + ) -> None: + """ + Initializer. + + Takes a type constant (a symbol number >= 256), a sequence of + child nodes, and an optional context keyword argument. + + As a side effect, the parent pointers of the children are updated. + """ + assert type >= 256, type + self.type = type + self.children = list(children) + for ch in self.children: + assert ch.parent is None, repr(ch) + ch.parent = self + self.invalidate_sibling_maps() + if prefix is not None: + self.prefix = prefix + if fixers_applied: + self.fixers_applied = fixers_applied[:] + else: + self.fixers_applied = None + + def __repr__(self) -> str: + """Return a canonical string representation.""" + assert self.type is not None + return "{}({}, {!r})".format( + self.__class__.__name__, + type_repr(self.type), + self.children, + ) + + def __str__(self) -> str: + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return "".join(map(str, self.children)) + + def _eq(self, other: Base) -> bool: + """Compare two nodes for equality.""" + return (self.type, self.children) == (other.type, other.children) + + def clone(self) -> "Node": + assert self.type is not None + """Return a cloned (deep) copy of self.""" + return Node( + self.type, + [ch.clone() for ch in self.children], + fixers_applied=self.fixers_applied, + ) + + def post_order(self) -> Iterator[NL]: + """Return a post-order iterator for the tree.""" + for child in self.children: + yield from child.post_order() + yield self + + def pre_order(self) -> Iterator[NL]: + """Return a pre-order iterator for the tree.""" + yield self + for child in self.children: + yield from child.pre_order() + + @property + def prefix(self) -> str: + """ + The whitespace and comments preceding this node in the input. + """ + if not self.children: + return "" + return self.children[0].prefix + + @prefix.setter + def prefix(self, prefix: str) -> None: + if self.children: + self.children[0].prefix = prefix + + def set_child(self, i: int, child: NL) -> None: + """ + Equivalent to 'node.children[i] = child'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children[i].parent = None + self.children[i] = child + self.changed() + self.invalidate_sibling_maps() + + def insert_child(self, i: int, child: NL) -> None: + """ + Equivalent to 'node.children.insert(i, child)'. This method also sets + the child's parent attribute appropriately. + """ + child.parent = self + self.children.insert(i, child) + self.changed() + self.invalidate_sibling_maps() + + def append_child(self, child: NL) -> None: + """ + Equivalent to 'node.children.append(child)'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children.append(child) + self.changed() + self.invalidate_sibling_maps() + + def invalidate_sibling_maps(self) -> None: + self.prev_sibling_map: Optional[Dict[int, Optional[NL]]] = None + self.next_sibling_map: Optional[Dict[int, Optional[NL]]] = None + + def update_sibling_maps(self) -> None: + _prev: Dict[int, Optional[NL]] = {} + _next: Dict[int, Optional[NL]] = {} + self.prev_sibling_map = _prev + self.next_sibling_map = _next + previous: Optional[NL] = None + for current in self.children: + _prev[id(current)] = previous + _next[id(previous)] = current + previous = current + _next[id(current)] = None + + +class Leaf(Base): + """Concrete implementation for leaf nodes.""" + + # Default values for instance variables + value: str + fixers_applied: List[Any] + bracket_depth: int + # Changed later in brackets.py + opening_bracket: Optional["Leaf"] = None + used_names: Optional[Set[str]] + _prefix = "" # Whitespace and comments preceding this token in the input + lineno: int = 0 # Line where this token starts in the input + column: int = 0 # Column where this token starts in the input + # If not None, this Leaf is created by converting a block of fmt off/skip + # code, and `fmt_pass_converted_first_leaf` points to the first Leaf in the + # converted code. + fmt_pass_converted_first_leaf: Optional["Leaf"] = None + + def __init__( + self, + type: int, + value: str, + context: Optional[Context] = None, + prefix: Optional[str] = None, + fixers_applied: List[Any] = [], + opening_bracket: Optional["Leaf"] = None, + fmt_pass_converted_first_leaf: Optional["Leaf"] = None, + ) -> None: + """ + Initializer. + + Takes a type constant (a token number < 256), a string value, and an + optional context keyword argument. + """ + + assert 0 <= type < 256, type + if context is not None: + self._prefix, (self.lineno, self.column) = context + self.type = type + self.value = value + if prefix is not None: + self._prefix = prefix + self.fixers_applied: Optional[List[Any]] = fixers_applied[:] + self.children = [] + self.opening_bracket = opening_bracket + self.fmt_pass_converted_first_leaf = fmt_pass_converted_first_leaf + + def __repr__(self) -> str: + """Return a canonical string representation.""" + from .pgen2.token import tok_name + + assert self.type is not None + return "{}({}, {!r})".format( + self.__class__.__name__, + tok_name.get(self.type, self.type), + self.value, + ) + + def __str__(self) -> str: + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return self._prefix + str(self.value) + + def _eq(self, other: "Leaf") -> bool: + """Compare two nodes for equality.""" + return (self.type, self.value) == (other.type, other.value) + + def clone(self) -> "Leaf": + assert self.type is not None + """Return a cloned (deep) copy of self.""" + return Leaf( + self.type, + self.value, + (self.prefix, (self.lineno, self.column)), + fixers_applied=self.fixers_applied, + ) + + def leaves(self) -> Iterator["Leaf"]: + yield self + + def post_order(self) -> Iterator["Leaf"]: + """Return a post-order iterator for the tree.""" + yield self + + def pre_order(self) -> Iterator["Leaf"]: + """Return a pre-order iterator for the tree.""" + yield self + + @property + def prefix(self) -> str: + """ + The whitespace and comments preceding this token in the input. + """ + return self._prefix + + @prefix.setter + def prefix(self, prefix: str) -> None: + self.changed() + self._prefix = prefix + + +def convert(gr: Grammar, raw_node: RawNode) -> NL: + """ + Convert raw node information to a Node or Leaf instance. + + This is passed to the parser driver which calls it whenever a reduction of a + grammar rule produces a new complete node, so that the tree is build + strictly bottom-up. + """ + type, value, context, children = raw_node + if children or type in gr.number2symbol: + # If there's exactly one child, return that child instead of + # creating a new node. + assert children is not None + if len(children) == 1: + return children[0] + return Node(type, children, context=context) + else: + return Leaf(type, value or "", context=context) + + +_Results = Dict[str, NL] + + +class BasePattern: + """ + A pattern is a tree matching pattern. + + It looks for a specific node type (token or symbol), and + optionally for a specific content. + + This is an abstract base class. There are three concrete + subclasses: + + - LeafPattern matches a single leaf node; + - NodePattern matches a single node (usually non-leaf); + - WildcardPattern matches a sequence of nodes of variable length. + """ + + # Defaults for instance variables + type: Optional[int] + type = None # Node type (token if < 256, symbol if >= 256) + content: Any = None # Optional content matching pattern + name: Optional[str] = None # Optional name used to store match in results dict + + def __new__(cls, *args, **kwds): + """Constructor that prevents BasePattern from being instantiated.""" + assert cls is not BasePattern, "Cannot instantiate BasePattern" + return object.__new__(cls) + + def __repr__(self) -> str: + assert self.type is not None + args = [type_repr(self.type), self.content, self.name] + while args and args[-1] is None: + del args[-1] + return "{}({})".format(self.__class__.__name__, ", ".join(map(repr, args))) + + def _submatch(self, node, results=None) -> bool: + raise NotImplementedError + + def optimize(self) -> "BasePattern": + """ + A subclass can define this as a hook for optimizations. + + Returns either self or another node with the same effect. + """ + return self + + def match(self, node: NL, results: Optional[_Results] = None) -> bool: + """ + Does this pattern exactly match a node? + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + Default implementation for non-wildcard patterns. + """ + if self.type is not None and node.type != self.type: + return False + if self.content is not None: + r: Optional[_Results] = None + if results is not None: + r = {} + if not self._submatch(node, r): + return False + if r: + assert results is not None + results.update(r) + if results is not None and self.name: + results[self.name] = node + return True + + def match_seq(self, nodes: List[NL], results: Optional[_Results] = None) -> bool: + """ + Does this pattern exactly match a sequence of nodes? + + Default implementation for non-wildcard patterns. + """ + if len(nodes) != 1: + return False + return self.match(nodes[0], results) + + def generate_matches(self, nodes: List[NL]) -> Iterator[Tuple[int, _Results]]: + """ + Generator yielding all matches for this pattern. + + Default implementation for non-wildcard patterns. + """ + r: _Results = {} + if nodes and self.match(nodes[0], r): + yield 1, r + + +class LeafPattern(BasePattern): + def __init__( + self, + type: Optional[int] = None, + content: Optional[str] = None, + name: Optional[str] = None, + ) -> None: + """ + Initializer. Takes optional type, content, and name. + + The type, if given must be a token type (< 256). If not given, + this matches any *leaf* node; the content may still be required. + + The content, if given, must be a string. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert 0 <= type < 256, type + if content is not None: + assert isinstance(content, str), repr(content) + self.type = type + self.content = content + self.name = name + + def match(self, node: NL, results=None) -> bool: + """Override match() to insist on a leaf node.""" + if not isinstance(node, Leaf): + return False + return BasePattern.match(self, node, results) + + def _submatch(self, node, results=None): + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + return self.content == node.value + + +class NodePattern(BasePattern): + wildcards: bool = False + + def __init__( + self, + type: Optional[int] = None, + content: Optional[Iterable[str]] = None, + name: Optional[str] = None, + ) -> None: + """ + Initializer. Takes optional type, content, and name. + + The type, if given, must be a symbol type (>= 256). If the + type is None this matches *any* single node (leaf or not), + except if content is not None, in which it only matches + non-leaf nodes that also match the content pattern. + + The content, if not None, must be a sequence of Patterns that + must match the node's children exactly. If the content is + given, the type must not be None. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert type >= 256, type + if content is not None: + assert not isinstance(content, str), repr(content) + newcontent = list(content) + for i, item in enumerate(newcontent): + assert isinstance(item, BasePattern), (i, item) + # I don't even think this code is used anywhere, but it does cause + # unreachable errors from mypy. This function's signature does look + # odd though *shrug*. + if isinstance(item, WildcardPattern): # type: ignore[unreachable] + self.wildcards = True # type: ignore[unreachable] + self.type = type + self.content = newcontent # TODO: this is unbound when content is None + self.name = name + + def _submatch(self, node, results=None) -> bool: + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + if self.wildcards: + for c, r in generate_matches(self.content, node.children): + if c == len(node.children): + if results is not None: + results.update(r) + return True + return False + if len(self.content) != len(node.children): + return False + for subpattern, child in zip(self.content, node.children): + if not subpattern.match(child, results): + return False + return True + + +class WildcardPattern(BasePattern): + """ + A wildcard pattern can match zero or more nodes. + + This has all the flexibility needed to implement patterns like: + + .* .+ .? .{m,n} + (a b c | d e | f) + (...)* (...)+ (...)? (...){m,n} + + except it always uses non-greedy matching. + """ + + min: int + max: int + + def __init__( + self, + content: Optional[str] = None, + min: int = 0, + max: int = HUGE, + name: Optional[str] = None, + ) -> None: + """ + Initializer. + + Args: + content: optional sequence of subsequences of patterns; + if absent, matches one node; + if present, each subsequence is an alternative [*] + min: optional minimum number of times to match, default 0 + max: optional maximum number of times to match, default HUGE + name: optional name assigned to this match + + [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is + equivalent to (a b c | d e | f g h); if content is None, + this is equivalent to '.' in regular expression terms. + The min and max parameters work as follows: + min=0, max=maxint: .* + min=1, max=maxint: .+ + min=0, max=1: .? + min=1, max=1: . + If content is not None, replace the dot with the parenthesized + list of alternatives, e.g. (a b c | d e | f g h)* + """ + assert 0 <= min <= max <= HUGE, (min, max) + if content is not None: + f = lambda s: tuple(s) + wrapped_content = tuple(map(f, content)) # Protect against alterations + # Check sanity of alternatives + assert len(wrapped_content), repr( + wrapped_content + ) # Can't have zero alternatives + for alt in wrapped_content: + assert len(alt), repr(alt) # Can have empty alternatives + self.content = wrapped_content + self.min = min + self.max = max + self.name = name + + def optimize(self) -> Any: + """Optimize certain stacked wildcard patterns.""" + subpattern = None + if ( + self.content is not None + and len(self.content) == 1 + and len(self.content[0]) == 1 + ): + subpattern = self.content[0][0] + if self.min == 1 and self.max == 1: + if self.content is None: + return NodePattern(name=self.name) + if subpattern is not None and self.name == subpattern.name: + return subpattern.optimize() + if ( + self.min <= 1 + and isinstance(subpattern, WildcardPattern) + and subpattern.min <= 1 + and self.name == subpattern.name + ): + return WildcardPattern( + subpattern.content, + self.min * subpattern.min, + self.max * subpattern.max, + subpattern.name, + ) + return self + + def match(self, node, results=None) -> bool: + """Does this pattern exactly match a node?""" + return self.match_seq([node], results) + + def match_seq(self, nodes, results=None) -> bool: + """Does this pattern exactly match a sequence of nodes?""" + for c, r in self.generate_matches(nodes): + if c == len(nodes): + if results is not None: + results.update(r) + if self.name: + results[self.name] = list(nodes) + return True + return False + + def generate_matches(self, nodes) -> Iterator[Tuple[int, _Results]]: + """ + Generator yielding matches for a sequence of nodes. + + Args: + nodes: sequence of nodes + + Yields: + (count, results) tuples where: + count: the match comprises nodes[:count]; + results: dict containing named submatches. + """ + if self.content is None: + # Shortcut for special case (see __init__.__doc__) + for count in range(self.min, 1 + min(len(nodes), self.max)): + r = {} + if self.name: + r[self.name] = nodes[:count] + yield count, r + elif self.name == "bare_name": + yield self._bare_name_matches(nodes) + else: + # The reason for this is that hitting the recursion limit usually + # results in some ugly messages about how RuntimeErrors are being + # ignored. We only have to do this on CPython, though, because other + # implementations don't have this nasty bug in the first place. + if hasattr(sys, "getrefcount"): + save_stderr = sys.stderr + sys.stderr = StringIO() + try: + for count, r in self._recursive_matches(nodes, 0): + if self.name: + r[self.name] = nodes[:count] + yield count, r + except RuntimeError: + # We fall back to the iterative pattern matching scheme if the recursive + # scheme hits the recursion limit. + for count, r in self._iterative_matches(nodes): + if self.name: + r[self.name] = nodes[:count] + yield count, r + finally: + if hasattr(sys, "getrefcount"): + sys.stderr = save_stderr + + def _iterative_matches(self, nodes) -> Iterator[Tuple[int, _Results]]: + """Helper to iteratively yield the matches.""" + nodelen = len(nodes) + if 0 >= self.min: + yield 0, {} + + results = [] + # generate matches that use just one alt from self.content + for alt in self.content: + for c, r in generate_matches(alt, nodes): + yield c, r + results.append((c, r)) + + # for each match, iterate down the nodes + while results: + new_results = [] + for c0, r0 in results: + # stop if the entire set of nodes has been matched + if c0 < nodelen and c0 <= self.max: + for alt in self.content: + for c1, r1 in generate_matches(alt, nodes[c0:]): + if c1 > 0: + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + new_results.append((c0 + c1, r)) + results = new_results + + def _bare_name_matches(self, nodes) -> Tuple[int, _Results]: + """Special optimized matcher for bare_name.""" + count = 0 + r = {} # type: _Results + done = False + max = len(nodes) + while not done and count < max: + done = True + for leaf in self.content: + if leaf[0].match(nodes[count], r): + count += 1 + done = False + break + assert self.name is not None + r[self.name] = nodes[:count] + return count, r + + def _recursive_matches(self, nodes, count) -> Iterator[Tuple[int, _Results]]: + """Helper to recursively yield the matches.""" + assert self.content is not None + if count >= self.min: + yield 0, {} + if count < self.max: + for alt in self.content: + for c0, r0 in generate_matches(alt, nodes): + for c1, r1 in self._recursive_matches(nodes[c0:], count + 1): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + + +class NegatedPattern(BasePattern): + def __init__(self, content: Optional[BasePattern] = None) -> None: + """ + Initializer. + + The argument is either a pattern or None. If it is None, this + only matches an empty sequence (effectively '$' in regex + lingo). If it is not None, this matches whenever the argument + pattern doesn't have any matches. + """ + if content is not None: + assert isinstance(content, BasePattern), repr(content) + self.content = content + + def match(self, node, results=None) -> bool: + # We never match a node in its entirety + return False + + def match_seq(self, nodes, results=None) -> bool: + # We only match an empty sequence of nodes in its entirety + return len(nodes) == 0 + + def generate_matches(self, nodes: List[NL]) -> Iterator[Tuple[int, _Results]]: + if self.content is None: + # Return a match if there is an empty sequence + if len(nodes) == 0: + yield 0, {} + else: + # Return a match if the argument pattern has no matches + for c, r in self.content.generate_matches(nodes): + return + yield 0, {} + + +def generate_matches( + patterns: List[BasePattern], nodes: List[NL] +) -> Iterator[Tuple[int, _Results]]: + """ + Generator yielding matches for a sequence of patterns and nodes. + + Args: + patterns: a sequence of patterns + nodes: a sequence of nodes + + Yields: + (count, results) tuples where: + count: the entire sequence of patterns matches nodes[:count]; + results: dict containing named submatches. + """ + if not patterns: + yield 0, {} + else: + p, rest = patterns[0], patterns[1:] + for c0, r0 in p.generate_matches(nodes): + if not rest: + yield c0, r0 + else: + for c1, r1 in generate_matches(rest, nodes[c0:]): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 00000000..d12a8491 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 00000000..7a6bbb24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 00000000..66855531 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/_compat.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/_termui_impl.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/_textwrap.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/_winconsole.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/core.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/decorators.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/exceptions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/formatting.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/globals.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/parser.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/shell_completion.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/termui.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/testing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/types.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/click/utils.cpython-39.pyc,, +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/_compat.py,sha256=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 00000000..2c08da08 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 00000000..dca9a909 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/dbdpy-env/lib/python3.9/site-packages/click/__init__.py b/dbdpy-env/lib/python3.9/site-packages/click/__init__.py new file mode 100644 index 00000000..9a1dab04 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.7" diff --git a/dbdpy-env/lib/python3.9/site-packages/click/_compat.py b/dbdpy-env/lib/python3.9/site-packages/click/_compat.py new file mode 100644 index 00000000..23f88665 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( # noqa: F811 + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/dbdpy-env/lib/python3.9/site-packages/click/_termui_impl.py b/dbdpy-env/lib/python3.9/site-packages/click/_termui_impl.py new file mode 100644 index 00000000..f7446577 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/dbdpy-env/lib/python3.9/site-packages/click/_textwrap.py b/dbdpy-env/lib/python3.9/site-packages/click/_textwrap.py new file mode 100644 index 00000000..b47dcbd4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/_winconsole.py b/dbdpy-env/lib/python3.9/site-packages/click/_winconsole.py new file mode 100644 index 00000000..6b20df31 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/core.py b/dbdpy-env/lib/python3.9/site-packages/click/core.py new file mode 100644 index 00000000..cc65e896 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/core.py @@ -0,0 +1,3042 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/decorators.py b/dbdpy-env/lib/python3.9/site-packages/click/decorators.py new file mode 100644 index 00000000..d9bba950 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator # type: ignore[return-value] + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/exceptions.py b/dbdpy-env/lib/python3.9/site-packages/click/exceptions.py new file mode 100644 index 00000000..fe68a361 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/dbdpy-env/lib/python3.9/site-packages/click/formatting.py b/dbdpy-env/lib/python3.9/site-packages/click/formatting.py new file mode 100644 index 00000000..ddd2a2f8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/dbdpy-env/lib/python3.9/site-packages/click/globals.py b/dbdpy-env/lib/python3.9/site-packages/click/globals.py new file mode 100644 index 00000000..480058f1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/click/parser.py b/dbdpy-env/lib/python3.9/site-packages/click/parser.py new file mode 100644 index 00000000..5fa7adfa --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/py.typed b/dbdpy-env/lib/python3.9/site-packages/click/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/click/shell_completion.py b/dbdpy-env/lib/python3.9/site-packages/click/shell_completion.py new file mode 100644 index 00000000..dc9e00b9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/dbdpy-env/lib/python3.9/site-packages/click/termui.py b/dbdpy-env/lib/python3.9/site-packages/click/termui.py new file mode 100644 index 00000000..db7a4b28 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/dbdpy-env/lib/python3.9/site-packages/click/testing.py b/dbdpy-env/lib/python3.9/site-packages/click/testing.py new file mode 100644 index 00000000..e0df0d2a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/click/types.py b/dbdpy-env/lib/python3.9/site-packages/click/types.py new file mode 100644 index 00000000..2b1d1797 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/types.py @@ -0,0 +1,1089 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/dbdpy-env/lib/python3.9/site-packages/click/utils.py b/dbdpy-env/lib/python3.9/site-packages/click/utils.py new file mode 100644 index 00000000..d536434f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/LICENSE new file mode 100644 index 00000000..90f83c97 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021-2023, ContourPy Developers. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/METADATA new file mode 100644 index 00000000..ae131f08 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/METADATA @@ -0,0 +1,91 @@ +Metadata-Version: 2.1 +Name: contourpy +Version: 1.2.0 +Summary: Python library for calculating contours of 2D quadrilateral grids +Author-Email: Ian Thomas +License: BSD 3-Clause License + + Copyright (c) 2021-2023, ContourPy Developers. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: C++ +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Scientific/Engineering :: Information Analysis +Classifier: Topic :: Scientific/Engineering :: Mathematics +Classifier: Topic :: Scientific/Engineering :: Visualization +Project-URL: Homepage, https://github.com/contourpy/contourpy +Project-URL: Changelog, https://contourpy.readthedocs.io/en/latest/changelog.html +Project-URL: Documentation, https://contourpy.readthedocs.io +Project-URL: Repository, https://github.com/contourpy/contourpy +Requires-Python: >=3.9 +Requires-Dist: numpy<2.0,>=1.20 +Requires-Dist: furo; extra == "docs" +Requires-Dist: sphinx>=7.2; extra == "docs" +Requires-Dist: sphinx-copybutton; extra == "docs" +Requires-Dist: bokeh; extra == "bokeh" +Requires-Dist: selenium; extra == "bokeh" +Requires-Dist: contourpy[bokeh,docs]; extra == "mypy" +Requires-Dist: docutils-stubs; extra == "mypy" +Requires-Dist: mypy==1.6.1; extra == "mypy" +Requires-Dist: types-Pillow; extra == "mypy" +Requires-Dist: contourpy[test-no-images]; extra == "test" +Requires-Dist: matplotlib; extra == "test" +Requires-Dist: Pillow; extra == "test" +Requires-Dist: pytest; extra == "test-no-images" +Requires-Dist: pytest-cov; extra == "test-no-images" +Requires-Dist: pytest-xdist; extra == "test-no-images" +Requires-Dist: wurlitzer; extra == "test-no-images" +Provides-Extra: docs +Provides-Extra: bokeh +Provides-Extra: mypy +Provides-Extra: test +Provides-Extra: test-no-images +Description-Content-Type: text/markdown + +ContourPy + +ContourPy is a Python library for calculating contours of 2D quadrilateral grids. It is written in C++11 and wrapped using pybind11. + +It contains the 2005 and 2014 algorithms used in Matplotlib as well as a newer algorithm that includes more features and is available in both serial and multithreaded versions. It provides an easy way for Python libraries to use contouring algorithms without having to include Matplotlib as a dependency. + + * **Documentation**: https://contourpy.readthedocs.io + * **Source code**: https://github.com/contourpy/contourpy + +| | | +| --- | --- | +| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) [![anaconda version](https://img.shields.io/conda/v/anaconda/contourpy.svg?label=anaconda&color=1a9641)](https://anaconda.org/anaconda/contourpy) | +| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) [![conda-forge downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_conda-forge_monthly.svg)](https://anaconda.org/conda-forge/contourpy) [![anaconda downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_anaconda_monthly.svg)](https://anaconda.org/anaconda/contourpy) | +| Python version | [![Platforms](https://img.shields.io/pypi/pyversions/contourpy?color=fdae61)](https://pypi.org/project/contourpy/) | +| Coverage | [![Codecov](https://img.shields.io/codecov/c/gh/contourpy/contourpy?color=fdae61&label=codecov)](https://app.codecov.io/gh/contourpy/contourpy) | diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/RECORD new file mode 100644 index 00000000..3ca05927 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/RECORD @@ -0,0 +1,42 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/_version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/array.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/chunk.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/convert.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/dechunk.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/enum_util.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/typecheck.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/types.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/_build_config.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_renderer.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_util.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/data.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_renderer.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_util.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/contourpy/util/renderer.cpython-39.pyc,, +contourpy-1.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +contourpy-1.2.0.dist-info/LICENSE,sha256=wlIhVrp9Tfu-wmbf6pi_dqabxB7bGMrTIxd_rWsZs18,1534 +contourpy-1.2.0.dist-info/METADATA,sha256=JW30mmlS9Ap5mgMbdu5Fm7IQCRAhPjnXPkTcqfLN0Eg,5807 +contourpy-1.2.0.dist-info/RECORD,, +contourpy-1.2.0.dist-info/WHEEL,sha256=rFEbl7VGpdcTiWMLyPHKRieKvxwiToMCxVXFuj50F_A,91 +contourpy/__init__.py,sha256=qKoGLA4Q5-E-rCX9yWnkaAM3uX87Kff-E1vXXHO5AyI,11319 +contourpy/_contourpy.cpython-39-darwin.so,sha256=Y6UhNMJTRnyH2jdvNm2zyJjkcCF87dWDJcQ0VcZxWx0,707980 +contourpy/_contourpy.pyi,sha256=qCJj74hNvncMCfYN8n4YghbWd8I4-87wdpQRwoJBMuU,7111 +contourpy/_version.py,sha256=MpAT5hgNoHnTtG1XRD_GV_A7QrHVU6vJjGSw_8qMGA4,22 +contourpy/array.py,sha256=fNp-o8odWzqANFoT2J5ueMW7q7y1vSJkjzkEUYN4B-Q,9012 +contourpy/chunk.py,sha256=8njDQqlpuD22RjaaCyA75FXQsSQDY5hZGJSrxFpvGGU,3279 +contourpy/convert.py,sha256=AuHThR7s-VJIvUBydcwYiRs2WrlDvxY_5eQnHSlI7v8,23398 +contourpy/dechunk.py,sha256=7YDjPF2-fzttXJqvsGBkYfie6ZFawMoTdNaCc1o6WPE,5490 +contourpy/enum_util.py,sha256=o8MItJRs08oqzwPP3IwC75BBAY9Qq95saIzjkXBXwqA,1519 +contourpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +contourpy/typecheck.py,sha256=-V-U7Rs0LxDxDEd_rdKJM321nd4PrxV2ZX3DeChWo6E,10746 +contourpy/types.py,sha256=2K4T5tJpMIjYrkkg1Lqh3C2ZKlnOhnMtYmtwz92l_y8,247 +contourpy/util/__init__.py,sha256=eVhJ_crOHL7nkG4Kb0dOo7NL4WHMy_Px665aAN_3d-8,118 +contourpy/util/_build_config.py,sha256=rhWEzDkOBwM3_BEROPLVCjTvVZlQ_w_yicxB30gMaV0,2099 +contourpy/util/bokeh_renderer.py,sha256=OS-n5xqydxmdQ64FYmHOAaw_1PqP5JA-ihy0nEgtzgU,13848 +contourpy/util/bokeh_util.py,sha256=g7Lr_Wo8hZsgVrCdkdwXCBMXBV5SVocmUznoXUftPxI,2780 +contourpy/util/data.py,sha256=cPSAk3pUlg1N4uTp4chzXZLjR5uXnFa2h3adXn-_DJg,2566 +contourpy/util/mpl_renderer.py,sha256=VWnpAvGelCDkx7w4RS1JWArSKgACQojqHNarC8TbUDM,20013 +contourpy/util/mpl_util.py,sha256=q2OO2gGSO7bYgpNj3DCJtRUC8BjuBSrQClrZ92trT0U,3438 +contourpy/util/renderer.py,sha256=scRiAvbLo6jrDxT3AJ9cO-5PTtpL5BXRfGNt1Vxv7QI,2367 diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/WHEEL new file mode 100644 index 00000000..7991c975 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy-1.2.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: meson +Root-Is-Purelib: false +Tag: cp39-cp39-macosx_11_0_arm64 \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/__init__.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/__init__.py new file mode 100644 index 00000000..7b85874c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/__init__.py @@ -0,0 +1,262 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np + +from contourpy._contourpy import ( + ContourGenerator, FillType, LineType, Mpl2005ContourGenerator, Mpl2014ContourGenerator, + SerialContourGenerator, ThreadedContourGenerator, ZInterp, max_threads, +) +from contourpy._version import __version__ +from contourpy.chunk import calc_chunk_sizes +from contourpy.convert import convert_filled, convert_lines +from contourpy.dechunk import dechunk_filled, dechunk_lines +from contourpy.enum_util import as_fill_type, as_line_type, as_z_interp + +if TYPE_CHECKING: + from typing import Any + + from numpy.typing import ArrayLike + + from ._contourpy import CoordinateArray, MaskArray + +__all__ = [ + "__version__", + "contour_generator", + "convert_filled", + "convert_lines", + "dechunk_filled", + "dechunk_lines", + "max_threads", + "FillType", + "LineType", + "ContourGenerator", + "Mpl2005ContourGenerator", + "Mpl2014ContourGenerator", + "SerialContourGenerator", + "ThreadedContourGenerator", + "ZInterp", +] + + +# Simple mapping of algorithm name to class name. +_class_lookup: dict[str, type[ContourGenerator]] = dict( + mpl2005=Mpl2005ContourGenerator, + mpl2014=Mpl2014ContourGenerator, + serial=SerialContourGenerator, + threaded=ThreadedContourGenerator, +) + + +def _remove_z_mask( + z: ArrayLike | np.ma.MaskedArray[Any, Any] | None, +) -> tuple[CoordinateArray, MaskArray | None]: + # Preserve mask if present. + z_array = np.ma.asarray(z, dtype=np.float64) # type: ignore[no-untyped-call] + z_masked = np.ma.masked_invalid(z_array, copy=False) # type: ignore[no-untyped-call] + + if np.ma.is_masked(z_masked): # type: ignore[no-untyped-call] + mask = np.ma.getmask(z_masked) # type: ignore[no-untyped-call] + else: + mask = None + + return np.ma.getdata(z_masked), mask # type: ignore[no-untyped-call] + + +def contour_generator( + x: ArrayLike | None = None, + y: ArrayLike | None = None, + z: ArrayLike | np.ma.MaskedArray[Any, Any] | None = None, + *, + name: str = "serial", + corner_mask: bool | None = None, + line_type: LineType | str | None = None, + fill_type: FillType | str | None = None, + chunk_size: int | tuple[int, int] | None = None, + chunk_count: int | tuple[int, int] | None = None, + total_chunk_count: int | None = None, + quad_as_tri: bool = False, + z_interp: ZInterp | str | None = ZInterp.Linear, + thread_count: int = 0, +) -> ContourGenerator: + """Create and return a :class:`~contourpy._contourpy.ContourGenerator` object. + + The class and properties of the returned :class:`~contourpy._contourpy.ContourGenerator` are + determined by the function arguments, with sensible defaults. + + Args: + x (array-like of shape (ny, nx) or (nx,), optional): The x-coordinates of the ``z`` values. + May be 2D with the same shape as ``z.shape``, or 1D with length ``nx = z.shape[1]``. + If not specified are assumed to be ``np.arange(nx)``. Must be ordered monotonically. + y (array-like of shape (ny, nx) or (ny,), optional): The y-coordinates of the ``z`` values. + May be 2D with the same shape as ``z.shape``, or 1D with length ``ny = z.shape[0]``. + If not specified are assumed to be ``np.arange(ny)``. Must be ordered monotonically. + z (array-like of shape (ny, nx), may be a masked array): The 2D gridded values to calculate + the contours of. May be a masked array, and any invalid values (``np.inf`` or + ``np.nan``) will also be masked out. + name (str): Algorithm name, one of ``"serial"``, ``"threaded"``, ``"mpl2005"`` or + ``"mpl2014"``, default ``"serial"``. + corner_mask (bool, optional): Enable/disable corner masking, which only has an effect if + ``z`` is a masked array. If ``False``, any quad touching a masked point is masked out. + If ``True``, only the triangular corners of quads nearest these points are always masked + out, other triangular corners comprising three unmasked points are contoured as usual. + If not specified, uses the default provided by the algorithm ``name``. + line_type (LineType or str, optional): The format of contour line data returned from calls + to :meth:`~contourpy.ContourGenerator.lines`, specified either as a + :class:`~contourpy.LineType` or its string equivalent such as ``"SeparateCode"``. + If not specified, uses the default provided by the algorithm ``name``. + fill_type (FillType or str, optional): The format of filled contour data returned from calls + to :meth:`~contourpy.ContourGenerator.filled`, specified either as a + :class:`~contourpy.FillType` or its string equivalent such as ``"OuterOffset"``. + If not specified, uses the default provided by the algorithm ``name``. + chunk_size (int or tuple(int, int), optional): Chunk size in (y, x) directions, or the same + size in both directions if only one value is specified. + chunk_count (int or tuple(int, int), optional): Chunk count in (y, x) directions, or the + same count in both directions if only one value is specified. + total_chunk_count (int, optional): Total number of chunks. + quad_as_tri (bool): Enable/disable treating quads as 4 triangles, default ``False``. + If ``False``, a contour line within a quad is a straight line between points on two of + its edges. If ``True``, each full quad is divided into 4 triangles using a virtual point + at the centre (mean x, y of the corner points) and a contour line is piecewise linear + within those triangles. Corner-masked triangles are not affected by this setting, only + full unmasked quads. + z_interp (ZInterp or str, optional): How to interpolate ``z`` values when determining where + contour lines intersect the edges of quads and the ``z`` values of the central points of + quads, specified either as a :class:`~contourpy.ZInterp` or its string equivalent such + as ``"Log"``. Default is ``ZInterp.Linear``. + thread_count (int): Number of threads to use for contour calculation, default 0. Threads can + only be used with an algorithm ``name`` that supports threads (currently only + ``name="threaded"``) and there must be at least the same number of chunks as threads. + If ``thread_count=0`` and ``name="threaded"`` then it uses the maximum number of threads + as determined by the C++11 call ``std::thread::hardware_concurrency()``. If ``name`` is + something other than ``"threaded"`` then the ``thread_count`` will be set to ``1``. + + Return: + :class:`~contourpy._contourpy.ContourGenerator`. + + Note: + A maximum of one of ``chunk_size``, ``chunk_count`` and ``total_chunk_count`` may be + specified. + + Warning: + The ``name="mpl2005"`` algorithm does not implement chunking for contour lines. + """ + x = np.asarray(x, dtype=np.float64) + y = np.asarray(y, dtype=np.float64) + z, mask = _remove_z_mask(z) + + # Check arguments: z. + if z.ndim != 2: + raise TypeError(f"Input z must be 2D, not {z.ndim}D") + + if z.shape[0] < 2 or z.shape[1] < 2: + raise TypeError(f"Input z must be at least a (2, 2) shaped array, but has shape {z.shape}") + + ny, nx = z.shape + + # Check arguments: x and y. + if x.ndim != y.ndim: + raise TypeError(f"Number of dimensions of x ({x.ndim}) and y ({y.ndim}) do not match") + + if x.ndim == 0: + x = np.arange(nx, dtype=np.float64) + y = np.arange(ny, dtype=np.float64) + x, y = np.meshgrid(x, y) + elif x.ndim == 1: + if len(x) != nx: + raise TypeError(f"Length of x ({len(x)}) must match number of columns in z ({nx})") + if len(y) != ny: + raise TypeError(f"Length of y ({len(y)}) must match number of rows in z ({ny})") + x, y = np.meshgrid(x, y) + elif x.ndim == 2: + if x.shape != z.shape: + raise TypeError(f"Shapes of x {x.shape} and z {z.shape} do not match") + if y.shape != z.shape: + raise TypeError(f"Shapes of y {y.shape} and z {z.shape} do not match") + else: + raise TypeError(f"Inputs x and y must be None, 1D or 2D, not {x.ndim}D") + + # Check mask shape just in case. + if mask is not None and mask.shape != z.shape: + raise ValueError("If mask is set it must be a 2D array with the same shape as z") + + # Check arguments: name. + if name not in _class_lookup: + raise ValueError(f"Unrecognised contour generator name: {name}") + + # Check arguments: chunk_size, chunk_count and total_chunk_count. + y_chunk_size, x_chunk_size = calc_chunk_sizes( + chunk_size, chunk_count, total_chunk_count, ny, nx) + + cls = _class_lookup[name] + + # Check arguments: corner_mask. + if corner_mask is None: + # Set it to default, which is True if the algorithm supports it. + corner_mask = cls.supports_corner_mask() + elif corner_mask and not cls.supports_corner_mask(): + raise ValueError(f"{name} contour generator does not support corner_mask=True") + + # Check arguments: line_type. + if line_type is None: + line_type = cls.default_line_type + else: + line_type = as_line_type(line_type) + + if not cls.supports_line_type(line_type): + raise ValueError(f"{name} contour generator does not support line_type {line_type}") + + # Check arguments: fill_type. + if fill_type is None: + fill_type = cls.default_fill_type + else: + fill_type = as_fill_type(fill_type) + + if not cls.supports_fill_type(fill_type): + raise ValueError(f"{name} contour generator does not support fill_type {fill_type}") + + # Check arguments: quad_as_tri. + if quad_as_tri and not cls.supports_quad_as_tri(): + raise ValueError(f"{name} contour generator does not support quad_as_tri=True") + + # Check arguments: z_interp. + if z_interp is None: + z_interp = ZInterp.Linear + else: + z_interp = as_z_interp(z_interp) + + if z_interp != ZInterp.Linear and not cls.supports_z_interp(): + raise ValueError(f"{name} contour generator does not support z_interp {z_interp}") + + # Check arguments: thread_count. + if thread_count not in (0, 1) and not cls.supports_threads(): + raise ValueError(f"{name} contour generator does not support thread_count {thread_count}") + + # Prepare args and kwargs for contour generator constructor. + args = [x, y, z, mask] + kwargs: dict[str, int | bool | LineType | FillType | ZInterp] = { + "x_chunk_size": x_chunk_size, + "y_chunk_size": y_chunk_size, + } + + if name not in ("mpl2005", "mpl2014"): + kwargs["line_type"] = line_type + kwargs["fill_type"] = fill_type + + if cls.supports_corner_mask(): + kwargs["corner_mask"] = corner_mask + + if cls.supports_quad_as_tri(): + kwargs["quad_as_tri"] = quad_as_tri + + if cls.supports_z_interp(): + kwargs["z_interp"] = z_interp + + if cls.supports_threads(): + kwargs["thread_count"] = thread_count + + # Create contour generator. + cont_gen = cls(*args, **kwargs) + + return cont_gen diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/_contourpy.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/contourpy/_contourpy.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..09a82631c831cdb926d516031a996b9784b0799e GIT binary patch literal 707980 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

rVbY&!(yA`vgFqiuEF|O@O-=nOBR7XF1t+0 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 z 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 A8vp bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: object) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> NoReturn: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + +class LineType: + ChunkCombinedCode: ClassVar[cpy.LineType] + ChunkCombinedNan: ClassVar[cpy.LineType] + ChunkCombinedOffset: ClassVar[cpy.LineType] + Separate: ClassVar[cpy.LineType] + SeparateCode: ClassVar[cpy.LineType] + __members__: ClassVar[dict[str, cpy.LineType]] + def __eq__(self, other: object) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: object) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> NoReturn: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + +class ZInterp: + Linear: ClassVar[cpy.ZInterp] + Log: ClassVar[cpy.ZInterp] + __members__: ClassVar[dict[str, cpy.ZInterp]] + def __eq__(self, other: object) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: object) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> NoReturn: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + +def max_threads() -> int: ... + +class ContourGenerator: + def create_contour(self, level: float) -> LineReturn: ... + def create_filled_contour(self, lower_level: float, upper_level: float) -> FillReturn: ... + def filled(self, lower_level: float, upper_level: float) -> FillReturn: ... + def lines(self, level: float) -> LineReturn: ... + @staticmethod + def supports_corner_mask() -> bool: ... + @staticmethod + def supports_fill_type(fill_type: FillType) -> bool: ... + @staticmethod + def supports_line_type(line_type: LineType) -> bool: ... + @staticmethod + def supports_quad_as_tri() -> bool: ... + @staticmethod + def supports_threads() -> bool: ... + @staticmethod + def supports_z_interp() -> bool: ... + @property + def chunk_count(self) -> tuple[int, int]: ... + @property + def chunk_size(self) -> tuple[int, int]: ... + @property + def corner_mask(self) -> bool: ... + @property + def fill_type(self) -> FillType: ... + @property + def line_type(self) -> LineType: ... + @property + def quad_as_tri(self) -> bool: ... + @property + def thread_count(self) -> int: ... + @property + def z_interp(self) -> ZInterp: ... + default_fill_type: cpy.FillType + default_line_type: cpy.LineType + +class Mpl2005ContourGenerator(ContourGenerator): + def __init__( + self, + x: CoordinateArray, + y: CoordinateArray, + z: CoordinateArray, + mask: MaskArray, + *, + x_chunk_size: int = 0, + y_chunk_size: int = 0, + ) -> None: ... + +class Mpl2014ContourGenerator(ContourGenerator): + def __init__( + self, + x: CoordinateArray, + y: CoordinateArray, + z: CoordinateArray, + mask: MaskArray, + *, + corner_mask: bool, + x_chunk_size: int = 0, + y_chunk_size: int = 0, + ) -> None: ... + +class SerialContourGenerator(ContourGenerator): + def __init__( + self, + x: CoordinateArray, + y: CoordinateArray, + z: CoordinateArray, + mask: MaskArray, + *, + corner_mask: bool, + line_type: LineType, + fill_type: FillType, + quad_as_tri: bool, + z_interp: ZInterp, + x_chunk_size: int = 0, + y_chunk_size: int = 0, + ) -> None: ... + def _write_cache(self) -> NoReturn: ... + +class ThreadedContourGenerator(ContourGenerator): + def __init__( + self, + x: CoordinateArray, + y: CoordinateArray, + z: CoordinateArray, + mask: MaskArray, + *, + corner_mask: bool, + line_type: LineType, + fill_type: FillType, + quad_as_tri: bool, + z_interp: ZInterp, + x_chunk_size: int = 0, + y_chunk_size: int = 0, + thread_count: int = 0, + ) -> None: ... + def _write_cache(self) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/_version.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/_version.py new file mode 100644 index 00000000..c68196d1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/_version.py @@ -0,0 +1 @@ +__version__ = "1.2.0" diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/array.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/array.py new file mode 100644 index 00000000..fbc53d6c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/array.py @@ -0,0 +1,261 @@ +from __future__ import annotations + +from itertools import chain +from typing import TYPE_CHECKING + +import numpy as np + +from contourpy.typecheck import check_code_array, check_offset_array, check_point_array +from contourpy.types import CLOSEPOLY, LINETO, MOVETO, code_dtype, offset_dtype, point_dtype + +if TYPE_CHECKING: + import contourpy._contourpy as cpy + + +def codes_from_offsets(offsets: cpy.OffsetArray) -> cpy.CodeArray: + """Determine codes from offsets, assuming they all correspond to closed polygons. + """ + check_offset_array(offsets) + + n = offsets[-1] + codes = np.full(n, LINETO, dtype=code_dtype) + codes[offsets[:-1]] = MOVETO + codes[offsets[1:] - 1] = CLOSEPOLY + return codes + + +def codes_from_offsets_and_points( + offsets: cpy.OffsetArray, + points: cpy.PointArray, +) -> cpy.CodeArray: + """Determine codes from offsets and points, using the equality of the start and end points of + each line to determine if lines are closed or not. + """ + check_offset_array(offsets) + check_point_array(points) + + codes = np.full(len(points), LINETO, dtype=code_dtype) + codes[offsets[:-1]] = MOVETO + + end_offsets = offsets[1:] - 1 + closed = np.all(points[offsets[:-1]] == points[end_offsets], axis=1) + codes[end_offsets[closed]] = CLOSEPOLY + + return codes + + +def codes_from_points(points: cpy.PointArray) -> cpy.CodeArray: + """Determine codes for a single line, using the equality of the start and end points to + determine if the line is closed or not. + """ + check_point_array(points) + + n = len(points) + codes = np.full(n, LINETO, dtype=code_dtype) + codes[0] = MOVETO + if np.all(points[0] == points[-1]): + codes[-1] = CLOSEPOLY + return codes + + +def concat_codes(list_of_codes: list[cpy.CodeArray]) -> cpy.CodeArray: + """Concatenate a list of codes arrays into a single code array. + """ + if not list_of_codes: + raise ValueError("Empty list passed to concat_codes") + + return np.concatenate(list_of_codes, dtype=code_dtype) + + +def concat_codes_or_none(list_of_codes_or_none: list[cpy.CodeArray | None]) -> cpy.CodeArray | None: + """Concatenate a list of codes arrays or None into a single code array or None. + """ + list_of_codes = [codes for codes in list_of_codes_or_none if codes is not None] + if list_of_codes: + return concat_codes(list_of_codes) + else: + return None + + +def concat_offsets(list_of_offsets: list[cpy.OffsetArray]) -> cpy.OffsetArray: + """Concatenate a list of offsets arrays into a single offset array. + """ + if not list_of_offsets: + raise ValueError("Empty list passed to concat_offsets") + + n = len(list_of_offsets) + cumulative = np.cumsum([offsets[-1] for offsets in list_of_offsets], dtype=offset_dtype) + ret: cpy.OffsetArray = np.concatenate( + (list_of_offsets[0], *(list_of_offsets[i+1][1:] + cumulative[i] for i in range(n-1))), + dtype=offset_dtype, + ) + return ret + + +def concat_offsets_or_none( + list_of_offsets_or_none: list[cpy.OffsetArray | None], +) -> cpy.OffsetArray | None: + """Concatenate a list of offsets arrays or None into a single offset array or None. + """ + list_of_offsets = [offsets for offsets in list_of_offsets_or_none if offsets is not None] + if list_of_offsets: + return concat_offsets(list_of_offsets) + else: + return None + + +def concat_points(list_of_points: list[cpy.PointArray]) -> cpy.PointArray: + """Concatenate a list of point arrays into a single point array. + """ + if not list_of_points: + raise ValueError("Empty list passed to concat_points") + + return np.concatenate(list_of_points, dtype=point_dtype) + + +def concat_points_or_none( + list_of_points_or_none: list[cpy.PointArray | None], +) -> cpy.PointArray | None: + """Concatenate a list of point arrays or None into a single point array or None. + """ + list_of_points = [points for points in list_of_points_or_none if points is not None] + if list_of_points: + return concat_points(list_of_points) + else: + return None + + +def concat_points_or_none_with_nan( + list_of_points_or_none: list[cpy.PointArray | None], +) -> cpy.PointArray | None: + """Concatenate a list of points or None into a single point array or None, with NaNs used to + separate each line. + """ + list_of_points = [points for points in list_of_points_or_none if points is not None] + if list_of_points: + return concat_points_with_nan(list_of_points) + else: + return None + + +def concat_points_with_nan(list_of_points: list[cpy.PointArray]) -> cpy.PointArray: + """Concatenate a list of points into a single point array with NaNs used to separate each line. + """ + if not list_of_points: + raise ValueError("Empty list passed to concat_points_with_nan") + + if len(list_of_points) == 1: + return list_of_points[0] + else: + nan_spacer = np.full((1, 2), np.nan, dtype=point_dtype) + list_of_points = [list_of_points[0], + *list(chain(*((nan_spacer, x) for x in list_of_points[1:])))] + return concat_points(list_of_points) + + +def insert_nan_at_offsets(points: cpy.PointArray, offsets: cpy.OffsetArray) -> cpy.PointArray: + """Insert NaNs into a point array at locations specified by an offset array. + """ + check_point_array(points) + check_offset_array(offsets) + + if len(offsets) <= 2: + return points + else: + nan_spacer = np.array([np.nan, np.nan], dtype=point_dtype) + # Convert offsets to int64 to avoid numpy error when mixing signed and unsigned ints. + return np.insert(points, offsets[1:-1].astype(np.int64), nan_spacer, axis=0) + + +def offsets_from_codes(codes: cpy.CodeArray) -> cpy.OffsetArray: + """Determine offsets from codes using locations of MOVETO codes. + """ + check_code_array(codes) + + return np.append(np.nonzero(codes == MOVETO)[0], len(codes)).astype(offset_dtype) + + +def offsets_from_lengths(list_of_points: list[cpy.PointArray]) -> cpy.OffsetArray: + """Determine offsets from lengths of point arrays. + """ + if not list_of_points: + raise ValueError("Empty list passed to offsets_from_lengths") + + return np.cumsum([0] + [len(line) for line in list_of_points], dtype=offset_dtype) + + +def outer_offsets_from_list_of_codes(list_of_codes: list[cpy.CodeArray]) -> cpy.OffsetArray: + """Determine outer offsets from codes using locations of MOVETO codes. + """ + if not list_of_codes: + raise ValueError("Empty list passed to outer_offsets_from_list_of_codes") + + return np.cumsum([0] + [np.count_nonzero(codes == MOVETO) for codes in list_of_codes], + dtype=offset_dtype) + + +def outer_offsets_from_list_of_offsets(list_of_offsets: list[cpy.OffsetArray]) -> cpy.OffsetArray: + """Determine outer offsets from a list of offsets. + """ + if not list_of_offsets: + raise ValueError("Empty list passed to outer_offsets_from_list_of_offsets") + + return np.cumsum([0] + [len(offsets)-1 for offsets in list_of_offsets], dtype=offset_dtype) + + +def remove_nan(points: cpy.PointArray) -> tuple[cpy.PointArray, cpy.OffsetArray]: + """Remove NaN from a points array, also return the offsets corresponding to the NaN removed. + """ + check_point_array(points) + + nan_offsets = np.nonzero(np.isnan(points[:, 0]))[0] + if len(nan_offsets) == 0: + return points, np.array([0, len(points)], dtype=offset_dtype) + else: + points = np.delete(points, nan_offsets, axis=0) + nan_offsets -= np.arange(len(nan_offsets)) + offsets: cpy.OffsetArray = np.empty(len(nan_offsets)+2, dtype=offset_dtype) + offsets[0] = 0 + offsets[1:-1] = nan_offsets + offsets[-1] = len(points) + return points, offsets + + +def split_codes_by_offsets(codes: cpy.CodeArray, offsets: cpy.OffsetArray) -> list[cpy.CodeArray]: + """Split a code array at locations specified by an offset array into a list of code arrays. + """ + check_code_array(codes) + check_offset_array(offsets) + + if len(offsets) > 2: + return np.split(codes, offsets[1:-1]) + else: + return [codes] + + +def split_points_by_offsets( + points: cpy.PointArray, + offsets: cpy.OffsetArray, +) -> list[cpy.PointArray]: + """Split a point array at locations specified by an offset array into a list of point arrays. + """ + check_point_array(points) + check_offset_array(offsets) + + if len(offsets) > 2: + return np.split(points, offsets[1:-1]) + else: + return [points] + + +def split_points_at_nan(points: cpy.PointArray) -> list[cpy.PointArray]: + """Split a points array at NaNs into a list of point arrays. + """ + check_point_array(points) + + nan_offsets = np.nonzero(np.isnan(points[:, 0]))[0] + if len(nan_offsets) == 0: + return [points] + else: + nan_offsets = np.concatenate(([-1], nan_offsets, [len(points)])) # type: ignore[arg-type] + return [points[s+1:e] for s, e in zip(nan_offsets[:-1], nan_offsets[1:])] diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/chunk.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/chunk.py new file mode 100644 index 00000000..94fded1b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/chunk.py @@ -0,0 +1,95 @@ +from __future__ import annotations + +import math + + +def calc_chunk_sizes( + chunk_size: int | tuple[int, int] | None, + chunk_count: int | tuple[int, int] | None, + total_chunk_count: int | None, + ny: int, + nx: int, +) -> tuple[int, int]: + """Calculate chunk sizes. + + Args: + chunk_size (int or tuple(int, int), optional): Chunk size in (y, x) directions, or the same + size in both directions if only one is specified. Cannot be negative. + chunk_count (int or tuple(int, int), optional): Chunk count in (y, x) directions, or the + same count in both directions if only one is specified. If less than 1, set to 1. + total_chunk_count (int, optional): Total number of chunks. If less than 1, set to 1. + ny (int): Number of grid points in y-direction. + nx (int): Number of grid points in x-direction. + + Return: + tuple(int, int): Chunk sizes (y_chunk_size, x_chunk_size). + + Note: + Zero or one of ``chunk_size``, ``chunk_count`` and ``total_chunk_count`` should be + specified. + """ + if sum([chunk_size is not None, chunk_count is not None, total_chunk_count is not None]) > 1: + raise ValueError("Only one of chunk_size, chunk_count and total_chunk_count should be set") + + if nx < 2 or ny < 2: + raise ValueError(f"(ny, nx) must be at least (2, 2), not ({ny}, {nx})") + + if total_chunk_count is not None: + max_chunk_count = (nx-1)*(ny-1) + total_chunk_count = min(max(total_chunk_count, 1), max_chunk_count) + if total_chunk_count == 1: + chunk_size = 0 + elif total_chunk_count == max_chunk_count: + chunk_size = (1, 1) + else: + factors = two_factors(total_chunk_count) + if ny > nx: + chunk_count = factors + else: + chunk_count = (factors[1], factors[0]) + + if chunk_count is not None: + if isinstance(chunk_count, tuple): + y_chunk_count, x_chunk_count = chunk_count + else: + y_chunk_count = x_chunk_count = chunk_count + x_chunk_count = min(max(x_chunk_count, 1), nx-1) + y_chunk_count = min(max(y_chunk_count, 1), ny-1) + chunk_size = (math.ceil((ny-1) / y_chunk_count), math.ceil((nx-1) / x_chunk_count)) + + if chunk_size is None: + y_chunk_size = x_chunk_size = 0 + elif isinstance(chunk_size, tuple): + y_chunk_size, x_chunk_size = chunk_size + else: + y_chunk_size = x_chunk_size = chunk_size + + if x_chunk_size < 0 or y_chunk_size < 0: + raise ValueError("chunk_size cannot be negative") + + return y_chunk_size, x_chunk_size + + +def two_factors(n: int) -> tuple[int, int]: + """Split an integer into two integer factors. + + The two factors will be as close as possible to the sqrt of n, and are returned in decreasing + order. Worst case returns (n, 1). + + Args: + n (int): The integer to factorize, must be positive. + + Return: + tuple(int, int): The two factors of n, in decreasing order. + """ + if n < 0: + raise ValueError(f"two_factors expects positive integer not {n}") + + i = math.ceil(math.sqrt(n)) + while n % i != 0: + i -= 1 + j = n // i + if i > j: + return i, j + else: + return j, i diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/convert.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/convert.py new file mode 100644 index 00000000..75a54b08 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/convert.py @@ -0,0 +1,555 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +import numpy as np + +from contourpy._contourpy import FillType, LineType +import contourpy.array as arr +from contourpy.enum_util import as_fill_type, as_line_type +from contourpy.typecheck import check_filled, check_lines +from contourpy.types import MOVETO, offset_dtype + +if TYPE_CHECKING: + import contourpy._contourpy as cpy + + +def _convert_filled_from_OuterCode( + filled: cpy.FillReturn_OuterCode, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.OuterCode: + return filled + elif fill_type_to == FillType.OuterOffset: + return (filled[0], [arr.offsets_from_codes(codes) for codes in filled[1]]) + + if len(filled[0]) > 0: + points = arr.concat_points(filled[0]) + codes = arr.concat_codes(filled[1]) + else: + points = None + codes = None + + if fill_type_to == FillType.ChunkCombinedCode: + return ([points], [codes]) + elif fill_type_to == FillType.ChunkCombinedOffset: + return ([points], [None if codes is None else arr.offsets_from_codes(codes)]) + elif fill_type_to == FillType.ChunkCombinedCodeOffset: + outer_offsets = None if points is None else arr.offsets_from_lengths(filled[0]) + ret1: cpy.FillReturn_ChunkCombinedCodeOffset = ([points], [codes], [outer_offsets]) + return ret1 + elif fill_type_to == FillType.ChunkCombinedOffsetOffset: + if codes is None: + ret2: cpy.FillReturn_ChunkCombinedOffsetOffset = ([None], [None], [None]) + else: + offsets = arr.offsets_from_codes(codes) + outer_offsets = arr.outer_offsets_from_list_of_codes(filled[1]) + ret2 = ([points], [offsets], [outer_offsets]) + return ret2 + else: + raise ValueError(f"Invalid FillType {fill_type_to}") + + +def _convert_filled_from_OuterOffset( + filled: cpy.FillReturn_OuterOffset, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.OuterCode: + separate_codes = [arr.codes_from_offsets(offsets) for offsets in filled[1]] + return (filled[0], separate_codes) + elif fill_type_to == FillType.OuterOffset: + return filled + + if len(filled[0]) > 0: + points = arr.concat_points(filled[0]) + offsets = arr.concat_offsets(filled[1]) + else: + points = None + offsets = None + + if fill_type_to == FillType.ChunkCombinedCode: + return ([points], [None if offsets is None else arr.codes_from_offsets(offsets)]) + elif fill_type_to == FillType.ChunkCombinedOffset: + return ([points], [offsets]) + elif fill_type_to == FillType.ChunkCombinedCodeOffset: + if offsets is None: + ret1: cpy.FillReturn_ChunkCombinedCodeOffset = ([None], [None], [None]) + else: + codes = arr.codes_from_offsets(offsets) + outer_offsets = arr.offsets_from_lengths(filled[0]) + ret1 = ([points], [codes], [outer_offsets]) + return ret1 + elif fill_type_to == FillType.ChunkCombinedOffsetOffset: + if points is None: + ret2: cpy.FillReturn_ChunkCombinedOffsetOffset = ([None], [None], [None]) + else: + outer_offsets = arr.outer_offsets_from_list_of_offsets(filled[1]) + ret2 = ([points], [offsets], [outer_offsets]) + return ret2 + else: + raise ValueError(f"Invalid FillType {fill_type_to}") + + +def _convert_filled_from_ChunkCombinedCode( + filled: cpy.FillReturn_ChunkCombinedCode, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.ChunkCombinedCode: + return filled + elif fill_type_to == FillType.ChunkCombinedOffset: + codes = [None if codes is None else arr.offsets_from_codes(codes) for codes in filled[1]] + return (filled[0], codes) + else: + raise ValueError( + f"Conversion from {FillType.ChunkCombinedCode} to {fill_type_to} not supported") + + +def _convert_filled_from_ChunkCombinedOffset( + filled: cpy.FillReturn_ChunkCombinedOffset, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.ChunkCombinedCode: + chunk_codes: list[cpy.CodeArray | None] = [] + for points, offsets in zip(*filled): + if points is None: + chunk_codes.append(None) + else: + if TYPE_CHECKING: + assert offsets is not None + chunk_codes.append(arr.codes_from_offsets_and_points(offsets, points)) + return (filled[0], chunk_codes) + elif fill_type_to == FillType.ChunkCombinedOffset: + return filled + else: + raise ValueError( + f"Conversion from {FillType.ChunkCombinedOffset} to {fill_type_to} not supported") + + +def _convert_filled_from_ChunkCombinedCodeOffset( + filled: cpy.FillReturn_ChunkCombinedCodeOffset, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.OuterCode: + separate_points = [] + separate_codes = [] + for points, codes, outer_offsets in zip(*filled): + if points is not None: + if TYPE_CHECKING: + assert codes is not None + assert outer_offsets is not None + separate_points += arr.split_points_by_offsets(points, outer_offsets) + separate_codes += arr.split_codes_by_offsets(codes, outer_offsets) + return (separate_points, separate_codes) + elif fill_type_to == FillType.OuterOffset: + separate_points = [] + separate_offsets = [] + for points, codes, outer_offsets in zip(*filled): + if points is not None: + if TYPE_CHECKING: + assert codes is not None + assert outer_offsets is not None + separate_points += arr.split_points_by_offsets(points, outer_offsets) + separate_codes = arr.split_codes_by_offsets(codes, outer_offsets) + separate_offsets += [arr.offsets_from_codes(codes) for codes in separate_codes] + return (separate_points, separate_offsets) + elif fill_type_to == FillType.ChunkCombinedCode: + ret1: cpy.FillReturn_ChunkCombinedCode = (filled[0], filled[1]) + return ret1 + elif fill_type_to == FillType.ChunkCombinedOffset: + all_offsets = [None if codes is None else arr.offsets_from_codes(codes) + for codes in filled[1]] + ret2: cpy.FillReturn_ChunkCombinedOffset = (filled[0], all_offsets) + return ret2 + elif fill_type_to == FillType.ChunkCombinedCodeOffset: + return filled + elif fill_type_to == FillType.ChunkCombinedOffsetOffset: + chunk_offsets: list[cpy.OffsetArray | None] = [] + chunk_outer_offsets: list[cpy.OffsetArray | None] = [] + for codes, outer_offsets in zip(*filled[1:]): + if codes is None: + chunk_offsets.append(None) + chunk_outer_offsets.append(None) + else: + if TYPE_CHECKING: + assert outer_offsets is not None + offsets = arr.offsets_from_codes(codes) + outer_offsets = np.array([np.nonzero(offsets == oo)[0][0] for oo in outer_offsets], + dtype=offset_dtype) + chunk_offsets.append(offsets) + chunk_outer_offsets.append(outer_offsets) + ret3: cpy.FillReturn_ChunkCombinedOffsetOffset = ( + filled[0], chunk_offsets, chunk_outer_offsets, + ) + return ret3 + else: + raise ValueError(f"Invalid FillType {fill_type_to}") + + +def _convert_filled_from_ChunkCombinedOffsetOffset( + filled: cpy.FillReturn_ChunkCombinedOffsetOffset, + fill_type_to: FillType, +) -> cpy.FillReturn: + if fill_type_to == FillType.OuterCode: + separate_points = [] + separate_codes = [] + for points, offsets, outer_offsets in zip(*filled): + if points is not None: + if TYPE_CHECKING: + assert offsets is not None + assert outer_offsets is not None + codes = arr.codes_from_offsets_and_points(offsets, points) + outer_offsets = offsets[outer_offsets] + separate_points += arr.split_points_by_offsets(points, outer_offsets) + separate_codes += arr.split_codes_by_offsets(codes, outer_offsets) + return (separate_points, separate_codes) + elif fill_type_to == FillType.OuterOffset: + separate_points = [] + separate_offsets = [] + for points, offsets, outer_offsets in zip(*filled): + if points is not None: + if TYPE_CHECKING: + assert offsets is not None + assert outer_offsets is not None + if len(outer_offsets) > 2: + separate_offsets += [offsets[s:e+1] - offsets[s] for s, e in + zip(outer_offsets[:-1], outer_offsets[1:])] + else: + separate_offsets.append(offsets) + separate_points += arr.split_points_by_offsets(points, offsets[outer_offsets]) + return (separate_points, separate_offsets) + elif fill_type_to == FillType.ChunkCombinedCode: + chunk_codes: list[cpy.CodeArray | None] = [] + for points, offsets, outer_offsets in zip(*filled): + if points is None: + chunk_codes.append(None) + else: + if TYPE_CHECKING: + assert offsets is not None + assert outer_offsets is not None + chunk_codes.append(arr.codes_from_offsets_and_points(offsets, points)) + ret1: cpy.FillReturn_ChunkCombinedCode = (filled[0], chunk_codes) + return ret1 + elif fill_type_to == FillType.ChunkCombinedOffset: + return (filled[0], filled[1]) + elif fill_type_to == FillType.ChunkCombinedCodeOffset: + chunk_codes = [] + chunk_outer_offsets: list[cpy.OffsetArray | None] = [] + for points, offsets, outer_offsets in zip(*filled): + if points is None: + chunk_codes.append(None) + chunk_outer_offsets.append(None) + else: + if TYPE_CHECKING: + assert offsets is not None + assert outer_offsets is not None + chunk_codes.append(arr.codes_from_offsets_and_points(offsets, points)) + chunk_outer_offsets.append(offsets[outer_offsets]) + ret2: cpy.FillReturn_ChunkCombinedCodeOffset = (filled[0], chunk_codes, chunk_outer_offsets) + return ret2 + elif fill_type_to == FillType.ChunkCombinedOffsetOffset: + return filled + else: + raise ValueError(f"Invalid FillType {fill_type_to}") + + +def convert_filled( + filled: cpy.FillReturn, + fill_type_from: FillType | str, + fill_type_to: FillType | str, +) -> cpy.FillReturn: + """Return the specified filled contours converted to a different :class:`~contourpy.FillType`. + + Args: + filled (sequence of arrays): Filled contour polygons to convert. + fill_type_from (FillType or str): :class:`~contourpy.FillType` to convert from as enum or + string equivalent. + fill_type_to (FillType or str): :class:`~contourpy.FillType` to convert to as enum or string + equivalent. + + Return: + Converted filled contour polygons. + + When converting non-chunked fill types (``FillType.OuterCode`` or ``FillType.OuterOffset``) to + chunked ones, all polygons are placed in the first chunk. When converting in the other + direction, all chunk information is discarded. Converting a fill type that is not aware of the + relationship between outer boundaries and contained holes (``FillType.ChunkCombinedCode`` or) + ``FillType.ChunkCombinedOffset``) to one that is will raise a ``ValueError``. + + .. versionadded:: 1.2.0 + """ + fill_type_from = as_fill_type(fill_type_from) + fill_type_to = as_fill_type(fill_type_to) + + check_filled(filled, fill_type_from) + + if fill_type_from == FillType.OuterCode: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_OuterCode, filled) + return _convert_filled_from_OuterCode(filled, fill_type_to) + elif fill_type_from == FillType.OuterOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_OuterOffset, filled) + return _convert_filled_from_OuterOffset(filled, fill_type_to) + elif fill_type_from == FillType.ChunkCombinedCode: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCode, filled) + return _convert_filled_from_ChunkCombinedCode(filled, fill_type_to) + elif fill_type_from == FillType.ChunkCombinedOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffset, filled) + return _convert_filled_from_ChunkCombinedOffset(filled, fill_type_to) + elif fill_type_from == FillType.ChunkCombinedCodeOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCodeOffset, filled) + return _convert_filled_from_ChunkCombinedCodeOffset(filled, fill_type_to) + elif fill_type_from == FillType.ChunkCombinedOffsetOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffsetOffset, filled) + return _convert_filled_from_ChunkCombinedOffsetOffset(filled, fill_type_to) + else: + raise ValueError(f"Invalid FillType {fill_type_from}") + + +def _convert_lines_from_Separate( + lines: cpy.LineReturn_Separate, + line_type_to: LineType, +) -> cpy.LineReturn: + if line_type_to == LineType.Separate: + return lines + elif line_type_to == LineType.SeparateCode: + separate_codes = [arr.codes_from_points(line) for line in lines] + return (lines, separate_codes) + elif line_type_to == LineType.ChunkCombinedCode: + if not lines: + ret1: cpy.LineReturn_ChunkCombinedCode = ([None], [None]) + else: + points = arr.concat_points(lines) + offsets = arr.offsets_from_lengths(lines) + codes = arr.codes_from_offsets_and_points(offsets, points) + ret1 = ([points], [codes]) + return ret1 + elif line_type_to == LineType.ChunkCombinedOffset: + if not lines: + ret2: cpy.LineReturn_ChunkCombinedOffset = ([None], [None]) + else: + ret2 = ([arr.concat_points(lines)], [arr.offsets_from_lengths(lines)]) + return ret2 + elif line_type_to == LineType.ChunkCombinedNan: + if not lines: + ret3: cpy.LineReturn_ChunkCombinedNan = ([None],) + else: + ret3 = ([arr.concat_points_with_nan(lines)],) + return ret3 + else: + raise ValueError(f"Invalid LineType {line_type_to}") + + +def _convert_lines_from_SeparateCode( + lines: cpy.LineReturn_SeparateCode, + line_type_to: LineType, +) -> cpy.LineReturn: + if line_type_to == LineType.Separate: + # Drop codes. + return lines[0] + elif line_type_to == LineType.SeparateCode: + return lines + elif line_type_to == LineType.ChunkCombinedCode: + if not lines[0]: + ret1: cpy.LineReturn_ChunkCombinedCode = ([None], [None]) + else: + ret1 = ([arr.concat_points(lines[0])], [arr.concat_codes(lines[1])]) + return ret1 + elif line_type_to == LineType.ChunkCombinedOffset: + if not lines[0]: + ret2: cpy.LineReturn_ChunkCombinedOffset = ([None], [None]) + else: + ret2 = ([arr.concat_points(lines[0])], [arr.offsets_from_lengths(lines[0])]) + return ret2 + elif line_type_to == LineType.ChunkCombinedNan: + if not lines[0]: + ret3: cpy.LineReturn_ChunkCombinedNan = ([None],) + else: + ret3 = ([arr.concat_points_with_nan(lines[0])],) + return ret3 + else: + raise ValueError(f"Invalid LineType {line_type_to}") + + +def _convert_lines_from_ChunkCombinedCode( + lines: cpy.LineReturn_ChunkCombinedCode, + line_type_to: LineType, +) -> cpy.LineReturn: + if line_type_to in (LineType.Separate, LineType.SeparateCode): + separate_lines = [] + for points, codes in zip(*lines): + if points is not None: + if TYPE_CHECKING: + assert codes is not None + split_at = np.nonzero(codes == MOVETO)[0] + if len(split_at) > 1: + separate_lines += np.split(points, split_at[1:]) + else: + separate_lines.append(points) + if line_type_to == LineType.Separate: + return separate_lines + else: + separate_codes = [arr.codes_from_points(line) for line in separate_lines] + return (separate_lines, separate_codes) + elif line_type_to == LineType.ChunkCombinedCode: + return lines + elif line_type_to == LineType.ChunkCombinedOffset: + chunk_offsets = [None if codes is None else arr.offsets_from_codes(codes) + for codes in lines[1]] + return (lines[0], chunk_offsets) + elif line_type_to == LineType.ChunkCombinedNan: + points_nan: list[cpy.PointArray | None] = [] + for points, codes in zip(*lines): + if points is None: + points_nan.append(None) + else: + if TYPE_CHECKING: + assert codes is not None + offsets = arr.offsets_from_codes(codes) + points_nan.append(arr.insert_nan_at_offsets(points, offsets)) + return (points_nan,) + else: + raise ValueError(f"Invalid LineType {line_type_to}") + + +def _convert_lines_from_ChunkCombinedOffset( + lines: cpy.LineReturn_ChunkCombinedOffset, + line_type_to: LineType, +) -> cpy.LineReturn: + if line_type_to in (LineType.Separate, LineType.SeparateCode): + separate_lines = [] + for points, offsets in zip(*lines): + if points is not None: + if TYPE_CHECKING: + assert offsets is not None + separate_lines += arr.split_points_by_offsets(points, offsets) + if line_type_to == LineType.Separate: + return separate_lines + else: + separate_codes = [arr.codes_from_points(line) for line in separate_lines] + return (separate_lines, separate_codes) + elif line_type_to == LineType.ChunkCombinedCode: + chunk_codes: list[cpy.CodeArray | None] = [] + for points, offsets in zip(*lines): + if points is None: + chunk_codes.append(None) + else: + if TYPE_CHECKING: + assert offsets is not None + chunk_codes.append(arr.codes_from_offsets_and_points(offsets, points)) + return (lines[0], chunk_codes) + elif line_type_to == LineType.ChunkCombinedOffset: + return lines + elif line_type_to == LineType.ChunkCombinedNan: + points_nan: list[cpy.PointArray | None] = [] + for points, offsets in zip(*lines): + if points is None: + points_nan.append(None) + else: + if TYPE_CHECKING: + assert offsets is not None + points_nan.append(arr.insert_nan_at_offsets(points, offsets)) + return (points_nan,) + else: + raise ValueError(f"Invalid LineType {line_type_to}") + + +def _convert_lines_from_ChunkCombinedNan( + lines: cpy.LineReturn_ChunkCombinedNan, + line_type_to: LineType, +) -> cpy.LineReturn: + if line_type_to in (LineType.Separate, LineType.SeparateCode): + separate_lines = [] + for points in lines[0]: + if points is not None: + separate_lines += arr.split_points_at_nan(points) + if line_type_to == LineType.Separate: + return separate_lines + else: + separate_codes = [arr.codes_from_points(points) for points in separate_lines] + return (separate_lines, separate_codes) + elif line_type_to == LineType.ChunkCombinedCode: + chunk_points: list[cpy.PointArray | None] = [] + chunk_codes: list[cpy.CodeArray | None] = [] + for points in lines[0]: + if points is None: + chunk_points.append(None) + chunk_codes.append(None) + else: + points, offsets = arr.remove_nan(points) + chunk_points.append(points) + chunk_codes.append(arr.codes_from_offsets_and_points(offsets, points)) + return (chunk_points, chunk_codes) + elif line_type_to == LineType.ChunkCombinedOffset: + chunk_points = [] + chunk_offsets: list[cpy.OffsetArray | None] = [] + for points in lines[0]: + if points is None: + chunk_points.append(None) + chunk_offsets.append(None) + else: + points, offsets = arr.remove_nan(points) + chunk_points.append(points) + chunk_offsets.append(offsets) + return (chunk_points, chunk_offsets) + elif line_type_to == LineType.ChunkCombinedNan: + return lines + else: + raise ValueError(f"Invalid LineType {line_type_to}") + + +def convert_lines( + lines: cpy.LineReturn, + line_type_from: LineType | str, + line_type_to: LineType | str, +) -> cpy.LineReturn: + """Return the specified contour lines converted to a different :class:`~contourpy.LineType`. + + Args: + lines (sequence of arrays): Contour lines to convert. + line_type_from (LineType or str): :class:`~contourpy.LineType` to convert from as enum or + string equivalent. + line_type_to (LineType or str): :class:`~contourpy.LineType` to convert to as enum or string + equivalent. + + Return: + Converted contour lines. + + When converting non-chunked line types (``LineType.Separate`` or ``LineType.SeparateCode``) to + chunked ones (``LineType.ChunkCombinedCode``, ``LineType.ChunkCombinedOffset`` or + ``LineType.ChunkCombinedNan``), all lines are placed in the first chunk. When converting in the + other direction, all chunk information is discarded. + + .. versionadded:: 1.2.0 + """ + line_type_from = as_line_type(line_type_from) + line_type_to = as_line_type(line_type_to) + + check_lines(lines, line_type_from) + + if line_type_from == LineType.Separate: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_Separate, lines) + return _convert_lines_from_Separate(lines, line_type_to) + elif line_type_from == LineType.SeparateCode: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_SeparateCode, lines) + return _convert_lines_from_SeparateCode(lines, line_type_to) + elif line_type_from == LineType.ChunkCombinedCode: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedCode, lines) + return _convert_lines_from_ChunkCombinedCode(lines, line_type_to) + elif line_type_from == LineType.ChunkCombinedOffset: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedOffset, lines) + return _convert_lines_from_ChunkCombinedOffset(lines, line_type_to) + elif line_type_from == LineType.ChunkCombinedNan: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedNan, lines) + return _convert_lines_from_ChunkCombinedNan(lines, line_type_to) + else: + raise ValueError(f"Invalid LineType {line_type_from}") diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/dechunk.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/dechunk.py new file mode 100644 index 00000000..92b61bba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/dechunk.py @@ -0,0 +1,142 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from contourpy._contourpy import FillType, LineType +from contourpy.array import ( + concat_codes_or_none, concat_offsets_or_none, concat_points_or_none, + concat_points_or_none_with_nan, +) +from contourpy.enum_util import as_fill_type, as_line_type +from contourpy.typecheck import check_filled, check_lines + +if TYPE_CHECKING: + import contourpy._contourpy as cpy + + +def dechunk_filled(filled: cpy.FillReturn, fill_type: FillType | str) -> cpy.FillReturn: + """Return the specified filled contours with all chunked data moved into the first chunk. + + Filled contours that are not chunked (``FillType.OuterCode`` and ``FillType.OuterOffset``) and + those that are but only contain a single chunk are returned unmodified. Individual polygons are + unchanged, they are not geometrically combined. + + Args: + filled (sequence of arrays): Filled contour data as returned by + :func:`~contourpy.ContourGenerator.filled`. + fill_type (FillType or str): Type of ``filled`` as enum or string equivalent. + + Return: + Filled contours in a single chunk. + + .. versionadded:: 1.2.0 + """ + fill_type = as_fill_type(fill_type) + + if fill_type in (FillType.OuterCode, FillType.OuterOffset): + # No-op if fill_type is not chunked. + return filled + + check_filled(filled, fill_type) + if len(filled[0]) < 2: + # No-op if just one chunk. + return filled + + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_Chunk, filled) + points = concat_points_or_none(filled[0]) + + if fill_type == FillType.ChunkCombinedCode: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCode, filled) + if points is None: + ret1: cpy.FillReturn_ChunkCombinedCode = ([None], [None]) + else: + ret1 = ([points], [concat_codes_or_none(filled[1])]) + return ret1 + elif fill_type == FillType.ChunkCombinedOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffset, filled) + if points is None: + ret2: cpy.FillReturn_ChunkCombinedOffset = ([None], [None]) + else: + ret2 = ([points], [concat_offsets_or_none(filled[1])]) + return ret2 + elif fill_type == FillType.ChunkCombinedCodeOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCodeOffset, filled) + if points is None: + ret3: cpy.FillReturn_ChunkCombinedCodeOffset = ([None], [None], [None]) + else: + outer_offsets = concat_offsets_or_none(filled[2]) + ret3 = ([points], [concat_codes_or_none(filled[1])], [outer_offsets]) + return ret3 + elif fill_type == FillType.ChunkCombinedOffsetOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffsetOffset, filled) + if points is None: + ret4: cpy.FillReturn_ChunkCombinedOffsetOffset = ([None], [None], [None]) + else: + outer_offsets = concat_offsets_or_none(filled[2]) + ret4 = ([points], [concat_offsets_or_none(filled[1])], [outer_offsets]) + return ret4 + else: + raise ValueError(f"Invalid FillType {fill_type}") + + +def dechunk_lines(lines: cpy.LineReturn, line_type: LineType | str) -> cpy.LineReturn: + """Return the specified contour lines with all chunked data moved into the first chunk. + + Contour lines that are not chunked (``LineType.Separate`` and ``LineType.SeparateCode``) and + those that are but only contain a single chunk are returned unmodified. Individual lines are + unchanged, they are not geometrically combined. + + Args: + lines (sequence of arrays): Contour line data as returned by + :func:`~contourpy.ContourGenerator.lines`. + line_type (LineType or str): Type of ``lines`` as enum or string equivalent. + + Return: + Contour lines in a single chunk. + + .. versionadded:: 1.2.0 + """ + line_type = as_line_type(line_type) + if line_type in (LineType.Separate, LineType.SeparateCode): + # No-op if line_type is not chunked. + return lines + + check_lines(lines, line_type) + if len(lines[0]) < 2: + # No-op if just one chunk. + return lines + + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_Chunk, lines) + + if line_type == LineType.ChunkCombinedCode: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedCode, lines) + points = concat_points_or_none(lines[0]) + if points is None: + ret1: cpy.LineReturn_ChunkCombinedCode = ([None], [None]) + else: + ret1 = ([points], [concat_codes_or_none(lines[1])]) + return ret1 + elif line_type == LineType.ChunkCombinedOffset: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedOffset, lines) + points = concat_points_or_none(lines[0]) + if points is None: + ret2: cpy.LineReturn_ChunkCombinedOffset = ([None], [None]) + else: + ret2 = ([points], [concat_offsets_or_none(lines[1])]) + return ret2 + elif line_type == LineType.ChunkCombinedNan: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedNan, lines) + points = concat_points_or_none_with_nan(lines[0]) + ret3: cpy.LineReturn_ChunkCombinedNan = ([points],) + return ret3 + else: + raise ValueError(f"Invalid LineType {line_type}") diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/enum_util.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/enum_util.py new file mode 100644 index 00000000..14229abe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/enum_util.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from contourpy._contourpy import FillType, LineType, ZInterp + + +def as_fill_type(fill_type: FillType | str) -> FillType: + """Coerce a FillType or string value to a FillType. + + Args: + fill_type (FillType or str): Value to convert. + + Return: + FillType: Converted value. + """ + if isinstance(fill_type, str): + try: + return FillType.__members__[fill_type] + except KeyError as e: + raise ValueError(f"'{fill_type}' is not a valid FillType") from e + else: + return fill_type + + +def as_line_type(line_type: LineType | str) -> LineType: + """Coerce a LineType or string value to a LineType. + + Args: + line_type (LineType or str): Value to convert. + + Return: + LineType: Converted value. + """ + if isinstance(line_type, str): + try: + return LineType.__members__[line_type] + except KeyError as e: + raise ValueError(f"'{line_type}' is not a valid LineType") from e + else: + return line_type + + +def as_z_interp(z_interp: ZInterp | str) -> ZInterp: + """Coerce a ZInterp or string value to a ZInterp. + + Args: + z_interp (ZInterp or str): Value to convert. + + Return: + ZInterp: Converted value. + """ + if isinstance(z_interp, str): + try: + return ZInterp.__members__[z_interp] + except KeyError as e: + raise ValueError(f"'{z_interp}' is not a valid ZInterp") from e + else: + return z_interp diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/py.typed b/dbdpy-env/lib/python3.9/site-packages/contourpy/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/typecheck.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/typecheck.py new file mode 100644 index 00000000..06a18f6c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/typecheck.py @@ -0,0 +1,203 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, cast + +import numpy as np + +from contourpy import FillType, LineType +from contourpy.enum_util import as_fill_type, as_line_type +from contourpy.types import MOVETO, code_dtype, offset_dtype, point_dtype + +if TYPE_CHECKING: + import contourpy._contourpy as cpy + + +# Minimalist array-checking functions that check dtype, ndims and shape only. +# They do not walk the arrays to check the contents for performance reasons. +def check_code_array(codes: Any) -> None: + if not isinstance(codes, np.ndarray): + raise TypeError(f"Expected numpy array not {type(codes)}") + if codes.dtype != code_dtype: + raise ValueError(f"Expected numpy array of dtype {code_dtype} not {codes.dtype}") + if not (codes.ndim == 1 and len(codes) > 1): + raise ValueError(f"Expected numpy array of shape (?,) not {codes.shape}") + if codes[0] != MOVETO: + raise ValueError(f"First element of code array must be {MOVETO}, not {codes[0]}") + + +def check_offset_array(offsets: Any) -> None: + if not isinstance(offsets, np.ndarray): + raise TypeError(f"Expected numpy array not {type(offsets)}") + if offsets.dtype != offset_dtype: + raise ValueError(f"Expected numpy array of dtype {offset_dtype} not {offsets.dtype}") + if not (offsets.ndim == 1 and len(offsets) > 1): + raise ValueError(f"Expected numpy array of shape (?,) not {offsets.shape}") + if offsets[0] != 0: + raise ValueError(f"First element of offset array must be 0, not {offsets[0]}") + + +def check_point_array(points: Any) -> None: + if not isinstance(points, np.ndarray): + raise TypeError(f"Expected numpy array not {type(points)}") + if points.dtype != point_dtype: + raise ValueError(f"Expected numpy array of dtype {point_dtype} not {points.dtype}") + if not (points.ndim == 2 and points.shape[1] ==2 and points.shape[0] > 1): + raise ValueError(f"Expected numpy array of shape (?, 2) not {points.shape}") + + +def _check_tuple_of_lists_with_same_length( + maybe_tuple: Any, + tuple_length: int, + allow_empty_lists: bool = True, +) -> None: + if not isinstance(maybe_tuple, tuple): + raise TypeError(f"Expected tuple not {type(maybe_tuple)}") + if len(maybe_tuple) != tuple_length: + raise ValueError(f"Expected tuple of length {tuple_length} not {len(maybe_tuple)}") + for maybe_list in maybe_tuple: + if not isinstance(maybe_list, list): + msg = f"Expected tuple to contain {tuple_length} lists but found a {type(maybe_list)}" + raise TypeError(msg) + lengths = [len(item) for item in maybe_tuple] + if len(set(lengths)) != 1: + msg = f"Expected {tuple_length} lists with same length but lengths are {lengths}" + raise ValueError(msg) + if not allow_empty_lists and lengths[0] == 0: + raise ValueError(f"Expected {tuple_length} non-empty lists") + + +def check_filled(filled: cpy.FillReturn, fill_type: FillType | str) -> None: + fill_type = as_fill_type(fill_type) + + if fill_type == FillType.OuterCode: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_OuterCode, filled) + _check_tuple_of_lists_with_same_length(filled, 2) + for i, (points, codes) in enumerate(zip(*filled)): + check_point_array(points) + check_code_array(codes) + if len(points) != len(codes): + raise ValueError(f"Points and codes have different lengths in polygon {i}") + elif fill_type == FillType.OuterOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_OuterOffset, filled) + _check_tuple_of_lists_with_same_length(filled, 2) + for i, (points, offsets) in enumerate(zip(*filled)): + check_point_array(points) + check_offset_array(offsets) + if offsets[-1] != len(points): + raise ValueError(f"Inconsistent points and offsets in polygon {i}") + elif fill_type == FillType.ChunkCombinedCode: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCode, filled) + _check_tuple_of_lists_with_same_length(filled, 2, allow_empty_lists=False) + for chunk, (points_or_none, codes_or_none) in enumerate(zip(*filled)): + if points_or_none is not None and codes_or_none is not None: + check_point_array(points_or_none) + check_code_array(codes_or_none) + if len(points_or_none) != len(codes_or_none): + raise ValueError(f"Points and codes have different lengths in chunk {chunk}") + elif not (points_or_none is None and codes_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {chunk}") + elif fill_type == FillType.ChunkCombinedOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffset, filled) + _check_tuple_of_lists_with_same_length(filled, 2, allow_empty_lists=False) + for chunk, (points_or_none, offsets_or_none) in enumerate(zip(*filled)): + if points_or_none is not None and offsets_or_none is not None: + check_point_array(points_or_none) + check_offset_array(offsets_or_none) + if offsets_or_none[-1] != len(points_or_none): + raise ValueError(f"Inconsistent points and offsets in chunk {chunk}") + elif not (points_or_none is None and offsets_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {chunk}") + elif fill_type == FillType.ChunkCombinedCodeOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedCodeOffset, filled) + _check_tuple_of_lists_with_same_length(filled, 3, allow_empty_lists=False) + for i, (points_or_none, codes_or_none, outer_offsets_or_none) in enumerate(zip(*filled)): + if (points_or_none is not None and codes_or_none is not None and + outer_offsets_or_none is not None): + check_point_array(points_or_none) + check_code_array(codes_or_none) + check_offset_array(outer_offsets_or_none) + if len(codes_or_none) != len(points_or_none): + raise ValueError(f"Points and codes have different lengths in chunk {i}") + if outer_offsets_or_none[-1] != len(codes_or_none): + raise ValueError(f"Inconsistent codes and outer_offsets in chunk {i}") + elif not (points_or_none is None and codes_or_none is None and + outer_offsets_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {i}") + elif fill_type == FillType.ChunkCombinedOffsetOffset: + if TYPE_CHECKING: + filled = cast(cpy.FillReturn_ChunkCombinedOffsetOffset, filled) + _check_tuple_of_lists_with_same_length(filled, 3, allow_empty_lists=False) + for i, (points_or_none, offsets_or_none, outer_offsets_or_none) in enumerate(zip(*filled)): + if (points_or_none is not None and offsets_or_none is not None and + outer_offsets_or_none is not None): + check_point_array(points_or_none) + check_offset_array(offsets_or_none) + check_offset_array(outer_offsets_or_none) + if offsets_or_none[-1] != len(points_or_none): + raise ValueError(f"Inconsistent points and offsets in chunk {i}") + if outer_offsets_or_none[-1] != len(offsets_or_none) - 1: + raise ValueError(f"Inconsistent offsets and outer_offsets in chunk {i}") + elif not (points_or_none is None and offsets_or_none is None and + outer_offsets_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {i}") + else: + raise ValueError(f"Invalid FillType {fill_type}") + + +def check_lines(lines: cpy.LineReturn, line_type: LineType | str) -> None: + line_type = as_line_type(line_type) + + if line_type == LineType.Separate: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_Separate, lines) + if not isinstance(lines, list): + raise TypeError(f"Expected list not {type(lines)}") + for points in lines: + check_point_array(points) + elif line_type == LineType.SeparateCode: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_SeparateCode, lines) + _check_tuple_of_lists_with_same_length(lines, 2) + for i, (points, codes) in enumerate(zip(*lines)): + check_point_array(points) + check_code_array(codes) + if len(points) != len(codes): + raise ValueError(f"Points and codes have different lengths in line {i}") + elif line_type == LineType.ChunkCombinedCode: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedCode, lines) + _check_tuple_of_lists_with_same_length(lines, 2, allow_empty_lists=False) + for chunk, (points_or_none, codes_or_none) in enumerate(zip(*lines)): + if points_or_none is not None and codes_or_none is not None: + check_point_array(points_or_none) + check_code_array(codes_or_none) + if len(points_or_none) != len(codes_or_none): + raise ValueError(f"Points and codes have different lengths in chunk {chunk}") + elif not (points_or_none is None and codes_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {chunk}") + elif line_type == LineType.ChunkCombinedOffset: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedOffset, lines) + _check_tuple_of_lists_with_same_length(lines, 2, allow_empty_lists=False) + for chunk, (points_or_none, offsets_or_none) in enumerate(zip(*lines)): + if points_or_none is not None and offsets_or_none is not None: + check_point_array(points_or_none) + check_offset_array(offsets_or_none) + if offsets_or_none[-1] != len(points_or_none): + raise ValueError(f"Inconsistent points and offsets in chunk {chunk}") + elif not (points_or_none is None and offsets_or_none is None): + raise ValueError(f"Inconsistent Nones in chunk {chunk}") + elif line_type == LineType.ChunkCombinedNan: + if TYPE_CHECKING: + lines = cast(cpy.LineReturn_ChunkCombinedNan, lines) + _check_tuple_of_lists_with_same_length(lines, 1, allow_empty_lists=False) + for chunk, points_or_none in enumerate(lines[0]): + if points_or_none is not None: + check_point_array(points_or_none) + else: + raise ValueError(f"Invalid LineType {line_type}") diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/types.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/types.py new file mode 100644 index 00000000..e704b98e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/types.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +import numpy as np + +# dtypes of arrays returned by ContourPy. +point_dtype = np.float64 +code_dtype = np.uint8 +offset_dtype = np.uint32 + +# Kind codes used in Matplotlib Paths. +MOVETO = 1 +LINETO = 2 +CLOSEPOLY = 79 diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/__init__.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/__init__.py new file mode 100644 index 00000000..fe33fcef --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/__init__.py @@ -0,0 +1,5 @@ +from __future__ import annotations + +from contourpy.util._build_config import build_config + +__all__ = ["build_config"] diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/_build_config.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/_build_config.py new file mode 100644 index 00000000..be03ff8d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/_build_config.py @@ -0,0 +1,60 @@ +# _build_config.py.in is converted into _build_config.py during the meson build process. + +from __future__ import annotations + + +def build_config() -> dict[str, str]: + """ + Return a dictionary containing build configuration settings. + + All dictionary keys and values are strings, for example ``False`` is + returned as ``"False"``. + + .. versionadded:: 1.1.0 + """ + return dict( + # Python settings + python_version="3.9", + python_install_dir=r"/usr/local/lib/python3.9/site-packages/", + python_path=r"/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/build-env-zs6oj9xe/bin/python", + + # Package versions + contourpy_version="1.2.0", + meson_version="1.2.3", + mesonpy_version="0.15.0", + pybind11_version="2.11.1", + + # Misc meson settings + meson_backend="ninja", + build_dir=r"/Users/runner/work/contourpy/contourpy/.mesonpy-o59qzh5e/lib/contourpy/util", + source_dir=r"/Users/runner/work/contourpy/contourpy/lib/contourpy/util", + cross_build="True", + + # Build options + build_options=r"-Dbuildtype=release -Db_ndebug=if-release -Db_vscrt=md -Dvsenv=True --cross-file=/Users/runner/work/contourpy/contourpy/.mesonpy-o59qzh5e/meson-python-cross-file.ini --native-file=/Users/runner/work/contourpy/contourpy/.mesonpy-o59qzh5e/meson-python-native-file.ini", + buildtype="release", + cpp_std="c++17", + debug="False", + optimization="3", + vsenv="True", + b_ndebug="if-release", + b_vscrt="from_buildtype", + + # C++ compiler + compiler_name="clang", + compiler_version="13.0.0", + linker_id="ld64", + compile_command="c++ -arch arm64", + + # Host machine + host_cpu="arm64", + host_cpu_family="aarch64", + host_cpu_endian="little", + host_cpu_system="darwin", + + # Build machine, same as host machine if not a cross_build + build_cpu="x86_64", + build_cpu_family="x86_64", + build_cpu_endian="little", + build_cpu_system="darwin", + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_renderer.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_renderer.py new file mode 100644 index 00000000..c467fe9f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_renderer.py @@ -0,0 +1,336 @@ +from __future__ import annotations + +import io +from typing import TYPE_CHECKING, Any + +from bokeh.io import export_png, export_svg, show +from bokeh.io.export import get_screenshot_as_png +from bokeh.layouts import gridplot +from bokeh.models.annotations.labels import Label +from bokeh.palettes import Category10 +from bokeh.plotting import figure +import numpy as np + +from contourpy import FillType, LineType +from contourpy.enum_util import as_fill_type, as_line_type +from contourpy.util.bokeh_util import filled_to_bokeh, lines_to_bokeh +from contourpy.util.renderer import Renderer + +if TYPE_CHECKING: + from bokeh.models import GridPlot + from bokeh.palettes import Palette + from numpy.typing import ArrayLike + from selenium.webdriver.remote.webdriver import WebDriver + + from contourpy._contourpy import FillReturn, LineReturn + + +class BokehRenderer(Renderer): + """Utility renderer using Bokeh to render a grid of plots over the same (x, y) range. + + Args: + nrows (int, optional): Number of rows of plots, default ``1``. + ncols (int, optional): Number of columns of plots, default ``1``. + figsize (tuple(float, float), optional): Figure size in inches (assuming 100 dpi), default + ``(9, 9)``. + show_frame (bool, optional): Whether to show frame and axes ticks, default ``True``. + want_svg (bool, optional): Whether output is required in SVG format or not, default + ``False``. + + Warning: + :class:`~contourpy.util.bokeh_renderer.BokehRenderer`, unlike + :class:`~contourpy.util.mpl_renderer.MplRenderer`, needs to be told in advance if output to + SVG format will be required later, otherwise it will assume PNG output. + """ + _figures: list[figure] + _layout: GridPlot + _palette: Palette + _want_svg: bool + + def __init__( + self, + nrows: int = 1, + ncols: int = 1, + figsize: tuple[float, float] = (9, 9), + show_frame: bool = True, + want_svg: bool = False, + ) -> None: + self._want_svg = want_svg + self._palette = Category10[10] + + total_size = 100*np.asarray(figsize, dtype=int) # Assuming 100 dpi. + + nfigures = nrows*ncols + self._figures = [] + backend = "svg" if self._want_svg else "canvas" + for _ in range(nfigures): + fig = figure(output_backend=backend) + fig.xgrid.visible = False + fig.ygrid.visible = False + self._figures.append(fig) + if not show_frame: + fig.outline_line_color = None # type: ignore[assignment] + fig.axis.visible = False + + self._layout = gridplot( + self._figures, ncols=ncols, toolbar_location=None, # type: ignore[arg-type] + width=total_size[0] // ncols, height=total_size[1] // nrows) + + def _convert_color(self, color: str) -> str: + if isinstance(color, str) and color[0] == "C": + index = int(color[1:]) + color = self._palette[index] + return color + + def _get_figure(self, ax: figure | int) -> figure: + if isinstance(ax, int): + ax = self._figures[ax] + return ax + + def filled( + self, + filled: FillReturn, + fill_type: FillType | str, + ax: figure | int = 0, + color: str = "C0", + alpha: float = 0.7, + ) -> None: + """Plot filled contours on a single plot. + + Args: + filled (sequence of arrays): Filled contour data as returned by + :func:`~contourpy.ContourGenerator.filled`. + fill_type (FillType or str): Type of ``filled`` data as returned by + :attr:`~contourpy.ContourGenerator.fill_type`, or a string equivalent. + ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. + color (str, optional): Color to plot with. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``Category10`` palette. Default ``"C0"``. + alpha (float, optional): Opacity to plot with, default ``0.7``. + """ + fill_type = as_fill_type(fill_type) + fig = self._get_figure(ax) + color = self._convert_color(color) + xs, ys = filled_to_bokeh(filled, fill_type) + if len(xs) > 0: + fig.multi_polygons(xs=[xs], ys=[ys], color=color, fill_alpha=alpha, line_width=0) + + def grid( + self, + x: ArrayLike, + y: ArrayLike, + ax: figure | int = 0, + color: str = "black", + alpha: float = 0.1, + point_color: str | None = None, + quad_as_tri_alpha: float = 0, + ) -> None: + """Plot quad grid lines on a single plot. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. + color (str, optional): Color to plot grid lines, default ``"black"``. + alpha (float, optional): Opacity to plot lines with, default ``0.1``. + point_color (str, optional): Color to plot grid points or ``None`` if grid points + should not be plotted, default ``None``. + quad_as_tri_alpha (float, optional): Opacity to plot ``quad_as_tri`` grid, default + ``0``. + + Colors may be a string color or the letter ``"C"`` followed by an integer in the range + ``"C0"`` to ``"C9"`` to use a color from the ``Category10`` palette. + + Warning: + ``quad_as_tri_alpha > 0`` plots all quads as though they are unmasked. + """ + fig = self._get_figure(ax) + x, y = self._grid_as_2d(x, y) + xs = [row for row in x] + [row for row in x.T] + ys = [row for row in y] + [row for row in y.T] + kwargs = dict(line_color=color, alpha=alpha) + fig.multi_line(xs, ys, **kwargs) + if quad_as_tri_alpha > 0: + # Assumes no quad mask. + xmid = (0.25*(x[:-1, :-1] + x[1:, :-1] + x[:-1, 1:] + x[1:, 1:])).ravel() + ymid = (0.25*(y[:-1, :-1] + y[1:, :-1] + y[:-1, 1:] + y[1:, 1:])).ravel() + fig.multi_line( + [row for row in np.stack((x[:-1, :-1].ravel(), xmid, x[1:, 1:].ravel()), axis=1)], + [row for row in np.stack((y[:-1, :-1].ravel(), ymid, y[1:, 1:].ravel()), axis=1)], + **kwargs) + fig.multi_line( + [row for row in np.stack((x[:-1, 1:].ravel(), xmid, x[1:, :-1].ravel()), axis=1)], + [row for row in np.stack((y[:-1, 1:].ravel(), ymid, y[1:, :-1].ravel()), axis=1)], + **kwargs) + if point_color is not None: + fig.circle( + x=x.ravel(), y=y.ravel(), fill_color=color, line_color=None, alpha=alpha, size=8) + + def lines( + self, + lines: LineReturn, + line_type: LineType | str, + ax: figure | int = 0, + color: str = "C0", + alpha: float = 1.0, + linewidth: float = 1, + ) -> None: + """Plot contour lines on a single plot. + + Args: + lines (sequence of arrays): Contour line data as returned by + :func:`~contourpy.ContourGenerator.lines`. + line_type (LineType or str): Type of ``lines`` data as returned by + :attr:`~contourpy.ContourGenerator.line_type`, or a string equivalent. + ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. + color (str, optional): Color to plot lines. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``Category10`` palette. Default ``"C0"``. + alpha (float, optional): Opacity to plot lines with, default ``1.0``. + linewidth (float, optional): Width of lines, default ``1``. + + Note: + Assumes all lines are open line strips not closed line loops. + """ + line_type = as_line_type(line_type) + fig = self._get_figure(ax) + color = self._convert_color(color) + xs, ys = lines_to_bokeh(lines, line_type) + if xs is not None: + fig.line(xs, ys, line_color=color, line_alpha=alpha, line_width=linewidth) + + def mask( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike | np.ma.MaskedArray[Any, Any], + ax: figure | int = 0, + color: str = "black", + ) -> None: + """Plot masked out grid points as circles on a single plot. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + z (masked array of shape (ny, nx): z-values. + ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. + color (str, optional): Circle color, default ``"black"``. + """ + mask = np.ma.getmask(z) # type: ignore[no-untyped-call] + if mask is np.ma.nomask: + return + fig = self._get_figure(ax) + color = self._convert_color(color) + x, y = self._grid_as_2d(x, y) + fig.circle(x[mask], y[mask], fill_color=color, size=10) + + def save( + self, + filename: str, + transparent: bool = False, + *, + webdriver: WebDriver | None = None, + ) -> None: + """Save plots to SVG or PNG file. + + Args: + filename (str): Filename to save to. + transparent (bool, optional): Whether background should be transparent, default + ``False``. + webdriver (WebDriver, optional): Selenium WebDriver instance to use to create the image. + + .. versionadded:: 1.1.1 + + Warning: + To output to SVG file, ``want_svg=True`` must have been passed to the constructor. + """ + if transparent: + for fig in self._figures: + fig.background_fill_color = None # type: ignore[assignment] + fig.border_fill_color = None # type: ignore[assignment] + + if self._want_svg: + export_svg(self._layout, filename=filename, webdriver=webdriver) + else: + export_png(self._layout, filename=filename, webdriver=webdriver) + + def save_to_buffer(self, *, webdriver: WebDriver | None = None) -> io.BytesIO: + """Save plots to an ``io.BytesIO`` buffer. + + Args: + webdriver (WebDriver, optional): Selenium WebDriver instance to use to create the image. + + .. versionadded:: 1.1.1 + + Return: + BytesIO: PNG image buffer. + """ + image = get_screenshot_as_png(self._layout, driver=webdriver) + buffer = io.BytesIO() + image.save(buffer, "png") + return buffer + + def show(self) -> None: + """Show plots in web browser, in usual Bokeh manner. + """ + show(self._layout) + + def title(self, title: str, ax: figure | int = 0, color: str | None = None) -> None: + """Set the title of a single plot. + + Args: + title (str): Title text. + ax (int or Bokeh Figure, optional): Which plot to set the title of, default ``0``. + color (str, optional): Color to set title. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``Category10`` palette. Default ``None`` which is ``black``. + """ + fig = self._get_figure(ax) + fig.title = title # type: ignore[assignment] + fig.title.align = "center" # type: ignore[attr-defined] + if color is not None: + fig.title.text_color = self._convert_color(color) # type: ignore[attr-defined] + + def z_values( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + ax: figure | int = 0, + color: str = "green", + fmt: str = ".1f", + quad_as_tri: bool = False, + ) -> None: + """Show ``z`` values on a single plot. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + z (array-like of shape (ny, nx): z-values. + ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. + color (str, optional): Color of added text. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``Category10`` palette. Default ``"green"``. + fmt (str, optional): Format to display z-values, default ``".1f"``. + quad_as_tri (bool, optional): Whether to show z-values at the ``quad_as_tri`` centres + of quads. + + Warning: + ``quad_as_tri=True`` shows z-values for all quads, even if masked. + """ + fig = self._get_figure(ax) + color = self._convert_color(color) + x, y = self._grid_as_2d(x, y) + z = np.asarray(z) + ny, nx = z.shape + kwargs = dict(text_color=color, text_align="center", text_baseline="middle") + for j in range(ny): + for i in range(nx): + fig.add_layout(Label(x=x[j, i], y=y[j, i], text=f"{z[j, i]:{fmt}}", **kwargs)) + if quad_as_tri: + for j in range(ny-1): + for i in range(nx-1): + xx = np.mean(x[j:j+2, i:i+2]) + yy = np.mean(y[j:j+2, i:i+2]) + zz = np.mean(z[j:j+2, i:i+2]) + fig.add_layout(Label(x=xx, y=yy, text=f"{zz:{fmt}}", **kwargs)) diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_util.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_util.py new file mode 100644 index 00000000..80b9396e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/bokeh_util.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from contourpy import FillType, LineType +from contourpy.array import offsets_from_codes +from contourpy.convert import convert_lines +from contourpy.dechunk import dechunk_lines + +if TYPE_CHECKING: + from contourpy._contourpy import ( + CoordinateArray, FillReturn, LineReturn, LineReturn_ChunkCombinedNan, + ) + + +def filled_to_bokeh( + filled: FillReturn, + fill_type: FillType, +) -> tuple[list[list[CoordinateArray]], list[list[CoordinateArray]]]: + xs: list[list[CoordinateArray]] = [] + ys: list[list[CoordinateArray]] = [] + if fill_type in (FillType.OuterOffset, FillType.ChunkCombinedOffset, + FillType.OuterCode, FillType.ChunkCombinedCode): + have_codes = fill_type in (FillType.OuterCode, FillType.ChunkCombinedCode) + + for points, offsets in zip(*filled): + if points is None: + continue + if have_codes: + offsets = offsets_from_codes(offsets) + xs.append([]) # New outer with zero or more holes. + ys.append([]) + for i in range(len(offsets)-1): + xys = points[offsets[i]:offsets[i+1]] + xs[-1].append(xys[:, 0]) + ys[-1].append(xys[:, 1]) + elif fill_type in (FillType.ChunkCombinedCodeOffset, FillType.ChunkCombinedOffsetOffset): + for points, codes_or_offsets, outer_offsets in zip(*filled): + if points is None: + continue + for j in range(len(outer_offsets)-1): + if fill_type == FillType.ChunkCombinedCodeOffset: + codes = codes_or_offsets[outer_offsets[j]:outer_offsets[j+1]] + offsets = offsets_from_codes(codes) + outer_offsets[j] + else: + offsets = codes_or_offsets[outer_offsets[j]:outer_offsets[j+1]+1] + xs.append([]) # New outer with zero or more holes. + ys.append([]) + for k in range(len(offsets)-1): + xys = points[offsets[k]:offsets[k+1]] + xs[-1].append(xys[:, 0]) + ys[-1].append(xys[:, 1]) + else: + raise RuntimeError(f"Conversion of FillType {fill_type} to Bokeh is not implemented") + + return xs, ys + + +def lines_to_bokeh( + lines: LineReturn, + line_type: LineType, +) -> tuple[CoordinateArray | None, CoordinateArray | None]: + lines = convert_lines(lines, line_type, LineType.ChunkCombinedNan) + lines = dechunk_lines(lines, LineType.ChunkCombinedNan) + if TYPE_CHECKING: + lines = cast(LineReturn_ChunkCombinedNan, lines) + points = lines[0][0] + if points is None: + return None, None + else: + return points[:, 0], points[:, 1] diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/data.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/data.py new file mode 100644 index 00000000..5ab26172 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/data.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +import numpy as np + +if TYPE_CHECKING: + from contourpy._contourpy import CoordinateArray + + +def simple( + shape: tuple[int, int], want_mask: bool = False, +) -> tuple[CoordinateArray, CoordinateArray, CoordinateArray | np.ma.MaskedArray[Any, Any]]: + """Return simple test data consisting of the sum of two gaussians. + + Args: + shape (tuple(int, int)): 2D shape of data to return. + want_mask (bool, optional): Whether test data should be masked or not, default ``False``. + + Return: + Tuple of 3 arrays: ``x``, ``y``, ``z`` test data, ``z`` will be masked if + ``want_mask=True``. + """ + ny, nx = shape + x = np.arange(nx, dtype=np.float64) + y = np.arange(ny, dtype=np.float64) + x, y = np.meshgrid(x, y) + + xscale = nx - 1.0 + yscale = ny - 1.0 + + # z is sum of 2D gaussians. + amp = np.asarray([1.0, -1.0, 0.8, -0.9, 0.7]) + mid = np.asarray([[0.4, 0.2], [0.3, 0.8], [0.9, 0.75], [0.7, 0.3], [0.05, 0.7]]) + width = np.asarray([0.4, 0.2, 0.2, 0.2, 0.1]) + + z = np.zeros_like(x) + for i in range(len(amp)): + z += amp[i]*np.exp(-((x/xscale - mid[i, 0])**2 + (y/yscale - mid[i, 1])**2) / width[i]**2) + + if want_mask: + mask = np.logical_or( + ((x/xscale - 1.0)**2 / 0.2 + (y/yscale - 0.0)**2 / 0.1) < 1.0, + ((x/xscale - 0.2)**2 / 0.02 + (y/yscale - 0.45)**2 / 0.08) < 1.0, + ) + z = np.ma.array(z, mask=mask) # type: ignore[no-untyped-call] + + return x, y, z + + +def random( + shape: tuple[int, int], seed: int = 2187, mask_fraction: float = 0.0, +) -> tuple[CoordinateArray, CoordinateArray, CoordinateArray | np.ma.MaskedArray[Any, Any]]: + """Return random test data. + + Args: + shape (tuple(int, int)): 2D shape of data to return. + seed (int, optional): Seed for random number generator, default 2187. + mask_fraction (float, optional): Fraction of elements to mask, default 0. + + Return: + Tuple of 3 arrays: ``x``, ``y``, ``z`` test data, ``z`` will be masked if + ``mask_fraction`` is greater than zero. + """ + ny, nx = shape + x = np.arange(nx, dtype=np.float64) + y = np.arange(ny, dtype=np.float64) + x, y = np.meshgrid(x, y) + + rng = np.random.default_rng(seed) + z = rng.uniform(size=shape) + + if mask_fraction > 0.0: + mask_fraction = min(mask_fraction, 0.99) + mask = rng.uniform(size=shape) < mask_fraction + z = np.ma.array(z, mask=mask) # type: ignore[no-untyped-call] + + return x, y, z diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_renderer.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_renderer.py new file mode 100644 index 00000000..2d8997f2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_renderer.py @@ -0,0 +1,532 @@ +from __future__ import annotations + +from collections.abc import Sequence +import io +from typing import TYPE_CHECKING, Any, cast + +import matplotlib.collections as mcollections +import matplotlib.pyplot as plt +import numpy as np + +from contourpy import FillType, LineType +from contourpy.convert import convert_filled, convert_lines +from contourpy.enum_util import as_fill_type, as_line_type +from contourpy.util.mpl_util import filled_to_mpl_paths, lines_to_mpl_paths +from contourpy.util.renderer import Renderer + +if TYPE_CHECKING: + from matplotlib.axes import Axes + from matplotlib.figure import Figure + from numpy.typing import ArrayLike + + import contourpy._contourpy as cpy + + +class MplRenderer(Renderer): + """Utility renderer using Matplotlib to render a grid of plots over the same (x, y) range. + + Args: + nrows (int, optional): Number of rows of plots, default ``1``. + ncols (int, optional): Number of columns of plots, default ``1``. + figsize (tuple(float, float), optional): Figure size in inches, default ``(9, 9)``. + show_frame (bool, optional): Whether to show frame and axes ticks, default ``True``. + backend (str, optional): Matplotlib backend to use or ``None`` for default backend. + Default ``None``. + gridspec_kw (dict, optional): Gridspec keyword arguments to pass to ``plt.subplots``, + default None. + """ + _axes: Sequence[Axes] + _fig: Figure + _want_tight: bool + + def __init__( + self, + nrows: int = 1, + ncols: int = 1, + figsize: tuple[float, float] = (9, 9), + show_frame: bool = True, + backend: str | None = None, + gridspec_kw: dict[str, Any] | None = None, + ) -> None: + if backend is not None: + import matplotlib + matplotlib.use(backend) + + kwargs: dict[str, Any] = dict(figsize=figsize, squeeze=False, sharex=True, sharey=True) + if gridspec_kw is not None: + kwargs["gridspec_kw"] = gridspec_kw + else: + kwargs["subplot_kw"] = dict(aspect="equal") + + self._fig, axes = plt.subplots(nrows, ncols, **kwargs) + self._axes = axes.flatten() + if not show_frame: + for ax in self._axes: + ax.axis("off") + + self._want_tight = True + + def __del__(self) -> None: + if hasattr(self, "_fig"): + plt.close(self._fig) + + def _autoscale(self) -> None: + # Using axes._need_autoscale attribute if need to autoscale before rendering after adding + # lines/filled. Only want to autoscale once per axes regardless of how many lines/filled + # added. + for ax in self._axes: + if getattr(ax, "_need_autoscale", False): + ax.autoscale_view(tight=True) + ax._need_autoscale = False # type: ignore[attr-defined] + if self._want_tight and len(self._axes) > 1: + self._fig.tight_layout() + + def _get_ax(self, ax: Axes | int) -> Axes: + if isinstance(ax, int): + ax = self._axes[ax] + return ax + + def filled( + self, + filled: cpy.FillReturn, + fill_type: FillType | str, + ax: Axes | int = 0, + color: str = "C0", + alpha: float = 0.7, + ) -> None: + """Plot filled contours on a single Axes. + + Args: + filled (sequence of arrays): Filled contour data as returned by + :func:`~contourpy.ContourGenerator.filled`. + fill_type (FillType or str): Type of ``filled`` data as returned by + :attr:`~contourpy.ContourGenerator.fill_type`, or string equivalent + ax (int or Maplotlib Axes, optional): Which axes to plot on, default ``0``. + color (str, optional): Color to plot with. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``tab10`` colormap. Default ``"C0"``. + alpha (float, optional): Opacity to plot with, default ``0.7``. + """ + fill_type = as_fill_type(fill_type) + ax = self._get_ax(ax) + paths = filled_to_mpl_paths(filled, fill_type) + collection = mcollections.PathCollection( + paths, facecolors=color, edgecolors="none", lw=0, alpha=alpha) + ax.add_collection(collection) + ax._need_autoscale = True # type: ignore[attr-defined] + + def grid( + self, + x: ArrayLike, + y: ArrayLike, + ax: Axes | int = 0, + color: str = "black", + alpha: float = 0.1, + point_color: str | None = None, + quad_as_tri_alpha: float = 0, + ) -> None: + """Plot quad grid lines on a single Axes. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + ax (int or Matplotlib Axes, optional): Which Axes to plot on, default ``0``. + color (str, optional): Color to plot grid lines, default ``"black"``. + alpha (float, optional): Opacity to plot lines with, default ``0.1``. + point_color (str, optional): Color to plot grid points or ``None`` if grid points + should not be plotted, default ``None``. + quad_as_tri_alpha (float, optional): Opacity to plot ``quad_as_tri`` grid, default 0. + + Colors may be a string color or the letter ``"C"`` followed by an integer in the range + ``"C0"`` to ``"C9"`` to use a color from the ``tab10`` colormap. + + Warning: + ``quad_as_tri_alpha > 0`` plots all quads as though they are unmasked. + """ + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + kwargs: dict[str, Any] = dict(color=color, alpha=alpha) + ax.plot(x, y, x.T, y.T, **kwargs) + if quad_as_tri_alpha > 0: + # Assumes no quad mask. + xmid = 0.25*(x[:-1, :-1] + x[1:, :-1] + x[:-1, 1:] + x[1:, 1:]) + ymid = 0.25*(y[:-1, :-1] + y[1:, :-1] + y[:-1, 1:] + y[1:, 1:]) + kwargs["alpha"] = quad_as_tri_alpha + ax.plot( + np.stack((x[:-1, :-1], xmid, x[1:, 1:])).reshape((3, -1)), + np.stack((y[:-1, :-1], ymid, y[1:, 1:])).reshape((3, -1)), + np.stack((x[1:, :-1], xmid, x[:-1, 1:])).reshape((3, -1)), + np.stack((y[1:, :-1], ymid, y[:-1, 1:])).reshape((3, -1)), + **kwargs) + if point_color is not None: + ax.plot(x, y, color=point_color, alpha=alpha, marker="o", lw=0) + ax._need_autoscale = True # type: ignore[attr-defined] + + def lines( + self, + lines: cpy.LineReturn, + line_type: LineType | str, + ax: Axes | int = 0, + color: str = "C0", + alpha: float = 1.0, + linewidth: float = 1, + ) -> None: + """Plot contour lines on a single Axes. + + Args: + lines (sequence of arrays): Contour line data as returned by + :func:`~contourpy.ContourGenerator.lines`. + line_type (LineType or str): Type of ``lines`` data as returned by + :attr:`~contourpy.ContourGenerator.line_type`, or string equivalent. + ax (int or Matplotlib Axes, optional): Which Axes to plot on, default ``0``. + color (str, optional): Color to plot lines. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``tab10`` colormap. Default ``"C0"``. + alpha (float, optional): Opacity to plot lines with, default ``1.0``. + linewidth (float, optional): Width of lines, default ``1``. + """ + line_type = as_line_type(line_type) + ax = self._get_ax(ax) + paths = lines_to_mpl_paths(lines, line_type) + collection = mcollections.PathCollection( + paths, facecolors="none", edgecolors=color, lw=linewidth, alpha=alpha) + ax.add_collection(collection) + ax._need_autoscale = True # type: ignore[attr-defined] + + def mask( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike | np.ma.MaskedArray[Any, Any], + ax: Axes | int = 0, + color: str = "black", + ) -> None: + """Plot masked out grid points as circles on a single Axes. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + z (masked array of shape (ny, nx): z-values. + ax (int or Matplotlib Axes, optional): Which Axes to plot on, default ``0``. + color (str, optional): Circle color, default ``"black"``. + """ + mask = np.ma.getmask(z) # type: ignore[no-untyped-call] + if mask is np.ma.nomask: + return + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + ax.plot(x[mask], y[mask], "o", c=color) + + def save(self, filename: str, transparent: bool = False) -> None: + """Save plots to SVG or PNG file. + + Args: + filename (str): Filename to save to. + transparent (bool, optional): Whether background should be transparent, default + ``False``. + """ + self._autoscale() + self._fig.savefig(filename, transparent=transparent) + + def save_to_buffer(self) -> io.BytesIO: + """Save plots to an ``io.BytesIO`` buffer. + + Return: + BytesIO: PNG image buffer. + """ + self._autoscale() + buf = io.BytesIO() + self._fig.savefig(buf, format="png") + buf.seek(0) + return buf + + def show(self) -> None: + """Show plots in an interactive window, in the usual Matplotlib manner. + """ + self._autoscale() + plt.show() + + def title(self, title: str, ax: Axes | int = 0, color: str | None = None) -> None: + """Set the title of a single Axes. + + Args: + title (str): Title text. + ax (int or Matplotlib Axes, optional): Which Axes to set the title of, default ``0``. + color (str, optional): Color to set title. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``tab10`` colormap. Default is ``None`` which uses Matplotlib's default title color + that depends on the stylesheet in use. + """ + if color: + self._get_ax(ax).set_title(title, color=color) + else: + self._get_ax(ax).set_title(title) + + def z_values( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + ax: Axes | int = 0, + color: str = "green", + fmt: str = ".1f", + quad_as_tri: bool = False, + ) -> None: + """Show ``z`` values on a single Axes. + + Args: + x (array-like of shape (ny, nx) or (nx,)): The x-coordinates of the grid points. + y (array-like of shape (ny, nx) or (ny,)): The y-coordinates of the grid points. + z (array-like of shape (ny, nx): z-values. + ax (int or Matplotlib Axes, optional): Which Axes to plot on, default ``0``. + color (str, optional): Color of added text. May be a string color or the letter ``"C"`` + followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the + ``tab10`` colormap. Default ``"green"``. + fmt (str, optional): Format to display z-values, default ``".1f"``. + quad_as_tri (bool, optional): Whether to show z-values at the ``quad_as_tri`` centers + of quads. + + Warning: + ``quad_as_tri=True`` shows z-values for all quads, even if masked. + """ + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + z = np.asarray(z) + ny, nx = z.shape + for j in range(ny): + for i in range(nx): + ax.text(x[j, i], y[j, i], f"{z[j, i]:{fmt}}", ha="center", va="center", + color=color, clip_on=True) + if quad_as_tri: + for j in range(ny-1): + for i in range(nx-1): + xx = np.mean(x[j:j+2, i:i+2]) + yy = np.mean(y[j:j+2, i:i+2]) + zz = np.mean(z[j:j+2, i:i+2]) + ax.text(xx, yy, f"{zz:{fmt}}", ha="center", va="center", color=color, + clip_on=True) + + +class MplTestRenderer(MplRenderer): + """Test renderer implemented using Matplotlib. + + No whitespace around plots and no spines/ticks displayed. + Uses Agg backend, so can only save to file/buffer, cannot call ``show()``. + """ + def __init__( + self, + nrows: int = 1, + ncols: int = 1, + figsize: tuple[float, float] = (9, 9), + ) -> None: + gridspec = { + "left": 0.01, + "right": 0.99, + "top": 0.99, + "bottom": 0.01, + "wspace": 0.01, + "hspace": 0.01, + } + super().__init__( + nrows, ncols, figsize, show_frame=True, backend="Agg", gridspec_kw=gridspec, + ) + + for ax in self._axes: + ax.set_xmargin(0.0) + ax.set_ymargin(0.0) + ax.set_xticks([]) + ax.set_yticks([]) + + self._want_tight = False + + +class MplDebugRenderer(MplRenderer): + """Debug renderer implemented using Matplotlib. + + Extends ``MplRenderer`` to add extra information to help in debugging such as markers, arrows, + text, etc. + """ + def __init__( + self, + nrows: int = 1, + ncols: int = 1, + figsize: tuple[float, float] = (9, 9), + show_frame: bool = True, + ) -> None: + super().__init__(nrows, ncols, figsize, show_frame) + + def _arrow( + self, + ax: Axes, + line_start: cpy.CoordinateArray, + line_end: cpy.CoordinateArray, + color: str, + alpha: float, + arrow_size: float, + ) -> None: + mid = 0.5*(line_start + line_end) + along = line_end - line_start + along /= np.sqrt(np.dot(along, along)) # Unit vector. + right = np.asarray((along[1], -along[0])) + arrow = np.stack(( + mid - (along*0.5 - right)*arrow_size, + mid + along*0.5*arrow_size, + mid - (along*0.5 + right)*arrow_size, + )) + ax.plot(arrow[:, 0], arrow[:, 1], "-", c=color, alpha=alpha) + + def filled( + self, + filled: cpy.FillReturn, + fill_type: FillType | str, + ax: Axes | int = 0, + color: str = "C1", + alpha: float = 0.7, + line_color: str = "C0", + line_alpha: float = 0.7, + point_color: str = "C0", + start_point_color: str = "red", + arrow_size: float = 0.1, + ) -> None: + fill_type = as_fill_type(fill_type) + super().filled(filled, fill_type, ax, color, alpha) + + if line_color is None and point_color is None: + return + + ax = self._get_ax(ax) + filled = convert_filled(filled, fill_type, FillType.ChunkCombinedOffset) + + # Lines. + if line_color is not None: + for points, offsets in zip(*filled): + if points is None: + continue + for start, end in zip(offsets[:-1], offsets[1:]): + xys = points[start:end] + ax.plot(xys[:, 0], xys[:, 1], c=line_color, alpha=line_alpha) + + if arrow_size > 0.0: + n = len(xys) + for i in range(n-1): + self._arrow(ax, xys[i], xys[i+1], line_color, line_alpha, arrow_size) + + # Points. + if point_color is not None: + for points, offsets in zip(*filled): + if points is None: + continue + mask = np.ones(offsets[-1], dtype=bool) + mask[offsets[1:]-1] = False # Exclude end points. + if start_point_color is not None: + start_indices = offsets[:-1] + mask[start_indices] = False # Exclude start points. + ax.plot( + points[:, 0][mask], points[:, 1][mask], "o", c=point_color, alpha=line_alpha) + + if start_point_color is not None: + ax.plot(points[:, 0][start_indices], points[:, 1][start_indices], "o", + c=start_point_color, alpha=line_alpha) + + def lines( + self, + lines: cpy.LineReturn, + line_type: LineType | str, + ax: Axes | int = 0, + color: str = "C0", + alpha: float = 1.0, + linewidth: float = 1, + point_color: str = "C0", + start_point_color: str = "red", + arrow_size: float = 0.1, + ) -> None: + line_type = as_line_type(line_type) + super().lines(lines, line_type, ax, color, alpha, linewidth) + + if arrow_size == 0.0 and point_color is None: + return + + ax = self._get_ax(ax) + separate_lines = convert_lines(lines, line_type, LineType.Separate) + if TYPE_CHECKING: + separate_lines = cast(cpy.LineReturn_Separate, separate_lines) + + if arrow_size > 0.0: + for line in separate_lines: + for i in range(len(line)-1): + self._arrow(ax, line[i], line[i+1], color, alpha, arrow_size) + + if point_color is not None: + for line in separate_lines: + start_index = 0 + end_index = len(line) + if start_point_color is not None: + ax.plot(line[0, 0], line[0, 1], "o", c=start_point_color, alpha=alpha) + start_index = 1 + if line[0][0] == line[-1][0] and line[0][1] == line[-1][1]: + end_index -= 1 + ax.plot(line[start_index:end_index, 0], line[start_index:end_index, 1], "o", + c=color, alpha=alpha) + + def point_numbers( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + ax: Axes | int = 0, + color: str = "red", + ) -> None: + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + z = np.asarray(z) + ny, nx = z.shape + for j in range(ny): + for i in range(nx): + quad = i + j*nx + ax.text(x[j, i], y[j, i], str(quad), ha="right", va="top", color=color, + clip_on=True) + + def quad_numbers( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + ax: Axes | int = 0, + color: str = "blue", + ) -> None: + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + z = np.asarray(z) + ny, nx = z.shape + for j in range(1, ny): + for i in range(1, nx): + quad = i + j*nx + xmid = x[j-1:j+1, i-1:i+1].mean() + ymid = y[j-1:j+1, i-1:i+1].mean() + ax.text(xmid, ymid, str(quad), ha="center", va="center", color=color, clip_on=True) + + def z_levels( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + lower_level: float, + upper_level: float | None = None, + ax: Axes | int = 0, + color: str = "green", + ) -> None: + ax = self._get_ax(ax) + x, y = self._grid_as_2d(x, y) + z = np.asarray(z) + ny, nx = z.shape + for j in range(ny): + for i in range(nx): + zz = z[j, i] + if upper_level is not None and zz > upper_level: + z_level = 2 + elif zz > lower_level: + z_level = 1 + else: + z_level = 0 + ax.text(x[j, i], y[j, i], str(z_level), ha="left", va="bottom", color=color, + clip_on=True) diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_util.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_util.py new file mode 100644 index 00000000..10a2ccdb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/mpl_util.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +import matplotlib.path as mpath +import numpy as np + +from contourpy import FillType, LineType +from contourpy.array import codes_from_offsets + +if TYPE_CHECKING: + from contourpy._contourpy import FillReturn, LineReturn, LineReturn_Separate + + +def filled_to_mpl_paths(filled: FillReturn, fill_type: FillType) -> list[mpath.Path]: + if fill_type in (FillType.OuterCode, FillType.ChunkCombinedCode): + paths = [mpath.Path(points, codes) for points, codes in zip(*filled) if points is not None] + elif fill_type in (FillType.OuterOffset, FillType.ChunkCombinedOffset): + paths = [mpath.Path(points, codes_from_offsets(offsets)) + for points, offsets in zip(*filled) if points is not None] + elif fill_type == FillType.ChunkCombinedCodeOffset: + paths = [] + for points, codes, outer_offsets in zip(*filled): + if points is None: + continue + points = np.split(points, outer_offsets[1:-1]) + codes = np.split(codes, outer_offsets[1:-1]) + paths += [mpath.Path(p, c) for p, c in zip(points, codes)] + elif fill_type == FillType.ChunkCombinedOffsetOffset: + paths = [] + for points, offsets, outer_offsets in zip(*filled): + if points is None: + continue + for i in range(len(outer_offsets)-1): + offs = offsets[outer_offsets[i]:outer_offsets[i+1]+1] + pts = points[offs[0]:offs[-1]] + paths += [mpath.Path(pts, codes_from_offsets(offs - offs[0]))] + else: + raise RuntimeError(f"Conversion of FillType {fill_type} to MPL Paths is not implemented") + return paths + + +def lines_to_mpl_paths(lines: LineReturn, line_type: LineType) -> list[mpath.Path]: + if line_type == LineType.Separate: + if TYPE_CHECKING: + lines = cast(LineReturn_Separate, lines) + paths = [] + for line in lines: + # Drawing as Paths so that they can be closed correctly. + closed = line[0, 0] == line[-1, 0] and line[0, 1] == line[-1, 1] + paths.append(mpath.Path(line, closed=closed)) + elif line_type in (LineType.SeparateCode, LineType.ChunkCombinedCode): + paths = [mpath.Path(points, codes) for points, codes in zip(*lines) if points is not None] + elif line_type == LineType.ChunkCombinedOffset: + paths = [] + for points, offsets in zip(*lines): + if points is None: + continue + for i in range(len(offsets)-1): + line = points[offsets[i]:offsets[i+1]] + closed = line[0, 0] == line[-1, 0] and line[0, 1] == line[-1, 1] + paths.append(mpath.Path(line, closed=closed)) + elif line_type == LineType.ChunkCombinedNan: + paths = [] + for points in lines[0]: + if points is None: + continue + nan_offsets = np.nonzero(np.isnan(points[:, 0]))[0] + nan_offsets = np.concatenate([[-1], nan_offsets, [len(points)]]) + for s, e in zip(nan_offsets[:-1], nan_offsets[1:]): + line = points[s+1:e] + closed = line[0, 0] == line[-1, 0] and line[0, 1] == line[-1, 1] + paths.append(mpath.Path(line, closed=closed)) + else: + raise RuntimeError(f"Conversion of LineType {line_type} to MPL Paths is not implemented") + return paths diff --git a/dbdpy-env/lib/python3.9/site-packages/contourpy/util/renderer.py b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/renderer.py new file mode 100644 index 00000000..f4bdfdff --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/contourpy/util/renderer.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING, Any + +import numpy as np + +if TYPE_CHECKING: + import io + + from numpy.typing import ArrayLike + + from contourpy._contourpy import CoordinateArray, FillReturn, FillType, LineReturn, LineType + + +class Renderer(ABC): + """Abstract base class for renderers, defining the interface that they must implement.""" + + def _grid_as_2d(self, x: ArrayLike, y: ArrayLike) -> tuple[CoordinateArray, CoordinateArray]: + x = np.asarray(x) + y = np.asarray(y) + if x.ndim == 1: + x, y = np.meshgrid(x, y) + return x, y + + x = np.asarray(x) + y = np.asarray(y) + if x.ndim == 1: + x, y = np.meshgrid(x, y) + return x, y + + @abstractmethod + def filled( + self, + filled: FillReturn, + fill_type: FillType | str, + ax: Any = 0, + color: str = "C0", + alpha: float = 0.7, + ) -> None: + pass + + @abstractmethod + def grid( + self, + x: ArrayLike, + y: ArrayLike, + ax: Any = 0, + color: str = "black", + alpha: float = 0.1, + point_color: str | None = None, + quad_as_tri_alpha: float = 0, + ) -> None: + pass + + @abstractmethod + def lines( + self, + lines: LineReturn, + line_type: LineType | str, + ax: Any = 0, + color: str = "C0", + alpha: float = 1.0, + linewidth: float = 1, + ) -> None: + pass + + @abstractmethod + def mask( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike | np.ma.MaskedArray[Any, Any], + ax: Any = 0, + color: str = "black", + ) -> None: + pass + + @abstractmethod + def save(self, filename: str, transparent: bool = False) -> None: + pass + + @abstractmethod + def save_to_buffer(self) -> io.BytesIO: + pass + + @abstractmethod + def show(self) -> None: + pass + + @abstractmethod + def title(self, title: str, ax: Any = 0, color: str | None = None) -> None: + pass + + @abstractmethod + def z_values( + self, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + ax: Any = 0, + color: str = "green", + fmt: str = ".1f", + quad_as_tri: bool = False, + ) -> None: + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/LICENSE new file mode 100644 index 00000000..d41d8089 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2015, matplotlib project +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the matplotlib project nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/METADATA new file mode 100644 index 00000000..e81ab4fa --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/METADATA @@ -0,0 +1,78 @@ +Metadata-Version: 2.1 +Name: cycler +Version: 0.12.1 +Summary: Composable style cycles +Author-email: Thomas A Caswell +License: Copyright (c) 2015, matplotlib project + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the matplotlib project nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Project-URL: homepage, https://matplotlib.org/cycler/ +Project-URL: repository, https://github.com/matplotlib/cycler +Keywords: cycle kwargs +Classifier: License :: OSI Approved :: BSD License +Classifier: Development Status :: 4 - Beta +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE +Provides-Extra: docs +Requires-Dist: ipython ; extra == 'docs' +Requires-Dist: matplotlib ; extra == 'docs' +Requires-Dist: numpydoc ; extra == 'docs' +Requires-Dist: sphinx ; extra == 'docs' +Provides-Extra: tests +Requires-Dist: pytest ; extra == 'tests' +Requires-Dist: pytest-cov ; extra == 'tests' +Requires-Dist: pytest-xdist ; extra == 'tests' + +|PyPi|_ |Conda|_ |Supported Python versions|_ |GitHub Actions|_ |Codecov|_ + +.. |PyPi| image:: https://img.shields.io/pypi/v/cycler.svg?style=flat +.. _PyPi: https://pypi.python.org/pypi/cycler + +.. |Conda| image:: https://img.shields.io/conda/v/conda-forge/cycler +.. _Conda: https://anaconda.org/conda-forge/cycler + +.. |Supported Python versions| image:: https://img.shields.io/pypi/pyversions/cycler.svg +.. _Supported Python versions: https://pypi.python.org/pypi/cycler + +.. |GitHub Actions| image:: https://github.com/matplotlib/cycler/actions/workflows/tests.yml/badge.svg +.. _GitHub Actions: https://github.com/matplotlib/cycler/actions + +.. |Codecov| image:: https://codecov.io/github/matplotlib/cycler/badge.svg?branch=main&service=github +.. _Codecov: https://codecov.io/github/matplotlib/cycler?branch=main + +cycler: composable cycles +========================= + +Docs: https://matplotlib.org/cycler/ diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/RECORD new file mode 100644 index 00000000..baa90824 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/RECORD @@ -0,0 +1,9 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/cycler/__init__.cpython-39.pyc,, +cycler-0.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +cycler-0.12.1.dist-info/LICENSE,sha256=8SGBQ9dm2j_qZvEzlrfxXfRqgzA_Kb-Wum6Y601C9Ag,1497 +cycler-0.12.1.dist-info/METADATA,sha256=IyieGbdvHgE5Qidpbmryts0c556JcxIJv5GVFIsY7TY,3779 +cycler-0.12.1.dist-info/RECORD,, +cycler-0.12.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92 +cycler-0.12.1.dist-info/top_level.txt,sha256=D8BVVDdAAelLb2FOEz7lDpc6-AL21ylKPrMhtG6yzyE,7 +cycler/__init__.py,sha256=1JdRgv5Zzxo-W1ev7B_LWquysWP6LZH6CHk_COtIaXE,16709 +cycler/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/WHEEL new file mode 100644 index 00000000..7e688737 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/top_level.txt new file mode 100644 index 00000000..22546440 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler-0.12.1.dist-info/top_level.txt @@ -0,0 +1 @@ +cycler diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler/__init__.py b/dbdpy-env/lib/python3.9/site-packages/cycler/__init__.py new file mode 100644 index 00000000..97949547 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/cycler/__init__.py @@ -0,0 +1,573 @@ +""" +Cycler +====== + +Cycling through combinations of values, producing dictionaries. + +You can add cyclers:: + + from cycler import cycler + cc = (cycler(color=list('rgb')) + + cycler(linestyle=['-', '--', '-.'])) + for d in cc: + print(d) + +Results in:: + + {'color': 'r', 'linestyle': '-'} + {'color': 'g', 'linestyle': '--'} + {'color': 'b', 'linestyle': '-.'} + + +You can multiply cyclers:: + + from cycler import cycler + cc = (cycler(color=list('rgb')) * + cycler(linestyle=['-', '--', '-.'])) + for d in cc: + print(d) + +Results in:: + + {'color': 'r', 'linestyle': '-'} + {'color': 'r', 'linestyle': '--'} + {'color': 'r', 'linestyle': '-.'} + {'color': 'g', 'linestyle': '-'} + {'color': 'g', 'linestyle': '--'} + {'color': 'g', 'linestyle': '-.'} + {'color': 'b', 'linestyle': '-'} + {'color': 'b', 'linestyle': '--'} + {'color': 'b', 'linestyle': '-.'} +""" + + +from __future__ import annotations + +from collections.abc import Hashable, Iterable, Generator +import copy +from functools import reduce +from itertools import product, cycle +from operator import mul, add +# Dict, List, Union required for runtime cast calls +from typing import TypeVar, Generic, Callable, Union, Dict, List, Any, overload, cast + +__version__ = "0.12.1" + +K = TypeVar("K", bound=Hashable) +L = TypeVar("L", bound=Hashable) +V = TypeVar("V") +U = TypeVar("U") + + +def _process_keys( + left: Cycler[K, V] | Iterable[dict[K, V]], + right: Cycler[K, V] | Iterable[dict[K, V]] | None, +) -> set[K]: + """ + Helper function to compose cycler keys. + + Parameters + ---------- + left, right : iterable of dictionaries or None + The cyclers to be composed. + + Returns + ------- + keys : set + The keys in the composition of the two cyclers. + """ + l_peek: dict[K, V] = next(iter(left)) if left != [] else {} + r_peek: dict[K, V] = next(iter(right)) if right is not None else {} + l_key: set[K] = set(l_peek.keys()) + r_key: set[K] = set(r_peek.keys()) + if l_key & r_key: + raise ValueError("Can not compose overlapping cycles") + return l_key | r_key + + +def concat(left: Cycler[K, V], right: Cycler[K, U]) -> Cycler[K, V | U]: + r""" + Concatenate `Cycler`\s, as if chained using `itertools.chain`. + + The keys must match exactly. + + Examples + -------- + >>> num = cycler('a', range(3)) + >>> let = cycler('a', 'abc') + >>> num.concat(let) + cycler('a', [0, 1, 2, 'a', 'b', 'c']) + + Returns + ------- + `Cycler` + The concatenated cycler. + """ + if left.keys != right.keys: + raise ValueError( + "Keys do not match:\n" + "\tIntersection: {both!r}\n" + "\tDisjoint: {just_one!r}".format( + both=left.keys & right.keys, just_one=left.keys ^ right.keys + ) + ) + _l = cast(Dict[K, List[Union[V, U]]], left.by_key()) + _r = cast(Dict[K, List[Union[V, U]]], right.by_key()) + return reduce(add, (_cycler(k, _l[k] + _r[k]) for k in left.keys)) + + +class Cycler(Generic[K, V]): + """ + Composable cycles. + + This class has compositions methods: + + ``+`` + for 'inner' products (zip) + + ``+=`` + in-place ``+`` + + ``*`` + for outer products (`itertools.product`) and integer multiplication + + ``*=`` + in-place ``*`` + + and supports basic slicing via ``[]``. + + Parameters + ---------- + left, right : Cycler or None + The 'left' and 'right' cyclers. + op : func or None + Function which composes the 'left' and 'right' cyclers. + """ + + def __call__(self): + return cycle(self) + + def __init__( + self, + left: Cycler[K, V] | Iterable[dict[K, V]] | None, + right: Cycler[K, V] | None = None, + op: Any = None, + ): + """ + Semi-private init. + + Do not use this directly, use `cycler` function instead. + """ + if isinstance(left, Cycler): + self._left: Cycler[K, V] | list[dict[K, V]] = Cycler( + left._left, left._right, left._op + ) + elif left is not None: + # Need to copy the dictionary or else that will be a residual + # mutable that could lead to strange errors + self._left = [copy.copy(v) for v in left] + else: + self._left = [] + + if isinstance(right, Cycler): + self._right: Cycler[K, V] | None = Cycler( + right._left, right._right, right._op + ) + else: + self._right = None + + self._keys: set[K] = _process_keys(self._left, self._right) + self._op: Any = op + + def __contains__(self, k): + return k in self._keys + + @property + def keys(self) -> set[K]: + """The keys this Cycler knows about.""" + return set(self._keys) + + def change_key(self, old: K, new: K) -> None: + """ + Change a key in this cycler to a new name. + Modification is performed in-place. + + Does nothing if the old key is the same as the new key. + Raises a ValueError if the new key is already a key. + Raises a KeyError if the old key isn't a key. + """ + if old == new: + return + if new in self._keys: + raise ValueError( + f"Can't replace {old} with {new}, {new} is already a key" + ) + if old not in self._keys: + raise KeyError( + f"Can't replace {old} with {new}, {old} is not a key" + ) + + self._keys.remove(old) + self._keys.add(new) + + if self._right is not None and old in self._right.keys: + self._right.change_key(old, new) + + # self._left should always be non-None + # if self._keys is non-empty. + elif isinstance(self._left, Cycler): + self._left.change_key(old, new) + else: + # It should be completely safe at this point to + # assume that the old key can be found in each + # iteration. + self._left = [{new: entry[old]} for entry in self._left] + + @classmethod + def _from_iter(cls, label: K, itr: Iterable[V]) -> Cycler[K, V]: + """ + Class method to create 'base' Cycler objects + that do not have a 'right' or 'op' and for which + the 'left' object is not another Cycler. + + Parameters + ---------- + label : hashable + The property key. + + itr : iterable + Finite length iterable of the property values. + + Returns + ------- + `Cycler` + New 'base' cycler. + """ + ret: Cycler[K, V] = cls(None) + ret._left = list({label: v} for v in itr) + ret._keys = {label} + return ret + + def __getitem__(self, key: slice) -> Cycler[K, V]: + # TODO : maybe add numpy style fancy slicing + if isinstance(key, slice): + trans = self.by_key() + return reduce(add, (_cycler(k, v[key]) for k, v in trans.items())) + else: + raise ValueError("Can only use slices with Cycler.__getitem__") + + def __iter__(self) -> Generator[dict[K, V], None, None]: + if self._right is None: + for left in self._left: + yield dict(left) + else: + if self._op is None: + raise TypeError( + "Operation cannot be None when both left and right are defined" + ) + for a, b in self._op(self._left, self._right): + out = {} + out.update(a) + out.update(b) + yield out + + def __add__(self, other: Cycler[L, U]) -> Cycler[K | L, V | U]: + """ + Pair-wise combine two equal length cyclers (zip). + + Parameters + ---------- + other : Cycler + """ + if len(self) != len(other): + raise ValueError( + f"Can only add equal length cycles, not {len(self)} and {len(other)}" + ) + return Cycler( + cast(Cycler[Union[K, L], Union[V, U]], self), + cast(Cycler[Union[K, L], Union[V, U]], other), + zip + ) + + @overload + def __mul__(self, other: Cycler[L, U]) -> Cycler[K | L, V | U]: + ... + + @overload + def __mul__(self, other: int) -> Cycler[K, V]: + ... + + def __mul__(self, other): + """ + Outer product of two cyclers (`itertools.product`) or integer + multiplication. + + Parameters + ---------- + other : Cycler or int + """ + if isinstance(other, Cycler): + return Cycler( + cast(Cycler[Union[K, L], Union[V, U]], self), + cast(Cycler[Union[K, L], Union[V, U]], other), + product + ) + elif isinstance(other, int): + trans = self.by_key() + return reduce( + add, (_cycler(k, v * other) for k, v in trans.items()) + ) + else: + return NotImplemented + + @overload + def __rmul__(self, other: Cycler[L, U]) -> Cycler[K | L, V | U]: + ... + + @overload + def __rmul__(self, other: int) -> Cycler[K, V]: + ... + + def __rmul__(self, other): + return self * other + + def __len__(self) -> int: + op_dict: dict[Callable, Callable[[int, int], int]] = {zip: min, product: mul} + if self._right is None: + return len(self._left) + l_len = len(self._left) + r_len = len(self._right) + return op_dict[self._op](l_len, r_len) + + # iadd and imul do not exapand the the type as the returns must be consistent with + # self, thus they flag as inconsistent with add/mul + def __iadd__(self, other: Cycler[K, V]) -> Cycler[K, V]: # type: ignore[misc] + """ + In-place pair-wise combine two equal length cyclers (zip). + + Parameters + ---------- + other : Cycler + """ + if not isinstance(other, Cycler): + raise TypeError("Cannot += with a non-Cycler object") + # True shallow copy of self is fine since this is in-place + old_self = copy.copy(self) + self._keys = _process_keys(old_self, other) + self._left = old_self + self._op = zip + self._right = Cycler(other._left, other._right, other._op) + return self + + def __imul__(self, other: Cycler[K, V] | int) -> Cycler[K, V]: # type: ignore[misc] + """ + In-place outer product of two cyclers (`itertools.product`). + + Parameters + ---------- + other : Cycler + """ + if not isinstance(other, Cycler): + raise TypeError("Cannot *= with a non-Cycler object") + # True shallow copy of self is fine since this is in-place + old_self = copy.copy(self) + self._keys = _process_keys(old_self, other) + self._left = old_self + self._op = product + self._right = Cycler(other._left, other._right, other._op) + return self + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Cycler): + return False + if len(self) != len(other): + return False + if self.keys ^ other.keys: + return False + return all(a == b for a, b in zip(self, other)) + + __hash__ = None # type: ignore + + def __repr__(self) -> str: + op_map = {zip: "+", product: "*"} + if self._right is None: + lab = self.keys.pop() + itr = list(v[lab] for v in self) + return f"cycler({lab!r}, {itr!r})" + else: + op = op_map.get(self._op, "?") + msg = "({left!r} {op} {right!r})" + return msg.format(left=self._left, op=op, right=self._right) + + def _repr_html_(self) -> str: + # an table showing the value of each key through a full cycle + output = "" + sorted_keys = sorted(self.keys, key=repr) + for key in sorted_keys: + output += f"" + for d in iter(self): + output += "" + for k in sorted_keys: + output += f"" + output += "" + output += "
{key!r}
{d[k]!r}
" + return output + + def by_key(self) -> dict[K, list[V]]: + """ + Values by key. + + This returns the transposed values of the cycler. Iterating + over a `Cycler` yields dicts with a single value for each key, + this method returns a `dict` of `list` which are the values + for the given key. + + The returned value can be used to create an equivalent `Cycler` + using only `+`. + + Returns + ------- + transpose : dict + dict of lists of the values for each key. + """ + + # TODO : sort out if this is a bottle neck, if there is a better way + # and if we care. + + keys = self.keys + out: dict[K, list[V]] = {k: list() for k in keys} + + for d in self: + for k in keys: + out[k].append(d[k]) + return out + + # for back compatibility + _transpose = by_key + + def simplify(self) -> Cycler[K, V]: + """ + Simplify the cycler into a sum (but no products) of cyclers. + + Returns + ------- + simple : Cycler + """ + # TODO: sort out if it is worth the effort to make sure this is + # balanced. Currently it is is + # (((a + b) + c) + d) vs + # ((a + b) + (c + d)) + # I would believe that there is some performance implications + trans = self.by_key() + return reduce(add, (_cycler(k, v) for k, v in trans.items())) + + concat = concat + + +@overload +def cycler(arg: Cycler[K, V]) -> Cycler[K, V]: + ... + + +@overload +def cycler(**kwargs: Iterable[V]) -> Cycler[str, V]: + ... + + +@overload +def cycler(label: K, itr: Iterable[V]) -> Cycler[K, V]: + ... + + +def cycler(*args, **kwargs): + """ + Create a new `Cycler` object from a single positional argument, + a pair of positional arguments, or the combination of keyword arguments. + + cycler(arg) + cycler(label1=itr1[, label2=iter2[, ...]]) + cycler(label, itr) + + Form 1 simply copies a given `Cycler` object. + + Form 2 composes a `Cycler` as an inner product of the + pairs of keyword arguments. In other words, all of the + iterables are cycled simultaneously, as if through zip(). + + Form 3 creates a `Cycler` from a label and an iterable. + This is useful for when the label cannot be a keyword argument + (e.g., an integer or a name that has a space in it). + + Parameters + ---------- + arg : Cycler + Copy constructor for Cycler (does a shallow copy of iterables). + label : name + The property key. In the 2-arg form of the function, + the label can be any hashable object. In the keyword argument + form of the function, it must be a valid python identifier. + itr : iterable + Finite length iterable of the property values. + Can be a single-property `Cycler` that would + be like a key change, but as a shallow copy. + + Returns + ------- + cycler : Cycler + New `Cycler` for the given property + + """ + if args and kwargs: + raise TypeError( + "cycler() can only accept positional OR keyword arguments -- not both." + ) + + if len(args) == 1: + if not isinstance(args[0], Cycler): + raise TypeError( + "If only one positional argument given, it must " + "be a Cycler instance." + ) + return Cycler(args[0]) + elif len(args) == 2: + return _cycler(*args) + elif len(args) > 2: + raise TypeError( + "Only a single Cycler can be accepted as the lone " + "positional argument. Use keyword arguments instead." + ) + + if kwargs: + return reduce(add, (_cycler(k, v) for k, v in kwargs.items())) + + raise TypeError("Must have at least a positional OR keyword arguments") + + +def _cycler(label: K, itr: Iterable[V]) -> Cycler[K, V]: + """ + Create a new `Cycler` object from a property name and iterable of values. + + Parameters + ---------- + label : hashable + The property key. + itr : iterable + Finite length iterable of the property values. + + Returns + ------- + cycler : Cycler + New `Cycler` for the given property + """ + if isinstance(itr, Cycler): + keys = itr.keys + if len(keys) != 1: + msg = "Can not create Cycler from a multi-property Cycler" + raise ValueError(msg) + + lab = keys.pop() + # Doesn't need to be a new list because + # _from_iter() will be creating that new list anyway. + itr = (v[lab] for v in itr) + + return Cycler._from_iter(label, itr) diff --git a/dbdpy-env/lib/python3.9/site-packages/cycler/py.typed b/dbdpy-env/lib/python3.9/site-packages/cycler/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/__init__.py new file mode 100644 index 00000000..6c00e567 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/__init__.py @@ -0,0 +1,8 @@ +import logging +from fontTools.misc.loggingTools import configLogger + +log = logging.getLogger(__name__) + +version = __version__ = "4.47.0" + +__all__ = ["version", "log", "configLogger"] diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/__main__.py new file mode 100644 index 00000000..7c74ad3c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/__main__.py @@ -0,0 +1,35 @@ +import sys + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # TODO Handle library-wide options. Eg.: + # --unicodedata + # --verbose / other logging stuff + + # TODO Allow a way to run arbitrary modules? Useful for setting + # library-wide options and calling another library. Eg.: + # + # $ fonttools --unicodedata=... fontmake ... + # + # This allows for a git-like command where thirdparty commands + # can be added. Should we just try importing the fonttools + # module first and try without if it fails? + + if len(sys.argv) < 2: + sys.argv.append("help") + if sys.argv[1] == "-h" or sys.argv[1] == "--help": + sys.argv[1] = "help" + mod = "fontTools." + sys.argv[1] + sys.argv[1] = sys.argv[0] + " " + sys.argv[1] + del sys.argv[0] + + import runpy + + runpy.run_module(mod, run_name="__main__") + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/afmLib.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/afmLib.py new file mode 100644 index 00000000..e8964695 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/afmLib.py @@ -0,0 +1,440 @@ +"""Module for reading and writing AFM (Adobe Font Metrics) files. + +Note that this has been designed to read in AFM files generated by Fontographer +and has not been tested on many other files. In particular, it does not +implement the whole Adobe AFM specification [#f1]_ but, it should read most +"common" AFM files. + +Here is an example of using `afmLib` to read, modify and write an AFM file: + + >>> from fontTools.afmLib import AFM + >>> f = AFM("Tests/afmLib/data/TestAFM.afm") + >>> + >>> # Accessing a pair gets you the kern value + >>> f[("V","A")] + -60 + >>> + >>> # Accessing a glyph name gets you metrics + >>> f["A"] + (65, 668, (8, -25, 660, 666)) + >>> # (charnum, width, bounding box) + >>> + >>> # Accessing an attribute gets you metadata + >>> f.FontName + 'TestFont-Regular' + >>> f.FamilyName + 'TestFont' + >>> f.Weight + 'Regular' + >>> f.XHeight + 500 + >>> f.Ascender + 750 + >>> + >>> # Attributes and items can also be set + >>> f[("A","V")] = -150 # Tighten kerning + >>> f.FontName = "TestFont Squished" + >>> + >>> # And the font written out again (remove the # in front) + >>> #f.write("testfont-squished.afm") + +.. rubric:: Footnotes + +.. [#f1] `Adobe Technote 5004 `_, + Adobe Font Metrics File Format Specification. + +""" + + +import re + +# every single line starts with a "word" +identifierRE = re.compile(r"^([A-Za-z]+).*") + +# regular expression to parse char lines +charRE = re.compile( + r"(-?\d+)" # charnum + r"\s*;\s*WX\s+" # ; WX + r"(-?\d+)" # width + r"\s*;\s*N\s+" # ; N + r"([.A-Za-z0-9_]+)" # charname + r"\s*;\s*B\s+" # ; B + r"(-?\d+)" # left + r"\s+" + r"(-?\d+)" # bottom + r"\s+" + r"(-?\d+)" # right + r"\s+" + r"(-?\d+)" # top + r"\s*;\s*" # ; +) + +# regular expression to parse kerning lines +kernRE = re.compile( + r"([.A-Za-z0-9_]+)" # leftchar + r"\s+" + r"([.A-Za-z0-9_]+)" # rightchar + r"\s+" + r"(-?\d+)" # value + r"\s*" +) + +# regular expressions to parse composite info lines of the form: +# Aacute 2 ; PCC A 0 0 ; PCC acute 182 211 ; +compositeRE = re.compile( + r"([.A-Za-z0-9_]+)" # char name + r"\s+" + r"(\d+)" # number of parts + r"\s*;\s*" +) +componentRE = re.compile( + r"PCC\s+" # PPC + r"([.A-Za-z0-9_]+)" # base char name + r"\s+" + r"(-?\d+)" # x offset + r"\s+" + r"(-?\d+)" # y offset + r"\s*;\s*" +) + +preferredAttributeOrder = [ + "FontName", + "FullName", + "FamilyName", + "Weight", + "ItalicAngle", + "IsFixedPitch", + "FontBBox", + "UnderlinePosition", + "UnderlineThickness", + "Version", + "Notice", + "EncodingScheme", + "CapHeight", + "XHeight", + "Ascender", + "Descender", +] + + +class error(Exception): + pass + + +class AFM(object): + _attrs = None + + _keywords = [ + "StartFontMetrics", + "EndFontMetrics", + "StartCharMetrics", + "EndCharMetrics", + "StartKernData", + "StartKernPairs", + "EndKernPairs", + "EndKernData", + "StartComposites", + "EndComposites", + ] + + def __init__(self, path=None): + """AFM file reader. + + Instantiating an object with a path name will cause the file to be opened, + read, and parsed. Alternatively the path can be left unspecified, and a + file can be parsed later with the :meth:`read` method.""" + self._attrs = {} + self._chars = {} + self._kerning = {} + self._index = {} + self._comments = [] + self._composites = {} + if path is not None: + self.read(path) + + def read(self, path): + """Opens, reads and parses a file.""" + lines = readlines(path) + for line in lines: + if not line.strip(): + continue + m = identifierRE.match(line) + if m is None: + raise error("syntax error in AFM file: " + repr(line)) + + pos = m.regs[1][1] + word = line[:pos] + rest = line[pos:].strip() + if word in self._keywords: + continue + if word == "C": + self.parsechar(rest) + elif word == "KPX": + self.parsekernpair(rest) + elif word == "CC": + self.parsecomposite(rest) + else: + self.parseattr(word, rest) + + def parsechar(self, rest): + m = charRE.match(rest) + if m is None: + raise error("syntax error in AFM file: " + repr(rest)) + things = [] + for fr, to in m.regs[1:]: + things.append(rest[fr:to]) + charname = things[2] + del things[2] + charnum, width, l, b, r, t = (int(thing) for thing in things) + self._chars[charname] = charnum, width, (l, b, r, t) + + def parsekernpair(self, rest): + m = kernRE.match(rest) + if m is None: + raise error("syntax error in AFM file: " + repr(rest)) + things = [] + for fr, to in m.regs[1:]: + things.append(rest[fr:to]) + leftchar, rightchar, value = things + value = int(value) + self._kerning[(leftchar, rightchar)] = value + + def parseattr(self, word, rest): + if word == "FontBBox": + l, b, r, t = [int(thing) for thing in rest.split()] + self._attrs[word] = l, b, r, t + elif word == "Comment": + self._comments.append(rest) + else: + try: + value = int(rest) + except (ValueError, OverflowError): + self._attrs[word] = rest + else: + self._attrs[word] = value + + def parsecomposite(self, rest): + m = compositeRE.match(rest) + if m is None: + raise error("syntax error in AFM file: " + repr(rest)) + charname = m.group(1) + ncomponents = int(m.group(2)) + rest = rest[m.regs[0][1] :] + components = [] + while True: + m = componentRE.match(rest) + if m is None: + raise error("syntax error in AFM file: " + repr(rest)) + basechar = m.group(1) + xoffset = int(m.group(2)) + yoffset = int(m.group(3)) + components.append((basechar, xoffset, yoffset)) + rest = rest[m.regs[0][1] :] + if not rest: + break + assert len(components) == ncomponents + self._composites[charname] = components + + def write(self, path, sep="\r"): + """Writes out an AFM font to the given path.""" + import time + + lines = [ + "StartFontMetrics 2.0", + "Comment Generated by afmLib; at %s" + % (time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(time.time()))), + ] + + # write comments, assuming (possibly wrongly!) they should + # all appear at the top + for comment in self._comments: + lines.append("Comment " + comment) + + # write attributes, first the ones we know about, in + # a preferred order + attrs = self._attrs + for attr in preferredAttributeOrder: + if attr in attrs: + value = attrs[attr] + if attr == "FontBBox": + value = "%s %s %s %s" % value + lines.append(attr + " " + str(value)) + # then write the attributes we don't know about, + # in alphabetical order + items = sorted(attrs.items()) + for attr, value in items: + if attr in preferredAttributeOrder: + continue + lines.append(attr + " " + str(value)) + + # write char metrics + lines.append("StartCharMetrics " + repr(len(self._chars))) + items = [ + (charnum, (charname, width, box)) + for charname, (charnum, width, box) in self._chars.items() + ] + + def myKey(a): + """Custom key function to make sure unencoded chars (-1) + end up at the end of the list after sorting.""" + if a[0] == -1: + a = (0xFFFF,) + a[1:] # 0xffff is an arbitrary large number + return a + + items.sort(key=myKey) + + for charnum, (charname, width, (l, b, r, t)) in items: + lines.append( + "C %d ; WX %d ; N %s ; B %d %d %d %d ;" + % (charnum, width, charname, l, b, r, t) + ) + lines.append("EndCharMetrics") + + # write kerning info + lines.append("StartKernData") + lines.append("StartKernPairs " + repr(len(self._kerning))) + items = sorted(self._kerning.items()) + for (leftchar, rightchar), value in items: + lines.append("KPX %s %s %d" % (leftchar, rightchar, value)) + lines.append("EndKernPairs") + lines.append("EndKernData") + + if self._composites: + composites = sorted(self._composites.items()) + lines.append("StartComposites %s" % len(self._composites)) + for charname, components in composites: + line = "CC %s %s ;" % (charname, len(components)) + for basechar, xoffset, yoffset in components: + line = line + " PCC %s %s %s ;" % (basechar, xoffset, yoffset) + lines.append(line) + lines.append("EndComposites") + + lines.append("EndFontMetrics") + + writelines(path, lines, sep) + + def has_kernpair(self, pair): + """Returns `True` if the given glyph pair (specified as a tuple) exists + in the kerning dictionary.""" + return pair in self._kerning + + def kernpairs(self): + """Returns a list of all kern pairs in the kerning dictionary.""" + return list(self._kerning.keys()) + + def has_char(self, char): + """Returns `True` if the given glyph exists in the font.""" + return char in self._chars + + def chars(self): + """Returns a list of all glyph names in the font.""" + return list(self._chars.keys()) + + def comments(self): + """Returns all comments from the file.""" + return self._comments + + def addComment(self, comment): + """Adds a new comment to the file.""" + self._comments.append(comment) + + def addComposite(self, glyphName, components): + """Specifies that the glyph `glyphName` is made up of the given components. + The components list should be of the following form:: + + [ + (glyphname, xOffset, yOffset), + ... + ] + + """ + self._composites[glyphName] = components + + def __getattr__(self, attr): + if attr in self._attrs: + return self._attrs[attr] + else: + raise AttributeError(attr) + + def __setattr__(self, attr, value): + # all attrs *not* starting with "_" are consider to be AFM keywords + if attr[:1] == "_": + self.__dict__[attr] = value + else: + self._attrs[attr] = value + + def __delattr__(self, attr): + # all attrs *not* starting with "_" are consider to be AFM keywords + if attr[:1] == "_": + try: + del self.__dict__[attr] + except KeyError: + raise AttributeError(attr) + else: + try: + del self._attrs[attr] + except KeyError: + raise AttributeError(attr) + + def __getitem__(self, key): + if isinstance(key, tuple): + # key is a tuple, return the kernpair + return self._kerning[key] + else: + # return the metrics instead + return self._chars[key] + + def __setitem__(self, key, value): + if isinstance(key, tuple): + # key is a tuple, set kernpair + self._kerning[key] = value + else: + # set char metrics + self._chars[key] = value + + def __delitem__(self, key): + if isinstance(key, tuple): + # key is a tuple, del kernpair + del self._kerning[key] + else: + # del char metrics + del self._chars[key] + + def __repr__(self): + if hasattr(self, "FullName"): + return "" % self.FullName + else: + return "" % id(self) + + +def readlines(path): + with open(path, "r", encoding="ascii") as f: + data = f.read() + return data.splitlines() + + +def writelines(path, lines, sep="\r"): + with open(path, "w", encoding="ascii", newline=sep) as f: + f.write("\n".join(lines) + "\n") + + +if __name__ == "__main__": + import EasyDialogs + + path = EasyDialogs.AskFileForOpen() + if path: + afm = AFM(path) + char = "A" + if afm.has_char(char): + print(afm[char]) # print charnum, width and boundingbox + pair = ("A", "V") + if afm.has_kernpair(pair): + print(afm[pair]) # print kerning value for pair + print(afm.Version) # various other afm entries have become attributes + print(afm.Weight) + # afm.comments() returns a list of all Comment lines found in the AFM + print(afm.comments()) + # print afm.chars() + # print afm.kernpairs() + print(afm) + afm.write(path + ".muck") diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/agl.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/agl.py new file mode 100644 index 00000000..d6994628 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/agl.py @@ -0,0 +1,5233 @@ +# -*- coding: utf-8 -*- +# The tables below are taken from +# https://github.com/adobe-type-tools/agl-aglfn/raw/4036a9ca80a62f64f9de4f7321a9a045ad0ecfd6/glyphlist.txt +# and +# https://github.com/adobe-type-tools/agl-aglfn/raw/4036a9ca80a62f64f9de4f7321a9a045ad0ecfd6/aglfn.txt +""" +Interface to the Adobe Glyph List + +This module exists to convert glyph names from the Adobe Glyph List +to their Unicode equivalents. Example usage: + + >>> from fontTools.agl import toUnicode + >>> toUnicode("nahiragana") + 'な' + +It also contains two dictionaries, ``UV2AGL`` and ``AGL2UV``, which map from +Unicode codepoints to AGL names and vice versa: + + >>> import fontTools + >>> fontTools.agl.UV2AGL[ord("?")] + 'question' + >>> fontTools.agl.AGL2UV["wcircumflex"] + 373 + +This is used by fontTools when it has to construct glyph names for a font which +doesn't include any (e.g. format 3.0 post tables). +""" + +from fontTools.misc.textTools import tostr +import re + + +_aglText = """\ +# ----------------------------------------------------------- +# Copyright 2002-2019 Adobe (http://www.adobe.com/). +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the +# following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# Neither the name of Adobe nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------- +# Name: Adobe Glyph List +# Table version: 2.0 +# Date: September 20, 2002 +# URL: https://github.com/adobe-type-tools/agl-aglfn +# +# Format: two semicolon-delimited fields: +# (1) glyph name--upper/lowercase letters and digits +# (2) Unicode scalar value--four uppercase hexadecimal digits +# +A;0041 +AE;00C6 +AEacute;01FC +AEmacron;01E2 +AEsmall;F7E6 +Aacute;00C1 +Aacutesmall;F7E1 +Abreve;0102 +Abreveacute;1EAE +Abrevecyrillic;04D0 +Abrevedotbelow;1EB6 +Abrevegrave;1EB0 +Abrevehookabove;1EB2 +Abrevetilde;1EB4 +Acaron;01CD +Acircle;24B6 +Acircumflex;00C2 +Acircumflexacute;1EA4 +Acircumflexdotbelow;1EAC +Acircumflexgrave;1EA6 +Acircumflexhookabove;1EA8 +Acircumflexsmall;F7E2 +Acircumflextilde;1EAA +Acute;F6C9 +Acutesmall;F7B4 +Acyrillic;0410 +Adblgrave;0200 +Adieresis;00C4 +Adieresiscyrillic;04D2 +Adieresismacron;01DE +Adieresissmall;F7E4 +Adotbelow;1EA0 +Adotmacron;01E0 +Agrave;00C0 +Agravesmall;F7E0 +Ahookabove;1EA2 +Aiecyrillic;04D4 +Ainvertedbreve;0202 +Alpha;0391 +Alphatonos;0386 +Amacron;0100 +Amonospace;FF21 +Aogonek;0104 +Aring;00C5 +Aringacute;01FA +Aringbelow;1E00 +Aringsmall;F7E5 +Asmall;F761 +Atilde;00C3 +Atildesmall;F7E3 +Aybarmenian;0531 +B;0042 +Bcircle;24B7 +Bdotaccent;1E02 +Bdotbelow;1E04 +Becyrillic;0411 +Benarmenian;0532 +Beta;0392 +Bhook;0181 +Blinebelow;1E06 +Bmonospace;FF22 +Brevesmall;F6F4 +Bsmall;F762 +Btopbar;0182 +C;0043 +Caarmenian;053E +Cacute;0106 +Caron;F6CA +Caronsmall;F6F5 +Ccaron;010C +Ccedilla;00C7 +Ccedillaacute;1E08 +Ccedillasmall;F7E7 +Ccircle;24B8 +Ccircumflex;0108 +Cdot;010A +Cdotaccent;010A +Cedillasmall;F7B8 +Chaarmenian;0549 +Cheabkhasiancyrillic;04BC +Checyrillic;0427 +Chedescenderabkhasiancyrillic;04BE +Chedescendercyrillic;04B6 +Chedieresiscyrillic;04F4 +Cheharmenian;0543 +Chekhakassiancyrillic;04CB +Cheverticalstrokecyrillic;04B8 +Chi;03A7 +Chook;0187 +Circumflexsmall;F6F6 +Cmonospace;FF23 +Coarmenian;0551 +Csmall;F763 +D;0044 +DZ;01F1 +DZcaron;01C4 +Daarmenian;0534 +Dafrican;0189 +Dcaron;010E +Dcedilla;1E10 +Dcircle;24B9 +Dcircumflexbelow;1E12 +Dcroat;0110 +Ddotaccent;1E0A +Ddotbelow;1E0C +Decyrillic;0414 +Deicoptic;03EE +Delta;2206 +Deltagreek;0394 +Dhook;018A +Dieresis;F6CB +DieresisAcute;F6CC +DieresisGrave;F6CD +Dieresissmall;F7A8 +Digammagreek;03DC +Djecyrillic;0402 +Dlinebelow;1E0E +Dmonospace;FF24 +Dotaccentsmall;F6F7 +Dslash;0110 +Dsmall;F764 +Dtopbar;018B +Dz;01F2 +Dzcaron;01C5 +Dzeabkhasiancyrillic;04E0 +Dzecyrillic;0405 +Dzhecyrillic;040F +E;0045 +Eacute;00C9 +Eacutesmall;F7E9 +Ebreve;0114 +Ecaron;011A +Ecedillabreve;1E1C +Echarmenian;0535 +Ecircle;24BA +Ecircumflex;00CA +Ecircumflexacute;1EBE +Ecircumflexbelow;1E18 +Ecircumflexdotbelow;1EC6 +Ecircumflexgrave;1EC0 +Ecircumflexhookabove;1EC2 +Ecircumflexsmall;F7EA +Ecircumflextilde;1EC4 +Ecyrillic;0404 +Edblgrave;0204 +Edieresis;00CB +Edieresissmall;F7EB +Edot;0116 +Edotaccent;0116 +Edotbelow;1EB8 +Efcyrillic;0424 +Egrave;00C8 +Egravesmall;F7E8 +Eharmenian;0537 +Ehookabove;1EBA +Eightroman;2167 +Einvertedbreve;0206 +Eiotifiedcyrillic;0464 +Elcyrillic;041B +Elevenroman;216A +Emacron;0112 +Emacronacute;1E16 +Emacrongrave;1E14 +Emcyrillic;041C +Emonospace;FF25 +Encyrillic;041D +Endescendercyrillic;04A2 +Eng;014A +Enghecyrillic;04A4 +Enhookcyrillic;04C7 +Eogonek;0118 +Eopen;0190 +Epsilon;0395 +Epsilontonos;0388 +Ercyrillic;0420 +Ereversed;018E +Ereversedcyrillic;042D +Escyrillic;0421 +Esdescendercyrillic;04AA +Esh;01A9 +Esmall;F765 +Eta;0397 +Etarmenian;0538 +Etatonos;0389 +Eth;00D0 +Ethsmall;F7F0 +Etilde;1EBC +Etildebelow;1E1A +Euro;20AC +Ezh;01B7 +Ezhcaron;01EE +Ezhreversed;01B8 +F;0046 +Fcircle;24BB +Fdotaccent;1E1E +Feharmenian;0556 +Feicoptic;03E4 +Fhook;0191 +Fitacyrillic;0472 +Fiveroman;2164 +Fmonospace;FF26 +Fourroman;2163 +Fsmall;F766 +G;0047 +GBsquare;3387 +Gacute;01F4 +Gamma;0393 +Gammaafrican;0194 +Gangiacoptic;03EA +Gbreve;011E +Gcaron;01E6 +Gcedilla;0122 +Gcircle;24BC +Gcircumflex;011C +Gcommaaccent;0122 +Gdot;0120 +Gdotaccent;0120 +Gecyrillic;0413 +Ghadarmenian;0542 +Ghemiddlehookcyrillic;0494 +Ghestrokecyrillic;0492 +Gheupturncyrillic;0490 +Ghook;0193 +Gimarmenian;0533 +Gjecyrillic;0403 +Gmacron;1E20 +Gmonospace;FF27 +Grave;F6CE +Gravesmall;F760 +Gsmall;F767 +Gsmallhook;029B +Gstroke;01E4 +H;0048 +H18533;25CF +H18543;25AA +H18551;25AB +H22073;25A1 +HPsquare;33CB +Haabkhasiancyrillic;04A8 +Hadescendercyrillic;04B2 +Hardsigncyrillic;042A +Hbar;0126 +Hbrevebelow;1E2A +Hcedilla;1E28 +Hcircle;24BD +Hcircumflex;0124 +Hdieresis;1E26 +Hdotaccent;1E22 +Hdotbelow;1E24 +Hmonospace;FF28 +Hoarmenian;0540 +Horicoptic;03E8 +Hsmall;F768 +Hungarumlaut;F6CF +Hungarumlautsmall;F6F8 +Hzsquare;3390 +I;0049 +IAcyrillic;042F +IJ;0132 +IUcyrillic;042E +Iacute;00CD +Iacutesmall;F7ED +Ibreve;012C +Icaron;01CF +Icircle;24BE +Icircumflex;00CE +Icircumflexsmall;F7EE +Icyrillic;0406 +Idblgrave;0208 +Idieresis;00CF +Idieresisacute;1E2E +Idieresiscyrillic;04E4 +Idieresissmall;F7EF +Idot;0130 +Idotaccent;0130 +Idotbelow;1ECA +Iebrevecyrillic;04D6 +Iecyrillic;0415 +Ifraktur;2111 +Igrave;00CC +Igravesmall;F7EC +Ihookabove;1EC8 +Iicyrillic;0418 +Iinvertedbreve;020A +Iishortcyrillic;0419 +Imacron;012A +Imacroncyrillic;04E2 +Imonospace;FF29 +Iniarmenian;053B +Iocyrillic;0401 +Iogonek;012E +Iota;0399 +Iotaafrican;0196 +Iotadieresis;03AA +Iotatonos;038A +Ismall;F769 +Istroke;0197 +Itilde;0128 +Itildebelow;1E2C +Izhitsacyrillic;0474 +Izhitsadblgravecyrillic;0476 +J;004A +Jaarmenian;0541 +Jcircle;24BF +Jcircumflex;0134 +Jecyrillic;0408 +Jheharmenian;054B +Jmonospace;FF2A +Jsmall;F76A +K;004B +KBsquare;3385 +KKsquare;33CD +Kabashkircyrillic;04A0 +Kacute;1E30 +Kacyrillic;041A +Kadescendercyrillic;049A +Kahookcyrillic;04C3 +Kappa;039A +Kastrokecyrillic;049E +Kaverticalstrokecyrillic;049C +Kcaron;01E8 +Kcedilla;0136 +Kcircle;24C0 +Kcommaaccent;0136 +Kdotbelow;1E32 +Keharmenian;0554 +Kenarmenian;053F +Khacyrillic;0425 +Kheicoptic;03E6 +Khook;0198 +Kjecyrillic;040C +Klinebelow;1E34 +Kmonospace;FF2B +Koppacyrillic;0480 +Koppagreek;03DE +Ksicyrillic;046E +Ksmall;F76B +L;004C +LJ;01C7 +LL;F6BF +Lacute;0139 +Lambda;039B +Lcaron;013D +Lcedilla;013B +Lcircle;24C1 +Lcircumflexbelow;1E3C +Lcommaaccent;013B +Ldot;013F +Ldotaccent;013F +Ldotbelow;1E36 +Ldotbelowmacron;1E38 +Liwnarmenian;053C +Lj;01C8 +Ljecyrillic;0409 +Llinebelow;1E3A +Lmonospace;FF2C +Lslash;0141 +Lslashsmall;F6F9 +Lsmall;F76C +M;004D +MBsquare;3386 +Macron;F6D0 +Macronsmall;F7AF +Macute;1E3E +Mcircle;24C2 +Mdotaccent;1E40 +Mdotbelow;1E42 +Menarmenian;0544 +Mmonospace;FF2D +Msmall;F76D +Mturned;019C +Mu;039C +N;004E +NJ;01CA +Nacute;0143 +Ncaron;0147 +Ncedilla;0145 +Ncircle;24C3 +Ncircumflexbelow;1E4A +Ncommaaccent;0145 +Ndotaccent;1E44 +Ndotbelow;1E46 +Nhookleft;019D +Nineroman;2168 +Nj;01CB +Njecyrillic;040A +Nlinebelow;1E48 +Nmonospace;FF2E +Nowarmenian;0546 +Nsmall;F76E +Ntilde;00D1 +Ntildesmall;F7F1 +Nu;039D +O;004F +OE;0152 +OEsmall;F6FA +Oacute;00D3 +Oacutesmall;F7F3 +Obarredcyrillic;04E8 +Obarreddieresiscyrillic;04EA +Obreve;014E +Ocaron;01D1 +Ocenteredtilde;019F +Ocircle;24C4 +Ocircumflex;00D4 +Ocircumflexacute;1ED0 +Ocircumflexdotbelow;1ED8 +Ocircumflexgrave;1ED2 +Ocircumflexhookabove;1ED4 +Ocircumflexsmall;F7F4 +Ocircumflextilde;1ED6 +Ocyrillic;041E +Odblacute;0150 +Odblgrave;020C +Odieresis;00D6 +Odieresiscyrillic;04E6 +Odieresissmall;F7F6 +Odotbelow;1ECC +Ogoneksmall;F6FB +Ograve;00D2 +Ogravesmall;F7F2 +Oharmenian;0555 +Ohm;2126 +Ohookabove;1ECE +Ohorn;01A0 +Ohornacute;1EDA +Ohorndotbelow;1EE2 +Ohorngrave;1EDC +Ohornhookabove;1EDE +Ohorntilde;1EE0 +Ohungarumlaut;0150 +Oi;01A2 +Oinvertedbreve;020E +Omacron;014C +Omacronacute;1E52 +Omacrongrave;1E50 +Omega;2126 +Omegacyrillic;0460 +Omegagreek;03A9 +Omegaroundcyrillic;047A +Omegatitlocyrillic;047C +Omegatonos;038F +Omicron;039F +Omicrontonos;038C +Omonospace;FF2F +Oneroman;2160 +Oogonek;01EA +Oogonekmacron;01EC +Oopen;0186 +Oslash;00D8 +Oslashacute;01FE +Oslashsmall;F7F8 +Osmall;F76F +Ostrokeacute;01FE +Otcyrillic;047E +Otilde;00D5 +Otildeacute;1E4C +Otildedieresis;1E4E +Otildesmall;F7F5 +P;0050 +Pacute;1E54 +Pcircle;24C5 +Pdotaccent;1E56 +Pecyrillic;041F +Peharmenian;054A +Pemiddlehookcyrillic;04A6 +Phi;03A6 +Phook;01A4 +Pi;03A0 +Piwrarmenian;0553 +Pmonospace;FF30 +Psi;03A8 +Psicyrillic;0470 +Psmall;F770 +Q;0051 +Qcircle;24C6 +Qmonospace;FF31 +Qsmall;F771 +R;0052 +Raarmenian;054C +Racute;0154 +Rcaron;0158 +Rcedilla;0156 +Rcircle;24C7 +Rcommaaccent;0156 +Rdblgrave;0210 +Rdotaccent;1E58 +Rdotbelow;1E5A +Rdotbelowmacron;1E5C +Reharmenian;0550 +Rfraktur;211C +Rho;03A1 +Ringsmall;F6FC +Rinvertedbreve;0212 +Rlinebelow;1E5E +Rmonospace;FF32 +Rsmall;F772 +Rsmallinverted;0281 +Rsmallinvertedsuperior;02B6 +S;0053 +SF010000;250C +SF020000;2514 +SF030000;2510 +SF040000;2518 +SF050000;253C +SF060000;252C +SF070000;2534 +SF080000;251C +SF090000;2524 +SF100000;2500 +SF110000;2502 +SF190000;2561 +SF200000;2562 +SF210000;2556 +SF220000;2555 +SF230000;2563 +SF240000;2551 +SF250000;2557 +SF260000;255D +SF270000;255C +SF280000;255B +SF360000;255E +SF370000;255F +SF380000;255A +SF390000;2554 +SF400000;2569 +SF410000;2566 +SF420000;2560 +SF430000;2550 +SF440000;256C +SF450000;2567 +SF460000;2568 +SF470000;2564 +SF480000;2565 +SF490000;2559 +SF500000;2558 +SF510000;2552 +SF520000;2553 +SF530000;256B +SF540000;256A +Sacute;015A +Sacutedotaccent;1E64 +Sampigreek;03E0 +Scaron;0160 +Scarondotaccent;1E66 +Scaronsmall;F6FD +Scedilla;015E +Schwa;018F +Schwacyrillic;04D8 +Schwadieresiscyrillic;04DA +Scircle;24C8 +Scircumflex;015C +Scommaaccent;0218 +Sdotaccent;1E60 +Sdotbelow;1E62 +Sdotbelowdotaccent;1E68 +Seharmenian;054D +Sevenroman;2166 +Shaarmenian;0547 +Shacyrillic;0428 +Shchacyrillic;0429 +Sheicoptic;03E2 +Shhacyrillic;04BA +Shimacoptic;03EC +Sigma;03A3 +Sixroman;2165 +Smonospace;FF33 +Softsigncyrillic;042C +Ssmall;F773 +Stigmagreek;03DA +T;0054 +Tau;03A4 +Tbar;0166 +Tcaron;0164 +Tcedilla;0162 +Tcircle;24C9 +Tcircumflexbelow;1E70 +Tcommaaccent;0162 +Tdotaccent;1E6A +Tdotbelow;1E6C +Tecyrillic;0422 +Tedescendercyrillic;04AC +Tenroman;2169 +Tetsecyrillic;04B4 +Theta;0398 +Thook;01AC +Thorn;00DE +Thornsmall;F7FE +Threeroman;2162 +Tildesmall;F6FE +Tiwnarmenian;054F +Tlinebelow;1E6E +Tmonospace;FF34 +Toarmenian;0539 +Tonefive;01BC +Tonesix;0184 +Tonetwo;01A7 +Tretroflexhook;01AE +Tsecyrillic;0426 +Tshecyrillic;040B +Tsmall;F774 +Twelveroman;216B +Tworoman;2161 +U;0055 +Uacute;00DA +Uacutesmall;F7FA +Ubreve;016C +Ucaron;01D3 +Ucircle;24CA +Ucircumflex;00DB +Ucircumflexbelow;1E76 +Ucircumflexsmall;F7FB +Ucyrillic;0423 +Udblacute;0170 +Udblgrave;0214 +Udieresis;00DC +Udieresisacute;01D7 +Udieresisbelow;1E72 +Udieresiscaron;01D9 +Udieresiscyrillic;04F0 +Udieresisgrave;01DB +Udieresismacron;01D5 +Udieresissmall;F7FC +Udotbelow;1EE4 +Ugrave;00D9 +Ugravesmall;F7F9 +Uhookabove;1EE6 +Uhorn;01AF +Uhornacute;1EE8 +Uhorndotbelow;1EF0 +Uhorngrave;1EEA +Uhornhookabove;1EEC +Uhorntilde;1EEE +Uhungarumlaut;0170 +Uhungarumlautcyrillic;04F2 +Uinvertedbreve;0216 +Ukcyrillic;0478 +Umacron;016A +Umacroncyrillic;04EE +Umacrondieresis;1E7A +Umonospace;FF35 +Uogonek;0172 +Upsilon;03A5 +Upsilon1;03D2 +Upsilonacutehooksymbolgreek;03D3 +Upsilonafrican;01B1 +Upsilondieresis;03AB +Upsilondieresishooksymbolgreek;03D4 +Upsilonhooksymbol;03D2 +Upsilontonos;038E +Uring;016E +Ushortcyrillic;040E +Usmall;F775 +Ustraightcyrillic;04AE +Ustraightstrokecyrillic;04B0 +Utilde;0168 +Utildeacute;1E78 +Utildebelow;1E74 +V;0056 +Vcircle;24CB +Vdotbelow;1E7E +Vecyrillic;0412 +Vewarmenian;054E +Vhook;01B2 +Vmonospace;FF36 +Voarmenian;0548 +Vsmall;F776 +Vtilde;1E7C +W;0057 +Wacute;1E82 +Wcircle;24CC +Wcircumflex;0174 +Wdieresis;1E84 +Wdotaccent;1E86 +Wdotbelow;1E88 +Wgrave;1E80 +Wmonospace;FF37 +Wsmall;F777 +X;0058 +Xcircle;24CD +Xdieresis;1E8C +Xdotaccent;1E8A +Xeharmenian;053D +Xi;039E +Xmonospace;FF38 +Xsmall;F778 +Y;0059 +Yacute;00DD +Yacutesmall;F7FD +Yatcyrillic;0462 +Ycircle;24CE +Ycircumflex;0176 +Ydieresis;0178 +Ydieresissmall;F7FF +Ydotaccent;1E8E +Ydotbelow;1EF4 +Yericyrillic;042B +Yerudieresiscyrillic;04F8 +Ygrave;1EF2 +Yhook;01B3 +Yhookabove;1EF6 +Yiarmenian;0545 +Yicyrillic;0407 +Yiwnarmenian;0552 +Ymonospace;FF39 +Ysmall;F779 +Ytilde;1EF8 +Yusbigcyrillic;046A +Yusbigiotifiedcyrillic;046C +Yuslittlecyrillic;0466 +Yuslittleiotifiedcyrillic;0468 +Z;005A +Zaarmenian;0536 +Zacute;0179 +Zcaron;017D +Zcaronsmall;F6FF +Zcircle;24CF +Zcircumflex;1E90 +Zdot;017B +Zdotaccent;017B +Zdotbelow;1E92 +Zecyrillic;0417 +Zedescendercyrillic;0498 +Zedieresiscyrillic;04DE +Zeta;0396 +Zhearmenian;053A +Zhebrevecyrillic;04C1 +Zhecyrillic;0416 +Zhedescendercyrillic;0496 +Zhedieresiscyrillic;04DC +Zlinebelow;1E94 +Zmonospace;FF3A +Zsmall;F77A +Zstroke;01B5 +a;0061 +aabengali;0986 +aacute;00E1 +aadeva;0906 +aagujarati;0A86 +aagurmukhi;0A06 +aamatragurmukhi;0A3E +aarusquare;3303 +aavowelsignbengali;09BE +aavowelsigndeva;093E +aavowelsigngujarati;0ABE +abbreviationmarkarmenian;055F +abbreviationsigndeva;0970 +abengali;0985 +abopomofo;311A +abreve;0103 +abreveacute;1EAF +abrevecyrillic;04D1 +abrevedotbelow;1EB7 +abrevegrave;1EB1 +abrevehookabove;1EB3 +abrevetilde;1EB5 +acaron;01CE +acircle;24D0 +acircumflex;00E2 +acircumflexacute;1EA5 +acircumflexdotbelow;1EAD +acircumflexgrave;1EA7 +acircumflexhookabove;1EA9 +acircumflextilde;1EAB +acute;00B4 +acutebelowcmb;0317 +acutecmb;0301 +acutecomb;0301 +acutedeva;0954 +acutelowmod;02CF +acutetonecmb;0341 +acyrillic;0430 +adblgrave;0201 +addakgurmukhi;0A71 +adeva;0905 +adieresis;00E4 +adieresiscyrillic;04D3 +adieresismacron;01DF +adotbelow;1EA1 +adotmacron;01E1 +ae;00E6 +aeacute;01FD +aekorean;3150 +aemacron;01E3 +afii00208;2015 +afii08941;20A4 +afii10017;0410 +afii10018;0411 +afii10019;0412 +afii10020;0413 +afii10021;0414 +afii10022;0415 +afii10023;0401 +afii10024;0416 +afii10025;0417 +afii10026;0418 +afii10027;0419 +afii10028;041A +afii10029;041B +afii10030;041C +afii10031;041D +afii10032;041E +afii10033;041F +afii10034;0420 +afii10035;0421 +afii10036;0422 +afii10037;0423 +afii10038;0424 +afii10039;0425 +afii10040;0426 +afii10041;0427 +afii10042;0428 +afii10043;0429 +afii10044;042A +afii10045;042B +afii10046;042C +afii10047;042D +afii10048;042E +afii10049;042F +afii10050;0490 +afii10051;0402 +afii10052;0403 +afii10053;0404 +afii10054;0405 +afii10055;0406 +afii10056;0407 +afii10057;0408 +afii10058;0409 +afii10059;040A +afii10060;040B +afii10061;040C +afii10062;040E +afii10063;F6C4 +afii10064;F6C5 +afii10065;0430 +afii10066;0431 +afii10067;0432 +afii10068;0433 +afii10069;0434 +afii10070;0435 +afii10071;0451 +afii10072;0436 +afii10073;0437 +afii10074;0438 +afii10075;0439 +afii10076;043A +afii10077;043B +afii10078;043C +afii10079;043D +afii10080;043E +afii10081;043F +afii10082;0440 +afii10083;0441 +afii10084;0442 +afii10085;0443 +afii10086;0444 +afii10087;0445 +afii10088;0446 +afii10089;0447 +afii10090;0448 +afii10091;0449 +afii10092;044A +afii10093;044B +afii10094;044C +afii10095;044D +afii10096;044E +afii10097;044F +afii10098;0491 +afii10099;0452 +afii10100;0453 +afii10101;0454 +afii10102;0455 +afii10103;0456 +afii10104;0457 +afii10105;0458 +afii10106;0459 +afii10107;045A +afii10108;045B +afii10109;045C +afii10110;045E +afii10145;040F +afii10146;0462 +afii10147;0472 +afii10148;0474 +afii10192;F6C6 +afii10193;045F +afii10194;0463 +afii10195;0473 +afii10196;0475 +afii10831;F6C7 +afii10832;F6C8 +afii10846;04D9 +afii299;200E +afii300;200F +afii301;200D +afii57381;066A +afii57388;060C +afii57392;0660 +afii57393;0661 +afii57394;0662 +afii57395;0663 +afii57396;0664 +afii57397;0665 +afii57398;0666 +afii57399;0667 +afii57400;0668 +afii57401;0669 +afii57403;061B +afii57407;061F +afii57409;0621 +afii57410;0622 +afii57411;0623 +afii57412;0624 +afii57413;0625 +afii57414;0626 +afii57415;0627 +afii57416;0628 +afii57417;0629 +afii57418;062A +afii57419;062B +afii57420;062C +afii57421;062D +afii57422;062E +afii57423;062F +afii57424;0630 +afii57425;0631 +afii57426;0632 +afii57427;0633 +afii57428;0634 +afii57429;0635 +afii57430;0636 +afii57431;0637 +afii57432;0638 +afii57433;0639 +afii57434;063A +afii57440;0640 +afii57441;0641 +afii57442;0642 +afii57443;0643 +afii57444;0644 +afii57445;0645 +afii57446;0646 +afii57448;0648 +afii57449;0649 +afii57450;064A +afii57451;064B +afii57452;064C +afii57453;064D +afii57454;064E +afii57455;064F +afii57456;0650 +afii57457;0651 +afii57458;0652 +afii57470;0647 +afii57505;06A4 +afii57506;067E +afii57507;0686 +afii57508;0698 +afii57509;06AF +afii57511;0679 +afii57512;0688 +afii57513;0691 +afii57514;06BA +afii57519;06D2 +afii57534;06D5 +afii57636;20AA +afii57645;05BE +afii57658;05C3 +afii57664;05D0 +afii57665;05D1 +afii57666;05D2 +afii57667;05D3 +afii57668;05D4 +afii57669;05D5 +afii57670;05D6 +afii57671;05D7 +afii57672;05D8 +afii57673;05D9 +afii57674;05DA +afii57675;05DB +afii57676;05DC +afii57677;05DD +afii57678;05DE +afii57679;05DF +afii57680;05E0 +afii57681;05E1 +afii57682;05E2 +afii57683;05E3 +afii57684;05E4 +afii57685;05E5 +afii57686;05E6 +afii57687;05E7 +afii57688;05E8 +afii57689;05E9 +afii57690;05EA +afii57694;FB2A +afii57695;FB2B +afii57700;FB4B +afii57705;FB1F +afii57716;05F0 +afii57717;05F1 +afii57718;05F2 +afii57723;FB35 +afii57793;05B4 +afii57794;05B5 +afii57795;05B6 +afii57796;05BB +afii57797;05B8 +afii57798;05B7 +afii57799;05B0 +afii57800;05B2 +afii57801;05B1 +afii57802;05B3 +afii57803;05C2 +afii57804;05C1 +afii57806;05B9 +afii57807;05BC +afii57839;05BD +afii57841;05BF +afii57842;05C0 +afii57929;02BC +afii61248;2105 +afii61289;2113 +afii61352;2116 +afii61573;202C +afii61574;202D +afii61575;202E +afii61664;200C +afii63167;066D +afii64937;02BD +agrave;00E0 +agujarati;0A85 +agurmukhi;0A05 +ahiragana;3042 +ahookabove;1EA3 +aibengali;0990 +aibopomofo;311E +aideva;0910 +aiecyrillic;04D5 +aigujarati;0A90 +aigurmukhi;0A10 +aimatragurmukhi;0A48 +ainarabic;0639 +ainfinalarabic;FECA +aininitialarabic;FECB +ainmedialarabic;FECC +ainvertedbreve;0203 +aivowelsignbengali;09C8 +aivowelsigndeva;0948 +aivowelsigngujarati;0AC8 +akatakana;30A2 +akatakanahalfwidth;FF71 +akorean;314F +alef;05D0 +alefarabic;0627 +alefdageshhebrew;FB30 +aleffinalarabic;FE8E +alefhamzaabovearabic;0623 +alefhamzaabovefinalarabic;FE84 +alefhamzabelowarabic;0625 +alefhamzabelowfinalarabic;FE88 +alefhebrew;05D0 +aleflamedhebrew;FB4F +alefmaddaabovearabic;0622 +alefmaddaabovefinalarabic;FE82 +alefmaksuraarabic;0649 +alefmaksurafinalarabic;FEF0 +alefmaksurainitialarabic;FEF3 +alefmaksuramedialarabic;FEF4 +alefpatahhebrew;FB2E +alefqamatshebrew;FB2F +aleph;2135 +allequal;224C +alpha;03B1 +alphatonos;03AC +amacron;0101 +amonospace;FF41 +ampersand;0026 +ampersandmonospace;FF06 +ampersandsmall;F726 +amsquare;33C2 +anbopomofo;3122 +angbopomofo;3124 +angkhankhuthai;0E5A +angle;2220 +anglebracketleft;3008 +anglebracketleftvertical;FE3F +anglebracketright;3009 +anglebracketrightvertical;FE40 +angleleft;2329 +angleright;232A +angstrom;212B +anoteleia;0387 +anudattadeva;0952 +anusvarabengali;0982 +anusvaradeva;0902 +anusvaragujarati;0A82 +aogonek;0105 +apaatosquare;3300 +aparen;249C +apostrophearmenian;055A +apostrophemod;02BC +apple;F8FF +approaches;2250 +approxequal;2248 +approxequalorimage;2252 +approximatelyequal;2245 +araeaekorean;318E +araeakorean;318D +arc;2312 +arighthalfring;1E9A +aring;00E5 +aringacute;01FB +aringbelow;1E01 +arrowboth;2194 +arrowdashdown;21E3 +arrowdashleft;21E0 +arrowdashright;21E2 +arrowdashup;21E1 +arrowdblboth;21D4 +arrowdbldown;21D3 +arrowdblleft;21D0 +arrowdblright;21D2 +arrowdblup;21D1 +arrowdown;2193 +arrowdownleft;2199 +arrowdownright;2198 +arrowdownwhite;21E9 +arrowheaddownmod;02C5 +arrowheadleftmod;02C2 +arrowheadrightmod;02C3 +arrowheadupmod;02C4 +arrowhorizex;F8E7 +arrowleft;2190 +arrowleftdbl;21D0 +arrowleftdblstroke;21CD +arrowleftoverright;21C6 +arrowleftwhite;21E6 +arrowright;2192 +arrowrightdblstroke;21CF +arrowrightheavy;279E +arrowrightoverleft;21C4 +arrowrightwhite;21E8 +arrowtableft;21E4 +arrowtabright;21E5 +arrowup;2191 +arrowupdn;2195 +arrowupdnbse;21A8 +arrowupdownbase;21A8 +arrowupleft;2196 +arrowupleftofdown;21C5 +arrowupright;2197 +arrowupwhite;21E7 +arrowvertex;F8E6 +asciicircum;005E +asciicircummonospace;FF3E +asciitilde;007E +asciitildemonospace;FF5E +ascript;0251 +ascriptturned;0252 +asmallhiragana;3041 +asmallkatakana;30A1 +asmallkatakanahalfwidth;FF67 +asterisk;002A +asteriskaltonearabic;066D +asteriskarabic;066D +asteriskmath;2217 +asteriskmonospace;FF0A +asterisksmall;FE61 +asterism;2042 +asuperior;F6E9 +asymptoticallyequal;2243 +at;0040 +atilde;00E3 +atmonospace;FF20 +atsmall;FE6B +aturned;0250 +aubengali;0994 +aubopomofo;3120 +audeva;0914 +augujarati;0A94 +augurmukhi;0A14 +aulengthmarkbengali;09D7 +aumatragurmukhi;0A4C +auvowelsignbengali;09CC +auvowelsigndeva;094C +auvowelsigngujarati;0ACC +avagrahadeva;093D +aybarmenian;0561 +ayin;05E2 +ayinaltonehebrew;FB20 +ayinhebrew;05E2 +b;0062 +babengali;09AC +backslash;005C +backslashmonospace;FF3C +badeva;092C +bagujarati;0AAC +bagurmukhi;0A2C +bahiragana;3070 +bahtthai;0E3F +bakatakana;30D0 +bar;007C +barmonospace;FF5C +bbopomofo;3105 +bcircle;24D1 +bdotaccent;1E03 +bdotbelow;1E05 +beamedsixteenthnotes;266C +because;2235 +becyrillic;0431 +beharabic;0628 +behfinalarabic;FE90 +behinitialarabic;FE91 +behiragana;3079 +behmedialarabic;FE92 +behmeeminitialarabic;FC9F +behmeemisolatedarabic;FC08 +behnoonfinalarabic;FC6D +bekatakana;30D9 +benarmenian;0562 +bet;05D1 +beta;03B2 +betasymbolgreek;03D0 +betdagesh;FB31 +betdageshhebrew;FB31 +bethebrew;05D1 +betrafehebrew;FB4C +bhabengali;09AD +bhadeva;092D +bhagujarati;0AAD +bhagurmukhi;0A2D +bhook;0253 +bihiragana;3073 +bikatakana;30D3 +bilabialclick;0298 +bindigurmukhi;0A02 +birusquare;3331 +blackcircle;25CF +blackdiamond;25C6 +blackdownpointingtriangle;25BC +blackleftpointingpointer;25C4 +blackleftpointingtriangle;25C0 +blacklenticularbracketleft;3010 +blacklenticularbracketleftvertical;FE3B +blacklenticularbracketright;3011 +blacklenticularbracketrightvertical;FE3C +blacklowerlefttriangle;25E3 +blacklowerrighttriangle;25E2 +blackrectangle;25AC +blackrightpointingpointer;25BA +blackrightpointingtriangle;25B6 +blacksmallsquare;25AA +blacksmilingface;263B +blacksquare;25A0 +blackstar;2605 +blackupperlefttriangle;25E4 +blackupperrighttriangle;25E5 +blackuppointingsmalltriangle;25B4 +blackuppointingtriangle;25B2 +blank;2423 +blinebelow;1E07 +block;2588 +bmonospace;FF42 +bobaimaithai;0E1A +bohiragana;307C +bokatakana;30DC +bparen;249D +bqsquare;33C3 +braceex;F8F4 +braceleft;007B +braceleftbt;F8F3 +braceleftmid;F8F2 +braceleftmonospace;FF5B +braceleftsmall;FE5B +bracelefttp;F8F1 +braceleftvertical;FE37 +braceright;007D +bracerightbt;F8FE +bracerightmid;F8FD +bracerightmonospace;FF5D +bracerightsmall;FE5C +bracerighttp;F8FC +bracerightvertical;FE38 +bracketleft;005B +bracketleftbt;F8F0 +bracketleftex;F8EF +bracketleftmonospace;FF3B +bracketlefttp;F8EE +bracketright;005D +bracketrightbt;F8FB +bracketrightex;F8FA +bracketrightmonospace;FF3D +bracketrighttp;F8F9 +breve;02D8 +brevebelowcmb;032E +brevecmb;0306 +breveinvertedbelowcmb;032F +breveinvertedcmb;0311 +breveinverteddoublecmb;0361 +bridgebelowcmb;032A +bridgeinvertedbelowcmb;033A +brokenbar;00A6 +bstroke;0180 +bsuperior;F6EA +btopbar;0183 +buhiragana;3076 +bukatakana;30D6 +bullet;2022 +bulletinverse;25D8 +bulletoperator;2219 +bullseye;25CE +c;0063 +caarmenian;056E +cabengali;099A +cacute;0107 +cadeva;091A +cagujarati;0A9A +cagurmukhi;0A1A +calsquare;3388 +candrabindubengali;0981 +candrabinducmb;0310 +candrabindudeva;0901 +candrabindugujarati;0A81 +capslock;21EA +careof;2105 +caron;02C7 +caronbelowcmb;032C +caroncmb;030C +carriagereturn;21B5 +cbopomofo;3118 +ccaron;010D +ccedilla;00E7 +ccedillaacute;1E09 +ccircle;24D2 +ccircumflex;0109 +ccurl;0255 +cdot;010B +cdotaccent;010B +cdsquare;33C5 +cedilla;00B8 +cedillacmb;0327 +cent;00A2 +centigrade;2103 +centinferior;F6DF +centmonospace;FFE0 +centoldstyle;F7A2 +centsuperior;F6E0 +chaarmenian;0579 +chabengali;099B +chadeva;091B +chagujarati;0A9B +chagurmukhi;0A1B +chbopomofo;3114 +cheabkhasiancyrillic;04BD +checkmark;2713 +checyrillic;0447 +chedescenderabkhasiancyrillic;04BF +chedescendercyrillic;04B7 +chedieresiscyrillic;04F5 +cheharmenian;0573 +chekhakassiancyrillic;04CC +cheverticalstrokecyrillic;04B9 +chi;03C7 +chieuchacirclekorean;3277 +chieuchaparenkorean;3217 +chieuchcirclekorean;3269 +chieuchkorean;314A +chieuchparenkorean;3209 +chochangthai;0E0A +chochanthai;0E08 +chochingthai;0E09 +chochoethai;0E0C +chook;0188 +cieucacirclekorean;3276 +cieucaparenkorean;3216 +cieuccirclekorean;3268 +cieuckorean;3148 +cieucparenkorean;3208 +cieucuparenkorean;321C +circle;25CB +circlemultiply;2297 +circleot;2299 +circleplus;2295 +circlepostalmark;3036 +circlewithlefthalfblack;25D0 +circlewithrighthalfblack;25D1 +circumflex;02C6 +circumflexbelowcmb;032D +circumflexcmb;0302 +clear;2327 +clickalveolar;01C2 +clickdental;01C0 +clicklateral;01C1 +clickretroflex;01C3 +club;2663 +clubsuitblack;2663 +clubsuitwhite;2667 +cmcubedsquare;33A4 +cmonospace;FF43 +cmsquaredsquare;33A0 +coarmenian;0581 +colon;003A +colonmonetary;20A1 +colonmonospace;FF1A +colonsign;20A1 +colonsmall;FE55 +colontriangularhalfmod;02D1 +colontriangularmod;02D0 +comma;002C +commaabovecmb;0313 +commaaboverightcmb;0315 +commaaccent;F6C3 +commaarabic;060C +commaarmenian;055D +commainferior;F6E1 +commamonospace;FF0C +commareversedabovecmb;0314 +commareversedmod;02BD +commasmall;FE50 +commasuperior;F6E2 +commaturnedabovecmb;0312 +commaturnedmod;02BB +compass;263C +congruent;2245 +contourintegral;222E +control;2303 +controlACK;0006 +controlBEL;0007 +controlBS;0008 +controlCAN;0018 +controlCR;000D +controlDC1;0011 +controlDC2;0012 +controlDC3;0013 +controlDC4;0014 +controlDEL;007F +controlDLE;0010 +controlEM;0019 +controlENQ;0005 +controlEOT;0004 +controlESC;001B +controlETB;0017 +controlETX;0003 +controlFF;000C +controlFS;001C +controlGS;001D +controlHT;0009 +controlLF;000A +controlNAK;0015 +controlRS;001E +controlSI;000F +controlSO;000E +controlSOT;0002 +controlSTX;0001 +controlSUB;001A +controlSYN;0016 +controlUS;001F +controlVT;000B +copyright;00A9 +copyrightsans;F8E9 +copyrightserif;F6D9 +cornerbracketleft;300C +cornerbracketlefthalfwidth;FF62 +cornerbracketleftvertical;FE41 +cornerbracketright;300D +cornerbracketrighthalfwidth;FF63 +cornerbracketrightvertical;FE42 +corporationsquare;337F +cosquare;33C7 +coverkgsquare;33C6 +cparen;249E +cruzeiro;20A2 +cstretched;0297 +curlyand;22CF +curlyor;22CE +currency;00A4 +cyrBreve;F6D1 +cyrFlex;F6D2 +cyrbreve;F6D4 +cyrflex;F6D5 +d;0064 +daarmenian;0564 +dabengali;09A6 +dadarabic;0636 +dadeva;0926 +dadfinalarabic;FEBE +dadinitialarabic;FEBF +dadmedialarabic;FEC0 +dagesh;05BC +dageshhebrew;05BC +dagger;2020 +daggerdbl;2021 +dagujarati;0AA6 +dagurmukhi;0A26 +dahiragana;3060 +dakatakana;30C0 +dalarabic;062F +dalet;05D3 +daletdagesh;FB33 +daletdageshhebrew;FB33 +dalethatafpatah;05D3 05B2 +dalethatafpatahhebrew;05D3 05B2 +dalethatafsegol;05D3 05B1 +dalethatafsegolhebrew;05D3 05B1 +dalethebrew;05D3 +dalethiriq;05D3 05B4 +dalethiriqhebrew;05D3 05B4 +daletholam;05D3 05B9 +daletholamhebrew;05D3 05B9 +daletpatah;05D3 05B7 +daletpatahhebrew;05D3 05B7 +daletqamats;05D3 05B8 +daletqamatshebrew;05D3 05B8 +daletqubuts;05D3 05BB +daletqubutshebrew;05D3 05BB +daletsegol;05D3 05B6 +daletsegolhebrew;05D3 05B6 +daletsheva;05D3 05B0 +daletshevahebrew;05D3 05B0 +dalettsere;05D3 05B5 +dalettserehebrew;05D3 05B5 +dalfinalarabic;FEAA +dammaarabic;064F +dammalowarabic;064F +dammatanaltonearabic;064C +dammatanarabic;064C +danda;0964 +dargahebrew;05A7 +dargalefthebrew;05A7 +dasiapneumatacyrilliccmb;0485 +dblGrave;F6D3 +dblanglebracketleft;300A +dblanglebracketleftvertical;FE3D +dblanglebracketright;300B +dblanglebracketrightvertical;FE3E +dblarchinvertedbelowcmb;032B +dblarrowleft;21D4 +dblarrowright;21D2 +dbldanda;0965 +dblgrave;F6D6 +dblgravecmb;030F +dblintegral;222C +dbllowline;2017 +dbllowlinecmb;0333 +dbloverlinecmb;033F +dblprimemod;02BA +dblverticalbar;2016 +dblverticallineabovecmb;030E +dbopomofo;3109 +dbsquare;33C8 +dcaron;010F +dcedilla;1E11 +dcircle;24D3 +dcircumflexbelow;1E13 +dcroat;0111 +ddabengali;09A1 +ddadeva;0921 +ddagujarati;0AA1 +ddagurmukhi;0A21 +ddalarabic;0688 +ddalfinalarabic;FB89 +dddhadeva;095C +ddhabengali;09A2 +ddhadeva;0922 +ddhagujarati;0AA2 +ddhagurmukhi;0A22 +ddotaccent;1E0B +ddotbelow;1E0D +decimalseparatorarabic;066B +decimalseparatorpersian;066B +decyrillic;0434 +degree;00B0 +dehihebrew;05AD +dehiragana;3067 +deicoptic;03EF +dekatakana;30C7 +deleteleft;232B +deleteright;2326 +delta;03B4 +deltaturned;018D +denominatorminusonenumeratorbengali;09F8 +dezh;02A4 +dhabengali;09A7 +dhadeva;0927 +dhagujarati;0AA7 +dhagurmukhi;0A27 +dhook;0257 +dialytikatonos;0385 +dialytikatonoscmb;0344 +diamond;2666 +diamondsuitwhite;2662 +dieresis;00A8 +dieresisacute;F6D7 +dieresisbelowcmb;0324 +dieresiscmb;0308 +dieresisgrave;F6D8 +dieresistonos;0385 +dihiragana;3062 +dikatakana;30C2 +dittomark;3003 +divide;00F7 +divides;2223 +divisionslash;2215 +djecyrillic;0452 +dkshade;2593 +dlinebelow;1E0F +dlsquare;3397 +dmacron;0111 +dmonospace;FF44 +dnblock;2584 +dochadathai;0E0E +dodekthai;0E14 +dohiragana;3069 +dokatakana;30C9 +dollar;0024 +dollarinferior;F6E3 +dollarmonospace;FF04 +dollaroldstyle;F724 +dollarsmall;FE69 +dollarsuperior;F6E4 +dong;20AB +dorusquare;3326 +dotaccent;02D9 +dotaccentcmb;0307 +dotbelowcmb;0323 +dotbelowcomb;0323 +dotkatakana;30FB +dotlessi;0131 +dotlessj;F6BE +dotlessjstrokehook;0284 +dotmath;22C5 +dottedcircle;25CC +doubleyodpatah;FB1F +doubleyodpatahhebrew;FB1F +downtackbelowcmb;031E +downtackmod;02D5 +dparen;249F +dsuperior;F6EB +dtail;0256 +dtopbar;018C +duhiragana;3065 +dukatakana;30C5 +dz;01F3 +dzaltone;02A3 +dzcaron;01C6 +dzcurl;02A5 +dzeabkhasiancyrillic;04E1 +dzecyrillic;0455 +dzhecyrillic;045F +e;0065 +eacute;00E9 +earth;2641 +ebengali;098F +ebopomofo;311C +ebreve;0115 +ecandradeva;090D +ecandragujarati;0A8D +ecandravowelsigndeva;0945 +ecandravowelsigngujarati;0AC5 +ecaron;011B +ecedillabreve;1E1D +echarmenian;0565 +echyiwnarmenian;0587 +ecircle;24D4 +ecircumflex;00EA +ecircumflexacute;1EBF +ecircumflexbelow;1E19 +ecircumflexdotbelow;1EC7 +ecircumflexgrave;1EC1 +ecircumflexhookabove;1EC3 +ecircumflextilde;1EC5 +ecyrillic;0454 +edblgrave;0205 +edeva;090F +edieresis;00EB +edot;0117 +edotaccent;0117 +edotbelow;1EB9 +eegurmukhi;0A0F +eematragurmukhi;0A47 +efcyrillic;0444 +egrave;00E8 +egujarati;0A8F +eharmenian;0567 +ehbopomofo;311D +ehiragana;3048 +ehookabove;1EBB +eibopomofo;311F +eight;0038 +eightarabic;0668 +eightbengali;09EE +eightcircle;2467 +eightcircleinversesansserif;2791 +eightdeva;096E +eighteencircle;2471 +eighteenparen;2485 +eighteenperiod;2499 +eightgujarati;0AEE +eightgurmukhi;0A6E +eighthackarabic;0668 +eighthangzhou;3028 +eighthnotebeamed;266B +eightideographicparen;3227 +eightinferior;2088 +eightmonospace;FF18 +eightoldstyle;F738 +eightparen;247B +eightperiod;248F +eightpersian;06F8 +eightroman;2177 +eightsuperior;2078 +eightthai;0E58 +einvertedbreve;0207 +eiotifiedcyrillic;0465 +ekatakana;30A8 +ekatakanahalfwidth;FF74 +ekonkargurmukhi;0A74 +ekorean;3154 +elcyrillic;043B +element;2208 +elevencircle;246A +elevenparen;247E +elevenperiod;2492 +elevenroman;217A +ellipsis;2026 +ellipsisvertical;22EE +emacron;0113 +emacronacute;1E17 +emacrongrave;1E15 +emcyrillic;043C +emdash;2014 +emdashvertical;FE31 +emonospace;FF45 +emphasismarkarmenian;055B +emptyset;2205 +enbopomofo;3123 +encyrillic;043D +endash;2013 +endashvertical;FE32 +endescendercyrillic;04A3 +eng;014B +engbopomofo;3125 +enghecyrillic;04A5 +enhookcyrillic;04C8 +enspace;2002 +eogonek;0119 +eokorean;3153 +eopen;025B +eopenclosed;029A +eopenreversed;025C +eopenreversedclosed;025E +eopenreversedhook;025D +eparen;24A0 +epsilon;03B5 +epsilontonos;03AD +equal;003D +equalmonospace;FF1D +equalsmall;FE66 +equalsuperior;207C +equivalence;2261 +erbopomofo;3126 +ercyrillic;0440 +ereversed;0258 +ereversedcyrillic;044D +escyrillic;0441 +esdescendercyrillic;04AB +esh;0283 +eshcurl;0286 +eshortdeva;090E +eshortvowelsigndeva;0946 +eshreversedloop;01AA +eshsquatreversed;0285 +esmallhiragana;3047 +esmallkatakana;30A7 +esmallkatakanahalfwidth;FF6A +estimated;212E +esuperior;F6EC +eta;03B7 +etarmenian;0568 +etatonos;03AE +eth;00F0 +etilde;1EBD +etildebelow;1E1B +etnahtafoukhhebrew;0591 +etnahtafoukhlefthebrew;0591 +etnahtahebrew;0591 +etnahtalefthebrew;0591 +eturned;01DD +eukorean;3161 +euro;20AC +evowelsignbengali;09C7 +evowelsigndeva;0947 +evowelsigngujarati;0AC7 +exclam;0021 +exclamarmenian;055C +exclamdbl;203C +exclamdown;00A1 +exclamdownsmall;F7A1 +exclammonospace;FF01 +exclamsmall;F721 +existential;2203 +ezh;0292 +ezhcaron;01EF +ezhcurl;0293 +ezhreversed;01B9 +ezhtail;01BA +f;0066 +fadeva;095E +fagurmukhi;0A5E +fahrenheit;2109 +fathaarabic;064E +fathalowarabic;064E +fathatanarabic;064B +fbopomofo;3108 +fcircle;24D5 +fdotaccent;1E1F +feharabic;0641 +feharmenian;0586 +fehfinalarabic;FED2 +fehinitialarabic;FED3 +fehmedialarabic;FED4 +feicoptic;03E5 +female;2640 +ff;FB00 +ffi;FB03 +ffl;FB04 +fi;FB01 +fifteencircle;246E +fifteenparen;2482 +fifteenperiod;2496 +figuredash;2012 +filledbox;25A0 +filledrect;25AC +finalkaf;05DA +finalkafdagesh;FB3A +finalkafdageshhebrew;FB3A +finalkafhebrew;05DA +finalkafqamats;05DA 05B8 +finalkafqamatshebrew;05DA 05B8 +finalkafsheva;05DA 05B0 +finalkafshevahebrew;05DA 05B0 +finalmem;05DD +finalmemhebrew;05DD +finalnun;05DF +finalnunhebrew;05DF +finalpe;05E3 +finalpehebrew;05E3 +finaltsadi;05E5 +finaltsadihebrew;05E5 +firsttonechinese;02C9 +fisheye;25C9 +fitacyrillic;0473 +five;0035 +fivearabic;0665 +fivebengali;09EB +fivecircle;2464 +fivecircleinversesansserif;278E +fivedeva;096B +fiveeighths;215D +fivegujarati;0AEB +fivegurmukhi;0A6B +fivehackarabic;0665 +fivehangzhou;3025 +fiveideographicparen;3224 +fiveinferior;2085 +fivemonospace;FF15 +fiveoldstyle;F735 +fiveparen;2478 +fiveperiod;248C +fivepersian;06F5 +fiveroman;2174 +fivesuperior;2075 +fivethai;0E55 +fl;FB02 +florin;0192 +fmonospace;FF46 +fmsquare;3399 +fofanthai;0E1F +fofathai;0E1D +fongmanthai;0E4F +forall;2200 +four;0034 +fourarabic;0664 +fourbengali;09EA +fourcircle;2463 +fourcircleinversesansserif;278D +fourdeva;096A +fourgujarati;0AEA +fourgurmukhi;0A6A +fourhackarabic;0664 +fourhangzhou;3024 +fourideographicparen;3223 +fourinferior;2084 +fourmonospace;FF14 +fournumeratorbengali;09F7 +fouroldstyle;F734 +fourparen;2477 +fourperiod;248B +fourpersian;06F4 +fourroman;2173 +foursuperior;2074 +fourteencircle;246D +fourteenparen;2481 +fourteenperiod;2495 +fourthai;0E54 +fourthtonechinese;02CB +fparen;24A1 +fraction;2044 +franc;20A3 +g;0067 +gabengali;0997 +gacute;01F5 +gadeva;0917 +gafarabic;06AF +gaffinalarabic;FB93 +gafinitialarabic;FB94 +gafmedialarabic;FB95 +gagujarati;0A97 +gagurmukhi;0A17 +gahiragana;304C +gakatakana;30AC +gamma;03B3 +gammalatinsmall;0263 +gammasuperior;02E0 +gangiacoptic;03EB +gbopomofo;310D +gbreve;011F +gcaron;01E7 +gcedilla;0123 +gcircle;24D6 +gcircumflex;011D +gcommaaccent;0123 +gdot;0121 +gdotaccent;0121 +gecyrillic;0433 +gehiragana;3052 +gekatakana;30B2 +geometricallyequal;2251 +gereshaccenthebrew;059C +gereshhebrew;05F3 +gereshmuqdamhebrew;059D +germandbls;00DF +gershayimaccenthebrew;059E +gershayimhebrew;05F4 +getamark;3013 +ghabengali;0998 +ghadarmenian;0572 +ghadeva;0918 +ghagujarati;0A98 +ghagurmukhi;0A18 +ghainarabic;063A +ghainfinalarabic;FECE +ghaininitialarabic;FECF +ghainmedialarabic;FED0 +ghemiddlehookcyrillic;0495 +ghestrokecyrillic;0493 +gheupturncyrillic;0491 +ghhadeva;095A +ghhagurmukhi;0A5A +ghook;0260 +ghzsquare;3393 +gihiragana;304E +gikatakana;30AE +gimarmenian;0563 +gimel;05D2 +gimeldagesh;FB32 +gimeldageshhebrew;FB32 +gimelhebrew;05D2 +gjecyrillic;0453 +glottalinvertedstroke;01BE +glottalstop;0294 +glottalstopinverted;0296 +glottalstopmod;02C0 +glottalstopreversed;0295 +glottalstopreversedmod;02C1 +glottalstopreversedsuperior;02E4 +glottalstopstroke;02A1 +glottalstopstrokereversed;02A2 +gmacron;1E21 +gmonospace;FF47 +gohiragana;3054 +gokatakana;30B4 +gparen;24A2 +gpasquare;33AC +gradient;2207 +grave;0060 +gravebelowcmb;0316 +gravecmb;0300 +gravecomb;0300 +gravedeva;0953 +gravelowmod;02CE +gravemonospace;FF40 +gravetonecmb;0340 +greater;003E +greaterequal;2265 +greaterequalorless;22DB +greatermonospace;FF1E +greaterorequivalent;2273 +greaterorless;2277 +greateroverequal;2267 +greatersmall;FE65 +gscript;0261 +gstroke;01E5 +guhiragana;3050 +guillemotleft;00AB +guillemotright;00BB +guilsinglleft;2039 +guilsinglright;203A +gukatakana;30B0 +guramusquare;3318 +gysquare;33C9 +h;0068 +haabkhasiancyrillic;04A9 +haaltonearabic;06C1 +habengali;09B9 +hadescendercyrillic;04B3 +hadeva;0939 +hagujarati;0AB9 +hagurmukhi;0A39 +haharabic;062D +hahfinalarabic;FEA2 +hahinitialarabic;FEA3 +hahiragana;306F +hahmedialarabic;FEA4 +haitusquare;332A +hakatakana;30CF +hakatakanahalfwidth;FF8A +halantgurmukhi;0A4D +hamzaarabic;0621 +hamzadammaarabic;0621 064F +hamzadammatanarabic;0621 064C +hamzafathaarabic;0621 064E +hamzafathatanarabic;0621 064B +hamzalowarabic;0621 +hamzalowkasraarabic;0621 0650 +hamzalowkasratanarabic;0621 064D +hamzasukunarabic;0621 0652 +hangulfiller;3164 +hardsigncyrillic;044A +harpoonleftbarbup;21BC +harpoonrightbarbup;21C0 +hasquare;33CA +hatafpatah;05B2 +hatafpatah16;05B2 +hatafpatah23;05B2 +hatafpatah2f;05B2 +hatafpatahhebrew;05B2 +hatafpatahnarrowhebrew;05B2 +hatafpatahquarterhebrew;05B2 +hatafpatahwidehebrew;05B2 +hatafqamats;05B3 +hatafqamats1b;05B3 +hatafqamats28;05B3 +hatafqamats34;05B3 +hatafqamatshebrew;05B3 +hatafqamatsnarrowhebrew;05B3 +hatafqamatsquarterhebrew;05B3 +hatafqamatswidehebrew;05B3 +hatafsegol;05B1 +hatafsegol17;05B1 +hatafsegol24;05B1 +hatafsegol30;05B1 +hatafsegolhebrew;05B1 +hatafsegolnarrowhebrew;05B1 +hatafsegolquarterhebrew;05B1 +hatafsegolwidehebrew;05B1 +hbar;0127 +hbopomofo;310F +hbrevebelow;1E2B +hcedilla;1E29 +hcircle;24D7 +hcircumflex;0125 +hdieresis;1E27 +hdotaccent;1E23 +hdotbelow;1E25 +he;05D4 +heart;2665 +heartsuitblack;2665 +heartsuitwhite;2661 +hedagesh;FB34 +hedageshhebrew;FB34 +hehaltonearabic;06C1 +heharabic;0647 +hehebrew;05D4 +hehfinalaltonearabic;FBA7 +hehfinalalttwoarabic;FEEA +hehfinalarabic;FEEA +hehhamzaabovefinalarabic;FBA5 +hehhamzaaboveisolatedarabic;FBA4 +hehinitialaltonearabic;FBA8 +hehinitialarabic;FEEB +hehiragana;3078 +hehmedialaltonearabic;FBA9 +hehmedialarabic;FEEC +heiseierasquare;337B +hekatakana;30D8 +hekatakanahalfwidth;FF8D +hekutaarusquare;3336 +henghook;0267 +herutusquare;3339 +het;05D7 +hethebrew;05D7 +hhook;0266 +hhooksuperior;02B1 +hieuhacirclekorean;327B +hieuhaparenkorean;321B +hieuhcirclekorean;326D +hieuhkorean;314E +hieuhparenkorean;320D +hihiragana;3072 +hikatakana;30D2 +hikatakanahalfwidth;FF8B +hiriq;05B4 +hiriq14;05B4 +hiriq21;05B4 +hiriq2d;05B4 +hiriqhebrew;05B4 +hiriqnarrowhebrew;05B4 +hiriqquarterhebrew;05B4 +hiriqwidehebrew;05B4 +hlinebelow;1E96 +hmonospace;FF48 +hoarmenian;0570 +hohipthai;0E2B +hohiragana;307B +hokatakana;30DB +hokatakanahalfwidth;FF8E +holam;05B9 +holam19;05B9 +holam26;05B9 +holam32;05B9 +holamhebrew;05B9 +holamnarrowhebrew;05B9 +holamquarterhebrew;05B9 +holamwidehebrew;05B9 +honokhukthai;0E2E +hookabovecomb;0309 +hookcmb;0309 +hookpalatalizedbelowcmb;0321 +hookretroflexbelowcmb;0322 +hoonsquare;3342 +horicoptic;03E9 +horizontalbar;2015 +horncmb;031B +hotsprings;2668 +house;2302 +hparen;24A3 +hsuperior;02B0 +hturned;0265 +huhiragana;3075 +huiitosquare;3333 +hukatakana;30D5 +hukatakanahalfwidth;FF8C +hungarumlaut;02DD +hungarumlautcmb;030B +hv;0195 +hyphen;002D +hypheninferior;F6E5 +hyphenmonospace;FF0D +hyphensmall;FE63 +hyphensuperior;F6E6 +hyphentwo;2010 +i;0069 +iacute;00ED +iacyrillic;044F +ibengali;0987 +ibopomofo;3127 +ibreve;012D +icaron;01D0 +icircle;24D8 +icircumflex;00EE +icyrillic;0456 +idblgrave;0209 +ideographearthcircle;328F +ideographfirecircle;328B +ideographicallianceparen;323F +ideographiccallparen;323A +ideographiccentrecircle;32A5 +ideographicclose;3006 +ideographiccomma;3001 +ideographiccommaleft;FF64 +ideographiccongratulationparen;3237 +ideographiccorrectcircle;32A3 +ideographicearthparen;322F +ideographicenterpriseparen;323D +ideographicexcellentcircle;329D +ideographicfestivalparen;3240 +ideographicfinancialcircle;3296 +ideographicfinancialparen;3236 +ideographicfireparen;322B +ideographichaveparen;3232 +ideographichighcircle;32A4 +ideographiciterationmark;3005 +ideographiclaborcircle;3298 +ideographiclaborparen;3238 +ideographicleftcircle;32A7 +ideographiclowcircle;32A6 +ideographicmedicinecircle;32A9 +ideographicmetalparen;322E +ideographicmoonparen;322A +ideographicnameparen;3234 +ideographicperiod;3002 +ideographicprintcircle;329E +ideographicreachparen;3243 +ideographicrepresentparen;3239 +ideographicresourceparen;323E +ideographicrightcircle;32A8 +ideographicsecretcircle;3299 +ideographicselfparen;3242 +ideographicsocietyparen;3233 +ideographicspace;3000 +ideographicspecialparen;3235 +ideographicstockparen;3231 +ideographicstudyparen;323B +ideographicsunparen;3230 +ideographicsuperviseparen;323C +ideographicwaterparen;322C +ideographicwoodparen;322D +ideographiczero;3007 +ideographmetalcircle;328E +ideographmooncircle;328A +ideographnamecircle;3294 +ideographsuncircle;3290 +ideographwatercircle;328C +ideographwoodcircle;328D +ideva;0907 +idieresis;00EF +idieresisacute;1E2F +idieresiscyrillic;04E5 +idotbelow;1ECB +iebrevecyrillic;04D7 +iecyrillic;0435 +ieungacirclekorean;3275 +ieungaparenkorean;3215 +ieungcirclekorean;3267 +ieungkorean;3147 +ieungparenkorean;3207 +igrave;00EC +igujarati;0A87 +igurmukhi;0A07 +ihiragana;3044 +ihookabove;1EC9 +iibengali;0988 +iicyrillic;0438 +iideva;0908 +iigujarati;0A88 +iigurmukhi;0A08 +iimatragurmukhi;0A40 +iinvertedbreve;020B +iishortcyrillic;0439 +iivowelsignbengali;09C0 +iivowelsigndeva;0940 +iivowelsigngujarati;0AC0 +ij;0133 +ikatakana;30A4 +ikatakanahalfwidth;FF72 +ikorean;3163 +ilde;02DC +iluyhebrew;05AC +imacron;012B +imacroncyrillic;04E3 +imageorapproximatelyequal;2253 +imatragurmukhi;0A3F +imonospace;FF49 +increment;2206 +infinity;221E +iniarmenian;056B +integral;222B +integralbottom;2321 +integralbt;2321 +integralex;F8F5 +integraltop;2320 +integraltp;2320 +intersection;2229 +intisquare;3305 +invbullet;25D8 +invcircle;25D9 +invsmileface;263B +iocyrillic;0451 +iogonek;012F +iota;03B9 +iotadieresis;03CA +iotadieresistonos;0390 +iotalatin;0269 +iotatonos;03AF +iparen;24A4 +irigurmukhi;0A72 +ismallhiragana;3043 +ismallkatakana;30A3 +ismallkatakanahalfwidth;FF68 +issharbengali;09FA +istroke;0268 +isuperior;F6ED +iterationhiragana;309D +iterationkatakana;30FD +itilde;0129 +itildebelow;1E2D +iubopomofo;3129 +iucyrillic;044E +ivowelsignbengali;09BF +ivowelsigndeva;093F +ivowelsigngujarati;0ABF +izhitsacyrillic;0475 +izhitsadblgravecyrillic;0477 +j;006A +jaarmenian;0571 +jabengali;099C +jadeva;091C +jagujarati;0A9C +jagurmukhi;0A1C +jbopomofo;3110 +jcaron;01F0 +jcircle;24D9 +jcircumflex;0135 +jcrossedtail;029D +jdotlessstroke;025F +jecyrillic;0458 +jeemarabic;062C +jeemfinalarabic;FE9E +jeeminitialarabic;FE9F +jeemmedialarabic;FEA0 +jeharabic;0698 +jehfinalarabic;FB8B +jhabengali;099D +jhadeva;091D +jhagujarati;0A9D +jhagurmukhi;0A1D +jheharmenian;057B +jis;3004 +jmonospace;FF4A +jparen;24A5 +jsuperior;02B2 +k;006B +kabashkircyrillic;04A1 +kabengali;0995 +kacute;1E31 +kacyrillic;043A +kadescendercyrillic;049B +kadeva;0915 +kaf;05DB +kafarabic;0643 +kafdagesh;FB3B +kafdageshhebrew;FB3B +kaffinalarabic;FEDA +kafhebrew;05DB +kafinitialarabic;FEDB +kafmedialarabic;FEDC +kafrafehebrew;FB4D +kagujarati;0A95 +kagurmukhi;0A15 +kahiragana;304B +kahookcyrillic;04C4 +kakatakana;30AB +kakatakanahalfwidth;FF76 +kappa;03BA +kappasymbolgreek;03F0 +kapyeounmieumkorean;3171 +kapyeounphieuphkorean;3184 +kapyeounpieupkorean;3178 +kapyeounssangpieupkorean;3179 +karoriisquare;330D +kashidaautoarabic;0640 +kashidaautonosidebearingarabic;0640 +kasmallkatakana;30F5 +kasquare;3384 +kasraarabic;0650 +kasratanarabic;064D +kastrokecyrillic;049F +katahiraprolongmarkhalfwidth;FF70 +kaverticalstrokecyrillic;049D +kbopomofo;310E +kcalsquare;3389 +kcaron;01E9 +kcedilla;0137 +kcircle;24DA +kcommaaccent;0137 +kdotbelow;1E33 +keharmenian;0584 +kehiragana;3051 +kekatakana;30B1 +kekatakanahalfwidth;FF79 +kenarmenian;056F +kesmallkatakana;30F6 +kgreenlandic;0138 +khabengali;0996 +khacyrillic;0445 +khadeva;0916 +khagujarati;0A96 +khagurmukhi;0A16 +khaharabic;062E +khahfinalarabic;FEA6 +khahinitialarabic;FEA7 +khahmedialarabic;FEA8 +kheicoptic;03E7 +khhadeva;0959 +khhagurmukhi;0A59 +khieukhacirclekorean;3278 +khieukhaparenkorean;3218 +khieukhcirclekorean;326A +khieukhkorean;314B +khieukhparenkorean;320A +khokhaithai;0E02 +khokhonthai;0E05 +khokhuatthai;0E03 +khokhwaithai;0E04 +khomutthai;0E5B +khook;0199 +khorakhangthai;0E06 +khzsquare;3391 +kihiragana;304D +kikatakana;30AD +kikatakanahalfwidth;FF77 +kiroguramusquare;3315 +kiromeetorusquare;3316 +kirosquare;3314 +kiyeokacirclekorean;326E +kiyeokaparenkorean;320E +kiyeokcirclekorean;3260 +kiyeokkorean;3131 +kiyeokparenkorean;3200 +kiyeoksioskorean;3133 +kjecyrillic;045C +klinebelow;1E35 +klsquare;3398 +kmcubedsquare;33A6 +kmonospace;FF4B +kmsquaredsquare;33A2 +kohiragana;3053 +kohmsquare;33C0 +kokaithai;0E01 +kokatakana;30B3 +kokatakanahalfwidth;FF7A +kooposquare;331E +koppacyrillic;0481 +koreanstandardsymbol;327F +koroniscmb;0343 +kparen;24A6 +kpasquare;33AA +ksicyrillic;046F +ktsquare;33CF +kturned;029E +kuhiragana;304F +kukatakana;30AF +kukatakanahalfwidth;FF78 +kvsquare;33B8 +kwsquare;33BE +l;006C +labengali;09B2 +lacute;013A +ladeva;0932 +lagujarati;0AB2 +lagurmukhi;0A32 +lakkhangyaothai;0E45 +lamaleffinalarabic;FEFC +lamalefhamzaabovefinalarabic;FEF8 +lamalefhamzaaboveisolatedarabic;FEF7 +lamalefhamzabelowfinalarabic;FEFA +lamalefhamzabelowisolatedarabic;FEF9 +lamalefisolatedarabic;FEFB +lamalefmaddaabovefinalarabic;FEF6 +lamalefmaddaaboveisolatedarabic;FEF5 +lamarabic;0644 +lambda;03BB +lambdastroke;019B +lamed;05DC +lameddagesh;FB3C +lameddageshhebrew;FB3C +lamedhebrew;05DC +lamedholam;05DC 05B9 +lamedholamdagesh;05DC 05B9 05BC +lamedholamdageshhebrew;05DC 05B9 05BC +lamedholamhebrew;05DC 05B9 +lamfinalarabic;FEDE +lamhahinitialarabic;FCCA +laminitialarabic;FEDF +lamjeeminitialarabic;FCC9 +lamkhahinitialarabic;FCCB +lamlamhehisolatedarabic;FDF2 +lammedialarabic;FEE0 +lammeemhahinitialarabic;FD88 +lammeeminitialarabic;FCCC +lammeemjeeminitialarabic;FEDF FEE4 FEA0 +lammeemkhahinitialarabic;FEDF FEE4 FEA8 +largecircle;25EF +lbar;019A +lbelt;026C +lbopomofo;310C +lcaron;013E +lcedilla;013C +lcircle;24DB +lcircumflexbelow;1E3D +lcommaaccent;013C +ldot;0140 +ldotaccent;0140 +ldotbelow;1E37 +ldotbelowmacron;1E39 +leftangleabovecmb;031A +lefttackbelowcmb;0318 +less;003C +lessequal;2264 +lessequalorgreater;22DA +lessmonospace;FF1C +lessorequivalent;2272 +lessorgreater;2276 +lessoverequal;2266 +lesssmall;FE64 +lezh;026E +lfblock;258C +lhookretroflex;026D +lira;20A4 +liwnarmenian;056C +lj;01C9 +ljecyrillic;0459 +ll;F6C0 +lladeva;0933 +llagujarati;0AB3 +llinebelow;1E3B +llladeva;0934 +llvocalicbengali;09E1 +llvocalicdeva;0961 +llvocalicvowelsignbengali;09E3 +llvocalicvowelsigndeva;0963 +lmiddletilde;026B +lmonospace;FF4C +lmsquare;33D0 +lochulathai;0E2C +logicaland;2227 +logicalnot;00AC +logicalnotreversed;2310 +logicalor;2228 +lolingthai;0E25 +longs;017F +lowlinecenterline;FE4E +lowlinecmb;0332 +lowlinedashed;FE4D +lozenge;25CA +lparen;24A7 +lslash;0142 +lsquare;2113 +lsuperior;F6EE +ltshade;2591 +luthai;0E26 +lvocalicbengali;098C +lvocalicdeva;090C +lvocalicvowelsignbengali;09E2 +lvocalicvowelsigndeva;0962 +lxsquare;33D3 +m;006D +mabengali;09AE +macron;00AF +macronbelowcmb;0331 +macroncmb;0304 +macronlowmod;02CD +macronmonospace;FFE3 +macute;1E3F +madeva;092E +magujarati;0AAE +magurmukhi;0A2E +mahapakhhebrew;05A4 +mahapakhlefthebrew;05A4 +mahiragana;307E +maichattawalowleftthai;F895 +maichattawalowrightthai;F894 +maichattawathai;0E4B +maichattawaupperleftthai;F893 +maieklowleftthai;F88C +maieklowrightthai;F88B +maiekthai;0E48 +maiekupperleftthai;F88A +maihanakatleftthai;F884 +maihanakatthai;0E31 +maitaikhuleftthai;F889 +maitaikhuthai;0E47 +maitholowleftthai;F88F +maitholowrightthai;F88E +maithothai;0E49 +maithoupperleftthai;F88D +maitrilowleftthai;F892 +maitrilowrightthai;F891 +maitrithai;0E4A +maitriupperleftthai;F890 +maiyamokthai;0E46 +makatakana;30DE +makatakanahalfwidth;FF8F +male;2642 +mansyonsquare;3347 +maqafhebrew;05BE +mars;2642 +masoracirclehebrew;05AF +masquare;3383 +mbopomofo;3107 +mbsquare;33D4 +mcircle;24DC +mcubedsquare;33A5 +mdotaccent;1E41 +mdotbelow;1E43 +meemarabic;0645 +meemfinalarabic;FEE2 +meeminitialarabic;FEE3 +meemmedialarabic;FEE4 +meemmeeminitialarabic;FCD1 +meemmeemisolatedarabic;FC48 +meetorusquare;334D +mehiragana;3081 +meizierasquare;337E +mekatakana;30E1 +mekatakanahalfwidth;FF92 +mem;05DE +memdagesh;FB3E +memdageshhebrew;FB3E +memhebrew;05DE +menarmenian;0574 +merkhahebrew;05A5 +merkhakefulahebrew;05A6 +merkhakefulalefthebrew;05A6 +merkhalefthebrew;05A5 +mhook;0271 +mhzsquare;3392 +middledotkatakanahalfwidth;FF65 +middot;00B7 +mieumacirclekorean;3272 +mieumaparenkorean;3212 +mieumcirclekorean;3264 +mieumkorean;3141 +mieumpansioskorean;3170 +mieumparenkorean;3204 +mieumpieupkorean;316E +mieumsioskorean;316F +mihiragana;307F +mikatakana;30DF +mikatakanahalfwidth;FF90 +minus;2212 +minusbelowcmb;0320 +minuscircle;2296 +minusmod;02D7 +minusplus;2213 +minute;2032 +miribaarusquare;334A +mirisquare;3349 +mlonglegturned;0270 +mlsquare;3396 +mmcubedsquare;33A3 +mmonospace;FF4D +mmsquaredsquare;339F +mohiragana;3082 +mohmsquare;33C1 +mokatakana;30E2 +mokatakanahalfwidth;FF93 +molsquare;33D6 +momathai;0E21 +moverssquare;33A7 +moverssquaredsquare;33A8 +mparen;24A8 +mpasquare;33AB +mssquare;33B3 +msuperior;F6EF +mturned;026F +mu;00B5 +mu1;00B5 +muasquare;3382 +muchgreater;226B +muchless;226A +mufsquare;338C +mugreek;03BC +mugsquare;338D +muhiragana;3080 +mukatakana;30E0 +mukatakanahalfwidth;FF91 +mulsquare;3395 +multiply;00D7 +mumsquare;339B +munahhebrew;05A3 +munahlefthebrew;05A3 +musicalnote;266A +musicalnotedbl;266B +musicflatsign;266D +musicsharpsign;266F +mussquare;33B2 +muvsquare;33B6 +muwsquare;33BC +mvmegasquare;33B9 +mvsquare;33B7 +mwmegasquare;33BF +mwsquare;33BD +n;006E +nabengali;09A8 +nabla;2207 +nacute;0144 +nadeva;0928 +nagujarati;0AA8 +nagurmukhi;0A28 +nahiragana;306A +nakatakana;30CA +nakatakanahalfwidth;FF85 +napostrophe;0149 +nasquare;3381 +nbopomofo;310B +nbspace;00A0 +ncaron;0148 +ncedilla;0146 +ncircle;24DD +ncircumflexbelow;1E4B +ncommaaccent;0146 +ndotaccent;1E45 +ndotbelow;1E47 +nehiragana;306D +nekatakana;30CD +nekatakanahalfwidth;FF88 +newsheqelsign;20AA +nfsquare;338B +ngabengali;0999 +ngadeva;0919 +ngagujarati;0A99 +ngagurmukhi;0A19 +ngonguthai;0E07 +nhiragana;3093 +nhookleft;0272 +nhookretroflex;0273 +nieunacirclekorean;326F +nieunaparenkorean;320F +nieuncieuckorean;3135 +nieuncirclekorean;3261 +nieunhieuhkorean;3136 +nieunkorean;3134 +nieunpansioskorean;3168 +nieunparenkorean;3201 +nieunsioskorean;3167 +nieuntikeutkorean;3166 +nihiragana;306B +nikatakana;30CB +nikatakanahalfwidth;FF86 +nikhahitleftthai;F899 +nikhahitthai;0E4D +nine;0039 +ninearabic;0669 +ninebengali;09EF +ninecircle;2468 +ninecircleinversesansserif;2792 +ninedeva;096F +ninegujarati;0AEF +ninegurmukhi;0A6F +ninehackarabic;0669 +ninehangzhou;3029 +nineideographicparen;3228 +nineinferior;2089 +ninemonospace;FF19 +nineoldstyle;F739 +nineparen;247C +nineperiod;2490 +ninepersian;06F9 +nineroman;2178 +ninesuperior;2079 +nineteencircle;2472 +nineteenparen;2486 +nineteenperiod;249A +ninethai;0E59 +nj;01CC +njecyrillic;045A +nkatakana;30F3 +nkatakanahalfwidth;FF9D +nlegrightlong;019E +nlinebelow;1E49 +nmonospace;FF4E +nmsquare;339A +nnabengali;09A3 +nnadeva;0923 +nnagujarati;0AA3 +nnagurmukhi;0A23 +nnnadeva;0929 +nohiragana;306E +nokatakana;30CE +nokatakanahalfwidth;FF89 +nonbreakingspace;00A0 +nonenthai;0E13 +nonuthai;0E19 +noonarabic;0646 +noonfinalarabic;FEE6 +noonghunnaarabic;06BA +noonghunnafinalarabic;FB9F +noonhehinitialarabic;FEE7 FEEC +nooninitialarabic;FEE7 +noonjeeminitialarabic;FCD2 +noonjeemisolatedarabic;FC4B +noonmedialarabic;FEE8 +noonmeeminitialarabic;FCD5 +noonmeemisolatedarabic;FC4E +noonnoonfinalarabic;FC8D +notcontains;220C +notelement;2209 +notelementof;2209 +notequal;2260 +notgreater;226F +notgreaternorequal;2271 +notgreaternorless;2279 +notidentical;2262 +notless;226E +notlessnorequal;2270 +notparallel;2226 +notprecedes;2280 +notsubset;2284 +notsucceeds;2281 +notsuperset;2285 +nowarmenian;0576 +nparen;24A9 +nssquare;33B1 +nsuperior;207F +ntilde;00F1 +nu;03BD +nuhiragana;306C +nukatakana;30CC +nukatakanahalfwidth;FF87 +nuktabengali;09BC +nuktadeva;093C +nuktagujarati;0ABC +nuktagurmukhi;0A3C +numbersign;0023 +numbersignmonospace;FF03 +numbersignsmall;FE5F +numeralsigngreek;0374 +numeralsignlowergreek;0375 +numero;2116 +nun;05E0 +nundagesh;FB40 +nundageshhebrew;FB40 +nunhebrew;05E0 +nvsquare;33B5 +nwsquare;33BB +nyabengali;099E +nyadeva;091E +nyagujarati;0A9E +nyagurmukhi;0A1E +o;006F +oacute;00F3 +oangthai;0E2D +obarred;0275 +obarredcyrillic;04E9 +obarreddieresiscyrillic;04EB +obengali;0993 +obopomofo;311B +obreve;014F +ocandradeva;0911 +ocandragujarati;0A91 +ocandravowelsigndeva;0949 +ocandravowelsigngujarati;0AC9 +ocaron;01D2 +ocircle;24DE +ocircumflex;00F4 +ocircumflexacute;1ED1 +ocircumflexdotbelow;1ED9 +ocircumflexgrave;1ED3 +ocircumflexhookabove;1ED5 +ocircumflextilde;1ED7 +ocyrillic;043E +odblacute;0151 +odblgrave;020D +odeva;0913 +odieresis;00F6 +odieresiscyrillic;04E7 +odotbelow;1ECD +oe;0153 +oekorean;315A +ogonek;02DB +ogonekcmb;0328 +ograve;00F2 +ogujarati;0A93 +oharmenian;0585 +ohiragana;304A +ohookabove;1ECF +ohorn;01A1 +ohornacute;1EDB +ohorndotbelow;1EE3 +ohorngrave;1EDD +ohornhookabove;1EDF +ohorntilde;1EE1 +ohungarumlaut;0151 +oi;01A3 +oinvertedbreve;020F +okatakana;30AA +okatakanahalfwidth;FF75 +okorean;3157 +olehebrew;05AB +omacron;014D +omacronacute;1E53 +omacrongrave;1E51 +omdeva;0950 +omega;03C9 +omega1;03D6 +omegacyrillic;0461 +omegalatinclosed;0277 +omegaroundcyrillic;047B +omegatitlocyrillic;047D +omegatonos;03CE +omgujarati;0AD0 +omicron;03BF +omicrontonos;03CC +omonospace;FF4F +one;0031 +onearabic;0661 +onebengali;09E7 +onecircle;2460 +onecircleinversesansserif;278A +onedeva;0967 +onedotenleader;2024 +oneeighth;215B +onefitted;F6DC +onegujarati;0AE7 +onegurmukhi;0A67 +onehackarabic;0661 +onehalf;00BD +onehangzhou;3021 +oneideographicparen;3220 +oneinferior;2081 +onemonospace;FF11 +onenumeratorbengali;09F4 +oneoldstyle;F731 +oneparen;2474 +oneperiod;2488 +onepersian;06F1 +onequarter;00BC +oneroman;2170 +onesuperior;00B9 +onethai;0E51 +onethird;2153 +oogonek;01EB +oogonekmacron;01ED +oogurmukhi;0A13 +oomatragurmukhi;0A4B +oopen;0254 +oparen;24AA +openbullet;25E6 +option;2325 +ordfeminine;00AA +ordmasculine;00BA +orthogonal;221F +oshortdeva;0912 +oshortvowelsigndeva;094A +oslash;00F8 +oslashacute;01FF +osmallhiragana;3049 +osmallkatakana;30A9 +osmallkatakanahalfwidth;FF6B +ostrokeacute;01FF +osuperior;F6F0 +otcyrillic;047F +otilde;00F5 +otildeacute;1E4D +otildedieresis;1E4F +oubopomofo;3121 +overline;203E +overlinecenterline;FE4A +overlinecmb;0305 +overlinedashed;FE49 +overlinedblwavy;FE4C +overlinewavy;FE4B +overscore;00AF +ovowelsignbengali;09CB +ovowelsigndeva;094B +ovowelsigngujarati;0ACB +p;0070 +paampssquare;3380 +paasentosquare;332B +pabengali;09AA +pacute;1E55 +padeva;092A +pagedown;21DF +pageup;21DE +pagujarati;0AAA +pagurmukhi;0A2A +pahiragana;3071 +paiyannoithai;0E2F +pakatakana;30D1 +palatalizationcyrilliccmb;0484 +palochkacyrillic;04C0 +pansioskorean;317F +paragraph;00B6 +parallel;2225 +parenleft;0028 +parenleftaltonearabic;FD3E +parenleftbt;F8ED +parenleftex;F8EC +parenleftinferior;208D +parenleftmonospace;FF08 +parenleftsmall;FE59 +parenleftsuperior;207D +parenlefttp;F8EB +parenleftvertical;FE35 +parenright;0029 +parenrightaltonearabic;FD3F +parenrightbt;F8F8 +parenrightex;F8F7 +parenrightinferior;208E +parenrightmonospace;FF09 +parenrightsmall;FE5A +parenrightsuperior;207E +parenrighttp;F8F6 +parenrightvertical;FE36 +partialdiff;2202 +paseqhebrew;05C0 +pashtahebrew;0599 +pasquare;33A9 +patah;05B7 +patah11;05B7 +patah1d;05B7 +patah2a;05B7 +patahhebrew;05B7 +patahnarrowhebrew;05B7 +patahquarterhebrew;05B7 +patahwidehebrew;05B7 +pazerhebrew;05A1 +pbopomofo;3106 +pcircle;24DF +pdotaccent;1E57 +pe;05E4 +pecyrillic;043F +pedagesh;FB44 +pedageshhebrew;FB44 +peezisquare;333B +pefinaldageshhebrew;FB43 +peharabic;067E +peharmenian;057A +pehebrew;05E4 +pehfinalarabic;FB57 +pehinitialarabic;FB58 +pehiragana;307A +pehmedialarabic;FB59 +pekatakana;30DA +pemiddlehookcyrillic;04A7 +perafehebrew;FB4E +percent;0025 +percentarabic;066A +percentmonospace;FF05 +percentsmall;FE6A +period;002E +periodarmenian;0589 +periodcentered;00B7 +periodhalfwidth;FF61 +periodinferior;F6E7 +periodmonospace;FF0E +periodsmall;FE52 +periodsuperior;F6E8 +perispomenigreekcmb;0342 +perpendicular;22A5 +perthousand;2030 +peseta;20A7 +pfsquare;338A +phabengali;09AB +phadeva;092B +phagujarati;0AAB +phagurmukhi;0A2B +phi;03C6 +phi1;03D5 +phieuphacirclekorean;327A +phieuphaparenkorean;321A +phieuphcirclekorean;326C +phieuphkorean;314D +phieuphparenkorean;320C +philatin;0278 +phinthuthai;0E3A +phisymbolgreek;03D5 +phook;01A5 +phophanthai;0E1E +phophungthai;0E1C +phosamphaothai;0E20 +pi;03C0 +pieupacirclekorean;3273 +pieupaparenkorean;3213 +pieupcieuckorean;3176 +pieupcirclekorean;3265 +pieupkiyeokkorean;3172 +pieupkorean;3142 +pieupparenkorean;3205 +pieupsioskiyeokkorean;3174 +pieupsioskorean;3144 +pieupsiostikeutkorean;3175 +pieupthieuthkorean;3177 +pieuptikeutkorean;3173 +pihiragana;3074 +pikatakana;30D4 +pisymbolgreek;03D6 +piwrarmenian;0583 +plus;002B +plusbelowcmb;031F +pluscircle;2295 +plusminus;00B1 +plusmod;02D6 +plusmonospace;FF0B +plussmall;FE62 +plussuperior;207A +pmonospace;FF50 +pmsquare;33D8 +pohiragana;307D +pointingindexdownwhite;261F +pointingindexleftwhite;261C +pointingindexrightwhite;261E +pointingindexupwhite;261D +pokatakana;30DD +poplathai;0E1B +postalmark;3012 +postalmarkface;3020 +pparen;24AB +precedes;227A +prescription;211E +primemod;02B9 +primereversed;2035 +product;220F +projective;2305 +prolongedkana;30FC +propellor;2318 +propersubset;2282 +propersuperset;2283 +proportion;2237 +proportional;221D +psi;03C8 +psicyrillic;0471 +psilipneumatacyrilliccmb;0486 +pssquare;33B0 +puhiragana;3077 +pukatakana;30D7 +pvsquare;33B4 +pwsquare;33BA +q;0071 +qadeva;0958 +qadmahebrew;05A8 +qafarabic;0642 +qaffinalarabic;FED6 +qafinitialarabic;FED7 +qafmedialarabic;FED8 +qamats;05B8 +qamats10;05B8 +qamats1a;05B8 +qamats1c;05B8 +qamats27;05B8 +qamats29;05B8 +qamats33;05B8 +qamatsde;05B8 +qamatshebrew;05B8 +qamatsnarrowhebrew;05B8 +qamatsqatanhebrew;05B8 +qamatsqatannarrowhebrew;05B8 +qamatsqatanquarterhebrew;05B8 +qamatsqatanwidehebrew;05B8 +qamatsquarterhebrew;05B8 +qamatswidehebrew;05B8 +qarneyparahebrew;059F +qbopomofo;3111 +qcircle;24E0 +qhook;02A0 +qmonospace;FF51 +qof;05E7 +qofdagesh;FB47 +qofdageshhebrew;FB47 +qofhatafpatah;05E7 05B2 +qofhatafpatahhebrew;05E7 05B2 +qofhatafsegol;05E7 05B1 +qofhatafsegolhebrew;05E7 05B1 +qofhebrew;05E7 +qofhiriq;05E7 05B4 +qofhiriqhebrew;05E7 05B4 +qofholam;05E7 05B9 +qofholamhebrew;05E7 05B9 +qofpatah;05E7 05B7 +qofpatahhebrew;05E7 05B7 +qofqamats;05E7 05B8 +qofqamatshebrew;05E7 05B8 +qofqubuts;05E7 05BB +qofqubutshebrew;05E7 05BB +qofsegol;05E7 05B6 +qofsegolhebrew;05E7 05B6 +qofsheva;05E7 05B0 +qofshevahebrew;05E7 05B0 +qoftsere;05E7 05B5 +qoftserehebrew;05E7 05B5 +qparen;24AC +quarternote;2669 +qubuts;05BB +qubuts18;05BB +qubuts25;05BB +qubuts31;05BB +qubutshebrew;05BB +qubutsnarrowhebrew;05BB +qubutsquarterhebrew;05BB +qubutswidehebrew;05BB +question;003F +questionarabic;061F +questionarmenian;055E +questiondown;00BF +questiondownsmall;F7BF +questiongreek;037E +questionmonospace;FF1F +questionsmall;F73F +quotedbl;0022 +quotedblbase;201E +quotedblleft;201C +quotedblmonospace;FF02 +quotedblprime;301E +quotedblprimereversed;301D +quotedblright;201D +quoteleft;2018 +quoteleftreversed;201B +quotereversed;201B +quoteright;2019 +quoterightn;0149 +quotesinglbase;201A +quotesingle;0027 +quotesinglemonospace;FF07 +r;0072 +raarmenian;057C +rabengali;09B0 +racute;0155 +radeva;0930 +radical;221A +radicalex;F8E5 +radoverssquare;33AE +radoverssquaredsquare;33AF +radsquare;33AD +rafe;05BF +rafehebrew;05BF +ragujarati;0AB0 +ragurmukhi;0A30 +rahiragana;3089 +rakatakana;30E9 +rakatakanahalfwidth;FF97 +ralowerdiagonalbengali;09F1 +ramiddlediagonalbengali;09F0 +ramshorn;0264 +ratio;2236 +rbopomofo;3116 +rcaron;0159 +rcedilla;0157 +rcircle;24E1 +rcommaaccent;0157 +rdblgrave;0211 +rdotaccent;1E59 +rdotbelow;1E5B +rdotbelowmacron;1E5D +referencemark;203B +reflexsubset;2286 +reflexsuperset;2287 +registered;00AE +registersans;F8E8 +registerserif;F6DA +reharabic;0631 +reharmenian;0580 +rehfinalarabic;FEAE +rehiragana;308C +rehyehaleflamarabic;0631 FEF3 FE8E 0644 +rekatakana;30EC +rekatakanahalfwidth;FF9A +resh;05E8 +reshdageshhebrew;FB48 +reshhatafpatah;05E8 05B2 +reshhatafpatahhebrew;05E8 05B2 +reshhatafsegol;05E8 05B1 +reshhatafsegolhebrew;05E8 05B1 +reshhebrew;05E8 +reshhiriq;05E8 05B4 +reshhiriqhebrew;05E8 05B4 +reshholam;05E8 05B9 +reshholamhebrew;05E8 05B9 +reshpatah;05E8 05B7 +reshpatahhebrew;05E8 05B7 +reshqamats;05E8 05B8 +reshqamatshebrew;05E8 05B8 +reshqubuts;05E8 05BB +reshqubutshebrew;05E8 05BB +reshsegol;05E8 05B6 +reshsegolhebrew;05E8 05B6 +reshsheva;05E8 05B0 +reshshevahebrew;05E8 05B0 +reshtsere;05E8 05B5 +reshtserehebrew;05E8 05B5 +reversedtilde;223D +reviahebrew;0597 +reviamugrashhebrew;0597 +revlogicalnot;2310 +rfishhook;027E +rfishhookreversed;027F +rhabengali;09DD +rhadeva;095D +rho;03C1 +rhook;027D +rhookturned;027B +rhookturnedsuperior;02B5 +rhosymbolgreek;03F1 +rhotichookmod;02DE +rieulacirclekorean;3271 +rieulaparenkorean;3211 +rieulcirclekorean;3263 +rieulhieuhkorean;3140 +rieulkiyeokkorean;313A +rieulkiyeoksioskorean;3169 +rieulkorean;3139 +rieulmieumkorean;313B +rieulpansioskorean;316C +rieulparenkorean;3203 +rieulphieuphkorean;313F +rieulpieupkorean;313C +rieulpieupsioskorean;316B +rieulsioskorean;313D +rieulthieuthkorean;313E +rieultikeutkorean;316A +rieulyeorinhieuhkorean;316D +rightangle;221F +righttackbelowcmb;0319 +righttriangle;22BF +rihiragana;308A +rikatakana;30EA +rikatakanahalfwidth;FF98 +ring;02DA +ringbelowcmb;0325 +ringcmb;030A +ringhalfleft;02BF +ringhalfleftarmenian;0559 +ringhalfleftbelowcmb;031C +ringhalfleftcentered;02D3 +ringhalfright;02BE +ringhalfrightbelowcmb;0339 +ringhalfrightcentered;02D2 +rinvertedbreve;0213 +rittorusquare;3351 +rlinebelow;1E5F +rlongleg;027C +rlonglegturned;027A +rmonospace;FF52 +rohiragana;308D +rokatakana;30ED +rokatakanahalfwidth;FF9B +roruathai;0E23 +rparen;24AD +rrabengali;09DC +rradeva;0931 +rragurmukhi;0A5C +rreharabic;0691 +rrehfinalarabic;FB8D +rrvocalicbengali;09E0 +rrvocalicdeva;0960 +rrvocalicgujarati;0AE0 +rrvocalicvowelsignbengali;09C4 +rrvocalicvowelsigndeva;0944 +rrvocalicvowelsigngujarati;0AC4 +rsuperior;F6F1 +rtblock;2590 +rturned;0279 +rturnedsuperior;02B4 +ruhiragana;308B +rukatakana;30EB +rukatakanahalfwidth;FF99 +rupeemarkbengali;09F2 +rupeesignbengali;09F3 +rupiah;F6DD +ruthai;0E24 +rvocalicbengali;098B +rvocalicdeva;090B +rvocalicgujarati;0A8B +rvocalicvowelsignbengali;09C3 +rvocalicvowelsigndeva;0943 +rvocalicvowelsigngujarati;0AC3 +s;0073 +sabengali;09B8 +sacute;015B +sacutedotaccent;1E65 +sadarabic;0635 +sadeva;0938 +sadfinalarabic;FEBA +sadinitialarabic;FEBB +sadmedialarabic;FEBC +sagujarati;0AB8 +sagurmukhi;0A38 +sahiragana;3055 +sakatakana;30B5 +sakatakanahalfwidth;FF7B +sallallahoualayhewasallamarabic;FDFA +samekh;05E1 +samekhdagesh;FB41 +samekhdageshhebrew;FB41 +samekhhebrew;05E1 +saraaathai;0E32 +saraaethai;0E41 +saraaimaimalaithai;0E44 +saraaimaimuanthai;0E43 +saraamthai;0E33 +saraathai;0E30 +saraethai;0E40 +saraiileftthai;F886 +saraiithai;0E35 +saraileftthai;F885 +saraithai;0E34 +saraothai;0E42 +saraueeleftthai;F888 +saraueethai;0E37 +saraueleftthai;F887 +sarauethai;0E36 +sarauthai;0E38 +sarauuthai;0E39 +sbopomofo;3119 +scaron;0161 +scarondotaccent;1E67 +scedilla;015F +schwa;0259 +schwacyrillic;04D9 +schwadieresiscyrillic;04DB +schwahook;025A +scircle;24E2 +scircumflex;015D +scommaaccent;0219 +sdotaccent;1E61 +sdotbelow;1E63 +sdotbelowdotaccent;1E69 +seagullbelowcmb;033C +second;2033 +secondtonechinese;02CA +section;00A7 +seenarabic;0633 +seenfinalarabic;FEB2 +seeninitialarabic;FEB3 +seenmedialarabic;FEB4 +segol;05B6 +segol13;05B6 +segol1f;05B6 +segol2c;05B6 +segolhebrew;05B6 +segolnarrowhebrew;05B6 +segolquarterhebrew;05B6 +segoltahebrew;0592 +segolwidehebrew;05B6 +seharmenian;057D +sehiragana;305B +sekatakana;30BB +sekatakanahalfwidth;FF7E +semicolon;003B +semicolonarabic;061B +semicolonmonospace;FF1B +semicolonsmall;FE54 +semivoicedmarkkana;309C +semivoicedmarkkanahalfwidth;FF9F +sentisquare;3322 +sentosquare;3323 +seven;0037 +sevenarabic;0667 +sevenbengali;09ED +sevencircle;2466 +sevencircleinversesansserif;2790 +sevendeva;096D +seveneighths;215E +sevengujarati;0AED +sevengurmukhi;0A6D +sevenhackarabic;0667 +sevenhangzhou;3027 +sevenideographicparen;3226 +seveninferior;2087 +sevenmonospace;FF17 +sevenoldstyle;F737 +sevenparen;247A +sevenperiod;248E +sevenpersian;06F7 +sevenroman;2176 +sevensuperior;2077 +seventeencircle;2470 +seventeenparen;2484 +seventeenperiod;2498 +seventhai;0E57 +sfthyphen;00AD +shaarmenian;0577 +shabengali;09B6 +shacyrillic;0448 +shaddaarabic;0651 +shaddadammaarabic;FC61 +shaddadammatanarabic;FC5E +shaddafathaarabic;FC60 +shaddafathatanarabic;0651 064B +shaddakasraarabic;FC62 +shaddakasratanarabic;FC5F +shade;2592 +shadedark;2593 +shadelight;2591 +shademedium;2592 +shadeva;0936 +shagujarati;0AB6 +shagurmukhi;0A36 +shalshelethebrew;0593 +shbopomofo;3115 +shchacyrillic;0449 +sheenarabic;0634 +sheenfinalarabic;FEB6 +sheeninitialarabic;FEB7 +sheenmedialarabic;FEB8 +sheicoptic;03E3 +sheqel;20AA +sheqelhebrew;20AA +sheva;05B0 +sheva115;05B0 +sheva15;05B0 +sheva22;05B0 +sheva2e;05B0 +shevahebrew;05B0 +shevanarrowhebrew;05B0 +shevaquarterhebrew;05B0 +shevawidehebrew;05B0 +shhacyrillic;04BB +shimacoptic;03ED +shin;05E9 +shindagesh;FB49 +shindageshhebrew;FB49 +shindageshshindot;FB2C +shindageshshindothebrew;FB2C +shindageshsindot;FB2D +shindageshsindothebrew;FB2D +shindothebrew;05C1 +shinhebrew;05E9 +shinshindot;FB2A +shinshindothebrew;FB2A +shinsindot;FB2B +shinsindothebrew;FB2B +shook;0282 +sigma;03C3 +sigma1;03C2 +sigmafinal;03C2 +sigmalunatesymbolgreek;03F2 +sihiragana;3057 +sikatakana;30B7 +sikatakanahalfwidth;FF7C +siluqhebrew;05BD +siluqlefthebrew;05BD +similar;223C +sindothebrew;05C2 +siosacirclekorean;3274 +siosaparenkorean;3214 +sioscieuckorean;317E +sioscirclekorean;3266 +sioskiyeokkorean;317A +sioskorean;3145 +siosnieunkorean;317B +siosparenkorean;3206 +siospieupkorean;317D +siostikeutkorean;317C +six;0036 +sixarabic;0666 +sixbengali;09EC +sixcircle;2465 +sixcircleinversesansserif;278F +sixdeva;096C +sixgujarati;0AEC +sixgurmukhi;0A6C +sixhackarabic;0666 +sixhangzhou;3026 +sixideographicparen;3225 +sixinferior;2086 +sixmonospace;FF16 +sixoldstyle;F736 +sixparen;2479 +sixperiod;248D +sixpersian;06F6 +sixroman;2175 +sixsuperior;2076 +sixteencircle;246F +sixteencurrencydenominatorbengali;09F9 +sixteenparen;2483 +sixteenperiod;2497 +sixthai;0E56 +slash;002F +slashmonospace;FF0F +slong;017F +slongdotaccent;1E9B +smileface;263A +smonospace;FF53 +sofpasuqhebrew;05C3 +softhyphen;00AD +softsigncyrillic;044C +sohiragana;305D +sokatakana;30BD +sokatakanahalfwidth;FF7F +soliduslongoverlaycmb;0338 +solidusshortoverlaycmb;0337 +sorusithai;0E29 +sosalathai;0E28 +sosothai;0E0B +sosuathai;0E2A +space;0020 +spacehackarabic;0020 +spade;2660 +spadesuitblack;2660 +spadesuitwhite;2664 +sparen;24AE +squarebelowcmb;033B +squarecc;33C4 +squarecm;339D +squarediagonalcrosshatchfill;25A9 +squarehorizontalfill;25A4 +squarekg;338F +squarekm;339E +squarekmcapital;33CE +squareln;33D1 +squarelog;33D2 +squaremg;338E +squaremil;33D5 +squaremm;339C +squaremsquared;33A1 +squareorthogonalcrosshatchfill;25A6 +squareupperlefttolowerrightfill;25A7 +squareupperrighttolowerleftfill;25A8 +squareverticalfill;25A5 +squarewhitewithsmallblack;25A3 +srsquare;33DB +ssabengali;09B7 +ssadeva;0937 +ssagujarati;0AB7 +ssangcieuckorean;3149 +ssanghieuhkorean;3185 +ssangieungkorean;3180 +ssangkiyeokkorean;3132 +ssangnieunkorean;3165 +ssangpieupkorean;3143 +ssangsioskorean;3146 +ssangtikeutkorean;3138 +ssuperior;F6F2 +sterling;00A3 +sterlingmonospace;FFE1 +strokelongoverlaycmb;0336 +strokeshortoverlaycmb;0335 +subset;2282 +subsetnotequal;228A +subsetorequal;2286 +succeeds;227B +suchthat;220B +suhiragana;3059 +sukatakana;30B9 +sukatakanahalfwidth;FF7D +sukunarabic;0652 +summation;2211 +sun;263C +superset;2283 +supersetnotequal;228B +supersetorequal;2287 +svsquare;33DC +syouwaerasquare;337C +t;0074 +tabengali;09A4 +tackdown;22A4 +tackleft;22A3 +tadeva;0924 +tagujarati;0AA4 +tagurmukhi;0A24 +taharabic;0637 +tahfinalarabic;FEC2 +tahinitialarabic;FEC3 +tahiragana;305F +tahmedialarabic;FEC4 +taisyouerasquare;337D +takatakana;30BF +takatakanahalfwidth;FF80 +tatweelarabic;0640 +tau;03C4 +tav;05EA +tavdages;FB4A +tavdagesh;FB4A +tavdageshhebrew;FB4A +tavhebrew;05EA +tbar;0167 +tbopomofo;310A +tcaron;0165 +tccurl;02A8 +tcedilla;0163 +tcheharabic;0686 +tchehfinalarabic;FB7B +tchehinitialarabic;FB7C +tchehmedialarabic;FB7D +tchehmeeminitialarabic;FB7C FEE4 +tcircle;24E3 +tcircumflexbelow;1E71 +tcommaaccent;0163 +tdieresis;1E97 +tdotaccent;1E6B +tdotbelow;1E6D +tecyrillic;0442 +tedescendercyrillic;04AD +teharabic;062A +tehfinalarabic;FE96 +tehhahinitialarabic;FCA2 +tehhahisolatedarabic;FC0C +tehinitialarabic;FE97 +tehiragana;3066 +tehjeeminitialarabic;FCA1 +tehjeemisolatedarabic;FC0B +tehmarbutaarabic;0629 +tehmarbutafinalarabic;FE94 +tehmedialarabic;FE98 +tehmeeminitialarabic;FCA4 +tehmeemisolatedarabic;FC0E +tehnoonfinalarabic;FC73 +tekatakana;30C6 +tekatakanahalfwidth;FF83 +telephone;2121 +telephoneblack;260E +telishagedolahebrew;05A0 +telishaqetanahebrew;05A9 +tencircle;2469 +tenideographicparen;3229 +tenparen;247D +tenperiod;2491 +tenroman;2179 +tesh;02A7 +tet;05D8 +tetdagesh;FB38 +tetdageshhebrew;FB38 +tethebrew;05D8 +tetsecyrillic;04B5 +tevirhebrew;059B +tevirlefthebrew;059B +thabengali;09A5 +thadeva;0925 +thagujarati;0AA5 +thagurmukhi;0A25 +thalarabic;0630 +thalfinalarabic;FEAC +thanthakhatlowleftthai;F898 +thanthakhatlowrightthai;F897 +thanthakhatthai;0E4C +thanthakhatupperleftthai;F896 +theharabic;062B +thehfinalarabic;FE9A +thehinitialarabic;FE9B +thehmedialarabic;FE9C +thereexists;2203 +therefore;2234 +theta;03B8 +theta1;03D1 +thetasymbolgreek;03D1 +thieuthacirclekorean;3279 +thieuthaparenkorean;3219 +thieuthcirclekorean;326B +thieuthkorean;314C +thieuthparenkorean;320B +thirteencircle;246C +thirteenparen;2480 +thirteenperiod;2494 +thonangmonthothai;0E11 +thook;01AD +thophuthaothai;0E12 +thorn;00FE +thothahanthai;0E17 +thothanthai;0E10 +thothongthai;0E18 +thothungthai;0E16 +thousandcyrillic;0482 +thousandsseparatorarabic;066C +thousandsseparatorpersian;066C +three;0033 +threearabic;0663 +threebengali;09E9 +threecircle;2462 +threecircleinversesansserif;278C +threedeva;0969 +threeeighths;215C +threegujarati;0AE9 +threegurmukhi;0A69 +threehackarabic;0663 +threehangzhou;3023 +threeideographicparen;3222 +threeinferior;2083 +threemonospace;FF13 +threenumeratorbengali;09F6 +threeoldstyle;F733 +threeparen;2476 +threeperiod;248A +threepersian;06F3 +threequarters;00BE +threequartersemdash;F6DE +threeroman;2172 +threesuperior;00B3 +threethai;0E53 +thzsquare;3394 +tihiragana;3061 +tikatakana;30C1 +tikatakanahalfwidth;FF81 +tikeutacirclekorean;3270 +tikeutaparenkorean;3210 +tikeutcirclekorean;3262 +tikeutkorean;3137 +tikeutparenkorean;3202 +tilde;02DC +tildebelowcmb;0330 +tildecmb;0303 +tildecomb;0303 +tildedoublecmb;0360 +tildeoperator;223C +tildeoverlaycmb;0334 +tildeverticalcmb;033E +timescircle;2297 +tipehahebrew;0596 +tipehalefthebrew;0596 +tippigurmukhi;0A70 +titlocyrilliccmb;0483 +tiwnarmenian;057F +tlinebelow;1E6F +tmonospace;FF54 +toarmenian;0569 +tohiragana;3068 +tokatakana;30C8 +tokatakanahalfwidth;FF84 +tonebarextrahighmod;02E5 +tonebarextralowmod;02E9 +tonebarhighmod;02E6 +tonebarlowmod;02E8 +tonebarmidmod;02E7 +tonefive;01BD +tonesix;0185 +tonetwo;01A8 +tonos;0384 +tonsquare;3327 +topatakthai;0E0F +tortoiseshellbracketleft;3014 +tortoiseshellbracketleftsmall;FE5D +tortoiseshellbracketleftvertical;FE39 +tortoiseshellbracketright;3015 +tortoiseshellbracketrightsmall;FE5E +tortoiseshellbracketrightvertical;FE3A +totaothai;0E15 +tpalatalhook;01AB +tparen;24AF +trademark;2122 +trademarksans;F8EA +trademarkserif;F6DB +tretroflexhook;0288 +triagdn;25BC +triaglf;25C4 +triagrt;25BA +triagup;25B2 +ts;02A6 +tsadi;05E6 +tsadidagesh;FB46 +tsadidageshhebrew;FB46 +tsadihebrew;05E6 +tsecyrillic;0446 +tsere;05B5 +tsere12;05B5 +tsere1e;05B5 +tsere2b;05B5 +tserehebrew;05B5 +tserenarrowhebrew;05B5 +tserequarterhebrew;05B5 +tserewidehebrew;05B5 +tshecyrillic;045B +tsuperior;F6F3 +ttabengali;099F +ttadeva;091F +ttagujarati;0A9F +ttagurmukhi;0A1F +tteharabic;0679 +ttehfinalarabic;FB67 +ttehinitialarabic;FB68 +ttehmedialarabic;FB69 +tthabengali;09A0 +tthadeva;0920 +tthagujarati;0AA0 +tthagurmukhi;0A20 +tturned;0287 +tuhiragana;3064 +tukatakana;30C4 +tukatakanahalfwidth;FF82 +tusmallhiragana;3063 +tusmallkatakana;30C3 +tusmallkatakanahalfwidth;FF6F +twelvecircle;246B +twelveparen;247F +twelveperiod;2493 +twelveroman;217B +twentycircle;2473 +twentyhangzhou;5344 +twentyparen;2487 +twentyperiod;249B +two;0032 +twoarabic;0662 +twobengali;09E8 +twocircle;2461 +twocircleinversesansserif;278B +twodeva;0968 +twodotenleader;2025 +twodotleader;2025 +twodotleadervertical;FE30 +twogujarati;0AE8 +twogurmukhi;0A68 +twohackarabic;0662 +twohangzhou;3022 +twoideographicparen;3221 +twoinferior;2082 +twomonospace;FF12 +twonumeratorbengali;09F5 +twooldstyle;F732 +twoparen;2475 +twoperiod;2489 +twopersian;06F2 +tworoman;2171 +twostroke;01BB +twosuperior;00B2 +twothai;0E52 +twothirds;2154 +u;0075 +uacute;00FA +ubar;0289 +ubengali;0989 +ubopomofo;3128 +ubreve;016D +ucaron;01D4 +ucircle;24E4 +ucircumflex;00FB +ucircumflexbelow;1E77 +ucyrillic;0443 +udattadeva;0951 +udblacute;0171 +udblgrave;0215 +udeva;0909 +udieresis;00FC +udieresisacute;01D8 +udieresisbelow;1E73 +udieresiscaron;01DA +udieresiscyrillic;04F1 +udieresisgrave;01DC +udieresismacron;01D6 +udotbelow;1EE5 +ugrave;00F9 +ugujarati;0A89 +ugurmukhi;0A09 +uhiragana;3046 +uhookabove;1EE7 +uhorn;01B0 +uhornacute;1EE9 +uhorndotbelow;1EF1 +uhorngrave;1EEB +uhornhookabove;1EED +uhorntilde;1EEF +uhungarumlaut;0171 +uhungarumlautcyrillic;04F3 +uinvertedbreve;0217 +ukatakana;30A6 +ukatakanahalfwidth;FF73 +ukcyrillic;0479 +ukorean;315C +umacron;016B +umacroncyrillic;04EF +umacrondieresis;1E7B +umatragurmukhi;0A41 +umonospace;FF55 +underscore;005F +underscoredbl;2017 +underscoremonospace;FF3F +underscorevertical;FE33 +underscorewavy;FE4F +union;222A +universal;2200 +uogonek;0173 +uparen;24B0 +upblock;2580 +upperdothebrew;05C4 +upsilon;03C5 +upsilondieresis;03CB +upsilondieresistonos;03B0 +upsilonlatin;028A +upsilontonos;03CD +uptackbelowcmb;031D +uptackmod;02D4 +uragurmukhi;0A73 +uring;016F +ushortcyrillic;045E +usmallhiragana;3045 +usmallkatakana;30A5 +usmallkatakanahalfwidth;FF69 +ustraightcyrillic;04AF +ustraightstrokecyrillic;04B1 +utilde;0169 +utildeacute;1E79 +utildebelow;1E75 +uubengali;098A +uudeva;090A +uugujarati;0A8A +uugurmukhi;0A0A +uumatragurmukhi;0A42 +uuvowelsignbengali;09C2 +uuvowelsigndeva;0942 +uuvowelsigngujarati;0AC2 +uvowelsignbengali;09C1 +uvowelsigndeva;0941 +uvowelsigngujarati;0AC1 +v;0076 +vadeva;0935 +vagujarati;0AB5 +vagurmukhi;0A35 +vakatakana;30F7 +vav;05D5 +vavdagesh;FB35 +vavdagesh65;FB35 +vavdageshhebrew;FB35 +vavhebrew;05D5 +vavholam;FB4B +vavholamhebrew;FB4B +vavvavhebrew;05F0 +vavyodhebrew;05F1 +vcircle;24E5 +vdotbelow;1E7F +vecyrillic;0432 +veharabic;06A4 +vehfinalarabic;FB6B +vehinitialarabic;FB6C +vehmedialarabic;FB6D +vekatakana;30F9 +venus;2640 +verticalbar;007C +verticallineabovecmb;030D +verticallinebelowcmb;0329 +verticallinelowmod;02CC +verticallinemod;02C8 +vewarmenian;057E +vhook;028B +vikatakana;30F8 +viramabengali;09CD +viramadeva;094D +viramagujarati;0ACD +visargabengali;0983 +visargadeva;0903 +visargagujarati;0A83 +vmonospace;FF56 +voarmenian;0578 +voicediterationhiragana;309E +voicediterationkatakana;30FE +voicedmarkkana;309B +voicedmarkkanahalfwidth;FF9E +vokatakana;30FA +vparen;24B1 +vtilde;1E7D +vturned;028C +vuhiragana;3094 +vukatakana;30F4 +w;0077 +wacute;1E83 +waekorean;3159 +wahiragana;308F +wakatakana;30EF +wakatakanahalfwidth;FF9C +wakorean;3158 +wasmallhiragana;308E +wasmallkatakana;30EE +wattosquare;3357 +wavedash;301C +wavyunderscorevertical;FE34 +wawarabic;0648 +wawfinalarabic;FEEE +wawhamzaabovearabic;0624 +wawhamzaabovefinalarabic;FE86 +wbsquare;33DD +wcircle;24E6 +wcircumflex;0175 +wdieresis;1E85 +wdotaccent;1E87 +wdotbelow;1E89 +wehiragana;3091 +weierstrass;2118 +wekatakana;30F1 +wekorean;315E +weokorean;315D +wgrave;1E81 +whitebullet;25E6 +whitecircle;25CB +whitecircleinverse;25D9 +whitecornerbracketleft;300E +whitecornerbracketleftvertical;FE43 +whitecornerbracketright;300F +whitecornerbracketrightvertical;FE44 +whitediamond;25C7 +whitediamondcontainingblacksmalldiamond;25C8 +whitedownpointingsmalltriangle;25BF +whitedownpointingtriangle;25BD +whiteleftpointingsmalltriangle;25C3 +whiteleftpointingtriangle;25C1 +whitelenticularbracketleft;3016 +whitelenticularbracketright;3017 +whiterightpointingsmalltriangle;25B9 +whiterightpointingtriangle;25B7 +whitesmallsquare;25AB +whitesmilingface;263A +whitesquare;25A1 +whitestar;2606 +whitetelephone;260F +whitetortoiseshellbracketleft;3018 +whitetortoiseshellbracketright;3019 +whiteuppointingsmalltriangle;25B5 +whiteuppointingtriangle;25B3 +wihiragana;3090 +wikatakana;30F0 +wikorean;315F +wmonospace;FF57 +wohiragana;3092 +wokatakana;30F2 +wokatakanahalfwidth;FF66 +won;20A9 +wonmonospace;FFE6 +wowaenthai;0E27 +wparen;24B2 +wring;1E98 +wsuperior;02B7 +wturned;028D +wynn;01BF +x;0078 +xabovecmb;033D +xbopomofo;3112 +xcircle;24E7 +xdieresis;1E8D +xdotaccent;1E8B +xeharmenian;056D +xi;03BE +xmonospace;FF58 +xparen;24B3 +xsuperior;02E3 +y;0079 +yaadosquare;334E +yabengali;09AF +yacute;00FD +yadeva;092F +yaekorean;3152 +yagujarati;0AAF +yagurmukhi;0A2F +yahiragana;3084 +yakatakana;30E4 +yakatakanahalfwidth;FF94 +yakorean;3151 +yamakkanthai;0E4E +yasmallhiragana;3083 +yasmallkatakana;30E3 +yasmallkatakanahalfwidth;FF6C +yatcyrillic;0463 +ycircle;24E8 +ycircumflex;0177 +ydieresis;00FF +ydotaccent;1E8F +ydotbelow;1EF5 +yeharabic;064A +yehbarreearabic;06D2 +yehbarreefinalarabic;FBAF +yehfinalarabic;FEF2 +yehhamzaabovearabic;0626 +yehhamzaabovefinalarabic;FE8A +yehhamzaaboveinitialarabic;FE8B +yehhamzaabovemedialarabic;FE8C +yehinitialarabic;FEF3 +yehmedialarabic;FEF4 +yehmeeminitialarabic;FCDD +yehmeemisolatedarabic;FC58 +yehnoonfinalarabic;FC94 +yehthreedotsbelowarabic;06D1 +yekorean;3156 +yen;00A5 +yenmonospace;FFE5 +yeokorean;3155 +yeorinhieuhkorean;3186 +yerahbenyomohebrew;05AA +yerahbenyomolefthebrew;05AA +yericyrillic;044B +yerudieresiscyrillic;04F9 +yesieungkorean;3181 +yesieungpansioskorean;3183 +yesieungsioskorean;3182 +yetivhebrew;059A +ygrave;1EF3 +yhook;01B4 +yhookabove;1EF7 +yiarmenian;0575 +yicyrillic;0457 +yikorean;3162 +yinyang;262F +yiwnarmenian;0582 +ymonospace;FF59 +yod;05D9 +yoddagesh;FB39 +yoddageshhebrew;FB39 +yodhebrew;05D9 +yodyodhebrew;05F2 +yodyodpatahhebrew;FB1F +yohiragana;3088 +yoikorean;3189 +yokatakana;30E8 +yokatakanahalfwidth;FF96 +yokorean;315B +yosmallhiragana;3087 +yosmallkatakana;30E7 +yosmallkatakanahalfwidth;FF6E +yotgreek;03F3 +yoyaekorean;3188 +yoyakorean;3187 +yoyakthai;0E22 +yoyingthai;0E0D +yparen;24B4 +ypogegrammeni;037A +ypogegrammenigreekcmb;0345 +yr;01A6 +yring;1E99 +ysuperior;02B8 +ytilde;1EF9 +yturned;028E +yuhiragana;3086 +yuikorean;318C +yukatakana;30E6 +yukatakanahalfwidth;FF95 +yukorean;3160 +yusbigcyrillic;046B +yusbigiotifiedcyrillic;046D +yuslittlecyrillic;0467 +yuslittleiotifiedcyrillic;0469 +yusmallhiragana;3085 +yusmallkatakana;30E5 +yusmallkatakanahalfwidth;FF6D +yuyekorean;318B +yuyeokorean;318A +yyabengali;09DF +yyadeva;095F +z;007A +zaarmenian;0566 +zacute;017A +zadeva;095B +zagurmukhi;0A5B +zaharabic;0638 +zahfinalarabic;FEC6 +zahinitialarabic;FEC7 +zahiragana;3056 +zahmedialarabic;FEC8 +zainarabic;0632 +zainfinalarabic;FEB0 +zakatakana;30B6 +zaqefgadolhebrew;0595 +zaqefqatanhebrew;0594 +zarqahebrew;0598 +zayin;05D6 +zayindagesh;FB36 +zayindageshhebrew;FB36 +zayinhebrew;05D6 +zbopomofo;3117 +zcaron;017E +zcircle;24E9 +zcircumflex;1E91 +zcurl;0291 +zdot;017C +zdotaccent;017C +zdotbelow;1E93 +zecyrillic;0437 +zedescendercyrillic;0499 +zedieresiscyrillic;04DF +zehiragana;305C +zekatakana;30BC +zero;0030 +zeroarabic;0660 +zerobengali;09E6 +zerodeva;0966 +zerogujarati;0AE6 +zerogurmukhi;0A66 +zerohackarabic;0660 +zeroinferior;2080 +zeromonospace;FF10 +zerooldstyle;F730 +zeropersian;06F0 +zerosuperior;2070 +zerothai;0E50 +zerowidthjoiner;FEFF +zerowidthnonjoiner;200C +zerowidthspace;200B +zeta;03B6 +zhbopomofo;3113 +zhearmenian;056A +zhebrevecyrillic;04C2 +zhecyrillic;0436 +zhedescendercyrillic;0497 +zhedieresiscyrillic;04DD +zihiragana;3058 +zikatakana;30B8 +zinorhebrew;05AE +zlinebelow;1E95 +zmonospace;FF5A +zohiragana;305E +zokatakana;30BE +zparen;24B5 +zretroflexhook;0290 +zstroke;01B6 +zuhiragana;305A +zukatakana;30BA +# END +""" + + +_aglfnText = """\ +# ----------------------------------------------------------- +# Copyright 2002-2019 Adobe (http://www.adobe.com/). +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the +# following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# Neither the name of Adobe nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------- +# Name: Adobe Glyph List For New Fonts +# Table version: 1.7 +# Date: November 6, 2008 +# URL: https://github.com/adobe-type-tools/agl-aglfn +# +# Description: +# +# AGLFN (Adobe Glyph List For New Fonts) provides a list of base glyph +# names that are recommended for new fonts, which are compatible with +# the AGL (Adobe Glyph List) Specification, and which should be used +# as described in Section 6 of that document. AGLFN comprises the set +# of glyph names from AGL that map via the AGL Specification rules to +# the semantically correct UV (Unicode Value). For example, "Asmall" +# is omitted because AGL maps this glyph name to the PUA (Private Use +# Area) value U+F761, rather than to the UV that maps from the glyph +# name "A." Also omitted is "ffi," because AGL maps this to the +# Alphabetic Presentation Forms value U+FB03, rather than decomposing +# it into the following sequence of three UVs: U+0066, U+0066, and +# U+0069. The name "arrowvertex" has been omitted because this glyph +# now has a real UV, and AGL is now incorrect in mapping it to the PUA +# value U+F8E6. If you do not find an appropriate name for your glyph +# in this list, then please refer to Section 6 of the AGL +# Specification. +# +# Format: three semicolon-delimited fields: +# (1) Standard UV or CUS UV--four uppercase hexadecimal digits +# (2) Glyph name--upper/lowercase letters and digits +# (3) Character names: Unicode character names for standard UVs, and +# descriptive names for CUS UVs--uppercase letters, hyphen, and +# space +# +# The records are sorted by glyph name in increasing ASCII order, +# entries with the same glyph name are sorted in decreasing priority +# order, the UVs and Unicode character names are provided for +# convenience, lines starting with "#" are comments, and blank lines +# should be ignored. +# +# Revision History: +# +# 1.7 [6 November 2008] +# - Reverted to the original 1.4 and earlier mappings for Delta, +# Omega, and mu. +# - Removed mappings for "afii" names. These should now be assigned +# "uni" names. +# - Removed mappings for "commaaccent" names. These should now be +# assigned "uni" names. +# +# 1.6 [30 January 2006] +# - Completed work intended in 1.5. +# +# 1.5 [23 November 2005] +# - Removed duplicated block at end of file. +# - Changed mappings: +# 2206;Delta;INCREMENT changed to 0394;Delta;GREEK CAPITAL LETTER DELTA +# 2126;Omega;OHM SIGN changed to 03A9;Omega;GREEK CAPITAL LETTER OMEGA +# 03BC;mu;MICRO SIGN changed to 03BC;mu;GREEK SMALL LETTER MU +# - Corrected statement above about why "ffi" is omitted. +# +# 1.4 [24 September 2003] +# - Changed version to 1.4, to avoid confusion with the AGL 1.3. +# - Fixed spelling errors in the header. +# - Fully removed "arrowvertex," as it is mapped only to a PUA Unicode +# value in some fonts. +# +# 1.1 [17 April 2003] +# - Renamed [Tt]cedilla back to [Tt]commaaccent. +# +# 1.0 [31 January 2003] +# - Original version. +# - Derived from the AGLv1.2 by: +# removing the PUA area codes; +# removing duplicate Unicode mappings; and +# renaming "tcommaaccent" to "tcedilla" and "Tcommaaccent" to "Tcedilla" +# +0041;A;LATIN CAPITAL LETTER A +00C6;AE;LATIN CAPITAL LETTER AE +01FC;AEacute;LATIN CAPITAL LETTER AE WITH ACUTE +00C1;Aacute;LATIN CAPITAL LETTER A WITH ACUTE +0102;Abreve;LATIN CAPITAL LETTER A WITH BREVE +00C2;Acircumflex;LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C4;Adieresis;LATIN CAPITAL LETTER A WITH DIAERESIS +00C0;Agrave;LATIN CAPITAL LETTER A WITH GRAVE +0391;Alpha;GREEK CAPITAL LETTER ALPHA +0386;Alphatonos;GREEK CAPITAL LETTER ALPHA WITH TONOS +0100;Amacron;LATIN CAPITAL LETTER A WITH MACRON +0104;Aogonek;LATIN CAPITAL LETTER A WITH OGONEK +00C5;Aring;LATIN CAPITAL LETTER A WITH RING ABOVE +01FA;Aringacute;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +00C3;Atilde;LATIN CAPITAL LETTER A WITH TILDE +0042;B;LATIN CAPITAL LETTER B +0392;Beta;GREEK CAPITAL LETTER BETA +0043;C;LATIN CAPITAL LETTER C +0106;Cacute;LATIN CAPITAL LETTER C WITH ACUTE +010C;Ccaron;LATIN CAPITAL LETTER C WITH CARON +00C7;Ccedilla;LATIN CAPITAL LETTER C WITH CEDILLA +0108;Ccircumflex;LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A;Cdotaccent;LATIN CAPITAL LETTER C WITH DOT ABOVE +03A7;Chi;GREEK CAPITAL LETTER CHI +0044;D;LATIN CAPITAL LETTER D +010E;Dcaron;LATIN CAPITAL LETTER D WITH CARON +0110;Dcroat;LATIN CAPITAL LETTER D WITH STROKE +2206;Delta;INCREMENT +0045;E;LATIN CAPITAL LETTER E +00C9;Eacute;LATIN CAPITAL LETTER E WITH ACUTE +0114;Ebreve;LATIN CAPITAL LETTER E WITH BREVE +011A;Ecaron;LATIN CAPITAL LETTER E WITH CARON +00CA;Ecircumflex;LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB;Edieresis;LATIN CAPITAL LETTER E WITH DIAERESIS +0116;Edotaccent;LATIN CAPITAL LETTER E WITH DOT ABOVE +00C8;Egrave;LATIN CAPITAL LETTER E WITH GRAVE +0112;Emacron;LATIN CAPITAL LETTER E WITH MACRON +014A;Eng;LATIN CAPITAL LETTER ENG +0118;Eogonek;LATIN CAPITAL LETTER E WITH OGONEK +0395;Epsilon;GREEK CAPITAL LETTER EPSILON +0388;Epsilontonos;GREEK CAPITAL LETTER EPSILON WITH TONOS +0397;Eta;GREEK CAPITAL LETTER ETA +0389;Etatonos;GREEK CAPITAL LETTER ETA WITH TONOS +00D0;Eth;LATIN CAPITAL LETTER ETH +20AC;Euro;EURO SIGN +0046;F;LATIN CAPITAL LETTER F +0047;G;LATIN CAPITAL LETTER G +0393;Gamma;GREEK CAPITAL LETTER GAMMA +011E;Gbreve;LATIN CAPITAL LETTER G WITH BREVE +01E6;Gcaron;LATIN CAPITAL LETTER G WITH CARON +011C;Gcircumflex;LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0120;Gdotaccent;LATIN CAPITAL LETTER G WITH DOT ABOVE +0048;H;LATIN CAPITAL LETTER H +25CF;H18533;BLACK CIRCLE +25AA;H18543;BLACK SMALL SQUARE +25AB;H18551;WHITE SMALL SQUARE +25A1;H22073;WHITE SQUARE +0126;Hbar;LATIN CAPITAL LETTER H WITH STROKE +0124;Hcircumflex;LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0049;I;LATIN CAPITAL LETTER I +0132;IJ;LATIN CAPITAL LIGATURE IJ +00CD;Iacute;LATIN CAPITAL LETTER I WITH ACUTE +012C;Ibreve;LATIN CAPITAL LETTER I WITH BREVE +00CE;Icircumflex;LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF;Idieresis;LATIN CAPITAL LETTER I WITH DIAERESIS +0130;Idotaccent;LATIN CAPITAL LETTER I WITH DOT ABOVE +2111;Ifraktur;BLACK-LETTER CAPITAL I +00CC;Igrave;LATIN CAPITAL LETTER I WITH GRAVE +012A;Imacron;LATIN CAPITAL LETTER I WITH MACRON +012E;Iogonek;LATIN CAPITAL LETTER I WITH OGONEK +0399;Iota;GREEK CAPITAL LETTER IOTA +03AA;Iotadieresis;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +038A;Iotatonos;GREEK CAPITAL LETTER IOTA WITH TONOS +0128;Itilde;LATIN CAPITAL LETTER I WITH TILDE +004A;J;LATIN CAPITAL LETTER J +0134;Jcircumflex;LATIN CAPITAL LETTER J WITH CIRCUMFLEX +004B;K;LATIN CAPITAL LETTER K +039A;Kappa;GREEK CAPITAL LETTER KAPPA +004C;L;LATIN CAPITAL LETTER L +0139;Lacute;LATIN CAPITAL LETTER L WITH ACUTE +039B;Lambda;GREEK CAPITAL LETTER LAMDA +013D;Lcaron;LATIN CAPITAL LETTER L WITH CARON +013F;Ldot;LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141;Lslash;LATIN CAPITAL LETTER L WITH STROKE +004D;M;LATIN CAPITAL LETTER M +039C;Mu;GREEK CAPITAL LETTER MU +004E;N;LATIN CAPITAL LETTER N +0143;Nacute;LATIN CAPITAL LETTER N WITH ACUTE +0147;Ncaron;LATIN CAPITAL LETTER N WITH CARON +00D1;Ntilde;LATIN CAPITAL LETTER N WITH TILDE +039D;Nu;GREEK CAPITAL LETTER NU +004F;O;LATIN CAPITAL LETTER O +0152;OE;LATIN CAPITAL LIGATURE OE +00D3;Oacute;LATIN CAPITAL LETTER O WITH ACUTE +014E;Obreve;LATIN CAPITAL LETTER O WITH BREVE +00D4;Ocircumflex;LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D6;Odieresis;LATIN CAPITAL LETTER O WITH DIAERESIS +00D2;Ograve;LATIN CAPITAL LETTER O WITH GRAVE +01A0;Ohorn;LATIN CAPITAL LETTER O WITH HORN +0150;Ohungarumlaut;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +014C;Omacron;LATIN CAPITAL LETTER O WITH MACRON +2126;Omega;OHM SIGN +038F;Omegatonos;GREEK CAPITAL LETTER OMEGA WITH TONOS +039F;Omicron;GREEK CAPITAL LETTER OMICRON +038C;Omicrontonos;GREEK CAPITAL LETTER OMICRON WITH TONOS +00D8;Oslash;LATIN CAPITAL LETTER O WITH STROKE +01FE;Oslashacute;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +00D5;Otilde;LATIN CAPITAL LETTER O WITH TILDE +0050;P;LATIN CAPITAL LETTER P +03A6;Phi;GREEK CAPITAL LETTER PHI +03A0;Pi;GREEK CAPITAL LETTER PI +03A8;Psi;GREEK CAPITAL LETTER PSI +0051;Q;LATIN CAPITAL LETTER Q +0052;R;LATIN CAPITAL LETTER R +0154;Racute;LATIN CAPITAL LETTER R WITH ACUTE +0158;Rcaron;LATIN CAPITAL LETTER R WITH CARON +211C;Rfraktur;BLACK-LETTER CAPITAL R +03A1;Rho;GREEK CAPITAL LETTER RHO +0053;S;LATIN CAPITAL LETTER S +250C;SF010000;BOX DRAWINGS LIGHT DOWN AND RIGHT +2514;SF020000;BOX DRAWINGS LIGHT UP AND RIGHT +2510;SF030000;BOX DRAWINGS LIGHT DOWN AND LEFT +2518;SF040000;BOX DRAWINGS LIGHT UP AND LEFT +253C;SF050000;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +252C;SF060000;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +2534;SF070000;BOX DRAWINGS LIGHT UP AND HORIZONTAL +251C;SF080000;BOX DRAWINGS LIGHT VERTICAL AND RIGHT +2524;SF090000;BOX DRAWINGS LIGHT VERTICAL AND LEFT +2500;SF100000;BOX DRAWINGS LIGHT HORIZONTAL +2502;SF110000;BOX DRAWINGS LIGHT VERTICAL +2561;SF190000;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +2562;SF200000;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +2556;SF210000;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +2555;SF220000;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +2563;SF230000;BOX DRAWINGS DOUBLE VERTICAL AND LEFT +2551;SF240000;BOX DRAWINGS DOUBLE VERTICAL +2557;SF250000;BOX DRAWINGS DOUBLE DOWN AND LEFT +255D;SF260000;BOX DRAWINGS DOUBLE UP AND LEFT +255C;SF270000;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +255B;SF280000;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +255E;SF360000;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +255F;SF370000;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +255A;SF380000;BOX DRAWINGS DOUBLE UP AND RIGHT +2554;SF390000;BOX DRAWINGS DOUBLE DOWN AND RIGHT +2569;SF400000;BOX DRAWINGS DOUBLE UP AND HORIZONTAL +2566;SF410000;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +2560;SF420000;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +2550;SF430000;BOX DRAWINGS DOUBLE HORIZONTAL +256C;SF440000;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +2567;SF450000;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +2568;SF460000;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +2564;SF470000;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +2565;SF480000;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +2559;SF490000;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +2558;SF500000;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +2552;SF510000;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +2553;SF520000;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +256B;SF530000;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +256A;SF540000;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +015A;Sacute;LATIN CAPITAL LETTER S WITH ACUTE +0160;Scaron;LATIN CAPITAL LETTER S WITH CARON +015E;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA +015C;Scircumflex;LATIN CAPITAL LETTER S WITH CIRCUMFLEX +03A3;Sigma;GREEK CAPITAL LETTER SIGMA +0054;T;LATIN CAPITAL LETTER T +03A4;Tau;GREEK CAPITAL LETTER TAU +0166;Tbar;LATIN CAPITAL LETTER T WITH STROKE +0164;Tcaron;LATIN CAPITAL LETTER T WITH CARON +0398;Theta;GREEK CAPITAL LETTER THETA +00DE;Thorn;LATIN CAPITAL LETTER THORN +0055;U;LATIN CAPITAL LETTER U +00DA;Uacute;LATIN CAPITAL LETTER U WITH ACUTE +016C;Ubreve;LATIN CAPITAL LETTER U WITH BREVE +00DB;Ucircumflex;LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC;Udieresis;LATIN CAPITAL LETTER U WITH DIAERESIS +00D9;Ugrave;LATIN CAPITAL LETTER U WITH GRAVE +01AF;Uhorn;LATIN CAPITAL LETTER U WITH HORN +0170;Uhungarumlaut;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +016A;Umacron;LATIN CAPITAL LETTER U WITH MACRON +0172;Uogonek;LATIN CAPITAL LETTER U WITH OGONEK +03A5;Upsilon;GREEK CAPITAL LETTER UPSILON +03D2;Upsilon1;GREEK UPSILON WITH HOOK SYMBOL +03AB;Upsilondieresis;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +038E;Upsilontonos;GREEK CAPITAL LETTER UPSILON WITH TONOS +016E;Uring;LATIN CAPITAL LETTER U WITH RING ABOVE +0168;Utilde;LATIN CAPITAL LETTER U WITH TILDE +0056;V;LATIN CAPITAL LETTER V +0057;W;LATIN CAPITAL LETTER W +1E82;Wacute;LATIN CAPITAL LETTER W WITH ACUTE +0174;Wcircumflex;LATIN CAPITAL LETTER W WITH CIRCUMFLEX +1E84;Wdieresis;LATIN CAPITAL LETTER W WITH DIAERESIS +1E80;Wgrave;LATIN CAPITAL LETTER W WITH GRAVE +0058;X;LATIN CAPITAL LETTER X +039E;Xi;GREEK CAPITAL LETTER XI +0059;Y;LATIN CAPITAL LETTER Y +00DD;Yacute;LATIN CAPITAL LETTER Y WITH ACUTE +0176;Ycircumflex;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178;Ydieresis;LATIN CAPITAL LETTER Y WITH DIAERESIS +1EF2;Ygrave;LATIN CAPITAL LETTER Y WITH GRAVE +005A;Z;LATIN CAPITAL LETTER Z +0179;Zacute;LATIN CAPITAL LETTER Z WITH ACUTE +017D;Zcaron;LATIN CAPITAL LETTER Z WITH CARON +017B;Zdotaccent;LATIN CAPITAL LETTER Z WITH DOT ABOVE +0396;Zeta;GREEK CAPITAL LETTER ZETA +0061;a;LATIN SMALL LETTER A +00E1;aacute;LATIN SMALL LETTER A WITH ACUTE +0103;abreve;LATIN SMALL LETTER A WITH BREVE +00E2;acircumflex;LATIN SMALL LETTER A WITH CIRCUMFLEX +00B4;acute;ACUTE ACCENT +0301;acutecomb;COMBINING ACUTE ACCENT +00E4;adieresis;LATIN SMALL LETTER A WITH DIAERESIS +00E6;ae;LATIN SMALL LETTER AE +01FD;aeacute;LATIN SMALL LETTER AE WITH ACUTE +00E0;agrave;LATIN SMALL LETTER A WITH GRAVE +2135;aleph;ALEF SYMBOL +03B1;alpha;GREEK SMALL LETTER ALPHA +03AC;alphatonos;GREEK SMALL LETTER ALPHA WITH TONOS +0101;amacron;LATIN SMALL LETTER A WITH MACRON +0026;ampersand;AMPERSAND +2220;angle;ANGLE +2329;angleleft;LEFT-POINTING ANGLE BRACKET +232A;angleright;RIGHT-POINTING ANGLE BRACKET +0387;anoteleia;GREEK ANO TELEIA +0105;aogonek;LATIN SMALL LETTER A WITH OGONEK +2248;approxequal;ALMOST EQUAL TO +00E5;aring;LATIN SMALL LETTER A WITH RING ABOVE +01FB;aringacute;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +2194;arrowboth;LEFT RIGHT ARROW +21D4;arrowdblboth;LEFT RIGHT DOUBLE ARROW +21D3;arrowdbldown;DOWNWARDS DOUBLE ARROW +21D0;arrowdblleft;LEFTWARDS DOUBLE ARROW +21D2;arrowdblright;RIGHTWARDS DOUBLE ARROW +21D1;arrowdblup;UPWARDS DOUBLE ARROW +2193;arrowdown;DOWNWARDS ARROW +2190;arrowleft;LEFTWARDS ARROW +2192;arrowright;RIGHTWARDS ARROW +2191;arrowup;UPWARDS ARROW +2195;arrowupdn;UP DOWN ARROW +21A8;arrowupdnbse;UP DOWN ARROW WITH BASE +005E;asciicircum;CIRCUMFLEX ACCENT +007E;asciitilde;TILDE +002A;asterisk;ASTERISK +2217;asteriskmath;ASTERISK OPERATOR +0040;at;COMMERCIAL AT +00E3;atilde;LATIN SMALL LETTER A WITH TILDE +0062;b;LATIN SMALL LETTER B +005C;backslash;REVERSE SOLIDUS +007C;bar;VERTICAL LINE +03B2;beta;GREEK SMALL LETTER BETA +2588;block;FULL BLOCK +007B;braceleft;LEFT CURLY BRACKET +007D;braceright;RIGHT CURLY BRACKET +005B;bracketleft;LEFT SQUARE BRACKET +005D;bracketright;RIGHT SQUARE BRACKET +02D8;breve;BREVE +00A6;brokenbar;BROKEN BAR +2022;bullet;BULLET +0063;c;LATIN SMALL LETTER C +0107;cacute;LATIN SMALL LETTER C WITH ACUTE +02C7;caron;CARON +21B5;carriagereturn;DOWNWARDS ARROW WITH CORNER LEFTWARDS +010D;ccaron;LATIN SMALL LETTER C WITH CARON +00E7;ccedilla;LATIN SMALL LETTER C WITH CEDILLA +0109;ccircumflex;LATIN SMALL LETTER C WITH CIRCUMFLEX +010B;cdotaccent;LATIN SMALL LETTER C WITH DOT ABOVE +00B8;cedilla;CEDILLA +00A2;cent;CENT SIGN +03C7;chi;GREEK SMALL LETTER CHI +25CB;circle;WHITE CIRCLE +2297;circlemultiply;CIRCLED TIMES +2295;circleplus;CIRCLED PLUS +02C6;circumflex;MODIFIER LETTER CIRCUMFLEX ACCENT +2663;club;BLACK CLUB SUIT +003A;colon;COLON +20A1;colonmonetary;COLON SIGN +002C;comma;COMMA +2245;congruent;APPROXIMATELY EQUAL TO +00A9;copyright;COPYRIGHT SIGN +00A4;currency;CURRENCY SIGN +0064;d;LATIN SMALL LETTER D +2020;dagger;DAGGER +2021;daggerdbl;DOUBLE DAGGER +010F;dcaron;LATIN SMALL LETTER D WITH CARON +0111;dcroat;LATIN SMALL LETTER D WITH STROKE +00B0;degree;DEGREE SIGN +03B4;delta;GREEK SMALL LETTER DELTA +2666;diamond;BLACK DIAMOND SUIT +00A8;dieresis;DIAERESIS +0385;dieresistonos;GREEK DIALYTIKA TONOS +00F7;divide;DIVISION SIGN +2593;dkshade;DARK SHADE +2584;dnblock;LOWER HALF BLOCK +0024;dollar;DOLLAR SIGN +20AB;dong;DONG SIGN +02D9;dotaccent;DOT ABOVE +0323;dotbelowcomb;COMBINING DOT BELOW +0131;dotlessi;LATIN SMALL LETTER DOTLESS I +22C5;dotmath;DOT OPERATOR +0065;e;LATIN SMALL LETTER E +00E9;eacute;LATIN SMALL LETTER E WITH ACUTE +0115;ebreve;LATIN SMALL LETTER E WITH BREVE +011B;ecaron;LATIN SMALL LETTER E WITH CARON +00EA;ecircumflex;LATIN SMALL LETTER E WITH CIRCUMFLEX +00EB;edieresis;LATIN SMALL LETTER E WITH DIAERESIS +0117;edotaccent;LATIN SMALL LETTER E WITH DOT ABOVE +00E8;egrave;LATIN SMALL LETTER E WITH GRAVE +0038;eight;DIGIT EIGHT +2208;element;ELEMENT OF +2026;ellipsis;HORIZONTAL ELLIPSIS +0113;emacron;LATIN SMALL LETTER E WITH MACRON +2014;emdash;EM DASH +2205;emptyset;EMPTY SET +2013;endash;EN DASH +014B;eng;LATIN SMALL LETTER ENG +0119;eogonek;LATIN SMALL LETTER E WITH OGONEK +03B5;epsilon;GREEK SMALL LETTER EPSILON +03AD;epsilontonos;GREEK SMALL LETTER EPSILON WITH TONOS +003D;equal;EQUALS SIGN +2261;equivalence;IDENTICAL TO +212E;estimated;ESTIMATED SYMBOL +03B7;eta;GREEK SMALL LETTER ETA +03AE;etatonos;GREEK SMALL LETTER ETA WITH TONOS +00F0;eth;LATIN SMALL LETTER ETH +0021;exclam;EXCLAMATION MARK +203C;exclamdbl;DOUBLE EXCLAMATION MARK +00A1;exclamdown;INVERTED EXCLAMATION MARK +2203;existential;THERE EXISTS +0066;f;LATIN SMALL LETTER F +2640;female;FEMALE SIGN +2012;figuredash;FIGURE DASH +25A0;filledbox;BLACK SQUARE +25AC;filledrect;BLACK RECTANGLE +0035;five;DIGIT FIVE +215D;fiveeighths;VULGAR FRACTION FIVE EIGHTHS +0192;florin;LATIN SMALL LETTER F WITH HOOK +0034;four;DIGIT FOUR +2044;fraction;FRACTION SLASH +20A3;franc;FRENCH FRANC SIGN +0067;g;LATIN SMALL LETTER G +03B3;gamma;GREEK SMALL LETTER GAMMA +011F;gbreve;LATIN SMALL LETTER G WITH BREVE +01E7;gcaron;LATIN SMALL LETTER G WITH CARON +011D;gcircumflex;LATIN SMALL LETTER G WITH CIRCUMFLEX +0121;gdotaccent;LATIN SMALL LETTER G WITH DOT ABOVE +00DF;germandbls;LATIN SMALL LETTER SHARP S +2207;gradient;NABLA +0060;grave;GRAVE ACCENT +0300;gravecomb;COMBINING GRAVE ACCENT +003E;greater;GREATER-THAN SIGN +2265;greaterequal;GREATER-THAN OR EQUAL TO +00AB;guillemotleft;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00BB;guillemotright;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +2039;guilsinglleft;SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A;guilsinglright;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0068;h;LATIN SMALL LETTER H +0127;hbar;LATIN SMALL LETTER H WITH STROKE +0125;hcircumflex;LATIN SMALL LETTER H WITH CIRCUMFLEX +2665;heart;BLACK HEART SUIT +0309;hookabovecomb;COMBINING HOOK ABOVE +2302;house;HOUSE +02DD;hungarumlaut;DOUBLE ACUTE ACCENT +002D;hyphen;HYPHEN-MINUS +0069;i;LATIN SMALL LETTER I +00ED;iacute;LATIN SMALL LETTER I WITH ACUTE +012D;ibreve;LATIN SMALL LETTER I WITH BREVE +00EE;icircumflex;LATIN SMALL LETTER I WITH CIRCUMFLEX +00EF;idieresis;LATIN SMALL LETTER I WITH DIAERESIS +00EC;igrave;LATIN SMALL LETTER I WITH GRAVE +0133;ij;LATIN SMALL LIGATURE IJ +012B;imacron;LATIN SMALL LETTER I WITH MACRON +221E;infinity;INFINITY +222B;integral;INTEGRAL +2321;integralbt;BOTTOM HALF INTEGRAL +2320;integraltp;TOP HALF INTEGRAL +2229;intersection;INTERSECTION +25D8;invbullet;INVERSE BULLET +25D9;invcircle;INVERSE WHITE CIRCLE +263B;invsmileface;BLACK SMILING FACE +012F;iogonek;LATIN SMALL LETTER I WITH OGONEK +03B9;iota;GREEK SMALL LETTER IOTA +03CA;iotadieresis;GREEK SMALL LETTER IOTA WITH DIALYTIKA +0390;iotadieresistonos;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AF;iotatonos;GREEK SMALL LETTER IOTA WITH TONOS +0129;itilde;LATIN SMALL LETTER I WITH TILDE +006A;j;LATIN SMALL LETTER J +0135;jcircumflex;LATIN SMALL LETTER J WITH CIRCUMFLEX +006B;k;LATIN SMALL LETTER K +03BA;kappa;GREEK SMALL LETTER KAPPA +0138;kgreenlandic;LATIN SMALL LETTER KRA +006C;l;LATIN SMALL LETTER L +013A;lacute;LATIN SMALL LETTER L WITH ACUTE +03BB;lambda;GREEK SMALL LETTER LAMDA +013E;lcaron;LATIN SMALL LETTER L WITH CARON +0140;ldot;LATIN SMALL LETTER L WITH MIDDLE DOT +003C;less;LESS-THAN SIGN +2264;lessequal;LESS-THAN OR EQUAL TO +258C;lfblock;LEFT HALF BLOCK +20A4;lira;LIRA SIGN +2227;logicaland;LOGICAL AND +00AC;logicalnot;NOT SIGN +2228;logicalor;LOGICAL OR +017F;longs;LATIN SMALL LETTER LONG S +25CA;lozenge;LOZENGE +0142;lslash;LATIN SMALL LETTER L WITH STROKE +2591;ltshade;LIGHT SHADE +006D;m;LATIN SMALL LETTER M +00AF;macron;MACRON +2642;male;MALE SIGN +2212;minus;MINUS SIGN +2032;minute;PRIME +00B5;mu;MICRO SIGN +00D7;multiply;MULTIPLICATION SIGN +266A;musicalnote;EIGHTH NOTE +266B;musicalnotedbl;BEAMED EIGHTH NOTES +006E;n;LATIN SMALL LETTER N +0144;nacute;LATIN SMALL LETTER N WITH ACUTE +0149;napostrophe;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +0148;ncaron;LATIN SMALL LETTER N WITH CARON +0039;nine;DIGIT NINE +2209;notelement;NOT AN ELEMENT OF +2260;notequal;NOT EQUAL TO +2284;notsubset;NOT A SUBSET OF +00F1;ntilde;LATIN SMALL LETTER N WITH TILDE +03BD;nu;GREEK SMALL LETTER NU +0023;numbersign;NUMBER SIGN +006F;o;LATIN SMALL LETTER O +00F3;oacute;LATIN SMALL LETTER O WITH ACUTE +014F;obreve;LATIN SMALL LETTER O WITH BREVE +00F4;ocircumflex;LATIN SMALL LETTER O WITH CIRCUMFLEX +00F6;odieresis;LATIN SMALL LETTER O WITH DIAERESIS +0153;oe;LATIN SMALL LIGATURE OE +02DB;ogonek;OGONEK +00F2;ograve;LATIN SMALL LETTER O WITH GRAVE +01A1;ohorn;LATIN SMALL LETTER O WITH HORN +0151;ohungarumlaut;LATIN SMALL LETTER O WITH DOUBLE ACUTE +014D;omacron;LATIN SMALL LETTER O WITH MACRON +03C9;omega;GREEK SMALL LETTER OMEGA +03D6;omega1;GREEK PI SYMBOL +03CE;omegatonos;GREEK SMALL LETTER OMEGA WITH TONOS +03BF;omicron;GREEK SMALL LETTER OMICRON +03CC;omicrontonos;GREEK SMALL LETTER OMICRON WITH TONOS +0031;one;DIGIT ONE +2024;onedotenleader;ONE DOT LEADER +215B;oneeighth;VULGAR FRACTION ONE EIGHTH +00BD;onehalf;VULGAR FRACTION ONE HALF +00BC;onequarter;VULGAR FRACTION ONE QUARTER +2153;onethird;VULGAR FRACTION ONE THIRD +25E6;openbullet;WHITE BULLET +00AA;ordfeminine;FEMININE ORDINAL INDICATOR +00BA;ordmasculine;MASCULINE ORDINAL INDICATOR +221F;orthogonal;RIGHT ANGLE +00F8;oslash;LATIN SMALL LETTER O WITH STROKE +01FF;oslashacute;LATIN SMALL LETTER O WITH STROKE AND ACUTE +00F5;otilde;LATIN SMALL LETTER O WITH TILDE +0070;p;LATIN SMALL LETTER P +00B6;paragraph;PILCROW SIGN +0028;parenleft;LEFT PARENTHESIS +0029;parenright;RIGHT PARENTHESIS +2202;partialdiff;PARTIAL DIFFERENTIAL +0025;percent;PERCENT SIGN +002E;period;FULL STOP +00B7;periodcentered;MIDDLE DOT +22A5;perpendicular;UP TACK +2030;perthousand;PER MILLE SIGN +20A7;peseta;PESETA SIGN +03C6;phi;GREEK SMALL LETTER PHI +03D5;phi1;GREEK PHI SYMBOL +03C0;pi;GREEK SMALL LETTER PI +002B;plus;PLUS SIGN +00B1;plusminus;PLUS-MINUS SIGN +211E;prescription;PRESCRIPTION TAKE +220F;product;N-ARY PRODUCT +2282;propersubset;SUBSET OF +2283;propersuperset;SUPERSET OF +221D;proportional;PROPORTIONAL TO +03C8;psi;GREEK SMALL LETTER PSI +0071;q;LATIN SMALL LETTER Q +003F;question;QUESTION MARK +00BF;questiondown;INVERTED QUESTION MARK +0022;quotedbl;QUOTATION MARK +201E;quotedblbase;DOUBLE LOW-9 QUOTATION MARK +201C;quotedblleft;LEFT DOUBLE QUOTATION MARK +201D;quotedblright;RIGHT DOUBLE QUOTATION MARK +2018;quoteleft;LEFT SINGLE QUOTATION MARK +201B;quotereversed;SINGLE HIGH-REVERSED-9 QUOTATION MARK +2019;quoteright;RIGHT SINGLE QUOTATION MARK +201A;quotesinglbase;SINGLE LOW-9 QUOTATION MARK +0027;quotesingle;APOSTROPHE +0072;r;LATIN SMALL LETTER R +0155;racute;LATIN SMALL LETTER R WITH ACUTE +221A;radical;SQUARE ROOT +0159;rcaron;LATIN SMALL LETTER R WITH CARON +2286;reflexsubset;SUBSET OF OR EQUAL TO +2287;reflexsuperset;SUPERSET OF OR EQUAL TO +00AE;registered;REGISTERED SIGN +2310;revlogicalnot;REVERSED NOT SIGN +03C1;rho;GREEK SMALL LETTER RHO +02DA;ring;RING ABOVE +2590;rtblock;RIGHT HALF BLOCK +0073;s;LATIN SMALL LETTER S +015B;sacute;LATIN SMALL LETTER S WITH ACUTE +0161;scaron;LATIN SMALL LETTER S WITH CARON +015F;scedilla;LATIN SMALL LETTER S WITH CEDILLA +015D;scircumflex;LATIN SMALL LETTER S WITH CIRCUMFLEX +2033;second;DOUBLE PRIME +00A7;section;SECTION SIGN +003B;semicolon;SEMICOLON +0037;seven;DIGIT SEVEN +215E;seveneighths;VULGAR FRACTION SEVEN EIGHTHS +2592;shade;MEDIUM SHADE +03C3;sigma;GREEK SMALL LETTER SIGMA +03C2;sigma1;GREEK SMALL LETTER FINAL SIGMA +223C;similar;TILDE OPERATOR +0036;six;DIGIT SIX +002F;slash;SOLIDUS +263A;smileface;WHITE SMILING FACE +0020;space;SPACE +2660;spade;BLACK SPADE SUIT +00A3;sterling;POUND SIGN +220B;suchthat;CONTAINS AS MEMBER +2211;summation;N-ARY SUMMATION +263C;sun;WHITE SUN WITH RAYS +0074;t;LATIN SMALL LETTER T +03C4;tau;GREEK SMALL LETTER TAU +0167;tbar;LATIN SMALL LETTER T WITH STROKE +0165;tcaron;LATIN SMALL LETTER T WITH CARON +2234;therefore;THEREFORE +03B8;theta;GREEK SMALL LETTER THETA +03D1;theta1;GREEK THETA SYMBOL +00FE;thorn;LATIN SMALL LETTER THORN +0033;three;DIGIT THREE +215C;threeeighths;VULGAR FRACTION THREE EIGHTHS +00BE;threequarters;VULGAR FRACTION THREE QUARTERS +02DC;tilde;SMALL TILDE +0303;tildecomb;COMBINING TILDE +0384;tonos;GREEK TONOS +2122;trademark;TRADE MARK SIGN +25BC;triagdn;BLACK DOWN-POINTING TRIANGLE +25C4;triaglf;BLACK LEFT-POINTING POINTER +25BA;triagrt;BLACK RIGHT-POINTING POINTER +25B2;triagup;BLACK UP-POINTING TRIANGLE +0032;two;DIGIT TWO +2025;twodotenleader;TWO DOT LEADER +2154;twothirds;VULGAR FRACTION TWO THIRDS +0075;u;LATIN SMALL LETTER U +00FA;uacute;LATIN SMALL LETTER U WITH ACUTE +016D;ubreve;LATIN SMALL LETTER U WITH BREVE +00FB;ucircumflex;LATIN SMALL LETTER U WITH CIRCUMFLEX +00FC;udieresis;LATIN SMALL LETTER U WITH DIAERESIS +00F9;ugrave;LATIN SMALL LETTER U WITH GRAVE +01B0;uhorn;LATIN SMALL LETTER U WITH HORN +0171;uhungarumlaut;LATIN SMALL LETTER U WITH DOUBLE ACUTE +016B;umacron;LATIN SMALL LETTER U WITH MACRON +005F;underscore;LOW LINE +2017;underscoredbl;DOUBLE LOW LINE +222A;union;UNION +2200;universal;FOR ALL +0173;uogonek;LATIN SMALL LETTER U WITH OGONEK +2580;upblock;UPPER HALF BLOCK +03C5;upsilon;GREEK SMALL LETTER UPSILON +03CB;upsilondieresis;GREEK SMALL LETTER UPSILON WITH DIALYTIKA +03B0;upsilondieresistonos;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03CD;upsilontonos;GREEK SMALL LETTER UPSILON WITH TONOS +016F;uring;LATIN SMALL LETTER U WITH RING ABOVE +0169;utilde;LATIN SMALL LETTER U WITH TILDE +0076;v;LATIN SMALL LETTER V +0077;w;LATIN SMALL LETTER W +1E83;wacute;LATIN SMALL LETTER W WITH ACUTE +0175;wcircumflex;LATIN SMALL LETTER W WITH CIRCUMFLEX +1E85;wdieresis;LATIN SMALL LETTER W WITH DIAERESIS +2118;weierstrass;SCRIPT CAPITAL P +1E81;wgrave;LATIN SMALL LETTER W WITH GRAVE +0078;x;LATIN SMALL LETTER X +03BE;xi;GREEK SMALL LETTER XI +0079;y;LATIN SMALL LETTER Y +00FD;yacute;LATIN SMALL LETTER Y WITH ACUTE +0177;ycircumflex;LATIN SMALL LETTER Y WITH CIRCUMFLEX +00FF;ydieresis;LATIN SMALL LETTER Y WITH DIAERESIS +00A5;yen;YEN SIGN +1EF3;ygrave;LATIN SMALL LETTER Y WITH GRAVE +007A;z;LATIN SMALL LETTER Z +017A;zacute;LATIN SMALL LETTER Z WITH ACUTE +017E;zcaron;LATIN SMALL LETTER Z WITH CARON +017C;zdotaccent;LATIN SMALL LETTER Z WITH DOT ABOVE +0030;zero;DIGIT ZERO +03B6;zeta;GREEK SMALL LETTER ZETA +# END +""" + + +class AGLError(Exception): + pass + + +LEGACY_AGL2UV = {} +AGL2UV = {} +UV2AGL = {} + + +def _builddicts(): + import re + + lines = _aglText.splitlines() + + parseAGL_RE = re.compile("([A-Za-z0-9]+);((?:[0-9A-F]{4})(?: (?:[0-9A-F]{4}))*)$") + + for line in lines: + if not line or line[:1] == "#": + continue + m = parseAGL_RE.match(line) + if not m: + raise AGLError("syntax error in glyphlist.txt: %s" % repr(line[:20])) + unicodes = m.group(2) + assert len(unicodes) % 5 == 4 + unicodes = [int(unicode, 16) for unicode in unicodes.split()] + glyphName = tostr(m.group(1)) + LEGACY_AGL2UV[glyphName] = unicodes + + lines = _aglfnText.splitlines() + + parseAGLFN_RE = re.compile("([0-9A-F]{4});([A-Za-z0-9]+);.*?$") + + for line in lines: + if not line or line[:1] == "#": + continue + m = parseAGLFN_RE.match(line) + if not m: + raise AGLError("syntax error in aglfn.txt: %s" % repr(line[:20])) + unicode = m.group(1) + assert len(unicode) == 4 + unicode = int(unicode, 16) + glyphName = tostr(m.group(2)) + AGL2UV[glyphName] = unicode + UV2AGL[unicode] = glyphName + + +_builddicts() + + +def toUnicode(glyph, isZapfDingbats=False): + """Convert glyph names to Unicode, such as ``'longs_t.oldstyle'`` --> ``u'ſt'`` + + If ``isZapfDingbats`` is ``True``, the implementation recognizes additional + glyph names (as required by the AGL specification). + """ + # https://github.com/adobe-type-tools/agl-specification#2-the-mapping + # + # 1. Drop all the characters from the glyph name starting with + # the first occurrence of a period (U+002E; FULL STOP), if any. + glyph = glyph.split(".", 1)[0] + + # 2. Split the remaining string into a sequence of components, + # using underscore (U+005F; LOW LINE) as the delimiter. + components = glyph.split("_") + + # 3. Map each component to a character string according to the + # procedure below, and concatenate those strings; the result + # is the character string to which the glyph name is mapped. + result = [_glyphComponentToUnicode(c, isZapfDingbats) for c in components] + return "".join(result) + + +def _glyphComponentToUnicode(component, isZapfDingbats): + # If the font is Zapf Dingbats (PostScript FontName: ZapfDingbats), + # and the component is in the ITC Zapf Dingbats Glyph List, then + # map it to the corresponding character in that list. + dingbat = _zapfDingbatsToUnicode(component) if isZapfDingbats else None + if dingbat: + return dingbat + + # Otherwise, if the component is in AGL, then map it + # to the corresponding character in that list. + uchars = LEGACY_AGL2UV.get(component) + if uchars: + return "".join(map(chr, uchars)) + + # Otherwise, if the component is of the form "uni" (U+0075, + # U+006E, and U+0069) followed by a sequence of uppercase + # hexadecimal digits (0–9 and A–F, meaning U+0030 through + # U+0039 and U+0041 through U+0046), if the length of that + # sequence is a multiple of four, and if each group of four + # digits represents a value in the ranges 0000 through D7FF + # or E000 through FFFF, then interpret each as a Unicode scalar + # value and map the component to the string made of those + # scalar values. Note that the range and digit-length + # restrictions mean that the "uni" glyph name prefix can be + # used only with UVs in the Basic Multilingual Plane (BMP). + uni = _uniToUnicode(component) + if uni: + return uni + + # Otherwise, if the component is of the form "u" (U+0075) + # followed by a sequence of four to six uppercase hexadecimal + # digits (0–9 and A–F, meaning U+0030 through U+0039 and + # U+0041 through U+0046), and those digits represents a value + # in the ranges 0000 through D7FF or E000 through 10FFFF, then + # interpret it as a Unicode scalar value and map the component + # to the string made of this scalar value. + uni = _uToUnicode(component) + if uni: + return uni + + # Otherwise, map the component to an empty string. + return "" + + +# https://github.com/adobe-type-tools/agl-aglfn/blob/master/zapfdingbats.txt +_AGL_ZAPF_DINGBATS = ( + " ✁✂✄☎✆✝✞✟✠✡☛☞✌✍✎✏✑✒✓✔✕✖✗✘✙✚✛✜✢✣✤✥✦✧★✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀" + "❁❂❃❄❅❆❇❈❉❊❋●❍■❏❑▲▼◆❖ ◗❘❙❚❯❱❲❳❨❩❬❭❪❫❴❵❛❜❝❞❡❢❣❤✐❥❦❧♠♥♦♣ ✉✈✇" + "①②③④⑤⑥⑦⑧⑨⑩❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔→➣↔" + "↕➙➛➜➝➞➟➠➡➢➤➥➦➧➨➩➫➭➯➲➳➵➸➺➻➼➽➾➚➪➶➹➘➴➷➬➮➱✃❐❒❮❰" +) + + +def _zapfDingbatsToUnicode(glyph): + """Helper for toUnicode().""" + if len(glyph) < 2 or glyph[0] != "a": + return None + try: + gid = int(glyph[1:]) + except ValueError: + return None + if gid < 0 or gid >= len(_AGL_ZAPF_DINGBATS): + return None + uchar = _AGL_ZAPF_DINGBATS[gid] + return uchar if uchar != " " else None + + +_re_uni = re.compile("^uni([0-9A-F]+)$") + + +def _uniToUnicode(component): + """Helper for toUnicode() to handle "uniABCD" components.""" + match = _re_uni.match(component) + if match is None: + return None + digits = match.group(1) + if len(digits) % 4 != 0: + return None + chars = [int(digits[i : i + 4], 16) for i in range(0, len(digits), 4)] + if any(c >= 0xD800 and c <= 0xDFFF for c in chars): + # The AGL specification explicitly excluded surrogate pairs. + return None + return "".join([chr(c) for c in chars]) + + +_re_u = re.compile("^u([0-9A-F]{4,6})$") + + +def _uToUnicode(component): + """Helper for toUnicode() to handle "u1ABCD" components.""" + match = _re_u.match(component) + if match is None: + return None + digits = match.group(1) + try: + value = int(digits, 16) + except ValueError: + return None + if (value >= 0x0000 and value <= 0xD7FF) or (value >= 0xE000 and value <= 0x10FFFF): + return chr(value) + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/__init__.py new file mode 100644 index 00000000..644508c1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/__init__.py @@ -0,0 +1,3830 @@ +"""cffLib: read/write Adobe CFF fonts + +OpenType fonts with PostScript outlines contain a completely independent +font file, Adobe's *Compact Font Format*. So dealing with OpenType fonts +requires also dealing with CFF. This module allows you to read and write +fonts written in the CFF format. + +In 2016, OpenType 1.8 introduced the `CFF2 `_ +format which, along with other changes, extended the CFF format to deal with +the demands of variable fonts. This module parses both original CFF and CFF2. + +""" + +from fontTools.misc import sstruct +from fontTools.misc import psCharStrings +from fontTools.misc.arrayTools import unionRect, intRect +from fontTools.misc.textTools import ( + bytechr, + byteord, + bytesjoin, + tobytes, + tostr, + safeEval, +) +from fontTools.ttLib import TTFont +from fontTools.ttLib.tables.otBase import OTTableWriter +from fontTools.ttLib.tables.otBase import OTTableReader +from fontTools.ttLib.tables import otTables as ot +from io import BytesIO +import struct +import logging +import re + +# mute cffLib debug messages when running ttx in verbose mode +DEBUG = logging.DEBUG - 1 +log = logging.getLogger(__name__) + +cffHeaderFormat = """ + major: B + minor: B + hdrSize: B +""" + +maxStackLimit = 513 +# maxstack operator has been deprecated. max stack is now always 513. + + +class StopHintCountEvent(Exception): + pass + + +class _DesubroutinizingT2Decompiler(psCharStrings.SimpleT2Decompiler): + stop_hintcount_ops = ( + "op_hintmask", + "op_cntrmask", + "op_rmoveto", + "op_hmoveto", + "op_vmoveto", + ) + + def __init__(self, localSubrs, globalSubrs, private=None): + psCharStrings.SimpleT2Decompiler.__init__( + self, localSubrs, globalSubrs, private + ) + + def execute(self, charString): + self.need_hintcount = True # until proven otherwise + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, self.stop_hint_count) + + if hasattr(charString, "_desubroutinized"): + # If a charstring has already been desubroutinized, we will still + # need to execute it if we need to count hints in order to + # compute the byte length for mask arguments, and haven't finished + # counting hints pairs. + if self.need_hintcount and self.callingStack: + try: + psCharStrings.SimpleT2Decompiler.execute(self, charString) + except StopHintCountEvent: + del self.callingStack[-1] + return + + charString._patches = [] + psCharStrings.SimpleT2Decompiler.execute(self, charString) + desubroutinized = charString.program[:] + for idx, expansion in reversed(charString._patches): + assert idx >= 2 + assert desubroutinized[idx - 1] in [ + "callsubr", + "callgsubr", + ], desubroutinized[idx - 1] + assert type(desubroutinized[idx - 2]) == int + if expansion[-1] == "return": + expansion = expansion[:-1] + desubroutinized[idx - 2 : idx] = expansion + if not self.private.in_cff2: + if "endchar" in desubroutinized: + # Cut off after first endchar + desubroutinized = desubroutinized[ + : desubroutinized.index("endchar") + 1 + ] + else: + if not len(desubroutinized) or desubroutinized[-1] != "return": + desubroutinized.append("return") + + charString._desubroutinized = desubroutinized + del charString._patches + + def op_callsubr(self, index): + subr = self.localSubrs[self.operandStack[-1] + self.localBias] + psCharStrings.SimpleT2Decompiler.op_callsubr(self, index) + self.processSubr(index, subr) + + def op_callgsubr(self, index): + subr = self.globalSubrs[self.operandStack[-1] + self.globalBias] + psCharStrings.SimpleT2Decompiler.op_callgsubr(self, index) + self.processSubr(index, subr) + + def stop_hint_count(self, *args): + self.need_hintcount = False + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, None) + cs = self.callingStack[-1] + if hasattr(cs, "_desubroutinized"): + raise StopHintCountEvent() + + def op_hintmask(self, index): + psCharStrings.SimpleT2Decompiler.op_hintmask(self, index) + if self.need_hintcount: + self.stop_hint_count() + + def processSubr(self, index, subr): + cs = self.callingStack[-1] + if not hasattr(cs, "_desubroutinized"): + cs._patches.append((index, subr._desubroutinized)) + + +class CFFFontSet(object): + """A CFF font "file" can contain more than one font, although this is + extremely rare (and not allowed within OpenType fonts). + + This class is the entry point for parsing a CFF table. To actually + manipulate the data inside the CFF font, you will want to access the + ``CFFFontSet``'s :class:`TopDict` object. To do this, a ``CFFFontSet`` + object can either be treated as a dictionary (with appropriate + ``keys()`` and ``values()`` methods) mapping font names to :class:`TopDict` + objects, or as a list. + + .. code:: python + + from fontTools import ttLib + tt = ttLib.TTFont("Tests/cffLib/data/LinLibertine_RBI.otf") + tt["CFF "].cff + # + tt["CFF "].cff[0] # Here's your actual font data + # + + """ + + def decompile(self, file, otFont, isCFF2=None): + """Parse a binary CFF file into an internal representation. ``file`` + should be a file handle object. ``otFont`` is the top-level + :py:class:`fontTools.ttLib.ttFont.TTFont` object containing this CFF file. + + If ``isCFF2`` is passed and set to ``True`` or ``False``, then the + library makes an assertion that the CFF header is of the appropriate + version. + """ + + self.otFont = otFont + sstruct.unpack(cffHeaderFormat, file.read(3), self) + if isCFF2 is not None: + # called from ttLib: assert 'major' as read from file matches the + # expected version + expected_major = 2 if isCFF2 else 1 + if self.major != expected_major: + raise ValueError( + "Invalid CFF 'major' version: expected %d, found %d" + % (expected_major, self.major) + ) + else: + # use 'major' version from file to determine if isCFF2 + assert self.major in (1, 2), "Unknown CFF format" + isCFF2 = self.major == 2 + if not isCFF2: + self.offSize = struct.unpack("B", file.read(1))[0] + file.seek(self.hdrSize) + self.fontNames = list(tostr(s) for s in Index(file, isCFF2=isCFF2)) + self.topDictIndex = TopDictIndex(file, isCFF2=isCFF2) + self.strings = IndexedStrings(file) + else: # isCFF2 + self.topDictSize = struct.unpack(">H", file.read(2))[0] + file.seek(self.hdrSize) + self.fontNames = ["CFF2Font"] + cff2GetGlyphOrder = otFont.getGlyphOrder + # in CFF2, offsetSize is the size of the TopDict data. + self.topDictIndex = TopDictIndex( + file, cff2GetGlyphOrder, self.topDictSize, isCFF2=isCFF2 + ) + self.strings = None + self.GlobalSubrs = GlobalSubrsIndex(file, isCFF2=isCFF2) + self.topDictIndex.strings = self.strings + self.topDictIndex.GlobalSubrs = self.GlobalSubrs + + def __len__(self): + return len(self.fontNames) + + def keys(self): + return list(self.fontNames) + + def values(self): + return self.topDictIndex + + def __getitem__(self, nameOrIndex): + """Return TopDict instance identified by name (str) or index (int + or any object that implements `__index__`). + """ + if hasattr(nameOrIndex, "__index__"): + index = nameOrIndex.__index__() + elif isinstance(nameOrIndex, str): + name = nameOrIndex + try: + index = self.fontNames.index(name) + except ValueError: + raise KeyError(nameOrIndex) + else: + raise TypeError(nameOrIndex) + return self.topDictIndex[index] + + def compile(self, file, otFont, isCFF2=None): + """Write the object back into binary representation onto the given file. + ``file`` should be a file handle object. ``otFont`` is the top-level + :py:class:`fontTools.ttLib.ttFont.TTFont` object containing this CFF file. + + If ``isCFF2`` is passed and set to ``True`` or ``False``, then the + library makes an assertion that the CFF header is of the appropriate + version. + """ + self.otFont = otFont + if isCFF2 is not None: + # called from ttLib: assert 'major' value matches expected version + expected_major = 2 if isCFF2 else 1 + if self.major != expected_major: + raise ValueError( + "Invalid CFF 'major' version: expected %d, found %d" + % (expected_major, self.major) + ) + else: + # use current 'major' value to determine output format + assert self.major in (1, 2), "Unknown CFF format" + isCFF2 = self.major == 2 + + if otFont.recalcBBoxes and not isCFF2: + for topDict in self.topDictIndex: + topDict.recalcFontBBox() + + if not isCFF2: + strings = IndexedStrings() + else: + strings = None + writer = CFFWriter(isCFF2) + topCompiler = self.topDictIndex.getCompiler(strings, self, isCFF2=isCFF2) + if isCFF2: + self.hdrSize = 5 + writer.add(sstruct.pack(cffHeaderFormat, self)) + # Note: topDictSize will most likely change in CFFWriter.toFile(). + self.topDictSize = topCompiler.getDataLength() + writer.add(struct.pack(">H", self.topDictSize)) + else: + self.hdrSize = 4 + self.offSize = 4 # will most likely change in CFFWriter.toFile(). + writer.add(sstruct.pack(cffHeaderFormat, self)) + writer.add(struct.pack("B", self.offSize)) + if not isCFF2: + fontNames = Index() + for name in self.fontNames: + fontNames.append(name) + writer.add(fontNames.getCompiler(strings, self, isCFF2=isCFF2)) + writer.add(topCompiler) + if not isCFF2: + writer.add(strings.getCompiler()) + writer.add(self.GlobalSubrs.getCompiler(strings, self, isCFF2=isCFF2)) + + for topDict in self.topDictIndex: + if not hasattr(topDict, "charset") or topDict.charset is None: + charset = otFont.getGlyphOrder() + topDict.charset = charset + children = topCompiler.getChildren(strings) + for child in children: + writer.add(child) + + writer.toFile(file) + + def toXML(self, xmlWriter): + """Write the object into XML representation onto the given + :class:`fontTools.misc.xmlWriter.XMLWriter`. + + .. code:: python + + writer = xmlWriter.XMLWriter(sys.stdout) + tt["CFF "].cff.toXML(writer) + + """ + + xmlWriter.simpletag("major", value=self.major) + xmlWriter.newline() + xmlWriter.simpletag("minor", value=self.minor) + xmlWriter.newline() + for fontName in self.fontNames: + xmlWriter.begintag("CFFFont", name=tostr(fontName)) + xmlWriter.newline() + font = self[fontName] + font.toXML(xmlWriter) + xmlWriter.endtag("CFFFont") + xmlWriter.newline() + xmlWriter.newline() + xmlWriter.begintag("GlobalSubrs") + xmlWriter.newline() + self.GlobalSubrs.toXML(xmlWriter) + xmlWriter.endtag("GlobalSubrs") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, otFont=None): + """Reads data from the XML element into the ``CFFFontSet`` object.""" + self.otFont = otFont + + # set defaults. These will be replaced if there are entries for them + # in the XML file. + if not hasattr(self, "major"): + self.major = 1 + if not hasattr(self, "minor"): + self.minor = 0 + + if name == "CFFFont": + if self.major == 1: + if not hasattr(self, "offSize"): + # this will be recalculated when the cff is compiled. + self.offSize = 4 + if not hasattr(self, "hdrSize"): + self.hdrSize = 4 + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + if not hasattr(self, "fontNames"): + self.fontNames = [] + self.topDictIndex = TopDictIndex() + fontName = attrs["name"] + self.fontNames.append(fontName) + topDict = TopDict(GlobalSubrs=self.GlobalSubrs) + topDict.charset = None # gets filled in later + elif self.major == 2: + if not hasattr(self, "hdrSize"): + self.hdrSize = 5 + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + if not hasattr(self, "fontNames"): + self.fontNames = ["CFF2Font"] + cff2GetGlyphOrder = self.otFont.getGlyphOrder + topDict = TopDict( + GlobalSubrs=self.GlobalSubrs, cff2GetGlyphOrder=cff2GetGlyphOrder + ) + self.topDictIndex = TopDictIndex(None, cff2GetGlyphOrder) + self.topDictIndex.append(topDict) + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + topDict.fromXML(name, attrs, content) + + if hasattr(topDict, "VarStore") and topDict.FDArray[0].vstore is None: + fdArray = topDict.FDArray + for fontDict in fdArray: + if hasattr(fontDict, "Private"): + fontDict.Private.vstore = topDict.VarStore + + elif name == "GlobalSubrs": + subrCharStringClass = psCharStrings.T2CharString + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + subr = subrCharStringClass() + subr.fromXML(name, attrs, content) + self.GlobalSubrs.append(subr) + elif name == "major": + self.major = int(attrs["value"]) + elif name == "minor": + self.minor = int(attrs["value"]) + + def convertCFFToCFF2(self, otFont): + """Converts this object from CFF format to CFF2 format. This conversion + is done 'in-place'. The conversion cannot be reversed. + + This assumes a decompiled CFF table. (i.e. that the object has been + filled via :meth:`decompile`.)""" + self.major = 2 + cff2GetGlyphOrder = self.otFont.getGlyphOrder + topDictData = TopDictIndex(None, cff2GetGlyphOrder) + topDictData.items = self.topDictIndex.items + self.topDictIndex = topDictData + topDict = topDictData[0] + if hasattr(topDict, "Private"): + privateDict = topDict.Private + else: + privateDict = None + opOrder = buildOrder(topDictOperators2) + topDict.order = opOrder + topDict.cff2GetGlyphOrder = cff2GetGlyphOrder + for entry in topDictOperators: + key = entry[1] + if key not in opOrder: + if key in topDict.rawDict: + del topDict.rawDict[key] + if hasattr(topDict, key): + delattr(topDict, key) + + if not hasattr(topDict, "FDArray"): + fdArray = topDict.FDArray = FDArrayIndex() + fdArray.strings = None + fdArray.GlobalSubrs = topDict.GlobalSubrs + topDict.GlobalSubrs.fdArray = fdArray + charStrings = topDict.CharStrings + if charStrings.charStringsAreIndexed: + charStrings.charStringsIndex.fdArray = fdArray + else: + charStrings.fdArray = fdArray + fontDict = FontDict() + fontDict.setCFF2(True) + fdArray.append(fontDict) + fontDict.Private = privateDict + privateOpOrder = buildOrder(privateDictOperators2) + for entry in privateDictOperators: + key = entry[1] + if key not in privateOpOrder: + if key in privateDict.rawDict: + # print "Removing private dict", key + del privateDict.rawDict[key] + if hasattr(privateDict, key): + delattr(privateDict, key) + # print "Removing privateDict attr", key + else: + # clean up the PrivateDicts in the fdArray + fdArray = topDict.FDArray + privateOpOrder = buildOrder(privateDictOperators2) + for fontDict in fdArray: + fontDict.setCFF2(True) + for key in fontDict.rawDict.keys(): + if key not in fontDict.order: + del fontDict.rawDict[key] + if hasattr(fontDict, key): + delattr(fontDict, key) + + privateDict = fontDict.Private + for entry in privateDictOperators: + key = entry[1] + if key not in privateOpOrder: + if key in privateDict.rawDict: + # print "Removing private dict", key + del privateDict.rawDict[key] + if hasattr(privateDict, key): + delattr(privateDict, key) + # print "Removing privateDict attr", key + # At this point, the Subrs and Charstrings are all still T2Charstring class + # easiest to fix this by compiling, then decompiling again + file = BytesIO() + self.compile(file, otFont, isCFF2=True) + file.seek(0) + self.decompile(file, otFont, isCFF2=True) + + def desubroutinize(self): + for fontName in self.fontNames: + font = self[fontName] + cs = font.CharStrings + for g in font.charset: + c, _ = cs.getItemAndSelector(g) + c.decompile() + subrs = getattr(c.private, "Subrs", []) + decompiler = _DesubroutinizingT2Decompiler( + subrs, c.globalSubrs, c.private + ) + decompiler.execute(c) + c.program = c._desubroutinized + del c._desubroutinized + # Delete all the local subrs + if hasattr(font, "FDArray"): + for fd in font.FDArray: + pd = fd.Private + if hasattr(pd, "Subrs"): + del pd.Subrs + if "Subrs" in pd.rawDict: + del pd.rawDict["Subrs"] + else: + pd = font.Private + if hasattr(pd, "Subrs"): + del pd.Subrs + if "Subrs" in pd.rawDict: + del pd.rawDict["Subrs"] + # as well as the global subrs + self.GlobalSubrs.clear() + + +class CFFWriter(object): + """Helper class for serializing CFF data to binary. Used by + :meth:`CFFFontSet.compile`.""" + + def __init__(self, isCFF2): + self.data = [] + self.isCFF2 = isCFF2 + + def add(self, table): + self.data.append(table) + + def toFile(self, file): + lastPosList = None + count = 1 + while True: + log.log(DEBUG, "CFFWriter.toFile() iteration: %d", count) + count = count + 1 + pos = 0 + posList = [pos] + for item in self.data: + if hasattr(item, "getDataLength"): + endPos = pos + item.getDataLength() + if isinstance(item, TopDictIndexCompiler) and item.isCFF2: + self.topDictSize = item.getDataLength() + else: + endPos = pos + len(item) + if hasattr(item, "setPos"): + item.setPos(pos, endPos) + pos = endPos + posList.append(pos) + if posList == lastPosList: + break + lastPosList = posList + log.log(DEBUG, "CFFWriter.toFile() writing to file.") + begin = file.tell() + if self.isCFF2: + self.data[1] = struct.pack(">H", self.topDictSize) + else: + self.offSize = calcOffSize(lastPosList[-1]) + self.data[1] = struct.pack("B", self.offSize) + posList = [0] + for item in self.data: + if hasattr(item, "toFile"): + item.toFile(file) + else: + file.write(item) + posList.append(file.tell() - begin) + assert posList == lastPosList + + +def calcOffSize(largestOffset): + if largestOffset < 0x100: + offSize = 1 + elif largestOffset < 0x10000: + offSize = 2 + elif largestOffset < 0x1000000: + offSize = 3 + else: + offSize = 4 + return offSize + + +class IndexCompiler(object): + """Base class for writing CFF `INDEX data `_ + to binary.""" + + def __init__(self, items, strings, parent, isCFF2=None): + if isCFF2 is None and hasattr(parent, "isCFF2"): + isCFF2 = parent.isCFF2 + assert isCFF2 is not None + self.isCFF2 = isCFF2 + self.items = self.getItems(items, strings) + self.parent = parent + + def getItems(self, items, strings): + return items + + def getOffsets(self): + # An empty INDEX contains only the count field. + if self.items: + pos = 1 + offsets = [pos] + for item in self.items: + if hasattr(item, "getDataLength"): + pos = pos + item.getDataLength() + else: + pos = pos + len(item) + offsets.append(pos) + else: + offsets = [] + return offsets + + def getDataLength(self): + if self.isCFF2: + countSize = 4 + else: + countSize = 2 + + if self.items: + lastOffset = self.getOffsets()[-1] + offSize = calcOffSize(lastOffset) + dataLength = ( + countSize + + 1 # count + + (len(self.items) + 1) * offSize # offSize + + lastOffset # the offsets + - 1 # size of object data + ) + else: + # count. For empty INDEX tables, this is the only entry. + dataLength = countSize + + return dataLength + + def toFile(self, file): + offsets = self.getOffsets() + if self.isCFF2: + writeCard32(file, len(self.items)) + else: + writeCard16(file, len(self.items)) + # An empty INDEX contains only the count field. + if self.items: + offSize = calcOffSize(offsets[-1]) + writeCard8(file, offSize) + offSize = -offSize + pack = struct.pack + for offset in offsets: + binOffset = pack(">l", offset)[offSize:] + assert len(binOffset) == -offSize + file.write(binOffset) + for item in self.items: + if hasattr(item, "toFile"): + item.toFile(file) + else: + data = tobytes(item, encoding="latin1") + file.write(data) + + +class IndexedStringsCompiler(IndexCompiler): + def getItems(self, items, strings): + return items.strings + + +class TopDictIndexCompiler(IndexCompiler): + """Helper class for writing the TopDict to binary.""" + + def getItems(self, items, strings): + out = [] + for item in items: + out.append(item.getCompiler(strings, self)) + return out + + def getChildren(self, strings): + children = [] + for topDict in self.items: + children.extend(topDict.getChildren(strings)) + return children + + def getOffsets(self): + if self.isCFF2: + offsets = [0, self.items[0].getDataLength()] + return offsets + else: + return super(TopDictIndexCompiler, self).getOffsets() + + def getDataLength(self): + if self.isCFF2: + dataLength = self.items[0].getDataLength() + return dataLength + else: + return super(TopDictIndexCompiler, self).getDataLength() + + def toFile(self, file): + if self.isCFF2: + self.items[0].toFile(file) + else: + super(TopDictIndexCompiler, self).toFile(file) + + +class FDArrayIndexCompiler(IndexCompiler): + """Helper class for writing the + `Font DICT INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for item in items: + out.append(item.getCompiler(strings, self)) + return out + + def getChildren(self, strings): + children = [] + for fontDict in self.items: + children.extend(fontDict.getChildren(strings)) + return children + + def toFile(self, file): + offsets = self.getOffsets() + if self.isCFF2: + writeCard32(file, len(self.items)) + else: + writeCard16(file, len(self.items)) + offSize = calcOffSize(offsets[-1]) + writeCard8(file, offSize) + offSize = -offSize + pack = struct.pack + for offset in offsets: + binOffset = pack(">l", offset)[offSize:] + assert len(binOffset) == -offSize + file.write(binOffset) + for item in self.items: + if hasattr(item, "toFile"): + item.toFile(file) + else: + file.write(item) + + def setPos(self, pos, endPos): + self.parent.rawDict["FDArray"] = pos + + +class GlobalSubrsCompiler(IndexCompiler): + """Helper class for writing the `global subroutine INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for cs in items: + cs.compile(self.isCFF2) + out.append(cs.bytecode) + return out + + +class SubrsCompiler(GlobalSubrsCompiler): + """Helper class for writing the `local subroutine INDEX `_ + to binary.""" + + def setPos(self, pos, endPos): + offset = pos - self.parent.pos + self.parent.rawDict["Subrs"] = offset + + +class CharStringsCompiler(GlobalSubrsCompiler): + """Helper class for writing the `CharStrings INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for cs in items: + cs.compile(self.isCFF2) + out.append(cs.bytecode) + return out + + def setPos(self, pos, endPos): + self.parent.rawDict["CharStrings"] = pos + + +class Index(object): + """This class represents what the CFF spec calls an INDEX (an array of + variable-sized objects). `Index` items can be addressed and set using + Python list indexing.""" + + compilerClass = IndexCompiler + + def __init__(self, file=None, isCFF2=None): + assert (isCFF2 is None) == (file is None) + self.items = [] + name = self.__class__.__name__ + if file is None: + return + self._isCFF2 = isCFF2 + log.log(DEBUG, "loading %s at %s", name, file.tell()) + self.file = file + if isCFF2: + count = readCard32(file) + else: + count = readCard16(file) + if count == 0: + return + self.items = [None] * count + offSize = readCard8(file) + log.log(DEBUG, " index count: %s offSize: %s", count, offSize) + assert offSize <= 4, "offSize too large: %s" % offSize + self.offsets = offsets = [] + pad = b"\0" * (4 - offSize) + for index in range(count + 1): + chunk = file.read(offSize) + chunk = pad + chunk + (offset,) = struct.unpack(">L", chunk) + offsets.append(int(offset)) + self.offsetBase = file.tell() - 1 + file.seek(self.offsetBase + offsets[-1]) # pretend we've read the whole lot + log.log(DEBUG, " end of %s at %s", name, file.tell()) + + def __len__(self): + return len(self.items) + + def __getitem__(self, index): + item = self.items[index] + if item is not None: + return item + offset = self.offsets[index] + self.offsetBase + size = self.offsets[index + 1] - self.offsets[index] + file = self.file + file.seek(offset) + data = file.read(size) + assert len(data) == size + item = self.produceItem(index, data, file, offset) + self.items[index] = item + return item + + def __setitem__(self, index, item): + self.items[index] = item + + def produceItem(self, index, data, file, offset): + return data + + def append(self, item): + """Add an item to an INDEX.""" + self.items.append(item) + + def getCompiler(self, strings, parent, isCFF2=None): + return self.compilerClass(self, strings, parent, isCFF2=isCFF2) + + def clear(self): + """Empty the INDEX.""" + del self.items[:] + + +class GlobalSubrsIndex(Index): + """This index contains all the global subroutines in the font. A global + subroutine is a set of ``CharString`` data which is accessible to any + glyph in the font, and are used to store repeated instructions - for + example, components may be encoded as global subroutines, but so could + hinting instructions. + + Remember that when interpreting a ``callgsubr`` instruction (or indeed + a ``callsubr`` instruction) that you will need to add the "subroutine + number bias" to number given: + + .. code:: python + + tt = ttLib.TTFont("Almendra-Bold.otf") + u = tt["CFF "].cff[0].CharStrings["udieresis"] + u.decompile() + + u.toXML(XMLWriter(sys.stdout)) + # + # -64 callgsubr <-- Subroutine which implements the dieresis mark + # + + tt["CFF "].cff[0].GlobalSubrs[-64] # <-- WRONG + # + + tt["CFF "].cff[0].GlobalSubrs[-64 + 107] # <-- RIGHT + # + + ("The bias applied depends on the number of subrs (gsubrs). If the number of + subrs (gsubrs) is less than 1240, the bias is 107. Otherwise if it is less + than 33900, it is 1131; otherwise it is 32768.", + `Subroutine Operators `) + """ + + compilerClass = GlobalSubrsCompiler + subrClass = psCharStrings.T2CharString + charStringClass = psCharStrings.T2CharString + + def __init__( + self, + file=None, + globalSubrs=None, + private=None, + fdSelect=None, + fdArray=None, + isCFF2=None, + ): + super(GlobalSubrsIndex, self).__init__(file, isCFF2=isCFF2) + self.globalSubrs = globalSubrs + self.private = private + if fdSelect: + self.fdSelect = fdSelect + if fdArray: + self.fdArray = fdArray + + def produceItem(self, index, data, file, offset): + if self.private is not None: + private = self.private + elif hasattr(self, "fdArray") and self.fdArray is not None: + if hasattr(self, "fdSelect") and self.fdSelect is not None: + fdIndex = self.fdSelect[index] + else: + fdIndex = 0 + private = self.fdArray[fdIndex].Private + else: + private = None + return self.subrClass(data, private=private, globalSubrs=self.globalSubrs) + + def toXML(self, xmlWriter): + """Write the subroutines index into XML representation onto the given + :class:`fontTools.misc.xmlWriter.XMLWriter`. + + .. code:: python + + writer = xmlWriter.XMLWriter(sys.stdout) + tt["CFF "].cff[0].GlobalSubrs.toXML(writer) + + """ + xmlWriter.comment( + "The 'index' attribute is only for humans; " "it is ignored when parsed." + ) + xmlWriter.newline() + for i in range(len(self)): + subr = self[i] + if subr.needsDecompilation(): + xmlWriter.begintag("CharString", index=i, raw=1) + else: + xmlWriter.begintag("CharString", index=i) + xmlWriter.newline() + subr.toXML(xmlWriter) + xmlWriter.endtag("CharString") + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + if name != "CharString": + return + subr = self.subrClass() + subr.fromXML(name, attrs, content) + self.append(subr) + + def getItemAndSelector(self, index): + sel = None + if hasattr(self, "fdSelect"): + sel = self.fdSelect[index] + return self[index], sel + + +class SubrsIndex(GlobalSubrsIndex): + """This index contains a glyph's local subroutines. A local subroutine is a + private set of ``CharString`` data which is accessible only to the glyph to + which the index is attached.""" + + compilerClass = SubrsCompiler + + +class TopDictIndex(Index): + """This index represents the array of ``TopDict`` structures in the font + (again, usually only one entry is present). Hence the following calls are + equivalent: + + .. code:: python + + tt["CFF "].cff[0] + # + tt["CFF "].cff.topDictIndex[0] + # + + """ + + compilerClass = TopDictIndexCompiler + + def __init__(self, file=None, cff2GetGlyphOrder=None, topSize=0, isCFF2=None): + assert (isCFF2 is None) == (file is None) + self.cff2GetGlyphOrder = cff2GetGlyphOrder + if file is not None and isCFF2: + self._isCFF2 = isCFF2 + self.items = [] + name = self.__class__.__name__ + log.log(DEBUG, "loading %s at %s", name, file.tell()) + self.file = file + count = 1 + self.items = [None] * count + self.offsets = [0, topSize] + self.offsetBase = file.tell() + # pretend we've read the whole lot + file.seek(self.offsetBase + topSize) + log.log(DEBUG, " end of %s at %s", name, file.tell()) + else: + super(TopDictIndex, self).__init__(file, isCFF2=isCFF2) + + def produceItem(self, index, data, file, offset): + top = TopDict( + self.strings, + file, + offset, + self.GlobalSubrs, + self.cff2GetGlyphOrder, + isCFF2=self._isCFF2, + ) + top.decompile(data) + return top + + def toXML(self, xmlWriter): + for i in range(len(self)): + xmlWriter.begintag("FontDict", index=i) + xmlWriter.newline() + self[i].toXML(xmlWriter) + xmlWriter.endtag("FontDict") + xmlWriter.newline() + + +class FDArrayIndex(Index): + compilerClass = FDArrayIndexCompiler + + def toXML(self, xmlWriter): + for i in range(len(self)): + xmlWriter.begintag("FontDict", index=i) + xmlWriter.newline() + self[i].toXML(xmlWriter) + xmlWriter.endtag("FontDict") + xmlWriter.newline() + + def produceItem(self, index, data, file, offset): + fontDict = FontDict( + self.strings, + file, + offset, + self.GlobalSubrs, + isCFF2=self._isCFF2, + vstore=self.vstore, + ) + fontDict.decompile(data) + return fontDict + + def fromXML(self, name, attrs, content): + if name != "FontDict": + return + fontDict = FontDict() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + fontDict.fromXML(name, attrs, content) + self.append(fontDict) + + +class VarStoreData(object): + def __init__(self, file=None, otVarStore=None): + self.file = file + self.data = None + self.otVarStore = otVarStore + self.font = TTFont() # dummy font for the decompile function. + + def decompile(self): + if self.file: + # read data in from file. Assume position is correct. + length = readCard16(self.file) + self.data = self.file.read(length) + globalState = {} + reader = OTTableReader(self.data, globalState) + self.otVarStore = ot.VarStore() + self.otVarStore.decompile(reader, self.font) + return self + + def compile(self): + writer = OTTableWriter() + self.otVarStore.compile(writer, self.font) + # Note that this omits the initial Card16 length from the CFF2 + # VarStore data block + self.data = writer.getAllData() + + def writeXML(self, xmlWriter, name): + self.otVarStore.toXML(xmlWriter, self.font) + + def xmlRead(self, name, attrs, content, parent): + self.otVarStore = ot.VarStore() + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + self.otVarStore.fromXML(name, attrs, content, self.font) + else: + pass + return None + + def __len__(self): + return len(self.data) + + def getNumRegions(self, vsIndex): + if vsIndex is None: + vsIndex = 0 + varData = self.otVarStore.VarData[vsIndex] + numRegions = varData.VarRegionCount + return numRegions + + +class FDSelect(object): + def __init__(self, file=None, numGlyphs=None, format=None): + if file: + # read data in from file + self.format = readCard8(file) + if self.format == 0: + from array import array + + self.gidArray = array("B", file.read(numGlyphs)).tolist() + elif self.format == 3: + gidArray = [None] * numGlyphs + nRanges = readCard16(file) + fd = None + prev = None + for i in range(nRanges): + first = readCard16(file) + if prev is not None: + for glyphID in range(prev, first): + gidArray[glyphID] = fd + prev = first + fd = readCard8(file) + if prev is not None: + first = readCard16(file) + for glyphID in range(prev, first): + gidArray[glyphID] = fd + self.gidArray = gidArray + elif self.format == 4: + gidArray = [None] * numGlyphs + nRanges = readCard32(file) + fd = None + prev = None + for i in range(nRanges): + first = readCard32(file) + if prev is not None: + for glyphID in range(prev, first): + gidArray[glyphID] = fd + prev = first + fd = readCard16(file) + if prev is not None: + first = readCard32(file) + for glyphID in range(prev, first): + gidArray[glyphID] = fd + self.gidArray = gidArray + else: + assert False, "unsupported FDSelect format: %s" % format + else: + # reading from XML. Make empty gidArray, and leave format as passed in. + # format is None will result in the smallest representation being used. + self.format = format + self.gidArray = [] + + def __len__(self): + return len(self.gidArray) + + def __getitem__(self, index): + return self.gidArray[index] + + def __setitem__(self, index, fdSelectValue): + self.gidArray[index] = fdSelectValue + + def append(self, fdSelectValue): + self.gidArray.append(fdSelectValue) + + +class CharStrings(object): + """The ``CharStrings`` in the font represent the instructions for drawing + each glyph. This object presents a dictionary interface to the font's + CharStrings, indexed by glyph name: + + .. code:: python + + tt["CFF "].cff[0].CharStrings["a"] + # + + See :class:`fontTools.misc.psCharStrings.T1CharString` and + :class:`fontTools.misc.psCharStrings.T2CharString` for how to decompile, + compile and interpret the glyph drawing instructions in the returned objects. + + """ + + def __init__( + self, + file, + charset, + globalSubrs, + private, + fdSelect, + fdArray, + isCFF2=None, + varStore=None, + ): + self.globalSubrs = globalSubrs + self.varStore = varStore + if file is not None: + self.charStringsIndex = SubrsIndex( + file, globalSubrs, private, fdSelect, fdArray, isCFF2=isCFF2 + ) + self.charStrings = charStrings = {} + for i in range(len(charset)): + charStrings[charset[i]] = i + # read from OTF file: charStrings.values() are indices into + # charStringsIndex. + self.charStringsAreIndexed = 1 + else: + self.charStrings = {} + # read from ttx file: charStrings.values() are actual charstrings + self.charStringsAreIndexed = 0 + self.private = private + if fdSelect is not None: + self.fdSelect = fdSelect + if fdArray is not None: + self.fdArray = fdArray + + def keys(self): + return list(self.charStrings.keys()) + + def values(self): + if self.charStringsAreIndexed: + return self.charStringsIndex + else: + return list(self.charStrings.values()) + + def has_key(self, name): + return name in self.charStrings + + __contains__ = has_key + + def __len__(self): + return len(self.charStrings) + + def __getitem__(self, name): + charString = self.charStrings[name] + if self.charStringsAreIndexed: + charString = self.charStringsIndex[charString] + return charString + + def __setitem__(self, name, charString): + if self.charStringsAreIndexed: + index = self.charStrings[name] + self.charStringsIndex[index] = charString + else: + self.charStrings[name] = charString + + def getItemAndSelector(self, name): + if self.charStringsAreIndexed: + index = self.charStrings[name] + return self.charStringsIndex.getItemAndSelector(index) + else: + if hasattr(self, "fdArray"): + if hasattr(self, "fdSelect"): + sel = self.charStrings[name].fdSelectIndex + else: + sel = 0 + else: + sel = None + return self.charStrings[name], sel + + def toXML(self, xmlWriter): + names = sorted(self.keys()) + for name in names: + charStr, fdSelectIndex = self.getItemAndSelector(name) + if charStr.needsDecompilation(): + raw = [("raw", 1)] + else: + raw = [] + if fdSelectIndex is None: + xmlWriter.begintag("CharString", [("name", name)] + raw) + else: + xmlWriter.begintag( + "CharString", + [("name", name), ("fdSelectIndex", fdSelectIndex)] + raw, + ) + xmlWriter.newline() + charStr.toXML(xmlWriter) + xmlWriter.endtag("CharString") + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + if name != "CharString": + continue + fdID = -1 + if hasattr(self, "fdArray"): + try: + fdID = safeEval(attrs["fdSelectIndex"]) + except KeyError: + fdID = 0 + private = self.fdArray[fdID].Private + else: + private = self.private + + glyphName = attrs["name"] + charStringClass = psCharStrings.T2CharString + charString = charStringClass(private=private, globalSubrs=self.globalSubrs) + charString.fromXML(name, attrs, content) + if fdID >= 0: + charString.fdSelectIndex = fdID + self[glyphName] = charString + + +def readCard8(file): + return byteord(file.read(1)) + + +def readCard16(file): + (value,) = struct.unpack(">H", file.read(2)) + return value + + +def readCard32(file): + (value,) = struct.unpack(">L", file.read(4)) + return value + + +def writeCard8(file, value): + file.write(bytechr(value)) + + +def writeCard16(file, value): + file.write(struct.pack(">H", value)) + + +def writeCard32(file, value): + file.write(struct.pack(">L", value)) + + +def packCard8(value): + return bytechr(value) + + +def packCard16(value): + return struct.pack(">H", value) + + +def packCard32(value): + return struct.pack(">L", value) + + +def buildOperatorDict(table): + d = {} + for op, name, arg, default, conv in table: + d[op] = (name, arg) + return d + + +def buildOpcodeDict(table): + d = {} + for op, name, arg, default, conv in table: + if isinstance(op, tuple): + op = bytechr(op[0]) + bytechr(op[1]) + else: + op = bytechr(op) + d[name] = (op, arg) + return d + + +def buildOrder(table): + l = [] + for op, name, arg, default, conv in table: + l.append(name) + return l + + +def buildDefaults(table): + d = {} + for op, name, arg, default, conv in table: + if default is not None: + d[name] = default + return d + + +def buildConverters(table): + d = {} + for op, name, arg, default, conv in table: + d[name] = conv + return d + + +class SimpleConverter(object): + def read(self, parent, value): + if not hasattr(parent, "file"): + return self._read(parent, value) + file = parent.file + pos = file.tell() + try: + return self._read(parent, value) + finally: + file.seek(pos) + + def _read(self, parent, value): + return value + + def write(self, parent, value): + return value + + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return attrs["value"] + + +class ASCIIConverter(SimpleConverter): + def _read(self, parent, value): + return tostr(value, encoding="ascii") + + def write(self, parent, value): + return tobytes(value, encoding="ascii") + + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, value=tostr(value, encoding="ascii")) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return tobytes(attrs["value"], encoding=("ascii")) + + +class Latin1Converter(SimpleConverter): + def _read(self, parent, value): + return tostr(value, encoding="latin1") + + def write(self, parent, value): + return tobytes(value, encoding="latin1") + + def xmlWrite(self, xmlWriter, name, value): + value = tostr(value, encoding="latin1") + if name in ["Notice", "Copyright"]: + value = re.sub(r"[\r\n]\s+", " ", value) + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return tobytes(attrs["value"], encoding=("latin1")) + + +def parseNum(s): + try: + value = int(s) + except: + value = float(s) + return value + + +def parseBlendList(s): + valueList = [] + for element in s: + if isinstance(element, str): + continue + name, attrs, content = element + blendList = attrs["value"].split() + blendList = [eval(val) for val in blendList] + valueList.append(blendList) + if len(valueList) == 1: + valueList = valueList[0] + return valueList + + +class NumberConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + if isinstance(value, list): + xmlWriter.begintag(name) + xmlWriter.newline() + xmlWriter.indent() + blendValue = " ".join([str(val) for val in value]) + xmlWriter.simpletag(kBlendDictOpName, value=blendValue) + xmlWriter.newline() + xmlWriter.dedent() + xmlWriter.endtag(name) + xmlWriter.newline() + else: + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + valueString = attrs.get("value", None) + if valueString is None: + value = parseBlendList(content) + else: + value = parseNum(attrs["value"]) + return value + + +class ArrayConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + if value and isinstance(value[0], list): + xmlWriter.begintag(name) + xmlWriter.newline() + xmlWriter.indent() + for valueList in value: + blendValue = " ".join([str(val) for val in valueList]) + xmlWriter.simpletag(kBlendDictOpName, value=blendValue) + xmlWriter.newline() + xmlWriter.dedent() + xmlWriter.endtag(name) + xmlWriter.newline() + else: + value = " ".join([str(val) for val in value]) + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + valueString = attrs.get("value", None) + if valueString is None: + valueList = parseBlendList(content) + else: + values = valueString.split() + valueList = [parseNum(value) for value in values] + return valueList + + +class TableConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.begintag(name) + xmlWriter.newline() + value.toXML(xmlWriter) + xmlWriter.endtag(name) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + ob = self.getClass()() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + ob.fromXML(name, attrs, content) + return ob + + +class PrivateDictConverter(TableConverter): + def getClass(self): + return PrivateDict + + def _read(self, parent, value): + size, offset = value + file = parent.file + isCFF2 = parent._isCFF2 + try: + vstore = parent.vstore + except AttributeError: + vstore = None + priv = PrivateDict(parent.strings, file, offset, isCFF2=isCFF2, vstore=vstore) + file.seek(offset) + data = file.read(size) + assert len(data) == size + priv.decompile(data) + return priv + + def write(self, parent, value): + return (0, 0) # dummy value + + +class SubrsConverter(TableConverter): + def getClass(self): + return SubrsIndex + + def _read(self, parent, value): + file = parent.file + isCFF2 = parent._isCFF2 + file.seek(parent.offset + value) # Offset(self) + return SubrsIndex(file, isCFF2=isCFF2) + + def write(self, parent, value): + return 0 # dummy value + + +class CharStringsConverter(TableConverter): + def _read(self, parent, value): + file = parent.file + isCFF2 = parent._isCFF2 + charset = parent.charset + varStore = getattr(parent, "VarStore", None) + globalSubrs = parent.GlobalSubrs + if hasattr(parent, "FDArray"): + fdArray = parent.FDArray + if hasattr(parent, "FDSelect"): + fdSelect = parent.FDSelect + else: + fdSelect = None + private = None + else: + fdSelect, fdArray = None, None + private = parent.Private + file.seek(value) # Offset(0) + charStrings = CharStrings( + file, + charset, + globalSubrs, + private, + fdSelect, + fdArray, + isCFF2=isCFF2, + varStore=varStore, + ) + return charStrings + + def write(self, parent, value): + return 0 # dummy value + + def xmlRead(self, name, attrs, content, parent): + if hasattr(parent, "FDArray"): + # if it is a CID-keyed font, then the private Dict is extracted from the + # parent.FDArray + fdArray = parent.FDArray + if hasattr(parent, "FDSelect"): + fdSelect = parent.FDSelect + else: + fdSelect = None + private = None + else: + # if it is a name-keyed font, then the private dict is in the top dict, + # and + # there is no fdArray. + private, fdSelect, fdArray = parent.Private, None, None + charStrings = CharStrings( + None, + None, + parent.GlobalSubrs, + private, + fdSelect, + fdArray, + varStore=getattr(parent, "VarStore", None), + ) + charStrings.fromXML(name, attrs, content) + return charStrings + + +class CharsetConverter(SimpleConverter): + def _read(self, parent, value): + isCID = hasattr(parent, "ROS") + if value > 2: + numGlyphs = parent.numGlyphs + file = parent.file + file.seek(value) + log.log(DEBUG, "loading charset at %s", value) + format = readCard8(file) + if format == 0: + charset = parseCharset0(numGlyphs, file, parent.strings, isCID) + elif format == 1 or format == 2: + charset = parseCharset(numGlyphs, file, parent.strings, isCID, format) + else: + raise NotImplementedError + assert len(charset) == numGlyphs + log.log(DEBUG, " charset end at %s", file.tell()) + # make sure glyph names are unique + allNames = {} + newCharset = [] + for glyphName in charset: + if glyphName in allNames: + # make up a new glyphName that's unique + n = allNames[glyphName] + while (glyphName + "#" + str(n)) in allNames: + n += 1 + allNames[glyphName] = n + 1 + glyphName = glyphName + "#" + str(n) + allNames[glyphName] = 1 + newCharset.append(glyphName) + charset = newCharset + else: # offset == 0 -> no charset data. + if isCID or "CharStrings" not in parent.rawDict: + # We get here only when processing fontDicts from the FDArray of + # CFF-CID fonts. Only the real topDict references the chrset. + assert value == 0 + charset = None + elif value == 0: + charset = cffISOAdobeStrings + elif value == 1: + charset = cffIExpertStrings + elif value == 2: + charset = cffExpertSubsetStrings + if charset and (len(charset) != parent.numGlyphs): + charset = charset[: parent.numGlyphs] + return charset + + def write(self, parent, value): + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + # XXX only write charset when not in OT/TTX context, where we + # dump charset as a separate "GlyphOrder" table. + # # xmlWriter.simpletag("charset") + xmlWriter.comment("charset is dumped separately as the 'GlyphOrder' element") + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + pass + + +class CharsetCompiler(object): + def __init__(self, strings, charset, parent): + assert charset[0] == ".notdef" + isCID = hasattr(parent.dictObj, "ROS") + data0 = packCharset0(charset, isCID, strings) + data = packCharset(charset, isCID, strings) + if len(data) < len(data0): + self.data = data + else: + self.data = data0 + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["charset"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +def getStdCharSet(charset): + # check to see if we can use a predefined charset value. + predefinedCharSetVal = None + predefinedCharSets = [ + (cffISOAdobeStringCount, cffISOAdobeStrings, 0), + (cffExpertStringCount, cffIExpertStrings, 1), + (cffExpertSubsetStringCount, cffExpertSubsetStrings, 2), + ] + lcs = len(charset) + for cnt, pcs, csv in predefinedCharSets: + if predefinedCharSetVal is not None: + break + if lcs > cnt: + continue + predefinedCharSetVal = csv + for i in range(lcs): + if charset[i] != pcs[i]: + predefinedCharSetVal = None + break + return predefinedCharSetVal + + +def getCIDfromName(name, strings): + return int(name[3:]) + + +def getSIDfromName(name, strings): + return strings.getSID(name) + + +def packCharset0(charset, isCID, strings): + fmt = 0 + data = [packCard8(fmt)] + if isCID: + getNameID = getCIDfromName + else: + getNameID = getSIDfromName + + for name in charset[1:]: + data.append(packCard16(getNameID(name, strings))) + return bytesjoin(data) + + +def packCharset(charset, isCID, strings): + fmt = 1 + ranges = [] + first = None + end = 0 + if isCID: + getNameID = getCIDfromName + else: + getNameID = getSIDfromName + + for name in charset[1:]: + SID = getNameID(name, strings) + if first is None: + first = SID + elif end + 1 != SID: + nLeft = end - first + if nLeft > 255: + fmt = 2 + ranges.append((first, nLeft)) + first = SID + end = SID + if end: + nLeft = end - first + if nLeft > 255: + fmt = 2 + ranges.append((first, nLeft)) + + data = [packCard8(fmt)] + if fmt == 1: + nLeftFunc = packCard8 + else: + nLeftFunc = packCard16 + for first, nLeft in ranges: + data.append(packCard16(first) + nLeftFunc(nLeft)) + return bytesjoin(data) + + +def parseCharset0(numGlyphs, file, strings, isCID): + charset = [".notdef"] + if isCID: + for i in range(numGlyphs - 1): + CID = readCard16(file) + charset.append("cid" + str(CID).zfill(5)) + else: + for i in range(numGlyphs - 1): + SID = readCard16(file) + charset.append(strings[SID]) + return charset + + +def parseCharset(numGlyphs, file, strings, isCID, fmt): + charset = [".notdef"] + count = 1 + if fmt == 1: + nLeftFunc = readCard8 + else: + nLeftFunc = readCard16 + while count < numGlyphs: + first = readCard16(file) + nLeft = nLeftFunc(file) + if isCID: + for CID in range(first, first + nLeft + 1): + charset.append("cid" + str(CID).zfill(5)) + else: + for SID in range(first, first + nLeft + 1): + charset.append(strings[SID]) + count = count + nLeft + 1 + return charset + + +class EncodingCompiler(object): + def __init__(self, strings, encoding, parent): + assert not isinstance(encoding, str) + data0 = packEncoding0(parent.dictObj.charset, encoding, parent.strings) + data1 = packEncoding1(parent.dictObj.charset, encoding, parent.strings) + if len(data0) < len(data1): + self.data = data0 + else: + self.data = data1 + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["Encoding"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class EncodingConverter(SimpleConverter): + def _read(self, parent, value): + if value == 0: + return "StandardEncoding" + elif value == 1: + return "ExpertEncoding" + else: + assert value > 1 + file = parent.file + file.seek(value) + log.log(DEBUG, "loading Encoding at %s", value) + fmt = readCard8(file) + haveSupplement = fmt & 0x80 + if haveSupplement: + raise NotImplementedError("Encoding supplements are not yet supported") + fmt = fmt & 0x7F + if fmt == 0: + encoding = parseEncoding0( + parent.charset, file, haveSupplement, parent.strings + ) + elif fmt == 1: + encoding = parseEncoding1( + parent.charset, file, haveSupplement, parent.strings + ) + return encoding + + def write(self, parent, value): + if value == "StandardEncoding": + return 0 + elif value == "ExpertEncoding": + return 1 + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + if value in ("StandardEncoding", "ExpertEncoding"): + xmlWriter.simpletag(name, name=value) + xmlWriter.newline() + return + xmlWriter.begintag(name) + xmlWriter.newline() + for code in range(len(value)): + glyphName = value[code] + if glyphName != ".notdef": + xmlWriter.simpletag("map", code=hex(code), name=glyphName) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + if "name" in attrs: + return attrs["name"] + encoding = [".notdef"] * 256 + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + code = safeEval(attrs["code"]) + glyphName = attrs["name"] + encoding[code] = glyphName + return encoding + + +def parseEncoding0(charset, file, haveSupplement, strings): + nCodes = readCard8(file) + encoding = [".notdef"] * 256 + for glyphID in range(1, nCodes + 1): + code = readCard8(file) + if code != 0: + encoding[code] = charset[glyphID] + return encoding + + +def parseEncoding1(charset, file, haveSupplement, strings): + nRanges = readCard8(file) + encoding = [".notdef"] * 256 + glyphID = 1 + for i in range(nRanges): + code = readCard8(file) + nLeft = readCard8(file) + for glyphID in range(glyphID, glyphID + nLeft + 1): + encoding[code] = charset[glyphID] + code = code + 1 + glyphID = glyphID + 1 + return encoding + + +def packEncoding0(charset, encoding, strings): + fmt = 0 + m = {} + for code in range(len(encoding)): + name = encoding[code] + if name != ".notdef": + m[name] = code + codes = [] + for name in charset[1:]: + code = m.get(name) + codes.append(code) + + while codes and codes[-1] is None: + codes.pop() + + data = [packCard8(fmt), packCard8(len(codes))] + for code in codes: + if code is None: + code = 0 + data.append(packCard8(code)) + return bytesjoin(data) + + +def packEncoding1(charset, encoding, strings): + fmt = 1 + m = {} + for code in range(len(encoding)): + name = encoding[code] + if name != ".notdef": + m[name] = code + ranges = [] + first = None + end = 0 + for name in charset[1:]: + code = m.get(name, -1) + if first is None: + first = code + elif end + 1 != code: + nLeft = end - first + ranges.append((first, nLeft)) + first = code + end = code + nLeft = end - first + ranges.append((first, nLeft)) + + # remove unencoded glyphs at the end. + while ranges and ranges[-1][0] == -1: + ranges.pop() + + data = [packCard8(fmt), packCard8(len(ranges))] + for first, nLeft in ranges: + if first == -1: # unencoded + first = 0 + data.append(packCard8(first) + packCard8(nLeft)) + return bytesjoin(data) + + +class FDArrayConverter(TableConverter): + def _read(self, parent, value): + try: + vstore = parent.VarStore + except AttributeError: + vstore = None + file = parent.file + isCFF2 = parent._isCFF2 + file.seek(value) + fdArray = FDArrayIndex(file, isCFF2=isCFF2) + fdArray.vstore = vstore + fdArray.strings = parent.strings + fdArray.GlobalSubrs = parent.GlobalSubrs + return fdArray + + def write(self, parent, value): + return 0 # dummy value + + def xmlRead(self, name, attrs, content, parent): + fdArray = FDArrayIndex() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + fdArray.fromXML(name, attrs, content) + return fdArray + + +class FDSelectConverter(SimpleConverter): + def _read(self, parent, value): + file = parent.file + file.seek(value) + fdSelect = FDSelect(file, parent.numGlyphs) + return fdSelect + + def write(self, parent, value): + return 0 # dummy value + + # The FDSelect glyph data is written out to XML in the charstring keys, + # so we write out only the format selector + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, [("format", value.format)]) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + fmt = safeEval(attrs["format"]) + file = None + numGlyphs = None + fdSelect = FDSelect(file, numGlyphs, fmt) + return fdSelect + + +class VarStoreConverter(SimpleConverter): + def _read(self, parent, value): + file = parent.file + file.seek(value) + varStore = VarStoreData(file) + varStore.decompile() + return varStore + + def write(self, parent, value): + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + value.writeXML(xmlWriter, name) + + def xmlRead(self, name, attrs, content, parent): + varStore = VarStoreData() + varStore.xmlRead(name, attrs, content, parent) + return varStore + + +def packFDSelect0(fdSelectArray): + fmt = 0 + data = [packCard8(fmt)] + for index in fdSelectArray: + data.append(packCard8(index)) + return bytesjoin(data) + + +def packFDSelect3(fdSelectArray): + fmt = 3 + fdRanges = [] + lenArray = len(fdSelectArray) + lastFDIndex = -1 + for i in range(lenArray): + fdIndex = fdSelectArray[i] + if lastFDIndex != fdIndex: + fdRanges.append([i, fdIndex]) + lastFDIndex = fdIndex + sentinelGID = i + 1 + + data = [packCard8(fmt)] + data.append(packCard16(len(fdRanges))) + for fdRange in fdRanges: + data.append(packCard16(fdRange[0])) + data.append(packCard8(fdRange[1])) + data.append(packCard16(sentinelGID)) + return bytesjoin(data) + + +def packFDSelect4(fdSelectArray): + fmt = 4 + fdRanges = [] + lenArray = len(fdSelectArray) + lastFDIndex = -1 + for i in range(lenArray): + fdIndex = fdSelectArray[i] + if lastFDIndex != fdIndex: + fdRanges.append([i, fdIndex]) + lastFDIndex = fdIndex + sentinelGID = i + 1 + + data = [packCard8(fmt)] + data.append(packCard32(len(fdRanges))) + for fdRange in fdRanges: + data.append(packCard32(fdRange[0])) + data.append(packCard16(fdRange[1])) + data.append(packCard32(sentinelGID)) + return bytesjoin(data) + + +class FDSelectCompiler(object): + def __init__(self, fdSelect, parent): + fmt = fdSelect.format + fdSelectArray = fdSelect.gidArray + if fmt == 0: + self.data = packFDSelect0(fdSelectArray) + elif fmt == 3: + self.data = packFDSelect3(fdSelectArray) + elif fmt == 4: + self.data = packFDSelect4(fdSelectArray) + else: + # choose smaller of the two formats + data0 = packFDSelect0(fdSelectArray) + data3 = packFDSelect3(fdSelectArray) + if len(data0) < len(data3): + self.data = data0 + fdSelect.format = 0 + else: + self.data = data3 + fdSelect.format = 3 + + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["FDSelect"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class VarStoreCompiler(object): + def __init__(self, varStoreData, parent): + self.parent = parent + if not varStoreData.data: + varStoreData.compile() + data = [packCard16(len(varStoreData.data)), varStoreData.data] + self.data = bytesjoin(data) + + def setPos(self, pos, endPos): + self.parent.rawDict["VarStore"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class ROSConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + registry, order, supplement = value + xmlWriter.simpletag( + name, + [ + ("Registry", tostr(registry)), + ("Order", tostr(order)), + ("Supplement", supplement), + ], + ) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return (attrs["Registry"], attrs["Order"], safeEval(attrs["Supplement"])) + + +topDictOperators = [ + # opcode name argument type default converter + (25, "maxstack", "number", None, None), + ((12, 30), "ROS", ("SID", "SID", "number"), None, ROSConverter()), + ((12, 20), "SyntheticBase", "number", None, None), + (0, "version", "SID", None, None), + (1, "Notice", "SID", None, Latin1Converter()), + ((12, 0), "Copyright", "SID", None, Latin1Converter()), + (2, "FullName", "SID", None, Latin1Converter()), + ((12, 38), "FontName", "SID", None, Latin1Converter()), + (3, "FamilyName", "SID", None, Latin1Converter()), + (4, "Weight", "SID", None, None), + ((12, 1), "isFixedPitch", "number", 0, None), + ((12, 2), "ItalicAngle", "number", 0, None), + ((12, 3), "UnderlinePosition", "number", -100, None), + ((12, 4), "UnderlineThickness", "number", 50, None), + ((12, 5), "PaintType", "number", 0, None), + ((12, 6), "CharstringType", "number", 2, None), + ((12, 7), "FontMatrix", "array", [0.001, 0, 0, 0.001, 0, 0], None), + (13, "UniqueID", "number", None, None), + (5, "FontBBox", "array", [0, 0, 0, 0], None), + ((12, 8), "StrokeWidth", "number", 0, None), + (14, "XUID", "array", None, None), + ((12, 21), "PostScript", "SID", None, None), + ((12, 22), "BaseFontName", "SID", None, None), + ((12, 23), "BaseFontBlend", "delta", None, None), + ((12, 31), "CIDFontVersion", "number", 0, None), + ((12, 32), "CIDFontRevision", "number", 0, None), + ((12, 33), "CIDFontType", "number", 0, None), + ((12, 34), "CIDCount", "number", 8720, None), + (15, "charset", "number", None, CharsetConverter()), + ((12, 35), "UIDBase", "number", None, None), + (16, "Encoding", "number", 0, EncodingConverter()), + (18, "Private", ("number", "number"), None, PrivateDictConverter()), + ((12, 37), "FDSelect", "number", None, FDSelectConverter()), + ((12, 36), "FDArray", "number", None, FDArrayConverter()), + (17, "CharStrings", "number", None, CharStringsConverter()), + (24, "VarStore", "number", None, VarStoreConverter()), +] + +topDictOperators2 = [ + # opcode name argument type default converter + (25, "maxstack", "number", None, None), + ((12, 7), "FontMatrix", "array", [0.001, 0, 0, 0.001, 0, 0], None), + ((12, 37), "FDSelect", "number", None, FDSelectConverter()), + ((12, 36), "FDArray", "number", None, FDArrayConverter()), + (17, "CharStrings", "number", None, CharStringsConverter()), + (24, "VarStore", "number", None, VarStoreConverter()), +] + +# Note! FDSelect and FDArray must both preceed CharStrings in the output XML build order, +# in order for the font to compile back from xml. + +kBlendDictOpName = "blend" +blendOp = 23 + +privateDictOperators = [ + # opcode name argument type default converter + (22, "vsindex", "number", None, None), + ( + blendOp, + kBlendDictOpName, + "blendList", + None, + None, + ), # This is for reading to/from XML: it not written to CFF. + (6, "BlueValues", "delta", None, None), + (7, "OtherBlues", "delta", None, None), + (8, "FamilyBlues", "delta", None, None), + (9, "FamilyOtherBlues", "delta", None, None), + ((12, 9), "BlueScale", "number", 0.039625, None), + ((12, 10), "BlueShift", "number", 7, None), + ((12, 11), "BlueFuzz", "number", 1, None), + (10, "StdHW", "number", None, None), + (11, "StdVW", "number", None, None), + ((12, 12), "StemSnapH", "delta", None, None), + ((12, 13), "StemSnapV", "delta", None, None), + ((12, 14), "ForceBold", "number", 0, None), + ((12, 15), "ForceBoldThreshold", "number", None, None), # deprecated + ((12, 16), "lenIV", "number", None, None), # deprecated + ((12, 17), "LanguageGroup", "number", 0, None), + ((12, 18), "ExpansionFactor", "number", 0.06, None), + ((12, 19), "initialRandomSeed", "number", 0, None), + (20, "defaultWidthX", "number", 0, None), + (21, "nominalWidthX", "number", 0, None), + (19, "Subrs", "number", None, SubrsConverter()), +] + +privateDictOperators2 = [ + # opcode name argument type default converter + (22, "vsindex", "number", None, None), + ( + blendOp, + kBlendDictOpName, + "blendList", + None, + None, + ), # This is for reading to/from XML: it not written to CFF. + (6, "BlueValues", "delta", None, None), + (7, "OtherBlues", "delta", None, None), + (8, "FamilyBlues", "delta", None, None), + (9, "FamilyOtherBlues", "delta", None, None), + ((12, 9), "BlueScale", "number", 0.039625, None), + ((12, 10), "BlueShift", "number", 7, None), + ((12, 11), "BlueFuzz", "number", 1, None), + (10, "StdHW", "number", None, None), + (11, "StdVW", "number", None, None), + ((12, 12), "StemSnapH", "delta", None, None), + ((12, 13), "StemSnapV", "delta", None, None), + ((12, 17), "LanguageGroup", "number", 0, None), + ((12, 18), "ExpansionFactor", "number", 0.06, None), + (19, "Subrs", "number", None, SubrsConverter()), +] + + +def addConverters(table): + for i in range(len(table)): + op, name, arg, default, conv = table[i] + if conv is not None: + continue + if arg in ("delta", "array"): + conv = ArrayConverter() + elif arg == "number": + conv = NumberConverter() + elif arg == "SID": + conv = ASCIIConverter() + elif arg == "blendList": + conv = None + else: + assert False + table[i] = op, name, arg, default, conv + + +addConverters(privateDictOperators) +addConverters(topDictOperators) + + +class TopDictDecompiler(psCharStrings.DictDecompiler): + operators = buildOperatorDict(topDictOperators) + + +class PrivateDictDecompiler(psCharStrings.DictDecompiler): + operators = buildOperatorDict(privateDictOperators) + + +class DictCompiler(object): + maxBlendStack = 0 + + def __init__(self, dictObj, strings, parent, isCFF2=None): + if strings: + assert isinstance(strings, IndexedStrings) + if isCFF2 is None and hasattr(parent, "isCFF2"): + isCFF2 = parent.isCFF2 + assert isCFF2 is not None + self.isCFF2 = isCFF2 + self.dictObj = dictObj + self.strings = strings + self.parent = parent + rawDict = {} + for name in dictObj.order: + value = getattr(dictObj, name, None) + if value is None: + continue + conv = dictObj.converters[name] + value = conv.write(dictObj, value) + if value == dictObj.defaults.get(name): + continue + rawDict[name] = value + self.rawDict = rawDict + + def setPos(self, pos, endPos): + pass + + def getDataLength(self): + return len(self.compile("getDataLength")) + + def compile(self, reason): + log.log(DEBUG, "-- compiling %s for %s", self.__class__.__name__, reason) + rawDict = self.rawDict + data = [] + for name in self.dictObj.order: + value = rawDict.get(name) + if value is None: + continue + op, argType = self.opcodes[name] + if isinstance(argType, tuple): + l = len(argType) + assert len(value) == l, "value doesn't match arg type" + for i in range(l): + arg = argType[i] + v = value[i] + arghandler = getattr(self, "arg_" + arg) + data.append(arghandler(v)) + else: + arghandler = getattr(self, "arg_" + argType) + data.append(arghandler(value)) + data.append(op) + data = bytesjoin(data) + return data + + def toFile(self, file): + data = self.compile("toFile") + file.write(data) + + def arg_number(self, num): + if isinstance(num, list): + data = [encodeNumber(val) for val in num] + data.append(encodeNumber(1)) + data.append(bytechr(blendOp)) + datum = bytesjoin(data) + else: + datum = encodeNumber(num) + return datum + + def arg_SID(self, s): + return psCharStrings.encodeIntCFF(self.strings.getSID(s)) + + def arg_array(self, value): + data = [] + for num in value: + data.append(self.arg_number(num)) + return bytesjoin(data) + + def arg_delta(self, value): + if not value: + return b"" + val0 = value[0] + if isinstance(val0, list): + data = self.arg_delta_blend(value) + else: + out = [] + last = 0 + for v in value: + out.append(v - last) + last = v + data = [] + for num in out: + data.append(encodeNumber(num)) + return bytesjoin(data) + + def arg_delta_blend(self, value): + """A delta list with blend lists has to be *all* blend lists. + + The value is a list is arranged as follows:: + + [ + [V0, d0..dn] + [V1, d0..dn] + ... + [Vm, d0..dn] + ] + + ``V`` is the absolute coordinate value from the default font, and ``d0-dn`` + are the delta values from the *n* regions. Each ``V`` is an absolute + coordinate from the default font. + + We want to return a list:: + + [ + [v0, v1..vm] + [d0..dn] + ... + [d0..dn] + numBlends + blendOp + ] + + where each ``v`` is relative to the previous default font value. + """ + numMasters = len(value[0]) + numBlends = len(value) + numStack = (numBlends * numMasters) + 1 + if numStack > self.maxBlendStack: + # Figure out the max number of value we can blend + # and divide this list up into chunks of that size. + + numBlendValues = int((self.maxBlendStack - 1) / numMasters) + out = [] + while True: + numVal = min(len(value), numBlendValues) + if numVal == 0: + break + valList = value[0:numVal] + out1 = self.arg_delta_blend(valList) + out.extend(out1) + value = value[numVal:] + else: + firstList = [0] * numBlends + deltaList = [None] * numBlends + i = 0 + prevVal = 0 + while i < numBlends: + # For PrivateDict BlueValues, the default font + # values are absolute, not relative. + # Must convert these back to relative coordinates + # befor writing to CFF2. + defaultValue = value[i][0] + firstList[i] = defaultValue - prevVal + prevVal = defaultValue + deltaList[i] = value[i][1:] + i += 1 + + relValueList = firstList + for blendList in deltaList: + relValueList.extend(blendList) + out = [encodeNumber(val) for val in relValueList] + out.append(encodeNumber(numBlends)) + out.append(bytechr(blendOp)) + return out + + +def encodeNumber(num): + if isinstance(num, float): + return psCharStrings.encodeFloat(num) + else: + return psCharStrings.encodeIntCFF(num) + + +class TopDictCompiler(DictCompiler): + opcodes = buildOpcodeDict(topDictOperators) + + def getChildren(self, strings): + isCFF2 = self.isCFF2 + children = [] + if self.dictObj.cff2GetGlyphOrder is None: + if hasattr(self.dictObj, "charset") and self.dictObj.charset: + if hasattr(self.dictObj, "ROS"): # aka isCID + charsetCode = None + else: + charsetCode = getStdCharSet(self.dictObj.charset) + if charsetCode is None: + children.append( + CharsetCompiler(strings, self.dictObj.charset, self) + ) + else: + self.rawDict["charset"] = charsetCode + if hasattr(self.dictObj, "Encoding") and self.dictObj.Encoding: + encoding = self.dictObj.Encoding + if not isinstance(encoding, str): + children.append(EncodingCompiler(strings, encoding, self)) + else: + if hasattr(self.dictObj, "VarStore"): + varStoreData = self.dictObj.VarStore + varStoreComp = VarStoreCompiler(varStoreData, self) + children.append(varStoreComp) + if hasattr(self.dictObj, "FDSelect"): + # I have not yet supported merging a ttx CFF-CID font, as there are + # interesting issues about merging the FDArrays. Here I assume that + # either the font was read from XML, and the FDSelect indices are all + # in the charstring data, or the FDSelect array is already fully defined. + fdSelect = self.dictObj.FDSelect + # probably read in from XML; assume fdIndex in CharString data + if len(fdSelect) == 0: + charStrings = self.dictObj.CharStrings + for name in self.dictObj.charset: + fdSelect.append(charStrings[name].fdSelectIndex) + fdSelectComp = FDSelectCompiler(fdSelect, self) + children.append(fdSelectComp) + if hasattr(self.dictObj, "CharStrings"): + items = [] + charStrings = self.dictObj.CharStrings + for name in self.dictObj.charset: + items.append(charStrings[name]) + charStringsComp = CharStringsCompiler(items, strings, self, isCFF2=isCFF2) + children.append(charStringsComp) + if hasattr(self.dictObj, "FDArray"): + # I have not yet supported merging a ttx CFF-CID font, as there are + # interesting issues about merging the FDArrays. Here I assume that the + # FDArray info is correct and complete. + fdArrayIndexComp = self.dictObj.FDArray.getCompiler(strings, self) + children.append(fdArrayIndexComp) + children.extend(fdArrayIndexComp.getChildren(strings)) + if hasattr(self.dictObj, "Private"): + privComp = self.dictObj.Private.getCompiler(strings, self) + children.append(privComp) + children.extend(privComp.getChildren(strings)) + return children + + +class FontDictCompiler(DictCompiler): + opcodes = buildOpcodeDict(topDictOperators) + + def __init__(self, dictObj, strings, parent, isCFF2=None): + super(FontDictCompiler, self).__init__(dictObj, strings, parent, isCFF2=isCFF2) + # + # We now take some effort to detect if there were any key/value pairs + # supplied that were ignored in the FontDict context, and issue a warning + # for those cases. + # + ignoredNames = [] + dictObj = self.dictObj + for name in sorted(set(dictObj.converters) - set(dictObj.order)): + if name in dictObj.rawDict: + # The font was directly read from binary. In this + # case, we want to report *all* "useless" key/value + # pairs that are in the font, not just the ones that + # are different from the default. + ignoredNames.append(name) + else: + # The font was probably read from a TTX file. We only + # warn about keys whos value is not the default. The + # ones that have the default value will not be written + # to binary anyway. + default = dictObj.defaults.get(name) + if default is not None: + conv = dictObj.converters[name] + default = conv.read(dictObj, default) + if getattr(dictObj, name, None) != default: + ignoredNames.append(name) + if ignoredNames: + log.warning( + "Some CFF FDArray/FontDict keys were ignored upon compile: " + + " ".join(sorted(ignoredNames)) + ) + + def getChildren(self, strings): + children = [] + if hasattr(self.dictObj, "Private"): + privComp = self.dictObj.Private.getCompiler(strings, self) + children.append(privComp) + children.extend(privComp.getChildren(strings)) + return children + + +class PrivateDictCompiler(DictCompiler): + maxBlendStack = maxStackLimit + opcodes = buildOpcodeDict(privateDictOperators) + + def setPos(self, pos, endPos): + size = endPos - pos + self.parent.rawDict["Private"] = size, pos + self.pos = pos + + def getChildren(self, strings): + children = [] + if hasattr(self.dictObj, "Subrs"): + children.append(self.dictObj.Subrs.getCompiler(strings, self)) + return children + + +class BaseDict(object): + def __init__(self, strings=None, file=None, offset=None, isCFF2=None): + assert (isCFF2 is None) == (file is None) + self.rawDict = {} + self.skipNames = [] + self.strings = strings + if file is None: + return + self._isCFF2 = isCFF2 + self.file = file + if offset is not None: + log.log(DEBUG, "loading %s at %s", self.__class__.__name__, offset) + self.offset = offset + + def decompile(self, data): + log.log(DEBUG, " length %s is %d", self.__class__.__name__, len(data)) + dec = self.decompilerClass(self.strings, self) + dec.decompile(data) + self.rawDict = dec.getDict() + self.postDecompile() + + def postDecompile(self): + pass + + def getCompiler(self, strings, parent, isCFF2=None): + return self.compilerClass(self, strings, parent, isCFF2=isCFF2) + + def __getattr__(self, name): + if name[:2] == name[-2:] == "__": + # to make deepcopy() and pickle.load() work, we need to signal with + # AttributeError that dunder methods like '__deepcopy__' or '__getstate__' + # aren't implemented. For more details, see: + # https://github.com/fonttools/fonttools/pull/1488 + raise AttributeError(name) + value = self.rawDict.get(name, None) + if value is None: + value = self.defaults.get(name) + if value is None: + raise AttributeError(name) + conv = self.converters[name] + value = conv.read(self, value) + setattr(self, name, value) + return value + + def toXML(self, xmlWriter): + for name in self.order: + if name in self.skipNames: + continue + value = getattr(self, name, None) + # XXX For "charset" we never skip calling xmlWrite even if the + # value is None, so we always write the following XML comment: + # + # + # + # Charset is None when 'CFF ' table is imported from XML into an + # empty TTFont(). By writing this comment all the time, we obtain + # the same XML output whether roundtripping XML-to-XML or + # dumping binary-to-XML + if value is None and name != "charset": + continue + conv = self.converters[name] + conv.xmlWrite(xmlWriter, name, value) + ignoredNames = set(self.rawDict) - set(self.order) + if ignoredNames: + xmlWriter.comment( + "some keys were ignored: %s" % " ".join(sorted(ignoredNames)) + ) + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + conv = self.converters[name] + value = conv.xmlRead(name, attrs, content, self) + setattr(self, name, value) + + +class TopDict(BaseDict): + """The ``TopDict`` represents the top-level dictionary holding font + information. CFF2 tables contain a restricted set of top-level entries + as described `here `_, + but CFF tables may contain a wider range of information. This information + can be accessed through attributes or through the dictionary returned + through the ``rawDict`` property: + + .. code:: python + + font = tt["CFF "].cff[0] + font.FamilyName + # 'Linux Libertine O' + font.rawDict["FamilyName"] + # 'Linux Libertine O' + + More information is available in the CFF file's private dictionary, accessed + via the ``Private`` property: + + .. code:: python + + tt["CFF "].cff[0].Private.BlueValues + # [-15, 0, 515, 515, 666, 666] + + """ + + defaults = buildDefaults(topDictOperators) + converters = buildConverters(topDictOperators) + compilerClass = TopDictCompiler + order = buildOrder(topDictOperators) + decompilerClass = TopDictDecompiler + + def __init__( + self, + strings=None, + file=None, + offset=None, + GlobalSubrs=None, + cff2GetGlyphOrder=None, + isCFF2=None, + ): + super(TopDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.cff2GetGlyphOrder = cff2GetGlyphOrder + self.GlobalSubrs = GlobalSubrs + if isCFF2: + self.defaults = buildDefaults(topDictOperators2) + self.charset = cff2GetGlyphOrder() + self.order = buildOrder(topDictOperators2) + else: + self.defaults = buildDefaults(topDictOperators) + self.order = buildOrder(topDictOperators) + + def getGlyphOrder(self): + """Returns a list of glyph names in the CFF font.""" + return self.charset + + def postDecompile(self): + offset = self.rawDict.get("CharStrings") + if offset is None: + return + # get the number of glyphs beforehand. + self.file.seek(offset) + if self._isCFF2: + self.numGlyphs = readCard32(self.file) + else: + self.numGlyphs = readCard16(self.file) + + def toXML(self, xmlWriter): + if hasattr(self, "CharStrings"): + self.decompileAllCharStrings() + if hasattr(self, "ROS"): + self.skipNames = ["Encoding"] + if not hasattr(self, "ROS") or not hasattr(self, "CharStrings"): + # these values have default values, but I only want them to show up + # in CID fonts. + self.skipNames = [ + "CIDFontVersion", + "CIDFontRevision", + "CIDFontType", + "CIDCount", + ] + BaseDict.toXML(self, xmlWriter) + + def decompileAllCharStrings(self): + # Make sure that all the Private Dicts have been instantiated. + for i, charString in enumerate(self.CharStrings.values()): + try: + charString.decompile() + except: + log.error("Error in charstring %s", i) + raise + + def recalcFontBBox(self): + fontBBox = None + for charString in self.CharStrings.values(): + bounds = charString.calcBounds(self.CharStrings) + if bounds is not None: + if fontBBox is not None: + fontBBox = unionRect(fontBBox, bounds) + else: + fontBBox = bounds + + if fontBBox is None: + self.FontBBox = self.defaults["FontBBox"][:] + else: + self.FontBBox = list(intRect(fontBBox)) + + +class FontDict(BaseDict): + # + # Since fonttools used to pass a lot of fields that are not relevant in the FDArray + # FontDict, there are 'ttx' files in the wild that contain all these. These got in + # the ttx files because fonttools writes explicit values for all the TopDict default + # values. These are not actually illegal in the context of an FDArray FontDict - you + # can legally, per spec, put any arbitrary key/value pair in a FontDict - but are + # useless since current major company CFF interpreters ignore anything but the set + # listed in this file. So, we just silently skip them. An exception is Weight: this + # is not used by any interpreter, but some foundries have asked that this be + # supported in FDArray FontDicts just to preserve information about the design when + # the font is being inspected. + # + # On top of that, there are fonts out there that contain such useless FontDict values. + # + # By subclassing TopDict, we *allow* all key/values from TopDict, both when reading + # from binary or when reading from XML, but by overriding `order` with a limited + # list of names, we ensure that only the useful names ever get exported to XML and + # ever get compiled into the binary font. + # + # We override compilerClass so we can warn about "useless" key/value pairs, either + # from the original binary font or from TTX input. + # + # See: + # - https://github.com/fonttools/fonttools/issues/740 + # - https://github.com/fonttools/fonttools/issues/601 + # - https://github.com/adobe-type-tools/afdko/issues/137 + # + defaults = {} + converters = buildConverters(topDictOperators) + compilerClass = FontDictCompiler + orderCFF = ["FontName", "FontMatrix", "Weight", "Private"] + orderCFF2 = ["Private"] + decompilerClass = TopDictDecompiler + + def __init__( + self, + strings=None, + file=None, + offset=None, + GlobalSubrs=None, + isCFF2=None, + vstore=None, + ): + super(FontDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.vstore = vstore + self.setCFF2(isCFF2) + + def setCFF2(self, isCFF2): + # isCFF2 may be None. + if isCFF2: + self.order = self.orderCFF2 + self._isCFF2 = True + else: + self.order = self.orderCFF + self._isCFF2 = False + + +class PrivateDict(BaseDict): + defaults = buildDefaults(privateDictOperators) + converters = buildConverters(privateDictOperators) + order = buildOrder(privateDictOperators) + decompilerClass = PrivateDictDecompiler + compilerClass = PrivateDictCompiler + + def __init__(self, strings=None, file=None, offset=None, isCFF2=None, vstore=None): + super(PrivateDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.vstore = vstore + if isCFF2: + self.defaults = buildDefaults(privateDictOperators2) + self.order = buildOrder(privateDictOperators2) + # Provide dummy values. This avoids needing to provide + # an isCFF2 state in a lot of places. + self.nominalWidthX = self.defaultWidthX = None + else: + self.defaults = buildDefaults(privateDictOperators) + self.order = buildOrder(privateDictOperators) + + @property + def in_cff2(self): + return self._isCFF2 + + def getNumRegions(self, vi=None): # called from misc/psCharStrings.py + # if getNumRegions is being called, we can assume that VarStore exists. + if vi is None: + if hasattr(self, "vsindex"): + vi = self.vsindex + else: + vi = 0 + numRegions = self.vstore.getNumRegions(vi) + return numRegions + + +class IndexedStrings(object): + + """SID -> string mapping.""" + + def __init__(self, file=None): + if file is None: + strings = [] + else: + strings = [tostr(s, encoding="latin1") for s in Index(file, isCFF2=False)] + self.strings = strings + + def getCompiler(self): + return IndexedStringsCompiler(self, None, self, isCFF2=False) + + def __len__(self): + return len(self.strings) + + def __getitem__(self, SID): + if SID < cffStandardStringCount: + return cffStandardStrings[SID] + else: + return self.strings[SID - cffStandardStringCount] + + def getSID(self, s): + if not hasattr(self, "stringMapping"): + self.buildStringMapping() + s = tostr(s, encoding="latin1") + if s in cffStandardStringMapping: + SID = cffStandardStringMapping[s] + elif s in self.stringMapping: + SID = self.stringMapping[s] + else: + SID = len(self.strings) + cffStandardStringCount + self.strings.append(s) + self.stringMapping[s] = SID + return SID + + def getStrings(self): + return self.strings + + def buildStringMapping(self): + self.stringMapping = {} + for index in range(len(self.strings)): + self.stringMapping[self.strings[index]] = index + cffStandardStringCount + + +# The 391 Standard Strings as used in the CFF format. +# from Adobe Technical None #5176, version 1.0, 18 March 1998 + +cffStandardStrings = [ + ".notdef", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold", +] + +cffStandardStringCount = 391 +assert len(cffStandardStrings) == cffStandardStringCount +# build reverse mapping +cffStandardStringMapping = {} +for _i in range(cffStandardStringCount): + cffStandardStringMapping[cffStandardStrings[_i]] = _i + +cffISOAdobeStrings = [ + ".notdef", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", +] + +cffISOAdobeStringCount = 229 +assert len(cffISOAdobeStrings) == cffISOAdobeStringCount + +cffIExpertStrings = [ + ".notdef", + "space", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "onequarter", + "onehalf", + "threequarters", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", +] + +cffExpertStringCount = 166 +assert len(cffIExpertStrings) == cffExpertStringCount + +cffExpertSubsetStrings = [ + ".notdef", + "space", + "dollaroldstyle", + "dollarsuperior", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "hyphensuperior", + "colonmonetary", + "onefitted", + "rupiah", + "centoldstyle", + "figuredash", + "hypheninferior", + "onequarter", + "onehalf", + "threequarters", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", +] + +cffExpertSubsetStringCount = 87 +assert len(cffExpertSubsetStrings) == cffExpertSubsetStringCount diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/specializer.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/specializer.py new file mode 100644 index 00000000..efc15af7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/specializer.py @@ -0,0 +1,849 @@ +# -*- coding: utf-8 -*- + +"""T2CharString operator specializer and generalizer. + +PostScript glyph drawing operations can be expressed in multiple different +ways. For example, as well as the ``lineto`` operator, there is also a +``hlineto`` operator which draws a horizontal line, removing the need to +specify a ``dx`` coordinate, and a ``vlineto`` operator which draws a +vertical line, removing the need to specify a ``dy`` coordinate. As well +as decompiling :class:`fontTools.misc.psCharStrings.T2CharString` objects +into lists of operations, this module allows for conversion between general +and specific forms of the operation. + +""" + +from fontTools.cffLib import maxStackLimit + + +def stringToProgram(string): + if isinstance(string, str): + string = string.split() + program = [] + for token in string: + try: + token = int(token) + except ValueError: + try: + token = float(token) + except ValueError: + pass + program.append(token) + return program + + +def programToString(program): + return " ".join(str(x) for x in program) + + +def programToCommands(program, getNumRegions=None): + """Takes a T2CharString program list and returns list of commands. + Each command is a two-tuple of commandname,arg-list. The commandname might + be empty string if no commandname shall be emitted (used for glyph width, + hintmask/cntrmask argument, as well as stray arguments at the end of the + program (🤷). + 'getNumRegions' may be None, or a callable object. It must return the + number of regions. 'getNumRegions' takes a single argument, vsindex. If + the vsindex argument is None, getNumRegions returns the default number + of regions for the charstring, else it returns the numRegions for + the vsindex. + The Charstring may or may not start with a width value. If the first + non-blend operator has an odd number of arguments, then the first argument is + a width, and is popped off. This is complicated with blend operators, as + there may be more than one before the first hint or moveto operator, and each + one reduces several arguments to just one list argument. We have to sum the + number of arguments that are not part of the blend arguments, and all the + 'numBlends' values. We could instead have said that by definition, if there + is a blend operator, there is no width value, since CFF2 Charstrings don't + have width values. I discussed this with Behdad, and we are allowing for an + initial width value in this case because developers may assemble a CFF2 + charstring from CFF Charstrings, which could have width values. + """ + + seenWidthOp = False + vsIndex = None + lenBlendStack = 0 + lastBlendIndex = 0 + commands = [] + stack = [] + it = iter(program) + + for token in it: + if not isinstance(token, str): + stack.append(token) + continue + + if token == "blend": + assert getNumRegions is not None + numSourceFonts = 1 + getNumRegions(vsIndex) + # replace the blend op args on the stack with a single list + # containing all the blend op args. + numBlends = stack[-1] + numBlendArgs = numBlends * numSourceFonts + 1 + # replace first blend op by a list of the blend ops. + stack[-numBlendArgs:] = [stack[-numBlendArgs:]] + lenBlendStack += numBlends + len(stack) - 1 + lastBlendIndex = len(stack) + # if a blend op exists, this is or will be a CFF2 charstring. + continue + + elif token == "vsindex": + vsIndex = stack[-1] + assert type(vsIndex) is int + + elif (not seenWidthOp) and token in { + "hstem", + "hstemhm", + "vstem", + "vstemhm", + "cntrmask", + "hintmask", + "hmoveto", + "vmoveto", + "rmoveto", + "endchar", + }: + seenWidthOp = True + parity = token in {"hmoveto", "vmoveto"} + if lenBlendStack: + # lenBlendStack has the number of args represented by the last blend + # arg and all the preceding args. We need to now add the number of + # args following the last blend arg. + numArgs = lenBlendStack + len(stack[lastBlendIndex:]) + else: + numArgs = len(stack) + if numArgs and (numArgs % 2) ^ parity: + width = stack.pop(0) + commands.append(("", [width])) + + if token in {"hintmask", "cntrmask"}: + if stack: + commands.append(("", stack)) + commands.append((token, [])) + commands.append(("", [next(it)])) + else: + commands.append((token, stack)) + stack = [] + if stack: + commands.append(("", stack)) + return commands + + +def _flattenBlendArgs(args): + token_list = [] + for arg in args: + if isinstance(arg, list): + token_list.extend(arg) + token_list.append("blend") + else: + token_list.append(arg) + return token_list + + +def commandsToProgram(commands): + """Takes a commands list as returned by programToCommands() and converts + it back to a T2CharString program list.""" + program = [] + for op, args in commands: + if any(isinstance(arg, list) for arg in args): + args = _flattenBlendArgs(args) + program.extend(args) + if op: + program.append(op) + return program + + +def _everyN(el, n): + """Group the list el into groups of size n""" + if len(el) % n != 0: + raise ValueError(el) + for i in range(0, len(el), n): + yield el[i : i + n] + + +class _GeneralizerDecombinerCommandsMap(object): + @staticmethod + def rmoveto(args): + if len(args) != 2: + raise ValueError(args) + yield ("rmoveto", args) + + @staticmethod + def hmoveto(args): + if len(args) != 1: + raise ValueError(args) + yield ("rmoveto", [args[0], 0]) + + @staticmethod + def vmoveto(args): + if len(args) != 1: + raise ValueError(args) + yield ("rmoveto", [0, args[0]]) + + @staticmethod + def rlineto(args): + if not args: + raise ValueError(args) + for args in _everyN(args, 2): + yield ("rlineto", args) + + @staticmethod + def hlineto(args): + if not args: + raise ValueError(args) + it = iter(args) + try: + while True: + yield ("rlineto", [next(it), 0]) + yield ("rlineto", [0, next(it)]) + except StopIteration: + pass + + @staticmethod + def vlineto(args): + if not args: + raise ValueError(args) + it = iter(args) + try: + while True: + yield ("rlineto", [0, next(it)]) + yield ("rlineto", [next(it), 0]) + except StopIteration: + pass + + @staticmethod + def rrcurveto(args): + if not args: + raise ValueError(args) + for args in _everyN(args, 6): + yield ("rrcurveto", args) + + @staticmethod + def hhcurveto(args): + if len(args) < 4 or len(args) % 4 > 1: + raise ValueError(args) + if len(args) % 2 == 1: + yield ("rrcurveto", [args[1], args[0], args[2], args[3], args[4], 0]) + args = args[5:] + for args in _everyN(args, 4): + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[3], 0]) + + @staticmethod + def vvcurveto(args): + if len(args) < 4 or len(args) % 4 > 1: + raise ValueError(args) + if len(args) % 2 == 1: + yield ("rrcurveto", [args[0], args[1], args[2], args[3], 0, args[4]]) + args = args[5:] + for args in _everyN(args, 4): + yield ("rrcurveto", [0, args[0], args[1], args[2], 0, args[3]]) + + @staticmethod + def hvcurveto(args): + if len(args) < 4 or len(args) % 8 not in {0, 1, 4, 5}: + raise ValueError(args) + last_args = None + if len(args) % 2 == 1: + lastStraight = len(args) % 8 == 5 + args, last_args = args[:-5], args[-5:] + it = _everyN(args, 4) + try: + while True: + args = next(it) + yield ("rrcurveto", [args[0], 0, args[1], args[2], 0, args[3]]) + args = next(it) + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], 0]) + except StopIteration: + pass + if last_args: + args = last_args + if lastStraight: + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[4], args[3]]) + else: + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], args[4]]) + + @staticmethod + def vhcurveto(args): + if len(args) < 4 or len(args) % 8 not in {0, 1, 4, 5}: + raise ValueError(args) + last_args = None + if len(args) % 2 == 1: + lastStraight = len(args) % 8 == 5 + args, last_args = args[:-5], args[-5:] + it = _everyN(args, 4) + try: + while True: + args = next(it) + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], 0]) + args = next(it) + yield ("rrcurveto", [args[0], 0, args[1], args[2], 0, args[3]]) + except StopIteration: + pass + if last_args: + args = last_args + if lastStraight: + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], args[4]]) + else: + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[4], args[3]]) + + @staticmethod + def rcurveline(args): + if len(args) < 8 or len(args) % 6 != 2: + raise ValueError(args) + args, last_args = args[:-2], args[-2:] + for args in _everyN(args, 6): + yield ("rrcurveto", args) + yield ("rlineto", last_args) + + @staticmethod + def rlinecurve(args): + if len(args) < 8 or len(args) % 2 != 0: + raise ValueError(args) + args, last_args = args[:-6], args[-6:] + for args in _everyN(args, 2): + yield ("rlineto", args) + yield ("rrcurveto", last_args) + + +def _convertBlendOpToArgs(blendList): + # args is list of blend op args. Since we are supporting + # recursive blend op calls, some of these args may also + # be a list of blend op args, and need to be converted before + # we convert the current list. + if any([isinstance(arg, list) for arg in blendList]): + args = [ + i + for e in blendList + for i in (_convertBlendOpToArgs(e) if isinstance(e, list) else [e]) + ] + else: + args = blendList + + # We now know that blendList contains a blend op argument list, even if + # some of the args are lists that each contain a blend op argument list. + # Convert from: + # [default font arg sequence x0,...,xn] + [delta tuple for x0] + ... + [delta tuple for xn] + # to: + # [ [x0] + [delta tuple for x0], + # ..., + # [xn] + [delta tuple for xn] ] + numBlends = args[-1] + # Can't use args.pop() when the args are being used in a nested list + # comprehension. See calling context + args = args[:-1] + + numRegions = len(args) // numBlends - 1 + if not (numBlends * (numRegions + 1) == len(args)): + raise ValueError(blendList) + + defaultArgs = [[arg] for arg in args[:numBlends]] + deltaArgs = args[numBlends:] + numDeltaValues = len(deltaArgs) + deltaList = [ + deltaArgs[i : i + numRegions] for i in range(0, numDeltaValues, numRegions) + ] + blend_args = [a + b + [1] for a, b in zip(defaultArgs, deltaList)] + return blend_args + + +def generalizeCommands(commands, ignoreErrors=False): + result = [] + mapping = _GeneralizerDecombinerCommandsMap + for op, args in commands: + # First, generalize any blend args in the arg list. + if any([isinstance(arg, list) for arg in args]): + try: + args = [ + n + for arg in args + for n in ( + _convertBlendOpToArgs(arg) if isinstance(arg, list) else [arg] + ) + ] + except ValueError: + if ignoreErrors: + # Store op as data, such that consumers of commands do not have to + # deal with incorrect number of arguments. + result.append(("", args)) + result.append(("", [op])) + else: + raise + + func = getattr(mapping, op, None) + if not func: + result.append((op, args)) + continue + try: + for command in func(args): + result.append(command) + except ValueError: + if ignoreErrors: + # Store op as data, such that consumers of commands do not have to + # deal with incorrect number of arguments. + result.append(("", args)) + result.append(("", [op])) + else: + raise + return result + + +def generalizeProgram(program, getNumRegions=None, **kwargs): + return commandsToProgram( + generalizeCommands(programToCommands(program, getNumRegions), **kwargs) + ) + + +def _categorizeVector(v): + """ + Takes X,Y vector v and returns one of r, h, v, or 0 depending on which + of X and/or Y are zero, plus tuple of nonzero ones. If both are zero, + it returns a single zero still. + + >>> _categorizeVector((0,0)) + ('0', (0,)) + >>> _categorizeVector((1,0)) + ('h', (1,)) + >>> _categorizeVector((0,2)) + ('v', (2,)) + >>> _categorizeVector((1,2)) + ('r', (1, 2)) + """ + if not v[0]: + if not v[1]: + return "0", v[:1] + else: + return "v", v[1:] + else: + if not v[1]: + return "h", v[:1] + else: + return "r", v + + +def _mergeCategories(a, b): + if a == "0": + return b + if b == "0": + return a + if a == b: + return a + return None + + +def _negateCategory(a): + if a == "h": + return "v" + if a == "v": + return "h" + assert a in "0r" + return a + + +def _convertToBlendCmds(args): + # return a list of blend commands, and + # the remaining non-blended args, if any. + num_args = len(args) + stack_use = 0 + new_args = [] + i = 0 + while i < num_args: + arg = args[i] + if not isinstance(arg, list): + new_args.append(arg) + i += 1 + stack_use += 1 + else: + prev_stack_use = stack_use + # The arg is a tuple of blend values. + # These are each (master 0,delta 1..delta n, 1) + # Combine as many successive tuples as we can, + # up to the max stack limit. + num_sources = len(arg) - 1 + blendlist = [arg] + i += 1 + stack_use += 1 + num_sources # 1 for the num_blends arg + while (i < num_args) and isinstance(args[i], list): + blendlist.append(args[i]) + i += 1 + stack_use += num_sources + if stack_use + num_sources > maxStackLimit: + # if we are here, max stack is the CFF2 max stack. + # I use the CFF2 max stack limit here rather than + # the 'maxstack' chosen by the client, as the default + # maxstack may have been used unintentionally. For all + # the other operators, this just produces a little less + # optimization, but here it puts a hard (and low) limit + # on the number of source fonts that can be used. + break + # blendList now contains as many single blend tuples as can be + # combined without exceeding the CFF2 stack limit. + num_blends = len(blendlist) + # append the 'num_blends' default font values + blend_args = [] + for arg in blendlist: + blend_args.append(arg[0]) + for arg in blendlist: + assert arg[-1] == 1 + blend_args.extend(arg[1:-1]) + blend_args.append(num_blends) + new_args.append(blend_args) + stack_use = prev_stack_use + num_blends + + return new_args + + +def _addArgs(a, b): + if isinstance(b, list): + if isinstance(a, list): + if len(a) != len(b) or a[-1] != b[-1]: + raise ValueError() + return [_addArgs(va, vb) for va, vb in zip(a[:-1], b[:-1])] + [a[-1]] + else: + a, b = b, a + if isinstance(a, list): + assert a[-1] == 1 + return [_addArgs(a[0], b)] + a[1:] + return a + b + + +def specializeCommands( + commands, + ignoreErrors=False, + generalizeFirst=True, + preserveTopology=False, + maxstack=48, +): + # We perform several rounds of optimizations. They are carefully ordered and are: + # + # 0. Generalize commands. + # This ensures that they are in our expected simple form, with each line/curve only + # having arguments for one segment, and using the generic form (rlineto/rrcurveto). + # If caller is sure the input is in this form, they can turn off generalization to + # save time. + # + # 1. Combine successive rmoveto operations. + # + # 2. Specialize rmoveto/rlineto/rrcurveto operators into horizontal/vertical variants. + # We specialize into some, made-up, variants as well, which simplifies following + # passes. + # + # 3. Merge or delete redundant operations, to the extent requested. + # OpenType spec declares point numbers in CFF undefined. As such, we happily + # change topology. If client relies on point numbers (in GPOS anchors, or for + # hinting purposes(what?)) they can turn this off. + # + # 4. Peephole optimization to revert back some of the h/v variants back into their + # original "relative" operator (rline/rrcurveto) if that saves a byte. + # + # 5. Combine adjacent operators when possible, minding not to go over max stack size. + # + # 6. Resolve any remaining made-up operators into real operators. + # + # I have convinced myself that this produces optimal bytecode (except for, possibly + # one byte each time maxstack size prohibits combining.) YMMV, but you'd be wrong. :-) + # A dynamic-programming approach can do the same but would be significantly slower. + # + # 7. For any args which are blend lists, convert them to a blend command. + + # 0. Generalize commands. + if generalizeFirst: + commands = generalizeCommands(commands, ignoreErrors=ignoreErrors) + else: + commands = list(commands) # Make copy since we modify in-place later. + + # 1. Combine successive rmoveto operations. + for i in range(len(commands) - 1, 0, -1): + if "rmoveto" == commands[i][0] == commands[i - 1][0]: + v1, v2 = commands[i - 1][1], commands[i][1] + commands[i - 1] = ("rmoveto", [v1[0] + v2[0], v1[1] + v2[1]]) + del commands[i] + + # 2. Specialize rmoveto/rlineto/rrcurveto operators into horizontal/vertical variants. + # + # We, in fact, specialize into more, made-up, variants that special-case when both + # X and Y components are zero. This simplifies the following optimization passes. + # This case is rare, but OCD does not let me skip it. + # + # After this round, we will have four variants that use the following mnemonics: + # + # - 'r' for relative, ie. non-zero X and non-zero Y, + # - 'h' for horizontal, ie. zero X and non-zero Y, + # - 'v' for vertical, ie. non-zero X and zero Y, + # - '0' for zeros, ie. zero X and zero Y. + # + # The '0' pseudo-operators are not part of the spec, but help simplify the following + # optimization rounds. We resolve them at the end. So, after this, we will have four + # moveto and four lineto variants: + # + # - 0moveto, 0lineto + # - hmoveto, hlineto + # - vmoveto, vlineto + # - rmoveto, rlineto + # + # and sixteen curveto variants. For example, a '0hcurveto' operator means a curve + # dx0,dy0,dx1,dy1,dx2,dy2,dx3,dy3 where dx0, dx1, and dy3 are zero but not dx3. + # An 'rvcurveto' means dx3 is zero but not dx0,dy0,dy3. + # + # There are nine different variants of curves without the '0'. Those nine map exactly + # to the existing curve variants in the spec: rrcurveto, and the four variants hhcurveto, + # vvcurveto, hvcurveto, and vhcurveto each cover two cases, one with an odd number of + # arguments and one without. Eg. an hhcurveto with an extra argument (odd number of + # arguments) is in fact an rhcurveto. The operators in the spec are designed such that + # all four of rhcurveto, rvcurveto, hrcurveto, and vrcurveto are encodable for one curve. + # + # Of the curve types with '0', the 00curveto is equivalent to a lineto variant. The rest + # of the curve types with a 0 need to be encoded as a h or v variant. Ie. a '0' can be + # thought of a "don't care" and can be used as either an 'h' or a 'v'. As such, we always + # encode a number 0 as argument when we use a '0' variant. Later on, we can just substitute + # the '0' with either 'h' or 'v' and it works. + # + # When we get to curve splines however, things become more complicated... XXX finish this. + # There's one more complexity with splines. If one side of the spline is not horizontal or + # vertical (or zero), ie. if it's 'r', then it limits which spline types we can encode. + # Only hhcurveto and vvcurveto operators can encode a spline starting with 'r', and + # only hvcurveto and vhcurveto operators can encode a spline ending with 'r'. + # This limits our merge opportunities later. + # + for i in range(len(commands)): + op, args = commands[i] + + if op in {"rmoveto", "rlineto"}: + c, args = _categorizeVector(args) + commands[i] = c + op[1:], args + continue + + if op == "rrcurveto": + c1, args1 = _categorizeVector(args[:2]) + c2, args2 = _categorizeVector(args[-2:]) + commands[i] = c1 + c2 + "curveto", args1 + args[2:4] + args2 + continue + + # 3. Merge or delete redundant operations, to the extent requested. + # + # TODO + # A 0moveto that comes before all other path operations can be removed. + # though I find conflicting evidence for this. + # + # TODO + # "If hstem and vstem hints are both declared at the beginning of a + # CharString, and this sequence is followed directly by the hintmask or + # cntrmask operators, then the vstem hint operator (or, if applicable, + # the vstemhm operator) need not be included." + # + # "The sequence and form of a CFF2 CharString program may be represented as: + # {hs* vs* cm* hm* mt subpath}? {mt subpath}*" + # + # https://www.microsoft.com/typography/otspec/cff2charstr.htm#section3.1 + # + # For Type2 CharStrings the sequence is: + # w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar" + + # Some other redundancies change topology (point numbers). + if not preserveTopology: + for i in range(len(commands) - 1, -1, -1): + op, args = commands[i] + + # A 00curveto is demoted to a (specialized) lineto. + if op == "00curveto": + assert len(args) == 4 + c, args = _categorizeVector(args[1:3]) + op = c + "lineto" + commands[i] = op, args + # and then... + + # A 0lineto can be deleted. + if op == "0lineto": + del commands[i] + continue + + # Merge adjacent hlineto's and vlineto's. + # In CFF2 charstrings from variable fonts, each + # arg item may be a list of blendable values, one from + # each source font. + if i and op in {"hlineto", "vlineto"} and (op == commands[i - 1][0]): + _, other_args = commands[i - 1] + assert len(args) == 1 and len(other_args) == 1 + try: + new_args = [_addArgs(args[0], other_args[0])] + except ValueError: + continue + commands[i - 1] = (op, new_args) + del commands[i] + continue + + # 4. Peephole optimization to revert back some of the h/v variants back into their + # original "relative" operator (rline/rrcurveto) if that saves a byte. + for i in range(1, len(commands) - 1): + op, args = commands[i] + prv, nxt = commands[i - 1][0], commands[i + 1][0] + + if op in {"0lineto", "hlineto", "vlineto"} and prv == nxt == "rlineto": + assert len(args) == 1 + args = [0, args[0]] if op[0] == "v" else [args[0], 0] + commands[i] = ("rlineto", args) + continue + + if op[2:] == "curveto" and len(args) == 5 and prv == nxt == "rrcurveto": + assert (op[0] == "r") ^ (op[1] == "r") + if op[0] == "v": + pos = 0 + elif op[0] != "r": + pos = 1 + elif op[1] == "v": + pos = 4 + else: + pos = 5 + # Insert, while maintaining the type of args (can be tuple or list). + args = args[:pos] + type(args)((0,)) + args[pos:] + commands[i] = ("rrcurveto", args) + continue + + # 5. Combine adjacent operators when possible, minding not to go over max stack size. + for i in range(len(commands) - 1, 0, -1): + op1, args1 = commands[i - 1] + op2, args2 = commands[i] + new_op = None + + # Merge logic... + if {op1, op2} <= {"rlineto", "rrcurveto"}: + if op1 == op2: + new_op = op1 + else: + if op2 == "rrcurveto" and len(args2) == 6: + new_op = "rlinecurve" + elif len(args2) == 2: + new_op = "rcurveline" + + elif (op1, op2) in {("rlineto", "rlinecurve"), ("rrcurveto", "rcurveline")}: + new_op = op2 + + elif {op1, op2} == {"vlineto", "hlineto"}: + new_op = op1 + + elif "curveto" == op1[2:] == op2[2:]: + d0, d1 = op1[:2] + d2, d3 = op2[:2] + + if d1 == "r" or d2 == "r" or d0 == d3 == "r": + continue + + d = _mergeCategories(d1, d2) + if d is None: + continue + if d0 == "r": + d = _mergeCategories(d, d3) + if d is None: + continue + new_op = "r" + d + "curveto" + elif d3 == "r": + d0 = _mergeCategories(d0, _negateCategory(d)) + if d0 is None: + continue + new_op = d0 + "r" + "curveto" + else: + d0 = _mergeCategories(d0, d3) + if d0 is None: + continue + new_op = d0 + d + "curveto" + + # Make sure the stack depth does not exceed (maxstack - 1), so + # that subroutinizer can insert subroutine calls at any point. + if new_op and len(args1) + len(args2) < maxstack: + commands[i - 1] = (new_op, args1 + args2) + del commands[i] + + # 6. Resolve any remaining made-up operators into real operators. + for i in range(len(commands)): + op, args = commands[i] + + if op in {"0moveto", "0lineto"}: + commands[i] = "h" + op[1:], args + continue + + if op[2:] == "curveto" and op[:2] not in {"rr", "hh", "vv", "vh", "hv"}: + op0, op1 = op[:2] + if (op0 == "r") ^ (op1 == "r"): + assert len(args) % 2 == 1 + if op0 == "0": + op0 = "h" + if op1 == "0": + op1 = "h" + if op0 == "r": + op0 = op1 + if op1 == "r": + op1 = _negateCategory(op0) + assert {op0, op1} <= {"h", "v"}, (op0, op1) + + if len(args) % 2: + if op0 != op1: # vhcurveto / hvcurveto + if (op0 == "h") ^ (len(args) % 8 == 1): + # Swap last two args order + args = args[:-2] + args[-1:] + args[-2:-1] + else: # hhcurveto / vvcurveto + if op0 == "h": # hhcurveto + # Swap first two args order + args = args[1:2] + args[:1] + args[2:] + + commands[i] = op0 + op1 + "curveto", args + continue + + # 7. For any series of args which are blend lists, convert the series to a single blend arg. + for i in range(len(commands)): + op, args = commands[i] + if any(isinstance(arg, list) for arg in args): + commands[i] = op, _convertToBlendCmds(args) + + return commands + + +def specializeProgram(program, getNumRegions=None, **kwargs): + return commandsToProgram( + specializeCommands(programToCommands(program, getNumRegions), **kwargs) + ) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.specialer", + description="CFF CharString generalizer/specializer", + ) + parser.add_argument("program", metavar="command", nargs="*", help="Commands.") + parser.add_argument( + "--num-regions", + metavar="NumRegions", + nargs="*", + default=None, + help="Number of variable-font regions for blend opertaions.", + ) + + options = parser.parse_args(sys.argv[1:]) + + getNumRegions = ( + None + if options.num_regions is None + else lambda vsIndex: int(options.num_regions[0 if vsIndex is None else vsIndex]) + ) + + program = stringToProgram(options.program) + print("Program:") + print(programToString(program)) + commands = programToCommands(program, getNumRegions) + print("Commands:") + print(commands) + program2 = commandsToProgram(commands) + print("Program from commands:") + print(programToString(program2)) + assert program == program2 + print("Generalized program:") + print(programToString(generalizeProgram(program, getNumRegions))) + print("Specialized program:") + print(programToString(specializeProgram(program, getNumRegions))) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/width.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/width.py new file mode 100644 index 00000000..0ba3ed39 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cffLib/width.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- + +"""T2CharString glyph width optimizer. + +CFF glyphs whose width equals the CFF Private dictionary's ``defaultWidthX`` +value do not need to specify their width in their charstring, saving bytes. +This module determines the optimum ``defaultWidthX`` and ``nominalWidthX`` +values for a font, when provided with a list of glyph widths.""" + +from fontTools.ttLib import TTFont +from collections import defaultdict +from operator import add +from functools import reduce + + +class missingdict(dict): + def __init__(self, missing_func): + self.missing_func = missing_func + + def __missing__(self, v): + return self.missing_func(v) + + +def cumSum(f, op=add, start=0, decreasing=False): + keys = sorted(f.keys()) + minx, maxx = keys[0], keys[-1] + + total = reduce(op, f.values(), start) + + if decreasing: + missing = lambda x: start if x > maxx else total + domain = range(maxx, minx - 1, -1) + else: + missing = lambda x: start if x < minx else total + domain = range(minx, maxx + 1) + + out = missingdict(missing) + + v = start + for x in domain: + v = op(v, f[x]) + out[x] = v + + return out + + +def byteCost(widths, default, nominal): + if not hasattr(widths, "items"): + d = defaultdict(int) + for w in widths: + d[w] += 1 + widths = d + + cost = 0 + for w, freq in widths.items(): + if w == default: + continue + diff = abs(w - nominal) + if diff <= 107: + cost += freq + elif diff <= 1131: + cost += freq * 2 + else: + cost += freq * 5 + return cost + + +def optimizeWidthsBruteforce(widths): + """Bruteforce version. Veeeeeeeeeeeeeeeeery slow. Only works for smallests of fonts.""" + + d = defaultdict(int) + for w in widths: + d[w] += 1 + + # Maximum number of bytes using default can possibly save + maxDefaultAdvantage = 5 * max(d.values()) + + minw, maxw = min(widths), max(widths) + domain = list(range(minw, maxw + 1)) + + bestCostWithoutDefault = min(byteCost(widths, None, nominal) for nominal in domain) + + bestCost = len(widths) * 5 + 1 + for nominal in domain: + if byteCost(widths, None, nominal) > bestCost + maxDefaultAdvantage: + continue + for default in domain: + cost = byteCost(widths, default, nominal) + if cost < bestCost: + bestCost = cost + bestDefault = default + bestNominal = nominal + + return bestDefault, bestNominal + + +def optimizeWidths(widths): + """Given a list of glyph widths, or dictionary mapping glyph width to number of + glyphs having that, returns a tuple of best CFF default and nominal glyph widths. + + This algorithm is linear in UPEM+numGlyphs.""" + + if not hasattr(widths, "items"): + d = defaultdict(int) + for w in widths: + d[w] += 1 + widths = d + + keys = sorted(widths.keys()) + minw, maxw = keys[0], keys[-1] + domain = list(range(minw, maxw + 1)) + + # Cumulative sum/max forward/backward. + cumFrqU = cumSum(widths, op=add) + cumMaxU = cumSum(widths, op=max) + cumFrqD = cumSum(widths, op=add, decreasing=True) + cumMaxD = cumSum(widths, op=max, decreasing=True) + + # Cost per nominal choice, without default consideration. + nomnCostU = missingdict( + lambda x: cumFrqU[x] + cumFrqU[x - 108] + cumFrqU[x - 1132] * 3 + ) + nomnCostD = missingdict( + lambda x: cumFrqD[x] + cumFrqD[x + 108] + cumFrqD[x + 1132] * 3 + ) + nomnCost = missingdict(lambda x: nomnCostU[x] + nomnCostD[x] - widths[x]) + + # Cost-saving per nominal choice, by best default choice. + dfltCostU = missingdict( + lambda x: max(cumMaxU[x], cumMaxU[x - 108] * 2, cumMaxU[x - 1132] * 5) + ) + dfltCostD = missingdict( + lambda x: max(cumMaxD[x], cumMaxD[x + 108] * 2, cumMaxD[x + 1132] * 5) + ) + dfltCost = missingdict(lambda x: max(dfltCostU[x], dfltCostD[x])) + + # Combined cost per nominal choice. + bestCost = missingdict(lambda x: nomnCost[x] - dfltCost[x]) + + # Best nominal. + nominal = min(domain, key=lambda x: bestCost[x]) + + # Work back the best default. + bestC = bestCost[nominal] + dfltC = nomnCost[nominal] - bestCost[nominal] + ends = [] + if dfltC == dfltCostU[nominal]: + starts = [nominal, nominal - 108, nominal - 1132] + for start in starts: + while cumMaxU[start] and cumMaxU[start] == cumMaxU[start - 1]: + start -= 1 + ends.append(start) + else: + starts = [nominal, nominal + 108, nominal + 1132] + for start in starts: + while cumMaxD[start] and cumMaxD[start] == cumMaxD[start + 1]: + start += 1 + ends.append(start) + default = min(ends, key=lambda default: byteCost(widths, default, nominal)) + + return default, nominal + + +def main(args=None): + """Calculate optimum defaultWidthX/nominalWidthX values""" + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.width", + description=main.__doc__, + ) + parser.add_argument( + "inputs", metavar="FILE", type=str, nargs="+", help="Input TTF files" + ) + parser.add_argument( + "-b", + "--brute-force", + dest="brute", + action="store_true", + help="Use brute-force approach (VERY slow)", + ) + + args = parser.parse_args(args) + + for fontfile in args.inputs: + font = TTFont(fontfile) + hmtx = font["hmtx"] + widths = [m[0] for m in hmtx.metrics.values()] + if args.brute: + default, nominal = optimizeWidthsBruteforce(widths) + else: + default, nominal = optimizeWidths(widths) + print( + "glyphs=%d default=%d nominal=%d byteCost=%d" + % (len(widths), default, nominal, byteCost(widths, default, nominal)) + ) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + main() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/builder.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/builder.py new file mode 100644 index 00000000..442bc20e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/builder.py @@ -0,0 +1,659 @@ +""" +colorLib.builder: Build COLR/CPAL tables from scratch + +""" +import collections +import copy +import enum +from functools import partial +from math import ceil, log +from typing import ( + Any, + Dict, + Generator, + Iterable, + List, + Mapping, + Optional, + Sequence, + Tuple, + Type, + TypeVar, + Union, +) +from fontTools.misc.arrayTools import intRect +from fontTools.misc.fixedTools import fixedToFloat +from fontTools.misc.treeTools import build_n_ary_tree +from fontTools.ttLib.tables import C_O_L_R_ +from fontTools.ttLib.tables import C_P_A_L_ +from fontTools.ttLib.tables import _n_a_m_e +from fontTools.ttLib.tables import otTables as ot +from fontTools.ttLib.tables.otTables import ExtendMode, CompositeMode +from .errors import ColorLibError +from .geometry import round_start_circle_stable_containment +from .table_builder import BuildCallback, TableBuilder + + +# TODO move type aliases to colorLib.types? +T = TypeVar("T") +_Kwargs = Mapping[str, Any] +_PaintInput = Union[int, _Kwargs, ot.Paint, Tuple[str, "_PaintInput"]] +_PaintInputList = Sequence[_PaintInput] +_ColorGlyphsDict = Dict[str, Union[_PaintInputList, _PaintInput]] +_ColorGlyphsV0Dict = Dict[str, Sequence[Tuple[str, int]]] +_ClipBoxInput = Union[ + Tuple[int, int, int, int, int], # format 1, variable + Tuple[int, int, int, int], # format 0, non-variable + ot.ClipBox, +] + + +MAX_PAINT_COLR_LAYER_COUNT = 255 +_DEFAULT_ALPHA = 1.0 +_MAX_REUSE_LEN = 32 + + +def _beforeBuildPaintRadialGradient(paint, source): + x0 = source["x0"] + y0 = source["y0"] + r0 = source["r0"] + x1 = source["x1"] + y1 = source["y1"] + r1 = source["r1"] + + # TODO apparently no builder_test confirms this works (?) + + # avoid abrupt change after rounding when c0 is near c1's perimeter + c = round_start_circle_stable_containment((x0, y0), r0, (x1, y1), r1) + x0, y0 = c.centre + r0 = c.radius + + # update source to ensure paint is built with corrected values + source["x0"] = x0 + source["y0"] = y0 + source["r0"] = r0 + source["x1"] = x1 + source["y1"] = y1 + source["r1"] = r1 + + return paint, source + + +def _defaultColorStop(): + colorStop = ot.ColorStop() + colorStop.Alpha = _DEFAULT_ALPHA + return colorStop + + +def _defaultVarColorStop(): + colorStop = ot.VarColorStop() + colorStop.Alpha = _DEFAULT_ALPHA + return colorStop + + +def _defaultColorLine(): + colorLine = ot.ColorLine() + colorLine.Extend = ExtendMode.PAD + return colorLine + + +def _defaultVarColorLine(): + colorLine = ot.VarColorLine() + colorLine.Extend = ExtendMode.PAD + return colorLine + + +def _defaultPaintSolid(): + paint = ot.Paint() + paint.Alpha = _DEFAULT_ALPHA + return paint + + +def _buildPaintCallbacks(): + return { + ( + BuildCallback.BEFORE_BUILD, + ot.Paint, + ot.PaintFormat.PaintRadialGradient, + ): _beforeBuildPaintRadialGradient, + ( + BuildCallback.BEFORE_BUILD, + ot.Paint, + ot.PaintFormat.PaintVarRadialGradient, + ): _beforeBuildPaintRadialGradient, + (BuildCallback.CREATE_DEFAULT, ot.ColorStop): _defaultColorStop, + (BuildCallback.CREATE_DEFAULT, ot.VarColorStop): _defaultVarColorStop, + (BuildCallback.CREATE_DEFAULT, ot.ColorLine): _defaultColorLine, + (BuildCallback.CREATE_DEFAULT, ot.VarColorLine): _defaultVarColorLine, + ( + BuildCallback.CREATE_DEFAULT, + ot.Paint, + ot.PaintFormat.PaintSolid, + ): _defaultPaintSolid, + ( + BuildCallback.CREATE_DEFAULT, + ot.Paint, + ot.PaintFormat.PaintVarSolid, + ): _defaultPaintSolid, + } + + +def populateCOLRv0( + table: ot.COLR, + colorGlyphsV0: _ColorGlyphsV0Dict, + glyphMap: Optional[Mapping[str, int]] = None, +): + """Build v0 color layers and add to existing COLR table. + + Args: + table: a raw ``otTables.COLR()`` object (not ttLib's ``table_C_O_L_R_``). + colorGlyphsV0: map of base glyph names to lists of (layer glyph names, + color palette index) tuples. Can be empty. + glyphMap: a map from glyph names to glyph indices, as returned from + ``TTFont.getReverseGlyphMap()``, to optionally sort base records by GID. + """ + if glyphMap is not None: + colorGlyphItems = sorted( + colorGlyphsV0.items(), key=lambda item: glyphMap[item[0]] + ) + else: + colorGlyphItems = colorGlyphsV0.items() + baseGlyphRecords = [] + layerRecords = [] + for baseGlyph, layers in colorGlyphItems: + baseRec = ot.BaseGlyphRecord() + baseRec.BaseGlyph = baseGlyph + baseRec.FirstLayerIndex = len(layerRecords) + baseRec.NumLayers = len(layers) + baseGlyphRecords.append(baseRec) + + for layerGlyph, paletteIndex in layers: + layerRec = ot.LayerRecord() + layerRec.LayerGlyph = layerGlyph + layerRec.PaletteIndex = paletteIndex + layerRecords.append(layerRec) + + table.BaseGlyphRecordArray = table.LayerRecordArray = None + if baseGlyphRecords: + table.BaseGlyphRecordArray = ot.BaseGlyphRecordArray() + table.BaseGlyphRecordArray.BaseGlyphRecord = baseGlyphRecords + if layerRecords: + table.LayerRecordArray = ot.LayerRecordArray() + table.LayerRecordArray.LayerRecord = layerRecords + table.BaseGlyphRecordCount = len(baseGlyphRecords) + table.LayerRecordCount = len(layerRecords) + + +def buildCOLR( + colorGlyphs: _ColorGlyphsDict, + version: Optional[int] = None, + *, + glyphMap: Optional[Mapping[str, int]] = None, + varStore: Optional[ot.VarStore] = None, + varIndexMap: Optional[ot.DeltaSetIndexMap] = None, + clipBoxes: Optional[Dict[str, _ClipBoxInput]] = None, + allowLayerReuse: bool = True, +) -> C_O_L_R_.table_C_O_L_R_: + """Build COLR table from color layers mapping. + + Args: + + colorGlyphs: map of base glyph name to, either list of (layer glyph name, + color palette index) tuples for COLRv0; or a single ``Paint`` (dict) or + list of ``Paint`` for COLRv1. + version: the version of COLR table. If None, the version is determined + by the presence of COLRv1 paints or variation data (varStore), which + require version 1; otherwise, if all base glyphs use only simple color + layers, version 0 is used. + glyphMap: a map from glyph names to glyph indices, as returned from + TTFont.getReverseGlyphMap(), to optionally sort base records by GID. + varStore: Optional ItemVarationStore for deltas associated with v1 layer. + varIndexMap: Optional DeltaSetIndexMap for deltas associated with v1 layer. + clipBoxes: Optional map of base glyph name to clip box 4- or 5-tuples: + (xMin, yMin, xMax, yMax) or (xMin, yMin, xMax, yMax, varIndexBase). + + Returns: + A new COLR table. + """ + self = C_O_L_R_.table_C_O_L_R_() + + if varStore is not None and version == 0: + raise ValueError("Can't add VarStore to COLRv0") + + if version in (None, 0) and not varStore: + # split color glyphs into v0 and v1 and encode separately + colorGlyphsV0, colorGlyphsV1 = _split_color_glyphs_by_version(colorGlyphs) + if version == 0 and colorGlyphsV1: + raise ValueError("Can't encode COLRv1 glyphs in COLRv0") + else: + # unless explicitly requested for v1 or have variations, in which case + # we encode all color glyph as v1 + colorGlyphsV0, colorGlyphsV1 = {}, colorGlyphs + + colr = ot.COLR() + + populateCOLRv0(colr, colorGlyphsV0, glyphMap) + + colr.LayerList, colr.BaseGlyphList = buildColrV1( + colorGlyphsV1, + glyphMap, + allowLayerReuse=allowLayerReuse, + ) + + if version is None: + version = 1 if (varStore or colorGlyphsV1) else 0 + elif version not in (0, 1): + raise NotImplementedError(version) + self.version = colr.Version = version + + if version == 0: + self.ColorLayers = self._decompileColorLayersV0(colr) + else: + colr.ClipList = buildClipList(clipBoxes) if clipBoxes else None + colr.VarIndexMap = varIndexMap + colr.VarStore = varStore + self.table = colr + + return self + + +def buildClipList(clipBoxes: Dict[str, _ClipBoxInput]) -> ot.ClipList: + clipList = ot.ClipList() + clipList.Format = 1 + clipList.clips = {name: buildClipBox(box) for name, box in clipBoxes.items()} + return clipList + + +def buildClipBox(clipBox: _ClipBoxInput) -> ot.ClipBox: + if isinstance(clipBox, ot.ClipBox): + return clipBox + n = len(clipBox) + clip = ot.ClipBox() + if n not in (4, 5): + raise ValueError(f"Invalid ClipBox: expected 4 or 5 values, found {n}") + clip.xMin, clip.yMin, clip.xMax, clip.yMax = intRect(clipBox[:4]) + clip.Format = int(n == 5) + 1 + if n == 5: + clip.VarIndexBase = int(clipBox[4]) + return clip + + +class ColorPaletteType(enum.IntFlag): + USABLE_WITH_LIGHT_BACKGROUND = 0x0001 + USABLE_WITH_DARK_BACKGROUND = 0x0002 + + @classmethod + def _missing_(cls, value): + # enforce reserved bits + if isinstance(value, int) and (value < 0 or value & 0xFFFC != 0): + raise ValueError(f"{value} is not a valid {cls.__name__}") + return super()._missing_(value) + + +# None, 'abc' or {'en': 'abc', 'de': 'xyz'} +_OptionalLocalizedString = Union[None, str, Dict[str, str]] + + +def buildPaletteLabels( + labels: Iterable[_OptionalLocalizedString], nameTable: _n_a_m_e.table__n_a_m_e +) -> List[Optional[int]]: + return [ + nameTable.addMultilingualName(l, mac=False) + if isinstance(l, dict) + else C_P_A_L_.table_C_P_A_L_.NO_NAME_ID + if l is None + else nameTable.addMultilingualName({"en": l}, mac=False) + for l in labels + ] + + +def buildCPAL( + palettes: Sequence[Sequence[Tuple[float, float, float, float]]], + paletteTypes: Optional[Sequence[ColorPaletteType]] = None, + paletteLabels: Optional[Sequence[_OptionalLocalizedString]] = None, + paletteEntryLabels: Optional[Sequence[_OptionalLocalizedString]] = None, + nameTable: Optional[_n_a_m_e.table__n_a_m_e] = None, +) -> C_P_A_L_.table_C_P_A_L_: + """Build CPAL table from list of color palettes. + + Args: + palettes: list of lists of colors encoded as tuples of (R, G, B, A) floats + in the range [0..1]. + paletteTypes: optional list of ColorPaletteType, one for each palette. + paletteLabels: optional list of palette labels. Each lable can be either: + None (no label), a string (for for default English labels), or a + localized string (as a dict keyed with BCP47 language codes). + paletteEntryLabels: optional list of palette entry labels, one for each + palette entry (see paletteLabels). + nameTable: optional name table where to store palette and palette entry + labels. Required if either paletteLabels or paletteEntryLabels is set. + + Return: + A new CPAL v0 or v1 table, if custom palette types or labels are specified. + """ + if len({len(p) for p in palettes}) != 1: + raise ColorLibError("color palettes have different lengths") + + if (paletteLabels or paletteEntryLabels) and not nameTable: + raise TypeError( + "nameTable is required if palette or palette entries have labels" + ) + + cpal = C_P_A_L_.table_C_P_A_L_() + cpal.numPaletteEntries = len(palettes[0]) + + cpal.palettes = [] + for i, palette in enumerate(palettes): + colors = [] + for j, color in enumerate(palette): + if not isinstance(color, tuple) or len(color) != 4: + raise ColorLibError( + f"In palette[{i}][{j}]: expected (R, G, B, A) tuple, got {color!r}" + ) + if any(v > 1 or v < 0 for v in color): + raise ColorLibError( + f"palette[{i}][{j}] has invalid out-of-range [0..1] color: {color!r}" + ) + # input colors are RGBA, CPAL encodes them as BGRA + red, green, blue, alpha = color + colors.append( + C_P_A_L_.Color(*(round(v * 255) for v in (blue, green, red, alpha))) + ) + cpal.palettes.append(colors) + + if any(v is not None for v in (paletteTypes, paletteLabels, paletteEntryLabels)): + cpal.version = 1 + + if paletteTypes is not None: + if len(paletteTypes) != len(palettes): + raise ColorLibError( + f"Expected {len(palettes)} paletteTypes, got {len(paletteTypes)}" + ) + cpal.paletteTypes = [ColorPaletteType(t).value for t in paletteTypes] + else: + cpal.paletteTypes = [C_P_A_L_.table_C_P_A_L_.DEFAULT_PALETTE_TYPE] * len( + palettes + ) + + if paletteLabels is not None: + if len(paletteLabels) != len(palettes): + raise ColorLibError( + f"Expected {len(palettes)} paletteLabels, got {len(paletteLabels)}" + ) + cpal.paletteLabels = buildPaletteLabels(paletteLabels, nameTable) + else: + cpal.paletteLabels = [C_P_A_L_.table_C_P_A_L_.NO_NAME_ID] * len(palettes) + + if paletteEntryLabels is not None: + if len(paletteEntryLabels) != cpal.numPaletteEntries: + raise ColorLibError( + f"Expected {cpal.numPaletteEntries} paletteEntryLabels, " + f"got {len(paletteEntryLabels)}" + ) + cpal.paletteEntryLabels = buildPaletteLabels(paletteEntryLabels, nameTable) + else: + cpal.paletteEntryLabels = [ + C_P_A_L_.table_C_P_A_L_.NO_NAME_ID + ] * cpal.numPaletteEntries + else: + cpal.version = 0 + + return cpal + + +# COLR v1 tables +# See draft proposal at: https://github.com/googlefonts/colr-gradients-spec + + +def _is_colrv0_layer(layer: Any) -> bool: + # Consider as COLRv0 layer any sequence of length 2 (be it tuple or list) in which + # the first element is a str (the layerGlyph) and the second element is an int + # (CPAL paletteIndex). + # https://github.com/googlefonts/ufo2ft/issues/426 + try: + layerGlyph, paletteIndex = layer + except (TypeError, ValueError): + return False + else: + return isinstance(layerGlyph, str) and isinstance(paletteIndex, int) + + +def _split_color_glyphs_by_version( + colorGlyphs: _ColorGlyphsDict, +) -> Tuple[_ColorGlyphsV0Dict, _ColorGlyphsDict]: + colorGlyphsV0 = {} + colorGlyphsV1 = {} + for baseGlyph, layers in colorGlyphs.items(): + if all(_is_colrv0_layer(l) for l in layers): + colorGlyphsV0[baseGlyph] = layers + else: + colorGlyphsV1[baseGlyph] = layers + + # sanity check + assert set(colorGlyphs) == (set(colorGlyphsV0) | set(colorGlyphsV1)) + + return colorGlyphsV0, colorGlyphsV1 + + +def _reuse_ranges(num_layers: int) -> Generator[Tuple[int, int], None, None]: + # TODO feels like something itertools might have already + for lbound in range(num_layers): + # Reuse of very large #s of layers is relatively unlikely + # +2: we want sequences of at least 2 + # otData handles single-record duplication + for ubound in range( + lbound + 2, min(num_layers + 1, lbound + 2 + _MAX_REUSE_LEN) + ): + yield (lbound, ubound) + + +class LayerReuseCache: + reusePool: Mapping[Tuple[Any, ...], int] + tuples: Mapping[int, Tuple[Any, ...]] + keepAlive: List[ot.Paint] # we need id to remain valid + + def __init__(self): + self.reusePool = {} + self.tuples = {} + self.keepAlive = [] + + def _paint_tuple(self, paint: ot.Paint): + # start simple, who even cares about cyclic graphs or interesting field types + def _tuple_safe(value): + if isinstance(value, enum.Enum): + return value + elif hasattr(value, "__dict__"): + return tuple( + (k, _tuple_safe(v)) for k, v in sorted(value.__dict__.items()) + ) + elif isinstance(value, collections.abc.MutableSequence): + return tuple(_tuple_safe(e) for e in value) + return value + + # Cache the tuples for individual Paint instead of the whole sequence + # because the seq could be a transient slice + result = self.tuples.get(id(paint), None) + if result is None: + result = _tuple_safe(paint) + self.tuples[id(paint)] = result + self.keepAlive.append(paint) + return result + + def _as_tuple(self, paints: Sequence[ot.Paint]) -> Tuple[Any, ...]: + return tuple(self._paint_tuple(p) for p in paints) + + def try_reuse(self, layers: List[ot.Paint]) -> List[ot.Paint]: + found_reuse = True + while found_reuse: + found_reuse = False + + ranges = sorted( + _reuse_ranges(len(layers)), + key=lambda t: (t[1] - t[0], t[1], t[0]), + reverse=True, + ) + for lbound, ubound in ranges: + reuse_lbound = self.reusePool.get( + self._as_tuple(layers[lbound:ubound]), -1 + ) + if reuse_lbound == -1: + continue + new_slice = ot.Paint() + new_slice.Format = int(ot.PaintFormat.PaintColrLayers) + new_slice.NumLayers = ubound - lbound + new_slice.FirstLayerIndex = reuse_lbound + layers = layers[:lbound] + [new_slice] + layers[ubound:] + found_reuse = True + break + return layers + + def add(self, layers: List[ot.Paint], first_layer_index: int): + for lbound, ubound in _reuse_ranges(len(layers)): + self.reusePool[self._as_tuple(layers[lbound:ubound])] = ( + lbound + first_layer_index + ) + + +class LayerListBuilder: + layers: List[ot.Paint] + cache: LayerReuseCache + allowLayerReuse: bool + + def __init__(self, *, allowLayerReuse=True): + self.layers = [] + if allowLayerReuse: + self.cache = LayerReuseCache() + else: + self.cache = None + + # We need to intercept construction of PaintColrLayers + callbacks = _buildPaintCallbacks() + callbacks[ + ( + BuildCallback.BEFORE_BUILD, + ot.Paint, + ot.PaintFormat.PaintColrLayers, + ) + ] = self._beforeBuildPaintColrLayers + self.tableBuilder = TableBuilder(callbacks) + + # COLR layers is unusual in that it modifies shared state + # so we need a callback into an object + def _beforeBuildPaintColrLayers(self, dest, source): + # Sketchy gymnastics: a sequence input will have dropped it's layers + # into NumLayers; get it back + if isinstance(source.get("NumLayers", None), collections.abc.Sequence): + layers = source["NumLayers"] + else: + layers = source["Layers"] + + # Convert maps seqs or whatever into typed objects + layers = [self.buildPaint(l) for l in layers] + + # No reason to have a colr layers with just one entry + if len(layers) == 1: + return layers[0], {} + + if self.cache is not None: + # Look for reuse, with preference to longer sequences + # This may make the layer list smaller + layers = self.cache.try_reuse(layers) + + # The layer list is now final; if it's too big we need to tree it + is_tree = len(layers) > MAX_PAINT_COLR_LAYER_COUNT + layers = build_n_ary_tree(layers, n=MAX_PAINT_COLR_LAYER_COUNT) + + # We now have a tree of sequences with Paint leaves. + # Convert the sequences into PaintColrLayers. + def listToColrLayers(layer): + if isinstance(layer, collections.abc.Sequence): + return self.buildPaint( + { + "Format": ot.PaintFormat.PaintColrLayers, + "Layers": [listToColrLayers(l) for l in layer], + } + ) + return layer + + layers = [listToColrLayers(l) for l in layers] + + # No reason to have a colr layers with just one entry + if len(layers) == 1: + return layers[0], {} + + paint = ot.Paint() + paint.Format = int(ot.PaintFormat.PaintColrLayers) + paint.NumLayers = len(layers) + paint.FirstLayerIndex = len(self.layers) + self.layers.extend(layers) + + # Register our parts for reuse provided we aren't a tree + # If we are a tree the leaves registered for reuse and that will suffice + if self.cache is not None and not is_tree: + self.cache.add(layers, paint.FirstLayerIndex) + + # we've fully built dest; empty source prevents generalized build from kicking in + return paint, {} + + def buildPaint(self, paint: _PaintInput) -> ot.Paint: + return self.tableBuilder.build(ot.Paint, paint) + + def build(self) -> Optional[ot.LayerList]: + if not self.layers: + return None + layers = ot.LayerList() + layers.LayerCount = len(self.layers) + layers.Paint = self.layers + return layers + + +def buildBaseGlyphPaintRecord( + baseGlyph: str, layerBuilder: LayerListBuilder, paint: _PaintInput +) -> ot.BaseGlyphList: + self = ot.BaseGlyphPaintRecord() + self.BaseGlyph = baseGlyph + self.Paint = layerBuilder.buildPaint(paint) + return self + + +def _format_glyph_errors(errors: Mapping[str, Exception]) -> str: + lines = [] + for baseGlyph, error in sorted(errors.items()): + lines.append(f" {baseGlyph} => {type(error).__name__}: {error}") + return "\n".join(lines) + + +def buildColrV1( + colorGlyphs: _ColorGlyphsDict, + glyphMap: Optional[Mapping[str, int]] = None, + *, + allowLayerReuse: bool = True, +) -> Tuple[Optional[ot.LayerList], ot.BaseGlyphList]: + if glyphMap is not None: + colorGlyphItems = sorted( + colorGlyphs.items(), key=lambda item: glyphMap[item[0]] + ) + else: + colorGlyphItems = colorGlyphs.items() + + errors = {} + baseGlyphs = [] + layerBuilder = LayerListBuilder(allowLayerReuse=allowLayerReuse) + for baseGlyph, paint in colorGlyphItems: + try: + baseGlyphs.append(buildBaseGlyphPaintRecord(baseGlyph, layerBuilder, paint)) + + except (ColorLibError, OverflowError, ValueError, TypeError) as e: + errors[baseGlyph] = e + + if errors: + failed_glyphs = _format_glyph_errors(errors) + exc = ColorLibError(f"Failed to build BaseGlyphList:\n{failed_glyphs}") + exc.errors = errors + raise exc from next(iter(errors.values())) + + layers = layerBuilder.build() + glyphs = ot.BaseGlyphList() + glyphs.BaseGlyphCount = len(baseGlyphs) + glyphs.BaseGlyphPaintRecord = baseGlyphs + return (layers, glyphs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/errors.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/errors.py new file mode 100644 index 00000000..18cbebba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/errors.py @@ -0,0 +1,2 @@ +class ColorLibError(Exception): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/geometry.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/geometry.py new file mode 100644 index 00000000..1ce161bf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/geometry.py @@ -0,0 +1,143 @@ +"""Helpers for manipulating 2D points and vectors in COLR table.""" + +from math import copysign, cos, hypot, isclose, pi +from fontTools.misc.roundTools import otRound + + +def _vector_between(origin, target): + return (target[0] - origin[0], target[1] - origin[1]) + + +def _round_point(pt): + return (otRound(pt[0]), otRound(pt[1])) + + +def _unit_vector(vec): + length = hypot(*vec) + if length == 0: + return None + return (vec[0] / length, vec[1] / length) + + +_CIRCLE_INSIDE_TOLERANCE = 1e-4 + + +# The unit vector's X and Y components are respectively +# U = (cos(α), sin(α)) +# where α is the angle between the unit vector and the positive x axis. +_UNIT_VECTOR_THRESHOLD = cos(3 / 8 * pi) # == sin(1/8 * pi) == 0.38268343236508984 + + +def _rounding_offset(direction): + # Return 2-tuple of -/+ 1.0 or 0.0 approximately based on the direction vector. + # We divide the unit circle in 8 equal slices oriented towards the cardinal + # (N, E, S, W) and intermediate (NE, SE, SW, NW) directions. To each slice we + # map one of the possible cases: -1, 0, +1 for either X and Y coordinate. + # E.g. Return (+1.0, -1.0) if unit vector is oriented towards SE, or + # (-1.0, 0.0) if it's pointing West, etc. + uv = _unit_vector(direction) + if not uv: + return (0, 0) + + result = [] + for uv_component in uv: + if -_UNIT_VECTOR_THRESHOLD <= uv_component < _UNIT_VECTOR_THRESHOLD: + # unit vector component near 0: direction almost orthogonal to the + # direction of the current axis, thus keep coordinate unchanged + result.append(0) + else: + # nudge coord by +/- 1.0 in direction of unit vector + result.append(copysign(1.0, uv_component)) + return tuple(result) + + +class Circle: + def __init__(self, centre, radius): + self.centre = centre + self.radius = radius + + def __repr__(self): + return f"Circle(centre={self.centre}, radius={self.radius})" + + def round(self): + return Circle(_round_point(self.centre), otRound(self.radius)) + + def inside(self, outer_circle, tolerance=_CIRCLE_INSIDE_TOLERANCE): + dist = self.radius + hypot(*_vector_between(self.centre, outer_circle.centre)) + return ( + isclose(outer_circle.radius, dist, rel_tol=_CIRCLE_INSIDE_TOLERANCE) + or outer_circle.radius > dist + ) + + def concentric(self, other): + return self.centre == other.centre + + def move(self, dx, dy): + self.centre = (self.centre[0] + dx, self.centre[1] + dy) + + +def round_start_circle_stable_containment(c0, r0, c1, r1): + """Round start circle so that it stays inside/outside end circle after rounding. + + The rounding of circle coordinates to integers may cause an abrupt change + if the start circle c0 is so close to the end circle c1's perimiter that + it ends up falling outside (or inside) as a result of the rounding. + To keep the gradient unchanged, we nudge it in the right direction. + + See: + https://github.com/googlefonts/colr-gradients-spec/issues/204 + https://github.com/googlefonts/picosvg/issues/158 + """ + start, end = Circle(c0, r0), Circle(c1, r1) + + inside_before_round = start.inside(end) + + round_start = start.round() + round_end = end.round() + inside_after_round = round_start.inside(round_end) + + if inside_before_round == inside_after_round: + return round_start + elif inside_after_round: + # start was outside before rounding: we need to push start away from end + direction = _vector_between(round_end.centre, round_start.centre) + radius_delta = +1.0 + else: + # start was inside before rounding: we need to push start towards end + direction = _vector_between(round_start.centre, round_end.centre) + radius_delta = -1.0 + dx, dy = _rounding_offset(direction) + + # At most 2 iterations ought to be enough to converge. Before the loop, we + # know the start circle didn't keep containment after normal rounding; thus + # we continue adjusting by -/+ 1.0 until containment is restored. + # Normal rounding can at most move each coordinates -/+0.5; in the worst case + # both the start and end circle's centres and radii will be rounded in opposite + # directions, e.g. when they move along a 45 degree diagonal: + # c0 = (1.5, 1.5) ===> (2.0, 2.0) + # r0 = 0.5 ===> 1.0 + # c1 = (0.499, 0.499) ===> (0.0, 0.0) + # r1 = 2.499 ===> 2.0 + # In this example, the relative distance between the circles, calculated + # as r1 - (r0 + distance(c0, c1)) is initially 0.57437 (c0 is inside c1), and + # -1.82842 after rounding (c0 is now outside c1). Nudging c0 by -1.0 on both + # x and y axes moves it towards c1 by hypot(-1.0, -1.0) = 1.41421. Two of these + # moves cover twice that distance, which is enough to restore containment. + max_attempts = 2 + for _ in range(max_attempts): + if round_start.concentric(round_end): + # can't move c0 towards c1 (they are the same), so we change the radius + round_start.radius += radius_delta + assert round_start.radius >= 0 + else: + round_start.move(dx, dy) + if inside_before_round == round_start.inside(round_end): + break + else: # likely a bug + raise AssertionError( + f"Rounding circle {start} " + f"{'inside' if inside_before_round else 'outside'} " + f"{end} failed after {max_attempts} attempts!" + ) + + return round_start diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/table_builder.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/table_builder.py new file mode 100644 index 00000000..f1e182c4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/table_builder.py @@ -0,0 +1,223 @@ +""" +colorLib.table_builder: Generic helper for filling in BaseTable derivatives from tuples and maps and such. + +""" + +import collections +import enum +from fontTools.ttLib.tables.otBase import ( + BaseTable, + FormatSwitchingBaseTable, + UInt8FormatSwitchingBaseTable, +) +from fontTools.ttLib.tables.otConverters import ( + ComputedInt, + SimpleValue, + Struct, + Short, + UInt8, + UShort, + IntValue, + FloatValue, + OptionalValue, +) +from fontTools.misc.roundTools import otRound + + +class BuildCallback(enum.Enum): + """Keyed on (BEFORE_BUILD, class[, Format if available]). + Receives (dest, source). + Should return (dest, source), which can be new objects. + """ + + BEFORE_BUILD = enum.auto() + + """Keyed on (AFTER_BUILD, class[, Format if available]). + Receives (dest). + Should return dest, which can be a new object. + """ + AFTER_BUILD = enum.auto() + + """Keyed on (CREATE_DEFAULT, class[, Format if available]). + Receives no arguments. + Should return a new instance of class. + """ + CREATE_DEFAULT = enum.auto() + + +def _assignable(convertersByName): + return {k: v for k, v in convertersByName.items() if not isinstance(v, ComputedInt)} + + +def _isNonStrSequence(value): + return isinstance(value, collections.abc.Sequence) and not isinstance(value, str) + + +def _split_format(cls, source): + if _isNonStrSequence(source): + assert len(source) > 0, f"{cls} needs at least format from {source}" + fmt, remainder = source[0], source[1:] + elif isinstance(source, collections.abc.Mapping): + assert "Format" in source, f"{cls} needs at least Format from {source}" + remainder = source.copy() + fmt = remainder.pop("Format") + else: + raise ValueError(f"Not sure how to populate {cls} from {source}") + + assert isinstance( + fmt, collections.abc.Hashable + ), f"{cls} Format is not hashable: {fmt!r}" + assert fmt in cls.convertersByName, f"{cls} invalid Format: {fmt!r}" + + return fmt, remainder + + +class TableBuilder: + """ + Helps to populate things derived from BaseTable from maps, tuples, etc. + + A table of lifecycle callbacks may be provided to add logic beyond what is possible + based on otData info for the target class. See BuildCallbacks. + """ + + def __init__(self, callbackTable=None): + if callbackTable is None: + callbackTable = {} + self._callbackTable = callbackTable + + def _convert(self, dest, field, converter, value): + enumClass = getattr(converter, "enumClass", None) + + if enumClass: + if isinstance(value, enumClass): + pass + elif isinstance(value, str): + try: + value = getattr(enumClass, value.upper()) + except AttributeError: + raise ValueError(f"{value} is not a valid {enumClass}") + else: + value = enumClass(value) + + elif isinstance(converter, IntValue): + value = otRound(value) + elif isinstance(converter, FloatValue): + value = float(value) + + elif isinstance(converter, Struct): + if converter.repeat: + if _isNonStrSequence(value): + value = [self.build(converter.tableClass, v) for v in value] + else: + value = [self.build(converter.tableClass, value)] + setattr(dest, converter.repeat, len(value)) + else: + value = self.build(converter.tableClass, value) + elif callable(converter): + value = converter(value) + + setattr(dest, field, value) + + def build(self, cls, source): + assert issubclass(cls, BaseTable) + + if isinstance(source, cls): + return source + + callbackKey = (cls,) + fmt = None + if issubclass(cls, FormatSwitchingBaseTable): + fmt, source = _split_format(cls, source) + callbackKey = (cls, fmt) + + dest = self._callbackTable.get( + (BuildCallback.CREATE_DEFAULT,) + callbackKey, lambda: cls() + )() + assert isinstance(dest, cls) + + convByName = _assignable(cls.convertersByName) + skippedFields = set() + + # For format switchers we need to resolve converters based on format + if issubclass(cls, FormatSwitchingBaseTable): + dest.Format = fmt + convByName = _assignable(convByName[dest.Format]) + skippedFields.add("Format") + + # Convert sequence => mapping so before thunk only has to handle one format + if _isNonStrSequence(source): + # Sequence (typically list or tuple) assumed to match fields in declaration order + assert len(source) <= len( + convByName + ), f"Sequence of {len(source)} too long for {cls}; expected <= {len(convByName)} values" + source = dict(zip(convByName.keys(), source)) + + dest, source = self._callbackTable.get( + (BuildCallback.BEFORE_BUILD,) + callbackKey, lambda d, s: (d, s) + )(dest, source) + + if isinstance(source, collections.abc.Mapping): + for field, value in source.items(): + if field in skippedFields: + continue + converter = convByName.get(field, None) + if not converter: + raise ValueError( + f"Unrecognized field {field} for {cls}; expected one of {sorted(convByName.keys())}" + ) + self._convert(dest, field, converter, value) + else: + # let's try as a 1-tuple + dest = self.build(cls, (source,)) + + for field, conv in convByName.items(): + if not hasattr(dest, field) and isinstance(conv, OptionalValue): + setattr(dest, field, conv.DEFAULT) + + dest = self._callbackTable.get( + (BuildCallback.AFTER_BUILD,) + callbackKey, lambda d: d + )(dest) + + return dest + + +class TableUnbuilder: + def __init__(self, callbackTable=None): + if callbackTable is None: + callbackTable = {} + self._callbackTable = callbackTable + + def unbuild(self, table): + assert isinstance(table, BaseTable) + + source = {} + + callbackKey = (type(table),) + if isinstance(table, FormatSwitchingBaseTable): + source["Format"] = int(table.Format) + callbackKey += (table.Format,) + + for converter in table.getConverters(): + if isinstance(converter, ComputedInt): + continue + value = getattr(table, converter.name) + + enumClass = getattr(converter, "enumClass", None) + if enumClass: + source[converter.name] = value.name.lower() + elif isinstance(converter, Struct): + if converter.repeat: + source[converter.name] = [self.unbuild(v) for v in value] + else: + source[converter.name] = self.unbuild(value) + elif isinstance(converter, SimpleValue): + # "simple" values (e.g. int, float, str) need no further un-building + source[converter.name] = value + else: + raise NotImplementedError( + "Don't know how unbuild {value!r} with {converter!r}" + ) + + source = self._callbackTable.get(callbackKey, lambda s: s)(source) + + return source diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/unbuilder.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/unbuilder.py new file mode 100644 index 00000000..ac243550 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/colorLib/unbuilder.py @@ -0,0 +1,81 @@ +from fontTools.ttLib.tables import otTables as ot +from .table_builder import TableUnbuilder + + +def unbuildColrV1(layerList, baseGlyphList): + layers = [] + if layerList: + layers = layerList.Paint + unbuilder = LayerListUnbuilder(layers) + return { + rec.BaseGlyph: unbuilder.unbuildPaint(rec.Paint) + for rec in baseGlyphList.BaseGlyphPaintRecord + } + + +def _flatten_layers(lst): + for paint in lst: + if paint["Format"] == ot.PaintFormat.PaintColrLayers: + yield from _flatten_layers(paint["Layers"]) + else: + yield paint + + +class LayerListUnbuilder: + def __init__(self, layers): + self.layers = layers + + callbacks = { + ( + ot.Paint, + ot.PaintFormat.PaintColrLayers, + ): self._unbuildPaintColrLayers, + } + self.tableUnbuilder = TableUnbuilder(callbacks) + + def unbuildPaint(self, paint): + assert isinstance(paint, ot.Paint) + return self.tableUnbuilder.unbuild(paint) + + def _unbuildPaintColrLayers(self, source): + assert source["Format"] == ot.PaintFormat.PaintColrLayers + + layers = list( + _flatten_layers( + [ + self.unbuildPaint(childPaint) + for childPaint in self.layers[ + source["FirstLayerIndex"] : source["FirstLayerIndex"] + + source["NumLayers"] + ] + ] + ) + ) + + if len(layers) == 1: + return layers[0] + + return {"Format": source["Format"], "Layers": layers} + + +if __name__ == "__main__": + from pprint import pprint + import sys + from fontTools.ttLib import TTFont + + try: + fontfile = sys.argv[1] + except IndexError: + sys.exit("usage: fonttools colorLib.unbuilder FONTFILE") + + font = TTFont(fontfile) + colr = font["COLR"] + if colr.version < 1: + sys.exit(f"error: No COLR table version=1 found in {fontfile}") + + colorGlyphs = unbuildColrV1( + colr.table.LayerList, + colr.table.BaseGlyphList, + ) + + pprint(colorGlyphs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/config/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/config/__init__.py new file mode 100644 index 00000000..c106fe51 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/config/__init__.py @@ -0,0 +1,74 @@ +""" +Define all configuration options that can affect the working of fontTools +modules. E.g. optimization levels of varLib IUP, otlLib GPOS compression level, +etc. If this file gets too big, split it into smaller files per-module. + +An instance of the Config class can be attached to a TTFont object, so that +the various modules can access their configuration options from it. +""" +from textwrap import dedent + +from fontTools.misc.configTools import * + + +class Config(AbstractConfig): + options = Options() + + +OPTIONS = Config.options + + +Config.register_option( + name="fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL", + help=dedent( + """\ + GPOS Lookup type 2 (PairPos) compression level: + 0 = do not attempt to compact PairPos lookups; + 1 to 8 = create at most 1 to 8 new subtables for each existing + subtable, provided that it would yield a 50%% file size saving; + 9 = create as many new subtables as needed to yield a file size saving. + Default: 0. + + This compaction aims to save file size, by splitting large class + kerning subtables (Format 2) that contain many zero values into + smaller and denser subtables. It's a trade-off between the overhead + of several subtables versus the sparseness of one big subtable. + + See the pull request: https://github.com/fonttools/fonttools/pull/2326 + """ + ), + default=0, + parse=int, + validate=lambda v: v in range(10), +) + +Config.register_option( + name="fontTools.ttLib.tables.otBase:USE_HARFBUZZ_REPACKER", + help=dedent( + """\ + FontTools tries to use the HarfBuzz Repacker to serialize GPOS/GSUB tables + if the uharfbuzz python bindings are importable, otherwise falls back to its + slower, less efficient serializer. Set to False to always use the latter. + Set to True to explicitly request the HarfBuzz Repacker (will raise an + error if uharfbuzz cannot be imported). + """ + ), + default=None, + parse=Option.parse_optional_bool, + validate=Option.validate_optional_bool, +) + +Config.register_option( + name="fontTools.otlLib.builder:WRITE_GPOS7", + help=dedent( + """\ + macOS before 13.2 didn’t support GPOS LookupType 7 (non-chaining + ContextPos lookups), so FontTools.otlLib.builder disables a file size + optimisation that would use LookupType 7 instead of 8 when there is no + chaining (no prefix or suffix). Set to True to enable the optimization. + """ + ), + default=False, + parse=Option.parse_optional_bool, + validate=Option.validate_optional_bool, +) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__init__.py new file mode 100644 index 00000000..4ae6356e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .cu2qu import * diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__main__.py new file mode 100644 index 00000000..084bf8f9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/__main__.py @@ -0,0 +1,6 @@ +import sys +from .cli import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/benchmark.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/benchmark.py new file mode 100644 index 00000000..2ab1e966 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/benchmark.py @@ -0,0 +1,55 @@ +"""Benchmark the cu2qu algorithm performance.""" + +from .cu2qu import * +import random +import timeit + +MAX_ERR = 0.05 + + +def generate_curve(): + return [ + tuple(float(random.randint(0, 2048)) for coord in range(2)) + for point in range(4) + ] + + +def setup_curve_to_quadratic(): + return generate_curve(), MAX_ERR + + +def setup_curves_to_quadratic(): + num_curves = 3 + return ([generate_curve() for curve in range(num_curves)], [MAX_ERR] * num_curves) + + +def run_benchmark(module, function, setup_suffix="", repeat=5, number=1000): + setup_func = "setup_" + function + if setup_suffix: + print("%s with %s:" % (function, setup_suffix), end="") + setup_func += "_" + setup_suffix + else: + print("%s:" % function, end="") + + def wrapper(function, setup_func): + function = globals()[function] + setup_func = globals()[setup_func] + + def wrapped(): + return function(*setup_func()) + + return wrapped + + results = timeit.repeat(wrapper(function, setup_func), repeat=repeat, number=number) + print("\t%5.1fus" % (min(results) * 1000000.0 / number)) + + +def main(): + """Benchmark the cu2qu algorithm performance.""" + run_benchmark("cu2qu", "curve_to_quadratic") + run_benchmark("cu2qu", "curves_to_quadratic") + + +if __name__ == "__main__": + random.seed(1) + main() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cli.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cli.py new file mode 100644 index 00000000..9144043f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cli.py @@ -0,0 +1,198 @@ +import os +import argparse +import logging +import shutil +import multiprocessing as mp +from contextlib import closing +from functools import partial + +import fontTools +from .ufo import font_to_quadratic, fonts_to_quadratic + +ufo_module = None +try: + import ufoLib2 as ufo_module +except ImportError: + try: + import defcon as ufo_module + except ImportError as e: + pass + + +logger = logging.getLogger("fontTools.cu2qu") + + +def _cpu_count(): + try: + return mp.cpu_count() + except NotImplementedError: # pragma: no cover + return 1 + + +def open_ufo(path): + if hasattr(ufo_module.Font, "open"): # ufoLib2 + return ufo_module.Font.open(path) + return ufo_module.Font(path) # defcon + + +def _font_to_quadratic(input_path, output_path=None, **kwargs): + ufo = open_ufo(input_path) + logger.info("Converting curves for %s", input_path) + if font_to_quadratic(ufo, **kwargs): + logger.info("Saving %s", output_path) + if output_path: + ufo.save(output_path) + else: + ufo.save() # save in-place + elif output_path: + _copytree(input_path, output_path) + + +def _samepath(path1, path2): + # TODO on python3+, there's os.path.samefile + path1 = os.path.normcase(os.path.abspath(os.path.realpath(path1))) + path2 = os.path.normcase(os.path.abspath(os.path.realpath(path2))) + return path1 == path2 + + +def _copytree(input_path, output_path): + if _samepath(input_path, output_path): + logger.debug("input and output paths are the same file; skipped copy") + return + if os.path.exists(output_path): + shutil.rmtree(output_path) + shutil.copytree(input_path, output_path) + + +def main(args=None): + """Convert a UFO font from cubic to quadratic curves""" + parser = argparse.ArgumentParser(prog="cu2qu") + parser.add_argument("--version", action="version", version=fontTools.__version__) + parser.add_argument( + "infiles", + nargs="+", + metavar="INPUT", + help="one or more input UFO source file(s).", + ) + parser.add_argument("-v", "--verbose", action="count", default=0) + parser.add_argument( + "-e", + "--conversion-error", + type=float, + metavar="ERROR", + default=None, + help="maxiumum approximation error measured in EM (default: 0.001)", + ) + parser.add_argument( + "-m", + "--mixed", + default=False, + action="store_true", + help="whether to used mixed quadratic and cubic curves", + ) + parser.add_argument( + "--keep-direction", + dest="reverse_direction", + action="store_false", + help="do not reverse the contour direction", + ) + + mode_parser = parser.add_mutually_exclusive_group() + mode_parser.add_argument( + "-i", + "--interpolatable", + action="store_true", + help="whether curve conversion should keep interpolation compatibility", + ) + mode_parser.add_argument( + "-j", + "--jobs", + type=int, + nargs="?", + default=1, + const=_cpu_count(), + metavar="N", + help="Convert using N multiple processes (default: %(default)s)", + ) + + output_parser = parser.add_mutually_exclusive_group() + output_parser.add_argument( + "-o", + "--output-file", + default=None, + metavar="OUTPUT", + help=( + "output filename for the converted UFO. By default fonts are " + "modified in place. This only works with a single input." + ), + ) + output_parser.add_argument( + "-d", + "--output-dir", + default=None, + metavar="DIRECTORY", + help="output directory where to save converted UFOs", + ) + + options = parser.parse_args(args) + + if ufo_module is None: + parser.error("Either ufoLib2 or defcon are required to run this script.") + + if not options.verbose: + level = "WARNING" + elif options.verbose == 1: + level = "INFO" + else: + level = "DEBUG" + logging.basicConfig(level=level) + + if len(options.infiles) > 1 and options.output_file: + parser.error("-o/--output-file can't be used with multile inputs") + + if options.output_dir: + output_dir = options.output_dir + if not os.path.exists(output_dir): + os.mkdir(output_dir) + elif not os.path.isdir(output_dir): + parser.error("'%s' is not a directory" % output_dir) + output_paths = [ + os.path.join(output_dir, os.path.basename(p)) for p in options.infiles + ] + elif options.output_file: + output_paths = [options.output_file] + else: + # save in-place + output_paths = [None] * len(options.infiles) + + kwargs = dict( + dump_stats=options.verbose > 0, + max_err_em=options.conversion_error, + reverse_direction=options.reverse_direction, + all_quadratic=False if options.mixed else True, + ) + + if options.interpolatable: + logger.info("Converting curves compatibly") + ufos = [open_ufo(infile) for infile in options.infiles] + if fonts_to_quadratic(ufos, **kwargs): + for ufo, output_path in zip(ufos, output_paths): + logger.info("Saving %s", output_path) + if output_path: + ufo.save(output_path) + else: + ufo.save() + else: + for input_path, output_path in zip(options.infiles, output_paths): + if output_path: + _copytree(input_path, output_path) + else: + jobs = min(len(options.infiles), options.jobs) if options.jobs > 1 else 1 + if jobs > 1: + func = partial(_font_to_quadratic, **kwargs) + logger.info("Running %d parallel processes", jobs) + with closing(mp.Pool(jobs)) as pool: + pool.starmap(func, zip(options.infiles, output_paths)) + else: + for input_path, output_path in zip(options.infiles, output_paths): + _font_to_quadratic(input_path, output_path, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.c b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.c new file mode 100644 index 00000000..8a94679b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.c @@ -0,0 +1,14893 @@ +/* Generated by Cython 3.0.6 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "define_macros": [ + [ + "CYTHON_TRACE_NOGIL", + "1" + ] + ], + "name": "fontTools.cu2qu.cu2qu", + "sources": [ + "Lib/fontTools/cu2qu/cu2qu.py" + ] + }, + "module_name": "fontTools.cu2qu.cu2qu" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_6" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x030006F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; // borrowed + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; // we don't yet need to distinguish between versions > 11 + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); // we don't have access to __pyx_empty_bytes here + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__cu2qu__cu2qu +#define __PYX_HAVE_API__fontTools__cu2qu__cu2qu +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const wchar_t *u) +{ + const wchar_t *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#endif +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else // Py < 3.12 + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "Lib/fontTools/cu2qu/cu2qu.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen; + +/* "fontTools/cu2qu/cu2qu.py":127 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ +struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen { + PyObject_HEAD + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_a1; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_b1; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_c1; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_d1; + double __pyx_v_delta_2; + double __pyx_v_delta_3; + double __pyx_v_dt; + int __pyx_v_i; + int __pyx_v_n; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + double __pyx_v_t1; + double __pyx_v_t1_2; + int __pyx_t_0; + int __pyx_t_1; + int __pyx_t_2; +}; + +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyIntCompare.proto */ +static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif +#endif +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg // no-op + #define __Pyx_Arg_XDECREF_VARARGS(arg) // no-op - arg is borrowed +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg // no-op, __Pyx_Arg_FASTCALL is direct and this needs + #define __Pyx_Arg_XDECREF_FASTCALL(arg) // no-op - arg was returned from array +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* pep479.proto */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* IterNext.proto */ +#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL) +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *); + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* AssertionsEnabled.proto */ +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (1) +#elif CYTHON_COMPILING_IN_LIMITED_API || (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030C0000) + static int __pyx_assertions_enabled_flag; + #define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag) + static int __Pyx_init_assertions_enabled(void) { + PyObject *builtins, *debug, *debug_str; + int flag; + builtins = PyEval_GetBuiltins(); + if (!builtins) goto bad; + debug_str = PyUnicode_FromStringAndSize("__debug__", 9); + if (!debug_str) goto bad; + debug = PyObject_GetItem(builtins, debug_str); + Py_DECREF(debug_str); + if (!debug) goto bad; + flag = PyObject_IsTrue(debug); + Py_DECREF(debug); + if (flag == -1) goto bad; + __pyx_assertions_enabled_flag = flag; + return 0; + bad: + __pyx_assertions_enabled_flag = 1; + return -1; + } +#else + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (!Py_OptimizeFlag) +#endif + +/* SetItemInt.proto */ +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, + int is_list, int wraparound, int boundscheck); + +/* ModInt[long].proto */ +static CYTHON_INLINE long __Pyx_mod_long(long, long); + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* PyObjectCallNoArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* ValidateBasesTuple.proto */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + +/* pybytes_as_double.proto */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj); +static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length); +static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + as_c_string = PyBytes_AS_STRING(obj); + size = PyBytes_GET_SIZE(obj); +#else + if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) { + return (double)-1; + } +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} +static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + as_c_string = PyByteArray_AS_STRING(obj); + size = PyByteArray_GET_SIZE(obj); +#else + as_c_string = PyByteArray_AsString(obj); + if (as_c_string == NULL) { + return (double)-1; + } + size = PyByteArray_Size(obj); +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} + +/* pyunicode_as_double.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS +static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) { + int last_was_punctuation; + Py_ssize_t i; + last_was_punctuation = 1; + for (i=start; i <= end; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + int is_punctuation = (chr == '_') | (chr == '.'); + *buffer = (char)chr; + buffer += (chr != '_'); + if (unlikely(chr > 127)) goto parse_failure; + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyUnicode_AsDouble_inf_nan(const void* data, int kind, Py_ssize_t start, Py_ssize_t length) { + int matches = 1; + Py_UCS4 chr; + Py_UCS4 sign = PyUnicode_READ(kind, data, start); + int is_signed = (sign == '-') | (sign == '+'); + start += is_signed; + length -= is_signed; + switch (PyUnicode_READ(kind, data, start)) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'a') | (chr == 'A'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'n') | (chr == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'f') | (chr == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+3); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+4); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+5); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+6); + matches &= (chr == 't') | (chr == 'T'); + chr = PyUnicode_READ(kind, data, start+7); + matches &= (chr == 'y') | (chr == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) { + double value; + const char *last; + char *end; + Py_ssize_t start, length = PyUnicode_GET_LENGTH(obj); + const int kind = PyUnicode_KIND(obj); + const void* data = PyUnicode_DATA(obj); + start = 0; + while (Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, start))) + start++; + while (start < length - 1 && Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, length - 1))) + length--; + length -= start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyUnicode_AsDouble_inf_nan(data, kind, start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + if (length < 40) { + char number[40]; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((length + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} +#endif +static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) { +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS + if (unlikely(__Pyx_PyUnicode_READY(obj) == -1)) + return (double)-1; + if (likely(PyUnicode_IS_ASCII(obj))) { + const char *s; + Py_ssize_t length; + s = PyUnicode_AsUTF8AndSize(obj, &length); + return __Pyx__PyBytes_AsDouble(obj, s, length); + } + return __Pyx_PyUnicode_AsDouble_WithSpaces(obj); +#else + return __Pyx_SlowPyString_AsDouble(obj); +#endif +} + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; // used by FusedFunction for copying defaults + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* FromPy.proto */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject*); + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* ToPy.proto */ +#define __pyx_PyComplex_FromComplex(z)\ + PyComplex_FromDoubles((double)__Pyx_CREAL(z),\ + (double)__Pyx_CIMAG(z)) + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* CoroutineBase.proto */ +struct __pyx_CoroutineObject; +typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else +typedef struct { + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct __pyx_CoroutineObject { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; + PyObject *gi_weakreflist; + PyObject *classobj; + PyObject *yieldfrom; + PyObject *gi_name; + PyObject *gi_qualname; + PyObject *gi_modulename; + PyObject *gi_code; + PyObject *gi_frame; + int resume_label; + char is_running; +} __pyx_CoroutineObject; +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); +static int __Pyx_Coroutine_clear(PyObject *self); +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); +static PyObject *__Pyx_Coroutine_Close(PyObject *self); +static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else +#define __Pyx_Coroutine_SwapException(self) {\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ + } +#define __Pyx_Coroutine_ResetAndClearException(self) {\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ + } +#endif +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) +#else +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) +#endif +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); + +/* PatchModuleWithCoroutine.proto */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); + +/* PatchGeneratorABC.proto */ +static int __Pyx_patch_abc(void); + +/* Generator.proto */ +#define __Pyx_Generator_USED +#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType) +#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ + __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name) +static PyObject *__Pyx_Generator_Next(PyObject *self); +static int __pyx_Generator_init(PyObject *module); + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.cu2qu.cu2qu" */ +static CYTHON_INLINE double __pyx_f_9fontTools_5cu2qu_5cu2qu_dot(__pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_points(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_parameters(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_n_iter(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, PyObject *); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_three(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE __pyx_t_double_complex __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_control(double, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE __pyx_t_double_complex __pyx_f_9fontTools_5cu2qu_5cu2qu_calc_intersect(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static int __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, double); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_quadratic(PyObject *, double); /*proto*/ +static PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_spline(PyObject *, int, double, int); /*proto*/ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.cu2qu.cu2qu" +extern int __pyx_module_is_main_fontTools__cu2qu__cu2qu; +int __pyx_module_is_main_fontTools__cu2qu__cu2qu = 0; + +/* Implementation of "fontTools.cu2qu.cu2qu" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_AttributeError; +static PyObject *__pyx_builtin_ImportError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_ZeroDivisionError; +static PyObject *__pyx_builtin_AssertionError; +/* #### Code section: string_decls ### */ +static const char __pyx_k_a[] = "a"; +static const char __pyx_k_b[] = "b"; +static const char __pyx_k_c[] = "c"; +static const char __pyx_k_d[] = "d"; +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_l[] = "l"; +static const char __pyx_k_n[] = "n"; +static const char __pyx_k_p[] = "p"; +static const char __pyx_k_s[] = "s"; +static const char __pyx_k__2[] = "."; +static const char __pyx_k__3[] = "*"; +static const char __pyx_k__9[] = "?"; +static const char __pyx_k_a1[] = "a1"; +static const char __pyx_k_b1[] = "b1"; +static const char __pyx_k_c1[] = "c1"; +static const char __pyx_k_d1[] = "d1"; +static const char __pyx_k_dt[] = "dt"; +static const char __pyx_k_gc[] = "gc"; +static const char __pyx_k_p0[] = "p0"; +static const char __pyx_k_p1[] = "p1"; +static const char __pyx_k_p2[] = "p2"; +static const char __pyx_k_p3[] = "p3"; +static const char __pyx_k_t1[] = "t1"; +static const char __pyx_k_NAN[] = "NAN"; +static const char __pyx_k_NaN[] = "NaN"; +static const char __pyx_k_all[] = "__all__"; +static const char __pyx_k_args[] = "args"; +static const char __pyx_k_imag[] = "imag"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_math[] = "math"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_real[] = "real"; +static const char __pyx_k_send[] = "send"; +static const char __pyx_k_spec[] = "__spec__"; +static const char __pyx_k_t1_2[] = "t1_2"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_Error[] = "Error"; +static const char __pyx_k_MAX_N[] = "MAX_N"; +static const char __pyx_k_close[] = "close"; +static const char __pyx_k_curve[] = "curve"; +static const char __pyx_k_isnan[] = "isnan"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_throw[] = "throw"; +static const char __pyx_k_curves[] = "curves"; +static const char __pyx_k_cython[] = "cython"; +static const char __pyx_k_enable[] = "enable"; +static const char __pyx_k_errors[] = "errors"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_last_i[] = "last_i"; +static const char __pyx_k_spline[] = "spline"; +static const char __pyx_k_delta_2[] = "delta_2"; +static const char __pyx_k_delta_3[] = "delta_3"; +static const char __pyx_k_disable[] = "disable"; +static const char __pyx_k_max_err[] = "max_err"; +static const char __pyx_k_splines[] = "splines"; +static const char __pyx_k_COMPILED[] = "COMPILED"; +static const char __pyx_k_isenabled[] = "isenabled"; +static const char __pyx_k_Cu2QuError[] = "Cu2QuError"; +static const char __pyx_k_max_errors[] = "max_errors"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_all_quadratic[] = "all_quadratic"; +static const char __pyx_k_AssertionError[] = "AssertionError"; +static const char __pyx_k_AttributeError[] = "AttributeError"; +static const char __pyx_k_fontTools_misc[] = "fontTools.misc"; +static const char __pyx_k_ZeroDivisionError[] = "ZeroDivisionError"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_curve_to_quadratic[] = "curve_to_quadratic"; +static const char __pyx_k_ApproxNotFoundError[] = "ApproxNotFoundError"; +static const char __pyx_k_curves_to_quadratic[] = "curves_to_quadratic"; +static const char __pyx_k_fontTools_cu2qu_cu2qu[] = "fontTools.cu2qu.cu2qu"; +static const char __pyx_k_split_cubic_into_n_gen[] = "_split_cubic_into_n_gen"; +static const char __pyx_k_Lib_fontTools_cu2qu_cu2qu_py[] = "Lib/fontTools/cu2qu/cu2qu.py"; +static const char __pyx_k_curves_to_quadratic_line_474[] = "curves_to_quadratic (line 474)"; +static const char __pyx_k_Return_quadratic_Bezier_splines[] = "Return quadratic Bezier splines approximating the input cubic Beziers.\n\n Args:\n curves: A sequence of *n* curves, each curve being a sequence of four\n 2D tuples.\n max_errors: A sequence of *n* floats representing the maximum permissible\n deviation from each of the cubic Bezier curves.\n all_quadratic (bool): If True (default) returned values are a\n quadratic spline. If False, they are either a single quadratic\n curve or a single cubic curve.\n\n Example::\n\n >>> curves_to_quadratic( [\n ... [ (50,50), (100,100), (150,100), (200,50) ],\n ... [ (75,50), (120,100), (150,75), (200,60) ]\n ... ], [1,1] )\n [[(50.0, 50.0), (75.0, 75.0), (125.0, 91.66666666666666), (175.0, 75.0), (200.0, 50.0)], [(75.0, 50.0), (97.5, 75.0), (135.41666666666666, 82.08333333333333), (175.0, 67.5), (200.0, 60.0)]]\n\n The returned splines have \"implied oncurve points\" suitable for use in\n TrueType ``glif`` outlines - i.e. in the first spline returned above,\n the first quadratic segment runs from (50,50) to\n ( (75 + 125)/2 , (120 + 91.666..)/2 ) = (100, 83.333...).\n\n Returns:\n If all_quadratic is True, a list of splines, each spline being a list\n of 2D tuples.\n\n If all_quadratic is False, a list of curves, each curve being a quadratic\n (length 3), or cubic (length 4).\n\n Raises:\n fontTools.cu2qu.Errors.ApproxNotFoundError: if no suitable approximation\n can be found for all curves with the given parameters.\n "; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu__split_cubic_into_n_gen(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3, int __pyx_v_n); /* proto */ +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu_3curve_to_quadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, double __pyx_v_max_err, int __pyx_v_all_quadratic); /* proto */ +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu_5curves_to_quadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curves, PyObject *__pyx_v_max_errors, int __pyx_v_all_quadratic); /* proto */ +static PyObject *__pyx_tp_new_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + PyObject *__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen; + #endif + PyTypeObject *__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen; + PyObject *__pyx_n_s_ApproxNotFoundError; + PyObject *__pyx_n_s_AssertionError; + PyObject *__pyx_n_s_AttributeError; + PyObject *__pyx_n_s_COMPILED; + PyObject *__pyx_n_s_Cu2QuError; + PyObject *__pyx_n_s_Error; + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py; + PyObject *__pyx_n_s_MAX_N; + PyObject *__pyx_n_s_NAN; + PyObject *__pyx_n_u_NaN; + PyObject *__pyx_kp_u_Return_quadratic_Bezier_splines; + PyObject *__pyx_n_s_ZeroDivisionError; + PyObject *__pyx_kp_u__2; + PyObject *__pyx_n_s__3; + PyObject *__pyx_n_s__9; + PyObject *__pyx_n_s_a; + PyObject *__pyx_n_s_a1; + PyObject *__pyx_n_s_all; + PyObject *__pyx_n_s_all_quadratic; + PyObject *__pyx_n_s_args; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_b; + PyObject *__pyx_n_s_b1; + PyObject *__pyx_n_s_c; + PyObject *__pyx_n_s_c1; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_close; + PyObject *__pyx_n_s_curve; + PyObject *__pyx_n_s_curve_to_quadratic; + PyObject *__pyx_n_u_curve_to_quadratic; + PyObject *__pyx_n_s_curves; + PyObject *__pyx_n_s_curves_to_quadratic; + PyObject *__pyx_n_u_curves_to_quadratic; + PyObject *__pyx_kp_u_curves_to_quadratic_line_474; + PyObject *__pyx_n_s_cython; + PyObject *__pyx_n_s_d; + PyObject *__pyx_n_s_d1; + PyObject *__pyx_n_s_delta_2; + PyObject *__pyx_n_s_delta_3; + PyObject *__pyx_kp_u_disable; + PyObject *__pyx_n_s_dt; + PyObject *__pyx_kp_u_enable; + PyObject *__pyx_n_s_errors; + PyObject *__pyx_n_s_fontTools_cu2qu_cu2qu; + PyObject *__pyx_n_s_fontTools_misc; + PyObject *__pyx_kp_u_gc; + PyObject *__pyx_n_s_i; + PyObject *__pyx_n_s_imag; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_kp_u_isenabled; + PyObject *__pyx_n_s_isnan; + PyObject *__pyx_n_s_l; + PyObject *__pyx_n_s_last_i; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_s_math; + PyObject *__pyx_n_s_max_err; + PyObject *__pyx_n_s_max_errors; + PyObject *__pyx_n_s_n; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_p; + PyObject *__pyx_n_s_p0; + PyObject *__pyx_n_s_p1; + PyObject *__pyx_n_s_p2; + PyObject *__pyx_n_s_p3; + PyObject *__pyx_n_s_range; + PyObject *__pyx_n_s_real; + PyObject *__pyx_n_s_s; + PyObject *__pyx_n_s_send; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_spline; + PyObject *__pyx_n_s_splines; + PyObject *__pyx_n_s_split_cubic_into_n_gen; + PyObject *__pyx_n_s_t1; + PyObject *__pyx_n_s_t1_2; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_throw; + PyObject *__pyx_int_1; + PyObject *__pyx_int_2; + PyObject *__pyx_int_3; + PyObject *__pyx_int_4; + PyObject *__pyx_int_6; + PyObject *__pyx_int_100; + PyObject *__pyx_codeobj_; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__5; + PyObject *__pyx_tuple__7; + PyObject *__pyx_codeobj__6; + PyObject *__pyx_codeobj__8; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen); + Py_CLEAR(clear_module_state->__pyx_n_s_ApproxNotFoundError); + Py_CLEAR(clear_module_state->__pyx_n_s_AssertionError); + Py_CLEAR(clear_module_state->__pyx_n_s_AttributeError); + Py_CLEAR(clear_module_state->__pyx_n_s_COMPILED); + Py_CLEAR(clear_module_state->__pyx_n_s_Cu2QuError); + Py_CLEAR(clear_module_state->__pyx_n_s_Error); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py); + Py_CLEAR(clear_module_state->__pyx_n_s_MAX_N); + Py_CLEAR(clear_module_state->__pyx_n_s_NAN); + Py_CLEAR(clear_module_state->__pyx_n_u_NaN); + Py_CLEAR(clear_module_state->__pyx_kp_u_Return_quadratic_Bezier_splines); + Py_CLEAR(clear_module_state->__pyx_n_s_ZeroDivisionError); + Py_CLEAR(clear_module_state->__pyx_kp_u__2); + Py_CLEAR(clear_module_state->__pyx_n_s__3); + Py_CLEAR(clear_module_state->__pyx_n_s__9); + Py_CLEAR(clear_module_state->__pyx_n_s_a); + Py_CLEAR(clear_module_state->__pyx_n_s_a1); + Py_CLEAR(clear_module_state->__pyx_n_s_all); + Py_CLEAR(clear_module_state->__pyx_n_s_all_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_args); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_b); + Py_CLEAR(clear_module_state->__pyx_n_s_b1); + Py_CLEAR(clear_module_state->__pyx_n_s_c); + Py_CLEAR(clear_module_state->__pyx_n_s_c1); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_close); + Py_CLEAR(clear_module_state->__pyx_n_s_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_to_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_u_curve_to_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_curves); + Py_CLEAR(clear_module_state->__pyx_n_s_curves_to_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_u_curves_to_quadratic); + Py_CLEAR(clear_module_state->__pyx_kp_u_curves_to_quadratic_line_474); + Py_CLEAR(clear_module_state->__pyx_n_s_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_d); + Py_CLEAR(clear_module_state->__pyx_n_s_d1); + Py_CLEAR(clear_module_state->__pyx_n_s_delta_2); + Py_CLEAR(clear_module_state->__pyx_n_s_delta_3); + Py_CLEAR(clear_module_state->__pyx_kp_u_disable); + Py_CLEAR(clear_module_state->__pyx_n_s_dt); + Py_CLEAR(clear_module_state->__pyx_kp_u_enable); + Py_CLEAR(clear_module_state->__pyx_n_s_errors); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_cu2qu_cu2qu); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc); + Py_CLEAR(clear_module_state->__pyx_kp_u_gc); + Py_CLEAR(clear_module_state->__pyx_n_s_i); + Py_CLEAR(clear_module_state->__pyx_n_s_imag); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); + Py_CLEAR(clear_module_state->__pyx_n_s_isnan); + Py_CLEAR(clear_module_state->__pyx_n_s_l); + Py_CLEAR(clear_module_state->__pyx_n_s_last_i); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_s_math); + Py_CLEAR(clear_module_state->__pyx_n_s_max_err); + Py_CLEAR(clear_module_state->__pyx_n_s_max_errors); + Py_CLEAR(clear_module_state->__pyx_n_s_n); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_p); + Py_CLEAR(clear_module_state->__pyx_n_s_p0); + Py_CLEAR(clear_module_state->__pyx_n_s_p1); + Py_CLEAR(clear_module_state->__pyx_n_s_p2); + Py_CLEAR(clear_module_state->__pyx_n_s_p3); + Py_CLEAR(clear_module_state->__pyx_n_s_range); + Py_CLEAR(clear_module_state->__pyx_n_s_real); + Py_CLEAR(clear_module_state->__pyx_n_s_s); + Py_CLEAR(clear_module_state->__pyx_n_s_send); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_spline); + Py_CLEAR(clear_module_state->__pyx_n_s_splines); + Py_CLEAR(clear_module_state->__pyx_n_s_split_cubic_into_n_gen); + Py_CLEAR(clear_module_state->__pyx_n_s_t1); + Py_CLEAR(clear_module_state->__pyx_n_s_t1_2); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_throw); + Py_CLEAR(clear_module_state->__pyx_int_1); + Py_CLEAR(clear_module_state->__pyx_int_2); + Py_CLEAR(clear_module_state->__pyx_int_3); + Py_CLEAR(clear_module_state->__pyx_int_4); + Py_CLEAR(clear_module_state->__pyx_int_6); + Py_CLEAR(clear_module_state->__pyx_int_100); + Py_CLEAR(clear_module_state->__pyx_codeobj_); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__5); + Py_CLEAR(clear_module_state->__pyx_tuple__7); + Py_CLEAR(clear_module_state->__pyx_codeobj__6); + Py_CLEAR(clear_module_state->__pyx_codeobj__8); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen); + Py_VISIT(traverse_module_state->__pyx_n_s_ApproxNotFoundError); + Py_VISIT(traverse_module_state->__pyx_n_s_AssertionError); + Py_VISIT(traverse_module_state->__pyx_n_s_AttributeError); + Py_VISIT(traverse_module_state->__pyx_n_s_COMPILED); + Py_VISIT(traverse_module_state->__pyx_n_s_Cu2QuError); + Py_VISIT(traverse_module_state->__pyx_n_s_Error); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py); + Py_VISIT(traverse_module_state->__pyx_n_s_MAX_N); + Py_VISIT(traverse_module_state->__pyx_n_s_NAN); + Py_VISIT(traverse_module_state->__pyx_n_u_NaN); + Py_VISIT(traverse_module_state->__pyx_kp_u_Return_quadratic_Bezier_splines); + Py_VISIT(traverse_module_state->__pyx_n_s_ZeroDivisionError); + Py_VISIT(traverse_module_state->__pyx_kp_u__2); + Py_VISIT(traverse_module_state->__pyx_n_s__3); + Py_VISIT(traverse_module_state->__pyx_n_s__9); + Py_VISIT(traverse_module_state->__pyx_n_s_a); + Py_VISIT(traverse_module_state->__pyx_n_s_a1); + Py_VISIT(traverse_module_state->__pyx_n_s_all); + Py_VISIT(traverse_module_state->__pyx_n_s_all_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_args); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_b); + Py_VISIT(traverse_module_state->__pyx_n_s_b1); + Py_VISIT(traverse_module_state->__pyx_n_s_c); + Py_VISIT(traverse_module_state->__pyx_n_s_c1); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_close); + Py_VISIT(traverse_module_state->__pyx_n_s_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_to_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_u_curve_to_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_curves); + Py_VISIT(traverse_module_state->__pyx_n_s_curves_to_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_u_curves_to_quadratic); + Py_VISIT(traverse_module_state->__pyx_kp_u_curves_to_quadratic_line_474); + Py_VISIT(traverse_module_state->__pyx_n_s_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_d); + Py_VISIT(traverse_module_state->__pyx_n_s_d1); + Py_VISIT(traverse_module_state->__pyx_n_s_delta_2); + Py_VISIT(traverse_module_state->__pyx_n_s_delta_3); + Py_VISIT(traverse_module_state->__pyx_kp_u_disable); + Py_VISIT(traverse_module_state->__pyx_n_s_dt); + Py_VISIT(traverse_module_state->__pyx_kp_u_enable); + Py_VISIT(traverse_module_state->__pyx_n_s_errors); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_cu2qu_cu2qu); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc); + Py_VISIT(traverse_module_state->__pyx_kp_u_gc); + Py_VISIT(traverse_module_state->__pyx_n_s_i); + Py_VISIT(traverse_module_state->__pyx_n_s_imag); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); + Py_VISIT(traverse_module_state->__pyx_n_s_isnan); + Py_VISIT(traverse_module_state->__pyx_n_s_l); + Py_VISIT(traverse_module_state->__pyx_n_s_last_i); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_s_math); + Py_VISIT(traverse_module_state->__pyx_n_s_max_err); + Py_VISIT(traverse_module_state->__pyx_n_s_max_errors); + Py_VISIT(traverse_module_state->__pyx_n_s_n); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_p); + Py_VISIT(traverse_module_state->__pyx_n_s_p0); + Py_VISIT(traverse_module_state->__pyx_n_s_p1); + Py_VISIT(traverse_module_state->__pyx_n_s_p2); + Py_VISIT(traverse_module_state->__pyx_n_s_p3); + Py_VISIT(traverse_module_state->__pyx_n_s_range); + Py_VISIT(traverse_module_state->__pyx_n_s_real); + Py_VISIT(traverse_module_state->__pyx_n_s_s); + Py_VISIT(traverse_module_state->__pyx_n_s_send); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_spline); + Py_VISIT(traverse_module_state->__pyx_n_s_splines); + Py_VISIT(traverse_module_state->__pyx_n_s_split_cubic_into_n_gen); + Py_VISIT(traverse_module_state->__pyx_n_s_t1); + Py_VISIT(traverse_module_state->__pyx_n_s_t1_2); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_throw); + Py_VISIT(traverse_module_state->__pyx_int_1); + Py_VISIT(traverse_module_state->__pyx_int_2); + Py_VISIT(traverse_module_state->__pyx_int_3); + Py_VISIT(traverse_module_state->__pyx_int_4); + Py_VISIT(traverse_module_state->__pyx_int_6); + Py_VISIT(traverse_module_state->__pyx_int_100); + Py_VISIT(traverse_module_state->__pyx_codeobj_); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__5); + Py_VISIT(traverse_module_state->__pyx_tuple__7); + Py_VISIT(traverse_module_state->__pyx_codeobj__6); + Py_VISIT(traverse_module_state->__pyx_codeobj__8); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#define __pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen __pyx_mstate_global->__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen +#endif +#define __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen __pyx_mstate_global->__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen +#define __pyx_n_s_ApproxNotFoundError __pyx_mstate_global->__pyx_n_s_ApproxNotFoundError +#define __pyx_n_s_AssertionError __pyx_mstate_global->__pyx_n_s_AssertionError +#define __pyx_n_s_AttributeError __pyx_mstate_global->__pyx_n_s_AttributeError +#define __pyx_n_s_COMPILED __pyx_mstate_global->__pyx_n_s_COMPILED +#define __pyx_n_s_Cu2QuError __pyx_mstate_global->__pyx_n_s_Cu2QuError +#define __pyx_n_s_Error __pyx_mstate_global->__pyx_n_s_Error +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py __pyx_mstate_global->__pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py +#define __pyx_n_s_MAX_N __pyx_mstate_global->__pyx_n_s_MAX_N +#define __pyx_n_s_NAN __pyx_mstate_global->__pyx_n_s_NAN +#define __pyx_n_u_NaN __pyx_mstate_global->__pyx_n_u_NaN +#define __pyx_kp_u_Return_quadratic_Bezier_splines __pyx_mstate_global->__pyx_kp_u_Return_quadratic_Bezier_splines +#define __pyx_n_s_ZeroDivisionError __pyx_mstate_global->__pyx_n_s_ZeroDivisionError +#define __pyx_kp_u__2 __pyx_mstate_global->__pyx_kp_u__2 +#define __pyx_n_s__3 __pyx_mstate_global->__pyx_n_s__3 +#define __pyx_n_s__9 __pyx_mstate_global->__pyx_n_s__9 +#define __pyx_n_s_a __pyx_mstate_global->__pyx_n_s_a +#define __pyx_n_s_a1 __pyx_mstate_global->__pyx_n_s_a1 +#define __pyx_n_s_all __pyx_mstate_global->__pyx_n_s_all +#define __pyx_n_s_all_quadratic __pyx_mstate_global->__pyx_n_s_all_quadratic +#define __pyx_n_s_args __pyx_mstate_global->__pyx_n_s_args +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_b __pyx_mstate_global->__pyx_n_s_b +#define __pyx_n_s_b1 __pyx_mstate_global->__pyx_n_s_b1 +#define __pyx_n_s_c __pyx_mstate_global->__pyx_n_s_c +#define __pyx_n_s_c1 __pyx_mstate_global->__pyx_n_s_c1 +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_close __pyx_mstate_global->__pyx_n_s_close +#define __pyx_n_s_curve __pyx_mstate_global->__pyx_n_s_curve +#define __pyx_n_s_curve_to_quadratic __pyx_mstate_global->__pyx_n_s_curve_to_quadratic +#define __pyx_n_u_curve_to_quadratic __pyx_mstate_global->__pyx_n_u_curve_to_quadratic +#define __pyx_n_s_curves __pyx_mstate_global->__pyx_n_s_curves +#define __pyx_n_s_curves_to_quadratic __pyx_mstate_global->__pyx_n_s_curves_to_quadratic +#define __pyx_n_u_curves_to_quadratic __pyx_mstate_global->__pyx_n_u_curves_to_quadratic +#define __pyx_kp_u_curves_to_quadratic_line_474 __pyx_mstate_global->__pyx_kp_u_curves_to_quadratic_line_474 +#define __pyx_n_s_cython __pyx_mstate_global->__pyx_n_s_cython +#define __pyx_n_s_d __pyx_mstate_global->__pyx_n_s_d +#define __pyx_n_s_d1 __pyx_mstate_global->__pyx_n_s_d1 +#define __pyx_n_s_delta_2 __pyx_mstate_global->__pyx_n_s_delta_2 +#define __pyx_n_s_delta_3 __pyx_mstate_global->__pyx_n_s_delta_3 +#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable +#define __pyx_n_s_dt __pyx_mstate_global->__pyx_n_s_dt +#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable +#define __pyx_n_s_errors __pyx_mstate_global->__pyx_n_s_errors +#define __pyx_n_s_fontTools_cu2qu_cu2qu __pyx_mstate_global->__pyx_n_s_fontTools_cu2qu_cu2qu +#define __pyx_n_s_fontTools_misc __pyx_mstate_global->__pyx_n_s_fontTools_misc +#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc +#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i +#define __pyx_n_s_imag __pyx_mstate_global->__pyx_n_s_imag +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled +#define __pyx_n_s_isnan __pyx_mstate_global->__pyx_n_s_isnan +#define __pyx_n_s_l __pyx_mstate_global->__pyx_n_s_l +#define __pyx_n_s_last_i __pyx_mstate_global->__pyx_n_s_last_i +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_s_math __pyx_mstate_global->__pyx_n_s_math +#define __pyx_n_s_max_err __pyx_mstate_global->__pyx_n_s_max_err +#define __pyx_n_s_max_errors __pyx_mstate_global->__pyx_n_s_max_errors +#define __pyx_n_s_n __pyx_mstate_global->__pyx_n_s_n +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_p __pyx_mstate_global->__pyx_n_s_p +#define __pyx_n_s_p0 __pyx_mstate_global->__pyx_n_s_p0 +#define __pyx_n_s_p1 __pyx_mstate_global->__pyx_n_s_p1 +#define __pyx_n_s_p2 __pyx_mstate_global->__pyx_n_s_p2 +#define __pyx_n_s_p3 __pyx_mstate_global->__pyx_n_s_p3 +#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range +#define __pyx_n_s_real __pyx_mstate_global->__pyx_n_s_real +#define __pyx_n_s_s __pyx_mstate_global->__pyx_n_s_s +#define __pyx_n_s_send __pyx_mstate_global->__pyx_n_s_send +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_spline __pyx_mstate_global->__pyx_n_s_spline +#define __pyx_n_s_splines __pyx_mstate_global->__pyx_n_s_splines +#define __pyx_n_s_split_cubic_into_n_gen __pyx_mstate_global->__pyx_n_s_split_cubic_into_n_gen +#define __pyx_n_s_t1 __pyx_mstate_global->__pyx_n_s_t1 +#define __pyx_n_s_t1_2 __pyx_mstate_global->__pyx_n_s_t1_2 +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_throw __pyx_mstate_global->__pyx_n_s_throw +#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 +#define __pyx_int_2 __pyx_mstate_global->__pyx_int_2 +#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3 +#define __pyx_int_4 __pyx_mstate_global->__pyx_int_4 +#define __pyx_int_6 __pyx_mstate_global->__pyx_int_6 +#define __pyx_int_100 __pyx_mstate_global->__pyx_int_100 +#define __pyx_codeobj_ __pyx_mstate_global->__pyx_codeobj_ +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 +#define __pyx_tuple__7 __pyx_mstate_global->__pyx_tuple__7 +#define __pyx_codeobj__6 __pyx_mstate_global->__pyx_codeobj__6 +#define __pyx_codeobj__8 __pyx_mstate_global->__pyx_codeobj__8 +/* #### Code section: module_code ### */ + +/* "fontTools/cu2qu/cu2qu.py":40 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + +static CYTHON_INLINE double __pyx_f_9fontTools_5cu2qu_5cu2qu_dot(__pyx_t_double_complex __pyx_v_v1, __pyx_t_double_complex __pyx_v_v2) { + double __pyx_r; + + /* "fontTools/cu2qu/cu2qu.py":54 + * double: Dot product. + * """ + * return (v1 * v2.conjugate()).real # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __Pyx_CREAL(__Pyx_c_prod_double(__pyx_v_v1, __Pyx_c_conj_double(__pyx_v_v2))); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":40 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":57 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_points(__pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d) { + __pyx_t_double_complex __pyx_v__1; + __pyx_t_double_complex __pyx_v__2; + __pyx_t_double_complex __pyx_v__3; + __pyx_t_double_complex __pyx_v__4; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __pyx_t_double_complex __pyx_t_1; + __pyx_t_double_complex __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calc_cubic_points", 1); + + /* "fontTools/cu2qu/cu2qu.py":64 + * ) + * def calc_cubic_points(a, b, c, d): + * _1 = d # <<<<<<<<<<<<<< + * _2 = (c / 3.0) + d + * _3 = (b + c) / 3.0 + _2 + */ + __pyx_v__1 = __pyx_v_d; + + /* "fontTools/cu2qu/cu2qu.py":65 + * def calc_cubic_points(a, b, c, d): + * _1 = d + * _2 = (c / 3.0) + d # <<<<<<<<<<<<<< + * _3 = (b + c) / 3.0 + _2 + * _4 = a + d + c + b + */ + __pyx_t_1 = __pyx_t_double_complex_from_parts(3.0, 0); + if (unlikely(__Pyx_c_is_zero_double(__pyx_t_1))) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 65, __pyx_L1_error) + } + __pyx_v__2 = __Pyx_c_sum_double(__Pyx_c_quot_double(__pyx_v_c, __pyx_t_1), __pyx_v_d); + + /* "fontTools/cu2qu/cu2qu.py":66 + * _1 = d + * _2 = (c / 3.0) + d + * _3 = (b + c) / 3.0 + _2 # <<<<<<<<<<<<<< + * _4 = a + d + c + b + * return _1, _2, _3, _4 + */ + __pyx_t_1 = __Pyx_c_sum_double(__pyx_v_b, __pyx_v_c); + __pyx_t_2 = __pyx_t_double_complex_from_parts(3.0, 0); + if (unlikely(__Pyx_c_is_zero_double(__pyx_t_2))) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 66, __pyx_L1_error) + } + __pyx_v__3 = __Pyx_c_sum_double(__Pyx_c_quot_double(__pyx_t_1, __pyx_t_2), __pyx_v__2); + + /* "fontTools/cu2qu/cu2qu.py":67 + * _2 = (c / 3.0) + d + * _3 = (b + c) / 3.0 + _2 + * _4 = a + d + c + b # <<<<<<<<<<<<<< + * return _1, _2, _3, _4 + * + */ + __pyx_v__4 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_a, __pyx_v_d), __pyx_v_c), __pyx_v_b); + + /* "fontTools/cu2qu/cu2qu.py":68 + * _3 = (b + c) / 3.0 + _2 + * _4 = a + d + c + b + * return _1, _2, _3, _4 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v__1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v__2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v__3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_v__4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3)) __PYX_ERR(0, 68, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_t_6)) __PYX_ERR(0, 68, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_r = __pyx_t_7; + __pyx_t_7 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":57 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.calc_cubic_points", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":71 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_parameters(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_d; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calc_cubic_parameters", 1); + + /* "fontTools/cu2qu/cu2qu.py":78 + * @cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) + * def calc_cubic_parameters(p0, p1, p2, p3): + * c = (p1 - p0) * 3.0 # <<<<<<<<<<<<<< + * b = (p2 - p1) * 3.0 - c + * d = p0 + */ + __pyx_v_c = __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p0), __pyx_t_double_complex_from_parts(3.0, 0)); + + /* "fontTools/cu2qu/cu2qu.py":79 + * def calc_cubic_parameters(p0, p1, p2, p3): + * c = (p1 - p0) * 3.0 + * b = (p2 - p1) * 3.0 - c # <<<<<<<<<<<<<< + * d = p0 + * a = p3 - d - c - b + */ + __pyx_v_b = __Pyx_c_diff_double(__Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p1), __pyx_t_double_complex_from_parts(3.0, 0)), __pyx_v_c); + + /* "fontTools/cu2qu/cu2qu.py":80 + * c = (p1 - p0) * 3.0 + * b = (p2 - p1) * 3.0 - c + * d = p0 # <<<<<<<<<<<<<< + * a = p3 - d - c - b + * return a, b, c, d + */ + __pyx_v_d = __pyx_v_p0; + + /* "fontTools/cu2qu/cu2qu.py":81 + * b = (p2 - p1) * 3.0 - c + * d = p0 + * a = p3 - d - c - b # <<<<<<<<<<<<<< + * return a, b, c, d + * + */ + __pyx_v_a = __Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__pyx_v_p3, __pyx_v_d), __pyx_v_c), __pyx_v_b); + + /* "fontTools/cu2qu/cu2qu.py":82 + * d = p0 + * a = p3 - d - c - b + * return a, b, c, d # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_d); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2)) __PYX_ERR(0, 82, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 82, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4)) __PYX_ERR(0, 82, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":71 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.calc_cubic_parameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":85 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_n_iter(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3, PyObject *__pyx_v_n) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + __pyx_t_double_complex __pyx_t_7; + __pyx_t_double_complex __pyx_t_8; + __pyx_t_double_complex __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_t_14; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("split_cubic_into_n_iter", 1); + + /* "fontTools/cu2qu/cu2qu.py":107 + * """ + * # Hand-coded special-cases + * if n == 2: # <<<<<<<<<<<<<< + * return iter(split_cubic_into_two(p0, p1, p2, p3)) + * if n == 3: + */ + __pyx_t_1 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_n, __pyx_int_2, 2, 0)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 107, __pyx_L1_error) + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":108 + * # Hand-coded special-cases + * if n == 2: + * return iter(split_cubic_into_two(p0, p1, p2, p3)) # <<<<<<<<<<<<<< + * if n == 3: + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":107 + * """ + * # Hand-coded special-cases + * if n == 2: # <<<<<<<<<<<<<< + * return iter(split_cubic_into_two(p0, p1, p2, p3)) + * if n == 3: + */ + } + + /* "fontTools/cu2qu/cu2qu.py":109 + * if n == 2: + * return iter(split_cubic_into_two(p0, p1, p2, p3)) + * if n == 3: # <<<<<<<<<<<<<< + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + * if n == 4: + */ + __pyx_t_1 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_n, __pyx_int_3, 3, 0)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 109, __pyx_L1_error) + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":110 + * return iter(split_cubic_into_two(p0, p1, p2, p3)) + * if n == 3: + * return iter(split_cubic_into_three(p0, p1, p2, p3)) # <<<<<<<<<<<<<< + * if n == 4: + * a, b = split_cubic_into_two(p0, p1, p2, p3) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_three(__pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":109 + * if n == 2: + * return iter(split_cubic_into_two(p0, p1, p2, p3)) + * if n == 3: # <<<<<<<<<<<<<< + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + * if n == 4: + */ + } + + /* "fontTools/cu2qu/cu2qu.py":111 + * if n == 3: + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + * if n == 4: # <<<<<<<<<<<<<< + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + */ + __pyx_t_1 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_n, __pyx_int_4, 4, 0)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 111, __pyx_L1_error) + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":112 + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + * if n == 4: + * a, b = split_cubic_into_two(p0, p1, p2, p3) # <<<<<<<<<<<<<< + * return iter( + * split_cubic_into_two(a[0], a[1], a[2], a[3]) + */ + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 112, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_4 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 112, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 112, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/cu2qu/cu2qu.py":113 + * if n == 4: + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( # <<<<<<<<<<<<<< + * split_cubic_into_two(a[0], a[1], a[2], a[3]) + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/cu2qu/cu2qu.py":114 + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + * split_cubic_into_two(a[0], a[1], a[2], a[3]) # <<<<<<<<<<<<<< + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) + * ) + */ + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/cu2qu/cu2qu.py":115 + * return iter( + * split_cubic_into_two(a[0], a[1], a[2], a[3]) + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) # <<<<<<<<<<<<<< + * ) + * if n == 6: + */ + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_t_10, __pyx_t_9, __pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/cu2qu/cu2qu.py":113 + * if n == 4: + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( # <<<<<<<<<<<<<< + * split_cubic_into_two(a[0], a[1], a[2], a[3]) + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) + */ + __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":111 + * if n == 3: + * return iter(split_cubic_into_three(p0, p1, p2, p3)) + * if n == 4: # <<<<<<<<<<<<<< + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + */ + } + + /* "fontTools/cu2qu/cu2qu.py":117 + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) + * ) + * if n == 6: # <<<<<<<<<<<<<< + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + */ + __pyx_t_1 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_n, __pyx_int_6, 6, 0)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 117, __pyx_L1_error) + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":118 + * ) + * if n == 6: + * a, b = split_cubic_into_two(p0, p1, p2, p3) # <<<<<<<<<<<<<< + * return iter( + * split_cubic_into_three(a[0], a[1], a[2], a[3]) + */ + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) { + PyObject* sequence = __pyx_t_4; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 118, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 118, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 118, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/cu2qu/cu2qu.py":119 + * if n == 6: + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( # <<<<<<<<<<<<<< + * split_cubic_into_three(a[0], a[1], a[2], a[3]) + * + split_cubic_into_three(b[0], b[1], b[2], b[3]) + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/cu2qu/cu2qu.py":120 + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + * split_cubic_into_three(a[0], a[1], a[2], a[3]) # <<<<<<<<<<<<<< + * + split_cubic_into_three(b[0], b[1], b[2], b[3]) + * ) + */ + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_a, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_three(__pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/cu2qu/cu2qu.py":121 + * return iter( + * split_cubic_into_three(a[0], a[1], a[2], a[3]) + * + split_cubic_into_three(b[0], b[1], b[2], b[3]) # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_three(__pyx_t_10, __pyx_t_9, __pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/cu2qu/cu2qu.py":119 + * if n == 6: + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( # <<<<<<<<<<<<<< + * split_cubic_into_three(a[0], a[1], a[2], a[3]) + * + split_cubic_into_three(b[0], b[1], b[2], b[3]) + */ + __pyx_t_2 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":117 + * + split_cubic_into_two(b[0], b[1], b[2], b[3]) + * ) + * if n == 6: # <<<<<<<<<<<<<< + * a, b = split_cubic_into_two(p0, p1, p2, p3) + * return iter( + */ + } + + /* "fontTools/cu2qu/cu2qu.py":124 + * ) + * + * return _split_cubic_into_n_gen(p0, p1, p2, p3, n) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_split_cubic_into_n_gen); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_p1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_11 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_13 = NULL; + __pyx_t_14 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_13)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_13); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_14 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[6] = {__pyx_t_13, __pyx_t_4, __pyx_t_5, __pyx_t_11, __pyx_t_12, __pyx_v_n}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_14, 5+__pyx_t_14); + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":85 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.split_cubic_into_n_iter", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_5cu2qu_5cu2qu_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/cu2qu/cu2qu.py":127 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_1_split_cubic_into_n_gen(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5cu2qu_5cu2qu__split_cubic_into_n_gen, "_split_cubic_into_n_gen(double complex p0, double complex p1, double complex p2, double complex p3, int n)"); +static PyMethodDef __pyx_mdef_9fontTools_5cu2qu_5cu2qu_1_split_cubic_into_n_gen = {"_split_cubic_into_n_gen", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5cu2qu_5cu2qu_1_split_cubic_into_n_gen, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5cu2qu_5cu2qu__split_cubic_into_n_gen}; +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_1_split_cubic_into_n_gen(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + int __pyx_v_n; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_cubic_into_n_gen (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_p0,&__pyx_n_s_p1,&__pyx_n_s_p2,&__pyx_n_s_p3,&__pyx_n_s_n,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p0)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 127, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_n_gen", 1, 5, 5, 1); __PYX_ERR(0, 127, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_n_gen", 1, 5, 5, 2); __PYX_ERR(0, 127, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_n_gen", 1, 5, 5, 3); __PYX_ERR(0, 127, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_n)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_n_gen", 1, 5, 5, 4); __PYX_ERR(0, 127, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_split_cubic_into_n_gen") < 0)) __PYX_ERR(0, 127, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_p0 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L3_error) + __pyx_v_p1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L3_error) + __pyx_v_p2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L3_error) + __pyx_v_p3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L3_error) + __pyx_v_n = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_n_gen", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 127, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu._split_cubic_into_n_gen", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5cu2qu_5cu2qu__split_cubic_into_n_gen(__pyx_self, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3, __pyx_v_n); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu__split_cubic_into_n_gen(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3, int __pyx_v_n) { + struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_split_cubic_into_n_gen", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *)__pyx_tp_new_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen(__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 127, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_p0 = __pyx_v_p0; + __pyx_cur_scope->__pyx_v_p1 = __pyx_v_p1; + __pyx_cur_scope->__pyx_v_p2 = __pyx_v_p2; + __pyx_cur_scope->__pyx_v_p3 = __pyx_v_p3; + __pyx_cur_scope->__pyx_v_n = __pyx_v_n; + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_5cu2qu_5cu2qu_2generator, __pyx_codeobj_, (PyObject *) __pyx_cur_scope, __pyx_n_s_split_cubic_into_n_gen, __pyx_n_s_split_cubic_into_n_gen, __pyx_n_s_fontTools_cu2qu_cu2qu); if (unlikely(!gen)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu._split_cubic_into_n_gen", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_5cu2qu_5cu2qu_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + __pyx_t_double_complex __pyx_t_8; + __pyx_t_double_complex __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + __pyx_t_double_complex __pyx_t_11; + int __pyx_t_12; + int __pyx_t_13; + int __pyx_t_14; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_cubic_into_n_gen", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L8_resume_from_yield; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 127, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":142 + * ) + * def _split_cubic_into_n_gen(p0, p1, p2, p3, n): + * a, b, c, d = calc_cubic_parameters(p0, p1, p2, p3) # <<<<<<<<<<<<<< + * dt = 1 / n + * delta_2 = dt * dt + */ + __pyx_t_1 = __pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_parameters(__pyx_cur_scope->__pyx_v_p0, __pyx_cur_scope->__pyx_v_p1, __pyx_cur_scope->__pyx_v_p2, __pyx_cur_scope->__pyx_v_p3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 142, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_4 = PyList_GET_ITEM(sequence, 2); + __pyx_t_5 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_7(__pyx_t_6); if (unlikely(!item)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 4) < 0) __PYX_ERR(0, 142, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 142, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_11 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_cur_scope->__pyx_v_a = __pyx_t_8; + __pyx_cur_scope->__pyx_v_b = __pyx_t_9; + __pyx_cur_scope->__pyx_v_c = __pyx_t_10; + __pyx_cur_scope->__pyx_v_d = __pyx_t_11; + + /* "fontTools/cu2qu/cu2qu.py":143 + * def _split_cubic_into_n_gen(p0, p1, p2, p3, n): + * a, b, c, d = calc_cubic_parameters(p0, p1, p2, p3) + * dt = 1 / n # <<<<<<<<<<<<<< + * delta_2 = dt * dt + * delta_3 = dt * delta_2 + */ + if (unlikely(__pyx_cur_scope->__pyx_v_n == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 143, __pyx_L1_error) + } + __pyx_cur_scope->__pyx_v_dt = (1.0 / ((double)__pyx_cur_scope->__pyx_v_n)); + + /* "fontTools/cu2qu/cu2qu.py":144 + * a, b, c, d = calc_cubic_parameters(p0, p1, p2, p3) + * dt = 1 / n + * delta_2 = dt * dt # <<<<<<<<<<<<<< + * delta_3 = dt * delta_2 + * for i in range(n): + */ + __pyx_cur_scope->__pyx_v_delta_2 = (__pyx_cur_scope->__pyx_v_dt * __pyx_cur_scope->__pyx_v_dt); + + /* "fontTools/cu2qu/cu2qu.py":145 + * dt = 1 / n + * delta_2 = dt * dt + * delta_3 = dt * delta_2 # <<<<<<<<<<<<<< + * for i in range(n): + * t1 = i * dt + */ + __pyx_cur_scope->__pyx_v_delta_3 = (__pyx_cur_scope->__pyx_v_dt * __pyx_cur_scope->__pyx_v_delta_2); + + /* "fontTools/cu2qu/cu2qu.py":146 + * delta_2 = dt * dt + * delta_3 = dt * delta_2 + * for i in range(n): # <<<<<<<<<<<<<< + * t1 = i * dt + * t1_2 = t1 * t1 + */ + __pyx_t_12 = __pyx_cur_scope->__pyx_v_n; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_cur_scope->__pyx_v_i = __pyx_t_14; + + /* "fontTools/cu2qu/cu2qu.py":147 + * delta_3 = dt * delta_2 + * for i in range(n): + * t1 = i * dt # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * # calc new a, b, c and d + */ + __pyx_cur_scope->__pyx_v_t1 = (__pyx_cur_scope->__pyx_v_i * __pyx_cur_scope->__pyx_v_dt); + + /* "fontTools/cu2qu/cu2qu.py":148 + * for i in range(n): + * t1 = i * dt + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * # calc new a, b, c and d + * a1 = a * delta_3 + */ + __pyx_cur_scope->__pyx_v_t1_2 = (__pyx_cur_scope->__pyx_v_t1 * __pyx_cur_scope->__pyx_v_t1); + + /* "fontTools/cu2qu/cu2qu.py":150 + * t1_2 = t1 * t1 + * # calc new a, b, c and d + * a1 = a * delta_3 # <<<<<<<<<<<<<< + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt + */ + __pyx_cur_scope->__pyx_v_a1 = __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_3, 0)); + + /* "fontTools/cu2qu/cu2qu.py":151 + * # calc new a, b, c and d + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 # <<<<<<<<<<<<<< + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt + * d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d + */ + __pyx_cur_scope->__pyx_v_b1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_2, 0)); + + /* "fontTools/cu2qu/cu2qu.py":152 + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt # <<<<<<<<<<<<<< + * d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d + * yield calc_cubic_points(a1, b1, c1, d1) + */ + __pyx_cur_scope->__pyx_v_c1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(2, 0), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_c), __Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_dt, 0)); + + /* "fontTools/cu2qu/cu2qu.py":153 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt + * d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d # <<<<<<<<<<<<<< + * yield calc_cubic_points(a1, b1, c1, d1) + * + */ + __pyx_cur_scope->__pyx_v_d1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0)), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_b, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_c, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0))), __pyx_cur_scope->__pyx_v_d); + + /* "fontTools/cu2qu/cu2qu.py":154 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt + * d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d + * yield calc_cubic_points(a1, b1, c1, d1) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __pyx_f_9fontTools_5cu2qu_5cu2qu_calc_cubic_points(__pyx_cur_scope->__pyx_v_a1, __pyx_cur_scope->__pyx_v_b1, __pyx_cur_scope->__pyx_v_c1, __pyx_cur_scope->__pyx_v_d1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_cur_scope->__pyx_t_0 = __pyx_t_12; + __pyx_cur_scope->__pyx_t_1 = __pyx_t_13; + __pyx_cur_scope->__pyx_t_2 = __pyx_t_14; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L8_resume_from_yield:; + __pyx_t_12 = __pyx_cur_scope->__pyx_t_0; + __pyx_t_13 = __pyx_cur_scope->__pyx_t_1; + __pyx_t_14 = __pyx_cur_scope->__pyx_t_2; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 154, __pyx_L1_error) + } + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* "fontTools/cu2qu/cu2qu.py":127 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + + /* function exit code */ + PyErr_SetNone(PyExc_StopIteration); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("_split_cubic_into_n_gen", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":157 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_two(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + __pyx_t_double_complex __pyx_v_mid; + __pyx_t_double_complex __pyx_v_deriv3; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __pyx_t_double_complex __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("split_cubic_into_two", 1); + + /* "fontTools/cu2qu/cu2qu.py":178 + * values). + * """ + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 # <<<<<<<<<<<<<< + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + */ + __pyx_v_mid = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_p0, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__pyx_v_p1, __pyx_v_p2))), __pyx_v_p3), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/cu2qu/cu2qu.py":179 + * """ + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 # <<<<<<<<<<<<<< + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + */ + __pyx_v_deriv3 = __Pyx_c_prod_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_p3, __pyx_v_p2), __pyx_v_p1), __pyx_v_p0), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/cu2qu/cu2qu.py":180 + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( # <<<<<<<<<<<<<< + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/cu2qu/cu2qu.py":181 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p0, __pyx_v_p1), __pyx_t_double_complex_from_parts(0.5, 0)); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_c_diff_double(__pyx_v_mid, __pyx_v_deriv3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_mid); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_3)) __PYX_ERR(0, 181, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_4)) __PYX_ERR(0, 181, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_5 = 0; + + /* "fontTools/cu2qu/cu2qu.py":182 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_mid); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = __Pyx_c_sum_double(__pyx_v_mid, __pyx_v_deriv3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p2, __pyx_v_p3), __pyx_t_double_complex_from_parts(0.5, 0)); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5)) __PYX_ERR(0, 182, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4)) __PYX_ERR(0, 182, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_3)) __PYX_ERR(0, 182, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_t_1)) __PYX_ERR(0, 182, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":181 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6)) __PYX_ERR(0, 181, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_7)) __PYX_ERR(0, 181, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_7 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":157 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.split_cubic_into_two", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":186 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_three(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + __pyx_t_double_complex __pyx_v_mid1; + __pyx_t_double_complex __pyx_v_deriv1; + __pyx_t_double_complex __pyx_v_mid2; + __pyx_t_double_complex __pyx_v_deriv2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __pyx_t_double_complex __pyx_t_2; + __pyx_t_double_complex __pyx_t_3; + __pyx_t_double_complex __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("split_cubic_into_three", 1); + + /* "fontTools/cu2qu/cu2qu.py":215 + * values). + * """ + * mid1 = (8 * p0 + 12 * p1 + 6 * p2 + p3) * (1 / 27) # <<<<<<<<<<<<<< + * deriv1 = (p3 + 3 * p2 - 4 * p0) * (1 / 27) + * mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) + */ + __pyx_v_mid1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(8, 0), __pyx_v_p0), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(12, 0), __pyx_v_p1)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(6, 0), __pyx_v_p2)), __pyx_v_p3), __pyx_t_double_complex_from_parts((1.0 / 27.0), 0)); + + /* "fontTools/cu2qu/cu2qu.py":216 + * """ + * mid1 = (8 * p0 + 12 * p1 + 6 * p2 + p3) * (1 / 27) + * deriv1 = (p3 + 3 * p2 - 4 * p0) * (1 / 27) # <<<<<<<<<<<<<< + * mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + */ + __pyx_v_deriv1 = __Pyx_c_prod_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_p3, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_v_p2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(4, 0), __pyx_v_p0)), __pyx_t_double_complex_from_parts((1.0 / 27.0), 0)); + + /* "fontTools/cu2qu/cu2qu.py":217 + * mid1 = (8 * p0 + 12 * p1 + 6 * p2 + p3) * (1 / 27) + * deriv1 = (p3 + 3 * p2 - 4 * p0) * (1 / 27) + * mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) # <<<<<<<<<<<<<< + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + * return ( + */ + __pyx_v_mid2 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_p0, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(6, 0), __pyx_v_p1)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(12, 0), __pyx_v_p2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(8, 0), __pyx_v_p3)), __pyx_t_double_complex_from_parts((1.0 / 27.0), 0)); + + /* "fontTools/cu2qu/cu2qu.py":218 + * deriv1 = (p3 + 3 * p2 - 4 * p0) * (1 / 27) + * mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) # <<<<<<<<<<<<<< + * return ( + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), + */ + __pyx_v_deriv2 = __Pyx_c_prod_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(4, 0), __pyx_v_p3), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_v_p1)), __pyx_v_p0), __pyx_t_double_complex_from_parts((1.0 / 27.0), 0)); + + /* "fontTools/cu2qu/cu2qu.py":219 + * mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + * return ( # <<<<<<<<<<<<<< + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), + * (mid1, mid1 + deriv1, mid2 - deriv2, mid2), + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/cu2qu/cu2qu.py":220 + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + * return ( + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), # <<<<<<<<<<<<<< + * (mid1, mid1 + deriv1, mid2 - deriv2, mid2), + * (mid2, mid2 + deriv2, (p2 + 2 * p3) / 3.0, p3), + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(2, 0), __pyx_v_p0), __pyx_v_p1); + __pyx_t_3 = __pyx_t_double_complex_from_parts(3.0, 0); + if (unlikely(__Pyx_c_is_zero_double(__pyx_t_3))) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 220, __pyx_L1_error) + } + __pyx_t_4 = __Pyx_c_quot_double(__pyx_t_2, __pyx_t_3); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_c_diff_double(__pyx_v_mid1, __pyx_v_deriv1); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_mid1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = PyTuple_New(4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_5)) __PYX_ERR(0, 220, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_6)) __PYX_ERR(0, 220, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 3, __pyx_t_7)) __PYX_ERR(0, 220, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_t_7 = 0; + + /* "fontTools/cu2qu/cu2qu.py":221 + * return ( + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), + * (mid1, mid1 + deriv1, mid2 - deriv2, mid2), # <<<<<<<<<<<<<< + * (mid2, mid2 + deriv2, (p2 + 2 * p3) / 3.0, p3), + * ) + */ + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_mid1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = __Pyx_c_sum_double(__pyx_v_mid1, __pyx_v_deriv1); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 = __Pyx_c_diff_double(__pyx_v_mid2, __pyx_v_deriv2); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_mid2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7)) __PYX_ERR(0, 221, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_6)) __PYX_ERR(0, 221, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_t_5)) __PYX_ERR(0, 221, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 3, __pyx_t_1)) __PYX_ERR(0, 221, __pyx_L1_error); + __pyx_t_7 = 0; + __pyx_t_6 = 0; + __pyx_t_5 = 0; + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":222 + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), + * (mid1, mid1 + deriv1, mid2 - deriv2, mid2), + * (mid2, mid2 + deriv2, (p2 + 2 * p3) / 3.0, p3), # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_mid2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_c_sum_double(__pyx_v_mid2, __pyx_v_deriv2); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_c_sum_double(__pyx_v_p2, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(2, 0), __pyx_v_p3)); + __pyx_t_3 = __pyx_t_double_complex_from_parts(3.0, 0); + if (unlikely(__Pyx_c_is_zero_double(__pyx_t_3))) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 222, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_c_quot_double(__pyx_t_4, __pyx_t_3); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_10 = PyTuple_New(4); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1)) __PYX_ERR(0, 222, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_5)) __PYX_ERR(0, 222, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_6)) __PYX_ERR(0, 222, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 3, __pyx_t_7)) __PYX_ERR(0, 222, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_t_7 = 0; + + /* "fontTools/cu2qu/cu2qu.py":220 + * deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + * return ( + * (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), # <<<<<<<<<<<<<< + * (mid1, mid1 + deriv1, mid2 - deriv2, mid2), + * (mid2, mid2 + deriv2, (p2 + 2 * p3) / 3.0, p3), + */ + __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8)) __PYX_ERR(0, 220, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_9)) __PYX_ERR(0, 220, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_10)) __PYX_ERR(0, 220, __pyx_L1_error); + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_10 = 0; + __pyx_r = __pyx_t_7; + __pyx_t_7 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":186 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.split_cubic_into_three", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":226 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.complex) + */ + +static CYTHON_INLINE __pyx_t_double_complex __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_control(double __pyx_v_t, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + __pyx_t_double_complex __pyx_v__p1; + __pyx_t_double_complex __pyx_v__p2; + __pyx_t_double_complex __pyx_r; + + /* "fontTools/cu2qu/cu2qu.py":250 + * complex: Location of candidate control point on quadratic curve. + * """ + * _p1 = p0 + (p1 - p0) * 1.5 # <<<<<<<<<<<<<< + * _p2 = p3 + (p2 - p3) * 1.5 + * return _p1 + (_p2 - _p1) * t + */ + __pyx_v__p1 = __Pyx_c_sum_double(__pyx_v_p0, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p0), __pyx_t_double_complex_from_parts(1.5, 0))); + + /* "fontTools/cu2qu/cu2qu.py":251 + * """ + * _p1 = p0 + (p1 - p0) * 1.5 + * _p2 = p3 + (p2 - p3) * 1.5 # <<<<<<<<<<<<<< + * return _p1 + (_p2 - _p1) * t + * + */ + __pyx_v__p2 = __Pyx_c_sum_double(__pyx_v_p3, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p3), __pyx_t_double_complex_from_parts(1.5, 0))); + + /* "fontTools/cu2qu/cu2qu.py":252 + * _p1 = p0 + (p1 - p0) * 1.5 + * _p2 = p3 + (p2 - p3) * 1.5 + * return _p1 + (_p2 - _p1) * t # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __Pyx_c_sum_double(__pyx_v__p1, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v__p2, __pyx_v__p1), __pyx_t_double_complex_from_parts(__pyx_v_t, 0))); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":226 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.complex) + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":255 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.complex) + */ + +static CYTHON_INLINE __pyx_t_double_complex __pyx_f_9fontTools_5cu2qu_5cu2qu_calc_intersect(__pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d) { + __pyx_t_double_complex __pyx_v_ab; + __pyx_t_double_complex __pyx_v_cd; + __pyx_t_double_complex __pyx_v_p; + double __pyx_v_h; + __pyx_t_double_complex __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + double __pyx_t_4; + double __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + __pyx_t_double_complex __pyx_t_13; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calc_intersect", 1); + + /* "fontTools/cu2qu/cu2qu.py":273 + * if no intersection was found. + * """ + * ab = b - a # <<<<<<<<<<<<<< + * cd = d - c + * p = ab * 1j + */ + __pyx_v_ab = __Pyx_c_diff_double(__pyx_v_b, __pyx_v_a); + + /* "fontTools/cu2qu/cu2qu.py":274 + * """ + * ab = b - a + * cd = d - c # <<<<<<<<<<<<<< + * p = ab * 1j + * try: + */ + __pyx_v_cd = __Pyx_c_diff_double(__pyx_v_d, __pyx_v_c); + + /* "fontTools/cu2qu/cu2qu.py":275 + * ab = b - a + * cd = d - c + * p = ab * 1j # <<<<<<<<<<<<<< + * try: + * h = dot(p, a - c) / dot(p, cd) + */ + __pyx_v_p = __Pyx_c_prod_double(__pyx_v_ab, __pyx_t_double_complex_from_parts(0, 1.0)); + + /* "fontTools/cu2qu/cu2qu.py":276 + * cd = d - c + * p = ab * 1j + * try: # <<<<<<<<<<<<<< + * h = dot(p, a - c) / dot(p, cd) + * except ZeroDivisionError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "fontTools/cu2qu/cu2qu.py":277 + * p = ab * 1j + * try: + * h = dot(p, a - c) / dot(p, cd) # <<<<<<<<<<<<<< + * except ZeroDivisionError: + * return complex(NAN, NAN) + */ + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_dot(__pyx_v_p, __Pyx_c_diff_double(__pyx_v_a, __pyx_v_c)); if (unlikely(__pyx_t_4 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 277, __pyx_L3_error) + __pyx_t_5 = __pyx_f_9fontTools_5cu2qu_5cu2qu_dot(__pyx_v_p, __pyx_v_cd); if (unlikely(__pyx_t_5 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 277, __pyx_L3_error) + if (unlikely(__pyx_t_5 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 277, __pyx_L3_error) + } + __pyx_v_h = (__pyx_t_4 / __pyx_t_5); + + /* "fontTools/cu2qu/cu2qu.py":276 + * cd = d - c + * p = ab * 1j + * try: # <<<<<<<<<<<<<< + * h = dot(p, a - c) / dot(p, cd) + * except ZeroDivisionError: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "fontTools/cu2qu/cu2qu.py":278 + * try: + * h = dot(p, a - c) / dot(p, cd) + * except ZeroDivisionError: # <<<<<<<<<<<<<< + * return complex(NAN, NAN) + * return c + cd * h + */ + __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_ZeroDivisionError); + if (__pyx_t_6) { + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.calc_intersect", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 278, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_9); + + /* "fontTools/cu2qu/cu2qu.py":279 + * h = dot(p, a - c) / dot(p, cd) + * except ZeroDivisionError: + * return complex(NAN, NAN) # <<<<<<<<<<<<<< + * return c + cd * h + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_NAN); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 279, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_NAN); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 279, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 279, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_10)) __PYX_ERR(0, 279, __pyx_L5_except_error); + __Pyx_GIVEREF(__pyx_t_11); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_11)) __PYX_ERR(0, 279, __pyx_L5_except_error); + __pyx_t_10 = 0; + __pyx_t_11 = 0; + __pyx_t_11 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_12, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 279, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 279, __pyx_L5_except_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_r = __pyx_t_13; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L6_except_return; + } + goto __pyx_L5_except_error; + + /* "fontTools/cu2qu/cu2qu.py":276 + * cd = d - c + * p = ab * 1j + * try: # <<<<<<<<<<<<<< + * h = dot(p, a - c) / dot(p, cd) + * except ZeroDivisionError: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + __pyx_L8_try_end:; + } + + /* "fontTools/cu2qu/cu2qu.py":280 + * except ZeroDivisionError: + * return complex(NAN, NAN) + * return c + cd * h # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __Pyx_c_sum_double(__pyx_v_c, __Pyx_c_prod_double(__pyx_v_cd, __pyx_t_double_complex_from_parts(__pyx_v_h, 0))); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":255 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.complex) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.calc_intersect", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = __pyx_t_double_complex_from_parts(0, 0); + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":283 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.returns(cython.int) + * @cython.locals( + */ + +static int __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3, double __pyx_v_tolerance) { + __pyx_t_double_complex __pyx_v_mid; + __pyx_t_double_complex __pyx_v_deriv3; + int __pyx_r; + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + + /* "fontTools/cu2qu/cu2qu.py":312 + * """ + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_2 = (__Pyx_c_abs_double(__pyx_v_p2) <= __pyx_v_tolerance); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__Pyx_c_abs_double(__pyx_v_p1) <= __pyx_v_tolerance); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":313 + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: + * return True # <<<<<<<<<<<<<< + * + * # Split. + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":312 + * """ + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: # <<<<<<<<<<<<<< + * return True + * + */ + } + + /* "fontTools/cu2qu/cu2qu.py":316 + * + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 # <<<<<<<<<<<<<< + * if abs(mid) > tolerance: + * return False + */ + __pyx_v_mid = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_p0, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__pyx_v_p1, __pyx_v_p2))), __pyx_v_p3), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/cu2qu/cu2qu.py":317 + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: # <<<<<<<<<<<<<< + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + __pyx_t_1 = (__Pyx_c_abs_double(__pyx_v_mid) > __pyx_v_tolerance); + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":318 + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: + * return False # <<<<<<<<<<<<<< + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return cubic_farthest_fit_inside( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":317 + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: # <<<<<<<<<<<<<< + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + } + + /* "fontTools/cu2qu/cu2qu.py":319 + * if abs(mid) > tolerance: + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 # <<<<<<<<<<<<<< + * return cubic_farthest_fit_inside( + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + */ + __pyx_v_deriv3 = __Pyx_c_prod_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_p3, __pyx_v_p2), __pyx_v_p1), __pyx_v_p0), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/cu2qu/cu2qu.py":320 + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return cubic_farthest_fit_inside( # <<<<<<<<<<<<<< + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + * ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) + */ + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_v_p0, __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p0, __pyx_v_p1), __pyx_t_double_complex_from_parts(0.5, 0)), __Pyx_c_diff_double(__pyx_v_mid, __pyx_v_deriv3), __pyx_v_mid, __pyx_v_tolerance); if (unlikely(__pyx_t_4 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 320, __pyx_L1_error) + if (__pyx_t_4) { + } else { + __pyx_t_3 = __pyx_t_4; + goto __pyx_L7_bool_binop_done; + } + + /* "fontTools/cu2qu/cu2qu.py":322 + * return cubic_farthest_fit_inside( + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + * ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_4 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_v_mid, __Pyx_c_sum_double(__pyx_v_mid, __pyx_v_deriv3), __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p2, __pyx_v_p3), __pyx_t_double_complex_from_parts(0.5, 0)), __pyx_v_p3, __pyx_v_tolerance); if (unlikely(__pyx_t_4 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 322, __pyx_L1_error) + __pyx_t_3 = __pyx_t_4; + __pyx_L7_bool_binop_done:; + __pyx_r = __pyx_t_3; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":283 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.returns(cython.int) + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.cubic_farthest_fit_inside", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":325 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals(tolerance=cython.double) + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_quadratic(PyObject *__pyx_v_cubic, double __pyx_v_tolerance) { + __pyx_t_double_complex __pyx_v_q1; + __pyx_t_double_complex __pyx_v_c0; + __pyx_t_double_complex __pyx_v_c1; + __pyx_t_double_complex __pyx_v_c2; + __pyx_t_double_complex __pyx_v_c3; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __pyx_t_double_complex __pyx_t_2; + __pyx_t_double_complex __pyx_t_3; + __pyx_t_double_complex __pyx_t_4; + __pyx_t_double_complex __pyx_t_5; + __pyx_t_double_complex __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubic_approx_quadratic", 1); + + /* "fontTools/cu2qu/cu2qu.py":349 + * """ + * + * q1 = calc_intersect(cubic[0], cubic[1], cubic[2], cubic[3]) # <<<<<<<<<<<<<< + * if math.isnan(q1.imag): + * return None + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __pyx_f_9fontTools_5cu2qu_5cu2qu_calc_intersect(__pyx_t_2, __pyx_t_3, __pyx_t_4, __pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 349, __pyx_L1_error) + __pyx_v_q1 = __pyx_t_6; + + /* "fontTools/cu2qu/cu2qu.py":350 + * + * q1 = calc_intersect(cubic[0], cubic[1], cubic[2], cubic[3]) + * if math.isnan(q1.imag): # <<<<<<<<<<<<<< + * return None + * c0 = cubic[0] + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_math); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_isnan); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyFloat_FromDouble(__Pyx_CIMAG(__pyx_v_q1)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_8))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_8, function); + __pyx_t_10 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_8, __pyx_callargs+1-__pyx_t_10, 1+__pyx_t_10); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } + __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_11 < 0))) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_11) { + + /* "fontTools/cu2qu/cu2qu.py":351 + * q1 = calc_intersect(cubic[0], cubic[1], cubic[2], cubic[3]) + * if math.isnan(q1.imag): + * return None # <<<<<<<<<<<<<< + * c0 = cubic[0] + * c3 = cubic[3] + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":350 + * + * q1 = calc_intersect(cubic[0], cubic[1], cubic[2], cubic[3]) + * if math.isnan(q1.imag): # <<<<<<<<<<<<<< + * return None + * c0 = cubic[0] + */ + } + + /* "fontTools/cu2qu/cu2qu.py":352 + * if math.isnan(q1.imag): + * return None + * c0 = cubic[0] # <<<<<<<<<<<<<< + * c3 = cubic[3] + * c1 = c0 + (q1 - c0) * (2 / 3) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 352, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 352, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_c0 = __pyx_t_6; + + /* "fontTools/cu2qu/cu2qu.py":353 + * return None + * c0 = cubic[0] + * c3 = cubic[3] # <<<<<<<<<<<<<< + * c1 = c0 + (q1 - c0) * (2 / 3) + * c2 = c3 + (q1 - c3) * (2 / 3) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 353, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 353, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_c3 = __pyx_t_6; + + /* "fontTools/cu2qu/cu2qu.py":354 + * c0 = cubic[0] + * c3 = cubic[3] + * c1 = c0 + (q1 - c0) * (2 / 3) # <<<<<<<<<<<<<< + * c2 = c3 + (q1 - c3) * (2 / 3) + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): + */ + __pyx_v_c1 = __Pyx_c_sum_double(__pyx_v_c0, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_q1, __pyx_v_c0), __pyx_t_double_complex_from_parts((2.0 / 3.0), 0))); + + /* "fontTools/cu2qu/cu2qu.py":355 + * c3 = cubic[3] + * c1 = c0 + (q1 - c0) * (2 / 3) + * c2 = c3 + (q1 - c3) * (2 / 3) # <<<<<<<<<<<<<< + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): + * return None + */ + __pyx_v_c2 = __Pyx_c_sum_double(__pyx_v_c3, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_q1, __pyx_v_c3), __pyx_t_double_complex_from_parts((2.0 / 3.0), 0))); + + /* "fontTools/cu2qu/cu2qu.py":356 + * c1 = c0 + (q1 - c0) * (2 / 3) + * c2 = c3 + (q1 - c3) * (2 / 3) + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): # <<<<<<<<<<<<<< + * return None + * return c0, q1, c3 + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_c1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_cubic, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = PyNumber_Subtract(__pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_c2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_cubic, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_10 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_t_double_complex_from_parts(0, 0), __pyx_t_6, __pyx_t_5, __pyx_t_double_complex_from_parts(0, 0), __pyx_v_tolerance); if (unlikely(__pyx_t_10 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 356, __pyx_L1_error) + __pyx_t_11 = (!(__pyx_t_10 != 0)); + if (__pyx_t_11) { + + /* "fontTools/cu2qu/cu2qu.py":357 + * c2 = c3 + (q1 - c3) * (2 / 3) + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): + * return None # <<<<<<<<<<<<<< + * return c0, q1, c3 + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":356 + * c1 = c0 + (q1 - c0) * (2 / 3) + * c2 = c3 + (q1 - c3) * (2 / 3) + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): # <<<<<<<<<<<<<< + * return None + * return c0, q1, c3 + */ + } + + /* "fontTools/cu2qu/cu2qu.py":358 + * if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): + * return None + * return c0, q1, c3 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_c0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __pyx_PyComplex_FromComplex(__pyx_v_q1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_c3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1)) __PYX_ERR(0, 358, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_8)) __PYX_ERR(0, 358, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_t_7)) __PYX_ERR(0, 358, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_8 = 0; + __pyx_t_7 = 0; + __pyx_r = __pyx_t_9; + __pyx_t_9 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":325 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals(tolerance=cython.double) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.cubic_approx_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":361 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int, tolerance=cython.double) + * @cython.locals(i=cython.int) + */ + +static PyObject *__pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_spline(PyObject *__pyx_v_cubic, int __pyx_v_n, double __pyx_v_tolerance, int __pyx_v_all_quadratic) { + __pyx_t_double_complex __pyx_v_q0; + __pyx_t_double_complex __pyx_v_q1; + __pyx_t_double_complex __pyx_v_next_q1; + __pyx_t_double_complex __pyx_v_q2; + __pyx_t_double_complex __pyx_v_d1; + CYTHON_UNUSED __pyx_t_double_complex __pyx_v_c0; + __pyx_t_double_complex __pyx_v_c1; + __pyx_t_double_complex __pyx_v_c2; + __pyx_t_double_complex __pyx_v_c3; + int __pyx_v_i; + PyObject *__pyx_v_cubics = NULL; + PyObject *__pyx_v_next_cubic = NULL; + PyObject *__pyx_v_spline = NULL; + __pyx_t_double_complex __pyx_v_d0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + __pyx_t_double_complex __pyx_t_4; + __pyx_t_double_complex __pyx_t_5; + __pyx_t_double_complex __pyx_t_6; + __pyx_t_double_complex __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + __pyx_t_double_complex __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + long __pyx_t_11; + long __pyx_t_12; + int __pyx_t_13; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *(*__pyx_t_16)(PyObject *); + long __pyx_t_17; + int __pyx_t_18; + int __pyx_t_19; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubic_approx_spline", 1); + + /* "fontTools/cu2qu/cu2qu.py":390 + * """ + * + * if n == 1: # <<<<<<<<<<<<<< + * return cubic_approx_quadratic(cubic, tolerance) + * if n == 2 and all_quadratic == False: + */ + __pyx_t_1 = (__pyx_v_n == 1); + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":391 + * + * if n == 1: + * return cubic_approx_quadratic(cubic, tolerance) # <<<<<<<<<<<<<< + * if n == 2 and all_quadratic == False: + * return cubic + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_quadratic(__pyx_v_cubic, __pyx_v_tolerance); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":390 + * """ + * + * if n == 1: # <<<<<<<<<<<<<< + * return cubic_approx_quadratic(cubic, tolerance) + * if n == 2 and all_quadratic == False: + */ + } + + /* "fontTools/cu2qu/cu2qu.py":392 + * if n == 1: + * return cubic_approx_quadratic(cubic, tolerance) + * if n == 2 and all_quadratic == False: # <<<<<<<<<<<<<< + * return cubic + * + */ + __pyx_t_3 = (__pyx_v_n == 2); + if (__pyx_t_3) { + } else { + __pyx_t_1 = __pyx_t_3; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_3 = (__pyx_v_all_quadratic == 0); + __pyx_t_1 = __pyx_t_3; + __pyx_L5_bool_binop_done:; + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":393 + * return cubic_approx_quadratic(cubic, tolerance) + * if n == 2 and all_quadratic == False: + * return cubic # <<<<<<<<<<<<<< + * + * cubics = split_cubic_into_n_iter(cubic[0], cubic[1], cubic[2], cubic[3], n) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_cubic); + __pyx_r = __pyx_v_cubic; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":392 + * if n == 1: + * return cubic_approx_quadratic(cubic, tolerance) + * if n == 2 and all_quadratic == False: # <<<<<<<<<<<<<< + * return cubic + * + */ + } + + /* "fontTools/cu2qu/cu2qu.py":395 + * return cubic + * + * cubics = split_cubic_into_n_iter(cubic[0], cubic[1], cubic[2], cubic[3], n) # <<<<<<<<<<<<<< + * + * # calculate the spline of quadratics and check errors at the same time. + */ + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_cubic, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_cubic, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = __pyx_f_9fontTools_5cu2qu_5cu2qu_split_cubic_into_n_iter(__pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_cubics = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/cu2qu/cu2qu.py":398 + * + * # calculate the spline of quadratics and check errors at the same time. + * next_cubic = next(cubics) # <<<<<<<<<<<<<< + * next_q1 = cubic_approx_control( + * 0, next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + */ + __pyx_t_8 = __Pyx_PyIter_Next(__pyx_v_cubics); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 398, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_v_next_cubic = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/cu2qu/cu2qu.py":400 + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( + * 0, next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] # <<<<<<<<<<<<<< + * ) + * q2 = cubic[0] + */ + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_next_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_next_cubic, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_next_cubic, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_next_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_4 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/cu2qu/cu2qu.py":399 + * # calculate the spline of quadratics and check errors at the same time. + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( # <<<<<<<<<<<<<< + * 0, next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + * ) + */ + __pyx_t_9 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_control(0.0, __pyx_t_7, __pyx_t_6, __pyx_t_5, __pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 399, __pyx_L1_error) + __pyx_v_next_q1 = __pyx_t_9; + + /* "fontTools/cu2qu/cu2qu.py":402 + * 0, next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + * ) + * q2 = cubic[0] # <<<<<<<<<<<<<< + * d1 = 0j + * spline = [cubic[0], next_q1] + */ + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_q2 = __pyx_t_9; + + /* "fontTools/cu2qu/cu2qu.py":403 + * ) + * q2 = cubic[0] + * d1 = 0j # <<<<<<<<<<<<<< + * spline = [cubic[0], next_q1] + * for i in range(1, n + 1): + */ + __pyx_v_d1 = __pyx_t_double_complex_from_parts(0, 0.0); + + /* "fontTools/cu2qu/cu2qu.py":404 + * q2 = cubic[0] + * d1 = 0j + * spline = [cubic[0], next_q1] # <<<<<<<<<<<<<< + * for i in range(1, n + 1): + * # Current cubic to convert + */ + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_next_q1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = PyList_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyList_SET_ITEM(__pyx_t_10, 0, __pyx_t_8)) __PYX_ERR(0, 404, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_10, 1, __pyx_t_2)) __PYX_ERR(0, 404, __pyx_L1_error); + __pyx_t_8 = 0; + __pyx_t_2 = 0; + __pyx_v_spline = ((PyObject*)__pyx_t_10); + __pyx_t_10 = 0; + + /* "fontTools/cu2qu/cu2qu.py":405 + * d1 = 0j + * spline = [cubic[0], next_q1] + * for i in range(1, n + 1): # <<<<<<<<<<<<<< + * # Current cubic to convert + * c0, c1, c2, c3 = next_cubic + */ + __pyx_t_11 = (__pyx_v_n + 1); + __pyx_t_12 = __pyx_t_11; + for (__pyx_t_13 = 1; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) { + __pyx_v_i = __pyx_t_13; + + /* "fontTools/cu2qu/cu2qu.py":407 + * for i in range(1, n + 1): + * # Current cubic to convert + * c0, c1, c2, c3 = next_cubic # <<<<<<<<<<<<<< + * + * # Current quadratic approximation of current cubic + */ + if ((likely(PyTuple_CheckExact(__pyx_v_next_cubic))) || (PyList_CheckExact(__pyx_v_next_cubic))) { + PyObject* sequence = __pyx_v_next_cubic; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 407, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_14 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_10 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_14 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_14); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_10,&__pyx_t_2,&__pyx_t_8,&__pyx_t_14}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_10,&__pyx_t_2,&__pyx_t_8,&__pyx_t_14}; + __pyx_t_15 = PyObject_GetIter(__pyx_v_next_cubic); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __pyx_t_16 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_15); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_16(__pyx_t_15); if (unlikely(!item)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_16(__pyx_t_15), 4) < 0) __PYX_ERR(0, 407, __pyx_L1_error) + __pyx_t_16 = NULL; + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + __pyx_t_16 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 407, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_4 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_14); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_v_c0 = __pyx_t_9; + __pyx_v_c1 = __pyx_t_4; + __pyx_v_c2 = __pyx_t_5; + __pyx_v_c3 = __pyx_t_6; + + /* "fontTools/cu2qu/cu2qu.py":410 + * + * # Current quadratic approximation of current cubic + * q0 = q2 # <<<<<<<<<<<<<< + * q1 = next_q1 + * if i < n: + */ + __pyx_v_q0 = __pyx_v_q2; + + /* "fontTools/cu2qu/cu2qu.py":411 + * # Current quadratic approximation of current cubic + * q0 = q2 + * q1 = next_q1 # <<<<<<<<<<<<<< + * if i < n: + * next_cubic = next(cubics) + */ + __pyx_v_q1 = __pyx_v_next_q1; + + /* "fontTools/cu2qu/cu2qu.py":412 + * q0 = q2 + * q1 = next_q1 + * if i < n: # <<<<<<<<<<<<<< + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( + */ + __pyx_t_1 = (__pyx_v_i < __pyx_v_n); + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":413 + * q1 = next_q1 + * if i < n: + * next_cubic = next(cubics) # <<<<<<<<<<<<<< + * next_q1 = cubic_approx_control( + * i / (n - 1), next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + */ + __pyx_t_14 = __Pyx_PyIter_Next(__pyx_v_cubics); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 413, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF_SET(__pyx_v_next_cubic, __pyx_t_14); + __pyx_t_14 = 0; + + /* "fontTools/cu2qu/cu2qu.py":415 + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( + * i / (n - 1), next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] # <<<<<<<<<<<<<< + * ) + * spline.append(next_q1) + */ + __pyx_t_17 = (__pyx_v_n - 1); + if (unlikely(__pyx_t_17 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 415, __pyx_L1_error) + } + __pyx_t_14 = __Pyx_GetItemInt(__pyx_v_next_cubic, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_14); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_14 = __Pyx_GetItemInt(__pyx_v_next_cubic, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_5 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_14); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_14 = __Pyx_GetItemInt(__pyx_v_next_cubic, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_4 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_14); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_14 = __Pyx_GetItemInt(__pyx_v_next_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_14); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 415, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + + /* "fontTools/cu2qu/cu2qu.py":414 + * if i < n: + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( # <<<<<<<<<<<<<< + * i / (n - 1), next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + * ) + */ + __pyx_t_7 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_control((((double)__pyx_v_i) / ((double)__pyx_t_17)), __pyx_t_6, __pyx_t_5, __pyx_t_4, __pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 414, __pyx_L1_error) + __pyx_v_next_q1 = __pyx_t_7; + + /* "fontTools/cu2qu/cu2qu.py":417 + * i / (n - 1), next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + * ) + * spline.append(next_q1) # <<<<<<<<<<<<<< + * q2 = (q1 + next_q1) * 0.5 + * else: + */ + __pyx_t_14 = __pyx_PyComplex_FromComplex(__pyx_v_next_q1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_18 = __Pyx_PyList_Append(__pyx_v_spline, __pyx_t_14); if (unlikely(__pyx_t_18 == ((int)-1))) __PYX_ERR(0, 417, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + + /* "fontTools/cu2qu/cu2qu.py":418 + * ) + * spline.append(next_q1) + * q2 = (q1 + next_q1) * 0.5 # <<<<<<<<<<<<<< + * else: + * q2 = c3 + */ + __pyx_v_q2 = __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_q1, __pyx_v_next_q1), __pyx_t_double_complex_from_parts(0.5, 0)); + + /* "fontTools/cu2qu/cu2qu.py":412 + * q0 = q2 + * q1 = next_q1 + * if i < n: # <<<<<<<<<<<<<< + * next_cubic = next(cubics) + * next_q1 = cubic_approx_control( + */ + goto __pyx_L11; + } + + /* "fontTools/cu2qu/cu2qu.py":420 + * q2 = (q1 + next_q1) * 0.5 + * else: + * q2 = c3 # <<<<<<<<<<<<<< + * + * # End-point deltas + */ + /*else*/ { + __pyx_v_q2 = __pyx_v_c3; + } + __pyx_L11:; + + /* "fontTools/cu2qu/cu2qu.py":423 + * + * # End-point deltas + * d0 = d1 # <<<<<<<<<<<<<< + * d1 = q2 - c3 + * + */ + __pyx_v_d0 = __pyx_v_d1; + + /* "fontTools/cu2qu/cu2qu.py":424 + * # End-point deltas + * d0 = d1 + * d1 = q2 - c3 # <<<<<<<<<<<<<< + * + * if abs(d1) > tolerance or not cubic_farthest_fit_inside( + */ + __pyx_v_d1 = __Pyx_c_diff_double(__pyx_v_q2, __pyx_v_c3); + + /* "fontTools/cu2qu/cu2qu.py":426 + * d1 = q2 - c3 + * + * if abs(d1) > tolerance or not cubic_farthest_fit_inside( # <<<<<<<<<<<<<< + * d0, + * q0 + (q1 - q0) * (2 / 3) - c1, + */ + __pyx_t_3 = (__Pyx_c_abs_double(__pyx_v_d1) > __pyx_v_tolerance); + if (!__pyx_t_3) { + } else { + __pyx_t_1 = __pyx_t_3; + goto __pyx_L13_bool_binop_done; + } + + /* "fontTools/cu2qu/cu2qu.py":431 + * q2 + (q1 - q2) * (2 / 3) - c2, + * d1, + * tolerance, # <<<<<<<<<<<<<< + * ): + * return None + */ + __pyx_t_19 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_farthest_fit_inside(__pyx_v_d0, __Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_q0, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_q1, __pyx_v_q0), __pyx_t_double_complex_from_parts((2.0 / 3.0), 0))), __pyx_v_c1), __Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_q2, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_q1, __pyx_v_q2), __pyx_t_double_complex_from_parts((2.0 / 3.0), 0))), __pyx_v_c2), __pyx_v_d1, __pyx_v_tolerance); if (unlikely(__pyx_t_19 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 426, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":426 + * d1 = q2 - c3 + * + * if abs(d1) > tolerance or not cubic_farthest_fit_inside( # <<<<<<<<<<<<<< + * d0, + * q0 + (q1 - q0) * (2 / 3) - c1, + */ + __pyx_t_3 = (!(__pyx_t_19 != 0)); + __pyx_t_1 = __pyx_t_3; + __pyx_L13_bool_binop_done:; + if (__pyx_t_1) { + + /* "fontTools/cu2qu/cu2qu.py":433 + * tolerance, + * ): + * return None # <<<<<<<<<<<<<< + * spline.append(cubic[3]) + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":426 + * d1 = q2 - c3 + * + * if abs(d1) > tolerance or not cubic_farthest_fit_inside( # <<<<<<<<<<<<<< + * d0, + * q0 + (q1 - q0) * (2 / 3) - c1, + */ + } + } + + /* "fontTools/cu2qu/cu2qu.py":434 + * ): + * return None + * spline.append(cubic[3]) # <<<<<<<<<<<<<< + * + * return spline + */ + __pyx_t_14 = __Pyx_GetItemInt(__pyx_v_cubic, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 434, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_18 = __Pyx_PyList_Append(__pyx_v_spline, __pyx_t_14); if (unlikely(__pyx_t_18 == ((int)-1))) __PYX_ERR(0, 434, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + + /* "fontTools/cu2qu/cu2qu.py":436 + * spline.append(cubic[3]) + * + * return spline # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_spline); + __pyx_r = __pyx_v_spline; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":361 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int, tolerance=cython.double) + * @cython.locals(i=cython.int) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_14); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.cubic_approx_spline", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_cubics); + __Pyx_XDECREF(__pyx_v_next_cubic); + __Pyx_XDECREF(__pyx_v_spline); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":439 + * + * + * @cython.locals(max_err=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_4curve_to_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5cu2qu_5cu2qu_3curve_to_quadratic, "curve_to_quadratic(curve, double max_err, int all_quadratic=True)\nApproximate a cubic Bezier curve with a spline of n quadratics.\n\n Args:\n cubic (sequence): Four 2D tuples representing control points of\n the cubic Bezier curve.\n max_err (double): Permitted deviation from the original curve.\n all_quadratic (bool): If True (default) returned value is a\n quadratic spline. If False, it's either a single quadratic\n curve or a single cubic curve.\n\n Returns:\n If all_quadratic is True: A list of 2D tuples, representing\n control points of the quadratic spline if it fits within the\n given tolerance, or ``None`` if no suitable spline could be\n calculated.\n\n If all_quadratic is False: Either a quadratic curve (if length\n of output is 3), or a cubic curve (if length of output is 4).\n "); +static PyMethodDef __pyx_mdef_9fontTools_5cu2qu_5cu2qu_4curve_to_quadratic = {"curve_to_quadratic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5cu2qu_5cu2qu_4curve_to_quadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5cu2qu_5cu2qu_3curve_to_quadratic}; +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_4curve_to_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve = 0; + double __pyx_v_max_err; + int __pyx_v_all_quadratic; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curve_to_quadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curve,&__pyx_n_s_max_err,&__pyx_n_s_all_quadratic,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_err)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("curve_to_quadratic", 0, 2, 3, 1); __PYX_ERR(0, 439, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_all_quadratic); + if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "curve_to_quadratic") < 0)) __PYX_ERR(0, 439, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_curve = values[0]; + __pyx_v_max_err = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_max_err == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 442, __pyx_L3_error) + if (values[2]) { + __pyx_v_all_quadratic = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_all_quadratic == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 442, __pyx_L3_error) + } else { + + /* "fontTools/cu2qu/cu2qu.py":442 + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + * def curve_to_quadratic(curve, max_err, all_quadratic=True): # <<<<<<<<<<<<<< + * """Approximate a cubic Bezier curve with a spline of n quadratics. + * + */ + __pyx_v_all_quadratic = ((int)((int)1)); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curve_to_quadratic", 0, 2, 3, __pyx_nargs); __PYX_ERR(0, 439, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.curve_to_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5cu2qu_5cu2qu_3curve_to_quadratic(__pyx_self, __pyx_v_curve, __pyx_v_max_err, __pyx_v_all_quadratic); + + /* "fontTools/cu2qu/cu2qu.py":439 + * + * + * @cython.locals(max_err=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + */ + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu_3curve_to_quadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, double __pyx_v_max_err, int __pyx_v_all_quadratic) { + int __pyx_v_n; + PyObject *__pyx_v_spline = NULL; + PyObject *__pyx_7genexpr__pyx_v_p = NULL; + PyObject *__pyx_8genexpr1__pyx_v_s = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + long __pyx_t_7; + long __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curve_to_quadratic", 0); + __Pyx_INCREF(__pyx_v_curve); + + /* "fontTools/cu2qu/cu2qu.py":463 + * """ + * + * curve = [complex(*p) for p in curve] # <<<<<<<<<<<<<< + * + * for n in range(1, MAX_N + 1): + */ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_1); + if (likely(PyList_CheckExact(__pyx_v_curve)) || PyTuple_CheckExact(__pyx_v_curve)) { + __pyx_t_2 = __pyx_v_curve; __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + __pyx_t_4 = NULL; + } else { + __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_curve); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 463, __pyx_L5_error) + } + for (;;) { + if (likely(!__pyx_t_4)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 463, __pyx_L5_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 463, __pyx_L5_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 463, __pyx_L5_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 463, __pyx_L5_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } + } else { + __pyx_t_5 = __pyx_t_4(__pyx_t_2); + if (unlikely(!__pyx_t_5)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 463, __pyx_L5_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_5); + } + __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_p, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PySequence_Tuple(__pyx_7genexpr__pyx_v_p); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 463, __pyx_L5_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_p); __pyx_7genexpr__pyx_v_p = 0; + goto __pyx_L9_exit_scope; + __pyx_L5_error:; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_p); __pyx_7genexpr__pyx_v_p = 0; + goto __pyx_L1_error; + __pyx_L9_exit_scope:; + } /* exit inner scope */ + __Pyx_DECREF_SET(__pyx_v_curve, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":465 + * curve = [complex(*p) for p in curve] + * + * for n in range(1, MAX_N + 1): # <<<<<<<<<<<<<< + * spline = cubic_approx_spline(curve, n, max_err, all_quadratic) + * if spline is not None: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_MAX_N); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_t_1, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyInt_As_long(__pyx_t_2); if (unlikely((__pyx_t_7 == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 465, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __pyx_t_7; + for (__pyx_t_9 = 1; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { + __pyx_v_n = __pyx_t_9; + + /* "fontTools/cu2qu/cu2qu.py":466 + * + * for n in range(1, MAX_N + 1): + * spline = cubic_approx_spline(curve, n, max_err, all_quadratic) # <<<<<<<<<<<<<< + * if spline is not None: + * # done. go home + */ + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_spline(__pyx_v_curve, __pyx_v_n, __pyx_v_max_err, __pyx_v_all_quadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 466, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_spline, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/cu2qu/cu2qu.py":467 + * for n in range(1, MAX_N + 1): + * spline = cubic_approx_spline(curve, n, max_err, all_quadratic) + * if spline is not None: # <<<<<<<<<<<<<< + * # done. go home + * return [(s.real, s.imag) for s in spline] + */ + __pyx_t_10 = (__pyx_v_spline != Py_None); + if (__pyx_t_10) { + + /* "fontTools/cu2qu/cu2qu.py":469 + * if spline is not None: + * # done. go home + * return [(s.real, s.imag) for s in spline] # <<<<<<<<<<<<<< + * + * raise ApproxNotFoundError(curve) + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + if (likely(PyList_CheckExact(__pyx_v_spline)) || PyTuple_CheckExact(__pyx_v_spline)) { + __pyx_t_1 = __pyx_v_spline; __Pyx_INCREF(__pyx_t_1); + __pyx_t_3 = 0; + __pyx_t_4 = NULL; + } else { + __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_spline); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 469, __pyx_L15_error) + } + for (;;) { + if (likely(!__pyx_t_4)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 469, __pyx_L15_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_6); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 469, __pyx_L15_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 469, __pyx_L15_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_6); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 469, __pyx_L15_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } + } else { + __pyx_t_6 = __pyx_t_4(__pyx_t_1); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 469, __pyx_L15_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_s, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr1__pyx_v_s, __pyx_n_s_real); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr1__pyx_v_s, __pyx_n_s_imag); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_6)) __PYX_ERR(0, 469, __pyx_L15_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_5)) __PYX_ERR(0, 469, __pyx_L15_error); + __pyx_t_6 = 0; + __pyx_t_5 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_11))) __PYX_ERR(0, 469, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_s); __pyx_8genexpr1__pyx_v_s = 0; + goto __pyx_L19_exit_scope; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_s); __pyx_8genexpr1__pyx_v_s = 0; + goto __pyx_L1_error; + __pyx_L19_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":467 + * for n in range(1, MAX_N + 1): + * spline = cubic_approx_spline(curve, n, max_err, all_quadratic) + * if spline is not None: # <<<<<<<<<<<<<< + * # done. go home + * return [(s.real, s.imag) for s in spline] + */ + } + } + + /* "fontTools/cu2qu/cu2qu.py":471 + * return [(s.real, s.imag) for s in spline] + * + * raise ApproxNotFoundError(curve) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_ApproxNotFoundError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 471, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = NULL; + __pyx_t_9 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_9 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_v_curve}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_9, 1+__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 471, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 471, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":439 + * + * + * @cython.locals(max_err=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.curve_to_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_spline); + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_p); + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_s); + __Pyx_XDECREF(__pyx_v_curve); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/cu2qu/cu2qu.py":474 + * + * + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) # <<<<<<<<<<<<<< + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_6curves_to_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5cu2qu_5cu2qu_5curves_to_quadratic, "curves_to_quadratic(curves, max_errors, int all_quadratic=True)\nReturn quadratic Bezier splines approximating the input cubic Beziers.\n\n Args:\n curves: A sequence of *n* curves, each curve being a sequence of four\n 2D tuples.\n max_errors: A sequence of *n* floats representing the maximum permissible\n deviation from each of the cubic Bezier curves.\n all_quadratic (bool): If True (default) returned values are a\n quadratic spline. If False, they are either a single quadratic\n curve or a single cubic curve.\n\n Example::\n\n >>> curves_to_quadratic( [\n ... [ (50,50), (100,100), (150,100), (200,50) ],\n ... [ (75,50), (120,100), (150,75), (200,60) ]\n ... ], [1,1] )\n [[(50.0, 50.0), (75.0, 75.0), (125.0, 91.66666666666666), (175.0, 75.0), (200.0, 50.0)], [(75.0, 50.0), (97.5, 75.0), (135.41666666666666, 82.08333333333333), (175.0, 67.5), (200.0, 60.0)]]\n\n The returned splines have \"implied oncurve points\" suitable for use in\n TrueType ``glif`` outlines - i.e. in the first spline returned above,\n the first quadratic segment runs from (50,50) to\n ( (75 + 125)/2 , (120 + 91.666..)/2 ) = (100, 83.333...).\n\n Returns:\n If all_quadratic is True, a list of splines, each spline being a list\n of 2D tuples.\n\n If all_quadratic is False, a list of curves, each curve being a quadratic\n (length 3), or cubic (length 4).\n\n Raises:\n fontTools.cu2qu.Errors.ApproxNotFoundError: if no suitable approximation\n can be found for all curves with the given parameters.\n "); +static PyMethodDef __pyx_mdef_9fontTools_5cu2qu_5cu2qu_6curves_to_quadratic = {"curves_to_quadratic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5cu2qu_5cu2qu_6curves_to_quadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5cu2qu_5cu2qu_5curves_to_quadratic}; +static PyObject *__pyx_pw_9fontTools_5cu2qu_5cu2qu_6curves_to_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curves = 0; + PyObject *__pyx_v_max_errors = 0; + int __pyx_v_all_quadratic; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curves_to_quadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curves,&__pyx_n_s_max_errors,&__pyx_n_s_all_quadratic,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curves)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 474, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_errors)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 474, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("curves_to_quadratic", 0, 2, 3, 1); __PYX_ERR(0, 474, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_all_quadratic); + if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 474, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "curves_to_quadratic") < 0)) __PYX_ERR(0, 474, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_curves = values[0]; + __pyx_v_max_errors = values[1]; + if (values[2]) { + __pyx_v_all_quadratic = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_all_quadratic == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 476, __pyx_L3_error) + } else { + + /* "fontTools/cu2qu/cu2qu.py":476 + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): # <<<<<<<<<<<<<< + * """Return quadratic Bezier splines approximating the input cubic Beziers. + * + */ + __pyx_v_all_quadratic = ((int)((int)1)); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curves_to_quadratic", 0, 2, 3, __pyx_nargs); __PYX_ERR(0, 474, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.curves_to_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5cu2qu_5cu2qu_5curves_to_quadratic(__pyx_self, __pyx_v_curves, __pyx_v_max_errors, __pyx_v_all_quadratic); + + /* "fontTools/cu2qu/cu2qu.py":474 + * + * + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) # <<<<<<<<<<<<<< + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): + */ + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5cu2qu_5cu2qu_5curves_to_quadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curves, PyObject *__pyx_v_max_errors, int __pyx_v_all_quadratic) { + int __pyx_v_l; + int __pyx_v_last_i; + int __pyx_v_i; + PyObject *__pyx_v_splines = NULL; + PyObject *__pyx_v_n = NULL; + PyObject *__pyx_v_spline = NULL; + PyObject *__pyx_8genexpr2__pyx_v_curve = NULL; + PyObject *__pyx_8genexpr3__pyx_v_p = NULL; + PyObject *__pyx_8genexpr4__pyx_v_spline = NULL; + PyObject *__pyx_8genexpr5__pyx_v_s = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + Py_ssize_t __pyx_t_7; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_t_11; + int __pyx_t_12; + double __pyx_t_13; + long __pyx_t_14; + PyObject *__pyx_t_15 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curves_to_quadratic", 0); + __Pyx_INCREF(__pyx_v_curves); + + /* "fontTools/cu2qu/cu2qu.py":513 + * """ + * + * curves = [[complex(*p) for p in curve] for curve in curves] # <<<<<<<<<<<<<< + * assert len(max_errors) == len(curves) + * + */ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 513, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_1); + if (likely(PyList_CheckExact(__pyx_v_curves)) || PyTuple_CheckExact(__pyx_v_curves)) { + __pyx_t_2 = __pyx_v_curves; __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + __pyx_t_4 = NULL; + } else { + __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_curves); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 513, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 513, __pyx_L5_error) + } + for (;;) { + if (likely(!__pyx_t_4)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 513, __pyx_L5_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 513, __pyx_L5_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 513, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 513, __pyx_L5_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 513, __pyx_L5_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 513, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } + } else { + __pyx_t_5 = __pyx_t_4(__pyx_t_2); + if (unlikely(!__pyx_t_5)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 513, __pyx_L5_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_5); + } + __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_curve, __pyx_t_5); + __pyx_t_5 = 0; + { /* enter inner scope */ + __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_5); + if (likely(PyList_CheckExact(__pyx_8genexpr2__pyx_v_curve)) || PyTuple_CheckExact(__pyx_8genexpr2__pyx_v_curve)) { + __pyx_t_6 = __pyx_8genexpr2__pyx_v_curve; __Pyx_INCREF(__pyx_t_6); + __pyx_t_7 = 0; + __pyx_t_8 = NULL; + } else { + __pyx_t_7 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_8genexpr2__pyx_v_curve); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 513, __pyx_L10_error) + } + for (;;) { + if (likely(!__pyx_t_8)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 513, __pyx_L10_error) + #endif + if (__pyx_t_7 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_9 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 513, __pyx_L10_error) + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 513, __pyx_L10_error) + #endif + if (__pyx_t_7 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 513, __pyx_L10_error) + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + } + } else { + __pyx_t_9 = __pyx_t_8(__pyx_t_6); + if (unlikely(!__pyx_t_9)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 513, __pyx_L10_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_XDECREF_SET(__pyx_8genexpr3__pyx_v_p, __pyx_t_9); + __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PySequence_Tuple(__pyx_8genexpr3__pyx_v_p); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_10))) __PYX_ERR(0, 513, __pyx_L10_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_p); __pyx_8genexpr3__pyx_v_p = 0; + goto __pyx_L14_exit_scope; + __pyx_L10_error:; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_p); __pyx_8genexpr3__pyx_v_p = 0; + goto __pyx_L5_error; + __pyx_L14_exit_scope:; + } /* exit inner scope */ + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 513, __pyx_L5_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_curve); __pyx_8genexpr2__pyx_v_curve = 0; + goto __pyx_L16_exit_scope; + __pyx_L5_error:; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_curve); __pyx_8genexpr2__pyx_v_curve = 0; + goto __pyx_L1_error; + __pyx_L16_exit_scope:; + } /* exit inner scope */ + __Pyx_DECREF_SET(__pyx_v_curves, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":514 + * + * curves = [[complex(*p) for p in curve] for curve in curves] + * assert len(max_errors) == len(curves) # <<<<<<<<<<<<<< + * + * l = len(curves) + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_3 = PyObject_Length(__pyx_v_max_errors); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 514, __pyx_L1_error) + __pyx_t_7 = PyObject_Length(__pyx_v_curves); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 514, __pyx_L1_error) + __pyx_t_11 = (__pyx_t_3 == __pyx_t_7); + if (unlikely(!__pyx_t_11)) { + __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); + __PYX_ERR(0, 514, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(0, 514, __pyx_L1_error) + #endif + + /* "fontTools/cu2qu/cu2qu.py":516 + * assert len(max_errors) == len(curves) + * + * l = len(curves) # <<<<<<<<<<<<<< + * splines = [None] * l + * last_i = i = 0 + */ + __pyx_t_7 = PyObject_Length(__pyx_v_curves); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 516, __pyx_L1_error) + __pyx_v_l = __pyx_t_7; + + /* "fontTools/cu2qu/cu2qu.py":517 + * + * l = len(curves) + * splines = [None] * l # <<<<<<<<<<<<<< + * last_i = i = 0 + * n = 1 + */ + __pyx_t_1 = PyList_New(1 * ((__pyx_v_l<0) ? 0:__pyx_v_l)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 517, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + { Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < __pyx_v_l; __pyx_temp++) { + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, __pyx_temp, Py_None)) __PYX_ERR(0, 517, __pyx_L1_error); + } + } + __pyx_v_splines = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":518 + * l = len(curves) + * splines = [None] * l + * last_i = i = 0 # <<<<<<<<<<<<<< + * n = 1 + * while True: + */ + __pyx_v_last_i = 0; + __pyx_v_i = 0; + + /* "fontTools/cu2qu/cu2qu.py":519 + * splines = [None] * l + * last_i = i = 0 + * n = 1 # <<<<<<<<<<<<<< + * while True: + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + */ + __Pyx_INCREF(__pyx_int_1); + __pyx_v_n = __pyx_int_1; + + /* "fontTools/cu2qu/cu2qu.py":520 + * last_i = i = 0 + * n = 1 + * while True: # <<<<<<<<<<<<<< + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + * if spline is None: + */ + while (1) { + + /* "fontTools/cu2qu/cu2qu.py":521 + * n = 1 + * while True: + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) # <<<<<<<<<<<<<< + * if spline is None: + * if n == MAX_N: + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 521, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_n); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 521, __pyx_L1_error) + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_max_errors, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 521, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_13 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 521, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __pyx_f_9fontTools_5cu2qu_5cu2qu_cubic_approx_spline(__pyx_t_1, __pyx_t_12, __pyx_t_13, __pyx_v_all_quadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 521, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_spline, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/cu2qu/cu2qu.py":522 + * while True: + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + * if spline is None: # <<<<<<<<<<<<<< + * if n == MAX_N: + * break + */ + __pyx_t_11 = (__pyx_v_spline == Py_None); + if (__pyx_t_11) { + + /* "fontTools/cu2qu/cu2qu.py":523 + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + * if spline is None: + * if n == MAX_N: # <<<<<<<<<<<<<< + * break + * n += 1 + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_MAX_N); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 523, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyObject_RichCompare(__pyx_v_n, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 523, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_11 < 0))) __PYX_ERR(0, 523, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_11) { + + /* "fontTools/cu2qu/cu2qu.py":524 + * if spline is None: + * if n == MAX_N: + * break # <<<<<<<<<<<<<< + * n += 1 + * last_i = i + */ + goto __pyx_L18_break; + + /* "fontTools/cu2qu/cu2qu.py":523 + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + * if spline is None: + * if n == MAX_N: # <<<<<<<<<<<<<< + * break + * n += 1 + */ + } + + /* "fontTools/cu2qu/cu2qu.py":525 + * if n == MAX_N: + * break + * n += 1 # <<<<<<<<<<<<<< + * last_i = i + * continue + */ + __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_v_n, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 525, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_n, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/cu2qu/cu2qu.py":526 + * break + * n += 1 + * last_i = i # <<<<<<<<<<<<<< + * continue + * splines[i] = spline + */ + __pyx_v_last_i = __pyx_v_i; + + /* "fontTools/cu2qu/cu2qu.py":527 + * n += 1 + * last_i = i + * continue # <<<<<<<<<<<<<< + * splines[i] = spline + * i = (i + 1) % l + */ + goto __pyx_L17_continue; + + /* "fontTools/cu2qu/cu2qu.py":522 + * while True: + * spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + * if spline is None: # <<<<<<<<<<<<<< + * if n == MAX_N: + * break + */ + } + + /* "fontTools/cu2qu/cu2qu.py":528 + * last_i = i + * continue + * splines[i] = spline # <<<<<<<<<<<<<< + * i = (i + 1) % l + * if i == last_i: + */ + if (unlikely((__Pyx_SetItemInt(__pyx_v_splines, __pyx_v_i, __pyx_v_spline, int, 1, __Pyx_PyInt_From_int, 1, 1, 1) < 0))) __PYX_ERR(0, 528, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":529 + * continue + * splines[i] = spline + * i = (i + 1) % l # <<<<<<<<<<<<<< + * if i == last_i: + * # done. go home + */ + __pyx_t_14 = (__pyx_v_i + 1); + if (unlikely(__pyx_v_l == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + __PYX_ERR(0, 529, __pyx_L1_error) + } + __pyx_v_i = __Pyx_mod_long(__pyx_t_14, __pyx_v_l); + + /* "fontTools/cu2qu/cu2qu.py":530 + * splines[i] = spline + * i = (i + 1) % l + * if i == last_i: # <<<<<<<<<<<<<< + * # done. go home + * return [[(s.real, s.imag) for s in spline] for spline in splines] + */ + __pyx_t_11 = (__pyx_v_i == __pyx_v_last_i); + if (__pyx_t_11) { + + /* "fontTools/cu2qu/cu2qu.py":532 + * if i == last_i: + * # done. go home + * return [[(s.real, s.imag) for s in spline] for spline in splines] # <<<<<<<<<<<<<< + * + * raise ApproxNotFoundError(curves) + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L24_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_v_splines; __Pyx_INCREF(__pyx_t_2); + __pyx_t_7 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 532, __pyx_L24_error) + #endif + if (__pyx_t_7 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_5); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 532, __pyx_L24_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 532, __pyx_L24_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_XDECREF_SET(__pyx_8genexpr4__pyx_v_spline, __pyx_t_5); + __pyx_t_5 = 0; + { /* enter inner scope */ + __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_5); + if (likely(PyList_CheckExact(__pyx_8genexpr4__pyx_v_spline)) || PyTuple_CheckExact(__pyx_8genexpr4__pyx_v_spline)) { + __pyx_t_6 = __pyx_8genexpr4__pyx_v_spline; __Pyx_INCREF(__pyx_t_6); + __pyx_t_3 = 0; + __pyx_t_4 = NULL; + } else { + __pyx_t_3 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_8genexpr4__pyx_v_spline); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 532, __pyx_L29_error) + } + for (;;) { + if (likely(!__pyx_t_4)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 532, __pyx_L29_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_10 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_3); __Pyx_INCREF(__pyx_t_10); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 532, __pyx_L29_error) + #else + __pyx_t_10 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_10); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 532, __pyx_L29_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_3); __Pyx_INCREF(__pyx_t_10); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(0, 532, __pyx_L29_error) + #else + __pyx_t_10 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_10); + #endif + } + } else { + __pyx_t_10 = __pyx_t_4(__pyx_t_6); + if (unlikely(!__pyx_t_10)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 532, __pyx_L29_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_XDECREF_SET(__pyx_8genexpr5__pyx_v_s, __pyx_t_10); + __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr5__pyx_v_s, __pyx_n_s_real); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr5__pyx_v_s, __pyx_n_s_imag); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_GOTREF(__pyx_t_15); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_10)) __PYX_ERR(0, 532, __pyx_L29_error); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_t_9)) __PYX_ERR(0, 532, __pyx_L29_error); + __pyx_t_10 = 0; + __pyx_t_9 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_15))) __PYX_ERR(0, 532, __pyx_L29_error) + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_8genexpr5__pyx_v_s); __pyx_8genexpr5__pyx_v_s = 0; + goto __pyx_L33_exit_scope; + __pyx_L29_error:; + __Pyx_XDECREF(__pyx_8genexpr5__pyx_v_s); __pyx_8genexpr5__pyx_v_s = 0; + goto __pyx_L24_error; + __pyx_L33_exit_scope:; + } /* exit inner scope */ + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 532, __pyx_L24_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_8genexpr4__pyx_v_spline); __pyx_8genexpr4__pyx_v_spline = 0; + goto __pyx_L35_exit_scope; + __pyx_L24_error:; + __Pyx_XDECREF(__pyx_8genexpr4__pyx_v_spline); __pyx_8genexpr4__pyx_v_spline = 0; + goto __pyx_L1_error; + __pyx_L35_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/cu2qu/cu2qu.py":530 + * splines[i] = spline + * i = (i + 1) % l + * if i == last_i: # <<<<<<<<<<<<<< + * # done. go home + * return [[(s.real, s.imag) for s in spline] for spline in splines] + */ + } + __pyx_L17_continue:; + } + __pyx_L18_break:; + + /* "fontTools/cu2qu/cu2qu.py":534 + * return [[(s.real, s.imag) for s in spline] for spline in splines] + * + * raise ApproxNotFoundError(curves) # <<<<<<<<<<<<<< + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_ApproxNotFoundError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 534, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = NULL; + __pyx_t_12 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_12 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_curves}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_12, 1+__pyx_t_12); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 534, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 534, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":474 + * + * + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) # <<<<<<<<<<<<<< + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu.curves_to_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_splines); + __Pyx_XDECREF(__pyx_v_n); + __Pyx_XDECREF(__pyx_v_spline); + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_curve); + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_p); + __Pyx_XDECREF(__pyx_8genexpr4__pyx_v_spline); + __Pyx_XDECREF(__pyx_8genexpr5__pyx_v_s); + __Pyx_XDECREF(__pyx_v_curves); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *__pyx_freelist_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen[8]; +static int __pyx_freecount_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen = 0; + +static PyObject *__pyx_tp_new_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen)))) { + o = (PyObject*)__pyx_freelist_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen[--__pyx_freecount_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen)); + (void) PyObject_INIT(o, t); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen(PyObject *o) { + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen)))) { + __pyx_freelist_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen[__pyx_freecount_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen++] = ((struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen_spec = { + "fontTools.cu2qu.cu2qu.__pyx_scope_struct___split_cubic_into_n_gen", + sizeof(struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.cu2qu.cu2qu.""__pyx_scope_struct___split_cubic_into_n_gen", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_ApproxNotFoundError, __pyx_k_ApproxNotFoundError, sizeof(__pyx_k_ApproxNotFoundError), 0, 0, 1, 1}, + {&__pyx_n_s_AssertionError, __pyx_k_AssertionError, sizeof(__pyx_k_AssertionError), 0, 0, 1, 1}, + {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, + {&__pyx_n_s_COMPILED, __pyx_k_COMPILED, sizeof(__pyx_k_COMPILED), 0, 0, 1, 1}, + {&__pyx_n_s_Cu2QuError, __pyx_k_Cu2QuError, sizeof(__pyx_k_Cu2QuError), 0, 0, 1, 1}, + {&__pyx_n_s_Error, __pyx_k_Error, sizeof(__pyx_k_Error), 0, 0, 1, 1}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py, __pyx_k_Lib_fontTools_cu2qu_cu2qu_py, sizeof(__pyx_k_Lib_fontTools_cu2qu_cu2qu_py), 0, 0, 1, 0}, + {&__pyx_n_s_MAX_N, __pyx_k_MAX_N, sizeof(__pyx_k_MAX_N), 0, 0, 1, 1}, + {&__pyx_n_s_NAN, __pyx_k_NAN, sizeof(__pyx_k_NAN), 0, 0, 1, 1}, + {&__pyx_n_u_NaN, __pyx_k_NaN, sizeof(__pyx_k_NaN), 0, 1, 0, 1}, + {&__pyx_kp_u_Return_quadratic_Bezier_splines, __pyx_k_Return_quadratic_Bezier_splines, sizeof(__pyx_k_Return_quadratic_Bezier_splines), 0, 1, 0, 0}, + {&__pyx_n_s_ZeroDivisionError, __pyx_k_ZeroDivisionError, sizeof(__pyx_k_ZeroDivisionError), 0, 0, 1, 1}, + {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, + {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, + {&__pyx_n_s__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 0, 1, 1}, + {&__pyx_n_s_a, __pyx_k_a, sizeof(__pyx_k_a), 0, 0, 1, 1}, + {&__pyx_n_s_a1, __pyx_k_a1, sizeof(__pyx_k_a1), 0, 0, 1, 1}, + {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, + {&__pyx_n_s_all_quadratic, __pyx_k_all_quadratic, sizeof(__pyx_k_all_quadratic), 0, 0, 1, 1}, + {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 0, 1, 1}, + {&__pyx_n_s_b1, __pyx_k_b1, sizeof(__pyx_k_b1), 0, 0, 1, 1}, + {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, + {&__pyx_n_s_c1, __pyx_k_c1, sizeof(__pyx_k_c1), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, + {&__pyx_n_s_curve, __pyx_k_curve, sizeof(__pyx_k_curve), 0, 0, 1, 1}, + {&__pyx_n_s_curve_to_quadratic, __pyx_k_curve_to_quadratic, sizeof(__pyx_k_curve_to_quadratic), 0, 0, 1, 1}, + {&__pyx_n_u_curve_to_quadratic, __pyx_k_curve_to_quadratic, sizeof(__pyx_k_curve_to_quadratic), 0, 1, 0, 1}, + {&__pyx_n_s_curves, __pyx_k_curves, sizeof(__pyx_k_curves), 0, 0, 1, 1}, + {&__pyx_n_s_curves_to_quadratic, __pyx_k_curves_to_quadratic, sizeof(__pyx_k_curves_to_quadratic), 0, 0, 1, 1}, + {&__pyx_n_u_curves_to_quadratic, __pyx_k_curves_to_quadratic, sizeof(__pyx_k_curves_to_quadratic), 0, 1, 0, 1}, + {&__pyx_kp_u_curves_to_quadratic_line_474, __pyx_k_curves_to_quadratic_line_474, sizeof(__pyx_k_curves_to_quadratic_line_474), 0, 1, 0, 0}, + {&__pyx_n_s_cython, __pyx_k_cython, sizeof(__pyx_k_cython), 0, 0, 1, 1}, + {&__pyx_n_s_d, __pyx_k_d, sizeof(__pyx_k_d), 0, 0, 1, 1}, + {&__pyx_n_s_d1, __pyx_k_d1, sizeof(__pyx_k_d1), 0, 0, 1, 1}, + {&__pyx_n_s_delta_2, __pyx_k_delta_2, sizeof(__pyx_k_delta_2), 0, 0, 1, 1}, + {&__pyx_n_s_delta_3, __pyx_k_delta_3, sizeof(__pyx_k_delta_3), 0, 0, 1, 1}, + {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, + {&__pyx_n_s_dt, __pyx_k_dt, sizeof(__pyx_k_dt), 0, 0, 1, 1}, + {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, + {&__pyx_n_s_errors, __pyx_k_errors, sizeof(__pyx_k_errors), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_cu2qu_cu2qu, __pyx_k_fontTools_cu2qu_cu2qu, sizeof(__pyx_k_fontTools_cu2qu_cu2qu), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc, __pyx_k_fontTools_misc, sizeof(__pyx_k_fontTools_misc), 0, 0, 1, 1}, + {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_imag, __pyx_k_imag, sizeof(__pyx_k_imag), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, + {&__pyx_n_s_isnan, __pyx_k_isnan, sizeof(__pyx_k_isnan), 0, 0, 1, 1}, + {&__pyx_n_s_l, __pyx_k_l, sizeof(__pyx_k_l), 0, 0, 1, 1}, + {&__pyx_n_s_last_i, __pyx_k_last_i, sizeof(__pyx_k_last_i), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_math, __pyx_k_math, sizeof(__pyx_k_math), 0, 0, 1, 1}, + {&__pyx_n_s_max_err, __pyx_k_max_err, sizeof(__pyx_k_max_err), 0, 0, 1, 1}, + {&__pyx_n_s_max_errors, __pyx_k_max_errors, sizeof(__pyx_k_max_errors), 0, 0, 1, 1}, + {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_p, __pyx_k_p, sizeof(__pyx_k_p), 0, 0, 1, 1}, + {&__pyx_n_s_p0, __pyx_k_p0, sizeof(__pyx_k_p0), 0, 0, 1, 1}, + {&__pyx_n_s_p1, __pyx_k_p1, sizeof(__pyx_k_p1), 0, 0, 1, 1}, + {&__pyx_n_s_p2, __pyx_k_p2, sizeof(__pyx_k_p2), 0, 0, 1, 1}, + {&__pyx_n_s_p3, __pyx_k_p3, sizeof(__pyx_k_p3), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_real, __pyx_k_real, sizeof(__pyx_k_real), 0, 0, 1, 1}, + {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1}, + {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_spline, __pyx_k_spline, sizeof(__pyx_k_spline), 0, 0, 1, 1}, + {&__pyx_n_s_splines, __pyx_k_splines, sizeof(__pyx_k_splines), 0, 0, 1, 1}, + {&__pyx_n_s_split_cubic_into_n_gen, __pyx_k_split_cubic_into_n_gen, sizeof(__pyx_k_split_cubic_into_n_gen), 0, 0, 1, 1}, + {&__pyx_n_s_t1, __pyx_k_t1, sizeof(__pyx_k_t1), 0, 0, 1, 1}, + {&__pyx_n_s_t1_2, __pyx_k_t1_2, sizeof(__pyx_k_t1_2), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 22, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(0, 22, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 146, __pyx_L1_error) + __pyx_builtin_ZeroDivisionError = __Pyx_GetBuiltinName(__pyx_n_s_ZeroDivisionError); if (!__pyx_builtin_ZeroDivisionError) __PYX_ERR(0, 278, __pyx_L1_error) + __pyx_builtin_AssertionError = __Pyx_GetBuiltinName(__pyx_n_s_AssertionError); if (!__pyx_builtin_AssertionError) __PYX_ERR(0, 514, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/cu2qu/cu2qu.py":127 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + __pyx_tuple__4 = PyTuple_Pack(19, __pyx_n_s_p0, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p3, __pyx_n_s_n, __pyx_n_s_a1, __pyx_n_s_b1, __pyx_n_s_c1, __pyx_n_s_d1, __pyx_n_s_dt, __pyx_n_s_delta_2, __pyx_n_s_delta_3, __pyx_n_s_i, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_t1, __pyx_n_s_t1_2); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + __pyx_codeobj_ = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__4, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py, __pyx_n_s_split_cubic_into_n_gen, 127, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj_)) __PYX_ERR(0, 127, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":439 + * + * + * @cython.locals(max_err=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + */ + __pyx_tuple__5 = PyTuple_Pack(7, __pyx_n_s_curve, __pyx_n_s_max_err, __pyx_n_s_all_quadratic, __pyx_n_s_n, __pyx_n_s_spline, __pyx_n_s_p, __pyx_n_s_s); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 439, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py, __pyx_n_s_curve_to_quadratic, 439, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 439, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":474 + * + * + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) # <<<<<<<<<<<<<< + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): + */ + __pyx_tuple__7 = PyTuple_Pack(13, __pyx_n_s_curves, __pyx_n_s_max_errors, __pyx_n_s_all_quadratic, __pyx_n_s_l, __pyx_n_s_last_i, __pyx_n_s_i, __pyx_n_s_splines, __pyx_n_s_n, __pyx_n_s_spline, __pyx_n_s_curve, __pyx_n_s_p, __pyx_n_s_spline, __pyx_n_s_s); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 474, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_cu2qu_cu2qu_py, __pyx_n_s_curves_to_quadratic, 474, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 474, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_100 = PyInt_FromLong(100); if (unlikely(!__pyx_int_100)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + /* AssertionsEnabled.init */ + if (likely(__Pyx_init_assertions_enabled() == 0)); else + +if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen)) __PYX_ERR(0, 127, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen_spec, __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen) < 0) __PYX_ERR(0, 127, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen = &__pyx_type_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen) < 0) __PYX_ERR(0, 127, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen->tp_dictoffset && __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_5cu2qu_5cu2qu___pyx_scope_struct___split_cubic_into_n_gen->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_cu2qu(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_cu2qu}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "cu2qu", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initcu2qu(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initcu2qu(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_cu2qu(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_cu2qu(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_cu2qu(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + double __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'cu2qu' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("cu2qu", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to cu2qu pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_cu2qu(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_fontTools__cu2qu__cu2qu) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.cu2qu.cu2qu")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.cu2qu.cu2qu", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "fontTools/cu2qu/cu2qu.py":18 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "fontTools/cu2qu/cu2qu.py":21 + * import cython + * + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_True) < 0) __PYX_ERR(0, 21, __pyx_L2_error) + + /* "fontTools/cu2qu/cu2qu.py":18 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L7_try_end; + __pyx_L2_error:; + + /* "fontTools/cu2qu/cu2qu.py":22 + * + * COMPILED = cython.compiled + * except (AttributeError, ImportError): # <<<<<<<<<<<<<< + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches2(__pyx_builtin_AttributeError, __pyx_builtin_ImportError); + if (__pyx_t_4) { + __Pyx_AddTraceback("fontTools.cu2qu.cu2qu", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 22, __pyx_L4_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/cu2qu/cu2qu.py":24 + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython # <<<<<<<<<<<<<< + * + * COMPILED = False + */ + __pyx_t_8 = PyList_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 24, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_n_s_cython); + __Pyx_GIVEREF(__pyx_n_s_cython); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_n_s_cython)) __PYX_ERR(0, 24, __pyx_L4_except_error); + __pyx_t_9 = __Pyx_Import(__pyx_n_s_fontTools_misc, __pyx_t_8, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 24, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_ImportFrom(__pyx_t_9, __pyx_n_s_cython); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 24, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cython, __pyx_t_8) < 0) __PYX_ERR(0, 24, __pyx_L4_except_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/cu2qu/cu2qu.py":26 + * from fontTools.misc import cython + * + * COMPILED = False # <<<<<<<<<<<<<< + * + * import math + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_False) < 0) __PYX_ERR(0, 26, __pyx_L4_except_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L3_exception_handled; + } + goto __pyx_L4_except_error; + + /* "fontTools/cu2qu/cu2qu.py":18 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + __pyx_L4_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L3_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + __pyx_L7_try_end:; + } + + /* "fontTools/cu2qu/cu2qu.py":28 + * COMPILED = False + * + * import math # <<<<<<<<<<<<<< + * + * from .errors import Error as Cu2QuError, ApproxNotFoundError + */ + __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_math, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_math, __pyx_t_7) < 0) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/cu2qu/cu2qu.py":30 + * import math + * + * from .errors import Error as Cu2QuError, ApproxNotFoundError # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_7 = PyList_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_s_Error); + __Pyx_GIVEREF(__pyx_n_s_Error); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_n_s_Error)) __PYX_ERR(0, 30, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_ApproxNotFoundError); + __Pyx_GIVEREF(__pyx_n_s_ApproxNotFoundError); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 1, __pyx_n_s_ApproxNotFoundError)) __PYX_ERR(0, 30, __pyx_L1_error); + __pyx_t_6 = __Pyx_Import(__pyx_n_s_errors, __pyx_t_7, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_Error); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Cu2QuError, __pyx_t_7) < 0) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_ApproxNotFoundError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_ApproxNotFoundError, __pyx_t_7) < 0) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":33 + * + * + * __all__ = ["curve_to_quadratic", "curves_to_quadratic"] # <<<<<<<<<<<<<< + * + * MAX_N = 100 + */ + __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_n_u_curve_to_quadratic); + __Pyx_GIVEREF(__pyx_n_u_curve_to_quadratic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_n_u_curve_to_quadratic)) __PYX_ERR(0, 33, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_curves_to_quadratic); + __Pyx_GIVEREF(__pyx_n_u_curves_to_quadratic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 1, __pyx_n_u_curves_to_quadratic)) __PYX_ERR(0, 33, __pyx_L1_error); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_6) < 0) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":35 + * __all__ = ["curve_to_quadratic", "curves_to_quadratic"] + * + * MAX_N = 100 # <<<<<<<<<<<<<< + * + * NAN = float("NaN") + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_MAX_N, __pyx_int_100) < 0) __PYX_ERR(0, 35, __pyx_L1_error) + + /* "fontTools/cu2qu/cu2qu.py":37 + * MAX_N = 100 + * + * NAN = float("NaN") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_10 = __Pyx_PyUnicode_AsDouble(__pyx_n_u_NaN); if (unlikely(__pyx_t_10 == ((double)((double)-1)) && PyErr_Occurred())) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_6 = PyFloat_FromDouble(__pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_NAN, __pyx_t_6) < 0) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":127 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5cu2qu_5cu2qu_1_split_cubic_into_n_gen, 0, __pyx_n_s_split_cubic_into_n_gen, NULL, __pyx_n_s_fontTools_cu2qu_cu2qu, __pyx_d, ((PyObject *)__pyx_codeobj_)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_split_cubic_into_n_gen, __pyx_t_6) < 0) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":442 + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + * def curve_to_quadratic(curve, max_err, all_quadratic=True): # <<<<<<<<<<<<<< + * """Approximate a cubic Bezier curve with a spline of n quadratics. + * + */ + __pyx_t_6 = __Pyx_PyBool_FromLong(((int)1)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 442, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "fontTools/cu2qu/cu2qu.py":439 + * + * + * @cython.locals(max_err=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(n=cython.int) + * @cython.locals(all_quadratic=cython.int) + */ + __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 439, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6)) __PYX_ERR(0, 439, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5cu2qu_5cu2qu_4curve_to_quadratic, 0, __pyx_n_s_curve_to_quadratic, NULL, __pyx_n_s_fontTools_cu2qu_cu2qu, __pyx_d, ((PyObject *)__pyx_codeobj__6)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 439, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_6, __pyx_t_7); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curve_to_quadratic, __pyx_t_6) < 0) __PYX_ERR(0, 439, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":476 + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): # <<<<<<<<<<<<<< + * """Return quadratic Bezier splines approximating the input cubic Beziers. + * + */ + __pyx_t_6 = __Pyx_PyBool_FromLong(((int)1)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 476, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "fontTools/cu2qu/cu2qu.py":474 + * + * + * @cython.locals(l=cython.int, last_i=cython.int, i=cython.int) # <<<<<<<<<<<<<< + * @cython.locals(all_quadratic=cython.int) + * def curves_to_quadratic(curves, max_errors, all_quadratic=True): + */ + __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 474, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6)) __PYX_ERR(0, 474, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5cu2qu_5cu2qu_6curves_to_quadratic, 0, __pyx_n_s_curves_to_quadratic, NULL, __pyx_n_s_fontTools_cu2qu_cu2qu, __pyx_d, ((PyObject *)__pyx_codeobj__8)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 474, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_6, __pyx_t_7); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curves_to_quadratic, __pyx_t_6) < 0) __PYX_ERR(0, 474, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/cu2qu/cu2qu.py":1 + * # cython: language_level=3 # <<<<<<<<<<<<<< + * # distutils: define_macros=CYTHON_TRACE_NOGIL=1 + * + */ + __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_t_6, __pyx_kp_u_curves_to_quadratic_line_474, __pyx_kp_u_Return_quadratic_Bezier_splines) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_6) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.cu2qu.cu2qu", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.cu2qu.cu2qu"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* PyIntCompare */ +static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(inplace); + if (op1 == op2) { + return 1; + } + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + return (a == b); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + if (intval == 0) { + return (__Pyx_PyLong_IsZero(op1) == 1); + } else if (intval < 0) { + if (__Pyx_PyLong_IsNonNeg(op1)) + return 0; + intval = -intval; + } else { + if (__Pyx_PyLong_IsNeg(op1)) + return 0; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + return (unequal == 0); + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + return ((double)a == (double)b); + } + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_EQ)); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + PyObject* exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_subscript) { + PyObject *r, *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#elif CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; // error + return kwvalues[i]; + } + } + return NULL; // not found (no exception set) +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); // transfer ownership of value to values + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* pep479 */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) { + PyObject *exc, *val, *tb, *cur_exc; + __Pyx_PyThreadState_declare + #ifdef __Pyx_StopAsyncIteration_USED + int is_async_stopiteration = 0; + #endif + CYTHON_MAYBE_UNUSED_VAR(in_async_gen); + cur_exc = PyErr_Occurred(); + if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) { + #ifdef __Pyx_StopAsyncIteration_USED + if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) { + is_async_stopiteration = 1; + } else + #endif + return; + } + __Pyx_PyThreadState_assign + __Pyx_GetException(&exc, &val, &tb); + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + PyErr_SetString(PyExc_RuntimeError, + #ifdef __Pyx_StopAsyncIteration_USED + is_async_stopiteration ? "async generator raised StopAsyncIteration" : + in_async_gen ? "async generator raised StopIteration" : + #endif + "generator raised StopIteration"); +} + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* IterNext */ +static PyObject *__Pyx_PyIter_Next2Default(PyObject* defval) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (!defval || unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(defval); + return defval; + } + if (defval) { + Py_INCREF(defval); + return defval; + } + __Pyx_PyErr_SetNone(PyExc_StopIteration); + return NULL; +} +static void __Pyx_PyIter_Next_ErrorNoIterator(PyObject *iterator) { + __Pyx_TypeName iterator_type_name = __Pyx_PyType_GetName(Py_TYPE(iterator)); + PyErr_Format(PyExc_TypeError, + __Pyx_FMT_TYPENAME " object is not an iterator", iterator_type_name); + __Pyx_DECREF_TypeName(iterator_type_name); +} +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) { + PyObject* next; + iternextfunc iternext = Py_TYPE(iterator)->tp_iternext; + if (likely(iternext)) { +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + next = iternext(iterator); + if (likely(next)) + return next; +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + if (unlikely(iternext == &_PyObject_NextNotImplemented)) + return NULL; +#endif +#else + next = PyIter_Next(iterator); + if (likely(next)) + return next; +#endif + } else if (CYTHON_USE_TYPE_SLOTS || unlikely(!PyIter_Check(iterator))) { + __Pyx_PyIter_Next_ErrorNoIterator(iterator); + return NULL; + } +#if !CYTHON_USE_TYPE_SLOTS + else { + next = PyIter_Next(iterator); + if (likely(next)) + return next; + } +#endif + return __Pyx_PyIter_Next2Default(defval); +} + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long x; + long a = PyInt_AS_LONG(op1); + + x = (long)((unsigned long)a + (unsigned long)b); + if (likely((x^a) >= 0 || (x^b) >= 0)) + return PyInt_FromLong(x); + return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + const long b = intval; + long a, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return __Pyx_NewRef(op2); + } + if (likely(__Pyx_PyLong_IsCompact(op1))) { + a = __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + } + x = a + b; + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla + llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + double result; + + PyFPE_START_PROTECT("add", return NULL) + result = ((double)a) + (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* SetItemInt */ +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { + int r; + if (unlikely(!j)) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, + CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o)))) { + PyObject* old = PyList_GET_ITEM(o, n); + Py_INCREF(v); + PyList_SET_ITEM(o, n, v); + Py_DECREF(old); + return 1; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_ass_subscript) { + int r; + PyObject *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return -1; + r = mm->mp_ass_subscript(o, key, v); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_ass_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); + } + } + return sm->sq_ass_item(o, i, v); + } + } +#else + if (is_list || !PyMapping_Check(o)) + { + return PySequence_SetItem(o, i, v); + } +#endif + return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); +} + +/* ModInt[long] */ +static CYTHON_INLINE long __Pyx_mod_long(long a, long b) { + long r = a % b; + r += ((r != 0) & ((r ^ b) < 0)) * b; + return r; +} + +/* FixUpExtensionType */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* PyObjectCallNoArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#elif PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* ValidateBasesTuple */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_MACROS + n = PyTuple_GET_SIZE(bases); +#else + n = PyTuple_Size(bases); + if (n < 0) return -1; +#endif + for (i = 1; i < n; i++) + { +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + PyTypeObject *b; +#if PY_MAJOR_VERSION < 3 + if (PyClass_Check(b0)) + { + PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", + PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + if (dictoffset == 0) + { + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + } + return 0; +} +#endif + +/* PyType_Ready */ +static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) + gc = PyImport_GetModule(__pyx_kp_u_gc); + #endif + if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); + return -1; + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } + #endif + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); + #endif + } +#endif + return r; +#endif +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, attr_name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(attr_name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__2); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* ImportDottedModule */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; +} +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__3; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); +} + +/* pybytes_as_double */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj) { + PyObject *float_value; +#if PY_MAJOR_VERSION >= 3 + float_value = PyFloat_FromString(obj); +#else + float_value = PyFloat_FromString(obj, 0); +#endif + if (likely(float_value)) { +#if CYTHON_ASSUME_SAFE_MACROS + double value = PyFloat_AS_DOUBLE(float_value); +#else + double value = PyFloat_AsDouble(float_value); +#endif + Py_DECREF(float_value); + return value; + } + return (double)-1; +} +static const char* __Pyx__PyBytes_AsDouble_Copy(const char* start, char* buffer, Py_ssize_t length) { + int last_was_punctuation = 1; + Py_ssize_t i; + for (i=0; i < length; i++) { + char chr = start[i]; + int is_punctuation = (chr == '_') | (chr == '.') | (chr == 'e') | (chr == 'E'); + *buffer = chr; + buffer += (chr != '_'); + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyBytes_AsDouble_inf_nan(const char* start, Py_ssize_t length) { + int matches = 1; + char sign = start[0]; + int is_signed = (sign == '+') | (sign == '-'); + start += is_signed; + length -= is_signed; + switch (start[0]) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + matches &= (start[1] == 'a' || start[1] == 'A'); + matches &= (start[2] == 'n' || start[2] == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + matches &= (start[1] == 'n' || start[1] == 'N'); + matches &= (start[2] == 'f' || start[2] == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + matches &= (start[3] == 'i' || start[3] == 'I'); + matches &= (start[4] == 'n' || start[4] == 'N'); + matches &= (start[5] == 'i' || start[5] == 'I'); + matches &= (start[6] == 't' || start[6] == 'T'); + matches &= (start[7] == 'y' || start[7] == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static CYTHON_INLINE int __Pyx__PyBytes_AsDouble_IsSpace(char ch) { + return (ch == 0x20) | !((ch < 0x9) | (ch > 0xd)); +} +CYTHON_UNUSED static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length) { + double value; + Py_ssize_t i, digits; + const char *last = start + length; + char *end; + while (__Pyx__PyBytes_AsDouble_IsSpace(*start)) + start++; + while (start < last - 1 && __Pyx__PyBytes_AsDouble_IsSpace(last[-1])) + last--; + length = last - start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyBytes_AsDouble_inf_nan(start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + digits = 0; + for (i=0; i < length; digits += start[i++] != '_'); + if (likely(digits == length)) { + value = PyOS_string_to_double(start, &end, NULL); + } else if (digits < 40) { + char number[40]; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((digits + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} + +/* FetchSharedCythonModule */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* PyVectorcallFastCallDict */ +#if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* Declarations */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = (double)(1.0) / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = (double)(1.0) / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* FromPy */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject* o) { + Py_complex cval; +#if !CYTHON_COMPILING_IN_PYPY + if (PyComplex_CheckExact(o)) + cval = ((PyComplexObject *)o)->cval; + else +#endif + cval = PyComplex_AsCComplex(o); + return __pyx_t_double_complex_from_parts( + (double)cval.real, + (double)cval.imag); +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__9); + } + return name; +} +#endif + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallMethod1 */ +#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2 + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_GetMethod; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* CoroutineBase */ +#include +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *__pyx_tstate, PyObject **pvalue) { + PyObject *et, *ev, *tb; + PyObject *value = NULL; + CYTHON_UNUSED_VAR(__pyx_tstate); + __Pyx_ErrFetch(&et, &ev, &tb); + if (!et) { + Py_XDECREF(tb); + Py_XDECREF(ev); + Py_INCREF(Py_None); + *pvalue = Py_None; + return 0; + } + if (likely(et == PyExc_StopIteration)) { + if (!ev) { + Py_INCREF(Py_None); + value = Py_None; + } +#if PY_VERSION_HEX >= 0x030300A0 + else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } +#endif + else if (unlikely(PyTuple_Check(ev))) { + if (PyTuple_GET_SIZE(ev) >= 1) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + value = PyTuple_GET_ITEM(ev, 0); + Py_INCREF(value); +#else + value = PySequence_ITEM(ev, 0); +#endif + } else { + Py_INCREF(Py_None); + value = Py_None; + } + Py_DECREF(ev); + } + else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { + value = ev; + } + if (likely(value)) { + Py_XDECREF(tb); + Py_DECREF(et); + *pvalue = value; + return 0; + } + } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + PyErr_NormalizeException(&et, &ev, &tb); + if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + Py_XDECREF(tb); + Py_DECREF(et); +#if PY_VERSION_HEX >= 0x030300A0 + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); +#else + { + PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args); + Py_DECREF(ev); + if (likely(args)) { + value = PySequence_GetItem(args, 0); + Py_DECREF(args); + } + if (unlikely(!value)) { + __Pyx_ErrRestore(NULL, NULL, NULL); + Py_INCREF(Py_None); + value = Py_None; + } + } +#endif + *pvalue = value; + return 0; +} +static CYTHON_INLINE +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_CLEAR(exc_state->exc_value); +#else + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +#endif +} +#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { + msg = "coroutine already executing"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { + msg = "async generator already executing"; + #endif + } else { + msg = "generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); +} +#define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_NotStartedError(PyObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(gen)) { + msg = "can't send non-None value to a just-started coroutine"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a just-started async generator"; + #endif + } else { + msg = "can't send non-None value to a just-started generator"; + } + PyErr_SetString(PyExc_TypeError, msg); +} +#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing) (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) { + CYTHON_MAYBE_UNUSED_VAR(gen); + CYTHON_MAYBE_UNUSED_VAR(closing); + #ifdef __Pyx_Coroutine_USED + if (!closing && __Pyx_Coroutine_Check(gen)) { + PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); + } else + #endif + if (value) { + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); + else + #endif + PyErr_SetNone(PyExc_StopIteration); + } +} +static +PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { + __Pyx_PyThreadState_declare + PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; + PyObject *retval; + assert(!self->is_running); + if (unlikely(self->resume_label == 0)) { + if (unlikely(value && value != Py_None)) { + return __Pyx_Coroutine_NotStartedError((PyObject*)self); + } + } + if (unlikely(self->resume_label == -1)) { + return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); + } +#if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + tstate = __pyx_tstate; +#else + tstate = __Pyx_PyThreadState_Current; +#endif + exc_state = &self->gi_exc_state; + if (exc_state->exc_value) { + #if CYTHON_COMPILING_IN_PYPY + #else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #elif PY_VERSION_HEX >= 0x030B00a4 + exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback; + #else + exc_tb = exc_state->exc_traceback; + #endif + if (exc_tb) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + assert(f->f_back == NULL); + #if PY_VERSION_HEX >= 0x030B00A1 + f->f_back = PyThreadState_GetFrame(tstate); + #else + Py_XINCREF(tstate->frame); + f->f_back = tstate->frame; + #endif + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + Py_DECREF(exc_tb); + #endif + } + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } else { + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } +#endif + self->is_running = 1; + retval = self->body(self, tstate, value); + self->is_running = 0; +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif + return retval; +} +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { +#if CYTHON_COMPILING_IN_PYPY + CYTHON_UNUSED_VAR(exc_state); +#else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 + if (!exc_state->exc_value) return; + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #else + exc_tb = exc_state->exc_traceback; + #endif + if (likely(exc_tb)) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + Py_CLEAR(f->f_back); + #if PY_VERSION_HEX >= 0x030B00a4 + Py_DECREF(exc_tb); + #endif + } +#endif +} +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_MethodReturn(PyObject* gen, PyObject *retval) { + CYTHON_MAYBE_UNUSED_VAR(gen); + if (unlikely(!retval)) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (!__Pyx_PyErr_Occurred()) { + PyObject *exc = PyExc_StopIteration; + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + exc = __Pyx_PyExc_StopAsyncIteration; + #endif + __Pyx_PyErr_SetNone(exc); + } + } + return retval; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) +static CYTHON_INLINE +PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) { +#if PY_VERSION_HEX <= 0x030A00A1 + return _PyGen_Send(gen, arg); +#else + PyObject *result; + if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { +#if PY_VERSION_HEX < 0x030d00A1 + _PyGen_SetStopIterationValue(result); +#else + if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) { + PyErr_SetObject(PyExc_StopIteration, result); + } else { + PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result); + if (likely(exc != NULL)) { + PyErr_SetObject(PyExc_StopIteration, exc); + Py_DECREF(exc); + } + } +#endif + } + Py_DECREF(result); + result = NULL; + } + return result; +#endif +} +#endif +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { + PyObject *ret; + PyObject *val = NULL; + __Pyx_Coroutine_Undelegate(gen); + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); + ret = __Pyx_Coroutine_SendEx(gen, val, 0); + Py_XDECREF(val); + return ret; +} +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { + PyObject *retval; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + ret = __Pyx_async_gen_asend_send(yf, value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyCoro_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + { + if (value == Py_None) + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + else + ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value); + } + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + retval = __Pyx_Coroutine_FinishDelegation(gen); + } else { + retval = __Pyx_Coroutine_SendEx(gen, value, 0); + } + return __Pyx_Coroutine_MethodReturn(self, retval); +} +static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { + PyObject *retval = NULL; + int err = 0; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + if (__Pyx_CoroutineAwait_CheckExact(yf)) { + retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + retval = __Pyx_async_gen_asend_close(yf, NULL); + } else + if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { + retval = __Pyx_async_gen_athrow_close(yf, NULL); + } else + #endif + { + PyObject *meth; + gen->is_running = 1; + meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_close); + if (unlikely(!meth)) { + if (unlikely(PyErr_Occurred())) { + PyErr_WriteUnraisable(yf); + } + } else { + retval = __Pyx_PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (unlikely(!retval)) + err = -1; + } + gen->is_running = 0; + } + Py_XDECREF(retval); + return err; +} +static PyObject *__Pyx_Generator_Next(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Generator_Next(yf); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, Py_None); + } else + #endif + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + return __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_SendEx(gen, Py_None, 0); +} +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); + return __Pyx_Coroutine_Close(self); +} +static PyObject *__Pyx_Coroutine_Close(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *retval, *raised_exception; + PyObject *yf = gen->yieldfrom; + int err = 0; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + Py_INCREF(yf); + err = __Pyx_Coroutine_CloseIter(gen, yf); + __Pyx_Coroutine_Undelegate(gen); + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + retval = __Pyx_Coroutine_SendEx(gen, NULL, 1); + if (unlikely(retval)) { + const char *msg; + Py_DECREF(retval); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(self)) { + msg = "coroutine ignored GeneratorExit"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(self)) { +#if PY_VERSION_HEX < 0x03060000 + msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)"; +#else + msg = "async generator ignored GeneratorExit"; +#endif + #endif + } else { + msg = "generator ignored GeneratorExit"; + } + PyErr_SetString(PyExc_RuntimeError, msg); + return NULL; + } + raised_exception = PyErr_Occurred(); + if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) { + if (raised_exception) PyErr_Clear(); + Py_INCREF(Py_None); + return Py_None; + } + return NULL; +} +static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, + PyObject *args, int close_on_genexit) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + Py_INCREF(yf); + if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { + int err = __Pyx_Coroutine_CloseIter(gen, yf); + Py_DECREF(yf); + __Pyx_Coroutine_Undelegate(gen); + if (err < 0) + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); + goto throw_here; + } + gen->is_running = 1; + if (0 + #ifdef __Pyx_Generator_USED + || __Pyx_Generator_CheckExact(yf) + #endif + #ifdef __Pyx_Coroutine_USED + || __Pyx_Coroutine_Check(yf) + #endif + ) { + ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { + ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); + #endif + } else { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_throw); + if (unlikely(!meth)) { + Py_DECREF(yf); + if (unlikely(PyErr_Occurred())) { + gen->is_running = 0; + return NULL; + } + __Pyx_Coroutine_Undelegate(gen); + gen->is_running = 0; + goto throw_here; + } + if (likely(args)) { + ret = __Pyx_PyObject_Call(meth, args, NULL); + } else { + PyObject *cargs[4] = {NULL, typ, val, tb}; + ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } + Py_DECREF(meth); + } + gen->is_running = 0; + Py_DECREF(yf); + if (!ret) { + ret = __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_MethodReturn(self, ret); + } +throw_here: + __Pyx_Raise(typ, val, tb, NULL); + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); +} +static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { + PyObject *typ; + PyObject *val = NULL; + PyObject *tb = NULL; + if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))) + return NULL; + return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); +} +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_VISIT(exc_state->exc_value); +#else + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); +#endif + return 0; +} +static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { + Py_VISIT(gen->closure); + Py_VISIT(gen->classobj); + Py_VISIT(gen->yieldfrom); + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); +} +static int __Pyx_Coroutine_clear(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + Py_CLEAR(gen->closure); + Py_CLEAR(gen->classobj); + Py_CLEAR(gen->yieldfrom); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); + } +#endif + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_frame); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + Py_CLEAR(gen->gi_modulename); + return 0; +} +static void __Pyx_Coroutine_dealloc(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject_GC_UnTrack(gen); + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); + if (gen->resume_label >= 0) { + PyObject_GC_Track(self); +#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE + if (unlikely(PyObject_CallFinalizerFromDealloc(self))) +#else + Py_TYPE(gen)->tp_del(self); + if (unlikely(Py_REFCNT(self) > 0)) +#endif + { + return; + } + PyObject_GC_UnTrack(self); + } +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); + } +#endif + __Pyx_Coroutine_clear(self); + __Pyx_PyHeapTypeObject_GC_Del(gen); +} +static void __Pyx_Coroutine_del(PyObject *self) { + PyObject *error_type, *error_value, *error_traceback; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PyThreadState_declare + if (gen->resume_label < 0) { + return; + } +#if !CYTHON_USE_TP_FINALIZE + assert(self->ob_refcnt == 0); + __Pyx_SET_REFCNT(self, 1); +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); + if (unlikely(!res)) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); + return; + } + } +#endif + if (unlikely(gen->resume_label == 0 && !error_value)) { +#ifdef __Pyx_Coroutine_USED +#ifdef __Pyx_Generator_USED + if (!__Pyx_Generator_CheckExact(self)) +#endif + { + PyObject_GC_UnTrack(self); +#if PY_MAJOR_VERSION >= 3 || defined(PyErr_WarnFormat) + if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) + PyErr_WriteUnraisable(self); +#else + {PyObject *msg; + char *cmsg; + #if CYTHON_COMPILING_IN_PYPY + msg = NULL; + cmsg = (char*) "coroutine was never awaited"; + #else + char *cname; + PyObject *qualname; + qualname = gen->gi_qualname; + cname = PyString_AS_STRING(qualname); + msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname); + if (unlikely(!msg)) { + PyErr_Clear(); + cmsg = (char*) "coroutine was never awaited"; + } else { + cmsg = PyString_AS_STRING(msg); + } + #endif + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) + PyErr_WriteUnraisable(self); + Py_XDECREF(msg);} +#endif + PyObject_GC_Track(self); + } +#endif + } else { + PyObject *res = __Pyx_Coroutine_Close(self); + if (unlikely(!res)) { + if (PyErr_Occurred()) + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); +#if !CYTHON_USE_TP_FINALIZE + assert(Py_REFCNT(self) > 0); + if (likely(--self->ob_refcnt == 0)) { + return; + } + { + Py_ssize_t refcnt = Py_REFCNT(self); + _Py_NewReference(self); + __Pyx_SET_REFCNT(self, refcnt); + } +#if CYTHON_COMPILING_IN_CPYTHON + assert(PyType_IS_GC(Py_TYPE(self)) && + _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + _Py_DEC_REFTOTAL; +#endif +#ifdef COUNT_ALLOCS + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; +#endif +#endif +} +static PyObject * +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_name; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_name, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_qualname; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_qualname, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context) +{ + PyObject *frame = self->gi_frame; + CYTHON_UNUSED_VAR(context); + if (!frame) { + if (unlikely(!self->gi_code)) { + Py_RETURN_NONE; + } + frame = (PyObject *) PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + (PyCodeObject*) self->gi_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (unlikely(!frame)) + return NULL; + self->gi_frame = frame; + } + Py_INCREF(frame); + return frame; +} +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); + if (unlikely(!gen)) + return NULL; + return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + gen->body = body; + gen->closure = closure; + Py_XINCREF(closure); + gen->is_running = 0; + gen->resume_label = 0; + gen->classobj = NULL; + gen->yieldfrom = NULL; + #if PY_VERSION_HEX >= 0x030B00a4 + gen->gi_exc_state.exc_value = NULL; + #else + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; + #endif +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif + gen->gi_weakreflist = NULL; + Py_XINCREF(qualname); + gen->gi_qualname = qualname; + Py_XINCREF(name); + gen->gi_name = name; + Py_XINCREF(module_name); + gen->gi_modulename = module_name; + Py_XINCREF(code); + gen->gi_code = code; + gen->gi_frame = NULL; + PyObject_GC_Track(gen); + return gen; +} + +/* PatchModuleWithCoroutine */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + int result; + PyObject *globals, *result_obj; + globals = PyDict_New(); if (unlikely(!globals)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_coroutine_type", + #ifdef __Pyx_Coroutine_USED + (PyObject*)__pyx_CoroutineType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_generator_type", + #ifdef __Pyx_Generator_USED + (PyObject*)__pyx_GeneratorType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore; + result_obj = PyRun_String(py_code, Py_file_input, globals, globals); + if (unlikely(!result_obj)) goto ignore; + Py_DECREF(result_obj); + Py_DECREF(globals); + return module; +ignore: + Py_XDECREF(globals); + PyErr_WriteUnraisable(module); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { + Py_DECREF(module); + module = NULL; + } +#else + py_code++; +#endif + return module; +} + +/* PatchGeneratorABC */ +#ifndef CYTHON_REGISTER_ABCS +#define CYTHON_REGISTER_ABCS 1 +#endif +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) +static PyObject* __Pyx_patch_abc_module(PyObject *module); +static PyObject* __Pyx_patch_abc_module(PyObject *module) { + module = __Pyx_Coroutine_patch_module( + module, "" +"if _cython_generator_type is not None:\n" +" try: Generator = _module.Generator\n" +" except AttributeError: pass\n" +" else: Generator.register(_cython_generator_type)\n" +"if _cython_coroutine_type is not None:\n" +" try: Coroutine = _module.Coroutine\n" +" except AttributeError: pass\n" +" else: Coroutine.register(_cython_coroutine_type)\n" + ); + return module; +} +#endif +static int __Pyx_patch_abc(void) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + static int abc_patched = 0; + if (CYTHON_REGISTER_ABCS && !abc_patched) { + PyObject *module; + module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections"); + if (unlikely(!module)) { + PyErr_WriteUnraisable(NULL); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, + ((PY_MAJOR_VERSION >= 3) ? + "Cython module failed to register with collections.abc module" : + "Cython module failed to register with collections module"), 1) < 0)) { + return -1; + } + } else { + module = __Pyx_patch_abc_module(module); + abc_patched = 1; + if (unlikely(!module)) + return -1; + Py_DECREF(module); + } + module = PyImport_ImportModule("backports_abc"); + if (module) { + module = __Pyx_patch_abc_module(module); + Py_XDECREF(module); + } + if (!module) { + PyErr_Clear(); + } + } +#else + if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL); +#endif + return 0; +} + +/* Generator */ +static PyMethodDef __pyx_Generator_methods[] = { + {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, + (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, + {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, + (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, + (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, + {0, 0, 0, 0} +}; +static PyMemberDef __pyx_Generator_memberlist[] = { + {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, + {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, + (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, + {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, + {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0}, +#if CYTHON_USE_TYPE_SPECS + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyGetSetDef __pyx_Generator_getsets[] = { + {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, + (char*) PyDoc_STR("name of the generator"), 0}, + {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, + (char*) PyDoc_STR("qualified name of the generator"), 0}, + {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL, + (char*) PyDoc_STR("Frame of the generator"), 0}, + {0, 0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_GeneratorType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc}, + {Py_tp_traverse, (void *)__Pyx_Coroutine_traverse}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_Generator_Next}, + {Py_tp_methods, (void *)__pyx_Generator_methods}, + {Py_tp_members, (void *)__pyx_Generator_memberlist}, + {Py_tp_getset, (void *)__pyx_Generator_getsets}, + {Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict}, +#if CYTHON_USE_TP_FINALIZE + {Py_tp_finalize, (void *)__Pyx_Coroutine_del}, +#endif + {0, 0}, +}; +static PyType_Spec __pyx_GeneratorType_spec = { + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + __pyx_GeneratorType_slots +}; +#else +static PyTypeObject __pyx_GeneratorType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + (destructor) __Pyx_Coroutine_dealloc, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + 0, + (traverseproc) __Pyx_Coroutine_traverse, + 0, + 0, + offsetof(__pyx_CoroutineObject, gi_weakreflist), + 0, + (iternextfunc) __Pyx_Generator_Next, + __pyx_Generator_methods, + __pyx_Generator_memberlist, + __pyx_Generator_getsets, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if CYTHON_USE_TP_FINALIZE + 0, +#else + __Pyx_Coroutine_del, +#endif + 0, +#if CYTHON_USE_TP_FINALIZE + __Pyx_Coroutine_del, +#elif PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_Generator_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; + __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); +#endif + if (unlikely(!__pyx_GeneratorType)) { + return -1; + } + return 0; +} + +/* CheckBinaryVersion */ +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ +#if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..9ace13613b26baaafe1a172f71e37e9d5b085934 GIT binary patch literal 357207 zcmeFad3;nw*8ksuv_vG_pr8>&qJjn&Oq6Icz?g;vZbJv7fQAtSMG<#|ZV4(7?X+^a zwlJ=YeQ*KQ_H>gl|wJB^LRX6vOJz{xLrM-a;SQ|o}PsD5RZg+?x3G)HGj-~O%9;soV7e3IEdl9&E)9f7{tt8GrcMoBRU2$i_#?b? zbllDNEPM;H;ea($m zyCI$N&U#kk-O)=YNYY7w4!jaLb!zCwx!2ry<s`@l+EpQThDW=5_I$K!dCp)x}dY+~X0kO1%8tK_dB=v|)aJtwMkLr)ESK zPw#Yw++@e$N;y}K{p`EZS?9j_o5ySCoW1z8h5>}-Nt(mEQ;}THX-Qhb_>*zBlz+)9 z<$FA*GJIxv&I-+$eb)8YTp|DC=gkRTb;IBhgRh(ir4o5g!4cdT^<0WO$fc{PXCeN~ zUq%8M31lRYkw8WQ83|-0kdZ(}0vQQpB#@CnMgkcLWF(N0Kt=)?31lRYkw8WQ83|-0 zkdZ(}0vQQpB#@CnMgkcLWF(N0Kt=)?31lRYkw8WQ83|-0kdZ(}0vQQpB=G+i2~0Gt zPt54>w||-CnG*l{vMkSx!A5_5=iKOD;qgek?-Jj|zKOmGp=5hw~R00>Y@@LZX26nKL+<>p24aRuh01xPbGLQKz_o(UPGms?D_4J4f*FjnDd9 zJ9G`um60!vMKdLNw4|>Kb9NHuAbKEtMN1BAhuJu}6HKop%!wN2qgq|P1m&sfZArnr zp`sKw^E<Els;DvMiHrQ;&c>8co_YMDF;=9Z@b;^brNhR%|pXME3I6O!IQzf==Ow&}hm`#!VZ`<0aiwAFcySFsywY{Sr zQ4N8_%Jv!c`z5LEEz|5F#LaV2<6$t@0OM`(clr@;4euqH!rii*b;O|C$3pwo(Zae- z-!8xt_GHn!-j)1kODfUj$0dbCSl+LGMOburOyZAB#y{L1|Bl4l!~dw9J~5TL^14HVgBQi~$yOYTw;m6JP2MVslRw{@Q~IMPTX?jC(DPHF zr%LD=LVarr#rxlQRl$O0L|!GUIekz0;$cP6sV&8=b>AO8_mrjZ(-s}_Vsyyd@FwBH zoPNM~aabuS>b~zjdzaN}Hh!9CW_<&9VB8IcO4JeNtoA|bKf%j!@j^qRvnjB(14{$K z>$`LSQ9>G)2S=2gWGd?$t9hWu)7Hi#GlzE#-e_8{nvIG4#&}+Z@#33i_=}uCwBN#8 zq&54Th7*Y9-gmj^?w6ItZGq?u)#%!~W@^Kz_E&ix%GYo>zr``%MdN+ro#m6r8Qxf+ z#773J)%iz_Zr~+I6`0~S=d53l$nw7Oa0fN3I{`6AhyN<1N-J)4^2kWCr%9&N?OL6n zHkH7|xi6Vuf=;lFA;TFy8Z^thAQ|@t&nwXt?!8-KUM-_{ba)Gs1%Y?yz()vlygJ{w zWWL8FU(~B;DG8g(G-~_-mFcL*|>BaZ*M`gBDIiE z>or21P)(6VIEF@8iq}P0CSDL8!4-sU4=IG@kWfoB!V009A}euRga*7WLQK3Mtj86E zK67NpDE`lRo5I)Bhgc%xPHzd@_8eyMMO%cy`ZEf-t7Tz4Z zE<&DoK{ygu5YEsD`H)aw$Q*1%3WREk6ynHpe|U@Vx(KD>1>tA7g0Sa7m8TpMYNbXn zg=&ga7VX?U6 zS)dV?LPC{l9+nB!6j_er)?$Su=MQ~YDP9ns!xbJXG(rO;)IrTdOsJ+vGfuYVp#`st zuvNSuY{M0V?iyhyB-A>M;0VYCB&!$Khammy2fU0>8B-CP!kS7#V z4NiZmfwus!i%^JH5KfaI@;sywiXfq8Ua9a(g<^)nIa1fcl;r#&hidUsi;HlDhsheD z1`?`NBTN&D?u3IKB|OZ+>mt#luu`a|NCS?G5X0*tG>aF6S8xU4zcfM%Bvh?N*eVp=3CBfn z@VW@Q#S6k7TtNtGgnf`ur5eH0st|H;WUK`&53h@mFJ2J(;tImgG(rI+)cz|}oeG7b zJK^MLgi^dNLb-TB7=bGY9*tl^LcOdJs)eFE;mAkh@lM0*BFq#o2-o5Y!X_D5=}VAM zwnnHGswq;3BTtg!U4+*~SSnr+?!y&?do;o_NT`c7!g8USA}er?(g-W@x(E&81>q%J zLAXdG#2}$g)d2;Ff7;RBgjtVkXt)C!G|FBIJg$K|0AuggP`ctJQDR}h}i2&IrvGc`iFP)!jN z$K|0KuZvJ4UJ!nPD+t$WglUjaXJ~|(LeZUYTuIjAbrI^s3&Neaf>5Lp7C}PAWp1}3 zONDBREW>d}x#f6Wgcafi;VE1}Xys{r@~nh}TCL}c2BDfFF&r168Lx}bB3=--;0nST zjj$CG>J;6YJB4bBI5=)CcH?ys_K6pS1GpgM-l-6xo_*x8B01vFk8s?q`FP!|1$bp> zIZ0fKyFeFS2np3ivtJ}sQ=}9}9sUNb9M~zVQBb=n+ zfY(KsC0-C_;|lxRmq?yyEu?8h>cpV~;ka3s;&rnw!z=7RA}+q@k(1fCqd*nQX@1#LcOdJVnSgt;J9*V zk>vc*7F)#&58H5shpkan>P|?gI*s56g~fp5w&p&(E`sNP=AjF&@bFuWkOK)-sS)yo z!eYR25eg)^=Alr$@NgQg@NlI@D1wAKccS8`R4Dop&e3GUYvOegs>KV!MYw`+nntLB zglcBVXj+kJLSZrBxOVU?ye>kmctN-oR}gl~zK#{CgM@leBPT$R-cxJ$i06BSkb~pe;(2&ognaRW&=*$_ax_8#B-HOTLZMJt z3^?w5Uy9d7C>JjXBX9-bb=jV#I@=zpR5YEOGgxMOQ6cQ?1Ba{n8cfxTs zsv570P$OOtet|0pr5a%xBvg~0?`H~y#en0EQMGtoggWtpa3`)H9I})g7C}NqU5h~| zECw7`Czs=O5mty7gr{%?VWUP^2?=$vMraTUivh=Ni)OqoLW_7o*n%qvi#5VlNT^;H zDvovv#q5ORN^&<|7h#`xK{$Xb2-O)^?*hw5(>is#~oqH@wy16ctIG0D+vEwr27&i)I^O?BNT=Mj*Bo8uZu8CydccR z6@=eugjz_bqcuXEP}mPRF2Yj0F2XYLg765gAk5SV%ORoOy+m=eLMZG992cPhuZs{9 zF9_>#1!1s8XoiGZrV(0%Vs^rD`{qu(E`lRo5I)BhgzwbmOk_7C)MSmYPblmMHf~+5 z&cW*<aGzSp|Brt?zk)=~5*e`7 zK57+57xni*o6+CYvWJ!^YTpiCYKAwpIk_X{i0Cl3KZBeQH8~Gfup?`qV}>^rk~uiu zv~SyK+H)M^#gY5FkK7l0rS7%^o}l3zSDDNgYEHav+T(W%oEg~?>{Yzk`2-Y=8hR?R z(sA0!Und@aS@z1E#T3l;=^OQI(XP3uKP<|I{~=W5W$7-?wK{$k@x6mCTrb1#wa?a5@=C)+aX%cg##2g%oPh0(C?|Iu4x95Y%aXV_)>g6(x~*iT`kf6AZ6!U_Z!1N#mBiHV zb1LL|^?RB6ouz)qsNauOn%C9uGJc)&M^Jot<1ExlaD8iLB-Lsm%^$G)tY4_a_ZJ*t zMLKeEYw?!93Qv_BF#PpoJid#rUD#G)D8{}a<@oW{ok_DBFiaqM6$?kx;A4L zNRj=9;s|W2HiDmCn{BE#QjfNhTS%O&P4MRmT57YGqEv03p@%X$?!65f`Kc1TW%J$G z?I4-9na62+7vrA43l$#z`R%wyJ%$rhV_WeS)4si>p!M!Q!A2LOzKbBr5n9=sp-{{u?P7LEa~F)t z@>E!#R#hn1*9w{f*|Ba6VLrW451gx)}-$9b~ zW}P*3k8{m%DLocCnp3N>*Gr^aPPm#fof#4p9$rD(tYc#+`u8gSaC2x?ixC+w+I7c9 zIaE$NeD=_^r09~7_Ddc+v% zWNU?#oL{1lB&<#)e4$1qd{!KP^x~|5)#ltAAd$7fFAdItdz*8$C}m{3QQt@OW@x{+ zuj3v;e>`uA=V&~u#gi*i9}Ay8t0~b_)MseF=ZNqb4>Yykp6Cl$Wu(oxw+>d}y-phB zCwafiFT6jQa7A6Tl7-;@V4D$nPtfRNJ=iADDhO;w{-am*tS(N+M3=l*XnF8 zlgh?I$HBs1W+r)Ty9}ST4IY0f@lD<*Xf^rst+`UN{=j=5oqN-=)~2#S zxiaE6<5w*Qmb-=XX z^*UHOq;Cytiw?8alSImByiR1On3a+3YbQ#0CAY*DJx)07{PZngha1#DEH><-r4l|g z_xCfhJfWUU1dre`EfriheB(UeLh~3p9-cxoEI5xi8D*bfr%sIFwa4*+$@W{affGDVrR^(0pU}dIJT2gO7hs$_&L!K6s^K@9 z_EN>CojVlv5{H|1b-t`mjyA29fIT}$)OHgtsJBpxyUDAE7K<;&lsE(3dHI|ax&a+FV5+!wCSf#|lO+Lmf zx#P!tC(T6El@i58I}!R_GNKLbR|bzp{WY2xqKL_wI7Sf{2*LROdkTz?gYet852yii zT2QLm=W-n9Q5N5kSioAFL)8M-lO~Q)|DBk?(cy2%gc8klaMsxv2Sue08) zoIdwWry_rGv$rZU{YNI|K4io6D56AEl$*3R5yTbbPuZex=!7C{H=zhTT@|0zDI{1@ z`0cxOM=3S!8r=zOrSqo6a4;*!w4>7EriD43HndzVC}RJV%7{dLjmTi}Sv%q<;ugoy zyUkaicMrrE$B#+7s(7Z(8SKk_#dbj*L#W(MjqG75?5sLlq`y|NZV!*&tR%e$aRsac z&LSd3b0&!8W$Q%R5Z^)@Bc){3^j5-ANY=Depwf}6)LJ_?dp5!Jbki$IvHmF<-|PeBZCngvsKNuksL zU7P`rvTMS9HIK2VQjD|?a(YTc(k`c@HrXYDr{(veC1)J-%CESg9Hed|tyX(ix#Rc`LdQmGCNHAscXSP+#g$%cZ*mv17i zU9wcMszw~=7e!iI=E)%Eb{oyg6EqQ0NU}oqI-NaBW$*I~G{ia1&0a-zZeh2Q!e>_u zD5#GaRyGW-C^za)5Jsafh!rd&+gsFz;W}VHDl>g-b>A_^=%)HjrKl`H88!mZvRx{!I)XL&8VLs4Qzd2 z?tLea^?}xIGkhr9xbs9Jm zOfBJEhx~irn_+ytxw3fs4CAIgCo?AE_B&m>1JA)lApI+hRabV+n&C5U{LWZ4p=(#b zKc8U)_slR#J>SkSc6>L(cxyKS1eSUd1bjh2T#|Z8y53k-(X|_%W|FLzBwU5wv5_R3 z2zW&TUM1i)0{-p~Z^(hyE}=#7*Xg{zHD55F_||c`SFieIap2u8HdNOF46}zAqJ3** zn$xqD%yo$ieQUZ&O6E`1pm{6bT75=Kf-UlfW8`Hw!Vojx%*moUgS|0=jYu|aXV{L&b3Z?> zinS^MW(6ns!>?vlWqm)wSe1PodeMTX;9&|8f&j9JZJ;c1>>8Vi~OWt&)^OVb2T@Q0hT=u+(N#Im^7 zJ?yBd<;H`X%&gs2Wt&2uVl|qB)(5h-NH2>_MFSW^WMN;t#d-M*TCMC^p;Ut$&bcP_ zt-Vy&w*{U;`L`bJ{PlE(Feal&1KAOb_eEly9TJ)xP6r|iHJt8I)8+6-uT?|jKsF&{ z7#~VnnM{BGqv0`fCMnW~$CCYO$EQyh<>ZbBh`qyMH;^nk{3_PTP6LKps^Epmg3pwy z*~3rP1wSvjDR}*9y5O^aRB#Up7MqDB|FbeUYwPeAhy-kzgMI5((bTF^8e2~TmYLs? z-(9N2J{L(Hn=}KW%cbaU@1L4P&is+WomD-l9l+8YGa&G%kr3UCq%~wwD>#VD( z)DEd)ba;VO>YQW9ty^DJ%2a6D%IHw3C#3M7s?PDsV-AXBWbeKV}5QKIW zaXu`R99m3bB5f60*esm62)bY_7+?~22Acg2%I@!2f4 zeQR1}r0W!q1SvKZJ7S>4pCVhDeVlumXi9QT*oN?(#izQw{!7|Y*_>~)s%4Q# z`xG;g#+>6|OV)^~mB%JBx+XM(zY%$!YufP``85wBvaEt6FUnGkp9mxH7QdVOS-v%1 zV&hNAmhGA&#rv4@{x|%`FINfvD&9$W1J*}k_l%>&uspGL75goI>!0?>0<0r->D6k) z90>2~rY!;2XsC+bKEPa25b9cGpN}5Om>IBV<%QKsi&@Ac{h?`t>{~GQ)nCj+(#!cs zS_UIZ)T=K;2gcOx{jGgz4akTr>0ER)cw#**&DEs9oC zX4JQ3*m-l0F+Z1|%+&d07hf~a!iflYP$2Q!(K=j^eXnHDRV3v*g1!MCUi_L{PMSm#zO_}}q9 zip4Ww(YH=U>UbH9`quo6fVixuv@p6Dk$ptA3uEp?gweZWg^hZtlh0Un`_wLXwAGP* z_6N@MqB%-j$m4Uud~2!;z?Qo#zBLoY+k{t{rgTm3DN51Y8O*4EUIs*~Nojs@D<-Fp z`8nF-JmbaeBZf^i9%vjU)y#RtYOLF}qi#R-Y|MF+=X`vNDm}hPOK3>(W|BSF=+F8) z2gF(avewYrY{YHcy$9n_ME=(_kvAIQ?F2jX2FjqOCeirW!a+(27EYkvxy}c|rm9u& zSf73SV{F;9Eu8B}^AAr}_cK?ILO;iBAFcEKfqbGkk06LD>tBA(tOI4=8qvkjBT=NY z+C-7ID!FE7vu@p%nC-Ses1z8Fz#Nf^4o++bneQKItQt1g75qP)p{l6R2Z>_xHIFCX z;m)ZlEZ9FS*HI(wVXGAPyWl>17-jB~ZHqxWSZo{jo=okN^(gQy&h9_#Oim7B!%pX? zA}40N*kVR|93?r8L{*a0f#^W?)EVJ@DlKm3)T^>DNc8vF*^jwNew4z_UJ{ON3GZXk z@Hh=(T8GR*@9@CZ12U6O&%V>lYH8aE*QYKV#eTo^53EW11!bvP?^Rij({m&#Mbww8 z{5=$k5CM0VR!>F(3% zCa823r2Ck3#W76Zh?gfdl-(ST?K8#hrYn19j4*DjID)m%cJFZvw_=8O!-AfKW$Nuq zzzpM-%^1EcdZuBRULG^5cbDgELR$)2hOy)D-!cj8piEa+j0jy##*B&!y6`*Ug6#MS z1f*gEI(CAJtsu6NfV##lb^Fzb+1RQ3-Z@H!l}(jYwR3xac_Lk4up6fu&9uI!(cUIJ zsRyzLIbYGbo!l`X%@D5NO9iC)US}Ez9ee9B&MNk$QJP?`SicQ~#&;=o{LIJJWD4k0~AQmZ)(xB6Rw*%4^v@bPcU4*uB8KB<7_)cxH>#T>o0%o*_GIO}!agG0 zDzQv5A}8S&QP#hJ^&z5sAB1FE#)lIaU|HJ7b;bX`{Y%>a*Z(JxdFQ-0{6tviH2+uh zzbii^H@B&mxc|w&r2T*WUx;znIqx5TBCKY;ek9+?wvSV1@S7?xZbXbnHjZ#e@bj>*lp3eyhPNWYUgY`p}^b&|;D z1vA?3j^tAcXGnpvy>goG%h?fHW=3z73nZp>AoPA>aXUtEbTa=bI)9)n*pe^VjCyr5 zP@cDze0wm{E)bnBZi|nWUTgna%wVxn>dzB8vOSat3@y2341*Wh;fvut-a|!F|_1V;Eeirgy7WtvG!6)5+l^; z-|_txJjY$?w_dX*zU7lO$oEcpKUsck;!;4sx+-Q`QyREwqr^6R=r3eYVhX;RQhi3= zs2XEX`R0alKX(lNIq7Ay|ui;EH28bX-<=BG6B9S#&-%Nk+_)r{T*v_iWY1!O2o0 z2Jj!;eD`5^QDQeh<54j|?ULK19`?og&be?YXKvVPUMH8KI$#a_fSoAQ?y3(H)H5UM zFyj(hBjI(NVyRXVXU7`tk1qY5m~a`+kKn@`kr6xnESoTJ|mBkoF%?VS5|!S6GeQx-k}g zj8Lps%*GG1E6T3V%Q2!di}~$QHKtYBj5`gN)`G82t)(u2FdECo!(V-XNBgW5#||}A zSo>L$evD{T|M?P&$CdAM$*@-?%$|>`Y_cc5llt3~fBxnDwUhN=4avBYKo{m+4f0msCF|$B1MR60nD{AuOl8eQsb2fN3^h z9pYl^eTqwI`Cy)1iSAbnxL%!Q(!R3Du0M@h$=cnB6yU>vboZoXuxL-jYDHH4xCM*W#mSmjk`xa1Jv`c>Z+I2MeyMn!Zs`tvAfQ?*^<5<*l2tf_(!Vy#eHp)-djE z6YXZ#IM3*nT@=V_3J#I;3@Imz!+_*VeDX%^H1fvnHhLkt4Tl()V#sg+_aau^}b-GX`$b3Q4bdcMe{ZSBZ8aF$8{vjg zgW0K-_sZDwTbv`=7C}K5J*8qQ)x3p-P#4ejS?0%|2u7fTNmIA0`x_0j9j@QvYMXS7J4l4pzOBAQekqxD5j2(1M?;KB$G5fUc`4Zc$1ehM9!KKtw6%*-V8RIDqtv98D_0zS^7gB3$>2o_Ld~w1 z0WU0|zrlQUEh1PT)eZ8r0Z0F0@FWIH`G-@SzBaK_E@2!H*5&5RR$1|U0j1I(qsOz~ zsaZ#MX(tVp*_5{+9bo#29Ek>h$KXMT%KYm@qw;dqHe@CK*gl#3#QVFd*h;mk5a&C7 z_KB>6%-;83$b3C2S*sHI5OZ3S5y z%0>ly&P>anI&ZjHP7o8rE>9ZvwbdxZIbbF(#lT9;gSX4iSG+k>^F-x?w>s5$WRgCb z+HfLqyGE2dCMy9YMLZRz>K9!$IR%kW6j3Tx;n>FuHx!ZdIh$WQGc)W>G1d2v-`5g zy~8YPHo{L*C$?C(2FmsucS$GX2Di1}-20}P^`00O;Sak8kMi5WLuly`7;NH($NIL= zmppmU)wq-EaKeQ|_Sh$$0@DiY%Ml;98Uy?C#7BP$?8_%>wpsRls3o4GxJbUUuT8kL zy{*H}Jm<7WJO|GM~npPugv5Hm}p?QJULM)?ij9!6n@>F1{3N(#g72gy{Xpsu7QK2&> zv|K`~RcI~0_q588BoWgjf>Ji|?8W-*(4$r8QL!2AjV-l4&mSGa+w(RR`Wtt8i#Jnx z&)r5|kDlb~j@i`%%c!xyU)CJ@1VI>)2UM-ZnwTGRCiiq3tCfOeY-p;Kv5vM0t-zjG zX-2D>#S)*VED`a8SLe^hkc-KY<%hDkudS8GJ@t%Qe4?$ zO-B&O4OT3p%Lt_9<6p_44d=c;Q)+=qoNyYW=Xw&lxI%ud15PJmQ*3YNWRf@?YjH|yYO zor2YFjD6e8PQh|~14wD7;IIl_ExlA?x+iNCy1}$pFaJ^KC4|aE*)gpzU{9|tj?q}b zb8U7?)Z+6D&ioR+HR%ukjaTEnSse41y*>Y^vG%Yp1R$O)Ecl)pklSCt*x7zo?*=t( zSL$qiC@Vplp9>@Qf&xK1ncxD7W;Eg)xQ}x{6riW`EsmQc^gf<)N!ydO<;k=PLN$dz zn8{!uR%wWp8bXpN2;DxUtxl#@5UPCyq9z#(L{LNApdloQf|!=%Vp=k-f>4bn5Hpj( zKoo0;(=>!6Q4pmhD^7WJ?b6H>t5V1(feN-H}KyXBSR;!qB_;my=33 z>P05;%U=p{r4U34qWI-c$vEG6NF&O@Feq+9g_u+lK@`9IDa097_JUe5)2e;;U3G*; zVhc*>*?D5$NbfeMH?w}6-;WM1=Xt?|D(e&HGzxLEB;FMeF+x6K;71O%0*|4kEGxCH zaK1mB(L)y%dNA>kp1)O=&$Z;)Bl5yK4K5X849@kb zxt<|vL=GD_oRp;#vQpS!>Yg(@)Lwp<>f_;>W{n}wk>=4_nV`ZuiO;xr*Vo-XzC)(2;uhND0XN9VH zEScGVZ#uT^RkxpInjD>H+Ib9%4{^T5G&v85_~m-J@HD2ono5&t4l=SO81%ir>>Sfw z=N>A#PbT-LOi8)8azZhJfAJ^(uf^YPfX!H{TE!k+Z8F2qEQ-dSlch3qB99KTnpLJ7 zDZAln<*HwinatVGG3?}~8Zokpus6nV3tFei~yF9R9*VdTU zEb=CMQZ{zq24|IOn@;+n_+c#gH~f@3=V(qON$C9)Cn@`p{Al5MradaBweD$jA}`4O zQDI`VXnY?u4PmGBjqJk(Q3w6_ebuCA433Ec zd3(1fOmAQNZaoVBgo@m)3@94-e3l_?EdT|7&f;J1fvXj%6wCv2SiSag88O7jk{Rs< zr;wIrZ$_{af28z>sAb}}DZwW9J1%Bzc!+0*=ZX+$`eQk(xDJ1i-jdWgb_>4^jsoMQ z;-sWzGM>G}kjB$MU8MS5Sx2hb#Bcppij;O}e|+~*+Sc02(U4Nfdr~NSIUsg!0zj+e zKYuK5(U-fI11NR>QJ4Nt$ch`XA(Ti7@TTXDt47`GBtF z^GH!rKL4O*T0ReDrQ{_=QAiNd#)yZaFXA;YWdsFbJnc-fdZLxJpY4#Q<| zVP9s4bAlUoi>$R%n-;CYgPsJ{crWkI7yGzhEm*uMEDnxO}ur>tj zX*B_R<}?&@rpZ>m-mqi~f21shTU9ApRzi&Jza}N5MK_uMr|X2dO6ev(jPKUrMujQZe`!#%28l!%DkOCOCcZ zbSto|zvke$NkZ@AQ7wNIX{(bE90-roi3+HAAr&vu5-cE9kxC`?RHgNiD)&|0wYOBP zj}+3~>4`&3=+ksD*tg9Rft>=%tW;U~&WE&dqL);2D?T`qRH1EnY9+bUt~Qxm)lQj( zQoEXDFpIKB1*NC+poWkns&>S0@|S&QM0Qdck?c(zZRZ5ab{dgU7z*4*(3|pVS5_7wa-13# zMY7&YTp+6vrjz7>>UD$*Mo*PmZSd46=FWVBlGNrtn>Fl5edWwh%_i@to{g z!G3pkTV>t$I#s3`etTg}m3`ARw$x`v!mE?|-?yYk)qV43Vtnq@7a z-CT%8o<>A&qa;p(ioYkDf2oTq2%kaoYp#4OIF+MfcJ}5sxF?A*=g<3u8QCYyjS*|w z#jJsHKZhTo*sK*Ej4c`)HDATEBU zuw%XI4=>2`ESQP5_MXH|EatTcc}`E3&<$gKSHrkdAUZi6E(X z{hz@XWild9;zRx7^5!*kM(V2+s$JE-=-oCqzR*->N zPWIHj{Ox$0hsZA7B092wNt{CkM!m5`qTx)4{(Qf@03&&hYFZZ(uw*IuOlvGRew4YB zoa(F{90u@gS=;zLc4U)tlRYw-jxnN?oCumTBU+(Atqj~%E?vAlU&V^O;&qOJt$@Wg zaq5zm5=<3p#dW8-r^x*zdHovQ`Eyp~dZPP#J`>&F*=l5CH_<3v(jfjN9q+7gBUYr= zGblx|qXvq%<$C&)T}O8ohM(fnl_jQSy@ zlP4_MtSoyoxMZ9?`E?p=WU^B8KJvM@+Jf)-*-x*}R?>S|v%e*HqG^wT{mlzj7smo+ zlh;%7hp3Z!5}>Rx^hM(LYIh+PywB~2fwHaK23x08t|IOH2>Uqv1tzTbbGX!>lG&Ov zlQts(E(xer+|+7y%Cee@`!?O>noA?aTq&+6EE58E(^|xQZmkpP z=NR?OQ(%>s`t9s)sHjo@1pzOCf-bfdZx*9kz4OP2{EjenfsD>6r;btCfakzb2H5+F zbAFDtnc-Tw&>+uQFdC`*=Qi8?@{oD$G#;;Kt}<)%Ts19yIO;2TQ*24X#|(ICC9MatZ0BNrrM6Lsdb~ z9!05TKzm)CH@=e+^(&56i9u2?1w2au+I&qs2H-8MmvrAN=|kVU@LO3dCLRG`6y`OF6VTL<#jp5P(Niah_)4S zb|EU&RJm2KaCa&e}?SZJAwp49ZWvZ{qNVCSAygh1K=&KHG?1@_$ z#&=SMDr=wfpgL7$PtKiX)edaZ{+|-Ri`PH2@4t1hU(|KeZ#m0m7U76b9fzXMx1Wdx zN48LFe|W8&?V-2W^{ouKG#O<2;p<+0o-jvA<@!sP(8;E~jPp;`rYD-= z2F5(W*vqe&Kyf)F;igs0RfmCaP$njaGhKTZqD;5#>9mr8@&BzfdiTkh$} zbw){arJLydG3uWqsBV5U%)W$A=DvWGE+|YhSTwvo=TO@}C^XFs>It$M`qz-hEux4bf+N(~ znN^fHYGqd3Ksyv~e<4+sbqY#&xzwbEmX+{GfCRcA#pG8ki9+kD$`<5@8stb@?Fq>V zJY4K`9wC=rnB*t=2#iI5;yf}+3bIaFEkaM~M9T6~wUHM;d>|seK(60x65bg8!$UNG1+n9YPT zn&>2Gf67SXq+Arup320q-MCi`J2Bp3n5WnbH01}%-ZbjJB2A!-WA#rYF*B7}wjs1L zaibJTK_B&#f-aFncAv|V1&xMIFX(S@Sx-?@;LI;<*^UdUY^e# z#O1IlHGl_M3^8uETM=^Nuq7z#tMt(LM+i7zm#km`?zflK2`^~p)m)T#r5D562m~(! z`&Cl1+G8o+()JGqDrX2WBAW=Cke;}llm@JrG(Os?u2l!HXTMHN)}i`Iv$U9m>a9u0 zb~fX0eFf6cK93!bqW4EJev2nyH8MZ*=n{=;+LksZ8bb-ceL%UhAnAb?iz1m$7a zo%xBb>Uet+=Q+c(r53kSNvXwSq5yK`LRaBtf~i7iPGTV?o|!E1jI5$K=uhwS;@q|gd+Ub`>-vS*9_*R^tb)ZqXHbbV!*U<-6QR^6w7rAaS_Jb z1XmDO)N+o_;_Dr*0ytxsN|fB4X*@rqr$(b*hHqG3t5}eknYSlit#}sEq~8He8cAxy zZ>aaU)1_bC3!hj&_oBI|k#mbopu#^Jqf{Fkn0vlA;OBO}Y5TBYliJN)K1mWC?r_Dx znf9gDjo%Tb#^JA$8h#NmqT%)P1w}5W8ucsiCQS<&-r04PK2U;UCeBmZ%$0?SD_D}q zLwXm9_O#m~k|FelFnf**9g)Wokc_jB=XG4UMC3Kk&VEq{F`_~|9iID*Txb4|45;^% zB5h}bLhhOshw-WOf? zH?4gWDU+g*I>&oRZJR1rl1FZ%G+^W~uktQtt1>1wr`r(8(Q2e?Zf1+#pZgNcC-N6l zQzXfRNJBWA;3QG#Y>z93f>VmO>xPKPUFbx=_FPWi1W80w)w}0vhz7)Yh0r9EQc0#m zV&b*@IIpF}#lIy45iLb2b-(*uM06YFri#oaN#d#Y{Tk_e+-LfhZ2MI<%E#=|w!qv% z#;+?d%{JZb+V>>^c0Hs$UK9Ct=|#1?ig-<=cbM;Gv{NcK-sN&=<<8LX3U!Mt-+d0qndhh{ zLj;35@dixjR4E%YM2h~4vlQgc>uvSDS0xjfaox+fL%k91Plx*Qc44{>D!q{+lV(G_ zo2rnyudB76AzuxQX^A#C-@uEG4()Pw(j;P>+1^LhUE$KI=#A{=%&4g-mC3`%4U|m+BRi>rjo^15F-K&y^+`H zNLQP#+Ni39QxgnV7HN3Ps+vPv;-8~;?dCwc{-wUJ%bgr^XrC#FgI5GH$zvyv$njfm zW0K}e;86(cWfmz~u_w#*j!UtyhL)U0tZ7t!po~j>H6s z2n6KT6v&GLat&6<$cVp4U=seBP%@vjP??0-j`+$hzMfwQFbk z%YFzR>)r;Q*x(HKl|*mq{avYx+}f5Aw?4&-ddBuqw&flN;)sdVf%=9<$sM`t2OIA zj&z+ZA9gIC(?ix2we*b8*`f&Hg|j@tAx<~ZJ^PkfJkIr7R^yanHSsjpMsf?cJSaM< zRums~VH|cZ0`%(&>j~Z~<~|?f@-K%Jva)JeBm;Y>(wy$SQ|)_=C2(K2g#*ny<`u|t zJ#<{u%(8N?lE`T8jpA6xH!7`1l*uE|w#Um!tBr$lPVLc$&tMB(`-AjXa@NZTS!Nc6 z9+b%EbYw%~Zs8}n-+RdR{=iNT1MsE(I~M5TFXW<^<^5DPfTFoyi(?<(xK20|oabpd z9!OBD-yZn?!i6(FI3&Z*Y=RMHf8rKv^DWwYJU~^BX(!| zP9<2QexnRK2sT=B1_J@&|1;%FFL{*|j7y6ilmvF4a@O}GIzbXq`m-vw_BMh}(n0c? z-G_DPRixj^YM#hOw(lhUd>u0u<90rMVjbt+gm1$fm80|@c0tk1XP}2|T%nham!DuM z(&YS3G$1vmJpjcPv~K@Y=mHhG*QuotI@CmUA6u-+C2Z#COB5HX^5^JfHyB-(J@P*}7GY_m6 z&tN|BfKQCJ>G8t^@LOZv}@wUD%f&~!}Yvix=8Tn%? zKFG9rDUK$Hk(y1Bzn=uoG_%Y7CvqwtYUNX;g6A=zKO5a*A80$SY22 z^E|<~Y3y;RT0$oM8`zj;1oErfh3gNBAf4krAo4g;ea&?)()d$ph&=SZq|xK=f5zYC z!rxhG{P8eBR%o#Br~-vcVO$uMhuDT}n$osQv-%25{2rzhtLw4lQ>>n^S)Bzpiq#6u z>TgqNV0FC9YN|i`#Uk4sV84OKNJ{^`SdS60o?=F;>0OQ3+=$1QqvY3wSpo{}xp#aa2Me;LYkQAW?4oIvEi+iP%wXBF zQht`V?`?bUV)M%6yR;}BPfOKlN+sIi-bHwaY41`%(P6D5oZijj88f}dN;9jmZI|Dk%rh-^pQFjGY`jB`#KYTiw8p4kq_X~v z%g1erphAn(6BMx7khx(w58vm=cYWnK@#-ArM9xaUL2;-fzp3t6kyw2L7vc_RgmB}gRD0H#1;om|$&5n#K z(mV|jQxNyK5VGa53t z;=FlwC-D%@cN=lw(P0kRZSv76mU|E_rCl_%e7`J{ue|>dyGl1<9}Amt%eu- z=dBeP5dJRysFq6&FM7R1@;@o{ByJ=A2X)1|o=T&ay5c7xe~w8Ao>k4R zXGx3ed0CE|Bmk08JehPG55soLa!=6PANAA{={2$djUQPgKjoaMS5uTMBlT7y%81r-uPPkt z;&&k{L&8f)J8AK{t8dh4ELc2@n;~A(r7gZXz}Ka zR%3wD%~8CNLG_C(c}#qDQ6A@|Q2^tYrDxO9ce5$gG?Lk_l5EAPY^SDY(+%ThQ<}N; z9k;X@lI`qNw%rUs&T1l8pF^19XA&tiEB_#picW(qk&Vd1h)cu@X4+-$+3IzQ%|6$Cs<@p9g{&MXpS*=u zCiCtfCB{0(;jG?kC~iZ;Oxs(ea7qK#5ILhgS>v3nadI`z@^qZ_Zvk)~j3{v+p+8}U zA)z`974}oE!Omkb$8!-1S8b+;`p8z=9UB|qq z3(BrP$eoH`N+gekR+a4wePLRmW`DG@Nai726F0`m*F4tJYH?NBk~kq*UZohhliG6| z^%Eh++LI4*3YXyeheX*`*ncCr$F|vstfs~Ro>^6!J-)j61-#qnZ5pudHt{+5ICRW2 zhmOw+Jwv8^maDvX0tkHj+k#$`TOarP>`;NVyV2_;r`?XWh#78Id5} zfR}3&7!grMj*ny5Sgnl(Mm>W)tum*GiPmgwESJ5t@IF4N#bS?(M;t*iD)O>N!+7zW zvTuyY=>WwgE`7n{2^2R6xa?wm&M>-&#l2a4K+aW*51EI*&TA!2-n3T#4eHNwBofEf z=jZDFg44{*wzGEfVq*?A6 z5e}o<5+}_dqo&@dt9eZ$>>jyDRE>#1~o zHv`u0uk00leJX&RHzwNSZz_q!@ix+%vJA~% z{wIRCEO-rV7MEkKbag0a;QokbSQ`?9oVO@Ojdx*GKGna*+7$zNNzcX{)$rS;;n{MO z)t@|xJ9JcD=zXVpi;UB?YeRhNt+JWNc~2f2zI`CNSpT$2Kc9p1f0{Pz*eQ0Hr`h8# zr^NQ_g13T`sxJ2))8j7Faasgy>qJ8!;PD)UGVY-f zZ2Z093`Lz#ikCuv*S9ylkI1B=wyTfd$5g;INblWlkh~}+TC$b9HZ)m`nXO1l?)3JS z$)caG{En2HqiRc(w}y`-BH>k(+C)uzVFG)z9bW-+j0+-Lplw0ULpYClC9wuxzCV~` zZ*V&wEB>D1LyyeyTM>J^INb9R*$L(C)6hTMoml5&VH#Gq z%J~ZzfbL$`R5M(Oe%@;Q3bcBA?^U#29A~4h8UD z727*9mHGs!=_!)pT*5y(;G*>DN4VM{gDQE`>y06q=MxqFaK+A-pSBc)WdEC2&$wF(O_j?Dl};{00&b)h81d@c!7@45zp9Pd$QoR>Q+P|Z82x+} zsfUcVdA}B=nZbJO{+R0tqpGq(czUO}#HepB@Iui-K9DeZ12MxdVfL9}6z*gN(>lXA zx@5GXCw)d3ucn>!Ixb&Y==0VdWAcai-^Bms9-{_#@W*Ve{H8!SSllBIluBbVyPw9S zee%QiJ_?&i+(gEG_yOv}GOz}BFs9d_tLpes>pNrdMdT(KA0-(yeg6~^RO3H*YJOnwE=*WzIjTKG4q(PpR1DXDdjqdRk@r|mUD(G_9Bintp`OR=u26qI-`>3GkJZMzV%UfxL~U5bH|`v+%X|Q zdR&}ofxUxDgxM=9HFAoniEph;;!@$r5E3%LEpxBe50x4vb<&;>2WnShJ)MZ#O{8@m zb`fc(URpLg2vJzaXsqQf*4NS;Nxg30QMpB7{VNBou`X7fV5ueR{Yk6?#KYGL7wh*L zYXxi*yjDcvvUaM1dz<9W!6sGNh%~7n%F@>HB@wrgL@(3bjSIFKL?Z51!xTiM_AH*2 z1}E_E^o~kuS<^_DDkL_woAHjsz;g|qsIbM|ws5yGCN&bdR&!7zde2iWnq8SDCc+j4 zRnQ_Lzll<@`I%G0&&XN)jIFJ(|MCp7#IWSm&E?dXJLM>`Y{B@9(>8&hTZu`u$GEJS^!9Sn zQW+{I73`(n)Ry!w6P)6Wt1Xeb%oCjEyJKg*r8;cLnzoj^G-mm$q zd54s2X9*jH@8PNv@&8l&xNM0{`Wys?yTNddCxMx{#XnVWh3W6@GrBYqUMBM*kqyZc5`5Plda1KO*OMxLc*KG@^Tx*7H-thnxnt z8jI@{BQi6I*h&x8zK~`h_Le+?1+FI z{9n6aACm49_(3oegdbR;O=`XsnC0y-v?fe2pCF7$Z-_u}4!lh7osiJ-c&?yXQ$6_eaaIZG>}cmE%8 zX98wbarAuOs8J9j^ZowSeeMD#=KbF9c|M+px##p!Rb5?O zU0vN>XBZR@4M_ir-_6wg#xZ#d!}|GyP1q)gS!F`ZCrZCj;6B{gUd<4 zsa$$T!X=cAe%6UtaP54xtu(DkK_E2U0K(>fD%s@7yXkd9rg1_-*)c!}`uN(LFrHOg z>P)3u_*4C4Fn*4-Sxe3!E5|?^n3=vGrBa!6O}=oA$4@08bws%788At}$aIz^qHkRT zJnb;n7$%RlhN7Ju#(2XEl;c(cMH?LxYHU{K-SeR4j;ZmnJ2nS zl~-h*=`LNKt*B3C8oEo#`{_pCE$v#(pYrN#ZTDUU zf2-4P6D_IesM{ElqWK0?5GwzobVPxFQIpWw6!iAe+D~MZE&Y=IWIyfX1icHd_1IbB zBHjhx;62XUObyRdc-Gqqd?ET2HVicfyiLl^`z{M2SWG4B$xy{ttGL{cx#ILjp|k$3 zsCdVX6n{s>Z!IVu4F-omLL6Kg)%c!jyr&xaR&28ACK^2JPQ6$0?u9bhbhnZ(E+x5- zianz*wzgiIeCAgD@{OU1{AwO2fL3Ypncv#mI%V9>qZV5!Z!Qa*!le0VPm(#HO@JskpJ?_V&{N}b{)>@XFy*~;56`vcsjhKHz z77OaZwAInit1PKF=J-(2THJLfE2**n9f5vIUR{tz7rH~D*VAX((<+Q|zP4G#SYi~6=T}_X{bcRqn28&X;sycc>5q+W9SqV@#^6|5lWe+; z=Fa+Da;I3exdmF?_bRi;uo*DPIxkZ(nZVz+CgYqF%QcQLd>Ib^OkRM^v0wHAc-u#6 zt$=^=p)qVGbAfhRCgb(@;yqPp{>D^N@QyJ&T0V!_zCI3SHXeV!+?vxzt%?s^4AjLA zDge&_U^ogW^h$Uczrn~Rm7czaXEwuhOh47wC|9<+=))=eW}7UtfR&Z1lWnrX1<6Oc zWUE||ysst4KGX2EMvjM^;ES2o>+y6)aE0=0V*@OUXFuZ70G5F_EfZy}bKPW&V!g^% zLDf%UFZR$vyvOtruw8F=nD%^@PLVBXZ@`GMS+%1#`#%6A89SOr6IZoRz#I|$uHpa7 z;V8p=_>y?`VLizf(x1irk(HY$8?h}Z!8yVSN>Ne_T+WIdhE3rhU=GX(Ef^*&WJ(;E zy{aW#$meVe#)(oX_mdlLkvbb zNE^&(56{a%x^F8;M|nu}8z!8sUV|Rg6_ae*t7{2=;%dJi&pznE7nc4S38A6JR$qg* z(1h}L!k^{vPV+TMUTEDF%%fiT`&@x{3kzU72M;;8>%zt4_%6X6bq=!yKvr9~taa5_ z#~WEQph{8L=stDCYcwf%Gtcaudn>*U2L*8Y-%(jBq)RT<9(L~d@pT3zR+p=Ig;jh%(nOt9Z<*>Hsd{py#(G)dUO|0} zDe?vsqnS@*TWW|TLTs3eN3c0|8Qg<6rTBFQP@f_Nx}j~xwz|KSG@Zt2_-KEn8%%<1FXZaGAAG07V{~CqGK2Vj_=< zkig?49!I*=$vIy!$I)syK-M8X?y%hj`T0{D_tSB-%gS=c(NdXvN2Ar+-l@)BX{XXI z0|=&)b}wI8qYeSFmK`gY<;|E{&=%e=Iyw4UOL%Ocr(YnCvsp}kSozrta8V8?yo-*j zVTW)6x?gN}WHz4Geh|arB-zqtx1z{mi%_ndJ|Zig{RY6HjyFV5QrV7@0*EmBI5NX! zK!vw9sL#Bos!vd<6<26cNzT{Znr}%5*AjQ0?9z_n7`qP(xPH9uMo26>?4PdD+38|N z@ak$Bu12q6M5$NC#E4Ymc?at&mqe(1yRDT4+zbKkRY~!=DfI)&MA;o=TnzQ_{$Bf{dLig@*Ndoqo?3< zB(@Ou$Unf?Tl^Y2a{zF}$?FVh|GlVDo%z^q=eb+7hY68%&=r&@SS6fc1dORC>|r9+ z_l&N51>RV6t2xK{LXhrDE5=G@zh~X0C(3bjE|p;{$S|@`GFgLfh9uu$z5~cH++1_x zX+<3k_u!9KCf(>F7egSP?xKt{FE7S_NXKEn^gKG4Wl2wAd(`=be)PeB~RodAX;zRNQV5dTsc>-g61 zr?U6zJ(&HZAw~sBAUGVu62@0iCUJT!JCV*)OSEGv-lGqCz0u zbyFSJ0$$>BV=&$rwhHXB+pu&sSo|k=lz*Aa7k9Eo0enGvCGNGH)aHso`M``5W)_hs z9Zm*Nt#?$7IQpCLg&0ws&+AGQ!?wD8_-vDDtgln-vc#VC_R!P}uCT|SE3wTS~={~HvdSEp7Q`b-5nX(z{jNn%evLX$X++t8|z5V9j zoR#zz_=2NV#;IFBIFNKVh|mS;e|~MlBDhdZW#!M&d+e}=ZxAp|1m>t%A0(BVjV)fU zpZ?uG=BM8&o#W|gOi-MIoIyGw#?;2U4n(H1U7q=bN4G)P8`9$G1Iq3a!TplC!wQS=JL!1Cvl~~aR^`j7i#IDuQ?P>?=yYPk z5{KWrSF-e!B>67*AkV30&fS9QCrDLyd|-Ih+B;1`w`?atir;cSZ^`NH%@SwsqCPNLv9Jy0oz)!yD0v00Zm63Gv)}YJID#@ev-5;t{;r^6v>@`s?wRf zlQjx2o=2#09BkE@e^vHfc+>CsZQWb+&!ehLEhDc{;jbY}^B*jxJANytfOW@uXkZlg zB^{MQFa%>qN8-@f?(b78RKB8~s7z$^Ude<`co}B!ib?oF=kR@rjmuMwN0)P`XA-0^ z1{MC`e9m>i->p0ES--Y6KN=^?rOd+Tbo7aueRUwrfN(#U6|gV5>epUv2$ec)EIZg zVDw-&&S!|;6MNm-}CXtYt)^7!ZQ;mmF0jACs+#9 zYf`$Wk`dH)!BUd*RHsi>h86)Pf2)ErvNc?9 z({M%K`reFaxI#4OJT*6*yoDptsv|o6q9CJoy9y?664*zuQB29D@6i+8dvS58u)(LF zM!J`?HrB%7XZ+bpDWx{94zH66&Bji9L%0TvVEM>2(Uu4=B|SNN85~bG?~3e)I{}xz z!Mqv9D}F~Q11wvaCP;kF-oY!-he8*8TcOr6az<>EBRBAndV&a7WkMr4Ia_CjD>JJ& z=NV7`i(Q6LTMcN3)(=UyfKgutM;Yt2!mcJ2>gng$yP|n1)$;Wp3 zUTd}FolzTa&=SM7HfSb0ypDn(m|&p#ci;ztfy#U$-b0_{NRzNpx}Z<#-!P5)2YL@R%KE?eK9C^!7fs@i?dzoni?S!C zkip@zeQCw-UllqzjNg4$#aCbp)RHd*kzO4S=I|+MYGX>fO*OGcQNzJx%7yQ4GDfz+ zNXI@2T3hcgZ3d~R4?9DXla*w1cM~fpcaj+n2PU0;H#Ec>UegNYMz#p z-n=d{IO7ekSeCQSu^?6YGm@BfvL^Gb`)Kri06->4Y)t7>6ZA=XFlQJZd>jIm1t4>=pq#IZvhD1Q-T9~EdUd+e`tXk*EJ{2;9h9|Y(~fX@88 zTGrVAw=e3aq=ES_xO$vvJ|NW@BLm1v>bY~6!4 zN@{jQA*KqX8I#SMffhc3o^S4}CtZX9hnh>3P|@soHE}u4J*$28?P<~vqbW`mcpV`< z=S3<~3E_rFT~MK?_{$M747se0^4tstfT+eqYGBj`uTQ20OdtoaR$23sT4QUKo{zb; z%0xOk7*82*i$t@w!f`oegX==5;^|{hY2p4(uPt{?n?dc|upev7aS&k4rx&psQ>=#l zD#-KqQ}Stwx>2oe@wy{i$XreO*)CmXXZm*}IsW8|xz_upMueJ^A)dYy$l*i$xn$zh zkJ{QUYi(;ghX1egztDeX@gIuLch_EQ0rkdyZD+ez)^_4sc7!_MBiflc8~G^k%6R4C z)Wv+Z&WE@d`}KA@|NZrrx^Be>wmHJRq9~>HIR!-sUt)z5+`bIKqCfW6+=Ho9E5Y{X zu^-kSsEHEI3~rlY|xXgYd+M-^-f z4!+N!?*(i&3f+m_pO9#(b}6M~Rk-c;Urf%O(_Rn!Wy3xE;YIL2M~lT99`x`RU}UIy z1AxzOV}jpc=Lr5IMez3(eA(M-!Ls0I5&V)O_`fswbsqjm2VWbP{!HpLQjGZPi-0%N zY0b<99(Y*9EwwG@U;`Wk zoW1btGb2<9tCS}xBF7!T;y9B#2sUMu5mxg~?jZ4^bbVg1#`{OkwSC5a&QIE2s?OWd zL_00V@y{C0SRUR2$a_7ZX*D-K;f>Qp;joeF7()a(6%$FZLt1dNVq&m6t&kTiJ6`Im zwZ!flWmBCM0|47*u>vZ}s=R$(ZBW&(|Mkyt8)3C#x=z!MdR3OYhoiWAxK6ixF*O@> zq|6Rz6*S!rCy+i}WYuv2cn7{H>u&->O*QllyVv!Coxs(>_EwtrF-_wj;Nj~y(MVHx z>iHw)cL=wW!gZZ*=oFmz2PKqSf{EOkEpe~#0`GI)M^5CAohEa<(sAD! z5b8+Zu?|V>U(EL)F`Zr4^M=EMx9>J2mJlH`SO9l-a%JXR4Q9y^z~jV34b8oGBt!LPVnx zrgBc-4z=Ates%RgXF+wwRL6%IE776NpH~}Cbx2#o$R$4Iv!HrT~Ct>9VV44fAsGNgB*Nc1h~c*AbK zg7@iNMd#B6MoCZ$_E{I8$|VL3qf|1pAiA1x{bFgvOGuQ@h$Uv-WVZFDZtXLgYCa=& z4Oaw*{L$8YVlIKth=<>B%ubG4k9-3{Ve73^j3|pv*=c(k*suR!uwevfgv8VPkQP?* z2lrQ9X?j^5pVg+xMClBBc7xi?bh%y4k>w_hZ_ZV!%{tbU4#<@`JnTNuUW?R{U+u57 z)j^2gPyF`--|6c;WIlFos8%4lKg-Q;#V> zrOZ7?4al=@4PBFO&|3@Cp!HppwmSIJ?~Qd*h^21M{gM=G(5EVrx-MzOMy{R zfM6mBnAaInE&OK+I#-8KxMYA9^jb$JQlr=qXfvHJPM8hO7~@#EU45wG`jNl>5Fh#t z&r_rh8EqW&_O~rKa?VwwMBPM|$Tb@nFyGU#>PtXB)5Ltg!+EO5sgdbEeKnfc&m(LO z9?^Kp;`ffvVw>PY#!9)Fr`{`*V{hub9lBjkrK?E^&ODz28b8+x0P_N7Rm^k0;c82B z2N7A}P+nf)fb6h|muT(oBadh$&tY+=MuWTW@PK=9m~&A@{quWL>o-g}`C2B!R!b5s z?gc-NYMtk5Eu~iL1-U8+W3Idy791UwALq)ys`7{D%9|D8sz4aC-}X`Yzq<0vDW7Z} zjuOG%XT6a(ytbp2=&XU6&)LqZFFNwM7O_!WhlU#&sOBz@r?2Hv%z2Ky@Dl&h%nRB< zXRW<1X^I8b{3Vd%=tqaVhr1e0i-+ui!&ZD1i zXZs)1kfl^xFaqc*a}#Bp<7Qd#^kC2RyN^+KM)v0`b2Si_@27%o!Ia-Q9n#B0&X0wU zNVKu=7NzoR_!`2z3AYgia#jTY)FSxT8vMU{_!SPm8)&1{O^p%o85Ggj(LpPlUFn?S zAS>j`Ftgn~k%4H~Wx2W@kgky{sWCZWaM(*8RxVacLbz?B(u0{`b~(`9MoPwq>BwBq zktIm9+}4ga|vQ-i5fYGw*RnVd^aVZm(DIMTn^B za#pUIY3Po5XG(m39L<5RSvhX)u_{^^d=yoG){+;9oAHL!zUp3^yawsf1r&O^MFLVo zf{d01#wj$}S#hy^gEZk15=}scQHplkfTbm_>25x%@!h6PxN;z=vY)Bk_ZZs_F*wV5Q}$W?=w=W}h`FKVMc+8%U_+PH@$qpCp7N^757BVW~{)08jFRwLgc zL8IV)>|Zs~)8}T=_er!yuA!6(Dl(-CYEi;$~x%paAjR->`y4YX~Qz~!YT_k8k@Sh`F=e7lB(&JLs6QoJ$1UH7=4Txab zZC+qj97Urunm#mryGwY%U&&22UlIvRN5@E&(HOCw3noSo{%H^v%+^#JoELS_I#QWl zt1_dxB{8CFRpzqtaA;@JvRwwjT$K8H%KJJJi~%Kry{n8hx8ne4t>a?{u1 zW;!K3P3X3rzOLL`Ks9|`#FLx8I{4{p5Glcd=TkuZXm#{z`a0S7VZ&NWb26dT^!lJD zG~r9Jl}x5dYkS1Z4iHPL?i!R>zRUPlH-Jf!JA`jLiN8JEgo$%GBH}^bG>7Kh2DtKw z_bJanXVw~6D#Dp;o)~q)4o8rxNP7KBj%bo}jxJNNMM3*pC4cTDarHzzT4s$@kZR(2 zy^3WWp&~sNoTXOh5qqO=Etv1anD>~C%0ED*$2sd6;XKykY-}`~W{QE^NyIV|4drp$ zpj<6sDM0BAK%qQrE0n$RC{u>=%RNQYqF^77QiD(^CC#?$KPJ&y`8P@x54!Rp3=iEpE4L#yJinyl z#ct&Jd*Qkd8<}xjt7PC(%w5N#*qp+KTtHig*Yn4hFP-l6N~s;g3VuyDGbHVW zU(3t^iwMaP5uxRGh!(p7TyFCTM18`uEyH= zv&i01`|TP}YOjMWx7;3gV?wiplT*7CeuraI&C_h)^)?IDX^lr*_uFk_%37&w+aVWp~)oq(%!^SI_IpY*qJij#G$@m5pb2@8zNt zY@!%9l8T}f;OnUWJM{NGWyjiBFl0RP_ZWYY&3AekOOFB(!eWed3i>JaU7opQ+QgHM z9TPz+4|V~FxHr+Yp>Z_7!5|Xp?b_bqK>(G%j*f64@?1H8>&^-v4}#3%h5Z)(aR!Gv*+fXSYKNh07S5=B6-@G*dLz9fg=74!J5>_e_Bs}hIb zWYXb(G6R?b3CuQa0y?bhlgGca$M4J9ECVBf`0Dq#v;zG_Hf4er?rie;odRdimi+e=_Di;{PhA zmT*+_;+D?HqF{uV#EeA)5^&5+$^mwnv=IIuK`gS;Z^MQ{F2{nusZ;VTEpSL}mv5Lg zX@=D;IVft9T^?yMpobPTSD+ zYjsrtzw-XBWhWKW_5K08XG=bRnx7n93&uKrE%tQH5M4Xx=vqV_B;4`KmGN|0!FQ-_ z{dm91u}*h06gQ06K#?Pvg%GJj>iKJXEoNRIF@BRG(KGyVl?6rbjpP!ksLoYnoX&H95;Q@%)5W8ceyUhWD~2vXtv=R9*gf2hJoyr@j<6a{|O z?!p*cWD1)>_>qmc?WdY(k3{)0hJcA!(_{`XdOyGi}F<>oKOmi z7US0IGO~C!2St3sEr1T5y*UyKe5KGUEl?8;H}CnV@h(tP5q@j%hpHE;t_RvXAPqm4 z!!>(af-_KEQ+=Pkv4862&8faG-`FRmSU`3#YI}c2;j{!K$~r1H>&W*XZKva{T0gd9Du zz+5TQrF!O9K`z8wEN$&;)y1UM-_t>Hw+;n_%~AaNIj7WbYL?ngj==Gs=o-#P1W5WV z@*R~w7mWFpth2+-XAmFviyi45jfv4nn{~J>D`;4t)M;igAR!Wy#J!VLrXpVcId5`- zmDh>QuPe{lz=+XOQf%SF?^@+JgNq#2IP52pQnnv6nPfQDj)2Q{^)$i5im$=)A=OK!puWK%I&gK+Lc-SY zEIp(>F1%0XYQqPAIALrCIi!AXH_@cY0itUNqcTjPR9ZD?*o92wy)Sw>&MBM5UY?&z z#nd;0B_}vP%q}}fn9Rl<*nZR4mi7ZPU-7X6YT5=Tzs>{WXpg!$F~zXcA<~t}%uD9u zDC1mPc*ynu>=*mvG%ZY4wUe~04X(YZ(70^){7A}h*v#$`)vuwDjev@Jf1s=c#|L9> zIV6+OHl*I>u*Fu(tqbz0FS=B-)AFgaUFs%-U@gf5O795x;8{q@-RztPZy8b=j{frg zJj-_WuXA2t=v6&IF$~RkTDM#6ife&w-fk~vs&`IhkN4)eKC47S)`$#!GT0gCx~3jp z=Wer80g@M8zstK zDD!}vCIGKj4SvW(WQyKxNYfAq!vhVsZc$&KzXz&?Ju^X~?0ip!v}mcH3QKJo3=R|} zz;%-<9J0w#7{x&N{<;uI88hU$$$GH?EcWV#Cq$Jd+|5{_Y=QpuuC=h%&WbXoVqgAI z!rUu3na|(I%pTZ_cQ%f5H;1ns@m)8E7yME?L`4^OpC-vx39oYX$(`kXR!?k9-bq&2 z#EYNX%I2fegS$wDRP7-0X~Sr`h{#<)lX|Z#I9xNMuc)*&MzZ}ibXoA& z^=cpN`sF+FaAql;Y&yIXExYZYd__}+uGT2ks*P$*E2wp(Y7H%@Wor=OHgvsIv0qei zRYApLRIzJ8Me}UCT2jD4EUFcMH&5j8s`b%dZO zDX1QQ!TITWOOC|_&%PthDccP_c(EWzI>T3R%9hF7`$WV`d$UGcx9|3IYDqS`zh`^V z2jR+2Hje;87()$U5A#gwbq%PRgz6`x1$)Swk`%kKd{`M#3Y28)#B z_SMdt!ZeeMC*fV@`%3At!g2< zzz|tL%TFH`qV8nmTH}oKT!SP&!S)fNu9Rd~{z7YzHrK+h*GNb7S&BERaDS%UT99SW z?_2g~T4Z{d?eaIC-2Mz7HnQUd5Y#UC?0C<>B?6#hXLhFLYom670d>APLX^M85Ugw* zsKB9oQfN+Bz8ap&@`XaV-gMD|JxdzRR>!4uC#<(^l{rTnf~t%eAMu86$ZQ_Z%7QrS z5_*v%AfEndG4h`Y`F6;Z_^>QkA_G-JdQcJaj~{~2z8LuzNRFRtg}f?4{@&h&Ex#&<{3MTjgoZk-*B~!KZW-1Mc_naJgk0BhoIz`T zaRuJ=yXZq%O}euU+Kjg4Ig6b4c(zlCtYYk3k=jDKf`d-6X2um|(;|2_i4^iSn(b(0 zu;Q}dG#gx3UqshIvyBoD6{osuh^lsyyWJE>yQ zR4tfxCsc!SD*fz_IMC!}!ImRjv4$gyP#=&({l(SaBFY7*BS|g@@V8%tdV>~KIn+Ic zx&wpAxVpo+EnDPaEp5o1oqBE>k} z{*x4ULoSe;|AiEnxw(hSU!9D53>>+kF7XU#_}G#;cf-t8d!%}y_IRB_nBof5p2!gm zJ0U?#3bbukQ`+l;@$_A|hrO%~e!+|NpFZRpT*aFpTr>#M5 z?&w_Nb~f+Ych3HDk7l#|Nx%|fhf|VHM9;|_=behzMRZW@$rRuAV8&|UX82;=Da|Y` zz8OAs?A(~xHgF6ZFquVL+n;;EP4PJ1aG>UP7fM5ZjCjMLE8hJdARvA;Sz2Bl#G#{n?HpoH-8!l1@kA0XP8$!GPwlNUBuvbx(Wx6 z(<{h+lLM2mMBe>5vcwdJF5xeBBm^M}Z_D5djy%ST$VV9N3`tauO`0>cF4CmAne_am zxpI<3N0a7LmpjoBS#~C+VA3SbFRjI*U=2mB`~EIixe4=Acw2C)C>3G6w+Q3qIgBTG zjN*Y4)_*rm2S1H4o>zqNCSi1pxioxQn_8kc|u zFTsUAi!Z5QE#18c?+)P2`BsE^ScF-}mQWyGRL2-*EdmF7%q9;sSH0V6qU!ePEghBM zg54@NxFNzlADI6iM3n_OqKYWH&6;l!)pj=i{;x%K+)=)}_NRe%Xpqnx3xkwzcf*m! zOJ+x=#mgmTwbw{Tk9YaC*GH41JGpl)B4VFqvcr4DzUFgHe2Rki4z%KSKF)M>*>ZIB z=7eBu3=UCw$@OiLn!T;)`XKHQ*Nt;?>d)Prs&H0*PG#b$4?l-$!FW%l3ucP+>p0|0 z0!dYO+jNnBS*d?lSgdrjJNz?UZbi<&g~b*Ro0HG zI2ii!iuVYP|3dRyHny`z?}E0z^D7eh^c_6$L0k7QqPQykhmla;4Ed?-ARPCxCAaHQ zbZ34G&X(W?3RGt{wqC@C&GrMT$5eY(F#b}CjvZaoP9L}_ske$dxoT8_jfHv~(%f;1 z-YfC2CYyRtI%3jCGNxSeVFk&r0g< zP1=LTEVboMmtICp|8Bxg1dD$VxIpv>?A1d1(M5*VB3QhNbUSEW$E&y^SUgR>$NfII zL+!UGn?pT*^@8GW)OIHt2LX(30h;2#6OMx@M&6g>!*SruSsP5HMZ`%8FQZ_xd5gGq zfw=xOV0@pQQP4R*+SS@}J8e;ffciUlz-Kj@_UI&AO{(w4+V9V@?;nW`Mzc`}@Atec!_yrUi;0fCms^CN=C z@Kq@IH2y>b9ec!a@}oh_$%mx-z!}<$hA06Qkgk^O^~uZg;>3-byu!di>oy% zs+Eaq;dQ5qJMg&1^-8=UrrfNZ06;CUGa>MUq-V1nkItmJLclr(wN1^rFKn?JVNexu zwEq~K0cvpVqy68;Jab|BKQwxlu@6LWX;!`%^pWYhP(I`8Gx z`O#jTAIGoTVhMY0uYy0wC+tmv*Twy)n>%G zYTo6^rt|fCWU}c({T`ZZx>&ylCYu#MKiPD(-jd0t>-D>9viWvPy^XgV5;Xo{;7B(8 zhE!J~+yS>oRQPu)oTn+=vZLO^jr>H`V!=k0`X_kq0yP+kxlkiWlX=5(Q!IQ^%2tYN z^tPyCGCy#!$%c?+e4vDaOWxTgjVo8_Bl4KxmXNPR)ve4nbf2gy+2g9RBRI%g!$+FS zxp9H+7?sd07+2l8oq`b~TxC`xwo9sIE$(uh4RyOSY_aUPJl~H(w5eL_2(`&wimEq> z{=t0FA-m*AJt46rlnxK}FYS22PvqL?c8}H}K;PEL^uFTJOO~6z&R)>cbSD+~69q!W z)=D;aqw{Ck4veD8B%2S{yKSuWu=i@c+rEUpC(Lj;gM{$B#kOm4CeK`k3Qy-X*?exU z=qK$2YN+MDAD(Kt=jU>d*L#!J*3lf_k$DO>)oF<`McvG=`A5tbPPilvVk8(k@rK0^ zfwk;D`Puv@X31n%Wfd(oFdW#j&BxNiG}%Xw{H zuetY`D*+bvWlF&q{FD@DgDSQ65{Y$1JvVIS*SXik_+~ZAZt^ttuhbO9N05JP(df9y z{NeyQGk?50*|eV0$>wojGaxRSOF7L&=Jzq2^7Iwv}a7_7s)v*E3-+$Gex$4T^M}*me^D zVB4X*Ht(^Ufc;c#+YWLZzw`l66f}ciw_7P zoyL;ooxR+v7n;!?0C4|qUYn0G?vE1p8xTlD|EuxB_!-h9i(%e*B>LEYvIx?`W}3+? zpho}|EuM5W&t0f$d&S#%4Odd!=les{7aF;E98npghhv&=($D_9->ir4HILQLZoH@U(5ZPGKQr;2 zw+nUImh=n>M8|bvrwofR@D=0BWNj3K%i0@HKL$&}JNeU`jeyAA8y@2T-9ch_Hvj;7 zC(pU+Rhh4dgcr^tE0;!@yC~CoEDwKBMeNj~+AF>Mo{QINjBKlqxx_4&658C#igzKN^UCWJ>sdIuPGk z5<5)M@>A!%yAI#|Gs`dSM`r1^@%`0$!V6g`DIw*9ll-|KI#dKP9V}o(5*#4Hh16 z^T3YCBKgb!?o7@Pi;W))GGu~5vqn})!SRdsH8z%1y)gMBuv6O378aC##UQs-4aj#cn!3k%b(`G;|!dk44i%SaCo!44y~2EAE1Z*o4e_!FYgEGVYlXk z_0xm*LwIn*WHcRxWvb7j!UnB@!YBCC+=CJ`m5C1w<~>?(%=;%ZOR$=-X!Kwhd~B|y zqXe`ZpnZ4vo>xy4`fGtaGX{wPSd!gm~=c4!`Wf z0`;#qOP;hKdu$B-3DaO#P;(YPOW?r|8O)APHnVQeg=wFvZz&xPfNMPf=axJ5YLkKx zTgJQPehFA0b~K3UiO6ou^-3PTn~!&6x=v-D3-&l0AelFNxAFZ4hF~gVo#$7#wPntn z*^Q4pO9Op4Sc15g?{(GV^6;&$?X0e%?HT%fV=&jsSocc->}d{HGPjuj(=s=rS2P#q zz6yUU$w>DST7hclgb|Ugo0zrF7X_R8n3$)=+Od~*@${yUaTnuoota&4)}tkg%&sKB z{s1JT<*M;Hz8$PWn+)urqbr?n)o~M ztmkj|F<;kR96Sr^21$MY5;?H7<)eDY_8+5K_^8S*i+of-FEUJ7hN}88RBs)Ej9kHx z@LuZH8=&$z3}ku77&a;~sPDb;*A zD8q61vq66q&qD7c&SXtP-^rR<7e4ci6};LNG{O9qVqVW2^ClzwpMy(0Bc!o@+S9d=pawZjPr%kL%j#_C&8$hn3`YNGe)rYPUaDGAN` za;Iohflg3{K0rMFA(NumDIT2D75lSXWlS|;Zh2iXs1ONC`j zU7kZ5YM>;L4Sub9u%nSt9)v%3RB$I{sBVYZJvLzQOnjK^<1V+$IAGx0;qK2?a9Zd{ zs@YmslvULU`kS84od&nbjdHs2UjAC}D{6-$EW1pR=P3O17HgN^UbaH7pU%GaXLd zv!OT26lbw4=2|Rt4$bR`6a^xH3QPc?PF9r&0@+g>5Z&{C5g`0OcNzaz2KQP;&R+w{ zCZcdZiYA-h=tSd>;^?X$%IPO%v^K^DT!vU@(j$0l-NU{=(HfhV?M7wAzCk}ybjKot3c-7a)yy^uD&ym+Q_+o0YoQ==A1&evN-Fn}vX`q2 z&QgYzgR>BY8ExCuTIJRG$|x~YJY(H8mbQ3y>fcS)%3fkNF(ym`AP?`u+MfELX#T_= zNB??Rce*cjg;!A(QQ-S~Egr}O4+PndLQB{|r{E-j0x);#sjEr&Rs-b*prkTp4yQ78 z9D>&;vZ6ygHx6Uu%ITgpp-uHYdrs$g!=r1(3%)PZ*UHrex#2BV>L7jXa`p!eX7KS@ zwxN*znN^xcB^To9_12y8)lmEe9&y{?*v2=S+S)g|m-$9ZlbKaAYJPYceUW*S7+&&? z?&~a`J+WMT{{FdqMZe^;4ed=zUJ7E$kn6KxDf1~^NCV8VTadiMC7VyTAbFlk9tC>~ zfjnW!e7~Zg=p(E|6eRVWq{m% zA%Ke(Tj?WJt(j`!Tr1n9rU2`tO6p}xrmMPzoG6*#ux2By`>Og)4(r?q>$484-FgP= z{t;HBMwIFsV!>%bIf;UhJD-X{D|o_A7|e5i6%gKo8I8ABrv%JA@~7&g)^?4?>z7a)yeX2S#jwtC;Z|c< zp*r7|h)Q+FF0i$I$x|1R;J)tq5lfk>%tz?YYbu~x%bbgg3AhEcc`ceXEU^g@$UgM| zh)kfv1;QH&Bx~JxKEU`Mld+@T*kR+y?aGA}e00=KL&droz+S;Mr@M{NF*Km)Qr9m= zeAlI}4e+0(QQ>Wtx2;P!vp9|mIBqLtjGov^nM+nUiWf&(*zXPcK_*am)+g2vpXS)W ze3KVHS#;lQu#GbML=pYrtrL`@KDh|^L51)~eKMEzq?T^nv%FTx>W~*OkkB4of5eaL zkfB$rL*AuB)|})!qv`8w&!9fB30dCx5oWF$DAiNY?($BkA+@PxD=rjeved z^IX#bRcPBO^j!LOAci*!tgf-f#u}_%!7Fa3xnVR-De9doMpR|5y-eEf-+ip}EU02( zRTQZ4hnB{k{6JXltjgng((?2mvcjIcI0Clw1f1mwh;2>4cZ6W|C~D?VgQd zpmy4Rt0%Ub3;qYa&jr9Z9E-K9Q{bbT=>?J2jW}`%4Ri#I3^)prEmMq8t8i z6JMS>opN<9+O|$>65zA3s$IKxwz9o~^GI=ZH57!=a=-2#y`B8ml~XGEAT zVLHNe2~&jaF2ZyP6LL&;mxTS9RGh^Z&Ss&ujq1v8&E>}mN-_Mq8{isN-&Q0)7{W$M z5`QHZpZ@H@e101zi+L{l#U5s?*4E$yeU1md0t6GPvZF6!Pk5AkDx*?k@fO!!F7js$ zfI*rZy3vE~U?`{U+6FUX*^81hQIn@i_Kbv;bQA)sa+iyrSxN)SjDbN$?Xj(8u~;8Xm=*SDB4tw&5}7 z83Ni~rv0OLtZct9yqpw-s0_V?8Vp*0$l|r7cIV(N9zsSqu8P)M@)2+*ivNRCV?VCJ zrW!MqKXp&CB>9H_|Kw%(2L22o)fzke!*JKy`P~UkWOR;rPZ+bv$!MZE^3Zk&Y!E+kWS2x8U^>Rc#=QWQ>h_R4*scw z{4wt=i7m3rcLc9E*C3Z(HG?V&LNOd|OazLr=`AfzMkct6efa$NxKAAg6*R|?CaRYj zW^qqVybAn;dVry%C&tj=VJ`_l#d3Tv!&>wRt9e|ab*ai6JO_PEx&>s-Q#&v|j0K~Q zwL#H0Rpc%H5N?A{gA=6gd4>a!2zbFCzHMConxI`QXbzY{IV<2Sf$c2T1!N7y8&JNQ zUyF$XQ(g*AD|2I5}SsI^x~n6zD7Hq)eQsKQ@VOC+Gohv111+rYc1RR|Zw zsND>YH$g2TQcCATM8z8YHAJODHpH`MLk9(LY5bc4M_B<2r2ynaSwEpK01<4@2m+l@ zgECPuLtQFCqY1(neu@SK1ssh8kO%}0s?uWrK+Oit{f&VVPD+JC9a;Ey?)UgfFMCNP zZ>J=<0{*`l-mF}@m4ZE3lRH)<${ta{D;!A4lElkNkP|8XBAF5-{dqH7mqT}~L9q}H z7Ck^{Q-an-(5S~)nEGX;n&L>M39I}jxi zp5!7jLjB={&+B2=3gmw2g^~lhi;$=XizK0kiYN8g4$=`5WqVK%04C&*#c-?v(w=-$ zphoVso>fKxU$q|?@6_i6N6y>43|0T5jmq>1fj1@SFY>2M0g!5N;?O}8ej>=kge0&Z zcPD_ZuM8*{#ISk#BX-l!PJP0pHIl{{(ANOU2(<`0uk-vmoZ+{}kjcJU_SGSu|gq?2<4*)+6s z?rw%(OfW|fzjhlUI3_C4M$_mM*Ti;F6VI}0i)a+(b;M) ze5GK<=&pQiYX;y7;s7L@=afdB5}rwMK0ZI66c!;mJ=?N~XWfunr!R%+s9c}cgGpXu zMRJKH++&H5YIlg;l~Z9*K|+xxsFXDbKC*ORS7 z-E*>eE$NoR!IPG-sE{nQI#6uH-U-GViVawJM4oSncFtHdATz-gVuilGye_vX$BvwG z&U86QV(qYjnXlOZZS4i3)~yiP@~c0CAUu>mvn0I9=JvZg(o(rap1wh`l~uoi9!x?- zWB+q5qIhFT9g~6o0P1=BXrUV_f+2$A{n8I&=A%Yp3rvYCh;Jq@v0#tSjYwz%L$9T9lHUI?YB%DmgCAo%{o^AdL9IZ?UIxCeJed_o$mJeLmhH zms2`IE)uSq7#t@O2<0c=;mWceLiRaM%duW;qJYe*;Y7ymoGOz7$H200dz6B zW}oKP7ekU~4^G|u@l-lplq}JV7W=6x^A=!!3=MLf@{V3*-V9x=T!rTvx{yD^K9-ta zOgY6oDjhS4KVo(1$a?-)9x z4)}ZroJrPpKGq4tdN90T7=-jKC9M{kX`@B2rYgPNYtsk#d<3%%4xeF47!ntG?-OA* zTeiy~!pYqFjX-{_iD`~_yG*zgHf`7@WxS@0C5E3r%r3B%kjCwHa%?eXRbyo(VmBS{ zy6IKw4wdbJNk4S40Nr7v#$E7z!J8{6GFo+i5bDRkA)S0w3l){IW(zX|p#)usK9%d) zSI|{eq%6o0CC&^J+hl5p(U*9_+|&v3cc?yWlPah`=sJB3MX%56mA+;MrJWYm(2~@h zHIf0_*x@&wvY{;Kw|MBWr#$rd|unCpA2AudCon|*w$O7t8(TaW z+A!rfFWplH@Bo{N;pVx+6K&VGmf#B%n)r!bTA&Oi{9FyTomeqX5F#;zNfJP?f1+aR zM31dCJ{H}q;1pVLw_V_wTQ!!Ph5A+t_%9nR%}D}_J*hoPfDfQ392@otc|z=hMS_{- z5%7sy==#u!SbUfQ8!k{+ye)j#`=vvWK({WsSFrgkhOpC)x%#stIOPbY2(5Wu+fEaf z?%GCQ;?jCFF&ud+XSrFUC8zrm2>YxxA~P32^M|4mbAGBS%U)w=v&PmX*P7~PqwuG_ zv6EIF&cxL8mL^D;T^I6|k^gnR(8{x;N?xRdZJ4XtS@Ny#-rKv=_t4MsU{4 z+_Jv&1!@Y(s&Qlur*yJuRmA zzN+WX@bQ#KY!x3pQ8uoR#G1bT6%Aqc%QKDf|hVCAZER7aPGA-SfJJ|*^0%o#o}q*xeEL6 zC)qri63Hf&&KC;*smhj^Y<|cmul*v^W3}d;ggR7&=_htLacz37Q<^@As&cIBoh{ghDFE`q*=&QW!n3lr5 z)q_dfdb6OEw9E>u+lS7jLSxCDN11gS+!Qy{_G_*4U6;Q{!y?YqJ=}UX5{&hE49wBvbR^muSyKWC$gkX@t0=+7dFE5;C3=GNTe^yN;Qp$tOVD zA}Vii8c>J?0>df0r$;yA$UHj1aAsHCQp(||3kHMQRncE(4q4{^hz|QcuWM#Uk2m4* zGKBS!BuxyZ4r_Hw@b+PaSpP5ZO{TSiSlyCq^Wu1RgHllm&!hFtEQY(956tQVdoa@D z-3nuuKTyHAAbaV*W&EbF-t#=3o$D~iHZu{ZbBkLYtUJ`f-x}{h9b_4tqE_ zhj^k#d{=~+CNDFo5_=rOn>51(mwOuQO^AAqq>dgORb77XUvtF#N6`yAIm~wWj!uwa zorvuNjCl4Ukq04m(&z+7*-9lSP`3Kv?H&$u&v((;R`DJG;Az?Ue?$u-z|Wq}Xbj&W zQm!mO#=#aI5rJ4e2%=$EI1Yj{BU;WWCSja^{qNXernCOc32zZ{8}f5K?xQ{KVyO@> z+`P$yecw4)Q0~}aZ{kbOIZQlyhzdrX75emVrOs=I@WdP?6FnslQq9XJZZn+NIU$J< zcuM*~2?b?ICi2uAwKX+n&Z>;>x3m5Wvgi#nhr_Sk*(TPhM>+D!_Hg7mS&_hKL`Yzs zIK&IgQ)pq~+ZyqkKK(!Og9e8=dn-Dg{i`SV1W$0#%Mm6E8(TZP z-RfB#Z;i#XS9&e9OF<)Lbq${se0H!kOEw$UTX-TRxAA{3#%`$0yq?O&P8_VMlexcw z^@H5p_@lW{+Cl;5+}Ny(`O!g{#@NIk+v6l2D_rVi3d#nx9U@wbZ3+;KxU+}9d*bXa1K*?Q0VS!df|mqIk`Y5COS5QgG`8qo}OMMY-0!UJYR?cg_x! zBT9|zdtdyvK}uu$_MG6tv-vVlx;w2P$ZOr8;L~n8{h@dL0{|bYt^GlB`92)#kTD-# zfoZNALjR`qK&^Ys0iZOjZsnvy``&FqCwjx^xf9%W9{wc0a~6APkf^h7l5p-xWT|)y z)Q-oBAjm67xJf4+_=~3 z8#n0CHF;hTA6Nx9^G9cF(p|xmStyZqZI7q7D8DrpwPIE^q^SkLO9!azJoRrn2?gOk zw81>Kei11wJT5hq+Jvcu;s`Hi+A z;}y(GO>W2PCVYs7*-%+-Ewm9R28VB`e7{%)+~Q6*MXNGjs||1M4_IlOCr}nqT&!&U znsz>UHp#YjGb7S}oFIcNvo~>Mo+0pKZSY%|OxZSb{)_SH7JtzLfkUTJOFE?B-0TQ- zSvL0PDp6g5us;D_1k8dLR&jYh8(Vprib&EY*DI6bib#6A;XYB=*nj8%Wcy_rAr?Gf zeC|Khstjj1tdd~As!gAn6tU|izf+mqS@P9tezwW=44+=^dq&qAM^A~npQC%@-efwY9>H`;;#B^Kjb3s%!CLPt?7Wx2cL*2Ik*FkY83*h3B}pAw zNgC?&^HWu%w@&*FIM|(CcpWssA1D_dOqt~DjYgzdl{nj^z5QryJ<^|7EKUwG)b-Vb z=~9V7i&yVnHr*|=xR^3lOmPwmxL$C}PYLeAnTE)~j2W)+21NoP#1w9u@x8y4$6%3> z)t=5mqN+3NXVKm5X6O$}A+;Es zy@?K5!k^~7ffwqq;Ue=;E0VHJh4sc7o1+{PdM^pP8YN@KJ0|+8sNo#z=P_{KuBHYD z0wT}m^j%~#5Du+`PP^UE(4S_M3GI!_YV5z=DQZH=)C0NH)j;}8@h!-pDcSqXydB;l z{`8BbfIzfmh?YWm*RZIhiB12`JY?o-sHL*w*TCG$MZ_vlSv+ag<8@9e-JQCwnT^zD zO0+hrJLqr(F)Ra0pbxzohp!aOY;1H&KgXpOaiL2c*x2XN6ZKPeCu<4l9>5zN@&2JS z+irevvb7^HnoHEi$EdQ!%b+>NRrJ-SI@jC83=1A z9L$HP<_=VV#JWKh+8y4qU8*rQGik&;qn~)y;$-|DayE2;{uyE~v0O4ocZc@Jtz6kk zjDCnd0-_=JTmd~6pfgv{M7rea3WHYG4SuxyMja7$FQd$!lxbZNoM4#^_DY6%@DYFfj1rBevD>xP?x6kac#5rHDkvcbOHgTR<6#I z^DP!^QjcU~=YnGFamYX{A)c-e_Eb7HB*$w>Ve;(VmR`vznD`l+f_+4yhWRm;^=4|$ zJ6)?T<}11QJ>7=Et@o=pvn8DYTS+kVtnzF*h9nxd)Q z@^g>vkLK!+T|}(;g>7}8RJX^i-@Ym{WIP&U1W2Luz8baC?t&>wok{O;WWkHxU(OWu z!BMYM(zILLiCZ>y+{vnC8m#w9C;pT~{OMKF2LYhxU78> z&4mqGhHa8>0`1ROywHJ}O8T44CzbeuX*VKuYTibO+g@Xi=~fICx27lToIu zNx5{{=NDaDdmFzg!fJ6qLizQ%{IVPN2!2d0vJ?pz68;4iHz$-x;I2lPEfaPP%zT)= zLyMN+fa^qHE*x08g&WNAhV!f{p(SO1dCLehth?bCyAK3dKC5;Y!xL|KioQYEe`U?F z-a$1;0OAe*AgeNaIt#+(6=_{huTk>&>!bwxE{>1Afd}&KtSp1gI6QVcOz%DCn9Z<1 z=PU#r^*IHdTA`cM4)pkajn~s<#VLeb4a6sr#mb9W#PQ+aG2>G^eU+LMc8xbYAP9G* zHqxJOg!l2H^@Nynmee%y7f%v3MTDnM0W4YjpQ{r6_tFxaxNT7b()Qt(Y@Z#JohA;u z30l12O0|m+cB#zgcK;&S)k{Xh;gF{m)mAev)PS(=e2WoqN&J8YD3aTJQ}1OPzf5M{ z=-tBVB7R2;p+Hi-)r1qeEsp>-qbleU_U}m@1NRfQS0uPOw69qIrHqs6)Io(a_ZvED4+Jh9($-=w!&!G zcjr7-lx#eGJWzw%Xi(To@VA1Q+PJ!P7Cm@RQq=~GU_7=ZTAxleZojuA?^nNug%Yd3 zX=6fz{5jUT;6l!2SUOn@E`Wd}uXYdNMsfWb)ysBiJX2uZ#j)3nO6tVc4>Dxv(b)T9 zQl`%b`pHX3dKJ}!r%RQ{VC{v^$bCV6c)iB(sdq zh|G-bgByoVqz61jmD!Fm*ef#~E63iLXcxb=p5+hfc}eTO@dN55&we2Si!1w`o`^R- zrG=92aA$0Xmc#MvlA)su7AN!Q3efIuXr-JqQyAul<;8K~0_UF~qU>x*JblV`ya-C; zX#lRSH=n^e9pmaIx&4{?)(1e$CcVF40aUN%rlWmIv0tnfc=7ZKD6Z`LLcFoUWEfpq z>@q02!L+Y|?emi}JyF^EiE1!VB}Y&3?3Zn;wg;*{^3mr$6AXMg#bqbu%f4x47rDcG zUBm(b`-0SH|Cw$zhGhM+=^8G3F!S1~DgV_et(q1hMZNeS2kZ;~Nng^kF;`<$*RwJW za!Y@PkSvz4H-Cbo5)NZpNBzTtK^t_9l13`2ucHs~3=}y*()$laOl9_1Y{eYPTfr9I z%pcbCrt2dKW&lCIlyz+x>aDJO>#_OSIP&kz6-HM|=jhn5#F%1f(-ut4=cIi5KRrG&W<+Hx^G zp0$E~_C7=WRBSI3sHnn&c_A4l1?=2>2vz0j-&#JMFJDP{0{qv5&k5FisR2DVoWjf|dA}uv=9wv}vG2*o|xkdT@!lK`pvV{gy4cvY#4eR{cN9oK-&p zEWw_X3+t>*tOiD-c9W;^W6@X@S&M{}(iIT)N^wUYQF7DU2w>t$rjUIog5?hGm#Zc* z;m%ppA;kyV8;>q$2uvC~58Z-rtq695FN}Px5enR+@6v3OofpIkgxik}IZs(9k;{76 zV$(NcrrCCVa&{+l+^mWCA(&qdP~)5d98b^K!O91>P%nI(7bb6Wm~`|LfQAm=zaZNu z=mJzya~bXd4MjSDYKUi$vO-SPyV)bWi7cn)X-N*`Gp&#N%HahRaK`xwMx8kj%&M%w zM}~@>M^l#Ql*56pSn@vI8tgOtuB%f9AGs%WI zT)(2}njrAhrf7KW324Ld;)HX1>LDTpgY0V z*sZF$^1g6*G-X{YuH2U;=+5qW6wfeFlRF(LZ1hp@WwyA+6XO=yw#pHmUOtkuce062 zR!>KfumNT45@%fwKwm6;B!}{+---q`Rq=0;;JRTIP>AXeUrys7z_UUyD zqiIJ}|IAW|YF-JZ@Gex2tLa*K#kZpWj#k<_E&V+qP4LG-avrc&++qONNUjtWJW|83^-+LLx*KNm2ZcJ#xfh;f`h#ipHZMqVF#4V{w6$}xd3!bV2)*o* zY?fcFxvyH?*nim3`YG9t<| z)(Y&$Op5&7VW}1s>TbA@%Jlz(eiZm_Fj1z03vE6t*`glyakw;FY(g+$+=Z%*(YvvW zhMnB^xs}}Bs@;v+;S-dt%KqF%B(Gs8Rb_9=1tgbn+La}oJNrTvTE>G2*D02exgsa1 z=`DVOE*4Wumigw#YE@>lQ|)2Ote7tU8fcVG*AJ9d=O~S*uLD7FBLp$Mbt!6~g_}B0 z-E2ei5qx8e2i#-F8To}4*sSXy&ZE2$l#XKe$)iHeEyag|mEPW3$8KSA3-5$q$=NZw zZ|j!Qa5=QirRp7L+d7`p<3e$36r7MJwD*^|LVQ?hc{MTMaW%qR?7x9-r;l&3$P6s4 z%)H97I=IgU$||noGw^yDL!Hv*axDSVwzC6sY^{AB)Vh+)eP%XeP?j2`U6grll!>39 zIH!Lur+%xPgQ6TeF0@rW{%3N z8kpG}oEm6+!ZJTw*Y0EcfqS~(aCA!WprB=z!=57K^MZ`aprTN0m3gJh)W%s9lg=Dn z^MbRYY9*_Vlnm{Z>Q~JNLuY8v+&q6VKLuwuoxsSM?4$$NJdG>4 zFjo>KkdqZ(SVbEs8a#>+Al4@fe{S5GSdZQ@-4}2cg)N{B*S531n{8*Hki!T0^MBZT6Tqm7Y;U}}I|)e$5H`V;Mg~b32>bd} zIu+gPl&NLmHCqCfxzz8Uz)^C9UY7j$?2el5s%=ml>BJ&WP(nTt;U`C%6p} zoe3_O>!|sDr|MMq?VALBGxOf}{@=eF>Q?>gELC-G-Kx4(>C;ai2RpVtj|x0}Jf)tB zRfUEKIUK}>^zY?ZejWa5<>{U%y|wm$uFMo!ZQAsMi$1#IF=nwomoI}rYXledYim!* zfn*1pQ1+y_S+Go@?nMu7>vsC;PQCBlj*hhVIyxRj{2oHb@acGfI)(RX#qxTVye^g3bLI7C@_N3!mdIk4_Tl-Gc~hUB$cUL*3lT3*-6>jm<9k-T0auXXZznY?b0*DK_8qr6@%uh+=yb@Ey- zuQ$l+W_hK*SL_(RMP6@}*I&r%FXgpCUhkCGyXEy>dEF+jP4ar5ygneW+vW9PdEFte zkIL)g^7mGT1QC?q`*H`6rue|P)*Ei(#EqQ%gUjHbs zf0ozxE$?FO7>Xg?L<@G1>dXl{6 z;95bCOKT}cuL?X8qID^yPNq}=rLc`CT4zyeHKoYcd&P~E8cV5%C`BvhidQLh9HsVC zsvo7kqEtGivM}+tevbuUMJ}bjq|_;t`h-&S)z8)zO3{~RTi>G821>n5saq)ZETzcl zQ7gHMt9XM_4^WC6__y9oDf-Gp>#dYJky7=Pno6lFC{;+Qizrn=scK4HOsNV=-At+T zDYb)A#gw8i!?ez))ZZxOqErSht&=JB6H1Mu)Kp5HNU6n?8ceAGrFv89T1ur*>K;mc z1638fDb+@)Pbu{=rFy|kt$(J}FiP#C6uBL5-9xDbl%k(kt0IOT62TO1t7HEKFK6DK&~xf>N_6br`p-qKs0XQtA>) zy-%rIDfKp`9--8$l-ftB=O}fMQglXEk%A3?*6ox!hEn%ZYBHthAfTdvQa4b_OR0^N zs-qOGJ}Yja6n*KWg0?YQ>5C>6uThGA-=gBLl%hXhspx^VcIyI44W$%)wWDG>rKVD< zm{NI^s-hH~c2`_ZsbeVhOG;%^>S0QyQR;b0eTxU8;xCl?oKo$SIzXvjcq?mtk5VU5 z>J3WGq120%Dxp*}rD`elD5Y+o6umiAJV>cKDfKd?wos~#QrA(cKenw}H&ALEr7ob< z>68jl%15bkN?l2*pHb>IN)=IR2c_mx>Rn2mN~v!sg@wPUI03s`ts^NliBe8VEuj<+ zx9|i|3QJ5;aT%p>^YK}5?eXu9z!bf>WB6w|Ley8>Ml`HZIx2omsXtTdNlNXb)GL(Q zL#dA`^)#ivpwtdZ*`d9)2`Q;Mc5%C7$%F)Mg8W$Hzu;qLoL4Z9#yrcX?NXJ|#-+70 zZtwUDYG4lYz=-`(K`|-%3#jxDN%@%v>O4u&ITW|gP)Nt3PT^S0P)BXgsFbdcu3tNs zqwAOMVm{U{7-w@lm}6aT%Zw%R^AYnmbL?ck99PAdtxs(@e5ckY%7cMOaWGgJ&hyrc zUsa>7BK}$6FC7!(86$brH7`^v-0py<%7WE4&%wOs*5C!=N9=d<}Q{;=(R0o`^YCL7to`~P;Jk583-&gGn zhbmFku+t;!easRbZ5RZ z>|0gi3wV9bV7YT-U?fvUIei{)g#yk}AF1~wu$BjFs$<$n(5NKL5Hhw=#0r^>U| z?IR;~Sx|Xp&=Uzet9_wrAB-Mr0;K#^HC4`#ue!<~4*N?heKC!swamBLj|K+=&hqMD zm8vJ|POUe$n;R0Zji<8G9k*moDf&(BbmzQsXK{6n&zV!^EBDk?MsiUhGPi6#JZH|Nv7;u9%^l^;88>$9C?OE_&@-sFUjq$RSV$e11~h&5@w)28H2GU=T#DR1I9v&vDnz9ptqIe^DJ??%t++PibC#4Wuk@FflsGZ;s0Vtq)1T+d1EcKD<^Jk$gdg^J z;hxgqYM;7U)aMnGsZ08nSK(=LR@Vf=>IvZ<;EV)i@i}CE=TDvE#!t!}Gu}xZWBgcP zW&XT8%FK11qWX(->V!NP3!N#Kd!rhYOhXC!e&VC$56eet6#9Op9}U36$p+(5MWNWR zLQJu)0%p@l63gzY5Pss~rKmxz%b_b~pP0s+N?%}kq{2A?cO3UeJ$5>CVyv|ue;DIr zOe!{;@QfqJ?{Hoh6T@_;zuXxJ#(RNjunww@Ku@yQ6M!MmMKGbrjsjcqqwQRSAw+hB z<^I*afHUN&#)K8|Rr3%l#JRre;4J@Ye>gV%cf}><%)%d0@HG) zyQK*!$R_c)4Z0{G_Nda+MFV8#O2yX%+&;|y@(!S^ zLRxi1A{fps>kLvAtoASW2R!_M#?>TP#`$BH7ETP5KYn51kBkUA|9y*!A3coI8c`49 zv5|RH!cB;oywlB)Hy}3l>Ry0>(I3IYh1DMoacZ`UDN%!6Bv|RgWAraNcr#ag_ss{7`kKs8asbfXVr zzNTe1?jO${y6anosKdvZX;z_%#2!M)9`61D?Sifz(C{eJ;=22%Q{CkF(lhz~0P9PJsJ$@hoE*aiF@LCBR!fSwMIc0@wN~?lpH6Vw5o@#FeguQZSCM?+^72uf{ zzzYl3Yq&bS6|}y_037joX@xZ!gD&P!r9-|61p}3}^g1MKQATUoAYQBK%{i_G`$A4^ z!+Cw-aGqEw%Xf~DO&Q^=@L;^H!~(vI)Zm>-y)s}K;4Jcu_VZgqSZyDn=s*zf*EJz} ztpJZGt?^f49||uv^3BDKcj$;8)^WQv1uYV!2Cr&eZ9UQo9_DhAl(SGOajwP-8|_vN zFUuQ_O@eaW-Vwv|umuwy;T(=lFjY_@uP6&*`-!TE<+Zm$xVcsn++*F7#o`LwkTT~? zRY-*P6Ncwu=ORqY5)$$_WoEE+1+0ApcCr~weru|O*yRiRFQ8ql>RPPuRBPxJE1~E- zu19%Iz)SmZ?qIbW@1+&NGI6rER_8j0FL8Pz&f%d`MNObozTPS(Rn5gYxz2#kSBCo) zz<$~C8rrlFD}A+Vg4M{Zs=>wqIzkw`sR6vPs-{6E;#nz;5|ar#bB13~=9H_(Tq~b% zt;ZWdm!dwT3rXNV%~OVshga_MO3!lamtd_qvvv+Q%&HA<^IXB0GV1BL4K-f5k?iKj z!7a!N?y{g4WL(i}WQKgy+_Ya;$$QU=&yO1fMnsx(d1bH^8;Z!~lqS%gbWJsNNlwKG z!7`bPNN4euCTY=0klgN-YZ9O*fbOE6TS-<`i{AoY1Y1Y6kty$mlRK2T89&5Jt)!lU zHyCOpQXX`$Do?HKsJPA89l)SahRyeg+z0MjK-MA<42&iv361Jp0l62g>#7DGbn~Dy z-a+%sR>6x1IsrX4SaZ`rhfd=uFUON3pAFs$#wH#ON={up*>%XgW{Y;N3sv`rs*<4L zU#m>Q{XBAQ5}#{qRp6Z~f*8043K(bt5$7%#dO&pWJUV+i{Vy3prRWDhA zCwFu>;-L}M8PkJ18z{@cBbe(PeX0^30W?Al@iDehnV2c)$Rpre8*$e9eU)X`rClE($OasN_5@;C@X z5E`IVpRVmSdo5-J%p3kPU%ZGsff1etMcG2KpqrbOu7+Zi{Wepuy}Hys7hZX`B+`*`uG0EO0+sw}GtvD{B{b%44jlCs~> z;gC=^#6&`t^~*kk+LYEhM@SyIKR!b4Fvxa8)=R@Ejes;$)3g}tGJ=L}e>v^+cTI~>lqrOF!oBzOk19E8N*x4SZUR+b%(vd5Y|_b>Kd9Hy4gS!r7);d z*(TQMV#|OEpC=^O0s;?}54{wN5xF#ovCzs|MHLo+JO?nZa0n@&coTlvY0@uJmC#iR$}-?Wy5)%Qm^2J z4lfqVJ$PoysF-Tsa-1JvO(=KEEmFMJf_=OzX^|IplPc`#=z%YGcipm)Y%}T%YR?}F zq3Q9b2-W2&J}>rU$sHZlXPx=_$(F|g)3IY84l6p&22FbMbft5;u19XBsfw}9`6E?v zrar$mRWX+LU#MbCrgIe&>yeuoTNEY|V%dqN6>PX}?_-G8xO#1@?j>dt9PrYO5m+PV z3=dBqUY0AmKh(#ug`E3%)vq4Y;fv$TxXugCE|>9n-92Vl&sO?ywjhwG3L@t9WxNEn zJRP1lHSDBSX($-RK?RmOm9Z5gR{h;9S-W5ShB50brzL&BS%aAo2NN{8TGyg#IvK8+ zt1x5uah{;hv1x7FwTPNuBf+4v5_1FIUa(9G2Jqe@7k+s6!i0b}(-^KDcb)lfYYoiavb_AQS*y&0!lV?6$r= zQ*2^_5DSn=VSl~)i!w?(5V8cm&8xEPPNW+0kv$VR^F(Uhd|@kGC{jcC1EcK)!oIga z*j&ZJQGb@OZ$C?@_+yUSIR1v? zl$%t0dUHIO;}ba^#qng0T^!HnxR~SfIj-Qin&XQ&zJlX=j&J4oZjK+|_;HS(<@jZe z-{QE1<4-vLlH>0=PQO{Trys}1aeNZTV>zDA@hpxDI9|$eDaVx@ujaUpXMf@gF(Y1ftUJWAp3(YyTAJxUOgu7qqsnM_S+&Rcii+DfwzB`< z!p&SyUH&Y-&)L6FIq6Kejql4mrq_|fK790j{EF#|m@e*6bZx!!cW6$P-`&;NsrY&` z!v>D6(kYLs96b&fTKM`h-DTkmS@;+V>$qN_3IAfO$JvJam7->j=W@NYdOglMA5b|i zj?cI7UBbA5>016u3!l#aq1b9y&Hotd%eFE+s5$;;V;f$%|2KW=|1a6$f0GT8bxB$v zX@R5#k`_o>AZdZ51(Fs>S|DkGqy>@|NLnCifuseJ7D!qkX@R5#k`_o>AZdZ51(Fs> zS|DkGqy>@|NLnCifuseJ7D!qkX@R5#k`_o>AZdZ51(Fs>S|DkGqy>@|NLt|kRSWbT z+F&nPJ3EwJG&__Y8eEjW82>_pL)jrG{*5h~wfMA9ovmn2Xzt?E%>RmJ#{cR3qB9^? zXA3!t$8NNR(peYj8C*0gR9Ku}oL`h5noCUfGufc0y4;1e~t~6!vy^|L7dr$X8$o{JOOj_)#EGGwaDzli} zr=12TFD4zu^h-DZ!$6}@&_aZo@tAex5IdD8liqJz?eF3~?6$B%=SCu~UiU}t> zitd)bc(GXe0@GRKswy#u9P=mUc*0)4-wii&_{jozqw$IQz9-R?Q?xrUBc zJ&8mrdX{wJFGcq%>MU}piCc)f#T6sbw@pOUh_YG|vex2}5vvZE@)j!{l-<@jTeX>p z?Pekypw1zUhpz0N3HMQC)m0ngd3cnSgTjU60m~<=UmqvW@saOWh-@+C1*_o_mNFaS znWxi_gmk5BTb!pLxDeiws-^w6o3o)0zorp)%162%k25UtO1GHkBe*N^>>~UG2AmjC z?w)uqY$d(vA$M;=uIk^!{dPir+T$>uO;RKiJ5a^jc+p%s?oWZ1jzl7{4o)T zwKG+l*Nu9~XI1`=2^i{9o9i7-4RGu1k z-T7r@%3m>&wk43zN8_aJU6ZIYljP$GWTl((o4d%5E8WvAb%AfSuQGmb_A(=RW>Suu z7sETOPd-MosGPSIgB(`z`ycdsX~=Cc<#Ou}a25@?`QZhKh_TI-OUBjt?Uww-0ySEjeY=%F^Cn3=ow$va@#uP&Y>SQfwik;XOCO1 zJ&}_Jud{ugl|{aCIZD-~$=kxyR_x9sy%2WOuaRKURaka&9cQxr-yYVNj6w1 zO9C<4wnUnqtugI%MTkGGk6Xz!MNnbQT@d7uy(fV%*Ateb^4^5pd12f#>4%e4y=|e< z%uM+$3Hg}nDf2)=W|7}pL6aSPd=s%Pfrx=jtw}J*bw!A`vaW~u4w)vgjfn)Fsp=DQ z&w^XFU^TgR)sMgyMaMGGt;(Rqi|h&win5r0Owb))A1FdGysLT2Vgm`aX**M5%cr?M z)!4_GAlFbld6Pi1C4X_HpVl&Xpv(jwd-j_13b`Y_&6!wi(vuyleTyky-ogki+@bk^ ziGUHMOir9_DpRlN^21At=S(H;_O1w~l~7%}yc=53bbmKmDFOI7B$f4vgjw*(4*#?u zY)K^0gBzb18#)u?ePUa8L{m+-C-TgrxgbDg#ML~mSlqLTRs`qJ@N&P}Hxs>us@Kd^ zSotjFi;;5oaP9&hemJj_%wD2m8Ejs(xz7j$*97##_BM0S`hKyVcQ}tnA&fVA_OTGi zS#xYXPpeJctJ|!Ma>y^FML+H-6U`lXNdW6K?@C`8T1Px}8LHy+660PF46dvRQT9g8 z*7ti}_-xY>9QW2jk9DvuOu)z)o5UJ)9$JU-7mo`3GgB$sGUQ^uR5}y{-mWmb4wiW* z5X0jt1MWaMqgiFdm;dBUmpJzj!RslNPxM{_RlX{3m2Ax01jCVP{LDk_wEzw(+#=H< z>dN67s<4)3Q24~e53!0=<-AzBJH!vjh1CzS#e65ic|EalB<7}wZ4LPKV<>Vqq_$k# zVz0}pbF|po>m7U3 z8ti-RZ7E=>OKnT7>roFS^(pmsX9<2os@_&_Yp}Q28*JMl8*0dIOKtAaW^1$6jj9{9 z-PZ7w4JD=5_iA(U`}~$_A=2$BA_e|_oFYZEJSoIr#F0ZnWFy{NZcg^vk9~LHg0l$azNzYQa?qY?HVcc?w!ebd1)+u~CW9{e4 z!&v*XTFY4bt@=4*?T_kV#@a8{i;T5jsrMLfXFpT_V66Q-4d|untNkqHG1mT;<}%j) zki3kw|D;P8Yd=W0GuHl)o@A{3AN_%`_Ji~}W9`o<8xBs$p4uN#9%JoKXdYwj52%8% z_6u|+W9{E(8)NO~=LN>vug^g(&+p5<`l#}?KcBIT1^c&|$GC*CSJT;FOf6&WKju1( zH>>-7597j{6@H#^!z~K`Mf2aPusvJVNBf-_%vk%G8N*onm076y+0V>!#`Rm3z71Ob zZiRoL<+myPn3iu;_#MsPr0~a#>+e(eJI30N%b>ohzS^J5IL6w4%Ob|wk4qI}?YCtk zWAUKU{};yEugLg*O22cvqR(gSdPw0Fj2j+S_&QC0MB)1xw=w>Jaftoh_3N+nYyWoz zjKxz*-p^S7lJ*shx9?W;TNyVzr|=HO^}kd2eT~_F-q8b8dG&`BJ&&>LbA`(ow-nMK zBgBP_ONtbJjPdrf6#ko*U#9Sgfl9yj$LA&tmoX*mkLV)C5yqPtuV;K8;~N-1&G9M7c#z{@g~MMGrpPe7RGlnzK!uCjPGLn9OGXzev|PdjQ2Bsl<^_P zPcgO)R_%R`@zIQ5XFQzoTa3ptew*>BjNfHk!1w^;GRB7)uVF0MKjjsS(-=n?r!(Hl zxDVq884qUs6yxI=zsh(xIUPh^~Ow6ez(#@URgGd_;-DU5R%yBJSl zJcsdY#%C~I%($4bm+^UwBaFR_>ll|azK-!q#=l^!{e8a8So`h}&~?SJlb#@Y{E@8eYY+8^Br#`Ui%`L%?xhSL66uVh@fSJCSkFJ=4y;}XU% zFs@+y5#x=oEBS92*E2r$cvapO#?u%#FutDgcE%qvZewgaLCLo>9?e+1p~^d-aXRB| zjI$Yk&3G{5*+Y~*C*v)Qa~OZfcr4>dPQ^c!aV=vP<7XMqWt=%w@fR{aoAFY{cQYx0p7GBZZ((f199%{h{)9j;(*W^(7Q6$v z++h=MUQ_2IHWJOF%LGC~{NyJHCOjT^gCfZ*k&q>v5-Irt6F((MpMHNSV0{{wcB8Ms zt`w3y>C^mLpML*&ko9RybgECwsfqGtI@L$NFFnul8f*CyO5j5gm2ak#yneqr$nqK! ziOLu3;84q(=~Dh8ViKZ5%QM#Ub(Fv-CU2sXyncThFkIaqjkUbB{$@JK>-W8rSYBf- zAEJb*d^4To3+p6VoXqkXYk8+d-b^R?&^jf*nB_Ir@-9V=wcku9`Ry!U#qt_!d8b9* zOeguhEWd%}HP-TN4yAx_fr+0m$?NyqyI5XhqSO7aqXa$_k-V8s^7?)FX_nWR_({Id z(*MnLlGpFgZ?U|_THXmA^dU^;o9QI4-?u+ud5yKawf<&0$?Ny?9w({(r?HmDYnS{G zrt-~nlGpF^PL|hL%NJVY&2*Bl-=r9(v%JPy-er+D(@B0W%NMh}#@)%A=_IfB7lJIW zv6e5fly9b!yxxzvn&mat@>ctq=_IfBFB(~1V=Zqj-%KZYz2C8i|~bLm`EgFfcOlf2#^e2C>W zCVn}8S>{hOo#gd?;_EE0v6gpI0w0Q~d^4Ton{Sn5aZuNvG4adtDS;0~B(M1ilf2%q z?47InkH$X%-avx&@+AoL(eh?G$?N^^ z%`C66mUl|&xV)K8@~#II!^14Ev6e5f$eZaT-@x*Fb^952C$IU5PV#y`{vgY1tmS!n zh_&BLCwaYpf7(w~|Izp+;0;`Nin`OM`H4>Y^#1=r)~B(ScTxf$iV95pgh^hX7dS?# z`e;mac|R$E4@D$zrjxurUl_*n8WTUsHz3eQ%bV%4{6`f1bX`7UEx%onWAZK&o#gfT zMLElBtmW%0@@6{8>+_CZu)M}vK4g(M(@9>RkG#b48f$rHx>7*6z{F3ORXC0rX?!U%bzK#<3P(<=(I?3zvuZb+LG4WIXDNMly zA1!aDle|7J3$eV$TE0FlQQk}^c^99r{fgx^*7Bk3M0qn^me0SB)uPL1tmVfJOO)5= zcZ0_WaT405&+jHN*5`K%8SC>qA7g!fw}!DkzuUxEpWofeSfAfL$XK7>J+`!D#`^qjB4d4i=VGkS@6KSX&+pD=tk3Vt80+)93mNP4 zyQ>)M^SgT(>+`$qjP?25lZ^HG-Sdp~`Q7V`_4(c38SC@A?-}d!yWZoJJ@onAM8^93 zZWd#Gez%CRKEFGUu|B`6WUSBcE@rIH@2+F4&+l$!tk3V780+)9-!Rtacl#LY^Sk#L z>+`!-#`^s3YsUKguE%)QUVVOdJY#)+HK z`Q4R__4(axjP?25y^Qtw-9wD^`Q1~D_4(ZkjP?25n~e4O-G0XU{H~3$KEL~(u|B`c znxO2X&+m?7tk3U8GuG#K(-`aXyVDu#^SdRC_4!?tu|B_hfw4Znvrk0%nHXRB{H{M^ zeSSBRu|B^$pRqo_`vqfte)lG0eSX(xlG3lw??y7#=XbLh>+`$w8SC@AwT$)o-3^TO z`Q5J>>+`$k8SC@A7RLJgZro%coN8#5S2yrUS@H9{0Aqcgw}!Dk&%24SKF{0ESfA&; z%vhi2?Psjd^XyYpdHOuh$ylG~t!Avx^Il@C&+`s2*5`QxrYe2n4VpQGn9Vqy@%4x$5aU9|r~ZeMU&?qB;}XX2 zGOl2pbF$(OF<#4fE#v1I*D*f!6ve-h@fgPSjAt_5!kDaPKF_1q&_0xj=Y&4l2z`3u zcOLgD`_i!&Qr{DeK4&7BahU~QYQa$pzSDxAvf$S(_!A5M#)5mGGUoamZ^5}1JlTTh zSn$s**l)qBE%-VMzRiLgE%^5q{FVi`S+KwjLRQTFeJuC{3m#*^E(;D;=@*@EA(;7=|1 zdkgN1eHZin8D_zgEO?FuFSTHw1&1woodw@u!FOBm!xsFU1;1;-Z5C|LNNnE#3m$2~ zE(=~}!L=5Al?69g@Piiodkg-91%GbA9TwadYj5-Ynqa~6EO@yEZ?NFa7JR=2KV!i! zTkyLU{C5lPuwYsnnd?7XVPvUKo&`^};L|L)*n*c^aFqquSnwqlydLxG0&ZbG;j;pYfj5N<)Z72!67Um)C$@Joa{5E>A+B0Pw& z9pNE_hY@xlJc{rb!s7@}Ap8d5w+OUOcnaZZgl2?Y2+txshwwXu-y=Ma@B+e%2rnVL zjPMG=s|d8N*o*KQ!aju85#B&}6X7j{KOnq~@D9SC5dMttF2Z{Ve?g#i$bN+P5k5fp z2;pOdzakt!Xhrx0;UL1N2%jPR9f9^`4GD5HJBLlsS(4SoM|v6 z=0$_CcAvoz?UH^o;*cE)#53Y;q-L>;3?>ueuK?>Di&G5B?(9#9bGz^+#FRu|LY!&# zB*a;9KSG?5=tYP#6MP6I=4lT?oSW!BNN1Y72XR*1cMxZoJO^=3XTL#;pd7CxdIkZ- z;u0j56Yts785Ni5ThXyR-PPyBe1U)zb4rACCx;;MJbb5^opyAQC%>{B&u8Bs){IW_ zice*my?u~i*KR&QG5hz>ke|u8MtjnCG{AYB^=~Q#m zRKso2(+We2j|^zEI>$hk#VZDK%-#gZi2!9K`oT!Z(S2OG6@!2_XDmbc!XP2(HG`j1 z1*G?j7%8SJ!3hSDDI@OvLgy&21VGx20sFh?l%w58mO5ZwewOIHr>s=zwuA z6)Gq0s7_*&n>vX*IjO^qCu?47RRMRu{ zZ=ExQsg?94Sk{?z+5W65ps^O@m zIxNjWO)@F;(uAZ%XyT5~&7G=6rF2_HwXdwk+f@n6eG&Mw^6D~7Wrw?^kW7I5a&@)< z33WpvsZ}+e%5KOcc?7boC;4XUy3De!NhGzrGFa-V40j<&RBvT4TmzR#oz+SzIRfgM zROT!9)Ko^g(km_3J((1*T=N6+M`R!ko0dHo$<+5>|1<5B7d=|38 zBa9K6C9Yh$GwM_mjNU=K1zT%96FtM{PJE)w>#}Yrb3EY)J&NirLMe5}t8k>k)M`zM zm`fr*WLPy71eK#!u4xh6Fm`d*WVJiDhHiJllNYmir$;tMA(>8(WQ^M70~@1~Y&pG| zQB`Q*kA!rGa!-rhkN#RI!4g88?3JO(9mq(?3uNxlug6@EOxi4T+ z8}P09x2dG@H$*N%-JVh}?-gldV!qLHw{~QS8yl+Cbko=wU$MFi7UdV6zWB&Ii;hg5 zlfSrlX8wW&?lWeebM_)QSavU*T|9TutpB1EvD2Lh9l>1Vj$m%G&FQ|#8EfRLzgyQz z*P_saIgFNSLHId5!&kc|SX~wyn&dk${8Q2$j0wbF`yz{~)tjuU;qub%Z|Hd3d|$N( zPV;_DdnUqV+G;qs3{pofgP1=y)y1k*Nj@{#Hs#$H?5&|5=m~|YgKMRg;$tSPLN5zg z31g8KmJK9B|DdvRPjv*&Xz`?=hx-FzznX1+K(^BZ5m^)b5%upZ26ut6$MZ;?VzM-1 zxRVvBo-5t(P6~_QEpbk;1|xHIb^OkN7!LcYsY_V%F{JrRYa;A>nytUmJ#*2*!g&j3 z%dV}|&#W1LW{pMK0@c#alDRN{sk=a%Wu?0y-wZq^P~?l$R0rby!+o0X0zVvylDz`( z6dbEt7yDbPyRLM*<$6?A*gYXG;+_^ydrZl3rZjx{#freZ5wD0Tn|w9LnZmUJuRj={ zx=pmwI9sWy5ZUQf^}Ob6Y9TtF8#B7srXq)YIH}B34=fNO9~c6}gtFLEw$kkjNO#0BnveRR$tdyZrpg~SnPRyq z?T^>YUj=93F=hU$P_Wum7}h5dKRI%R18x&nSXIK*Kz}&kF*V(Emn$(wxJ?CCdHg0u zIGwJDE3Wdab)!9k#z%u17k&x7Jkpux!`O zj%B#RmBILnfOK2w4x@X(J3Xd5?ch0&ZnHVV?T_`ADyZ$=5=WYpsYyqc?q&-7VZkE} z`|-7o+|i0)k3*X!PQs=Dy|2ce!~_aCYwn7Ig(Fs$F-q*+qEk6BinSOsfl8^wPZQ|M z#c7sus0H2Mfq!CQYH7RNbs(FU*7z&&zGeNv2_A1WwTmgO3VSi|5UyTlX=8@hGG?U- zkFeI&?YyNKx}K!Vu{!W#N{{?o%|cq~hWy)<7Q&{n6?-17+9mSIXN!n47hsaZPG@YJ zC{Nu@+A?s{#tT*_)IENX*XzNfUFKd*KbfKXQ|JhfZ5M-3H$~Ge{1-I+_f#xz+=SQ! z@^7jfRL16oBN#4Wr5#(hAHjD2lCG|-cO-?LO8Fj2J9gg4KUt}6b^N<41B*}5ef6Je zl(|AsHuXm+>-3_5Sr4<|KWC~Rq0C%GUA-f9*sdn|BUJ8RQT5+cwY+f?V|Vr6RXym8 z-CX%II>HC3w{fkEyN+;Qf3I-u_pPp@nxO7_1DNQVaa05*5pQ zx&1Rn$SBYIV|CEPRW=51+#xKgyut9=(c{MEO&eVkfOGWfu%~kTXm3cqd5oSgZA@1M zs`BvGOq&2PhuYn9#+JSb#}}l!+EZOSM*ax`wKzPcP?nn~x4xte_PM(Eyec&OF9=axB!J9k_>H4&UO!NQC zvygws2*yM082qFGZ6ih0SSDA~vD1Jfoq8mXSgePlF|+-@cf|7V>~NSmu{l>6?{Bf! zz~sSA!Z{f|i>D_KZjuK#<}IV-!3`Z=nRlj>2RHid89!K>Jh;(kd!|E>n5WA>%Ss;eV9jkkVM-qJ$bDBmIwp^K z5{?r8spA^{hCzlW7W6dctyHztkOrAe)>E1NfC9iG!pbBUJ()!e)KxtPgFMAEnP-;j0YcM>adRw{Ef0*TDJ+oArrK_4C3zWxT=G`Z>>0 z`rhoX$|sznl3iZiZZ8}%(yvsgk5%7Sl}g{bzKX7~R+dm#WV+oofi?a>8Ggc`JScJE z{at&B(sz-H1YxTVt(#)%CtDEQ?pgW8`S|6Rg2k%0=>FjXkvTJJu)>mRuXs(}CAKiz!2yXX+c?D<8o;6SPj(9EV zkdz-)tFyUq(qqbBg`g8@FoHANF5UoW$VdJt zA;_#mr_VIxQy|{|z{Px@B!lTva*AE_F;|Fb$0DY3KKUT<#4X#$E!x<6cCF|6Yj=%D zo)bZdpj2BgnU=P)O>~R|jrzU*(0DWzfpk%QgcyMl$0o+qgsaC?!rL~&V)=vKd8g&! zXF2_)l1ZF|i1chkySE_DWlZg+4-KzGZ>zG4d+#K988 zq$7P`&!xiVGIm{@IhOD_;D11f0V3CK3`r3Wl?+sTH*V^+^bsL;RM=fcda8(4*oCnY ze74%m5XrST1~k0{*_Qrd$5$x-Hl)8myiM^R+6I1)5XCKyflYH!w;Owk9W9RjO`E`1 z*H_8xU!5u2MYOr~=pV7Up6QJv{toA8G!*N|?PiKbGwY54?*9S+?)f2kT&TOCJ zS*2wLG+j!%(!~zCUsTtM-aVHN5$OjTaBpm@v@NKf1DaljZnEn}Zu3U88OJrnOKk0v zPsV*1DC&yLwET_^*m^+IXDH*QwDu`v>+dd{iGFe#`b&OeyZgCq%?|flRBld+>H|-r z3}>pC_!wf_%6OZXP(2TK>?GbjcE$S;c$ytz;(dsRu88x_C*H3WZ-q_q-V2@*yO_8Y zvBw{8{|w@7SG?&$@!kd=v}@wch`XzE1>1o7pz2fon;wC#{-SPQcQUQRo~ZgZXlwjt zxgBkHzy>L>MJk?|w8rn&+oB!2C%s1POLz2KnvUmTo8##Aj!SzscAPDYKMS#U<87xK z6*jSB2%epm9_pDm@Q+OS?CdXB_v&h@yQu3oF;xs0P_3TPI@B>;sAnc!2;)D&Q+I_h z8q#b#%=ymc%7&Xk$2~}(?ZNXah6=+~uAYNUWSf*kp1SLVQ3tzRcD2h`=To}uut{A? z`;;>fXA0M}xx2)fLxzi08&gDaI{Hg4!Wp)@qV(LJ$EJgpxyL_s0pi?L(f5vAv1%sz zQ2Ol^ue+ZRt4bWAcrlF&koh(R?Srk+=k^T(ruq#*{oeX;eNkgqwBf=y4BDL*+EE{^ zFS;FhsLMX83zd@(+fqHwKs_#{x}uNw1Z@H8xgs~~SjwmR5zj)TpW%A0d@A%hP9O(> zcVC4qeG}>0k9KO_|FXV!*LKq9v5Vr7D7)vL6;oHBY&X|06ZOl@5PhkR^G9bLJ0G;3 zs9zP=Ro9W~2i|>iQNN5+LN|=`G!)ISWgcvS-i+^-zMj4;d-00%)bnx1V;OQhKKN5x z<4EXTi82oUR5Z2@vo}6_Hjjtv9Z}oSunqdd1km>bljt#^TTM(VT`UdTR_QAqX4yuXLEW#)J3jjdmRelT^~%Jm|8&2}ZcxbnJbqK7Do_)p$MX)91TEjjgXUPkvgo@YjmI zYNjpPH~;9yJ{KR;_{FePrDK0uH0ZTO3!Ai#V;ldzn{*u4_(eEX)ni?cXmCBs`J?KC zeezFeT!j15=i(uat-D#z(DZ2VE?cxus?7+#!)?m28H=bsy==yizBc2F{%K0zuJmYV zH`;Zy%^3T((wTj{&FC`}e8X)B}B%Gy0AL-z4x&1K%UeXUmL+ z9QJ5-zRlSCChMCGzIotV2tG#-sV}rOGg>vw9__WnW?cJ*(%I`An^A>2_F4vB4|o^% zsO^8Xm=?Nl~T?O76@ZQC|`+G(`UVC)rKE-Fd*k(A^ z*^J%bbzBbKtHAq(;`OY{iiXysu2Gv&_?o(}**DpY?WjZcE#SQ!yff2lCu|hc%7*re zdhW7EZTHv=+g{Z!TcgeJ!1lKL!TS(+Z%nVfk$89Yiu!ijqp45WjM@LG^rk)q8|(t# z@4)u~^LctleIJ1D6`PUzs;Y15Yc`|To8Wr~d=oO1K3kut&*6xs?zb5qy{yVk{RsM6 z!S@;X)-&H$@C^gsS2p9Gmy}IY4e0w0d^Wq$`a1LFXGeWA!Ixn-E`O2B?PWJ?eX*__ z2)<#Ns@(nH^MdbqyD|F)<{N4^vW9~XYtYs(^R4R}^{ofrIJo`;Bkgj#VZRD|*MiTHrOMn2 zzF{fR)SE!R1@zlN--F!@ELaFCr@*^-`Vk;IE*2w4)i!-)M*N#roc= zy<5RI41ANo_gm(h<}iAl0=|6cd!6;=9|IeLZ=S?la4}4zm zEpr$jKCbR>iU)i?@cE%H+=uOVEbIrqRSx6s3%J}Ghw&Vq$&^~~UJTyd%sccr*buyz zJB$sFvJJ0t7~)#+MZwoUTk0&?bzHP`cWTsri^F(!r_yP^9c|ePzI#wdZ+7hv+`AIb z@zK%`Qlro9Q0=hak2XEzF#7BS-xJXHNOo<1;Uaif=3UhJo)*hjH4&s?GLy97gYV!M7iLiy%L z<5P?;X7*EU9y&BydKY+ygZ==wB{#*$8V$a2(0OA&)s|i0+YP>H;N$tyeoBhbCm(#X z!S@04c}|24!M6}Smgi0TnJI>C3HZ(d--P~b!(p&tkEq=PzF%`&d?`kzAAD8dThDx3 z!8Z(iHQ?hp)LxrnWM2%vb>MrQ`SO1P8-nku6yyDEZ0l=NjJ{Fu-2}d215~;D!RH0v z?cnQSnfUA%3OoB6gy^Pk`?!@a-N@`#RPTfuScw zOYQ>S?^2BBa%F4r0^0Ek_+A5F|AC5c7x;FA@0}E*;cn)87y9;t?<4Sena?vKTJiz- zK1(r5?&5L}r5L@w0-piCN0`r+6D@J1M};lbaNViwCsI?5UKy#zkY1_igGZ@yw}NjN z_y(pL&aGVT(cn8Cd_%#vnECQ^qa`!Jmz!#|+@b6uMuTr0_$GnxF6P@0J}>xANi~{( z$@R-mHL_-dZyxx*V7_%DVL$Ml3BKF8+$E_-_Br5N2ELht*nU5S{lMo-HH2=5Kh@|{ z1-@0_yOH^J{S<4y^k|>jRAbD~RQ>u~41MdscRBbzU_Q?%toy)sE%qMzr^#RO5lo%7(qaLYocneFwhXN2_(*(6Q0LUEoViGp@T)>Fk}6W@PqC z!@4jHeef8`w_?}WXw~kFXrM^x>UDIQ(fjx`BWo!5hJ(+0Ozl@;m$4ZAy23LqI;1c5 zJU$db><`>O3Gct*ts6-R-37S?F-!{b!}7f7h|| zQ_w?<1@Hl2dY5q`{0?Q~9cr(@I?#2S*x^E6v(Cf1u;k~c2l9Ta^RPy2zFF+3L*Ao0 z4{Jsz@|uzNkj}f-X4KsTzO1^U`*dE^X0&X^J_O!p4t$z580Ai+_x^Ri%*VTbzG0_2 z4sV~b5&U&1m-gWH&rxKJFIMyiN&gnH zV`Hm{emm&3ivBCo5Blo|6ukuZt0e85`zx-jTO`Ljg@)%M&#~W z##PTQYxG=peq-rL`G)t|e5365`Njt~rZ?{2)T8n5&!;th`dDh?Cl97Hw*1P`__y8m z#smHFe%nLbUxGRPE!d*uZ@6by!*-vlGM69YYOI*-GW@6I8y^o5#wUI7emy}vabSeK z@vlQ{jem8B#s=IsyfYWs5xlfEKBWupPoLWuMcwL9mvyL1+m)$} zht{XSMvlf$pRvPcw#LtXrRvpyxqB1U>nI!UwW(gWs(Q`;k0aOXF39V8)lt1JL;Eff zJ2tiXSM@*8#!+y@~~%GT!-gRVEm$IIQ^ZhrPxzE zbYRdO$F$l-QI0Krq6dQ*qp`!IgS*oea!slRGCXbqy0{*S4;mp z&fVrXr=9q6&&^z#3p>xSr61gNy(q?>Y4p1b=U^XoHuh6zVPAD7_E%49{5F`6eX8dx zX@A*l`=U)h&bD{6mUaY%@xIp)r7`c*eq!_C zpv!1jD<;yulMOmL7WHmyAv^cTfB1_2YQKFC-@84ycWSTssHVZN%FqEu#F4gAIK45kS+ME$=){aq1j{c&D^`k#gR(-}!ux(`72l!(}IfZKKeZQCX5H>hbpXjC_p zJx+v0@y4^zpKWU%-gp-E=K)PW2VI^+P`P(i+W8FXHS`rxd>GHwo-Xdq zL*U!LenI2=UYBt@>QTWw6|wu*ziAtIcILNFnLEQ}WS|dWEwD3V9`)Zi!Xc(K99HY6C!o(65IcqsQv0npmYzJVF4%btsfYfOuhnyVAIad{U@&Cx zyd{h`>rmF^;H7=xbHTS7X|ip`T$gdckpn!f6>U&c5oqo4at={BiZ;0E4A7{I0ncVF zrGB&w<+!}++>i2iJ(sogz5!SZ3{q!nvj04twe(lWqkdd6KPdBLfo)6B_dO50jQ3H-6I6%M?Nhe#^RO*;-v%~)2pt=-tev%|yq!+s64=2cGF_ z9EkpX%ren9I0N%1^)I33*mR-h>>c1opG=r%m3;;@(O9(P(+)W=x5Ey4Zr*yZqxf9R zFBN#6$bMIykh#=}`*#3+cHLg}>^f{>0MQN%Reh@k&mo@WNnPEe8&S>_Jm*K@z2N}c z()?^}0{!qJv9kpB`wDH7cFoL}_ofJW4TE7%*u&bkiy=q0aG{UfL-!Erx&=6gAB3?B z^~Jmw%|JiP$Z{Duh$|e4`K{2Ii#B4NWUPMBWqb)dmg;~$BF<2A*#6DbcW8Yv5dCpL z(@#*=I`B|`+}1^ZS&BM+iTk&CAfSXL_jmm!SUdL$|a6 z*46z`R!QHk+kXnTpZb#Q=h3XC_p_ds`6fMBw+iT~%kHd)#t5nl=`h>ZN%?38*|q?( zEtJOJFH~S{-lc7^7B%O$LZ7y+Y)b&o8uH$oiFX!ikEOhP8o#MMC`adq(q*(e#7mzzoK1B9@RisBJJUpT za1X4Fus*`Qn$~kT&P@lZv)du-#43R`(IAnrsWnZ!M(dC}u`YQGG9*iDD$27X59{Y? zm5{xIWiMsfDd=CV_JJ?W!1`)aA;#YO#j1mN4u+7~hIHZ!sKo~z zlbR}RgErlfFAiPS8+F0`ctp)_@{F0*f;WG+zUW5mUG)1dzJ8?q)nY@@>&VYC<*&v# z{s_i#mqo{6=Czr4AN_KD(d*!y1YSRn1tY)DSn8s&V1#J&@E+)exJP>3N^8{BpQ$zK z-@fe_v>ErNtNu0gvyS3xiN<|wCv;FB6Q6bL)Vin*XW2ItO~AY2pP(xt-=Xr~ME>fp z*BA9iJMqol*!zsMOUj0#Fl1jg$-dRTzGyLc4`7^5$GS#Txf+lDficvJdj11rD2*R9 zMpj@PRAcC|O+N$804;}UIWgMNO-n$ddfaC!e-QA^IPbp~dA%?m(w>bCVgK>z1@HgW zzKHH`S+Deh>pr{ahL>!vhd;4rZkmsDDtH_S*$8O}eGz&fJZSH=>GQtLCl_6JVxZ_; zXJGNY>0=`IW{YA2YdrZF>(`>6+ z@m#LRa7~*J>^|DI>J#8xTV^KlddfucyfQJ7p5OHE|GrPymj5#S`;L8m(61zYoJm)z zZPos_rl6Mr|)dyPgCL=G~l1JranewQdNBJEx4f$KhW;XS%yXV~u`8PXwH#F8=r`~rr zfUfJkM~M0%xA!n6!yZ?gPD>3@jJ?YdIQ6vVd1nu=3HD&Exa-P};{Sk+ zcVg|6C_{a@ZQl;aSl>g3Uei&0K4dCbPX+W0eUtuPt$$NK`u@GB!yC)2`UXgS4bW$O zN6f#zqj-(w{vYQ1e+Ak&811XW-&ENU!wb+Nt@ z$bUW`Yl!0bJHxKi`--_VX6CM zo*$=K@*m~=3CMpRddUWp53BiTIqntVw-|eYC-YoYf;6pNUVse#mUNsm8~X`Z+f+O; zWy(=~?Tc?Z(H5O6a;EHr4Q|PF8MNQAHBDf>Qn!!p&)VN-ETwhIqmcg^YnB%5b#Gho z^;9^S=vUFvF-4qFGL`a6IyxpHer+bkpN`wbp=+Q6dpgrHupXK5F2*^G!6RX>c|%{g z74g2z?1s(KIi8z1|U}^~u+1KfiSb#^@54DBgy#dkFrX zjMh6u`wa1YSoie8`1;JiI6hz((`bx$+p<=C;>c=h{;s1Ke}E<5AqF*PEd5KSShZ^? z_7_kGYFEqrlBrm`Me9x!6B{mAyLO1MukvC}xB%^?d}>!Ow5bI;ccMSkVb75IKK;F1 ztiHhat*DrKHR?z8qWR@-h+nbw8hIV+_ZQSp<4;k)OKrVY*sxDXeAGtF_0fZlUQKdO z5A}7!UOBKs`p_3|#oy%Z%Yd!s!B*+EjH^>_aed>OPVd)8HC>1L(7i3CdQHMRS-R`H zbjy1gjXxs4G#h4t?w@YDR&aFp0tNILL*)D1MPQGc_oDBVU660M{?SveHG8HiowQ#Nd&dAT7Wtd&dUvh!C(ud#t?}WEr8!vlkxg>& zF4c;1=y`D>yh3%w^HkCg`({+HEMdrcV81(751hY#uBjgMp5$5}X_`9m(d(f9qN9g$#>e!sxbshJCpKP)PJaV0T0{X=W-g{Z*GVHMJ&*?tkZ&GEO z&&B&MY;Xhe8jxpg_x>|FiWhtnA9Lwm9F?}A=n<@Uvn}~I_t;SM1LW~)Y5Bb)%3S(h$%L+A?(3mj@?}Id!4#ji+ z8;pz8Z;t&%#!}kX^+FzV;ly^w(M{99M|*0SsiJu9%62)frej>Kz_^Nd(uv@wF-z*n zRC@k&i_&u@^tkZ%-)228qCD4yY8 z;*ymmQ}O;fDbq3NB{$wl4r1)2cI9I{Z(Olv>I|%5>D*)n-brcA+Y{%zt@fT+Yx}1T z;JQoR3)ZadmiGex+6?eEUa;ozBk(+a4d#+N@NT>3cu{;VEo}FGucD)Yowh#I% zr@oreXHzrYZQYoEK1KcB$2>yoc{;cG0BeU29fOm)7%V=y4s*-F>KNEWmt4g+X6fcGiX#P15G4*X(uM1YJy)P|;>RwChL(1Qe zHAEBg8Yb0))^+>d`#-F`d3@B>_5c5#OqQ91O%ot2PA1?o0qe%@#spjfxOGT1E|m$O zPQ<7bty)`|1Z#t6{h%mT+nQ*rnX$CBCe>J5gSIwkt97mIr>%*i9f(>f2nmYweZJoJ zJ;_WMY=7VH?~i%R`+b*l&pr2?bI(2Z-20}C2OiMe`UKCKH&bgs>-l8$YU+T`lRqi6 z@$9hIc5}?y?l$`Uz&Mv}pDc6@D-`X^W!HFF=eaW1d0ICJP7FBo%fMls=OXStwZ@YT zX4f0C#tTdg`-Y|QkmfGwsdF9Q%%gqDvCnAVXgc}`UsWeQgP}IT0{F7~vg~>Dl(#H< z-U;Nvw+E-M8G4R|mhhv-)5FhS9`r@a zv`680#`tT!_|O)*tkC7I!YPIQ1+(n&ga5-HC#!#pZ#%ihdS%~@uGqf$)_VNfaoI6t zE>~|D8WF48+ra<68!Ka!Td%!ZFZ)duv0%rR+`gIKP4nig%{^vjWscQWxGC6Qn9u$a zJ|r)CcoBP&Rkg(0e>>Q>oqej+z?A-74NUn4{jQ=Z!F>g@7T{mpPHfFT!Nm&<>b3=d zA^*};=vD!YDZp4lJ^9vi#|8J2_lo=?f2EEEzUlaJ-yZw3p7{MIV=plOsXyuY-37te z2J*@*Yh^dINzdC(J(b_af1I`I!iHe~67beOo7(#g?J2*C{;EuXe49q(JwcwvD{;QJ zMrG!5Mk}~GSzQ4f^?w0nx4Uz&p>u4X&ZAEGNR78<31!u{bX=0|oL4@(Du=ytH+$x} z?49Saht4^q8w)tU=UV@X+a2EtyghDLT=xFe@U49DPYgqz!K3@nMK!@;R@;3aof`W- z{__WJ%8xy8l+|zZIrwYduw;v~C!q2bFLSQU5@r@PAz{as+k0?N05epJ07&G_A$VVY%%SXvUgE|?@_*X?RC`bHT$2# zDbw_FCQfSmoyFdoPV&YwR?+uQjok~4?)xYYT3K0j(xJ3_Aphne!by6J_QkgzcginX z8XrR*dVJ-L`5P~Inln)BBY%7$Hciu~r?Y2nwN;d#-7%GU=SR@8@XJ%zEkxfgaZOmk z=705l4qmCT`!i!3C^7p^iMOp77@Pr z06m3fo%SK+s~Nl1;IRVx41a8hyGu*X@194PUf``C{RZ zZyg`cyR~T8D^oNlc6{V6j6VS0Klwaay@(&zI_ex#Xc&1)SNSC_?~2R&lht18XkM91 zdQV@ndcn7XcU64&&DTcP)%CR+U&s1Z{5=|{Nt=u8z2F}DA)m&p^h4txh2F(iSsmiP zOToXLcc-q2tDzrH4jB_a`0u;%bmZtXJ;Q_KCvkCV#u4V-vsZA$~<_o=8Mts zX4;(X#QY7~U&Zmo4xL92CnoP7r^fCPU%j6Pe`V*Z?*a!rKi&hb3CGWqpzpQlUF}id zLjG>@x}3bOfxI#C)#QD;J2^cHFGV>A>zRCZ2l{j6Dez9=ITbc9?M6?DpL$7?eWUR$ zVqD}~;LHJIR>d*DQPsrNSYu3{XN?;Yh` zcLH^1Ap6MRL7vGYJL58m_pw9A0;#PF*dVDBYiZPynES~xeB;eG#WZz z_-_aQhX(QYdZHmOc*yoc4|PoNSRJD+tAC+z5uWh5CsNlpI#SW+>=W*gzG_LR4Nts~ zHs(<_Ip6il?(=fsRnBYQm>b*YcCFuu&fkU3|HRSxo*$h`43#V9na(~`0rK)$UaV|7 zdzj0t^*zkz?@Y#KIgz;2qk{ca9;>~lAlP4vPVX*akC*i30^&JIYl6Qr_AEyd_eWZK ztipEc+)COa^t$|4i@-SsFW$;8!mrEOhcDLrPu})Nf-!H*igi-QV>x;eI#j|RuRymp z(wiKfZlb;)9$dw|gr6{E@ryWlg3VeKxjhA1%tvmK)%h-4R&5^_xNbq$zXi=?zdZ%) zoyetNWUKQG@E+i|nqN0{v*8!hxYFNjc@GLcG~0>p7LMS1Fl`+yy)Rrh@6|XK$L|#k z@X3aQ%4bX0m}BVB$D!lyV%+iR{HuMHFTby-W-4jS_x4;P9FE|f zx^42|U+ut8IOCUqCSl~b%X#nO9bBuMocAV;1Mf2!L-_!t^A-Rvy?hJ0M{Az>q^H-b zwbM)DCy_qGIV0XWa&V8M<$pa_3+K_`r1k8R@QD7?VN_yk{L4vCZ_~y8-Mge`yF1|% zcP=)UJKpEmUn$xIZ!fCJ0~hU+5G&la`cA83^%$%FnzLN7)yMB2Uv>S#@Zsm~*y_Wr z{)C~29fx(@O?k1eABRjiX`x^m2RpWX86Pd{+Ok8emC~hU-olllb(uG3rG>nem9w^GUTE6lvi+jk-zyt#t&FP7 zLDtF!%0!+uc^>k*UNX;`+as@;XX#(bVPrhx2rn$O`R9x75isLZ8#Vj>&!3Pz{;mr+ z#lRKJYTL+#8f-gC&C4XpL?RU#2*md@A zn6J!wQncSfyOA-${s{al*uS*tQyi~ysSS;7C3^kYR?F=O#WLNIHv5NYq1Lrj0oeJDjunXs-KXcYct+F?p?hJOsm{V+dLN;8ilX8G1d$F8! z@tYsNzb*Tuxq$f`X`RHM8#|o%Rr>ob^xH(=g;xgcZF{dcUN}Je1LLE0c!SNyf>~
Fd!@w^x(He)Jl^hMvc`ZN!=V3%oZ*Q)>6rLxzt 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.py new file mode 100644 index 00000000..e620b48a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/cu2qu.py @@ -0,0 +1,534 @@ +# cython: language_level=3 +# distutils: define_macros=CYTHON_TRACE_NOGIL=1 + +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +try: + import cython + + COMPILED = cython.compiled +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython + + COMPILED = False + +import math + +from .errors import Error as Cu2QuError, ApproxNotFoundError + + +__all__ = ["curve_to_quadratic", "curves_to_quadratic"] + +MAX_N = 100 + +NAN = float("NaN") + + +@cython.cfunc +@cython.inline +@cython.returns(cython.double) +@cython.locals(v1=cython.complex, v2=cython.complex) +def dot(v1, v2): + """Return the dot product of two vectors. + + Args: + v1 (complex): First vector. + v2 (complex): Second vector. + + Returns: + double: Dot product. + """ + return (v1 * v2.conjugate()).real + + +@cython.cfunc +@cython.inline +@cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) +@cython.locals( + _1=cython.complex, _2=cython.complex, _3=cython.complex, _4=cython.complex +) +def calc_cubic_points(a, b, c, d): + _1 = d + _2 = (c / 3.0) + d + _3 = (b + c) / 3.0 + _2 + _4 = a + d + c + b + return _1, _2, _3, _4 + + +@cython.cfunc +@cython.inline +@cython.locals( + p0=cython.complex, p1=cython.complex, p2=cython.complex, p3=cython.complex +) +@cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) +def calc_cubic_parameters(p0, p1, p2, p3): + c = (p1 - p0) * 3.0 + b = (p2 - p1) * 3.0 - c + d = p0 + a = p3 - d - c - b + return a, b, c, d + + +@cython.cfunc +@cython.inline +@cython.locals( + p0=cython.complex, p1=cython.complex, p2=cython.complex, p3=cython.complex +) +def split_cubic_into_n_iter(p0, p1, p2, p3, n): + """Split a cubic Bezier into n equal parts. + + Splits the curve into `n` equal parts by curve time. + (t=0..1/n, t=1/n..2/n, ...) + + Args: + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + + Returns: + An iterator yielding the control points (four complex values) of the + subcurves. + """ + # Hand-coded special-cases + if n == 2: + return iter(split_cubic_into_two(p0, p1, p2, p3)) + if n == 3: + return iter(split_cubic_into_three(p0, p1, p2, p3)) + if n == 4: + a, b = split_cubic_into_two(p0, p1, p2, p3) + return iter( + split_cubic_into_two(a[0], a[1], a[2], a[3]) + + split_cubic_into_two(b[0], b[1], b[2], b[3]) + ) + if n == 6: + a, b = split_cubic_into_two(p0, p1, p2, p3) + return iter( + split_cubic_into_three(a[0], a[1], a[2], a[3]) + + split_cubic_into_three(b[0], b[1], b[2], b[3]) + ) + + return _split_cubic_into_n_gen(p0, p1, p2, p3, n) + + +@cython.locals( + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, + n=cython.int, +) +@cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) +@cython.locals( + dt=cython.double, delta_2=cython.double, delta_3=cython.double, i=cython.int +) +@cython.locals( + a1=cython.complex, b1=cython.complex, c1=cython.complex, d1=cython.complex +) +def _split_cubic_into_n_gen(p0, p1, p2, p3, n): + a, b, c, d = calc_cubic_parameters(p0, p1, p2, p3) + dt = 1 / n + delta_2 = dt * dt + delta_3 = dt * delta_2 + for i in range(n): + t1 = i * dt + t1_2 = t1 * t1 + # calc new a, b, c and d + a1 = a * delta_3 + b1 = (3 * a * t1 + b) * delta_2 + c1 = (2 * b * t1 + c + 3 * a * t1_2) * dt + d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d + yield calc_cubic_points(a1, b1, c1, d1) + + +@cython.cfunc +@cython.inline +@cython.locals( + p0=cython.complex, p1=cython.complex, p2=cython.complex, p3=cython.complex +) +@cython.locals(mid=cython.complex, deriv3=cython.complex) +def split_cubic_into_two(p0, p1, p2, p3): + """Split a cubic Bezier into two equal parts. + + Splits the curve into two equal parts at t = 0.5 + + Args: + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + + Returns: + tuple: Two cubic Beziers (each expressed as a tuple of four complex + values). + """ + mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + deriv3 = (p3 + p2 - p1 - p0) * 0.125 + return ( + (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + ) + + +@cython.cfunc +@cython.inline +@cython.locals( + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals( + mid1=cython.complex, + deriv1=cython.complex, + mid2=cython.complex, + deriv2=cython.complex, +) +def split_cubic_into_three(p0, p1, p2, p3): + """Split a cubic Bezier into three equal parts. + + Splits the curve into three equal parts at t = 1/3 and t = 2/3 + + Args: + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + + Returns: + tuple: Three cubic Beziers (each expressed as a tuple of four complex + values). + """ + mid1 = (8 * p0 + 12 * p1 + 6 * p2 + p3) * (1 / 27) + deriv1 = (p3 + 3 * p2 - 4 * p0) * (1 / 27) + mid2 = (p0 + 6 * p1 + 12 * p2 + 8 * p3) * (1 / 27) + deriv2 = (4 * p3 - 3 * p1 - p0) * (1 / 27) + return ( + (p0, (2 * p0 + p1) / 3.0, mid1 - deriv1, mid1), + (mid1, mid1 + deriv1, mid2 - deriv2, mid2), + (mid2, mid2 + deriv2, (p2 + 2 * p3) / 3.0, p3), + ) + + +@cython.cfunc +@cython.inline +@cython.returns(cython.complex) +@cython.locals( + t=cython.double, + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals(_p1=cython.complex, _p2=cython.complex) +def cubic_approx_control(t, p0, p1, p2, p3): + """Approximate a cubic Bezier using a quadratic one. + + Args: + t (double): Position of control point. + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + + Returns: + complex: Location of candidate control point on quadratic curve. + """ + _p1 = p0 + (p1 - p0) * 1.5 + _p2 = p3 + (p2 - p3) * 1.5 + return _p1 + (_p2 - _p1) * t + + +@cython.cfunc +@cython.inline +@cython.returns(cython.complex) +@cython.locals(a=cython.complex, b=cython.complex, c=cython.complex, d=cython.complex) +@cython.locals(ab=cython.complex, cd=cython.complex, p=cython.complex, h=cython.double) +def calc_intersect(a, b, c, d): + """Calculate the intersection of two lines. + + Args: + a (complex): Start point of first line. + b (complex): End point of first line. + c (complex): Start point of second line. + d (complex): End point of second line. + + Returns: + complex: Location of intersection if one present, ``complex(NaN,NaN)`` + if no intersection was found. + """ + ab = b - a + cd = d - c + p = ab * 1j + try: + h = dot(p, a - c) / dot(p, cd) + except ZeroDivisionError: + return complex(NAN, NAN) + return c + cd * h + + +@cython.cfunc +@cython.returns(cython.int) +@cython.locals( + tolerance=cython.double, + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals(mid=cython.complex, deriv3=cython.complex) +def cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + """Check if a cubic Bezier lies within a given distance of the origin. + + "Origin" means *the* origin (0,0), not the start of the curve. Note that no + checks are made on the start and end positions of the curve; this function + only checks the inside of the curve. + + Args: + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + tolerance (double): Distance from origin. + + Returns: + bool: True if the cubic Bezier ``p`` entirely lies within a distance + ``tolerance`` of the origin, False otherwise. + """ + # First check p2 then p1, as p2 has higher error early on. + if abs(p2) <= tolerance and abs(p1) <= tolerance: + return True + + # Split. + mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + if abs(mid) > tolerance: + return False + deriv3 = (p3 + p2 - p1 - p0) * 0.125 + return cubic_farthest_fit_inside( + p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) + + +@cython.cfunc +@cython.inline +@cython.locals(tolerance=cython.double) +@cython.locals( + q1=cython.complex, + c0=cython.complex, + c1=cython.complex, + c2=cython.complex, + c3=cython.complex, +) +def cubic_approx_quadratic(cubic, tolerance): + """Approximate a cubic Bezier with a single quadratic within a given tolerance. + + Args: + cubic (sequence): Four complex numbers representing control points of + the cubic Bezier curve. + tolerance (double): Permitted deviation from the original curve. + + Returns: + Three complex numbers representing control points of the quadratic + curve if it fits within the given tolerance, or ``None`` if no suitable + curve could be calculated. + """ + + q1 = calc_intersect(cubic[0], cubic[1], cubic[2], cubic[3]) + if math.isnan(q1.imag): + return None + c0 = cubic[0] + c3 = cubic[3] + c1 = c0 + (q1 - c0) * (2 / 3) + c2 = c3 + (q1 - c3) * (2 / 3) + if not cubic_farthest_fit_inside(0, c1 - cubic[1], c2 - cubic[2], 0, tolerance): + return None + return c0, q1, c3 + + +@cython.cfunc +@cython.locals(n=cython.int, tolerance=cython.double) +@cython.locals(i=cython.int) +@cython.locals(all_quadratic=cython.int) +@cython.locals( + c0=cython.complex, c1=cython.complex, c2=cython.complex, c3=cython.complex +) +@cython.locals( + q0=cython.complex, + q1=cython.complex, + next_q1=cython.complex, + q2=cython.complex, + d1=cython.complex, +) +def cubic_approx_spline(cubic, n, tolerance, all_quadratic): + """Approximate a cubic Bezier curve with a spline of n quadratics. + + Args: + cubic (sequence): Four complex numbers representing control points of + the cubic Bezier curve. + n (int): Number of quadratic Bezier curves in the spline. + tolerance (double): Permitted deviation from the original curve. + + Returns: + A list of ``n+2`` complex numbers, representing control points of the + quadratic spline if it fits within the given tolerance, or ``None`` if + no suitable spline could be calculated. + """ + + if n == 1: + return cubic_approx_quadratic(cubic, tolerance) + if n == 2 and all_quadratic == False: + return cubic + + cubics = split_cubic_into_n_iter(cubic[0], cubic[1], cubic[2], cubic[3], n) + + # calculate the spline of quadratics and check errors at the same time. + next_cubic = next(cubics) + next_q1 = cubic_approx_control( + 0, next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + ) + q2 = cubic[0] + d1 = 0j + spline = [cubic[0], next_q1] + for i in range(1, n + 1): + # Current cubic to convert + c0, c1, c2, c3 = next_cubic + + # Current quadratic approximation of current cubic + q0 = q2 + q1 = next_q1 + if i < n: + next_cubic = next(cubics) + next_q1 = cubic_approx_control( + i / (n - 1), next_cubic[0], next_cubic[1], next_cubic[2], next_cubic[3] + ) + spline.append(next_q1) + q2 = (q1 + next_q1) * 0.5 + else: + q2 = c3 + + # End-point deltas + d0 = d1 + d1 = q2 - c3 + + if abs(d1) > tolerance or not cubic_farthest_fit_inside( + d0, + q0 + (q1 - q0) * (2 / 3) - c1, + q2 + (q1 - q2) * (2 / 3) - c2, + d1, + tolerance, + ): + return None + spline.append(cubic[3]) + + return spline + + +@cython.locals(max_err=cython.double) +@cython.locals(n=cython.int) +@cython.locals(all_quadratic=cython.int) +def curve_to_quadratic(curve, max_err, all_quadratic=True): + """Approximate a cubic Bezier curve with a spline of n quadratics. + + Args: + cubic (sequence): Four 2D tuples representing control points of + the cubic Bezier curve. + max_err (double): Permitted deviation from the original curve. + all_quadratic (bool): If True (default) returned value is a + quadratic spline. If False, it's either a single quadratic + curve or a single cubic curve. + + Returns: + If all_quadratic is True: A list of 2D tuples, representing + control points of the quadratic spline if it fits within the + given tolerance, or ``None`` if no suitable spline could be + calculated. + + If all_quadratic is False: Either a quadratic curve (if length + of output is 3), or a cubic curve (if length of output is 4). + """ + + curve = [complex(*p) for p in curve] + + for n in range(1, MAX_N + 1): + spline = cubic_approx_spline(curve, n, max_err, all_quadratic) + if spline is not None: + # done. go home + return [(s.real, s.imag) for s in spline] + + raise ApproxNotFoundError(curve) + + +@cython.locals(l=cython.int, last_i=cython.int, i=cython.int) +@cython.locals(all_quadratic=cython.int) +def curves_to_quadratic(curves, max_errors, all_quadratic=True): + """Return quadratic Bezier splines approximating the input cubic Beziers. + + Args: + curves: A sequence of *n* curves, each curve being a sequence of four + 2D tuples. + max_errors: A sequence of *n* floats representing the maximum permissible + deviation from each of the cubic Bezier curves. + all_quadratic (bool): If True (default) returned values are a + quadratic spline. If False, they are either a single quadratic + curve or a single cubic curve. + + Example:: + + >>> curves_to_quadratic( [ + ... [ (50,50), (100,100), (150,100), (200,50) ], + ... [ (75,50), (120,100), (150,75), (200,60) ] + ... ], [1,1] ) + [[(50.0, 50.0), (75.0, 75.0), (125.0, 91.66666666666666), (175.0, 75.0), (200.0, 50.0)], [(75.0, 50.0), (97.5, 75.0), (135.41666666666666, 82.08333333333333), (175.0, 67.5), (200.0, 60.0)]] + + The returned splines have "implied oncurve points" suitable for use in + TrueType ``glif`` outlines - i.e. in the first spline returned above, + the first quadratic segment runs from (50,50) to + ( (75 + 125)/2 , (120 + 91.666..)/2 ) = (100, 83.333...). + + Returns: + If all_quadratic is True, a list of splines, each spline being a list + of 2D tuples. + + If all_quadratic is False, a list of curves, each curve being a quadratic + (length 3), or cubic (length 4). + + Raises: + fontTools.cu2qu.Errors.ApproxNotFoundError: if no suitable approximation + can be found for all curves with the given parameters. + """ + + curves = [[complex(*p) for p in curve] for curve in curves] + assert len(max_errors) == len(curves) + + l = len(curves) + splines = [None] * l + last_i = i = 0 + n = 1 + while True: + spline = cubic_approx_spline(curves[i], n, max_errors[i], all_quadratic) + if spline is None: + if n == MAX_N: + break + n += 1 + last_i = i + continue + splines[i] = spline + i = (i + 1) % l + if i == last_i: + # done. go home + return [[(s.real, s.imag) for s in spline] for spline in splines] + + raise ApproxNotFoundError(curves) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/errors.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/errors.py new file mode 100644 index 00000000..fa3dc429 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/errors.py @@ -0,0 +1,77 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class Error(Exception): + """Base Cu2Qu exception class for all other errors.""" + + +class ApproxNotFoundError(Error): + def __init__(self, curve): + message = "no approximation found: %s" % curve + super().__init__(message) + self.curve = curve + + +class UnequalZipLengthsError(Error): + pass + + +class IncompatibleGlyphsError(Error): + def __init__(self, glyphs): + assert len(glyphs) > 1 + self.glyphs = glyphs + names = set(repr(g.name) for g in glyphs) + if len(names) > 1: + self.combined_name = "{%s}" % ", ".join(sorted(names)) + else: + self.combined_name = names.pop() + + def __repr__(self): + return "<%s %s>" % (type(self).__name__, self.combined_name) + + +class IncompatibleSegmentNumberError(IncompatibleGlyphsError): + def __str__(self): + return "Glyphs named %s have different number of segments" % ( + self.combined_name + ) + + +class IncompatibleSegmentTypesError(IncompatibleGlyphsError): + def __init__(self, glyphs, segments): + IncompatibleGlyphsError.__init__(self, glyphs) + self.segments = segments + + def __str__(self): + lines = [] + ndigits = len(str(max(self.segments))) + for i, tags in sorted(self.segments.items()): + lines.append( + "%s: (%s)" % (str(i).rjust(ndigits), ", ".join(repr(t) for t in tags)) + ) + return "Glyphs named %s have incompatible segment types:\n %s" % ( + self.combined_name, + "\n ".join(lines), + ) + + +class IncompatibleFontsError(Error): + def __init__(self, glyph_errors): + self.glyph_errors = glyph_errors + + def __str__(self): + return "fonts contains incompatible glyphs: %s" % ( + ", ".join(repr(g) for g in sorted(self.glyph_errors.keys())) + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/ufo.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/ufo.py new file mode 100644 index 00000000..10367cfe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/cu2qu/ufo.py @@ -0,0 +1,349 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Converts cubic bezier curves to quadratic splines. + +Conversion is performed such that the quadratic splines keep the same end-curve +tangents as the original cubics. The approach is iterative, increasing the +number of segments for a spline until the error gets below a bound. + +Respective curves from multiple fonts will be converted at once to ensure that +the resulting splines are interpolation-compatible. +""" + +import logging +from fontTools.pens.basePen import AbstractPen +from fontTools.pens.pointPen import PointToSegmentPen +from fontTools.pens.reverseContourPen import ReverseContourPen + +from . import curves_to_quadratic +from .errors import ( + UnequalZipLengthsError, + IncompatibleSegmentNumberError, + IncompatibleSegmentTypesError, + IncompatibleGlyphsError, + IncompatibleFontsError, +) + + +__all__ = ["fonts_to_quadratic", "font_to_quadratic"] + +# The default approximation error below is a relative value (1/1000 of the EM square). +# Later on, we convert it to absolute font units by multiplying it by a font's UPEM +# (see fonts_to_quadratic). +DEFAULT_MAX_ERR = 0.001 +CURVE_TYPE_LIB_KEY = "com.github.googlei18n.cu2qu.curve_type" + +logger = logging.getLogger(__name__) + + +_zip = zip + + +def zip(*args): + """Ensure each argument to zip has the same length. Also make sure a list is + returned for python 2/3 compatibility. + """ + + if len(set(len(a) for a in args)) != 1: + raise UnequalZipLengthsError(*args) + return list(_zip(*args)) + + +class GetSegmentsPen(AbstractPen): + """Pen to collect segments into lists of points for conversion. + + Curves always include their initial on-curve point, so some points are + duplicated between segments. + """ + + def __init__(self): + self._last_pt = None + self.segments = [] + + def _add_segment(self, tag, *args): + if tag in ["move", "line", "qcurve", "curve"]: + self._last_pt = args[-1] + self.segments.append((tag, args)) + + def moveTo(self, pt): + self._add_segment("move", pt) + + def lineTo(self, pt): + self._add_segment("line", pt) + + def qCurveTo(self, *points): + self._add_segment("qcurve", self._last_pt, *points) + + def curveTo(self, *points): + self._add_segment("curve", self._last_pt, *points) + + def closePath(self): + self._add_segment("close") + + def endPath(self): + self._add_segment("end") + + def addComponent(self, glyphName, transformation): + pass + + +def _get_segments(glyph): + """Get a glyph's segments as extracted by GetSegmentsPen.""" + + pen = GetSegmentsPen() + # glyph.draw(pen) + # We can't simply draw the glyph with the pen, but we must initialize the + # PointToSegmentPen explicitly with outputImpliedClosingLine=True. + # By default PointToSegmentPen does not outputImpliedClosingLine -- unless + # last and first point on closed contour are duplicated. Because we are + # converting multiple glyphs at the same time, we want to make sure + # this function returns the same number of segments, whether or not + # the last and first point overlap. + # https://github.com/googlefonts/fontmake/issues/572 + # https://github.com/fonttools/fonttools/pull/1720 + pointPen = PointToSegmentPen(pen, outputImpliedClosingLine=True) + glyph.drawPoints(pointPen) + return pen.segments + + +def _set_segments(glyph, segments, reverse_direction): + """Draw segments as extracted by GetSegmentsPen back to a glyph.""" + + glyph.clearContours() + pen = glyph.getPen() + if reverse_direction: + pen = ReverseContourPen(pen) + for tag, args in segments: + if tag == "move": + pen.moveTo(*args) + elif tag == "line": + pen.lineTo(*args) + elif tag == "curve": + pen.curveTo(*args[1:]) + elif tag == "qcurve": + pen.qCurveTo(*args[1:]) + elif tag == "close": + pen.closePath() + elif tag == "end": + pen.endPath() + else: + raise AssertionError('Unhandled segment type "%s"' % tag) + + +def _segments_to_quadratic(segments, max_err, stats, all_quadratic=True): + """Return quadratic approximations of cubic segments.""" + + assert all(s[0] == "curve" for s in segments), "Non-cubic given to convert" + + new_points = curves_to_quadratic([s[1] for s in segments], max_err, all_quadratic) + n = len(new_points[0]) + assert all(len(s) == n for s in new_points[1:]), "Converted incompatibly" + + spline_length = str(n - 2) + stats[spline_length] = stats.get(spline_length, 0) + 1 + + if all_quadratic or n == 3: + return [("qcurve", p) for p in new_points] + else: + return [("curve", p) for p in new_points] + + +def _glyphs_to_quadratic(glyphs, max_err, reverse_direction, stats, all_quadratic=True): + """Do the actual conversion of a set of compatible glyphs, after arguments + have been set up. + + Return True if the glyphs were modified, else return False. + """ + + try: + segments_by_location = zip(*[_get_segments(g) for g in glyphs]) + except UnequalZipLengthsError: + raise IncompatibleSegmentNumberError(glyphs) + if not any(segments_by_location): + return False + + # always modify input glyphs if reverse_direction is True + glyphs_modified = reverse_direction + + new_segments_by_location = [] + incompatible = {} + for i, segments in enumerate(segments_by_location): + tag = segments[0][0] + if not all(s[0] == tag for s in segments[1:]): + incompatible[i] = [s[0] for s in segments] + elif tag == "curve": + new_segments = _segments_to_quadratic( + segments, max_err, stats, all_quadratic + ) + if all_quadratic or new_segments != segments: + glyphs_modified = True + segments = new_segments + new_segments_by_location.append(segments) + + if glyphs_modified: + new_segments_by_glyph = zip(*new_segments_by_location) + for glyph, new_segments in zip(glyphs, new_segments_by_glyph): + _set_segments(glyph, new_segments, reverse_direction) + + if incompatible: + raise IncompatibleSegmentTypesError(glyphs, segments=incompatible) + return glyphs_modified + + +def glyphs_to_quadratic( + glyphs, max_err=None, reverse_direction=False, stats=None, all_quadratic=True +): + """Convert the curves of a set of compatible of glyphs to quadratic. + + All curves will be converted to quadratic at once, ensuring interpolation + compatibility. If this is not required, calling glyphs_to_quadratic with one + glyph at a time may yield slightly more optimized results. + + Return True if glyphs were modified, else return False. + + Raises IncompatibleGlyphsError if glyphs have non-interpolatable outlines. + """ + if stats is None: + stats = {} + + if not max_err: + # assume 1000 is the default UPEM + max_err = DEFAULT_MAX_ERR * 1000 + + if isinstance(max_err, (list, tuple)): + max_errors = max_err + else: + max_errors = [max_err] * len(glyphs) + assert len(max_errors) == len(glyphs) + + return _glyphs_to_quadratic( + glyphs, max_errors, reverse_direction, stats, all_quadratic + ) + + +def fonts_to_quadratic( + fonts, + max_err_em=None, + max_err=None, + reverse_direction=False, + stats=None, + dump_stats=False, + remember_curve_type=True, + all_quadratic=True, +): + """Convert the curves of a collection of fonts to quadratic. + + All curves will be converted to quadratic at once, ensuring interpolation + compatibility. If this is not required, calling fonts_to_quadratic with one + font at a time may yield slightly more optimized results. + + Return True if fonts were modified, else return False. + + By default, cu2qu stores the curve type in the fonts' lib, under a private + key "com.github.googlei18n.cu2qu.curve_type", and will not try to convert + them again if the curve type is already set to "quadratic". + Setting 'remember_curve_type' to False disables this optimization. + + Raises IncompatibleFontsError if same-named glyphs from different fonts + have non-interpolatable outlines. + """ + + if remember_curve_type: + curve_types = {f.lib.get(CURVE_TYPE_LIB_KEY, "cubic") for f in fonts} + if len(curve_types) == 1: + curve_type = next(iter(curve_types)) + if curve_type in ("quadratic", "mixed"): + logger.info("Curves already converted to quadratic") + return False + elif curve_type == "cubic": + pass # keep converting + else: + raise NotImplementedError(curve_type) + elif len(curve_types) > 1: + # going to crash later if they do differ + logger.warning("fonts may contain different curve types") + + if stats is None: + stats = {} + + if max_err_em and max_err: + raise TypeError("Only one of max_err and max_err_em can be specified.") + if not (max_err_em or max_err): + max_err_em = DEFAULT_MAX_ERR + + if isinstance(max_err, (list, tuple)): + assert len(max_err) == len(fonts) + max_errors = max_err + elif max_err: + max_errors = [max_err] * len(fonts) + + if isinstance(max_err_em, (list, tuple)): + assert len(fonts) == len(max_err_em) + max_errors = [f.info.unitsPerEm * e for f, e in zip(fonts, max_err_em)] + elif max_err_em: + max_errors = [f.info.unitsPerEm * max_err_em for f in fonts] + + modified = False + glyph_errors = {} + for name in set().union(*(f.keys() for f in fonts)): + glyphs = [] + cur_max_errors = [] + for font, error in zip(fonts, max_errors): + if name in font: + glyphs.append(font[name]) + cur_max_errors.append(error) + try: + modified |= _glyphs_to_quadratic( + glyphs, cur_max_errors, reverse_direction, stats, all_quadratic + ) + except IncompatibleGlyphsError as exc: + logger.error(exc) + glyph_errors[name] = exc + + if glyph_errors: + raise IncompatibleFontsError(glyph_errors) + + if modified and dump_stats: + spline_lengths = sorted(stats.keys()) + logger.info( + "New spline lengths: %s" + % (", ".join("%s: %d" % (l, stats[l]) for l in spline_lengths)) + ) + + if remember_curve_type: + for font in fonts: + curve_type = font.lib.get(CURVE_TYPE_LIB_KEY, "cubic") + new_curve_type = "quadratic" if all_quadratic else "mixed" + if curve_type != new_curve_type: + font.lib[CURVE_TYPE_LIB_KEY] = new_curve_type + modified = True + return modified + + +def glyph_to_quadratic(glyph, **kwargs): + """Convenience wrapper around glyphs_to_quadratic, for just one glyph. + Return True if the glyph was modified, else return False. + """ + + return glyphs_to_quadratic([glyph], **kwargs) + + +def font_to_quadratic(font, **kwargs): + """Convenience wrapper around fonts_to_quadratic, for just one font. + Return True if the font was modified, else return False. + """ + + return fonts_to_quadratic([font], **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/__init__.py new file mode 100644 index 00000000..69d4912c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/designspaceLib/__init__.py @@ -0,0 +1,3281 @@ +from __future__ import annotations + +import collections +import copy +import itertools +import math +import os +import posixpath +from io import BytesIO, StringIO +from textwrap import indent +from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union, cast + +from fontTools.misc import etree as ET +from fontTools.misc import plistlib +from fontTools.misc.loggingTools import LogMixin +from fontTools.misc.textTools import tobytes, tostr + +""" + designSpaceDocument + + - read and write designspace files +""" + +__all__ = [ + "AxisDescriptor", + "AxisLabelDescriptor", + "AxisMappingDescriptor", + "BaseDocReader", + "BaseDocWriter", + "DesignSpaceDocument", + "DesignSpaceDocumentError", + "DiscreteAxisDescriptor", + "InstanceDescriptor", + "LocationLabelDescriptor", + "RangeAxisSubsetDescriptor", + "RuleDescriptor", + "SourceDescriptor", + "ValueAxisSubsetDescriptor", + "VariableFontDescriptor", +] + +# ElementTree allows to find namespace-prefixed elements, but not attributes +# so we have to do it ourselves for 'xml:lang' +XML_NS = "{http://www.w3.org/XML/1998/namespace}" +XML_LANG = XML_NS + "lang" + + +def posix(path): + """Normalize paths using forward slash to work also on Windows.""" + new_path = posixpath.join(*path.split(os.path.sep)) + if path.startswith("/"): + # The above transformation loses absolute paths + new_path = "/" + new_path + elif path.startswith(r"\\"): + # The above transformation loses leading slashes of UNC path mounts + new_path = "//" + new_path + return new_path + + +def posixpath_property(private_name): + """Generate a propery that holds a path always using forward slashes.""" + + def getter(self): + # Normal getter + return getattr(self, private_name) + + def setter(self, value): + # The setter rewrites paths using forward slashes + if value is not None: + value = posix(value) + setattr(self, private_name, value) + + return property(getter, setter) + + +class DesignSpaceDocumentError(Exception): + def __init__(self, msg, obj=None): + self.msg = msg + self.obj = obj + + def __str__(self): + return str(self.msg) + (": %r" % self.obj if self.obj is not None else "") + + +class AsDictMixin(object): + def asdict(self): + d = {} + for attr, value in self.__dict__.items(): + if attr.startswith("_"): + continue + if hasattr(value, "asdict"): + value = value.asdict() + elif isinstance(value, list): + value = [v.asdict() if hasattr(v, "asdict") else v for v in value] + d[attr] = value + return d + + +class SimpleDescriptor(AsDictMixin): + """Containers for a bunch of attributes""" + + # XXX this is ugly. The 'print' is inappropriate here, and instead of + # assert, it should simply return True/False + def compare(self, other): + # test if this object contains the same data as the other + for attr in self._attrs: + try: + assert getattr(self, attr) == getattr(other, attr) + except AssertionError: + print( + "failed attribute", + attr, + getattr(self, attr), + "!=", + getattr(other, attr), + ) + + def __repr__(self): + attrs = [f"{a}={repr(getattr(self, a))}," for a in self._attrs] + attrs = indent("\n".join(attrs), " ") + return f"{self.__class__.__name__}(\n{attrs}\n)" + + +class SourceDescriptor(SimpleDescriptor): + """Simple container for data related to the source + + .. code:: python + + doc = DesignSpaceDocument() + s1 = SourceDescriptor() + s1.path = masterPath1 + s1.name = "master.ufo1" + s1.font = defcon.Font("master.ufo1") + s1.location = dict(weight=0) + s1.familyName = "MasterFamilyName" + s1.styleName = "MasterStyleNameOne" + s1.localisedFamilyName = dict(fr="Caractère") + s1.mutedGlyphNames.append("A") + s1.mutedGlyphNames.append("Z") + doc.addSource(s1) + + """ + + flavor = "source" + _attrs = [ + "filename", + "path", + "name", + "layerName", + "location", + "copyLib", + "copyGroups", + "copyFeatures", + "muteKerning", + "muteInfo", + "mutedGlyphNames", + "familyName", + "styleName", + "localisedFamilyName", + ] + + filename = posixpath_property("_filename") + path = posixpath_property("_path") + + def __init__( + self, + *, + filename=None, + path=None, + font=None, + name=None, + location=None, + designLocation=None, + layerName=None, + familyName=None, + styleName=None, + localisedFamilyName=None, + copyLib=False, + copyInfo=False, + copyGroups=False, + copyFeatures=False, + muteKerning=False, + muteInfo=False, + mutedGlyphNames=None, + ): + self.filename = filename + """string. A relative path to the source file, **as it is in the document**. + + MutatorMath + VarLib. + """ + self.path = path + """The absolute path, calculated from filename.""" + + self.font = font + """Any Python object. Optional. Points to a representation of this + source font that is loaded in memory, as a Python object (e.g. a + ``defcon.Font`` or a ``fontTools.ttFont.TTFont``). + + The default document reader will not fill-in this attribute, and the + default writer will not use this attribute. It is up to the user of + ``designspaceLib`` to either load the resource identified by + ``filename`` and store it in this field, or write the contents of + this field to the disk and make ```filename`` point to that. + """ + + self.name = name + """string. Optional. Unique identifier name for this source. + + MutatorMath + varLib. + """ + + self.designLocation = ( + designLocation if designLocation is not None else location or {} + ) + """dict. Axis values for this source, in design space coordinates. + + MutatorMath + varLib. + + This may be only part of the full design location. + See :meth:`getFullDesignLocation()` + + .. versionadded:: 5.0 + """ + + self.layerName = layerName + """string. The name of the layer in the source to look for + outline data. Default ``None`` which means ``foreground``. + """ + self.familyName = familyName + """string. Family name of this source. Though this data + can be extracted from the font, it can be efficient to have it right + here. + + varLib. + """ + self.styleName = styleName + """string. Style name of this source. Though this data + can be extracted from the font, it can be efficient to have it right + here. + + varLib. + """ + self.localisedFamilyName = localisedFamilyName or {} + """dict. A dictionary of localised family name strings, keyed by + language code. + + If present, will be used to build localized names for all instances. + + .. versionadded:: 5.0 + """ + + self.copyLib = copyLib + """bool. Indicates if the contents of the font.lib need to + be copied to the instances. + + MutatorMath. + + .. deprecated:: 5.0 + """ + self.copyInfo = copyInfo + """bool. Indicates if the non-interpolating font.info needs + to be copied to the instances. + + MutatorMath. + + .. deprecated:: 5.0 + """ + self.copyGroups = copyGroups + """bool. Indicates if the groups need to be copied to the + instances. + + MutatorMath. + + .. deprecated:: 5.0 + """ + self.copyFeatures = copyFeatures + """bool. Indicates if the feature text needs to be + copied to the instances. + + MutatorMath. + + .. deprecated:: 5.0 + """ + self.muteKerning = muteKerning + """bool. Indicates if the kerning data from this source + needs to be muted (i.e. not be part of the calculations). + + MutatorMath only. + """ + self.muteInfo = muteInfo + """bool. Indicated if the interpolating font.info data for + this source needs to be muted. + + MutatorMath only. + """ + self.mutedGlyphNames = mutedGlyphNames or [] + """list. Glyphnames that need to be muted in the + instances. + + MutatorMath only. + """ + + @property + def location(self): + """dict. Axis values for this source, in design space coordinates. + + MutatorMath + varLib. + + .. deprecated:: 5.0 + Use the more explicit alias for this property :attr:`designLocation`. + """ + return self.designLocation + + @location.setter + def location(self, location: Optional[SimpleLocationDict]): + self.designLocation = location or {} + + def setFamilyName(self, familyName, languageCode="en"): + """Setter for :attr:`localisedFamilyName` + + .. versionadded:: 5.0 + """ + self.localisedFamilyName[languageCode] = tostr(familyName) + + def getFamilyName(self, languageCode="en"): + """Getter for :attr:`localisedFamilyName` + + .. versionadded:: 5.0 + """ + return self.localisedFamilyName.get(languageCode) + + def getFullDesignLocation(self, doc: "DesignSpaceDocument") -> SimpleLocationDict: + """Get the complete design location of this source, from its + :attr:`designLocation` and the document's axis defaults. + + .. versionadded:: 5.0 + """ + result: SimpleLocationDict = {} + for axis in doc.axes: + if axis.name in self.designLocation: + result[axis.name] = self.designLocation[axis.name] + else: + result[axis.name] = axis.map_forward(axis.default) + return result + + +class RuleDescriptor(SimpleDescriptor): + """Represents the rule descriptor element: a set of glyph substitutions to + trigger conditionally in some parts of the designspace. + + .. code:: python + + r1 = RuleDescriptor() + r1.name = "unique.rule.name" + r1.conditionSets.append([dict(name="weight", minimum=-10, maximum=10), dict(...)]) + r1.conditionSets.append([dict(...), dict(...)]) + r1.subs.append(("a", "a.alt")) + + .. code:: xml + + + + + + + + + + + + + + """ + + _attrs = ["name", "conditionSets", "subs"] # what do we need here + + def __init__(self, *, name=None, conditionSets=None, subs=None): + self.name = name + """string. Unique name for this rule. Can be used to reference this rule data.""" + # list of lists of dict(name='aaaa', minimum=0, maximum=1000) + self.conditionSets = conditionSets or [] + """a list of conditionsets. + + - Each conditionset is a list of conditions. + - Each condition is a dict with ``name``, ``minimum`` and ``maximum`` keys. + """ + # list of substitutions stored as tuples of glyphnames ("a", "a.alt") + self.subs = subs or [] + """list of substitutions. + + - Each substitution is stored as tuples of glyphnames, e.g. ("a", "a.alt"). + - Note: By default, rules are applied first, before other text + shaping/OpenType layout, as they are part of the + `Required Variation Alternates OpenType feature `_. + See ref:`rules-element` § Attributes. + """ + + +def evaluateRule(rule, location): + """Return True if any of the rule's conditionsets matches the given location.""" + return any(evaluateConditions(c, location) for c in rule.conditionSets) + + +def evaluateConditions(conditions, location): + """Return True if all the conditions matches the given location. + + - If a condition has no minimum, check for < maximum. + - If a condition has no maximum, check for > minimum. + """ + for cd in conditions: + value = location[cd["name"]] + if cd.get("minimum") is None: + if value > cd["maximum"]: + return False + elif cd.get("maximum") is None: + if cd["minimum"] > value: + return False + elif not cd["minimum"] <= value <= cd["maximum"]: + return False + return True + + +def processRules(rules, location, glyphNames): + """Apply these rules at this location to these glyphnames. + + Return a new list of glyphNames with substitutions applied. + + - rule order matters + """ + newNames = [] + for rule in rules: + if evaluateRule(rule, location): + for name in glyphNames: + swap = False + for a, b in rule.subs: + if name == a: + swap = True + break + if swap: + newNames.append(b) + else: + newNames.append(name) + glyphNames = newNames + newNames = [] + return glyphNames + + +AnisotropicLocationDict = Dict[str, Union[float, Tuple[float, float]]] +SimpleLocationDict = Dict[str, float] + + +class AxisMappingDescriptor(SimpleDescriptor): + """Represents the axis mapping element: mapping an input location + to an output location in the designspace. + + .. code:: python + + m1 = AxisMappingDescriptor() + m1.inputLocation = {"weight": 900, "width": 150} + m1.outputLocation = {"weight": 870} + + .. code:: xml + + + + + + + + + + + + + """ + + _attrs = ["inputLocation", "outputLocation"] + + def __init__(self, *, inputLocation=None, outputLocation=None): + self.inputLocation: SimpleLocationDict = inputLocation or {} + """dict. Axis values for the input of the mapping, in design space coordinates. + + varLib. + + .. versionadded:: 5.1 + """ + self.outputLocation: SimpleLocationDict = outputLocation or {} + """dict. Axis values for the output of the mapping, in design space coordinates. + + varLib. + + .. versionadded:: 5.1 + """ + + +class InstanceDescriptor(SimpleDescriptor): + """Simple container for data related to the instance + + + .. code:: python + + i2 = InstanceDescriptor() + i2.path = instancePath2 + i2.familyName = "InstanceFamilyName" + i2.styleName = "InstanceStyleName" + i2.name = "instance.ufo2" + # anisotropic location + i2.designLocation = dict(weight=500, width=(400,300)) + i2.postScriptFontName = "InstancePostscriptName" + i2.styleMapFamilyName = "InstanceStyleMapFamilyName" + i2.styleMapStyleName = "InstanceStyleMapStyleName" + i2.lib['com.coolDesignspaceApp.specimenText'] = 'Hamburgerwhatever' + doc.addInstance(i2) + """ + + flavor = "instance" + _defaultLanguageCode = "en" + _attrs = [ + "filename", + "path", + "name", + "locationLabel", + "designLocation", + "userLocation", + "familyName", + "styleName", + "postScriptFontName", + "styleMapFamilyName", + "styleMapStyleName", + "localisedFamilyName", + "localisedStyleName", + "localisedStyleMapFamilyName", + "localisedStyleMapStyleName", + "glyphs", + "kerning", + "info", + "lib", + ] + + filename = posixpath_property("_filename") + path = posixpath_property("_path") + + def __init__( + self, + *, + filename=None, + path=None, + font=None, + name=None, + location=None, + locationLabel=None, + designLocation=None, + userLocation=None, + familyName=None, + styleName=None, + postScriptFontName=None, + styleMapFamilyName=None, + styleMapStyleName=None, + localisedFamilyName=None, + localisedStyleName=None, + localisedStyleMapFamilyName=None, + localisedStyleMapStyleName=None, + glyphs=None, + kerning=True, + info=True, + lib=None, + ): + self.filename = filename + """string. Relative path to the instance file, **as it is + in the document**. The file may or may not exist. + + MutatorMath + VarLib. + """ + self.path = path + """string. Absolute path to the instance file, calculated from + the document path and the string in the filename attr. The file may + or may not exist. + + MutatorMath. + """ + self.font = font + """Same as :attr:`SourceDescriptor.font` + + .. seealso:: :attr:`SourceDescriptor.font` + """ + self.name = name + """string. Unique identifier name of the instance, used to + identify it if it needs to be referenced from elsewhere in the + document. + """ + self.locationLabel = locationLabel + """Name of a :class:`LocationLabelDescriptor`. If + provided, the instance should have the same location as the + LocationLabel. + + .. seealso:: + :meth:`getFullDesignLocation` + :meth:`getFullUserLocation` + + .. versionadded:: 5.0 + """ + self.designLocation: AnisotropicLocationDict = ( + designLocation if designLocation is not None else (location or {}) + ) + """dict. Axis values for this instance, in design space coordinates. + + MutatorMath + varLib. + + .. seealso:: This may be only part of the full location. See: + :meth:`getFullDesignLocation` + :meth:`getFullUserLocation` + + .. versionadded:: 5.0 + """ + self.userLocation: SimpleLocationDict = userLocation or {} + """dict. Axis values for this instance, in user space coordinates. + + MutatorMath + varLib. + + .. seealso:: This may be only part of the full location. See: + :meth:`getFullDesignLocation` + :meth:`getFullUserLocation` + + .. versionadded:: 5.0 + """ + self.familyName = familyName + """string. Family name of this instance. + + MutatorMath + varLib. + """ + self.styleName = styleName + """string. Style name of this instance. + + MutatorMath + varLib. + """ + self.postScriptFontName = postScriptFontName + """string. Postscript fontname for this instance. + + MutatorMath + varLib. + """ + self.styleMapFamilyName = styleMapFamilyName + """string. StyleMap familyname for this instance. + + MutatorMath + varLib. + """ + self.styleMapStyleName = styleMapStyleName + """string. StyleMap stylename for this instance. + + MutatorMath + varLib. + """ + self.localisedFamilyName = localisedFamilyName or {} + """dict. A dictionary of localised family name + strings, keyed by language code. + """ + self.localisedStyleName = localisedStyleName or {} + """dict. A dictionary of localised stylename + strings, keyed by language code. + """ + self.localisedStyleMapFamilyName = localisedStyleMapFamilyName or {} + """A dictionary of localised style map + familyname strings, keyed by language code. + """ + self.localisedStyleMapStyleName = localisedStyleMapStyleName or {} + """A dictionary of localised style map + stylename strings, keyed by language code. + """ + self.glyphs = glyphs or {} + """dict for special master definitions for glyphs. If glyphs + need special masters (to record the results of executed rules for + example). + + MutatorMath. + + .. deprecated:: 5.0 + Use rules or sparse sources instead. + """ + self.kerning = kerning + """ bool. Indicates if this instance needs its kerning + calculated. + + MutatorMath. + + .. deprecated:: 5.0 + """ + self.info = info + """bool. Indicated if this instance needs the interpolating + font.info calculated. + + .. deprecated:: 5.0 + """ + + self.lib = lib or {} + """Custom data associated with this instance.""" + + @property + def location(self): + """dict. Axis values for this instance. + + MutatorMath + varLib. + + .. deprecated:: 5.0 + Use the more explicit alias for this property :attr:`designLocation`. + """ + return self.designLocation + + @location.setter + def location(self, location: Optional[AnisotropicLocationDict]): + self.designLocation = location or {} + + def setStyleName(self, styleName, languageCode="en"): + """These methods give easier access to the localised names.""" + self.localisedStyleName[languageCode] = tostr(styleName) + + def getStyleName(self, languageCode="en"): + return self.localisedStyleName.get(languageCode) + + def setFamilyName(self, familyName, languageCode="en"): + self.localisedFamilyName[languageCode] = tostr(familyName) + + def getFamilyName(self, languageCode="en"): + return self.localisedFamilyName.get(languageCode) + + def setStyleMapStyleName(self, styleMapStyleName, languageCode="en"): + self.localisedStyleMapStyleName[languageCode] = tostr(styleMapStyleName) + + def getStyleMapStyleName(self, languageCode="en"): + return self.localisedStyleMapStyleName.get(languageCode) + + def setStyleMapFamilyName(self, styleMapFamilyName, languageCode="en"): + self.localisedStyleMapFamilyName[languageCode] = tostr(styleMapFamilyName) + + def getStyleMapFamilyName(self, languageCode="en"): + return self.localisedStyleMapFamilyName.get(languageCode) + + def clearLocation(self, axisName: Optional[str] = None): + """Clear all location-related fields. Ensures that + :attr:``designLocation`` and :attr:``userLocation`` are dictionaries + (possibly empty if clearing everything). + + In order to update the location of this instance wholesale, a user + should first clear all the fields, then change the field(s) for which + they have data. + + .. code:: python + + instance.clearLocation() + instance.designLocation = {'Weight': (34, 36.5), 'Width': 100} + instance.userLocation = {'Opsz': 16} + + In order to update a single axis location, the user should only clear + that axis, then edit the values: + + .. code:: python + + instance.clearLocation('Weight') + instance.designLocation['Weight'] = (34, 36.5) + + Args: + axisName: if provided, only clear the location for that axis. + + .. versionadded:: 5.0 + """ + self.locationLabel = None + if axisName is None: + self.designLocation = {} + self.userLocation = {} + else: + if self.designLocation is None: + self.designLocation = {} + if axisName in self.designLocation: + del self.designLocation[axisName] + if self.userLocation is None: + self.userLocation = {} + if axisName in self.userLocation: + del self.userLocation[axisName] + + def getLocationLabelDescriptor( + self, doc: "DesignSpaceDocument" + ) -> Optional[LocationLabelDescriptor]: + """Get the :class:`LocationLabelDescriptor` instance that matches + this instances's :attr:`locationLabel`. + + Raises if the named label can't be found. + + .. versionadded:: 5.0 + """ + if self.locationLabel is None: + return None + label = doc.getLocationLabel(self.locationLabel) + if label is None: + raise DesignSpaceDocumentError( + "InstanceDescriptor.getLocationLabelDescriptor(): " + f"unknown location label `{self.locationLabel}` in instance `{self.name}`." + ) + return label + + def getFullDesignLocation( + self, doc: "DesignSpaceDocument" + ) -> AnisotropicLocationDict: + """Get the complete design location of this instance, by combining data + from the various location fields, default axis values and mappings, and + top-level location labels. + + The source of truth for this instance's location is determined for each + axis independently by taking the first not-None field in this list: + + - ``locationLabel``: the location along this axis is the same as the + matching STAT format 4 label. No anisotropy. + - ``designLocation[axisName]``: the explicit design location along this + axis, possibly anisotropic. + - ``userLocation[axisName]``: the explicit user location along this + axis. No anisotropy. + - ``axis.default``: default axis value. No anisotropy. + + .. versionadded:: 5.0 + """ + label = self.getLocationLabelDescriptor(doc) + if label is not None: + return doc.map_forward(label.userLocation) # type: ignore + result: AnisotropicLocationDict = {} + for axis in doc.axes: + if axis.name in self.designLocation: + result[axis.name] = self.designLocation[axis.name] + elif axis.name in self.userLocation: + result[axis.name] = axis.map_forward(self.userLocation[axis.name]) + else: + result[axis.name] = axis.map_forward(axis.default) + return result + + def getFullUserLocation(self, doc: "DesignSpaceDocument") -> SimpleLocationDict: + """Get the complete user location for this instance. + + .. seealso:: :meth:`getFullDesignLocation` + + .. versionadded:: 5.0 + """ + return doc.map_backward(self.getFullDesignLocation(doc)) + + +def tagForAxisName(name): + # try to find or make a tag name for this axis name + names = { + "weight": ("wght", dict(en="Weight")), + "width": ("wdth", dict(en="Width")), + "optical": ("opsz", dict(en="Optical Size")), + "slant": ("slnt", dict(en="Slant")), + "italic": ("ital", dict(en="Italic")), + } + if name.lower() in names: + return names[name.lower()] + if len(name) < 4: + tag = name + "*" * (4 - len(name)) + else: + tag = name[:4] + return tag, dict(en=name) + + +class AbstractAxisDescriptor(SimpleDescriptor): + flavor = "axis" + + def __init__( + self, + *, + tag=None, + name=None, + labelNames=None, + hidden=False, + map=None, + axisOrdering=None, + axisLabels=None, + ): + # opentype tag for this axis + self.tag = tag + """string. Four letter tag for this axis. Some might be + registered at the `OpenType + specification `__. + Privately-defined axis tags must begin with an uppercase letter and + use only uppercase letters or digits. + """ + # name of the axis used in locations + self.name = name + """string. Name of the axis as it is used in the location dicts. + + MutatorMath + varLib. + """ + # names for UI purposes, if this is not a standard axis, + self.labelNames = labelNames or {} + """dict. When defining a non-registered axis, it will be + necessary to define user-facing readable names for the axis. Keyed by + xml:lang code. Values are required to be ``unicode`` strings, even if + they only contain ASCII characters. + """ + self.hidden = hidden + """bool. Whether this axis should be hidden in user interfaces. + """ + self.map = map or [] + """list of input / output values that can describe a warp of user space + to design space coordinates. If no map values are present, it is assumed + user space is the same as design space, as in [(minimum, minimum), + (maximum, maximum)]. + + varLib. + """ + self.axisOrdering = axisOrdering + """STAT table field ``axisOrdering``. + + See: `OTSpec STAT Axis Record `_ + + .. versionadded:: 5.0 + """ + self.axisLabels: List[AxisLabelDescriptor] = axisLabels or [] + """STAT table entries for Axis Value Tables format 1, 2, 3. + + See: `OTSpec STAT Axis Value Tables `_ + + .. versionadded:: 5.0 + """ + + +class AxisDescriptor(AbstractAxisDescriptor): + """Simple container for the axis data. + + Add more localisations? + + .. code:: python + + a1 = AxisDescriptor() + a1.minimum = 1 + a1.maximum = 1000 + a1.default = 400 + a1.name = "weight" + a1.tag = "wght" + a1.labelNames['fa-IR'] = "قطر" + a1.labelNames['en'] = "Wéíght" + a1.map = [(1.0, 10.0), (400.0, 66.0), (1000.0, 990.0)] + a1.axisOrdering = 1 + a1.axisLabels = [ + AxisLabelDescriptor(name="Regular", userValue=400, elidable=True) + ] + doc.addAxis(a1) + """ + + _attrs = [ + "tag", + "name", + "maximum", + "minimum", + "default", + "map", + "axisOrdering", + "axisLabels", + ] + + def __init__( + self, + *, + tag=None, + name=None, + labelNames=None, + minimum=None, + default=None, + maximum=None, + hidden=False, + map=None, + axisOrdering=None, + axisLabels=None, + ): + super().__init__( + tag=tag, + name=name, + labelNames=labelNames, + hidden=hidden, + map=map, + axisOrdering=axisOrdering, + axisLabels=axisLabels, + ) + self.minimum = minimum + """number. The minimum value for this axis in user space. + + MutatorMath + varLib. + """ + self.maximum = maximum + """number. The maximum value for this axis in user space. + + MutatorMath + varLib. + """ + self.default = default + """number. The default value for this axis, i.e. when a new location is + created, this is the value this axis will get in user space. + + MutatorMath + varLib. + """ + + def serialize(self): + # output to a dict, used in testing + return dict( + tag=self.tag, + name=self.name, + labelNames=self.labelNames, + maximum=self.maximum, + minimum=self.minimum, + default=self.default, + hidden=self.hidden, + map=self.map, + axisOrdering=self.axisOrdering, + axisLabels=self.axisLabels, + ) + + def map_forward(self, v): + """Maps value from axis mapping's input (user) to output (design).""" + from fontTools.varLib.models import piecewiseLinearMap + + if not self.map: + return v + return piecewiseLinearMap(v, {k: v for k, v in self.map}) + + def map_backward(self, v): + """Maps value from axis mapping's output (design) to input (user).""" + from fontTools.varLib.models import piecewiseLinearMap + + if isinstance(v, tuple): + v = v[0] + if not self.map: + return v + return piecewiseLinearMap(v, {v: k for k, v in self.map}) + + +class DiscreteAxisDescriptor(AbstractAxisDescriptor): + """Container for discrete axis data. + + Use this for axes that do not interpolate. The main difference from a + continuous axis is that a continuous axis has a ``minimum`` and ``maximum``, + while a discrete axis has a list of ``values``. + + Example: an Italic axis with 2 stops, Roman and Italic, that are not + compatible. The axis still allows to bind together the full font family, + which is useful for the STAT table, however it can't become a variation + axis in a VF. + + .. code:: python + + a2 = DiscreteAxisDescriptor() + a2.values = [0, 1] + a2.default = 0 + a2.name = "Italic" + a2.tag = "ITAL" + a2.labelNames['fr'] = "Italique" + a2.map = [(0, 0), (1, -11)] + a2.axisOrdering = 2 + a2.axisLabels = [ + AxisLabelDescriptor(name="Roman", userValue=0, elidable=True) + ] + doc.addAxis(a2) + + .. versionadded:: 5.0 + """ + + flavor = "axis" + _attrs = ("tag", "name", "values", "default", "map", "axisOrdering", "axisLabels") + + def __init__( + self, + *, + tag=None, + name=None, + labelNames=None, + values=None, + default=None, + hidden=False, + map=None, + axisOrdering=None, + axisLabels=None, + ): + super().__init__( + tag=tag, + name=name, + labelNames=labelNames, + hidden=hidden, + map=map, + axisOrdering=axisOrdering, + axisLabels=axisLabels, + ) + self.default: float = default + """The default value for this axis, i.e. when a new location is + created, this is the value this axis will get in user space. + + However, this default value is less important than in continuous axes: + + - it doesn't define the "neutral" version of outlines from which + deltas would apply, as this axis does not interpolate. + - it doesn't provide the reference glyph set for the designspace, as + fonts at each value can have different glyph sets. + """ + self.values: List[float] = values or [] + """List of possible values for this axis. Contrary to continuous axes, + only the values in this list can be taken by the axis, nothing in-between. + """ + + def map_forward(self, value): + """Maps value from axis mapping's input to output. + + Returns value unchanged if no mapping entry is found. + + Note: for discrete axes, each value must have its mapping entry, if + you intend that value to be mapped. + """ + return next((v for k, v in self.map if k == value), value) + + def map_backward(self, value): + """Maps value from axis mapping's output to input. + + Returns value unchanged if no mapping entry is found. + + Note: for discrete axes, each value must have its mapping entry, if + you intend that value to be mapped. + """ + if isinstance(value, tuple): + value = value[0] + return next((k for k, v in self.map if v == value), value) + + +class AxisLabelDescriptor(SimpleDescriptor): + """Container for axis label data. + + Analogue of OpenType's STAT data for a single axis (formats 1, 2 and 3). + All values are user values. + See: `OTSpec STAT Axis value table, format 1, 2, 3 `_ + + The STAT format of the Axis value depends on which field are filled-in, + see :meth:`getFormat` + + .. versionadded:: 5.0 + """ + + flavor = "label" + _attrs = ( + "userMinimum", + "userValue", + "userMaximum", + "name", + "elidable", + "olderSibling", + "linkedUserValue", + "labelNames", + ) + + def __init__( + self, + *, + name, + userValue, + userMinimum=None, + userMaximum=None, + elidable=False, + olderSibling=False, + linkedUserValue=None, + labelNames=None, + ): + self.userMinimum: Optional[float] = userMinimum + """STAT field ``rangeMinValue`` (format 2).""" + self.userValue: float = userValue + """STAT field ``value`` (format 1, 3) or ``nominalValue`` (format 2).""" + self.userMaximum: Optional[float] = userMaximum + """STAT field ``rangeMaxValue`` (format 2).""" + self.name: str = name + """Label for this axis location, STAT field ``valueNameID``.""" + self.elidable: bool = elidable + """STAT flag ``ELIDABLE_AXIS_VALUE_NAME``. + + See: `OTSpec STAT Flags `_ + """ + self.olderSibling: bool = olderSibling + """STAT flag ``OLDER_SIBLING_FONT_ATTRIBUTE``. + + See: `OTSpec STAT Flags `_ + """ + self.linkedUserValue: Optional[float] = linkedUserValue + """STAT field ``linkedValue`` (format 3).""" + self.labelNames: MutableMapping[str, str] = labelNames or {} + """User-facing translations of this location's label. Keyed by + ``xml:lang`` code. + """ + + def getFormat(self) -> int: + """Determine which format of STAT Axis value to use to encode this label. + + =========== ========= =========== =========== =============== + STAT Format userValue userMinimum userMaximum linkedUserValue + =========== ========= =========== =========== =============== + 1 ✅ ❌ ❌ ❌ + 2 ✅ ✅ ✅ ❌ + 3 ✅ ❌ ❌ ✅ + =========== ========= =========== =========== =============== + """ + if self.linkedUserValue is not None: + return 3 + if self.userMinimum is not None or self.userMaximum is not None: + return 2 + return 1 + + @property + def defaultName(self) -> str: + """Return the English name from :attr:`labelNames` or the :attr:`name`.""" + return self.labelNames.get("en") or self.name + + +class LocationLabelDescriptor(SimpleDescriptor): + """Container for location label data. + + Analogue of OpenType's STAT data for a free-floating location (format 4). + All values are user values. + + See: `OTSpec STAT Axis value table, format 4 `_ + + .. versionadded:: 5.0 + """ + + flavor = "label" + _attrs = ("name", "elidable", "olderSibling", "userLocation", "labelNames") + + def __init__( + self, + *, + name, + userLocation, + elidable=False, + olderSibling=False, + labelNames=None, + ): + self.name: str = name + """Label for this named location, STAT field ``valueNameID``.""" + self.userLocation: SimpleLocationDict = userLocation or {} + """Location in user coordinates along each axis. + + If an axis is not mentioned, it is assumed to be at its default location. + + .. seealso:: This may be only part of the full location. See: + :meth:`getFullUserLocation` + """ + self.elidable: bool = elidable + """STAT flag ``ELIDABLE_AXIS_VALUE_NAME``. + + See: `OTSpec STAT Flags `_ + """ + self.olderSibling: bool = olderSibling + """STAT flag ``OLDER_SIBLING_FONT_ATTRIBUTE``. + + See: `OTSpec STAT Flags `_ + """ + self.labelNames: Dict[str, str] = labelNames or {} + """User-facing translations of this location's label. Keyed by + xml:lang code. + """ + + @property + def defaultName(self) -> str: + """Return the English name from :attr:`labelNames` or the :attr:`name`.""" + return self.labelNames.get("en") or self.name + + def getFullUserLocation(self, doc: "DesignSpaceDocument") -> SimpleLocationDict: + """Get the complete user location of this label, by combining data + from the explicit user location and default axis values. + + .. versionadded:: 5.0 + """ + return { + axis.name: self.userLocation.get(axis.name, axis.default) + for axis in doc.axes + } + + +class VariableFontDescriptor(SimpleDescriptor): + """Container for variable fonts, sub-spaces of the Designspace. + + Use-cases: + + - From a single DesignSpace with discrete axes, define 1 variable font + per value on the discrete axes. Before version 5, you would have needed + 1 DesignSpace per such variable font, and a lot of data duplication. + - From a big variable font with many axes, define subsets of that variable + font that only include some axes and freeze other axes at a given location. + + .. versionadded:: 5.0 + """ + + flavor = "variable-font" + _attrs = ("filename", "axisSubsets", "lib") + + filename = posixpath_property("_filename") + + def __init__(self, *, name, filename=None, axisSubsets=None, lib=None): + self.name: str = name + """string, required. Name of this variable to identify it during the + build process and from other parts of the document, and also as a + filename in case the filename property is empty. + + VarLib. + """ + self.filename: str = filename + """string, optional. Relative path to the variable font file, **as it is + in the document**. The file may or may not exist. + + If not specified, the :attr:`name` will be used as a basename for the file. + """ + self.axisSubsets: List[ + Union[RangeAxisSubsetDescriptor, ValueAxisSubsetDescriptor] + ] = (axisSubsets or []) + """Axis subsets to include in this variable font. + + If an axis is not mentioned, assume that we only want the default + location of that axis (same as a :class:`ValueAxisSubsetDescriptor`). + """ + self.lib: MutableMapping[str, Any] = lib or {} + """Custom data associated with this variable font.""" + + +class RangeAxisSubsetDescriptor(SimpleDescriptor): + """Subset of a continuous axis to include in a variable font. + + .. versionadded:: 5.0 + """ + + flavor = "axis-subset" + _attrs = ("name", "userMinimum", "userDefault", "userMaximum") + + def __init__( + self, *, name, userMinimum=-math.inf, userDefault=None, userMaximum=math.inf + ): + self.name: str = name + """Name of the :class:`AxisDescriptor` to subset.""" + self.userMinimum: float = userMinimum + """New minimum value of the axis in the target variable font. + If not specified, assume the same minimum value as the full axis. + (default = ``-math.inf``) + """ + self.userDefault: Optional[float] = userDefault + """New default value of the axis in the target variable font. + If not specified, assume the same default value as the full axis. + (default = ``None``) + """ + self.userMaximum: float = userMaximum + """New maximum value of the axis in the target variable font. + If not specified, assume the same maximum value as the full axis. + (default = ``math.inf``) + """ + + +class ValueAxisSubsetDescriptor(SimpleDescriptor): + """Single value of a discrete or continuous axis to use in a variable font. + + .. versionadded:: 5.0 + """ + + flavor = "axis-subset" + _attrs = ("name", "userValue") + + def __init__(self, *, name, userValue): + self.name: str = name + """Name of the :class:`AxisDescriptor` or :class:`DiscreteAxisDescriptor` + to "snapshot" or "freeze". + """ + self.userValue: float = userValue + """Value in user coordinates at which to freeze the given axis.""" + + +class BaseDocWriter(object): + _whiteSpace = " " + axisDescriptorClass = AxisDescriptor + discreteAxisDescriptorClass = DiscreteAxisDescriptor + axisLabelDescriptorClass = AxisLabelDescriptor + axisMappingDescriptorClass = AxisMappingDescriptor + locationLabelDescriptorClass = LocationLabelDescriptor + ruleDescriptorClass = RuleDescriptor + sourceDescriptorClass = SourceDescriptor + variableFontDescriptorClass = VariableFontDescriptor + valueAxisSubsetDescriptorClass = ValueAxisSubsetDescriptor + rangeAxisSubsetDescriptorClass = RangeAxisSubsetDescriptor + instanceDescriptorClass = InstanceDescriptor + + @classmethod + def getAxisDecriptor(cls): + return cls.axisDescriptorClass() + + @classmethod + def getAxisMappingDescriptor(cls): + return cls.axisMappingDescriptorClass() + + @classmethod + def getSourceDescriptor(cls): + return cls.sourceDescriptorClass() + + @classmethod + def getInstanceDescriptor(cls): + return cls.instanceDescriptorClass() + + @classmethod + def getRuleDescriptor(cls): + return cls.ruleDescriptorClass() + + def __init__(self, documentPath, documentObject: DesignSpaceDocument): + self.path = documentPath + self.documentObject = documentObject + self.effectiveFormatTuple = self._getEffectiveFormatTuple() + self.root = ET.Element("designspace") + + def write(self, pretty=True, encoding="UTF-8", xml_declaration=True): + self.root.attrib["format"] = ".".join(str(i) for i in self.effectiveFormatTuple) + + if ( + self.documentObject.axes + or self.documentObject.axisMappings + or self.documentObject.elidedFallbackName is not None + ): + axesElement = ET.Element("axes") + if self.documentObject.elidedFallbackName is not None: + axesElement.attrib[ + "elidedfallbackname" + ] = self.documentObject.elidedFallbackName + self.root.append(axesElement) + for axisObject in self.documentObject.axes: + self._addAxis(axisObject) + + if self.documentObject.axisMappings: + mappingsElement = ET.Element("mappings") + self.root.findall(".axes")[0].append(mappingsElement) + for mappingObject in self.documentObject.axisMappings: + self._addAxisMapping(mappingsElement, mappingObject) + + if self.documentObject.locationLabels: + labelsElement = ET.Element("labels") + for labelObject in self.documentObject.locationLabels: + self._addLocationLabel(labelsElement, labelObject) + self.root.append(labelsElement) + + if self.documentObject.rules: + if getattr(self.documentObject, "rulesProcessingLast", False): + attributes = {"processing": "last"} + else: + attributes = {} + self.root.append(ET.Element("rules", attributes)) + for ruleObject in self.documentObject.rules: + self._addRule(ruleObject) + + if self.documentObject.sources: + self.root.append(ET.Element("sources")) + for sourceObject in self.documentObject.sources: + self._addSource(sourceObject) + + if self.documentObject.variableFonts: + variableFontsElement = ET.Element("variable-fonts") + for variableFont in self.documentObject.variableFonts: + self._addVariableFont(variableFontsElement, variableFont) + self.root.append(variableFontsElement) + + if self.documentObject.instances: + self.root.append(ET.Element("instances")) + for instanceObject in self.documentObject.instances: + self._addInstance(instanceObject) + + if self.documentObject.lib: + self._addLib(self.root, self.documentObject.lib, 2) + + tree = ET.ElementTree(self.root) + tree.write( + self.path, + encoding=encoding, + method="xml", + xml_declaration=xml_declaration, + pretty_print=pretty, + ) + + def _getEffectiveFormatTuple(self): + """Try to use the version specified in the document, or a sufficiently + recent version to be able to encode what the document contains. + """ + minVersion = self.documentObject.formatTuple + if ( + any( + hasattr(axis, "values") + or axis.axisOrdering is not None + or axis.axisLabels + for axis in self.documentObject.axes + ) + or self.documentObject.locationLabels + or any(source.localisedFamilyName for source in self.documentObject.sources) + or self.documentObject.variableFonts + or any( + instance.locationLabel or instance.userLocation + for instance in self.documentObject.instances + ) + ): + if minVersion < (5, 0): + minVersion = (5, 0) + if self.documentObject.axisMappings: + if minVersion < (5, 1): + minVersion = (5, 1) + return minVersion + + def _makeLocationElement(self, locationObject, name=None): + """Convert Location dict to a locationElement.""" + locElement = ET.Element("location") + if name is not None: + locElement.attrib["name"] = name + validatedLocation = self.documentObject.newDefaultLocation() + for axisName, axisValue in locationObject.items(): + if axisName in validatedLocation: + # only accept values we know + validatedLocation[axisName] = axisValue + for dimensionName, dimensionValue in validatedLocation.items(): + dimElement = ET.Element("dimension") + dimElement.attrib["name"] = dimensionName + if type(dimensionValue) == tuple: + dimElement.attrib["xvalue"] = self.intOrFloat(dimensionValue[0]) + dimElement.attrib["yvalue"] = self.intOrFloat(dimensionValue[1]) + else: + dimElement.attrib["xvalue"] = self.intOrFloat(dimensionValue) + locElement.append(dimElement) + return locElement, validatedLocation + + def intOrFloat(self, num): + if int(num) == num: + return "%d" % num + return ("%f" % num).rstrip("0").rstrip(".") + + def _addRule(self, ruleObject): + # if none of the conditions have minimum or maximum values, do not add the rule. + ruleElement = ET.Element("rule") + if ruleObject.name is not None: + ruleElement.attrib["name"] = ruleObject.name + for conditions in ruleObject.conditionSets: + conditionsetElement = ET.Element("conditionset") + for cond in conditions: + if cond.get("minimum") is None and cond.get("maximum") is None: + # neither is defined, don't add this condition + continue + conditionElement = ET.Element("condition") + conditionElement.attrib["name"] = cond.get("name") + if cond.get("minimum") is not None: + conditionElement.attrib["minimum"] = self.intOrFloat( + cond.get("minimum") + ) + if cond.get("maximum") is not None: + conditionElement.attrib["maximum"] = self.intOrFloat( + cond.get("maximum") + ) + conditionsetElement.append(conditionElement) + if len(conditionsetElement): + ruleElement.append(conditionsetElement) + for sub in ruleObject.subs: + subElement = ET.Element("sub") + subElement.attrib["name"] = sub[0] + subElement.attrib["with"] = sub[1] + ruleElement.append(subElement) + if len(ruleElement): + self.root.findall(".rules")[0].append(ruleElement) + + def _addAxis(self, axisObject): + axisElement = ET.Element("axis") + axisElement.attrib["tag"] = axisObject.tag + axisElement.attrib["name"] = axisObject.name + self._addLabelNames(axisElement, axisObject.labelNames) + if axisObject.map: + for inputValue, outputValue in axisObject.map: + mapElement = ET.Element("map") + mapElement.attrib["input"] = self.intOrFloat(inputValue) + mapElement.attrib["output"] = self.intOrFloat(outputValue) + axisElement.append(mapElement) + if axisObject.axisOrdering or axisObject.axisLabels: + labelsElement = ET.Element("labels") + if axisObject.axisOrdering is not None: + labelsElement.attrib["ordering"] = str(axisObject.axisOrdering) + for label in axisObject.axisLabels: + self._addAxisLabel(labelsElement, label) + axisElement.append(labelsElement) + if hasattr(axisObject, "minimum"): + axisElement.attrib["minimum"] = self.intOrFloat(axisObject.minimum) + axisElement.attrib["maximum"] = self.intOrFloat(axisObject.maximum) + elif hasattr(axisObject, "values"): + axisElement.attrib["values"] = " ".join( + self.intOrFloat(v) for v in axisObject.values + ) + axisElement.attrib["default"] = self.intOrFloat(axisObject.default) + if axisObject.hidden: + axisElement.attrib["hidden"] = "1" + self.root.findall(".axes")[0].append(axisElement) + + def _addAxisMapping(self, mappingsElement, mappingObject): + mappingElement = ET.Element("mapping") + for what in ("inputLocation", "outputLocation"): + whatObject = getattr(mappingObject, what, None) + if whatObject is None: + continue + whatElement = ET.Element(what[:-8]) + mappingElement.append(whatElement) + + for name, value in whatObject.items(): + dimensionElement = ET.Element("dimension") + dimensionElement.attrib["name"] = name + dimensionElement.attrib["xvalue"] = self.intOrFloat(value) + whatElement.append(dimensionElement) + + mappingsElement.append(mappingElement) + + def _addAxisLabel( + self, axisElement: ET.Element, label: AxisLabelDescriptor + ) -> None: + labelElement = ET.Element("label") + labelElement.attrib["uservalue"] = self.intOrFloat(label.userValue) + if label.userMinimum is not None: + labelElement.attrib["userminimum"] = self.intOrFloat(label.userMinimum) + if label.userMaximum is not None: + labelElement.attrib["usermaximum"] = self.intOrFloat(label.userMaximum) + labelElement.attrib["name"] = label.name + if label.elidable: + labelElement.attrib["elidable"] = "true" + if label.olderSibling: + labelElement.attrib["oldersibling"] = "true" + if label.linkedUserValue is not None: + labelElement.attrib["linkeduservalue"] = self.intOrFloat( + label.linkedUserValue + ) + self._addLabelNames(labelElement, label.labelNames) + axisElement.append(labelElement) + + def _addLabelNames(self, parentElement, labelNames): + for languageCode, labelName in sorted(labelNames.items()): + languageElement = ET.Element("labelname") + languageElement.attrib[XML_LANG] = languageCode + languageElement.text = labelName + parentElement.append(languageElement) + + def _addLocationLabel( + self, parentElement: ET.Element, label: LocationLabelDescriptor + ) -> None: + labelElement = ET.Element("label") + labelElement.attrib["name"] = label.name + if label.elidable: + labelElement.attrib["elidable"] = "true" + if label.olderSibling: + labelElement.attrib["oldersibling"] = "true" + self._addLabelNames(labelElement, label.labelNames) + self._addLocationElement(labelElement, userLocation=label.userLocation) + parentElement.append(labelElement) + + def _addLocationElement( + self, + parentElement, + *, + designLocation: AnisotropicLocationDict = None, + userLocation: SimpleLocationDict = None, + ): + locElement = ET.Element("location") + for axis in self.documentObject.axes: + if designLocation is not None and axis.name in designLocation: + dimElement = ET.Element("dimension") + dimElement.attrib["name"] = axis.name + value = designLocation[axis.name] + if isinstance(value, tuple): + dimElement.attrib["xvalue"] = self.intOrFloat(value[0]) + dimElement.attrib["yvalue"] = self.intOrFloat(value[1]) + else: + dimElement.attrib["xvalue"] = self.intOrFloat(value) + locElement.append(dimElement) + elif userLocation is not None and axis.name in userLocation: + dimElement = ET.Element("dimension") + dimElement.attrib["name"] = axis.name + value = userLocation[axis.name] + dimElement.attrib["uservalue"] = self.intOrFloat(value) + locElement.append(dimElement) + if len(locElement) > 0: + parentElement.append(locElement) + + def _addInstance(self, instanceObject): + instanceElement = ET.Element("instance") + if instanceObject.name is not None: + instanceElement.attrib["name"] = instanceObject.name + if instanceObject.locationLabel is not None: + instanceElement.attrib["location"] = instanceObject.locationLabel + if instanceObject.familyName is not None: + instanceElement.attrib["familyname"] = instanceObject.familyName + if instanceObject.styleName is not None: + instanceElement.attrib["stylename"] = instanceObject.styleName + # add localisations + if instanceObject.localisedStyleName: + languageCodes = list(instanceObject.localisedStyleName.keys()) + languageCodes.sort() + for code in languageCodes: + if code == "en": + continue # already stored in the element attribute + localisedStyleNameElement = ET.Element("stylename") + localisedStyleNameElement.attrib[XML_LANG] = code + localisedStyleNameElement.text = instanceObject.getStyleName(code) + instanceElement.append(localisedStyleNameElement) + if instanceObject.localisedFamilyName: + languageCodes = list(instanceObject.localisedFamilyName.keys()) + languageCodes.sort() + for code in languageCodes: + if code == "en": + continue # already stored in the element attribute + localisedFamilyNameElement = ET.Element("familyname") + localisedFamilyNameElement.attrib[XML_LANG] = code + localisedFamilyNameElement.text = instanceObject.getFamilyName(code) + instanceElement.append(localisedFamilyNameElement) + if instanceObject.localisedStyleMapStyleName: + languageCodes = list(instanceObject.localisedStyleMapStyleName.keys()) + languageCodes.sort() + for code in languageCodes: + if code == "en": + continue + localisedStyleMapStyleNameElement = ET.Element("stylemapstylename") + localisedStyleMapStyleNameElement.attrib[XML_LANG] = code + localisedStyleMapStyleNameElement.text = ( + instanceObject.getStyleMapStyleName(code) + ) + instanceElement.append(localisedStyleMapStyleNameElement) + if instanceObject.localisedStyleMapFamilyName: + languageCodes = list(instanceObject.localisedStyleMapFamilyName.keys()) + languageCodes.sort() + for code in languageCodes: + if code == "en": + continue + localisedStyleMapFamilyNameElement = ET.Element("stylemapfamilyname") + localisedStyleMapFamilyNameElement.attrib[XML_LANG] = code + localisedStyleMapFamilyNameElement.text = ( + instanceObject.getStyleMapFamilyName(code) + ) + instanceElement.append(localisedStyleMapFamilyNameElement) + + if self.effectiveFormatTuple >= (5, 0): + if instanceObject.locationLabel is None: + self._addLocationElement( + instanceElement, + designLocation=instanceObject.designLocation, + userLocation=instanceObject.userLocation, + ) + else: + # Pre-version 5.0 code was validating and filling in the location + # dict while writing it out, as preserved below. + if instanceObject.location is not None: + locationElement, instanceObject.location = self._makeLocationElement( + instanceObject.location + ) + instanceElement.append(locationElement) + if instanceObject.filename is not None: + instanceElement.attrib["filename"] = instanceObject.filename + if instanceObject.postScriptFontName is not None: + instanceElement.attrib[ + "postscriptfontname" + ] = instanceObject.postScriptFontName + if instanceObject.styleMapFamilyName is not None: + instanceElement.attrib[ + "stylemapfamilyname" + ] = instanceObject.styleMapFamilyName + if instanceObject.styleMapStyleName is not None: + instanceElement.attrib[ + "stylemapstylename" + ] = instanceObject.styleMapStyleName + if self.effectiveFormatTuple < (5, 0): + # Deprecated members as of version 5.0 + if instanceObject.glyphs: + if instanceElement.findall(".glyphs") == []: + glyphsElement = ET.Element("glyphs") + instanceElement.append(glyphsElement) + glyphsElement = instanceElement.findall(".glyphs")[0] + for glyphName, data in sorted(instanceObject.glyphs.items()): + glyphElement = self._writeGlyphElement( + instanceElement, instanceObject, glyphName, data + ) + glyphsElement.append(glyphElement) + if instanceObject.kerning: + kerningElement = ET.Element("kerning") + instanceElement.append(kerningElement) + if instanceObject.info: + infoElement = ET.Element("info") + instanceElement.append(infoElement) + self._addLib(instanceElement, instanceObject.lib, 4) + self.root.findall(".instances")[0].append(instanceElement) + + def _addSource(self, sourceObject): + sourceElement = ET.Element("source") + if sourceObject.filename is not None: + sourceElement.attrib["filename"] = sourceObject.filename + if sourceObject.name is not None: + if sourceObject.name.find("temp_master") != 0: + # do not save temporary source names + sourceElement.attrib["name"] = sourceObject.name + if sourceObject.familyName is not None: + sourceElement.attrib["familyname"] = sourceObject.familyName + if sourceObject.styleName is not None: + sourceElement.attrib["stylename"] = sourceObject.styleName + if sourceObject.layerName is not None: + sourceElement.attrib["layer"] = sourceObject.layerName + if sourceObject.localisedFamilyName: + languageCodes = list(sourceObject.localisedFamilyName.keys()) + languageCodes.sort() + for code in languageCodes: + if code == "en": + continue # already stored in the element attribute + localisedFamilyNameElement = ET.Element("familyname") + localisedFamilyNameElement.attrib[XML_LANG] = code + localisedFamilyNameElement.text = sourceObject.getFamilyName(code) + sourceElement.append(localisedFamilyNameElement) + if sourceObject.copyLib: + libElement = ET.Element("lib") + libElement.attrib["copy"] = "1" + sourceElement.append(libElement) + if sourceObject.copyGroups: + groupsElement = ET.Element("groups") + groupsElement.attrib["copy"] = "1" + sourceElement.append(groupsElement) + if sourceObject.copyFeatures: + featuresElement = ET.Element("features") + featuresElement.attrib["copy"] = "1" + sourceElement.append(featuresElement) + if sourceObject.copyInfo or sourceObject.muteInfo: + infoElement = ET.Element("info") + if sourceObject.copyInfo: + infoElement.attrib["copy"] = "1" + if sourceObject.muteInfo: + infoElement.attrib["mute"] = "1" + sourceElement.append(infoElement) + if sourceObject.muteKerning: + kerningElement = ET.Element("kerning") + kerningElement.attrib["mute"] = "1" + sourceElement.append(kerningElement) + if sourceObject.mutedGlyphNames: + for name in sourceObject.mutedGlyphNames: + glyphElement = ET.Element("glyph") + glyphElement.attrib["name"] = name + glyphElement.attrib["mute"] = "1" + sourceElement.append(glyphElement) + if self.effectiveFormatTuple >= (5, 0): + self._addLocationElement( + sourceElement, designLocation=sourceObject.location + ) + else: + # Pre-version 5.0 code was validating and filling in the location + # dict while writing it out, as preserved below. + locationElement, sourceObject.location = self._makeLocationElement( + sourceObject.location + ) + sourceElement.append(locationElement) + self.root.findall(".sources")[0].append(sourceElement) + + def _addVariableFont( + self, parentElement: ET.Element, vf: VariableFontDescriptor + ) -> None: + vfElement = ET.Element("variable-font") + vfElement.attrib["name"] = vf.name + if vf.filename is not None: + vfElement.attrib["filename"] = vf.filename + if vf.axisSubsets: + subsetsElement = ET.Element("axis-subsets") + for subset in vf.axisSubsets: + subsetElement = ET.Element("axis-subset") + subsetElement.attrib["name"] = subset.name + # Mypy doesn't support narrowing union types via hasattr() + # https://mypy.readthedocs.io/en/stable/type_narrowing.html + # TODO(Python 3.10): use TypeGuard + if hasattr(subset, "userMinimum"): + subset = cast(RangeAxisSubsetDescriptor, subset) + if subset.userMinimum != -math.inf: + subsetElement.attrib["userminimum"] = self.intOrFloat( + subset.userMinimum + ) + if subset.userMaximum != math.inf: + subsetElement.attrib["usermaximum"] = self.intOrFloat( + subset.userMaximum + ) + if subset.userDefault is not None: + subsetElement.attrib["userdefault"] = self.intOrFloat( + subset.userDefault + ) + elif hasattr(subset, "userValue"): + subset = cast(ValueAxisSubsetDescriptor, subset) + subsetElement.attrib["uservalue"] = self.intOrFloat( + subset.userValue + ) + subsetsElement.append(subsetElement) + vfElement.append(subsetsElement) + self._addLib(vfElement, vf.lib, 4) + parentElement.append(vfElement) + + def _addLib(self, parentElement: ET.Element, data: Any, indent_level: int) -> None: + if not data: + return + libElement = ET.Element("lib") + libElement.append(plistlib.totree(data, indent_level=indent_level)) + parentElement.append(libElement) + + def _writeGlyphElement(self, instanceElement, instanceObject, glyphName, data): + glyphElement = ET.Element("glyph") + if data.get("mute"): + glyphElement.attrib["mute"] = "1" + if data.get("unicodes") is not None: + glyphElement.attrib["unicode"] = " ".join( + [hex(u) for u in data.get("unicodes")] + ) + if data.get("instanceLocation") is not None: + locationElement, data["instanceLocation"] = self._makeLocationElement( + data.get("instanceLocation") + ) + glyphElement.append(locationElement) + if glyphName is not None: + glyphElement.attrib["name"] = glyphName + if data.get("note") is not None: + noteElement = ET.Element("note") + noteElement.text = data.get("note") + glyphElement.append(noteElement) + if data.get("masters") is not None: + mastersElement = ET.Element("masters") + for m in data.get("masters"): + masterElement = ET.Element("master") + if m.get("glyphName") is not None: + masterElement.attrib["glyphname"] = m.get("glyphName") + if m.get("font") is not None: + masterElement.attrib["source"] = m.get("font") + if m.get("location") is not None: + locationElement, m["location"] = self._makeLocationElement( + m.get("location") + ) + masterElement.append(locationElement) + mastersElement.append(masterElement) + glyphElement.append(mastersElement) + return glyphElement + + +class BaseDocReader(LogMixin): + axisDescriptorClass = AxisDescriptor + discreteAxisDescriptorClass = DiscreteAxisDescriptor + axisLabelDescriptorClass = AxisLabelDescriptor + axisMappingDescriptorClass = AxisMappingDescriptor + locationLabelDescriptorClass = LocationLabelDescriptor + ruleDescriptorClass = RuleDescriptor + sourceDescriptorClass = SourceDescriptor + variableFontsDescriptorClass = VariableFontDescriptor + valueAxisSubsetDescriptorClass = ValueAxisSubsetDescriptor + rangeAxisSubsetDescriptorClass = RangeAxisSubsetDescriptor + instanceDescriptorClass = InstanceDescriptor + + def __init__(self, documentPath, documentObject): + self.path = documentPath + self.documentObject = documentObject + tree = ET.parse(self.path) + self.root = tree.getroot() + self.documentObject.formatVersion = self.root.attrib.get("format", "3.0") + self._axes = [] + self.rules = [] + self.sources = [] + self.instances = [] + self.axisDefaults = {} + self._strictAxisNames = True + + @classmethod + def fromstring(cls, string, documentObject): + f = BytesIO(tobytes(string, encoding="utf-8")) + self = cls(f, documentObject) + self.path = None + return self + + def read(self): + self.readAxes() + self.readLabels() + self.readRules() + self.readVariableFonts() + self.readSources() + self.readInstances() + self.readLib() + + def readRules(self): + # we also need to read any conditions that are outside of a condition set. + rules = [] + rulesElement = self.root.find(".rules") + if rulesElement is not None: + processingValue = rulesElement.attrib.get("processing", "first") + if processingValue not in {"first", "last"}: + raise DesignSpaceDocumentError( + " processing attribute value is not valid: %r, " + "expected 'first' or 'last'" % processingValue + ) + self.documentObject.rulesProcessingLast = processingValue == "last" + for ruleElement in self.root.findall(".rules/rule"): + ruleObject = self.ruleDescriptorClass() + ruleName = ruleObject.name = ruleElement.attrib.get("name") + # read any stray conditions outside a condition set + externalConditions = self._readConditionElements( + ruleElement, + ruleName, + ) + if externalConditions: + ruleObject.conditionSets.append(externalConditions) + self.log.info( + "Found stray rule conditions outside a conditionset. " + "Wrapped them in a new conditionset." + ) + # read the conditionsets + for conditionSetElement in ruleElement.findall(".conditionset"): + conditionSet = self._readConditionElements( + conditionSetElement, + ruleName, + ) + if conditionSet is not None: + ruleObject.conditionSets.append(conditionSet) + for subElement in ruleElement.findall(".sub"): + a = subElement.attrib["name"] + b = subElement.attrib["with"] + ruleObject.subs.append((a, b)) + rules.append(ruleObject) + self.documentObject.rules = rules + + def _readConditionElements(self, parentElement, ruleName=None): + cds = [] + for conditionElement in parentElement.findall(".condition"): + cd = {} + cdMin = conditionElement.attrib.get("minimum") + if cdMin is not None: + cd["minimum"] = float(cdMin) + else: + # will allow these to be None, assume axis.minimum + cd["minimum"] = None + cdMax = conditionElement.attrib.get("maximum") + if cdMax is not None: + cd["maximum"] = float(cdMax) + else: + # will allow these to be None, assume axis.maximum + cd["maximum"] = None + cd["name"] = conditionElement.attrib.get("name") + # # test for things + if cd.get("minimum") is None and cd.get("maximum") is None: + raise DesignSpaceDocumentError( + "condition missing required minimum or maximum in rule" + + (" '%s'" % ruleName if ruleName is not None else "") + ) + cds.append(cd) + return cds + + def readAxes(self): + # read the axes elements, including the warp map. + axesElement = self.root.find(".axes") + if axesElement is not None and "elidedfallbackname" in axesElement.attrib: + self.documentObject.elidedFallbackName = axesElement.attrib[ + "elidedfallbackname" + ] + axisElements = self.root.findall(".axes/axis") + if not axisElements: + return + for axisElement in axisElements: + if ( + self.documentObject.formatTuple >= (5, 0) + and "values" in axisElement.attrib + ): + axisObject = self.discreteAxisDescriptorClass() + axisObject.values = [ + float(s) for s in axisElement.attrib["values"].split(" ") + ] + else: + axisObject = self.axisDescriptorClass() + axisObject.minimum = float(axisElement.attrib.get("minimum")) + axisObject.maximum = float(axisElement.attrib.get("maximum")) + axisObject.default = float(axisElement.attrib.get("default")) + axisObject.name = axisElement.attrib.get("name") + if axisElement.attrib.get("hidden", False): + axisObject.hidden = True + axisObject.tag = axisElement.attrib.get("tag") + for mapElement in axisElement.findall("map"): + a = float(mapElement.attrib["input"]) + b = float(mapElement.attrib["output"]) + axisObject.map.append((a, b)) + for labelNameElement in axisElement.findall("labelname"): + # Note: elementtree reads the "xml:lang" attribute name as + # '{http://www.w3.org/XML/1998/namespace}lang' + for key, lang in labelNameElement.items(): + if key == XML_LANG: + axisObject.labelNames[lang] = tostr(labelNameElement.text) + labelElement = axisElement.find(".labels") + if labelElement is not None: + if "ordering" in labelElement.attrib: + axisObject.axisOrdering = int(labelElement.attrib["ordering"]) + for label in labelElement.findall(".label"): + axisObject.axisLabels.append(self.readAxisLabel(label)) + self.documentObject.axes.append(axisObject) + self.axisDefaults[axisObject.name] = axisObject.default + + mappingsElement = self.root.find(".axes/mappings") + self.documentObject.axisMappings = [] + if mappingsElement is not None: + for mappingElement in mappingsElement.findall("mapping"): + inputElement = mappingElement.find("input") + outputElement = mappingElement.find("output") + inputLoc = {} + outputLoc = {} + for dimElement in inputElement.findall(".dimension"): + name = dimElement.attrib["name"] + value = float(dimElement.attrib["xvalue"]) + inputLoc[name] = value + for dimElement in outputElement.findall(".dimension"): + name = dimElement.attrib["name"] + value = float(dimElement.attrib["xvalue"]) + outputLoc[name] = value + axisMappingObject = self.axisMappingDescriptorClass( + inputLocation=inputLoc, outputLocation=outputLoc + ) + self.documentObject.axisMappings.append(axisMappingObject) + + def readAxisLabel(self, element: ET.Element): + xml_attrs = { + "userminimum", + "uservalue", + "usermaximum", + "name", + "elidable", + "oldersibling", + "linkeduservalue", + } + unknown_attrs = set(element.attrib) - xml_attrs + if unknown_attrs: + raise DesignSpaceDocumentError( + f"label element contains unknown attributes: {', '.join(unknown_attrs)}" + ) + + name = element.get("name") + if name is None: + raise DesignSpaceDocumentError("label element must have a name attribute.") + valueStr = element.get("uservalue") + if valueStr is None: + raise DesignSpaceDocumentError( + "label element must have a uservalue attribute." + ) + value = float(valueStr) + minimumStr = element.get("userminimum") + minimum = float(minimumStr) if minimumStr is not None else None + maximumStr = element.get("usermaximum") + maximum = float(maximumStr) if maximumStr is not None else None + linkedValueStr = element.get("linkeduservalue") + linkedValue = float(linkedValueStr) if linkedValueStr is not None else None + elidable = True if element.get("elidable") == "true" else False + olderSibling = True if element.get("oldersibling") == "true" else False + labelNames = { + lang: label_name.text or "" + for label_name in element.findall("labelname") + for attr, lang in label_name.items() + if attr == XML_LANG + # Note: elementtree reads the "xml:lang" attribute name as + # '{http://www.w3.org/XML/1998/namespace}lang' + } + return self.axisLabelDescriptorClass( + name=name, + userValue=value, + userMinimum=minimum, + userMaximum=maximum, + elidable=elidable, + olderSibling=olderSibling, + linkedUserValue=linkedValue, + labelNames=labelNames, + ) + + def readLabels(self): + if self.documentObject.formatTuple < (5, 0): + return + + xml_attrs = {"name", "elidable", "oldersibling"} + for labelElement in self.root.findall(".labels/label"): + unknown_attrs = set(labelElement.attrib) - xml_attrs + if unknown_attrs: + raise DesignSpaceDocumentError( + f"Label element contains unknown attributes: {', '.join(unknown_attrs)}" + ) + + name = labelElement.get("name") + if name is None: + raise DesignSpaceDocumentError( + "label element must have a name attribute." + ) + designLocation, userLocation = self.locationFromElement(labelElement) + if designLocation: + raise DesignSpaceDocumentError( + f'_h3ggmhz>;@IW2^JwA5owu47%GVg1kqQ9V2fZKLWx)qMnQ$J zvqkU_k^W>6DkKqVKwMu;f^`U$VnH|`Duk6K#*=NMasA+zK}z)*&>C1>qT}5T;m!CPbuR7Gaqr<`Kk=hc;M;&@L8) z_n|`giAC@ck=E{N+O%2{(FMdIg!~jjwpb9hhYI2Aqm523BGOWekSB@w0^$&c!a5s< ziv{6Os1O=0LJ=a;ofe@)5}^geEzuRQ4q?1l5YB)KVWvfxgospW5h^7yogi*`n-1#` zYQ%zY9aIQoEJ8gZQh`O7C5eCn;%4_8ScfoAEC>%lg|NLvn2(6m$09UJB9?%-F}Vy@ z2+grpajcWCL(LA+`ZMFnHe?Xq&offHB*F-Yi(6O2IvYC0V#9i@k%VK7t(XIg}zh)DNZgyE8yP7p5aHM2@!9fBtogyTff8Eg?M5RvZg zXIe2{65#{HMR=7e&JPDn6$`>NQFQ!bqca^5X@a$(MiP+&#Eqy~DsB;Giv{6Ms9N!e zMVNz#G|VE*lf3h!84#no`Y%b*j0r+G_fXQr)(;@;pSO8Mg9#NrVaz7qSnBbqGab zsr*Q&Du3lD8Qf5UNadagF#^P?j)!%slVDZ(*`ic;r%{bnA|hqm%BM;qRDf)Y9&8P) zL#T%p!i}QnOtJ{G5RqQl#rSTvBtivkw9p1>tL`%s2o4|)p$OI?l!&GBQBYOBc7${q zJVYw55FsjnIMqq8PPGzNm7gz4bxVzEY$_ts@wW2ml9)0O=ev4XhcHVlmEQst!i^ST zHX_m<7GaJgq5{Ys=)um1bqI~Hvf&vep;KWInh=rJ?_?aXOcGH6#C&6tWlY8Su>!Zl z3gLYvp|guc@DY(-w+O2x5fwn(8EfeC6hbzv5VltmI&T-5T5}PRerpl(BoP%r-1<3G z#jOp)VTEw0lF*rJ5sDDY<4=@8Q1wh9JgDva2wT&$7V?)9Dwvj4R#K!Lzo9E^B+!m}tPln(352m0VJITfI=h({e zgw9SDp#l-CY(5zC$Ey7e-Axu*eIx7x0o}7+|be%=0kwiEEaW>3Saf>h; zRtR@037tP!ggJ;vqb$NaNz5aNLugcSi_iosgvCli=Uj`h3=yf9MQD}8Jc2lcb``e> zKCBQvRT4S}T7=bzNQ-k#n>r;C6?~aO$cA+YxndcU{h=C@UvVSTkx`yWy6t5Lgy)qP=bgw$|87@2o4|)VZ4glR!o8w!r4kfXNEV36&>b;|`-2kF_Hrm01K|5-|eAogQ|=I)u<_i_i-ygxf7b zHX_pg79m#>(+Lv92(S)es90`j5Uzv@;gg>lof<@>J1s)JBtivI)pi5L6{2_ z!owC}9wO2ti!fgjp#sG9MH8$;SSA*P7okG9%p$ZRBJFDt+9a_pL7WXftV38W7KE>% zLKtBYIuVgNa!i{-Um1jKh&!*$g>?vdVnNsqDuk{>jZQuy(qk53s3al=h_j&x)*+OL z1z{9a2+vyt4-sj)MW~QO-~e&k-6U9tP$?FK^PxgWScIvFNPp>LESfHfzyab~Q4i}7 zW{Cyi7N`(@ZV_f9BCYFd5aviCaDcd0%!hRdjbcG~1}cPs7NH3dX?ttKGD!pu5QoqP z>k!(-g77|62=5e_T75*M8PWL|UBa4hSB6U>et@_URRZe}Jh31g2Nl8_ zhZvm-M5I|3VZ0>b2Z%cisDyP0Q^kTX4Jw4+TZHL|NE0kVjU?g+h#L>HU>(A2u^`+D z6~aV|Fb5H7e~U0r67d7X^=2ciLue8U!eXcp_O%Gh5RukyXWG;%iTDBH9usJXbqKy# z5I%(pq2pkqvl>x&AtQB4B7XRH3LzWTA>@h$p+8gzf3*mCh)B0u8}cO)KS12guHmo_ zp-3zUM?!^gxkV^JM7qEtc#?=8Aa1oE59<&ni3QzbpAkKzPScee$*4oeuDuh!kLN+4OYt|3Bl87H5 zZf@qoI)tHOX~i(85O%i+!x51NSR0BY5kEj&1meLugbJ}BoCFoZdp|LL7>|hb(Y8jK zB#HO|;x1LE!a9WMVnMhPDuf3tLJcBP*2XMFRrQjHA0Q54HmpOKBNl|YP$67o5#}Kx zU1DvRFNyd8;$oO4SckAoEC??`h4530(29uUdb3Ru@dLzp(uZ{jtHpxwHB<=e4m2(A zL`3>(8zY6*7=&zy+q-jN9YUU15O#wK;W>+tkBD@|cg7DxB@sVBTq}xT9YTp%5Jo|T z5VHs#BGNQ#Lxm*b2Z$S!lVBY}rC1QohYI0%i!c=tsmLNsmqh#kaW>S$I)qtbLAV7f zgnkxbHX_n@VdIB6l87H54q-m5LueEW!ZT1IygAJ1G$A52S%hVh*qtD5rEP7) zcpoZ+dn|&Fh;*_Y533~+KS11$6Iz=>$QBF2_D~^Awg|b1NS?JJPZIG1#Eplcu+E0z zVnH|*Due?pLJ=ZT#3GbPB7T54gbG-PFkUPOXF!GU2#iTDBH zT9F6q5c0)>Fc>O?SB4s$p@>Kqtur%gxFq5Sh+An(U>$-d7KG!VLb%l;R3Hk$+Av-c z@dL!ga+Rw zIh|RiF(stxlvRZI0pe!&cvy!pNh}CwLxu4Deg>h*B2bLYr6+ zRzihvqD9!wBD9kVf-ge+0C8s^ov;oewB920f(l`PMR>u6f!U;jkSjv`0CBCzhjj=; z#bU!Ss1V-T*LdIA0X~J%Y$_Y6=Fd+2`Ys9EW!yEVLYiIOcEh}fH)hb z!a9WMVnMhPDuiEIgnkyGhEx#hMTj3DZk?PB>k#IM1z|2!2nSh&so$DOIgeBj=8F(N zK-^VQ6Rbm6CKiMjp+fj(i1EYknXq0w)=DY}Z6d@E5Z4zztV380tJ(dvCNunr+lEH>;06~Z+ZVKRLfB%j6mcC ziI@jPwL*lz0pe6A!8+ASSebvmCIKv{mw!!p8 z1*ss67a?$fxRAUO)*(z43&J$05b`a;?G|A=sUXyd5I8{G%$f!35N3-7;ZCR!KF&9O zIKv{$Ar*vqA_NW)=Z8jEhtMPzgvC%H{KX>dWf7K<3PP(0fdj-X^X;$>!50g{r%)kG zvk2|$jUQH%3PPs{(}`EsoDJEq4k1@82>qc#D6$CmTZBAPLC6;&aDX@)hQm69BC#MG z2^GS|LBC!@(BeHiJ-F`q%c+iI2ann`o%+^ooHO_6@3 zjr^NOp=HV}Pneg=#>UpzH=H7MH<9W!+>_Vd)zvY)`}Me4UTt%if6a$ky!X0|UeV$W z*%trXkFtRHsaLyXC=gZSyu?-QUg9!8^5p1s+mG(7da>rJ^`WYWf5XRtUiGq$SG~lz z)q?Y4%d7eoyxM7eE;Nb@ve^h>|1N^QZX-39lIxQtt}jQ5GLvsuZOwvdX86U zLjFRVe+c;|=fOebC}Q#Nw>jo{XX)Im94%S?jW%b8K&M(cioE@)HfP-)4(%7p(e;sk zs?GT%$cd6uTl}j5R8=*YH!iP-^Ad$e>@G6E-;LMKlBnnvyn7hce)|Vmq3Gj!>n&1u zFuL{?-$@;6U5j5tE?L!kp?j2&8VXBI)+)b{ETJ66v+ul1x8FcjQ2eM0#ozTGy~KIs zBOWTlPbaEPi9Oq>pHgvGDjt;j)|M);rKTBUizmBMlY>%yjD6t)m7du1-?qkLSE@KD zm1|3VE{`Pkyx7(_(3Kh(l-k3Vdd-w7Y=oG8D`@ibtVi#`i0HxtgPwhZ5CK2loL2Bl zIVT>zTGq;a^KFrvOpOCRHzendJdic|L0)JT#sv!3pirI|aO=*-(mIGOxu#&bd6}}5 z_bBaKl_#BlU{~R@Ky?*P*riu!+_;Ky+K7%bIq1l?Ha=AwI9}1c&@2^6@CnAAJAQUX8`>dRw-UDY}&~*>93Ig z2widh5nY9UGsrQ6+*Mc%6gBuywWr!PH$XqZpcf9?RplyXZ}5>_g?)`#U*Mgf!9%)D8W@=LEc26b@jD7*QW2eF zW;sT*%02P$jKGNBQW7KnufK849gv=`(ejXPL`hfS{tWW2!t>IM_`|A{U(EBkYTx13 zi2l}y4H&`K3Wgxz7xi0tBBxo2yv%FXlY*wM!aYgvDx7HkkCNF{_)}At`oZ7Xb}etc zhM%W|apLQ2<=FpGKV$#DAU*BZQk8E1n6ARt4Dy3`JaFQwcT@J8=V)dBuYtyiCz%;N z-~&T)mZBQWoH}_v9*zdKlv-O(x3(Myv0mT8%&B}3tGWt5HiqP<8FFg3A-@c8KW81r zkQXRSZ+>k^&d4-FHpu(&aFa}w<$p&3r?lo8r!0bO-H=C(A?F%Hent7#dV? zo2_6T$ZSf#|L+xiXeyX(DmdR&p#E0{cXwCt8cD|OKQ$E;M$DQ%V3}EDa^gq~m@5s* z`GCad6h&(KYyNf>&N2U=ZEER5c30sx=KpN|_ak-yXc6cXta|rlMh`vFo@3haI;7_! zpbFB5*C(bS&l%YJ@Ndu!Z>~&vsejOji$Q02oq<(MzY7e>d7IYLh_OhlV{0^)-Kf7< zJsA&A4vag*8aLV+ci0w;lVZAYJJP>hg)5C0`lK0mWVdlM0`%9}BQWk^T7q#KA;C)j zvHBw({s1=`Cp|z(ob+s8oMi=udvlW#~8vVZg%8b43zOl7^AB*Kld%y@3Bd|93-e1z`tUwe~a z+;o5`e^^j`VFlG22P_^N|Drsel;3^=tk6H`_Y4_LGkvIVuhgAzcuq2rB3#c!#}rv?~nd9TZ2Otu(*CtDcJ|FY&}sghJ2ed{*JrTXmCs&BGF{uC^XF1UwF zg@PtVWE0gJW?8_r225MPw8Pjb!bMmpd7k_ezek2g7aR{z@^Ge3bm3mGT%C1{r>e1E zs?zWbTX%WQAxmR2K34ADWTT`^=-&xV@rPcfLsgglofYOk25xc>d_?j{C_5P^i z<+$PlonjH+KG|K0{51Bf_xFEI%^mrEROWH{xC?g2*25d0z4|#mJJeWS{P8w?)@0Wv z!qr04uI;>$V_PG!zC2^;UAuH>ekhdoDI|TeX%CQtb`E)#Zy4>=rTOn%cOq@;UU~kf z-eB^}{iXq7{|UO(EeH5!Ok#mnvr^_>;$d~2m$*lrTeX8Le!Yq_baw0>pqE($4F-8P zD0!w$)`&llWeB+$($S685k>rEsuZc_a`rT6oT9mw)$o<)bbO%mXme= zOPp-ipn?A|JrRjrO}brTq6<&gKwHmwVR`&v)Asm10s0%;VQb6z1LKmQBbTL!R~%GWt3bjuf%6S7{$eTTL}kHR z`b*AY%q}_LVy&Yi-l!VLjQ!WA97eGMZ_nr2w4gqwQi)@-S&iQWpD3bDWMugCwOM?$ zXEfO!o2yj9^p{kQCT(ndEz4GRSz=oh9|;@9M@2@4^Nr#)X^JnuVHK}3bxGqkTh;Bh zsxQ{4s(aEj?sOWzH)(~%l#>O2z-TYN$gO8)d40;3IFPzkVung++5K4Q+@aIpO%x7s z0B5BD+LWP!>nLbqeE;D<_aI)KG|RqOHof@hJeFjG6d#=rYjoqIhuYT9x6MAlG-9As zt-tiaq~$=$WjiT3wNHFTs@45TALF@$L`H@`{#Jh2w;RI0#p&-&n$?(QeSMj&^l_sx zI!$Ae(>R*6?!~-3zQL-$WGj5xR#P9!Z(D84`Ygmqj(bH$h6fsr{n9j+IE}$6jU`s&-?omA*tsLIF=-mVbs8lpjccvOi&o=rM&s-> zjfqab|Z<@x2*KEu0OliDiHO%t? zBg1E6BH}C)#i6j<8+f&IE`|e;CH_oECFWE(+s|a z$6;~)GSk5el`V zv_^(Ue5D?qTpXV7wt7iB60S+q9K&k6zSdEL- z{E^`!jK-1OHuxXBWGg@1qzzbOdN^mIrfwpf&&_oXOHS7^)KI(|iz8o0+~H?(jdpZn zsiyOYRCQ|n}Jm2syoYMZDGvUQh*lz+S>7^CS4*to1h*$R%p3s zD1MBk3Oj0xH?!mDlpPzb&yO{BRBmp^XD`}jpR+YPHc$XNwy}1cXzj?gcAReQIL_L! z!3>p6{LwF84NqI2p8H(>IMO6<()Z^$I}SHlTkywa){cwym_s6`h2F#;^;`tWADU4O z#qYED;g8EUw_{++j_a*IjxctVY;MQfFIayZwKY3BD1bk{Fqc<3M_W5W){fJy9amaA zI!12RFQZd-+-pbfqo2ti7jACH$h78A5WO9E%eJ<6u=)F&E;s$A=Zx7ME;sD){ci*Zt0h| zj@-;2OHy{+VeR+>cS9qw&o;MXjI+bvnjPb;9W$*R510uXuC#WnP^UK(kFs`*+uV+u zh6MiD#o95@*ztr(-ozh&Z?XRPtI67eKVG5${`i=lV4M!JcC>R{A%9pqR=|N{c)j(tHuVH^5^6 zT#;o%NNhBDCE06gbeAVPQrE}a2`ee`5)C%5kG-}1*>-%$x3>W88K2kigm4R9=xR-V zN?vqf@+an4B&oN8IUY&A4~;JTj@0CvhW%db%ZA-3_F2OY*7fa^u>Q$Qv7Ez>-PyF} zCFM;W5FKG|MXuzmW)Jf1p-Xh(0n*Zo(*9m)TGLWmSt+fLm&hOCo#?x z-ZE@!0N4gY%;5Spc>zxCF5AS2*`y?KfDQvck1jk*HWqJEddtW}m#%b#((b4v{fy+7 zAZ=RZe>wO|Udijr(S<`~!Bu>-A-eEN)6PD$J*m%CL>Jy=5^|JqItl)P3=>m_pu4X% zqYM5(!BpkRJ@C1r;r?_E`+IzmDq8TD^fGkDe=*O(>m7pRC)Ax@+uSW6B_E)WD!pg1 ztu$sTePRnmjiHB?rraw=`)8hp%CaArKA` z0eB-72>;34i_E!1=_U}?xb$KK!l$z=u*4XdKseb8GyLN%jAvn<7BMjE3{1Glz$`Mc zaa{U9)@EfT-_=x)SlvCW?u?XfnYq`S)7R)K7T1tACj8c#U}Tw~Zy!V#yd8K#eskSv z-N)s0DEU)9%tCkQNMwgawnsikkCQW%k1qHmP*=;gIvUad-{*ro>fZ&}uR*oSSn*W= zqy9{X5v=J}ncbs*xgrfEZ*h1RIlM&%Z~c$K)2sN&Q4ViUho|pGL>Kfv*iDT8#Xhco zL&>j`w!N=BXWM&=!Rz~D@VLbiO3rn7GaO!(!5i>n@VFTlN}lBK4sv*>8oa%J3?3KP zp=2+I_s&Aw-Xepy|Bu1b_W_fS`PP384sSPuH~h!o>3cZIvmIWs!~4!`EF*plo?fI) z_IG%nFR<->*Wiu%F?jl1RB|yN<1_1@!_zlpxQp{+@VF*r{d0I@9o}4nck++H<06Um z&*6RlciY}NgE!&F;PKF0D7l=kL#n+GJG?0dZ_1Cs%NO2t4sU|P^9;y{lI9-XPL`9087z3KhR!Ib9!q~NWN-OJL*z#5!T1C0 zNznzQASeEAG!A6F^u~SNxyLs zE9|5)|s9vS&mQ6GUFlYSh&@fy1^NcIAlgSV1d!5|TF%!!M zn$cq|8*MGSTXtB>cD0u6<}9P@WAF1KroXo_=?!PnewcKLDe|s=$rxj1Bz8Z8*5Inx z_fH1h)(v5DtMpcQB3%5oTBt$%@;}`8H2`s42+cz|d9o?EXO;0magM7mNA;6%%myeGCkm`Td%xX6F}2{|GB`X?gAgJqWqON$5?=>A1YH_>f7 zR7GhgmFR zZ}0-1R)z5zG4A4Bi)QR4y_x48z8PsV=gUx&`JByEg1;A;$wx>qZfP`S%)%Jr>7hjU zuPfC~cPil4&TVx&cQzj3xJmuSvBosxCUZ^7jaiG+$~{G(aX z2dp=C<=jOGzqpFmi@j)8Bg6n0}Ml{L)vPx;O10OtYy=vvXwFGd6u?vNy9S>HPh<)!y8u zPW3@zz)LugzAv{nL!JKb^C=O#?Tx=@RRwd}C9=mTg+(M%O`Gv#FH= z_~|Y@gP(?2n?Cx$*mS*?xQ60uu!*pnf&I$9o4Klw0WQ7^jr1csd$h&`H(qcDcj!C$<&l+ncNnJ&av!QPT#&fL=ZC$2TM$IV}43RY4kb?O*&hFMTHKL$OQ^eu+Q9D`0K&%fYNxgXg3i+S~;)^JG8)V|1E#}t0Sh8v8b zmmf5C)c>xRN(8Ywrw&Kfu6j7?}Xz)CpDCd^MIoMjTiYu^%laY&V!h5dY+ z{)y7lPA1+mM%j}JPM$ewWGU}_NQJacnTi-kb(N-^4Yh-NbjRlTP1@zs;QVg5)Pvba zQ?otj*lBEhBX8_x=|M*wa12c|UI!d{Fk2@ZZ<)W2xW>N@J6PoOV78W*%dDsevnRc( z=4s74rkN9sSLU&aH(`i8WtgUbNi7hXcs<6%AX*z;uu9AL$8Tsr_J-Z!qW7Orj?l>Z z6Z&c6{7T!S@fWEyx*+_6VC~2HD#8Dq%}mX%*j$^b1pi8t8E)VbhM9JUh-O;d9h6~j z%;EYkhzNEyMRTT^q9!6ZO>8_o-jLKmVeC?L{crw{JWaaN9Q;zpe`(JyKgk~No?X6` z8i;34W{wlj?kh?AQtEp5R<7l&OEl1XM7O^N7N?k|jWqL|*T@?RcinN z!J7KsI~t9^Q)ZJi1ulI+Is^J*0AbJbtT0%0Jy$GPbp)XSQT8Mr1SQJ8lym+b3(F8| zhgmA^m@Q&$di77%rXs7oxlQj-fOTT(3dnzX${<*AZIrF& zwq1Cw_v%ZE$`XCdX9otDcv>Frex#sdm(3FWgnG}doVE7Mg1^q%SH3I0l&cvo$XA+i zU|Z7qN86Gi>Y}u>k~&s6CD=VgOFiy&htb5E%1RB(x-UrZuLLQ5EnaU*6@Smw3U&U> zY&+&)!#~s2$tB1pII(fBnu%eC_g%CjIf{hng8hHc?CUY9$7oXDjDFgro_xPuh>m|- zum}7gSUZ9ZTGXI*-`3vpA|GAw9l*(*jp;xAL3Q*n{Xv=jk5@J^eV+AMJkOY3_=8}r z=?3k3(3n?dzC`gtde6r8(|Z^0sAve8_7rV5Qt_SN-xg2xw)vlC5)^62on)$zNk&F} zzNO^<)~VK&!ig@3VnVXep#3+s9(Fuo^pBVRw>T!vnip`Pw#c&o!5WJ;R%j0xv>$9u zbirxTx)iPG!YQ!P=a$Mvr@r_tIT?j$6KB4Nzirsm?Y4rJ`+Ad?01%Dq9gc5Lh;2lCu!_YEA=?ABo1 zw*`!>k1n`K&0qb(e~fG_uyxm!D&ItTW}c=HyQ2{OS+qq1r-g?TOof|wfhtUgnklGi zplIxuyeANN{u{Z4b4-$)=hwYvJip!$d0th@bLKB|_%Gfg7u=cV`8;&x`MhC)=TjOh zTd{UF8piXV^BjvYSNX}_<}(7tC#4xP#TxURsM=ogCo8Gy4VtY=VnHE09 zF;{mBUqJ$Nss;Uu%~h6tl{#flS@zG@0KL?Jsx3W02W{g(jirTw)P&vtVYFG0_srr` zug;&|ve`KDaE8XwPRSoIjx5xTf;z}Rg$FHCKk0(#k>KvGMm`S*aT;{vU23jbosu2R zsyh5-Q&4_pP~P~}ls_Y_{8GwqWn4?aWXTz}jUSpe-X_CtGZk$zSI)t$YU2`aHf;s7 zC)6E+D*K;o_{7*SM~bSwhJuOUj@}~>s4>T=G~3W&q}dv>1H;}yVLq@=nt{M zLM;$f15jJ(>rHHkE@)Blvx4G{!QfgJFiioooFQ!%YG14uYrAJSl z!aFF?p=wa_i6z+dUxS_0q>3(hPqmf(AT8^F!Nvh!NbNh@iyA_~wcPtOM5AASv*N$o zk&d`ph)p#6zpF(Te5k^=%12H3S}p$}TI;1X0WH?26aOCc!n@p1GcX!1wmY7=BekAw zKD3hkEkaHT;qCxIU1e9q=^!L`f7ev?;j=+imjwm8m(CMa@G4vI*;K*ff`YQiBJQVx zU)qAVqzdjG6jUcz3fJvDkt^yG0BWqM+D zgO@lq?ftTsB23Z?54;Q6<%Pbu2P0ALgizcRa8)|DHUqOfe1Gron$P zt!m-g|7*^S)QVpDE;gz$Sxd>9=zQ^s`ApstbwQywa?j~lR<#Gr5l;-6u<;;pJ(u)X^|?J=a{gX+P) ze~TtUr+WIV=)?(2{0$_?fFb@Xa2nSHaq4{~F=14}j?pL{xPC|;y<8XB=Cf!|778Lhd{ zM!EGjj6S-GcNahG*u{)*gtFSDS>+?oZH&}iK<@F0Ge73}iqYA%jq`AHC{q6v|Ksc% zUr;}+@~_l8ZD7^?*7QRQ-^6T!!~SY+xwd!>5LKgJjbGkdBY8=8^RqP8`OZh(6_imu zYij;X$v%;~F(l}1$P3C6r{psJy!gMo_zFK8Ur=5B2`aCzh{TT90K}3fHPn8F(Cw00 z{$;;4{Sb-mYT+VvyHdiyz3V?jrgo6+NJ@TBwd$VxoJQRS68Kh)26>&n7+O~QT~>9U zf~Jnc%j55PweM{#Xqr`)IJr5mEK$v)d^m(- zU9&Wc7juP_D3{hLX!Tuep0&>-RgL|LCfcr8!0fhDZ!e|1rSXvnH$N%D(QIjJ)h->E zGM{)(C_KMAwR%E%oR5Mo9h$b}P-5c~($m~*;?|sh!7Rko#|EweyXRY{7m&s|EvnbMh9Sr-47SurQfE01?Dgq~`_m?QZE zq?#y~>$5;DrSow*hpg3&j355ZXwrkC!5Jpk<2u6}6E+%ypWy2s`?W9jYOm@yM_ zrGFtfv8L&Kq_wcirt(!A|5Te=%wVbF!!d<>*cn_Nf8QTzvp9bZZ)5tw^k4N)ZBG@Y z^^{p3Srpd#9q3s9zwvl?m%rk#AbpGeA6MbU@j;jO3JG(meCul!*G*$bv_|R%BbOx_$7@Q(IGxqh^AZztH8Fqldo&B0IR2i5 zu9qlp$txf6dc+*lmXF}chmXueY|8RREU9kqxL8$E(N9f9r;$fRzYZ!o7CF75=fQRr z%{SN{!UrX_}eJ=}7*SgaESJ%;ZB27&LOgs=u;54Pv}} z0aMPsOFdxHpHB4>aiME9=_pH_n45^^&SRxq%l0}izj~XoiOcgkdYf@`dN!?yKSV3W z(@3@A52nhs1#4^*#*(c4?Xr$*sPUqp#;en6)K{ptR3mRJ#x}2Uukyqds&r>n`T-4L zBR$y6nRlaIZ^~;cNtA>6WLjHyqnG%t38gnx_2KdH4{5cB4R*EqggcM^0*LXZHZLPu2?T-e2UdXAuf69%Bsa@f`n+Vn4>S#`1ZF z%IDD}jr}>u$$R;ah$;Co6oVFqEmFZvCYE?IF`qi!lBx&Q}yAi~#HpqNX zkn!)MYu_0Y8GX?|N{KDlJ;Q%t%Th~+j7fxN!H(|$3t@kE>?JfGaPvXqs+3|mk8PRdgimR7*^h=D- zE?8dh0&?W;MOm-MUmP=Hain1HefB|ii!_t zRTwMH6<#iDN;E!Z$b}khSJS_&1boVnRw=^e`x|hq^ZxE?10Srkjm0-=ZQb>zwML~C z4+h=Ow<;?=R+q9k?oX7?fleA5pJGNqKlAOj9hh}~iy3q8X)Nq)=B@n{>B#CTNVSti@)a2CY4dZ+dpO_3C~^X`sF369+TMjI^;3&_ZSV+k8>j-{(%_`SD%gN z4=-5Wkv(NreBFpQXC8v9{}umcQOBUHZ(iS!^@cb38{_IKT)k?{h%c^LF(a>GTvq(G zj#eIm;b;kee<6Rbh`%&u#0N9_dy`-4_H|vI3>dlZb{J4y5UpKWQa1VD!qZF~gO3=m ze5z8LQ9S(F5?Q(LJ0gjFUp3Ol2fRD;+_96F3N`+kxAsi}(2_OHSyj80$D0LI)-YZN z8yek_+&;OHetm|QXSGxvrf;IDo~-66kwJ9~H`eFeW7;FRC#;V2!*xqGvM%Wx`|aL{ zm#+D+qjz9;oH0@!KPnqzv#{n^%t$WR=i*Y!=Pc>dk2PkRg zZfmbNBW#Q50U@Jm)0E_L{K1NJ&qKhQi=Pd8(STXUTWH5%@>vABr_M_=8nL z?NviV`WptT{0;P?=%2Ya0X6&kgydJGc28G#z2L>ydx^^{STJtqK0!g#gyh{|(FJ2R z-`~BmI9vLfviSFG1H-j){bX#zOs<{I;zOAnRy;x*h~=4>I=NEF=XGy#UG33COdEb} zdszGBIc14cb6Iw!vesWAi#4=H*=thLc&cMTkQ$*J$gE5tbHV3Fxv>*mgqtQGgVkK~ zZ(8RPUHch}zBX5h>GmWya*u^;zaa$HM08^`5m{Ef_}C_|;iz4`MW6Kc$JRQl?$&Cd z3u6K`9KE5>wB5=Y`mXXuEQ{3sA5HKY`nHviSQoio@k9YY>%6tEds!ibmRJ(h7);5F>b z++Lhp)^OMwvWAu|Y7ZB@KR-{)x)7ZOu?iLuLcGyrWpE7`pGm=vk7;tN{{S^5&DxLyM{yNQifO!5KcHC#O?hSOCRe;6gdNAeJxT+$;s z$0mC{lGRUuRP;z*Ws}GENM2@>C-q3y#Ty`IKTb2yUgTX>)T4B*DgCTwsdBatT2y_J zmw0y0W~rxceE>=8kAymXbObV=+6qGd(rqcvb86*QS!$SPpLa2y=D56-ADMo{~F}@g5 zmRK0{j5*Ux#gJYg6Epj+|95j+{aSfRaJd^#|L)*_PB%&CvUqt z%Ur1g%u5NK6P9c~-%lRr#ozD}r{yL_<<_=GYMZ*a?!7!}_Ij46Q5+=<*hiCia-ZwG ztX7@iyukNqEF{fNTiLt-dm_p?VKfu6A8kbp?O6iQRu~ zIyT>Lnd7!ePTmu_*mWUxu}wY)MDmw59REenGRt+u&!QiW_RMJ~2kmR6y${+SvnAy~ zb+SB)f8v9G=figgU{hvky(N;W@YrGK79$hSC5~m{H0gWKY&`1Y30w#3#uf%o&(k0o z=zou6I8#u;>Nnj`pjaZDhk+f>cgJt^IK!Y?pYi?v59pXv>gilbPDMAENt~l|m!vlX zMa(AS!`Q=GuoZiX{A;WwDpLJU%92$4h(4q62+utH`e(*OZq+br#Ic?izuYT$OW4Hs z+<_vRX)z@S~fBgnm`$utW;#vII)vT|fhbc$&?C;I|kzZBp{855^C7aoI5hE+zzUK(j?Sb5K zZn1RqqtE}6O7cnacTJhx(p|gO8#mr2;q26SL;WME+oXeotti!h3_I4~CJmtQ-@6N@ z^5u^k>?*v4A##HWpy=SExeVd^o^U^-leu$1ylW2MRI!&hk*GH@M=OSTU5Xv;3BQV- z_7bL0#{<;X%oaUxtue>d>o--$fN}oa zf%697sb^TyLjLMstNFdTS!6beviQAfj{2edo9jLjeq6SK<2F0ui#y@7fB}}UE&t6#dANs6*> zRa*Dk@jQ+h{WMvo@Astd2dZs5clUih7Z+Oe;$JaPO-1pWgZk2zoo!4Dg5@?59)D-x zi8p^s8=kKU+OV>_k5ln7`)A???fV!TiJ5z{TCl^lfULP;78%+43kIxj=7^b#m|k8y zJ9!Hk-0~>qi0(Nv6#qsof~Zpt=b1YG)?6u%59h4%+Xq>nx$VKFtnNc!Okr~skve7^ z#XwZ7aZFkFLlE}HhMZWc@9UcS%?;m(0*YLX{e(4&A~_zzE7&fV_;W5(Zuk|h8_ca- z?zX<~FOZFCI4vDd28%|@A9@~x^Jq5A?uRi(hKs?e-p&1OI6R$p0-l`gdYb1obS#N2 zgEl`V_oJq6WmmuFABBo8^Ah26X6qcLXl%p9<2e-_KX$}-Rr@MBzf^v3D?s%HT&C$E zj22uA{3&A-Gl=4JzWZx;j#^4=Rhmn-apI1~OI(`q??oBVBtH%ZbR3QF-9g}H!R zN>agF$x`+v>do~ytHscnpK+xy;+&Ses^4($nfr33%c}W+AmiBF{x5CiWPqD^T$l1p zs5u{>3;>swt&9>z?J^D|TD=itmsKxMeoAc7J^EbyFk)@>wv8G+TAGecJsA+!vBa7i zwEC4q>dXRd{%$~xR^(XI730=iZ}O^+^Ab0YS8PW(b)c8{IWgAqnZM%mK~3I>s&#o) ze>5i+Bi2{1Rt3+6RCL7Js+(9IX$a416fU^KJgYHb$%8=msXC;bgPpN}3>L)I&AhmD zrkX_S%SJ4&{)|6+z*{`^D0S?maAQL9xJz;7h$Y+`lJ97?T=sg^%_k(ze3jFs(LtlG z_#nEb)>^%yjO+ipKE_qQv*s_a+S^MUrx0=Gv)sKLapq!beqSd9#_x-&KkN9TiH4f0 zZb{u4Y^(k5>BsTzVq3YtjZDHZR4 zMb-P`raVM1GKSsgXl{UJ7p$2;G+R48H&pdc;>D(G%GDoM9 zsn3G^MYjSI;T5SeWDX%yo-+IQ53=uI`#5aMsy=2&ybCC=0=YwE$NGGtysrc6!wvrHp+bvgG(Ic6-{x?2az zt^0Wm6`Xi3V*GQC70ovOYavuvtd8qWON5`k&H1pOe8{~;>i+&>TlXgMD|g~ef2QAx zPnadyokK=+H+t{#h7+iGaaRW?Of7k3Y!(VCex`0LkH0EA65-OIPW4+KTW8$WnQCw9 zc{J9)>719McaPCy(JXD%ear(mU2>1*aD#BppR}Bo&Vv2kva@05-fvRpq|UH(MEMzm zkjGwnM{c-JT>O<28v1-p;T4>P9yht~94~88*L&Q5tsk4HW&*C6d3IStsn($y9#$;^ zyx^_w)kE>%*b!I1!yGwTQ`#Ify<7cRdKs3ccUYRb%!3=g{&c3cw?S#e-w7TP@n>Je z2DxEJw*^i&cUQtY5oFPAZiTLUfjE!U!IsrPt0iaSX{jLDNV_9D51ud$Nx{y18Kwe;;~AxdY~$?4U+!K zFw%V1`dr=+*3F%pM__)EBT)>qNZrV$BImrwZ}{?gC|Sk%{U)`f!v^l{hQH=#=DL?# zcv^Q7rS)FI95BugjM3(m&^b}e1cBVg*E<42tNQC`(VJp(p& z#3$9ONlx!T9tW%Xh{>_a_Rk~Rseh^u4vN1=-zX;G%t`?%Y&?OY8cGv3+PG=3fc#*Uv=TO2>1So?Og_FWki zm3>X9hWs-F`^L$>i0s4nbWqN69SIl+l|N|2$QEwHbYd#dwn2 zna6Co_}i)Ct8DR8E&9MM7ymw0oG*~en5PVSx)nSFYV4M^)^7eD3!|IwPtgIv~^T8#&R?@DgWN; zPj{`;1E6!^*1o9$OqeSRu{`qN)_V;dqRVC1aD@Hip(8&37UVHLue+Fo7EZROkjnlp z{Cca;vpo%|t*p<*=O1r1J4@U)^T&HNc-ou^AD@4UJ?)~WpX=$v!P7nM=?Hr&AJCu2 z9|ZfZYe1u72$o^MEL+1`OqR{#OKd{=G&aPc6QvK)g+sMGI5>dUz~EhA@D2i0^`%t> z-1uu)52$LSs})>%`vlehG}OzjdRJ9Hx~hdLy-20_{Bc}Xca6^EJtUtzaXuz?F(Rf^>LU zy2}WJL|Zb;Qa^f!0?=eH@^1nNmpX`?#bjWQ#|VBTJIO`jK#Ow`xUuBlSvW>rG`TNo!M6>o=`IT`Jd8CA zpf=2ddZeJHfLaHYZ{Zpf;oY>zP)hW4R_@$q_~O*}U+1}30V4h>f^ikhp3?RAty?Gk zv2|-9|4-$A&Hy<7Ki}UdEo1SL-3V;HB6X{r;gXUM7#+4YmAn!B&eHF|ik`0qv6;dF z4BU)<70q6^DyadpwSYNnD)yk#Jo;#o5#YcT9_MixZYM?w=&S$}^`D=i=>wcBxwY2%4{*;M3sBw_V`nk3KG1@o_wYF;(TOOC zE9%mRx3GSvGp}Z|+?-D^anFwBZE=cP%2kA@jbnfCwOSR%zoMXTYTFiBJOZ}EPdtz0 ziISh8{OPv97u%=wO|>|r-n!Xu{au1sWNXx-YOs6es7m8h79Z0*T5+s#t?V`Y0ujSL z=+qFFE{QzxgB)?u#5EwHO+o1R9D$>zl=g_SC5&f%)7KV3BU`2k@_e`ODJblpPWNrP z@jAs|&7+Bi>Pw^k3*tJU$NKWor3**SXvFfy9^T}$O(MpQ&2=yZ%ipxL$FLdYy-@9i zup8};AoTc|7XsKlX%fMwGvD{N*q~fFXDl0+iGI_Ox7aV^rp$=znXWAq8uL4WVy!vYX0Qdk(@&F#DFK?gvX`$C}(&{F060fQE7p`wOX>F4pzekfh@R-dy?Kw1-5iU)i zR_bf0aZ(<<5xTm4P}*%NH!tXh?K<5)F6*|rbi22rcPuR3ZZV&BrfvcgxkzpF1ys}f zFNqJb-OYp<37g``Mx8jPfeD$z& z{ob&A$4S3$Gj`|bOFP7)FCA9BWAtS%UOucklHMVnKCH*joB+!9?6JFdTN$79cf;z& z_S=YFgZ#T&vnq|w{J>G?eF3iB-t4vv>h4$=z4KKyi}qd`eQ8DYJ5=$WMdaM68U%|a&C6H(+!^KH zucDnkM_E3&@1(!kYHnkpV5sDc0qF}n=!>@FclJv(6!zQ=Gz+Rq!xwBws;j^>|Ds{6 zxd#fnFe3|wq-Wt*ciVOXRDN$>Pw8>`pTq-;X{WE`@`+q!d$#7;gYrMoOF_KyHx7oB z$E|tQ6;B$0Ug?=8HRVm_eJ9tWCwzE4A>@cA4^c4i&N%KWT0V`BkDu`pclb=-q7&m5 z+@J`4ID?ZXH_{q+A-q*lJZtLvT*%{|A( zzR2=6xdg4ID4#|*_gecYqY3SibWV72C}O|aSd+!SU&Xe6F#rw1Z?H{T{Dx&_H+ys6lWVp_!kd>?9Rmmj z?g_j`=%9mW@;llK{0ThsKNBzu@&ob4H!kc8aT2|}1ucuGC7&PB;D3oF=_cnNjF7ppO zi_d#TB)4>n=RRW(> z3Q3w=EKd!qtS)r^?ayWDF*ESc2c*^}SE3CnqsbZD3P{o6tZW5A{uBsA6mYnv;A~Ar z!9^4DgTq%($=q4TkweIQ_3c4W8%>^KQ|t5&t!-Cff9`C?x=B>hAec$>5cz<&qZot% zsdXTiKa+mrIlShrzWo>5EZX2*!HF#v$kbS`*iX&1;rLSHR(8oKs=dw4uO%0-QE*mtat9kAUdZK3+f26VeR4WXj!>7QXopLp z%7$MwIfQD0a|~VirEc=F5Ve#mFAD5%?p{rSe-?Q#2K!d*CGTl4*lM{2%V5;JAwiY* zr5A#Y@E;8T@82n(GIcfLMuV*%1~3!P(ZCAqG@gUA)qTMZow@7-(lsH<1_ttsF{CrxX)U<-z_({E^5`tsqprdqU%?nHFd z3#~$hJa7L9VArxD`>DI+N@H>2Bz0#Sw#%&JRbEpb`?fnfUHBad#qbjmb6|`n6W{Sp zsnlL2`HiGxS*puMek5DThXLYEJqgV|F9s&@`HOcFK2UnO>5ACr3J*Bt|MRbdsmY^q z8u?$q8t=lB)yHCMaFa@hBZ!!=GYpT|^q}$dyvB#A+P93P-o|w^)wg+D(z>*Q^_+_1 zoBM-tuiTfiC((h8%e88uS6P|3WvSuzx;Yo4+vB9nD#Zij<%W)?)tx@yKtm|ht1MZ0 z_)@^q<7U~o{V2vWiQW4l-m5(G6`Z55$+-vSm{7WK4pXj{IqseH7w@sT`TzA7-`n8q zu@e7v?Q!cNMkMyQ5bm45c<0qZHS`y!UCv!a%U4G0r{D(eu*WZ={<8k!Toyv+bGD)4M4{l@I82=fJnQ|rjw* zBz)HF)i-Q32c-VQz>91wHzKPnjb5;@J=M|4)0t+XwO_g&PSr4+D&7FNjl!%`_2MQA z0nSk>rjAoJY@In(hhpqz`)O+OSwol^pZ}TY=VPS~tCI{X3za)LwEQcGI0gnS|V{5d6{;?((flolE%!aejs4>Lm@|^$qjgOzLJo$lnt8fq_Fys z*+{6S>_jUFiW!Wl(wWXRs*bu9nQSFD3}zwTVQ9RW{0Y^$y}QlO7G}}Af(3rEGZRbG z73OFy@J;|tr0PYGbF(5o7bKW7`a5ylWQ@}n8i;ECm|4i~4;*GaMHc)^AeBV@8QMds z-+a7*eOj!$pQc`sYU|C#$Q9P0tGDD!jY|3TH7v>n!?7y=#iDqOKy6Lm)jUo*ayztkKVxySe99^=5yC!tbvpOD#z52&77VENDt zSkX!{5cSku7Svr_6=&3}`ErV|^!Q2M(17&BJCxxsIHi&}+SIqceASODY{NhZ45Q43 zW95UMs46V}VA_7)ru^T_a?YX}A$I)>e^- ztyK*cUFm&xrrg%5UJjaSt?Do0^?JB7k}Af@s-r{hj24vQF69`P@*Z4Vu8Xc*oT`ic zV4Qa?_<`HxG_FBk7OD`{y|qBqQxDIArPbZp+)~`-a9Xf~!&MpkMYx{j)Lswj;r*5g zvB2qVPG+YbB=uo3A-P1hO*|PP!ffHKIFh(rPNIgCl&99pwkoEKA?BLd{)cbWD4U)J^E{Z&fXyO68Y@#@zGMadlJ4+}$W5wA4 zxlChaep(R^lu#Q^iQkbMabplSvOCe_OK3^WySN&p3;#4)wRl(@nRS_Hct)DMIC8t) z9Ia7M==-I2*8t!triGl!aL$~@c8To(k-rrpSnsy|62z{cWiRH`yWSn_m)MYEEWy{>ttU9h_4VOZY>>$C*BH|$ z-$?H)kIwLSrna{ooU)jh;pjpE4BO!XW7ubC>UlSV{hT;lb1QHw`>S?NsUZX(c~-C_MhU9X~p>byQu7H<~Y=gCjP-{moEGf4>624 z`Wd3Evqvf|2(ozNPNp$yopop?&6DRoAhPx9fRDY{_~0 zDYz58IqzXQnlznC22yc1~Y z4;3dKqf8%<-snHggF5y<$oG$7Pg$7n$NrNvLd>*htX7`i?0@+XXZyAG;&Q+Fd48rU zNXz&?<(_LJJM{{-vp#}E|7Ja_o#-#gCHhZAWPT?*R4an}Kj!;)bm9CzYN0gL(y8Eqh1+w2Qo`F>#{KpwI58*<{e(31Ba(Dv=ndgZC-Q z1$65e8S@-ix4QsNCAW4{w(?^4>6;C9a|KHPmbFw0kkwU$%<`67y=Q36S2=JUa34m_ zCXG|mW5AA*_Cu|B^IkHCL2mXAft&EscEOx8+}zY3CV*Of7;9MS#eMk?*r*w06&JAG zK(6I8R#Man1xKcjhqj3b55nlvnK3zb>b1gvzT3|ieft|p=RzNwlG<_8m(!Ot^@BBz zCIoUh0^ddI`f9OrWOj<;n!Cj8rcX;N4(Z53I&KqsVS~5gMY$TU0lCKcASqy2aJh=y ze{SFTWhzb=wX8*jGKJ%?dC<9;`l3YHBf_MKe4<+cRy0w~1DZZZQ&?Y_#{_X(gZx?0 z)a|7DoI9EPJxfFl#}WPxz8;^d*Y=rc;$wTf*6Z3^h|+qw;45RtTJ_>N_^J)O_rhmy z@(g`1&#kAZh0n+zmwImpyabhh4(_{+GL~SIMIW|lO8&LwN(9Sr4X zx$%#JRHcbytyQM=a%JaqCY4yfCrnZfW4(Bsjx|F%Mv+DxWqXo2=B;!NF!XPt*Y$a- z2&vggaqP7vCDZ!zfE^>8%dpGCBE8YpB_&ffpyi^;R)^}*DsKT8``ZOK&vWAtwL^C# zUX>Jq@a1UdXySI@adVN~+~96b;HG?>gyC|y;*Z{iCo3g6BxK-vjcamZ8!K# zz?5arc5VtWCCoHl9M*Lma`Ob$V8k}n{n<)U&v0+X(Q~sinkWJ@c%aaDkoYI&UQQXz z%_-Xnz^2nm=I+P%?c@X})1})$`|cMqF-&poPmNCQRRrgCY>g)R&*WOPyC+a|g55*? zrAMMD*5;I5Pb=)Q0;3VI?H1-`Gtnzl2xQ=S zCw?+p#F9@_$>N=HSjRe=C5cKPm^<5E3%*)v5()3o!fh#CYHhPw=%KE0v1Lla##)Dy zK~~G}7;RDQw42WzLERc-k}Y=KbB?H9LpiF^ge97g)snzO6VK{OUBVfnrNzgMY^aj7}px7?eI_Pj8iiTslMzIm=tc9 zcy}c+#Sn-Dv&pTf5WRB&KF+_W6MbnxS^BAkQ&}l7Lkxqp+3~d_0|oNSF+5P_UuyBI zpca=tmvr+yX%_`~c3f6&5H=VOmeAG>!drrpP4s@m(9-s05)rOlKK~c>$r&a*7VgML zoMXhBmThyk`2Q;9p_Yv%9^clO4O-K6CH}9cg5&=a*-87dP1+jT)}KIwczQrRGw{lo z1aOH#+gU=MTguqQ5wMX#tA}{ES9*O`0yor<-cQ6?{H%J3e>m=lcfCHw9aZnPZW`qa zx$ELytF1A;pR1hpFSjltFPn_VrpRHpRMer2Ji`1K<+d;4UG8Zm7w<_#!KQV%vguU# zP1MLuh6-0dn1(yji(4i-9ZngWR;xm45eq}DaWj{kMX{|7_3qFfMJ)fqWNbj{!VVn? z2`sjq;UZl4IMF|nFi^_=d9hx>r+IJDWS@-$UOo5&reA?+cBcILshcS+@jyAcc3b1u z1o%~JrgZMBC*x*>9#1rJkd;K7{KhVnYi~R{m~wdZ5OQriN^>9ZXg!tc;ZYxI2(H`t z(%01wc=UZwH8Hupbhza904U_N1w2HAwU8Sffn@M)6HH^i0PbuN=KeH;f$T6@WQzAIps{l`zgoEjwZge_W11#NCRUFx-k?TwJ))h-eI6-aP_^~ zvecHmY2S`VPU6o8sv)(ujLs$Tmk>q`ts&*if{sqMotz`^{_PBI{qEiNJv7$N=rojE zWVPj^>MLE8vTRC8WxeKZwP^y`d})JkOdDiP-be?asVqV*W;>JjK}r5B|ByTS+w;Hm zH{V*QuUEOsW6>XwfdG|R<}lWhsK^P>^nNBlJt;Q<+PA-JCILDKF{@`+#n&{+3DCFP z<@Iwb{kWl6bvS)U;~yfB!BC_l{f1Hee^EYSo(K>(ZkTRktBj_QjFM zPL<~VhVszQjV8`)N>lUrhUiMr{uDIxcf0IqSA+>ia8)Zz@QY|rt4uP~*vZflbmn9T zKWrm1w22o)>Z$&ztG+{i^&hGJCgrjnm%tkv%VcK~hEi;2s3aX(Dt90qyIS#wbbF!$ z&xwcjxA8a$iQDM?#j1&v5$A@hn%lfGm4;=hF8A=G!A$2Eu8tMbTJQ=NC_y7RH-nR0tfrMT_1{9()l!n(mYL4?U&L*Sr)zl2;?r<*10p-0 zVu%g5xae;PKf$>N-$O=LQkQ?=+=HD?l$2f=0Xys!vYeOIu(6wek_O#UBRQ4xDuqO9 zp4B%Se*aKO!aJ1be9x;T`z8sO=t`1s;K^1*z_@C6yFwDyaaBum_{Y;gVf>;)z)0FA zoQcVQk@J-!^aM}bC|*Q~Mscd@GBcA}^njWbguSAddD_7HmJdY{=b_}Ile>%NMycM+Kbf}#7cRew*I^wt1c_N#t(@me3ly9c3%RFIVpF5yRk(xdcF66 z%1IqKGd)Fj>7s*4<dh6+?Ml@kS5%A+&N&mO zh{|-)pA1eg2d2`qbZW|$yA$oG?qaq*xXSUny=&Okv_v*9s)l0bnM3n!^$6}jc#{cT ztoaDKG%xZ(%JHq&Qf?mBLhb|KdJ>iD@vX-PaGh^`ovR=Cwl~Acz_)HWM8bLu1DEx! z57j9C7vK7Lwf-M{>oY0?Ij!Ma?B5_B6f6aG%wSRQ2jw{%vk!0QJI&HoSK@OQ06H7jDey7s2rJc7o?A?Fd?NG;PoH3NxPX_8aQuXC3- zHB)p3X1onH*?aOpt&y?ugI8)`*5n_kI{ED&@C*xbQ(+)Y#ff=(&m&#rlh>(7ll(PY zPqRLPZMIA_V7fxZd&WGo43kdO_-#*l&N6h^fu?2|cGH!{Z$B!y@q2$yyTUSj&Q)#8 zuz7ox)t46gy0he#ubB{qZD}oDgt6Xu$cK(SYtS*3*^Su<(_+P_a5uY;l&a6ExVUTF zvqod{CWDoaSqxOpNqU|;X83RB9mEbiBOKnju3RtE7`^>Z5tZierBtbwm#S0R`4R+` zwk{2mosF$YsOBH=M$ac5`mHgv2_F*pW3!TfOsX&Q8BFTSFTA z54K3U&%1h>tz^U38k<)4SO3{itgXOlZD%EPsw>tPkRHT09WhBFR(QzU#K`N2`*KuOe zH&nH^A~h8fpQ8$#6fV=1q|mWg3GLI{*+Zo80$rs`CUQ<-x>q(k`8-YV4Fy+LUlToN z5(>Zpfg4V=o%KM@=F^XwYDW=g;0T}=%DAG|O(cVAE1DJr&!M7m6Khv1DI9Coz$VrK zM$*m-v+G+_>8S?hbZf1gD@Zwmt6CGP`X3fm?${p^WGK-CeQ1^&>aLxPxDTC90!?>- zgV^^UqloRcsTFQ6J)(lFXR`4CwTwJ&LlfKiH113c?iwI!BloCWV7d%cE1MfFB`fvL zjc;j`n;V`$WIL*`j*4c(|A4boHQNPyC&4y=<;Hh!EFvRv7v(m-51TQy@!gCN)HA;4Q6oH9jR?xs z55~7Z)TWEtoABD98Tkg|dTSYK^(1#W27Cz4)>(1n)c%r)6PU(X*R8kRjIy+-xPww} zoKxzXygO+p*e=a5Q%)DLMmh>+qCQNKsc3Va-%DhCA%{t-U@5P^g*jw6c zABhns(y{+mI}}bMDuA^^NGR1-n!N)_b)MO=+)=SNV<6va(M{ZH0u7`bHvu6YB_Yl_ z38#Ry9g9#mk9zX4s%XMp#wEht7=q31`_VfM1P$;2J^HT+)Qwa%_kJ$}i1(ZNM!x4J z?{iU^^Euw-*5&ZpI_So$#IBexWz$nb`6|%0^{gD^(y0sADl!@{k&i*w-LE@)Z;|Re zrKcS~BT~lclFHotXW|-J@179M|Edc@9r^)9HS*2F$v0#B#~4}Hc2L6kEXSxXN^Po2 z1$6HaFlv62I*c0JfmE}7u+hb^?@-r3-cDV(WW2!;?Wlp!W|VwF}0+*8@IC^R=5Qd12>yhf52H9_DV40g%Ccg(q4pZ zW2-*dv2#fu{|2_Y)*r+Ev1e}hJ_XfW|97fa)_*MnR8pBsi03)F_oE%Ra(l}}c==G!F7(NXj?<%a6XN(Q^laVId;^%%|; z)Q|`{l6Q6W1H<`|Na4GK;E~ft^4&-tgppcbYaa@5nYGU*q;59=k$oMSGmj6^)Kn%a zXk}<(;I4uwn|t)8H%sKq)LN#K1m;A&YtXe6|EIJ9dJgk`G#`PAmSkZ(st;$1K z3e7DZd;w$#n%oK9pg<|v+3FO1MaCpIDy9`g_Z}tz*$lB8*1eoqyvINqYl|b-9IbiV znQ{t(-67}58MHjWsk#!h5-K?V_Vf;Rg@1bL4Qsb#uUb<+0I;ttLh=5)w=FJY95) zVe3{V&Q@z%nRrFj+{(mw8nQAmfgeak4A{;(owi=At*uTx*vj1b(6T50Y$2A#CICSu zd%|Pk>V#{09!>pIdcpZ+&Pq9%i)Wqyj`;_ES$jb!8Y>(^i5orJN!&dIQS92W{95FB zM^m$qrerU~4VoS@Tv2*on`tr^{9G#4qe-SvBj+;ZL!bU{5bex0N;Nc_1#C}Aa$zf4ob`Vj0m;kub}6wMEmn{fTg zeJEU&3W@3p*L12#xRz9<%qKy9{u8tcBy29&2j;K$QJO}(K||L36^L+4=qhUx?v}`G z12E@Zj#qPKbe;L@&4(pwZWz{QzRaEd+WYrS^%}rpfyf%bF5Ec-I59}?MiUnq%JR+L z+C?PWO6oE$k>9nZIb!XJ861~ZSb6LdmFsIh+G}ww02mcsnEo6ADwkX+y%j9XaC(y_ zmh?w%A|7N-LMP$w-PEM$2r2z^NoCHJWpY{LVb(Yd$%k{N(a6TIAD~PFH~)1mar5^$ zQuBaU4+vww^e%0qIWvtw!cFpNBBEv}Ya4W(3%ecIn5i90HDiZ!34R8O^IVVOswxYu z@979mO0Ho+r6|zp5AyX(+rz*kW1>l0J7!O$dxP7N2KcSXBK+3DIn>}%@^U>&$C}bg z=gFnM>$Z%K3?X6OVN|r%N2^LUVRE{VvW2oITGNwO%JLl7-(+K*Hj`EJkL6^OT4^M$ z#w_|lF-PRKo`&mi1j^R>jo<7Tp2OpKrm-}|Indxg+EYkIR@#hr4XR1=Y&f~>YGUri#fi=6#nuW4)4P+q(Qfd$ES~D5`C>1BaEzO{-oRF8& zL}o-Q28dO$>_-i;vThzXNzr;*C|6HeNn{sCS7!nsN7qY~qu&})Zk|$a>~G*H-AJW+ z^xI}ym}0P={^Bm@Xg&cIc7Q~2q+796!aI1xym0FlB@Xg*5;{kHw1Zt8ViwKXr5!#9^9F(`&^V~WvZ!F%39?=S_$EzY0{K+ z*;u8ffr51bz&uK10(WXj1Cs+)(R9OK3bx13bkF2Rvmuh_7(n5L+ay<54pt({75R$6 zM~F$gaO0n@67m%1f{_@?2IrrhTQ-CeH#Z*&dQCpTqadV=XP!ZL{kuzZ_Akt6%#hf{ zGZ&DEtI`DZi*}RCQe#7O63WXD$@FLvRD@+s4_@dv+J-=d2<{82hx9aAgOpOysAF zl-EHMROattr8l>Sb-bpW9o2iC&71JBg66L64pR1M?aiD5GNB6AwiSuA^AcsbPyv%| zYQ?ruOk*lwSISuqy^?ZMRu{^`x$T(eP^q5f(ES6r&Nz2=_04*2^(M4X6WgNP_;5)< zSG+UMmv&nX_m-=c9%eZ;%@gB7JZnAId%e^=^@U5S>7%dpTTeEjf9(yNByYaHhI zb%BuGE(tx88aZ}9=jsO@(rDq3F51C#YDr~XbNO!2*zxoO?rJ1`f=z}$qG|%G`3;v? zP5)20dPvj3VRTSfyL^I;-Zn+!v_n#~h8IU93j;1--j-XdqvWZ*_6*V)*-gw z1$CIkXkTGuRzg;Q*{2eY(}bQZV&TJKO9H*PCp<`Y?m|Bf(aeO zW9M>*il-9YbTPEE)2OwAzJA+jw%2-bUz%qo=_Hu*+aV!j;%PQf<)v1Wk5C10N{hxb z9a{nIn1jWQq6NLhjo^)m`<`;n{4#Uq_4YkrN7-bL9Tf+<&0sn2i0Vm{o2ZU+jMMhE zd#O~9vFk*QoDn_H)el5br=gdn3YXK(c8l0>tR5-@II8A4k#eDh#+Ghj+IxwqBkG*w$SJWE1sQR~UNQsY6Y zV2f=dI@=Xd>sVcp=c}=9C{+AI)GS?VMNxxvh8v{g)iLJ5O`<&AK8WWQX2mm)wqks) zDkcFsaYyMVGn&aBOLQdMF1$9(=FhM}FTI}d&IUbl8<7OPP#U@0 zGMq(I`O#=4cL$8OTLI5`d$eoy$zD6_BlkLEvKuwxnJekZ(mw?8O6l{7s z@*cSlra+SKE(Yl9%?v0jtqfeyv>li6%+0{6j(gA1Ye>x;QFEWD=_BYBv8A19T~Tl) z8rd6ky%|dX9iCU|c|0>Siw@?~(jwMFrJFMPo7C<|yR{=(EYoJ?+JWy+*$H-b0|EbU zdS*(^1t2qmRCWW7-`&+vGs~6i@P<`*(^bGDFk%c|^>A7)cMtliq9ikLRJQ?Kse1|YfCDoh(-i0n+Ye@4VFGZcclEvRcK=e?!i@LlHb?QlKF z;d&gfeZ7HFk0;dKH+?j+E9f{+sD>BQk;m~&QESF_yr5jwRgxSTXtOi+i9!t1Gmp>* zp2CqPxfs!yxgz%B#t5RHdOU>;E!aSB^bE5-afL2OT6A&T3ZCJ5dDm*xE#LUFcE^%$Jf9NW;uyV^ z59Fe!E=suATNidRO3C(a9q+0msx-UZEDFW6GM@Pno0+$gcXX6-8pbizN!O7MX<~`*jR4$h9#WXK< zf#@?92=jw7dRcv%mo6+zF}k(?1qb_~8aH*4YFuOS zp2hx~8>1TMzizsFH>aee0Bf3t8Ce+z<1<(m#^gjWfa$SQ(nF?sE3Pralb0d!S13}; zv;$yO4RHReoy5+@+xREbXRzGky$=$hiCg4w>EUoeLL2xpMc`g+xL*+B{-f7VxNnOQ ztx~mkrkFPVo7-cup5Y0cOdXVacq9+QByC8}41YS%EE#D*a&jr1`@#TqUV8~4N&xE* z-e1GK$&0~fm(fce$N_A!BL|4}=}3X;xmcgWxRXLo?5pSLqTdL#_!zzInST@X*v>}n zJygxP93N@wr((aRLQWNpM#Wqi#M;h;@c^j*K&G- zak#{G8k0v%W`N?yd)K=#G6|^u_>N-VH#v)(=MZH5gBfB7MtP%uHq~udp*`k2HIA{g`GJh&^g?_}1#Ns^{$f?71^in!jrPg=@RkwsLn59{h z?~~B*$9Hi;Uy_q`UM>&_e<(zFof(8chb4DiWYeY8i6~3|4gBTWVP71X+ELT1Wiz8% zTVNjpBmZjzs!G-3nSK({vEbwF06>Z8juKJ#aDX0ehq+W_Z&7zNxlj`M0)KQ8OdmT4 zrY&09d#)jXTl202uGD0Q$Y3FIYjZ4K|9ZAKET;i;%(Ta@?eew9rC@>*ZXq?FE~#`% zcq+h<>hNnmZTm|PgYV?sxzc2jlqq!I>UFdBk&k3$(y;-Gr_2+%0M86hWD(`oYg06V zD5I|r81H&Kk=e9xEAa>u2k~NJswh%-uB*kc(&6sz6#e*gwE=qm9`*wBJ)bSgM@9 zuY8urD5oIsS!SY{oX_%zu0)-$hUT*z(ZR0pS&rqZRv_#r)gV1!O1+y`wlvVlx~$cq zd#K{LDZygST?{&u_CWXKGFH~}#C}$B2DvLYu9GOp1@gmO!=c%RBHkK)!6?#$(z~Ky zwQgleBMI{WVgtH|E59bt$2xn_X`EZPR} z3Vhi_RvanaM{HhLs*WbO?9~h0l%{o*3X)bk%X@=soy%O+_m(W@-DeHs%Ne8wgB+rs_cl~8MHEyUGMD#VgVbc z?j<%JNh%_{FTI=H{Fi;{%l@YJ|Fkdt>oJnpMPOcIU;3>8$cgMEfwQeT6QhYU3{%^i zzMU%B5@k0oVa^>k_haJ-TO4zGSa~d=aycjp?k)s?TcYIf?xIV@$hu3E?WmMfmU~!} za2e{?ziia*wggW}W!(s%w>6g7YZe@<#`!OH2m673J4WbR1n@nVL;z#=lwY(y2mqG+ zY0lHFp;GxlCZKKrV29th)ymUA%pCPsscM{YtCh!49;`e+(Vo#vJYRs!;1c#80Z8Ha zYVWAo9H{ zlm8YN-Z*M7^`ZA1q%nPZr?%kMTC(affz9woKEtu*Gpt1gdE+-z{^2V*zx(7o%zmvh z%x-g-k*ws9Bq+~;cvv8c1>#or%fvHxP}4sR9Tm?^3sLn4NoREph&hz~Qt?bB5A8sa ztk)e-BX`o|5@I&R`O*)>d`nX!<`<+`Q4F8LvPBr`tdFO@P@RQgooantk+11AWTKU( zKJjMgK}BqC8>FzJ;2iMno%#;Nas-Nn6{KMA5rE~p)R-a{sU?T~04x;D(^M3^`maw3 z*m*d-xi=&G*{mMafZzFwYTvqWcClJDXXIA6h)D#E%KQ@;Jc?^!v0O#z$b#K9v6zQ^ z+%>trs|0R!t?${ngqgo(u6*6&mGuKOH&v z0O4cl)l%$#St_RYDCHU?|AX*(RhulWcaD?5K|s}XN?wh7j$irL{|BD4BH=8WT zOK|l%QhXTkCWg$nCEd}*} z`VsQk^8-&VY!|Y33)xr4UPPCJD_3l!k2k3m^m(58oCs!`OeHoSPeu!SKdRpA%t!A% zdJ3$6vIhk?^-nl9kO^iklQG2GIf5QpG1}hrjZ!~-Y36TW#N(N#s9t52?}Rw-X`YBb z(kX?~DSAXcSeR@CvmoZxQtvyo_viD6PQQ1Zo}x~VrPKP~mbeMLLxubmiRPR|-WR50 z2i~;oOG#xelrY8kE_LNP!X@W(exQQvjPt>n#_MV{&KlK+E%)PI(_IocD34JVSk@!i zfD=v5rXcH}ylprC?4Vple>n$bq@?p7-$6D9<@!+!e4TfYy9;e?i#SHuWSx_?D$deY z;Aop=6Qd+xOqRAzvkwJK@7x$K~!;IP_I(G zL~o!=U31nUj{0oOy(NJ7I#1pA!{2U*?LeNq@6HLvrskQ4cdD!GnA~U_VW@U>1ek-y z`3Dq-^LG^o&)qu&GGG=HVz)x`8yaC$&Nm9rud{#I56W z!MH>CD^3%f4B^$iyfdgERdOT`t5g=xR7sUQX&8)~;T0GJx2(1FC4=y*gK#RfLqjve ze~DBSC!Bi_-8VhB1KF_eyeey}Y}igv67ZsrB|l@w@?#d_VSsw~{0!Gvfa_d6$h!}o zDDIbuc$tS)>L{N1onA3#Z$LNwOf=@k781Rvr-kD}+YwEkEP$mBAn%nD%z&lehTnK* z$CfBl!ShRbZ{F)_T{+^;ewnULv#xfhmfvj;n;N^ij)q!CoJwyUIfh1P;jQ|~MzHqT z7tJCjF?+TW-8%hv7FksrqDlgDOvx>@^Vgw?y(dAHG0L8ClxzpwcxF$Ka1GqZiirP+ zcs$an;BAvWxluNhtlJHg5D}h2f40UkR2N#~I7%1p^mqEvp#!XO+zFXksIC*XtF;w_ z1MiF%DCx^D=Z~#%GzCn}HI5eah;mHc0xXpK%>6`ZNoCH@H@&sSeD?e^7}i>eoxCJV zcjF+MGt`Nn<>&{;{L3L(n6Oc(9L2rvoVB1h8-m(5vDZLNqfO`Z3iq_TAN2&d^* zI}hLz4r5z;tKAaJK{W9bjdCj-zX(KD@waf;y)0c? zm+saApG&5+<<@dpb(c5>9?l~d;OJmk0-QVWI%qplg6*w0&2X2PEVLW3Xdw%ocXXB3 zH}b-pYY{Bd<)6|fk3r{9?$$S+1Ev9cDZnbVP`1?`Izj-HmAVQn8kR7EvmZg4iA2!%gGP21#E8F4B9|IN)W=t6v zE%5k<(mBrKK9ZSW3&9`Mlm1Lcj@!dHp)CaEFo~V!WBFmWM3X%@mDl@Zo#}zaPB#t> z#w)pUvuW}+YK@QE<|^qar#_mfStZS?Px2o7LH#&I)Ryup0f=YbkSd;mHV3VniAk{u z?<-&c()*as5YpTifOJy*2%KsNM5b!jjwz!3NHU{KoI|@Ejr=3163@I%U)HVPg^YVH zDSZP<+$&VQ5zkBg+xb56%)Y26siZ5~3p)(O8mfc{i6fYr66(-k7_`*ZWEJ0<<$MLc zgqE`c9p4Hi@!HK?GXIkvb{gff}Ugj%{;HOY$aUcnPcgrN?h|lQ$&J# ze@x89+u;RhGXb1`N(nyRXdsuzxj0uBhjTGd7Y9k)FM$W9@Viu10!(W;%i@`VED_|7 zhCiLxZtT$74zx5KA8teIMjz6t_i9l!UGy+Hu6k76B~pu~>H-N)Ty7;r(`+J@RMs*H zSLD@~PZLdCO$i8VS>?(B#uzwi;Y^y= zunp%?S#&Iu@=ORVd+L9BQ*d79O9I~K}|l=&||$QnGN z2bT4JZdbb^>%Tx(sZVQcR;X@X?@G=NzG!wlXGEoj1Dgrbd{_e<(!Y zUf0aBHLJYMkb#T#qC<9~*^lDLr~!eH^_4h@QJ__#?|;(KG65o4o=uyO?( zH|Z)}Ya^L|fsJTngt?coCzT(v6{@v#gJXUoz8SbA4yBNZj_h-` zCMv#MoFP#B-{O*iLp3$)?0@w{1G2WG>oEvK)>7;oE@m@<$WDDlmjxorpZcJNNq6UJ~m0TwB36-ennZO%rG ze(gOwq(0$1%b0_3UTmxmHETZ=XZ_lqx=R-wW=SwOVFznZ0U4v@%zW~!WQ3JOCOG$` zBXNS8f)`TGip#~6%S%d#F_xSH`1RDPXT@b4RdUM-6N3geh1Poyf1BlDCrmg8h%oxu z7sF1HRQ$IW!$zw4|M+6q<%8v0)md)YOCYi-hZfw~d;8}Yo?4)LHz!ETC4T9My)m1P z?c6ft$``KuJo5*gmARbuuwOcNdvVV`m1;{|%xYutz5!p%KTPcJ>IcfUVvRZ~>ME&_ z;MN?j6I3^_&F=WL!B$dtTD3o1#M!iJ$tBaOK(0y4h zof$I4#c5wq9%S}nOl{JQ@cx)K)e z2ozI+ERKgMY(2L$_FL3J@!byIICFv4dmD#ZuIrwtIv!rgL#LZ%3>HWqp$B!^fWLNy zx+vU5!xuyZYrh6NiwI&aHc~|JH91Nmf^Y0yK_Y@e&S3`fXdrv@R-0ZO3OtdQOc=~q z6Sc-^Y+_4$iU^!;4^Dbr{RD>K%^hg}@2}LMIR(j$lvW99Jaek>i>%D{1DY3F+!%X$ zX9xM|3v&^|tu*uwsfEer&*55sUQ^cr&t< zJ#B_RO}WkRzKE7fKf5kJOSQjg__a;vWsY|G~=I>5$&>fg-E18Z#B1n3Y`& z@I0F_k@9>q`$U|2&dgrx2s#sj*i$5maI24}zW>XoB991WFZjdIy6k20kEg`jDL1=z z!^Ma@ar$pVngjY+u_guRX)P{wV{bLN@$dPh((y^Cu+TC#2#|F}o163ZlbFaW2 zr&`Q={e|oSR?P-PgajipSg~PEzo&QV_d4&*zTeQijLqKQ<0M#YII1xw+pZ2Ke0SGr zpr3w#5pGDB2_R@$o5kodO!p?>;-sAj4sjaQvT>a(wuNs`Gk+}i0-_}H6%;V}Qm45PPmSZ5?IiF0w{a}e zdL>5`@Z4|6pJ37LYa35nbi2Ve&M1|4#@`wrHpY2xeJ(h51OX;Vg`o<;7w2$-WILfS zq|)C=hr#0Aky$vcfCG>uKx%JEJV>Z56qYqVFQS#Z6TcI4BCQOLR_+jGoilw5<=Xcq zE}r~Fj&DakZc1Vd(CVtWuhmh5kByBlY$G=QOl%vl@ij2>f8{=&Swp=lf$&#AsJ9>R z#m}#tqSJ$TW-WD)D$}xAKA2;{lKCnv@UEtrMZZ$A>0#5%IgNY;&v)aGB-IVWnSk|A z|5sIK|jF zO07~6y^$KIspQ|}G`zb$Gfv*$);Jk@8p$Ca8Ye$BAAh6w=}2y!c1ylZGyj-2ZZfjx zAb3f`X5Pbq@hAQz2_nGrm!msy3eW|syka;M%0}ylO*NnIhVMMd#+qeR<-BhuXEf0h zYsh?3qWUH9^N-@*I{*M;-K$uL;PumsH9S{-e>8u@vhOt3>5|G)1s2K2 zei1t3D!uoGiwg`+vJO8wSmdmcwH!HXRJ3_yCd?ca-Kk_YLFyZIm&smhWOH?eH@~kK zQ-a%5bDeCAddNDhX9|r;<0>JolAdgn2GQ0guaDsu+0Hzj*a(6YXH@Q?7AcTFa4pQ6 z>v)KPle4;d2anD~MgmLQN!CRST7;V#eB@X%#^59G=!bP~Yq@gd?5ncMn~ z5AmxWKuX4cs_M=lJn)!Jkc;xg*5tPmSMb}bCz$5hgVK=vY^7>eZwRFC$WShsFXN+*R>sndAoH+Awgi#T-hqj;8%9VDpC z%7e}}BPkk_dkWl39~(H!2X6nTn#h*i^D9@jw_rTav$M~UVf(V|(^1monzafu6^H@XE?ciu@R4KcCsrmZGi%0PW z@MRz4$FkdJ&!CS#mfPgqyR}Wuaez0%X1_0(v0}A`=Hd~d$C*9D`~bDCqP2g*flQtG z5Em{Rzt4NGjT+@OqyQ`12odI7Q`TP&5vZo0q&^Z%jkG`al|D2+W1Hm9v zhOao`QSb500U+Xc`<>owI{=@;y)^%EXFa}#&@Q)7Fbq}i{raI%6p}6{J^7SknIAHM zBC4~MnJ8~NyOo)!qQb4-63}ppp`}-ynFXb(k{R*LHFQxW-uRc|Sld-Rb327$b$AFr@`dpI8M=8L`Ez`=O?)DQ++&(-ybb-MO{ zkqRsYWT;fGp(0}|yyBThfE-S4SmO`ep#J7iTBQp9FXpI5E^{`yzxuVIeG_AjAdjHj z1o<+@=unVv`b9(An!@~{)xO>TU66k~vc92xK+Mtl%1>aB6XY8y&JOJh^cx8BIyVSc z*wF5>L=abbr&8H(q?>f%;Wn7g6KF=cOYM!=3IyjG-iZCh9h%IKxkK}aMZNFeu_4~- zpkEsf@yx|G#GTceA?|!iPQm?K&7P-O^+<2dySdS*q`XQ1IEDp_m8U+J|sjC;17r903R&Cr`C_p9)?e3+Rvg!MxYZbfqplF-*{$Qdb5uGC}WdaE zE&z)E1NYu4>&We99j@f2n#VJTt93`P55g%+&B%*r$e(!T;8r=Q_3vD7Om9LbWD77X zY>*WG;S?$%{SjCw9d?V(pZtOICTbk)XI1>GcofgPk_X?p3D7^q??zAF`nLcr|Kyd< z)?qkeuAVzk*TL!nEb-Ot(?1GT>wQdPBuqmqj+#LABCPQbeOW}*THTcOxyh~b?f;X8 zFgzyXJF-1j^T500?c8vj37vI(nrRcBb|!O){mT)u7LG6zv+lhehN4Qu^;u-yx&Qnty(*()<79H1iLa;@W5gxj5_t zN~_d7p1B`bp+@jG|7ys&H$7sl0(h&Is9I5`KY$awuo@Si7M^Ljbpvlv)tOoudXoo_T=Piwj2*PqC(0#^Gx zYc_Zv3k3h`2;?>~a@kuDY?Zp1Cjq<~8w#GIADMjHGv#+g))<|SM0q;aQmDevmaa3t z`Yi;fzi!m$A?WY7yW6)EO`S@ODj^;EDDljT^x!Wx|GMxR1MH0ValwG33m(~&Wyuld zaYTysBbH3Xe1Nuu-`m%9d^GUv*}8egl8erj6E<8dWIvf+Ni}E1${Nj_Qltqq)BgDWK0omew#uYI)Tn{;aEMH-%Ld; zIjr%Ukt+|T&X>N(m)3phTYJvz*~{SB2?Ozr9Sm@)XG7D&5OEwVKvYC=y5Q`M0%1aB zZ(^n*ugIkl2b-Zoyz18sz3W>WX4i*8wZXD&u`X&22fG}ft%E*35Jf;3xKfh;+Y%iIXh?Pp_5>!eBq6=vOK*h3vI+2sUy5t&Mxxae${jlW8uyd zNHWOb3e0lQ3n}~(rqxmO(~=O2`dLc%{&=z@cuL*rCz?2KJIzYHkLAUI;$O(U_aaw9 zd;(J$(EAhnMK0xiEj-%d($HwdxHo=aNigZ!i^>$5WwSV;9&-T z+IK?5{NGh-wV9!7PPK44NnzQL#xt*~r@r)*MIhWXutHDv<%uzN6U{?>kFJ-o6^^lM z)vOXdXy*!rJ;pP>%D2959jR*WNwuCVSR-PK?uC1y!oLU>F%C;M=*Q;fQ}WtUk*D>e zap*r=^e-@}YKnn`23bpcwxg-y*sZjdT-{m*A(o+JV(zMTyVA~Y(-28(YqYsN%AI%= zfXQLFJ+S?@V2CFBopE58dk8CLX%7cCntTn1)_ZM!ZCw2R2(I@EeT8D#m>%q~9WCM& z2(k{(H74IiwJ_MY_L2IeHwAf2p}}HVvH3uS=NdvzqZJ2~q$9Ty9R#kxq4)~80*CQq zu0TH^du_lJev}tiU*)y6ZgVG8C(o$ccRVwcK8Yn-GK8?% zvU+8n!8dU%K!rGQoc6h@>&3$BcwTFA2L9(s^i#cCt!MGfMbT)%;A3s|5y)xY~^MlkiGtMjoY?zGr+oaj@m~&tWqzmXRDJxs%`KNG2w`f6;uXq zY+ntYi#GlxaDQeDoDJUbUvq7`WYr2)*WfMUd1yegx}vmG~~%Zv{yW{J^XUUDK!DL6c^LgdycA3fVRW;a9hU=hEB7@p(hTxP z2&3QT1Q`9+&cN5k$UqeUic$MY!xhNwi$U+{$PO0OnA~21cZ1ws%8$vdrEzYj2ble4 zTN}%J>DhGmi7yyc%hz#_2rTat%4gPJ*Vm899Fnk!IsZ*D)bfN66GjnSd<;w-%W5Y6WQVq#U;%!bdImenBWoaIBS z>CPGC{^qMj%Jd_Hyb;WUS?0Yw+s5|g-GXQ1EZB`TP-_OYK}k5TgF)qRFIxKx&;njc z6a@piOx&nv-jcNfv_Fw3Cg>6|JXPbGj@|dY>*T)PVJE!a2OMv&98&(X%}weAIwva` zU{;^%H8rj{dv+S5UW==A7`QvX!CU{?XF*W~;`Sz$to_!oQdti6W}bvY%EpW>{?e5i zO>Ow`&0DcdK=ccdAm?rEr>d`QSA$+QRBr`bJfoLgO$Pil?Y&`;6!Pk3cK*~w^*)+0 z%RZA-HU?Gv?m3^!@2+a1rmN&uzDW=M%nyJU1D^cuubG5ZYMLY9OF<~sx+W(QW#=N< zD;80r$w@Tu|HU70hD`q~vuKehT{(Il_$Uz1iO!6SdnpGzUj^wp?~qixy=1GS%wC|5 zXa0qHt||dJe>OgR5C|?`8TRz_C+f*-M+cTexyzB^SG}RiY?tZ?xxwMU$!}QEtIM?8 z9n;>Fj4ee1U|JIRd~Z-pb6an{+v&g`_mKmtO-2oXE9Q;E3{(k3Ex_^2djj}2NGpaR zQ&lNgI^&8>v^4T};SY}Rtv=H&$b5_hsO(ERQnglnn?BW>yy(+z{Fpu+!#c5d%!@YC zKI4RlPNRRDmTo6REJAs@nm{jAMis;|*4u2D}7!yil+DDwBFW|bb~$U9!okH^ENi21n< zHN0OSBee6WdVx=Iz=x^vG=QU#-moEaI&_-hr|l;j$W#OaxfU-B_gwG2ntN_{GSzaT^immY@~RJwKo)9XZOP7@K?N;6yO@M)G5G z?`M>%x8zxybb@D-?mk_lW6cBNnnPU3nAcVRZt7Q`;ynP3*wp|NYxx3ZKO@ z8&tF>MW!`3&@PO(_N|wjcRFrvRkQo>*6V-qejDkIB~CijLPic@ZlvND(5BLVuq_;e zk+6tFz&wjYED`XFxo?qQ^&`Kd1CF`ZXO>Azd!WEgseF4D0S(4sGOZl_#M5@Kyl%@_U-?*Z3C$S})#gy0^L$NbvN+9>$_o2ou?_#)_8 z$KO)ZUhEdl`ZkCEioCcxc^(SL)o8Q2qWXYiu8zF)wa1yYl4ER9=_B;DcL9C-Kghrp zM^=6$OVu_al9^Ipdf)5eE~v9A0m)I;MzGF%!Hq9!z&i>oWWc&o7e3Ui-A=W4`H~?nhO9s*e~H1UMOZwuRbbC)C_a@;$u0nGMOk`x zJ;S4R@7B}k02s&KCk?ZIoe>cG?L#BY1!e8%H`EbV!SP^Ft9SBt2c`xhF}S(auN~HO z*N_})_%m#OQ#*(MDNtGqe*jN+1GBH_cm!_(Uig<#vq}$gj5$Kj|76}!giRSp4U>%f zgiz@1*4sg)>)==c=uHRK>>P&~{p+!b*4wns_1D+t)Y#Q z(w;*JOakw|z`W?lj{4Dz`3UIV>ZeS^{{j#_KNj{p{ZYY;?WNYp+g?4SnOrdbAkBOq zjZdEkSf8;iU%F~r4$oD)TF|er1Kr;qDISm>#Yv5Pg*LOJZZ6`aMmwd^J_%amE6Eqb zlmV$9{S?q@4OBeSg2>vkOjW|$@5fLCro;5lEfU<*(W8MsnOrJXNOcZ-SK}y8{LLq+ z)AW7SK{&nw-O$Fi!7r}WBMb@@Vu57pCMAtjpot$<$%4;JFr5yp^&Wvmk~^!`6Jd9k zS$B@B6)38@-Bkh|i#bHY+?MVP%VKNh@;f)stV*?NwT)*^R-5inZ;u0&e2NPD5>f|J z77AC^Y8aNoRBPK1%XeT=D9$tM#qvRi<@sthmTVy!YyS_Vu{t(UQwvBA7o%4@ZLIoX z&wTkv%_`n=#F5rra?_wXmTRpAZ{fY<2>s{Vwd zYvIcp|Fy;H!9ucY-wy?0@Y|svEO^`|z&)VmUqal3&6-PID70D6iV5k0?LXI#*{oaS z?4%-7?8jb&Oils|?-m0z4q1nArZk)T*tPuUD1nR6&h= z0}Y|-I@a+3X5YU;rN-=|%?XYiqaUfRpGDw4Gi-8v03bO1Xvpa`4+>`NT(w4ZoqI@5 zC(Waoe;}qH`|9#sO3+4jCU2mGYUrQ!(8||{{d=ibr7r65W{v20%LNB*jgHv5&s^8* z4$gIbj4-|&J;ijcjd6FwIP&56Cw_lg_&dAjcV?e=;5iKEMQN%uri#PL z{#KesjAu5sAf!GOjQ#G09O|th3`4wvm%5XkG%5?oa^(&dhmUvD1RMvqrR9uDjqXZGU&c!vBMyG>L;Plfs2Un!+>cPG$eDV028UKN<3 zEn|)(nWqk04fGq*usvP6)9c7w%xW$`@j2FZ6ef3M$Zm!%`*KH;15!&e(c}`|I(&SwJ#^kI!eq?fX1L`-feL)C&O?7>|D77#KRsvdb zDoS&1FtsCFQVByH7W)O-Ej-pZivl)}lMr7_08tLVLG-SLK@Rl325SNF3Jc;DF%Z{) zKI2(H1cxgl@}=^XeOG2n%d8E6xrqh}>x!`1xppNh(_^jwolt~4om`!X*1fLpbvuMjx!Xh_IL)hINqQYJc z#mq(+h_iH`x=7oB7<_!sx=7o)`M)?Guz2d>nDIG?$qN2q9;E!R3V8BRpScPHC^}Xh zK|FmAW-qL3PfD~djtIu&=Y)BcQM?8ynn%wH|F;28TRhsMHVg~*5S$toe*cz`9p~gn zjlrLi_Sy>YE=Bt!oAwW%6xy=@fZ~w_eC+P>Bx!GpEwz!)az23=TzliuCq?fOr(@K) zUeV8uxSxZ^u$W9Q@`A~%$hr0?Iq>cWf_^Qa5AoTJnG9>(-9B1l8zMUKS>ZrsM6U*- z<~A5$mf7|yd*N*Wi5XRNOWhmLkVXa|m?`i-O8>R;zs&p-#e{Equdqu=PZ)fm;Oh=2 zFtVhlCAjAarnbV5tQfRI;~CqE1hLf1M0#f099;4QaY(Pt(rD4zpvUe=XMnEx4JMP3 zvGp`!{%UM}7}#)Z{SWdv*Sb+vF)K1}5KFD;r-EYoGdomW&$Nry6+#K4E8pojVD@i^Q zYfk*~Uq~(jHY9nwkX%TTS&`|Hwr#pwP)vWF6BV%c^|n!x3rTX93s5w_MD-x~St+SV zcGx5*jwT@0Rc44epD(B$UL(jdtGZ9P1o6#=H@=U{sQO;(1Mz=7%=H zooVS^fsMDXb##@$aVKV7=gE65s1G3qW@}6ZdZdEA>wy00r-1$=$N}3fJg*bx9bgcp z!hatkX%z6Z`xY!?z62D|d*t}Ey8dJ@vZBv;C%N@OHBK&)Dt&n%qE)1hvtX>UjBZCo z;Vzu3g)f2U3TJdi3qTIZ-bUDW%%!S3kVz(qhmBDP5_mNpjPTa9If3s8pR&W|7$Ok- zRcwLd=gZ5(n{u>fe&8J!%YRqF(Ij{9q_lyfiJ*o`GIyyKaphtrID>bzcXH`B)nK4C zNca_P#QSG@X717gDOD`APU1TAB)j_ZgRa0f&5yICIH57GF{V*C$%YXMUvus0$Uu25 zkc|lR4vZS*H`*YT%~NRA<JNY9aM>;{x|p1VF_rZHbZ`FU?9o>hD|XU2Tp z*jE|%uTchOac3XW_YW4;cw z^uZOrptLcP_y7|t6gvfkt&+18LC-_IU81pq|Q1Um%%)kr$ zw(8u+h@!Z-G3Fjjn1mkDZ^NPC(8FA+d#w|w>|Wa~YI_oD7Qo-eKpq0GK<{XNuAk%O z5qUu?0U5_atF(MT;56f)dI?z_4oO`9+U&=U)y8NB<9Ady1_KK$}Z#+N_{2ngJOz7^cC!K_knpn5QC zxhFK+wIaz^HB0a2(eJ8PFn@Wx?|S!E45u_X+qVKtc*U;;5O=}mc=nA)!GXTos=Hgp z_x6|1Jrq3c)K+CUtYqK!;dy{j#g`t1@f|ctxL(D4-l2W9_wLTAvZy>C;AR~(%D^X8 z13+|(7Ji9^6OC6Q$==KR>UY1C;3_CzILBbs>2|pzMBdv_s=q7jF?=XPgdao=m{+(9 zww7n5ozp^WRT7X=P6Bq}ZXZ4I22`W1N&tbrFT;~0s$C??dsDRd{C+^Z*8&Ugokl&W z#J4w`VmKt|O^(S7Tzi!Wss|vP-#{avlJ2MkiuIVM%@JIGt}W@0u|fEr)c3xGmc80L zwMR;OwZ$W&Mya-HyE{~;0q9Jq8y+B}B?EzkoScHwk`cd^v%Z%wDBP^Cp74^D<$@e~ z!jgj09R;U*YxjN>PboR?YO~W7YPgew)TD&PuK4Zf&IRSI7GCEH4KIRb)P2i6!2?-A z!#G?Ud4#JdNmDp9zX<(dDTenA%h=KDXD$y9aTRQhH^$&yvgSzEtqP7SxX}Xjqz&qN z8Q143 z*?GcHpyqKTxeCr#)$ZSqXkl|ZN=@B(Jcre-LR^s=*l4FVmw2XTAa#zg9C7bu461_X zut5pot0ZoyyfH2Vaf6+D#*zf5K5R*ig8lmnjt?q0xUb+uznUAhM>Ynxt18%Wpi2A@ zlekO-0v_N-L~kOZ{qe%`0FnV9D1O%I>p)1c#9sVBvvV~4#ctQ~#EkmQYyq; zwdtO^Rdcl6iAhkeIhr@Iwfx>unxh@tkfV*q?}Sp}RQ2$1;Y!HADZN7vyL~@hLpifTDBqoM0|}8u|XSn z3SUN{{ShWF{qHDZ9p?c-=mq7V?paLywPtZ${=i6$9Q^$|f6V*8{X1{f69lZnjc;>Z10&1n|35@+TGq6t^!qHkVzPa{%LCF#AA_cSM8|qX!A3xroa^x0`Ud%OxGO(eFYS2$X-0 z5_4;~ebej zwsqDeS@Flh$tpk0wY06X>uam(g=U@VoqygjE1Z8e$$J?2ajVeQ!J#IXWd*-=xA~T< zr%OIeh>Hu|_@7RtCpZ3q!DmpYPU}8eNrT!28+R0(#Zd7o(lNtwwb?Q#l+egsQ2K`} zBJaG9%MBh*R$nQ_{(QdinHntvfg1#@xNshytqz0TEmqdrd1 z7E}AdU|;SI9(Nb)KbNCTFLj4{pK}K{xM7{RaWe{7?FnY#1HX--_}v8u&bv>24b8L7 zDNe&2EwAAUs4@IDU8#PPSL4^Vn8BI08QObYt5T1hgzBzZ1$F!YHFhFL>mK(@j<)aD z9PP{Fh(KibxG*A)BEn?W1Z3R^JyjK&YiH51cShMy2$bcxv;}3JG;GWDE%!Ee7nH@by}|v~XqEU*C-Zw< zIO-YcvjkG-(f6+y4q~?#P48(1P-wU)QGJuK@+6SU#bOO<KTZF*6X{f&dJ=YE7aGLJ)~R7QWyR%h@uV5exS z8r04|OW0fU&!)f#+~BNnCir>&fqnUB0DeP8jcwYhGtR=xoPpE6>pE>iUW|$E_|IGg zTjJemzxv+G-?$_H>~-3`uY){o)ehJDF_eC;6`*g(*uNfn+58qSYS_;PucTcIN>97k zW*d-{(?^@0QJZ7GqXj%bZ071{;ZYDw$2Ew^(eBs=&ZB3Hhg?o5)rK7JU1JNFkhHy5 zJUkkJ8NNGz!;btj*Uh<9TeYDAE*oY|aBis%A)H@i&cbM^UVKZzqfR@ZevLW6Fh|=7 zqXqU%J-nc~Gnb2``fo-7vHyUD@A5k@Gp54LL^Ym>Opa4f;3h|SD)_stl*35j{pvgs zcp1`Ak3cuZp+N++8HZ@&X1wMs?E!-bKI3x!{+&PO{onpILA903=3OMNa-RRM-v6wA z+yCfE+pr*^Q|XvZ1?S_v^9#=7=J{_R9VL)oNKeJ_3A(n<;2dWGd(I;p8K4kv$|$VG z@IvigTIrcJzR84WI)lGtUj2m@I6+Zk>YS<>!JV0%c39iv?D9mbq}Nb+vZv|sge~cdLul-qKx!s=ye{jsfi&*uuZQ( zhc6|T1XZR2;CBKiwZOaR6I-gF2W}s;$>wjY|0CBO{1Pg7-5U^Rs9;zE^djVFZ8D)T z9b4!d3T74|IJ8uPE8zKB37R1M+q`af@UsD-CWmDo)Xb_JF3+JKw!-j?5Sr~<#NiUf zd>5UIIEsS5GLPO8QKk4qYdx&=Eog3TaM;=3V0M)pTY~o-!o%X$Gg{QB^x@gHD2s0; zs|92Kdc3)G$1bQM)P%`n_EKlbYd|(CGj4q4QcukRT^9rQ8-#`TCaPv?#I=`6gx z(#J8wm)rC^^{fic!m~2T&k3No)##mwzB+i_48qPe-9Lb|c?n)BfyHGm;q?%ZaX^kf zMC65$SY9vuw(%+;TJ0XFfs*EZAjx<{V%6&V2aFAn(4LOE0N`z*iW^rWlQ|vwSZzVg zq{3eYb!yH;T=ZzuMvN%NC_nP{VO~8o9{)T|rX?IlImu97T_cd0g1WkE&+8*E0*bHtR=@_=u*IQDq zman%2{*dNT+4tDKZewl%l2ta&X0EoA*IJ)PMudfe3qME;(cxaCta2g&=bA`y=C~5Pc-?x;0%dp*XLf1 zCAV^)Lnx7^9zA!iP*y2)40@IaOZ~$&FyttvpPWGgUT1KE!=$DvlED{_MY!5_|*mzSKECd9x+TBfN&pFk;Q;Ly{HCv8fk z$Ed9yhgp~I_#Dm#Yr5fU1#IA?+MF9R-6-(`u=y>TxLkGbG`+$()fAL zYE-4h&(~D&|EKYD*?Uo4qt>0^1%~dw==ixD-40k=G*jQSKLX^1>@%el4^~gMGOCA{2V3KtKqYQ^yj8E1O*vB*P&}_fgN#Vvo(Ci ze&dP>GJKAe;d5%GaV~sCM88~o{A{^^Ev!C$a*^?K9gzO3@v|8fN5%2;HbA^^{2V5+ z7mlBwqPIrI&ja&O+kYQF7ek>Nmou+5er|XtDun-S{QQ9G;ctwe{{hU{;qiYse*Sd% zUyYyL?}kPjc@;2$*x2Le+s~4h_V~F5u5Kvs$#fEi5?{a@6zc)}L=^b$y8y%sApf)R zb0tg2`1x;yFn$&@LdMT^jObfjil3PA^L=m{dNuuN!NiAA8{;Q+ff_$QL2hTszxgiX z=Q~pR|1y5whcWX1I(|-X{8!`W>N`OTS#OP>-HY&EVf^fg864REJv>xke=^>{{)zaB zu>V%TD47Ui!JDg}l5C?eG_2w1W^}-24%rv^zZyUDq}B_@&u=dMtMT&$X|ndqTI1(^ zSf2s*8#&TH4@}o^zNW^{Uy&OOP~+z}(uA~3K+AAdh|825KeLb7l*EjmFG2J$em?jN zf5csP@$qv!0ITuy9}LO(IRj-cHh#`^2X_Kyx&;&CC#Ij6eHLNL>4Lan99oIsG8J5H z+oGI(4t57Wfm8S-Ek%DX?D25JU!eJ`s}N?N|3t{6FTk7zA0W|TV5%=JVLZ;#vthR# za_LXcfLXEND)ZOcQXGYN@smrx3WjNsT^2JV-nIWM+V~7;w3PUYS!1v@fCCW`Qcl-m>R*vE19kmvQs!f=38cWTtVl{*Maoi;l4g^l z`CqFB(3m${?Fcg)5umI3#arr{3Usx^8zk=|bO3Az{gu-gxmNco#A7B^jCheOE*PtW z@u_oOA+c~}*k4;XB?iC<3$BcF{##Uj>!X9S=5l*tK3mXY;tBLLE$|V&SU-XC?n?izsORT^5%Js@ym*N9c;M z>~}Vx%qsnh9YQHK>D`AA`1qc9g)aE~x%Ey2320lKFu>gF0opTc5;{n8b^yC7> z0~^ghR`^1J*Hcr#?TguujV(^%>~a44ly%xyS6T&yqeqM+5MZ(LS%vTEufY=GTN@IEM(ZO#xPzWlQWa0lWc4*n&!8H%m3}TPR^$?_&k2 zJp|(m8vmG8R4IoOcthT9ukq)Cyx&`S*__38a~iA-A1CwZ<7bFqd@1sIcZ(Y6+-1^% z8#a0zvcv7CJB`~FzchdIs;C1u)Y50O#aTYA1wOgGnY-D2a4qgLY65EkceV;yPcMwW zj53fKT4_2KO_8(tG8aw9n>fc)S|zs6a?oFrq&EYw4}8%#t|g`WBu`aM3zmrE+q zMm>-N843>pBc(o<=L>c4#5v;FC>KTt9$fy%&7TyBZl3$*KE{Nz>l(ihZx}aw&1vqRs#mpn895*5wKlb`T71n!i-A zC%-ol78l8-_cbO4x?|v*{7LWnJbt7*P|rYr_e8wt@4X~QE;dQcL#B)9?BJ=$;3Qv}-d!Vz0OkwW9sr zeuO`m|8%AQa1FLs!T^7%fIo>Z;EnSi{6q}!-O~YN2!NO;g~B6-h6a$16KDbUnU@I< zj~J(CFq%9Z3AUL7E#4i7L?0F2oiaW{jM5EF5fa=EA*r}al5~`?qc~kcKe7@vi1I@d zSg(b;rNI@^oB>2b=0vv#pwHsW_IR*;ZbynjrafF&Y|v2>6VtT=$&zx!xB)3FGYagI zF79uN6zPb8y3mi#wOPQYcr93JcB{_3$Bf!GGnzi)w^^#Ix)9UN`nYnsK{gWw37eeFa1iS=D_ff!By+9LiWzJfP2{bBq>ntuOO zH2w9IpHTXzOC;MK=+QOrvVyk{V#c!D>;Z<%4bt&ASnqY5mOlvc=94<~L)w+L<+CLD zSF}VZv4>PR9J7q9BCyf}<0*LDm<<0fbxyjV%eer)zQZpupo4*ab0P{`!REh75S8D0 z(hfa+iX4}{**hKtrm{EtRmd^QzzN<6l$gWNHb!Ug#XhOI8Q?+MFUSTCQ~_xv0Z_XJ zJEY=_FAfNO9tc43<9*0|!y&UccgERg{T{ z6Kq`K>YKlmr(`>DMf#sH0KXA{+X#?0ta$4_E49^0A6)6^|lo(I} zf_is~up(kxAAmTK6{jdxwUTV1fGAjgjH{ptoog>cO7WVDFv8pbEna*%lF=~CU>?N- z!!OVD*@qsxTa48mOECAbxH231#S?7r#Sg94zyNUEXaw{q84E$fZOF?5hqwJkcF^3k zdv4$wCTJu){ zDUk5fzIg{z14ASg zbC&*!IwIz0q?)?*bhHv6^~kyAE$Mp)pt`=5sRm9x<9B9*P<#u?BDBN)(1)e3=WZDqaTyeAr!Z%=jIx z8E#^H3AWi?x&}Ck^Xkl3ihOoArga9T%Qbr_-4LvcjNoD1Iy4CjKs<@W&MvmMNyD`G zL6m1}Ry&RMd01XfnrEQxiDfx()8thvyrmyNP0DBP33sRQN3LkEp#8tG_`MSrBD@8Dbzz zZ|nSlh;TEWn+jGA4b6>NAfx`r1TCWfQBWpQ4s~Wk&U3%>92+V1UHpjtzmt9Jx@?r9 zhR2YI;_3H3M(}%$dw;f-zgYd&TqiI9Wx^STmP7dJl>a0|q4#Yd|5kv1X0ezyO@Bk< z0AM!@V7CZBEs(&P*G-n1)%^$eF)t5G6)k4{a{mF+VKghxp)C}ndPn!cnjLjx!TQ$dLM0Debp_F%UXRzUGY1-*pT zaV$bRJRG#KbiAH(zjqKnWH;8Kgt5a{8rDB`N^&EBO^{6EsZsk zkd7T|HN*V@qboV3r#n~(E#QFX+UD_BQ2ECFDz`9fKl_F-EN>CBlVQVPeOL=2NopTfSA<+R?CJ`J z#NQCif|90>d!;*+RZm@yP>yY^?^cm&p}lztXByjYNg3iep9UJ8c5^+9^TDT>QTCJU zyXbt-+E23g{CQf@f!kxU?=kPdo5Blb3h)v{)P^rHRzdh`^GOz=Q`?%8jBj950 z&^$P|sC@aHp9(%76VQLhXOM*tgg=s<^V5}hk298!hsAyQ)kq@FBZOy;OYgyZWPR?6 zg?I}!ETQiql$d}w%pjcjiA+*@5=buqF&hy8DDVVdltV6@gkuhd1r3s7QGk0YFd07u z9l7v&6LXq4t#GQia4>|bohK`$6fp9SMuG*5$I4u~tY>)ijwrogI6Ae4-i+}lx>}#J z6!W+5(OxeA@}KQL`93;-OZkKC<(p$?<@{|mipCjtj{`Ae%l!!m=#F!K{>0AT%I6~{ z)bROP{7E$N2G($)Il`JGz$m$f{0*h|UL@I?{sZ%yFHnJ57jWmo5XmeYpx4>&qJ&z) zilv@>MK6WY;$?`AE}lo$`~#t%A*tvW`+(Gf>~Pz;ml2Lf@3o7gUM=Y=xK=hiz<75o zs--2FiQBsAX9JEu(}5Ejj&7F)^M&rKtl)lQ5)Lwf-oi}Ep+06MiU1>#PxO00NPT4) zQ!a3N^1N8oo79f7E*lqnI!+g$zTo^qcW@tO0gw)=MJP%5Y)!o3$Ox4r9k+6qA(Uiv zN$7~tdOWfOzx4#CflGEjS)LI*?%J@wYIIR(xf9cLIka-Z=z!oxy2);QbP5&XU`Z&AEOL`@~^9oFxk)5rT~t_>5`KOWNW{ zTKG1j5nuuFU_JmlOYV&%S;g31;XI@C)@Y3nO3nu*=Uyhyah5!cw{TD6@tADuB-^8r zZ1lQA6n*Y+lJP9^u~M$`I!hjpa_^Je&r9xos2Ca{Wj=or zYs0X}2%gNqC3^d}!@e!WIoW25$WC<#`5NrjiZw<{t_BeERSdZ$*D_RukWmFS!bO!4 zbDx4W{&rXE&7b5GBGvPDsJJpQGq-5- zGBIq>zZP6#X2w%oumT-;!AeKV1Nn*h%q_@kfnS(Zu(^AzH66sK;b;t3^uI9?x(@%~e>)e|-_zmxKx2q~ZD)_}A6z{OmBRw8UUC+k z3ipD9rY;hWP=$jym_WuDfGDZeoayPW-zC{@LHe2l zNH#h`-AH@o2~LZu<#RH@7BKahdr~QDXvLCDGvP5R6=UxXE=o^OWBZ>2* z4olIUWm-j!qQd0>!yDu&8$(n?o~8jri4&zEPmShCw%d@t<_O3$dVgr?yM+SP(s$fAZY+Wv z+WIaN`c5PW`VJCQLEn`s2|5BZxPrbD3EKaot?%ZSnU7N6bps}UrSBFUZH(4&1=lqO z5|H!5>;jQtZUvCW4JnzJd&+N-^}AgC2KJ*0D~N44b`WALL74z!M8*<@V=#^UV1U|M zqIu|_fy{gyXza8Nf4H{j-8dj2f$nyoqa8>>AUw>aFJp{Hf0sG%)d!aFV4XSm84P_| z_&5=;%!Oa$+TrXlyF9@&p5T5@(8?+0T>87rf(i)?Xt5w*vJQX|R;a0jM}5Nsiuzr6 zS1z^zleZ0|>;w+8~ZGth~?#?Vl;7g;O3tqn5L zAL(t2gFM%nIW1zhPK!Ol^E~ZuKw0cZRx5}9A&h~LGj2xiiV{Gt(Vw6P%HKzK24T6(h6KcTUg!6YFc#pW#zV#l2 zrR&nMsNWm+&}{SK`jq(iO#hEQ2h|)8S~ChpQZO_gm;>LX)^>{hr~{iKJi&ErM7SFS z({k*cAi>+1O5$`Ejv6Jte+P%r<`jH=2#y+^t*ZH#)xcZ9*#zzW-4gE@hD_-AYpSwr zC^dhEm@`X;(8N8&^ZateeCISA#38H# z0)bhRtaIse$IB%NLDxv`lC0l*JYWfYTq(rGX@^k-0Ay(I0N8ZyYJp^gFi$f@HS|op z1pqbwvtR`Gcx(oS;HBDclgf6$IUY_}Rdc`uq%T(a@Gu0iLdq3wCA}+9ZMy&4YWvs+N1* z;IhRLC1JP-E6VpG%AEIR#1sJsa+KZ0H#$6-oJbzbC;;Yk{ylC#x|A`M0Q%lC&as6n zLG`_Ae6ONoK}Q;Sn@W>LcI)>nmD;F+Yk zW|k|MEH5bhORHV0$$b3FcZG()nM9FVZ5&uD-XyisaR8~@#_|x*k;7u>ek(C*iP%(w za?un2h1Y^J5ajnn0b#+ee7pG)%3WL|J^=5&xeSls)5E|P4Ck%+qxYk$R0epUx@2Dm zc41v*(L>DQNt?O>Q{)3&9pIe@X_DJ#z{di%Gsghkd%Q6PXbC6|Sf#bVTPVSuDxNek zAbg*jivXSZjt>MS*lVczlr77FuCUb2huVOG-O%agYP5$d)U?kOnz28In>g2jP;`Z+ z&7p+DiOzNC7<|1N8ALZI6+O;_S4(D%9(>W2z6-q1{JLXB9)Gw%RRuE(o(TnD_H!UcA!;h7IGzCcYHaWkUJVJ zzEVnSAfU?Rs&u4VUx>fK<1yT`QE+xLS4J@~qjx<(hU`SUQxDQmu#Oqyyq8<;C?pbB zMjMwQi_DoZ$3;7Gr`LLfD3#|1pn3j{7n(F3SWBBs_;y8(U29ku{^c7QZd??{BFk#X zZni-SVeJB0{)1>_FtN`9aq$wj!HTPk zd=#elI|7+E@xu9XR%i|t3Y4TP2~KXTwBY)~jjdh!C9WV;HZKg~NMBF|f3Vh)qFO8< z)-AmAt;1cTb8xnIT~K>rK5yNqL>xtkbaa^7}*Pu%`xkW)X6d$>4RI zm9v_t<_^eI1ik>=Ix*VNWv~|dV81& zjd9Gp={cm*I*ix`kRXn@Pb|ELP{cun6T`f83^`IjM*Yj*f}9<29{+4J|OHF6-_O zQ{I|5cqC#lFELSKNr46JvUclj;0k^gZW7xX8L&kb^(PP-=ipPUk0F$>2N*yfVuMJV zEm*TPmadY+9!1D1wixcPfel;JxL$!E%T`Dc5_ShhK%4i-b44_d4B6IP;0-8DEihd0 zw#LptKPic63bEIRpxX_HeKZ4ouA2)tK}Gu;9d5P`UDFTM*^Q(2Cu534VtKekXHLp!oqJaE<~ER;Kpgys(lFav`$V0cV22y0bOsl}dhiOm0v z2?AI82b3&)aQMI&e(i%Os&`-|n;j(YZRsEo8P!3Wv$fzjI|X-QDuQb)%Jj8^Kz_foVZt4deCH?;)%g^TQNc?Y#-C zQ3AW8DGET=G{1nfKwCMyJQsf*06R6{GUU02-y9;}y0R^mIH! zkdJJlFlhek*;%8Q`}^^ojRvJi^P(wD4{tLl+NI`9M`d_0=*`iHrB#vx9!a(Vh+vNy zjtCnxC`n?qfo=jnbs&2G#W*wR0?u3(;mim$W(>UT+2qVPM(U2)^ZAorhn_p>ggYI%p)}P!c5f# z`N=&IbPfUzBaLuuDaQFIz_=JYoDq}+nGFOIF=MC?6BkcLRN7#SZ_N@}!(cTKP!H6V zh!GgyER#!2Fl&6%{9Fol1-~+7_Y9irrQQO3IVcAYo6ZDaIC5b5fxRtcz)pW-29x?X zhAAqr(;G0J?Cn*Ny&sFKqN3Sx4n?S?$=)igo9yMMWMkOdoH$fqZ{o9)5S8Ytq4~=J z0Nz*Zj>(Gp_Cs~{2*RRSJ{6_+jnVKewcm@q!SZO>qi^XAl+x^of|nhnOW=u#G)_(9 zsc0TiGv))R!ng;qm>Oe{wbdKY_!HIk$eR(>CWC4%sy1AK&Ylr%KjngQ80`qz5(eTX zIPoi_F`TIp#i>XL*4Le8+r*66-(N3aR0Hacd>Lrc&rC|x8G8)JZe!JYW|2(=z+DZG%0&jJOhU8~cmdY#= zoG~upfaGetb8NCV@>*llM^!jBeet@?osfKi1T7FyF(v~2Kplk$piF~9v)KRzimN|b z7z3k4M4+fxV_ebgm~81_?0{msx_P~fa_;M?hvD|Pn0EMQHLFK0cdk#cTjsHP00t(W z>4{%C-u8gRVAPrqYf!XLaj$5Fu7ckkSZ&SMLNk#MUu$J?H5=0lmqOHVG%$NSrYd!C z=Pw$xanv6^6aMg%wm*EQoSyGKuzlT8=7_3RLOi6{y+ zG=4_(_0-G%gbANmxue$3Yb+4yWsdRV@G7Fi>tOh;4kbP4n2^5L5C^RpI|+a!+LHi{ z(sNmK3^f*!tDI_5ttk5@|Id`b1FzaLgzlw`Yg-HT5HMpX;e}u^`XgjWrf$)prcpFc z5%a)6hb%hgVZqleeLYRCh&dm7VGio2wu ziMW!VmUeT_e$#0`_^zXOBKU>ThcyJh3AeK5$1oEZ-Bv{-zju3-*&=UGb8^6?F`i4o z@|gZ2rwLpo)8F6}9(TRj>t(i!7>5qj${Frn2+9&%blw6T%`PCF2#7}dRhjl_`N zz9?ZN5Vq|#ysSE^riWcdAvIUk0)xP2dY^tK?mh5=nZakmRCQG8d15ZCKEwHfV)a!V zl7i{Y_(N8|h;qiFRKB6=dmAxh`sd7#KJxj7D64(>7P}#IGFesLAuaF^Krq{&py6VR zVQOF-;0u_tyCy+4?Iwt&&#@rSi9pr@Et$<|DB0ec${&UQcLI(s$FwN^3uxU2(--oG z_`gK_H+1D2@ZX~FuW!{-KT-=BR}p_LkjHxSi1-7fUyQPoXg`5;4--4lI?$V5AxNbc z!+0lGim{}x1W*gKWwy42F;HMcG;m-kQ_g~TqmzOjGe8B#(f|K56B}5GQt9RFM&F@Q z;}234oxKJ+GG!-Hpu44y6(9m5!a}k&b^!qHYPA6HpR0)bI(q>?gQA42t^|D$K5TUf zjw$67{AB(sh^c`M1@srf<)!!Tj%~@+fsePbIHu^%p;t6~xm3In=Nw|B3d8*-3yy1;TG3=_LAl1yE&mjx3~Xhse6DH)b={ELbfzTl4d@zpUJ5srET z^2>?5Fe)Job|m7VoUL4%y~3pr02y>&ZLDW5`GH_;|4_^71TzD<>M9q}&BzHCQNfma z=B^(hKufwHLyYA5*m!*~qr`UfCbv<0-3;w@(imbji|%*{Qv<6@T{(k=)0^;zBKbN_ z02wKr`38}kco{RMFF<}mSWsdMkJXQ~KtA%DWsTA5)q#fj5MCj4FS2Fz^nR=dLf0=+ zP74fXf$u4FJ6Vf}iKv#qYNkAkd5EzVDY27b9y2u8BZadEGXrnN<5D=|lLAHv}5V78=p%Umzav%$f?Bm7?gIEu?(A`8l&-Ap4M2>nMl0n@J9k8h;wQhNTyv6DlnX^3zG^{zh35 z8*m@H2s*eHNa9LfBQCDViqE+5u)%Vzr3b9VIJNryN4mH62WtU6W_s3-IN;+CSh%on z_2?pKMO8t8xWq94AK{9Zu2wVXrU~qn2uU{n0Q1cc7(rK*qxUe<*3noBhM`IPZ7;<; zPqmefbm@1E#21Lh$JTFH4`Cvd*%{}$#_xM zL~Q85N-;5}WrE3szeOElrBoW1eS%yR3XPP~=1<~L=-A+1?hfDhoVA-%xPTHCGb8@_QzQJfAjN*5uCt>P0EP3&W%SE=Y3 zm7HuR^_bho#-#oj?Om`M|dQ70JBPcw!mrEqRrgB6SHf) zICKrRDXupl2<9kEhl`((ca!gKzCRUtw^~qHhtg7FEouRy3NnwbhxOo_TOibz#l|y~ z#?VxTx-gW_P#c8Qj;gOw485w#jr`#%b(ewI5m^;AV|lq(TY$Td1x{ndvv?aqz~8z4 zXCgMNrj#s$q(Wd9jlqxjUHVB^NMFr(s-0WuJF{Jp_N<9Z8a*BF459gbKMK&^fKAA+l~cfs~mL@!AzQ2vT*o{~4Ts(1k!W<{ERF1e$JXfBei$)CcCnvKE9@=)S-n2_s5UgQ#Q^ea-Y!}SUCvb zYBt=YYQXeXU~1WMw$#}xext7ifQV#QTvxn7r4DBhS#XHA}g(eqO6WIYwwIj ztnM6%ZUNtlb3A?_`c4ePnME8W>LY2ZGgrZJJeo}+(~ph9kMzhL4o0Nj!+0J`XbpN? zbW#O<^z5uKGVo!6pc(|I*Og%(XoFm~!$zFIS*R4-8g#WaS6_g^cENa;J{EZN18#$W z*Uh=H1oi=lN<(c2LanIBo2ZIb2>Q0^zcsUn?*%f|fXwfqp2AgJZvG^`4ehGG%bi7Q zszb_*0_p>PQZY0fr);ypq;(V!Lx-?Hq6=RZEeEDqRLWr<$Nb3vrl)Tii63Fq5-^AQF72(sVj$vy{|1I#V;@ZROJ-^GhKzFyyAoU#+dn-bihK2@}-!{i!@_} zr5Qv`JZ$WE$*Mj~hfvB$u#-5k7e9^Bwop2q-9!g5q}xrjH9&T}-cokq8!MRtdui)` z*#};!bsl7~N<;hnm`YrF!BVt}RxeI#BZH4e&#fmC2t2HPKcRQI^&E3kZaa5{LfmrB z*S9a&s7s;#*rWyw5^aM?yZ}mxU z1G)U5E*OUm=SG>NpP};>257wOrTWbHH)3J?2!47<@Y9zGewO8kZ)-xB`$CupLYRk& zFk7{{g1;EESU$LyOp8{>gi$I1y^Gax&$SCiV_(Mpw-#`&uL%hbH+HV4B!}xc*Vn+W zYRv+Lujo2!TL_ewJ`%I&A@w}LB-~7fpmhq|Rgp(Kjm^pA(Fyc6S_|0WK|>s~;(hc% zzKle;Ciz9trr4lVt~TLm0d7jiGMRBN(#_lWq6g@LM9<;a2T{c$f;u=Ge1qnZDrkO% z>1eSNg`DfpKtfFJST5d<_i&x!FZkmqHt_S`pjqnyW+A~15^!e;Za*HyljZ$)zHi6F zx&A0)8(=iXjy=mF5|cZIS7Z=;1An^X^Ky}?OW`9}>JI*DECn!pDFb>Ao0m?KXJ}0D z>=a$Uvn3G+WOr!(iQMK1zTrYL+3@+5F&wGpK)e*sCcT}C@8Hk1#q;=cP4N=`G%1dQ ztUK4&26xOCFf%WHh0%`U68!u(-k7sl;0gdRyCQ^HvS&C;sR?ZnMoye|hJkT%C}U+p zt8+0Rn0h~dcyUuTIAaVRLB%-lyB)f32lHYkyW}S(qFc+ zz8uMlg@5ERcodfKu0-97`yniLWc?cmnYT-vOhU*SNMfb?E=adko7sr=WfD2a3pa|J zGjuH#hu-vMsa_FT+?)mk{S)=0M6QDU;|Zp}haYO~zyK2YI4V`0=pl9@XxG3Y@kFKX zqe%{u_hHS8uwqDVz>?!o(%cQn!f|jY0!v%;9gm>W7=5840@NC!_>gC7Uu)=%C^aq6 z4%UO&91l#F8zaBWsi@=sRSjt3b2(^jiNjFDv4Gc`Mz7H*H>!iuEL>owJh0O3^biY} zh2XiO>?KfU))%UpE)ssE^TYs&s}dnj3tZ1e3O2idA73IKoct_si-kEJsgqXg zjRNL7EIJ4wyM3RFWbTB_IFyL?ZNzk|eT#>o<`38XW!a6w@%2?w zxCs1?E8Z%FWp=?{kH)`6=1;2eOOg;Jjo(0KDhphLR&M7P#~_jDwKe=BkIqTE~KWn(#F)i z=9uHsMY;+<(j69!jtGr7)gmseb4HLAS)FuG9~+UW5kzi`MdT}K2T}ojOto*$W2Ji2 zk644Ha5}JMr8xqe%`1gdYcwO%Yx9TA(N&t`s8LH*uLV{CD4OFI7D02|@(T5i-5laU zbD&6gT7@-l4N;XE0j{se)((E$kBx8?v=(21PGQYGUQ=D8kszIZgtkAbJhH;B65B~F z2jA^YkY;gby%S++ra?Vef>PRr>9!-KTC|4VsJZwBaLfGar}FaE5H%DCa09g~`PZ9m5<{)x0ZE z2v*T<4Q@7WmrB&4`NdpF5SrE$noaPxTO+e&C5%3eKG7M)jaCAK)0z22ti?Q!bvola ztcTg{a9wYb!tS!AJ3`V9uQA_L;+azUIRwqY=;-tkw~Q%&XQX`1Nco?z^cU&tw7)FR@Sh|&U;94)1qr}*n+g|_JuPvV7TyDBYUlmk z2+`}g7)d5SCdm1YJya*4Gs^N%CPdNbM53r?`3*=&-lFSm#?`}`B+O5f*{t>N$a(%@ zLtO<&lia~i%`MS+$2;9cCi$+@;H0gF@6%v70;j5C8iIh_8RFR2aRvG36zQnM``wiqpoo0m9 zx19ztwsKU#71DKDxPzCugV>R6Pfcigd-NIgTtQfsS=-^mIc>WDFf9pjsq?$lgQY(orpt6!X-H; zy@_nbVsycB-!tK55(qzv{RJ`ncVlZrLHZ6DkeJdg##1gOFbuMkX387TW!Ub>*{>%! zw=rhLFC(vYqBEa3am{Zqa$#0}eJXl%A`qY;@OvDXg<%B@r%Aq`z9~X$?L^pV-t9PR6wh1*8*$d?bKg;bc(f-D12;gP z5CVpQMLja)TZl2Po33}VcfBMn@Tq!hEYPv^jLig&6sekD5eG{i?@wFmkZ_^XHe+Q& z3zOO$NO}3TeK7Ybay;174J+52i?TNBjAE=cfqUjhh%`P_<-J$)M#A?Q!}V{A4FP`1 zj0xC=$3B=0yp{6W+yxXofwE!R%;}5|a#D;t)QN{4hXV9WUF|AZP5(S# zoWc{E#kQOOLZH)bITT+OuCWrHv&=HNPqGyB8L}z}dgplb?(_}hu?%|-G}3C9tS95% zSBoh(2oIFKulZjGVCfp~ARs4auqcG78PCZi5N&>-qNhVo!yfTTW)U(OPhQHL)ww}r zJ3bhRsQme5Kz0p6#NWf(2?hIbc*h7f(y$w%D@QKf5124TWegMQX70ec~R-Kq=n5F4H zWR8ZcspS7elc9a~(bX9_LR?Stk7veVUUU!w-=PZ|;3~!(AQkLlZ{s>ex^ZI%TP(r~lSPvXvlxOTHzk6=tE*p2r|1N?zVVy~eFT#JO%0KseV^MRY2Krp3OB4yfC3DnhZF3T2IW zWEI__E}(zPO7uU7L0qnEKvUqvF@^Gn{-}gg|6uCxNs1faDGEuU@0p_q4xW88VWJb|2nap7y&`0muA>Cr1QHGT=?xtbMdx(9^ z+S8X{cK-Z)C|mYqFs60}e=fK+FdMQF!x+3-jM)T<(gM4MDbv9e+(+_hgej4`0;`qB zGUX4E4vQ(%{svR3EwrwQs(4Z0yMV)9;s22}qOHA6r2X54n^S#0ie#ZJ&;q(M+=vpe zm{mt)#EUnG?udc>Nngsjh^(3{1m`?@YJbGbpi*7I$DUjn7C!6Dq4Zf~f^UiHH?s)4 z(pI9)(2Cg?UE)REnC}_s3rNTZ98zO8Yy4PO8ihil`B`_gZFeAvLtxCF6YeLXQi%PO z)@#g$d1tKo{FuZ!76aMHdOe*xo}d8(CH9M=&UNRZ45Dn|K}+ZQ2BI2@Ar@o;mj~!L z1|jI!Mh|46r2{cV7j4-Ab%YX+K|5yzf8y?k&5J~zu^$JV;J!Hk52zX5F!c-FNMF}M zjY>lVmLtNszM<5IX{U3YhIOLw^A)15L6q{@VBzH{DXgwsPJtb67r6;( zxYi@~mSaq)P_ta*b;_863bKMfnf$_nb6o)3cCNo1$>!6@f{}?0N4Eg*YAtxBPaz_( zMW^8EC%YwgvuTgl6vD(qsCLZI>+l6cOu0N(Go42?(QlmVW=5;xA#{V^)3L!Vhqu|e zuAk(f0m~9*psZGedGFJq&6KWS^eixQF0x5hanJrMnI9mfPyb5ww4!dhbQ=zqU^8?|oj0Treg(?>j8Tdz`^d6(xrua^z^Br!=eM z`L=kc)hpjqf3*ePLJc2<+Xwpp5xl`T{Tx4$OO-!z07#WKAmJ=40SOo)3)S_cOYsU3 z;^&^ugZhQ3WXPUq7ktk==054Y*rP|iu4uN;vJnl`aSd4t|8qGAA{QmBnwQYtx49){9K%TMAqXxcSb0;KT_K77R0Dc!M0K*Rdrrn>XMM(!lpJThk1 zs1;7K*fKzGvS0cjjpUmVNp`^A2Uq9g3qmKgCHF%)026wt;8rZcETPn%CG0oa;A&D3 zT^K?&D1lBorp&wrB{21*mQRKLF?xV@t78WKfi&m(PH4mMbf*GM^L00!SidHfC1)N%rQ!S0$a>I4E@H?7o2w- z0Q3s}8E3`&ao=E-k^3Uoix;Tke6?fjeW@Qv`|?i6?$VT0PSHCf8<|@Xt0t^!l#z58 z!zn#jO+}@(4SCgF1=KSi6JBtiTnN2#CYk~!jb4=+#}%x~w(!5p9Mm}6F;bOmr4gww z-%s|l1z$r3s4Yxp2#`av%&d6l%K_w}#Xu=i3whWs6}j~EW=Q^KV2DPG+%Nk-yYF-_ zcHUC{pAr73>w9D5pLUSUd0%9k^FH1e*@%%j@9Rl;3pL!g6S`k_=t| zXe>j{xbo!tfI)fk{qkHQPu?3@p3Kbz<;jo8^HF&&m**4md`h1GlxLAVpOfbc^5k-T zdGZQ*zA8`d)+$eaQ=Tj3$sJ1N$?wQ>l{{C=bB#RL%CkhCrSjY;&&~4OB2VsoDo_4U zo*&EeQ+aNe=MH&(DbJnq+$GO%JP*qAkUS5|lRK}WqCC@tYtSirY^1MWz4dmHKo{i{+dj~Dxy>2s&JdiFab^lbLl|no&@6_oVCVsc>M`^jL)92s#n3tQz}!z5 zI>FEn3>ge@fHn6rbP4;*mkf1c=tGA3F;vPBH;b987+S>8>kRQ4Li0I>-e+hzL!UFW zgdw`rtG?vXf8M+ev&z!+fFNSg$;;hr8jhZ`)p_>@Ghane3^emXyGqjc=PTF&K zGemb&ZUP==5<|%hHDahILv*K;>B z#LrLU9$<*`rQEX&-NVr3)e*Xzq0S7=V#vi1zZH?2%g|Vc{0t3a=uw6SF!U-zy&2lf zP&bD5Fw~Br-x%WXnOhe+UoK6}ZO#zg$hp@s#0AA%4?{G$bF&#b&d{9<9cJiZhQ4L! zZH9I*^a(>{3>{{ugrWGF2))D56%4(~P#1=Z7#hORqYO=B=zfMCWN0x%?=Uo%p&blO zXUJe^GDFpBA#@8vtr=p+&K%WcXK0x(9J&POii(DGz{r*dg-C#D>R!JIpQp>G))#n29fSmMHe`;Zd*=SG%6 z_~Y*|{Ov<3|05{>+(>mxihAFNe^!!8AH-$R=)ZB}qT$#Ono#~#{#CKZ7h1noy{E1B z)7Ja(8&rB+Z!6#WiuvvGc7D5jT-?;`x!JSgrcaobtxDwNP4^DV%bPkoB`14=XUfDB zl|d!qiKq^dJRMY?4w5Hj#=N+3~WLwX65<3Q>JIf)r#vF*RfOQE?rZ*UDq9}d2ums&OUuJGW$)KIB9ZrP6VAe72DtC z9x%|8HE8gV8*dsqZ1~M1Mvl5g<@`tPl-q8fI&FI1jG41$dwqAznLF>!XlV$`puvMi zWepxabX*_L;JyRnoJk&XB*~jQ!JCwmH+5>>oY_fJrcavco1C3A+dILVJuQ2>cXmpx zT1ogfEH^u8@Qm!~!{*J%P69K$zFGL4G8I{8WKWusGiA~Q@07ghs^Dw|bh0ly$(tv| zbEnMq=FLK;sY$c4C(O>9KD!+PQ&HxQ?4&8vX5`KC&Q6-0o9CN4IcZ`xl4j>ky(4=v z@ByePvjs-ptjXE4dMI={r6jp?kc8^xa96~VeT0dW`S=Nvr66( z*-3fRr_M{7?VCY*lR71}zGKP+J7dO_S#6RgOrM<8IYn~EjUDZ5f6IjScaH1WJ}u?e z_G8+%i0kWe-ZU=5-QPWIoC>=#N5;N-GKUSzylI?jb;&%)nUy)N@8Chh+=DR9bPpb6 zB_c~SedsXfO*X_qnIk;zL75i(p`)_;4ECrpl7EEDJuGwR5NBWJaA(Bz9h{YwIY|0_ z=3EGZ7j4$6O{=5{IbMjC$cNqIqUo($p^ec?9jFvPIHc%}+|6-Ln-$F9}FYn=&1u49@0FpEoVfH#=$K)VxWzSIFPIQr_9#SyQI} zBd(v@lS%%?_45pN4vXujgdS=kbJnc9SuyXPJSF^5Tp8*I85xx4?U(19K3SFM?-@13 z)z{-3I+W@C{~vq*0v|bJHv5fwCngyMxkYkr?I=W}*v zXOpnO^#A(*UcX&E%)ZZgp68r-=FFKhvnS73cEjt~Q0J|6l;GUJ$>Q*=b5y!(u>&|$ zO3T-m*J2AxU<@MeNselFO}VGk;i++y!5!|Z-t1L*YQ-5<>8V;TPxdOu%;}DjGFOcY zN2|uGp%3NFo1edEY2FfTk#Q!<)-IAmK`HiI?S>}v;2dM<5PK2)gqCGFo#j>KV%$@o z@N!h&S9z6tb07K}TorDoF&wiBi+!Q3sy4Qka&L*N${FYtPT4EuZW;ducOZbWy$UVO z(_}t6moX4J$wo6|k)aT5lFaO}8HSLl+;c5F71Wg9OyzY|wdIvo0izs49!B?4j~k~7 zI)WVL9mVDH*cO|{`AH7<26QqpMs9GpypzklS=!R&^X5C%Y2cK&YSr42~9> z%+!{xTsn7tAvZ=RH#K^hrz-Rin99W0uyPy$`gnQ%3UtoG`A*XrRJ5XS(Xs`a9HF!# zjM0m5d<@@9!??CPHn^&M7|u)TYP`mUM((!P5LgN09I*mt!-bBqHQIUFm1)UWYv*f@ zBrQ$MyX0rmMHfz;fU1IT75^O!~$Lz;8FyS5zHUelQ&MM^3$Z@@|A zti_q@UhBdjR#NHlx{ZIucva%5tlLn9&4y|WJsNh}DRxYJsdm+tX{D}Omxha-F=o1} zN<5`P%Ux5W@p>)>-avEAnTGnsl=5Dp2|=f)#%bgWFifg1PNUqj_8M)S$akt!f>`UR zz-T3lYB8HoH3sHdYCeXRVVDhk!pZ}7;jxlUrJ8YFFnkDK$~gs`$gZxoxXjWb2Pkjd zTIqK&L&Jzw?y4-mPB^CA>sss8uJM#t$*H5)sa2Na6v4kZ4)R}2lWJ=5U0nb$D|F!q zIW^2bO3Lu>W^Z*RRFLnkb*XwVbA$op)p(qkD%6y_y-+dwx^ckZI$TLL4?2$K@oLqY z;pb`(zIf0Ir?a}oEoK=|s?loP_}^8Ef7YWvYu~xbd%lKrk>+(*u7j-CUF$RsgHRN6 zHE7938I9M(Os~8I%`5Yi0zB1DS1q>26;N!dHFyXK*Bhn6|Eu7zJqH9Ry7yD;#0$ni{-ju*|x6b|+$8S@CS4-?czpauDi^2ZMg>%c|q!f$vjU~oS(HLevT5Q7tM#Jz4;O-WhcYU4G;Fd#Xx zXYd@xO#CY*zL*FbeaN_3nT&&i?j~(GFejAvXvT~g%@KE?=sD=&;!D5^217@6ji80@4ZsswxF#MQTay>qS0Yg{^nQR7~=hvylb4mgAnM}c9} zf$5}I+^ml+%^Hhah;?fB$BoUJnw{+(hx;c7>kXCF0y9Z@fpfBv)1BGQnOYHM8}L}Z ztVE3cj%{X9 zt-|fwgeMQYJ43&a*G8`iQkl#m|Wr^4+{7#P=M)+$Q82~RfBt-tFE$ESiv(Z<131s&WcST=&C|z zH#)wU@ZfrEJTH^?y~4BZS}{z!=wb)^iPIT;oOUW%b*RUAG4vZJTRxnyo<*Ax1jD+k|cmrzds__(zZI#0ddauV3>~|QugKm)51#!}2 zUM_|+^aaUs(D6_5bia5G`uaMxu37G>+6BwxLYO2r;49{wTnX`B_vaS+)c%k8`U_J&g7Y=L<&NrMo z#&aR#Q3?*X%Q0RYMsd!T)K0)SD<}J6%o77lzy@3{tl+E@_rS)uYCI}-j2pXhoEpAx z5Hag0)f}73aL;2L648ZRYFK3-ShjM>65MopaYEo=V-T;abr|Q& z^J1V|k4}pVWF00Fym7XUJ%+oqu}XLYTu?5~4)$s>`RZBaRC{YoeY8HM#Pp_biNFm& zt$H-TcHwNTs}gex$N0dm!F%F%0zGPjcv6YyD7aq2qlSv%!+=)bwFd4W`W7>0XPOxJ zMV}g5sGf#nwk)29i&Fw^K_f6XsC8B0kvBT*TucDwZ!U3Hi(@>=7~{qkYBjEMulquW zTNQ+z6Xw$(#02^ijiGmA4B}N!o?DJ}HJ%NjRieFONXHFYEe^eLt;g9SW=uvyOWm6% zi>tRWi^BbBjTR7+=ZZSB&>(LK?lo&&Yw-x82cfzuFV1|oQQT)QFs7mM9_-X|y#G42 zp!GRnFB+C9ao{YCSiH|}Zn551f47JRIzFdkq0SeF3KhHX6No0~ZY$;ND1WJZDquYx zVtOW~JGB^9*Vf_Tx)>yT>)n>7m~JaH*bz3yPq@%zOUwy^mlF9LA~OH=bO+K~t9ri~ z!RUqQnD@f5IQ{$h39v-`F{XAl5`G!iX2@GEV;h6-Z>$#a)HIt7{|`=ywYh9|Tc#Fc z%f_0vB`6SS`x+rBzuU1*#e>5~jU3J9z_#mF&7OU`ra69~#b(@%A9?TBV)oy!*}Cr6 zwBrBKV)y)1v+e(>W-s`;W-I==7PAN2E^K!`q}duC(qfu-YqpFgaFZ67{V>WO*5V2t z(PACl|u-UV3Mw7SOwCX!-_AdPJ-*6B3M>cIwLX5pS zB__5tMYb8ui++0XK=#$rM;CHCkK1M3uI6?vx0T#p%WXZk-{$t7v_Bw8Fm%05Dw{LO#F1H=re#)&@EcYXs+o9Z^%k6k> zr*V5Rx0iBT!0j4tOS!G$b~Crvb9*bdKjgN7+lRS*irW{s-OKHtx%~&XA8^~n?MZH9 zU2=cYxgEjndE8Fob|$yE+;QRLVQ%Y=8^3_gWK!_q2&(dU&3wm-$Tm_ zm|xHBp0?2P2IedOG@J-6-_LU89|t|I+E=_$womydBSx|+uV=aPPexp5c>~K|;CAQ2 z(DMDvSM4tr3$D%n5$hlEQTB7i%1C^!H~z(XAC}9#Vy0=cwN}bEoASih=D*2|Y)gI^ zz8RL&V}>I_IZgc0vgwoYwuGJkFlFMaSjX1Wr**sBABXrOM0~2bwaT{sD>NrJ6#sul z_twdF*0;(kdpl0OHRwx@E6Qt*-UK7e{~6n}vsEgza%)vjDv|9zmE2>r=V+4_in+Dg z8%%qrk~@oX&9t+>7kkgL-t2c}P1W35>m5gXr;__$+Ux4Yje`0rH8)xR(Enz;>1$Zy#^ zZn+;=OHPmf`W?By4fEyJetKr2T2T)~JrMOk)B{luL_HAoK-2?K4@5l>^+41EQ4d5t z5cNRR15pn|JrMOk)B{luL_HAoK-2?K4@5l>^+41EQ4d5t5cNRR15pn|JrMOk)B{lu zL_HAoK-2?K4@5l>^+41EQ4d5t5cNRR15pqBf64=cGk3)lZ=7G9Q8>Rkv3f*dUQwU_ zRgb97sCMAL?813PbF1rZg_l+@EShWnuP{IOpUN*>SV*s4lItw+iD)GZptC~64!vw+ z;!Y#qSL@EJsd4$7Ms^_2YvTM%RdleR%shkzGKnCTiZf4zwUA+u4O1fD92+^9iHOXb zErQDs!NQWY91+*nA;7vNyHLh<>p6FotENf>It$bl8sj#Y?eijBti^`dLrd1>BC?bz z?^1->Gw=HnM4dLdVhKX8nNWrTnde5Bmatq?29M1GcNM}hl`L@A3UA6?C_*68pyOAF zs99!4gH5=ys@#Y#rWC}X4;*6mhU!|MlQBx+2Nbg2WrzW^%u|a)RcS=8N3bSY?z|K+ z&fG<{HFb#R#Vo`CvE;0%sk7v`yd~x3PQ-gc&{G5ma%(#WqdwG)U_pqkTj5+^=c*Bv zl=>=5kzKdexwc$H>DG2`+!Z6cEZXgLUW(W`s2&G2ud1{NF>$n=+QtSc!8j|$;rG(L`;rm7C7qU)K*la3fO?yMK z5IzZF`%QT`WWt8Xek(jXXu8#0$bCC3^U&d(`IQLGD2#Lk^KeGVs6|Ufq+GYr{1d_A zON|izLZ{wtcv09{AOh<3q_{mOv&^&9jet#t!*-gp@k#&$_6;n;8} zaae-c@PO=EB7b*CesK5q1oOp7JAbnfewLYPKbcXr=x*kVQ7q3J^xmG3{2~#Z%4zJ05I7@XZ>}9Dbq8@bi zhvf$M{H@S3F)*!iyDAFZ>x>boHKbS_)WadU3-X=w+?AqnUDkYY3Rj4d6V{TIRe`el zc;mRpHi;uCFOfJEdMXH>+&itsYG~foLxC~eHiQ%`ba~5+qZ5+5$SW>-B7aXvKCYr7 z^VyKh!t#=`d_-VHm{(EQ98!q0PwmOxo(h6{vfo;)_T;V50$xd4Lvk-S-qj-F&R9XSXvSuYy63GY)8%DywxCAbz?yG|UkLg*xl%6O2Q$qD(~X4Gd61dOJ(R z*gRKU^A{qJvnbff0%IB@Ml)U~cUkfS15$&zfP>d=b6x@a&K`57nkhWXOfgGZ=TUxp&Bm6;b7tR@WNo9+Syy7Y43K0$`}`=s^G*-w5&mjIOmIC z&xPv65&7tCqI5S)al9{=A(Tb#9_B7_BUEFU&avQRma_LDF~T%iwUASN8Yju8rP2kF*nyXwzAON|5sLFR#sBsF2%kInZrs( z^uQ$^Peq+^Hgz#u9kE5;Ri?Qzjj}o2KR=N z4MwHA1bS<05bj&FUwv#&E!nQ^!CPNq3VhBAGq%fKA76iFeMXnP^^KT%`_8!i zwyyMg`<^ryPj61|np{6fh@iNx-rgKrT_3l9NNbYZu@$X|&8Nj`KmAzKGO)dWuT6`! z#cF%^%k2rYRlFfj#hpsUYu^N`xKm#vH~&uBn@M)OB3ZouUC0-U7v$knLEird$=@Rv zye|1ca_&CKza}^Dm;6V?j8k-otTE2emt+-p=$uqpzltX`o2=pr6_8b2pi;8-j;wDR zS;gtOSLwIP@~4zO`A=jO&*nq2ihmQECflRp*o+~ocs6s%DlW~{WEIC|Gg-x>`5{@w zlX;4);=$}At9UL)$ttc(S~`ypg#EDxTR}WBj=Jwkmr&okqgL6$kpU)$$Q9mkekWBCKtP9d;duGlH15z$tTFSlhe+W?QI}W zCO4BWCBH$wiu?|FBe{$GeX?zxY|lO9IPz|C2Kf)7Y+p5b5_u>2a&j~I z+vGO#?c|ThKPGpPe?`{T%l7`6>>wW@Pb1q#$oAxtCz5xPSCaRVuOa`1yp`NazMuRt z`6+TnnQYGiayI$jGV&hs7V=-n-zWc_+(7=2{44Sa^6TV`a@oH3 z$PV%e@&Z`$cancaZX~}zevW95-6F{~_|3mBBway{$5BP zNzNr_kqgLqJ2hWr`%cVvxmf)9}6$Op+O%DpFD+}L%x7K zpRD2~Uq`NI`5tlu`CW1|dBhl5e=B)8Sz~S>yqT=x z5kE^-@rOSqt9ZjR#!{d0g*TBk#tVL#tl|g9e;xA4n$~b*j3z$A$r(3E&LZcM*OC{K ze?%@L?q>)=$2Stl|?_kX4-Go5(6&@dM6WD@jJ9#^KC;89hUF6K^Qoey)LEcS%j=YB)J44DpOD-ZelYdO!OYR`= zC(pb<>c2(4iQG!wM?OqGcczr@BA1a*ke?xIKa|JcHcQGUk_*Tg?SWHKSeGee@R|VUV5R_FDBnZE+cU%N*he?K{q+)B$Vdi=20<)Ndf~AnzvsoxF$qwFOfCS+bYhO#Ur-FFAFgl;2OjoctE~XXI9LC;2e> zl0{O#i@cqDg8U{~+ZBV^i>76MQ_3fjtH~MU-;qaSqkNp8N=TJ2}2UmhU8A zMczezhTK3-yG+XOCYO=-kY6A_OCDJ$<(tVK@?P>E$ot8TA}RkCc?-Ff{08|jdD03g z-$lNje1iN>vi2i+{HLvy@`>bI$r?wI=PyK$_PJ4>&t9x$W{_V1X zLSNWZ^2(n2{c#QS#r`T50WO^wsaPozz#X^tE_20w2Mm{pNB*|8GXIX1@aM73E~5pDT-l`lfQB zuYUhMhx&?@zQdw#E*JXh_u?7USFH5A?9zZ>(SCEe&{w}N7g1la(ytd^@DUrKZ!Q=5 z>i6g>>MIuV;`kLi6z@sjpb+Tib6g7y9+B zuz}Ar)K{$ZGh}g~esj6d-`Oe!_N)CTD}7vsjE`W^ekCth=(n~S#o9+||H-1MK_Ixt8{u%Y}Y5_3xy?q+?&3+T1T*9_=wFile}P|uhy${P+zeqH?H5}3qE2a z^v&f$zxl9HtfgNikH2CeZ;apK3qE2a^v&f$U#*9kN`1vbUg$R2m7yfIuT)&mP(pT$+CQ@IqC>Qz}mg}#%T-2}D7v)o5vC{7n zU+@td(SCEe&{yk`Hmmx-FvJacQNLzszmgaB4E=5?-=y@(qTJ9=k>!F#{q?4DLtm|T zQu^e8zQzCbrgB4{>!XH#OZvZ_tn{t>Z!Q=5YCY8g>MK_It-C|pZ!Q=5YW>x9)K{$Z z>%|v*#AcaEUa-(t>$PsCzG6`>{I}C`{LSS;U#;(YfclD+{(jgHAHkx2bGgu0>%o3a zeZ@+@I>As6=$p%hzFI%FpZbcGzIFf2_n&y!9riX-_t>T#iCsJKi9hdT>qx@)%!nJQ(tj!`sQ*`zgjQnr@msP-*qM$ zfsbI(esj6dSL^EzP+zgqueY?{TrTw0db~4=rT-Kwee3ySE*JW0{oZBNSFH4{zBD)=&SXO%c-we>DOE8 zHMK_I3oO?k zRi3j})4mSdYJFxtS*_1pMpo-H*OJxx%+MON!G^T}#`W(irX&-^x7tUWUU`piT;H5A8Bt(+(B0BGaJZiedg0-wLbIDWVJr?BXS1ULnf`Gf5_v>YJKJcay84ZA@3yL zOx{C&f~?kOHj~x*%)gP<`pgcpTAvxSUbaWA&peB))@Nps)%whNoXl>wLUYOtk!4dk=6RltH^47=6A_z zedcXswLbHwWVJr?DY9Ch`7&9p&wQJ#)@N$vvb}13rh}~3XHF)o^_drv)%wf@WVJqX z1zD}nbdlBi%qp^4pSgvs)@R;KR_inGBCGY84P>=G^HH)|pZP3VtoY$gtM!?2*YNz{`ov7KTAw+aT+Q+oWVJrCgsj$Q){@ow%p1vSedgU{ zwLbG9vRa?{ELpA3{5@H%&wP`t)@Oc5R_ilAC9CzBDHU@6)cVY?k=6RlnPjy-a|v0k z&-@lyttM!>Tkk$Ik`^aj2<{q+IpZPLbtc z5m~LzTtZgsGmFV;edZ>zTAz6vS*_2!pRCqrK1^2YGoK@?^_j1d)%wgg$!dLOJ6WyI z>?W)AnQ0s3{;KtvXOq?X%q+56pP5Hi>ob>=)%wg*vRa?HiLBOV-b_~OGw&v=^_h)i zwLbGvvRa?{99gZ;e1)vmXa0q()@Qy?R_imn$Tx40*Y7XLYJFyMmGp;NpLrHpt({25uT&wQG!)@Qyoc>+YJKK6$ZCD&Wn{HJvzV;bXL`tL zedZRjTA#UxT+jA=KyFa$F)@)B^POh$GIA^VCbC+e`D?OTpZRaHTAw*-qqL{iXL`tL zedc3iwLbGGS*_1JzlQo;k9iGwKlvAAwLbGCS*_2!*bDt++`n*r=2Eg+pIJ&)>oa$e z7jix2K5`j3zE;}XPR=3kCRda9l6R92lmAIh{GL2thSy1Z3w}YHWZX{=rUm%Yl|C#I{kNmc*Z#>ye&L;nYJez!yoJ-FCj?`aB_LB?9 zZ<1G&&-<>FFD6%#%gE1@tI2U&rTk{{3UWR9C*hUuNd3d)8^~ScKax+7&%RO0Yh1s# zj+{t-nw&xICXXO5yGiOh$h*kn$%n|<iel_`S@@DdTdt!|7^iy&odH(HE zKZAS+c?9`iWCwZt9a4Tgc@sIC+(MpB&e$pCbIEJS3&~C70`hV4YVusa)GsFAN-iV6 zO|B-7{ehIM=T=L?3rTjv26S;sKbDu04V>l3U3$8>ReVvY*^VK14o2p8G#iUai->hpg6X9wV#un&&(y<<)x4Wn{Hp zb1hk|*Swaj)@y#Btk!EjLRRZFUni^enn%dJt=ANz)*xGO{bh#W6iwUC`QRKdioe9h z_!Qz_GnZO;tA#NfhREaagz#e)e$m2zw{Vw*zp!u;8fR|bNDEJ~@WmEhWZ}y#TxH>J zTlhy7ZnE%878XAX;{Sku-?Q*17PjMnndL`Xc#?%LvG8&Wms)tUg>Sd;gBJdkg=x!b$ef{W-_NQ!PBl!b>b%Y~fl9-)iBsneB8ou z38DKl)WVZ3JlDcYEqsNA*IC$S;T;yf-@=bs_<0MzYT-96{Jw=hvv6Eu=>DH!;jdZv z8x}6G@LCIBYvJt{zSqKgEc|;5AGC0{g$E^t?$6gPe1V0RSa`jKueb1zE&RBJ->~o@ z3&$mgw(mR(PqXl13tw&FYb?CQ!aFQ{pM{^0j7zHgykz0OS@>TTK4jrl7!TJVU5RuR z($z@cLUJM%Be{^)B9$V!k;Hhu9;pne9O)XQ3ZzP;4M;wu>yWk}eH-b!NL!J_IKK_) zdZZhWZbZ5X>3c{wBi(}ZeWV>ow<6t+B(4QJk$!-57t-BGKSa6*X&2IuknTmg59xlS zA0zz)=>en$q(-FwK@!)HpCbJX>E}qhk(!VmMtTJ4QKVlWJ%;o+(jFvno%towlSoe? zJ&p7$q-T+Sjr1JS^GLrz`YqB6NG~F_ApI}W%SgXN`aRMsNPCf9MfwBMYe=sn{SoO; zNc)lAKoZxkzaae;>2FAHBE5z5ccizG{(M0BW*;gLGmKiBGn;Xi?j)8GtzgEwjN#LO3j>kz0~{72pCy6V z_+;z|BWedTf_ovF$1wP!IQ)$o%r(DHLuCcuroo)xyEK>)`X&u#hP+23G*7)ngSnya z&`_DCH)t?RI37FVsS!s@?1Sm;88Sz{y&xFX-!Ms2mePo#f z=o77x^F_8PWPT_H&uk?V5+pw;Y(&QoBE#Z`WXPEJAz3OAz9};#Xtmf=R*Y_K1e6cU z37#)ONhAJxh$M21vzIbPwC$h(-kl6OylfQoz@(-TSV)ItTFfm$485sy8A0iQmA8*R-;q6PJ)Z9Nq!pa+krg-v#m9s+v$(sw< zuOJ!-9WRPQUhrgOm|pK>u<7Ma28X@cDdfFQM(FvF9Qmdv6^1?#e?IKRPn_pg`!?XU zE+sW?yzWK|$wQR+62_WGegQ($%Zsw;i$XG(GtX07>sBx9VM)RKf(vG5JL{@T#d~zt zVv6ilN(H{@cukk9q|)W}7Sykc#iF`Cij8)PcQEx_XKBwx zLTi1cXDwcV)`OxbEvfW)>+oWeaI;3Kcx^||MWya_uDZ(Fp6nW)>%CYQuGn-6{XPYR z1y@y-2QQQ=_uzFe;Vl$R=vzYAz#Ab-JT;!W+VZNvZU#q3dCAAPzs$oM0@<_WeONDd zSYe$%c)52jTb@_Aps0t|nq-#uU3_U?(Te=MB}<%(=U=gEIo_w}TsnWn!sVE&_f>J2 zmJk=WkyP1Y2t(gjs`^Iw1VXO`0`RQgv-4qoVGbT-2ak+yB> zRHLRq>()i!?d*U`0S-{1t2{U`n!Bc)W2z2`Ifzr;3gF_NuZ{+;D7^pR9fwp{Am^w; zOI#I9(qgLN4Zb#w2Nh=2)mh!b;ayABzQB$}(v7BjOI%e>4~F{w`S1cmPrNU)vVV%R z3`JL!rwSM3II!fCif>?FQUoi=^O1v6*O&QaaboR>E@ zf8P8{U298li42y@+yx64eRJ`WrOTEVTvk}LV&&zlR$s9uOmf-sWmha+zOu+Ucggbn z#U>ND!4M;QZ5dwwy3T`_6mIfjY!^MC*YjOf}5kT#a|jxl5g{b>jN7t{g9@ zRns(i!~zm)-RnFx?mk8OQeR)`t1iQ&3-k2eYVe9T9ikZ<%B#dYUyWbE<_FpmBIh-p z^#r9ZU9@Dr@U|&u$?`nYPG5@q6U_XUl&=lUZsfiO3zqPrXR-m;;CacV;#9Y&Em(3z z!NU9{c}2zyN19q-*Rah7MNyA(U5+8nGf^wjMwAALqle)=jl9yWzm8Mto9;j>rm;P}<6h!{_LEespH zf|ACWZo#mfk;8$Ub%o1@RxM@KG{`F5ldLfmPP0mewb^u0uHXP=$cULjkIKeWz*=IA zX{8=aUPPCXgPR=Nf|5&@&ztWIKQD~zWy=dgI#lSX6E^yUiLYEb*F4xQGuU({gk3Cx z%?c~RaSHY4^86L%&R#g*+0)5Zw4!j)vIRlA*1^&83yA8nD?A>&7q80atWhsLRM&*S zP4$r?sq7<+=tBCa~}o-ZhZ<6E++)WqWYW*qupUipScZn-7L~ zZ)Q+ygLrYf88>^YE6tT`P|qSwLVS`W`{{-nkJDX+8H;>`DKm}hMQDFU2f)NEXvI@) zKFA)^ZdM0{LVH^^Uj7?6#ML1x!3U+X0jA?2pNKIVFV_v4sBy2yP#9!W8@y(hd2!=o zlETxb&_3_QaB35Xl z#QcOx9J7d&rdgjhMWi*ud}WSEBjg@B;?~U$oQD1K#MI#9qll}TIxR5Y3f!(nv}aRi z7>c2fW+Ky^+1E6%ZxdlR@%=mcVe0+t2VwgC=n-MM{p=fI`m=*~5D^}_FcVX=zrvyD z;TeeeiIM1n_${oi(rtQ_5y)_QD?P#A4~&;iJH-qLH{a#K1u0p^JDW`z&fq|?0cKA< zI)psHHkuTXTG&Io$Z89DSQnW}*h9L=)WV-hN2X_aDjlIx507sn)a>a2ZiK3RKEgeP zjqsjs9Vq&1puasLtOfn)8)3@*?ImFbdU{;iUl;WK!1PqsdKfNnavJl#!0;9Pq1jkW zVxBbwi||{#mov@w1?zQ-Faf^no>&6a=Pg7UO~2Ir+nW@JIYC zdFLR0dv%Imu)xmTH?Z3SL(!+r!FuR?@OMhv!({-OMOY3t!GUQ+|Bl-qACd9 zT=yj%Qo*#q?R8%&feNPe*FRa)rbnU@s9;7U(xH10cv=wA9t0jC^d%iyLEuS4Un+q; z=>I{U7C6Xj>&h$fTef(XA9lYGN#)bC`|ZBzfex@i)avGP12#dKQw{6kF|8^Jz135> zJwCHih331#>IfzRYW(l(ygf}b<|D3lI+7*@CV*eDO+DH<-9`oPJ-%YAdNy>r&Emby zS8P)cRtCO7SyQuv=WzsG>J*KFxxhIdNw4a`oEl%I1|QU(rX{ntvZe+f^`54=V8enJ zhk@`|@Uin(ZdmZ5G9V2LUT{v&T+m~|i_z&>vK-3bh3fRo1sgW7o!>Nz`HBrQ&2Uc7 zQmDsFv!By57x37$f$jXJS<_c-*uZxFX#>{zrwwf9pEh8ff7-xy{^0EHtBzx)+1=@N ziqOs0<*n z?U@n0wK=^`5!$dBf!m(b+|NKCn=!DRf5w1y{uu+?`DYAR=btgKoqxuFb^aLx+xce< zSm(cBU_1W>1J?O37}(B#!GLxC3kJ6HUoc>u|AK+-{1*&Z=f7ZJJO2d(*7;`+Z0Daj zV4Z*Fz;^zb1J?Ox4s7S2IbfZC=D>FTnFH4OXAW%VpE+Qif7ZZu{#gUo`DYDm=btrT zoqyKAcK%rd*7;`*Z0DafV4Z)~z;^yw1J?Ox4{Yb3Jz$-G_P}=j*#p-3XAf-WpFLom zfA+w3{@DZ8`DYJo=MVlx&{w^$%o*6upEF>cKWAV&e@_28e~$~#zUog(r!;DQc+js0 zB&W2jo+C`_=MPS&G;D5i*0g^9{&Y&~foAvf=crQ}4sCWnf1Ns|^E4WFsa8Muj%TD&X&k5nteQgW&?d9!XKCV-`K2a5&qB=ndxAI zBkRPGSv7kX4UVh_M`k+M;K;gfWL7N={x9@hxFND>%V{+@vMEetrh^`iY&sK}Rf~rs zo7YEXI?&(M+_fEP9fB5Qega3OcU4%b~^|!(Qy^}7&AIicS zY+k2-x|7X_jhcJ0xXy{iuK7#wcV7sC7KrQAODj$(Yc(#`)8lUl-A--mq22^eX(4b0>dnFoZOTe7mhDcdsjI4T*Gxein~Evo zj{s}M9|@Yi;co#AGX8jQiu~iiDVp(zc6fz#ghs@o#nLJG;5Pu0D5?r?r(ZJuA$+e%1NG6QexN3Y;j3A?8 zr@d1OjGD97iLj%F8!ng2nY~k{XXQ-cUocLQ?Grh2v1V4_j{vQUOSOThg#MUj7ycJ&k!V@|KCK@QLe*?18Z~WdPk(e5k@Nffle<1G zgiTPx{_wJY>S2Fw*FW`;Kep?iYItYwYt2~Leg~dsss0#^n&xCo$*Gb231Bp8ntD8m zSY;yWS~O}}G-_HjYMKhh8H{-lJWWEQxmm(zSqj7A9R$r7LC!3QCn%vI;0z&=8xr|V z<(lJzsCZ^7mWS1HPqM~eLkAviC<|e2jz&!ji@q6+nihD%Ug0#y=!r&6GsiD0iAGIB z2-;}Wv}n|{3TJijiWH5SW<v=TDnsw2Hc}b3WnGKfhs;g9ADuESdfrm$Z zNrzStSS!<)N}z(^f-vJvcRdHh3#}lyy0QcNuvFv48$!f|@$)QCK_pMRMm!VFT9rqe0f>D{4aLUOk*kfj%~UU^{<= ze{0fv&j>bbU^{<=e^U}k!v=QbkMM6tB5Bybj{MUHY~+syS?ljv84a@5Z;uUZ=Z^+i zQ%f^@A9zA9;?W>${r1>^O?#q2*7`eKM1!pL+hYSe?TH3i>+f(84YJm6j}6!jZ#2kS ze}{``khOk$Y+!GAqe0gCJ6uGAto7Gp(I9K$H^Lv6BC{IuU?Uo2O^$KXBAcF^ zmWLyor$=Tw*d-#nVU5hHrAtKi6Yez)umm)T5KJA2MBLq`4$XZw&w;5XW z6ZJsU15pn|JrMOk)B{luL_HAoK-2?K4@5l>^+41EQ4d5t5cNRR15pn|JrMOk)B{lu zL_HAoK-2?K4@5l>^+41EQ4d5t5cNRR15pn|JrMOk)B{luL_HAoK-2?K4@5l>^+41E zQ4d5t5cNRR15pn|JrMOk)B{luL_P4|_Q1ZAN4`weG@Ga=5h)$%tvF4)No3$N5@~#l zhChp4F@N<6BP;ZuTojr=WSG!Iif5VAS?k_h8x*wKd+$71cIzibQ#8RLmSeU0ptfj_ zx3+GrH;`quS3N>%FA@yK9hRwfCEIq;@Io2{zl)!rE8j zsqzMQ*lN!)MrxlB4#!7uto+*JzfNa~c$s0&F!<=6USj8lGC|l(Xz$! z=Pi=GL(`hsie?mw5BZsUBnmrbTjyz7eKzIFuq}i9Uek_bzZ9btr)b*FKgDPTC>KQ| zgxtOu?KU*9Al0son5StFG0L&gK7)`*LRQB==Hn#F&7awcb}i1_AQq0oR@C#s3*VX3 znVVhq^kRE`>d^oEavJg+NKys0+R}{ghOcZh?B}CQ^n3LY?wpMzY>D=0+Bl3jHf>6s zw`NLZ`C5^ReBN63hOD_+r9O}$qz^*M|pE3%f|3p0y z^+41EQ4d5t5cNRR15pn|JrMOk)B{luL_HAoK-2?K4@5l>^+41EQ4d5t5cNRR15pn| zJrMOk)C2!7@<4Iikc`m|`(NMrjyCj!^EXYOuCg_Kyga7qKU?fg|9MICe{9zt&igKY z_D#&yAODVa*La(@KWW%peNLSAM6OL+F~_F07h@}IBp%LKt=V$*7GFlT;Oim(n5GTY zhQ;WkW3?xWhe^2ubBC;cQq!I)i^=#(oJ~?;+m-nNP*O z)MQl4I)**`uKmo1FGAU8$lpub_`RIA&wRK9wucWoG0V0w*seE(tz>CyTeaLz(GFp2 zd>^(7VC$LG6SFcsL0c~fTS?MZV^yfFVSU*825hZLJ~7L+LFo*A_z__%QF}@pFR_1R zZ5gXaYl-a*I5xHo$`_)YLm&R~+uB{iuiLrL+p*918GXe{+liSM<2Ve{>I=fQaO>;p$pha*m#@gcUh^}&7K zCffOF_tQdl;oqd}LC7@QwHg1yHgjE2_F5tPnUp>J7b*J|WQt?783(X+xr6&(A!JWT z+3g3U>>nY6{hF~C+uqt-MjwbiDEriqhu?>-AzJ;Pd(-*C^IX%(^)~Ex4EEm+Kg8mE ziEH{#zRjPMeq*87w`{R*F?0Ubos#=T_e-`nMBd)NW~@%c`LWx6)`^R89&LYnzFub2 zo*IpFs5L>J8;AcS+upcV9PdkMA^; zvu=seAe(spLYp=#_iEWT`@uoRx!qMq45J z4AzAN>s=)4y^r-4f6@K)V)&(1(~SO_*dmWj%N4S|Z=y^bL(!(zArGwCZC`UjwDXqV zXRMxp<2=Wf*q(XPwgP>?k3Qi4&zAY#j#% zZtLzI4xj#6_*D2S4}C=Vb20q66+YjNb2bHKOW^NoCZvuM`NGdaW+}eENPk!Sw)y~8 zx(tQvpUZ5CJA|#aSZ#%p?YF&uZVt2OftAh897p|Pj1_(3lP}I#Ev^?WarK3NfsN6ccI;R2_4kVLwGG#h9ON})Oc3L9 zVl2+_rrcjA#$l}grX1@grD#LD*T{Z4szII~jzir~Uyi;a?C*X=_R-tXj$F5G#x2;^ zpE$$t*Lv7)DAi{TBda>!MSG@;dQ0?KyXAQ3-;MUN?Z-shZ8#32P`Bu(qaKj;79Z?> zdN%7V`}B;}O=qyr7u!~tbsJo^6`!!ppSWzsxm?whv3lWnIi6*>Y<_K<&3|?y#?Ka; ze{h@4f37XYZ_kYJ56X-24|m1*W46Wkhc?FeV_RbU32ia{kv6+OIn(YxGtcgibJ_i) zw%PqDjdp+g98FJavHMfo?EYc4SbuzGtbasatiRo!_;6KR+=-(v56TvPYQHG4Da94* zuXF2hfY!=G4B^Y{#7T9z<%LlcgzQs0uOlG40 zI#XZOn||z3d2KS!-Wcyca=@lfeog8edC8_9c@w-X)&Cs))p5wC-}(nx7S|H*?`XH_kJ{@C zJ34Lpq|7w`1CU8=Lq7V=C!gE&)IZ4n(b0|a7M9x*{2kLZ{ewX>ANFu$LNzAhZ_D*b0zxUZI98j@`f4b z!{BX+{*Sw3^v8ZD{dlx9Mn7t|>sf8Gd}w2$|H~nEJ^gpGo}7=*RFqm^UIaHv*<-K8>aV>Z z?PxC8*@v>cuNijIwx#$#ekWG1c!B5KL3~eyokNgm`g#OWz7P%b47=l0i)dd_W2@gEu$r$6#r*^c(nC~J{r8Maja zi78;$I72oeGu8iIK4gDGJJaLz_5~=njW^2ed8z)-R)HHO4|S#bKdp$Uy=fU-7Oc4lL$zkOD&-hL29>Y0w?6Ww1YU5=8h2Ph5F2k`t_D+o6eGtds z&J^DVDe?LfPs_F*`#erRHYi@7nwMqB4#`XNckhE-ev0pt(U5ye_L*a2Ak!vgHVS*M z#pv%(kJra;o8o^C*VTCBeeewGcpkdPlYK`Q#Oqm4$~unDir0@W24`j)=iTox=X(D^ z$UYRKpL{Uc_xY75YmsH?F4VsjWp~0(QL^u(J=ypE9WnYBo_PI}J<>;?IPu*ZuV3Jr z>VFRV*LFj^p0`J~bJVspf7{LRdZulf|3b7Y6Z7e|EiroAdf2Rh%_oz5t@p(1j>l!& zTJMY3>*34R2awk|%|9ACS|i%93T-P%@*R03UjM~oQufH>@%m)Q9(fYmyy^ZIF$SF7 zlIA}-B+1vEk8A0R@%p64;`LNpy8q;uMBlOD$Qy-rcoThX8)X~X+Ocn$7x?F(on4>D>-!&;`L@h- ze^+O#f)eB;b1AeH?R=F$wzq z-Ll=Q&7UUk1b$4Ba?~PLDy~PQ7 z*Ux4Cx!cgD>rHxedjcddNH&=R5uqWEyDi70B2wHs+xRVCQ&=O+Wf(g1+nlY2)bI33^uJ#l|%~ z9ml=92sVo1d`BO`_3L@0eMlGC^z_U@#7Es6SAfct^+|WL4bQ-~ zZLt5dw-fa`_~GP18~VOI=aa4JO`Thk^v=6wy`5W=^m*vN?{%j%oxBq=6YV)&cO>b9 zG6(zL+nUsLG9P(6Vsbt?j&t}kj5`N0o+jA!?i9Oza(b$-do;E;r25`}BuPJZJV`IO zTl%W&vm`ykHQ3*lkgN}8TaTsSyXy>p$EajIb=w*K&MC=y*Q#WF-#v0)5*m?rC|N%n zbKhg1CF_sVH=Um+>!aGBmy)7SD&l?*O3`2E`PuPGs-BuT%)bx&(fL}c-n}nX?|2+} znA>(gpQc)0mu&ms0g557OUHqP%UWe@)VuoNV}~>zP#j(C8E#w_*N{n^X0! z2UGR2$nSm#`r8Kk9)j&P<>%#e-j}LRTE_nH0PHQMzjr|Y4%B^Ts=j9GU|%Zc*&R;Q z(J~a*0oZ8E@U3|@GiS|&%$yD{Y~02D*p#Y&um$b?Cfik#s(-Q`b}FFb&+w(XU}qNW zY=fOu$jgJBTO2uSJ{+CXu{c$K-A}#csk*WMMXCCuJ8Ao(RQ>oI*vg0Au|dAnOxPME z`~q83kk>fKw`S4koHb47=5&mK-tF9%ajE+I6Crmy_j5?9-Z>n0MnUH?*l8K!|6;oE z73?G+&jve5=jN;_KPRX2^A!D#$Jn>JQ*aNFs(W_G_H?$V=kEG}w-=m$!(UvEn_YCCnAb$h4t|79|Jb?TMVQ*ua zZ*eAc7oC;UaSwEF^9ArlCTv~_J6mAqja2lv zkvVIUM&@*S&}Xlwt~W*hcoX(5hjyJQdTR-E)9<46kynJgsjyQ%BFEM; z$ltLT{e6clU)+`gKMl|6n1wceSNe9%gyA{wUj)55$QzTQ$FvRdues&SoYry3n+RL} z6yNc2@%r%{@%ow%hvgg}g8bpg&qIDU&d1C%{L3+pbRLM+*DM;A(``rDv1DK8n{j&Q zszklBJy{==cZR>aGa3B``3G^{`s9ABNgA57__Ac|^U$1*eXw;C``>|N{rxwS_3pQk z*EZPS`66uC&hUTo67pVw9UJUCpR9LYEB9;7t7qh_c_In>JS3;%p=ABmYw4#)lJ$=t zht89*(+E5Fz)s6x|0nk$?*Z6xCHXqk8UDpn!R6^WpNxU6aml)Vr(M^l$6^eL$8k@~IXVdWLy*59 zR@bjY8WgANpC{>q8#Daf-AQ`aYe{-`ne;_>dlHU4^d_X`thpsM=h!*f9&+n1z&aUel)$vaLt* zv7ZZ)^t93BDe%p7*qH^L7Q1hh3wChNbi|&7=Xknnm$BCx$2KOV?0$ z6m&-?>9?ID{dyz;wo_nh5Ogx_zS~x- z$HHg!oFlI#>hJHv9OTVZ{kChQ-Jxx;_jam2*f!jM@S#M^*%EbOv-?HZd<6P_8~kL? z`K&!vU+R=PM>FL{s``0vSIUkHm)0bRD{fTLM zS|jq4w4ClMp?jI;Yr7~-ue?(FyJJq8t}jp1+t$eaPi+~F{*$JUY#Z+HUI2NU=Ibm; z(+91Q`_Z{R4b#UFn4dX(pKnUjJy$S)3uH1!_zzA&8>c7g?~THCbRyw(sb8q zSzp^7Y5J(V5&riQP@aPF=?>qQ52WdhX|la-52oo|Pp0VwtEBw7t`YvOXVUbuw?XH4 z0_IT(xK|kMd+(Ka{XKhv{@!||caVP&`FA4!4)B9W&mg^q{Cx?S?;}4yO@HtCG~L!X z!vFCru)jj?Z`W&S`p}jU{$p>a=^1S!Fz11trB%xE0S$G_D&k+XK8v2o}G0+ zgz^W^^?hnj*EbeQ8^;pT_1Mgj{u9H~^}&VI8I`UN&x8D(kS{vdcXVR9zU(q7e{@Q^ z9`73IKWRVLcVteweuT&RNPfEh3tUHzEJ)W!Y#ZtSWDDBAH9_wvO4n2A|BhAZIG(Uu z0lQD0m9zy#v&+?!2p6&bcnRI;+=XIUWr{h?kDhy;11ruchmrZ%Uh;`_lEZU1#~* z$DHj;+;*0~?VWV}@kP=z)*^@os%*k98pNs*1O;0*THEZRwMwD_RuWJfv{jLcFIe4xNtlo4p$rY@a{!xw$iE&N*|=nKNh3%$c0 z3H>W~O{e@;;GZ5`smGMVkogGemQr^Wb=T15n!%N!LdtgauMAz@C%9`I<>P4+3$F7A zREDNew}|H)+K!@p?V!reZ38L~F5>r6F5--LP zYfv{LtFrT&^vZh5+D1@zW*mDMJlDpdgUrg#r_(EU7xF%i@>M)n(`FIn`zgPi_p2zs zpXU<=uBy z(XK>nIW>j3EepD57wsO#`-qg_l-XI8(>i!RpZ7xETX?zu$=r&2eK z_j2C1oLdx{!~ZYv|BUmBb}ypte%@_^q5IRKwiUdu;{9sgeLpSwat-g#^Ip&Ur1OjR zZRCA3@B4V~;C&nKAM#$DO`k^>we3y`ivB~Ll+{s|KZf-RFd^RCc;7On=(~QY!E=6M zjM2o@;I7nEVy#qUF$A6pigpf34cv-V`^&fyJ^%< zr+zl|9TyaJ%}Nb^d!|u;dus5@In>`peGB!Ai;BKkm>N9mOx1^P7NrJv-%tG#>Ia-c zpT`#MU78yF^%;u(H!GmOiu%>mms7uGY|){=qy~R~y2Ag>n$%$1^VF}U{sro1j4KLm zNDY2-nt^{K?Ke~Z59)2FB7+NA1EdCja+={+x1|OTen|Ze>aV8WcVW?yU8%tbM;Ly2 zH|;yA|28!^rT)~)X_GE0`r&YD@Y&&t{?|vS4^bc6AHCAP> z)*oNeKRBg$82!JvX#WKE=MOKEb0|x+FSOe^YxLZ(0U9B+);PLetFv>a!4{`&ePE7$ zW+~|4%-iI-oL9TAq$`axEuP```W9DDyWoLGr(H0~7C+K=EHrxYQ`0W+Y1-&N04L{s zJjX&!2iRk;j+xdaxHf?!ma_@>ne|6QOkKyGCAh}uN8e%9l8jn zZMh_FRih`W@*28LQp$T)z6Xk)VEvf z-vIw9s(zNVrytD;TCkOVw#RD0(T2P=`r3SNTu^J#8qGRW7eV^eTpbtmP`A{fXjdF^ z1ZRva4$cHm#~RHixFn|7EB&8o3wmEeUc(gZt=SG=MNDyU#@QvouZC&Cnd~j^IbU1X zerAks_b{7pcdX`dU}=fCYLLG4F>Nfe_NsHosS&? z(?hF7(RzTKp-D^nYSI%MGwF@sf0N!;p|=uSdBwnW^Mv3Gc%Qjk;p+rnC%kuzit+W} z8=?75gzxWy?~k!T$4gq{T^A|-+aGWQ_ndKquakc4ImhN}KU4F0;9)iW2=uiDn;R|t zcu3Km%-->j^<$BxAFGA#Q?WtMi(2E{a}?d$vx|d^MRw400J{i!p1<0Hju$NSZc_9T z*aQ4AdJ`=4774vSGZvqR-cJmAXF%_dj^G0Y#la<0ih~b67XBVJ^!nfM2M$xOQ-wc2{Q0%U#xVwe zC63@?czOVytTud+(0vPgYOv7VspyW(2+PH^C6T3ROIF*xSZMwg-T#?0RzizD_og*m zXuYEabDpu#`byE-^FPoUA+%nM4F;ZK{9|7oFJW8stMd*=@ayF~*V=q$AHAYC=mxTF zL3h1{?q`awKl9{$eA=S-IHCIz<8$@#exsAR=0C>;o1@fyA$9(^VBn9O2OetZqpz~h z2QG`$$H%~Wp0WkCCoR01z9c)$YtMMZpO`w4vvgLSd^{U|*E7DKFmRdU+wd2ohW>Bk z`whYO8aiIl3!mXHmi&+SUJ!hn;BOh@XrLjN;mD;L+hM#cxtVdak}>qsMBl?>8AD$= zf_3QGlg<9{qCUQFH^=(E*%0Hi>f6mYs1+G*vIPTm78x48We+_5*jS%#8B4Xo(tJ2-Ar+b|+Zu`YNIE4sk?nFTENvyZp5O%}&M% zzW4Dz_o?{hA>MP)vBVS=-wx1Yig=qNIFi4~d~Yz4*dQUv5uC&`K0iu%oEA*4Dh`eU zkDSBwJgPMo5GS>iID&F!QqD{6BIXePcPlV*-cw}7w+s>ACR~HO=3)~SMqLFlhk3^Q zXVgh-RK8~b=Rwo`|CdM{1g!8pC7^hA5Ze^5as+omD+M~PS?t;GV}5-a?gnw=z0)5fpm+Uww36zUMqOgBjsf3?KAqIw?8((^*h>o z7hBq|RqdaqJzvvA)zv$+7h7un^Mv45+RGRanPl;OO{lN7Z&sRC#`hQR58{veI@1qe zYlHe}bqDERC}vQnXCVDa8MMTn>i>95|K4N~{F~>7 z@BHJjCU|qondhOLtrlADg~yr(K}-67H?Y0&ls|c_Y%gn}X#G55^x+ixAT}kkvhvWj zTYd9#Gv(%ZxEtQRoVA_;ALG{4I1kWH_{dpstm)AH=yVo5TjLb?Se;I~|4Q&#?XkX7 z=%o2eDHmC}zZu~ADgnFb3^mOc**;g}6dCK^G2C^m>C+R?5xouhYmHOdwA-WWO<-0% zU*lW}%;&(!yU=XCIMuZ}M%$NeTei}Wfqq`y{+1f^G5F0s7ZnGUU8UjsV*GKmeHr_e z@t!kBYutoAFN}%lZ05VH;`dVYGt#1$UAMC?n%h-)i2qw3a_HYj+*pw6>Udk>&W(5Y zhS`R8w$0YcM&OgB%{R!od3IM}E8{qSb0l2L9bvd#qK`WioX_CZ#Ak*3*nm64nHK4< ztyTO;hQFNhF8KG}q1LG_8&&yK%7c`%zHJovmVc=7Yblp+#R7A+MmI9NpLhADta+Z+ z_|aE3--nr;*=CQV9loVq@f!p9US()!?z}M1@|{={?X-D{Z<#Y%d*+2q|C`iF`}}p0 z{Vu*UjN=(#a_;OZ6gXcm`B>p(j0;>>>`?y?d=n$^9j{sO4(ha7@IDND0A01y2l-BE zabqNG@m*ma{!eh<6^8BT1)FPutprxHz)pHT60gky`y1f_*_b@!|2-16%_7U`z&2Z8 zGn26Yx& z;0u7yvBI0U1wLQF+br-Sfe(nT4V`rS$%5a2Z?Wj`RN%c9_X0E(vzKA_rvDMyVBSgI^2ff{sGQI|Nwmlf8w=*`&{~w|GATl#>wD*j!EdO5WOg_pD zdLGumg0JdvWBgMt{N?;rzAMerzsngxnfL_lIo5y{yp9{SGApkh-UU~iUvLffXBfDe zZ`2y|i07nFd9h|3IN1Ld_0~S+KBoGV`>eH3nf?agv}dFHjCIuAHB0G1cncJi1mp3g z!))=LZEF-i>t+scRni}WhdSXw_^kI0aOL%buSt$zDRK~=HQV^@q6Y`>(RluY@Z4AV zxQ@hBbP(U^_^VbXF@k&pDBr*2=W2C=-~amouHY!UFZYVPw`2G|OypU|{3h}ZlFN*S zzXtr7@M@K_iode__X=%eEC~McRffEtiarm;ayvUlSfrEy&oMyDkRa3w+6LM{vThlHeui{L-f<1l<>^c9P3TV&2s4e+_*! z`ZAc9CU-%J@)s6-GGF9_GY6bjJ5%z=^pB;kq|-v{FB5{=*f6bqhO7g=FfH9a>y5GF z3-d0tQoz^ji%x5p&^m0PwPr%lTNtLb-Js=O8%e9>X+^7iZ6vMzzachQ8=Y1kq4lkW z*7FmBjxk|c8w^?+IXF{>dcRgHTDBJ>X?+B(zzfl7bx>Eb-$HBcgka#OVOn0ZU*z(v zw5pyk`t?F2t-njZPC)A&p>@PU>*WbS&$(e*H3luo2U}^C8?>rgB56GZK6gv>eytT+ zvBhCK+%O@Sb9R{4OoLXSIg*ym7*lP{k+kjyUvqPGT8|5@eim9ACj^^Eg=t-7&~m&U zNvmyzl40@dk+g0DU(V~%Y272VLKYcrW_;y`X^l4fwJDO8ZJDCgwkeX<)zYs`(P`aG zo!C{w>;W#*uXTj_`P$#L`wm{kHB*tIxOpUXfb`tA*1|4f^qnsFBUuzwCN_}(L zoOP^e2jv2LfNz}j^#^6!EwHQ1?=v%xHN9sk-(Zw`GmbUAWhvibln2s}HN9>r7n-cK z-V+)cb$>VNOkUh+$C_TDOn9IAr|=rkJMdW3i*9fn+X z{3Wc@K>V?$+bEZ{y>&e;>o8gCM_Z@vXi&K4#6_>^-0*7OtlFYC{#tV5+he z3&=f~cR7^H# z$N<;lqquWH#f5ct#>P!QgtCUx_O5J8TlS62c+O_DT{oC`?k7F*lOE4qOWQ-nS}zeC zI|eBn72tPYAI4FCx}u*oXn^Z5ID|iVu9GjrMe<{IY$1Fj4> zPZYRpzI{3JdX00o0XG>qZxpz(zzun`#(Ap&=K!ub3fvUn#{Hwl`3nQC0JuODxcR_M zZLM)$W5E3cxSU@47u~K0Zo!rs=OhDeIB@PLaGwCT>a7~*cmr+_aNa0z-N0>lyT&=j zfJ+hnqQGUNw;lhiagH+J`UrnfY-OzI_g^*6TpccQZaz9o*+YO_uAWccCHdq`|9O-* zXGX>a&DmO6gJEM0*qAmXGJo#iy~3!kpx(oKrrZVb&V=B#eZe;*GT%FDsLFp1L560& zcR^3ScSxs>FJ(y7eD8Pg=dt8_zvey1$oDqf>#H3Njq>ZjJLj;0`@HA-E|;&R%5tj{z@vw03-)8CXV2(R9Fx*b~mo;@e{>^OXq1|3-XT%LT_^45|D_=1oIGiecq^IYt@|pcj|l3AFI|W|M(#Cn77tEi<0SY2e0%i=cZ881`FQWhr@WwoeJ+?sJF%f z3)U-~cY#xQt{Pv=_m-;P?}JzR{R1-BZVWa3iMBaL+|=-(!re}v+u^(XDuw@HV9eb9 zRKuUU!ENn}%)8?{nddF#^F`NNYn<0ob~iYJU#YuSWWAnqm1Qm=A1l7K;H&)0y(Qv7#@zl!o&V@%b8*QS@J z`xj7d9cwLLs9gG;l$&Gj?l|av5o(f{V#n9yzOi*PPILeLXp?=f9%H{R`ETh*#eFHR z-g)rSerg_#`8|2?FN=e5HpyejeJv^%eh?ax2lrNx2WOm{d2rjHa2`At88-jAt1y$N z%sn~43ccLZSd;MFxhO@?fu&RLIfeYe+m`jsKUm*vR`Qqp!4LQmv4fo3xI4_L&Kp%| zT9e4IKxD|8#LOks&$6y{vizCUduBz?jh#td$-5T1Z?nE{4%7Y2pzB7@LPPkjAEwq+ zRdXZh=wn}U$%fwW3C7-MmOokO?6A;zm;SvLrt`YlKl1NAbaIV#;+#l2JCRq;oal7+ zQ&+OhLT4N6-&ezQ{05!C>@c0SQxqNc9D8y)V!y563a}>;tv??NoewQ^J|uszPSMFl zUym4cyuVdC_i)EoJ2^5NIkM0+yKiT|;ursk4e2={V4~4zhK4DNDtw!s$GzRkW2S#K zFz(wU=PNT$^f%%0a|@3UQ~?uq>*w4VnKYl1>e{a()w?&T{I+E-DW7 zcZEjSefzJE_thF};7h9*x!_2r~FOf=Kih^r}W55 zk6j<`R%@%3;#Y{}&WO>{CxL75Ce=?J*Z455mTMKR>$umeU}~iAss@+%9*G0K1&5<7 z?7Pf(aq0&(&SYp9Q;H7~&5&yo~w&(++2M>}&Kv)>q= zZ`w{(^Fbo@R(?&qtHApSc!SL8!K*`!hY}n?k(aCsBv;(3#~TABG=~ zp$D1Qgy#hx*ElzW+mz=jcyL@3DNlhr0^B+S?onXey<{%DW^=xA+>RRO^9EckaNa0z zV}YCcX^rz4;H>?fPx*rX)HqjL__+%lIoC$=BXApld#qRcm7GyL@)_~JrTwk6_goj* zUf{-kPW-RKMaG-uz{^-`E;HiIf2er#u?p}cM~;mU-*i$e8u*WMW!$ zA^Me=^&mPgB4(96-cZco&Onl!Q5dYptQnk9DA3O+WHMi7_$P?0^q5u7EM)q}^KQnh z_EKf9^>J$6yaRbei&?uzpo1ed&a->zrW=_r2-L_Of<3mTfnU2KQa1v(0k~6pwV%Q{ z&?9X%PJTbNr~P;E;Jz}ly}*szS>sIU)m~zYalsm=y;pfQ=P4KLs&U3x@O}bb?W#z; z0=EIUF5L%Y>ar3YG6wZ?MaAE#c<3VfRBM#$@sM7g?k}X=(CI$WY0I}N9y*Wm1;#mu zjYgc4H$KIcVS8+)fxoT+c>BMU-Nc+noReY3Iie>O=WM_h#BKwZX^jhG(mOe$UDozq zva#2niLXre@4l7sSQ>c-N6kU${#5uVA)f8o7x|p{qB=YWz1c_EpZ5}cu@PUC%RQ#- z@wHrH&OwUK7s$_hNpv~~sgpUVc8f6wO^x@-+$nk5Nj5bHHIS!mXa7ljQtv#i*mUpm zx!{zs;VCi3?6_k6%uxgV&EZZ|t3KTJ$UQ;UBoS-I0Pj{kaR+SKBj9m!7p$BGa^QE1 z&zzv2MUrw4cNJRUiC_O#eB047IXAK%zNU3X<`h?AM@PP>asJBahsNEu(NLN(6odX!2Pij&mYn5)AQvb56L42ZaUhO zjx3`23|Z&ud3W1=oNepXU-&(;o7|nHU*C&fFO2M0H*n+HYn*ats8wF;In%qKqsEzF zX}?qSc2Q(|f!hF_wQs_^8Xsx?iS+LPHd$*K+veDDPj#W-FXNZrSO0HpJuR4jFj_hUrr@U|l=jim@LYD4N#OLI(=9IXJSi~22 zFx2$ruNW^eDsIwN^mp-_!Rad|a#mN?%Easa5|ppfjvj0J1XwdBsz_6F46#+Pczd#b zHuO#Ed-FM8Vy*X>|9kOi_F)5kc*s&G{7)tBTTGdXbF%#9*g*5LunkCCf!hJxLf{G> zF6oI6p95Cny*y%Fv!6M>P}3UeXPglqKHT5MZz-pbTUZjjIaT^O#J`$$x_pRh&34VS z`-8MIaxdCL{apgPDPF<4gU6a4v*2w_P%=4!Oe9CMyho0lRicd^haNuGR7)FEj(PFn z*wXe-CC9nc_m<;I*I%;idw2YOnSyX}{`w=6_53@1UJy*%Q#| z1GfXXlwR$-h5iBNe@puS?cJ7r3285IQ-M2nEIdA>{F7YhA7uWwluOwT%Jx%c#?Nnq zGw?{*u4FwTaN`cuI6EwDrF=fVe8J%w=Ppb84brDaBijqy2H-yK)n3Nyk**r&Hp-*< zRhcV>5R1J{edFGeV6{GO)BQnc=x2S2KgBMIFMOV7LrsTo36EPxr5d-(Hk)>l?jMX@ zNITCOzH0;4w6}(X$@=~wb8xWg6=fG6QLpE9y4jzB4}9q(;*-2*A8mTHN z`q|tMLS=vM)px-;?uQ!ZvR>s=PD3Y08UK{aJSK6^ujsFLL!?XvZpg73=l}I;FL+mh z_ueSwQ<-<~raUykwzX@Tjk}^_xHFo&_!n@;c&x2%f2_?fafp65FlTleY{oj8SU~oe z^*oebmcbqEm(X?sI7+y0y4VNKI=QFa%v}wEXC0nz3?*J_?NBmaD01(sjh@d_U_ayO z;r?(Lrw*P%U*M~1`nzOoHd7`(NaDmPywkQ(e8x)J34ZJR;^xk3>zv}{-KvKG?_;_{ zO)|&IS)pq1S>fxCso3Fnlv~@C>*eYGd6bVa?}6W?`XhVJ#r4VO3eT6rli2Yqj8S=7 zaTNa$D*M(bx6-s736<@l{LuA(N1irx!S5q1($EFpEP@X|+ar_QNBg@f?8pF_NZ*BK z3v!xHnaGIq&U)Uj;)`V0=P~w9sW0XK*9Vq%%l|Xr`SpR5x~rJKr9Qx2=Q6j6oxLWs zY}%LxOU&d3?j=oYQh9?6e*yjHe0ihv&DsZZ?mnCPJINWxf=hIJbU_JyD#k`O>-UhS zN;&P1{8C$%3|%WNg(Jg%N^jZgu|~Q-i}KHC=cSKk-`j5JPhL}f2O#Gl5sfd2-=dX=Vq>=caC;1QsmEgDedtFV{ppL2`tkb}GG3Gp+CNTq*=^*; zQ?=k=&f1Ufr|r8uQ7aR?BCGi~v;R3ltIH%OH-wn14}EXytJQ6k^(^>=yP8kdw35&JNK^BsUFA?BVzPhH|H4G#F2VO)Nl|Hh z|ANuPGSdIgk)Qllg~*5819$d&-jCmR&$h|4W^^sVx6YiA-!+MTaCdv1e7_?3nT^;< z8}?sC&PHUk6Cbe)-rfb5X781=42qny{LjKeD>l6pm}cUH#xD7eKyuny{#S&Du26y8 z$q!$8`Ad|EENd;XX+2|A+B^ZScH$ASU*9{)F7xhtY_;qxa8#%^brr;yCftmFh2g5W zi(YKx=z@vp?lN?EDZ0D_olf9>{1P8J*8P^?Z+}yb>GDNt-8lok+6|tp@#|c%G2&M% zzsi2o{lBIz4Y``U#BT}n(u^HeP#;<({`dIbci0~r=RX+R2Ok`(kL|pFgzd_q+d+)~ z5b_sZi+|JKbqn_4;CpcKhwZVN%K1*$e1{Uz9rwG-nske?CT(X;TA};yEPn~(#5^}7 ze#6>F`RxL=)(FG>6FKyTv+4TD@}Eb4;?Tn&VBoRo;B*DM-0(%kx5yZkc`U=<2#h>C(?- zXZ3ew6gz?k`TY;~Z`3^LL8m!!8s8G7;SXiH>(O=Ap3e`{V4uU%HQr)elO)F9qFf)zrRmcGFr1b*)`3U*vWaM zvOVBPI1p-_4DM;1eHPr3UlUo*`lA8&je>jY`$)Ly23&<#`LVX?DwZvzKPT!-_pKZ7 zhsVc)2k}LR@I_ttqQiWX!$q@tY$$wqhxK=zDzZXf%wLU_k80}{@_owOD{a1oW3}Mp z*n}}R>F18_9;gKu9*gxYJOdwX_-pZ}cikK3oA=Ym{QqOLZ7^UOfVs1Pw$$sY8QMUMmVW()bufV>C#V5=r&fpm{TVtFI%hhIA z#cE}FZJNF&PsO%|C2O-i0y99HEq=uQiK??xSMinlU;LWAQ~fW$AtLi-MYiOw)BL|c zrph)V5KKKbD0$lQ~}SE3jBj!bZUX6R`T?>`oM97Hes(aT}< zBEESuZDn46IY}EWI`RzY?{eTTR_?vj_hf-1xcc6{zSU=I!Iy+@Y*hA(G{%Kp&hi5v zpCY+X>KGjO$)v)Q}Gy1#ajK+M* zBpz~TTGI^VS!!4G2E}Q?d~oEm9*ie;aS`W>&fLJ{#Ygfav}2YeyAr^~I@am=>Qdk1 z$Y|x>IAq0du894LZ1AJlL$DY<-39E4a$Ua_p29XC5s%HFE)=89UeI^N6v@ZI+apu? z-Kg60!Owi0|HS3%M#X8f|AZ_Pt{$~ya=c^RG~19_INP$724AM`K18>*bCQ29{I`G3 zJddorcPQH$1|9ccwN~oK{|>&bZ9`6KU7zOfiyS0wZneybZTzm1%%2Y6%a9fG%IsN; zg=AzRdFm_prebewqQ5gX#s9f2dDg!eFEee)mrt{4vnN0EK(;^bfyAV(BbPh~&wFDN z{Hx*nS>~Y2`IE7e0G=f3q+Hx=lFZ;1LQ1G1$ z=HSgLf4?7^7Z~^Bh>Z2voH6`txsr26vexMN>{8!yv8%7*u&?NL)h7MXwC_%oEB%=I z6XiIw|9K^>qEp?>fmEq$4&7 zoh8m*pwzsxEIN0!YtpzYq@E!~E!0^fxiD~#W<(Qb(eX2omk zSWB%NX3Lxf37s}lDAakRPajB2*AHQTAZO5o} z%K-bT#C5-hN2|T77(LVff5@#H+bA`BPO11D_zrO9{T}LW*c*!YcBqBK^|l z)O0&|HIK*X75?|YzwsLk!hbyb9`W!YzpKSqUpK_At;@iNOcq{*Pwd=YF{3M^BEKsh zAIVy4pZKf#cA;VS{{k8%z#h2jHP)Hr116|k!0XVe;C_Y*_?Ee%QE2llwW;UP1;wmy zHZ@S59$KVrHQUO&k5$NH!*cv#;qu#*#t zVc#`|7(mVaeFm|2$J{Y^x>lE!=m@^VIXX2q2NSDj8S!B$?I(igGVomr-b+|#O&~uM zQz!9a?W2x$K4hcM*UY^(=9?IB$+*j<{7w3mGf?eSNtwiXuTjQcwc*cX4Jvzvnf~YK zyUckNhEJoqsqp7XQF)0K$R{*h+ZT)Nwts)mw)|N8l8rI(otwx9G{o4K46_aHoWcJROC-=X zJ~m-VK5=||jQwqYOu~{;HIA;!YqTzzdnEP~9si&7pYg5d0kX7U+tXUzPV~16J&6Ba zm~gtomw&AzIM$Z^z$Di4VrLz!qefzP=3NyP_iJ6U z7Ruw<8*dGGn~#RZOtG7JKsmFLg`5WYzd&amZTxnTzug!|_MUMx$iD`j7joyo8szX2 ze2Kr=K3uDtLzzZdv*^q+$L7-4KhowfwlDtlO=v&D|Iu{23^?&A6_ZqaRXb9*@nBU) zk{;j9psnOyJhVp#kH#Y}f3>FnPFGIN!smwn-tn9xZv1m4$<@#1+iZ2Sa@Be%M6Sbg zAXK)Jb~k}T@^!+?)BG>@pb5>^ON|`CZZ)3V1}&=$ikZ`74=UPko=VJifbk@Av33FH z9f<)Xw<&8G;*QZrqx|-zm)|~<`Obt3aK^zqJhIFoWoJZ|dC{F0*;w0ZQg(J^8NWq1 z#{1LAGIAATyv$wJwmDLEYGfJbamIMBj4TTTDRV}aaRbE|?@f_q-mcJ?moDZE2V>|LRUJjk&*B^E_9~jB8Kmc>pcV4JAw;19T)o4ak0L#!t1!utB#A9#9AkP z{JVi`gWv*A$A!)po=U8V%&hP_E_AQsy7G8jegjv7-~vv^gvzVUm@%4)5u@UC{+IK0Zr>aYDUEc zlj9SYIBdhVZ-!QY_23uepL5~y3;em9aaVJ59_KJ7H#Pp zIg0R_HgaD_{C_NSWMsYIv+|%BJUBRe*uZ?5*GKUpbNP?8-FK70KRF<2i%-~Bj4bL? zln$b`7vAlIRbMJ-L;R?pQ*U`K>0GHBh|cBNk(KPqp-ysal1J_sK~8<0>U+EavnBI* z7~6UUvkl%(Bp;19tGBLu$8g$D=tFo6$sL|SGj0>x5Z*P`uQJa5iVWS1buT_f=0xG& zo0062xclgWjl^ce4A_OWscz)|M-&VEKI=2hG__K~5w;slmvf&mzSJABWj{j8e z$MJpIf5A8MykB_6*EPeli~*C+7RF&-ALPS+L`6(aL7p)t^60-E+_uxSU;}-&#>2gN zl-PKAFFvL3rSVGdElp}{{7&g;pxKvbdik&TLZ7z0|BkQUM&YZrkK(KNMa9>3z4$s# z#yKaK@i5xEhvR!fp{DK=$TlxFFH*MPwB`JFeHb654;9Cf^nLNF=TsjgCm=F!II7BR ze^uj4c*CB;GC%kDv7p;;D9P1(jMzsr#=*G-TJl@RIpl(R!yG58pPgJ*71uHTu{nvI zHQV^@Irw)OD_RnM@k%Xd`1(4=d@z0h{(!m2I&Q3X*rw;A?Eb?df95dRs}+77!6a9J z|9kT$b#uFtTy5C%crCq?v0P@_zQld)G5re!ruBOz!}>of*$!t;dG8lJ`_B3uNkVTf z{0724qbDC__#(!vTK9?n(D8m}=I3qtG3%k$omcG3}=| zCUSgtU{7{v#k>ByF@9N3AC;fi>3pvG*Ybq2L*dOjmZQecH#&mkew!*vN{ZUGL4|_H z6HsH@EwNaCZt~JM;w~=T+?FnN=<>T_5+tOM{}N=LDT4&~blH}Tgo=n_g1HEzAvv=45Otdwh?8ORy(#ORgh@Xq^l>Jlb z=Lp^ACXh2JA!kxd&gAumw|+s~2yf!MgvV&>nhEgWU@mxrr^JVXyWyQAmyNL|@@jnO z(yrApw$2>rq_anC+E7KG{)G}37HG65XHbuP=3aT3Z{xk1Z({ z+x#y>=Kytv?jr6`{G0GVU4q7x?@8{$L5{b9-+*(}+I!%E8 zX}0uE2Ycmq_ArTOYn4H3Pa7g~(CFDO$vvmq>u{rUHy6k<9 zb$M}J1@>pL*FNVK=&~R$QX11$kWX2B%(>L*acW~c`>W(h_st^aOdu~)3O~bawoVWF zC1>NDZ17YJJ&8$#Mrq7@1^M(v+DX1cayuj8_wve$u7x(O(<^5j?GW$uRqQ}`Zik1x*wsTngc{$eLRRp}o{h9HC1&;o#`H}v7!P>2zIYZW)wxN8lhmH~q9ifMWY4DwkE_PuTG3b7JA8o4! z@28^+lW#A2*oocS>07iqk#obdYEH?cZ99Cm{Z{e3=tuYyzBp&`s2!gC*p1zmkT49M zis5OvtRZr=x)ONG!9U4*xD7r`zC7?HeY3&WiRy*7*1tsZX1h)Cc4IW&Cd85(??(>X zj$e+)KPTX)6UmJyvHps!JHYx}aJKuH`{--KqU^5F!Z=^(d@X3dG*!<<#@F|&ODK-7 z>lhX5YhT#MH!Vrqw@dsn`+c&9TbPu-r2Umd9dVXNAnO zSD;hQ`J|Eym-5m-D0$j{rQ(N~&}!di^Hoe&?^_a-eB1f0fex{Sn^n06-8o-WIX{P{ zNpC&t-ynN1)97zPCVoQd(Di=!G-YAdzs0v`Pf%Y_>+l^~66Z7F%$&g;ex#Wnhro_Su6(RBR}OLf&6ahB?jq9w5g z_f|xW3;e=AI%pdm=GBy~oCgzL8&u4&wSkyHWL=@Dvx=*Xw%S9HYsQ`E+_5KAxPSh< zF0qR=_TRGEe-N9IF(P+e2+if=%rUZnF_PKorEUS=5l)L8qK^@QdzCR#wO|2bBvT(F zTWrXfb3rDYK1R+VmO=L3WUXm!pvo!p-f-a|6e>J4e?iwF>NAPu`9^VTG(J8$&C181 zPIuhN_!y+~@fY~e`t;(1aX216_@1k2e_NHa6h5S%ld9Al(4M9R+b5~9HG{g25jJ1x zMD_05oA_IS?T~!eWvVO(T-v2-4`alWs$TNyH}h@k{q)cCL#S{k{gd%u!knK+|0GVB z#r+7Uf34tmZe|aPe4>hrv;1FRe~%KIx#Kv?H}z8APWGjB{SOW6-_CsrGPc$T{VzfV zX?v=ik3sX7(3J9LDCbUvg7Z78oK2M9WR$NK_%A~R*L+>&{D5+oQT~L$Q$FXLD(6AU zos_RdJ`%6bL0|viDR^aUJp`-+*rj``oEdzlIT6^UJFA=$zpVYX$~lIz63Vt2|C3YG zd6IFpkhX5xrhTX2tmCU*KL?ZU-wTY~1MBP+nBHK>?Q76q+#<}{)^z( zk*@ClL?prfwcJ1N!dSv|}=hKDHR_6Oo`1~3^ zAB4}<2A>bkn$^W#Xx(k_Y3#qf@1HqJ=ka6sv*vmB!2jj6l{LrZtl#sA$MRWY#HWzo zWgXrHe%5K}1Cf#JMbyS{uRJh=Mrd_;#ByS@cH)aRWG8EmKJ;PX!|*abHeFvgh%M#aplnI>(9XWJ{7z2&aAi~SP1`;fdSa|C z8_xbSd-LEgt7YEN#|>>{oh9pJ;m71fz6IF;FFEkykZ;Nb4qC0(s#vcBI>a-+mK+tk z%X;i>=m;D-kFYThxW%@-$X)VcocSAQ=dWkKiTcl>)sD&j(a+lD-)++1fiT&d)#%QBWdr7YzOT7f%0A4Cj{{Jbez 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 N_kQ5RTRXk9{{ZK", self.line_, column) + + def next_(self): + self.scan_over_(Lexer.CHAR_WHITESPACE_) + location = self.location_() + start = self.pos_ + text = self.text_ + limit = len(text) + if start >= limit: + raise StopIteration() + cur_char = text[start] + next_char = text[start + 1] if start + 1 < limit else None + + if cur_char == "\n": + self.pos_ += 1 + self.line_ += 1 + self.line_start_ = self.pos_ + return (Lexer.NEWLINE, None, location) + if cur_char == "\r": + self.pos_ += 2 if next_char == "\n" else 1 + self.line_ += 1 + self.line_start_ = self.pos_ + return (Lexer.NEWLINE, None, location) + if cur_char == "#": + self.scan_until_(Lexer.CHAR_NEWLINE_) + return (Lexer.COMMENT, text[start : self.pos_], location) + + if self.mode_ is Lexer.MODE_FILENAME_: + if cur_char != "(": + raise FeatureLibError("Expected '(' before file name", location) + self.scan_until_(")") + cur_char = text[self.pos_] if self.pos_ < limit else None + if cur_char != ")": + raise FeatureLibError("Expected ')' after file name", location) + self.pos_ += 1 + self.mode_ = Lexer.MODE_NORMAL_ + return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) + + if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + if cur_char == "@": + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + glyphclass = text[start + 1 : self.pos_] + if len(glyphclass) < 1: + raise FeatureLibError("Expected glyph class name", location) + if len(glyphclass) > 63: + raise FeatureLibError( + "Glyph class names must not be longer than 63 characters", location + ) + if not Lexer.RE_GLYPHCLASS.match(glyphclass): + raise FeatureLibError( + "Glyph class names must consist of letters, digits, " + "underscore, period or hyphen", + location, + ) + return (Lexer.GLYPHCLASS, glyphclass, location) + if cur_char in Lexer.CHAR_NAME_START_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + token = text[start : self.pos_] + if token == "include": + self.mode_ = Lexer.MODE_FILENAME_ + return (Lexer.NAME, token, location) + if cur_char == "0" and next_char in "xX": + self.pos_ += 2 + self.scan_over_(Lexer.CHAR_HEXDIGIT_) + return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + if cur_char in Lexer.CHAR_DIGIT_: + self.scan_over_(Lexer.CHAR_DIGIT_) + if self.pos_ >= limit or text[self.pos_] != ".": + return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + self.scan_over_(".") + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.FLOAT, float(text[start : self.pos_]), location) + if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_DIGIT_) + if self.pos_ >= limit or text[self.pos_] != ".": + return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + self.scan_over_(".") + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.FLOAT, float(text[start : self.pos_]), location) + if cur_char in Lexer.CHAR_SYMBOL_: + self.pos_ += 1 + return (Lexer.SYMBOL, cur_char, location) + if cur_char == '"': + self.pos_ += 1 + self.scan_until_('"') + if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': + self.pos_ += 1 + # strip newlines embedded within a string + string = re.sub("[\r\n]", "", text[start + 1 : self.pos_ - 1]) + return (Lexer.STRING, string, location) + else: + raise FeatureLibError("Expected '\"' to terminate string", location) + raise FeatureLibError("Unexpected character: %r" % cur_char, location) + + def scan_over_(self, valid): + p = self.pos_ + while p < self.text_length_ and self.text_[p] in valid: + p += 1 + self.pos_ = p + + def scan_until_(self, stop_at): + p = self.pos_ + while p < self.text_length_ and self.text_[p] not in stop_at: + p += 1 + self.pos_ = p + + def scan_anonymous_block(self, tag): + location = self.location_() + tag = tag.strip() + self.scan_until_(Lexer.CHAR_NEWLINE_) + self.scan_over_(Lexer.CHAR_NEWLINE_) + regexp = r"}\s*" + tag + r"\s*;" + split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + if len(split) != 2: + raise FeatureLibError( + "Expected '} %s;' to terminate anonymous block" % tag, location + ) + self.pos_ += len(split[0]) + return (Lexer.ANONYMOUS_BLOCK, split[0], location) + + +class IncludingLexer(object): + """A Lexer that follows include statements. + + The OpenType feature file specification states that due to + historical reasons, relative imports should be resolved in this + order: + + 1. If the source font is UFO format, then relative to the UFO's + font directory + 2. relative to the top-level include file + 3. relative to the parent include file + + We only support 1 (via includeDir) and 2. + """ + + def __init__(self, featurefile, *, includeDir=None): + """Initializes an IncludingLexer. + + Behavior: + If includeDir is passed, it will be used to determine the top-level + include directory to use for all encountered include statements. If it is + not passed, ``os.path.dirname(featurefile)`` will be considered the + include directory. + """ + + self.lexers_ = [self.make_lexer_(featurefile)] + self.featurefilepath = self.lexers_[0].filename_ + self.includeDir = includeDir + + def __iter__(self): + return self + + def next(self): # Python 2 + return self.__next__() + + def __next__(self): # Python 3 + while self.lexers_: + lexer = self.lexers_[-1] + try: + token_type, token, location = next(lexer) + except StopIteration: + self.lexers_.pop() + continue + if token_type is Lexer.NAME and token == "include": + fname_type, fname_token, fname_location = lexer.next() + if fname_type is not Lexer.FILENAME: + raise FeatureLibError("Expected file name", fname_location) + # semi_type, semi_token, semi_location = lexer.next() + # if semi_type is not Lexer.SYMBOL or semi_token != ";": + # raise FeatureLibError("Expected ';'", semi_location) + if os.path.isabs(fname_token): + path = fname_token + else: + if self.includeDir is not None: + curpath = self.includeDir + elif self.featurefilepath is not None: + curpath = os.path.dirname(self.featurefilepath) + else: + # if the IncludingLexer was initialized from an in-memory + # file-like stream, it doesn't have a 'name' pointing to + # its filesystem path, therefore we fall back to using the + # current working directory to resolve relative includes + curpath = os.getcwd() + path = os.path.join(curpath, fname_token) + if len(self.lexers_) >= 5: + raise FeatureLibError("Too many recursive includes", fname_location) + try: + self.lexers_.append(self.make_lexer_(path)) + except FileNotFoundError as err: + raise IncludedFeaNotFound(fname_token, fname_location) from err + else: + return (token_type, token, location) + raise StopIteration() + + @staticmethod + def make_lexer_(file_or_path): + if hasattr(file_or_path, "read"): + fileobj, closing = file_or_path, False + else: + filename, closing = file_or_path, True + fileobj = open(filename, "r", encoding="utf-8") + data = fileobj.read() + filename = getattr(fileobj, "name", None) + if closing: + fileobj.close() + return Lexer(data, filename) + + def scan_anonymous_block(self, tag): + return self.lexers_[-1].scan_anonymous_block(tag) + + +class NonIncludingLexer(IncludingLexer): + """Lexer that does not follow `include` statements, emits them as-is.""" + + def __next__(self): # Python 3 + return next(self.lexers_[0]) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/location.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/location.py new file mode 100644 index 00000000..50f761d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/location.py @@ -0,0 +1,12 @@ +from typing import NamedTuple + + +class FeatureLibLocation(NamedTuple): + """A location in a feature file""" + + file: str + line: int + column: int + + def __str__(self): + return f"{self.file}:{self.line}:{self.column}" diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lookupDebugInfo.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lookupDebugInfo.py new file mode 100644 index 00000000..d4da7de0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/lookupDebugInfo.py @@ -0,0 +1,12 @@ +from typing import NamedTuple + +LOOKUP_DEBUG_INFO_KEY = "com.github.fonttools.feaLib" +LOOKUP_DEBUG_ENV_VAR = "FONTTOOLS_LOOKUP_DEBUGGING" + + +class LookupDebugInfo(NamedTuple): + """Information about where a lookup came from, to be embedded in a font""" + + location: str + name: str + feature: list diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/parser.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/parser.py new file mode 100644 index 00000000..8ffdf644 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/parser.py @@ -0,0 +1,2365 @@ +from fontTools.feaLib.error import FeatureLibError +from fontTools.feaLib.lexer import Lexer, IncludingLexer, NonIncludingLexer +from fontTools.feaLib.variableScalar import VariableScalar +from fontTools.misc.encodingTools import getEncoding +from fontTools.misc.textTools import bytechr, tobytes, tostr +import fontTools.feaLib.ast as ast +import logging +import os +import re + + +log = logging.getLogger(__name__) + + +class Parser(object): + """Initializes a Parser object. + + Example: + + .. code:: python + + from fontTools.feaLib.parser import Parser + parser = Parser(file, font.getReverseGlyphMap()) + parsetree = parser.parse() + + Note: the ``glyphNames`` iterable serves a double role to help distinguish + glyph names from ranges in the presence of hyphens and to ensure that glyph + names referenced in a feature file are actually part of a font's glyph set. + If the iterable is left empty, no glyph name in glyph set checking takes + place, and all glyph tokens containing hyphens are treated as literal glyph + names, not as ranges. (Adding a space around the hyphen can, in any case, + help to disambiguate ranges from glyph names containing hyphens.) + + By default, the parser will follow ``include()`` statements in the feature + file. To turn this off, pass ``followIncludes=False``. Pass a directory string as + ``includeDir`` to explicitly declare a directory to search included feature files + in. + """ + + extensions = {} + ast = ast + SS_FEATURE_TAGS = {"ss%02d" % i for i in range(1, 20 + 1)} + CV_FEATURE_TAGS = {"cv%02d" % i for i in range(1, 99 + 1)} + + def __init__( + self, featurefile, glyphNames=(), followIncludes=True, includeDir=None, **kwargs + ): + if "glyphMap" in kwargs: + from fontTools.misc.loggingTools import deprecateArgument + + deprecateArgument("glyphMap", "use 'glyphNames' (iterable) instead") + if glyphNames: + raise TypeError( + "'glyphNames' and (deprecated) 'glyphMap' are " "mutually exclusive" + ) + glyphNames = kwargs.pop("glyphMap") + if kwargs: + raise TypeError( + "unsupported keyword argument%s: %s" + % ("" if len(kwargs) == 1 else "s", ", ".join(repr(k) for k in kwargs)) + ) + + self.glyphNames_ = set(glyphNames) + self.doc_ = self.ast.FeatureFile() + self.anchors_ = SymbolTable() + self.glyphclasses_ = SymbolTable() + self.lookups_ = SymbolTable() + self.valuerecords_ = SymbolTable() + self.symbol_tables_ = {self.anchors_, self.valuerecords_} + self.next_token_type_, self.next_token_ = (None, None) + self.cur_comments_ = [] + self.next_token_location_ = None + lexerClass = IncludingLexer if followIncludes else NonIncludingLexer + self.lexer_ = lexerClass(featurefile, includeDir=includeDir) + self.missing = {} + self.advance_lexer_(comments=True) + + def parse(self): + """Parse the file, and return a :class:`fontTools.feaLib.ast.FeatureFile` + object representing the root of the abstract syntax tree containing the + parsed contents of the file.""" + statements = self.doc_.statements + while self.next_token_type_ is not None or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("include"): + statements.append(self.parse_include_()) + elif self.cur_token_type_ is Lexer.GLYPHCLASS: + statements.append(self.parse_glyphclass_definition_()) + elif self.is_cur_keyword_(("anon", "anonymous")): + statements.append(self.parse_anonymous_()) + elif self.is_cur_keyword_("anchorDef"): + statements.append(self.parse_anchordef_()) + elif self.is_cur_keyword_("languagesystem"): + statements.append(self.parse_languagesystem_()) + elif self.is_cur_keyword_("lookup"): + statements.append(self.parse_lookup_(vertical=False)) + elif self.is_cur_keyword_("markClass"): + statements.append(self.parse_markClass_()) + elif self.is_cur_keyword_("feature"): + statements.append(self.parse_feature_block_()) + elif self.is_cur_keyword_("conditionset"): + statements.append(self.parse_conditionset_()) + elif self.is_cur_keyword_("variation"): + statements.append(self.parse_feature_block_(variation=True)) + elif self.is_cur_keyword_("table"): + statements.append(self.parse_table_()) + elif self.is_cur_keyword_("valueRecordDef"): + statements.append(self.parse_valuerecord_definition_(vertical=False)) + elif ( + self.cur_token_type_ is Lexer.NAME + and self.cur_token_ in self.extensions + ): + statements.append(self.extensions[self.cur_token_](self)) + elif self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected feature, languagesystem, lookup, markClass, " + 'table, or glyph class definition, got {} "{}"'.format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + # Report any missing glyphs at the end of parsing + if self.missing: + error = [ + " %s (first found at %s)" % (name, loc) + for name, loc in self.missing.items() + ] + raise FeatureLibError( + "The following glyph names are referenced but are missing from the " + "glyph set:\n" + ("\n".join(error)), + None, + ) + return self.doc_ + + def parse_anchor_(self): + # Parses an anchor in any of the four formats given in the feature + # file specification (2.e.vii). + self.expect_symbol_("<") + self.expect_keyword_("anchor") + location = self.cur_token_location_ + + if self.next_token_ == "NULL": # Format D + self.expect_keyword_("NULL") + self.expect_symbol_(">") + return None + + if self.next_token_type_ == Lexer.NAME: # Format E + name = self.expect_name_() + anchordef = self.anchors_.resolve(name) + if anchordef is None: + raise FeatureLibError( + 'Unknown anchor "%s"' % name, self.cur_token_location_ + ) + self.expect_symbol_(">") + return self.ast.Anchor( + anchordef.x, + anchordef.y, + name=name, + contourpoint=anchordef.contourpoint, + xDeviceTable=None, + yDeviceTable=None, + location=location, + ) + + x, y = self.expect_number_(variable=True), self.expect_number_(variable=True) + + contourpoint = None + if self.next_token_ == "contourpoint": # Format B + self.expect_keyword_("contourpoint") + contourpoint = self.expect_number_() + + if self.next_token_ == "<": # Format C + xDeviceTable = self.parse_device_() + yDeviceTable = self.parse_device_() + else: + xDeviceTable, yDeviceTable = None, None + + self.expect_symbol_(">") + return self.ast.Anchor( + x, + y, + name=None, + contourpoint=contourpoint, + xDeviceTable=xDeviceTable, + yDeviceTable=yDeviceTable, + location=location, + ) + + def parse_anchor_marks_(self): + # Parses a sequence of ``[ mark @MARKCLASS]*.`` + anchorMarks = [] # [(self.ast.Anchor, markClassName)*] + while self.next_token_ == "<": + anchor = self.parse_anchor_() + if anchor is None and self.next_token_ != "mark": + continue # without mark, eg. in GPOS type 5 + self.expect_keyword_("mark") + markClass = self.expect_markClass_reference_() + anchorMarks.append((anchor, markClass)) + return anchorMarks + + def parse_anchordef_(self): + # Parses a named anchor definition (`section 2.e.viii `_). + assert self.is_cur_keyword_("anchorDef") + location = self.cur_token_location_ + x, y = self.expect_number_(), self.expect_number_() + contourpoint = None + if self.next_token_ == "contourpoint": + self.expect_keyword_("contourpoint") + contourpoint = self.expect_number_() + name = self.expect_name_() + self.expect_symbol_(";") + anchordef = self.ast.AnchorDefinition( + name, x, y, contourpoint=contourpoint, location=location + ) + self.anchors_.define(name, anchordef) + return anchordef + + def parse_anonymous_(self): + # Parses an anonymous data block (`section 10 `_). + assert self.is_cur_keyword_(("anon", "anonymous")) + tag = self.expect_tag_() + _, content, location = self.lexer_.scan_anonymous_block(tag) + self.advance_lexer_() + self.expect_symbol_("}") + end_tag = self.expect_tag_() + assert tag == end_tag, "bad splitting in Lexer.scan_anonymous_block()" + self.expect_symbol_(";") + return self.ast.AnonymousBlock(tag, content, location=location) + + def parse_attach_(self): + # Parses a GDEF Attach statement (`section 9.b `_) + assert self.is_cur_keyword_("Attach") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + contourPoints = {self.expect_number_()} + while self.next_token_ != ";": + contourPoints.add(self.expect_number_()) + self.expect_symbol_(";") + return self.ast.AttachStatement(glyphs, contourPoints, location=location) + + def parse_enumerate_(self, vertical): + # Parse an enumerated pair positioning rule (`section 6.b.ii `_). + assert self.cur_token_ in {"enumerate", "enum"} + self.advance_lexer_() + return self.parse_position_(enumerated=True, vertical=vertical) + + def parse_GlyphClassDef_(self): + # Parses 'GlyphClassDef @BASE, @LIGATURES, @MARKS, @COMPONENTS;' + assert self.is_cur_keyword_("GlyphClassDef") + location = self.cur_token_location_ + if self.next_token_ != ",": + baseGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + baseGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ",": + ligatureGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + ligatureGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ",": + markGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + markGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ";": + componentGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + componentGlyphs = None + self.expect_symbol_(";") + return self.ast.GlyphClassDefStatement( + baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=location + ) + + def parse_glyphclass_definition_(self): + # Parses glyph class definitions such as '@UPPERCASE = [A-Z];' + location, name = self.cur_token_location_, self.cur_token_ + self.expect_symbol_("=") + glyphs = self.parse_glyphclass_(accept_glyphname=False) + self.expect_symbol_(";") + glyphclass = self.ast.GlyphClassDefinition(name, glyphs, location=location) + self.glyphclasses_.define(name, glyphclass) + return glyphclass + + def split_glyph_range_(self, name, location): + # Since v1.20, the OpenType Feature File specification allows + # for dashes in glyph names. A sequence like "a-b-c-d" could + # therefore mean a single glyph whose name happens to be + # "a-b-c-d", or it could mean a range from glyph "a" to glyph + # "b-c-d", or a range from glyph "a-b" to glyph "c-d", or a + # range from glyph "a-b-c" to glyph "d".Technically, this + # example could be resolved because the (pretty complex) + # definition of glyph ranges renders most of these splits + # invalid. But the specification does not say that a compiler + # should try to apply such fancy heuristics. To encourage + # unambiguous feature files, we therefore try all possible + # splits and reject the feature file if there are multiple + # splits possible. It is intentional that we don't just emit a + # warning; warnings tend to get ignored. To fix the problem, + # font designers can trivially add spaces around the intended + # split point, and we emit a compiler error that suggests + # how exactly the source should be rewritten to make things + # unambiguous. + parts = name.split("-") + solutions = [] + for i in range(len(parts)): + start, limit = "-".join(parts[0:i]), "-".join(parts[i:]) + if start in self.glyphNames_ and limit in self.glyphNames_: + solutions.append((start, limit)) + if len(solutions) == 1: + start, limit = solutions[0] + return start, limit + elif len(solutions) == 0: + raise FeatureLibError( + '"%s" is not a glyph in the font, and it can not be split ' + "into a range of known glyphs" % name, + location, + ) + else: + ranges = " or ".join(['"%s - %s"' % (s, l) for s, l in solutions]) + raise FeatureLibError( + 'Ambiguous glyph range "%s"; ' + "please use %s to clarify what you mean" % (name, ranges), + location, + ) + + def parse_glyphclass_(self, accept_glyphname, accept_null=False): + # Parses a glyph class, either named or anonymous, or (if + # ``bool(accept_glyphname)``) a glyph name. If ``bool(accept_null)`` then + # also accept the special NULL glyph. + if accept_glyphname and self.next_token_type_ in (Lexer.NAME, Lexer.CID): + if accept_null and self.next_token_ == "NULL": + # If you want a glyph called NULL, you should escape it. + self.advance_lexer_() + return self.ast.NullGlyph(location=self.cur_token_location_) + glyph = self.expect_glyph_() + self.check_glyph_name_in_glyph_set(glyph) + return self.ast.GlyphName(glyph, location=self.cur_token_location_) + if self.next_token_type_ is Lexer.GLYPHCLASS: + self.advance_lexer_() + gc = self.glyphclasses_.resolve(self.cur_token_) + if gc is None: + raise FeatureLibError( + "Unknown glyph class @%s" % self.cur_token_, + self.cur_token_location_, + ) + if isinstance(gc, self.ast.MarkClass): + return self.ast.MarkClassName(gc, location=self.cur_token_location_) + else: + return self.ast.GlyphClassName(gc, location=self.cur_token_location_) + + self.expect_symbol_("[") + location = self.cur_token_location_ + glyphs = self.ast.GlyphClass(location=location) + while self.next_token_ != "]": + if self.next_token_type_ is Lexer.NAME: + glyph = self.expect_glyph_() + location = self.cur_token_location_ + if "-" in glyph and self.glyphNames_ and glyph not in self.glyphNames_: + start, limit = self.split_glyph_range_(glyph, location) + self.check_glyph_name_in_glyph_set(start, limit) + glyphs.add_range( + start, limit, self.make_glyph_range_(location, start, limit) + ) + elif self.next_token_ == "-": + start = glyph + self.expect_symbol_("-") + limit = self.expect_glyph_() + self.check_glyph_name_in_glyph_set(start, limit) + glyphs.add_range( + start, limit, self.make_glyph_range_(location, start, limit) + ) + else: + if "-" in glyph and not self.glyphNames_: + log.warning( + str( + FeatureLibError( + f"Ambiguous glyph name that looks like a range: {glyph!r}", + location, + ) + ) + ) + self.check_glyph_name_in_glyph_set(glyph) + glyphs.append(glyph) + elif self.next_token_type_ is Lexer.CID: + glyph = self.expect_glyph_() + if self.next_token_ == "-": + range_location = self.cur_token_location_ + range_start = self.cur_token_ + self.expect_symbol_("-") + range_end = self.expect_cid_() + self.check_glyph_name_in_glyph_set( + f"cid{range_start:05d}", + f"cid{range_end:05d}", + ) + glyphs.add_cid_range( + range_start, + range_end, + self.make_cid_range_(range_location, range_start, range_end), + ) + else: + glyph_name = f"cid{self.cur_token_:05d}" + self.check_glyph_name_in_glyph_set(glyph_name) + glyphs.append(glyph_name) + elif self.next_token_type_ is Lexer.GLYPHCLASS: + self.advance_lexer_() + gc = self.glyphclasses_.resolve(self.cur_token_) + if gc is None: + raise FeatureLibError( + "Unknown glyph class @%s" % self.cur_token_, + self.cur_token_location_, + ) + if isinstance(gc, self.ast.MarkClass): + gc = self.ast.MarkClassName(gc, location=self.cur_token_location_) + else: + gc = self.ast.GlyphClassName(gc, location=self.cur_token_location_) + glyphs.add_class(gc) + else: + raise FeatureLibError( + "Expected glyph name, glyph range, " + f"or glyph class reference, found {self.next_token_!r}", + self.next_token_location_, + ) + self.expect_symbol_("]") + return glyphs + + def parse_glyph_pattern_(self, vertical): + # Parses a glyph pattern, including lookups and context, e.g.:: + # + # a b + # a b c' d e + # a b c' lookup ChangeC d e + prefix, glyphs, lookups, values, suffix = ([], [], [], [], []) + hasMarks = False + while self.next_token_ not in {"by", "from", ";", ","}: + gc = self.parse_glyphclass_(accept_glyphname=True) + marked = False + if self.next_token_ == "'": + self.expect_symbol_("'") + hasMarks = marked = True + if marked: + if suffix: + # makeotf also reports this as an error, while FontForge + # silently inserts ' in all the intervening glyphs. + # https://github.com/fonttools/fonttools/pull/1096 + raise FeatureLibError( + "Unsupported contextual target sequence: at most " + "one run of marked (') glyph/class names allowed", + self.cur_token_location_, + ) + glyphs.append(gc) + elif glyphs: + suffix.append(gc) + else: + prefix.append(gc) + + if self.is_next_value_(): + values.append(self.parse_valuerecord_(vertical)) + else: + values.append(None) + + lookuplist = None + while self.next_token_ == "lookup": + if lookuplist is None: + lookuplist = [] + self.expect_keyword_("lookup") + if not marked: + raise FeatureLibError( + "Lookups can only follow marked glyphs", + self.cur_token_location_, + ) + lookup_name = self.expect_name_() + lookup = self.lookups_.resolve(lookup_name) + if lookup is None: + raise FeatureLibError( + 'Unknown lookup "%s"' % lookup_name, self.cur_token_location_ + ) + lookuplist.append(lookup) + if marked: + lookups.append(lookuplist) + + if not glyphs and not suffix: # eg., "sub f f i by" + assert lookups == [] + return ([], prefix, [None] * len(prefix), values, [], hasMarks) + else: + if any(values[: len(prefix)]): + raise FeatureLibError( + "Positioning cannot be applied in the bactrack glyph sequence, " + "before the marked glyph sequence.", + self.cur_token_location_, + ) + marked_values = values[len(prefix) : len(prefix) + len(glyphs)] + if any(marked_values): + if any(values[len(prefix) + len(glyphs) :]): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + values = marked_values + elif values and values[-1]: + if len(glyphs) > 1 or any(values[:-1]): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + values = values[-1:] + elif any(values): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + return (prefix, glyphs, lookups, values, suffix, hasMarks) + + def parse_ignore_glyph_pattern_(self, sub): + location = self.cur_token_location_ + prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_( + vertical=False + ) + if any(lookups): + raise FeatureLibError( + f'No lookups can be specified for "ignore {sub}"', location + ) + if not hasMarks: + error = FeatureLibError( + f'Ambiguous "ignore {sub}", there should be least one marked glyph', + location, + ) + log.warning(str(error)) + suffix, glyphs = glyphs[1:], glyphs[0:1] + chainContext = (prefix, glyphs, suffix) + return chainContext + + def parse_ignore_context_(self, sub): + location = self.cur_token_location_ + chainContext = [self.parse_ignore_glyph_pattern_(sub)] + while self.next_token_ == ",": + self.expect_symbol_(",") + chainContext.append(self.parse_ignore_glyph_pattern_(sub)) + self.expect_symbol_(";") + return chainContext + + def parse_ignore_(self): + # Parses an ignore sub/pos rule. + assert self.is_cur_keyword_("ignore") + location = self.cur_token_location_ + self.advance_lexer_() + if self.cur_token_ in ["substitute", "sub"]: + chainContext = self.parse_ignore_context_("sub") + return self.ast.IgnoreSubstStatement(chainContext, location=location) + if self.cur_token_ in ["position", "pos"]: + chainContext = self.parse_ignore_context_("pos") + return self.ast.IgnorePosStatement(chainContext, location=location) + raise FeatureLibError( + 'Expected "substitute" or "position"', self.cur_token_location_ + ) + + def parse_include_(self): + assert self.cur_token_ == "include" + location = self.cur_token_location_ + filename = self.expect_filename_() + # self.expect_symbol_(";") + return ast.IncludeStatement(filename, location=location) + + def parse_language_(self): + assert self.is_cur_keyword_("language") + location = self.cur_token_location_ + language = self.expect_language_tag_() + include_default, required = (True, False) + if self.next_token_ in {"exclude_dflt", "include_dflt"}: + include_default = self.expect_name_() == "include_dflt" + if self.next_token_ == "required": + self.expect_keyword_("required") + required = True + self.expect_symbol_(";") + return self.ast.LanguageStatement( + language, include_default, required, location=location + ) + + def parse_ligatureCaretByIndex_(self): + assert self.is_cur_keyword_("LigatureCaretByIndex") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + carets = [self.expect_number_()] + while self.next_token_ != ";": + carets.append(self.expect_number_()) + self.expect_symbol_(";") + return self.ast.LigatureCaretByIndexStatement(glyphs, carets, location=location) + + def parse_ligatureCaretByPos_(self): + assert self.is_cur_keyword_("LigatureCaretByPos") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + carets = [self.expect_number_(variable=True)] + while self.next_token_ != ";": + carets.append(self.expect_number_(variable=True)) + self.expect_symbol_(";") + return self.ast.LigatureCaretByPosStatement(glyphs, carets, location=location) + + def parse_lookup_(self, vertical): + # Parses a ``lookup`` - either a lookup block, or a lookup reference + # inside a feature. + assert self.is_cur_keyword_("lookup") + location, name = self.cur_token_location_, self.expect_name_() + + if self.next_token_ == ";": + lookup = self.lookups_.resolve(name) + if lookup is None: + raise FeatureLibError( + 'Unknown lookup "%s"' % name, self.cur_token_location_ + ) + self.expect_symbol_(";") + return self.ast.LookupReferenceStatement(lookup, location=location) + + use_extension = False + if self.next_token_ == "useExtension": + self.expect_keyword_("useExtension") + use_extension = True + + block = self.ast.LookupBlock(name, use_extension, location=location) + self.parse_block_(block, vertical) + self.lookups_.define(name, block) + return block + + def parse_lookupflag_(self): + # Parses a ``lookupflag`` statement, either specified by number or + # in words. + assert self.is_cur_keyword_("lookupflag") + location = self.cur_token_location_ + + # format B: "lookupflag 6;" + if self.next_token_type_ == Lexer.NUMBER: + value = self.expect_number_() + self.expect_symbol_(";") + return self.ast.LookupFlagStatement(value, location=location) + + # format A: "lookupflag RightToLeft MarkAttachmentType @M;" + value_seen = False + value, markAttachment, markFilteringSet = 0, None, None + flags = { + "RightToLeft": 1, + "IgnoreBaseGlyphs": 2, + "IgnoreLigatures": 4, + "IgnoreMarks": 8, + } + seen = set() + while self.next_token_ != ";": + if self.next_token_ in seen: + raise FeatureLibError( + "%s can be specified only once" % self.next_token_, + self.next_token_location_, + ) + seen.add(self.next_token_) + if self.next_token_ == "MarkAttachmentType": + self.expect_keyword_("MarkAttachmentType") + markAttachment = self.parse_glyphclass_(accept_glyphname=False) + elif self.next_token_ == "UseMarkFilteringSet": + self.expect_keyword_("UseMarkFilteringSet") + markFilteringSet = self.parse_glyphclass_(accept_glyphname=False) + elif self.next_token_ in flags: + value_seen = True + value = value | flags[self.expect_name_()] + else: + raise FeatureLibError( + '"%s" is not a recognized lookupflag' % self.next_token_, + self.next_token_location_, + ) + self.expect_symbol_(";") + + if not any([value_seen, markAttachment, markFilteringSet]): + raise FeatureLibError( + "lookupflag must have a value", self.next_token_location_ + ) + + return self.ast.LookupFlagStatement( + value, + markAttachment=markAttachment, + markFilteringSet=markFilteringSet, + location=location, + ) + + def parse_markClass_(self): + assert self.is_cur_keyword_("markClass") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + if not glyphs.glyphSet(): + raise FeatureLibError( + "Empty glyph class in mark class definition", location + ) + anchor = self.parse_anchor_() + name = self.expect_class_name_() + self.expect_symbol_(";") + markClass = self.doc_.markClasses.get(name) + if markClass is None: + markClass = self.ast.MarkClass(name) + self.doc_.markClasses[name] = markClass + self.glyphclasses_.define(name, markClass) + mcdef = self.ast.MarkClassDefinition( + markClass, anchor, glyphs, location=location + ) + markClass.addDefinition(mcdef) + return mcdef + + def parse_position_(self, enumerated, vertical): + assert self.cur_token_ in {"position", "pos"} + if self.next_token_ == "cursive": # GPOS type 3 + return self.parse_position_cursive_(enumerated, vertical) + elif self.next_token_ == "base": # GPOS type 4 + return self.parse_position_base_(enumerated, vertical) + elif self.next_token_ == "ligature": # GPOS type 5 + return self.parse_position_ligature_(enumerated, vertical) + elif self.next_token_ == "mark": # GPOS type 6 + return self.parse_position_mark_(enumerated, vertical) + + location = self.cur_token_location_ + prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_( + vertical + ) + self.expect_symbol_(";") + + if any(lookups): + # GPOS type 8: Chaining contextual positioning; explicit lookups + if any(values): + raise FeatureLibError( + 'If "lookup" is present, no values must be specified', location + ) + return self.ast.ChainContextPosStatement( + prefix, glyphs, suffix, lookups, location=location + ) + + # Pair positioning, format A: "pos V 10 A -10;" + # Pair positioning, format B: "pos V A -20;" + if not prefix and not suffix and len(glyphs) == 2 and not hasMarks: + if values[0] is None: # Format B: "pos V A -20;" + values.reverse() + return self.ast.PairPosStatement( + glyphs[0], + values[0], + glyphs[1], + values[1], + enumerated=enumerated, + location=location, + ) + + if enumerated: + raise FeatureLibError( + '"enumerate" is only allowed with pair positionings', location + ) + return self.ast.SinglePosStatement( + list(zip(glyphs, values)), + prefix, + suffix, + forceChain=hasMarks, + location=location, + ) + + def parse_position_cursive_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("cursive") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' "cursive attachment positioning", + location, + ) + glyphclass = self.parse_glyphclass_(accept_glyphname=True) + entryAnchor = self.parse_anchor_() + exitAnchor = self.parse_anchor_() + self.expect_symbol_(";") + return self.ast.CursivePosStatement( + glyphclass, entryAnchor, exitAnchor, location=location + ) + + def parse_position_base_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("base") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-base attachment positioning", + location, + ) + base = self.parse_glyphclass_(accept_glyphname=True) + marks = self.parse_anchor_marks_() + self.expect_symbol_(";") + return self.ast.MarkBasePosStatement(base, marks, location=location) + + def parse_position_ligature_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("ligature") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-ligature attachment positioning", + location, + ) + ligatures = self.parse_glyphclass_(accept_glyphname=True) + marks = [self.parse_anchor_marks_()] + while self.next_token_ == "ligComponent": + self.expect_keyword_("ligComponent") + marks.append(self.parse_anchor_marks_()) + self.expect_symbol_(";") + return self.ast.MarkLigPosStatement(ligatures, marks, location=location) + + def parse_position_mark_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("mark") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-mark attachment positioning", + location, + ) + baseMarks = self.parse_glyphclass_(accept_glyphname=True) + marks = self.parse_anchor_marks_() + self.expect_symbol_(";") + return self.ast.MarkMarkPosStatement(baseMarks, marks, location=location) + + def parse_script_(self): + assert self.is_cur_keyword_("script") + location, script = self.cur_token_location_, self.expect_script_tag_() + self.expect_symbol_(";") + return self.ast.ScriptStatement(script, location=location) + + def parse_substitute_(self): + assert self.cur_token_ in {"substitute", "sub", "reversesub", "rsub"} + location = self.cur_token_location_ + reverse = self.cur_token_ in {"reversesub", "rsub"} + ( + old_prefix, + old, + lookups, + values, + old_suffix, + hasMarks, + ) = self.parse_glyph_pattern_(vertical=False) + if any(values): + raise FeatureLibError( + "Substitution statements cannot contain values", location + ) + new = [] + if self.next_token_ == "by": + keyword = self.expect_keyword_("by") + while self.next_token_ != ";": + gc = self.parse_glyphclass_(accept_glyphname=True, accept_null=True) + new.append(gc) + elif self.next_token_ == "from": + keyword = self.expect_keyword_("from") + new = [self.parse_glyphclass_(accept_glyphname=False)] + else: + keyword = None + self.expect_symbol_(";") + if len(new) == 0 and not any(lookups): + raise FeatureLibError( + 'Expected "by", "from" or explicit lookup references', + self.cur_token_location_, + ) + + # GSUB lookup type 3: Alternate substitution. + # Format: "substitute a from [a.1 a.2 a.3];" + if keyword == "from": + if reverse: + raise FeatureLibError( + 'Reverse chaining substitutions do not support "from"', location + ) + if len(old) != 1 or len(old[0].glyphSet()) != 1: + raise FeatureLibError('Expected a single glyph before "from"', location) + if len(new) != 1: + raise FeatureLibError( + 'Expected a single glyphclass after "from"', location + ) + return self.ast.AlternateSubstStatement( + old_prefix, old[0], old_suffix, new[0], location=location + ) + + num_lookups = len([l for l in lookups if l is not None]) + + is_deletion = False + if len(new) == 1 and isinstance(new[0], ast.NullGlyph): + new = [] # Deletion + is_deletion = True + + # GSUB lookup type 1: Single substitution. + # Format A: "substitute a by a.sc;" + # Format B: "substitute [one.fitted one.oldstyle] by one;" + # Format C: "substitute [a-d] by [A.sc-D.sc];" + if not reverse and len(old) == 1 and len(new) == 1 and num_lookups == 0: + glyphs = list(old[0].glyphSet()) + replacements = list(new[0].glyphSet()) + if len(replacements) == 1: + replacements = replacements * len(glyphs) + if len(glyphs) != len(replacements): + raise FeatureLibError( + 'Expected a glyph class with %d elements after "by", ' + "but found a glyph class with %d elements" + % (len(glyphs), len(replacements)), + location, + ) + return self.ast.SingleSubstStatement( + old, new, old_prefix, old_suffix, forceChain=hasMarks, location=location + ) + + # Glyph deletion, built as GSUB lookup type 2: Multiple substitution + # with empty replacement. + if is_deletion and len(old) == 1 and num_lookups == 0: + return self.ast.MultipleSubstStatement( + old_prefix, + old[0], + old_suffix, + (), + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 2: Multiple substitution. + # Format: "substitute f_f_i by f f i;" + # + # GlyphsApp introduces two additional formats: + # Format 1: "substitute [f_i f_l] by [f f] [i l];" + # Format 2: "substitute [f_i f_l] by f [i l];" + # http://handbook.glyphsapp.com/en/layout/multiple-substitution-with-classes/ + if not reverse and len(old) == 1 and len(new) > 1 and num_lookups == 0: + count = len(old[0].glyphSet()) + for n in new: + if not list(n.glyphSet()): + raise FeatureLibError("Empty class in replacement", location) + if len(n.glyphSet()) != 1 and len(n.glyphSet()) != count: + raise FeatureLibError( + f'Expected a glyph class with 1 or {count} elements after "by", ' + f"but found a glyph class with {len(n.glyphSet())} elements", + location, + ) + return self.ast.MultipleSubstStatement( + old_prefix, + old[0], + old_suffix, + new, + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 4: Ligature substitution. + # Format: "substitute f f i by f_f_i;" + if ( + not reverse + and len(old) > 1 + and len(new) == 1 + and len(new[0].glyphSet()) == 1 + and num_lookups == 0 + ): + return self.ast.LigatureSubstStatement( + old_prefix, + old, + old_suffix, + list(new[0].glyphSet())[0], + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 8: Reverse chaining substitution. + if reverse: + if len(old) != 1: + raise FeatureLibError( + "In reverse chaining single substitutions, " + "only a single glyph or glyph class can be replaced", + location, + ) + if len(new) != 1: + raise FeatureLibError( + "In reverse chaining single substitutions, " + 'the replacement (after "by") must be a single glyph ' + "or glyph class", + location, + ) + if num_lookups != 0: + raise FeatureLibError( + "Reverse chaining substitutions cannot call named lookups", location + ) + glyphs = sorted(list(old[0].glyphSet())) + replacements = sorted(list(new[0].glyphSet())) + if len(replacements) == 1: + replacements = replacements * len(glyphs) + if len(glyphs) != len(replacements): + raise FeatureLibError( + 'Expected a glyph class with %d elements after "by", ' + "but found a glyph class with %d elements" + % (len(glyphs), len(replacements)), + location, + ) + return self.ast.ReverseChainSingleSubstStatement( + old_prefix, old_suffix, old, new, location=location + ) + + if len(old) > 1 and len(new) > 1: + raise FeatureLibError( + "Direct substitution of multiple glyphs by multiple glyphs " + "is not supported", + location, + ) + + # If there are remaining glyphs to parse, this is an invalid GSUB statement + if len(new) != 0 or is_deletion: + raise FeatureLibError("Invalid substitution statement", location) + + # GSUB lookup type 6: Chaining contextual substitution. + rule = self.ast.ChainContextSubstStatement( + old_prefix, old, old_suffix, lookups, location=location + ) + return rule + + def parse_subtable_(self): + assert self.is_cur_keyword_("subtable") + location = self.cur_token_location_ + self.expect_symbol_(";") + return self.ast.SubtableStatement(location=location) + + def parse_size_parameters_(self): + # Parses a ``parameters`` statement used in ``size`` features. See + # `section 8.b `_. + assert self.is_cur_keyword_("parameters") + location = self.cur_token_location_ + DesignSize = self.expect_decipoint_() + SubfamilyID = self.expect_number_() + RangeStart = 0.0 + RangeEnd = 0.0 + if self.next_token_type_ in (Lexer.NUMBER, Lexer.FLOAT) or SubfamilyID != 0: + RangeStart = self.expect_decipoint_() + RangeEnd = self.expect_decipoint_() + + self.expect_symbol_(";") + return self.ast.SizeParameters( + DesignSize, SubfamilyID, RangeStart, RangeEnd, location=location + ) + + def parse_size_menuname_(self): + assert self.is_cur_keyword_("sizemenuname") + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + return self.ast.FeatureNameStatement( + "size", platformID, platEncID, langID, string, location=location + ) + + def parse_table_(self): + assert self.is_cur_keyword_("table") + location, name = self.cur_token_location_, self.expect_tag_() + table = self.ast.TableBlock(name, location=location) + self.expect_symbol_("{") + handler = { + "GDEF": self.parse_table_GDEF_, + "head": self.parse_table_head_, + "hhea": self.parse_table_hhea_, + "vhea": self.parse_table_vhea_, + "name": self.parse_table_name_, + "BASE": self.parse_table_BASE_, + "OS/2": self.parse_table_OS_2_, + "STAT": self.parse_table_STAT_, + }.get(name) + if handler: + handler(table) + else: + raise FeatureLibError( + '"table %s" is not supported' % name.strip(), location + ) + self.expect_symbol_("}") + end_tag = self.expect_tag_() + if end_tag != name: + raise FeatureLibError( + 'Expected "%s"' % name.strip(), self.cur_token_location_ + ) + self.expect_symbol_(";") + return table + + def parse_table_GDEF_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("Attach"): + statements.append(self.parse_attach_()) + elif self.is_cur_keyword_("GlyphClassDef"): + statements.append(self.parse_GlyphClassDef_()) + elif self.is_cur_keyword_("LigatureCaretByIndex"): + statements.append(self.parse_ligatureCaretByIndex_()) + elif self.is_cur_keyword_("LigatureCaretByPos"): + statements.append(self.parse_ligatureCaretByPos_()) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected Attach, LigatureCaretByIndex, " "or LigatureCaretByPos", + self.cur_token_location_, + ) + + def parse_table_head_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("FontRevision"): + statements.append(self.parse_FontRevision_()) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError("Expected FontRevision", self.cur_token_location_) + + def parse_table_hhea_(self, table): + statements = table.statements + fields = ("CaretOffset", "Ascender", "Descender", "LineGap") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields: + key = self.cur_token_.lower() + value = self.expect_number_() + statements.append( + self.ast.HheaField(key, value, location=self.cur_token_location_) + ) + if self.next_token_ != ";": + raise FeatureLibError( + "Incomplete statement", self.next_token_location_ + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected CaretOffset, Ascender, " "Descender or LineGap", + self.cur_token_location_, + ) + + def parse_table_vhea_(self, table): + statements = table.statements + fields = ("VertTypoAscender", "VertTypoDescender", "VertTypoLineGap") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields: + key = self.cur_token_.lower() + value = self.expect_number_() + statements.append( + self.ast.VheaField(key, value, location=self.cur_token_location_) + ) + if self.next_token_ != ";": + raise FeatureLibError( + "Incomplete statement", self.next_token_location_ + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected VertTypoAscender, " + "VertTypoDescender or VertTypoLineGap", + self.cur_token_location_, + ) + + def parse_table_name_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("nameid"): + statement = self.parse_nameid_() + if statement: + statements.append(statement) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError("Expected nameid", self.cur_token_location_) + + def parse_name_(self): + """Parses a name record. See `section 9.e `_.""" + platEncID = None + langID = None + if self.next_token_type_ in Lexer.NUMBERS: + platformID = self.expect_any_number_() + location = self.cur_token_location_ + if platformID not in (1, 3): + raise FeatureLibError("Expected platform id 1 or 3", location) + if self.next_token_type_ in Lexer.NUMBERS: + platEncID = self.expect_any_number_() + langID = self.expect_any_number_() + else: + platformID = 3 + location = self.cur_token_location_ + + if platformID == 1: # Macintosh + platEncID = platEncID or 0 # Roman + langID = langID or 0 # English + else: # 3, Windows + platEncID = platEncID or 1 # Unicode + langID = langID or 0x0409 # English + + string = self.expect_string_() + self.expect_symbol_(";") + + encoding = getEncoding(platformID, platEncID, langID) + if encoding is None: + raise FeatureLibError("Unsupported encoding", location) + unescaped = self.unescape_string_(string, encoding) + return platformID, platEncID, langID, unescaped + + def parse_stat_name_(self): + platEncID = None + langID = None + if self.next_token_type_ in Lexer.NUMBERS: + platformID = self.expect_any_number_() + location = self.cur_token_location_ + if platformID not in (1, 3): + raise FeatureLibError("Expected platform id 1 or 3", location) + if self.next_token_type_ in Lexer.NUMBERS: + platEncID = self.expect_any_number_() + langID = self.expect_any_number_() + else: + platformID = 3 + location = self.cur_token_location_ + + if platformID == 1: # Macintosh + platEncID = platEncID or 0 # Roman + langID = langID or 0 # English + else: # 3, Windows + platEncID = platEncID or 1 # Unicode + langID = langID or 0x0409 # English + + string = self.expect_string_() + encoding = getEncoding(platformID, platEncID, langID) + if encoding is None: + raise FeatureLibError("Unsupported encoding", location) + unescaped = self.unescape_string_(string, encoding) + return platformID, platEncID, langID, unescaped + + def parse_nameid_(self): + assert self.cur_token_ == "nameid", self.cur_token_ + location, nameID = self.cur_token_location_, self.expect_any_number_() + if nameID > 32767: + raise FeatureLibError( + "Name id value cannot be greater than 32767", self.cur_token_location_ + ) + platformID, platEncID, langID, string = self.parse_name_() + return self.ast.NameRecord( + nameID, platformID, platEncID, langID, string, location=location + ) + + def unescape_string_(self, string, encoding): + if encoding == "utf_16_be": + s = re.sub(r"\\[0-9a-fA-F]{4}", self.unescape_unichr_, string) + else: + unescape = lambda m: self.unescape_byte_(m, encoding) + s = re.sub(r"\\[0-9a-fA-F]{2}", unescape, string) + # We now have a Unicode string, but it might contain surrogate pairs. + # We convert surrogates to actual Unicode by round-tripping through + # Python's UTF-16 codec in a special mode. + utf16 = tobytes(s, "utf_16_be", "surrogatepass") + return tostr(utf16, "utf_16_be") + + @staticmethod + def unescape_unichr_(match): + n = match.group(0)[1:] + return chr(int(n, 16)) + + @staticmethod + def unescape_byte_(match, encoding): + n = match.group(0)[1:] + return bytechr(int(n, 16)).decode(encoding) + + def parse_table_BASE_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("HorizAxis.BaseTagList"): + horiz_bases = self.parse_base_tag_list_() + elif self.is_cur_keyword_("HorizAxis.BaseScriptList"): + horiz_scripts = self.parse_base_script_list_(len(horiz_bases)) + statements.append( + self.ast.BaseAxis( + horiz_bases, + horiz_scripts, + False, + location=self.cur_token_location_, + ) + ) + elif self.is_cur_keyword_("VertAxis.BaseTagList"): + vert_bases = self.parse_base_tag_list_() + elif self.is_cur_keyword_("VertAxis.BaseScriptList"): + vert_scripts = self.parse_base_script_list_(len(vert_bases)) + statements.append( + self.ast.BaseAxis( + vert_bases, + vert_scripts, + True, + location=self.cur_token_location_, + ) + ) + elif self.cur_token_ == ";": + continue + + def parse_table_OS_2_(self, table): + statements = table.statements + numbers = ( + "FSType", + "TypoAscender", + "TypoDescender", + "TypoLineGap", + "winAscent", + "winDescent", + "XHeight", + "CapHeight", + "WeightClass", + "WidthClass", + "LowerOpSize", + "UpperOpSize", + ) + ranges = ("UnicodeRange", "CodePageRange") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME: + key = self.cur_token_.lower() + value = None + if self.cur_token_ in numbers: + value = self.expect_number_() + elif self.is_cur_keyword_("Panose"): + value = [] + for i in range(10): + value.append(self.expect_number_()) + elif self.cur_token_ in ranges: + value = [] + while self.next_token_ != ";": + value.append(self.expect_number_()) + elif self.is_cur_keyword_("Vendor"): + value = self.expect_string_() + statements.append( + self.ast.OS2Field(key, value, location=self.cur_token_location_) + ) + elif self.cur_token_ == ";": + continue + + def parse_STAT_ElidedFallbackName(self): + assert self.is_cur_keyword_("ElidedFallbackName") + self.expect_symbol_("{") + names = [] + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_() + if self.is_cur_keyword_("name"): + platformID, platEncID, langID, string = self.parse_stat_name_() + nameRecord = self.ast.STATNameStatement( + "stat", + platformID, + platEncID, + langID, + string, + location=self.cur_token_location_, + ) + names.append(nameRecord) + else: + if self.cur_token_ != ";": + raise FeatureLibError( + f"Unexpected token {self.cur_token_} " f"in ElidedFallbackName", + self.cur_token_location_, + ) + self.expect_symbol_("}") + if not names: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + return names + + def parse_STAT_design_axis(self): + assert self.is_cur_keyword_("DesignAxis") + names = [] + axisTag = self.expect_tag_() + if ( + axisTag not in ("ital", "opsz", "slnt", "wdth", "wght") + and not axisTag.isupper() + ): + log.warning(f"Unregistered axis tag {axisTag} should be uppercase.") + axisOrder = self.expect_number_() + self.expect_symbol_("{") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_() + if self.cur_token_type_ is Lexer.COMMENT: + continue + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_stat_name_() + name = self.ast.STATNameStatement( + "stat", platformID, platEncID, langID, string, location=location + ) + names.append(name) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + f'Expected "name", got {self.cur_token_}', self.cur_token_location_ + ) + + self.expect_symbol_("}") + return self.ast.STATDesignAxisStatement( + axisTag, axisOrder, names, self.cur_token_location_ + ) + + def parse_STAT_axis_value_(self): + assert self.is_cur_keyword_("AxisValue") + self.expect_symbol_("{") + locations = [] + names = [] + flags = 0 + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + continue + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_stat_name_() + name = self.ast.STATNameStatement( + "stat", platformID, platEncID, langID, string, location=location + ) + names.append(name) + elif self.is_cur_keyword_("location"): + location = self.parse_STAT_location() + locations.append(location) + elif self.is_cur_keyword_("flag"): + flags = self.expect_stat_flags() + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + f"Unexpected token {self.cur_token_} " f"in AxisValue", + self.cur_token_location_, + ) + self.expect_symbol_("}") + if not names: + raise FeatureLibError('Expected "Axis Name"', self.cur_token_location_) + if not locations: + raise FeatureLibError('Expected "Axis location"', self.cur_token_location_) + if len(locations) > 1: + for location in locations: + if len(location.values) > 1: + raise FeatureLibError( + "Only one value is allowed in a " + "Format 4 Axis Value Record, but " + f"{len(location.values)} were found.", + self.cur_token_location_, + ) + format4_tags = [] + for location in locations: + tag = location.tag + if tag in format4_tags: + raise FeatureLibError( + f"Axis tag {tag} already " "defined.", self.cur_token_location_ + ) + format4_tags.append(tag) + + return self.ast.STATAxisValueStatement( + names, locations, flags, self.cur_token_location_ + ) + + def parse_STAT_location(self): + values = [] + tag = self.expect_tag_() + if len(tag.strip()) != 4: + raise FeatureLibError( + f"Axis tag {self.cur_token_} must be 4 " "characters", + self.cur_token_location_, + ) + + while self.next_token_ != ";": + if self.next_token_type_ is Lexer.FLOAT: + value = self.expect_float_() + values.append(value) + elif self.next_token_type_ is Lexer.NUMBER: + value = self.expect_number_() + values.append(value) + else: + raise FeatureLibError( + f'Unexpected value "{self.next_token_}". ' + "Expected integer or float.", + self.next_token_location_, + ) + if len(values) == 3: + nominal, min_val, max_val = values + if nominal < min_val or nominal > max_val: + raise FeatureLibError( + f"Default value {nominal} is outside " + f"of specified range " + f"{min_val}-{max_val}.", + self.next_token_location_, + ) + return self.ast.AxisValueLocationStatement(tag, values) + + def parse_table_STAT_(self, table): + statements = table.statements + design_axes = [] + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME: + if self.is_cur_keyword_("ElidedFallbackName"): + names = self.parse_STAT_ElidedFallbackName() + statements.append(self.ast.ElidedFallbackName(names)) + elif self.is_cur_keyword_("ElidedFallbackNameID"): + value = self.expect_number_() + statements.append(self.ast.ElidedFallbackNameID(value)) + self.expect_symbol_(";") + elif self.is_cur_keyword_("DesignAxis"): + designAxis = self.parse_STAT_design_axis() + design_axes.append(designAxis.tag) + statements.append(designAxis) + self.expect_symbol_(";") + elif self.is_cur_keyword_("AxisValue"): + axisValueRecord = self.parse_STAT_axis_value_() + for location in axisValueRecord.locations: + if location.tag not in design_axes: + # Tag must be defined in a DesignAxis before it + # can be referenced + raise FeatureLibError( + "DesignAxis not defined for " f"{location.tag}.", + self.cur_token_location_, + ) + statements.append(axisValueRecord) + self.expect_symbol_(";") + else: + raise FeatureLibError( + f"Unexpected token {self.cur_token_}", self.cur_token_location_ + ) + elif self.cur_token_ == ";": + continue + + def parse_base_tag_list_(self): + # Parses BASE table entries. (See `section 9.a `_) + assert self.cur_token_ in ( + "HorizAxis.BaseTagList", + "VertAxis.BaseTagList", + ), self.cur_token_ + bases = [] + while self.next_token_ != ";": + bases.append(self.expect_script_tag_()) + self.expect_symbol_(";") + return bases + + def parse_base_script_list_(self, count): + assert self.cur_token_ in ( + "HorizAxis.BaseScriptList", + "VertAxis.BaseScriptList", + ), self.cur_token_ + scripts = [(self.parse_base_script_record_(count))] + while self.next_token_ == ",": + self.expect_symbol_(",") + scripts.append(self.parse_base_script_record_(count)) + self.expect_symbol_(";") + return scripts + + def parse_base_script_record_(self, count): + script_tag = self.expect_script_tag_() + base_tag = self.expect_script_tag_() + coords = [self.expect_number_() for i in range(count)] + return script_tag, base_tag, coords + + def parse_device_(self): + result = None + self.expect_symbol_("<") + self.expect_keyword_("device") + if self.next_token_ == "NULL": + self.expect_keyword_("NULL") + else: + result = [(self.expect_number_(), self.expect_number_())] + while self.next_token_ == ",": + self.expect_symbol_(",") + result.append((self.expect_number_(), self.expect_number_())) + result = tuple(result) # make it hashable + self.expect_symbol_(">") + return result + + def is_next_value_(self): + return ( + self.next_token_type_ is Lexer.NUMBER + or self.next_token_ == "<" + or self.next_token_ == "(" + ) + + def parse_valuerecord_(self, vertical): + if ( + self.next_token_type_ is Lexer.SYMBOL and self.next_token_ == "(" + ) or self.next_token_type_ is Lexer.NUMBER: + number, location = ( + self.expect_number_(variable=True), + self.cur_token_location_, + ) + if vertical: + val = self.ast.ValueRecord( + yAdvance=number, vertical=vertical, location=location + ) + else: + val = self.ast.ValueRecord( + xAdvance=number, vertical=vertical, location=location + ) + return val + self.expect_symbol_("<") + location = self.cur_token_location_ + if self.next_token_type_ is Lexer.NAME: + name = self.expect_name_() + if name == "NULL": + self.expect_symbol_(">") + return self.ast.ValueRecord() + vrd = self.valuerecords_.resolve(name) + if vrd is None: + raise FeatureLibError( + 'Unknown valueRecordDef "%s"' % name, self.cur_token_location_ + ) + value = vrd.value + xPlacement, yPlacement = (value.xPlacement, value.yPlacement) + xAdvance, yAdvance = (value.xAdvance, value.yAdvance) + else: + xPlacement, yPlacement, xAdvance, yAdvance = ( + self.expect_number_(variable=True), + self.expect_number_(variable=True), + self.expect_number_(variable=True), + self.expect_number_(variable=True), + ) + + if self.next_token_ == "<": + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = ( + self.parse_device_(), + self.parse_device_(), + self.parse_device_(), + self.parse_device_(), + ) + allDeltas = sorted( + [ + delta + for size, delta in (xPlaDevice if xPlaDevice else ()) + + (yPlaDevice if yPlaDevice else ()) + + (xAdvDevice if xAdvDevice else ()) + + (yAdvDevice if yAdvDevice else ()) + ] + ) + if allDeltas[0] < -128 or allDeltas[-1] > 127: + raise FeatureLibError( + "Device value out of valid range (-128..127)", + self.cur_token_location_, + ) + else: + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (None, None, None, None) + + self.expect_symbol_(">") + return self.ast.ValueRecord( + xPlacement, + yPlacement, + xAdvance, + yAdvance, + xPlaDevice, + yPlaDevice, + xAdvDevice, + yAdvDevice, + vertical=vertical, + location=location, + ) + + def parse_valuerecord_definition_(self, vertical): + # Parses a named value record definition. (See section `2.e.v `_) + assert self.is_cur_keyword_("valueRecordDef") + location = self.cur_token_location_ + value = self.parse_valuerecord_(vertical) + name = self.expect_name_() + self.expect_symbol_(";") + vrd = self.ast.ValueRecordDefinition(name, value, location=location) + self.valuerecords_.define(name, vrd) + return vrd + + def parse_languagesystem_(self): + assert self.cur_token_ == "languagesystem" + location = self.cur_token_location_ + script = self.expect_script_tag_() + language = self.expect_language_tag_() + self.expect_symbol_(";") + return self.ast.LanguageSystemStatement(script, language, location=location) + + def parse_feature_block_(self, variation=False): + if variation: + assert self.cur_token_ == "variation" + else: + assert self.cur_token_ == "feature" + location = self.cur_token_location_ + tag = self.expect_tag_() + vertical = tag in {"vkrn", "vpal", "vhal", "valt"} + + stylisticset = None + cv_feature = None + size_feature = False + if tag in self.SS_FEATURE_TAGS: + stylisticset = tag + elif tag in self.CV_FEATURE_TAGS: + cv_feature = tag + elif tag == "size": + size_feature = True + + if variation: + conditionset = self.expect_name_() + + use_extension = False + if self.next_token_ == "useExtension": + self.expect_keyword_("useExtension") + use_extension = True + + if variation: + block = self.ast.VariationBlock( + tag, conditionset, use_extension=use_extension, location=location + ) + else: + block = self.ast.FeatureBlock( + tag, use_extension=use_extension, location=location + ) + self.parse_block_(block, vertical, stylisticset, size_feature, cv_feature) + return block + + def parse_feature_reference_(self): + assert self.cur_token_ == "feature", self.cur_token_ + location = self.cur_token_location_ + featureName = self.expect_tag_() + self.expect_symbol_(";") + return self.ast.FeatureReferenceStatement(featureName, location=location) + + def parse_featureNames_(self, tag): + """Parses a ``featureNames`` statement found in stylistic set features. + See section `8.c `_. + """ + assert self.cur_token_ == "featureNames", self.cur_token_ + block = self.ast.NestedBlock( + tag, self.cur_token_, location=self.cur_token_location_ + ) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + block.statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + block.statements.append( + self.ast.FeatureNameStatement( + tag, platformID, platEncID, langID, string, location=location + ) + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvParameters_(self, tag): + # Parses a ``cvParameters`` block found in Character Variant features. + # See section `8.d `_. + assert self.cur_token_ == "cvParameters", self.cur_token_ + block = self.ast.NestedBlock( + tag, self.cur_token_, location=self.cur_token_location_ + ) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + + statements = block.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_( + { + "FeatUILabelNameID", + "FeatUITooltipTextNameID", + "SampleTextNameID", + "ParamUILabelNameID", + } + ): + statements.append(self.parse_cvNameIDs_(tag, self.cur_token_)) + elif self.is_cur_keyword_("Character"): + statements.append(self.parse_cvCharacter_(tag)) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected statement: got {} {}".format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvNameIDs_(self, tag, block_name): + assert self.cur_token_ == block_name, self.cur_token_ + block = self.ast.NestedBlock(tag, block_name, location=self.cur_token_location_) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + block.statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + block.statements.append( + self.ast.CVParametersNameStatement( + tag, + platformID, + platEncID, + langID, + string, + block_name, + location=location, + ) + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvCharacter_(self, tag): + assert self.cur_token_ == "Character", self.cur_token_ + location, character = self.cur_token_location_, self.expect_any_number_() + self.expect_symbol_(";") + if not (0xFFFFFF >= character >= 0): + raise FeatureLibError( + "Character value must be between " + "{:#x} and {:#x}".format(0, 0xFFFFFF), + location, + ) + return self.ast.CharacterStatement(character, tag, location=location) + + def parse_FontRevision_(self): + # Parses a ``FontRevision`` statement found in the head table. See + # `section 9.c `_. + assert self.cur_token_ == "FontRevision", self.cur_token_ + location, version = self.cur_token_location_, self.expect_float_() + self.expect_symbol_(";") + if version <= 0: + raise FeatureLibError("Font revision numbers must be positive", location) + return self.ast.FontRevisionStatement(version, location=location) + + def parse_conditionset_(self): + name = self.expect_name_() + + conditions = {} + self.expect_symbol_("{") + + while self.next_token_ != "}": + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected an axis name", self.cur_token_location_) + + axis = self.cur_token_ + if axis in conditions: + raise FeatureLibError( + f"Repeated condition for axis {axis}", self.cur_token_location_ + ) + + if self.next_token_type_ is Lexer.FLOAT: + min_value = self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + min_value = self.expect_number_(variable=False) + + if self.next_token_type_ is Lexer.FLOAT: + max_value = self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + max_value = self.expect_number_(variable=False) + self.expect_symbol_(";") + + conditions[axis] = (min_value, max_value) + + self.expect_symbol_("}") + + finalname = self.expect_name_() + if finalname != name: + raise FeatureLibError('Expected "%s"' % name, self.cur_token_location_) + return self.ast.ConditionsetStatement(name, conditions) + + def parse_block_( + self, block, vertical, stylisticset=None, size_feature=False, cv_feature=None + ): + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + + statements = block.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.GLYPHCLASS: + statements.append(self.parse_glyphclass_definition_()) + elif self.is_cur_keyword_("anchorDef"): + statements.append(self.parse_anchordef_()) + elif self.is_cur_keyword_({"enum", "enumerate"}): + statements.append(self.parse_enumerate_(vertical=vertical)) + elif self.is_cur_keyword_("feature"): + statements.append(self.parse_feature_reference_()) + elif self.is_cur_keyword_("ignore"): + statements.append(self.parse_ignore_()) + elif self.is_cur_keyword_("language"): + statements.append(self.parse_language_()) + elif self.is_cur_keyword_("lookup"): + statements.append(self.parse_lookup_(vertical)) + elif self.is_cur_keyword_("lookupflag"): + statements.append(self.parse_lookupflag_()) + elif self.is_cur_keyword_("markClass"): + statements.append(self.parse_markClass_()) + elif self.is_cur_keyword_({"pos", "position"}): + statements.append( + self.parse_position_(enumerated=False, vertical=vertical) + ) + elif self.is_cur_keyword_("script"): + statements.append(self.parse_script_()) + elif self.is_cur_keyword_({"sub", "substitute", "rsub", "reversesub"}): + statements.append(self.parse_substitute_()) + elif self.is_cur_keyword_("subtable"): + statements.append(self.parse_subtable_()) + elif self.is_cur_keyword_("valueRecordDef"): + statements.append(self.parse_valuerecord_definition_(vertical)) + elif stylisticset and self.is_cur_keyword_("featureNames"): + statements.append(self.parse_featureNames_(stylisticset)) + elif cv_feature and self.is_cur_keyword_("cvParameters"): + statements.append(self.parse_cvParameters_(cv_feature)) + elif size_feature and self.is_cur_keyword_("parameters"): + statements.append(self.parse_size_parameters_()) + elif size_feature and self.is_cur_keyword_("sizemenuname"): + statements.append(self.parse_size_menuname_()) + elif ( + self.cur_token_type_ is Lexer.NAME + and self.cur_token_ in self.extensions + ): + statements.append(self.extensions[self.cur_token_](self)) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected glyph class definition or statement: got {} {}".format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + + name = self.expect_name_() + if name != block.name.strip(): + raise FeatureLibError( + 'Expected "%s"' % block.name.strip(), self.cur_token_location_ + ) + self.expect_symbol_(";") + + # A multiple substitution may have a single destination, in which case + # it will look just like a single substitution. So if there are both + # multiple and single substitutions, upgrade all the single ones to + # multiple substitutions. + + # Check if we have a mix of non-contextual singles and multiples. + has_single = False + has_multiple = False + for s in statements: + if isinstance(s, self.ast.SingleSubstStatement): + has_single = not any([s.prefix, s.suffix, s.forceChain]) + elif isinstance(s, self.ast.MultipleSubstStatement): + has_multiple = not any([s.prefix, s.suffix, s.forceChain]) + + # Upgrade all single substitutions to multiple substitutions. + if has_single and has_multiple: + statements = [] + for s in block.statements: + if isinstance(s, self.ast.SingleSubstStatement): + glyphs = s.glyphs[0].glyphSet() + replacements = s.replacements[0].glyphSet() + if len(replacements) == 1: + replacements *= len(glyphs) + for i, glyph in enumerate(glyphs): + statements.append( + self.ast.MultipleSubstStatement( + s.prefix, + glyph, + s.suffix, + [replacements[i]], + s.forceChain, + location=s.location, + ) + ) + else: + statements.append(s) + block.statements = statements + + def is_cur_keyword_(self, k): + if self.cur_token_type_ is Lexer.NAME: + if isinstance(k, type("")): # basestring is gone in Python3 + return self.cur_token_ == k + else: + return self.cur_token_ in k + return False + + def expect_class_name_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.GLYPHCLASS: + raise FeatureLibError("Expected @NAME", self.cur_token_location_) + return self.cur_token_ + + def expect_cid_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.CID: + return self.cur_token_ + raise FeatureLibError("Expected a CID", self.cur_token_location_) + + def expect_filename_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.FILENAME: + raise FeatureLibError("Expected file name", self.cur_token_location_) + return self.cur_token_ + + def expect_glyph_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME: + self.cur_token_ = self.cur_token_.lstrip("\\") + if len(self.cur_token_) > 63: + raise FeatureLibError( + "Glyph names must not be longer than 63 characters", + self.cur_token_location_, + ) + return self.cur_token_ + elif self.cur_token_type_ is Lexer.CID: + return "cid%05d" % self.cur_token_ + raise FeatureLibError("Expected a glyph name or CID", self.cur_token_location_) + + def check_glyph_name_in_glyph_set(self, *names): + """Adds a glyph name (just `start`) or glyph names of a + range (`start` and `end`) which are not in the glyph set + to the "missing list" for future error reporting. + + If no glyph set is present, does nothing. + """ + if self.glyphNames_: + for name in names: + if name in self.glyphNames_: + continue + if name not in self.missing: + self.missing[name] = self.cur_token_location_ + + def expect_markClass_reference_(self): + name = self.expect_class_name_() + mc = self.glyphclasses_.resolve(name) + if mc is None: + raise FeatureLibError( + "Unknown markClass @%s" % name, self.cur_token_location_ + ) + if not isinstance(mc, self.ast.MarkClass): + raise FeatureLibError( + "@%s is not a markClass" % name, self.cur_token_location_ + ) + return mc + + def expect_tag_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected a tag", self.cur_token_location_) + if len(self.cur_token_) > 4: + raise FeatureLibError( + "Tags cannot be longer than 4 characters", self.cur_token_location_ + ) + return (self.cur_token_ + " ")[:4] + + def expect_script_tag_(self): + tag = self.expect_tag_() + if tag == "dflt": + raise FeatureLibError( + '"dflt" is not a valid script tag; use "DFLT" instead', + self.cur_token_location_, + ) + return tag + + def expect_language_tag_(self): + tag = self.expect_tag_() + if tag == "DFLT": + raise FeatureLibError( + '"DFLT" is not a valid language tag; use "dflt" instead', + self.cur_token_location_, + ) + return tag + + def expect_symbol_(self, symbol): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol: + return symbol + raise FeatureLibError("Expected '%s'" % symbol, self.cur_token_location_) + + def expect_keyword_(self, keyword): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME and self.cur_token_ == keyword: + return self.cur_token_ + raise FeatureLibError('Expected "%s"' % keyword, self.cur_token_location_) + + def expect_name_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME: + return self.cur_token_ + raise FeatureLibError("Expected a name", self.cur_token_location_) + + def expect_number_(self, variable=False): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NUMBER: + return self.cur_token_ + if variable and self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == "(": + return self.expect_variable_scalar_() + raise FeatureLibError("Expected a number", self.cur_token_location_) + + def expect_variable_scalar_(self): + self.advance_lexer_() # "(" + scalar = VariableScalar() + while True: + if self.cur_token_type_ == Lexer.SYMBOL and self.cur_token_ == ")": + break + location, value = self.expect_master_() + scalar.add_value(location, value) + return scalar + + def expect_master_(self): + location = {} + while True: + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected an axis name", self.cur_token_location_) + axis = self.cur_token_ + self.advance_lexer_() + if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == "="): + raise FeatureLibError( + "Expected an equals sign", self.cur_token_location_ + ) + value = self.expect_number_() + location[axis] = value + if self.next_token_type_ is Lexer.NAME and self.next_token_[0] == ":": + # Lexer has just read the value as a glyph name. We'll correct it later + break + self.advance_lexer_() + if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ","): + raise FeatureLibError( + "Expected an comma or an equals sign", self.cur_token_location_ + ) + self.advance_lexer_() + self.advance_lexer_() + value = int(self.cur_token_[1:]) + self.advance_lexer_() + return location, value + + def expect_any_number_(self): + self.advance_lexer_() + if self.cur_token_type_ in Lexer.NUMBERS: + return self.cur_token_ + raise FeatureLibError( + "Expected a decimal, hexadecimal or octal number", self.cur_token_location_ + ) + + def expect_float_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.FLOAT: + return self.cur_token_ + raise FeatureLibError( + "Expected a floating-point number", self.cur_token_location_ + ) + + def expect_decipoint_(self): + if self.next_token_type_ == Lexer.FLOAT: + return self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + return self.expect_number_() / 10 + else: + raise FeatureLibError( + "Expected an integer or floating-point number", self.cur_token_location_ + ) + + def expect_stat_flags(self): + value = 0 + flags = { + "OlderSiblingFontAttribute": 1, + "ElidableAxisValueName": 2, + } + while self.next_token_ != ";": + if self.next_token_ in flags: + name = self.expect_name_() + value = value | flags[name] + else: + raise FeatureLibError( + f"Unexpected STAT flag {self.cur_token_}", self.cur_token_location_ + ) + return value + + def expect_stat_values_(self): + if self.next_token_type_ == Lexer.FLOAT: + return self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + return self.expect_number_() + else: + raise FeatureLibError( + "Expected an integer or floating-point number", self.cur_token_location_ + ) + + def expect_string_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.STRING: + return self.cur_token_ + raise FeatureLibError("Expected a string", self.cur_token_location_) + + def advance_lexer_(self, comments=False): + if comments and self.cur_comments_: + self.cur_token_type_ = Lexer.COMMENT + self.cur_token_, self.cur_token_location_ = self.cur_comments_.pop(0) + return + else: + self.cur_token_type_, self.cur_token_, self.cur_token_location_ = ( + self.next_token_type_, + self.next_token_, + self.next_token_location_, + ) + while True: + try: + ( + self.next_token_type_, + self.next_token_, + self.next_token_location_, + ) = next(self.lexer_) + except StopIteration: + self.next_token_type_, self.next_token_ = (None, None) + if self.next_token_type_ != Lexer.COMMENT: + break + self.cur_comments_.append((self.next_token_, self.next_token_location_)) + + @staticmethod + def reverse_string_(s): + """'abc' --> 'cba'""" + return "".join(reversed(list(s))) + + def make_cid_range_(self, location, start, limit): + """(location, 999, 1001) --> ["cid00999", "cid01000", "cid01001"]""" + result = list() + if start > limit: + raise FeatureLibError( + "Bad range: start should be less than limit", location + ) + for cid in range(start, limit + 1): + result.append("cid%05d" % cid) + return result + + def make_glyph_range_(self, location, start, limit): + """(location, "a.sc", "d.sc") --> ["a.sc", "b.sc", "c.sc", "d.sc"]""" + result = list() + if len(start) != len(limit): + raise FeatureLibError( + 'Bad range: "%s" and "%s" should have the same length' % (start, limit), + location, + ) + + rev = self.reverse_string_ + prefix = os.path.commonprefix([start, limit]) + suffix = rev(os.path.commonprefix([rev(start), rev(limit)])) + if len(suffix) > 0: + start_range = start[len(prefix) : -len(suffix)] + limit_range = limit[len(prefix) : -len(suffix)] + else: + start_range = start[len(prefix) :] + limit_range = limit[len(prefix) :] + + if start_range >= limit_range: + raise FeatureLibError( + "Start of range must be smaller than its end", location + ) + + uppercase = re.compile(r"^[A-Z]$") + if uppercase.match(start_range) and uppercase.match(limit_range): + for c in range(ord(start_range), ord(limit_range) + 1): + result.append("%s%c%s" % (prefix, c, suffix)) + return result + + lowercase = re.compile(r"^[a-z]$") + if lowercase.match(start_range) and lowercase.match(limit_range): + for c in range(ord(start_range), ord(limit_range) + 1): + result.append("%s%c%s" % (prefix, c, suffix)) + return result + + digits = re.compile(r"^[0-9]{1,3}$") + if digits.match(start_range) and digits.match(limit_range): + for i in range(int(start_range, 10), int(limit_range, 10) + 1): + number = ("000" + str(i))[-len(start_range) :] + result.append("%s%s%s" % (prefix, number, suffix)) + return result + + raise FeatureLibError('Bad range: "%s-%s"' % (start, limit), location) + + +class SymbolTable(object): + def __init__(self): + self.scopes_ = [{}] + + def enter_scope(self): + self.scopes_.append({}) + + def exit_scope(self): + self.scopes_.pop() + + def define(self, name, item): + self.scopes_[-1][name] = item + + def resolve(self, name): + for scope in reversed(self.scopes_): + item = scope.get(name) + if item: + return item + return None diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/variableScalar.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/variableScalar.py new file mode 100644 index 00000000..c97b4354 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/feaLib/variableScalar.py @@ -0,0 +1,112 @@ +from fontTools.varLib.models import VariationModel, normalizeValue, piecewiseLinearMap + + +def Location(loc): + return tuple(sorted(loc.items())) + + +class VariableScalar: + """A scalar with different values at different points in the designspace.""" + + def __init__(self, location_value={}): + self.values = {} + self.axes = {} + for location, value in location_value.items(): + self.add_value(location, value) + + def __repr__(self): + items = [] + for location, value in self.values.items(): + loc = ",".join(["%s=%i" % (ax, loc) for ax, loc in location]) + items.append("%s:%i" % (loc, value)) + return "(" + (" ".join(items)) + ")" + + @property + def does_vary(self): + values = list(self.values.values()) + return any(v != values[0] for v in values[1:]) + + @property + def axes_dict(self): + if not self.axes: + raise ValueError( + ".axes must be defined on variable scalar before interpolating" + ) + return {ax.axisTag: ax for ax in self.axes} + + def _normalized_location(self, location): + location = self.fix_location(location) + normalized_location = {} + for axtag in location.keys(): + if axtag not in self.axes_dict: + raise ValueError("Unknown axis %s in %s" % (axtag, location)) + axis = self.axes_dict[axtag] + normalized_location[axtag] = normalizeValue( + location[axtag], (axis.minValue, axis.defaultValue, axis.maxValue) + ) + + return Location(normalized_location) + + def fix_location(self, location): + location = dict(location) + for tag, axis in self.axes_dict.items(): + if tag not in location: + location[tag] = axis.defaultValue + return location + + def add_value(self, location, value): + if self.axes: + location = self.fix_location(location) + + self.values[Location(location)] = value + + def fix_all_locations(self): + self.values = { + Location(self.fix_location(l)): v for l, v in self.values.items() + } + + @property + def default(self): + self.fix_all_locations() + key = Location({ax.axisTag: ax.defaultValue for ax in self.axes}) + if key not in self.values: + raise ValueError("Default value could not be found") + # I *guess* we could interpolate one, but I don't know how. + return self.values[key] + + def value_at_location(self, location, model_cache=None, avar=None): + loc = location + if loc in self.values.keys(): + return self.values[loc] + values = list(self.values.values()) + return self.model(model_cache, avar).interpolateFromMasters(loc, values) + + def model(self, model_cache=None, avar=None): + if model_cache is not None: + key = tuple(self.values.keys()) + if key in model_cache: + return model_cache[key] + locations = [dict(self._normalized_location(k)) for k in self.values.keys()] + if avar is not None: + mapping = avar.segments + locations = [ + { + k: piecewiseLinearMap(v, mapping[k]) if k in mapping else v + for k, v in location.items() + } + for location in locations + ] + m = VariationModel(locations) + if model_cache is not None: + model_cache[key] = m + return m + + def get_deltas_and_supports(self, model_cache=None, avar=None): + values = list(self.values.values()) + return self.model(model_cache, avar).getDeltasAndSupports(values) + + def add_to_variation_store(self, store_builder, model_cache=None, avar=None): + deltas, supports = self.get_deltas_and_supports(model_cache, avar) + store_builder.setSupports(supports) + index = store_builder.storeDeltas(deltas) + return int(self.default), index diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/fontBuilder.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/fontBuilder.py new file mode 100644 index 00000000..dd57a050 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/fontBuilder.py @@ -0,0 +1,993 @@ +__all__ = ["FontBuilder"] + +""" +This module is *experimental*, meaning it still may evolve and change. + +The `FontBuilder` class is a convenient helper to construct working TTF or +OTF fonts from scratch. + +Note that the various setup methods cannot be called in arbitrary order, +due to various interdependencies between OpenType tables. Here is an order +that works: + + fb = FontBuilder(...) + fb.setupGlyphOrder(...) + fb.setupCharacterMap(...) + fb.setupGlyf(...) --or-- fb.setupCFF(...) + fb.setupHorizontalMetrics(...) + fb.setupHorizontalHeader() + fb.setupNameTable(...) + fb.setupOS2() + fb.addOpenTypeFeatures(...) + fb.setupPost() + fb.save(...) + +Here is how to build a minimal TTF: + +```python +from fontTools.fontBuilder import FontBuilder +from fontTools.pens.ttGlyphPen import TTGlyphPen + + +def drawTestGlyph(pen): + pen.moveTo((100, 100)) + pen.lineTo((100, 1000)) + pen.qCurveTo((200, 900), (400, 900), (500, 1000)) + pen.lineTo((500, 100)) + pen.closePath() + + +fb = FontBuilder(1024, isTTF=True) +fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"]) +fb.setupCharacterMap({32: "space", 65: "A", 97: "a"}) +advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0} + +familyName = "HelloTestFont" +styleName = "TotallyNormal" +version = "0.1" + +nameStrings = dict( + familyName=dict(en=familyName, nl="HalloTestFont"), + styleName=dict(en=styleName, nl="TotaalNormaal"), + uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName, + fullName=familyName + "-" + styleName, + psName=familyName + "-" + styleName, + version="Version " + version, +) + +pen = TTGlyphPen(None) +drawTestGlyph(pen) +glyph = pen.glyph() +glyphs = {".notdef": glyph, "space": glyph, "A": glyph, "a": glyph, ".null": glyph} +fb.setupGlyf(glyphs) +metrics = {} +glyphTable = fb.font["glyf"] +for gn, advanceWidth in advanceWidths.items(): + metrics[gn] = (advanceWidth, glyphTable[gn].xMin) +fb.setupHorizontalMetrics(metrics) +fb.setupHorizontalHeader(ascent=824, descent=-200) +fb.setupNameTable(nameStrings) +fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200) +fb.setupPost() +fb.save("test.ttf") +``` + +And here's how to build a minimal OTF: + +```python +from fontTools.fontBuilder import FontBuilder +from fontTools.pens.t2CharStringPen import T2CharStringPen + + +def drawTestGlyph(pen): + pen.moveTo((100, 100)) + pen.lineTo((100, 1000)) + pen.curveTo((200, 900), (400, 900), (500, 1000)) + pen.lineTo((500, 100)) + pen.closePath() + + +fb = FontBuilder(1024, isTTF=False) +fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"]) +fb.setupCharacterMap({32: "space", 65: "A", 97: "a"}) +advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0} + +familyName = "HelloTestFont" +styleName = "TotallyNormal" +version = "0.1" + +nameStrings = dict( + familyName=dict(en=familyName, nl="HalloTestFont"), + styleName=dict(en=styleName, nl="TotaalNormaal"), + uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName, + fullName=familyName + "-" + styleName, + psName=familyName + "-" + styleName, + version="Version " + version, +) + +pen = T2CharStringPen(600, None) +drawTestGlyph(pen) +charString = pen.getCharString() +charStrings = { + ".notdef": charString, + "space": charString, + "A": charString, + "a": charString, + ".null": charString, +} +fb.setupCFF(nameStrings["psName"], {"FullName": nameStrings["psName"]}, charStrings, {}) +lsb = {gn: cs.calcBounds(None)[0] for gn, cs in charStrings.items()} +metrics = {} +for gn, advanceWidth in advanceWidths.items(): + metrics[gn] = (advanceWidth, lsb[gn]) +fb.setupHorizontalMetrics(metrics) +fb.setupHorizontalHeader(ascent=824, descent=200) +fb.setupNameTable(nameStrings) +fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200) +fb.setupPost() +fb.save("test.otf") +``` +""" + +from .ttLib import TTFont, newTable +from .ttLib.tables._c_m_a_p import cmap_classes +from .ttLib.tables._g_l_y_f import flagCubic +from .ttLib.tables.O_S_2f_2 import Panose +from .misc.timeTools import timestampNow +import struct +from collections import OrderedDict + + +_headDefaults = dict( + tableVersion=1.0, + fontRevision=1.0, + checkSumAdjustment=0, + magicNumber=0x5F0F3CF5, + flags=0x0003, + unitsPerEm=1000, + created=0, + modified=0, + xMin=0, + yMin=0, + xMax=0, + yMax=0, + macStyle=0, + lowestRecPPEM=3, + fontDirectionHint=2, + indexToLocFormat=0, + glyphDataFormat=0, +) + +_maxpDefaultsTTF = dict( + tableVersion=0x00010000, + numGlyphs=0, + maxPoints=0, + maxContours=0, + maxCompositePoints=0, + maxCompositeContours=0, + maxZones=2, + maxTwilightPoints=0, + maxStorage=0, + maxFunctionDefs=0, + maxInstructionDefs=0, + maxStackElements=0, + maxSizeOfInstructions=0, + maxComponentElements=0, + maxComponentDepth=0, +) +_maxpDefaultsOTF = dict( + tableVersion=0x00005000, + numGlyphs=0, +) + +_postDefaults = dict( + formatType=3.0, + italicAngle=0, + underlinePosition=0, + underlineThickness=0, + isFixedPitch=0, + minMemType42=0, + maxMemType42=0, + minMemType1=0, + maxMemType1=0, +) + +_hheaDefaults = dict( + tableVersion=0x00010000, + ascent=0, + descent=0, + lineGap=0, + advanceWidthMax=0, + minLeftSideBearing=0, + minRightSideBearing=0, + xMaxExtent=0, + caretSlopeRise=1, + caretSlopeRun=0, + caretOffset=0, + reserved0=0, + reserved1=0, + reserved2=0, + reserved3=0, + metricDataFormat=0, + numberOfHMetrics=0, +) + +_vheaDefaults = dict( + tableVersion=0x00010000, + ascent=0, + descent=0, + lineGap=0, + advanceHeightMax=0, + minTopSideBearing=0, + minBottomSideBearing=0, + yMaxExtent=0, + caretSlopeRise=0, + caretSlopeRun=0, + reserved0=0, + reserved1=0, + reserved2=0, + reserved3=0, + reserved4=0, + metricDataFormat=0, + numberOfVMetrics=0, +) + +_nameIDs = dict( + copyright=0, + familyName=1, + styleName=2, + uniqueFontIdentifier=3, + fullName=4, + version=5, + psName=6, + trademark=7, + manufacturer=8, + designer=9, + description=10, + vendorURL=11, + designerURL=12, + licenseDescription=13, + licenseInfoURL=14, + # reserved = 15, + typographicFamily=16, + typographicSubfamily=17, + compatibleFullName=18, + sampleText=19, + postScriptCIDFindfontName=20, + wwsFamilyName=21, + wwsSubfamilyName=22, + lightBackgroundPalette=23, + darkBackgroundPalette=24, + variationsPostScriptNamePrefix=25, +) + +# to insert in setupNameTable doc string: +# print("\n".join(("%s (nameID %s)" % (k, v)) for k, v in sorted(_nameIDs.items(), key=lambda x: x[1]))) + +_panoseDefaults = Panose() + +_OS2Defaults = dict( + version=3, + xAvgCharWidth=0, + usWeightClass=400, + usWidthClass=5, + fsType=0x0004, # default: Preview & Print embedding + ySubscriptXSize=0, + ySubscriptYSize=0, + ySubscriptXOffset=0, + ySubscriptYOffset=0, + ySuperscriptXSize=0, + ySuperscriptYSize=0, + ySuperscriptXOffset=0, + ySuperscriptYOffset=0, + yStrikeoutSize=0, + yStrikeoutPosition=0, + sFamilyClass=0, + panose=_panoseDefaults, + ulUnicodeRange1=0, + ulUnicodeRange2=0, + ulUnicodeRange3=0, + ulUnicodeRange4=0, + achVendID="????", + fsSelection=0, + usFirstCharIndex=0, + usLastCharIndex=0, + sTypoAscender=0, + sTypoDescender=0, + sTypoLineGap=0, + usWinAscent=0, + usWinDescent=0, + ulCodePageRange1=0, + ulCodePageRange2=0, + sxHeight=0, + sCapHeight=0, + usDefaultChar=0, # .notdef + usBreakChar=32, # space + usMaxContext=0, + usLowerOpticalPointSize=0, + usUpperOpticalPointSize=0, +) + + +class FontBuilder(object): + def __init__(self, unitsPerEm=None, font=None, isTTF=True, glyphDataFormat=0): + """Initialize a FontBuilder instance. + + If the `font` argument is not given, a new `TTFont` will be + constructed, and `unitsPerEm` must be given. If `isTTF` is True, + the font will be a glyf-based TTF; if `isTTF` is False it will be + a CFF-based OTF. + + The `glyphDataFormat` argument corresponds to the `head` table field + that defines the format of the TrueType `glyf` table (default=0). + TrueType glyphs historically can only contain quadratic splines and static + components, but there's a proposal to add support for cubic Bezier curves as well + as variable composites/components at + https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1.md + You can experiment with the new features by setting `glyphDataFormat` to 1. + A ValueError is raised if `glyphDataFormat` is left at 0 but glyphs are added + that contain cubic splines or varcomposites. This is to prevent accidentally + creating fonts that are incompatible with existing TrueType implementations. + + If `font` is given, it must be a `TTFont` instance and `unitsPerEm` + must _not_ be given. The `isTTF` and `glyphDataFormat` arguments will be ignored. + """ + if font is None: + self.font = TTFont(recalcTimestamp=False) + self.isTTF = isTTF + now = timestampNow() + assert unitsPerEm is not None + self.setupHead( + unitsPerEm=unitsPerEm, + created=now, + modified=now, + glyphDataFormat=glyphDataFormat, + ) + self.setupMaxp() + else: + assert unitsPerEm is None + self.font = font + self.isTTF = "glyf" in font + + def save(self, file): + """Save the font. The 'file' argument can be either a pathname or a + writable file object. + """ + self.font.save(file) + + def _initTableWithValues(self, tableTag, defaults, values): + table = self.font[tableTag] = newTable(tableTag) + for k, v in defaults.items(): + setattr(table, k, v) + for k, v in values.items(): + setattr(table, k, v) + return table + + def _updateTableWithValues(self, tableTag, values): + table = self.font[tableTag] + for k, v in values.items(): + setattr(table, k, v) + + def setupHead(self, **values): + """Create a new `head` table and initialize it with default values, + which can be overridden by keyword arguments. + """ + self._initTableWithValues("head", _headDefaults, values) + + def updateHead(self, **values): + """Update the head table with the fields and values passed as + keyword arguments. + """ + self._updateTableWithValues("head", values) + + def setupGlyphOrder(self, glyphOrder): + """Set the glyph order for the font.""" + self.font.setGlyphOrder(glyphOrder) + + def setupCharacterMap(self, cmapping, uvs=None, allowFallback=False): + """Build the `cmap` table for the font. The `cmapping` argument should + be a dict mapping unicode code points as integers to glyph names. + + The `uvs` argument, when passed, must be a list of tuples, describing + Unicode Variation Sequences. These tuples have three elements: + (unicodeValue, variationSelector, glyphName) + `unicodeValue` and `variationSelector` are integer code points. + `glyphName` may be None, to indicate this is the default variation. + Text processors will then use the cmap to find the glyph name. + Each Unicode Variation Sequence should be an officially supported + sequence, but this is not policed. + """ + subTables = [] + highestUnicode = max(cmapping) if cmapping else 0 + if highestUnicode > 0xFFFF: + cmapping_3_1 = dict((k, v) for k, v in cmapping.items() if k < 0x10000) + subTable_3_10 = buildCmapSubTable(cmapping, 12, 3, 10) + subTables.append(subTable_3_10) + else: + cmapping_3_1 = cmapping + format = 4 + subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1) + try: + subTable_3_1.compile(self.font) + except struct.error: + # format 4 overflowed, fall back to format 12 + if not allowFallback: + raise ValueError( + "cmap format 4 subtable overflowed; sort glyph order by unicode to fix." + ) + format = 12 + subTable_3_1 = buildCmapSubTable(cmapping_3_1, format, 3, 1) + subTables.append(subTable_3_1) + subTable_0_3 = buildCmapSubTable(cmapping_3_1, format, 0, 3) + subTables.append(subTable_0_3) + + if uvs is not None: + uvsDict = {} + for unicodeValue, variationSelector, glyphName in uvs: + if cmapping.get(unicodeValue) == glyphName: + # this is a default variation + glyphName = None + if variationSelector not in uvsDict: + uvsDict[variationSelector] = [] + uvsDict[variationSelector].append((unicodeValue, glyphName)) + uvsSubTable = buildCmapSubTable({}, 14, 0, 5) + uvsSubTable.uvsDict = uvsDict + subTables.append(uvsSubTable) + + self.font["cmap"] = newTable("cmap") + self.font["cmap"].tableVersion = 0 + self.font["cmap"].tables = subTables + + def setupNameTable(self, nameStrings, windows=True, mac=True): + """Create the `name` table for the font. The `nameStrings` argument must + be a dict, mapping nameIDs or descriptive names for the nameIDs to name + record values. A value is either a string, or a dict, mapping language codes + to strings, to allow localized name table entries. + + By default, both Windows (platformID=3) and Macintosh (platformID=1) name + records are added, unless any of `windows` or `mac` arguments is False. + + The following descriptive names are available for nameIDs: + + copyright (nameID 0) + familyName (nameID 1) + styleName (nameID 2) + uniqueFontIdentifier (nameID 3) + fullName (nameID 4) + version (nameID 5) + psName (nameID 6) + trademark (nameID 7) + manufacturer (nameID 8) + designer (nameID 9) + description (nameID 10) + vendorURL (nameID 11) + designerURL (nameID 12) + licenseDescription (nameID 13) + licenseInfoURL (nameID 14) + typographicFamily (nameID 16) + typographicSubfamily (nameID 17) + compatibleFullName (nameID 18) + sampleText (nameID 19) + postScriptCIDFindfontName (nameID 20) + wwsFamilyName (nameID 21) + wwsSubfamilyName (nameID 22) + lightBackgroundPalette (nameID 23) + darkBackgroundPalette (nameID 24) + variationsPostScriptNamePrefix (nameID 25) + """ + nameTable = self.font["name"] = newTable("name") + nameTable.names = [] + + for nameName, nameValue in nameStrings.items(): + if isinstance(nameName, int): + nameID = nameName + else: + nameID = _nameIDs[nameName] + if isinstance(nameValue, str): + nameValue = dict(en=nameValue) + nameTable.addMultilingualName( + nameValue, ttFont=self.font, nameID=nameID, windows=windows, mac=mac + ) + + def setupOS2(self, **values): + """Create a new `OS/2` table and initialize it with default values, + which can be overridden by keyword arguments. + """ + self._initTableWithValues("OS/2", _OS2Defaults, values) + if "xAvgCharWidth" not in values: + assert ( + "hmtx" in self.font + ), "the 'hmtx' table must be setup before the 'OS/2' table" + self.font["OS/2"].recalcAvgCharWidth(self.font) + if not ( + "ulUnicodeRange1" in values + or "ulUnicodeRange2" in values + or "ulUnicodeRange3" in values + or "ulUnicodeRange3" in values + ): + assert ( + "cmap" in self.font + ), "the 'cmap' table must be setup before the 'OS/2' table" + self.font["OS/2"].recalcUnicodeRanges(self.font) + + def setupCFF(self, psName, fontInfo, charStringsDict, privateDict): + from .cffLib import ( + CFFFontSet, + TopDictIndex, + TopDict, + CharStrings, + GlobalSubrsIndex, + PrivateDict, + ) + + assert not self.isTTF + self.font.sfntVersion = "OTTO" + fontSet = CFFFontSet() + fontSet.major = 1 + fontSet.minor = 0 + fontSet.otFont = self.font + fontSet.fontNames = [psName] + fontSet.topDictIndex = TopDictIndex() + + globalSubrs = GlobalSubrsIndex() + fontSet.GlobalSubrs = globalSubrs + private = PrivateDict() + for key, value in privateDict.items(): + setattr(private, key, value) + fdSelect = None + fdArray = None + + topDict = TopDict() + topDict.charset = self.font.getGlyphOrder() + topDict.Private = private + topDict.GlobalSubrs = fontSet.GlobalSubrs + for key, value in fontInfo.items(): + setattr(topDict, key, value) + if "FontMatrix" not in fontInfo: + scale = 1 / self.font["head"].unitsPerEm + topDict.FontMatrix = [scale, 0, 0, scale, 0, 0] + + charStrings = CharStrings( + None, topDict.charset, globalSubrs, private, fdSelect, fdArray + ) + for glyphName, charString in charStringsDict.items(): + charString.private = private + charString.globalSubrs = globalSubrs + charStrings[glyphName] = charString + topDict.CharStrings = charStrings + + fontSet.topDictIndex.append(topDict) + + self.font["CFF "] = newTable("CFF ") + self.font["CFF "].cff = fontSet + + def setupCFF2(self, charStringsDict, fdArrayList=None, regions=None): + from .cffLib import ( + CFFFontSet, + TopDictIndex, + TopDict, + CharStrings, + GlobalSubrsIndex, + PrivateDict, + FDArrayIndex, + FontDict, + ) + + assert not self.isTTF + self.font.sfntVersion = "OTTO" + fontSet = CFFFontSet() + fontSet.major = 2 + fontSet.minor = 0 + + cff2GetGlyphOrder = self.font.getGlyphOrder + fontSet.topDictIndex = TopDictIndex(None, cff2GetGlyphOrder, None) + + globalSubrs = GlobalSubrsIndex() + fontSet.GlobalSubrs = globalSubrs + + if fdArrayList is None: + fdArrayList = [{}] + fdSelect = None + fdArray = FDArrayIndex() + fdArray.strings = None + fdArray.GlobalSubrs = globalSubrs + for privateDict in fdArrayList: + fontDict = FontDict() + fontDict.setCFF2(True) + private = PrivateDict() + for key, value in privateDict.items(): + setattr(private, key, value) + fontDict.Private = private + fdArray.append(fontDict) + + topDict = TopDict() + topDict.cff2GetGlyphOrder = cff2GetGlyphOrder + topDict.FDArray = fdArray + scale = 1 / self.font["head"].unitsPerEm + topDict.FontMatrix = [scale, 0, 0, scale, 0, 0] + + private = fdArray[0].Private + charStrings = CharStrings(None, None, globalSubrs, private, fdSelect, fdArray) + for glyphName, charString in charStringsDict.items(): + charString.private = private + charString.globalSubrs = globalSubrs + charStrings[glyphName] = charString + topDict.CharStrings = charStrings + + fontSet.topDictIndex.append(topDict) + + self.font["CFF2"] = newTable("CFF2") + self.font["CFF2"].cff = fontSet + + if regions: + self.setupCFF2Regions(regions) + + def setupCFF2Regions(self, regions): + from .varLib.builder import buildVarRegionList, buildVarData, buildVarStore + from .cffLib import VarStoreData + + assert "fvar" in self.font, "fvar must to be set up first" + assert "CFF2" in self.font, "CFF2 must to be set up first" + axisTags = [a.axisTag for a in self.font["fvar"].axes] + varRegionList = buildVarRegionList(regions, axisTags) + varData = buildVarData(list(range(len(regions))), None, optimize=False) + varStore = buildVarStore(varRegionList, [varData]) + vstore = VarStoreData(otVarStore=varStore) + topDict = self.font["CFF2"].cff.topDictIndex[0] + topDict.VarStore = vstore + for fontDict in topDict.FDArray: + fontDict.Private.vstore = vstore + + def setupGlyf(self, glyphs, calcGlyphBounds=True, validateGlyphFormat=True): + """Create the `glyf` table from a dict, that maps glyph names + to `fontTools.ttLib.tables._g_l_y_f.Glyph` objects, for example + as made by `fontTools.pens.ttGlyphPen.TTGlyphPen`. + + If `calcGlyphBounds` is True, the bounds of all glyphs will be + calculated. Only pass False if your glyph objects already have + their bounding box values set. + + If `validateGlyphFormat` is True, raise ValueError if any of the glyphs contains + cubic curves or is a variable composite but head.glyphDataFormat=0. + Set it to False to skip the check if you know in advance all the glyphs are + compatible with the specified glyphDataFormat. + """ + assert self.isTTF + + if validateGlyphFormat and self.font["head"].glyphDataFormat == 0: + for name, g in glyphs.items(): + if g.isVarComposite(): + raise ValueError( + f"Glyph {name!r} is a variable composite, but glyphDataFormat=0" + ) + elif g.numberOfContours > 0 and any(f & flagCubic for f in g.flags): + raise ValueError( + f"Glyph {name!r} has cubic Bezier outlines, but glyphDataFormat=0; " + "either convert to quadratics with cu2qu or set glyphDataFormat=1." + ) + + self.font["loca"] = newTable("loca") + self.font["glyf"] = newTable("glyf") + self.font["glyf"].glyphs = glyphs + if hasattr(self.font, "glyphOrder"): + self.font["glyf"].glyphOrder = self.font.glyphOrder + if calcGlyphBounds: + self.calcGlyphBounds() + + def setupFvar(self, axes, instances): + """Adds an font variations table to the font. + + Args: + axes (list): See below. + instances (list): See below. + + ``axes`` should be a list of axes, with each axis either supplied as + a py:class:`.designspaceLib.AxisDescriptor` object, or a tuple in the + format ```tupletag, minValue, defaultValue, maxValue, name``. + The ``name`` is either a string, or a dict, mapping language codes + to strings, to allow localized name table entries. + + ```instances`` should be a list of instances, with each instance either + supplied as a py:class:`.designspaceLib.InstanceDescriptor` object, or a + dict with keys ``location`` (mapping of axis tags to float values), + ``stylename`` and (optionally) ``postscriptfontname``. + The ``stylename`` is either a string, or a dict, mapping language codes + to strings, to allow localized name table entries. + """ + + addFvar(self.font, axes, instances) + + def setupAvar(self, axes, mappings=None): + """Adds an axis variations table to the font. + + Args: + axes (list): A list of py:class:`.designspaceLib.AxisDescriptor` objects. + """ + from .varLib import _add_avar + + if "fvar" not in self.font: + raise KeyError("'fvar' table is missing; can't add 'avar'.") + + axisTags = [axis.axisTag for axis in self.font["fvar"].axes] + axes = OrderedDict(enumerate(axes)) # Only values are used + _add_avar(self.font, axes, mappings, axisTags) + + def setupGvar(self, variations): + gvar = self.font["gvar"] = newTable("gvar") + gvar.version = 1 + gvar.reserved = 0 + gvar.variations = variations + + def calcGlyphBounds(self): + """Calculate the bounding boxes of all glyphs in the `glyf` table. + This is usually not called explicitly by client code. + """ + glyphTable = self.font["glyf"] + for glyph in glyphTable.glyphs.values(): + glyph.recalcBounds(glyphTable) + + def setupHorizontalMetrics(self, metrics): + """Create a new `hmtx` table, for horizontal metrics. + + The `metrics` argument must be a dict, mapping glyph names to + `(width, leftSidebearing)` tuples. + """ + self.setupMetrics("hmtx", metrics) + + def setupVerticalMetrics(self, metrics): + """Create a new `vmtx` table, for horizontal metrics. + + The `metrics` argument must be a dict, mapping glyph names to + `(height, topSidebearing)` tuples. + """ + self.setupMetrics("vmtx", metrics) + + def setupMetrics(self, tableTag, metrics): + """See `setupHorizontalMetrics()` and `setupVerticalMetrics()`.""" + assert tableTag in ("hmtx", "vmtx") + mtxTable = self.font[tableTag] = newTable(tableTag) + roundedMetrics = {} + for gn in metrics: + w, lsb = metrics[gn] + roundedMetrics[gn] = int(round(w)), int(round(lsb)) + mtxTable.metrics = roundedMetrics + + def setupHorizontalHeader(self, **values): + """Create a new `hhea` table initialize it with default values, + which can be overridden by keyword arguments. + """ + self._initTableWithValues("hhea", _hheaDefaults, values) + + def setupVerticalHeader(self, **values): + """Create a new `vhea` table initialize it with default values, + which can be overridden by keyword arguments. + """ + self._initTableWithValues("vhea", _vheaDefaults, values) + + def setupVerticalOrigins(self, verticalOrigins, defaultVerticalOrigin=None): + """Create a new `VORG` table. The `verticalOrigins` argument must be + a dict, mapping glyph names to vertical origin values. + + The `defaultVerticalOrigin` argument should be the most common vertical + origin value. If omitted, this value will be derived from the actual + values in the `verticalOrigins` argument. + """ + if defaultVerticalOrigin is None: + # find the most frequent vorg value + bag = {} + for gn in verticalOrigins: + vorg = verticalOrigins[gn] + if vorg not in bag: + bag[vorg] = 1 + else: + bag[vorg] += 1 + defaultVerticalOrigin = sorted( + bag, key=lambda vorg: bag[vorg], reverse=True + )[0] + self._initTableWithValues( + "VORG", + {}, + dict(VOriginRecords={}, defaultVertOriginY=defaultVerticalOrigin), + ) + vorgTable = self.font["VORG"] + vorgTable.majorVersion = 1 + vorgTable.minorVersion = 0 + for gn in verticalOrigins: + vorgTable[gn] = verticalOrigins[gn] + + def setupPost(self, keepGlyphNames=True, **values): + """Create a new `post` table and initialize it with default values, + which can be overridden by keyword arguments. + """ + isCFF2 = "CFF2" in self.font + postTable = self._initTableWithValues("post", _postDefaults, values) + if (self.isTTF or isCFF2) and keepGlyphNames: + postTable.formatType = 2.0 + postTable.extraNames = [] + postTable.mapping = {} + else: + postTable.formatType = 3.0 + + def setupMaxp(self): + """Create a new `maxp` table. This is called implicitly by FontBuilder + itself and is usually not called by client code. + """ + if self.isTTF: + defaults = _maxpDefaultsTTF + else: + defaults = _maxpDefaultsOTF + self._initTableWithValues("maxp", defaults, {}) + + def setupDummyDSIG(self): + """This adds an empty DSIG table to the font to make some MS applications + happy. This does not properly sign the font. + """ + values = dict( + ulVersion=1, + usFlag=0, + usNumSigs=0, + signatureRecords=[], + ) + self._initTableWithValues("DSIG", {}, values) + + def addOpenTypeFeatures(self, features, filename=None, tables=None, debug=False): + """Add OpenType features to the font from a string containing + Feature File syntax. + + The `filename` argument is used in error messages and to determine + where to look for "include" files. + + The optional `tables` argument can be a list of OTL tables tags to + build, allowing the caller to only build selected OTL tables. See + `fontTools.feaLib` for details. + + The optional `debug` argument controls whether to add source debugging + information to the font in the `Debg` table. + """ + from .feaLib.builder import addOpenTypeFeaturesFromString + + addOpenTypeFeaturesFromString( + self.font, features, filename=filename, tables=tables, debug=debug + ) + + def addFeatureVariations(self, conditionalSubstitutions, featureTag="rvrn"): + """Add conditional substitutions to a Variable Font. + + See `fontTools.varLib.featureVars.addFeatureVariations`. + """ + from .varLib import featureVars + + if "fvar" not in self.font: + raise KeyError("'fvar' table is missing; can't add FeatureVariations.") + + featureVars.addFeatureVariations( + self.font, conditionalSubstitutions, featureTag=featureTag + ) + + def setupCOLR( + self, + colorLayers, + version=None, + varStore=None, + varIndexMap=None, + clipBoxes=None, + allowLayerReuse=True, + ): + """Build new COLR table using color layers dictionary. + + Cf. `fontTools.colorLib.builder.buildCOLR`. + """ + from fontTools.colorLib.builder import buildCOLR + + glyphMap = self.font.getReverseGlyphMap() + self.font["COLR"] = buildCOLR( + colorLayers, + version=version, + glyphMap=glyphMap, + varStore=varStore, + varIndexMap=varIndexMap, + clipBoxes=clipBoxes, + allowLayerReuse=allowLayerReuse, + ) + + def setupCPAL( + self, + palettes, + paletteTypes=None, + paletteLabels=None, + paletteEntryLabels=None, + ): + """Build new CPAL table using list of palettes. + + Optionally build CPAL v1 table using paletteTypes, paletteLabels and + paletteEntryLabels. + + Cf. `fontTools.colorLib.builder.buildCPAL`. + """ + from fontTools.colorLib.builder import buildCPAL + + self.font["CPAL"] = buildCPAL( + palettes, + paletteTypes=paletteTypes, + paletteLabels=paletteLabels, + paletteEntryLabels=paletteEntryLabels, + nameTable=self.font.get("name"), + ) + + def setupStat(self, axes, locations=None, elidedFallbackName=2): + """Build a new 'STAT' table. + + See `fontTools.otlLib.builder.buildStatTable` for details about + the arguments. + """ + from .otlLib.builder import buildStatTable + + buildStatTable(self.font, axes, locations, elidedFallbackName) + + +def buildCmapSubTable(cmapping, format, platformID, platEncID): + subTable = cmap_classes[format](format) + subTable.cmap = cmapping + subTable.platformID = platformID + subTable.platEncID = platEncID + subTable.language = 0 + return subTable + + +def addFvar(font, axes, instances): + from .ttLib.tables._f_v_a_r import Axis, NamedInstance + + assert axes + + fvar = newTable("fvar") + nameTable = font["name"] + + for axis_def in axes: + axis = Axis() + + if isinstance(axis_def, tuple): + ( + axis.axisTag, + axis.minValue, + axis.defaultValue, + axis.maxValue, + name, + ) = axis_def + else: + (axis.axisTag, axis.minValue, axis.defaultValue, axis.maxValue, name) = ( + axis_def.tag, + axis_def.minimum, + axis_def.default, + axis_def.maximum, + axis_def.name, + ) + if axis_def.hidden: + axis.flags = 0x0001 # HIDDEN_AXIS + + if isinstance(name, str): + name = dict(en=name) + + axis.axisNameID = nameTable.addMultilingualName(name, ttFont=font) + fvar.axes.append(axis) + + for instance in instances: + if isinstance(instance, dict): + coordinates = instance["location"] + name = instance["stylename"] + psname = instance.get("postscriptfontname") + else: + coordinates = instance.location + name = instance.localisedStyleName or instance.styleName + psname = instance.postScriptFontName + + if isinstance(name, str): + name = dict(en=name) + + inst = NamedInstance() + inst.subfamilyNameID = nameTable.addMultilingualName(name, ttFont=font) + if psname is not None: + inst.postscriptNameID = nameTable.addName(psname) + inst.coordinates = coordinates + fvar.instances.append(inst) + + font["fvar"] = fvar diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/help.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/help.py new file mode 100644 index 00000000..2a238de3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/help.py @@ -0,0 +1,35 @@ +import pkgutil +import sys +import fontTools +import importlib +import os +from pathlib import Path + + +def main(): + """Show this help""" + path = fontTools.__path__ + descriptions = {} + for pkg in sorted( + mod.name + for mod in pkgutil.walk_packages([fontTools.__path__[0]], prefix="fontTools.") + ): + try: + imports = __import__(pkg, globals(), locals(), ["main"]) + except ImportError as e: + continue + try: + description = imports.main.__doc__ + if description: + pkg = pkg.replace("fontTools.", "").replace(".__main__", "") + # show the docstring's first line only + descriptions[pkg] = description.splitlines()[0] + except AttributeError as e: + pass + for pkg, description in descriptions.items(): + print("fonttools %-25s %s" % (pkg, description), file=sys.stderr) + + +if __name__ == "__main__": + print("fonttools v%s\n" % fontTools.__version__, file=sys.stderr) + main() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__init__.py new file mode 100644 index 00000000..8d8a5213 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__init__.py @@ -0,0 +1,210 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools import ttLib +import fontTools.merge.base +from fontTools.merge.cmap import ( + computeMegaGlyphOrder, + computeMegaCmap, + renameCFFCharStrings, +) +from fontTools.merge.layout import layoutPreMerge, layoutPostMerge +from fontTools.merge.options import Options +import fontTools.merge.tables +from fontTools.misc.loggingTools import Timer +from functools import reduce +import sys +import logging + + +log = logging.getLogger("fontTools.merge") +timer = Timer(logger=logging.getLogger(__name__ + ".timer"), level=logging.INFO) + + +class Merger(object): + """Font merger. + + This class merges multiple files into a single OpenType font, taking into + account complexities such as OpenType layout (``GSUB``/``GPOS``) tables and + cross-font metrics (e.g. ``hhea.ascent`` is set to the maximum value across + all the fonts). + + If multiple glyphs map to the same Unicode value, and the glyphs are considered + sufficiently different (that is, they differ in any of paths, widths, or + height), then subsequent glyphs are renamed and a lookup in the ``locl`` + feature will be created to disambiguate them. For example, if the arguments + are an Arabic font and a Latin font and both contain a set of parentheses, + the Latin glyphs will be renamed to ``parenleft#1`` and ``parenright#1``, + and a lookup will be inserted into the to ``locl`` feature (creating it if + necessary) under the ``latn`` script to substitute ``parenleft`` with + ``parenleft#1`` etc. + + Restrictions: + + - All fonts must have the same units per em. + - If duplicate glyph disambiguation takes place as described above then the + fonts must have a ``GSUB`` table. + + Attributes: + options: Currently unused. + """ + + def __init__(self, options=None): + if not options: + options = Options() + + self.options = options + + def _openFonts(self, fontfiles): + fonts = [ttLib.TTFont(fontfile) for fontfile in fontfiles] + for font, fontfile in zip(fonts, fontfiles): + font._merger__fontfile = fontfile + font._merger__name = font["name"].getDebugName(4) + return fonts + + def merge(self, fontfiles): + """Merges fonts together. + + Args: + fontfiles: A list of file names to be merged + + Returns: + A :class:`fontTools.ttLib.TTFont` object. Call the ``save`` method on + this to write it out to an OTF file. + """ + # + # Settle on a mega glyph order. + # + fonts = self._openFonts(fontfiles) + glyphOrders = [list(font.getGlyphOrder()) for font in fonts] + computeMegaGlyphOrder(self, glyphOrders) + + # Take first input file sfntVersion + sfntVersion = fonts[0].sfntVersion + + # Reload fonts and set new glyph names on them. + fonts = self._openFonts(fontfiles) + for font, glyphOrder in zip(fonts, glyphOrders): + font.setGlyphOrder(glyphOrder) + if "CFF " in font: + renameCFFCharStrings(self, glyphOrder, font["CFF "]) + + cmaps = [font["cmap"] for font in fonts] + self.duplicateGlyphsPerFont = [{} for _ in fonts] + computeMegaCmap(self, cmaps) + + mega = ttLib.TTFont(sfntVersion=sfntVersion) + mega.setGlyphOrder(self.glyphOrder) + + for font in fonts: + self._preMerge(font) + + self.fonts = fonts + + allTags = reduce(set.union, (list(font.keys()) for font in fonts), set()) + allTags.remove("GlyphOrder") + + for tag in sorted(allTags): + if tag in self.options.drop_tables: + continue + + with timer("merge '%s'" % tag): + tables = [font.get(tag, NotImplemented) for font in fonts] + + log.info("Merging '%s'.", tag) + clazz = ttLib.getTableClass(tag) + table = clazz(tag).merge(self, tables) + # XXX Clean this up and use: table = mergeObjects(tables) + + if table is not NotImplemented and table is not False: + mega[tag] = table + log.info("Merged '%s'.", tag) + else: + log.info("Dropped '%s'.", tag) + + del self.duplicateGlyphsPerFont + del self.fonts + + self._postMerge(mega) + + return mega + + def mergeObjects(self, returnTable, logic, tables): + # Right now we don't use self at all. Will use in the future + # for options and logging. + + allKeys = set.union( + set(), + *(vars(table).keys() for table in tables if table is not NotImplemented), + ) + for key in allKeys: + try: + mergeLogic = logic[key] + except KeyError: + try: + mergeLogic = logic["*"] + except KeyError: + raise Exception( + "Don't know how to merge key %s of class %s" + % (key, returnTable.__class__.__name__) + ) + if mergeLogic is NotImplemented: + continue + value = mergeLogic(getattr(table, key, NotImplemented) for table in tables) + if value is not NotImplemented: + setattr(returnTable, key, value) + + return returnTable + + def _preMerge(self, font): + layoutPreMerge(font) + + def _postMerge(self, font): + layoutPostMerge(font) + + if "OS/2" in font: + # https://github.com/fonttools/fonttools/issues/2538 + # TODO: Add an option to disable this? + font["OS/2"].recalcAvgCharWidth(font) + + +__all__ = ["Options", "Merger", "main"] + + +@timer("make one with everything (TOTAL TIME)") +def main(args=None): + """Merge multiple fonts into one""" + from fontTools import configLogger + + if args is None: + args = sys.argv[1:] + + options = Options() + args = options.parse_opts(args, ignore_unknown=["output-file"]) + outfile = "merged.ttf" + fontfiles = [] + for g in args: + if g.startswith("--output-file="): + outfile = g[14:] + continue + fontfiles.append(g) + + if len(args) < 1: + print("usage: pyftmerge font...", file=sys.stderr) + return 1 + + configLogger(level=logging.INFO if options.verbose else logging.WARNING) + if options.timing: + timer.logger.setLevel(logging.DEBUG) + else: + timer.logger.disabled = True + + merger = Merger(options=options) + font = merger.merge(fontfiles) + with timer("compile and save font"): + font.save(outfile) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__main__.py new file mode 100644 index 00000000..ff632d49 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/__main__.py @@ -0,0 +1,6 @@ +import sys +from fontTools.merge import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/base.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/base.py new file mode 100644 index 00000000..37f9097a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/base.py @@ -0,0 +1,81 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools.ttLib.tables.DefaultTable import DefaultTable +import logging + + +log = logging.getLogger("fontTools.merge") + + +def add_method(*clazzes, **kwargs): + """Returns a decorator function that adds a new method to one or + more classes.""" + allowDefault = kwargs.get("allowDefaultTable", False) + + def wrapper(method): + done = [] + for clazz in clazzes: + if clazz in done: + continue # Support multiple names of a clazz + done.append(clazz) + assert allowDefault or clazz != DefaultTable, "Oops, table class not found." + assert ( + method.__name__ not in clazz.__dict__ + ), "Oops, class '%s' has method '%s'." % (clazz.__name__, method.__name__) + setattr(clazz, method.__name__, method) + return None + + return wrapper + + +def mergeObjects(lst): + lst = [item for item in lst if item is not NotImplemented] + if not lst: + return NotImplemented + lst = [item for item in lst if item is not None] + if not lst: + return None + + clazz = lst[0].__class__ + assert all(type(item) == clazz for item in lst), lst + + logic = clazz.mergeMap + returnTable = clazz() + returnDict = {} + + allKeys = set.union(set(), *(vars(table).keys() for table in lst)) + for key in allKeys: + try: + mergeLogic = logic[key] + except KeyError: + try: + mergeLogic = logic["*"] + except KeyError: + raise Exception( + "Don't know how to merge key %s of class %s" % (key, clazz.__name__) + ) + if mergeLogic is NotImplemented: + continue + value = mergeLogic(getattr(table, key, NotImplemented) for table in lst) + if value is not NotImplemented: + returnDict[key] = value + + returnTable.__dict__ = returnDict + + return returnTable + + +@add_method(DefaultTable, allowDefaultTable=True) +def merge(self, m, tables): + if not hasattr(self, "mergeMap"): + log.info("Don't know how to merge '%s'.", self.tableTag) + return NotImplemented + + logic = self.mergeMap + + if isinstance(logic, dict): + return m.mergeObjects(self, self.mergeMap, tables) + else: + return logic(tables) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/cmap.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/cmap.py new file mode 100644 index 00000000..3209a5d7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/cmap.py @@ -0,0 +1,141 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools.merge.unicode import is_Default_Ignorable +from fontTools.pens.recordingPen import DecomposingRecordingPen +import logging + + +log = logging.getLogger("fontTools.merge") + + +def computeMegaGlyphOrder(merger, glyphOrders): + """Modifies passed-in glyphOrders to reflect new glyph names. + Stores merger.glyphOrder.""" + megaOrder = {} + for glyphOrder in glyphOrders: + for i, glyphName in enumerate(glyphOrder): + if glyphName in megaOrder: + n = megaOrder[glyphName] + while (glyphName + "." + repr(n)) in megaOrder: + n += 1 + megaOrder[glyphName] = n + glyphName += "." + repr(n) + glyphOrder[i] = glyphName + megaOrder[glyphName] = 1 + merger.glyphOrder = megaOrder = list(megaOrder.keys()) + + +def _glyphsAreSame( + glyphSet1, + glyphSet2, + glyph1, + glyph2, + advanceTolerance=0.05, + advanceToleranceEmpty=0.20, +): + pen1 = DecomposingRecordingPen(glyphSet1) + pen2 = DecomposingRecordingPen(glyphSet2) + g1 = glyphSet1[glyph1] + g2 = glyphSet2[glyph2] + g1.draw(pen1) + g2.draw(pen2) + if pen1.value != pen2.value: + return False + # Allow more width tolerance for glyphs with no ink + tolerance = advanceTolerance if pen1.value else advanceToleranceEmpty + # TODO Warn if advances not the same but within tolerance. + if abs(g1.width - g2.width) > g1.width * tolerance: + return False + if hasattr(g1, "height") and g1.height is not None: + if abs(g1.height - g2.height) > g1.height * tolerance: + return False + return True + + +# Valid (format, platformID, platEncID) triplets for cmap subtables containing +# Unicode BMP-only and Unicode Full Repertoire semantics. +# Cf. OpenType spec for "Platform specific encodings": +# https://docs.microsoft.com/en-us/typography/opentype/spec/name +class _CmapUnicodePlatEncodings: + BMP = {(4, 3, 1), (4, 0, 3), (4, 0, 4), (4, 0, 6)} + FullRepertoire = {(12, 3, 10), (12, 0, 4), (12, 0, 6)} + + +def computeMegaCmap(merger, cmapTables): + """Sets merger.cmap and merger.glyphOrder.""" + + # TODO Handle format=14. + # Only merge format 4 and 12 Unicode subtables, ignores all other subtables + # If there is a format 12 table for a font, ignore the format 4 table of it + chosenCmapTables = [] + for fontIdx, table in enumerate(cmapTables): + format4 = None + format12 = None + for subtable in table.tables: + properties = (subtable.format, subtable.platformID, subtable.platEncID) + if properties in _CmapUnicodePlatEncodings.BMP: + format4 = subtable + elif properties in _CmapUnicodePlatEncodings.FullRepertoire: + format12 = subtable + else: + log.warning( + "Dropped cmap subtable from font '%s':\t" + "format %2s, platformID %2s, platEncID %2s", + fontIdx, + subtable.format, + subtable.platformID, + subtable.platEncID, + ) + if format12 is not None: + chosenCmapTables.append((format12, fontIdx)) + elif format4 is not None: + chosenCmapTables.append((format4, fontIdx)) + + # Build the unicode mapping + merger.cmap = cmap = {} + fontIndexForGlyph = {} + glyphSets = [None for f in merger.fonts] if hasattr(merger, "fonts") else None + + for table, fontIdx in chosenCmapTables: + # handle duplicates + for uni, gid in table.cmap.items(): + oldgid = cmap.get(uni, None) + if oldgid is None: + cmap[uni] = gid + fontIndexForGlyph[gid] = fontIdx + elif is_Default_Ignorable(uni) or uni in (0x25CC,): # U+25CC DOTTED CIRCLE + continue + elif oldgid != gid: + # Char previously mapped to oldgid, now to gid. + # Record, to fix up in GSUB 'locl' later. + if merger.duplicateGlyphsPerFont[fontIdx].get(oldgid) is None: + if glyphSets is not None: + oldFontIdx = fontIndexForGlyph[oldgid] + for idx in (fontIdx, oldFontIdx): + if glyphSets[idx] is None: + glyphSets[idx] = merger.fonts[idx].getGlyphSet() + # if _glyphsAreSame(glyphSets[oldFontIdx], glyphSets[fontIdx], oldgid, gid): + # continue + merger.duplicateGlyphsPerFont[fontIdx][oldgid] = gid + elif merger.duplicateGlyphsPerFont[fontIdx][oldgid] != gid: + # Char previously mapped to oldgid but oldgid is already remapped to a different + # gid, because of another Unicode character. + # TODO: Try harder to do something about these. + log.warning( + "Dropped mapping from codepoint %#06X to glyphId '%s'", uni, gid + ) + + +def renameCFFCharStrings(merger, glyphOrder, cffTable): + """Rename topDictIndex charStrings based on glyphOrder.""" + td = cffTable.cff.topDictIndex[0] + + charStrings = {} + for i, v in enumerate(td.CharStrings.charStrings.values()): + glyphName = glyphOrder[i] + charStrings[glyphName] = v + td.CharStrings.charStrings = charStrings + + td.charset = list(glyphOrder) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/layout.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/layout.py new file mode 100644 index 00000000..6b85cd50 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/layout.py @@ -0,0 +1,530 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools import ttLib +from fontTools.ttLib.tables.DefaultTable import DefaultTable +from fontTools.ttLib.tables import otTables +from fontTools.merge.base import add_method, mergeObjects +from fontTools.merge.util import * +import logging + + +log = logging.getLogger("fontTools.merge") + + +def mergeLookupLists(lst): + # TODO Do smarter merge. + return sumLists(lst) + + +def mergeFeatures(lst): + assert lst + self = otTables.Feature() + self.FeatureParams = None + self.LookupListIndex = mergeLookupLists( + [l.LookupListIndex for l in lst if l.LookupListIndex] + ) + self.LookupCount = len(self.LookupListIndex) + return self + + +def mergeFeatureLists(lst): + d = {} + for l in lst: + for f in l: + tag = f.FeatureTag + if tag not in d: + d[tag] = [] + d[tag].append(f.Feature) + ret = [] + for tag in sorted(d.keys()): + rec = otTables.FeatureRecord() + rec.FeatureTag = tag + rec.Feature = mergeFeatures(d[tag]) + ret.append(rec) + return ret + + +def mergeLangSyses(lst): + assert lst + + # TODO Support merging ReqFeatureIndex + assert all(l.ReqFeatureIndex == 0xFFFF for l in lst) + + self = otTables.LangSys() + self.LookupOrder = None + self.ReqFeatureIndex = 0xFFFF + self.FeatureIndex = mergeFeatureLists( + [l.FeatureIndex for l in lst if l.FeatureIndex] + ) + self.FeatureCount = len(self.FeatureIndex) + return self + + +def mergeScripts(lst): + assert lst + + if len(lst) == 1: + return lst[0] + langSyses = {} + for sr in lst: + for lsr in sr.LangSysRecord: + if lsr.LangSysTag not in langSyses: + langSyses[lsr.LangSysTag] = [] + langSyses[lsr.LangSysTag].append(lsr.LangSys) + lsrecords = [] + for tag, langSys_list in sorted(langSyses.items()): + lsr = otTables.LangSysRecord() + lsr.LangSys = mergeLangSyses(langSys_list) + lsr.LangSysTag = tag + lsrecords.append(lsr) + + self = otTables.Script() + self.LangSysRecord = lsrecords + self.LangSysCount = len(lsrecords) + dfltLangSyses = [s.DefaultLangSys for s in lst if s.DefaultLangSys] + if dfltLangSyses: + self.DefaultLangSys = mergeLangSyses(dfltLangSyses) + else: + self.DefaultLangSys = None + return self + + +def mergeScriptRecords(lst): + d = {} + for l in lst: + for s in l: + tag = s.ScriptTag + if tag not in d: + d[tag] = [] + d[tag].append(s.Script) + ret = [] + for tag in sorted(d.keys()): + rec = otTables.ScriptRecord() + rec.ScriptTag = tag + rec.Script = mergeScripts(d[tag]) + ret.append(rec) + return ret + + +otTables.ScriptList.mergeMap = { + "ScriptCount": lambda lst: None, # TODO + "ScriptRecord": mergeScriptRecords, +} +otTables.BaseScriptList.mergeMap = { + "BaseScriptCount": lambda lst: None, # TODO + # TODO: Merge duplicate entries + "BaseScriptRecord": lambda lst: sorted( + sumLists(lst), key=lambda s: s.BaseScriptTag + ), +} + +otTables.FeatureList.mergeMap = { + "FeatureCount": sum, + "FeatureRecord": lambda lst: sorted(sumLists(lst), key=lambda s: s.FeatureTag), +} + +otTables.LookupList.mergeMap = { + "LookupCount": sum, + "Lookup": sumLists, +} + +otTables.Coverage.mergeMap = { + "Format": min, + "glyphs": sumLists, +} + +otTables.ClassDef.mergeMap = { + "Format": min, + "classDefs": sumDicts, +} + +otTables.LigCaretList.mergeMap = { + "Coverage": mergeObjects, + "LigGlyphCount": sum, + "LigGlyph": sumLists, +} + +otTables.AttachList.mergeMap = { + "Coverage": mergeObjects, + "GlyphCount": sum, + "AttachPoint": sumLists, +} + +# XXX Renumber MarkFilterSets of lookups +otTables.MarkGlyphSetsDef.mergeMap = { + "MarkSetTableFormat": equal, + "MarkSetCount": sum, + "Coverage": sumLists, +} + +otTables.Axis.mergeMap = { + "*": mergeObjects, +} + +# XXX Fix BASE table merging +otTables.BaseTagList.mergeMap = { + "BaseTagCount": sum, + "BaselineTag": sumLists, +} + +otTables.GDEF.mergeMap = ( + otTables.GSUB.mergeMap +) = ( + otTables.GPOS.mergeMap +) = otTables.BASE.mergeMap = otTables.JSTF.mergeMap = otTables.MATH.mergeMap = { + "*": mergeObjects, + "Version": max, +} + +ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass( + "GSUB" +).mergeMap = ttLib.getTableClass("GPOS").mergeMap = ttLib.getTableClass( + "BASE" +).mergeMap = ttLib.getTableClass( + "JSTF" +).mergeMap = ttLib.getTableClass( + "MATH" +).mergeMap = { + "tableTag": onlyExisting(equal), # XXX clean me up + "table": mergeObjects, +} + + +@add_method(ttLib.getTableClass("GSUB")) +def merge(self, m, tables): + assert len(tables) == len(m.duplicateGlyphsPerFont) + for i, (table, dups) in enumerate(zip(tables, m.duplicateGlyphsPerFont)): + if not dups: + continue + if table is None or table is NotImplemented: + log.warning( + "Have non-identical duplicates to resolve for '%s' but no GSUB. Are duplicates intended?: %s", + m.fonts[i]._merger__name, + dups, + ) + continue + + synthFeature = None + synthLookup = None + for script in table.table.ScriptList.ScriptRecord: + if script.ScriptTag == "DFLT": + continue # XXX + for langsys in [script.Script.DefaultLangSys] + [ + l.LangSys for l in script.Script.LangSysRecord + ]: + if langsys is None: + continue # XXX Create! + feature = [v for v in langsys.FeatureIndex if v.FeatureTag == "locl"] + assert len(feature) <= 1 + if feature: + feature = feature[0] + else: + if not synthFeature: + synthFeature = otTables.FeatureRecord() + synthFeature.FeatureTag = "locl" + f = synthFeature.Feature = otTables.Feature() + f.FeatureParams = None + f.LookupCount = 0 + f.LookupListIndex = [] + table.table.FeatureList.FeatureRecord.append(synthFeature) + table.table.FeatureList.FeatureCount += 1 + feature = synthFeature + langsys.FeatureIndex.append(feature) + langsys.FeatureIndex.sort(key=lambda v: v.FeatureTag) + + if not synthLookup: + subtable = otTables.SingleSubst() + subtable.mapping = dups + synthLookup = otTables.Lookup() + synthLookup.LookupFlag = 0 + synthLookup.LookupType = 1 + synthLookup.SubTableCount = 1 + synthLookup.SubTable = [subtable] + if table.table.LookupList is None: + # mtiLib uses None as default value for LookupList, + # while feaLib points to an empty array with count 0 + # TODO: make them do the same + table.table.LookupList = otTables.LookupList() + table.table.LookupList.Lookup = [] + table.table.LookupList.LookupCount = 0 + table.table.LookupList.Lookup.append(synthLookup) + table.table.LookupList.LookupCount += 1 + + if feature.Feature.LookupListIndex[:1] != [synthLookup]: + feature.Feature.LookupListIndex[:0] = [synthLookup] + feature.Feature.LookupCount += 1 + + DefaultTable.merge(self, m, tables) + return self + + +@add_method( + otTables.SingleSubst, + otTables.MultipleSubst, + otTables.AlternateSubst, + otTables.LigatureSubst, + otTables.ReverseChainSingleSubst, + otTables.SinglePos, + otTables.PairPos, + otTables.CursivePos, + otTables.MarkBasePos, + otTables.MarkLigPos, + otTables.MarkMarkPos, +) +def mapLookups(self, lookupMap): + pass + + +# Copied and trimmed down from subset.py +@add_method( + otTables.ContextSubst, + otTables.ChainContextSubst, + otTables.ContextPos, + otTables.ChainContextPos, +) +def __merge_classify_context(self): + class ContextHelper(object): + def __init__(self, klass, Format): + if klass.__name__.endswith("Subst"): + Typ = "Sub" + Type = "Subst" + else: + Typ = "Pos" + Type = "Pos" + if klass.__name__.startswith("Chain"): + Chain = "Chain" + else: + Chain = "" + ChainTyp = Chain + Typ + + self.Typ = Typ + self.Type = Type + self.Chain = Chain + self.ChainTyp = ChainTyp + + self.LookupRecord = Type + "LookupRecord" + + if Format == 1: + self.Rule = ChainTyp + "Rule" + self.RuleSet = ChainTyp + "RuleSet" + elif Format == 2: + self.Rule = ChainTyp + "ClassRule" + self.RuleSet = ChainTyp + "ClassSet" + + if self.Format not in [1, 2, 3]: + return None # Don't shoot the messenger; let it go + if not hasattr(self.__class__, "_merge__ContextHelpers"): + self.__class__._merge__ContextHelpers = {} + if self.Format not in self.__class__._merge__ContextHelpers: + helper = ContextHelper(self.__class__, self.Format) + self.__class__._merge__ContextHelpers[self.Format] = helper + return self.__class__._merge__ContextHelpers[self.Format] + + +@add_method( + otTables.ContextSubst, + otTables.ChainContextSubst, + otTables.ContextPos, + otTables.ChainContextPos, +) +def mapLookups(self, lookupMap): + c = self.__merge_classify_context() + + if self.Format in [1, 2]: + for rs in getattr(self, c.RuleSet): + if not rs: + continue + for r in getattr(rs, c.Rule): + if not r: + continue + for ll in getattr(r, c.LookupRecord): + if not ll: + continue + ll.LookupListIndex = lookupMap[ll.LookupListIndex] + elif self.Format == 3: + for ll in getattr(self, c.LookupRecord): + if not ll: + continue + ll.LookupListIndex = lookupMap[ll.LookupListIndex] + else: + assert 0, "unknown format: %s" % self.Format + + +@add_method(otTables.ExtensionSubst, otTables.ExtensionPos) +def mapLookups(self, lookupMap): + if self.Format == 1: + self.ExtSubTable.mapLookups(lookupMap) + else: + assert 0, "unknown format: %s" % self.Format + + +@add_method(otTables.Lookup) +def mapLookups(self, lookupMap): + for st in self.SubTable: + if not st: + continue + st.mapLookups(lookupMap) + + +@add_method(otTables.LookupList) +def mapLookups(self, lookupMap): + for l in self.Lookup: + if not l: + continue + l.mapLookups(lookupMap) + + +@add_method(otTables.Lookup) +def mapMarkFilteringSets(self, markFilteringSetMap): + if self.LookupFlag & 0x0010: + self.MarkFilteringSet = markFilteringSetMap[self.MarkFilteringSet] + + +@add_method(otTables.LookupList) +def mapMarkFilteringSets(self, markFilteringSetMap): + for l in self.Lookup: + if not l: + continue + l.mapMarkFilteringSets(markFilteringSetMap) + + +@add_method(otTables.Feature) +def mapLookups(self, lookupMap): + self.LookupListIndex = [lookupMap[i] for i in self.LookupListIndex] + + +@add_method(otTables.FeatureList) +def mapLookups(self, lookupMap): + for f in self.FeatureRecord: + if not f or not f.Feature: + continue + f.Feature.mapLookups(lookupMap) + + +@add_method(otTables.DefaultLangSys, otTables.LangSys) +def mapFeatures(self, featureMap): + self.FeatureIndex = [featureMap[i] for i in self.FeatureIndex] + if self.ReqFeatureIndex != 65535: + self.ReqFeatureIndex = featureMap[self.ReqFeatureIndex] + + +@add_method(otTables.Script) +def mapFeatures(self, featureMap): + if self.DefaultLangSys: + self.DefaultLangSys.mapFeatures(featureMap) + for l in self.LangSysRecord: + if not l or not l.LangSys: + continue + l.LangSys.mapFeatures(featureMap) + + +@add_method(otTables.ScriptList) +def mapFeatures(self, featureMap): + for s in self.ScriptRecord: + if not s or not s.Script: + continue + s.Script.mapFeatures(featureMap) + + +def layoutPreMerge(font): + # Map indices to references + + GDEF = font.get("GDEF") + GSUB = font.get("GSUB") + GPOS = font.get("GPOS") + + for t in [GSUB, GPOS]: + if not t: + continue + + if t.table.LookupList: + lookupMap = {i: v for i, v in enumerate(t.table.LookupList.Lookup)} + t.table.LookupList.mapLookups(lookupMap) + t.table.FeatureList.mapLookups(lookupMap) + + if ( + GDEF + and GDEF.table.Version >= 0x00010002 + and GDEF.table.MarkGlyphSetsDef + ): + markFilteringSetMap = { + i: v for i, v in enumerate(GDEF.table.MarkGlyphSetsDef.Coverage) + } + t.table.LookupList.mapMarkFilteringSets(markFilteringSetMap) + + if t.table.FeatureList and t.table.ScriptList: + featureMap = {i: v for i, v in enumerate(t.table.FeatureList.FeatureRecord)} + t.table.ScriptList.mapFeatures(featureMap) + + # TODO FeatureParams nameIDs + + +def layoutPostMerge(font): + # Map references back to indices + + GDEF = font.get("GDEF") + GSUB = font.get("GSUB") + GPOS = font.get("GPOS") + + for t in [GSUB, GPOS]: + if not t: + continue + + if t.table.FeatureList and t.table.ScriptList: + # Collect unregistered (new) features. + featureMap = GregariousIdentityDict(t.table.FeatureList.FeatureRecord) + t.table.ScriptList.mapFeatures(featureMap) + + # Record used features. + featureMap = AttendanceRecordingIdentityDict( + t.table.FeatureList.FeatureRecord + ) + t.table.ScriptList.mapFeatures(featureMap) + usedIndices = featureMap.s + + # Remove unused features + t.table.FeatureList.FeatureRecord = [ + f + for i, f in enumerate(t.table.FeatureList.FeatureRecord) + if i in usedIndices + ] + + # Map back to indices. + featureMap = NonhashableDict(t.table.FeatureList.FeatureRecord) + t.table.ScriptList.mapFeatures(featureMap) + + t.table.FeatureList.FeatureCount = len(t.table.FeatureList.FeatureRecord) + + if t.table.LookupList: + # Collect unregistered (new) lookups. + lookupMap = GregariousIdentityDict(t.table.LookupList.Lookup) + t.table.FeatureList.mapLookups(lookupMap) + t.table.LookupList.mapLookups(lookupMap) + + # Record used lookups. + lookupMap = AttendanceRecordingIdentityDict(t.table.LookupList.Lookup) + t.table.FeatureList.mapLookups(lookupMap) + t.table.LookupList.mapLookups(lookupMap) + usedIndices = lookupMap.s + + # Remove unused lookups + t.table.LookupList.Lookup = [ + l for i, l in enumerate(t.table.LookupList.Lookup) if i in usedIndices + ] + + # Map back to indices. + lookupMap = NonhashableDict(t.table.LookupList.Lookup) + t.table.FeatureList.mapLookups(lookupMap) + t.table.LookupList.mapLookups(lookupMap) + + t.table.LookupList.LookupCount = len(t.table.LookupList.Lookup) + + if GDEF and GDEF.table.Version >= 0x00010002: + markFilteringSetMap = NonhashableDict( + GDEF.table.MarkGlyphSetsDef.Coverage + ) + t.table.LookupList.mapMarkFilteringSets(markFilteringSetMap) + + # TODO FeatureParams nameIDs diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/options.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/options.py new file mode 100644 index 00000000..f1340093 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/options.py @@ -0,0 +1,82 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + + +class Options(object): + class UnknownOptionError(Exception): + pass + + def __init__(self, **kwargs): + self.verbose = False + self.timing = False + self.drop_tables = [] + + self.set(**kwargs) + + def set(self, **kwargs): + for k, v in kwargs.items(): + if not hasattr(self, k): + raise self.UnknownOptionError("Unknown option '%s'" % k) + setattr(self, k, v) + + def parse_opts(self, argv, ignore_unknown=[]): + ret = [] + opts = {} + for a in argv: + orig_a = a + if not a.startswith("--"): + ret.append(a) + continue + a = a[2:] + i = a.find("=") + op = "=" + if i == -1: + if a.startswith("no-"): + k = a[3:] + v = False + else: + k = a + v = True + else: + k = a[:i] + if k[-1] in "-+": + op = k[-1] + "=" # Ops is '-=' or '+=' now. + k = k[:-1] + v = a[i + 1 :] + ok = k + k = k.replace("-", "_") + if not hasattr(self, k): + if ignore_unknown is True or ok in ignore_unknown: + ret.append(orig_a) + continue + else: + raise self.UnknownOptionError("Unknown option '%s'" % a) + + ov = getattr(self, k) + if isinstance(ov, bool): + v = bool(v) + elif isinstance(ov, int): + v = int(v) + elif isinstance(ov, list): + vv = v.split(",") + if vv == [""]: + vv = [] + vv = [int(x, 0) if len(x) and x[0] in "0123456789" else x for x in vv] + if op == "=": + v = vv + elif op == "+=": + v = ov + v.extend(vv) + elif op == "-=": + v = ov + for x in vv: + if x in v: + v.remove(x) + else: + assert 0 + + opts[k] = v + self.set(**opts) + + return ret diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/tables.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/tables.py new file mode 100644 index 00000000..57ed64d3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/tables.py @@ -0,0 +1,339 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools import ttLib, cffLib +from fontTools.misc.psCharStrings import T2WidthExtractor +from fontTools.ttLib.tables.DefaultTable import DefaultTable +from fontTools.merge.base import add_method, mergeObjects +from fontTools.merge.cmap import computeMegaCmap +from fontTools.merge.util import * +import logging + + +log = logging.getLogger("fontTools.merge") + + +ttLib.getTableClass("maxp").mergeMap = { + "*": max, + "tableTag": equal, + "tableVersion": equal, + "numGlyphs": sum, + "maxStorage": first, + "maxFunctionDefs": first, + "maxInstructionDefs": first, + # TODO When we correctly merge hinting data, update these values: + # maxFunctionDefs, maxInstructionDefs, maxSizeOfInstructions +} + +headFlagsMergeBitMap = { + "size": 16, + "*": bitwise_or, + 1: bitwise_and, # Baseline at y = 0 + 2: bitwise_and, # lsb at x = 0 + 3: bitwise_and, # Force ppem to integer values. FIXME? + 5: bitwise_and, # Font is vertical + 6: lambda bit: 0, # Always set to zero + 11: bitwise_and, # Font data is 'lossless' + 13: bitwise_and, # Optimized for ClearType + 14: bitwise_and, # Last resort font. FIXME? equal or first may be better + 15: lambda bit: 0, # Always set to zero +} + +ttLib.getTableClass("head").mergeMap = { + "tableTag": equal, + "tableVersion": max, + "fontRevision": max, + "checkSumAdjustment": lambda lst: 0, # We need *something* here + "magicNumber": equal, + "flags": mergeBits(headFlagsMergeBitMap), + "unitsPerEm": equal, + "created": current_time, + "modified": current_time, + "xMin": min, + "yMin": min, + "xMax": max, + "yMax": max, + "macStyle": first, + "lowestRecPPEM": max, + "fontDirectionHint": lambda lst: 2, + "indexToLocFormat": first, + "glyphDataFormat": equal, +} + +ttLib.getTableClass("hhea").mergeMap = { + "*": equal, + "tableTag": equal, + "tableVersion": max, + "ascent": max, + "descent": min, + "lineGap": max, + "advanceWidthMax": max, + "minLeftSideBearing": min, + "minRightSideBearing": min, + "xMaxExtent": max, + "caretSlopeRise": first, + "caretSlopeRun": first, + "caretOffset": first, + "numberOfHMetrics": recalculate, +} + +ttLib.getTableClass("vhea").mergeMap = { + "*": equal, + "tableTag": equal, + "tableVersion": max, + "ascent": max, + "descent": min, + "lineGap": max, + "advanceHeightMax": max, + "minTopSideBearing": min, + "minBottomSideBearing": min, + "yMaxExtent": max, + "caretSlopeRise": first, + "caretSlopeRun": first, + "caretOffset": first, + "numberOfVMetrics": recalculate, +} + +os2FsTypeMergeBitMap = { + "size": 16, + "*": lambda bit: 0, + 1: bitwise_or, # no embedding permitted + 2: bitwise_and, # allow previewing and printing documents + 3: bitwise_and, # allow editing documents + 8: bitwise_or, # no subsetting permitted + 9: bitwise_or, # no embedding of outlines permitted +} + + +def mergeOs2FsType(lst): + lst = list(lst) + if all(item == 0 for item in lst): + return 0 + + # Compute least restrictive logic for each fsType value + for i in range(len(lst)): + # unset bit 1 (no embedding permitted) if either bit 2 or 3 is set + if lst[i] & 0x000C: + lst[i] &= ~0x0002 + # set bit 2 (allow previewing) if bit 3 is set (allow editing) + elif lst[i] & 0x0008: + lst[i] |= 0x0004 + # set bits 2 and 3 if everything is allowed + elif lst[i] == 0: + lst[i] = 0x000C + + fsType = mergeBits(os2FsTypeMergeBitMap)(lst) + # unset bits 2 and 3 if bit 1 is set (some font is "no embedding") + if fsType & 0x0002: + fsType &= ~0x000C + return fsType + + +ttLib.getTableClass("OS/2").mergeMap = { + "*": first, + "tableTag": equal, + "version": max, + "xAvgCharWidth": first, # Will be recalculated at the end on the merged font + "fsType": mergeOs2FsType, # Will be overwritten + "panose": first, # FIXME: should really be the first Latin font + "ulUnicodeRange1": bitwise_or, + "ulUnicodeRange2": bitwise_or, + "ulUnicodeRange3": bitwise_or, + "ulUnicodeRange4": bitwise_or, + "fsFirstCharIndex": min, + "fsLastCharIndex": max, + "sTypoAscender": max, + "sTypoDescender": min, + "sTypoLineGap": max, + "usWinAscent": max, + "usWinDescent": max, + # Version 1 + "ulCodePageRange1": onlyExisting(bitwise_or), + "ulCodePageRange2": onlyExisting(bitwise_or), + # Version 2, 3, 4 + "sxHeight": onlyExisting(max), + "sCapHeight": onlyExisting(max), + "usDefaultChar": onlyExisting(first), + "usBreakChar": onlyExisting(first), + "usMaxContext": onlyExisting(max), + # version 5 + "usLowerOpticalPointSize": onlyExisting(min), + "usUpperOpticalPointSize": onlyExisting(max), +} + + +@add_method(ttLib.getTableClass("OS/2")) +def merge(self, m, tables): + DefaultTable.merge(self, m, tables) + if self.version < 2: + # bits 8 and 9 are reserved and should be set to zero + self.fsType &= ~0x0300 + if self.version >= 3: + # Only one of bits 1, 2, and 3 may be set. We already take + # care of bit 1 implications in mergeOs2FsType. So unset + # bit 2 if bit 3 is already set. + if self.fsType & 0x0008: + self.fsType &= ~0x0004 + return self + + +ttLib.getTableClass("post").mergeMap = { + "*": first, + "tableTag": equal, + "formatType": max, + "isFixedPitch": min, + "minMemType42": max, + "maxMemType42": lambda lst: 0, + "minMemType1": max, + "maxMemType1": lambda lst: 0, + "mapping": onlyExisting(sumDicts), + "extraNames": lambda lst: [], +} + +ttLib.getTableClass("vmtx").mergeMap = ttLib.getTableClass("hmtx").mergeMap = { + "tableTag": equal, + "metrics": sumDicts, +} + +ttLib.getTableClass("name").mergeMap = { + "tableTag": equal, + "names": first, # FIXME? Does mixing name records make sense? +} + +ttLib.getTableClass("loca").mergeMap = { + "*": recalculate, + "tableTag": equal, +} + +ttLib.getTableClass("glyf").mergeMap = { + "tableTag": equal, + "glyphs": sumDicts, + "glyphOrder": sumLists, + "_reverseGlyphOrder": recalculate, + "axisTags": equal, +} + + +@add_method(ttLib.getTableClass("glyf")) +def merge(self, m, tables): + for i, table in enumerate(tables): + for g in table.glyphs.values(): + if i: + # Drop hints for all but first font, since + # we don't map functions / CVT values. + g.removeHinting() + # Expand composite glyphs to load their + # composite glyph names. + if g.isComposite() or g.isVarComposite(): + g.expand(table) + return DefaultTable.merge(self, m, tables) + + +ttLib.getTableClass("prep").mergeMap = lambda self, lst: first(lst) +ttLib.getTableClass("fpgm").mergeMap = lambda self, lst: first(lst) +ttLib.getTableClass("cvt ").mergeMap = lambda self, lst: first(lst) +ttLib.getTableClass("gasp").mergeMap = lambda self, lst: first( + lst +) # FIXME? Appears irreconcilable + + +@add_method(ttLib.getTableClass("CFF ")) +def merge(self, m, tables): + if any(hasattr(table.cff[0], "FDSelect") for table in tables): + raise NotImplementedError("Merging CID-keyed CFF tables is not supported yet") + + for table in tables: + table.cff.desubroutinize() + + newcff = tables[0] + newfont = newcff.cff[0] + private = newfont.Private + newDefaultWidthX, newNominalWidthX = private.defaultWidthX, private.nominalWidthX + storedNamesStrings = [] + glyphOrderStrings = [] + glyphOrder = set(newfont.getGlyphOrder()) + + for name in newfont.strings.strings: + if name not in glyphOrder: + storedNamesStrings.append(name) + else: + glyphOrderStrings.append(name) + + chrset = list(newfont.charset) + newcs = newfont.CharStrings + log.debug("FONT 0 CharStrings: %d.", len(newcs)) + + for i, table in enumerate(tables[1:], start=1): + font = table.cff[0] + defaultWidthX, nominalWidthX = ( + font.Private.defaultWidthX, + font.Private.nominalWidthX, + ) + widthsDiffer = ( + defaultWidthX != newDefaultWidthX or nominalWidthX != newNominalWidthX + ) + font.Private = private + fontGlyphOrder = set(font.getGlyphOrder()) + for name in font.strings.strings: + if name in fontGlyphOrder: + glyphOrderStrings.append(name) + cs = font.CharStrings + gs = table.cff.GlobalSubrs + log.debug("Font %d CharStrings: %d.", i, len(cs)) + chrset.extend(font.charset) + if newcs.charStringsAreIndexed: + for i, name in enumerate(cs.charStrings, start=len(newcs)): + newcs.charStrings[name] = i + newcs.charStringsIndex.items.append(None) + for name in cs.charStrings: + if widthsDiffer: + c = cs[name] + defaultWidthXToken = object() + extractor = T2WidthExtractor([], [], nominalWidthX, defaultWidthXToken) + extractor.execute(c) + width = extractor.width + if width is not defaultWidthXToken: + c.program.pop(0) + else: + width = defaultWidthX + if width != newDefaultWidthX: + c.program.insert(0, width - newNominalWidthX) + newcs[name] = cs[name] + + newfont.charset = chrset + newfont.numGlyphs = len(chrset) + newfont.strings.strings = glyphOrderStrings + storedNamesStrings + + return newcff + + +@add_method(ttLib.getTableClass("cmap")) +def merge(self, m, tables): + # TODO Handle format=14. + if not hasattr(m, "cmap"): + computeMegaCmap(m, tables) + cmap = m.cmap + + cmapBmpOnly = {uni: gid for uni, gid in cmap.items() if uni <= 0xFFFF} + self.tables = [] + module = ttLib.getTableModule("cmap") + if len(cmapBmpOnly) != len(cmap): + # format-12 required. + cmapTable = module.cmap_classes[12](12) + cmapTable.platformID = 3 + cmapTable.platEncID = 10 + cmapTable.language = 0 + cmapTable.cmap = cmap + self.tables.append(cmapTable) + # always create format-4 + cmapTable = module.cmap_classes[4](4) + cmapTable.platformID = 3 + cmapTable.platEncID = 1 + cmapTable.language = 0 + cmapTable.cmap = cmapBmpOnly + # ordered by platform then encoding + self.tables.insert(0, cmapTable) + self.tableVersion = 0 + self.numSubTables = len(self.tables) + return self diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/unicode.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/unicode.py new file mode 100644 index 00000000..65ae6c49 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/unicode.py @@ -0,0 +1,78 @@ +# Copyright 2021 Behdad Esfahbod. All Rights Reserved. + + +def is_Default_Ignorable(u): + # http://www.unicode.org/reports/tr44/#Default_Ignorable_Code_Point + # + # TODO Move me to unicodedata module and autogenerate. + # + # Unicode 14.0: + # $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/' + # 00AD # Cf SOFT HYPHEN + # 034F # Mn COMBINING GRAPHEME JOINER + # 061C # Cf ARABIC LETTER MARK + # 115F..1160 # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER + # 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + # 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + # 180E # Cf MONGOLIAN VOWEL SEPARATOR + # 180F # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + # 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK + # 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + # 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS + # 2065 # Cn + # 2066..206F # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + # 3164 # Lo HANGUL FILLER + # FE00..FE0F # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + # FEFF # Cf ZERO WIDTH NO-BREAK SPACE + # FFA0 # Lo HALFWIDTH HANGUL FILLER + # FFF0..FFF8 # Cn [9] .. + # 1BCA0..1BCA3 # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + # 1D173..1D17A # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + # E0000 # Cn + # E0001 # Cf LANGUAGE TAG + # E0002..E001F # Cn [30] .. + # E0020..E007F # Cf [96] TAG SPACE..CANCEL TAG + # E0080..E00FF # Cn [128] .. + # E0100..E01EF # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + # E01F0..E0FFF # Cn [3600] .. + return ( + u == 0x00AD + or u == 0x034F # Cf SOFT HYPHEN + or u == 0x061C # Mn COMBINING GRAPHEME JOINER + or 0x115F <= u <= 0x1160 # Cf ARABIC LETTER MARK + or 0x17B4 # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER + <= u + <= 0x17B5 + or 0x180B # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + <= u + <= 0x180D + or u # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + == 0x180E + or u == 0x180F # Cf MONGOLIAN VOWEL SEPARATOR + or 0x200B <= u <= 0x200F # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + or 0x202A <= u <= 0x202E # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK + or 0x2060 # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + <= u + <= 0x2064 + or u == 0x2065 # Cf [5] WORD JOINER..INVISIBLE PLUS + or 0x2066 <= u <= 0x206F # Cn + or u == 0x3164 # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + or 0xFE00 <= u <= 0xFE0F # Lo HANGUL FILLER + or u == 0xFEFF # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + or u == 0xFFA0 # Cf ZERO WIDTH NO-BREAK SPACE + or 0xFFF0 <= u <= 0xFFF8 # Lo HALFWIDTH HANGUL FILLER + or 0x1BCA0 <= u <= 0x1BCA3 # Cn [9] .. + or 0x1D173 # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + <= u + <= 0x1D17A + or u == 0xE0000 # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + or u == 0xE0001 # Cn + or 0xE0002 <= u <= 0xE001F # Cf LANGUAGE TAG + or 0xE0020 <= u <= 0xE007F # Cn [30] .. + or 0xE0080 <= u <= 0xE00FF # Cf [96] TAG SPACE..CANCEL TAG + or 0xE0100 <= u <= 0xE01EF # Cn [128] .. + or 0xE01F0 # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + <= u + <= 0xE0FFF + or False # Cn [3600] .. + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/util.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/util.py new file mode 100644 index 00000000..42fe39d5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/merge/util.py @@ -0,0 +1,143 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod, Roozbeh Pournader + +from fontTools.misc.timeTools import timestampNow +from fontTools.ttLib.tables.DefaultTable import DefaultTable +from functools import reduce +import operator +import logging + + +log = logging.getLogger("fontTools.merge") + + +# General utility functions for merging values from different fonts + + +def equal(lst): + lst = list(lst) + t = iter(lst) + first = next(t) + assert all(item == first for item in t), "Expected all items to be equal: %s" % lst + return first + + +def first(lst): + return next(iter(lst)) + + +def recalculate(lst): + return NotImplemented + + +def current_time(lst): + return timestampNow() + + +def bitwise_and(lst): + return reduce(operator.and_, lst) + + +def bitwise_or(lst): + return reduce(operator.or_, lst) + + +def avg_int(lst): + lst = list(lst) + return sum(lst) // len(lst) + + +def onlyExisting(func): + """Returns a filter func that when called with a list, + only calls func on the non-NotImplemented items of the list, + and only so if there's at least one item remaining. + Otherwise returns NotImplemented.""" + + def wrapper(lst): + items = [item for item in lst if item is not NotImplemented] + return func(items) if items else NotImplemented + + return wrapper + + +def sumLists(lst): + l = [] + for item in lst: + l.extend(item) + return l + + +def sumDicts(lst): + d = {} + for item in lst: + d.update(item) + return d + + +def mergeBits(bitmap): + def wrapper(lst): + lst = list(lst) + returnValue = 0 + for bitNumber in range(bitmap["size"]): + try: + mergeLogic = bitmap[bitNumber] + except KeyError: + try: + mergeLogic = bitmap["*"] + except KeyError: + raise Exception("Don't know how to merge bit %s" % bitNumber) + shiftedBit = 1 << bitNumber + mergedValue = mergeLogic(bool(item & shiftedBit) for item in lst) + returnValue |= mergedValue << bitNumber + return returnValue + + return wrapper + + +class AttendanceRecordingIdentityDict(object): + """A dictionary-like object that records indices of items actually accessed + from a list.""" + + def __init__(self, lst): + self.l = lst + self.d = {id(v): i for i, v in enumerate(lst)} + self.s = set() + + def __getitem__(self, v): + self.s.add(self.d[id(v)]) + return v + + +class GregariousIdentityDict(object): + """A dictionary-like object that welcomes guests without reservations and + adds them to the end of the guest list.""" + + def __init__(self, lst): + self.l = lst + self.s = set(id(v) for v in lst) + + def __getitem__(self, v): + if id(v) not in self.s: + self.s.add(id(v)) + self.l.append(v) + return v + + +class NonhashableDict(object): + """A dictionary-like object mapping objects to values.""" + + def __init__(self, keys, values=None): + if values is None: + self.d = {id(v): i for i, v in enumerate(keys)} + else: + self.d = {id(k): v for k, v in zip(keys, values)} + + def __getitem__(self, k): + return self.d[id(k)] + + def __setitem__(self, k, v): + self.d[id(k)] = v + + def __delitem__(self, k): + del self.d[id(k)] diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/__init__.py new file mode 100644 index 00000000..156cb232 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/__init__.py @@ -0,0 +1 @@ +"""Empty __init__.py file to signal Python this directory is a package.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/arrayTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/arrayTools.py new file mode 100644 index 00000000..ced8d87a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/arrayTools.py @@ -0,0 +1,424 @@ +"""Routines for calculating bounding boxes, point in rectangle calculations and +so on. +""" + +from fontTools.misc.roundTools import otRound +from fontTools.misc.vector import Vector as _Vector +import math +import warnings + + +def calcBounds(array): + """Calculate the bounding rectangle of a 2D points array. + + Args: + array: A sequence of 2D tuples. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + """ + if not array: + return 0, 0, 0, 0 + xs = [x for x, y in array] + ys = [y for x, y in array] + return min(xs), min(ys), max(xs), max(ys) + + +def calcIntBounds(array, round=otRound): + """Calculate the integer bounding rectangle of a 2D points array. + + Values are rounded to closest integer towards ``+Infinity`` using the + :func:`fontTools.misc.fixedTools.otRound` function by default, unless + an optional ``round`` function is passed. + + Args: + array: A sequence of 2D tuples. + round: A rounding function of type ``f(x: float) -> int``. + + Returns: + A four-item tuple of integers representing the bounding rectangle: + ``(xMin, yMin, xMax, yMax)``. + """ + return tuple(round(v) for v in calcBounds(array)) + + +def updateBounds(bounds, p, min=min, max=max): + """Add a point to a bounding rectangle. + + Args: + bounds: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax), or None``. + p: A 2D tuple representing a point. + min,max: functions to compute the minimum and maximum. + + Returns: + The updated bounding rectangle ``(xMin, yMin, xMax, yMax)``. + """ + (x, y) = p + if bounds is None: + return x, y, x, y + xMin, yMin, xMax, yMax = bounds + return min(xMin, x), min(yMin, y), max(xMax, x), max(yMax, y) + + +def pointInRect(p, rect): + """Test if a point is inside a bounding rectangle. + + Args: + p: A 2D tuple representing a point. + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + ``True`` if the point is inside the rectangle, ``False`` otherwise. + """ + (x, y) = p + xMin, yMin, xMax, yMax = rect + return (xMin <= x <= xMax) and (yMin <= y <= yMax) + + +def pointsInRect(array, rect): + """Determine which points are inside a bounding rectangle. + + Args: + array: A sequence of 2D tuples. + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A list containing the points inside the rectangle. + """ + if len(array) < 1: + return [] + xMin, yMin, xMax, yMax = rect + return [(xMin <= x <= xMax) and (yMin <= y <= yMax) for x, y in array] + + +def vectorLength(vector): + """Calculate the length of the given vector. + + Args: + vector: A 2D tuple. + + Returns: + The Euclidean length of the vector. + """ + x, y = vector + return math.sqrt(x**2 + y**2) + + +def asInt16(array): + """Round a list of floats to 16-bit signed integers. + + Args: + array: List of float values. + + Returns: + A list of rounded integers. + """ + return [int(math.floor(i + 0.5)) for i in array] + + +def normRect(rect): + """Normalize a bounding box rectangle. + + This function "turns the rectangle the right way up", so that the following + holds:: + + xMin <= xMax and yMin <= yMax + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A normalized bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return min(xMin, xMax), min(yMin, yMax), max(xMin, xMax), max(yMin, yMax) + + +def scaleRect(rect, x, y): + """Scale a bounding box rectangle. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + x: Factor to scale the rectangle along the X axis. + Y: Factor to scale the rectangle along the Y axis. + + Returns: + A scaled bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin * x, yMin * y, xMax * x, yMax * y + + +def offsetRect(rect, dx, dy): + """Offset a bounding box rectangle. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + dx: Amount to offset the rectangle along the X axis. + dY: Amount to offset the rectangle along the Y axis. + + Returns: + An offset bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin + dx, yMin + dy, xMax + dx, yMax + dy + + +def insetRect(rect, dx, dy): + """Inset a bounding box rectangle on all sides. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + dx: Amount to inset the rectangle along the X axis. + dY: Amount to inset the rectangle along the Y axis. + + Returns: + An inset bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin + dx, yMin + dy, xMax - dx, yMax - dy + + +def sectRect(rect1, rect2): + """Test for rectangle-rectangle intersection. + + Args: + rect1: First bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + rect2: Second bounding rectangle. + + Returns: + A boolean and a rectangle. + If the input rectangles intersect, returns ``True`` and the intersecting + rectangle. Returns ``False`` and ``(0, 0, 0, 0)`` if the input + rectangles don't intersect. + """ + (xMin1, yMin1, xMax1, yMax1) = rect1 + (xMin2, yMin2, xMax2, yMax2) = rect2 + xMin, yMin, xMax, yMax = ( + max(xMin1, xMin2), + max(yMin1, yMin2), + min(xMax1, xMax2), + min(yMax1, yMax2), + ) + if xMin >= xMax or yMin >= yMax: + return False, (0, 0, 0, 0) + return True, (xMin, yMin, xMax, yMax) + + +def unionRect(rect1, rect2): + """Determine union of bounding rectangles. + + Args: + rect1: First bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + rect2: Second bounding rectangle. + + Returns: + The smallest rectangle in which both input rectangles are fully + enclosed. + """ + (xMin1, yMin1, xMax1, yMax1) = rect1 + (xMin2, yMin2, xMax2, yMax2) = rect2 + xMin, yMin, xMax, yMax = ( + min(xMin1, xMin2), + min(yMin1, yMin2), + max(xMax1, xMax2), + max(yMax1, yMax2), + ) + return (xMin, yMin, xMax, yMax) + + +def rectCenter(rect): + """Determine rectangle center. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A 2D tuple representing the point at the center of the rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return (xMin + xMax) / 2, (yMin + yMax) / 2 + + +def rectArea(rect): + """Determine rectangle area. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + The area of the rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return (yMax - yMin) * (xMax - xMin) + + +def intRect(rect): + """Round a rectangle to integer values. + + Guarantees that the resulting rectangle is NOT smaller than the original. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A rounded bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + xMin = int(math.floor(xMin)) + yMin = int(math.floor(yMin)) + xMax = int(math.ceil(xMax)) + yMax = int(math.ceil(yMax)) + return (xMin, yMin, xMax, yMax) + + +def quantizeRect(rect, factor=1): + """ + >>> bounds = (72.3, -218.4, 1201.3, 919.1) + >>> quantizeRect(bounds) + (72, -219, 1202, 920) + >>> quantizeRect(bounds, factor=10) + (70, -220, 1210, 920) + >>> quantizeRect(bounds, factor=100) + (0, -300, 1300, 1000) + """ + if factor < 1: + raise ValueError(f"Expected quantization factor >= 1, found: {factor!r}") + xMin, yMin, xMax, yMax = normRect(rect) + return ( + int(math.floor(xMin / factor) * factor), + int(math.floor(yMin / factor) * factor), + int(math.ceil(xMax / factor) * factor), + int(math.ceil(yMax / factor) * factor), + ) + + +class Vector(_Vector): + def __init__(self, *args, **kwargs): + warnings.warn( + "fontTools.misc.arrayTools.Vector has been deprecated, please use " + "fontTools.misc.vector.Vector instead.", + DeprecationWarning, + ) + + +def pairwise(iterable, reverse=False): + """Iterate over current and next items in iterable. + + Args: + iterable: An iterable + reverse: If true, iterate in reverse order. + + Returns: + A iterable yielding two elements per iteration. + + Example: + + >>> tuple(pairwise([])) + () + >>> tuple(pairwise([], reverse=True)) + () + >>> tuple(pairwise([0])) + ((0, 0),) + >>> tuple(pairwise([0], reverse=True)) + ((0, 0),) + >>> tuple(pairwise([0, 1])) + ((0, 1), (1, 0)) + >>> tuple(pairwise([0, 1], reverse=True)) + ((1, 0), (0, 1)) + >>> tuple(pairwise([0, 1, 2])) + ((0, 1), (1, 2), (2, 0)) + >>> tuple(pairwise([0, 1, 2], reverse=True)) + ((2, 1), (1, 0), (0, 2)) + >>> tuple(pairwise(['a', 'b', 'c', 'd'])) + (('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')) + >>> tuple(pairwise(['a', 'b', 'c', 'd'], reverse=True)) + (('d', 'c'), ('c', 'b'), ('b', 'a'), ('a', 'd')) + """ + if not iterable: + return + if reverse: + it = reversed(iterable) + else: + it = iter(iterable) + first = next(it, None) + a = first + for b in it: + yield (a, b) + a = b + yield (a, first) + + +def _test(): + """ + >>> import math + >>> calcBounds([]) + (0, 0, 0, 0) + >>> calcBounds([(0, 40), (0, 100), (50, 50), (80, 10)]) + (0, 10, 80, 100) + >>> updateBounds((0, 0, 0, 0), (100, 100)) + (0, 0, 100, 100) + >>> pointInRect((50, 50), (0, 0, 100, 100)) + True + >>> pointInRect((0, 0), (0, 0, 100, 100)) + True + >>> pointInRect((100, 100), (0, 0, 100, 100)) + True + >>> not pointInRect((101, 100), (0, 0, 100, 100)) + True + >>> list(pointsInRect([(50, 50), (0, 0), (100, 100), (101, 100)], (0, 0, 100, 100))) + [True, True, True, False] + >>> vectorLength((3, 4)) + 5.0 + >>> vectorLength((1, 1)) == math.sqrt(2) + True + >>> list(asInt16([0, 0.1, 0.5, 0.9])) + [0, 0, 1, 1] + >>> normRect((0, 10, 100, 200)) + (0, 10, 100, 200) + >>> normRect((100, 200, 0, 10)) + (0, 10, 100, 200) + >>> scaleRect((10, 20, 50, 150), 1.5, 2) + (15.0, 40, 75.0, 300) + >>> offsetRect((10, 20, 30, 40), 5, 6) + (15, 26, 35, 46) + >>> insetRect((10, 20, 50, 60), 5, 10) + (15, 30, 45, 50) + >>> insetRect((10, 20, 50, 60), -5, -10) + (5, 10, 55, 70) + >>> intersects, rect = sectRect((0, 10, 20, 30), (0, 40, 20, 50)) + >>> not intersects + True + >>> intersects, rect = sectRect((0, 10, 20, 30), (5, 20, 35, 50)) + >>> intersects + 1 + >>> rect + (5, 20, 20, 30) + >>> unionRect((0, 10, 20, 30), (0, 40, 20, 50)) + (0, 10, 20, 50) + >>> rectCenter((0, 0, 100, 200)) + (50.0, 100.0) + >>> rectCenter((0, 0, 100, 199.0)) + (50.0, 99.5) + >>> intRect((0.9, 2.9, 3.1, 4.1)) + (0, 2, 4, 5) + """ + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.c b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.c new file mode 100644 index 00000000..9f492720 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.c @@ -0,0 +1,41552 @@ +/* Generated by Cython 3.0.6 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "fontTools.misc.bezierTools", + "sources": [ + "Lib/fontTools/misc/bezierTools.py" + ] + }, + "module_name": "fontTools.misc.bezierTools" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_6" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x030006F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; // borrowed + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; // we don't yet need to distinguish between versions > 11 + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); // we don't have access to __pyx_empty_bytes here + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__misc__bezierTools +#define __PYX_HAVE_API__fontTools__misc__bezierTools +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const wchar_t *u) +{ + const wchar_t *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#endif +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else // Py < 3.12 + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "Lib/fontTools/misc/bezierTools.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; +struct __pyx_defaults; +typedef struct __pyx_defaults __pyx_defaults; +struct __pyx_defaults { + PyObject *__pyx_arg_sqrt; +}; + +/* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_t; +}; + + +/* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_t; +}; + + +/* "fontTools/misc/bezierTools.py":637 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC { + PyObject_HEAD + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + PyObject *__pyx_v_ts; +}; + + +/* "fontTools/misc/bezierTools.py":763 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC { + PyObject_HEAD + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_a1; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_b1; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_c1; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_d1; + double __pyx_v_delta; + double __pyx_v_delta_2; + double __pyx_v_delta_3; + PyObject *__pyx_v_i; + PyObject *__pyx_v_pt1; + PyObject *__pyx_v_pt2; + PyObject *__pyx_v_pt3; + PyObject *__pyx_v_pt4; + double __pyx_v_t1; + double __pyx_v_t1_2; + double __pyx_v_t1_3; + double __pyx_v_t2; + PyObject *__pyx_v_ts; + PyObject *__pyx_t_0; + Py_ssize_t __pyx_t_1; + PyObject *(*__pyx_t_2)(PyObject *); +}; + + +/* "fontTools/misc/bezierTools.py":1245 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_i; +}; + + +/* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t { + PyObject_HEAD + PyObject *__pyx_v_precision; +}; + + +/* "fontTools/misc/bezierTools.py":1375 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_p; +}; + + +/* "fontTools/misc/bezierTools.py":1475 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * + */ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_x; +}; + +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg // no-op + #define __Pyx_Arg_XDECREF_VARARGS(arg) // no-op - arg is borrowed +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg // no-op, __Pyx_Arg_FASTCALL is direct and this needs + #define __Pyx_Arg_XDECREF_FASTCALL(arg) // no-op - arg was returned from array +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif +#endif +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_MultiplyCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_MultiplyCObj(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceMultiply(op1, op2) : PyNumber_Multiply(op1, op2)) +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_TrueDivideObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_TrueDivideObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceTrueDivide(op1, op2) : PyNumber_TrueDivide(op1, op2)) +#endif + +/* PyIntCompare.proto */ +static CYTHON_INLINE int __Pyx_PyInt_BoolNeObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* PyIntCompare.proto */ +static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* RaiseUnboundLocalError.proto */ +static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* pep479.proto */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* PyObjectCallNoArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* CoroutineBase.proto */ +struct __pyx_CoroutineObject; +typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else +typedef struct { + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct __pyx_CoroutineObject { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; + PyObject *gi_weakreflist; + PyObject *classobj; + PyObject *yieldfrom; + PyObject *gi_name; + PyObject *gi_qualname; + PyObject *gi_modulename; + PyObject *gi_code; + PyObject *gi_frame; + int resume_label; + char is_running; +} __pyx_CoroutineObject; +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); +static int __Pyx_Coroutine_clear(PyObject *self); +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); +static PyObject *__Pyx_Coroutine_Close(PyObject *self); +static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else +#define __Pyx_Coroutine_SwapException(self) {\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ + } +#define __Pyx_Coroutine_ResetAndClearException(self) {\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ + } +#endif +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) +#else +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) +#endif +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PatchModuleWithCoroutine.proto */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); + +/* PatchGeneratorABC.proto */ +static int __Pyx_patch_abc(void); + +/* Generator.proto */ +#define __Pyx_Generator_USED +#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType) +#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ + __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name) +static PyObject *__Pyx_Generator_Next(PyObject *self); +static int __pyx_Generator_init(PyObject *module); + +/* GeneratorYieldFrom.proto */ +static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source); + +/* append.proto */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) +#endif + +/* py_abs.proto */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num); +#define __Pyx_PyNumber_Absolute(x)\ + ((likely(PyLong_CheckExact(x))) ?\ + (likely(__Pyx_PyLong_IsNonNeg(x)) ? (Py_INCREF(x), (x)) : __Pyx_PyLong_AbsNeg(x)) :\ + PyNumber_Absolute(x)) +#else +#define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x) +#endif + +/* PyFloatBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyFloat_TrueDivideObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyFloat_TrueDivideObjC(op1, op2, floatval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceTrueDivide(op1, op2) : PyNumber_TrueDivide(op1, op2)) +#endif + +/* pybytes_as_double.proto */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj); +static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length); +static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + as_c_string = PyBytes_AS_STRING(obj); + size = PyBytes_GET_SIZE(obj); +#else + if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) { + return (double)-1; + } +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} +static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + as_c_string = PyByteArray_AS_STRING(obj); + size = PyByteArray_GET_SIZE(obj); +#else + as_c_string = PyByteArray_AsString(obj); + if (as_c_string == NULL) { + return (double)-1; + } + size = PyByteArray_Size(obj); +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} + +/* pyunicode_as_double.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS +static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) { + int last_was_punctuation; + Py_ssize_t i; + last_was_punctuation = 1; + for (i=start; i <= end; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + int is_punctuation = (chr == '_') | (chr == '.'); + *buffer = (char)chr; + buffer += (chr != '_'); + if (unlikely(chr > 127)) goto parse_failure; + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyUnicode_AsDouble_inf_nan(const void* data, int kind, Py_ssize_t start, Py_ssize_t length) { + int matches = 1; + Py_UCS4 chr; + Py_UCS4 sign = PyUnicode_READ(kind, data, start); + int is_signed = (sign == '-') | (sign == '+'); + start += is_signed; + length -= is_signed; + switch (PyUnicode_READ(kind, data, start)) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'a') | (chr == 'A'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'n') | (chr == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'f') | (chr == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+3); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+4); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+5); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+6); + matches &= (chr == 't') | (chr == 'T'); + chr = PyUnicode_READ(kind, data, start+7); + matches &= (chr == 'y') | (chr == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) { + double value; + const char *last; + char *end; + Py_ssize_t start, length = PyUnicode_GET_LENGTH(obj); + const int kind = PyUnicode_KIND(obj); + const void* data = PyUnicode_DATA(obj); + start = 0; + while (Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, start))) + start++; + while (start < length - 1 && Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, length - 1))) + length--; + length -= start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyUnicode_AsDouble_inf_nan(data, kind, start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + if (length < 40) { + char number[40]; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((length + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} +#endif +static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) { +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS + if (unlikely(__Pyx_PyUnicode_READY(obj) == -1)) + return (double)-1; + if (likely(PyUnicode_IS_ASCII(obj))) { + const char *s; + Py_ssize_t length; + s = PyUnicode_AsUTF8AndSize(obj, &length); + return __Pyx__PyBytes_AsDouble(obj, s, length); + } + return __Pyx_PyUnicode_AsDouble_WithSpaces(obj); +#else + return __Pyx_SlowPyString_AsDouble(obj); +#endif +} + +/* pynumber_float.proto */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj); +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : __Pyx__PyNumber_Float(x)) + +/* PyFloatBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static int __Pyx_PyFloat_BoolEqObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyFloat_BoolEqObjC(op1, op2, floatval, inplace, zerodivision_check)\ + __Pyx_PyObject_IsTrueAndDecref(PyObject_RichCompare(op1, op2, Py_EQ)) + #endif + +/* pow2.proto */ +#define __Pyx_PyNumber_Power2(a, b) PyNumber_Power(a, b, Py_None) + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_SubtractCObj(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2)) +#endif + +/* RaiseClosureNameError.proto */ +static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname); + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; // used by FusedFunction for copying defaults + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* ListExtend.proto */ +static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + PyObject* none = _PyList_Extend((PyListObject*)L, v); + if (unlikely(!none)) + return -1; + Py_DECREF(none); + return 0; +#else + return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); +#endif +} + +/* pyfrozenset_new.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it); + +/* PySetContains.proto */ +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* ValidateBasesTuple.proto */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* FromPy.proto */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject*); + +/* ToPy.proto */ +#define __pyx_PyComplex_FromComplex(z)\ + PyComplex_FromDoubles((double)__Pyx_CREAL(z),\ + (double)__Pyx_CIMAG(z)) + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.misc.bezierTools" */ +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(double); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.misc.bezierTools" +extern int __pyx_module_is_main_fontTools__misc__bezierTools; +int __pyx_module_is_main_fontTools__misc__bezierTools = 0; + +/* Implementation of "fontTools.misc.bezierTools" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_AttributeError; +static PyObject *__pyx_builtin_ImportError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_round; +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_TypeError; +static PyObject *__pyx_builtin_print; +/* #### Code section: string_decls ### */ +static const char __pyx_k_Q[] = "Q"; +static const char __pyx_k_R[] = "R"; +static const char __pyx_k_a[] = "a"; +static const char __pyx_k_b[] = "b"; +static const char __pyx_k_c[] = "c"; +static const char __pyx_k_d[] = "d"; +static const char __pyx_k_e[] = "e"; +static const char __pyx_k_g[] = "%g"; +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_n[] = "n"; +static const char __pyx_k_r[] = "r"; +static const char __pyx_k_s[] = "s"; +static const char __pyx_k_t[] = "t"; +static const char __pyx_k_x[] = "x"; +static const char __pyx_k_y[] = "y"; +static const char __pyx_k_DD[] = "DD"; +static const char __pyx_k_Q3[] = "Q3"; +static const char __pyx_k_R2[] = "R2"; +static const char __pyx_k__9[] = ", "; +static const char __pyx_k_a1[] = "a1"; +static const char __pyx_k_a2[] = "a2"; +static const char __pyx_k_a3[] = "a3"; +static const char __pyx_k_ax[] = "ax"; +static const char __pyx_k_ay[] = "ay"; +static const char __pyx_k_b1[] = "b1"; +static const char __pyx_k_bx[] = "bx"; +static const char __pyx_k_by[] = "by"; +static const char __pyx_k_c1[] = "c1"; +static const char __pyx_k_cx[] = "cx"; +static const char __pyx_k_cy[] = "cy"; +static const char __pyx_k_d0[] = "d0"; +static const char __pyx_k_d1[] = "d1"; +static const char __pyx_k_dx[] = "dx"; +static const char __pyx_k_dy[] = "dy"; +static const char __pyx_k_e1[] = "e1"; +static const char __pyx_k_e2[] = "e2"; +static const char __pyx_k_ex[] = "ex"; +static const char __pyx_k_ey[] = "ey"; +static const char __pyx_k_gc[] = "gc"; +static const char __pyx_k_it[] = "it"; +static const char __pyx_k_p0[] = "p0"; +static const char __pyx_k_p1[] = "p1"; +static const char __pyx_k_p2[] = "p2"; +static const char __pyx_k_p3[] = "p3"; +static const char __pyx_k_pi[] = "pi"; +static const char __pyx_k_pt[] = "pt"; +static const char __pyx_k_px[] = "px"; +static const char __pyx_k_py[] = "py"; +static const char __pyx_k_s1[] = "s1"; +static const char __pyx_k_s2[] = "s2"; +static const char __pyx_k_sx[] = "sx"; +static const char __pyx_k_sy[] = "sy"; +static const char __pyx_k_t1[] = "t1"; +static const char __pyx_k_t2[] = "t2"; +static const char __pyx_k_ts[] = "ts"; +static const char __pyx_k_v0[] = "v0"; +static const char __pyx_k_v1[] = "v1"; +static const char __pyx_k_v2[] = "v2"; +static const char __pyx_k_v3[] = "v3"; +static const char __pyx_k_v4[] = "v4"; +static const char __pyx_k_x0[] = "x0"; +static const char __pyx_k_x1[] = "x1"; +static const char __pyx_k_x2[] = "x2"; +static const char __pyx_k_x3[] = "x3"; +static const char __pyx_k_x4[] = "x4"; +static const char __pyx_k_y1[] = "y1"; +static const char __pyx_k_y2[] = "y2"; +static const char __pyx_k_y3[] = "y3"; +static const char __pyx_k_y4[] = "y4"; +static const char __pyx_k_1_t[] = "_1_t"; +static const char __pyx_k_Len[] = "Len"; +static const char __pyx_k__10[] = "."; +static const char __pyx_k__11[] = "*"; +static const char __pyx_k__91[] = "_"; +static const char __pyx_k_a1x[] = "a1x"; +static const char __pyx_k_a1y[] = "a1y"; +static const char __pyx_k_all[] = "__all__"; +static const char __pyx_k_ax2[] = "ax2"; +static const char __pyx_k_ax3[] = "ax3"; +static const char __pyx_k_ay2[] = "ay2"; +static const char __pyx_k_ay3[] = "ay3"; +static const char __pyx_k_b1x[] = "b1x"; +static const char __pyx_k_b1y[] = "b1y"; +static const char __pyx_k_box[] = "box"; +static const char __pyx_k_bx2[] = "bx2"; +static const char __pyx_k_by2[] = "by2"; +static const char __pyx_k_c11[] = "c11"; +static const char __pyx_k_c12[] = "c12"; +static const char __pyx_k_c1x[] = "c1x"; +static const char __pyx_k_c1y[] = "c1y"; +static const char __pyx_k_c21[] = "c21"; +static const char __pyx_k_c22[] = "c22"; +static const char __pyx_k_cos[] = "cos"; +static const char __pyx_k_d1x[] = "d1x"; +static const char __pyx_k_d1y[] = "d1y"; +static const char __pyx_k_e1x[] = "e1x"; +static const char __pyx_k_e1y[] = "e1y"; +static const char __pyx_k_e2x[] = "e2x"; +static const char __pyx_k_e2y[] = "e2y"; +static const char __pyx_k_end[] = "end"; +static const char __pyx_k_key[] = "key"; +static const char __pyx_k_mid[] = "mid"; +static const char __pyx_k_obj[] = "obj"; +static const char __pyx_k_one[] = "one"; +static const char __pyx_k_pt1[] = "pt1"; +static const char __pyx_k_pt2[] = "pt2"; +static const char __pyx_k_pt3[] = "pt3"; +static const char __pyx_k_pt4[] = "pt4"; +static const char __pyx_k_rDD[] = "rDD"; +static const char __pyx_k_rQ2[] = "rQ2"; +static const char __pyx_k_s1x[] = "s1x"; +static const char __pyx_k_s1y[] = "s1y"; +static const char __pyx_k_s2x[] = "s2x"; +static const char __pyx_k_s2y[] = "s2y"; +static const char __pyx_k_s_2[] = "(%s)"; +static const char __pyx_k_seg[] = "seg"; +static const char __pyx_k_sys[] = "sys"; +static const char __pyx_k_two[] = "two"; +static const char __pyx_k__105[] = "?"; +static const char __pyx_k_a1_3[] = "a1_3"; +static const char __pyx_k_acos[] = "acos"; +static const char __pyx_k_arch[] = "arch"; +static const char __pyx_k_args[] = "args"; +static const char __pyx_k_exit[] = "exit"; +static const char __pyx_k_line[] = "line"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_math[] = "math"; +static const char __pyx_k_mult[] = "mult"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_off1[] = "off1"; +static const char __pyx_k_off2[] = "off2"; +static const char __pyx_k_pt1x[] = "pt1x"; +static const char __pyx_k_pt1y[] = "pt1y"; +static const char __pyx_k_pt2x[] = "pt2x"; +static const char __pyx_k_pt2y[] = "pt2y"; +static const char __pyx_k_seen[] = "seen"; +static const char __pyx_k_seg1[] = "seg1"; +static const char __pyx_k_seg2[] = "seg2"; +static const char __pyx_k_send[] = "send"; +static const char __pyx_k_spec[] = "__spec__"; +static const char __pyx_k_sqrt[] = "sqrt"; +static const char __pyx_k_t1_2[] = "t1_2"; +static const char __pyx_k_t1_3[] = "t1_3"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_1_t_2[] = "_1_t_2"; +static const char __pyx_k_R2_Q3[] = "R2_Q3"; +static const char __pyx_k_angle[] = "angle"; +static const char __pyx_k_asinh[] = "asinh"; +static const char __pyx_k_atan2[] = "atan2"; +static const char __pyx_k_close[] = "close"; +static const char __pyx_k_curve[] = "curve"; +static const char __pyx_k_delta[] = "delta"; +static const char __pyx_k_found[] = "found"; +static const char __pyx_k_line1[] = "line1"; +static const char __pyx_k_line2[] = "line2"; +static const char __pyx_k_midPt[] = "midPt"; +static const char __pyx_k_print[] = "print"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_roots[] = "roots"; +static const char __pyx_k_round[] = "round"; +static const char __pyx_k_scale[] = "scale"; +static const char __pyx_k_start[] = "start"; +static const char __pyx_k_theta[] = "theta"; +static const char __pyx_k_throw[] = "throw"; +static const char __pyx_k_where[] = "where"; +static const char __pyx_k_xDiff[] = "xDiff"; +static const char __pyx_k_yDiff[] = "yDiff"; +static const char __pyx_k_append[] = "append"; +static const char __pyx_k_curve1[] = "curve1"; +static const char __pyx_k_curve2[] = "curve2"; +static const char __pyx_k_cython[] = "cython"; +static const char __pyx_k_deriv3[] = "deriv3"; +static const char __pyx_k_enable[] = "enable"; +static const char __pyx_k_failed[] = "failed"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_insert[] = "insert"; +static const char __pyx_k_line_t[] = "line_t"; +static const char __pyx_k_origin[] = "origin"; +static const char __pyx_k_points[] = "points"; +static const char __pyx_k_range1[] = "range1"; +static const char __pyx_k_range2[] = "range2"; +static const char __pyx_k_rotate[] = "rotate"; +static const char __pyx_k_xRoots[] = "xRoots"; +static const char __pyx_k_yRoots[] = "yRoots"; +static const char __pyx_k_2_t_1_t[] = "_2_t_1_t"; +static const char __pyx_k_bounds1[] = "bounds1"; +static const char __pyx_k_bounds2[] = "bounds2"; +static const char __pyx_k_delta_2[] = "delta_2"; +static const char __pyx_k_delta_3[] = "delta_3"; +static const char __pyx_k_disable[] = "disable"; +static const char __pyx_k_doctest[] = "doctest"; +static const char __pyx_k_epsilon[] = "epsilon"; +static const char __pyx_k_genexpr[] = "genexpr"; +static const char __pyx_k_isclose[] = "isclose"; +static const char __pyx_k_segment[] = "segment"; +static const char __pyx_k_slope12[] = "slope12"; +static const char __pyx_k_slope34[] = "slope34"; +static const char __pyx_k_swapped[] = "swapped"; +static const char __pyx_k_testmod[] = "testmod"; +static const char __pyx_k_COMPILED[] = "COMPILED"; +static const char __pyx_k_Identity[] = "Identity"; +static const char __pyx_k_midpoint[] = "midpoint"; +static const char __pyx_k_origDist[] = "origDist"; +static const char __pyx_k_pointAtT[] = "pointAtT"; +static const char __pyx_k_rectArea[] = "rectArea"; +static const char __pyx_k_sectRect[] = "sectRect"; +static const char __pyx_k_segments[] = "segments"; +static const char __pyx_k_TypeError[] = "TypeError"; +static const char __pyx_k_c11_range[] = "c11_range"; +static const char __pyx_k_c12_range[] = "c12_range"; +static const char __pyx_k_c21_range[] = "c21_range"; +static const char __pyx_k_c22_range[] = "c22_range"; +static const char __pyx_k_isenabled[] = "isenabled"; +static const char __pyx_k_maybeline[] = "maybeline"; +static const char __pyx_k_precision[] = "precision"; +static const char __pyx_k_solutions[] = "solutions"; +static const char __pyx_k_splitLine[] = "splitLine"; +static const char __pyx_k_tolerance[] = "tolerance"; +static const char __pyx_k_translate[] = "translate"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_calcBounds[] = "calcBounds"; +static const char __pyx_k_intersects[] = "intersects"; +static const char __pyx_k_namedtuple[] = "namedtuple"; +static const char __pyx_k_solveCubic[] = "solveCubic"; +static const char __pyx_k_splitCubic[] = "splitCubic"; +static const char __pyx_k_unique_key[] = "unique_key"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_collections[] = "collections"; +static const char __pyx_k_is_linelike[] = "_is_linelike"; +static const char __pyx_k_pointFinder[] = "pointFinder"; +static const char __pyx_k_segmentrepr[] = "_segmentrepr"; +static const char __pyx_k_Intersection[] = "Intersection"; +static const char __pyx_k_curve_bounds[] = "_curve_bounds"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_isHorizontal[] = "isHorizontal"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_linePointAtT[] = "linePointAtT"; +static const char __pyx_k_line_t_of_pt[] = "_line_t_of_pt"; +static const char __pyx_k_aligned_curve[] = "aligned_curve"; +static const char __pyx_k_class_getitem[] = "__class_getitem__"; +static const char __pyx_k_cubicPointAtT[] = "cubicPointAtT"; +static const char __pyx_k_epsilonDigits[] = "epsilonDigits"; +static const char __pyx_k_intersections[] = "intersections"; +static const char __pyx_k_printSegments[] = "printSegments"; +static const char __pyx_k_splitCubicAtT[] = "_splitCubicAtT"; +static const char __pyx_k_unique_values[] = "unique_values"; +static const char __pyx_k_AttributeError[] = "AttributeError"; +static const char __pyx_k_cubicPointAtTC[] = "cubicPointAtTC"; +static const char __pyx_k_fontTools_misc[] = "fontTools.misc"; +static const char __pyx_k_solveQuadratic[] = "solveQuadratic"; +static const char __pyx_k_splitCubicAtTC[] = "splitCubicAtTC"; +static const char __pyx_k_splitQuadratic[] = "splitQuadratic"; +static const char __pyx_k_calcCubicBounds[] = "calcCubicBounds"; +static const char __pyx_k_calcCubicPoints[] = "calcCubicPoints"; +static const char __pyx_k_intersection_ts[] = "intersection_ts"; +static const char __pyx_k_segmentPointAtT[] = "segmentPointAtT"; +static const char __pyx_k_splitCubicAtT_2[] = "splitCubicAtT"; +static const char __pyx_k_transformPoints[] = "transformPoints"; +static const char __pyx_k_splitCubicAtTC_2[] = "_splitCubicAtTC"; +static const char __pyx_k_quadraticPointAtT[] = "quadraticPointAtT"; +static const char __pyx_k_splitQuadraticAtT[] = "_splitQuadraticAtT"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_calcCubicArcLength[] = "calcCubicArcLength"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_splitLine_line_450[] = "splitLine (line 450)"; +static const char __pyx_k_split_segment_at_t[] = "_split_segment_at_t"; +static const char __pyx_k_calcCubicArcLengthC[] = "calcCubicArcLengthC"; +static const char __pyx_k_calcCubicParameters[] = "calcCubicParameters"; +static const char __pyx_k_calcQuadraticBounds[] = "calcQuadraticBounds"; +static const char __pyx_k_calcQuadraticPoints[] = "calcQuadraticPoints"; +static const char __pyx_k_solveCubic_line_841[] = "solveCubic (line 841)"; +static const char __pyx_k_splitCubic_line_552[] = "splitCubic (line 552)"; +static const char __pyx_k_splitQuadraticAtT_2[] = "splitQuadraticAtT"; +static const char __pyx_k_Unknown_curve_degree[] = "Unknown curve degree"; +static const char __pyx_k_split_cubic_into_two[] = "_split_cubic_into_two"; +static const char __pyx_k_lineLineIntersections[] = "lineLineIntersections"; +static const char __pyx_k_segmentrepr_line_1465[] = "_segmentrepr (line 1465)"; +static const char __pyx_k_splitCubicIntoTwoAtTC[] = "splitCubicIntoTwoAtTC"; +static const char __pyx_k_calcQuadraticArcLength[] = "calcQuadraticArcLength"; +static const char __pyx_k_curveLineIntersections[] = "curveLineIntersections"; +static const char __pyx_k_splitCubicAtT_line_613[] = "splitCubicAtT (line 613)"; +static const char __pyx_k_calcQuadraticArcLengthC[] = "calcQuadraticArcLengthC"; +static const char __pyx_k_calcQuadraticParameters[] = "calcQuadraticParameters"; +static const char __pyx_k_curveCurveIntersections[] = "curveCurveIntersections"; +static const char __pyx_k_splitQuadratic_line_507[] = "splitQuadratic (line 507)"; +static const char __pyx_k_alignment_transformation[] = "_alignment_transformation"; +static const char __pyx_k_calcCubicBounds_line_412[] = "calcCubicBounds (line 412)"; +static const char __pyx_k_fontTools_misc_transform[] = "fontTools.misc.transform"; +static const char __pyx_k_approximateCubicArcLength[] = "approximateCubicArcLength"; +static const char __pyx_k_fontTools_misc_arrayTools[] = "fontTools.misc.arrayTools"; +static const char __pyx_k_splitCubic_locals_genexpr[] = "splitCubic..genexpr"; +static const char __pyx_k_approximateCubicArcLengthC[] = "approximateCubicArcLengthC"; +static const char __pyx_k_calcCubicArcLengthCRecurse[] = "_calcCubicArcLengthCRecurse"; +static const char __pyx_k_curve_line_intersections_t[] = "_curve_line_intersections_t"; +static const char __pyx_k_fontTools_misc_bezierTools[] = "fontTools.misc.bezierTools"; +static const char __pyx_k_is_linelike_locals_genexpr[] = "_is_linelike..genexpr"; +static const char __pyx_k_segmentrepr_locals_genexpr[] = "_segmentrepr..genexpr"; +static const char __pyx_k_splitQuadraticAtT_line_589[] = "splitQuadraticAtT (line 589)"; +static const char __pyx_k_curve_curve_intersections_t[] = "_curve_curve_intersections_t"; +static const char __pyx_k_segmentSegmentIntersections[] = "segmentSegmentIntersections"; +static const char __pyx_k_calcQuadraticBounds_line_298[] = "calcQuadraticBounds (line 298)"; +static const char __pyx_k_approximateQuadraticArcLength[] = "approximateQuadraticArcLength"; +static const char __pyx_k_segmentrepr_1_2_3_2_3_4_0_1_2[] = "\n >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]])\n '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))'\n "; +static const char __pyx_k_splitQuadratic_locals_genexpr[] = "splitQuadratic..genexpr"; +static const char __pyx_k_approximateQuadraticArcLengthC[] = "approximateQuadraticArcLengthC"; +static const char __pyx_k_Approximates_the_arc_length_for[] = "Approximates the arc length for a cubic Bezier segment.\n\n Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length.\n See :func:`calcCubicArcLength` for a slower but more accurate result.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0))\n 190.04332968932817\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100))\n 154.8852074945903\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150.\n 149.99999999999991\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150.\n 136.9267662156362\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp\n 154.80848416537057\n "; +static const char __pyx_k_Calculates_the_arc_length_for_a[] = "Calculates the arc length for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment\n 0.0\n >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points\n 80.0\n >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical\n 80.0\n >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points\n 107.70329614269008\n >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0))\n 154.02976155645263\n >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0))\n 120.21581243984076\n >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50))\n 102.53273816445825\n >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside\n 66.66666666666667\n >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back\n 40.0\n "; +static const char __pyx_k_Finds_intersections_between_two[] = "Finds intersections between two line segments.\n\n Args:\n s1, e1: Coordinates of the first line as 2D tuples.\n s2, e2: Coordinates of the second line as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n\n >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367))\n >>> len(a)\n 1\n >>> intersection = a[0]\n >>> intersection.pt\n (374.44882952482897, 313.73458370177315)\n >>> (intersection.t1, intersection.t2)\n (0.45069111555824465, 0.5408153767394238)\n "; +static const char __pyx_k_Solve_a_cubic_equation_Solves_a[] = "Solve a cubic equation.\n\n Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.\n\n Args:\n a: coefficient of *x\302\263*\n b: coefficient of *x\302\262*\n c: coefficient of *x*\n d: constant term\n\n Returns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!\n\n Examples::\n\n >>> solveCubic(1, 1, -6, 0)\n [-3.0, -0.0, 2.0]\n >>> solveCubic(-10.0, -9.0, 48.0, -29.0)\n [-2.9, 1.0, 1.0]\n >>> solveCubic(-9.875, -9.0, 47.625, -28.75)\n [-2.911392, 1.0, 1.0]\n >>> solveCubic(1.0, -4.5, 6.75, -3.375)\n [1.5, 1.5, 1.5]\n >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)\n [0.5, 0.5, 0.5]\n >>> solveCubic(\n ... 9.0, 0.0, 0.0, -7.62939453125e-05\n ... ) == [-0.0, -0.0, -0.0]\n True\n "; +static const char __pyx_k_Split_a_cubic_Bezier_curve_at_a[] = "Split a cubic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being four 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False))\n ((0, 0), (25, 100), (75, 100), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True))\n ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25))\n ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25))\n ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15))\n "; +static const char __pyx_k_both_points_are_on_same_side_of[] = "_both_points_are_on_same_side_of_origin"; +static const char __pyx_k_calcQuadraticArcLength_line_151[] = "calcQuadraticArcLength (line 151)"; +static const char __pyx_k_curve_curve_intersections_t_loc[] = "_curve_curve_intersections_t..midpoint"; +static const char __pyx_k_curve_line_intersections_t_loca[] = "_curve_line_intersections_t..genexpr"; +static const char __pyx_k_lineLineIntersections_line_1147[] = "lineLineIntersections (line 1147)"; +static const char __pyx_k_Calculates_the_bounding_rectangl[] = "Calculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as a 2D tuple.\n pt2: Handle point of the Bezier as a 2D tuple.\n pt3: End point of the Bezier as a 2D tuple.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0))\n (0, 0, 100, 50.0)\n >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))\n (0.0, 0.0, 100, 100)\n "; +static const char __pyx_k_Couldn_t_work_out_which_intersec[] = "Couldn't work out which intersection function to use"; +static const char __pyx_k_Finds_intersections_between_a_cu[] = "Finds intersections between a curve and a line.\n\n Args:\n curve: List of coordinates of the curve segment as 2D tuples.\n line: List of coordinates of the line segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = curveLineIntersections(curve, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n "; +static const char __pyx_k_Lib_fontTools_misc_bezierTools_p[] = "Lib/fontTools/misc/bezierTools.py"; +static const char __pyx_k_Split_a_cubic_Bezier_curve_at_on[] = "Split a cubic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being four 2D tuples).\n\n Examples::\n\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25))\n ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0))\n "; +static const char __pyx_k_Split_a_line_at_a_given_coordina[] = "Split a line at a given coordinate.\n\n Args:\n pt1: Start point of line as 2D tuple.\n pt2: End point of line as 2D tuple.\n where: Position at which to split the line.\n isHorizontal: Direction of the ray splitting the line. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two line segments (each line segment being two 2D tuples)\n if the line was successfully split, or a list containing the original\n line.\n\n Example::\n\n >>> printSegments(splitLine((0, 0), (100, 100), 50, True))\n ((0, 0), (50, 50))\n ((50, 50), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 100, True))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, True))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, False))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((100, 0), (0, 0), 50, False))\n ((100, 0), (50, 0))\n ((50, 0), (0, 0))\n >>> printSegments(splitLine((0, 100), (0, 0), 50, True))\n ((0, 100), (0, 50))\n ((0, 50), (0, 0))\n "; +static const char __pyx_k_Split_a_quadratic_Bezier_curve_a[] = "Split a quadratic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being three 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False))\n ((0, 0), (50, 100), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False))\n ((0, 0), (12.5, 25), (25, 37.5))\n ((25, 37.5), (62.5, 75), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True))\n ((0, 0), (7.32233, 14.6447), (14.6447, 25))\n ((14.6447, 25), (50, 75), (85.3553, 25))\n ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15))\n >>> # XXX I'm not at all sure if the following behavior is desirable:\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (50, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n "; +static const char __pyx_k_approximateCubicArcLength_line_3[] = "approximateCubicArcLength (line 332)"; +static const char __pyx_k_curveCurveIntersections_line_137[] = "curveCurveIntersections (line 1378)"; +static const char __pyx_k_curveLineIntersections_line_1248[] = "curveLineIntersections (line 1248)"; +static const char __pyx_k_fontTools_misc_bezierTools_py_to[] = "fontTools.misc.bezierTools.py -- tools for working with Bezier path segments.\n"; +static const char __pyx_k_segmentSegmentIntersections_line[] = "segmentSegmentIntersections (line 1417)"; +static const char __pyx_k_Finds_intersections_between_two_2[] = "Finds intersections between two segments.\n\n Args:\n seg1: List of coordinates of the first segment as 2D tuples.\n seg2: List of coordinates of the second segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = segmentSegmentIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = segmentSegmentIntersections(curve3, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n\n "; +static const char __pyx_k_curve_curve_intersections_t_loc_2[] = "_curve_curve_intersections_t.."; +static const char __pyx_k_Calculates_the_bounding_rectangl_2[] = "Calculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0))\n (0, 0, 100, 75.0)\n >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100))\n (0.0, 0.0, 100, 100)\n >>> print(\"%f %f %f %f\" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))\n 35.566243 0.000000 64.433757 75.000000\n "; +static const char __pyx_k_Finds_intersections_between_a_cu_2[] = "Finds intersections between a curve and a curve.\n\n Args:\n curve1: List of coordinates of the first curve segment as 2D tuples.\n curve2: List of coordinates of the second curve segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = curveCurveIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n "; +static const char __pyx_k_Split_a_quadratic_Bezier_curve_a_2[] = "Split a quadratic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being three 2D tuples).\n\n Examples::\n\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (62.5, 50), (75, 37.5))\n ((75, 37.5), (87.5, 25), (100, 0))\n "; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_tolerance); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p0, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_mult, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_tolerance); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_sqrt); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_pt); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_origin); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s1, PyObject *__pyx_v_e1, PyObject *__pyx_v_s2, PyObject *__pyx_v_e2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_r); /* proto */ +static PyObject *__pyx_lambda_funcdef_lambda3(PyObject *__pyx_self, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2, PyObject *__pyx_v_precision, PyObject *__pyx_v_range1, PyObject *__pyx_v_range2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg1, PyObject *__pyx_v_seg2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_obj); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segments); /* proto */ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + #endif + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + PyObject *__pyx_n_s_1_t; + PyObject *__pyx_n_s_1_t_2; + PyObject *__pyx_n_s_2_t_1_t; + PyObject *__pyx_kp_u_Approximates_the_arc_length_for; + PyObject *__pyx_n_s_AttributeError; + PyObject *__pyx_n_s_COMPILED; + PyObject *__pyx_kp_u_Calculates_the_arc_length_for_a; + PyObject *__pyx_kp_u_Calculates_the_bounding_rectangl; + PyObject *__pyx_kp_u_Calculates_the_bounding_rectangl_2; + PyObject *__pyx_kp_u_Couldn_t_work_out_which_intersec; + PyObject *__pyx_n_s_DD; + PyObject *__pyx_kp_u_Finds_intersections_between_a_cu; + PyObject *__pyx_kp_u_Finds_intersections_between_a_cu_2; + PyObject *__pyx_kp_u_Finds_intersections_between_two; + PyObject *__pyx_kp_u_Finds_intersections_between_two_2; + PyObject *__pyx_n_s_Identity; + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_n_s_Intersection; + PyObject *__pyx_n_u_Intersection; + PyObject *__pyx_n_s_Len; + PyObject *__pyx_kp_s_Lib_fontTools_misc_bezierTools_p; + PyObject *__pyx_n_s_Q; + PyObject *__pyx_n_s_Q3; + PyObject *__pyx_n_s_R; + PyObject *__pyx_n_s_R2; + PyObject *__pyx_n_s_R2_Q3; + PyObject *__pyx_kp_u_Solve_a_cubic_equation_Solves_a; + PyObject *__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a; + PyObject *__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on; + PyObject *__pyx_kp_u_Split_a_line_at_a_given_coordina; + PyObject *__pyx_kp_u_Split_a_quadratic_Bezier_curve_a; + PyObject *__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2; + PyObject *__pyx_n_s_TypeError; + PyObject *__pyx_kp_u_Unknown_curve_degree; + PyObject *__pyx_n_s_ValueError; + PyObject *__pyx_kp_u__10; + PyObject *__pyx_n_s__105; + PyObject *__pyx_n_s__11; + PyObject *__pyx_kp_u__9; + PyObject *__pyx_n_s__91; + PyObject *__pyx_n_s_a; + PyObject *__pyx_n_s_a1; + PyObject *__pyx_n_s_a1_3; + PyObject *__pyx_n_s_a1x; + PyObject *__pyx_n_s_a1y; + PyObject *__pyx_n_s_a2; + PyObject *__pyx_n_s_a3; + PyObject *__pyx_n_s_acos; + PyObject *__pyx_n_s_aligned_curve; + PyObject *__pyx_n_s_alignment_transformation; + PyObject *__pyx_n_s_all; + PyObject *__pyx_n_s_angle; + PyObject *__pyx_n_s_append; + PyObject *__pyx_n_s_approximateCubicArcLength; + PyObject *__pyx_n_u_approximateCubicArcLength; + PyObject *__pyx_n_s_approximateCubicArcLengthC; + PyObject *__pyx_n_u_approximateCubicArcLengthC; + PyObject *__pyx_kp_u_approximateCubicArcLength_line_3; + PyObject *__pyx_n_s_approximateQuadraticArcLength; + PyObject *__pyx_n_u_approximateQuadraticArcLength; + PyObject *__pyx_n_s_approximateQuadraticArcLengthC; + PyObject *__pyx_n_u_approximateQuadraticArcLengthC; + PyObject *__pyx_n_s_arch; + PyObject *__pyx_n_s_args; + PyObject *__pyx_n_s_asinh; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_atan2; + PyObject *__pyx_n_s_ax; + PyObject *__pyx_n_s_ax2; + PyObject *__pyx_n_s_ax3; + PyObject *__pyx_n_s_ay; + PyObject *__pyx_n_s_ay2; + PyObject *__pyx_n_s_ay3; + PyObject *__pyx_n_s_b; + PyObject *__pyx_n_s_b1; + PyObject *__pyx_n_s_b1x; + PyObject *__pyx_n_s_b1y; + PyObject *__pyx_n_s_both_points_are_on_same_side_of; + PyObject *__pyx_n_s_bounds1; + PyObject *__pyx_n_s_bounds2; + PyObject *__pyx_n_s_box; + PyObject *__pyx_n_s_bx; + PyObject *__pyx_n_s_bx2; + PyObject *__pyx_n_s_by; + PyObject *__pyx_n_s_by2; + PyObject *__pyx_n_s_c; + PyObject *__pyx_n_s_c1; + PyObject *__pyx_n_s_c11; + PyObject *__pyx_n_s_c11_range; + PyObject *__pyx_n_s_c12; + PyObject *__pyx_n_s_c12_range; + PyObject *__pyx_n_s_c1x; + PyObject *__pyx_n_s_c1y; + PyObject *__pyx_n_s_c21; + PyObject *__pyx_n_s_c21_range; + PyObject *__pyx_n_s_c22; + PyObject *__pyx_n_s_c22_range; + PyObject *__pyx_n_s_calcBounds; + PyObject *__pyx_n_s_calcCubicArcLength; + PyObject *__pyx_n_u_calcCubicArcLength; + PyObject *__pyx_n_s_calcCubicArcLengthC; + PyObject *__pyx_n_u_calcCubicArcLengthC; + PyObject *__pyx_n_s_calcCubicArcLengthCRecurse; + PyObject *__pyx_n_s_calcCubicBounds; + PyObject *__pyx_n_u_calcCubicBounds; + PyObject *__pyx_kp_u_calcCubicBounds_line_412; + PyObject *__pyx_n_s_calcCubicParameters; + PyObject *__pyx_n_s_calcCubicPoints; + PyObject *__pyx_n_s_calcQuadraticArcLength; + PyObject *__pyx_n_u_calcQuadraticArcLength; + PyObject *__pyx_n_s_calcQuadraticArcLengthC; + PyObject *__pyx_n_u_calcQuadraticArcLengthC; + PyObject *__pyx_kp_u_calcQuadraticArcLength_line_151; + PyObject *__pyx_n_s_calcQuadraticBounds; + PyObject *__pyx_n_u_calcQuadraticBounds; + PyObject *__pyx_kp_u_calcQuadraticBounds_line_298; + PyObject *__pyx_n_s_calcQuadraticParameters; + PyObject *__pyx_n_s_calcQuadraticPoints; + PyObject *__pyx_n_s_class_getitem; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_close; + PyObject *__pyx_n_s_collections; + PyObject *__pyx_n_s_cos; + PyObject *__pyx_n_s_cubicPointAtT; + PyObject *__pyx_n_u_cubicPointAtT; + PyObject *__pyx_n_s_cubicPointAtTC; + PyObject *__pyx_n_u_cubicPointAtTC; + PyObject *__pyx_n_s_curve; + PyObject *__pyx_n_s_curve1; + PyObject *__pyx_n_s_curve2; + PyObject *__pyx_n_s_curveCurveIntersections; + PyObject *__pyx_n_u_curveCurveIntersections; + PyObject *__pyx_kp_u_curveCurveIntersections_line_137; + PyObject *__pyx_n_s_curveLineIntersections; + PyObject *__pyx_n_u_curveLineIntersections; + PyObject *__pyx_kp_u_curveLineIntersections_line_1248; + PyObject *__pyx_n_s_curve_bounds; + PyObject *__pyx_n_s_curve_curve_intersections_t; + PyObject *__pyx_n_s_curve_curve_intersections_t_loc; + PyObject *__pyx_n_s_curve_curve_intersections_t_loc_2; + PyObject *__pyx_n_s_curve_line_intersections_t; + PyObject *__pyx_n_s_curve_line_intersections_t_loca; + PyObject *__pyx_n_s_cx; + PyObject *__pyx_n_s_cy; + PyObject *__pyx_n_s_cython; + PyObject *__pyx_n_s_d; + PyObject *__pyx_n_s_d0; + PyObject *__pyx_n_s_d1; + PyObject *__pyx_n_s_d1x; + PyObject *__pyx_n_s_d1y; + PyObject *__pyx_n_s_delta; + PyObject *__pyx_n_s_delta_2; + PyObject *__pyx_n_s_delta_3; + PyObject *__pyx_n_s_deriv3; + PyObject *__pyx_kp_u_disable; + PyObject *__pyx_n_s_doctest; + PyObject *__pyx_n_s_dx; + PyObject *__pyx_n_s_dy; + PyObject *__pyx_n_s_e; + PyObject *__pyx_n_s_e1; + PyObject *__pyx_n_s_e1x; + PyObject *__pyx_n_s_e1y; + PyObject *__pyx_n_s_e2; + PyObject *__pyx_n_s_e2x; + PyObject *__pyx_n_s_e2y; + PyObject *__pyx_kp_u_enable; + PyObject *__pyx_n_s_end; + PyObject *__pyx_n_s_epsilon; + PyObject *__pyx_n_s_epsilonDigits; + PyObject *__pyx_n_s_ex; + PyObject *__pyx_n_s_exit; + PyObject *__pyx_n_s_ey; + PyObject *__pyx_n_s_failed; + PyObject *__pyx_n_s_fontTools_misc; + PyObject *__pyx_n_s_fontTools_misc_arrayTools; + PyObject *__pyx_n_s_fontTools_misc_bezierTools; + PyObject *__pyx_n_s_fontTools_misc_transform; + PyObject *__pyx_n_s_found; + PyObject *__pyx_kp_u_g; + PyObject *__pyx_kp_u_gc; + PyObject *__pyx_n_s_genexpr; + PyObject *__pyx_n_s_i; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_n_s_insert; + PyObject *__pyx_n_s_intersection_ts; + PyObject *__pyx_n_s_intersections; + PyObject *__pyx_n_s_intersects; + PyObject *__pyx_n_s_isHorizontal; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_n_s_is_linelike; + PyObject *__pyx_n_s_is_linelike_locals_genexpr; + PyObject *__pyx_n_s_isclose; + PyObject *__pyx_kp_u_isenabled; + PyObject *__pyx_n_s_it; + PyObject *__pyx_n_s_key; + PyObject *__pyx_n_s_line; + PyObject *__pyx_n_s_line1; + PyObject *__pyx_n_s_line2; + PyObject *__pyx_n_s_lineLineIntersections; + PyObject *__pyx_n_u_lineLineIntersections; + PyObject *__pyx_kp_u_lineLineIntersections_line_1147; + PyObject *__pyx_n_s_linePointAtT; + PyObject *__pyx_n_u_linePointAtT; + PyObject *__pyx_n_s_line_t; + PyObject *__pyx_n_s_line_t_of_pt; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_u_main; + PyObject *__pyx_n_s_math; + PyObject *__pyx_n_s_maybeline; + PyObject *__pyx_n_s_mid; + PyObject *__pyx_n_s_midPt; + PyObject *__pyx_n_s_midpoint; + PyObject *__pyx_n_s_mult; + PyObject *__pyx_n_s_n; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_namedtuple; + PyObject *__pyx_n_s_obj; + PyObject *__pyx_n_s_off1; + PyObject *__pyx_n_s_off2; + PyObject *__pyx_n_s_one; + PyObject *__pyx_n_s_origDist; + PyObject *__pyx_n_s_origin; + PyObject *__pyx_n_s_p0; + PyObject *__pyx_n_s_p1; + PyObject *__pyx_n_s_p2; + PyObject *__pyx_n_s_p3; + PyObject *__pyx_n_s_pi; + PyObject *__pyx_n_s_pointAtT; + PyObject *__pyx_n_s_pointFinder; + PyObject *__pyx_n_s_points; + PyObject *__pyx_n_s_precision; + PyObject *__pyx_n_s_print; + PyObject *__pyx_n_s_printSegments; + PyObject *__pyx_n_s_pt; + PyObject *__pyx_n_u_pt; + PyObject *__pyx_n_s_pt1; + PyObject *__pyx_n_s_pt1x; + PyObject *__pyx_n_s_pt1y; + PyObject *__pyx_n_s_pt2; + PyObject *__pyx_n_s_pt2x; + PyObject *__pyx_n_s_pt2y; + PyObject *__pyx_n_s_pt3; + PyObject *__pyx_n_s_pt4; + PyObject *__pyx_n_s_px; + PyObject *__pyx_n_s_py; + PyObject *__pyx_n_s_quadraticPointAtT; + PyObject *__pyx_n_u_quadraticPointAtT; + PyObject *__pyx_n_s_r; + PyObject *__pyx_n_s_rDD; + PyObject *__pyx_n_s_rQ2; + PyObject *__pyx_n_s_range; + PyObject *__pyx_n_s_range1; + PyObject *__pyx_n_s_range2; + PyObject *__pyx_n_s_rectArea; + PyObject *__pyx_n_s_roots; + PyObject *__pyx_n_s_rotate; + PyObject *__pyx_n_s_round; + PyObject *__pyx_n_s_s; + PyObject *__pyx_n_s_s1; + PyObject *__pyx_n_s_s1x; + PyObject *__pyx_n_s_s1y; + PyObject *__pyx_n_s_s2; + PyObject *__pyx_n_s_s2x; + PyObject *__pyx_n_s_s2y; + PyObject *__pyx_kp_u_s_2; + PyObject *__pyx_n_s_scale; + PyObject *__pyx_n_s_sectRect; + PyObject *__pyx_n_s_seen; + PyObject *__pyx_n_s_seg; + PyObject *__pyx_n_s_seg1; + PyObject *__pyx_n_s_seg2; + PyObject *__pyx_n_s_segment; + PyObject *__pyx_n_s_segmentPointAtT; + PyObject *__pyx_n_u_segmentPointAtT; + PyObject *__pyx_n_s_segmentSegmentIntersections; + PyObject *__pyx_n_u_segmentSegmentIntersections; + PyObject *__pyx_kp_u_segmentSegmentIntersections_line; + PyObject *__pyx_n_s_segmentrepr; + PyObject *__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2; + PyObject *__pyx_kp_u_segmentrepr_line_1465; + PyObject *__pyx_n_s_segmentrepr_locals_genexpr; + PyObject *__pyx_n_s_segments; + PyObject *__pyx_n_s_send; + PyObject *__pyx_n_s_slope12; + PyObject *__pyx_n_s_slope34; + PyObject *__pyx_n_s_solutions; + PyObject *__pyx_n_s_solveCubic; + PyObject *__pyx_n_u_solveCubic; + PyObject *__pyx_kp_u_solveCubic_line_841; + PyObject *__pyx_n_s_solveQuadratic; + PyObject *__pyx_n_u_solveQuadratic; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_splitCubic; + PyObject *__pyx_n_u_splitCubic; + PyObject *__pyx_n_s_splitCubicAtT; + PyObject *__pyx_n_s_splitCubicAtTC; + PyObject *__pyx_n_u_splitCubicAtTC; + PyObject *__pyx_n_s_splitCubicAtTC_2; + PyObject *__pyx_n_s_splitCubicAtT_2; + PyObject *__pyx_n_u_splitCubicAtT_2; + PyObject *__pyx_kp_u_splitCubicAtT_line_613; + PyObject *__pyx_n_s_splitCubicIntoTwoAtTC; + PyObject *__pyx_n_u_splitCubicIntoTwoAtTC; + PyObject *__pyx_kp_u_splitCubic_line_552; + PyObject *__pyx_n_s_splitCubic_locals_genexpr; + PyObject *__pyx_n_s_splitLine; + PyObject *__pyx_n_u_splitLine; + PyObject *__pyx_kp_u_splitLine_line_450; + PyObject *__pyx_n_s_splitQuadratic; + PyObject *__pyx_n_u_splitQuadratic; + PyObject *__pyx_n_s_splitQuadraticAtT; + PyObject *__pyx_n_s_splitQuadraticAtT_2; + PyObject *__pyx_n_u_splitQuadraticAtT_2; + PyObject *__pyx_kp_u_splitQuadraticAtT_line_589; + PyObject *__pyx_kp_u_splitQuadratic_line_507; + PyObject *__pyx_n_s_splitQuadratic_locals_genexpr; + PyObject *__pyx_n_s_split_cubic_into_two; + PyObject *__pyx_n_s_split_segment_at_t; + PyObject *__pyx_n_s_sqrt; + PyObject *__pyx_n_s_start; + PyObject *__pyx_n_s_swapped; + PyObject *__pyx_n_s_sx; + PyObject *__pyx_n_s_sy; + PyObject *__pyx_n_s_sys; + PyObject *__pyx_n_s_t; + PyObject *__pyx_n_s_t1; + PyObject *__pyx_n_u_t1; + PyObject *__pyx_n_s_t1_2; + PyObject *__pyx_n_s_t1_3; + PyObject *__pyx_n_s_t2; + PyObject *__pyx_n_u_t2; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_testmod; + PyObject *__pyx_n_s_theta; + PyObject *__pyx_n_s_throw; + PyObject *__pyx_n_s_tolerance; + PyObject *__pyx_n_s_transformPoints; + PyObject *__pyx_n_s_translate; + PyObject *__pyx_n_s_ts; + PyObject *__pyx_n_s_two; + PyObject *__pyx_n_s_unique_key; + PyObject *__pyx_n_s_unique_values; + PyObject *__pyx_n_s_v0; + PyObject *__pyx_n_s_v1; + PyObject *__pyx_n_s_v2; + PyObject *__pyx_n_s_v3; + PyObject *__pyx_n_s_v4; + PyObject *__pyx_n_s_where; + PyObject *__pyx_n_s_x; + PyObject *__pyx_n_s_x0; + PyObject *__pyx_n_s_x1; + PyObject *__pyx_n_s_x2; + PyObject *__pyx_n_s_x3; + PyObject *__pyx_n_s_x4; + PyObject *__pyx_n_s_xDiff; + PyObject *__pyx_n_s_xRoots; + PyObject *__pyx_n_s_y; + PyObject *__pyx_n_s_y1; + PyObject *__pyx_n_s_y2; + PyObject *__pyx_n_s_y3; + PyObject *__pyx_n_s_y4; + PyObject *__pyx_n_s_yDiff; + PyObject *__pyx_n_s_yRoots; + PyObject *__pyx_float_0_0; + PyObject *__pyx_float_0_5; + PyObject *__pyx_float_1_0; + PyObject *__pyx_float_2_0; + PyObject *__pyx_float_3_0; + PyObject *__pyx_float_4_0; + PyObject *__pyx_float_9_0; + PyObject *__pyx_float_1eneg_3; + PyObject *__pyx_float_27_0; + PyObject *__pyx_float_54_0; + PyObject *__pyx_float_0_005; + PyObject *__pyx_float_0_125; + PyObject *__pyx_float_1eneg_10; + PyObject *__pyx_float_neg_2_0; + PyObject *__pyx_int_0; + PyObject *__pyx_int_1; + PyObject *__pyx_int_2; + PyObject *__pyx_int_3; + PyObject *__pyx_int_6; + PyObject *__pyx_int_neg_1; + PyObject *__pyx_codeobj_; + PyObject *__pyx_tuple__2; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__5; + PyObject *__pyx_tuple__6; + PyObject *__pyx_tuple__8; + PyObject *__pyx_tuple__12; + PyObject *__pyx_tuple__14; + PyObject *__pyx_tuple__15; + PyObject *__pyx_tuple__17; + PyObject *__pyx_tuple__19; + PyObject *__pyx_tuple__21; + PyObject *__pyx_tuple__23; + PyObject *__pyx_tuple__26; + PyObject *__pyx_tuple__28; + PyObject *__pyx_tuple__30; + PyObject *__pyx_tuple__32; + PyObject *__pyx_tuple__34; + PyObject *__pyx_tuple__36; + PyObject *__pyx_tuple__38; + PyObject *__pyx_tuple__40; + PyObject *__pyx_tuple__42; + PyObject *__pyx_tuple__44; + PyObject *__pyx_tuple__46; + PyObject *__pyx_tuple__48; + PyObject *__pyx_tuple__50; + PyObject *__pyx_tuple__52; + PyObject *__pyx_tuple__53; + PyObject *__pyx_tuple__55; + PyObject *__pyx_tuple__57; + PyObject *__pyx_tuple__59; + PyObject *__pyx_tuple__61; + PyObject *__pyx_tuple__63; + PyObject *__pyx_tuple__65; + PyObject *__pyx_tuple__67; + PyObject *__pyx_tuple__69; + PyObject *__pyx_tuple__71; + PyObject *__pyx_tuple__73; + PyObject *__pyx_tuple__75; + PyObject *__pyx_tuple__77; + PyObject *__pyx_tuple__79; + PyObject *__pyx_tuple__81; + PyObject *__pyx_tuple__83; + PyObject *__pyx_tuple__85; + PyObject *__pyx_tuple__87; + PyObject *__pyx_tuple__89; + PyObject *__pyx_tuple__92; + PyObject *__pyx_tuple__94; + PyObject *__pyx_tuple__95; + PyObject *__pyx_tuple__97; + PyObject *__pyx_tuple__99; + PyObject *__pyx_codeobj__3; + PyObject *__pyx_codeobj__7; + PyObject *__pyx_tuple__101; + PyObject *__pyx_tuple__103; + PyObject *__pyx_codeobj__13; + PyObject *__pyx_codeobj__16; + PyObject *__pyx_codeobj__18; + PyObject *__pyx_codeobj__20; + PyObject *__pyx_codeobj__22; + PyObject *__pyx_codeobj__24; + PyObject *__pyx_codeobj__25; + PyObject *__pyx_codeobj__27; + PyObject *__pyx_codeobj__29; + PyObject *__pyx_codeobj__31; + PyObject *__pyx_codeobj__33; + PyObject *__pyx_codeobj__35; + PyObject *__pyx_codeobj__37; + PyObject *__pyx_codeobj__39; + PyObject *__pyx_codeobj__41; + PyObject *__pyx_codeobj__43; + PyObject *__pyx_codeobj__45; + PyObject *__pyx_codeobj__47; + PyObject *__pyx_codeobj__49; + PyObject *__pyx_codeobj__51; + PyObject *__pyx_codeobj__54; + PyObject *__pyx_codeobj__56; + PyObject *__pyx_codeobj__58; + PyObject *__pyx_codeobj__60; + PyObject *__pyx_codeobj__62; + PyObject *__pyx_codeobj__64; + PyObject *__pyx_codeobj__66; + PyObject *__pyx_codeobj__68; + PyObject *__pyx_codeobj__70; + PyObject *__pyx_codeobj__72; + PyObject *__pyx_codeobj__74; + PyObject *__pyx_codeobj__76; + PyObject *__pyx_codeobj__78; + PyObject *__pyx_codeobj__80; + PyObject *__pyx_codeobj__82; + PyObject *__pyx_codeobj__84; + PyObject *__pyx_codeobj__86; + PyObject *__pyx_codeobj__88; + PyObject *__pyx_codeobj__90; + PyObject *__pyx_codeobj__93; + PyObject *__pyx_codeobj__96; + PyObject *__pyx_codeobj__98; + PyObject *__pyx_codeobj__100; + PyObject *__pyx_codeobj__102; + PyObject *__pyx_codeobj__104; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_1_t); + Py_CLEAR(clear_module_state->__pyx_n_s_1_t_2); + Py_CLEAR(clear_module_state->__pyx_n_s_2_t_1_t); + Py_CLEAR(clear_module_state->__pyx_kp_u_Approximates_the_arc_length_for); + Py_CLEAR(clear_module_state->__pyx_n_s_AttributeError); + Py_CLEAR(clear_module_state->__pyx_n_s_COMPILED); + Py_CLEAR(clear_module_state->__pyx_kp_u_Calculates_the_arc_length_for_a); + Py_CLEAR(clear_module_state->__pyx_kp_u_Calculates_the_bounding_rectangl); + Py_CLEAR(clear_module_state->__pyx_kp_u_Calculates_the_bounding_rectangl_2); + Py_CLEAR(clear_module_state->__pyx_kp_u_Couldn_t_work_out_which_intersec); + Py_CLEAR(clear_module_state->__pyx_n_s_DD); + Py_CLEAR(clear_module_state->__pyx_kp_u_Finds_intersections_between_a_cu); + Py_CLEAR(clear_module_state->__pyx_kp_u_Finds_intersections_between_a_cu_2); + Py_CLEAR(clear_module_state->__pyx_kp_u_Finds_intersections_between_two); + Py_CLEAR(clear_module_state->__pyx_kp_u_Finds_intersections_between_two_2); + Py_CLEAR(clear_module_state->__pyx_n_s_Identity); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_n_s_Intersection); + Py_CLEAR(clear_module_state->__pyx_n_u_Intersection); + Py_CLEAR(clear_module_state->__pyx_n_s_Len); + Py_CLEAR(clear_module_state->__pyx_kp_s_Lib_fontTools_misc_bezierTools_p); + Py_CLEAR(clear_module_state->__pyx_n_s_Q); + Py_CLEAR(clear_module_state->__pyx_n_s_Q3); + Py_CLEAR(clear_module_state->__pyx_n_s_R); + Py_CLEAR(clear_module_state->__pyx_n_s_R2); + Py_CLEAR(clear_module_state->__pyx_n_s_R2_Q3); + Py_CLEAR(clear_module_state->__pyx_kp_u_Solve_a_cubic_equation_Solves_a); + Py_CLEAR(clear_module_state->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a); + Py_CLEAR(clear_module_state->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on); + Py_CLEAR(clear_module_state->__pyx_kp_u_Split_a_line_at_a_given_coordina); + Py_CLEAR(clear_module_state->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a); + Py_CLEAR(clear_module_state->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2); + Py_CLEAR(clear_module_state->__pyx_n_s_TypeError); + Py_CLEAR(clear_module_state->__pyx_kp_u_Unknown_curve_degree); + Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); + Py_CLEAR(clear_module_state->__pyx_kp_u__10); + Py_CLEAR(clear_module_state->__pyx_n_s__105); + Py_CLEAR(clear_module_state->__pyx_n_s__11); + Py_CLEAR(clear_module_state->__pyx_kp_u__9); + Py_CLEAR(clear_module_state->__pyx_n_s__91); + Py_CLEAR(clear_module_state->__pyx_n_s_a); + Py_CLEAR(clear_module_state->__pyx_n_s_a1); + Py_CLEAR(clear_module_state->__pyx_n_s_a1_3); + Py_CLEAR(clear_module_state->__pyx_n_s_a1x); + Py_CLEAR(clear_module_state->__pyx_n_s_a1y); + Py_CLEAR(clear_module_state->__pyx_n_s_a2); + Py_CLEAR(clear_module_state->__pyx_n_s_a3); + Py_CLEAR(clear_module_state->__pyx_n_s_acos); + Py_CLEAR(clear_module_state->__pyx_n_s_aligned_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_alignment_transformation); + Py_CLEAR(clear_module_state->__pyx_n_s_all); + Py_CLEAR(clear_module_state->__pyx_n_s_angle); + Py_CLEAR(clear_module_state->__pyx_n_s_append); + Py_CLEAR(clear_module_state->__pyx_n_s_approximateCubicArcLength); + Py_CLEAR(clear_module_state->__pyx_n_u_approximateCubicArcLength); + Py_CLEAR(clear_module_state->__pyx_n_s_approximateCubicArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_u_approximateCubicArcLengthC); + Py_CLEAR(clear_module_state->__pyx_kp_u_approximateCubicArcLength_line_3); + Py_CLEAR(clear_module_state->__pyx_n_s_approximateQuadraticArcLength); + Py_CLEAR(clear_module_state->__pyx_n_u_approximateQuadraticArcLength); + Py_CLEAR(clear_module_state->__pyx_n_s_approximateQuadraticArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_u_approximateQuadraticArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_s_arch); + Py_CLEAR(clear_module_state->__pyx_n_s_args); + Py_CLEAR(clear_module_state->__pyx_n_s_asinh); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_atan2); + Py_CLEAR(clear_module_state->__pyx_n_s_ax); + Py_CLEAR(clear_module_state->__pyx_n_s_ax2); + Py_CLEAR(clear_module_state->__pyx_n_s_ax3); + Py_CLEAR(clear_module_state->__pyx_n_s_ay); + Py_CLEAR(clear_module_state->__pyx_n_s_ay2); + Py_CLEAR(clear_module_state->__pyx_n_s_ay3); + Py_CLEAR(clear_module_state->__pyx_n_s_b); + Py_CLEAR(clear_module_state->__pyx_n_s_b1); + Py_CLEAR(clear_module_state->__pyx_n_s_b1x); + Py_CLEAR(clear_module_state->__pyx_n_s_b1y); + Py_CLEAR(clear_module_state->__pyx_n_s_both_points_are_on_same_side_of); + Py_CLEAR(clear_module_state->__pyx_n_s_bounds1); + Py_CLEAR(clear_module_state->__pyx_n_s_bounds2); + Py_CLEAR(clear_module_state->__pyx_n_s_box); + Py_CLEAR(clear_module_state->__pyx_n_s_bx); + Py_CLEAR(clear_module_state->__pyx_n_s_bx2); + Py_CLEAR(clear_module_state->__pyx_n_s_by); + Py_CLEAR(clear_module_state->__pyx_n_s_by2); + Py_CLEAR(clear_module_state->__pyx_n_s_c); + Py_CLEAR(clear_module_state->__pyx_n_s_c1); + Py_CLEAR(clear_module_state->__pyx_n_s_c11); + Py_CLEAR(clear_module_state->__pyx_n_s_c11_range); + Py_CLEAR(clear_module_state->__pyx_n_s_c12); + Py_CLEAR(clear_module_state->__pyx_n_s_c12_range); + Py_CLEAR(clear_module_state->__pyx_n_s_c1x); + Py_CLEAR(clear_module_state->__pyx_n_s_c1y); + Py_CLEAR(clear_module_state->__pyx_n_s_c21); + Py_CLEAR(clear_module_state->__pyx_n_s_c21_range); + Py_CLEAR(clear_module_state->__pyx_n_s_c22); + Py_CLEAR(clear_module_state->__pyx_n_s_c22_range); + Py_CLEAR(clear_module_state->__pyx_n_s_calcBounds); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicArcLength); + Py_CLEAR(clear_module_state->__pyx_n_u_calcCubicArcLength); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_u_calcCubicArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicArcLengthCRecurse); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicBounds); + Py_CLEAR(clear_module_state->__pyx_n_u_calcCubicBounds); + Py_CLEAR(clear_module_state->__pyx_kp_u_calcCubicBounds_line_412); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicParameters); + Py_CLEAR(clear_module_state->__pyx_n_s_calcCubicPoints); + Py_CLEAR(clear_module_state->__pyx_n_s_calcQuadraticArcLength); + Py_CLEAR(clear_module_state->__pyx_n_u_calcQuadraticArcLength); + Py_CLEAR(clear_module_state->__pyx_n_s_calcQuadraticArcLengthC); + Py_CLEAR(clear_module_state->__pyx_n_u_calcQuadraticArcLengthC); + Py_CLEAR(clear_module_state->__pyx_kp_u_calcQuadraticArcLength_line_151); + Py_CLEAR(clear_module_state->__pyx_n_s_calcQuadraticBounds); + Py_CLEAR(clear_module_state->__pyx_n_u_calcQuadraticBounds); + Py_CLEAR(clear_module_state->__pyx_kp_u_calcQuadraticBounds_line_298); + Py_CLEAR(clear_module_state->__pyx_n_s_calcQuadraticParameters); + Py_CLEAR(clear_module_state->__pyx_n_s_calcQuadraticPoints); + Py_CLEAR(clear_module_state->__pyx_n_s_class_getitem); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_close); + Py_CLEAR(clear_module_state->__pyx_n_s_collections); + Py_CLEAR(clear_module_state->__pyx_n_s_cos); + Py_CLEAR(clear_module_state->__pyx_n_s_cubicPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_u_cubicPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_cubicPointAtTC); + Py_CLEAR(clear_module_state->__pyx_n_u_cubicPointAtTC); + Py_CLEAR(clear_module_state->__pyx_n_s_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_curve1); + Py_CLEAR(clear_module_state->__pyx_n_s_curve2); + Py_CLEAR(clear_module_state->__pyx_n_s_curveCurveIntersections); + Py_CLEAR(clear_module_state->__pyx_n_u_curveCurveIntersections); + Py_CLEAR(clear_module_state->__pyx_kp_u_curveCurveIntersections_line_137); + Py_CLEAR(clear_module_state->__pyx_n_s_curveLineIntersections); + Py_CLEAR(clear_module_state->__pyx_n_u_curveLineIntersections); + Py_CLEAR(clear_module_state->__pyx_kp_u_curveLineIntersections_line_1248); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_bounds); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_curve_intersections_t); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_curve_intersections_t_loc); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_curve_intersections_t_loc_2); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_line_intersections_t); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_line_intersections_t_loca); + Py_CLEAR(clear_module_state->__pyx_n_s_cx); + Py_CLEAR(clear_module_state->__pyx_n_s_cy); + Py_CLEAR(clear_module_state->__pyx_n_s_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_d); + Py_CLEAR(clear_module_state->__pyx_n_s_d0); + Py_CLEAR(clear_module_state->__pyx_n_s_d1); + Py_CLEAR(clear_module_state->__pyx_n_s_d1x); + Py_CLEAR(clear_module_state->__pyx_n_s_d1y); + Py_CLEAR(clear_module_state->__pyx_n_s_delta); + Py_CLEAR(clear_module_state->__pyx_n_s_delta_2); + Py_CLEAR(clear_module_state->__pyx_n_s_delta_3); + Py_CLEAR(clear_module_state->__pyx_n_s_deriv3); + Py_CLEAR(clear_module_state->__pyx_kp_u_disable); + Py_CLEAR(clear_module_state->__pyx_n_s_doctest); + Py_CLEAR(clear_module_state->__pyx_n_s_dx); + Py_CLEAR(clear_module_state->__pyx_n_s_dy); + Py_CLEAR(clear_module_state->__pyx_n_s_e); + Py_CLEAR(clear_module_state->__pyx_n_s_e1); + Py_CLEAR(clear_module_state->__pyx_n_s_e1x); + Py_CLEAR(clear_module_state->__pyx_n_s_e1y); + Py_CLEAR(clear_module_state->__pyx_n_s_e2); + Py_CLEAR(clear_module_state->__pyx_n_s_e2x); + Py_CLEAR(clear_module_state->__pyx_n_s_e2y); + Py_CLEAR(clear_module_state->__pyx_kp_u_enable); + Py_CLEAR(clear_module_state->__pyx_n_s_end); + Py_CLEAR(clear_module_state->__pyx_n_s_epsilon); + Py_CLEAR(clear_module_state->__pyx_n_s_epsilonDigits); + Py_CLEAR(clear_module_state->__pyx_n_s_ex); + Py_CLEAR(clear_module_state->__pyx_n_s_exit); + Py_CLEAR(clear_module_state->__pyx_n_s_ey); + Py_CLEAR(clear_module_state->__pyx_n_s_failed); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc_arrayTools); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc_bezierTools); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc_transform); + Py_CLEAR(clear_module_state->__pyx_n_s_found); + Py_CLEAR(clear_module_state->__pyx_kp_u_g); + Py_CLEAR(clear_module_state->__pyx_kp_u_gc); + Py_CLEAR(clear_module_state->__pyx_n_s_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_i); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_n_s_insert); + Py_CLEAR(clear_module_state->__pyx_n_s_intersection_ts); + Py_CLEAR(clear_module_state->__pyx_n_s_intersections); + Py_CLEAR(clear_module_state->__pyx_n_s_intersects); + Py_CLEAR(clear_module_state->__pyx_n_s_isHorizontal); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_n_s_is_linelike); + Py_CLEAR(clear_module_state->__pyx_n_s_is_linelike_locals_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_isclose); + Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); + Py_CLEAR(clear_module_state->__pyx_n_s_it); + Py_CLEAR(clear_module_state->__pyx_n_s_key); + Py_CLEAR(clear_module_state->__pyx_n_s_line); + Py_CLEAR(clear_module_state->__pyx_n_s_line1); + Py_CLEAR(clear_module_state->__pyx_n_s_line2); + Py_CLEAR(clear_module_state->__pyx_n_s_lineLineIntersections); + Py_CLEAR(clear_module_state->__pyx_n_u_lineLineIntersections); + Py_CLEAR(clear_module_state->__pyx_kp_u_lineLineIntersections_line_1147); + Py_CLEAR(clear_module_state->__pyx_n_s_linePointAtT); + Py_CLEAR(clear_module_state->__pyx_n_u_linePointAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_line_t); + Py_CLEAR(clear_module_state->__pyx_n_s_line_t_of_pt); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_u_main); + Py_CLEAR(clear_module_state->__pyx_n_s_math); + Py_CLEAR(clear_module_state->__pyx_n_s_maybeline); + Py_CLEAR(clear_module_state->__pyx_n_s_mid); + Py_CLEAR(clear_module_state->__pyx_n_s_midPt); + Py_CLEAR(clear_module_state->__pyx_n_s_midpoint); + Py_CLEAR(clear_module_state->__pyx_n_s_mult); + Py_CLEAR(clear_module_state->__pyx_n_s_n); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_namedtuple); + Py_CLEAR(clear_module_state->__pyx_n_s_obj); + Py_CLEAR(clear_module_state->__pyx_n_s_off1); + Py_CLEAR(clear_module_state->__pyx_n_s_off2); + Py_CLEAR(clear_module_state->__pyx_n_s_one); + Py_CLEAR(clear_module_state->__pyx_n_s_origDist); + Py_CLEAR(clear_module_state->__pyx_n_s_origin); + Py_CLEAR(clear_module_state->__pyx_n_s_p0); + Py_CLEAR(clear_module_state->__pyx_n_s_p1); + Py_CLEAR(clear_module_state->__pyx_n_s_p2); + Py_CLEAR(clear_module_state->__pyx_n_s_p3); + Py_CLEAR(clear_module_state->__pyx_n_s_pi); + Py_CLEAR(clear_module_state->__pyx_n_s_pointAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_pointFinder); + Py_CLEAR(clear_module_state->__pyx_n_s_points); + Py_CLEAR(clear_module_state->__pyx_n_s_precision); + Py_CLEAR(clear_module_state->__pyx_n_s_print); + Py_CLEAR(clear_module_state->__pyx_n_s_printSegments); + Py_CLEAR(clear_module_state->__pyx_n_s_pt); + Py_CLEAR(clear_module_state->__pyx_n_u_pt); + Py_CLEAR(clear_module_state->__pyx_n_s_pt1); + Py_CLEAR(clear_module_state->__pyx_n_s_pt1x); + Py_CLEAR(clear_module_state->__pyx_n_s_pt1y); + Py_CLEAR(clear_module_state->__pyx_n_s_pt2); + Py_CLEAR(clear_module_state->__pyx_n_s_pt2x); + Py_CLEAR(clear_module_state->__pyx_n_s_pt2y); + Py_CLEAR(clear_module_state->__pyx_n_s_pt3); + Py_CLEAR(clear_module_state->__pyx_n_s_pt4); + Py_CLEAR(clear_module_state->__pyx_n_s_px); + Py_CLEAR(clear_module_state->__pyx_n_s_py); + Py_CLEAR(clear_module_state->__pyx_n_s_quadraticPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_u_quadraticPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_r); + Py_CLEAR(clear_module_state->__pyx_n_s_rDD); + Py_CLEAR(clear_module_state->__pyx_n_s_rQ2); + Py_CLEAR(clear_module_state->__pyx_n_s_range); + Py_CLEAR(clear_module_state->__pyx_n_s_range1); + Py_CLEAR(clear_module_state->__pyx_n_s_range2); + Py_CLEAR(clear_module_state->__pyx_n_s_rectArea); + Py_CLEAR(clear_module_state->__pyx_n_s_roots); + Py_CLEAR(clear_module_state->__pyx_n_s_rotate); + Py_CLEAR(clear_module_state->__pyx_n_s_round); + Py_CLEAR(clear_module_state->__pyx_n_s_s); + Py_CLEAR(clear_module_state->__pyx_n_s_s1); + Py_CLEAR(clear_module_state->__pyx_n_s_s1x); + Py_CLEAR(clear_module_state->__pyx_n_s_s1y); + Py_CLEAR(clear_module_state->__pyx_n_s_s2); + Py_CLEAR(clear_module_state->__pyx_n_s_s2x); + Py_CLEAR(clear_module_state->__pyx_n_s_s2y); + Py_CLEAR(clear_module_state->__pyx_kp_u_s_2); + Py_CLEAR(clear_module_state->__pyx_n_s_scale); + Py_CLEAR(clear_module_state->__pyx_n_s_sectRect); + Py_CLEAR(clear_module_state->__pyx_n_s_seen); + Py_CLEAR(clear_module_state->__pyx_n_s_seg); + Py_CLEAR(clear_module_state->__pyx_n_s_seg1); + Py_CLEAR(clear_module_state->__pyx_n_s_seg2); + Py_CLEAR(clear_module_state->__pyx_n_s_segment); + Py_CLEAR(clear_module_state->__pyx_n_s_segmentPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_u_segmentPointAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_segmentSegmentIntersections); + Py_CLEAR(clear_module_state->__pyx_n_u_segmentSegmentIntersections); + Py_CLEAR(clear_module_state->__pyx_kp_u_segmentSegmentIntersections_line); + Py_CLEAR(clear_module_state->__pyx_n_s_segmentrepr); + Py_CLEAR(clear_module_state->__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2); + Py_CLEAR(clear_module_state->__pyx_kp_u_segmentrepr_line_1465); + Py_CLEAR(clear_module_state->__pyx_n_s_segmentrepr_locals_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_segments); + Py_CLEAR(clear_module_state->__pyx_n_s_send); + Py_CLEAR(clear_module_state->__pyx_n_s_slope12); + Py_CLEAR(clear_module_state->__pyx_n_s_slope34); + Py_CLEAR(clear_module_state->__pyx_n_s_solutions); + Py_CLEAR(clear_module_state->__pyx_n_s_solveCubic); + Py_CLEAR(clear_module_state->__pyx_n_u_solveCubic); + Py_CLEAR(clear_module_state->__pyx_kp_u_solveCubic_line_841); + Py_CLEAR(clear_module_state->__pyx_n_s_solveQuadratic); + Py_CLEAR(clear_module_state->__pyx_n_u_solveQuadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubic); + Py_CLEAR(clear_module_state->__pyx_n_u_splitCubic); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_n_u_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicAtTC_2); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicAtT_2); + Py_CLEAR(clear_module_state->__pyx_n_u_splitCubicAtT_2); + Py_CLEAR(clear_module_state->__pyx_kp_u_splitCubicAtT_line_613); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicIntoTwoAtTC); + Py_CLEAR(clear_module_state->__pyx_n_u_splitCubicIntoTwoAtTC); + Py_CLEAR(clear_module_state->__pyx_kp_u_splitCubic_line_552); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubic_locals_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_splitLine); + Py_CLEAR(clear_module_state->__pyx_n_u_splitLine); + Py_CLEAR(clear_module_state->__pyx_kp_u_splitLine_line_450); + Py_CLEAR(clear_module_state->__pyx_n_s_splitQuadratic); + Py_CLEAR(clear_module_state->__pyx_n_u_splitQuadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_splitQuadraticAtT); + Py_CLEAR(clear_module_state->__pyx_n_s_splitQuadraticAtT_2); + Py_CLEAR(clear_module_state->__pyx_n_u_splitQuadraticAtT_2); + Py_CLEAR(clear_module_state->__pyx_kp_u_splitQuadraticAtT_line_589); + Py_CLEAR(clear_module_state->__pyx_kp_u_splitQuadratic_line_507); + Py_CLEAR(clear_module_state->__pyx_n_s_splitQuadratic_locals_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_split_cubic_into_two); + Py_CLEAR(clear_module_state->__pyx_n_s_split_segment_at_t); + Py_CLEAR(clear_module_state->__pyx_n_s_sqrt); + Py_CLEAR(clear_module_state->__pyx_n_s_start); + Py_CLEAR(clear_module_state->__pyx_n_s_swapped); + Py_CLEAR(clear_module_state->__pyx_n_s_sx); + Py_CLEAR(clear_module_state->__pyx_n_s_sy); + Py_CLEAR(clear_module_state->__pyx_n_s_sys); + Py_CLEAR(clear_module_state->__pyx_n_s_t); + Py_CLEAR(clear_module_state->__pyx_n_s_t1); + Py_CLEAR(clear_module_state->__pyx_n_u_t1); + Py_CLEAR(clear_module_state->__pyx_n_s_t1_2); + Py_CLEAR(clear_module_state->__pyx_n_s_t1_3); + Py_CLEAR(clear_module_state->__pyx_n_s_t2); + Py_CLEAR(clear_module_state->__pyx_n_u_t2); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_testmod); + Py_CLEAR(clear_module_state->__pyx_n_s_theta); + Py_CLEAR(clear_module_state->__pyx_n_s_throw); + Py_CLEAR(clear_module_state->__pyx_n_s_tolerance); + Py_CLEAR(clear_module_state->__pyx_n_s_transformPoints); + Py_CLEAR(clear_module_state->__pyx_n_s_translate); + Py_CLEAR(clear_module_state->__pyx_n_s_ts); + Py_CLEAR(clear_module_state->__pyx_n_s_two); + Py_CLEAR(clear_module_state->__pyx_n_s_unique_key); + Py_CLEAR(clear_module_state->__pyx_n_s_unique_values); + Py_CLEAR(clear_module_state->__pyx_n_s_v0); + Py_CLEAR(clear_module_state->__pyx_n_s_v1); + Py_CLEAR(clear_module_state->__pyx_n_s_v2); + Py_CLEAR(clear_module_state->__pyx_n_s_v3); + Py_CLEAR(clear_module_state->__pyx_n_s_v4); + Py_CLEAR(clear_module_state->__pyx_n_s_where); + Py_CLEAR(clear_module_state->__pyx_n_s_x); + Py_CLEAR(clear_module_state->__pyx_n_s_x0); + Py_CLEAR(clear_module_state->__pyx_n_s_x1); + Py_CLEAR(clear_module_state->__pyx_n_s_x2); + Py_CLEAR(clear_module_state->__pyx_n_s_x3); + Py_CLEAR(clear_module_state->__pyx_n_s_x4); + Py_CLEAR(clear_module_state->__pyx_n_s_xDiff); + Py_CLEAR(clear_module_state->__pyx_n_s_xRoots); + Py_CLEAR(clear_module_state->__pyx_n_s_y); + Py_CLEAR(clear_module_state->__pyx_n_s_y1); + Py_CLEAR(clear_module_state->__pyx_n_s_y2); + Py_CLEAR(clear_module_state->__pyx_n_s_y3); + Py_CLEAR(clear_module_state->__pyx_n_s_y4); + Py_CLEAR(clear_module_state->__pyx_n_s_yDiff); + Py_CLEAR(clear_module_state->__pyx_n_s_yRoots); + Py_CLEAR(clear_module_state->__pyx_float_0_0); + Py_CLEAR(clear_module_state->__pyx_float_0_5); + Py_CLEAR(clear_module_state->__pyx_float_1_0); + Py_CLEAR(clear_module_state->__pyx_float_2_0); + Py_CLEAR(clear_module_state->__pyx_float_3_0); + Py_CLEAR(clear_module_state->__pyx_float_4_0); + Py_CLEAR(clear_module_state->__pyx_float_9_0); + Py_CLEAR(clear_module_state->__pyx_float_1eneg_3); + Py_CLEAR(clear_module_state->__pyx_float_27_0); + Py_CLEAR(clear_module_state->__pyx_float_54_0); + Py_CLEAR(clear_module_state->__pyx_float_0_005); + Py_CLEAR(clear_module_state->__pyx_float_0_125); + Py_CLEAR(clear_module_state->__pyx_float_1eneg_10); + Py_CLEAR(clear_module_state->__pyx_float_neg_2_0); + Py_CLEAR(clear_module_state->__pyx_int_0); + Py_CLEAR(clear_module_state->__pyx_int_1); + Py_CLEAR(clear_module_state->__pyx_int_2); + Py_CLEAR(clear_module_state->__pyx_int_3); + Py_CLEAR(clear_module_state->__pyx_int_6); + Py_CLEAR(clear_module_state->__pyx_int_neg_1); + Py_CLEAR(clear_module_state->__pyx_codeobj_); + Py_CLEAR(clear_module_state->__pyx_tuple__2); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__5); + Py_CLEAR(clear_module_state->__pyx_tuple__6); + Py_CLEAR(clear_module_state->__pyx_tuple__8); + Py_CLEAR(clear_module_state->__pyx_tuple__12); + Py_CLEAR(clear_module_state->__pyx_tuple__14); + Py_CLEAR(clear_module_state->__pyx_tuple__15); + Py_CLEAR(clear_module_state->__pyx_tuple__17); + Py_CLEAR(clear_module_state->__pyx_tuple__19); + Py_CLEAR(clear_module_state->__pyx_tuple__21); + Py_CLEAR(clear_module_state->__pyx_tuple__23); + Py_CLEAR(clear_module_state->__pyx_tuple__26); + Py_CLEAR(clear_module_state->__pyx_tuple__28); + Py_CLEAR(clear_module_state->__pyx_tuple__30); + Py_CLEAR(clear_module_state->__pyx_tuple__32); + Py_CLEAR(clear_module_state->__pyx_tuple__34); + Py_CLEAR(clear_module_state->__pyx_tuple__36); + Py_CLEAR(clear_module_state->__pyx_tuple__38); + Py_CLEAR(clear_module_state->__pyx_tuple__40); + Py_CLEAR(clear_module_state->__pyx_tuple__42); + Py_CLEAR(clear_module_state->__pyx_tuple__44); + Py_CLEAR(clear_module_state->__pyx_tuple__46); + Py_CLEAR(clear_module_state->__pyx_tuple__48); + Py_CLEAR(clear_module_state->__pyx_tuple__50); + Py_CLEAR(clear_module_state->__pyx_tuple__52); + Py_CLEAR(clear_module_state->__pyx_tuple__53); + Py_CLEAR(clear_module_state->__pyx_tuple__55); + Py_CLEAR(clear_module_state->__pyx_tuple__57); + Py_CLEAR(clear_module_state->__pyx_tuple__59); + Py_CLEAR(clear_module_state->__pyx_tuple__61); + Py_CLEAR(clear_module_state->__pyx_tuple__63); + Py_CLEAR(clear_module_state->__pyx_tuple__65); + Py_CLEAR(clear_module_state->__pyx_tuple__67); + Py_CLEAR(clear_module_state->__pyx_tuple__69); + Py_CLEAR(clear_module_state->__pyx_tuple__71); + Py_CLEAR(clear_module_state->__pyx_tuple__73); + Py_CLEAR(clear_module_state->__pyx_tuple__75); + Py_CLEAR(clear_module_state->__pyx_tuple__77); + Py_CLEAR(clear_module_state->__pyx_tuple__79); + Py_CLEAR(clear_module_state->__pyx_tuple__81); + Py_CLEAR(clear_module_state->__pyx_tuple__83); + Py_CLEAR(clear_module_state->__pyx_tuple__85); + Py_CLEAR(clear_module_state->__pyx_tuple__87); + Py_CLEAR(clear_module_state->__pyx_tuple__89); + Py_CLEAR(clear_module_state->__pyx_tuple__92); + Py_CLEAR(clear_module_state->__pyx_tuple__94); + Py_CLEAR(clear_module_state->__pyx_tuple__95); + Py_CLEAR(clear_module_state->__pyx_tuple__97); + Py_CLEAR(clear_module_state->__pyx_tuple__99); + Py_CLEAR(clear_module_state->__pyx_codeobj__3); + Py_CLEAR(clear_module_state->__pyx_codeobj__7); + Py_CLEAR(clear_module_state->__pyx_tuple__101); + Py_CLEAR(clear_module_state->__pyx_tuple__103); + Py_CLEAR(clear_module_state->__pyx_codeobj__13); + Py_CLEAR(clear_module_state->__pyx_codeobj__16); + Py_CLEAR(clear_module_state->__pyx_codeobj__18); + Py_CLEAR(clear_module_state->__pyx_codeobj__20); + Py_CLEAR(clear_module_state->__pyx_codeobj__22); + Py_CLEAR(clear_module_state->__pyx_codeobj__24); + Py_CLEAR(clear_module_state->__pyx_codeobj__25); + Py_CLEAR(clear_module_state->__pyx_codeobj__27); + Py_CLEAR(clear_module_state->__pyx_codeobj__29); + Py_CLEAR(clear_module_state->__pyx_codeobj__31); + Py_CLEAR(clear_module_state->__pyx_codeobj__33); + Py_CLEAR(clear_module_state->__pyx_codeobj__35); + Py_CLEAR(clear_module_state->__pyx_codeobj__37); + Py_CLEAR(clear_module_state->__pyx_codeobj__39); + Py_CLEAR(clear_module_state->__pyx_codeobj__41); + Py_CLEAR(clear_module_state->__pyx_codeobj__43); + Py_CLEAR(clear_module_state->__pyx_codeobj__45); + Py_CLEAR(clear_module_state->__pyx_codeobj__47); + Py_CLEAR(clear_module_state->__pyx_codeobj__49); + Py_CLEAR(clear_module_state->__pyx_codeobj__51); + Py_CLEAR(clear_module_state->__pyx_codeobj__54); + Py_CLEAR(clear_module_state->__pyx_codeobj__56); + Py_CLEAR(clear_module_state->__pyx_codeobj__58); + Py_CLEAR(clear_module_state->__pyx_codeobj__60); + Py_CLEAR(clear_module_state->__pyx_codeobj__62); + Py_CLEAR(clear_module_state->__pyx_codeobj__64); + Py_CLEAR(clear_module_state->__pyx_codeobj__66); + Py_CLEAR(clear_module_state->__pyx_codeobj__68); + Py_CLEAR(clear_module_state->__pyx_codeobj__70); + Py_CLEAR(clear_module_state->__pyx_codeobj__72); + Py_CLEAR(clear_module_state->__pyx_codeobj__74); + Py_CLEAR(clear_module_state->__pyx_codeobj__76); + Py_CLEAR(clear_module_state->__pyx_codeobj__78); + Py_CLEAR(clear_module_state->__pyx_codeobj__80); + Py_CLEAR(clear_module_state->__pyx_codeobj__82); + Py_CLEAR(clear_module_state->__pyx_codeobj__84); + Py_CLEAR(clear_module_state->__pyx_codeobj__86); + Py_CLEAR(clear_module_state->__pyx_codeobj__88); + Py_CLEAR(clear_module_state->__pyx_codeobj__90); + Py_CLEAR(clear_module_state->__pyx_codeobj__93); + Py_CLEAR(clear_module_state->__pyx_codeobj__96); + Py_CLEAR(clear_module_state->__pyx_codeobj__98); + Py_CLEAR(clear_module_state->__pyx_codeobj__100); + Py_CLEAR(clear_module_state->__pyx_codeobj__102); + Py_CLEAR(clear_module_state->__pyx_codeobj__104); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_1_t); + Py_VISIT(traverse_module_state->__pyx_n_s_1_t_2); + Py_VISIT(traverse_module_state->__pyx_n_s_2_t_1_t); + Py_VISIT(traverse_module_state->__pyx_kp_u_Approximates_the_arc_length_for); + Py_VISIT(traverse_module_state->__pyx_n_s_AttributeError); + Py_VISIT(traverse_module_state->__pyx_n_s_COMPILED); + Py_VISIT(traverse_module_state->__pyx_kp_u_Calculates_the_arc_length_for_a); + Py_VISIT(traverse_module_state->__pyx_kp_u_Calculates_the_bounding_rectangl); + Py_VISIT(traverse_module_state->__pyx_kp_u_Calculates_the_bounding_rectangl_2); + Py_VISIT(traverse_module_state->__pyx_kp_u_Couldn_t_work_out_which_intersec); + Py_VISIT(traverse_module_state->__pyx_n_s_DD); + Py_VISIT(traverse_module_state->__pyx_kp_u_Finds_intersections_between_a_cu); + Py_VISIT(traverse_module_state->__pyx_kp_u_Finds_intersections_between_a_cu_2); + Py_VISIT(traverse_module_state->__pyx_kp_u_Finds_intersections_between_two); + Py_VISIT(traverse_module_state->__pyx_kp_u_Finds_intersections_between_two_2); + Py_VISIT(traverse_module_state->__pyx_n_s_Identity); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_n_s_Intersection); + Py_VISIT(traverse_module_state->__pyx_n_u_Intersection); + Py_VISIT(traverse_module_state->__pyx_n_s_Len); + Py_VISIT(traverse_module_state->__pyx_kp_s_Lib_fontTools_misc_bezierTools_p); + Py_VISIT(traverse_module_state->__pyx_n_s_Q); + Py_VISIT(traverse_module_state->__pyx_n_s_Q3); + Py_VISIT(traverse_module_state->__pyx_n_s_R); + Py_VISIT(traverse_module_state->__pyx_n_s_R2); + Py_VISIT(traverse_module_state->__pyx_n_s_R2_Q3); + Py_VISIT(traverse_module_state->__pyx_kp_u_Solve_a_cubic_equation_Solves_a); + Py_VISIT(traverse_module_state->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a); + Py_VISIT(traverse_module_state->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on); + Py_VISIT(traverse_module_state->__pyx_kp_u_Split_a_line_at_a_given_coordina); + Py_VISIT(traverse_module_state->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a); + Py_VISIT(traverse_module_state->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2); + Py_VISIT(traverse_module_state->__pyx_n_s_TypeError); + Py_VISIT(traverse_module_state->__pyx_kp_u_Unknown_curve_degree); + Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); + Py_VISIT(traverse_module_state->__pyx_kp_u__10); + Py_VISIT(traverse_module_state->__pyx_n_s__105); + Py_VISIT(traverse_module_state->__pyx_n_s__11); + Py_VISIT(traverse_module_state->__pyx_kp_u__9); + Py_VISIT(traverse_module_state->__pyx_n_s__91); + Py_VISIT(traverse_module_state->__pyx_n_s_a); + Py_VISIT(traverse_module_state->__pyx_n_s_a1); + Py_VISIT(traverse_module_state->__pyx_n_s_a1_3); + Py_VISIT(traverse_module_state->__pyx_n_s_a1x); + Py_VISIT(traverse_module_state->__pyx_n_s_a1y); + Py_VISIT(traverse_module_state->__pyx_n_s_a2); + Py_VISIT(traverse_module_state->__pyx_n_s_a3); + Py_VISIT(traverse_module_state->__pyx_n_s_acos); + Py_VISIT(traverse_module_state->__pyx_n_s_aligned_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_alignment_transformation); + Py_VISIT(traverse_module_state->__pyx_n_s_all); + Py_VISIT(traverse_module_state->__pyx_n_s_angle); + Py_VISIT(traverse_module_state->__pyx_n_s_append); + Py_VISIT(traverse_module_state->__pyx_n_s_approximateCubicArcLength); + Py_VISIT(traverse_module_state->__pyx_n_u_approximateCubicArcLength); + Py_VISIT(traverse_module_state->__pyx_n_s_approximateCubicArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_u_approximateCubicArcLengthC); + Py_VISIT(traverse_module_state->__pyx_kp_u_approximateCubicArcLength_line_3); + Py_VISIT(traverse_module_state->__pyx_n_s_approximateQuadraticArcLength); + Py_VISIT(traverse_module_state->__pyx_n_u_approximateQuadraticArcLength); + Py_VISIT(traverse_module_state->__pyx_n_s_approximateQuadraticArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_u_approximateQuadraticArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_s_arch); + Py_VISIT(traverse_module_state->__pyx_n_s_args); + Py_VISIT(traverse_module_state->__pyx_n_s_asinh); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_atan2); + Py_VISIT(traverse_module_state->__pyx_n_s_ax); + Py_VISIT(traverse_module_state->__pyx_n_s_ax2); + Py_VISIT(traverse_module_state->__pyx_n_s_ax3); + Py_VISIT(traverse_module_state->__pyx_n_s_ay); + Py_VISIT(traverse_module_state->__pyx_n_s_ay2); + Py_VISIT(traverse_module_state->__pyx_n_s_ay3); + Py_VISIT(traverse_module_state->__pyx_n_s_b); + Py_VISIT(traverse_module_state->__pyx_n_s_b1); + Py_VISIT(traverse_module_state->__pyx_n_s_b1x); + Py_VISIT(traverse_module_state->__pyx_n_s_b1y); + Py_VISIT(traverse_module_state->__pyx_n_s_both_points_are_on_same_side_of); + Py_VISIT(traverse_module_state->__pyx_n_s_bounds1); + Py_VISIT(traverse_module_state->__pyx_n_s_bounds2); + Py_VISIT(traverse_module_state->__pyx_n_s_box); + Py_VISIT(traverse_module_state->__pyx_n_s_bx); + Py_VISIT(traverse_module_state->__pyx_n_s_bx2); + Py_VISIT(traverse_module_state->__pyx_n_s_by); + Py_VISIT(traverse_module_state->__pyx_n_s_by2); + Py_VISIT(traverse_module_state->__pyx_n_s_c); + Py_VISIT(traverse_module_state->__pyx_n_s_c1); + Py_VISIT(traverse_module_state->__pyx_n_s_c11); + Py_VISIT(traverse_module_state->__pyx_n_s_c11_range); + Py_VISIT(traverse_module_state->__pyx_n_s_c12); + Py_VISIT(traverse_module_state->__pyx_n_s_c12_range); + Py_VISIT(traverse_module_state->__pyx_n_s_c1x); + Py_VISIT(traverse_module_state->__pyx_n_s_c1y); + Py_VISIT(traverse_module_state->__pyx_n_s_c21); + Py_VISIT(traverse_module_state->__pyx_n_s_c21_range); + Py_VISIT(traverse_module_state->__pyx_n_s_c22); + Py_VISIT(traverse_module_state->__pyx_n_s_c22_range); + Py_VISIT(traverse_module_state->__pyx_n_s_calcBounds); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicArcLength); + Py_VISIT(traverse_module_state->__pyx_n_u_calcCubicArcLength); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_u_calcCubicArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicArcLengthCRecurse); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicBounds); + Py_VISIT(traverse_module_state->__pyx_n_u_calcCubicBounds); + Py_VISIT(traverse_module_state->__pyx_kp_u_calcCubicBounds_line_412); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicParameters); + Py_VISIT(traverse_module_state->__pyx_n_s_calcCubicPoints); + Py_VISIT(traverse_module_state->__pyx_n_s_calcQuadraticArcLength); + Py_VISIT(traverse_module_state->__pyx_n_u_calcQuadraticArcLength); + Py_VISIT(traverse_module_state->__pyx_n_s_calcQuadraticArcLengthC); + Py_VISIT(traverse_module_state->__pyx_n_u_calcQuadraticArcLengthC); + Py_VISIT(traverse_module_state->__pyx_kp_u_calcQuadraticArcLength_line_151); + Py_VISIT(traverse_module_state->__pyx_n_s_calcQuadraticBounds); + Py_VISIT(traverse_module_state->__pyx_n_u_calcQuadraticBounds); + Py_VISIT(traverse_module_state->__pyx_kp_u_calcQuadraticBounds_line_298); + Py_VISIT(traverse_module_state->__pyx_n_s_calcQuadraticParameters); + Py_VISIT(traverse_module_state->__pyx_n_s_calcQuadraticPoints); + Py_VISIT(traverse_module_state->__pyx_n_s_class_getitem); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_close); + Py_VISIT(traverse_module_state->__pyx_n_s_collections); + Py_VISIT(traverse_module_state->__pyx_n_s_cos); + Py_VISIT(traverse_module_state->__pyx_n_s_cubicPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_u_cubicPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_cubicPointAtTC); + Py_VISIT(traverse_module_state->__pyx_n_u_cubicPointAtTC); + Py_VISIT(traverse_module_state->__pyx_n_s_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_curve1); + Py_VISIT(traverse_module_state->__pyx_n_s_curve2); + Py_VISIT(traverse_module_state->__pyx_n_s_curveCurveIntersections); + Py_VISIT(traverse_module_state->__pyx_n_u_curveCurveIntersections); + Py_VISIT(traverse_module_state->__pyx_kp_u_curveCurveIntersections_line_137); + Py_VISIT(traverse_module_state->__pyx_n_s_curveLineIntersections); + Py_VISIT(traverse_module_state->__pyx_n_u_curveLineIntersections); + Py_VISIT(traverse_module_state->__pyx_kp_u_curveLineIntersections_line_1248); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_bounds); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_curve_intersections_t); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_curve_intersections_t_loc); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_curve_intersections_t_loc_2); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_line_intersections_t); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_line_intersections_t_loca); + Py_VISIT(traverse_module_state->__pyx_n_s_cx); + Py_VISIT(traverse_module_state->__pyx_n_s_cy); + Py_VISIT(traverse_module_state->__pyx_n_s_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_d); + Py_VISIT(traverse_module_state->__pyx_n_s_d0); + Py_VISIT(traverse_module_state->__pyx_n_s_d1); + Py_VISIT(traverse_module_state->__pyx_n_s_d1x); + Py_VISIT(traverse_module_state->__pyx_n_s_d1y); + Py_VISIT(traverse_module_state->__pyx_n_s_delta); + Py_VISIT(traverse_module_state->__pyx_n_s_delta_2); + Py_VISIT(traverse_module_state->__pyx_n_s_delta_3); + Py_VISIT(traverse_module_state->__pyx_n_s_deriv3); + Py_VISIT(traverse_module_state->__pyx_kp_u_disable); + Py_VISIT(traverse_module_state->__pyx_n_s_doctest); + Py_VISIT(traverse_module_state->__pyx_n_s_dx); + Py_VISIT(traverse_module_state->__pyx_n_s_dy); + Py_VISIT(traverse_module_state->__pyx_n_s_e); + Py_VISIT(traverse_module_state->__pyx_n_s_e1); + Py_VISIT(traverse_module_state->__pyx_n_s_e1x); + Py_VISIT(traverse_module_state->__pyx_n_s_e1y); + Py_VISIT(traverse_module_state->__pyx_n_s_e2); + Py_VISIT(traverse_module_state->__pyx_n_s_e2x); + Py_VISIT(traverse_module_state->__pyx_n_s_e2y); + Py_VISIT(traverse_module_state->__pyx_kp_u_enable); + Py_VISIT(traverse_module_state->__pyx_n_s_end); + Py_VISIT(traverse_module_state->__pyx_n_s_epsilon); + Py_VISIT(traverse_module_state->__pyx_n_s_epsilonDigits); + Py_VISIT(traverse_module_state->__pyx_n_s_ex); + Py_VISIT(traverse_module_state->__pyx_n_s_exit); + Py_VISIT(traverse_module_state->__pyx_n_s_ey); + Py_VISIT(traverse_module_state->__pyx_n_s_failed); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc_arrayTools); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc_bezierTools); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc_transform); + Py_VISIT(traverse_module_state->__pyx_n_s_found); + Py_VISIT(traverse_module_state->__pyx_kp_u_g); + Py_VISIT(traverse_module_state->__pyx_kp_u_gc); + Py_VISIT(traverse_module_state->__pyx_n_s_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_i); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_n_s_insert); + Py_VISIT(traverse_module_state->__pyx_n_s_intersection_ts); + Py_VISIT(traverse_module_state->__pyx_n_s_intersections); + Py_VISIT(traverse_module_state->__pyx_n_s_intersects); + Py_VISIT(traverse_module_state->__pyx_n_s_isHorizontal); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_n_s_is_linelike); + Py_VISIT(traverse_module_state->__pyx_n_s_is_linelike_locals_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_isclose); + Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); + Py_VISIT(traverse_module_state->__pyx_n_s_it); + Py_VISIT(traverse_module_state->__pyx_n_s_key); + Py_VISIT(traverse_module_state->__pyx_n_s_line); + Py_VISIT(traverse_module_state->__pyx_n_s_line1); + Py_VISIT(traverse_module_state->__pyx_n_s_line2); + Py_VISIT(traverse_module_state->__pyx_n_s_lineLineIntersections); + Py_VISIT(traverse_module_state->__pyx_n_u_lineLineIntersections); + Py_VISIT(traverse_module_state->__pyx_kp_u_lineLineIntersections_line_1147); + Py_VISIT(traverse_module_state->__pyx_n_s_linePointAtT); + Py_VISIT(traverse_module_state->__pyx_n_u_linePointAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_line_t); + Py_VISIT(traverse_module_state->__pyx_n_s_line_t_of_pt); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_u_main); + Py_VISIT(traverse_module_state->__pyx_n_s_math); + Py_VISIT(traverse_module_state->__pyx_n_s_maybeline); + Py_VISIT(traverse_module_state->__pyx_n_s_mid); + Py_VISIT(traverse_module_state->__pyx_n_s_midPt); + Py_VISIT(traverse_module_state->__pyx_n_s_midpoint); + Py_VISIT(traverse_module_state->__pyx_n_s_mult); + Py_VISIT(traverse_module_state->__pyx_n_s_n); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_namedtuple); + Py_VISIT(traverse_module_state->__pyx_n_s_obj); + Py_VISIT(traverse_module_state->__pyx_n_s_off1); + Py_VISIT(traverse_module_state->__pyx_n_s_off2); + Py_VISIT(traverse_module_state->__pyx_n_s_one); + Py_VISIT(traverse_module_state->__pyx_n_s_origDist); + Py_VISIT(traverse_module_state->__pyx_n_s_origin); + Py_VISIT(traverse_module_state->__pyx_n_s_p0); + Py_VISIT(traverse_module_state->__pyx_n_s_p1); + Py_VISIT(traverse_module_state->__pyx_n_s_p2); + Py_VISIT(traverse_module_state->__pyx_n_s_p3); + Py_VISIT(traverse_module_state->__pyx_n_s_pi); + Py_VISIT(traverse_module_state->__pyx_n_s_pointAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_pointFinder); + Py_VISIT(traverse_module_state->__pyx_n_s_points); + Py_VISIT(traverse_module_state->__pyx_n_s_precision); + Py_VISIT(traverse_module_state->__pyx_n_s_print); + Py_VISIT(traverse_module_state->__pyx_n_s_printSegments); + Py_VISIT(traverse_module_state->__pyx_n_s_pt); + Py_VISIT(traverse_module_state->__pyx_n_u_pt); + Py_VISIT(traverse_module_state->__pyx_n_s_pt1); + Py_VISIT(traverse_module_state->__pyx_n_s_pt1x); + Py_VISIT(traverse_module_state->__pyx_n_s_pt1y); + Py_VISIT(traverse_module_state->__pyx_n_s_pt2); + Py_VISIT(traverse_module_state->__pyx_n_s_pt2x); + Py_VISIT(traverse_module_state->__pyx_n_s_pt2y); + Py_VISIT(traverse_module_state->__pyx_n_s_pt3); + Py_VISIT(traverse_module_state->__pyx_n_s_pt4); + Py_VISIT(traverse_module_state->__pyx_n_s_px); + Py_VISIT(traverse_module_state->__pyx_n_s_py); + Py_VISIT(traverse_module_state->__pyx_n_s_quadraticPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_u_quadraticPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_r); + Py_VISIT(traverse_module_state->__pyx_n_s_rDD); + Py_VISIT(traverse_module_state->__pyx_n_s_rQ2); + Py_VISIT(traverse_module_state->__pyx_n_s_range); + Py_VISIT(traverse_module_state->__pyx_n_s_range1); + Py_VISIT(traverse_module_state->__pyx_n_s_range2); + Py_VISIT(traverse_module_state->__pyx_n_s_rectArea); + Py_VISIT(traverse_module_state->__pyx_n_s_roots); + Py_VISIT(traverse_module_state->__pyx_n_s_rotate); + Py_VISIT(traverse_module_state->__pyx_n_s_round); + Py_VISIT(traverse_module_state->__pyx_n_s_s); + Py_VISIT(traverse_module_state->__pyx_n_s_s1); + Py_VISIT(traverse_module_state->__pyx_n_s_s1x); + Py_VISIT(traverse_module_state->__pyx_n_s_s1y); + Py_VISIT(traverse_module_state->__pyx_n_s_s2); + Py_VISIT(traverse_module_state->__pyx_n_s_s2x); + Py_VISIT(traverse_module_state->__pyx_n_s_s2y); + Py_VISIT(traverse_module_state->__pyx_kp_u_s_2); + Py_VISIT(traverse_module_state->__pyx_n_s_scale); + Py_VISIT(traverse_module_state->__pyx_n_s_sectRect); + Py_VISIT(traverse_module_state->__pyx_n_s_seen); + Py_VISIT(traverse_module_state->__pyx_n_s_seg); + Py_VISIT(traverse_module_state->__pyx_n_s_seg1); + Py_VISIT(traverse_module_state->__pyx_n_s_seg2); + Py_VISIT(traverse_module_state->__pyx_n_s_segment); + Py_VISIT(traverse_module_state->__pyx_n_s_segmentPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_u_segmentPointAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_segmentSegmentIntersections); + Py_VISIT(traverse_module_state->__pyx_n_u_segmentSegmentIntersections); + Py_VISIT(traverse_module_state->__pyx_kp_u_segmentSegmentIntersections_line); + Py_VISIT(traverse_module_state->__pyx_n_s_segmentrepr); + Py_VISIT(traverse_module_state->__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2); + Py_VISIT(traverse_module_state->__pyx_kp_u_segmentrepr_line_1465); + Py_VISIT(traverse_module_state->__pyx_n_s_segmentrepr_locals_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_segments); + Py_VISIT(traverse_module_state->__pyx_n_s_send); + Py_VISIT(traverse_module_state->__pyx_n_s_slope12); + Py_VISIT(traverse_module_state->__pyx_n_s_slope34); + Py_VISIT(traverse_module_state->__pyx_n_s_solutions); + Py_VISIT(traverse_module_state->__pyx_n_s_solveCubic); + Py_VISIT(traverse_module_state->__pyx_n_u_solveCubic); + Py_VISIT(traverse_module_state->__pyx_kp_u_solveCubic_line_841); + Py_VISIT(traverse_module_state->__pyx_n_s_solveQuadratic); + Py_VISIT(traverse_module_state->__pyx_n_u_solveQuadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubic); + Py_VISIT(traverse_module_state->__pyx_n_u_splitCubic); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_n_u_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicAtTC_2); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicAtT_2); + Py_VISIT(traverse_module_state->__pyx_n_u_splitCubicAtT_2); + Py_VISIT(traverse_module_state->__pyx_kp_u_splitCubicAtT_line_613); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicIntoTwoAtTC); + Py_VISIT(traverse_module_state->__pyx_n_u_splitCubicIntoTwoAtTC); + Py_VISIT(traverse_module_state->__pyx_kp_u_splitCubic_line_552); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubic_locals_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_splitLine); + Py_VISIT(traverse_module_state->__pyx_n_u_splitLine); + Py_VISIT(traverse_module_state->__pyx_kp_u_splitLine_line_450); + Py_VISIT(traverse_module_state->__pyx_n_s_splitQuadratic); + Py_VISIT(traverse_module_state->__pyx_n_u_splitQuadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_splitQuadraticAtT); + Py_VISIT(traverse_module_state->__pyx_n_s_splitQuadraticAtT_2); + Py_VISIT(traverse_module_state->__pyx_n_u_splitQuadraticAtT_2); + Py_VISIT(traverse_module_state->__pyx_kp_u_splitQuadraticAtT_line_589); + Py_VISIT(traverse_module_state->__pyx_kp_u_splitQuadratic_line_507); + Py_VISIT(traverse_module_state->__pyx_n_s_splitQuadratic_locals_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_split_cubic_into_two); + Py_VISIT(traverse_module_state->__pyx_n_s_split_segment_at_t); + Py_VISIT(traverse_module_state->__pyx_n_s_sqrt); + Py_VISIT(traverse_module_state->__pyx_n_s_start); + Py_VISIT(traverse_module_state->__pyx_n_s_swapped); + Py_VISIT(traverse_module_state->__pyx_n_s_sx); + Py_VISIT(traverse_module_state->__pyx_n_s_sy); + Py_VISIT(traverse_module_state->__pyx_n_s_sys); + Py_VISIT(traverse_module_state->__pyx_n_s_t); + Py_VISIT(traverse_module_state->__pyx_n_s_t1); + Py_VISIT(traverse_module_state->__pyx_n_u_t1); + Py_VISIT(traverse_module_state->__pyx_n_s_t1_2); + Py_VISIT(traverse_module_state->__pyx_n_s_t1_3); + Py_VISIT(traverse_module_state->__pyx_n_s_t2); + Py_VISIT(traverse_module_state->__pyx_n_u_t2); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_testmod); + Py_VISIT(traverse_module_state->__pyx_n_s_theta); + Py_VISIT(traverse_module_state->__pyx_n_s_throw); + Py_VISIT(traverse_module_state->__pyx_n_s_tolerance); + Py_VISIT(traverse_module_state->__pyx_n_s_transformPoints); + Py_VISIT(traverse_module_state->__pyx_n_s_translate); + Py_VISIT(traverse_module_state->__pyx_n_s_ts); + Py_VISIT(traverse_module_state->__pyx_n_s_two); + Py_VISIT(traverse_module_state->__pyx_n_s_unique_key); + Py_VISIT(traverse_module_state->__pyx_n_s_unique_values); + Py_VISIT(traverse_module_state->__pyx_n_s_v0); + Py_VISIT(traverse_module_state->__pyx_n_s_v1); + Py_VISIT(traverse_module_state->__pyx_n_s_v2); + Py_VISIT(traverse_module_state->__pyx_n_s_v3); + Py_VISIT(traverse_module_state->__pyx_n_s_v4); + Py_VISIT(traverse_module_state->__pyx_n_s_where); + Py_VISIT(traverse_module_state->__pyx_n_s_x); + Py_VISIT(traverse_module_state->__pyx_n_s_x0); + Py_VISIT(traverse_module_state->__pyx_n_s_x1); + Py_VISIT(traverse_module_state->__pyx_n_s_x2); + Py_VISIT(traverse_module_state->__pyx_n_s_x3); + Py_VISIT(traverse_module_state->__pyx_n_s_x4); + Py_VISIT(traverse_module_state->__pyx_n_s_xDiff); + Py_VISIT(traverse_module_state->__pyx_n_s_xRoots); + Py_VISIT(traverse_module_state->__pyx_n_s_y); + Py_VISIT(traverse_module_state->__pyx_n_s_y1); + Py_VISIT(traverse_module_state->__pyx_n_s_y2); + Py_VISIT(traverse_module_state->__pyx_n_s_y3); + Py_VISIT(traverse_module_state->__pyx_n_s_y4); + Py_VISIT(traverse_module_state->__pyx_n_s_yDiff); + Py_VISIT(traverse_module_state->__pyx_n_s_yRoots); + Py_VISIT(traverse_module_state->__pyx_float_0_0); + Py_VISIT(traverse_module_state->__pyx_float_0_5); + Py_VISIT(traverse_module_state->__pyx_float_1_0); + Py_VISIT(traverse_module_state->__pyx_float_2_0); + Py_VISIT(traverse_module_state->__pyx_float_3_0); + Py_VISIT(traverse_module_state->__pyx_float_4_0); + Py_VISIT(traverse_module_state->__pyx_float_9_0); + Py_VISIT(traverse_module_state->__pyx_float_1eneg_3); + Py_VISIT(traverse_module_state->__pyx_float_27_0); + Py_VISIT(traverse_module_state->__pyx_float_54_0); + Py_VISIT(traverse_module_state->__pyx_float_0_005); + Py_VISIT(traverse_module_state->__pyx_float_0_125); + Py_VISIT(traverse_module_state->__pyx_float_1eneg_10); + Py_VISIT(traverse_module_state->__pyx_float_neg_2_0); + Py_VISIT(traverse_module_state->__pyx_int_0); + Py_VISIT(traverse_module_state->__pyx_int_1); + Py_VISIT(traverse_module_state->__pyx_int_2); + Py_VISIT(traverse_module_state->__pyx_int_3); + Py_VISIT(traverse_module_state->__pyx_int_6); + Py_VISIT(traverse_module_state->__pyx_int_neg_1); + Py_VISIT(traverse_module_state->__pyx_codeobj_); + Py_VISIT(traverse_module_state->__pyx_tuple__2); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__5); + Py_VISIT(traverse_module_state->__pyx_tuple__6); + Py_VISIT(traverse_module_state->__pyx_tuple__8); + Py_VISIT(traverse_module_state->__pyx_tuple__12); + Py_VISIT(traverse_module_state->__pyx_tuple__14); + Py_VISIT(traverse_module_state->__pyx_tuple__15); + Py_VISIT(traverse_module_state->__pyx_tuple__17); + Py_VISIT(traverse_module_state->__pyx_tuple__19); + Py_VISIT(traverse_module_state->__pyx_tuple__21); + Py_VISIT(traverse_module_state->__pyx_tuple__23); + Py_VISIT(traverse_module_state->__pyx_tuple__26); + Py_VISIT(traverse_module_state->__pyx_tuple__28); + Py_VISIT(traverse_module_state->__pyx_tuple__30); + Py_VISIT(traverse_module_state->__pyx_tuple__32); + Py_VISIT(traverse_module_state->__pyx_tuple__34); + Py_VISIT(traverse_module_state->__pyx_tuple__36); + Py_VISIT(traverse_module_state->__pyx_tuple__38); + Py_VISIT(traverse_module_state->__pyx_tuple__40); + Py_VISIT(traverse_module_state->__pyx_tuple__42); + Py_VISIT(traverse_module_state->__pyx_tuple__44); + Py_VISIT(traverse_module_state->__pyx_tuple__46); + Py_VISIT(traverse_module_state->__pyx_tuple__48); + Py_VISIT(traverse_module_state->__pyx_tuple__50); + Py_VISIT(traverse_module_state->__pyx_tuple__52); + Py_VISIT(traverse_module_state->__pyx_tuple__53); + Py_VISIT(traverse_module_state->__pyx_tuple__55); + Py_VISIT(traverse_module_state->__pyx_tuple__57); + Py_VISIT(traverse_module_state->__pyx_tuple__59); + Py_VISIT(traverse_module_state->__pyx_tuple__61); + Py_VISIT(traverse_module_state->__pyx_tuple__63); + Py_VISIT(traverse_module_state->__pyx_tuple__65); + Py_VISIT(traverse_module_state->__pyx_tuple__67); + Py_VISIT(traverse_module_state->__pyx_tuple__69); + Py_VISIT(traverse_module_state->__pyx_tuple__71); + Py_VISIT(traverse_module_state->__pyx_tuple__73); + Py_VISIT(traverse_module_state->__pyx_tuple__75); + Py_VISIT(traverse_module_state->__pyx_tuple__77); + Py_VISIT(traverse_module_state->__pyx_tuple__79); + Py_VISIT(traverse_module_state->__pyx_tuple__81); + Py_VISIT(traverse_module_state->__pyx_tuple__83); + Py_VISIT(traverse_module_state->__pyx_tuple__85); + Py_VISIT(traverse_module_state->__pyx_tuple__87); + Py_VISIT(traverse_module_state->__pyx_tuple__89); + Py_VISIT(traverse_module_state->__pyx_tuple__92); + Py_VISIT(traverse_module_state->__pyx_tuple__94); + Py_VISIT(traverse_module_state->__pyx_tuple__95); + Py_VISIT(traverse_module_state->__pyx_tuple__97); + Py_VISIT(traverse_module_state->__pyx_tuple__99); + Py_VISIT(traverse_module_state->__pyx_codeobj__3); + Py_VISIT(traverse_module_state->__pyx_codeobj__7); + Py_VISIT(traverse_module_state->__pyx_tuple__101); + Py_VISIT(traverse_module_state->__pyx_tuple__103); + Py_VISIT(traverse_module_state->__pyx_codeobj__13); + Py_VISIT(traverse_module_state->__pyx_codeobj__16); + Py_VISIT(traverse_module_state->__pyx_codeobj__18); + Py_VISIT(traverse_module_state->__pyx_codeobj__20); + Py_VISIT(traverse_module_state->__pyx_codeobj__22); + Py_VISIT(traverse_module_state->__pyx_codeobj__24); + Py_VISIT(traverse_module_state->__pyx_codeobj__25); + Py_VISIT(traverse_module_state->__pyx_codeobj__27); + Py_VISIT(traverse_module_state->__pyx_codeobj__29); + Py_VISIT(traverse_module_state->__pyx_codeobj__31); + Py_VISIT(traverse_module_state->__pyx_codeobj__33); + Py_VISIT(traverse_module_state->__pyx_codeobj__35); + Py_VISIT(traverse_module_state->__pyx_codeobj__37); + Py_VISIT(traverse_module_state->__pyx_codeobj__39); + Py_VISIT(traverse_module_state->__pyx_codeobj__41); + Py_VISIT(traverse_module_state->__pyx_codeobj__43); + Py_VISIT(traverse_module_state->__pyx_codeobj__45); + Py_VISIT(traverse_module_state->__pyx_codeobj__47); + Py_VISIT(traverse_module_state->__pyx_codeobj__49); + Py_VISIT(traverse_module_state->__pyx_codeobj__51); + Py_VISIT(traverse_module_state->__pyx_codeobj__54); + Py_VISIT(traverse_module_state->__pyx_codeobj__56); + Py_VISIT(traverse_module_state->__pyx_codeobj__58); + Py_VISIT(traverse_module_state->__pyx_codeobj__60); + Py_VISIT(traverse_module_state->__pyx_codeobj__62); + Py_VISIT(traverse_module_state->__pyx_codeobj__64); + Py_VISIT(traverse_module_state->__pyx_codeobj__66); + Py_VISIT(traverse_module_state->__pyx_codeobj__68); + Py_VISIT(traverse_module_state->__pyx_codeobj__70); + Py_VISIT(traverse_module_state->__pyx_codeobj__72); + Py_VISIT(traverse_module_state->__pyx_codeobj__74); + Py_VISIT(traverse_module_state->__pyx_codeobj__76); + Py_VISIT(traverse_module_state->__pyx_codeobj__78); + Py_VISIT(traverse_module_state->__pyx_codeobj__80); + Py_VISIT(traverse_module_state->__pyx_codeobj__82); + Py_VISIT(traverse_module_state->__pyx_codeobj__84); + Py_VISIT(traverse_module_state->__pyx_codeobj__86); + Py_VISIT(traverse_module_state->__pyx_codeobj__88); + Py_VISIT(traverse_module_state->__pyx_codeobj__90); + Py_VISIT(traverse_module_state->__pyx_codeobj__93); + Py_VISIT(traverse_module_state->__pyx_codeobj__96); + Py_VISIT(traverse_module_state->__pyx_codeobj__98); + Py_VISIT(traverse_module_state->__pyx_codeobj__100); + Py_VISIT(traverse_module_state->__pyx_codeobj__102); + Py_VISIT(traverse_module_state->__pyx_codeobj__104); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr +#define __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr __pyx_mstate_global->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr +#endif +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr +#define __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr +#define __pyx_n_s_1_t __pyx_mstate_global->__pyx_n_s_1_t +#define __pyx_n_s_1_t_2 __pyx_mstate_global->__pyx_n_s_1_t_2 +#define __pyx_n_s_2_t_1_t __pyx_mstate_global->__pyx_n_s_2_t_1_t +#define __pyx_kp_u_Approximates_the_arc_length_for __pyx_mstate_global->__pyx_kp_u_Approximates_the_arc_length_for +#define __pyx_n_s_AttributeError __pyx_mstate_global->__pyx_n_s_AttributeError +#define __pyx_n_s_COMPILED __pyx_mstate_global->__pyx_n_s_COMPILED +#define __pyx_kp_u_Calculates_the_arc_length_for_a __pyx_mstate_global->__pyx_kp_u_Calculates_the_arc_length_for_a +#define __pyx_kp_u_Calculates_the_bounding_rectangl __pyx_mstate_global->__pyx_kp_u_Calculates_the_bounding_rectangl +#define __pyx_kp_u_Calculates_the_bounding_rectangl_2 __pyx_mstate_global->__pyx_kp_u_Calculates_the_bounding_rectangl_2 +#define __pyx_kp_u_Couldn_t_work_out_which_intersec __pyx_mstate_global->__pyx_kp_u_Couldn_t_work_out_which_intersec +#define __pyx_n_s_DD __pyx_mstate_global->__pyx_n_s_DD +#define __pyx_kp_u_Finds_intersections_between_a_cu __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_a_cu +#define __pyx_kp_u_Finds_intersections_between_a_cu_2 __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_a_cu_2 +#define __pyx_kp_u_Finds_intersections_between_two __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_two +#define __pyx_kp_u_Finds_intersections_between_two_2 __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_two_2 +#define __pyx_n_s_Identity __pyx_mstate_global->__pyx_n_s_Identity +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_n_s_Intersection __pyx_mstate_global->__pyx_n_s_Intersection +#define __pyx_n_u_Intersection __pyx_mstate_global->__pyx_n_u_Intersection +#define __pyx_n_s_Len __pyx_mstate_global->__pyx_n_s_Len +#define __pyx_kp_s_Lib_fontTools_misc_bezierTools_p __pyx_mstate_global->__pyx_kp_s_Lib_fontTools_misc_bezierTools_p +#define __pyx_n_s_Q __pyx_mstate_global->__pyx_n_s_Q +#define __pyx_n_s_Q3 __pyx_mstate_global->__pyx_n_s_Q3 +#define __pyx_n_s_R __pyx_mstate_global->__pyx_n_s_R +#define __pyx_n_s_R2 __pyx_mstate_global->__pyx_n_s_R2 +#define __pyx_n_s_R2_Q3 __pyx_mstate_global->__pyx_n_s_R2_Q3 +#define __pyx_kp_u_Solve_a_cubic_equation_Solves_a __pyx_mstate_global->__pyx_kp_u_Solve_a_cubic_equation_Solves_a +#define __pyx_kp_u_Split_a_cubic_Bezier_curve_at_a __pyx_mstate_global->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a +#define __pyx_kp_u_Split_a_cubic_Bezier_curve_at_on __pyx_mstate_global->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on +#define __pyx_kp_u_Split_a_line_at_a_given_coordina __pyx_mstate_global->__pyx_kp_u_Split_a_line_at_a_given_coordina +#define __pyx_kp_u_Split_a_quadratic_Bezier_curve_a __pyx_mstate_global->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a +#define __pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2 __pyx_mstate_global->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2 +#define __pyx_n_s_TypeError __pyx_mstate_global->__pyx_n_s_TypeError +#define __pyx_kp_u_Unknown_curve_degree __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree +#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError +#define __pyx_kp_u__10 __pyx_mstate_global->__pyx_kp_u__10 +#define __pyx_n_s__105 __pyx_mstate_global->__pyx_n_s__105 +#define __pyx_n_s__11 __pyx_mstate_global->__pyx_n_s__11 +#define __pyx_kp_u__9 __pyx_mstate_global->__pyx_kp_u__9 +#define __pyx_n_s__91 __pyx_mstate_global->__pyx_n_s__91 +#define __pyx_n_s_a __pyx_mstate_global->__pyx_n_s_a +#define __pyx_n_s_a1 __pyx_mstate_global->__pyx_n_s_a1 +#define __pyx_n_s_a1_3 __pyx_mstate_global->__pyx_n_s_a1_3 +#define __pyx_n_s_a1x __pyx_mstate_global->__pyx_n_s_a1x +#define __pyx_n_s_a1y __pyx_mstate_global->__pyx_n_s_a1y +#define __pyx_n_s_a2 __pyx_mstate_global->__pyx_n_s_a2 +#define __pyx_n_s_a3 __pyx_mstate_global->__pyx_n_s_a3 +#define __pyx_n_s_acos __pyx_mstate_global->__pyx_n_s_acos +#define __pyx_n_s_aligned_curve __pyx_mstate_global->__pyx_n_s_aligned_curve +#define __pyx_n_s_alignment_transformation __pyx_mstate_global->__pyx_n_s_alignment_transformation +#define __pyx_n_s_all __pyx_mstate_global->__pyx_n_s_all +#define __pyx_n_s_angle __pyx_mstate_global->__pyx_n_s_angle +#define __pyx_n_s_append __pyx_mstate_global->__pyx_n_s_append +#define __pyx_n_s_approximateCubicArcLength __pyx_mstate_global->__pyx_n_s_approximateCubicArcLength +#define __pyx_n_u_approximateCubicArcLength __pyx_mstate_global->__pyx_n_u_approximateCubicArcLength +#define __pyx_n_s_approximateCubicArcLengthC __pyx_mstate_global->__pyx_n_s_approximateCubicArcLengthC +#define __pyx_n_u_approximateCubicArcLengthC __pyx_mstate_global->__pyx_n_u_approximateCubicArcLengthC +#define __pyx_kp_u_approximateCubicArcLength_line_3 __pyx_mstate_global->__pyx_kp_u_approximateCubicArcLength_line_3 +#define __pyx_n_s_approximateQuadraticArcLength __pyx_mstate_global->__pyx_n_s_approximateQuadraticArcLength +#define __pyx_n_u_approximateQuadraticArcLength __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLength +#define __pyx_n_s_approximateQuadraticArcLengthC __pyx_mstate_global->__pyx_n_s_approximateQuadraticArcLengthC +#define __pyx_n_u_approximateQuadraticArcLengthC __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLengthC +#define __pyx_n_s_arch __pyx_mstate_global->__pyx_n_s_arch +#define __pyx_n_s_args __pyx_mstate_global->__pyx_n_s_args +#define __pyx_n_s_asinh __pyx_mstate_global->__pyx_n_s_asinh +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_atan2 __pyx_mstate_global->__pyx_n_s_atan2 +#define __pyx_n_s_ax __pyx_mstate_global->__pyx_n_s_ax +#define __pyx_n_s_ax2 __pyx_mstate_global->__pyx_n_s_ax2 +#define __pyx_n_s_ax3 __pyx_mstate_global->__pyx_n_s_ax3 +#define __pyx_n_s_ay __pyx_mstate_global->__pyx_n_s_ay +#define __pyx_n_s_ay2 __pyx_mstate_global->__pyx_n_s_ay2 +#define __pyx_n_s_ay3 __pyx_mstate_global->__pyx_n_s_ay3 +#define __pyx_n_s_b __pyx_mstate_global->__pyx_n_s_b +#define __pyx_n_s_b1 __pyx_mstate_global->__pyx_n_s_b1 +#define __pyx_n_s_b1x __pyx_mstate_global->__pyx_n_s_b1x +#define __pyx_n_s_b1y __pyx_mstate_global->__pyx_n_s_b1y +#define __pyx_n_s_both_points_are_on_same_side_of __pyx_mstate_global->__pyx_n_s_both_points_are_on_same_side_of +#define __pyx_n_s_bounds1 __pyx_mstate_global->__pyx_n_s_bounds1 +#define __pyx_n_s_bounds2 __pyx_mstate_global->__pyx_n_s_bounds2 +#define __pyx_n_s_box __pyx_mstate_global->__pyx_n_s_box +#define __pyx_n_s_bx __pyx_mstate_global->__pyx_n_s_bx +#define __pyx_n_s_bx2 __pyx_mstate_global->__pyx_n_s_bx2 +#define __pyx_n_s_by __pyx_mstate_global->__pyx_n_s_by +#define __pyx_n_s_by2 __pyx_mstate_global->__pyx_n_s_by2 +#define __pyx_n_s_c __pyx_mstate_global->__pyx_n_s_c +#define __pyx_n_s_c1 __pyx_mstate_global->__pyx_n_s_c1 +#define __pyx_n_s_c11 __pyx_mstate_global->__pyx_n_s_c11 +#define __pyx_n_s_c11_range __pyx_mstate_global->__pyx_n_s_c11_range +#define __pyx_n_s_c12 __pyx_mstate_global->__pyx_n_s_c12 +#define __pyx_n_s_c12_range __pyx_mstate_global->__pyx_n_s_c12_range +#define __pyx_n_s_c1x __pyx_mstate_global->__pyx_n_s_c1x +#define __pyx_n_s_c1y __pyx_mstate_global->__pyx_n_s_c1y +#define __pyx_n_s_c21 __pyx_mstate_global->__pyx_n_s_c21 +#define __pyx_n_s_c21_range __pyx_mstate_global->__pyx_n_s_c21_range +#define __pyx_n_s_c22 __pyx_mstate_global->__pyx_n_s_c22 +#define __pyx_n_s_c22_range __pyx_mstate_global->__pyx_n_s_c22_range +#define __pyx_n_s_calcBounds __pyx_mstate_global->__pyx_n_s_calcBounds +#define __pyx_n_s_calcCubicArcLength __pyx_mstate_global->__pyx_n_s_calcCubicArcLength +#define __pyx_n_u_calcCubicArcLength __pyx_mstate_global->__pyx_n_u_calcCubicArcLength +#define __pyx_n_s_calcCubicArcLengthC __pyx_mstate_global->__pyx_n_s_calcCubicArcLengthC +#define __pyx_n_u_calcCubicArcLengthC __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthC +#define __pyx_n_s_calcCubicArcLengthCRecurse __pyx_mstate_global->__pyx_n_s_calcCubicArcLengthCRecurse +#define __pyx_n_s_calcCubicBounds __pyx_mstate_global->__pyx_n_s_calcCubicBounds +#define __pyx_n_u_calcCubicBounds __pyx_mstate_global->__pyx_n_u_calcCubicBounds +#define __pyx_kp_u_calcCubicBounds_line_412 __pyx_mstate_global->__pyx_kp_u_calcCubicBounds_line_412 +#define __pyx_n_s_calcCubicParameters __pyx_mstate_global->__pyx_n_s_calcCubicParameters +#define __pyx_n_s_calcCubicPoints __pyx_mstate_global->__pyx_n_s_calcCubicPoints +#define __pyx_n_s_calcQuadraticArcLength __pyx_mstate_global->__pyx_n_s_calcQuadraticArcLength +#define __pyx_n_u_calcQuadraticArcLength __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLength +#define __pyx_n_s_calcQuadraticArcLengthC __pyx_mstate_global->__pyx_n_s_calcQuadraticArcLengthC +#define __pyx_n_u_calcQuadraticArcLengthC __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLengthC +#define __pyx_kp_u_calcQuadraticArcLength_line_151 __pyx_mstate_global->__pyx_kp_u_calcQuadraticArcLength_line_151 +#define __pyx_n_s_calcQuadraticBounds __pyx_mstate_global->__pyx_n_s_calcQuadraticBounds +#define __pyx_n_u_calcQuadraticBounds __pyx_mstate_global->__pyx_n_u_calcQuadraticBounds +#define __pyx_kp_u_calcQuadraticBounds_line_298 __pyx_mstate_global->__pyx_kp_u_calcQuadraticBounds_line_298 +#define __pyx_n_s_calcQuadraticParameters __pyx_mstate_global->__pyx_n_s_calcQuadraticParameters +#define __pyx_n_s_calcQuadraticPoints __pyx_mstate_global->__pyx_n_s_calcQuadraticPoints +#define __pyx_n_s_class_getitem __pyx_mstate_global->__pyx_n_s_class_getitem +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_close __pyx_mstate_global->__pyx_n_s_close +#define __pyx_n_s_collections __pyx_mstate_global->__pyx_n_s_collections +#define __pyx_n_s_cos __pyx_mstate_global->__pyx_n_s_cos +#define __pyx_n_s_cubicPointAtT __pyx_mstate_global->__pyx_n_s_cubicPointAtT +#define __pyx_n_u_cubicPointAtT __pyx_mstate_global->__pyx_n_u_cubicPointAtT +#define __pyx_n_s_cubicPointAtTC __pyx_mstate_global->__pyx_n_s_cubicPointAtTC +#define __pyx_n_u_cubicPointAtTC __pyx_mstate_global->__pyx_n_u_cubicPointAtTC +#define __pyx_n_s_curve __pyx_mstate_global->__pyx_n_s_curve +#define __pyx_n_s_curve1 __pyx_mstate_global->__pyx_n_s_curve1 +#define __pyx_n_s_curve2 __pyx_mstate_global->__pyx_n_s_curve2 +#define __pyx_n_s_curveCurveIntersections __pyx_mstate_global->__pyx_n_s_curveCurveIntersections +#define __pyx_n_u_curveCurveIntersections __pyx_mstate_global->__pyx_n_u_curveCurveIntersections +#define __pyx_kp_u_curveCurveIntersections_line_137 __pyx_mstate_global->__pyx_kp_u_curveCurveIntersections_line_137 +#define __pyx_n_s_curveLineIntersections __pyx_mstate_global->__pyx_n_s_curveLineIntersections +#define __pyx_n_u_curveLineIntersections __pyx_mstate_global->__pyx_n_u_curveLineIntersections +#define __pyx_kp_u_curveLineIntersections_line_1248 __pyx_mstate_global->__pyx_kp_u_curveLineIntersections_line_1248 +#define __pyx_n_s_curve_bounds __pyx_mstate_global->__pyx_n_s_curve_bounds +#define __pyx_n_s_curve_curve_intersections_t __pyx_mstate_global->__pyx_n_s_curve_curve_intersections_t +#define __pyx_n_s_curve_curve_intersections_t_loc __pyx_mstate_global->__pyx_n_s_curve_curve_intersections_t_loc +#define __pyx_n_s_curve_curve_intersections_t_loc_2 __pyx_mstate_global->__pyx_n_s_curve_curve_intersections_t_loc_2 +#define __pyx_n_s_curve_line_intersections_t __pyx_mstate_global->__pyx_n_s_curve_line_intersections_t +#define __pyx_n_s_curve_line_intersections_t_loca __pyx_mstate_global->__pyx_n_s_curve_line_intersections_t_loca +#define __pyx_n_s_cx __pyx_mstate_global->__pyx_n_s_cx +#define __pyx_n_s_cy __pyx_mstate_global->__pyx_n_s_cy +#define __pyx_n_s_cython __pyx_mstate_global->__pyx_n_s_cython +#define __pyx_n_s_d __pyx_mstate_global->__pyx_n_s_d +#define __pyx_n_s_d0 __pyx_mstate_global->__pyx_n_s_d0 +#define __pyx_n_s_d1 __pyx_mstate_global->__pyx_n_s_d1 +#define __pyx_n_s_d1x __pyx_mstate_global->__pyx_n_s_d1x +#define __pyx_n_s_d1y __pyx_mstate_global->__pyx_n_s_d1y +#define __pyx_n_s_delta __pyx_mstate_global->__pyx_n_s_delta +#define __pyx_n_s_delta_2 __pyx_mstate_global->__pyx_n_s_delta_2 +#define __pyx_n_s_delta_3 __pyx_mstate_global->__pyx_n_s_delta_3 +#define __pyx_n_s_deriv3 __pyx_mstate_global->__pyx_n_s_deriv3 +#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable +#define __pyx_n_s_doctest __pyx_mstate_global->__pyx_n_s_doctest +#define __pyx_n_s_dx __pyx_mstate_global->__pyx_n_s_dx +#define __pyx_n_s_dy __pyx_mstate_global->__pyx_n_s_dy +#define __pyx_n_s_e __pyx_mstate_global->__pyx_n_s_e +#define __pyx_n_s_e1 __pyx_mstate_global->__pyx_n_s_e1 +#define __pyx_n_s_e1x __pyx_mstate_global->__pyx_n_s_e1x +#define __pyx_n_s_e1y __pyx_mstate_global->__pyx_n_s_e1y +#define __pyx_n_s_e2 __pyx_mstate_global->__pyx_n_s_e2 +#define __pyx_n_s_e2x __pyx_mstate_global->__pyx_n_s_e2x +#define __pyx_n_s_e2y __pyx_mstate_global->__pyx_n_s_e2y +#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable +#define __pyx_n_s_end __pyx_mstate_global->__pyx_n_s_end +#define __pyx_n_s_epsilon __pyx_mstate_global->__pyx_n_s_epsilon +#define __pyx_n_s_epsilonDigits __pyx_mstate_global->__pyx_n_s_epsilonDigits +#define __pyx_n_s_ex __pyx_mstate_global->__pyx_n_s_ex +#define __pyx_n_s_exit __pyx_mstate_global->__pyx_n_s_exit +#define __pyx_n_s_ey __pyx_mstate_global->__pyx_n_s_ey +#define __pyx_n_s_failed __pyx_mstate_global->__pyx_n_s_failed +#define __pyx_n_s_fontTools_misc __pyx_mstate_global->__pyx_n_s_fontTools_misc +#define __pyx_n_s_fontTools_misc_arrayTools __pyx_mstate_global->__pyx_n_s_fontTools_misc_arrayTools +#define __pyx_n_s_fontTools_misc_bezierTools __pyx_mstate_global->__pyx_n_s_fontTools_misc_bezierTools +#define __pyx_n_s_fontTools_misc_transform __pyx_mstate_global->__pyx_n_s_fontTools_misc_transform +#define __pyx_n_s_found __pyx_mstate_global->__pyx_n_s_found +#define __pyx_kp_u_g __pyx_mstate_global->__pyx_kp_u_g +#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc +#define __pyx_n_s_genexpr __pyx_mstate_global->__pyx_n_s_genexpr +#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_n_s_insert __pyx_mstate_global->__pyx_n_s_insert +#define __pyx_n_s_intersection_ts __pyx_mstate_global->__pyx_n_s_intersection_ts +#define __pyx_n_s_intersections __pyx_mstate_global->__pyx_n_s_intersections +#define __pyx_n_s_intersects __pyx_mstate_global->__pyx_n_s_intersects +#define __pyx_n_s_isHorizontal __pyx_mstate_global->__pyx_n_s_isHorizontal +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_n_s_is_linelike __pyx_mstate_global->__pyx_n_s_is_linelike +#define __pyx_n_s_is_linelike_locals_genexpr __pyx_mstate_global->__pyx_n_s_is_linelike_locals_genexpr +#define __pyx_n_s_isclose __pyx_mstate_global->__pyx_n_s_isclose +#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled +#define __pyx_n_s_it __pyx_mstate_global->__pyx_n_s_it +#define __pyx_n_s_key __pyx_mstate_global->__pyx_n_s_key +#define __pyx_n_s_line __pyx_mstate_global->__pyx_n_s_line +#define __pyx_n_s_line1 __pyx_mstate_global->__pyx_n_s_line1 +#define __pyx_n_s_line2 __pyx_mstate_global->__pyx_n_s_line2 +#define __pyx_n_s_lineLineIntersections __pyx_mstate_global->__pyx_n_s_lineLineIntersections +#define __pyx_n_u_lineLineIntersections __pyx_mstate_global->__pyx_n_u_lineLineIntersections +#define __pyx_kp_u_lineLineIntersections_line_1147 __pyx_mstate_global->__pyx_kp_u_lineLineIntersections_line_1147 +#define __pyx_n_s_linePointAtT __pyx_mstate_global->__pyx_n_s_linePointAtT +#define __pyx_n_u_linePointAtT __pyx_mstate_global->__pyx_n_u_linePointAtT +#define __pyx_n_s_line_t __pyx_mstate_global->__pyx_n_s_line_t +#define __pyx_n_s_line_t_of_pt __pyx_mstate_global->__pyx_n_s_line_t_of_pt +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_u_main __pyx_mstate_global->__pyx_n_u_main +#define __pyx_n_s_math __pyx_mstate_global->__pyx_n_s_math +#define __pyx_n_s_maybeline __pyx_mstate_global->__pyx_n_s_maybeline +#define __pyx_n_s_mid __pyx_mstate_global->__pyx_n_s_mid +#define __pyx_n_s_midPt __pyx_mstate_global->__pyx_n_s_midPt +#define __pyx_n_s_midpoint __pyx_mstate_global->__pyx_n_s_midpoint +#define __pyx_n_s_mult __pyx_mstate_global->__pyx_n_s_mult +#define __pyx_n_s_n __pyx_mstate_global->__pyx_n_s_n +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_namedtuple __pyx_mstate_global->__pyx_n_s_namedtuple +#define __pyx_n_s_obj __pyx_mstate_global->__pyx_n_s_obj +#define __pyx_n_s_off1 __pyx_mstate_global->__pyx_n_s_off1 +#define __pyx_n_s_off2 __pyx_mstate_global->__pyx_n_s_off2 +#define __pyx_n_s_one __pyx_mstate_global->__pyx_n_s_one +#define __pyx_n_s_origDist __pyx_mstate_global->__pyx_n_s_origDist +#define __pyx_n_s_origin __pyx_mstate_global->__pyx_n_s_origin +#define __pyx_n_s_p0 __pyx_mstate_global->__pyx_n_s_p0 +#define __pyx_n_s_p1 __pyx_mstate_global->__pyx_n_s_p1 +#define __pyx_n_s_p2 __pyx_mstate_global->__pyx_n_s_p2 +#define __pyx_n_s_p3 __pyx_mstate_global->__pyx_n_s_p3 +#define __pyx_n_s_pi __pyx_mstate_global->__pyx_n_s_pi +#define __pyx_n_s_pointAtT __pyx_mstate_global->__pyx_n_s_pointAtT +#define __pyx_n_s_pointFinder __pyx_mstate_global->__pyx_n_s_pointFinder +#define __pyx_n_s_points __pyx_mstate_global->__pyx_n_s_points +#define __pyx_n_s_precision __pyx_mstate_global->__pyx_n_s_precision +#define __pyx_n_s_print __pyx_mstate_global->__pyx_n_s_print +#define __pyx_n_s_printSegments __pyx_mstate_global->__pyx_n_s_printSegments +#define __pyx_n_s_pt __pyx_mstate_global->__pyx_n_s_pt +#define __pyx_n_u_pt __pyx_mstate_global->__pyx_n_u_pt +#define __pyx_n_s_pt1 __pyx_mstate_global->__pyx_n_s_pt1 +#define __pyx_n_s_pt1x __pyx_mstate_global->__pyx_n_s_pt1x +#define __pyx_n_s_pt1y __pyx_mstate_global->__pyx_n_s_pt1y +#define __pyx_n_s_pt2 __pyx_mstate_global->__pyx_n_s_pt2 +#define __pyx_n_s_pt2x __pyx_mstate_global->__pyx_n_s_pt2x +#define __pyx_n_s_pt2y __pyx_mstate_global->__pyx_n_s_pt2y +#define __pyx_n_s_pt3 __pyx_mstate_global->__pyx_n_s_pt3 +#define __pyx_n_s_pt4 __pyx_mstate_global->__pyx_n_s_pt4 +#define __pyx_n_s_px __pyx_mstate_global->__pyx_n_s_px +#define __pyx_n_s_py __pyx_mstate_global->__pyx_n_s_py +#define __pyx_n_s_quadraticPointAtT __pyx_mstate_global->__pyx_n_s_quadraticPointAtT +#define __pyx_n_u_quadraticPointAtT __pyx_mstate_global->__pyx_n_u_quadraticPointAtT +#define __pyx_n_s_r __pyx_mstate_global->__pyx_n_s_r +#define __pyx_n_s_rDD __pyx_mstate_global->__pyx_n_s_rDD +#define __pyx_n_s_rQ2 __pyx_mstate_global->__pyx_n_s_rQ2 +#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range +#define __pyx_n_s_range1 __pyx_mstate_global->__pyx_n_s_range1 +#define __pyx_n_s_range2 __pyx_mstate_global->__pyx_n_s_range2 +#define __pyx_n_s_rectArea __pyx_mstate_global->__pyx_n_s_rectArea +#define __pyx_n_s_roots __pyx_mstate_global->__pyx_n_s_roots +#define __pyx_n_s_rotate __pyx_mstate_global->__pyx_n_s_rotate +#define __pyx_n_s_round __pyx_mstate_global->__pyx_n_s_round +#define __pyx_n_s_s __pyx_mstate_global->__pyx_n_s_s +#define __pyx_n_s_s1 __pyx_mstate_global->__pyx_n_s_s1 +#define __pyx_n_s_s1x __pyx_mstate_global->__pyx_n_s_s1x +#define __pyx_n_s_s1y __pyx_mstate_global->__pyx_n_s_s1y +#define __pyx_n_s_s2 __pyx_mstate_global->__pyx_n_s_s2 +#define __pyx_n_s_s2x __pyx_mstate_global->__pyx_n_s_s2x +#define __pyx_n_s_s2y __pyx_mstate_global->__pyx_n_s_s2y +#define __pyx_kp_u_s_2 __pyx_mstate_global->__pyx_kp_u_s_2 +#define __pyx_n_s_scale __pyx_mstate_global->__pyx_n_s_scale +#define __pyx_n_s_sectRect __pyx_mstate_global->__pyx_n_s_sectRect +#define __pyx_n_s_seen __pyx_mstate_global->__pyx_n_s_seen +#define __pyx_n_s_seg __pyx_mstate_global->__pyx_n_s_seg +#define __pyx_n_s_seg1 __pyx_mstate_global->__pyx_n_s_seg1 +#define __pyx_n_s_seg2 __pyx_mstate_global->__pyx_n_s_seg2 +#define __pyx_n_s_segment __pyx_mstate_global->__pyx_n_s_segment +#define __pyx_n_s_segmentPointAtT __pyx_mstate_global->__pyx_n_s_segmentPointAtT +#define __pyx_n_u_segmentPointAtT __pyx_mstate_global->__pyx_n_u_segmentPointAtT +#define __pyx_n_s_segmentSegmentIntersections __pyx_mstate_global->__pyx_n_s_segmentSegmentIntersections +#define __pyx_n_u_segmentSegmentIntersections __pyx_mstate_global->__pyx_n_u_segmentSegmentIntersections +#define __pyx_kp_u_segmentSegmentIntersections_line __pyx_mstate_global->__pyx_kp_u_segmentSegmentIntersections_line +#define __pyx_n_s_segmentrepr __pyx_mstate_global->__pyx_n_s_segmentrepr +#define __pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2 __pyx_mstate_global->__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2 +#define __pyx_kp_u_segmentrepr_line_1465 __pyx_mstate_global->__pyx_kp_u_segmentrepr_line_1465 +#define __pyx_n_s_segmentrepr_locals_genexpr __pyx_mstate_global->__pyx_n_s_segmentrepr_locals_genexpr +#define __pyx_n_s_segments __pyx_mstate_global->__pyx_n_s_segments +#define __pyx_n_s_send __pyx_mstate_global->__pyx_n_s_send +#define __pyx_n_s_slope12 __pyx_mstate_global->__pyx_n_s_slope12 +#define __pyx_n_s_slope34 __pyx_mstate_global->__pyx_n_s_slope34 +#define __pyx_n_s_solutions __pyx_mstate_global->__pyx_n_s_solutions +#define __pyx_n_s_solveCubic __pyx_mstate_global->__pyx_n_s_solveCubic +#define __pyx_n_u_solveCubic __pyx_mstate_global->__pyx_n_u_solveCubic +#define __pyx_kp_u_solveCubic_line_841 __pyx_mstate_global->__pyx_kp_u_solveCubic_line_841 +#define __pyx_n_s_solveQuadratic __pyx_mstate_global->__pyx_n_s_solveQuadratic +#define __pyx_n_u_solveQuadratic __pyx_mstate_global->__pyx_n_u_solveQuadratic +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_splitCubic __pyx_mstate_global->__pyx_n_s_splitCubic +#define __pyx_n_u_splitCubic __pyx_mstate_global->__pyx_n_u_splitCubic +#define __pyx_n_s_splitCubicAtT __pyx_mstate_global->__pyx_n_s_splitCubicAtT +#define __pyx_n_s_splitCubicAtTC __pyx_mstate_global->__pyx_n_s_splitCubicAtTC +#define __pyx_n_u_splitCubicAtTC __pyx_mstate_global->__pyx_n_u_splitCubicAtTC +#define __pyx_n_s_splitCubicAtTC_2 __pyx_mstate_global->__pyx_n_s_splitCubicAtTC_2 +#define __pyx_n_s_splitCubicAtT_2 __pyx_mstate_global->__pyx_n_s_splitCubicAtT_2 +#define __pyx_n_u_splitCubicAtT_2 __pyx_mstate_global->__pyx_n_u_splitCubicAtT_2 +#define __pyx_kp_u_splitCubicAtT_line_613 __pyx_mstate_global->__pyx_kp_u_splitCubicAtT_line_613 +#define __pyx_n_s_splitCubicIntoTwoAtTC __pyx_mstate_global->__pyx_n_s_splitCubicIntoTwoAtTC +#define __pyx_n_u_splitCubicIntoTwoAtTC __pyx_mstate_global->__pyx_n_u_splitCubicIntoTwoAtTC +#define __pyx_kp_u_splitCubic_line_552 __pyx_mstate_global->__pyx_kp_u_splitCubic_line_552 +#define __pyx_n_s_splitCubic_locals_genexpr __pyx_mstate_global->__pyx_n_s_splitCubic_locals_genexpr +#define __pyx_n_s_splitLine __pyx_mstate_global->__pyx_n_s_splitLine +#define __pyx_n_u_splitLine __pyx_mstate_global->__pyx_n_u_splitLine +#define __pyx_kp_u_splitLine_line_450 __pyx_mstate_global->__pyx_kp_u_splitLine_line_450 +#define __pyx_n_s_splitQuadratic __pyx_mstate_global->__pyx_n_s_splitQuadratic +#define __pyx_n_u_splitQuadratic __pyx_mstate_global->__pyx_n_u_splitQuadratic +#define __pyx_n_s_splitQuadraticAtT __pyx_mstate_global->__pyx_n_s_splitQuadraticAtT +#define __pyx_n_s_splitQuadraticAtT_2 __pyx_mstate_global->__pyx_n_s_splitQuadraticAtT_2 +#define __pyx_n_u_splitQuadraticAtT_2 __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT_2 +#define __pyx_kp_u_splitQuadraticAtT_line_589 __pyx_mstate_global->__pyx_kp_u_splitQuadraticAtT_line_589 +#define __pyx_kp_u_splitQuadratic_line_507 __pyx_mstate_global->__pyx_kp_u_splitQuadratic_line_507 +#define __pyx_n_s_splitQuadratic_locals_genexpr __pyx_mstate_global->__pyx_n_s_splitQuadratic_locals_genexpr +#define __pyx_n_s_split_cubic_into_two __pyx_mstate_global->__pyx_n_s_split_cubic_into_two +#define __pyx_n_s_split_segment_at_t __pyx_mstate_global->__pyx_n_s_split_segment_at_t +#define __pyx_n_s_sqrt __pyx_mstate_global->__pyx_n_s_sqrt +#define __pyx_n_s_start __pyx_mstate_global->__pyx_n_s_start +#define __pyx_n_s_swapped __pyx_mstate_global->__pyx_n_s_swapped +#define __pyx_n_s_sx __pyx_mstate_global->__pyx_n_s_sx +#define __pyx_n_s_sy __pyx_mstate_global->__pyx_n_s_sy +#define __pyx_n_s_sys __pyx_mstate_global->__pyx_n_s_sys +#define __pyx_n_s_t __pyx_mstate_global->__pyx_n_s_t +#define __pyx_n_s_t1 __pyx_mstate_global->__pyx_n_s_t1 +#define __pyx_n_u_t1 __pyx_mstate_global->__pyx_n_u_t1 +#define __pyx_n_s_t1_2 __pyx_mstate_global->__pyx_n_s_t1_2 +#define __pyx_n_s_t1_3 __pyx_mstate_global->__pyx_n_s_t1_3 +#define __pyx_n_s_t2 __pyx_mstate_global->__pyx_n_s_t2 +#define __pyx_n_u_t2 __pyx_mstate_global->__pyx_n_u_t2 +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_testmod __pyx_mstate_global->__pyx_n_s_testmod +#define __pyx_n_s_theta __pyx_mstate_global->__pyx_n_s_theta +#define __pyx_n_s_throw __pyx_mstate_global->__pyx_n_s_throw +#define __pyx_n_s_tolerance __pyx_mstate_global->__pyx_n_s_tolerance +#define __pyx_n_s_transformPoints __pyx_mstate_global->__pyx_n_s_transformPoints +#define __pyx_n_s_translate __pyx_mstate_global->__pyx_n_s_translate +#define __pyx_n_s_ts __pyx_mstate_global->__pyx_n_s_ts +#define __pyx_n_s_two __pyx_mstate_global->__pyx_n_s_two +#define __pyx_n_s_unique_key __pyx_mstate_global->__pyx_n_s_unique_key +#define __pyx_n_s_unique_values __pyx_mstate_global->__pyx_n_s_unique_values +#define __pyx_n_s_v0 __pyx_mstate_global->__pyx_n_s_v0 +#define __pyx_n_s_v1 __pyx_mstate_global->__pyx_n_s_v1 +#define __pyx_n_s_v2 __pyx_mstate_global->__pyx_n_s_v2 +#define __pyx_n_s_v3 __pyx_mstate_global->__pyx_n_s_v3 +#define __pyx_n_s_v4 __pyx_mstate_global->__pyx_n_s_v4 +#define __pyx_n_s_where __pyx_mstate_global->__pyx_n_s_where +#define __pyx_n_s_x __pyx_mstate_global->__pyx_n_s_x +#define __pyx_n_s_x0 __pyx_mstate_global->__pyx_n_s_x0 +#define __pyx_n_s_x1 __pyx_mstate_global->__pyx_n_s_x1 +#define __pyx_n_s_x2 __pyx_mstate_global->__pyx_n_s_x2 +#define __pyx_n_s_x3 __pyx_mstate_global->__pyx_n_s_x3 +#define __pyx_n_s_x4 __pyx_mstate_global->__pyx_n_s_x4 +#define __pyx_n_s_xDiff __pyx_mstate_global->__pyx_n_s_xDiff +#define __pyx_n_s_xRoots __pyx_mstate_global->__pyx_n_s_xRoots +#define __pyx_n_s_y __pyx_mstate_global->__pyx_n_s_y +#define __pyx_n_s_y1 __pyx_mstate_global->__pyx_n_s_y1 +#define __pyx_n_s_y2 __pyx_mstate_global->__pyx_n_s_y2 +#define __pyx_n_s_y3 __pyx_mstate_global->__pyx_n_s_y3 +#define __pyx_n_s_y4 __pyx_mstate_global->__pyx_n_s_y4 +#define __pyx_n_s_yDiff __pyx_mstate_global->__pyx_n_s_yDiff +#define __pyx_n_s_yRoots __pyx_mstate_global->__pyx_n_s_yRoots +#define __pyx_float_0_0 __pyx_mstate_global->__pyx_float_0_0 +#define __pyx_float_0_5 __pyx_mstate_global->__pyx_float_0_5 +#define __pyx_float_1_0 __pyx_mstate_global->__pyx_float_1_0 +#define __pyx_float_2_0 __pyx_mstate_global->__pyx_float_2_0 +#define __pyx_float_3_0 __pyx_mstate_global->__pyx_float_3_0 +#define __pyx_float_4_0 __pyx_mstate_global->__pyx_float_4_0 +#define __pyx_float_9_0 __pyx_mstate_global->__pyx_float_9_0 +#define __pyx_float_1eneg_3 __pyx_mstate_global->__pyx_float_1eneg_3 +#define __pyx_float_27_0 __pyx_mstate_global->__pyx_float_27_0 +#define __pyx_float_54_0 __pyx_mstate_global->__pyx_float_54_0 +#define __pyx_float_0_005 __pyx_mstate_global->__pyx_float_0_005 +#define __pyx_float_0_125 __pyx_mstate_global->__pyx_float_0_125 +#define __pyx_float_1eneg_10 __pyx_mstate_global->__pyx_float_1eneg_10 +#define __pyx_float_neg_2_0 __pyx_mstate_global->__pyx_float_neg_2_0 +#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0 +#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 +#define __pyx_int_2 __pyx_mstate_global->__pyx_int_2 +#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3 +#define __pyx_int_6 __pyx_mstate_global->__pyx_int_6 +#define __pyx_int_neg_1 __pyx_mstate_global->__pyx_int_neg_1 +#define __pyx_codeobj_ __pyx_mstate_global->__pyx_codeobj_ +#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 +#define __pyx_tuple__6 __pyx_mstate_global->__pyx_tuple__6 +#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 +#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 +#define __pyx_tuple__14 __pyx_mstate_global->__pyx_tuple__14 +#define __pyx_tuple__15 __pyx_mstate_global->__pyx_tuple__15 +#define __pyx_tuple__17 __pyx_mstate_global->__pyx_tuple__17 +#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 +#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21 +#define __pyx_tuple__23 __pyx_mstate_global->__pyx_tuple__23 +#define __pyx_tuple__26 __pyx_mstate_global->__pyx_tuple__26 +#define __pyx_tuple__28 __pyx_mstate_global->__pyx_tuple__28 +#define __pyx_tuple__30 __pyx_mstate_global->__pyx_tuple__30 +#define __pyx_tuple__32 __pyx_mstate_global->__pyx_tuple__32 +#define __pyx_tuple__34 __pyx_mstate_global->__pyx_tuple__34 +#define __pyx_tuple__36 __pyx_mstate_global->__pyx_tuple__36 +#define __pyx_tuple__38 __pyx_mstate_global->__pyx_tuple__38 +#define __pyx_tuple__40 __pyx_mstate_global->__pyx_tuple__40 +#define __pyx_tuple__42 __pyx_mstate_global->__pyx_tuple__42 +#define __pyx_tuple__44 __pyx_mstate_global->__pyx_tuple__44 +#define __pyx_tuple__46 __pyx_mstate_global->__pyx_tuple__46 +#define __pyx_tuple__48 __pyx_mstate_global->__pyx_tuple__48 +#define __pyx_tuple__50 __pyx_mstate_global->__pyx_tuple__50 +#define __pyx_tuple__52 __pyx_mstate_global->__pyx_tuple__52 +#define __pyx_tuple__53 __pyx_mstate_global->__pyx_tuple__53 +#define __pyx_tuple__55 __pyx_mstate_global->__pyx_tuple__55 +#define __pyx_tuple__57 __pyx_mstate_global->__pyx_tuple__57 +#define __pyx_tuple__59 __pyx_mstate_global->__pyx_tuple__59 +#define __pyx_tuple__61 __pyx_mstate_global->__pyx_tuple__61 +#define __pyx_tuple__63 __pyx_mstate_global->__pyx_tuple__63 +#define __pyx_tuple__65 __pyx_mstate_global->__pyx_tuple__65 +#define __pyx_tuple__67 __pyx_mstate_global->__pyx_tuple__67 +#define __pyx_tuple__69 __pyx_mstate_global->__pyx_tuple__69 +#define __pyx_tuple__71 __pyx_mstate_global->__pyx_tuple__71 +#define __pyx_tuple__73 __pyx_mstate_global->__pyx_tuple__73 +#define __pyx_tuple__75 __pyx_mstate_global->__pyx_tuple__75 +#define __pyx_tuple__77 __pyx_mstate_global->__pyx_tuple__77 +#define __pyx_tuple__79 __pyx_mstate_global->__pyx_tuple__79 +#define __pyx_tuple__81 __pyx_mstate_global->__pyx_tuple__81 +#define __pyx_tuple__83 __pyx_mstate_global->__pyx_tuple__83 +#define __pyx_tuple__85 __pyx_mstate_global->__pyx_tuple__85 +#define __pyx_tuple__87 __pyx_mstate_global->__pyx_tuple__87 +#define __pyx_tuple__89 __pyx_mstate_global->__pyx_tuple__89 +#define __pyx_tuple__92 __pyx_mstate_global->__pyx_tuple__92 +#define __pyx_tuple__94 __pyx_mstate_global->__pyx_tuple__94 +#define __pyx_tuple__95 __pyx_mstate_global->__pyx_tuple__95 +#define __pyx_tuple__97 __pyx_mstate_global->__pyx_tuple__97 +#define __pyx_tuple__99 __pyx_mstate_global->__pyx_tuple__99 +#define __pyx_codeobj__3 __pyx_mstate_global->__pyx_codeobj__3 +#define __pyx_codeobj__7 __pyx_mstate_global->__pyx_codeobj__7 +#define __pyx_tuple__101 __pyx_mstate_global->__pyx_tuple__101 +#define __pyx_tuple__103 __pyx_mstate_global->__pyx_tuple__103 +#define __pyx_codeobj__13 __pyx_mstate_global->__pyx_codeobj__13 +#define __pyx_codeobj__16 __pyx_mstate_global->__pyx_codeobj__16 +#define __pyx_codeobj__18 __pyx_mstate_global->__pyx_codeobj__18 +#define __pyx_codeobj__20 __pyx_mstate_global->__pyx_codeobj__20 +#define __pyx_codeobj__22 __pyx_mstate_global->__pyx_codeobj__22 +#define __pyx_codeobj__24 __pyx_mstate_global->__pyx_codeobj__24 +#define __pyx_codeobj__25 __pyx_mstate_global->__pyx_codeobj__25 +#define __pyx_codeobj__27 __pyx_mstate_global->__pyx_codeobj__27 +#define __pyx_codeobj__29 __pyx_mstate_global->__pyx_codeobj__29 +#define __pyx_codeobj__31 __pyx_mstate_global->__pyx_codeobj__31 +#define __pyx_codeobj__33 __pyx_mstate_global->__pyx_codeobj__33 +#define __pyx_codeobj__35 __pyx_mstate_global->__pyx_codeobj__35 +#define __pyx_codeobj__37 __pyx_mstate_global->__pyx_codeobj__37 +#define __pyx_codeobj__39 __pyx_mstate_global->__pyx_codeobj__39 +#define __pyx_codeobj__41 __pyx_mstate_global->__pyx_codeobj__41 +#define __pyx_codeobj__43 __pyx_mstate_global->__pyx_codeobj__43 +#define __pyx_codeobj__45 __pyx_mstate_global->__pyx_codeobj__45 +#define __pyx_codeobj__47 __pyx_mstate_global->__pyx_codeobj__47 +#define __pyx_codeobj__49 __pyx_mstate_global->__pyx_codeobj__49 +#define __pyx_codeobj__51 __pyx_mstate_global->__pyx_codeobj__51 +#define __pyx_codeobj__54 __pyx_mstate_global->__pyx_codeobj__54 +#define __pyx_codeobj__56 __pyx_mstate_global->__pyx_codeobj__56 +#define __pyx_codeobj__58 __pyx_mstate_global->__pyx_codeobj__58 +#define __pyx_codeobj__60 __pyx_mstate_global->__pyx_codeobj__60 +#define __pyx_codeobj__62 __pyx_mstate_global->__pyx_codeobj__62 +#define __pyx_codeobj__64 __pyx_mstate_global->__pyx_codeobj__64 +#define __pyx_codeobj__66 __pyx_mstate_global->__pyx_codeobj__66 +#define __pyx_codeobj__68 __pyx_mstate_global->__pyx_codeobj__68 +#define __pyx_codeobj__70 __pyx_mstate_global->__pyx_codeobj__70 +#define __pyx_codeobj__72 __pyx_mstate_global->__pyx_codeobj__72 +#define __pyx_codeobj__74 __pyx_mstate_global->__pyx_codeobj__74 +#define __pyx_codeobj__76 __pyx_mstate_global->__pyx_codeobj__76 +#define __pyx_codeobj__78 __pyx_mstate_global->__pyx_codeobj__78 +#define __pyx_codeobj__80 __pyx_mstate_global->__pyx_codeobj__80 +#define __pyx_codeobj__82 __pyx_mstate_global->__pyx_codeobj__82 +#define __pyx_codeobj__84 __pyx_mstate_global->__pyx_codeobj__84 +#define __pyx_codeobj__86 __pyx_mstate_global->__pyx_codeobj__86 +#define __pyx_codeobj__88 __pyx_mstate_global->__pyx_codeobj__88 +#define __pyx_codeobj__90 __pyx_mstate_global->__pyx_codeobj__90 +#define __pyx_codeobj__93 __pyx_mstate_global->__pyx_codeobj__93 +#define __pyx_codeobj__96 __pyx_mstate_global->__pyx_codeobj__96 +#define __pyx_codeobj__98 __pyx_mstate_global->__pyx_codeobj__98 +#define __pyx_codeobj__100 __pyx_mstate_global->__pyx_codeobj__100 +#define __pyx_codeobj__102 __pyx_mstate_global->__pyx_codeobj__102 +#define __pyx_codeobj__104 __pyx_mstate_global->__pyx_codeobj__104 +/* #### Code section: module_code ### */ + +/* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_calcCubicArcLength, "calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005)\nCalculates the arc length for a cubic Bezier segment.\n\n Whereas :func:`approximateCubicArcLength` approximates the length, this\n function calculates it by \"measuring\", recursively dividing the curve\n until the divided segments are shorter than ``tolerance``.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n tolerance: Controls the precision of the calcuation.\n\n Returns:\n Arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_1calcCubicArcLength = {"calcCubicArcLength", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_calcCubicArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_tolerance = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_tolerance,0}; + values[4] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)((PyObject*)__pyx_float_0_005))); + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, 1); __PYX_ERR(0, 56, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, 2); __PYX_ERR(0, 56, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, 3); __PYX_ERR(0, 56, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tolerance); + if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcCubicArcLength") < 0)) __PYX_ERR(0, 56, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_tolerance = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, __pyx_nargs); __PYX_ERR(0, 56, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_tolerance); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_tolerance) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicArcLength", 1); + + /* "fontTools/misc/bezierTools.py":70 + * Arc length value. + * """ + * return calcCubicArcLengthC( # <<<<<<<<<<<<<< + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance + * ) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicArcLengthC); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":71 + * """ + * return calcCubicArcLengthC( + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_8 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_8 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[6] = {__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_v_tolerance}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_8, 5+__pyx_t_8); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_2_split_cubic_into_two, "_split_cubic_into_two(p0, p1, p2, p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_3_split_cubic_into_two = {"_split_cubic_into_two", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_2_split_cubic_into_two}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_p0 = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + PyObject *__pyx_v_p3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_cubic_into_two (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_p0,&__pyx_n_s_p1,&__pyx_n_s_p2,&__pyx_n_s_p3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p0)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, 1); __PYX_ERR(0, 75, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, 2); __PYX_ERR(0, 75, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, 3); __PYX_ERR(0, 75, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_split_cubic_into_two") < 0)) __PYX_ERR(0, 75, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_p0 = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + __pyx_v_p3 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 75, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_cubic_into_two", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(__pyx_self, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p0, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3) { + PyObject *__pyx_v_mid = NULL; + PyObject *__pyx_v_deriv3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_split_cubic_into_two", 1); + + /* "fontTools/misc/bezierTools.py":76 + * + * def _split_cubic_into_two(p0, p1, p2, p3): + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 # <<<<<<<<<<<<<< + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_p1, __pyx_v_p2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_t_1, 3, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_v_p0, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_float_0_125); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_mid = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":77 + * def _split_cubic_into_two(p0, p1, p2, p3): + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 # <<<<<<<<<<<<<< + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_p3, __pyx_v_p2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_p0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_float_0_125); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_deriv3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":78 + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( # <<<<<<<<<<<<<< + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":79 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) + */ + __pyx_t_2 = PyNumber_Add(__pyx_v_p0, __pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_float_0_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Subtract(__pyx_v_mid, __pyx_v_deriv3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_p0); + __Pyx_GIVEREF(__pyx_v_p0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_p0)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_mid); + __Pyx_GIVEREF(__pyx_v_mid); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_v_mid)) __PYX_ERR(0, 79, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":80 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_2 = PyNumber_Add(__pyx_v_mid, __pyx_v_deriv3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_float_0_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_mid); + __Pyx_GIVEREF(__pyx_v_mid); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_mid)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_p3); + __Pyx_GIVEREF(__pyx_v_p3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_p3)) __PYX_ERR(0, 80, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":79 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) + */ + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1)) __PYX_ERR(0, 79, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_cubic_into_two", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_mid); + __Pyx_XDECREF(__pyx_v_deriv3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse, "_calcCubicArcLengthCRecurse(double mult, double complex p0, double complex p1, double complex p2, double complex p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse = {"_calcCubicArcLengthCRecurse", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + double __pyx_v_mult; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_calcCubicArcLengthCRecurse (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_mult,&__pyx_n_s_p0,&__pyx_n_s_p1,&__pyx_n_s_p2,&__pyx_n_s_p3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_mult)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p0)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, 1); __PYX_ERR(0, 84, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, 2); __PYX_ERR(0, 84, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, 3); __PYX_ERR(0, 84, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, 4); __PYX_ERR(0, 84, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_calcCubicArcLengthCRecurse") < 0)) __PYX_ERR(0, 84, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_mult = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_mult == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p0 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[4]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 84, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._calcCubicArcLengthCRecurse", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(__pyx_self, __pyx_v_mult, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_mult, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + double __pyx_v_arch; + double __pyx_v_box; + PyObject *__pyx_v_one = NULL; + PyObject *__pyx_v_two = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + PyObject *(*__pyx_t_10)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_calcCubicArcLengthCRecurse", 1); + + /* "fontTools/misc/bezierTools.py":93 + * @cython.locals(mult=cython.double, arch=cython.double, box=cython.double) + * def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + * arch = abs(p0 - p3) # <<<<<<<<<<<<<< + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult >= box: + */ + __pyx_v_arch = __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p0, __pyx_v_p3)); + + /* "fontTools/misc/bezierTools.py":94 + * def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) # <<<<<<<<<<<<<< + * if arch * mult >= box: + * return (arch + box) * 0.5 + */ + __pyx_v_box = ((__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p0, __pyx_v_p1)) + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p2))) + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p3))); + + /* "fontTools/misc/bezierTools.py":95 + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult >= box: # <<<<<<<<<<<<<< + * return (arch + box) * 0.5 + * else: + */ + __pyx_t_1 = ((__pyx_v_arch * __pyx_v_mult) >= __pyx_v_box); + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":96 + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult >= box: + * return (arch + box) * 0.5 # <<<<<<<<<<<<<< + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyFloat_FromDouble(((__pyx_v_arch + __pyx_v_box) * 0.5)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":95 + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult >= box: # <<<<<<<<<<<<<< + * return (arch + box) * 0.5 + * else: + */ + } + + /* "fontTools/misc/bezierTools.py":98 + * return (arch + box) * 0.5 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) # <<<<<<<<<<<<<< + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two + */ + /*else*/ { + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_split_cubic_into_two); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_p1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_9 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_8, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_9, 4+__pyx_t_9); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 98, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_7 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_7); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_10 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_3 = __pyx_t_10(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_7 = __pyx_t_10(__pyx_t_6); if (unlikely(!__pyx_t_7)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_6), 2) < 0) __PYX_ERR(0, 98, __pyx_L1_error) + __pyx_t_10 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_10 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 98, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_one = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_two = __pyx_t_7; + __pyx_t_7 = 0; + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error); + __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PySequence_Tuple(__pyx_v_one); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = PyNumber_Add(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "fontTools/misc/bezierTools.py":100 + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_2 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) + */ + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":100 + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_2 = __Pyx_PySequence_Tuple(__pyx_v_two); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) + */ + __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyNumber_Add(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._calcCubicArcLengthCRecurse", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_one); + __Pyx_XDECREF(__pyx_v_two); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC, "calcCubicArcLengthC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double tolerance=0.005)\nCalculates the arc length for a cubic Bezier segment.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n tolerance: Controls the precision of the calcuation.\n\n Returns:\n Arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC = {"calcCubicArcLengthC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_tolerance; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_tolerance,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, 1); __PYX_ERR(0, 104, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, 2); __PYX_ERR(0, 104, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, 3); __PYX_ERR(0, 104, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tolerance); + if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcCubicArcLengthC") < 0)) __PYX_ERR(0, 104, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + if (values[4]) { + __pyx_v_tolerance = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_tolerance == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + } else { + __pyx_v_tolerance = ((double)((double)0.005)); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, __pyx_nargs); __PYX_ERR(0, 104, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_tolerance); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_tolerance) { + double __pyx_v_mult; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicArcLengthC", 1); + + /* "fontTools/misc/bezierTools.py":125 + * Arc length value. + * """ + * mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math # <<<<<<<<<<<<<< + * return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) + * + */ + __pyx_v_mult = (1.0 + (1.5 * __pyx_v_tolerance)); + + /* "fontTools/misc/bezierTools.py":126 + * """ + * mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math + * return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_pt2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_v_pt3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_pt4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_9 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[6] = {__pyx_t_8, __pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_9, 5+__pyx_t_9); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":133 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_t_double_complex __pyx_v_v1, __pyx_t_double_complex __pyx_v_v2) { + double __pyx_r; + + /* "fontTools/misc/bezierTools.py":138 + * @cython.locals(v1=cython.complex, v2=cython.complex) + * def _dot(v1, v2): + * return (v1 * v2.conjugate()).real # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __Pyx_CREAL(__Pyx_c_prod_double(__pyx_v_v1, __Pyx_c_conj_double(__pyx_v_v2))); + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":133 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":141 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(double __pyx_v_x) { + double __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + double __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_intSecAtan", 1); + + /* "fontTools/misc/bezierTools.py":148 + * # In : sympy.integrate(sp.sec(sp.atan(x))) + * # Out: x*sqrt(x**2 + 1)/2 + asinh(x)/2 + * return x * math.sqrt(x**2 + 1) / 2 + math.asinh(x) / 2 # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyFloat_FromDouble((pow(__pyx_v_x, 2.0) + 1.0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_t_3}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyInt_TrueDivideObjC(__pyx_t_4, __pyx_int_2, 2, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_math); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_asinh); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_t_1}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = __Pyx_PyInt_TrueDivideObjC(__pyx_t_4, __pyx_int_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_7; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":141 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools._intSecAtan", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength, "calcQuadraticArcLength(pt1, pt2, pt3)\nCalculates the arc length for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment\n 0.0\n >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points\n 80.0\n >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical\n 80.0\n >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points\n 107.70329614269008\n >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0))\n 154.02976155645263\n >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0))\n 120.21581243984076\n >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50))\n 102.53273816445825\n >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside\n 66.66666666666667\n >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back\n 40.0\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength = {"calcQuadraticArcLength", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLength", 1, 3, 3, 1); __PYX_ERR(0, 151, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLength", 1, 3, 3, 2); __PYX_ERR(0, 151, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcQuadraticArcLength") < 0)) __PYX_ERR(0, 151, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLength", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 151, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticArcLength", 1); + + /* "fontTools/misc/bezierTools.py":183 + * 40.0 + * """ + * return calcQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcQuadraticArcLengthC); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 3+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC, "calcQuadraticArcLengthC(double complex pt1, double complex pt2, double complex pt3)\nCalculates the arc length for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as a complex number.\n pt2: Handle point of the Bezier as a complex number.\n pt3: End point of the Bezier as a complex number.\n\n Returns:\n Arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC = {"calcQuadraticArcLengthC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLengthC", 1, 3, 3, 1); __PYX_ERR(0, 186, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLengthC", 1, 3, 3, 2); __PYX_ERR(0, 186, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcQuadraticArcLengthC") < 0)) __PYX_ERR(0, 186, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLengthC", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 186, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3) { + double __pyx_v_scale; + double __pyx_v_origDist; + double __pyx_v_a; + double __pyx_v_b; + double __pyx_v_x0; + double __pyx_v_x1; + double __pyx_v_Len; + __pyx_t_double_complex __pyx_v_d0; + __pyx_t_double_complex __pyx_v_d1; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_n; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + double __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + double __pyx_t_6; + double __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticArcLengthC", 1); + + /* "fontTools/misc/bezierTools.py":218 + * # Analytical solution to the length of a quadratic bezier. + * # Documentation: https://github.com/fonttools/fonttools/issues/3055 + * d0 = pt2 - pt1 # <<<<<<<<<<<<<< + * d1 = pt3 - pt2 + * d = d1 - d0 + */ + __pyx_v_d0 = __Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1); + + /* "fontTools/misc/bezierTools.py":219 + * # Documentation: https://github.com/fonttools/fonttools/issues/3055 + * d0 = pt2 - pt1 + * d1 = pt3 - pt2 # <<<<<<<<<<<<<< + * d = d1 - d0 + * n = d * 1j + */ + __pyx_v_d1 = __Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt2); + + /* "fontTools/misc/bezierTools.py":220 + * d0 = pt2 - pt1 + * d1 = pt3 - pt2 + * d = d1 - d0 # <<<<<<<<<<<<<< + * n = d * 1j + * scale = abs(n) + */ + __pyx_v_d = __Pyx_c_diff_double(__pyx_v_d1, __pyx_v_d0); + + /* "fontTools/misc/bezierTools.py":221 + * d1 = pt3 - pt2 + * d = d1 - d0 + * n = d * 1j # <<<<<<<<<<<<<< + * scale = abs(n) + * if scale == 0.0: + */ + __pyx_v_n = __Pyx_c_prod_double(__pyx_v_d, __pyx_t_double_complex_from_parts(0, 1.0)); + + /* "fontTools/misc/bezierTools.py":222 + * d = d1 - d0 + * n = d * 1j + * scale = abs(n) # <<<<<<<<<<<<<< + * if scale == 0.0: + * return abs(pt3 - pt1) + */ + __pyx_v_scale = __Pyx_c_abs_double(__pyx_v_n); + + /* "fontTools/misc/bezierTools.py":223 + * n = d * 1j + * scale = abs(n) + * if scale == 0.0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + */ + __pyx_t_1 = (__pyx_v_scale == 0.0); + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":224 + * scale = abs(n) + * if scale == 0.0: + * return abs(pt3 - pt1) # <<<<<<<<<<<<<< + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyFloat_FromDouble(__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":223 + * n = d * 1j + * scale = abs(n) + * if scale == 0.0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + */ + } + + /* "fontTools/misc/bezierTools.py":225 + * if scale == 0.0: + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) # <<<<<<<<<<<<<< + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: + */ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_n, __pyx_v_d0); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 225, __pyx_L1_error) + __pyx_v_origDist = __pyx_t_3; + + /* "fontTools/misc/bezierTools.py":226 + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: # <<<<<<<<<<<<<< + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) + */ + __pyx_t_2 = PyFloat_FromDouble(fabs(__pyx_v_origDist)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":227 + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) + */ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d0, __pyx_v_d1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 227, __pyx_L1_error) + __pyx_t_1 = (__pyx_t_3 >= 0.0); + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":228 + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) # <<<<<<<<<<<<<< + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyFloat_FromDouble(__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":227 + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) + */ + } + + /* "fontTools/misc/bezierTools.py":229 + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) # <<<<<<<<<<<<<< + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist + */ + __pyx_t_3 = __Pyx_c_abs_double(__pyx_v_d0); + __pyx_t_6 = __Pyx_c_abs_double(__pyx_v_d1); + __pyx_v_a = __pyx_t_3; + __pyx_v_b = __pyx_t_6; + + /* "fontTools/misc/bezierTools.py":230 + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) # <<<<<<<<<<<<<< + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_6 = ((__pyx_v_a * __pyx_v_a) + (__pyx_v_b * __pyx_v_b)); + __pyx_t_3 = (__pyx_v_a + __pyx_v_b); + if (unlikely(__pyx_t_3 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 230, __pyx_L1_error) + } + __pyx_t_5 = PyFloat_FromDouble((__pyx_t_6 / __pyx_t_3)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":226 + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: # <<<<<<<<<<<<<< + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) + */ + } + + /* "fontTools/misc/bezierTools.py":231 + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist # <<<<<<<<<<<<<< + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + */ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d, __pyx_v_d0); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 231, __pyx_L1_error) + if (unlikely(__pyx_v_origDist == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 231, __pyx_L1_error) + } + __pyx_v_x0 = (__pyx_t_3 / __pyx_v_origDist); + + /* "fontTools/misc/bezierTools.py":232 + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist # <<<<<<<<<<<<<< + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + * return Len + */ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d, __pyx_v_d1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 232, __pyx_L1_error) + if (unlikely(__pyx_v_origDist == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 232, __pyx_L1_error) + } + __pyx_v_x1 = (__pyx_t_3 / __pyx_v_origDist); + + /* "fontTools/misc/bezierTools.py":233 + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) # <<<<<<<<<<<<<< + * return Len + * + */ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(__pyx_v_x1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 233, __pyx_L1_error) + __pyx_t_6 = __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(__pyx_v_x0); if (unlikely(__pyx_t_6 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 233, __pyx_L1_error) + __pyx_t_7 = ((2.0 * (__pyx_t_3 - __pyx_t_6)) * __pyx_v_origDist); + __pyx_t_6 = (__pyx_v_scale * (__pyx_v_x1 - __pyx_v_x0)); + if (unlikely(__pyx_t_6 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 233, __pyx_L1_error) + } + __pyx_v_Len = fabs((__pyx_t_7 / __pyx_t_6)); + + /* "fontTools/misc/bezierTools.py":234 + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + * return Len # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_Len); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength, "approximateQuadraticArcLength(pt1, pt2, pt3)\nCalculates the arc length for a quadratic Bezier segment.\n\n Uses Gauss-Legendre quadrature for a branch-free approximation.\n See :func:`calcQuadraticArcLength` for a slower but more accurate result.\n\n Args:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\n Returns:\n Approximate arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength = {"approximateQuadraticArcLength", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateQuadraticArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 237, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 237, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLength", 1, 3, 3, 1); __PYX_ERR(0, 237, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 237, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLength", 1, 3, 3, 2); __PYX_ERR(0, 237, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "approximateQuadraticArcLength") < 0)) __PYX_ERR(0, 237, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLength", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 237, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateQuadraticArcLength", 1); + + /* "fontTools/misc/bezierTools.py":251 + * Approximate arc length value. + * """ + * return approximateQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_approximateQuadraticArcLengthC); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 3+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC, "approximateQuadraticArcLengthC(double complex pt1, double complex pt2, double complex pt3)\nCalculates the arc length for a quadratic Bezier segment.\n\n Uses Gauss-Legendre quadrature for a branch-free approximation.\n See :func:`calcQuadraticArcLength` for a slower but more accurate result.\n\n Args:\n pt1: Start point of the Bezier as a complex number.\n pt2: Handle point of the Bezier as a complex number.\n pt3: End point of the Bezier as a complex number.\n\n Returns:\n Approximate arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC = {"approximateQuadraticArcLengthC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateQuadraticArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 254, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 254, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLengthC", 1, 3, 3, 1); __PYX_ERR(0, 254, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 254, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLengthC", 1, 3, 3, 2); __PYX_ERR(0, 254, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "approximateQuadraticArcLengthC") < 0)) __PYX_ERR(0, 254, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLengthC", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 254, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3) { + double __pyx_v_v0; + double __pyx_v_v1; + double __pyx_v_v2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateQuadraticArcLengthC", 1); + + /* "fontTools/misc/bezierTools.py":287 + * # abs(BezierCurveC[2].diff(t).subs({t:T})) for T in sorted(.5, .5sqrt(3/5)/2), + * # weighted 5/18, 8/18, 5/18 respectively. + * v0 = abs( # <<<<<<<<<<<<<< + * -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + * ) + */ + __pyx_v_v0 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.492943519233745, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.430331482911935, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.0626120363218102, 0), __pyx_v_pt3))); + + /* "fontTools/misc/bezierTools.py":290 + * -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + * ) + * v1 = abs(pt3 - pt1) * 0.4444444444444444 # <<<<<<<<<<<<<< + * v2 = abs( + * -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 + */ + __pyx_v_v1 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1)) * 0.4444444444444444); + + /* "fontTools/misc/bezierTools.py":291 + * ) + * v1 = abs(pt3 - pt1) * 0.4444444444444444 + * v2 = abs( # <<<<<<<<<<<<<< + * -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 + * ) + */ + __pyx_v_v2 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.0626120363218102, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.430331482911935, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.492943519233745, 0), __pyx_v_pt3))); + + /* "fontTools/misc/bezierTools.py":295 + * ) + * + * return v0 + v1 + v2 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyFloat_FromDouble(((__pyx_v_v0 + __pyx_v_v1) + __pyx_v_v2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_16calcQuadraticBounds, "calcQuadraticBounds(pt1, pt2, pt3)\nCalculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as a 2D tuple.\n pt2: Handle point of the Bezier as a 2D tuple.\n pt3: End point of the Bezier as a 2D tuple.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0))\n (0, 0, 100, 50.0)\n >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))\n (0.0, 0.0, 100, 100)\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_17calcQuadraticBounds = {"calcQuadraticBounds", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_16calcQuadraticBounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticBounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 298, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 298, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticBounds", 1, 3, 3, 1); __PYX_ERR(0, 298, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 298, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticBounds", 1, 3, 3, 2); __PYX_ERR(0, 298, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcQuadraticBounds") < 0)) __PYX_ERR(0, 298, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticBounds", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 298, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_ax2 = NULL; + PyObject *__pyx_v_ay2 = NULL; + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_points = NULL; + PyObject *__pyx_7genexpr__pyx_v_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + Py_ssize_t __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticBounds", 1); + + /* "fontTools/misc/bezierTools.py":316 + * (0.0, 0.0, 100, 100) + * """ + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcQuadraticParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < 0) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_6 = PyList_GET_ITEM(sequence, 0); + __pyx_t_8 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_8); + #else + __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + index = 1; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < 0) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ax = __pyx_t_6; + __pyx_t_6 = 0; + __pyx_v_ay = __pyx_t_8; + __pyx_t_8 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_8 = PyList_GET_ITEM(sequence, 0); + __pyx_t_6 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_6); + #else + __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + index = 1; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < 0) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_bx = __pyx_t_8; + __pyx_t_8 = 0; + __pyx_v_by = __pyx_t_6; + __pyx_t_6 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_6 = PyList_GET_ITEM(sequence, 0); + __pyx_t_8 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_8); + #else + __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + index = 1; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < 0) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_cx = __pyx_t_6; + __pyx_t_6 = 0; + __pyx_v_cy = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":317 + * """ + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + * ax2 = ax * 2.0 # <<<<<<<<<<<<<< + * ay2 = ay * 2.0 + * roots = [] + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 317, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":318 + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 # <<<<<<<<<<<<<< + * roots = [] + * if ax2 != 0: + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":319 + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 + * roots = [] # <<<<<<<<<<<<<< + * if ax2 != 0: + * roots.append(-bx / ax2) + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 319, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":320 + * ay2 = ay * 2.0 + * roots = [] + * if ax2 != 0: # <<<<<<<<<<<<<< + * roots.append(-bx / ax2) + * if ay2 != 0: + */ + __pyx_t_10 = (__Pyx_PyInt_BoolNeObjC(__pyx_v_ax2, __pyx_int_0, 0, 0)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 320, __pyx_L1_error) + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":321 + * roots = [] + * if ax2 != 0: + * roots.append(-bx / ax2) # <<<<<<<<<<<<<< + * if ay2 != 0: + * roots.append(-by / ay2) + */ + __pyx_t_1 = PyNumber_Negative(__pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_ax2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_roots, __pyx_t_5); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":320 + * ay2 = ay * 2.0 + * roots = [] + * if ax2 != 0: # <<<<<<<<<<<<<< + * roots.append(-bx / ax2) + * if ay2 != 0: + */ + } + + /* "fontTools/misc/bezierTools.py":322 + * if ax2 != 0: + * roots.append(-bx / ax2) + * if ay2 != 0: # <<<<<<<<<<<<<< + * roots.append(-by / ay2) + * points = [ + */ + __pyx_t_10 = (__Pyx_PyInt_BoolNeObjC(__pyx_v_ay2, __pyx_int_0, 0, 0)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 322, __pyx_L1_error) + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":323 + * roots.append(-bx / ax2) + * if ay2 != 0: + * roots.append(-by / ay2) # <<<<<<<<<<<<<< + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + */ + __pyx_t_5 = PyNumber_Negative(__pyx_v_by); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_5, __pyx_v_ay2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_roots, __pyx_t_1); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":322 + * if ax2 != 0: + * roots.append(-bx / ax2) + * if ay2 != 0: # <<<<<<<<<<<<<< + * roots.append(-by / ay2) + * points = [ + */ + } + + /* "fontTools/misc/bezierTools.py":328 + * for t in roots + * if 0 <= t < 1 + * ] + [pt1, pt3] # <<<<<<<<<<<<<< + * return calcBounds(points) + * + */ + { /* enter inner scope */ + + /* "fontTools/misc/bezierTools.py":324 + * if ay2 != 0: + * roots.append(-by / ay2) + * points = [ # <<<<<<<<<<<<<< + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 324, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":326 + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots # <<<<<<<<<<<<<< + * if 0 <= t < 1 + * ] + [pt1, pt3] + */ + __pyx_t_5 = __pyx_v_roots; __Pyx_INCREF(__pyx_t_5); + __pyx_t_12 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 326, __pyx_L15_error) + #endif + if (__pyx_t_12 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_12); __Pyx_INCREF(__pyx_t_3); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 326, __pyx_L15_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 326, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_t, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":327 + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots + * if 0 <= t < 1 # <<<<<<<<<<<<<< + * ] + [pt1, pt3] + * return calcBounds(points) + */ + __pyx_t_3 = PyObject_RichCompare(__pyx_int_0, __pyx_7genexpr__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 327, __pyx_L15_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_3)) { + __Pyx_DECREF(__pyx_t_3); + __pyx_t_3 = PyObject_RichCompare(__pyx_7genexpr__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 327, __pyx_L15_error) + } + __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 327, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":325 + * roots.append(-by / ay2) + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) # <<<<<<<<<<<<<< + * for t in roots + * if 0 <= t < 1 + */ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_ax, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v_bx, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_8, __pyx_v_cx); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Multiply(__pyx_v_ay, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_8, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Multiply(__pyx_v_by, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = PyNumber_Add(__pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Add(__pyx_t_6, __pyx_v_cy); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error); + __pyx_t_3 = 0; + __pyx_t_8 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 324, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":327 + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots + * if 0 <= t < 1 # <<<<<<<<<<<<<< + * ] + [pt1, pt3] + * return calcBounds(points) + */ + } + + /* "fontTools/misc/bezierTools.py":326 + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots # <<<<<<<<<<<<<< + * if 0 <= t < 1 + * ] + [pt1, pt3] + */ + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); __pyx_7genexpr__pyx_v_t = 0; + goto __pyx_L20_exit_scope; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); __pyx_7genexpr__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L20_exit_scope:; + } /* exit inner scope */ + + /* "fontTools/misc/bezierTools.py":328 + * for t in roots + * if 0 <= t < 1 + * ] + [pt1, pt3] # <<<<<<<<<<<<<< + * return calcBounds(points) + * + */ + __pyx_t_5 = PyList_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 328, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_v_pt1)) __PYX_ERR(0, 328, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 1, __pyx_v_pt3)) __PYX_ERR(0, 328, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 328, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_points = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":329 + * if 0 <= t < 1 + * ] + [pt1, pt3] + * return calcBounds(points) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_calcBounds); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_points}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_ax2); + __Pyx_XDECREF(__pyx_v_ay2); + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_points); + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_18approximateCubicArcLength, "approximateCubicArcLength(pt1, pt2, pt3, pt4)\nApproximates the arc length for a cubic Bezier segment.\n\n Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length.\n See :func:`calcCubicArcLength` for a slower but more accurate result.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0))\n 190.04332968932817\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100))\n 154.8852074945903\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150.\n 149.99999999999991\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150.\n 136.9267662156362\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp\n 154.80848416537057\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_19approximateCubicArcLength = {"approximateCubicArcLength", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_18approximateCubicArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateCubicArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 332, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 332, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, 1); __PYX_ERR(0, 332, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 332, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, 2); __PYX_ERR(0, 332, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 332, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, 3); __PYX_ERR(0, 332, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "approximateCubicArcLength") < 0)) __PYX_ERR(0, 332, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 332, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateCubicArcLength", 1); + + /* "fontTools/misc/bezierTools.py":357 + * 154.80848416537057 + * """ + * return approximateCubicArcLengthC( # <<<<<<<<<<<<<< + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) + * ) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_approximateCubicArcLengthC); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 357, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":358 + * """ + * return approximateCubicArcLengthC( + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_pt4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_8 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_8 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_8, 4+__pyx_t_8); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 357, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC, "approximateCubicArcLengthC(double complex pt1, double complex pt2, double complex pt3, double complex pt4)\nApproximates the arc length for a cubic Bezier segment.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n\n Returns:\n Arc length value.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC = {"approximateCubicArcLengthC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateCubicArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 362, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 362, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, 1); __PYX_ERR(0, 362, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 362, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, 2); __PYX_ERR(0, 362, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 362, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, 3); __PYX_ERR(0, 362, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "approximateCubicArcLengthC") < 0)) __PYX_ERR(0, 362, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 362, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4) { + double __pyx_v_v0; + double __pyx_v_v1; + double __pyx_v_v2; + double __pyx_v_v3; + double __pyx_v_v4; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateCubicArcLengthC", 1); + + /* "fontTools/misc/bezierTools.py":393 + * # abs(BezierCurveC[3].diff(t).subs({t:T})) for T in sorted(0, .5(3/7)**.5/2, .5, 1), + * # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + * v0 = abs(pt2 - pt1) * 0.15 # <<<<<<<<<<<<<< + * v1 = abs( + * -0.558983582205757 * pt1 + */ + __pyx_v_v0 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1)) * 0.15); + + /* "fontTools/misc/bezierTools.py":394 + * # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + * v0 = abs(pt2 - pt1) * 0.15 + * v1 = abs( # <<<<<<<<<<<<<< + * -0.558983582205757 * pt1 + * + 0.325650248872424 * pt2 + */ + __pyx_v_v1 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.558983582205757, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.325650248872424, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.208983582205757, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.024349751127576, 0), __pyx_v_pt4))); + + /* "fontTools/misc/bezierTools.py":400 + * + 0.024349751127576 * pt4 + * ) + * v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 # <<<<<<<<<<<<<< + * v3 = abs( + * -0.024349751127576 * pt1 + */ + __pyx_v_v2 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt1), __pyx_v_pt3), __pyx_v_pt2)) * 0.26666666666666666); + + /* "fontTools/misc/bezierTools.py":401 + * ) + * v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 + * v3 = abs( # <<<<<<<<<<<<<< + * -0.024349751127576 * pt1 + * - 0.208983582205757 * pt2 + */ + __pyx_v_v3 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.024349751127576, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.208983582205757, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.325650248872424, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.558983582205757, 0), __pyx_v_pt4))); + + /* "fontTools/misc/bezierTools.py":407 + * + 0.558983582205757 * pt4 + * ) + * v4 = abs(pt4 - pt3) * 0.15 # <<<<<<<<<<<<<< + * + * return v0 + v1 + v2 + v3 + v4 + */ + __pyx_v_v4 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt3)) * 0.15); + + /* "fontTools/misc/bezierTools.py":409 + * v4 = abs(pt4 - pt3) * 0.15 + * + * return v0 + v1 + v2 + v3 + v4 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyFloat_FromDouble(((((__pyx_v_v0 + __pyx_v_v1) + __pyx_v_v2) + __pyx_v_v3) + __pyx_v_v4)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_22calcCubicBounds, "calcCubicBounds(pt1, pt2, pt3, pt4)\nCalculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0))\n (0, 0, 100, 75.0)\n >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100))\n (0.0, 0.0, 100, 100)\n >>> print(\"%f %f %f %f\" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))\n 35.566243 0.000000 64.433757 75.000000\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_23calcCubicBounds = {"calcCubicBounds", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_22calcCubicBounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicBounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 412, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 412, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, 1); __PYX_ERR(0, 412, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 412, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, 2); __PYX_ERR(0, 412, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 412, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, 3); __PYX_ERR(0, 412, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcCubicBounds") < 0)) __PYX_ERR(0, 412, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 412, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_ax3 = NULL; + PyObject *__pyx_v_ay3 = NULL; + PyObject *__pyx_v_bx2 = NULL; + PyObject *__pyx_v_by2 = NULL; + PyObject *__pyx_v_xRoots = NULL; + PyObject *__pyx_v_yRoots = NULL; + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_points = NULL; + PyObject *__pyx_8genexpr1__pyx_v_t = NULL; + PyObject *__pyx_8genexpr2__pyx_v_t = NULL; + PyObject *__pyx_8genexpr3__pyx_v_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + Py_ssize_t __pyx_t_11; + PyObject *(*__pyx_t_12)(PyObject *); + int __pyx_t_13; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicBounds", 1); + + /* "fontTools/misc/bezierTools.py":430 + * 35.566243 0.000000 64.433757 75.000000 + * """ + * (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * # calc first derivative + * ax3 = ax * 3.0 + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 4+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + __pyx_t_6 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < 0) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_7 = PyList_GET_ITEM(sequence, 0); + __pyx_t_9 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_9); + #else + __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 1; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < 0) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ax = __pyx_t_7; + __pyx_t_7 = 0; + __pyx_v_ay = __pyx_t_9; + __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_9 = PyList_GET_ITEM(sequence, 0); + __pyx_t_7 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_7); + #else + __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < 0) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_bx = __pyx_t_9; + __pyx_t_9 = 0; + __pyx_v_by = __pyx_t_7; + __pyx_t_7 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_7 = PyList_GET_ITEM(sequence, 0); + __pyx_t_9 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_9); + #else + __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 1; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < 0) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_cx = __pyx_t_7; + __pyx_t_7 = 0; + __pyx_v_cy = __pyx_t_9; + __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_6))) || (PyList_CheckExact(__pyx_t_6))) { + PyObject* sequence = __pyx_t_6; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_9 = PyList_GET_ITEM(sequence, 0); + __pyx_t_7 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_7); + #else + __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < 0) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __pyx_v_dx = __pyx_t_9; + __pyx_t_9 = 0; + __pyx_v_dy = __pyx_t_7; + __pyx_t_7 = 0; + + /* "fontTools/misc/bezierTools.py":432 + * (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) + * # calc first derivative + * ax3 = ax * 3.0 # <<<<<<<<<<<<<< + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":433 + * # calc first derivative + * ax3 = ax * 3.0 + * ay3 = ay * 3.0 # <<<<<<<<<<<<<< + * bx2 = bx * 2.0 + * by2 = by * 2.0 + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 433, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":434 + * ax3 = ax * 3.0 + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 # <<<<<<<<<<<<<< + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_bx, __pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_bx2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":435 + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 + * by2 = by * 2.0 # <<<<<<<<<<<<<< + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_by, __pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_by2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":436 + * bx2 = bx * 2.0 + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] # <<<<<<<<<<<<<< + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + * roots = xRoots + yRoots + */ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_solveQuadratic); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_ax3, __pyx_v_bx2, __pyx_v_cx}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + if (likely(PyList_CheckExact(__pyx_t_6)) || PyTuple_CheckExact(__pyx_t_6)) { + __pyx_t_5 = __pyx_t_6; __Pyx_INCREF(__pyx_t_5); + __pyx_t_11 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_11 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_12 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 436, __pyx_L15_error) + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_5))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_11); __Pyx_INCREF(__pyx_t_6); __pyx_t_11++; if (unlikely((0 < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_11); __Pyx_INCREF(__pyx_t_6); __pyx_t_11++; if (unlikely((0 < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } + } else { + __pyx_t_6 = __pyx_t_12(__pyx_t_5); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 436, __pyx_L15_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_t, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = PyObject_RichCompare(__pyx_int_0, __pyx_8genexpr1__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_6)) { + __Pyx_DECREF(__pyx_t_6); + __pyx_t_6 = PyObject_RichCompare(__pyx_8genexpr1__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + } + __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_13 < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_13) { + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_8genexpr1__pyx_v_t))) __PYX_ERR(0, 436, __pyx_L15_error) + } + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); __pyx_8genexpr1__pyx_v_t = 0; + goto __pyx_L20_exit_scope; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); __pyx_8genexpr1__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L20_exit_scope:; + } /* exit inner scope */ + __pyx_v_xRoots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":437 + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] # <<<<<<<<<<<<<< + * roots = xRoots + yRoots + * + */ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_solveQuadratic); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_ay3, __pyx_v_by2, __pyx_v_cy}; + __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) { + __pyx_t_6 = __pyx_t_5; __Pyx_INCREF(__pyx_t_6); + __pyx_t_11 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_11 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_12 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 437, __pyx_L23_error) + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_11); __Pyx_INCREF(__pyx_t_5); __pyx_t_11++; if (unlikely((0 < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_11); __Pyx_INCREF(__pyx_t_5); __pyx_t_11++; if (unlikely((0 < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } + } else { + __pyx_t_5 = __pyx_t_12(__pyx_t_6); + if (unlikely(!__pyx_t_5)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 437, __pyx_L23_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_5); + } + __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_t, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = PyObject_RichCompare(__pyx_int_0, __pyx_8genexpr2__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_5)) { + __Pyx_DECREF(__pyx_t_5); + __pyx_t_5 = PyObject_RichCompare(__pyx_8genexpr2__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + } + __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_13 < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__pyx_t_13) { + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_8genexpr2__pyx_v_t))) __PYX_ERR(0, 437, __pyx_L23_error) + } + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); __pyx_8genexpr2__pyx_v_t = 0; + goto __pyx_L28_exit_scope; + __pyx_L23_error:; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); __pyx_8genexpr2__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L28_exit_scope:; + } /* exit inner scope */ + __pyx_v_yRoots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":438 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + * roots = xRoots + yRoots # <<<<<<<<<<<<<< + * + * points = [ + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_xRoots, __pyx_v_yRoots); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 438, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":446 + * ) + * for t in roots + * ] + [pt1, pt4] # <<<<<<<<<<<<<< + * return calcBounds(points) + * + */ + { /* enter inner scope */ + + /* "fontTools/misc/bezierTools.py":440 + * roots = xRoots + yRoots + * + * points = [ # <<<<<<<<<<<<<< + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 440, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":445 + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + * for t in roots # <<<<<<<<<<<<<< + * ] + [pt1, pt4] + * return calcBounds(points) + */ + __pyx_t_6 = __pyx_v_roots; __Pyx_INCREF(__pyx_t_6); + __pyx_t_11 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 445, __pyx_L31_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_11); __Pyx_INCREF(__pyx_t_5); __pyx_t_11++; if (unlikely((0 < 0))) __PYX_ERR(0, 445, __pyx_L31_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 445, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_XDECREF_SET(__pyx_8genexpr3__pyx_v_t, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":442 + * points = [ + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, # <<<<<<<<<<<<<< + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + */ + __pyx_t_5 = PyNumber_Multiply(__pyx_v_ax, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_5, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyNumber_Multiply(__pyx_t_3, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v_bx, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_cx, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_5, __pyx_v_dx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":443 + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, + * ay * t * t * t + by * t * t + cy * t + dy, # <<<<<<<<<<<<<< + * ) + * for t in roots + */ + __pyx_t_5 = PyNumber_Multiply(__pyx_v_ay, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_5, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyNumber_Multiply(__pyx_t_3, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v_by, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = PyNumber_Multiply(__pyx_t_3, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyNumber_Multiply(__pyx_v_cy, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_v_dy); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":442 + * points = [ + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, # <<<<<<<<<<<<<< + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + */ + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_7)) __PYX_ERR(0, 442, __pyx_L31_error); + __pyx_t_2 = 0; + __pyx_t_7 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 440, __pyx_L31_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":445 + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + * for t in roots # <<<<<<<<<<<<<< + * ] + [pt1, pt4] + * return calcBounds(points) + */ + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); __pyx_8genexpr3__pyx_v_t = 0; + goto __pyx_L35_exit_scope; + __pyx_L31_error:; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); __pyx_8genexpr3__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L35_exit_scope:; + } /* exit inner scope */ + + /* "fontTools/misc/bezierTools.py":446 + * ) + * for t in roots + * ] + [pt1, pt4] # <<<<<<<<<<<<<< + * return calcBounds(points) + * + */ + __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 446, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_pt1)) __PYX_ERR(0, 446, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 1, __pyx_v_pt4)) __PYX_ERR(0, 446, __pyx_L1_error); + __pyx_t_5 = PyNumber_Add(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 446, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_points = ((PyObject*)__pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":447 + * for t in roots + * ] + [pt1, pt4] + * return calcBounds(points) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_calcBounds); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 447, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_points}; + __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 447, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_ax3); + __Pyx_XDECREF(__pyx_v_ay3); + __Pyx_XDECREF(__pyx_v_bx2); + __Pyx_XDECREF(__pyx_v_by2); + __Pyx_XDECREF(__pyx_v_xRoots); + __Pyx_XDECREF(__pyx_v_yRoots); + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_points); + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_24splitLine, "splitLine(pt1, pt2, where, isHorizontal)\nSplit a line at a given coordinate.\n\n Args:\n pt1: Start point of line as 2D tuple.\n pt2: End point of line as 2D tuple.\n where: Position at which to split the line.\n isHorizontal: Direction of the ray splitting the line. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two line segments (each line segment being two 2D tuples)\n if the line was successfully split, or a list containing the original\n line.\n\n Example::\n\n >>> printSegments(splitLine((0, 0), (100, 100), 50, True))\n ((0, 0), (50, 50))\n ((50, 50), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 100, True))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, True))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, False))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((100, 0), (0, 0), 50, False))\n ((100, 0), (50, 0))\n ((50, 0), (0, 0))\n >>> printSegments(splitLine((0, 100), (0, 0), 50, True))\n ((0, 100), (0, 50))\n ((0, 50), (0, 0))\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_25splitLine = {"splitLine", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_24splitLine}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitLine (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_where,&__pyx_n_s_isHorizontal,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, 1); __PYX_ERR(0, 450, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_where)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, 2); __PYX_ERR(0, 450, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_isHorizontal)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, 3); __PYX_ERR(0, 450, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "splitLine") < 0)) __PYX_ERR(0, 450, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_where = values[2]; + __pyx_v_isHorizontal = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 450, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitLine", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_pt1x = NULL; + PyObject *__pyx_v_pt1y = NULL; + PyObject *__pyx_v_pt2x = NULL; + PyObject *__pyx_v_pt2y = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_t = NULL; + PyObject *__pyx_v_midPt = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitLine", 1); + + /* "fontTools/misc/bezierTools.py":486 + * ((0, 50), (0, 0)) + * """ + * pt1x, pt1y = pt1 # <<<<<<<<<<<<<< + * pt2x, pt2y = pt2 + * + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 486, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 486, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 486, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_pt1x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_pt1y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":487 + * """ + * pt1x, pt1y = pt1 + * pt2x, pt2y = pt2 # <<<<<<<<<<<<<< + * + * ax = pt2x - pt1x + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 487, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 487, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 487, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_pt2x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_pt2y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":489 + * pt2x, pt2y = pt2 + * + * ax = pt2x - pt1x # <<<<<<<<<<<<<< + * ay = pt2y - pt1y + * + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_pt2x, __pyx_v_pt1x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 489, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":490 + * + * ax = pt2x - pt1x + * ay = pt2y - pt1y # <<<<<<<<<<<<<< + * + * bx = pt1x + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_pt2y, __pyx_v_pt1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":492 + * ay = pt2y - pt1y + * + * bx = pt1x # <<<<<<<<<<<<<< + * by = pt1y + * + */ + __Pyx_INCREF(__pyx_v_pt1x); + __pyx_v_bx = __pyx_v_pt1x; + + /* "fontTools/misc/bezierTools.py":493 + * + * bx = pt1x + * by = pt1y # <<<<<<<<<<<<<< + * + * a = (ax, ay)[isHorizontal] + */ + __Pyx_INCREF(__pyx_v_pt1y); + __pyx_v_by = __pyx_v_pt1y; + + /* "fontTools/misc/bezierTools.py":495 + * by = pt1y + * + * a = (ax, ay)[isHorizontal] # <<<<<<<<<<<<<< + * + * if a == 0: + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ax)) __PYX_ERR(0, 495, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ay)) __PYX_ERR(0, 495, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 495, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":497 + * a = (ax, ay)[isHorizontal] + * + * if a == 0: # <<<<<<<<<<<<<< + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + */ + __pyx_t_5 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_a, __pyx_int_0, 0, 0)); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 497, __pyx_L1_error) + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":498 + * + * if a == 0: + * return [(pt1, pt2)] # <<<<<<<<<<<<<< + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 498, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pt1)) __PYX_ERR(0, 498, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_pt2)) __PYX_ERR(0, 498, __pyx_L1_error); + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 498, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2)) __PYX_ERR(0, 498, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":497 + * a = (ax, ay)[isHorizontal] + * + * if a == 0: # <<<<<<<<<<<<<< + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + */ + } + + /* "fontTools/misc/bezierTools.py":499 + * if a == 0: + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a # <<<<<<<<<<<<<< + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_bx)) __PYX_ERR(0, 499, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_by)) __PYX_ERR(0, 499, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_v_where, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_a); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_t = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":500 + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: # <<<<<<<<<<<<<< + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] + */ + __pyx_t_2 = PyObject_RichCompare(__pyx_int_0, __pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 500, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_2)) { + __Pyx_DECREF(__pyx_t_2); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 500, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 500, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":501 + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by # <<<<<<<<<<<<<< + * return [(pt1, midPt), (midPt, pt2)] + * else: + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 501, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3)) __PYX_ERR(0, 501, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_v_midPt = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":502 + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] # <<<<<<<<<<<<<< + * else: + * return [(pt1, pt2)] + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pt1)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_midPt); + __Pyx_GIVEREF(__pyx_v_midPt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_midPt)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_midPt); + __Pyx_GIVEREF(__pyx_v_midPt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_midPt)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_pt2)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":500 + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: # <<<<<<<<<<<<<< + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] + */ + } + + /* "fontTools/misc/bezierTools.py":504 + * return [(pt1, midPt), (midPt, pt2)] + * else: + * return [(pt1, pt2)] # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_pt1)) __PYX_ERR(0, 504, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_pt2)) __PYX_ERR(0, 504, __pyx_L1_error); + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 504, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitLine", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_pt1x); + __Pyx_XDECREF(__pyx_v_pt1y); + __Pyx_XDECREF(__pyx_v_pt2x); + __Pyx_XDECREF(__pyx_v_pt2y); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_XDECREF(__pyx_v_midPt); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_26splitQuadratic, "splitQuadratic(pt1, pt2, pt3, where, isHorizontal)\nSplit a quadratic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being three 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False))\n ((0, 0), (50, 100), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False))\n ((0, 0), (12.5, 25), (25, 37.5))\n ((25, 37.5), (62.5, 75), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True))\n ((0, 0), (7.32233, 14.6447), (14.6447, 25))\n ((14.6447, 25), (50, 75), (85.3553, 25))\n ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15))\n >>> # XXX I'm not at all sure if the following behavior is desirable:\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (50, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_27splitQuadratic = {"splitQuadratic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_26splitQuadratic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitQuadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_where,&__pyx_n_s_isHorizontal,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 507, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 507, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, 1); __PYX_ERR(0, 507, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 507, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, 2); __PYX_ERR(0, 507, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_where)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 507, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, 3); __PYX_ERR(0, 507, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_isHorizontal)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 507, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, 4); __PYX_ERR(0, 507, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "splitQuadratic") < 0)) __PYX_ERR(0, 507, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_where = values[3]; + __pyx_v_isHorizontal = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 507, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 546, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_splitQuadratic_locals_genexpr, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 546, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 546, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 546, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 546, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_t); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_t, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_int_0, __pyx_cur_scope->__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_t))) __PYX_ERR(0, 546, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_solutions = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitQuadratic", 1); + + /* "fontTools/misc/bezierTools.py":542 + * ((50, 50), (75, 50), (100, 0)) + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * solutions = solveQuadratic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcQuadraticParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 542, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < 0) __PYX_ERR(0, 542, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 542, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_b = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":543 + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * solutions = solveQuadratic( # <<<<<<<<<<<<<< + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_solveQuadratic); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "fontTools/misc/bezierTools.py":544 + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * solutions = solveQuadratic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where # <<<<<<<<<<<<<< + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + */ + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_a, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_b, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_v_c, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = PyNumber_Subtract(__pyx_t_6, __pyx_v_where); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_6, __pyx_t_3, __pyx_t_2, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_v_solutions = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] + */ + __pyx_t_5 = __pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(NULL, __pyx_v_solutions); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_8 = __Pyx_Generator_Next(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_1 = ((PyObject*)__pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_9 = PyList_Sort(__pyx_t_1); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF_SET(__pyx_v_solutions, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":547 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) + */ + __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_solutions); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 547, __pyx_L1_error) + __pyx_t_11 = (!__pyx_t_10); + if (__pyx_t_11) { + + /* "fontTools/misc/bezierTools.py":548 + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: + * return [(pt1, pt2, pt3)] # <<<<<<<<<<<<<< + * return _splitQuadraticAtT(a, b, c, *solutions) + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_pt1)) __PYX_ERR(0, 548, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_pt2)) __PYX_ERR(0, 548, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_pt3)) __PYX_ERR(0, 548, __pyx_L1_error); + __pyx_t_8 = PyList_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 548, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":547 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) + */ + } + + /* "fontTools/misc/bezierTools.py":549 + * if not solutions: + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_splitQuadraticAtT); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_a)) __PYX_ERR(0, 549, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_b)) __PYX_ERR(0, 549, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_c)) __PYX_ERR(0, 549, __pyx_L1_error); + __pyx_t_5 = __Pyx_PySequence_Tuple(__pyx_v_solutions); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_2, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_solutions); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_28splitCubic, "splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal)\nSplit a cubic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being four 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False))\n ((0, 0), (25, 100), (75, 100), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True))\n ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25))\n ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25))\n ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15))\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_29splitCubic = {"splitCubic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_28splitCubic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[6] = {0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_where,&__pyx_n_s_isHorizontal,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, 1); __PYX_ERR(0, 552, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, 2); __PYX_ERR(0, 552, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, 3); __PYX_ERR(0, 552, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_where)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, 4); __PYX_ERR(0, 552, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_isHorizontal)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, 5); __PYX_ERR(0, 552, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "splitCubic") < 0)) __PYX_ERR(0, 552, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 6)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_where = values[4]; + __pyx_v_isHorizontal = values[5]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, __pyx_nargs); __PYX_ERR(0, 552, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 583, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_splitCubic_locals_genexpr, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 583, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 583, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 583, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 583, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_t); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_t, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_int_0, __pyx_cur_scope->__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_t, __pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_t))) __PYX_ERR(0, 583, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_v_solutions = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubic", 1); + + /* "fontTools/misc/bezierTools.py":579 + * ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15)) + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * solutions = solveCubic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 4+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 579, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + __pyx_t_6 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < 0) __PYX_ERR(0, 579, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 579, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_b = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + __pyx_v_d = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":580 + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * solutions = solveCubic( # <<<<<<<<<<<<<< + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_solveCubic); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 580, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "fontTools/misc/bezierTools.py":581 + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * solutions = solveCubic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where # <<<<<<<<<<<<<< + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + */ + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_a, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_b, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_c, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyObject_GetItem(__pyx_v_d, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = PyNumber_Subtract(__pyx_t_7, __pyx_v_where); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_7, __pyx_t_5, __pyx_t_3, __pyx_t_2, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_4, 4+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 580, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __pyx_v_solutions = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] + */ + __pyx_t_6 = __pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(NULL, __pyx_v_solutions); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 = __Pyx_Generator_Next(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_1 = ((PyObject*)__pyx_t_9); + __pyx_t_9 = 0; + __pyx_t_10 = PyList_Sort(__pyx_t_1); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF_SET(__pyx_v_solutions, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":584 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) + */ + __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_solutions); if (unlikely((__pyx_t_11 < 0))) __PYX_ERR(0, 584, __pyx_L1_error) + __pyx_t_12 = (!__pyx_t_11); + if (__pyx_t_12) { + + /* "fontTools/misc/bezierTools.py":585 + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] # <<<<<<<<<<<<<< + * return _splitCubicAtT(a, b, c, d, *solutions) + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_pt1)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_pt2)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_pt3)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_pt4)) __PYX_ERR(0, 585, __pyx_L1_error); + __pyx_t_9 = PyList_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 585, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_9, 0, __pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_9; + __pyx_t_9 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":584 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) + */ + } + + /* "fontTools/misc/bezierTools.py":586 + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_splitCubicAtT); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_a)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_b)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_c)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d); + __Pyx_GIVEREF(__pyx_v_d); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_d)) __PYX_ERR(0, 586, __pyx_L1_error); + __pyx_t_6 = __Pyx_PySequence_Tuple(__pyx_v_solutions); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XDECREF(__pyx_v_solutions); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_30splitQuadraticAtT, "splitQuadraticAtT(pt1, pt2, pt3, *ts)\nSplit a quadratic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being three 2D tuples).\n\n Examples::\n\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (62.5, 50), (75, 37.5))\n ((75, 37.5), (87.5, 25), (100, 0))\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_31splitQuadraticAtT = {"splitQuadraticAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_30splitQuadraticAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitQuadraticAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 3, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 589, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 589, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadraticAtT", 0, 3, 3, 1); __PYX_ERR(0, 589, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 589, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitQuadraticAtT", 0, 3, 3, 2); __PYX_ERR(0, 589, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 3) ? kwd_pos_args : 3; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "splitQuadraticAtT") < 0)) __PYX_ERR(0, 589, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitQuadraticAtT", 0, 3, 3, __pyx_nargs); __PYX_ERR(0, 589, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitQuadraticAtT", 1); + + /* "fontTools/misc/bezierTools.py":609 + * ((75, 37.5), (87.5, 25), (100, 0)) + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * return _splitQuadraticAtT(a, b, c, *ts) + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcQuadraticParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 3+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 609, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < 0) __PYX_ERR(0, 609, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 609, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_b = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":610 + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * return _splitQuadraticAtT(a, b, c, *ts) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_splitQuadraticAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_a)) __PYX_ERR(0, 610, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_b)) __PYX_ERR(0, 610, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_c)) __PYX_ERR(0, 610, __pyx_L1_error); + __pyx_t_3 = PyNumber_Add(__pyx_t_5, __pyx_v_ts); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_32splitCubicAtT, "splitCubicAtT(pt1, pt2, pt3, pt4, *ts)\nSplit a cubic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being four 2D tuples).\n\n Examples::\n\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25))\n ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0))\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_33splitCubicAtT = {"splitCubicAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_32splitCubicAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 613, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 613, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, 1); __PYX_ERR(0, 613, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 613, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, 2); __PYX_ERR(0, 613, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 613, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, 3); __PYX_ERR(0, 613, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "splitCubicAtT") < 0)) __PYX_ERR(0, 613, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 613, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicAtT", 1); + + /* "fontTools/misc/bezierTools.py":633 + * ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0)) + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * return _splitCubicAtT(a, b, c, d, *ts) + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 4+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 633, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_5 = PyList_GET_ITEM(sequence, 2); + __pyx_t_6 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < 0) __PYX_ERR(0, 633, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 633, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_b = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + __pyx_v_d = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":634 + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * return _splitCubicAtT(a, b, c, d, *ts) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_splitCubicAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_a)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_b)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_c)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d); + __Pyx_GIVEREF(__pyx_v_d); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_v_d)) __PYX_ERR(0, 634, __pyx_L1_error); + __pyx_t_5 = PyNumber_Add(__pyx_t_6, __pyx_v_ts); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_36generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":637 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_34splitCubicAtTC, "splitCubicAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, *ts)\nSplit a cubic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers..\n *ts: Positions at which to split the curve.\n\n Yields:\n Curve segments (each curve segment being four complex numbers).\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_35splitCubicAtTC = {"splitCubicAtTC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_34splitCubicAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 637, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 637, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, 1); __PYX_ERR(0, 637, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 637, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, 2); __PYX_ERR(0, 637, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 637, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, 3); __PYX_ERR(0, 637, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "splitCubicAtTC") < 0)) __PYX_ERR(0, 637, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 647, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 647, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 647, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 647, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 637, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_CLEAR(__pyx_v_ts); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicAtTC", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 637, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_pt1 = __pyx_v_pt1; + __pyx_cur_scope->__pyx_v_pt2 = __pyx_v_pt2; + __pyx_cur_scope->__pyx_v_pt3 = __pyx_v_pt3; + __pyx_cur_scope->__pyx_v_pt4 = __pyx_v_pt4; + __pyx_cur_scope->__pyx_v_ts = __pyx_v_ts; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_ts); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_36generator, __pyx_codeobj_, (PyObject *) __pyx_cur_scope, __pyx_n_s_splitCubicAtTC, __pyx_n_s_splitCubicAtTC, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 637, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_36generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + __pyx_t_double_complex __pyx_t_8; + __pyx_t_double_complex __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + __pyx_t_double_complex __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtTC", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L6_resume_from_yield_from; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 637, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":657 + * Curve segments (each curve segment being four complex numbers). + * """ + * a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * yield from _splitCubicAtTC(a, b, c, d, *ts) + * + */ + __pyx_t_1 = __pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_cur_scope->__pyx_v_pt1, __pyx_cur_scope->__pyx_v_pt2, __pyx_cur_scope->__pyx_v_pt3, __pyx_cur_scope->__pyx_v_pt4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 657, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + __pyx_t_4 = PyList_GET_ITEM(sequence, 2); + __pyx_t_5 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_7(__pyx_t_6); if (unlikely(!item)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 4) < 0) __PYX_ERR(0, 657, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 657, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_11 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 657, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_cur_scope->__pyx_v_a = __pyx_t_8; + __pyx_cur_scope->__pyx_v_b = __pyx_t_9; + __pyx_cur_scope->__pyx_v_c = __pyx_t_10; + __pyx_cur_scope->__pyx_v_d = __pyx_t_11; + + /* "fontTools/misc/bezierTools.py":658 + * """ + * a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) + * yield from _splitCubicAtTC(a, b, c, d, *ts) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_splitCubicAtTC_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_a); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_d); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5)) __PYX_ERR(0, 658, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4)) __PYX_ERR(0, 658, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3)) __PYX_ERR(0, 658, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2)) __PYX_ERR(0, 658, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_6, __pyx_cur_scope->__pyx_v_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 658, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __Pyx_Generator_Yield_From(__pyx_generator, __pyx_t_6); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XGOTREF(__pyx_r); + if (likely(__pyx_r)) { + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L6_resume_from_yield_from:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 658, __pyx_L1_error) + } else { + PyObject* exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (exc_type) { + if (likely(exc_type == PyExc_StopIteration || (exc_type != PyExc_GeneratorExit && __Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))) PyErr_Clear(); + else __PYX_ERR(0, 658, __pyx_L1_error) + } + } + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* "fontTools/misc/bezierTools.py":637 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, + */ + + /* function exit code */ + PyErr_SetNone(PyExc_StopIteration); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":661 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC, "splitCubicIntoTwoAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double t)\nSplit a cubic Bezier curve at t.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n t: Position at which to split the curve.\n\n Returns:\n A tuple of two curve segments (each curve segment being four complex numbers).\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC = {"splitCubicIntoTwoAtTC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_t; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicIntoTwoAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 661, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 661, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, 1); __PYX_ERR(0, 661, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 661, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, 2); __PYX_ERR(0, 661, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 661, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, 3); __PYX_ERR(0, 661, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 661, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, 4); __PYX_ERR(0, 661, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "splitCubicIntoTwoAtTC") < 0)) __PYX_ERR(0, 661, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L3_error) + __pyx_v_t = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_t == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 661, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicIntoTwoAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t) { + double __pyx_v_t2; + double __pyx_v__1_t; + double __pyx_v__1_t_2; + double __pyx_v__2_t_1_t; + __pyx_t_double_complex __pyx_v_pointAtT; + __pyx_t_double_complex __pyx_v_off1; + __pyx_t_double_complex __pyx_v_off2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicIntoTwoAtTC", 1); + + /* "fontTools/misc/bezierTools.py":685 + * A tuple of two curve segments (each curve segment being four complex numbers). + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + */ + __pyx_v_t2 = (__pyx_v_t * __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":686 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * _2_t_1_t = 2 * t * _1_t + */ + __pyx_v__1_t = (1.0 - __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":687 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * _2_t_1_t = 2 * t * _1_t + * pointAtT = ( + */ + __pyx_v__1_t_2 = (__pyx_v__1_t * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":688 + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + * _2_t_1_t = 2 * t * _1_t # <<<<<<<<<<<<<< + * pointAtT = ( + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + */ + __pyx_v__2_t_1_t = ((2.0 * __pyx_v_t) * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":690 + * _2_t_1_t = 2 * t * _1_t + * pointAtT = ( + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 # <<<<<<<<<<<<<< + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 + */ + __pyx_v_pointAtT = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v__1_t), 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v_t), 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t * __pyx_v_t2), 0), __pyx_v_pt3)))), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v_t2 * __pyx_v_t), 0), __pyx_v_pt4)); + + /* "fontTools/misc/bezierTools.py":692 + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 # <<<<<<<<<<<<<< + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + * + */ + __pyx_v_off1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__1_t_2, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__2_t_1_t, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v_t2, 0), __pyx_v_pt3)); + + /* "fontTools/misc/bezierTools.py":693 + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 # <<<<<<<<<<<<<< + * + * pt2 = pt1 + (pt2 - pt1) * t + */ + __pyx_v_off2 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__1_t_2, 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__2_t_1_t, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v_t2, 0), __pyx_v_pt4)); + + /* "fontTools/misc/bezierTools.py":695 + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + * + * pt2 = pt1 + (pt2 - pt1) * t # <<<<<<<<<<<<<< + * pt3 = pt4 + (pt3 - pt4) * _1_t + * + */ + __pyx_v_pt2 = __Pyx_c_sum_double(__pyx_v_pt1, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1), __pyx_t_double_complex_from_parts(__pyx_v_t, 0))); + + /* "fontTools/misc/bezierTools.py":696 + * + * pt2 = pt1 + (pt2 - pt1) * t + * pt3 = pt4 + (pt3 - pt4) * _1_t # <<<<<<<<<<<<<< + * + * return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) + */ + __pyx_v_pt3 = __Pyx_c_sum_double(__pyx_v_pt4, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt4), __pyx_t_double_complex_from_parts(__pyx_v__1_t, 0))); + + /* "fontTools/misc/bezierTools.py":698 + * pt3 = pt4 + (pt3 - pt4) * _1_t + * + * return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_pt2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_off1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pointAtT); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4)) __PYX_ERR(0, 698, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pointAtT); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_off2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_pt3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_pt4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_3)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5)) __PYX_ERR(0, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6)) __PYX_ERR(0, 698, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":661 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicIntoTwoAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":701 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT, "_splitQuadraticAtT(a, b, c, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT = {"_splitQuadraticAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitQuadraticAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 3, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 701, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 701, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitQuadraticAtT", 0, 3, 3, 1); __PYX_ERR(0, 701, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 701, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitQuadraticAtT", 0, 3, 3, 2); __PYX_ERR(0, 701, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 3) ? kwd_pos_args : 3; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "_splitQuadraticAtT") < 0)) __PYX_ERR(0, 701, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitQuadraticAtT", 0, 3, 3, __pyx_nargs); __PYX_ERR(0, 701, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_segments = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_i = NULL; + PyObject *__pyx_v_t1 = NULL; + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v_delta = NULL; + PyObject *__pyx_v_delta_2 = NULL; + PyObject *__pyx_v_a1x = NULL; + PyObject *__pyx_v_a1y = NULL; + PyObject *__pyx_v_b1x = NULL; + PyObject *__pyx_v_b1y = NULL; + PyObject *__pyx_v_t1_2 = NULL; + PyObject *__pyx_v_c1x = NULL; + PyObject *__pyx_v_c1y = NULL; + PyObject *__pyx_v_pt1 = NULL; + PyObject *__pyx_v_pt2 = NULL; + PyObject *__pyx_v_pt3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *(*__pyx_t_5)(PyObject *); + Py_ssize_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitQuadraticAtT", 0); + __Pyx_INCREF(__pyx_v_ts); + + /* "fontTools/misc/bezierTools.py":702 + * + * def _splitQuadraticAtT(a, b, c, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * segments = [] + * ts.insert(0, 0.0) + */ + __pyx_t_1 = PySequence_List(__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 702, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_ts, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":703 + * def _splitQuadraticAtT(a, b, c, *ts): + * ts = list(ts) + * segments = [] # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_segments = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":704 + * ts = list(ts) + * segments = [] + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * ax, ay = a + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_ts, __pyx_n_s_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 704, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":705 + * segments = [] + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_v_ts, __pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 705, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":706 + * ts.insert(0, 0.0) + * ts.append(1.0) + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c + */ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 706, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 706, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 706, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 706, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 706, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 706, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":707 + * ts.append(1.0) + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * for i in range(len(ts) - 1): + */ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 707, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 707, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 707, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 707, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 707, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 707, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":708 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] + */ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 708, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 708, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 708, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 708, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 708, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":709 + * bx, by = b + * cx, cy = c + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + __pyx_t_6 = PyObject_Length(__pyx_v_ts); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 709, __pyx_L1_error) + __pyx_t_1 = PyInt_FromSsize_t((__pyx_t_6 - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) { + __pyx_t_1 = __pyx_t_2; __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 709, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 709, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 709, __pyx_L1_error) + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 709, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 709, __pyx_L1_error) + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } + } else { + __pyx_t_2 = __pyx_t_7(__pyx_t_1); + if (unlikely(!__pyx_t_2)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 709, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":710 + * cx, cy = c + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 + */ + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 710, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_t1, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":711 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * # calc new a, b and c + */ + __pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 711, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 711, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_t2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":712 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * # calc new a, b and c + * delta_2 = delta * delta + */ + __pyx_t_4 = PyNumber_Subtract(__pyx_v_t2, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_delta, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":714 + * delta = t2 - t1 + * # calc new a, b and c + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * a1x = ax * delta_2 + * a1y = ay * delta_2 + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_delta_2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":715 + * # calc new a, b and c + * delta_2 = delta * delta + * a1x = ax * delta_2 # <<<<<<<<<<<<<< + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_delta_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_a1x, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":716 + * delta_2 = delta * delta + * a1x = ax * delta_2 + * a1y = ay * delta_2 # <<<<<<<<<<<<<< + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_delta_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_a1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":717 + * a1x = ax * delta_2 + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta # <<<<<<<<<<<<<< + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 + */ + __pyx_t_4 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_v_ax, 2, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 717, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 717, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 717, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_v_delta); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 717, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1x, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":718 + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx + */ + __pyx_t_2 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_v_ay, 2, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_v_by); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_v_delta); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":719 + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * c1x = ax * t1_2 + bx * t1 + cx + * c1y = ay * t1_2 + by * t1 + cy + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 719, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t1_2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":720 + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx # <<<<<<<<<<<<<< + * c1y = ay * t1_2 + by * t1 + cy + * + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t1_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = PyNumber_Multiply(__pyx_v_bx, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = PyNumber_Add(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1x, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":721 + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx + * c1y = ay * t1_2 + by * t1 + cy # <<<<<<<<<<<<<< + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t1_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = PyNumber_Multiply(__pyx_v_by, __pyx_v_t1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Add(__pyx_t_4, __pyx_v_cy); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1y, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":723 + * c1y = ay * t1_2 + by * t1 + cy + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) # <<<<<<<<<<<<<< + * segments.append((pt1, pt2, pt3)) + * return segments + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_calcQuadraticPoints); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_a1x); + __Pyx_GIVEREF(__pyx_v_a1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_a1x)) __PYX_ERR(0, 723, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_a1y); + __Pyx_GIVEREF(__pyx_v_a1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_a1y)) __PYX_ERR(0, 723, __pyx_L1_error); + __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_v_b1x); + __Pyx_GIVEREF(__pyx_v_b1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_b1x)) __PYX_ERR(0, 723, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b1y); + __Pyx_GIVEREF(__pyx_v_b1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_b1y)) __PYX_ERR(0, 723, __pyx_L1_error); + __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_INCREF(__pyx_v_c1x); + __Pyx_GIVEREF(__pyx_v_c1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_c1x)) __PYX_ERR(0, 723, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c1y); + __Pyx_GIVEREF(__pyx_v_c1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_c1y)) __PYX_ERR(0, 723, __pyx_L1_error); + __pyx_t_11 = NULL; + __pyx_t_12 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_12 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_11, __pyx_t_2, __pyx_t_9, __pyx_t_10}; + __pyx_t_8 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_12, 3+__pyx_t_12); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_8))) || (PyList_CheckExact(__pyx_t_8))) { + PyObject* sequence = __pyx_t_8; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 723, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_4 = PyList_GET_ITEM(sequence, 0); + __pyx_t_10 = PyList_GET_ITEM(sequence, 1); + __pyx_t_9 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_9); + #else + __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_4 = __pyx_t_5(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_10 = __pyx_t_5(__pyx_t_2); if (unlikely(!__pyx_t_10)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_10); + index = 2; __pyx_t_9 = __pyx_t_5(__pyx_t_2); if (unlikely(!__pyx_t_9)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_2), 3) < 0) __PYX_ERR(0, 723, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 723, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_pt1, __pyx_t_4); + __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt2, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt3, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":724 + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + * segments.append((pt1, pt2, pt3)) # <<<<<<<<<<<<<< + * return segments + * + */ + __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_pt1)) __PYX_ERR(0, 724, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_pt2)) __PYX_ERR(0, 724, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_pt3)) __PYX_ERR(0, 724, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_segments, __pyx_t_8); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":709 + * bx, by = b + * cx, cy = c + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":725 + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + * segments.append((pt1, pt2, pt3)) + * return segments # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_segments); + __pyx_r = __pyx_v_segments; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":701 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_segments); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_i); + __Pyx_XDECREF(__pyx_v_t1); + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v_delta); + __Pyx_XDECREF(__pyx_v_delta_2); + __Pyx_XDECREF(__pyx_v_a1x); + __Pyx_XDECREF(__pyx_v_a1y); + __Pyx_XDECREF(__pyx_v_b1x); + __Pyx_XDECREF(__pyx_v_b1y); + __Pyx_XDECREF(__pyx_v_t1_2); + __Pyx_XDECREF(__pyx_v_c1x); + __Pyx_XDECREF(__pyx_v_c1y); + __Pyx_XDECREF(__pyx_v_pt1); + __Pyx_XDECREF(__pyx_v_pt2); + __Pyx_XDECREF(__pyx_v_pt3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":728 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_41_splitCubicAtT, "_splitCubicAtT(a, b, c, d, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_42_splitCubicAtT = {"_splitCubicAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_41_splitCubicAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,&__pyx_n_s_d,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, 1); __PYX_ERR(0, 728, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, 2); __PYX_ERR(0, 728, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_d)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, 3); __PYX_ERR(0, 728, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "_splitCubicAtT") < 0)) __PYX_ERR(0, 728, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 728, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_segments = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_i = NULL; + PyObject *__pyx_v_t1 = NULL; + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v_delta = NULL; + PyObject *__pyx_v_delta_2 = NULL; + PyObject *__pyx_v_delta_3 = NULL; + PyObject *__pyx_v_t1_2 = NULL; + PyObject *__pyx_v_t1_3 = NULL; + PyObject *__pyx_v_a1x = NULL; + PyObject *__pyx_v_a1y = NULL; + PyObject *__pyx_v_b1x = NULL; + PyObject *__pyx_v_b1y = NULL; + PyObject *__pyx_v_c1x = NULL; + PyObject *__pyx_v_c1y = NULL; + PyObject *__pyx_v_d1x = NULL; + PyObject *__pyx_v_d1y = NULL; + PyObject *__pyx_v_pt1 = NULL; + PyObject *__pyx_v_pt2 = NULL; + PyObject *__pyx_v_pt3 = NULL; + PyObject *__pyx_v_pt4 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *(*__pyx_t_5)(PyObject *); + Py_ssize_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_t_13; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitCubicAtT", 0); + __Pyx_INCREF(__pyx_v_ts); + + /* "fontTools/misc/bezierTools.py":729 + * + * def _splitCubicAtT(a, b, c, d, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) + */ + __pyx_t_1 = PySequence_List(__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 729, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_ts, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":730 + * def _splitCubicAtT(a, b, c, d, *ts): + * ts = list(ts) + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * segments = [] + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_ts, __pyx_n_s_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":731 + * ts = list(ts) + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * segments = [] + * ax, ay = a + */ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_v_ts, __pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 731, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":732 + * ts.insert(0, 0.0) + * ts.append(1.0) + * segments = [] # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 732, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_segments = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":733 + * ts.append(1.0) + * segments = [] + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c + */ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 733, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 733, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 733, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 733, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 733, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":734 + * segments = [] + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * dx, dy = d + */ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 734, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 734, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 734, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 734, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 734, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 734, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":735 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * dx, dy = d + * for i in range(len(ts) - 1): + */ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 735, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 735, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 735, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 735, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 735, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 735, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":736 + * bx, by = b + * cx, cy = c + * dx, dy = d # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] + */ + if ((likely(PyTuple_CheckExact(__pyx_v_d))) || (PyList_CheckExact(__pyx_v_d))) { + PyObject* sequence = __pyx_v_d; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 736, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 736, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 736, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_d); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 736, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 736, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 736, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_dy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":737 + * cx, cy = c + * dx, dy = d + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + __pyx_t_6 = PyObject_Length(__pyx_v_ts); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 737, __pyx_L1_error) + __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6 - 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) { + __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 737, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 737, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 737, __pyx_L1_error) + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 737, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 737, __pyx_L1_error) + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } + } else { + __pyx_t_1 = __pyx_t_7(__pyx_t_2); + if (unlikely(!__pyx_t_1)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 737, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":738 + * dx, dy = d + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 + */ + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 738, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_t1, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":739 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * + */ + __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 739, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 739, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_t2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":740 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * + * delta_2 = delta * delta + */ + __pyx_t_4 = PyNumber_Subtract(__pyx_v_t2, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_delta, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":742 + * delta = t2 - t1 + * + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_delta_2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":743 + * + * delta_2 = delta * delta + * delta_3 = delta * delta_2 # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_delta_3, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":744 + * delta_2 = delta * delta + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * t1_3 = t1 * t1_2 + * + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t1_2, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":745 + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 # <<<<<<<<<<<<<< + * + * # calc new a, b, c and d + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 745, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t1_3, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":748 + * + * # calc new a, b, c and d + * a1x = ax * delta_3 # <<<<<<<<<<<<<< + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_delta_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 748, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_a1x, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":749 + * # calc new a, b, c and d + * a1x = ax * delta_3 + * a1y = ay * delta_3 # <<<<<<<<<<<<<< + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_delta_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 749, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_a1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":750 + * a1x = ax * delta_3 + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 # <<<<<<<<<<<<<< + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + */ + __pyx_t_4 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_v_ax, 3, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_4, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_v_bx); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_4, __pyx_v_delta_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1x, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":751 + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 # <<<<<<<<<<<<<< + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + */ + __pyx_t_1 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_v_ay, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 751, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 751, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 751, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_v_delta_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 751, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":752 + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta # <<<<<<<<<<<<<< + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + */ + __pyx_t_4 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_v_bx, 2, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_4, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_v_cx); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_v_ax, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Multiply(__pyx_t_1, __pyx_v_delta); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1x, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":753 + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta # <<<<<<<<<<<<<< + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + */ + __pyx_t_8 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_v_by, 2, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_8, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_v_ay, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_v_delta); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 753, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":754 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx # <<<<<<<<<<<<<< + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t1_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Multiply(__pyx_v_bx, __pyx_v_t1_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = PyNumber_Add(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_v_cx, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Add(__pyx_t_8, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 754, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_d1x, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":755 + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy # <<<<<<<<<<<<<< + * pt1, pt2, pt3, pt4 = calcCubicPoints( + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t1_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_v_by, __pyx_v_t1_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = PyNumber_Add(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_v_cy, __pyx_v_t1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Add(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_v_dy); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_d1y, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":756 + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( # <<<<<<<<<<<<<< + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_calcCubicPoints); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":757 + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) # <<<<<<<<<<<<<< + * ) + * segments.append((pt1, pt2, pt3, pt4)) + */ + __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_a1x); + __Pyx_GIVEREF(__pyx_v_a1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_a1x)) __PYX_ERR(0, 757, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_a1y); + __Pyx_GIVEREF(__pyx_v_a1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_a1y)) __PYX_ERR(0, 757, __pyx_L1_error); + __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_v_b1x); + __Pyx_GIVEREF(__pyx_v_b1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_b1x)) __PYX_ERR(0, 757, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b1y); + __Pyx_GIVEREF(__pyx_v_b1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_b1y)) __PYX_ERR(0, 757, __pyx_L1_error); + __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_INCREF(__pyx_v_c1x); + __Pyx_GIVEREF(__pyx_v_c1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_c1x)) __PYX_ERR(0, 757, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c1y); + __Pyx_GIVEREF(__pyx_v_c1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_c1y)) __PYX_ERR(0, 757, __pyx_L1_error); + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_d1x); + __Pyx_GIVEREF(__pyx_v_d1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_d1x)) __PYX_ERR(0, 757, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d1y); + __Pyx_GIVEREF(__pyx_v_d1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_d1y)) __PYX_ERR(0, 757, __pyx_L1_error); + __pyx_t_12 = NULL; + __pyx_t_13 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_12)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_12); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_13 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_12, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_13, 4+__pyx_t_13); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) { + PyObject* sequence = __pyx_t_4; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 756, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_11 = PyList_GET_ITEM(sequence, 1); + __pyx_t_10 = PyList_GET_ITEM(sequence, 2); + __pyx_t_9 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_9); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_10,&__pyx_t_9}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_10,&__pyx_t_9}; + __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_5(__pyx_t_8); if (unlikely(!item)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_8), 4) < 0) __PYX_ERR(0, 756, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L14_unpacking_done; + __pyx_L13_unpacking_failed:; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 756, __pyx_L1_error) + __pyx_L14_unpacking_done:; + } + + /* "fontTools/misc/bezierTools.py":756 + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( # <<<<<<<<<<<<<< + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) + */ + __Pyx_XDECREF_SET(__pyx_v_pt1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt2, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt3, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt4, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":759 + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) + * segments.append((pt1, pt2, pt3, pt4)) # <<<<<<<<<<<<<< + * return segments + * + */ + __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_pt1)) __PYX_ERR(0, 759, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_pt2)) __PYX_ERR(0, 759, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_pt3)) __PYX_ERR(0, 759, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_v_pt4)) __PYX_ERR(0, 759, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_segments, __pyx_t_4); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":737 + * cx, cy = c + * dx, dy = d + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":760 + * ) + * segments.append((pt1, pt2, pt3, pt4)) + * return segments # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_segments); + __pyx_r = __pyx_v_segments; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":728 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_segments); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_i); + __Pyx_XDECREF(__pyx_v_t1); + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v_delta); + __Pyx_XDECREF(__pyx_v_delta_2); + __Pyx_XDECREF(__pyx_v_delta_3); + __Pyx_XDECREF(__pyx_v_t1_2); + __Pyx_XDECREF(__pyx_v_t1_3); + __Pyx_XDECREF(__pyx_v_a1x); + __Pyx_XDECREF(__pyx_v_a1y); + __Pyx_XDECREF(__pyx_v_b1x); + __Pyx_XDECREF(__pyx_v_b1y); + __Pyx_XDECREF(__pyx_v_c1x); + __Pyx_XDECREF(__pyx_v_c1y); + __Pyx_XDECREF(__pyx_v_d1x); + __Pyx_XDECREF(__pyx_v_d1y); + __Pyx_XDECREF(__pyx_v_pt1); + __Pyx_XDECREF(__pyx_v_pt2); + __Pyx_XDECREF(__pyx_v_pt3); + __Pyx_XDECREF(__pyx_v_pt4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_45generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":763 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_43_splitCubicAtTC, "_splitCubicAtTC(double complex a, double complex b, double complex c, double complex d, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_44_splitCubicAtTC = {"_splitCubicAtTC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_43_splitCubicAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_d; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,&__pyx_n_s_d,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + default: + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 763, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 763, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, 1); __PYX_ERR(0, 763, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 763, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, 2); __PYX_ERR(0, 763, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_d)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 763, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, 3); __PYX_ERR(0, 763, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, used_pos_args, "_splitCubicAtTC") < 0)) __PYX_ERR(0, 763, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_a = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 778, __pyx_L3_error) + __pyx_v_b = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 778, __pyx_L3_error) + __pyx_v_c = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 778, __pyx_L3_error) + __pyx_v_d = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 778, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 763, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_CLEAR(__pyx_v_ts); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d, __pyx_v_ts); + + /* function exit code */ + __Pyx_DECREF(__pyx_v_ts); + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitCubicAtTC", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 763, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_a = __pyx_v_a; + __pyx_cur_scope->__pyx_v_b = __pyx_v_b; + __pyx_cur_scope->__pyx_v_c = __pyx_v_c; + __pyx_cur_scope->__pyx_v_d = __pyx_v_d; + __pyx_cur_scope->__pyx_v_ts = __pyx_v_ts; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_ts); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_45generator1, __pyx_codeobj__3, (PyObject *) __pyx_cur_scope, __pyx_n_s_splitCubicAtTC_2, __pyx_n_s_splitCubicAtTC_2, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_45generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + PyObject *(*__pyx_t_5)(PyObject *); + double __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *(*__pyx_t_12)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtTC", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L8_resume_from_yield; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 763, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":779 + * ) + * def _splitCubicAtTC(a, b, c, d, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) + */ + __pyx_t_1 = PySequence_List(__pyx_cur_scope->__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 779, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_DECREF_SET(__pyx_cur_scope->__pyx_v_ts, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":780 + * def _splitCubicAtTC(a, b, c, d, *ts): + * ts = list(ts) + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * for i in range(len(ts) - 1): + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_ts, __pyx_n_s_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":781 + * ts = list(ts) + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] + */ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_cur_scope->__pyx_v_ts, __pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 781, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":782 + * ts.insert(0, 0.0) + * ts.append(1.0) + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + __pyx_t_4 = PyObject_Length(__pyx_cur_scope->__pyx_v_ts); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 782, __pyx_L1_error) + __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) { + __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = NULL; + } else { + __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 782, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + for (;;) { + if (likely(!__pyx_t_5)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 782, __pyx_L1_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 782, __pyx_L1_error) + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 782, __pyx_L1_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 782, __pyx_L1_error) + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } + } else { + __pyx_t_1 = __pyx_t_5(__pyx_t_2); + if (unlikely(!__pyx_t_1)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 782, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_i, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":783 + * ts.append(1.0) + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 + */ + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_cur_scope->__pyx_v_ts, __pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 783, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_cur_scope->__pyx_v_t1 = __pyx_t_6; + + /* "fontTools/misc/bezierTools.py":784 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * + */ + __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_cur_scope->__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 784, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_GetItem(__pyx_cur_scope->__pyx_v_ts, __pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 784, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_7); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 784, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_cur_scope->__pyx_v_t2 = __pyx_t_6; + + /* "fontTools/misc/bezierTools.py":785 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * + * delta_2 = delta * delta + */ + __pyx_cur_scope->__pyx_v_delta = (__pyx_cur_scope->__pyx_v_t2 - __pyx_cur_scope->__pyx_v_t1); + + /* "fontTools/misc/bezierTools.py":787 + * delta = t2 - t1 + * + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + */ + __pyx_cur_scope->__pyx_v_delta_2 = (__pyx_cur_scope->__pyx_v_delta * __pyx_cur_scope->__pyx_v_delta); + + /* "fontTools/misc/bezierTools.py":788 + * + * delta_2 = delta * delta + * delta_3 = delta * delta_2 # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 + */ + __pyx_cur_scope->__pyx_v_delta_3 = (__pyx_cur_scope->__pyx_v_delta * __pyx_cur_scope->__pyx_v_delta_2); + + /* "fontTools/misc/bezierTools.py":789 + * delta_2 = delta * delta + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * t1_3 = t1 * t1_2 + * + */ + __pyx_cur_scope->__pyx_v_t1_2 = (__pyx_cur_scope->__pyx_v_t1 * __pyx_cur_scope->__pyx_v_t1); + + /* "fontTools/misc/bezierTools.py":790 + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 # <<<<<<<<<<<<<< + * + * # calc new a, b, c and d + */ + __pyx_cur_scope->__pyx_v_t1_3 = (__pyx_cur_scope->__pyx_v_t1 * __pyx_cur_scope->__pyx_v_t1_2); + + /* "fontTools/misc/bezierTools.py":793 + * + * # calc new a, b, c and d + * a1 = a * delta_3 # <<<<<<<<<<<<<< + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + */ + __pyx_cur_scope->__pyx_v_a1 = __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_3, 0)); + + /* "fontTools/misc/bezierTools.py":794 + * # calc new a, b, c and d + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 # <<<<<<<<<<<<<< + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + */ + __pyx_cur_scope->__pyx_v_b1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_2, 0)); + + /* "fontTools/misc/bezierTools.py":795 + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta # <<<<<<<<<<<<<< + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + */ + __pyx_cur_scope->__pyx_v_c1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(2, 0), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_c), __Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta, 0)); + + /* "fontTools/misc/bezierTools.py":796 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d # <<<<<<<<<<<<<< + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + * yield (pt1, pt2, pt3, pt4) + */ + __pyx_cur_scope->__pyx_v_d1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_3, 0)), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_b, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_c, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0))), __pyx_cur_scope->__pyx_v_d); + + /* "fontTools/misc/bezierTools.py":797 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) # <<<<<<<<<<<<<< + * yield (pt1, pt2, pt3, pt4) + * + */ + __pyx_t_7 = __pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_cur_scope->__pyx_v_a1, __pyx_cur_scope->__pyx_v_b1, __pyx_cur_scope->__pyx_v_c1, __pyx_cur_scope->__pyx_v_d1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 797, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) { + PyObject* sequence = __pyx_t_7; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 797, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_8 = PyList_GET_ITEM(sequence, 1); + __pyx_t_9 = PyList_GET_ITEM(sequence, 2); + __pyx_t_10 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 797, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10}; + __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 797, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_12 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_11); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_12(__pyx_t_11); if (unlikely(!item)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_11), 4) < 0) __PYX_ERR(0, 797, __pyx_L1_error) + __pyx_t_12 = NULL; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_12 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 797, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt1); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt1, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt2); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt2, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt3); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt3, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt4); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt4, __pyx_t_10); + __Pyx_GIVEREF(__pyx_t_10); + __pyx_t_10 = 0; + + /* "fontTools/misc/bezierTools.py":798 + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + * yield (pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_cur_scope->__pyx_v_pt1)) __PYX_ERR(0, 798, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_cur_scope->__pyx_v_pt2)) __PYX_ERR(0, 798, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_cur_scope->__pyx_v_pt3)) __PYX_ERR(0, 798, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_cur_scope->__pyx_v_pt4)) __PYX_ERR(0, 798, __pyx_L1_error); + __pyx_r = __pyx_t_7; + __pyx_t_7 = 0; + __Pyx_XGIVEREF(__pyx_t_2); + __pyx_cur_scope->__pyx_t_0 = __pyx_t_2; + __pyx_cur_scope->__pyx_t_1 = __pyx_t_4; + __pyx_cur_scope->__pyx_t_2 = __pyx_t_5; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L8_resume_from_yield:; + __pyx_t_2 = __pyx_cur_scope->__pyx_t_0; + __pyx_cur_scope->__pyx_t_0 = 0; + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __pyx_cur_scope->__pyx_t_1; + __pyx_t_5 = __pyx_cur_scope->__pyx_t_2; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 798, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":782 + * ts.insert(0, 0.0) + * ts.append(1.0) + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] + */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* "fontTools/misc/bezierTools.py":763 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, + */ + + /* function exit code */ + PyErr_SetNone(PyExc_StopIteration); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("_splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":808 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__(CYTHON_UNUSED PyObject *__pyx_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__defaults__", 1); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_sqrt); + __Pyx_GIVEREF(__Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_sqrt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self)->__pyx_arg_sqrt)) __PYX_ERR(0, 808, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 808, __pyx_L1_error); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None)) __PYX_ERR(0, 808, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.misc.bezierTools.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_46solveQuadratic, "solveQuadratic(a, b, c, sqrt=sqrt)\nSolve a quadratic equation.\n\n Solves *a*x*x + b*x + c = 0* where a, b and c are real.\n\n Args:\n a: coefficient of *x\302\262*\n b: coefficient of *x*\n c: constant term\n\n Returns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_47solveQuadratic = {"solveQuadratic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_46solveQuadratic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_sqrt = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("solveQuadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,&__pyx_n_s_sqrt,0}; + __pyx_defaults *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_self); + values[3] = __Pyx_Arg_NewRef_FASTCALL(__pyx_dynamic_args->__pyx_arg_sqrt); + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("solveQuadratic", 0, 3, 4, 1); __PYX_ERR(0, 808, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("solveQuadratic", 0, 3, 4, 2); __PYX_ERR(0, 808, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_sqrt); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "solveQuadratic") < 0)) __PYX_ERR(0, 808, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_sqrt = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("solveQuadratic", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 808, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_sqrt); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_sqrt) { + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_DD = NULL; + PyObject *__pyx_v_rDD = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("solveQuadratic", 1); + + /* "fontTools/misc/bezierTools.py":822 + * be sorted nor to contain unique values! + * """ + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution + */ + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 822, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 822, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 822, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 822, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":823 + * """ + * if abs(a) < epsilon: + * if abs(b) < epsilon: # <<<<<<<<<<<<<< + * # We have a non-equation; therefore, we have no valid solution + * roots = [] + */ + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 823, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 823, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":825 + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution + * roots = [] # <<<<<<<<<<<<<< + * else: + * # We have a linear equation with 1 root. + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 825, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":823 + * """ + * if abs(a) < epsilon: + * if abs(b) < epsilon: # <<<<<<<<<<<<<< + * # We have a non-equation; therefore, we have no valid solution + * roots = [] + */ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":828 + * else: + * # We have a linear equation with 1 root. + * roots = [-c / b] # <<<<<<<<<<<<<< + * else: + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + */ + /*else*/ { + __pyx_t_1 = PyNumber_Negative(__pyx_v_c); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 828, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 828, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 828, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2)) __PYX_ERR(0, 828, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + } + __pyx_L4:; + + /* "fontTools/misc/bezierTools.py":822 + * be sorted nor to contain unique values! + * """ + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution + */ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":831 + * else: + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c # <<<<<<<<<<<<<< + * if DD >= 0.0: + * rDD = sqrt(DD) + */ + /*else*/ { + __pyx_t_1 = PyNumber_Multiply(__pyx_v_b, __pyx_v_b); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 831, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_float_4_0, __pyx_v_a); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 831, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 831, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 831, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_DD = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":832 + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: # <<<<<<<<<<<<<< + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + */ + __pyx_t_2 = PyObject_RichCompare(__pyx_v_DD, __pyx_float_0_0, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 832, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 832, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":833 + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: + * rDD = sqrt(DD) # <<<<<<<<<<<<<< + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + * else: + */ + __Pyx_INCREF(__pyx_v_sqrt); + __pyx_t_3 = __pyx_v_sqrt; __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_DD}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 833, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_rDD = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":834 + * if DD >= 0.0: + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] # <<<<<<<<<<<<<< + * else: + * # complex roots, ignore + */ + __pyx_t_2 = PyNumber_Negative(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_v_rDD); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Negative(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_rDD); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_3)) __PYX_ERR(0, 834, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_t_1)) __PYX_ERR(0, 834, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_v_roots = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":832 + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: # <<<<<<<<<<<<<< + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + */ + goto __pyx_L5; + } + + /* "fontTools/misc/bezierTools.py":837 + * else: + * # complex roots, ignore + * roots = [] # <<<<<<<<<<<<<< + * return roots + * + */ + /*else*/ { + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 837, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_roots = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + } + __pyx_L5:; + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":838 + * # complex roots, ignore + * roots = [] + * return roots # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_roots); + __pyx_r = __pyx_v_roots; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":808 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_DD); + __Pyx_XDECREF(__pyx_v_rDD); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":841 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_48solveCubic, "solveCubic(a, b, c, d)\nSolve a cubic equation.\n\n Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.\n\n Args:\n a: coefficient of *x\302\263*\n b: coefficient of *x\302\262*\n c: coefficient of *x*\n d: constant term\n\n Returns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!\n\n Examples::\n\n >>> solveCubic(1, 1, -6, 0)\n [-3.0, -0.0, 2.0]\n >>> solveCubic(-10.0, -9.0, 48.0, -29.0)\n [-2.9, 1.0, 1.0]\n >>> solveCubic(-9.875, -9.0, 47.625, -28.75)\n [-2.911392, 1.0, 1.0]\n >>> solveCubic(1.0, -4.5, 6.75, -3.375)\n [1.5, 1.5, 1.5]\n >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)\n [0.5, 0.5, 0.5]\n >>> solveCubic(\n ... 9.0, 0.0, 0.0, -7.62939453125e-05\n ... ) == [-0.0, -0.0, -0.0]\n True\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_49solveCubic = {"solveCubic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_48solveCubic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("solveCubic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,&__pyx_n_s_d,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, 1); __PYX_ERR(0, 841, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, 2); __PYX_ERR(0, 841, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_d)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, 3); __PYX_ERR(0, 841, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "solveCubic") < 0)) __PYX_ERR(0, 841, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 841, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_v_a1 = NULL; + PyObject *__pyx_v_a2 = NULL; + PyObject *__pyx_v_a3 = NULL; + PyObject *__pyx_v_Q = NULL; + PyObject *__pyx_v_R = NULL; + PyObject *__pyx_v_R2 = NULL; + PyObject *__pyx_v_Q3 = NULL; + PyObject *__pyx_v_R2_Q3 = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_theta = NULL; + PyObject *__pyx_v_rQ2 = NULL; + PyObject *__pyx_v_a1_3 = NULL; + PyObject *__pyx_v_x0 = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + double __pyx_t_8; + double __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("solveCubic", 0); + __Pyx_INCREF(__pyx_v_a); + + /* "fontTools/misc/bezierTools.py":879 + * # found at: http://www.strangecreations.com/library/snippets/Cubic.C + * # + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. + */ + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":882 + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. + * return solveQuadratic(b, c, d) # <<<<<<<<<<<<<< + * a = float(a) + * a1 = b / a + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_solveQuadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 882, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_1, __pyx_v_b, __pyx_v_c, __pyx_v_d}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 882, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":879 + * # found at: http://www.strangecreations.com/library/snippets/Cubic.C + * # + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. + */ + } + + /* "fontTools/misc/bezierTools.py":883 + * # returns unreliable results, so we fall back to quad. + * return solveQuadratic(b, c, d) + * a = float(a) # <<<<<<<<<<<<<< + * a1 = b / a + * a2 = c / a + */ + __pyx_t_3 = __Pyx_PyNumber_Float(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 883, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_a, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":884 + * return solveQuadratic(b, c, d) + * a = float(a) + * a1 = b / a # <<<<<<<<<<<<<< + * a2 = c / a + * a3 = d / a + */ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_b, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 884, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a1 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":885 + * a = float(a) + * a1 = b / a + * a2 = c / a # <<<<<<<<<<<<<< + * a3 = d / a + * + */ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_c, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 885, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":886 + * a1 = b / a + * a2 = c / a + * a3 = d / a # <<<<<<<<<<<<<< + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 + */ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_d, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 886, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a3 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":888 + * a3 = d / a + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 # <<<<<<<<<<<<<< + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + * + */ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_a1, __pyx_v_a1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 888, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Multiply(__pyx_float_3_0, __pyx_v_a2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 888, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 888, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_9_0, 9.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 888, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_Q = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":889 + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 # <<<<<<<<<<<<<< + * + * R2 = R * R + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_float_2_0, __pyx_v_a1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_a1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_a1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_float_9_0, __pyx_v_a1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_v_a2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_float_27_0, __pyx_v_a3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_2, __pyx_float_54_0, 54.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_R = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":891 + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + * + * R2 = R * R # <<<<<<<<<<<<<< + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 + */ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_R, __pyx_v_R); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 891, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_R2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":892 + * + * R2 = R * R + * Q3 = Q * Q * Q # <<<<<<<<<<<<<< + * R2 = 0 if R2 < epsilon else R2 + * Q3 = 0 if abs(Q3) < epsilon else Q3 + */ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_Q, __pyx_v_Q); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 892, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_Q); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 892, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_Q3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":893 + * R2 = R * R + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 # <<<<<<<<<<<<<< + * Q3 = 0 if abs(Q3) < epsilon else Q3 + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 893, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_v_R2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 893, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 893, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + __Pyx_INCREF(__pyx_int_0); + __pyx_t_2 = __pyx_int_0; + } else { + __Pyx_INCREF(__pyx_v_R2); + __pyx_t_2 = __pyx_v_R2; + } + __Pyx_DECREF_SET(__pyx_v_R2, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":894 + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 + * Q3 = 0 if abs(Q3) < epsilon else Q3 # <<<<<<<<<<<<<< + * + * R2_Q3 = R2 - Q3 + */ + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_v_Q3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 894, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 894, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 894, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 894, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_4) { + __Pyx_INCREF(__pyx_int_0); + __pyx_t_2 = __pyx_int_0; + } else { + __Pyx_INCREF(__pyx_v_Q3); + __pyx_t_2 = __pyx_v_Q3; + } + __Pyx_DECREF_SET(__pyx_v_Q3, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":896 + * Q3 = 0 if abs(Q3) < epsilon else Q3 + * + * R2_Q3 = R2 - Q3 # <<<<<<<<<<<<<< + * + * if R2 == 0.0 and Q3 == 0.0: + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_R2, __pyx_v_Q3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_R2_Q3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":898 + * R2_Q3 = R2 - Q3 + * + * if R2 == 0.0 and Q3 == 0.0: # <<<<<<<<<<<<<< + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + */ + __pyx_t_7 = (__Pyx_PyFloat_BoolEqObjC(__pyx_v_R2, __pyx_float_0_0, 0.0, 0, 0)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 898, __pyx_L1_error) + if (__pyx_t_7) { + } else { + __pyx_t_4 = __pyx_t_7; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_7 = (__Pyx_PyFloat_BoolEqObjC(__pyx_v_Q3, __pyx_float_0_0, 0.0, 0, 0)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 898, __pyx_L1_error) + __pyx_t_4 = __pyx_t_7; + __pyx_L5_bool_binop_done:; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":899 + * + * if R2 == 0.0 and Q3 == 0.0: + * x = round(-a1 / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: + */ + __pyx_t_2 = PyNumber_Negative(__pyx_v_a1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_2, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6)) __PYX_ERR(0, 899, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":900 + * if R2 == 0.0 and Q3 == 0.0: + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] # <<<<<<<<<<<<<< + * elif R2_Q3 <= epsilon * 0.5: + * # The epsilon * .5 above ensures that Q3 is not zero. + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 900, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_v_x)) __PYX_ERR(0, 900, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_v_x)) __PYX_ERR(0, 900, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_v_x)) __PYX_ERR(0, 900, __pyx_L1_error); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":898 + * R2_Q3 = R2 - Q3 + * + * if R2 == 0.0 and Q3 == 0.0: # <<<<<<<<<<<<<< + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + */ + } + + /* "fontTools/misc/bezierTools.py":901 + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: # <<<<<<<<<<<<<< + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_float_0_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyObject_RichCompare(__pyx_v_R2_Q3, __pyx_t_3, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":903 + * elif R2_Q3 <= epsilon * 0.5: + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) # <<<<<<<<<<<<<< + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_acos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = -1.0; + __pyx_t_9 = 1.0; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_v_Q3}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_v_R, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_10 = PyFloat_FromDouble(__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = PyObject_RichCompare(__pyx_t_10, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_11); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (__pyx_t_4) { + __pyx_t_11 = PyFloat_FromDouble(__pyx_t_9); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_6 = __pyx_t_11; + __pyx_t_11 = 0; + } else { + __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = __pyx_t_1; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_INCREF(__pyx_t_6); + __pyx_t_1 = __pyx_t_6; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_11 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_10 = PyObject_RichCompare(__pyx_t_11, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__pyx_t_4) { + __pyx_t_10 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_6 = __pyx_t_10; + __pyx_t_10 = 0; + } else { + __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = __pyx_t_1; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_6}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_theta = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":904 + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + * rQ2 = -2.0 * sqrt(Q) # <<<<<<<<<<<<<< + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 904, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_v_Q}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 904, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = PyNumber_Multiply(__pyx_float_neg_2_0, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 904, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_rQ2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":905 + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 # <<<<<<<<<<<<<< + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + */ + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_a1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 905, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a1_3 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":906 + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_cos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_theta, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_6}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_2 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Subtract(__pyx_t_2, __pyx_v_a1_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x0 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":907 + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + * x0, x1, x2 = sorted([x0, x1, x2]) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_cos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pi); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = PyNumber_Multiply(__pyx_float_2_0, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_v_theta, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_6, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_1}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_2 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Subtract(__pyx_t_2, __pyx_v_a1_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x1 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":908 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_cos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pi); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyNumber_Multiply(__pyx_float_4_0, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_v_theta, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_6}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_2 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Subtract(__pyx_t_2, __pyx_v_a1_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":909 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + * x0, x1, x2 = sorted([x0, x1, x2]) # <<<<<<<<<<<<<< + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + */ + __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 909, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_v_x0)) __PYX_ERR(0, 909, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_v_x1)) __PYX_ERR(0, 909, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_v_x2)) __PYX_ERR(0, 909, __pyx_L1_error); + __pyx_t_3 = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_12 = PyList_Sort(__pyx_t_3); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 909, __pyx_L1_error) + if (1) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 909, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_6 = PyList_GET_ITEM(sequence, 1); + __pyx_t_1 = PyList_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 909, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 909, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 909, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":911 + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: + */ + __pyx_t_3 = PyNumber_Subtract(__pyx_v_x1, __pyx_v_x0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_4 = __pyx_t_7; + goto __pyx_L8_bool_binop_done; + } + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_x1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_6, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __pyx_t_7; + __pyx_L8_bool_binop_done:; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":912 + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + */ + __pyx_t_3 = PyNumber_Add(__pyx_v_x0, __pyx_v_x1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_v_x2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3)) __PYX_ERR(0, 912, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1)) __PYX_ERR(0, 912, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_1); + __Pyx_INCREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_1); + __Pyx_INCREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":911 + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: + */ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":913 + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x1, __pyx_v_x0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":914 + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) # <<<<<<<<<<<<<< + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: + */ + __pyx_t_3 = PyNumber_Add(__pyx_v_x0, __pyx_v_x1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6)) __PYX_ERR(0, 914, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_INCREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_3); + __Pyx_INCREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":915 + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) # <<<<<<<<<<<<<< + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x2)) __PYX_ERR(0, 915, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(0, 915, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":913 + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + */ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":916 + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + */ + __pyx_t_3 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_x1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":917 + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) # <<<<<<<<<<<<<< + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + * else: + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x0)) __PYX_ERR(0, 917, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6)) __PYX_ERR(0, 917, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_1, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":918 + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) # <<<<<<<<<<<<<< + * else: + * x0 = round(x0, epsilonDigits) + */ + __pyx_t_6 = PyNumber_Add(__pyx_v_x1, __pyx_v_x2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_6, __pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_6); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":916 + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + */ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":920 + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + * else: + * x0 = round(x0, epsilonDigits) # <<<<<<<<<<<<<< + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) + */ + /*else*/ { + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x0)) __PYX_ERR(0, 920, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6)) __PYX_ERR(0, 920, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":921 + * else: + * x0 = round(x0, epsilonDigits) + * x1 = round(x1, epsilonDigits) # <<<<<<<<<<<<<< + * x2 = round(x2, epsilonDigits) + * return [x0, x1, x2] + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x1)) __PYX_ERR(0, 921, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6)) __PYX_ERR(0, 921, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":922 + * x0 = round(x0, epsilonDigits) + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) # <<<<<<<<<<<<<< + * return [x0, x1, x2] + * else: + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 922, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 922, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x2)) __PYX_ERR(0, 922, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6)) __PYX_ERR(0, 922, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 922, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_6); + __pyx_t_6 = 0; + } + __pyx_L7:; + + /* "fontTools/misc/bezierTools.py":923 + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * return [x0, x1, x2] # <<<<<<<<<<<<<< + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_6 = PyList_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 923, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_x0)) __PYX_ERR(0, 923, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 1, __pyx_v_x1)) __PYX_ERR(0, 923, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 2, __pyx_v_x2)) __PYX_ERR(0, 923, __pyx_L1_error); + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":901 + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: # <<<<<<<<<<<<<< + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + */ + } + + /* "fontTools/misc/bezierTools.py":925 + * return [x0, x1, x2] + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) # <<<<<<<<<<<<<< + * x = x + Q / x + * if R >= 0.0: + */ + /*else*/ { + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_R2_Q3}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_v_R); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyFloat_FromDouble((1.0 / 3.0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyNumber_Power2(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":926 + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x # <<<<<<<<<<<<<< + * if R >= 0.0: + * x = -x + */ + __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_v_Q, __pyx_v_x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 926, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyNumber_Add(__pyx_v_x, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 926, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":927 + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x + * if R >= 0.0: # <<<<<<<<<<<<<< + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) + */ + __pyx_t_3 = PyObject_RichCompare(__pyx_v_R, __pyx_float_0_0, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 927, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 927, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":928 + * x = x + Q / x + * if R >= 0.0: + * x = -x # <<<<<<<<<<<<<< + * x = round(x - a1 / 3.0, epsilonDigits) + * return [x] + */ + __pyx_t_3 = PyNumber_Negative(__pyx_v_x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 928, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":927 + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x + * if R >= 0.0: # <<<<<<<<<<<<<< + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) + */ + } + + /* "fontTools/misc/bezierTools.py":929 + * if R >= 0.0: + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * return [x] + * + */ + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_a1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6)) __PYX_ERR(0, 929, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(0, 929, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":930 + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) + * return [x] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 930, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_v_x)) __PYX_ERR(0, 930, __pyx_L1_error); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":841 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a1); + __Pyx_XDECREF(__pyx_v_a2); + __Pyx_XDECREF(__pyx_v_a3); + __Pyx_XDECREF(__pyx_v_Q); + __Pyx_XDECREF(__pyx_v_R); + __Pyx_XDECREF(__pyx_v_R2); + __Pyx_XDECREF(__pyx_v_Q3); + __Pyx_XDECREF(__pyx_v_R2_Q3); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_theta); + __Pyx_XDECREF(__pyx_v_rQ2); + __Pyx_XDECREF(__pyx_v_a1_3); + __Pyx_XDECREF(__pyx_v_x0); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":938 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_50calcQuadraticParameters, "calcQuadraticParameters(pt1, pt2, pt3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_51calcQuadraticParameters = {"calcQuadraticParameters", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_50calcQuadraticParameters}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticParameters (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticParameters", 1, 3, 3, 1); __PYX_ERR(0, 938, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticParameters", 1, 3, 3, 2); __PYX_ERR(0, 938, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcQuadraticParameters") < 0)) __PYX_ERR(0, 938, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticParameters", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 938, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticParameters", 1); + + /* "fontTools/misc/bezierTools.py":939 + * + * def calcQuadraticParameters(pt1, pt2, pt3): + * x2, y2 = pt2 # <<<<<<<<<<<<<< + * x3, y3 = pt3 + * cx, cy = pt1 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 939, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 939, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 939, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 939, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 939, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 939, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":940 + * def calcQuadraticParameters(pt1, pt2, pt3): + * x2, y2 = pt2 + * x3, y3 = pt3 # <<<<<<<<<<<<<< + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt3))) || (PyList_CheckExact(__pyx_v_pt3))) { + PyObject* sequence = __pyx_v_pt3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 940, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 940, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 940, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 940, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 940, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 940, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_x3 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":941 + * x2, y2 = pt2 + * x3, y3 = pt3 + * cx, cy = pt1 # <<<<<<<<<<<<<< + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 941, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 941, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 941, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 941, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 941, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 941, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":942 + * x3, y3 = pt3 + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 # <<<<<<<<<<<<<< + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 942, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 942, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":943 + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 # <<<<<<<<<<<<<< + * ax = x3 - cx - bx + * ay = y3 - cy - by + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y2, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 943, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_float_2_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 943, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":944 + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx # <<<<<<<<<<<<<< + * ay = y3 - cy - by + * return (ax, ay), (bx, by), (cx, cy) + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_x3, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 944, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 944, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":945 + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx + * ay = y3 - cy - by # <<<<<<<<<<<<<< + * return (ax, ay), (bx, by), (cx, cy) + * + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y3, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 945, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_by); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 945, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":946 + * ax = x3 - cx - bx + * ay = y3 - cy - by + * return (ax, ay), (bx, by), (cx, cy) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ax)) __PYX_ERR(0, 946, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_ay)) __PYX_ERR(0, 946, __pyx_L1_error); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_bx)) __PYX_ERR(0, 946, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_by)) __PYX_ERR(0, 946, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_cx); + __Pyx_GIVEREF(__pyx_v_cx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cx)) __PYX_ERR(0, 946, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cy); + __Pyx_GIVEREF(__pyx_v_cy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_cy)) __PYX_ERR(0, 946, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2)) __PYX_ERR(0, 946, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1)) __PYX_ERR(0, 946, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 946, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":938 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":949 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_52calcCubicParameters, "calcCubicParameters(pt1, pt2, pt3, pt4)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_53calcCubicParameters = {"calcCubicParameters", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_52calcCubicParameters}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicParameters (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, 1); __PYX_ERR(0, 949, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, 2); __PYX_ERR(0, 949, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, 3); __PYX_ERR(0, 949, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcCubicParameters") < 0)) __PYX_ERR(0, 949, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 949, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_x4 = NULL; + PyObject *__pyx_v_y4 = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicParameters", 1); + + /* "fontTools/misc/bezierTools.py":950 + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): + * x2, y2 = pt2 # <<<<<<<<<<<<<< + * x3, y3 = pt3 + * x4, y4 = pt4 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 950, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 950, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 950, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 950, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 950, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 950, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":951 + * def calcCubicParameters(pt1, pt2, pt3, pt4): + * x2, y2 = pt2 + * x3, y3 = pt3 # <<<<<<<<<<<<<< + * x4, y4 = pt4 + * dx, dy = pt1 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt3))) || (PyList_CheckExact(__pyx_v_pt3))) { + PyObject* sequence = __pyx_v_pt3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 951, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 951, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 951, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 951, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 951, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 951, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_x3 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":952 + * x2, y2 = pt2 + * x3, y3 = pt3 + * x4, y4 = pt4 # <<<<<<<<<<<<<< + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt4))) || (PyList_CheckExact(__pyx_v_pt4))) { + PyObject* sequence = __pyx_v_pt4; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 952, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 952, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 952, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_x4 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y4 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":953 + * x3, y3 = pt3 + * x4, y4 = pt4 + * dx, dy = pt1 # <<<<<<<<<<<<<< + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 953, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 953, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 953, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_dy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":954 + * x4, y4 = pt4 + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 # <<<<<<<<<<<<<< + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 954, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 954, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":955 + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 # <<<<<<<<<<<<<< + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_y2, __pyx_v_dy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 955, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 955, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":956 + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx # <<<<<<<<<<<<<< + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x3, __pyx_v_x2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 956, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 956, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 956, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":957 + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy # <<<<<<<<<<<<<< + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y3, __pyx_v_y2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":958 + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx # <<<<<<<<<<<<<< + * ay = y4 - dy - cy - by + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x4, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":959 + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by # <<<<<<<<<<<<<< + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) + * + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y4, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":960 + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ax)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ay)) __PYX_ERR(0, 960, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_bx)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_by)) __PYX_ERR(0, 960, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_cx); + __Pyx_GIVEREF(__pyx_v_cx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cx)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cy); + __Pyx_GIVEREF(__pyx_v_cy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_cy)) __PYX_ERR(0, 960, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_dx); + __Pyx_GIVEREF(__pyx_v_dx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_dx)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_dy); + __Pyx_GIVEREF(__pyx_v_dy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_dy)) __PYX_ERR(0, 960, __pyx_L1_error); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3)) __PYX_ERR(0, 960, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5)) __PYX_ERR(0, 960, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":949 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_x4); + __Pyx_XDECREF(__pyx_v_y4); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":963 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4) { + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicParametersC", 1); + + /* "fontTools/misc/bezierTools.py":975 + * ) + * def calcCubicParametersC(pt1, pt2, pt3, pt4): + * c = (pt2 - pt1) * 3.0 # <<<<<<<<<<<<<< + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b + */ + __pyx_v_c = __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1), __pyx_t_double_complex_from_parts(3.0, 0)); + + /* "fontTools/misc/bezierTools.py":976 + * def calcCubicParametersC(pt1, pt2, pt3, pt4): + * c = (pt2 - pt1) * 3.0 + * b = (pt3 - pt2) * 3.0 - c # <<<<<<<<<<<<<< + * a = pt4 - pt1 - c - b + * return (a, b, c, pt1) + */ + __pyx_v_b = __Pyx_c_diff_double(__Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt2), __pyx_t_double_complex_from_parts(3.0, 0)), __pyx_v_c); + + /* "fontTools/misc/bezierTools.py":977 + * c = (pt2 - pt1) * 3.0 + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b # <<<<<<<<<<<<<< + * return (a, b, c, pt1) + * + */ + __pyx_v_a = __Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt1), __pyx_v_c), __pyx_v_b); + + /* "fontTools/misc/bezierTools.py":978 + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b + * return (a, b, c, pt1) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 978, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 978, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 978, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 978, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 978, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1)) __PYX_ERR(0, 978, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2)) __PYX_ERR(0, 978, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 978, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4)) __PYX_ERR(0, 978, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":963 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParametersC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":981 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_54calcQuadraticPoints, "calcQuadraticPoints(a, b, c)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_55calcQuadraticPoints = {"calcQuadraticPoints", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_54calcQuadraticPoints}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticPoints (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 981, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 981, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticPoints", 1, 3, 3, 1); __PYX_ERR(0, 981, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 981, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcQuadraticPoints", 1, 3, 3, 2); __PYX_ERR(0, 981, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcQuadraticPoints") < 0)) __PYX_ERR(0, 981, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticPoints", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 981, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_y1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticPoints", 1); + + /* "fontTools/misc/bezierTools.py":982 + * + * def calcQuadraticPoints(a, b, c): + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c + */ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 982, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 982, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 982, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 982, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 982, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 982, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":983 + * def calcQuadraticPoints(a, b, c): + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * x1 = cx + */ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 983, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 983, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 983, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 983, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 983, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 983, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":984 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * x1 = cx + * y1 = cy + */ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 984, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 984, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 984, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 984, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 984, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 984, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":985 + * bx, by = b + * cx, cy = c + * x1 = cx # <<<<<<<<<<<<<< + * y1 = cy + * x2 = (bx * 0.5) + cx + */ + __Pyx_INCREF(__pyx_v_cx); + __pyx_v_x1 = __pyx_v_cx; + + /* "fontTools/misc/bezierTools.py":986 + * cx, cy = c + * x1 = cx + * y1 = cy # <<<<<<<<<<<<<< + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy + */ + __Pyx_INCREF(__pyx_v_cy); + __pyx_v_y1 = __pyx_v_cy; + + /* "fontTools/misc/bezierTools.py":987 + * x1 = cx + * y1 = cy + * x2 = (bx * 0.5) + cx # <<<<<<<<<<<<<< + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_bx, __pyx_float_0_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 987, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 987, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":988 + * y1 = cy + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy # <<<<<<<<<<<<<< + * x3 = ax + bx + cx + * y3 = ay + by + cy + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_by, __pyx_float_0_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 988, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 988, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":989 + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx # <<<<<<<<<<<<<< + * y3 = ay + by + cy + * return (x1, y1), (x2, y2), (x3, y3) + */ + __pyx_t_2 = PyNumber_Add(__pyx_v_ax, __pyx_v_bx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":990 + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx + * y3 = ay + by + cy # <<<<<<<<<<<<<< + * return (x1, y1), (x2, y2), (x3, y3) + * + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_ay, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_y3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":991 + * x3 = ax + bx + cx + * y3 = ay + by + cy + * return (x1, y1), (x2, y2), (x3, y3) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x1)) __PYX_ERR(0, 991, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y1); + __Pyx_GIVEREF(__pyx_v_y1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y1)) __PYX_ERR(0, 991, __pyx_L1_error); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x2)) __PYX_ERR(0, 991, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y2); + __Pyx_GIVEREF(__pyx_v_y2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y2)) __PYX_ERR(0, 991, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x3); + __Pyx_GIVEREF(__pyx_v_x3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x3)) __PYX_ERR(0, 991, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y3); + __Pyx_GIVEREF(__pyx_v_y3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_y3)) __PYX_ERR(0, 991, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2)) __PYX_ERR(0, 991, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1)) __PYX_ERR(0, 991, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 991, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":981 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_y1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":994 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_56calcCubicPoints, "calcCubicPoints(a, b, c, d)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_57calcCubicPoints = {"calcCubicPoints", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_56calcCubicPoints}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicPoints (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,&__pyx_n_s_d,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 994, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 994, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, 1); __PYX_ERR(0, 994, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 994, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, 2); __PYX_ERR(0, 994, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_d)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 994, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, 3); __PYX_ERR(0, 994, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "calcCubicPoints") < 0)) __PYX_ERR(0, 994, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 994, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_y1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_x4 = NULL; + PyObject *__pyx_v_y4 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicPoints", 1); + + /* "fontTools/misc/bezierTools.py":995 + * + * def calcCubicPoints(a, b, c, d): + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c + */ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 995, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 995, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 995, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 995, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 995, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":996 + * def calcCubicPoints(a, b, c, d): + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * dx, dy = d + */ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 996, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 996, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 996, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 996, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 996, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 996, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":997 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * dx, dy = d + * x1 = dx + */ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 997, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 997, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 997, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 997, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 997, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 997, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":998 + * bx, by = b + * cx, cy = c + * dx, dy = d # <<<<<<<<<<<<<< + * x1 = dx + * y1 = dy + */ + if ((likely(PyTuple_CheckExact(__pyx_v_d))) || (PyList_CheckExact(__pyx_v_d))) { + PyObject* sequence = __pyx_v_d; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 998, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_d); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 998, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 998, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_dy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":999 + * cx, cy = c + * dx, dy = d + * x1 = dx # <<<<<<<<<<<<<< + * y1 = dy + * x2 = (cx / 3.0) + dx + */ + __Pyx_INCREF(__pyx_v_dx); + __pyx_v_x1 = __pyx_v_dx; + + /* "fontTools/misc/bezierTools.py":1000 + * dx, dy = d + * x1 = dx + * y1 = dy # <<<<<<<<<<<<<< + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy + */ + __Pyx_INCREF(__pyx_v_dy); + __pyx_v_y1 = __pyx_v_dy; + + /* "fontTools/misc/bezierTools.py":1001 + * x1 = dx + * y1 = dy + * x2 = (cx / 3.0) + dx # <<<<<<<<<<<<<< + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 + */ + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_cx, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1001, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_dx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1001, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1002 + * y1 = dy + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy # <<<<<<<<<<<<<< + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 + */ + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_cy, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1003 + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 # <<<<<<<<<<<<<< + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_bx, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_x2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1004 + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 # <<<<<<<<<<<<<< + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_by, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_y2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1005 + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx # <<<<<<<<<<<<<< + * y4 = ay + dy + cy + by + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_ax, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x4 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1006 + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by # <<<<<<<<<<<<<< + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) + * + */ + __pyx_t_1 = PyNumber_Add(__pyx_v_ay, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1006, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1006, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1006, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y4 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1007 + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x1)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y1); + __Pyx_GIVEREF(__pyx_v_y1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y1)) __PYX_ERR(0, 1007, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x2)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y2); + __Pyx_GIVEREF(__pyx_v_y2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y2)) __PYX_ERR(0, 1007, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x3); + __Pyx_GIVEREF(__pyx_v_x3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x3)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y3); + __Pyx_GIVEREF(__pyx_v_y3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_y3)) __PYX_ERR(0, 1007, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_x4); + __Pyx_GIVEREF(__pyx_v_x4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_x4)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y4); + __Pyx_GIVEREF(__pyx_v_y4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_y4)) __PYX_ERR(0, 1007, __pyx_L1_error); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3)) __PYX_ERR(0, 1007, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5)) __PYX_ERR(0, 1007, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":994 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_y1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_x4); + __Pyx_XDECREF(__pyx_v_y4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1010 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d) { + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + __pyx_t_double_complex __pyx_v_p4; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicPointsC", 1); + + /* "fontTools/misc/bezierTools.py":1022 + * ) + * def calcCubicPointsC(a, b, c, d): + * p2 = c * (1 / 3) + d # <<<<<<<<<<<<<< + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d + */ + __pyx_v_p2 = __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_v_c, __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_d); + + /* "fontTools/misc/bezierTools.py":1023 + * def calcCubicPointsC(a, b, c, d): + * p2 = c * (1 / 3) + d + * p3 = (b + c) * (1 / 3) + p2 # <<<<<<<<<<<<<< + * p4 = a + b + c + d + * return (d, p2, p3, p4) + */ + __pyx_v_p3 = __Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_b, __pyx_v_c), __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_p2); + + /* "fontTools/misc/bezierTools.py":1024 + * p2 = c * (1 / 3) + d + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d # <<<<<<<<<<<<<< + * return (d, p2, p3, p4) + * + */ + __pyx_v_p4 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_a, __pyx_v_b), __pyx_v_c), __pyx_v_d); + + /* "fontTools/misc/bezierTools.py":1025 + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d + * return (d, p2, p3, p4) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_d); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_p4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1)) __PYX_ERR(0, 1025, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2)) __PYX_ERR(0, 1025, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3)) __PYX_ERR(0, 1025, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4)) __PYX_ERR(0, 1025, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1010 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPointsC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1033 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_58linePointAtT, "linePointAtT(pt1, pt2, t)\nFinds the point at time `t` on a line.\n\n Args:\n pt1, pt2: Coordinates of the line as 2D tuples.\n t: The time along the line.\n\n Returns:\n A 2D tuple with the coordinates of the point.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_59linePointAtT = {"linePointAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_58linePointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("linePointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("linePointAtT", 1, 3, 3, 1); __PYX_ERR(0, 1033, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("linePointAtT", 1, 3, 3, 2); __PYX_ERR(0, 1033, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "linePointAtT") < 0)) __PYX_ERR(0, 1033, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_t = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("linePointAtT", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1033, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.linePointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_t) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("linePointAtT", 1); + + /* "fontTools/misc/bezierTools.py":1043 + * A 2D tuple with the coordinates of the point. + * """ + * return ((pt1[0] * (1 - t) + pt2[0] * t), (pt1[1] * (1 - t) + pt2[1] * t)) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2)) __PYX_ERR(0, 1043, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(0, 1043, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1033 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools.linePointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1046 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_60quadraticPointAtT, "quadraticPointAtT(pt1, pt2, pt3, t)\nFinds the point at time `t` on a quadratic curve.\n\n Args:\n pt1, pt2, pt3: Coordinates of the curve as 2D tuples.\n t: The time along the curve.\n\n Returns:\n A 2D tuple with the coordinates of the point.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_61quadraticPointAtT = {"quadraticPointAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_60quadraticPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("quadraticPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, 1); __PYX_ERR(0, 1046, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, 2); __PYX_ERR(0, 1046, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, 3); __PYX_ERR(0, 1046, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "quadraticPointAtT") < 0)) __PYX_ERR(0, 1046, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_t = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 1046, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.quadraticPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_t) { + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("quadraticPointAtT", 1); + + /* "fontTools/misc/bezierTools.py":1056 + * A 2D tuple with the coordinates of the point. + * """ + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] # <<<<<<<<<<<<<< + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + * return (x, y) + */ + __pyx_t_1 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_t_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1056, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1057 + * """ + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] # <<<<<<<<<<<<<< + * return (x, y) + * + */ + __pyx_t_1 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_t_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt3, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1058 + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + * return (x, y) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1058, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x)) __PYX_ERR(0, 1058, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y)) __PYX_ERR(0, 1058, __pyx_L1_error); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1046 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools.quadraticPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1061 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_62cubicPointAtT, "cubicPointAtT(pt1, pt2, pt3, pt4, t)\nFinds the point at time `t` on a cubic curve.\n\n Args:\n pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples.\n t: The time along the curve.\n\n Returns:\n A 2D tuple with the coordinates of the point.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_63cubicPointAtT = {"cubicPointAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_62cubicPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("cubicPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, 1); __PYX_ERR(0, 1061, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, 2); __PYX_ERR(0, 1061, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, 3); __PYX_ERR(0, 1061, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, 4); __PYX_ERR(0, 1061, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "cubicPointAtT") < 0)) __PYX_ERR(0, 1061, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_t = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 1061, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_t) { + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v__1_t = NULL; + PyObject *__pyx_v__1_t_2 = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubicPointAtT", 1); + + /* "fontTools/misc/bezierTools.py":1071 + * A 2D tuple with the coordinates of the point. + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1071, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_t2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1072 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * x = ( + */ + __pyx_t_1 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1072, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__1_t = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1073 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * x = ( + * _1_t_2 * _1_t * pt1[0] + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v__1_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1073, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__1_t_2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1075 + * _1_t_2 = _1_t * _1_t + * x = ( + * _1_t_2 * _1_t * pt1[0] # <<<<<<<<<<<<<< + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + * + t2 * t * pt4[0] + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v__1_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1075, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1075, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1075, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1076 + * x = ( + * _1_t_2 * _1_t * pt1[0] + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) # <<<<<<<<<<<<<< + * + t2 * t * pt4[0] + * ) + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v_t2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_t_2, 3, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1076, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1077 + * _1_t_2 * _1_t * pt1[0] + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + * + t2 * t * pt4[0] # <<<<<<<<<<<<<< + * ) + * y = ( + */ + __pyx_t_5 = PyNumber_Multiply(__pyx_v_t2, __pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1077, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt4, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1077, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1077, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1077, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1080 + * ) + * y = ( + * _1_t_2 * _1_t * pt1[1] # <<<<<<<<<<<<<< + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + * + t2 * t * pt4[1] + */ + __pyx_t_3 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v__1_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1080, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1080, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1080, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1081 + * y = ( + * _1_t_2 * _1_t * pt1[1] + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) # <<<<<<<<<<<<<< + * + t2 * t * pt4[1] + * ) + */ + __pyx_t_4 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v_t2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_pt3, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyInt_MultiplyCObj(__pyx_int_3, __pyx_t_4, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1081, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1082 + * _1_t_2 * _1_t * pt1[1] + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + * + t2 * t * pt4[1] # <<<<<<<<<<<<<< + * ) + * return (x, y) + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t2, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt4, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1084 + * + t2 * t * pt4[1] + * ) + * return (x, y) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1084, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x)) __PYX_ERR(0, 1084, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y)) __PYX_ERR(0, 1084, __pyx_L1_error); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1061 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v__1_t); + __Pyx_XDECREF(__pyx_v__1_t_2); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1087 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_64cubicPointAtTC, "cubicPointAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double t)\nFinds the point at time `t` on a cubic curve.\n\n Args:\n pt1, pt2, pt3, pt4: Coordinates of the curve as complex numbers.\n t: The time along the curve.\n\n Returns:\n A complex number with the coordinates of the point.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_65cubicPointAtTC = {"cubicPointAtTC", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_64cubicPointAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_t; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("cubicPointAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pt1,&__pyx_n_s_pt2,&__pyx_n_s_pt3,&__pyx_n_s_pt4,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1087, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1087, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, 1); __PYX_ERR(0, 1087, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1087, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, 2); __PYX_ERR(0, 1087, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt4)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1087, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, 3); __PYX_ERR(0, 1087, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1087, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, 4); __PYX_ERR(0, 1087, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "cubicPointAtTC") < 0)) __PYX_ERR(0, 1087, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1096, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1096, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1096, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1096, __pyx_L3_error) + __pyx_v_t = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_t == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1096, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 1087, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t) { + double __pyx_v_t2; + double __pyx_v__1_t; + double __pyx_v__1_t_2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __pyx_t_double_complex __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubicPointAtTC", 1); + + /* "fontTools/misc/bezierTools.py":1106 + * A complex number with the coordinates of the point. + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + */ + __pyx_v_t2 = (__pyx_v_t * __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":1107 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + */ + __pyx_v__1_t = (1.0 - __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":1108 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + * + */ + __pyx_v__1_t_2 = (__pyx_v__1_t * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":1109 + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v__1_t), 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v_t), 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t * __pyx_v_t2), 0), __pyx_v_pt3)))), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v_t2 * __pyx_v_t), 0), __pyx_v_pt4)); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1087 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1112 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_66segmentPointAtT, "segmentPointAtT(seg, t)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_67segmentPointAtT = {"segmentPointAtT", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_66segmentPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_seg = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("segmentPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_seg,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_seg)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1112, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1112, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("segmentPointAtT", 1, 2, 2, 1); __PYX_ERR(0, 1112, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "segmentPointAtT") < 0)) __PYX_ERR(0, 1112, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_seg = values[0]; + __pyx_v_t = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("segmentPointAtT", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1112, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(__pyx_self, __pyx_v_seg, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg, PyObject *__pyx_v_t) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("segmentPointAtT", 1); + + /* "fontTools/misc/bezierTools.py":1113 + * + * def segmentPointAtT(seg, t): + * if len(seg) == 2: # <<<<<<<<<<<<<< + * return linePointAtT(*seg, t) + * elif len(seg) == 3: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1113, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 2); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1114 + * def segmentPointAtT(seg, t): + * if len(seg) == 2: + * return linePointAtT(*seg, t) # <<<<<<<<<<<<<< + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_linePointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t)) __PYX_ERR(0, 1114, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1113 + * + * def segmentPointAtT(seg, t): + * if len(seg) == 2: # <<<<<<<<<<<<<< + * return linePointAtT(*seg, t) + * elif len(seg) == 3: + */ + } + + /* "fontTools/misc/bezierTools.py":1115 + * if len(seg) == 2: + * return linePointAtT(*seg, t) + * elif len(seg) == 3: # <<<<<<<<<<<<<< + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1115, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1116 + * return linePointAtT(*seg, t) + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) # <<<<<<<<<<<<<< + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_quadraticPointAtT); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_t)) __PYX_ERR(0, 1116, __pyx_L1_error); + __pyx_t_4 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1115 + * if len(seg) == 2: + * return linePointAtT(*seg, t) + * elif len(seg) == 3: # <<<<<<<<<<<<<< + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: + */ + } + + /* "fontTools/misc/bezierTools.py":1117 + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: # <<<<<<<<<<<<<< + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") + */ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1117, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1118 + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_cubicPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t)) __PYX_ERR(0, 1118, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1117 + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: # <<<<<<<<<<<<<< + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") + */ + } + + /* "fontTools/misc/bezierTools.py":1119 + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_Raise(__pyx_t_5, 0, 0, 0); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_ERR(0, 1119, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1112 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1127 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_68_line_t_of_pt, "_line_t_of_pt(s, e, pt)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_69_line_t_of_pt = {"_line_t_of_pt", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_68_line_t_of_pt}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_s = 0; + PyObject *__pyx_v_e = 0; + PyObject *__pyx_v_pt = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_line_t_of_pt (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_s,&__pyx_n_s_e,&__pyx_n_s_pt,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_s)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1127, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_e)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_line_t_of_pt", 1, 3, 3, 1); __PYX_ERR(0, 1127, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pt)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1127, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_line_t_of_pt", 1, 3, 3, 2); __PYX_ERR(0, 1127, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_line_t_of_pt") < 0)) __PYX_ERR(0, 1127, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_s = values[0]; + __pyx_v_e = values[1]; + __pyx_v_pt = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_line_t_of_pt", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1127, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._line_t_of_pt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(__pyx_self, __pyx_v_s, __pyx_v_e, __pyx_v_pt); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_pt) { + PyObject *__pyx_v_sx = NULL; + PyObject *__pyx_v_sy = NULL; + PyObject *__pyx_v_ex = NULL; + PyObject *__pyx_v_ey = NULL; + PyObject *__pyx_v_px = NULL; + PyObject *__pyx_v_py = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_line_t_of_pt", 1); + + /* "fontTools/misc/bezierTools.py":1128 + * + * def _line_t_of_pt(s, e, pt): + * sx, sy = s # <<<<<<<<<<<<<< + * ex, ey = e + * px, py = pt + */ + if ((likely(PyTuple_CheckExact(__pyx_v_s))) || (PyList_CheckExact(__pyx_v_s))) { + PyObject* sequence = __pyx_v_s; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1128, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1128, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1128, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1128, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1128, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1128, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_sx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_sy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1129 + * def _line_t_of_pt(s, e, pt): + * sx, sy = s + * ex, ey = e # <<<<<<<<<<<<<< + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + */ + if ((likely(PyTuple_CheckExact(__pyx_v_e))) || (PyList_CheckExact(__pyx_v_e))) { + PyObject* sequence = __pyx_v_e; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1129, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1129, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1129, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ex = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ey = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1130 + * sx, sy = s + * ex, ey = e + * px, py = pt # <<<<<<<<<<<<<< + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + * # Line is a point! + */ + if ((likely(PyTuple_CheckExact(__pyx_v_pt))) || (PyList_CheckExact(__pyx_v_pt))) { + PyObject* sequence = __pyx_v_pt; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1130, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1130, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1130, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_px = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_py = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1131 + * ex, ey = e + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: # <<<<<<<<<<<<<< + * # Line is a point! + * return -1 + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_sx, __pyx_v_ex); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L10_bool_binop_done; + } + __pyx_t_3 = PyNumber_Subtract(__pyx_v_sy, __pyx_v_ey); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyNumber_Absolute(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1131, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_6; + __pyx_L10_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1133 + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + * # Line is a point! + * return -1 # <<<<<<<<<<<<<< + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_int_neg_1); + __pyx_r = __pyx_int_neg_1; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1131 + * ex, ey = e + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: # <<<<<<<<<<<<<< + * # Line is a point! + * return -1 + */ + } + + /* "fontTools/misc/bezierTools.py":1135 + * return -1 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): # <<<<<<<<<<<<<< + * return (px - sx) / (ex - sx) + * else: + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_sx, __pyx_v_ex); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_v_sy, __pyx_v_ey); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyNumber_Absolute(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1136 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): + * return (px - sx) / (ex - sx) # <<<<<<<<<<<<<< + * else: + * return (py - sy) / (ey - sy) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyNumber_Subtract(__pyx_v_px, __pyx_v_sx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_v_ex, __pyx_v_sx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1135 + * return -1 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): # <<<<<<<<<<<<<< + * return (px - sx) / (ex - sx) + * else: + */ + } + + /* "fontTools/misc/bezierTools.py":1138 + * return (px - sx) / (ex - sx) + * else: + * return (py - sy) / (ey - sy) # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_py, __pyx_v_sy); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Subtract(__pyx_v_ey, __pyx_v_sy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1127 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._line_t_of_pt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sx); + __Pyx_XDECREF(__pyx_v_sy); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_XDECREF(__pyx_v_ey); + __Pyx_XDECREF(__pyx_v_px); + __Pyx_XDECREF(__pyx_v_py); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1141 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin, "_both_points_are_on_same_side_of_origin(a, b, origin)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin = {"_both_points_are_on_same_side_of_origin", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_origin = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_both_points_are_on_same_side_of_origin (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_origin,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_a)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1141, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_b)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1141, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_both_points_are_on_same_side_of_origin", 1, 3, 3, 1); __PYX_ERR(0, 1141, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_origin)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1141, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_both_points_are_on_same_side_of_origin", 1, 3, 3, 2); __PYX_ERR(0, 1141, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_both_points_are_on_same_side_of_origin") < 0)) __PYX_ERR(0, 1141, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_origin = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_both_points_are_on_same_side_of_origin", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1141, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._both_points_are_on_same_side_of_origin", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_origin); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_origin) { + PyObject *__pyx_v_xDiff = NULL; + PyObject *__pyx_v_yDiff = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_both_points_are_on_same_side_of_origin", 1); + + /* "fontTools/misc/bezierTools.py":1142 + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) # <<<<<<<<<<<<<< + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + * return not (xDiff <= 0.0 and yDiff <= 0.0) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_origin, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_origin, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_xDiff = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1143 + * def _both_points_are_on_same_side_of_origin(a, b, origin): + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) # <<<<<<<<<<<<<< + * return not (xDiff <= 0.0 and yDiff <= 0.0) + * + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_origin, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_origin, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_yDiff = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1144 + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + * return not (xDiff <= 0.0 and yDiff <= 0.0) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyObject_RichCompare(__pyx_v_xDiff, __pyx_float_0_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1144, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L3_bool_binop_done; + } + __pyx_t_1 = PyObject_RichCompare(__pyx_v_yDiff, __pyx_float_0_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1144, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_6; + __pyx_L3_bool_binop_done:; + __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_5)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1141 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools._both_points_are_on_same_side_of_origin", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_xDiff); + __Pyx_XDECREF(__pyx_v_yDiff); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1147 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_72lineLineIntersections, "lineLineIntersections(s1, e1, s2, e2)\nFinds intersections between two line segments.\n\n Args:\n s1, e1: Coordinates of the first line as 2D tuples.\n s2, e2: Coordinates of the second line as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n\n >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367))\n >>> len(a)\n 1\n >>> intersection = a[0]\n >>> intersection.pt\n (374.44882952482897, 313.73458370177315)\n >>> (intersection.t1, intersection.t2)\n (0.45069111555824465, 0.5408153767394238)\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_73lineLineIntersections = {"lineLineIntersections", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_72lineLineIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_s1 = 0; + PyObject *__pyx_v_e1 = 0; + PyObject *__pyx_v_s2 = 0; + PyObject *__pyx_v_e2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("lineLineIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_s1,&__pyx_n_s_e1,&__pyx_n_s_s2,&__pyx_n_s_e2,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_s1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1147, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_e1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1147, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, 1); __PYX_ERR(0, 1147, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_s2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1147, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, 2); __PYX_ERR(0, 1147, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_e2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1147, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, 3); __PYX_ERR(0, 1147, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "lineLineIntersections") < 0)) __PYX_ERR(0, 1147, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_s1 = values[0]; + __pyx_v_e1 = values[1]; + __pyx_v_s2 = values[2]; + __pyx_v_e2 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 1147, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.lineLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(__pyx_self, __pyx_v_s1, __pyx_v_e1, __pyx_v_s2, __pyx_v_e2); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s1, PyObject *__pyx_v_e1, PyObject *__pyx_v_s2, PyObject *__pyx_v_e2) { + PyObject *__pyx_v_s1x = NULL; + PyObject *__pyx_v_s1y = NULL; + PyObject *__pyx_v_e1x = NULL; + PyObject *__pyx_v_e1y = NULL; + PyObject *__pyx_v_s2x = NULL; + PyObject *__pyx_v_s2y = NULL; + PyObject *__pyx_v_e2x = NULL; + PyObject *__pyx_v_e2y = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_slope34 = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_v_pt = NULL; + PyObject *__pyx_v_slope12 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("lineLineIntersections", 1); + + /* "fontTools/misc/bezierTools.py":1170 + * (0.45069111555824465, 0.5408153767394238) + * """ + * s1x, s1y = s1 # <<<<<<<<<<<<<< + * e1x, e1y = e1 + * s2x, s2y = s2 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_s1))) || (PyList_CheckExact(__pyx_v_s1))) { + PyObject* sequence = __pyx_v_s1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1170, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1170, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1170, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1170, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1170, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1170, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_s1x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_s1y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1171 + * """ + * s1x, s1y = s1 + * e1x, e1y = e1 # <<<<<<<<<<<<<< + * s2x, s2y = s2 + * e2x, e2y = e2 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_e1))) || (PyList_CheckExact(__pyx_v_e1))) { + PyObject* sequence = __pyx_v_e1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1171, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1171, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1171, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_e1x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_e1y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1172 + * s1x, s1y = s1 + * e1x, e1y = e1 + * s2x, s2y = s2 # <<<<<<<<<<<<<< + * e2x, e2y = e2 + * if ( + */ + if ((likely(PyTuple_CheckExact(__pyx_v_s2))) || (PyList_CheckExact(__pyx_v_s2))) { + PyObject* sequence = __pyx_v_s2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1172, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1172, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1172, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_s2x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_s2y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1173 + * e1x, e1y = e1 + * s2x, s2y = s2 + * e2x, e2y = e2 # <<<<<<<<<<<<<< + * if ( + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + */ + if ((likely(PyTuple_CheckExact(__pyx_v_e2))) || (PyList_CheckExact(__pyx_v_e2))) { + PyObject* sequence = __pyx_v_e2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1173, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1173, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1173, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_e2x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_e2y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1175 + * e2x, e2y = e2 + * if ( + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) # <<<<<<<<<<<<<< + * ): # Parallel vertical + * return [] + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_5 = __pyx_t_7; + goto __pyx_L12_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1x, __pyx_v_e1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_5 = __pyx_t_7; + goto __pyx_L12_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s1x, __pyx_v_s2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1175, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (!__pyx_t_7); + __pyx_t_5 = __pyx_t_8; + __pyx_L12_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1174 + * s2x, s2y = s2 + * e2x, e2y = e2 + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical + */ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1177 + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical + * return [] # <<<<<<<<<<<<<< + * if ( + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1174 + * s2x, s2y = s2 + * e2x, e2y = e2 + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical + */ + } + + /* "fontTools/misc/bezierTools.py":1179 + * return [] + * if ( + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) # <<<<<<<<<<<<<< + * ): # Parallel horizontal + * return [] + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s2y, __pyx_v_e2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L16_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s1y, __pyx_v_e1y}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L16_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1y, __pyx_v_s2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (!__pyx_t_8); + __pyx_t_5 = __pyx_t_7; + __pyx_L16_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1178 + * ): # Parallel vertical + * return [] + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal + */ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1181 + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal + * return [] # <<<<<<<<<<<<<< + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1178 + * ): # Parallel vertical + * return [] + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal + */ + } + + /* "fontTools/misc/bezierTools.py":1182 + * ): # Parallel horizontal + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_5 = __pyx_t_7; + goto __pyx_L20_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s2y, __pyx_v_e2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_7; + __pyx_L20_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1183 + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] # <<<<<<<<<<<<<< + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1182 + * ): # Parallel horizontal + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + */ + } + + /* "fontTools/misc/bezierTools.py":1184 + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(e1x, s1x): + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s1x, __pyx_v_e1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_5 = __pyx_t_7; + goto __pyx_L23_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1y, __pyx_v_e1y}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_7; + __pyx_L23_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1185 + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] # <<<<<<<<<<<<<< + * if math.isclose(e1x, s1x): + * x = s1x + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1185, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1184 + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(e1x, s1x): + */ + } + + /* "fontTools/misc/bezierTools.py":1186 + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] + * if math.isclose(e1x, s1x): # <<<<<<<<<<<<<< + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_e1x, __pyx_v_s1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1187 + * return [] + * if math.isclose(e1x, s1x): + * x = s1x # <<<<<<<<<<<<<< + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y + */ + __Pyx_INCREF(__pyx_v_s1x); + __pyx_v_x = __pyx_v_s1x; + + /* "fontTools/misc/bezierTools.py":1188 + * if math.isclose(e1x, s1x): + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) # <<<<<<<<<<<<<< + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_e2y, __pyx_v_s2y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_e2x, __pyx_v_s2x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_slope34 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1189 + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y # <<<<<<<<<<<<<< + * pt = (x, y) + * return [ + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s2x); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_v_slope34, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_v_s2y); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1190 + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) # <<<<<<<<<<<<<< + * return [ + * Intersection( + */ + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1190, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x)) __PYX_ERR(0, 1190, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y)) __PYX_ERR(0, 1190, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1191 + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1192 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":1193 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] + */ + __pyx_t_3 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_pt, __pyx_v_pt) < 0) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_t1, __pyx_t_1) < 0) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_t2, __pyx_t_1) < 0) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1192 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1191 + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 1191, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1186 + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] + * if math.isclose(e1x, s1x): # <<<<<<<<<<<<<< + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) + */ + } + + /* "fontTools/misc/bezierTools.py":1196 + * ) + * ] + * if math.isclose(s2x, e2x): # <<<<<<<<<<<<<< + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_math); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1197 + * ] + * if math.isclose(s2x, e2x): + * x = s2x # <<<<<<<<<<<<<< + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y + */ + __Pyx_INCREF(__pyx_v_s2x); + __pyx_v_x = __pyx_v_s2x; + + /* "fontTools/misc/bezierTools.py":1198 + * if math.isclose(s2x, e2x): + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) # <<<<<<<<<<<<<< + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + */ + __pyx_t_3 = PyNumber_Subtract(__pyx_v_e1y, __pyx_v_s1y); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1198, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Subtract(__pyx_v_e1x, __pyx_v_s1x); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1198, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1198, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_slope12 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1199 + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y # <<<<<<<<<<<<<< + * pt = (x, y) + * return [ + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s1x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_v_slope12, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_s1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1200 + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) # <<<<<<<<<<<<<< + * return [ + * Intersection( + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1200, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x)) __PYX_ERR(0, 1200, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y)) __PYX_ERR(0, 1200, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1201 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1202 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1202, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1203 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_pt, __pyx_v_pt) < 0) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_t1, __pyx_t_3) < 0) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_t2, __pyx_t_3) < 0) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1202 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1202, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1201 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1201, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_3)) __PYX_ERR(0, 1201, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1196 + * ) + * ] + * if math.isclose(s2x, e2x): # <<<<<<<<<<<<<< + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) + */ + } + + /* "fontTools/misc/bezierTools.py":1207 + * ] + * + * slope12 = (e1y - s1y) / (e1x - s1x) # <<<<<<<<<<<<<< + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): + */ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_e1y, __pyx_v_s1y); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_e1x, __pyx_v_s1x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_slope12 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1208 + * + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) # <<<<<<<<<<<<<< + * if math.isclose(slope12, slope34): + * return [] + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_e2y, __pyx_v_s2y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1208, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_e2x, __pyx_v_s2x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1208, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1208, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_slope34 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1209 + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): # <<<<<<<<<<<<<< + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isclose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_slope12, __pyx_v_slope34}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1210 + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): + * return [] # <<<<<<<<<<<<<< + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1210, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1209 + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): # <<<<<<<<<<<<<< + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + */ + } + + /* "fontTools/misc/bezierTools.py":1211 + * if math.isclose(slope12, slope34): + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) # <<<<<<<<<<<<<< + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + */ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_slope12, __pyx_v_s1x); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_s1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_slope34, __pyx_v_s2x); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_v_s2y); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Subtract(__pyx_v_slope12, __pyx_v_slope34); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1212 + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y # <<<<<<<<<<<<<< + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( + */ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s1x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Multiply(__pyx_v_slope12, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_v_s1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1213 + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) # <<<<<<<<<<<<<< + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1213, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x)) __PYX_ERR(0, 1213, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y)) __PYX_ERR(0, 1213, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1214 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_both_points_are_on_same_side_of); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":1215 + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 # <<<<<<<<<<<<<< + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ + */ + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_pt, __pyx_v_e1, __pyx_v_s1}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + + /* "fontTools/misc/bezierTools.py":1214 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + */ + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_5 = __pyx_t_7; + goto __pyx_L29_bool_binop_done; + } + + /* "fontTools/misc/bezierTools.py":1216 + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): # <<<<<<<<<<<<<< + * return [ + * Intersection( + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_both_points_are_on_same_side_of); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_pt, __pyx_v_s2, __pyx_v_e2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_7; + __pyx_L29_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1214 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + */ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1217 + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1218 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1219 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] + */ + __pyx_t_3 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_pt, __pyx_v_pt) < 0) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_t1, __pyx_t_2) < 0) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_t2, __pyx_t_2) < 0) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1218 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) + */ + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1217 + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + */ + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1217, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 1217, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1214 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + */ + } + + /* "fontTools/misc/bezierTools.py":1222 + * ) + * ] + * return [] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1147 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.misc.bezierTools.lineLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_s1x); + __Pyx_XDECREF(__pyx_v_s1y); + __Pyx_XDECREF(__pyx_v_e1x); + __Pyx_XDECREF(__pyx_v_e1y); + __Pyx_XDECREF(__pyx_v_s2x); + __Pyx_XDECREF(__pyx_v_s2y); + __Pyx_XDECREF(__pyx_v_e2x); + __Pyx_XDECREF(__pyx_v_e2y); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_slope34); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XDECREF(__pyx_v_pt); + __Pyx_XDECREF(__pyx_v_slope12); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1225 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_74_alignment_transformation, "_alignment_transformation(segment)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_75_alignment_transformation = {"_alignment_transformation", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_74_alignment_transformation}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segment = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_alignment_transformation (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_segment,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_segment)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1225, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_alignment_transformation") < 0)) __PYX_ERR(0, 1225, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_segment = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_alignment_transformation", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1225, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._alignment_transformation", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(__pyx_self, __pyx_v_segment); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment) { + PyObject *__pyx_v_start = NULL; + PyObject *__pyx_v_end = NULL; + PyObject *__pyx_v_angle = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_alignment_transformation", 1); + + /* "fontTools/misc/bezierTools.py":1229 + * # origin. Apply this transformation to curves and root-find to find + * # intersections with the segment. + * start = segment[0] # <<<<<<<<<<<<<< + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_segment, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_start = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1230 + * # intersections with the segment. + * start = segment[0] + * end = segment[-1] # <<<<<<<<<<<<<< + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) + * return Identity.rotate(-angle).translate(-start[0], -start[1]) + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_segment, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_end = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1231 + * start = segment[0] + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) # <<<<<<<<<<<<<< + * return Identity.rotate(-angle).translate(-start[0], -start[1]) + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_atan2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_end, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_start, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyNumber_Subtract(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_end, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_start, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyNumber_Subtract(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_5, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_angle = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1232 + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) + * return Identity.rotate(-angle).translate(-start[0], -start[1]) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Identity); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_rotate); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Negative(__pyx_v_angle); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_6}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_translate); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_start, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyNumber_Negative(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_start, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Negative(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_t_6, __pyx_t_2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1225 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools._alignment_transformation", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_start); + __Pyx_XDECREF(__pyx_v_end); + __Pyx_XDECREF(__pyx_v_angle); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1235 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t, "_curve_line_intersections_t(curve, line)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t = {"_curve_line_intersections_t", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve = 0; + PyObject *__pyx_v_line = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_line_intersections_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curve,&__pyx_n_s_line,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1235, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_line)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1235, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_curve_line_intersections_t", 1, 2, 2, 1); __PYX_ERR(0, 1235, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_curve_line_intersections_t") < 0)) __PYX_ERR(0, 1235, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_curve = values[0]; + __pyx_v_line = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_line_intersections_t", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1235, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(__pyx_self, __pyx_v_curve, __pyx_v_line); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1245 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1245, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_curve_line_intersections_t_loca, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1245, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1245, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1245, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1245, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1245, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1245, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1245, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_i, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_float_0_0, __pyx_cur_scope->__pyx_v_i, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_i, __pyx_int_1, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_i))) __PYX_ERR(0, 1245, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1235 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line) { + PyObject *__pyx_v_aligned_curve = NULL; + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *(*__pyx_t_9)(PyObject *); + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_line_intersections_t", 1); + + /* "fontTools/misc/bezierTools.py":1236 + * + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) # <<<<<<<<<<<<<< + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_alignment_transformation); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_line}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_transformPoints); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_curve}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_aligned_curve = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1237 + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: # <<<<<<<<<<<<<< + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + */ + __pyx_t_6 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1237, __pyx_L1_error) + __pyx_t_7 = (__pyx_t_6 == 3); + if (__pyx_t_7) { + + /* "fontTools/misc/bezierTools.py":1238 + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) # <<<<<<<<<<<<<< + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_calcQuadraticParameters); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_aligned_curve); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1238, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + __pyx_t_4 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_8 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8); + index = 0; __pyx_t_3 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_1 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_1)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 2; __pyx_t_4 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_4)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) __PYX_ERR(0, 1238, __pyx_L1_error) + __pyx_t_9 = NULL; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_9 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1238, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_c = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1239 + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) # <<<<<<<<<<<<<< + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_solveQuadratic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_c, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_10 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_t_1, __pyx_t_3, __pyx_t_8}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __pyx_v_intersections = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1237 + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: # <<<<<<<<<<<<<< + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + */ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1240 + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + */ + __pyx_t_6 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1240, __pyx_L1_error) + __pyx_t_7 = (__pyx_t_6 == 4); + if (likely(__pyx_t_7)) { + + /* "fontTools/misc/bezierTools.py":1241 + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) # <<<<<<<<<<<<<< + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + * else: + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_calcCubicParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_aligned_curve); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_8))) || (PyList_CheckExact(__pyx_t_8))) { + PyObject* sequence = __pyx_t_8; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1241, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_4 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + __pyx_t_3 = PyList_GET_ITEM(sequence, 2); + __pyx_t_1 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_4,&__pyx_t_2,&__pyx_t_3,&__pyx_t_1}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 1241, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_4,&__pyx_t_2,&__pyx_t_3,&__pyx_t_1}; + __pyx_t_10 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_9(__pyx_t_10); if (unlikely(!item)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_10), 4) < 0) __PYX_ERR(0, 1241, __pyx_L1_error) + __pyx_t_9 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_9 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1241, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __pyx_v_a = __pyx_t_4; + __pyx_t_4 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_d = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1242 + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) # <<<<<<<<<<<<<< + * else: + * raise ValueError("Unknown curve degree") + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_solveCubic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_c, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_d, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_11, __pyx_t_3, __pyx_t_2, __pyx_t_4, __pyx_t_10}; + __pyx_t_8 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_5, 4+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_v_intersections = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":1240 + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + */ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1244 + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + * else: + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * return sorted(i for i in intersections if 0.0 <= i <= 1) + * + */ + /*else*/ { + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(0, 1244, __pyx_L1_error) + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":1245 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(NULL, __pyx_v_intersections); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_Generator_Next(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = ((PyObject*)__pyx_t_10); + __pyx_t_10 = 0; + __pyx_t_12 = PyList_Sort(__pyx_t_8); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 1245, __pyx_L1_error) + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1235 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_aligned_curve); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1248 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_78curveLineIntersections, "curveLineIntersections(curve, line)\nFinds intersections between a curve and a line.\n\n Args:\n curve: List of coordinates of the curve segment as 2D tuples.\n line: List of coordinates of the line segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = curveLineIntersections(curve, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_79curveLineIntersections = {"curveLineIntersections", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_78curveLineIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve = 0; + PyObject *__pyx_v_line = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curveLineIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curve,&__pyx_n_s_line,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1248, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_line)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1248, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("curveLineIntersections", 1, 2, 2, 1); __PYX_ERR(0, 1248, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "curveLineIntersections") < 0)) __PYX_ERR(0, 1248, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_curve = values[0]; + __pyx_v_line = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curveLineIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1248, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(__pyx_self, __pyx_v_curve, __pyx_v_line); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line) { + PyObject *__pyx_v_pointFinder = NULL; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_v_t = NULL; + PyObject *__pyx_v_pt = NULL; + PyObject *__pyx_v_line_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curveLineIntersections", 1); + + /* "fontTools/misc/bezierTools.py":1269 + * (84.9000930760723, 189.87306176459828) + * """ + * if len(curve) == 3: # <<<<<<<<<<<<<< + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1269, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1270 + * """ + * if len(curve) == 3: + * pointFinder = quadraticPointAtT # <<<<<<<<<<<<<< + * elif len(curve) == 4: + * pointFinder = cubicPointAtT + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_quadraticPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1270, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_pointFinder = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1269 + * (84.9000930760723, 189.87306176459828) + * """ + * if len(curve) == 3: # <<<<<<<<<<<<<< + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: + */ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1271 + * if len(curve) == 3: + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * pointFinder = cubicPointAtT + * else: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1271, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (likely(__pyx_t_2)) { + + /* "fontTools/misc/bezierTools.py":1272 + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: + * pointFinder = cubicPointAtT # <<<<<<<<<<<<<< + * else: + * raise ValueError("Unknown curve degree") + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_cubicPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1272, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_pointFinder = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1271 + * if len(curve) == 3: + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * pointFinder = cubicPointAtT + * else: + */ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1274 + * pointFinder = cubicPointAtT + * else: + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1274, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 1274, __pyx_L1_error) + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":1275 + * else: + * raise ValueError("Unknown curve degree") + * intersections = [] # <<<<<<<<<<<<<< + * for t in _curve_line_intersections_t(curve, line): + * pt = pointFinder(*curve, t) + */ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_intersections = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1276 + * raise ValueError("Unknown curve degree") + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * pt = pointFinder(*curve, t) + * # Back-project the point onto the line, to avoid problems with + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_curve_line_intersections_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_v_curve, __pyx_v_line}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) { + __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); + __pyx_t_1 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_1 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1276, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_4))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_4); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1276, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_3); __pyx_t_1++; if (unlikely((0 < 0))) __PYX_ERR(0, 1276, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_4); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1276, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_3); __pyx_t_1++; if (unlikely((0 < 0))) __PYX_ERR(0, 1276, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } + } else { + __pyx_t_3 = __pyx_t_7(__pyx_t_4); + if (unlikely(!__pyx_t_3)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1276, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1277 + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): + * pt = pointFinder(*curve, t) # <<<<<<<<<<<<<< + * # Back-project the point onto the line, to avoid problems with + * # numerical accuracy in the case of vertical and horizontal lines + */ + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_curve); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t)) __PYX_ERR(0, 1277, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_v_pointFinder, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1280 + * # Back-project the point onto the line, to avoid problems with + * # numerical accuracy in the case of vertical and horizontal lines + * line_t = _line_t_of_pt(*line, pt) # <<<<<<<<<<<<<< + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_line_t_of_pt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_line); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_pt); + __Pyx_GIVEREF(__pyx_v_pt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_pt)) __PYX_ERR(0, 1280, __pyx_L1_error); + __pyx_t_9 = PyNumber_Add(__pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_line_t, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1281 + * # numerical accuracy in the case of vertical and horizontal lines + * line_t = _line_t_of_pt(*line, pt) + * pt = linePointAtT(*line, line_t) # <<<<<<<<<<<<<< + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + * return intersections + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_linePointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PySequence_Tuple(__pyx_v_line); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_line_t); + __Pyx_GIVEREF(__pyx_v_line_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_line_t)) __PYX_ERR(0, 1281, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_9, __pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF_SET(__pyx_v_pt, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1282 + * line_t = _line_t_of_pt(*line, pt) + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) # <<<<<<<<<<<<<< + * return intersections + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_8 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_pt, __pyx_v_pt) < 0) __PYX_ERR(0, 1282, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_t1, __pyx_v_t) < 0) __PYX_ERR(0, 1282, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_t2, __pyx_v_line_t) < 0) __PYX_ERR(0, 1282, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_intersections, __pyx_t_3); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1282, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1276 + * raise ValueError("Unknown curve degree") + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * pt = pointFinder(*curve, t) + * # Back-project the point onto the line, to avoid problems with + */ + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1283 + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + * return intersections # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_intersections); + __pyx_r = __pyx_v_intersections; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1248 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_pointFinder); + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_XDECREF(__pyx_v_pt); + __Pyx_XDECREF(__pyx_v_line_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1286 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_80_curve_bounds, "_curve_bounds(c)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_81_curve_bounds = {"_curve_bounds", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_80_curve_bounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_c = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_bounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_c,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1286, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_curve_bounds") < 0)) __PYX_ERR(0, 1286, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_c = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_bounds", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1286, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_bounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(__pyx_self, __pyx_v_c); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_bounds", 1); + + /* "fontTools/misc/bezierTools.py":1287 + * + * def _curve_bounds(c): + * if len(c) == 3: # <<<<<<<<<<<<<< + * return calcQuadraticBounds(*c) + * elif len(c) == 4: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1287, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1288 + * def _curve_bounds(c): + * if len(c) == 3: + * return calcQuadraticBounds(*c) # <<<<<<<<<<<<<< + * elif len(c) == 4: + * return calcCubicBounds(*c) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_calcQuadraticBounds); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1287 + * + * def _curve_bounds(c): + * if len(c) == 3: # <<<<<<<<<<<<<< + * return calcQuadraticBounds(*c) + * elif len(c) == 4: + */ + } + + /* "fontTools/misc/bezierTools.py":1289 + * if len(c) == 3: + * return calcQuadraticBounds(*c) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") + */ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1289, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1290 + * return calcQuadraticBounds(*c) + * elif len(c) == 4: + * return calcCubicBounds(*c) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_calcCubicBounds); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1290, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1290, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1290, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1289 + * if len(c) == 3: + * return calcQuadraticBounds(*c) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") + */ + } + + /* "fontTools/misc/bezierTools.py":1291 + * elif len(c) == 4: + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1291, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 1291, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1286 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_bounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1294 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_82_split_segment_at_t, "_split_segment_at_t(c, t)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_83_split_segment_at_t = {"_split_segment_at_t", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_82_split_segment_at_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_segment_at_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_c,&__pyx_n_s_t,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_c)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1294, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1294, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_split_segment_at_t", 1, 2, 2, 1); __PYX_ERR(0, 1294, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_split_segment_at_t") < 0)) __PYX_ERR(0, 1294, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_c = values[0]; + __pyx_v_t = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_split_segment_at_t", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1294, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_segment_at_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(__pyx_self, __pyx_v_c, __pyx_v_t); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c, PyObject *__pyx_v_t) { + PyObject *__pyx_v_s = NULL; + PyObject *__pyx_v_e = NULL; + PyObject *__pyx_v_midpoint = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_split_segment_at_t", 1); + + /* "fontTools/misc/bezierTools.py":1295 + * + * def _split_segment_at_t(c, t): + * if len(c) == 2: # <<<<<<<<<<<<<< + * s, e = c + * midpoint = linePointAtT(s, e, t) + */ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1295, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 2); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1296 + * def _split_segment_at_t(c, t): + * if len(c) == 2: + * s, e = c # <<<<<<<<<<<<<< + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] + */ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1296, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_4 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 1296, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1296, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_s = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_e = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1297 + * if len(c) == 2: + * s, e = c + * midpoint = linePointAtT(s, e, t) # <<<<<<<<<<<<<< + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_linePointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_5, __pyx_v_s, __pyx_v_e, __pyx_v_t}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_7, 3+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_midpoint = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1298 + * s, e = c + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] # <<<<<<<<<<<<<< + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_s); + __Pyx_GIVEREF(__pyx_v_s); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_s)) __PYX_ERR(0, 1298, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_midpoint); + __Pyx_GIVEREF(__pyx_v_midpoint); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_midpoint)) __PYX_ERR(0, 1298, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_midpoint); + __Pyx_GIVEREF(__pyx_v_midpoint); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_midpoint)) __PYX_ERR(0, 1298, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_e); + __Pyx_GIVEREF(__pyx_v_e); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_e)) __PYX_ERR(0, 1298, __pyx_L1_error); + __pyx_t_5 = PyList_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_t_4)) __PYX_ERR(0, 1298, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 1, __pyx_t_3)) __PYX_ERR(0, 1298, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1295 + * + * def _split_segment_at_t(c, t): + * if len(c) == 2: # <<<<<<<<<<<<<< + * s, e = c + * midpoint = linePointAtT(s, e, t) + */ + } + + /* "fontTools/misc/bezierTools.py":1299 + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: # <<<<<<<<<<<<<< + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: + */ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1299, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1300 + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) # <<<<<<<<<<<<<< + * elif len(c) == 4: + * return splitCubicAtT(*c, t) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_splitQuadraticAtT_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_t)) __PYX_ERR(0, 1300, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1300, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1299 + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: # <<<<<<<<<<<<<< + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: + */ + } + + /* "fontTools/misc/bezierTools.py":1301 + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") + */ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1301, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1302 + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: + * return splitCubicAtT(*c, t) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_splitCubicAtT_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t)) __PYX_ERR(0, 1302, __pyx_L1_error); + __pyx_t_3 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1301 + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") + */ + } + + /* "fontTools/misc/bezierTools.py":1303 + * elif len(c) == 4: + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_Raise(__pyx_t_5, 0, 0, 0); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_ERR(0, 1303, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1294 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_segment_at_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_s); + __Pyx_XDECREF(__pyx_v_e); + __Pyx_XDECREF(__pyx_v_midpoint); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t, "_curve_curve_intersections_t(curve1, curve2, precision=1e-3, range1=None, range2=None)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t = {"_curve_curve_intersections_t", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve1 = 0; + PyObject *__pyx_v_curve2 = 0; + PyObject *__pyx_v_precision = 0; + PyObject *__pyx_v_range1 = 0; + PyObject *__pyx_v_range2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_curve_intersections_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curve1,&__pyx_n_s_curve2,&__pyx_n_s_precision,&__pyx_n_s_range1,&__pyx_n_s_range2,0}; + values[2] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)((PyObject*)__pyx_float_1eneg_3))); + + /* "fontTools/misc/bezierTools.py":1307 + * + * def _curve_curve_intersections_t( + * curve1, curve2, precision=1e-3, range1=None, range2=None # <<<<<<<<<<<<<< + * ): + * bounds1 = _curve_bounds(curve1) + */ + values[3] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)Py_None)); + values[4] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)Py_None)); + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1306, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1306, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_curve_curve_intersections_t", 0, 2, 5, 1); __PYX_ERR(0, 1306, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_precision); + if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1306, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_range1); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1306, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_range2); + if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1306, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_curve_curve_intersections_t") < 0)) __PYX_ERR(0, 1306, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_curve1 = values[0]; + __pyx_v_curve2 = values[1]; + __pyx_v_precision = values[2]; + __pyx_v_range1 = values[3]; + __pyx_v_range2 = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_curve_intersections_t", 0, 2, 5, __pyx_nargs); __PYX_ERR(0, 1306, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(__pyx_self, __pyx_v_curve1, __pyx_v_curve2, __pyx_v_precision, __pyx_v_range1, __pyx_v_range2); + + /* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1322 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint = {"midpoint", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_r = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("midpoint (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_r,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_r)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1322, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "midpoint") < 0)) __PYX_ERR(0, 1322, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_r = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("midpoint", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1322, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.midpoint", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_self, __pyx_v_r); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_r) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("midpoint", 1); + + /* "fontTools/misc/bezierTools.py":1323 + * + * def midpoint(r): + * return 0.5 * (r[0] + r[1]) # <<<<<<<<<<<<<< + * + * # If they do overlap but they're tiny, approximate + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_r, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_r, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_float_0_5, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1322 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.midpoint", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1359 + * ) + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) # <<<<<<<<<<<<<< + * seen = set() + * unique_values = [] + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3 = {"lambda3", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("lambda3 (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ts,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ts)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1359, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "lambda3") < 0)) __PYX_ERR(0, 1359, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_ts = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("lambda3", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1359, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_lambda_funcdef_lambda3(__pyx_self, __pyx_v_ts); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_lambda_funcdef_lambda3(PyObject *__pyx_self, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_cur_scope; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_outer_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("lambda3", 1); + __pyx_outer_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *) __Pyx_CyFunction_GetClosure(__pyx_self); + __pyx_cur_scope = __pyx_outer_scope; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_ts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (unlikely(!__pyx_cur_scope->__pyx_v_precision)) { __Pyx_RaiseClosureNameError("precision"); __PYX_ERR(0, 1359, __pyx_L1_error) } + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_cur_scope->__pyx_v_precision); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyNumber_Int(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_ts, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (unlikely(!__pyx_cur_scope->__pyx_v_precision)) { __Pyx_RaiseClosureNameError("precision"); __PYX_ERR(0, 1359, __pyx_L1_error) } + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_cur_scope->__pyx_v_precision); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyNumber_Int(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 1359, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2, PyObject *__pyx_v_precision, PyObject *__pyx_v_range1, PyObject *__pyx_v_range2) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_cur_scope; + PyObject *__pyx_v_bounds1 = NULL; + PyObject *__pyx_v_bounds2 = NULL; + PyObject *__pyx_v_intersects = NULL; + CYTHON_UNUSED PyObject *__pyx_v__ = NULL; + PyObject *__pyx_v_midpoint = 0; + PyObject *__pyx_v_c11 = NULL; + PyObject *__pyx_v_c12 = NULL; + PyObject *__pyx_v_c11_range = NULL; + PyObject *__pyx_v_c12_range = NULL; + PyObject *__pyx_v_c21 = NULL; + PyObject *__pyx_v_c22 = NULL; + PyObject *__pyx_v_c21_range = NULL; + PyObject *__pyx_v_c22_range = NULL; + PyObject *__pyx_v_found = NULL; + PyObject *__pyx_v_unique_key = NULL; + PyObject *__pyx_v_seen = NULL; + PyObject *__pyx_v_unique_values = NULL; + PyObject *__pyx_v_ts = NULL; + PyObject *__pyx_v_key = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + int __pyx_t_9; + Py_ssize_t __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_curve_intersections_t", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1306, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_precision = __pyx_v_precision; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_INCREF(__pyx_v_range1); + __Pyx_INCREF(__pyx_v_range2); + + /* "fontTools/misc/bezierTools.py":1309 + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + * bounds1 = _curve_bounds(curve1) # <<<<<<<<<<<<<< + * bounds2 = _curve_bounds(curve2) + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_curve_bounds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve1}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_bounds1 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1310 + * ): + * bounds1 = _curve_bounds(curve1) + * bounds2 = _curve_bounds(curve2) # <<<<<<<<<<<<<< + * + * if not range1: + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_curve_bounds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_bounds2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1312 + * bounds2 = _curve_bounds(curve2) + * + * if not range1: # <<<<<<<<<<<<<< + * range1 = (0.0, 1.0) + * if not range2: + */ + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_range1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1312, __pyx_L1_error) + __pyx_t_6 = (!__pyx_t_5); + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1313 + * + * if not range1: + * range1 = (0.0, 1.0) # <<<<<<<<<<<<<< + * if not range2: + * range2 = (0.0, 1.0) + */ + __Pyx_INCREF(__pyx_tuple__5); + __Pyx_DECREF_SET(__pyx_v_range1, __pyx_tuple__5); + + /* "fontTools/misc/bezierTools.py":1312 + * bounds2 = _curve_bounds(curve2) + * + * if not range1: # <<<<<<<<<<<<<< + * range1 = (0.0, 1.0) + * if not range2: + */ + } + + /* "fontTools/misc/bezierTools.py":1314 + * if not range1: + * range1 = (0.0, 1.0) + * if not range2: # <<<<<<<<<<<<<< + * range2 = (0.0, 1.0) + * + */ + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_range2); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1314, __pyx_L1_error) + __pyx_t_5 = (!__pyx_t_6); + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1315 + * range1 = (0.0, 1.0) + * if not range2: + * range2 = (0.0, 1.0) # <<<<<<<<<<<<<< + * + * # If bounds don't intersect, go home + */ + __Pyx_INCREF(__pyx_tuple__5); + __Pyx_DECREF_SET(__pyx_v_range2, __pyx_tuple__5); + + /* "fontTools/misc/bezierTools.py":1314 + * if not range1: + * range1 = (0.0, 1.0) + * if not range2: # <<<<<<<<<<<<<< + * range2 = (0.0, 1.0) + * + */ + } + + /* "fontTools/misc/bezierTools.py":1318 + * + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) # <<<<<<<<<<<<<< + * if not intersects: + * return [] + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_sectRect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_bounds1, __pyx_v_bounds2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1318, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 1318, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1318, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_intersects = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v__ = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1319 + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: # <<<<<<<<<<<<<< + * return [] + * + */ + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_intersects); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1319, __pyx_L1_error) + __pyx_t_6 = (!__pyx_t_5); + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1320 + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: + * return [] # <<<<<<<<<<<<<< + * + * def midpoint(r): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1320, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1319 + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: # <<<<<<<<<<<<<< + * return [] + * + */ + } + + /* "fontTools/misc/bezierTools.py":1322 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * + */ + __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint, 0, __pyx_n_s_curve_curve_intersections_t_loc, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__7)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1322, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_midpoint = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1326 + * + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: # <<<<<<<<<<<<<< + * return [(midpoint(range1), midpoint(range2))] + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_rectArea); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_bounds1}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_cur_scope->__pyx_v_precision, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_5) { + } else { + __pyx_t_6 = __pyx_t_5; + goto __pyx_L9_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_rectArea); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_bounds2}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_cur_scope->__pyx_v_precision, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __pyx_t_5; + __pyx_L9_bool_binop_done:; + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1327 + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: + * return [(midpoint(range1), midpoint(range2))] # <<<<<<<<<<<<<< + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1327, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1327, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1327, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 1327, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3)) __PYX_ERR(0, 1327, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1327, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 1327, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1326 + * + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: # <<<<<<<<<<<<<< + * return [(midpoint(range1), midpoint(range2))] + * + */ + } + + /* "fontTools/misc/bezierTools.py":1329 + * return [(midpoint(range1), midpoint(range2))] + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) # <<<<<<<<<<<<<< + * c11_range = (range1[0], midpoint(range1)) + * c12_range = (midpoint(range1), range1[1]) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_split_segment_at_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve1, __pyx_float_0_5}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1329, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_1)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 1329, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1329, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __pyx_v_c11 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c12 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1330 + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) + * c11_range = (range1[0], midpoint(range1)) # <<<<<<<<<<<<<< + * c12_range = (midpoint(range1), range1[1]) + * + */ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_range1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3)) __PYX_ERR(0, 1330, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1)) __PYX_ERR(0, 1330, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_v_c11_range = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1331 + * c11, c12 = _split_segment_at_t(curve1, 0.5) + * c11_range = (range1[0], midpoint(range1)) + * c12_range = (midpoint(range1), range1[1]) # <<<<<<<<<<<<<< + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) + */ + __pyx_t_2 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_range1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 1331, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(0, 1331, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_v_c12_range = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1333 + * c12_range = (midpoint(range1), range1[1]) + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) # <<<<<<<<<<<<<< + * c21_range = (range2[0], midpoint(range2)) + * c22_range = (midpoint(range2), range2[1]) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_split_segment_at_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_curve2, __pyx_float_0_5}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1333, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_1 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_1)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 1333, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L14_unpacking_done; + __pyx_L13_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1333, __pyx_L1_error) + __pyx_L14_unpacking_done:; + } + __pyx_v_c21 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_c22 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1334 + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) + * c21_range = (range2[0], midpoint(range2)) # <<<<<<<<<<<<<< + * c22_range = (midpoint(range2), range2[1]) + * + */ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_range2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3)) __PYX_ERR(0, 1334, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2)) __PYX_ERR(0, 1334, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_v_c21_range = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1335 + * c21, c22 = _split_segment_at_t(curve2, 0.5) + * c21_range = (range2[0], midpoint(range2)) + * c22_range = (midpoint(range2), range2[1]) # <<<<<<<<<<<<<< + * + * found = [] + */ + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1335, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_range2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1335, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1335, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 1335, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(0, 1335, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_v_c22_range = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1337 + * c22_range = (midpoint(range2), range2[1]) + * + * found = [] # <<<<<<<<<<<<<< + * found.extend( + * _curve_curve_intersections_t( + */ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_found = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1339 + * found = [] + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c21, precision, range1=c11_range, range2=c21_range + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_curve_curve_intersections_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1339, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":1340 + * found.extend( + * _curve_curve_intersections_t( + * c11, c21, precision, range1=c11_range, range2=c21_range # <<<<<<<<<<<<<< + * ) + * ) + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1339, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_c11); + __Pyx_GIVEREF(__pyx_v_c11); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_c11)) __PYX_ERR(0, 1339, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c21); + __Pyx_GIVEREF(__pyx_v_c21); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_c21)) __PYX_ERR(0, 1339, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_cur_scope->__pyx_v_precision)) __PYX_ERR(0, 1339, __pyx_L1_error); + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_range1, __pyx_v_c11_range) < 0) __PYX_ERR(0, 1340, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_range2, __pyx_v_c21_range) < 0) __PYX_ERR(0, 1340, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1339 + * found = [] + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c21, precision, range1=c11_range, range2=c21_range + * ) + */ + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1339, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1338 + * + * found = [] + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c11, c21, precision, range1=c11_range, range2=c21_range + */ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_7); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1338, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/misc/bezierTools.py":1344 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c21, precision, range1=c12_range, range2=c21_range + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_curve_curve_intersections_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":1345 + * found.extend( + * _curve_curve_intersections_t( + * c12, c21, precision, range1=c12_range, range2=c21_range # <<<<<<<<<<<<<< + * ) + * ) + */ + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_c12); + __Pyx_GIVEREF(__pyx_v_c12); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_c12)) __PYX_ERR(0, 1344, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c21); + __Pyx_GIVEREF(__pyx_v_c21); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_c21)) __PYX_ERR(0, 1344, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_cur_scope->__pyx_v_precision)) __PYX_ERR(0, 1344, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1345, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_range1, __pyx_v_c12_range) < 0) __PYX_ERR(0, 1345, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_range2, __pyx_v_c21_range) < 0) __PYX_ERR(0, 1345, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1344 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c21, precision, range1=c12_range, range2=c21_range + * ) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1343 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c12, c21, precision, range1=c12_range, range2=c21_range + */ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1349 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c22, precision, range1=c11_range, range2=c22_range + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_curve_curve_intersections_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":1350 + * found.extend( + * _curve_curve_intersections_t( + * c11, c22, precision, range1=c11_range, range2=c22_range # <<<<<<<<<<<<<< + * ) + * ) + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_c11); + __Pyx_GIVEREF(__pyx_v_c11); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_c11)) __PYX_ERR(0, 1349, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c22); + __Pyx_GIVEREF(__pyx_v_c22); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_c22)) __PYX_ERR(0, 1349, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_cur_scope->__pyx_v_precision)) __PYX_ERR(0, 1349, __pyx_L1_error); + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_range1, __pyx_v_c11_range) < 0) __PYX_ERR(0, 1350, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_range2, __pyx_v_c22_range) < 0) __PYX_ERR(0, 1350, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1349 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c22, precision, range1=c11_range, range2=c22_range + * ) + */ + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1348 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c11, c22, precision, range1=c11_range, range2=c22_range + */ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_7); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1348, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/misc/bezierTools.py":1354 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c22, precision, range1=c12_range, range2=c22_range + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_curve_curve_intersections_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":1355 + * found.extend( + * _curve_curve_intersections_t( + * c12, c22, precision, range1=c12_range, range2=c22_range # <<<<<<<<<<<<<< + * ) + * ) + */ + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_c12); + __Pyx_GIVEREF(__pyx_v_c12); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_c12)) __PYX_ERR(0, 1354, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c22); + __Pyx_GIVEREF(__pyx_v_c22); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_c22)) __PYX_ERR(0, 1354, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_cur_scope->__pyx_v_precision)) __PYX_ERR(0, 1354, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_range1, __pyx_v_c12_range) < 0) __PYX_ERR(0, 1355, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_range2, __pyx_v_c22_range) < 0) __PYX_ERR(0, 1355, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1354 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c22, precision, range1=c12_range, range2=c22_range + * ) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1353 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c12, c22, precision, range1=c12_range, range2=c22_range + */ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1353, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1359 + * ) + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) # <<<<<<<<<<<<<< + * seen = set() + * unique_values = [] + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3, 0, __pyx_n_s_curve_curve_intersections_t_loc_2, ((PyObject*)__pyx_cur_scope), __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1359, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_unique_key = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1360 + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + * seen = set() # <<<<<<<<<<<<<< + * unique_values = [] + * + */ + __pyx_t_3 = PySet_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1360, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_seen = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1361 + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + * seen = set() + * unique_values = [] # <<<<<<<<<<<<<< + * + * for ts in found: + */ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_unique_values = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1363 + * unique_values = [] + * + * for ts in found: # <<<<<<<<<<<<<< + * key = unique_key(ts) + * if key in seen: + */ + __pyx_t_3 = __pyx_v_found; __Pyx_INCREF(__pyx_t_3); + __pyx_t_10 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1363, __pyx_L1_error) + #endif + if (__pyx_t_10 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely((0 < 0))) __PYX_ERR(0, 1363, __pyx_L1_error) + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1363, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_XDECREF_SET(__pyx_v_ts, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1364 + * + * for ts in found: + * key = unique_key(ts) # <<<<<<<<<<<<<< + * if key in seen: + * continue + */ + __pyx_t_2 = __pyx_lambda_funcdef_lambda3(__pyx_v_unique_key, __pyx_v_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1364, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1365 + * for ts in found: + * key = unique_key(ts) + * if key in seen: # <<<<<<<<<<<<<< + * continue + * seen.add(key) + */ + __pyx_t_6 = (__Pyx_PySet_ContainsTF(__pyx_v_key, __pyx_v_seen, Py_EQ)); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1365, __pyx_L1_error) + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1366 + * key = unique_key(ts) + * if key in seen: + * continue # <<<<<<<<<<<<<< + * seen.add(key) + * unique_values.append(ts) + */ + goto __pyx_L15_continue; + + /* "fontTools/misc/bezierTools.py":1365 + * for ts in found: + * key = unique_key(ts) + * if key in seen: # <<<<<<<<<<<<<< + * continue + * seen.add(key) + */ + } + + /* "fontTools/misc/bezierTools.py":1367 + * if key in seen: + * continue + * seen.add(key) # <<<<<<<<<<<<<< + * unique_values.append(ts) + * + */ + __pyx_t_9 = PySet_Add(__pyx_v_seen, __pyx_v_key); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1367, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1368 + * continue + * seen.add(key) + * unique_values.append(ts) # <<<<<<<<<<<<<< + * + * return unique_values + */ + __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_unique_values, __pyx_v_ts); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1368, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1363 + * unique_values = [] + * + * for ts in found: # <<<<<<<<<<<<<< + * key = unique_key(ts) + * if key in seen: + */ + __pyx_L15_continue:; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1370 + * unique_values.append(ts) + * + * return unique_values # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_unique_values); + __pyx_r = __pyx_v_unique_values; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_bounds1); + __Pyx_XDECREF(__pyx_v_bounds2); + __Pyx_XDECREF(__pyx_v_intersects); + __Pyx_XDECREF(__pyx_v__); + __Pyx_XDECREF(__pyx_v_midpoint); + __Pyx_XDECREF(__pyx_v_c11); + __Pyx_XDECREF(__pyx_v_c12); + __Pyx_XDECREF(__pyx_v_c11_range); + __Pyx_XDECREF(__pyx_v_c12_range); + __Pyx_XDECREF(__pyx_v_c21); + __Pyx_XDECREF(__pyx_v_c22); + __Pyx_XDECREF(__pyx_v_c21_range); + __Pyx_XDECREF(__pyx_v_c22_range); + __Pyx_XDECREF(__pyx_v_found); + __Pyx_XDECREF(__pyx_v_unique_key); + __Pyx_XDECREF(__pyx_v_seen); + __Pyx_XDECREF(__pyx_v_unique_values); + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_key); + __Pyx_XDECREF(__pyx_v_range1); + __Pyx_XDECREF(__pyx_v_range2); + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1373 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_86_is_linelike, "_is_linelike(segment)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_87_is_linelike = {"_is_linelike", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_86_is_linelike}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segment = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_is_linelike (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_segment,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_segment)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1373, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_is_linelike") < 0)) __PYX_ERR(0, 1373, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_segment = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_is_linelike", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1373, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(__pyx_self, __pyx_v_segment); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1375 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1375, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_is_linelike_locals_genexpr, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1375, __pyx_L1_error) + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1375, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1375, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1375, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1375, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1375, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1375, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1375, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_p); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_p, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_math); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_isclose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_p, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = NULL; + __pyx_t_8 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_8 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_t_5, __pyx_float_0_0}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_8, 2+__pyx_t_8); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_10 = (!__pyx_t_9); + if (__pyx_t_10) { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_False); + __pyx_r = Py_False; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_True); + __pyx_r = Py_True; + goto __pyx_L0; + } + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1373 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment) { + PyObject *__pyx_v_maybeline = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_is_linelike", 1); + + /* "fontTools/misc/bezierTools.py":1374 + * + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) # <<<<<<<<<<<<<< + * return all(math.isclose(p[1], 0.0) for p in maybeline) + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_alignment_transformation); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_segment}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_transformPoints); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_segment}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_maybeline = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1375 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(NULL, __pyx_v_maybeline); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_Generator_Next(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1375, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1373 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_maybeline); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1378 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_88curveCurveIntersections, "curveCurveIntersections(curve1, curve2)\nFinds intersections between a curve and a curve.\n\n Args:\n curve1: List of coordinates of the first curve segment as 2D tuples.\n curve2: List of coordinates of the second curve segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = curveCurveIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_89curveCurveIntersections = {"curveCurveIntersections", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_88curveCurveIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve1 = 0; + PyObject *__pyx_v_curve2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curveCurveIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_curve1,&__pyx_n_s_curve2,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1378, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_curve2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1378, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("curveCurveIntersections", 1, 2, 2, 1); __PYX_ERR(0, 1378, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "curveCurveIntersections") < 0)) __PYX_ERR(0, 1378, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_curve1 = values[0]; + __pyx_v_curve2 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curveCurveIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1378, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveCurveIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(__pyx_self, __pyx_v_curve1, __pyx_v_curve2); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2) { + PyObject *__pyx_v_line1 = NULL; + PyObject *__pyx_v_line2 = NULL; + PyObject *__pyx_v_intersection_ts = NULL; + PyObject *__pyx_8genexpr8__pyx_v_ts = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curveCurveIntersections", 1); + + /* "fontTools/misc/bezierTools.py":1399 + * (81.7831487395506, 109.88904552375288) + * """ + * if _is_linelike(curve1): # <<<<<<<<<<<<<< + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_is_linelike); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1399, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve1}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1399, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1399, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1400 + * """ + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] # <<<<<<<<<<<<<< + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curve1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curve1, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(0, 1400, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(0, 1400, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_v_line1 = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1401 + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_is_linelike); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_curve2}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1401, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1402 + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] # <<<<<<<<<<<<<< + * return lineLineIntersections(*line1, *line2) + * else: + */ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_curve2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curve2, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3)) __PYX_ERR(0, 1402, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2)) __PYX_ERR(0, 1402, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_v_line2 = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1403 + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) # <<<<<<<<<<<<<< + * else: + * return curveLineIntersections(curve2, line1) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_lineLineIntersections); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1403, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_v_line1, __pyx_v_line2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1403, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1403, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1401 + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) + */ + } + + /* "fontTools/misc/bezierTools.py":1405 + * return lineLineIntersections(*line1, *line2) + * else: + * return curveLineIntersections(curve2, line1) # <<<<<<<<<<<<<< + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_curveLineIntersections); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1405, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve2, __pyx_v_line1}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1405, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1399 + * (81.7831487395506, 109.88904552375288) + * """ + * if _is_linelike(curve1): # <<<<<<<<<<<<<< + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): + */ + } + + /* "fontTools/misc/bezierTools.py":1406 + * else: + * return curveLineIntersections(curve2, line1) + * elif _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_is_linelike); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_curve2}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1407 + * return curveLineIntersections(curve2, line1) + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] # <<<<<<<<<<<<<< + * return curveLineIntersections(curve1, line2) + * + */ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_curve2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curve2, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3)) __PYX_ERR(0, 1407, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2)) __PYX_ERR(0, 1407, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_v_line2 = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1408 + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) # <<<<<<<<<<<<<< + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_curveLineIntersections); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_curve1, __pyx_v_line2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1406 + * else: + * return curveLineIntersections(curve2, line1) + * elif _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) + */ + } + + /* "fontTools/misc/bezierTools.py":1410 + * return curveLineIntersections(curve1, line2) + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) # <<<<<<<<<<<<<< + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_curve_curve_intersections_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_curve1, __pyx_v_curve2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1410, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_intersection_ts = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1411 + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) + * return [ # <<<<<<<<<<<<<< + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1411, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1413 + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts # <<<<<<<<<<<<<< + * ] + * + */ + if (likely(PyList_CheckExact(__pyx_v_intersection_ts)) || PyTuple_CheckExact(__pyx_v_intersection_ts)) { + __pyx_t_2 = __pyx_v_intersection_ts; __Pyx_INCREF(__pyx_t_2); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_intersection_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1413, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1413, __pyx_L7_error) + } + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1413, __pyx_L7_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 1413, __pyx_L7_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1413, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1413, __pyx_L7_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 1413, __pyx_L7_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1413, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } + } else { + __pyx_t_3 = __pyx_t_7(__pyx_t_2); + if (unlikely(!__pyx_t_3)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1413, __pyx_L7_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_XDECREF_SET(__pyx_8genexpr8__pyx_v_ts, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1412 + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) # <<<<<<<<<<<<<< + * for ts in intersection_ts + * ] + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_segmentPointAtT); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_GetItemInt(__pyx_8genexpr8__pyx_v_ts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_10))) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_10); + if (likely(__pyx_t_12)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10); + __Pyx_INCREF(__pyx_t_12); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_10, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_12, __pyx_v_curve1, __pyx_t_11}; + __pyx_t_9 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + } + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_pt, __pyx_t_9) < 0) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_GetItemInt(__pyx_8genexpr8__pyx_v_ts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_9); + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_t1, __pyx_t_9) < 0) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_GetItemInt(__pyx_8genexpr8__pyx_v_ts, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_9); + if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_t2, __pyx_t_9) < 0) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1412, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_9))) __PYX_ERR(0, 1411, __pyx_L7_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":1413 + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts # <<<<<<<<<<<<<< + * ] + * + */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_ts); __pyx_8genexpr8__pyx_v_ts = 0; + goto __pyx_L11_exit_scope; + __pyx_L7_error:; + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_ts); __pyx_8genexpr8__pyx_v_ts = 0; + goto __pyx_L1_error; + __pyx_L11_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1378 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveCurveIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_line1); + __Pyx_XDECREF(__pyx_v_line2); + __Pyx_XDECREF(__pyx_v_intersection_ts); + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_ts); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1417 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections, "segmentSegmentIntersections(seg1, seg2)\nFinds intersections between two segments.\n\n Args:\n seg1: List of coordinates of the first segment as 2D tuples.\n seg2: List of coordinates of the second segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = segmentSegmentIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = segmentSegmentIntersections(curve3, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections = {"segmentSegmentIntersections", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_seg1 = 0; + PyObject *__pyx_v_seg2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("segmentSegmentIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_seg1,&__pyx_n_s_seg2,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_seg1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1417, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_seg2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1417, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("segmentSegmentIntersections", 1, 2, 2, 1); __PYX_ERR(0, 1417, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "segmentSegmentIntersections") < 0)) __PYX_ERR(0, 1417, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_seg1 = values[0]; + __pyx_v_seg2 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("segmentSegmentIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1417, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentSegmentIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(__pyx_self, __pyx_v_seg1, __pyx_v_seg2); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg1, PyObject *__pyx_v_seg2) { + int __pyx_v_swapped; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_8genexpr9__pyx_v_i = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + Py_ssize_t __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *(*__pyx_t_12)(PyObject *); + PyObject *__pyx_t_13 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("segmentSegmentIntersections", 0); + __Pyx_INCREF(__pyx_v_seg1); + __Pyx_INCREF(__pyx_v_seg2); + + /* "fontTools/misc/bezierTools.py":1447 + * """ + * # Arrange by degree + * swapped = False # <<<<<<<<<<<<<< + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 + */ + __pyx_v_swapped = 0; + + /* "fontTools/misc/bezierTools.py":1448 + * # Arrange by degree + * swapped = False + * if len(seg2) > len(seg1): # <<<<<<<<<<<<<< + * seg2, seg1 = seg1, seg2 + * swapped = True + */ + __pyx_t_1 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1448, __pyx_L1_error) + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1448, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_1 > __pyx_t_2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1449 + * swapped = False + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 # <<<<<<<<<<<<<< + * swapped = True + * if len(seg1) > 2: + */ + __pyx_t_4 = __pyx_v_seg1; + __pyx_t_5 = __pyx_v_seg2; + __pyx_v_seg2 = __pyx_t_4; + __pyx_t_4 = 0; + __pyx_v_seg1 = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1450 + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 + * swapped = True # <<<<<<<<<<<<<< + * if len(seg1) > 2: + * if len(seg2) > 2: + */ + __pyx_v_swapped = 1; + + /* "fontTools/misc/bezierTools.py":1448 + * # Arrange by degree + * swapped = False + * if len(seg2) > len(seg1): # <<<<<<<<<<<<<< + * seg2, seg1 = seg1, seg2 + * swapped = True + */ + } + + /* "fontTools/misc/bezierTools.py":1451 + * seg2, seg1 = seg1, seg2 + * swapped = True + * if len(seg1) > 2: # <<<<<<<<<<<<<< + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) + */ + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1451, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_2 > 2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1452 + * swapped = True + * if len(seg1) > 2: + * if len(seg2) > 2: # <<<<<<<<<<<<<< + * intersections = curveCurveIntersections(seg1, seg2) + * else: + */ + __pyx_t_2 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1452, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_2 > 2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1453 + * if len(seg1) > 2: + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) # <<<<<<<<<<<<<< + * else: + * intersections = curveLineIntersections(seg1, seg2) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_curveCurveIntersections); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1453, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + __pyx_t_9 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_8, __pyx_v_seg1, __pyx_v_seg2}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_7, __pyx_callargs+1-__pyx_t_9, 2+__pyx_t_9); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1453, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __pyx_v_intersections = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1452 + * swapped = True + * if len(seg1) > 2: + * if len(seg2) > 2: # <<<<<<<<<<<<<< + * intersections = curveCurveIntersections(seg1, seg2) + * else: + */ + goto __pyx_L5; + } + + /* "fontTools/misc/bezierTools.py":1455 + * intersections = curveCurveIntersections(seg1, seg2) + * else: + * intersections = curveLineIntersections(seg1, seg2) # <<<<<<<<<<<<<< + * elif len(seg1) == 2 and len(seg2) == 2: + * intersections = lineLineIntersections(*seg1, *seg2) + */ + /*else*/ { + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_curveLineIntersections); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + __pyx_t_9 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_8, __pyx_v_seg1, __pyx_v_seg2}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_7, __pyx_callargs+1-__pyx_t_9, 2+__pyx_t_9); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __pyx_v_intersections = __pyx_t_6; + __pyx_t_6 = 0; + } + __pyx_L5:; + + /* "fontTools/misc/bezierTools.py":1451 + * seg2, seg1 = seg1, seg2 + * swapped = True + * if len(seg1) > 2: # <<<<<<<<<<<<<< + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) + */ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":1456 + * else: + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: # <<<<<<<<<<<<<< + * intersections = lineLineIntersections(*seg1, *seg2) + * else: + */ + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1456, __pyx_L1_error) + __pyx_t_10 = (__pyx_t_2 == 2); + if (__pyx_t_10) { + } else { + __pyx_t_3 = __pyx_t_10; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_2 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1456, __pyx_L1_error) + __pyx_t_10 = (__pyx_t_2 == 2); + __pyx_t_3 = __pyx_t_10; + __pyx_L6_bool_binop_done:; + if (likely(__pyx_t_3)) { + + /* "fontTools/misc/bezierTools.py":1457 + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: + * intersections = lineLineIntersections(*seg1, *seg2) # <<<<<<<<<<<<<< + * else: + * raise ValueError("Couldn't work out which intersection function to use") + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_lineLineIntersections); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1457, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PySequence_Tuple(__pyx_v_seg1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1457, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_seg2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1457, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1457, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1457, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_intersections = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":1456 + * else: + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: # <<<<<<<<<<<<<< + * intersections = lineLineIntersections(*seg1, *seg2) + * else: + */ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":1459 + * intersections = lineLineIntersections(*seg1, *seg2) + * else: + * raise ValueError("Couldn't work out which intersection function to use") # <<<<<<<<<<<<<< + * if not swapped: + * return intersections + */ + /*else*/ { + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(0, 1459, __pyx_L1_error) + } + __pyx_L4:; + + /* "fontTools/misc/bezierTools.py":1460 + * else: + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: # <<<<<<<<<<<<<< + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + */ + __pyx_t_3 = (!__pyx_v_swapped); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1461 + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: + * return intersections # <<<<<<<<<<<<<< + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_intersections); + __pyx_r = __pyx_v_intersections; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1460 + * else: + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: # <<<<<<<<<<<<<< + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + */ + } + + /* "fontTools/misc/bezierTools.py":1462 + * if not swapped: + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_8); + if (likely(PyList_CheckExact(__pyx_v_intersections)) || PyTuple_CheckExact(__pyx_v_intersections)) { + __pyx_t_11 = __pyx_v_intersections; __Pyx_INCREF(__pyx_t_11); + __pyx_t_2 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_11 = PyObject_GetIter(__pyx_v_intersections); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1462, __pyx_L11_error) + } + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_11))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_11); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1462, __pyx_L11_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1462, __pyx_L11_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_11, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_11); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1462, __pyx_L11_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_11, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1462, __pyx_L11_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_11, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } + } else { + __pyx_t_6 = __pyx_t_12(__pyx_t_11); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1462, __pyx_L11_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_XDECREF_SET(__pyx_8genexpr9__pyx_v_i, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Intersection); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr9__pyx_v_i, __pyx_n_s_pt); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_13); + if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_pt, __pyx_t_13) < 0) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr9__pyx_v_i, __pyx_n_s_t2); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_13); + if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_t1, __pyx_t_13) < 0) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr9__pyx_v_i, __pyx_n_s_t1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_13); + if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_t2, __pyx_t_13) < 0) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_7); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_8, (PyObject*)__pyx_t_13))) __PYX_ERR(0, 1462, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + } + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_i); __pyx_8genexpr9__pyx_v_i = 0; + goto __pyx_L15_exit_scope; + __pyx_L11_error:; + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_i); __pyx_8genexpr9__pyx_v_i = 0; + goto __pyx_L1_error; + __pyx_L15_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1417 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentSegmentIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_i); + __Pyx_XDECREF(__pyx_v_seg1); + __Pyx_XDECREF(__pyx_v_seg2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1465 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_92_segmentrepr, "_segmentrepr(obj)\n\n >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]])\n '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))'\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_93_segmentrepr = {"_segmentrepr", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_92_segmentrepr}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_obj = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_segmentrepr (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_obj)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1465, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_segmentrepr") < 0)) __PYX_ERR(0, 1465, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_obj = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_segmentrepr", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1465, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(__pyx_self, __pyx_v_obj); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1475 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1475, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_segmentrepr_locals_genexpr, __pyx_n_s_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1475, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1475, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1475, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1475, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1475, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1475, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1475, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1475, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_x); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_x, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_segmentrepr); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_cur_scope->__pyx_v_x}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1465 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + */ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_obj) { + PyObject *__pyx_v_it = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_segmentrepr", 1); + + /* "fontTools/misc/bezierTools.py":1470 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "fontTools/misc/bezierTools.py":1471 + * """ + * try: + * it = iter(obj) # <<<<<<<<<<<<<< + * except TypeError: + * return "%g" % obj + */ + __pyx_t_4 = PyObject_GetIter(__pyx_v_obj); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1471, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_v_it = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1470 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: + */ + } + + /* "fontTools/misc/bezierTools.py":1475 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(NULL, __pyx_v_it); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1475, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_Generator_Next(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1475, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyUnicode_Join(__pyx_kp_u__9, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1475, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyUnicode_Format(__pyx_kp_u_s_2, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1475, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1472 + * try: + * it = iter(obj) + * except TypeError: # <<<<<<<<<<<<<< + * return "%g" % obj + * else: + */ + __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); + if (__pyx_t_6) { + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_7) < 0) __PYX_ERR(0, 1472, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":1473 + * it = iter(obj) + * except TypeError: + * return "%g" % obj # <<<<<<<<<<<<<< + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_8 = __Pyx_PyUnicode_FormatSafe(__pyx_kp_u_g, __pyx_v_obj); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1473, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L6_except_return; + } + goto __pyx_L5_except_error; + + /* "fontTools/misc/bezierTools.py":1470 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1465 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_it); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1478 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_94printSegments, "printSegments(segments)\nHelper for the doctests, displaying each segment in a list of\n segments on a single line as a tuple.\n "); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_95printSegments = {"printSegments", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_94printSegments}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segments = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("printSegments (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_segments,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_segments)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1478, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "printSegments") < 0)) __PYX_ERR(0, 1478, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_segments = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("printSegments", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1478, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.printSegments", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(__pyx_self, __pyx_v_segments); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segments) { + PyObject *__pyx_v_segment = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("printSegments", 1); + + /* "fontTools/misc/bezierTools.py":1482 + * segments on a single line as a tuple. + * """ + * for segment in segments: # <<<<<<<<<<<<<< + * print(_segmentrepr(segment)) + * + */ + if (likely(PyList_CheckExact(__pyx_v_segments)) || PyTuple_CheckExact(__pyx_v_segments)) { + __pyx_t_1 = __pyx_v_segments; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_segments); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1482, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1482, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1482, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1482, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1482, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1482, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 1482, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1482, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 1482, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XDECREF_SET(__pyx_v_segment, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1483 + * """ + * for segment in segments: + * print(_segmentrepr(segment)) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_segmentrepr); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1483, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_v_segment}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1483, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1483, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1482 + * segments on a single line as a tuple. + * """ + * for segment in segments: # <<<<<<<<<<<<<< + * print(_segmentrepr(segment)) + * + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1478 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.printSegments", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_segment); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_t); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_t) { + e = (*v)(p->__pyx_v_t, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct__genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct__genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_t); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_t) { + e = (*v)(p->__pyx_v_t, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_1_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_1_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_ts); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o; + if (p->__pyx_v_ts) { + e = (*v)(p->__pyx_v_ts, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_2_splitCubicAtTC", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_2_splitCubicAtTC", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_i); + Py_CLEAR(p->__pyx_v_pt1); + Py_CLEAR(p->__pyx_v_pt2); + Py_CLEAR(p->__pyx_v_pt3); + Py_CLEAR(p->__pyx_v_pt4); + Py_CLEAR(p->__pyx_v_ts); + Py_CLEAR(p->__pyx_t_0); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o; + if (p->__pyx_v_i) { + e = (*v)(p->__pyx_v_i, a); if (e) return e; + } + if (p->__pyx_v_pt1) { + e = (*v)(p->__pyx_v_pt1, a); if (e) return e; + } + if (p->__pyx_v_pt2) { + e = (*v)(p->__pyx_v_pt2, a); if (e) return e; + } + if (p->__pyx_v_pt3) { + e = (*v)(p->__pyx_v_pt3, a); if (e) return e; + } + if (p->__pyx_v_pt4) { + e = (*v)(p->__pyx_v_pt4, a); if (e) return e; + } + if (p->__pyx_v_ts) { + e = (*v)(p->__pyx_v_ts, a); if (e) return e; + } + if (p->__pyx_t_0) { + e = (*v)(p->__pyx_t_0, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_3__splitCubicAtTC", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_3__splitCubicAtTC", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_i); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_i) { + e = (*v)(p->__pyx_v_i, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_4_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_4_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_precision); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + if (p->__pyx_v_precision) { + e = (*v)(p->__pyx_v_precision, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + tmp = ((PyObject*)p->__pyx_v_precision); + p->__pyx_v_precision = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_clear, (void *)__pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_5__curve_curve_intersections_t", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_5__curve_curve_intersections_t", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_traverse*/ + __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_p); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_p) { + e = (*v)(p->__pyx_v_p, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_6_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_6_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[8]; +static int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[--__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_x); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)))) { + __pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_x) { + e = (*v)(p->__pyx_v_x, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_7_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_7_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_1_t, __pyx_k_1_t, sizeof(__pyx_k_1_t), 0, 0, 1, 1}, + {&__pyx_n_s_1_t_2, __pyx_k_1_t_2, sizeof(__pyx_k_1_t_2), 0, 0, 1, 1}, + {&__pyx_n_s_2_t_1_t, __pyx_k_2_t_1_t, sizeof(__pyx_k_2_t_1_t), 0, 0, 1, 1}, + {&__pyx_kp_u_Approximates_the_arc_length_for, __pyx_k_Approximates_the_arc_length_for, sizeof(__pyx_k_Approximates_the_arc_length_for), 0, 1, 0, 0}, + {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, + {&__pyx_n_s_COMPILED, __pyx_k_COMPILED, sizeof(__pyx_k_COMPILED), 0, 0, 1, 1}, + {&__pyx_kp_u_Calculates_the_arc_length_for_a, __pyx_k_Calculates_the_arc_length_for_a, sizeof(__pyx_k_Calculates_the_arc_length_for_a), 0, 1, 0, 0}, + {&__pyx_kp_u_Calculates_the_bounding_rectangl, __pyx_k_Calculates_the_bounding_rectangl, sizeof(__pyx_k_Calculates_the_bounding_rectangl), 0, 1, 0, 0}, + {&__pyx_kp_u_Calculates_the_bounding_rectangl_2, __pyx_k_Calculates_the_bounding_rectangl_2, sizeof(__pyx_k_Calculates_the_bounding_rectangl_2), 0, 1, 0, 0}, + {&__pyx_kp_u_Couldn_t_work_out_which_intersec, __pyx_k_Couldn_t_work_out_which_intersec, sizeof(__pyx_k_Couldn_t_work_out_which_intersec), 0, 1, 0, 0}, + {&__pyx_n_s_DD, __pyx_k_DD, sizeof(__pyx_k_DD), 0, 0, 1, 1}, + {&__pyx_kp_u_Finds_intersections_between_a_cu, __pyx_k_Finds_intersections_between_a_cu, sizeof(__pyx_k_Finds_intersections_between_a_cu), 0, 1, 0, 0}, + {&__pyx_kp_u_Finds_intersections_between_a_cu_2, __pyx_k_Finds_intersections_between_a_cu_2, sizeof(__pyx_k_Finds_intersections_between_a_cu_2), 0, 1, 0, 0}, + {&__pyx_kp_u_Finds_intersections_between_two, __pyx_k_Finds_intersections_between_two, sizeof(__pyx_k_Finds_intersections_between_two), 0, 1, 0, 0}, + {&__pyx_kp_u_Finds_intersections_between_two_2, __pyx_k_Finds_intersections_between_two_2, sizeof(__pyx_k_Finds_intersections_between_two_2), 0, 1, 0, 0}, + {&__pyx_n_s_Identity, __pyx_k_Identity, sizeof(__pyx_k_Identity), 0, 0, 1, 1}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_n_s_Intersection, __pyx_k_Intersection, sizeof(__pyx_k_Intersection), 0, 0, 1, 1}, + {&__pyx_n_u_Intersection, __pyx_k_Intersection, sizeof(__pyx_k_Intersection), 0, 1, 0, 1}, + {&__pyx_n_s_Len, __pyx_k_Len, sizeof(__pyx_k_Len), 0, 0, 1, 1}, + {&__pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_k_Lib_fontTools_misc_bezierTools_p, sizeof(__pyx_k_Lib_fontTools_misc_bezierTools_p), 0, 0, 1, 0}, + {&__pyx_n_s_Q, __pyx_k_Q, sizeof(__pyx_k_Q), 0, 0, 1, 1}, + {&__pyx_n_s_Q3, __pyx_k_Q3, sizeof(__pyx_k_Q3), 0, 0, 1, 1}, + {&__pyx_n_s_R, __pyx_k_R, sizeof(__pyx_k_R), 0, 0, 1, 1}, + {&__pyx_n_s_R2, __pyx_k_R2, sizeof(__pyx_k_R2), 0, 0, 1, 1}, + {&__pyx_n_s_R2_Q3, __pyx_k_R2_Q3, sizeof(__pyx_k_R2_Q3), 0, 0, 1, 1}, + {&__pyx_kp_u_Solve_a_cubic_equation_Solves_a, __pyx_k_Solve_a_cubic_equation_Solves_a, sizeof(__pyx_k_Solve_a_cubic_equation_Solves_a), 0, 1, 0, 0}, + {&__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a, __pyx_k_Split_a_cubic_Bezier_curve_at_a, sizeof(__pyx_k_Split_a_cubic_Bezier_curve_at_a), 0, 1, 0, 0}, + {&__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on, __pyx_k_Split_a_cubic_Bezier_curve_at_on, sizeof(__pyx_k_Split_a_cubic_Bezier_curve_at_on), 0, 1, 0, 0}, + {&__pyx_kp_u_Split_a_line_at_a_given_coordina, __pyx_k_Split_a_line_at_a_given_coordina, sizeof(__pyx_k_Split_a_line_at_a_given_coordina), 0, 1, 0, 0}, + {&__pyx_kp_u_Split_a_quadratic_Bezier_curve_a, __pyx_k_Split_a_quadratic_Bezier_curve_a, sizeof(__pyx_k_Split_a_quadratic_Bezier_curve_a), 0, 1, 0, 0}, + {&__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2, __pyx_k_Split_a_quadratic_Bezier_curve_a_2, sizeof(__pyx_k_Split_a_quadratic_Bezier_curve_a_2), 0, 1, 0, 0}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_kp_u_Unknown_curve_degree, __pyx_k_Unknown_curve_degree, sizeof(__pyx_k_Unknown_curve_degree), 0, 1, 0, 0}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_kp_u__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 1, 0, 0}, + {&__pyx_n_s__105, __pyx_k__105, sizeof(__pyx_k__105), 0, 0, 1, 1}, + {&__pyx_n_s__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 0, 1, 1}, + {&__pyx_kp_u__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 1, 0, 0}, + {&__pyx_n_s__91, __pyx_k__91, sizeof(__pyx_k__91), 0, 0, 1, 1}, + {&__pyx_n_s_a, __pyx_k_a, sizeof(__pyx_k_a), 0, 0, 1, 1}, + {&__pyx_n_s_a1, __pyx_k_a1, sizeof(__pyx_k_a1), 0, 0, 1, 1}, + {&__pyx_n_s_a1_3, __pyx_k_a1_3, sizeof(__pyx_k_a1_3), 0, 0, 1, 1}, + {&__pyx_n_s_a1x, __pyx_k_a1x, sizeof(__pyx_k_a1x), 0, 0, 1, 1}, + {&__pyx_n_s_a1y, __pyx_k_a1y, sizeof(__pyx_k_a1y), 0, 0, 1, 1}, + {&__pyx_n_s_a2, __pyx_k_a2, sizeof(__pyx_k_a2), 0, 0, 1, 1}, + {&__pyx_n_s_a3, __pyx_k_a3, sizeof(__pyx_k_a3), 0, 0, 1, 1}, + {&__pyx_n_s_acos, __pyx_k_acos, sizeof(__pyx_k_acos), 0, 0, 1, 1}, + {&__pyx_n_s_aligned_curve, __pyx_k_aligned_curve, sizeof(__pyx_k_aligned_curve), 0, 0, 1, 1}, + {&__pyx_n_s_alignment_transformation, __pyx_k_alignment_transformation, sizeof(__pyx_k_alignment_transformation), 0, 0, 1, 1}, + {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, + {&__pyx_n_s_angle, __pyx_k_angle, sizeof(__pyx_k_angle), 0, 0, 1, 1}, + {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1}, + {&__pyx_n_s_approximateCubicArcLength, __pyx_k_approximateCubicArcLength, sizeof(__pyx_k_approximateCubicArcLength), 0, 0, 1, 1}, + {&__pyx_n_u_approximateCubicArcLength, __pyx_k_approximateCubicArcLength, sizeof(__pyx_k_approximateCubicArcLength), 0, 1, 0, 1}, + {&__pyx_n_s_approximateCubicArcLengthC, __pyx_k_approximateCubicArcLengthC, sizeof(__pyx_k_approximateCubicArcLengthC), 0, 0, 1, 1}, + {&__pyx_n_u_approximateCubicArcLengthC, __pyx_k_approximateCubicArcLengthC, sizeof(__pyx_k_approximateCubicArcLengthC), 0, 1, 0, 1}, + {&__pyx_kp_u_approximateCubicArcLength_line_3, __pyx_k_approximateCubicArcLength_line_3, sizeof(__pyx_k_approximateCubicArcLength_line_3), 0, 1, 0, 0}, + {&__pyx_n_s_approximateQuadraticArcLength, __pyx_k_approximateQuadraticArcLength, sizeof(__pyx_k_approximateQuadraticArcLength), 0, 0, 1, 1}, + {&__pyx_n_u_approximateQuadraticArcLength, __pyx_k_approximateQuadraticArcLength, sizeof(__pyx_k_approximateQuadraticArcLength), 0, 1, 0, 1}, + {&__pyx_n_s_approximateQuadraticArcLengthC, __pyx_k_approximateQuadraticArcLengthC, sizeof(__pyx_k_approximateQuadraticArcLengthC), 0, 0, 1, 1}, + {&__pyx_n_u_approximateQuadraticArcLengthC, __pyx_k_approximateQuadraticArcLengthC, sizeof(__pyx_k_approximateQuadraticArcLengthC), 0, 1, 0, 1}, + {&__pyx_n_s_arch, __pyx_k_arch, sizeof(__pyx_k_arch), 0, 0, 1, 1}, + {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1}, + {&__pyx_n_s_asinh, __pyx_k_asinh, sizeof(__pyx_k_asinh), 0, 0, 1, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_atan2, __pyx_k_atan2, sizeof(__pyx_k_atan2), 0, 0, 1, 1}, + {&__pyx_n_s_ax, __pyx_k_ax, sizeof(__pyx_k_ax), 0, 0, 1, 1}, + {&__pyx_n_s_ax2, __pyx_k_ax2, sizeof(__pyx_k_ax2), 0, 0, 1, 1}, + {&__pyx_n_s_ax3, __pyx_k_ax3, sizeof(__pyx_k_ax3), 0, 0, 1, 1}, + {&__pyx_n_s_ay, __pyx_k_ay, sizeof(__pyx_k_ay), 0, 0, 1, 1}, + {&__pyx_n_s_ay2, __pyx_k_ay2, sizeof(__pyx_k_ay2), 0, 0, 1, 1}, + {&__pyx_n_s_ay3, __pyx_k_ay3, sizeof(__pyx_k_ay3), 0, 0, 1, 1}, + {&__pyx_n_s_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 0, 1, 1}, + {&__pyx_n_s_b1, __pyx_k_b1, sizeof(__pyx_k_b1), 0, 0, 1, 1}, + {&__pyx_n_s_b1x, __pyx_k_b1x, sizeof(__pyx_k_b1x), 0, 0, 1, 1}, + {&__pyx_n_s_b1y, __pyx_k_b1y, sizeof(__pyx_k_b1y), 0, 0, 1, 1}, + {&__pyx_n_s_both_points_are_on_same_side_of, __pyx_k_both_points_are_on_same_side_of, sizeof(__pyx_k_both_points_are_on_same_side_of), 0, 0, 1, 1}, + {&__pyx_n_s_bounds1, __pyx_k_bounds1, sizeof(__pyx_k_bounds1), 0, 0, 1, 1}, + {&__pyx_n_s_bounds2, __pyx_k_bounds2, sizeof(__pyx_k_bounds2), 0, 0, 1, 1}, + {&__pyx_n_s_box, __pyx_k_box, sizeof(__pyx_k_box), 0, 0, 1, 1}, + {&__pyx_n_s_bx, __pyx_k_bx, sizeof(__pyx_k_bx), 0, 0, 1, 1}, + {&__pyx_n_s_bx2, __pyx_k_bx2, sizeof(__pyx_k_bx2), 0, 0, 1, 1}, + {&__pyx_n_s_by, __pyx_k_by, sizeof(__pyx_k_by), 0, 0, 1, 1}, + {&__pyx_n_s_by2, __pyx_k_by2, sizeof(__pyx_k_by2), 0, 0, 1, 1}, + {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, + {&__pyx_n_s_c1, __pyx_k_c1, sizeof(__pyx_k_c1), 0, 0, 1, 1}, + {&__pyx_n_s_c11, __pyx_k_c11, sizeof(__pyx_k_c11), 0, 0, 1, 1}, + {&__pyx_n_s_c11_range, __pyx_k_c11_range, sizeof(__pyx_k_c11_range), 0, 0, 1, 1}, + {&__pyx_n_s_c12, __pyx_k_c12, sizeof(__pyx_k_c12), 0, 0, 1, 1}, + {&__pyx_n_s_c12_range, __pyx_k_c12_range, sizeof(__pyx_k_c12_range), 0, 0, 1, 1}, + {&__pyx_n_s_c1x, __pyx_k_c1x, sizeof(__pyx_k_c1x), 0, 0, 1, 1}, + {&__pyx_n_s_c1y, __pyx_k_c1y, sizeof(__pyx_k_c1y), 0, 0, 1, 1}, + {&__pyx_n_s_c21, __pyx_k_c21, sizeof(__pyx_k_c21), 0, 0, 1, 1}, + {&__pyx_n_s_c21_range, __pyx_k_c21_range, sizeof(__pyx_k_c21_range), 0, 0, 1, 1}, + {&__pyx_n_s_c22, __pyx_k_c22, sizeof(__pyx_k_c22), 0, 0, 1, 1}, + {&__pyx_n_s_c22_range, __pyx_k_c22_range, sizeof(__pyx_k_c22_range), 0, 0, 1, 1}, + {&__pyx_n_s_calcBounds, __pyx_k_calcBounds, sizeof(__pyx_k_calcBounds), 0, 0, 1, 1}, + {&__pyx_n_s_calcCubicArcLength, __pyx_k_calcCubicArcLength, sizeof(__pyx_k_calcCubicArcLength), 0, 0, 1, 1}, + {&__pyx_n_u_calcCubicArcLength, __pyx_k_calcCubicArcLength, sizeof(__pyx_k_calcCubicArcLength), 0, 1, 0, 1}, + {&__pyx_n_s_calcCubicArcLengthC, __pyx_k_calcCubicArcLengthC, sizeof(__pyx_k_calcCubicArcLengthC), 0, 0, 1, 1}, + {&__pyx_n_u_calcCubicArcLengthC, __pyx_k_calcCubicArcLengthC, sizeof(__pyx_k_calcCubicArcLengthC), 0, 1, 0, 1}, + {&__pyx_n_s_calcCubicArcLengthCRecurse, __pyx_k_calcCubicArcLengthCRecurse, sizeof(__pyx_k_calcCubicArcLengthCRecurse), 0, 0, 1, 1}, + {&__pyx_n_s_calcCubicBounds, __pyx_k_calcCubicBounds, sizeof(__pyx_k_calcCubicBounds), 0, 0, 1, 1}, + {&__pyx_n_u_calcCubicBounds, __pyx_k_calcCubicBounds, sizeof(__pyx_k_calcCubicBounds), 0, 1, 0, 1}, + {&__pyx_kp_u_calcCubicBounds_line_412, __pyx_k_calcCubicBounds_line_412, sizeof(__pyx_k_calcCubicBounds_line_412), 0, 1, 0, 0}, + {&__pyx_n_s_calcCubicParameters, __pyx_k_calcCubicParameters, sizeof(__pyx_k_calcCubicParameters), 0, 0, 1, 1}, + {&__pyx_n_s_calcCubicPoints, __pyx_k_calcCubicPoints, sizeof(__pyx_k_calcCubicPoints), 0, 0, 1, 1}, + {&__pyx_n_s_calcQuadraticArcLength, __pyx_k_calcQuadraticArcLength, sizeof(__pyx_k_calcQuadraticArcLength), 0, 0, 1, 1}, + {&__pyx_n_u_calcQuadraticArcLength, __pyx_k_calcQuadraticArcLength, sizeof(__pyx_k_calcQuadraticArcLength), 0, 1, 0, 1}, + {&__pyx_n_s_calcQuadraticArcLengthC, __pyx_k_calcQuadraticArcLengthC, sizeof(__pyx_k_calcQuadraticArcLengthC), 0, 0, 1, 1}, + {&__pyx_n_u_calcQuadraticArcLengthC, __pyx_k_calcQuadraticArcLengthC, sizeof(__pyx_k_calcQuadraticArcLengthC), 0, 1, 0, 1}, + {&__pyx_kp_u_calcQuadraticArcLength_line_151, __pyx_k_calcQuadraticArcLength_line_151, sizeof(__pyx_k_calcQuadraticArcLength_line_151), 0, 1, 0, 0}, + {&__pyx_n_s_calcQuadraticBounds, __pyx_k_calcQuadraticBounds, sizeof(__pyx_k_calcQuadraticBounds), 0, 0, 1, 1}, + {&__pyx_n_u_calcQuadraticBounds, __pyx_k_calcQuadraticBounds, sizeof(__pyx_k_calcQuadraticBounds), 0, 1, 0, 1}, + {&__pyx_kp_u_calcQuadraticBounds_line_298, __pyx_k_calcQuadraticBounds_line_298, sizeof(__pyx_k_calcQuadraticBounds_line_298), 0, 1, 0, 0}, + {&__pyx_n_s_calcQuadraticParameters, __pyx_k_calcQuadraticParameters, sizeof(__pyx_k_calcQuadraticParameters), 0, 0, 1, 1}, + {&__pyx_n_s_calcQuadraticPoints, __pyx_k_calcQuadraticPoints, sizeof(__pyx_k_calcQuadraticPoints), 0, 0, 1, 1}, + {&__pyx_n_s_class_getitem, __pyx_k_class_getitem, sizeof(__pyx_k_class_getitem), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, + {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1}, + {&__pyx_n_s_cos, __pyx_k_cos, sizeof(__pyx_k_cos), 0, 0, 1, 1}, + {&__pyx_n_s_cubicPointAtT, __pyx_k_cubicPointAtT, sizeof(__pyx_k_cubicPointAtT), 0, 0, 1, 1}, + {&__pyx_n_u_cubicPointAtT, __pyx_k_cubicPointAtT, sizeof(__pyx_k_cubicPointAtT), 0, 1, 0, 1}, + {&__pyx_n_s_cubicPointAtTC, __pyx_k_cubicPointAtTC, sizeof(__pyx_k_cubicPointAtTC), 0, 0, 1, 1}, + {&__pyx_n_u_cubicPointAtTC, __pyx_k_cubicPointAtTC, sizeof(__pyx_k_cubicPointAtTC), 0, 1, 0, 1}, + {&__pyx_n_s_curve, __pyx_k_curve, sizeof(__pyx_k_curve), 0, 0, 1, 1}, + {&__pyx_n_s_curve1, __pyx_k_curve1, sizeof(__pyx_k_curve1), 0, 0, 1, 1}, + {&__pyx_n_s_curve2, __pyx_k_curve2, sizeof(__pyx_k_curve2), 0, 0, 1, 1}, + {&__pyx_n_s_curveCurveIntersections, __pyx_k_curveCurveIntersections, sizeof(__pyx_k_curveCurveIntersections), 0, 0, 1, 1}, + {&__pyx_n_u_curveCurveIntersections, __pyx_k_curveCurveIntersections, sizeof(__pyx_k_curveCurveIntersections), 0, 1, 0, 1}, + {&__pyx_kp_u_curveCurveIntersections_line_137, __pyx_k_curveCurveIntersections_line_137, sizeof(__pyx_k_curveCurveIntersections_line_137), 0, 1, 0, 0}, + {&__pyx_n_s_curveLineIntersections, __pyx_k_curveLineIntersections, sizeof(__pyx_k_curveLineIntersections), 0, 0, 1, 1}, + {&__pyx_n_u_curveLineIntersections, __pyx_k_curveLineIntersections, sizeof(__pyx_k_curveLineIntersections), 0, 1, 0, 1}, + {&__pyx_kp_u_curveLineIntersections_line_1248, __pyx_k_curveLineIntersections_line_1248, sizeof(__pyx_k_curveLineIntersections_line_1248), 0, 1, 0, 0}, + {&__pyx_n_s_curve_bounds, __pyx_k_curve_bounds, sizeof(__pyx_k_curve_bounds), 0, 0, 1, 1}, + {&__pyx_n_s_curve_curve_intersections_t, __pyx_k_curve_curve_intersections_t, sizeof(__pyx_k_curve_curve_intersections_t), 0, 0, 1, 1}, + {&__pyx_n_s_curve_curve_intersections_t_loc, __pyx_k_curve_curve_intersections_t_loc, sizeof(__pyx_k_curve_curve_intersections_t_loc), 0, 0, 1, 1}, + {&__pyx_n_s_curve_curve_intersections_t_loc_2, __pyx_k_curve_curve_intersections_t_loc_2, sizeof(__pyx_k_curve_curve_intersections_t_loc_2), 0, 0, 1, 1}, + {&__pyx_n_s_curve_line_intersections_t, __pyx_k_curve_line_intersections_t, sizeof(__pyx_k_curve_line_intersections_t), 0, 0, 1, 1}, + {&__pyx_n_s_curve_line_intersections_t_loca, __pyx_k_curve_line_intersections_t_loca, sizeof(__pyx_k_curve_line_intersections_t_loca), 0, 0, 1, 1}, + {&__pyx_n_s_cx, __pyx_k_cx, sizeof(__pyx_k_cx), 0, 0, 1, 1}, + {&__pyx_n_s_cy, __pyx_k_cy, sizeof(__pyx_k_cy), 0, 0, 1, 1}, + {&__pyx_n_s_cython, __pyx_k_cython, sizeof(__pyx_k_cython), 0, 0, 1, 1}, + {&__pyx_n_s_d, __pyx_k_d, sizeof(__pyx_k_d), 0, 0, 1, 1}, + {&__pyx_n_s_d0, __pyx_k_d0, sizeof(__pyx_k_d0), 0, 0, 1, 1}, + {&__pyx_n_s_d1, __pyx_k_d1, sizeof(__pyx_k_d1), 0, 0, 1, 1}, + {&__pyx_n_s_d1x, __pyx_k_d1x, sizeof(__pyx_k_d1x), 0, 0, 1, 1}, + {&__pyx_n_s_d1y, __pyx_k_d1y, sizeof(__pyx_k_d1y), 0, 0, 1, 1}, + {&__pyx_n_s_delta, __pyx_k_delta, sizeof(__pyx_k_delta), 0, 0, 1, 1}, + {&__pyx_n_s_delta_2, __pyx_k_delta_2, sizeof(__pyx_k_delta_2), 0, 0, 1, 1}, + {&__pyx_n_s_delta_3, __pyx_k_delta_3, sizeof(__pyx_k_delta_3), 0, 0, 1, 1}, + {&__pyx_n_s_deriv3, __pyx_k_deriv3, sizeof(__pyx_k_deriv3), 0, 0, 1, 1}, + {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, + {&__pyx_n_s_doctest, __pyx_k_doctest, sizeof(__pyx_k_doctest), 0, 0, 1, 1}, + {&__pyx_n_s_dx, __pyx_k_dx, sizeof(__pyx_k_dx), 0, 0, 1, 1}, + {&__pyx_n_s_dy, __pyx_k_dy, sizeof(__pyx_k_dy), 0, 0, 1, 1}, + {&__pyx_n_s_e, __pyx_k_e, sizeof(__pyx_k_e), 0, 0, 1, 1}, + {&__pyx_n_s_e1, __pyx_k_e1, sizeof(__pyx_k_e1), 0, 0, 1, 1}, + {&__pyx_n_s_e1x, __pyx_k_e1x, sizeof(__pyx_k_e1x), 0, 0, 1, 1}, + {&__pyx_n_s_e1y, __pyx_k_e1y, sizeof(__pyx_k_e1y), 0, 0, 1, 1}, + {&__pyx_n_s_e2, __pyx_k_e2, sizeof(__pyx_k_e2), 0, 0, 1, 1}, + {&__pyx_n_s_e2x, __pyx_k_e2x, sizeof(__pyx_k_e2x), 0, 0, 1, 1}, + {&__pyx_n_s_e2y, __pyx_k_e2y, sizeof(__pyx_k_e2y), 0, 0, 1, 1}, + {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, + {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1}, + {&__pyx_n_s_epsilon, __pyx_k_epsilon, sizeof(__pyx_k_epsilon), 0, 0, 1, 1}, + {&__pyx_n_s_epsilonDigits, __pyx_k_epsilonDigits, sizeof(__pyx_k_epsilonDigits), 0, 0, 1, 1}, + {&__pyx_n_s_ex, __pyx_k_ex, sizeof(__pyx_k_ex), 0, 0, 1, 1}, + {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1}, + {&__pyx_n_s_ey, __pyx_k_ey, sizeof(__pyx_k_ey), 0, 0, 1, 1}, + {&__pyx_n_s_failed, __pyx_k_failed, sizeof(__pyx_k_failed), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc, __pyx_k_fontTools_misc, sizeof(__pyx_k_fontTools_misc), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc_arrayTools, __pyx_k_fontTools_misc_arrayTools, sizeof(__pyx_k_fontTools_misc_arrayTools), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc_bezierTools, __pyx_k_fontTools_misc_bezierTools, sizeof(__pyx_k_fontTools_misc_bezierTools), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc_transform, __pyx_k_fontTools_misc_transform, sizeof(__pyx_k_fontTools_misc_transform), 0, 0, 1, 1}, + {&__pyx_n_s_found, __pyx_k_found, sizeof(__pyx_k_found), 0, 0, 1, 1}, + {&__pyx_kp_u_g, __pyx_k_g, sizeof(__pyx_k_g), 0, 1, 0, 0}, + {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, + {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_n_s_insert, __pyx_k_insert, sizeof(__pyx_k_insert), 0, 0, 1, 1}, + {&__pyx_n_s_intersection_ts, __pyx_k_intersection_ts, sizeof(__pyx_k_intersection_ts), 0, 0, 1, 1}, + {&__pyx_n_s_intersections, __pyx_k_intersections, sizeof(__pyx_k_intersections), 0, 0, 1, 1}, + {&__pyx_n_s_intersects, __pyx_k_intersects, sizeof(__pyx_k_intersects), 0, 0, 1, 1}, + {&__pyx_n_s_isHorizontal, __pyx_k_isHorizontal, sizeof(__pyx_k_isHorizontal), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_n_s_is_linelike, __pyx_k_is_linelike, sizeof(__pyx_k_is_linelike), 0, 0, 1, 1}, + {&__pyx_n_s_is_linelike_locals_genexpr, __pyx_k_is_linelike_locals_genexpr, sizeof(__pyx_k_is_linelike_locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_isclose, __pyx_k_isclose, sizeof(__pyx_k_isclose), 0, 0, 1, 1}, + {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, + {&__pyx_n_s_it, __pyx_k_it, sizeof(__pyx_k_it), 0, 0, 1, 1}, + {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, + {&__pyx_n_s_line, __pyx_k_line, sizeof(__pyx_k_line), 0, 0, 1, 1}, + {&__pyx_n_s_line1, __pyx_k_line1, sizeof(__pyx_k_line1), 0, 0, 1, 1}, + {&__pyx_n_s_line2, __pyx_k_line2, sizeof(__pyx_k_line2), 0, 0, 1, 1}, + {&__pyx_n_s_lineLineIntersections, __pyx_k_lineLineIntersections, sizeof(__pyx_k_lineLineIntersections), 0, 0, 1, 1}, + {&__pyx_n_u_lineLineIntersections, __pyx_k_lineLineIntersections, sizeof(__pyx_k_lineLineIntersections), 0, 1, 0, 1}, + {&__pyx_kp_u_lineLineIntersections_line_1147, __pyx_k_lineLineIntersections_line_1147, sizeof(__pyx_k_lineLineIntersections_line_1147), 0, 1, 0, 0}, + {&__pyx_n_s_linePointAtT, __pyx_k_linePointAtT, sizeof(__pyx_k_linePointAtT), 0, 0, 1, 1}, + {&__pyx_n_u_linePointAtT, __pyx_k_linePointAtT, sizeof(__pyx_k_linePointAtT), 0, 1, 0, 1}, + {&__pyx_n_s_line_t, __pyx_k_line_t, sizeof(__pyx_k_line_t), 0, 0, 1, 1}, + {&__pyx_n_s_line_t_of_pt, __pyx_k_line_t_of_pt, sizeof(__pyx_k_line_t_of_pt), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_u_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 1, 0, 1}, + {&__pyx_n_s_math, __pyx_k_math, sizeof(__pyx_k_math), 0, 0, 1, 1}, + {&__pyx_n_s_maybeline, __pyx_k_maybeline, sizeof(__pyx_k_maybeline), 0, 0, 1, 1}, + {&__pyx_n_s_mid, __pyx_k_mid, sizeof(__pyx_k_mid), 0, 0, 1, 1}, + {&__pyx_n_s_midPt, __pyx_k_midPt, sizeof(__pyx_k_midPt), 0, 0, 1, 1}, + {&__pyx_n_s_midpoint, __pyx_k_midpoint, sizeof(__pyx_k_midpoint), 0, 0, 1, 1}, + {&__pyx_n_s_mult, __pyx_k_mult, sizeof(__pyx_k_mult), 0, 0, 1, 1}, + {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_namedtuple, __pyx_k_namedtuple, sizeof(__pyx_k_namedtuple), 0, 0, 1, 1}, + {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, + {&__pyx_n_s_off1, __pyx_k_off1, sizeof(__pyx_k_off1), 0, 0, 1, 1}, + {&__pyx_n_s_off2, __pyx_k_off2, sizeof(__pyx_k_off2), 0, 0, 1, 1}, + {&__pyx_n_s_one, __pyx_k_one, sizeof(__pyx_k_one), 0, 0, 1, 1}, + {&__pyx_n_s_origDist, __pyx_k_origDist, sizeof(__pyx_k_origDist), 0, 0, 1, 1}, + {&__pyx_n_s_origin, __pyx_k_origin, sizeof(__pyx_k_origin), 0, 0, 1, 1}, + {&__pyx_n_s_p0, __pyx_k_p0, sizeof(__pyx_k_p0), 0, 0, 1, 1}, + {&__pyx_n_s_p1, __pyx_k_p1, sizeof(__pyx_k_p1), 0, 0, 1, 1}, + {&__pyx_n_s_p2, __pyx_k_p2, sizeof(__pyx_k_p2), 0, 0, 1, 1}, + {&__pyx_n_s_p3, __pyx_k_p3, sizeof(__pyx_k_p3), 0, 0, 1, 1}, + {&__pyx_n_s_pi, __pyx_k_pi, sizeof(__pyx_k_pi), 0, 0, 1, 1}, + {&__pyx_n_s_pointAtT, __pyx_k_pointAtT, sizeof(__pyx_k_pointAtT), 0, 0, 1, 1}, + {&__pyx_n_s_pointFinder, __pyx_k_pointFinder, sizeof(__pyx_k_pointFinder), 0, 0, 1, 1}, + {&__pyx_n_s_points, __pyx_k_points, sizeof(__pyx_k_points), 0, 0, 1, 1}, + {&__pyx_n_s_precision, __pyx_k_precision, sizeof(__pyx_k_precision), 0, 0, 1, 1}, + {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1}, + {&__pyx_n_s_printSegments, __pyx_k_printSegments, sizeof(__pyx_k_printSegments), 0, 0, 1, 1}, + {&__pyx_n_s_pt, __pyx_k_pt, sizeof(__pyx_k_pt), 0, 0, 1, 1}, + {&__pyx_n_u_pt, __pyx_k_pt, sizeof(__pyx_k_pt), 0, 1, 0, 1}, + {&__pyx_n_s_pt1, __pyx_k_pt1, sizeof(__pyx_k_pt1), 0, 0, 1, 1}, + {&__pyx_n_s_pt1x, __pyx_k_pt1x, sizeof(__pyx_k_pt1x), 0, 0, 1, 1}, + {&__pyx_n_s_pt1y, __pyx_k_pt1y, sizeof(__pyx_k_pt1y), 0, 0, 1, 1}, + {&__pyx_n_s_pt2, __pyx_k_pt2, sizeof(__pyx_k_pt2), 0, 0, 1, 1}, + {&__pyx_n_s_pt2x, __pyx_k_pt2x, sizeof(__pyx_k_pt2x), 0, 0, 1, 1}, + {&__pyx_n_s_pt2y, __pyx_k_pt2y, sizeof(__pyx_k_pt2y), 0, 0, 1, 1}, + {&__pyx_n_s_pt3, __pyx_k_pt3, sizeof(__pyx_k_pt3), 0, 0, 1, 1}, + {&__pyx_n_s_pt4, __pyx_k_pt4, sizeof(__pyx_k_pt4), 0, 0, 1, 1}, + {&__pyx_n_s_px, __pyx_k_px, sizeof(__pyx_k_px), 0, 0, 1, 1}, + {&__pyx_n_s_py, __pyx_k_py, sizeof(__pyx_k_py), 0, 0, 1, 1}, + {&__pyx_n_s_quadraticPointAtT, __pyx_k_quadraticPointAtT, sizeof(__pyx_k_quadraticPointAtT), 0, 0, 1, 1}, + {&__pyx_n_u_quadraticPointAtT, __pyx_k_quadraticPointAtT, sizeof(__pyx_k_quadraticPointAtT), 0, 1, 0, 1}, + {&__pyx_n_s_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 0, 1, 1}, + {&__pyx_n_s_rDD, __pyx_k_rDD, sizeof(__pyx_k_rDD), 0, 0, 1, 1}, + {&__pyx_n_s_rQ2, __pyx_k_rQ2, sizeof(__pyx_k_rQ2), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_range1, __pyx_k_range1, sizeof(__pyx_k_range1), 0, 0, 1, 1}, + {&__pyx_n_s_range2, __pyx_k_range2, sizeof(__pyx_k_range2), 0, 0, 1, 1}, + {&__pyx_n_s_rectArea, __pyx_k_rectArea, sizeof(__pyx_k_rectArea), 0, 0, 1, 1}, + {&__pyx_n_s_roots, __pyx_k_roots, sizeof(__pyx_k_roots), 0, 0, 1, 1}, + {&__pyx_n_s_rotate, __pyx_k_rotate, sizeof(__pyx_k_rotate), 0, 0, 1, 1}, + {&__pyx_n_s_round, __pyx_k_round, sizeof(__pyx_k_round), 0, 0, 1, 1}, + {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1}, + {&__pyx_n_s_s1, __pyx_k_s1, sizeof(__pyx_k_s1), 0, 0, 1, 1}, + {&__pyx_n_s_s1x, __pyx_k_s1x, sizeof(__pyx_k_s1x), 0, 0, 1, 1}, + {&__pyx_n_s_s1y, __pyx_k_s1y, sizeof(__pyx_k_s1y), 0, 0, 1, 1}, + {&__pyx_n_s_s2, __pyx_k_s2, sizeof(__pyx_k_s2), 0, 0, 1, 1}, + {&__pyx_n_s_s2x, __pyx_k_s2x, sizeof(__pyx_k_s2x), 0, 0, 1, 1}, + {&__pyx_n_s_s2y, __pyx_k_s2y, sizeof(__pyx_k_s2y), 0, 0, 1, 1}, + {&__pyx_kp_u_s_2, __pyx_k_s_2, sizeof(__pyx_k_s_2), 0, 1, 0, 0}, + {&__pyx_n_s_scale, __pyx_k_scale, sizeof(__pyx_k_scale), 0, 0, 1, 1}, + {&__pyx_n_s_sectRect, __pyx_k_sectRect, sizeof(__pyx_k_sectRect), 0, 0, 1, 1}, + {&__pyx_n_s_seen, __pyx_k_seen, sizeof(__pyx_k_seen), 0, 0, 1, 1}, + {&__pyx_n_s_seg, __pyx_k_seg, sizeof(__pyx_k_seg), 0, 0, 1, 1}, + {&__pyx_n_s_seg1, __pyx_k_seg1, sizeof(__pyx_k_seg1), 0, 0, 1, 1}, + {&__pyx_n_s_seg2, __pyx_k_seg2, sizeof(__pyx_k_seg2), 0, 0, 1, 1}, + {&__pyx_n_s_segment, __pyx_k_segment, sizeof(__pyx_k_segment), 0, 0, 1, 1}, + {&__pyx_n_s_segmentPointAtT, __pyx_k_segmentPointAtT, sizeof(__pyx_k_segmentPointAtT), 0, 0, 1, 1}, + {&__pyx_n_u_segmentPointAtT, __pyx_k_segmentPointAtT, sizeof(__pyx_k_segmentPointAtT), 0, 1, 0, 1}, + {&__pyx_n_s_segmentSegmentIntersections, __pyx_k_segmentSegmentIntersections, sizeof(__pyx_k_segmentSegmentIntersections), 0, 0, 1, 1}, + {&__pyx_n_u_segmentSegmentIntersections, __pyx_k_segmentSegmentIntersections, sizeof(__pyx_k_segmentSegmentIntersections), 0, 1, 0, 1}, + {&__pyx_kp_u_segmentSegmentIntersections_line, __pyx_k_segmentSegmentIntersections_line, sizeof(__pyx_k_segmentSegmentIntersections_line), 0, 1, 0, 0}, + {&__pyx_n_s_segmentrepr, __pyx_k_segmentrepr, sizeof(__pyx_k_segmentrepr), 0, 0, 1, 1}, + {&__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2, __pyx_k_segmentrepr_1_2_3_2_3_4_0_1_2, sizeof(__pyx_k_segmentrepr_1_2_3_2_3_4_0_1_2), 0, 1, 0, 0}, + {&__pyx_kp_u_segmentrepr_line_1465, __pyx_k_segmentrepr_line_1465, sizeof(__pyx_k_segmentrepr_line_1465), 0, 1, 0, 0}, + {&__pyx_n_s_segmentrepr_locals_genexpr, __pyx_k_segmentrepr_locals_genexpr, sizeof(__pyx_k_segmentrepr_locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_segments, __pyx_k_segments, sizeof(__pyx_k_segments), 0, 0, 1, 1}, + {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1}, + {&__pyx_n_s_slope12, __pyx_k_slope12, sizeof(__pyx_k_slope12), 0, 0, 1, 1}, + {&__pyx_n_s_slope34, __pyx_k_slope34, sizeof(__pyx_k_slope34), 0, 0, 1, 1}, + {&__pyx_n_s_solutions, __pyx_k_solutions, sizeof(__pyx_k_solutions), 0, 0, 1, 1}, + {&__pyx_n_s_solveCubic, __pyx_k_solveCubic, sizeof(__pyx_k_solveCubic), 0, 0, 1, 1}, + {&__pyx_n_u_solveCubic, __pyx_k_solveCubic, sizeof(__pyx_k_solveCubic), 0, 1, 0, 1}, + {&__pyx_kp_u_solveCubic_line_841, __pyx_k_solveCubic_line_841, sizeof(__pyx_k_solveCubic_line_841), 0, 1, 0, 0}, + {&__pyx_n_s_solveQuadratic, __pyx_k_solveQuadratic, sizeof(__pyx_k_solveQuadratic), 0, 0, 1, 1}, + {&__pyx_n_u_solveQuadratic, __pyx_k_solveQuadratic, sizeof(__pyx_k_solveQuadratic), 0, 1, 0, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_splitCubic, __pyx_k_splitCubic, sizeof(__pyx_k_splitCubic), 0, 0, 1, 1}, + {&__pyx_n_u_splitCubic, __pyx_k_splitCubic, sizeof(__pyx_k_splitCubic), 0, 1, 0, 1}, + {&__pyx_n_s_splitCubicAtT, __pyx_k_splitCubicAtT, sizeof(__pyx_k_splitCubicAtT), 0, 0, 1, 1}, + {&__pyx_n_s_splitCubicAtTC, __pyx_k_splitCubicAtTC, sizeof(__pyx_k_splitCubicAtTC), 0, 0, 1, 1}, + {&__pyx_n_u_splitCubicAtTC, __pyx_k_splitCubicAtTC, sizeof(__pyx_k_splitCubicAtTC), 0, 1, 0, 1}, + {&__pyx_n_s_splitCubicAtTC_2, __pyx_k_splitCubicAtTC_2, sizeof(__pyx_k_splitCubicAtTC_2), 0, 0, 1, 1}, + {&__pyx_n_s_splitCubicAtT_2, __pyx_k_splitCubicAtT_2, sizeof(__pyx_k_splitCubicAtT_2), 0, 0, 1, 1}, + {&__pyx_n_u_splitCubicAtT_2, __pyx_k_splitCubicAtT_2, sizeof(__pyx_k_splitCubicAtT_2), 0, 1, 0, 1}, + {&__pyx_kp_u_splitCubicAtT_line_613, __pyx_k_splitCubicAtT_line_613, sizeof(__pyx_k_splitCubicAtT_line_613), 0, 1, 0, 0}, + {&__pyx_n_s_splitCubicIntoTwoAtTC, __pyx_k_splitCubicIntoTwoAtTC, sizeof(__pyx_k_splitCubicIntoTwoAtTC), 0, 0, 1, 1}, + {&__pyx_n_u_splitCubicIntoTwoAtTC, __pyx_k_splitCubicIntoTwoAtTC, sizeof(__pyx_k_splitCubicIntoTwoAtTC), 0, 1, 0, 1}, + {&__pyx_kp_u_splitCubic_line_552, __pyx_k_splitCubic_line_552, sizeof(__pyx_k_splitCubic_line_552), 0, 1, 0, 0}, + {&__pyx_n_s_splitCubic_locals_genexpr, __pyx_k_splitCubic_locals_genexpr, sizeof(__pyx_k_splitCubic_locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_splitLine, __pyx_k_splitLine, sizeof(__pyx_k_splitLine), 0, 0, 1, 1}, + {&__pyx_n_u_splitLine, __pyx_k_splitLine, sizeof(__pyx_k_splitLine), 0, 1, 0, 1}, + {&__pyx_kp_u_splitLine_line_450, __pyx_k_splitLine_line_450, sizeof(__pyx_k_splitLine_line_450), 0, 1, 0, 0}, + {&__pyx_n_s_splitQuadratic, __pyx_k_splitQuadratic, sizeof(__pyx_k_splitQuadratic), 0, 0, 1, 1}, + {&__pyx_n_u_splitQuadratic, __pyx_k_splitQuadratic, sizeof(__pyx_k_splitQuadratic), 0, 1, 0, 1}, + {&__pyx_n_s_splitQuadraticAtT, __pyx_k_splitQuadraticAtT, sizeof(__pyx_k_splitQuadraticAtT), 0, 0, 1, 1}, + {&__pyx_n_s_splitQuadraticAtT_2, __pyx_k_splitQuadraticAtT_2, sizeof(__pyx_k_splitQuadraticAtT_2), 0, 0, 1, 1}, + {&__pyx_n_u_splitQuadraticAtT_2, __pyx_k_splitQuadraticAtT_2, sizeof(__pyx_k_splitQuadraticAtT_2), 0, 1, 0, 1}, + {&__pyx_kp_u_splitQuadraticAtT_line_589, __pyx_k_splitQuadraticAtT_line_589, sizeof(__pyx_k_splitQuadraticAtT_line_589), 0, 1, 0, 0}, + {&__pyx_kp_u_splitQuadratic_line_507, __pyx_k_splitQuadratic_line_507, sizeof(__pyx_k_splitQuadratic_line_507), 0, 1, 0, 0}, + {&__pyx_n_s_splitQuadratic_locals_genexpr, __pyx_k_splitQuadratic_locals_genexpr, sizeof(__pyx_k_splitQuadratic_locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_split_cubic_into_two, __pyx_k_split_cubic_into_two, sizeof(__pyx_k_split_cubic_into_two), 0, 0, 1, 1}, + {&__pyx_n_s_split_segment_at_t, __pyx_k_split_segment_at_t, sizeof(__pyx_k_split_segment_at_t), 0, 0, 1, 1}, + {&__pyx_n_s_sqrt, __pyx_k_sqrt, sizeof(__pyx_k_sqrt), 0, 0, 1, 1}, + {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, + {&__pyx_n_s_swapped, __pyx_k_swapped, sizeof(__pyx_k_swapped), 0, 0, 1, 1}, + {&__pyx_n_s_sx, __pyx_k_sx, sizeof(__pyx_k_sx), 0, 0, 1, 1}, + {&__pyx_n_s_sy, __pyx_k_sy, sizeof(__pyx_k_sy), 0, 0, 1, 1}, + {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, + {&__pyx_n_s_t, __pyx_k_t, sizeof(__pyx_k_t), 0, 0, 1, 1}, + {&__pyx_n_s_t1, __pyx_k_t1, sizeof(__pyx_k_t1), 0, 0, 1, 1}, + {&__pyx_n_u_t1, __pyx_k_t1, sizeof(__pyx_k_t1), 0, 1, 0, 1}, + {&__pyx_n_s_t1_2, __pyx_k_t1_2, sizeof(__pyx_k_t1_2), 0, 0, 1, 1}, + {&__pyx_n_s_t1_3, __pyx_k_t1_3, sizeof(__pyx_k_t1_3), 0, 0, 1, 1}, + {&__pyx_n_s_t2, __pyx_k_t2, sizeof(__pyx_k_t2), 0, 0, 1, 1}, + {&__pyx_n_u_t2, __pyx_k_t2, sizeof(__pyx_k_t2), 0, 1, 0, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_testmod, __pyx_k_testmod, sizeof(__pyx_k_testmod), 0, 0, 1, 1}, + {&__pyx_n_s_theta, __pyx_k_theta, sizeof(__pyx_k_theta), 0, 0, 1, 1}, + {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1}, + {&__pyx_n_s_tolerance, __pyx_k_tolerance, sizeof(__pyx_k_tolerance), 0, 0, 1, 1}, + {&__pyx_n_s_transformPoints, __pyx_k_transformPoints, sizeof(__pyx_k_transformPoints), 0, 0, 1, 1}, + {&__pyx_n_s_translate, __pyx_k_translate, sizeof(__pyx_k_translate), 0, 0, 1, 1}, + {&__pyx_n_s_ts, __pyx_k_ts, sizeof(__pyx_k_ts), 0, 0, 1, 1}, + {&__pyx_n_s_two, __pyx_k_two, sizeof(__pyx_k_two), 0, 0, 1, 1}, + {&__pyx_n_s_unique_key, __pyx_k_unique_key, sizeof(__pyx_k_unique_key), 0, 0, 1, 1}, + {&__pyx_n_s_unique_values, __pyx_k_unique_values, sizeof(__pyx_k_unique_values), 0, 0, 1, 1}, + {&__pyx_n_s_v0, __pyx_k_v0, sizeof(__pyx_k_v0), 0, 0, 1, 1}, + {&__pyx_n_s_v1, __pyx_k_v1, sizeof(__pyx_k_v1), 0, 0, 1, 1}, + {&__pyx_n_s_v2, __pyx_k_v2, sizeof(__pyx_k_v2), 0, 0, 1, 1}, + {&__pyx_n_s_v3, __pyx_k_v3, sizeof(__pyx_k_v3), 0, 0, 1, 1}, + {&__pyx_n_s_v4, __pyx_k_v4, sizeof(__pyx_k_v4), 0, 0, 1, 1}, + {&__pyx_n_s_where, __pyx_k_where, sizeof(__pyx_k_where), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {&__pyx_n_s_x0, __pyx_k_x0, sizeof(__pyx_k_x0), 0, 0, 1, 1}, + {&__pyx_n_s_x1, __pyx_k_x1, sizeof(__pyx_k_x1), 0, 0, 1, 1}, + {&__pyx_n_s_x2, __pyx_k_x2, sizeof(__pyx_k_x2), 0, 0, 1, 1}, + {&__pyx_n_s_x3, __pyx_k_x3, sizeof(__pyx_k_x3), 0, 0, 1, 1}, + {&__pyx_n_s_x4, __pyx_k_x4, sizeof(__pyx_k_x4), 0, 0, 1, 1}, + {&__pyx_n_s_xDiff, __pyx_k_xDiff, sizeof(__pyx_k_xDiff), 0, 0, 1, 1}, + {&__pyx_n_s_xRoots, __pyx_k_xRoots, sizeof(__pyx_k_xRoots), 0, 0, 1, 1}, + {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, + {&__pyx_n_s_y1, __pyx_k_y1, sizeof(__pyx_k_y1), 0, 0, 1, 1}, + {&__pyx_n_s_y2, __pyx_k_y2, sizeof(__pyx_k_y2), 0, 0, 1, 1}, + {&__pyx_n_s_y3, __pyx_k_y3, sizeof(__pyx_k_y3), 0, 0, 1, 1}, + {&__pyx_n_s_y4, __pyx_k_y4, sizeof(__pyx_k_y4), 0, 0, 1, 1}, + {&__pyx_n_s_yDiff, __pyx_k_yDiff, sizeof(__pyx_k_yDiff), 0, 0, 1, 1}, + {&__pyx_n_s_yRoots, __pyx_k_yRoots, sizeof(__pyx_k_yRoots), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 14, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(0, 14, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 709, __pyx_L1_error) + __pyx_builtin_round = __Pyx_GetBuiltinName(__pyx_n_s_round); if (!__pyx_builtin_round) __PYX_ERR(0, 899, __pyx_L1_error) + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 1119, __pyx_L1_error) + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 1472, __pyx_L1_error) + __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 1483, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/misc/bezierTools.py":704 + * ts = list(ts) + * segments = [] + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * ax, ay = a + */ + __pyx_tuple__2 = PyTuple_Pack(2, __pyx_int_0, __pyx_float_0_0); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 704, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "fontTools/misc/bezierTools.py":1119 + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Unknown_curve_degree); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 1119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "fontTools/misc/bezierTools.py":1313 + * + * if not range1: + * range1 = (0.0, 1.0) # <<<<<<<<<<<<<< + * if not range2: + * range2 = (0.0, 1.0) + */ + __pyx_tuple__5 = PyTuple_Pack(2, __pyx_float_0_0, __pyx_float_1_0); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 1313, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "fontTools/misc/bezierTools.py":1322 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_n_s_r); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 1322, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + __pyx_codeobj__7 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__6, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_midpoint, 1322, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__7)) __PYX_ERR(0, 1322, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1459 + * intersections = lineLineIntersections(*seg1, *seg2) + * else: + * raise ValueError("Couldn't work out which intersection function to use") # <<<<<<<<<<<<<< + * if not swapped: + * return intersections + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Couldn_t_work_out_which_intersec); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 1459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * + */ + __pyx_tuple__12 = PyTuple_Pack(5, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_tolerance); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicArcLength, 56, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 56, __pyx_L1_error) + __pyx_tuple__14 = PyTuple_Pack(1, ((PyObject*)__pyx_float_0_005)); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__14); + __Pyx_GIVEREF(__pyx_tuple__14); + + /* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + __pyx_tuple__15 = PyTuple_Pack(6, __pyx_n_s_p0, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p3, __pyx_n_s_mid, __pyx_n_s_deriv3); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_split_cubic_into_two, 75, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(0, 75, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, + */ + __pyx_tuple__17 = PyTuple_Pack(9, __pyx_n_s_mult, __pyx_n_s_p0, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p3, __pyx_n_s_arch, __pyx_n_s_box, __pyx_n_s_one, __pyx_n_s_two); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__17); + __Pyx_GIVEREF(__pyx_tuple__17); + __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicArcLengthCRecurse, 84, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(0, 84, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_tuple__19 = PyTuple_Pack(6, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_tolerance, __pyx_n_s_mult); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__19); + __Pyx_GIVEREF(__pyx_tuple__19); + __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicArcLengthC, 104, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 104, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + __pyx_tuple__21 = PyTuple_Pack(3, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__21); + __Pyx_GIVEREF(__pyx_tuple__21); + __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcQuadraticArcLength, 151, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(0, 151, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_tuple__23 = PyTuple_Pack(14, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_scale, __pyx_n_s_origDist, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_x0, __pyx_n_s_x1, __pyx_n_s_Len, __pyx_n_s_d0, __pyx_n_s_d1, __pyx_n_s_d, __pyx_n_s_n); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__23); + __Pyx_GIVEREF(__pyx_tuple__23); + __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 14, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcQuadraticArcLengthC, 186, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 186, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_approximateQuadraticArcLength, 237, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) __PYX_ERR(0, 237, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_tuple__26 = PyTuple_Pack(6, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_v0, __pyx_n_s_v1, __pyx_n_s_v2); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__26); + __Pyx_GIVEREF(__pyx_tuple__26); + __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_approximateQuadraticArcLengthC, 254, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) __PYX_ERR(0, 254, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + __pyx_tuple__28 = PyTuple_Pack(14, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_ax2, __pyx_n_s_ay2, __pyx_n_s_roots, __pyx_n_s_points, __pyx_n_s_t); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__28); + __Pyx_GIVEREF(__pyx_tuple__28); + __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 14, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcQuadraticBounds, 298, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) __PYX_ERR(0, 298, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * + */ + __pyx_tuple__30 = PyTuple_Pack(4, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__30); + __Pyx_GIVEREF(__pyx_tuple__30); + __pyx_codeobj__31 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__30, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_approximateCubicArcLength, 332, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__31)) __PYX_ERR(0, 332, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_tuple__32 = PyTuple_Pack(9, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_v0, __pyx_n_s_v1, __pyx_n_s_v2, __pyx_n_s_v3, __pyx_n_s_v4); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(0, 362, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__32); + __Pyx_GIVEREF(__pyx_tuple__32); + __pyx_codeobj__33 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__32, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_approximateCubicArcLengthC, 362, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__33)) __PYX_ERR(0, 362, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + __pyx_tuple__34 = PyTuple_Pack(23, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_dx, __pyx_n_s_dy, __pyx_n_s_ax3, __pyx_n_s_ay3, __pyx_n_s_bx2, __pyx_n_s_by2, __pyx_n_s_xRoots, __pyx_n_s_yRoots, __pyx_n_s_roots, __pyx_n_s_points, __pyx_n_s_t, __pyx_n_s_t, __pyx_n_s_t); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 412, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__34); + __Pyx_GIVEREF(__pyx_tuple__34); + __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 23, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicBounds, 412, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) __PYX_ERR(0, 412, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * + */ + __pyx_tuple__36 = PyTuple_Pack(15, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_where, __pyx_n_s_isHorizontal, __pyx_n_s_pt1x, __pyx_n_s_pt1y, __pyx_n_s_pt2x, __pyx_n_s_pt2y, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_a, __pyx_n_s_t, __pyx_n_s_midPt); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__36); + __Pyx_GIVEREF(__pyx_tuple__36); + __pyx_codeobj__37 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 15, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__36, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitLine, 450, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__37)) __PYX_ERR(0, 450, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * + */ + __pyx_tuple__38 = PyTuple_Pack(11, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_where, __pyx_n_s_isHorizontal, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_solutions, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__38); + __Pyx_GIVEREF(__pyx_tuple__38); + __pyx_codeobj__39 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__38, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitQuadratic, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__39)) __PYX_ERR(0, 507, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * + */ + __pyx_tuple__40 = PyTuple_Pack(13, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_where, __pyx_n_s_isHorizontal, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_solutions, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__40)) __PYX_ERR(0, 552, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__40); + __Pyx_GIVEREF(__pyx_tuple__40); + __pyx_codeobj__41 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__40, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubic, 552, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__41)) __PYX_ERR(0, 552, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * + */ + __pyx_tuple__42 = PyTuple_Pack(7, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_ts, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__42); + __Pyx_GIVEREF(__pyx_tuple__42); + __pyx_codeobj__43 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__42, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitQuadraticAtT_2, 589, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__43)) __PYX_ERR(0, 589, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * + */ + __pyx_tuple__44 = PyTuple_Pack(9, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_ts, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d); if (unlikely(!__pyx_tuple__44)) __PYX_ERR(0, 613, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__44); + __Pyx_GIVEREF(__pyx_tuple__44); + __pyx_codeobj__45 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__44, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubicAtT_2, 613, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__45)) __PYX_ERR(0, 613, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":637 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, + */ + __pyx_codeobj_ = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS|CO_GENERATOR, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__44, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubicAtTC, 637, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj_)) __PYX_ERR(0, 637, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":661 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + __pyx_tuple__46 = PyTuple_Pack(12, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_t, __pyx_n_s_t2, __pyx_n_s_1_t, __pyx_n_s_1_t_2, __pyx_n_s_2_t_1_t, __pyx_n_s_pointAtT, __pyx_n_s_off1, __pyx_n_s_off2); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(0, 661, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__46); + __Pyx_GIVEREF(__pyx_tuple__46); + __pyx_codeobj__47 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 12, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__46, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubicIntoTwoAtTC, 661, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__47)) __PYX_ERR(0, 661, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":701 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] + */ + __pyx_tuple__48 = PyTuple_Pack(26, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_ts, __pyx_n_s_segments, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_i, __pyx_n_s_t1, __pyx_n_s_t2, __pyx_n_s_delta, __pyx_n_s_delta_2, __pyx_n_s_a1x, __pyx_n_s_a1y, __pyx_n_s_b1x, __pyx_n_s_b1y, __pyx_n_s_t1_2, __pyx_n_s_c1x, __pyx_n_s_c1y, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3); if (unlikely(!__pyx_tuple__48)) __PYX_ERR(0, 701, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__48); + __Pyx_GIVEREF(__pyx_tuple__48); + __pyx_codeobj__49 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 26, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__48, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitQuadraticAtT, 701, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__49)) __PYX_ERR(0, 701, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":728 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) + */ + __pyx_tuple__50 = PyTuple_Pack(34, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_ts, __pyx_n_s_segments, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_dx, __pyx_n_s_dy, __pyx_n_s_i, __pyx_n_s_t1, __pyx_n_s_t2, __pyx_n_s_delta, __pyx_n_s_delta_2, __pyx_n_s_delta_3, __pyx_n_s_t1_2, __pyx_n_s_t1_3, __pyx_n_s_a1x, __pyx_n_s_a1y, __pyx_n_s_b1x, __pyx_n_s_b1y, __pyx_n_s_c1x, __pyx_n_s_c1y, __pyx_n_s_d1x, __pyx_n_s_d1y, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4); if (unlikely(!__pyx_tuple__50)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__50); + __Pyx_GIVEREF(__pyx_tuple__50); + __pyx_codeobj__51 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 34, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__50, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubicAtT, 728, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__51)) __PYX_ERR(0, 728, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":763 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, + */ + __pyx_tuple__52 = PyTuple_Pack(21, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_ts, __pyx_n_s_t1, __pyx_n_s_t2, __pyx_n_s_delta, __pyx_n_s_delta_2, __pyx_n_s_delta_3, __pyx_n_s_a1, __pyx_n_s_b1, __pyx_n_s_c1, __pyx_n_s_d1, __pyx_n_s_i, __pyx_n_s_t1_2, __pyx_n_s_t1_3, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__52); + __Pyx_GIVEREF(__pyx_tuple__52); + __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 21, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS|CO_GENERATOR, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__52, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_splitCubicAtTC_2, 763, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(0, 763, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":808 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * + */ + __pyx_tuple__53 = PyTuple_Pack(7, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_sqrt, __pyx_n_s_roots, __pyx_n_s_DD, __pyx_n_s_rDD); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__53); + __Pyx_GIVEREF(__pyx_tuple__53); + __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_solveQuadratic, 808, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) __PYX_ERR(0, 808, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":841 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * + */ + __pyx_tuple__55 = PyTuple_Pack(19, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_a1, __pyx_n_s_a2, __pyx_n_s_a3, __pyx_n_s_Q, __pyx_n_s_R, __pyx_n_s_R2, __pyx_n_s_Q3, __pyx_n_s_R2_Q3, __pyx_n_s_x, __pyx_n_s_theta, __pyx_n_s_rQ2, __pyx_n_s_a1_3, __pyx_n_s_x0, __pyx_n_s_x1, __pyx_n_s_x2); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__55); + __Pyx_GIVEREF(__pyx_tuple__55); + __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_solveCubic, 841, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) __PYX_ERR(0, 841, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":938 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + __pyx_tuple__57 = PyTuple_Pack(13, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x3, __pyx_n_s_y3, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_ax, __pyx_n_s_ay); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(0, 938, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__57); + __Pyx_GIVEREF(__pyx_tuple__57); + __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcQuadraticParameters, 938, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) __PYX_ERR(0, 938, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":949 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + __pyx_tuple__59 = PyTuple_Pack(18, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x3, __pyx_n_s_y3, __pyx_n_s_x4, __pyx_n_s_y4, __pyx_n_s_dx, __pyx_n_s_dy, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_ax, __pyx_n_s_ay); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 949, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__59); + __Pyx_GIVEREF(__pyx_tuple__59); + __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 18, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicParameters, 949, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 949, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":981 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_tuple__61 = PyTuple_Pack(15, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x3, __pyx_n_s_y3); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(0, 981, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__61); + __Pyx_GIVEREF(__pyx_tuple__61); + __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 15, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcQuadraticPoints, 981, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(0, 981, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":994 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_tuple__63 = PyTuple_Pack(20, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_d, __pyx_n_s_ax, __pyx_n_s_ay, __pyx_n_s_bx, __pyx_n_s_by, __pyx_n_s_cx, __pyx_n_s_cy, __pyx_n_s_dx, __pyx_n_s_dy, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x3, __pyx_n_s_y3, __pyx_n_s_x4, __pyx_n_s_y4); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 994, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__63); + __Pyx_GIVEREF(__pyx_tuple__63); + __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 20, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_calcCubicPoints, 994, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(0, 994, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1033 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * + */ + __pyx_tuple__65 = PyTuple_Pack(3, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_t); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 1033, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__65); + __Pyx_GIVEREF(__pyx_tuple__65); + __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_linePointAtT, 1033, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 1033, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1046 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * + */ + __pyx_tuple__67 = PyTuple_Pack(6, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_t, __pyx_n_s_x, __pyx_n_s_y); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1046, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__67); + __Pyx_GIVEREF(__pyx_tuple__67); + __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_quadraticPointAtT, 1046, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1046, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1061 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * + */ + __pyx_tuple__69 = PyTuple_Pack(10, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_t, __pyx_n_s_t2, __pyx_n_s_1_t, __pyx_n_s_1_t_2, __pyx_n_s_x, __pyx_n_s_y); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 1061, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__69); + __Pyx_GIVEREF(__pyx_tuple__69); + __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_cubicPointAtT, 1061, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 1061, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1087 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + __pyx_tuple__71 = PyTuple_Pack(8, __pyx_n_s_pt1, __pyx_n_s_pt2, __pyx_n_s_pt3, __pyx_n_s_pt4, __pyx_n_s_t, __pyx_n_s_t2, __pyx_n_s_1_t, __pyx_n_s_1_t_2); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__71); + __Pyx_GIVEREF(__pyx_tuple__71); + __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_cubicPointAtTC, 1087, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) __PYX_ERR(0, 1087, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1112 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) + */ + __pyx_tuple__73 = PyTuple_Pack(2, __pyx_n_s_seg, __pyx_n_s_t); if (unlikely(!__pyx_tuple__73)) __PYX_ERR(0, 1112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__73); + __Pyx_GIVEREF(__pyx_tuple__73); + __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_segmentPointAtT, 1112, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) __PYX_ERR(0, 1112, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1127 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e + */ + __pyx_tuple__75 = PyTuple_Pack(9, __pyx_n_s_s, __pyx_n_s_e, __pyx_n_s_pt, __pyx_n_s_sx, __pyx_n_s_sy, __pyx_n_s_ex, __pyx_n_s_ey, __pyx_n_s_px, __pyx_n_s_py); if (unlikely(!__pyx_tuple__75)) __PYX_ERR(0, 1127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__75); + __Pyx_GIVEREF(__pyx_tuple__75); + __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_line_t_of_pt, 1127, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) __PYX_ERR(0, 1127, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1141 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + */ + __pyx_tuple__77 = PyTuple_Pack(5, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_origin, __pyx_n_s_xDiff, __pyx_n_s_yDiff); if (unlikely(!__pyx_tuple__77)) __PYX_ERR(0, 1141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__77); + __Pyx_GIVEREF(__pyx_tuple__77); + __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_both_points_are_on_same_side_of, 1141, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) __PYX_ERR(0, 1141, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1147 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * + */ + __pyx_tuple__79 = PyTuple_Pack(17, __pyx_n_s_s1, __pyx_n_s_e1, __pyx_n_s_s2, __pyx_n_s_e2, __pyx_n_s_s1x, __pyx_n_s_s1y, __pyx_n_s_e1x, __pyx_n_s_e1y, __pyx_n_s_s2x, __pyx_n_s_s2y, __pyx_n_s_e2x, __pyx_n_s_e2y, __pyx_n_s_x, __pyx_n_s_slope34, __pyx_n_s_y, __pyx_n_s_pt, __pyx_n_s_slope12); if (unlikely(!__pyx_tuple__79)) __PYX_ERR(0, 1147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__79); + __Pyx_GIVEREF(__pyx_tuple__79); + __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_lineLineIntersections, 1147, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) __PYX_ERR(0, 1147, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1225 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find + */ + __pyx_tuple__81 = PyTuple_Pack(4, __pyx_n_s_segment, __pyx_n_s_start, __pyx_n_s_end, __pyx_n_s_angle); if (unlikely(!__pyx_tuple__81)) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__81); + __Pyx_GIVEREF(__pyx_tuple__81); + __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_alignment_transformation, 1225, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) __PYX_ERR(0, 1225, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1235 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + */ + __pyx_tuple__83 = PyTuple_Pack(10, __pyx_n_s_curve, __pyx_n_s_line, __pyx_n_s_aligned_curve, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_intersections, __pyx_n_s_d, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__83)) __PYX_ERR(0, 1235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__83); + __Pyx_GIVEREF(__pyx_tuple__83); + __pyx_codeobj__84 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__83, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_curve_line_intersections_t, 1235, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__84)) __PYX_ERR(0, 1235, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1248 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * + */ + __pyx_tuple__85 = PyTuple_Pack(7, __pyx_n_s_curve, __pyx_n_s_line, __pyx_n_s_pointFinder, __pyx_n_s_intersections, __pyx_n_s_t, __pyx_n_s_pt, __pyx_n_s_line_t); if (unlikely(!__pyx_tuple__85)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__85); + __Pyx_GIVEREF(__pyx_tuple__85); + __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_curveLineIntersections, 1248, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) __PYX_ERR(0, 1248, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1286 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) + */ + __pyx_tuple__87 = PyTuple_Pack(1, __pyx_n_s_c); if (unlikely(!__pyx_tuple__87)) __PYX_ERR(0, 1286, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__87); + __Pyx_GIVEREF(__pyx_tuple__87); + __pyx_codeobj__88 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__87, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_curve_bounds, 1286, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__88)) __PYX_ERR(0, 1286, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1294 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c + */ + __pyx_tuple__89 = PyTuple_Pack(5, __pyx_n_s_c, __pyx_n_s_t, __pyx_n_s_s, __pyx_n_s_e, __pyx_n_s_midpoint); if (unlikely(!__pyx_tuple__89)) __PYX_ERR(0, 1294, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__89); + __Pyx_GIVEREF(__pyx_tuple__89); + __pyx_codeobj__90 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__89, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_split_segment_at_t, 1294, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__90)) __PYX_ERR(0, 1294, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + __pyx_tuple__92 = PyTuple_Pack(25, __pyx_n_s_curve1, __pyx_n_s_curve2, __pyx_n_s_precision, __pyx_n_s_range1, __pyx_n_s_range2, __pyx_n_s_bounds1, __pyx_n_s_bounds2, __pyx_n_s_intersects, __pyx_n_s__91, __pyx_n_s_midpoint, __pyx_n_s_midpoint, __pyx_n_s_c11, __pyx_n_s_c12, __pyx_n_s_c11_range, __pyx_n_s_c12_range, __pyx_n_s_c21, __pyx_n_s_c22, __pyx_n_s_c21_range, __pyx_n_s_c22_range, __pyx_n_s_found, __pyx_n_s_unique_key, __pyx_n_s_seen, __pyx_n_s_unique_values, __pyx_n_s_ts, __pyx_n_s_key); if (unlikely(!__pyx_tuple__92)) __PYX_ERR(0, 1306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__92); + __Pyx_GIVEREF(__pyx_tuple__92); + __pyx_codeobj__93 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 25, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__92, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_curve_curve_intersections_t, 1306, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__93)) __PYX_ERR(0, 1306, __pyx_L1_error) + __pyx_tuple__94 = PyTuple_Pack(3, ((PyObject*)__pyx_float_1eneg_3), Py_None, Py_None); if (unlikely(!__pyx_tuple__94)) __PYX_ERR(0, 1306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__94); + __Pyx_GIVEREF(__pyx_tuple__94); + + /* "fontTools/misc/bezierTools.py":1373 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) + */ + __pyx_tuple__95 = PyTuple_Pack(4, __pyx_n_s_segment, __pyx_n_s_maybeline, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__95)) __PYX_ERR(0, 1373, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__95); + __Pyx_GIVEREF(__pyx_tuple__95); + __pyx_codeobj__96 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__95, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_is_linelike, 1373, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__96)) __PYX_ERR(0, 1373, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1378 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * + */ + __pyx_tuple__97 = PyTuple_Pack(6, __pyx_n_s_curve1, __pyx_n_s_curve2, __pyx_n_s_line1, __pyx_n_s_line2, __pyx_n_s_intersection_ts, __pyx_n_s_ts); if (unlikely(!__pyx_tuple__97)) __PYX_ERR(0, 1378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__97); + __Pyx_GIVEREF(__pyx_tuple__97); + __pyx_codeobj__98 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__97, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_curveCurveIntersections, 1378, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__98)) __PYX_ERR(0, 1378, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1417 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * + */ + __pyx_tuple__99 = PyTuple_Pack(5, __pyx_n_s_seg1, __pyx_n_s_seg2, __pyx_n_s_swapped, __pyx_n_s_intersections, __pyx_n_s_i); if (unlikely(!__pyx_tuple__99)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__99); + __Pyx_GIVEREF(__pyx_tuple__99); + __pyx_codeobj__100 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__99, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_segmentSegmentIntersections, 1417, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__100)) __PYX_ERR(0, 1417, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1465 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + */ + __pyx_tuple__101 = PyTuple_Pack(4, __pyx_n_s_obj, __pyx_n_s_it, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__101)) __PYX_ERR(0, 1465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__101); + __Pyx_GIVEREF(__pyx_tuple__101); + __pyx_codeobj__102 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__101, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_segmentrepr, 1465, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__102)) __PYX_ERR(0, 1465, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1478 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. + */ + __pyx_tuple__103 = PyTuple_Pack(2, __pyx_n_s_segments, __pyx_n_s_segment); if (unlikely(!__pyx_tuple__103)) __PYX_ERR(0, 1478, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__103); + __Pyx_GIVEREF(__pyx_tuple__103); + __pyx_codeobj__104 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__103, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_misc_bezierTools_p, __pyx_n_s_printSegments, 1478, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__104)) __PYX_ERR(0, 1478, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_float_0_0 = PyFloat_FromDouble(0.0); if (unlikely(!__pyx_float_0_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_0_5 = PyFloat_FromDouble(0.5); if (unlikely(!__pyx_float_0_5)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_1_0 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_float_1_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_2_0 = PyFloat_FromDouble(2.0); if (unlikely(!__pyx_float_2_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_3_0 = PyFloat_FromDouble(3.0); if (unlikely(!__pyx_float_3_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_4_0 = PyFloat_FromDouble(4.0); if (unlikely(!__pyx_float_4_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_9_0 = PyFloat_FromDouble(9.0); if (unlikely(!__pyx_float_9_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_1eneg_3 = PyFloat_FromDouble(1e-3); if (unlikely(!__pyx_float_1eneg_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_27_0 = PyFloat_FromDouble(27.0); if (unlikely(!__pyx_float_27_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_54_0 = PyFloat_FromDouble(54.0); if (unlikely(!__pyx_float_54_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_0_005 = PyFloat_FromDouble(0.005); if (unlikely(!__pyx_float_0_005)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_0_125 = PyFloat_FromDouble(0.125); if (unlikely(!__pyx_float_0_125)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_1eneg_10 = PyFloat_FromDouble(1e-10); if (unlikely(!__pyx_float_1eneg_10)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_float_neg_2_0 = PyFloat_FromDouble(-2.0); if (unlikely(!__pyx_float_neg_2_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + return 0; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)) __PYX_ERR(0, 546, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) < 0) __PYX_ERR(0, 546, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) < 0) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)) __PYX_ERR(0, 583, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 583, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)) __PYX_ERR(0, 637, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) < 0) __PYX_ERR(0, 637, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) < 0) __PYX_ERR(0, 637, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)) __PYX_ERR(0, 763, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) < 0) __PYX_ERR(0, 763, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) < 0) __PYX_ERR(0, 763, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)) __PYX_ERR(0, 1245, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) < 0) __PYX_ERR(0, 1245, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) < 0) __PYX_ERR(0, 1245, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)) __PYX_ERR(0, 1306, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) < 0) __PYX_ERR(0, 1306, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) < 0) __PYX_ERR(0, 1306, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)) __PYX_ERR(0, 1375, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) < 0) __PYX_ERR(0, 1375, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) < 0) __PYX_ERR(0, 1375, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)) __PYX_ERR(0, 1475, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec, __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) < 0) __PYX_ERR(0, 1475, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) < 0) __PYX_ERR(0, 1475, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_dictoffset && __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_bezierTools(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_bezierTools}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "bezierTools", + __pyx_k_fontTools_misc_bezierTools_py_to, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initbezierTools(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initbezierTools(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_bezierTools(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_bezierTools(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_bezierTools(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'bezierTools' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("bezierTools", __pyx_methods, __pyx_k_fontTools_misc_bezierTools_py_to, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to bezierTools pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_bezierTools(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_fontTools__misc__bezierTools) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.misc.bezierTools")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.misc.bezierTools", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "fontTools/misc/bezierTools.py":5 + * """ + * + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea # <<<<<<<<<<<<<< + * from fontTools.misc.transform import Identity + * import math + */ + __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_calcBounds); + __Pyx_GIVEREF(__pyx_n_s_calcBounds); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_calcBounds)) __PYX_ERR(0, 5, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_sectRect); + __Pyx_GIVEREF(__pyx_n_s_sectRect); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_sectRect)) __PYX_ERR(0, 5, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_rectArea); + __Pyx_GIVEREF(__pyx_n_s_rectArea); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_rectArea)) __PYX_ERR(0, 5, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_fontTools_misc_arrayTools, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_calcBounds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcBounds, __pyx_t_2) < 0) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_sectRect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_sectRect, __pyx_t_2) < 0) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_rectArea); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_rectArea, __pyx_t_2) < 0) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":6 + * + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea + * from fontTools.misc.transform import Identity # <<<<<<<<<<<<<< + * import math + * from collections import namedtuple + */ + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_s_Identity); + __Pyx_GIVEREF(__pyx_n_s_Identity); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_Identity)) __PYX_ERR(0, 6, __pyx_L1_error); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_fontTools_misc_transform, __pyx_t_3, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Identity); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Identity, __pyx_t_3) < 0) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":7 + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea + * from fontTools.misc.transform import Identity + * import math # <<<<<<<<<<<<<< + * from collections import namedtuple + * + */ + __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_math, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_math, __pyx_t_2) < 0) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":8 + * from fontTools.misc.transform import Identity + * import math + * from collections import namedtuple # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_namedtuple); + __Pyx_GIVEREF(__pyx_n_s_namedtuple); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_namedtuple)) __PYX_ERR(0, 8, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_namedtuple); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_namedtuple, __pyx_t_2) < 0) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":10 + * from collections import namedtuple + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "fontTools/misc/bezierTools.py":13 + * import cython + * + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_True) < 0) __PYX_ERR(0, 13, __pyx_L2_error) + + /* "fontTools/misc/bezierTools.py":10 + * from collections import namedtuple + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L7_try_end; + __pyx_L2_error:; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":14 + * + * COMPILED = cython.compiled + * except (AttributeError, ImportError): # <<<<<<<<<<<<<< + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + */ + __pyx_t_6 = __Pyx_PyErr_ExceptionMatches2(__pyx_builtin_AttributeError, __pyx_builtin_ImportError); + if (__pyx_t_6) { + __Pyx_AddTraceback("fontTools.misc.bezierTools", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_2, &__pyx_t_7) < 0) __PYX_ERR(0, 14, __pyx_L4_except_error) + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":16 + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython # <<<<<<<<<<<<<< + * + * COMPILED = False + */ + __pyx_t_8 = PyList_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 16, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_n_s_cython); + __Pyx_GIVEREF(__pyx_n_s_cython); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_n_s_cython)) __PYX_ERR(0, 16, __pyx_L4_except_error); + __pyx_t_9 = __Pyx_Import(__pyx_n_s_fontTools_misc, __pyx_t_8, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 16, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_ImportFrom(__pyx_t_9, __pyx_n_s_cython); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 16, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cython, __pyx_t_8) < 0) __PYX_ERR(0, 16, __pyx_L4_except_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":18 + * from fontTools.misc import cython + * + * COMPILED = False # <<<<<<<<<<<<<< + * + * + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_False) < 0) __PYX_ERR(0, 18, __pyx_L4_except_error) + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L3_exception_handled; + } + goto __pyx_L4_except_error; + + /* "fontTools/misc/bezierTools.py":10 + * from collections import namedtuple + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + __pyx_L4_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L3_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_4, __pyx_t_5); + __pyx_L7_try_end:; + } + + /* "fontTools/misc/bezierTools.py":21 + * + * + * Intersection = namedtuple("Intersection", ["pt", "t1", "t2"]) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_namedtuple); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_u_pt); + __Pyx_GIVEREF(__pyx_n_u_pt); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_u_pt)) __PYX_ERR(0, 21, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_t1); + __Pyx_GIVEREF(__pyx_n_u_t1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_u_t1)) __PYX_ERR(0, 21, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_t2); + __Pyx_GIVEREF(__pyx_n_u_t2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_u_t2)) __PYX_ERR(0, 21, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_Intersection); + __Pyx_GIVEREF(__pyx_n_u_Intersection); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_Intersection)) __PYX_ERR(0, 21, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Intersection, __pyx_t_2) < 0) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":24 + * + * + * __all__ = [ # <<<<<<<<<<<<<< + * "approximateCubicArcLength", + * "approximateCubicArcLengthC", + */ + __pyx_t_2 = PyList_New(28); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_u_approximateCubicArcLength); + __Pyx_GIVEREF(__pyx_n_u_approximateCubicArcLength); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_u_approximateCubicArcLength)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_approximateCubicArcLengthC); + __Pyx_GIVEREF(__pyx_n_u_approximateCubicArcLengthC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_u_approximateCubicArcLengthC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_approximateQuadraticArcLength); + __Pyx_GIVEREF(__pyx_n_u_approximateQuadraticArcLength); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_u_approximateQuadraticArcLength)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_approximateQuadraticArcLengthC); + __Pyx_GIVEREF(__pyx_n_u_approximateQuadraticArcLengthC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_u_approximateQuadraticArcLengthC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcCubicArcLength); + __Pyx_GIVEREF(__pyx_n_u_calcCubicArcLength); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_u_calcCubicArcLength)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcCubicArcLengthC); + __Pyx_GIVEREF(__pyx_n_u_calcCubicArcLengthC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_u_calcCubicArcLengthC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcQuadraticArcLength); + __Pyx_GIVEREF(__pyx_n_u_calcQuadraticArcLength); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_u_calcQuadraticArcLength)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcQuadraticArcLengthC); + __Pyx_GIVEREF(__pyx_n_u_calcQuadraticArcLengthC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_u_calcQuadraticArcLengthC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcCubicBounds); + __Pyx_GIVEREF(__pyx_n_u_calcCubicBounds); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 8, __pyx_n_u_calcCubicBounds)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_calcQuadraticBounds); + __Pyx_GIVEREF(__pyx_n_u_calcQuadraticBounds); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 9, __pyx_n_u_calcQuadraticBounds)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitLine); + __Pyx_GIVEREF(__pyx_n_u_splitLine); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 10, __pyx_n_u_splitLine)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitQuadratic); + __Pyx_GIVEREF(__pyx_n_u_splitQuadratic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 11, __pyx_n_u_splitQuadratic)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitCubic); + __Pyx_GIVEREF(__pyx_n_u_splitCubic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 12, __pyx_n_u_splitCubic)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitQuadraticAtT_2); + __Pyx_GIVEREF(__pyx_n_u_splitQuadraticAtT_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 13, __pyx_n_u_splitQuadraticAtT_2)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitCubicAtT_2); + __Pyx_GIVEREF(__pyx_n_u_splitCubicAtT_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 14, __pyx_n_u_splitCubicAtT_2)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitCubicAtTC); + __Pyx_GIVEREF(__pyx_n_u_splitCubicAtTC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 15, __pyx_n_u_splitCubicAtTC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_splitCubicIntoTwoAtTC); + __Pyx_GIVEREF(__pyx_n_u_splitCubicIntoTwoAtTC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 16, __pyx_n_u_splitCubicIntoTwoAtTC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_solveQuadratic); + __Pyx_GIVEREF(__pyx_n_u_solveQuadratic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 17, __pyx_n_u_solveQuadratic)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_solveCubic); + __Pyx_GIVEREF(__pyx_n_u_solveCubic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 18, __pyx_n_u_solveCubic)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_quadraticPointAtT); + __Pyx_GIVEREF(__pyx_n_u_quadraticPointAtT); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 19, __pyx_n_u_quadraticPointAtT)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_cubicPointAtT); + __Pyx_GIVEREF(__pyx_n_u_cubicPointAtT); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 20, __pyx_n_u_cubicPointAtT)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_cubicPointAtTC); + __Pyx_GIVEREF(__pyx_n_u_cubicPointAtTC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 21, __pyx_n_u_cubicPointAtTC)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_linePointAtT); + __Pyx_GIVEREF(__pyx_n_u_linePointAtT); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 22, __pyx_n_u_linePointAtT)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_segmentPointAtT); + __Pyx_GIVEREF(__pyx_n_u_segmentPointAtT); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 23, __pyx_n_u_segmentPointAtT)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_lineLineIntersections); + __Pyx_GIVEREF(__pyx_n_u_lineLineIntersections); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 24, __pyx_n_u_lineLineIntersections)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_curveLineIntersections); + __Pyx_GIVEREF(__pyx_n_u_curveLineIntersections); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 25, __pyx_n_u_curveLineIntersections)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_curveCurveIntersections); + __Pyx_GIVEREF(__pyx_n_u_curveCurveIntersections); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 26, __pyx_n_u_curveCurveIntersections)) __PYX_ERR(0, 24, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_segmentSegmentIntersections); + __Pyx_GIVEREF(__pyx_n_u_segmentSegmentIntersections); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 27, __pyx_n_u_segmentSegmentIntersections)) __PYX_ERR(0, 24, __pyx_L1_error); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_2) < 0) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_1calcCubicArcLength, 0, __pyx_n_s_calcCubicArcLength, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__13)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_tuple__14); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicArcLength, __pyx_t_2) < 0) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_3_split_cubic_into_two, 0, __pyx_n_s_split_cubic_into_two, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__16)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_split_cubic_into_two, __pyx_t_2) < 0) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse, 0, __pyx_n_s_calcCubicArcLengthCRecurse, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__18)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicArcLengthCRecurse, __pyx_t_2) < 0) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":115 + * mult=cython.double, + * ) + * def calcCubicArcLengthC(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * + */ + __pyx_t_2 = PyFloat_FromDouble(((double)0.005)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC, 0, __pyx_n_s_calcCubicArcLengthC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__20)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicArcLengthC, __pyx_t_2) < 0) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":129 + * + * + * epsilonDigits = 6 # <<<<<<<<<<<<<< + * epsilon = 1e-10 + * + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_epsilonDigits, __pyx_int_6) < 0) __PYX_ERR(0, 129, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":130 + * + * epsilonDigits = 6 + * epsilon = 1e-10 # <<<<<<<<<<<<<< + * + * + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_epsilon, __pyx_float_1eneg_10) < 0) __PYX_ERR(0, 130, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength, 0, __pyx_n_s_calcQuadraticArcLength, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__22)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcQuadraticArcLength, __pyx_t_2) < 0) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC, 0, __pyx_n_s_calcQuadraticArcLengthC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__24)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcQuadraticArcLengthC, __pyx_t_2) < 0) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength, 0, __pyx_n_s_approximateQuadraticArcLength, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__25)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_approximateQuadraticArcLength, __pyx_t_2) < 0) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC, 0, __pyx_n_s_approximateQuadraticArcLengthC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__27)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_approximateQuadraticArcLengthC, __pyx_t_2) < 0) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_17calcQuadraticBounds, 0, __pyx_n_s_calcQuadraticBounds, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__29)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcQuadraticBounds, __pyx_t_2) < 0) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_19approximateCubicArcLength, 0, __pyx_n_s_approximateCubicArcLength, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__31)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_approximateCubicArcLength, __pyx_t_2) < 0) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC, 0, __pyx_n_s_approximateCubicArcLengthC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__33)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 362, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_approximateCubicArcLengthC, __pyx_t_2) < 0) __PYX_ERR(0, 362, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_23calcCubicBounds, 0, __pyx_n_s_calcCubicBounds, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 412, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicBounds, __pyx_t_2) < 0) __PYX_ERR(0, 412, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_25splitLine, 0, __pyx_n_s_splitLine, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__37)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitLine, __pyx_t_2) < 0) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_27splitQuadratic, 0, __pyx_n_s_splitQuadratic, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__39)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitQuadratic, __pyx_t_2) < 0) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_29splitCubic, 0, __pyx_n_s_splitCubic, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__41)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 552, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubic, __pyx_t_2) < 0) __PYX_ERR(0, 552, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_31splitQuadraticAtT, 0, __pyx_n_s_splitQuadraticAtT_2, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__43)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitQuadraticAtT_2, __pyx_t_2) < 0) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_33splitCubicAtT, 0, __pyx_n_s_splitCubicAtT_2, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__45)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 613, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicAtT_2, __pyx_t_2) < 0) __PYX_ERR(0, 613, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":637 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_35splitCubicAtTC, 0, __pyx_n_s_splitCubicAtTC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj_)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 637, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicAtTC, __pyx_t_2) < 0) __PYX_ERR(0, 637, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":661 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC, 0, __pyx_n_s_splitCubicIntoTwoAtTC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__47)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 661, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicIntoTwoAtTC, __pyx_t_2) < 0) __PYX_ERR(0, 661, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":701 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT, 0, __pyx_n_s_splitQuadraticAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__49)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 701, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitQuadraticAtT, __pyx_t_2) < 0) __PYX_ERR(0, 701, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":728 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_42_splitCubicAtT, 0, __pyx_n_s_splitCubicAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__51)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicAtT, __pyx_t_2) < 0) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":763 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_44_splitCubicAtTC, 0, __pyx_n_s_splitCubicAtTC_2, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__3)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicAtTC_2, __pyx_t_2) < 0) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":805 + * # + * + * from math import sqrt, acos, cos, pi # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_2 = PyList_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_sqrt); + __Pyx_GIVEREF(__pyx_n_s_sqrt); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_sqrt)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_acos); + __Pyx_GIVEREF(__pyx_n_s_acos); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_acos)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_cos); + __Pyx_GIVEREF(__pyx_n_s_cos); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_cos)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_pi); + __Pyx_GIVEREF(__pyx_n_s_pi); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_pi)) __PYX_ERR(0, 805, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_math, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_sqrt, __pyx_t_2) < 0) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_acos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_acos, __pyx_t_2) < 0) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_cos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cos, __pyx_t_2) < 0) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_pi); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pi, __pyx_t_2) < 0) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":808 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_47solveQuadratic, 0, __pyx_n_s_solveQuadratic, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__54)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults), 1)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_CyFunction_Defaults(__pyx_defaults, __pyx_t_3)->__pyx_arg_sqrt = __pyx_t_2; + __Pyx_GIVEREF(__pyx_t_2); + __pyx_t_2 = 0; + __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_solveQuadratic, __pyx_t_3) < 0) __PYX_ERR(0, 808, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":841 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_49solveCubic, 0, __pyx_n_s_solveCubic, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__56)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_solveCubic, __pyx_t_3) < 0) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":938 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_51calcQuadraticParameters, 0, __pyx_n_s_calcQuadraticParameters, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__58)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 938, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcQuadraticParameters, __pyx_t_3) < 0) __PYX_ERR(0, 938, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":949 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_53calcCubicParameters, 0, __pyx_n_s_calcCubicParameters, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__60)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 949, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicParameters, __pyx_t_3) < 0) __PYX_ERR(0, 949, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":981 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_55calcQuadraticPoints, 0, __pyx_n_s_calcQuadraticPoints, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__62)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 981, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcQuadraticPoints, __pyx_t_3) < 0) __PYX_ERR(0, 981, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":994 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_57calcCubicPoints, 0, __pyx_n_s_calcCubicPoints, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 994, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calcCubicPoints, __pyx_t_3) < 0) __PYX_ERR(0, 994, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1033 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_59linePointAtT, 0, __pyx_n_s_linePointAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1033, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_linePointAtT, __pyx_t_3) < 0) __PYX_ERR(0, 1033, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1046 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_61quadraticPointAtT, 0, __pyx_n_s_quadraticPointAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1046, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_quadraticPointAtT, __pyx_t_3) < 0) __PYX_ERR(0, 1046, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1061 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_63cubicPointAtT, 0, __pyx_n_s_cubicPointAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1061, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cubicPointAtT, __pyx_t_3) < 0) __PYX_ERR(0, 1061, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1087 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_65cubicPointAtTC, 0, __pyx_n_s_cubicPointAtTC, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__72)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cubicPointAtTC, __pyx_t_3) < 0) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1112 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_67segmentPointAtT, 0, __pyx_n_s_segmentPointAtT, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__74)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1112, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_segmentPointAtT, __pyx_t_3) < 0) __PYX_ERR(0, 1112, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1127 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_69_line_t_of_pt, 0, __pyx_n_s_line_t_of_pt, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__76)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_line_t_of_pt, __pyx_t_3) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1141 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin, 0, __pyx_n_s_both_points_are_on_same_side_of, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__78)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_both_points_are_on_same_side_of, __pyx_t_3) < 0) __PYX_ERR(0, 1141, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1147 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_73lineLineIntersections, 0, __pyx_n_s_lineLineIntersections, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__80)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_lineLineIntersections, __pyx_t_3) < 0) __PYX_ERR(0, 1147, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1225 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_75_alignment_transformation, 0, __pyx_n_s_alignment_transformation, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__82)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_alignment_transformation, __pyx_t_3) < 0) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1235 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t, 0, __pyx_n_s_curve_line_intersections_t, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__84)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curve_line_intersections_t, __pyx_t_3) < 0) __PYX_ERR(0, 1235, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1248 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_79curveLineIntersections, 0, __pyx_n_s_curveLineIntersections, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__86)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curveLineIntersections, __pyx_t_3) < 0) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1286 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_81_curve_bounds, 0, __pyx_n_s_curve_bounds, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__88)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1286, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curve_bounds, __pyx_t_3) < 0) __PYX_ERR(0, 1286, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1294 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_83_split_segment_at_t, 0, __pyx_n_s_split_segment_at_t, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__90)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1294, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_split_segment_at_t, __pyx_t_3) < 0) __PYX_ERR(0, 1294, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1306 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t, 0, __pyx_n_s_curve_curve_intersections_t, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__93)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__94); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curve_curve_intersections_t, __pyx_t_3) < 0) __PYX_ERR(0, 1306, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1373 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_87_is_linelike, 0, __pyx_n_s_is_linelike, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__96)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1373, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_is_linelike, __pyx_t_3) < 0) __PYX_ERR(0, 1373, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1378 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_89curveCurveIntersections, 0, __pyx_n_s_curveCurveIntersections, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__98)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_curveCurveIntersections, __pyx_t_3) < 0) __PYX_ERR(0, 1378, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1417 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections, 0, __pyx_n_s_segmentSegmentIntersections, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__100)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_segmentSegmentIntersections, __pyx_t_3) < 0) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1465 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_93_segmentrepr, 0, __pyx_n_s_segmentrepr, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__102)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_segmentrepr, __pyx_t_3) < 0) __PYX_ERR(0, 1465, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1478 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_95printSegments, 0, __pyx_n_s_printSegments, NULL, __pyx_n_s_fontTools_misc_bezierTools, __pyx_d, ((PyObject *)__pyx_codeobj__104)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1478, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_printSegments, __pyx_t_3) < 0) __PYX_ERR(0, 1478, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1486 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * import sys + * import doctest + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = (__Pyx_PyUnicode_Equals(__pyx_t_3, __pyx_n_u_main, Py_EQ)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 1486, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":1487 + * + * if __name__ == "__main__": + * import sys # <<<<<<<<<<<<<< + * import doctest + * + */ + __pyx_t_3 = __Pyx_ImportDottedModule(__pyx_n_s_sys, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_3) < 0) __PYX_ERR(0, 1487, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1488 + * if __name__ == "__main__": + * import sys + * import doctest # <<<<<<<<<<<<<< + * + * sys.exit(doctest.testmod().failed) + */ + __pyx_t_3 = __Pyx_ImportDottedModule(__pyx_n_s_doctest, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1488, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_doctest, __pyx_t_3) < 0) __PYX_ERR(0, 1488, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1490 + * import doctest + * + * sys.exit(doctest.testmod().failed) # <<<<<<<<<<<<<< + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_sys); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_exit); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_doctest); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_testmod); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_failed); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1486 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * import sys + * import doctest + */ + } + + /* "fontTools/misc/bezierTools.py":1 + * # -*- coding: utf-8 -*- # <<<<<<<<<<<<<< + * """fontTools.misc.bezierTools.py -- tools for working with Bezier path segments. + * """ + */ + __pyx_t_3 = __Pyx_PyDict_NewPresized(15); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_calcQuadraticArcLength_line_151, __pyx_kp_u_Calculates_the_arc_length_for_a) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_calcQuadraticBounds_line_298, __pyx_kp_u_Calculates_the_bounding_rectangl) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_approximateCubicArcLength_line_3, __pyx_kp_u_Approximates_the_arc_length_for) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_calcCubicBounds_line_412, __pyx_kp_u_Calculates_the_bounding_rectangl_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_splitLine_line_450, __pyx_kp_u_Split_a_line_at_a_given_coordina) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_splitQuadratic_line_507, __pyx_kp_u_Split_a_quadratic_Bezier_curve_a) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_splitCubic_line_552, __pyx_kp_u_Split_a_cubic_Bezier_curve_at_a) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_splitQuadraticAtT_line_589, __pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_splitCubicAtT_line_613, __pyx_kp_u_Split_a_cubic_Bezier_curve_at_on) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_solveCubic_line_841, __pyx_kp_u_Solve_a_cubic_equation_Solves_a) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_lineLineIntersections_line_1147, __pyx_kp_u_Finds_intersections_between_two) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_curveLineIntersections_line_1248, __pyx_kp_u_Finds_intersections_between_a_cu) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_curveCurveIntersections_line_137, __pyx_kp_u_Finds_intersections_between_a_cu_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_segmentSegmentIntersections_line, __pyx_kp_u_Finds_intersections_between_two_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_kp_u_segmentrepr_line_1465, __pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_3) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.misc.bezierTools", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.misc.bezierTools"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; // error + return kwvalues[i]; + } + } + return NULL; // not found (no exception set) +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); // transfer ownership of value to values + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#elif CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_MultiplyCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op2))) { + const long a = intval; + long b = PyInt_AS_LONG(op2); + +#ifdef HAVE_LONG_LONG + if (sizeof(PY_LONG_LONG) > sizeof(long)) { + PY_LONG_LONG result = (PY_LONG_LONG)a * (PY_LONG_LONG)b; + return (result >= LONG_MIN && result <= LONG_MAX) ? + PyInt_FromLong((long)result) : PyLong_FromLongLong(result); + } +#endif +#if CYTHON_USE_TYPE_SLOTS + return PyInt_Type.tp_as_number->nb_multiply(op1, op2); +#else + return PyNumber_Multiply(op1, op2); +#endif + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op2))) { + const long a = intval; + long b, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG lla = intval; + PY_LONG_LONG llb, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op2))) { + return __Pyx_NewRef(op2); + } + if (likely(__Pyx_PyLong_IsCompact(op2))) { + b = __Pyx_PyLong_CompactValue(op2); + } else { + const digit* digits = __Pyx_PyLong_Digits(op2); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op2); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT+30) { + b = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT+30) { + llb = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT+30) { + b = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT+30) { + b = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT+30) { + llb = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT+30) { + b = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT+30) { + b = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT+30) { + llb = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT+30) { + b = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_multiply(op1, op2); + } + } + CYTHON_UNUSED_VAR(a); + CYTHON_UNUSED_VAR(b); + #ifdef HAVE_LONG_LONG + llb = b; + goto long_long; + #else + return PyLong_Type.tp_as_number->nb_multiply(op1, op2); + #endif + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla * llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op2)) { + const long a = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double b = __pyx_PyFloat_AsDouble(op2); +#else + double b = PyFloat_AS_DOUBLE(op2); +#endif + double result; + + PyFPE_START_PROTECT("multiply", return NULL) + result = ((double)a) * (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceMultiply : PyNumber_Multiply)(op1, op2); +} +#endif + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + PyObject* exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_TrueDivideObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + + if (8 * sizeof(long) <= 53 || likely(labs(a) <= ((PY_LONG_LONG)1 << 53))) { + return PyFloat_FromDouble((double)a / (double)b); + } + return PyInt_Type.tp_as_number->nb_true_divide(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + const long b = intval; + long a, x; + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + } + if (likely(__Pyx_PyLong_IsCompact(op1))) { + a = __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT && 1 * PyLong_SHIFT < 53) { + a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT && 1 * PyLong_SHIFT < 53) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT && 2 * PyLong_SHIFT < 53) { + a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT && 2 * PyLong_SHIFT < 53) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT && 3 * PyLong_SHIFT < 53) { + a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT && 3 * PyLong_SHIFT < 53) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_true_divide(op1, op2); + } + } + if ((8 * sizeof(long) <= 53 || likely(labs(a) <= ((PY_LONG_LONG)1 << 53))) + || __Pyx_PyLong_DigitCount(op1) <= 52 / PyLong_SHIFT) { + return PyFloat_FromDouble((double)a / (double)b); + } + return PyLong_Type.tp_as_number->nb_true_divide(op1, op2); + return PyLong_FromLong(x); + + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + double result; + + PyFPE_START_PROTECT("divide", return NULL) + result = ((double)a) / (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceTrueDivide : PyNumber_TrueDivide)(op1, op2); +} +#endif + +/* PyIntCompare */ +static CYTHON_INLINE int __Pyx_PyInt_BoolNeObjC(PyObject *op1, PyObject *op2, long intval, long inplace) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(inplace); + if (op1 == op2) { + return 0; + } + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + return (a != b); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + if (intval == 0) { + return (__Pyx_PyLong_IsZero(op1) != 1); + } else if (intval < 0) { + if (__Pyx_PyLong_IsNonNeg(op1)) + return 1; + intval = -intval; + } else { + if (__Pyx_PyLong_IsNeg(op1)) + return 1; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + return (unequal != 0); + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + return ((double)a != (double)b); + } + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_NE)); +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_subscript) { + PyObject *r, *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { + PyObject *runerr = NULL; + Py_ssize_t key_value; + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + __Pyx_TypeName index_type_name = __Pyx_PyType_GetName(Py_TYPE(index)); + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); + __Pyx_DECREF_TypeName(index_type_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { + __Pyx_TypeName obj_type_name; + if (likely(PyType_Check(obj))) { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_n_s_class_getitem); + if (!meth) { + PyErr_Clear(); + } else { + PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); + Py_DECREF(meth); + return result; + } + } + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { + PyTypeObject *tp = Py_TYPE(obj); + PyMappingMethods *mm = tp->tp_as_mapping; + PySequenceMethods *sm = tp->tp_as_sequence; + if (likely(mm && mm->mp_subscript)) { + return mm->mp_subscript(obj, key); + } + if (likely(sm && sm->sq_item)) { + return __Pyx_PyObject_GetIndex(obj, key); + } + return __Pyx_PyObject_GetItem_Slow(obj, key); +} +#endif + +/* PyIntCompare */ +static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(inplace); + if (op1 == op2) { + return 1; + } + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + return (a == b); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + if (intval == 0) { + return (__Pyx_PyLong_IsZero(op1) == 1); + } else if (intval < 0) { + if (__Pyx_PyLong_IsNonNeg(op1)) + return 0; + intval = -intval; + } else { + if (__Pyx_PyLong_IsNeg(op1)) + return 0; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + return (unequal == 0); + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + return ((double)a == (double)b); + } + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_EQ)); +} + +/* RaiseUnboundLocalError */ +static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { + PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* pep479 */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) { + PyObject *exc, *val, *tb, *cur_exc; + __Pyx_PyThreadState_declare + #ifdef __Pyx_StopAsyncIteration_USED + int is_async_stopiteration = 0; + #endif + CYTHON_MAYBE_UNUSED_VAR(in_async_gen); + cur_exc = PyErr_Occurred(); + if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) { + #ifdef __Pyx_StopAsyncIteration_USED + if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) { + is_async_stopiteration = 1; + } else + #endif + return; + } + __Pyx_PyThreadState_assign + __Pyx_GetException(&exc, &val, &tb); + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + PyErr_SetString(PyExc_RuntimeError, + #ifdef __Pyx_StopAsyncIteration_USED + is_async_stopiteration ? "async generator raised StopAsyncIteration" : + in_async_gen ? "async generator raised StopIteration" : + #endif + "generator raised StopIteration"); +} + +/* FixUpExtensionType */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* FetchSharedCythonModule */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#elif PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2 + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_GetMethod; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* PyObjectCallNoArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* CoroutineBase */ +#include +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *__pyx_tstate, PyObject **pvalue) { + PyObject *et, *ev, *tb; + PyObject *value = NULL; + CYTHON_UNUSED_VAR(__pyx_tstate); + __Pyx_ErrFetch(&et, &ev, &tb); + if (!et) { + Py_XDECREF(tb); + Py_XDECREF(ev); + Py_INCREF(Py_None); + *pvalue = Py_None; + return 0; + } + if (likely(et == PyExc_StopIteration)) { + if (!ev) { + Py_INCREF(Py_None); + value = Py_None; + } +#if PY_VERSION_HEX >= 0x030300A0 + else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } +#endif + else if (unlikely(PyTuple_Check(ev))) { + if (PyTuple_GET_SIZE(ev) >= 1) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + value = PyTuple_GET_ITEM(ev, 0); + Py_INCREF(value); +#else + value = PySequence_ITEM(ev, 0); +#endif + } else { + Py_INCREF(Py_None); + value = Py_None; + } + Py_DECREF(ev); + } + else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { + value = ev; + } + if (likely(value)) { + Py_XDECREF(tb); + Py_DECREF(et); + *pvalue = value; + return 0; + } + } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + PyErr_NormalizeException(&et, &ev, &tb); + if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + Py_XDECREF(tb); + Py_DECREF(et); +#if PY_VERSION_HEX >= 0x030300A0 + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); +#else + { + PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args); + Py_DECREF(ev); + if (likely(args)) { + value = PySequence_GetItem(args, 0); + Py_DECREF(args); + } + if (unlikely(!value)) { + __Pyx_ErrRestore(NULL, NULL, NULL); + Py_INCREF(Py_None); + value = Py_None; + } + } +#endif + *pvalue = value; + return 0; +} +static CYTHON_INLINE +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_CLEAR(exc_state->exc_value); +#else + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +#endif +} +#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { + msg = "coroutine already executing"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { + msg = "async generator already executing"; + #endif + } else { + msg = "generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); +} +#define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_NotStartedError(PyObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(gen)) { + msg = "can't send non-None value to a just-started coroutine"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a just-started async generator"; + #endif + } else { + msg = "can't send non-None value to a just-started generator"; + } + PyErr_SetString(PyExc_TypeError, msg); +} +#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing) (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) { + CYTHON_MAYBE_UNUSED_VAR(gen); + CYTHON_MAYBE_UNUSED_VAR(closing); + #ifdef __Pyx_Coroutine_USED + if (!closing && __Pyx_Coroutine_Check(gen)) { + PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); + } else + #endif + if (value) { + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); + else + #endif + PyErr_SetNone(PyExc_StopIteration); + } +} +static +PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { + __Pyx_PyThreadState_declare + PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; + PyObject *retval; + assert(!self->is_running); + if (unlikely(self->resume_label == 0)) { + if (unlikely(value && value != Py_None)) { + return __Pyx_Coroutine_NotStartedError((PyObject*)self); + } + } + if (unlikely(self->resume_label == -1)) { + return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); + } +#if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + tstate = __pyx_tstate; +#else + tstate = __Pyx_PyThreadState_Current; +#endif + exc_state = &self->gi_exc_state; + if (exc_state->exc_value) { + #if CYTHON_COMPILING_IN_PYPY + #else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #elif PY_VERSION_HEX >= 0x030B00a4 + exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback; + #else + exc_tb = exc_state->exc_traceback; + #endif + if (exc_tb) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + assert(f->f_back == NULL); + #if PY_VERSION_HEX >= 0x030B00A1 + f->f_back = PyThreadState_GetFrame(tstate); + #else + Py_XINCREF(tstate->frame); + f->f_back = tstate->frame; + #endif + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + Py_DECREF(exc_tb); + #endif + } + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } else { + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } +#endif + self->is_running = 1; + retval = self->body(self, tstate, value); + self->is_running = 0; +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif + return retval; +} +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { +#if CYTHON_COMPILING_IN_PYPY + CYTHON_UNUSED_VAR(exc_state); +#else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 + if (!exc_state->exc_value) return; + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #else + exc_tb = exc_state->exc_traceback; + #endif + if (likely(exc_tb)) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + Py_CLEAR(f->f_back); + #if PY_VERSION_HEX >= 0x030B00a4 + Py_DECREF(exc_tb); + #endif + } +#endif +} +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_MethodReturn(PyObject* gen, PyObject *retval) { + CYTHON_MAYBE_UNUSED_VAR(gen); + if (unlikely(!retval)) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (!__Pyx_PyErr_Occurred()) { + PyObject *exc = PyExc_StopIteration; + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + exc = __Pyx_PyExc_StopAsyncIteration; + #endif + __Pyx_PyErr_SetNone(exc); + } + } + return retval; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) +static CYTHON_INLINE +PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) { +#if PY_VERSION_HEX <= 0x030A00A1 + return _PyGen_Send(gen, arg); +#else + PyObject *result; + if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { +#if PY_VERSION_HEX < 0x030d00A1 + _PyGen_SetStopIterationValue(result); +#else + if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) { + PyErr_SetObject(PyExc_StopIteration, result); + } else { + PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result); + if (likely(exc != NULL)) { + PyErr_SetObject(PyExc_StopIteration, exc); + Py_DECREF(exc); + } + } +#endif + } + Py_DECREF(result); + result = NULL; + } + return result; +#endif +} +#endif +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { + PyObject *ret; + PyObject *val = NULL; + __Pyx_Coroutine_Undelegate(gen); + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); + ret = __Pyx_Coroutine_SendEx(gen, val, 0); + Py_XDECREF(val); + return ret; +} +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { + PyObject *retval; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + ret = __Pyx_async_gen_asend_send(yf, value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyCoro_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + { + if (value == Py_None) + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + else + ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value); + } + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + retval = __Pyx_Coroutine_FinishDelegation(gen); + } else { + retval = __Pyx_Coroutine_SendEx(gen, value, 0); + } + return __Pyx_Coroutine_MethodReturn(self, retval); +} +static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { + PyObject *retval = NULL; + int err = 0; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + if (__Pyx_CoroutineAwait_CheckExact(yf)) { + retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + retval = __Pyx_async_gen_asend_close(yf, NULL); + } else + if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { + retval = __Pyx_async_gen_athrow_close(yf, NULL); + } else + #endif + { + PyObject *meth; + gen->is_running = 1; + meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_close); + if (unlikely(!meth)) { + if (unlikely(PyErr_Occurred())) { + PyErr_WriteUnraisable(yf); + } + } else { + retval = __Pyx_PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (unlikely(!retval)) + err = -1; + } + gen->is_running = 0; + } + Py_XDECREF(retval); + return err; +} +static PyObject *__Pyx_Generator_Next(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Generator_Next(yf); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, Py_None); + } else + #endif + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + return __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_SendEx(gen, Py_None, 0); +} +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); + return __Pyx_Coroutine_Close(self); +} +static PyObject *__Pyx_Coroutine_Close(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *retval, *raised_exception; + PyObject *yf = gen->yieldfrom; + int err = 0; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + Py_INCREF(yf); + err = __Pyx_Coroutine_CloseIter(gen, yf); + __Pyx_Coroutine_Undelegate(gen); + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + retval = __Pyx_Coroutine_SendEx(gen, NULL, 1); + if (unlikely(retval)) { + const char *msg; + Py_DECREF(retval); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(self)) { + msg = "coroutine ignored GeneratorExit"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(self)) { +#if PY_VERSION_HEX < 0x03060000 + msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)"; +#else + msg = "async generator ignored GeneratorExit"; +#endif + #endif + } else { + msg = "generator ignored GeneratorExit"; + } + PyErr_SetString(PyExc_RuntimeError, msg); + return NULL; + } + raised_exception = PyErr_Occurred(); + if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) { + if (raised_exception) PyErr_Clear(); + Py_INCREF(Py_None); + return Py_None; + } + return NULL; +} +static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, + PyObject *args, int close_on_genexit) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + Py_INCREF(yf); + if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { + int err = __Pyx_Coroutine_CloseIter(gen, yf); + Py_DECREF(yf); + __Pyx_Coroutine_Undelegate(gen); + if (err < 0) + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); + goto throw_here; + } + gen->is_running = 1; + if (0 + #ifdef __Pyx_Generator_USED + || __Pyx_Generator_CheckExact(yf) + #endif + #ifdef __Pyx_Coroutine_USED + || __Pyx_Coroutine_Check(yf) + #endif + ) { + ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { + ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); + #endif + } else { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_throw); + if (unlikely(!meth)) { + Py_DECREF(yf); + if (unlikely(PyErr_Occurred())) { + gen->is_running = 0; + return NULL; + } + __Pyx_Coroutine_Undelegate(gen); + gen->is_running = 0; + goto throw_here; + } + if (likely(args)) { + ret = __Pyx_PyObject_Call(meth, args, NULL); + } else { + PyObject *cargs[4] = {NULL, typ, val, tb}; + ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } + Py_DECREF(meth); + } + gen->is_running = 0; + Py_DECREF(yf); + if (!ret) { + ret = __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_MethodReturn(self, ret); + } +throw_here: + __Pyx_Raise(typ, val, tb, NULL); + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); +} +static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { + PyObject *typ; + PyObject *val = NULL; + PyObject *tb = NULL; + if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))) + return NULL; + return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); +} +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_VISIT(exc_state->exc_value); +#else + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); +#endif + return 0; +} +static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { + Py_VISIT(gen->closure); + Py_VISIT(gen->classobj); + Py_VISIT(gen->yieldfrom); + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); +} +static int __Pyx_Coroutine_clear(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + Py_CLEAR(gen->closure); + Py_CLEAR(gen->classobj); + Py_CLEAR(gen->yieldfrom); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); + } +#endif + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_frame); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + Py_CLEAR(gen->gi_modulename); + return 0; +} +static void __Pyx_Coroutine_dealloc(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject_GC_UnTrack(gen); + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); + if (gen->resume_label >= 0) { + PyObject_GC_Track(self); +#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE + if (unlikely(PyObject_CallFinalizerFromDealloc(self))) +#else + Py_TYPE(gen)->tp_del(self); + if (unlikely(Py_REFCNT(self) > 0)) +#endif + { + return; + } + PyObject_GC_UnTrack(self); + } +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); + } +#endif + __Pyx_Coroutine_clear(self); + __Pyx_PyHeapTypeObject_GC_Del(gen); +} +static void __Pyx_Coroutine_del(PyObject *self) { + PyObject *error_type, *error_value, *error_traceback; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PyThreadState_declare + if (gen->resume_label < 0) { + return; + } +#if !CYTHON_USE_TP_FINALIZE + assert(self->ob_refcnt == 0); + __Pyx_SET_REFCNT(self, 1); +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); + if (unlikely(!res)) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); + return; + } + } +#endif + if (unlikely(gen->resume_label == 0 && !error_value)) { +#ifdef __Pyx_Coroutine_USED +#ifdef __Pyx_Generator_USED + if (!__Pyx_Generator_CheckExact(self)) +#endif + { + PyObject_GC_UnTrack(self); +#if PY_MAJOR_VERSION >= 3 || defined(PyErr_WarnFormat) + if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) + PyErr_WriteUnraisable(self); +#else + {PyObject *msg; + char *cmsg; + #if CYTHON_COMPILING_IN_PYPY + msg = NULL; + cmsg = (char*) "coroutine was never awaited"; + #else + char *cname; + PyObject *qualname; + qualname = gen->gi_qualname; + cname = PyString_AS_STRING(qualname); + msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname); + if (unlikely(!msg)) { + PyErr_Clear(); + cmsg = (char*) "coroutine was never awaited"; + } else { + cmsg = PyString_AS_STRING(msg); + } + #endif + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) + PyErr_WriteUnraisable(self); + Py_XDECREF(msg);} +#endif + PyObject_GC_Track(self); + } +#endif + } else { + PyObject *res = __Pyx_Coroutine_Close(self); + if (unlikely(!res)) { + if (PyErr_Occurred()) + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); +#if !CYTHON_USE_TP_FINALIZE + assert(Py_REFCNT(self) > 0); + if (likely(--self->ob_refcnt == 0)) { + return; + } + { + Py_ssize_t refcnt = Py_REFCNT(self); + _Py_NewReference(self); + __Pyx_SET_REFCNT(self, refcnt); + } +#if CYTHON_COMPILING_IN_CPYTHON + assert(PyType_IS_GC(Py_TYPE(self)) && + _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + _Py_DEC_REFTOTAL; +#endif +#ifdef COUNT_ALLOCS + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; +#endif +#endif +} +static PyObject * +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_name; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_name, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_qualname; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_qualname, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context) +{ + PyObject *frame = self->gi_frame; + CYTHON_UNUSED_VAR(context); + if (!frame) { + if (unlikely(!self->gi_code)) { + Py_RETURN_NONE; + } + frame = (PyObject *) PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + (PyCodeObject*) self->gi_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (unlikely(!frame)) + return NULL; + self->gi_frame = frame; + } + Py_INCREF(frame); + return frame; +} +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); + if (unlikely(!gen)) + return NULL; + return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + gen->body = body; + gen->closure = closure; + Py_XINCREF(closure); + gen->is_running = 0; + gen->resume_label = 0; + gen->classobj = NULL; + gen->yieldfrom = NULL; + #if PY_VERSION_HEX >= 0x030B00a4 + gen->gi_exc_state.exc_value = NULL; + #else + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; + #endif +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif + gen->gi_weakreflist = NULL; + Py_XINCREF(qualname); + gen->gi_qualname = qualname; + Py_XINCREF(name); + gen->gi_name = name; + Py_XINCREF(module_name); + gen->gi_modulename = module_name; + Py_XINCREF(code); + gen->gi_code = code; + gen->gi_frame = NULL; + PyObject_GC_Track(gen); + return gen; +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, attr_name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(attr_name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PatchModuleWithCoroutine */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + int result; + PyObject *globals, *result_obj; + globals = PyDict_New(); if (unlikely(!globals)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_coroutine_type", + #ifdef __Pyx_Coroutine_USED + (PyObject*)__pyx_CoroutineType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_generator_type", + #ifdef __Pyx_Generator_USED + (PyObject*)__pyx_GeneratorType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore; + result_obj = PyRun_String(py_code, Py_file_input, globals, globals); + if (unlikely(!result_obj)) goto ignore; + Py_DECREF(result_obj); + Py_DECREF(globals); + return module; +ignore: + Py_XDECREF(globals); + PyErr_WriteUnraisable(module); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { + Py_DECREF(module); + module = NULL; + } +#else + py_code++; +#endif + return module; +} + +/* PatchGeneratorABC */ +#ifndef CYTHON_REGISTER_ABCS +#define CYTHON_REGISTER_ABCS 1 +#endif +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) +static PyObject* __Pyx_patch_abc_module(PyObject *module); +static PyObject* __Pyx_patch_abc_module(PyObject *module) { + module = __Pyx_Coroutine_patch_module( + module, "" +"if _cython_generator_type is not None:\n" +" try: Generator = _module.Generator\n" +" except AttributeError: pass\n" +" else: Generator.register(_cython_generator_type)\n" +"if _cython_coroutine_type is not None:\n" +" try: Coroutine = _module.Coroutine\n" +" except AttributeError: pass\n" +" else: Coroutine.register(_cython_coroutine_type)\n" + ); + return module; +} +#endif +static int __Pyx_patch_abc(void) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + static int abc_patched = 0; + if (CYTHON_REGISTER_ABCS && !abc_patched) { + PyObject *module; + module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections"); + if (unlikely(!module)) { + PyErr_WriteUnraisable(NULL); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, + ((PY_MAJOR_VERSION >= 3) ? + "Cython module failed to register with collections.abc module" : + "Cython module failed to register with collections module"), 1) < 0)) { + return -1; + } + } else { + module = __Pyx_patch_abc_module(module); + abc_patched = 1; + if (unlikely(!module)) + return -1; + Py_DECREF(module); + } + module = PyImport_ImportModule("backports_abc"); + if (module) { + module = __Pyx_patch_abc_module(module); + Py_XDECREF(module); + } + if (!module) { + PyErr_Clear(); + } + } +#else + if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL); +#endif + return 0; +} + +/* Generator */ +static PyMethodDef __pyx_Generator_methods[] = { + {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, + (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, + {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, + (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, + (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, + {0, 0, 0, 0} +}; +static PyMemberDef __pyx_Generator_memberlist[] = { + {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, + {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, + (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, + {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, + {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0}, +#if CYTHON_USE_TYPE_SPECS + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyGetSetDef __pyx_Generator_getsets[] = { + {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, + (char*) PyDoc_STR("name of the generator"), 0}, + {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, + (char*) PyDoc_STR("qualified name of the generator"), 0}, + {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL, + (char*) PyDoc_STR("Frame of the generator"), 0}, + {0, 0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_GeneratorType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc}, + {Py_tp_traverse, (void *)__Pyx_Coroutine_traverse}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_Generator_Next}, + {Py_tp_methods, (void *)__pyx_Generator_methods}, + {Py_tp_members, (void *)__pyx_Generator_memberlist}, + {Py_tp_getset, (void *)__pyx_Generator_getsets}, + {Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict}, +#if CYTHON_USE_TP_FINALIZE + {Py_tp_finalize, (void *)__Pyx_Coroutine_del}, +#endif + {0, 0}, +}; +static PyType_Spec __pyx_GeneratorType_spec = { + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + __pyx_GeneratorType_slots +}; +#else +static PyTypeObject __pyx_GeneratorType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + (destructor) __Pyx_Coroutine_dealloc, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + 0, + (traverseproc) __Pyx_Coroutine_traverse, + 0, + 0, + offsetof(__pyx_CoroutineObject, gi_weakreflist), + 0, + (iternextfunc) __Pyx_Generator_Next, + __pyx_Generator_methods, + __pyx_Generator_memberlist, + __pyx_Generator_getsets, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if CYTHON_USE_TP_FINALIZE + 0, +#else + __Pyx_Coroutine_del, +#endif + 0, +#if CYTHON_USE_TP_FINALIZE + __Pyx_Coroutine_del, +#elif PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_Generator_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; + __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); +#endif + if (unlikely(!__pyx_GeneratorType)) { + return -1; + } + return 0; +} + +/* GeneratorYieldFrom */ +#if CYTHON_USE_TYPE_SLOTS +static void __Pyx_PyIter_CheckErrorAndDecref(PyObject *source) { + __Pyx_TypeName source_type_name = __Pyx_PyType_GetName(Py_TYPE(source)); + PyErr_Format(PyExc_TypeError, + "iter() returned non-iterator of type '" __Pyx_FMT_TYPENAME "'", source_type_name); + __Pyx_DECREF_TypeName(source_type_name); + Py_DECREF(source); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) { + PyObject *source_gen, *retval; +#ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(source)) { + Py_INCREF(source); + source_gen = source; + retval = __Pyx_Generator_Next(source); + } else +#endif + { +#if CYTHON_USE_TYPE_SLOTS + if (likely(Py_TYPE(source)->tp_iter)) { + source_gen = Py_TYPE(source)->tp_iter(source); + if (unlikely(!source_gen)) + return NULL; + if (unlikely(!PyIter_Check(source_gen))) { + __Pyx_PyIter_CheckErrorAndDecref(source_gen); + return NULL; + } + } else +#endif + { + source_gen = PyObject_GetIter(source); + if (unlikely(!source_gen)) + return NULL; + } + retval = __Pyx_PyObject_GetIterNextFunc(source_gen)(source_gen); + } + if (likely(retval)) { + gen->yieldfrom = source_gen; + return retval; + } + Py_DECREF(source_gen); + return NULL; +} + +/* append */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { + if (likely(PyList_CheckExact(L))) { + if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; + } else { + PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x); + if (unlikely(!retval)) + return -1; + Py_DECREF(retval); + } + return 0; +} + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long x; + long a = PyInt_AS_LONG(op1); + + x = (long)((unsigned long)a + (unsigned long)b); + if (likely((x^a) >= 0 || (x^b) >= 0)) + return PyInt_FromLong(x); + return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + const long b = intval; + long a, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return __Pyx_NewRef(op2); + } + if (likely(__Pyx_PyLong_IsCompact(op1))) { + a = __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + } + x = a + b; + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla + llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + double result; + + PyFPE_START_PROTECT("add", return NULL) + result = ((double)a) + (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); +} +#endif + +/* py_abs */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) { +#if PY_VERSION_HEX >= 0x030C00A7 + if (likely(__Pyx_PyLong_IsCompact(n))) { + return PyLong_FromSize_t(__Pyx_PyLong_CompactValueUnsigned(n)); + } +#else + if (likely(Py_SIZE(n) == -1)) { + return PyLong_FromUnsignedLong(__Pyx_PyLong_Digits(n)[0]); + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + { + PyObject *copy = _PyLong_Copy((PyLongObject*)n); + if (likely(copy)) { + #if PY_VERSION_HEX >= 0x030C00A7 + ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK; + #else + __Pyx_SET_SIZE(copy, -Py_SIZE(copy)); + #endif + } + return copy; + } +#else + return PyNumber_Negative(n); +#endif +} +#endif + +/* PyFloatBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyFloat_TrueDivideObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) { + const double b = floatval; + double a, result; + CYTHON_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + if (likely(PyFloat_CheckExact(op1))) { +#if CYTHON_COMPILING_IN_LIMITED_API + a = __pyx_PyFloat_AsDouble(op1); +#else + a = PyFloat_AS_DOUBLE(op1); +#endif + + } else + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + a = (double) PyInt_AS_LONG(op1); + + } else + #endif + if (likely(PyLong_CheckExact(op1))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsZero(op1)) { + a = 0.0; + + } else if (__Pyx_PyLong_IsCompact(op1)) { + a = (double) __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + case 2: + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (1 * PyLong_SHIFT < 53))) { + a = (double) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -2) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -3: + case 3: + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53))) { + a = (double) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -3) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -4: + case 4: + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53))) { + a = (double) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (4 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -4) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + default: + #endif + a = PyLong_AsDouble(op1); + if (unlikely(a == -1.0 && PyErr_Occurred())) return NULL; + #if CYTHON_USE_PYLONG_INTERNALS + } + } + #endif + } else { + return (inplace ? PyNumber_InPlaceTrueDivide : PyNumber_TrueDivide)(op1, op2); + } + PyFPE_START_PROTECT("divide", return NULL) + result = a / b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); +} +#endif + +/* pybytes_as_double */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj) { + PyObject *float_value; +#if PY_MAJOR_VERSION >= 3 + float_value = PyFloat_FromString(obj); +#else + float_value = PyFloat_FromString(obj, 0); +#endif + if (likely(float_value)) { +#if CYTHON_ASSUME_SAFE_MACROS + double value = PyFloat_AS_DOUBLE(float_value); +#else + double value = PyFloat_AsDouble(float_value); +#endif + Py_DECREF(float_value); + return value; + } + return (double)-1; +} +static const char* __Pyx__PyBytes_AsDouble_Copy(const char* start, char* buffer, Py_ssize_t length) { + int last_was_punctuation = 1; + Py_ssize_t i; + for (i=0; i < length; i++) { + char chr = start[i]; + int is_punctuation = (chr == '_') | (chr == '.') | (chr == 'e') | (chr == 'E'); + *buffer = chr; + buffer += (chr != '_'); + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyBytes_AsDouble_inf_nan(const char* start, Py_ssize_t length) { + int matches = 1; + char sign = start[0]; + int is_signed = (sign == '+') | (sign == '-'); + start += is_signed; + length -= is_signed; + switch (start[0]) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + matches &= (start[1] == 'a' || start[1] == 'A'); + matches &= (start[2] == 'n' || start[2] == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + matches &= (start[1] == 'n' || start[1] == 'N'); + matches &= (start[2] == 'f' || start[2] == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + matches &= (start[3] == 'i' || start[3] == 'I'); + matches &= (start[4] == 'n' || start[4] == 'N'); + matches &= (start[5] == 'i' || start[5] == 'I'); + matches &= (start[6] == 't' || start[6] == 'T'); + matches &= (start[7] == 'y' || start[7] == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static CYTHON_INLINE int __Pyx__PyBytes_AsDouble_IsSpace(char ch) { + return (ch == 0x20) | !((ch < 0x9) | (ch > 0xd)); +} +CYTHON_UNUSED static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length) { + double value; + Py_ssize_t i, digits; + const char *last = start + length; + char *end; + while (__Pyx__PyBytes_AsDouble_IsSpace(*start)) + start++; + while (start < last - 1 && __Pyx__PyBytes_AsDouble_IsSpace(last[-1])) + last--; + length = last - start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyBytes_AsDouble_inf_nan(start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + digits = 0; + for (i=0; i < length; digits += start[i++] != '_'); + if (likely(digits == length)) { + value = PyOS_string_to_double(start, &end, NULL); + } else if (digits < 40) { + char number[40]; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((digits + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} + +/* pynumber_float */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj) { + double val; + if (PyLong_CheckExact(obj)) { +#if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(obj))) { + val = (double) __Pyx_PyLong_CompactValue(obj); + goto no_error; + } +#endif + val = PyLong_AsDouble(obj); + } else if (PyUnicode_CheckExact(obj)) { + val = __Pyx_PyUnicode_AsDouble(obj); + } else if (PyBytes_CheckExact(obj)) { + val = __Pyx_PyBytes_AsDouble(obj); + } else if (PyByteArray_CheckExact(obj)) { + val = __Pyx_PyByteArray_AsDouble(obj); + } else { + return PyNumber_Float(obj); + } + if (unlikely(val == -1 && PyErr_Occurred())) { + return NULL; + } +#if CYTHON_USE_PYLONG_INTERNALS +no_error: +#endif + return PyFloat_FromDouble(val); +} + +/* PyFloatBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static int __Pyx_PyFloat_BoolEqObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) { + const double b = floatval; + double a; + CYTHON_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + if (op1 == op2) { + return 1; + } + if (likely(PyFloat_CheckExact(op1))) { +#if CYTHON_COMPILING_IN_LIMITED_API + a = __pyx_PyFloat_AsDouble(op1); +#else + a = PyFloat_AS_DOUBLE(op1); +#endif + + } else + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + a = (double) PyInt_AS_LONG(op1); + + } else + #endif + if (likely(PyLong_CheckExact(op1))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsZero(op1)) { + a = 0.0; + + } else if (__Pyx_PyLong_IsCompact(op1)) { + a = (double) __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + case 2: + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (1 * PyLong_SHIFT < 53))) { + a = (double) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -2) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -3: + case 3: + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53))) { + a = (double) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -3) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -4: + case 4: + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53))) { + a = (double) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (4 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -4) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + default: + #endif + return __Pyx_PyObject_IsTrueAndDecref( + PyFloat_Type.tp_richcompare(op2, op1, Py_EQ)); + #if CYTHON_USE_PYLONG_INTERNALS + } + } + #endif + } else { + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_EQ)); + } + if (a == b) { + return 1; + } else { + return 0; + } +} +#endif + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op2))) { + const long a = intval; + long x; + long b = PyInt_AS_LONG(op2); + + x = (long)((unsigned long)a - (unsigned long)b); + if (likely((x^a) >= 0 || (x^~b) >= 0)) + return PyInt_FromLong(x); + return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op2))) { + const long a = intval; + long b, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG lla = intval; + PY_LONG_LONG llb, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op2))) { + return __Pyx_NewRef(op1); + } + if (likely(__Pyx_PyLong_IsCompact(op2))) { + b = __Pyx_PyLong_CompactValue(op2); + } else { + const digit* digits = __Pyx_PyLong_Digits(op2); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op2); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + b = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + b = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + b = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + b = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + b = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + b = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + } + x = a - b; + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla - llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op2)) { + const long a = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double b = __pyx_PyFloat_AsDouble(op2); +#else + double b = PyFloat_AS_DOUBLE(op2); +#endif + double result; + + PyFPE_START_PROTECT("subtract", return NULL) + result = ((double)a) - (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2); +} +#endif + +/* RaiseClosureNameError */ +static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) { + PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname); +} + +/* PyVectorcallFastCallDict */ +#if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* pyfrozenset_new */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it) { + if (it) { + PyObject* result; +#if CYTHON_COMPILING_IN_PYPY + PyObject* args; + args = PyTuple_Pack(1, it); + if (unlikely(!args)) + return NULL; + result = PyObject_Call((PyObject*)&PyFrozenSet_Type, args, NULL); + Py_DECREF(args); + return result; +#else + if (PyFrozenSet_CheckExact(it)) { + Py_INCREF(it); + return it; + } + result = PyFrozenSet_New(it); + if (unlikely(!result)) + return NULL; + if ((PY_VERSION_HEX >= 0x031000A1) || likely(PySet_GET_SIZE(result))) + return result; + Py_DECREF(result); +#endif + } +#if CYTHON_USE_TYPE_SLOTS + return PyFrozenSet_Type.tp_new(&PyFrozenSet_Type, __pyx_empty_tuple, NULL); +#else + return PyObject_Call((PyObject*)&PyFrozenSet_Type, __pyx_empty_tuple, NULL); +#endif +} + +/* PySetContains */ +static int __Pyx_PySet_ContainsUnhashable(PyObject *set, PyObject *key) { + int result = -1; + if (PySet_Check(key) && PyErr_ExceptionMatches(PyExc_TypeError)) { + PyObject *tmpkey; + PyErr_Clear(); + tmpkey = __Pyx_PyFrozenSet_New(key); + if (tmpkey != NULL) { + result = PySet_Contains(set, tmpkey); + Py_DECREF(tmpkey); + } + } + return result; +} +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq) { + int result = PySet_Contains(set, key); + if (unlikely(result < 0)) { + result = __Pyx_PySet_ContainsUnhashable(set, key); + } + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* ValidateBasesTuple */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_MACROS + n = PyTuple_GET_SIZE(bases); +#else + n = PyTuple_Size(bases); + if (n < 0) return -1; +#endif + for (i = 1; i < n; i++) + { +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + PyTypeObject *b; +#if PY_MAJOR_VERSION < 3 + if (PyClass_Check(b0)) + { + PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", + PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + if (dictoffset == 0) + { + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + } + return 0; +} +#endif + +/* PyType_Ready */ +static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) + gc = PyImport_GetModule(__pyx_kp_u_gc); + #endif + if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); + return -1; + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } + #endif + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); + #endif + } +#endif + return r; +#endif +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__10); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* ImportDottedModule */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; +} +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__11; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* Declarations */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = (double)(1.0) / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = (double)(1.0) / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* FromPy */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject* o) { + Py_complex cval; +#if !CYTHON_COMPILING_IN_PYPY + if (PyComplex_CheckExact(o)) + cval = ((PyComplexObject *)o)->cval; + else +#endif + cval = PyComplex_AsCComplex(o); + return __pyx_t_double_complex_from_parts( + (double)cval.real, + (double)cval.imag); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__105); + } + return name; +} +#endif + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CheckBinaryVersion */ +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ +#if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..06f3a6dd830b362b6d88686a9b1a16a8b197b522 GIT binary patch literal 1189069 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 bK75#d`?Rzkke-&Z12j~-#FLFF zLkr)8EX}+Qf9+oQQ^!UwC?mcU;)A1}CcDnQFbZZS+Sk`NN7;YiPrNJ)>G~xS*qd1R zTWo0B=YVHU;S*JOg5p^yX+Ie+UYE)f6k6OAg;G&5nMGbDRx0dtR(INznP`^7$>mtK zYN5}d!K}h|9J^a3u8w0LMFSL-d-%%1Ko~z1oWCBNo9JRhg zqLicC25aisPPsKdu+Fbpu8&iW^BK$KvD|ZRxo=fDx7S~la!Xk5bf+BUn&miITLay4 zU#N0bPJKhATm{Q*I!Dpj*(ukN<=UfM`8%!{GhoYJgg-ISQjJRMkxuSN%k}|{m>=h% zeEBR2@5ICssyR*xX;YP3;v$xK3nijOu?kcx9B^sMGcI@*!QUo$rx>^*-T{{u+zD{E z1%YOB2eJv*K@^k=;pS!dU5(;1NIX>SA~eK#PJ2VOu4psToabAl8vrlszI|HJ0ybQ= z=@tp)VV)woXd(0X%({?1jRc_%q^C*H0?IE1j64t3IxgO)4P1cVFYvqEdeD)%bSac3 znjINVWoaTucvo_f=KyCoz>1=Q4kc+0)dQ6z%#k?dv-B-`33 zVwE;ck>eIli*ym7Tb4t?;5$eEhOr4n_cd;*!Xl*T5M+UIKH(QJ0ukpkAL*D`wNNMY z04+UoOL18>$hy5P?N}X1??g{Q0WnwPX*p03Ts2KK$?6Pn$-ROIjn4_7xUa~!Gy>p) zB*&>kySP0-3FpX)YTh>N{E1-!fJ^{z^`Y)6iGB|ZYGTzwImp5>V88Lk2-4-afs6-B z+|?XIqKrXPd5Se*KXd$&Vt{)~zfKm*|ByBG6B>`zaGlUjiJ3P8DBJPvOoTyj#Z(GA z1Gl8%(cPoKmIy9OV*(Z+T4+9=WcR&Vz#F62(nRYA5yHCP@&K!w;#?AREgGeTKLty1 z!y1-^hZ^GZvz%ihJzz&4MEG9@;t_DEj%>rojT>qQ7jg2kg#yI2*1H*T#OQS!w@IPb z?>vA;NUt{rx8P7%hjbzDalE5+1FI3ZT`gTZguTpO>8F@37fx6&y4_mA5;&ZWPYF8v z+99l~weSami4g@xlxr2Ng9ia;y`FwkpxoQrjuL5X!L|o)!i?C>N3b?2TUzLEBqfsD zWIl|p;Q*Usz<%H~J`)*ew{y=I7CY8JWYhl@ibz#WVw^{W9@YbO`b*B@C-0FmTx0y~(5LH4$u<)_IIUB&({8hnZTFB4ZjB3TK2iR~HTr8=$MWi?#6>}Ik zTE6dhacg16#)nl<`U^=T`4PJ3h6vVYdBLme8XP6(y1{BDWo!-E$c(7-yGCv|KO0Ci+pz+*TMHMtWB)8b#grq z&`vgUzxy4vNT}tD0D{{wz|m>;!}@xo^-u6NjxhBt!s6~;-AKJetZdJv{9#8vfWo*e z*gEx0fH1)eS0m7mWf5RH?cZ!df||wU%Pwa4B~jYm4(FdXX+5tvtK&7DDYE;8Tz#ej z>y!uCasE+^)t!`MaYcXYF@I7|{}SIZfdBMY@t-b+|8yJurwN(LfBGw0gp*OG@=s## zO(5w%orSJUvbvt(H0lF1s{Ccx-(dhLx)oCPUmf=bE1BdzhMs;o~{dkdDo)qxc~m;jRn?Xbe_( z=bt57QOq@JhM(Y}fM&RhWx3URjshQczd;M>$FBu4A_|8i7^1Y#YqyV z;q9NK4Xq!eC28hr4$?Ohkj{Zq!Ws>v$53*!P~!OrD{Hk++P;!BF;M9Wz}r_LU(wO_ zSUTvHqXs_bn5;N;P{QmV`x+3bpxX&_90HAVfgpfMh`C0v3(N&H2i8Y-M7iJ^Uzm~9 zayng{a_tDlHNJ^V)2$~;VX~8KWrNx!XfM|J`Dm3EYUxZ3+tHpn`d16BWfhoih^W?T zK>2s(API7qz8RIsrMe<=5M(!>5th{CQYpGE^mbxiB~=f-yWKF@kvr)dlAtiNx;lz~ z8)&sxlVG#;pNPwHMeITdjypZTDuAe6yojvtu~m!mxAp6RCmgklsT z1!itT7J-DlG+S(GWYwwr1r&>3HD@$>#O?)s1QLpcgxqC2Rlz$@Fp&!4zQd{PLRDGt zEYSAw7o?4mZd=M(k^=PG$#{z7UQ@xJ)cu%yE1y73bBBO7Ybjz0;KU0egl5iIk%*dT zJ6ZzIoXYaN{X+{Epr$#cq;57?Iwy>$*f=m`?WGKr50PvC6MtZK!V!$lM66XA$fL8J zh{8lf6V)C8C|)N#48PXBq!9U`7twfnkk<=PBI=un+J`^hin~C!V>Xq)09=l_XWxO| z1?R36O^`cf2kGBvo&Q0cb9Kco+}B~?_Lfq;FtGD-JPQN=F_#F)z>kpcRv1Br-U_nL zJ_+?nE4R#f4XKIL@^(@CW&E*vO6ygWTqf#^8=ay+9JFdgzE8%m6t)JaQQ(cAQ&tai zZ({ZmhITPy*^0nC3MTn`Q=J;>AfHF%#V9zZ3QuHmm9x@}*Ou6XU)jX96p=5|ggsh_ zMQaEjZ)#hvgqG|)}RJMTo=3&=M8oULYc%+M^N4tpK+L4??zyN`OhGyglMK~ zi8stm0kur~1n3+~`z<_je4Pal`xU&zDaXmO;+rstcT}r};;w5w;#mWohH?AuE%?#$ zmtttIo+Hgi%hNSXQ0J*$xD(BeyCXonUu`?s{lRAn8~giMmI%Aze9^)?;6=1I(UmwA za*r7f6N7z$nxC$AD2rr$G8?O?Wi8MKKbHiir)@0jMP|Lvtgm5A$D23jRuR0NHb0gQ zf^eZ}1=^3{CXN!F!HUft#cv%(pIV#nN51aJl?E^UM&F>SFPA9(L_9AP32#1rE5@78 z%EajQ8{5I2gQ-{%QzjIL?vwh}jK_Y-Trc*)sUSynbiA9Lo`k-`m|?bd+DVwIi*>9$X$h(pJko^@QInVl`)E3}6K zLurMTRu$ohyL?VcHwO$;Uci=!gv(1qlb|r;(Q_*x2bh2oFFh?s684_7&{8x{E#CMc z3ob8aBFp{|FURoa7yCytV_R))U%R&UTdTIVC4Q&lH;mud{t3PhhrqJdR#(=6uW!XAn^kEln+f*n$iWqAC4 z51Ep1RFj)Uvw+A~dK8;QXHbL4W>JkEi~3pwPd?6P&UT`{5aNVWUN>`R0j{i}z%2(e z*>Y!nhxizLk{)VYtxtYDZoF5m)oqMe<>8YPAhAA?=CNs3Su=R5FFAukh*{?hOoY)< zpfi~Qc+?Xdj`*hxGzO>McmlIvlDmna0-LxkB+&qlwg2=&TKk891=E1q2jcMLi#Y3P z+gb&vQf!1j09QT~bC$xy}G!Noow11gewJ%8#Rhn$E?WJBu;2BhT)T&te_ zWzp34MzE^NTHX|`dIXs59zgmRw3EvcRmPCAAmDADCP5fIsdeJN=t)((KC(7an}^42 z{2Zp~I3j_0@dp3MA95aX3A`Tr=^v?=ZwCGl z|H$i4P(FDcQ9;80Ad)4rd3K5tl<-KnjLW;AJC%zhb{>(kg%GnnAX7RB`gZxTMEbD@ z&<{jnl^>5U3;Z|!k^NR9MW1sXaZ|#1#Bog=;#Sf>avh07Zyn$NPy%tMf22P9;D5+k zU?1220Q$7hU&WX0w}w2f#`lw`+Vxb>|1e1yxW2JNY*iTAx9AIFHW$bIvE8*uS;k>IS)h zd^zV6(SOkkB)W%^BhD*y4D}k$C)Otr#}r@oprvyBDS>b;ybsgK-m}-nuOj`6!BgKi(B`kJttk|Whm?sG1C3?Qp z%f?K=YcTzZ)2x@Ba^cAkZe)8NK#p#Drg4Thb9ZgPkL)=OqM|ml!bq1z$4_{NiGrQR zTReFv12?~CxE$GMbn`Hi)nvk~m9c%4xVDurNz?l+ZH5r9VVKOJ| zW0oeK%lrodV8AyFKU|G1AC?F$g{aArj4Q$2*3*=c_{Ikge+il98zdU{w_x`pFhGh1 zh5(M@Nb@#uKkdyCvMLlWSia!#ETi+lb*nZ~e)B6}#*E;>@J zB7jn4_@cb0x2`9YxU_b|Y=rle_NuIo?uWEnOOudKr7#V(L543QJkJR2FP4At{ZkQ7ME5}2N@k)Q?b5N z{+Whc^vNpXWaN7*XOkOGfj(8?CsN@~hUpDMJ3o_GNL9S6UWA0!TP;kGq`GI~9+9-V zo8PyIaIfd-yGFJ7YLy?viSoFq(pg>Qq(Na}c4ulYvJ+_9j~K6-%5Vp3HG zsuW3D_+h-;yfaQ^%|(`4uTTQ*UiibKh^|+baWK3YLcFr@zKJ_l&K@dn?7RkO91a;U z;7$gX{T^6Zem}4(op~>azWDZ;sQwF2-NS)1RJn?)55*r zRj~bV$(Q#8PP-M*mFMy4BtBiqrv`lL$EW>pFP0baX(yhnt3aF#aeE-pPVEjqe?NGx zxUtp(zt7`$B7WkV@BtG@0{C&*jaXI9bZ)&FR8s#u4SNm?EDw+- z?g8OEjjXS3fZA79)$z~M)LL6${ctp$n*d4sOV*9nfFsFC<(tnWm4F#79&OLkPuXb1 zIdkUB znKNh3pi$AW3Jr0th*$218 zA+0GE@4LE}-cH?BlvS+)%F&%1c<5NsFWc#v@XN;uM;bY0PeX)t?k|NNl4 zd1L?lF#Qzm${Rwo;+HWY`nRuXZDZL}_gIb@OzoVHx5UY9<-~F2+w@GB9{$ zmNmKIa#dj`=3#+sj?A3nz6(+H%Vla{S@uB$+M>slS*G8bJC$FzCynHLdGmon;1aA>RM5J=6sT>iYPavWzad%fMh_^XhUufAhuR8Pr1GH zQeNqan(Voe;>Ls_QDmB1GF`&=U_B@hZl$NAqgtISw8yHFDv?9=-n{-A4Ulw;J7+eF zaSOveJZ#wtRoh#Xt+DJaI)xGNF0;CH)F)|hxGhZ4^aW!l{7!mfpeHHgP2cEgIZwd_ zDoy+Y8tyvxuA33})4u}yGqlr?O>C0;l-8#|=+jL1Y2_nPsk8OzN`2ZEMxTV=h1@ba zqdWeR|9J!9+UKpi(HBl7Ji#gw%jVB-AP-t-2`x*Us3~1qPh;Xt_joIhb?#ATJf>Pk zDTVLzbBtZ(N3PdhMz)|Q}WFDR2}gps@xoPx@6v7Xs3|&sfUezULU-Gi55||NrirjPUHKS-u{Z{XQtphy6QZ5NYK*W- zA^ADy^La}Uq;J%%GA^cUy?!->P{wei?3uo zWgZ!f_nC#YDkxU1vq@|UTtC#F^0X{j;k`5=B9b6SM5?F{ZgSvj?`~R78JE2_mR+!; z>}jju)K~>|cVb;>;Xhvgy{3q{u&`ip={2;T2VB^DnU;%*XbI0|BIWsWSE!dEOg_2j zKk6zP7K}-5`6llG+1<+Wj=g7h`_A)=V{qkHV;zM?Fp_#ve)pmEe0auTGJHM>=7c{c zIk#m!a=gk%at>2X&(Rz*bbSqT*lWp&r@*O#_X;E4!Rjh_=_R}e2g1}2X75>bS6+Gr z8H`7CY+x*{<=r>J9~;<+0>Q;A9oMCQ$%+EKYJ2|9T%wM66GkauzBtpxhG?As?nI>w zm-2_orU)yUB09Uu6X$;;1bfxggQcOZ&`u<%q4&8a4TpTaXna?kafk7{`{X`WSdG8c z*t(Z_?#nuOCPLkg;asu8H{mFFf%1v1tfFHrXE2$syPNl)%!fLQs-#-<=v5MyPAqy+nwvdHl2#aa`$im zVpKC>2KKX$bstDuxK#XG+I{&08g^aD!^`{jqATBddDdRO6RynLJ*llcGdJBro9uK+ zvSGaHmD_M?6`3k@n4%L!$snp46GP3eoJ$e=^lnK`eB5Z#J8>XWOI^vOJBVFG)8O#W ztT*h%#2}Z)07#>w_pIcEp=d>dYTeUyR`3qU(3urf)64U-I*u>T*q354wfJ=y{Mx%{ z5i@pOrzAR%M)PnE*$i*t8;4&`niZ^1)mG(8sFUT*^Ni;{63?AVcJ`=Ks;Vz=Q*`@7#aCC*$KW8 z8l8M|W0Abptz(kMCT^$7V3!EX6|iP`^CsOTQZ$u?G7G4f2eWRmbRpakyw~bm`mn*c z!&qdQU>pLBWJ6yR8I<+TJLwV4#!&h#EWJulYjWn^&g)w(yiav zp33=;%kdOw&py~M=Se*MPI=u&hgbAEm$ws4DKHI#*Af3S)hzjVIV$CI%Q zAk%k#EWX7DnEj&lTYUeq#c(_^!f`dPO>YTDhBwl$Xtow&x%J!SH%i;-y46AYDH_8Y zN>6(Kn9}o2*s;UYQuI-Bdrr1&t5GyDT)%n@>$es_mfS0l8&#IpaB2BN)WflQ>6L4( z->T_9j>*3TZCb>Rx%C@vRvN0_Qg5rdK^Qr~<#J4K*j7j119k}UD+8rJO;HDS!)Q_j~=6X0QY_)>jPtsK2Pe=R~2Gq(9 z`}l07nkByi{kA%@w*r4?hDa~QVjHXpwCuVXI5wspH^P>ks#1{U+qCTY3f`DZKd$UA zlil93mNC&qYi3)?P57N(YRN-#64}hSQnz($QF(I;@a~m8k>x=ju(LU;FPM7^i`G%h zGOc6b@SDuBuk77t91?XgB=!*!g9>m?)j_tD&DW4fd-RSpz6bWQU6bFBE zhUW5gRGvAOr;R+Vocc%{ko)@44Sc=dzCLRZJ`#jJ<<0Nr;q6@B+-h%uzHM3F{Egsr zDsTSQQbS?YSaueWVDW>{a9N-omiaa;WqB5?guP92XD7okh$=7J-BgDJ?0y641oOdb z!A#4#<^1p*m-8RwX6BhYYds!bUMAW$xQR8$Oc!y`HCx&W19}FoR`#X(gBJ)qPu=36CeQL5wCq=H(p#X&VM)ixA7r zi&82%eX0|uLTsgjR?u4EncQ4xIuu`mXLvD9L|TM~X!xWRoco&4L~-qfy4w{cU!uEjcQTZ9JU4Z1?N&h_>url`kW&Q4eVEJ!ahbh|092q_WKtcQcO&{LktEZ zRxmAfshAer`=J|QsasJmWH#VF^w*T9>{)qRn6B5rC&tOON|!l!jox*&FLs#cl=sli zmDzgj9>CxxoLb1yM(91WYouno{FqiX0Pcn*VUCJvUd>7T8Z{!=4m=bY4axR4*^vT~ zy>~JuYj*xgMA>l`*K^mhxXwr5GuCBs?RTjrHY~2Ibk#Q=cd6@;t4_1Dz19*Cuy#CR z6)ld5iUgl9pvt5)I3mo=mTQi=n5XVA5h9?P!5}~z1dxzvL&-4gFSP6gjKbEdy|CrM zw2!EdaVx7>w(LBetT3{kL{66M6{MR9dP62_ZKVNqK}%%8H?o3~!PXhq=!W}bYMN@o zc;kGD2T_ZWHF)KNj*tqMNNBmzu%TD!qSC}5R_4jnGSU!W*oIqVyvA#?aN~M@IrBC> zRZWbKV4NiK9K@$~uI+T~Fe5=!?dy=q?1?V`Rr1bt^4~?hY`>*U5+Z?CIfl<;%2jaF z@eSm}f-Uj?EQnjK8w_hmj(Pk@0j)hQ;)auNV}*Q@V1B^10s|+}h!n)+1F6zz zEG*Mwgr#+Jk?>itEc(cO?ZC)@qs z^9yy!ZTXCTGJE|EKF0RB7qexw6}Bmvp(pIM)!$X6&Af|V;xW_x9sMv~(}QI$OVJ1A zGY$X_$k)}viJvs7b5;eZ@it(rO}i`WaI&^m1&`6%=;TBh>E$y9P#Vr^9S;`wYr4#q zJ>Y>H5(BbK#=|Y+^(9m1g1d^Am(Mr|D6OS6+1eghC0Ue}X?QB$7F~ulQb&6jJI*AT zD%Qu$oNxm};Ao1<;<_qSfQ9lILwOJ7a8^EJIFD8^nf@Id8m4S~c5j;{G~FT2_pCt@ zaiRG~7_pksBsoJflOK)3^rcjUlzA!`vP1+M0ay`iZ`#_VQt;`JD>Nu{gZyh20oGbFXQ z2S284jb*1zgno@hUoqDnmig@Io2WaOcet6M67wXKvx(wc)m;ckZk|ca6I~}#wtU7_ z)a=IEldX?3+F*%b7+=CxCQbN(Gek@6iC|94>}F(ueQ>jY$?iY&8e7CT)BmZ9Dfa}U zjVvv>Ec?1F&ZXlJvH)@mW^FRvmdjKW&$O*&GJ<`~Aa(cUIb-2MN+i=)8O;xe=0uR= zKFwJ*>_%Jup!W zPn03xM}}X%E2*)1jSMNP*RLB0ob2)2SI&BWhsup!ZT(xpYvtDqTOUB|?+G@wdyWim z1L5jS3!&qyl9errZg=tBG;c3!-oR1J;VZ$I+k=pC@`E0pSb%IC8D2@9Yx$$+{2@kK zakxCXEGX^|F-l5=^M^RsJ<1>AQup}Z^@sQu6Ki})`1AcCUgs342I$V3rM#s)?+{9icaKB_HXPCIe&=H76If2fc&Ta5c}9N ztE~SMfVM5QZ;h$?U4tW1Gzn}-zp|FxQhA&|#5Y>fWD?)%M=djdh^xWD-n>7=C-`)j z{AZ3QJ?0NFEXw&Yt^NPy57Eyp%MJ!hr!RSbh@QStKjsh7$f~H&AL3!wFF)cBQA2+Q z)9K;z=K1uFXtkd8aM{HaiuprKAy4Ix_(Qy`Zw3Ak8yOCNH-7q2e~4EvqwWEeRjuA1 zq64+s_M!KO*p<&VNp2*pa_ZGck|UjEiV*!-{t%;7;e7g56&~c8c|Ggsm_Ni5d|j76 z#3!VCe~1M2{m=a&Zee@GwDbRoKg1ZY$oWGI=LG|Xxl-T{F-REZ{2>mqx5yu&x3cE_ zAwH(3HBJ1#_lG!(+5A8EhuCkBv!_M2D#bf+{t$oqry53Ynm?P_mN`_KF#mfF!i zR-ro{);k3pEo+U5Kq=0cpvA7WLbSjG86e5Ho3(y~f+s=mf8!7FIT$&Ai1Mh`0)L3ts1i9;@BJa3A^TeTFKO-6 zMP_yRLwpB=JAa7F)qeAbxKK~#4>3Vc<_~d-O0y26;jVKh z)gkWhBj`Zn5Aj_#`c$V+6ZOgaLoCUCIzgY#*Qfu~A7Z|Szq!Z`G91LRY)fi8Xm>nf z^ZpP=Xi9hf5X0P~{2@lW$Dij9@eZ52IVV{*UK`r`L!i^hA7TlPiS7I$rpL6rb;Uft+W zgRNYdx?$vR@s;#Y{^NqXUH*!CWmY!@At_B4I*Qhv*m{~@ez@ZTddVNdY$hwX)J|=> zfc#Hy#PAPKqLon*LG}3!^mQ@N#5A=0y^SizuNqU4Jbn?`t(B~HKL6sd;EzGOI8azs>t% zZP}7}#CL#~1(^dnij3F=5Xmkxdbuj5^fBl+3p%KP->?ASMHf5ZL{uC;OW0%R9{!b} zXq1Va`shYx4rWSQJ2!TwC&L^XP`;#9nYb7=-*^3D(+Re=%4CPpNUE ztm0uc;*?pz2`~9k@)10V6o2y)8~hu>7|ku>)!oFa&+sQdh~*?=n|G{`tKzpsL^m|x zf?JPN#g_q#3|qMPT>ASHkUgmjl;|KxD0mlFC;7|;SNpfC@T+9H{!jLAXCLD9&9(P$ z4|&lyaslmV8b-6)>6;Dh_ir24#!CCQMRlM2C=Gg@%cczMnUQ^s`&Vg!BL)J-r5)bmxZSEL(qA2Mb^q z_Csy|c9eni`?s0^*}v6K%+~AtZ`r?X_>uiviE}&PqJ`ddXXAYcA}1SK?Kf|$ZdT8X zlT?j1ZeN<9Ofgq5@p(s()Ic&djfEiLmwFndr|rqnbex_x*V7q# zl2b#lIsA-}>#dNlqwAB|^I$d}6Td(SLijLb7|HxGM-fJ37rXx~cmod6__Q}0s7}Or zIjR9G1~s6JreMrrIB|tt0M4-Etg{ndI8pfOUPcq~)j82jP2RJji$$pkPE(CY3wa2r zLi;N5n6JH{*6;@!Ph|^|**?CK3-gu8y`$K|qEozGP2a!|YtQloWf8Cc}2x!R!HA=o4qio}9wiinCC0Ao4jn}GqH8n2`Z_bhQC7x9C0r{F^Bu(b3bu~T! zYmz&v(Qpd0fY_UT;&=Gnn%!NwGps9q`df@McVGG2S7~4u=$mmPEbYpO-*JO{{q z7s>wk4(AD~yC4;Q#Q*jkLddoSLk@KM=Jv6idHdt@^U#jE6IR}Iu*)~+A)Dy0#j^Cx zy>uSy^RW_6UC-H3KShgpLxOzUB__(w6Oamkgrxvb3w6H{_l=)B$zA?jb1S!((*};> zaeowAGpotjck^TG*8MeYWqZDM9|@V)tFp)T0P&Bwusz5wK)7VyuGSUw+F7|?W!yGY zN>DOoY5iztrOo>5pTW1N5%VgpRX_ypN&aorva`2P%gT-efG&sl>@-bow#kzD7VydR zY{~~SC~Sl%wd{#DRu^yOH`lP$J?KQg zJG&|#8ED{qTY)B1rvW^+@7;^^$Y^*bwR4^`nOe=*QeZ06IusRf4v`lyoXY#$5E%(h}?KEO3aIN%$?A$D_QU02)hpB-#$=)dKY ztK5Y^>8e3+nX?DRWApWMxr%JEW^qsDT~?YpRNTTn_On_mop>dZgQ4H4 z0H_*3U^cs-vpTZ`&pyqzgv8d^b8EdaOx~D(x74Oy)r2dHJ0vI1mRHC1WI++>PyS$d zRCP!;nSXTq&zj(bDET`}o@)l_&DcF8+ETFKSxJJ$ZYP(!kV+~C%t~H&L1zHG`c374 z`N``>>p9D{ptIFzRnRAJ(d^(>C1=dxRZ=8Xt*<$=dMD~^ zhyS~{mqz%%s^{#K5_N5s=p1UsCcYWlw{ONKZd>)QkPP*kp1bN9kI{4q42J_eEO~?v zpSlVCP*+1ijE+63CLoYHB(M9**4*8fTq@SsdnrF0N$b0yb_PL*$s`uOD``N=dQ25(u6Y`{+#y&VVY{gs zO_a+4Z`Jm$9uU^|M0RsU?Od#Nsl+?Bd>*^;T*CZT6Yiio>Un&mra09ZJV z7t0(TCI5Tit-ajlt23O97Gijw8i zPqW-+x&bJ508BW#0II=|DEEi3pTv!Z_}rjJl>DwG8z~5;u8}F14Ubkb^#UnyCwJ{g z3yE9>fyTr0%@J z{s267+B9)TejwM7MfD>A}pK2ci1ziPcX1dB9xI8lk+BNwmSc7FREws5jwU4mWkPwkp z1a*9dtF-9x4QXdaKi0|@n$ZV}-P}Y5>V6#N?!?{MeKl^6$-qsNTyg*dP!a24{reBns zSc@E2;M5by={UK}b8@9sm*~!nNzZk{yz7+rekSI+U-5gTJ5Q)LX3#X#*Wa70RP%&d zhWtlg|4={D*NZ5}rKQ23CS%4bI0AjWZYLN4VSgxfJfy-1s$Vk9ovvP!`6`)y3lxJb zDW!ahnsUNLszi=BFPx?l^4WgpX;If!+L6xVIvNn6TtEv{_qeVu{S=+c#6wN?*V5ZR zlaJH&-LUtCqxfU;^UGi(P{8#D=QA`!&Dfd6Ud2eJ?`BaM-ozi}^>aEcc@wOx$XULK zsU({u)BRVIe^34}EOkjTl;{K{T6f65Z>0Cl{Di>wt$4>XX#x9FXaN4kv2aT(Y?B6g zx>=rr9F>`c;R*yOU$@g&%14C}J!B1^b6>mjwf#3Qf|-xQhh46ntOmovg{P^g?-5nn zT0ted^45y=tbTWcCtQhIQ&GRCd-ZrjI}aP_qjhfUk>uIOLt56lDR2AwH$uO<$VfhC zk35YwiL%5HcQJ-gg+>9^q~UgG2B?(ME-s=EZE>li=&%{%dGa`ZB5~lS1@e1nwqhHO=gY>JT#Tp(ZiL!Mtah!;6Y%bg(B8!GT%^8pBM_9$>16pBZrwm z_#(ZbD)X;OR~(gx$h@_stS#DV6TG$d$)Wtu>dbe5XK5qa1;3&SfOFSk)Xc0|D!iIm zgYtre_JafUxbwt@5VvSRW|R52RcDH-n~CY1Y!2E+xmh*iPprHT2FKmgVyr z+Rr>D6^|8LFq2f;u4YiPI<0VoV^00zROCQoQOI4pWJEQTrdi^h?n~K3ZJ!R_cmv-DN9Ra!}uD^GN0gE7`Hi_eWvyV zXPbFmd>^CKszOSG8*K&ui#^t3wXog}uJf{qqs|jdW*)o&(|dDjon>t(H-#9nqv=zM4ypU~$giJ9f zjSXUHOB@_MoXJB)-xf=( zj1r}kSW5rsL4&|c{UfpI;&*+dJjAkP`_LGq2_gX_LE)@ICv@V$R*L7Li zQnFZCHG&>qspV*CVuxQ#qdN-aTYAWx$7yNd-3H@fpV+G5ZI}TC*km?~OHP2?x`a-q zFt;Lb`0NJ(U}5U!X)$2xQ6RYQdfQQ|o)#x6poH5j0b3FY%_snrpBHR+zw6dZupLjoF42}=v`=tmd6Dx z@D3xXNd+iN2}Xx?7}_8L!_oH%LrgJasV&*iKac2Ag%8X+EV70ZdW2B!=}><7Y@vL+ zq3m&`v%d=tk8s_V+G94B*}-V*7DRX@*#2JhhDP9;znx-K%q^CuUT5z+3+w6n?k!hw)d&_+vC) zP-6OXe!#IrL4`6?OL!%2;$%J8Wxax|h55phTn1ek1gwm~S{7Ei)Wclr`=t7LH0*6( z>QCCqv@rvwL4g!lzw$0u(8jdSWLZqF!3`_yEqye5CGrTR_1-V^@*CulMc2#6 zX(6WhNazkp!xVXhBw%TiG;}F?Tz;{@s}WugK#>WDvZ`Qmxwz5f$BGO;D7@EH(;Hr9 zlmIOl@uziY`^i)T9h__NYU74~oFQ%ySQt)M>~U}VG%Gw1L_lk@sHBm-zs3aX*3v|` zGgW4^%9Qro!d`~CmsJMs2!r-@a2$X#v%^YWDRs7e+rWKuH68A1(&enw^kh`ibK(%I z=`kyFfCK)Zz3ky$uC*8EPV;r}3GJn(ZTSWXb+rZX?gXBx@`t+jS-f-U0&El>LLZ@| zNVMeh-_7^%FauFPn`geLWXK&ri~?_6uiM;N;Tjpdjf0EB`vM?M_?C+f?-R7k2e48a zJ4U^umC~WZV%r(kW)@8kJQ^41e`MAP6SSD>{BDYp&=!*oA5t^$N<2Jwm&3+YKyNHs z@-?H@-R00JUJDiciVDKN7}m~KuNyJSyV;ExLma-`h%u>y0iQiOLiXn4J+k6_e=mmL z7WnEBv8q$Rzksw0^HU|{wBhnUnH^DttgKC8`w_7bAy18k6&NMhViYB|^2j<$bf`2+ zytyhziSLh#H33Q-1m2;1PNF+PVt0f5ksAu!-5~y4^50I6C~<8BMpJm662Yer8yOho z`Oew|PH|>3O&!*pfzgAcWTYRQ86^&m9z-z)xfM}atOeoa9R0NAz?{Mwj0im)5xRIh z9TC3!l@a09f8~hq^-xa)VGj`w0PFAzhIX|5AtGQbfQ7>jo(Pwp3U!~-y59IU3kctC z%@F^3h?6u#V0)XMDRU!3tm=f+zhwZmYYN$cR9K!ydC@wqH`NdD)w_1>;@b7iSGjiW zXzdElG-Q5$-Jl(&ors?qOOERdG^zi9J6I-5 zsMKVZ`t^D^!YZim74HPRcx_Ycr-va+N;;yDKZTR8Bbwt*ENHi4(!ec+or~fLJzJ~OseV|!5 zf>F@aQ%}e6#1=qlzeiZFuniz%nLD+%BV29U07A+Kc#mwkna`I|e=(~~D?7G**$-f$ zA1(VE&(w7Io?svMZMC8XR)EIBj1Fdu$ZyD%JN?mOxi@or1dVqn|`5=`I}?J19!5C zOB$7|WTs;Vw?C-uG9Bl;gK=kEV)lS=7ESjPWqy=2Ym}&QYDd(j|H){HXqhK@cn>;ylQ=!j^zo=pAjd}d{1;^=b3Yo?+egj%nlp`lY>qglTM zuKDkGTn?v&VTmE*%m&V;5#5#~A_OlzzzP08^Cx#(Qay79a{2C&(X=pym1VB0#1d>; zGQqt0$GAfC3KahDbz@$*R_bu=W?Cp5z#n(*Q*0@l6#8G>A49(!^ijfT!FwZo3la|z zY6snz_hJL!I#H4 zN#l$U|JmeLj-2z*9Iu)A6(e3-@a=sNd`t(uy-}Y(}&z%?%W%8#+ls_MwBg*47 zBFg&^<=cBS^@CuaJc6_=8f)X=9OH<=(SyV>I?qqdHQ}m{a~P}rMeVSUMEpU*e#bcW z=Yu^97|BESdFa_ht`V<%VvYEuEZ2w?)v~~0t5rMpr5&{5)c?2@VG3la>BJK}x%$00 zs9+T6;LShomc(<)?7Bsl5owswrY$@Q;R(pjIgpnEl6eG36M+;h(X!O6z3OaY&2UxT zCpZroskPX0gjsbaU~_3$RrZQuoSPU`l^uDeX4^5zbzkqb;$GXNlZiK??>i(x#$;-1 z_Bd@%F;G&YSN{a+mlZm9z1V4^{@wLr=Ue@SAx2M(5Ez<6 zK*#Wfz(65za1MbVSmKBP=XwOTZjZoa{}zGI;DB~pev3#l0(_jSe~GWZg-_w@x%#j0 z^?%yi5#W&y?Few$C|xV|Qyp;L+V!7kN%+O|VzbTd1Ma|+cC-ho{w}=aCrSy{ob(NU zFTGg;LZ)?i*N9IMR9HMF8V>&v?EbH=bAY~hux6DGa*W?S2SXjbFi;w}XKugjlP zCUxh}xv`NNuE9-oT5!7bAMrvg0T zhmOf>?y)Lf8r0bFvr4B$QKk>34bBod-%f5guxrdlRW<%fn~Y9HEV~td%lO`b^H;xo zG4}a~F^9RGfwk{5Tg;ApTX0da^?Vw)rCd(g=j*|yL(n<}*UayC;uFI&eL2f{M$Ism zk*ue@e`lA&d28(Yo!0G*MOwCD2j7;{J-Mrnt`m?xJEL8d$^t@TeY}11wuWT&h3=0H zysCMUy?mWiogELVS70$ud^%B8m(BeRKh9dtfWh$mDLy#SiSx;KV%@`tnoZoPY;OPf zaSB#vdQRs@5nbSiYU^5wnvA=Ztbt`~h$DKw zkVVrU>q^lG?F+9H#(BW_#CC<33C12~v$Vaab}e6vE^&}G**u(s01^IHaB{RNAmP6O zWNekZUS2tntwH9uY}qLndm^WA(*~!$wboOs-v;&0_L+|A@p~*lbsKDxVt^Z&@tk*8HP*QwSZtNK_T(w z@AOyon7b{ffJmnQVYwC3Ng=ZGJ@kXa=jBrH zIUtA6__gp+a7)Yuu#;&jwu#8G^bfGG|_6t0XzMIXX~|k|zj>)UN>|or=T6 zSKNi4@l-PT5oAs~?3lK+cifpe;rWg%&_z9zi(n~p7rdc4u#+mRt+ zwBd{i3EiwlPAC0sWA+FJ+e7$0>iB+2f}41gzh2xe+CN_ReQuKfD}swQmi&+QkKKKI z4T2D?xJBqQ6noH2?M`dfMN& z!2aD=89rzu^4*W!>kU0Hp{#0y|XlK3sd0aPt?q~QV)Az-4YW{S4@DFpO z(P;Prg1%{6;Yer0MMYb%=FIPJzo3O%W7j8ElD)C$3Er4Q-&hixM5_d;u`K;dWh|;e zoo0W#TC>KsYB`i^DG zFdijRuKN^&5vX)G#B>!BUb=W%I9JS?Ob`r#$}ma8Myij!?ucjY781u3b|r(&=G9r7 z#dqUa7?PudPKMYlekZkr{Z=~_aXW#_V>lk8xE z2+k3O{7s-LyDV3>aCT`u1BK!57Z?iZ^KE(wy6;QV(HT^3H_8QH++-bR9%B8e#MzG@ zV%EYW#d_vxzLz(j22xEL#^JTFUNFNIN~SiUlilSD(;&WN$4MX;HL5O$*o6g+LKdKx ziuA2$FJ-^8bsnMc)VS*=TjTr~OQvn7&*&pOZ7 z&R7hG&?w=3KlMg<_sik^n}Ry?c>4u!>kQC;?TGw56}(JM5q(d{fhnBh@Nn`7crac> zhrfm*!6`RdhxoK)YB30cXkm%)b|ZINu)^wd-Ui#}>btxEZ3`%7#)=xkf;(>kn$mhA z$ae*Ko794?2FZne-8%=Va5ik+EO_PyLob;+#Rx~JGJ~vR4h}Nsci0P$8FqdFWwBVq z7p}XglMDSki!IluT$(0DD{Chgb)7}d3so&`xBPpDBt*ptvU@ZZ?Tm6ls0OULud#~q z^JZ=%x1K@A5qR6kt>om4+^5X3q;^xrk|bz&sX97zcn}yH6cnN{aqvaduk}e|;t2QHz~eCYs4Fvuy2o1)_;&%3-s7GOMaZt2(8iMP zPCePp)OfJD`LZ!_id)h>+Gst5x{`-nc)_Srqr= z4f#Ll?buY*d_6$++l3x((%v~O)q2k2H^c)v*!9-)eSC#EtP<-E3J)PP25S*!_6m-& z|5)&c_Y5yPPjxNjlBv!V3ldbzaZsC6_;ukK29aoODKg0U_zzZYirW0*b*`MOYbw`A z;$-uv+&yH8#evw~%1Mj_lYKc20+k!Aa&MDp_1*2tMeSS0x)(1Yl^f~HsVh}(n9AKl zV$(j*%nA#BCW=?Jr3CtR>K0hVh*=>5Q+g&v6EG- zcdl61crk~XFJ}0yAH$DW6jsywun?9X4n8Y>JR4ro$=>Afg*0qR2WsGiEny&BXXv|7 zCvt%zOxTRiH@m=tZzd24M?lDfF8~B# zz>E7`!(>Xu-%!aK{+npzU6sBrVErxMh#5iJiUEG=JWbxj!5%j7}J?d+N0L8|2)bb+#-zUF$W2nYr*EX=w^#qFx zYbd(HLsLh4Xo}Nlyy)=;+6ZBApTbsynTPaA3=$<3uH&U(D%>Gt2U?|31Ke#SLQ*UQ zI3H4DSVU5f{0JX@WrQ1gCmOKg$?8p@2LMRC%PhfjF51R82XMOU!Qv^dM|JswMcXhO zi#;uhi>{$GP<%Cn&7h@@5pzA$sGe}Nk_QR7yH;7L5wP+IB78)ApeqoDTWIVUl@%KW zDzCJXBZzB~yIi5@OY{;*6J55j_a+XiAQmM(UT(NKygaGQFBqyfx~o%+Yiv*?Cw}I7 z0K9T>J)RGCZFD{02$Sytv5V00V4aZq=2~SQo;coci*OxgyXmUajiX^vcg+e8oam)m zrwx!$jb+FFLUTaTa`12dokYm*C3)UoUpk>%RA*)Diemf-Dc+(mA!=?s+)t$nPv(y= z92fjCgI2-)M~|yaB3@xUXKb>}S9IlJp%#Y8hRsmZ3YVwTBz04|Tb5~9*m_L7i?a~+ zw@Mt%N_7<8ni!Gu#|5<>{kiu`?DE|jTTibYpX5#qh9>>%X;#xlkaZpFY1XStjIb$Sg@FO_ZK?d&e=ld8?zk^PdQ(4KVW8v@61OgVsckD4y|WRjj2lq z5;d4>GOL5O!P4QzjgCc9NukUq)2oR*!Dx3XgB!*1fKp|&$twSnd`){nop4`xzG*u> zB>~>lMNbJmZKx-BwXJDqJ$=qo&;*B?gw4J~F)B)QM@?eBP(T%v*Zi8xLom^@N;l}G zC>x)L4^e`$1TNW};is}8ay}|sNtG(=q;i+(ZX$8>R3H<&5JlX zL0fEpPc5U&SD4LW`+ExXk!~A*a+NIqyU<2!s~SP#}Je#>JLV7AIzTb}BC z(AU9@UpaX?K9)1T9^B+=mL;Df0Bm9!w*e2_r*@zyz|1{ zIjJUF026%v)y)!_*SFC-3$u#dkv?Z?}N$K!T{$NEHtL9O% zZM$_tTnmvW1?3w<#I+<3#>#FN_UjN%q`_a zSd-Ire;-INz7iAlJPxMGM17d-`^4{w=KIAzaX#$EFXHq4Vmlx96x8exBlP z$agS-(??2ao!R$|MctfcS6*>G%v}8{CzuYEN6_{l4u?+<_6QCHKln4kZ{7P3jz7O- z=2^Esa{iSbzehl*DFJ^ueMF1w9Dan1cuR~W6WEKsXV=2d2&i~-_n%^i*PK45^K175 z%bj2Q>_^V84RQF5k8)}M!RaC|kN5bkFZ`0i52l7giw-zI11LJXwsJQcKzl5<0rWO+ z44`l3#|F^3g49^HrH!Tgza6MS#d7H)t%Js8Jl_n;ZW?F+nW5LAvpVx_@PI?F($F)#rtX5ZHweIP{JTOZQcXC6Y%vyP?mxZK zR1-qiD9D=zwgz?0{MOr>iX;Ja7gy5;dfHP@-@sMjPI}r>Xda{LI9+o7BU_g2RrcFl`wRq0nBn@SEqC;PH*tHu8IpP_*=)#a2w|7yY|VNumr~R+ zzuSBOxFyr0$&C+$A^~+wrg!9^5}%Q_W}K+X9$5nFs+BywkjeFIEL2XIOHclyGGnS| zrP+Up+c05${&&(%9DZYcq8QX8;>a;)e^t4c8S0|wMzg50lITX27Tt*b=AEKgOlDTD z+eAM1hXAUIeW`hdmg^oz3aT-HE{;-X z@>}!?QEb!T7?uEVYc5Pe1aWB>EKy?wg@@Znbi<+Ac@J;(SngNYee6+V3!EQEd~PiPaJlJ4agsc zxB=o3t zGo67=yqV72%|l|8TR@Ux?Q^$*X+eNMEOF`JekuSZV zZl~5G^UWDEi9>(`Rwi%CXCQ)-+_sGp+X<&^zy5~Ea&|vgjVr|BGuo%1PXko%{?t2E z_3o*9|3+32ZTJUShz;huPoQ^h?Uu&?v90=vzZ6w^zgn6n1i?k*=%XzqSY4cHR3C77 z$@n9UmX%y*!xbyDa27=z9F9xZN8xegE^m87JDqu&r6-aaPLVuT7tP>-E~4*Sx`iY7 zq=16oUCb^XHA3OdNy5cp`(4?#-G+xP^-#>i)_T~Ghi!O(J8Um;Ud8P)m3b8ZrhYG< zslTSya`42;t+Q5}3Ufcy&b^eS_lAP^fUvyh8J$s7KbEZTEKKnw#3w6$dF zh@F&nzCS~XP(^)=fg(e(Q2)Hpv45K6*CdpG^Sp{gnOWI zgYfP7m7!wo5u!T^?QRZj+u1*9ZLUJCK@T2 zOkLB7dRb%bNAK|~Vx+Dtk(4C*oXyuq|AyI4w$kjaOGE;lG_G#k`@3dGy3`_a(@Cn# zz8Q$6E>VQaCw7Kf5+V7NiI!qR(-MKHEc1e~XV?~C=AZ&fJqh~Jp*_v1=5kvcJxG>E zp5EP}#6HnO|L8%2)e2Td50dwmGB|n=$63la|4`9@H8s3d%1miu$X=q{l~6ADUX&Ki z-rdn=7EkI((Qp(@LR*Gq)E)k+oFz2XPLg}ygw#wxSOU~6pP=rmNp*L87<2-*C_5DyyDSJXpR_?4a4h+jFBACdSd&|Hher$>o7#J@P*A^v+t zib!05c)9AynDx!#-FU=J_3~O;I3MFBa*HPi%^$R`zuja@w8 zia7bti;y<*kLGPH^6%wa5d|P9XvJlsXU2?~xxfVLYRQGP1k9#6QFTL4@8_;TqyyZy z|Ji-GBl@60Wgq_HK0FkC7#Mx{tNZXo^x@wOI%WwM0?ltCIK4U=V3OqT5FIXjpFg<~ z3tpO0kgc<$S~Q|tA7cHy*d(kA)74v@ViQIGLAitzH%Ffe|z#j$$g8R>R-It!% z0TGZbD^`9C?Nc|Uqiv#KR|1L1syj_v=b+DgMY3YA;%@D3S+^ zW^+a|b#_8h@a6DxZk^4yWg%?|Wk{eE-P}Bpkp~HA?369Sd2dHG~U(_HW-6o{dunq+BC0VBxmym?S2(i@ZM7l0Pd)8h-`M&{7ulba=bd)z5b3 zt+D8~Cn2so2RDmuGc?p18nPY@38z?DxAv+lG6vJB@xyg~iBQ9rvnWnn?E!N^BOv^# z@!*+X>qJyb9-sN((|TCpJNVhj??Vc3+uh;T_CyZ1o`zd+o`Y#vuA89$S7+v&kXTzf zG!w=)oMZ8O*CJMGr6<-vh&8lF#67*X^7Ix*L{z)>oZLb+PpNOAT(}Ln3X`mJ*#u;a zC)Vr|@7$o1b#C+Y908Ygja5eH_Q==cFArJ^?E@mT4+Q=l9)4rL3xEWbBZL>7y$*!; zk_@Q@vpm8|GK6)PF92%_5I(>mT$D$6KUWQ?UXrgNEV06Cq52iaij5sb;V*ZNC_Hyd z-{?Lu3h$8zm&fiTA^e6Nwu*+2k__SL&cp6@57rHz-zJR0BOcFD`099Np#98QIl_dO z0U|gb=4F*->Ja)wcq#NnLVQT){{PfAuSaZw#?~~~#+A6y9weV^6;;Kj__(sf%cA_E zt>y0@J@kqmDx(KYQkG|M^e{Gh80Q~M^^MF=PJ{Ett@tE-JgfF_B!3K=6I96Gb;|_t|gnT&p8YLA(W-q-<(n#t%=63rg5AC;|T zGSY=TobOtPz39qVopjN))iGnyQQ{7fPR%~TDOTq-1PMIXlf7W5IsgS;aCAEgTc8b+Nbr%g{cmXAkNrRXsbY zo;%40VhwZ1BFhkX3g~vNUDyv=+a7eY>hZ+&#-ImGPW#O{=qY2+5kG1Sx`f=3G04#* zJ&mOB_iVQr<#lCx&Jv`(L0N)6KRss&>Q53fEW4|>1WnL`EJ453gDgP}JkarxC1|>l z-0)k6B}iCOEqL!491&wxaHf9N8qVpyZ2bgRp9Zz*9lH$}zOwV~ zDCa4JAf3mjc2Xd{h8?8vYB%T$)(4$|SGYc~0Hm=cf@Fo32=44zrdQvws6c@5 zV%eUv-9N&+7o?8o_=i>uD>!lEkV>Y1BPaJcryBOQV%T^)<&{n8@=cUoD~4vhykzQAsu2^<7oGC9#ncrR3b=5|;I3hj1Y2vp@REo& zODI1HpXKIllNI6X95D;NImMb{v%tyQswp-Lyugg3QGK{(iiefQ?`%k-C4#dAE#E-q zf^|#+hgp>-ML7!Z1u45w!C8)c$&|QCT&W}6ZNVoFm1OEJOLlf0U8*NHh2n~ezwW!>!yXGZgG?G2qI+sy;esQvKU_u>yRJS9uJ-D>Pi#@olmYX0V z%kZ_Lxt9bOKr~8U7HW~ClZ}PGQTmgX?zAC`jow*No=}vh7&42xS-->>drh)ySPub8dMkBsn?hRYt!Ii(LZZ8w)o^FgbA$w z{3x|GY7-0WSYwi@Ei}7DjmYm+CR5$)L(Xsq;ia^QNH;iuIfV9#wUhczw9kGP*(LT3 zR!gQ{M`#uxncE&^7s!1RU`Dv3cy@Xpx*+J(uFgf)?|uU(5j-dwQG z&p_o+-}dK|>~#fDUr^iQO41crkyiy@o}|X*8-eccNM>}tP0&3>v=PiGbhAr0Pn#E1 zTy^3r5U-OS{JlZ;WSb{tCXWv%Sq*Zokq-F92AuxL+RZn?aS`-eBj~xl`azBLn7JDX z`o^hxtnAF$M&qtbB|8pdOK5zaC+eufU)SKK@Z@!!RJq+!a1=Ai{<$q3FGmX1J2`?x zW0`qSvh*D45C6bZUfu-9$FQVALq~*72b%5%sKjEPqVu}JZk9hsm4YG)qY-pc5rxq( z{V4ca1d8`hdXx>XuY-5_5)R=dkIk4#!92^KgKt!~ohfFz;2{;cf+E3%Bcvp)v*F3q zdUQRSLeJfd|Ku$cZfMHwhF;nukC~-5WI`C`s*`@Mp~zWMom$gLX-w_Qg8_VYeYYVM z#wWCS#)Y=y6T3qK7n4cu)my@(S18V`IWB;1iE(9Hu!Di~taqD6gK_g)CJu5scrvv_ z3Hb@DIy<^Pq9(e_+)7P+WheLJ#}*{#8dhabC|!G3T_l!bOAxp2xMmAY)en<5x_II) z=9H=HSZOe8y&d#IAZoB8VC25UVQ6hgn5tEGtTrUJ7@1paR}+c6^$_MoPvT_y4!SG6 z$@-jIYSrxgjGVN&GI*WTa4S*9K{cn6L#-(}Qq&a(kC4shP&F~K5)RzvN*9Jq+L>p@%*^bapH*lXB}Gyl<)x zTl274>_ZpcH_yMLFT$n`Ub+~wLolgwb=z?Wurl+VIRB6n#qY><)D5?i$WVsv-zz6( z9#t8stBj*!va8oKZt<|hL9)9|ykXzl&)e(iIq#wcCm4SW6JYA%ekg|AoOI-5c zcF7yL1vnM?2-mjko`XEYZKLBcL&9PugrZ% z?1k&`jYZd4`w1<#tekZ`4Ykdt=l4;nEh|e9Wh^Uq(vQ}p=V<*hV5s^Y0W}@;k>U3$ zKWny9{9pyaZXJ>)noJ);{?=dTjzU-RiUBEq6xuJdU}L|vG(jLU^TJ)oNqc9y#+@Uo zJQ*0y)A2^4(%!z(xj2uyN|WhV@j?%7JJztXh2qjpl~)VJAwQ^fS}2~T@A+vdU&--Q zq6KLuX%F8WM=mGr!&?M)eaK_Jh~dJ;hMM0jd8~(D)1L|B*y3IT%^oDk?V)q@Afi}` z282Cm2-t&0fIakz9x9^;F|d6S%f|MtCiqlR-dNz zxCoxOj13?p(Ji0x zoGPIQ5PQ;JHjY~QyW6d$kA9kK>9p@L#kQbwiLNe);HO7xb8pg)5yiz4@djGz;YSUKAlvP**r_2}GD7cF9jEtA{{@Mf}MTp#k!` zexAQk)cPB5v)2FVlU(cn@}2dwwJ!MAU~Bi$QMLaI#{coQhL?iAIH*(mj@(~u*gD>Z zLybjZ9r;7&s44URU`<)pnrq7PZ+%CKTCO8|xCTv#8uVZ4svGerfj`~{YkI@H?~hbU>PB~99tXDJZd>kh55g$Cs^pSG{k_9J>IMdf_pCJN&n z7e_qe9^4M}P$R-S9DK>9j&)8@`Z(e3;IB4&UGjt^b{?Dz03Ow0FY&ccddD?>9nm#^y760B zRfQ|ZwxfLGi;ebLQEN_AjA}oG7dX>TVJ5tKr+#{B8Yv7GtyciBN4om-A> zXDaLMwx5z%y}l^W-^XM5^Oq9*UB^9Q^8Ys8IG|(Ur=DWkXDSbR3&?i85Va=)pdcPg zW%eZ8e?~sVu{lN5l-35NT3iSgXG$Rwi{Ca~NxjL`KP3Q56A#Qw5lxzwDS;PVGLH^EbqLOD8UvQxFD z=QXUhR2G-t*7MiGwOvc12HJVUnyhtS^7_TLabvr|+o&b!-Gxim`BH8%fIOD!DY{F#QL85}C%T`!e{B+hQN8umQW_dd^N( zLnm9Nn=KPNY!;0}wNz!eQC!=#HJLL?5QN?;77W9!k0Q8LYZP->l#;AQsxz&oM|Cla zL|gEvAj=}riqHMud&7I&(w%+OMn`5we~Pk^>I__WbPy>w=H@4kTG*z`Ogg)@ z7ZTQCduP<7jA2WxXFD?Ju&uy9%_egHT4GCq;D^I~3vaVB;xR^0FB3x=hW20_?2I1n zV9PjlP1XW-nEY^zv^F{Ach8$ilN#x@e%a zCi5WyUSU9G22T}*h`K@%Tg3hlQ-onL%bqY9@xq0SP&F819Sj+{^pGmPBAi)7#h5xV z&hGS*ewz$_d7v+EdTbn)6RA z6Gfq5zOv-*oz0mW{;cFe6V4qDm?(}k*mXmACVz+`nf7PW^f|bQtYJrTxK4j4>cA~w z5IZU494zXoMDJ|Qo^_{axJt<_fWiRZh3B#z2mB5{OX`pQR%&(*_2&oyN{nbv!_5pW_&Vo_5Z>;G8r6cLuV=Nu>b3T-)g z{Vx&nVFQ2iFxp9SnCM49#^JDh=nyW8!&yf_mG+hI$a*Byx|Ok4+P#AsX;-HA&vWnj zB6POjwR?D{G=YH8)MNN&lvVH*O;~i4-~!5DSbru{Z-~03-5<4=`R-+sy~x%gBCb4) zUdYU&WW#ro)^<0vtWFg&z{_ytf@Y|u;1DuXNlp?CbBrY0OV*@!kZ?JYspHpToku_t z(=0g+)|ZDGtYm7W5C(ZfraJ(uU9%bbYDem%ELp=UlrJ}&PXd}74}VaVmeq(N^z1xe zGSycl+^DL~jMG*|i7RqOgyqFHgw`Q94U`R`3SVYFR|Xt4O(jz*DztN>mT8FjDKBz) z^+hMbUDkwStV|?w-IP0w?G-2ftPK()#J=7cXR;^kuf;Bg&PTt#!P>Mu zdDA@Wwe%n?OX|`?!BoAM{v`>n!52GX=Q?hLwOg~B>Z{C)4im>-bh!EA#d1R)qMm8( zzTS%ZHuTR;8}1yXL2Exvgo`kqB^%B&hjKTay5sKC7*bY3e0w~f{owPFZPf?WSvys( zctL%3vB*=X*Tl}}pFhxbPI?F@DVjb< zNo*G{Xdr0#__n$8`6AQWSP~z&?2DdKVWa&<;s?B&JD4SR;eM5)k=r1O91l$!wWz#1KI z$mjC5HvuZqU^3-5(vw}PT6He3QVJ|3w+xtr6cwW85So*r+rs+XPwHiNByTbwpq6Q@ zhkpdm@|hvjFK>R9PR$MWoQ`M@{mE+&8q4;e;enFJ+82vlSkhT`+m8**t3LxwuCy-f z6sdE-!#5ZMF!t|UZkb+Xf`9rWHGe&I3H z705A?e?`Yg4giu+X_POSLCwaekW z@C`%fPpKTvZ!Gf`VPlh)pew+`MZo5ini$BiZoW9;slnnPi3IgkE6YJU(e|{EX?{$Z z+*ikFIaap^@hT%I+9c@3D^s|t4Q~Kf8E(GN?RXt>x8uD5QOak^{#o9hM}tb;|L zR*vQa$pP+S0w7KbHp0VkEb0 z=>t>hiU1QQ9OUdq$z*2gO5c)Plhg^VBb&ZqmJJm@+}f!I7Pj2_N?oc(+oy5SgRu5p zwkX^cvEH;ozH~|5S6meinWP?aF6ronPKOvY@ri*j<}XCh2K?&0+Op9cB(n z&8J2n`hZ;PF3qRM-*aN$9PV4UZ$5*sIT`p<*cNtHw_)Rvd=yDf4;OzUSJ2u|V5ugtu@iwkL+S5$J9Sb?1=;T2SvXj5Hj)xgn}* z4ws<=Kl5d9Fg4kghWMbmiaekkSP#Y+*NY39EfTRY;oC-#1-VyrcQ<>xT7nPy<5^+2 zyGu}zS*`Dzkm!!C9IVD=2n}AkO8T{ker`@lreFCCmfeCAN98kDS@&LQ)GnM|);R*K zxuN1MG+!O>zg8lMn?z}zNV2UP+CdZl`Vr(C|Fr7%gOxy)ZJ}K5pVm^m`ItCt&jwK= zqLUgYZ#WH$d}JtZLOOcLDLBPNidCN4=gnrE=2hukosW+QhIEPSNYs@ z>uBhq_}&b!Td|B<|{WB9m<`&g!r5Ae~Xcd!}wdFfpsL5!vQQ(aCpuw09TLWI9@NZ7)zU9{;M zS!XBw0xlZEpWLSFwY1NCa1ukb$7-AFJB&AS9r!XoZZ0ibtih$b2q*04cW*jV(5559 zL=>=xGxgveMXUlrR?AS(V+^5nafuT#1+zwYjNE3VlP4bdSk34YY(2|uyeR<5TDy)veXHB8 z`>Uf0x872g#^%??z;oN49eC0%$60&|zsw=9t4H8w9K5idjwz`8-(M-WomEueLe)8{ zyE<35j0mdxQ+O)WD3A3>jD`N=KJgq8e$OzQv=Rr5*BA=F;{QbcUybWZ!ToT@4yl~* zNeN3NnSry3PePHtLuIDoEwh z1>~AjqNUg?EV z!P6vy^lp|-9!r0FhateZpfAD!$~U2Hjc#3PTfgqO3N9d{=ItwIE!m-JBMdo-g;q+d zVw$R}gsrJ-%+^{tA>ZDxKi}FFuloAEu!3=-eqI3*EFdk!+=Qp5(#{Ua%)R`@{PCS%7vePiu3 zjB78lpwg=UWf4KJpB4*d*ru5moak^eXV0X&Ck-FZ69E%mN3P(i-U6umwFYB>OYEQ( zge^>_E)oF|CKp(a#N+nGs;t}DhD)9>v)OFPCT_^*s9hWsQ$^n36pLqi>=0Y7fA4o} zmVMN*L+vn@SzA!t#XGFdj)NzM!IO(>$5u|btaFFjv(&!3g^Aj?le$##NS1T_qiqQG zWxJo6=m-!_IWL2QLNQw31?kra;shU5e*IeItd9>tfNk_#RkoVgm&wCsRj;?Qa=`qH z#wvm4Z$GPbD9l(ps%pZO-8$3`XDB4FagV!%SRL4!mc#!!-e2C@2zeHnnfr% zvr=PXi*B~dJ!^ z<&^#HE|B1)*q&@n_t*m<%JYJmy%XJ7rb5)}%>KG>%fiH;71C`=>Q3{08kt2{#KpsO<=dXh$jns)=c%WEvEU+VyQUL3X|9Pl1hc0&CJkj zOK*Hna0|A5(((;4&;Bl0jj=v{Lb}P%ZP;sIv9O-Sk10(&{sCyYKz5v3Ca+u^xqH_x z8Duli`bhyuGLxkN5LdCG(B1#4xynMkIc-ki^SmEZBEmzSP`Econ$_-bt1Nq|lVrrs zIZkg*vLeaqzPw|=gbIfNEt&p6*|Ntn%m`PJOn=seS3(ANt7@$7QG%9IIpLXJM6|EY z_N~tDVa>74WP)rtzx2#EipID+_%rNm!4KW~)5n3#CO%ZKlWf^Z^2LBmP(Yd)cVj^v z*yJTXTXd4yMlHZ{oYJfCa<*0AXcHxuXy+!fIl40ke4ZJ7ep$t}M`HnBRPv8}DsL{) zgeXz;o|V@Y47R}jpb(t92OXkMuUXkSdHwD~*u-vlEKRIID^8{sl7r5Y^fax^_Zs+& z15$NH$Dl_4cz3N(ccq#&Mc8s$UAD2QJ*oLDpFvuxo|a+U;YfnIjg2jP;-Cu$qj+S= zD73Yem-^5?<(B^az?a>F12;%?$R_^I=%!WI-K_>sxU8fknZB9F2`z1z#9bQsjYSXg zQ=RQG3)@P0vP;Jv{2|70Rb~Y2!PM6u!aUdk!qs+^JXG&4BuT$@yUUzfOJ+OdR5lZj z2zdT3b1v+@5Ipj6REe+E{~s~D^=nq&;0s?5ky68;^4sa?qmL+m9uNVEO zqe85tL_2q4XhUnuieSQHeulr>Fq{*!r7WYFYVOm!b?h)uW91Du{RzoGuAL7L! zq$6Br5-fvJ(+l4bjT#IB;*eyz6g>DmRiBmp9lhJ8+AzLXva4mz!@*gAwG4M!25sSK z*eQdy@YGcL^_&vYC9i#YuSi1l5svA%tkLET@}X&3p9LF15QF=nzA=_;FZCRdc1!Kl zMTWoGzns>ZzYX+7q0(43YaWZI-NCQCxhFhEE7Gg@g2hTrfa*B1xGO;C2Ah%182)pQ z3SF^-Rc3qe>H*3*((FNc*quLpTcGkCEEH{rIhlSG^~q6XNQC{98XLB;8IjFzY!1#7 zL$onL>}b}@Z57_r(-T0$%egNh)4G|7PRhbVsv`(ge!L26 z?cvj)i+yiRB^R);G2g(^F@){j`DS;~xnsp0Yj z-@;?Q0)n{z#RLt4#lq1ME{PG&hXyjkpW1l?+Tp za1m7A+tIpYz8=y7ijG1Hu(V{>IjuN3mtl ztv9=zI?vo}si1imH%O9SqGi?Zi@r4pGPMbp@i%+lE9=cGY3g{yNwv;{7ay#PAnVP& z_6NcI_1wJk;NSn*^XgXzAKmKkb6V&7wjMqaG};7bMED&g{CW#NdXSjgeEjmx)i?aa zC+o-WL!y)a1N@Fy4}Mbi+XPdKJ^k+44Ezoke)M$SdU#%6XV>e+I_u)cdU&tHnMGRR zm%kqVeogE3aCe^m1GhMRJhvYHevS0;M#HgFgyRa-_4*3o$iRo63r8)M;E2wwKlD|e zG94nOC-|5cWQqN4W&~HFvtsp3Y|4^-2 zA25}*p!7Rxb34%DQTBgYhZIcLlBD?x4xFWe?}e}Np)!40N1I!#DN~s~*Hk(QbcKq#eQGrwn5u|{ z3>MPaoN0?AT%(kz#IQew+~hRSCa0YkKw86dE6SoVp3|0IN|BFKlwJ*&u=ERCo==b# zjj328*u(|Qji=rUmf{itLo5l`Fs^TBJvMlvGkFm-MM6tZ2gVOx|x()<@KhNH>MWY^y*(8Z7&JI@-G`Sn&tEOPzw&78>z zBHpka8EsR?SwBgMFjl%*#Y3Pe$C0$PIL9^XWWe=n*o1RTNPcR6ws9JP0 z_?b-?o<=LcwXNY=Qtcsc0pvV%jg1BQy-w?5mCzxrFi!Xbzs`7bRXO0gPSqgSqK^i`#qa~}u z!vG13^<33_YY)bCIetJ9=N_=ANOyhvEoZxI&~O{IHH~r2Sqwl|S6&xH^j`u%_t9m3 zKfmo^Ox2}37dDG~++Nt{>0AW%^l$W2&ZJ&=lnl94L0msVW}M_nj~&!g+wUXjQrY=Z za~QmHi^{<}d;Lvgc3Mv9@J-ID=I05@Kes2hhR6iR?AC1@bKtwJQx3da*9uQ@2oL&6 z*p+nkl}&k}Rb{c{rUIV^d@Cel$>-=^2FSGe0wHhn0n^b?Z}TEx8#vJMd@Q*mFkI^# z?REzpt&A1rzwE|KgdZVH;mhrrKMXg5n#I)+z+Qld||lWn1yr zB%F=e|503(DM`;T8XkdG;=&R{#tv6|-OJ`I+y6Wl*%vDMrv7L|QW(dusPCuLVM-mO z)PYLvqtsqX{Z^@BQo#hO%4eAo&^G)*6SJEXjgk@xh;EqCDmBr|bbH9tVj0AXzBg?h zeWhn1s51yf@`9i{l>|jk1i;#usQvMrtyy@v+By!pTc_?dsDvBl5tZ*j`acaI$TCLR_yZ~}PZUY-1fnm?5 zy|bV0nc|P;(8m1;xp!CJJ`4%sqme9x&ZA;g+&i#lT9m?_7f&FW8LB0VatlmpxP0^TNz zM|sD{C{Lfx9cbL5@i5Q$Tj!a6*0Ut!@=~5kF-cjY;>NX&N@g@3^wi+lxz!cy z*Z8Orjg)amSsqcu{I{9f*XI~+Ke-&~X$LB<0b=$j%XH=zFD1Kq^?3#VU1$006t0>&;IIG`>o3XiRMKDdc zTFzMFQLzt)h1*qi<$e0^Ry;CpyWniK&L4wSp2Ei*jucC!mNlP5SGn2pDc*!6qb`8%_}g$%97#s|DZHm)A2pTa%Rl!(}I3f}je$0^?Z2Q({fm1>A3v?7Vbmni}Ee)<{A7zzjQ2Tpm6 z((Dzb#^MlInbe~^fQ^Gh3E2Y$$=?dIV3 z)Taq&XIOr&R9Cl5f9SoEDAm6WcGh=#KDQ3?K6Q$QrL(TDr5?~S-{oe1R`l0$R@}Sg z8Q-N1uThn2UHC`qsjpS{nIv=U?ADhR=n%XcQ+I%;Rm)Oo~ zWSf@q>YC3?fs*-NaH?Sn@uT%uyU)|sU^4}SzXVoxjr3gibe?)LQ*g0+8s?tPcTdCJ z(?j2=oUO~=wZf8h_*ljW6I+b^ltlTcwHwE-|BF(oHy9b8P?0f7reLp5wir8(#aI>z zdH}Qe1KX^{MUN+xXUgQ^)D*@dP5nxkZwdR2*{=~xj5e7$V}tTOOV{!Lxcv|hph!ub zJtHq?ZaucsmMo?I75!FBnf!~Heg$TsNJrqfH&g}4N z!@zE-D{|kIRn0GUkGN;-dd`mS(fgZwyQgt^q{`g`9veN9=_!1fKmSSL4Io^2l&JS# zN8}{Iy4zsM!Tc}K{uuIx-A&T9pcaTgL_4nq;{7TD)&h+$BL~-f?NG~_|y5XuZI5Szt-UM_p4|9*W#;n zQN(}U^%79b_rIQ<+b^~L`%E?dJ`HyD_(f3@@~=Dp^}U;U{1&p^wf-652WENxbrTNJ z1~l(q*DzQ=e(!zuAK^FZDo4M3{7f$nnm6_M?IrwP5`Oe_o_{?LzpVdSqjvrHU5i}& z59s&NmFwcy2pahRBm8Pvk*=R9{BQ~6`PcLCYt)pf^$AIwb@9W$-u1(99sJlL55R~r zt^Mn+e~&QyV##asa_07%)wlCBT);WW_49-y5)M&Pxa%~&Wc}-Zf10OEhg1HfpTe0u zA!Pq?e4daUC`g%-6R|(YF<2_!(#hRmn4ssy&QzX{e{y)z4?h9}7E7X95J`=1v|m8y z3=Xk5yW~x%rZeg^Igv--NZd#~U9jCMDoK|N`;Z@t_OOh^dr<@L+vv0W@pow%ljVCK zTXtt7Xr~RBqk z&x*63KI=}u1OD@|rW4VBV~H2YA}d)mCW#g!&y==4#`BLZyG9kxLBLhNLs8-LfTxWFvAa5OZ!-xO^8k5T)@;B z7HBh<8d?O};Hw9`;sdtelP3>{a=>>4Zlp^FP%A-GJuMKh^H#_m#Lo`|!3FIi`rj;0 z#k9&49H3CH)RC;BW39q?r8BQfAVG+>xvo~f{ByxFM=ILpNJZNmNwm$8t)p#DA0peR zKy)I)=0d`4vZqP#(!xWA`mmcL3AAFMy7R++Zf*?_gKu=0lCL+Jlgnn;Uqo0c$rx*@p6gPrf4QE&s@f8STL@w zukk8ZeQ!?;D*kT&ZFP-wrzAnz@1;ZZr zpY&Y77F*aPc$^GY>PCIDN`7ONFnqlTh$WBVO?Vi8J*HAqo1piGo&w))CJNYYd?IZazeaPvNAPcC zm9n%y?Z_YN$!)NJgB{)5?0`?k^mb$3x>29pjAwZ>z6O1bYtWKd@_Y7G zl)ls-(N{X0TQL<-I;yuUj6oaxkx$#5Au(V{SJqT=3|Ns?4vN&xDL_)m#>Bp5cx( z8?#gyZBeK)H4`HeD$h&EyR6@+A?KsogR@Hi?I$1+E(%Lck=MY>q1rmyxZ(r5`Z%$&hBI|Suo z3#WKQa2#(j+KCqm-vnUkONz)bmvL|Ss^5uawQ#gnDzu^t)o-C}xp}5QO{?t$|me>ZpL}ILy zr)$FQ`t}1_Xp9~zr>?rm6=Ok3n24FpmiV&dmJ z1!<2K^(THpWWrhDHc+K>%Ao*um9%6$lq4sx9Lb}|6H`mVV(1rPb{GJ}s0*^?f2kIjMKqf-B{s{i19Ft!TV7|_<8=&kgxn_vmZ`&qDmZo;q#Q^kV}@znf^_0 zizTkXk5isLmVt^IAeC2>lV36ao~AKc!kwU8Ll@W^j$idC1kMz`%N$SZ+{POmX*GAwBh=6uJz$-ya9`)CYek2 z@BpUXkppn10Ne(EY<(th7Cs}qwbpgy1FBU5=VWquvX(Zeu283BNU#*GbuAOJ*8ng= zWvU}a(-zT-X}rMpQb%x7nMGsL7p6)CeQC5Cd9maq0WpokSGZpO`WYeosjIE$f~KQ` z$={g}jU}!^BKKsMu@gq?W(zbWSc;~8xg8i4DLX$2(XO!>d_x1Gff5ZHV-Tho zm8y_y-Pdo!jw#q{8*GU}YpOZEf9fFtm@m=uL%c?Fo47Q3S7ti>E$< z=_OGV^UB)TJ-$C-;Oae0Bj3Tcmt#_a>^s2{7>5We!m(gqKMv!LgdP=bL*xiLj>p5K zSrklAf$UBN-)Z?KcS@|7DVg~YyqPJS%WU31^+o^GhrxqGq6KFYmr^O-V`PWR`BT~u zw*hh`Ola3TM7DSh+qT$L!dV&d%&;P28ajr5S_v(=kJe%uHklX=hWGB1pK#S=1~>9D z=)anAV`@U_lqSvlbD0V9UuZ?LPEi%gNqMsy+c?eE}O@qVulZ|Llv;i!+?-QV4Qhu*{H4S};nANy} z2Y>%f#M)UtnM@(Vg7mjuf83pZ_P0ULETZzyI;yieN`vnej$jMhV*F6scxkF`$?SHl z%7dvP{JmXrP;gH6)1tpL#&j``%{=H?lnG&di@|I7Hl zj6K<3@;kuxVkbm|R_lNNX1qdL&1DWv{EK*ndmodz|6hz(I29oO<#>e+zGcp~3%*OX z!pL#)3X7v=YDX@{SqhsMFz%OyOl{ z0g6{J_4??6`SA)zQBiOiP!+Eb*TWz5pn*Amd^F4#-6Jp^-rz?U4N0I+z4i}bxk zyh8V{qRw;GLg^``Czqa7$_WkEd{&2yC{Mj!o_ZS{ z38M8k)R+&Vr~qxI9!DnT;7fi)u^L$--_RncXY?4Nr3PFfnM=`IhIc$Vv(2~49NY!L z$}^Q~`=?fpTHZE3>btg=w(t3BQzfQNpI4n}({y(Es881Rd^NY&sd%RJiF4Suz9IhM z6Xz61iEdG%hb2Z$+o-(Hn>C72hn|@&=EO%$>)3OF&Yy^<51emH6r-kZ5brauW(5=6 zn0a(Rw;PkZ$0a9`oZym;v~RXh#u7v)83GGb4>~$?U=u9KPU<>5yeJ^$qkh}~Zg441 zw^nF$Jf$o16j<+%?yZ|V66{So>JQ!zATkv% zMU7_bOC4R)7S1?KP01AY(@(5oHvKVDnyn&1_E99r!S=nw2M8w=)1wa3>Lj&D5wC9o z?hxRHJDc4d^{DG%-{Da+W24iSsbHD>a_N$GGx;(9eS3Lb( z3_7s{Bh~4R6{(tuFw!KLs1XL5-E!@4)XYijviA#zZx988fh7YeZ{ctT>;U^aka-J- zkMTa*MB9Y<9ZUXE44m6vKTD&(_5S*JdaH^w>LE-$8+2-&C&l){&x=+#8Q>;!og4WG zv17U*Fo#*m2Cq0W*yu|>PmL@KE##Y_*bOHQHl+Dz+&cq>f?+hSiq_1@xGhAaSC+KdD!8Zs#X}>sp`AZTmfnTue-_(R0E6 zWDxtD$Gcg^+Gima@QZUKceLks2l8nAC(aOfEhAQ+ZWOK_O8C2m7}H@bx}{J<+Si$V zUl8=LaxL88op~i^IRRxXCiV1lmVAD4#W&NAP^U-h;VT|oKi(xp<0BrM#^B%x-n9>4 z5lcQw-lkV#b-H)cNai9e#>7R8C3@*38TWef-J0jm_ANsaojAwT<1xgitnFBRCR_E0 zI$8gDzH156Sr+Vin#N;IuPCSDKkk&=4ekxROxYh2)t54OEI!3cpzvPu498(oR!fY^ z8szw$U|9Vs*qsN-*2PX|`o8&EPF`FkdC>$ACok5G57Yj@=3vyRPF~2Oh;ruQ!+!YG zaP&A4MFy+YA0t#{BN4_hXq<*{v`w(X%{*l~Og&XUgB)r9sWf4r+v!P>($FKYtNTmE40z44T$rY)A*bV3AW zqOT{FZvc@GHWbohMMGw~*iAKN8*z-vs5Nb!IID>`T>mj=k2O+#n8>y@d_6{Kn zS4V0Jav0N7Y%mBn1MV#A{|WSgc3xnraeVs_YL)UsIeKpEP5@CQ;}Buy`U zGUIDiu$@qYnCXIDSY!3d$*KjSQP~%cx4a5yQc!H&Sg|k&($ul0z(OEF;N2PqQv#Za#?;Nat*L{m_jJogB zkF5I+a*nd5FX+Cn)O`~6!AqRGhVv#*mYWcF@;uy+_O!;XS=e2H@XdXIdFfc2HG(N% z6M3Is2R+xM4SP^X*XiXRTNDrXY4I&MMmVbzwfYSBa0`C36L;&4Q%A3X)3kBwP`c;- zyCV|RWW2ppJ6SysC;$D!wjOQquEXUywMUXX_o&@d>^hRNr+fgd^gx}@@!*kEktrCkaw0BH>HZ|w3N8e^&qCQuD=POfx;wz(l6NEl(eCe~c zY(oUFe)t{q288!;VBl!Vy z{qD$!9E~0E-xP?Asm!$*7)_l@btMGzPxon8`R=Tf-41#3CZK8XOYoqW#_ct#siD*E z%+`7v>W(?iL%L_taxsCLw4CZ7Cwow8+f>I0r%0buD|sDOx9A3`)@n}F1Gx^-1<&m3 zy-wn841Y{}D`;c&_6UYuBr#KctM-}M&Y-Kgm+oA423`FN7sIWFd5|UA8I+CL`pDj) zNACgB5?HM0lR~Nmv-uPj@$fV8@?z|K`*=6Q4JnwlkBOMCt;k%#uC`{`#?3)Jy<=nV zHda(MlrxtWd)xR&ptT7`QYW_Y5B*a?zHMBJ#O#bmAAjElO;zQiKE*a>cKvxXm`}ZP z_VC=6_Hgmf+rzb*pHpSy;+cYsOO7XbmrKe@zQZLap`tYkW9Z4Udt6jX{J=9o`%Qi{ z$z&p`&BXEbLp9hl1&NqN@sDqLq#E)2&IXigov^R(nP7V^@#m>^MJM>V_)_U-=&&e4 z2(;w4GMUWsTW04s)C$4iw58Zxmmnk|yx(pXOMYf5_m3Na()rihXuLo_&ZK(`*Kf|G zJKMf@_~!}md8V+sn=~~llFSR3EbAYU{QZlA*LLItXUM_pX4lnu%Y95m`h0M`0ClKf zA1rkyonAn3s?cagA$s#S^}O(lcNREc$J=9wplAeNFVg^YZ`@KHs)idApIP9At<=s( z^{z;jEZ|4cp2;#G2d9Fim@e4`rlaDQl^^qF&=s0AU8u@(zy9Z|h$Ul`3|}`(-rN{f z^bCwadt|$7g!5FJ-)}9BpgB@nQ&RnrX6IQH!YYmM7ofF(fF0W={L~=)TQ&Az9ttnz zPma=NVMjicI^QwblVwJa5@V$c?!h2{Di6QFk6GBn3d4jY8QzPCiR-Ozv&Y-LeVdf7 zCn;=l7z=xxZQsx#Hf-CVlN(!G+2aY%W%#2X2Im4DU8j|mJs2J}6INhzy8n^9j*RT< zRBiHh;o^;K;&VGGOeJe%muISX!*3K&NmQZbUx&tC&$pv77@qHP&4D-0`eMLv0!ohU&|E`%p zTyup+zVwau%0bW-*w_s|`8GGZDnO|`b$U1KNr#h6@gsZSQDiYs@+J7w5-&Ul7$D5? zD6VoRFkZ(TKUB<{De2497CZnp8Ud&B4t0v~sjMCTN^lDwHP<9g5?r&xnIUwd)I+Mb zX6GhO2l+I3k!<;|+ex55$jhvSZhLu^MH+W=P^WJ#BiL#zyNi&{i*-BQy|#Aq8Y_O2 z=4v}Rjxqd4=%@PokSWv_rC>i&hG#5!9M4T3#Omz+(#Ue#i1lu-&Huz~>&L4?^@j_C@tfa1^hsi(`LgzE0q1`?+);(wR=e|I&F#Z=pvCzbL2t31bYu z<67bOSD3i|I^hQ${kDh*KYuKeoF0bXu=U~>2ftCw%n^S1{)C_NKOSKCVPa5cgrock zQYbk8b5Tngu0$l%j}ea2wDBiwA@woqPk5!4r%Z=qD)m$NSDu)q-rOZ`mO31Oxv}!q zyMWJ>Ohh=7zc=~@{)BVHR$KIw`pH271*cjK-k)$M^;Z!7cg@SfZ$175>&=SvK8rQK z*+A;;N#)NQ@)w%6oMI$eZyF)?j0XIgjoifQoeP&&2*Z=c;asSN|B(X20UK<4pH234 zs}VD-WkhaOyj!8(DES^YV^E2#E72#jk$hYjB3}w9enPY(VV%*|r(DbI8 z5#0qd!BlaLn|l>-lD6;iHM9Ye)3d*(e@uy0QO1**5g+Gd!Bv1TG1-MqL@&1C>*V9* z(0-D7o-v>n+PZc0!jz{ZHc^}KVw($lz4LWMGL3Vl&<&T!5AlKd zA=bF59UTC(!HcNiIF8zcpUs{fi(TdH*-d0~*<$u~`kpDd6-xr<=!7=ku#A>X7LLJZ zCB`3KEP4U-CX3zSV3{K9;{_te<&jtN>bLJ$U9rSvG}*kTS*80zab&s-U&OfOG+fK^ zb{#6woZH|W2g6vRQ2lEk+=(k{rhV8b_d)sEi7X0K7Yvux$x*(w&1S{GSGHNf^|KuN zTnd)v2E{cLOBO<-unm70%_pIkMV^Tfw1L^0A#weaqLwLHS523a)pZ0v>eA%Kvdg}G z%e6N0Oq@Y}`8HM$%kxY)*=y58EV&S#Y&zJnPgzfKg)Gld(6W*=(kX$P?&8jxd;qgfs-i!bE#oXeRHoU>)(bG0G0a?yn!bP82&2S%)8$Y8AGj6-+kmby1QpIli*sAgNu{w<@Uejs4RqNBK}wjjJAqR>lF2uerM zQM-dqt}=(`k8phWF8s2-4;C$@coLxA>Y+N%#fS@x)FWKB}!eP)B#G}uGF5SfuTJ|^{)x2_0lyf!)$mv&taoj$!UMB9U%|#302mMmwZ=8 zT7}%{CW`Ib+^=0!JGR{aYNOR;G&*wX z($627(yQQ)>QRnhYude@hB`5OcQ5%7YCI4}+piobkm?bc+mIrtEuSrcQ){X`6!xms+|g@>VI zk}I2=ALIP3z4-ro{*}T@bjGwv|MRz3ENiPc) z&jUvZX5HS+93-QpSU!$;W}Ekc$ofBMtjEV;>;I3+$Fa!P=j^4dM{SBu8fk^C_tP%Lhwy3e^>1trOKPPj$|?PEqLKIfH`)@t@~Q;0Wc5cf zdE8-;IArATxZ+PX_^#5Ab9hXaGMHV%zSO>V(2cyPlB2fEQzciwj>BUFqpY;yCn}JB z6HDGk4dM0tk;7-?UFGRRcZ;V+OdMJoE8-aTp`1}Y$%*IOwdrAkt!_iViWMDI^i{0A z5m65v^&m0^4^t87SD#thu$qd(jZEB2#sj1!WLH~d+DIH5eF=#8weV5YQhis@23WaT z+GnhSGFL&(y?9$E`TQr4KbCkxJo@?^S4KTW*^J~#(B73{HyBwc*XYZ2vU1v>72M{_ z_4eiZsocA~q%pCiPFJGbY+vpp)T~%yn#v9G<>J1aCe+|QUY0g|?|U*alZ^G(LwrZ} z&hSZC#Gfn~9kQN`hVdD`=7dfzDs5N;s5}Tu;2+xtl!f5X_7DvB&Jl$E2I0Gw5dJI( zH}WS7!8O1`uvRR2Ex#2>$t8kmhVz5@S^JQ7m)?Sp0s7puxmf?2D~n}l#F9S(*EX15 zDi=hi@G5?^!PJBgdpI|N587W}OI{_88fJfo*xv#6x1as(VSkJ5Z&CTI>&H+)|DwIA z2hgjn_NFf6l`QySG~S82Q(onF!B_obMaG|BmBt2gTVK&V8vb9!suq*BdHk!`z&A-h z;ku$KByGF+c)y6W-A_jT*94Vki-70b%cRFT(pAj^c>6O3d{su9s+7KHi2h!7p8g&; zOnhhE|Fz&X|Zu+1|*6U~l4Q|y@Pw1!Xa|qdBTGX$&T9JS= zkPDAPZ%zjn{xKEL0Sgs z&L6_uwjoF0E3JLB+Et5hs3P^d^W^%nL+mS3mky)+aFy50u_26Ntes$k3+-_{A`z2# z$zBvpmo^)1^E-wqUBR^1ysU{T&o1@cRi54mIpmy4M0n+iUN-j-d-V?~@1qw|Hrx@! zv!!%(1Q9d;Uh&?P40Y0yFAkUG3B48w6RX<`-GN>e zi{%~B982t=_pV_P()n>1#k6Z=C1dM#`Wf{(JHO!H`Ke>|SuVkDoZbb{j zNIWRYDgTKXq(N+!NisqOG=5{r6*d*Tg;2n*W-EuX{WEqMX97Q4oTQX12tym*Mxm@FV3NJQ04LsEvr` z>h<7vEciV-zBPWa#8Lo7HLq`e=Kg2HFP3~VFQ?|`**v!i=DgApN1e}B+VH7xl#+^r zXK&f#SqIO@7fSkdc=#|Af>U^6R{lJeH!GhBM4Od0dYtcZ3$EM1{QDYf0LghgIvGK- zxSzZ2%Pn{8=qb3&>ToWe#Ph6`24B**vAUCt+wz%iHuQUU?pWV)rv6Ti&Iy#{Qy5w7b7=U7 z<}+n=bE<;p!_)Nzx|EZp)b^Rt=49+pET&2Yxy<)@}AsrbT`i4vlqK z_*HDshot9|p3hXs@4g=ojqQ1l)Q#8;OSS-PS!~dBU=LiQKP$;Ri_EhqxP~-u)>uNp%uJJfDXZmAWn=J^KBdYeJ}Oe@Ok#+Tg-boyu*je==M!X8|)f!vmzB+B>2=!W)CdQYiz5LXvC+K`#eu9K5I3G{9ipWw0I> ztgRg^>jZ)8A#qa`fqUA48}Gq=GTl&<{vdEH&KkI53>F=>|=9hEPHE~l9P)vla zsy=~siR3zB1*Y-tGIkt|J{0k1$lE0!QWX^S_Cr> zaIMStCYJE3bXH=wT1rz#o2Gqjs?uIAc&({gyw*Dy@lq}q0}eCu)8MEwQ+Uiy&;;4S zPG}B3RzE2wp>M%SKw(9lNtQ8ig!~eca79O$Q$nLUXb=3Xm`iL=PV~-)P(4CjZBJhF zX4n{Vt_&0KOYl7!sWp#N;1LzjR*R^BANSs7Hi7j>ROUEW=24Z=!9dwEP8RqwCY3IY z%1BqBp2t+Ck}}dtjPoP*NPfVgO%O5|!bPOCY3J`68FXQiH69rq-Dq#L6Endns5}%T zq+M|~aG%xHgzy)X@Mz zP)}PN1HFn4lrfqg0QMp8G+{FAR-8uzGljdoB5nDn$#_!R1gpFJ)NFkY=I4QEu=@lp z@UcqDSW}42Um1AegBpE(3npBm;nJ6KqWOTRL%4cUVnx%c)6OrXPP=x`UAlopXnu?1 zzdLS3{StcLXqv)iwGZ~j=2T|x+?$VGp7FUi@3}X3+MDcx*X@rxRr@rs%5!-)2{|N? zHQfz>6Io%5C3lea{k`Ig)1A+{M?LPYP`HEwF5c*>TlLnK!mfD)Ya~^2Ek6?K$-Pm} zgMVVjK&=I@uCRhj(8qM`^mg8%G`9Wf1-euZaO*WLw@U1 zi@R+hdb2_{c{hNZE$|7|xz#8KH%R}@${V;?;&wO>;KAreTmi>mg$z2+q1mOE?^Lf; zsk}k*5BHAAG$)bgyLW7*$i17wyVis0QRT~&Y}o@kX9`!K#-?i;F)?4+`KRWv2K@a6 zzJo7{x@77(vZm>gi7!AhO;i?Tt+6r)VC-^#oNmq6VrzDfrw?Gu7@Di%#>&R|aJupI zEKyE)E4~g7#ze{6kA>+hm#CaFJWs zd+@i`!YkVF;}-VDIoP!1ljo6cS36L50Xx{_VeC0o;0Bf#5|@+1vSG6JUPNc0XzGYc_ME@95Oz*M=)S`@@Ry(O`yU7V^HV{JkaKTChKC%{CXo#g?%lJAjy zXoN+TwLD$WNFKAU_+8Hb`QhEH_<+f)vGlu2Vd-d&2A@)o(2D?Qg-|dDzN56+S1o}* zG=$kAuaY(4wSa|=r)o*mM&rVh(P(rAes~-+4jplG)Dap=49@Tn-m@;*)Hw=D?z+za zZscJ*F~qd(#0ao_3AQKr1Y2k@_(i+!)Yv9la_06| z-Te$&*U1Nn@JuGJW7pHq?anvO^7kQ6JB_DIhfdw~Q}`H9xX4~xi#BLS$}-A@k2>;%&t~RBRt{{nh+168^SHO)SPauCfr%W(48<{Hc7>7 zk!yTK+Te*Q_+{ni5+97d7>`ESz@K%>OQJ=k%H0X(B4KL)D>nl`A86AOz&aKG0*FdV zhqtc-!ejgk1>a&3H|z`oB92z_)~%I$q|`H`pP-3Ru78HTu)w>WR*X7D*6s z&cuJ2m)4`p$i=)A+466qgmH2z%oiNx%Q=&}z42FYV^q$f=W@Qo+pXO5Di`zRB$ia4 zsmCWq<#a>{^+k(*r(3z_RBq8z4o|7zDkmNfc8tooppWdL-@{h!S(V$9EQr6A;RK$t z8oI;UYv}6NU_S6|=GUDj^`qg&$q#5M`VsnOi#eq875lrQVn?djm~1hfbC@mWaQ4Lv z@!v(oj#9Ckv&BZcVwV+3h`ZG+61Lk9Xx2IUV%w;AF;>*$*DYi5!McIjqu0mCUdZ&k z4kD>JBKjtiJXUb=pq}+>0k> z^BcS2&x|?MunMM#%LPt^R7wT;@> zg5X0dfe#iRt1S~0C$PgR&wx|h}-qs78w@@M04L|6> z*Yx5e68`|LL2_1pL$=qc$JCPN7pnpQTQ|jScw2yDRo{XBSm8r@9-oVzFm9y9w6>_= zkLXC!SEj2mjli5s1#j>$2(Q*aI)m-Lx!r!!YJa0WdTH|4^|S1r9J((euI)6h2YrkHAN)$3PhLA(*JM+CQXGDXxy) zu)rV{J!CA0IFd{wTTvzu5J21M)&kAA7e^bkSAfPStwODCKUS0l*n-#%N3-n+1pE?v z`%F6lW0m16vAJ|A&?{{iy#S8LSmGjVV7!|nA3V={iQmhCDNpX>W#Rz4EMja_S@d)Z*O8M7#0EKhIiD^8O{}Z z*92cp5pOF}!&to-Qe2TbuN$hZ8pt|Gk6hJ74pi3&6xSz14Z5o+ng^VSrExaOXq@;_ zjqB!r+wmKG{D`l0J}wkIH3H!Jqsq=M+#8u((=5g*wHTiBs}v~fr`+S_BQtexQ2DA&8>BJ|ufJq|U77l;2KORVni+~3O= z)y72z9IAiLI0ZB$Ue~?8PDRyj3a^Rc(u-Tp-sq$wkHfk0WJ>l?-i_Bfui@M5eb}ql zdmr|<79Viw_R`mD_I3L|R_EO(vf^P!$YdRO*AHPDcX0vB(4p-<5uxihe#nE*eG{Xs zUujA{f~>vw>I#CG5&K5rao7{p|IU3PtAn>XI{YH5L-7FQxAFi9Vq;&g`ccmb3$e5=kfFRiL94?$3wpn zL?^F{Uo5czfDvWZXOFE8Zr#q=WB2Ffls(qSbDLoE2*>LnUHwSmNN2;Pg_jPNQ5GF^ zvCpw)lwG&88D-n@gi+ROMV?Xi=!2}&j|B>Dr1>XUw(%&f_z17zlmkL*(}nX42OHR{4WF)lJ}dJK|DxCf;X;6(ZqA)=k+wMSbkP$j`X z9`GV%7xLEM1eL=5bkb$R&IgjzHMsb*N$R{s`Liu)w@TYqogPiarBl1|QvNb~vlFh6 zse9;+d*)IN4&Iy@bb+Ng?t`&k#t9dxWi@>{0=l7>!D}|gDQ!5ICm)p4G@!JhPu}Am zr44;^k1pyP(4QiagIVh7)M7dQIyl!cUsmYL6VaFE>TS%e?XLKk5!~iJXlNft>`~L6 zrBh4t!RrutbxU{{e@YvU$$g7+GpM}zvw{J@KuT%-CvupV2yCY0ap#E}^@Ka~Z8H22 z&clIHf0gL_v{IKS^@vjEDRqxhrz>@`C9GOXh&eEGk>aCm9Nf?i!K+Fq2H5cH%&9U@ZdG%|u z2M;@@lY(9wi1aAEaTxsujGS4KQy@Kh)UqyGriKad`Y{p{OE&|v@4^KRGbpo*$4qLF z^p3ZF0VSy_Zcc4KMT$f47X|<|+Jk6dnl*IB?kI9Od6}i#`VkE8HC(!VB|VFBKcoG} z(rd}b_ks$XhVuDF}LZ*JhwDur zinY(0tkzM%GxxR}Kfk&e@U5@Q8`u%SMfvP_x>KwT?Z?=!Z^>Y_1orzlmQIq)?;B$~ z{aJsZ)gtc|62wVsi8 zD92=K!(00EcYynG<2xZZ$l)DbbRPvAx_(>d`q%4FXDw7ArFsZoom$y z=1pFhH62SoZf{KH%5WOnLqKxC9Ku279?v9!>po|SgI8{_{wD}_q_S`?hZF3qBhewe z!t0laVl#PIn5A0K4kY;GB%~qopAZI^0sp@Y+qrs|#L{OfMSTP_x{7D$>Gj}_zqnRs z#f{f6+I#cTZ7d19sQ8!(oX>oAz|lFJ(Yy=4Sz=dBWDPiT#2PW@3^wE8K4uh-pPH$A5q2pPgfQ%TwAEp};rLnhXB)}|Im2hnuo zkXD6u-F7MU_!2}7HdVR3T4UIRHMgVRmNmCHN<}$Up}98UbX77 z^I6}hu_S>S1zog5Nm_pHeAeo-j>#OjLh;Cnx3NapibQN{#-%uv^?qo@UgQ1sq*Q8otjTfO0(Rvt3EG$h{6It}#m`RTq%Q zu{l!24gY{8*BXWVI(3eR%88|0)UU0s;fuKjxI8ggr6;i&=NUaK-O;%o4^L*r!rio)y6N=Yfng4TIyq#qblhT>Ji(|8FP{I=_1gu!9?Z{E;a7u(-QA z@qFt<8?tyjIIps79F&M9PUF2JgRvre8#SEsIAQd_E^3!fxLFo#4To8=+D`Bnv7K2w zLca8D4kimZ!TppBKsir>Fx_hrg2#nu)oK{X?p3DIJ1TM#A0vB-jUn~&7GC0T`HVnp z69w5bVPUd5z{L{Rk%Klr)r%;I?WmVh$@f%B$4#u#fv~cwH#J;|qnynr3mr&wC*(jV z#}d7iN_SX6D7N9%x8TqU`65bq&x;~95f{h%OrzU|LynO<#piz)?=ySkwoVRL!kF7k zV^bD~>Xa2VZEbe^JHg*>HC*bNiUmYFpZXSbHn810>&=Nsq*31^KQGyZM>}YU8_Ubn z+w2yd;hT|K=I#KU7f+3q(W4rDOy&GzgyOBhB8<#~x>~)HIf9vDMsYk{6i;vNP9mBe z6}6L!=0#xBQ%sP$$n0wj-nRzN?kEMdr3R0?QAW)I-ga5UdW$O*(QfA)1s*yL4?d^W z>{NlMNA4u@Ho`r#g12w+jL@H#79CQuKl@P_yAxpmP_CH-4^E2P1p>UN4es8t_NZind; z_pid2ab<5Lv7AIaQ_!@8D!3gzdfkKO+V>$*q8o`aE(TGd0ntk_hrKC|5^I1^)^iD0 z#+7k>6z8RqeX*c6_gs)K0jbSYKp%y`K6D`trPfw(l5++3)AATgX4;7si*#NJ&+Is$ zhdbO{4k7#emIFU*K=>0|W61}UIc=nXcVn585#RC5MsFCw(__`rhduedv8GOo$eRhhB5rT=sS=DMC1p2=EKHckk(<_z*hvOz< zxcf04OFT~zjd?l0W(EfeuEu>|mZ%UZIXBhq24;$=2Tp92x|0-cM~#YX9Nxub0+Ozx zT{y;A4lyy_P`d$u@DbaG+O=xdp@IyL;2XW(6{0;F7_r1Z9TwViJ}^#(RHS}t9#GV@dkcOmO&`}W_1fz9 zl(T$({CD5SH)sy_9Ia?eJBB22F(`RTUczgGsFgmtDlgJ?1JHA)U%bH_gT!SM+HBAY zc8|*Rw=#MC_$F;vXQyrU2|7d>_aP%Ppw^&Q$DqX;071Z-?V5_mP$IZZRLj23_QVK# zU2?y)S;r2954D3tvE(OO{z`K!fM~O$(Pmp~$;bBLh#?}(jyj(qeeAmA*x@FT!>)%* zd;lZZgz`!7J6;=*pf!trORwSQ-Qz_%j&eR_Id!0$ z`ZGO6A|=Q7HG4H3(4s#95mbwmt#f9{bh1^%X}6yQ_hqaFu+U1eP+~N7xuMZ|#P8y< zOWo5^^)o`wab;tPhg|EaP#rF?N4NYG4e3tN>qk|B`+upiPztGnR1=*{_hyfT-G$3? zU(j@;VaH^vq0I;v31f--U440HrzAuxclWfTjBxaFCEM&Xlu1|2{S-_9uuM&~ENwGM$;B1M(z8>9xJ>4fO@s0b6f<}xV|)mJ-)4nQ>6CqEk^vL7{A zt3kDjboJTd=}VigYSn+{`+r)rN-Z|hB>!P_RrSH2-TQEXNFjY${hiQDsa)4c8T%7Y zVYQm$zOM+*)^}GaRc0wtX|D_RN7+HLY);&;HW5K?Cr{oM>!!PR;07+_AS(;&6Mv={e$=ehVm^qRIV~#D3r@kW2 zyIVz?%~#vU(;HeZn=;@-U2WT#}%lwM<}NB9i6sd|pa8TX6&LWgDxp{Oa_e3aPAbWKOwdR9WUbSnoI`P++iiwA6E z$1=hE;zmww7jjqAjBqPbP~iICfRXR%L=SU`=nBSQSIA+*=}9WljFz?2N<{?J|LkFL z99+LJQUS)28@AQaZyJkfso6RV&fa(y(TBQhK0@u4XI3zRpnN{n6>KAJ)eXKs`GFGY zeaXkcIVS?+jF;zxW|qtRNu6v`FbB3I*dewl^S~fY#-{GM!rWgJT;>W7fijY>Z|8qS zUbb5EEGIYH-e8p^oomf|ia^LpmVG7a2pVx(ajL3V%C>--wG(HkOgYb3`#5y(Q?LqO z8+kx{{`c`d^GEJoo?2?^^bAb2Q?M&Gdd;cT%4*A8%yJ!p)zp2Avg(fPmxD3Mwrx<_ zTIOJS1)cKrj=NQG>4C??157iH?v(cTTSpgda@Dk* zXUKa^`v52woHRGZq%zXADjeT(<*y_<9W{}k%G8JP)O?4y^lB@eY3Icy z2g9=E+oI6zQqTcK;X6nZ$?%w3C#OMj4tGUr;{A~h#0-0eux#%OlSZLk{l%eD@12ijm4nW}o9uPLiB5d50Fw?|rL^<^>Egj$pRpg$G zUe3A6H=|d|Q7>&B%geYcpef!a;gp-T5hadh>T0r?Y2@9jX-CMEkyWQ|HsX{c?ts&d z!{0$3hu$pE1K(4@*YW_wck-`A)q0oCbf{W{oM+BShMa}G!Kw~bGnaX4V>Bp$K zTagDNWuvPuksWuS^ki)^z7SPDx&UX%mAaXwkv0Kre}IK=qP&s5C<4rppH7mQ61G0= z!`+eWh`x}=i`;a5?6XJ5P9oVp3eGsZK8@4vzX?>48l1t*r)DzfM_m4n0; zK(HQ%y6dUgYi7BcTXwg4cUy|*k;bN3@r3h=pnCOYnnULr2IZv69%x48z9=M8=Tl#! zVVy^g%G4K?saJyYM-b$f3b+Cj0D2GI*nEj%=jLSFpM#|)EutcAq5PcieoTDjH zwJgF6z0l3T7GzFNn{!jnkD8w1v@TN)72B8|JH`N+9SA*yIjiGfXsL8Yy*)p zDGRcuS_g9(ZK+Hxgkr<3Ij>Zt2G`0nnzCZS%~wg+vb4v8@XU(z;98oC=IaWfuyV`1 zi{7R<)RRgfC%XOE2dq25;$N@c#jNR?9n1|t<*#sceXu9>a9zE0R1|d%)!P9}vbkm( z%#;e&BFM3c%TcZn&d91&ye5H`#B0(gbApfIl6dM}&iv5b_8V9P=G@>-y-nX^MntCM z+-}BVg$eEOzR}-Rw2U((j2o0Gx`EBzFJ6JVUWwiAZjcM#!klMO@0j*B820bQk4Zc2 z>oo{czb!E&N_2}7RZ&80V0lCzOB6?mH6UPbL_sCWYUNrXVXC4fq7wzRko>v2NEp&6ZOdyKL?{CTiLILZ3jKmv*W49%4$qnVq)}WQj}2^9>&DmKWR+ zJ9jRJ{}{(w@tsCP1l-7SAY^gxMWj!8GH)*#Z3Dcl);aV!AL~YIIYmxt9rmyyC{|CV z9i)`);z69Kzq}*Mn{$3W@-Rd4f)5Sj@7OUNOS}WdvJ&r&x@hA1F_s(`avx<;ZP|ot z7~;cD{DM~&oW|hY?IC~ z`dI>Rxm7-a3wT!)bOFI2hoH#*h^ogc!U;_uM5E>vH)=LTL1}95 z7{tHYOgf8XQkJc1qBu&d0SSZiuce)3lavX2;23Cu%@z?h8n1o^ z|6d$hAqTza{G9vu7CSCn4sXJaMb%ON!dK$GyfdmSMxYAh?X;@b$)MHsS;-;1(m%hL z9!vfWVBrKo^kG;>Eiutpl@*QCBpQpI4tTPuYD{Ot1S55ihPxx2RL}4WTrxW3+Qlzb z#wuPR)a9fvKr`HdN}_lh*mwVkBhc|Otx2%dr=7n}F@+-#es^P#B<(cAKsR7in) zZ%+r#sgN&kVe|W4^|ZsOkd6730KX0Jn>Ni>Yl$IXZ;AhL_O)6x_$(oTX$gr9OGt27 zLNd=1n#RJua?JavlbS-L9}5aq?ZOlUH@fOV%lT4mOp||bhxO34-7ur;y;-`>5Etys zA4uEstsNh;R#rl~;7SkGk@uXp^!Qa6oKP7TuSHZhMDr%eRK^7Y^Om_sHjl7dA6=Z`A2N4&7(+>jK@c zE(Be<`AZvKSLEI3P`Pzo5Fai%Z>?%&}DP8EIAAXdSO>D+uW^gQJy|Tk99&33jiq$xr z9`i6!H-_m6<0qc_zUClc_~@aE)RM~7+{)BDeqAt_2Y-9x1v92H^<8;tiMMbfqljoE ztTSLr3TENlqd8f@P?Z+{)Q%?)Q>(Pn*Y=m#oAeM$*HCLpu@Vj5|{sq}4|9X_h{i?#ytpzpC`jw?u zRrj|2kdSh9(Dhdph7~k>IBICPKnCekSu(t1Jm|dwzqV)o{3{DDsP0LmWOL2lM9T$( ztnk0AQgLhhyYP~|Wn*;x_lnW*#k7-#Vx z7I47+++ZA~eu;xClMAZ%C|6Ut#C=h4G1-5X+baRRYq=Z|ohtxcW_i~$Dk>QjJCon&^*g+0*jAQYTkHwrQ?Df|Yh3=5bVB zP|<#tx8S*ANkjBz?i)^Srn%fsIn}n1yzS8vmOuSoJ8D^po(lS& zn;$x0rzl>bJ=>-heHPQopl+&PJCtx~t+3e~qPY;8I838}GEY}T-bHx@!(IMq-j=3a zOXb`}IW9PJLjby9)uzJImzdmnH0|1)gqX3-!9cJI4&_gD?r8F6tVYzSeX`heBgS0! zo2D}Zs2`-xHKah`^az3Gu!4Cm*v;S+ysQ1)){qn05qf|e`jJe zOeCW%kyVZ)yzPy2TR+!@Ri7E5!>O(pp3OE%I@bT?CPfXnqX{+2m?Y2K9solI2kO+|1@UvlXv*^5jdPAgoW{H|5 zvj~sE8J-LQG5Lqt0!u&rzeC`NoN)%8$9f&Aet!;BeV;#Bs;-gIJ<8fB zs=k8JXJe&c%o9e{$A99-QT3@p8+Z`&+p{DF7;)3Hv=Fnkk_$+Ie?^^s2tdnI6eT)F ziIowrH%5s`QDS10XcJ`~&zr~^7!!Tf#ZMSV*sCRmbhd5T)@IwE zrO3)CbCzmZI%X-WImQ4Ei4s!%*W=0zlWaYtPq)D>l=BlgY0s_z=lWc~*}%2|t73pb zUSR3ssJb=QI%?z)3k7A^a*QPw3w<^ic>UN#t9%6(VaB1d?SH3-in&INkk>SMP<}P# z!ry)_jh^`Yg5e#-13iM^3ulHr&KS`2%Z+~V^p#Z==_`j+q%S>>?VybuDY@RWLx0am zY8CQzvb`dLQdf#f%Z(-1uF;TQ9rWc>xPk}km9UmnaLpO;9Y#>{Y@WjY{GksIgK(%Q zRkW8jiWhiN@97FU3jBsOl?ZhZsz2e|!+rQFgd~Qhr_S=c8}Pd7c9( zp3Wn63!OoMIr}aZKv8jjEnY&!`#*P7toBOGub|?tjImZ!EV5Tn@zpF9r;-vCza0V< zpW(sP|ID_o{w}_L-Rt)&d+`AvwyJ-Oy`uhmal5)+9BYwTtAiTVU&n)QzpwxP&s_T- zGrj0nanY{p)?XCWA7@#@)qfZ%Yd;(l_T<5x{f!!b?to)Ad4rm#EuPxyfa%FLkp0BJiCTRawdSYl68>&jb0W^K z^l>}Jr+u(feAC%(&(y5JVYk67K(^cxGCliobA4=4Y_;e}+%_e@7$j+4ur*lVL>_|D zJh*u|{^k$2;ex=};BZF@D-1WDS~-|A>0B6I!Gp{JgTvz~OOyJyX|vA$Yp}Nc*Ne(i z-vWL&0}lhCkDt=W@x1y!k)79eIcABh_j*;N79Xe;1{QZSHN`D+t@bZ+N^2;Kw9{QcH%6#H$~Z$#Uy-{=v&>23S)TI{!uXSR5w7_2Kc2zxFV z6HgyF-&#Ft`Uden^J-SaGX+BqhD5BOk{nDhGfABk{ESQLKFsS6vA22mVRGi!ri`1T zGaLN~XkfD*ZQ54(sAdA!ZDBiheR~b9OhE;+ggd*p=j^a!Xof*U@xp|6JPB(cK=@a zouFlSHh;9Yl=5x{DFgps0#}))1GzF9>pM33T7h_lKe4)tG>7%AY&?QeeTHSt3YUX2+Wl=oR`=hICx zUO2AGjlblB%-8ju=rY@W9p24XJ6~-WbZmLPnj@XC^D|sUx`&WE2ITJY$Rz}v`|JMr z_m0(PMzyZYKYUI5Ey~mIvwRT;IQ)=+Is6(0A$aN(kKfmjt-h=915r5D*w!5bx1c2< z8)55ef={f6TAm?I1N2j+~squtQ zDjM7gsk@F6E-XL&e3f;p1rsq@Uwycacza*iYSV61^I|bax?r%O@7*eQSSDREc_*oS zw~CKfZhhfh-2$N>U3f>Rk)6&T3@O&4;P6trlp)Qwp7cqLL=MjmF9Eaq?ocoMjDJ14>Yd;>C%S$2w{sf-#!+){ATO-FBfzdaU7?-$g|}*9mbnyY zvE;S(A-f@8C*EZ@@8woid{8f-wk+;_@^*&1`oMy`FwvY9UyS(~pPgwY-m5=_D+!BR$DQO8Y@v zcOe}xS7Z6cGtnk}y74#KtYTPZVc0E9_Zp1vLCwq$7fK&Xo@db95dzHH4(*+A`q{d! zSkO)r*xCiv%oc98X%CJXJI|gtlOS7@^+WK<3D8^t9Em3ceUv)};LYQGPu!=MGE++S zK9qi#RW=UBqY*XZVbSq<#{k^+>5mWu6r|YQY@qN%-BGpc*;L7F#p&jH(e!R zDI$;pAMr|6Fl4xRSUHc^nT7zn5shspgMb`gd5eyhAT5goFH~L@-QR1!yXZ5S$N6X@ zK5^ns8Zg1$3STD#-gX8r<_#0DP=wPRZ?@@R<_gI6-X`Li)A_4Hoxe@89zxL#P!l&l```W#29z}9I7(^6uZ zbyrr!`BY?^O&6{kho!41O;PJ-_R~`LtEqMg<15(vc(gG-WcZJ z=LNL_Bs^bK)wP?qzQj-odOe=#X&7<%d9If)EX~~bJQTgOa%H`k`kpW1rM`7o;B)UA z2P&SJtx};BGFs+(<5d#f915XMtGUDEWWJ?(;RN9YEtI#Q4@?84XO3`usc2i%F=N2d z>T<7Vgh8#c(a_pUCBkOY`MnMjFYPm?E%}@rP8W_}N3l2Bn$u+;6ZU~CD!E}8T+*;_j37aa6jiE9Ej zxsI@&avc%y)f=JG8opDkai`jYJ}GaR;fUP_TOy z^Vjf!Gh6lYeQLHb@<#kF6rDeoZkvq?Qas# zr0>y2M#Rd494p0-yOm|)`9%&#Bk|nV5H#_m{#4lLo#4R56BlRk9$@Io@5Hc(+Wg&( zEE{w`)D>CPd>1AfbbA|F&5f)%WI)zil*$@(yN=oXcpF*lu%;?VNiW3{?LdZ`9x`TL zRJOY9Y|<>Aj8oiXVDGB>W_7MZ{oIe6zCY$IyMIyyRxU&MJgQ;o4=NG*MVMnnKgVo`5B>` zBE8bm#ASB_wZ>vP#U7wkmR{Ly0P<4Xc`N-~){AmZIY#o5Fp?H{% z`dqKIFigE$lKLvbGqv0<;>`Ds&OnVPjtJNgPh5eoLfwmg;VG1xj$t#$TD#7I3|otN z)i8-zkWnLPw@H#U``t|m96R7Id(r#&D5=3O!(PY-svTdRDLW}3(yOLWKzBURl_H#h z;JUpxM(LutgCT=|LLq2YXz3B4L&{x%yV)s~lEa2PE~; zM2)etN%1e?g(1ArJ4s!UMW=1jc}J+s_AoCSAk9M4TyIZRVd@QP#gkpdWilGL48JY! z()VirYcasaKsL(J5PnP90aw)@L5DU8XfK%lRoJQRof+sxxv4qt^PW^z&mCrY!w8^& zUv9oPD@<=~=3X?&;)y%6xb4JpqEgas?Hkysw};i6TJ=!E2P!!(Fg(({!r_O@XU zp~zPEg=1U{pK~FvVEQ*<-;{*w1h<&8qAZrvF6@AN4Wjt$XIwOQ7qFwH%pQV}t}^q? z1=XN>ReLeVy$025dZ-i3MP{gdVJjCG9w1Y1;3oB+aP?YiY>A{fR*xtbQKiz6VN2Fe z>DU?H(^ThP1P>~OAKYZab=!d}ixrdb(@ciAJR7KNI6)kt(cafXrDzv{t+q zL=<|dzQPH;|MpKT8|UE7X1J99!HLdwhz`2U{9zG4ZgOI2O(;}~^8&>acPKr}TgZ_* zHEk;EuP#psJi*SHhKuD*ad}Em9;g1|$-nd9FKU|c2S|E)!l>dDU$@CcD0vYq_4aj{ zK(38g@;v2l6Xb6m!Q`1Lv#Pr_knQKpLNwV&WoAcZvJp<~4zA%K!gjeMEal?n7N-m3 zXM1h^R!o)(=2e_N9+UC=`tjrldYf$AH-!XE#)X)w5?~6n#{VORm84!Rs+`}xD9t(L zX^uEW*CCi?C4MYhx7Vc??)OwSxE7n9u%5Sgf>DIWl;yoX=gkyZ$Hy)KQRhiWE#Ej+ zeg+g%pglJ0O&~5E$K?Dk+JI@6KjGm01j(FE?DwtkAEyvR-nkAU6K60k6>R8}BN_22 zBAOsjxQV|A<|Y3+k|=zE6)v{I8@y*!_+ie1%NJOZk|DP~tT08c&%KeV zu!u8$=9A<~by#{nX_VgHO79fla;i#SVApnpO9kMCkIYhk5Xn^d5dU#J@e_l}Ypc=| z6l4X=ae{=PEvZZF2`l*tB^Bdo;}I0@&Lxvv%mrG8?h3Lswv#<6;!iPWPV-%MlWub# z)ZVk3)Lo+k>?BDs!qDi%w&bQ_C+SBucgC^rjn5C@>|$=i{H;}zSNgi*9=-amC{VH* z&lc7xo?s0CkOh81#k$0v`9{1$Gr^J9O1Mvax~S%s6G(`JL}lm>#gj?=H~5RxD%VAu z4R7nM<~pQ`k5zF-1^$vCQo#Ft<>lrj_ki zisFR$5gHUxg^JhA9$8>yNdeM}BBpj&(xa?)v;zaurVH@yNyxGc(B`h7as_U-NcWCK zatfxe3uncyy76cua&WU??C7&&-#PIe!q>-EiaU&wvrs(dKrBi}5u}1n9ll=>NNTT= zG|)I-Q7ej6P0NUXvVBhJVv(cbiF0Wk&7rQRCU-MrDRTqy~Q#0B+i7rkb(Sdl@ zocmXM0jB3tpW^oYLI6@<;s=(tV+#!junVwbez12fF^Cl&#ODd4^-OkoHjAh1GZNtx zpQ;)muxb0M3w(&Y!NJY{sxoCO#MIc{2E<}4<5KKq>CD0tIw>8Ek($=tmC!h(L^Jo+ zK!o9fv1Uv* z-qW4YKrJ|v7KV=M8>^%AiApc~+@%+~_)%%4-GaJSSqJ0I0?J;h^pY<~k3vnIrKH>S zHH{!5Ro~bY6)jTw@hEZcQF>J~pFd3MFPhgT$C0q~#h6N4+uV{qmQin0n+2_MQycSI zGk>uq=6Q}WHmoYb=6Cy#qzOWPf)KyMe>4djA;IEZ7fjcdgFn#R zcK;zALKieVT(b0$P@jxzj+ADk{NEoY1=Bw<`N!P_&Ml3K)ujAi#N0pDVcFiW^uW?$ zwf-MaME+Cw*Wh1Q!^}6#IE4NGii!Sy4xJ)H=d=HPbo?ob^H(_TBtu}${{{m7p{~iZ ztV!)1nL7D>yTD(}?I-9un?`EejLgF}Dd?~Z-|znLTAa^TlA zf|?2*+}_jgLX&?2D@edz`8(k6(DDc1at7isApR~W24JUP>;v`&qhC8kzY(~9mIE~E zH&N`5WXS;(jL7nSBJwnZzlL7I#9**TH&&eVN|y1!T|9e@zAm)xM44}>j}RC6G0EEJ-me$f^Yb$c>g=w}DT zf6B@0t6{a*f35{rGsNjIhtr$?q9K#Qu+CPl&PwXk=0sRzg~Mo-FuDLjKF)>jHXmRt zC*xC}hn4>3D*2Sn<&P^~^Cp05wg9N+X)@Q6SsNo)H)x{f7)ov3B`6gp654Ux_9WKi z@vxH~#QWWO01fAhui1f=uA~%9{~GZM8evl+xv{5n5tScg$7b3FhX&muSZ<`!c7fZM zV0R&@J%g)Aczd-T!~3zN+VL&d*8Otsb929(``oX2AGhV}QvqCVlsA=!r-F}-E%#o^ z$_f0-v>4vyek3Qig;sr8xuY|=!TBKE72{MWa4lz*JttF^v#k4}{EDg?-E)XS?Tzc1 zdfvPI<{-|Vya9n*CWucI#t%%}=ZY2X!q%xlG%Ej?8>`4pSl6^{7;t{pQg~DU!lz4RI@kLh_?^nB-_1V zg>?G)cfrRHD+(!UA3n4WALKf*GG*aI@9;q~Xj$FD2T5Ld#Z}^GxpIrx!-|kguZIr{ z!-whN!_@F$5)WKQ<#w?)zr^Ihq`1@KFmIyyt~>r{=WiSjhfFswc|6e;bFPS(3S9kx zqjC%TV(-Eg|3&IzDsbQ_Y%V2(4F%%Z#)l|>N6X#JHFQ4Vx zDbjf2c$n`Z@{t-v5PWB6=e)m9r;{=<58Libmjz#3aWN15CW~pJOKcxQ?-kqsS?9gn zD(Kp}TSQOir(9Hj?WUNXjwfP&%;2XmjRF4g#D`HvgyJCqir6IZ^??{UpF!=l3eg+~6Lh|ZOA-MW8Su5a7*9;!)igm4`}EB~PHb552)A)N zIrbIH$Hn9p;6+ z!ss-D^|pqv4XAi?laeslWyHlF?c0aci4a}Orw1596sEBJ=hN`sE|I8VFBOdgKbtr4}dA_Iuf4PrRlAI{m`!g9XpS0qSSpH;5;11*U&J zf8f>ArUu@Z=~n&!L!IdN*0%BHLNivq4C54<@jz^q8{gIFk^S_iMY2i)PKBWvU)aMg zCM|)NHKj0B4+YcZfiZ*UO5BV9DGq=*gXiEGfUIh??I3=f!E<0XXe^(Lfa;)_Rc)=B zM63D#yJBp3{_2U|U!daw?z1QLDw>q0FKbqsCa$>MPHN!yd&%`ieAI5Nv0&zpZ-+hd z+QQBB$icf?kNg2mP%wR&r2D^lq7P;?zmk1B#4kfN;up?#BkM`Sr(<*9a*T6Q_{emV z!pid^DV(w(i=9ZJzni2`Ec9PAyLFT3m5mo=jg)f(@KqfT%LWvVl)HcihTWytHB$6Y zFnxJAQi>gpd*tA_t;2EofC$G}HfV4xG#mxxzpk78$G(8OVT98rMd{PndEKf=vvB3y z2L9&@vv}{ZVsct)#tT`U81jCPU5)owhP>B9!Sod&@86g4oQ~Za0CDnB^_0oSIsGHv zr?NrA`xpNx`4E)U=lS@;6 zwElAQkG~)13}8(wB<8=G=s?kR;kX6l_RAsnKfi|q1JmhS9k_JHKa1+4i7^MkV{-`p ze=pRW;rg{sg@{IJB>xgZ&zZn#W#CW4u#VpT!?l&su|?;Je+5C}B2xWN)@Q$+gag3a zuPGWmS)J=_Ebqcu#cN+7$Hm`Wd#?*wL~yG*-m6WNZb!xf!C`eNz6PF3bE`IG4N3R` z@8X^1wR<-xj{}%9WdC!AFXSX;)ktXF-u5%Lo7SeBG_$w++uNJFr|Z74PUPPPmZ%H5 zRdw{3`hiQiL#%@NFj+Lok;RSOvq;2`VUZ|;@5FExthXo+!z;Xs_Lt9tlVNg+;h2;| zjEkb>eQ8PnIMchaqJ*d^#i^g*ijusNo$REfih`^v!X$yw#}u8XS0pJR_==2+u7c}< z&yC6%eWbb8JA3thBP1{xC*L7a+wL>}c|ftw;3cQ;Y!DtE&9zY&ZgyY_Id zpsqS7w&!nz1A&tqfe~eIBgemqvb4K^V_}xH{E8qZemlhJwUF!l+d(a?1?ux1e>0t0 zy=9Bny}uO{8!?C|8!?>~L-_P9g83O?M@cC(w&H5b57KNC7(X{s=zbf-3>53dqrtSS~RwF3-^4=DG znTX2ocwaRZjhoRNwIV9NWaZoks+?-6wRQH86)?>QD_clIWo>JX%E@hAEBC^j-1fC{ zd*|d9)yh36CwE}2+$Pz%!$xGI^j)4P4-g(UGCONocGk@GL9d3Jebt#<9rkAX5NToi zaHID?CP&IGYx{6iCZ`lB-M&~-N_?XQ-X-L)mRdJoKS7kCz07gpPR(C4PjPy(A`N+W zHlir;tahc^3YJ)I9e0A3U#X=mv(8q2aEKO5?MF6r!!0p(F#HP6(2{%}YZsU7f4FSp zMvE&|v!{i>VulK$hdeV`KrMPmO+(h!Ec=4IV3Sm2G^D>Z8+s4MITd^Zf1*gK*KimN zEU%2PyzFV^jy3Rn6HS|F)!yG5>PvYqg47U@VjHp69R{0ZgVj~AT{w?V?0CmnQ?dFH z^x=g`4Q&pn}9^l7$A*W2kb-ch!@d+hiyK>nQ^Za&5%>Dd{Bxam^eU)~Z zSrStc5k z$)>sGYId-P_Thu(8cWfXWDjNGL+|imNcbSb+RDh#{zF=!TkOWS}*afa>+ae6(_!9}kcDAn`sgDt}Lt!}PcoT;6 z?umq9(BDI0n7VZ+4E;00@LwVWx&0pb9OQxaH!QX8C+N8GHEW;qbcTm_B!42t630cO zOs2a=*}k(v#(sI6F?RdEMvQGdHDqj`SjgB38OG*?LjE7g;aqh^Z_-tT!f4`$)x;mPBmlo$TVL zB6K(8NmrHcAj{vV4ch-fcLuP_kO(xTv>I={-CJ+>*3G?1zmeC;y-CUO*518I)3L^F zrnmGKE-aBz$CX~e4_4Dklcs35JhxB6&FL2J0#aueVy9{Y6W%Yn$?<-j?Au?*`(u#g zTDR_sz-j59P(Rzw}wx{?S4EH~sqdU#h=J`_nCn_BXEA9X<8^H$18D zCy?cPyaea>w|~s0?RN^>ABC6BwSO&7YQMSKuiz!1|CxaPp#2wQ0RB4u zzqHk+^ji}2_vf6IYyUK!jDE8GV|j^edaXQKawD4r*@!kpn*PydtN#{T>*Sazz}%iW zZ{@F{6Uni8K{=T^E4VXAjw!a>I(yJ?e2-1yb5Dlq;?%3fske$#Un7+X;|h!@eBH(6 zZ&OHc{;Uw)N60PJtRB4MBue6Bw&podQ(RTvvPDje?xmC{t|}!)x0fBGyR;;oe+36K zbf327+@i`=KX!OACte9>30`iY3;cQ@s+oIeA3kg*UUzX-!Rq z2V0I37FER_`M@3(ue%;+ph#7`?st~iV^+LwI#6-$kEyEv8T{1(TA#G!%w`#n@#}SJ zn|fPun2A8$lL^$V2;CRvDVXqS#Z?4l3*4RQRtM8KL5{=w(xsixT}FK27tJD2WaAGj zKFf}QO#I_zM95q19elA3i{u?yB{T85|F)qXUluIr3L11n@?Q3R(J(>|JQb!WFXN3( zF?*lSd5C`N-+!Gy z5gQ${0UHhDi9oQycr5S=W(@{Z7KFP5;l^wT4($Mf;odKV(9q)7*Z}hTsSY zAQ%<9=1`G595|eN9>Nc?6&AkDN$uEPt1X=GjV}SI=$fG|@)$$$O>Fy0uk=J}%b`g?gN{XMR?{$5?CzkLSl?|DP88N`#~)b(FTN)$RG zou7J3BzHV}m44doxLiN24nb{r1%XT@s%7V5HB`kO7WYy;@=8)e2~e<2-T9RXAk|q= zIYK}Db4+O5gLsdPd$iY|Zbb`v^j4Ndc0Lfk5||IB{rN2Hyn4kcdoGisH5SA+IA|pOlk@_RmS(+X|ko=E9D?a*7>iRmk6xBlKplMJ!zodF6YWl-6)pJ!#4utGh z|Eg-A@(23Q0t2y3Y>Fq}!r=4uCq8nJ?1|v3F4;l*Pc=Iu*p0G*P+a+fN^1O;q+0-I zcqwCJH^v4>wWIlg`12c@m7h&y_PV8=f2{aIc?X1(2lF@a=Qp5amwP+@S@T21p<&5S z@NP~Qmfq;~rVp?`C2R4dLQNLTI)*{*;`kp4NkbL~NFSZ9zh0b_9)4j{6pv=Ueh>N7 z*9ArhdTHmYmVuv(%KyP;zb~Nqi*Y;1;TM(^e$|5DttHw9%|-ZiH2h8$emvE20sKS! zg6|AeZvnq!!Ecv$YU3AAECW#3^5*8(jousQyZQCetdddue(#uCI9?9V3TB-t9Fb_` zyV2hslbEwFgZxx=Ja>|`SJP#eni9+BP2ayL$eLAGejCiH8a-~EH0nDTQI(%~z$z`N z%Qc(Sw}hOUe5PXf7vcZ5Hk|)EF^#Y*-o;djk35-v%@sOA`(uq2O1B_p0c#nZnjkdn zZ+vyVRVh==+Tr+H8`fbsenqvFuJjgH8;3^L(-24xn;J}nC*V(xC)2?5TL@@sd53Q| z-qM~zI$14iq#W6&U-krhsi;{KVOvdX*5CMn+_Co?xvT1Mkw#XA_skhY*n%nL=ZI)G zX_(FN7$$4Y`31B3QPB(%Q#{ERHTs_8ProSQRNIV1Ta*X%}b2Mv+z zrh3wp_oF&J9lHhsLj{&Nk_vcY*B4pD|mro;`$egZMv%|Cs^1>GuUZ zNe_GF>DV8GX0WtN(pNVNhc7|4hQNJ_X}@BG`!%hh$Mp3|A*O0PaVQ)YwOAcqaTZ6LZh?dGF&#~5SX;;^SvV}QYqp?y34 z0cvkttQiPZQ82Tiw7LXt9O+C}J2P3i4-ZTgdQ2Yi#7MH}?UiGh$BMy3sD7+89dP)h z1793?o8$4`;bcjtCT1v)!}sxog*yn8nR$QW38}DvtfF+&JQfgvF!pLFYO57ZRsA*M zM)6ihHFHtWr@LrsFR&<^?G}tr>xZooNgb;q*-g>CziBY0IPFS=-57}E?sGO!MIsar zMQ9W)29ynX2vdGn?Na|pbk+g!17Z(+Z6S!o7J?z^y-$U^c$n}rdRIh-A!q- z3MYwq$+;#B*!$A6fAIDN8+5TR~5Qe0C^bk`VXRU&d_pLB^mI0b^v&}we~fS|X~-t@@u`g)&OMX}KyNaq`^ZV|Ap7GXmSP=Dno0_WVmQ`WgYFmc_#gWTEUGFcE7+j4)aaMq-o4^V%To z9}x91D8U}-G+{{RlznBCNd$Qj96A;>3Y(tk&Q0`#t4;a6FshKsUDT|I>N z#!rtBu{_Kk=^pYJPq<2KK`Z98)|-~J0}6TTCP_H&EGGf28JY86u8TlwfWcok5G;Tzrt)XlNK)?4QxiSoZ7ix-{D#%2PxW6l zP~co%({2WRr{2le}*}rD6~`P0Icq>QmAA6yjxe zhdYE}4SRD{Lq)YRW-g|*xp*jL6w`=CbT#Q22SU88N^Bu-Y>q6k@I3P_?!C{@N}ZSJq)RL_k-6TbHK((z3k^BH1N2=-#cc8x-&{ zysuTiBz?gc0ymC}Cm&+Fy11&OB}=z|6jeUoo_QU6gW#-TV7FpinuOj>@4&gv!5}LC zOOgB+LA=$hZMtco#&kIqVUyW{xoMB=5rtnmxkbo_Q(k)ZbSoKpM(j-oDsA44>YQnH zBHNe-s$BykXuuw`8aT)`FoF_7Wg$Po(woBemQ^_BAd4!Mcl|KIhk-Ay>_S zXk6H$ctK%%;iB_bA=AzPqgtCi$5_(0+ItJX&(?{gf(6MDRHl(S{wV%nMA{`-1+z5+ zGkFLr7VkVFb|FF>TE>WDMf;-GuJ-dwe*}p>1QyKP&JtFt6d2U;*3htj0+-d}}V2Vc8YI{rF*mW%uLPQCWuSi^LZ5 zKjp>Sg=LH2CZ;fybT}T1{M&-rg75b=xTgy4Awqig)_Uw>si*5vACfGXy^S7QS?acW z)DooNx#h?5_%_VpPU`~`8N-SC3gS!SP1G@J@_3D2tumqu(YB;2B-t$-8Wb;h!TKSy zJYY2j+Wx!Z!gDKWLtpt`#V=^HmZ)i5@Z87twniDNd9+i>=7)Vl4X0fv7|LR4_H`-FXT;`KG(bN*q=C9 z(cC(B2Fx&y`f>_m`JQ*T*zhbbvSk~=c~=zqo@5L;1utoqM%vr(?Kde{qplD$bp`zG zlB!k<52SH1@nG|;GC(ZHl3H1k>71<8-Ce;ESxGy(f~FX)dK6c;E1#1B`bd4^vn1Vr zl3|t6yKmwu@fYwXlDVWKrG$iFGq$-p#@0mAQk7x~& zr7SwYlUiM|yCr>89?xRTA0)JaA0(^xSHvI$;)raB%Pnn_pt=i{%(2exGtx0lNmcnv z&az(pfk0zRojd|V_^E5BE91W`0z53Mf z$1Ar`7Hj&A0Hjw#L``6RVM_}Cxd>7{R1)bCqzM5e8Gw_p=^GbL^&X=xk7nTHRZQ|< zb+tc=r?;`%ecsP5eT}umdLmPU24oMe^xuiv-7%<1@_gBn3%z3M`9Hb>8{_HHpn%uG z!COPgFZlnRf3W4S?nn>L0KpCoEmm(MT@F`Z$XN&+O$r8E7`Q# zZ2$CjOq#%JdXi%h%f8mKrp;RRs;F%;!-CCBMsmz*&OyT)5O3o9&pT9*ojgENFjy_- zHT{k`Nl?5aY9Z4mFj}3V?7s^HhQQKs;TSsUS|+>mx%lOGWsnujZmf|rma$qedq+JE zk)E3U5sx~KTrtkShCDVXYMK|!M!n(kZZ%;jk-fJsurE$9Z*b5JRhvdD>rC{v=#)v` zZ3OuBuHa8_ii>**>DUDk66fEb5m%BTqV-C~-9wxSE13OFX2|&sr93p*#hO{A_TI<~ zrDMx4SJ-+^E)}PT^Z$&qxC1{BKEU|KSexDQKm}EmF{l~|hg{Y5Jz+7-dwD);*PY%t zlP7uMmXqb5AZ=_uzk=Ca#FGBTD4~Z2IF;PZfB*bVu-(tFW#XyzWAFnXCXG+LzS>*r^<622tU%!suxI{VWRt0k;1DVbbz9)XJ`hSEtU|-_i z^t_7tf3;VM!KS`FDXZi^{L8Z&HOc!0)Lz}wAB`Z#N6y6c$*RfZID2#T5%Z54DX>ar zD4*a}$=+hJQ8m1GQM&o;>DpZVC_~bKG3>9dZdQJ(KIvK7`D5*`W@Wqm)z$R#a_@;! z(Nl3iSTeJ}df@xg8<6@8;x^+Qgxc+^P6TKBKDzK_Uv&lDi8bk@7yUGUQzVar?N@@N zwpSBWXIa?U_^tCPKhN(S4ZnEunyiu zAFkxBs_89#^wTKG8~c{iT58`?s+&>JMv$uV4@E6gq8)|-pBisXrdOA6Z)m+QS!E2l zF1MSiAzQmxVpHOxpno`^q^@FNudxvHmbC5Y{_0QnC8uC)SAk_Pw#%>dw`LhSgg7!8 zNr0Vuz}|(%Qa37d!Po5OUH_i(AU8dpYy?MWHE1tBT6a5wR(H;{%BSdDdY)()`J`4@ z_I>AcY~=!RF#k@SbFgnObt03FTui#HyCzy;`%1)G+w1af47wv&sV%V8kQPO_`^%e` zbjknbCVcsAd~LN#nO=g3IWv8g#@0E!Qs{LGxvgzpUb2_PbP_L*+RHq>u)DcEt)=D) z?Gx?5mJVmkB9Cv~*!dzXe$%M#3z&PUZgOvMwkE*GDC!-l<{rRhC8X&@I}cU+wu2LWk&6HYF-$k-H+vo@s=$u#G30GXL1V zaDq>A(Q?PrW{Nc1%?9&lSs>Q&t`8eZ2RL+z{Wuyj6J3oRt=8EK3sQK~YN@^Kr56x6 zoT{!*_mW)NK2c&fGS#V!SCaTpvHO%_nbq7CUSOQbmSQF64jwUNMsmbeAGuohZc)`C z9I%`}619$jqiB0k z>#MNK-wu*Lwq#Uc#Nz8zGu^QV_6}xl?6hU#_&To=GOfR!b$}#7uBnr$087H&eKrI= zX%o=<2S{BV78#v|lpXvMZkM`TsFHf(`-fHtnT=3fC8E+DCt;`wMMb94C|vzZ z6cGjCxYqkSHH0Id68dA<_#vCXO;gHDWv?%8Dg)JuLUum68?!1)+#dW4B+Q**TU6PF zp?a!Jfl|{H>%1aBIB7^e%mERJN=LQbrQJO&U4yYz-iP-)c`rYfhimjuC@epwRVP#p zO?*MW{75X~UO0d{Z1m>686fol@&!^zlf&R$gxP%LRn*TB+$SJ8`F_PS zfos9r7y|mc1eNirPX&ML)d`7y%#!E1`|8HOi-BNk3h&6UE}vq}aHa*gfTYl=D6Q!s zJX$?7D!_w&izhz{xUsL{5>I}>yCZAO8v$86o7ZNp0WrVU4f3&VBEygGy>kIo9P7 zLGOkw5*v(RR+4IUF+aA2KZ!+$HwCK=i7D?|b53+_e8!2+WU8b%?KVDT2mAjE|WA}r#`1B62N5QWQwMiBNovkq6YVs?ay+CNHTvZ~Qh#{#P= zJWfRqPm@7dnp)vqeV5tDBX5;eoW5YHIcEa{Fm#7X}8&bty40SmIn{_c+#i zRiLCnB%&@L&Gq`hpj30ljLt%@56|i`jZ>TWW{p;Ew^=vo=h#`dxcr)}O*7JQgKIw+pW1n>kKj)Tw zZas3a0;c{<6?#ft9hOZU&tT%Y7Y2s4fR_dWjeUB$g0}1~p zT!yZ|2P)811(vB=W0$&8&n;$s6xIp2=f4ouTTK?+SFH9?N?eYm@5|@qy7Yd_mfmw5 z=S%05@+YY1TPnJjih6o#rl&P}+FnnEBBp*fUT>kW_ucDm%A3Nk1TS$tCcA`iU0I&* zQNbG>=8S{y8gt5-g=-33cAS>i=BAxjW9>3Qy^=NUEIad`+XA8lM_9M$%3b(jqMoqy{9 zjx6yg|5l}Ylz*$tly8=QOHM5vLDOB9`1R69#i^HZYJHA|l#NE6ubBq2uHIbL5_i_d z;b#_C^=v7>h_g>SKJ{R(OJl&8($3`{;LmVVh5T8|H@ScF0VdZv?}>cp&loP8$N3SR^Oo@fyxie_cX37E7RXp+Cr);?r?iXXY~`m!`{GQr?y|wzA#` z@BHo}!Fkfk#67ts^!2$dfPk05IeRI`(fz3HPvj31QE#eeP%_`#<{@r^$kT%Iogv~V z$$)W`288Rhf-Sjkl*`GV%%Av3oxf!TV_l!^2dYrIBZFh`7*_7^aCpeRy*!*noJ4*a z16D4Up7O6;^#T4L*Q3iedwyO0ztMZ5i}U}4CA0iLFFGBVJO$)tTuc8s|4$dFGyhK( zo_4PO6>u~*Rhm;oq&WHPB$@5S-H*!x1iOJB@)_c{e2e(4^LEU^Z+S)LeEsN!0e%mI z(2P;S4@B$uckw5}k2^N+O0dA7{FR_*i)!O%4D5xKq;bR~BL7(D(?4VUJOC_Cn&U(J zyy7!*288;O`w5?!|LoGkjeo<#Qo?T`wK)I3Aiz)Fjv2Rg13!cs32oG8ga%OPo65V` z2GA8p*#P=}unnMHcE}n)Rf1HN{~5L!L+mCD1AJ4Aw>n<`_80@zHAfFg1#)wAx}m25 zWDfHyGzx+hab-0UZGz2eMH4rXSgf;>)mOLU>@PbJ-h&Rkfrj3;MO{i?uef+KmVQ;E zR|=+#1*#)TIk+#?QDF4)`5udBzQT+Fws2^t7j*?$XoF zJb4w!-I%7V8R|2`cH;j~{?Flmwtuts{zEejxztOX+R-iLqSQ1=p7ZP6A@hlI7%1$b z^fnxmZctR!nd3=?(ExnvRmht#veB|HT0m&{5ZC%P$Q5V4tt@q`V0+XMf z#E-edcBK}B?jNK}fg~1FQDzlZ9)6S#OS}<*03=!}N8TZLHm$`mk)3h6g!XE`eADOWeRBzehrc&-V$qh62b7q zUj%J3Y^9^kBhBOV+FqB*m2+d;2N1ig#mTXD;BK$zg$W^wR`rG-1no+R4D^|*ZdN_`UGxTr?4;Ne|lI{^d zy2Q%tWrlI^E6s)bzCe3l@m|cd!7+N$_yPHC;z@OZ|E1-zb%T}T3?ADRr*T%I&TGyF+%jLkK^8T zg--Jw5W5S5q+-y}6KVz&S6#+|t5fo74wA7{bBZdpnrEg@tU{%F4sBc0&0=8_)@$qH z^kuDU5busxK$glD2M~)@w%L_Cd1uTG6jGf&cE&GuAUS-C${R{XuzXCcJ_Qt0%N0D> zk5#Wk-o%xcbAx=_tHx9$$s6yxM`uOcjUj+KHf;>FeIohT7(<1nC#*<;b|8rfAGTrhZV zQc=earT6fNZS>9*J0$`W6#hp{x;Jd3TL;mH)5t!S9LP!1<(8!SkBBD{RziL^RU8yn zTx`i;hvsm8%kRXEbnFN`a?t$rolYb2xp_o!y+koNn>uV5x1@wQh3`4YajGs0TBwJm zX!yIs7MdwH_f;#2&NRx)UiQ+~y~ONg552I*+8^h4L23btF5Q15zG_n| zBS#-XuH6LtBjpNZLhPjq>E@T;7xLc4AIxU|kzfE~lJ9$Fg*<94g2bcxFcRH1|6Xaz z)!w%k)2DPtk&;srOtKS?yCHcGWrW<4pv>Wvi6_RIz^?NS5o|#$1xso4bjO>hpfNl} zvw_ZpD#Cg45Sp$GwZkwgY`Vpb=9{1#0r*xc-*otsgn1Fhf8sjF{>)tOA>*Bol7 z*DFqQqP!^8IQTuj0kTBwebOz+L+?Cu{p8V*Jv0j+T7(Znc#t=zniW(L&rFt*5e#-I zLBDwu^=hn|O+&c2?QM>W@#F-QC+wR_y0Py;8zG9J-0|hVN&+@|145*mC{H%%Hh`Tb zfpI;wcBbS>tkF5sI^IiRg(+4cTWQWy(JuKN%C|yLCg{#sm;AQ&GRD2c?WIyLG<^|} zoJqR8heodEn_=Xslal;G(FQq3()ow!kc!#V51T-=`z6cnWjCvV17mF+H5_0{8aOVOl_ zwRQGE-)ga^(o7*hw>9)4%ivyRrtLF$p^{*j)}0Z^&AWlz=(~cp4|6HyHKKZm1hq(du*eF|2RoOFrEyoddMUhcA&vF>HKy^Pcg2H~=2 z!w$KlRGiXY^|j==DgJtdTwQYmDMIRTl%@Bl5UEk!B|Zx*5CMv^nCsw@pVi)DU{_pu zBnUhgRD4erTZa|rks4C7!OpFE1Hr>|%c$B6IU8V1U9Yhsjwkk}CNGQZWheLYh`ns9 z7us$Fpn}x=q%@pSWD{9^atn1ew;>Orq(}(ej&r~ojTP`RQVgL?*I!CW+QZz|OyDgEORlfY&7%b} zH9^w^GSWb%SvtQiCr6ytRQs@LJ!XUT-7cL%HpM=ZDZ#$q=&`k%q!LD8%DQ!+2gs;XMDek*1jp-Q@jqT0q)x0a5oys&Jf@?AQ;G*8fZ$GB(Dp zw*F@kCKTB{iFDa{RB+Zr8buUz+hrH1+isw&_D@jY{eNa8G6I)+O^&vH)2>_g1%PdV zp6R$BAkaE)fUthuSJMLKkWOdvwDyao6QMM#|opZoeiJj@#C9=2D z`Nwd8-}Txll%m(pCf$1N=+05Eo#M*w5tV(w%Ca7_Ru{#^TptlATZML^g6HF8*lc+>qs%M>d6p7YpV~qAt$sTAJN2BesCjur6GfcBP zEk?<#PCGX&S#Bk>jMfiek2ComdfcF4ugWTmCvLN%FSzldGYi~BJb8=@+E&PG?*@VW zQHXE-EVdWcdKUn~;wB7M-So-$j=tY2o~$%T%TeOZh>}y3E^EM90(NE9rL4MaXrSZG z*OeH>CXmFGpbb2+a-m7RjkmX%W-(gAUzK2iC%mLXJ)TgQVl){v)RFo~O=zH>bgUj0 zBGNO1;U;6`3ug*tElI=+Ib(8UY62v!L4*< zYPma%_`QP@Pdsh_Ucm8t(Ru2?2k-;pM;~M_ces~Qdl{t{#_l6jbt{;j#{^vwPh3Z) zCe9nJ&_?eM5uVOlxcVsJiHc-|CNB*NrQnZ0fEP(+$8`f}Us9>Cp~LYzO1}-DNRB0* zyo{W{;6@?TZ&}LXB(S~X$&qCGL-`{K?9%E!Kr(`yX2x4>K#6|=P}#!CuML*mIDp!Q z;{Xm4j_qw21-_i08X7AhMxEc33Bx=05hpUquH-H#9G~dUpnXRs8N7L#l8(l|1ZTbO z7b8O5lsuPI?`BKND5&I_O1+9y|75GR*1O2yNKqu;v82`B=~gRL7|-{|ci#ggF-H%F z^DtQt9i$c-KB@)4yks?FMrtiSvL!f5b(FU)OmcP2bY4X#e>}$xF(Iftl*%w_UQk12 zEBG$)a_kENH?ANH1DC# z1iV|yT^ItoO1X%-lw9I{7Tzk#<0`pdy0m-sTn+3RUi?QmyeFY)_q@`g?T;(XbGX)P z57yFUm+-D$bv|pR@KxB->d7B8%|YI-%NQjvDmBdwwr8bWG%eWfL!XCL3Jb>8yr#_m zk*j?c2=#PqyrVmrjOa!kpe#oj-6+eid3Sak^NZ<~z?<{3nn+?D4G9!b=*_`Lq6_>j z@aMeEz^(1i`H|xIb4HZl&+&kv&NjCQU++d?SQoKO-uMQC&U=FbIuMXZNSBDGa750W zc%obfZ8O>;p16txclL7bLjh{~WQDnLx5lutlc_f28Owf&52v;R$3KT5FYc$n%XM+G zIoQaix{M^cb=BE)YhnSs;$@k=a7RfmbL<5dsg1Wi|K@a2Ah&^NbM#&6#+eBZQdF7= zmo-(i3F#ddQuYdmhD^8ORQT5G6efRW$)c z5-Z@^qA-$@h(g8Dh{A_dk3=CH{>di{);hT3K$&1LA9>GOYcS`&01J7+%-TtOz(8jp z(&IDDLNZJ0qae|lU4HZ?pUFSn8*|vZ%w4j+iZx{gwyL`OPFiyo| zRkn&#I0-vEip9uDJUI$WQbRBTs{~KcCM>NeRpgw98nj?srcCD?eC^srM7n`B3f@sRd=3JMY=aRujoQmKaMQ&|u4stcLdd>#4tCDk@Y+$u>+%w;( zYtn9V%DOJOjO1EQk(aDwtoNCcaI9rcekG@#D5+h+@dzC~$T|pZ%DO2kkNVbmURy@z(k1v|ZrKZ!#hrR(;4~fDTo7}cITkG|MJZDc$Er_(%p=3&H9btt`Yu#~wfchzc zMVRi`kY$SWQA)~;b^c!mX?Vfv|g0MSyf6{4jM0|xz>oK0G0rjkNx zLypvjNPk+EX)swiopcw>kYa%O8J%=*CQ-(YTLU6QDv4TxGf*14@)jd_)v%CYmc1f) z5a~wnW7ZnW8Mn)FNXYD7O1FgpYpOET(ZCky;T~0+Qn;FuP`IWi6rN1=NDs4gl+u^g z6lvaWf*)y0qqj_RNEW?r9_g=w7(~JGws`Vc?qU0n@WR?vLS>aX-P_B&iwQ|TIL2P38tp;4&mNkE57M83ndi5#?pW<@D+FrIamn3u@PDm{ zl*hr=D?5{hOqSY3u@oY^kh7+;T~7NMIGO)FYA&Mk$|1`a5N7a%6KS{MR4|CgRP1y zx;bTo`jPX)x^7_Db!YJas(nC}dAv1me!cE0_btHY08C3fjS;thbTG}^PRH(U=uecF zH=XZY5pXd%kAce2A5FRq{R$g+(a`S$TlV1Zp%!fLOJHsAe`7c}%UtYsgMXk3W|SR=j!tnYCP6q0k`n`5s|;7f zpyT?4n-lV+>6sHcEmjlEp08+j2~J};t9Dxh7Q0an)pY)XAt8g_rz8S3T-HGB^gH$tiXO0uw~O(xc-9qpip{p*O8m@=pI3<%75WVc+?IE;?b9+nS$i}h}(+Z z!(cNFd@9&7Qkq0AoYZ+VGA;uf!5_4_Rc=B>B?gu$P*I&`(l6#IO zI3?H|-2(A9DP6?B!MjZWA=SHtJpYU3XahbYAKHZPFUt44epAZ766mV@myUq)gMlK- zk3Xt5<*f`pl)p??mJ8}MrDuczc8GdpqPsGpeUKHSjG*th?BEEB0S1CzSGovVDzKW- zLV}9!4!UuiJ)76sJ6}Mt1!rNVwO_Qe!{LOPkJ*RRn#Wctxr> z-SJ7Zc{owLIbHx7tt?m3V%C+7=BrjJwm?6kf3oRsW{G3&3}*>8Q8Y^|4rhseCQJGE z0YtMz*TXbR=-Ob;EHOZ+Z4D5=CFMoRJ9-&m{n&hGkSa>Mi-Sjk6z)sJv)J&m8;^IR zG)hwW6Zz2=P;%xQVnM}7?+N^oVDmNR#sZuAF9JOpuV@GHc>;h+oP4NoQY><=(s2T- zlG@%C)D(@03rYgZL2gN#X5EGs%ZaJIB-#=^{ zSX22O?0bMdDB!Z2w;N1wy~Q2+CF1E<&K3|G0sbYx4P;S((&nrxe|rvivsHS$W((pV zT;jNXP{)w#1TY4+x6QcC_Z5MY!6%~0KUorzZnYHSMM1$(I-huLkQOHu2MfHjX~v<3 zkcvC_F{wD;QQ+Nudnl}w6&bMt6N-4U$Ns`Je;o%G1a`&&`a87)D(yU?!DrH-_RsB6{P zVaH1jl)E|RTCGTuBH8L40yM#+uASB~AS10xD5!Q6-BKc9j>JO}OA;+p~6n*VeW&vwdqE84>;)eWlEPQ>Lf{sIh zfPEJV*ycH8FpNDfh8F_`(USisnbMUFeK!zLA(Ei{uqUJDw=^Pt6h=~)Bh$Oejhbo zIQ|?Obuud~jDbHl9k2%Rd&IJ<0Hc41_`eeKj24KxHWGqO`*=t=7JiWy@O4BLWX?B& zBvLs9`JdDk){;ZkMJjk%h;@X*?=Oe`KZTT?jtyEJLaR0V()`c}Pv!W%4821#=nW6i z+dNaZpk054uVSbFrkW`nKO(2`oMH33&Herv93{@7z4GTtGBi4Yr5=LW;%DfICJ7^~ zz9a1Vu!&F${BGo6%J`!=3=8*CzoZf0Ms;@ASB2FE1~l4@RHJ$@DO>1KQD-?TZsr82$&!u=gttXW?@tR{y^~mj@9H^!P}-*9{Al`@vB^SOa`)(Gc|>V zGG@ql^~YhwV7raIP*b01JGd{bf$bcZ3UF?Q(!+L_GQ4D**YT3d7(&%2WU82vGqH-9C}x zi`XCablCTWV?z5tf@0+5$dIki;>l@T3i2oO2a@l(K*Z(OaFRhNR_+&~7*7@muQKr3 zEOCi1aCBJ{!pGklH<_%!tzm{;d;|7T2HUao!qFi+ho~uMy8eV@!Oji*7(4eBJ3kpk zi-qG~H6}>H@WnfJO80^5kpZsnw8`N5rEq(R8?k=nO87Wx^a3UIqn2DeA(1IdGyr&KavkseU8;*}CMjaa`%qwOq;TFO8keji2cPq5Wm^Y1vDMt^rd*Y)?(eKLe}(Xe?ewFMR= zK4NVXiJw1|Lklpd5Zp7wpku-z;g9BA4F#T|SDZ6JO33Oj>V!;c5I%GYAH+6mN{sY7Lb;O^P6-I<`XR%A<3Pe0Xlj?+fBp~wFC4#h2r{Q> z!$H03&p;*PFsej_hYq8A5g8|zkDMKeWq16fh-D9cOf1iRi9XqNWY{MG0o&4=N!toH zGn4~B{-TDhGQD|#YOcIK5X+~nU~F$3=T0ogwhzQo2$!V3^rvW@QaFCQ%@Xq4WYAx* zy#_<`DpS?@ul~u&+<=xDEJrQ^%PwG<(?KD9iFK?RjETb1Zv={=1JOGOrZ}g$29|N- zNq|AZj*#GFQtS!^(!fL=9x2AnPk#QygR@}-K>aTzKW57$oFwfTaw`H{1Tt#sXWb9} zhP^if-aGiZpttZCf_H2J3xC&JJGaJ<+LmnJTyp8=mzc=7Iq_6D;Y^Hk&x!5IjAhqJ! zUPjkx!b-VkQb9M38Vi}6H(N>)alx{&v1lY zXy6=SuL)caf!i!gQpV|6c~{}1S>%(pS)rZ2s)QluQ-sPF=I}F10slIA-=98kYC4dN zi-GI!$j#79Dr!%|&;U!-()y*8s>RD+V+;AGH-k~B2~yKQyAEg(^nU}aI)3ENl9ypF z1ldC-F8z@fCn<;vI}DMyto6=B#P}Yrf1MMT2SLPX5OHI3O!Z$eh1y)_c*C)dDQfm z+gPY@Lt&`VHY{r-JDU9ADR6zB%A=x6HtUpF^< zU@J6DXb;>%*E)M(!l@$K#OGS{J@!B)KV}b-D)Y|;fb4-E zcN4FjnRp_wqvJ|y-8*m%z&EnoZJV1Jpfy568f=^)L1&dfsjKqCuPC@ z$3kFN0DE&-SwB8>SlG~RH01iREfu!JDgTY#*au9X+01tD=e5&dK95^0Ix-UM85GQ9 ztOT0|6Okcp8r%jVIRyL!0W}A~qPjgoDG+H{a_=`~2Qa5jeTx1z`S9O1>%V#1exlaR zkk8Rsu3P7qDb>1l21{DH^*Mg5Tjz;^hYSxH$gwkZYhw^Gt+12R3RMCC>s#%b>DC)n z^ZQ|Fg~f0K6LWo*NOhxaj(stXj?T1woR-t6=Dqc!Lrmp@FdYbv2|?RChHZc4+HMR0 ziPV%o+ND!N>j>2xuD0h$oKkicDF;eZp!h8eLi3$XDdsQi>l?DM z?+*#v`wQ)vlu92kLTLC>YWp8SGJVtx3f&YbtTP3}Q?nTdf&UC+KGSH(uEO!V0wStt z4>?-NA4^L}KkA-4c;|z@K3xzD1KUIkf@!+_vs;m(($reNkb>aX0pKl{j z)aI`|$>Ds3)pII%oa!BGElSLDsWmaLJV=!_-F>r{>PyUHR4|qoQOBQwT?4f{xWP0u zXl2JN?9Nmx-W6M-tDzI{U80uKv=oV-Yw~7l`=5!g*<(7uw*+FN^7fD`uCFQ$HYLSUvIIT&0*0N3_e(+BO?Oo^1F$Oq=I@42&!H8hUPo#+4$ts$z)S(IW!8_6 zIuA1&S)I?4+;#pPbjhMLsV80RKT+2dT#mfN&B3{{!a)7$Lo%&VTWE2jfo>jCgWawSMU4TK9hh zWJzk+7)SM8z@vd0j?4Iuv&Q1N7Zbb_GkMc~&Eg~K_;9X|EWd%E9!WzWu>RpJRcLPr z?L{>=5oXKD3#n13d^AxAu(qbK~!chr=aU*{B=nteC`vcYSO zOgWi2sCOh2m-jcB7{ZUq#FH3|#it^4#W^Nz`QIL=iW|Hecc>*6 zC8-+jh{^8k3yhkwP@5EvuLgwcH4~Al`i5dZQ`Y$p1n`cC;Kh?|17z~Hh|Jrz=8hG# z6G76TPc#==-!p{fmZQ#|a%=KuOg+1yu_q$u7Hs>|WH2;Z7#rH{X>8zZ?~r-me+Lj8 z4<;aG^xSrZ0S|U{)5MoLt-;W^fv<~)j*}j$d8XQao1x4%NZo=hpJZ01TU@ZcahY4N z{gHBR9IDOGjYU8Iav}TqZ5+th12X)AFU|Qe(UeAh>wuE#ybL8*%!QJ%Tr1ri4{YLE zw13F4P`;6 z|Gbg{g*KpIUa)xbdPclo&Y$0@Z3DA;?MTD>XBysK4gau1sD*BFV`W1RQs0Qy$#=Wd z&f>mYFjzC^YElU7#!>K{o7l{Uw;iKYo3DN_zhuWB^`nc$*T|b$|6-f3>M$EPU843( zG3^5i%r*T4fI<09BbopDP(d_b^%Q`)gBhD2J9DL84wOy$Dm;W7emOJQfR2|$(=YxP zjYEn>Tf}sD(*+{!Jx4AqMF7I_*&-Mq$!NyV90C%p?T3qRY1?t|?=r%gA7WZNf7sEE zzNQg<@#LT7CHnNDEpetHsKVM^wFoyYS=B7dv3Mu-{LdJEPRb{`o+?sL-LCx}n+0^k z7ShfSNh=DF|AnJ_E3;u_gb7fn)`+ohT=_+FXUMiKisYY#@t`%P*78iXJB8mKiE#@5 z@M1B*Wa~&4%y`PX@nfU>NgL%Mg5KR1hH5V${6c`6lr2JXkg|0}t`|mcmrwI}HZD#C=z z&V66+u⪙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ೠ>@z{4rRi@^{poZyEDL4`dNc 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⪻&YJYD&9DQ#xW)E=OU!YXYhB;su+%+=xWKqxY? zpc<-T`_2KCchF3s{CmO-gWOo?7KX%y0I9=8s>-HHFo{-s)r1G;MRu0yQ39Ez)aX3m z_fYnZi{n!a***!vH)i(G9@`MLB0qyTda#PEBeqAs6u zLkmBHNZf_^kGjvw;PW5u^S0pg z7CyZ{b`}(H<^w1g4FxVIG+KG74G6RiBA5|Vl5_2X4b!G*Qc1@;lVY~Nv)0UoaDV52 zHXrs))t2VN&I}+-=#)cx@w*@CCwD&Vrg?-^wf*ur{p4N37v@lENRByFyA$TnD%n(3 zvCA0RknGQn%!lbBNAKe?MlOop<71-2`LLyp#o^1C537WAbN01{^I?UReN&xTyFQ!^ zo@|f`=flE||^>nm+5N^0N~ddpOQ7&!`N_QAB) zIXi{?LK}uO75=S=-h%W~0A4V21mXU@h`xfEU+Z(S7eJ?iIQ2JX(EdrYEG;C#SV3Qs!gDL#tT`C=}Ba# zH-7s7bvrvG`C7P<0X5X)-bA(8*8fBkhY8NY@wHT}sVn!w)Rnz>M}`HmWHVb(z#N4z z3inC@{aX~0uF+_4BeY2WTW|m7&6@>AybWy)s=z8O+m|uV>F*KboSSbx;+&fcslj`c zq}H>Y1uL5+(2eZG89-qWu51U>Rk$1`aYHyYOH&^%)Dz-=Pk>iRF*G4GNaLlHEe;&a zFX1xZ^|=C^@i~D{J9+{My+9*h^P?U03h60h{7gyXW?AjdGdY>n+s5=WZ-!O{ zX>*1waaq3qR|xf4xmhmCWO>1|sE7Mv6ySX&lVzXWEQe&W{AyWbSo&9!#p_0lb?z5v z6$M3Ha&l0 zsB`Wuv5H|}J8$H)UjeJ$;S&eA!zbKUo9&Pux#tb+#gLu@C`NGrMeXSA{q3Y|?8uSx zNm!DyXx7S%r$aa3SGu`@_Xgxtk4cSJI0MDr08z6;t~;_fd~+guCl{7sYJFIe8rD=o zX2P5@ue9eMW#7;XQ>{u;m$O%NVOe9{79O8d?)Ij0|6qkI#$em}O7Bpi8ZQy(4x9_o zxZ4>olQVz9Dy}h%Y>WCq){eb{1_ayoZ{ZaSFd6x`yf9UHzw=X)>JV((Z`^@>`z*9A zPM+1lcJ7}+HFb9Guk?Nw`H_EjK}9W}DNbr-uB~E?E%`yEbx;4>5U^BuPem&E0@SJA z?E!nlZR!_PRYgkVkh3lPgW1B5^YB04!(S_8=&sA_27wtMnHpl}$^l?S2xMh#^61d>mn3Xb16Z>< z0$)&RMNyK$)KL5nc41^uvIu_3-pF{W%Bp+0;L!xt8*X&9AiTCd;JHgW79Zf?cDUfT2gCHNcPSL(m;H!i_jvCm9b=J+0{OR3Bhbbg zvZnvkV#}($a||A{rWc@Mg2M-1Vb2nDu3Ug-MN=*CKOl96zNzkq{wD7Fsw8#Yfa0F( z$__MN&_^U@`CapJK*zJTwt~hrXv~o~Dg-0=_4}L-jEK{!V&~7ZCeFkNNh?qFY_+rM zYM8jHe0;Fz4Y%Yv@0w8#n(sgqwpi=c{Pc=FJYN>JZg(^1f~&4&SsupsP(>wnvU*o| zl`UOY5aTKgH8f2+mu(3uFyvY$kX-1qE>wK0wB}RberXq4sZb3PwGxg#mEH62?5L+f zlsa|#a0pq`G~I_E4n&~6ljl-gRo=hQ;nj21)Q7IZurb~5PRn(J6DV5*T04U*;o9)I{BiWg_Fu_Y_f>dWs8s< zwch-Doa~5LqPZj*IH`OIEi0HUuJ@0np8Dql2In~x(d9o-S7AhrF%X{Tu#Z_;k(YxQ z69yyDjO+tP7~~!x6`tkLmu{yqQ#JNn`$T>&v97HhgF0HmfUQ7>;cvuS0 zYQ~Gr8dIW)(}_f(xMLm|Vt!lXj(K3&^P(b-s4{;AM>I^L^Brt`)sASmheC8j19lyS zu)l=m_w%Av+D*c``|n&gW5sgLF%9$BZZL{t8o1^qhp}Ri3v4`(O@J8q{ab#_0r@LM zV68kvxCx?4RUs#0DzZOyyQ383Y6EAQ$ta(LZ;)w>!tflWDvq1t428@YN()%u%)qKX z|F=;2_$cD8e2jL^06~-0dJhv-oa&3uyKnpG*aH-wDg;;BHlYRjodaKYU(_F0PMZU( z5G;jTQwNjZe;p=3qSW>mcR6IOCCJ}jB2E}P)r42!c(At2|9~hAm5%80a1+2MP*plV z6wUMUV>(LYgQMaEtsy*2=x@R%Cz_9uu~)vA9IX)*`E z+z75Yxgb~!!|psuFijo=hZWon40dtz@G1Tsxd@KQ2E*z zgP1Q#{^)f9uEZSSD4KXVi$!1(wjQMS`0tX%=vZ^_j2ZN3Y;Z*4bkQQ~k=5=@@22&f z<*xhMb698t-gepOxfignu&_G2b3c-ApHu7T_lWErF()|Gz=Zay5t3JHeWvvq%($5P zy`8D1X5oxW^d8l_F8sY}j@qoXAlJX7GTL6j5BeK5|7sI*Ug{vXvGG*@Xld(SktfI$ zjca?0jI|vC8pRn0gSfg!8_XjIsaSWzMX_2(zMMqDfj?9NZa8&7Upw01quBz*me}-m zQ>JDzdApHDIUGlZXGwfct-@#hGYul+(aWjGF@PBQ_TuBwb>18@cz?(UraqP*)z%y^ zW45&p_8ctN0kJIJSdoLUukkB`Z5GQ5A7l1*RpGM{B{#OzDjx)(>^3tbgKSk-#ByDSRf6;>EC&@Kl zYf>k_>XZB)HY?lF4VYU)^@8Nb#Qs8OQS5SPRi=aYYRieNEl7Sw;Sal6#{&F7aH^H}`;>|0jU~%W3cq*TJm3OBjc0tgqcReI3|IR}_DaYe5U4Y>i z2U^*J^?LR_78}`3v2F^eyinF*U6T~ClW#RjR*!qaxHItoQ6aEH)^tHgW`8Gvt79cy z6Pvmw`e&&<2P&0XPFu<7|A>vyptj?)6kpqMnmwPl=Zp4y*`CwwS#8gm_DtJzjy+$u z=RAA9Y0m}reA}M?vgdpD{J@?I?fJ1iKegu~doH%;m-hV1p3CgH+@9asbA>%Udwy@v zAME*~J%6(2zwP;pJ=fZEy*)SBbE7@~v}Xg*UfXdidp5S`*7j^_&u#44!k*jOv!y*- z+p~>5x3_0Id+ubgWY2x=+1Z}^+q0`Z53*-BdmduX9`-!U zo`>7>2z&On=TY|TW6xvkS!B=S>{(*ZzV_^A&y(zViak%Y=Ky=2Vb8PddA2^an)!|Zv9JukKA2zy>(&oX;nWzUiJyw;xA+jF!%E9`lbJ>&Mg*`Ag5yw#q! z*>kKt$J_G`drq+DKkPZlp7+>uvOVv&=M;NBWY0(J`ItSY+Ve?!K5fru?K#b!&)f4w zd%kSX>GrI)=S+L1?K#JuuiJB;J>TTnputc*eBCTPbSJ&(#>t_F>up!PouaokdZRP4 zR!(ns>aBs^{;9XM2-TrXhcxhi(A(E~TducX^|nZFOjtGW-_zSZdYh-WnBJ=OcB0;< z>1~AG9@Cq~Vg6*j-K{tIh=k{i?Szy|q9)`or|5#bW*-z4g$Wjt&~y zPj4l98>+XX^fpRw{~vqj0vK0Ow*Rwf3Z>ivatU(rP$*5I4ZE9rxus28T4_sYS_mNS zZjwzCnq;@Tn>GQI6;TTUu7KDNyhJWq5HKoe|A-J3u_)kzAOSA~RBQ!dLEsAr@_*l% z=RLP%)0DO!`h8hwW`6U|duGm@IdkURo>R@S8#q?Vv3ohjSAg4|50PIramN?L`aS zdOOFaaqLEpRd8$r#};$!Dvm`s#xsL9ez9ch1svnX*&65Aog8cB7~g{4`Z11e(*mAwvuBe$GSLn5XU~pvAsBUBgYCjb}z?1&CvH2Y12NB!O;aDTb5*%B`v8y>YpJTUkY!1g* zC1b0fW6yEy7>*fJD0Udf4&m7T9OIWyw@%^MB95_AMOzEUUgy|F9Qzx`uI1Pe$8P1= zZ#niL#~$X`vmE;=$Nt4JzCzq~0G()UAY7x5Yu)9$7(q($gxU}oyswu`L~5QMsHdf zZ9N>Lr(cb>D>+8b5EyOWj?s1*$L`|T?Hs#}V?X0qAIF~K*mWHHZ;oBTu><#_*d-jR;#d#I8aUR) zu~i&v;n*iRb`Hm`;aEM#Zs*uSjy=gS9_HF!<5-Ym2hmh;YYE3@bLT?&Q zkUntAkAD2r)6ZV?yOZ>Ci~$|y?$_b4lw&-6ZO>axS3G<}-;*f6whr}r58=hAA9xsSq;^%iXjdv(I@O3J+E=ynULwEz%hx%Uv^O1Z5S5PhuV{& z=2#-uooerj8p&u^i;-$e#MT+j9kFE82n9kZ^(PcGLcvf1eLwV&^8Bm#DggQJG{% zY+W>AHg%`W&KQ*uX>RVO;-Y3En(XdKpW+6rX@jYSERWLqbUBtt)si+^8|mndBHx0ZNGG|?nWNpf z?2}JE*}2m0l`1Lm&occpXPG6zidkmBucB3Ulv3C}(^`{2jla}iURD;YsjRLk3swiJ zEYmm(s*n=ZvMW@HD$1oh3aThCt*)*J`m4%o$}4L8Wjj`mE=HF<(>%)TpbmP18SRNQ zr?BD7WLvDeqs45Bnt=+x?hxF5f%2Nt8s{&t6KXQsu1RxuGCt0llvS421S_j5D}#ZG z%CgGfj#Y%}z#HCE6>FIR-T?mU^6K(HWkp$)zd~(n`MP+$Ku+lw3ZEI6ltu=DN zL4PUj;MIX(d09<$xxcD%yQ<6$G&`W`%v+f@iDOXp2TLo;f>mYJfy(moit1p+b}hP` zmZ!%I9UE;E&!Ua)IJTKI7f80ZM6GfvD@!Y#KlkxtTdii*K-FaQ@;hR&I8TC_BF(F< zV#}pBj~JhtV%=RWoIeq5PDQ#_(V(Gc9XolPidYBr?HZ{@cN=@Ga{8zi7&%(eI(8>! zx2K|=dZIyVAEyZn%@MgNcosHFyM)6fJxklWW|_U}Z_m<5562@tGsEGrCm^ovI*(gC zX%BYXWAp80YJQ^3+?7lHc3&Q``+66P9ZU9IF2VLLp=D8L=07SQTUAr-y8f}VXMi8T zCRCG0Z#$23=IGp#RTZOc$x)YX9kSGB$~#@myFFzJ98b_0K*_Y}t)~1x&77_dn66^2 z;yitl`v>(TZFcmdvWn6Qnva#2abHqDv$DLDCdgG4RVJ^d`k`m(IZ_=@GrMM_)Y%%3 zkLJ3z_U1N|>K9EUX%K3Ub(wq?q9Sz4(oLsM^X&=N!gktwT)C4pX-%z*M!VFxQerKg zl+Z*bq9(bco{!KO%i8E1b4hzL#S^OLSS&$9pqjE_ex-8Ae8Y5~k#LjpkLL|zE`&4W zSw_BLsRLCChZj4VBOEqkP3Ke7Bxjk?2(^_avn{fghpTWno(hL&QJ4yZ!)no7KW+p{ z3X(US80txDQXQTm?Oig=xmsPFCeAWb?VVARH$rKb0M#j(5vZ_J{yYYuOaE zd;Lz_DFUTc)n$Ql+6`(dD*Tl^C83?7y2f8#Q4ypgNwC_vQ;fAgq}IjMzAJrBt{=Hi zs*|)jQQ8~oMvnV>FHj@P=$$_qBwyIii(ZkLe*E{*xrKg+6X zxcin@(1;ie200$AuAz8EK&6*g(E*^c$}#bf?iaCpr2E2@vwu_R5gLkJRdU*0V{};+ zO<>BatAjNa!EzdpYq;z{S!q=noiWmdpg>hsS)jr$mTTfVG?dcSPS^aTH09WDXr@+9 zoxCOxpc7|01uZYHq=T2gw4&T!9iR(Mm9!U>2g~dpzpegmU)xse=jrOvRpS}<pGLrix|yK&MWE{>SHv+iWo!wRm)M zj|u;iGe)(K8H-!^`bDbOSlk(pB~tnVwQ~a-bSuX=!#JbNSZ*v2(*GffHpDvkj0ty{ zqIB7ZPrNXVRK}!vY~&uw$XWm&NRqrU)ERjR9YpB= z*)$z;T=hA3b{Su@nXRte1WP@~G>11`0#zAn_-}c&iU$eoK6>u#U@0A918kx{?xUk~ zNqmArhp5?lQB|dte6}?^SY2A>I0~wz1p;L?G(XzrB2|Xj<)yToN?Hmnt*n&hd5*dT z*d~ASS1mwIK>76Qsrr$R-ybZitOx{xWsU{X0ahJl)t|fzw6;ZQX{j2+)iPB}>gMFN zub~5UMOh$N5uNR~FCeqWO!FioU9M=0c8z~AU1pd6794kt zunp8o=egyruJ_>>pDaqe6<_OH$Sv%cb=w!M$9dJ0$Fv=;%GfobF@Sb$ zeXd&;DCLULP=bq<6tlNNiMoENjg>rnNzUpjdl71i;k;D7Q&xd%#e2W2Hq^lST30EJ zDOEHU*OUgTDgssNl&7?+rrKXl+kxuluU0EmRa#zE9-y?Kd##-5d=ZTrp}Lxm8#MvG z*Q6H5s~ccfM_LUvT(Cl&Wx1;5OsB=wRFnq&JgVCjso|T7m6YbFuxd9tldqyX^U>LK zf~4DhTjN`dE|F5lSC5kDBcvKScG)0zY$|CFaWtxoHO8s^YmA}6H3DqMuz;1zHwVbK zzsyao80Y?{4sxz-DqZb^+*!7>{=5>N-FL^jG-utl@~-Gs)~4L!8HY=kZ=&C)%DP{D>z(^djuXrR>A9 zdIrSxI7j}x<2&xNzrFnJKI|*^|E#0FYBA42-)Z7vN`KMO6%-Ux%uZyJFQ^VKx*2c7RlRcw0WAHjqUDr)+sbjc`Vy%Xj&$Z zl#X&o+l+QDPcI@r-H9B>qmNapqDsav+I$LlYBueZ=%226J+4RI|7u0gJQAv$lG{p-B%lNK) zc_}>rsLqTK9dT0SOs6Vy1M3RY+^?)c-KcV}pfjBu=q#$Ts*3I%Im_as=j^J|fWM-= z%yE*$BM=Y1N12U{jppJRopcG2CWiEXM+aRhpbM#(O|;U}sY(NE#n>i=t8M$zojhtB84@syr1nUJ$#f|>ULFajFZA~_DenX=n;~~$`J#V zl}J0WzA&UmHP=98tmuv74S6Ie&M6N+^?eNP)>gRZa zM_tjg-q0~i)X4_DoHEm(cZk~P&njAMvc0R#u{%*hZ&!1Btkil@iSp2$5~>JQsfPoq z5Y?=gqP=BClhG8Q|9j|Puc01_O%kg|Sc4Q&I{!~mvXV=)(Hx-v)xQwkC0P|EqU1o( zq8_4Nqd7=yL2t;X+K(DRlv6LpV$%UY-)*|Y~@EQ*w1Xb7QZUm740G2@n+iCw5@wn zZLuz+#c1&xEdlz!hyL{%EzyotME|8X;uO)Y(GpFxuce?p$%izfCDu$Y#-)rF^653A zMl?YG_s~CrApK9#AVs@WX5LAn@nm}km4cc+&|5_Atky>5ss9y|4dt|UD%-$@Ik=emvQtBh66Mmu$*c6Aq4y%yL-cT{Nq zzJQM0MtfJ1-U6}9b8ey#)zrxjqNw9mi|wvnI^>Pf(Y`urZ(rE}^tz&Y_pqIwZRaLx zF{lw%Q!B8G`V&xp`Q2arW5bes-7P?qCY7JxWDIrE?M+%gdUdgl{`59c9cZD{wfJ9s z%IKsQ0*x+%-;Qii@ADb-;HnX8Z4L0Bpg{+2^*-i&y1{D1{YE@s#Dhk>%!s!es&~@S zN=Nu1m}o-BlZHBq7;*ARkw=QU1O4fxKjfUE9zlPYXgR5JBTn3FB#Z<-L!3AxXy`#n z{S9cKG}?RT(#>i^-3X??DS8-~0^XoB+$E`mBo&Yh(*G2trI$=k&NPy=FY$Yx&8g+| zk0Nw?oh}&hKXRg{X7~@kcq(nnA(9$KdHzDifO5JAV7aI{9na@N@Z?t&O3tNw!{^c! z__FgTd!aO_uJ`TLmFv-+D%A^akEc>TLXIF%QP} zy)5b-$Wj?7v+85pVWfu$EhCj-+eg-xtDx+>1Hhf0)^fUQyLAAu>rg?@uvz|=UFzVs zwy0XZWgl6GeWlYn)&@ig9aNqyEpXn2_YU75Y;zgjJ1AaZNOL?G-x

-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%0AY5P<&N8>EFxr?|k~VG%}8|-?nVn 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 z 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�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 PcU*CvN?U!!ZVLVn%xa+t literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.py new file mode 100644 index 00000000..a1a707b0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/bezierTools.py @@ -0,0 +1,1490 @@ +# -*- coding: utf-8 -*- +"""fontTools.misc.bezierTools.py -- tools for working with Bezier path segments. +""" + +from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea +from fontTools.misc.transform import Identity +import math +from collections import namedtuple + +try: + import cython + + COMPILED = cython.compiled +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython + + COMPILED = False + + +Intersection = namedtuple("Intersection", ["pt", "t1", "t2"]) + + +__all__ = [ + "approximateCubicArcLength", + "approximateCubicArcLengthC", + "approximateQuadraticArcLength", + "approximateQuadraticArcLengthC", + "calcCubicArcLength", + "calcCubicArcLengthC", + "calcQuadraticArcLength", + "calcQuadraticArcLengthC", + "calcCubicBounds", + "calcQuadraticBounds", + "splitLine", + "splitQuadratic", + "splitCubic", + "splitQuadraticAtT", + "splitCubicAtT", + "splitCubicAtTC", + "splitCubicIntoTwoAtTC", + "solveQuadratic", + "solveCubic", + "quadraticPointAtT", + "cubicPointAtT", + "cubicPointAtTC", + "linePointAtT", + "segmentPointAtT", + "lineLineIntersections", + "curveLineIntersections", + "curveCurveIntersections", + "segmentSegmentIntersections", +] + + +def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): + """Calculates the arc length for a cubic Bezier segment. + + Whereas :func:`approximateCubicArcLength` approximates the length, this + function calculates it by "measuring", recursively dividing the curve + until the divided segments are shorter than ``tolerance``. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + tolerance: Controls the precision of the calcuation. + + Returns: + Arc length value. + """ + return calcCubicArcLengthC( + complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance + ) + + +def _split_cubic_into_two(p0, p1, p2, p3): + mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + deriv3 = (p3 + p2 - p1 - p0) * 0.125 + return ( + (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + ) + + +@cython.returns(cython.double) +@cython.locals( + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals(mult=cython.double, arch=cython.double, box=cython.double) +def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + arch = abs(p0 - p3) + box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + if arch * mult >= box: + return (arch + box) * 0.5 + else: + one, two = _split_cubic_into_two(p0, p1, p2, p3) + return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + mult, *two + ) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals( + tolerance=cython.double, + mult=cython.double, +) +def calcCubicArcLengthC(pt1, pt2, pt3, pt4, tolerance=0.005): + """Calculates the arc length for a cubic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + tolerance: Controls the precision of the calcuation. + + Returns: + Arc length value. + """ + mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math + return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) + + +epsilonDigits = 6 +epsilon = 1e-10 + + +@cython.cfunc +@cython.inline +@cython.returns(cython.double) +@cython.locals(v1=cython.complex, v2=cython.complex) +def _dot(v1, v2): + return (v1 * v2.conjugate()).real + + +@cython.cfunc +@cython.inline +@cython.returns(cython.double) +@cython.locals(x=cython.double) +def _intSecAtan(x): + # In : sympy.integrate(sp.sec(sp.atan(x))) + # Out: x*sqrt(x**2 + 1)/2 + asinh(x)/2 + return x * math.sqrt(x**2 + 1) / 2 + math.asinh(x) / 2 + + +def calcQuadraticArcLength(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as 2D tuple. + pt2: Handle point of the Bezier as 2D tuple. + pt3: End point of the Bezier as 2D tuple. + + Returns: + Arc length value. + + Example:: + + >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment + 0.0 + >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points + 80.0 + >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical + 80.0 + >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points + 107.70329614269008 + >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0)) + 154.02976155645263 + >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0)) + 120.21581243984076 + >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50)) + 102.53273816445825 + >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside + 66.66666666666667 + >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back + 40.0 + """ + return calcQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + d0=cython.complex, + d1=cython.complex, + d=cython.complex, + n=cython.complex, +) +@cython.locals( + scale=cython.double, + origDist=cython.double, + a=cython.double, + b=cython.double, + x0=cython.double, + x1=cython.double, + Len=cython.double, +) +def calcQuadraticArcLengthC(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as a complex number. + pt2: Handle point of the Bezier as a complex number. + pt3: End point of the Bezier as a complex number. + + Returns: + Arc length value. + """ + # Analytical solution to the length of a quadratic bezier. + # Documentation: https://github.com/fonttools/fonttools/issues/3055 + d0 = pt2 - pt1 + d1 = pt3 - pt2 + d = d1 - d0 + n = d * 1j + scale = abs(n) + if scale == 0.0: + return abs(pt3 - pt1) + origDist = _dot(n, d0) + if abs(origDist) < epsilon: + if _dot(d0, d1) >= 0: + return abs(pt3 - pt1) + a, b = abs(d0), abs(d1) + return (a * a + b * b) / (a + b) + x0 = _dot(d, d0) / origDist + x1 = _dot(d, d1) / origDist + Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + return Len + + +def approximateQuadraticArcLength(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Uses Gauss-Legendre quadrature for a branch-free approximation. + See :func:`calcQuadraticArcLength` for a slower but more accurate result. + + Args: + pt1: Start point of the Bezier as 2D tuple. + pt2: Handle point of the Bezier as 2D tuple. + pt3: End point of the Bezier as 2D tuple. + + Returns: + Approximate arc length value. + """ + return approximateQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, +) +@cython.locals( + v0=cython.double, + v1=cython.double, + v2=cython.double, +) +def approximateQuadraticArcLengthC(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Uses Gauss-Legendre quadrature for a branch-free approximation. + See :func:`calcQuadraticArcLength` for a slower but more accurate result. + + Args: + pt1: Start point of the Bezier as a complex number. + pt2: Handle point of the Bezier as a complex number. + pt3: End point of the Bezier as a complex number. + + Returns: + Approximate arc length value. + """ + # This, essentially, approximates the length-of-derivative function + # to be integrated with the best-matching fifth-degree polynomial + # approximation of it. + # + # https://en.wikipedia.org/wiki/Gaussian_quadrature#Gauss.E2.80.93Legendre_quadrature + + # abs(BezierCurveC[2].diff(t).subs({t:T})) for T in sorted(.5, .5±sqrt(3/5)/2), + # weighted 5/18, 8/18, 5/18 respectively. + v0 = abs( + -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + ) + v1 = abs(pt3 - pt1) * 0.4444444444444444 + v2 = abs( + -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 + ) + + return v0 + v1 + v2 + + +def calcQuadraticBounds(pt1, pt2, pt3): + """Calculates the bounding rectangle for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as a 2D tuple. + pt2: Handle point of the Bezier as a 2D tuple. + pt3: End point of the Bezier as a 2D tuple. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + + Example:: + + >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) + (0, 0, 100, 50.0) + >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) + (0.0, 0.0, 100, 100) + """ + (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + ax2 = ax * 2.0 + ay2 = ay * 2.0 + roots = [] + if ax2 != 0: + roots.append(-bx / ax2) + if ay2 != 0: + roots.append(-by / ay2) + points = [ + (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + for t in roots + if 0 <= t < 1 + ] + [pt1, pt3] + return calcBounds(points) + + +def approximateCubicArcLength(pt1, pt2, pt3, pt4): + """Approximates the arc length for a cubic Bezier segment. + + Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length. + See :func:`calcCubicArcLength` for a slower but more accurate result. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + + Returns: + Arc length value. + + Example:: + + >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0)) + 190.04332968932817 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100)) + 154.8852074945903 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150. + 149.99999999999991 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150. + 136.9267662156362 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp + 154.80848416537057 + """ + return approximateCubicArcLengthC( + complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) + ) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals( + v0=cython.double, + v1=cython.double, + v2=cython.double, + v3=cython.double, + v4=cython.double, +) +def approximateCubicArcLengthC(pt1, pt2, pt3, pt4): + """Approximates the arc length for a cubic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + + Returns: + Arc length value. + """ + # This, essentially, approximates the length-of-derivative function + # to be integrated with the best-matching seventh-degree polynomial + # approximation of it. + # + # https://en.wikipedia.org/wiki/Gaussian_quadrature#Gauss.E2.80.93Lobatto_rules + + # abs(BezierCurveC[3].diff(t).subs({t:T})) for T in sorted(0, .5±(3/7)**.5/2, .5, 1), + # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + v0 = abs(pt2 - pt1) * 0.15 + v1 = abs( + -0.558983582205757 * pt1 + + 0.325650248872424 * pt2 + + 0.208983582205757 * pt3 + + 0.024349751127576 * pt4 + ) + v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 + v3 = abs( + -0.024349751127576 * pt1 + - 0.208983582205757 * pt2 + - 0.325650248872424 * pt3 + + 0.558983582205757 * pt4 + ) + v4 = abs(pt4 - pt3) * 0.15 + + return v0 + v1 + v2 + v3 + v4 + + +def calcCubicBounds(pt1, pt2, pt3, pt4): + """Calculates the bounding rectangle for a quadratic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + + Example:: + + >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) + (0, 0, 100, 75.0) + >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) + (0.0, 0.0, 100, 100) + >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) + 35.566243 0.000000 64.433757 75.000000 + """ + (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) + # calc first derivative + ax3 = ax * 3.0 + ay3 = ay * 3.0 + bx2 = bx * 2.0 + by2 = by * 2.0 + xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + roots = xRoots + yRoots + + points = [ + ( + ax * t * t * t + bx * t * t + cx * t + dx, + ay * t * t * t + by * t * t + cy * t + dy, + ) + for t in roots + ] + [pt1, pt4] + return calcBounds(points) + + +def splitLine(pt1, pt2, where, isHorizontal): + """Split a line at a given coordinate. + + Args: + pt1: Start point of line as 2D tuple. + pt2: End point of line as 2D tuple. + where: Position at which to split the line. + isHorizontal: Direction of the ray splitting the line. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two line segments (each line segment being two 2D tuples) + if the line was successfully split, or a list containing the original + line. + + Example:: + + >>> printSegments(splitLine((0, 0), (100, 100), 50, True)) + ((0, 0), (50, 50)) + ((50, 50), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 100, True)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, True)) + ((0, 0), (0, 0)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, False)) + ((0, 0), (0, 0)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((100, 0), (0, 0), 50, False)) + ((100, 0), (50, 0)) + ((50, 0), (0, 0)) + >>> printSegments(splitLine((0, 100), (0, 0), 50, True)) + ((0, 100), (0, 50)) + ((0, 50), (0, 0)) + """ + pt1x, pt1y = pt1 + pt2x, pt2y = pt2 + + ax = pt2x - pt1x + ay = pt2y - pt1y + + bx = pt1x + by = pt1y + + a = (ax, ay)[isHorizontal] + + if a == 0: + return [(pt1, pt2)] + t = (where - (bx, by)[isHorizontal]) / a + if 0 <= t < 1: + midPt = ax * t + bx, ay * t + by + return [(pt1, midPt), (midPt, pt2)] + else: + return [(pt1, pt2)] + + +def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): + """Split a quadratic Bezier curve at a given coordinate. + + Args: + pt1,pt2,pt3: Control points of the Bezier as 2D tuples. + where: Position at which to split the curve. + isHorizontal: Direction of the ray splitting the curve. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two curve segments (each curve segment being three 2D tuples) + if the curve was successfully split, or a list containing the original + curve. + + Example:: + + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False)) + ((0, 0), (50, 100), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False)) + ((0, 0), (12.5, 25), (25, 37.5)) + ((25, 37.5), (62.5, 75), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True)) + ((0, 0), (7.32233, 14.6447), (14.6447, 25)) + ((14.6447, 25), (50, 75), (85.3553, 25)) + ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15)) + >>> # XXX I'm not at all sure if the following behavior is desirable: + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (50, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + """ + a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + solutions = solveQuadratic( + a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + ) + solutions = sorted(t for t in solutions if 0 <= t < 1) + if not solutions: + return [(pt1, pt2, pt3)] + return _splitQuadraticAtT(a, b, c, *solutions) + + +def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): + """Split a cubic Bezier curve at a given coordinate. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + where: Position at which to split the curve. + isHorizontal: Direction of the ray splitting the curve. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two curve segments (each curve segment being four 2D tuples) + if the curve was successfully split, or a list containing the original + curve. + + Example:: + + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False)) + ((0, 0), (25, 100), (75, 100), (100, 0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True)) + ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25)) + ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25)) + ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15)) + """ + a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + solutions = solveCubic( + a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + ) + solutions = sorted(t for t in solutions if 0 <= t < 1) + if not solutions: + return [(pt1, pt2, pt3, pt4)] + return _splitCubicAtT(a, b, c, d, *solutions) + + +def splitQuadraticAtT(pt1, pt2, pt3, *ts): + """Split a quadratic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3: Control points of the Bezier as 2D tuples. + *ts: Positions at which to split the curve. + + Returns: + A list of curve segments (each curve segment being three 2D tuples). + + Examples:: + + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (62.5, 50), (75, 37.5)) + ((75, 37.5), (87.5, 25), (100, 0)) + """ + a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + return _splitQuadraticAtT(a, b, c, *ts) + + +def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): + """Split a cubic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + *ts: Positions at which to split the curve. + + Returns: + A list of curve segments (each curve segment being four 2D tuples). + + Examples:: + + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25)) + ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0)) + """ + a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + return _splitCubicAtT(a, b, c, d, *ts) + + +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, +) +def splitCubicAtTC(pt1, pt2, pt3, pt4, *ts): + """Split a cubic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.. + *ts: Positions at which to split the curve. + + Yields: + Curve segments (each curve segment being four complex numbers). + """ + a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) + yield from _splitCubicAtTC(a, b, c, d, *ts) + + +@cython.returns(cython.complex) +@cython.locals( + t=cython.double, + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + pointAtT=cython.complex, + off1=cython.complex, + off2=cython.complex, +) +@cython.locals( + t2=cython.double, _1_t=cython.double, _1_t_2=cython.double, _2_t_1_t=cython.double +) +def splitCubicIntoTwoAtTC(pt1, pt2, pt3, pt4, t): + """Split a cubic Bezier curve at t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + t: Position at which to split the curve. + + Returns: + A tuple of two curve segments (each curve segment being four complex numbers). + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + _2_t_1_t = 2 * t * _1_t + pointAtT = ( + _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + ) + off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 + off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + + pt2 = pt1 + (pt2 - pt1) * t + pt3 = pt4 + (pt3 - pt4) * _1_t + + return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) + + +def _splitQuadraticAtT(a, b, c, *ts): + ts = list(ts) + segments = [] + ts.insert(0, 0.0) + ts.append(1.0) + ax, ay = a + bx, by = b + cx, cy = c + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + # calc new a, b and c + delta_2 = delta * delta + a1x = ax * delta_2 + a1y = ay * delta_2 + b1x = (2 * ax * t1 + bx) * delta + b1y = (2 * ay * t1 + by) * delta + t1_2 = t1 * t1 + c1x = ax * t1_2 + bx * t1 + cx + c1y = ay * t1_2 + by * t1 + cy + + pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + segments.append((pt1, pt2, pt3)) + return segments + + +def _splitCubicAtT(a, b, c, d, *ts): + ts = list(ts) + ts.insert(0, 0.0) + ts.append(1.0) + segments = [] + ax, ay = a + bx, by = b + cx, cy = c + dx, dy = d + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + + delta_2 = delta * delta + delta_3 = delta * delta_2 + t1_2 = t1 * t1 + t1_3 = t1 * t1_2 + + # calc new a, b, c and d + a1x = ax * delta_3 + a1y = ay * delta_3 + b1x = (3 * ax * t1 + bx) * delta_2 + b1y = (3 * ay * t1 + by) * delta_2 + c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + pt1, pt2, pt3, pt4 = calcCubicPoints( + (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + ) + segments.append((pt1, pt2, pt3, pt4)) + return segments + + +@cython.locals( + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, + t1=cython.double, + t2=cython.double, + delta=cython.double, + delta_2=cython.double, + delta_3=cython.double, + a1=cython.complex, + b1=cython.complex, + c1=cython.complex, + d1=cython.complex, +) +def _splitCubicAtTC(a, b, c, d, *ts): + ts = list(ts) + ts.insert(0, 0.0) + ts.append(1.0) + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + + delta_2 = delta * delta + delta_3 = delta * delta_2 + t1_2 = t1 * t1 + t1_3 = t1 * t1_2 + + # calc new a, b, c and d + a1 = a * delta_3 + b1 = (3 * a * t1 + b) * delta_2 + c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + d1 = a * t1_3 + b * t1_2 + c * t1 + d + pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + yield (pt1, pt2, pt3, pt4) + + +# +# Equation solvers. +# + +from math import sqrt, acos, cos, pi + + +def solveQuadratic(a, b, c, sqrt=sqrt): + """Solve a quadratic equation. + + Solves *a*x*x + b*x + c = 0* where a, b and c are real. + + Args: + a: coefficient of *x²* + b: coefficient of *x* + c: constant term + + Returns: + A list of roots. Note that the returned list is neither guaranteed to + be sorted nor to contain unique values! + """ + if abs(a) < epsilon: + if abs(b) < epsilon: + # We have a non-equation; therefore, we have no valid solution + roots = [] + else: + # We have a linear equation with 1 root. + roots = [-c / b] + else: + # We have a true quadratic equation. Apply the quadratic formula to find two roots. + DD = b * b - 4.0 * a * c + if DD >= 0.0: + rDD = sqrt(DD) + roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + else: + # complex roots, ignore + roots = [] + return roots + + +def solveCubic(a, b, c, d): + """Solve a cubic equation. + + Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real. + + Args: + a: coefficient of *x³* + b: coefficient of *x²* + c: coefficient of *x* + d: constant term + + Returns: + A list of roots. Note that the returned list is neither guaranteed to + be sorted nor to contain unique values! + + Examples:: + + >>> solveCubic(1, 1, -6, 0) + [-3.0, -0.0, 2.0] + >>> solveCubic(-10.0, -9.0, 48.0, -29.0) + [-2.9, 1.0, 1.0] + >>> solveCubic(-9.875, -9.0, 47.625, -28.75) + [-2.911392, 1.0, 1.0] + >>> solveCubic(1.0, -4.5, 6.75, -3.375) + [1.5, 1.5, 1.5] + >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123) + [0.5, 0.5, 0.5] + >>> solveCubic( + ... 9.0, 0.0, 0.0, -7.62939453125e-05 + ... ) == [-0.0, -0.0, -0.0] + True + """ + # + # adapted from: + # CUBIC.C - Solve a cubic polynomial + # public domain by Ross Cottrell + # found at: http://www.strangecreations.com/library/snippets/Cubic.C + # + if abs(a) < epsilon: + # don't just test for zero; for very small values of 'a' solveCubic() + # returns unreliable results, so we fall back to quad. + return solveQuadratic(b, c, d) + a = float(a) + a1 = b / a + a2 = c / a + a3 = d / a + + Q = (a1 * a1 - 3.0 * a2) / 9.0 + R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + + R2 = R * R + Q3 = Q * Q * Q + R2 = 0 if R2 < epsilon else R2 + Q3 = 0 if abs(Q3) < epsilon else Q3 + + R2_Q3 = R2 - Q3 + + if R2 == 0.0 and Q3 == 0.0: + x = round(-a1 / 3.0, epsilonDigits) + return [x, x, x] + elif R2_Q3 <= epsilon * 0.5: + # The epsilon * .5 above ensures that Q3 is not zero. + theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + rQ2 = -2.0 * sqrt(Q) + a1_3 = a1 / 3.0 + x0 = rQ2 * cos(theta / 3.0) - a1_3 + x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + x0, x1, x2 = sorted([x0, x1, x2]) + # Merge roots that are close-enough + if x1 - x0 < epsilon and x2 - x1 < epsilon: + x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + elif x1 - x0 < epsilon: + x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + x2 = round(x2, epsilonDigits) + elif x2 - x1 < epsilon: + x0 = round(x0, epsilonDigits) + x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + else: + x0 = round(x0, epsilonDigits) + x1 = round(x1, epsilonDigits) + x2 = round(x2, epsilonDigits) + return [x0, x1, x2] + else: + x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + x = x + Q / x + if R >= 0.0: + x = -x + x = round(x - a1 / 3.0, epsilonDigits) + return [x] + + +# +# Conversion routines for points to parameters and vice versa +# + + +def calcQuadraticParameters(pt1, pt2, pt3): + x2, y2 = pt2 + x3, y3 = pt3 + cx, cy = pt1 + bx = (x2 - cx) * 2.0 + by = (y2 - cy) * 2.0 + ax = x3 - cx - bx + ay = y3 - cy - by + return (ax, ay), (bx, by), (cx, cy) + + +def calcCubicParameters(pt1, pt2, pt3, pt4): + x2, y2 = pt2 + x3, y3 = pt3 + x4, y4 = pt4 + dx, dy = pt1 + cx = (x2 - dx) * 3.0 + cy = (y2 - dy) * 3.0 + bx = (x3 - x2) * 3.0 - cx + by = (y3 - y2) * 3.0 - cy + ax = x4 - dx - cx - bx + ay = y4 - dy - cy - by + return (ax, ay), (bx, by), (cx, cy), (dx, dy) + + +@cython.cfunc +@cython.inline +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + a=cython.complex, + b=cython.complex, + c=cython.complex, +) +def calcCubicParametersC(pt1, pt2, pt3, pt4): + c = (pt2 - pt1) * 3.0 + b = (pt3 - pt2) * 3.0 - c + a = pt4 - pt1 - c - b + return (a, b, c, pt1) + + +def calcQuadraticPoints(a, b, c): + ax, ay = a + bx, by = b + cx, cy = c + x1 = cx + y1 = cy + x2 = (bx * 0.5) + cx + y2 = (by * 0.5) + cy + x3 = ax + bx + cx + y3 = ay + by + cy + return (x1, y1), (x2, y2), (x3, y3) + + +def calcCubicPoints(a, b, c, d): + ax, ay = a + bx, by = b + cx, cy = c + dx, dy = d + x1 = dx + y1 = dy + x2 = (cx / 3.0) + dx + y2 = (cy / 3.0) + dy + x3 = (bx + cx) / 3.0 + x2 + y3 = (by + cy) / 3.0 + y2 + x4 = ax + dx + cx + bx + y4 = ay + dy + cy + by + return (x1, y1), (x2, y2), (x3, y3), (x4, y4) + + +@cython.cfunc +@cython.inline +@cython.locals( + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, + p2=cython.complex, + p3=cython.complex, + p4=cython.complex, +) +def calcCubicPointsC(a, b, c, d): + p2 = c * (1 / 3) + d + p3 = (b + c) * (1 / 3) + p2 + p4 = a + b + c + d + return (d, p2, p3, p4) + + +# +# Point at time +# + + +def linePointAtT(pt1, pt2, t): + """Finds the point at time `t` on a line. + + Args: + pt1, pt2: Coordinates of the line as 2D tuples. + t: The time along the line. + + Returns: + A 2D tuple with the coordinates of the point. + """ + return ((pt1[0] * (1 - t) + pt2[0] * t), (pt1[1] * (1 - t) + pt2[1] * t)) + + +def quadraticPointAtT(pt1, pt2, pt3, t): + """Finds the point at time `t` on a quadratic curve. + + Args: + pt1, pt2, pt3: Coordinates of the curve as 2D tuples. + t: The time along the curve. + + Returns: + A 2D tuple with the coordinates of the point. + """ + x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + return (x, y) + + +def cubicPointAtT(pt1, pt2, pt3, pt4, t): + """Finds the point at time `t` on a cubic curve. + + Args: + pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples. + t: The time along the curve. + + Returns: + A 2D tuple with the coordinates of the point. + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + x = ( + _1_t_2 * _1_t * pt1[0] + + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + + t2 * t * pt4[0] + ) + y = ( + _1_t_2 * _1_t * pt1[1] + + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + + t2 * t * pt4[1] + ) + return (x, y) + + +@cython.returns(cython.complex) +@cython.locals( + t=cython.double, + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals(t2=cython.double, _1_t=cython.double, _1_t_2=cython.double) +def cubicPointAtTC(pt1, pt2, pt3, pt4, t): + """Finds the point at time `t` on a cubic curve. + + Args: + pt1, pt2, pt3, pt4: Coordinates of the curve as complex numbers. + t: The time along the curve. + + Returns: + A complex number with the coordinates of the point. + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + + +def segmentPointAtT(seg, t): + if len(seg) == 2: + return linePointAtT(*seg, t) + elif len(seg) == 3: + return quadraticPointAtT(*seg, t) + elif len(seg) == 4: + return cubicPointAtT(*seg, t) + raise ValueError("Unknown curve degree") + + +# +# Intersection finders +# + + +def _line_t_of_pt(s, e, pt): + sx, sy = s + ex, ey = e + px, py = pt + if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + # Line is a point! + return -1 + # Use the largest + if abs(sx - ex) > abs(sy - ey): + return (px - sx) / (ex - sx) + else: + return (py - sy) / (ey - sy) + + +def _both_points_are_on_same_side_of_origin(a, b, origin): + xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + return not (xDiff <= 0.0 and yDiff <= 0.0) + + +def lineLineIntersections(s1, e1, s2, e2): + """Finds intersections between two line segments. + + Args: + s1, e1: Coordinates of the first line as 2D tuples. + s2, e2: Coordinates of the second line as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + + >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367)) + >>> len(a) + 1 + >>> intersection = a[0] + >>> intersection.pt + (374.44882952482897, 313.73458370177315) + >>> (intersection.t1, intersection.t2) + (0.45069111555824465, 0.5408153767394238) + """ + s1x, s1y = s1 + e1x, e1y = e1 + s2x, s2y = s2 + e2x, e2y = e2 + if ( + math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + ): # Parallel vertical + return [] + if ( + math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + ): # Parallel horizontal + return [] + if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + return [] + if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + return [] + if math.isclose(e1x, s1x): + x = s1x + slope34 = (e2y - s2y) / (e2x - s2x) + y = slope34 * (x - s2x) + s2y + pt = (x, y) + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + if math.isclose(s2x, e2x): + x = s2x + slope12 = (e1y - s1y) / (e1x - s1x) + y = slope12 * (x - s1x) + s1y + pt = (x, y) + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + + slope12 = (e1y - s1y) / (e1x - s1x) + slope34 = (e2y - s2y) / (e2x - s2x) + if math.isclose(slope12, slope34): + return [] + x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + y = slope12 * (x - s1x) + s1y + pt = (x, y) + if _both_points_are_on_same_side_of_origin( + pt, e1, s1 + ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + return [] + + +def _alignment_transformation(segment): + # Returns a transformation which aligns a segment horizontally at the + # origin. Apply this transformation to curves and root-find to find + # intersections with the segment. + start = segment[0] + end = segment[-1] + angle = math.atan2(end[1] - start[1], end[0] - start[0]) + return Identity.rotate(-angle).translate(-start[0], -start[1]) + + +def _curve_line_intersections_t(curve, line): + aligned_curve = _alignment_transformation(line).transformPoints(curve) + if len(curve) == 3: + a, b, c = calcQuadraticParameters(*aligned_curve) + intersections = solveQuadratic(a[1], b[1], c[1]) + elif len(curve) == 4: + a, b, c, d = calcCubicParameters(*aligned_curve) + intersections = solveCubic(a[1], b[1], c[1], d[1]) + else: + raise ValueError("Unknown curve degree") + return sorted(i for i in intersections if 0.0 <= i <= 1) + + +def curveLineIntersections(curve, line): + """Finds intersections between a curve and a line. + + Args: + curve: List of coordinates of the curve segment as 2D tuples. + line: List of coordinates of the line segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ] + >>> line = [ (25, 260), (230, 20) ] + >>> intersections = curveLineIntersections(curve, line) + >>> len(intersections) + 3 + >>> intersections[0].pt + (84.9000930760723, 189.87306176459828) + """ + if len(curve) == 3: + pointFinder = quadraticPointAtT + elif len(curve) == 4: + pointFinder = cubicPointAtT + else: + raise ValueError("Unknown curve degree") + intersections = [] + for t in _curve_line_intersections_t(curve, line): + pt = pointFinder(*curve, t) + # Back-project the point onto the line, to avoid problems with + # numerical accuracy in the case of vertical and horizontal lines + line_t = _line_t_of_pt(*line, pt) + pt = linePointAtT(*line, line_t) + intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + return intersections + + +def _curve_bounds(c): + if len(c) == 3: + return calcQuadraticBounds(*c) + elif len(c) == 4: + return calcCubicBounds(*c) + raise ValueError("Unknown curve degree") + + +def _split_segment_at_t(c, t): + if len(c) == 2: + s, e = c + midpoint = linePointAtT(s, e, t) + return [(s, midpoint), (midpoint, e)] + if len(c) == 3: + return splitQuadraticAtT(*c, t) + elif len(c) == 4: + return splitCubicAtT(*c, t) + raise ValueError("Unknown curve degree") + + +def _curve_curve_intersections_t( + curve1, curve2, precision=1e-3, range1=None, range2=None +): + bounds1 = _curve_bounds(curve1) + bounds2 = _curve_bounds(curve2) + + if not range1: + range1 = (0.0, 1.0) + if not range2: + range2 = (0.0, 1.0) + + # If bounds don't intersect, go home + intersects, _ = sectRect(bounds1, bounds2) + if not intersects: + return [] + + def midpoint(r): + return 0.5 * (r[0] + r[1]) + + # If they do overlap but they're tiny, approximate + if rectArea(bounds1) < precision and rectArea(bounds2) < precision: + return [(midpoint(range1), midpoint(range2))] + + c11, c12 = _split_segment_at_t(curve1, 0.5) + c11_range = (range1[0], midpoint(range1)) + c12_range = (midpoint(range1), range1[1]) + + c21, c22 = _split_segment_at_t(curve2, 0.5) + c21_range = (range2[0], midpoint(range2)) + c22_range = (midpoint(range2), range2[1]) + + found = [] + found.extend( + _curve_curve_intersections_t( + c11, c21, precision, range1=c11_range, range2=c21_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c12, c21, precision, range1=c12_range, range2=c21_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c11, c22, precision, range1=c11_range, range2=c22_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c12, c22, precision, range1=c12_range, range2=c22_range + ) + ) + + unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + seen = set() + unique_values = [] + + for ts in found: + key = unique_key(ts) + if key in seen: + continue + seen.add(key) + unique_values.append(ts) + + return unique_values + + +def _is_linelike(segment): + maybeline = _alignment_transformation(segment).transformPoints(segment) + return all(math.isclose(p[1], 0.0) for p in maybeline) + + +def curveCurveIntersections(curve1, curve2): + """Finds intersections between a curve and a curve. + + Args: + curve1: List of coordinates of the first curve segment as 2D tuples. + curve2: List of coordinates of the second curve segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] + >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] + >>> intersections = curveCurveIntersections(curve1, curve2) + >>> len(intersections) + 3 + >>> intersections[0].pt + (81.7831487395506, 109.88904552375288) + """ + if _is_linelike(curve1): + line1 = curve1[0], curve1[-1] + if _is_linelike(curve2): + line2 = curve2[0], curve2[-1] + return lineLineIntersections(*line1, *line2) + else: + return curveLineIntersections(curve2, line1) + elif _is_linelike(curve2): + line2 = curve2[0], curve2[-1] + return curveLineIntersections(curve1, line2) + + intersection_ts = _curve_curve_intersections_t(curve1, curve2) + return [ + Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + for ts in intersection_ts + ] + + +def segmentSegmentIntersections(seg1, seg2): + """Finds intersections between two segments. + + Args: + seg1: List of coordinates of the first segment as 2D tuples. + seg2: List of coordinates of the second segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] + >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] + >>> intersections = segmentSegmentIntersections(curve1, curve2) + >>> len(intersections) + 3 + >>> intersections[0].pt + (81.7831487395506, 109.88904552375288) + >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ] + >>> line = [ (25, 260), (230, 20) ] + >>> intersections = segmentSegmentIntersections(curve3, line) + >>> len(intersections) + 3 + >>> intersections[0].pt + (84.9000930760723, 189.87306176459828) + + """ + # Arrange by degree + swapped = False + if len(seg2) > len(seg1): + seg2, seg1 = seg1, seg2 + swapped = True + if len(seg1) > 2: + if len(seg2) > 2: + intersections = curveCurveIntersections(seg1, seg2) + else: + intersections = curveLineIntersections(seg1, seg2) + elif len(seg1) == 2 and len(seg2) == 2: + intersections = lineLineIntersections(*seg1, *seg2) + else: + raise ValueError("Couldn't work out which intersection function to use") + if not swapped: + return intersections + return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + + +def _segmentrepr(obj): + """ + >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + """ + try: + it = iter(obj) + except TypeError: + return "%g" % obj + else: + return "(%s)" % ", ".join(_segmentrepr(x) for x in it) + + +def printSegments(segments): + """Helper for the doctests, displaying each segment in a list of + segments on a single line as a tuple. + """ + for segment in segments: + print(_segmentrepr(segment)) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/classifyTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/classifyTools.py new file mode 100644 index 00000000..2235bbd7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/classifyTools.py @@ -0,0 +1,171 @@ +""" fontTools.misc.classifyTools.py -- tools for classifying things. +""" + + +class Classifier(object): + + """ + Main Classifier object, used to classify things into similar sets. + """ + + def __init__(self, sort=True): + self._things = set() # set of all things known so far + self._sets = [] # list of class sets produced so far + self._mapping = {} # map from things to their class set + self._dirty = False + self._sort = sort + + def add(self, set_of_things): + """ + Add a set to the classifier. Any iterable is accepted. + """ + if not set_of_things: + return + + self._dirty = True + + things, sets, mapping = self._things, self._sets, self._mapping + + s = set(set_of_things) + intersection = s.intersection(things) # existing things + s.difference_update(intersection) # new things + difference = s + del s + + # Add new class for new things + if difference: + things.update(difference) + sets.append(difference) + for thing in difference: + mapping[thing] = difference + del difference + + while intersection: + # Take one item and process the old class it belongs to + old_class = mapping[next(iter(intersection))] + old_class_intersection = old_class.intersection(intersection) + + # Update old class to remove items from new set + old_class.difference_update(old_class_intersection) + + # Remove processed items from todo list + intersection.difference_update(old_class_intersection) + + # Add new class for the intersection with old class + sets.append(old_class_intersection) + for thing in old_class_intersection: + mapping[thing] = old_class_intersection + del old_class_intersection + + def update(self, list_of_sets): + """ + Add a a list of sets to the classifier. Any iterable of iterables is accepted. + """ + for s in list_of_sets: + self.add(s) + + def _process(self): + if not self._dirty: + return + + # Do any deferred processing + sets = self._sets + self._sets = [s for s in sets if s] + + if self._sort: + self._sets = sorted(self._sets, key=lambda s: (-len(s), sorted(s))) + + self._dirty = False + + # Output methods + + def getThings(self): + """Returns the set of all things known so far. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._things + + def getMapping(self): + """Returns the mapping from things to their class set. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._mapping + + def getClasses(self): + """Returns the list of class sets. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._sets + + +def classify(list_of_sets, sort=True): + """ + Takes a iterable of iterables (list of sets from here on; but any + iterable works.), and returns the smallest list of sets such that + each set, is either a subset, or is disjoint from, each of the input + sets. + + In other words, this function classifies all the things present in + any of the input sets, into similar classes, based on which sets + things are a member of. + + If sort=True, return class sets are sorted by decreasing size and + their natural sort order within each class size. Otherwise, class + sets are returned in the order that they were identified, which is + generally not significant. + + >>> classify([]) == ([], {}) + True + >>> classify([[]]) == ([], {}) + True + >>> classify([[], []]) == ([], {}) + True + >>> classify([[1]]) == ([{1}], {1: {1}}) + True + >>> classify([[1,2]]) == ([{1, 2}], {1: {1, 2}, 2: {1, 2}}) + True + >>> classify([[1],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}}) + True + >>> classify([[1,2],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}}) + True + >>> classify([[1,2],[2,4]]) == ([{1}, {2}, {4}], {1: {1}, 2: {2}, 4: {4}}) + True + >>> classify([[1,2],[2,4,5]]) == ( + ... [{4, 5}, {1}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}}) + True + >>> classify([[1,2],[2,4,5]], sort=False) == ( + ... [{1}, {4, 5}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}}) + True + >>> classify([[1,2,9],[2,4,5]], sort=False) == ( + ... [{1, 9}, {4, 5}, {2}], {1: {1, 9}, 2: {2}, 4: {4, 5}, 5: {4, 5}, + ... 9: {1, 9}}) + True + >>> classify([[1,2,9,15],[2,4,5]], sort=False) == ( + ... [{1, 9, 15}, {4, 5}, {2}], {1: {1, 9, 15}, 2: {2}, 4: {4, 5}, + ... 5: {4, 5}, 9: {1, 9, 15}, 15: {1, 9, 15}}) + True + >>> classes, mapping = classify([[1,2,9,15],[2,4,5],[15,5]], sort=False) + >>> set([frozenset(c) for c in classes]) == set( + ... [frozenset(s) for s in ({1, 9}, {4}, {2}, {5}, {15})]) + True + >>> mapping == {1: {1, 9}, 2: {2}, 4: {4}, 5: {5}, 9: {1, 9}, 15: {15}} + True + """ + classifier = Classifier(sort=sort) + classifier.update(list_of_sets) + return classifier.getClasses(), classifier.getMapping() + + +if __name__ == "__main__": + import sys, doctest + + sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cliTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cliTools.py new file mode 100644 index 00000000..8322ea9e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cliTools.py @@ -0,0 +1,52 @@ +"""Collection of utilities for command-line interfaces and console scripts.""" +import os +import re + + +numberAddedRE = re.compile(r"#\d+$") + + +def makeOutputFileName( + input, outputDir=None, extension=None, overWrite=False, suffix="" +): + """Generates a suitable file name for writing output. + + Often tools will want to take a file, do some kind of transformation to it, + and write it out again. This function determines an appropriate name for the + output file, through one or more of the following steps: + + - changing the output directory + - appending suffix before file extension + - replacing the file extension + - suffixing the filename with a number (``#1``, ``#2``, etc.) to avoid + overwriting an existing file. + + Args: + input: Name of input file. + outputDir: Optionally, a new directory to write the file into. + suffix: Optionally, a string suffix is appended to file name before + the extension. + extension: Optionally, a replacement for the current file extension. + overWrite: Overwriting an existing file is permitted if true; if false + and the proposed filename exists, a new name will be generated by + adding an appropriate number suffix. + + Returns: + str: Suitable output filename + """ + dirName, fileName = os.path.split(input) + fileName, ext = os.path.splitext(fileName) + if outputDir: + dirName = outputDir + fileName = numberAddedRE.split(fileName)[0] + if extension is None: + extension = os.path.splitext(input)[1] + output = os.path.join(dirName, fileName + suffix + extension) + n = 1 + if not overWrite: + while os.path.exists(output): + output = os.path.join( + dirName, fileName + suffix + "#" + repr(n) + extension + ) + n += 1 + return output diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/configTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/configTools.py new file mode 100644 index 00000000..38bbada2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/configTools.py @@ -0,0 +1,348 @@ +""" +Code of the config system; not related to fontTools or fonts in particular. + +The options that are specific to fontTools are in :mod:`fontTools.config`. + +To create your own config system, you need to create an instance of +:class:`Options`, and a subclass of :class:`AbstractConfig` with its +``options`` class variable set to your instance of Options. + +""" +from __future__ import annotations + +import logging +from dataclasses import dataclass +from typing import ( + Any, + Callable, + ClassVar, + Dict, + Iterable, + Mapping, + MutableMapping, + Optional, + Set, + Union, +) + + +log = logging.getLogger(__name__) + +__all__ = [ + "AbstractConfig", + "ConfigAlreadyRegisteredError", + "ConfigError", + "ConfigUnknownOptionError", + "ConfigValueParsingError", + "ConfigValueValidationError", + "Option", + "Options", +] + + +class ConfigError(Exception): + """Base exception for the config module.""" + + +class ConfigAlreadyRegisteredError(ConfigError): + """Raised when a module tries to register a configuration option that + already exists. + + Should not be raised too much really, only when developing new fontTools + modules. + """ + + def __init__(self, name): + super().__init__(f"Config option {name} is already registered.") + + +class ConfigValueParsingError(ConfigError): + """Raised when a configuration value cannot be parsed.""" + + def __init__(self, name, value): + super().__init__( + f"Config option {name}: value cannot be parsed (given {repr(value)})" + ) + + +class ConfigValueValidationError(ConfigError): + """Raised when a configuration value cannot be validated.""" + + def __init__(self, name, value): + super().__init__( + f"Config option {name}: value is invalid (given {repr(value)})" + ) + + +class ConfigUnknownOptionError(ConfigError): + """Raised when a configuration option is unknown.""" + + def __init__(self, option_or_name): + name = ( + f"'{option_or_name.name}' (id={id(option_or_name)})>" + if isinstance(option_or_name, Option) + else f"'{option_or_name}'" + ) + super().__init__(f"Config option {name} is unknown") + + +# eq=False because Options are unique, not fungible objects +@dataclass(frozen=True, eq=False) +class Option: + name: str + """Unique name identifying the option (e.g. package.module:MY_OPTION).""" + help: str + """Help text for this option.""" + default: Any + """Default value for this option.""" + parse: Callable[[str], Any] + """Turn input (e.g. string) into proper type. Only when reading from file.""" + validate: Optional[Callable[[Any], bool]] = None + """Return true if the given value is an acceptable value.""" + + @staticmethod + def parse_optional_bool(v: str) -> Optional[bool]: + s = str(v).lower() + if s in {"0", "no", "false"}: + return False + if s in {"1", "yes", "true"}: + return True + if s in {"auto", "none"}: + return None + raise ValueError("invalid optional bool: {v!r}") + + @staticmethod + def validate_optional_bool(v: Any) -> bool: + return v is None or isinstance(v, bool) + + +class Options(Mapping): + """Registry of available options for a given config system. + + Define new options using the :meth:`register()` method. + + Access existing options using the Mapping interface. + """ + + __options: Dict[str, Option] + + def __init__(self, other: "Options" = None) -> None: + self.__options = {} + if other is not None: + for option in other.values(): + self.register_option(option) + + def register( + self, + name: str, + help: str, + default: Any, + parse: Callable[[str], Any], + validate: Optional[Callable[[Any], bool]] = None, + ) -> Option: + """Create and register a new option.""" + return self.register_option(Option(name, help, default, parse, validate)) + + def register_option(self, option: Option) -> Option: + """Register a new option.""" + name = option.name + if name in self.__options: + raise ConfigAlreadyRegisteredError(name) + self.__options[name] = option + return option + + def is_registered(self, option: Option) -> bool: + """Return True if the same option object is already registered.""" + return self.__options.get(option.name) is option + + def __getitem__(self, key: str) -> Option: + return self.__options.__getitem__(key) + + def __iter__(self) -> Iterator[str]: + return self.__options.__iter__() + + def __len__(self) -> int: + return self.__options.__len__() + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}({{\n" + + "".join( + f" {k!r}: Option(default={v.default!r}, ...),\n" + for k, v in self.__options.items() + ) + + "})" + ) + + +_USE_GLOBAL_DEFAULT = object() + + +class AbstractConfig(MutableMapping): + """ + Create a set of config values, optionally pre-filled with values from + the given dictionary or pre-existing config object. + + The class implements the MutableMapping protocol keyed by option name (`str`). + For convenience its methods accept either Option or str as the key parameter. + + .. seealso:: :meth:`set()` + + This config class is abstract because it needs its ``options`` class + var to be set to an instance of :class:`Options` before it can be + instanciated and used. + + .. code:: python + + class MyConfig(AbstractConfig): + options = Options() + + MyConfig.register_option( "test:option_name", "This is an option", 0, int, lambda v: isinstance(v, int)) + + cfg = MyConfig({"test:option_name": 10}) + + """ + + options: ClassVar[Options] + + @classmethod + def register_option( + cls, + name: str, + help: str, + default: Any, + parse: Callable[[str], Any], + validate: Optional[Callable[[Any], bool]] = None, + ) -> Option: + """Register an available option in this config system.""" + return cls.options.register( + name, help=help, default=default, parse=parse, validate=validate + ) + + _values: Dict[str, Any] + + def __init__( + self, + values: Union[AbstractConfig, Dict[Union[Option, str], Any]] = {}, + parse_values: bool = False, + skip_unknown: bool = False, + ): + self._values = {} + values_dict = values._values if isinstance(values, AbstractConfig) else values + for name, value in values_dict.items(): + self.set(name, value, parse_values, skip_unknown) + + def _resolve_option(self, option_or_name: Union[Option, str]) -> Option: + if isinstance(option_or_name, Option): + option = option_or_name + if not self.options.is_registered(option): + raise ConfigUnknownOptionError(option) + return option + elif isinstance(option_or_name, str): + name = option_or_name + try: + return self.options[name] + except KeyError: + raise ConfigUnknownOptionError(name) + else: + raise TypeError( + "expected Option or str, found " + f"{type(option_or_name).__name__}: {option_or_name!r}" + ) + + def set( + self, + option_or_name: Union[Option, str], + value: Any, + parse_values: bool = False, + skip_unknown: bool = False, + ): + """Set the value of an option. + + Args: + * `option_or_name`: an `Option` object or its name (`str`). + * `value`: the value to be assigned to given option. + * `parse_values`: parse the configuration value from a string into + its proper type, as per its `Option` object. The default + behavior is to raise `ConfigValueValidationError` when the value + is not of the right type. Useful when reading options from a + file type that doesn't support as many types as Python. + * `skip_unknown`: skip unknown configuration options. The default + behaviour is to raise `ConfigUnknownOptionError`. Useful when + reading options from a configuration file that has extra entries + (e.g. for a later version of fontTools) + """ + try: + option = self._resolve_option(option_or_name) + except ConfigUnknownOptionError as e: + if skip_unknown: + log.debug(str(e)) + return + raise + + # Can be useful if the values come from a source that doesn't have + # strict typing (.ini file? Terminal input?) + if parse_values: + try: + value = option.parse(value) + except Exception as e: + raise ConfigValueParsingError(option.name, value) from e + + if option.validate is not None and not option.validate(value): + raise ConfigValueValidationError(option.name, value) + + self._values[option.name] = value + + def get( + self, option_or_name: Union[Option, str], default: Any = _USE_GLOBAL_DEFAULT + ) -> Any: + """ + Get the value of an option. The value which is returned is the first + provided among: + + 1. a user-provided value in the options's ``self._values`` dict + 2. a caller-provided default value to this method call + 3. the global default for the option provided in ``fontTools.config`` + + This is to provide the ability to migrate progressively from config + options passed as arguments to fontTools APIs to config options read + from the current TTFont, e.g. + + .. code:: python + + def fontToolsAPI(font, some_option): + value = font.cfg.get("someLib.module:SOME_OPTION", some_option) + # use value + + That way, the function will work the same for users of the API that + still pass the option to the function call, but will favour the new + config mechanism if the given font specifies a value for that option. + """ + option = self._resolve_option(option_or_name) + if option.name in self._values: + return self._values[option.name] + if default is not _USE_GLOBAL_DEFAULT: + return default + return option.default + + def copy(self): + return self.__class__(self._values) + + def __getitem__(self, option_or_name: Union[Option, str]) -> Any: + return self.get(option_or_name) + + def __setitem__(self, option_or_name: Union[Option, str], value: Any) -> None: + return self.set(option_or_name, value) + + def __delitem__(self, option_or_name: Union[Option, str]) -> None: + option = self._resolve_option(option_or_name) + del self._values[option.name] + + def __iter__(self) -> Iterable[str]: + return self._values.__iter__() + + def __len__(self) -> int: + return len(self._values) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({repr(self._values)})" diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cython.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cython.py new file mode 100644 index 00000000..2a42d94a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/cython.py @@ -0,0 +1,27 @@ +""" Exports a no-op 'cython' namespace similar to +https://github.com/cython/cython/blob/master/Cython/Shadow.py + +This allows to optionally compile @cython decorated functions +(when cython is available at built time), or run the same code +as pure-python, without runtime dependency on cython module. + +We only define the symbols that we use. E.g. see fontTools.cu2qu +""" + +from types import SimpleNamespace + + +def _empty_decorator(x): + return x + + +compiled = False + +for name in ("double", "complex", "int"): + globals()[name] = None + +for name in ("cfunc", "inline"): + globals()[name] = _empty_decorator + +locals = lambda **_: _empty_decorator +returns = lambda _: _empty_decorator diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/dictTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/dictTools.py new file mode 100644 index 00000000..e3c0df73 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/dictTools.py @@ -0,0 +1,84 @@ +"""Misc dict tools.""" + + +__all__ = ["hashdict"] + + +# https://stackoverflow.com/questions/1151658/python-hashable-dicts +class hashdict(dict): + """ + hashable dict implementation, suitable for use as a key into + other dicts. + + >>> h1 = hashdict({"apples": 1, "bananas":2}) + >>> h2 = hashdict({"bananas": 3, "mangoes": 5}) + >>> h1+h2 + hashdict(apples=1, bananas=3, mangoes=5) + >>> d1 = {} + >>> d1[h1] = "salad" + >>> d1[h1] + 'salad' + >>> d1[h2] + Traceback (most recent call last): + ... + KeyError: hashdict(bananas=3, mangoes=5) + + based on answers from + http://stackoverflow.com/questions/1151658/python-hashable-dicts + + """ + + def __key(self): + return tuple(sorted(self.items())) + + def __repr__(self): + return "{0}({1})".format( + self.__class__.__name__, + ", ".join("{0}={1}".format(str(i[0]), repr(i[1])) for i in self.__key()), + ) + + def __hash__(self): + return hash(self.__key()) + + def __setitem__(self, key, value): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def __delitem__(self, key): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def clear(self): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def pop(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def popitem(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def setdefault(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def update(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + # update is not ok because it mutates the object + # __add__ is ok because it creates a new object + # while the new object is under construction, it's ok to mutate it + def __add__(self, right): + result = hashdict(self) + dict.update(result, right) + return result diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/eexec.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/eexec.py new file mode 100644 index 00000000..cafa312c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/eexec.py @@ -0,0 +1,119 @@ +""" +PostScript Type 1 fonts make use of two types of encryption: charstring +encryption and ``eexec`` encryption. Charstring encryption is used for +the charstrings themselves, while ``eexec`` is used to encrypt larger +sections of the font program, such as the ``Private`` and ``CharStrings`` +dictionaries. Despite the different names, the algorithm is the same, +although ``eexec`` encryption uses a fixed initial key R=55665. + +The algorithm uses cipher feedback, meaning that the ciphertext is used +to modify the key. Because of this, the routines in this module return +the new key at the end of the operation. + +""" + +from fontTools.misc.textTools import bytechr, bytesjoin, byteord + + +def _decryptChar(cipher, R): + cipher = byteord(cipher) + plain = ((cipher ^ (R >> 8))) & 0xFF + R = ((cipher + R) * 52845 + 22719) & 0xFFFF + return bytechr(plain), R + + +def _encryptChar(plain, R): + plain = byteord(plain) + cipher = ((plain ^ (R >> 8))) & 0xFF + R = ((cipher + R) * 52845 + 22719) & 0xFFFF + return bytechr(cipher), R + + +def decrypt(cipherstring, R): + r""" + Decrypts a string using the Type 1 encryption algorithm. + + Args: + cipherstring: String of ciphertext. + R: Initial key. + + Returns: + decryptedStr: Plaintext string. + R: Output key for subsequent decryptions. + + Examples:: + + >>> testStr = b"\0\0asdadads asds\265" + >>> decryptedStr, R = decrypt(testStr, 12321) + >>> decryptedStr == b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + True + >>> R == 36142 + True + """ + plainList = [] + for cipher in cipherstring: + plain, R = _decryptChar(cipher, R) + plainList.append(plain) + plainstring = bytesjoin(plainList) + return plainstring, int(R) + + +def encrypt(plainstring, R): + r""" + Encrypts a string using the Type 1 encryption algorithm. + + Note that the algorithm as described in the Type 1 specification requires the + plaintext to be prefixed with a number of random bytes. (For ``eexec`` the + number of random bytes is set to 4.) This routine does *not* add the random + prefix to its input. + + Args: + plainstring: String of plaintext. + R: Initial key. + + Returns: + cipherstring: Ciphertext string. + R: Output key for subsequent encryptions. + + Examples:: + + >>> testStr = b"\0\0asdadads asds\265" + >>> decryptedStr, R = decrypt(testStr, 12321) + >>> decryptedStr == b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + True + >>> R == 36142 + True + + >>> testStr = b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + >>> encryptedStr, R = encrypt(testStr, 12321) + >>> encryptedStr == b"\0\0asdadads asds\265" + True + >>> R == 36142 + True + """ + cipherList = [] + for plain in plainstring: + cipher, R = _encryptChar(plain, R) + cipherList.append(cipher) + cipherstring = bytesjoin(cipherList) + return cipherstring, int(R) + + +def hexString(s): + import binascii + + return binascii.hexlify(s) + + +def deHexString(h): + import binascii + + h = bytesjoin(h.split()) + return binascii.unhexlify(h) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/encodingTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/encodingTools.py new file mode 100644 index 00000000..3b2651d3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/encodingTools.py @@ -0,0 +1,72 @@ +"""fontTools.misc.encodingTools.py -- tools for working with OpenType encodings. +""" + +import fontTools.encodings.codecs + +# Map keyed by platformID, then platEncID, then possibly langID +_encodingMap = { + 0: { # Unicode + 0: "utf_16_be", + 1: "utf_16_be", + 2: "utf_16_be", + 3: "utf_16_be", + 4: "utf_16_be", + 5: "utf_16_be", + 6: "utf_16_be", + }, + 1: { # Macintosh + # See + # https://github.com/fonttools/fonttools/issues/236 + 0: { # Macintosh, platEncID==0, keyed by langID + 15: "mac_iceland", + 17: "mac_turkish", + 18: "mac_croatian", + 24: "mac_latin2", + 25: "mac_latin2", + 26: "mac_latin2", + 27: "mac_latin2", + 28: "mac_latin2", + 36: "mac_latin2", + 37: "mac_romanian", + 38: "mac_latin2", + 39: "mac_latin2", + 40: "mac_latin2", + Ellipsis: "mac_roman", # Other + }, + 1: "x_mac_japanese_ttx", + 2: "x_mac_trad_chinese_ttx", + 3: "x_mac_korean_ttx", + 6: "mac_greek", + 7: "mac_cyrillic", + 25: "x_mac_simp_chinese_ttx", + 29: "mac_latin2", + 35: "mac_turkish", + 37: "mac_iceland", + }, + 2: { # ISO + 0: "ascii", + 1: "utf_16_be", + 2: "latin1", + }, + 3: { # Microsoft + 0: "utf_16_be", + 1: "utf_16_be", + 2: "shift_jis", + 3: "gb2312", + 4: "big5", + 5: "euc_kr", + 6: "johab", + 10: "utf_16_be", + }, +} + + +def getEncoding(platformID, platEncID, langID, default=None): + """Returns the Python encoding name for OpenType platformID/encodingID/langID + triplet. If encoding for these values is not known, by default None is + returned. That can be overriden by passing a value to the default argument. + """ + encoding = _encodingMap.get(platformID, {}).get(platEncID, default) + if isinstance(encoding, dict): + encoding = encoding.get(langID, encoding[Ellipsis]) + return encoding diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/etree.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/etree.py new file mode 100644 index 00000000..9d4a65c3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/etree.py @@ -0,0 +1,478 @@ +"""Shim module exporting the same ElementTree API for lxml and +xml.etree backends. + +When lxml is installed, it is automatically preferred over the built-in +xml.etree module. +On Python 2.7, the cElementTree module is preferred over the pure-python +ElementTree module. + +Besides exporting a unified interface, this also defines extra functions +or subclasses built-in ElementTree classes to add features that are +only availble in lxml, like OrderedDict for attributes, pretty_print and +iterwalk. +""" +from fontTools.misc.textTools import tostr + + +XML_DECLARATION = """""" + +__all__ = [ + # public symbols + "Comment", + "dump", + "Element", + "ElementTree", + "fromstring", + "fromstringlist", + "iselement", + "iterparse", + "parse", + "ParseError", + "PI", + "ProcessingInstruction", + "QName", + "SubElement", + "tostring", + "tostringlist", + "TreeBuilder", + "XML", + "XMLParser", + "register_namespace", +] + +try: + from lxml.etree import * + + _have_lxml = True +except ImportError: + try: + from xml.etree.cElementTree import * + + # the cElementTree version of XML function doesn't support + # the optional 'parser' keyword argument + from xml.etree.ElementTree import XML + except ImportError: # pragma: no cover + from xml.etree.ElementTree import * + _have_lxml = False + + import sys + + # dict is always ordered in python >= 3.6 and on pypy + PY36 = sys.version_info >= (3, 6) + try: + import __pypy__ + except ImportError: + __pypy__ = None + _dict_is_ordered = bool(PY36 or __pypy__) + del PY36, __pypy__ + + if _dict_is_ordered: + _Attrib = dict + else: + from collections import OrderedDict as _Attrib + + if isinstance(Element, type): + _Element = Element + else: + # in py27, cElementTree.Element cannot be subclassed, so + # we need to import the pure-python class + from xml.etree.ElementTree import Element as _Element + + class Element(_Element): + """Element subclass that keeps the order of attributes.""" + + def __init__(self, tag, attrib=_Attrib(), **extra): + super(Element, self).__init__(tag) + self.attrib = _Attrib() + if attrib: + self.attrib.update(attrib) + if extra: + self.attrib.update(extra) + + def SubElement(parent, tag, attrib=_Attrib(), **extra): + """Must override SubElement as well otherwise _elementtree.SubElement + fails if 'parent' is a subclass of Element object. + """ + element = parent.__class__(tag, attrib, **extra) + parent.append(element) + return element + + def _iterwalk(element, events, tag): + include = tag is None or element.tag == tag + if include and "start" in events: + yield ("start", element) + for e in element: + for item in _iterwalk(e, events, tag): + yield item + if include: + yield ("end", element) + + def iterwalk(element_or_tree, events=("end",), tag=None): + """A tree walker that generates events from an existing tree as + if it was parsing XML data with iterparse(). + Drop-in replacement for lxml.etree.iterwalk. + """ + if iselement(element_or_tree): + element = element_or_tree + else: + element = element_or_tree.getroot() + if tag == "*": + tag = None + for item in _iterwalk(element, events, tag): + yield item + + _ElementTree = ElementTree + + class ElementTree(_ElementTree): + """ElementTree subclass that adds 'pretty_print' and 'doctype' + arguments to the 'write' method. + Currently these are only supported for the default XML serialization + 'method', and not also for "html" or "text", for these are delegated + to the base class. + """ + + def write( + self, + file_or_filename, + encoding=None, + xml_declaration=False, + method=None, + doctype=None, + pretty_print=False, + ): + if method and method != "xml": + # delegate to super-class + super(ElementTree, self).write( + file_or_filename, + encoding=encoding, + xml_declaration=xml_declaration, + method=method, + ) + return + + if encoding is not None and encoding.lower() == "unicode": + if xml_declaration: + raise ValueError( + "Serialisation to unicode must not request an XML declaration" + ) + write_declaration = False + encoding = "unicode" + elif xml_declaration is None: + # by default, write an XML declaration only for non-standard encodings + write_declaration = encoding is not None and encoding.upper() not in ( + "ASCII", + "UTF-8", + "UTF8", + "US-ASCII", + ) + else: + write_declaration = xml_declaration + + if encoding is None: + encoding = "ASCII" + + if pretty_print: + # NOTE this will modify the tree in-place + _indent(self._root) + + with _get_writer(file_or_filename, encoding) as write: + if write_declaration: + write(XML_DECLARATION % encoding.upper()) + if pretty_print: + write("\n") + if doctype: + write(_tounicode(doctype)) + if pretty_print: + write("\n") + + qnames, namespaces = _namespaces(self._root) + _serialize_xml(write, self._root, qnames, namespaces) + + import io + + def tostring( + element, + encoding=None, + xml_declaration=None, + method=None, + doctype=None, + pretty_print=False, + ): + """Custom 'tostring' function that uses our ElementTree subclass, with + pretty_print support. + """ + stream = io.StringIO() if encoding == "unicode" else io.BytesIO() + ElementTree(element).write( + stream, + encoding=encoding, + xml_declaration=xml_declaration, + method=method, + doctype=doctype, + pretty_print=pretty_print, + ) + return stream.getvalue() + + # serialization support + + import re + + # Valid XML strings can include any Unicode character, excluding control + # characters, the surrogate blocks, FFFE, and FFFF: + # Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + # Here we reversed the pattern to match only the invalid characters. + # For the 'narrow' python builds supporting only UCS-2, which represent + # characters beyond BMP as UTF-16 surrogate pairs, we need to pass through + # the surrogate block. I haven't found a more elegant solution... + UCS2 = sys.maxunicode < 0x10FFFF + if UCS2: + _invalid_xml_string = re.compile( + "[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]" + ) + else: + _invalid_xml_string = re.compile( + "[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]" + ) + + def _tounicode(s): + """Test if a string is valid user input and decode it to unicode string + using ASCII encoding if it's a bytes string. + Reject all bytes/unicode input that contains non-XML characters. + Reject all bytes input that contains non-ASCII characters. + """ + try: + s = tostr(s, encoding="ascii", errors="strict") + except UnicodeDecodeError: + raise ValueError( + "Bytes strings can only contain ASCII characters. " + "Use unicode strings for non-ASCII characters." + ) + except AttributeError: + _raise_serialization_error(s) + if s and _invalid_xml_string.search(s): + raise ValueError( + "All strings must be XML compatible: Unicode or ASCII, " + "no NULL bytes or control characters" + ) + return s + + import contextlib + + @contextlib.contextmanager + def _get_writer(file_or_filename, encoding): + # returns text write method and release all resources after using + try: + write = file_or_filename.write + except AttributeError: + # file_or_filename is a file name + f = open( + file_or_filename, + "w", + encoding="utf-8" if encoding == "unicode" else encoding, + errors="xmlcharrefreplace", + ) + with f: + yield f.write + else: + # file_or_filename is a file-like object + # encoding determines if it is a text or binary writer + if encoding == "unicode": + # use a text writer as is + yield write + else: + # wrap a binary writer with TextIOWrapper + detach_buffer = False + if isinstance(file_or_filename, io.BufferedIOBase): + buf = file_or_filename + elif isinstance(file_or_filename, io.RawIOBase): + buf = io.BufferedWriter(file_or_filename) + detach_buffer = True + else: + # This is to handle passed objects that aren't in the + # IOBase hierarchy, but just have a write method + buf = io.BufferedIOBase() + buf.writable = lambda: True + buf.write = write + try: + # TextIOWrapper uses this methods to determine + # if BOM (for UTF-16, etc) should be added + buf.seekable = file_or_filename.seekable + buf.tell = file_or_filename.tell + except AttributeError: + pass + wrapper = io.TextIOWrapper( + buf, + encoding=encoding, + errors="xmlcharrefreplace", + newline="\n", + ) + try: + yield wrapper.write + finally: + # Keep the original file open when the TextIOWrapper and + # the BufferedWriter are destroyed + wrapper.detach() + if detach_buffer: + buf.detach() + + from xml.etree.ElementTree import _namespace_map + + def _namespaces(elem): + # identify namespaces used in this tree + + # maps qnames to *encoded* prefix:local names + qnames = {None: None} + + # maps uri:s to prefixes + namespaces = {} + + def add_qname(qname): + # calculate serialized qname representation + try: + qname = _tounicode(qname) + if qname[:1] == "{": + uri, tag = qname[1:].rsplit("}", 1) + prefix = namespaces.get(uri) + if prefix is None: + prefix = _namespace_map.get(uri) + if prefix is None: + prefix = "ns%d" % len(namespaces) + else: + prefix = _tounicode(prefix) + if prefix != "xml": + namespaces[uri] = prefix + if prefix: + qnames[qname] = "%s:%s" % (prefix, tag) + else: + qnames[qname] = tag # default element + else: + qnames[qname] = qname + except TypeError: + _raise_serialization_error(qname) + + # populate qname and namespaces table + for elem in elem.iter(): + tag = elem.tag + if isinstance(tag, QName): + if tag.text not in qnames: + add_qname(tag.text) + elif isinstance(tag, str): + if tag not in qnames: + add_qname(tag) + elif tag is not None and tag is not Comment and tag is not PI: + _raise_serialization_error(tag) + for key, value in elem.items(): + if isinstance(key, QName): + key = key.text + if key not in qnames: + add_qname(key) + if isinstance(value, QName) and value.text not in qnames: + add_qname(value.text) + text = elem.text + if isinstance(text, QName) and text.text not in qnames: + add_qname(text.text) + return qnames, namespaces + + def _serialize_xml(write, elem, qnames, namespaces, **kwargs): + tag = elem.tag + text = elem.text + if tag is Comment: + write("" % _tounicode(text)) + elif tag is ProcessingInstruction: + write("" % _tounicode(text)) + else: + tag = qnames[_tounicode(tag) if tag is not None else None] + if tag is None: + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_xml(write, e, qnames, None) + else: + write("<" + tag) + if namespaces: + for uri, prefix in sorted( + namespaces.items(), key=lambda x: x[1] + ): # sort on prefix + if prefix: + prefix = ":" + prefix + write(' xmlns%s="%s"' % (prefix, _escape_attrib(uri))) + attrs = elem.attrib + if attrs: + # try to keep existing attrib order + if len(attrs) <= 1 or type(attrs) is _Attrib: + items = attrs.items() + else: + # if plain dict, use lexical order + items = sorted(attrs.items()) + for k, v in items: + if isinstance(k, QName): + k = _tounicode(k.text) + else: + k = _tounicode(k) + if isinstance(v, QName): + v = qnames[_tounicode(v.text)] + else: + v = _escape_attrib(v) + write(' %s="%s"' % (qnames[k], v)) + if text is not None or len(elem): + write(">") + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_xml(write, e, qnames, None) + write("") + else: + write("/>") + if elem.tail: + write(_escape_cdata(elem.tail)) + + def _raise_serialization_error(text): + raise TypeError("cannot serialize %r (type %s)" % (text, type(text).__name__)) + + def _escape_cdata(text): + # escape character data + try: + text = _tounicode(text) + # it's worth avoiding do-nothing calls for short strings + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + def _escape_attrib(text): + # escape attribute value + try: + text = _tounicode(text) + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if '"' in text: + text = text.replace('"', """) + if "\n" in text: + text = text.replace("\n", " ") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + def _indent(elem, level=0): + # From http://effbot.org/zone/element-lib.htm#prettyprint + i = "\n" + level * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + _indent(elem, level + 1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/filenames.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/filenames.py new file mode 100644 index 00000000..d279f89c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/filenames.py @@ -0,0 +1,246 @@ +""" +This module implements the algorithm for converting between a "user name" - +something that a user can choose arbitrarily inside a font editor - and a file +name suitable for use in a wide range of operating systems and filesystems. + +The `UFO 3 specification `_ +provides an example of an algorithm for such conversion, which avoids illegal +characters, reserved file names, ambiguity between upper- and lower-case +characters, and clashes with existing files. + +This code was originally copied from +`ufoLib `_ +by Tal Leming and is copyright (c) 2005-2016, The RoboFab Developers: + +- Erik van Blokland +- Tal Leming +- Just van Rossum +""" + + +illegalCharacters = r"\" * + / : < > ? [ \ ] | \0".split(" ") +illegalCharacters += [chr(i) for i in range(1, 32)] +illegalCharacters += [chr(0x7F)] +reservedFileNames = "CON PRN AUX CLOCK$ NUL A:-Z: COM1".lower().split(" ") +reservedFileNames += "LPT1 LPT2 LPT3 COM2 COM3 COM4".lower().split(" ") +maxFileNameLength = 255 + + +class NameTranslationError(Exception): + pass + + +def userNameToFileName(userName, existing=[], prefix="", suffix=""): + """Converts from a user name to a file name. + + Takes care to avoid illegal characters, reserved file names, ambiguity between + upper- and lower-case characters, and clashes with existing files. + + Args: + userName (str): The input file name. + existing: A case-insensitive list of all existing file names. + prefix: Prefix to be prepended to the file name. + suffix: Suffix to be appended to the file name. + + Returns: + A suitable filename. + + Raises: + NameTranslationError: If no suitable name could be generated. + + Examples:: + + >>> userNameToFileName("a") == "a" + True + >>> userNameToFileName("A") == "A_" + True + >>> userNameToFileName("AE") == "A_E_" + True + >>> userNameToFileName("Ae") == "A_e" + True + >>> userNameToFileName("ae") == "ae" + True + >>> userNameToFileName("aE") == "aE_" + True + >>> userNameToFileName("a.alt") == "a.alt" + True + >>> userNameToFileName("A.alt") == "A_.alt" + True + >>> userNameToFileName("A.Alt") == "A_.A_lt" + True + >>> userNameToFileName("A.aLt") == "A_.aL_t" + True + >>> userNameToFileName(u"A.alT") == "A_.alT_" + True + >>> userNameToFileName("T_H") == "T__H_" + True + >>> userNameToFileName("T_h") == "T__h" + True + >>> userNameToFileName("t_h") == "t_h" + True + >>> userNameToFileName("F_F_I") == "F__F__I_" + True + >>> userNameToFileName("f_f_i") == "f_f_i" + True + >>> userNameToFileName("Aacute_V.swash") == "A_acute_V_.swash" + True + >>> userNameToFileName(".notdef") == "_notdef" + True + >>> userNameToFileName("con") == "_con" + True + >>> userNameToFileName("CON") == "C_O_N_" + True + >>> userNameToFileName("con.alt") == "_con.alt" + True + >>> userNameToFileName("alt.con") == "alt._con" + True + """ + # the incoming name must be a str + if not isinstance(userName, str): + raise ValueError("The value for userName must be a string.") + # establish the prefix and suffix lengths + prefixLength = len(prefix) + suffixLength = len(suffix) + # replace an initial period with an _ + # if no prefix is to be added + if not prefix and userName[0] == ".": + userName = "_" + userName[1:] + # filter the user name + filteredUserName = [] + for character in userName: + # replace illegal characters with _ + if character in illegalCharacters: + character = "_" + # add _ to all non-lower characters + elif character != character.lower(): + character += "_" + filteredUserName.append(character) + userName = "".join(filteredUserName) + # clip to 255 + sliceLength = maxFileNameLength - prefixLength - suffixLength + userName = userName[:sliceLength] + # test for illegal files names + parts = [] + for part in userName.split("."): + if part.lower() in reservedFileNames: + part = "_" + part + parts.append(part) + userName = ".".join(parts) + # test for clash + fullName = prefix + userName + suffix + if fullName.lower() in existing: + fullName = handleClash1(userName, existing, prefix, suffix) + # finished + return fullName + + +def handleClash1(userName, existing=[], prefix="", suffix=""): + """ + existing should be a case-insensitive list + of all existing file names. + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = ["a" * 5] + + >>> e = list(existing) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "aaaaa" + "1".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000002.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "AAAAA" + "2".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + """ + # if the prefix length + user name length + suffix length + 15 is at + # or past the maximum length, silce 15 characters off of the user name + prefixLength = len(prefix) + suffixLength = len(suffix) + if prefixLength + len(userName) + suffixLength + 15 > maxFileNameLength: + l = prefixLength + len(userName) + suffixLength + 15 + sliceLength = maxFileNameLength - l + userName = userName[:sliceLength] + finalName = None + # try to add numbers to create a unique name + counter = 1 + while finalName is None: + name = userName + str(counter).zfill(15) + fullName = prefix + name + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= 999999999999999: + break + # if there is a clash, go to the next fallback + if finalName is None: + finalName = handleClash2(existing, prefix, suffix) + # finished + return finalName + + +def handleClash2(existing=[], prefix="", suffix=""): + """ + existing should be a case-insensitive list + of all existing file names. + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = [prefix + str(i) + suffix for i in range(100)] + + >>> e = list(existing) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.100.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "1" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.1.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "2" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.2.0000000000') + True + """ + # calculate the longest possible string + maxLength = maxFileNameLength - len(prefix) - len(suffix) + maxValue = int("9" * maxLength) + # try to find a number + finalName = None + counter = 1 + while finalName is None: + fullName = prefix + str(counter) + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= maxValue: + break + # raise an error if nothing has been found + if finalName is None: + raise NameTranslationError("No unique name could be found.") + # finished + return finalName + + +if __name__ == "__main__": + import doctest + import sys + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/fixedTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/fixedTools.py new file mode 100644 index 00000000..33004287 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/fixedTools.py @@ -0,0 +1,253 @@ +""" +The `OpenType specification `_ +defines two fixed-point data types: + +``Fixed`` + A 32-bit signed fixed-point number with a 16 bit twos-complement + magnitude component and 16 fractional bits. +``F2DOT14`` + A 16-bit signed fixed-point number with a 2 bit twos-complement + magnitude component and 14 fractional bits. + +To support reading and writing data with these data types, this module provides +functions for converting between fixed-point, float and string representations. + +.. data:: MAX_F2DOT14 + + The maximum value that can still fit in an F2Dot14. (1.99993896484375) +""" + +from .roundTools import otRound, nearestMultipleShortestRepr +import logging + +log = logging.getLogger(__name__) + +__all__ = [ + "MAX_F2DOT14", + "fixedToFloat", + "floatToFixed", + "floatToFixedToFloat", + "floatToFixedToStr", + "fixedToStr", + "strToFixed", + "strToFixedToFloat", + "ensureVersionIsLong", + "versionToFixed", +] + + +MAX_F2DOT14 = 0x7FFF / (1 << 14) + + +def fixedToFloat(value, precisionBits): + """Converts a fixed-point number to a float given the number of + precision bits. + + Args: + value (int): Number in fixed-point format. + precisionBits (int): Number of precision bits. + + Returns: + Floating point value. + + Examples:: + + >>> import math + >>> f = fixedToFloat(-10139, precisionBits=14) + >>> math.isclose(f, -0.61883544921875) + True + """ + return value / (1 << precisionBits) + + +def floatToFixed(value, precisionBits): + """Converts a float to a fixed-point number given the number of + precision bits. + + Args: + value (float): Floating point value. + precisionBits (int): Number of precision bits. + + Returns: + int: Fixed-point representation. + + Examples:: + + >>> floatToFixed(-0.61883544921875, precisionBits=14) + -10139 + >>> floatToFixed(-0.61884, precisionBits=14) + -10139 + """ + return otRound(value * (1 << precisionBits)) + + +def floatToFixedToFloat(value, precisionBits): + """Converts a float to a fixed-point number and back again. + + By converting the float to fixed, rounding it, and converting it back + to float again, this returns a floating point values which is exactly + representable in fixed-point format. + + Note: this **is** equivalent to ``fixedToFloat(floatToFixed(value))``. + + Args: + value (float): The input floating point value. + precisionBits (int): Number of precision bits. + + Returns: + float: The transformed and rounded value. + + Examples:: + >>> import math + >>> f1 = -0.61884 + >>> f2 = floatToFixedToFloat(-0.61884, precisionBits=14) + >>> f1 != f2 + True + >>> math.isclose(f2, -0.61883544921875) + True + """ + scale = 1 << precisionBits + return otRound(value * scale) / scale + + +def fixedToStr(value, precisionBits): + """Converts a fixed-point number to a string representing a decimal float. + + This chooses the float that has the shortest decimal representation (the least + number of fractional decimal digits). + + For example, to convert a fixed-point number in a 2.14 format, use + ``precisionBits=14``:: + + >>> fixedToStr(-10139, precisionBits=14) + '-0.61884' + + This is pretty slow compared to the simple division used in ``fixedToFloat``. + Use sporadically when you need to serialize or print the fixed-point number in + a human-readable form. + It uses nearestMultipleShortestRepr under the hood. + + Args: + value (int): The fixed-point value to convert. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + str: A string representation of the value. + """ + scale = 1 << precisionBits + return nearestMultipleShortestRepr(value / scale, factor=1.0 / scale) + + +def strToFixed(string, precisionBits): + """Converts a string representing a decimal float to a fixed-point number. + + Args: + string (str): A string representing a decimal float. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + int: Fixed-point representation. + + Examples:: + + >>> ## to convert a float string to a 2.14 fixed-point number: + >>> strToFixed('-0.61884', precisionBits=14) + -10139 + """ + value = float(string) + return otRound(value * (1 << precisionBits)) + + +def strToFixedToFloat(string, precisionBits): + """Convert a string to a decimal float with fixed-point rounding. + + This first converts string to a float, then turns it into a fixed-point + number with ``precisionBits`` fractional binary digits, then back to a + float again. + + This is simply a shorthand for fixedToFloat(floatToFixed(float(s))). + + Args: + string (str): A string representing a decimal float. + precisionBits (int): Number of precision bits. + + Returns: + float: The transformed and rounded value. + + Examples:: + + >>> import math + >>> s = '-0.61884' + >>> bits = 14 + >>> f = strToFixedToFloat(s, precisionBits=bits) + >>> math.isclose(f, -0.61883544921875) + True + >>> f == fixedToFloat(floatToFixed(float(s), precisionBits=bits), precisionBits=bits) + True + """ + value = float(string) + scale = 1 << precisionBits + return otRound(value * scale) / scale + + +def floatToFixedToStr(value, precisionBits): + """Convert float to string with fixed-point rounding. + + This uses the shortest decimal representation (ie. the least + number of fractional decimal digits) to represent the equivalent + fixed-point number with ``precisionBits`` fractional binary digits. + It uses nearestMultipleShortestRepr under the hood. + + >>> floatToFixedToStr(-0.61883544921875, precisionBits=14) + '-0.61884' + + Args: + value (float): The float value to convert. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + str: A string representation of the value. + + """ + scale = 1 << precisionBits + return nearestMultipleShortestRepr(value, factor=1.0 / scale) + + +def ensureVersionIsLong(value): + """Ensure a table version is an unsigned long. + + OpenType table version numbers are expressed as a single unsigned long + comprising of an unsigned short major version and unsigned short minor + version. This function detects if the value to be used as a version number + looks too small (i.e. is less than ``0x10000``), and converts it to + fixed-point using :func:`floatToFixed` if so. + + Args: + value (Number): a candidate table version number. + + Returns: + int: A table version number, possibly corrected to fixed-point. + """ + if value < 0x10000: + newValue = floatToFixed(value, 16) + log.warning( + "Table version value is a float: %.4f; " "fix to use hex instead: 0x%08x", + value, + newValue, + ) + value = newValue + return value + + +def versionToFixed(value): + """Ensure a table version number is fixed-point. + + Args: + value (str): a candidate table version number. + + Returns: + int: A table version number, possibly corrected to fixed-point. + """ + value = int(value, 0) if value.startswith("0") else float(value) + value = ensureVersionIsLong(value) + return value diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/intTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/intTools.py new file mode 100644 index 00000000..0ca29854 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/intTools.py @@ -0,0 +1,25 @@ +__all__ = ["popCount", "bit_count", "bit_indices"] + + +try: + bit_count = int.bit_count +except AttributeError: + + def bit_count(v): + return bin(v).count("1") + + +"""Return number of 1 bits (population count) of the absolute value of an integer. + +See https://docs.python.org/3.10/library/stdtypes.html#int.bit_count +""" +popCount = bit_count # alias + + +def bit_indices(v): + """Return list of indices where bits are set, 0 being the index of the least significant bit. + + >>> bit_indices(0b101) + [0, 2] + """ + return [i for i, b in enumerate(bin(v)[::-1]) if b == "1"] diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/loggingTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/loggingTools.py new file mode 100644 index 00000000..78704f5a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/loggingTools.py @@ -0,0 +1,543 @@ +import sys +import logging +import timeit +from functools import wraps +from collections.abc import Mapping, Callable +import warnings +from logging import PercentStyle + + +# default logging level used by Timer class +TIME_LEVEL = logging.DEBUG + +# per-level format strings used by the default formatter +# (the level name is not printed for INFO and DEBUG messages) +DEFAULT_FORMATS = { + "*": "%(levelname)s: %(message)s", + "INFO": "%(message)s", + "DEBUG": "%(message)s", +} + + +class LevelFormatter(logging.Formatter): + """Log formatter with level-specific formatting. + + Formatter class which optionally takes a dict of logging levels to + format strings, allowing to customise the log records appearance for + specific levels. + + + Attributes: + fmt: A dictionary mapping logging levels to format strings. + The ``*`` key identifies the default format string. + datefmt: As per py:class:`logging.Formatter` + style: As per py:class:`logging.Formatter` + + >>> import sys + >>> handler = logging.StreamHandler(sys.stdout) + >>> formatter = LevelFormatter( + ... fmt={ + ... '*': '[%(levelname)s] %(message)s', + ... 'DEBUG': '%(name)s [%(levelname)s] %(message)s', + ... 'INFO': '%(message)s', + ... }) + >>> handler.setFormatter(formatter) + >>> log = logging.getLogger('test') + >>> log.setLevel(logging.DEBUG) + >>> log.addHandler(handler) + >>> log.debug('this uses a custom format string') + test [DEBUG] this uses a custom format string + >>> log.info('this also uses a custom format string') + this also uses a custom format string + >>> log.warning("this one uses the default format string") + [WARNING] this one uses the default format string + """ + + def __init__(self, fmt=None, datefmt=None, style="%"): + if style != "%": + raise ValueError( + "only '%' percent style is supported in both python 2 and 3" + ) + if fmt is None: + fmt = DEFAULT_FORMATS + if isinstance(fmt, str): + default_format = fmt + custom_formats = {} + elif isinstance(fmt, Mapping): + custom_formats = dict(fmt) + default_format = custom_formats.pop("*", None) + else: + raise TypeError("fmt must be a str or a dict of str: %r" % fmt) + super(LevelFormatter, self).__init__(default_format, datefmt) + self.default_format = self._fmt + self.custom_formats = {} + for level, fmt in custom_formats.items(): + level = logging._checkLevel(level) + self.custom_formats[level] = fmt + + def format(self, record): + if self.custom_formats: + fmt = self.custom_formats.get(record.levelno, self.default_format) + if self._fmt != fmt: + self._fmt = fmt + # for python >= 3.2, _style needs to be set if _fmt changes + if PercentStyle: + self._style = PercentStyle(fmt) + return super(LevelFormatter, self).format(record) + + +def configLogger(**kwargs): + """A more sophisticated logging system configuation manager. + + This is more or less the same as :py:func:`logging.basicConfig`, + with some additional options and defaults. + + The default behaviour is to create a ``StreamHandler`` which writes to + sys.stderr, set a formatter using the ``DEFAULT_FORMATS`` strings, and add + the handler to the top-level library logger ("fontTools"). + + A number of optional keyword arguments may be specified, which can alter + the default behaviour. + + Args: + + logger: Specifies the logger name or a Logger instance to be + configured. (Defaults to "fontTools" logger). Unlike ``basicConfig``, + this function can be called multiple times to reconfigure a logger. + If the logger or any of its children already exists before the call is + made, they will be reset before the new configuration is applied. + filename: Specifies that a ``FileHandler`` be created, using the + specified filename, rather than a ``StreamHandler``. + filemode: Specifies the mode to open the file, if filename is + specified. (If filemode is unspecified, it defaults to ``a``). + format: Use the specified format string for the handler. This + argument also accepts a dictionary of format strings keyed by + level name, to allow customising the records appearance for + specific levels. The special ``'*'`` key is for 'any other' level. + datefmt: Use the specified date/time format. + level: Set the logger level to the specified level. + stream: Use the specified stream to initialize the StreamHandler. Note + that this argument is incompatible with ``filename`` - if both + are present, ``stream`` is ignored. + handlers: If specified, this should be an iterable of already created + handlers, which will be added to the logger. Any handler in the + list which does not have a formatter assigned will be assigned the + formatter created in this function. + filters: If specified, this should be an iterable of already created + filters. If the ``handlers`` do not already have filters assigned, + these filters will be added to them. + propagate: All loggers have a ``propagate`` attribute which determines + whether to continue searching for handlers up the logging hierarchy. + If not provided, the "propagate" attribute will be set to ``False``. + """ + # using kwargs to enforce keyword-only arguments in py2. + handlers = kwargs.pop("handlers", None) + if handlers is None: + if "stream" in kwargs and "filename" in kwargs: + raise ValueError( + "'stream' and 'filename' should not be " "specified together" + ) + else: + if "stream" in kwargs or "filename" in kwargs: + raise ValueError( + "'stream' or 'filename' should not be " + "specified together with 'handlers'" + ) + if handlers is None: + filename = kwargs.pop("filename", None) + mode = kwargs.pop("filemode", "a") + if filename: + h = logging.FileHandler(filename, mode) + else: + stream = kwargs.pop("stream", None) + h = logging.StreamHandler(stream) + handlers = [h] + # By default, the top-level library logger is configured. + logger = kwargs.pop("logger", "fontTools") + if not logger or isinstance(logger, str): + # empty "" or None means the 'root' logger + logger = logging.getLogger(logger) + # before (re)configuring, reset named logger and its children (if exist) + _resetExistingLoggers(parent=logger.name) + # use DEFAULT_FORMATS if 'format' is None + fs = kwargs.pop("format", None) + dfs = kwargs.pop("datefmt", None) + # XXX: '%' is the only format style supported on both py2 and 3 + style = kwargs.pop("style", "%") + fmt = LevelFormatter(fs, dfs, style) + filters = kwargs.pop("filters", []) + for h in handlers: + if h.formatter is None: + h.setFormatter(fmt) + if not h.filters: + for f in filters: + h.addFilter(f) + logger.addHandler(h) + if logger.name != "root": + # stop searching up the hierarchy for handlers + logger.propagate = kwargs.pop("propagate", False) + # set a custom severity level + level = kwargs.pop("level", None) + if level is not None: + logger.setLevel(level) + if kwargs: + keys = ", ".join(kwargs.keys()) + raise ValueError("Unrecognised argument(s): %s" % keys) + + +def _resetExistingLoggers(parent="root"): + """Reset the logger named 'parent' and all its children to their initial + state, if they already exist in the current configuration. + """ + root = logging.root + # get sorted list of all existing loggers + existing = sorted(root.manager.loggerDict.keys()) + if parent == "root": + # all the existing loggers are children of 'root' + loggers_to_reset = [parent] + existing + elif parent not in existing: + # nothing to do + return + elif parent in existing: + loggers_to_reset = [parent] + # collect children, starting with the entry after parent name + i = existing.index(parent) + 1 + prefixed = parent + "." + pflen = len(prefixed) + num_existing = len(existing) + while i < num_existing: + if existing[i][:pflen] == prefixed: + loggers_to_reset.append(existing[i]) + i += 1 + for name in loggers_to_reset: + if name == "root": + root.setLevel(logging.WARNING) + for h in root.handlers[:]: + root.removeHandler(h) + for f in root.filters[:]: + root.removeFilters(f) + root.disabled = False + else: + logger = root.manager.loggerDict[name] + logger.level = logging.NOTSET + logger.handlers = [] + logger.filters = [] + logger.propagate = True + logger.disabled = False + + +class Timer(object): + """Keeps track of overall time and split/lap times. + + >>> import time + >>> timer = Timer() + >>> time.sleep(0.01) + >>> print("First lap:", timer.split()) + First lap: ... + >>> time.sleep(0.02) + >>> print("Second lap:", timer.split()) + Second lap: ... + >>> print("Overall time:", timer.time()) + Overall time: ... + + Can be used as a context manager inside with-statements. + + >>> with Timer() as t: + ... time.sleep(0.01) + >>> print("%0.3f seconds" % t.elapsed) + 0... seconds + + If initialised with a logger, it can log the elapsed time automatically + upon exiting the with-statement. + + >>> import logging + >>> log = logging.getLogger("my-fancy-timer-logger") + >>> configLogger(logger=log, level="DEBUG", format="%(message)s", stream=sys.stdout) + >>> with Timer(log, 'do something'): + ... time.sleep(0.01) + Took ... to do something + + The same Timer instance, holding a reference to a logger, can be reused + in multiple with-statements, optionally with different messages or levels. + + >>> timer = Timer(log) + >>> with timer(): + ... time.sleep(0.01) + elapsed time: ...s + >>> with timer('redo it', level=logging.INFO): + ... time.sleep(0.02) + Took ... to redo it + + It can also be used as a function decorator to log the time elapsed to run + the decorated function. + + >>> @timer() + ... def test1(): + ... time.sleep(0.01) + >>> @timer('run test 2', level=logging.INFO) + ... def test2(): + ... time.sleep(0.02) + >>> test1() + Took ... to run 'test1' + >>> test2() + Took ... to run test 2 + """ + + # timeit.default_timer choses the most accurate clock for each platform + _time = timeit.default_timer + default_msg = "elapsed time: %(time).3fs" + default_format = "Took %(time).3fs to %(msg)s" + + def __init__(self, logger=None, msg=None, level=None, start=None): + self.reset(start) + if logger is None: + for arg in ("msg", "level"): + if locals().get(arg) is not None: + raise ValueError("'%s' can't be specified without a 'logger'" % arg) + self.logger = logger + self.level = level if level is not None else TIME_LEVEL + self.msg = msg + + def reset(self, start=None): + """Reset timer to 'start_time' or the current time.""" + if start is None: + self.start = self._time() + else: + self.start = start + self.last = self.start + self.elapsed = 0.0 + + def time(self): + """Return the overall time (in seconds) since the timer started.""" + return self._time() - self.start + + def split(self): + """Split and return the lap time (in seconds) in between splits.""" + current = self._time() + self.elapsed = current - self.last + self.last = current + return self.elapsed + + def formatTime(self, msg, time): + """Format 'time' value in 'msg' and return formatted string. + If 'msg' contains a '%(time)' format string, try to use that. + Otherwise, use the predefined 'default_format'. + If 'msg' is empty or None, fall back to 'default_msg'. + """ + if not msg: + msg = self.default_msg + if msg.find("%(time)") < 0: + msg = self.default_format % {"msg": msg, "time": time} + else: + try: + msg = msg % {"time": time} + except (KeyError, ValueError): + pass # skip if the format string is malformed + return msg + + def __enter__(self): + """Start a new lap""" + self.last = self._time() + self.elapsed = 0.0 + return self + + def __exit__(self, exc_type, exc_value, traceback): + """End the current lap. If timer has a logger, log the time elapsed, + using the format string in self.msg (or the default one). + """ + time = self.split() + if self.logger is None or exc_type: + # if there's no logger attached, or if any exception occurred in + # the with-statement, exit without logging the time + return + message = self.formatTime(self.msg, time) + # Allow log handlers to see the individual parts to facilitate things + # like a server accumulating aggregate stats. + msg_parts = {"msg": self.msg, "time": time} + self.logger.log(self.level, message, msg_parts) + + def __call__(self, func_or_msg=None, **kwargs): + """If the first argument is a function, return a decorator which runs + the wrapped function inside Timer's context manager. + Otherwise, treat the first argument as a 'msg' string and return an updated + Timer instance, referencing the same logger. + A 'level' keyword can also be passed to override self.level. + """ + if isinstance(func_or_msg, Callable): + func = func_or_msg + # use the function name when no explicit 'msg' is provided + if not self.msg: + self.msg = "run '%s'" % func.__name__ + + @wraps(func) + def wrapper(*args, **kwds): + with self: + return func(*args, **kwds) + + return wrapper + else: + msg = func_or_msg or kwargs.get("msg") + level = kwargs.get("level", self.level) + return self.__class__(self.logger, msg, level) + + def __float__(self): + return self.elapsed + + def __int__(self): + return int(self.elapsed) + + def __str__(self): + return "%.3f" % self.elapsed + + +class ChannelsFilter(logging.Filter): + """Provides a hierarchical filter for log entries based on channel names. + + Filters out records emitted from a list of enabled channel names, + including their children. It works the same as the ``logging.Filter`` + class, but allows the user to specify multiple channel names. + + >>> import sys + >>> handler = logging.StreamHandler(sys.stdout) + >>> handler.setFormatter(logging.Formatter("%(message)s")) + >>> filter = ChannelsFilter("A.B", "C.D") + >>> handler.addFilter(filter) + >>> root = logging.getLogger() + >>> root.addHandler(handler) + >>> root.setLevel(level=logging.DEBUG) + >>> logging.getLogger('A.B').debug('this record passes through') + this record passes through + >>> logging.getLogger('A.B.C').debug('records from children also pass') + records from children also pass + >>> logging.getLogger('C.D').debug('this one as well') + this one as well + >>> logging.getLogger('A.B.').debug('also this one') + also this one + >>> logging.getLogger('A.F').debug('but this one does not!') + >>> logging.getLogger('C.DE').debug('neither this one!') + """ + + def __init__(self, *names): + self.names = names + self.num = len(names) + self.lengths = {n: len(n) for n in names} + + def filter(self, record): + if self.num == 0: + return True + for name in self.names: + nlen = self.lengths[name] + if name == record.name: + return True + elif record.name.find(name, 0, nlen) == 0 and record.name[nlen] == ".": + return True + return False + + +class CapturingLogHandler(logging.Handler): + def __init__(self, logger, level): + super(CapturingLogHandler, self).__init__(level=level) + self.records = [] + if isinstance(logger, str): + self.logger = logging.getLogger(logger) + else: + self.logger = logger + + def __enter__(self): + self.original_disabled = self.logger.disabled + self.original_level = self.logger.level + self.original_propagate = self.logger.propagate + + self.logger.addHandler(self) + self.logger.setLevel(self.level) + self.logger.disabled = False + self.logger.propagate = False + + return self + + def __exit__(self, type, value, traceback): + self.logger.removeHandler(self) + self.logger.setLevel(self.original_level) + self.logger.disabled = self.original_disabled + self.logger.propagate = self.original_propagate + + return self + + def emit(self, record): + self.records.append(record) + + def assertRegex(self, regexp, msg=None): + import re + + pattern = re.compile(regexp) + for r in self.records: + if pattern.search(r.getMessage()): + return True + if msg is None: + msg = "Pattern '%s' not found in logger records" % regexp + assert 0, msg + + +class LogMixin(object): + """Mixin class that adds logging functionality to another class. + + You can define a new class that subclasses from ``LogMixin`` as well as + other base classes through multiple inheritance. + All instances of that class will have a ``log`` property that returns + a ``logging.Logger`` named after their respective ``.``. + + For example: + + >>> class BaseClass(object): + ... pass + >>> class MyClass(LogMixin, BaseClass): + ... pass + >>> a = MyClass() + >>> isinstance(a.log, logging.Logger) + True + >>> print(a.log.name) + fontTools.misc.loggingTools.MyClass + >>> class AnotherClass(MyClass): + ... pass + >>> b = AnotherClass() + >>> isinstance(b.log, logging.Logger) + True + >>> print(b.log.name) + fontTools.misc.loggingTools.AnotherClass + """ + + @property + def log(self): + if not hasattr(self, "_log"): + name = ".".join((self.__class__.__module__, self.__class__.__name__)) + self._log = logging.getLogger(name) + return self._log + + +def deprecateArgument(name, msg, category=UserWarning): + """Raise a warning about deprecated function argument 'name'.""" + warnings.warn("%r is deprecated; %s" % (name, msg), category=category, stacklevel=3) + + +def deprecateFunction(msg, category=UserWarning): + """Decorator to raise a warning when a deprecated function is called.""" + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + "%r is deprecated; %s" % (func.__name__, msg), + category=category, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + + return decorator + + +if __name__ == "__main__": + import doctest + + sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macCreatorType.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macCreatorType.py new file mode 100644 index 00000000..36b15aca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macCreatorType.py @@ -0,0 +1,56 @@ +from fontTools.misc.textTools import Tag, bytesjoin, strjoin + +try: + import xattr +except ImportError: + xattr = None + + +def _reverseString(s): + s = list(s) + s.reverse() + return strjoin(s) + + +def getMacCreatorAndType(path): + """Returns file creator and file type codes for a path. + + Args: + path (str): A file path. + + Returns: + A tuple of two :py:class:`fontTools.textTools.Tag` objects, the first + representing the file creator and the second representing the + file type. + """ + if xattr is not None: + try: + finderInfo = xattr.getxattr(path, "com.apple.FinderInfo") + except (KeyError, IOError): + pass + else: + fileType = Tag(finderInfo[:4]) + fileCreator = Tag(finderInfo[4:8]) + return fileCreator, fileType + return None, None + + +def setMacCreatorAndType(path, fileCreator, fileType): + """Set file creator and file type codes for a path. + + Note that if the ``xattr`` module is not installed, no action is + taken but no error is raised. + + Args: + path (str): A file path. + fileCreator: A four-character file creator tag. + fileType: A four-character file type tag. + + """ + if xattr is not None: + from fontTools.misc.textTools import pad + + if not all(len(s) == 4 for s in (fileCreator, fileType)): + raise TypeError("arg must be string of 4 chars") + finderInfo = pad(bytesjoin([fileType, fileCreator]), 32) + xattr.setxattr(path, "com.apple.FinderInfo", finderInfo) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macRes.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macRes.py new file mode 100644 index 00000000..f5a6cfe4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/macRes.py @@ -0,0 +1,261 @@ +from io import BytesIO +import struct +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytesjoin, tostr +from collections import OrderedDict +from collections.abc import MutableMapping + + +class ResourceError(Exception): + pass + + +class ResourceReader(MutableMapping): + """Reader for Mac OS resource forks. + + Parses a resource fork and returns resources according to their type. + If run on OS X, this will open the resource fork in the filesystem. + Otherwise, it will open the file itself and attempt to read it as + though it were a resource fork. + + The returned object can be indexed by type and iterated over, + returning in each case a list of py:class:`Resource` objects + representing all the resources of a certain type. + + """ + + def __init__(self, fileOrPath): + """Open a file + + Args: + fileOrPath: Either an object supporting a ``read`` method, an + ``os.PathLike`` object, or a string. + """ + self._resources = OrderedDict() + if hasattr(fileOrPath, "read"): + self.file = fileOrPath + else: + try: + # try reading from the resource fork (only works on OS X) + self.file = self.openResourceFork(fileOrPath) + self._readFile() + return + except (ResourceError, IOError): + # if it fails, use the data fork + self.file = self.openDataFork(fileOrPath) + self._readFile() + + @staticmethod + def openResourceFork(path): + if hasattr(path, "__fspath__"): # support os.PathLike objects + path = path.__fspath__() + with open(path + "/..namedfork/rsrc", "rb") as resfork: + data = resfork.read() + infile = BytesIO(data) + infile.name = path + return infile + + @staticmethod + def openDataFork(path): + with open(path, "rb") as datafork: + data = datafork.read() + infile = BytesIO(data) + infile.name = path + return infile + + def _readFile(self): + self._readHeaderAndMap() + self._readTypeList() + + def _read(self, numBytes, offset=None): + if offset is not None: + try: + self.file.seek(offset) + except OverflowError: + raise ResourceError("Failed to seek offset ('offset' is too large)") + if self.file.tell() != offset: + raise ResourceError("Failed to seek offset (reached EOF)") + try: + data = self.file.read(numBytes) + except OverflowError: + raise ResourceError("Cannot read resource ('numBytes' is too large)") + if len(data) != numBytes: + raise ResourceError("Cannot read resource (not enough data)") + return data + + def _readHeaderAndMap(self): + self.file.seek(0) + headerData = self._read(ResourceForkHeaderSize) + sstruct.unpack(ResourceForkHeader, headerData, self) + # seek to resource map, skip reserved + mapOffset = self.mapOffset + 22 + resourceMapData = self._read(ResourceMapHeaderSize, mapOffset) + sstruct.unpack(ResourceMapHeader, resourceMapData, self) + self.absTypeListOffset = self.mapOffset + self.typeListOffset + self.absNameListOffset = self.mapOffset + self.nameListOffset + + def _readTypeList(self): + absTypeListOffset = self.absTypeListOffset + numTypesData = self._read(2, absTypeListOffset) + (self.numTypes,) = struct.unpack(">H", numTypesData) + absTypeListOffset2 = absTypeListOffset + 2 + for i in range(self.numTypes + 1): + resTypeItemOffset = absTypeListOffset2 + ResourceTypeItemSize * i + resTypeItemData = self._read(ResourceTypeItemSize, resTypeItemOffset) + item = sstruct.unpack(ResourceTypeItem, resTypeItemData) + resType = tostr(item["type"], encoding="mac-roman") + refListOffset = absTypeListOffset + item["refListOffset"] + numRes = item["numRes"] + 1 + resources = self._readReferenceList(resType, refListOffset, numRes) + self._resources[resType] = resources + + def _readReferenceList(self, resType, refListOffset, numRes): + resources = [] + for i in range(numRes): + refOffset = refListOffset + ResourceRefItemSize * i + refData = self._read(ResourceRefItemSize, refOffset) + res = Resource(resType) + res.decompile(refData, self) + resources.append(res) + return resources + + def __getitem__(self, resType): + return self._resources[resType] + + def __delitem__(self, resType): + del self._resources[resType] + + def __setitem__(self, resType, resources): + self._resources[resType] = resources + + def __len__(self): + return len(self._resources) + + def __iter__(self): + return iter(self._resources) + + def keys(self): + return self._resources.keys() + + @property + def types(self): + """A list of the types of resources in the resource fork.""" + return list(self._resources.keys()) + + def countResources(self, resType): + """Return the number of resources of a given type.""" + try: + return len(self[resType]) + except KeyError: + return 0 + + def getIndices(self, resType): + """Returns a list of indices of resources of a given type.""" + numRes = self.countResources(resType) + if numRes: + return list(range(1, numRes + 1)) + else: + return [] + + def getNames(self, resType): + """Return list of names of all resources of a given type.""" + return [res.name for res in self.get(resType, []) if res.name is not None] + + def getIndResource(self, resType, index): + """Return resource of given type located at an index ranging from 1 + to the number of resources for that type, or None if not found. + """ + if index < 1: + return None + try: + res = self[resType][index - 1] + except (KeyError, IndexError): + return None + return res + + def getNamedResource(self, resType, name): + """Return the named resource of given type, else return None.""" + name = tostr(name, encoding="mac-roman") + for res in self.get(resType, []): + if res.name == name: + return res + return None + + def close(self): + if not self.file.closed: + self.file.close() + + +class Resource(object): + """Represents a resource stored within a resource fork. + + Attributes: + type: resource type. + data: resource data. + id: ID. + name: resource name. + attr: attributes. + """ + + def __init__( + self, resType=None, resData=None, resID=None, resName=None, resAttr=None + ): + self.type = resType + self.data = resData + self.id = resID + self.name = resName + self.attr = resAttr + + def decompile(self, refData, reader): + sstruct.unpack(ResourceRefItem, refData, self) + # interpret 3-byte dataOffset as (padded) ULONG to unpack it with struct + (self.dataOffset,) = struct.unpack(">L", bytesjoin([b"\0", self.dataOffset])) + absDataOffset = reader.dataOffset + self.dataOffset + (dataLength,) = struct.unpack(">L", reader._read(4, absDataOffset)) + self.data = reader._read(dataLength) + if self.nameOffset == -1: + return + absNameOffset = reader.absNameListOffset + self.nameOffset + (nameLength,) = struct.unpack("B", reader._read(1, absNameOffset)) + (name,) = struct.unpack(">%ss" % nameLength, reader._read(nameLength)) + self.name = tostr(name, encoding="mac-roman") + + +ResourceForkHeader = """ + > # big endian + dataOffset: L + mapOffset: L + dataLen: L + mapLen: L +""" + +ResourceForkHeaderSize = sstruct.calcsize(ResourceForkHeader) + +ResourceMapHeader = """ + > # big endian + attr: H + typeListOffset: H + nameListOffset: H +""" + +ResourceMapHeaderSize = sstruct.calcsize(ResourceMapHeader) + +ResourceTypeItem = """ + > # big endian + type: 4s + numRes: H + refListOffset: H +""" + +ResourceTypeItemSize = sstruct.calcsize(ResourceTypeItem) + +ResourceRefItem = """ + > # big endian + id: h + nameOffset: h + attr: B + dataOffset: 3s + reserved: L +""" + +ResourceRefItemSize = sstruct.calcsize(ResourceRefItem) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/__init__.py new file mode 100644 index 00000000..066eef38 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/__init__.py @@ -0,0 +1,681 @@ +import collections.abc +import re +from typing import ( + Any, + Callable, + Dict, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Type, + Union, + IO, +) +import warnings +from io import BytesIO +from datetime import datetime +from base64 import b64encode, b64decode +from numbers import Integral +from types import SimpleNamespace +from functools import singledispatch + +from fontTools.misc import etree + +from fontTools.misc.textTools import tostr + + +# By default, we +# - deserialize elements as bytes and +# - serialize bytes as elements. +# Before, on Python 2, we +# - deserialized elements as plistlib.Data objects, in order to +# distinguish them from the built-in str type (which is bytes on python2) +# - serialized bytes as elements (they must have only contained +# ASCII characters in this case) +# You can pass use_builtin_types=[True|False] to the load/dump etc. functions +# to enforce a specific treatment. +# NOTE that unicode type always maps to element, and plistlib.Data +# always maps to element, regardless of use_builtin_types. +USE_BUILTIN_TYPES = True + +XML_DECLARATION = b"""""" + +PLIST_DOCTYPE = ( + b'' +) + + +# Date should conform to a subset of ISO 8601: +# YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z' +_date_parser = re.compile( + r"(?P\d\d\d\d)" + r"(?:-(?P\d\d)" + r"(?:-(?P\d\d)" + r"(?:T(?P\d\d)" + r"(?::(?P\d\d)" + r"(?::(?P\d\d))" + r"?)?)?)?)?Z", + re.ASCII, +) + + +def _date_from_string(s: str) -> datetime: + order = ("year", "month", "day", "hour", "minute", "second") + m = _date_parser.match(s) + if m is None: + raise ValueError(f"Expected ISO 8601 date string, but got '{s:r}'.") + gd = m.groupdict() + lst = [] + for key in order: + val = gd[key] + if val is None: + break + lst.append(int(val)) + # NOTE: mypy doesn't know that lst is 6 elements long. + return datetime(*lst) # type:ignore + + +def _date_to_string(d: datetime) -> str: + return "%04d-%02d-%02dT%02d:%02d:%02dZ" % ( + d.year, + d.month, + d.day, + d.hour, + d.minute, + d.second, + ) + + +class Data: + """Represents binary data when ``use_builtin_types=False.`` + + This class wraps binary data loaded from a plist file when the + ``use_builtin_types`` argument to the loading function (:py:func:`fromtree`, + :py:func:`load`, :py:func:`loads`) is false. + + The actual binary data is retrieved using the ``data`` attribute. + """ + + def __init__(self, data: bytes) -> None: + if not isinstance(data, bytes): + raise TypeError("Expected bytes, found %s" % type(data).__name__) + self.data = data + + @classmethod + def fromBase64(cls, data: Union[bytes, str]) -> "Data": + return cls(b64decode(data)) + + def asBase64(self, maxlinelength: int = 76, indent_level: int = 1) -> bytes: + return _encode_base64( + self.data, maxlinelength=maxlinelength, indent_level=indent_level + ) + + def __eq__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.data == other.data + elif isinstance(other, bytes): + return self.data == other + else: + return NotImplemented + + def __repr__(self) -> str: + return "%s(%s)" % (self.__class__.__name__, repr(self.data)) + + +def _encode_base64( + data: bytes, maxlinelength: Optional[int] = 76, indent_level: int = 1 +) -> bytes: + data = b64encode(data) + if data and maxlinelength: + # split into multiple lines right-justified to 'maxlinelength' chars + indent = b"\n" + b" " * indent_level + max_length = max(16, maxlinelength - len(indent)) + chunks = [] + for i in range(0, len(data), max_length): + chunks.append(indent) + chunks.append(data[i : i + max_length]) + chunks.append(indent) + data = b"".join(chunks) + return data + + +# Mypy does not support recursive type aliases as of 0.782, Pylance does. +# https://github.com/python/mypy/issues/731 +# https://devblogs.microsoft.com/python/pylance-introduces-five-new-features-that-enable-type-magic-for-python-developers/#1-support-for-recursive-type-aliases +PlistEncodable = Union[ + bool, + bytes, + Data, + datetime, + float, + Integral, + Mapping[str, Any], + Sequence[Any], + str, +] + + +class PlistTarget: + """Event handler using the ElementTree Target API that can be + passed to a XMLParser to produce property list objects from XML. + It is based on the CPython plistlib module's _PlistParser class, + but does not use the expat parser. + + >>> from fontTools.misc import etree + >>> parser = etree.XMLParser(target=PlistTarget()) + >>> result = etree.XML( + ... "" + ... " something" + ... " blah" + ... "", + ... parser=parser) + >>> result == {"something": "blah"} + True + + Links: + https://github.com/python/cpython/blob/main/Lib/plistlib.py + http://lxml.de/parsing.html#the-target-parser-interface + """ + + def __init__( + self, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, + ) -> None: + self.stack: List[PlistEncodable] = [] + self.current_key: Optional[str] = None + self.root: Optional[PlistEncodable] = None + if use_builtin_types is None: + self._use_builtin_types = USE_BUILTIN_TYPES + else: + if use_builtin_types is False: + warnings.warn( + "Setting use_builtin_types to False is deprecated and will be " + "removed soon.", + DeprecationWarning, + ) + self._use_builtin_types = use_builtin_types + self._dict_type = dict_type + + def start(self, tag: str, attrib: Mapping[str, str]) -> None: + self._data: List[str] = [] + handler = _TARGET_START_HANDLERS.get(tag) + if handler is not None: + handler(self) + + def end(self, tag: str) -> None: + handler = _TARGET_END_HANDLERS.get(tag) + if handler is not None: + handler(self) + + def data(self, data: str) -> None: + self._data.append(data) + + def close(self) -> PlistEncodable: + if self.root is None: + raise ValueError("No root set.") + return self.root + + # helpers + + def add_object(self, value: PlistEncodable) -> None: + if self.current_key is not None: + stack_top = self.stack[-1] + if not isinstance(stack_top, collections.abc.MutableMapping): + raise ValueError("unexpected element: %r" % stack_top) + stack_top[self.current_key] = value + self.current_key = None + elif not self.stack: + # this is the root object + self.root = value + else: + stack_top = self.stack[-1] + if not isinstance(stack_top, list): + raise ValueError("unexpected element: %r" % stack_top) + stack_top.append(value) + + def get_data(self) -> str: + data = "".join(self._data) + self._data = [] + return data + + +# event handlers + + +def start_dict(self: PlistTarget) -> None: + d = self._dict_type() + self.add_object(d) + self.stack.append(d) + + +def end_dict(self: PlistTarget) -> None: + if self.current_key: + raise ValueError("missing value for key '%s'" % self.current_key) + self.stack.pop() + + +def end_key(self: PlistTarget) -> None: + if self.current_key or not isinstance(self.stack[-1], collections.abc.Mapping): + raise ValueError("unexpected key") + self.current_key = self.get_data() + + +def start_array(self: PlistTarget) -> None: + a: List[PlistEncodable] = [] + self.add_object(a) + self.stack.append(a) + + +def end_array(self: PlistTarget) -> None: + self.stack.pop() + + +def end_true(self: PlistTarget) -> None: + self.add_object(True) + + +def end_false(self: PlistTarget) -> None: + self.add_object(False) + + +def end_integer(self: PlistTarget) -> None: + self.add_object(int(self.get_data())) + + +def end_real(self: PlistTarget) -> None: + self.add_object(float(self.get_data())) + + +def end_string(self: PlistTarget) -> None: + self.add_object(self.get_data()) + + +def end_data(self: PlistTarget) -> None: + if self._use_builtin_types: + self.add_object(b64decode(self.get_data())) + else: + self.add_object(Data.fromBase64(self.get_data())) + + +def end_date(self: PlistTarget) -> None: + self.add_object(_date_from_string(self.get_data())) + + +_TARGET_START_HANDLERS: Dict[str, Callable[[PlistTarget], None]] = { + "dict": start_dict, + "array": start_array, +} + +_TARGET_END_HANDLERS: Dict[str, Callable[[PlistTarget], None]] = { + "dict": end_dict, + "array": end_array, + "key": end_key, + "true": end_true, + "false": end_false, + "integer": end_integer, + "real": end_real, + "string": end_string, + "data": end_data, + "date": end_date, +} + + +# functions to build element tree from plist data + + +def _string_element(value: str, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("string") + el.text = value + return el + + +def _bool_element(value: bool, ctx: SimpleNamespace) -> etree.Element: + if value: + return etree.Element("true") + return etree.Element("false") + + +def _integer_element(value: int, ctx: SimpleNamespace) -> etree.Element: + if -1 << 63 <= value < 1 << 64: + el = etree.Element("integer") + el.text = "%d" % value + return el + raise OverflowError(value) + + +def _real_element(value: float, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("real") + el.text = repr(value) + return el + + +def _dict_element( + d: Mapping[str, PlistEncodable], ctx: SimpleNamespace +) -> etree.Element: + el = etree.Element("dict") + items = d.items() + if ctx.sort_keys: + items = sorted(items) # type: ignore + ctx.indent_level += 1 + for key, value in items: + if not isinstance(key, str): + if ctx.skipkeys: + continue + raise TypeError("keys must be strings") + k = etree.SubElement(el, "key") + k.text = tostr(key, "utf-8") + el.append(_make_element(value, ctx)) + ctx.indent_level -= 1 + return el + + +def _array_element( + array: Sequence[PlistEncodable], ctx: SimpleNamespace +) -> etree.Element: + el = etree.Element("array") + if len(array) == 0: + return el + ctx.indent_level += 1 + for value in array: + el.append(_make_element(value, ctx)) + ctx.indent_level -= 1 + return el + + +def _date_element(date: datetime, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("date") + el.text = _date_to_string(date) + return el + + +def _data_element(data: bytes, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("data") + # NOTE: mypy is confused about whether el.text should be str or bytes. + el.text = _encode_base64( # type: ignore + data, + maxlinelength=(76 if ctx.pretty_print else None), + indent_level=ctx.indent_level, + ) + return el + + +def _string_or_data_element(raw_bytes: bytes, ctx: SimpleNamespace) -> etree.Element: + if ctx.use_builtin_types: + return _data_element(raw_bytes, ctx) + else: + try: + string = raw_bytes.decode(encoding="ascii", errors="strict") + except UnicodeDecodeError: + raise ValueError( + "invalid non-ASCII bytes; use unicode string instead: %r" % raw_bytes + ) + return _string_element(string, ctx) + + +# The following is probably not entirely correct. The signature should take `Any` +# and return `NoReturn`. At the time of this writing, neither mypy nor Pyright +# can deal with singledispatch properly and will apply the signature of the base +# function to all others. Being slightly dishonest makes it type-check and return +# usable typing information for the optimistic case. +@singledispatch +def _make_element(value: PlistEncodable, ctx: SimpleNamespace) -> etree.Element: + raise TypeError("unsupported type: %s" % type(value)) + + +_make_element.register(str)(_string_element) +_make_element.register(bool)(_bool_element) +_make_element.register(Integral)(_integer_element) +_make_element.register(float)(_real_element) +_make_element.register(collections.abc.Mapping)(_dict_element) +_make_element.register(list)(_array_element) +_make_element.register(tuple)(_array_element) +_make_element.register(datetime)(_date_element) +_make_element.register(bytes)(_string_or_data_element) +_make_element.register(bytearray)(_data_element) +_make_element.register(Data)(lambda v, ctx: _data_element(v.data, ctx)) + + +# Public functions to create element tree from plist-compatible python +# data structures and viceversa, for use when (de)serializing GLIF xml. + + +def totree( + value: PlistEncodable, + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, + indent_level: int = 1, +) -> etree.Element: + """Convert a value derived from a plist into an XML tree. + + Args: + value: Any kind of value to be serialized to XML. + sort_keys: Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as ASCII strings or an + exception raised if they cannot be decoded as such. Defaults + to ``True`` if not present. Deprecated. + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Returns: an ``etree`` ``Element`` object. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-ASCII binary data is present + and `use_builtin_types` is false. + """ + if use_builtin_types is None: + use_builtin_types = USE_BUILTIN_TYPES + else: + use_builtin_types = use_builtin_types + context = SimpleNamespace( + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + indent_level=indent_level, + ) + return _make_element(value, context) + + +def fromtree( + tree: etree.Element, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Convert an XML tree to a plist structure. + + Args: + tree: An ``etree`` ``Element``. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: An object (usually a dictionary). + """ + target = PlistTarget(use_builtin_types=use_builtin_types, dict_type=dict_type) + for action, element in etree.iterwalk(tree, events=("start", "end")): + if action == "start": + target.start(element.tag, element.attrib) + elif action == "end": + # if there are no children, parse the leaf's data + if not len(element): + # always pass str, not None + target.data(element.text or "") + target.end(element.tag) + return target.close() + + +# python3 plistlib API + + +def load( + fp: IO[bytes], + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Load a plist file into an object. + + Args: + fp: An opened file. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: + An object (usually a dictionary) representing the top level of + the plist file. + """ + + if not hasattr(fp, "read"): + raise AttributeError("'%s' object has no attribute 'read'" % type(fp).__name__) + target = PlistTarget(use_builtin_types=use_builtin_types, dict_type=dict_type) + parser = etree.XMLParser(target=target) + result = etree.parse(fp, parser=parser) + # lxml returns the target object directly, while ElementTree wraps + # it as the root of an ElementTree object + try: + return result.getroot() + except AttributeError: + return result + + +def loads( + value: bytes, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Load a plist file from a string into an object. + + Args: + value: A bytes string containing a plist. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: + An object (usually a dictionary) representing the top level of + the plist file. + """ + + fp = BytesIO(value) + return load(fp, use_builtin_types=use_builtin_types, dict_type=dict_type) + + +def dump( + value: PlistEncodable, + fp: IO[bytes], + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, +) -> None: + """Write a Python object to a plist file. + + Args: + value: An object to write. + fp: A file opened for writing. + sort_keys (bool): Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as ASCII strings or an + exception raised if they cannot be represented. Defaults + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-representable binary data is present + and `use_builtin_types` is false. + """ + + if not hasattr(fp, "write"): + raise AttributeError("'%s' object has no attribute 'write'" % type(fp).__name__) + root = etree.Element("plist", version="1.0") + el = totree( + value, + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + ) + root.append(el) + tree = etree.ElementTree(root) + # we write the doctype ourselves instead of using the 'doctype' argument + # of 'write' method, becuse lxml will force adding a '\n' even when + # pretty_print is False. + if pretty_print: + header = b"\n".join((XML_DECLARATION, PLIST_DOCTYPE, b"")) + else: + header = XML_DECLARATION + PLIST_DOCTYPE + fp.write(header) + tree.write( # type: ignore + fp, + encoding="utf-8", + pretty_print=pretty_print, + xml_declaration=False, + ) + + +def dumps( + value: PlistEncodable, + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, +) -> bytes: + """Write a Python object to a string in plist format. + + Args: + value: An object to write. + sort_keys (bool): Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as strings or an + exception raised if they cannot be represented. Defaults + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Returns: + string: A plist representation of the Python object. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-representable binary data is present + and `use_builtin_types` is false. + """ + fp = BytesIO() + dump( + value, + fp, + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + ) + return fp.getvalue() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/py.typed b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/plistlib/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py new file mode 100644 index 00000000..cc9ca01c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psCharStrings.py @@ -0,0 +1,1476 @@ +"""psCharStrings.py -- module implementing various kinds of CharStrings: +CFF dictionary data and Type1/Type2 CharStrings. +""" + +from fontTools.misc.fixedTools import ( + fixedToFloat, + floatToFixed, + floatToFixedToStr, + strToFixedToFloat, +) +from fontTools.misc.textTools import bytechr, byteord, bytesjoin, strjoin +from fontTools.pens.boundsPen import BoundsPen +import struct +import logging + + +log = logging.getLogger(__name__) + + +def read_operator(self, b0, data, index): + if b0 == 12: + op = (b0, byteord(data[index])) + index = index + 1 + else: + op = b0 + try: + operator = self.operators[op] + except KeyError: + return None, index + value = self.handle_operator(operator) + return value, index + + +def read_byte(self, b0, data, index): + return b0 - 139, index + + +def read_smallInt1(self, b0, data, index): + b1 = byteord(data[index]) + return (b0 - 247) * 256 + b1 + 108, index + 1 + + +def read_smallInt2(self, b0, data, index): + b1 = byteord(data[index]) + return -(b0 - 251) * 256 - b1 - 108, index + 1 + + +def read_shortInt(self, b0, data, index): + (value,) = struct.unpack(">h", data[index : index + 2]) + return value, index + 2 + + +def read_longInt(self, b0, data, index): + (value,) = struct.unpack(">l", data[index : index + 4]) + return value, index + 4 + + +def read_fixed1616(self, b0, data, index): + (value,) = struct.unpack(">l", data[index : index + 4]) + return fixedToFloat(value, precisionBits=16), index + 4 + + +def read_reserved(self, b0, data, index): + assert NotImplementedError + return NotImplemented, index + + +def read_realNumber(self, b0, data, index): + number = "" + while True: + b = byteord(data[index]) + index = index + 1 + nibble0 = (b & 0xF0) >> 4 + nibble1 = b & 0x0F + if nibble0 == 0xF: + break + number = number + realNibbles[nibble0] + if nibble1 == 0xF: + break + number = number + realNibbles[nibble1] + return float(number), index + + +t1OperandEncoding = [None] * 256 +t1OperandEncoding[0:32] = (32) * [read_operator] +t1OperandEncoding[32:247] = (247 - 32) * [read_byte] +t1OperandEncoding[247:251] = (251 - 247) * [read_smallInt1] +t1OperandEncoding[251:255] = (255 - 251) * [read_smallInt2] +t1OperandEncoding[255] = read_longInt +assert len(t1OperandEncoding) == 256 + +t2OperandEncoding = t1OperandEncoding[:] +t2OperandEncoding[28] = read_shortInt +t2OperandEncoding[255] = read_fixed1616 + +cffDictOperandEncoding = t2OperandEncoding[:] +cffDictOperandEncoding[29] = read_longInt +cffDictOperandEncoding[30] = read_realNumber +cffDictOperandEncoding[255] = read_reserved + + +realNibbles = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + ".", + "E", + "E-", + None, + "-", +] +realNibblesDict = {v: i for i, v in enumerate(realNibbles)} + +maxOpStack = 193 + + +def buildOperatorDict(operatorList): + oper = {} + opc = {} + for item in operatorList: + if len(item) == 2: + oper[item[0]] = item[1] + else: + oper[item[0]] = item[1:] + if isinstance(item[0], tuple): + opc[item[1]] = item[0] + else: + opc[item[1]] = (item[0],) + return oper, opc + + +t2Operators = [ + # opcode name + (1, "hstem"), + (3, "vstem"), + (4, "vmoveto"), + (5, "rlineto"), + (6, "hlineto"), + (7, "vlineto"), + (8, "rrcurveto"), + (10, "callsubr"), + (11, "return"), + (14, "endchar"), + (15, "vsindex"), + (16, "blend"), + (18, "hstemhm"), + (19, "hintmask"), + (20, "cntrmask"), + (21, "rmoveto"), + (22, "hmoveto"), + (23, "vstemhm"), + (24, "rcurveline"), + (25, "rlinecurve"), + (26, "vvcurveto"), + (27, "hhcurveto"), + # (28, 'shortint'), # not really an operator + (29, "callgsubr"), + (30, "vhcurveto"), + (31, "hvcurveto"), + ((12, 0), "ignore"), # dotsection. Yes, there a few very early OTF/CFF + # fonts with this deprecated operator. Just ignore it. + ((12, 3), "and"), + ((12, 4), "or"), + ((12, 5), "not"), + ((12, 8), "store"), + ((12, 9), "abs"), + ((12, 10), "add"), + ((12, 11), "sub"), + ((12, 12), "div"), + ((12, 13), "load"), + ((12, 14), "neg"), + ((12, 15), "eq"), + ((12, 18), "drop"), + ((12, 20), "put"), + ((12, 21), "get"), + ((12, 22), "ifelse"), + ((12, 23), "random"), + ((12, 24), "mul"), + ((12, 26), "sqrt"), + ((12, 27), "dup"), + ((12, 28), "exch"), + ((12, 29), "index"), + ((12, 30), "roll"), + ((12, 34), "hflex"), + ((12, 35), "flex"), + ((12, 36), "hflex1"), + ((12, 37), "flex1"), +] + + +def getIntEncoder(format): + if format == "cff": + twoByteOp = bytechr(28) + fourByteOp = bytechr(29) + elif format == "t1": + twoByteOp = None + fourByteOp = bytechr(255) + else: + assert format == "t2" + twoByteOp = bytechr(28) + fourByteOp = None + + def encodeInt( + value, + fourByteOp=fourByteOp, + bytechr=bytechr, + pack=struct.pack, + unpack=struct.unpack, + twoByteOp=twoByteOp, + ): + if -107 <= value <= 107: + code = bytechr(value + 139) + elif 108 <= value <= 1131: + value = value - 108 + code = bytechr((value >> 8) + 247) + bytechr(value & 0xFF) + elif -1131 <= value <= -108: + value = -value - 108 + code = bytechr((value >> 8) + 251) + bytechr(value & 0xFF) + elif twoByteOp is not None and -32768 <= value <= 32767: + code = twoByteOp + pack(">h", value) + elif fourByteOp is None: + # Backwards compatible hack: due to a previous bug in FontTools, + # 16.16 fixed numbers were written out as 4-byte ints. When + # these numbers were small, they were wrongly written back as + # small ints instead of 4-byte ints, breaking round-tripping. + # This here workaround doesn't do it any better, since we can't + # distinguish anymore between small ints that were supposed to + # be small fixed numbers and small ints that were just small + # ints. Hence the warning. + log.warning( + "4-byte T2 number got passed to the " + "IntType handler. This should happen only when reading in " + "old XML files.\n" + ) + code = bytechr(255) + pack(">l", value) + else: + code = fourByteOp + pack(">l", value) + return code + + return encodeInt + + +encodeIntCFF = getIntEncoder("cff") +encodeIntT1 = getIntEncoder("t1") +encodeIntT2 = getIntEncoder("t2") + + +def encodeFixed(f, pack=struct.pack): + """For T2 only""" + value = floatToFixed(f, precisionBits=16) + if value & 0xFFFF == 0: # check if the fractional part is zero + return encodeIntT2(value >> 16) # encode only the integer part + else: + return b"\xff" + pack(">l", value) # encode the entire fixed point value + + +realZeroBytes = bytechr(30) + bytechr(0xF) + + +def encodeFloat(f): + # For CFF only, used in cffLib + if f == 0.0: # 0.0 == +0.0 == -0.0 + return realZeroBytes + # Note: 14 decimal digits seems to be the limitation for CFF real numbers + # in macOS. However, we use 8 here to match the implementation of AFDKO. + s = "%.8G" % f + if s[:2] == "0.": + s = s[1:] + elif s[:3] == "-0.": + s = "-" + s[2:] + nibbles = [] + while s: + c = s[0] + s = s[1:] + if c == "E": + c2 = s[:1] + if c2 == "-": + s = s[1:] + c = "E-" + elif c2 == "+": + s = s[1:] + nibbles.append(realNibblesDict[c]) + nibbles.append(0xF) + if len(nibbles) % 2: + nibbles.append(0xF) + d = bytechr(30) + for i in range(0, len(nibbles), 2): + d = d + bytechr(nibbles[i] << 4 | nibbles[i + 1]) + return d + + +class CharStringCompileError(Exception): + pass + + +class SimpleT2Decompiler(object): + def __init__(self, localSubrs, globalSubrs, private=None, blender=None): + self.localSubrs = localSubrs + self.localBias = calcSubrBias(localSubrs) + self.globalSubrs = globalSubrs + self.globalBias = calcSubrBias(globalSubrs) + self.private = private + self.blender = blender + self.reset() + + def reset(self): + self.callingStack = [] + self.operandStack = [] + self.hintCount = 0 + self.hintMaskBytes = 0 + self.numRegions = 0 + self.vsIndex = 0 + + def execute(self, charString): + self.callingStack.append(charString) + needsDecompilation = charString.needsDecompilation() + if needsDecompilation: + program = [] + pushToProgram = program.append + else: + pushToProgram = lambda x: None + pushToStack = self.operandStack.append + index = 0 + while True: + token, isOperator, index = charString.getToken(index) + if token is None: + break # we're done! + pushToProgram(token) + if isOperator: + handlerName = "op_" + token + handler = getattr(self, handlerName, None) + if handler is not None: + rv = handler(index) + if rv: + hintMaskBytes, index = rv + pushToProgram(hintMaskBytes) + else: + self.popall() + else: + pushToStack(token) + if needsDecompilation: + charString.setProgram(program) + del self.callingStack[-1] + + def pop(self): + value = self.operandStack[-1] + del self.operandStack[-1] + return value + + def popall(self): + stack = self.operandStack[:] + self.operandStack[:] = [] + return stack + + def push(self, value): + self.operandStack.append(value) + + def op_return(self, index): + if self.operandStack: + pass + + def op_endchar(self, index): + pass + + def op_ignore(self, index): + pass + + def op_callsubr(self, index): + subrIndex = self.pop() + subr = self.localSubrs[subrIndex + self.localBias] + self.execute(subr) + + def op_callgsubr(self, index): + subrIndex = self.pop() + subr = self.globalSubrs[subrIndex + self.globalBias] + self.execute(subr) + + def op_hstem(self, index): + self.countHints() + + def op_vstem(self, index): + self.countHints() + + def op_hstemhm(self, index): + self.countHints() + + def op_vstemhm(self, index): + self.countHints() + + def op_hintmask(self, index): + if not self.hintMaskBytes: + self.countHints() + self.hintMaskBytes = (self.hintCount + 7) // 8 + hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) + return hintMaskBytes, index + + op_cntrmask = op_hintmask + + def countHints(self): + args = self.popall() + self.hintCount = self.hintCount + len(args) // 2 + + # misc + def op_and(self, index): + raise NotImplementedError + + def op_or(self, index): + raise NotImplementedError + + def op_not(self, index): + raise NotImplementedError + + def op_store(self, index): + raise NotImplementedError + + def op_abs(self, index): + raise NotImplementedError + + def op_add(self, index): + raise NotImplementedError + + def op_sub(self, index): + raise NotImplementedError + + def op_div(self, index): + raise NotImplementedError + + def op_load(self, index): + raise NotImplementedError + + def op_neg(self, index): + raise NotImplementedError + + def op_eq(self, index): + raise NotImplementedError + + def op_drop(self, index): + raise NotImplementedError + + def op_put(self, index): + raise NotImplementedError + + def op_get(self, index): + raise NotImplementedError + + def op_ifelse(self, index): + raise NotImplementedError + + def op_random(self, index): + raise NotImplementedError + + def op_mul(self, index): + raise NotImplementedError + + def op_sqrt(self, index): + raise NotImplementedError + + def op_dup(self, index): + raise NotImplementedError + + def op_exch(self, index): + raise NotImplementedError + + def op_index(self, index): + raise NotImplementedError + + def op_roll(self, index): + raise NotImplementedError + + def op_blend(self, index): + if self.numRegions == 0: + self.numRegions = self.private.getNumRegions() + numBlends = self.pop() + numOps = numBlends * (self.numRegions + 1) + if self.blender is None: + del self.operandStack[ + -(numOps - numBlends) : + ] # Leave the default operands on the stack. + else: + argi = len(self.operandStack) - numOps + end_args = tuplei = argi + numBlends + while argi < end_args: + next_ti = tuplei + self.numRegions + deltas = self.operandStack[tuplei:next_ti] + delta = self.blender(self.vsIndex, deltas) + self.operandStack[argi] += delta + tuplei = next_ti + argi += 1 + self.operandStack[end_args:] = [] + + def op_vsindex(self, index): + vi = self.pop() + self.vsIndex = vi + self.numRegions = self.private.getNumRegions(vi) + + +t1Operators = [ + # opcode name + (1, "hstem"), + (3, "vstem"), + (4, "vmoveto"), + (5, "rlineto"), + (6, "hlineto"), + (7, "vlineto"), + (8, "rrcurveto"), + (9, "closepath"), + (10, "callsubr"), + (11, "return"), + (13, "hsbw"), + (14, "endchar"), + (21, "rmoveto"), + (22, "hmoveto"), + (30, "vhcurveto"), + (31, "hvcurveto"), + ((12, 0), "dotsection"), + ((12, 1), "vstem3"), + ((12, 2), "hstem3"), + ((12, 6), "seac"), + ((12, 7), "sbw"), + ((12, 12), "div"), + ((12, 16), "callothersubr"), + ((12, 17), "pop"), + ((12, 33), "setcurrentpoint"), +] + + +class T2WidthExtractor(SimpleT2Decompiler): + def __init__( + self, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private=None, + blender=None, + ): + SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs, private, blender) + self.nominalWidthX = nominalWidthX + self.defaultWidthX = defaultWidthX + + def reset(self): + SimpleT2Decompiler.reset(self) + self.gotWidth = 0 + self.width = 0 + + def popallWidth(self, evenOdd=0): + args = self.popall() + if not self.gotWidth: + if evenOdd ^ (len(args) % 2): + # For CFF2 charstrings, this should never happen + assert ( + self.defaultWidthX is not None + ), "CFF2 CharStrings must not have an initial width value" + self.width = self.nominalWidthX + args[0] + args = args[1:] + else: + self.width = self.defaultWidthX + self.gotWidth = 1 + return args + + def countHints(self): + args = self.popallWidth() + self.hintCount = self.hintCount + len(args) // 2 + + def op_rmoveto(self, index): + self.popallWidth() + + def op_hmoveto(self, index): + self.popallWidth(1) + + def op_vmoveto(self, index): + self.popallWidth(1) + + def op_endchar(self, index): + self.popallWidth() + + +class T2OutlineExtractor(T2WidthExtractor): + def __init__( + self, + pen, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private=None, + blender=None, + ): + T2WidthExtractor.__init__( + self, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private, + blender, + ) + self.pen = pen + self.subrLevel = 0 + + def reset(self): + T2WidthExtractor.reset(self) + self.currentPoint = (0, 0) + self.sawMoveTo = 0 + self.subrLevel = 0 + + def execute(self, charString): + self.subrLevel += 1 + super().execute(charString) + self.subrLevel -= 1 + if self.subrLevel == 0: + self.endPath() + + def _nextPoint(self, point): + x, y = self.currentPoint + point = x + point[0], y + point[1] + self.currentPoint = point + return point + + def rMoveTo(self, point): + self.pen.moveTo(self._nextPoint(point)) + self.sawMoveTo = 1 + + def rLineTo(self, point): + if not self.sawMoveTo: + self.rMoveTo((0, 0)) + self.pen.lineTo(self._nextPoint(point)) + + def rCurveTo(self, pt1, pt2, pt3): + if not self.sawMoveTo: + self.rMoveTo((0, 0)) + nextPoint = self._nextPoint + self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) + + def closePath(self): + if self.sawMoveTo: + self.pen.closePath() + self.sawMoveTo = 0 + + def endPath(self): + # In T2 there are no open paths, so always do a closePath when + # finishing a sub path. We avoid spurious calls to closePath() + # because its a real T1 op we're emulating in T2 whereas + # endPath() is just a means to that emulation + if self.sawMoveTo: + self.closePath() + + # + # hint operators + # + # def op_hstem(self, index): + # self.countHints() + # def op_vstem(self, index): + # self.countHints() + # def op_hstemhm(self, index): + # self.countHints() + # def op_vstemhm(self, index): + # self.countHints() + # def op_hintmask(self, index): + # self.countHints() + # def op_cntrmask(self, index): + # self.countHints() + + # + # path constructors, moveto + # + def op_rmoveto(self, index): + self.endPath() + self.rMoveTo(self.popallWidth()) + + def op_hmoveto(self, index): + self.endPath() + self.rMoveTo((self.popallWidth(1)[0], 0)) + + def op_vmoveto(self, index): + self.endPath() + self.rMoveTo((0, self.popallWidth(1)[0])) + + def op_endchar(self, index): + self.endPath() + args = self.popallWidth() + if args: + from fontTools.encodings.StandardEncoding import StandardEncoding + + # endchar can do seac accent bulding; The T2 spec says it's deprecated, + # but recent software that shall remain nameless does output it. + adx, ady, bchar, achar = args + baseGlyph = StandardEncoding[bchar] + self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) + accentGlyph = StandardEncoding[achar] + self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) + + # + # path constructors, lines + # + def op_rlineto(self, index): + args = self.popall() + for i in range(0, len(args), 2): + point = args[i : i + 2] + self.rLineTo(point) + + def op_hlineto(self, index): + self.alternatingLineto(1) + + def op_vlineto(self, index): + self.alternatingLineto(0) + + # + # path constructors, curves + # + def op_rrcurveto(self, index): + """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" + args = self.popall() + for i in range(0, len(args), 6): + ( + dxa, + dya, + dxb, + dyb, + dxc, + dyc, + ) = args[i : i + 6] + self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) + + def op_rcurveline(self, index): + """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" + args = self.popall() + for i in range(0, len(args) - 2, 6): + dxb, dyb, dxc, dyc, dxd, dyd = args[i : i + 6] + self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) + self.rLineTo(args[-2:]) + + def op_rlinecurve(self, index): + """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" + args = self.popall() + lineArgs = args[:-6] + for i in range(0, len(lineArgs), 2): + self.rLineTo(lineArgs[i : i + 2]) + dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] + self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) + + def op_vvcurveto(self, index): + "dx1? {dya dxb dyb dyc}+ vvcurveto" + args = self.popall() + if len(args) % 2: + dx1 = args[0] + args = args[1:] + else: + dx1 = 0 + for i in range(0, len(args), 4): + dya, dxb, dyb, dyc = args[i : i + 4] + self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) + dx1 = 0 + + def op_hhcurveto(self, index): + """dy1? {dxa dxb dyb dxc}+ hhcurveto""" + args = self.popall() + if len(args) % 2: + dy1 = args[0] + args = args[1:] + else: + dy1 = 0 + for i in range(0, len(args), 4): + dxa, dxb, dyb, dxc = args[i : i + 4] + self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) + dy1 = 0 + + def op_vhcurveto(self, index): + """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) + {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto + """ + args = self.popall() + while args: + args = self.vcurveto(args) + if args: + args = self.hcurveto(args) + + def op_hvcurveto(self, index): + """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? + {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? + """ + args = self.popall() + while args: + args = self.hcurveto(args) + if args: + args = self.vcurveto(args) + + # + # path constructors, flex + # + def op_hflex(self, index): + dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() + dy1 = dy3 = dy4 = dy6 = 0 + dy5 = -dy2 + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_flex(self, index): + dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_hflex1(self, index): + dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() + dy3 = dy4 = 0 + dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) + + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_flex1(self, index): + dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() + dx = dx1 + dx2 + dx3 + dx4 + dx5 + dy = dy1 + dy2 + dy3 + dy4 + dy5 + if abs(dx) > abs(dy): + dx6 = d6 + dy6 = -dy + else: + dx6 = -dx + dy6 = d6 + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + # misc + def op_and(self, index): + raise NotImplementedError + + def op_or(self, index): + raise NotImplementedError + + def op_not(self, index): + raise NotImplementedError + + def op_store(self, index): + raise NotImplementedError + + def op_abs(self, index): + raise NotImplementedError + + def op_add(self, index): + raise NotImplementedError + + def op_sub(self, index): + raise NotImplementedError + + def op_div(self, index): + num2 = self.pop() + num1 = self.pop() + d1 = num1 // num2 + d2 = num1 / num2 + if d1 == d2: + self.push(d1) + else: + self.push(d2) + + def op_load(self, index): + raise NotImplementedError + + def op_neg(self, index): + raise NotImplementedError + + def op_eq(self, index): + raise NotImplementedError + + def op_drop(self, index): + raise NotImplementedError + + def op_put(self, index): + raise NotImplementedError + + def op_get(self, index): + raise NotImplementedError + + def op_ifelse(self, index): + raise NotImplementedError + + def op_random(self, index): + raise NotImplementedError + + def op_mul(self, index): + raise NotImplementedError + + def op_sqrt(self, index): + raise NotImplementedError + + def op_dup(self, index): + raise NotImplementedError + + def op_exch(self, index): + raise NotImplementedError + + def op_index(self, index): + raise NotImplementedError + + def op_roll(self, index): + raise NotImplementedError + + # + # miscellaneous helpers + # + def alternatingLineto(self, isHorizontal): + args = self.popall() + for arg in args: + if isHorizontal: + point = (arg, 0) + else: + point = (0, arg) + self.rLineTo(point) + isHorizontal = not isHorizontal + + def vcurveto(self, args): + dya, dxb, dyb, dxc = args[:4] + args = args[4:] + if len(args) == 1: + dyc = args[0] + args = [] + else: + dyc = 0 + self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) + return args + + def hcurveto(self, args): + dxa, dxb, dyb, dyc = args[:4] + args = args[4:] + if len(args) == 1: + dxc = args[0] + args = [] + else: + dxc = 0 + self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) + return args + + +class T1OutlineExtractor(T2OutlineExtractor): + def __init__(self, pen, subrs): + self.pen = pen + self.subrs = subrs + self.reset() + + def reset(self): + self.flexing = 0 + self.width = 0 + self.sbx = 0 + T2OutlineExtractor.reset(self) + + def endPath(self): + if self.sawMoveTo: + self.pen.endPath() + self.sawMoveTo = 0 + + def popallWidth(self, evenOdd=0): + return self.popall() + + def exch(self): + stack = self.operandStack + stack[-1], stack[-2] = stack[-2], stack[-1] + + # + # path constructors + # + def op_rmoveto(self, index): + if self.flexing: + return + self.endPath() + self.rMoveTo(self.popall()) + + def op_hmoveto(self, index): + if self.flexing: + # We must add a parameter to the stack if we are flexing + self.push(0) + return + self.endPath() + self.rMoveTo((self.popall()[0], 0)) + + def op_vmoveto(self, index): + if self.flexing: + # We must add a parameter to the stack if we are flexing + self.push(0) + self.exch() + return + self.endPath() + self.rMoveTo((0, self.popall()[0])) + + def op_closepath(self, index): + self.closePath() + + def op_setcurrentpoint(self, index): + args = self.popall() + x, y = args + self.currentPoint = x, y + + def op_endchar(self, index): + self.endPath() + + def op_hsbw(self, index): + sbx, wx = self.popall() + self.width = wx + self.sbx = sbx + self.currentPoint = sbx, self.currentPoint[1] + + def op_sbw(self, index): + self.popall() # XXX + + # + def op_callsubr(self, index): + subrIndex = self.pop() + subr = self.subrs[subrIndex] + self.execute(subr) + + def op_callothersubr(self, index): + subrIndex = self.pop() + nArgs = self.pop() + # print nArgs, subrIndex, "callothersubr" + if subrIndex == 0 and nArgs == 3: + self.doFlex() + self.flexing = 0 + elif subrIndex == 1 and nArgs == 0: + self.flexing = 1 + # ignore... + + def op_pop(self, index): + pass # ignore... + + def doFlex(self): + finaly = self.pop() + finalx = self.pop() + self.pop() # flex height is unused + + p3y = self.pop() + p3x = self.pop() + bcp4y = self.pop() + bcp4x = self.pop() + bcp3y = self.pop() + bcp3x = self.pop() + p2y = self.pop() + p2x = self.pop() + bcp2y = self.pop() + bcp2x = self.pop() + bcp1y = self.pop() + bcp1x = self.pop() + rpy = self.pop() + rpx = self.pop() + + # call rrcurveto + self.push(bcp1x + rpx) + self.push(bcp1y + rpy) + self.push(bcp2x) + self.push(bcp2y) + self.push(p2x) + self.push(p2y) + self.op_rrcurveto(None) + + # call rrcurveto + self.push(bcp3x) + self.push(bcp3y) + self.push(bcp4x) + self.push(bcp4y) + self.push(p3x) + self.push(p3y) + self.op_rrcurveto(None) + + # Push back final coords so subr 0 can find them + self.push(finalx) + self.push(finaly) + + def op_dotsection(self, index): + self.popall() # XXX + + def op_hstem3(self, index): + self.popall() # XXX + + def op_seac(self, index): + "asb adx ady bchar achar seac" + from fontTools.encodings.StandardEncoding import StandardEncoding + + asb, adx, ady, bchar, achar = self.popall() + baseGlyph = StandardEncoding[bchar] + self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) + accentGlyph = StandardEncoding[achar] + adx = adx + self.sbx - asb # seac weirdness + self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) + + def op_vstem3(self, index): + self.popall() # XXX + + +class T2CharString(object): + operandEncoding = t2OperandEncoding + operators, opcodes = buildOperatorDict(t2Operators) + decompilerClass = SimpleT2Decompiler + outlineExtractor = T2OutlineExtractor + + def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): + if program is None: + program = [] + self.bytecode = bytecode + self.program = program + self.private = private + self.globalSubrs = globalSubrs if globalSubrs is not None else [] + self._cur_vsindex = None + + def getNumRegions(self, vsindex=None): + pd = self.private + assert pd is not None + if vsindex is not None: + self._cur_vsindex = vsindex + elif self._cur_vsindex is None: + self._cur_vsindex = pd.vsindex if hasattr(pd, "vsindex") else 0 + return pd.getNumRegions(self._cur_vsindex) + + def __repr__(self): + if self.bytecode is None: + return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) + else: + return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) + + def getIntEncoder(self): + return encodeIntT2 + + def getFixedEncoder(self): + return encodeFixed + + def decompile(self): + if not self.needsDecompilation(): + return + subrs = getattr(self.private, "Subrs", []) + decompiler = self.decompilerClass(subrs, self.globalSubrs, self.private) + decompiler.execute(self) + + def draw(self, pen, blender=None): + subrs = getattr(self.private, "Subrs", []) + extractor = self.outlineExtractor( + pen, + subrs, + self.globalSubrs, + self.private.nominalWidthX, + self.private.defaultWidthX, + self.private, + blender, + ) + extractor.execute(self) + self.width = extractor.width + + def calcBounds(self, glyphSet): + boundsPen = BoundsPen(glyphSet) + self.draw(boundsPen) + return boundsPen.bounds + + def compile(self, isCFF2=False): + if self.bytecode is not None: + return + opcodes = self.opcodes + program = self.program + + if isCFF2: + # If present, remove return and endchar operators. + if program and program[-1] in ("return", "endchar"): + program = program[:-1] + elif program and not isinstance(program[-1], str): + raise CharStringCompileError( + "T2CharString or Subr has items on the stack after last operator." + ) + + bytecode = [] + encodeInt = self.getIntEncoder() + encodeFixed = self.getFixedEncoder() + i = 0 + end = len(program) + while i < end: + token = program[i] + i = i + 1 + if isinstance(token, str): + try: + bytecode.extend(bytechr(b) for b in opcodes[token]) + except KeyError: + raise CharStringCompileError("illegal operator: %s" % token) + if token in ("hintmask", "cntrmask"): + bytecode.append(program[i]) # hint mask + i = i + 1 + elif isinstance(token, int): + bytecode.append(encodeInt(token)) + elif isinstance(token, float): + bytecode.append(encodeFixed(token)) + else: + assert 0, "unsupported type: %s" % type(token) + try: + bytecode = bytesjoin(bytecode) + except TypeError: + log.error(bytecode) + raise + self.setBytecode(bytecode) + + def needsDecompilation(self): + return self.bytecode is not None + + def setProgram(self, program): + self.program = program + self.bytecode = None + + def setBytecode(self, bytecode): + self.bytecode = bytecode + self.program = None + + def getToken(self, index, len=len, byteord=byteord, isinstance=isinstance): + if self.bytecode is not None: + if index >= len(self.bytecode): + return None, 0, 0 + b0 = byteord(self.bytecode[index]) + index = index + 1 + handler = self.operandEncoding[b0] + token, index = handler(self, b0, self.bytecode, index) + else: + if index >= len(self.program): + return None, 0, 0 + token = self.program[index] + index = index + 1 + isOperator = isinstance(token, str) + return token, isOperator, index + + def getBytes(self, index, nBytes): + if self.bytecode is not None: + newIndex = index + nBytes + bytes = self.bytecode[index:newIndex] + index = newIndex + else: + bytes = self.program[index] + index = index + 1 + assert len(bytes) == nBytes + return bytes, index + + def handle_operator(self, operator): + return operator + + def toXML(self, xmlWriter, ttFont=None): + from fontTools.misc.textTools import num2binary + + if self.bytecode is not None: + xmlWriter.dumphex(self.bytecode) + else: + index = 0 + args = [] + while True: + token, isOperator, index = self.getToken(index) + if token is None: + break + if isOperator: + if token in ("hintmask", "cntrmask"): + hintMask, isOperator, index = self.getToken(index) + bits = [] + for byte in hintMask: + bits.append(num2binary(byteord(byte), 8)) + hintMask = strjoin(bits) + line = " ".join(args + [token, hintMask]) + else: + line = " ".join(args + [token]) + xmlWriter.write(line) + xmlWriter.newline() + args = [] + else: + if isinstance(token, float): + token = floatToFixedToStr(token, precisionBits=16) + else: + token = str(token) + args.append(token) + if args: + # NOTE: only CFF2 charstrings/subrs can have numeric arguments on + # the stack after the last operator. Compiling this would fail if + # this is part of CFF 1.0 table. + line = " ".join(args) + xmlWriter.write(line) + + def fromXML(self, name, attrs, content): + from fontTools.misc.textTools import binary2num, readHex + + if attrs.get("raw"): + self.setBytecode(readHex(content)) + return + content = strjoin(content) + content = content.split() + program = [] + end = len(content) + i = 0 + while i < end: + token = content[i] + i = i + 1 + try: + token = int(token) + except ValueError: + try: + token = strToFixedToFloat(token, precisionBits=16) + except ValueError: + program.append(token) + if token in ("hintmask", "cntrmask"): + mask = content[i] + maskBytes = b"" + for j in range(0, len(mask), 8): + maskBytes = maskBytes + bytechr(binary2num(mask[j : j + 8])) + program.append(maskBytes) + i = i + 1 + else: + program.append(token) + else: + program.append(token) + self.setProgram(program) + + +class T1CharString(T2CharString): + operandEncoding = t1OperandEncoding + operators, opcodes = buildOperatorDict(t1Operators) + + def __init__(self, bytecode=None, program=None, subrs=None): + super().__init__(bytecode, program) + self.subrs = subrs + + def getIntEncoder(self): + return encodeIntT1 + + def getFixedEncoder(self): + def encodeFixed(value): + raise TypeError("Type 1 charstrings don't support floating point operands") + + def decompile(self): + if self.bytecode is None: + return + program = [] + index = 0 + while True: + token, isOperator, index = self.getToken(index) + if token is None: + break + program.append(token) + self.setProgram(program) + + def draw(self, pen): + extractor = T1OutlineExtractor(pen, self.subrs) + extractor.execute(self) + self.width = extractor.width + + +class DictDecompiler(object): + operandEncoding = cffDictOperandEncoding + + def __init__(self, strings, parent=None): + self.stack = [] + self.strings = strings + self.dict = {} + self.parent = parent + + def getDict(self): + assert len(self.stack) == 0, "non-empty stack" + return self.dict + + def decompile(self, data): + index = 0 + lenData = len(data) + push = self.stack.append + while index < lenData: + b0 = byteord(data[index]) + index = index + 1 + handler = self.operandEncoding[b0] + value, index = handler(self, b0, data, index) + if value is not None: + push(value) + + def pop(self): + value = self.stack[-1] + del self.stack[-1] + return value + + def popall(self): + args = self.stack[:] + del self.stack[:] + return args + + def handle_operator(self, operator): + operator, argType = operator + if isinstance(argType, tuple): + value = () + for i in range(len(argType) - 1, -1, -1): + arg = argType[i] + arghandler = getattr(self, "arg_" + arg) + value = (arghandler(operator),) + value + else: + arghandler = getattr(self, "arg_" + argType) + value = arghandler(operator) + if operator == "blend": + self.stack.extend(value) + else: + self.dict[operator] = value + + def arg_number(self, name): + if isinstance(self.stack[0], list): + out = self.arg_blend_number(self.stack) + else: + out = self.pop() + return out + + def arg_blend_number(self, name): + out = [] + blendArgs = self.pop() + numMasters = len(blendArgs) + out.append(blendArgs) + out.append("blend") + dummy = self.popall() + return blendArgs + + def arg_SID(self, name): + return self.strings[self.pop()] + + def arg_array(self, name): + return self.popall() + + def arg_blendList(self, name): + """ + There may be non-blend args at the top of the stack. We first calculate + where the blend args start in the stack. These are the last + numMasters*numBlends) +1 args. + The blend args starts with numMasters relative coordinate values, the BlueValues in the list from the default master font. This is followed by + numBlends list of values. Each of value in one of these lists is the + Variable Font delta for the matching region. + + We re-arrange this to be a list of numMaster entries. Each entry starts with the corresponding default font relative value, and is followed by + the delta values. We then convert the default values, the first item in each entry, to an absolute value. + """ + vsindex = self.dict.get("vsindex", 0) + numMasters = ( + self.parent.getNumRegions(vsindex) + 1 + ) # only a PrivateDict has blended ops. + numBlends = self.pop() + args = self.popall() + numArgs = len(args) + # The spec says that there should be no non-blended Blue Values,. + assert numArgs == numMasters * numBlends + value = [None] * numBlends + numDeltas = numMasters - 1 + i = 0 + prevVal = 0 + while i < numBlends: + newVal = args[i] + prevVal + prevVal = newVal + masterOffset = numBlends + (i * numDeltas) + blendList = [newVal] + args[masterOffset : masterOffset + numDeltas] + value[i] = blendList + i += 1 + return value + + def arg_delta(self, name): + valueList = self.popall() + out = [] + if valueList and isinstance(valueList[0], list): + # arg_blendList() has already converted these to absolute values. + out = valueList + else: + current = 0 + for v in valueList: + current = current + v + out.append(current) + return out + + +def calcSubrBias(subrs): + nSubrs = len(subrs) + if nSubrs < 1240: + bias = 107 + elif nSubrs < 33900: + bias = 1131 + else: + bias = 32768 + return bias diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psLib.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psLib.py new file mode 100644 index 00000000..3bfdb4ae --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psLib.py @@ -0,0 +1,398 @@ +from fontTools.misc.textTools import bytechr, byteord, bytesjoin, tobytes, tostr +from fontTools.misc import eexec +from .psOperators import ( + PSOperators, + ps_StandardEncoding, + ps_array, + ps_boolean, + ps_dict, + ps_integer, + ps_literal, + ps_mark, + ps_name, + ps_operator, + ps_procedure, + ps_procmark, + ps_real, + ps_string, +) +import re +from collections.abc import Callable +from string import whitespace +import logging + + +log = logging.getLogger(__name__) + +ps_special = b"()<>[]{}%" # / is one too, but we take care of that one differently + +skipwhiteRE = re.compile(bytesjoin([b"[", whitespace, b"]*"])) +endofthingPat = bytesjoin([b"[^][(){}<>/%", whitespace, b"]*"]) +endofthingRE = re.compile(endofthingPat) +commentRE = re.compile(b"%[^\n\r]*") + +# XXX This not entirely correct as it doesn't allow *nested* embedded parens: +stringPat = rb""" + \( + ( + ( + [^()]* \ [()] + ) + | + ( + [^()]* \( [^()]* \) + ) + )* + [^()]* + \) +""" +stringPat = b"".join(stringPat.split()) +stringRE = re.compile(stringPat) + +hexstringRE = re.compile(bytesjoin([b"<[", whitespace, b"0-9A-Fa-f]*>"])) + + +class PSTokenError(Exception): + pass + + +class PSError(Exception): + pass + + +class PSTokenizer(object): + def __init__(self, buf=b"", encoding="ascii"): + # Force self.buf to be a byte string + buf = tobytes(buf) + self.buf = buf + self.len = len(buf) + self.pos = 0 + self.closed = False + self.encoding = encoding + + def read(self, n=-1): + """Read at most 'n' bytes from the buffer, or less if the read + hits EOF before obtaining 'n' bytes. + If 'n' is negative or omitted, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + if n is None or n < 0: + newpos = self.len + else: + newpos = min(self.pos + n, self.len) + r = self.buf[self.pos : newpos] + self.pos = newpos + return r + + def close(self): + if not self.closed: + self.closed = True + del self.buf, self.pos + + def getnexttoken( + self, + # localize some stuff, for performance + len=len, + ps_special=ps_special, + stringmatch=stringRE.match, + hexstringmatch=hexstringRE.match, + commentmatch=commentRE.match, + endmatch=endofthingRE.match, + ): + self.skipwhite() + if self.pos >= self.len: + return None, None + pos = self.pos + buf = self.buf + char = bytechr(byteord(buf[pos])) + if char in ps_special: + if char in b"{}[]": + tokentype = "do_special" + token = char + elif char == b"%": + tokentype = "do_comment" + _, nextpos = commentmatch(buf, pos).span() + token = buf[pos:nextpos] + elif char == b"(": + tokentype = "do_string" + m = stringmatch(buf, pos) + if m is None: + raise PSTokenError("bad string at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + elif char == b"<": + tokentype = "do_hexstring" + m = hexstringmatch(buf, pos) + if m is None: + raise PSTokenError("bad hexstring at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + else: + raise PSTokenError("bad token at character %d" % pos) + else: + if char == b"/": + tokentype = "do_literal" + m = endmatch(buf, pos + 1) + else: + tokentype = "" + m = endmatch(buf, pos) + if m is None: + raise PSTokenError("bad token at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + self.pos = pos + len(token) + token = tostr(token, encoding=self.encoding) + return tokentype, token + + def skipwhite(self, whitematch=skipwhiteRE.match): + _, nextpos = whitematch(self.buf, self.pos).span() + self.pos = nextpos + + def starteexec(self): + self.pos = self.pos + 1 + self.dirtybuf = self.buf[self.pos :] + self.buf, R = eexec.decrypt(self.dirtybuf, 55665) + self.len = len(self.buf) + self.pos = 4 + + def stopeexec(self): + if not hasattr(self, "dirtybuf"): + return + self.buf = self.dirtybuf + del self.dirtybuf + + +class PSInterpreter(PSOperators): + def __init__(self, encoding="ascii"): + systemdict = {} + userdict = {} + self.encoding = encoding + self.dictstack = [systemdict, userdict] + self.stack = [] + self.proclevel = 0 + self.procmark = ps_procmark() + self.fillsystemdict() + + def fillsystemdict(self): + systemdict = self.dictstack[0] + systemdict["["] = systemdict["mark"] = self.mark = ps_mark() + systemdict["]"] = ps_operator("]", self.do_makearray) + systemdict["true"] = ps_boolean(1) + systemdict["false"] = ps_boolean(0) + systemdict["StandardEncoding"] = ps_array(ps_StandardEncoding) + systemdict["FontDirectory"] = ps_dict({}) + self.suckoperators(systemdict, self.__class__) + + def suckoperators(self, systemdict, klass): + for name in dir(klass): + attr = getattr(self, name) + if isinstance(attr, Callable) and name[:3] == "ps_": + name = name[3:] + systemdict[name] = ps_operator(name, attr) + for baseclass in klass.__bases__: + self.suckoperators(systemdict, baseclass) + + def interpret(self, data, getattr=getattr): + tokenizer = self.tokenizer = PSTokenizer(data, self.encoding) + getnexttoken = tokenizer.getnexttoken + do_token = self.do_token + handle_object = self.handle_object + try: + while 1: + tokentype, token = getnexttoken() + if not token: + break + if tokentype: + handler = getattr(self, tokentype) + object = handler(token) + else: + object = do_token(token) + if object is not None: + handle_object(object) + tokenizer.close() + self.tokenizer = None + except: + if self.tokenizer is not None: + log.debug( + "ps error:\n" + "- - - - - - -\n" + "%s\n" + ">>>\n" + "%s\n" + "- - - - - - -", + self.tokenizer.buf[self.tokenizer.pos - 50 : self.tokenizer.pos], + self.tokenizer.buf[self.tokenizer.pos : self.tokenizer.pos + 50], + ) + raise + + def handle_object(self, object): + if not (self.proclevel or object.literal or object.type == "proceduretype"): + if object.type != "operatortype": + object = self.resolve_name(object.value) + if object.literal: + self.push(object) + else: + if object.type == "proceduretype": + self.call_procedure(object) + else: + object.function() + else: + self.push(object) + + def call_procedure(self, proc): + handle_object = self.handle_object + for item in proc.value: + handle_object(item) + + def resolve_name(self, name): + dictstack = self.dictstack + for i in range(len(dictstack) - 1, -1, -1): + if name in dictstack[i]: + return dictstack[i][name] + raise PSError("name error: " + str(name)) + + def do_token( + self, + token, + int=int, + float=float, + ps_name=ps_name, + ps_integer=ps_integer, + ps_real=ps_real, + ): + try: + num = int(token) + except (ValueError, OverflowError): + try: + num = float(token) + except (ValueError, OverflowError): + if "#" in token: + hashpos = token.find("#") + try: + base = int(token[:hashpos]) + num = int(token[hashpos + 1 :], base) + except (ValueError, OverflowError): + return ps_name(token) + else: + return ps_integer(num) + else: + return ps_name(token) + else: + return ps_real(num) + else: + return ps_integer(num) + + def do_comment(self, token): + pass + + def do_literal(self, token): + return ps_literal(token[1:]) + + def do_string(self, token): + return ps_string(token[1:-1]) + + def do_hexstring(self, token): + hexStr = "".join(token[1:-1].split()) + if len(hexStr) % 2: + hexStr = hexStr + "0" + cleanstr = [] + for i in range(0, len(hexStr), 2): + cleanstr.append(chr(int(hexStr[i : i + 2], 16))) + cleanstr = "".join(cleanstr) + return ps_string(cleanstr) + + def do_special(self, token): + if token == "{": + self.proclevel = self.proclevel + 1 + return self.procmark + elif token == "}": + proc = [] + while 1: + topobject = self.pop() + if topobject == self.procmark: + break + proc.append(topobject) + self.proclevel = self.proclevel - 1 + proc.reverse() + return ps_procedure(proc) + elif token == "[": + return self.mark + elif token == "]": + return ps_name("]") + else: + raise PSTokenError("huh?") + + def push(self, object): + self.stack.append(object) + + def pop(self, *types): + stack = self.stack + if not stack: + raise PSError("stack underflow") + object = stack[-1] + if types: + if object.type not in types: + raise PSError( + "typecheck, expected %s, found %s" % (repr(types), object.type) + ) + del stack[-1] + return object + + def do_makearray(self): + array = [] + while 1: + topobject = self.pop() + if topobject == self.mark: + break + array.append(topobject) + array.reverse() + self.push(ps_array(array)) + + def close(self): + """Remove circular references.""" + del self.stack + del self.dictstack + + +def unpack_item(item): + tp = type(item.value) + if tp == dict: + newitem = {} + for key, value in item.value.items(): + newitem[key] = unpack_item(value) + elif tp == list: + newitem = [None] * len(item.value) + for i in range(len(item.value)): + newitem[i] = unpack_item(item.value[i]) + if item.type == "proceduretype": + newitem = tuple(newitem) + else: + newitem = item.value + return newitem + + +def suckfont(data, encoding="ascii"): + m = re.search(rb"/FontName\s+/([^ \t\n\r]+)\s+def", data) + if m: + fontName = m.group(1) + fontName = fontName.decode() + else: + fontName = None + interpreter = PSInterpreter(encoding=encoding) + interpreter.interpret( + b"/Helvetica 4 dict dup /Encoding StandardEncoding put definefont pop" + ) + interpreter.interpret(data) + fontdir = interpreter.dictstack[0]["FontDirectory"].value + if fontName in fontdir: + rawfont = fontdir[fontName] + else: + # fall back, in case fontName wasn't found + fontNames = list(fontdir.keys()) + if len(fontNames) > 1: + fontNames.remove("Helvetica") + fontNames.sort() + rawfont = fontdir[fontNames[0]] + interpreter.close() + return unpack_item(rawfont) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psOperators.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psOperators.py new file mode 100644 index 00000000..d0b975ea --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/psOperators.py @@ -0,0 +1,572 @@ +_accessstrings = {0: "", 1: "readonly", 2: "executeonly", 3: "noaccess"} + + +class ps_object(object): + literal = 1 + access = 0 + value = None + + def __init__(self, value): + self.value = value + self.type = self.__class__.__name__[3:] + "type" + + def __repr__(self): + return "<%s %s>" % (self.__class__.__name__[3:], repr(self.value)) + + +class ps_operator(ps_object): + literal = 0 + + def __init__(self, name, function): + self.name = name + self.function = function + self.type = self.__class__.__name__[3:] + "type" + + def __repr__(self): + return "" % self.name + + +class ps_procedure(ps_object): + literal = 0 + + def __repr__(self): + return "" + + def __str__(self): + psstring = "{" + for i in range(len(self.value)): + if i: + psstring = psstring + " " + str(self.value[i]) + else: + psstring = psstring + str(self.value[i]) + return psstring + "}" + + +class ps_name(ps_object): + literal = 0 + + def __str__(self): + if self.literal: + return "/" + self.value + else: + return self.value + + +class ps_literal(ps_object): + def __str__(self): + return "/" + self.value + + +class ps_array(ps_object): + def __str__(self): + psstring = "[" + for i in range(len(self.value)): + item = self.value[i] + access = _accessstrings[item.access] + if access: + access = " " + access + if i: + psstring = psstring + " " + str(item) + access + else: + psstring = psstring + str(item) + access + return psstring + "]" + + def __repr__(self): + return "" + + +_type1_pre_eexec_order = [ + "FontInfo", + "FontName", + "Encoding", + "PaintType", + "FontType", + "FontMatrix", + "FontBBox", + "UniqueID", + "Metrics", + "StrokeWidth", +] + +_type1_fontinfo_order = [ + "version", + "Notice", + "FullName", + "FamilyName", + "Weight", + "ItalicAngle", + "isFixedPitch", + "UnderlinePosition", + "UnderlineThickness", +] + +_type1_post_eexec_order = ["Private", "CharStrings", "FID"] + + +def _type1_item_repr(key, value): + psstring = "" + access = _accessstrings[value.access] + if access: + access = access + " " + if key == "CharStrings": + psstring = psstring + "/%s %s def\n" % ( + key, + _type1_CharString_repr(value.value), + ) + elif key == "Encoding": + psstring = psstring + _type1_Encoding_repr(value, access) + else: + psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access) + return psstring + + +def _type1_Encoding_repr(encoding, access): + encoding = encoding.value + psstring = "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n" + for i in range(256): + name = encoding[i].value + if name != ".notdef": + psstring = psstring + "dup %d /%s put\n" % (i, name) + return psstring + access + "def\n" + + +def _type1_CharString_repr(charstrings): + items = sorted(charstrings.items()) + return "xxx" + + +class ps_font(ps_object): + def __str__(self): + psstring = "%d dict dup begin\n" % len(self.value) + for key in _type1_pre_eexec_order: + try: + value = self.value[key] + except KeyError: + pass + else: + psstring = psstring + _type1_item_repr(key, value) + items = sorted(self.value.items()) + for key, value in items: + if key not in _type1_pre_eexec_order + _type1_post_eexec_order: + psstring = psstring + _type1_item_repr(key, value) + psstring = psstring + "currentdict end\ncurrentfile eexec\ndup " + for key in _type1_post_eexec_order: + try: + value = self.value[key] + except KeyError: + pass + else: + psstring = psstring + _type1_item_repr(key, value) + return ( + psstring + + "dup/FontName get exch definefont pop\nmark currentfile closefile\n" + + 8 * (64 * "0" + "\n") + + "cleartomark" + + "\n" + ) + + def __repr__(self): + return "" + + +class ps_file(ps_object): + pass + + +class ps_dict(ps_object): + def __str__(self): + psstring = "%d dict dup begin\n" % len(self.value) + items = sorted(self.value.items()) + for key, value in items: + access = _accessstrings[value.access] + if access: + access = access + " " + psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access) + return psstring + "end " + + def __repr__(self): + return "" + + +class ps_mark(ps_object): + def __init__(self): + self.value = "mark" + self.type = self.__class__.__name__[3:] + "type" + + +class ps_procmark(ps_object): + def __init__(self): + self.value = "procmark" + self.type = self.__class__.__name__[3:] + "type" + + +class ps_null(ps_object): + def __init__(self): + self.type = self.__class__.__name__[3:] + "type" + + +class ps_boolean(ps_object): + def __str__(self): + if self.value: + return "true" + else: + return "false" + + +class ps_string(ps_object): + def __str__(self): + return "(%s)" % repr(self.value)[1:-1] + + +class ps_integer(ps_object): + def __str__(self): + return repr(self.value) + + +class ps_real(ps_object): + def __str__(self): + return repr(self.value) + + +class PSOperators(object): + def ps_def(self): + obj = self.pop() + name = self.pop() + self.dictstack[-1][name.value] = obj + + def ps_bind(self): + proc = self.pop("proceduretype") + self.proc_bind(proc) + self.push(proc) + + def proc_bind(self, proc): + for i in range(len(proc.value)): + item = proc.value[i] + if item.type == "proceduretype": + self.proc_bind(item) + else: + if not item.literal: + try: + obj = self.resolve_name(item.value) + except: + pass + else: + if obj.type == "operatortype": + proc.value[i] = obj + + def ps_exch(self): + if len(self.stack) < 2: + raise RuntimeError("stack underflow") + obj1 = self.pop() + obj2 = self.pop() + self.push(obj1) + self.push(obj2) + + def ps_dup(self): + if not self.stack: + raise RuntimeError("stack underflow") + self.push(self.stack[-1]) + + def ps_exec(self): + obj = self.pop() + if obj.type == "proceduretype": + self.call_procedure(obj) + else: + self.handle_object(obj) + + def ps_count(self): + self.push(ps_integer(len(self.stack))) + + def ps_eq(self): + any1 = self.pop() + any2 = self.pop() + self.push(ps_boolean(any1.value == any2.value)) + + def ps_ne(self): + any1 = self.pop() + any2 = self.pop() + self.push(ps_boolean(any1.value != any2.value)) + + def ps_cvx(self): + obj = self.pop() + obj.literal = 0 + self.push(obj) + + def ps_matrix(self): + matrix = [ + ps_real(1.0), + ps_integer(0), + ps_integer(0), + ps_real(1.0), + ps_integer(0), + ps_integer(0), + ] + self.push(ps_array(matrix)) + + def ps_string(self): + num = self.pop("integertype").value + self.push(ps_string("\0" * num)) + + def ps_type(self): + obj = self.pop() + self.push(ps_string(obj.type)) + + def ps_store(self): + value = self.pop() + key = self.pop() + name = key.value + for i in range(len(self.dictstack) - 1, -1, -1): + if name in self.dictstack[i]: + self.dictstack[i][name] = value + break + self.dictstack[-1][name] = value + + def ps_where(self): + name = self.pop() + # XXX + self.push(ps_boolean(0)) + + def ps_systemdict(self): + self.push(ps_dict(self.dictstack[0])) + + def ps_userdict(self): + self.push(ps_dict(self.dictstack[1])) + + def ps_currentdict(self): + self.push(ps_dict(self.dictstack[-1])) + + def ps_currentfile(self): + self.push(ps_file(self.tokenizer)) + + def ps_eexec(self): + f = self.pop("filetype").value + f.starteexec() + + def ps_closefile(self): + f = self.pop("filetype").value + f.skipwhite() + f.stopeexec() + + def ps_cleartomark(self): + obj = self.pop() + while obj != self.mark: + obj = self.pop() + + def ps_readstring(self, ps_boolean=ps_boolean, len=len): + s = self.pop("stringtype") + oldstr = s.value + f = self.pop("filetype") + # pad = file.value.read(1) + # for StringIO, this is faster + f.value.pos = f.value.pos + 1 + newstr = f.value.read(len(oldstr)) + s.value = newstr + self.push(s) + self.push(ps_boolean(len(oldstr) == len(newstr))) + + def ps_known(self): + key = self.pop() + d = self.pop("dicttype", "fonttype") + self.push(ps_boolean(key.value in d.value)) + + def ps_if(self): + proc = self.pop("proceduretype") + if self.pop("booleantype").value: + self.call_procedure(proc) + + def ps_ifelse(self): + proc2 = self.pop("proceduretype") + proc1 = self.pop("proceduretype") + if self.pop("booleantype").value: + self.call_procedure(proc1) + else: + self.call_procedure(proc2) + + def ps_readonly(self): + obj = self.pop() + if obj.access < 1: + obj.access = 1 + self.push(obj) + + def ps_executeonly(self): + obj = self.pop() + if obj.access < 2: + obj.access = 2 + self.push(obj) + + def ps_noaccess(self): + obj = self.pop() + if obj.access < 3: + obj.access = 3 + self.push(obj) + + def ps_not(self): + obj = self.pop("booleantype", "integertype") + if obj.type == "booleantype": + self.push(ps_boolean(not obj.value)) + else: + self.push(ps_integer(~obj.value)) + + def ps_print(self): + str = self.pop("stringtype") + print("PS output --->", str.value) + + def ps_anchorsearch(self): + seek = self.pop("stringtype") + s = self.pop("stringtype") + seeklen = len(seek.value) + if s.value[:seeklen] == seek.value: + self.push(ps_string(s.value[seeklen:])) + self.push(seek) + self.push(ps_boolean(1)) + else: + self.push(s) + self.push(ps_boolean(0)) + + def ps_array(self): + num = self.pop("integertype") + array = ps_array([None] * num.value) + self.push(array) + + def ps_astore(self): + array = self.pop("arraytype") + for i in range(len(array.value) - 1, -1, -1): + array.value[i] = self.pop() + self.push(array) + + def ps_load(self): + name = self.pop() + self.push(self.resolve_name(name.value)) + + def ps_put(self): + obj1 = self.pop() + obj2 = self.pop() + obj3 = self.pop("arraytype", "dicttype", "stringtype", "proceduretype") + tp = obj3.type + if tp == "arraytype" or tp == "proceduretype": + obj3.value[obj2.value] = obj1 + elif tp == "dicttype": + obj3.value[obj2.value] = obj1 + elif tp == "stringtype": + index = obj2.value + obj3.value = obj3.value[:index] + chr(obj1.value) + obj3.value[index + 1 :] + + def ps_get(self): + obj1 = self.pop() + if obj1.value == "Encoding": + pass + obj2 = self.pop( + "arraytype", "dicttype", "stringtype", "proceduretype", "fonttype" + ) + tp = obj2.type + if tp in ("arraytype", "proceduretype"): + self.push(obj2.value[obj1.value]) + elif tp in ("dicttype", "fonttype"): + self.push(obj2.value[obj1.value]) + elif tp == "stringtype": + self.push(ps_integer(ord(obj2.value[obj1.value]))) + else: + assert False, "shouldn't get here" + + def ps_getinterval(self): + obj1 = self.pop("integertype") + obj2 = self.pop("integertype") + obj3 = self.pop("arraytype", "stringtype") + tp = obj3.type + if tp == "arraytype": + self.push(ps_array(obj3.value[obj2.value : obj2.value + obj1.value])) + elif tp == "stringtype": + self.push(ps_string(obj3.value[obj2.value : obj2.value + obj1.value])) + + def ps_putinterval(self): + obj1 = self.pop("arraytype", "stringtype") + obj2 = self.pop("integertype") + obj3 = self.pop("arraytype", "stringtype") + tp = obj3.type + if tp == "arraytype": + obj3.value[obj2.value : obj2.value + len(obj1.value)] = obj1.value + elif tp == "stringtype": + newstr = obj3.value[: obj2.value] + newstr = newstr + obj1.value + newstr = newstr + obj3.value[obj2.value + len(obj1.value) :] + obj3.value = newstr + + def ps_cvn(self): + self.push(ps_name(self.pop("stringtype").value)) + + def ps_index(self): + n = self.pop("integertype").value + if n < 0: + raise RuntimeError("index may not be negative") + self.push(self.stack[-1 - n]) + + def ps_for(self): + proc = self.pop("proceduretype") + limit = self.pop("integertype", "realtype").value + increment = self.pop("integertype", "realtype").value + i = self.pop("integertype", "realtype").value + while 1: + if increment > 0: + if i > limit: + break + else: + if i < limit: + break + if type(i) == type(0.0): + self.push(ps_real(i)) + else: + self.push(ps_integer(i)) + self.call_procedure(proc) + i = i + increment + + def ps_forall(self): + proc = self.pop("proceduretype") + obj = self.pop("arraytype", "stringtype", "dicttype") + tp = obj.type + if tp == "arraytype": + for item in obj.value: + self.push(item) + self.call_procedure(proc) + elif tp == "stringtype": + for item in obj.value: + self.push(ps_integer(ord(item))) + self.call_procedure(proc) + elif tp == "dicttype": + for key, value in obj.value.items(): + self.push(ps_name(key)) + self.push(value) + self.call_procedure(proc) + + def ps_definefont(self): + font = self.pop("dicttype") + name = self.pop() + font = ps_font(font.value) + self.dictstack[0]["FontDirectory"].value[name.value] = font + self.push(font) + + def ps_findfont(self): + name = self.pop() + font = self.dictstack[0]["FontDirectory"].value[name.value] + self.push(font) + + def ps_pop(self): + self.pop() + + def ps_dict(self): + self.pop("integertype") + self.push(ps_dict({})) + + def ps_begin(self): + self.dictstack.append(self.pop("dicttype").value) + + def ps_end(self): + if len(self.dictstack) > 2: + del self.dictstack[-1] + else: + raise RuntimeError("dictstack underflow") + + +notdef = ".notdef" +from fontTools.encodings.StandardEncoding import StandardEncoding + +ps_StandardEncoding = list(map(ps_name, StandardEncoding)) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/py23.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/py23.py new file mode 100644 index 00000000..29f634d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/py23.py @@ -0,0 +1,96 @@ +"""Python 2/3 compat layer leftovers.""" + +import decimal as _decimal +import math as _math +import warnings +from contextlib import redirect_stderr, redirect_stdout +from io import BytesIO +from io import StringIO as UnicodeIO +from types import SimpleNamespace + +from .textTools import Tag, bytechr, byteord, bytesjoin, strjoin, tobytes, tostr + +warnings.warn( + "The py23 module has been deprecated and will be removed in a future release. " + "Please update your code.", + DeprecationWarning, +) + +__all__ = [ + "basestring", + "bytechr", + "byteord", + "BytesIO", + "bytesjoin", + "open", + "Py23Error", + "range", + "RecursionError", + "round", + "SimpleNamespace", + "StringIO", + "strjoin", + "Tag", + "tobytes", + "tostr", + "tounicode", + "unichr", + "unicode", + "UnicodeIO", + "xrange", + "zip", +] + + +class Py23Error(NotImplementedError): + pass + + +RecursionError = RecursionError +StringIO = UnicodeIO + +basestring = str +isclose = _math.isclose +isfinite = _math.isfinite +open = open +range = range +round = round3 = round +unichr = chr +unicode = str +zip = zip + +tounicode = tostr + + +def xrange(*args, **kwargs): + raise Py23Error("'xrange' is not defined. Use 'range' instead.") + + +def round2(number, ndigits=None): + """ + Implementation of Python 2 built-in round() function. + Rounds a number to a given precision in decimal digits (default + 0 digits). The result is a floating point number. Values are rounded + to the closest multiple of 10 to the power minus ndigits; if two + multiples are equally close, rounding is done away from 0. + ndigits may be negative. + See Python 2 documentation: + https://docs.python.org/2/library/functions.html?highlight=round#round + """ + if ndigits is None: + ndigits = 0 + + if ndigits < 0: + exponent = 10 ** (-ndigits) + quotient, remainder = divmod(number, exponent) + if remainder >= exponent // 2 and number >= 0: + quotient += 1 + return float(quotient * exponent) + else: + exponent = _decimal.Decimal("10") ** (-ndigits) + + d = _decimal.Decimal.from_float(number).quantize( + exponent, rounding=_decimal.ROUND_HALF_UP + ) + + return float(d) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/roundTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/roundTools.py new file mode 100644 index 00000000..a4d45c31 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/roundTools.py @@ -0,0 +1,110 @@ +""" +Various round-to-integer helpers. +""" + +import math +import functools +import logging + +log = logging.getLogger(__name__) + +__all__ = [ + "noRound", + "otRound", + "maybeRound", + "roundFunc", + "nearestMultipleShortestRepr", +] + + +def noRound(value): + return value + + +def otRound(value): + """Round float value to nearest integer towards ``+Infinity``. + + The OpenType spec (in the section on `"normalization" of OpenType Font Variations `_) + defines the required method for converting floating point values to + fixed-point. In particular it specifies the following rounding strategy: + + for fractional values of 0.5 and higher, take the next higher integer; + for other fractional values, truncate. + + This function rounds the floating-point value according to this strategy + in preparation for conversion to fixed-point. + + Args: + value (float): The input floating-point value. + + Returns + float: The rounded value. + """ + # See this thread for how we ended up with this implementation: + # https://github.com/fonttools/fonttools/issues/1248#issuecomment-383198166 + return int(math.floor(value + 0.5)) + + +def maybeRound(v, tolerance, round=otRound): + rounded = round(v) + return rounded if abs(rounded - v) <= tolerance else v + + +def roundFunc(tolerance, round=otRound): + if tolerance < 0: + raise ValueError("Rounding tolerance must be positive") + + if tolerance == 0: + return noRound + + if tolerance >= 0.5: + return round + + return functools.partial(maybeRound, tolerance=tolerance, round=round) + + +def nearestMultipleShortestRepr(value: float, factor: float) -> str: + """Round to nearest multiple of factor and return shortest decimal representation. + + This chooses the float that is closer to a multiple of the given factor while + having the shortest decimal representation (the least number of fractional decimal + digits). + + For example, given the following: + + >>> nearestMultipleShortestRepr(-0.61883544921875, 1.0/(1<<14)) + '-0.61884' + + Useful when you need to serialize or print a fixed-point number (or multiples + thereof, such as F2Dot14 fractions of 180 degrees in COLRv1 PaintRotate) in + a human-readable form. + + Args: + value (value): The value to be rounded and serialized. + factor (float): The value which the result is a close multiple of. + + Returns: + str: A compact string representation of the value. + """ + if not value: + return "0.0" + + value = otRound(value / factor) * factor + eps = 0.5 * factor + lo = value - eps + hi = value + eps + # If the range of valid choices spans an integer, return the integer. + if int(lo) != int(hi): + return str(float(round(value))) + + fmt = "%.8f" + lo = fmt % lo + hi = fmt % hi + assert len(lo) == len(hi) and lo != hi + for i in range(len(lo)): + if lo[i] != hi[i]: + break + period = lo.find(".") + assert period < i + fmt = "%%.%df" % (i - period) + return fmt % value diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/sstruct.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/sstruct.py new file mode 100644 index 00000000..d35bc9a5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/sstruct.py @@ -0,0 +1,220 @@ +"""sstruct.py -- SuperStruct + +Higher level layer on top of the struct module, enabling to +bind names to struct elements. The interface is similar to +struct, except the objects passed and returned are not tuples +(or argument lists), but dictionaries or instances. + +Just like struct, we use fmt strings to describe a data +structure, except we use one line per element. Lines are +separated by newlines or semi-colons. Each line contains +either one of the special struct characters ('@', '=', '<', +'>' or '!') or a 'name:formatchar' combo (eg. 'myFloat:f'). +Repetitions, like the struct module offers them are not useful +in this context, except for fixed length strings (eg. 'myInt:5h' +is not allowed but 'myString:5s' is). The 'x' fmt character +(pad byte) is treated as 'special', since it is by definition +anonymous. Extra whitespace is allowed everywhere. + +The sstruct module offers one feature that the "normal" struct +module doesn't: support for fixed point numbers. These are spelled +as "n.mF", where n is the number of bits before the point, and m +the number of bits after the point. Fixed point numbers get +converted to floats. + +pack(fmt, object): + 'object' is either a dictionary or an instance (or actually + anything that has a __dict__ attribute). If it is a dictionary, + its keys are used for names. If it is an instance, it's + attributes are used to grab struct elements from. Returns + a string containing the data. + +unpack(fmt, data, object=None) + If 'object' is omitted (or None), a new dictionary will be + returned. If 'object' is a dictionary, it will be used to add + struct elements to. If it is an instance (or in fact anything + that has a __dict__ attribute), an attribute will be added for + each struct element. In the latter two cases, 'object' itself + is returned. + +unpack2(fmt, data, object=None) + Convenience function. Same as unpack, except data may be longer + than needed. The returned value is a tuple: (object, leftoverdata). + +calcsize(fmt) + like struct.calcsize(), but uses our own fmt strings: + it returns the size of the data in bytes. +""" + +from fontTools.misc.fixedTools import fixedToFloat as fi2fl, floatToFixed as fl2fi +from fontTools.misc.textTools import tobytes, tostr +import struct +import re + +__version__ = "1.2" +__copyright__ = "Copyright 1998, Just van Rossum " + + +class Error(Exception): + pass + + +def pack(fmt, obj): + formatstring, names, fixes = getformat(fmt, keep_pad_byte=True) + elements = [] + if not isinstance(obj, dict): + obj = obj.__dict__ + for name in names: + value = obj[name] + if name in fixes: + # fixed point conversion + value = fl2fi(value, fixes[name]) + elif isinstance(value, str): + value = tobytes(value) + elements.append(value) + data = struct.pack(*(formatstring,) + tuple(elements)) + return data + + +def unpack(fmt, data, obj=None): + if obj is None: + obj = {} + data = tobytes(data) + formatstring, names, fixes = getformat(fmt) + if isinstance(obj, dict): + d = obj + else: + d = obj.__dict__ + elements = struct.unpack(formatstring, data) + for i in range(len(names)): + name = names[i] + value = elements[i] + if name in fixes: + # fixed point conversion + value = fi2fl(value, fixes[name]) + elif isinstance(value, bytes): + try: + value = tostr(value) + except UnicodeDecodeError: + pass + d[name] = value + return obj + + +def unpack2(fmt, data, obj=None): + length = calcsize(fmt) + return unpack(fmt, data[:length], obj), data[length:] + + +def calcsize(fmt): + formatstring, names, fixes = getformat(fmt) + return struct.calcsize(formatstring) + + +# matches "name:formatchar" (whitespace is allowed) +_elementRE = re.compile( + r"\s*" # whitespace + r"([A-Za-z_][A-Za-z_0-9]*)" # name (python identifier) + r"\s*:\s*" # whitespace : whitespace + r"([xcbB?hHiIlLqQfd]|" # formatchar... + r"[0-9]+[ps]|" # ...formatchar... + r"([0-9]+)\.([0-9]+)(F))" # ...formatchar + r"\s*" # whitespace + r"(#.*)?$" # [comment] + end of string +) + +# matches the special struct fmt chars and 'x' (pad byte) +_extraRE = re.compile(r"\s*([x@=<>!])\s*(#.*)?$") + +# matches an "empty" string, possibly containing whitespace and/or a comment +_emptyRE = re.compile(r"\s*(#.*)?$") + +_fixedpointmappings = {8: "b", 16: "h", 32: "l"} + +_formatcache = {} + + +def getformat(fmt, keep_pad_byte=False): + fmt = tostr(fmt, encoding="ascii") + try: + formatstring, names, fixes = _formatcache[fmt] + except KeyError: + lines = re.split("[\n;]", fmt) + formatstring = "" + names = [] + fixes = {} + for line in lines: + if _emptyRE.match(line): + continue + m = _extraRE.match(line) + if m: + formatchar = m.group(1) + if formatchar != "x" and formatstring: + raise Error("a special fmt char must be first") + else: + m = _elementRE.match(line) + if not m: + raise Error("syntax error in fmt: '%s'" % line) + name = m.group(1) + formatchar = m.group(2) + if keep_pad_byte or formatchar != "x": + names.append(name) + if m.group(3): + # fixed point + before = int(m.group(3)) + after = int(m.group(4)) + bits = before + after + if bits not in [8, 16, 32]: + raise Error("fixed point must be 8, 16 or 32 bits long") + formatchar = _fixedpointmappings[bits] + assert m.group(5) == "F" + fixes[name] = after + formatstring = formatstring + formatchar + _formatcache[fmt] = formatstring, names, fixes + return formatstring, names, fixes + + +def _test(): + fmt = """ + # comments are allowed + > # big endian (see documentation for struct) + # empty lines are allowed: + + ashort: h + along: l + abyte: b # a byte + achar: c + astr: 5s + afloat: f; adouble: d # multiple "statements" are allowed + afixed: 16.16F + abool: ? + apad: x + """ + + print("size:", calcsize(fmt)) + + class foo(object): + pass + + i = foo() + + i.ashort = 0x7FFF + i.along = 0x7FFFFFFF + i.abyte = 0x7F + i.achar = "a" + i.astr = "12345" + i.afloat = 0.5 + i.adouble = 0.5 + i.afixed = 1.5 + i.abool = True + + data = pack(fmt, i) + print("data:", repr(data)) + print(unpack(fmt, data)) + i2 = foo() + unpack(fmt, data, i2) + print(vars(i2)) + + +if __name__ == "__main__": + _test() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/symfont.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/symfont.py new file mode 100644 index 00000000..fb9e20a4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/symfont.py @@ -0,0 +1,248 @@ +from fontTools.pens.basePen import BasePen +from functools import partial +from itertools import count +import sympy as sp +import sys + +n = 3 # Max Bezier degree; 3 for cubic, 2 for quadratic + +t, x, y = sp.symbols("t x y", real=True) +c = sp.symbols("c", real=False) # Complex representation instead of x/y + +X = tuple(sp.symbols("x:%d" % (n + 1), real=True)) +Y = tuple(sp.symbols("y:%d" % (n + 1), real=True)) +P = tuple(zip(*(sp.symbols("p:%d[%s]" % (n + 1, w), real=True) for w in "01"))) +C = tuple(sp.symbols("c:%d" % (n + 1), real=False)) + +# Cubic Bernstein basis functions +BinomialCoefficient = [(1, 0)] +for i in range(1, n + 1): + last = BinomialCoefficient[-1] + this = tuple(last[j - 1] + last[j] for j in range(len(last))) + (0,) + BinomialCoefficient.append(this) +BinomialCoefficient = tuple(tuple(item[:-1]) for item in BinomialCoefficient) +del last, this + +BernsteinPolynomial = tuple( + tuple(c * t**i * (1 - t) ** (n - i) for i, c in enumerate(coeffs)) + for n, coeffs in enumerate(BinomialCoefficient) +) + +BezierCurve = tuple( + tuple( + sum(P[i][j] * bernstein for i, bernstein in enumerate(bernsteins)) + for j in range(2) + ) + for n, bernsteins in enumerate(BernsteinPolynomial) +) +BezierCurveC = tuple( + sum(C[i] * bernstein for i, bernstein in enumerate(bernsteins)) + for n, bernsteins in enumerate(BernsteinPolynomial) +) + + +def green(f, curveXY): + f = -sp.integrate(sp.sympify(f), y) + f = f.subs({x: curveXY[0], y: curveXY[1]}) + f = sp.integrate(f * sp.diff(curveXY[0], t), (t, 0, 1)) + return f + + +class _BezierFuncsLazy(dict): + def __init__(self, symfunc): + self._symfunc = symfunc + self._bezfuncs = {} + + def __missing__(self, i): + args = ["p%d" % d for d in range(i + 1)] + f = green(self._symfunc, BezierCurve[i]) + f = sp.gcd_terms(f.collect(sum(P, ()))) # Optimize + return sp.lambdify(args, f) + + +class GreenPen(BasePen): + _BezierFuncs = {} + + @classmethod + def _getGreenBezierFuncs(celf, func): + funcstr = str(func) + if not funcstr in celf._BezierFuncs: + celf._BezierFuncs[funcstr] = _BezierFuncsLazy(func) + return celf._BezierFuncs[funcstr] + + def __init__(self, func, glyphset=None): + BasePen.__init__(self, glyphset) + self._funcs = self._getGreenBezierFuncs(func) + self.value = 0 + + def _moveTo(self, p0): + self.__startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + self._lineTo(self.__startPoint) + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + # Green theorem is not defined on open contours. + raise NotImplementedError + + def _lineTo(self, p1): + p0 = self._getCurrentPoint() + self.value += self._funcs[1](p0, p1) + + def _qCurveToOne(self, p1, p2): + p0 = self._getCurrentPoint() + self.value += self._funcs[2](p0, p1, p2) + + def _curveToOne(self, p1, p2, p3): + p0 = self._getCurrentPoint() + self.value += self._funcs[3](p0, p1, p2, p3) + + +# Sample pens. +# Do not use this in real code. +# Use fontTools.pens.momentsPen.MomentsPen instead. +AreaPen = partial(GreenPen, func=1) +MomentXPen = partial(GreenPen, func=x) +MomentYPen = partial(GreenPen, func=y) +MomentXXPen = partial(GreenPen, func=x * x) +MomentYYPen = partial(GreenPen, func=y * y) +MomentXYPen = partial(GreenPen, func=x * y) + + +def printGreenPen(penName, funcs, file=sys.stdout, docstring=None): + if docstring is not None: + print('"""%s"""' % docstring) + + print( + """from fontTools.pens.basePen import BasePen, OpenContourError +try: + import cython + + COMPILED = cython.compiled +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython + + COMPILED = False + + +__all__ = ["%s"] + +class %s(BasePen): + + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) +""" + % (penName, penName), + file=file, + ) + for name, f in funcs: + print(" self.%s = 0" % name, file=file) + print( + """ + def _moveTo(self, p0): + self.__startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + self._lineTo(self.__startPoint) + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + # Green theorem is not defined on open contours. + raise OpenContourError( + "Green theorem is not defined on open contours." + ) +""", + end="", + file=file, + ) + + for n in (1, 2, 3): + subs = {P[i][j]: [X, Y][j][i] for i in range(n + 1) for j in range(2)} + greens = [green(f, BezierCurve[n]) for name, f in funcs] + greens = [sp.gcd_terms(f.collect(sum(P, ()))) for f in greens] # Optimize + greens = [f.subs(subs) for f in greens] # Convert to p to x/y + defs, exprs = sp.cse( + greens, + optimizations="basic", + symbols=(sp.Symbol("r%d" % i) for i in count()), + ) + + print() + for name, value in defs: + print(" @cython.locals(%s=cython.double)" % name, file=file) + if n == 1: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + def _lineTo(self, p1): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 +""", + file=file, + ) + elif n == 2: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + def _qCurveToOne(self, p1, p2): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 + x2,y2 = p2 +""", + file=file, + ) + elif n == 3: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + @cython.locals(x3=cython.double, y3=cython.double) + def _curveToOne(self, p1, p2, p3): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 + x2,y2 = p2 + x3,y3 = p3 +""", + file=file, + ) + for name, value in defs: + print(" %s = %s" % (name, value), file=file) + + print(file=file) + for name, value in zip([f[0] for f in funcs], exprs): + print(" self.%s += %s" % (name, value), file=file) + + print( + """ +if __name__ == '__main__': + from fontTools.misc.symfont import x, y, printGreenPen + printGreenPen('%s', [""" + % penName, + file=file, + ) + for name, f in funcs: + print(" ('%s', %s)," % (name, str(f)), file=file) + print(" ])", file=file) + + +if __name__ == "__main__": + pen = AreaPen() + pen.moveTo((100, 100)) + pen.lineTo((100, 200)) + pen.lineTo((200, 200)) + pen.curveTo((200, 250), (300, 300), (250, 350)) + pen.lineTo((200, 100)) + pen.closePath() + print(pen.value) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/testTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/testTools.py new file mode 100644 index 00000000..be611613 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/testTools.py @@ -0,0 +1,229 @@ +"""Helpers for writing unit tests.""" + +from collections.abc import Iterable +from io import BytesIO +import os +import re +import shutil +import sys +import tempfile +from unittest import TestCase as _TestCase +from fontTools.config import Config +from fontTools.misc.textTools import tobytes +from fontTools.misc.xmlWriter import XMLWriter + + +def parseXML(xmlSnippet): + """Parses a snippet of XML. + + Input can be either a single string (unicode or UTF-8 bytes), or a + a sequence of strings. + + The result is in the same format that would be returned by + XMLReader, but the parser imposes no constraints on the root + element so it can be called on small snippets of TTX files. + """ + # To support snippets with multiple elements, we add a fake root. + reader = TestXMLReader_() + xml = b"" + if isinstance(xmlSnippet, bytes): + xml += xmlSnippet + elif isinstance(xmlSnippet, str): + xml += tobytes(xmlSnippet, "utf-8") + elif isinstance(xmlSnippet, Iterable): + xml += b"".join(tobytes(s, "utf-8") for s in xmlSnippet) + else: + raise TypeError( + "expected string or sequence of strings; found %r" + % type(xmlSnippet).__name__ + ) + xml += b"" + reader.parser.Parse(xml, 0) + return reader.root[2] + + +def parseXmlInto(font, parseInto, xmlSnippet): + parsed_xml = [e for e in parseXML(xmlSnippet.strip()) if not isinstance(e, str)] + for name, attrs, content in parsed_xml: + parseInto.fromXML(name, attrs, content, font) + parseInto.populateDefaults() + return parseInto + + +class FakeFont: + def __init__(self, glyphs): + self.glyphOrder_ = glyphs + self.reverseGlyphOrderDict_ = {g: i for i, g in enumerate(glyphs)} + self.lazy = False + self.tables = {} + self.cfg = Config() + + def __getitem__(self, tag): + return self.tables[tag] + + def __setitem__(self, tag, table): + self.tables[tag] = table + + def get(self, tag, default=None): + return self.tables.get(tag, default) + + def getGlyphID(self, name): + return self.reverseGlyphOrderDict_[name] + + def getGlyphIDMany(self, lst): + return [self.getGlyphID(gid) for gid in lst] + + def getGlyphName(self, glyphID): + if glyphID < len(self.glyphOrder_): + return self.glyphOrder_[glyphID] + else: + return "glyph%.5d" % glyphID + + def getGlyphNameMany(self, lst): + return [self.getGlyphName(gid) for gid in lst] + + def getGlyphOrder(self): + return self.glyphOrder_ + + def getReverseGlyphMap(self): + return self.reverseGlyphOrderDict_ + + def getGlyphNames(self): + return sorted(self.getGlyphOrder()) + + +class TestXMLReader_(object): + def __init__(self): + from xml.parsers.expat import ParserCreate + + self.parser = ParserCreate() + self.parser.StartElementHandler = self.startElement_ + self.parser.EndElementHandler = self.endElement_ + self.parser.CharacterDataHandler = self.addCharacterData_ + self.root = None + self.stack = [] + + def startElement_(self, name, attrs): + element = (name, attrs, []) + if self.stack: + self.stack[-1][2].append(element) + else: + self.root = element + self.stack.append(element) + + def endElement_(self, name): + self.stack.pop() + + def addCharacterData_(self, data): + self.stack[-1][2].append(data) + + +def makeXMLWriter(newlinestr="\n"): + # don't write OS-specific new lines + writer = XMLWriter(BytesIO(), newlinestr=newlinestr) + # erase XML declaration + writer.file.seek(0) + writer.file.truncate() + return writer + + +def getXML(func, ttFont=None): + """Call the passed toXML function and return the written content as a + list of lines (unicode strings). + Result is stripped of XML declaration and OS-specific newline characters. + """ + writer = makeXMLWriter() + func(writer, ttFont) + xml = writer.file.getvalue().decode("utf-8") + # toXML methods must always end with a writer.newline() + assert xml.endswith("\n") + return xml.splitlines() + + +def stripVariableItemsFromTTX( + string: str, + ttLibVersion: bool = True, + checkSumAdjustment: bool = True, + modified: bool = True, + created: bool = True, + sfntVersion: bool = False, # opt-in only +) -> str: + """Strip stuff like ttLibVersion, checksums, timestamps, etc. from TTX dumps.""" + # ttlib changes with the fontTools version + if ttLibVersion: + string = re.sub(' ttLibVersion="[^"]+"', "", string) + # sometimes (e.g. some subsetter tests) we don't care whether it's OTF or TTF + if sfntVersion: + string = re.sub(' sfntVersion="[^"]+"', "", string) + # head table checksum and creation and mod date changes with each save. + if checkSumAdjustment: + string = re.sub('', "", string) + if modified: + string = re.sub('', "", string) + if created: + string = re.sub('', "", string) + return string + + +class MockFont(object): + """A font-like object that automatically adds any looked up glyphname + to its glyphOrder.""" + + def __init__(self): + self._glyphOrder = [".notdef"] + + class AllocatingDict(dict): + def __missing__(reverseDict, key): + self._glyphOrder.append(key) + gid = len(reverseDict) + reverseDict[key] = gid + return gid + + self._reverseGlyphOrder = AllocatingDict({".notdef": 0}) + self.lazy = False + + def getGlyphID(self, glyph): + gid = self._reverseGlyphOrder[glyph] + return gid + + def getReverseGlyphMap(self): + return self._reverseGlyphOrder + + def getGlyphName(self, gid): + return self._glyphOrder[gid] + + def getGlyphOrder(self): + return self._glyphOrder + + +class TestCase(_TestCase): + def __init__(self, methodName): + _TestCase.__init__(self, methodName) + # Python 3 renamed assertRaisesRegexp to assertRaisesRegex, + # and fires deprecation warnings if a program uses the old name. + if not hasattr(self, "assertRaisesRegex"): + self.assertRaisesRegex = self.assertRaisesRegexp + + +class DataFilesHandler(TestCase): + def setUp(self): + self.tempdir = None + self.num_tempfiles = 0 + + def tearDown(self): + if self.tempdir: + shutil.rmtree(self.tempdir) + + def getpath(self, testfile): + folder = os.path.dirname(sys.modules[self.__module__].__file__) + return os.path.join(folder, "data", testfile) + + def temp_dir(self): + if not self.tempdir: + self.tempdir = tempfile.mkdtemp() + + def temp_font(self, font_path, file_name): + self.temp_dir() + temppath = os.path.join(self.tempdir, file_name) + shutil.copy2(font_path, temppath) + return temppath diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/textTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/textTools.py new file mode 100644 index 00000000..f7ca1acc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/textTools.py @@ -0,0 +1,155 @@ +"""fontTools.misc.textTools.py -- miscellaneous routines.""" + + +import ast +import string + + +# alias kept for backward compatibility +safeEval = ast.literal_eval + + +class Tag(str): + @staticmethod + def transcode(blob): + if isinstance(blob, bytes): + blob = blob.decode("latin-1") + return blob + + def __new__(self, content): + return str.__new__(self, self.transcode(content)) + + def __ne__(self, other): + return not self.__eq__(other) + + def __eq__(self, other): + return str.__eq__(self, self.transcode(other)) + + def __hash__(self): + return str.__hash__(self) + + def tobytes(self): + return self.encode("latin-1") + + +def readHex(content): + """Convert a list of hex strings to binary data.""" + return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str))) + + +def deHexStr(hexdata): + """Convert a hex string to binary data.""" + hexdata = strjoin(hexdata.split()) + if len(hexdata) % 2: + hexdata = hexdata + "0" + data = [] + for i in range(0, len(hexdata), 2): + data.append(bytechr(int(hexdata[i : i + 2], 16))) + return bytesjoin(data) + + +def hexStr(data): + """Convert binary data to a hex string.""" + h = string.hexdigits + r = "" + for c in data: + i = byteord(c) + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r + + +def num2binary(l, bits=32): + items = [] + binary = "" + for i in range(bits): + if l & 0x1: + binary = "1" + binary + else: + binary = "0" + binary + l = l >> 1 + if not ((i + 1) % 8): + items.append(binary) + binary = "" + if binary: + items.append(binary) + items.reverse() + assert l in (0, -1), "number doesn't fit in number of bits" + return " ".join(items) + + +def binary2num(bin): + bin = strjoin(bin.split()) + l = 0 + for digit in bin: + l = l << 1 + if digit != "0": + l = l | 0x1 + return l + + +def caselessSort(alist): + """Return a sorted copy of a list. If there are only strings + in the list, it will not consider case. + """ + + try: + return sorted(alist, key=lambda a: (a.lower(), a)) + except TypeError: + return sorted(alist) + + +def pad(data, size): + r"""Pad byte string 'data' with null bytes until its length is a + multiple of 'size'. + + >>> len(pad(b'abcd', 4)) + 4 + >>> len(pad(b'abcde', 2)) + 6 + >>> len(pad(b'abcde', 4)) + 8 + >>> pad(b'abcdef', 4) == b'abcdef\x00\x00' + True + """ + data = tobytes(data) + if size > 1: + remainder = len(data) % size + if remainder: + data += b"\0" * (size - remainder) + return data + + +def tostr(s, encoding="ascii", errors="strict"): + if not isinstance(s, str): + return s.decode(encoding, errors) + else: + return s + + +def tobytes(s, encoding="ascii", errors="strict"): + if isinstance(s, str): + return s.encode(encoding, errors) + else: + return bytes(s) + + +def bytechr(n): + return bytes([n]) + + +def byteord(c): + return c if isinstance(c, int) else ord(c) + + +def strjoin(iterable, joiner=""): + return tostr(joiner).join(iterable) + + +def bytesjoin(iterable, joiner=b""): + return tobytes(joiner).join(tobytes(item) for item in iterable) + + +if __name__ == "__main__": + import doctest, sys + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/timeTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/timeTools.py new file mode 100644 index 00000000..175ce815 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/timeTools.py @@ -0,0 +1,88 @@ +"""fontTools.misc.timeTools.py -- tools for working with OpenType timestamps. +""" + +import os +import time +from datetime import datetime, timezone +import calendar + + +epoch_diff = calendar.timegm((1904, 1, 1, 0, 0, 0, 0, 0, 0)) + +DAYNAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] +MONTHNAMES = [ + None, + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", +] + + +def asctime(t=None): + """ + Convert a tuple or struct_time representing a time as returned by gmtime() + or localtime() to a 24-character string of the following form: + + >>> asctime(time.gmtime(0)) + 'Thu Jan 1 00:00:00 1970' + + If t is not provided, the current time as returned by localtime() is used. + Locale information is not used by asctime(). + + This is meant to normalise the output of the built-in time.asctime() across + different platforms and Python versions. + In Python 3.x, the day of the month is right-justified, whereas on Windows + Python 2.7 it is padded with zeros. + + See https://github.com/fonttools/fonttools/issues/455 + """ + if t is None: + t = time.localtime() + s = "%s %s %2s %s" % ( + DAYNAMES[t.tm_wday], + MONTHNAMES[t.tm_mon], + t.tm_mday, + time.strftime("%H:%M:%S %Y", t), + ) + return s + + +def timestampToString(value): + return asctime(time.gmtime(max(0, value + epoch_diff))) + + +def timestampFromString(value): + wkday, mnth = value[:7].split() + t = datetime.strptime(value[7:], " %d %H:%M:%S %Y") + t = t.replace(month=MONTHNAMES.index(mnth), tzinfo=timezone.utc) + wkday_idx = DAYNAMES.index(wkday) + assert t.weekday() == wkday_idx, '"' + value + '" has inconsistent weekday' + return int(t.timestamp()) - epoch_diff + + +def timestampNow(): + # https://reproducible-builds.org/specs/source-date-epoch/ + source_date_epoch = os.environ.get("SOURCE_DATE_EPOCH") + if source_date_epoch is not None: + return int(source_date_epoch) - epoch_diff + return int(time.time() - epoch_diff) + + +def timestampSinceEpoch(value): + return int(value - epoch_diff) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/transform.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/transform.py new file mode 100644 index 00000000..f85b54b7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/transform.py @@ -0,0 +1,495 @@ +"""Affine 2D transformation matrix class. + +The Transform class implements various transformation matrix operations, +both on the matrix itself, as well as on 2D coordinates. + +Transform instances are effectively immutable: all methods that operate on the +transformation itself always return a new instance. This has as the +interesting side effect that Transform instances are hashable, ie. they can be +used as dictionary keys. + +This module exports the following symbols: + +Transform + this is the main class +Identity + Transform instance set to the identity transformation +Offset + Convenience function that returns a translating transformation +Scale + Convenience function that returns a scaling transformation + +The DecomposedTransform class implements a transformation with separate +translate, rotation, scale, skew, and transformation-center components. + +:Example: + + >>> t = Transform(2, 0, 0, 3, 0, 0) + >>> t.transformPoint((100, 100)) + (200, 300) + >>> t = Scale(2, 3) + >>> t.transformPoint((100, 100)) + (200, 300) + >>> t.transformPoint((0, 0)) + (0, 0) + >>> t = Offset(2, 3) + >>> t.transformPoint((100, 100)) + (102, 103) + >>> t.transformPoint((0, 0)) + (2, 3) + >>> t2 = t.scale(0.5) + >>> t2.transformPoint((100, 100)) + (52.0, 53.0) + >>> import math + >>> t3 = t2.rotate(math.pi / 2) + >>> t3.transformPoint((0, 0)) + (2.0, 3.0) + >>> t3.transformPoint((100, 100)) + (-48.0, 53.0) + >>> t = Identity.scale(0.5).translate(100, 200).skew(0.1, 0.2) + >>> t.transformPoints([(0, 0), (1, 1), (100, 100)]) + [(50.0, 100.0), (50.550167336042726, 100.60135501775433), (105.01673360427253, 160.13550177543362)] + >>> +""" + +import math +from typing import NamedTuple +from dataclasses import dataclass + + +__all__ = ["Transform", "Identity", "Offset", "Scale", "DecomposedTransform"] + + +_EPSILON = 1e-15 +_ONE_EPSILON = 1 - _EPSILON +_MINUS_ONE_EPSILON = -1 + _EPSILON + + +def _normSinCos(v): + if abs(v) < _EPSILON: + v = 0 + elif v > _ONE_EPSILON: + v = 1 + elif v < _MINUS_ONE_EPSILON: + v = -1 + return v + + +class Transform(NamedTuple): + + """2x2 transformation matrix plus offset, a.k.a. Affine transform. + Transform instances are immutable: all transforming methods, eg. + rotate(), return a new Transform instance. + + :Example: + + >>> t = Transform() + >>> t + + >>> t.scale(2) + + >>> t.scale(2.5, 5.5) + + >>> + >>> t.scale(2, 3).transformPoint((100, 100)) + (200, 300) + + Transform's constructor takes six arguments, all of which are + optional, and can be used as keyword arguments:: + + >>> Transform(12) + + >>> Transform(dx=12) + + >>> Transform(yx=12) + + + Transform instances also behave like sequences of length 6:: + + >>> len(Identity) + 6 + >>> list(Identity) + [1, 0, 0, 1, 0, 0] + >>> tuple(Identity) + (1, 0, 0, 1, 0, 0) + + Transform instances are comparable:: + + >>> t1 = Identity.scale(2, 3).translate(4, 6) + >>> t2 = Identity.translate(8, 18).scale(2, 3) + >>> t1 == t2 + 1 + + But beware of floating point rounding errors:: + + >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) + >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) + >>> t1 + + >>> t2 + + >>> t1 == t2 + 0 + + Transform instances are hashable, meaning you can use them as + keys in dictionaries:: + + >>> d = {Scale(12, 13): None} + >>> d + {: None} + + But again, beware of floating point rounding errors:: + + >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) + >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) + >>> t1 + + >>> t2 + + >>> d = {t1: None} + >>> d + {: None} + >>> d[t2] + Traceback (most recent call last): + File "", line 1, in ? + KeyError: + """ + + xx: float = 1 + xy: float = 0 + yx: float = 0 + yy: float = 1 + dx: float = 0 + dy: float = 0 + + def transformPoint(self, p): + """Transform a point. + + :Example: + + >>> t = Transform() + >>> t = t.scale(2.5, 5.5) + >>> t.transformPoint((100, 100)) + (250.0, 550.0) + """ + (x, y) = p + xx, xy, yx, yy, dx, dy = self + return (xx * x + yx * y + dx, xy * x + yy * y + dy) + + def transformPoints(self, points): + """Transform a list of points. + + :Example: + + >>> t = Scale(2, 3) + >>> t.transformPoints([(0, 0), (0, 100), (100, 100), (100, 0)]) + [(0, 0), (0, 300), (200, 300), (200, 0)] + >>> + """ + xx, xy, yx, yy, dx, dy = self + return [(xx * x + yx * y + dx, xy * x + yy * y + dy) for x, y in points] + + def transformVector(self, v): + """Transform an (dx, dy) vector, treating translation as zero. + + :Example: + + >>> t = Transform(2, 0, 0, 2, 10, 20) + >>> t.transformVector((3, -4)) + (6, -8) + >>> + """ + (dx, dy) = v + xx, xy, yx, yy = self[:4] + return (xx * dx + yx * dy, xy * dx + yy * dy) + + def transformVectors(self, vectors): + """Transform a list of (dx, dy) vector, treating translation as zero. + + :Example: + >>> t = Transform(2, 0, 0, 2, 10, 20) + >>> t.transformVectors([(3, -4), (5, -6)]) + [(6, -8), (10, -12)] + >>> + """ + xx, xy, yx, yy = self[:4] + return [(xx * dx + yx * dy, xy * dx + yy * dy) for dx, dy in vectors] + + def translate(self, x=0, y=0): + """Return a new transformation, translated (offset) by x, y. + + :Example: + >>> t = Transform() + >>> t.translate(20, 30) + + >>> + """ + return self.transform((1, 0, 0, 1, x, y)) + + def scale(self, x=1, y=None): + """Return a new transformation, scaled by x, y. The 'y' argument + may be None, which implies to use the x value for y as well. + + :Example: + >>> t = Transform() + >>> t.scale(5) + + >>> t.scale(5, 6) + + >>> + """ + if y is None: + y = x + return self.transform((x, 0, 0, y, 0, 0)) + + def rotate(self, angle): + """Return a new transformation, rotated by 'angle' (radians). + + :Example: + >>> import math + >>> t = Transform() + >>> t.rotate(math.pi / 2) + + >>> + """ + import math + + c = _normSinCos(math.cos(angle)) + s = _normSinCos(math.sin(angle)) + return self.transform((c, s, -s, c, 0, 0)) + + def skew(self, x=0, y=0): + """Return a new transformation, skewed by x and y. + + :Example: + >>> import math + >>> t = Transform() + >>> t.skew(math.pi / 4) + + >>> + """ + import math + + return self.transform((1, math.tan(y), math.tan(x), 1, 0, 0)) + + def transform(self, other): + """Return a new transformation, transformed by another + transformation. + + :Example: + >>> t = Transform(2, 0, 0, 3, 1, 6) + >>> t.transform((4, 3, 2, 1, 5, 6)) + + >>> + """ + xx1, xy1, yx1, yy1, dx1, dy1 = other + xx2, xy2, yx2, yy2, dx2, dy2 = self + return self.__class__( + xx1 * xx2 + xy1 * yx2, + xx1 * xy2 + xy1 * yy2, + yx1 * xx2 + yy1 * yx2, + yx1 * xy2 + yy1 * yy2, + xx2 * dx1 + yx2 * dy1 + dx2, + xy2 * dx1 + yy2 * dy1 + dy2, + ) + + def reverseTransform(self, other): + """Return a new transformation, which is the other transformation + transformed by self. self.reverseTransform(other) is equivalent to + other.transform(self). + + :Example: + >>> t = Transform(2, 0, 0, 3, 1, 6) + >>> t.reverseTransform((4, 3, 2, 1, 5, 6)) + + >>> Transform(4, 3, 2, 1, 5, 6).transform((2, 0, 0, 3, 1, 6)) + + >>> + """ + xx1, xy1, yx1, yy1, dx1, dy1 = self + xx2, xy2, yx2, yy2, dx2, dy2 = other + return self.__class__( + xx1 * xx2 + xy1 * yx2, + xx1 * xy2 + xy1 * yy2, + yx1 * xx2 + yy1 * yx2, + yx1 * xy2 + yy1 * yy2, + xx2 * dx1 + yx2 * dy1 + dx2, + xy2 * dx1 + yy2 * dy1 + dy2, + ) + + def inverse(self): + """Return the inverse transformation. + + :Example: + >>> t = Identity.translate(2, 3).scale(4, 5) + >>> t.transformPoint((10, 20)) + (42, 103) + >>> it = t.inverse() + >>> it.transformPoint((42, 103)) + (10.0, 20.0) + >>> + """ + if self == Identity: + return self + xx, xy, yx, yy, dx, dy = self + det = xx * yy - yx * xy + xx, xy, yx, yy = yy / det, -xy / det, -yx / det, xx / det + dx, dy = -xx * dx - yx * dy, -xy * dx - yy * dy + return self.__class__(xx, xy, yx, yy, dx, dy) + + def toPS(self): + """Return a PostScript representation + + :Example: + + >>> t = Identity.scale(2, 3).translate(4, 5) + >>> t.toPS() + '[2 0 0 3 8 15]' + >>> + """ + return "[%s %s %s %s %s %s]" % self + + def toDecomposed(self) -> "DecomposedTransform": + """Decompose into a DecomposedTransform.""" + return DecomposedTransform.fromTransform(self) + + def __bool__(self): + """Returns True if transform is not identity, False otherwise. + + :Example: + + >>> bool(Identity) + False + >>> bool(Transform()) + False + >>> bool(Scale(1.)) + False + >>> bool(Scale(2)) + True + >>> bool(Offset()) + False + >>> bool(Offset(0)) + False + >>> bool(Offset(2)) + True + """ + return self != Identity + + def __repr__(self): + return "<%s [%g %g %g %g %g %g]>" % ((self.__class__.__name__,) + self) + + +Identity = Transform() + + +def Offset(x=0, y=0): + """Return the identity transformation offset by x, y. + + :Example: + >>> Offset(2, 3) + + >>> + """ + return Transform(1, 0, 0, 1, x, y) + + +def Scale(x, y=None): + """Return the identity transformation scaled by x, y. The 'y' argument + may be None, which implies to use the x value for y as well. + + :Example: + >>> Scale(2, 3) + + >>> + """ + if y is None: + y = x + return Transform(x, 0, 0, y, 0, 0) + + +@dataclass +class DecomposedTransform: + """The DecomposedTransform class implements a transformation with separate + translate, rotation, scale, skew, and transformation-center components. + """ + + translateX: float = 0 + translateY: float = 0 + rotation: float = 0 # in degrees, counter-clockwise + scaleX: float = 1 + scaleY: float = 1 + skewX: float = 0 # in degrees, clockwise + skewY: float = 0 # in degrees, counter-clockwise + tCenterX: float = 0 + tCenterY: float = 0 + + @classmethod + def fromTransform(self, transform): + # Adapted from an answer on + # https://math.stackexchange.com/questions/13150/extracting-rotation-scale-values-from-2d-transformation-matrix + a, b, c, d, x, y = transform + + sx = math.copysign(1, a) + if sx < 0: + a *= sx + b *= sx + + delta = a * d - b * c + + rotation = 0 + scaleX = scaleY = 0 + skewX = skewY = 0 + + # Apply the QR-like decomposition. + if a != 0 or b != 0: + r = math.sqrt(a * a + b * b) + rotation = math.acos(a / r) if b >= 0 else -math.acos(a / r) + scaleX, scaleY = (r, delta / r) + skewX, skewY = (math.atan((a * c + b * d) / (r * r)), 0) + elif c != 0 or d != 0: + s = math.sqrt(c * c + d * d) + rotation = math.pi / 2 - ( + math.acos(-c / s) if d >= 0 else -math.acos(c / s) + ) + scaleX, scaleY = (delta / s, s) + skewX, skewY = (0, math.atan((a * c + b * d) / (s * s))) + else: + # a = b = c = d = 0 + pass + + return DecomposedTransform( + x, + y, + math.degrees(rotation), + scaleX * sx, + scaleY, + math.degrees(skewX) * sx, + math.degrees(skewY), + 0, + 0, + ) + + def toTransform(self): + """Return the Transform() equivalent of this transformation. + + :Example: + >>> DecomposedTransform(scaleX=2, scaleY=2).toTransform() + + >>> + """ + t = Transform() + t = t.translate( + self.translateX + self.tCenterX, self.translateY + self.tCenterY + ) + t = t.rotate(math.radians(self.rotation)) + t = t.scale(self.scaleX, self.scaleY) + t = t.skew(math.radians(self.skewX), math.radians(self.skewY)) + t = t.translate(-self.tCenterX, -self.tCenterY) + return t + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/treeTools.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/treeTools.py new file mode 100644 index 00000000..24e10ba5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/treeTools.py @@ -0,0 +1,45 @@ +"""Generic tools for working with trees.""" + +from math import ceil, log + + +def build_n_ary_tree(leaves, n): + """Build N-ary tree from sequence of leaf nodes. + + Return a list of lists where each non-leaf node is a list containing + max n nodes. + """ + if not leaves: + return [] + + assert n > 1 + + depth = ceil(log(len(leaves), n)) + + if depth <= 1: + return list(leaves) + + # Fully populate complete subtrees of root until we have enough leaves left + root = [] + unassigned = None + full_step = n ** (depth - 1) + for i in range(0, len(leaves), full_step): + subtree = leaves[i : i + full_step] + if len(subtree) < full_step: + unassigned = subtree + break + while len(subtree) > n: + subtree = [subtree[k : k + n] for k in range(0, len(subtree), n)] + root.append(subtree) + + if unassigned: + # Recurse to fill the last subtree, which is the only partially populated one + subtree = build_n_ary_tree(unassigned, n) + if len(subtree) <= n - len(root): + # replace last subtree with its children if they can still fit + root.extend(subtree) + else: + root.append(subtree) + assert len(root) <= n + + return root diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/vector.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/vector.py new file mode 100644 index 00000000..666ff15c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/vector.py @@ -0,0 +1,148 @@ +from numbers import Number +import math +import operator +import warnings + + +__all__ = ["Vector"] + + +class Vector(tuple): + + """A math-like vector. + + Represents an n-dimensional numeric vector. ``Vector`` objects support + vector addition and subtraction, scalar multiplication and division, + negation, rounding, and comparison tests. + """ + + __slots__ = () + + def __new__(cls, values, keep=False): + if keep is not False: + warnings.warn( + "the 'keep' argument has been deprecated", + DeprecationWarning, + ) + if type(values) == Vector: + # No need to create a new object + return values + return super().__new__(cls, values) + + def __repr__(self): + return f"{self.__class__.__name__}({super().__repr__()})" + + def _vectorOp(self, other, op): + if isinstance(other, Vector): + assert len(self) == len(other) + return self.__class__(op(a, b) for a, b in zip(self, other)) + if isinstance(other, Number): + return self.__class__(op(v, other) for v in self) + raise NotImplementedError() + + def _scalarOp(self, other, op): + if isinstance(other, Number): + return self.__class__(op(v, other) for v in self) + raise NotImplementedError() + + def _unaryOp(self, op): + return self.__class__(op(v) for v in self) + + def __add__(self, other): + return self._vectorOp(other, operator.add) + + __radd__ = __add__ + + def __sub__(self, other): + return self._vectorOp(other, operator.sub) + + def __rsub__(self, other): + return self._vectorOp(other, _operator_rsub) + + def __mul__(self, other): + return self._scalarOp(other, operator.mul) + + __rmul__ = __mul__ + + def __truediv__(self, other): + return self._scalarOp(other, operator.truediv) + + def __rtruediv__(self, other): + return self._scalarOp(other, _operator_rtruediv) + + def __pos__(self): + return self._unaryOp(operator.pos) + + def __neg__(self): + return self._unaryOp(operator.neg) + + def __round__(self, *, round=round): + return self._unaryOp(round) + + def __eq__(self, other): + if isinstance(other, list): + # bw compat Vector([1, 2, 3]) == [1, 2, 3] + other = tuple(other) + return super().__eq__(other) + + def __ne__(self, other): + return not self.__eq__(other) + + def __bool__(self): + return any(self) + + __nonzero__ = __bool__ + + def __abs__(self): + return math.sqrt(sum(x * x for x in self)) + + def length(self): + """Return the length of the vector. Equivalent to abs(vector).""" + return abs(self) + + def normalized(self): + """Return the normalized vector of the vector.""" + return self / abs(self) + + def dot(self, other): + """Performs vector dot product, returning the sum of + ``a[0] * b[0], a[1] * b[1], ...``""" + assert len(self) == len(other) + return sum(a * b for a, b in zip(self, other)) + + # Deprecated methods/properties + + def toInt(self): + warnings.warn( + "the 'toInt' method has been deprecated, use round(vector) instead", + DeprecationWarning, + ) + return self.__round__() + + @property + def values(self): + warnings.warn( + "the 'values' attribute has been deprecated, use " + "the vector object itself instead", + DeprecationWarning, + ) + return list(self) + + @values.setter + def values(self, values): + raise AttributeError( + "can't set attribute, the 'values' attribute has been deprecated", + ) + + def isclose(self, other: "Vector", **kwargs) -> bool: + """Return True if the vector is close to another Vector.""" + assert len(self) == len(other) + return all(math.isclose(a, b, **kwargs) for a, b in zip(self, other)) + + +def _operator_rsub(a, b): + return operator.sub(b, a) + + +def _operator_rtruediv(a, b): + return operator.truediv(b, a) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/visitor.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/visitor.py new file mode 100644 index 00000000..d2898954 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/visitor.py @@ -0,0 +1,141 @@ +"""Generic visitor pattern implementation for Python objects.""" + +import enum + + +class Visitor(object): + defaultStop = False + + @classmethod + def _register(celf, clazzes_attrs): + assert celf != Visitor, "Subclass Visitor instead." + if "_visitors" not in celf.__dict__: + celf._visitors = {} + + def wrapper(method): + assert method.__name__ == "visit" + for clazzes, attrs in clazzes_attrs: + if type(clazzes) != tuple: + clazzes = (clazzes,) + if type(attrs) == str: + attrs = (attrs,) + for clazz in clazzes: + _visitors = celf._visitors.setdefault(clazz, {}) + for attr in attrs: + assert attr not in _visitors, ( + "Oops, class '%s' has visitor function for '%s' defined already." + % (clazz.__name__, attr) + ) + _visitors[attr] = method + return None + + return wrapper + + @classmethod + def register(celf, clazzes): + if type(clazzes) != tuple: + clazzes = (clazzes,) + return celf._register([(clazzes, (None,))]) + + @classmethod + def register_attr(celf, clazzes, attrs): + clazzes_attrs = [] + if type(clazzes) != tuple: + clazzes = (clazzes,) + if type(attrs) == str: + attrs = (attrs,) + for clazz in clazzes: + clazzes_attrs.append((clazz, attrs)) + return celf._register(clazzes_attrs) + + @classmethod + def register_attrs(celf, clazzes_attrs): + return celf._register(clazzes_attrs) + + @classmethod + def _visitorsFor(celf, thing, _default={}): + typ = type(thing) + + for celf in celf.mro(): + _visitors = getattr(celf, "_visitors", None) + if _visitors is None: + break + + m = celf._visitors.get(typ, None) + if m is not None: + return m + + return _default + + def visitObject(self, obj, *args, **kwargs): + """Called to visit an object. This function loops over all non-private + attributes of the objects and calls any user-registered (via + @register_attr() or @register_attrs()) visit() functions. + + If there is no user-registered visit function, of if there is and it + returns True, or it returns None (or doesn't return anything) and + visitor.defaultStop is False (default), then the visitor will proceed + to call self.visitAttr()""" + + keys = sorted(vars(obj).keys()) + _visitors = self._visitorsFor(obj) + defaultVisitor = _visitors.get("*", None) + for key in keys: + if key[0] == "_": + continue + value = getattr(obj, key) + visitorFunc = _visitors.get(key, defaultVisitor) + if visitorFunc is not None: + ret = visitorFunc(self, obj, key, value, *args, **kwargs) + if ret == False or (ret is None and self.defaultStop): + continue + self.visitAttr(obj, key, value, *args, **kwargs) + + def visitAttr(self, obj, attr, value, *args, **kwargs): + """Called to visit an attribute of an object.""" + self.visit(value, *args, **kwargs) + + def visitList(self, obj, *args, **kwargs): + """Called to visit any value that is a list.""" + for value in obj: + self.visit(value, *args, **kwargs) + + def visitDict(self, obj, *args, **kwargs): + """Called to visit any value that is a dictionary.""" + for value in obj.values(): + self.visit(value, *args, **kwargs) + + def visitLeaf(self, obj, *args, **kwargs): + """Called to visit any value that is not an object, list, + or dictionary.""" + pass + + def visit(self, obj, *args, **kwargs): + """This is the main entry to the visitor. The visitor will visit object + obj. + + The visitor will first determine if there is a registered (via + @register()) visit function for the type of object. If there is, it + will be called, and (visitor, obj, *args, **kwargs) will be passed to + the user visit function. + + If there is no user-registered visit function, of if there is and it + returns True, or it returns None (or doesn't return anything) and + visitor.defaultStop is False (default), then the visitor will proceed + to dispatch to one of self.visitObject(), self.visitList(), + self.visitDict(), or self.visitLeaf() (any of which can be overriden in + a subclass).""" + + visitorFunc = self._visitorsFor(obj).get(None, None) + if visitorFunc is not None: + ret = visitorFunc(self, obj, *args, **kwargs) + if ret == False or (ret is None and self.defaultStop): + return + if hasattr(obj, "__dict__") and not isinstance(obj, enum.Enum): + self.visitObject(obj, *args, **kwargs) + elif isinstance(obj, list): + self.visitList(obj, *args, **kwargs) + elif isinstance(obj, dict): + self.visitDict(obj, *args, **kwargs) + else: + self.visitLeaf(obj, *args, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlReader.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlReader.py new file mode 100644 index 00000000..d8e502f1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlReader.py @@ -0,0 +1,188 @@ +from fontTools import ttLib +from fontTools.misc.textTools import safeEval +from fontTools.ttLib.tables.DefaultTable import DefaultTable +import sys +import os +import logging + + +log = logging.getLogger(__name__) + + +class TTXParseError(Exception): + pass + + +BUFSIZE = 0x4000 + + +class XMLReader(object): + def __init__( + self, fileOrPath, ttFont, progress=None, quiet=None, contentOnly=False + ): + if fileOrPath == "-": + fileOrPath = sys.stdin + if not hasattr(fileOrPath, "read"): + self.file = open(fileOrPath, "rb") + self._closeStream = True + else: + # assume readable file object + self.file = fileOrPath + self._closeStream = False + self.ttFont = ttFont + self.progress = progress + if quiet is not None: + from fontTools.misc.loggingTools import deprecateArgument + + deprecateArgument("quiet", "configure logging instead") + self.quiet = quiet + self.root = None + self.contentStack = [] + self.contentOnly = contentOnly + self.stackSize = 0 + + def read(self, rootless=False): + if rootless: + self.stackSize += 1 + if self.progress: + self.file.seek(0, 2) + fileSize = self.file.tell() + self.progress.set(0, fileSize // 100 or 1) + self.file.seek(0) + self._parseFile(self.file) + if self._closeStream: + self.close() + if rootless: + self.stackSize -= 1 + + def close(self): + self.file.close() + + def _parseFile(self, file): + from xml.parsers.expat import ParserCreate + + parser = ParserCreate() + parser.StartElementHandler = self._startElementHandler + parser.EndElementHandler = self._endElementHandler + parser.CharacterDataHandler = self._characterDataHandler + + pos = 0 + while True: + chunk = file.read(BUFSIZE) + if not chunk: + parser.Parse(chunk, 1) + break + pos = pos + len(chunk) + if self.progress: + self.progress.set(pos // 100) + parser.Parse(chunk, 0) + + def _startElementHandler(self, name, attrs): + if self.stackSize == 1 and self.contentOnly: + # We already know the table we're parsing, skip + # parsing the table tag and continue to + # stack '2' which begins parsing content + self.contentStack.append([]) + self.stackSize = 2 + return + stackSize = self.stackSize + self.stackSize = stackSize + 1 + subFile = attrs.get("src") + if subFile is not None: + if hasattr(self.file, "name"): + # if file has a name, get its parent directory + dirname = os.path.dirname(self.file.name) + else: + # else fall back to using the current working directory + dirname = os.getcwd() + subFile = os.path.join(dirname, subFile) + if not stackSize: + if name != "ttFont": + raise TTXParseError("illegal root tag: %s" % name) + if self.ttFont.reader is None and not self.ttFont.tables: + sfntVersion = attrs.get("sfntVersion") + if sfntVersion is not None: + if len(sfntVersion) != 4: + sfntVersion = safeEval('"' + sfntVersion + '"') + self.ttFont.sfntVersion = sfntVersion + self.contentStack.append([]) + elif stackSize == 1: + if subFile is not None: + subReader = XMLReader(subFile, self.ttFont, self.progress) + subReader.read() + self.contentStack.append([]) + return + tag = ttLib.xmlToTag(name) + msg = "Parsing '%s' table..." % tag + if self.progress: + self.progress.setLabel(msg) + log.info(msg) + if tag == "GlyphOrder": + tableClass = ttLib.GlyphOrder + elif "ERROR" in attrs or ("raw" in attrs and safeEval(attrs["raw"])): + tableClass = DefaultTable + else: + tableClass = ttLib.getTableClass(tag) + if tableClass is None: + tableClass = DefaultTable + if tag == "loca" and tag in self.ttFont: + # Special-case the 'loca' table as we need the + # original if the 'glyf' table isn't recompiled. + self.currentTable = self.ttFont[tag] + else: + self.currentTable = tableClass(tag) + self.ttFont[tag] = self.currentTable + self.contentStack.append([]) + elif stackSize == 2 and subFile is not None: + subReader = XMLReader(subFile, self.ttFont, self.progress, contentOnly=True) + subReader.read() + self.contentStack.append([]) + self.root = subReader.root + elif stackSize == 2: + self.contentStack.append([]) + self.root = (name, attrs, self.contentStack[-1]) + else: + l = [] + self.contentStack[-1].append((name, attrs, l)) + self.contentStack.append(l) + + def _characterDataHandler(self, data): + if self.stackSize > 1: + # parser parses in chunks, so we may get multiple calls + # for the same text node; thus we need to append the data + # to the last item in the content stack: + # https://github.com/fonttools/fonttools/issues/2614 + if ( + data != "\n" + and self.contentStack[-1] + and isinstance(self.contentStack[-1][-1], str) + and self.contentStack[-1][-1] != "\n" + ): + self.contentStack[-1][-1] += data + else: + self.contentStack[-1].append(data) + + def _endElementHandler(self, name): + self.stackSize = self.stackSize - 1 + del self.contentStack[-1] + if not self.contentOnly: + if self.stackSize == 1: + self.root = None + elif self.stackSize == 2: + name, attrs, content = self.root + self.currentTable.fromXML(name, attrs, content, self.ttFont) + self.root = None + + +class ProgressPrinter(object): + def __init__(self, title, maxval=100): + print(title) + + def set(self, val, maxval=None): + pass + + def increment(self, val=1): + pass + + def setLabel(self, text): + print(text) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlWriter.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlWriter.py new file mode 100644 index 00000000..9a8dc3e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/misc/xmlWriter.py @@ -0,0 +1,204 @@ +"""xmlWriter.py -- Simple XML authoring class""" + +from fontTools.misc.textTools import byteord, strjoin, tobytes, tostr +import sys +import os +import string + +INDENT = " " + + +class XMLWriter(object): + def __init__( + self, + fileOrPath, + indentwhite=INDENT, + idlefunc=None, + encoding="utf_8", + newlinestr="\n", + ): + if encoding.lower().replace("-", "").replace("_", "") != "utf8": + raise Exception("Only UTF-8 encoding is supported.") + if fileOrPath == "-": + fileOrPath = sys.stdout + if not hasattr(fileOrPath, "write"): + self.filename = fileOrPath + self.file = open(fileOrPath, "wb") + self._closeStream = True + else: + self.filename = None + # assume writable file object + self.file = fileOrPath + self._closeStream = False + + # Figure out if writer expects bytes or unicodes + try: + # The bytes check should be first. See: + # https://github.com/fonttools/fonttools/pull/233 + self.file.write(b"") + self.totype = tobytes + except TypeError: + # This better not fail. + self.file.write("") + self.totype = tostr + self.indentwhite = self.totype(indentwhite) + if newlinestr is None: + self.newlinestr = self.totype(os.linesep) + else: + self.newlinestr = self.totype(newlinestr) + self.indentlevel = 0 + self.stack = [] + self.needindent = 1 + self.idlefunc = idlefunc + self.idlecounter = 0 + self._writeraw('') + self.newline() + + def __enter__(self): + return self + + def __exit__(self, exception_type, exception_value, traceback): + self.close() + + def close(self): + if self._closeStream: + self.file.close() + + def write(self, string, indent=True): + """Writes text.""" + self._writeraw(escape(string), indent=indent) + + def writecdata(self, string): + """Writes text in a CDATA section.""" + self._writeraw("") + + def write8bit(self, data, strip=False): + """Writes a bytes() sequence into the XML, escaping + non-ASCII bytes. When this is read in xmlReader, + the original bytes can be recovered by encoding to + 'latin-1'.""" + self._writeraw(escape8bit(data), strip=strip) + + def write_noindent(self, string): + """Writes text without indentation.""" + self._writeraw(escape(string), indent=False) + + def _writeraw(self, data, indent=True, strip=False): + """Writes bytes, possibly indented.""" + if indent and self.needindent: + self.file.write(self.indentlevel * self.indentwhite) + self.needindent = 0 + s = self.totype(data, encoding="utf_8") + if strip: + s = s.strip() + self.file.write(s) + + def newline(self): + self.file.write(self.newlinestr) + self.needindent = 1 + idlecounter = self.idlecounter + if not idlecounter % 100 and self.idlefunc is not None: + self.idlefunc() + self.idlecounter = idlecounter + 1 + + def comment(self, data): + data = escape(data) + lines = data.split("\n") + self._writeraw("") + + def simpletag(self, _TAG_, *args, **kwargs): + attrdata = self.stringifyattrs(*args, **kwargs) + data = "<%s%s/>" % (_TAG_, attrdata) + self._writeraw(data) + + def begintag(self, _TAG_, *args, **kwargs): + attrdata = self.stringifyattrs(*args, **kwargs) + data = "<%s%s>" % (_TAG_, attrdata) + self._writeraw(data) + self.stack.append(_TAG_) + self.indent() + + def endtag(self, _TAG_): + assert self.stack and self.stack[-1] == _TAG_, "nonmatching endtag" + del self.stack[-1] + self.dedent() + data = "" % _TAG_ + self._writeraw(data) + + def dumphex(self, data): + linelength = 16 + hexlinelength = linelength * 2 + chunksize = 8 + for i in range(0, len(data), linelength): + hexline = hexStr(data[i : i + linelength]) + line = "" + white = "" + for j in range(0, hexlinelength, chunksize): + line = line + white + hexline[j : j + chunksize] + white = " " + self._writeraw(line) + self.newline() + + def indent(self): + self.indentlevel = self.indentlevel + 1 + + def dedent(self): + assert self.indentlevel > 0 + self.indentlevel = self.indentlevel - 1 + + def stringifyattrs(self, *args, **kwargs): + if kwargs: + assert not args + attributes = sorted(kwargs.items()) + elif args: + assert len(args) == 1 + attributes = args[0] + else: + return "" + data = "" + for attr, value in attributes: + if not isinstance(value, (bytes, str)): + value = str(value) + data = data + ' %s="%s"' % (attr, escapeattr(value)) + return data + + +def escape(data): + data = tostr(data, "utf_8") + data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + data = data.replace("\r", " ") + return data + + +def escapeattr(data): + data = escape(data) + data = data.replace('"', """) + return data + + +def escape8bit(data): + """Input is Unicode string.""" + + def escapechar(c): + n = ord(c) + if 32 <= n <= 127 and c not in "<&>": + return c + else: + return "&#" + repr(n) + ";" + + return strjoin(map(escapechar, data.decode("latin-1"))) + + +def hexStr(s): + h = string.hexdigits + r = "" + for c in s: + i = byteord(c) + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__init__.py new file mode 100644 index 00000000..dbedf275 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__init__.py @@ -0,0 +1,1402 @@ +#!/usr/bin/python + +# FontDame-to-FontTools for OpenType Layout tables +# +# Source language spec is available at: +# http://monotype.github.io/OpenType_Table_Source/otl_source.html +# https://github.com/Monotype/OpenType_Table_Source/ + +from fontTools import ttLib +from fontTools.ttLib.tables._c_m_a_p import cmap_classes +from fontTools.ttLib.tables import otTables as ot +from fontTools.ttLib.tables.otBase import ValueRecord, valueRecordFormatDict +from fontTools.otlLib import builder as otl +from contextlib import contextmanager +from fontTools.ttLib import newTable +from fontTools.feaLib.lookupDebugInfo import LOOKUP_DEBUG_ENV_VAR, LOOKUP_DEBUG_INFO_KEY +from operator import setitem +import os +import logging + + +class MtiLibError(Exception): + pass + + +class ReferenceNotFoundError(MtiLibError): + pass + + +class FeatureNotFoundError(ReferenceNotFoundError): + pass + + +class LookupNotFoundError(ReferenceNotFoundError): + pass + + +log = logging.getLogger("fontTools.mtiLib") + + +def makeGlyph(s): + if s[:2] in ["U ", "u "]: + return ttLib.TTFont._makeGlyphName(int(s[2:], 16)) + elif s[:2] == "# ": + return "glyph%.5d" % int(s[2:]) + assert s.find(" ") < 0, "Space found in glyph name: %s" % s + assert s, "Glyph name is empty" + return s + + +def makeGlyphs(l): + return [makeGlyph(g) for g in l] + + +def mapLookup(sym, mapping): + # Lookups are addressed by name. So resolved them using a map if available. + # Fallback to parsing as lookup index if a map isn't provided. + if mapping is not None: + try: + idx = mapping[sym] + except KeyError: + raise LookupNotFoundError(sym) + else: + idx = int(sym) + return idx + + +def mapFeature(sym, mapping): + # Features are referenced by index according the spec. So, if symbol is an + # integer, use it directly. Otherwise look up in the map if provided. + try: + idx = int(sym) + except ValueError: + try: + idx = mapping[sym] + except KeyError: + raise FeatureNotFoundError(sym) + return idx + + +def setReference(mapper, mapping, sym, setter, collection, key): + try: + mapped = mapper(sym, mapping) + except ReferenceNotFoundError as e: + try: + if mapping is not None: + mapping.addDeferredMapping( + lambda ref: setter(collection, key, ref), sym, e + ) + return + except AttributeError: + pass + raise + setter(collection, key, mapped) + + +class DeferredMapping(dict): + def __init__(self): + self._deferredMappings = [] + + def addDeferredMapping(self, setter, sym, e): + log.debug("Adding deferred mapping for symbol '%s' %s", sym, type(e).__name__) + self._deferredMappings.append((setter, sym, e)) + + def applyDeferredMappings(self): + for setter, sym, e in self._deferredMappings: + log.debug( + "Applying deferred mapping for symbol '%s' %s", sym, type(e).__name__ + ) + try: + mapped = self[sym] + except KeyError: + raise e + setter(mapped) + log.debug("Set to %s", mapped) + self._deferredMappings = [] + + +def parseScriptList(lines, featureMap=None): + self = ot.ScriptList() + records = [] + with lines.between("script table"): + for line in lines: + while len(line) < 4: + line.append("") + scriptTag, langSysTag, defaultFeature, features = line + log.debug("Adding script %s language-system %s", scriptTag, langSysTag) + + langSys = ot.LangSys() + langSys.LookupOrder = None + if defaultFeature: + setReference( + mapFeature, + featureMap, + defaultFeature, + setattr, + langSys, + "ReqFeatureIndex", + ) + else: + langSys.ReqFeatureIndex = 0xFFFF + syms = stripSplitComma(features) + langSys.FeatureIndex = theList = [3] * len(syms) + for i, sym in enumerate(syms): + setReference(mapFeature, featureMap, sym, setitem, theList, i) + langSys.FeatureCount = len(langSys.FeatureIndex) + + script = [s for s in records if s.ScriptTag == scriptTag] + if script: + script = script[0].Script + else: + scriptRec = ot.ScriptRecord() + scriptRec.ScriptTag = scriptTag + " " * (4 - len(scriptTag)) + scriptRec.Script = ot.Script() + records.append(scriptRec) + script = scriptRec.Script + script.DefaultLangSys = None + script.LangSysRecord = [] + script.LangSysCount = 0 + + if langSysTag == "default": + script.DefaultLangSys = langSys + else: + langSysRec = ot.LangSysRecord() + langSysRec.LangSysTag = langSysTag + " " * (4 - len(langSysTag)) + langSysRec.LangSys = langSys + script.LangSysRecord.append(langSysRec) + script.LangSysCount = len(script.LangSysRecord) + + for script in records: + script.Script.LangSysRecord = sorted( + script.Script.LangSysRecord, key=lambda rec: rec.LangSysTag + ) + self.ScriptRecord = sorted(records, key=lambda rec: rec.ScriptTag) + self.ScriptCount = len(self.ScriptRecord) + return self + + +def parseFeatureList(lines, lookupMap=None, featureMap=None): + self = ot.FeatureList() + self.FeatureRecord = [] + with lines.between("feature table"): + for line in lines: + name, featureTag, lookups = line + if featureMap is not None: + assert name not in featureMap, "Duplicate feature name: %s" % name + featureMap[name] = len(self.FeatureRecord) + # If feature name is integer, make sure it matches its index. + try: + assert int(name) == len(self.FeatureRecord), "%d %d" % ( + name, + len(self.FeatureRecord), + ) + except ValueError: + pass + featureRec = ot.FeatureRecord() + featureRec.FeatureTag = featureTag + featureRec.Feature = ot.Feature() + self.FeatureRecord.append(featureRec) + feature = featureRec.Feature + feature.FeatureParams = None + syms = stripSplitComma(lookups) + feature.LookupListIndex = theList = [None] * len(syms) + for i, sym in enumerate(syms): + setReference(mapLookup, lookupMap, sym, setitem, theList, i) + feature.LookupCount = len(feature.LookupListIndex) + + self.FeatureCount = len(self.FeatureRecord) + return self + + +def parseLookupFlags(lines): + flags = 0 + filterset = None + allFlags = [ + "righttoleft", + "ignorebaseglyphs", + "ignoreligatures", + "ignoremarks", + "markattachmenttype", + "markfiltertype", + ] + while lines.peeks()[0].lower() in allFlags: + line = next(lines) + flag = { + "righttoleft": 0x0001, + "ignorebaseglyphs": 0x0002, + "ignoreligatures": 0x0004, + "ignoremarks": 0x0008, + }.get(line[0].lower()) + if flag: + assert line[1].lower() in ["yes", "no"], line[1] + if line[1].lower() == "yes": + flags |= flag + continue + if line[0].lower() == "markattachmenttype": + flags |= int(line[1]) << 8 + continue + if line[0].lower() == "markfiltertype": + flags |= 0x10 + filterset = int(line[1]) + return flags, filterset + + +def parseSingleSubst(lines, font, _lookupMap=None): + mapping = {} + for line in lines: + assert len(line) == 2, line + line = makeGlyphs(line) + mapping[line[0]] = line[1] + return otl.buildSingleSubstSubtable(mapping) + + +def parseMultiple(lines, font, _lookupMap=None): + mapping = {} + for line in lines: + line = makeGlyphs(line) + mapping[line[0]] = line[1:] + return otl.buildMultipleSubstSubtable(mapping) + + +def parseAlternate(lines, font, _lookupMap=None): + mapping = {} + for line in lines: + line = makeGlyphs(line) + mapping[line[0]] = line[1:] + return otl.buildAlternateSubstSubtable(mapping) + + +def parseLigature(lines, font, _lookupMap=None): + mapping = {} + for line in lines: + assert len(line) >= 2, line + line = makeGlyphs(line) + mapping[tuple(line[1:])] = line[0] + return otl.buildLigatureSubstSubtable(mapping) + + +def parseSinglePos(lines, font, _lookupMap=None): + values = {} + for line in lines: + assert len(line) == 3, line + w = line[0].title().replace(" ", "") + assert w in valueRecordFormatDict + g = makeGlyph(line[1]) + v = int(line[2]) + if g not in values: + values[g] = ValueRecord() + assert not hasattr(values[g], w), (g, w) + setattr(values[g], w, v) + return otl.buildSinglePosSubtable(values, font.getReverseGlyphMap()) + + +def parsePair(lines, font, _lookupMap=None): + self = ot.PairPos() + self.ValueFormat1 = self.ValueFormat2 = 0 + typ = lines.peeks()[0].split()[0].lower() + if typ in ("left", "right"): + self.Format = 1 + values = {} + for line in lines: + assert len(line) == 4, line + side = line[0].split()[0].lower() + assert side in ("left", "right"), side + what = line[0][len(side) :].title().replace(" ", "") + mask = valueRecordFormatDict[what][0] + glyph1, glyph2 = makeGlyphs(line[1:3]) + value = int(line[3]) + if not glyph1 in values: + values[glyph1] = {} + if not glyph2 in values[glyph1]: + values[glyph1][glyph2] = (ValueRecord(), ValueRecord()) + rec2 = values[glyph1][glyph2] + if side == "left": + self.ValueFormat1 |= mask + vr = rec2[0] + else: + self.ValueFormat2 |= mask + vr = rec2[1] + assert not hasattr(vr, what), (vr, what) + setattr(vr, what, value) + self.Coverage = makeCoverage(set(values.keys()), font) + self.PairSet = [] + for glyph1 in self.Coverage.glyphs: + values1 = values[glyph1] + pairset = ot.PairSet() + records = pairset.PairValueRecord = [] + for glyph2 in sorted(values1.keys(), key=font.getGlyphID): + values2 = values1[glyph2] + pair = ot.PairValueRecord() + pair.SecondGlyph = glyph2 + pair.Value1 = values2[0] + pair.Value2 = values2[1] if self.ValueFormat2 else None + records.append(pair) + pairset.PairValueCount = len(pairset.PairValueRecord) + self.PairSet.append(pairset) + self.PairSetCount = len(self.PairSet) + elif typ.endswith("class"): + self.Format = 2 + classDefs = [None, None] + while lines.peeks()[0].endswith("class definition begin"): + typ = lines.peek()[0][: -len("class definition begin")].lower() + idx, klass = { + "first": (0, ot.ClassDef1), + "second": (1, ot.ClassDef2), + }[typ] + assert classDefs[idx] is None + classDefs[idx] = parseClassDef(lines, font, klass=klass) + self.ClassDef1, self.ClassDef2 = classDefs + self.Class1Count, self.Class2Count = ( + 1 + max(c.classDefs.values()) for c in classDefs + ) + self.Class1Record = [ot.Class1Record() for i in range(self.Class1Count)] + for rec1 in self.Class1Record: + rec1.Class2Record = [ot.Class2Record() for j in range(self.Class2Count)] + for rec2 in rec1.Class2Record: + rec2.Value1 = ValueRecord() + rec2.Value2 = ValueRecord() + for line in lines: + assert len(line) == 4, line + side = line[0].split()[0].lower() + assert side in ("left", "right"), side + what = line[0][len(side) :].title().replace(" ", "") + mask = valueRecordFormatDict[what][0] + class1, class2, value = (int(x) for x in line[1:4]) + rec2 = self.Class1Record[class1].Class2Record[class2] + if side == "left": + self.ValueFormat1 |= mask + vr = rec2.Value1 + else: + self.ValueFormat2 |= mask + vr = rec2.Value2 + assert not hasattr(vr, what), (vr, what) + setattr(vr, what, value) + for rec1 in self.Class1Record: + for rec2 in rec1.Class2Record: + rec2.Value1 = ValueRecord(self.ValueFormat1, rec2.Value1) + rec2.Value2 = ( + ValueRecord(self.ValueFormat2, rec2.Value2) + if self.ValueFormat2 + else None + ) + + self.Coverage = makeCoverage(set(self.ClassDef1.classDefs.keys()), font) + else: + assert 0, typ + return self + + +def parseKernset(lines, font, _lookupMap=None): + typ = lines.peeks()[0].split()[0].lower() + if typ in ("left", "right"): + with lines.until( + ("firstclass definition begin", "secondclass definition begin") + ): + return parsePair(lines, font) + return parsePair(lines, font) + + +def makeAnchor(data, klass=ot.Anchor): + assert len(data) <= 2 + anchor = klass() + anchor.Format = 1 + anchor.XCoordinate, anchor.YCoordinate = intSplitComma(data[0]) + if len(data) > 1 and data[1] != "": + anchor.Format = 2 + anchor.AnchorPoint = int(data[1]) + return anchor + + +def parseCursive(lines, font, _lookupMap=None): + records = {} + for line in lines: + assert len(line) in [3, 4], line + idx, klass = { + "entry": (0, ot.EntryAnchor), + "exit": (1, ot.ExitAnchor), + }[line[0]] + glyph = makeGlyph(line[1]) + if glyph not in records: + records[glyph] = [None, None] + assert records[glyph][idx] is None, (glyph, idx) + records[glyph][idx] = makeAnchor(line[2:], klass) + return otl.buildCursivePosSubtable(records, font.getReverseGlyphMap()) + + +def makeMarkRecords(data, coverage, c): + records = [] + for glyph in coverage.glyphs: + klass, anchor = data[glyph] + record = c.MarkRecordClass() + record.Class = klass + setattr(record, c.MarkAnchor, anchor) + records.append(record) + return records + + +def makeBaseRecords(data, coverage, c, classCount): + records = [] + idx = {} + for glyph in coverage.glyphs: + idx[glyph] = len(records) + record = c.BaseRecordClass() + anchors = [None] * classCount + setattr(record, c.BaseAnchor, anchors) + records.append(record) + for (glyph, klass), anchor in data.items(): + record = records[idx[glyph]] + anchors = getattr(record, c.BaseAnchor) + assert anchors[klass] is None, (glyph, klass) + anchors[klass] = anchor + return records + + +def makeLigatureRecords(data, coverage, c, classCount): + records = [None] * len(coverage.glyphs) + idx = {g: i for i, g in enumerate(coverage.glyphs)} + + for (glyph, klass, compIdx, compCount), anchor in data.items(): + record = records[idx[glyph]] + if record is None: + record = records[idx[glyph]] = ot.LigatureAttach() + record.ComponentCount = compCount + record.ComponentRecord = [ot.ComponentRecord() for i in range(compCount)] + for compRec in record.ComponentRecord: + compRec.LigatureAnchor = [None] * classCount + assert record.ComponentCount == compCount, ( + glyph, + record.ComponentCount, + compCount, + ) + + anchors = record.ComponentRecord[compIdx - 1].LigatureAnchor + assert anchors[klass] is None, (glyph, compIdx, klass) + anchors[klass] = anchor + return records + + +def parseMarkToSomething(lines, font, c): + self = c.Type() + self.Format = 1 + markData = {} + baseData = {} + Data = { + "mark": (markData, c.MarkAnchorClass), + "base": (baseData, c.BaseAnchorClass), + "ligature": (baseData, c.BaseAnchorClass), + } + maxKlass = 0 + for line in lines: + typ = line[0] + assert typ in ("mark", "base", "ligature") + glyph = makeGlyph(line[1]) + data, anchorClass = Data[typ] + extraItems = 2 if typ == "ligature" else 0 + extras = tuple(int(i) for i in line[2 : 2 + extraItems]) + klass = int(line[2 + extraItems]) + anchor = makeAnchor(line[3 + extraItems :], anchorClass) + if typ == "mark": + key, value = glyph, (klass, anchor) + else: + key, value = ((glyph, klass) + extras), anchor + assert key not in data, key + data[key] = value + maxKlass = max(maxKlass, klass) + + # Mark + markCoverage = makeCoverage(set(markData.keys()), font, c.MarkCoverageClass) + markArray = c.MarkArrayClass() + markRecords = makeMarkRecords(markData, markCoverage, c) + setattr(markArray, c.MarkRecord, markRecords) + setattr(markArray, c.MarkCount, len(markRecords)) + setattr(self, c.MarkCoverage, markCoverage) + setattr(self, c.MarkArray, markArray) + self.ClassCount = maxKlass + 1 + + # Base + self.classCount = 0 if not baseData else 1 + max(k[1] for k, v in baseData.items()) + baseCoverage = makeCoverage( + set([k[0] for k in baseData.keys()]), font, c.BaseCoverageClass + ) + baseArray = c.BaseArrayClass() + if c.Base == "Ligature": + baseRecords = makeLigatureRecords(baseData, baseCoverage, c, self.classCount) + else: + baseRecords = makeBaseRecords(baseData, baseCoverage, c, self.classCount) + setattr(baseArray, c.BaseRecord, baseRecords) + setattr(baseArray, c.BaseCount, len(baseRecords)) + setattr(self, c.BaseCoverage, baseCoverage) + setattr(self, c.BaseArray, baseArray) + + return self + + +class MarkHelper(object): + def __init__(self): + for Which in ("Mark", "Base"): + for What in ("Coverage", "Array", "Count", "Record", "Anchor"): + key = Which + What + if Which == "Mark" and What in ("Count", "Record", "Anchor"): + value = key + else: + value = getattr(self, Which) + What + if value == "LigatureRecord": + value = "LigatureAttach" + setattr(self, key, value) + if What != "Count": + klass = getattr(ot, value) + setattr(self, key + "Class", klass) + + +class MarkToBaseHelper(MarkHelper): + Mark = "Mark" + Base = "Base" + Type = ot.MarkBasePos + + +class MarkToMarkHelper(MarkHelper): + Mark = "Mark1" + Base = "Mark2" + Type = ot.MarkMarkPos + + +class MarkToLigatureHelper(MarkHelper): + Mark = "Mark" + Base = "Ligature" + Type = ot.MarkLigPos + + +def parseMarkToBase(lines, font, _lookupMap=None): + return parseMarkToSomething(lines, font, MarkToBaseHelper()) + + +def parseMarkToMark(lines, font, _lookupMap=None): + return parseMarkToSomething(lines, font, MarkToMarkHelper()) + + +def parseMarkToLigature(lines, font, _lookupMap=None): + return parseMarkToSomething(lines, font, MarkToLigatureHelper()) + + +def stripSplitComma(line): + return [s.strip() for s in line.split(",")] if line else [] + + +def intSplitComma(line): + return [int(i) for i in line.split(",")] if line else [] + + +# Copied from fontTools.subset +class ContextHelper(object): + def __init__(self, klassName, Format): + if klassName.endswith("Subst"): + Typ = "Sub" + Type = "Subst" + else: + Typ = "Pos" + Type = "Pos" + if klassName.startswith("Chain"): + Chain = "Chain" + InputIdx = 1 + DataLen = 3 + else: + Chain = "" + InputIdx = 0 + DataLen = 1 + ChainTyp = Chain + Typ + + self.Typ = Typ + self.Type = Type + self.Chain = Chain + self.ChainTyp = ChainTyp + self.InputIdx = InputIdx + self.DataLen = DataLen + + self.LookupRecord = Type + "LookupRecord" + + if Format == 1: + Coverage = lambda r: r.Coverage + ChainCoverage = lambda r: r.Coverage + ContextData = lambda r: (None,) + ChainContextData = lambda r: (None, None, None) + SetContextData = None + SetChainContextData = None + RuleData = lambda r: (r.Input,) + ChainRuleData = lambda r: (r.Backtrack, r.Input, r.LookAhead) + + def SetRuleData(r, d): + (r.Input,) = d + (r.GlyphCount,) = (len(x) + 1 for x in d) + + def ChainSetRuleData(r, d): + (r.Backtrack, r.Input, r.LookAhead) = d + ( + r.BacktrackGlyphCount, + r.InputGlyphCount, + r.LookAheadGlyphCount, + ) = (len(d[0]), len(d[1]) + 1, len(d[2])) + + elif Format == 2: + Coverage = lambda r: r.Coverage + ChainCoverage = lambda r: r.Coverage + ContextData = lambda r: (r.ClassDef,) + ChainContextData = lambda r: ( + r.BacktrackClassDef, + r.InputClassDef, + r.LookAheadClassDef, + ) + + def SetContextData(r, d): + (r.ClassDef,) = d + + def SetChainContextData(r, d): + (r.BacktrackClassDef, r.InputClassDef, r.LookAheadClassDef) = d + + RuleData = lambda r: (r.Class,) + ChainRuleData = lambda r: (r.Backtrack, r.Input, r.LookAhead) + + def SetRuleData(r, d): + (r.Class,) = d + (r.GlyphCount,) = (len(x) + 1 for x in d) + + def ChainSetRuleData(r, d): + (r.Backtrack, r.Input, r.LookAhead) = d + ( + r.BacktrackGlyphCount, + r.InputGlyphCount, + r.LookAheadGlyphCount, + ) = (len(d[0]), len(d[1]) + 1, len(d[2])) + + elif Format == 3: + Coverage = lambda r: r.Coverage[0] + ChainCoverage = lambda r: r.InputCoverage[0] + ContextData = None + ChainContextData = None + SetContextData = None + SetChainContextData = None + RuleData = lambda r: r.Coverage + ChainRuleData = lambda r: ( + r.BacktrackCoverage + r.InputCoverage + r.LookAheadCoverage + ) + + def SetRuleData(r, d): + (r.Coverage,) = d + (r.GlyphCount,) = (len(x) for x in d) + + def ChainSetRuleData(r, d): + (r.BacktrackCoverage, r.InputCoverage, r.LookAheadCoverage) = d + ( + r.BacktrackGlyphCount, + r.InputGlyphCount, + r.LookAheadGlyphCount, + ) = (len(x) for x in d) + + else: + assert 0, "unknown format: %s" % Format + + if Chain: + self.Coverage = ChainCoverage + self.ContextData = ChainContextData + self.SetContextData = SetChainContextData + self.RuleData = ChainRuleData + self.SetRuleData = ChainSetRuleData + else: + self.Coverage = Coverage + self.ContextData = ContextData + self.SetContextData = SetContextData + self.RuleData = RuleData + self.SetRuleData = SetRuleData + + if Format == 1: + self.Rule = ChainTyp + "Rule" + self.RuleCount = ChainTyp + "RuleCount" + self.RuleSet = ChainTyp + "RuleSet" + self.RuleSetCount = ChainTyp + "RuleSetCount" + self.Intersect = lambda glyphs, c, r: [r] if r in glyphs else [] + elif Format == 2: + self.Rule = ChainTyp + "ClassRule" + self.RuleCount = ChainTyp + "ClassRuleCount" + self.RuleSet = ChainTyp + "ClassSet" + self.RuleSetCount = ChainTyp + "ClassSetCount" + self.Intersect = lambda glyphs, c, r: ( + c.intersect_class(glyphs, r) + if c + else (set(glyphs) if r == 0 else set()) + ) + + self.ClassDef = "InputClassDef" if Chain else "ClassDef" + self.ClassDefIndex = 1 if Chain else 0 + self.Input = "Input" if Chain else "Class" + + +def parseLookupRecords(items, klassName, lookupMap=None): + klass = getattr(ot, klassName) + lst = [] + for item in items: + rec = klass() + item = stripSplitComma(item) + assert len(item) == 2, item + idx = int(item[0]) + assert idx > 0, idx + rec.SequenceIndex = idx - 1 + setReference(mapLookup, lookupMap, item[1], setattr, rec, "LookupListIndex") + lst.append(rec) + return lst + + +def makeClassDef(classDefs, font, klass=ot.Coverage): + if not classDefs: + return None + self = klass() + self.classDefs = dict(classDefs) + return self + + +def parseClassDef(lines, font, klass=ot.ClassDef): + classDefs = {} + with lines.between("class definition"): + for line in lines: + glyph = makeGlyph(line[0]) + assert glyph not in classDefs, glyph + classDefs[glyph] = int(line[1]) + return makeClassDef(classDefs, font, klass) + + +def makeCoverage(glyphs, font, klass=ot.Coverage): + if not glyphs: + return None + if isinstance(glyphs, set): + glyphs = sorted(glyphs) + coverage = klass() + coverage.glyphs = sorted(set(glyphs), key=font.getGlyphID) + return coverage + + +def parseCoverage(lines, font, klass=ot.Coverage): + glyphs = [] + with lines.between("coverage definition"): + for line in lines: + glyphs.append(makeGlyph(line[0])) + return makeCoverage(glyphs, font, klass) + + +def bucketizeRules(self, c, rules, bucketKeys): + buckets = {} + for seq, recs in rules: + buckets.setdefault(seq[c.InputIdx][0], []).append( + (tuple(s[1 if i == c.InputIdx else 0 :] for i, s in enumerate(seq)), recs) + ) + + rulesets = [] + for firstGlyph in bucketKeys: + if firstGlyph not in buckets: + rulesets.append(None) + continue + thisRules = [] + for seq, recs in buckets[firstGlyph]: + rule = getattr(ot, c.Rule)() + c.SetRuleData(rule, seq) + setattr(rule, c.Type + "Count", len(recs)) + setattr(rule, c.LookupRecord, recs) + thisRules.append(rule) + + ruleset = getattr(ot, c.RuleSet)() + setattr(ruleset, c.Rule, thisRules) + setattr(ruleset, c.RuleCount, len(thisRules)) + rulesets.append(ruleset) + + setattr(self, c.RuleSet, rulesets) + setattr(self, c.RuleSetCount, len(rulesets)) + + +def parseContext(lines, font, Type, lookupMap=None): + self = getattr(ot, Type)() + typ = lines.peeks()[0].split()[0].lower() + if typ == "glyph": + self.Format = 1 + log.debug("Parsing %s format %s", Type, self.Format) + c = ContextHelper(Type, self.Format) + rules = [] + for line in lines: + assert line[0].lower() == "glyph", line[0] + while len(line) < 1 + c.DataLen: + line.append("") + seq = tuple(makeGlyphs(stripSplitComma(i)) for i in line[1 : 1 + c.DataLen]) + recs = parseLookupRecords(line[1 + c.DataLen :], c.LookupRecord, lookupMap) + rules.append((seq, recs)) + + firstGlyphs = set(seq[c.InputIdx][0] for seq, recs in rules) + self.Coverage = makeCoverage(firstGlyphs, font) + bucketizeRules(self, c, rules, self.Coverage.glyphs) + elif typ.endswith("class"): + self.Format = 2 + log.debug("Parsing %s format %s", Type, self.Format) + c = ContextHelper(Type, self.Format) + classDefs = [None] * c.DataLen + while lines.peeks()[0].endswith("class definition begin"): + typ = lines.peek()[0][: -len("class definition begin")].lower() + idx, klass = { + 1: { + "": (0, ot.ClassDef), + }, + 3: { + "backtrack": (0, ot.BacktrackClassDef), + "": (1, ot.InputClassDef), + "lookahead": (2, ot.LookAheadClassDef), + }, + }[c.DataLen][typ] + assert classDefs[idx] is None, idx + classDefs[idx] = parseClassDef(lines, font, klass=klass) + c.SetContextData(self, classDefs) + rules = [] + for line in lines: + assert line[0].lower().startswith("class"), line[0] + while len(line) < 1 + c.DataLen: + line.append("") + seq = tuple(intSplitComma(i) for i in line[1 : 1 + c.DataLen]) + recs = parseLookupRecords(line[1 + c.DataLen :], c.LookupRecord, lookupMap) + rules.append((seq, recs)) + firstClasses = set(seq[c.InputIdx][0] for seq, recs in rules) + firstGlyphs = set( + g for g, c in classDefs[c.InputIdx].classDefs.items() if c in firstClasses + ) + self.Coverage = makeCoverage(firstGlyphs, font) + bucketizeRules(self, c, rules, range(max(firstClasses) + 1)) + elif typ.endswith("coverage"): + self.Format = 3 + log.debug("Parsing %s format %s", Type, self.Format) + c = ContextHelper(Type, self.Format) + coverages = tuple([] for i in range(c.DataLen)) + while lines.peeks()[0].endswith("coverage definition begin"): + typ = lines.peek()[0][: -len("coverage definition begin")].lower() + idx, klass = { + 1: { + "": (0, ot.Coverage), + }, + 3: { + "backtrack": (0, ot.BacktrackCoverage), + "input": (1, ot.InputCoverage), + "lookahead": (2, ot.LookAheadCoverage), + }, + }[c.DataLen][typ] + coverages[idx].append(parseCoverage(lines, font, klass=klass)) + c.SetRuleData(self, coverages) + lines = list(lines) + assert len(lines) == 1 + line = lines[0] + assert line[0].lower() == "coverage", line[0] + recs = parseLookupRecords(line[1:], c.LookupRecord, lookupMap) + setattr(self, c.Type + "Count", len(recs)) + setattr(self, c.LookupRecord, recs) + else: + assert 0, typ + return self + + +def parseContextSubst(lines, font, lookupMap=None): + return parseContext(lines, font, "ContextSubst", lookupMap=lookupMap) + + +def parseContextPos(lines, font, lookupMap=None): + return parseContext(lines, font, "ContextPos", lookupMap=lookupMap) + + +def parseChainedSubst(lines, font, lookupMap=None): + return parseContext(lines, font, "ChainContextSubst", lookupMap=lookupMap) + + +def parseChainedPos(lines, font, lookupMap=None): + return parseContext(lines, font, "ChainContextPos", lookupMap=lookupMap) + + +def parseReverseChainedSubst(lines, font, _lookupMap=None): + self = ot.ReverseChainSingleSubst() + self.Format = 1 + coverages = ([], []) + while lines.peeks()[0].endswith("coverage definition begin"): + typ = lines.peek()[0][: -len("coverage definition begin")].lower() + idx, klass = { + "backtrack": (0, ot.BacktrackCoverage), + "lookahead": (1, ot.LookAheadCoverage), + }[typ] + coverages[idx].append(parseCoverage(lines, font, klass=klass)) + self.BacktrackCoverage = coverages[0] + self.BacktrackGlyphCount = len(self.BacktrackCoverage) + self.LookAheadCoverage = coverages[1] + self.LookAheadGlyphCount = len(self.LookAheadCoverage) + mapping = {} + for line in lines: + assert len(line) == 2, line + line = makeGlyphs(line) + mapping[line[0]] = line[1] + self.Coverage = makeCoverage(set(mapping.keys()), font) + self.Substitute = [mapping[k] for k in self.Coverage.glyphs] + self.GlyphCount = len(self.Substitute) + return self + + +def parseLookup(lines, tableTag, font, lookupMap=None): + line = lines.expect("lookup") + _, name, typ = line + log.debug("Parsing lookup type %s %s", typ, name) + lookup = ot.Lookup() + lookup.LookupFlag, filterset = parseLookupFlags(lines) + if filterset is not None: + lookup.MarkFilteringSet = filterset + lookup.LookupType, parseLookupSubTable = { + "GSUB": { + "single": (1, parseSingleSubst), + "multiple": (2, parseMultiple), + "alternate": (3, parseAlternate), + "ligature": (4, parseLigature), + "context": (5, parseContextSubst), + "chained": (6, parseChainedSubst), + "reversechained": (8, parseReverseChainedSubst), + }, + "GPOS": { + "single": (1, parseSinglePos), + "pair": (2, parsePair), + "kernset": (2, parseKernset), + "cursive": (3, parseCursive), + "mark to base": (4, parseMarkToBase), + "mark to ligature": (5, parseMarkToLigature), + "mark to mark": (6, parseMarkToMark), + "context": (7, parseContextPos), + "chained": (8, parseChainedPos), + }, + }[tableTag][typ] + + with lines.until("lookup end"): + subtables = [] + + while lines.peek(): + with lines.until(("% subtable", "subtable end")): + while lines.peek(): + subtable = parseLookupSubTable(lines, font, lookupMap) + assert lookup.LookupType == subtable.LookupType + subtables.append(subtable) + if lines.peeks()[0] in ("% subtable", "subtable end"): + next(lines) + lines.expect("lookup end") + + lookup.SubTable = subtables + lookup.SubTableCount = len(lookup.SubTable) + if lookup.SubTableCount == 0: + # Remove this return when following is fixed: + # https://github.com/fonttools/fonttools/issues/789 + return None + return lookup + + +def parseGSUBGPOS(lines, font, tableTag): + container = ttLib.getTableClass(tableTag)() + lookupMap = DeferredMapping() + featureMap = DeferredMapping() + assert tableTag in ("GSUB", "GPOS") + log.debug("Parsing %s", tableTag) + self = getattr(ot, tableTag)() + self.Version = 0x00010000 + fields = { + "script table begin": ( + "ScriptList", + lambda lines: parseScriptList(lines, featureMap), + ), + "feature table begin": ( + "FeatureList", + lambda lines: parseFeatureList(lines, lookupMap, featureMap), + ), + "lookup": ("LookupList", None), + } + for attr, parser in fields.values(): + setattr(self, attr, None) + while lines.peek() is not None: + typ = lines.peek()[0].lower() + if typ not in fields: + log.debug("Skipping %s", lines.peek()) + next(lines) + continue + attr, parser = fields[typ] + if typ == "lookup": + if self.LookupList is None: + self.LookupList = ot.LookupList() + self.LookupList.Lookup = [] + _, name, _ = lines.peek() + lookup = parseLookup(lines, tableTag, font, lookupMap) + if lookupMap is not None: + assert name not in lookupMap, "Duplicate lookup name: %s" % name + lookupMap[name] = len(self.LookupList.Lookup) + else: + assert int(name) == len(self.LookupList.Lookup), "%d %d" % ( + name, + len(self.Lookup), + ) + self.LookupList.Lookup.append(lookup) + else: + assert getattr(self, attr) is None, attr + setattr(self, attr, parser(lines)) + if self.LookupList: + self.LookupList.LookupCount = len(self.LookupList.Lookup) + if lookupMap is not None: + lookupMap.applyDeferredMappings() + if os.environ.get(LOOKUP_DEBUG_ENV_VAR): + if "Debg" not in font: + font["Debg"] = newTable("Debg") + font["Debg"].data = {} + debug = ( + font["Debg"] + .data.setdefault(LOOKUP_DEBUG_INFO_KEY, {}) + .setdefault(tableTag, {}) + ) + for name, lookup in lookupMap.items(): + debug[str(lookup)] = ["", name, ""] + + featureMap.applyDeferredMappings() + container.table = self + return container + + +def parseGSUB(lines, font): + return parseGSUBGPOS(lines, font, "GSUB") + + +def parseGPOS(lines, font): + return parseGSUBGPOS(lines, font, "GPOS") + + +def parseAttachList(lines, font): + points = {} + with lines.between("attachment list"): + for line in lines: + glyph = makeGlyph(line[0]) + assert glyph not in points, glyph + points[glyph] = [int(i) for i in line[1:]] + return otl.buildAttachList(points, font.getReverseGlyphMap()) + + +def parseCaretList(lines, font): + carets = {} + with lines.between("carets"): + for line in lines: + glyph = makeGlyph(line[0]) + assert glyph not in carets, glyph + num = int(line[1]) + thisCarets = [int(i) for i in line[2:]] + assert num == len(thisCarets), line + carets[glyph] = thisCarets + return otl.buildLigCaretList(carets, {}, font.getReverseGlyphMap()) + + +def makeMarkFilteringSets(sets, font): + self = ot.MarkGlyphSetsDef() + self.MarkSetTableFormat = 1 + self.MarkSetCount = 1 + max(sets.keys()) + self.Coverage = [None] * self.MarkSetCount + for k, v in sorted(sets.items()): + self.Coverage[k] = makeCoverage(set(v), font) + return self + + +def parseMarkFilteringSets(lines, font): + sets = {} + with lines.between("set definition"): + for line in lines: + assert len(line) == 2, line + glyph = makeGlyph(line[0]) + # TODO accept set names + st = int(line[1]) + if st not in sets: + sets[st] = [] + sets[st].append(glyph) + return makeMarkFilteringSets(sets, font) + + +def parseGDEF(lines, font): + container = ttLib.getTableClass("GDEF")() + log.debug("Parsing GDEF") + self = ot.GDEF() + fields = { + "class definition begin": ( + "GlyphClassDef", + lambda lines, font: parseClassDef(lines, font, klass=ot.GlyphClassDef), + ), + "attachment list begin": ("AttachList", parseAttachList), + "carets begin": ("LigCaretList", parseCaretList), + "mark attachment class definition begin": ( + "MarkAttachClassDef", + lambda lines, font: parseClassDef(lines, font, klass=ot.MarkAttachClassDef), + ), + "markfilter set definition begin": ("MarkGlyphSetsDef", parseMarkFilteringSets), + } + for attr, parser in fields.values(): + setattr(self, attr, None) + while lines.peek() is not None: + typ = lines.peek()[0].lower() + if typ not in fields: + log.debug("Skipping %s", typ) + next(lines) + continue + attr, parser = fields[typ] + assert getattr(self, attr) is None, attr + setattr(self, attr, parser(lines, font)) + self.Version = 0x00010000 if self.MarkGlyphSetsDef is None else 0x00010002 + container.table = self + return container + + +def parseCmap(lines, font): + container = ttLib.getTableClass("cmap")() + log.debug("Parsing cmap") + tables = [] + while lines.peek() is not None: + lines.expect("cmap subtable %d" % len(tables)) + platId, encId, fmt, lang = [ + parseCmapId(lines, field) + for field in ("platformID", "encodingID", "format", "language") + ] + table = cmap_classes[fmt](fmt) + table.platformID = platId + table.platEncID = encId + table.language = lang + table.cmap = {} + line = next(lines) + while line[0] != "end subtable": + table.cmap[int(line[0], 16)] = line[1] + line = next(lines) + tables.append(table) + container.tableVersion = 0 + container.tables = tables + return container + + +def parseCmapId(lines, field): + line = next(lines) + assert field == line[0] + return int(line[1]) + + +def parseTable(lines, font, tableTag=None): + log.debug("Parsing table") + line = lines.peeks() + tag = None + if line[0].split()[0] == "FontDame": + tag = line[0].split()[1] + elif " ".join(line[0].split()[:3]) == "Font Chef Table": + tag = line[0].split()[3] + if tag is not None: + next(lines) + tag = tag.ljust(4) + if tableTag is None: + tableTag = tag + else: + assert tableTag == tag, (tableTag, tag) + + assert ( + tableTag is not None + ), "Don't know what table to parse and data doesn't specify" + + return { + "GSUB": parseGSUB, + "GPOS": parseGPOS, + "GDEF": parseGDEF, + "cmap": parseCmap, + }[tableTag](lines, font) + + +class Tokenizer(object): + def __init__(self, f): + # TODO BytesIO / StringIO as needed? also, figure out whether we work on bytes or unicode + lines = iter(f) + try: + self.filename = f.name + except: + self.filename = None + self.lines = iter(lines) + self.line = "" + self.lineno = 0 + self.stoppers = [] + self.buffer = None + + def __iter__(self): + return self + + def _next_line(self): + self.lineno += 1 + line = self.line = next(self.lines) + line = [s.strip() for s in line.split("\t")] + if len(line) == 1 and not line[0]: + del line[0] + if line and not line[-1]: + log.warning("trailing tab found on line %d: %s" % (self.lineno, self.line)) + while line and not line[-1]: + del line[-1] + return line + + def _next_nonempty(self): + while True: + line = self._next_line() + # Skip comments and empty lines + if line and line[0] and (line[0][0] != "%" or line[0] == "% subtable"): + return line + + def _next_buffered(self): + if self.buffer: + ret = self.buffer + self.buffer = None + return ret + else: + return self._next_nonempty() + + def __next__(self): + line = self._next_buffered() + if line[0].lower() in self.stoppers: + self.buffer = line + raise StopIteration + return line + + def next(self): + return self.__next__() + + def peek(self): + if not self.buffer: + try: + self.buffer = self._next_nonempty() + except StopIteration: + return None + if self.buffer[0].lower() in self.stoppers: + return None + return self.buffer + + def peeks(self): + ret = self.peek() + return ret if ret is not None else ("",) + + @contextmanager + def between(self, tag): + start = tag + " begin" + end = tag + " end" + self.expectendswith(start) + self.stoppers.append(end) + yield + del self.stoppers[-1] + self.expect(tag + " end") + + @contextmanager + def until(self, tags): + if type(tags) is not tuple: + tags = (tags,) + self.stoppers.extend(tags) + yield + del self.stoppers[-len(tags) :] + + def expect(self, s): + line = next(self) + tag = line[0].lower() + assert tag == s, "Expected '%s', got '%s'" % (s, tag) + return line + + def expectendswith(self, s): + line = next(self) + tag = line[0].lower() + assert tag.endswith(s), "Expected '*%s', got '%s'" % (s, tag) + return line + + +def build(f, font, tableTag=None): + """Convert a Monotype font layout file to an OpenType layout object + + A font object must be passed, but this may be a "dummy" font; it is only + used for sorting glyph sets when making coverage tables and to hold the + OpenType layout table while it is being built. + + Args: + f: A file object. + font (TTFont): A font object. + tableTag (string): If provided, asserts that the file contains data for the + given OpenType table. + + Returns: + An object representing the table. (e.g. ``table_G_S_U_B_``) + """ + lines = Tokenizer(f) + return parseTable(lines, font, tableTag=tableTag) + + +def main(args=None, font=None): + """Convert a FontDame OTL file to TTX XML + + Writes XML output to stdout. + + Args: + args: Command line arguments (``--font``, ``--table``, input files). + """ + import sys + from fontTools import configLogger + from fontTools.misc.testTools import MockFont + + if args is None: + args = sys.argv[1:] + + # configure the library logger (for >= WARNING) + configLogger() + # comment this out to enable debug messages from mtiLib's logger + # log.setLevel(logging.DEBUG) + + import argparse + + parser = argparse.ArgumentParser( + "fonttools mtiLib", + description=main.__doc__, + ) + + parser.add_argument( + "--font", + "-f", + metavar="FILE", + dest="font", + help="Input TTF files (used for glyph classes and sorting coverage tables)", + ) + parser.add_argument( + "--table", + "-t", + metavar="TABLE", + dest="tableTag", + help="Table to fill (sniffed from input file if not provided)", + ) + parser.add_argument( + "inputs", metavar="FILE", type=str, nargs="+", help="Input FontDame .txt files" + ) + + args = parser.parse_args(args) + + if font is None: + if args.font: + font = ttLib.TTFont(args.font) + else: + font = MockFont() + + for f in args.inputs: + log.debug("Processing %s", f) + with open(f, "rt", encoding="utf-8") as f: + table = build(f, font, tableTag=args.tableTag) + blob = table.compile(font) # Make sure it compiles + decompiled = table.__class__() + decompiled.decompile(blob, font) # Make sure it decompiles! + + # continue + from fontTools.misc import xmlWriter + + tag = table.tableTag + writer = xmlWriter.XMLWriter(sys.stdout) + writer.begintag(tag) + writer.newline() + # table.toXML(writer, font) + decompiled.toXML(writer, font) + writer.endtag(tag) + writer.newline() + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__main__.py new file mode 100644 index 00000000..29c802bc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/mtiLib/__main__.py @@ -0,0 +1,5 @@ +import sys +from fontTools.mtiLib import main + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/__init__.py new file mode 100644 index 00000000..12e414fc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/__init__.py @@ -0,0 +1 @@ +"""OpenType Layout-related functionality.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/builder.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/builder.py new file mode 100644 index 00000000..3508a7e2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/builder.py @@ -0,0 +1,2920 @@ +from collections import namedtuple, OrderedDict +import os +from fontTools.misc.fixedTools import fixedToFloat +from fontTools import ttLib +from fontTools.ttLib.tables import otTables as ot +from fontTools.ttLib.tables.otBase import ( + ValueRecord, + valueRecordFormatDict, + OTTableWriter, + CountReference, +) +from fontTools.ttLib.tables import otBase +from fontTools.feaLib.ast import STATNameStatement +from fontTools.otlLib.optimize.gpos import ( + _compression_level_from_env, + compact_lookup, +) +from fontTools.otlLib.error import OpenTypeLibError +from functools import reduce +import logging +import copy + + +log = logging.getLogger(__name__) + + +def buildCoverage(glyphs, glyphMap): + """Builds a coverage table. + + Coverage tables (as defined in the `OpenType spec `__) + are used in all OpenType Layout lookups apart from the Extension type, and + define the glyphs involved in a layout subtable. This allows shaping engines + to compare the glyph stream with the coverage table and quickly determine + whether a subtable should be involved in a shaping operation. + + This function takes a list of glyphs and a glyphname-to-ID map, and + returns a ``Coverage`` object representing the coverage table. + + Example:: + + glyphMap = font.getReverseGlyphMap() + glyphs = [ "A", "B", "C" ] + coverage = buildCoverage(glyphs, glyphMap) + + Args: + glyphs: a sequence of glyph names. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + An ``otTables.Coverage`` object or ``None`` if there are no glyphs + supplied. + """ + + if not glyphs: + return None + self = ot.Coverage() + try: + self.glyphs = sorted(set(glyphs), key=glyphMap.__getitem__) + except KeyError as e: + raise ValueError(f"Could not find glyph {e} in font") from e + + return self + + +LOOKUP_FLAG_RIGHT_TO_LEFT = 0x0001 +LOOKUP_FLAG_IGNORE_BASE_GLYPHS = 0x0002 +LOOKUP_FLAG_IGNORE_LIGATURES = 0x0004 +LOOKUP_FLAG_IGNORE_MARKS = 0x0008 +LOOKUP_FLAG_USE_MARK_FILTERING_SET = 0x0010 + + +def buildLookup(subtables, flags=0, markFilterSet=None): + """Turns a collection of rules into a lookup. + + A Lookup (as defined in the `OpenType Spec `__) + wraps the individual rules in a layout operation (substitution or + positioning) in a data structure expressing their overall lookup type - + for example, single substitution, mark-to-base attachment, and so on - + as well as the lookup flags and any mark filtering sets. You may import + the following constants to express lookup flags: + + - ``LOOKUP_FLAG_RIGHT_TO_LEFT`` + - ``LOOKUP_FLAG_IGNORE_BASE_GLYPHS`` + - ``LOOKUP_FLAG_IGNORE_LIGATURES`` + - ``LOOKUP_FLAG_IGNORE_MARKS`` + - ``LOOKUP_FLAG_USE_MARK_FILTERING_SET`` + + Args: + subtables: A list of layout subtable objects (e.g. + ``MultipleSubst``, ``PairPos``, etc.) or ``None``. + flags (int): This lookup's flags. + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + + Returns: + An ``otTables.Lookup`` object or ``None`` if there are no subtables + supplied. + """ + if subtables is None: + return None + subtables = [st for st in subtables if st is not None] + if not subtables: + return None + assert all( + t.LookupType == subtables[0].LookupType for t in subtables + ), "all subtables must have the same LookupType; got %s" % repr( + [t.LookupType for t in subtables] + ) + self = ot.Lookup() + self.LookupType = subtables[0].LookupType + self.LookupFlag = flags + self.SubTable = subtables + self.SubTableCount = len(self.SubTable) + if markFilterSet is not None: + self.LookupFlag |= LOOKUP_FLAG_USE_MARK_FILTERING_SET + assert isinstance(markFilterSet, int), markFilterSet + self.MarkFilteringSet = markFilterSet + else: + assert (self.LookupFlag & LOOKUP_FLAG_USE_MARK_FILTERING_SET) == 0, ( + "if markFilterSet is None, flags must not set " + "LOOKUP_FLAG_USE_MARK_FILTERING_SET; flags=0x%04x" % flags + ) + return self + + +class LookupBuilder(object): + SUBTABLE_BREAK_ = "SUBTABLE_BREAK" + + def __init__(self, font, location, table, lookup_type): + self.font = font + self.glyphMap = font.getReverseGlyphMap() + self.location = location + self.table, self.lookup_type = table, lookup_type + self.lookupflag = 0 + self.markFilterSet = None + self.lookup_index = None # assigned when making final tables + assert table in ("GPOS", "GSUB") + + def equals(self, other): + return ( + isinstance(other, self.__class__) + and self.table == other.table + and self.lookupflag == other.lookupflag + and self.markFilterSet == other.markFilterSet + ) + + def inferGlyphClasses(self): + """Infers glyph glasses for the GDEF table, such as {"cedilla":3}.""" + return {} + + def getAlternateGlyphs(self): + """Helper for building 'aalt' features.""" + return {} + + def buildLookup_(self, subtables): + return buildLookup(subtables, self.lookupflag, self.markFilterSet) + + def buildMarkClasses_(self, marks): + """{"cedilla": ("BOTTOM", ast.Anchor), ...} --> {"BOTTOM":0, "TOP":1} + + Helper for MarkBasePostBuilder, MarkLigPosBuilder, and + MarkMarkPosBuilder. Seems to return the same numeric IDs + for mark classes as the AFDKO makeotf tool. + """ + ids = {} + for mark in sorted(marks.keys(), key=self.font.getGlyphID): + markClassName, _markAnchor = marks[mark] + if markClassName not in ids: + ids[markClassName] = len(ids) + return ids + + def setBacktrackCoverage_(self, prefix, subtable): + subtable.BacktrackGlyphCount = len(prefix) + subtable.BacktrackCoverage = [] + for p in reversed(prefix): + coverage = buildCoverage(p, self.glyphMap) + subtable.BacktrackCoverage.append(coverage) + + def setLookAheadCoverage_(self, suffix, subtable): + subtable.LookAheadGlyphCount = len(suffix) + subtable.LookAheadCoverage = [] + for s in suffix: + coverage = buildCoverage(s, self.glyphMap) + subtable.LookAheadCoverage.append(coverage) + + def setInputCoverage_(self, glyphs, subtable): + subtable.InputGlyphCount = len(glyphs) + subtable.InputCoverage = [] + for g in glyphs: + coverage = buildCoverage(g, self.glyphMap) + subtable.InputCoverage.append(coverage) + + def setCoverage_(self, glyphs, subtable): + subtable.GlyphCount = len(glyphs) + subtable.Coverage = [] + for g in glyphs: + coverage = buildCoverage(g, self.glyphMap) + subtable.Coverage.append(coverage) + + def build_subst_subtables(self, mapping, klass): + substitutions = [{}] + for key in mapping: + if key[0] == self.SUBTABLE_BREAK_: + substitutions.append({}) + else: + substitutions[-1][key] = mapping[key] + subtables = [klass(s) for s in substitutions] + return subtables + + def add_subtable_break(self, location): + """Add an explicit subtable break. + + Args: + location: A string or tuple representing the location in the + original source which produced this break, or ``None`` if + no location is provided. + """ + log.warning( + OpenTypeLibError( + 'unsupported "subtable" statement for lookup type', location + ) + ) + + +class AlternateSubstBuilder(LookupBuilder): + """Builds an Alternate Substitution (GSUB3) lookup. + + Users are expected to manually add alternate glyph substitutions to + the ``alternates`` attribute after the object has been initialized, + e.g.:: + + builder.alternates["A"] = ["A.alt1", "A.alt2"] + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + alternates: An ordered dictionary of alternates, mapping glyph names + to a list of names of alternates. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 3) + self.alternates = OrderedDict() + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.alternates == other.alternates + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the alternate + substitution lookup. + """ + subtables = self.build_subst_subtables( + self.alternates, buildAlternateSubstSubtable + ) + return self.buildLookup_(subtables) + + def getAlternateGlyphs(self): + return self.alternates + + def add_subtable_break(self, location): + self.alternates[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_ + + +class ChainContextualRule( + namedtuple("ChainContextualRule", ["prefix", "glyphs", "suffix", "lookups"]) +): + @property + def is_subtable_break(self): + return self.prefix == LookupBuilder.SUBTABLE_BREAK_ + + +class ChainContextualRuleset: + def __init__(self): + self.rules = [] + + def addRule(self, rule): + self.rules.append(rule) + + @property + def hasPrefixOrSuffix(self): + # Do we have any prefixes/suffixes? If this is False for all + # rulesets, we can express the whole lookup as GPOS5/GSUB7. + for rule in self.rules: + if len(rule.prefix) > 0 or len(rule.suffix) > 0: + return True + return False + + @property + def hasAnyGlyphClasses(self): + # Do we use glyph classes anywhere in the rules? If this is False + # we can express this subtable as a Format 1. + for rule in self.rules: + for coverage in (rule.prefix, rule.glyphs, rule.suffix): + if any(len(x) > 1 for x in coverage): + return True + return False + + def format2ClassDefs(self): + PREFIX, GLYPHS, SUFFIX = 0, 1, 2 + classDefBuilders = [] + for ix in [PREFIX, GLYPHS, SUFFIX]: + context = [] + for r in self.rules: + context.append(r[ix]) + classes = self._classBuilderForContext(context) + if not classes: + return None + classDefBuilders.append(classes) + return classDefBuilders + + def _classBuilderForContext(self, context): + classdefbuilder = ClassDefBuilder(useClass0=False) + for position in context: + for glyphset in position: + glyphs = set(glyphset) + if not classdefbuilder.canAdd(glyphs): + return None + classdefbuilder.add(glyphs) + return classdefbuilder + + +class ChainContextualBuilder(LookupBuilder): + def equals(self, other): + return LookupBuilder.equals(self, other) and self.rules == other.rules + + def rulesets(self): + # Return a list of ChainContextRuleset objects, taking explicit + # subtable breaks into account + ruleset = [ChainContextualRuleset()] + for rule in self.rules: + if rule.is_subtable_break: + ruleset.append(ChainContextualRuleset()) + continue + ruleset[-1].addRule(rule) + # Squish any empty subtables + return [x for x in ruleset if len(x.rules) > 0] + + def getCompiledSize_(self, subtables): + size = 0 + for st in subtables: + w = OTTableWriter() + w["LookupType"] = CountReference( + {"LookupType": st.LookupType}, "LookupType" + ) + # We need to make a copy here because compiling + # modifies the subtable (finalizing formats etc.) + copy.deepcopy(st).compile(w, self.font) + size += len(w.getAllData()) + return size + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the chained + contextual positioning lookup. + """ + subtables = [] + + rulesets = self.rulesets() + chaining = any(ruleset.hasPrefixOrSuffix for ruleset in rulesets) + + # https://github.com/fonttools/fonttools/issues/2539 + # + # Unfortunately, as of 2022-03-07, Apple's CoreText renderer does not + # correctly process GPOS7 lookups, so for now we force contextual + # positioning lookups to be chaining (GPOS8). + # + # This seems to be fixed as of macOS 13.2, but we keep disabling this + # for now until we are no longer concerned about old macOS versions. + # But we allow people to opt-out of this with the config key below. + write_gpos7 = self.font.cfg.get("fontTools.otlLib.builder:WRITE_GPOS7") + # horrible separation of concerns breach + if not write_gpos7 and self.subtable_type == "Pos": + chaining = True + + for ruleset in rulesets: + # Determine format strategy. We try to build formats 1, 2 and 3 + # subtables and then work out which is best. candidates list holds + # the subtables in each format for this ruleset (including a dummy + # "format 0" to make the addressing match the format numbers). + + # We can always build a format 3 lookup by accumulating each of + # the rules into a list, so start with that. + candidates = [None, None, None, []] + for rule in ruleset.rules: + candidates[3].append(self.buildFormat3Subtable(rule, chaining)) + + # Can we express the whole ruleset as a format 2 subtable? + classdefs = ruleset.format2ClassDefs() + if classdefs: + candidates[2] = [ + self.buildFormat2Subtable(ruleset, classdefs, chaining) + ] + + if not ruleset.hasAnyGlyphClasses: + candidates[1] = [self.buildFormat1Subtable(ruleset, chaining)] + + for i in [1, 2, 3]: + if candidates[i]: + try: + self.getCompiledSize_(candidates[i]) + except Exception as e: + log.warning( + "Contextual format %i at %s overflowed (%s)" + % (i, str(self.location), e) + ) + candidates[i] = None + + candidates = [x for x in candidates if x is not None] + if not candidates: + raise OpenTypeLibError("All candidates overflowed", self.location) + + winner = min(candidates, key=self.getCompiledSize_) + subtables.extend(winner) + + # If we are not chaining, lookup type will be automatically fixed by + # buildLookup_ + return self.buildLookup_(subtables) + + def buildFormat1Subtable(self, ruleset, chaining=True): + st = self.newSubtable_(chaining=chaining) + st.Format = 1 + st.populateDefaults() + coverage = set() + rulesetsByFirstGlyph = {} + ruleAttr = self.ruleAttr_(format=1, chaining=chaining) + + for rule in ruleset.rules: + ruleAsSubtable = self.newRule_(format=1, chaining=chaining) + + if chaining: + ruleAsSubtable.BacktrackGlyphCount = len(rule.prefix) + ruleAsSubtable.LookAheadGlyphCount = len(rule.suffix) + ruleAsSubtable.Backtrack = [list(x)[0] for x in reversed(rule.prefix)] + ruleAsSubtable.LookAhead = [list(x)[0] for x in rule.suffix] + + ruleAsSubtable.InputGlyphCount = len(rule.glyphs) + else: + ruleAsSubtable.GlyphCount = len(rule.glyphs) + + ruleAsSubtable.Input = [list(x)[0] for x in rule.glyphs[1:]] + + self.buildLookupList(rule, ruleAsSubtable) + + firstGlyph = list(rule.glyphs[0])[0] + if firstGlyph not in rulesetsByFirstGlyph: + coverage.add(firstGlyph) + rulesetsByFirstGlyph[firstGlyph] = [] + rulesetsByFirstGlyph[firstGlyph].append(ruleAsSubtable) + + st.Coverage = buildCoverage(coverage, self.glyphMap) + ruleSets = [] + for g in st.Coverage.glyphs: + ruleSet = self.newRuleSet_(format=1, chaining=chaining) + setattr(ruleSet, ruleAttr, rulesetsByFirstGlyph[g]) + setattr(ruleSet, f"{ruleAttr}Count", len(rulesetsByFirstGlyph[g])) + ruleSets.append(ruleSet) + + setattr(st, self.ruleSetAttr_(format=1, chaining=chaining), ruleSets) + setattr( + st, self.ruleSetAttr_(format=1, chaining=chaining) + "Count", len(ruleSets) + ) + + return st + + def buildFormat2Subtable(self, ruleset, classdefs, chaining=True): + st = self.newSubtable_(chaining=chaining) + st.Format = 2 + st.populateDefaults() + + if chaining: + ( + st.BacktrackClassDef, + st.InputClassDef, + st.LookAheadClassDef, + ) = [c.build() for c in classdefs] + else: + st.ClassDef = classdefs[1].build() + + inClasses = classdefs[1].classes() + + classSets = [] + for _ in inClasses: + classSet = self.newRuleSet_(format=2, chaining=chaining) + classSets.append(classSet) + + coverage = set() + classRuleAttr = self.ruleAttr_(format=2, chaining=chaining) + + for rule in ruleset.rules: + ruleAsSubtable = self.newRule_(format=2, chaining=chaining) + if chaining: + ruleAsSubtable.BacktrackGlyphCount = len(rule.prefix) + ruleAsSubtable.LookAheadGlyphCount = len(rule.suffix) + # The glyphs in the rule may be list, tuple, odict_keys... + # Order is not important anyway because they are guaranteed + # to be members of the same class. + ruleAsSubtable.Backtrack = [ + st.BacktrackClassDef.classDefs[list(x)[0]] + for x in reversed(rule.prefix) + ] + ruleAsSubtable.LookAhead = [ + st.LookAheadClassDef.classDefs[list(x)[0]] for x in rule.suffix + ] + + ruleAsSubtable.InputGlyphCount = len(rule.glyphs) + ruleAsSubtable.Input = [ + st.InputClassDef.classDefs[list(x)[0]] for x in rule.glyphs[1:] + ] + setForThisRule = classSets[ + st.InputClassDef.classDefs[list(rule.glyphs[0])[0]] + ] + else: + ruleAsSubtable.GlyphCount = len(rule.glyphs) + ruleAsSubtable.Class = [ # The spec calls this InputSequence + st.ClassDef.classDefs[list(x)[0]] for x in rule.glyphs[1:] + ] + setForThisRule = classSets[ + st.ClassDef.classDefs[list(rule.glyphs[0])[0]] + ] + + self.buildLookupList(rule, ruleAsSubtable) + coverage |= set(rule.glyphs[0]) + + getattr(setForThisRule, classRuleAttr).append(ruleAsSubtable) + setattr( + setForThisRule, + f"{classRuleAttr}Count", + getattr(setForThisRule, f"{classRuleAttr}Count") + 1, + ) + setattr(st, self.ruleSetAttr_(format=2, chaining=chaining), classSets) + setattr( + st, self.ruleSetAttr_(format=2, chaining=chaining) + "Count", len(classSets) + ) + st.Coverage = buildCoverage(coverage, self.glyphMap) + return st + + def buildFormat3Subtable(self, rule, chaining=True): + st = self.newSubtable_(chaining=chaining) + st.Format = 3 + if chaining: + self.setBacktrackCoverage_(rule.prefix, st) + self.setLookAheadCoverage_(rule.suffix, st) + self.setInputCoverage_(rule.glyphs, st) + else: + self.setCoverage_(rule.glyphs, st) + self.buildLookupList(rule, st) + return st + + def buildLookupList(self, rule, st): + for sequenceIndex, lookupList in enumerate(rule.lookups): + if lookupList is not None: + if not isinstance(lookupList, list): + # Can happen with synthesised lookups + lookupList = [lookupList] + for l in lookupList: + if l.lookup_index is None: + if isinstance(self, ChainContextPosBuilder): + other = "substitution" + else: + other = "positioning" + raise OpenTypeLibError( + "Missing index of the specified " + f"lookup, might be a {other} lookup", + self.location, + ) + rec = self.newLookupRecord_(st) + rec.SequenceIndex = sequenceIndex + rec.LookupListIndex = l.lookup_index + + def add_subtable_break(self, location): + self.rules.append( + ChainContextualRule( + self.SUBTABLE_BREAK_, + self.SUBTABLE_BREAK_, + self.SUBTABLE_BREAK_, + [self.SUBTABLE_BREAK_], + ) + ) + + def newSubtable_(self, chaining=True): + subtablename = f"Context{self.subtable_type}" + if chaining: + subtablename = "Chain" + subtablename + st = getattr(ot, subtablename)() # ot.ChainContextPos()/ot.ChainSubst()/etc. + setattr(st, f"{self.subtable_type}Count", 0) + setattr(st, f"{self.subtable_type}LookupRecord", []) + return st + + # Format 1 and format 2 GSUB5/GSUB6/GPOS7/GPOS8 rulesets and rules form a family: + # + # format 1 ruleset format 1 rule format 2 ruleset format 2 rule + # GSUB5 SubRuleSet SubRule SubClassSet SubClassRule + # GSUB6 ChainSubRuleSet ChainSubRule ChainSubClassSet ChainSubClassRule + # GPOS7 PosRuleSet PosRule PosClassSet PosClassRule + # GPOS8 ChainPosRuleSet ChainPosRule ChainPosClassSet ChainPosClassRule + # + # The following functions generate the attribute names and subtables according + # to this naming convention. + def ruleSetAttr_(self, format=1, chaining=True): + if format == 1: + formatType = "Rule" + elif format == 2: + formatType = "Class" + else: + raise AssertionError(formatType) + subtablename = f"{self.subtable_type[0:3]}{formatType}Set" # Sub, not Subst. + if chaining: + subtablename = "Chain" + subtablename + return subtablename + + def ruleAttr_(self, format=1, chaining=True): + if format == 1: + formatType = "" + elif format == 2: + formatType = "Class" + else: + raise AssertionError(formatType) + subtablename = f"{self.subtable_type[0:3]}{formatType}Rule" # Sub, not Subst. + if chaining: + subtablename = "Chain" + subtablename + return subtablename + + def newRuleSet_(self, format=1, chaining=True): + st = getattr( + ot, self.ruleSetAttr_(format, chaining) + )() # ot.ChainPosRuleSet()/ot.SubRuleSet()/etc. + st.populateDefaults() + return st + + def newRule_(self, format=1, chaining=True): + st = getattr( + ot, self.ruleAttr_(format, chaining) + )() # ot.ChainPosClassRule()/ot.SubClassRule()/etc. + st.populateDefaults() + return st + + def attachSubtableWithCount_( + self, st, subtable_name, count_name, existing=None, index=None, chaining=False + ): + if chaining: + subtable_name = "Chain" + subtable_name + count_name = "Chain" + count_name + + if not hasattr(st, count_name): + setattr(st, count_name, 0) + setattr(st, subtable_name, []) + + if existing: + new_subtable = existing + else: + # Create a new, empty subtable from otTables + new_subtable = getattr(ot, subtable_name)() + + setattr(st, count_name, getattr(st, count_name) + 1) + + if index: + getattr(st, subtable_name).insert(index, new_subtable) + else: + getattr(st, subtable_name).append(new_subtable) + + return new_subtable + + def newLookupRecord_(self, st): + return self.attachSubtableWithCount_( + st, + f"{self.subtable_type}LookupRecord", + f"{self.subtable_type}Count", + chaining=False, + ) # Oddly, it isn't ChainSubstLookupRecord + + +class ChainContextPosBuilder(ChainContextualBuilder): + """Builds a Chained Contextual Positioning (GPOS8) lookup. + + Users are expected to manually add rules to the ``rules`` attribute after + the object has been initialized, e.g.:: + + # pos [A B] [C D] x' lookup lu1 y' z' lookup lu2 E; + + prefix = [ ["A", "B"], ["C", "D"] ] + suffix = [ ["E"] ] + glyphs = [ ["x"], ["y"], ["z"] ] + lookups = [ [lu1], None, [lu2] ] + builder.rules.append( (prefix, glyphs, suffix, lookups) ) + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + rules: A list of tuples representing the rules in this lookup. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 8) + self.rules = [] + self.subtable_type = "Pos" + + def find_chainable_single_pos(self, lookups, glyphs, value): + """Helper for add_single_pos_chained_()""" + res = None + for lookup in lookups[::-1]: + if lookup == self.SUBTABLE_BREAK_: + return res + if isinstance(lookup, SinglePosBuilder) and all( + lookup.can_add(glyph, value) for glyph in glyphs + ): + res = lookup + return res + + +class ChainContextSubstBuilder(ChainContextualBuilder): + """Builds a Chained Contextual Substitution (GSUB6) lookup. + + Users are expected to manually add rules to the ``rules`` attribute after + the object has been initialized, e.g.:: + + # sub [A B] [C D] x' lookup lu1 y' z' lookup lu2 E; + + prefix = [ ["A", "B"], ["C", "D"] ] + suffix = [ ["E"] ] + glyphs = [ ["x"], ["y"], ["z"] ] + lookups = [ [lu1], None, [lu2] ] + builder.rules.append( (prefix, glyphs, suffix, lookups) ) + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + rules: A list of tuples representing the rules in this lookup. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 6) + self.rules = [] # (prefix, input, suffix, lookups) + self.subtable_type = "Subst" + + def getAlternateGlyphs(self): + result = {} + for rule in self.rules: + if rule.is_subtable_break: + continue + for lookups in rule.lookups: + if not isinstance(lookups, list): + lookups = [lookups] + for lookup in lookups: + if lookup is not None: + alts = lookup.getAlternateGlyphs() + for glyph, replacements in alts.items(): + result.setdefault(glyph, set()).update(replacements) + return result + + def find_chainable_single_subst(self, mapping): + """Helper for add_single_subst_chained_()""" + res = None + for rule in self.rules[::-1]: + if rule.is_subtable_break: + return res + for sub in rule.lookups: + if isinstance(sub, SingleSubstBuilder) and not any( + g in mapping and mapping[g] != sub.mapping[g] for g in sub.mapping + ): + res = sub + return res + + +class LigatureSubstBuilder(LookupBuilder): + """Builds a Ligature Substitution (GSUB4) lookup. + + Users are expected to manually add ligatures to the ``ligatures`` + attribute after the object has been initialized, e.g.:: + + # sub f i by f_i; + builder.ligatures[("f","f","i")] = "f_f_i" + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + ligatures: An ordered dictionary mapping a tuple of glyph names to the + ligature glyphname. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 4) + self.ligatures = OrderedDict() # {('f','f','i'): 'f_f_i'} + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.ligatures == other.ligatures + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the ligature + substitution lookup. + """ + subtables = self.build_subst_subtables( + self.ligatures, buildLigatureSubstSubtable + ) + return self.buildLookup_(subtables) + + def add_subtable_break(self, location): + self.ligatures[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_ + + +class MultipleSubstBuilder(LookupBuilder): + """Builds a Multiple Substitution (GSUB2) lookup. + + Users are expected to manually add substitutions to the ``mapping`` + attribute after the object has been initialized, e.g.:: + + # sub uni06C0 by uni06D5.fina hamza.above; + builder.mapping["uni06C0"] = [ "uni06D5.fina", "hamza.above"] + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + mapping: An ordered dictionary mapping a glyph name to a list of + substituted glyph names. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 2) + self.mapping = OrderedDict() + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.mapping == other.mapping + + def build(self): + subtables = self.build_subst_subtables(self.mapping, buildMultipleSubstSubtable) + return self.buildLookup_(subtables) + + def add_subtable_break(self, location): + self.mapping[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_ + + +class CursivePosBuilder(LookupBuilder): + """Builds a Cursive Positioning (GPOS3) lookup. + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + attachments: An ordered dictionary mapping a glyph name to a two-element + tuple of ``otTables.Anchor`` objects. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 3) + self.attachments = {} + + def equals(self, other): + return ( + LookupBuilder.equals(self, other) and self.attachments == other.attachments + ) + + def add_attachment(self, location, glyphs, entryAnchor, exitAnchor): + """Adds attachment information to the cursive positioning lookup. + + Args: + location: A string or tuple representing the location in the + original source which produced this lookup. (Unused.) + glyphs: A list of glyph names sharing these entry and exit + anchor locations. + entryAnchor: A ``otTables.Anchor`` object representing the + entry anchor, or ``None`` if no entry anchor is present. + exitAnchor: A ``otTables.Anchor`` object representing the + exit anchor, or ``None`` if no exit anchor is present. + """ + for glyph in glyphs: + self.attachments[glyph] = (entryAnchor, exitAnchor) + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the cursive + positioning lookup. + """ + st = buildCursivePosSubtable(self.attachments, self.glyphMap) + return self.buildLookup_([st]) + + +class MarkBasePosBuilder(LookupBuilder): + """Builds a Mark-To-Base Positioning (GPOS4) lookup. + + Users are expected to manually add marks and bases to the ``marks`` + and ``bases`` attributes after the object has been initialized, e.g.:: + + builder.marks["acute"] = (0, a1) + builder.marks["grave"] = (0, a1) + builder.marks["cedilla"] = (1, a2) + builder.bases["a"] = {0: a3, 1: a5} + builder.bases["b"] = {0: a4, 1: a5} + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + marks: An dictionary mapping a glyph name to a two-element + tuple containing a mark class ID and ``otTables.Anchor`` object. + bases: An dictionary mapping a glyph name to a dictionary of + mark class IDs and ``otTables.Anchor`` object. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 4) + self.marks = {} # glyphName -> (markClassName, anchor) + self.bases = {} # glyphName -> {markClassName: anchor} + + def equals(self, other): + return ( + LookupBuilder.equals(self, other) + and self.marks == other.marks + and self.bases == other.bases + ) + + def inferGlyphClasses(self): + result = {glyph: 1 for glyph in self.bases} + result.update({glyph: 3 for glyph in self.marks}) + return result + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the mark-to-base + positioning lookup. + """ + markClasses = self.buildMarkClasses_(self.marks) + marks = {} + for mark, (mc, anchor) in self.marks.items(): + if mc not in markClasses: + raise ValueError( + "Mark class %s not found for mark glyph %s" % (mc, mark) + ) + marks[mark] = (markClasses[mc], anchor) + bases = {} + for glyph, anchors in self.bases.items(): + bases[glyph] = {} + for mc, anchor in anchors.items(): + if mc not in markClasses: + raise ValueError( + "Mark class %s not found for base glyph %s" % (mc, glyph) + ) + bases[glyph][markClasses[mc]] = anchor + subtables = buildMarkBasePos(marks, bases, self.glyphMap) + return self.buildLookup_(subtables) + + +class MarkLigPosBuilder(LookupBuilder): + """Builds a Mark-To-Ligature Positioning (GPOS5) lookup. + + Users are expected to manually add marks and bases to the ``marks`` + and ``ligatures`` attributes after the object has been initialized, e.g.:: + + builder.marks["acute"] = (0, a1) + builder.marks["grave"] = (0, a1) + builder.marks["cedilla"] = (1, a2) + builder.ligatures["f_i"] = [ + { 0: a3, 1: a5 }, # f + { 0: a4, 1: a5 } # i + ] + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + marks: An dictionary mapping a glyph name to a two-element + tuple containing a mark class ID and ``otTables.Anchor`` object. + ligatures: An dictionary mapping a glyph name to an array with one + element for each ligature component. Each array element should be + a dictionary mapping mark class IDs to ``otTables.Anchor`` objects. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 5) + self.marks = {} # glyphName -> (markClassName, anchor) + self.ligatures = {} # glyphName -> [{markClassName: anchor}, ...] + + def equals(self, other): + return ( + LookupBuilder.equals(self, other) + and self.marks == other.marks + and self.ligatures == other.ligatures + ) + + def inferGlyphClasses(self): + result = {glyph: 2 for glyph in self.ligatures} + result.update({glyph: 3 for glyph in self.marks}) + return result + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the mark-to-ligature + positioning lookup. + """ + markClasses = self.buildMarkClasses_(self.marks) + marks = { + mark: (markClasses[mc], anchor) for mark, (mc, anchor) in self.marks.items() + } + ligs = {} + for lig, components in self.ligatures.items(): + ligs[lig] = [] + for c in components: + ligs[lig].append({markClasses[mc]: a for mc, a in c.items()}) + subtables = buildMarkLigPos(marks, ligs, self.glyphMap) + return self.buildLookup_(subtables) + + +class MarkMarkPosBuilder(LookupBuilder): + """Builds a Mark-To-Mark Positioning (GPOS6) lookup. + + Users are expected to manually add marks and bases to the ``marks`` + and ``baseMarks`` attributes after the object has been initialized, e.g.:: + + builder.marks["acute"] = (0, a1) + builder.marks["grave"] = (0, a1) + builder.marks["cedilla"] = (1, a2) + builder.baseMarks["acute"] = {0: a3} + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + marks: An dictionary mapping a glyph name to a two-element + tuple containing a mark class ID and ``otTables.Anchor`` object. + baseMarks: An dictionary mapping a glyph name to a dictionary + containing one item: a mark class ID and a ``otTables.Anchor`` object. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 6) + self.marks = {} # glyphName -> (markClassName, anchor) + self.baseMarks = {} # glyphName -> {markClassName: anchor} + + def equals(self, other): + return ( + LookupBuilder.equals(self, other) + and self.marks == other.marks + and self.baseMarks == other.baseMarks + ) + + def inferGlyphClasses(self): + result = {glyph: 3 for glyph in self.baseMarks} + result.update({glyph: 3 for glyph in self.marks}) + return result + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the mark-to-mark + positioning lookup. + """ + markClasses = self.buildMarkClasses_(self.marks) + markClassList = sorted(markClasses.keys(), key=markClasses.get) + marks = { + mark: (markClasses[mc], anchor) for mark, (mc, anchor) in self.marks.items() + } + + st = ot.MarkMarkPos() + st.Format = 1 + st.ClassCount = len(markClasses) + st.Mark1Coverage = buildCoverage(marks, self.glyphMap) + st.Mark2Coverage = buildCoverage(self.baseMarks, self.glyphMap) + st.Mark1Array = buildMarkArray(marks, self.glyphMap) + st.Mark2Array = ot.Mark2Array() + st.Mark2Array.Mark2Count = len(st.Mark2Coverage.glyphs) + st.Mark2Array.Mark2Record = [] + for base in st.Mark2Coverage.glyphs: + anchors = [self.baseMarks[base].get(mc) for mc in markClassList] + st.Mark2Array.Mark2Record.append(buildMark2Record(anchors)) + return self.buildLookup_([st]) + + +class ReverseChainSingleSubstBuilder(LookupBuilder): + """Builds a Reverse Chaining Contextual Single Substitution (GSUB8) lookup. + + Users are expected to manually add substitutions to the ``substitutions`` + attribute after the object has been initialized, e.g.:: + + # reversesub [a e n] d' by d.alt; + prefix = [ ["a", "e", "n"] ] + suffix = [] + mapping = { "d": "d.alt" } + builder.substitutions.append( (prefix, suffix, mapping) ) + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + substitutions: A three-element tuple consisting of a prefix sequence, + a suffix sequence, and a dictionary of single substitutions. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 8) + self.rules = [] # (prefix, suffix, mapping) + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.rules == other.rules + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the chained + contextual substitution lookup. + """ + subtables = [] + for prefix, suffix, mapping in self.rules: + st = ot.ReverseChainSingleSubst() + st.Format = 1 + self.setBacktrackCoverage_(prefix, st) + self.setLookAheadCoverage_(suffix, st) + st.Coverage = buildCoverage(mapping.keys(), self.glyphMap) + st.GlyphCount = len(mapping) + st.Substitute = [mapping[g] for g in st.Coverage.glyphs] + subtables.append(st) + return self.buildLookup_(subtables) + + def add_subtable_break(self, location): + # Nothing to do here, each substitution is in its own subtable. + pass + + +class SingleSubstBuilder(LookupBuilder): + """Builds a Single Substitution (GSUB1) lookup. + + Users are expected to manually add substitutions to the ``mapping`` + attribute after the object has been initialized, e.g.:: + + # sub x by y; + builder.mapping["x"] = "y" + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + mapping: A dictionary mapping a single glyph name to another glyph name. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GSUB", 1) + self.mapping = OrderedDict() + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.mapping == other.mapping + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the multiple + substitution lookup. + """ + subtables = self.build_subst_subtables(self.mapping, buildSingleSubstSubtable) + return self.buildLookup_(subtables) + + def getAlternateGlyphs(self): + return {glyph: set([repl]) for glyph, repl in self.mapping.items()} + + def add_subtable_break(self, location): + self.mapping[(self.SUBTABLE_BREAK_, location)] = self.SUBTABLE_BREAK_ + + +class ClassPairPosSubtableBuilder(object): + """Builds class-based Pair Positioning (GPOS2 format 2) subtables. + + Note that this does *not* build a GPOS2 ``otTables.Lookup`` directly, + but builds a list of ``otTables.PairPos`` subtables. It is used by the + :class:`PairPosBuilder` below. + + Attributes: + builder (PairPosBuilder): A pair positioning lookup builder. + """ + + def __init__(self, builder): + self.builder_ = builder + self.classDef1_, self.classDef2_ = None, None + self.values_ = {} # (glyphclass1, glyphclass2) --> (value1, value2) + self.forceSubtableBreak_ = False + self.subtables_ = [] + + def addPair(self, gc1, value1, gc2, value2): + """Add a pair positioning rule. + + Args: + gc1: A set of glyph names for the "left" glyph + value1: An ``otTables.ValueRecord`` object for the left glyph's + positioning. + gc2: A set of glyph names for the "right" glyph + value2: An ``otTables.ValueRecord`` object for the right glyph's + positioning. + """ + mergeable = ( + not self.forceSubtableBreak_ + and self.classDef1_ is not None + and self.classDef1_.canAdd(gc1) + and self.classDef2_ is not None + and self.classDef2_.canAdd(gc2) + ) + if not mergeable: + self.flush_() + self.classDef1_ = ClassDefBuilder(useClass0=True) + self.classDef2_ = ClassDefBuilder(useClass0=False) + self.values_ = {} + self.classDef1_.add(gc1) + self.classDef2_.add(gc2) + self.values_[(gc1, gc2)] = (value1, value2) + + def addSubtableBreak(self): + """Add an explicit subtable break at this point.""" + self.forceSubtableBreak_ = True + + def subtables(self): + """Return the list of ``otTables.PairPos`` subtables constructed.""" + self.flush_() + return self.subtables_ + + def flush_(self): + if self.classDef1_ is None or self.classDef2_ is None: + return + st = buildPairPosClassesSubtable(self.values_, self.builder_.glyphMap) + if st.Coverage is None: + return + self.subtables_.append(st) + self.forceSubtableBreak_ = False + + +class PairPosBuilder(LookupBuilder): + """Builds a Pair Positioning (GPOS2) lookup. + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + pairs: An array of class-based pair positioning tuples. Usually + manipulated with the :meth:`addClassPair` method below. + glyphPairs: A dictionary mapping a tuple of glyph names to a tuple + of ``otTables.ValueRecord`` objects. Usually manipulated with the + :meth:`addGlyphPair` method below. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 2) + self.pairs = [] # [(gc1, value1, gc2, value2)*] + self.glyphPairs = {} # (glyph1, glyph2) --> (value1, value2) + self.locations = {} # (gc1, gc2) --> (filepath, line, column) + + def addClassPair(self, location, glyphclass1, value1, glyphclass2, value2): + """Add a class pair positioning rule to the current lookup. + + Args: + location: A string or tuple representing the location in the + original source which produced this rule. Unused. + glyphclass1: A set of glyph names for the "left" glyph in the pair. + value1: A ``otTables.ValueRecord`` for positioning the left glyph. + glyphclass2: A set of glyph names for the "right" glyph in the pair. + value2: A ``otTables.ValueRecord`` for positioning the right glyph. + """ + self.pairs.append((glyphclass1, value1, glyphclass2, value2)) + + def addGlyphPair(self, location, glyph1, value1, glyph2, value2): + """Add a glyph pair positioning rule to the current lookup. + + Args: + location: A string or tuple representing the location in the + original source which produced this rule. + glyph1: A glyph name for the "left" glyph in the pair. + value1: A ``otTables.ValueRecord`` for positioning the left glyph. + glyph2: A glyph name for the "right" glyph in the pair. + value2: A ``otTables.ValueRecord`` for positioning the right glyph. + """ + key = (glyph1, glyph2) + oldValue = self.glyphPairs.get(key, None) + if oldValue is not None: + # the Feature File spec explicitly allows specific pairs generated + # by an 'enum' rule to be overridden by preceding single pairs + otherLoc = self.locations[key] + log.debug( + "Already defined position for pair %s %s at %s; " + "choosing the first value", + glyph1, + glyph2, + otherLoc, + ) + else: + self.glyphPairs[key] = (value1, value2) + self.locations[key] = location + + def add_subtable_break(self, location): + self.pairs.append( + ( + self.SUBTABLE_BREAK_, + self.SUBTABLE_BREAK_, + self.SUBTABLE_BREAK_, + self.SUBTABLE_BREAK_, + ) + ) + + def equals(self, other): + return ( + LookupBuilder.equals(self, other) + and self.glyphPairs == other.glyphPairs + and self.pairs == other.pairs + ) + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the pair positioning + lookup. + """ + builders = {} + builder = ClassPairPosSubtableBuilder(self) + for glyphclass1, value1, glyphclass2, value2 in self.pairs: + if glyphclass1 is self.SUBTABLE_BREAK_: + builder.addSubtableBreak() + continue + builder.addPair(glyphclass1, value1, glyphclass2, value2) + subtables = [] + if self.glyphPairs: + subtables.extend(buildPairPosGlyphs(self.glyphPairs, self.glyphMap)) + subtables.extend(builder.subtables()) + lookup = self.buildLookup_(subtables) + + # Compact the lookup + # This is a good moment to do it because the compaction should create + # smaller subtables, which may prevent overflows from happening. + # Keep reading the value from the ENV until ufo2ft switches to the config system + level = self.font.cfg.get( + "fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL", + default=_compression_level_from_env(), + ) + if level != 0: + log.info("Compacting GPOS...") + compact_lookup(self.font, level, lookup) + + return lookup + + +class SinglePosBuilder(LookupBuilder): + """Builds a Single Positioning (GPOS1) lookup. + + Attributes: + font (``fontTools.TTLib.TTFont``): A font object. + location: A string or tuple representing the location in the original + source which produced this lookup. + mapping: A dictionary mapping a glyph name to a ``otTables.ValueRecord`` + objects. Usually manipulated with the :meth:`add_pos` method below. + lookupflag (int): The lookup's flag + markFilterSet: Either ``None`` if no mark filtering set is used, or + an integer representing the filtering set to be used for this + lookup. If a mark filtering set is provided, + `LOOKUP_FLAG_USE_MARK_FILTERING_SET` will be set on the lookup's + flags. + """ + + def __init__(self, font, location): + LookupBuilder.__init__(self, font, location, "GPOS", 1) + self.locations = {} # glyph -> (filename, line, column) + self.mapping = {} # glyph -> ot.ValueRecord + + def add_pos(self, location, glyph, otValueRecord): + """Add a single positioning rule. + + Args: + location: A string or tuple representing the location in the + original source which produced this lookup. + glyph: A glyph name. + otValueRection: A ``otTables.ValueRecord`` used to position the + glyph. + """ + if not self.can_add(glyph, otValueRecord): + otherLoc = self.locations[glyph] + raise OpenTypeLibError( + 'Already defined different position for glyph "%s" at %s' + % (glyph, otherLoc), + location, + ) + if otValueRecord: + self.mapping[glyph] = otValueRecord + self.locations[glyph] = location + + def can_add(self, glyph, value): + assert isinstance(value, ValueRecord) + curValue = self.mapping.get(glyph) + return curValue is None or curValue == value + + def equals(self, other): + return LookupBuilder.equals(self, other) and self.mapping == other.mapping + + def build(self): + """Build the lookup. + + Returns: + An ``otTables.Lookup`` object representing the single positioning + lookup. + """ + subtables = buildSinglePos(self.mapping, self.glyphMap) + return self.buildLookup_(subtables) + + +# GSUB + + +def buildSingleSubstSubtable(mapping): + """Builds a single substitution (GSUB1) subtable. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.SingleSubstBuilder` instead. + + Args: + mapping: A dictionary mapping input glyph names to output glyph names. + + Returns: + An ``otTables.SingleSubst`` object, or ``None`` if the mapping dictionary + is empty. + """ + if not mapping: + return None + self = ot.SingleSubst() + self.mapping = dict(mapping) + return self + + +def buildMultipleSubstSubtable(mapping): + """Builds a multiple substitution (GSUB2) subtable. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.MultipleSubstBuilder` instead. + + Example:: + + # sub uni06C0 by uni06D5.fina hamza.above + # sub uni06C2 by uni06C1.fina hamza.above; + + subtable = buildMultipleSubstSubtable({ + "uni06C0": [ "uni06D5.fina", "hamza.above"], + "uni06C2": [ "uni06D1.fina", "hamza.above"] + }) + + Args: + mapping: A dictionary mapping input glyph names to a list of output + glyph names. + + Returns: + An ``otTables.MultipleSubst`` object or ``None`` if the mapping dictionary + is empty. + """ + if not mapping: + return None + self = ot.MultipleSubst() + self.mapping = dict(mapping) + return self + + +def buildAlternateSubstSubtable(mapping): + """Builds an alternate substitution (GSUB3) subtable. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.AlternateSubstBuilder` instead. + + Args: + mapping: A dictionary mapping input glyph names to a list of output + glyph names. + + Returns: + An ``otTables.AlternateSubst`` object or ``None`` if the mapping dictionary + is empty. + """ + if not mapping: + return None + self = ot.AlternateSubst() + self.alternates = dict(mapping) + return self + + +def _getLigatureKey(components): + # Computes a key for ordering ligatures in a GSUB Type-4 lookup. + + # When building the OpenType lookup, we need to make sure that + # the longest sequence of components is listed first, so we + # use the negative length as the primary key for sorting. + # To make buildLigatureSubstSubtable() deterministic, we use the + # component sequence as the secondary key. + + # For example, this will sort (f,f,f) < (f,f,i) < (f,f) < (f,i) < (f,l). + return (-len(components), components) + + +def buildLigatureSubstSubtable(mapping): + """Builds a ligature substitution (GSUB4) subtable. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.LigatureSubstBuilder` instead. + + Example:: + + # sub f f i by f_f_i; + # sub f i by f_i; + + subtable = buildLigatureSubstSubtable({ + ("f", "f", "i"): "f_f_i", + ("f", "i"): "f_i", + }) + + Args: + mapping: A dictionary mapping tuples of glyph names to output + glyph names. + + Returns: + An ``otTables.LigatureSubst`` object or ``None`` if the mapping dictionary + is empty. + """ + + if not mapping: + return None + self = ot.LigatureSubst() + # The following single line can replace the rest of this function + # with fontTools >= 3.1: + # self.ligatures = dict(mapping) + self.ligatures = {} + for components in sorted(mapping.keys(), key=_getLigatureKey): + ligature = ot.Ligature() + ligature.Component = components[1:] + ligature.CompCount = len(ligature.Component) + 1 + ligature.LigGlyph = mapping[components] + firstGlyph = components[0] + self.ligatures.setdefault(firstGlyph, []).append(ligature) + return self + + +# GPOS + + +def buildAnchor(x, y, point=None, deviceX=None, deviceY=None): + """Builds an Anchor table. + + This determines the appropriate anchor format based on the passed parameters. + + Args: + x (int): X coordinate. + y (int): Y coordinate. + point (int): Index of glyph contour point, if provided. + deviceX (``otTables.Device``): X coordinate device table, if provided. + deviceY (``otTables.Device``): Y coordinate device table, if provided. + + Returns: + An ``otTables.Anchor`` object. + """ + self = ot.Anchor() + self.XCoordinate, self.YCoordinate = x, y + self.Format = 1 + if point is not None: + self.AnchorPoint = point + self.Format = 2 + if deviceX is not None or deviceY is not None: + assert ( + self.Format == 1 + ), "Either point, or both of deviceX/deviceY, must be None." + self.XDeviceTable = deviceX + self.YDeviceTable = deviceY + self.Format = 3 + return self + + +def buildBaseArray(bases, numMarkClasses, glyphMap): + """Builds a base array record. + + As part of building mark-to-base positioning rules, you will need to define + a ``BaseArray`` record, which "defines for each base glyph an array of + anchors, one for each mark class." This function builds the base array + subtable. + + Example:: + + bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}} + basearray = buildBaseArray(bases, 2, font.getReverseGlyphMap()) + + Args: + bases (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being dictionaries mapping mark class ID + to the appropriate ``otTables.Anchor`` object used for attaching marks + of that class. + numMarkClasses (int): The total number of mark classes for which anchors + are defined. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + An ``otTables.BaseArray`` object. + """ + self = ot.BaseArray() + self.BaseRecord = [] + for base in sorted(bases, key=glyphMap.__getitem__): + b = bases[base] + anchors = [b.get(markClass) for markClass in range(numMarkClasses)] + self.BaseRecord.append(buildBaseRecord(anchors)) + self.BaseCount = len(self.BaseRecord) + return self + + +def buildBaseRecord(anchors): + # [otTables.Anchor, otTables.Anchor, ...] --> otTables.BaseRecord + self = ot.BaseRecord() + self.BaseAnchor = anchors + return self + + +def buildComponentRecord(anchors): + """Builds a component record. + + As part of building mark-to-ligature positioning rules, you will need to + define ``ComponentRecord`` objects, which contain "an array of offsets... + to the Anchor tables that define all the attachment points used to attach + marks to the component." This function builds the component record. + + Args: + anchors: A list of ``otTables.Anchor`` objects or ``None``. + + Returns: + A ``otTables.ComponentRecord`` object or ``None`` if no anchors are + supplied. + """ + if not anchors: + return None + self = ot.ComponentRecord() + self.LigatureAnchor = anchors + return self + + +def buildCursivePosSubtable(attach, glyphMap): + """Builds a cursive positioning (GPOS3) subtable. + + Cursive positioning lookups are made up of a coverage table of glyphs, + and a set of ``EntryExitRecord`` records containing the anchors for + each glyph. This function builds the cursive positioning subtable. + + Example:: + + subtable = buildCursivePosSubtable({ + "AlifIni": (None, buildAnchor(0, 50)), + "BehMed": (buildAnchor(500,250), buildAnchor(0,50)), + # ... + }, font.getReverseGlyphMap()) + + Args: + attach (dict): A mapping between glyph names and a tuple of two + ``otTables.Anchor`` objects representing entry and exit anchors. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + An ``otTables.CursivePos`` object, or ``None`` if the attachment + dictionary was empty. + """ + if not attach: + return None + self = ot.CursivePos() + self.Format = 1 + self.Coverage = buildCoverage(attach.keys(), glyphMap) + self.EntryExitRecord = [] + for glyph in self.Coverage.glyphs: + entryAnchor, exitAnchor = attach[glyph] + rec = ot.EntryExitRecord() + rec.EntryAnchor = entryAnchor + rec.ExitAnchor = exitAnchor + self.EntryExitRecord.append(rec) + self.EntryExitCount = len(self.EntryExitRecord) + return self + + +def buildDevice(deltas): + """Builds a Device record as part of a ValueRecord or Anchor. + + Device tables specify size-specific adjustments to value records + and anchors to reflect changes based on the resolution of the output. + For example, one could specify that an anchor's Y position should be + increased by 1 pixel when displayed at 8 pixels per em. This routine + builds device records. + + Args: + deltas: A dictionary mapping pixels-per-em sizes to the delta + adjustment in pixels when the font is displayed at that size. + + Returns: + An ``otTables.Device`` object if any deltas were supplied, or + ``None`` otherwise. + """ + if not deltas: + return None + self = ot.Device() + keys = deltas.keys() + self.StartSize = startSize = min(keys) + self.EndSize = endSize = max(keys) + assert 0 <= startSize <= endSize + self.DeltaValue = deltaValues = [ + deltas.get(size, 0) for size in range(startSize, endSize + 1) + ] + maxDelta = max(deltaValues) + minDelta = min(deltaValues) + assert minDelta > -129 and maxDelta < 128 + if minDelta > -3 and maxDelta < 2: + self.DeltaFormat = 1 + elif minDelta > -9 and maxDelta < 8: + self.DeltaFormat = 2 + else: + self.DeltaFormat = 3 + return self + + +def buildLigatureArray(ligs, numMarkClasses, glyphMap): + """Builds a LigatureArray subtable. + + As part of building a mark-to-ligature lookup, you will need to define + the set of anchors (for each mark class) on each component of the ligature + where marks can be attached. For example, for an Arabic divine name ligature + (lam lam heh), you may want to specify mark attachment positioning for + superior marks (fatha, etc.) and inferior marks (kasra, etc.) on each glyph + of the ligature. This routine builds the ligature array record. + + Example:: + + buildLigatureArray({ + "lam-lam-heh": [ + { 0: superiorAnchor1, 1: inferiorAnchor1 }, # attach points for lam1 + { 0: superiorAnchor2, 1: inferiorAnchor2 }, # attach points for lam2 + { 0: superiorAnchor3, 1: inferiorAnchor3 }, # attach points for heh + ] + }, 2, font.getReverseGlyphMap()) + + Args: + ligs (dict): A mapping of ligature names to an array of dictionaries: + for each component glyph in the ligature, an dictionary mapping + mark class IDs to anchors. + numMarkClasses (int): The number of mark classes. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + An ``otTables.LigatureArray`` object if deltas were supplied. + """ + self = ot.LigatureArray() + self.LigatureAttach = [] + for lig in sorted(ligs, key=glyphMap.__getitem__): + anchors = [] + for component in ligs[lig]: + anchors.append([component.get(mc) for mc in range(numMarkClasses)]) + self.LigatureAttach.append(buildLigatureAttach(anchors)) + self.LigatureCount = len(self.LigatureAttach) + return self + + +def buildLigatureAttach(components): + # [[Anchor, Anchor], [Anchor, Anchor, Anchor]] --> LigatureAttach + self = ot.LigatureAttach() + self.ComponentRecord = [buildComponentRecord(c) for c in components] + self.ComponentCount = len(self.ComponentRecord) + return self + + +def buildMarkArray(marks, glyphMap): + """Builds a mark array subtable. + + As part of building mark-to-* positioning rules, you will need to define + a MarkArray subtable, which "defines the class and the anchor point + for a mark glyph." This function builds the mark array subtable. + + Example:: + + mark = { + "acute": (0, buildAnchor(300,712)), + # ... + } + markarray = buildMarkArray(marks, font.getReverseGlyphMap()) + + Args: + marks (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being a tuple of mark class number and + an ``otTables.Anchor`` object representing the mark's attachment + point. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + An ``otTables.MarkArray`` object. + """ + self = ot.MarkArray() + self.MarkRecord = [] + for mark in sorted(marks.keys(), key=glyphMap.__getitem__): + markClass, anchor = marks[mark] + markrec = buildMarkRecord(markClass, anchor) + self.MarkRecord.append(markrec) + self.MarkCount = len(self.MarkRecord) + return self + + +def buildMarkBasePos(marks, bases, glyphMap): + """Build a list of MarkBasePos (GPOS4) subtables. + + This routine turns a set of marks and bases into a list of mark-to-base + positioning subtables. Currently the list will contain a single subtable + containing all marks and bases, although at a later date it may return the + optimal list of subtables subsetting the marks and bases into groups which + save space. See :func:`buildMarkBasePosSubtable` below. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.MarkBasePosBuilder` instead. + + Example:: + + # a1, a2, a3, a4, a5 = buildAnchor(500, 100), ... + + marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)} + bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}} + markbaseposes = buildMarkBasePos(marks, bases, font.getReverseGlyphMap()) + + Args: + marks (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being a tuple of mark class number and + an ``otTables.Anchor`` object representing the mark's attachment + point. (See :func:`buildMarkArray`.) + bases (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being dictionaries mapping mark class ID + to the appropriate ``otTables.Anchor`` object used for attaching marks + of that class. (See :func:`buildBaseArray`.) + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A list of ``otTables.MarkBasePos`` objects. + """ + # TODO: Consider emitting multiple subtables to save space. + # Partition the marks and bases into disjoint subsets, so that + # MarkBasePos rules would only access glyphs from a single + # subset. This would likely lead to smaller mark/base + # matrices, so we might be able to omit many of the empty + # anchor tables that we currently produce. Of course, this + # would only work if the MarkBasePos rules of real-world fonts + # allow partitioning into multiple subsets. We should find out + # whether this is the case; if so, implement the optimization. + # On the other hand, a very large number of subtables could + # slow down layout engines; so this would need profiling. + return [buildMarkBasePosSubtable(marks, bases, glyphMap)] + + +def buildMarkBasePosSubtable(marks, bases, glyphMap): + """Build a single MarkBasePos (GPOS4) subtable. + + This builds a mark-to-base lookup subtable containing all of the referenced + marks and bases. See :func:`buildMarkBasePos`. + + Args: + marks (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being a tuple of mark class number and + an ``otTables.Anchor`` object representing the mark's attachment + point. (See :func:`buildMarkArray`.) + bases (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being dictionaries mapping mark class ID + to the appropriate ``otTables.Anchor`` object used for attaching marks + of that class. (See :func:`buildBaseArray`.) + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A ``otTables.MarkBasePos`` object. + """ + self = ot.MarkBasePos() + self.Format = 1 + self.MarkCoverage = buildCoverage(marks, glyphMap) + self.MarkArray = buildMarkArray(marks, glyphMap) + self.ClassCount = max([mc for mc, _ in marks.values()]) + 1 + self.BaseCoverage = buildCoverage(bases, glyphMap) + self.BaseArray = buildBaseArray(bases, self.ClassCount, glyphMap) + return self + + +def buildMarkLigPos(marks, ligs, glyphMap): + """Build a list of MarkLigPos (GPOS5) subtables. + + This routine turns a set of marks and ligatures into a list of mark-to-ligature + positioning subtables. Currently the list will contain a single subtable + containing all marks and ligatures, although at a later date it may return + the optimal list of subtables subsetting the marks and ligatures into groups + which save space. See :func:`buildMarkLigPosSubtable` below. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.MarkLigPosBuilder` instead. + + Example:: + + # a1, a2, a3, a4, a5 = buildAnchor(500, 100), ... + marks = { + "acute": (0, a1), + "grave": (0, a1), + "cedilla": (1, a2) + } + ligs = { + "f_i": [ + { 0: a3, 1: a5 }, # f + { 0: a4, 1: a5 } # i + ], + # "c_t": [{...}, {...}] + } + markligposes = buildMarkLigPos(marks, ligs, + font.getReverseGlyphMap()) + + Args: + marks (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being a tuple of mark class number and + an ``otTables.Anchor`` object representing the mark's attachment + point. (See :func:`buildMarkArray`.) + ligs (dict): A mapping of ligature names to an array of dictionaries: + for each component glyph in the ligature, an dictionary mapping + mark class IDs to anchors. (See :func:`buildLigatureArray`.) + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A list of ``otTables.MarkLigPos`` objects. + + """ + # TODO: Consider splitting into multiple subtables to save space, + # as with MarkBasePos, this would be a trade-off that would need + # profiling. And, depending on how typical fonts are structured, + # it might not be worth doing at all. + return [buildMarkLigPosSubtable(marks, ligs, glyphMap)] + + +def buildMarkLigPosSubtable(marks, ligs, glyphMap): + """Build a single MarkLigPos (GPOS5) subtable. + + This builds a mark-to-base lookup subtable containing all of the referenced + marks and bases. See :func:`buildMarkLigPos`. + + Args: + marks (dict): A dictionary mapping anchors to glyphs; the keys being + glyph names, and the values being a tuple of mark class number and + an ``otTables.Anchor`` object representing the mark's attachment + point. (See :func:`buildMarkArray`.) + ligs (dict): A mapping of ligature names to an array of dictionaries: + for each component glyph in the ligature, an dictionary mapping + mark class IDs to anchors. (See :func:`buildLigatureArray`.) + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A ``otTables.MarkLigPos`` object. + """ + self = ot.MarkLigPos() + self.Format = 1 + self.MarkCoverage = buildCoverage(marks, glyphMap) + self.MarkArray = buildMarkArray(marks, glyphMap) + self.ClassCount = max([mc for mc, _ in marks.values()]) + 1 + self.LigatureCoverage = buildCoverage(ligs, glyphMap) + self.LigatureArray = buildLigatureArray(ligs, self.ClassCount, glyphMap) + return self + + +def buildMarkRecord(classID, anchor): + assert isinstance(classID, int) + assert isinstance(anchor, ot.Anchor) + self = ot.MarkRecord() + self.Class = classID + self.MarkAnchor = anchor + return self + + +def buildMark2Record(anchors): + # [otTables.Anchor, otTables.Anchor, ...] --> otTables.Mark2Record + self = ot.Mark2Record() + self.Mark2Anchor = anchors + return self + + +def _getValueFormat(f, values, i): + # Helper for buildPairPos{Glyphs|Classes}Subtable. + if f is not None: + return f + mask = 0 + for value in values: + if value is not None and value[i] is not None: + mask |= value[i].getFormat() + return mask + + +def buildPairPosClassesSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2=None): + """Builds a class pair adjustment (GPOS2 format 2) subtable. + + Kerning tables are generally expressed as pair positioning tables using + class-based pair adjustments. This routine builds format 2 PairPos + subtables. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.ClassPairPosSubtableBuilder` + instead, as this takes care of ensuring that the supplied pairs can be + formed into non-overlapping classes and emitting individual subtables + whenever the non-overlapping requirement means that a new subtable is + required. + + Example:: + + pairs = {} + + pairs[( + [ "K", "X" ], + [ "W", "V" ] + )] = ( buildValue(xAdvance=+5), buildValue() ) + # pairs[(... , ...)] = (..., ...) + + pairpos = buildPairPosClassesSubtable(pairs, font.getReverseGlyphMap()) + + Args: + pairs (dict): Pair positioning data; the keys being a two-element + tuple of lists of glyphnames, and the values being a two-element + tuple of ``otTables.ValueRecord`` objects. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + valueFormat1: Force the "left" value records to the given format. + valueFormat2: Force the "right" value records to the given format. + + Returns: + A ``otTables.PairPos`` object. + """ + coverage = set() + classDef1 = ClassDefBuilder(useClass0=True) + classDef2 = ClassDefBuilder(useClass0=False) + for gc1, gc2 in sorted(pairs): + coverage.update(gc1) + classDef1.add(gc1) + classDef2.add(gc2) + self = ot.PairPos() + self.Format = 2 + valueFormat1 = self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0) + valueFormat2 = self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1) + self.Coverage = buildCoverage(coverage, glyphMap) + self.ClassDef1 = classDef1.build() + self.ClassDef2 = classDef2.build() + classes1 = classDef1.classes() + classes2 = classDef2.classes() + self.Class1Record = [] + for c1 in classes1: + rec1 = ot.Class1Record() + rec1.Class2Record = [] + self.Class1Record.append(rec1) + for c2 in classes2: + rec2 = ot.Class2Record() + val1, val2 = pairs.get((c1, c2), (None, None)) + rec2.Value1 = ( + ValueRecord(src=val1, valueFormat=valueFormat1) + if valueFormat1 + else None + ) + rec2.Value2 = ( + ValueRecord(src=val2, valueFormat=valueFormat2) + if valueFormat2 + else None + ) + rec1.Class2Record.append(rec2) + self.Class1Count = len(self.Class1Record) + self.Class2Count = len(classes2) + return self + + +def buildPairPosGlyphs(pairs, glyphMap): + """Builds a list of glyph-based pair adjustment (GPOS2 format 1) subtables. + + This organises a list of pair positioning adjustments into subtables based + on common value record formats. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.PairPosBuilder` + instead. + + Example:: + + pairs = { + ("K", "W"): ( buildValue(xAdvance=+5), buildValue() ), + ("K", "V"): ( buildValue(xAdvance=+5), buildValue() ), + # ... + } + + subtables = buildPairPosGlyphs(pairs, font.getReverseGlyphMap()) + + Args: + pairs (dict): Pair positioning data; the keys being a two-element + tuple of glyphnames, and the values being a two-element + tuple of ``otTables.ValueRecord`` objects. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A list of ``otTables.PairPos`` objects. + """ + + p = {} # (formatA, formatB) --> {(glyphA, glyphB): (valA, valB)} + for (glyphA, glyphB), (valA, valB) in pairs.items(): + formatA = valA.getFormat() if valA is not None else 0 + formatB = valB.getFormat() if valB is not None else 0 + pos = p.setdefault((formatA, formatB), {}) + pos[(glyphA, glyphB)] = (valA, valB) + return [ + buildPairPosGlyphsSubtable(pos, glyphMap, formatA, formatB) + for ((formatA, formatB), pos) in sorted(p.items()) + ] + + +def buildPairPosGlyphsSubtable(pairs, glyphMap, valueFormat1=None, valueFormat2=None): + """Builds a single glyph-based pair adjustment (GPOS2 format 1) subtable. + + This builds a PairPos subtable from a dictionary of glyph pairs and + their positioning adjustments. See also :func:`buildPairPosGlyphs`. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.PairPosBuilder` instead. + + Example:: + + pairs = { + ("K", "W"): ( buildValue(xAdvance=+5), buildValue() ), + ("K", "V"): ( buildValue(xAdvance=+5), buildValue() ), + # ... + } + + pairpos = buildPairPosGlyphsSubtable(pairs, font.getReverseGlyphMap()) + + Args: + pairs (dict): Pair positioning data; the keys being a two-element + tuple of glyphnames, and the values being a two-element + tuple of ``otTables.ValueRecord`` objects. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + valueFormat1: Force the "left" value records to the given format. + valueFormat2: Force the "right" value records to the given format. + + Returns: + A ``otTables.PairPos`` object. + """ + self = ot.PairPos() + self.Format = 1 + valueFormat1 = self.ValueFormat1 = _getValueFormat(valueFormat1, pairs.values(), 0) + valueFormat2 = self.ValueFormat2 = _getValueFormat(valueFormat2, pairs.values(), 1) + p = {} + for (glyphA, glyphB), (valA, valB) in pairs.items(): + p.setdefault(glyphA, []).append((glyphB, valA, valB)) + self.Coverage = buildCoverage({g for g, _ in pairs.keys()}, glyphMap) + self.PairSet = [] + for glyph in self.Coverage.glyphs: + ps = ot.PairSet() + ps.PairValueRecord = [] + self.PairSet.append(ps) + for glyph2, val1, val2 in sorted(p[glyph], key=lambda x: glyphMap[x[0]]): + pvr = ot.PairValueRecord() + pvr.SecondGlyph = glyph2 + pvr.Value1 = ( + ValueRecord(src=val1, valueFormat=valueFormat1) + if valueFormat1 + else None + ) + pvr.Value2 = ( + ValueRecord(src=val2, valueFormat=valueFormat2) + if valueFormat2 + else None + ) + ps.PairValueRecord.append(pvr) + ps.PairValueCount = len(ps.PairValueRecord) + self.PairSetCount = len(self.PairSet) + return self + + +def buildSinglePos(mapping, glyphMap): + """Builds a list of single adjustment (GPOS1) subtables. + + This builds a list of SinglePos subtables from a dictionary of glyph + names and their positioning adjustments. The format of the subtables are + determined to optimize the size of the resulting subtables. + See also :func:`buildSinglePosSubtable`. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.SinglePosBuilder` instead. + + Example:: + + mapping = { + "V": buildValue({ "xAdvance" : +5 }), + # ... + } + + subtables = buildSinglePos(pairs, font.getReverseGlyphMap()) + + Args: + mapping (dict): A mapping between glyphnames and + ``otTables.ValueRecord`` objects. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A list of ``otTables.SinglePos`` objects. + """ + result, handled = [], set() + # In SinglePos format 1, the covered glyphs all share the same ValueRecord. + # In format 2, each glyph has its own ValueRecord, but these records + # all have the same properties (eg., all have an X but no Y placement). + coverages, masks, values = {}, {}, {} + for glyph, value in mapping.items(): + key = _getSinglePosValueKey(value) + coverages.setdefault(key, []).append(glyph) + masks.setdefault(key[0], []).append(key) + values[key] = value + + # If a ValueRecord is shared between multiple glyphs, we generate + # a SinglePos format 1 subtable; that is the most compact form. + for key, glyphs in coverages.items(): + # 5 ushorts is the length of introducing another sublookup + if len(glyphs) * _getSinglePosValueSize(key) > 5: + format1Mapping = {g: values[key] for g in glyphs} + result.append(buildSinglePosSubtable(format1Mapping, glyphMap)) + handled.add(key) + + # In the remaining ValueRecords, look for those whose valueFormat + # (the set of used properties) is shared between multiple records. + # These will get encoded in format 2. + for valueFormat, keys in masks.items(): + f2 = [k for k in keys if k not in handled] + if len(f2) > 1: + format2Mapping = {} + for k in f2: + format2Mapping.update((g, values[k]) for g in coverages[k]) + result.append(buildSinglePosSubtable(format2Mapping, glyphMap)) + handled.update(f2) + + # The remaining ValueRecords are only used by a few glyphs, normally + # one. We encode these in format 1 again. + for key, glyphs in coverages.items(): + if key not in handled: + for g in glyphs: + st = buildSinglePosSubtable({g: values[key]}, glyphMap) + result.append(st) + + # When the OpenType layout engine traverses the subtables, it will + # stop after the first matching subtable. Therefore, we sort the + # resulting subtables by decreasing coverage size; this increases + # the chance that the layout engine can do an early exit. (Of course, + # this would only be true if all glyphs were equally frequent, which + # is not really the case; but we do not know their distribution). + # If two subtables cover the same number of glyphs, we sort them + # by glyph ID so that our output is deterministic. + result.sort(key=lambda t: _getSinglePosTableKey(t, glyphMap)) + return result + + +def buildSinglePosSubtable(values, glyphMap): + """Builds a single adjustment (GPOS1) subtable. + + This builds a list of SinglePos subtables from a dictionary of glyph + names and their positioning adjustments. The format of the subtable is + determined to optimize the size of the output. + See also :func:`buildSinglePos`. + + Note that if you are implementing a layout compiler, you may find it more + flexible to use + :py:class:`fontTools.otlLib.lookupBuilders.SinglePosBuilder` instead. + + Example:: + + mapping = { + "V": buildValue({ "xAdvance" : +5 }), + # ... + } + + subtable = buildSinglePos(pairs, font.getReverseGlyphMap()) + + Args: + mapping (dict): A mapping between glyphnames and + ``otTables.ValueRecord`` objects. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A ``otTables.SinglePos`` object. + """ + self = ot.SinglePos() + self.Coverage = buildCoverage(values.keys(), glyphMap) + valueFormat = self.ValueFormat = reduce( + int.__or__, [v.getFormat() for v in values.values()], 0 + ) + valueRecords = [ + ValueRecord(src=values[g], valueFormat=valueFormat) + for g in self.Coverage.glyphs + ] + if all(v == valueRecords[0] for v in valueRecords): + self.Format = 1 + if self.ValueFormat != 0: + self.Value = valueRecords[0] + else: + self.Value = None + else: + self.Format = 2 + self.Value = valueRecords + self.ValueCount = len(self.Value) + return self + + +def _getSinglePosTableKey(subtable, glyphMap): + assert isinstance(subtable, ot.SinglePos), subtable + glyphs = subtable.Coverage.glyphs + return (-len(glyphs), glyphMap[glyphs[0]]) + + +def _getSinglePosValueKey(valueRecord): + # otBase.ValueRecord --> (2, ("YPlacement": 12)) + assert isinstance(valueRecord, ValueRecord), valueRecord + valueFormat, result = 0, [] + for name, value in valueRecord.__dict__.items(): + if isinstance(value, ot.Device): + result.append((name, _makeDeviceTuple(value))) + else: + result.append((name, value)) + valueFormat |= valueRecordFormatDict[name][0] + result.sort() + result.insert(0, valueFormat) + return tuple(result) + + +_DeviceTuple = namedtuple("_DeviceTuple", "DeltaFormat StartSize EndSize DeltaValue") + + +def _makeDeviceTuple(device): + # otTables.Device --> tuple, for making device tables unique + return _DeviceTuple( + device.DeltaFormat, + device.StartSize, + device.EndSize, + () if device.DeltaFormat & 0x8000 else tuple(device.DeltaValue), + ) + + +def _getSinglePosValueSize(valueKey): + # Returns how many ushorts this valueKey (short form of ValueRecord) takes up + count = 0 + for _, v in valueKey[1:]: + if isinstance(v, _DeviceTuple): + count += len(v.DeltaValue) + 3 + else: + count += 1 + return count + + +def buildValue(value): + """Builds a positioning value record. + + Value records are used to specify coordinates and adjustments for + positioning and attaching glyphs. Many of the positioning functions + in this library take ``otTables.ValueRecord`` objects as arguments. + This function builds value records from dictionaries. + + Args: + value (dict): A dictionary with zero or more of the following keys: + - ``xPlacement`` + - ``yPlacement`` + - ``xAdvance`` + - ``yAdvance`` + - ``xPlaDevice`` + - ``yPlaDevice`` + - ``xAdvDevice`` + - ``yAdvDevice`` + + Returns: + An ``otTables.ValueRecord`` object. + """ + self = ValueRecord() + for k, v in value.items(): + setattr(self, k, v) + return self + + +# GDEF + + +def buildAttachList(attachPoints, glyphMap): + """Builds an AttachList subtable. + + A GDEF table may contain an Attachment Point List table (AttachList) + which stores the contour indices of attachment points for glyphs with + attachment points. This routine builds AttachList subtables. + + Args: + attachPoints (dict): A mapping between glyph names and a list of + contour indices. + + Returns: + An ``otTables.AttachList`` object if attachment points are supplied, + or ``None`` otherwise. + """ + if not attachPoints: + return None + self = ot.AttachList() + self.Coverage = buildCoverage(attachPoints.keys(), glyphMap) + self.AttachPoint = [buildAttachPoint(attachPoints[g]) for g in self.Coverage.glyphs] + self.GlyphCount = len(self.AttachPoint) + return self + + +def buildAttachPoint(points): + # [4, 23, 41] --> otTables.AttachPoint + # Only used by above. + if not points: + return None + self = ot.AttachPoint() + self.PointIndex = sorted(set(points)) + self.PointCount = len(self.PointIndex) + return self + + +def buildCaretValueForCoord(coord): + # 500 --> otTables.CaretValue, format 1 + # (500, DeviceTable) --> otTables.CaretValue, format 3 + self = ot.CaretValue() + if isinstance(coord, tuple): + self.Format = 3 + self.Coordinate, self.DeviceTable = coord + else: + self.Format = 1 + self.Coordinate = coord + return self + + +def buildCaretValueForPoint(point): + # 4 --> otTables.CaretValue, format 2 + self = ot.CaretValue() + self.Format = 2 + self.CaretValuePoint = point + return self + + +def buildLigCaretList(coords, points, glyphMap): + """Builds a ligature caret list table. + + Ligatures appear as a single glyph representing multiple characters; however + when, for example, editing text containing a ``f_i`` ligature, the user may + want to place the cursor between the ``f`` and the ``i``. The ligature caret + list in the GDEF table specifies the position to display the "caret" (the + character insertion indicator, typically a flashing vertical bar) "inside" + the ligature to represent an insertion point. The insertion positions may + be specified either by coordinate or by contour point. + + Example:: + + coords = { + "f_f_i": [300, 600] # f|fi cursor at 300 units, ff|i cursor at 600. + } + points = { + "c_t": [28] # c|t cursor appears at coordinate of contour point 28. + } + ligcaretlist = buildLigCaretList(coords, points, font.getReverseGlyphMap()) + + Args: + coords: A mapping between glyph names and a list of coordinates for + the insertion point of each ligature component after the first one. + points: A mapping between glyph names and a list of contour points for + the insertion point of each ligature component after the first one. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns: + A ``otTables.LigCaretList`` object if any carets are present, or + ``None`` otherwise.""" + glyphs = set(coords.keys()) if coords else set() + if points: + glyphs.update(points.keys()) + carets = {g: buildLigGlyph(coords.get(g), points.get(g)) for g in glyphs} + carets = {g: c for g, c in carets.items() if c is not None} + if not carets: + return None + self = ot.LigCaretList() + self.Coverage = buildCoverage(carets.keys(), glyphMap) + self.LigGlyph = [carets[g] for g in self.Coverage.glyphs] + self.LigGlyphCount = len(self.LigGlyph) + return self + + +def buildLigGlyph(coords, points): + # ([500], [4]) --> otTables.LigGlyph; None for empty coords/points + carets = [] + if coords: + coords = sorted(coords, key=lambda c: c[0] if isinstance(c, tuple) else c) + carets.extend([buildCaretValueForCoord(c) for c in coords]) + if points: + carets.extend([buildCaretValueForPoint(p) for p in sorted(points)]) + if not carets: + return None + self = ot.LigGlyph() + self.CaretValue = carets + self.CaretCount = len(self.CaretValue) + return self + + +def buildMarkGlyphSetsDef(markSets, glyphMap): + """Builds a mark glyph sets definition table. + + OpenType Layout lookups may choose to use mark filtering sets to consider + or ignore particular combinations of marks. These sets are specified by + setting a flag on the lookup, but the mark filtering sets are defined in + the ``GDEF`` table. This routine builds the subtable containing the mark + glyph set definitions. + + Example:: + + set0 = set("acute", "grave") + set1 = set("caron", "grave") + + markglyphsets = buildMarkGlyphSetsDef([set0, set1], font.getReverseGlyphMap()) + + Args: + + markSets: A list of sets of glyphnames. + glyphMap: a glyph name to ID map, typically returned from + ``font.getReverseGlyphMap()``. + + Returns + An ``otTables.MarkGlyphSetsDef`` object. + """ + if not markSets: + return None + self = ot.MarkGlyphSetsDef() + self.MarkSetTableFormat = 1 + self.Coverage = [buildCoverage(m, glyphMap) for m in markSets] + self.MarkSetCount = len(self.Coverage) + return self + + +class ClassDefBuilder(object): + """Helper for building ClassDef tables.""" + + def __init__(self, useClass0): + self.classes_ = set() + self.glyphs_ = {} + self.useClass0_ = useClass0 + + def canAdd(self, glyphs): + if isinstance(glyphs, (set, frozenset)): + glyphs = sorted(glyphs) + glyphs = tuple(glyphs) + if glyphs in self.classes_: + return True + for glyph in glyphs: + if glyph in self.glyphs_: + return False + return True + + def add(self, glyphs): + if isinstance(glyphs, (set, frozenset)): + glyphs = sorted(glyphs) + glyphs = tuple(glyphs) + if glyphs in self.classes_: + return + self.classes_.add(glyphs) + for glyph in glyphs: + if glyph in self.glyphs_: + raise OpenTypeLibError( + f"Glyph {glyph} is already present in class.", None + ) + self.glyphs_[glyph] = glyphs + + def classes(self): + # In ClassDef1 tables, class id #0 does not need to be encoded + # because zero is the default. Therefore, we use id #0 for the + # glyph class that has the largest number of members. However, + # in other tables than ClassDef1, 0 means "every other glyph" + # so we should not use that ID for any real glyph classes; + # we implement this by inserting an empty set at position 0. + # + # TODO: Instead of counting the number of glyphs in each class, + # we should determine the encoded size. If the glyphs in a large + # class form a contiguous range, the encoding is actually quite + # compact, whereas a non-contiguous set might need a lot of bytes + # in the output file. We don't get this right with the key below. + result = sorted(self.classes_, key=lambda s: (-len(s), s)) + if not self.useClass0_: + result.insert(0, frozenset()) + return result + + def build(self): + glyphClasses = {} + for classID, glyphs in enumerate(self.classes()): + if classID == 0: + continue + for glyph in glyphs: + glyphClasses[glyph] = classID + classDef = ot.ClassDef() + classDef.classDefs = glyphClasses + return classDef + + +AXIS_VALUE_NEGATIVE_INFINITY = fixedToFloat(-0x80000000, 16) +AXIS_VALUE_POSITIVE_INFINITY = fixedToFloat(0x7FFFFFFF, 16) + + +def buildStatTable( + ttFont, axes, locations=None, elidedFallbackName=2, windowsNames=True, macNames=True +): + """Add a 'STAT' table to 'ttFont'. + + 'axes' is a list of dictionaries describing axes and their + values. + + Example:: + + axes = [ + dict( + tag="wght", + name="Weight", + ordering=0, # optional + values=[ + dict(value=100, name='Thin'), + dict(value=300, name='Light'), + dict(value=400, name='Regular', flags=0x2), + dict(value=900, name='Black'), + ], + ) + ] + + Each axis dict must have 'tag' and 'name' items. 'tag' maps + to the 'AxisTag' field. 'name' can be a name ID (int), a string, + or a dictionary containing multilingual names (see the + addMultilingualName() name table method), and will translate to + the AxisNameID field. + + An axis dict may contain an 'ordering' item that maps to the + AxisOrdering field. If omitted, the order of the axes list is + used to calculate AxisOrdering fields. + + The axis dict may contain a 'values' item, which is a list of + dictionaries describing AxisValue records belonging to this axis. + + Each value dict must have a 'name' item, which can be a name ID + (int), a string, or a dictionary containing multilingual names, + like the axis name. It translates to the ValueNameID field. + + Optionally the value dict can contain a 'flags' item. It maps to + the AxisValue Flags field, and will be 0 when omitted. + + The format of the AxisValue is determined by the remaining contents + of the value dictionary: + + If the value dict contains a 'value' item, an AxisValue record + Format 1 is created. If in addition to the 'value' item it contains + a 'linkedValue' item, an AxisValue record Format 3 is built. + + If the value dict contains a 'nominalValue' item, an AxisValue + record Format 2 is built. Optionally it may contain 'rangeMinValue' + and 'rangeMaxValue' items. These map to -Infinity and +Infinity + respectively if omitted. + + You cannot specify Format 4 AxisValue tables this way, as they are + not tied to a single axis, and specify a name for a location that + is defined by multiple axes values. Instead, you need to supply the + 'locations' argument. + + The optional 'locations' argument specifies AxisValue Format 4 + tables. It should be a list of dicts, where each dict has a 'name' + item, which works just like the value dicts above, an optional + 'flags' item (defaulting to 0x0), and a 'location' dict. A + location dict key is an axis tag, and the associated value is the + location on the specified axis. They map to the AxisIndex and Value + fields of the AxisValueRecord. + + Example:: + + locations = [ + dict(name='Regular ABCD', location=dict(wght=300, ABCD=100)), + dict(name='Bold ABCD XYZ', location=dict(wght=600, ABCD=200)), + ] + + The optional 'elidedFallbackName' argument can be a name ID (int), + a string, a dictionary containing multilingual names, or a list of + STATNameStatements. It translates to the ElidedFallbackNameID field. + + The 'ttFont' argument must be a TTFont instance that already has a + 'name' table. If a 'STAT' table already exists, it will be + overwritten by the newly created one. + """ + ttFont["STAT"] = ttLib.newTable("STAT") + statTable = ttFont["STAT"].table = ot.STAT() + nameTable = ttFont["name"] + statTable.ElidedFallbackNameID = _addName( + nameTable, elidedFallbackName, windows=windowsNames, mac=macNames + ) + + # 'locations' contains data for AxisValue Format 4 + axisRecords, axisValues = _buildAxisRecords( + axes, nameTable, windowsNames=windowsNames, macNames=macNames + ) + if not locations: + statTable.Version = 0x00010001 + else: + # We'll be adding Format 4 AxisValue records, which + # requires a higher table version + statTable.Version = 0x00010002 + multiAxisValues = _buildAxisValuesFormat4( + locations, axes, nameTable, windowsNames=windowsNames, macNames=macNames + ) + axisValues = multiAxisValues + axisValues + nameTable.names.sort() + + # Store AxisRecords + axisRecordArray = ot.AxisRecordArray() + axisRecordArray.Axis = axisRecords + # XXX these should not be hard-coded but computed automatically + statTable.DesignAxisRecordSize = 8 + statTable.DesignAxisRecord = axisRecordArray + statTable.DesignAxisCount = len(axisRecords) + + statTable.AxisValueCount = 0 + statTable.AxisValueArray = None + if axisValues: + # Store AxisValueRecords + axisValueArray = ot.AxisValueArray() + axisValueArray.AxisValue = axisValues + statTable.AxisValueArray = axisValueArray + statTable.AxisValueCount = len(axisValues) + + +def _buildAxisRecords(axes, nameTable, windowsNames=True, macNames=True): + axisRecords = [] + axisValues = [] + for axisRecordIndex, axisDict in enumerate(axes): + axis = ot.AxisRecord() + axis.AxisTag = axisDict["tag"] + axis.AxisNameID = _addName( + nameTable, axisDict["name"], 256, windows=windowsNames, mac=macNames + ) + axis.AxisOrdering = axisDict.get("ordering", axisRecordIndex) + axisRecords.append(axis) + + for axisVal in axisDict.get("values", ()): + axisValRec = ot.AxisValue() + axisValRec.AxisIndex = axisRecordIndex + axisValRec.Flags = axisVal.get("flags", 0) + axisValRec.ValueNameID = _addName( + nameTable, axisVal["name"], windows=windowsNames, mac=macNames + ) + + if "value" in axisVal: + axisValRec.Value = axisVal["value"] + if "linkedValue" in axisVal: + axisValRec.Format = 3 + axisValRec.LinkedValue = axisVal["linkedValue"] + else: + axisValRec.Format = 1 + elif "nominalValue" in axisVal: + axisValRec.Format = 2 + axisValRec.NominalValue = axisVal["nominalValue"] + axisValRec.RangeMinValue = axisVal.get( + "rangeMinValue", AXIS_VALUE_NEGATIVE_INFINITY + ) + axisValRec.RangeMaxValue = axisVal.get( + "rangeMaxValue", AXIS_VALUE_POSITIVE_INFINITY + ) + else: + raise ValueError("Can't determine format for AxisValue") + + axisValues.append(axisValRec) + return axisRecords, axisValues + + +def _buildAxisValuesFormat4( + locations, axes, nameTable, windowsNames=True, macNames=True +): + axisTagToIndex = {} + for axisRecordIndex, axisDict in enumerate(axes): + axisTagToIndex[axisDict["tag"]] = axisRecordIndex + + axisValues = [] + for axisLocationDict in locations: + axisValRec = ot.AxisValue() + axisValRec.Format = 4 + axisValRec.ValueNameID = _addName( + nameTable, axisLocationDict["name"], windows=windowsNames, mac=macNames + ) + axisValRec.Flags = axisLocationDict.get("flags", 0) + axisValueRecords = [] + for tag, value in axisLocationDict["location"].items(): + avr = ot.AxisValueRecord() + avr.AxisIndex = axisTagToIndex[tag] + avr.Value = value + axisValueRecords.append(avr) + axisValueRecords.sort(key=lambda avr: avr.AxisIndex) + axisValRec.AxisCount = len(axisValueRecords) + axisValRec.AxisValueRecord = axisValueRecords + axisValues.append(axisValRec) + return axisValues + + +def _addName(nameTable, value, minNameID=0, windows=True, mac=True): + if isinstance(value, int): + # Already a nameID + return value + if isinstance(value, str): + names = dict(en=value) + elif isinstance(value, dict): + names = value + elif isinstance(value, list): + nameID = nameTable._findUnusedNameID() + for nameRecord in value: + if isinstance(nameRecord, STATNameStatement): + nameTable.setName( + nameRecord.string, + nameID, + nameRecord.platformID, + nameRecord.platEncID, + nameRecord.langID, + ) + else: + raise TypeError("value must be a list of STATNameStatements") + return nameID + else: + raise TypeError("value must be int, str, dict or list") + return nameTable.addMultilingualName( + names, windows=windows, mac=mac, minNameID=minNameID + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/error.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/error.py new file mode 100644 index 00000000..1cbef578 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/error.py @@ -0,0 +1,11 @@ +class OpenTypeLibError(Exception): + def __init__(self, message, location): + Exception.__init__(self, message) + self.location = location + + def __str__(self): + message = Exception.__str__(self) + if self.location: + return f"{self.location}: {message}" + else: + return message diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/maxContextCalc.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/maxContextCalc.py new file mode 100644 index 00000000..03e7561b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/maxContextCalc.py @@ -0,0 +1,96 @@ +__all__ = ["maxCtxFont"] + + +def maxCtxFont(font): + """Calculate the usMaxContext value for an entire font.""" + + maxCtx = 0 + for tag in ("GSUB", "GPOS"): + if tag not in font: + continue + table = font[tag].table + if not table.LookupList: + continue + for lookup in table.LookupList.Lookup: + for st in lookup.SubTable: + maxCtx = maxCtxSubtable(maxCtx, tag, lookup.LookupType, st) + return maxCtx + + +def maxCtxSubtable(maxCtx, tag, lookupType, st): + """Calculate usMaxContext based on a single lookup table (and an existing + max value). + """ + + # single positioning, single / multiple substitution + if (tag == "GPOS" and lookupType == 1) or ( + tag == "GSUB" and lookupType in (1, 2, 3) + ): + maxCtx = max(maxCtx, 1) + + # pair positioning + elif tag == "GPOS" and lookupType == 2: + maxCtx = max(maxCtx, 2) + + # ligatures + elif tag == "GSUB" and lookupType == 4: + for ligatures in st.ligatures.values(): + for ligature in ligatures: + maxCtx = max(maxCtx, ligature.CompCount) + + # context + elif (tag == "GPOS" and lookupType == 7) or (tag == "GSUB" and lookupType == 5): + maxCtx = maxCtxContextualSubtable(maxCtx, st, "Pos" if tag == "GPOS" else "Sub") + + # chained context + elif (tag == "GPOS" and lookupType == 8) or (tag == "GSUB" and lookupType == 6): + maxCtx = maxCtxContextualSubtable( + maxCtx, st, "Pos" if tag == "GPOS" else "Sub", "Chain" + ) + + # extensions + elif (tag == "GPOS" and lookupType == 9) or (tag == "GSUB" and lookupType == 7): + maxCtx = maxCtxSubtable(maxCtx, tag, st.ExtensionLookupType, st.ExtSubTable) + + # reverse-chained context + elif tag == "GSUB" and lookupType == 8: + maxCtx = maxCtxContextualRule(maxCtx, st, "Reverse") + + return maxCtx + + +def maxCtxContextualSubtable(maxCtx, st, ruleType, chain=""): + """Calculate usMaxContext based on a contextual feature subtable.""" + + if st.Format == 1: + for ruleset in getattr(st, "%s%sRuleSet" % (chain, ruleType)): + if ruleset is None: + continue + for rule in getattr(ruleset, "%s%sRule" % (chain, ruleType)): + if rule is None: + continue + maxCtx = maxCtxContextualRule(maxCtx, rule, chain) + + elif st.Format == 2: + for ruleset in getattr(st, "%s%sClassSet" % (chain, ruleType)): + if ruleset is None: + continue + for rule in getattr(ruleset, "%s%sClassRule" % (chain, ruleType)): + if rule is None: + continue + maxCtx = maxCtxContextualRule(maxCtx, rule, chain) + + elif st.Format == 3: + maxCtx = maxCtxContextualRule(maxCtx, st, chain) + + return maxCtx + + +def maxCtxContextualRule(maxCtx, st, chain): + """Calculate usMaxContext based on a contextual feature rule.""" + + if not chain: + return max(maxCtx, st.GlyphCount) + elif chain == "Reverse": + return max(maxCtx, st.GlyphCount + st.LookAheadGlyphCount) + return max(maxCtx, st.InputGlyphCount + st.LookAheadGlyphCount) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__init__.py new file mode 100644 index 00000000..25bce9cd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__init__.py @@ -0,0 +1,53 @@ +from argparse import RawTextHelpFormatter +from fontTools.otlLib.optimize.gpos import COMPRESSION_LEVEL, compact +from fontTools.ttLib import TTFont + + +def main(args=None): + """Optimize the layout tables of an existing font""" + from argparse import ArgumentParser + + from fontTools import configLogger + + parser = ArgumentParser( + prog="otlLib.optimize", + description=main.__doc__, + formatter_class=RawTextHelpFormatter, + ) + parser.add_argument("font") + parser.add_argument( + "-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file" + ) + parser.add_argument( + "--gpos-compression-level", + help=COMPRESSION_LEVEL.help, + default=COMPRESSION_LEVEL.default, + choices=list(range(10)), + type=int, + ) + logging_group = parser.add_mutually_exclusive_group(required=False) + logging_group.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + logging_group.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + options = parser.parse_args(args) + + configLogger( + level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") + ) + + font = TTFont(options.font) + compact(font, options.gpos_compression_level) + font.save(options.outfile or options.font) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) > 1: + sys.exit(main()) + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__main__.py new file mode 100644 index 00000000..b0ae9081 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/__main__.py @@ -0,0 +1,6 @@ +import sys +from fontTools.otlLib.optimize import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/gpos.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/gpos.py new file mode 100644 index 00000000..01c2257c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/otlLib/optimize/gpos.py @@ -0,0 +1,453 @@ +import logging +import os +from collections import defaultdict, namedtuple +from functools import reduce +from itertools import chain +from math import log2 +from typing import DefaultDict, Dict, Iterable, List, Sequence, Tuple + +from fontTools.config import OPTIONS +from fontTools.misc.intTools import bit_count, bit_indices +from fontTools.ttLib import TTFont +from fontTools.ttLib.tables import otBase, otTables + +log = logging.getLogger(__name__) + +COMPRESSION_LEVEL = OPTIONS[f"{__name__}:COMPRESSION_LEVEL"] + +# Kept because ufo2ft depends on it, to be removed once ufo2ft uses the config instead +# https://github.com/fonttools/fonttools/issues/2592 +GPOS_COMPACT_MODE_ENV_KEY = "FONTTOOLS_GPOS_COMPACT_MODE" +GPOS_COMPACT_MODE_DEFAULT = str(COMPRESSION_LEVEL.default) + + +def _compression_level_from_env() -> int: + env_level = GPOS_COMPACT_MODE_DEFAULT + if GPOS_COMPACT_MODE_ENV_KEY in os.environ: + import warnings + + warnings.warn( + f"'{GPOS_COMPACT_MODE_ENV_KEY}' environment variable is deprecated. " + "Please set the 'fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL' option " + "in TTFont.cfg.", + DeprecationWarning, + ) + + env_level = os.environ[GPOS_COMPACT_MODE_ENV_KEY] + if len(env_level) == 1 and env_level in "0123456789": + return int(env_level) + raise ValueError(f"Bad {GPOS_COMPACT_MODE_ENV_KEY}={env_level}") + + +def compact(font: TTFont, level: int) -> TTFont: + # Ideal plan: + # 1. Find lookups of Lookup Type 2: Pair Adjustment Positioning Subtable + # https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-2-pair-adjustment-positioning-subtable + # 2. Extract glyph-glyph kerning and class-kerning from all present subtables + # 3. Regroup into different subtable arrangements + # 4. Put back into the lookup + # + # Actual implementation: + # 2. Only class kerning is optimized currently + # 3. If the input kerning is already in several subtables, the subtables + # are not grouped together first; instead each subtable is treated + # independently, so currently this step is: + # Split existing subtables into more smaller subtables + gpos = font["GPOS"] + for lookup in gpos.table.LookupList.Lookup: + if lookup.LookupType == 2: + compact_lookup(font, level, lookup) + elif lookup.LookupType == 9 and lookup.SubTable[0].ExtensionLookupType == 2: + compact_ext_lookup(font, level, lookup) + return font + + +def compact_lookup(font: TTFont, level: int, lookup: otTables.Lookup) -> None: + new_subtables = compact_pair_pos(font, level, lookup.SubTable) + lookup.SubTable = new_subtables + lookup.SubTableCount = len(new_subtables) + + +def compact_ext_lookup(font: TTFont, level: int, lookup: otTables.Lookup) -> None: + new_subtables = compact_pair_pos( + font, level, [ext_subtable.ExtSubTable for ext_subtable in lookup.SubTable] + ) + new_ext_subtables = [] + for subtable in new_subtables: + ext_subtable = otTables.ExtensionPos() + ext_subtable.Format = 1 + ext_subtable.ExtSubTable = subtable + new_ext_subtables.append(ext_subtable) + lookup.SubTable = new_ext_subtables + lookup.SubTableCount = len(new_ext_subtables) + + +def compact_pair_pos( + font: TTFont, level: int, subtables: Sequence[otTables.PairPos] +) -> Sequence[otTables.PairPos]: + new_subtables = [] + for subtable in subtables: + if subtable.Format == 1: + # Not doing anything to Format 1 (yet?) + new_subtables.append(subtable) + elif subtable.Format == 2: + new_subtables.extend(compact_class_pairs(font, level, subtable)) + return new_subtables + + +def compact_class_pairs( + font: TTFont, level: int, subtable: otTables.PairPos +) -> List[otTables.PairPos]: + from fontTools.otlLib.builder import buildPairPosClassesSubtable + + subtables = [] + classes1: DefaultDict[int, List[str]] = defaultdict(list) + for g in subtable.Coverage.glyphs: + classes1[subtable.ClassDef1.classDefs.get(g, 0)].append(g) + classes2: DefaultDict[int, List[str]] = defaultdict(list) + for g, i in subtable.ClassDef2.classDefs.items(): + classes2[i].append(g) + all_pairs = {} + for i, class1 in enumerate(subtable.Class1Record): + for j, class2 in enumerate(class1.Class2Record): + if is_really_zero(class2): + continue + all_pairs[(tuple(sorted(classes1[i])), tuple(sorted(classes2[j])))] = ( + getattr(class2, "Value1", None), + getattr(class2, "Value2", None), + ) + grouped_pairs = cluster_pairs_by_class2_coverage_custom_cost(font, all_pairs, level) + for pairs in grouped_pairs: + subtables.append(buildPairPosClassesSubtable(pairs, font.getReverseGlyphMap())) + return subtables + + +def is_really_zero(class2: otTables.Class2Record) -> bool: + v1 = getattr(class2, "Value1", None) + v2 = getattr(class2, "Value2", None) + return (v1 is None or v1.getEffectiveFormat() == 0) and ( + v2 is None or v2.getEffectiveFormat() == 0 + ) + + +Pairs = Dict[ + Tuple[Tuple[str, ...], Tuple[str, ...]], + Tuple[otBase.ValueRecord, otBase.ValueRecord], +] + + +# Adapted from https://github.com/fonttools/fonttools/blob/f64f0b42f2d1163b2d85194e0979def539f5dca3/Lib/fontTools/ttLib/tables/otTables.py#L935-L958 +def _getClassRanges(glyphIDs: Iterable[int]): + glyphIDs = sorted(glyphIDs) + last = glyphIDs[0] + ranges = [[last]] + for glyphID in glyphIDs[1:]: + if glyphID != last + 1: + ranges[-1].append(last) + ranges.append([glyphID]) + last = glyphID + ranges[-1].append(last) + return ranges, glyphIDs[0], glyphIDs[-1] + + +# Adapted from https://github.com/fonttools/fonttools/blob/f64f0b42f2d1163b2d85194e0979def539f5dca3/Lib/fontTools/ttLib/tables/otTables.py#L960-L989 +def _classDef_bytes( + class_data: List[Tuple[List[Tuple[int, int]], int, int]], + class_ids: List[int], + coverage=False, +): + if not class_ids: + return 0 + first_ranges, min_glyph_id, max_glyph_id = class_data[class_ids[0]] + range_count = len(first_ranges) + for i in class_ids[1:]: + data = class_data[i] + range_count += len(data[0]) + min_glyph_id = min(min_glyph_id, data[1]) + max_glyph_id = max(max_glyph_id, data[2]) + glyphCount = max_glyph_id - min_glyph_id + 1 + # https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1 + format1_bytes = 6 + glyphCount * 2 + # https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2 + format2_bytes = 4 + range_count * 6 + return min(format1_bytes, format2_bytes) + + +ClusteringContext = namedtuple( + "ClusteringContext", + [ + "lines", + "all_class1", + "all_class1_data", + "all_class2_data", + "valueFormat1_bytes", + "valueFormat2_bytes", + ], +) + + +class Cluster: + # TODO(Python 3.7): Turn this into a dataclass + # ctx: ClusteringContext + # indices: int + # Caches + # TODO(Python 3.8): use functools.cached_property instead of the + # manually cached properties, and remove the cache fields listed below. + # _indices: Optional[List[int]] = None + # _column_indices: Optional[List[int]] = None + # _cost: Optional[int] = None + + __slots__ = "ctx", "indices_bitmask", "_indices", "_column_indices", "_cost" + + def __init__(self, ctx: ClusteringContext, indices_bitmask: int): + self.ctx = ctx + self.indices_bitmask = indices_bitmask + self._indices = None + self._column_indices = None + self._cost = None + + @property + def indices(self): + if self._indices is None: + self._indices = bit_indices(self.indices_bitmask) + return self._indices + + @property + def column_indices(self): + if self._column_indices is None: + # Indices of columns that have a 1 in at least 1 line + # => binary OR all the lines + bitmask = reduce(int.__or__, (self.ctx.lines[i] for i in self.indices)) + self._column_indices = bit_indices(bitmask) + return self._column_indices + + @property + def width(self): + # Add 1 because Class2=0 cannot be used but needs to be encoded. + return len(self.column_indices) + 1 + + @property + def cost(self): + if self._cost is None: + self._cost = ( + # 2 bytes to store the offset to this subtable in the Lookup table above + 2 + # Contents of the subtable + # From: https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment + # uint16 posFormat Format identifier: format = 2 + + 2 + # Offset16 coverageOffset Offset to Coverage table, from beginning of PairPos subtable. + + 2 + + self.coverage_bytes + # uint16 valueFormat1 ValueRecord definition — for the first glyph of the pair (may be zero). + + 2 + # uint16 valueFormat2 ValueRecord definition — for the second glyph of the pair (may be zero). + + 2 + # Offset16 classDef1Offset Offset to ClassDef table, from beginning of PairPos subtable — for the first glyph of the pair. + + 2 + + self.classDef1_bytes + # Offset16 classDef2Offset Offset to ClassDef table, from beginning of PairPos subtable — for the second glyph of the pair. + + 2 + + self.classDef2_bytes + # uint16 class1Count Number of classes in classDef1 table — includes Class 0. + + 2 + # uint16 class2Count Number of classes in classDef2 table — includes Class 0. + + 2 + # Class1Record class1Records[class1Count] Array of Class1 records, ordered by classes in classDef1. + + (self.ctx.valueFormat1_bytes + self.ctx.valueFormat2_bytes) + * len(self.indices) + * self.width + ) + return self._cost + + @property + def coverage_bytes(self): + format1_bytes = ( + # From https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1 + # uint16 coverageFormat Format identifier — format = 1 + # uint16 glyphCount Number of glyphs in the glyph array + 4 + # uint16 glyphArray[glyphCount] Array of glyph IDs — in numerical order + + sum(len(self.ctx.all_class1[i]) for i in self.indices) * 2 + ) + ranges = sorted( + chain.from_iterable(self.ctx.all_class1_data[i][0] for i in self.indices) + ) + merged_range_count = 0 + last = None + for start, end in ranges: + if last is not None and start != last + 1: + merged_range_count += 1 + last = end + format2_bytes = ( + # From https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2 + # uint16 coverageFormat Format identifier — format = 2 + # uint16 rangeCount Number of RangeRecords + 4 + # RangeRecord rangeRecords[rangeCount] Array of glyph ranges — ordered by startGlyphID. + # uint16 startGlyphID First glyph ID in the range + # uint16 endGlyphID Last glyph ID in the range + # uint16 startCoverageIndex Coverage Index of first glyph ID in range + + merged_range_count * 6 + ) + return min(format1_bytes, format2_bytes) + + @property + def classDef1_bytes(self): + # We can skip encoding one of the Class1 definitions, and use + # Class1=0 to represent it instead, because Class1 is gated by the + # Coverage definition. Use Class1=0 for the highest byte savings. + # Going through all options takes too long, pick the biggest class + # = what happens in otlLib.builder.ClassDefBuilder.classes() + biggest_index = max(self.indices, key=lambda i: len(self.ctx.all_class1[i])) + return _classDef_bytes( + self.ctx.all_class1_data, [i for i in self.indices if i != biggest_index] + ) + + @property + def classDef2_bytes(self): + # All Class2 need to be encoded because we can't use Class2=0 + return _classDef_bytes(self.ctx.all_class2_data, self.column_indices) + + +def cluster_pairs_by_class2_coverage_custom_cost( + font: TTFont, + pairs: Pairs, + compression: int = 5, +) -> List[Pairs]: + if not pairs: + # The subtable was actually empty? + return [pairs] + + # Sorted for reproducibility/determinism + all_class1 = sorted(set(pair[0] for pair in pairs)) + all_class2 = sorted(set(pair[1] for pair in pairs)) + + # Use Python's big ints for binary vectors representing each line + lines = [ + sum( + 1 << i if (class1, class2) in pairs else 0 + for i, class2 in enumerate(all_class2) + ) + for class1 in all_class1 + ] + + # Map glyph names to ids and work with ints throughout for ClassDef formats + name_to_id = font.getReverseGlyphMap() + # Each entry in the arrays below is (range_count, min_glyph_id, max_glyph_id) + all_class1_data = [ + _getClassRanges(name_to_id[name] for name in cls) for cls in all_class1 + ] + all_class2_data = [ + _getClassRanges(name_to_id[name] for name in cls) for cls in all_class2 + ] + + format1 = 0 + format2 = 0 + for pair, value in pairs.items(): + format1 |= value[0].getEffectiveFormat() if value[0] else 0 + format2 |= value[1].getEffectiveFormat() if value[1] else 0 + valueFormat1_bytes = bit_count(format1) * 2 + valueFormat2_bytes = bit_count(format2) * 2 + + ctx = ClusteringContext( + lines, + all_class1, + all_class1_data, + all_class2_data, + valueFormat1_bytes, + valueFormat2_bytes, + ) + + cluster_cache: Dict[int, Cluster] = {} + + def make_cluster(indices: int) -> Cluster: + cluster = cluster_cache.get(indices, None) + if cluster is not None: + return cluster + cluster = Cluster(ctx, indices) + cluster_cache[indices] = cluster + return cluster + + def merge(cluster: Cluster, other: Cluster) -> Cluster: + return make_cluster(cluster.indices_bitmask | other.indices_bitmask) + + # Agglomerative clustering by hand, checking the cost gain of the new + # cluster against the previously separate clusters + # Start with 1 cluster per line + # cluster = set of lines = new subtable + clusters = [make_cluster(1 << i) for i in range(len(lines))] + + # Cost of 1 cluster with everything + # `(1 << len) - 1` gives a bitmask full of 1's of length `len` + cost_before_splitting = make_cluster((1 << len(lines)) - 1).cost + log.debug(f" len(clusters) = {len(clusters)}") + + while len(clusters) > 1: + lowest_cost_change = None + best_cluster_index = None + best_other_index = None + best_merged = None + for i, cluster in enumerate(clusters): + for j, other in enumerate(clusters[i + 1 :]): + merged = merge(cluster, other) + cost_change = merged.cost - cluster.cost - other.cost + if lowest_cost_change is None or cost_change < lowest_cost_change: + lowest_cost_change = cost_change + best_cluster_index = i + best_other_index = i + 1 + j + best_merged = merged + assert lowest_cost_change is not None + assert best_cluster_index is not None + assert best_other_index is not None + assert best_merged is not None + + # If the best merge we found is still taking down the file size, then + # there's no question: we must do it, because it's beneficial in both + # ways (lower file size and lower number of subtables). However, if the + # best merge we found is not reducing file size anymore, then we need to + # look at the other stop criteria = the compression factor. + if lowest_cost_change > 0: + # Stop critera: check whether we should keep merging. + # Compute size reduction brought by splitting + cost_after_splitting = sum(c.cost for c in clusters) + # size_reduction so that after = before * (1 - size_reduction) + # E.g. before = 1000, after = 800, 1 - 800/1000 = 0.2 + size_reduction = 1 - cost_after_splitting / cost_before_splitting + + # Force more merging by taking into account the compression number. + # Target behaviour: compression number = 1 to 9, default 5 like gzip + # - 1 = accept to add 1 subtable to reduce size by 50% + # - 5 = accept to add 5 subtables to reduce size by 50% + # See https://github.com/harfbuzz/packtab/blob/master/Lib/packTab/__init__.py#L690-L691 + # Given the size reduction we have achieved so far, compute how many + # new subtables are acceptable. + max_new_subtables = -log2(1 - size_reduction) * compression + log.debug( + f" len(clusters) = {len(clusters):3d} size_reduction={size_reduction:5.2f} max_new_subtables={max_new_subtables}", + ) + if compression == 9: + # Override level 9 to mean: create any number of subtables + max_new_subtables = len(clusters) + + # If we have managed to take the number of new subtables below the + # threshold, then we can stop. + if len(clusters) <= max_new_subtables + 1: + break + + # No reason to stop yet, do the merge and move on to the next. + del clusters[best_other_index] + clusters[best_cluster_index] = best_merged + + # All clusters are final; turn bitmasks back into the "Pairs" format + pairs_by_class1: Dict[Tuple[str, ...], Pairs] = defaultdict(dict) + for pair, values in pairs.items(): + pairs_by_class1[pair[0]][pair] = values + pairs_groups: List[Pairs] = [] + for cluster in clusters: + pairs_group: Pairs = dict() + for i in cluster.indices: + class1 = all_class1[i] + pairs_group.update(pairs_by_class1[class1]) + pairs_groups.append(pairs_group) + return pairs_groups diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/__init__.py new file mode 100644 index 00000000..156cb232 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/__init__.py @@ -0,0 +1 @@ +"""Empty __init__.py file to signal Python this directory is a package.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/areaPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/areaPen.py new file mode 100644 index 00000000..004bb06b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/areaPen.py @@ -0,0 +1,52 @@ +"""Calculate the area of a glyph.""" + +from fontTools.pens.basePen import BasePen + + +__all__ = ["AreaPen"] + + +class AreaPen(BasePen): + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) + self.value = 0 + + def _moveTo(self, p0): + self._p0 = self._startPoint = p0 + + def _lineTo(self, p1): + x0, y0 = self._p0 + x1, y1 = p1 + self.value -= (x1 - x0) * (y1 + y0) * 0.5 + self._p0 = p1 + + def _qCurveToOne(self, p1, p2): + # https://github.com/Pomax/bezierinfo/issues/44 + p0 = self._p0 + x0, y0 = p0[0], p0[1] + x1, y1 = p1[0] - x0, p1[1] - y0 + x2, y2 = p2[0] - x0, p2[1] - y0 + self.value -= (x2 * y1 - x1 * y2) / 3 + self._lineTo(p2) + self._p0 = p2 + + def _curveToOne(self, p1, p2, p3): + # https://github.com/Pomax/bezierinfo/issues/44 + p0 = self._p0 + x0, y0 = p0[0], p0[1] + x1, y1 = p1[0] - x0, p1[1] - y0 + x2, y2 = p2[0] - x0, p2[1] - y0 + x3, y3 = p3[0] - x0, p3[1] - y0 + self.value -= (x1 * (-y2 - y3) + x2 * (y1 - 2 * y3) + x3 * (y1 + 2 * y2)) * 0.15 + self._lineTo(p3) + self._p0 = p3 + + def _closePath(self): + self._lineTo(self._startPoint) + del self._p0, self._startPoint + + def _endPath(self): + if self._p0 != self._startPoint: + # Area is not defined for open contours. + raise NotImplementedError + del self._p0, self._startPoint diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/basePen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/basePen.py new file mode 100644 index 00000000..ac8abd40 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/basePen.py @@ -0,0 +1,444 @@ +"""fontTools.pens.basePen.py -- Tools and base classes to build pen objects. + +The Pen Protocol + +A Pen is a kind of object that standardizes the way how to "draw" outlines: +it is a middle man between an outline and a drawing. In other words: +it is an abstraction for drawing outlines, making sure that outline objects +don't need to know the details about how and where they're being drawn, and +that drawings don't need to know the details of how outlines are stored. + +The most basic pattern is this:: + + outline.draw(pen) # 'outline' draws itself onto 'pen' + +Pens can be used to render outlines to the screen, but also to construct +new outlines. Eg. an outline object can be both a drawable object (it has a +draw() method) as well as a pen itself: you *build* an outline using pen +methods. + +The AbstractPen class defines the Pen protocol. It implements almost +nothing (only no-op closePath() and endPath() methods), but is useful +for documentation purposes. Subclassing it basically tells the reader: +"this class implements the Pen protocol.". An examples of an AbstractPen +subclass is :py:class:`fontTools.pens.transformPen.TransformPen`. + +The BasePen class is a base implementation useful for pens that actually +draw (for example a pen renders outlines using a native graphics engine). +BasePen contains a lot of base functionality, making it very easy to build +a pen that fully conforms to the pen protocol. Note that if you subclass +BasePen, you *don't* override moveTo(), lineTo(), etc., but _moveTo(), +_lineTo(), etc. See the BasePen doc string for details. Examples of +BasePen subclasses are fontTools.pens.boundsPen.BoundsPen and +fontTools.pens.cocoaPen.CocoaPen. + +Coordinates are usually expressed as (x, y) tuples, but generally any +sequence of length 2 will do. +""" + +from typing import Tuple, Dict + +from fontTools.misc.loggingTools import LogMixin +from fontTools.misc.transform import DecomposedTransform + +__all__ = [ + "AbstractPen", + "NullPen", + "BasePen", + "PenError", + "decomposeSuperBezierSegment", + "decomposeQuadraticSegment", +] + + +class PenError(Exception): + """Represents an error during penning.""" + + +class OpenContourError(PenError): + pass + + +class AbstractPen: + def moveTo(self, pt: Tuple[float, float]) -> None: + """Begin a new sub path, set the current point to 'pt'. You must + end each sub path with a call to pen.closePath() or pen.endPath(). + """ + raise NotImplementedError + + def lineTo(self, pt: Tuple[float, float]) -> None: + """Draw a straight line from the current point to 'pt'.""" + raise NotImplementedError + + def curveTo(self, *points: Tuple[float, float]) -> None: + """Draw a cubic bezier with an arbitrary number of control points. + + The last point specified is on-curve, all others are off-curve + (control) points. If the number of control points is > 2, the + segment is split into multiple bezier segments. This works + like this: + + Let n be the number of control points (which is the number of + arguments to this call minus 1). If n==2, a plain vanilla cubic + bezier is drawn. If n==1, we fall back to a quadratic segment and + if n==0 we draw a straight line. It gets interesting when n>2: + n-1 PostScript-style cubic segments will be drawn as if it were + one curve. See decomposeSuperBezierSegment(). + + The conversion algorithm used for n>2 is inspired by NURB + splines, and is conceptually equivalent to the TrueType "implied + points" principle. See also decomposeQuadraticSegment(). + """ + raise NotImplementedError + + def qCurveTo(self, *points: Tuple[float, float]) -> None: + """Draw a whole string of quadratic curve segments. + + The last point specified is on-curve, all others are off-curve + points. + + This method implements TrueType-style curves, breaking up curves + using 'implied points': between each two consequtive off-curve points, + there is one implied point exactly in the middle between them. See + also decomposeQuadraticSegment(). + + The last argument (normally the on-curve point) may be None. + This is to support contours that have NO on-curve points (a rarely + seen feature of TrueType outlines). + """ + raise NotImplementedError + + def closePath(self) -> None: + """Close the current sub path. You must call either pen.closePath() + or pen.endPath() after each sub path. + """ + pass + + def endPath(self) -> None: + """End the current sub path, but don't close it. You must call + either pen.closePath() or pen.endPath() after each sub path. + """ + pass + + def addComponent( + self, + glyphName: str, + transformation: Tuple[float, float, float, float, float, float], + ) -> None: + """Add a sub glyph. The 'transformation' argument must be a 6-tuple + containing an affine transformation, or a Transform object from the + fontTools.misc.transform module. More precisely: it should be a + sequence containing 6 numbers. + """ + raise NotImplementedError + + def addVarComponent( + self, + glyphName: str, + transformation: DecomposedTransform, + location: Dict[str, float], + ) -> None: + """Add a VarComponent sub glyph. The 'transformation' argument + must be a DecomposedTransform from the fontTools.misc.transform module, + and the 'location' argument must be a dictionary mapping axis tags + to their locations. + """ + # GlyphSet decomposes for us + raise AttributeError + + +class NullPen(AbstractPen): + + """A pen that does nothing.""" + + def moveTo(self, pt): + pass + + def lineTo(self, pt): + pass + + def curveTo(self, *points): + pass + + def qCurveTo(self, *points): + pass + + def closePath(self): + pass + + def endPath(self): + pass + + def addComponent(self, glyphName, transformation): + pass + + def addVarComponent(self, glyphName, transformation, location): + pass + + +class LoggingPen(LogMixin, AbstractPen): + """A pen with a ``log`` property (see fontTools.misc.loggingTools.LogMixin)""" + + pass + + +class MissingComponentError(KeyError): + """Indicates a component pointing to a non-existent glyph in the glyphset.""" + + +class DecomposingPen(LoggingPen): + + """Implements a 'addComponent' method that decomposes components + (i.e. draws them onto self as simple contours). + It can also be used as a mixin class (e.g. see ContourRecordingPen). + + You must override moveTo, lineTo, curveTo and qCurveTo. You may + additionally override closePath, endPath and addComponent. + + By default a warning message is logged when a base glyph is missing; + set the class variable ``skipMissingComponents`` to False if you want + to raise a :class:`MissingComponentError` exception. + """ + + skipMissingComponents = True + + def __init__(self, glyphSet): + """Takes a single 'glyphSet' argument (dict), in which the glyphs + that are referenced as components are looked up by their name. + """ + super(DecomposingPen, self).__init__() + self.glyphSet = glyphSet + + def addComponent(self, glyphName, transformation): + """Transform the points of the base glyph and draw it onto self.""" + from fontTools.pens.transformPen import TransformPen + + try: + glyph = self.glyphSet[glyphName] + except KeyError: + if not self.skipMissingComponents: + raise MissingComponentError(glyphName) + self.log.warning("glyph '%s' is missing from glyphSet; skipped" % glyphName) + else: + tPen = TransformPen(self, transformation) + glyph.draw(tPen) + + def addVarComponent(self, glyphName, transformation, location): + # GlyphSet decomposes for us + raise AttributeError + + +class BasePen(DecomposingPen): + + """Base class for drawing pens. You must override _moveTo, _lineTo and + _curveToOne. You may additionally override _closePath, _endPath, + addComponent, addVarComponent, and/or _qCurveToOne. You should not + override any other methods. + """ + + def __init__(self, glyphSet=None): + super(BasePen, self).__init__(glyphSet) + self.__currentPoint = None + + # must override + + def _moveTo(self, pt): + raise NotImplementedError + + def _lineTo(self, pt): + raise NotImplementedError + + def _curveToOne(self, pt1, pt2, pt3): + raise NotImplementedError + + # may override + + def _closePath(self): + pass + + def _endPath(self): + pass + + def _qCurveToOne(self, pt1, pt2): + """This method implements the basic quadratic curve type. The + default implementation delegates the work to the cubic curve + function. Optionally override with a native implementation. + """ + pt0x, pt0y = self.__currentPoint + pt1x, pt1y = pt1 + pt2x, pt2y = pt2 + mid1x = pt0x + 0.66666666666666667 * (pt1x - pt0x) + mid1y = pt0y + 0.66666666666666667 * (pt1y - pt0y) + mid2x = pt2x + 0.66666666666666667 * (pt1x - pt2x) + mid2y = pt2y + 0.66666666666666667 * (pt1y - pt2y) + self._curveToOne((mid1x, mid1y), (mid2x, mid2y), pt2) + + # don't override + + def _getCurrentPoint(self): + """Return the current point. This is not part of the public + interface, yet is useful for subclasses. + """ + return self.__currentPoint + + def closePath(self): + self._closePath() + self.__currentPoint = None + + def endPath(self): + self._endPath() + self.__currentPoint = None + + def moveTo(self, pt): + self._moveTo(pt) + self.__currentPoint = pt + + def lineTo(self, pt): + self._lineTo(pt) + self.__currentPoint = pt + + def curveTo(self, *points): + n = len(points) - 1 # 'n' is the number of control points + assert n >= 0 + if n == 2: + # The common case, we have exactly two BCP's, so this is a standard + # cubic bezier. Even though decomposeSuperBezierSegment() handles + # this case just fine, we special-case it anyway since it's so + # common. + self._curveToOne(*points) + self.__currentPoint = points[-1] + elif n > 2: + # n is the number of control points; split curve into n-1 cubic + # bezier segments. The algorithm used here is inspired by NURB + # splines and the TrueType "implied point" principle, and ensures + # the smoothest possible connection between two curve segments, + # with no disruption in the curvature. It is practical since it + # allows one to construct multiple bezier segments with a much + # smaller amount of points. + _curveToOne = self._curveToOne + for pt1, pt2, pt3 in decomposeSuperBezierSegment(points): + _curveToOne(pt1, pt2, pt3) + self.__currentPoint = pt3 + elif n == 1: + self.qCurveTo(*points) + elif n == 0: + self.lineTo(points[0]) + else: + raise AssertionError("can't get there from here") + + def qCurveTo(self, *points): + n = len(points) - 1 # 'n' is the number of control points + assert n >= 0 + if points[-1] is None: + # Special case for TrueType quadratics: it is possible to + # define a contour with NO on-curve points. BasePen supports + # this by allowing the final argument (the expected on-curve + # point) to be None. We simulate the feature by making the implied + # on-curve point between the last and the first off-curve points + # explicit. + x, y = points[-2] # last off-curve point + nx, ny = points[0] # first off-curve point + impliedStartPoint = (0.5 * (x + nx), 0.5 * (y + ny)) + self.__currentPoint = impliedStartPoint + self._moveTo(impliedStartPoint) + points = points[:-1] + (impliedStartPoint,) + if n > 0: + # Split the string of points into discrete quadratic curve + # segments. Between any two consecutive off-curve points + # there's an implied on-curve point exactly in the middle. + # This is where the segment splits. + _qCurveToOne = self._qCurveToOne + for pt1, pt2 in decomposeQuadraticSegment(points): + _qCurveToOne(pt1, pt2) + self.__currentPoint = pt2 + else: + self.lineTo(points[0]) + + +def decomposeSuperBezierSegment(points): + """Split the SuperBezier described by 'points' into a list of regular + bezier segments. The 'points' argument must be a sequence with length + 3 or greater, containing (x, y) coordinates. The last point is the + destination on-curve point, the rest of the points are off-curve points. + The start point should not be supplied. + + This function returns a list of (pt1, pt2, pt3) tuples, which each + specify a regular curveto-style bezier segment. + """ + n = len(points) - 1 + assert n > 1 + bezierSegments = [] + pt1, pt2, pt3 = points[0], None, None + for i in range(2, n + 1): + # calculate points in between control points. + nDivisions = min(i, 3, n - i + 2) + for j in range(1, nDivisions): + factor = j / nDivisions + temp1 = points[i - 1] + temp2 = points[i - 2] + temp = ( + temp2[0] + factor * (temp1[0] - temp2[0]), + temp2[1] + factor * (temp1[1] - temp2[1]), + ) + if pt2 is None: + pt2 = temp + else: + pt3 = (0.5 * (pt2[0] + temp[0]), 0.5 * (pt2[1] + temp[1])) + bezierSegments.append((pt1, pt2, pt3)) + pt1, pt2, pt3 = temp, None, None + bezierSegments.append((pt1, points[-2], points[-1])) + return bezierSegments + + +def decomposeQuadraticSegment(points): + """Split the quadratic curve segment described by 'points' into a list + of "atomic" quadratic segments. The 'points' argument must be a sequence + with length 2 or greater, containing (x, y) coordinates. The last point + is the destination on-curve point, the rest of the points are off-curve + points. The start point should not be supplied. + + This function returns a list of (pt1, pt2) tuples, which each specify a + plain quadratic bezier segment. + """ + n = len(points) - 1 + assert n > 0 + quadSegments = [] + for i in range(n - 1): + x, y = points[i] + nx, ny = points[i + 1] + impliedPt = (0.5 * (x + nx), 0.5 * (y + ny)) + quadSegments.append((points[i], impliedPt)) + quadSegments.append((points[-2], points[-1])) + return quadSegments + + +class _TestPen(BasePen): + """Test class that prints PostScript to stdout.""" + + def _moveTo(self, pt): + print("%s %s moveto" % (pt[0], pt[1])) + + def _lineTo(self, pt): + print("%s %s lineto" % (pt[0], pt[1])) + + def _curveToOne(self, bcp1, bcp2, pt): + print( + "%s %s %s %s %s %s curveto" + % (bcp1[0], bcp1[1], bcp2[0], bcp2[1], pt[0], pt[1]) + ) + + def _closePath(self): + print("closepath") + + +if __name__ == "__main__": + pen = _TestPen(None) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0)) + pen.closePath() + + pen = _TestPen(None) + # testing the "no on-curve point" scenario + pen.qCurveTo((0, 0), (0, 100), (100, 100), (100, 0), None) + pen.closePath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/boundsPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/boundsPen.py new file mode 100644 index 00000000..d833cc89 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/boundsPen.py @@ -0,0 +1,100 @@ +from fontTools.misc.arrayTools import updateBounds, pointInRect, unionRect +from fontTools.misc.bezierTools import calcCubicBounds, calcQuadraticBounds +from fontTools.pens.basePen import BasePen + + +__all__ = ["BoundsPen", "ControlBoundsPen"] + + +class ControlBoundsPen(BasePen): + + """Pen to calculate the "control bounds" of a shape. This is the + bounding box of all control points, so may be larger than the + actual bounding box if there are curves that don't have points + on their extremes. + + When the shape has been drawn, the bounds are available as the + ``bounds`` attribute of the pen object. It's a 4-tuple:: + + (xMin, yMin, xMax, yMax). + + If ``ignoreSinglePoints`` is True, single points are ignored. + """ + + def __init__(self, glyphSet, ignoreSinglePoints=False): + BasePen.__init__(self, glyphSet) + self.ignoreSinglePoints = ignoreSinglePoints + self.init() + + def init(self): + self.bounds = None + self._start = None + + def _moveTo(self, pt): + self._start = pt + if not self.ignoreSinglePoints: + self._addMoveTo() + + def _addMoveTo(self): + if self._start is None: + return + bounds = self.bounds + if bounds: + self.bounds = updateBounds(bounds, self._start) + else: + x, y = self._start + self.bounds = (x, y, x, y) + self._start = None + + def _lineTo(self, pt): + self._addMoveTo() + self.bounds = updateBounds(self.bounds, pt) + + def _curveToOne(self, bcp1, bcp2, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, bcp1) + bounds = updateBounds(bounds, bcp2) + bounds = updateBounds(bounds, pt) + self.bounds = bounds + + def _qCurveToOne(self, bcp, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, bcp) + bounds = updateBounds(bounds, pt) + self.bounds = bounds + + +class BoundsPen(ControlBoundsPen): + + """Pen to calculate the bounds of a shape. It calculates the + correct bounds even when the shape contains curves that don't + have points on their extremes. This is somewhat slower to compute + than the "control bounds". + + When the shape has been drawn, the bounds are available as the + ``bounds`` attribute of the pen object. It's a 4-tuple:: + + (xMin, yMin, xMax, yMax) + """ + + def _curveToOne(self, bcp1, bcp2, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, pt) + if not pointInRect(bcp1, bounds) or not pointInRect(bcp2, bounds): + bounds = unionRect( + bounds, calcCubicBounds(self._getCurrentPoint(), bcp1, bcp2, pt) + ) + self.bounds = bounds + + def _qCurveToOne(self, bcp, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, pt) + if not pointInRect(bcp, bounds): + bounds = unionRect( + bounds, calcQuadraticBounds(self._getCurrentPoint(), bcp, pt) + ) + self.bounds = bounds diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cairoPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cairoPen.py new file mode 100644 index 00000000..9cd5da91 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cairoPen.py @@ -0,0 +1,26 @@ +"""Pen to draw to a Cairo graphics library context.""" + +from fontTools.pens.basePen import BasePen + + +__all__ = ["CairoPen"] + + +class CairoPen(BasePen): + """Pen to draw to a Cairo graphics library context.""" + + def __init__(self, glyphSet, context): + BasePen.__init__(self, glyphSet) + self.context = context + + def _moveTo(self, p): + self.context.move_to(*p) + + def _lineTo(self, p): + self.context.line_to(*p) + + def _curveToOne(self, p1, p2, p3): + self.context.curve_to(*p1, *p2, *p3) + + def _closePath(self): + self.context.close_path() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cocoaPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cocoaPen.py new file mode 100644 index 00000000..5369c309 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cocoaPen.py @@ -0,0 +1,26 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["CocoaPen"] + + +class CocoaPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + from AppKit import NSBezierPath + + path = NSBezierPath.bezierPath() + self.path = path + + def _moveTo(self, p): + self.path.moveToPoint_(p) + + def _lineTo(self, p): + self.path.lineToPoint_(p) + + def _curveToOne(self, p1, p2, p3): + self.path.curveToPoint_controlPoint1_controlPoint2_(p3, p1, p2) + + def _closePath(self): + self.path.closePath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cu2quPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cu2quPen.py new file mode 100644 index 00000000..5730b325 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/cu2quPen.py @@ -0,0 +1,325 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import operator +from fontTools.cu2qu import curve_to_quadratic, curves_to_quadratic +from fontTools.pens.basePen import decomposeSuperBezierSegment +from fontTools.pens.filterPen import FilterPen +from fontTools.pens.reverseContourPen import ReverseContourPen +from fontTools.pens.pointPen import BasePointToSegmentPen +from fontTools.pens.pointPen import ReverseContourPointPen + + +class Cu2QuPen(FilterPen): + """A filter pen to convert cubic bezier curves to quadratic b-splines + using the FontTools SegmentPen protocol. + + Args: + + other_pen: another SegmentPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + stats: a dictionary counting the point numbers of quadratic segments. + all_quadratic: if True (default), only quadratic b-splines are generated. + if False, quadratic curves or cubic curves are generated depending + on which one is more economical. + """ + + def __init__( + self, + other_pen, + max_err, + reverse_direction=False, + stats=None, + all_quadratic=True, + ): + if reverse_direction: + other_pen = ReverseContourPen(other_pen) + super().__init__(other_pen) + self.max_err = max_err + self.stats = stats + self.all_quadratic = all_quadratic + + def _convert_curve(self, pt1, pt2, pt3): + curve = (self.current_pt, pt1, pt2, pt3) + result = curve_to_quadratic(curve, self.max_err, self.all_quadratic) + if self.stats is not None: + n = str(len(result) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + if self.all_quadratic: + self.qCurveTo(*result[1:]) + else: + if len(result) == 3: + self.qCurveTo(*result[1:]) + else: + assert len(result) == 4 + super().curveTo(*result[1:]) + + def curveTo(self, *points): + n = len(points) + if n == 3: + # this is the most common case, so we special-case it + self._convert_curve(*points) + elif n > 3: + for segment in decomposeSuperBezierSegment(points): + self._convert_curve(*segment) + else: + self.qCurveTo(*points) + + +class Cu2QuPointPen(BasePointToSegmentPen): + """A filter pen to convert cubic bezier curves to quadratic b-splines + using the FontTools PointPen protocol. + + Args: + other_point_pen: another PointPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: reverse the winding direction of all contours. + stats: a dictionary counting the point numbers of quadratic segments. + all_quadratic: if True (default), only quadratic b-splines are generated. + if False, quadratic curves or cubic curves are generated depending + on which one is more economical. + """ + + __points_required = { + "move": (1, operator.eq), + "line": (1, operator.eq), + "qcurve": (2, operator.ge), + "curve": (3, operator.eq), + } + + def __init__( + self, + other_point_pen, + max_err, + reverse_direction=False, + stats=None, + all_quadratic=True, + ): + BasePointToSegmentPen.__init__(self) + if reverse_direction: + self.pen = ReverseContourPointPen(other_point_pen) + else: + self.pen = other_point_pen + self.max_err = max_err + self.stats = stats + self.all_quadratic = all_quadratic + + def _flushContour(self, segments): + assert len(segments) >= 1 + closed = segments[0][0] != "move" + new_segments = [] + prev_points = segments[-1][1] + prev_on_curve = prev_points[-1][0] + for segment_type, points in segments: + if segment_type == "curve": + for sub_points in self._split_super_bezier_segments(points): + on_curve, smooth, name, kwargs = sub_points[-1] + bcp1, bcp2 = sub_points[0][0], sub_points[1][0] + cubic = [prev_on_curve, bcp1, bcp2, on_curve] + quad = curve_to_quadratic(cubic, self.max_err, self.all_quadratic) + if self.stats is not None: + n = str(len(quad) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + new_points = [(pt, False, None, {}) for pt in quad[1:-1]] + new_points.append((on_curve, smooth, name, kwargs)) + if self.all_quadratic or len(new_points) == 2: + new_segments.append(["qcurve", new_points]) + else: + new_segments.append(["curve", new_points]) + prev_on_curve = sub_points[-1][0] + else: + new_segments.append([segment_type, points]) + prev_on_curve = points[-1][0] + if closed: + # the BasePointToSegmentPen.endPath method that calls _flushContour + # rotates the point list of closed contours so that they end with + # the first on-curve point. We restore the original starting point. + new_segments = new_segments[-1:] + new_segments[:-1] + self._drawPoints(new_segments) + + def _split_super_bezier_segments(self, points): + sub_segments = [] + # n is the number of control points + n = len(points) - 1 + if n == 2: + # a simple bezier curve segment + sub_segments.append(points) + elif n > 2: + # a "super" bezier; decompose it + on_curve, smooth, name, kwargs = points[-1] + num_sub_segments = n - 1 + for i, sub_points in enumerate( + decomposeSuperBezierSegment([pt for pt, _, _, _ in points]) + ): + new_segment = [] + for point in sub_points[:-1]: + new_segment.append((point, False, None, {})) + if i == (num_sub_segments - 1): + # the last on-curve keeps its original attributes + new_segment.append((on_curve, smooth, name, kwargs)) + else: + # on-curves of sub-segments are always "smooth" + new_segment.append((sub_points[-1], True, None, {})) + sub_segments.append(new_segment) + else: + raise AssertionError("expected 2 control points, found: %d" % n) + return sub_segments + + def _drawPoints(self, segments): + pen = self.pen + pen.beginPath() + last_offcurves = [] + points_required = self.__points_required + for i, (segment_type, points) in enumerate(segments): + if segment_type in points_required: + n, op = points_required[segment_type] + assert op(len(points), n), ( + f"illegal {segment_type!r} segment point count: " + f"expected {n}, got {len(points)}" + ) + offcurves = points[:-1] + if i == 0: + # any off-curve points preceding the first on-curve + # will be appended at the end of the contour + last_offcurves = offcurves + else: + for pt, smooth, name, kwargs in offcurves: + pen.addPoint(pt, None, smooth, name, **kwargs) + pt, smooth, name, kwargs = points[-1] + if pt is None: + assert segment_type == "qcurve" + # special quadratic contour with no on-curve points: + # we need to skip the "None" point. See also the Pen + # protocol's qCurveTo() method and fontTools.pens.basePen + pass + else: + pen.addPoint(pt, segment_type, smooth, name, **kwargs) + else: + raise AssertionError("unexpected segment type: %r" % segment_type) + for pt, smooth, name, kwargs in last_offcurves: + pen.addPoint(pt, None, smooth, name, **kwargs) + pen.endPath() + + def addComponent(self, baseGlyphName, transformation): + assert self.currentPath is None + self.pen.addComponent(baseGlyphName, transformation) + + +class Cu2QuMultiPen: + """A filter multi-pen to convert cubic bezier curves to quadratic b-splines + in a interpolation-compatible manner, using the FontTools SegmentPen protocol. + + Args: + + other_pens: list of SegmentPens used to draw the transformed outlines. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + + This pen does not follow the normal SegmentPen protocol. Instead, its + moveTo/lineTo/qCurveTo/curveTo methods take a list of tuples that are + arguments that would normally be passed to a SegmentPen, one item for + each of the pens in other_pens. + """ + + # TODO Simplify like 3e8ebcdce592fe8a59ca4c3a294cc9724351e1ce + # Remove start_pts and _add_moveTO + + def __init__(self, other_pens, max_err, reverse_direction=False): + if reverse_direction: + other_pens = [ + ReverseContourPen(pen, outputImpliedClosingLine=True) + for pen in other_pens + ] + self.pens = other_pens + self.max_err = max_err + self.start_pts = None + self.current_pts = None + + def _check_contour_is_open(self): + if self.current_pts is None: + raise AssertionError("moveTo is required") + + def _check_contour_is_closed(self): + if self.current_pts is not None: + raise AssertionError("closePath or endPath is required") + + def _add_moveTo(self): + if self.start_pts is not None: + for pt, pen in zip(self.start_pts, self.pens): + pen.moveTo(*pt) + self.start_pts = None + + def moveTo(self, pts): + self._check_contour_is_closed() + self.start_pts = self.current_pts = pts + self._add_moveTo() + + def lineTo(self, pts): + self._check_contour_is_open() + self._add_moveTo() + for pt, pen in zip(pts, self.pens): + pen.lineTo(*pt) + self.current_pts = pts + + def qCurveTo(self, pointsList): + self._check_contour_is_open() + if len(pointsList[0]) == 1: + self.lineTo([(points[0],) for points in pointsList]) + return + self._add_moveTo() + current_pts = [] + for points, pen in zip(pointsList, self.pens): + pen.qCurveTo(*points) + current_pts.append((points[-1],)) + self.current_pts = current_pts + + def _curves_to_quadratic(self, pointsList): + curves = [] + for current_pt, points in zip(self.current_pts, pointsList): + curves.append(current_pt + points) + quadratics = curves_to_quadratic(curves, [self.max_err] * len(curves)) + pointsList = [] + for quadratic in quadratics: + pointsList.append(quadratic[1:]) + self.qCurveTo(pointsList) + + def curveTo(self, pointsList): + self._check_contour_is_open() + self._curves_to_quadratic(pointsList) + + def closePath(self): + self._check_contour_is_open() + if self.start_pts is None: + for pen in self.pens: + pen.closePath() + self.current_pts = self.start_pts = None + + def endPath(self): + self._check_contour_is_open() + if self.start_pts is None: + for pen in self.pens: + pen.endPath() + self.current_pts = self.start_pts = None + + def addComponent(self, glyphName, transformations): + self._check_contour_is_closed() + for trans, pen in zip(transformations, self.pens): + pen.addComponent(glyphName, trans) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/explicitClosingLinePen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/explicitClosingLinePen.py new file mode 100644 index 00000000..e3c9c943 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/explicitClosingLinePen.py @@ -0,0 +1,101 @@ +from fontTools.pens.filterPen import ContourFilterPen + + +class ExplicitClosingLinePen(ContourFilterPen): + """A filter pen that adds an explicit lineTo to the first point of each closed + contour if the end point of the last segment is not already the same as the first point. + Otherwise, it passes the contour through unchanged. + + >>> from pprint import pprint + >>> from fontTools.pens.recordingPen import RecordingPen + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.lineTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (100, 100)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (100, 100))), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (100, 100)) + >>> pen.lineTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (100, 100))), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (0, 0))), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.closePath() + >>> pprint(rec.value) + [('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.endPath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('endPath', ())] + """ + + def filterContour(self, contour): + if ( + not contour + or contour[0][0] != "moveTo" + or contour[-1][0] != "closePath" + or len(contour) < 3 + ): + return + movePt = contour[0][1][0] + lastSeg = contour[-2][1] + if lastSeg and movePt != lastSeg[-1]: + contour[-1:] = [("lineTo", (movePt,)), ("closePath", ())] diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/filterPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/filterPen.py new file mode 100644 index 00000000..81423109 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/filterPen.py @@ -0,0 +1,164 @@ +from fontTools.pens.basePen import AbstractPen +from fontTools.pens.pointPen import AbstractPointPen +from fontTools.pens.recordingPen import RecordingPen + + +class _PassThruComponentsMixin(object): + def addComponent(self, glyphName, transformation, **kwargs): + self._outPen.addComponent(glyphName, transformation, **kwargs) + + +class FilterPen(_PassThruComponentsMixin, AbstractPen): + + """Base class for pens that apply some transformation to the coordinates + they receive and pass them to another pen. + + You can override any of its methods. The default implementation does + nothing, but passes the commands unmodified to the other pen. + + >>> from fontTools.pens.recordingPen import RecordingPen + >>> rec = RecordingPen() + >>> pen = FilterPen(rec) + >>> v = iter(rec.value) + + >>> pen.moveTo((0, 0)) + >>> next(v) + ('moveTo', ((0, 0),)) + + >>> pen.lineTo((1, 1)) + >>> next(v) + ('lineTo', ((1, 1),)) + + >>> pen.curveTo((2, 2), (3, 3), (4, 4)) + >>> next(v) + ('curveTo', ((2, 2), (3, 3), (4, 4))) + + >>> pen.qCurveTo((5, 5), (6, 6), (7, 7), (8, 8)) + >>> next(v) + ('qCurveTo', ((5, 5), (6, 6), (7, 7), (8, 8))) + + >>> pen.closePath() + >>> next(v) + ('closePath', ()) + + >>> pen.moveTo((9, 9)) + >>> next(v) + ('moveTo', ((9, 9),)) + + >>> pen.endPath() + >>> next(v) + ('endPath', ()) + + >>> pen.addComponent('foo', (1, 0, 0, 1, 0, 0)) + >>> next(v) + ('addComponent', ('foo', (1, 0, 0, 1, 0, 0))) + """ + + def __init__(self, outPen): + self._outPen = outPen + self.current_pt = None + + def moveTo(self, pt): + self._outPen.moveTo(pt) + self.current_pt = pt + + def lineTo(self, pt): + self._outPen.lineTo(pt) + self.current_pt = pt + + def curveTo(self, *points): + self._outPen.curveTo(*points) + self.current_pt = points[-1] + + def qCurveTo(self, *points): + self._outPen.qCurveTo(*points) + self.current_pt = points[-1] + + def closePath(self): + self._outPen.closePath() + self.current_pt = None + + def endPath(self): + self._outPen.endPath() + self.current_pt = None + + +class ContourFilterPen(_PassThruComponentsMixin, RecordingPen): + """A "buffered" filter pen that accumulates contour data, passes + it through a ``filterContour`` method when the contour is closed or ended, + and finally draws the result with the output pen. + + Components are passed through unchanged. + """ + + def __init__(self, outPen): + super(ContourFilterPen, self).__init__() + self._outPen = outPen + + def closePath(self): + super(ContourFilterPen, self).closePath() + self._flushContour() + + def endPath(self): + super(ContourFilterPen, self).endPath() + self._flushContour() + + def _flushContour(self): + result = self.filterContour(self.value) + if result is not None: + self.value = result + self.replay(self._outPen) + self.value = [] + + def filterContour(self, contour): + """Subclasses must override this to perform the filtering. + + The contour is a list of pen (operator, operands) tuples. + Operators are strings corresponding to the AbstractPen methods: + "moveTo", "lineTo", "curveTo", "qCurveTo", "closePath" and + "endPath". The operands are the positional arguments that are + passed to each method. + + If the method doesn't return a value (i.e. returns None), it's + assumed that the argument was modified in-place. + Otherwise, the return value is drawn with the output pen. + """ + return # or return contour + + +class FilterPointPen(_PassThruComponentsMixin, AbstractPointPen): + """Baseclass for point pens that apply some transformation to the + coordinates they receive and pass them to another point pen. + + You can override any of its methods. The default implementation does + nothing, but passes the commands unmodified to the other pen. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = FilterPointPen(rec) + >>> v = iter(rec.value) + >>> pen.beginPath(identifier="abc") + >>> next(v) + ('beginPath', (), {'identifier': 'abc'}) + >>> pen.addPoint((1, 2), "line", False) + >>> next(v) + ('addPoint', ((1, 2), 'line', False, None), {}) + >>> pen.addComponent("a", (2, 0, 0, 2, 10, -10), identifier="0001") + >>> next(v) + ('addComponent', ('a', (2, 0, 0, 2, 10, -10)), {'identifier': '0001'}) + >>> pen.endPath() + >>> next(v) + ('endPath', (), {}) + """ + + def __init__(self, outPointPen): + self._outPen = outPointPen + + def beginPath(self, **kwargs): + self._outPen.beginPath(**kwargs) + + def endPath(self): + self._outPen.endPath() + + def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs): + self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/freetypePen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/freetypePen.py new file mode 100644 index 00000000..870776bc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/freetypePen.py @@ -0,0 +1,458 @@ +# -*- coding: utf-8 -*- + +"""Pen to rasterize paths with FreeType.""" + +__all__ = ["FreeTypePen"] + +import os +import ctypes +import platform +import subprocess +import collections +import math + +import freetype +from freetype.raw import FT_Outline_Get_Bitmap, FT_Outline_Get_BBox, FT_Outline_Get_CBox +from freetype.ft_types import FT_Pos +from freetype.ft_structs import FT_Vector, FT_BBox, FT_Bitmap, FT_Outline +from freetype.ft_enums import ( + FT_OUTLINE_NONE, + FT_OUTLINE_EVEN_ODD_FILL, + FT_PIXEL_MODE_GRAY, + FT_CURVE_TAG_ON, + FT_CURVE_TAG_CONIC, + FT_CURVE_TAG_CUBIC, +) +from freetype.ft_errors import FT_Exception + +from fontTools.pens.basePen import BasePen, PenError +from fontTools.misc.roundTools import otRound +from fontTools.misc.transform import Transform + +Contour = collections.namedtuple("Contour", ("points", "tags")) + + +class FreeTypePen(BasePen): + """Pen to rasterize paths with FreeType. Requires `freetype-py` module. + + Constructs ``FT_Outline`` from the paths, and renders it within a bitmap + buffer. + + For ``array()`` and ``show()``, `numpy` and `matplotlib` must be installed. + For ``image()``, `Pillow` is required. Each module is lazily loaded when the + corresponding method is called. + + Args: + glyphSet: a dictionary of drawable glyph objects keyed by name + used to resolve component references in composite glyphs. + + :Examples: + If `numpy` and `matplotlib` is available, the following code will + show the glyph image of `fi` in a new window:: + + from fontTools.ttLib import TTFont + from fontTools.pens.freetypePen import FreeTypePen + from fontTools.misc.transform import Offset + pen = FreeTypePen(None) + font = TTFont('SourceSansPro-Regular.otf') + glyph = font.getGlyphSet()['fi'] + glyph.draw(pen) + width, ascender, descender = glyph.width, font['OS/2'].usWinAscent, -font['OS/2'].usWinDescent + height = ascender - descender + pen.show(width=width, height=height, transform=Offset(0, -descender)) + + Combining with `uharfbuzz`, you can typeset a chunk of glyphs in a pen:: + + import uharfbuzz as hb + from fontTools.pens.freetypePen import FreeTypePen + from fontTools.pens.transformPen import TransformPen + from fontTools.misc.transform import Offset + + en1, en2, ar, ja = 'Typesetting', 'Jeff', 'صف الحروف', 'たいぷせっと' + for text, font_path, direction, typo_ascender, typo_descender, vhea_ascender, vhea_descender, contain, features in ( + (en1, 'NotoSans-Regular.ttf', 'ltr', 2189, -600, None, None, False, {"kern": True, "liga": True}), + (en2, 'NotoSans-Regular.ttf', 'ltr', 2189, -600, None, None, True, {"kern": True, "liga": True}), + (ar, 'NotoSansArabic-Regular.ttf', 'rtl', 1374, -738, None, None, False, {"kern": True, "liga": True}), + (ja, 'NotoSansJP-Regular.otf', 'ltr', 880, -120, 500, -500, False, {"palt": True, "kern": True}), + (ja, 'NotoSansJP-Regular.otf', 'ttb', 880, -120, 500, -500, False, {"vert": True, "vpal": True, "vkrn": True}) + ): + blob = hb.Blob.from_file_path(font_path) + face = hb.Face(blob) + font = hb.Font(face) + buf = hb.Buffer() + buf.direction = direction + buf.add_str(text) + buf.guess_segment_properties() + hb.shape(font, buf, features) + + x, y = 0, 0 + pen = FreeTypePen(None) + for info, pos in zip(buf.glyph_infos, buf.glyph_positions): + gid = info.codepoint + transformed = TransformPen(pen, Offset(x + pos.x_offset, y + pos.y_offset)) + font.draw_glyph_with_pen(gid, transformed) + x += pos.x_advance + y += pos.y_advance + + offset, width, height = None, None, None + if direction in ('ltr', 'rtl'): + offset = (0, -typo_descender) + width = x + height = typo_ascender - typo_descender + else: + offset = (-vhea_descender, -y) + width = vhea_ascender - vhea_descender + height = -y + pen.show(width=width, height=height, transform=Offset(*offset), contain=contain) + + For Jupyter Notebook, the rendered image will be displayed in a cell if + you replace ``show()`` with ``image()`` in the examples. + """ + + def __init__(self, glyphSet): + BasePen.__init__(self, glyphSet) + self.contours = [] + + def outline(self, transform=None, evenOdd=False): + """Converts the current contours to ``FT_Outline``. + + Args: + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + """ + transform = transform or Transform() + if not hasattr(transform, "transformPoint"): + transform = Transform(*transform) + n_contours = len(self.contours) + n_points = sum((len(contour.points) for contour in self.contours)) + points = [] + for contour in self.contours: + for point in contour.points: + point = transform.transformPoint(point) + points.append( + FT_Vector( + FT_Pos(otRound(point[0] * 64)), FT_Pos(otRound(point[1] * 64)) + ) + ) + tags = [] + for contour in self.contours: + for tag in contour.tags: + tags.append(tag) + contours = [] + contours_sum = 0 + for contour in self.contours: + contours_sum += len(contour.points) + contours.append(contours_sum - 1) + flags = FT_OUTLINE_EVEN_ODD_FILL if evenOdd else FT_OUTLINE_NONE + return FT_Outline( + (ctypes.c_short)(n_contours), + (ctypes.c_short)(n_points), + (FT_Vector * n_points)(*points), + (ctypes.c_ubyte * n_points)(*tags), + (ctypes.c_short * n_contours)(*contours), + (ctypes.c_int)(flags), + ) + + def buffer( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Renders the current contours within a bitmap buffer. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A tuple of ``(buffer, size)``, where ``buffer`` is a ``bytes`` + object of the resulted bitmap and ``size`` is a 2-tuple of its + dimension. + + :Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + :Example: + .. code-block:: + + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> buf, size = pen.buffer(width=500, height=1000) + >> type(buf), len(buf), size + (, 500000, (500, 1000)) + + """ + transform = transform or Transform() + if not hasattr(transform, "transformPoint"): + transform = Transform(*transform) + contain_x, contain_y = contain or width is None, contain or height is None + if contain_x or contain_y: + dx, dy = transform.dx, transform.dy + bbox = self.bbox + p1, p2, p3, p4 = ( + transform.transformPoint((bbox[0], bbox[1])), + transform.transformPoint((bbox[2], bbox[1])), + transform.transformPoint((bbox[0], bbox[3])), + transform.transformPoint((bbox[2], bbox[3])), + ) + px, py = (p1[0], p2[0], p3[0], p4[0]), (p1[1], p2[1], p3[1], p4[1]) + if contain_x: + if width is None: + dx = dx - min(*px) + width = max(*px) - min(*px) + else: + dx = dx - min(min(*px), 0.0) + width = max(width, max(*px) - min(min(*px), 0.0)) + if contain_y: + if height is None: + dy = dy - min(*py) + height = max(*py) - min(*py) + else: + dy = dy - min(min(*py), 0.0) + height = max(height, max(*py) - min(min(*py), 0.0)) + transform = Transform(*transform[:4], dx, dy) + width, height = math.ceil(width), math.ceil(height) + buf = ctypes.create_string_buffer(width * height) + bitmap = FT_Bitmap( + (ctypes.c_int)(height), + (ctypes.c_int)(width), + (ctypes.c_int)(width), + (ctypes.POINTER(ctypes.c_ubyte))(buf), + (ctypes.c_short)(256), + (ctypes.c_ubyte)(FT_PIXEL_MODE_GRAY), + (ctypes.c_char)(0), + (ctypes.c_void_p)(None), + ) + outline = self.outline(transform=transform, evenOdd=evenOdd) + err = FT_Outline_Get_Bitmap( + freetype.get_handle(), ctypes.byref(outline), ctypes.byref(bitmap) + ) + if err != 0: + raise FT_Exception(err) + return buf.raw, (width, height) + + def array( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Returns the rendered contours as a numpy array. Requires `numpy`. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A ``numpy.ndarray`` object with a shape of ``(height, width)``. + Each element takes a value in the range of ``[0.0, 1.0]``. + + :Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + :Example: + .. code-block:: + + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> arr = pen.array(width=500, height=1000) + >> type(a), a.shape + (, (1000, 500)) + """ + import numpy as np + + buf, size = self.buffer( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + return np.frombuffer(buf, "B").reshape((size[1], size[0])) / 255.0 + + def show( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Plots the rendered contours with `pyplot`. Requires `numpy` and + `matplotlib`. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + :Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + :Example: + .. code-block:: + + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> pen.show(width=500, height=1000) + """ + from matplotlib import pyplot as plt + + a = self.array( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + plt.imshow(a, cmap="gray_r", vmin=0, vmax=1) + plt.show() + + def image( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Returns the rendered contours as a PIL image. Requires `Pillow`. + Can be used to display a glyph image in Jupyter Notebook. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A ``PIL.image`` object. The image is filled in black with alpha + channel obtained from the rendered bitmap. + + :Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + :Example: + .. code-block:: + + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> img = pen.image(width=500, height=1000) + >> type(img), img.size + (, (500, 1000)) + """ + from PIL import Image + + buf, size = self.buffer( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + img = Image.new("L", size, 0) + img.putalpha(Image.frombuffer("L", size, buf)) + return img + + @property + def bbox(self): + """Computes the exact bounding box of an outline. + + Returns: + A tuple of ``(xMin, yMin, xMax, yMax)``. + """ + bbox = FT_BBox() + outline = self.outline() + FT_Outline_Get_BBox(ctypes.byref(outline), ctypes.byref(bbox)) + return (bbox.xMin / 64.0, bbox.yMin / 64.0, bbox.xMax / 64.0, bbox.yMax / 64.0) + + @property + def cbox(self): + """Returns an outline's ‘control box’. + + Returns: + A tuple of ``(xMin, yMin, xMax, yMax)``. + """ + cbox = FT_BBox() + outline = self.outline() + FT_Outline_Get_CBox(ctypes.byref(outline), ctypes.byref(cbox)) + return (cbox.xMin / 64.0, cbox.yMin / 64.0, cbox.xMax / 64.0, cbox.yMax / 64.0) + + def _moveTo(self, pt): + contour = Contour([], []) + self.contours.append(contour) + contour.points.append(pt) + contour.tags.append(FT_CURVE_TAG_ON) + + def _lineTo(self, pt): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + contour = self.contours[-1] + contour.points.append(pt) + contour.tags.append(FT_CURVE_TAG_ON) + + def _curveToOne(self, p1, p2, p3): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + t1, t2, t3 = FT_CURVE_TAG_CUBIC, FT_CURVE_TAG_CUBIC, FT_CURVE_TAG_ON + contour = self.contours[-1] + for p, t in ((p1, t1), (p2, t2), (p3, t3)): + contour.points.append(p) + contour.tags.append(t) + + def _qCurveToOne(self, p1, p2): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + t1, t2 = FT_CURVE_TAG_CONIC, FT_CURVE_TAG_ON + contour = self.contours[-1] + for p, t in ((p1, t1), (p2, t2)): + contour.points.append(p) + contour.tags.append(t) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/hashPointPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/hashPointPen.py new file mode 100644 index 00000000..b82468ec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/hashPointPen.py @@ -0,0 +1,75 @@ +# Modified from https://github.com/adobe-type-tools/psautohint/blob/08b346865710ed3c172f1eb581d6ef243b203f99/python/psautohint/ufoFont.py#L800-L838 +import hashlib + +from fontTools.pens.basePen import MissingComponentError +from fontTools.pens.pointPen import AbstractPointPen + + +class HashPointPen(AbstractPointPen): + """ + This pen can be used to check if a glyph's contents (outlines plus + components) have changed. + + Components are added as the original outline plus each composite's + transformation. + + Example: You have some TrueType hinting code for a glyph which you want to + compile. The hinting code specifies a hash value computed with HashPointPen + that was valid for the glyph's outlines at the time the hinting code was + written. Now you can calculate the hash for the glyph's current outlines to + check if the outlines have changed, which would probably make the hinting + code invalid. + + > glyph = ufo[name] + > hash_pen = HashPointPen(glyph.width, ufo) + > glyph.drawPoints(hash_pen) + > ttdata = glyph.lib.get("public.truetype.instructions", None) + > stored_hash = ttdata.get("id", None) # The hash is stored in the "id" key + > if stored_hash is None or stored_hash != hash_pen.hash: + > logger.error(f"Glyph hash mismatch, glyph '{name}' will have no instructions in font.") + > else: + > # The hash values are identical, the outline has not changed. + > # Compile the hinting code ... + > pass + """ + + def __init__(self, glyphWidth=0, glyphSet=None): + self.glyphset = glyphSet + self.data = ["w%s" % round(glyphWidth, 9)] + + @property + def hash(self): + data = "".join(self.data) + if len(data) >= 128: + data = hashlib.sha512(data.encode("ascii")).hexdigest() + return data + + def beginPath(self, identifier=None, **kwargs): + pass + + def endPath(self): + self.data.append("|") + + def addPoint( + self, + pt, + segmentType=None, + smooth=False, + name=None, + identifier=None, + **kwargs, + ): + if segmentType is None: + pt_type = "o" # offcurve + else: + pt_type = segmentType[0] + self.data.append(f"{pt_type}{pt[0]:g}{pt[1]:+g}") + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + tr = "".join([f"{t:+}" for t in transformation]) + self.data.append("[") + try: + self.glyphset[baseGlyphName].drawPoints(self) + except KeyError: + raise MissingComponentError(baseGlyphName) + self.data.append(f"({tr})]") diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.c b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.c new file mode 100644 index 00000000..0786758c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.c @@ -0,0 +1,13727 @@ +/* Generated by Cython 3.0.6 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "fontTools.pens.momentsPen", + "sources": [ + "Lib/fontTools/pens/momentsPen.py" + ] + }, + "module_name": "fontTools.pens.momentsPen" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_6" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x030006F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; // borrowed + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; // we don't yet need to distinguish between versions > 11 + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); // we don't have access to __pyx_empty_bytes here + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__pens__momentsPen +#define __PYX_HAVE_API__fontTools__pens__momentsPen +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const wchar_t *u) +{ + const wchar_t *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#endif +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else // Py < 3.12 + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "Lib/fontTools/pens/momentsPen.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg // no-op + #define __Pyx_Arg_XDECREF_VARARGS(arg) // no-op - arg is borrowed +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg // no-op, __Pyx_Arg_FASTCALL is direct and this needs + #define __Pyx_Arg_XDECREF_FASTCALL(arg) // no-op - arg was returned from array +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif +#endif +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); + +/* PyObjectSetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o, n, NULL) +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value); +#else +#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n) +#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* Py3UpdateBases.proto */ +static PyObject* __Pyx_PEP560_update_bases(PyObject *bases); + +/* CalculateMetaclass.proto */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; // used by FusedFunction for copying defaults + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* SetNameInClass.proto */ +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value)) +#elif CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value)) +#else +#define __Pyx_SetNameInClass(ns, name, value) PyObject_SetItem(ns, name, value) +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectLookupSpecial.proto */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_LookupSpecialNoError(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 0) +#define __Pyx_PyObject_LookupSpecial(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 1) +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error); +#else +#define __Pyx_PyObject_LookupSpecialNoError(o,n) __Pyx_PyObject_GetAttrStrNoError(o,n) +#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n) +#endif + +/* Py3ClassCreate.proto */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, + PyObject *mkw, PyObject *modname, PyObject *doc); +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, + PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.pens.momentsPen" */ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.pens.momentsPen" +extern int __pyx_module_is_main_fontTools__pens__momentsPen; +int __pyx_module_is_main_fontTools__pens__momentsPen = 0; + +/* Implementation of "fontTools.pens.momentsPen" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_AttributeError; +static PyObject *__pyx_builtin_ImportError; +/* #### Code section: string_decls ### */ +static const char __pyx_k_[] = "."; +static const char __pyx_k_x[] = "x"; +static const char __pyx_k_y[] = "y"; +static const char __pyx_k_p0[] = "p0"; +static const char __pyx_k_p1[] = "p1"; +static const char __pyx_k_p2[] = "p2"; +static const char __pyx_k_p3[] = "p3"; +static const char __pyx_k_r0[] = "r0"; +static const char __pyx_k_r1[] = "r1"; +static const char __pyx_k_r2[] = "r2"; +static const char __pyx_k_r3[] = "r3"; +static const char __pyx_k_r4[] = "r4"; +static const char __pyx_k_r5[] = "r5"; +static const char __pyx_k_r6[] = "r6"; +static const char __pyx_k_r7[] = "r7"; +static const char __pyx_k_r8[] = "r8"; +static const char __pyx_k_r9[] = "r9"; +static const char __pyx_k_x0[] = "x0"; +static const char __pyx_k_x1[] = "x1"; +static const char __pyx_k_x2[] = "x2"; +static const char __pyx_k_x3[] = "x3"; +static const char __pyx_k_y0[] = "y0"; +static const char __pyx_k_y1[] = "y1"; +static const char __pyx_k_y2[] = "y2"; +static const char __pyx_k_y3[] = "y3"; +static const char __pyx_k__16[] = "?"; +static const char __pyx_k_all[] = "__all__"; +static const char __pyx_k_doc[] = "__doc__"; +static const char __pyx_k_r10[] = "r10"; +static const char __pyx_k_r11[] = "r11"; +static const char __pyx_k_r12[] = "r12"; +static const char __pyx_k_r13[] = "r13"; +static const char __pyx_k_r14[] = "r14"; +static const char __pyx_k_r15[] = "r15"; +static const char __pyx_k_r16[] = "r16"; +static const char __pyx_k_r17[] = "r17"; +static const char __pyx_k_r18[] = "r18"; +static const char __pyx_k_r19[] = "r19"; +static const char __pyx_k_r20[] = "r20"; +static const char __pyx_k_r21[] = "r21"; +static const char __pyx_k_r22[] = "r22"; +static const char __pyx_k_r23[] = "r23"; +static const char __pyx_k_r24[] = "r24"; +static const char __pyx_k_r25[] = "r25"; +static const char __pyx_k_r26[] = "r26"; +static const char __pyx_k_r27[] = "r27"; +static const char __pyx_k_r28[] = "r28"; +static const char __pyx_k_r29[] = "r29"; +static const char __pyx_k_r30[] = "r30"; +static const char __pyx_k_r31[] = "r31"; +static const char __pyx_k_r32[] = "r32"; +static const char __pyx_k_r33[] = "r33"; +static const char __pyx_k_r34[] = "r34"; +static const char __pyx_k_r35[] = "r35"; +static const char __pyx_k_r36[] = "r36"; +static const char __pyx_k_r37[] = "r37"; +static const char __pyx_k_r38[] = "r38"; +static const char __pyx_k_r39[] = "r39"; +static const char __pyx_k_r40[] = "r40"; +static const char __pyx_k_r41[] = "r41"; +static const char __pyx_k_r42[] = "r42"; +static const char __pyx_k_r43[] = "r43"; +static const char __pyx_k_r44[] = "r44"; +static const char __pyx_k_r45[] = "r45"; +static const char __pyx_k_r46[] = "r46"; +static const char __pyx_k_r47[] = "r47"; +static const char __pyx_k_r48[] = "r48"; +static const char __pyx_k_r49[] = "r49"; +static const char __pyx_k_r50[] = "r50"; +static const char __pyx_k_r51[] = "r51"; +static const char __pyx_k_r52[] = "r52"; +static const char __pyx_k_r53[] = "r53"; +static const char __pyx_k_r54[] = "r54"; +static const char __pyx_k_r55[] = "r55"; +static const char __pyx_k_r56[] = "r56"; +static const char __pyx_k_r57[] = "r57"; +static const char __pyx_k_r58[] = "r58"; +static const char __pyx_k_r59[] = "r59"; +static const char __pyx_k_r60[] = "r60"; +static const char __pyx_k_r61[] = "r61"; +static const char __pyx_k_r62[] = "r62"; +static const char __pyx_k_r63[] = "r63"; +static const char __pyx_k_r64[] = "r64"; +static const char __pyx_k_r65[] = "r65"; +static const char __pyx_k_r66[] = "r66"; +static const char __pyx_k_r67[] = "r67"; +static const char __pyx_k_r68[] = "r68"; +static const char __pyx_k_r69[] = "r69"; +static const char __pyx_k_r70[] = "r70"; +static const char __pyx_k_r71[] = "r71"; +static const char __pyx_k_r72[] = "r72"; +static const char __pyx_k_r73[] = "r73"; +static const char __pyx_k_r74[] = "r74"; +static const char __pyx_k_r75[] = "r75"; +static const char __pyx_k_r76[] = "r76"; +static const char __pyx_k_r77[] = "r77"; +static const char __pyx_k_r78[] = "r78"; +static const char __pyx_k_r79[] = "r79"; +static const char __pyx_k_r80[] = "r80"; +static const char __pyx_k_r81[] = "r81"; +static const char __pyx_k_r82[] = "r82"; +static const char __pyx_k_r83[] = "r83"; +static const char __pyx_k_r84[] = "r84"; +static const char __pyx_k_r85[] = "r85"; +static const char __pyx_k_r86[] = "r86"; +static const char __pyx_k_r87[] = "r87"; +static const char __pyx_k_r88[] = "r88"; +static const char __pyx_k_r89[] = "r89"; +static const char __pyx_k_r90[] = "r90"; +static const char __pyx_k_r91[] = "r91"; +static const char __pyx_k_r92[] = "r92"; +static const char __pyx_k_r93[] = "r93"; +static const char __pyx_k_r94[] = "r94"; +static const char __pyx_k_r95[] = "r95"; +static const char __pyx_k_r96[] = "r96"; +static const char __pyx_k_r97[] = "r97"; +static const char __pyx_k_r98[] = "r98"; +static const char __pyx_k_r99[] = "r99"; +static const char __pyx_k_area[] = "area"; +static const char __pyx_k_dict[] = "__dict__"; +static const char __pyx_k_init[] = "__init__"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_r100[] = "r100"; +static const char __pyx_k_r101[] = "r101"; +static const char __pyx_k_r102[] = "r102"; +static const char __pyx_k_r103[] = "r103"; +static const char __pyx_k_r104[] = "r104"; +static const char __pyx_k_r105[] = "r105"; +static const char __pyx_k_r106[] = "r106"; +static const char __pyx_k_r107[] = "r107"; +static const char __pyx_k_r108[] = "r108"; +static const char __pyx_k_r109[] = "r109"; +static const char __pyx_k_r110[] = "r110"; +static const char __pyx_k_r111[] = "r111"; +static const char __pyx_k_r112[] = "r112"; +static const char __pyx_k_r113[] = "r113"; +static const char __pyx_k_r114[] = "r114"; +static const char __pyx_k_r115[] = "r115"; +static const char __pyx_k_r116[] = "r116"; +static const char __pyx_k_r117[] = "r117"; +static const char __pyx_k_r118[] = "r118"; +static const char __pyx_k_r119[] = "r119"; +static const char __pyx_k_r120[] = "r120"; +static const char __pyx_k_r121[] = "r121"; +static const char __pyx_k_r122[] = "r122"; +static const char __pyx_k_r123[] = "r123"; +static const char __pyx_k_r124[] = "r124"; +static const char __pyx_k_r125[] = "r125"; +static const char __pyx_k_r126[] = "r126"; +static const char __pyx_k_r127[] = "r127"; +static const char __pyx_k_r128[] = "r128"; +static const char __pyx_k_r129[] = "r129"; +static const char __pyx_k_r130[] = "r130"; +static const char __pyx_k_r131[] = "r131"; +static const char __pyx_k_r132[] = "r132"; +static const char __pyx_k_self[] = "self"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_super[] = "super"; +static const char __pyx_k_cython[] = "cython"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_lineTo[] = "_lineTo"; +static const char __pyx_k_module[] = "__module__"; +static const char __pyx_k_moveTo[] = "_moveTo"; +static const char __pyx_k_BasePen[] = "BasePen"; +static const char __pyx_k_endPath[] = "_endPath"; +static const char __pyx_k_momentX[] = "momentX"; +static const char __pyx_k_momentY[] = "momentY"; +static const char __pyx_k_prepare[] = "__prepare__"; +static const char __pyx_k_COMPILED[] = "COMPILED"; +static const char __pyx_k_glyphset[] = "glyphset"; +static const char __pyx_k_momentXX[] = "momentXX"; +static const char __pyx_k_momentXY[] = "momentXY"; +static const char __pyx_k_momentYY[] = "momentYY"; +static const char __pyx_k_qualname[] = "__qualname__"; +static const char __pyx_k_set_name[] = "__set_name__"; +static const char __pyx_k_closePath[] = "_closePath"; +static const char __pyx_k_metaclass[] = "__metaclass__"; +static const char __pyx_k_MomentsPen[] = "MomentsPen"; +static const char __pyx_k_curveToOne[] = "_curveToOne"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_mro_entries[] = "__mro_entries__"; +static const char __pyx_k_qCurveToOne[] = "_qCurveToOne"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_init_subclass[] = "__init_subclass__"; +static const char __pyx_k_printGreenPen[] = "printGreenPen"; +static const char __pyx_k_AttributeError[] = "AttributeError"; +static const char __pyx_k_fontTools_misc[] = "fontTools.misc"; +static const char __pyx_k_getCurrentPoint[] = "_getCurrentPoint"; +static const char __pyx_k_OpenContourError[] = "OpenContourError"; +static const char __pyx_k_MomentsPen___init[] = "MomentsPen.__init__"; +static const char __pyx_k_MomentsPen__lineTo[] = "MomentsPen._lineTo"; +static const char __pyx_k_MomentsPen__moveTo[] = "MomentsPen._moveTo"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_MomentsPen__endPath[] = "MomentsPen._endPath"; +static const char __pyx_k_MomentsPen__closePath[] = "MomentsPen._closePath"; +static const char __pyx_k_MomentsPen__curveToOne[] = "MomentsPen._curveToOne"; +static const char __pyx_k_MomentsPen__startPoint[] = "_MomentsPen__startPoint"; +static const char __pyx_k_fontTools_misc_symfont[] = "fontTools.misc.symfont"; +static const char __pyx_k_fontTools_pens_basePen[] = "fontTools.pens.basePen"; +static const char __pyx_k_MomentsPen__qCurveToOne[] = "MomentsPen._qCurveToOne"; +static const char __pyx_k_fontTools_pens_momentsPen[] = "fontTools.pens.momentsPen"; +static const char __pyx_k_Glyph_statistics_not_defined_on[] = "Glyph statistics not defined on open contours."; +static const char __pyx_k_Lib_fontTools_pens_momentsPen_py[] = "Lib/fontTools/pens/momentsPen.py"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_glyphset); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyObject *__pyx_kp_u_; + PyObject *__pyx_n_s_AttributeError; + PyObject *__pyx_n_s_BasePen; + PyObject *__pyx_n_s_COMPILED; + PyObject *__pyx_kp_u_Glyph_statistics_not_defined_on; + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_kp_s_Lib_fontTools_pens_momentsPen_py; + PyObject *__pyx_n_s_MomentsPen; + PyObject *__pyx_n_u_MomentsPen; + PyObject *__pyx_n_s_MomentsPen___init; + PyObject *__pyx_n_s_MomentsPen__closePath; + PyObject *__pyx_n_s_MomentsPen__curveToOne; + PyObject *__pyx_n_s_MomentsPen__endPath; + PyObject *__pyx_n_s_MomentsPen__lineTo; + PyObject *__pyx_n_s_MomentsPen__moveTo; + PyObject *__pyx_n_s_MomentsPen__qCurveToOne; + PyObject *__pyx_n_s_MomentsPen__startPoint; + PyObject *__pyx_n_s_OpenContourError; + PyObject *__pyx_n_s__16; + PyObject *__pyx_n_s_all; + PyObject *__pyx_n_s_area; + PyObject *__pyx_n_u_area; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_closePath; + PyObject *__pyx_n_s_curveToOne; + PyObject *__pyx_n_s_cython; + PyObject *__pyx_n_s_dict; + PyObject *__pyx_n_s_doc; + PyObject *__pyx_n_s_endPath; + PyObject *__pyx_n_s_fontTools_misc; + PyObject *__pyx_n_s_fontTools_misc_symfont; + PyObject *__pyx_n_s_fontTools_pens_basePen; + PyObject *__pyx_n_s_fontTools_pens_momentsPen; + PyObject *__pyx_n_s_getCurrentPoint; + PyObject *__pyx_n_s_glyphset; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_init; + PyObject *__pyx_n_s_init_subclass; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_n_s_lineTo; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_u_main; + PyObject *__pyx_n_s_metaclass; + PyObject *__pyx_n_s_module; + PyObject *__pyx_n_s_momentX; + PyObject *__pyx_n_u_momentX; + PyObject *__pyx_n_s_momentXX; + PyObject *__pyx_n_u_momentXX; + PyObject *__pyx_n_s_momentXY; + PyObject *__pyx_n_u_momentXY; + PyObject *__pyx_n_s_momentY; + PyObject *__pyx_n_u_momentY; + PyObject *__pyx_n_s_momentYY; + PyObject *__pyx_n_u_momentYY; + PyObject *__pyx_n_s_moveTo; + PyObject *__pyx_n_s_mro_entries; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_p0; + PyObject *__pyx_n_s_p1; + PyObject *__pyx_n_s_p2; + PyObject *__pyx_n_s_p3; + PyObject *__pyx_n_s_prepare; + PyObject *__pyx_n_s_printGreenPen; + PyObject *__pyx_n_s_qCurveToOne; + PyObject *__pyx_n_s_qualname; + PyObject *__pyx_n_s_r0; + PyObject *__pyx_n_s_r1; + PyObject *__pyx_n_s_r10; + PyObject *__pyx_n_s_r100; + PyObject *__pyx_n_s_r101; + PyObject *__pyx_n_s_r102; + PyObject *__pyx_n_s_r103; + PyObject *__pyx_n_s_r104; + PyObject *__pyx_n_s_r105; + PyObject *__pyx_n_s_r106; + PyObject *__pyx_n_s_r107; + PyObject *__pyx_n_s_r108; + PyObject *__pyx_n_s_r109; + PyObject *__pyx_n_s_r11; + PyObject *__pyx_n_s_r110; + PyObject *__pyx_n_s_r111; + PyObject *__pyx_n_s_r112; + PyObject *__pyx_n_s_r113; + PyObject *__pyx_n_s_r114; + PyObject *__pyx_n_s_r115; + PyObject *__pyx_n_s_r116; + PyObject *__pyx_n_s_r117; + PyObject *__pyx_n_s_r118; + PyObject *__pyx_n_s_r119; + PyObject *__pyx_n_s_r12; + PyObject *__pyx_n_s_r120; + PyObject *__pyx_n_s_r121; + PyObject *__pyx_n_s_r122; + PyObject *__pyx_n_s_r123; + PyObject *__pyx_n_s_r124; + PyObject *__pyx_n_s_r125; + PyObject *__pyx_n_s_r126; + PyObject *__pyx_n_s_r127; + PyObject *__pyx_n_s_r128; + PyObject *__pyx_n_s_r129; + PyObject *__pyx_n_s_r13; + PyObject *__pyx_n_s_r130; + PyObject *__pyx_n_s_r131; + PyObject *__pyx_n_s_r132; + PyObject *__pyx_n_s_r14; + PyObject *__pyx_n_s_r15; + PyObject *__pyx_n_s_r16; + PyObject *__pyx_n_s_r17; + PyObject *__pyx_n_s_r18; + PyObject *__pyx_n_s_r19; + PyObject *__pyx_n_s_r2; + PyObject *__pyx_n_s_r20; + PyObject *__pyx_n_s_r21; + PyObject *__pyx_n_s_r22; + PyObject *__pyx_n_s_r23; + PyObject *__pyx_n_s_r24; + PyObject *__pyx_n_s_r25; + PyObject *__pyx_n_s_r26; + PyObject *__pyx_n_s_r27; + PyObject *__pyx_n_s_r28; + PyObject *__pyx_n_s_r29; + PyObject *__pyx_n_s_r3; + PyObject *__pyx_n_s_r30; + PyObject *__pyx_n_s_r31; + PyObject *__pyx_n_s_r32; + PyObject *__pyx_n_s_r33; + PyObject *__pyx_n_s_r34; + PyObject *__pyx_n_s_r35; + PyObject *__pyx_n_s_r36; + PyObject *__pyx_n_s_r37; + PyObject *__pyx_n_s_r38; + PyObject *__pyx_n_s_r39; + PyObject *__pyx_n_s_r4; + PyObject *__pyx_n_s_r40; + PyObject *__pyx_n_s_r41; + PyObject *__pyx_n_s_r42; + PyObject *__pyx_n_s_r43; + PyObject *__pyx_n_s_r44; + PyObject *__pyx_n_s_r45; + PyObject *__pyx_n_s_r46; + PyObject *__pyx_n_s_r47; + PyObject *__pyx_n_s_r48; + PyObject *__pyx_n_s_r49; + PyObject *__pyx_n_s_r5; + PyObject *__pyx_n_s_r50; + PyObject *__pyx_n_s_r51; + PyObject *__pyx_n_s_r52; + PyObject *__pyx_n_s_r53; + PyObject *__pyx_n_s_r54; + PyObject *__pyx_n_s_r55; + PyObject *__pyx_n_s_r56; + PyObject *__pyx_n_s_r57; + PyObject *__pyx_n_s_r58; + PyObject *__pyx_n_s_r59; + PyObject *__pyx_n_s_r6; + PyObject *__pyx_n_s_r60; + PyObject *__pyx_n_s_r61; + PyObject *__pyx_n_s_r62; + PyObject *__pyx_n_s_r63; + PyObject *__pyx_n_s_r64; + PyObject *__pyx_n_s_r65; + PyObject *__pyx_n_s_r66; + PyObject *__pyx_n_s_r67; + PyObject *__pyx_n_s_r68; + PyObject *__pyx_n_s_r69; + PyObject *__pyx_n_s_r7; + PyObject *__pyx_n_s_r70; + PyObject *__pyx_n_s_r71; + PyObject *__pyx_n_s_r72; + PyObject *__pyx_n_s_r73; + PyObject *__pyx_n_s_r74; + PyObject *__pyx_n_s_r75; + PyObject *__pyx_n_s_r76; + PyObject *__pyx_n_s_r77; + PyObject *__pyx_n_s_r78; + PyObject *__pyx_n_s_r79; + PyObject *__pyx_n_s_r8; + PyObject *__pyx_n_s_r80; + PyObject *__pyx_n_s_r81; + PyObject *__pyx_n_s_r82; + PyObject *__pyx_n_s_r83; + PyObject *__pyx_n_s_r84; + PyObject *__pyx_n_s_r85; + PyObject *__pyx_n_s_r86; + PyObject *__pyx_n_s_r87; + PyObject *__pyx_n_s_r88; + PyObject *__pyx_n_s_r89; + PyObject *__pyx_n_s_r9; + PyObject *__pyx_n_s_r90; + PyObject *__pyx_n_s_r91; + PyObject *__pyx_n_s_r92; + PyObject *__pyx_n_s_r93; + PyObject *__pyx_n_s_r94; + PyObject *__pyx_n_s_r95; + PyObject *__pyx_n_s_r96; + PyObject *__pyx_n_s_r97; + PyObject *__pyx_n_s_r98; + PyObject *__pyx_n_s_r99; + PyObject *__pyx_n_s_self; + PyObject *__pyx_n_s_set_name; + PyObject *__pyx_n_s_super; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_x; + PyObject *__pyx_n_s_x0; + PyObject *__pyx_n_s_x1; + PyObject *__pyx_n_s_x2; + PyObject *__pyx_n_s_x3; + PyObject *__pyx_n_s_y; + PyObject *__pyx_n_s_y0; + PyObject *__pyx_n_s_y1; + PyObject *__pyx_n_s_y2; + PyObject *__pyx_n_s_y3; + PyObject *__pyx_int_0; + PyObject *__pyx_int_1; + PyObject *__pyx_int_2; + PyObject *__pyx_tuple__2; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__5; + PyObject *__pyx_tuple__9; + PyObject *__pyx_tuple__11; + PyObject *__pyx_tuple__13; + PyObject *__pyx_tuple__15; + PyObject *__pyx_codeobj__3; + PyObject *__pyx_codeobj__6; + PyObject *__pyx_codeobj__7; + PyObject *__pyx_codeobj__8; + PyObject *__pyx_codeobj__10; + PyObject *__pyx_codeobj__12; + PyObject *__pyx_codeobj__14; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_kp_u_); + Py_CLEAR(clear_module_state->__pyx_n_s_AttributeError); + Py_CLEAR(clear_module_state->__pyx_n_s_BasePen); + Py_CLEAR(clear_module_state->__pyx_n_s_COMPILED); + Py_CLEAR(clear_module_state->__pyx_kp_u_Glyph_statistics_not_defined_on); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Lib_fontTools_pens_momentsPen_py); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen); + Py_CLEAR(clear_module_state->__pyx_n_u_MomentsPen); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen___init); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__closePath); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__curveToOne); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__endPath); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__lineTo); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__moveTo); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__qCurveToOne); + Py_CLEAR(clear_module_state->__pyx_n_s_MomentsPen__startPoint); + Py_CLEAR(clear_module_state->__pyx_n_s_OpenContourError); + Py_CLEAR(clear_module_state->__pyx_n_s__16); + Py_CLEAR(clear_module_state->__pyx_n_s_all); + Py_CLEAR(clear_module_state->__pyx_n_s_area); + Py_CLEAR(clear_module_state->__pyx_n_u_area); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_closePath); + Py_CLEAR(clear_module_state->__pyx_n_s_curveToOne); + Py_CLEAR(clear_module_state->__pyx_n_s_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_dict); + Py_CLEAR(clear_module_state->__pyx_n_s_doc); + Py_CLEAR(clear_module_state->__pyx_n_s_endPath); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc_symfont); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_pens_basePen); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_pens_momentsPen); + Py_CLEAR(clear_module_state->__pyx_n_s_getCurrentPoint); + Py_CLEAR(clear_module_state->__pyx_n_s_glyphset); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_init); + Py_CLEAR(clear_module_state->__pyx_n_s_init_subclass); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_n_s_lineTo); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_u_main); + Py_CLEAR(clear_module_state->__pyx_n_s_metaclass); + Py_CLEAR(clear_module_state->__pyx_n_s_module); + Py_CLEAR(clear_module_state->__pyx_n_s_momentX); + Py_CLEAR(clear_module_state->__pyx_n_u_momentX); + Py_CLEAR(clear_module_state->__pyx_n_s_momentXX); + Py_CLEAR(clear_module_state->__pyx_n_u_momentXX); + Py_CLEAR(clear_module_state->__pyx_n_s_momentXY); + Py_CLEAR(clear_module_state->__pyx_n_u_momentXY); + Py_CLEAR(clear_module_state->__pyx_n_s_momentY); + Py_CLEAR(clear_module_state->__pyx_n_u_momentY); + Py_CLEAR(clear_module_state->__pyx_n_s_momentYY); + Py_CLEAR(clear_module_state->__pyx_n_u_momentYY); + Py_CLEAR(clear_module_state->__pyx_n_s_moveTo); + Py_CLEAR(clear_module_state->__pyx_n_s_mro_entries); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_p0); + Py_CLEAR(clear_module_state->__pyx_n_s_p1); + Py_CLEAR(clear_module_state->__pyx_n_s_p2); + Py_CLEAR(clear_module_state->__pyx_n_s_p3); + Py_CLEAR(clear_module_state->__pyx_n_s_prepare); + Py_CLEAR(clear_module_state->__pyx_n_s_printGreenPen); + Py_CLEAR(clear_module_state->__pyx_n_s_qCurveToOne); + Py_CLEAR(clear_module_state->__pyx_n_s_qualname); + Py_CLEAR(clear_module_state->__pyx_n_s_r0); + Py_CLEAR(clear_module_state->__pyx_n_s_r1); + Py_CLEAR(clear_module_state->__pyx_n_s_r10); + Py_CLEAR(clear_module_state->__pyx_n_s_r100); + Py_CLEAR(clear_module_state->__pyx_n_s_r101); + Py_CLEAR(clear_module_state->__pyx_n_s_r102); + Py_CLEAR(clear_module_state->__pyx_n_s_r103); + Py_CLEAR(clear_module_state->__pyx_n_s_r104); + Py_CLEAR(clear_module_state->__pyx_n_s_r105); + Py_CLEAR(clear_module_state->__pyx_n_s_r106); + Py_CLEAR(clear_module_state->__pyx_n_s_r107); + Py_CLEAR(clear_module_state->__pyx_n_s_r108); + Py_CLEAR(clear_module_state->__pyx_n_s_r109); + Py_CLEAR(clear_module_state->__pyx_n_s_r11); + Py_CLEAR(clear_module_state->__pyx_n_s_r110); + Py_CLEAR(clear_module_state->__pyx_n_s_r111); + Py_CLEAR(clear_module_state->__pyx_n_s_r112); + Py_CLEAR(clear_module_state->__pyx_n_s_r113); + Py_CLEAR(clear_module_state->__pyx_n_s_r114); + Py_CLEAR(clear_module_state->__pyx_n_s_r115); + Py_CLEAR(clear_module_state->__pyx_n_s_r116); + Py_CLEAR(clear_module_state->__pyx_n_s_r117); + Py_CLEAR(clear_module_state->__pyx_n_s_r118); + Py_CLEAR(clear_module_state->__pyx_n_s_r119); + Py_CLEAR(clear_module_state->__pyx_n_s_r12); + Py_CLEAR(clear_module_state->__pyx_n_s_r120); + Py_CLEAR(clear_module_state->__pyx_n_s_r121); + Py_CLEAR(clear_module_state->__pyx_n_s_r122); + Py_CLEAR(clear_module_state->__pyx_n_s_r123); + Py_CLEAR(clear_module_state->__pyx_n_s_r124); + Py_CLEAR(clear_module_state->__pyx_n_s_r125); + Py_CLEAR(clear_module_state->__pyx_n_s_r126); + Py_CLEAR(clear_module_state->__pyx_n_s_r127); + Py_CLEAR(clear_module_state->__pyx_n_s_r128); + Py_CLEAR(clear_module_state->__pyx_n_s_r129); + Py_CLEAR(clear_module_state->__pyx_n_s_r13); + Py_CLEAR(clear_module_state->__pyx_n_s_r130); + Py_CLEAR(clear_module_state->__pyx_n_s_r131); + Py_CLEAR(clear_module_state->__pyx_n_s_r132); + Py_CLEAR(clear_module_state->__pyx_n_s_r14); + Py_CLEAR(clear_module_state->__pyx_n_s_r15); + Py_CLEAR(clear_module_state->__pyx_n_s_r16); + Py_CLEAR(clear_module_state->__pyx_n_s_r17); + Py_CLEAR(clear_module_state->__pyx_n_s_r18); + Py_CLEAR(clear_module_state->__pyx_n_s_r19); + Py_CLEAR(clear_module_state->__pyx_n_s_r2); + Py_CLEAR(clear_module_state->__pyx_n_s_r20); + Py_CLEAR(clear_module_state->__pyx_n_s_r21); + Py_CLEAR(clear_module_state->__pyx_n_s_r22); + Py_CLEAR(clear_module_state->__pyx_n_s_r23); + Py_CLEAR(clear_module_state->__pyx_n_s_r24); + Py_CLEAR(clear_module_state->__pyx_n_s_r25); + Py_CLEAR(clear_module_state->__pyx_n_s_r26); + Py_CLEAR(clear_module_state->__pyx_n_s_r27); + Py_CLEAR(clear_module_state->__pyx_n_s_r28); + Py_CLEAR(clear_module_state->__pyx_n_s_r29); + Py_CLEAR(clear_module_state->__pyx_n_s_r3); + Py_CLEAR(clear_module_state->__pyx_n_s_r30); + Py_CLEAR(clear_module_state->__pyx_n_s_r31); + Py_CLEAR(clear_module_state->__pyx_n_s_r32); + Py_CLEAR(clear_module_state->__pyx_n_s_r33); + Py_CLEAR(clear_module_state->__pyx_n_s_r34); + Py_CLEAR(clear_module_state->__pyx_n_s_r35); + Py_CLEAR(clear_module_state->__pyx_n_s_r36); + Py_CLEAR(clear_module_state->__pyx_n_s_r37); + Py_CLEAR(clear_module_state->__pyx_n_s_r38); + Py_CLEAR(clear_module_state->__pyx_n_s_r39); + Py_CLEAR(clear_module_state->__pyx_n_s_r4); + Py_CLEAR(clear_module_state->__pyx_n_s_r40); + Py_CLEAR(clear_module_state->__pyx_n_s_r41); + Py_CLEAR(clear_module_state->__pyx_n_s_r42); + Py_CLEAR(clear_module_state->__pyx_n_s_r43); + Py_CLEAR(clear_module_state->__pyx_n_s_r44); + Py_CLEAR(clear_module_state->__pyx_n_s_r45); + Py_CLEAR(clear_module_state->__pyx_n_s_r46); + Py_CLEAR(clear_module_state->__pyx_n_s_r47); + Py_CLEAR(clear_module_state->__pyx_n_s_r48); + Py_CLEAR(clear_module_state->__pyx_n_s_r49); + Py_CLEAR(clear_module_state->__pyx_n_s_r5); + Py_CLEAR(clear_module_state->__pyx_n_s_r50); + Py_CLEAR(clear_module_state->__pyx_n_s_r51); + Py_CLEAR(clear_module_state->__pyx_n_s_r52); + Py_CLEAR(clear_module_state->__pyx_n_s_r53); + Py_CLEAR(clear_module_state->__pyx_n_s_r54); + Py_CLEAR(clear_module_state->__pyx_n_s_r55); + Py_CLEAR(clear_module_state->__pyx_n_s_r56); + Py_CLEAR(clear_module_state->__pyx_n_s_r57); + Py_CLEAR(clear_module_state->__pyx_n_s_r58); + Py_CLEAR(clear_module_state->__pyx_n_s_r59); + Py_CLEAR(clear_module_state->__pyx_n_s_r6); + Py_CLEAR(clear_module_state->__pyx_n_s_r60); + Py_CLEAR(clear_module_state->__pyx_n_s_r61); + Py_CLEAR(clear_module_state->__pyx_n_s_r62); + Py_CLEAR(clear_module_state->__pyx_n_s_r63); + Py_CLEAR(clear_module_state->__pyx_n_s_r64); + Py_CLEAR(clear_module_state->__pyx_n_s_r65); + Py_CLEAR(clear_module_state->__pyx_n_s_r66); + Py_CLEAR(clear_module_state->__pyx_n_s_r67); + Py_CLEAR(clear_module_state->__pyx_n_s_r68); + Py_CLEAR(clear_module_state->__pyx_n_s_r69); + Py_CLEAR(clear_module_state->__pyx_n_s_r7); + Py_CLEAR(clear_module_state->__pyx_n_s_r70); + Py_CLEAR(clear_module_state->__pyx_n_s_r71); + Py_CLEAR(clear_module_state->__pyx_n_s_r72); + Py_CLEAR(clear_module_state->__pyx_n_s_r73); + Py_CLEAR(clear_module_state->__pyx_n_s_r74); + Py_CLEAR(clear_module_state->__pyx_n_s_r75); + Py_CLEAR(clear_module_state->__pyx_n_s_r76); + Py_CLEAR(clear_module_state->__pyx_n_s_r77); + Py_CLEAR(clear_module_state->__pyx_n_s_r78); + Py_CLEAR(clear_module_state->__pyx_n_s_r79); + Py_CLEAR(clear_module_state->__pyx_n_s_r8); + Py_CLEAR(clear_module_state->__pyx_n_s_r80); + Py_CLEAR(clear_module_state->__pyx_n_s_r81); + Py_CLEAR(clear_module_state->__pyx_n_s_r82); + Py_CLEAR(clear_module_state->__pyx_n_s_r83); + Py_CLEAR(clear_module_state->__pyx_n_s_r84); + Py_CLEAR(clear_module_state->__pyx_n_s_r85); + Py_CLEAR(clear_module_state->__pyx_n_s_r86); + Py_CLEAR(clear_module_state->__pyx_n_s_r87); + Py_CLEAR(clear_module_state->__pyx_n_s_r88); + Py_CLEAR(clear_module_state->__pyx_n_s_r89); + Py_CLEAR(clear_module_state->__pyx_n_s_r9); + Py_CLEAR(clear_module_state->__pyx_n_s_r90); + Py_CLEAR(clear_module_state->__pyx_n_s_r91); + Py_CLEAR(clear_module_state->__pyx_n_s_r92); + Py_CLEAR(clear_module_state->__pyx_n_s_r93); + Py_CLEAR(clear_module_state->__pyx_n_s_r94); + Py_CLEAR(clear_module_state->__pyx_n_s_r95); + Py_CLEAR(clear_module_state->__pyx_n_s_r96); + Py_CLEAR(clear_module_state->__pyx_n_s_r97); + Py_CLEAR(clear_module_state->__pyx_n_s_r98); + Py_CLEAR(clear_module_state->__pyx_n_s_r99); + Py_CLEAR(clear_module_state->__pyx_n_s_self); + Py_CLEAR(clear_module_state->__pyx_n_s_set_name); + Py_CLEAR(clear_module_state->__pyx_n_s_super); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_x); + Py_CLEAR(clear_module_state->__pyx_n_s_x0); + Py_CLEAR(clear_module_state->__pyx_n_s_x1); + Py_CLEAR(clear_module_state->__pyx_n_s_x2); + Py_CLEAR(clear_module_state->__pyx_n_s_x3); + Py_CLEAR(clear_module_state->__pyx_n_s_y); + Py_CLEAR(clear_module_state->__pyx_n_s_y0); + Py_CLEAR(clear_module_state->__pyx_n_s_y1); + Py_CLEAR(clear_module_state->__pyx_n_s_y2); + Py_CLEAR(clear_module_state->__pyx_n_s_y3); + Py_CLEAR(clear_module_state->__pyx_int_0); + Py_CLEAR(clear_module_state->__pyx_int_1); + Py_CLEAR(clear_module_state->__pyx_int_2); + Py_CLEAR(clear_module_state->__pyx_tuple__2); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__5); + Py_CLEAR(clear_module_state->__pyx_tuple__9); + Py_CLEAR(clear_module_state->__pyx_tuple__11); + Py_CLEAR(clear_module_state->__pyx_tuple__13); + Py_CLEAR(clear_module_state->__pyx_tuple__15); + Py_CLEAR(clear_module_state->__pyx_codeobj__3); + Py_CLEAR(clear_module_state->__pyx_codeobj__6); + Py_CLEAR(clear_module_state->__pyx_codeobj__7); + Py_CLEAR(clear_module_state->__pyx_codeobj__8); + Py_CLEAR(clear_module_state->__pyx_codeobj__10); + Py_CLEAR(clear_module_state->__pyx_codeobj__12); + Py_CLEAR(clear_module_state->__pyx_codeobj__14); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_kp_u_); + Py_VISIT(traverse_module_state->__pyx_n_s_AttributeError); + Py_VISIT(traverse_module_state->__pyx_n_s_BasePen); + Py_VISIT(traverse_module_state->__pyx_n_s_COMPILED); + Py_VISIT(traverse_module_state->__pyx_kp_u_Glyph_statistics_not_defined_on); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Lib_fontTools_pens_momentsPen_py); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen); + Py_VISIT(traverse_module_state->__pyx_n_u_MomentsPen); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen___init); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__closePath); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__curveToOne); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__endPath); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__lineTo); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__moveTo); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__qCurveToOne); + Py_VISIT(traverse_module_state->__pyx_n_s_MomentsPen__startPoint); + Py_VISIT(traverse_module_state->__pyx_n_s_OpenContourError); + Py_VISIT(traverse_module_state->__pyx_n_s__16); + Py_VISIT(traverse_module_state->__pyx_n_s_all); + Py_VISIT(traverse_module_state->__pyx_n_s_area); + Py_VISIT(traverse_module_state->__pyx_n_u_area); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_closePath); + Py_VISIT(traverse_module_state->__pyx_n_s_curveToOne); + Py_VISIT(traverse_module_state->__pyx_n_s_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_dict); + Py_VISIT(traverse_module_state->__pyx_n_s_doc); + Py_VISIT(traverse_module_state->__pyx_n_s_endPath); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc_symfont); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_pens_basePen); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_pens_momentsPen); + Py_VISIT(traverse_module_state->__pyx_n_s_getCurrentPoint); + Py_VISIT(traverse_module_state->__pyx_n_s_glyphset); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_init); + Py_VISIT(traverse_module_state->__pyx_n_s_init_subclass); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_n_s_lineTo); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_u_main); + Py_VISIT(traverse_module_state->__pyx_n_s_metaclass); + Py_VISIT(traverse_module_state->__pyx_n_s_module); + Py_VISIT(traverse_module_state->__pyx_n_s_momentX); + Py_VISIT(traverse_module_state->__pyx_n_u_momentX); + Py_VISIT(traverse_module_state->__pyx_n_s_momentXX); + Py_VISIT(traverse_module_state->__pyx_n_u_momentXX); + Py_VISIT(traverse_module_state->__pyx_n_s_momentXY); + Py_VISIT(traverse_module_state->__pyx_n_u_momentXY); + Py_VISIT(traverse_module_state->__pyx_n_s_momentY); + Py_VISIT(traverse_module_state->__pyx_n_u_momentY); + Py_VISIT(traverse_module_state->__pyx_n_s_momentYY); + Py_VISIT(traverse_module_state->__pyx_n_u_momentYY); + Py_VISIT(traverse_module_state->__pyx_n_s_moveTo); + Py_VISIT(traverse_module_state->__pyx_n_s_mro_entries); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_p0); + Py_VISIT(traverse_module_state->__pyx_n_s_p1); + Py_VISIT(traverse_module_state->__pyx_n_s_p2); + Py_VISIT(traverse_module_state->__pyx_n_s_p3); + Py_VISIT(traverse_module_state->__pyx_n_s_prepare); + Py_VISIT(traverse_module_state->__pyx_n_s_printGreenPen); + Py_VISIT(traverse_module_state->__pyx_n_s_qCurveToOne); + Py_VISIT(traverse_module_state->__pyx_n_s_qualname); + Py_VISIT(traverse_module_state->__pyx_n_s_r0); + Py_VISIT(traverse_module_state->__pyx_n_s_r1); + Py_VISIT(traverse_module_state->__pyx_n_s_r10); + Py_VISIT(traverse_module_state->__pyx_n_s_r100); + Py_VISIT(traverse_module_state->__pyx_n_s_r101); + Py_VISIT(traverse_module_state->__pyx_n_s_r102); + Py_VISIT(traverse_module_state->__pyx_n_s_r103); + Py_VISIT(traverse_module_state->__pyx_n_s_r104); + Py_VISIT(traverse_module_state->__pyx_n_s_r105); + Py_VISIT(traverse_module_state->__pyx_n_s_r106); + Py_VISIT(traverse_module_state->__pyx_n_s_r107); + Py_VISIT(traverse_module_state->__pyx_n_s_r108); + Py_VISIT(traverse_module_state->__pyx_n_s_r109); + Py_VISIT(traverse_module_state->__pyx_n_s_r11); + Py_VISIT(traverse_module_state->__pyx_n_s_r110); + Py_VISIT(traverse_module_state->__pyx_n_s_r111); + Py_VISIT(traverse_module_state->__pyx_n_s_r112); + Py_VISIT(traverse_module_state->__pyx_n_s_r113); + Py_VISIT(traverse_module_state->__pyx_n_s_r114); + Py_VISIT(traverse_module_state->__pyx_n_s_r115); + Py_VISIT(traverse_module_state->__pyx_n_s_r116); + Py_VISIT(traverse_module_state->__pyx_n_s_r117); + Py_VISIT(traverse_module_state->__pyx_n_s_r118); + Py_VISIT(traverse_module_state->__pyx_n_s_r119); + Py_VISIT(traverse_module_state->__pyx_n_s_r12); + Py_VISIT(traverse_module_state->__pyx_n_s_r120); + Py_VISIT(traverse_module_state->__pyx_n_s_r121); + Py_VISIT(traverse_module_state->__pyx_n_s_r122); + Py_VISIT(traverse_module_state->__pyx_n_s_r123); + Py_VISIT(traverse_module_state->__pyx_n_s_r124); + Py_VISIT(traverse_module_state->__pyx_n_s_r125); + Py_VISIT(traverse_module_state->__pyx_n_s_r126); + Py_VISIT(traverse_module_state->__pyx_n_s_r127); + Py_VISIT(traverse_module_state->__pyx_n_s_r128); + Py_VISIT(traverse_module_state->__pyx_n_s_r129); + Py_VISIT(traverse_module_state->__pyx_n_s_r13); + Py_VISIT(traverse_module_state->__pyx_n_s_r130); + Py_VISIT(traverse_module_state->__pyx_n_s_r131); + Py_VISIT(traverse_module_state->__pyx_n_s_r132); + Py_VISIT(traverse_module_state->__pyx_n_s_r14); + Py_VISIT(traverse_module_state->__pyx_n_s_r15); + Py_VISIT(traverse_module_state->__pyx_n_s_r16); + Py_VISIT(traverse_module_state->__pyx_n_s_r17); + Py_VISIT(traverse_module_state->__pyx_n_s_r18); + Py_VISIT(traverse_module_state->__pyx_n_s_r19); + Py_VISIT(traverse_module_state->__pyx_n_s_r2); + Py_VISIT(traverse_module_state->__pyx_n_s_r20); + Py_VISIT(traverse_module_state->__pyx_n_s_r21); + Py_VISIT(traverse_module_state->__pyx_n_s_r22); + Py_VISIT(traverse_module_state->__pyx_n_s_r23); + Py_VISIT(traverse_module_state->__pyx_n_s_r24); + Py_VISIT(traverse_module_state->__pyx_n_s_r25); + Py_VISIT(traverse_module_state->__pyx_n_s_r26); + Py_VISIT(traverse_module_state->__pyx_n_s_r27); + Py_VISIT(traverse_module_state->__pyx_n_s_r28); + Py_VISIT(traverse_module_state->__pyx_n_s_r29); + Py_VISIT(traverse_module_state->__pyx_n_s_r3); + Py_VISIT(traverse_module_state->__pyx_n_s_r30); + Py_VISIT(traverse_module_state->__pyx_n_s_r31); + Py_VISIT(traverse_module_state->__pyx_n_s_r32); + Py_VISIT(traverse_module_state->__pyx_n_s_r33); + Py_VISIT(traverse_module_state->__pyx_n_s_r34); + Py_VISIT(traverse_module_state->__pyx_n_s_r35); + Py_VISIT(traverse_module_state->__pyx_n_s_r36); + Py_VISIT(traverse_module_state->__pyx_n_s_r37); + Py_VISIT(traverse_module_state->__pyx_n_s_r38); + Py_VISIT(traverse_module_state->__pyx_n_s_r39); + Py_VISIT(traverse_module_state->__pyx_n_s_r4); + Py_VISIT(traverse_module_state->__pyx_n_s_r40); + Py_VISIT(traverse_module_state->__pyx_n_s_r41); + Py_VISIT(traverse_module_state->__pyx_n_s_r42); + Py_VISIT(traverse_module_state->__pyx_n_s_r43); + Py_VISIT(traverse_module_state->__pyx_n_s_r44); + Py_VISIT(traverse_module_state->__pyx_n_s_r45); + Py_VISIT(traverse_module_state->__pyx_n_s_r46); + Py_VISIT(traverse_module_state->__pyx_n_s_r47); + Py_VISIT(traverse_module_state->__pyx_n_s_r48); + Py_VISIT(traverse_module_state->__pyx_n_s_r49); + Py_VISIT(traverse_module_state->__pyx_n_s_r5); + Py_VISIT(traverse_module_state->__pyx_n_s_r50); + Py_VISIT(traverse_module_state->__pyx_n_s_r51); + Py_VISIT(traverse_module_state->__pyx_n_s_r52); + Py_VISIT(traverse_module_state->__pyx_n_s_r53); + Py_VISIT(traverse_module_state->__pyx_n_s_r54); + Py_VISIT(traverse_module_state->__pyx_n_s_r55); + Py_VISIT(traverse_module_state->__pyx_n_s_r56); + Py_VISIT(traverse_module_state->__pyx_n_s_r57); + Py_VISIT(traverse_module_state->__pyx_n_s_r58); + Py_VISIT(traverse_module_state->__pyx_n_s_r59); + Py_VISIT(traverse_module_state->__pyx_n_s_r6); + Py_VISIT(traverse_module_state->__pyx_n_s_r60); + Py_VISIT(traverse_module_state->__pyx_n_s_r61); + Py_VISIT(traverse_module_state->__pyx_n_s_r62); + Py_VISIT(traverse_module_state->__pyx_n_s_r63); + Py_VISIT(traverse_module_state->__pyx_n_s_r64); + Py_VISIT(traverse_module_state->__pyx_n_s_r65); + Py_VISIT(traverse_module_state->__pyx_n_s_r66); + Py_VISIT(traverse_module_state->__pyx_n_s_r67); + Py_VISIT(traverse_module_state->__pyx_n_s_r68); + Py_VISIT(traverse_module_state->__pyx_n_s_r69); + Py_VISIT(traverse_module_state->__pyx_n_s_r7); + Py_VISIT(traverse_module_state->__pyx_n_s_r70); + Py_VISIT(traverse_module_state->__pyx_n_s_r71); + Py_VISIT(traverse_module_state->__pyx_n_s_r72); + Py_VISIT(traverse_module_state->__pyx_n_s_r73); + Py_VISIT(traverse_module_state->__pyx_n_s_r74); + Py_VISIT(traverse_module_state->__pyx_n_s_r75); + Py_VISIT(traverse_module_state->__pyx_n_s_r76); + Py_VISIT(traverse_module_state->__pyx_n_s_r77); + Py_VISIT(traverse_module_state->__pyx_n_s_r78); + Py_VISIT(traverse_module_state->__pyx_n_s_r79); + Py_VISIT(traverse_module_state->__pyx_n_s_r8); + Py_VISIT(traverse_module_state->__pyx_n_s_r80); + Py_VISIT(traverse_module_state->__pyx_n_s_r81); + Py_VISIT(traverse_module_state->__pyx_n_s_r82); + Py_VISIT(traverse_module_state->__pyx_n_s_r83); + Py_VISIT(traverse_module_state->__pyx_n_s_r84); + Py_VISIT(traverse_module_state->__pyx_n_s_r85); + Py_VISIT(traverse_module_state->__pyx_n_s_r86); + Py_VISIT(traverse_module_state->__pyx_n_s_r87); + Py_VISIT(traverse_module_state->__pyx_n_s_r88); + Py_VISIT(traverse_module_state->__pyx_n_s_r89); + Py_VISIT(traverse_module_state->__pyx_n_s_r9); + Py_VISIT(traverse_module_state->__pyx_n_s_r90); + Py_VISIT(traverse_module_state->__pyx_n_s_r91); + Py_VISIT(traverse_module_state->__pyx_n_s_r92); + Py_VISIT(traverse_module_state->__pyx_n_s_r93); + Py_VISIT(traverse_module_state->__pyx_n_s_r94); + Py_VISIT(traverse_module_state->__pyx_n_s_r95); + Py_VISIT(traverse_module_state->__pyx_n_s_r96); + Py_VISIT(traverse_module_state->__pyx_n_s_r97); + Py_VISIT(traverse_module_state->__pyx_n_s_r98); + Py_VISIT(traverse_module_state->__pyx_n_s_r99); + Py_VISIT(traverse_module_state->__pyx_n_s_self); + Py_VISIT(traverse_module_state->__pyx_n_s_set_name); + Py_VISIT(traverse_module_state->__pyx_n_s_super); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_x); + Py_VISIT(traverse_module_state->__pyx_n_s_x0); + Py_VISIT(traverse_module_state->__pyx_n_s_x1); + Py_VISIT(traverse_module_state->__pyx_n_s_x2); + Py_VISIT(traverse_module_state->__pyx_n_s_x3); + Py_VISIT(traverse_module_state->__pyx_n_s_y); + Py_VISIT(traverse_module_state->__pyx_n_s_y0); + Py_VISIT(traverse_module_state->__pyx_n_s_y1); + Py_VISIT(traverse_module_state->__pyx_n_s_y2); + Py_VISIT(traverse_module_state->__pyx_n_s_y3); + Py_VISIT(traverse_module_state->__pyx_int_0); + Py_VISIT(traverse_module_state->__pyx_int_1); + Py_VISIT(traverse_module_state->__pyx_int_2); + Py_VISIT(traverse_module_state->__pyx_tuple__2); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__5); + Py_VISIT(traverse_module_state->__pyx_tuple__9); + Py_VISIT(traverse_module_state->__pyx_tuple__11); + Py_VISIT(traverse_module_state->__pyx_tuple__13); + Py_VISIT(traverse_module_state->__pyx_tuple__15); + Py_VISIT(traverse_module_state->__pyx_codeobj__3); + Py_VISIT(traverse_module_state->__pyx_codeobj__6); + Py_VISIT(traverse_module_state->__pyx_codeobj__7); + Py_VISIT(traverse_module_state->__pyx_codeobj__8); + Py_VISIT(traverse_module_state->__pyx_codeobj__10); + Py_VISIT(traverse_module_state->__pyx_codeobj__12); + Py_VISIT(traverse_module_state->__pyx_codeobj__14); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_kp_u_ __pyx_mstate_global->__pyx_kp_u_ +#define __pyx_n_s_AttributeError __pyx_mstate_global->__pyx_n_s_AttributeError +#define __pyx_n_s_BasePen __pyx_mstate_global->__pyx_n_s_BasePen +#define __pyx_n_s_COMPILED __pyx_mstate_global->__pyx_n_s_COMPILED +#define __pyx_kp_u_Glyph_statistics_not_defined_on __pyx_mstate_global->__pyx_kp_u_Glyph_statistics_not_defined_on +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_kp_s_Lib_fontTools_pens_momentsPen_py __pyx_mstate_global->__pyx_kp_s_Lib_fontTools_pens_momentsPen_py +#define __pyx_n_s_MomentsPen __pyx_mstate_global->__pyx_n_s_MomentsPen +#define __pyx_n_u_MomentsPen __pyx_mstate_global->__pyx_n_u_MomentsPen +#define __pyx_n_s_MomentsPen___init __pyx_mstate_global->__pyx_n_s_MomentsPen___init +#define __pyx_n_s_MomentsPen__closePath __pyx_mstate_global->__pyx_n_s_MomentsPen__closePath +#define __pyx_n_s_MomentsPen__curveToOne __pyx_mstate_global->__pyx_n_s_MomentsPen__curveToOne +#define __pyx_n_s_MomentsPen__endPath __pyx_mstate_global->__pyx_n_s_MomentsPen__endPath +#define __pyx_n_s_MomentsPen__lineTo __pyx_mstate_global->__pyx_n_s_MomentsPen__lineTo +#define __pyx_n_s_MomentsPen__moveTo __pyx_mstate_global->__pyx_n_s_MomentsPen__moveTo +#define __pyx_n_s_MomentsPen__qCurveToOne __pyx_mstate_global->__pyx_n_s_MomentsPen__qCurveToOne +#define __pyx_n_s_MomentsPen__startPoint __pyx_mstate_global->__pyx_n_s_MomentsPen__startPoint +#define __pyx_n_s_OpenContourError __pyx_mstate_global->__pyx_n_s_OpenContourError +#define __pyx_n_s__16 __pyx_mstate_global->__pyx_n_s__16 +#define __pyx_n_s_all __pyx_mstate_global->__pyx_n_s_all +#define __pyx_n_s_area __pyx_mstate_global->__pyx_n_s_area +#define __pyx_n_u_area __pyx_mstate_global->__pyx_n_u_area +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_closePath __pyx_mstate_global->__pyx_n_s_closePath +#define __pyx_n_s_curveToOne __pyx_mstate_global->__pyx_n_s_curveToOne +#define __pyx_n_s_cython __pyx_mstate_global->__pyx_n_s_cython +#define __pyx_n_s_dict __pyx_mstate_global->__pyx_n_s_dict +#define __pyx_n_s_doc __pyx_mstate_global->__pyx_n_s_doc +#define __pyx_n_s_endPath __pyx_mstate_global->__pyx_n_s_endPath +#define __pyx_n_s_fontTools_misc __pyx_mstate_global->__pyx_n_s_fontTools_misc +#define __pyx_n_s_fontTools_misc_symfont __pyx_mstate_global->__pyx_n_s_fontTools_misc_symfont +#define __pyx_n_s_fontTools_pens_basePen __pyx_mstate_global->__pyx_n_s_fontTools_pens_basePen +#define __pyx_n_s_fontTools_pens_momentsPen __pyx_mstate_global->__pyx_n_s_fontTools_pens_momentsPen +#define __pyx_n_s_getCurrentPoint __pyx_mstate_global->__pyx_n_s_getCurrentPoint +#define __pyx_n_s_glyphset __pyx_mstate_global->__pyx_n_s_glyphset +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_init __pyx_mstate_global->__pyx_n_s_init +#define __pyx_n_s_init_subclass __pyx_mstate_global->__pyx_n_s_init_subclass +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_n_s_lineTo __pyx_mstate_global->__pyx_n_s_lineTo +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_u_main __pyx_mstate_global->__pyx_n_u_main +#define __pyx_n_s_metaclass __pyx_mstate_global->__pyx_n_s_metaclass +#define __pyx_n_s_module __pyx_mstate_global->__pyx_n_s_module +#define __pyx_n_s_momentX __pyx_mstate_global->__pyx_n_s_momentX +#define __pyx_n_u_momentX __pyx_mstate_global->__pyx_n_u_momentX +#define __pyx_n_s_momentXX __pyx_mstate_global->__pyx_n_s_momentXX +#define __pyx_n_u_momentXX __pyx_mstate_global->__pyx_n_u_momentXX +#define __pyx_n_s_momentXY __pyx_mstate_global->__pyx_n_s_momentXY +#define __pyx_n_u_momentXY __pyx_mstate_global->__pyx_n_u_momentXY +#define __pyx_n_s_momentY __pyx_mstate_global->__pyx_n_s_momentY +#define __pyx_n_u_momentY __pyx_mstate_global->__pyx_n_u_momentY +#define __pyx_n_s_momentYY __pyx_mstate_global->__pyx_n_s_momentYY +#define __pyx_n_u_momentYY __pyx_mstate_global->__pyx_n_u_momentYY +#define __pyx_n_s_moveTo __pyx_mstate_global->__pyx_n_s_moveTo +#define __pyx_n_s_mro_entries __pyx_mstate_global->__pyx_n_s_mro_entries +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_p0 __pyx_mstate_global->__pyx_n_s_p0 +#define __pyx_n_s_p1 __pyx_mstate_global->__pyx_n_s_p1 +#define __pyx_n_s_p2 __pyx_mstate_global->__pyx_n_s_p2 +#define __pyx_n_s_p3 __pyx_mstate_global->__pyx_n_s_p3 +#define __pyx_n_s_prepare __pyx_mstate_global->__pyx_n_s_prepare +#define __pyx_n_s_printGreenPen __pyx_mstate_global->__pyx_n_s_printGreenPen +#define __pyx_n_s_qCurveToOne __pyx_mstate_global->__pyx_n_s_qCurveToOne +#define __pyx_n_s_qualname __pyx_mstate_global->__pyx_n_s_qualname +#define __pyx_n_s_r0 __pyx_mstate_global->__pyx_n_s_r0 +#define __pyx_n_s_r1 __pyx_mstate_global->__pyx_n_s_r1 +#define __pyx_n_s_r10 __pyx_mstate_global->__pyx_n_s_r10 +#define __pyx_n_s_r100 __pyx_mstate_global->__pyx_n_s_r100 +#define __pyx_n_s_r101 __pyx_mstate_global->__pyx_n_s_r101 +#define __pyx_n_s_r102 __pyx_mstate_global->__pyx_n_s_r102 +#define __pyx_n_s_r103 __pyx_mstate_global->__pyx_n_s_r103 +#define __pyx_n_s_r104 __pyx_mstate_global->__pyx_n_s_r104 +#define __pyx_n_s_r105 __pyx_mstate_global->__pyx_n_s_r105 +#define __pyx_n_s_r106 __pyx_mstate_global->__pyx_n_s_r106 +#define __pyx_n_s_r107 __pyx_mstate_global->__pyx_n_s_r107 +#define __pyx_n_s_r108 __pyx_mstate_global->__pyx_n_s_r108 +#define __pyx_n_s_r109 __pyx_mstate_global->__pyx_n_s_r109 +#define __pyx_n_s_r11 __pyx_mstate_global->__pyx_n_s_r11 +#define __pyx_n_s_r110 __pyx_mstate_global->__pyx_n_s_r110 +#define __pyx_n_s_r111 __pyx_mstate_global->__pyx_n_s_r111 +#define __pyx_n_s_r112 __pyx_mstate_global->__pyx_n_s_r112 +#define __pyx_n_s_r113 __pyx_mstate_global->__pyx_n_s_r113 +#define __pyx_n_s_r114 __pyx_mstate_global->__pyx_n_s_r114 +#define __pyx_n_s_r115 __pyx_mstate_global->__pyx_n_s_r115 +#define __pyx_n_s_r116 __pyx_mstate_global->__pyx_n_s_r116 +#define __pyx_n_s_r117 __pyx_mstate_global->__pyx_n_s_r117 +#define __pyx_n_s_r118 __pyx_mstate_global->__pyx_n_s_r118 +#define __pyx_n_s_r119 __pyx_mstate_global->__pyx_n_s_r119 +#define __pyx_n_s_r12 __pyx_mstate_global->__pyx_n_s_r12 +#define __pyx_n_s_r120 __pyx_mstate_global->__pyx_n_s_r120 +#define __pyx_n_s_r121 __pyx_mstate_global->__pyx_n_s_r121 +#define __pyx_n_s_r122 __pyx_mstate_global->__pyx_n_s_r122 +#define __pyx_n_s_r123 __pyx_mstate_global->__pyx_n_s_r123 +#define __pyx_n_s_r124 __pyx_mstate_global->__pyx_n_s_r124 +#define __pyx_n_s_r125 __pyx_mstate_global->__pyx_n_s_r125 +#define __pyx_n_s_r126 __pyx_mstate_global->__pyx_n_s_r126 +#define __pyx_n_s_r127 __pyx_mstate_global->__pyx_n_s_r127 +#define __pyx_n_s_r128 __pyx_mstate_global->__pyx_n_s_r128 +#define __pyx_n_s_r129 __pyx_mstate_global->__pyx_n_s_r129 +#define __pyx_n_s_r13 __pyx_mstate_global->__pyx_n_s_r13 +#define __pyx_n_s_r130 __pyx_mstate_global->__pyx_n_s_r130 +#define __pyx_n_s_r131 __pyx_mstate_global->__pyx_n_s_r131 +#define __pyx_n_s_r132 __pyx_mstate_global->__pyx_n_s_r132 +#define __pyx_n_s_r14 __pyx_mstate_global->__pyx_n_s_r14 +#define __pyx_n_s_r15 __pyx_mstate_global->__pyx_n_s_r15 +#define __pyx_n_s_r16 __pyx_mstate_global->__pyx_n_s_r16 +#define __pyx_n_s_r17 __pyx_mstate_global->__pyx_n_s_r17 +#define __pyx_n_s_r18 __pyx_mstate_global->__pyx_n_s_r18 +#define __pyx_n_s_r19 __pyx_mstate_global->__pyx_n_s_r19 +#define __pyx_n_s_r2 __pyx_mstate_global->__pyx_n_s_r2 +#define __pyx_n_s_r20 __pyx_mstate_global->__pyx_n_s_r20 +#define __pyx_n_s_r21 __pyx_mstate_global->__pyx_n_s_r21 +#define __pyx_n_s_r22 __pyx_mstate_global->__pyx_n_s_r22 +#define __pyx_n_s_r23 __pyx_mstate_global->__pyx_n_s_r23 +#define __pyx_n_s_r24 __pyx_mstate_global->__pyx_n_s_r24 +#define __pyx_n_s_r25 __pyx_mstate_global->__pyx_n_s_r25 +#define __pyx_n_s_r26 __pyx_mstate_global->__pyx_n_s_r26 +#define __pyx_n_s_r27 __pyx_mstate_global->__pyx_n_s_r27 +#define __pyx_n_s_r28 __pyx_mstate_global->__pyx_n_s_r28 +#define __pyx_n_s_r29 __pyx_mstate_global->__pyx_n_s_r29 +#define __pyx_n_s_r3 __pyx_mstate_global->__pyx_n_s_r3 +#define __pyx_n_s_r30 __pyx_mstate_global->__pyx_n_s_r30 +#define __pyx_n_s_r31 __pyx_mstate_global->__pyx_n_s_r31 +#define __pyx_n_s_r32 __pyx_mstate_global->__pyx_n_s_r32 +#define __pyx_n_s_r33 __pyx_mstate_global->__pyx_n_s_r33 +#define __pyx_n_s_r34 __pyx_mstate_global->__pyx_n_s_r34 +#define __pyx_n_s_r35 __pyx_mstate_global->__pyx_n_s_r35 +#define __pyx_n_s_r36 __pyx_mstate_global->__pyx_n_s_r36 +#define __pyx_n_s_r37 __pyx_mstate_global->__pyx_n_s_r37 +#define __pyx_n_s_r38 __pyx_mstate_global->__pyx_n_s_r38 +#define __pyx_n_s_r39 __pyx_mstate_global->__pyx_n_s_r39 +#define __pyx_n_s_r4 __pyx_mstate_global->__pyx_n_s_r4 +#define __pyx_n_s_r40 __pyx_mstate_global->__pyx_n_s_r40 +#define __pyx_n_s_r41 __pyx_mstate_global->__pyx_n_s_r41 +#define __pyx_n_s_r42 __pyx_mstate_global->__pyx_n_s_r42 +#define __pyx_n_s_r43 __pyx_mstate_global->__pyx_n_s_r43 +#define __pyx_n_s_r44 __pyx_mstate_global->__pyx_n_s_r44 +#define __pyx_n_s_r45 __pyx_mstate_global->__pyx_n_s_r45 +#define __pyx_n_s_r46 __pyx_mstate_global->__pyx_n_s_r46 +#define __pyx_n_s_r47 __pyx_mstate_global->__pyx_n_s_r47 +#define __pyx_n_s_r48 __pyx_mstate_global->__pyx_n_s_r48 +#define __pyx_n_s_r49 __pyx_mstate_global->__pyx_n_s_r49 +#define __pyx_n_s_r5 __pyx_mstate_global->__pyx_n_s_r5 +#define __pyx_n_s_r50 __pyx_mstate_global->__pyx_n_s_r50 +#define __pyx_n_s_r51 __pyx_mstate_global->__pyx_n_s_r51 +#define __pyx_n_s_r52 __pyx_mstate_global->__pyx_n_s_r52 +#define __pyx_n_s_r53 __pyx_mstate_global->__pyx_n_s_r53 +#define __pyx_n_s_r54 __pyx_mstate_global->__pyx_n_s_r54 +#define __pyx_n_s_r55 __pyx_mstate_global->__pyx_n_s_r55 +#define __pyx_n_s_r56 __pyx_mstate_global->__pyx_n_s_r56 +#define __pyx_n_s_r57 __pyx_mstate_global->__pyx_n_s_r57 +#define __pyx_n_s_r58 __pyx_mstate_global->__pyx_n_s_r58 +#define __pyx_n_s_r59 __pyx_mstate_global->__pyx_n_s_r59 +#define __pyx_n_s_r6 __pyx_mstate_global->__pyx_n_s_r6 +#define __pyx_n_s_r60 __pyx_mstate_global->__pyx_n_s_r60 +#define __pyx_n_s_r61 __pyx_mstate_global->__pyx_n_s_r61 +#define __pyx_n_s_r62 __pyx_mstate_global->__pyx_n_s_r62 +#define __pyx_n_s_r63 __pyx_mstate_global->__pyx_n_s_r63 +#define __pyx_n_s_r64 __pyx_mstate_global->__pyx_n_s_r64 +#define __pyx_n_s_r65 __pyx_mstate_global->__pyx_n_s_r65 +#define __pyx_n_s_r66 __pyx_mstate_global->__pyx_n_s_r66 +#define __pyx_n_s_r67 __pyx_mstate_global->__pyx_n_s_r67 +#define __pyx_n_s_r68 __pyx_mstate_global->__pyx_n_s_r68 +#define __pyx_n_s_r69 __pyx_mstate_global->__pyx_n_s_r69 +#define __pyx_n_s_r7 __pyx_mstate_global->__pyx_n_s_r7 +#define __pyx_n_s_r70 __pyx_mstate_global->__pyx_n_s_r70 +#define __pyx_n_s_r71 __pyx_mstate_global->__pyx_n_s_r71 +#define __pyx_n_s_r72 __pyx_mstate_global->__pyx_n_s_r72 +#define __pyx_n_s_r73 __pyx_mstate_global->__pyx_n_s_r73 +#define __pyx_n_s_r74 __pyx_mstate_global->__pyx_n_s_r74 +#define __pyx_n_s_r75 __pyx_mstate_global->__pyx_n_s_r75 +#define __pyx_n_s_r76 __pyx_mstate_global->__pyx_n_s_r76 +#define __pyx_n_s_r77 __pyx_mstate_global->__pyx_n_s_r77 +#define __pyx_n_s_r78 __pyx_mstate_global->__pyx_n_s_r78 +#define __pyx_n_s_r79 __pyx_mstate_global->__pyx_n_s_r79 +#define __pyx_n_s_r8 __pyx_mstate_global->__pyx_n_s_r8 +#define __pyx_n_s_r80 __pyx_mstate_global->__pyx_n_s_r80 +#define __pyx_n_s_r81 __pyx_mstate_global->__pyx_n_s_r81 +#define __pyx_n_s_r82 __pyx_mstate_global->__pyx_n_s_r82 +#define __pyx_n_s_r83 __pyx_mstate_global->__pyx_n_s_r83 +#define __pyx_n_s_r84 __pyx_mstate_global->__pyx_n_s_r84 +#define __pyx_n_s_r85 __pyx_mstate_global->__pyx_n_s_r85 +#define __pyx_n_s_r86 __pyx_mstate_global->__pyx_n_s_r86 +#define __pyx_n_s_r87 __pyx_mstate_global->__pyx_n_s_r87 +#define __pyx_n_s_r88 __pyx_mstate_global->__pyx_n_s_r88 +#define __pyx_n_s_r89 __pyx_mstate_global->__pyx_n_s_r89 +#define __pyx_n_s_r9 __pyx_mstate_global->__pyx_n_s_r9 +#define __pyx_n_s_r90 __pyx_mstate_global->__pyx_n_s_r90 +#define __pyx_n_s_r91 __pyx_mstate_global->__pyx_n_s_r91 +#define __pyx_n_s_r92 __pyx_mstate_global->__pyx_n_s_r92 +#define __pyx_n_s_r93 __pyx_mstate_global->__pyx_n_s_r93 +#define __pyx_n_s_r94 __pyx_mstate_global->__pyx_n_s_r94 +#define __pyx_n_s_r95 __pyx_mstate_global->__pyx_n_s_r95 +#define __pyx_n_s_r96 __pyx_mstate_global->__pyx_n_s_r96 +#define __pyx_n_s_r97 __pyx_mstate_global->__pyx_n_s_r97 +#define __pyx_n_s_r98 __pyx_mstate_global->__pyx_n_s_r98 +#define __pyx_n_s_r99 __pyx_mstate_global->__pyx_n_s_r99 +#define __pyx_n_s_self __pyx_mstate_global->__pyx_n_s_self +#define __pyx_n_s_set_name __pyx_mstate_global->__pyx_n_s_set_name +#define __pyx_n_s_super __pyx_mstate_global->__pyx_n_s_super +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_x __pyx_mstate_global->__pyx_n_s_x +#define __pyx_n_s_x0 __pyx_mstate_global->__pyx_n_s_x0 +#define __pyx_n_s_x1 __pyx_mstate_global->__pyx_n_s_x1 +#define __pyx_n_s_x2 __pyx_mstate_global->__pyx_n_s_x2 +#define __pyx_n_s_x3 __pyx_mstate_global->__pyx_n_s_x3 +#define __pyx_n_s_y __pyx_mstate_global->__pyx_n_s_y +#define __pyx_n_s_y0 __pyx_mstate_global->__pyx_n_s_y0 +#define __pyx_n_s_y1 __pyx_mstate_global->__pyx_n_s_y1 +#define __pyx_n_s_y2 __pyx_mstate_global->__pyx_n_s_y2 +#define __pyx_n_s_y3 __pyx_mstate_global->__pyx_n_s_y3 +#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0 +#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 +#define __pyx_int_2 __pyx_mstate_global->__pyx_int_2 +#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 +#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 +#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 +#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 +#define __pyx_tuple__15 __pyx_mstate_global->__pyx_tuple__15 +#define __pyx_codeobj__3 __pyx_mstate_global->__pyx_codeobj__3 +#define __pyx_codeobj__6 __pyx_mstate_global->__pyx_codeobj__6 +#define __pyx_codeobj__7 __pyx_mstate_global->__pyx_codeobj__7 +#define __pyx_codeobj__8 __pyx_mstate_global->__pyx_codeobj__8 +#define __pyx_codeobj__10 __pyx_mstate_global->__pyx_codeobj__10 +#define __pyx_codeobj__12 __pyx_mstate_global->__pyx_codeobj__12 +#define __pyx_codeobj__14 __pyx_mstate_global->__pyx_codeobj__14 +/* #### Code section: module_code ### */ + +/* "fontTools/pens/momentsPen.py":18 + * + * class MomentsPen(BasePen): + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen___init__, "MomentsPen.__init__(self, glyphset=None)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__ = {"__init__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen___init__}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_glyphset = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_glyphset,0}; + values[1] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)Py_None)); + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 18, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_glyphset); + if (value) { values[1] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 18, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__init__") < 0)) __PYX_ERR(0, 18, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_self = values[0]; + __pyx_v_glyphset = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 2, __pyx_nargs); __PYX_ERR(0, 18, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(__pyx_self, __pyx_v_self, __pyx_v_glyphset); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_glyphset) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 1); + + /* "fontTools/pens/momentsPen.py":19 + * class MomentsPen(BasePen): + * def __init__(self, glyphset=None): + * BasePen.__init__(self, glyphset) # <<<<<<<<<<<<<< + * + * self.area = 0 + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_BasePen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_self, __pyx_v_glyphset}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":21 + * BasePen.__init__(self, glyphset) + * + * self.area = 0 # <<<<<<<<<<<<<< + * self.momentX = 0 + * self.momentY = 0 + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_area, __pyx_int_0) < 0) __PYX_ERR(0, 21, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":22 + * + * self.area = 0 + * self.momentX = 0 # <<<<<<<<<<<<<< + * self.momentY = 0 + * self.momentXX = 0 + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentX, __pyx_int_0) < 0) __PYX_ERR(0, 22, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":23 + * self.area = 0 + * self.momentX = 0 + * self.momentY = 0 # <<<<<<<<<<<<<< + * self.momentXX = 0 + * self.momentXY = 0 + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentY, __pyx_int_0) < 0) __PYX_ERR(0, 23, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":24 + * self.momentX = 0 + * self.momentY = 0 + * self.momentXX = 0 # <<<<<<<<<<<<<< + * self.momentXY = 0 + * self.momentYY = 0 + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXX, __pyx_int_0) < 0) __PYX_ERR(0, 24, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":25 + * self.momentY = 0 + * self.momentXX = 0 + * self.momentXY = 0 # <<<<<<<<<<<<<< + * self.momentYY = 0 + * + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXY, __pyx_int_0) < 0) __PYX_ERR(0, 25, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":26 + * self.momentXX = 0 + * self.momentXY = 0 + * self.momentYY = 0 # <<<<<<<<<<<<<< + * + * def _moveTo(self, p0): + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentYY, __pyx_int_0) < 0) __PYX_ERR(0, 26, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":18 + * + * class MomentsPen(BasePen): + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":28 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self.__startPoint = p0 + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo, "MomentsPen._moveTo(self, p0)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo = {"_moveTo", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p0 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_moveTo (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_p0,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 28, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p0)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 28, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_moveTo", 1, 2, 2, 1); __PYX_ERR(0, 28, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_moveTo") < 0)) __PYX_ERR(0, 28, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_self = values[0]; + __pyx_v_p0 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_moveTo", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 28, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._moveTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(__pyx_self, __pyx_v_self, __pyx_v_p0); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p0) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_moveTo", 1); + + /* "fontTools/pens/momentsPen.py":29 + * + * def _moveTo(self, p0): + * self.__startPoint = p0 # <<<<<<<<<<<<<< + * + * def _closePath(self): + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_MomentsPen__startPoint, __pyx_v_p0) < 0) __PYX_ERR(0, 29, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":28 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self.__startPoint = p0 + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._moveTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":31 + * self.__startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath, "MomentsPen._closePath(self)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath = {"_closePath", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_closePath (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 31, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_closePath") < 0)) __PYX_ERR(0, 31, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_closePath", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 31, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._closePath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(__pyx_self, __pyx_v_self); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_p0 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_closePath", 1); + + /* "fontTools/pens/momentsPen.py":32 + * + * def _closePath(self): + * p0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * if p0 != self.__startPoint: + * self._lineTo(self.__startPoint) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_getCurrentPoint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_p0 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":33 + * def _closePath(self): + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: # <<<<<<<<<<<<<< + * self._lineTo(self.__startPoint) + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_MomentsPen__startPoint); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_p0, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/pens/momentsPen.py":34 + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + * self._lineTo(self.__startPoint) # <<<<<<<<<<<<<< + * + * def _endPath(self): + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_lineTo); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_MomentsPen__startPoint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_3}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":33 + * def _closePath(self): + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: # <<<<<<<<<<<<<< + * self._lineTo(self.__startPoint) + * + */ + } + + /* "fontTools/pens/momentsPen.py":31 + * self.__startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._closePath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p0); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":36 + * self._lineTo(self.__startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath, "MomentsPen._endPath(self)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath = {"_endPath", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_endPath (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 36, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_endPath") < 0)) __PYX_ERR(0, 36, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_endPath", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 36, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._endPath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(__pyx_self, __pyx_v_self); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_p0 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_endPath", 1); + + /* "fontTools/pens/momentsPen.py":37 + * + * def _endPath(self): + * p0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * if p0 != self.__startPoint: + * raise OpenContourError("Glyph statistics not defined on open contours.") + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_getCurrentPoint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_p0 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":38 + * def _endPath(self): + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: # <<<<<<<<<<<<<< + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_MomentsPen__startPoint); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_p0, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(__pyx_t_5)) { + + /* "fontTools/pens/momentsPen.py":39 + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + * raise OpenContourError("Glyph statistics not defined on open contours.") # <<<<<<<<<<<<<< + * + * @cython.locals(r0=cython.double) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_OpenContourError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_kp_u_Glyph_statistics_not_defined_on}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 39, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":38 + * def _endPath(self): + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: # <<<<<<<<<<<<<< + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + */ + } + + /* "fontTools/pens/momentsPen.py":36 + * self._lineTo(self.__startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._endPath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p0); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":41 + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo, "MomentsPen._lineTo(self, p1)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo = {"_lineTo", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_lineTo (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_p1,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 41, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 41, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_lineTo", 1, 2, 2, 1); __PYX_ERR(0, 41, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_lineTo") < 0)) __PYX_ERR(0, 41, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_lineTo", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 41, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._lineTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(__pyx_self, __pyx_v_self, __pyx_v_p1); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1) { + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_lineTo", 1); + + /* "fontTools/pens/momentsPen.py":57 + * @cython.locals(x1=cython.double, y1=cython.double) + * def _lineTo(self, p1): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_getCurrentPoint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 57, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 57, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":58 + * def _lineTo(self, p1): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * + * r0 = x1 * y0 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 58, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 58, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 58, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":60 + * x1, y1 = p1 + * + * r0 = x1 * y0 # <<<<<<<<<<<<<< + * r1 = x1 * y1 + * r2 = x1**2 + */ + __pyx_v_r0 = (__pyx_v_x1 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":61 + * + * r0 = x1 * y0 + * r1 = x1 * y1 # <<<<<<<<<<<<<< + * r2 = x1**2 + * r3 = r2 * y1 + */ + __pyx_v_r1 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":62 + * r0 = x1 * y0 + * r1 = x1 * y1 + * r2 = x1**2 # <<<<<<<<<<<<<< + * r3 = r2 * y1 + * r4 = y0 - y1 + */ + __pyx_v_r2 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":63 + * r1 = x1 * y1 + * r2 = x1**2 + * r3 = r2 * y1 # <<<<<<<<<<<<<< + * r4 = y0 - y1 + * r5 = r4 * x0 + */ + __pyx_v_r3 = (__pyx_v_r2 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":64 + * r2 = x1**2 + * r3 = r2 * y1 + * r4 = y0 - y1 # <<<<<<<<<<<<<< + * r5 = r4 * x0 + * r6 = x0**2 + */ + __pyx_v_r4 = (__pyx_v_y0 - __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":65 + * r3 = r2 * y1 + * r4 = y0 - y1 + * r5 = r4 * x0 # <<<<<<<<<<<<<< + * r6 = x0**2 + * r7 = 2 * y0 + */ + __pyx_v_r5 = (__pyx_v_r4 * __pyx_v_x0); + + /* "fontTools/pens/momentsPen.py":66 + * r4 = y0 - y1 + * r5 = r4 * x0 + * r6 = x0**2 # <<<<<<<<<<<<<< + * r7 = 2 * y0 + * r8 = y0**2 + */ + __pyx_v_r6 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":67 + * r5 = r4 * x0 + * r6 = x0**2 + * r7 = 2 * y0 # <<<<<<<<<<<<<< + * r8 = y0**2 + * r9 = y1**2 + */ + __pyx_v_r7 = (2.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":68 + * r6 = x0**2 + * r7 = 2 * y0 + * r8 = y0**2 # <<<<<<<<<<<<<< + * r9 = y1**2 + * r10 = x1**3 + */ + __pyx_v_r8 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":69 + * r7 = 2 * y0 + * r8 = y0**2 + * r9 = y1**2 # <<<<<<<<<<<<<< + * r10 = x1**3 + * r11 = y0**3 + */ + __pyx_v_r9 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":70 + * r8 = y0**2 + * r9 = y1**2 + * r10 = x1**3 # <<<<<<<<<<<<<< + * r11 = y0**3 + * r12 = y1**3 + */ + __pyx_v_r10 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":71 + * r9 = y1**2 + * r10 = x1**3 + * r11 = y0**3 # <<<<<<<<<<<<<< + * r12 = y1**3 + * + */ + __pyx_v_r11 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":72 + * r10 = x1**3 + * r11 = y0**3 + * r12 = y1**3 # <<<<<<<<<<<<<< + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + */ + __pyx_v_r12 = pow(__pyx_v_y1, 3.0); + + /* "fontTools/pens/momentsPen.py":74 + * r12 = y1**3 + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 # <<<<<<<<<<<<<< + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_area); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyFloat_FromDouble(((((-__pyx_v_r0) / 2.0) - (__pyx_v_r1 / 2.0)) + ((__pyx_v_x0 * (__pyx_v_y0 + __pyx_v_y1)) / 2.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_area, __pyx_t_2) < 0) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":75 + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 # <<<<<<<<<<<<<< + * self.momentY += ( + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyFloat_FromDouble(((((((-__pyx_v_r2) * __pyx_v_y0) / 6.0) - (__pyx_v_r3 / 3.0)) - ((__pyx_v_r5 * __pyx_v_x1) / 6.0)) + ((__pyx_v_r6 * (__pyx_v_r7 + __pyx_v_y1)) / 6.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentX, __pyx_t_3) < 0) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":76 + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( # <<<<<<<<<<<<<< + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentY); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":77 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( + */ + __pyx_t_1 = PyFloat_FromDouble(((((((-__pyx_v_r0) * __pyx_v_y1) / 6.0) - ((__pyx_v_r8 * __pyx_v_x1) / 6.0)) - ((__pyx_v_r9 * __pyx_v_x1) / 6.0)) + ((__pyx_v_x0 * ((__pyx_v_r8 + __pyx_v_r9) + (__pyx_v_y0 * __pyx_v_y1))) / 6.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":76 + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( # <<<<<<<<<<<<<< + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentY, __pyx_t_2) < 0) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":79 + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r10 * y0 / 12 + * - r10 * y1 / 4 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":84 + * - r2 * r5 / 12 + * - r4 * r6 * x1 / 12 + * + x0**3 * (3 * y0 + y1) / 12 # <<<<<<<<<<<<<< + * ) + * self.momentXY += ( + */ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r10) * __pyx_v_y0) / 12.0) - ((__pyx_v_r10 * __pyx_v_y1) / 4.0)) - ((__pyx_v_r2 * __pyx_v_r5) / 12.0)) - (((__pyx_v_r4 * __pyx_v_r6) * __pyx_v_x1) / 12.0)) + ((pow(__pyx_v_x0, 3.0) * ((3.0 * __pyx_v_y0) + __pyx_v_y1)) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":79 + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r10 * y0 / 12 + * - r10 * y1 / 4 + */ + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXX, __pyx_t_3) < 0) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":86 + * + x0**3 * (3 * y0 + y1) / 12 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r2 * r8 / 24 + * - r2 * r9 / 8 + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXY); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":91 + * - r3 * r7 / 24 + * + r6 * (r7 * y1 + 3 * r8 + r9) / 24 + * - x0 * x1 * (r8 - r9) / 12 # <<<<<<<<<<<<<< + * ) + * self.momentYY += ( + */ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r2) * __pyx_v_r8) / 24.0) - ((__pyx_v_r2 * __pyx_v_r9) / 8.0)) - ((__pyx_v_r3 * __pyx_v_r7) / 24.0)) + ((__pyx_v_r6 * (((__pyx_v_r7 * __pyx_v_y1) + (3.0 * __pyx_v_r8)) + __pyx_v_r9)) / 24.0)) - (((__pyx_v_x0 * __pyx_v_x1) * (__pyx_v_r8 - __pyx_v_r9)) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":86 + * + x0**3 * (3 * y0 + y1) / 12 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r2 * r8 / 24 + * - r2 * r9 / 8 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXY, __pyx_t_2) < 0) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":93 + * - x0 * x1 * (r8 - r9) / 12 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r0 * r9 / 12 + * - r1 * r8 / 12 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":98 + * - r11 * x1 / 12 + * - r12 * x1 / 12 + * + x0 * (r11 + r12 + r8 * y1 + r9 * y0) / 12 # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r0) * __pyx_v_r9) / 12.0) - ((__pyx_v_r1 * __pyx_v_r8) / 12.0)) - ((__pyx_v_r11 * __pyx_v_x1) / 12.0)) - ((__pyx_v_r12 * __pyx_v_x1) / 12.0)) + ((__pyx_v_x0 * (((__pyx_v_r11 + __pyx_v_r12) + (__pyx_v_r8 * __pyx_v_y1)) + (__pyx_v_r9 * __pyx_v_y0))) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":93 + * - x0 * x1 * (r8 - r9) / 12 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r0 * r9 / 12 + * - r1 * r8 / 12 + */ + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentYY, __pyx_t_3) < 0) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":41 + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._lineTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":101 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne, "MomentsPen._qCurveToOne(self, p1, p2)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne = {"_qCurveToOne", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_qCurveToOne (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_p1,&__pyx_n_s_p2,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 101, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 101, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_qCurveToOne", 1, 3, 3, 1); __PYX_ERR(0, 101, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 101, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_qCurveToOne", 1, 3, 3, 2); __PYX_ERR(0, 101, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_qCurveToOne") < 0)) __PYX_ERR(0, 101, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_qCurveToOne", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 101, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._qCurveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(__pyx_self, __pyx_v_self, __pyx_v_p1, __pyx_v_p2); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2) { + double __pyx_v_x2; + double __pyx_v_y2; + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r53; + double __pyx_v_r52; + double __pyx_v_r51; + double __pyx_v_r50; + double __pyx_v_r49; + double __pyx_v_r48; + double __pyx_v_r47; + double __pyx_v_r46; + double __pyx_v_r45; + double __pyx_v_r44; + double __pyx_v_r43; + double __pyx_v_r42; + double __pyx_v_r41; + double __pyx_v_r40; + double __pyx_v_r39; + double __pyx_v_r38; + double __pyx_v_r37; + double __pyx_v_r36; + double __pyx_v_r35; + double __pyx_v_r34; + double __pyx_v_r33; + double __pyx_v_r32; + double __pyx_v_r31; + double __pyx_v_r30; + double __pyx_v_r29; + double __pyx_v_r28; + double __pyx_v_r27; + double __pyx_v_r26; + double __pyx_v_r25; + double __pyx_v_r24; + double __pyx_v_r23; + double __pyx_v_r22; + double __pyx_v_r21; + double __pyx_v_r20; + double __pyx_v_r19; + double __pyx_v_r18; + double __pyx_v_r17; + double __pyx_v_r16; + double __pyx_v_r15; + double __pyx_v_r14; + double __pyx_v_r13; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_qCurveToOne", 1); + + /* "fontTools/pens/momentsPen.py":159 + * @cython.locals(x2=cython.double, y2=cython.double) + * def _qCurveToOne(self, p1, p2): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * x2, y2 = p2 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_getCurrentPoint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 159, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 159, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 159, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":160 + * def _qCurveToOne(self, p1, p2): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * x2, y2 = p2 + * + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 160, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 160, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 160, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":161 + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 + * x2, y2 = p2 # <<<<<<<<<<<<<< + * + * r0 = 2 * y1 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p2))) || (PyList_CheckExact(__pyx_v_p2))) { + PyObject* sequence = __pyx_v_p2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 161, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 161, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 161, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 161, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_7; + __pyx_v_y2 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":163 + * x2, y2 = p2 + * + * r0 = 2 * y1 # <<<<<<<<<<<<<< + * r1 = r0 * x2 + * r2 = x2 * y2 + */ + __pyx_v_r0 = (2.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":164 + * + * r0 = 2 * y1 + * r1 = r0 * x2 # <<<<<<<<<<<<<< + * r2 = x2 * y2 + * r3 = 3 * r2 + */ + __pyx_v_r1 = (__pyx_v_r0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":165 + * r0 = 2 * y1 + * r1 = r0 * x2 + * r2 = x2 * y2 # <<<<<<<<<<<<<< + * r3 = 3 * r2 + * r4 = 2 * x1 + */ + __pyx_v_r2 = (__pyx_v_x2 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":166 + * r1 = r0 * x2 + * r2 = x2 * y2 + * r3 = 3 * r2 # <<<<<<<<<<<<<< + * r4 = 2 * x1 + * r5 = 3 * y0 + */ + __pyx_v_r3 = (3.0 * __pyx_v_r2); + + /* "fontTools/pens/momentsPen.py":167 + * r2 = x2 * y2 + * r3 = 3 * r2 + * r4 = 2 * x1 # <<<<<<<<<<<<<< + * r5 = 3 * y0 + * r6 = x1**2 + */ + __pyx_v_r4 = (2.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":168 + * r3 = 3 * r2 + * r4 = 2 * x1 + * r5 = 3 * y0 # <<<<<<<<<<<<<< + * r6 = x1**2 + * r7 = x2**2 + */ + __pyx_v_r5 = (3.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":169 + * r4 = 2 * x1 + * r5 = 3 * y0 + * r6 = x1**2 # <<<<<<<<<<<<<< + * r7 = x2**2 + * r8 = 4 * y1 + */ + __pyx_v_r6 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":170 + * r5 = 3 * y0 + * r6 = x1**2 + * r7 = x2**2 # <<<<<<<<<<<<<< + * r8 = 4 * y1 + * r9 = 10 * y2 + */ + __pyx_v_r7 = pow(__pyx_v_x2, 2.0); + + /* "fontTools/pens/momentsPen.py":171 + * r6 = x1**2 + * r7 = x2**2 + * r8 = 4 * y1 # <<<<<<<<<<<<<< + * r9 = 10 * y2 + * r10 = 2 * y2 + */ + __pyx_v_r8 = (4.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":172 + * r7 = x2**2 + * r8 = 4 * y1 + * r9 = 10 * y2 # <<<<<<<<<<<<<< + * r10 = 2 * y2 + * r11 = r4 * x2 + */ + __pyx_v_r9 = (10.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":173 + * r8 = 4 * y1 + * r9 = 10 * y2 + * r10 = 2 * y2 # <<<<<<<<<<<<<< + * r11 = r4 * x2 + * r12 = x0**2 + */ + __pyx_v_r10 = (2.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":174 + * r9 = 10 * y2 + * r10 = 2 * y2 + * r11 = r4 * x2 # <<<<<<<<<<<<<< + * r12 = x0**2 + * r13 = 10 * y0 + */ + __pyx_v_r11 = (__pyx_v_r4 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":175 + * r10 = 2 * y2 + * r11 = r4 * x2 + * r12 = x0**2 # <<<<<<<<<<<<<< + * r13 = 10 * y0 + * r14 = r4 * y2 + */ + __pyx_v_r12 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":176 + * r11 = r4 * x2 + * r12 = x0**2 + * r13 = 10 * y0 # <<<<<<<<<<<<<< + * r14 = r4 * y2 + * r15 = x2 * y0 + */ + __pyx_v_r13 = (10.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":177 + * r12 = x0**2 + * r13 = 10 * y0 + * r14 = r4 * y2 # <<<<<<<<<<<<<< + * r15 = x2 * y0 + * r16 = 4 * x1 + */ + __pyx_v_r14 = (__pyx_v_r4 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":178 + * r13 = 10 * y0 + * r14 = r4 * y2 + * r15 = x2 * y0 # <<<<<<<<<<<<<< + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 + */ + __pyx_v_r15 = (__pyx_v_x2 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":179 + * r14 = r4 * y2 + * r15 = x2 * y0 + * r16 = 4 * x1 # <<<<<<<<<<<<<< + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 + */ + __pyx_v_r16 = (4.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":180 + * r15 = x2 * y0 + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 # <<<<<<<<<<<<<< + * r18 = r2 * r8 + * r19 = y1**2 + */ + __pyx_v_r17 = ((__pyx_v_r0 * __pyx_v_x1) + __pyx_v_r2); + + /* "fontTools/pens/momentsPen.py":181 + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 # <<<<<<<<<<<<<< + * r19 = y1**2 + * r20 = 2 * r19 + */ + __pyx_v_r18 = (__pyx_v_r2 * __pyx_v_r8); + + /* "fontTools/pens/momentsPen.py":182 + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 + * r19 = y1**2 # <<<<<<<<<<<<<< + * r20 = 2 * r19 + * r21 = y2**2 + */ + __pyx_v_r19 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":183 + * r18 = r2 * r8 + * r19 = y1**2 + * r20 = 2 * r19 # <<<<<<<<<<<<<< + * r21 = y2**2 + * r22 = r21 * x2 + */ + __pyx_v_r20 = (2.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":184 + * r19 = y1**2 + * r20 = 2 * r19 + * r21 = y2**2 # <<<<<<<<<<<<<< + * r22 = r21 * x2 + * r23 = 5 * r22 + */ + __pyx_v_r21 = pow(__pyx_v_y2, 2.0); + + /* "fontTools/pens/momentsPen.py":185 + * r20 = 2 * r19 + * r21 = y2**2 + * r22 = r21 * x2 # <<<<<<<<<<<<<< + * r23 = 5 * r22 + * r24 = y0**2 + */ + __pyx_v_r22 = (__pyx_v_r21 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":186 + * r21 = y2**2 + * r22 = r21 * x2 + * r23 = 5 * r22 # <<<<<<<<<<<<<< + * r24 = y0**2 + * r25 = y0 * y2 + */ + __pyx_v_r23 = (5.0 * __pyx_v_r22); + + /* "fontTools/pens/momentsPen.py":187 + * r22 = r21 * x2 + * r23 = 5 * r22 + * r24 = y0**2 # <<<<<<<<<<<<<< + * r25 = y0 * y2 + * r26 = 5 * r24 + */ + __pyx_v_r24 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":188 + * r23 = 5 * r22 + * r24 = y0**2 + * r25 = y0 * y2 # <<<<<<<<<<<<<< + * r26 = 5 * r24 + * r27 = x1**3 + */ + __pyx_v_r25 = (__pyx_v_y0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":189 + * r24 = y0**2 + * r25 = y0 * y2 + * r26 = 5 * r24 # <<<<<<<<<<<<<< + * r27 = x1**3 + * r28 = x2**3 + */ + __pyx_v_r26 = (5.0 * __pyx_v_r24); + + /* "fontTools/pens/momentsPen.py":190 + * r25 = y0 * y2 + * r26 = 5 * r24 + * r27 = x1**3 # <<<<<<<<<<<<<< + * r28 = x2**3 + * r29 = 30 * y1 + */ + __pyx_v_r27 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":191 + * r26 = 5 * r24 + * r27 = x1**3 + * r28 = x2**3 # <<<<<<<<<<<<<< + * r29 = 30 * y1 + * r30 = 6 * y1 + */ + __pyx_v_r28 = pow(__pyx_v_x2, 3.0); + + /* "fontTools/pens/momentsPen.py":192 + * r27 = x1**3 + * r28 = x2**3 + * r29 = 30 * y1 # <<<<<<<<<<<<<< + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 + */ + __pyx_v_r29 = (30.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":193 + * r28 = x2**3 + * r29 = 30 * y1 + * r30 = 6 * y1 # <<<<<<<<<<<<<< + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 + */ + __pyx_v_r30 = (6.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":194 + * r29 = 30 * y1 + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 # <<<<<<<<<<<<<< + * r32 = 5 * y2 + * r33 = 12 * r6 + */ + __pyx_v_r31 = ((10.0 * __pyx_v_r7) * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":195 + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 # <<<<<<<<<<<<<< + * r33 = 12 * r6 + * r34 = 30 * x1 + */ + __pyx_v_r32 = (5.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":196 + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 + * r33 = 12 * r6 # <<<<<<<<<<<<<< + * r34 = 30 * x1 + * r35 = x1 * y1 + */ + __pyx_v_r33 = (12.0 * __pyx_v_r6); + + /* "fontTools/pens/momentsPen.py":197 + * r32 = 5 * y2 + * r33 = 12 * r6 + * r34 = 30 * x1 # <<<<<<<<<<<<<< + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 + */ + __pyx_v_r34 = (30.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":198 + * r33 = 12 * r6 + * r34 = 30 * x1 + * r35 = x1 * y1 # <<<<<<<<<<<<<< + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 + */ + __pyx_v_r35 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":199 + * r34 = 30 * x1 + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 # <<<<<<<<<<<<<< + * r37 = 12 * x1 + * r38 = 20 * r6 + */ + __pyx_v_r36 = (__pyx_v_r3 + (20.0 * __pyx_v_r35)); + + /* "fontTools/pens/momentsPen.py":200 + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 # <<<<<<<<<<<<<< + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 + */ + __pyx_v_r37 = (12.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":201 + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 + * r38 = 20 * r6 # <<<<<<<<<<<<<< + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 + */ + __pyx_v_r38 = (20.0 * __pyx_v_r6); + + /* "fontTools/pens/momentsPen.py":202 + * r37 = 12 * x1 + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 # <<<<<<<<<<<<<< + * r40 = r32 * r7 + * r41 = 60 * y1 + */ + __pyx_v_r39 = ((8.0 * __pyx_v_r6) * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":203 + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 # <<<<<<<<<<<<<< + * r41 = 60 * y1 + * r42 = 20 * r19 + */ + __pyx_v_r40 = (__pyx_v_r32 * __pyx_v_r7); + + /* "fontTools/pens/momentsPen.py":204 + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 + * r41 = 60 * y1 # <<<<<<<<<<<<<< + * r42 = 20 * r19 + * r43 = 4 * r19 + */ + __pyx_v_r41 = (60.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":205 + * r40 = r32 * r7 + * r41 = 60 * y1 + * r42 = 20 * r19 # <<<<<<<<<<<<<< + * r43 = 4 * r19 + * r44 = 15 * r21 + */ + __pyx_v_r42 = (20.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":206 + * r41 = 60 * y1 + * r42 = 20 * r19 + * r43 = 4 * r19 # <<<<<<<<<<<<<< + * r44 = 15 * r21 + * r45 = 12 * x2 + */ + __pyx_v_r43 = (4.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":207 + * r42 = 20 * r19 + * r43 = 4 * r19 + * r44 = 15 * r21 # <<<<<<<<<<<<<< + * r45 = 12 * x2 + * r46 = 12 * y2 + */ + __pyx_v_r44 = (15.0 * __pyx_v_r21); + + /* "fontTools/pens/momentsPen.py":208 + * r43 = 4 * r19 + * r44 = 15 * r21 + * r45 = 12 * x2 # <<<<<<<<<<<<<< + * r46 = 12 * y2 + * r47 = 6 * x1 + */ + __pyx_v_r45 = (12.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":209 + * r44 = 15 * r21 + * r45 = 12 * x2 + * r46 = 12 * y2 # <<<<<<<<<<<<<< + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 + */ + __pyx_v_r46 = (12.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":210 + * r45 = 12 * x2 + * r46 = 12 * y2 + * r47 = 6 * x1 # <<<<<<<<<<<<<< + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 + */ + __pyx_v_r47 = (6.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":211 + * r46 = 12 * y2 + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 # <<<<<<<<<<<<<< + * r49 = 8 * y1**3 + * r50 = y2**3 + */ + __pyx_v_r48 = (((8.0 * __pyx_v_r19) * __pyx_v_x1) + __pyx_v_r23); + + /* "fontTools/pens/momentsPen.py":212 + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 # <<<<<<<<<<<<<< + * r50 = y2**3 + * r51 = y0**3 + */ + __pyx_v_r49 = (8.0 * pow(__pyx_v_y1, 3.0)); + + /* "fontTools/pens/momentsPen.py":213 + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 + * r50 = y2**3 # <<<<<<<<<<<<<< + * r51 = y0**3 + * r52 = 10 * y1 + */ + __pyx_v_r50 = pow(__pyx_v_y2, 3.0); + + /* "fontTools/pens/momentsPen.py":214 + * r49 = 8 * y1**3 + * r50 = y2**3 + * r51 = y0**3 # <<<<<<<<<<<<<< + * r52 = 10 * y1 + * r53 = 12 * y1 + */ + __pyx_v_r51 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":215 + * r50 = y2**3 + * r51 = y0**3 + * r52 = 10 * y1 # <<<<<<<<<<<<<< + * r53 = 12 * y1 + * + */ + __pyx_v_r52 = (10.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":216 + * r51 = y0**3 + * r52 = 10 * y1 + * r53 = 12 * y1 # <<<<<<<<<<<<<< + * + * self.area += ( + */ + __pyx_v_r53 = (12.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":218 + * r53 = 12 * y1 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 6 + * - r3 / 6 + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_area); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":223 + * + x0 * (r0 + r5 + y2) / 6 + * + x1 * y2 / 3 + * - y0 * (r4 + x2) / 6 # <<<<<<<<<<<<<< + * ) + * self.momentX += ( + */ + __pyx_t_3 = PyFloat_FromDouble(((((((-__pyx_v_r1) / 6.0) - (__pyx_v_r3 / 6.0)) + ((__pyx_v_x0 * ((__pyx_v_r0 + __pyx_v_r5) + __pyx_v_y2)) / 6.0)) + ((__pyx_v_x1 * __pyx_v_y2) / 3.0)) - ((__pyx_v_y0 * (__pyx_v_r4 + __pyx_v_x2)) / 6.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":218 + * r53 = 12 * y1 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 6 + * - r3 / 6 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_area, __pyx_t_2) < 0) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":225 + * - y0 * (r4 + x2) / 6 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * -r11 * (-r10 + y1) / 30 + * + r12 * (r13 + r8 + y2) / 30 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":232 + * - r7 * r9 / 30 + * + x0 * (r14 - r15 - r16 * y0 + r17) / 30 + * - y0 * (r11 + 2 * r6 + r7) / 30 # <<<<<<<<<<<<<< + * ) + * self.momentY += ( + */ + __pyx_t_3 = PyFloat_FromDouble((((((((((-__pyx_v_r11) * ((-__pyx_v_r10) + __pyx_v_y1)) / 30.0) + ((__pyx_v_r12 * ((__pyx_v_r13 + __pyx_v_r8) + __pyx_v_y2)) / 30.0)) + ((__pyx_v_r6 * __pyx_v_y2) / 15.0)) - ((__pyx_v_r7 * __pyx_v_r8) / 30.0)) - ((__pyx_v_r7 * __pyx_v_r9) / 30.0)) + ((__pyx_v_x0 * (((__pyx_v_r14 - __pyx_v_r15) - (__pyx_v_r16 * __pyx_v_y0)) + __pyx_v_r17)) / 30.0)) - ((__pyx_v_y0 * ((__pyx_v_r11 + (2.0 * __pyx_v_r6)) + __pyx_v_r7)) / 30.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":225 + * - y0 * (r4 + x2) / 6 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * -r11 * (-r10 + y1) / 30 + * + r12 * (r13 + r8 + y2) / 30 + */ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentX, __pyx_t_1) < 0) __PYX_ERR(0, 225, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":234 + * - y0 * (r11 + 2 * r6 + r7) / 30 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r18 / 30 + * - r20 * x2 / 30 + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentY); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":241 + * + x0 * (r0 * y2 + r20 + r21 + r25 + r26 + r8 * y0) / 30 + * + x1 * y2 * (r10 + y1) / 15 + * - y0 * (r1 + r17) / 30 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( + */ + __pyx_t_3 = PyFloat_FromDouble(((((((((-__pyx_v_r18) / 30.0) - ((__pyx_v_r20 * __pyx_v_x2) / 30.0)) - (__pyx_v_r23 / 30.0)) - ((__pyx_v_r24 * (__pyx_v_r16 + __pyx_v_x2)) / 30.0)) + ((__pyx_v_x0 * ((((((__pyx_v_r0 * __pyx_v_y2) + __pyx_v_r20) + __pyx_v_r21) + __pyx_v_r25) + __pyx_v_r26) + (__pyx_v_r8 * __pyx_v_y0))) / 30.0)) + (((__pyx_v_x1 * __pyx_v_y2) * (__pyx_v_r10 + __pyx_v_y1)) / 15.0)) - ((__pyx_v_y0 * (__pyx_v_r1 + __pyx_v_r17)) / 30.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":234 + * - y0 * (r11 + 2 * r6 + r7) / 30 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r18 / 30 + * - r20 * x2 / 30 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentY, __pyx_t_2) < 0) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":243 + * - y0 * (r1 + r17) / 30 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420 + * + 2 * r27 * y2 / 105 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":263 + * ) + * / 420 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 # <<<<<<<<<<<<<< + * ) + * self.momentXY += ( + */ + __pyx_t_3 = PyFloat_FromDouble(((((((((((__pyx_v_r12 * ((((__pyx_v_r1 - (5.0 * __pyx_v_r15)) - (__pyx_v_r34 * __pyx_v_y0)) + __pyx_v_r36) + (__pyx_v_r9 * __pyx_v_x1))) / 420.0) + (((2.0 * __pyx_v_r27) * __pyx_v_y2) / 105.0)) - ((__pyx_v_r28 * __pyx_v_r29) / 420.0)) - ((__pyx_v_r28 * __pyx_v_y2) / 4.0)) - ((__pyx_v_r31 * (__pyx_v_r0 - (3.0 * __pyx_v_y2))) / 420.0)) - (((__pyx_v_r6 * __pyx_v_x2) * (__pyx_v_r0 - __pyx_v_r32)) / 105.0)) + ((pow(__pyx_v_x0, 3.0) * ((__pyx_v_r30 + (21.0 * __pyx_v_y0)) + __pyx_v_y2)) / 84.0)) - ((__pyx_v_x0 * ((((((((__pyx_v_r0 * __pyx_v_r7) + (__pyx_v_r15 * __pyx_v_r37)) - (__pyx_v_r2 * __pyx_v_r37)) - (__pyx_v_r33 * __pyx_v_y2)) + (__pyx_v_r38 * __pyx_v_y0)) - __pyx_v_r39) - __pyx_v_r40) + (__pyx_v_r5 * __pyx_v_r7))) / 420.0)) - ((__pyx_v_y0 * ((((8.0 * __pyx_v_r27) + (5.0 * __pyx_v_r28)) + __pyx_v_r31) + (__pyx_v_r33 * __pyx_v_x2))) / 420.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":243 + * - y0 * (r1 + r17) / 30 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420 + * + 2 * r27 * y2 / 105 + */ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXX, __pyx_t_1) < 0) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":265 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840 + * - r16 * x2 * (r43 - r44) / 840 + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXY); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 265, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":285 + * ) + * / 420 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 # <<<<<<<<<<<<<< + * ) + * self.momentYY += ( + */ + __pyx_t_3 = PyFloat_FromDouble(((((((((((__pyx_v_r12 * ((((((__pyx_v_r13 * __pyx_v_y2) + (3.0 * __pyx_v_r21)) + (105.0 * __pyx_v_r24)) + (__pyx_v_r41 * __pyx_v_y0)) + __pyx_v_r42) + (__pyx_v_r46 * __pyx_v_y1))) / 840.0) - (((__pyx_v_r16 * __pyx_v_x2) * (__pyx_v_r43 - __pyx_v_r44)) / 840.0)) - ((__pyx_v_r21 * __pyx_v_r7) / 8.0)) - ((__pyx_v_r24 * ((__pyx_v_r38 + (__pyx_v_r45 * __pyx_v_x1)) + (3.0 * __pyx_v_r7))) / 840.0)) - (((__pyx_v_r41 * __pyx_v_r7) * __pyx_v_y2) / 840.0)) - ((__pyx_v_r42 * __pyx_v_r7) / 840.0)) + (((__pyx_v_r6 * __pyx_v_y2) * (__pyx_v_r32 + __pyx_v_r8)) / 210.0)) + ((__pyx_v_x0 * (((((((((-__pyx_v_r15) * __pyx_v_r8) + (__pyx_v_r16 * __pyx_v_r25)) + __pyx_v_r18) + (__pyx_v_r21 * __pyx_v_r47)) - (__pyx_v_r24 * __pyx_v_r34)) - (__pyx_v_r26 * __pyx_v_x2)) + (__pyx_v_r35 * __pyx_v_r46)) + __pyx_v_r48)) / 420.0)) - ((__pyx_v_y0 * (((((__pyx_v_r16 * __pyx_v_r2) + (__pyx_v_r30 * __pyx_v_r7)) + (__pyx_v_r35 * __pyx_v_r45)) + __pyx_v_r39) + __pyx_v_r40)) / 420.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 285, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":265 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840 + * - r16 * x2 * (r43 - r44) / 840 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 265, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXY, __pyx_t_2) < 0) __PYX_ERR(0, 265, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":287 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r2 * r42 / 420 + * - r22 * r29 / 420 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":309 + * / 420 + * + x1 * y2 * (r43 + r44 + r9 * y1) / 210 + * - y0 * (r19 * r45 + r2 * r53 - r21 * r4 + r48) / 420 # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_3 = PyFloat_FromDouble((((((((((((-__pyx_v_r2) * __pyx_v_r42) / 420.0) - ((__pyx_v_r22 * __pyx_v_r29) / 420.0)) - ((__pyx_v_r24 * ((__pyx_v_r14 + __pyx_v_r36) + (__pyx_v_r52 * __pyx_v_x2))) / 420.0)) - ((__pyx_v_r49 * __pyx_v_x2) / 420.0)) - ((__pyx_v_r50 * __pyx_v_x2) / 12.0)) - ((__pyx_v_r51 * (__pyx_v_r47 + __pyx_v_x2)) / 84.0)) + ((__pyx_v_x0 * ((((((((((__pyx_v_r19 * __pyx_v_r46) + (__pyx_v_r21 * __pyx_v_r5)) + (__pyx_v_r21 * __pyx_v_r52)) + (__pyx_v_r24 * __pyx_v_r29)) + (__pyx_v_r25 * __pyx_v_r53)) + (__pyx_v_r26 * __pyx_v_y2)) + (__pyx_v_r42 * __pyx_v_y0)) + __pyx_v_r49) + (5.0 * __pyx_v_r50)) + (35.0 * __pyx_v_r51))) / 420.0)) + (((__pyx_v_x1 * __pyx_v_y2) * ((__pyx_v_r43 + __pyx_v_r44) + (__pyx_v_r9 * __pyx_v_y1))) / 210.0)) - ((__pyx_v_y0 * ((((__pyx_v_r19 * __pyx_v_r45) + (__pyx_v_r2 * __pyx_v_r53)) - (__pyx_v_r21 * __pyx_v_r4)) + __pyx_v_r48)) / 420.0))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":287 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r2 * r42 / 420 + * - r22 * r29 / 420 + */ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentYY, __pyx_t_1) < 0) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":101 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._qCurveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":312 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne, "MomentsPen._curveToOne(self, p1, p2, p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne = {"_curveToOne", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + PyObject *__pyx_v_p3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curveToOne (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_p1,&__pyx_n_s_p2,&__pyx_n_s_p3,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 312, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 312, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, 1); __PYX_ERR(0, 312, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 312, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, 2); __PYX_ERR(0, 312, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p3)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 312, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, 3); __PYX_ERR(0, 312, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_curveToOne") < 0)) __PYX_ERR(0, 312, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + __pyx_v_p3 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 312, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._curveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(__pyx_self, __pyx_v_self, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3) { + double __pyx_v_x3; + double __pyx_v_y3; + double __pyx_v_x2; + double __pyx_v_y2; + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r132; + double __pyx_v_r131; + double __pyx_v_r130; + double __pyx_v_r129; + double __pyx_v_r128; + double __pyx_v_r127; + double __pyx_v_r126; + double __pyx_v_r125; + double __pyx_v_r124; + double __pyx_v_r123; + double __pyx_v_r122; + double __pyx_v_r121; + double __pyx_v_r120; + double __pyx_v_r119; + double __pyx_v_r118; + double __pyx_v_r117; + double __pyx_v_r116; + double __pyx_v_r115; + double __pyx_v_r114; + double __pyx_v_r113; + double __pyx_v_r112; + double __pyx_v_r111; + double __pyx_v_r110; + double __pyx_v_r109; + double __pyx_v_r108; + double __pyx_v_r107; + double __pyx_v_r106; + double __pyx_v_r105; + double __pyx_v_r104; + double __pyx_v_r103; + double __pyx_v_r102; + double __pyx_v_r101; + double __pyx_v_r100; + double __pyx_v_r99; + double __pyx_v_r98; + double __pyx_v_r97; + double __pyx_v_r96; + double __pyx_v_r95; + double __pyx_v_r94; + double __pyx_v_r93; + double __pyx_v_r92; + double __pyx_v_r91; + double __pyx_v_r90; + double __pyx_v_r89; + double __pyx_v_r88; + double __pyx_v_r87; + double __pyx_v_r86; + double __pyx_v_r85; + double __pyx_v_r84; + double __pyx_v_r83; + double __pyx_v_r82; + double __pyx_v_r81; + double __pyx_v_r80; + double __pyx_v_r79; + double __pyx_v_r78; + double __pyx_v_r77; + double __pyx_v_r76; + double __pyx_v_r75; + double __pyx_v_r74; + double __pyx_v_r73; + double __pyx_v_r72; + double __pyx_v_r71; + double __pyx_v_r70; + double __pyx_v_r69; + double __pyx_v_r68; + double __pyx_v_r67; + double __pyx_v_r66; + double __pyx_v_r65; + double __pyx_v_r64; + double __pyx_v_r63; + double __pyx_v_r62; + double __pyx_v_r61; + double __pyx_v_r60; + double __pyx_v_r59; + double __pyx_v_r58; + double __pyx_v_r57; + double __pyx_v_r56; + double __pyx_v_r55; + double __pyx_v_r54; + double __pyx_v_r53; + double __pyx_v_r52; + double __pyx_v_r51; + double __pyx_v_r50; + double __pyx_v_r49; + double __pyx_v_r48; + double __pyx_v_r47; + double __pyx_v_r46; + double __pyx_v_r45; + double __pyx_v_r44; + double __pyx_v_r43; + double __pyx_v_r42; + double __pyx_v_r41; + double __pyx_v_r40; + double __pyx_v_r39; + double __pyx_v_r38; + double __pyx_v_r37; + double __pyx_v_r36; + double __pyx_v_r35; + double __pyx_v_r34; + double __pyx_v_r33; + double __pyx_v_r32; + double __pyx_v_r31; + double __pyx_v_r30; + double __pyx_v_r29; + double __pyx_v_r28; + double __pyx_v_r27; + double __pyx_v_r26; + double __pyx_v_r25; + double __pyx_v_r24; + double __pyx_v_r23; + double __pyx_v_r22; + double __pyx_v_r21; + double __pyx_v_r20; + double __pyx_v_r19; + double __pyx_v_r18; + double __pyx_v_r17; + double __pyx_v_r16; + double __pyx_v_r15; + double __pyx_v_r14; + double __pyx_v_r13; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curveToOne", 1); + + /* "fontTools/pens/momentsPen.py":450 + * @cython.locals(x3=cython.double, y3=cython.double) + * def _curveToOne(self, p1, p2, p3): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * x2, y2 = p2 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_getCurrentPoint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 450, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) __PYX_ERR(0, 450, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 450, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":451 + * def _curveToOne(self, p1, p2, p3): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * x2, y2 = p2 + * x3, y3 = p3 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 451, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 451, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 451, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":452 + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 + * x2, y2 = p2 # <<<<<<<<<<<<<< + * x3, y3 = p3 + * + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p2))) || (PyList_CheckExact(__pyx_v_p2))) { + PyObject* sequence = __pyx_v_p2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 452, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 452, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 452, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_7; + __pyx_v_y2 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":453 + * x1, y1 = p1 + * x2, y2 = p2 + * x3, y3 = p3 # <<<<<<<<<<<<<< + * + * r0 = 6 * y2 + */ + if ((likely(PyTuple_CheckExact(__pyx_v_p3))) || (PyList_CheckExact(__pyx_v_p3))) { + PyObject* sequence = __pyx_v_p3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 453, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_3 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 453, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 453, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 453, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 453, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 453, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 453, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 453, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x3 = __pyx_t_8; + __pyx_v_y3 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":455 + * x3, y3 = p3 + * + * r0 = 6 * y2 # <<<<<<<<<<<<<< + * r1 = r0 * x3 + * r2 = 10 * y3 + */ + __pyx_v_r0 = (6.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":456 + * + * r0 = 6 * y2 + * r1 = r0 * x3 # <<<<<<<<<<<<<< + * r2 = 10 * y3 + * r3 = r2 * x3 + */ + __pyx_v_r1 = (__pyx_v_r0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":457 + * r0 = 6 * y2 + * r1 = r0 * x3 + * r2 = 10 * y3 # <<<<<<<<<<<<<< + * r3 = r2 * x3 + * r4 = 3 * y1 + */ + __pyx_v_r2 = (10.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":458 + * r1 = r0 * x3 + * r2 = 10 * y3 + * r3 = r2 * x3 # <<<<<<<<<<<<<< + * r4 = 3 * y1 + * r5 = 6 * x1 + */ + __pyx_v_r3 = (__pyx_v_r2 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":459 + * r2 = 10 * y3 + * r3 = r2 * x3 + * r4 = 3 * y1 # <<<<<<<<<<<<<< + * r5 = 6 * x1 + * r6 = 3 * x2 + */ + __pyx_v_r4 = (3.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":460 + * r3 = r2 * x3 + * r4 = 3 * y1 + * r5 = 6 * x1 # <<<<<<<<<<<<<< + * r6 = 3 * x2 + * r7 = 6 * y1 + */ + __pyx_v_r5 = (6.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":461 + * r4 = 3 * y1 + * r5 = 6 * x1 + * r6 = 3 * x2 # <<<<<<<<<<<<<< + * r7 = 6 * y1 + * r8 = 3 * y2 + */ + __pyx_v_r6 = (3.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":462 + * r5 = 6 * x1 + * r6 = 3 * x2 + * r7 = 6 * y1 # <<<<<<<<<<<<<< + * r8 = 3 * y2 + * r9 = x2**2 + */ + __pyx_v_r7 = (6.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":463 + * r6 = 3 * x2 + * r7 = 6 * y1 + * r8 = 3 * y2 # <<<<<<<<<<<<<< + * r9 = x2**2 + * r10 = 45 * r9 + */ + __pyx_v_r8 = (3.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":464 + * r7 = 6 * y1 + * r8 = 3 * y2 + * r9 = x2**2 # <<<<<<<<<<<<<< + * r10 = 45 * r9 + * r11 = r10 * y3 + */ + __pyx_v_r9 = pow(__pyx_v_x2, 2.0); + + /* "fontTools/pens/momentsPen.py":465 + * r8 = 3 * y2 + * r9 = x2**2 + * r10 = 45 * r9 # <<<<<<<<<<<<<< + * r11 = r10 * y3 + * r12 = x3**2 + */ + __pyx_v_r10 = (45.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":466 + * r9 = x2**2 + * r10 = 45 * r9 + * r11 = r10 * y3 # <<<<<<<<<<<<<< + * r12 = x3**2 + * r13 = r12 * y2 + */ + __pyx_v_r11 = (__pyx_v_r10 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":467 + * r10 = 45 * r9 + * r11 = r10 * y3 + * r12 = x3**2 # <<<<<<<<<<<<<< + * r13 = r12 * y2 + * r14 = r12 * y3 + */ + __pyx_v_r12 = pow(__pyx_v_x3, 2.0); + + /* "fontTools/pens/momentsPen.py":468 + * r11 = r10 * y3 + * r12 = x3**2 + * r13 = r12 * y2 # <<<<<<<<<<<<<< + * r14 = r12 * y3 + * r15 = 7 * y3 + */ + __pyx_v_r13 = (__pyx_v_r12 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":469 + * r12 = x3**2 + * r13 = r12 * y2 + * r14 = r12 * y3 # <<<<<<<<<<<<<< + * r15 = 7 * y3 + * r16 = 15 * x3 + */ + __pyx_v_r14 = (__pyx_v_r12 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":470 + * r13 = r12 * y2 + * r14 = r12 * y3 + * r15 = 7 * y3 # <<<<<<<<<<<<<< + * r16 = 15 * x3 + * r17 = r16 * x2 + */ + __pyx_v_r15 = (7.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":471 + * r14 = r12 * y3 + * r15 = 7 * y3 + * r16 = 15 * x3 # <<<<<<<<<<<<<< + * r17 = r16 * x2 + * r18 = x1**2 + */ + __pyx_v_r16 = (15.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":472 + * r15 = 7 * y3 + * r16 = 15 * x3 + * r17 = r16 * x2 # <<<<<<<<<<<<<< + * r18 = x1**2 + * r19 = 9 * r18 + */ + __pyx_v_r17 = (__pyx_v_r16 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":473 + * r16 = 15 * x3 + * r17 = r16 * x2 + * r18 = x1**2 # <<<<<<<<<<<<<< + * r19 = 9 * r18 + * r20 = x0**2 + */ + __pyx_v_r18 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":474 + * r17 = r16 * x2 + * r18 = x1**2 + * r19 = 9 * r18 # <<<<<<<<<<<<<< + * r20 = x0**2 + * r21 = 21 * y1 + */ + __pyx_v_r19 = (9.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":475 + * r18 = x1**2 + * r19 = 9 * r18 + * r20 = x0**2 # <<<<<<<<<<<<<< + * r21 = 21 * y1 + * r22 = 9 * r9 + */ + __pyx_v_r20 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":476 + * r19 = 9 * r18 + * r20 = x0**2 + * r21 = 21 * y1 # <<<<<<<<<<<<<< + * r22 = 9 * r9 + * r23 = r7 * x3 + */ + __pyx_v_r21 = (21.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":477 + * r20 = x0**2 + * r21 = 21 * y1 + * r22 = 9 * r9 # <<<<<<<<<<<<<< + * r23 = r7 * x3 + * r24 = 9 * y2 + */ + __pyx_v_r22 = (9.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":478 + * r21 = 21 * y1 + * r22 = 9 * r9 + * r23 = r7 * x3 # <<<<<<<<<<<<<< + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 + */ + __pyx_v_r23 = (__pyx_v_r7 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":479 + * r22 = 9 * r9 + * r23 = r7 * x3 + * r24 = 9 * y2 # <<<<<<<<<<<<<< + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 + */ + __pyx_v_r24 = (9.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":480 + * r23 = r7 * x3 + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 # <<<<<<<<<<<<<< + * r26 = 9 * x2 + * r27 = x2 * y3 + */ + __pyx_v_r25 = ((__pyx_v_r24 * __pyx_v_x2) + __pyx_v_r3); + + /* "fontTools/pens/momentsPen.py":481 + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 # <<<<<<<<<<<<<< + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 + */ + __pyx_v_r26 = (9.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":482 + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 + * r27 = x2 * y3 # <<<<<<<<<<<<<< + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 + */ + __pyx_v_r27 = (__pyx_v_x2 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":483 + * r26 = 9 * x2 + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 # <<<<<<<<<<<<<< + * r29 = 3 * x1 + * r30 = 45 * x1 + */ + __pyx_v_r28 = (((-__pyx_v_r26) * __pyx_v_y1) + (15.0 * __pyx_v_r27)); + + /* "fontTools/pens/momentsPen.py":484 + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 # <<<<<<<<<<<<<< + * r30 = 45 * x1 + * r31 = 12 * x3 + */ + __pyx_v_r29 = (3.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":485 + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 + * r30 = 45 * x1 # <<<<<<<<<<<<<< + * r31 = 12 * x3 + * r32 = 45 * r18 + */ + __pyx_v_r30 = (45.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":486 + * r29 = 3 * x1 + * r30 = 45 * x1 + * r31 = 12 * x3 # <<<<<<<<<<<<<< + * r32 = 45 * r18 + * r33 = 5 * r12 + */ + __pyx_v_r31 = (12.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":487 + * r30 = 45 * x1 + * r31 = 12 * x3 + * r32 = 45 * r18 # <<<<<<<<<<<<<< + * r33 = 5 * r12 + * r34 = r8 * x3 + */ + __pyx_v_r32 = (45.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":488 + * r31 = 12 * x3 + * r32 = 45 * r18 + * r33 = 5 * r12 # <<<<<<<<<<<<<< + * r34 = r8 * x3 + * r35 = 105 * y0 + */ + __pyx_v_r33 = (5.0 * __pyx_v_r12); + + /* "fontTools/pens/momentsPen.py":489 + * r32 = 45 * r18 + * r33 = 5 * r12 + * r34 = r8 * x3 # <<<<<<<<<<<<<< + * r35 = 105 * y0 + * r36 = 30 * y0 + */ + __pyx_v_r34 = (__pyx_v_r8 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":490 + * r33 = 5 * r12 + * r34 = r8 * x3 + * r35 = 105 * y0 # <<<<<<<<<<<<<< + * r36 = 30 * y0 + * r37 = r36 * x2 + */ + __pyx_v_r35 = (105.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":491 + * r34 = r8 * x3 + * r35 = 105 * y0 + * r36 = 30 * y0 # <<<<<<<<<<<<<< + * r37 = r36 * x2 + * r38 = 5 * x3 + */ + __pyx_v_r36 = (30.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":492 + * r35 = 105 * y0 + * r36 = 30 * y0 + * r37 = r36 * x2 # <<<<<<<<<<<<<< + * r38 = 5 * x3 + * r39 = 15 * y3 + */ + __pyx_v_r37 = (__pyx_v_r36 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":493 + * r36 = 30 * y0 + * r37 = r36 * x2 + * r38 = 5 * x3 # <<<<<<<<<<<<<< + * r39 = 15 * y3 + * r40 = 5 * y3 + */ + __pyx_v_r38 = (5.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":494 + * r37 = r36 * x2 + * r38 = 5 * x3 + * r39 = 15 * y3 # <<<<<<<<<<<<<< + * r40 = 5 * y3 + * r41 = r40 * x3 + */ + __pyx_v_r39 = (15.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":495 + * r38 = 5 * x3 + * r39 = 15 * y3 + * r40 = 5 * y3 # <<<<<<<<<<<<<< + * r41 = r40 * x3 + * r42 = x2 * y2 + */ + __pyx_v_r40 = (5.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":496 + * r39 = 15 * y3 + * r40 = 5 * y3 + * r41 = r40 * x3 # <<<<<<<<<<<<<< + * r42 = x2 * y2 + * r43 = 18 * r42 + */ + __pyx_v_r41 = (__pyx_v_r40 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":497 + * r40 = 5 * y3 + * r41 = r40 * x3 + * r42 = x2 * y2 # <<<<<<<<<<<<<< + * r43 = 18 * r42 + * r44 = 45 * y1 + */ + __pyx_v_r42 = (__pyx_v_x2 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":498 + * r41 = r40 * x3 + * r42 = x2 * y2 + * r43 = 18 * r42 # <<<<<<<<<<<<<< + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 + */ + __pyx_v_r43 = (18.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":499 + * r42 = x2 * y2 + * r43 = 18 * r42 + * r44 = 45 * y1 # <<<<<<<<<<<<<< + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 + */ + __pyx_v_r44 = (45.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":500 + * r43 = 18 * r42 + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 # <<<<<<<<<<<<<< + * r46 = y2 * y3 + * r47 = r46 * x3 + */ + __pyx_v_r45 = ((__pyx_v_r41 + __pyx_v_r43) + (__pyx_v_r44 * __pyx_v_x1)); + + /* "fontTools/pens/momentsPen.py":501 + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 # <<<<<<<<<<<<<< + * r47 = r46 * x3 + * r48 = y2**2 + */ + __pyx_v_r46 = (__pyx_v_y2 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":502 + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 + * r47 = r46 * x3 # <<<<<<<<<<<<<< + * r48 = y2**2 + * r49 = 45 * r48 + */ + __pyx_v_r47 = (__pyx_v_r46 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":503 + * r46 = y2 * y3 + * r47 = r46 * x3 + * r48 = y2**2 # <<<<<<<<<<<<<< + * r49 = 45 * r48 + * r50 = r49 * x3 + */ + __pyx_v_r48 = pow(__pyx_v_y2, 2.0); + + /* "fontTools/pens/momentsPen.py":504 + * r47 = r46 * x3 + * r48 = y2**2 + * r49 = 45 * r48 # <<<<<<<<<<<<<< + * r50 = r49 * x3 + * r51 = y3**2 + */ + __pyx_v_r49 = (45.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":505 + * r48 = y2**2 + * r49 = 45 * r48 + * r50 = r49 * x3 # <<<<<<<<<<<<<< + * r51 = y3**2 + * r52 = r51 * x3 + */ + __pyx_v_r50 = (__pyx_v_r49 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":506 + * r49 = 45 * r48 + * r50 = r49 * x3 + * r51 = y3**2 # <<<<<<<<<<<<<< + * r52 = r51 * x3 + * r53 = y1**2 + */ + __pyx_v_r51 = pow(__pyx_v_y3, 2.0); + + /* "fontTools/pens/momentsPen.py":507 + * r50 = r49 * x3 + * r51 = y3**2 + * r52 = r51 * x3 # <<<<<<<<<<<<<< + * r53 = y1**2 + * r54 = 9 * r53 + */ + __pyx_v_r52 = (__pyx_v_r51 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":508 + * r51 = y3**2 + * r52 = r51 * x3 + * r53 = y1**2 # <<<<<<<<<<<<<< + * r54 = 9 * r53 + * r55 = y0**2 + */ + __pyx_v_r53 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":509 + * r52 = r51 * x3 + * r53 = y1**2 + * r54 = 9 * r53 # <<<<<<<<<<<<<< + * r55 = y0**2 + * r56 = 21 * x1 + */ + __pyx_v_r54 = (9.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":510 + * r53 = y1**2 + * r54 = 9 * r53 + * r55 = y0**2 # <<<<<<<<<<<<<< + * r56 = 21 * x1 + * r57 = 6 * x2 + */ + __pyx_v_r55 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":511 + * r54 = 9 * r53 + * r55 = y0**2 + * r56 = 21 * x1 # <<<<<<<<<<<<<< + * r57 = 6 * x2 + * r58 = r16 * y2 + */ + __pyx_v_r56 = (21.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":512 + * r55 = y0**2 + * r56 = 21 * x1 + * r57 = 6 * x2 # <<<<<<<<<<<<<< + * r58 = r16 * y2 + * r59 = r39 * y2 + */ + __pyx_v_r57 = (6.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":513 + * r56 = 21 * x1 + * r57 = 6 * x2 + * r58 = r16 * y2 # <<<<<<<<<<<<<< + * r59 = r39 * y2 + * r60 = 9 * r48 + */ + __pyx_v_r58 = (__pyx_v_r16 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":514 + * r57 = 6 * x2 + * r58 = r16 * y2 + * r59 = r39 * y2 # <<<<<<<<<<<<<< + * r60 = 9 * r48 + * r61 = r6 * y3 + */ + __pyx_v_r59 = (__pyx_v_r39 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":515 + * r58 = r16 * y2 + * r59 = r39 * y2 + * r60 = 9 * r48 # <<<<<<<<<<<<<< + * r61 = r6 * y3 + * r62 = 3 * y3 + */ + __pyx_v_r60 = (9.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":516 + * r59 = r39 * y2 + * r60 = 9 * r48 + * r61 = r6 * y3 # <<<<<<<<<<<<<< + * r62 = 3 * y3 + * r63 = r36 * y2 + */ + __pyx_v_r61 = (__pyx_v_r6 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":517 + * r60 = 9 * r48 + * r61 = r6 * y3 + * r62 = 3 * y3 # <<<<<<<<<<<<<< + * r63 = r36 * y2 + * r64 = y1 * y3 + */ + __pyx_v_r62 = (3.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":518 + * r61 = r6 * y3 + * r62 = 3 * y3 + * r63 = r36 * y2 # <<<<<<<<<<<<<< + * r64 = y1 * y3 + * r65 = 45 * r53 + */ + __pyx_v_r63 = (__pyx_v_r36 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":519 + * r62 = 3 * y3 + * r63 = r36 * y2 + * r64 = y1 * y3 # <<<<<<<<<<<<<< + * r65 = 45 * r53 + * r66 = 5 * r51 + */ + __pyx_v_r64 = (__pyx_v_y1 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":520 + * r63 = r36 * y2 + * r64 = y1 * y3 + * r65 = 45 * r53 # <<<<<<<<<<<<<< + * r66 = 5 * r51 + * r67 = x2**3 + */ + __pyx_v_r65 = (45.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":521 + * r64 = y1 * y3 + * r65 = 45 * r53 + * r66 = 5 * r51 # <<<<<<<<<<<<<< + * r67 = x2**3 + * r68 = x3**3 + */ + __pyx_v_r66 = (5.0 * __pyx_v_r51); + + /* "fontTools/pens/momentsPen.py":522 + * r65 = 45 * r53 + * r66 = 5 * r51 + * r67 = x2**3 # <<<<<<<<<<<<<< + * r68 = x3**3 + * r69 = 630 * y2 + */ + __pyx_v_r67 = pow(__pyx_v_x2, 3.0); + + /* "fontTools/pens/momentsPen.py":523 + * r66 = 5 * r51 + * r67 = x2**3 + * r68 = x3**3 # <<<<<<<<<<<<<< + * r69 = 630 * y2 + * r70 = 126 * x3 + */ + __pyx_v_r68 = pow(__pyx_v_x3, 3.0); + + /* "fontTools/pens/momentsPen.py":524 + * r67 = x2**3 + * r68 = x3**3 + * r69 = 630 * y2 # <<<<<<<<<<<<<< + * r70 = 126 * x3 + * r71 = x1**3 + */ + __pyx_v_r69 = (630.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":525 + * r68 = x3**3 + * r69 = 630 * y2 + * r70 = 126 * x3 # <<<<<<<<<<<<<< + * r71 = x1**3 + * r72 = 126 * x2 + */ + __pyx_v_r70 = (126.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":526 + * r69 = 630 * y2 + * r70 = 126 * x3 + * r71 = x1**3 # <<<<<<<<<<<<<< + * r72 = 126 * x2 + * r73 = 63 * r9 + */ + __pyx_v_r71 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":527 + * r70 = 126 * x3 + * r71 = x1**3 + * r72 = 126 * x2 # <<<<<<<<<<<<<< + * r73 = 63 * r9 + * r74 = r73 * x3 + */ + __pyx_v_r72 = (126.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":528 + * r71 = x1**3 + * r72 = 126 * x2 + * r73 = 63 * r9 # <<<<<<<<<<<<<< + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 + */ + __pyx_v_r73 = (63.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":529 + * r72 = 126 * x2 + * r73 = 63 * r9 + * r74 = r73 * x3 # <<<<<<<<<<<<<< + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 + */ + __pyx_v_r74 = (__pyx_v_r73 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":530 + * r73 = 63 * r9 + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 # <<<<<<<<<<<<<< + * r76 = 630 * x1 + * r77 = 14 * x3 + */ + __pyx_v_r75 = ((__pyx_v_r15 * __pyx_v_x3) + (15.0 * __pyx_v_r42)); + + /* "fontTools/pens/momentsPen.py":531 + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 # <<<<<<<<<<<<<< + * r77 = 14 * x3 + * r78 = 21 * r27 + */ + __pyx_v_r76 = (630.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":532 + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 + * r77 = 14 * x3 # <<<<<<<<<<<<<< + * r78 = 21 * r27 + * r79 = 42 * x1 + */ + __pyx_v_r77 = (14.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":533 + * r76 = 630 * x1 + * r77 = 14 * x3 + * r78 = 21 * r27 # <<<<<<<<<<<<<< + * r79 = 42 * x1 + * r80 = 42 * x2 + */ + __pyx_v_r78 = (21.0 * __pyx_v_r27); + + /* "fontTools/pens/momentsPen.py":534 + * r77 = 14 * x3 + * r78 = 21 * r27 + * r79 = 42 * x1 # <<<<<<<<<<<<<< + * r80 = 42 * x2 + * r81 = x1 * y2 + */ + __pyx_v_r79 = (42.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":535 + * r78 = 21 * r27 + * r79 = 42 * x1 + * r80 = 42 * x2 # <<<<<<<<<<<<<< + * r81 = x1 * y2 + * r82 = 63 * r42 + */ + __pyx_v_r80 = (42.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":536 + * r79 = 42 * x1 + * r80 = 42 * x2 + * r81 = x1 * y2 # <<<<<<<<<<<<<< + * r82 = 63 * r42 + * r83 = x1 * y1 + */ + __pyx_v_r81 = (__pyx_v_x1 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":537 + * r80 = 42 * x2 + * r81 = x1 * y2 + * r82 = 63 * r42 # <<<<<<<<<<<<<< + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 + */ + __pyx_v_r82 = (63.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":538 + * r81 = x1 * y2 + * r82 = 63 * r42 + * r83 = x1 * y1 # <<<<<<<<<<<<<< + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 + */ + __pyx_v_r83 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":539 + * r82 = 63 * r42 + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 # <<<<<<<<<<<<<< + * r85 = x2 * x3 + * r86 = r85 * y1 + */ + __pyx_v_r84 = ((__pyx_v_r41 + __pyx_v_r82) + (378.0 * __pyx_v_r83)); + + /* "fontTools/pens/momentsPen.py":540 + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 # <<<<<<<<<<<<<< + * r86 = r85 * y1 + * r87 = r27 * x3 + */ + __pyx_v_r85 = (__pyx_v_x2 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":541 + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 + * r86 = r85 * y1 # <<<<<<<<<<<<<< + * r87 = r27 * x3 + * r88 = 27 * r9 + */ + __pyx_v_r86 = (__pyx_v_r85 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":542 + * r85 = x2 * x3 + * r86 = r85 * y1 + * r87 = r27 * x3 # <<<<<<<<<<<<<< + * r88 = 27 * r9 + * r89 = r88 * y2 + */ + __pyx_v_r87 = (__pyx_v_r27 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":543 + * r86 = r85 * y1 + * r87 = r27 * x3 + * r88 = 27 * r9 # <<<<<<<<<<<<<< + * r89 = r88 * y2 + * r90 = 42 * r14 + */ + __pyx_v_r88 = (27.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":544 + * r87 = r27 * x3 + * r88 = 27 * r9 + * r89 = r88 * y2 # <<<<<<<<<<<<<< + * r90 = 42 * r14 + * r91 = 90 * x1 + */ + __pyx_v_r89 = (__pyx_v_r88 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":545 + * r88 = 27 * r9 + * r89 = r88 * y2 + * r90 = 42 * r14 # <<<<<<<<<<<<<< + * r91 = 90 * x1 + * r92 = 189 * r18 + */ + __pyx_v_r90 = (42.0 * __pyx_v_r14); + + /* "fontTools/pens/momentsPen.py":546 + * r89 = r88 * y2 + * r90 = 42 * r14 + * r91 = 90 * x1 # <<<<<<<<<<<<<< + * r92 = 189 * r18 + * r93 = 378 * r18 + */ + __pyx_v_r91 = (90.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":547 + * r90 = 42 * r14 + * r91 = 90 * x1 + * r92 = 189 * r18 # <<<<<<<<<<<<<< + * r93 = 378 * r18 + * r94 = r12 * y1 + */ + __pyx_v_r92 = (189.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":548 + * r91 = 90 * x1 + * r92 = 189 * r18 + * r93 = 378 * r18 # <<<<<<<<<<<<<< + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 + */ + __pyx_v_r93 = (378.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":549 + * r92 = 189 * r18 + * r93 = 378 * r18 + * r94 = r12 * y1 # <<<<<<<<<<<<<< + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 + */ + __pyx_v_r94 = (__pyx_v_r12 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":550 + * r93 = 378 * r18 + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 # <<<<<<<<<<<<<< + * r96 = r79 * x3 + * r97 = 30 * r85 + */ + __pyx_v_r95 = ((252.0 * __pyx_v_x1) * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":551 + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 # <<<<<<<<<<<<<< + * r97 = 30 * r85 + * r98 = r83 * x3 + */ + __pyx_v_r96 = (__pyx_v_r79 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":552 + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 + * r97 = 30 * r85 # <<<<<<<<<<<<<< + * r98 = r83 * x3 + * r99 = 30 * x3 + */ + __pyx_v_r97 = (30.0 * __pyx_v_r85); + + /* "fontTools/pens/momentsPen.py":553 + * r96 = r79 * x3 + * r97 = 30 * r85 + * r98 = r83 * x3 # <<<<<<<<<<<<<< + * r99 = 30 * x3 + * r100 = 42 * x3 + */ + __pyx_v_r98 = (__pyx_v_r83 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":554 + * r97 = 30 * r85 + * r98 = r83 * x3 + * r99 = 30 * x3 # <<<<<<<<<<<<<< + * r100 = 42 * x3 + * r101 = r42 * x1 + */ + __pyx_v_r99 = (30.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":555 + * r98 = r83 * x3 + * r99 = 30 * x3 + * r100 = 42 * x3 # <<<<<<<<<<<<<< + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + */ + __pyx_v_r100 = (42.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":556 + * r99 = 30 * x3 + * r100 = 42 * x3 + * r101 = r42 * x1 # <<<<<<<<<<<<<< + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 + */ + __pyx_v_r101 = (__pyx_v_r42 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":557 + * r100 = 42 * x3 + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 # <<<<<<<<<<<<<< + * r103 = 378 * r48 + * r104 = 18 * y1 + */ + __pyx_v_r102 = ((((__pyx_v_r10 * __pyx_v_y2) + (14.0 * __pyx_v_r14)) + ((126.0 * __pyx_v_r18) * __pyx_v_y1)) + (__pyx_v_r81 * __pyx_v_r99)); + + /* "fontTools/pens/momentsPen.py":558 + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 # <<<<<<<<<<<<<< + * r104 = 18 * y1 + * r105 = r104 * y2 + */ + __pyx_v_r103 = (378.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":559 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 + * r104 = 18 * y1 # <<<<<<<<<<<<<< + * r105 = r104 * y2 + * r106 = y0 * y1 + */ + __pyx_v_r104 = (18.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":560 + * r103 = 378 * r48 + * r104 = 18 * y1 + * r105 = r104 * y2 # <<<<<<<<<<<<<< + * r106 = y0 * y1 + * r107 = 252 * y2 + */ + __pyx_v_r105 = (__pyx_v_r104 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":561 + * r104 = 18 * y1 + * r105 = r104 * y2 + * r106 = y0 * y1 # <<<<<<<<<<<<<< + * r107 = 252 * y2 + * r108 = r107 * y0 + */ + __pyx_v_r106 = (__pyx_v_y0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":562 + * r105 = r104 * y2 + * r106 = y0 * y1 + * r107 = 252 * y2 # <<<<<<<<<<<<<< + * r108 = r107 * y0 + * r109 = y0 * y3 + */ + __pyx_v_r107 = (252.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":563 + * r106 = y0 * y1 + * r107 = 252 * y2 + * r108 = r107 * y0 # <<<<<<<<<<<<<< + * r109 = y0 * y3 + * r110 = 42 * r64 + */ + __pyx_v_r108 = (__pyx_v_r107 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":564 + * r107 = 252 * y2 + * r108 = r107 * y0 + * r109 = y0 * y3 # <<<<<<<<<<<<<< + * r110 = 42 * r64 + * r111 = 378 * r53 + */ + __pyx_v_r109 = (__pyx_v_y0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":565 + * r108 = r107 * y0 + * r109 = y0 * y3 + * r110 = 42 * r64 # <<<<<<<<<<<<<< + * r111 = 378 * r53 + * r112 = 63 * r48 + */ + __pyx_v_r110 = (42.0 * __pyx_v_r64); + + /* "fontTools/pens/momentsPen.py":566 + * r109 = y0 * y3 + * r110 = 42 * r64 + * r111 = 378 * r53 # <<<<<<<<<<<<<< + * r112 = 63 * r48 + * r113 = 27 * x2 + */ + __pyx_v_r111 = (378.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":567 + * r110 = 42 * r64 + * r111 = 378 * r53 + * r112 = 63 * r48 # <<<<<<<<<<<<<< + * r113 = 27 * x2 + * r114 = r27 * y2 + */ + __pyx_v_r112 = (63.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":568 + * r111 = 378 * r53 + * r112 = 63 * r48 + * r113 = 27 * x2 # <<<<<<<<<<<<<< + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 + */ + __pyx_v_r113 = (27.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":569 + * r112 = 63 * r48 + * r113 = 27 * x2 + * r114 = r27 * y2 # <<<<<<<<<<<<<< + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 + */ + __pyx_v_r114 = (__pyx_v_r27 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":570 + * r113 = 27 * x2 + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 # <<<<<<<<<<<<<< + * r116 = x3 * y3 + * r117 = 54 * r42 + */ + __pyx_v_r115 = ((__pyx_v_r113 * __pyx_v_r48) + (42.0 * __pyx_v_r52)); + + /* "fontTools/pens/momentsPen.py":571 + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 # <<<<<<<<<<<<<< + * r117 = 54 * r42 + * r118 = r51 * x1 + */ + __pyx_v_r116 = (__pyx_v_x3 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":572 + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 + * r117 = 54 * r42 # <<<<<<<<<<<<<< + * r118 = r51 * x1 + * r119 = r51 * x2 + */ + __pyx_v_r117 = (54.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":573 + * r116 = x3 * y3 + * r117 = 54 * r42 + * r118 = r51 * x1 # <<<<<<<<<<<<<< + * r119 = r51 * x2 + * r120 = r48 * x1 + */ + __pyx_v_r118 = (__pyx_v_r51 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":574 + * r117 = 54 * r42 + * r118 = r51 * x1 + * r119 = r51 * x2 # <<<<<<<<<<<<<< + * r120 = r48 * x1 + * r121 = 21 * x3 + */ + __pyx_v_r119 = (__pyx_v_r51 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":575 + * r118 = r51 * x1 + * r119 = r51 * x2 + * r120 = r48 * x1 # <<<<<<<<<<<<<< + * r121 = 21 * x3 + * r122 = r64 * x1 + */ + __pyx_v_r120 = (__pyx_v_r48 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":576 + * r119 = r51 * x2 + * r120 = r48 * x1 + * r121 = 21 * x3 # <<<<<<<<<<<<<< + * r122 = r64 * x1 + * r123 = r81 * y3 + */ + __pyx_v_r121 = (21.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":577 + * r120 = r48 * x1 + * r121 = 21 * x3 + * r122 = r64 * x1 # <<<<<<<<<<<<<< + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + */ + __pyx_v_r122 = (__pyx_v_r64 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":578 + * r121 = 21 * x3 + * r122 = r64 * x1 + * r123 = r81 * y3 # <<<<<<<<<<<<<< + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 + */ + __pyx_v_r123 = (__pyx_v_r81 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":579 + * r122 = r64 * x1 + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 # <<<<<<<<<<<<<< + * r125 = y2**3 + * r126 = y3**3 + */ + __pyx_v_r124 = (((((30.0 * __pyx_v_r27) * __pyx_v_y1) + (__pyx_v_r49 * __pyx_v_x2)) + (14.0 * __pyx_v_r52)) + ((126.0 * __pyx_v_r53) * __pyx_v_x1)); + + /* "fontTools/pens/momentsPen.py":580 + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 # <<<<<<<<<<<<<< + * r126 = y3**3 + * r127 = y1**3 + */ + __pyx_v_r125 = pow(__pyx_v_y2, 3.0); + + /* "fontTools/pens/momentsPen.py":581 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 + * r126 = y3**3 # <<<<<<<<<<<<<< + * r127 = y1**3 + * r128 = y0**3 + */ + __pyx_v_r126 = pow(__pyx_v_y3, 3.0); + + /* "fontTools/pens/momentsPen.py":582 + * r125 = y2**3 + * r126 = y3**3 + * r127 = y1**3 # <<<<<<<<<<<<<< + * r128 = y0**3 + * r129 = r51 * y2 + */ + __pyx_v_r127 = pow(__pyx_v_y1, 3.0); + + /* "fontTools/pens/momentsPen.py":583 + * r126 = y3**3 + * r127 = y1**3 + * r128 = y0**3 # <<<<<<<<<<<<<< + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 + */ + __pyx_v_r128 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":584 + * r127 = y1**3 + * r128 = y0**3 + * r129 = r51 * y2 # <<<<<<<<<<<<<< + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 + */ + __pyx_v_r129 = (__pyx_v_r51 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":585 + * r128 = y0**3 + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 # <<<<<<<<<<<<<< + * r131 = 189 * r53 + * r132 = 90 * y2 + */ + __pyx_v_r130 = ((__pyx_v_r112 * __pyx_v_y3) + (__pyx_v_r21 * __pyx_v_r51)); + + /* "fontTools/pens/momentsPen.py":586 + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 # <<<<<<<<<<<<<< + * r132 = 90 * y2 + * + */ + __pyx_v_r131 = (189.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":587 + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 + * r132 = 90 * y2 # <<<<<<<<<<<<<< + * + * self.area += ( + */ + __pyx_v_r132 = (90.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":589 + * r132 = 90 * y2 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 20 + * - r3 / 20 + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_area); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":596 + * + 3 * x1 * (y2 + y3) / 20 + * + 3 * x2 * y3 / 10 + * - y0 * (r5 + r6 + x3) / 20 # <<<<<<<<<<<<<< + * ) + * self.momentX += ( + */ + __pyx_t_1 = PyFloat_FromDouble(((((((((-__pyx_v_r1) / 20.0) - (__pyx_v_r3 / 20.0)) - ((__pyx_v_r4 * (__pyx_v_x2 + __pyx_v_x3)) / 20.0)) + ((__pyx_v_x0 * (((__pyx_v_r7 + __pyx_v_r8) + (10.0 * __pyx_v_y0)) + __pyx_v_y3)) / 20.0)) + (((3.0 * __pyx_v_x1) * (__pyx_v_y2 + __pyx_v_y3)) / 20.0)) + (((3.0 * __pyx_v_x2) * __pyx_v_y3) / 10.0)) - ((__pyx_v_y0 * ((__pyx_v_r5 + __pyx_v_r6) + __pyx_v_x3)) / 20.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":589 + * r132 = 90 * y2 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 20 + * - r3 / 20 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_area, __pyx_t_2) < 0) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":598 + * - y0 * (r5 + r6 + x3) / 20 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * r11 / 840 + * - r13 / 8 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 598, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":620 + * ) + * / 840 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 # <<<<<<<<<<<<<< + * ) + * self.momentY += ( + */ + __pyx_t_1 = PyFloat_FromDouble(((((((((((__pyx_v_r11 / 840.0) - (__pyx_v_r13 / 8.0)) - (__pyx_v_r14 / 3.0)) - ((__pyx_v_r17 * ((-__pyx_v_r15) + __pyx_v_r8)) / 840.0)) + ((__pyx_v_r19 * (__pyx_v_r8 + (2.0 * __pyx_v_y3))) / 840.0)) + ((__pyx_v_r20 * (((__pyx_v_r0 + __pyx_v_r21) + (56.0 * __pyx_v_y0)) + __pyx_v_y3)) / 168.0)) + ((__pyx_v_r29 * (((-__pyx_v_r23) + __pyx_v_r25) + __pyx_v_r28)) / 840.0)) - ((__pyx_v_r4 * (((10.0 * __pyx_v_r12) + __pyx_v_r17) + __pyx_v_r22)) / 840.0)) + ((__pyx_v_x0 * (((((((((12.0 * __pyx_v_r27) + (__pyx_v_r30 * __pyx_v_y2)) + __pyx_v_r34) - (__pyx_v_r35 * __pyx_v_x1)) - __pyx_v_r37) - (__pyx_v_r38 * __pyx_v_y0)) + (__pyx_v_r39 * __pyx_v_x1)) - (__pyx_v_r4 * __pyx_v_x3)) + __pyx_v_r45)) / 840.0)) - ((__pyx_v_y0 * (((((__pyx_v_r17 + (__pyx_v_r30 * __pyx_v_x2)) + (__pyx_v_r31 * __pyx_v_x1)) + __pyx_v_r32) + __pyx_v_r33) + (18.0 * __pyx_v_r9))) / 840.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 620, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":598 + * - y0 * (r5 + r6 + x3) / 20 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * r11 / 840 + * - r13 / 8 + */ + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 598, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentX, __pyx_t_3) < 0) __PYX_ERR(0, 598, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":622 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r4 * (r25 + r58) / 840 + * - r47 / 8 + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentY); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 622, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":645 + * + x1 * (r24 * y1 + 10 * r51 + r59 + r60 + r7 * y3) / 280 + * + x2 * y3 * (r15 + r8) / 56 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( + */ + __pyx_t_1 = PyFloat_FromDouble(((((((((((((-__pyx_v_r4) * (__pyx_v_r25 + __pyx_v_r58)) / 840.0) - (__pyx_v_r47 / 8.0)) - (__pyx_v_r50 / 840.0)) - (__pyx_v_r52 / 6.0)) - ((__pyx_v_r54 * (__pyx_v_r6 + (2.0 * __pyx_v_x3))) / 840.0)) - ((__pyx_v_r55 * ((__pyx_v_r56 + __pyx_v_r57) + __pyx_v_x3)) / 168.0)) + ((__pyx_v_x0 * ((((((((((__pyx_v_r35 * __pyx_v_y1) + (__pyx_v_r40 * __pyx_v_y0)) + (__pyx_v_r44 * __pyx_v_y2)) + (18.0 * __pyx_v_r48)) + (140.0 * __pyx_v_r55)) + __pyx_v_r59) + __pyx_v_r63) + (12.0 * __pyx_v_r64)) + __pyx_v_r65) + __pyx_v_r66)) / 840.0)) + ((__pyx_v_x1 * (((((__pyx_v_r24 * __pyx_v_y1) + (10.0 * __pyx_v_r51)) + __pyx_v_r59) + __pyx_v_r60) + (__pyx_v_r7 * __pyx_v_y3))) / 280.0)) + (((__pyx_v_x2 * __pyx_v_y3) * (__pyx_v_r15 + __pyx_v_r8)) / 56.0)) - ((__pyx_v_y0 * ((((((__pyx_v_r16 * __pyx_v_y1) + (__pyx_v_r31 * __pyx_v_y2)) + (__pyx_v_r44 * __pyx_v_x2)) + __pyx_v_r45) + __pyx_v_r61) - (__pyx_v_r62 * __pyx_v_x1))) / 840.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 645, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":622 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r4 * (r25 + r58) / 840 + * - r47 / 8 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 622, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentY, __pyx_t_2) < 0) __PYX_ERR(0, 622, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":647 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r12 * r72 * (-r40 + r8) / 9240 + * + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 647, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":705 + * ) + * / 9240 + * - y0 # <<<<<<<<<<<<<< + * * ( + * r12 * r56 + */ + __pyx_t_1 = PyFloat_FromDouble(((((((((((((((((-__pyx_v_r12) * __pyx_v_r72) * ((-__pyx_v_r40) + __pyx_v_r8)) / 9240.0) + (((3.0 * __pyx_v_r18) * (((__pyx_v_r28 + __pyx_v_r34) - (__pyx_v_r38 * __pyx_v_y1)) + __pyx_v_r75)) / 3080.0)) + ((__pyx_v_r20 * (((((((((__pyx_v_r24 * __pyx_v_x3) - (__pyx_v_r72 * __pyx_v_y0)) - (__pyx_v_r76 * __pyx_v_y0)) - (__pyx_v_r77 * __pyx_v_y0)) + __pyx_v_r78) + (__pyx_v_r79 * __pyx_v_y3)) + (__pyx_v_r80 * __pyx_v_y1)) + (210.0 * __pyx_v_r81)) + __pyx_v_r84)) / 9240.0)) - ((__pyx_v_r29 * ((((((((__pyx_v_r12 * __pyx_v_r21) + (14.0 * __pyx_v_r13)) + (__pyx_v_r44 * __pyx_v_r9)) - (__pyx_v_r73 * __pyx_v_y3)) + (54.0 * __pyx_v_r86)) - (84.0 * __pyx_v_r87)) - __pyx_v_r89) - __pyx_v_r90)) / 9240.0)) - ((__pyx_v_r4 * (((((70.0 * __pyx_v_r12) * __pyx_v_x2) + (27.0 * __pyx_v_r67)) + (42.0 * __pyx_v_r68)) + __pyx_v_r74)) / 9240.0)) + (((3.0 * __pyx_v_r67) * __pyx_v_y3) / 220.0)) - ((__pyx_v_r68 * __pyx_v_r69) / 9240.0)) - ((__pyx_v_r68 * __pyx_v_y3) / 4.0)) - (((__pyx_v_r70 * __pyx_v_r9) * ((-__pyx_v_r62) + __pyx_v_y2)) / 9240.0)) + (((3.0 * __pyx_v_r71) * (__pyx_v_r24 + __pyx_v_r40)) / 3080.0)) + ((pow(__pyx_v_x0, 3.0) * (((__pyx_v_r24 + __pyx_v_r44) + (165.0 * __pyx_v_y0)) + __pyx_v_y3)) / 660.0)) + ((__pyx_v_x0 * (((((((((((((((((((__pyx_v_r100 * __pyx_v_r27) + (162.0 * __pyx_v_r101)) + __pyx_v_r102) + __pyx_v_r11) + ((63.0 * __pyx_v_r18) * __pyx_v_y3)) + (__pyx_v_r27 * __pyx_v_r91)) - (__pyx_v_r33 * __pyx_v_y0)) - (__pyx_v_r37 * __pyx_v_x3)) + (__pyx_v_r43 * __pyx_v_x3)) - (__pyx_v_r73 * __pyx_v_y0)) - (__pyx_v_r88 * __pyx_v_y1)) + (__pyx_v_r92 * __pyx_v_y2)) - (__pyx_v_r93 * __pyx_v_y0)) - (9.0 * __pyx_v_r94)) - (__pyx_v_r95 * __pyx_v_y0)) - (__pyx_v_r96 * __pyx_v_y0)) - (__pyx_v_r97 * __pyx_v_y1)) - (18.0 * __pyx_v_r98)) + ((__pyx_v_r99 * __pyx_v_x1) * __pyx_v_y3))) / 9240.0)) - ((__pyx_v_y0 * ((((((((((__pyx_v_r12 * __pyx_v_r56) + (__pyx_v_r12 * __pyx_v_r80)) + (__pyx_v_r32 * __pyx_v_x3)) + (45.0 * __pyx_v_r67)) + (14.0 * __pyx_v_r68)) + (126.0 * __pyx_v_r71)) + __pyx_v_r74) + (__pyx_v_r85 * __pyx_v_r91)) + ((135.0 * __pyx_v_r9) * __pyx_v_x1)) + (__pyx_v_r92 * __pyx_v_x2))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":647 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r12 * r72 * (-r40 + r8) / 9240 + * + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080 + */ + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 647, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXX, __pyx_t_3) < 0) __PYX_ERR(0, 647, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":720 + * / 9240 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r103 * r12 / 18480 + * - r12 * r51 / 8 + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentXY); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":782 + * ) + * / 3080 + * - y0 # <<<<<<<<<<<<<< + * * ( + * 54 * r101 + */ + __pyx_t_1 = PyFloat_FromDouble((((((((((((((((-__pyx_v_r103) * __pyx_v_r12) / 18480.0) - ((__pyx_v_r12 * __pyx_v_r51) / 8.0)) - (((3.0 * __pyx_v_r14) * __pyx_v_y2) / 44.0)) + (((3.0 * __pyx_v_r18) * ((((__pyx_v_r105 + (__pyx_v_r2 * __pyx_v_y1)) + (18.0 * __pyx_v_r46)) + (15.0 * __pyx_v_r48)) + (7.0 * __pyx_v_r51))) / 6160.0)) + ((__pyx_v_r20 * ((((((((((1260.0 * __pyx_v_r106) + (__pyx_v_r107 * __pyx_v_y1)) + __pyx_v_r108) + (28.0 * __pyx_v_r109)) + __pyx_v_r110) + __pyx_v_r111) + __pyx_v_r112) + (30.0 * __pyx_v_r46)) + (2310.0 * __pyx_v_r55)) + __pyx_v_r66)) / 18480.0)) - ((__pyx_v_r54 * (((7.0 * __pyx_v_r12) + (18.0 * __pyx_v_r85)) + (15.0 * __pyx_v_r9))) / 18480.0)) - ((__pyx_v_r55 * (((((__pyx_v_r33 + __pyx_v_r73) + __pyx_v_r93) + __pyx_v_r95) + __pyx_v_r96) + __pyx_v_r97)) / 18480.0)) - ((__pyx_v_r7 * (((((42.0 * __pyx_v_r13) + (__pyx_v_r82 * __pyx_v_x3)) + (28.0 * __pyx_v_r87)) + __pyx_v_r89) + __pyx_v_r90)) / 18480.0)) - (((3.0 * __pyx_v_r85) * (__pyx_v_r48 - __pyx_v_r66)) / 220.0)) + ((((3.0 * __pyx_v_r9) * __pyx_v_y3) * (__pyx_v_r62 + (2.0 * __pyx_v_y2))) / 440.0)) + ((__pyx_v_x0 * (((((((((((((((((((((((-__pyx_v_r1) * __pyx_v_y0) - ((84.0 * __pyx_v_r106) * __pyx_v_x2)) + (__pyx_v_r109 * __pyx_v_r56)) + (54.0 * __pyx_v_r114)) + (__pyx_v_r117 * __pyx_v_y1)) + (15.0 * __pyx_v_r118)) + (21.0 * __pyx_v_r119)) + (81.0 * __pyx_v_r120)) + (__pyx_v_r121 * __pyx_v_r46)) + (54.0 * __pyx_v_r122)) + (60.0 * __pyx_v_r123)) + __pyx_v_r124) - ((__pyx_v_r21 * __pyx_v_x3) * __pyx_v_y0)) + (__pyx_v_r23 * __pyx_v_y3)) - (__pyx_v_r54 * __pyx_v_x3)) - (__pyx_v_r55 * __pyx_v_r72)) - (__pyx_v_r55 * __pyx_v_r76)) - (__pyx_v_r55 * __pyx_v_r77)) + ((__pyx_v_r57 * __pyx_v_y0) * __pyx_v_y3)) + (__pyx_v_r60 * __pyx_v_x3)) + ((84.0 * __pyx_v_r81) * __pyx_v_y0)) + ((189.0 * __pyx_v_r81) * __pyx_v_y1))) / 9240.0)) + ((__pyx_v_x1 * ((((((((__pyx_v_r104 * __pyx_v_r27) - (__pyx_v_r105 * __pyx_v_x3)) - (__pyx_v_r113 * __pyx_v_r53)) + (63.0 * __pyx_v_r114)) + __pyx_v_r115) - (__pyx_v_r16 * __pyx_v_r53)) + (28.0 * __pyx_v_r47)) + (__pyx_v_r51 * __pyx_v_r80))) / 3080.0)) - ((__pyx_v_y0 * (((((((((((((54.0 * __pyx_v_r101) + __pyx_v_r102) + (__pyx_v_r116 * __pyx_v_r5)) + (__pyx_v_r117 * __pyx_v_x3)) + (21.0 * __pyx_v_r13)) - (__pyx_v_r19 * __pyx_v_y3)) + (__pyx_v_r22 * __pyx_v_y3)) + (__pyx_v_r78 * __pyx_v_x3)) + ((189.0 * __pyx_v_r83) * __pyx_v_x2)) + (60.0 * __pyx_v_r86)) + ((81.0 * __pyx_v_r9) * __pyx_v_y1)) + (15.0 * __pyx_v_r94)) + (54.0 * __pyx_v_r98))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":720 + * / 9240 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r103 * r12 / 18480 + * - r12 * r51 / 8 + */ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentXY, __pyx_t_2) < 0) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":800 + * / 9240 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r103 * r116 / 9240 + * - r125 * r70 / 9240 + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 800, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":848 + * / 3080 + * + 3 * x2 * y3 * (r48 + r66 + r8 * y3) / 220 + * - y0 # <<<<<<<<<<<<<< + * * ( + * r100 * r46 + */ + __pyx_t_1 = PyFloat_FromDouble((((((((((((((((-__pyx_v_r103) * __pyx_v_r116) / 9240.0) - ((__pyx_v_r125 * __pyx_v_r70) / 9240.0)) - ((__pyx_v_r126 * __pyx_v_x3) / 12.0)) - (((3.0 * __pyx_v_r127) * (__pyx_v_r26 + __pyx_v_r38)) / 3080.0)) - ((__pyx_v_r128 * ((__pyx_v_r26 + __pyx_v_r30) + __pyx_v_x3)) / 660.0)) - ((__pyx_v_r4 * ((((__pyx_v_r112 * __pyx_v_x3) + __pyx_v_r115) - (14.0 * __pyx_v_r119)) + (84.0 * __pyx_v_r47))) / 9240.0)) - ((__pyx_v_r52 * __pyx_v_r69) / 9240.0)) - ((__pyx_v_r54 * ((__pyx_v_r58 + __pyx_v_r61) + __pyx_v_r75)) / 9240.0)) - ((__pyx_v_r55 * ((((((__pyx_v_r100 * __pyx_v_y1) + (__pyx_v_r121 * __pyx_v_y2)) + (__pyx_v_r26 * __pyx_v_y3)) + (__pyx_v_r79 * __pyx_v_y2)) + __pyx_v_r84) + ((210.0 * __pyx_v_x2) * __pyx_v_y1))) / 9240.0)) + ((__pyx_v_x0 * (((((((((((((((((((__pyx_v_r108 * __pyx_v_y1) + (__pyx_v_r110 * __pyx_v_y0)) + (__pyx_v_r111 * __pyx_v_y0)) + (__pyx_v_r112 * __pyx_v_y0)) + (45.0 * __pyx_v_r125)) + (14.0 * __pyx_v_r126)) + (126.0 * __pyx_v_r127)) + (770.0 * __pyx_v_r128)) + (42.0 * __pyx_v_r129)) + __pyx_v_r130) + (__pyx_v_r131 * __pyx_v_y2)) + (__pyx_v_r132 * __pyx_v_r64)) + ((135.0 * __pyx_v_r48) * __pyx_v_y1)) + ((630.0 * __pyx_v_r55) * __pyx_v_y1)) + ((126.0 * __pyx_v_r55) * __pyx_v_y2)) + ((14.0 * __pyx_v_r55) * __pyx_v_y3)) + (__pyx_v_r63 * __pyx_v_y3)) + (__pyx_v_r65 * __pyx_v_y3)) + (__pyx_v_r66 * __pyx_v_y0))) / 9240.0)) + ((__pyx_v_x1 * ((((((((27.0 * __pyx_v_r125) + (42.0 * __pyx_v_r126)) + (70.0 * __pyx_v_r129)) + __pyx_v_r130) + (__pyx_v_r39 * __pyx_v_r53)) + (__pyx_v_r44 * __pyx_v_r48)) + ((27.0 * __pyx_v_r53) * __pyx_v_y2)) + ((54.0 * __pyx_v_r64) * __pyx_v_y2))) / 3080.0)) + ((((3.0 * __pyx_v_x2) * __pyx_v_y3) * ((__pyx_v_r48 + __pyx_v_r66) + (__pyx_v_r8 * __pyx_v_y3))) / 220.0)) - ((__pyx_v_y0 * (((((((((((((__pyx_v_r100 * __pyx_v_r46) + (18.0 * __pyx_v_r114)) - (9.0 * __pyx_v_r118)) - (27.0 * __pyx_v_r120)) - (18.0 * __pyx_v_r122)) - (30.0 * __pyx_v_r123)) + __pyx_v_r124) + (__pyx_v_r131 * __pyx_v_x2)) + ((__pyx_v_r132 * __pyx_v_x3) * __pyx_v_y1)) + ((162.0 * __pyx_v_r42) * __pyx_v_y1)) + __pyx_v_r50) + ((63.0 * __pyx_v_r53) * __pyx_v_x3)) + (__pyx_v_r64 * __pyx_v_r99))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":800 + * / 9240 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r103 * r116 / 9240 + * - r125 * r70 / 9240 + */ + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 800, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_momentYY, __pyx_t_3) < 0) __PYX_ERR(0, 800, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":312 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._curveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, + {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, + {&__pyx_n_s_BasePen, __pyx_k_BasePen, sizeof(__pyx_k_BasePen), 0, 0, 1, 1}, + {&__pyx_n_s_COMPILED, __pyx_k_COMPILED, sizeof(__pyx_k_COMPILED), 0, 0, 1, 1}, + {&__pyx_kp_u_Glyph_statistics_not_defined_on, __pyx_k_Glyph_statistics_not_defined_on, sizeof(__pyx_k_Glyph_statistics_not_defined_on), 0, 1, 0, 0}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_k_Lib_fontTools_pens_momentsPen_py, sizeof(__pyx_k_Lib_fontTools_pens_momentsPen_py), 0, 0, 1, 0}, + {&__pyx_n_s_MomentsPen, __pyx_k_MomentsPen, sizeof(__pyx_k_MomentsPen), 0, 0, 1, 1}, + {&__pyx_n_u_MomentsPen, __pyx_k_MomentsPen, sizeof(__pyx_k_MomentsPen), 0, 1, 0, 1}, + {&__pyx_n_s_MomentsPen___init, __pyx_k_MomentsPen___init, sizeof(__pyx_k_MomentsPen___init), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__closePath, __pyx_k_MomentsPen__closePath, sizeof(__pyx_k_MomentsPen__closePath), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__curveToOne, __pyx_k_MomentsPen__curveToOne, sizeof(__pyx_k_MomentsPen__curveToOne), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__endPath, __pyx_k_MomentsPen__endPath, sizeof(__pyx_k_MomentsPen__endPath), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__lineTo, __pyx_k_MomentsPen__lineTo, sizeof(__pyx_k_MomentsPen__lineTo), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__moveTo, __pyx_k_MomentsPen__moveTo, sizeof(__pyx_k_MomentsPen__moveTo), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__qCurveToOne, __pyx_k_MomentsPen__qCurveToOne, sizeof(__pyx_k_MomentsPen__qCurveToOne), 0, 0, 1, 1}, + {&__pyx_n_s_MomentsPen__startPoint, __pyx_k_MomentsPen__startPoint, sizeof(__pyx_k_MomentsPen__startPoint), 0, 0, 1, 1}, + {&__pyx_n_s_OpenContourError, __pyx_k_OpenContourError, sizeof(__pyx_k_OpenContourError), 0, 0, 1, 1}, + {&__pyx_n_s__16, __pyx_k__16, sizeof(__pyx_k__16), 0, 0, 1, 1}, + {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, + {&__pyx_n_s_area, __pyx_k_area, sizeof(__pyx_k_area), 0, 0, 1, 1}, + {&__pyx_n_u_area, __pyx_k_area, sizeof(__pyx_k_area), 0, 1, 0, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_closePath, __pyx_k_closePath, sizeof(__pyx_k_closePath), 0, 0, 1, 1}, + {&__pyx_n_s_curveToOne, __pyx_k_curveToOne, sizeof(__pyx_k_curveToOne), 0, 0, 1, 1}, + {&__pyx_n_s_cython, __pyx_k_cython, sizeof(__pyx_k_cython), 0, 0, 1, 1}, + {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, + {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, + {&__pyx_n_s_endPath, __pyx_k_endPath, sizeof(__pyx_k_endPath), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc, __pyx_k_fontTools_misc, sizeof(__pyx_k_fontTools_misc), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc_symfont, __pyx_k_fontTools_misc_symfont, sizeof(__pyx_k_fontTools_misc_symfont), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_pens_basePen, __pyx_k_fontTools_pens_basePen, sizeof(__pyx_k_fontTools_pens_basePen), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_pens_momentsPen, __pyx_k_fontTools_pens_momentsPen, sizeof(__pyx_k_fontTools_pens_momentsPen), 0, 0, 1, 1}, + {&__pyx_n_s_getCurrentPoint, __pyx_k_getCurrentPoint, sizeof(__pyx_k_getCurrentPoint), 0, 0, 1, 1}, + {&__pyx_n_s_glyphset, __pyx_k_glyphset, sizeof(__pyx_k_glyphset), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1}, + {&__pyx_n_s_init_subclass, __pyx_k_init_subclass, sizeof(__pyx_k_init_subclass), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_n_s_lineTo, __pyx_k_lineTo, sizeof(__pyx_k_lineTo), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_u_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 1, 0, 1}, + {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1}, + {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1}, + {&__pyx_n_s_momentX, __pyx_k_momentX, sizeof(__pyx_k_momentX), 0, 0, 1, 1}, + {&__pyx_n_u_momentX, __pyx_k_momentX, sizeof(__pyx_k_momentX), 0, 1, 0, 1}, + {&__pyx_n_s_momentXX, __pyx_k_momentXX, sizeof(__pyx_k_momentXX), 0, 0, 1, 1}, + {&__pyx_n_u_momentXX, __pyx_k_momentXX, sizeof(__pyx_k_momentXX), 0, 1, 0, 1}, + {&__pyx_n_s_momentXY, __pyx_k_momentXY, sizeof(__pyx_k_momentXY), 0, 0, 1, 1}, + {&__pyx_n_u_momentXY, __pyx_k_momentXY, sizeof(__pyx_k_momentXY), 0, 1, 0, 1}, + {&__pyx_n_s_momentY, __pyx_k_momentY, sizeof(__pyx_k_momentY), 0, 0, 1, 1}, + {&__pyx_n_u_momentY, __pyx_k_momentY, sizeof(__pyx_k_momentY), 0, 1, 0, 1}, + {&__pyx_n_s_momentYY, __pyx_k_momentYY, sizeof(__pyx_k_momentYY), 0, 0, 1, 1}, + {&__pyx_n_u_momentYY, __pyx_k_momentYY, sizeof(__pyx_k_momentYY), 0, 1, 0, 1}, + {&__pyx_n_s_moveTo, __pyx_k_moveTo, sizeof(__pyx_k_moveTo), 0, 0, 1, 1}, + {&__pyx_n_s_mro_entries, __pyx_k_mro_entries, sizeof(__pyx_k_mro_entries), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_p0, __pyx_k_p0, sizeof(__pyx_k_p0), 0, 0, 1, 1}, + {&__pyx_n_s_p1, __pyx_k_p1, sizeof(__pyx_k_p1), 0, 0, 1, 1}, + {&__pyx_n_s_p2, __pyx_k_p2, sizeof(__pyx_k_p2), 0, 0, 1, 1}, + {&__pyx_n_s_p3, __pyx_k_p3, sizeof(__pyx_k_p3), 0, 0, 1, 1}, + {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1}, + {&__pyx_n_s_printGreenPen, __pyx_k_printGreenPen, sizeof(__pyx_k_printGreenPen), 0, 0, 1, 1}, + {&__pyx_n_s_qCurveToOne, __pyx_k_qCurveToOne, sizeof(__pyx_k_qCurveToOne), 0, 0, 1, 1}, + {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1}, + {&__pyx_n_s_r0, __pyx_k_r0, sizeof(__pyx_k_r0), 0, 0, 1, 1}, + {&__pyx_n_s_r1, __pyx_k_r1, sizeof(__pyx_k_r1), 0, 0, 1, 1}, + {&__pyx_n_s_r10, __pyx_k_r10, sizeof(__pyx_k_r10), 0, 0, 1, 1}, + {&__pyx_n_s_r100, __pyx_k_r100, sizeof(__pyx_k_r100), 0, 0, 1, 1}, + {&__pyx_n_s_r101, __pyx_k_r101, sizeof(__pyx_k_r101), 0, 0, 1, 1}, + {&__pyx_n_s_r102, __pyx_k_r102, sizeof(__pyx_k_r102), 0, 0, 1, 1}, + {&__pyx_n_s_r103, __pyx_k_r103, sizeof(__pyx_k_r103), 0, 0, 1, 1}, + {&__pyx_n_s_r104, __pyx_k_r104, sizeof(__pyx_k_r104), 0, 0, 1, 1}, + {&__pyx_n_s_r105, __pyx_k_r105, sizeof(__pyx_k_r105), 0, 0, 1, 1}, + {&__pyx_n_s_r106, __pyx_k_r106, sizeof(__pyx_k_r106), 0, 0, 1, 1}, + {&__pyx_n_s_r107, __pyx_k_r107, sizeof(__pyx_k_r107), 0, 0, 1, 1}, + {&__pyx_n_s_r108, __pyx_k_r108, sizeof(__pyx_k_r108), 0, 0, 1, 1}, + {&__pyx_n_s_r109, __pyx_k_r109, sizeof(__pyx_k_r109), 0, 0, 1, 1}, + {&__pyx_n_s_r11, __pyx_k_r11, sizeof(__pyx_k_r11), 0, 0, 1, 1}, + {&__pyx_n_s_r110, __pyx_k_r110, sizeof(__pyx_k_r110), 0, 0, 1, 1}, + {&__pyx_n_s_r111, __pyx_k_r111, sizeof(__pyx_k_r111), 0, 0, 1, 1}, + {&__pyx_n_s_r112, __pyx_k_r112, sizeof(__pyx_k_r112), 0, 0, 1, 1}, + {&__pyx_n_s_r113, __pyx_k_r113, sizeof(__pyx_k_r113), 0, 0, 1, 1}, + {&__pyx_n_s_r114, __pyx_k_r114, sizeof(__pyx_k_r114), 0, 0, 1, 1}, + {&__pyx_n_s_r115, __pyx_k_r115, sizeof(__pyx_k_r115), 0, 0, 1, 1}, + {&__pyx_n_s_r116, __pyx_k_r116, sizeof(__pyx_k_r116), 0, 0, 1, 1}, + {&__pyx_n_s_r117, __pyx_k_r117, sizeof(__pyx_k_r117), 0, 0, 1, 1}, + {&__pyx_n_s_r118, __pyx_k_r118, sizeof(__pyx_k_r118), 0, 0, 1, 1}, + {&__pyx_n_s_r119, __pyx_k_r119, sizeof(__pyx_k_r119), 0, 0, 1, 1}, + {&__pyx_n_s_r12, __pyx_k_r12, sizeof(__pyx_k_r12), 0, 0, 1, 1}, + {&__pyx_n_s_r120, __pyx_k_r120, sizeof(__pyx_k_r120), 0, 0, 1, 1}, + {&__pyx_n_s_r121, __pyx_k_r121, sizeof(__pyx_k_r121), 0, 0, 1, 1}, + {&__pyx_n_s_r122, __pyx_k_r122, sizeof(__pyx_k_r122), 0, 0, 1, 1}, + {&__pyx_n_s_r123, __pyx_k_r123, sizeof(__pyx_k_r123), 0, 0, 1, 1}, + {&__pyx_n_s_r124, __pyx_k_r124, sizeof(__pyx_k_r124), 0, 0, 1, 1}, + {&__pyx_n_s_r125, __pyx_k_r125, sizeof(__pyx_k_r125), 0, 0, 1, 1}, + {&__pyx_n_s_r126, __pyx_k_r126, sizeof(__pyx_k_r126), 0, 0, 1, 1}, + {&__pyx_n_s_r127, __pyx_k_r127, sizeof(__pyx_k_r127), 0, 0, 1, 1}, + {&__pyx_n_s_r128, __pyx_k_r128, sizeof(__pyx_k_r128), 0, 0, 1, 1}, + {&__pyx_n_s_r129, __pyx_k_r129, sizeof(__pyx_k_r129), 0, 0, 1, 1}, + {&__pyx_n_s_r13, __pyx_k_r13, sizeof(__pyx_k_r13), 0, 0, 1, 1}, + {&__pyx_n_s_r130, __pyx_k_r130, sizeof(__pyx_k_r130), 0, 0, 1, 1}, + {&__pyx_n_s_r131, __pyx_k_r131, sizeof(__pyx_k_r131), 0, 0, 1, 1}, + {&__pyx_n_s_r132, __pyx_k_r132, sizeof(__pyx_k_r132), 0, 0, 1, 1}, + {&__pyx_n_s_r14, __pyx_k_r14, sizeof(__pyx_k_r14), 0, 0, 1, 1}, + {&__pyx_n_s_r15, __pyx_k_r15, sizeof(__pyx_k_r15), 0, 0, 1, 1}, + {&__pyx_n_s_r16, __pyx_k_r16, sizeof(__pyx_k_r16), 0, 0, 1, 1}, + {&__pyx_n_s_r17, __pyx_k_r17, sizeof(__pyx_k_r17), 0, 0, 1, 1}, + {&__pyx_n_s_r18, __pyx_k_r18, sizeof(__pyx_k_r18), 0, 0, 1, 1}, + {&__pyx_n_s_r19, __pyx_k_r19, sizeof(__pyx_k_r19), 0, 0, 1, 1}, + {&__pyx_n_s_r2, __pyx_k_r2, sizeof(__pyx_k_r2), 0, 0, 1, 1}, + {&__pyx_n_s_r20, __pyx_k_r20, sizeof(__pyx_k_r20), 0, 0, 1, 1}, + {&__pyx_n_s_r21, __pyx_k_r21, sizeof(__pyx_k_r21), 0, 0, 1, 1}, + {&__pyx_n_s_r22, __pyx_k_r22, sizeof(__pyx_k_r22), 0, 0, 1, 1}, + {&__pyx_n_s_r23, __pyx_k_r23, sizeof(__pyx_k_r23), 0, 0, 1, 1}, + {&__pyx_n_s_r24, __pyx_k_r24, sizeof(__pyx_k_r24), 0, 0, 1, 1}, + {&__pyx_n_s_r25, __pyx_k_r25, sizeof(__pyx_k_r25), 0, 0, 1, 1}, + {&__pyx_n_s_r26, __pyx_k_r26, sizeof(__pyx_k_r26), 0, 0, 1, 1}, + {&__pyx_n_s_r27, __pyx_k_r27, sizeof(__pyx_k_r27), 0, 0, 1, 1}, + {&__pyx_n_s_r28, __pyx_k_r28, sizeof(__pyx_k_r28), 0, 0, 1, 1}, + {&__pyx_n_s_r29, __pyx_k_r29, sizeof(__pyx_k_r29), 0, 0, 1, 1}, + {&__pyx_n_s_r3, __pyx_k_r3, sizeof(__pyx_k_r3), 0, 0, 1, 1}, + {&__pyx_n_s_r30, __pyx_k_r30, sizeof(__pyx_k_r30), 0, 0, 1, 1}, + {&__pyx_n_s_r31, __pyx_k_r31, sizeof(__pyx_k_r31), 0, 0, 1, 1}, + {&__pyx_n_s_r32, __pyx_k_r32, sizeof(__pyx_k_r32), 0, 0, 1, 1}, + {&__pyx_n_s_r33, __pyx_k_r33, sizeof(__pyx_k_r33), 0, 0, 1, 1}, + {&__pyx_n_s_r34, __pyx_k_r34, sizeof(__pyx_k_r34), 0, 0, 1, 1}, + {&__pyx_n_s_r35, __pyx_k_r35, sizeof(__pyx_k_r35), 0, 0, 1, 1}, + {&__pyx_n_s_r36, __pyx_k_r36, sizeof(__pyx_k_r36), 0, 0, 1, 1}, + {&__pyx_n_s_r37, __pyx_k_r37, sizeof(__pyx_k_r37), 0, 0, 1, 1}, + {&__pyx_n_s_r38, __pyx_k_r38, sizeof(__pyx_k_r38), 0, 0, 1, 1}, + {&__pyx_n_s_r39, __pyx_k_r39, sizeof(__pyx_k_r39), 0, 0, 1, 1}, + {&__pyx_n_s_r4, __pyx_k_r4, sizeof(__pyx_k_r4), 0, 0, 1, 1}, + {&__pyx_n_s_r40, __pyx_k_r40, sizeof(__pyx_k_r40), 0, 0, 1, 1}, + {&__pyx_n_s_r41, __pyx_k_r41, sizeof(__pyx_k_r41), 0, 0, 1, 1}, + {&__pyx_n_s_r42, __pyx_k_r42, sizeof(__pyx_k_r42), 0, 0, 1, 1}, + {&__pyx_n_s_r43, __pyx_k_r43, sizeof(__pyx_k_r43), 0, 0, 1, 1}, + {&__pyx_n_s_r44, __pyx_k_r44, sizeof(__pyx_k_r44), 0, 0, 1, 1}, + {&__pyx_n_s_r45, __pyx_k_r45, sizeof(__pyx_k_r45), 0, 0, 1, 1}, + {&__pyx_n_s_r46, __pyx_k_r46, sizeof(__pyx_k_r46), 0, 0, 1, 1}, + {&__pyx_n_s_r47, __pyx_k_r47, sizeof(__pyx_k_r47), 0, 0, 1, 1}, + {&__pyx_n_s_r48, __pyx_k_r48, sizeof(__pyx_k_r48), 0, 0, 1, 1}, + {&__pyx_n_s_r49, __pyx_k_r49, sizeof(__pyx_k_r49), 0, 0, 1, 1}, + {&__pyx_n_s_r5, __pyx_k_r5, sizeof(__pyx_k_r5), 0, 0, 1, 1}, + {&__pyx_n_s_r50, __pyx_k_r50, sizeof(__pyx_k_r50), 0, 0, 1, 1}, + {&__pyx_n_s_r51, __pyx_k_r51, sizeof(__pyx_k_r51), 0, 0, 1, 1}, + {&__pyx_n_s_r52, __pyx_k_r52, sizeof(__pyx_k_r52), 0, 0, 1, 1}, + {&__pyx_n_s_r53, __pyx_k_r53, sizeof(__pyx_k_r53), 0, 0, 1, 1}, + {&__pyx_n_s_r54, __pyx_k_r54, sizeof(__pyx_k_r54), 0, 0, 1, 1}, + {&__pyx_n_s_r55, __pyx_k_r55, sizeof(__pyx_k_r55), 0, 0, 1, 1}, + {&__pyx_n_s_r56, __pyx_k_r56, sizeof(__pyx_k_r56), 0, 0, 1, 1}, + {&__pyx_n_s_r57, __pyx_k_r57, sizeof(__pyx_k_r57), 0, 0, 1, 1}, + {&__pyx_n_s_r58, __pyx_k_r58, sizeof(__pyx_k_r58), 0, 0, 1, 1}, + {&__pyx_n_s_r59, __pyx_k_r59, sizeof(__pyx_k_r59), 0, 0, 1, 1}, + {&__pyx_n_s_r6, __pyx_k_r6, sizeof(__pyx_k_r6), 0, 0, 1, 1}, + {&__pyx_n_s_r60, __pyx_k_r60, sizeof(__pyx_k_r60), 0, 0, 1, 1}, + {&__pyx_n_s_r61, __pyx_k_r61, sizeof(__pyx_k_r61), 0, 0, 1, 1}, + {&__pyx_n_s_r62, __pyx_k_r62, sizeof(__pyx_k_r62), 0, 0, 1, 1}, + {&__pyx_n_s_r63, __pyx_k_r63, sizeof(__pyx_k_r63), 0, 0, 1, 1}, + {&__pyx_n_s_r64, __pyx_k_r64, sizeof(__pyx_k_r64), 0, 0, 1, 1}, + {&__pyx_n_s_r65, __pyx_k_r65, sizeof(__pyx_k_r65), 0, 0, 1, 1}, + {&__pyx_n_s_r66, __pyx_k_r66, sizeof(__pyx_k_r66), 0, 0, 1, 1}, + {&__pyx_n_s_r67, __pyx_k_r67, sizeof(__pyx_k_r67), 0, 0, 1, 1}, + {&__pyx_n_s_r68, __pyx_k_r68, sizeof(__pyx_k_r68), 0, 0, 1, 1}, + {&__pyx_n_s_r69, __pyx_k_r69, sizeof(__pyx_k_r69), 0, 0, 1, 1}, + {&__pyx_n_s_r7, __pyx_k_r7, sizeof(__pyx_k_r7), 0, 0, 1, 1}, + {&__pyx_n_s_r70, __pyx_k_r70, sizeof(__pyx_k_r70), 0, 0, 1, 1}, + {&__pyx_n_s_r71, __pyx_k_r71, sizeof(__pyx_k_r71), 0, 0, 1, 1}, + {&__pyx_n_s_r72, __pyx_k_r72, sizeof(__pyx_k_r72), 0, 0, 1, 1}, + {&__pyx_n_s_r73, __pyx_k_r73, sizeof(__pyx_k_r73), 0, 0, 1, 1}, + {&__pyx_n_s_r74, __pyx_k_r74, sizeof(__pyx_k_r74), 0, 0, 1, 1}, + {&__pyx_n_s_r75, __pyx_k_r75, sizeof(__pyx_k_r75), 0, 0, 1, 1}, + {&__pyx_n_s_r76, __pyx_k_r76, sizeof(__pyx_k_r76), 0, 0, 1, 1}, + {&__pyx_n_s_r77, __pyx_k_r77, sizeof(__pyx_k_r77), 0, 0, 1, 1}, + {&__pyx_n_s_r78, __pyx_k_r78, sizeof(__pyx_k_r78), 0, 0, 1, 1}, + {&__pyx_n_s_r79, __pyx_k_r79, sizeof(__pyx_k_r79), 0, 0, 1, 1}, + {&__pyx_n_s_r8, __pyx_k_r8, sizeof(__pyx_k_r8), 0, 0, 1, 1}, + {&__pyx_n_s_r80, __pyx_k_r80, sizeof(__pyx_k_r80), 0, 0, 1, 1}, + {&__pyx_n_s_r81, __pyx_k_r81, sizeof(__pyx_k_r81), 0, 0, 1, 1}, + {&__pyx_n_s_r82, __pyx_k_r82, sizeof(__pyx_k_r82), 0, 0, 1, 1}, + {&__pyx_n_s_r83, __pyx_k_r83, sizeof(__pyx_k_r83), 0, 0, 1, 1}, + {&__pyx_n_s_r84, __pyx_k_r84, sizeof(__pyx_k_r84), 0, 0, 1, 1}, + {&__pyx_n_s_r85, __pyx_k_r85, sizeof(__pyx_k_r85), 0, 0, 1, 1}, + {&__pyx_n_s_r86, __pyx_k_r86, sizeof(__pyx_k_r86), 0, 0, 1, 1}, + {&__pyx_n_s_r87, __pyx_k_r87, sizeof(__pyx_k_r87), 0, 0, 1, 1}, + {&__pyx_n_s_r88, __pyx_k_r88, sizeof(__pyx_k_r88), 0, 0, 1, 1}, + {&__pyx_n_s_r89, __pyx_k_r89, sizeof(__pyx_k_r89), 0, 0, 1, 1}, + {&__pyx_n_s_r9, __pyx_k_r9, sizeof(__pyx_k_r9), 0, 0, 1, 1}, + {&__pyx_n_s_r90, __pyx_k_r90, sizeof(__pyx_k_r90), 0, 0, 1, 1}, + {&__pyx_n_s_r91, __pyx_k_r91, sizeof(__pyx_k_r91), 0, 0, 1, 1}, + {&__pyx_n_s_r92, __pyx_k_r92, sizeof(__pyx_k_r92), 0, 0, 1, 1}, + {&__pyx_n_s_r93, __pyx_k_r93, sizeof(__pyx_k_r93), 0, 0, 1, 1}, + {&__pyx_n_s_r94, __pyx_k_r94, sizeof(__pyx_k_r94), 0, 0, 1, 1}, + {&__pyx_n_s_r95, __pyx_k_r95, sizeof(__pyx_k_r95), 0, 0, 1, 1}, + {&__pyx_n_s_r96, __pyx_k_r96, sizeof(__pyx_k_r96), 0, 0, 1, 1}, + {&__pyx_n_s_r97, __pyx_k_r97, sizeof(__pyx_k_r97), 0, 0, 1, 1}, + {&__pyx_n_s_r98, __pyx_k_r98, sizeof(__pyx_k_r98), 0, 0, 1, 1}, + {&__pyx_n_s_r99, __pyx_k_r99, sizeof(__pyx_k_r99), 0, 0, 1, 1}, + {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, + {&__pyx_n_s_set_name, __pyx_k_set_name, sizeof(__pyx_k_set_name), 0, 0, 1, 1}, + {&__pyx_n_s_super, __pyx_k_super, sizeof(__pyx_k_super), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {&__pyx_n_s_x0, __pyx_k_x0, sizeof(__pyx_k_x0), 0, 0, 1, 1}, + {&__pyx_n_s_x1, __pyx_k_x1, sizeof(__pyx_k_x1), 0, 0, 1, 1}, + {&__pyx_n_s_x2, __pyx_k_x2, sizeof(__pyx_k_x2), 0, 0, 1, 1}, + {&__pyx_n_s_x3, __pyx_k_x3, sizeof(__pyx_k_x3), 0, 0, 1, 1}, + {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, + {&__pyx_n_s_y0, __pyx_k_y0, sizeof(__pyx_k_y0), 0, 0, 1, 1}, + {&__pyx_n_s_y1, __pyx_k_y1, sizeof(__pyx_k_y1), 0, 0, 1, 1}, + {&__pyx_n_s_y2, __pyx_k_y2, sizeof(__pyx_k_y2), 0, 0, 1, 1}, + {&__pyx_n_s_y3, __pyx_k_y3, sizeof(__pyx_k_y3), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 7, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(0, 7, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/pens/momentsPen.py":18 + * + * class MomentsPen(BasePen): + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * + */ + __pyx_tuple__2 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_glyphset); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_init, 18, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(0, 18, __pyx_L1_error) + __pyx_tuple__4 = PyTuple_Pack(1, Py_None); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "fontTools/pens/momentsPen.py":28 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self.__startPoint = p0 + * + */ + __pyx_tuple__5 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_p0); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_moveTo, 28, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 28, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":31 + * self.__startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + __pyx_codeobj__7 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_closePath, 31, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__7)) __PYX_ERR(0, 31, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":36 + * self._lineTo(self.__startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_endPath, 36, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 36, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":41 + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_tuple__9 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_p1, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x0, __pyx_n_s_y0, __pyx_n_s_r12, __pyx_n_s_r11, __pyx_n_s_r10, __pyx_n_s_r9, __pyx_n_s_r8, __pyx_n_s_r7, __pyx_n_s_r6, __pyx_n_s_r5, __pyx_n_s_r4, __pyx_n_s_r3, __pyx_n_s_r2, __pyx_n_s_r1, __pyx_n_s_r0); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 41, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_lineTo, 41, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) __PYX_ERR(0, 41, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":101 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_tuple__11 = PyTuple_Pack(63, __pyx_n_s_self, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x0, __pyx_n_s_y0, __pyx_n_s_r53, __pyx_n_s_r52, __pyx_n_s_r51, __pyx_n_s_r50, __pyx_n_s_r49, __pyx_n_s_r48, __pyx_n_s_r47, __pyx_n_s_r46, __pyx_n_s_r45, __pyx_n_s_r44, __pyx_n_s_r43, __pyx_n_s_r42, __pyx_n_s_r41, __pyx_n_s_r40, __pyx_n_s_r39, __pyx_n_s_r38, __pyx_n_s_r37, __pyx_n_s_r36, __pyx_n_s_r35, __pyx_n_s_r34, __pyx_n_s_r33, __pyx_n_s_r32, __pyx_n_s_r31, __pyx_n_s_r30, __pyx_n_s_r29, __pyx_n_s_r28, __pyx_n_s_r27, __pyx_n_s_r26, __pyx_n_s_r25, __pyx_n_s_r24, __pyx_n_s_r23, __pyx_n_s_r22, __pyx_n_s_r21, __pyx_n_s_r20, __pyx_n_s_r19, __pyx_n_s_r18, __pyx_n_s_r17, __pyx_n_s_r16, __pyx_n_s_r15, __pyx_n_s_r14, __pyx_n_s_r13, __pyx_n_s_r12, __pyx_n_s_r11, __pyx_n_s_r10, __pyx_n_s_r9, __pyx_n_s_r8, __pyx_n_s_r7, __pyx_n_s_r6, __pyx_n_s_r5, __pyx_n_s_r4, __pyx_n_s_r3, __pyx_n_s_r2, __pyx_n_s_r1, __pyx_n_s_r0); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 63, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_qCurveToOne, 101, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) __PYX_ERR(0, 101, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":312 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_tuple__13 = PyTuple_Pack(145, __pyx_n_s_self, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p3, __pyx_n_s_x3, __pyx_n_s_y3, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x0, __pyx_n_s_y0, __pyx_n_s_r132, __pyx_n_s_r131, __pyx_n_s_r130, __pyx_n_s_r129, __pyx_n_s_r128, __pyx_n_s_r127, __pyx_n_s_r126, __pyx_n_s_r125, __pyx_n_s_r124, __pyx_n_s_r123, __pyx_n_s_r122, __pyx_n_s_r121, __pyx_n_s_r120, __pyx_n_s_r119, __pyx_n_s_r118, __pyx_n_s_r117, __pyx_n_s_r116, __pyx_n_s_r115, __pyx_n_s_r114, __pyx_n_s_r113, __pyx_n_s_r112, __pyx_n_s_r111, __pyx_n_s_r110, __pyx_n_s_r109, __pyx_n_s_r108, __pyx_n_s_r107, __pyx_n_s_r106, __pyx_n_s_r105, __pyx_n_s_r104, __pyx_n_s_r103, __pyx_n_s_r102, __pyx_n_s_r101, __pyx_n_s_r100, __pyx_n_s_r99, __pyx_n_s_r98, __pyx_n_s_r97, __pyx_n_s_r96, __pyx_n_s_r95, __pyx_n_s_r94, __pyx_n_s_r93, __pyx_n_s_r92, __pyx_n_s_r91, __pyx_n_s_r90, __pyx_n_s_r89, __pyx_n_s_r88, __pyx_n_s_r87, __pyx_n_s_r86, __pyx_n_s_r85, __pyx_n_s_r84, __pyx_n_s_r83, __pyx_n_s_r82, __pyx_n_s_r81, __pyx_n_s_r80, __pyx_n_s_r79, __pyx_n_s_r78, __pyx_n_s_r77, __pyx_n_s_r76, __pyx_n_s_r75, __pyx_n_s_r74, __pyx_n_s_r73, __pyx_n_s_r72, __pyx_n_s_r71, __pyx_n_s_r70, __pyx_n_s_r69, __pyx_n_s_r68, __pyx_n_s_r67, __pyx_n_s_r66, __pyx_n_s_r65, __pyx_n_s_r64, __pyx_n_s_r63, __pyx_n_s_r62, __pyx_n_s_r61, __pyx_n_s_r60, __pyx_n_s_r59, __pyx_n_s_r58, __pyx_n_s_r57, __pyx_n_s_r56, __pyx_n_s_r55, __pyx_n_s_r54, __pyx_n_s_r53, __pyx_n_s_r52, __pyx_n_s_r51, __pyx_n_s_r50, __pyx_n_s_r49, __pyx_n_s_r48, __pyx_n_s_r47, __pyx_n_s_r46, __pyx_n_s_r45, __pyx_n_s_r44, __pyx_n_s_r43, __pyx_n_s_r42, __pyx_n_s_r41, __pyx_n_s_r40, __pyx_n_s_r39, __pyx_n_s_r38, __pyx_n_s_r37, __pyx_n_s_r36, __pyx_n_s_r35, __pyx_n_s_r34, __pyx_n_s_r33, __pyx_n_s_r32, __pyx_n_s_r31, __pyx_n_s_r30, __pyx_n_s_r29, __pyx_n_s_r28, __pyx_n_s_r27, __pyx_n_s_r26, __pyx_n_s_r25, __pyx_n_s_r24, __pyx_n_s_r23, __pyx_n_s_r22, __pyx_n_s_r21, __pyx_n_s_r20, __pyx_n_s_r19, __pyx_n_s_r18, __pyx_n_s_r17, __pyx_n_s_r16, __pyx_n_s_r15, __pyx_n_s_r14, __pyx_n_s_r13, __pyx_n_s_r12, __pyx_n_s_r11, __pyx_n_s_r10, __pyx_n_s_r9, __pyx_n_s_r8, __pyx_n_s_r7, __pyx_n_s_r6, __pyx_n_s_r5, __pyx_n_s_r4, __pyx_n_s_r3, __pyx_n_s_r2, __pyx_n_s_r1, __pyx_n_s_r0); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 312, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 145, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_pens_momentsPen_py, __pyx_n_s_curveToOne, 312, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 312, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":874 + * "MomentsPen", + * [ + * ("area", 1), # <<<<<<<<<<<<<< + * ("momentX", x), + * ("momentY", y), + */ + __pyx_tuple__15 = PyTuple_Pack(2, __pyx_n_u_area, __pyx_int_1); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 874, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + return 0; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_momentsPen(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_momentsPen}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "momentsPen", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initmomentsPen(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initmomentsPen(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_momentsPen(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_momentsPen(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_momentsPen(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'momentsPen' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("momentsPen", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to momentsPen pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_momentsPen(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_fontTools__pens__momentsPen) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.pens.momentsPen")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.pens.momentsPen", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "fontTools/pens/momentsPen.py":1 + * from fontTools.pens.basePen import BasePen, OpenContourError # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_BasePen); + __Pyx_GIVEREF(__pyx_n_s_BasePen); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BasePen)) __PYX_ERR(0, 1, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_OpenContourError); + __Pyx_GIVEREF(__pyx_n_s_OpenContourError); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_OpenContourError)) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_fontTools_pens_basePen, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_BasePen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_BasePen, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_OpenContourError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_OpenContourError, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":3 + * from fontTools.pens.basePen import BasePen, OpenContourError + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "fontTools/pens/momentsPen.py":6 + * import cython + * + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_True) < 0) __PYX_ERR(0, 6, __pyx_L2_error) + + /* "fontTools/pens/momentsPen.py":3 + * from fontTools.pens.basePen import BasePen, OpenContourError + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L7_try_end; + __pyx_L2_error:; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":7 + * + * COMPILED = cython.compiled + * except (AttributeError, ImportError): # <<<<<<<<<<<<<< + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + */ + __pyx_t_6 = __Pyx_PyErr_ExceptionMatches2(__pyx_builtin_AttributeError, __pyx_builtin_ImportError); + if (__pyx_t_6) { + __Pyx_AddTraceback("fontTools.pens.momentsPen", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_2, &__pyx_t_7) < 0) __PYX_ERR(0, 7, __pyx_L4_except_error) + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/pens/momentsPen.py":9 + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython # <<<<<<<<<<<<<< + * + * COMPILED = False + */ + __pyx_t_8 = PyList_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 9, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_n_s_cython); + __Pyx_GIVEREF(__pyx_n_s_cython); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_n_s_cython)) __PYX_ERR(0, 9, __pyx_L4_except_error); + __pyx_t_9 = __Pyx_Import(__pyx_n_s_fontTools_misc, __pyx_t_8, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 9, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_ImportFrom(__pyx_t_9, __pyx_n_s_cython); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 9, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cython, __pyx_t_8) < 0) __PYX_ERR(0, 9, __pyx_L4_except_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/pens/momentsPen.py":11 + * from fontTools.misc import cython + * + * COMPILED = False # <<<<<<<<<<<<<< + * + * + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_False) < 0) __PYX_ERR(0, 11, __pyx_L4_except_error) + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L3_exception_handled; + } + goto __pyx_L4_except_error; + + /* "fontTools/pens/momentsPen.py":3 + * from fontTools.pens.basePen import BasePen, OpenContourError + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + __pyx_L4_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L3_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_4, __pyx_t_5); + __pyx_L7_try_end:; + } + + /* "fontTools/pens/momentsPen.py":14 + * + * + * __all__ = ["MomentsPen"] # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_7 = PyList_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_u_MomentsPen); + __Pyx_GIVEREF(__pyx_n_u_MomentsPen); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_n_u_MomentsPen)) __PYX_ERR(0, 14, __pyx_L1_error); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_7) < 0) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/pens/momentsPen.py":17 + * + * + * class MomentsPen(BasePen): # <<<<<<<<<<<<<< + * def __init__(self, glyphset=None): + * BasePen.__init__(self, glyphset) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_BasePen); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_7)) __PYX_ERR(0, 17, __pyx_L1_error); + __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PEP560_update_bases(__pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_CalculateMetaclass(NULL, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_Py3MetaclassPrepare(__pyx_t_3, __pyx_t_7, __pyx_n_s_MomentsPen, __pyx_n_s_MomentsPen, (PyObject *) NULL, __pyx_n_s_fontTools_pens_momentsPen, (PyObject *) NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + if (__pyx_t_7 != __pyx_t_2) { + if (unlikely((PyDict_SetItemString(__pyx_t_9, "__orig_bases__", __pyx_t_2) < 0))) __PYX_ERR(0, 17, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":18 + * + * class MomentsPen(BasePen): + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__, 0, __pyx_n_s_MomentsPen___init, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__3)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_tuple__4); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_init, __pyx_t_2) < 0) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":28 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self.__startPoint = p0 + * + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo, 0, __pyx_n_s_MomentsPen__moveTo, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__6)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_moveTo, __pyx_t_2) < 0) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":31 + * self.__startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath, 0, __pyx_n_s_MomentsPen__closePath, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__7)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_closePath, __pyx_t_2) < 0) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":36 + * self._lineTo(self.__startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self.__startPoint: + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath, 0, __pyx_n_s_MomentsPen__endPath, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__8)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_endPath, __pyx_t_2) < 0) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":41 + * raise OpenContourError("Glyph statistics not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo, 0, __pyx_n_s_MomentsPen__lineTo, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__10)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 41, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_lineTo, __pyx_t_2) < 0) __PYX_ERR(0, 41, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":101 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne, 0, __pyx_n_s_MomentsPen__qCurveToOne, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__12)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_qCurveToOne, __pyx_t_2) < 0) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":312 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne, 0, __pyx_n_s_MomentsPen__curveToOne, NULL, __pyx_n_s_fontTools_pens_momentsPen, __pyx_d, ((PyObject *)__pyx_codeobj__14)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 312, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_SetNameInClass(__pyx_t_9, __pyx_n_s_curveToOne, __pyx_t_2) < 0) __PYX_ERR(0, 312, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":17 + * + * + * class MomentsPen(BasePen): # <<<<<<<<<<<<<< + * def __init__(self, glyphset=None): + * BasePen.__init__(self, glyphset) + */ + __pyx_t_2 = __Pyx_Py3ClassCreate(__pyx_t_3, __pyx_n_s_MomentsPen, __pyx_t_7, __pyx_t_9, NULL, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_MomentsPen, __pyx_t_2) < 0) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/pens/momentsPen.py":868 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * from fontTools.misc.symfont import x, y, printGreenPen + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 868, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_10 = (__Pyx_PyUnicode_Equals(__pyx_t_7, __pyx_n_u_main, Py_EQ)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 868, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (__pyx_t_10) { + + /* "fontTools/pens/momentsPen.py":869 + * + * if __name__ == "__main__": + * from fontTools.misc.symfont import x, y, printGreenPen # <<<<<<<<<<<<<< + * + * printGreenPen( + */ + __pyx_t_7 = PyList_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_s_x); + __Pyx_GIVEREF(__pyx_n_s_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_n_s_x)) __PYX_ERR(0, 869, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_y); + __Pyx_GIVEREF(__pyx_n_s_y); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 1, __pyx_n_s_y)) __PYX_ERR(0, 869, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_printGreenPen); + __Pyx_GIVEREF(__pyx_n_s_printGreenPen); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 2, __pyx_n_s_printGreenPen)) __PYX_ERR(0, 869, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_fontTools_misc_symfont, __pyx_t_7, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_x); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_x, __pyx_t_7) < 0) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_y); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_y, __pyx_t_7) < 0) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_printGreenPen); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_printGreenPen, __pyx_t_7) < 0) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/pens/momentsPen.py":871 + * from fontTools.misc.symfont import x, y, printGreenPen + * + * printGreenPen( # <<<<<<<<<<<<<< + * "MomentsPen", + * [ + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_printGreenPen); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 871, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/pens/momentsPen.py":875 + * [ + * ("area", 1), + * ("momentX", x), # <<<<<<<<<<<<<< + * ("momentY", y), + * ("momentXX", x**2), + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_x); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 875, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 875, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_n_u_momentX); + __Pyx_GIVEREF(__pyx_n_u_momentX); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_n_u_momentX)) __PYX_ERR(0, 875, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_7)) __PYX_ERR(0, 875, __pyx_L1_error); + __pyx_t_7 = 0; + + /* "fontTools/pens/momentsPen.py":876 + * ("area", 1), + * ("momentX", x), + * ("momentY", y), # <<<<<<<<<<<<<< + * ("momentXX", x**2), + * ("momentXY", x * y), + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_y); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_u_momentY); + __Pyx_GIVEREF(__pyx_n_u_momentY); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_n_u_momentY)) __PYX_ERR(0, 876, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_7)) __PYX_ERR(0, 876, __pyx_L1_error); + __pyx_t_7 = 0; + + /* "fontTools/pens/momentsPen.py":877 + * ("momentX", x), + * ("momentY", y), + * ("momentXX", x**2), # <<<<<<<<<<<<<< + * ("momentXY", x * y), + * ("momentYY", y**2), + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_x); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = PyNumber_Power(__pyx_t_7, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_u_momentXX); + __Pyx_GIVEREF(__pyx_n_u_momentXX); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_n_u_momentXX)) __PYX_ERR(0, 877, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_8)) __PYX_ERR(0, 877, __pyx_L1_error); + __pyx_t_8 = 0; + + /* "fontTools/pens/momentsPen.py":878 + * ("momentY", y), + * ("momentXX", x**2), + * ("momentXY", x * y), # <<<<<<<<<<<<<< + * ("momentYY", y**2), + * ], + */ + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_x); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 878, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_y); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 878, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = PyNumber_Multiply(__pyx_t_8, __pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 878, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 878, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_n_u_momentXY); + __Pyx_GIVEREF(__pyx_n_u_momentXY); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_n_u_momentXY)) __PYX_ERR(0, 878, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_12); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_12)) __PYX_ERR(0, 878, __pyx_L1_error); + __pyx_t_12 = 0; + + /* "fontTools/pens/momentsPen.py":879 + * ("momentXX", x**2), + * ("momentXY", x * y), + * ("momentYY", y**2), # <<<<<<<<<<<<<< + * ], + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_y); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_8 = PyNumber_Power(__pyx_t_12, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 879, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_n_u_momentYY); + __Pyx_GIVEREF(__pyx_n_u_momentYY); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_n_u_momentYY)) __PYX_ERR(0, 879, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_8)) __PYX_ERR(0, 879, __pyx_L1_error); + __pyx_t_8 = 0; + + /* "fontTools/pens/momentsPen.py":873 + * printGreenPen( + * "MomentsPen", + * [ # <<<<<<<<<<<<<< + * ("area", 1), + * ("momentX", x), + */ + __pyx_t_8 = PyList_New(6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 873, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_tuple__15)) __PYX_ERR(0, 873, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 1, __pyx_t_9)) __PYX_ERR(0, 873, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 2, __pyx_t_2)) __PYX_ERR(0, 873, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 3, __pyx_t_7)) __PYX_ERR(0, 873, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_11); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 4, __pyx_t_11)) __PYX_ERR(0, 873, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_12); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 5, __pyx_t_12)) __PYX_ERR(0, 873, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_2 = 0; + __pyx_t_7 = 0; + __pyx_t_11 = 0; + __pyx_t_12 = 0; + + /* "fontTools/pens/momentsPen.py":871 + * from fontTools.misc.symfont import x, y, printGreenPen + * + * printGreenPen( # <<<<<<<<<<<<<< + * "MomentsPen", + * [ + */ + __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 871, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_n_u_MomentsPen); + __Pyx_GIVEREF(__pyx_n_u_MomentsPen); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_n_u_MomentsPen)) __PYX_ERR(0, 871, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_8)) __PYX_ERR(0, 871, __pyx_L1_error); + __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_12, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 871, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/pens/momentsPen.py":868 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * from fontTools.misc.symfont import x, y, printGreenPen + * + */ + } + + /* "fontTools/pens/momentsPen.py":1 + * from fontTools.pens.basePen import BasePen, OpenContourError # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_8 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_8) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.pens.momentsPen", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.pens.momentsPen"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; // error + return kwvalues[i]; + } + } + return NULL; // not found (no exception set) +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); // transfer ownership of value to values + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#elif CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectSetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_setattro)) + return tp->tp_setattro(obj, attr_name, value); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_setattr)) + return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value); +#endif + return PyObject_SetAttr(obj, attr_name, value); +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + PyObject* exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u_); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* Py3UpdateBases */ +static PyObject* +__Pyx_PEP560_update_bases(PyObject *bases) +{ + Py_ssize_t i, j, size_bases; + PyObject *base, *meth, *new_base, *result, *new_bases = NULL; + size_bases = PyTuple_GET_SIZE(bases); + for (i = 0; i < size_bases; i++) { + base = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(base)) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + meth = __Pyx_PyObject_GetAttrStrNoError(base, __pyx_n_s_mro_entries); + if (!meth && PyErr_Occurred()) { + goto error; + } + if (!meth) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + new_base = __Pyx_PyObject_CallOneArg(meth, bases); + Py_DECREF(meth); + if (!new_base) { + goto error; + } + if (!PyTuple_Check(new_base)) { + PyErr_SetString(PyExc_TypeError, + "__mro_entries__ must return a tuple"); + Py_DECREF(new_base); + goto error; + } + if (!new_bases) { + if (!(new_bases = PyList_New(i))) { + goto error; + } + for (j = 0; j < i; j++) { + base = PyTuple_GET_ITEM(bases, j); + PyList_SET_ITEM(new_bases, j, base); + Py_INCREF(base); + } + } + j = PyList_GET_SIZE(new_bases); + if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + goto error; + } + Py_DECREF(new_base); + } + if (!new_bases) { + Py_INCREF(bases); + return bases; + } + result = PyList_AsTuple(new_bases); + Py_DECREF(new_bases); + return result; +error: + Py_XDECREF(new_bases); + return NULL; +} + +/* CalculateMetaclass */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { + Py_ssize_t i, nbases; +#if CYTHON_ASSUME_SAFE_MACROS + nbases = PyTuple_GET_SIZE(bases); +#else + nbases = PyTuple_Size(bases); + if (nbases < 0) return NULL; +#endif + for (i=0; i < nbases; i++) { + PyTypeObject *tmptype; +#if CYTHON_ASSUME_SAFE_MACROS + PyObject *tmp = PyTuple_GET_ITEM(bases, i); +#else + PyObject *tmp = PyTuple_GetItem(bases, i); + if (!tmp) return NULL; +#endif + tmptype = Py_TYPE(tmp); +#if PY_MAJOR_VERSION < 3 + if (tmptype == &PyClass_Type) + continue; +#endif + if (!metaclass) { + metaclass = tmptype; + continue; + } + if (PyType_IsSubtype(metaclass, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, metaclass)) { + metaclass = tmptype; + continue; + } + PyErr_SetString(PyExc_TypeError, + "metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases"); + return NULL; + } + if (!metaclass) { +#if PY_MAJOR_VERSION < 3 + metaclass = &PyClass_Type; +#else + metaclass = &PyType_Type; +#endif + } + Py_INCREF((PyObject*) metaclass); + return (PyObject*) metaclass; +} + +/* FixUpExtensionType */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* FetchSharedCythonModule */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* PyVectorcallFastCallDict */ +#if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyObjectCall2Args */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectLookupSpecial */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error) { + PyObject *res; + PyTypeObject *tp = Py_TYPE(obj); +#if PY_MAJOR_VERSION < 3 + if (unlikely(PyInstance_Check(obj))) + return with_error ? __Pyx_PyObject_GetAttrStr(obj, attr_name) : __Pyx_PyObject_GetAttrStrNoError(obj, attr_name); +#endif + res = _PyType_Lookup(tp, attr_name); + if (likely(res)) { + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (!f) { + Py_INCREF(res); + } else { + res = f(res, obj, (PyObject *)tp); + } + } else if (with_error) { + PyErr_SetObject(PyExc_AttributeError, attr_name); + } + return res; +} +#endif + +/* Py3ClassCreate */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, + PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { + PyObject *ns; + if (metaclass) { + PyObject *prep = __Pyx_PyObject_GetAttrStrNoError(metaclass, __pyx_n_s_prepare); + if (prep) { + PyObject *pargs[3] = {NULL, name, bases}; + ns = __Pyx_PyObject_FastCallDict(prep, pargs+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw); + Py_DECREF(prep); + } else { + if (unlikely(PyErr_Occurred())) + return NULL; + ns = PyDict_New(); + } + } else { + ns = PyDict_New(); + } + if (unlikely(!ns)) + return NULL; + if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad; +#if PY_VERSION_HEX >= 0x03030000 + if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad; +#else + CYTHON_MAYBE_UNUSED_VAR(qualname); +#endif + if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad; + return ns; +bad: + Py_DECREF(ns); + return NULL; +} +#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS +static int __Pyx_SetNamesPEP487(PyObject *type_obj) { + PyTypeObject *type = (PyTypeObject*) type_obj; + PyObject *names_to_set, *key, *value, *set_name, *tmp; + Py_ssize_t i = 0; +#if CYTHON_USE_TYPE_SLOTS + names_to_set = PyDict_Copy(type->tp_dict); +#else + { + PyObject *d = PyObject_GetAttr(type_obj, __pyx_n_s_dict); + names_to_set = NULL; + if (likely(d)) { + PyObject *names_to_set = PyDict_New(); + int ret = likely(names_to_set) ? PyDict_Update(names_to_set, d) : -1; + Py_DECREF(d); + if (unlikely(ret < 0)) + Py_CLEAR(names_to_set); + } + } +#endif + if (unlikely(names_to_set == NULL)) + goto bad; + while (PyDict_Next(names_to_set, &i, &key, &value)) { + set_name = __Pyx_PyObject_LookupSpecialNoError(value, __pyx_n_s_set_name); + if (unlikely(set_name != NULL)) { + tmp = __Pyx_PyObject_Call2Args(set_name, type_obj, key); + Py_DECREF(set_name); + if (unlikely(tmp == NULL)) { + __Pyx_TypeName value_type_name = + __Pyx_PyType_GetName(Py_TYPE(value)); + __Pyx_TypeName type_name = __Pyx_PyType_GetName(type); + PyErr_Format(PyExc_RuntimeError, +#if PY_MAJOR_VERSION >= 3 + "Error calling __set_name__ on '" __Pyx_FMT_TYPENAME "' instance %R " "in '" __Pyx_FMT_TYPENAME "'", + value_type_name, key, type_name); +#else + "Error calling __set_name__ on '" __Pyx_FMT_TYPENAME "' instance %.100s in '" __Pyx_FMT_TYPENAME "'", + value_type_name, + PyString_Check(key) ? PyString_AS_STRING(key) : "?", + type_name); +#endif + goto bad; + } else { + Py_DECREF(tmp); + } + } + else if (unlikely(PyErr_Occurred())) { + goto bad; + } + } + Py_DECREF(names_to_set); + return 0; +bad: + Py_XDECREF(names_to_set); + return -1; +} +static PyObject *__Pyx_InitSubclassPEP487(PyObject *type_obj, PyObject *mkw) { +#if CYTHON_USE_TYPE_SLOTS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + PyTypeObject *type = (PyTypeObject*) type_obj; + PyObject *mro = type->tp_mro; + Py_ssize_t i, nbases; + if (unlikely(!mro)) goto done; + (void) &__Pyx_GetBuiltinName; + Py_INCREF(mro); + nbases = PyTuple_GET_SIZE(mro); + assert(PyTuple_GET_ITEM(mro, 0) == type_obj); + for (i = 1; i < nbases-1; i++) { + PyObject *base, *dict, *meth; + base = PyTuple_GET_ITEM(mro, i); + dict = ((PyTypeObject *)base)->tp_dict; + meth = __Pyx_PyDict_GetItemStrWithError(dict, __pyx_n_s_init_subclass); + if (unlikely(meth)) { + descrgetfunc f = Py_TYPE(meth)->tp_descr_get; + PyObject *res; + Py_INCREF(meth); + if (likely(f)) { + res = f(meth, NULL, type_obj); + Py_DECREF(meth); + if (unlikely(!res)) goto bad; + meth = res; + } + res = __Pyx_PyObject_FastCallDict(meth, NULL, 0, mkw); + Py_DECREF(meth); + if (unlikely(!res)) goto bad; + Py_DECREF(res); + goto done; + } else if (unlikely(PyErr_Occurred())) { + goto bad; + } + } +done: + Py_XDECREF(mro); + return type_obj; +bad: + Py_XDECREF(mro); + Py_DECREF(type_obj); + return NULL; +#else + PyObject *super_type, *super, *func, *res; +#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type) + super_type = __Pyx_GetBuiltinName(__pyx_n_s_super); +#else + super_type = (PyObject*) &PySuper_Type; + (void) &__Pyx_GetBuiltinName; +#endif + super = likely(super_type) ? __Pyx_PyObject_Call2Args(super_type, type_obj, type_obj) : NULL; +#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type) + Py_XDECREF(super_type); +#endif + if (unlikely(!super)) { + Py_CLEAR(type_obj); + goto done; + } + func = __Pyx_PyObject_GetAttrStrNoError(super, __pyx_n_s_init_subclass); + Py_DECREF(super); + if (likely(!func)) { + if (unlikely(PyErr_Occurred())) + Py_CLEAR(type_obj); + goto done; + } + res = __Pyx_PyObject_FastCallDict(func, NULL, 0, mkw); + Py_DECREF(func); + if (unlikely(!res)) + Py_CLEAR(type_obj); + Py_XDECREF(res); +done: + return type_obj; +#endif +} +#endif +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, + PyObject *dict, PyObject *mkw, + int calculate_metaclass, int allow_py2_metaclass) { + PyObject *result; + PyObject *owned_metaclass = NULL; + PyObject *margs[4] = {NULL, name, bases, dict}; + if (allow_py2_metaclass) { + owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass); + if (owned_metaclass) { + metaclass = owned_metaclass; + } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { + PyErr_Clear(); + } else { + return NULL; + } + } + if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { + metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); + Py_XDECREF(owned_metaclass); + if (unlikely(!metaclass)) + return NULL; + owned_metaclass = metaclass; + } + result = __Pyx_PyObject_FastCallDict(metaclass, margs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, +#if PY_VERSION_HEX < 0x030600A4 + (metaclass == (PyObject*)&PyType_Type) ? NULL : mkw +#else + mkw +#endif + ); + Py_XDECREF(owned_metaclass); +#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS + if (likely(result) && likely(PyType_Check(result))) { + if (unlikely(__Pyx_SetNamesPEP487(result) < 0)) { + Py_CLEAR(result); + } else { + result = __Pyx_InitSubclassPEP487(result, mkw); + } + } +#else + (void) &__Pyx_GetBuiltinName; +#endif + return result; +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__16); + } + return name; +} +#endif + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CheckBinaryVersion */ +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ +#if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/momentsPen.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..52956c3aa1794673327c6c4cf1b3ac413eecf537 GIT binary patch literal 325516 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 z%0A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 0.0015 else self._addCubicRecursive + ) + self._addQuadratic = ( + self._addQuadraticQuadrature + if tolerance >= 0.00075 + else self._addQuadraticExact + ) + + def _moveTo(self, p0): + self.__startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + self._lineTo(self.__startPoint) + + def _lineTo(self, p1): + p0 = self._getCurrentPoint() + self.value += _distance(p0, p1) + + def _addQuadraticExact(self, c0, c1, c2): + self.value += calcQuadraticArcLengthC(c0, c1, c2) + + def _addQuadraticQuadrature(self, c0, c1, c2): + self.value += approximateQuadraticArcLengthC(c0, c1, c2) + + def _qCurveToOne(self, p1, p2): + p0 = self._getCurrentPoint() + self._addQuadratic(complex(*p0), complex(*p1), complex(*p2)) + + def _addCubicRecursive(self, c0, c1, c2, c3): + self.value += calcCubicArcLengthC(c0, c1, c2, c3, self.tolerance) + + def _addCubicQuadrature(self, c0, c1, c2, c3): + self.value += approximateCubicArcLengthC(c0, c1, c2, c3) + + def _curveToOne(self, p1, p2, p3): + p0 = self._getCurrentPoint() + self._addCubic(complex(*p0), complex(*p1), complex(*p2), complex(*p3)) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointInsidePen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointInsidePen.py new file mode 100644 index 00000000..8a579ae4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointInsidePen.py @@ -0,0 +1,192 @@ +"""fontTools.pens.pointInsidePen -- Pen implementing "point inside" testing +for shapes. +""" + +from fontTools.pens.basePen import BasePen +from fontTools.misc.bezierTools import solveQuadratic, solveCubic + + +__all__ = ["PointInsidePen"] + + +class PointInsidePen(BasePen): + + """This pen implements "point inside" testing: to test whether + a given point lies inside the shape (black) or outside (white). + Instances of this class can be recycled, as long as the + setTestPoint() method is used to set the new point to test. + + Typical usage: + + pen = PointInsidePen(glyphSet, (100, 200)) + outline.draw(pen) + isInside = pen.getResult() + + Both the even-odd algorithm and the non-zero-winding-rule + algorithm are implemented. The latter is the default, specify + True for the evenOdd argument of __init__ or setTestPoint + to use the even-odd algorithm. + """ + + # This class implements the classical "shoot a ray from the test point + # to infinity and count how many times it intersects the outline" (as well + # as the non-zero variant, where the counter is incremented if the outline + # intersects the ray in one direction and decremented if it intersects in + # the other direction). + # I found an amazingly clear explanation of the subtleties involved in + # implementing this correctly for polygons here: + # http://graphics.cs.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html + # I extended the principles outlined on that page to curves. + + def __init__(self, glyphSet, testPoint, evenOdd=False): + BasePen.__init__(self, glyphSet) + self.setTestPoint(testPoint, evenOdd) + + def setTestPoint(self, testPoint, evenOdd=False): + """Set the point to test. Call this _before_ the outline gets drawn.""" + self.testPoint = testPoint + self.evenOdd = evenOdd + self.firstPoint = None + self.intersectionCount = 0 + + def getWinding(self): + if self.firstPoint is not None: + # always make sure the sub paths are closed; the algorithm only works + # for closed paths. + self.closePath() + return self.intersectionCount + + def getResult(self): + """After the shape has been drawn, getResult() returns True if the test + point lies within the (black) shape, and False if it doesn't. + """ + winding = self.getWinding() + if self.evenOdd: + result = winding % 2 + else: # non-zero + result = self.intersectionCount != 0 + return not not result + + def _addIntersection(self, goingUp): + if self.evenOdd or goingUp: + self.intersectionCount += 1 + else: + self.intersectionCount -= 1 + + def _moveTo(self, point): + if self.firstPoint is not None: + # always make sure the sub paths are closed; the algorithm only works + # for closed paths. + self.closePath() + self.firstPoint = point + + def _lineTo(self, point): + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = point + + if x1 < x and x2 < x: + return + if y1 < y and y2 < y: + return + if y1 >= y and y2 >= y: + return + + dx = x2 - x1 + dy = y2 - y1 + t = (y - y1) / dy + ix = dx * t + x1 + if ix < x: + return + self._addIntersection(y2 > y1) + + def _curveToOne(self, bcp1, bcp2, point): + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = bcp1 + x3, y3 = bcp2 + x4, y4 = point + + if x1 < x and x2 < x and x3 < x and x4 < x: + return + if y1 < y and y2 < y and y3 < y and y4 < y: + return + if y1 >= y and y2 >= y and y3 >= y and y4 >= y: + return + + dy = y1 + cy = (y2 - dy) * 3.0 + by = (y3 - y2) * 3.0 - cy + ay = y4 - dy - cy - by + solutions = sorted(solveCubic(ay, by, cy, dy - y)) + solutions = [t for t in solutions if -0.0 <= t <= 1.0] + if not solutions: + return + + dx = x1 + cx = (x2 - dx) * 3.0 + bx = (x3 - x2) * 3.0 - cx + ax = x4 - dx - cx - bx + + above = y1 >= y + lastT = None + for t in solutions: + if t == lastT: + continue + lastT = t + t2 = t * t + t3 = t2 * t + + direction = 3 * ay * t2 + 2 * by * t + cy + incomingGoingUp = outgoingGoingUp = direction > 0.0 + if direction == 0.0: + direction = 6 * ay * t + 2 * by + outgoingGoingUp = direction > 0.0 + incomingGoingUp = not outgoingGoingUp + if direction == 0.0: + direction = ay + incomingGoingUp = outgoingGoingUp = direction > 0.0 + + xt = ax * t3 + bx * t2 + cx * t + dx + if xt < x: + continue + + if t in (0.0, -0.0): + if not outgoingGoingUp: + self._addIntersection(outgoingGoingUp) + elif t == 1.0: + if incomingGoingUp: + self._addIntersection(incomingGoingUp) + else: + if incomingGoingUp == outgoingGoingUp: + self._addIntersection(outgoingGoingUp) + # else: + # we're not really intersecting, merely touching + + def _qCurveToOne_unfinished(self, bcp, point): + # XXX need to finish this, for now doing it through a cubic + # (BasePen implements _qCurveTo in terms of a cubic) will + # have to do. + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = bcp + x3, y3 = point + c = y1 + b = (y2 - c) * 2.0 + a = y3 - c - b + solutions = sorted(solveQuadratic(a, b, c - y)) + solutions = [ + t for t in solutions if ZERO_MINUS_EPSILON <= t <= ONE_PLUS_EPSILON + ] + if not solutions: + return + # XXX + + def _closePath(self): + if self._getCurrentPoint() != self.firstPoint: + self.lineTo(self.firstPoint) + self.firstPoint = None + + def _endPath(self): + """Insideness is not defined for open contours.""" + raise NotImplementedError diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointPen.py new file mode 100644 index 00000000..eb1ebc20 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/pointPen.py @@ -0,0 +1,525 @@ +""" +========= +PointPens +========= + +Where **SegmentPens** have an intuitive approach to drawing +(if you're familiar with postscript anyway), the **PointPen** +is geared towards accessing all the data in the contours of +the glyph. A PointPen has a very simple interface, it just +steps through all the points in a call from glyph.drawPoints(). +This allows the caller to provide more data for each point. +For instance, whether or not a point is smooth, and its name. +""" + +import math +from typing import Any, Optional, Tuple, Dict + +from fontTools.pens.basePen import AbstractPen, PenError +from fontTools.misc.transform import DecomposedTransform + +__all__ = [ + "AbstractPointPen", + "BasePointToSegmentPen", + "PointToSegmentPen", + "SegmentToPointPen", + "GuessSmoothPointPen", + "ReverseContourPointPen", +] + + +class AbstractPointPen: + """Baseclass for all PointPens.""" + + def beginPath(self, identifier: Optional[str] = None, **kwargs: Any) -> None: + """Start a new sub path.""" + raise NotImplementedError + + def endPath(self) -> None: + """End the current sub path.""" + raise NotImplementedError + + def addPoint( + self, + pt: Tuple[float, float], + segmentType: Optional[str] = None, + smooth: bool = False, + name: Optional[str] = None, + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a point to the current sub path.""" + raise NotImplementedError + + def addComponent( + self, + baseGlyphName: str, + transformation: Tuple[float, float, float, float, float, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a sub glyph.""" + raise NotImplementedError + + def addVarComponent( + self, + glyphName: str, + transformation: DecomposedTransform, + location: Dict[str, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a VarComponent sub glyph. The 'transformation' argument + must be a DecomposedTransform from the fontTools.misc.transform module, + and the 'location' argument must be a dictionary mapping axis tags + to their locations. + """ + # ttGlyphSet decomposes for us + raise AttributeError + + +class BasePointToSegmentPen(AbstractPointPen): + """ + Base class for retrieving the outline in a segment-oriented + way. The PointPen protocol is simple yet also a little tricky, + so when you need an outline presented as segments but you have + as points, do use this base implementation as it properly takes + care of all the edge cases. + """ + + def __init__(self): + self.currentPath = None + + def beginPath(self, identifier=None, **kwargs): + if self.currentPath is not None: + raise PenError("Path already begun.") + self.currentPath = [] + + def _flushContour(self, segments): + """Override this method. + + It will be called for each non-empty sub path with a list + of segments: the 'segments' argument. + + The segments list contains tuples of length 2: + (segmentType, points) + + segmentType is one of "move", "line", "curve" or "qcurve". + "move" may only occur as the first segment, and it signifies + an OPEN path. A CLOSED path does NOT start with a "move", in + fact it will not contain a "move" at ALL. + + The 'points' field in the 2-tuple is a list of point info + tuples. The list has 1 or more items, a point tuple has + four items: + (point, smooth, name, kwargs) + 'point' is an (x, y) coordinate pair. + + For a closed path, the initial moveTo point is defined as + the last point of the last segment. + + The 'points' list of "move" and "line" segments always contains + exactly one point tuple. + """ + raise NotImplementedError + + def endPath(self): + if self.currentPath is None: + raise PenError("Path not begun.") + points = self.currentPath + self.currentPath = None + if not points: + return + if len(points) == 1: + # Not much more we can do than output a single move segment. + pt, segmentType, smooth, name, kwargs = points[0] + segments = [("move", [(pt, smooth, name, kwargs)])] + self._flushContour(segments) + return + segments = [] + if points[0][1] == "move": + # It's an open contour, insert a "move" segment for the first + # point and remove that first point from the point list. + pt, segmentType, smooth, name, kwargs = points[0] + segments.append(("move", [(pt, smooth, name, kwargs)])) + points.pop(0) + else: + # It's a closed contour. Locate the first on-curve point, and + # rotate the point list so that it _ends_ with an on-curve + # point. + firstOnCurve = None + for i in range(len(points)): + segmentType = points[i][1] + if segmentType is not None: + firstOnCurve = i + break + if firstOnCurve is None: + # Special case for quadratics: a contour with no on-curve + # points. Add a "None" point. (See also the Pen protocol's + # qCurveTo() method and fontTools.pens.basePen.py.) + points.append((None, "qcurve", None, None, None)) + else: + points = points[firstOnCurve + 1 :] + points[: firstOnCurve + 1] + + currentSegment = [] + for pt, segmentType, smooth, name, kwargs in points: + currentSegment.append((pt, smooth, name, kwargs)) + if segmentType is None: + continue + segments.append((segmentType, currentSegment)) + currentSegment = [] + + self._flushContour(segments) + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self.currentPath is None: + raise PenError("Path not begun") + self.currentPath.append((pt, segmentType, smooth, name, kwargs)) + + +class PointToSegmentPen(BasePointToSegmentPen): + """ + Adapter class that converts the PointPen protocol to the + (Segment)Pen protocol. + + NOTE: The segment pen does not support and will drop point names, identifiers + and kwargs. + """ + + def __init__(self, segmentPen, outputImpliedClosingLine=False): + BasePointToSegmentPen.__init__(self) + self.pen = segmentPen + self.outputImpliedClosingLine = outputImpliedClosingLine + + def _flushContour(self, segments): + if not segments: + raise PenError("Must have at least one segment.") + pen = self.pen + if segments[0][0] == "move": + # It's an open path. + closed = False + points = segments[0][1] + if len(points) != 1: + raise PenError(f"Illegal move segment point count: {len(points)}") + movePt, _, _, _ = points[0] + del segments[0] + else: + # It's a closed path, do a moveTo to the last + # point of the last segment. + closed = True + segmentType, points = segments[-1] + movePt, _, _, _ = points[-1] + if movePt is None: + # quad special case: a contour with no on-curve points contains + # one "qcurve" segment that ends with a point that's None. We + # must not output a moveTo() in that case. + pass + else: + pen.moveTo(movePt) + outputImpliedClosingLine = self.outputImpliedClosingLine + nSegments = len(segments) + lastPt = movePt + for i in range(nSegments): + segmentType, points = segments[i] + points = [pt for pt, _, _, _ in points] + if segmentType == "line": + if len(points) != 1: + raise PenError(f"Illegal line segment point count: {len(points)}") + pt = points[0] + # For closed contours, a 'lineTo' is always implied from the last oncurve + # point to the starting point, thus we can omit it when the last and + # starting point don't overlap. + # However, when the last oncurve point is a "line" segment and has same + # coordinates as the starting point of a closed contour, we need to output + # the closing 'lineTo' explicitly (regardless of the value of the + # 'outputImpliedClosingLine' option) in order to disambiguate this case from + # the implied closing 'lineTo', otherwise the duplicate point would be lost. + # See https://github.com/googlefonts/fontmake/issues/572. + if ( + i + 1 != nSegments + or outputImpliedClosingLine + or not closed + or pt == lastPt + ): + pen.lineTo(pt) + lastPt = pt + elif segmentType == "curve": + pen.curveTo(*points) + lastPt = points[-1] + elif segmentType == "qcurve": + pen.qCurveTo(*points) + lastPt = points[-1] + else: + raise PenError(f"Illegal segmentType: {segmentType}") + if closed: + pen.closePath() + else: + pen.endPath() + + def addComponent(self, glyphName, transform, identifier=None, **kwargs): + del identifier # unused + del kwargs # unused + self.pen.addComponent(glyphName, transform) + + +class SegmentToPointPen(AbstractPen): + """ + Adapter class that converts the (Segment)Pen protocol to the + PointPen protocol. + """ + + def __init__(self, pointPen, guessSmooth=True): + if guessSmooth: + self.pen = GuessSmoothPointPen(pointPen) + else: + self.pen = pointPen + self.contour = None + + def _flushContour(self): + pen = self.pen + pen.beginPath() + for pt, segmentType in self.contour: + pen.addPoint(pt, segmentType=segmentType) + pen.endPath() + + def moveTo(self, pt): + self.contour = [] + self.contour.append((pt, "move")) + + def lineTo(self, pt): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + self.contour.append((pt, "line")) + + def curveTo(self, *pts): + if not pts: + raise TypeError("Must pass in at least one point") + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + for pt in pts[:-1]: + self.contour.append((pt, None)) + self.contour.append((pts[-1], "curve")) + + def qCurveTo(self, *pts): + if not pts: + raise TypeError("Must pass in at least one point") + if pts[-1] is None: + self.contour = [] + else: + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + for pt in pts[:-1]: + self.contour.append((pt, None)) + if pts[-1] is not None: + self.contour.append((pts[-1], "qcurve")) + + def closePath(self): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + if len(self.contour) > 1 and self.contour[0][0] == self.contour[-1][0]: + self.contour[0] = self.contour[-1] + del self.contour[-1] + else: + # There's an implied line at the end, replace "move" with "line" + # for the first point + pt, tp = self.contour[0] + if tp == "move": + self.contour[0] = pt, "line" + self._flushContour() + self.contour = None + + def endPath(self): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + self._flushContour() + self.contour = None + + def addComponent(self, glyphName, transform): + if self.contour is not None: + raise PenError("Components must be added before or after contours") + self.pen.addComponent(glyphName, transform) + + +class GuessSmoothPointPen(AbstractPointPen): + """ + Filtering PointPen that tries to determine whether an on-curve point + should be "smooth", ie. that it's a "tangent" point or a "curve" point. + """ + + def __init__(self, outPen, error=0.05): + self._outPen = outPen + self._error = error + self._points = None + + def _flushContour(self): + if self._points is None: + raise PenError("Path not begun") + points = self._points + nPoints = len(points) + if not nPoints: + return + if points[0][1] == "move": + # Open path. + indices = range(1, nPoints - 1) + elif nPoints > 1: + # Closed path. To avoid having to mod the contour index, we + # simply abuse Python's negative index feature, and start at -1 + indices = range(-1, nPoints - 1) + else: + # closed path containing 1 point (!), ignore. + indices = [] + for i in indices: + pt, segmentType, _, name, kwargs = points[i] + if segmentType is None: + continue + prev = i - 1 + next = i + 1 + if points[prev][1] is not None and points[next][1] is not None: + continue + # At least one of our neighbors is an off-curve point + pt = points[i][0] + prevPt = points[prev][0] + nextPt = points[next][0] + if pt != prevPt and pt != nextPt: + dx1, dy1 = pt[0] - prevPt[0], pt[1] - prevPt[1] + dx2, dy2 = nextPt[0] - pt[0], nextPt[1] - pt[1] + a1 = math.atan2(dy1, dx1) + a2 = math.atan2(dy2, dx2) + if abs(a1 - a2) < self._error: + points[i] = pt, segmentType, True, name, kwargs + + for pt, segmentType, smooth, name, kwargs in points: + self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) + + def beginPath(self, identifier=None, **kwargs): + if self._points is not None: + raise PenError("Path already begun") + self._points = [] + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.beginPath(**kwargs) + + def endPath(self): + self._flushContour() + self._outPen.endPath() + self._points = None + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self._points is None: + raise PenError("Path not begun") + if identifier is not None: + kwargs["identifier"] = identifier + self._points.append((pt, segmentType, False, name, kwargs)) + + def addComponent(self, glyphName, transformation, identifier=None, **kwargs): + if self._points is not None: + raise PenError("Components must be added before or after contours") + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.addComponent(glyphName, transformation, **kwargs) + + def addVarComponent( + self, glyphName, transformation, location, identifier=None, **kwargs + ): + if self._points is not None: + raise PenError("VarComponents must be added before or after contours") + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.addVarComponent(glyphName, transformation, location, **kwargs) + + +class ReverseContourPointPen(AbstractPointPen): + """ + This is a PointPen that passes outline data to another PointPen, but + reversing the winding direction of all contours. Components are simply + passed through unchanged. + + Closed contours are reversed in such a way that the first point remains + the first point. + """ + + def __init__(self, outputPointPen): + self.pen = outputPointPen + # a place to store the points for the current sub path + self.currentContour = None + + def _flushContour(self): + pen = self.pen + contour = self.currentContour + if not contour: + pen.beginPath(identifier=self.currentContourIdentifier) + pen.endPath() + return + + closed = contour[0][1] != "move" + if not closed: + lastSegmentType = "move" + else: + # Remove the first point and insert it at the end. When + # the list of points gets reversed, this point will then + # again be at the start. In other words, the following + # will hold: + # for N in range(len(originalContour)): + # originalContour[N] == reversedContour[-N] + contour.append(contour.pop(0)) + # Find the first on-curve point. + firstOnCurve = None + for i in range(len(contour)): + if contour[i][1] is not None: + firstOnCurve = i + break + if firstOnCurve is None: + # There are no on-curve points, be basically have to + # do nothing but contour.reverse(). + lastSegmentType = None + else: + lastSegmentType = contour[firstOnCurve][1] + + contour.reverse() + if not closed: + # Open paths must start with a move, so we simply dump + # all off-curve points leading up to the first on-curve. + while contour[0][1] is None: + contour.pop(0) + pen.beginPath(identifier=self.currentContourIdentifier) + for pt, nextSegmentType, smooth, name, kwargs in contour: + if nextSegmentType is not None: + segmentType = lastSegmentType + lastSegmentType = nextSegmentType + else: + segmentType = None + pen.addPoint( + pt, segmentType=segmentType, smooth=smooth, name=name, **kwargs + ) + pen.endPath() + + def beginPath(self, identifier=None, **kwargs): + if self.currentContour is not None: + raise PenError("Path already begun") + self.currentContour = [] + self.currentContourIdentifier = identifier + self.onCurve = [] + + def endPath(self): + if self.currentContour is None: + raise PenError("Path not begun") + self._flushContour() + self.currentContour = None + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self.currentContour is None: + raise PenError("Path not begun") + if identifier is not None: + kwargs["identifier"] = identifier + self.currentContour.append((pt, segmentType, smooth, name, kwargs)) + + def addComponent(self, glyphName, transform, identifier=None, **kwargs): + if self.currentContour is not None: + raise PenError("Components must be added before or after contours") + self.pen.addComponent(glyphName, transform, identifier=identifier, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qtPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qtPen.py new file mode 100644 index 00000000..eb13d03d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qtPen.py @@ -0,0 +1,29 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["QtPen"] + + +class QtPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + from PyQt5.QtGui import QPainterPath + + path = QPainterPath() + self.path = path + + def _moveTo(self, p): + self.path.moveTo(*p) + + def _lineTo(self, p): + self.path.lineTo(*p) + + def _curveToOne(self, p1, p2, p3): + self.path.cubicTo(*p1, *p2, *p3) + + def _qCurveToOne(self, p1, p2): + self.path.quadTo(*p1, *p2) + + def _closePath(self): + self.path.closeSubpath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qu2cuPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qu2cuPen.py new file mode 100644 index 00000000..7e400f98 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/qu2cuPen.py @@ -0,0 +1,105 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2023 Behdad Esfahbod. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from fontTools.qu2cu import quadratic_to_curves +from fontTools.pens.filterPen import ContourFilterPen +from fontTools.pens.reverseContourPen import ReverseContourPen +import math + + +class Qu2CuPen(ContourFilterPen): + """A filter pen to convert quadratic bezier splines to cubic curves + using the FontTools SegmentPen protocol. + + Args: + + other_pen: another SegmentPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + stats: a dictionary counting the point numbers of cubic segments. + """ + + def __init__( + self, + other_pen, + max_err, + all_cubic=False, + reverse_direction=False, + stats=None, + ): + if reverse_direction: + other_pen = ReverseContourPen(other_pen) + super().__init__(other_pen) + self.all_cubic = all_cubic + self.max_err = max_err + self.stats = stats + + def _quadratics_to_curve(self, q): + curves = quadratic_to_curves(q, self.max_err, all_cubic=self.all_cubic) + if self.stats is not None: + for curve in curves: + n = str(len(curve) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + for curve in curves: + if len(curve) == 4: + yield ("curveTo", curve[1:]) + else: + yield ("qCurveTo", curve[1:]) + + def filterContour(self, contour): + quadratics = [] + currentPt = None + newContour = [] + for op, args in contour: + if op == "qCurveTo" and ( + self.all_cubic or (len(args) > 2 and args[-1] is not None) + ): + if args[-1] is None: + raise NotImplementedError( + "oncurve-less contours with all_cubic not implemented" + ) + quadratics.append((currentPt,) + args) + else: + if quadratics: + newContour.extend(self._quadratics_to_curve(quadratics)) + quadratics = [] + newContour.append((op, args)) + currentPt = args[-1] if args else None + if quadratics: + newContour.extend(self._quadratics_to_curve(quadratics)) + + if not self.all_cubic: + # Add back implicit oncurve points + contour = newContour + newContour = [] + for op, args in contour: + if op == "qCurveTo" and newContour and newContour[-1][0] == "qCurveTo": + pt0 = newContour[-1][1][-2] + pt1 = newContour[-1][1][-1] + pt2 = args[0] + if ( + pt1 is not None + and math.isclose(pt2[0] - pt1[0], pt1[0] - pt0[0]) + and math.isclose(pt2[1] - pt1[1], pt1[1] - pt0[1]) + ): + newArgs = newContour[-1][1][:-1] + args + newContour[-1] = (op, newArgs) + continue + + newContour.append((op, args)) + + return newContour diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/quartzPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/quartzPen.py new file mode 100644 index 00000000..6e1228d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/quartzPen.py @@ -0,0 +1,44 @@ +from fontTools.pens.basePen import BasePen + +from Quartz.CoreGraphics import CGPathCreateMutable, CGPathMoveToPoint +from Quartz.CoreGraphics import CGPathAddLineToPoint, CGPathAddCurveToPoint +from Quartz.CoreGraphics import CGPathAddQuadCurveToPoint, CGPathCloseSubpath + + +__all__ = ["QuartzPen"] + + +class QuartzPen(BasePen): + + """A pen that creates a CGPath + + Parameters + - path: an optional CGPath to add to + - xform: an optional CGAffineTransform to apply to the path + """ + + def __init__(self, glyphSet, path=None, xform=None): + BasePen.__init__(self, glyphSet) + if path is None: + path = CGPathCreateMutable() + self.path = path + self.xform = xform + + def _moveTo(self, pt): + x, y = pt + CGPathMoveToPoint(self.path, self.xform, x, y) + + def _lineTo(self, pt): + x, y = pt + CGPathAddLineToPoint(self.path, self.xform, x, y) + + def _curveToOne(self, p1, p2, p3): + (x1, y1), (x2, y2), (x3, y3) = p1, p2, p3 + CGPathAddCurveToPoint(self.path, self.xform, x1, y1, x2, y2, x3, y3) + + def _qCurveToOne(self, p1, p2): + (x1, y1), (x2, y2) = p1, p2 + CGPathAddQuadCurveToPoint(self.path, self.xform, x1, y1, x2, y2) + + def _closePath(self): + CGPathCloseSubpath(self.path) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/recordingPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/recordingPen.py new file mode 100644 index 00000000..e24b6526 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/recordingPen.py @@ -0,0 +1,212 @@ +"""Pen recording operations that can be accessed or replayed.""" +from fontTools.pens.basePen import AbstractPen, DecomposingPen +from fontTools.pens.pointPen import AbstractPointPen + + +__all__ = [ + "replayRecording", + "RecordingPen", + "DecomposingRecordingPen", + "RecordingPointPen", + "lerpRecordings", +] + + +def replayRecording(recording, pen): + """Replay a recording, as produced by RecordingPen or DecomposingRecordingPen, + to a pen. + + Note that recording does not have to be produced by those pens. + It can be any iterable of tuples of method name and tuple-of-arguments. + Likewise, pen can be any objects receiving those method calls. + """ + for operator, operands in recording: + getattr(pen, operator)(*operands) + + +class RecordingPen(AbstractPen): + """Pen recording operations that can be accessed or replayed. + + The recording can be accessed as pen.value; or replayed using + pen.replay(otherPen). + + :Example: + + from fontTools.ttLib import TTFont + from fontTools.pens.recordingPen import RecordingPen + + glyph_name = 'dollar' + font_path = 'MyFont.otf' + + font = TTFont(font_path) + glyphset = font.getGlyphSet() + glyph = glyphset[glyph_name] + + pen = RecordingPen() + glyph.draw(pen) + print(pen.value) + """ + + def __init__(self): + self.value = [] + + def moveTo(self, p0): + self.value.append(("moveTo", (p0,))) + + def lineTo(self, p1): + self.value.append(("lineTo", (p1,))) + + def qCurveTo(self, *points): + self.value.append(("qCurveTo", points)) + + def curveTo(self, *points): + self.value.append(("curveTo", points)) + + def closePath(self): + self.value.append(("closePath", ())) + + def endPath(self): + self.value.append(("endPath", ())) + + def addComponent(self, glyphName, transformation): + self.value.append(("addComponent", (glyphName, transformation))) + + def addVarComponent(self, glyphName, transformation, location): + self.value.append(("addVarComponent", (glyphName, transformation, location))) + + def replay(self, pen): + replayRecording(self.value, pen) + + draw = replay + + +class DecomposingRecordingPen(DecomposingPen, RecordingPen): + """Same as RecordingPen, except that it doesn't keep components + as references, but draws them decomposed as regular contours. + + The constructor takes a single 'glyphSet' positional argument, + a dictionary of glyph objects (i.e. with a 'draw' method) keyed + by thir name:: + + >>> class SimpleGlyph(object): + ... def draw(self, pen): + ... pen.moveTo((0, 0)) + ... pen.curveTo((1, 1), (2, 2), (3, 3)) + ... pen.closePath() + >>> class CompositeGlyph(object): + ... def draw(self, pen): + ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) + >>> glyphSet = {'a': SimpleGlyph(), 'b': CompositeGlyph()} + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPen(glyphSet) + ... glyph.draw(pen) + ... print("{}: {}".format(name, pen.value)) + a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] + b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] + """ + + # raises KeyError if base glyph is not found in glyphSet + skipMissingComponents = False + + +class RecordingPointPen(AbstractPointPen): + """PointPen recording operations that can be accessed or replayed. + + The recording can be accessed as pen.value; or replayed using + pointPen.replay(otherPointPen). + + :Example: + + from defcon import Font + from fontTools.pens.recordingPen import RecordingPointPen + + glyph_name = 'a' + font_path = 'MyFont.ufo' + + font = Font(font_path) + glyph = font[glyph_name] + + pen = RecordingPointPen() + glyph.drawPoints(pen) + print(pen.value) + + new_glyph = font.newGlyph('b') + pen.replay(new_glyph.getPointPen()) + """ + + def __init__(self): + self.value = [] + + def beginPath(self, identifier=None, **kwargs): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("beginPath", (), kwargs)) + + def endPath(self): + self.value.append(("endPath", (), {})) + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("addPoint", (pt, segmentType, smooth, name), kwargs)) + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("addComponent", (baseGlyphName, transformation), kwargs)) + + def addVarComponent( + self, baseGlyphName, transformation, location, identifier=None, **kwargs + ): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append( + ("addVarComponent", (baseGlyphName, transformation, location), kwargs) + ) + + def replay(self, pointPen): + for operator, args, kwargs in self.value: + getattr(pointPen, operator)(*args, **kwargs) + + drawPoints = replay + + +def lerpRecordings(recording1, recording2, factor=0.5): + """Linearly interpolate between two recordings. The recordings + must be decomposed, i.e. they must not contain any components. + + Factor is typically between 0 and 1. 0 means the first recording, + 1 means the second recording, and 0.5 means the average of the + two recordings. Other values are possible, and can be useful to + extrapolate. Defaults to 0.5. + + Returns a generator with the new recording. + """ + if len(recording1) != len(recording2): + raise ValueError( + "Mismatched lengths: %d and %d" % (len(recording1), len(recording2)) + ) + for (op1, args1), (op2, args2) in zip(recording1, recording2): + if op1 != op2: + raise ValueError("Mismatched operations: %s, %s" % (op1, op2)) + if op1 == "addComponent": + raise ValueError("Cannot interpolate components") + else: + mid_args = [ + (x1 + (x2 - x1) * factor, y1 + (y2 - y1) * factor) + for (x1, y1), (x2, y2) in zip(args1, args2) + ] + yield (op1, mid_args) + + +if __name__ == "__main__": + pen = RecordingPen() + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25)) + pen.closePath() + from pprint import pprint + + pprint(pen.value) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reportLabPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reportLabPen.py new file mode 100644 index 00000000..2cb89c8b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reportLabPen.py @@ -0,0 +1,80 @@ +from fontTools.pens.basePen import BasePen +from reportlab.graphics.shapes import Path + + +__all__ = ["ReportLabPen"] + + +class ReportLabPen(BasePen): + + """A pen for drawing onto a ``reportlab.graphics.shapes.Path`` object.""" + + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + path = Path() + self.path = path + + def _moveTo(self, p): + (x, y) = p + self.path.moveTo(x, y) + + def _lineTo(self, p): + (x, y) = p + self.path.lineTo(x, y) + + def _curveToOne(self, p1, p2, p3): + (x1, y1) = p1 + (x2, y2) = p2 + (x3, y3) = p3 + self.path.curveTo(x1, y1, x2, y2, x3, y3) + + def _closePath(self): + self.path.closePath() + + +if __name__ == "__main__": + import sys + + if len(sys.argv) < 3: + print( + "Usage: reportLabPen.py []" + ) + print( + " If no image file name is created, by default .png is created." + ) + print(" example: reportLabPen.py Arial.TTF R test.png") + print( + " (The file format will be PNG, regardless of the image file name supplied)" + ) + sys.exit(0) + + from fontTools.ttLib import TTFont + from reportlab.lib import colors + + path = sys.argv[1] + glyphName = sys.argv[2] + if len(sys.argv) > 3: + imageFile = sys.argv[3] + else: + imageFile = "%s.png" % glyphName + + font = TTFont(path) # it would work just as well with fontTools.t1Lib.T1Font + gs = font.getGlyphSet() + pen = ReportLabPen(gs, Path(fillColor=colors.red, strokeWidth=5)) + g = gs[glyphName] + g.draw(pen) + + w, h = g.width, 1000 + from reportlab.graphics import renderPM + from reportlab.graphics.shapes import Group, Drawing, scale + + # Everything is wrapped in a group to allow transformations. + g = Group(pen.path) + g.translate(0, 200) + g.scale(0.3, 0.3) + + d = Drawing(w, h) + d.add(g) + + renderPM.drawToFile(d, imageFile, fmt="PNG") diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reverseContourPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reverseContourPen.py new file mode 100644 index 00000000..a3756ab1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/reverseContourPen.py @@ -0,0 +1,96 @@ +from fontTools.misc.arrayTools import pairwise +from fontTools.pens.filterPen import ContourFilterPen + + +__all__ = ["reversedContour", "ReverseContourPen"] + + +class ReverseContourPen(ContourFilterPen): + """Filter pen that passes outline data to another pen, but reversing + the winding direction of all contours. Components are simply passed + through unchanged. + + Closed contours are reversed in such a way that the first point remains + the first point. + """ + + def __init__(self, outPen, outputImpliedClosingLine=False): + super().__init__(outPen) + self.outputImpliedClosingLine = outputImpliedClosingLine + + def filterContour(self, contour): + return reversedContour(contour, self.outputImpliedClosingLine) + + +def reversedContour(contour, outputImpliedClosingLine=False): + """Generator that takes a list of pen's (operator, operands) tuples, + and yields them with the winding direction reversed. + """ + if not contour: + return # nothing to do, stop iteration + + # valid contours must have at least a starting and ending command, + # can't have one without the other + assert len(contour) > 1, "invalid contour" + + # the type of the last command determines if the contour is closed + contourType = contour.pop()[0] + assert contourType in ("endPath", "closePath") + closed = contourType == "closePath" + + firstType, firstPts = contour.pop(0) + assert firstType in ("moveTo", "qCurveTo"), ( + "invalid initial segment type: %r" % firstType + ) + firstOnCurve = firstPts[-1] + if firstType == "qCurveTo": + # special case for TrueType paths contaning only off-curve points + assert firstOnCurve is None, "off-curve only paths must end with 'None'" + assert not contour, "only one qCurveTo allowed per off-curve path" + firstPts = (firstPts[0],) + tuple(reversed(firstPts[1:-1])) + (None,) + + if not contour: + # contour contains only one segment, nothing to reverse + if firstType == "moveTo": + closed = False # single-point paths can't be closed + else: + closed = True # off-curve paths are closed by definition + yield firstType, firstPts + else: + lastType, lastPts = contour[-1] + lastOnCurve = lastPts[-1] + if closed: + # for closed paths, we keep the starting point + yield firstType, firstPts + if firstOnCurve != lastOnCurve: + # emit an implied line between the last and first points + yield "lineTo", (lastOnCurve,) + contour[-1] = (lastType, tuple(lastPts[:-1]) + (firstOnCurve,)) + + if len(contour) > 1: + secondType, secondPts = contour[0] + else: + # contour has only two points, the second and last are the same + secondType, secondPts = lastType, lastPts + + if not outputImpliedClosingLine: + # if a lineTo follows the initial moveTo, after reversing it + # will be implied by the closePath, so we don't emit one; + # unless the lineTo and moveTo overlap, in which case we keep the + # duplicate points + if secondType == "lineTo" and firstPts != secondPts: + del contour[0] + if contour: + contour[-1] = (lastType, tuple(lastPts[:-1]) + secondPts) + else: + # for open paths, the last point will become the first + yield firstType, (lastOnCurve,) + contour[-1] = (lastType, tuple(lastPts[:-1]) + (firstOnCurve,)) + + # we iterate over all segment pairs in reverse order, and yield + # each one with the off-curve points reversed (if any), and + # with the on-curve point of the following segment + for (curType, curPts), (_, nextPts) in pairwise(contour, reverse=True): + yield curType, tuple(reversed(curPts[:-1])) + (nextPts[-1],) + + yield "closePath" if closed else "endPath", () diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/roundingPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/roundingPen.py new file mode 100644 index 00000000..2a7c476c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/roundingPen.py @@ -0,0 +1,112 @@ +from fontTools.misc.roundTools import otRound +from fontTools.misc.transform import Transform +from fontTools.pens.filterPen import FilterPen, FilterPointPen + + +__all__ = ["RoundingPen", "RoundingPointPen"] + + +class RoundingPen(FilterPen): + """ + Filter pen that rounds point coordinates and component XY offsets to integer. + + >>> from fontTools.pens.recordingPen import RecordingPen + >>> recpen = RecordingPen() + >>> roundpen = RoundingPen(recpen) + >>> roundpen.moveTo((0.4, 0.6)) + >>> roundpen.lineTo((1.6, 2.5)) + >>> roundpen.qCurveTo((2.4, 4.6), (3.3, 5.7), (4.9, 6.1)) + >>> roundpen.curveTo((6.4, 8.6), (7.3, 9.7), (8.9, 10.1)) + >>> roundpen.addComponent("a", (1.5, 0, 0, 1.5, 10.5, -10.5)) + >>> recpen.value == [ + ... ('moveTo', ((0, 1),)), + ... ('lineTo', ((2, 3),)), + ... ('qCurveTo', ((2, 5), (3, 6), (5, 6))), + ... ('curveTo', ((6, 9), (7, 10), (9, 10))), + ... ('addComponent', ('a', (1.5, 0, 0, 1.5, 11, -10))), + ... ] + True + """ + + def __init__(self, outPen, roundFunc=otRound): + super().__init__(outPen) + self.roundFunc = roundFunc + + def moveTo(self, pt): + self._outPen.moveTo((self.roundFunc(pt[0]), self.roundFunc(pt[1]))) + + def lineTo(self, pt): + self._outPen.lineTo((self.roundFunc(pt[0]), self.roundFunc(pt[1]))) + + def curveTo(self, *points): + self._outPen.curveTo( + *((self.roundFunc(x), self.roundFunc(y)) for x, y in points) + ) + + def qCurveTo(self, *points): + self._outPen.qCurveTo( + *((self.roundFunc(x), self.roundFunc(y)) for x, y in points) + ) + + def addComponent(self, glyphName, transformation): + self._outPen.addComponent( + glyphName, + Transform( + *transformation[:4], + self.roundFunc(transformation[4]), + self.roundFunc(transformation[5]), + ), + ) + + +class RoundingPointPen(FilterPointPen): + """ + Filter point pen that rounds point coordinates and component XY offsets to integer. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> recpen = RecordingPointPen() + >>> roundpen = RoundingPointPen(recpen) + >>> roundpen.beginPath() + >>> roundpen.addPoint((0.4, 0.6), 'line') + >>> roundpen.addPoint((1.6, 2.5), 'line') + >>> roundpen.addPoint((2.4, 4.6)) + >>> roundpen.addPoint((3.3, 5.7)) + >>> roundpen.addPoint((4.9, 6.1), 'qcurve') + >>> roundpen.endPath() + >>> roundpen.addComponent("a", (1.5, 0, 0, 1.5, 10.5, -10.5)) + >>> recpen.value == [ + ... ('beginPath', (), {}), + ... ('addPoint', ((0, 1), 'line', False, None), {}), + ... ('addPoint', ((2, 3), 'line', False, None), {}), + ... ('addPoint', ((2, 5), None, False, None), {}), + ... ('addPoint', ((3, 6), None, False, None), {}), + ... ('addPoint', ((5, 6), 'qcurve', False, None), {}), + ... ('endPath', (), {}), + ... ('addComponent', ('a', (1.5, 0, 0, 1.5, 11, -10)), {}), + ... ] + True + """ + + def __init__(self, outPen, roundFunc=otRound): + super().__init__(outPen) + self.roundFunc = roundFunc + + def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs): + self._outPen.addPoint( + (self.roundFunc(pt[0]), self.roundFunc(pt[1])), + segmentType=segmentType, + smooth=smooth, + name=name, + **kwargs, + ) + + def addComponent(self, baseGlyphName, transformation, **kwargs): + self._outPen.addComponent( + baseGlyphName, + Transform( + *transformation[:4], + self.roundFunc(transformation[4]), + self.roundFunc(transformation[5]), + ), + **kwargs, + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/statisticsPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/statisticsPen.py new file mode 100644 index 00000000..403ef39f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/statisticsPen.py @@ -0,0 +1,308 @@ +"""Pen calculating area, center of mass, variance and standard-deviation, +covariance and correlation, and slant, of glyph shapes.""" +from math import sqrt, degrees, atan +from fontTools.pens.basePen import BasePen, OpenContourError +from fontTools.pens.momentsPen import MomentsPen + +__all__ = ["StatisticsPen", "StatisticsControlPen"] + + +class StatisticsBase: + def __init__(self): + self._zero() + + def _zero(self): + self.area = 0 + self.meanX = 0 + self.meanY = 0 + self.varianceX = 0 + self.varianceY = 0 + self.stddevX = 0 + self.stddevY = 0 + self.covariance = 0 + self.correlation = 0 + self.slant = 0 + + def _update(self): + # XXX The variance formulas should never produce a negative value, + # but due to reasons I don't understand, both of our pens do. + # So we take the absolute value here. + self.varianceX = abs(self.varianceX) + self.varianceY = abs(self.varianceY) + + self.stddevX = stddevX = sqrt(self.varianceX) + self.stddevY = stddevY = sqrt(self.varianceY) + + # Correlation(X,Y) = Covariance(X,Y) / ( stddev(X) * stddev(Y) ) + # https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient + if stddevX * stddevY == 0: + correlation = float("NaN") + else: + # XXX The above formula should never produce a value outside + # the range [-1, 1], but due to reasons I don't understand, + # (probably the same issue as above), it does. So we clamp. + correlation = self.covariance / (stddevX * stddevY) + correlation = max(-1, min(1, correlation)) + self.correlation = correlation if abs(correlation) > 1e-3 else 0 + + slant = ( + self.covariance / self.varianceY if self.varianceY != 0 else float("NaN") + ) + self.slant = slant if abs(slant) > 1e-3 else 0 + + +class StatisticsPen(StatisticsBase, MomentsPen): + + """Pen calculating area, center of mass, variance and + standard-deviation, covariance and correlation, and slant, + of glyph shapes. + + Note that if the glyph shape is self-intersecting, the values + are not correct (but well-defined). Moreover, area will be + negative if contour directions are clockwise.""" + + def __init__(self, glyphset=None): + MomentsPen.__init__(self, glyphset=glyphset) + StatisticsBase.__init__(self) + + def _closePath(self): + MomentsPen._closePath(self) + self._update() + + def _update(self): + area = self.area + if not area: + self._zero() + return + + # Center of mass + # https://en.wikipedia.org/wiki/Center_of_mass#A_continuous_volume + self.meanX = meanX = self.momentX / area + self.meanY = meanY = self.momentY / area + + # Var(X) = E[X^2] - E[X]^2 + self.varianceX = self.momentXX / area - meanX * meanX + self.varianceY = self.momentYY / area - meanY * meanY + + # Covariance(X,Y) = (E[X.Y] - E[X]E[Y]) + self.covariance = self.momentXY / area - meanX * meanY + + StatisticsBase._update(self) + + +class StatisticsControlPen(StatisticsBase, BasePen): + + """Pen calculating area, center of mass, variance and + standard-deviation, covariance and correlation, and slant, + of glyph shapes, using the control polygon only. + + Note that if the glyph shape is self-intersecting, the values + are not correct (but well-defined). Moreover, area will be + negative if contour directions are clockwise.""" + + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) + StatisticsBase.__init__(self) + self._nodes = [] + + def _moveTo(self, pt): + self._nodes.append(complex(*pt)) + + def _lineTo(self, pt): + self._nodes.append(complex(*pt)) + + def _qCurveToOne(self, pt1, pt2): + for pt in (pt1, pt2): + self._nodes.append(complex(*pt)) + + def _curveToOne(self, pt1, pt2, pt3): + for pt in (pt1, pt2, pt3): + self._nodes.append(complex(*pt)) + + def _closePath(self): + self._update() + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + raise OpenContourError("Glyph statistics not defined on open contours.") + + def _update(self): + nodes = self._nodes + n = len(nodes) + + # Triangle formula + self.area = ( + sum( + (p0.real * p1.imag - p1.real * p0.imag) + for p0, p1 in zip(nodes, nodes[1:] + nodes[:1]) + ) + / 2 + ) + + # Center of mass + # https://en.wikipedia.org/wiki/Center_of_mass#A_system_of_particles + sumNodes = sum(nodes) + self.meanX = meanX = sumNodes.real / n + self.meanY = meanY = sumNodes.imag / n + + if n > 1: + # Var(X) = (sum[X^2] - sum[X]^2 / n) / (n - 1) + # https://www.statisticshowto.com/probability-and-statistics/descriptive-statistics/sample-variance/ + self.varianceX = varianceX = ( + sum(p.real * p.real for p in nodes) + - (sumNodes.real * sumNodes.real) / n + ) / (n - 1) + self.varianceY = varianceY = ( + sum(p.imag * p.imag for p in nodes) + - (sumNodes.imag * sumNodes.imag) / n + ) / (n - 1) + + # Covariance(X,Y) = (sum[X.Y] - sum[X].sum[Y] / n) / (n - 1) + self.covariance = covariance = ( + sum(p.real * p.imag for p in nodes) + - (sumNodes.real * sumNodes.imag) / n + ) / (n - 1) + else: + self.varianceX = varianceX = 0 + self.varianceY = varianceY = 0 + self.covariance = covariance = 0 + + StatisticsBase._update(self) + + +def _test(glyphset, upem, glyphs, quiet=False, *, control=False): + from fontTools.pens.transformPen import TransformPen + from fontTools.misc.transform import Scale + + wght_sum = 0 + wght_sum_perceptual = 0 + wdth_sum = 0 + slnt_sum = 0 + slnt_sum_perceptual = 0 + for glyph_name in glyphs: + glyph = glyphset[glyph_name] + if control: + pen = StatisticsControlPen(glyphset=glyphset) + else: + pen = StatisticsPen(glyphset=glyphset) + transformer = TransformPen(pen, Scale(1.0 / upem)) + glyph.draw(transformer) + + area = abs(pen.area) + width = glyph.width + wght_sum += area + wght_sum_perceptual += pen.area * width + wdth_sum += width + slnt_sum += pen.slant + slnt_sum_perceptual += pen.slant * width + + if quiet: + continue + + print() + print("glyph:", glyph_name) + + for item in [ + "area", + "momentX", + "momentY", + "momentXX", + "momentYY", + "momentXY", + "meanX", + "meanY", + "varianceX", + "varianceY", + "stddevX", + "stddevY", + "covariance", + "correlation", + "slant", + ]: + print("%s: %g" % (item, getattr(pen, item))) + + if not quiet: + print() + print("font:") + + print("weight: %g" % (wght_sum * upem / wdth_sum)) + print("weight (perceptual): %g" % (wght_sum_perceptual / wdth_sum)) + print("width: %g" % (wdth_sum / upem / len(glyphs))) + slant = slnt_sum / len(glyphs) + print("slant: %g" % slant) + print("slant angle: %g" % -degrees(atan(slant))) + slant_perceptual = slnt_sum_perceptual / wdth_sum + print("slant (perceptual): %g" % slant_perceptual) + print("slant (perceptual) angle: %g" % -degrees(atan(slant_perceptual))) + + +def main(args): + """Report font glyph shape geometricsl statistics""" + + if args is None: + import sys + + args = sys.argv[1:] + + import argparse + + parser = argparse.ArgumentParser( + "fonttools pens.statisticsPen", + description="Report font glyph shape geometricsl statistics", + ) + parser.add_argument("font", metavar="font.ttf", help="Font file.") + parser.add_argument("glyphs", metavar="glyph-name", help="Glyph names.", nargs="*") + parser.add_argument( + "-y", + metavar="", + help="Face index into a collection to open. Zero based.", + ) + parser.add_argument( + "-c", + "--control", + action="store_true", + help="Use the control-box pen instead of the Green therem.", + ) + parser.add_argument( + "-q", "--quiet", action="store_true", help="Only report font-wide statistics." + ) + parser.add_argument( + "--variations", + metavar="AXIS=LOC", + default="", + help="List of space separated locations. A location consist in " + "the name of a variation axis, followed by '=' and a number. E.g.: " + "wght=700 wdth=80. The default is the location of the base master.", + ) + + options = parser.parse_args(args) + + glyphs = options.glyphs + fontNumber = int(options.y) if options.y is not None else 0 + + location = {} + for tag_v in options.variations.split(): + fields = tag_v.split("=") + tag = fields[0].strip() + v = int(fields[1]) + location[tag] = v + + from fontTools.ttLib import TTFont + + font = TTFont(options.font, fontNumber=fontNumber) + if not glyphs: + glyphs = font.getGlyphOrder() + _test( + font.getGlyphSet(location=location), + font["head"].unitsPerEm, + glyphs, + quiet=options.quiet, + control=options.control, + ) + + +if __name__ == "__main__": + import sys + + main(sys.argv[1:]) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/svgPathPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/svgPathPen.py new file mode 100644 index 00000000..53b3683f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/svgPathPen.py @@ -0,0 +1,293 @@ +from typing import Callable +from fontTools.pens.basePen import BasePen + + +def pointToString(pt, ntos=str): + return " ".join(ntos(i) for i in pt) + + +class SVGPathPen(BasePen): + """Pen to draw SVG path d commands. + + Example:: + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((1, 1)) + >>> pen.curveTo((2, 2), (3, 3), (4, 4)) + >>> pen.closePath() + >>> pen.getCommands() + 'M0 0 1 1C2 2 3 3 4 4Z' + + Args: + glyphSet: a dictionary of drawable glyph objects keyed by name + used to resolve component references in composite glyphs. + ntos: a callable that takes a number and returns a string, to + customize how numbers are formatted (default: str). + + Note: + Fonts have a coordinate system where Y grows up, whereas in SVG, + Y grows down. As such, rendering path data from this pen in + SVG typically results in upside-down glyphs. You can fix this + by wrapping the data from this pen in an SVG group element with + transform, or wrap this pen in a transform pen. For example: + + spen = svgPathPen.SVGPathPen(glyphset) + pen= TransformPen(spen , (1, 0, 0, -1, 0, 0)) + glyphset[glyphname].draw(pen) + print(tpen.getCommands()) + """ + + def __init__(self, glyphSet, ntos: Callable[[float], str] = str): + BasePen.__init__(self, glyphSet) + self._commands = [] + self._lastCommand = None + self._lastX = None + self._lastY = None + self._ntos = ntos + + def _handleAnchor(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.moveTo((10, 10)) + >>> pen._commands + ['M10 10'] + """ + if self._lastCommand == "M": + self._commands.pop(-1) + + def _moveTo(self, pt): + """ + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen._commands + ['M0 0'] + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 0)) + >>> pen._commands + ['M10 0'] + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 10)) + >>> pen._commands + ['M0 10'] + """ + self._handleAnchor() + t = "M%s" % (pointToString(pt, self._ntos)) + self._commands.append(t) + self._lastCommand = "M" + self._lastX, self._lastY = pt + + def _lineTo(self, pt): + """ + # duplicate point + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((10, 10)) + >>> pen._commands + ['M10 10'] + + # vertical line + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((10, 0)) + >>> pen._commands + ['M10 10', 'V0'] + + # horizontal line + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((0, 10)) + >>> pen._commands + ['M10 10', 'H0'] + + # basic + >>> pen = SVGPathPen(None) + >>> pen.lineTo((70, 80)) + >>> pen._commands + ['L70 80'] + + # basic following a moveto + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((10, 10)) + >>> pen._commands + ['M0 0', ' 10 10'] + """ + x, y = pt + # duplicate point + if x == self._lastX and y == self._lastY: + return + # vertical line + elif x == self._lastX: + cmd = "V" + pts = self._ntos(y) + # horizontal line + elif y == self._lastY: + cmd = "H" + pts = self._ntos(x) + # previous was a moveto + elif self._lastCommand == "M": + cmd = None + pts = " " + pointToString(pt, self._ntos) + # basic + else: + cmd = "L" + pts = pointToString(pt, self._ntos) + # write the string + t = "" + if cmd: + t += cmd + self._lastCommand = cmd + t += pts + self._commands.append(t) + # store for future reference + self._lastX, self._lastY = pt + + def _curveToOne(self, pt1, pt2, pt3): + """ + >>> pen = SVGPathPen(None) + >>> pen.curveTo((10, 20), (30, 40), (50, 60)) + >>> pen._commands + ['C10 20 30 40 50 60'] + """ + t = "C" + t += pointToString(pt1, self._ntos) + " " + t += pointToString(pt2, self._ntos) + " " + t += pointToString(pt3, self._ntos) + self._commands.append(t) + self._lastCommand = "C" + self._lastX, self._lastY = pt3 + + def _qCurveToOne(self, pt1, pt2): + """ + >>> pen = SVGPathPen(None) + >>> pen.qCurveTo((10, 20), (30, 40)) + >>> pen._commands + ['Q10 20 30 40'] + >>> from fontTools.misc.roundTools import otRound + >>> pen = SVGPathPen(None, ntos=lambda v: str(otRound(v))) + >>> pen.qCurveTo((3, 3), (7, 5), (11, 4)) + >>> pen._commands + ['Q3 3 5 4', 'Q7 5 11 4'] + """ + assert pt2 is not None + t = "Q" + t += pointToString(pt1, self._ntos) + " " + t += pointToString(pt2, self._ntos) + self._commands.append(t) + self._lastCommand = "Q" + self._lastX, self._lastY = pt2 + + def _closePath(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.closePath() + >>> pen._commands + ['Z'] + """ + self._commands.append("Z") + self._lastCommand = "Z" + self._lastX = self._lastY = None + + def _endPath(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.endPath() + >>> pen._commands + [] + """ + self._lastCommand = None + self._lastX = self._lastY = None + + def getCommands(self): + return "".join(self._commands) + + +def main(args=None): + """Generate per-character SVG from font and text""" + + if args is None: + import sys + + args = sys.argv[1:] + + from fontTools.ttLib import TTFont + import argparse + + parser = argparse.ArgumentParser( + "fonttools pens.svgPathPen", description="Generate SVG from text" + ) + parser.add_argument("font", metavar="font.ttf", help="Font file.") + parser.add_argument("text", metavar="text", help="Text string.") + parser.add_argument( + "-y", + metavar="", + help="Face index into a collection to open. Zero based.", + ) + parser.add_argument( + "--variations", + metavar="AXIS=LOC", + default="", + help="List of space separated locations. A location consist in " + "the name of a variation axis, followed by '=' and a number. E.g.: " + "wght=700 wdth=80. The default is the location of the base master.", + ) + + options = parser.parse_args(args) + + fontNumber = int(options.y) if options.y is not None else 0 + + font = TTFont(options.font, fontNumber=fontNumber) + text = options.text + + location = {} + for tag_v in options.variations.split(): + fields = tag_v.split("=") + tag = fields[0].strip() + v = float(fields[1]) + location[tag] = v + + hhea = font["hhea"] + ascent, descent = hhea.ascent, hhea.descent + + glyphset = font.getGlyphSet(location=location) + cmap = font["cmap"].getBestCmap() + + s = "" + width = 0 + for u in text: + g = cmap[ord(u)] + glyph = glyphset[g] + + pen = SVGPathPen(glyphset) + glyph.draw(pen) + commands = pen.getCommands() + + s += '\n' % ( + width, + ascent, + commands, + ) + + width += glyph.width + + print('') + print( + '' + % (width, ascent - descent) + ) + print(s, end="") + print("") + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/t2CharStringPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/t2CharStringPen.py new file mode 100644 index 00000000..41ab0f92 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/t2CharStringPen.py @@ -0,0 +1,68 @@ +# Copyright (c) 2009 Type Supply LLC +# Author: Tal Leming + +from fontTools.misc.roundTools import otRound, roundFunc +from fontTools.misc.psCharStrings import T2CharString +from fontTools.pens.basePen import BasePen +from fontTools.cffLib.specializer import specializeCommands, commandsToProgram + + +class T2CharStringPen(BasePen): + """Pen to draw Type 2 CharStrings. + + The 'roundTolerance' argument controls the rounding of point coordinates. + It is defined as the maximum absolute difference between the original + float and the rounded integer value. + The default tolerance of 0.5 means that all floats are rounded to integer; + a value of 0 disables rounding; values in between will only round floats + which are close to their integral part within the tolerated range. + """ + + def __init__(self, width, glyphSet, roundTolerance=0.5, CFF2=False): + super(T2CharStringPen, self).__init__(glyphSet) + self.round = roundFunc(roundTolerance) + self._CFF2 = CFF2 + self._width = width + self._commands = [] + self._p0 = (0, 0) + + def _p(self, pt): + p0 = self._p0 + pt = self._p0 = (self.round(pt[0]), self.round(pt[1])) + return [pt[0] - p0[0], pt[1] - p0[1]] + + def _moveTo(self, pt): + self._commands.append(("rmoveto", self._p(pt))) + + def _lineTo(self, pt): + self._commands.append(("rlineto", self._p(pt))) + + def _curveToOne(self, pt1, pt2, pt3): + _p = self._p + self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3))) + + def _closePath(self): + pass + + def _endPath(self): + pass + + def getCharString(self, private=None, globalSubrs=None, optimize=True): + commands = self._commands + if optimize: + maxstack = 48 if not self._CFF2 else 513 + commands = specializeCommands( + commands, generalizeFirst=False, maxstack=maxstack + ) + program = commandsToProgram(commands) + if self._width is not None: + assert ( + not self._CFF2 + ), "CFF2 does not allow encoding glyph width in CharString." + program.insert(0, otRound(self._width)) + if not self._CFF2: + program.append("endchar") + charString = T2CharString( + program=program, private=private, globalSubrs=globalSubrs + ) + return charString diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/teePen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/teePen.py new file mode 100644 index 00000000..2828175a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/teePen.py @@ -0,0 +1,54 @@ +"""Pen multiplexing drawing to one or more pens.""" +from fontTools.pens.basePen import AbstractPen + + +__all__ = ["TeePen"] + + +class TeePen(AbstractPen): + """Pen multiplexing drawing to one or more pens. + + Use either as TeePen(pen1, pen2, ...) or TeePen(iterableOfPens).""" + + def __init__(self, *pens): + if len(pens) == 1: + pens = pens[0] + self.pens = pens + + def moveTo(self, p0): + for pen in self.pens: + pen.moveTo(p0) + + def lineTo(self, p1): + for pen in self.pens: + pen.lineTo(p1) + + def qCurveTo(self, *points): + for pen in self.pens: + pen.qCurveTo(*points) + + def curveTo(self, *points): + for pen in self.pens: + pen.curveTo(*points) + + def closePath(self): + for pen in self.pens: + pen.closePath() + + def endPath(self): + for pen in self.pens: + pen.endPath() + + def addComponent(self, glyphName, transformation): + for pen in self.pens: + pen.addComponent(glyphName, transformation) + + +if __name__ == "__main__": + from fontTools.pens.basePen import _TestPen + + pen = TeePen(_TestPen(), _TestPen()) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25)) + pen.closePath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/transformPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/transformPen.py new file mode 100644 index 00000000..2e572f61 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/transformPen.py @@ -0,0 +1,111 @@ +from fontTools.pens.filterPen import FilterPen, FilterPointPen + + +__all__ = ["TransformPen", "TransformPointPen"] + + +class TransformPen(FilterPen): + + """Pen that transforms all coordinates using a Affine transformation, + and passes them to another pen. + """ + + def __init__(self, outPen, transformation): + """The 'outPen' argument is another pen object. It will receive the + transformed coordinates. The 'transformation' argument can either + be a six-tuple, or a fontTools.misc.transform.Transform object. + """ + super(TransformPen, self).__init__(outPen) + if not hasattr(transformation, "transformPoint"): + from fontTools.misc.transform import Transform + + transformation = Transform(*transformation) + self._transformation = transformation + self._transformPoint = transformation.transformPoint + self._stack = [] + + def moveTo(self, pt): + self._outPen.moveTo(self._transformPoint(pt)) + + def lineTo(self, pt): + self._outPen.lineTo(self._transformPoint(pt)) + + def curveTo(self, *points): + self._outPen.curveTo(*self._transformPoints(points)) + + def qCurveTo(self, *points): + if points[-1] is None: + points = self._transformPoints(points[:-1]) + [None] + else: + points = self._transformPoints(points) + self._outPen.qCurveTo(*points) + + def _transformPoints(self, points): + transformPoint = self._transformPoint + return [transformPoint(pt) for pt in points] + + def closePath(self): + self._outPen.closePath() + + def endPath(self): + self._outPen.endPath() + + def addComponent(self, glyphName, transformation): + transformation = self._transformation.transform(transformation) + self._outPen.addComponent(glyphName, transformation) + + +class TransformPointPen(FilterPointPen): + """PointPen that transforms all coordinates using a Affine transformation, + and passes them to another PointPen. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = TransformPointPen(rec, (2, 0, 0, 2, -10, 5)) + >>> v = iter(rec.value) + >>> pen.beginPath(identifier="contour-0") + >>> next(v) + ('beginPath', (), {'identifier': 'contour-0'}) + >>> pen.addPoint((100, 100), "line") + >>> next(v) + ('addPoint', ((190, 205), 'line', False, None), {}) + >>> pen.endPath() + >>> next(v) + ('endPath', (), {}) + >>> pen.addComponent("a", (1, 0, 0, 1, -10, 5), identifier="component-0") + >>> next(v) + ('addComponent', ('a', ), {'identifier': 'component-0'}) + """ + + def __init__(self, outPointPen, transformation): + """The 'outPointPen' argument is another point pen object. + It will receive the transformed coordinates. + The 'transformation' argument can either be a six-tuple, or a + fontTools.misc.transform.Transform object. + """ + super().__init__(outPointPen) + if not hasattr(transformation, "transformPoint"): + from fontTools.misc.transform import Transform + + transformation = Transform(*transformation) + self._transformation = transformation + self._transformPoint = transformation.transformPoint + + def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs): + self._outPen.addPoint( + self._transformPoint(pt), segmentType, smooth, name, **kwargs + ) + + def addComponent(self, baseGlyphName, transformation, **kwargs): + transformation = self._transformation.transform(transformation) + self._outPen.addComponent(baseGlyphName, transformation, **kwargs) + + +if __name__ == "__main__": + from fontTools.pens.basePen import _TestPen + + pen = TransformPen(_TestPen(None), (2, 0, 0.5, 2, -10, 0)) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0)) + pen.closePath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/ttGlyphPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/ttGlyphPen.py new file mode 100644 index 00000000..de2ccaee --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/ttGlyphPen.py @@ -0,0 +1,335 @@ +from array import array +from typing import Any, Callable, Dict, Optional, Tuple +from fontTools.misc.fixedTools import MAX_F2DOT14, floatToFixedToFloat +from fontTools.misc.loggingTools import LogMixin +from fontTools.pens.pointPen import AbstractPointPen +from fontTools.misc.roundTools import otRound +from fontTools.pens.basePen import LoggingPen, PenError +from fontTools.pens.transformPen import TransformPen, TransformPointPen +from fontTools.ttLib.tables import ttProgram +from fontTools.ttLib.tables._g_l_y_f import flagOnCurve, flagCubic +from fontTools.ttLib.tables._g_l_y_f import Glyph +from fontTools.ttLib.tables._g_l_y_f import GlyphComponent +from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates +from fontTools.ttLib.tables._g_l_y_f import dropImpliedOnCurvePoints +import math + + +__all__ = ["TTGlyphPen", "TTGlyphPointPen"] + + +class _TTGlyphBasePen: + def __init__( + self, + glyphSet: Optional[Dict[str, Any]], + handleOverflowingTransforms: bool = True, + ) -> None: + """ + Construct a new pen. + + Args: + glyphSet (Dict[str, Any]): A glyphset object, used to resolve components. + handleOverflowingTransforms (bool): See below. + + If ``handleOverflowingTransforms`` is True, the components' transform values + are checked that they don't overflow the limits of a F2Dot14 number: + -2.0 <= v < +2.0. If any transform value exceeds these, the composite + glyph is decomposed. + + An exception to this rule is done for values that are very close to +2.0 + (both for consistency with the -2.0 case, and for the relative frequency + these occur in real fonts). When almost +2.0 values occur (and all other + values are within the range -2.0 <= x <= +2.0), they are clamped to the + maximum positive value that can still be encoded as an F2Dot14: i.e. + 1.99993896484375. + + If False, no check is done and all components are translated unmodified + into the glyf table, followed by an inevitable ``struct.error`` once an + attempt is made to compile them. + + If both contours and components are present in a glyph, the components + are decomposed. + """ + self.glyphSet = glyphSet + self.handleOverflowingTransforms = handleOverflowingTransforms + self.init() + + def _decompose( + self, + glyphName: str, + transformation: Tuple[float, float, float, float, float, float], + ): + tpen = self.transformPen(self, transformation) + getattr(self.glyphSet[glyphName], self.drawMethod)(tpen) + + def _isClosed(self): + """ + Check if the current path is closed. + """ + raise NotImplementedError + + def init(self) -> None: + self.points = [] + self.endPts = [] + self.types = [] + self.components = [] + + def addComponent( + self, + baseGlyphName: str, + transformation: Tuple[float, float, float, float, float, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """ + Add a sub glyph. + """ + self.components.append((baseGlyphName, transformation)) + + def _buildComponents(self, componentFlags): + if self.handleOverflowingTransforms: + # we can't encode transform values > 2 or < -2 in F2Dot14, + # so we must decompose the glyph if any transform exceeds these + overflowing = any( + s > 2 or s < -2 + for (glyphName, transformation) in self.components + for s in transformation[:4] + ) + components = [] + for glyphName, transformation in self.components: + if glyphName not in self.glyphSet: + self.log.warning(f"skipped non-existing component '{glyphName}'") + continue + if self.points or (self.handleOverflowingTransforms and overflowing): + # can't have both coordinates and components, so decompose + self._decompose(glyphName, transformation) + continue + + component = GlyphComponent() + component.glyphName = glyphName + component.x, component.y = (otRound(v) for v in transformation[4:]) + # quantize floats to F2Dot14 so we get same values as when decompiled + # from a binary glyf table + transformation = tuple( + floatToFixedToFloat(v, 14) for v in transformation[:4] + ) + if transformation != (1, 0, 0, 1): + if self.handleOverflowingTransforms and any( + MAX_F2DOT14 < s <= 2 for s in transformation + ): + # clamp values ~= +2.0 so we can keep the component + transformation = tuple( + MAX_F2DOT14 if MAX_F2DOT14 < s <= 2 else s + for s in transformation + ) + component.transform = (transformation[:2], transformation[2:]) + component.flags = componentFlags + components.append(component) + return components + + def glyph( + self, + componentFlags: int = 0x04, + dropImpliedOnCurves: bool = False, + *, + round: Callable[[float], int] = otRound, + ) -> Glyph: + """ + Returns a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + + Args: + componentFlags: Flags to use for component glyphs. (default: 0x04) + + dropImpliedOnCurves: Whether to remove implied-oncurve points. (default: False) + """ + if not self._isClosed(): + raise PenError("Didn't close last contour.") + components = self._buildComponents(componentFlags) + + glyph = Glyph() + glyph.coordinates = GlyphCoordinates(self.points) + glyph.endPtsOfContours = self.endPts + glyph.flags = array("B", self.types) + self.init() + + if components: + # If both components and contours were present, they have by now + # been decomposed by _buildComponents. + glyph.components = components + glyph.numberOfContours = -1 + else: + glyph.numberOfContours = len(glyph.endPtsOfContours) + glyph.program = ttProgram.Program() + glyph.program.fromBytecode(b"") + if dropImpliedOnCurves: + dropImpliedOnCurvePoints(glyph) + glyph.coordinates.toInt(round=round) + + return glyph + + +class TTGlyphPen(_TTGlyphBasePen, LoggingPen): + """ + Pen used for drawing to a TrueType glyph. + + This pen can be used to construct or modify glyphs in a TrueType format + font. After using the pen to draw, use the ``.glyph()`` method to retrieve + a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + """ + + drawMethod = "draw" + transformPen = TransformPen + + def __init__( + self, + glyphSet: Optional[Dict[str, Any]] = None, + handleOverflowingTransforms: bool = True, + outputImpliedClosingLine: bool = False, + ) -> None: + super().__init__(glyphSet, handleOverflowingTransforms) + self.outputImpliedClosingLine = outputImpliedClosingLine + + def _addPoint(self, pt: Tuple[float, float], tp: int) -> None: + self.points.append(pt) + self.types.append(tp) + + def _popPoint(self) -> None: + self.points.pop() + self.types.pop() + + def _isClosed(self) -> bool: + return (not self.points) or ( + self.endPts and self.endPts[-1] == len(self.points) - 1 + ) + + def lineTo(self, pt: Tuple[float, float]) -> None: + self._addPoint(pt, flagOnCurve) + + def moveTo(self, pt: Tuple[float, float]) -> None: + if not self._isClosed(): + raise PenError('"move"-type point must begin a new contour.') + self._addPoint(pt, flagOnCurve) + + def curveTo(self, *points) -> None: + assert len(points) % 2 == 1 + for pt in points[:-1]: + self._addPoint(pt, flagCubic) + + # last point is None if there are no on-curve points + if points[-1] is not None: + self._addPoint(points[-1], 1) + + def qCurveTo(self, *points) -> None: + assert len(points) >= 1 + for pt in points[:-1]: + self._addPoint(pt, 0) + + # last point is None if there are no on-curve points + if points[-1] is not None: + self._addPoint(points[-1], 1) + + def closePath(self) -> None: + endPt = len(self.points) - 1 + + # ignore anchors (one-point paths) + if endPt == 0 or (self.endPts and endPt == self.endPts[-1] + 1): + self._popPoint() + return + + if not self.outputImpliedClosingLine: + # if first and last point on this path are the same, remove last + startPt = 0 + if self.endPts: + startPt = self.endPts[-1] + 1 + if self.points[startPt] == self.points[endPt]: + self._popPoint() + endPt -= 1 + + self.endPts.append(endPt) + + def endPath(self) -> None: + # TrueType contours are always "closed" + self.closePath() + + +class TTGlyphPointPen(_TTGlyphBasePen, LogMixin, AbstractPointPen): + """ + Point pen used for drawing to a TrueType glyph. + + This pen can be used to construct or modify glyphs in a TrueType format + font. After using the pen to draw, use the ``.glyph()`` method to retrieve + a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + """ + + drawMethod = "drawPoints" + transformPen = TransformPointPen + + def init(self) -> None: + super().init() + self._currentContourStartIndex = None + + def _isClosed(self) -> bool: + return self._currentContourStartIndex is None + + def beginPath(self, identifier: Optional[str] = None, **kwargs: Any) -> None: + """ + Start a new sub path. + """ + if not self._isClosed(): + raise PenError("Didn't close previous contour.") + self._currentContourStartIndex = len(self.points) + + def endPath(self) -> None: + """ + End the current sub path. + """ + # TrueType contours are always "closed" + if self._isClosed(): + raise PenError("Contour is already closed.") + if self._currentContourStartIndex == len(self.points): + # ignore empty contours + self._currentContourStartIndex = None + return + + contourStart = self.endPts[-1] + 1 if self.endPts else 0 + self.endPts.append(len(self.points) - 1) + self._currentContourStartIndex = None + + # Resolve types for any cubic segments + flags = self.types + for i in range(contourStart, len(flags)): + if flags[i] == "curve": + j = i - 1 + if j < contourStart: + j = len(flags) - 1 + while flags[j] == 0: + flags[j] = flagCubic + j -= 1 + flags[i] = flagOnCurve + + def addPoint( + self, + pt: Tuple[float, float], + segmentType: Optional[str] = None, + smooth: bool = False, + name: Optional[str] = None, + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """ + Add a point to the current sub path. + """ + if self._isClosed(): + raise PenError("Can't add a point to a closed contour.") + if segmentType is None: + self.types.append(0) + elif segmentType in ("line", "move"): + self.types.append(flagOnCurve) + elif segmentType == "qcurve": + self.types.append(flagOnCurve) + elif segmentType == "curve": + self.types.append("curve") + else: + raise AssertionError(segmentType) + + self.points.append(pt) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/wxPen.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/wxPen.py new file mode 100644 index 00000000..c790641a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/pens/wxPen.py @@ -0,0 +1,29 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["WxPen"] + + +class WxPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + import wx + + path = wx.GraphicsRenderer.GetDefaultRenderer().CreatePath() + self.path = path + + def _moveTo(self, p): + self.path.MoveToPoint(*p) + + def _lineTo(self, p): + self.path.AddLineToPoint(*p) + + def _curveToOne(self, p1, p2, p3): + self.path.AddCurveToPoint(*p1 + p2 + p3) + + def _qCurveToOne(self, p1, p2): + self.path.AddQuadCurveToPoint(*p1 + p2) + + def _closePath(self): + self.path.CloseSubpath() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__init__.py new file mode 100644 index 00000000..ce357417 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .qu2cu import * diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__main__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__main__.py new file mode 100644 index 00000000..27728cc7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/__main__.py @@ -0,0 +1,7 @@ +import sys + +from .cli import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/benchmark.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/benchmark.py new file mode 100644 index 00000000..cee55f5e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/benchmark.py @@ -0,0 +1,57 @@ +"""Benchmark the qu2cu algorithm performance.""" + +from .qu2cu import * +from fontTools.cu2qu import curve_to_quadratic +import random +import timeit + +MAX_ERR = 0.5 +NUM_CURVES = 5 + + +def generate_curves(n): + points = [ + tuple(float(random.randint(0, 2048)) for coord in range(2)) + for point in range(1 + 3 * n) + ] + curves = [] + for i in range(n): + curves.append(tuple(points[i * 3 : i * 3 + 4])) + return curves + + +def setup_quadratic_to_curves(): + curves = generate_curves(NUM_CURVES) + quadratics = [curve_to_quadratic(curve, MAX_ERR) for curve in curves] + return quadratics, MAX_ERR + + +def run_benchmark(module, function, setup_suffix="", repeat=25, number=1): + setup_func = "setup_" + function + if setup_suffix: + print("%s with %s:" % (function, setup_suffix), end="") + setup_func += "_" + setup_suffix + else: + print("%s:" % function, end="") + + def wrapper(function, setup_func): + function = globals()[function] + setup_func = globals()[setup_func] + + def wrapped(): + return function(*setup_func()) + + return wrapped + + results = timeit.repeat(wrapper(function, setup_func), repeat=repeat, number=number) + print("\t%5.1fus" % (min(results) * 1000000.0 / number)) + + +def main(): + """Benchmark the qu2cu algorithm performance.""" + run_benchmark("qu2cu", "quadratic_to_curves") + + +if __name__ == "__main__": + random.seed(1) + main() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/cli.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/cli.py new file mode 100644 index 00000000..a07fd6dc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/cli.py @@ -0,0 +1,125 @@ +import os +import argparse +import logging +from fontTools.misc.cliTools import makeOutputFileName +from fontTools.ttLib import TTFont +from fontTools.pens.qu2cuPen import Qu2CuPen +from fontTools.pens.ttGlyphPen import TTGlyphPen +import fontTools + + +logger = logging.getLogger("fontTools.qu2cu") + + +def _font_to_cubic(input_path, output_path=None, **kwargs): + font = TTFont(input_path) + logger.info("Converting curves for %s", input_path) + + stats = {} if kwargs["dump_stats"] else None + qu2cu_kwargs = { + "stats": stats, + "max_err": kwargs["max_err_em"] * font["head"].unitsPerEm, + "all_cubic": kwargs["all_cubic"], + } + + assert "gvar" not in font, "Cannot convert variable font" + glyphSet = font.getGlyphSet() + glyphOrder = font.getGlyphOrder() + glyf = font["glyf"] + for glyphName in glyphOrder: + glyph = glyphSet[glyphName] + ttpen = TTGlyphPen(glyphSet) + pen = Qu2CuPen(ttpen, **qu2cu_kwargs) + glyph.draw(pen) + glyf[glyphName] = ttpen.glyph(dropImpliedOnCurves=True) + + font["head"].glyphDataFormat = 1 + + if kwargs["dump_stats"]: + logger.info("Stats: %s", stats) + + logger.info("Saving %s", output_path) + font.save(output_path) + + +def main(args=None): + """Convert an OpenType font from quadratic to cubic curves""" + parser = argparse.ArgumentParser(prog="qu2cu") + parser.add_argument("--version", action="version", version=fontTools.__version__) + parser.add_argument( + "infiles", + nargs="+", + metavar="INPUT", + help="one or more input TTF source file(s).", + ) + parser.add_argument("-v", "--verbose", action="count", default=0) + parser.add_argument( + "-e", + "--conversion-error", + type=float, + metavar="ERROR", + default=0.001, + help="maxiumum approximation error measured in EM (default: 0.001)", + ) + parser.add_argument( + "-c", + "--all-cubic", + default=False, + action="store_true", + help="whether to only use cubic curves", + ) + + output_parser = parser.add_mutually_exclusive_group() + output_parser.add_argument( + "-o", + "--output-file", + default=None, + metavar="OUTPUT", + help=("output filename for the converted TTF."), + ) + output_parser.add_argument( + "-d", + "--output-dir", + default=None, + metavar="DIRECTORY", + help="output directory where to save converted TTFs", + ) + + options = parser.parse_args(args) + + if not options.verbose: + level = "WARNING" + elif options.verbose == 1: + level = "INFO" + else: + level = "DEBUG" + logging.basicConfig(level=level) + + if len(options.infiles) > 1 and options.output_file: + parser.error("-o/--output-file can't be used with multile inputs") + + if options.output_dir: + output_dir = options.output_dir + if not os.path.exists(output_dir): + os.mkdir(output_dir) + elif not os.path.isdir(output_dir): + parser.error("'%s' is not a directory" % output_dir) + output_paths = [ + os.path.join(output_dir, os.path.basename(p)) for p in options.infiles + ] + elif options.output_file: + output_paths = [options.output_file] + else: + output_paths = [ + makeOutputFileName(p, overWrite=True, suffix=".cubic") + for p in options.infiles + ] + + kwargs = dict( + dump_stats=options.verbose > 0, + max_err_em=options.conversion_error, + all_cubic=options.all_cubic, + ) + + for input_path, output_path in zip(options.infiles, output_paths): + _font_to_cubic(input_path, output_path, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.c b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.c new file mode 100644 index 00000000..db95fc23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.c @@ -0,0 +1,16325 @@ +/* Generated by Cython 3.0.6 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "define_macros": [ + [ + "CYTHON_TRACE_NOGIL", + "1" + ] + ], + "name": "fontTools.qu2cu.qu2cu", + "sources": [ + "Lib/fontTools/qu2cu/qu2cu.py" + ] + }, + "module_name": "fontTools.qu2cu.qu2cu" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_6" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x030006F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; // borrowed + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; // we don't yet need to distinguish between versions > 11 + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); // we don't have access to __pyx_empty_bytes here + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__qu2cu__qu2cu +#define __PYX_HAVE_API__fontTools__qu2cu__qu2cu +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const wchar_t *u) +{ + const wchar_t *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#endif +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else // Py < 3.12 + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "Lib/fontTools/qu2cu/qu2cu.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr; +struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr; + +/* "fontTools/qu2cu/qu2cu.py":238 + * + * if not is_complex: + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] # <<<<<<<<<<<<<< + * return curves + * + */ +struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_c; + int __pyx_v_cost; + int __pyx_v_is_complex; + PyObject *__pyx_t_0; + Py_ssize_t __pyx_t_1; + PyObject *(*__pyx_t_2)(PyObject *); +}; + + +/* "fontTools/qu2cu/qu2cu.py":343 + * for k, reconst in enumerate(reconstructed): + * orig = elevated_quadratics[j + k] + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) # <<<<<<<<<<<<<< + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + */ +struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + int __pyx_v_all_cubic; + int __pyx_v_count; + double __pyx_v_err; + double __pyx_v_error; + int __pyx_v_i; + int __pyx_v_i_sol_count; + double __pyx_v_i_sol_error; + int __pyx_v_is_cubic; + int __pyx_v_j; + int __pyx_v_j_sol_count; + double __pyx_v_j_sol_error; + int __pyx_v_k; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + int __pyx_v_start; + int __pyx_v_this_sol_count; + double __pyx_v_tolerance; + __pyx_t_double_complex __pyx_v_u; + __pyx_t_double_complex __pyx_v_v; + PyObject *__pyx_t_0; + Py_ssize_t __pyx_t_1; + PyObject *(*__pyx_t_2)(PyObject *); +}; + +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg // no-op + #define __Pyx_Arg_XDECREF_VARARGS(arg) // no-op - arg is borrowed +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg // no-op, __Pyx_Arg_FASTCALL is direct and this needs + #define __Pyx_Arg_XDECREF_FASTCALL(arg) // no-op - arg was returned from array +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* AssertionsEnabled.proto */ +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (1) +#elif CYTHON_COMPILING_IN_LIMITED_API || (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030C0000) + static int __pyx_assertions_enabled_flag; + #define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag) + static int __Pyx_init_assertions_enabled(void) { + PyObject *builtins, *debug, *debug_str; + int flag; + builtins = PyEval_GetBuiltins(); + if (!builtins) goto bad; + debug_str = PyUnicode_FromStringAndSize("__debug__", 9); + if (!debug_str) goto bad; + debug = PyObject_GetItem(builtins, debug_str); + Py_DECREF(debug_str); + if (!debug) goto bad; + flag = PyObject_IsTrue(debug); + Py_DECREF(debug); + if (flag == -1) goto bad; + __pyx_assertions_enabled_flag = flag; + return 0; + bad: + __pyx_assertions_enabled_flag = 1; + return -1; + } +#else + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (!Py_OptimizeFlag) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* py_abs.proto */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num); +#define __Pyx_PyNumber_Absolute(x)\ + ((likely(PyLong_CheckExact(x))) ?\ + (likely(__Pyx_PyLong_IsNonNeg(x)) ? (Py_INCREF(x), (x)) : __Pyx_PyLong_AbsNeg(x)) :\ + PyNumber_Absolute(x)) +#else +#define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x) +#endif + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* SliceTupleAndList.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop); +#else +#define __Pyx_PyList_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop) +#define __Pyx_PyTuple_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop) +#endif + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_SubtractCObj(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2)) +#endif + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* RaiseUnboundLocalError.proto */ +static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* pep479.proto */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif +#endif +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); + +/* SliceObject.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( + PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** py_start, PyObject** py_stop, PyObject** py_slice, + int has_cstart, int has_cstop, int wraparound); + +/* PyObjectCallNoArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* pop.proto */ +static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); +#define __Pyx_PyObject_Pop(L) (likely(PyList_CheckExact(L)) ?\ + __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L)) +#else +#define __Pyx_PyList_Pop(L) __Pyx__PyObject_Pop(L) +#define __Pyx_PyObject_Pop(L) __Pyx__PyObject_Pop(L) +#endif + +/* UnpackUnboundCMethod.proto */ +typedef struct { + PyObject *type; + PyObject **method_name; + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; + +/* CallUnboundCMethod0.proto */ +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CallUnboundCMethod0(cfunc, self)\ + (likely((cfunc)->func) ?\ + (likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) :\ + (PY_VERSION_HEX >= 0x030600B1 && likely((cfunc)->flag == METH_FASTCALL) ?\ + (PY_VERSION_HEX >= 0x030700A0 ?\ + (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0) :\ + (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0, NULL)) :\ + (PY_VERSION_HEX >= 0x030700A0 && (cfunc)->flag == (METH_FASTCALL | METH_KEYWORDS) ?\ + (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0, NULL) :\ + (likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, __pyx_empty_tuple, NULL)) :\ + ((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, __pyx_empty_tuple) :\ + __Pyx__CallUnboundCMethod0(cfunc, self)))))) :\ + __Pyx__CallUnboundCMethod0(cfunc, self)) +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* ListExtend.proto */ +static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + PyObject* none = _PyList_Extend((PyListObject*)L, v); + if (unlikely(!none)) + return -1; + Py_DECREF(none); + return 0; +#else + return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); +#endif +} + +/* RaiseUnexpectedTypeError.proto */ +static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); + +/* PyIntBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) +#endif + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* pyfrozenset_new.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it); + +/* PySetContains.proto */ +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* ValidateBasesTuple.proto */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; // used by FusedFunction for copying defaults + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* FromPy.proto */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject*); + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* ToPy.proto */ +#define __pyx_PyComplex_FromComplex(z)\ + PyComplex_FromDoubles((double)__Pyx_CREAL(z),\ + (double)__Pyx_CIMAG(z)) + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* CoroutineBase.proto */ +struct __pyx_CoroutineObject; +typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else +typedef struct { + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct __pyx_CoroutineObject { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; + PyObject *gi_weakreflist; + PyObject *classobj; + PyObject *yieldfrom; + PyObject *gi_name; + PyObject *gi_qualname; + PyObject *gi_modulename; + PyObject *gi_code; + PyObject *gi_frame; + int resume_label; + char is_running; +} __pyx_CoroutineObject; +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); +static int __Pyx_Coroutine_clear(PyObject *self); +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); +static PyObject *__Pyx_Coroutine_Close(PyObject *self); +static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else +#define __Pyx_Coroutine_SwapException(self) {\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ + } +#define __Pyx_Coroutine_ResetAndClearException(self) {\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ + } +#endif +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) +#else +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) +#endif +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); + +/* PatchModuleWithCoroutine.proto */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); + +/* PatchGeneratorABC.proto */ +static int __Pyx_patch_abc(void); + +/* Generator.proto */ +#define __Pyx_Generator_USED +#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType) +#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ + __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name) +static PyObject *__Pyx_Generator_Next(PyObject *self); +static int __pyx_Generator_init(PyObject *module); + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.qu2cu.qu2cu" */ +static int __pyx_f_9fontTools_5qu2cu_5qu2cu_cubic_farthest_fit_inside(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, double); /*proto*/ +static PyObject *__pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(PyObject *, int, int); /*proto*/ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.qu2cu.qu2cu" +extern int __pyx_module_is_main_fontTools__qu2cu__qu2cu; +int __pyx_module_is_main_fontTools__qu2cu__qu2cu = 0; + +/* Implementation of "fontTools.qu2cu.qu2cu" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_AttributeError; +static PyObject *__pyx_builtin_ImportError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_AssertionError; +static PyObject *__pyx_builtin_ZeroDivisionError; +static PyObject *__pyx_builtin_enumerate; +static PyObject *__pyx_builtin_reversed; +static PyObject *__pyx_builtin_zip; +static PyObject *__pyx_builtin_print; +/* #### Code section: string_decls ### */ +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_j[] = "j"; +static const char __pyx_k_k[] = "k"; +static const char __pyx_k_p[] = "p"; +static const char __pyx_k_q[] = "q"; +static const char __pyx_k_u[] = "u"; +static const char __pyx_k_v[] = "v"; +static const char __pyx_k_x[] = "x"; +static const char __pyx_k_y[] = "y"; +static const char __pyx_k__3[] = "."; +static const char __pyx_k__4[] = "*"; +static const char __pyx_k_gc[] = "gc"; +static const char __pyx_k_on[] = "on"; +static const char __pyx_k_p0[] = "p0"; +static const char __pyx_k_p1[] = "p1"; +static const char __pyx_k_p2[] = "p2"; +static const char __pyx_k_p3[] = "p3"; +static const char __pyx_k_qq[] = "qq"; +static const char __pyx_k_ts[] = "ts"; +static const char __pyx_k__15[] = "?"; +static const char __pyx_k_all[] = "__all__"; +static const char __pyx_k_err[] = "err"; +static const char __pyx_k_pop[] = "pop"; +static const char __pyx_k_zip[] = "zip"; +static const char __pyx_k_List[] = "List"; +static const char __pyx_k_args[] = "args"; +static const char __pyx_k_bool[] = "bool"; +static const char __pyx_k_cost[] = "cost"; +static const char __pyx_k_imag[] = "imag"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_math[] = "math"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_off1[] = "off1"; +static const char __pyx_k_off2[] = "off2"; +static const char __pyx_k_orig[] = "orig"; +static const char __pyx_k_real[] = "real"; +static const char __pyx_k_send[] = "send"; +static const char __pyx_k_sols[] = "sols"; +static const char __pyx_k_spec[] = "__spec__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_Point[] = "Point"; +static const char __pyx_k_Tuple[] = "Tuple"; +static const char __pyx_k_Union[] = "Union"; +static const char __pyx_k_close[] = "close"; +static const char __pyx_k_costs[] = "costs"; +static const char __pyx_k_count[] = "count"; +static const char __pyx_k_cubic[] = "cubic"; +static const char __pyx_k_curve[] = "curve"; +static const char __pyx_k_error[] = "error"; +static const char __pyx_k_float[] = "float"; +static const char __pyx_k_i_sol[] = "i_sol"; +static const char __pyx_k_print[] = "print"; +static const char __pyx_k_quads[] = "quads"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_start[] = "start"; +static const char __pyx_k_throw[] = "throw"; +static const char __pyx_k_curves[] = "curves"; +static const char __pyx_k_cython[] = "cython"; +static const char __pyx_k_enable[] = "enable"; +static const char __pyx_k_forced[] = "forced"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_main_2[] = "main"; +static const char __pyx_k_p1_2_3[] = "p1_2_3"; +static const char __pyx_k_return[] = "return"; +static const char __pyx_k_splits[] = "splits"; +static const char __pyx_k_typing[] = "typing"; +static const char __pyx_k_disable[] = "disable"; +static const char __pyx_k_genexpr[] = "genexpr"; +static const char __pyx_k_max_err[] = "max_err"; +static const char __pyx_k_reconst[] = "reconst"; +static const char __pyx_k_COMPILED[] = "COMPILED"; +static const char __pyx_k_Solution[] = "Solution"; +static const char __pyx_k_best_sol[] = "best_sol"; +static const char __pyx_k_is_cubic[] = "is_cubic"; +static const char __pyx_k_reversed[] = "reversed"; +static const char __pyx_k_all_cubic[] = "all_cubic"; +static const char __pyx_k_enumerate[] = "enumerate"; +static const char __pyx_k_isenabled[] = "isenabled"; +static const char __pyx_k_tolerance[] = "tolerance"; +static const char __pyx_k_impossible[] = "impossible"; +static const char __pyx_k_is_complex[] = "is_complex"; +static const char __pyx_k_namedtuple[] = "namedtuple"; +static const char __pyx_k_num_points[] = "num_points"; +static const char __pyx_k_quadratics[] = "quadratics"; +static const char __pyx_k_this_count[] = "this_count"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_collections[] = "collections"; +static const char __pyx_k_i_sol_count[] = "i_sol_count"; +static const char __pyx_k_i_sol_error[] = "i_sol_error"; +static const char __pyx_k_j_sol_count[] = "j_sol_count"; +static const char __pyx_k_j_sol_error[] = "j_sol_error"; +static const char __pyx_k_start_index[] = "start_index"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_class_getitem[] = "__class_getitem__"; +static const char __pyx_k_num_offcurves[] = "num_offcurves"; +static const char __pyx_k_reconstructed[] = "reconstructed"; +static const char __pyx_k_AssertionError[] = "AssertionError"; +static const char __pyx_k_AttributeError[] = "AttributeError"; +static const char __pyx_k_Original_curve[] = "Original curve:"; +static const char __pyx_k_fontTools_misc[] = "fontTools.misc"; +static const char __pyx_k_generate_curve[] = "generate_curve"; +static const char __pyx_k_splitCubicAtTC[] = "splitCubicAtTC"; +static const char __pyx_k_this_sol_count[] = "this_sol_count"; +static const char __pyx_k_List_List_Point[] = "List[List[Point]]"; +static const char __pyx_k_fontTools_cu2qu[] = "fontTools.cu2qu"; +static const char __pyx_k_List_Tuple_Point[] = "List[Tuple[Point, ...]]"; +static const char __pyx_k_spline_to_curves[] = "spline_to_curves"; +static const char __pyx_k_ZeroDivisionError[] = "ZeroDivisionError"; +static const char __pyx_k_elevate_quadratic[] = "elevate_quadratic"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_curve_to_quadratic[] = "curve_to_quadratic"; +static const char __pyx_k_reconstructed_iter[] = "reconstructed_iter"; +static const char __pyx_k_elevated_quadratics[] = "elevated_quadratics"; +static const char __pyx_k_quadratic_to_curves[] = "quadratic_to_curves"; +static const char __pyx_k_Reconstructed_curve_s[] = "Reconstructed curve(s):"; +static const char __pyx_k_fontTools_qu2cu_qu2cu[] = "fontTools.qu2cu.qu2cu"; +static const char __pyx_k_reconstruct_tolerance[] = "reconstruct_tolerance"; +static const char __pyx_k_add_implicit_on_curves[] = "add_implicit_on_curves"; +static const char __pyx_k_fontTools_cu2qu_benchmark[] = "fontTools.cu2qu.benchmark"; +static const char __pyx_k_fontTools_misc_bezierTools[] = "fontTools.misc.bezierTools"; +static const char __pyx_k_Lib_fontTools_qu2cu_qu2cu_py[] = "Lib/fontTools/qu2cu/qu2cu.py"; +static const char __pyx_k_spline_to_curves_locals_genexpr[] = "spline_to_curves..genexpr"; +static const char __pyx_k_One_random_cubic_turned_into_d_q[] = "One random cubic turned into %d quadratics."; +static const char __pyx_k_Those_quadratics_turned_back_int[] = "Those quadratics turned back into %d cubics. "; +static const char __pyx_k_cu2qu_tolerance_g_qu2cu_toleranc[] = "cu2qu tolerance %g. qu2cu tolerance %g."; +static const char __pyx_k_quadratic_spline_requires_at_lea[] = "quadratic spline requires at least 3 points"; +static const char __pyx_k_quadratic_to_curves_locals_genex[] = "quadratic_to_curves..genexpr"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_elevate_quadratic(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_2add_implicit_on_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_4quadratic_to_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quads, double __pyx_v_max_err, PyObject *__pyx_v_all_cubic); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_6spline_to_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_q, PyObject *__pyx_v_costs, double __pyx_v_tolerance, int __pyx_v_all_cubic); /* proto */ +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_8main(CYTHON_UNUSED PyObject *__pyx_self); /* proto */ +static PyObject *__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static __Pyx_CachedCFunction __pyx_umethod_PyList_Type_pop = {0, 0, 0, 0, 0}; +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + PyObject *__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr; + PyObject *__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr; + #endif + PyTypeObject *__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr; + PyTypeObject *__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr; + PyObject *__pyx_n_s_AssertionError; + PyObject *__pyx_n_s_AttributeError; + PyObject *__pyx_n_s_COMPILED; + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py; + PyObject *__pyx_n_s_List; + PyObject *__pyx_kp_s_List_List_Point; + PyObject *__pyx_kp_s_List_Tuple_Point; + PyObject *__pyx_kp_u_One_random_cubic_turned_into_d_q; + PyObject *__pyx_kp_u_Original_curve; + PyObject *__pyx_n_s_Point; + PyObject *__pyx_kp_u_Reconstructed_curve_s; + PyObject *__pyx_n_s_Solution; + PyObject *__pyx_n_u_Solution; + PyObject *__pyx_kp_u_Those_quadratics_turned_back_int; + PyObject *__pyx_n_s_Tuple; + PyObject *__pyx_n_s_Union; + PyObject *__pyx_n_s_ZeroDivisionError; + PyObject *__pyx_n_s__15; + PyObject *__pyx_kp_u__3; + PyObject *__pyx_n_s__4; + PyObject *__pyx_n_s_add_implicit_on_curves; + PyObject *__pyx_n_s_all; + PyObject *__pyx_n_s_all_cubic; + PyObject *__pyx_n_s_args; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_best_sol; + PyObject *__pyx_n_s_bool; + PyObject *__pyx_n_s_class_getitem; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_close; + PyObject *__pyx_n_s_collections; + PyObject *__pyx_n_s_cost; + PyObject *__pyx_n_s_costs; + PyObject *__pyx_n_s_count; + PyObject *__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc; + PyObject *__pyx_n_s_cubic; + PyObject *__pyx_n_s_curve; + PyObject *__pyx_n_s_curve_to_quadratic; + PyObject *__pyx_n_s_curves; + PyObject *__pyx_n_s_cython; + PyObject *__pyx_kp_u_disable; + PyObject *__pyx_n_s_elevate_quadratic; + PyObject *__pyx_n_s_elevated_quadratics; + PyObject *__pyx_kp_u_enable; + PyObject *__pyx_n_s_enumerate; + PyObject *__pyx_n_s_err; + PyObject *__pyx_n_s_error; + PyObject *__pyx_n_u_error; + PyObject *__pyx_n_s_float; + PyObject *__pyx_n_s_fontTools_cu2qu; + PyObject *__pyx_n_s_fontTools_cu2qu_benchmark; + PyObject *__pyx_n_s_fontTools_misc; + PyObject *__pyx_n_s_fontTools_misc_bezierTools; + PyObject *__pyx_n_s_fontTools_qu2cu_qu2cu; + PyObject *__pyx_n_s_forced; + PyObject *__pyx_kp_u_gc; + PyObject *__pyx_n_s_generate_curve; + PyObject *__pyx_n_s_genexpr; + PyObject *__pyx_n_s_i; + PyObject *__pyx_n_s_i_sol; + PyObject *__pyx_n_s_i_sol_count; + PyObject *__pyx_n_s_i_sol_error; + PyObject *__pyx_n_s_imag; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_impossible; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_n_s_is_complex; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_n_s_is_cubic; + PyObject *__pyx_n_u_is_cubic; + PyObject *__pyx_kp_u_isenabled; + PyObject *__pyx_n_s_j; + PyObject *__pyx_n_s_j_sol_count; + PyObject *__pyx_n_s_j_sol_error; + PyObject *__pyx_n_s_k; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_u_main; + PyObject *__pyx_n_s_main_2; + PyObject *__pyx_n_s_math; + PyObject *__pyx_n_s_max_err; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_namedtuple; + PyObject *__pyx_n_s_num_offcurves; + PyObject *__pyx_n_s_num_points; + PyObject *__pyx_n_u_num_points; + PyObject *__pyx_n_s_off1; + PyObject *__pyx_n_s_off2; + PyObject *__pyx_n_s_on; + PyObject *__pyx_n_s_orig; + PyObject *__pyx_n_s_p; + PyObject *__pyx_n_s_p0; + PyObject *__pyx_n_s_p1; + PyObject *__pyx_n_s_p1_2_3; + PyObject *__pyx_n_s_p2; + PyObject *__pyx_n_s_p3; + PyObject *__pyx_n_s_pop; + PyObject *__pyx_n_s_print; + PyObject *__pyx_n_s_q; + PyObject *__pyx_n_s_qq; + PyObject *__pyx_kp_u_quadratic_spline_requires_at_lea; + PyObject *__pyx_n_s_quadratic_to_curves; + PyObject *__pyx_n_u_quadratic_to_curves; + PyObject *__pyx_n_s_quadratic_to_curves_locals_genex; + PyObject *__pyx_n_s_quadratics; + PyObject *__pyx_n_s_quads; + PyObject *__pyx_n_s_range; + PyObject *__pyx_n_s_real; + PyObject *__pyx_n_s_reconst; + PyObject *__pyx_n_s_reconstruct_tolerance; + PyObject *__pyx_n_s_reconstructed; + PyObject *__pyx_n_s_reconstructed_iter; + PyObject *__pyx_n_s_return; + PyObject *__pyx_n_s_reversed; + PyObject *__pyx_n_s_send; + PyObject *__pyx_n_s_sols; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_spline_to_curves; + PyObject *__pyx_n_s_spline_to_curves_locals_genexpr; + PyObject *__pyx_n_s_splitCubicAtTC; + PyObject *__pyx_n_s_splits; + PyObject *__pyx_n_s_start; + PyObject *__pyx_n_s_start_index; + PyObject *__pyx_n_u_start_index; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_this_count; + PyObject *__pyx_n_s_this_sol_count; + PyObject *__pyx_n_s_throw; + PyObject *__pyx_n_s_tolerance; + PyObject *__pyx_n_s_ts; + PyObject *__pyx_n_s_typing; + PyObject *__pyx_n_s_u; + PyObject *__pyx_n_s_v; + PyObject *__pyx_n_s_x; + PyObject *__pyx_n_s_y; + PyObject *__pyx_n_s_zip; + PyObject *__pyx_int_0; + PyObject *__pyx_int_1; + PyObject *__pyx_int_3; + PyObject *__pyx_slice_; + PyObject *__pyx_tuple__2; + PyObject *__pyx_tuple__5; + PyObject *__pyx_tuple__7; + PyObject *__pyx_tuple__9; + PyObject *__pyx_tuple__11; + PyObject *__pyx_tuple__13; + PyObject *__pyx_codeobj__6; + PyObject *__pyx_codeobj__8; + PyObject *__pyx_codeobj__10; + PyObject *__pyx_codeobj__12; + PyObject *__pyx_codeobj__14; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_AssertionError); + Py_CLEAR(clear_module_state->__pyx_n_s_AttributeError); + Py_CLEAR(clear_module_state->__pyx_n_s_COMPILED); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py); + Py_CLEAR(clear_module_state->__pyx_n_s_List); + Py_CLEAR(clear_module_state->__pyx_kp_s_List_List_Point); + Py_CLEAR(clear_module_state->__pyx_kp_s_List_Tuple_Point); + Py_CLEAR(clear_module_state->__pyx_kp_u_One_random_cubic_turned_into_d_q); + Py_CLEAR(clear_module_state->__pyx_kp_u_Original_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_Point); + Py_CLEAR(clear_module_state->__pyx_kp_u_Reconstructed_curve_s); + Py_CLEAR(clear_module_state->__pyx_n_s_Solution); + Py_CLEAR(clear_module_state->__pyx_n_u_Solution); + Py_CLEAR(clear_module_state->__pyx_kp_u_Those_quadratics_turned_back_int); + Py_CLEAR(clear_module_state->__pyx_n_s_Tuple); + Py_CLEAR(clear_module_state->__pyx_n_s_Union); + Py_CLEAR(clear_module_state->__pyx_n_s_ZeroDivisionError); + Py_CLEAR(clear_module_state->__pyx_n_s__15); + Py_CLEAR(clear_module_state->__pyx_kp_u__3); + Py_CLEAR(clear_module_state->__pyx_n_s__4); + Py_CLEAR(clear_module_state->__pyx_n_s_add_implicit_on_curves); + Py_CLEAR(clear_module_state->__pyx_n_s_all); + Py_CLEAR(clear_module_state->__pyx_n_s_all_cubic); + Py_CLEAR(clear_module_state->__pyx_n_s_args); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_best_sol); + Py_CLEAR(clear_module_state->__pyx_n_s_bool); + Py_CLEAR(clear_module_state->__pyx_n_s_class_getitem); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_close); + Py_CLEAR(clear_module_state->__pyx_n_s_collections); + Py_CLEAR(clear_module_state->__pyx_n_s_cost); + Py_CLEAR(clear_module_state->__pyx_n_s_costs); + Py_CLEAR(clear_module_state->__pyx_n_s_count); + Py_CLEAR(clear_module_state->__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc); + Py_CLEAR(clear_module_state->__pyx_n_s_cubic); + Py_CLEAR(clear_module_state->__pyx_n_s_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_curve_to_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_curves); + Py_CLEAR(clear_module_state->__pyx_n_s_cython); + Py_CLEAR(clear_module_state->__pyx_kp_u_disable); + Py_CLEAR(clear_module_state->__pyx_n_s_elevate_quadratic); + Py_CLEAR(clear_module_state->__pyx_n_s_elevated_quadratics); + Py_CLEAR(clear_module_state->__pyx_kp_u_enable); + Py_CLEAR(clear_module_state->__pyx_n_s_enumerate); + Py_CLEAR(clear_module_state->__pyx_n_s_err); + Py_CLEAR(clear_module_state->__pyx_n_s_error); + Py_CLEAR(clear_module_state->__pyx_n_u_error); + Py_CLEAR(clear_module_state->__pyx_n_s_float); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_cu2qu); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_cu2qu_benchmark); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_misc_bezierTools); + Py_CLEAR(clear_module_state->__pyx_n_s_fontTools_qu2cu_qu2cu); + Py_CLEAR(clear_module_state->__pyx_n_s_forced); + Py_CLEAR(clear_module_state->__pyx_kp_u_gc); + Py_CLEAR(clear_module_state->__pyx_n_s_generate_curve); + Py_CLEAR(clear_module_state->__pyx_n_s_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_i); + Py_CLEAR(clear_module_state->__pyx_n_s_i_sol); + Py_CLEAR(clear_module_state->__pyx_n_s_i_sol_count); + Py_CLEAR(clear_module_state->__pyx_n_s_i_sol_error); + Py_CLEAR(clear_module_state->__pyx_n_s_imag); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_impossible); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_n_s_is_complex); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_n_s_is_cubic); + Py_CLEAR(clear_module_state->__pyx_n_u_is_cubic); + Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); + Py_CLEAR(clear_module_state->__pyx_n_s_j); + Py_CLEAR(clear_module_state->__pyx_n_s_j_sol_count); + Py_CLEAR(clear_module_state->__pyx_n_s_j_sol_error); + Py_CLEAR(clear_module_state->__pyx_n_s_k); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_u_main); + Py_CLEAR(clear_module_state->__pyx_n_s_main_2); + Py_CLEAR(clear_module_state->__pyx_n_s_math); + Py_CLEAR(clear_module_state->__pyx_n_s_max_err); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_namedtuple); + Py_CLEAR(clear_module_state->__pyx_n_s_num_offcurves); + Py_CLEAR(clear_module_state->__pyx_n_s_num_points); + Py_CLEAR(clear_module_state->__pyx_n_u_num_points); + Py_CLEAR(clear_module_state->__pyx_n_s_off1); + Py_CLEAR(clear_module_state->__pyx_n_s_off2); + Py_CLEAR(clear_module_state->__pyx_n_s_on); + Py_CLEAR(clear_module_state->__pyx_n_s_orig); + Py_CLEAR(clear_module_state->__pyx_n_s_p); + Py_CLEAR(clear_module_state->__pyx_n_s_p0); + Py_CLEAR(clear_module_state->__pyx_n_s_p1); + Py_CLEAR(clear_module_state->__pyx_n_s_p1_2_3); + Py_CLEAR(clear_module_state->__pyx_n_s_p2); + Py_CLEAR(clear_module_state->__pyx_n_s_p3); + Py_CLEAR(clear_module_state->__pyx_n_s_pop); + Py_CLEAR(clear_module_state->__pyx_n_s_print); + Py_CLEAR(clear_module_state->__pyx_n_s_q); + Py_CLEAR(clear_module_state->__pyx_n_s_qq); + Py_CLEAR(clear_module_state->__pyx_kp_u_quadratic_spline_requires_at_lea); + Py_CLEAR(clear_module_state->__pyx_n_s_quadratic_to_curves); + Py_CLEAR(clear_module_state->__pyx_n_u_quadratic_to_curves); + Py_CLEAR(clear_module_state->__pyx_n_s_quadratic_to_curves_locals_genex); + Py_CLEAR(clear_module_state->__pyx_n_s_quadratics); + Py_CLEAR(clear_module_state->__pyx_n_s_quads); + Py_CLEAR(clear_module_state->__pyx_n_s_range); + Py_CLEAR(clear_module_state->__pyx_n_s_real); + Py_CLEAR(clear_module_state->__pyx_n_s_reconst); + Py_CLEAR(clear_module_state->__pyx_n_s_reconstruct_tolerance); + Py_CLEAR(clear_module_state->__pyx_n_s_reconstructed); + Py_CLEAR(clear_module_state->__pyx_n_s_reconstructed_iter); + Py_CLEAR(clear_module_state->__pyx_n_s_return); + Py_CLEAR(clear_module_state->__pyx_n_s_reversed); + Py_CLEAR(clear_module_state->__pyx_n_s_send); + Py_CLEAR(clear_module_state->__pyx_n_s_sols); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_spline_to_curves); + Py_CLEAR(clear_module_state->__pyx_n_s_spline_to_curves_locals_genexpr); + Py_CLEAR(clear_module_state->__pyx_n_s_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_n_s_splits); + Py_CLEAR(clear_module_state->__pyx_n_s_start); + Py_CLEAR(clear_module_state->__pyx_n_s_start_index); + Py_CLEAR(clear_module_state->__pyx_n_u_start_index); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_this_count); + Py_CLEAR(clear_module_state->__pyx_n_s_this_sol_count); + Py_CLEAR(clear_module_state->__pyx_n_s_throw); + Py_CLEAR(clear_module_state->__pyx_n_s_tolerance); + Py_CLEAR(clear_module_state->__pyx_n_s_ts); + Py_CLEAR(clear_module_state->__pyx_n_s_typing); + Py_CLEAR(clear_module_state->__pyx_n_s_u); + Py_CLEAR(clear_module_state->__pyx_n_s_v); + Py_CLEAR(clear_module_state->__pyx_n_s_x); + Py_CLEAR(clear_module_state->__pyx_n_s_y); + Py_CLEAR(clear_module_state->__pyx_n_s_zip); + Py_CLEAR(clear_module_state->__pyx_int_0); + Py_CLEAR(clear_module_state->__pyx_int_1); + Py_CLEAR(clear_module_state->__pyx_int_3); + Py_CLEAR(clear_module_state->__pyx_slice_); + Py_CLEAR(clear_module_state->__pyx_tuple__2); + Py_CLEAR(clear_module_state->__pyx_tuple__5); + Py_CLEAR(clear_module_state->__pyx_tuple__7); + Py_CLEAR(clear_module_state->__pyx_tuple__9); + Py_CLEAR(clear_module_state->__pyx_tuple__11); + Py_CLEAR(clear_module_state->__pyx_tuple__13); + Py_CLEAR(clear_module_state->__pyx_codeobj__6); + Py_CLEAR(clear_module_state->__pyx_codeobj__8); + Py_CLEAR(clear_module_state->__pyx_codeobj__10); + Py_CLEAR(clear_module_state->__pyx_codeobj__12); + Py_CLEAR(clear_module_state->__pyx_codeobj__14); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_AssertionError); + Py_VISIT(traverse_module_state->__pyx_n_s_AttributeError); + Py_VISIT(traverse_module_state->__pyx_n_s_COMPILED); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py); + Py_VISIT(traverse_module_state->__pyx_n_s_List); + Py_VISIT(traverse_module_state->__pyx_kp_s_List_List_Point); + Py_VISIT(traverse_module_state->__pyx_kp_s_List_Tuple_Point); + Py_VISIT(traverse_module_state->__pyx_kp_u_One_random_cubic_turned_into_d_q); + Py_VISIT(traverse_module_state->__pyx_kp_u_Original_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_Point); + Py_VISIT(traverse_module_state->__pyx_kp_u_Reconstructed_curve_s); + Py_VISIT(traverse_module_state->__pyx_n_s_Solution); + Py_VISIT(traverse_module_state->__pyx_n_u_Solution); + Py_VISIT(traverse_module_state->__pyx_kp_u_Those_quadratics_turned_back_int); + Py_VISIT(traverse_module_state->__pyx_n_s_Tuple); + Py_VISIT(traverse_module_state->__pyx_n_s_Union); + Py_VISIT(traverse_module_state->__pyx_n_s_ZeroDivisionError); + Py_VISIT(traverse_module_state->__pyx_n_s__15); + Py_VISIT(traverse_module_state->__pyx_kp_u__3); + Py_VISIT(traverse_module_state->__pyx_n_s__4); + Py_VISIT(traverse_module_state->__pyx_n_s_add_implicit_on_curves); + Py_VISIT(traverse_module_state->__pyx_n_s_all); + Py_VISIT(traverse_module_state->__pyx_n_s_all_cubic); + Py_VISIT(traverse_module_state->__pyx_n_s_args); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_best_sol); + Py_VISIT(traverse_module_state->__pyx_n_s_bool); + Py_VISIT(traverse_module_state->__pyx_n_s_class_getitem); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_close); + Py_VISIT(traverse_module_state->__pyx_n_s_collections); + Py_VISIT(traverse_module_state->__pyx_n_s_cost); + Py_VISIT(traverse_module_state->__pyx_n_s_costs); + Py_VISIT(traverse_module_state->__pyx_n_s_count); + Py_VISIT(traverse_module_state->__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc); + Py_VISIT(traverse_module_state->__pyx_n_s_cubic); + Py_VISIT(traverse_module_state->__pyx_n_s_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_curve_to_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_curves); + Py_VISIT(traverse_module_state->__pyx_n_s_cython); + Py_VISIT(traverse_module_state->__pyx_kp_u_disable); + Py_VISIT(traverse_module_state->__pyx_n_s_elevate_quadratic); + Py_VISIT(traverse_module_state->__pyx_n_s_elevated_quadratics); + Py_VISIT(traverse_module_state->__pyx_kp_u_enable); + Py_VISIT(traverse_module_state->__pyx_n_s_enumerate); + Py_VISIT(traverse_module_state->__pyx_n_s_err); + Py_VISIT(traverse_module_state->__pyx_n_s_error); + Py_VISIT(traverse_module_state->__pyx_n_u_error); + Py_VISIT(traverse_module_state->__pyx_n_s_float); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_cu2qu); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_cu2qu_benchmark); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_misc_bezierTools); + Py_VISIT(traverse_module_state->__pyx_n_s_fontTools_qu2cu_qu2cu); + Py_VISIT(traverse_module_state->__pyx_n_s_forced); + Py_VISIT(traverse_module_state->__pyx_kp_u_gc); + Py_VISIT(traverse_module_state->__pyx_n_s_generate_curve); + Py_VISIT(traverse_module_state->__pyx_n_s_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_i); + Py_VISIT(traverse_module_state->__pyx_n_s_i_sol); + Py_VISIT(traverse_module_state->__pyx_n_s_i_sol_count); + Py_VISIT(traverse_module_state->__pyx_n_s_i_sol_error); + Py_VISIT(traverse_module_state->__pyx_n_s_imag); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_impossible); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_n_s_is_complex); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_n_s_is_cubic); + Py_VISIT(traverse_module_state->__pyx_n_u_is_cubic); + Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); + Py_VISIT(traverse_module_state->__pyx_n_s_j); + Py_VISIT(traverse_module_state->__pyx_n_s_j_sol_count); + Py_VISIT(traverse_module_state->__pyx_n_s_j_sol_error); + Py_VISIT(traverse_module_state->__pyx_n_s_k); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_u_main); + Py_VISIT(traverse_module_state->__pyx_n_s_main_2); + Py_VISIT(traverse_module_state->__pyx_n_s_math); + Py_VISIT(traverse_module_state->__pyx_n_s_max_err); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_namedtuple); + Py_VISIT(traverse_module_state->__pyx_n_s_num_offcurves); + Py_VISIT(traverse_module_state->__pyx_n_s_num_points); + Py_VISIT(traverse_module_state->__pyx_n_u_num_points); + Py_VISIT(traverse_module_state->__pyx_n_s_off1); + Py_VISIT(traverse_module_state->__pyx_n_s_off2); + Py_VISIT(traverse_module_state->__pyx_n_s_on); + Py_VISIT(traverse_module_state->__pyx_n_s_orig); + Py_VISIT(traverse_module_state->__pyx_n_s_p); + Py_VISIT(traverse_module_state->__pyx_n_s_p0); + Py_VISIT(traverse_module_state->__pyx_n_s_p1); + Py_VISIT(traverse_module_state->__pyx_n_s_p1_2_3); + Py_VISIT(traverse_module_state->__pyx_n_s_p2); + Py_VISIT(traverse_module_state->__pyx_n_s_p3); + Py_VISIT(traverse_module_state->__pyx_n_s_pop); + Py_VISIT(traverse_module_state->__pyx_n_s_print); + Py_VISIT(traverse_module_state->__pyx_n_s_q); + Py_VISIT(traverse_module_state->__pyx_n_s_qq); + Py_VISIT(traverse_module_state->__pyx_kp_u_quadratic_spline_requires_at_lea); + Py_VISIT(traverse_module_state->__pyx_n_s_quadratic_to_curves); + Py_VISIT(traverse_module_state->__pyx_n_u_quadratic_to_curves); + Py_VISIT(traverse_module_state->__pyx_n_s_quadratic_to_curves_locals_genex); + Py_VISIT(traverse_module_state->__pyx_n_s_quadratics); + Py_VISIT(traverse_module_state->__pyx_n_s_quads); + Py_VISIT(traverse_module_state->__pyx_n_s_range); + Py_VISIT(traverse_module_state->__pyx_n_s_real); + Py_VISIT(traverse_module_state->__pyx_n_s_reconst); + Py_VISIT(traverse_module_state->__pyx_n_s_reconstruct_tolerance); + Py_VISIT(traverse_module_state->__pyx_n_s_reconstructed); + Py_VISIT(traverse_module_state->__pyx_n_s_reconstructed_iter); + Py_VISIT(traverse_module_state->__pyx_n_s_return); + Py_VISIT(traverse_module_state->__pyx_n_s_reversed); + Py_VISIT(traverse_module_state->__pyx_n_s_send); + Py_VISIT(traverse_module_state->__pyx_n_s_sols); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_spline_to_curves); + Py_VISIT(traverse_module_state->__pyx_n_s_spline_to_curves_locals_genexpr); + Py_VISIT(traverse_module_state->__pyx_n_s_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_n_s_splits); + Py_VISIT(traverse_module_state->__pyx_n_s_start); + Py_VISIT(traverse_module_state->__pyx_n_s_start_index); + Py_VISIT(traverse_module_state->__pyx_n_u_start_index); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_this_count); + Py_VISIT(traverse_module_state->__pyx_n_s_this_sol_count); + Py_VISIT(traverse_module_state->__pyx_n_s_throw); + Py_VISIT(traverse_module_state->__pyx_n_s_tolerance); + Py_VISIT(traverse_module_state->__pyx_n_s_ts); + Py_VISIT(traverse_module_state->__pyx_n_s_typing); + Py_VISIT(traverse_module_state->__pyx_n_s_u); + Py_VISIT(traverse_module_state->__pyx_n_s_v); + Py_VISIT(traverse_module_state->__pyx_n_s_x); + Py_VISIT(traverse_module_state->__pyx_n_s_y); + Py_VISIT(traverse_module_state->__pyx_n_s_zip); + Py_VISIT(traverse_module_state->__pyx_int_0); + Py_VISIT(traverse_module_state->__pyx_int_1); + Py_VISIT(traverse_module_state->__pyx_int_3); + Py_VISIT(traverse_module_state->__pyx_slice_); + Py_VISIT(traverse_module_state->__pyx_tuple__2); + Py_VISIT(traverse_module_state->__pyx_tuple__5); + Py_VISIT(traverse_module_state->__pyx_tuple__7); + Py_VISIT(traverse_module_state->__pyx_tuple__9); + Py_VISIT(traverse_module_state->__pyx_tuple__11); + Py_VISIT(traverse_module_state->__pyx_tuple__13); + Py_VISIT(traverse_module_state->__pyx_codeobj__6); + Py_VISIT(traverse_module_state->__pyx_codeobj__8); + Py_VISIT(traverse_module_state->__pyx_codeobj__10); + Py_VISIT(traverse_module_state->__pyx_codeobj__12); + Py_VISIT(traverse_module_state->__pyx_codeobj__14); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#define __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr __pyx_mstate_global->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr +#define __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr +#endif +#define __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr +#define __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr +#define __pyx_n_s_AssertionError __pyx_mstate_global->__pyx_n_s_AssertionError +#define __pyx_n_s_AttributeError __pyx_mstate_global->__pyx_n_s_AttributeError +#define __pyx_n_s_COMPILED __pyx_mstate_global->__pyx_n_s_COMPILED +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py __pyx_mstate_global->__pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py +#define __pyx_n_s_List __pyx_mstate_global->__pyx_n_s_List +#define __pyx_kp_s_List_List_Point __pyx_mstate_global->__pyx_kp_s_List_List_Point +#define __pyx_kp_s_List_Tuple_Point __pyx_mstate_global->__pyx_kp_s_List_Tuple_Point +#define __pyx_kp_u_One_random_cubic_turned_into_d_q __pyx_mstate_global->__pyx_kp_u_One_random_cubic_turned_into_d_q +#define __pyx_kp_u_Original_curve __pyx_mstate_global->__pyx_kp_u_Original_curve +#define __pyx_n_s_Point __pyx_mstate_global->__pyx_n_s_Point +#define __pyx_kp_u_Reconstructed_curve_s __pyx_mstate_global->__pyx_kp_u_Reconstructed_curve_s +#define __pyx_n_s_Solution __pyx_mstate_global->__pyx_n_s_Solution +#define __pyx_n_u_Solution __pyx_mstate_global->__pyx_n_u_Solution +#define __pyx_kp_u_Those_quadratics_turned_back_int __pyx_mstate_global->__pyx_kp_u_Those_quadratics_turned_back_int +#define __pyx_n_s_Tuple __pyx_mstate_global->__pyx_n_s_Tuple +#define __pyx_n_s_Union __pyx_mstate_global->__pyx_n_s_Union +#define __pyx_n_s_ZeroDivisionError __pyx_mstate_global->__pyx_n_s_ZeroDivisionError +#define __pyx_n_s__15 __pyx_mstate_global->__pyx_n_s__15 +#define __pyx_kp_u__3 __pyx_mstate_global->__pyx_kp_u__3 +#define __pyx_n_s__4 __pyx_mstate_global->__pyx_n_s__4 +#define __pyx_n_s_add_implicit_on_curves __pyx_mstate_global->__pyx_n_s_add_implicit_on_curves +#define __pyx_n_s_all __pyx_mstate_global->__pyx_n_s_all +#define __pyx_n_s_all_cubic __pyx_mstate_global->__pyx_n_s_all_cubic +#define __pyx_n_s_args __pyx_mstate_global->__pyx_n_s_args +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_best_sol __pyx_mstate_global->__pyx_n_s_best_sol +#define __pyx_n_s_bool __pyx_mstate_global->__pyx_n_s_bool +#define __pyx_n_s_class_getitem __pyx_mstate_global->__pyx_n_s_class_getitem +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_close __pyx_mstate_global->__pyx_n_s_close +#define __pyx_n_s_collections __pyx_mstate_global->__pyx_n_s_collections +#define __pyx_n_s_cost __pyx_mstate_global->__pyx_n_s_cost +#define __pyx_n_s_costs __pyx_mstate_global->__pyx_n_s_costs +#define __pyx_n_s_count __pyx_mstate_global->__pyx_n_s_count +#define __pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc __pyx_mstate_global->__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc +#define __pyx_n_s_cubic __pyx_mstate_global->__pyx_n_s_cubic +#define __pyx_n_s_curve __pyx_mstate_global->__pyx_n_s_curve +#define __pyx_n_s_curve_to_quadratic __pyx_mstate_global->__pyx_n_s_curve_to_quadratic +#define __pyx_n_s_curves __pyx_mstate_global->__pyx_n_s_curves +#define __pyx_n_s_cython __pyx_mstate_global->__pyx_n_s_cython +#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable +#define __pyx_n_s_elevate_quadratic __pyx_mstate_global->__pyx_n_s_elevate_quadratic +#define __pyx_n_s_elevated_quadratics __pyx_mstate_global->__pyx_n_s_elevated_quadratics +#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable +#define __pyx_n_s_enumerate __pyx_mstate_global->__pyx_n_s_enumerate +#define __pyx_n_s_err __pyx_mstate_global->__pyx_n_s_err +#define __pyx_n_s_error __pyx_mstate_global->__pyx_n_s_error +#define __pyx_n_u_error __pyx_mstate_global->__pyx_n_u_error +#define __pyx_n_s_float __pyx_mstate_global->__pyx_n_s_float +#define __pyx_n_s_fontTools_cu2qu __pyx_mstate_global->__pyx_n_s_fontTools_cu2qu +#define __pyx_n_s_fontTools_cu2qu_benchmark __pyx_mstate_global->__pyx_n_s_fontTools_cu2qu_benchmark +#define __pyx_n_s_fontTools_misc __pyx_mstate_global->__pyx_n_s_fontTools_misc +#define __pyx_n_s_fontTools_misc_bezierTools __pyx_mstate_global->__pyx_n_s_fontTools_misc_bezierTools +#define __pyx_n_s_fontTools_qu2cu_qu2cu __pyx_mstate_global->__pyx_n_s_fontTools_qu2cu_qu2cu +#define __pyx_n_s_forced __pyx_mstate_global->__pyx_n_s_forced +#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc +#define __pyx_n_s_generate_curve __pyx_mstate_global->__pyx_n_s_generate_curve +#define __pyx_n_s_genexpr __pyx_mstate_global->__pyx_n_s_genexpr +#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i +#define __pyx_n_s_i_sol __pyx_mstate_global->__pyx_n_s_i_sol +#define __pyx_n_s_i_sol_count __pyx_mstate_global->__pyx_n_s_i_sol_count +#define __pyx_n_s_i_sol_error __pyx_mstate_global->__pyx_n_s_i_sol_error +#define __pyx_n_s_imag __pyx_mstate_global->__pyx_n_s_imag +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_impossible __pyx_mstate_global->__pyx_n_s_impossible +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_n_s_is_complex __pyx_mstate_global->__pyx_n_s_is_complex +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_n_s_is_cubic __pyx_mstate_global->__pyx_n_s_is_cubic +#define __pyx_n_u_is_cubic __pyx_mstate_global->__pyx_n_u_is_cubic +#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled +#define __pyx_n_s_j __pyx_mstate_global->__pyx_n_s_j +#define __pyx_n_s_j_sol_count __pyx_mstate_global->__pyx_n_s_j_sol_count +#define __pyx_n_s_j_sol_error __pyx_mstate_global->__pyx_n_s_j_sol_error +#define __pyx_n_s_k __pyx_mstate_global->__pyx_n_s_k +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_u_main __pyx_mstate_global->__pyx_n_u_main +#define __pyx_n_s_main_2 __pyx_mstate_global->__pyx_n_s_main_2 +#define __pyx_n_s_math __pyx_mstate_global->__pyx_n_s_math +#define __pyx_n_s_max_err __pyx_mstate_global->__pyx_n_s_max_err +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_namedtuple __pyx_mstate_global->__pyx_n_s_namedtuple +#define __pyx_n_s_num_offcurves __pyx_mstate_global->__pyx_n_s_num_offcurves +#define __pyx_n_s_num_points __pyx_mstate_global->__pyx_n_s_num_points +#define __pyx_n_u_num_points __pyx_mstate_global->__pyx_n_u_num_points +#define __pyx_n_s_off1 __pyx_mstate_global->__pyx_n_s_off1 +#define __pyx_n_s_off2 __pyx_mstate_global->__pyx_n_s_off2 +#define __pyx_n_s_on __pyx_mstate_global->__pyx_n_s_on +#define __pyx_n_s_orig __pyx_mstate_global->__pyx_n_s_orig +#define __pyx_n_s_p __pyx_mstate_global->__pyx_n_s_p +#define __pyx_n_s_p0 __pyx_mstate_global->__pyx_n_s_p0 +#define __pyx_n_s_p1 __pyx_mstate_global->__pyx_n_s_p1 +#define __pyx_n_s_p1_2_3 __pyx_mstate_global->__pyx_n_s_p1_2_3 +#define __pyx_n_s_p2 __pyx_mstate_global->__pyx_n_s_p2 +#define __pyx_n_s_p3 __pyx_mstate_global->__pyx_n_s_p3 +#define __pyx_n_s_pop __pyx_mstate_global->__pyx_n_s_pop +#define __pyx_n_s_print __pyx_mstate_global->__pyx_n_s_print +#define __pyx_n_s_q __pyx_mstate_global->__pyx_n_s_q +#define __pyx_n_s_qq __pyx_mstate_global->__pyx_n_s_qq +#define __pyx_kp_u_quadratic_spline_requires_at_lea __pyx_mstate_global->__pyx_kp_u_quadratic_spline_requires_at_lea +#define __pyx_n_s_quadratic_to_curves __pyx_mstate_global->__pyx_n_s_quadratic_to_curves +#define __pyx_n_u_quadratic_to_curves __pyx_mstate_global->__pyx_n_u_quadratic_to_curves +#define __pyx_n_s_quadratic_to_curves_locals_genex __pyx_mstate_global->__pyx_n_s_quadratic_to_curves_locals_genex +#define __pyx_n_s_quadratics __pyx_mstate_global->__pyx_n_s_quadratics +#define __pyx_n_s_quads __pyx_mstate_global->__pyx_n_s_quads +#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range +#define __pyx_n_s_real __pyx_mstate_global->__pyx_n_s_real +#define __pyx_n_s_reconst __pyx_mstate_global->__pyx_n_s_reconst +#define __pyx_n_s_reconstruct_tolerance __pyx_mstate_global->__pyx_n_s_reconstruct_tolerance +#define __pyx_n_s_reconstructed __pyx_mstate_global->__pyx_n_s_reconstructed +#define __pyx_n_s_reconstructed_iter __pyx_mstate_global->__pyx_n_s_reconstructed_iter +#define __pyx_n_s_return __pyx_mstate_global->__pyx_n_s_return +#define __pyx_n_s_reversed __pyx_mstate_global->__pyx_n_s_reversed +#define __pyx_n_s_send __pyx_mstate_global->__pyx_n_s_send +#define __pyx_n_s_sols __pyx_mstate_global->__pyx_n_s_sols +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_spline_to_curves __pyx_mstate_global->__pyx_n_s_spline_to_curves +#define __pyx_n_s_spline_to_curves_locals_genexpr __pyx_mstate_global->__pyx_n_s_spline_to_curves_locals_genexpr +#define __pyx_n_s_splitCubicAtTC __pyx_mstate_global->__pyx_n_s_splitCubicAtTC +#define __pyx_n_s_splits __pyx_mstate_global->__pyx_n_s_splits +#define __pyx_n_s_start __pyx_mstate_global->__pyx_n_s_start +#define __pyx_n_s_start_index __pyx_mstate_global->__pyx_n_s_start_index +#define __pyx_n_u_start_index __pyx_mstate_global->__pyx_n_u_start_index +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_this_count __pyx_mstate_global->__pyx_n_s_this_count +#define __pyx_n_s_this_sol_count __pyx_mstate_global->__pyx_n_s_this_sol_count +#define __pyx_n_s_throw __pyx_mstate_global->__pyx_n_s_throw +#define __pyx_n_s_tolerance __pyx_mstate_global->__pyx_n_s_tolerance +#define __pyx_n_s_ts __pyx_mstate_global->__pyx_n_s_ts +#define __pyx_n_s_typing __pyx_mstate_global->__pyx_n_s_typing +#define __pyx_n_s_u __pyx_mstate_global->__pyx_n_s_u +#define __pyx_n_s_v __pyx_mstate_global->__pyx_n_s_v +#define __pyx_n_s_x __pyx_mstate_global->__pyx_n_s_x +#define __pyx_n_s_y __pyx_mstate_global->__pyx_n_s_y +#define __pyx_n_s_zip __pyx_mstate_global->__pyx_n_s_zip +#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0 +#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 +#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3 +#define __pyx_slice_ __pyx_mstate_global->__pyx_slice_ +#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 +#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 +#define __pyx_tuple__7 __pyx_mstate_global->__pyx_tuple__7 +#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 +#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 +#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 +#define __pyx_codeobj__6 __pyx_mstate_global->__pyx_codeobj__6 +#define __pyx_codeobj__8 __pyx_mstate_global->__pyx_codeobj__8 +#define __pyx_codeobj__10 __pyx_mstate_global->__pyx_codeobj__10 +#define __pyx_codeobj__12 __pyx_mstate_global->__pyx_codeobj__12 +#define __pyx_codeobj__14 __pyx_mstate_global->__pyx_codeobj__14 +/* #### Code section: module_code ### */ + +/* "fontTools/qu2cu/qu2cu.py":43 + * + * # Copied from cu2qu + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.returns(cython.int) + * @cython.locals( + */ + +static int __pyx_f_9fontTools_5qu2cu_5qu2cu_cubic_farthest_fit_inside(__pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3, double __pyx_v_tolerance) { + __pyx_t_double_complex __pyx_v_mid; + __pyx_t_double_complex __pyx_v_deriv3; + int __pyx_r; + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + + /* "fontTools/qu2cu/qu2cu.py":72 + * """ + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_2 = (__Pyx_c_abs_double(__pyx_v_p2) <= __pyx_v_tolerance); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__Pyx_c_abs_double(__pyx_v_p1) <= __pyx_v_tolerance); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + if (__pyx_t_1) { + + /* "fontTools/qu2cu/qu2cu.py":73 + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: + * return True # <<<<<<<<<<<<<< + * + * # Split. + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":72 + * """ + * # First check p2 then p1, as p2 has higher error early on. + * if abs(p2) <= tolerance and abs(p1) <= tolerance: # <<<<<<<<<<<<<< + * return True + * + */ + } + + /* "fontTools/qu2cu/qu2cu.py":76 + * + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 # <<<<<<<<<<<<<< + * if abs(mid) > tolerance: + * return False + */ + __pyx_v_mid = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_p0, __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__pyx_v_p1, __pyx_v_p2))), __pyx_v_p3), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/qu2cu/qu2cu.py":77 + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: # <<<<<<<<<<<<<< + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + __pyx_t_1 = (__Pyx_c_abs_double(__pyx_v_mid) > __pyx_v_tolerance); + if (__pyx_t_1) { + + /* "fontTools/qu2cu/qu2cu.py":78 + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: + * return False # <<<<<<<<<<<<<< + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return cubic_farthest_fit_inside( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":77 + * # Split. + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * if abs(mid) > tolerance: # <<<<<<<<<<<<<< + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + */ + } + + /* "fontTools/qu2cu/qu2cu.py":79 + * if abs(mid) > tolerance: + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 # <<<<<<<<<<<<<< + * return cubic_farthest_fit_inside( + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + */ + __pyx_v_deriv3 = __Pyx_c_prod_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__pyx_v_p3, __pyx_v_p2), __pyx_v_p1), __pyx_v_p0), __pyx_t_double_complex_from_parts(0.125, 0)); + + /* "fontTools/qu2cu/qu2cu.py":80 + * return False + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return cubic_farthest_fit_inside( # <<<<<<<<<<<<<< + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + * ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) + */ + __pyx_t_4 = __pyx_f_9fontTools_5qu2cu_5qu2cu_cubic_farthest_fit_inside(__pyx_v_p0, __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p0, __pyx_v_p1), __pyx_t_double_complex_from_parts(0.5, 0)), __Pyx_c_diff_double(__pyx_v_mid, __pyx_v_deriv3), __pyx_v_mid, __pyx_v_tolerance); if (unlikely(__pyx_t_4 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 80, __pyx_L1_error) + if (__pyx_t_4) { + } else { + __pyx_t_3 = __pyx_t_4; + goto __pyx_L7_bool_binop_done; + } + + /* "fontTools/qu2cu/qu2cu.py":82 + * return cubic_farthest_fit_inside( + * p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + * ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_4 = __pyx_f_9fontTools_5qu2cu_5qu2cu_cubic_farthest_fit_inside(__pyx_v_mid, __Pyx_c_sum_double(__pyx_v_mid, __pyx_v_deriv3), __Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_p2, __pyx_v_p3), __pyx_t_double_complex_from_parts(0.5, 0)), __pyx_v_p3, __pyx_v_tolerance); if (unlikely(__pyx_t_4 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 82, __pyx_L1_error) + __pyx_t_3 = __pyx_t_4; + __pyx_L7_bool_binop_done:; + __pyx_r = __pyx_t_3; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":43 + * + * # Copied from cu2qu + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.returns(cython.int) + * @cython.locals( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.cubic_farthest_fit_inside", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":85 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_1elevate_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5qu2cu_5qu2cu_elevate_quadratic, "elevate_quadratic(double complex p0, double complex p1, double complex p2)\nGiven a quadratic bezier curve, return its degree-elevated cubic."); +static PyMethodDef __pyx_mdef_9fontTools_5qu2cu_5qu2cu_1elevate_quadratic = {"elevate_quadratic", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5qu2cu_5qu2cu_1elevate_quadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5qu2cu_5qu2cu_elevate_quadratic}; +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_1elevate_quadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("elevate_quadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_p0,&__pyx_n_s_p1,&__pyx_n_s_p2,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p0)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 85, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p1)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 85, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("elevate_quadratic", 1, 3, 3, 1); __PYX_ERR(0, 85, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p2)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 85, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("elevate_quadratic", 1, 3, 3, 2); __PYX_ERR(0, 85, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "elevate_quadratic") < 0)) __PYX_ERR(0, 85, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v_p0 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 91, __pyx_L3_error) + __pyx_v_p1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 91, __pyx_L3_error) + __pyx_v_p2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 91, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("elevate_quadratic", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 85, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.elevate_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5qu2cu_5qu2cu_elevate_quadratic(__pyx_self, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_elevate_quadratic(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2) { + __pyx_t_double_complex __pyx_v_p1_2_3; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __pyx_t_double_complex __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("elevate_quadratic", 1); + + /* "fontTools/qu2cu/qu2cu.py":95 + * + * # https://pomax.github.io/bezierinfo/#reordering + * p1_2_3 = p1 * (2 / 3) # <<<<<<<<<<<<<< + * return ( + * p0, + */ + __pyx_v_p1_2_3 = __Pyx_c_prod_double(__pyx_v_p1, __pyx_t_double_complex_from_parts((2.0 / 3.0), 0)); + + /* "fontTools/qu2cu/qu2cu.py":96 + * # https://pomax.github.io/bezierinfo/#reordering + * p1_2_3 = p1 * (2 / 3) + * return ( # <<<<<<<<<<<<<< + * p0, + * (p0 * (1 / 3) + p1_2_3), + */ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/qu2cu/qu2cu.py":97 + * p1_2_3 = p1 * (2 / 3) + * return ( + * p0, # <<<<<<<<<<<<<< + * (p0 * (1 / 3) + p1_2_3), + * (p2 * (1 / 3) + p1_2_3), + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/qu2cu/qu2cu.py":98 + * return ( + * p0, + * (p0 * (1 / 3) + p1_2_3), # <<<<<<<<<<<<<< + * (p2 * (1 / 3) + p1_2_3), + * p2, + */ + __pyx_t_2 = __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_v_p0, __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_p1_2_3); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/qu2cu/qu2cu.py":99 + * p0, + * (p0 * (1 / 3) + p1_2_3), + * (p2 * (1 / 3) + p1_2_3), # <<<<<<<<<<<<<< + * p2, + * ) + */ + __pyx_t_2 = __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_v_p2, __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_p1_2_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/qu2cu/qu2cu.py":100 + * (p0 * (1 / 3) + p1_2_3), + * (p2 * (1 / 3) + p1_2_3), + * p2, # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "fontTools/qu2cu/qu2cu.py":97 + * p1_2_3 = p1 * (2 / 3) + * return ( + * p0, # <<<<<<<<<<<<<< + * (p0 * (1 / 3) + p1_2_3), + * (p2 * (1 / 3) + p1_2_3), + */ + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_3)) __PYX_ERR(0, 97, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_4)) __PYX_ERR(0, 97, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5)) __PYX_ERR(0, 97, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":85 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.elevate_quadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":104 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.locals( + * start=cython.int, + */ + +static PyObject *__pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(PyObject *__pyx_v_curves, int __pyx_v_start, int __pyx_v_n) { + int __pyx_v_k; + double __pyx_v_prod_ratio; + double __pyx_v_sum_ratio; + double __pyx_v_ratio; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + PyObject *__pyx_v_ts = NULL; + PyObject *__pyx_v_ck = NULL; + PyObject *__pyx_v_c_before = NULL; + PyObject *__pyx_v_curve = NULL; + double __pyx_7genexpr__pyx_v_t; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + long __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + double __pyx_t_11; + int __pyx_t_12; + Py_ssize_t __pyx_t_13; + __pyx_t_double_complex __pyx_t_14; + PyObject *__pyx_t_15 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("merge_curves", 1); + + /* "fontTools/qu2cu/qu2cu.py":124 + * + * # Reconstruct the t values of the cut segments + * prod_ratio = 1.0 # <<<<<<<<<<<<<< + * sum_ratio = 1.0 + * ts = [1] + */ + __pyx_v_prod_ratio = 1.0; + + /* "fontTools/qu2cu/qu2cu.py":125 + * # Reconstruct the t values of the cut segments + * prod_ratio = 1.0 + * sum_ratio = 1.0 # <<<<<<<<<<<<<< + * ts = [1] + * for k in range(1, n): + */ + __pyx_v_sum_ratio = 1.0; + + /* "fontTools/qu2cu/qu2cu.py":126 + * prod_ratio = 1.0 + * sum_ratio = 1.0 + * ts = [1] # <<<<<<<<<<<<<< + * for k in range(1, n): + * ck = curves[start + k] + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_int_1); + __Pyx_GIVEREF(__pyx_int_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_1)) __PYX_ERR(0, 126, __pyx_L1_error); + __pyx_v_ts = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":127 + * sum_ratio = 1.0 + * ts = [1] + * for k in range(1, n): # <<<<<<<<<<<<<< + * ck = curves[start + k] + * c_before = curves[start + k - 1] + */ + __pyx_t_2 = __pyx_v_n; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 1; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_k = __pyx_t_4; + + /* "fontTools/qu2cu/qu2cu.py":128 + * ts = [1] + * for k in range(1, n): + * ck = curves[start + k] # <<<<<<<<<<<<<< + * c_before = curves[start + k - 1] + * + */ + __pyx_t_5 = (__pyx_v_start + __pyx_v_k); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_t_5, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 128, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_ck, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":129 + * for k in range(1, n): + * ck = curves[start + k] + * c_before = curves[start + k - 1] # <<<<<<<<<<<<<< + * + * # |t_(k+1) - t_k| / |t_k - t_(k - 1)| = ratio + */ + __pyx_t_6 = ((__pyx_v_start + __pyx_v_k) - 1); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_t_6, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_c_before, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":132 + * + * # |t_(k+1) - t_k| / |t_k - t_(k - 1)| = ratio + * assert ck[0] == c_before[3] # <<<<<<<<<<<<<< + * ratio = abs(ck[1] - ck[0]) / abs(c_before[3] - c_before[2]) + * + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_ck, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_c_before, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = PyObject_RichCompare(__pyx_t_1, __pyx_t_7, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_9)) { + __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); + __PYX_ERR(0, 132, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(0, 132, __pyx_L1_error) + #endif + + /* "fontTools/qu2cu/qu2cu.py":133 + * # |t_(k+1) - t_k| / |t_k - t_(k - 1)| = ratio + * assert ck[0] == c_before[3] + * ratio = abs(ck[1] - ck[0]) / abs(c_before[3] - c_before[2]) # <<<<<<<<<<<<<< + * + * prod_ratio *= ratio + */ + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_ck, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_ck, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyNumber_Absolute(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_c_before, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_c_before, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_10 = PyNumber_Subtract(__pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyNumber_Absolute(__pyx_t_10); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyNumber_Divide(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_10); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_v_ratio = __pyx_t_11; + + /* "fontTools/qu2cu/qu2cu.py":135 + * ratio = abs(ck[1] - ck[0]) / abs(c_before[3] - c_before[2]) + * + * prod_ratio *= ratio # <<<<<<<<<<<<<< + * sum_ratio += prod_ratio + * ts.append(sum_ratio) + */ + __pyx_v_prod_ratio = (__pyx_v_prod_ratio * __pyx_v_ratio); + + /* "fontTools/qu2cu/qu2cu.py":136 + * + * prod_ratio *= ratio + * sum_ratio += prod_ratio # <<<<<<<<<<<<<< + * ts.append(sum_ratio) + * + */ + __pyx_v_sum_ratio = (__pyx_v_sum_ratio + __pyx_v_prod_ratio); + + /* "fontTools/qu2cu/qu2cu.py":137 + * prod_ratio *= ratio + * sum_ratio += prod_ratio + * ts.append(sum_ratio) # <<<<<<<<<<<<<< + * + * # (t(n) - t(n - 1)) / (t_(1) - t(0)) = prod_ratio + */ + __pyx_t_10 = PyFloat_FromDouble(__pyx_v_sum_ratio); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_12 = __Pyx_PyList_Append(__pyx_v_ts, __pyx_t_10); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + } + + /* "fontTools/qu2cu/qu2cu.py":141 + * # (t(n) - t(n - 1)) / (t_(1) - t(0)) = prod_ratio + * + * ts = [t / sum_ratio for t in ts[:-1]] # <<<<<<<<<<<<<< + * + * p0 = curves[start][0] + */ + { /* enter inner scope */ + __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_8 = __Pyx_PyList_GetSlice(__pyx_v_ts, 0, -1L); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __pyx_t_8; __Pyx_INCREF(__pyx_t_7); + __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_7); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 141, __pyx_L1_error) + #endif + if (__pyx_t_13 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_8 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_13); __Pyx_INCREF(__pyx_t_8); __pyx_t_13++; if (unlikely((0 < 0))) __PYX_ERR(0, 141, __pyx_L1_error) + #else + __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_7, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_8); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_7genexpr__pyx_v_t = __pyx_t_11; + if (unlikely(__pyx_v_sum_ratio == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 141, __pyx_L1_error) + } + __pyx_t_8 = PyFloat_FromDouble((__pyx_7genexpr__pyx_v_t / __pyx_v_sum_ratio)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (unlikely(__Pyx_ListComp_Append(__pyx_t_10, (PyObject*)__pyx_t_8))) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } /* exit inner scope */ + __Pyx_DECREF_SET(__pyx_v_ts, ((PyObject*)__pyx_t_10)); + __pyx_t_10 = 0; + + /* "fontTools/qu2cu/qu2cu.py":143 + * ts = [t / sum_ratio for t in ts[:-1]] + * + * p0 = curves[start][0] # <<<<<<<<<<<<<< + * p1 = curves[start][1] + * p2 = curves[start + n - 1][2] + */ + __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_v_start, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_10, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_p0 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":144 + * + * p0 = curves[start][0] + * p1 = curves[start][1] # <<<<<<<<<<<<<< + * p2 = curves[start + n - 1][2] + * p3 = curves[start + n - 1][3] + */ + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_v_start, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_7, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_v_p1 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":145 + * p0 = curves[start][0] + * p1 = curves[start][1] + * p2 = curves[start + n - 1][2] # <<<<<<<<<<<<<< + * p3 = curves[start + n - 1][3] + * + */ + __pyx_t_6 = ((__pyx_v_start + __pyx_v_n) - 1); + __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_t_6, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_10, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_p2 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":146 + * p1 = curves[start][1] + * p2 = curves[start + n - 1][2] + * p3 = curves[start + n - 1][3] # <<<<<<<<<<<<<< + * + * # Build the curve by scaling the control-points. + */ + __pyx_t_6 = ((__pyx_v_start + __pyx_v_n) - 1); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_curves, __pyx_t_6, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_7, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_v_p3 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":149 + * + * # Build the curve by scaling the control-points. + * p1 = p0 + (p1 - p0) / (ts[0] if ts else 1) # <<<<<<<<<<<<<< + * p2 = p3 + (p2 - p3) / ((1 - ts[-1]) if ts else 1) + * + */ + __pyx_t_10 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_14 = __Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p0); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_t_14); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = (PyList_GET_SIZE(__pyx_v_ts) != 0); + if (__pyx_t_9) { + __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_ts, 0, long, 1, __Pyx_PyInt_From_long, 1, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __pyx_t_1; + __pyx_t_1 = 0; + } else { + __Pyx_INCREF(__pyx_int_1); + __pyx_t_8 = __pyx_int_1; + } + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Add(__pyx_t_10, __pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_8); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_p1 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":150 + * # Build the curve by scaling the control-points. + * p1 = p0 + (p1 - p0) / (ts[0] if ts else 1) + * p2 = p3 + (p2 - p3) / ((1 - ts[-1]) if ts else 1) # <<<<<<<<<<<<<< + * + * curve = (p0, p1, p2, p3) + */ + __pyx_t_8 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_14 = __Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p3); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_t_14); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = (PyList_GET_SIZE(__pyx_v_ts) != 0); + if (__pyx_t_9) { + __pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_ts, -1L, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_15 = __Pyx_PyInt_SubtractCObj(__pyx_int_1, __pyx_t_7, 1, 0, 0); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_10 = __pyx_t_15; + __pyx_t_15 = 0; + } else { + __Pyx_INCREF(__pyx_int_1); + __pyx_t_10 = __pyx_int_1; + } + __pyx_t_15 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_10); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = PyNumber_Add(__pyx_t_8, __pyx_t_15); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + __pyx_t_14 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_v_p2 = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":152 + * p2 = p3 + (p2 - p3) / ((1 - ts[-1]) if ts else 1) + * + * curve = (p0, p1, p2, p3) # <<<<<<<<<<<<<< + * + * return curve, ts + */ + __pyx_t_10 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_15 = __pyx_PyComplex_FromComplex(__pyx_v_p1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __pyx_t_8 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10)) __PYX_ERR(0, 152, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_15); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_15)) __PYX_ERR(0, 152, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_8)) __PYX_ERR(0, 152, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_t_1)) __PYX_ERR(0, 152, __pyx_L1_error); + __pyx_t_10 = 0; + __pyx_t_15 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = 0; + __pyx_v_curve = __pyx_t_7; + __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":154 + * curve = (p0, p1, p2, p3) + * + * return curve, ts # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 154, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_v_curve); + __Pyx_GIVEREF(__pyx_v_curve); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_curve)) __PYX_ERR(0, 154, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ts); + __Pyx_GIVEREF(__pyx_v_ts); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_ts)) __PYX_ERR(0, 154, __pyx_L1_error); + __pyx_r = __pyx_t_7; + __pyx_t_7 = 0; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":104 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.locals( + * start=cython.int, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.merge_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_ck); + __Pyx_XDECREF(__pyx_v_c_before); + __Pyx_XDECREF(__pyx_v_curve); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":157 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * count=cython.int, + * num_offcurves=cython.int, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_3add_implicit_on_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5qu2cu_5qu2cu_2add_implicit_on_curves, "add_implicit_on_curves(p)"); +static PyMethodDef __pyx_mdef_9fontTools_5qu2cu_5qu2cu_3add_implicit_on_curves = {"add_implicit_on_curves", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5qu2cu_5qu2cu_3add_implicit_on_curves, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5qu2cu_5qu2cu_2add_implicit_on_curves}; +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_3add_implicit_on_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_p = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("add_implicit_on_curves (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_p,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_p)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "add_implicit_on_curves") < 0)) __PYX_ERR(0, 157, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v_p = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("add_implicit_on_curves", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 157, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.add_implicit_on_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5qu2cu_5qu2cu_2add_implicit_on_curves(__pyx_self, __pyx_v_p); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_2add_implicit_on_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p) { + int __pyx_v_count; + int __pyx_v_num_offcurves; + int __pyx_v_i; + __pyx_t_double_complex __pyx_v_off1; + __pyx_t_double_complex __pyx_v_off2; + __pyx_t_double_complex __pyx_v_on; + PyObject *__pyx_v_q = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + __pyx_t_double_complex __pyx_t_6; + long __pyx_t_7; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("add_implicit_on_curves", 1); + + /* "fontTools/qu2cu/qu2cu.py":166 + * ) + * def add_implicit_on_curves(p): + * q = list(p) # <<<<<<<<<<<<<< + * count = 0 + * num_offcurves = len(p) - 2 + */ + __pyx_t_1 = PySequence_List(__pyx_v_p); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 166, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_q = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":167 + * def add_implicit_on_curves(p): + * q = list(p) + * count = 0 # <<<<<<<<<<<<<< + * num_offcurves = len(p) - 2 + * for i in range(1, num_offcurves): + */ + __pyx_v_count = 0; + + /* "fontTools/qu2cu/qu2cu.py":168 + * q = list(p) + * count = 0 + * num_offcurves = len(p) - 2 # <<<<<<<<<<<<<< + * for i in range(1, num_offcurves): + * off1 = p[i] + */ + __pyx_t_2 = PyObject_Length(__pyx_v_p); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 168, __pyx_L1_error) + __pyx_v_num_offcurves = (__pyx_t_2 - 2); + + /* "fontTools/qu2cu/qu2cu.py":169 + * count = 0 + * num_offcurves = len(p) - 2 + * for i in range(1, num_offcurves): # <<<<<<<<<<<<<< + * off1 = p[i] + * off2 = p[i + 1] + */ + __pyx_t_3 = __pyx_v_num_offcurves; + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_5 = 1; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "fontTools/qu2cu/qu2cu.py":170 + * num_offcurves = len(p) - 2 + * for i in range(1, num_offcurves): + * off1 = p[i] # <<<<<<<<<<<<<< + * off2 = p[i + 1] + * on = off1 + (off2 - off1) * 0.5 + */ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_p, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 170, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 170, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_off1 = __pyx_t_6; + + /* "fontTools/qu2cu/qu2cu.py":171 + * for i in range(1, num_offcurves): + * off1 = p[i] + * off2 = p[i + 1] # <<<<<<<<<<<<<< + * on = off1 + (off2 - off1) * 0.5 + * q.insert(i + 1 + count, on) + */ + __pyx_t_7 = (__pyx_v_i + 1); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_p, __pyx_t_7, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 171, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_off2 = __pyx_t_6; + + /* "fontTools/qu2cu/qu2cu.py":172 + * off1 = p[i] + * off2 = p[i + 1] + * on = off1 + (off2 - off1) * 0.5 # <<<<<<<<<<<<<< + * q.insert(i + 1 + count, on) + * count += 1 + */ + __pyx_v_on = __Pyx_c_sum_double(__pyx_v_off1, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_off2, __pyx_v_off1), __pyx_t_double_complex_from_parts(0.5, 0))); + + /* "fontTools/qu2cu/qu2cu.py":173 + * off2 = p[i + 1] + * on = off1 + (off2 - off1) * 0.5 + * q.insert(i + 1 + count, on) # <<<<<<<<<<<<<< + * count += 1 + * return q + */ + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_on); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = PyList_Insert(__pyx_v_q, ((__pyx_v_i + 1) + __pyx_v_count), __pyx_t_1); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":174 + * on = off1 + (off2 - off1) * 0.5 + * q.insert(i + 1 + count, on) + * count += 1 # <<<<<<<<<<<<<< + * return q + * + */ + __pyx_v_count = (__pyx_v_count + 1); + } + + /* "fontTools/qu2cu/qu2cu.py":175 + * q.insert(i + 1 + count, on) + * count += 1 + * return q # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_q); + __pyx_r = __pyx_v_q; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":157 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * count=cython.int, + * num_offcurves=cython.int, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.add_implicit_on_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_q); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_5quadratic_to_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5qu2cu_5qu2cu_4quadratic_to_curves, "quadratic_to_curves(list quads: List[List[Point]], double max_err: float = 0.5, all_cubic: bool = False) -> List[Tuple[Point, ...]]\nConverts a connecting list of quadratic splines to a list of quadratic\n and cubic curves.\n\n A quadratic spline is specified as a list of points. Either each point is\n a 2-tuple of X,Y coordinates, or each point is a complex number with\n real/imaginary components representing X,Y coordinates.\n\n The first and last points are on-curve points and the rest are off-curve\n points, with an implied on-curve point in the middle between every two\n consequtive off-curve points.\n\n Returns:\n The output is a list of tuples of points. Points are represented\n in the same format as the input, either as 2-tuples or complex numbers.\n\n Each tuple is either of length three, for a quadratic curve, or four,\n for a cubic curve. Each curve's last point is the same as the next\n curve's first point.\n\n Args:\n quads: quadratic splines\n\n max_err: absolute error tolerance; defaults to 0.5\n\n all_cubic: if True, only cubic curves are generated; defaults to False\n "); +static PyMethodDef __pyx_mdef_9fontTools_5qu2cu_5qu2cu_5quadratic_to_curves = {"quadratic_to_curves", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5qu2cu_5qu2cu_5quadratic_to_curves, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5qu2cu_5qu2cu_4quadratic_to_curves}; +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_5quadratic_to_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_quads = 0; + double __pyx_v_max_err; + PyObject *__pyx_v_all_cubic = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("quadratic_to_curves (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_quads,&__pyx_n_s_max_err,&__pyx_n_s_all_cubic,0}; + + /* "fontTools/qu2cu/qu2cu.py":188 + * quads: List[List[Point]], + * max_err: float = 0.5, + * all_cubic: bool = False, # <<<<<<<<<<<<<< + * ) -> List[Tuple[Point, ...]]: + * """Converts a connecting list of quadratic splines to a list of quadratic + */ + values[2] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)((PyObject *)Py_False))); + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_quads)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_err); + if (value) { values[1] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_all_cubic); + if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "quadratic_to_curves") < 0)) __PYX_ERR(0, 181, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_quads = ((PyObject*)values[0]); + if (values[1]) { + __pyx_v_max_err = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_max_err == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 187, __pyx_L3_error) + } else { + __pyx_v_max_err = ((double)((double)0.5)); + } + __pyx_v_all_cubic = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("quadratic_to_curves", 0, 1, 3, __pyx_nargs); __PYX_ERR(0, 181, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.quadratic_to_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_quads), (&PyList_Type), 0, "quads", 1))) __PYX_ERR(0, 186, __pyx_L1_error) + __pyx_r = __pyx_pf_9fontTools_5qu2cu_5qu2cu_4quadratic_to_curves(__pyx_self, __pyx_v_quads, __pyx_v_max_err, __pyx_v_all_cubic); + + /* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/qu2cu/qu2cu.py":238 + * + * if not is_complex: + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] # <<<<<<<<<<<<<< + * return curves + * + */ + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr(__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 238, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_quadratic_to_curves_locals_genex, __pyx_n_s_fontTools_qu2cu_qu2cu); if (unlikely(!gen)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.quadratic_to_curves.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L6_resume_from_yield; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 238, __pyx_L1_error) + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 238, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 238, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 238, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 238, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 238, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 238, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_c); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_c, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_c, __pyx_n_s_real); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_c, __pyx_n_s_imag); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5)) __PYX_ERR(0, 238, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + __Pyx_XGIVEREF(__pyx_t_1); + __pyx_cur_scope->__pyx_t_0 = __pyx_t_1; + __pyx_cur_scope->__pyx_t_1 = __pyx_t_2; + __pyx_cur_scope->__pyx_t_2 = __pyx_t_3; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L6_resume_from_yield:; + __pyx_t_1 = __pyx_cur_scope->__pyx_t_0; + __pyx_cur_scope->__pyx_t_0 = 0; + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_cur_scope->__pyx_t_1; + __pyx_t_3 = __pyx_cur_scope->__pyx_t_2; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 238, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + PyErr_SetNone(PyExc_StopIteration); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_4quadratic_to_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_quads, double __pyx_v_max_err, PyObject *__pyx_v_all_cubic) { + int __pyx_v_cost; + int __pyx_v_is_complex; + PyObject *__pyx_v_q = NULL; + PyObject *__pyx_v_costs = NULL; + PyObject *__pyx_v_p = NULL; + CYTHON_UNUSED Py_ssize_t __pyx_v_i; + PyObject *__pyx_v_qq = NULL; + PyObject *__pyx_v_curves = NULL; + PyObject *__pyx_8genexpr1__pyx_v_p = NULL; + PyObject *__pyx_8genexpr2__pyx_v_x = NULL; + PyObject *__pyx_8genexpr2__pyx_v_y = NULL; + PyObject *__pyx_8genexpr3__pyx_v_curve = NULL; + PyObject *__pyx_8genexpr3__pyx_v_0 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + Py_ssize_t __pyx_t_7; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *(*__pyx_t_13)(PyObject *); + Py_ssize_t __pyx_t_14; + Py_ssize_t __pyx_t_15; + int __pyx_t_16; + int __pyx_t_17; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("quadratic_to_curves", 0); + __Pyx_INCREF(__pyx_v_quads); + + /* "fontTools/qu2cu/qu2cu.py":216 + * all_cubic: if True, only cubic curves are generated; defaults to False + * """ + * is_complex = type(quads[0][0]) is complex # <<<<<<<<<<<<<< + * if not is_complex: + * quads = [[complex(x, y) for (x, y) in p] for p in quads] + */ + __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_quads, 0, long, 1, __Pyx_PyInt_From_long, 1, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_3 = (((PyObject *)Py_TYPE(__pyx_t_2)) == ((PyObject *)(&PyComplex_Type))); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_is_complex = __pyx_t_3; + + /* "fontTools/qu2cu/qu2cu.py":217 + * """ + * is_complex = type(quads[0][0]) is complex + * if not is_complex: # <<<<<<<<<<<<<< + * quads = [[complex(x, y) for (x, y) in p] for p in quads] + * + */ + __pyx_t_3 = (!(__pyx_v_is_complex != 0)); + if (__pyx_t_3) { + + /* "fontTools/qu2cu/qu2cu.py":218 + * is_complex = type(quads[0][0]) is complex + * if not is_complex: + * quads = [[complex(x, y) for (x, y) in p] for p in quads] # <<<<<<<<<<<<<< + * + * q = [quads[0][0]] + */ + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 218, __pyx_L6_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __pyx_v_quads; __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 218, __pyx_L6_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_5); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 218, __pyx_L6_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 218, __pyx_L6_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_p, __pyx_t_5); + __pyx_t_5 = 0; + { /* enter inner scope */ + __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_5); + if (likely(PyList_CheckExact(__pyx_8genexpr1__pyx_v_p)) || PyTuple_CheckExact(__pyx_8genexpr1__pyx_v_p)) { + __pyx_t_6 = __pyx_8genexpr1__pyx_v_p; __Pyx_INCREF(__pyx_t_6); + __pyx_t_7 = 0; + __pyx_t_8 = NULL; + } else { + __pyx_t_7 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_8genexpr1__pyx_v_p); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 218, __pyx_L11_error) + } + for (;;) { + if (likely(!__pyx_t_8)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 218, __pyx_L11_error) + #endif + if (__pyx_t_7 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_9 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 218, __pyx_L11_error) + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 218, __pyx_L11_error) + #endif + if (__pyx_t_7 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 218, __pyx_L11_error) + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + } + } else { + __pyx_t_9 = __pyx_t_8(__pyx_t_6); + if (unlikely(!__pyx_t_9)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 218, __pyx_L11_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_9); + } + if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) { + PyObject* sequence = __pyx_t_9; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 218, __pyx_L11_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_10 = PyList_GET_ITEM(sequence, 0); + __pyx_t_11 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_11); + #else + __pyx_t_10 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_11); + #endif + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_12 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_13 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_12); + index = 0; __pyx_t_10 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_10)) goto __pyx_L14_unpacking_failed; + __Pyx_GOTREF(__pyx_t_10); + index = 1; __pyx_t_11 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_11)) goto __pyx_L14_unpacking_failed; + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 2) < 0) __PYX_ERR(0, 218, __pyx_L11_error) + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L15_unpacking_done; + __pyx_L14_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 218, __pyx_L11_error) + __pyx_L15_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_x, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_y, __pyx_t_11); + __pyx_t_11 = 0; + __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_8genexpr2__pyx_v_x); + __Pyx_GIVEREF(__pyx_8genexpr2__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_8genexpr2__pyx_v_x)) __PYX_ERR(0, 218, __pyx_L11_error); + __Pyx_INCREF(__pyx_8genexpr2__pyx_v_y); + __Pyx_GIVEREF(__pyx_8genexpr2__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_8genexpr2__pyx_v_y)) __PYX_ERR(0, 218, __pyx_L11_error); + __pyx_t_11 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_9, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_11))) __PYX_ERR(0, 218, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_x); __pyx_8genexpr2__pyx_v_x = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_y); __pyx_8genexpr2__pyx_v_y = 0; + goto __pyx_L17_exit_scope; + __pyx_L11_error:; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_x); __pyx_8genexpr2__pyx_v_x = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_y); __pyx_8genexpr2__pyx_v_y = 0; + goto __pyx_L6_error; + __pyx_L17_exit_scope:; + } /* exit inner scope */ + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 218, __pyx_L6_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_p); __pyx_8genexpr1__pyx_v_p = 0; + goto __pyx_L19_exit_scope; + __pyx_L6_error:; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_p); __pyx_8genexpr1__pyx_v_p = 0; + goto __pyx_L1_error; + __pyx_L19_exit_scope:; + } /* exit inner scope */ + __Pyx_DECREF_SET(__pyx_v_quads, ((PyObject*)__pyx_t_2)); + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":217 + * """ + * is_complex = type(quads[0][0]) is complex + * if not is_complex: # <<<<<<<<<<<<<< + * quads = [[complex(x, y) for (x, y) in p] for p in quads] + * + */ + } + + /* "fontTools/qu2cu/qu2cu.py":220 + * quads = [[complex(x, y) for (x, y) in p] for p in quads] + * + * q = [quads[0][0]] # <<<<<<<<<<<<<< + * costs = [1] + * cost = 1 + */ + __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_quads, 0, long, 1, __Pyx_PyInt_From_long, 1, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_v_q = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":221 + * + * q = [quads[0][0]] + * costs = [1] # <<<<<<<<<<<<<< + * cost = 1 + * for p in quads: + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_int_1); + __Pyx_GIVEREF(__pyx_int_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_int_1)) __PYX_ERR(0, 221, __pyx_L1_error); + __pyx_v_costs = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":222 + * q = [quads[0][0]] + * costs = [1] + * cost = 1 # <<<<<<<<<<<<<< + * for p in quads: + * assert q[-1] == p[0] + */ + __pyx_v_cost = 1; + + /* "fontTools/qu2cu/qu2cu.py":223 + * costs = [1] + * cost = 1 + * for p in quads: # <<<<<<<<<<<<<< + * assert q[-1] == p[0] + * for i in range(len(p) - 2): + */ + __pyx_t_2 = __pyx_v_quads; __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 223, __pyx_L1_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 223, __pyx_L1_error) + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + __Pyx_XDECREF_SET(__pyx_v_p, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":224 + * cost = 1 + * for p in quads: + * assert q[-1] == p[0] # <<<<<<<<<<<<<< + * for i in range(len(p) - 2): + * cost += 1 + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_q, -1L, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_p, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) { + __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); + __PYX_ERR(0, 224, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(0, 224, __pyx_L1_error) + #endif + + /* "fontTools/qu2cu/qu2cu.py":225 + * for p in quads: + * assert q[-1] == p[0] + * for i in range(len(p) - 2): # <<<<<<<<<<<<<< + * cost += 1 + * costs.append(cost) + */ + __pyx_t_7 = PyObject_Length(__pyx_v_p); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 225, __pyx_L1_error) + __pyx_t_14 = (__pyx_t_7 - 2); + __pyx_t_7 = __pyx_t_14; + for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_7; __pyx_t_15+=1) { + __pyx_v_i = __pyx_t_15; + + /* "fontTools/qu2cu/qu2cu.py":226 + * assert q[-1] == p[0] + * for i in range(len(p) - 2): + * cost += 1 # <<<<<<<<<<<<<< + * costs.append(cost) + * costs.append(cost) + */ + __pyx_v_cost = (__pyx_v_cost + 1); + + /* "fontTools/qu2cu/qu2cu.py":227 + * for i in range(len(p) - 2): + * cost += 1 + * costs.append(cost) # <<<<<<<<<<<<<< + * costs.append(cost) + * qq = add_implicit_on_curves(p)[1:] + */ + __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_cost); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 227, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_costs, __pyx_t_6); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 227, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":228 + * cost += 1 + * costs.append(cost) + * costs.append(cost) # <<<<<<<<<<<<<< + * qq = add_implicit_on_curves(p)[1:] + * costs.pop() + */ + __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_cost); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_costs, __pyx_t_6); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + + /* "fontTools/qu2cu/qu2cu.py":229 + * costs.append(cost) + * costs.append(cost) + * qq = add_implicit_on_curves(p)[1:] # <<<<<<<<<<<<<< + * costs.pop() + * q.extend(qq) + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_add_implicit_on_curves); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = NULL; + __pyx_t_17 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_17 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_p}; + __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_17, 1+__pyx_t_17); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_t_5 = __Pyx_PyObject_GetSlice(__pyx_t_6, 1, 0, NULL, NULL, &__pyx_slice_, 1, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF_SET(__pyx_v_qq, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/qu2cu/qu2cu.py":230 + * costs.append(cost) + * qq = add_implicit_on_curves(p)[1:] + * costs.pop() # <<<<<<<<<<<<<< + * q.extend(qq) + * cost += 1 + */ + __pyx_t_5 = __Pyx_PyList_Pop(__pyx_v_costs); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/qu2cu/qu2cu.py":231 + * qq = add_implicit_on_curves(p)[1:] + * costs.pop() + * q.extend(qq) # <<<<<<<<<<<<<< + * cost += 1 + * costs.append(cost) + */ + __pyx_t_16 = __Pyx_PyList_Extend(__pyx_v_q, __pyx_v_qq); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 231, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":232 + * costs.pop() + * q.extend(qq) + * cost += 1 # <<<<<<<<<<<<<< + * costs.append(cost) + * + */ + __pyx_v_cost = (__pyx_v_cost + 1); + + /* "fontTools/qu2cu/qu2cu.py":233 + * q.extend(qq) + * cost += 1 + * costs.append(cost) # <<<<<<<<<<<<<< + * + * curves = spline_to_curves(q, costs, max_err, all_cubic) + */ + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_cost); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_costs, __pyx_t_5); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 233, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/qu2cu/qu2cu.py":223 + * costs = [1] + * cost = 1 + * for p in quads: # <<<<<<<<<<<<<< + * assert q[-1] == p[0] + * for i in range(len(p) - 2): + */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":235 + * costs.append(cost) + * + * curves = spline_to_curves(q, costs, max_err, all_cubic) # <<<<<<<<<<<<<< + * + * if not is_complex: + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_spline_to_curves); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyFloat_FromDouble(__pyx_v_max_err); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = NULL; + __pyx_t_17 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_17 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_1, __pyx_v_q, __pyx_v_costs, __pyx_t_6, __pyx_v_all_cubic}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_17, 4+__pyx_t_17); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_v_curves = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":237 + * curves = spline_to_curves(q, costs, max_err, all_cubic) + * + * if not is_complex: # <<<<<<<<<<<<<< + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] + * return curves + */ + __pyx_t_3 = (!(__pyx_v_is_complex != 0)); + if (__pyx_t_3) { + + /* "fontTools/qu2cu/qu2cu.py":238 + * + * if not is_complex: + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] # <<<<<<<<<<<<<< + * return curves + * + */ + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_2); + if (likely(PyList_CheckExact(__pyx_v_curves)) || PyTuple_CheckExact(__pyx_v_curves)) { + __pyx_t_5 = __pyx_v_curves; __Pyx_INCREF(__pyx_t_5); + __pyx_t_4 = 0; + __pyx_t_8 = NULL; + } else { + __pyx_t_4 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_curves); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 238, __pyx_L28_error) + } + for (;;) { + if (likely(!__pyx_t_8)) { + if (likely(PyList_CheckExact(__pyx_t_5))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 238, __pyx_L28_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 238, __pyx_L28_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 238, __pyx_L28_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(0, 238, __pyx_L28_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } + } else { + __pyx_t_6 = __pyx_t_8(__pyx_t_5); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 238, __pyx_L28_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_XDECREF_SET(__pyx_8genexpr3__pyx_v_curve, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __pyx_pf_9fontTools_5qu2cu_5qu2cu_19quadratic_to_curves_8genexpr3_genexpr(NULL, __pyx_8genexpr3__pyx_v_curve); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = __Pyx_PySequence_Tuple(__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_1))) __PYX_ERR(0, 238, __pyx_L28_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_curve); __pyx_8genexpr3__pyx_v_curve = 0; + goto __pyx_L32_exit_scope; + __pyx_L28_error:; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_curve); __pyx_8genexpr3__pyx_v_curve = 0; + goto __pyx_L1_error; + __pyx_L32_exit_scope:; + } /* exit inner scope */ + __Pyx_DECREF_SET(__pyx_v_curves, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":237 + * curves = spline_to_curves(q, costs, max_err, all_cubic) + * + * if not is_complex: # <<<<<<<<<<<<<< + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] + * return curves + */ + } + + /* "fontTools/qu2cu/qu2cu.py":239 + * if not is_complex: + * curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] + * return curves # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + if (!(likely(PyList_CheckExact(__pyx_v_curves))||((__pyx_v_curves) == Py_None) || __Pyx_RaiseUnexpectedTypeError("list", __pyx_v_curves))) __PYX_ERR(0, 239, __pyx_L1_error) + __Pyx_INCREF(__pyx_v_curves); + __pyx_r = ((PyObject*)__pyx_v_curves); + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.quadratic_to_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_q); + __Pyx_XDECREF(__pyx_v_costs); + __Pyx_XDECREF(__pyx_v_p); + __Pyx_XDECREF(__pyx_v_qq); + __Pyx_XDECREF(__pyx_v_curves); + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_p); + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_x); + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_y); + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_curve); + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_0); + __Pyx_XDECREF(__pyx_v_quads); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_7spline_to_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5qu2cu_5qu2cu_6spline_to_curves, "spline_to_curves(q, costs, double tolerance=0.5, int all_cubic=False)\n\n q: quadratic spline with alternating on-curve / off-curve points.\n\n costs: cumulative list of encoding cost of q in terms of number of\n points that need to be encoded. Implied on-curve points do not\n contribute to the cost. If all points need to be encoded, then\n costs will be range(1, len(q)+1).\n "); +static PyMethodDef __pyx_mdef_9fontTools_5qu2cu_5qu2cu_7spline_to_curves = {"spline_to_curves", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_5qu2cu_5qu2cu_7spline_to_curves, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_5qu2cu_5qu2cu_6spline_to_curves}; +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_7spline_to_curves(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_q = 0; + PyObject *__pyx_v_costs = 0; + double __pyx_v_tolerance; + int __pyx_v_all_cubic; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("spline_to_curves (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_q,&__pyx_n_s_costs,&__pyx_n_s_tolerance,&__pyx_n_s_all_cubic,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_q)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 245, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_costs)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 245, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("spline_to_curves", 0, 2, 4, 1); __PYX_ERR(0, 245, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tolerance); + if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 245, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_all_cubic); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 245, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "spline_to_curves") < 0)) __PYX_ERR(0, 245, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_q = values[0]; + __pyx_v_costs = values[1]; + if (values[2]) { + __pyx_v_tolerance = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_tolerance == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 268, __pyx_L3_error) + } else { + __pyx_v_tolerance = ((double)((double)0.5)); + } + if (values[3]) { + __pyx_v_all_cubic = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_all_cubic == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 268, __pyx_L3_error) + } else { + + /* "fontTools/qu2cu/qu2cu.py":268 + * u=cython.complex, + * ) + * def spline_to_curves(q, costs, tolerance=0.5, all_cubic=False): # <<<<<<<<<<<<<< + * """ + * q: quadratic spline with alternating on-curve / off-curve points. + */ + __pyx_v_all_cubic = ((int)((int)0)); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("spline_to_curves", 0, 2, 4, __pyx_nargs); __PYX_ERR(0, 245, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.spline_to_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_5qu2cu_5qu2cu_6spline_to_curves(__pyx_self, __pyx_v_q, __pyx_v_costs, __pyx_v_tolerance, __pyx_v_all_cubic); + + /* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/qu2cu/qu2cu.py":343 + * for k, reconst in enumerate(reconstructed): + * orig = elevated_quadratics[j + k] + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) # <<<<<<<<<<<<<< + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + */ + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr(__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 343, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_2generator1, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_spline_to_curves_locals_genexpr, __pyx_n_s_fontTools_qu2cu_qu2cu); if (unlikely(!gen)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.spline_to_curves.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + __pyx_t_double_complex __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L8_resume_from_yield; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 343, __pyx_L1_error) + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 343, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 343, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 343, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 343, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 343, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 343, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 343, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) { + PyObject* sequence = __pyx_t_4; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 343, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_5 = PyList_GET_ITEM(sequence, 0); + __pyx_t_6 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + #else + __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 343, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 343, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_6); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_cur_scope->__pyx_v_v = __pyx_t_9; + __pyx_cur_scope->__pyx_v_u = __pyx_t_10; + __pyx_t_10 = __Pyx_c_diff_double(__pyx_cur_scope->__pyx_v_v, __pyx_cur_scope->__pyx_v_u); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_t_10); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + __Pyx_XGIVEREF(__pyx_t_1); + __pyx_cur_scope->__pyx_t_0 = __pyx_t_1; + __pyx_cur_scope->__pyx_t_1 = __pyx_t_2; + __pyx_cur_scope->__pyx_t_2 = __pyx_t_3; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L8_resume_from_yield:; + __pyx_t_1 = __pyx_cur_scope->__pyx_t_0; + __pyx_cur_scope->__pyx_t_0 = 0; + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_cur_scope->__pyx_t_1; + __pyx_t_3 = __pyx_cur_scope->__pyx_t_2; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 343, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + PyErr_SetNone(PyExc_StopIteration); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_6spline_to_curves(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_q, PyObject *__pyx_v_costs, double __pyx_v_tolerance, int __pyx_v_all_cubic) { + int __pyx_v_i; + int __pyx_v_j; + int __pyx_v_k; + int __pyx_v_start; + int __pyx_v_i_sol_count; + int __pyx_v_j_sol_count; + double __pyx_v_err; + double __pyx_v_error; + double __pyx_v_i_sol_error; + double __pyx_v_j_sol_error; + int __pyx_v_is_cubic; + int __pyx_v_count; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + PyObject *__pyx_v_elevated_quadratics = NULL; + PyObject *__pyx_v_forced = NULL; + PyObject *__pyx_v_sols = NULL; + PyObject *__pyx_v_impossible = NULL; + PyObject *__pyx_v_best_sol = NULL; + PyObject *__pyx_v_this_count = NULL; + PyObject *__pyx_v_i_sol = NULL; + PyObject *__pyx_v_curve = NULL; + PyObject *__pyx_v_ts = NULL; + PyObject *__pyx_v_reconstructed_iter = NULL; + PyObject *__pyx_v_reconstructed = NULL; + PyObject *__pyx_v_reconst = NULL; + PyObject *__pyx_v_orig = NULL; + PyObject *__pyx_v_splits = NULL; + PyObject *__pyx_v_cubic = NULL; + PyObject *__pyx_v_curves = NULL; + int __pyx_8genexpr5__pyx_v_i; + PyObject *__pyx_gb_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_2generator1 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + long __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + int __pyx_t_11; + int __pyx_t_12; + int __pyx_t_13; + int __pyx_t_14; + int __pyx_t_15; + double __pyx_t_16; + PyObject *__pyx_t_17 = NULL; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *(*__pyx_t_22)(PyObject *); + Py_ssize_t __pyx_t_23; + PyObject *(*__pyx_t_24)(PyObject *); + int __pyx_t_25; + double __pyx_t_26; + double __pyx_t_27; + __pyx_t_double_complex __pyx_t_28; + __pyx_t_double_complex __pyx_t_29; + __pyx_t_double_complex __pyx_t_30; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("spline_to_curves", 1); + + /* "fontTools/qu2cu/qu2cu.py":278 + * """ + * + * assert len(q) >= 3, "quadratic spline requires at least 3 points" # <<<<<<<<<<<<<< + * + * # Elevate quadratic segments to cubic + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_1 = PyObject_Length(__pyx_v_q); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 278, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 >= 3); + if (unlikely(!__pyx_t_2)) { + __Pyx_Raise(__pyx_builtin_AssertionError, __pyx_kp_u_quadratic_spline_requires_at_lea, 0, 0); + __PYX_ERR(0, 278, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(0, 278, __pyx_L1_error) + #endif + + /* "fontTools/qu2cu/qu2cu.py":281 + * + * # Elevate quadratic segments to cubic + * elevated_quadratics = [ # <<<<<<<<<<<<<< + * elevate_quadratic(*q[i : i + 3]) for i in range(0, len(q) - 2, 2) + * ] + */ + { /* enter inner scope */ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/qu2cu/qu2cu.py":282 + * # Elevate quadratic segments to cubic + * elevated_quadratics = [ + * elevate_quadratic(*q[i : i + 3]) for i in range(0, len(q) - 2, 2) # <<<<<<<<<<<<<< + * ] + * + */ + __pyx_t_1 = PyObject_Length(__pyx_v_q); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 282, __pyx_L1_error) + __pyx_t_4 = (__pyx_t_1 - 2); + __pyx_t_1 = __pyx_t_4; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_1; __pyx_t_5+=2) { + __pyx_8genexpr5__pyx_v_i = __pyx_t_5; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_elevate_quadratic); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_v_q, __pyx_8genexpr5__pyx_v_i, (__pyx_8genexpr5__pyx_v_i + 3), NULL, NULL, NULL, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 281, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + } /* exit inner scope */ + __pyx_v_elevated_quadratics = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/qu2cu/qu2cu.py":286 + * + * # Find sharp corners; they have to be oncurves for sure. + * forced = set() # <<<<<<<<<<<<<< + * for i in range(1, len(elevated_quadratics)): + * p0 = elevated_quadratics[i - 1][2] + */ + __pyx_t_3 = PySet_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 286, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_forced = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/qu2cu/qu2cu.py":287 + * # Find sharp corners; they have to be oncurves for sure. + * forced = set() + * for i in range(1, len(elevated_quadratics)): # <<<<<<<<<<<<<< + * p0 = elevated_quadratics[i - 1][2] + * p1 = elevated_quadratics[i][0] + */ + __pyx_t_4 = __Pyx_PyList_GET_SIZE(__pyx_v_elevated_quadratics); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 287, __pyx_L1_error) + __pyx_t_1 = __pyx_t_4; + for (__pyx_t_5 = 1; __pyx_t_5 < __pyx_t_1; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "fontTools/qu2cu/qu2cu.py":288 + * forced = set() + * for i in range(1, len(elevated_quadratics)): + * p0 = elevated_quadratics[i - 1][2] # <<<<<<<<<<<<<< + * p1 = elevated_quadratics[i][0] + * p2 = elevated_quadratics[i][1] + */ + __pyx_t_9 = (__pyx_v_i - 1); + __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_elevated_quadratics, __pyx_t_9, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_3, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 288, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_p0 = __pyx_t_10; + + /* "fontTools/qu2cu/qu2cu.py":289 + * for i in range(1, len(elevated_quadratics)): + * p0 = elevated_quadratics[i - 1][2] + * p1 = elevated_quadratics[i][0] # <<<<<<<<<<<<<< + * p2 = elevated_quadratics[i][1] + * if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): + */ + __pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_elevated_quadratics, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_7, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 289, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_p1 = __pyx_t_10; + + /* "fontTools/qu2cu/qu2cu.py":290 + * p0 = elevated_quadratics[i - 1][2] + * p1 = elevated_quadratics[i][0] + * p2 = elevated_quadratics[i][1] # <<<<<<<<<<<<<< + * if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): + * forced.add(i) + */ + __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_elevated_quadratics, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 290, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_3, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 290, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 290, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_p2 = __pyx_t_10; + + /* "fontTools/qu2cu/qu2cu.py":291 + * p1 = elevated_quadratics[i][0] + * p2 = elevated_quadratics[i][1] + * if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): # <<<<<<<<<<<<<< + * forced.add(i) + * + */ + __pyx_t_2 = ((__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p0)) + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p1))) > (__pyx_v_tolerance + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p0)))); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":292 + * p2 = elevated_quadratics[i][1] + * if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): + * forced.add(i) # <<<<<<<<<<<<<< + * + * # Dynamic-Programming to find the solution with fewest number of + */ + __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 292, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_11 = PySet_Add(__pyx_v_forced, __pyx_t_7); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 292, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":291 + * p1 = elevated_quadratics[i][0] + * p2 = elevated_quadratics[i][1] + * if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): # <<<<<<<<<<<<<< + * forced.add(i) + * + */ + } + } + + /* "fontTools/qu2cu/qu2cu.py":296 + * # Dynamic-Programming to find the solution with fewest number of + * # cubic curves, and within those the one with smallest error. + * sols = [Solution(0, 0, 0, False)] # <<<<<<<<<<<<<< + * impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) + * start = 0 + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_Solution); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyList_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_t_3)) __PYX_ERR(0, 296, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_v_sols = ((PyObject*)__pyx_t_7); + __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":297 + * # cubic curves, and within those the one with smallest error. + * sols = [Solution(0, 0, 0, False)] + * impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) # <<<<<<<<<<<<<< + * start = 0 + * for i in range(1, len(elevated_quadratics) + 1): + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Solution); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyList_GET_SIZE(__pyx_v_elevated_quadratics); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 297, __pyx_L1_error) + __pyx_t_8 = PyInt_FromSsize_t(((__pyx_t_4 * 3) + 1)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_6, __pyx_t_8, __pyx_int_0, __pyx_int_1, Py_False}; + __pyx_t_7 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 4+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_impossible = __pyx_t_7; + __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":298 + * sols = [Solution(0, 0, 0, False)] + * impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) + * start = 0 # <<<<<<<<<<<<<< + * for i in range(1, len(elevated_quadratics) + 1): + * best_sol = impossible + */ + __pyx_v_start = 0; + + /* "fontTools/qu2cu/qu2cu.py":299 + * impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) + * start = 0 + * for i in range(1, len(elevated_quadratics) + 1): # <<<<<<<<<<<<<< + * best_sol = impossible + * for j in range(start, i): + */ + __pyx_t_4 = __Pyx_PyList_GET_SIZE(__pyx_v_elevated_quadratics); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 299, __pyx_L1_error) + __pyx_t_1 = (__pyx_t_4 + 1); + __pyx_t_4 = __pyx_t_1; + for (__pyx_t_5 = 1; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "fontTools/qu2cu/qu2cu.py":300 + * start = 0 + * for i in range(1, len(elevated_quadratics) + 1): + * best_sol = impossible # <<<<<<<<<<<<<< + * for j in range(start, i): + * j_sol_count, j_sol_error = sols[j].num_points, sols[j].error + */ + __Pyx_INCREF(__pyx_v_impossible); + __Pyx_XDECREF_SET(__pyx_v_best_sol, __pyx_v_impossible); + + /* "fontTools/qu2cu/qu2cu.py":301 + * for i in range(1, len(elevated_quadratics) + 1): + * best_sol = impossible + * for j in range(start, i): # <<<<<<<<<<<<<< + * j_sol_count, j_sol_error = sols[j].num_points, sols[j].error + * + */ + __pyx_t_12 = __pyx_v_i; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = __pyx_v_start; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_v_j = __pyx_t_14; + + /* "fontTools/qu2cu/qu2cu.py":302 + * best_sol = impossible + * for j in range(start, i): + * j_sol_count, j_sol_error = sols[j].num_points, sols[j].error # <<<<<<<<<<<<<< + * + * if not all_cubic: + */ + __pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_sols, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_num_points); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_sols, __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_error); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_16 = __pyx_PyFloat_AsDouble(__pyx_t_7); if (unlikely((__pyx_t_16 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 302, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_j_sol_count = __pyx_t_15; + __pyx_v_j_sol_error = __pyx_t_16; + + /* "fontTools/qu2cu/qu2cu.py":304 + * j_sol_count, j_sol_error = sols[j].num_points, sols[j].error + * + * if not all_cubic: # <<<<<<<<<<<<<< + * # Solution with quadratics between j:i + * this_count = costs[2 * i - 1] - costs[2 * j] + 1 + */ + __pyx_t_2 = (!(__pyx_v_all_cubic != 0)); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":306 + * if not all_cubic: + * # Solution with quadratics between j:i + * this_count = costs[2 * i - 1] - costs[2 * j] + 1 # <<<<<<<<<<<<<< + * i_sol_count = j_sol_count + this_count + * i_sol_error = j_sol_error + */ + __pyx_t_9 = ((2 * __pyx_v_i) - 1); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_costs, __pyx_t_9, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = (2 * __pyx_v_j); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_costs, __pyx_t_9, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = PyNumber_Subtract(__pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyInt_AddObjC(__pyx_t_8, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 306, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_this_count, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/qu2cu/qu2cu.py":307 + * # Solution with quadratics between j:i + * this_count = costs[2 * i - 1] - costs[2 * j] + 1 + * i_sol_count = j_sol_count + this_count # <<<<<<<<<<<<<< + * i_sol_error = j_sol_error + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_j_sol_count); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_v_this_count); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 307, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_i_sol_count = __pyx_t_15; + + /* "fontTools/qu2cu/qu2cu.py":308 + * this_count = costs[2 * i - 1] - costs[2 * j] + 1 + * i_sol_count = j_sol_count + this_count + * i_sol_error = j_sol_error # <<<<<<<<<<<<<< + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + * if i_sol < best_sol: + */ + __pyx_v_i_sol_error = __pyx_v_j_sol_error; + + /* "fontTools/qu2cu/qu2cu.py":309 + * i_sol_count = j_sol_count + this_count + * i_sol_error = j_sol_error + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) # <<<<<<<<<<<<<< + * if i_sol < best_sol: + * best_sol = i_sol + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Solution); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_i_sol_count); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = PyFloat_FromDouble(__pyx_v_i_sol_error); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_17 = __Pyx_PyInt_From_int((__pyx_v_i - __pyx_v_j)); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __pyx_t_18 = NULL; + __pyx_t_15 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_18)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_18); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_15 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_18, __pyx_t_7, __pyx_t_6, __pyx_t_17, Py_False}; + __pyx_t_8 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_15, 4+__pyx_t_15); + __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __Pyx_XDECREF_SET(__pyx_v_i_sol, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":310 + * i_sol_error = j_sol_error + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + * if i_sol < best_sol: # <<<<<<<<<<<<<< + * best_sol = i_sol + * + */ + __pyx_t_8 = PyObject_RichCompare(__pyx_v_i_sol, __pyx_v_best_sol, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 310, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 310, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":311 + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + * if i_sol < best_sol: + * best_sol = i_sol # <<<<<<<<<<<<<< + * + * if this_count <= 3: + */ + __Pyx_INCREF(__pyx_v_i_sol); + __Pyx_DECREF_SET(__pyx_v_best_sol, __pyx_v_i_sol); + + /* "fontTools/qu2cu/qu2cu.py":310 + * i_sol_error = j_sol_error + * i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + * if i_sol < best_sol: # <<<<<<<<<<<<<< + * best_sol = i_sol + * + */ + } + + /* "fontTools/qu2cu/qu2cu.py":313 + * best_sol = i_sol + * + * if this_count <= 3: # <<<<<<<<<<<<<< + * # Can't get any better than this in the path below + * continue + */ + __pyx_t_8 = PyObject_RichCompare(__pyx_v_this_count, __pyx_int_3, Py_LE); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 313, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 313, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":315 + * if this_count <= 3: + * # Can't get any better than this in the path below + * continue # <<<<<<<<<<<<<< + * + * # Fit elevated_quadratics[j:i] into one cubic + */ + goto __pyx_L10_continue; + + /* "fontTools/qu2cu/qu2cu.py":313 + * best_sol = i_sol + * + * if this_count <= 3: # <<<<<<<<<<<<<< + * # Can't get any better than this in the path below + * continue + */ + } + + /* "fontTools/qu2cu/qu2cu.py":304 + * j_sol_count, j_sol_error = sols[j].num_points, sols[j].error + * + * if not all_cubic: # <<<<<<<<<<<<<< + * # Solution with quadratics between j:i + * this_count = costs[2 * i - 1] - costs[2 * j] + 1 + */ + } + + /* "fontTools/qu2cu/qu2cu.py":318 + * + * # Fit elevated_quadratics[j:i] into one cubic + * try: # <<<<<<<<<<<<<< + * curve, ts = merge_curves(elevated_quadratics, j, i - j) + * except ZeroDivisionError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_19); + __Pyx_XGOTREF(__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_21); + /*try:*/ { + + /* "fontTools/qu2cu/qu2cu.py":319 + * # Fit elevated_quadratics[j:i] into one cubic + * try: + * curve, ts = merge_curves(elevated_quadratics, j, i - j) # <<<<<<<<<<<<<< + * except ZeroDivisionError: + * continue + */ + __pyx_t_8 = __pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(__pyx_v_elevated_quadratics, __pyx_v_j, (__pyx_v_i - __pyx_v_j)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 319, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + if ((likely(PyTuple_CheckExact(__pyx_t_8))) || (PyList_CheckExact(__pyx_t_8))) { + PyObject* sequence = __pyx_t_8; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 319, __pyx_L15_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_17 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_3 = PyList_GET_ITEM(sequence, 0); + __pyx_t_17 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_17); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 319, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_17 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 319, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_17); + #endif + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 319, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_22 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_3 = __pyx_t_22(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L23_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_17 = __pyx_t_22(__pyx_t_6); if (unlikely(!__pyx_t_17)) goto __pyx_L23_unpacking_failed; + __Pyx_GOTREF(__pyx_t_17); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_22(__pyx_t_6), 2) < 0) __PYX_ERR(0, 319, __pyx_L15_error) + __pyx_t_22 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L24_unpacking_done; + __pyx_L23_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_22 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 319, __pyx_L15_error) + __pyx_L24_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_curve, __pyx_t_3); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_ts, __pyx_t_17); + __pyx_t_17 = 0; + + /* "fontTools/qu2cu/qu2cu.py":318 + * + * # Fit elevated_quadratics[j:i] into one cubic + * try: # <<<<<<<<<<<<<< + * curve, ts = merge_curves(elevated_quadratics, j, i - j) + * except ZeroDivisionError: + */ + } + __Pyx_XDECREF(__pyx_t_19); __pyx_t_19 = 0; + __Pyx_XDECREF(__pyx_t_20); __pyx_t_20 = 0; + __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0; + goto __pyx_L22_try_end; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; + __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":320 + * try: + * curve, ts = merge_curves(elevated_quadratics, j, i - j) + * except ZeroDivisionError: # <<<<<<<<<<<<<< + * continue + * + */ + __pyx_t_15 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_ZeroDivisionError); + if (__pyx_t_15) { + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.spline_to_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_17, &__pyx_t_3) < 0) __PYX_ERR(0, 320, __pyx_L17_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_3); + + /* "fontTools/qu2cu/qu2cu.py":321 + * curve, ts = merge_curves(elevated_quadratics, j, i - j) + * except ZeroDivisionError: + * continue # <<<<<<<<<<<<<< + * + * # Now reconstruct the segments from the fitted curve + */ + goto __pyx_L25_except_continue; + __pyx_L25_except_continue:; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L21_try_continue; + } + goto __pyx_L17_except_error; + + /* "fontTools/qu2cu/qu2cu.py":318 + * + * # Fit elevated_quadratics[j:i] into one cubic + * try: # <<<<<<<<<<<<<< + * curve, ts = merge_curves(elevated_quadratics, j, i - j) + * except ZeroDivisionError: + */ + __pyx_L17_except_error:; + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_ExceptionReset(__pyx_t_19, __pyx_t_20, __pyx_t_21); + goto __pyx_L1_error; + __pyx_L21_try_continue:; + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_ExceptionReset(__pyx_t_19, __pyx_t_20, __pyx_t_21); + goto __pyx_L10_continue; + __pyx_L22_try_end:; + } + + /* "fontTools/qu2cu/qu2cu.py":324 + * + * # Now reconstruct the segments from the fitted curve + * reconstructed_iter = splitCubicAtTC(*curve, *ts) # <<<<<<<<<<<<<< + * reconstructed = [] + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_splitCubicAtTC); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 324, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_17 = __Pyx_PySequence_Tuple(__pyx_v_curve); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 324, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_ts); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 324, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = PyNumber_Add(__pyx_t_17, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 324, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 324, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF_SET(__pyx_v_reconstructed_iter, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":325 + * # Now reconstruct the segments from the fitted curve + * reconstructed_iter = splitCubicAtTC(*curve, *ts) + * reconstructed = [] # <<<<<<<<<<<<<< + * + * # Knot errors + */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_XDECREF_SET(__pyx_v_reconstructed, ((PyObject*)__pyx_t_8)); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":328 + * + * # Knot errors + * error = 0 # <<<<<<<<<<<<<< + * for k, reconst in enumerate(reconstructed_iter): + * orig = elevated_quadratics[j + k] + */ + __pyx_v_error = 0.0; + + /* "fontTools/qu2cu/qu2cu.py":329 + * # Knot errors + * error = 0 + * for k, reconst in enumerate(reconstructed_iter): # <<<<<<<<<<<<<< + * orig = elevated_quadratics[j + k] + * err = abs(reconst[3] - orig[3]) + */ + __pyx_t_15 = 0; + if (likely(PyList_CheckExact(__pyx_v_reconstructed_iter)) || PyTuple_CheckExact(__pyx_v_reconstructed_iter)) { + __pyx_t_8 = __pyx_v_reconstructed_iter; __Pyx_INCREF(__pyx_t_8); + __pyx_t_23 = 0; + __pyx_t_24 = NULL; + } else { + __pyx_t_23 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_v_reconstructed_iter); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_24 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8); if (unlikely(!__pyx_t_24)) __PYX_ERR(0, 329, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_24)) { + if (likely(PyList_CheckExact(__pyx_t_8))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_8); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 329, __pyx_L1_error) + #endif + if (__pyx_t_23 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_23); __Pyx_INCREF(__pyx_t_6); __pyx_t_23++; if (unlikely((0 < 0))) __PYX_ERR(0, 329, __pyx_L1_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_8); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 329, __pyx_L1_error) + #endif + if (__pyx_t_23 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_23); __Pyx_INCREF(__pyx_t_6); __pyx_t_23++; if (unlikely((0 < 0))) __PYX_ERR(0, 329, __pyx_L1_error) + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + } + } else { + __pyx_t_6 = __pyx_t_24(__pyx_t_8); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(0, 329, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_XDECREF_SET(__pyx_v_reconst, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_v_k = __pyx_t_15; + __pyx_t_15 = (__pyx_t_15 + 1); + + /* "fontTools/qu2cu/qu2cu.py":330 + * error = 0 + * for k, reconst in enumerate(reconstructed_iter): + * orig = elevated_quadratics[j + k] # <<<<<<<<<<<<<< + * err = abs(reconst[3] - orig[3]) + * error = max(error, err) + */ + __pyx_t_25 = (__pyx_v_j + __pyx_v_k); + __pyx_t_6 = __Pyx_GetItemInt_List(__pyx_v_elevated_quadratics, __pyx_t_25, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_XDECREF_SET(__pyx_v_orig, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":331 + * for k, reconst in enumerate(reconstructed_iter): + * orig = elevated_quadratics[j + k] + * err = abs(reconst[3] - orig[3]) # <<<<<<<<<<<<<< + * error = max(error, err) + * if error > tolerance: + */ + __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_reconst, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_orig, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_17 = PyNumber_Subtract(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_t_17); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __pyx_t_16 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_16 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 331, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_err = __pyx_t_16; + + /* "fontTools/qu2cu/qu2cu.py":332 + * orig = elevated_quadratics[j + k] + * err = abs(reconst[3] - orig[3]) + * error = max(error, err) # <<<<<<<<<<<<<< + * if error > tolerance: + * break + */ + __pyx_t_16 = __pyx_v_err; + __pyx_t_26 = __pyx_v_error; + __pyx_t_2 = (__pyx_t_16 > __pyx_t_26); + if (__pyx_t_2) { + __pyx_t_27 = __pyx_t_16; + } else { + __pyx_t_27 = __pyx_t_26; + } + __pyx_v_error = __pyx_t_27; + + /* "fontTools/qu2cu/qu2cu.py":333 + * err = abs(reconst[3] - orig[3]) + * error = max(error, err) + * if error > tolerance: # <<<<<<<<<<<<<< + * break + * reconstructed.append(reconst) + */ + __pyx_t_2 = (__pyx_v_error > __pyx_v_tolerance); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":334 + * error = max(error, err) + * if error > tolerance: + * break # <<<<<<<<<<<<<< + * reconstructed.append(reconst) + * if error > tolerance: + */ + goto __pyx_L28_break; + + /* "fontTools/qu2cu/qu2cu.py":333 + * err = abs(reconst[3] - orig[3]) + * error = max(error, err) + * if error > tolerance: # <<<<<<<<<<<<<< + * break + * reconstructed.append(reconst) + */ + } + + /* "fontTools/qu2cu/qu2cu.py":335 + * if error > tolerance: + * break + * reconstructed.append(reconst) # <<<<<<<<<<<<<< + * if error > tolerance: + * # Not feasible + */ + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_reconstructed, __pyx_v_reconst); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 335, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":329 + * # Knot errors + * error = 0 + * for k, reconst in enumerate(reconstructed_iter): # <<<<<<<<<<<<<< + * orig = elevated_quadratics[j + k] + * err = abs(reconst[3] - orig[3]) + */ + } + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L30_for_end; + __pyx_L28_break:; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L30_for_end; + __pyx_L30_for_end:; + + /* "fontTools/qu2cu/qu2cu.py":336 + * break + * reconstructed.append(reconst) + * if error > tolerance: # <<<<<<<<<<<<<< + * # Not feasible + * continue + */ + __pyx_t_2 = (__pyx_v_error > __pyx_v_tolerance); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":338 + * if error > tolerance: + * # Not feasible + * continue # <<<<<<<<<<<<<< + * + * # Interior errors + */ + goto __pyx_L10_continue; + + /* "fontTools/qu2cu/qu2cu.py":336 + * break + * reconstructed.append(reconst) + * if error > tolerance: # <<<<<<<<<<<<<< + * # Not feasible + * continue + */ + } + + /* "fontTools/qu2cu/qu2cu.py":341 + * + * # Interior errors + * for k, reconst in enumerate(reconstructed): # <<<<<<<<<<<<<< + * orig = elevated_quadratics[j + k] + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + */ + __pyx_t_15 = 0; + __pyx_t_8 = __pyx_v_reconstructed; __Pyx_INCREF(__pyx_t_8); + __pyx_t_23 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_8); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 341, __pyx_L1_error) + #endif + if (__pyx_t_23 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_23); __Pyx_INCREF(__pyx_t_3); __pyx_t_23++; if (unlikely((0 < 0))) __PYX_ERR(0, 341, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 341, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_reconst, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_v_k = __pyx_t_15; + __pyx_t_15 = (__pyx_t_15 + 1); + + /* "fontTools/qu2cu/qu2cu.py":342 + * # Interior errors + * for k, reconst in enumerate(reconstructed): + * orig = elevated_quadratics[j + k] # <<<<<<<<<<<<<< + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + * + */ + __pyx_t_25 = (__pyx_v_j + __pyx_v_k); + __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_elevated_quadratics, __pyx_t_25, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 342, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_XDECREF_SET(__pyx_v_orig, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/qu2cu/qu2cu.py":343 + * for k, reconst in enumerate(reconstructed): + * orig = elevated_quadratics[j + k] + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) # <<<<<<<<<<<<<< + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_reconst); + __Pyx_GIVEREF(__pyx_v_reconst); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_reconst)) __PYX_ERR(0, 343, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_orig); + __Pyx_GIVEREF(__pyx_v_orig); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_orig)) __PYX_ERR(0, 343, __pyx_L1_error); + __pyx_t_17 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_3, NULL); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __pyx_pf_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_genexpr(NULL, __pyx_t_17); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __pyx_t_17 = __Pyx_PySequence_Tuple(__pyx_t_3); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (1) { + PyObject* sequence = __pyx_t_17; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 343, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_18 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_18); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_6,&__pyx_t_7,&__pyx_t_18}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + } + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_28 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_6); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_29 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_7); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_30 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_18); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0; + __pyx_v_p0 = __pyx_t_10; + __pyx_v_p1 = __pyx_t_28; + __pyx_v_p2 = __pyx_t_29; + __pyx_v_p3 = __pyx_t_30; + + /* "fontTools/qu2cu/qu2cu.py":345 + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): # <<<<<<<<<<<<<< + * error = tolerance + 1 + * break + */ + __pyx_t_25 = __pyx_f_9fontTools_5qu2cu_5qu2cu_cubic_farthest_fit_inside(__pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3, __pyx_v_tolerance); if (unlikely(__pyx_t_25 == ((int)-1) && PyErr_Occurred())) __PYX_ERR(0, 345, __pyx_L1_error) + __pyx_t_2 = (!(__pyx_t_25 != 0)); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":346 + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + * error = tolerance + 1 # <<<<<<<<<<<<<< + * break + * if error > tolerance: + */ + __pyx_v_error = (__pyx_v_tolerance + 1.0); + + /* "fontTools/qu2cu/qu2cu.py":347 + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + * error = tolerance + 1 + * break # <<<<<<<<<<<<<< + * if error > tolerance: + * # Not feasible + */ + goto __pyx_L33_break; + + /* "fontTools/qu2cu/qu2cu.py":345 + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + * + * if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): # <<<<<<<<<<<<<< + * error = tolerance + 1 + * break + */ + } + + /* "fontTools/qu2cu/qu2cu.py":341 + * + * # Interior errors + * for k, reconst in enumerate(reconstructed): # <<<<<<<<<<<<<< + * orig = elevated_quadratics[j + k] + * p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + */ + } + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L35_for_end; + __pyx_L33_break:; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L35_for_end; + __pyx_L35_for_end:; + + /* "fontTools/qu2cu/qu2cu.py":348 + * error = tolerance + 1 + * break + * if error > tolerance: # <<<<<<<<<<<<<< + * # Not feasible + * continue + */ + __pyx_t_2 = (__pyx_v_error > __pyx_v_tolerance); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":350 + * if error > tolerance: + * # Not feasible + * continue # <<<<<<<<<<<<<< + * + * # Save best solution + */ + goto __pyx_L10_continue; + + /* "fontTools/qu2cu/qu2cu.py":348 + * error = tolerance + 1 + * break + * if error > tolerance: # <<<<<<<<<<<<<< + * # Not feasible + * continue + */ + } + + /* "fontTools/qu2cu/qu2cu.py":353 + * + * # Save best solution + * i_sol_count = j_sol_count + 3 # <<<<<<<<<<<<<< + * i_sol_error = max(j_sol_error, error) + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + */ + __pyx_v_i_sol_count = (__pyx_v_j_sol_count + 3); + + /* "fontTools/qu2cu/qu2cu.py":354 + * # Save best solution + * i_sol_count = j_sol_count + 3 + * i_sol_error = max(j_sol_error, error) # <<<<<<<<<<<<<< + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + * if i_sol < best_sol: + */ + __pyx_t_27 = __pyx_v_error; + __pyx_t_16 = __pyx_v_j_sol_error; + __pyx_t_2 = (__pyx_t_27 > __pyx_t_16); + if (__pyx_t_2) { + __pyx_t_26 = __pyx_t_27; + } else { + __pyx_t_26 = __pyx_t_16; + } + __pyx_v_i_sol_error = __pyx_t_26; + + /* "fontTools/qu2cu/qu2cu.py":355 + * i_sol_count = j_sol_count + 3 + * i_sol_error = max(j_sol_error, error) + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) # <<<<<<<<<<<<<< + * if i_sol < best_sol: + * best_sol = i_sol + */ + __Pyx_GetModuleGlobalName(__pyx_t_17, __pyx_n_s_Solution); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __pyx_t_18 = __Pyx_PyInt_From_int(__pyx_v_i_sol_count); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_18); + __pyx_t_7 = PyFloat_FromDouble(__pyx_v_i_sol_error); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_i - __pyx_v_j)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = NULL; + __pyx_t_15 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_17))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_17); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_17); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_17, function); + __pyx_t_15 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_t_18, __pyx_t_7, __pyx_t_6, Py_True}; + __pyx_t_8 = __Pyx_PyObject_FastCall(__pyx_t_17, __pyx_callargs+1-__pyx_t_15, 4+__pyx_t_15); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + } + __Pyx_XDECREF_SET(__pyx_v_i_sol, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":356 + * i_sol_error = max(j_sol_error, error) + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + * if i_sol < best_sol: # <<<<<<<<<<<<<< + * best_sol = i_sol + * + */ + __pyx_t_8 = PyObject_RichCompare(__pyx_v_i_sol, __pyx_v_best_sol, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 356, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 356, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":357 + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + * if i_sol < best_sol: + * best_sol = i_sol # <<<<<<<<<<<<<< + * + * if i_sol_count == 3: + */ + __Pyx_INCREF(__pyx_v_i_sol); + __Pyx_DECREF_SET(__pyx_v_best_sol, __pyx_v_i_sol); + + /* "fontTools/qu2cu/qu2cu.py":356 + * i_sol_error = max(j_sol_error, error) + * i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + * if i_sol < best_sol: # <<<<<<<<<<<<<< + * best_sol = i_sol + * + */ + } + + /* "fontTools/qu2cu/qu2cu.py":359 + * best_sol = i_sol + * + * if i_sol_count == 3: # <<<<<<<<<<<<<< + * # Can't get any better than this + * break + */ + __pyx_t_2 = (__pyx_v_i_sol_count == 3); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":361 + * if i_sol_count == 3: + * # Can't get any better than this + * break # <<<<<<<<<<<<<< + * + * sols.append(best_sol) + */ + goto __pyx_L11_break; + + /* "fontTools/qu2cu/qu2cu.py":359 + * best_sol = i_sol + * + * if i_sol_count == 3: # <<<<<<<<<<<<<< + * # Can't get any better than this + * break + */ + } + __pyx_L10_continue:; + } + __pyx_L11_break:; + + /* "fontTools/qu2cu/qu2cu.py":363 + * break + * + * sols.append(best_sol) # <<<<<<<<<<<<<< + * if i in forced: + * start = i + */ + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_sols, __pyx_v_best_sol); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 363, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":364 + * + * sols.append(best_sol) + * if i in forced: # <<<<<<<<<<<<<< + * start = i + * + */ + __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 364, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = (__Pyx_PySet_ContainsTF(__pyx_t_8, __pyx_v_forced, Py_EQ)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 364, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":365 + * sols.append(best_sol) + * if i in forced: + * start = i # <<<<<<<<<<<<<< + * + * # Reconstruct solution + */ + __pyx_v_start = __pyx_v_i; + + /* "fontTools/qu2cu/qu2cu.py":364 + * + * sols.append(best_sol) + * if i in forced: # <<<<<<<<<<<<<< + * start = i + * + */ + } + } + + /* "fontTools/qu2cu/qu2cu.py":368 + * + * # Reconstruct solution + * splits = [] # <<<<<<<<<<<<<< + * cubic = [] + * i = len(sols) - 1 + */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 368, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_v_splits = ((PyObject*)__pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":369 + * # Reconstruct solution + * splits = [] + * cubic = [] # <<<<<<<<<<<<<< + * i = len(sols) - 1 + * while i: + */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 369, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_v_cubic = ((PyObject*)__pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":370 + * splits = [] + * cubic = [] + * i = len(sols) - 1 # <<<<<<<<<<<<<< + * while i: + * count, is_cubic = sols[i].start_index, sols[i].is_cubic + */ + __pyx_t_1 = __Pyx_PyList_GET_SIZE(__pyx_v_sols); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 370, __pyx_L1_error) + __pyx_v_i = (__pyx_t_1 - 1); + + /* "fontTools/qu2cu/qu2cu.py":371 + * cubic = [] + * i = len(sols) - 1 + * while i: # <<<<<<<<<<<<<< + * count, is_cubic = sols[i].start_index, sols[i].is_cubic + * splits.append(i) + */ + while (1) { + __pyx_t_2 = (__pyx_v_i != 0); + if (!__pyx_t_2) break; + + /* "fontTools/qu2cu/qu2cu.py":372 + * i = len(sols) - 1 + * while i: + * count, is_cubic = sols[i].start_index, sols[i].is_cubic # <<<<<<<<<<<<<< + * splits.append(i) + * cubic.append(is_cubic) + */ + __pyx_t_8 = __Pyx_GetItemInt_List(__pyx_v_sols, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_start_index); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_17); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __pyx_t_17 = __Pyx_GetItemInt_List(__pyx_v_sols, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_17, __pyx_n_s_is_cubic); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 372, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_count = __pyx_t_5; + __pyx_v_is_cubic = __pyx_t_12; + + /* "fontTools/qu2cu/qu2cu.py":373 + * while i: + * count, is_cubic = sols[i].start_index, sols[i].is_cubic + * splits.append(i) # <<<<<<<<<<<<<< + * cubic.append(is_cubic) + * i -= count + */ + __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 373, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_splits, __pyx_t_8); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 373, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":374 + * count, is_cubic = sols[i].start_index, sols[i].is_cubic + * splits.append(i) + * cubic.append(is_cubic) # <<<<<<<<<<<<<< + * i -= count + * curves = [] + */ + __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_is_cubic); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_cubic, __pyx_t_8); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 374, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":375 + * splits.append(i) + * cubic.append(is_cubic) + * i -= count # <<<<<<<<<<<<<< + * curves = [] + * j = 0 + */ + __pyx_v_i = (__pyx_v_i - __pyx_v_count); + } + + /* "fontTools/qu2cu/qu2cu.py":376 + * cubic.append(is_cubic) + * i -= count + * curves = [] # <<<<<<<<<<<<<< + * j = 0 + * for i, is_cubic in reversed(list(zip(splits, cubic))): + */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 376, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_v_curves = ((PyObject*)__pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/qu2cu/qu2cu.py":377 + * i -= count + * curves = [] + * j = 0 # <<<<<<<<<<<<<< + * for i, is_cubic in reversed(list(zip(splits, cubic))): + * if is_cubic: + */ + __pyx_v_j = 0; + + /* "fontTools/qu2cu/qu2cu.py":378 + * curves = [] + * j = 0 + * for i, is_cubic in reversed(list(zip(splits, cubic))): # <<<<<<<<<<<<<< + * if is_cubic: + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + */ + __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_splits); + __Pyx_GIVEREF(__pyx_v_splits); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_splits)) __PYX_ERR(0, 378, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cubic); + __Pyx_GIVEREF(__pyx_v_cubic); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_cubic)) __PYX_ERR(0, 378, __pyx_L1_error); + __pyx_t_17 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_8, NULL); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PySequence_ListKeepNew(__pyx_t_17); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __pyx_t_17 = __pyx_t_8; __Pyx_INCREF(__pyx_t_17); + __pyx_t_1 = __Pyx_PyList_GET_SIZE(__pyx_t_17); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 378, __pyx_L1_error) + #endif + --__pyx_t_1; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + for (;;) { + if (__pyx_t_1 < 0) break; + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_17); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 378, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_8 = PyList_GET_ITEM(__pyx_t_17, __pyx_t_1); __Pyx_INCREF(__pyx_t_8); __pyx_t_1--; if (unlikely((0 < 0))) __PYX_ERR(0, 378, __pyx_L1_error) + #else + __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_17, __pyx_t_1); __pyx_t_1--; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + if ((likely(PyTuple_CheckExact(__pyx_t_8))) || (PyList_CheckExact(__pyx_t_8))) { + PyObject* sequence = __pyx_t_8; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 378, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_6 = PyList_GET_ITEM(sequence, 0); + __pyx_t_7 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + #else + __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_18 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_18); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_22 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_18); + index = 0; __pyx_t_6 = __pyx_t_22(__pyx_t_18); if (unlikely(!__pyx_t_6)) goto __pyx_L44_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + index = 1; __pyx_t_7 = __pyx_t_22(__pyx_t_18); if (unlikely(!__pyx_t_7)) goto __pyx_L44_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_22(__pyx_t_18), 2) < 0) __PYX_ERR(0, 378, __pyx_L1_error) + __pyx_t_22 = NULL; + __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0; + goto __pyx_L45_unpacking_done; + __pyx_L44_unpacking_failed:; + __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0; + __pyx_t_22 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 378, __pyx_L1_error) + __pyx_L45_unpacking_done:; + } + __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 378, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_v_i = __pyx_t_12; + __pyx_v_is_cubic = __pyx_t_5; + + /* "fontTools/qu2cu/qu2cu.py":379 + * j = 0 + * for i, is_cubic in reversed(list(zip(splits, cubic))): + * if is_cubic: # <<<<<<<<<<<<<< + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + * else: + */ + __pyx_t_2 = (__pyx_v_is_cubic != 0); + if (__pyx_t_2) { + + /* "fontTools/qu2cu/qu2cu.py":380 + * for i, is_cubic in reversed(list(zip(splits, cubic))): + * if is_cubic: + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) # <<<<<<<<<<<<<< + * else: + * for k in range(j, i): + */ + __pyx_t_8 = __pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(__pyx_v_elevated_quadratics, __pyx_v_j, (__pyx_v_i - __pyx_v_j)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 380, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __Pyx_GetItemInt(__pyx_t_8, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 380, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_curves, __pyx_t_7); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 380, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":379 + * j = 0 + * for i, is_cubic in reversed(list(zip(splits, cubic))): + * if is_cubic: # <<<<<<<<<<<<<< + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + * else: + */ + goto __pyx_L46; + } + + /* "fontTools/qu2cu/qu2cu.py":382 + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + * else: + * for k in range(j, i): # <<<<<<<<<<<<<< + * curves.append(q[k * 2 : k * 2 + 3]) + * j = i + */ + /*else*/ { + __pyx_t_5 = __pyx_v_i; + __pyx_t_12 = __pyx_t_5; + for (__pyx_t_13 = __pyx_v_j; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) { + __pyx_v_k = __pyx_t_13; + + /* "fontTools/qu2cu/qu2cu.py":383 + * else: + * for k in range(j, i): + * curves.append(q[k * 2 : k * 2 + 3]) # <<<<<<<<<<<<<< + * j = i + * + */ + __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_v_q, (__pyx_v_k * 2), ((__pyx_v_k * 2) + 3), NULL, NULL, NULL, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 383, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_curves, __pyx_t_7); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 383, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + } + __pyx_L46:; + + /* "fontTools/qu2cu/qu2cu.py":384 + * for k in range(j, i): + * curves.append(q[k * 2 : k * 2 + 3]) + * j = i # <<<<<<<<<<<<<< + * + * return curves + */ + __pyx_v_j = __pyx_v_i; + + /* "fontTools/qu2cu/qu2cu.py":378 + * curves = [] + * j = 0 + * for i, is_cubic in reversed(list(zip(splits, cubic))): # <<<<<<<<<<<<<< + * if is_cubic: + * curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + */ + } + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + + /* "fontTools/qu2cu/qu2cu.py":386 + * j = i + * + * return curves # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_curves); + __pyx_r = __pyx_v_curves; + goto __pyx_L0; + + /* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_17); + __Pyx_XDECREF(__pyx_t_18); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.spline_to_curves", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_elevated_quadratics); + __Pyx_XDECREF(__pyx_v_forced); + __Pyx_XDECREF(__pyx_v_sols); + __Pyx_XDECREF(__pyx_v_impossible); + __Pyx_XDECREF(__pyx_v_best_sol); + __Pyx_XDECREF(__pyx_v_this_count); + __Pyx_XDECREF(__pyx_v_i_sol); + __Pyx_XDECREF(__pyx_v_curve); + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_reconstructed_iter); + __Pyx_XDECREF(__pyx_v_reconstructed); + __Pyx_XDECREF(__pyx_v_reconst); + __Pyx_XDECREF(__pyx_v_orig); + __Pyx_XDECREF(__pyx_v_splits); + __Pyx_XDECREF(__pyx_v_cubic); + __Pyx_XDECREF(__pyx_v_curves); + __Pyx_XDECREF(__pyx_gb_9fontTools_5qu2cu_5qu2cu_16spline_to_curves_2generator1); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/qu2cu/qu2cu.py":389 + * + * + * def main(): # <<<<<<<<<<<<<< + * from fontTools.cu2qu.benchmark import generate_curve + * from fontTools.cu2qu import curve_to_quadratic + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_9main(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_5qu2cu_5qu2cu_8main, "main()"); +static PyMethodDef __pyx_mdef_9fontTools_5qu2cu_5qu2cu_9main = {"main", (PyCFunction)__pyx_pw_9fontTools_5qu2cu_5qu2cu_9main, METH_NOARGS, __pyx_doc_9fontTools_5qu2cu_5qu2cu_8main}; +static PyObject *__pyx_pw_9fontTools_5qu2cu_5qu2cu_9main(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("main (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_9fontTools_5qu2cu_5qu2cu_8main(__pyx_self); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_5qu2cu_5qu2cu_8main(CYTHON_UNUSED PyObject *__pyx_self) { + PyObject *__pyx_v_generate_curve = NULL; + PyObject *__pyx_v_curve_to_quadratic = NULL; + double __pyx_v_tolerance; + double __pyx_v_reconstruct_tolerance; + PyObject *__pyx_v_curve = NULL; + PyObject *__pyx_v_quadratics = NULL; + PyObject *__pyx_v_curves = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + Py_ssize_t __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("main", 1); + + /* "fontTools/qu2cu/qu2cu.py":390 + * + * def main(): + * from fontTools.cu2qu.benchmark import generate_curve # <<<<<<<<<<<<<< + * from fontTools.cu2qu import curve_to_quadratic + * + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 390, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_generate_curve); + __Pyx_GIVEREF(__pyx_n_s_generate_curve); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_generate_curve)) __PYX_ERR(0, 390, __pyx_L1_error); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_fontTools_cu2qu_benchmark, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_generate_curve); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 390, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_generate_curve = __pyx_t_1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":391 + * def main(): + * from fontTools.cu2qu.benchmark import generate_curve + * from fontTools.cu2qu import curve_to_quadratic # <<<<<<<<<<<<<< + * + * tolerance = 0.05 + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_curve_to_quadratic); + __Pyx_GIVEREF(__pyx_n_s_curve_to_quadratic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_curve_to_quadratic)) __PYX_ERR(0, 391, __pyx_L1_error); + __pyx_t_1 = __Pyx_Import(__pyx_n_s_fontTools_cu2qu, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_curve_to_quadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_2); + __pyx_v_curve_to_quadratic = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":393 + * from fontTools.cu2qu import curve_to_quadratic + * + * tolerance = 0.05 # <<<<<<<<<<<<<< + * reconstruct_tolerance = tolerance * 1 + * curve = generate_curve() + */ + __pyx_v_tolerance = 0.05; + + /* "fontTools/qu2cu/qu2cu.py":394 + * + * tolerance = 0.05 + * reconstruct_tolerance = tolerance * 1 # <<<<<<<<<<<<<< + * curve = generate_curve() + * quadratics = curve_to_quadratic(curve, tolerance) + */ + __pyx_v_reconstruct_tolerance = (__pyx_v_tolerance * 1.0); + + /* "fontTools/qu2cu/qu2cu.py":395 + * tolerance = 0.05 + * reconstruct_tolerance = tolerance * 1 + * curve = generate_curve() # <<<<<<<<<<<<<< + * quadratics = curve_to_quadratic(curve, tolerance) + * print( + */ + __Pyx_INCREF(__pyx_v_generate_curve); + __pyx_t_2 = __pyx_v_generate_curve; __pyx_t_3 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 395, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } + __pyx_v_curve = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":396 + * reconstruct_tolerance = tolerance * 1 + * curve = generate_curve() + * quadratics = curve_to_quadratic(curve, tolerance) # <<<<<<<<<<<<<< + * print( + * "cu2qu tolerance %g. qu2cu tolerance %g." % (tolerance, reconstruct_tolerance) + */ + __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tolerance); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 396, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_curve_to_quadratic); + __pyx_t_3 = __pyx_v_curve_to_quadratic; __pyx_t_5 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_v_curve, __pyx_t_2}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 396, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_quadratics = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/qu2cu/qu2cu.py":398 + * quadratics = curve_to_quadratic(curve, tolerance) + * print( + * "cu2qu tolerance %g. qu2cu tolerance %g." % (tolerance, reconstruct_tolerance) # <<<<<<<<<<<<<< + * ) + * print("One random cubic turned into %d quadratics." % len(quadratics)) + */ + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_tolerance); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 398, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyFloat_FromDouble(__pyx_v_reconstruct_tolerance); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 398, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 398, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 398, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3)) __PYX_ERR(0, 398, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 398, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":397 + * curve = generate_curve() + * quadratics = curve_to_quadratic(curve, tolerance) + * print( # <<<<<<<<<<<<<< + * "cu2qu tolerance %g. qu2cu tolerance %g." % (tolerance, reconstruct_tolerance) + * ) + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 397, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":400 + * "cu2qu tolerance %g. qu2cu tolerance %g." % (tolerance, reconstruct_tolerance) + * ) + * print("One random cubic turned into %d quadratics." % len(quadratics)) # <<<<<<<<<<<<<< + * curves = quadratic_to_curves([quadratics], reconstruct_tolerance) + * print("Those quadratics turned back into %d cubics. " % len(curves)) + */ + __pyx_t_6 = PyObject_Length(__pyx_v_quadratics); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 400, __pyx_L1_error) + __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_One_random_cubic_turned_into_d_q, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 400, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":401 + * ) + * print("One random cubic turned into %d quadratics." % len(quadratics)) + * curves = quadratic_to_curves([quadratics], reconstruct_tolerance) # <<<<<<<<<<<<<< + * print("Those quadratics turned back into %d cubics. " % len(curves)) + * print("Original curve:", curve) + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_quadratic_to_curves); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_quadratics); + __Pyx_GIVEREF(__pyx_v_quadratics); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_quadratics)) __PYX_ERR(0, 401, __pyx_L1_error); + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_reconstruct_tolerance); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = NULL; + __pyx_t_4 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_4 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_t_1, __pyx_t_5}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_curves = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":402 + * print("One random cubic turned into %d quadratics." % len(quadratics)) + * curves = quadratic_to_curves([quadratics], reconstruct_tolerance) + * print("Those quadratics turned back into %d cubics. " % len(curves)) # <<<<<<<<<<<<<< + * print("Original curve:", curve) + * print("Reconstructed curve(s):", curves) + */ + __pyx_t_6 = PyObject_Length(__pyx_v_curves); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 402, __pyx_L1_error) + __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_Those_quadratics_turned_back_int, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":403 + * curves = quadratic_to_curves([quadratics], reconstruct_tolerance) + * print("Those quadratics turned back into %d cubics. " % len(curves)) + * print("Original curve:", curve) # <<<<<<<<<<<<<< + * print("Reconstructed curve(s):", curves) + * + */ + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 403, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_kp_u_Original_curve); + __Pyx_GIVEREF(__pyx_kp_u_Original_curve); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Original_curve)) __PYX_ERR(0, 403, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_curve); + __Pyx_GIVEREF(__pyx_v_curve); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_curve)) __PYX_ERR(0, 403, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 403, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/qu2cu/qu2cu.py":404 + * print("Those quadratics turned back into %d cubics. " % len(curves)) + * print("Original curve:", curve) + * print("Reconstructed curve(s):", curves) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_kp_u_Reconstructed_curve_s); + __Pyx_GIVEREF(__pyx_kp_u_Reconstructed_curve_s); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Reconstructed_curve_s)) __PYX_ERR(0, 404, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_curves); + __Pyx_GIVEREF(__pyx_v_curves); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_curves)) __PYX_ERR(0, 404, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/qu2cu/qu2cu.py":389 + * + * + * def main(): # <<<<<<<<<<<<<< + * from fontTools.cu2qu.benchmark import generate_curve + * from fontTools.cu2qu import curve_to_quadratic + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu.main", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_generate_curve); + __Pyx_XDECREF(__pyx_v_curve_to_quadratic); + __Pyx_XDECREF(__pyx_v_curve); + __Pyx_XDECREF(__pyx_v_quadratics); + __Pyx_XDECREF(__pyx_v_curves); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *__pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr[8]; +static int __pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr[--__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_c); + Py_CLEAR(p->__pyx_t_0); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr)))) { + __pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr[__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr++] = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_c) { + e = (*v)(p->__pyx_v_c, a); if (e) return e; + } + if (p->__pyx_t_0) { + e = (*v)(p->__pyx_t_0, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr_spec = { + "fontTools.qu2cu.qu2cu.__pyx_scope_struct__genexpr", + sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.qu2cu.qu2cu.""__pyx_scope_struct__genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *__pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr[8]; +static int __pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr = 0; + +static PyObject *__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + #if CYTHON_COMPILING_IN_CPYTHON + if (likely((int)(__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr)))) { + o = (PyObject*)__pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr[--__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else + #endif + { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + #endif + return o; +} + +static void __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_t_0); + #if CYTHON_COMPILING_IN_CPYTHON + if (((int)(__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr)))) { + __pyx_freelist_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr[__pyx_freecount_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)o); + } else + #endif + { + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr *)o; + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_t_0) { + e = (*v)(p->__pyx_t_0, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr_spec = { + "fontTools.qu2cu.qu2cu.__pyx_scope_struct_1_genexpr", + sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, + __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.qu2cu.qu2cu.""__pyx_scope_struct_1_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_AssertionError, __pyx_k_AssertionError, sizeof(__pyx_k_AssertionError), 0, 0, 1, 1}, + {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, + {&__pyx_n_s_COMPILED, __pyx_k_COMPILED, sizeof(__pyx_k_COMPILED), 0, 0, 1, 1}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_k_Lib_fontTools_qu2cu_qu2cu_py, sizeof(__pyx_k_Lib_fontTools_qu2cu_qu2cu_py), 0, 0, 1, 0}, + {&__pyx_n_s_List, __pyx_k_List, sizeof(__pyx_k_List), 0, 0, 1, 1}, + {&__pyx_kp_s_List_List_Point, __pyx_k_List_List_Point, sizeof(__pyx_k_List_List_Point), 0, 0, 1, 0}, + {&__pyx_kp_s_List_Tuple_Point, __pyx_k_List_Tuple_Point, sizeof(__pyx_k_List_Tuple_Point), 0, 0, 1, 0}, + {&__pyx_kp_u_One_random_cubic_turned_into_d_q, __pyx_k_One_random_cubic_turned_into_d_q, sizeof(__pyx_k_One_random_cubic_turned_into_d_q), 0, 1, 0, 0}, + {&__pyx_kp_u_Original_curve, __pyx_k_Original_curve, sizeof(__pyx_k_Original_curve), 0, 1, 0, 0}, + {&__pyx_n_s_Point, __pyx_k_Point, sizeof(__pyx_k_Point), 0, 0, 1, 1}, + {&__pyx_kp_u_Reconstructed_curve_s, __pyx_k_Reconstructed_curve_s, sizeof(__pyx_k_Reconstructed_curve_s), 0, 1, 0, 0}, + {&__pyx_n_s_Solution, __pyx_k_Solution, sizeof(__pyx_k_Solution), 0, 0, 1, 1}, + {&__pyx_n_u_Solution, __pyx_k_Solution, sizeof(__pyx_k_Solution), 0, 1, 0, 1}, + {&__pyx_kp_u_Those_quadratics_turned_back_int, __pyx_k_Those_quadratics_turned_back_int, sizeof(__pyx_k_Those_quadratics_turned_back_int), 0, 1, 0, 0}, + {&__pyx_n_s_Tuple, __pyx_k_Tuple, sizeof(__pyx_k_Tuple), 0, 0, 1, 1}, + {&__pyx_n_s_Union, __pyx_k_Union, sizeof(__pyx_k_Union), 0, 0, 1, 1}, + {&__pyx_n_s_ZeroDivisionError, __pyx_k_ZeroDivisionError, sizeof(__pyx_k_ZeroDivisionError), 0, 0, 1, 1}, + {&__pyx_n_s__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 0, 1, 1}, + {&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0}, + {&__pyx_n_s__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 1, 1}, + {&__pyx_n_s_add_implicit_on_curves, __pyx_k_add_implicit_on_curves, sizeof(__pyx_k_add_implicit_on_curves), 0, 0, 1, 1}, + {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, + {&__pyx_n_s_all_cubic, __pyx_k_all_cubic, sizeof(__pyx_k_all_cubic), 0, 0, 1, 1}, + {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_best_sol, __pyx_k_best_sol, sizeof(__pyx_k_best_sol), 0, 0, 1, 1}, + {&__pyx_n_s_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 0, 1, 1}, + {&__pyx_n_s_class_getitem, __pyx_k_class_getitem, sizeof(__pyx_k_class_getitem), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, + {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1}, + {&__pyx_n_s_cost, __pyx_k_cost, sizeof(__pyx_k_cost), 0, 0, 1, 1}, + {&__pyx_n_s_costs, __pyx_k_costs, sizeof(__pyx_k_costs), 0, 0, 1, 1}, + {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, + {&__pyx_kp_u_cu2qu_tolerance_g_qu2cu_toleranc, __pyx_k_cu2qu_tolerance_g_qu2cu_toleranc, sizeof(__pyx_k_cu2qu_tolerance_g_qu2cu_toleranc), 0, 1, 0, 0}, + {&__pyx_n_s_cubic, __pyx_k_cubic, sizeof(__pyx_k_cubic), 0, 0, 1, 1}, + {&__pyx_n_s_curve, __pyx_k_curve, sizeof(__pyx_k_curve), 0, 0, 1, 1}, + {&__pyx_n_s_curve_to_quadratic, __pyx_k_curve_to_quadratic, sizeof(__pyx_k_curve_to_quadratic), 0, 0, 1, 1}, + {&__pyx_n_s_curves, __pyx_k_curves, sizeof(__pyx_k_curves), 0, 0, 1, 1}, + {&__pyx_n_s_cython, __pyx_k_cython, sizeof(__pyx_k_cython), 0, 0, 1, 1}, + {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, + {&__pyx_n_s_elevate_quadratic, __pyx_k_elevate_quadratic, sizeof(__pyx_k_elevate_quadratic), 0, 0, 1, 1}, + {&__pyx_n_s_elevated_quadratics, __pyx_k_elevated_quadratics, sizeof(__pyx_k_elevated_quadratics), 0, 0, 1, 1}, + {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, + {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, + {&__pyx_n_s_err, __pyx_k_err, sizeof(__pyx_k_err), 0, 0, 1, 1}, + {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, + {&__pyx_n_u_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 1, 0, 1}, + {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_cu2qu, __pyx_k_fontTools_cu2qu, sizeof(__pyx_k_fontTools_cu2qu), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_cu2qu_benchmark, __pyx_k_fontTools_cu2qu_benchmark, sizeof(__pyx_k_fontTools_cu2qu_benchmark), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc, __pyx_k_fontTools_misc, sizeof(__pyx_k_fontTools_misc), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_misc_bezierTools, __pyx_k_fontTools_misc_bezierTools, sizeof(__pyx_k_fontTools_misc_bezierTools), 0, 0, 1, 1}, + {&__pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_k_fontTools_qu2cu_qu2cu, sizeof(__pyx_k_fontTools_qu2cu_qu2cu), 0, 0, 1, 1}, + {&__pyx_n_s_forced, __pyx_k_forced, sizeof(__pyx_k_forced), 0, 0, 1, 1}, + {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, + {&__pyx_n_s_generate_curve, __pyx_k_generate_curve, sizeof(__pyx_k_generate_curve), 0, 0, 1, 1}, + {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_i_sol, __pyx_k_i_sol, sizeof(__pyx_k_i_sol), 0, 0, 1, 1}, + {&__pyx_n_s_i_sol_count, __pyx_k_i_sol_count, sizeof(__pyx_k_i_sol_count), 0, 0, 1, 1}, + {&__pyx_n_s_i_sol_error, __pyx_k_i_sol_error, sizeof(__pyx_k_i_sol_error), 0, 0, 1, 1}, + {&__pyx_n_s_imag, __pyx_k_imag, sizeof(__pyx_k_imag), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_impossible, __pyx_k_impossible, sizeof(__pyx_k_impossible), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_n_s_is_complex, __pyx_k_is_complex, sizeof(__pyx_k_is_complex), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_n_s_is_cubic, __pyx_k_is_cubic, sizeof(__pyx_k_is_cubic), 0, 0, 1, 1}, + {&__pyx_n_u_is_cubic, __pyx_k_is_cubic, sizeof(__pyx_k_is_cubic), 0, 1, 0, 1}, + {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, + {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1}, + {&__pyx_n_s_j_sol_count, __pyx_k_j_sol_count, sizeof(__pyx_k_j_sol_count), 0, 0, 1, 1}, + {&__pyx_n_s_j_sol_error, __pyx_k_j_sol_error, sizeof(__pyx_k_j_sol_error), 0, 0, 1, 1}, + {&__pyx_n_s_k, __pyx_k_k, sizeof(__pyx_k_k), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_u_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 1, 0, 1}, + {&__pyx_n_s_main_2, __pyx_k_main_2, sizeof(__pyx_k_main_2), 0, 0, 1, 1}, + {&__pyx_n_s_math, __pyx_k_math, sizeof(__pyx_k_math), 0, 0, 1, 1}, + {&__pyx_n_s_max_err, __pyx_k_max_err, sizeof(__pyx_k_max_err), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_namedtuple, __pyx_k_namedtuple, sizeof(__pyx_k_namedtuple), 0, 0, 1, 1}, + {&__pyx_n_s_num_offcurves, __pyx_k_num_offcurves, sizeof(__pyx_k_num_offcurves), 0, 0, 1, 1}, + {&__pyx_n_s_num_points, __pyx_k_num_points, sizeof(__pyx_k_num_points), 0, 0, 1, 1}, + {&__pyx_n_u_num_points, __pyx_k_num_points, sizeof(__pyx_k_num_points), 0, 1, 0, 1}, + {&__pyx_n_s_off1, __pyx_k_off1, sizeof(__pyx_k_off1), 0, 0, 1, 1}, + {&__pyx_n_s_off2, __pyx_k_off2, sizeof(__pyx_k_off2), 0, 0, 1, 1}, + {&__pyx_n_s_on, __pyx_k_on, sizeof(__pyx_k_on), 0, 0, 1, 1}, + {&__pyx_n_s_orig, __pyx_k_orig, sizeof(__pyx_k_orig), 0, 0, 1, 1}, + {&__pyx_n_s_p, __pyx_k_p, sizeof(__pyx_k_p), 0, 0, 1, 1}, + {&__pyx_n_s_p0, __pyx_k_p0, sizeof(__pyx_k_p0), 0, 0, 1, 1}, + {&__pyx_n_s_p1, __pyx_k_p1, sizeof(__pyx_k_p1), 0, 0, 1, 1}, + {&__pyx_n_s_p1_2_3, __pyx_k_p1_2_3, sizeof(__pyx_k_p1_2_3), 0, 0, 1, 1}, + {&__pyx_n_s_p2, __pyx_k_p2, sizeof(__pyx_k_p2), 0, 0, 1, 1}, + {&__pyx_n_s_p3, __pyx_k_p3, sizeof(__pyx_k_p3), 0, 0, 1, 1}, + {&__pyx_n_s_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 0, 0, 1, 1}, + {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1}, + {&__pyx_n_s_q, __pyx_k_q, sizeof(__pyx_k_q), 0, 0, 1, 1}, + {&__pyx_n_s_qq, __pyx_k_qq, sizeof(__pyx_k_qq), 0, 0, 1, 1}, + {&__pyx_kp_u_quadratic_spline_requires_at_lea, __pyx_k_quadratic_spline_requires_at_lea, sizeof(__pyx_k_quadratic_spline_requires_at_lea), 0, 1, 0, 0}, + {&__pyx_n_s_quadratic_to_curves, __pyx_k_quadratic_to_curves, sizeof(__pyx_k_quadratic_to_curves), 0, 0, 1, 1}, + {&__pyx_n_u_quadratic_to_curves, __pyx_k_quadratic_to_curves, sizeof(__pyx_k_quadratic_to_curves), 0, 1, 0, 1}, + {&__pyx_n_s_quadratic_to_curves_locals_genex, __pyx_k_quadratic_to_curves_locals_genex, sizeof(__pyx_k_quadratic_to_curves_locals_genex), 0, 0, 1, 1}, + {&__pyx_n_s_quadratics, __pyx_k_quadratics, sizeof(__pyx_k_quadratics), 0, 0, 1, 1}, + {&__pyx_n_s_quads, __pyx_k_quads, sizeof(__pyx_k_quads), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_real, __pyx_k_real, sizeof(__pyx_k_real), 0, 0, 1, 1}, + {&__pyx_n_s_reconst, __pyx_k_reconst, sizeof(__pyx_k_reconst), 0, 0, 1, 1}, + {&__pyx_n_s_reconstruct_tolerance, __pyx_k_reconstruct_tolerance, sizeof(__pyx_k_reconstruct_tolerance), 0, 0, 1, 1}, + {&__pyx_n_s_reconstructed, __pyx_k_reconstructed, sizeof(__pyx_k_reconstructed), 0, 0, 1, 1}, + {&__pyx_n_s_reconstructed_iter, __pyx_k_reconstructed_iter, sizeof(__pyx_k_reconstructed_iter), 0, 0, 1, 1}, + {&__pyx_n_s_return, __pyx_k_return, sizeof(__pyx_k_return), 0, 0, 1, 1}, + {&__pyx_n_s_reversed, __pyx_k_reversed, sizeof(__pyx_k_reversed), 0, 0, 1, 1}, + {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1}, + {&__pyx_n_s_sols, __pyx_k_sols, sizeof(__pyx_k_sols), 0, 0, 1, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_spline_to_curves, __pyx_k_spline_to_curves, sizeof(__pyx_k_spline_to_curves), 0, 0, 1, 1}, + {&__pyx_n_s_spline_to_curves_locals_genexpr, __pyx_k_spline_to_curves_locals_genexpr, sizeof(__pyx_k_spline_to_curves_locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_splitCubicAtTC, __pyx_k_splitCubicAtTC, sizeof(__pyx_k_splitCubicAtTC), 0, 0, 1, 1}, + {&__pyx_n_s_splits, __pyx_k_splits, sizeof(__pyx_k_splits), 0, 0, 1, 1}, + {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, + {&__pyx_n_s_start_index, __pyx_k_start_index, sizeof(__pyx_k_start_index), 0, 0, 1, 1}, + {&__pyx_n_u_start_index, __pyx_k_start_index, sizeof(__pyx_k_start_index), 0, 1, 0, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_this_count, __pyx_k_this_count, sizeof(__pyx_k_this_count), 0, 0, 1, 1}, + {&__pyx_n_s_this_sol_count, __pyx_k_this_sol_count, sizeof(__pyx_k_this_sol_count), 0, 0, 1, 1}, + {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1}, + {&__pyx_n_s_tolerance, __pyx_k_tolerance, sizeof(__pyx_k_tolerance), 0, 0, 1, 1}, + {&__pyx_n_s_ts, __pyx_k_ts, sizeof(__pyx_k_ts), 0, 0, 1, 1}, + {&__pyx_n_s_typing, __pyx_k_typing, sizeof(__pyx_k_typing), 0, 0, 1, 1}, + {&__pyx_n_s_u, __pyx_k_u, sizeof(__pyx_k_u), 0, 0, 1, 1}, + {&__pyx_n_s_v, __pyx_k_v, sizeof(__pyx_k_v), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, + {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 23, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(0, 23, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 127, __pyx_L1_error) + __pyx_builtin_AssertionError = __Pyx_GetBuiltinName(__pyx_n_s_AssertionError); if (!__pyx_builtin_AssertionError) __PYX_ERR(0, 132, __pyx_L1_error) + __pyx_builtin_ZeroDivisionError = __Pyx_GetBuiltinName(__pyx_n_s_ZeroDivisionError); if (!__pyx_builtin_ZeroDivisionError) __PYX_ERR(0, 320, __pyx_L1_error) + __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(0, 329, __pyx_L1_error) + __pyx_builtin_reversed = __Pyx_GetBuiltinName(__pyx_n_s_reversed); if (!__pyx_builtin_reversed) __PYX_ERR(0, 378, __pyx_L1_error) + __pyx_builtin_zip = __Pyx_GetBuiltinName(__pyx_n_s_zip); if (!__pyx_builtin_zip) __PYX_ERR(0, 378, __pyx_L1_error) + __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 397, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/qu2cu/qu2cu.py":229 + * costs.append(cost) + * costs.append(cost) + * qq = add_implicit_on_curves(p)[1:] # <<<<<<<<<<<<<< + * costs.pop() + * q.extend(qq) + */ + __pyx_slice_ = PySlice_New(__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_slice_)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_slice_); + __Pyx_GIVEREF(__pyx_slice_); + + /* "fontTools/qu2cu/qu2cu.py":296 + * # Dynamic-Programming to find the solution with fewest number of + * # cubic curves, and within those the one with smallest error. + * sols = [Solution(0, 0, 0, False)] # <<<<<<<<<<<<<< + * impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) + * start = 0 + */ + __pyx_tuple__2 = PyTuple_Pack(4, __pyx_int_0, __pyx_int_0, __pyx_int_0, Py_False); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "fontTools/qu2cu/qu2cu.py":85 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + __pyx_tuple__5 = PyTuple_Pack(4, __pyx_n_s_p0, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p1_2_3); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_n_s_elevate_quadratic, 85, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 85, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":157 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * count=cython.int, + * num_offcurves=cython.int, + */ + __pyx_tuple__7 = PyTuple_Pack(8, __pyx_n_s_p, __pyx_n_s_count, __pyx_n_s_num_offcurves, __pyx_n_s_i, __pyx_n_s_off1, __pyx_n_s_off2, __pyx_n_s_on, __pyx_n_s_q); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_n_s_add_implicit_on_curves, 157, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 157, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + __pyx_tuple__9 = PyTuple_Pack(17, __pyx_n_s_quads, __pyx_n_s_max_err, __pyx_n_s_all_cubic, __pyx_n_s_cost, __pyx_n_s_is_complex, __pyx_n_s_q, __pyx_n_s_costs, __pyx_n_s_p, __pyx_n_s_i, __pyx_n_s_qq, __pyx_n_s_curves, __pyx_n_s_p, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_curve, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 17, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_n_s_quadratic_to_curves, 181, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) __PYX_ERR(0, 181, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + __pyx_tuple__11 = PyTuple_Pack(42, __pyx_n_s_q, __pyx_n_s_costs, __pyx_n_s_tolerance, __pyx_n_s_all_cubic, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_start, __pyx_n_s_i_sol_count, __pyx_n_s_j_sol_count, __pyx_n_s_this_sol_count, __pyx_n_s_err, __pyx_n_s_error, __pyx_n_s_i_sol_error, __pyx_n_s_j_sol_error, __pyx_n_s_is_cubic, __pyx_n_s_count, __pyx_n_s_p0, __pyx_n_s_p1, __pyx_n_s_p2, __pyx_n_s_p3, __pyx_n_s_v, __pyx_n_s_u, __pyx_n_s_elevated_quadratics, __pyx_n_s_forced, __pyx_n_s_sols, __pyx_n_s_impossible, __pyx_n_s_best_sol, __pyx_n_s_this_count, __pyx_n_s_i_sol, __pyx_n_s_curve, __pyx_n_s_ts, __pyx_n_s_reconstructed_iter, __pyx_n_s_reconstructed, __pyx_n_s_reconst, __pyx_n_s_orig, __pyx_n_s_splits, __pyx_n_s_cubic, __pyx_n_s_curves, __pyx_n_s_i, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 42, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_n_s_spline_to_curves, 245, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) __PYX_ERR(0, 245, __pyx_L1_error) + + /* "fontTools/qu2cu/qu2cu.py":389 + * + * + * def main(): # <<<<<<<<<<<<<< + * from fontTools.cu2qu.benchmark import generate_curve + * from fontTools.cu2qu import curve_to_quadratic + */ + __pyx_tuple__13 = PyTuple_Pack(7, __pyx_n_s_generate_curve, __pyx_n_s_curve_to_quadratic, __pyx_n_s_tolerance, __pyx_n_s_reconstruct_tolerance, __pyx_n_s_curve, __pyx_n_s_quadratics, __pyx_n_s_curves); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 389, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Lib_fontTools_qu2cu_qu2cu_py, __pyx_n_s_main_2, 389, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 389, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + __pyx_umethod_PyList_Type_pop.type = (PyObject*)&PyList_Type; + __pyx_umethod_PyList_Type_pop.method_name = &__pyx_n_s_pop; + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + /* AssertionsEnabled.init */ + if (likely(__Pyx_init_assertions_enabled() == 0)); else + +if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr)) __PYX_ERR(0, 238, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr_spec, __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr) < 0) __PYX_ERR(0, 238, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr = &__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr) < 0) __PYX_ERR(0, 238, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr->tp_dictoffset && __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct__genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr)) __PYX_ERR(0, 343, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr_spec, __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 343, __pyx_L1_error) + #else + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr = &__pyx_type_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 343, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr->tp_dictoffset && __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_9fontTools_5qu2cu_5qu2cu___pyx_scope_struct_1_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_qu2cu(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_qu2cu}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "qu2cu", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initqu2cu(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initqu2cu(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_qu2cu(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_qu2cu(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_qu2cu(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'qu2cu' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("qu2cu", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to qu2cu pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_qu2cu(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_fontTools__qu2cu__qu2cu) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.qu2cu.qu2cu")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.qu2cu.qu2cu", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "fontTools/qu2cu/qu2cu.py":19 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "fontTools/qu2cu/qu2cu.py":22 + * import cython + * + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_True) < 0) __PYX_ERR(0, 22, __pyx_L2_error) + + /* "fontTools/qu2cu/qu2cu.py":19 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L7_try_end; + __pyx_L2_error:; + + /* "fontTools/qu2cu/qu2cu.py":23 + * + * COMPILED = cython.compiled + * except (AttributeError, ImportError): # <<<<<<<<<<<<<< + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches2(__pyx_builtin_AttributeError, __pyx_builtin_ImportError); + if (__pyx_t_4) { + __Pyx_AddTraceback("fontTools.qu2cu.qu2cu", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 23, __pyx_L4_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/qu2cu/qu2cu.py":25 + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython # <<<<<<<<<<<<<< + * + * COMPILED = False + */ + __pyx_t_8 = PyList_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 25, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_n_s_cython); + __Pyx_GIVEREF(__pyx_n_s_cython); + if (__Pyx_PyList_SET_ITEM(__pyx_t_8, 0, __pyx_n_s_cython)) __PYX_ERR(0, 25, __pyx_L4_except_error); + __pyx_t_9 = __Pyx_Import(__pyx_n_s_fontTools_misc, __pyx_t_8, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 25, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_ImportFrom(__pyx_t_9, __pyx_n_s_cython); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 25, __pyx_L4_except_error) + __Pyx_GOTREF(__pyx_t_8); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cython, __pyx_t_8) < 0) __PYX_ERR(0, 25, __pyx_L4_except_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/qu2cu/qu2cu.py":27 + * from fontTools.misc import cython + * + * COMPILED = False # <<<<<<<<<<<<<< + * + * from fontTools.misc.bezierTools import splitCubicAtTC + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_COMPILED, Py_False) < 0) __PYX_ERR(0, 27, __pyx_L4_except_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L3_exception_handled; + } + goto __pyx_L4_except_error; + + /* "fontTools/qu2cu/qu2cu.py":19 + * # limitations under the License. + * + * try: # <<<<<<<<<<<<<< + * import cython + * + */ + __pyx_L4_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L3_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + __pyx_L7_try_end:; + } + + /* "fontTools/qu2cu/qu2cu.py":29 + * COMPILED = False + * + * from fontTools.misc.bezierTools import splitCubicAtTC # <<<<<<<<<<<<<< + * from collections import namedtuple + * import math + */ + __pyx_t_7 = PyList_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_s_splitCubicAtTC); + __Pyx_GIVEREF(__pyx_n_s_splitCubicAtTC); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_n_s_splitCubicAtTC)) __PYX_ERR(0, 29, __pyx_L1_error); + __pyx_t_6 = __Pyx_Import(__pyx_n_s_fontTools_misc_bezierTools, __pyx_t_7, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_splitCubicAtTC); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_splitCubicAtTC, __pyx_t_7) < 0) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":30 + * + * from fontTools.misc.bezierTools import splitCubicAtTC + * from collections import namedtuple # <<<<<<<<<<<<<< + * import math + * from typing import ( + */ + __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_n_s_namedtuple); + __Pyx_GIVEREF(__pyx_n_s_namedtuple); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_n_s_namedtuple)) __PYX_ERR(0, 30, __pyx_L1_error); + __pyx_t_7 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_6, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_ImportFrom(__pyx_t_7, __pyx_n_s_namedtuple); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_namedtuple, __pyx_t_6) < 0) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":31 + * from fontTools.misc.bezierTools import splitCubicAtTC + * from collections import namedtuple + * import math # <<<<<<<<<<<<<< + * from typing import ( + * List, + */ + __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_math, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_math, __pyx_t_7) < 0) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/qu2cu/qu2cu.py":33 + * import math + * from typing import ( + * List, # <<<<<<<<<<<<<< + * Tuple, + * Union, + */ + __pyx_t_7 = PyList_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_n_s_List); + __Pyx_GIVEREF(__pyx_n_s_List); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 0, __pyx_n_s_List)) __PYX_ERR(0, 33, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_Tuple); + __Pyx_GIVEREF(__pyx_n_s_Tuple); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 1, __pyx_n_s_Tuple)) __PYX_ERR(0, 33, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_s_Union); + __Pyx_GIVEREF(__pyx_n_s_Union); + if (__Pyx_PyList_SET_ITEM(__pyx_t_7, 2, __pyx_n_s_Union)) __PYX_ERR(0, 33, __pyx_L1_error); + + /* "fontTools/qu2cu/qu2cu.py":32 + * from collections import namedtuple + * import math + * from typing import ( # <<<<<<<<<<<<<< + * List, + * Tuple, + */ + __pyx_t_6 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_7, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_List); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_7) < 0) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_7) < 0) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_7) < 0) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":39 + * + * + * __all__ = ["quadratic_to_curves"] # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_n_u_quadratic_to_curves); + __Pyx_GIVEREF(__pyx_n_u_quadratic_to_curves); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_n_u_quadratic_to_curves)) __PYX_ERR(0, 39, __pyx_L1_error); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_6) < 0) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":85 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * p0=cython.complex, + * p1=cython.complex, + */ + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5qu2cu_5qu2cu_1elevate_quadratic, 0, __pyx_n_s_elevate_quadratic, NULL, __pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_d, ((PyObject *)__pyx_codeobj__6)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_elevate_quadratic, __pyx_t_6) < 0) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":157 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * count=cython.int, + * num_offcurves=cython.int, + */ + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5qu2cu_5qu2cu_3add_implicit_on_curves, 0, __pyx_n_s_add_implicit_on_curves, NULL, __pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_d, ((PyObject *)__pyx_codeobj__8)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_add_implicit_on_curves, __pyx_t_6) < 0) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":178 + * + * + * Point = Union[Tuple[float, float], complex] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF((PyObject *)(&PyFloat_Type)); + __Pyx_GIVEREF((PyObject *)(&PyFloat_Type)); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)))) __PYX_ERR(0, 178, __pyx_L1_error); + __Pyx_INCREF((PyObject *)(&PyFloat_Type)); + __Pyx_GIVEREF((PyObject *)(&PyFloat_Type)); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)(&PyFloat_Type)))) __PYX_ERR(0, 178, __pyx_L1_error); + __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9)) __PYX_ERR(0, 178, __pyx_L1_error); + __Pyx_INCREF((PyObject *)(&PyComplex_Type)); + __Pyx_GIVEREF((PyObject *)(&PyComplex_Type)); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)(&PyComplex_Type)))) __PYX_ERR(0, 178, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Point, __pyx_t_9) < 0) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/qu2cu/qu2cu.py":187 + * def quadratic_to_curves( + * quads: List[List[Point]], + * max_err: float = 0.5, # <<<<<<<<<<<<<< + * all_cubic: bool = False, + * ) -> List[Tuple[Point, ...]]: + */ + __pyx_t_9 = PyFloat_FromDouble(((double)0.5)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 187, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + + /* "fontTools/qu2cu/qu2cu.py":181 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * cost=cython.int, + * is_complex=cython.int, + */ + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9)) __PYX_ERR(0, 181, __pyx_L1_error); + __Pyx_INCREF(((PyObject *)Py_False)); + __Pyx_GIVEREF(((PyObject *)Py_False)); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)Py_False))) __PYX_ERR(0, 181, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_quads, __pyx_kp_s_List_List_Point) < 0) __PYX_ERR(0, 181, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_max_err, __pyx_n_s_float) < 0) __PYX_ERR(0, 181, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_all_cubic, __pyx_n_s_bool) < 0) __PYX_ERR(0, 181, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_return, __pyx_kp_s_List_Tuple_Point) < 0) __PYX_ERR(0, 181, __pyx_L1_error) + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5qu2cu_5qu2cu_5quadratic_to_curves, 0, __pyx_n_s_quadratic_to_curves, NULL, __pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_d, ((PyObject *)__pyx_codeobj__10)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_6, __pyx_t_5); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_9); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_quadratic_to_curves, __pyx_t_6) < 0) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":242 + * + * + * Solution = namedtuple("Solution", ["num_points", "error", "start_index", "is_cubic"]) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_namedtuple); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 = PyList_New(4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_n_u_num_points); + __Pyx_GIVEREF(__pyx_n_u_num_points); + if (__Pyx_PyList_SET_ITEM(__pyx_t_9, 0, __pyx_n_u_num_points)) __PYX_ERR(0, 242, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_error); + __Pyx_GIVEREF(__pyx_n_u_error); + if (__Pyx_PyList_SET_ITEM(__pyx_t_9, 1, __pyx_n_u_error)) __PYX_ERR(0, 242, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_start_index); + __Pyx_GIVEREF(__pyx_n_u_start_index); + if (__Pyx_PyList_SET_ITEM(__pyx_t_9, 2, __pyx_n_u_start_index)) __PYX_ERR(0, 242, __pyx_L1_error); + __Pyx_INCREF(__pyx_n_u_is_cubic); + __Pyx_GIVEREF(__pyx_n_u_is_cubic); + if (__Pyx_PyList_SET_ITEM(__pyx_t_9, 3, __pyx_n_u_is_cubic)) __PYX_ERR(0, 242, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_n_u_Solution); + __Pyx_GIVEREF(__pyx_n_u_Solution); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_n_u_Solution)) __PYX_ERR(0, 242, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_9)) __PYX_ERR(0, 242, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_5, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Solution, __pyx_t_9) < 0) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/qu2cu/qu2cu.py":268 + * u=cython.complex, + * ) + * def spline_to_curves(q, costs, tolerance=0.5, all_cubic=False): # <<<<<<<<<<<<<< + * """ + * q: quadratic spline with alternating on-curve / off-curve points. + */ + __pyx_t_9 = PyFloat_FromDouble(((double)0.5)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 268, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_5 = __Pyx_PyBool_FromLong(((int)0)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 268, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "fontTools/qu2cu/qu2cu.py":245 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * i=cython.int, + * j=cython.int, + */ + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_9)) __PYX_ERR(0, 245, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5)) __PYX_ERR(0, 245, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5qu2cu_5qu2cu_7spline_to_curves, 0, __pyx_n_s_spline_to_curves, NULL, __pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_d, ((PyObject *)__pyx_codeobj__12)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_5, __pyx_t_6); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_spline_to_curves, __pyx_t_5) < 0) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/qu2cu/qu2cu.py":389 + * + * + * def main(): # <<<<<<<<<<<<<< + * from fontTools.cu2qu.benchmark import generate_curve + * from fontTools.cu2qu import curve_to_quadratic + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_5qu2cu_5qu2cu_9main, 0, __pyx_n_s_main_2, NULL, __pyx_n_s_fontTools_qu2cu_qu2cu, __pyx_d, ((PyObject *)__pyx_codeobj__14)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 389, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_main_2, __pyx_t_5) < 0) __PYX_ERR(0, 389, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/qu2cu/qu2cu.py":407 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * main() + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_10 = (__Pyx_PyUnicode_Equals(__pyx_t_5, __pyx_n_u_main, Py_EQ)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 407, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__pyx_t_10) { + + /* "fontTools/qu2cu/qu2cu.py":408 + * + * if __name__ == "__main__": + * main() # <<<<<<<<<<<<<< + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_main_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/qu2cu/qu2cu.py":407 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * main() + */ + } + + /* "fontTools/qu2cu/qu2cu.py":1 + * # cython: language_level=3 # <<<<<<<<<<<<<< + * # distutils: define_macros=CYTHON_TRACE_NOGIL=1 + * + */ + __pyx_t_6 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_6) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.qu2cu.qu2cu", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.qu2cu.qu2cu"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; // error + return kwvalues[i]; + } + } + return NULL; // not found (no exception set) +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); // transfer ownership of value to values + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; // ownership transferred to values +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_subscript) { + PyObject *r, *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* py_abs */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) { +#if PY_VERSION_HEX >= 0x030C00A7 + if (likely(__Pyx_PyLong_IsCompact(n))) { + return PyLong_FromSize_t(__Pyx_PyLong_CompactValueUnsigned(n)); + } +#else + if (likely(Py_SIZE(n) == -1)) { + return PyLong_FromUnsignedLong(__Pyx_PyLong_Digits(n)[0]); + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + { + PyObject *copy = _PyLong_Copy((PyLongObject*)n); + if (likely(copy)) { + #if PY_VERSION_HEX >= 0x030C00A7 + ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK; + #else + __Pyx_SET_SIZE(copy, -Py_SIZE(copy)); + #endif + } + return copy; + } +#else + return PyNumber_Negative(n); +#endif +} +#endif + +/* SliceTupleAndList */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_crop_slice(Py_ssize_t* _start, Py_ssize_t* _stop, Py_ssize_t* _length) { + Py_ssize_t start = *_start, stop = *_stop, length = *_length; + if (start < 0) { + start += length; + if (start < 0) + start = 0; + } + if (stop < 0) + stop += length; + else if (stop > length) + stop = length; + *_length = stop - start; + *_start = start; + *_stop = stop; +} +static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice( + PyObject* src, Py_ssize_t start, Py_ssize_t stop) { + Py_ssize_t length = PyList_GET_SIZE(src); + __Pyx_crop_slice(&start, &stop, &length); + if (length <= 0) { + return PyList_New(0); + } + return __Pyx_PyList_FromArray(((PyListObject*)src)->ob_item + start, length); +} +static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice( + PyObject* src, Py_ssize_t start, Py_ssize_t stop) { + Py_ssize_t length = PyTuple_GET_SIZE(src); + __Pyx_crop_slice(&start, &stop, &length); + return __Pyx_PyTuple_FromArray(((PyTupleObject*)src)->ob_item + start, length); +} +#endif + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op2))) { + const long a = intval; + long x; + long b = PyInt_AS_LONG(op2); + + x = (long)((unsigned long)a - (unsigned long)b); + if (likely((x^a) >= 0 || (x^~b) >= 0)) + return PyInt_FromLong(x); + return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op2))) { + const long a = intval; + long b, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG lla = intval; + PY_LONG_LONG llb, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op2))) { + return __Pyx_NewRef(op1); + } + if (likely(__Pyx_PyLong_IsCompact(op2))) { + b = __Pyx_PyLong_CompactValue(op2); + } else { + const digit* digits = __Pyx_PyLong_Digits(op2); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op2); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + b = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + b = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + b = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + b = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + b = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + llb = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + b = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + } + x = a - b; + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla - llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op2)) { + const long a = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double b = __pyx_PyFloat_AsDouble(op2); +#else + double b = PyFloat_AS_DOUBLE(op2); +#endif + double result; + + PyFPE_START_PROTECT("subtract", return NULL) + result = ((double)a) - (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2); +} +#endif + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + type_name = __Pyx_PyType_GetName(type); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* RaiseUnboundLocalError */ +static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { + PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* pep479 */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) { + PyObject *exc, *val, *tb, *cur_exc; + __Pyx_PyThreadState_declare + #ifdef __Pyx_StopAsyncIteration_USED + int is_async_stopiteration = 0; + #endif + CYTHON_MAYBE_UNUSED_VAR(in_async_gen); + cur_exc = PyErr_Occurred(); + if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) { + #ifdef __Pyx_StopAsyncIteration_USED + if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) { + is_async_stopiteration = 1; + } else + #endif + return; + } + __Pyx_PyThreadState_assign + __Pyx_GetException(&exc, &val, &tb); + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + PyErr_SetString(PyExc_RuntimeError, + #ifdef __Pyx_StopAsyncIteration_USED + is_async_stopiteration ? "async generator raised StopAsyncIteration" : + in_async_gen ? "async generator raised StopIteration" : + #endif + "generator raised StopIteration"); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + PyObject* exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#elif CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* SliceObject */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, + Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, + int has_cstart, int has_cstop, int wraparound) { + __Pyx_TypeName obj_type_name; +#if CYTHON_USE_TYPE_SLOTS + PyMappingMethods* mp; +#if PY_MAJOR_VERSION < 3 + PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence; + if (likely(ms && ms->sq_slice)) { + if (!has_cstart) { + if (_py_start && (*_py_start != Py_None)) { + cstart = __Pyx_PyIndex_AsSsize_t(*_py_start); + if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; + } else + cstart = 0; + } + if (!has_cstop) { + if (_py_stop && (*_py_stop != Py_None)) { + cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop); + if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; + } else + cstop = PY_SSIZE_T_MAX; + } + if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) { + Py_ssize_t l = ms->sq_length(obj); + if (likely(l >= 0)) { + if (cstop < 0) { + cstop += l; + if (cstop < 0) cstop = 0; + } + if (cstart < 0) { + cstart += l; + if (cstart < 0) cstart = 0; + } + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + goto bad; + PyErr_Clear(); + } + } + return ms->sq_slice(obj, cstart, cstop); + } +#else + CYTHON_UNUSED_VAR(wraparound); +#endif + mp = Py_TYPE(obj)->tp_as_mapping; + if (likely(mp && mp->mp_subscript)) +#else + CYTHON_UNUSED_VAR(wraparound); +#endif + { + PyObject* result; + PyObject *py_slice, *py_start, *py_stop; + if (_py_slice) { + py_slice = *_py_slice; + } else { + PyObject* owned_start = NULL; + PyObject* owned_stop = NULL; + if (_py_start) { + py_start = *_py_start; + } else { + if (has_cstart) { + owned_start = py_start = PyInt_FromSsize_t(cstart); + if (unlikely(!py_start)) goto bad; + } else + py_start = Py_None; + } + if (_py_stop) { + py_stop = *_py_stop; + } else { + if (has_cstop) { + owned_stop = py_stop = PyInt_FromSsize_t(cstop); + if (unlikely(!py_stop)) { + Py_XDECREF(owned_start); + goto bad; + } + } else + py_stop = Py_None; + } + py_slice = PySlice_New(py_start, py_stop, Py_None); + Py_XDECREF(owned_start); + Py_XDECREF(owned_stop); + if (unlikely(!py_slice)) goto bad; + } +#if CYTHON_USE_TYPE_SLOTS + result = mp->mp_subscript(obj, py_slice); +#else + result = PyObject_GetItem(obj, py_slice); +#endif + if (!_py_slice) { + Py_DECREF(py_slice); + } + return result; + } + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is unsliceable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); +bad: + return NULL; +} + +/* PyObjectCallNoArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#elif PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* UnpackUnboundCMethod */ +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + PyObject *result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), + METH_VARARGS | METH_KEYWORDS, + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + target->method = method; +#if CYTHON_COMPILING_IN_CPYTHON + #if PY_MAJOR_VERSION >= 3 + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + #else + if (likely(!__Pyx_CyOrPyCFunction_Check(method))) + #endif + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + target->method = unbound_method; + } + } + return 0; +} + +/* CallUnboundCMethod0 */ +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *args, *result = NULL; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_ASSUME_SAFE_MACROS + args = PyTuple_New(1); + if (unlikely(!args)) goto bad; + Py_INCREF(self); + PyTuple_SET_ITEM(args, 0, self); +#else + args = PyTuple_Pack(1, self); + if (unlikely(!args)) goto bad; +#endif + result = __Pyx_PyObject_Call(cfunc->method, args, NULL); + Py_DECREF(args); +bad: + return result; +} + +/* pop */ +static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) { + if (__Pyx_IS_TYPE(L, &PySet_Type)) { + return PySet_Pop(L); + } + return __Pyx_PyObject_CallMethod0(L, __pyx_n_s_pop); +} +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) { + if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) { + __Pyx_SET_SIZE(L, Py_SIZE(L) - 1); + return PyList_GET_ITEM(L, PyList_GET_SIZE(L)); + } + return __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyList_Type_pop, L); +} +#endif + +/* RaiseUnexpectedTypeError */ +static int +__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) +{ + __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, + expected, obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* PyIntBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long x; + long a = PyInt_AS_LONG(op1); + + x = (long)((unsigned long)a + (unsigned long)b); + if (likely((x^a) >= 0 || (x^b) >= 0)) + return PyInt_FromLong(x); + return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + const long b = intval; + long a, x; +#ifdef HAVE_LONG_LONG + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla, llx; +#endif + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return __Pyx_NewRef(op2); + } + if (likely(__Pyx_PyLong_IsCompact(op1))) { + a = __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case -4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + break; + #ifdef HAVE_LONG_LONG + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + goto long_long; + #endif + } + CYTHON_FALLTHROUGH; + default: return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + } + x = a + b; + return PyLong_FromLong(x); +#ifdef HAVE_LONG_LONG + long_long: + llx = lla + llb; + return PyLong_FromLongLong(llx); +#endif + + + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; +#if CYTHON_COMPILING_IN_LIMITED_API + double a = __pyx_PyFloat_AsDouble(op1); +#else + double a = PyFloat_AS_DOUBLE(op1); +#endif + double result; + + PyFPE_START_PROTECT("add", return NULL) + result = ((double)a) + (double)b; + PyFPE_END_PROTECT(result) + return PyFloat_FromDouble(result); + } + return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* pyfrozenset_new */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it) { + if (it) { + PyObject* result; +#if CYTHON_COMPILING_IN_PYPY + PyObject* args; + args = PyTuple_Pack(1, it); + if (unlikely(!args)) + return NULL; + result = PyObject_Call((PyObject*)&PyFrozenSet_Type, args, NULL); + Py_DECREF(args); + return result; +#else + if (PyFrozenSet_CheckExact(it)) { + Py_INCREF(it); + return it; + } + result = PyFrozenSet_New(it); + if (unlikely(!result)) + return NULL; + if ((PY_VERSION_HEX >= 0x031000A1) || likely(PySet_GET_SIZE(result))) + return result; + Py_DECREF(result); +#endif + } +#if CYTHON_USE_TYPE_SLOTS + return PyFrozenSet_Type.tp_new(&PyFrozenSet_Type, __pyx_empty_tuple, NULL); +#else + return PyObject_Call((PyObject*)&PyFrozenSet_Type, __pyx_empty_tuple, NULL); +#endif +} + +/* PySetContains */ +static int __Pyx_PySet_ContainsUnhashable(PyObject *set, PyObject *key) { + int result = -1; + if (PySet_Check(key) && PyErr_ExceptionMatches(PyExc_TypeError)) { + PyObject *tmpkey; + PyErr_Clear(); + tmpkey = __Pyx_PyFrozenSet_New(key); + if (tmpkey != NULL) { + result = PySet_Contains(set, tmpkey); + Py_DECREF(tmpkey); + } + } + return result; +} +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq) { + int result = PySet_Contains(set, key); + if (unlikely(result < 0)) { + result = __Pyx_PySet_ContainsUnhashable(set, key); + } + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__3); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* FixUpExtensionType */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* ValidateBasesTuple */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_MACROS + n = PyTuple_GET_SIZE(bases); +#else + n = PyTuple_Size(bases); + if (n < 0) return -1; +#endif + for (i = 1; i < n; i++) + { +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + PyTypeObject *b; +#if PY_MAJOR_VERSION < 3 + if (PyClass_Check(b0)) + { + PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", + PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + if (dictoffset == 0) + { + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + } + return 0; +} +#endif + +/* PyType_Ready */ +static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) + gc = PyImport_GetModule(__pyx_kp_u_gc); + #endif + if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); + return -1; + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } + #endif + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); + #endif + } +#endif + return r; +#endif +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, attr_name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(attr_name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; +} +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__4; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); +} + +/* FetchSharedCythonModule */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* PyVectorcallFastCallDict */ +#if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { + PyObject *runerr = NULL; + Py_ssize_t key_value; + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + __Pyx_TypeName index_type_name = __Pyx_PyType_GetName(Py_TYPE(index)); + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); + __Pyx_DECREF_TypeName(index_type_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { + __Pyx_TypeName obj_type_name; + if (likely(PyType_Check(obj))) { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_n_s_class_getitem); + if (!meth) { + PyErr_Clear(); + } else { + PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); + Py_DECREF(meth); + return result; + } + } + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { + PyTypeObject *tp = Py_TYPE(obj); + PyMappingMethods *mm = tp->tp_as_mapping; + PySequenceMethods *sm = tp->tp_as_sequence; + if (likely(mm && mm->mp_subscript)) { + return mm->mp_subscript(obj, key); + } + if (likely(sm && sm->sq_item)) { + return __Pyx_PyObject_GetIndex(obj, key); + } + return __Pyx_PyObject_GetItem_Slow(obj, key); +} +#endif + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* Declarations */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = (double)(1.0) / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = (double)(1.0) / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* FromPy */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject* o) { + Py_complex cval; +#if !CYTHON_COMPILING_IN_PYPY + if (PyComplex_CheckExact(o)) + cval = ((PyComplexObject *)o)->cval; + else +#endif + cval = PyComplex_AsCComplex(o); + return __pyx_t_double_complex_from_parts( + (double)cval.real, + (double)cval.imag); +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__15); + } + return name; +} +#endif + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); +#if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } +#endif + if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallMethod1 */ +#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2 + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_GetMethod; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* CoroutineBase */ +#include +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *__pyx_tstate, PyObject **pvalue) { + PyObject *et, *ev, *tb; + PyObject *value = NULL; + CYTHON_UNUSED_VAR(__pyx_tstate); + __Pyx_ErrFetch(&et, &ev, &tb); + if (!et) { + Py_XDECREF(tb); + Py_XDECREF(ev); + Py_INCREF(Py_None); + *pvalue = Py_None; + return 0; + } + if (likely(et == PyExc_StopIteration)) { + if (!ev) { + Py_INCREF(Py_None); + value = Py_None; + } +#if PY_VERSION_HEX >= 0x030300A0 + else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } +#endif + else if (unlikely(PyTuple_Check(ev))) { + if (PyTuple_GET_SIZE(ev) >= 1) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + value = PyTuple_GET_ITEM(ev, 0); + Py_INCREF(value); +#else + value = PySequence_ITEM(ev, 0); +#endif + } else { + Py_INCREF(Py_None); + value = Py_None; + } + Py_DECREF(ev); + } + else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { + value = ev; + } + if (likely(value)) { + Py_XDECREF(tb); + Py_DECREF(et); + *pvalue = value; + return 0; + } + } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + PyErr_NormalizeException(&et, &ev, &tb); + if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + Py_XDECREF(tb); + Py_DECREF(et); +#if PY_VERSION_HEX >= 0x030300A0 + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); +#else + { + PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args); + Py_DECREF(ev); + if (likely(args)) { + value = PySequence_GetItem(args, 0); + Py_DECREF(args); + } + if (unlikely(!value)) { + __Pyx_ErrRestore(NULL, NULL, NULL); + Py_INCREF(Py_None); + value = Py_None; + } + } +#endif + *pvalue = value; + return 0; +} +static CYTHON_INLINE +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_CLEAR(exc_state->exc_value); +#else + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +#endif +} +#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { + msg = "coroutine already executing"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { + msg = "async generator already executing"; + #endif + } else { + msg = "generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); +} +#define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_NotStartedError(PyObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(gen)) { + msg = "can't send non-None value to a just-started coroutine"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a just-started async generator"; + #endif + } else { + msg = "can't send non-None value to a just-started generator"; + } + PyErr_SetString(PyExc_TypeError, msg); +} +#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing) (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) { + CYTHON_MAYBE_UNUSED_VAR(gen); + CYTHON_MAYBE_UNUSED_VAR(closing); + #ifdef __Pyx_Coroutine_USED + if (!closing && __Pyx_Coroutine_Check(gen)) { + PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); + } else + #endif + if (value) { + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); + else + #endif + PyErr_SetNone(PyExc_StopIteration); + } +} +static +PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { + __Pyx_PyThreadState_declare + PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; + PyObject *retval; + assert(!self->is_running); + if (unlikely(self->resume_label == 0)) { + if (unlikely(value && value != Py_None)) { + return __Pyx_Coroutine_NotStartedError((PyObject*)self); + } + } + if (unlikely(self->resume_label == -1)) { + return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); + } +#if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + tstate = __pyx_tstate; +#else + tstate = __Pyx_PyThreadState_Current; +#endif + exc_state = &self->gi_exc_state; + if (exc_state->exc_value) { + #if CYTHON_COMPILING_IN_PYPY + #else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #elif PY_VERSION_HEX >= 0x030B00a4 + exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback; + #else + exc_tb = exc_state->exc_traceback; + #endif + if (exc_tb) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + assert(f->f_back == NULL); + #if PY_VERSION_HEX >= 0x030B00A1 + f->f_back = PyThreadState_GetFrame(tstate); + #else + Py_XINCREF(tstate->frame); + f->f_back = tstate->frame; + #endif + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + Py_DECREF(exc_tb); + #endif + } + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } else { + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } +#endif + self->is_running = 1; + retval = self->body(self, tstate, value); + self->is_running = 0; +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif + return retval; +} +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { +#if CYTHON_COMPILING_IN_PYPY + CYTHON_UNUSED_VAR(exc_state); +#else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 + if (!exc_state->exc_value) return; + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #else + exc_tb = exc_state->exc_traceback; + #endif + if (likely(exc_tb)) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + Py_CLEAR(f->f_back); + #if PY_VERSION_HEX >= 0x030B00a4 + Py_DECREF(exc_tb); + #endif + } +#endif +} +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_MethodReturn(PyObject* gen, PyObject *retval) { + CYTHON_MAYBE_UNUSED_VAR(gen); + if (unlikely(!retval)) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (!__Pyx_PyErr_Occurred()) { + PyObject *exc = PyExc_StopIteration; + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + exc = __Pyx_PyExc_StopAsyncIteration; + #endif + __Pyx_PyErr_SetNone(exc); + } + } + return retval; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) +static CYTHON_INLINE +PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) { +#if PY_VERSION_HEX <= 0x030A00A1 + return _PyGen_Send(gen, arg); +#else + PyObject *result; + if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { +#if PY_VERSION_HEX < 0x030d00A1 + _PyGen_SetStopIterationValue(result); +#else + if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) { + PyErr_SetObject(PyExc_StopIteration, result); + } else { + PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result); + if (likely(exc != NULL)) { + PyErr_SetObject(PyExc_StopIteration, exc); + Py_DECREF(exc); + } + } +#endif + } + Py_DECREF(result); + result = NULL; + } + return result; +#endif +} +#endif +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { + PyObject *ret; + PyObject *val = NULL; + __Pyx_Coroutine_Undelegate(gen); + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); + ret = __Pyx_Coroutine_SendEx(gen, val, 0); + Py_XDECREF(val); + return ret; +} +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { + PyObject *retval; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + ret = __Pyx_async_gen_asend_send(yf, value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyCoro_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + { + if (value == Py_None) + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + else + ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value); + } + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + retval = __Pyx_Coroutine_FinishDelegation(gen); + } else { + retval = __Pyx_Coroutine_SendEx(gen, value, 0); + } + return __Pyx_Coroutine_MethodReturn(self, retval); +} +static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { + PyObject *retval = NULL; + int err = 0; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + if (__Pyx_CoroutineAwait_CheckExact(yf)) { + retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + retval = __Pyx_async_gen_asend_close(yf, NULL); + } else + if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { + retval = __Pyx_async_gen_athrow_close(yf, NULL); + } else + #endif + { + PyObject *meth; + gen->is_running = 1; + meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_close); + if (unlikely(!meth)) { + if (unlikely(PyErr_Occurred())) { + PyErr_WriteUnraisable(yf); + } + } else { + retval = __Pyx_PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (unlikely(!retval)) + err = -1; + } + gen->is_running = 0; + } + Py_XDECREF(retval); + return err; +} +static PyObject *__Pyx_Generator_Next(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Generator_Next(yf); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, Py_None); + } else + #endif + ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf); + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + return __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_SendEx(gen, Py_None, 0); +} +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); + return __Pyx_Coroutine_Close(self); +} +static PyObject *__Pyx_Coroutine_Close(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *retval, *raised_exception; + PyObject *yf = gen->yieldfrom; + int err = 0; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + Py_INCREF(yf); + err = __Pyx_Coroutine_CloseIter(gen, yf); + __Pyx_Coroutine_Undelegate(gen); + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + retval = __Pyx_Coroutine_SendEx(gen, NULL, 1); + if (unlikely(retval)) { + const char *msg; + Py_DECREF(retval); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(self)) { + msg = "coroutine ignored GeneratorExit"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(self)) { +#if PY_VERSION_HEX < 0x03060000 + msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)"; +#else + msg = "async generator ignored GeneratorExit"; +#endif + #endif + } else { + msg = "generator ignored GeneratorExit"; + } + PyErr_SetString(PyExc_RuntimeError, msg); + return NULL; + } + raised_exception = PyErr_Occurred(); + if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) { + if (raised_exception) PyErr_Clear(); + Py_INCREF(Py_None); + return Py_None; + } + return NULL; +} +static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, + PyObject *args, int close_on_genexit) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + Py_INCREF(yf); + if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { + int err = __Pyx_Coroutine_CloseIter(gen, yf); + Py_DECREF(yf); + __Pyx_Coroutine_Undelegate(gen); + if (err < 0) + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); + goto throw_here; + } + gen->is_running = 1; + if (0 + #ifdef __Pyx_Generator_USED + || __Pyx_Generator_CheckExact(yf) + #endif + #ifdef __Pyx_Coroutine_USED + || __Pyx_Coroutine_Check(yf) + #endif + ) { + ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { + ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); + #endif + } else { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_throw); + if (unlikely(!meth)) { + Py_DECREF(yf); + if (unlikely(PyErr_Occurred())) { + gen->is_running = 0; + return NULL; + } + __Pyx_Coroutine_Undelegate(gen); + gen->is_running = 0; + goto throw_here; + } + if (likely(args)) { + ret = __Pyx_PyObject_Call(meth, args, NULL); + } else { + PyObject *cargs[4] = {NULL, typ, val, tb}; + ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } + Py_DECREF(meth); + } + gen->is_running = 0; + Py_DECREF(yf); + if (!ret) { + ret = __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_MethodReturn(self, ret); + } +throw_here: + __Pyx_Raise(typ, val, tb, NULL); + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); +} +static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { + PyObject *typ; + PyObject *val = NULL; + PyObject *tb = NULL; + if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))) + return NULL; + return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); +} +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_VISIT(exc_state->exc_value); +#else + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); +#endif + return 0; +} +static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { + Py_VISIT(gen->closure); + Py_VISIT(gen->classobj); + Py_VISIT(gen->yieldfrom); + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); +} +static int __Pyx_Coroutine_clear(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + Py_CLEAR(gen->closure); + Py_CLEAR(gen->classobj); + Py_CLEAR(gen->yieldfrom); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); + } +#endif + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_frame); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + Py_CLEAR(gen->gi_modulename); + return 0; +} +static void __Pyx_Coroutine_dealloc(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject_GC_UnTrack(gen); + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); + if (gen->resume_label >= 0) { + PyObject_GC_Track(self); +#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE + if (unlikely(PyObject_CallFinalizerFromDealloc(self))) +#else + Py_TYPE(gen)->tp_del(self); + if (unlikely(Py_REFCNT(self) > 0)) +#endif + { + return; + } + PyObject_GC_UnTrack(self); + } +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); + } +#endif + __Pyx_Coroutine_clear(self); + __Pyx_PyHeapTypeObject_GC_Del(gen); +} +static void __Pyx_Coroutine_del(PyObject *self) { + PyObject *error_type, *error_value, *error_traceback; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PyThreadState_declare + if (gen->resume_label < 0) { + return; + } +#if !CYTHON_USE_TP_FINALIZE + assert(self->ob_refcnt == 0); + __Pyx_SET_REFCNT(self, 1); +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); + if (unlikely(!res)) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); + return; + } + } +#endif + if (unlikely(gen->resume_label == 0 && !error_value)) { +#ifdef __Pyx_Coroutine_USED +#ifdef __Pyx_Generator_USED + if (!__Pyx_Generator_CheckExact(self)) +#endif + { + PyObject_GC_UnTrack(self); +#if PY_MAJOR_VERSION >= 3 || defined(PyErr_WarnFormat) + if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) + PyErr_WriteUnraisable(self); +#else + {PyObject *msg; + char *cmsg; + #if CYTHON_COMPILING_IN_PYPY + msg = NULL; + cmsg = (char*) "coroutine was never awaited"; + #else + char *cname; + PyObject *qualname; + qualname = gen->gi_qualname; + cname = PyString_AS_STRING(qualname); + msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname); + if (unlikely(!msg)) { + PyErr_Clear(); + cmsg = (char*) "coroutine was never awaited"; + } else { + cmsg = PyString_AS_STRING(msg); + } + #endif + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) + PyErr_WriteUnraisable(self); + Py_XDECREF(msg);} +#endif + PyObject_GC_Track(self); + } +#endif + } else { + PyObject *res = __Pyx_Coroutine_Close(self); + if (unlikely(!res)) { + if (PyErr_Occurred()) + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); +#if !CYTHON_USE_TP_FINALIZE + assert(Py_REFCNT(self) > 0); + if (likely(--self->ob_refcnt == 0)) { + return; + } + { + Py_ssize_t refcnt = Py_REFCNT(self); + _Py_NewReference(self); + __Pyx_SET_REFCNT(self, refcnt); + } +#if CYTHON_COMPILING_IN_CPYTHON + assert(PyType_IS_GC(Py_TYPE(self)) && + _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + _Py_DEC_REFTOTAL; +#endif +#ifdef COUNT_ALLOCS + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; +#endif +#endif +} +static PyObject * +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_name; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_name, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_qualname; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_qualname, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context) +{ + PyObject *frame = self->gi_frame; + CYTHON_UNUSED_VAR(context); + if (!frame) { + if (unlikely(!self->gi_code)) { + Py_RETURN_NONE; + } + frame = (PyObject *) PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + (PyCodeObject*) self->gi_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (unlikely(!frame)) + return NULL; + self->gi_frame = frame; + } + Py_INCREF(frame); + return frame; +} +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); + if (unlikely(!gen)) + return NULL; + return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + gen->body = body; + gen->closure = closure; + Py_XINCREF(closure); + gen->is_running = 0; + gen->resume_label = 0; + gen->classobj = NULL; + gen->yieldfrom = NULL; + #if PY_VERSION_HEX >= 0x030B00a4 + gen->gi_exc_state.exc_value = NULL; + #else + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; + #endif +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif + gen->gi_weakreflist = NULL; + Py_XINCREF(qualname); + gen->gi_qualname = qualname; + Py_XINCREF(name); + gen->gi_name = name; + Py_XINCREF(module_name); + gen->gi_modulename = module_name; + Py_XINCREF(code); + gen->gi_code = code; + gen->gi_frame = NULL; + PyObject_GC_Track(gen); + return gen; +} + +/* PatchModuleWithCoroutine */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + int result; + PyObject *globals, *result_obj; + globals = PyDict_New(); if (unlikely(!globals)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_coroutine_type", + #ifdef __Pyx_Coroutine_USED + (PyObject*)__pyx_CoroutineType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_generator_type", + #ifdef __Pyx_Generator_USED + (PyObject*)__pyx_GeneratorType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore; + result_obj = PyRun_String(py_code, Py_file_input, globals, globals); + if (unlikely(!result_obj)) goto ignore; + Py_DECREF(result_obj); + Py_DECREF(globals); + return module; +ignore: + Py_XDECREF(globals); + PyErr_WriteUnraisable(module); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { + Py_DECREF(module); + module = NULL; + } +#else + py_code++; +#endif + return module; +} + +/* PatchGeneratorABC */ +#ifndef CYTHON_REGISTER_ABCS +#define CYTHON_REGISTER_ABCS 1 +#endif +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) +static PyObject* __Pyx_patch_abc_module(PyObject *module); +static PyObject* __Pyx_patch_abc_module(PyObject *module) { + module = __Pyx_Coroutine_patch_module( + module, "" +"if _cython_generator_type is not None:\n" +" try: Generator = _module.Generator\n" +" except AttributeError: pass\n" +" else: Generator.register(_cython_generator_type)\n" +"if _cython_coroutine_type is not None:\n" +" try: Coroutine = _module.Coroutine\n" +" except AttributeError: pass\n" +" else: Coroutine.register(_cython_coroutine_type)\n" + ); + return module; +} +#endif +static int __Pyx_patch_abc(void) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + static int abc_patched = 0; + if (CYTHON_REGISTER_ABCS && !abc_patched) { + PyObject *module; + module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections"); + if (unlikely(!module)) { + PyErr_WriteUnraisable(NULL); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, + ((PY_MAJOR_VERSION >= 3) ? + "Cython module failed to register with collections.abc module" : + "Cython module failed to register with collections module"), 1) < 0)) { + return -1; + } + } else { + module = __Pyx_patch_abc_module(module); + abc_patched = 1; + if (unlikely(!module)) + return -1; + Py_DECREF(module); + } + module = PyImport_ImportModule("backports_abc"); + if (module) { + module = __Pyx_patch_abc_module(module); + Py_XDECREF(module); + } + if (!module) { + PyErr_Clear(); + } + } +#else + if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL); +#endif + return 0; +} + +/* Generator */ +static PyMethodDef __pyx_Generator_methods[] = { + {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, + (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, + {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, + (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, + (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, + {0, 0, 0, 0} +}; +static PyMemberDef __pyx_Generator_memberlist[] = { + {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, + {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, + (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, + {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, + {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0}, +#if CYTHON_USE_TYPE_SPECS + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyGetSetDef __pyx_Generator_getsets[] = { + {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, + (char*) PyDoc_STR("name of the generator"), 0}, + {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, + (char*) PyDoc_STR("qualified name of the generator"), 0}, + {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL, + (char*) PyDoc_STR("Frame of the generator"), 0}, + {0, 0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_GeneratorType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc}, + {Py_tp_traverse, (void *)__Pyx_Coroutine_traverse}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_Generator_Next}, + {Py_tp_methods, (void *)__pyx_Generator_methods}, + {Py_tp_members, (void *)__pyx_Generator_memberlist}, + {Py_tp_getset, (void *)__pyx_Generator_getsets}, + {Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict}, +#if CYTHON_USE_TP_FINALIZE + {Py_tp_finalize, (void *)__Pyx_Coroutine_del}, +#endif + {0, 0}, +}; +static PyType_Spec __pyx_GeneratorType_spec = { + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + __pyx_GeneratorType_slots +}; +#else +static PyTypeObject __pyx_GeneratorType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, + (destructor) __Pyx_Coroutine_dealloc, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + 0, + (traverseproc) __Pyx_Coroutine_traverse, + 0, + 0, + offsetof(__pyx_CoroutineObject, gi_weakreflist), + 0, + (iternextfunc) __Pyx_Generator_Next, + __pyx_Generator_methods, + __pyx_Generator_memberlist, + __pyx_Generator_getsets, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if CYTHON_USE_TP_FINALIZE + 0, +#else + __Pyx_Coroutine_del, +#endif + 0, +#if CYTHON_USE_TP_FINALIZE + __Pyx_Coroutine_del, +#elif PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_Generator_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; + __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); +#endif + if (unlikely(!__pyx_GeneratorType)) { + return -1; + } + return 0; +} + +/* CheckBinaryVersion */ +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ +#if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..9db22bfb142b50cc3ef27e059eae4ca80d0b6a96 GIT binary patch literal 380407 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.py new file mode 100644 index 00000000..97a665f6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/qu2cu/qu2cu.py @@ -0,0 +1,408 @@ +# cython: language_level=3 +# distutils: define_macros=CYTHON_TRACE_NOGIL=1 + +# Copyright 2023 Google Inc. All Rights Reserved. +# Copyright 2023 Behdad Esfahbod. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +try: + import cython + + COMPILED = cython.compiled +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython + + COMPILED = False + +from fontTools.misc.bezierTools import splitCubicAtTC +from collections import namedtuple +import math +from typing import ( + List, + Tuple, + Union, +) + + +__all__ = ["quadratic_to_curves"] + + +# Copied from cu2qu +@cython.cfunc +@cython.returns(cython.int) +@cython.locals( + tolerance=cython.double, + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals(mid=cython.complex, deriv3=cython.complex) +def cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + """Check if a cubic Bezier lies within a given distance of the origin. + + "Origin" means *the* origin (0,0), not the start of the curve. Note that no + checks are made on the start and end positions of the curve; this function + only checks the inside of the curve. + + Args: + p0 (complex): Start point of curve. + p1 (complex): First handle of curve. + p2 (complex): Second handle of curve. + p3 (complex): End point of curve. + tolerance (double): Distance from origin. + + Returns: + bool: True if the cubic Bezier ``p`` entirely lies within a distance + ``tolerance`` of the origin, False otherwise. + """ + # First check p2 then p1, as p2 has higher error early on. + if abs(p2) <= tolerance and abs(p1) <= tolerance: + return True + + # Split. + mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + if abs(mid) > tolerance: + return False + deriv3 = (p3 + p2 - p1 - p0) * 0.125 + return cubic_farthest_fit_inside( + p0, (p0 + p1) * 0.5, mid - deriv3, mid, tolerance + ) and cubic_farthest_fit_inside(mid, mid + deriv3, (p2 + p3) * 0.5, p3, tolerance) + + +@cython.locals( + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p1_2_3=cython.complex, +) +def elevate_quadratic(p0, p1, p2): + """Given a quadratic bezier curve, return its degree-elevated cubic.""" + + # https://pomax.github.io/bezierinfo/#reordering + p1_2_3 = p1 * (2 / 3) + return ( + p0, + (p0 * (1 / 3) + p1_2_3), + (p2 * (1 / 3) + p1_2_3), + p2, + ) + + +@cython.cfunc +@cython.locals( + start=cython.int, + n=cython.int, + k=cython.int, + prod_ratio=cython.double, + sum_ratio=cython.double, + ratio=cython.double, + t=cython.double, + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +def merge_curves(curves, start, n): + """Give a cubic-Bezier spline, reconstruct one cubic-Bezier + that has the same endpoints and tangents and approxmates + the spline.""" + + # Reconstruct the t values of the cut segments + prod_ratio = 1.0 + sum_ratio = 1.0 + ts = [1] + for k in range(1, n): + ck = curves[start + k] + c_before = curves[start + k - 1] + + # |t_(k+1) - t_k| / |t_k - t_(k - 1)| = ratio + assert ck[0] == c_before[3] + ratio = abs(ck[1] - ck[0]) / abs(c_before[3] - c_before[2]) + + prod_ratio *= ratio + sum_ratio += prod_ratio + ts.append(sum_ratio) + + # (t(n) - t(n - 1)) / (t_(1) - t(0)) = prod_ratio + + ts = [t / sum_ratio for t in ts[:-1]] + + p0 = curves[start][0] + p1 = curves[start][1] + p2 = curves[start + n - 1][2] + p3 = curves[start + n - 1][3] + + # Build the curve by scaling the control-points. + p1 = p0 + (p1 - p0) / (ts[0] if ts else 1) + p2 = p3 + (p2 - p3) / ((1 - ts[-1]) if ts else 1) + + curve = (p0, p1, p2, p3) + + return curve, ts + + +@cython.locals( + count=cython.int, + num_offcurves=cython.int, + i=cython.int, + off1=cython.complex, + off2=cython.complex, + on=cython.complex, +) +def add_implicit_on_curves(p): + q = list(p) + count = 0 + num_offcurves = len(p) - 2 + for i in range(1, num_offcurves): + off1 = p[i] + off2 = p[i + 1] + on = off1 + (off2 - off1) * 0.5 + q.insert(i + 1 + count, on) + count += 1 + return q + + +Point = Union[Tuple[float, float], complex] + + +@cython.locals( + cost=cython.int, + is_complex=cython.int, +) +def quadratic_to_curves( + quads: List[List[Point]], + max_err: float = 0.5, + all_cubic: bool = False, +) -> List[Tuple[Point, ...]]: + """Converts a connecting list of quadratic splines to a list of quadratic + and cubic curves. + + A quadratic spline is specified as a list of points. Either each point is + a 2-tuple of X,Y coordinates, or each point is a complex number with + real/imaginary components representing X,Y coordinates. + + The first and last points are on-curve points and the rest are off-curve + points, with an implied on-curve point in the middle between every two + consequtive off-curve points. + + Returns: + The output is a list of tuples of points. Points are represented + in the same format as the input, either as 2-tuples or complex numbers. + + Each tuple is either of length three, for a quadratic curve, or four, + for a cubic curve. Each curve's last point is the same as the next + curve's first point. + + Args: + quads: quadratic splines + + max_err: absolute error tolerance; defaults to 0.5 + + all_cubic: if True, only cubic curves are generated; defaults to False + """ + is_complex = type(quads[0][0]) is complex + if not is_complex: + quads = [[complex(x, y) for (x, y) in p] for p in quads] + + q = [quads[0][0]] + costs = [1] + cost = 1 + for p in quads: + assert q[-1] == p[0] + for i in range(len(p) - 2): + cost += 1 + costs.append(cost) + costs.append(cost) + qq = add_implicit_on_curves(p)[1:] + costs.pop() + q.extend(qq) + cost += 1 + costs.append(cost) + + curves = spline_to_curves(q, costs, max_err, all_cubic) + + if not is_complex: + curves = [tuple((c.real, c.imag) for c in curve) for curve in curves] + return curves + + +Solution = namedtuple("Solution", ["num_points", "error", "start_index", "is_cubic"]) + + +@cython.locals( + i=cython.int, + j=cython.int, + k=cython.int, + start=cython.int, + i_sol_count=cython.int, + j_sol_count=cython.int, + this_sol_count=cython.int, + tolerance=cython.double, + err=cython.double, + error=cython.double, + i_sol_error=cython.double, + j_sol_error=cython.double, + all_cubic=cython.int, + is_cubic=cython.int, + count=cython.int, + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, + v=cython.complex, + u=cython.complex, +) +def spline_to_curves(q, costs, tolerance=0.5, all_cubic=False): + """ + q: quadratic spline with alternating on-curve / off-curve points. + + costs: cumulative list of encoding cost of q in terms of number of + points that need to be encoded. Implied on-curve points do not + contribute to the cost. If all points need to be encoded, then + costs will be range(1, len(q)+1). + """ + + assert len(q) >= 3, "quadratic spline requires at least 3 points" + + # Elevate quadratic segments to cubic + elevated_quadratics = [ + elevate_quadratic(*q[i : i + 3]) for i in range(0, len(q) - 2, 2) + ] + + # Find sharp corners; they have to be oncurves for sure. + forced = set() + for i in range(1, len(elevated_quadratics)): + p0 = elevated_quadratics[i - 1][2] + p1 = elevated_quadratics[i][0] + p2 = elevated_quadratics[i][1] + if abs(p1 - p0) + abs(p2 - p1) > tolerance + abs(p2 - p0): + forced.add(i) + + # Dynamic-Programming to find the solution with fewest number of + # cubic curves, and within those the one with smallest error. + sols = [Solution(0, 0, 0, False)] + impossible = Solution(len(elevated_quadratics) * 3 + 1, 0, 1, False) + start = 0 + for i in range(1, len(elevated_quadratics) + 1): + best_sol = impossible + for j in range(start, i): + j_sol_count, j_sol_error = sols[j].num_points, sols[j].error + + if not all_cubic: + # Solution with quadratics between j:i + this_count = costs[2 * i - 1] - costs[2 * j] + 1 + i_sol_count = j_sol_count + this_count + i_sol_error = j_sol_error + i_sol = Solution(i_sol_count, i_sol_error, i - j, False) + if i_sol < best_sol: + best_sol = i_sol + + if this_count <= 3: + # Can't get any better than this in the path below + continue + + # Fit elevated_quadratics[j:i] into one cubic + try: + curve, ts = merge_curves(elevated_quadratics, j, i - j) + except ZeroDivisionError: + continue + + # Now reconstruct the segments from the fitted curve + reconstructed_iter = splitCubicAtTC(*curve, *ts) + reconstructed = [] + + # Knot errors + error = 0 + for k, reconst in enumerate(reconstructed_iter): + orig = elevated_quadratics[j + k] + err = abs(reconst[3] - orig[3]) + error = max(error, err) + if error > tolerance: + break + reconstructed.append(reconst) + if error > tolerance: + # Not feasible + continue + + # Interior errors + for k, reconst in enumerate(reconstructed): + orig = elevated_quadratics[j + k] + p0, p1, p2, p3 = tuple(v - u for v, u in zip(reconst, orig)) + + if not cubic_farthest_fit_inside(p0, p1, p2, p3, tolerance): + error = tolerance + 1 + break + if error > tolerance: + # Not feasible + continue + + # Save best solution + i_sol_count = j_sol_count + 3 + i_sol_error = max(j_sol_error, error) + i_sol = Solution(i_sol_count, i_sol_error, i - j, True) + if i_sol < best_sol: + best_sol = i_sol + + if i_sol_count == 3: + # Can't get any better than this + break + + sols.append(best_sol) + if i in forced: + start = i + + # Reconstruct solution + splits = [] + cubic = [] + i = len(sols) - 1 + while i: + count, is_cubic = sols[i].start_index, sols[i].is_cubic + splits.append(i) + cubic.append(is_cubic) + i -= count + curves = [] + j = 0 + for i, is_cubic in reversed(list(zip(splits, cubic))): + if is_cubic: + curves.append(merge_curves(elevated_quadratics, j, i - j)[0]) + else: + for k in range(j, i): + curves.append(q[k * 2 : k * 2 + 3]) + j = i + + return curves + + +def main(): + from fontTools.cu2qu.benchmark import generate_curve + from fontTools.cu2qu import curve_to_quadratic + + tolerance = 0.05 + reconstruct_tolerance = tolerance * 1 + curve = generate_curve() + quadratics = curve_to_quadratic(curve, tolerance) + print( + "cu2qu tolerance %g. qu2cu tolerance %g." % (tolerance, reconstruct_tolerance) + ) + print("One random cubic turned into %d quadratics." % len(quadratics)) + curves = quadratic_to_curves([quadratics], reconstruct_tolerance) + print("Those quadratics turned back into %d cubics. " % len(curves)) + print("Original curve:", curve) + print("Reconstructed curve(s):", curves) + + +if __name__ == "__main__": + main() diff --git a/dbdpy-env/lib/python3.9/site-packages/fontTools/subset/__init__.py b/dbdpy-env/lib/python3.9/site-packages/fontTools/subset/__init__.py new file mode 100644 index 00000000..9b175843 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/fontTools/subset/__init__.py @@ -0,0 +1,3738 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod + +from fontTools import config +from fontTools.misc.roundTools import otRound +from fontTools import ttLib +from fontTools.ttLib.tables import otTables +from fontTools.ttLib.tables.otBase import USE_HARFBUZZ_REPACKER +from fontTools.otlLib.maxContextCalc import maxCtxFont +from fontTools.pens.basePen import NullPen +from fontTools.misc.loggingTools import Timer +from fontTools.misc.cliTools import makeOutputFileName +from fontTools.subset.util import _add_method, _uniq_sort +from fontTools.subset.cff import * +from fontTools.subset.svg import * +from fontTools.varLib import varStore # for subset_varidxes +from fontTools.ttLib.tables._n_a_m_e import NameRecordVisitor +import sys +import struct +import array +import logging +from collections import Counter, defaultdict +from functools import reduce +from types import MethodType + +__usage__ = "pyftsubset font-file [glyph...] [--option=value]..." + +__doc__ = ( + """\ +pyftsubset -- OpenType font subsetter and optimizer + +pyftsubset is an OpenType font subsetter and optimizer, based on fontTools. +It accepts any TT- or CFF-flavored OpenType (.otf or .ttf) or WOFF (.woff) +font file. The subsetted glyph set is based on the specified glyphs +or characters, and specified OpenType layout features. + +The tool also performs some size-reducing optimizations, aimed for using +subset fonts as webfonts. Individual optimizations can be enabled or +disabled, and are enabled by default when they are safe. + +Usage: """ + + __usage__ + + """ + +At least one glyph or one of --gids, --gids-file, --glyphs, --glyphs-file, +--text, --text-file, --unicodes, or --unicodes-file, must be specified. + +Args: + +font-file + The input font file. +glyph + Specify one or more glyph identifiers to include in the subset. Must be + PS glyph names, or the special string '*' to keep the entire glyph set. + +Initial glyph set specification +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These options populate the initial glyph set. Same option can appear +multiple times, and the results are accummulated. + +--gids=[,...] + Specify comma/whitespace-separated list of glyph IDs or ranges as decimal + numbers. For example, --gids=10-12,14 adds glyphs with numbers 10, 11, + 12, and 14. + +--gids-file= + Like --gids but reads from a file. Anything after a '#' on any line is + ignored as comments. + +--glyphs=[,...] + Specify comma/whitespace-separated PS glyph names to add to the subset. + Note that only PS glyph names are accepted, not gidNNN, U+XXXX, etc + that are accepted on the command line. The special string '*' will keep + the entire glyph set. + +--glyphs-file= + Like --glyphs but reads from a file. Anything after a '#' on any line + is ignored as comments. + +--text= + Specify characters to include in the subset, as UTF-8 string. + +--text-file= + Like --text but reads from a file. Newline character are not added to + the subset. + +--unicodes=[,...] + Specify comma/whitespace-separated list of Unicode codepoints or + ranges as hex numbers, optionally prefixed with 'U+', 'u', etc. + For example, --unicodes=41-5a,61-7a adds ASCII letters, so does + the more verbose --unicodes=U+0041-005A,U+0061-007A. + The special strings '*' will choose all Unicode characters mapped + by the font. + +--unicodes-file= + Like --unicodes, but reads from a file. Anything after a '#' on any + line in the file is ignored as comments. + +--ignore-missing-glyphs + Do not fail if some requested glyphs or gids are not available in + the font. + +--no-ignore-missing-glyphs + Stop and fail if some requested glyphs or gids are not available + in the font. [default] + +--ignore-missing-unicodes [default] + Do not fail if some requested Unicode characters (including those + indirectly specified using --text or --text-file) are not available + in the font. + +--no-ignore-missing-unicodes + Stop and fail if some requested Unicode characters are not available + in the font. + Note the default discrepancy between ignoring missing glyphs versus + unicodes. This is for historical reasons and in the future + --no-ignore-missing-unicodes might become default. + +Other options +^^^^^^^^^^^^^ + +For the other options listed below, to see the current value of the option, +pass a value of '?' to it, with or without a '='. + +Examples:: + + $ pyftsubset --glyph-names? + Current setting for 'glyph-names' is: False + $ ./pyftsubset --name-IDs=? + Current setting for 'name-IDs' is: [0, 1, 2, 3, 4, 5, 6] + $ ./pyftsubset --hinting? --no-hinting --hinting? + Current setting for 'hinting' is: True + Current setting for 'hinting' is: False + +Output options +^^^^^^^^^^^^^^ + +--output-file= + The output font file. If not specified, the subsetted font + will be saved in as font-file.subset. + +--flavor= + Specify flavor of output font file. May be 'woff' or 'woff2'. + Note that WOFF2 requires the Brotli Python extension, available + at https://github.com/google/brotli + +--with-zopfli + Use the Google Zopfli algorithm to compress WOFF. The output is 3-8 % + smaller than pure zlib, but the compression speed is much slower. + The Zopfli Python bindings are available at: + https://pypi.python.org/pypi/zopfli + +--harfbuzz-repacker + By default, we serialize GPOS/GSUB using the HarfBuzz Repacker when + uharfbuzz can be imported and is successful, otherwise fall back to + the pure-python serializer. Set the option to force using the HarfBuzz + Repacker (raises an error if uharfbuzz can't be found or fails). + +--no-harfbuzz-repacker + Always use the pure-python serializer even if uharfbuzz is available. + +Glyph set expansion +^^^^^^^^^^^^^^^^^^^ + +These options control how additional glyphs are added to the subset. + +--retain-gids + Retain glyph indices; just empty glyphs not needed in-place. + +--notdef-glyph + Add the '.notdef' glyph to the subset (ie, keep it). [default] + +--no-notdef-glyph + Drop the '.notdef' glyph unless specified in the glyph set. This + saves a few bytes, but is not possible for Postscript-flavored + fonts, as those require '.notdef'. For TrueType-flavored fonts, + this works fine as long as no unsupported glyphs are requested + from the font. + +--notdef-outline + Keep the outline of '.notdef' glyph. The '.notdef' glyph outline is + used when glyphs not supported by the font are to be shown. It is not + needed otherwise. + +--no-notdef-outline + When including a '.notdef' glyph, remove its outline. This saves + a few bytes. [default] + +--recommended-glyphs + Add glyphs 0, 1, 2, and 3 to the subset, as recommended for + TrueType-flavored fonts: '.notdef', 'NULL' or '.null', 'CR', 'space'. + Some legacy software might require this, but no modern system does. + +--no-recommended-glyphs + Do not add glyphs 0, 1, 2, and 3 to the subset, unless specified in + glyph set. [default] + +--no-layout-closure + Do not expand glyph set to add glyphs produced by OpenType layout + features. Instead, OpenType layout features will be subset to only + rules that are relevant to the otherwise-specified glyph set. + +--layout-features[+|-]=[,...] + Specify (=), add to (+=) or exclude from (-=) the comma-separated + set of OpenType layout feature tags that will be preserved. + Glyph variants used by the preserved features are added to the + specified subset glyph set. By default, 'calt', 'ccmp', 'clig', 'curs', + 'dnom', 'frac', 'kern', 'liga', 'locl', 'mark', 'mkmk', 'numr', 'rclt', + 'rlig', 'rvrn', and all features required for script shaping are + preserved. To see the full list, try '--layout-features=?'. + Use '*' to keep all features. + Multiple --layout-features options can be provided if necessary. + Examples: + + --layout-features+=onum,pnum,ss01 + * Keep the default set of features and 'onum', 'pnum', 'ss01'. + --layout-features-='mark','mkmk' + * Keep the default set of features but drop 'mark' and 'mkmk'. + --layout-features='kern' + * Only keep the 'kern' feature, drop all others. + --layout-features='' + * Drop all features. + --layout-features='*' + * Keep all features. + --layout-features+=aalt --layout-features-=vrt2 + * Keep default set of features plus 'aalt', but drop 'vrt2'. + +--layout-scripts[+|-]= +""" + + +# Style definitions for the HTML template +STYLE_INCLUDE = """ + +""" + + +# HTML template for HTMLWriter +DISPLAY_TEMPLATE = """ +

+ + + +""" + + +INCLUDED_FRAMES = """ + for (var i=0; i<{Nframes}; i++){{ + frames[i] = "{frame_dir}/frame" + ("0000000" + i).slice(-7) + + ".{frame_format}"; + }} +""" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.py new file mode 100644 index 00000000..13319d86 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.py @@ -0,0 +1,381 @@ +""" +Helper functions for managing the Matplotlib API. + +This documentation is only relevant for Matplotlib developers, not for users. + +.. warning:: + + This module and its submodules are for internal use only. Do not use them + in your own code. We may change the API at any time with no warning. + +""" + +import functools +import itertools +import re +import sys +import warnings + +from .deprecation import ( + deprecated, warn_deprecated, + rename_parameter, delete_parameter, make_keyword_only, + deprecate_method_override, deprecate_privatize_attribute, + suppress_matplotlib_deprecation_warning, + MatplotlibDeprecationWarning) + + +class classproperty: + """ + Like `property`, but also triggers on access via the class, and it is the + *class* that's passed as argument. + + Examples + -------- + :: + + class C: + @classproperty + def foo(cls): + return cls.__name__ + + assert C.foo == "C" + """ + + def __init__(self, fget, fset=None, fdel=None, doc=None): + self._fget = fget + if fset is not None or fdel is not None: + raise ValueError('classproperty only implements fget.') + self.fset = fset + self.fdel = fdel + # docs are ignored for now + self._doc = doc + + def __get__(self, instance, owner): + return self._fget(owner) + + @property + def fget(self): + return self._fget + + +# In the following check_foo() functions, the first parameter is positional-only to make +# e.g. `_api.check_isinstance([...], types=foo)` work. + +def check_isinstance(types, /, **kwargs): + """ + For each *key, value* pair in *kwargs*, check that *value* is an instance + of one of *types*; if not, raise an appropriate TypeError. + + As a special case, a ``None`` entry in *types* is treated as NoneType. + + Examples + -------- + >>> _api.check_isinstance((SomeClass, None), arg=arg) + """ + none_type = type(None) + types = ((types,) if isinstance(types, type) else + (none_type,) if types is None else + tuple(none_type if tp is None else tp for tp in types)) + + def type_name(tp): + return ("None" if tp is none_type + else tp.__qualname__ if tp.__module__ == "builtins" + else f"{tp.__module__}.{tp.__qualname__}") + + for k, v in kwargs.items(): + if not isinstance(v, types): + names = [*map(type_name, types)] + if "None" in names: # Move it to the end for better wording. + names.remove("None") + names.append("None") + raise TypeError( + "{!r} must be an instance of {}, not a {}".format( + k, + ", ".join(names[:-1]) + " or " + names[-1] + if len(names) > 1 else names[0], + type_name(type(v)))) + + +def check_in_list(values, /, *, _print_supported_values=True, **kwargs): + """ + For each *key, value* pair in *kwargs*, check that *value* is in *values*; + if not, raise an appropriate ValueError. + + Parameters + ---------- + values : iterable + Sequence of values to check on. + _print_supported_values : bool, default: True + Whether to print *values* when raising ValueError. + **kwargs : dict + *key, value* pairs as keyword arguments to find in *values*. + + Raises + ------ + ValueError + If any *value* in *kwargs* is not found in *values*. + + Examples + -------- + >>> _api.check_in_list(["foo", "bar"], arg=arg, other_arg=other_arg) + """ + if not kwargs: + raise TypeError("No argument to check!") + for key, val in kwargs.items(): + if val not in values: + msg = f"{val!r} is not a valid value for {key}" + if _print_supported_values: + msg += f"; supported values are {', '.join(map(repr, values))}" + raise ValueError(msg) + + +def check_shape(shape, /, **kwargs): + """ + For each *key, value* pair in *kwargs*, check that *value* has the shape *shape*; + if not, raise an appropriate ValueError. + + *None* in the shape is treated as a "free" size that can have any length. + e.g. (None, 2) -> (N, 2) + + The values checked must be numpy arrays. + + Examples + -------- + To check for (N, 2) shaped arrays + + >>> _api.check_shape((None, 2), arg=arg, other_arg=other_arg) + """ + for k, v in kwargs.items(): + data_shape = v.shape + + if (len(data_shape) != len(shape) + or any(s != t and t is not None for s, t in zip(data_shape, shape))): + dim_labels = iter(itertools.chain( + 'NMLKJIH', + (f"D{i}" for i in itertools.count()))) + text_shape = ", ".join([str(n) if n is not None else next(dim_labels) + for n in shape[::-1]][::-1]) + if len(shape) == 1: + text_shape += "," + + raise ValueError( + f"{k!r} must be {len(shape)}D with shape ({text_shape}), " + f"but your input has shape {v.shape}" + ) + + +def check_getitem(mapping, /, **kwargs): + """ + *kwargs* must consist of a single *key, value* pair. If *key* is in + *mapping*, return ``mapping[value]``; else, raise an appropriate + ValueError. + + Examples + -------- + >>> _api.check_getitem({"foo": "bar"}, arg=arg) + """ + if len(kwargs) != 1: + raise ValueError("check_getitem takes a single keyword argument") + (k, v), = kwargs.items() + try: + return mapping[v] + except KeyError: + raise ValueError( + f"{v!r} is not a valid value for {k}; supported values are " + f"{', '.join(map(repr, mapping))}") from None + + +def caching_module_getattr(cls): + """ + Helper decorator for implementing module-level ``__getattr__`` as a class. + + This decorator must be used at the module toplevel as follows:: + + @caching_module_getattr + class __getattr__: # The class *must* be named ``__getattr__``. + @property # Only properties are taken into account. + def name(self): ... + + The ``__getattr__`` class will be replaced by a ``__getattr__`` + function such that trying to access ``name`` on the module will + resolve the corresponding property (which may be decorated e.g. with + ``_api.deprecated`` for deprecating module globals). The properties are + all implicitly cached. Moreover, a suitable AttributeError is generated + and raised if no property with the given name exists. + """ + + assert cls.__name__ == "__getattr__" + # Don't accidentally export cls dunders. + props = {name: prop for name, prop in vars(cls).items() + if isinstance(prop, property)} + instance = cls() + + @functools.cache + def __getattr__(name): + if name in props: + return props[name].__get__(instance) + raise AttributeError( + f"module {cls.__module__!r} has no attribute {name!r}") + + return __getattr__ + + +def define_aliases(alias_d, cls=None): + """ + Class decorator for defining property aliases. + + Use as :: + + @_api.define_aliases({"property": ["alias", ...], ...}) + class C: ... + + For each property, if the corresponding ``get_property`` is defined in the + class so far, an alias named ``get_alias`` will be defined; the same will + be done for setters. If neither the getter nor the setter exists, an + exception will be raised. + + The alias map is stored as the ``_alias_map`` attribute on the class and + can be used by `.normalize_kwargs` (which assumes that higher priority + aliases come last). + """ + if cls is None: # Return the actual class decorator. + return functools.partial(define_aliases, alias_d) + + def make_alias(name): # Enforce a closure over *name*. + @functools.wraps(getattr(cls, name)) + def method(self, *args, **kwargs): + return getattr(self, name)(*args, **kwargs) + return method + + for prop, aliases in alias_d.items(): + exists = False + for prefix in ["get_", "set_"]: + if prefix + prop in vars(cls): + exists = True + for alias in aliases: + method = make_alias(prefix + prop) + method.__name__ = prefix + alias + method.__doc__ = f"Alias for `{prefix + prop}`." + setattr(cls, prefix + alias, method) + if not exists: + raise ValueError( + f"Neither getter nor setter exists for {prop!r}") + + def get_aliased_and_aliases(d): + return {*d, *(alias for aliases in d.values() for alias in aliases)} + + preexisting_aliases = getattr(cls, "_alias_map", {}) + conflicting = (get_aliased_and_aliases(preexisting_aliases) + & get_aliased_and_aliases(alias_d)) + if conflicting: + # Need to decide on conflict resolution policy. + raise NotImplementedError( + f"Parent class already defines conflicting aliases: {conflicting}") + cls._alias_map = {**preexisting_aliases, **alias_d} + return cls + + +def select_matching_signature(funcs, *args, **kwargs): + """ + Select and call the function that accepts ``*args, **kwargs``. + + *funcs* is a list of functions which should not raise any exception (other + than `TypeError` if the arguments passed do not match their signature). + + `select_matching_signature` tries to call each of the functions in *funcs* + with ``*args, **kwargs`` (in the order in which they are given). Calls + that fail with a `TypeError` are silently skipped. As soon as a call + succeeds, `select_matching_signature` returns its return value. If no + function accepts ``*args, **kwargs``, then the `TypeError` raised by the + last failing call is re-raised. + + Callers should normally make sure that any ``*args, **kwargs`` can only + bind a single *func* (to avoid any ambiguity), although this is not checked + by `select_matching_signature`. + + Notes + ----- + `select_matching_signature` is intended to help implementing + signature-overloaded functions. In general, such functions should be + avoided, except for back-compatibility concerns. A typical use pattern is + :: + + def my_func(*args, **kwargs): + params = select_matching_signature( + [lambda old1, old2: locals(), lambda new: locals()], + *args, **kwargs) + if "old1" in params: + warn_deprecated(...) + old1, old2 = params.values() # note that locals() is ordered. + else: + new, = params.values() + # do things with params + + which allows *my_func* to be called either with two parameters (*old1* and + *old2*) or a single one (*new*). Note that the new signature is given + last, so that callers get a `TypeError` corresponding to the new signature + if the arguments they passed in do not match any signature. + """ + # Rather than relying on locals() ordering, one could have just used func's + # signature (``bound = inspect.signature(func).bind(*args, **kwargs); + # bound.apply_defaults(); return bound``) but that is significantly slower. + for i, func in enumerate(funcs): + try: + return func(*args, **kwargs) + except TypeError: + if i == len(funcs) - 1: + raise + + +def nargs_error(name, takes, given): + """Generate a TypeError to be raised by function calls with wrong arity.""" + return TypeError(f"{name}() takes {takes} positional arguments but " + f"{given} were given") + + +def kwarg_error(name, kw): + """ + Generate a TypeError to be raised by function calls with wrong kwarg. + + Parameters + ---------- + name : str + The name of the calling function. + kw : str or Iterable[str] + Either the invalid keyword argument name, or an iterable yielding + invalid keyword arguments (e.g., a ``kwargs`` dict). + """ + if not isinstance(kw, str): + kw = next(iter(kw)) + return TypeError(f"{name}() got an unexpected keyword argument '{kw}'") + + +def recursive_subclasses(cls): + """Yield *cls* and direct and indirect subclasses of *cls*.""" + yield cls + for subcls in cls.__subclasses__(): + yield from recursive_subclasses(subcls) + + +def warn_external(message, category=None): + """ + `warnings.warn` wrapper that sets *stacklevel* to "outside Matplotlib". + + The original emitter of the warning can be obtained by patching this + function back to `warnings.warn`, i.e. ``_api.warn_external = + warnings.warn`` (or ``functools.partial(warnings.warn, stacklevel=2)``, + etc.). + """ + frame = sys._getframe() + for stacklevel in itertools.count(1): + if frame is None: + # when called in embedded context may hit frame is None + break + if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.(?!tests\.))", + # Work around sphinx-gallery not setting __name__. + frame.f_globals.get("__name__", "")): + break + frame = frame.f_back + # preemptively break reference cycle between locals and the frame + del frame + warnings.warn(message, category, stacklevel) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.pyi new file mode 100644 index 00000000..4baff7cd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/__init__.pyi @@ -0,0 +1,59 @@ +from collections.abc import Callable, Generator, Mapping, Sequence +from typing import Any, Iterable, TypeVar, overload + +from numpy.typing import NDArray + +from .deprecation import ( # noqa: re-exported API + deprecated as deprecated, + warn_deprecated as warn_deprecated, + rename_parameter as rename_parameter, + delete_parameter as delete_parameter, + make_keyword_only as make_keyword_only, + deprecate_method_override as deprecate_method_override, + deprecate_privatize_attribute as deprecate_privatize_attribute, + suppress_matplotlib_deprecation_warning as suppress_matplotlib_deprecation_warning, + MatplotlibDeprecationWarning as MatplotlibDeprecationWarning, +) + +_T = TypeVar("_T") + +class classproperty(Any): + def __init__( + self, + fget: Callable[[_T], Any], + fset: None = ..., + fdel: None = ..., + doc: str | None = None, + ): ... + # Replace return with Self when py3.9 is dropped + @overload + def __get__(self, instance: None, owner: None) -> classproperty: ... + @overload + def __get__(self, instance: object, owner: type[object]) -> Any: ... + @property + def fget(self) -> Callable[[_T], Any]: ... + +def check_isinstance( + types: type | tuple[type | None, ...], /, **kwargs: Any +) -> None: ... +def check_in_list( + values: Sequence[Any], /, *, _print_supported_values: bool = ..., **kwargs: Any +) -> None: ... +def check_shape(shape: tuple[int | None, ...], /, **kwargs: NDArray) -> None: ... +def check_getitem(mapping: Mapping[Any, Any], /, **kwargs: Any) -> Any: ... +def caching_module_getattr(cls: type) -> Callable[[str], Any]: ... +@overload +def define_aliases( + alias_d: dict[str, list[str]], cls: None = ... +) -> Callable[[type[_T]], type[_T]]: ... +@overload +def define_aliases(alias_d: dict[str, list[str]], cls: type[_T]) -> type[_T]: ... +def select_matching_signature( + funcs: list[Callable], *args: Any, **kwargs: Any +) -> Any: ... +def nargs_error(name: str, takes: int | str, given: int) -> TypeError: ... +def kwarg_error(name: str, kw: str | Iterable[str]) -> TypeError: ... +def recursive_subclasses(cls: type) -> Generator[type, None, None]: ... +def warn_external( + message: str | Warning, category: type[Warning] | None = ... +) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.py new file mode 100644 index 00000000..7c304173 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.py @@ -0,0 +1,510 @@ +""" +Helper functions for deprecating parts of the Matplotlib API. + +This documentation is only relevant for Matplotlib developers, not for users. + +.. warning:: + + This module is for internal use only. Do not use it in your own code. + We may change the API at any time with no warning. + +""" + +import contextlib +import functools +import inspect +import math +import warnings + + +class MatplotlibDeprecationWarning(DeprecationWarning): + """A class for issuing deprecation warnings for Matplotlib users.""" + + +def _generate_deprecation_warning( + since, message='', name='', alternative='', pending=False, obj_type='', + addendum='', *, removal=''): + if pending: + if removal: + raise ValueError( + "A pending deprecation cannot have a scheduled removal") + else: + removal = f"in {removal}" if removal else "two minor releases later" + if not message: + message = ( + ("The %(name)s %(obj_type)s" if obj_type else "%(name)s") + + (" will be deprecated in a future version" + if pending else + (" was deprecated in Matplotlib %(since)s" + + (" and will be removed %(removal)s" if removal else ""))) + + "." + + (" Use %(alternative)s instead." if alternative else "") + + (" %(addendum)s" if addendum else "")) + warning_cls = (PendingDeprecationWarning if pending + else MatplotlibDeprecationWarning) + return warning_cls(message % dict( + func=name, name=name, obj_type=obj_type, since=since, removal=removal, + alternative=alternative, addendum=addendum)) + + +def warn_deprecated( + since, *, message='', name='', alternative='', pending=False, + obj_type='', addendum='', removal=''): + """ + Display a standardized deprecation. + + Parameters + ---------- + since : str + The release at which this API became deprecated. + message : str, optional + Override the default deprecation message. The ``%(since)s``, + ``%(name)s``, ``%(alternative)s``, ``%(obj_type)s``, ``%(addendum)s``, + and ``%(removal)s`` format specifiers will be replaced by the values + of the respective arguments passed to this function. + name : str, optional + The name of the deprecated object. + alternative : str, optional + An alternative API that the user may use in place of the deprecated + API. The deprecation warning will tell the user about this alternative + if provided. + pending : bool, optional + If True, uses a PendingDeprecationWarning instead of a + DeprecationWarning. Cannot be used together with *removal*. + obj_type : str, optional + The object type being deprecated. + addendum : str, optional + Additional text appended directly to the final message. + removal : str, optional + The expected removal version. With the default (an empty string), a + removal version is automatically computed from *since*. Set to other + Falsy values to not schedule a removal date. Cannot be used together + with *pending*. + + Examples + -------- + :: + + # To warn of the deprecation of "matplotlib.name_of_module" + warn_deprecated('1.4.0', name='matplotlib.name_of_module', + obj_type='module') + """ + warning = _generate_deprecation_warning( + since, message, name, alternative, pending, obj_type, addendum, + removal=removal) + from . import warn_external + warn_external(warning, category=MatplotlibDeprecationWarning) + + +def deprecated(since, *, message='', name='', alternative='', pending=False, + obj_type=None, addendum='', removal=''): + """ + Decorator to mark a function, a class, or a property as deprecated. + + When deprecating a classmethod, a staticmethod, or a property, the + ``@deprecated`` decorator should go *under* ``@classmethod`` and + ``@staticmethod`` (i.e., `deprecated` should directly decorate the + underlying callable), but *over* ``@property``. + + When deprecating a class ``C`` intended to be used as a base class in a + multiple inheritance hierarchy, ``C`` *must* define an ``__init__`` method + (if ``C`` instead inherited its ``__init__`` from its own base class, then + ``@deprecated`` would mess up ``__init__`` inheritance when installing its + own (deprecation-emitting) ``C.__init__``). + + Parameters are the same as for `warn_deprecated`, except that *obj_type* + defaults to 'class' if decorating a class, 'attribute' if decorating a + property, and 'function' otherwise. + + Examples + -------- + :: + + @deprecated('1.4.0') + def the_function_to_deprecate(): + pass + """ + + def deprecate(obj, message=message, name=name, alternative=alternative, + pending=pending, obj_type=obj_type, addendum=addendum): + from matplotlib._api import classproperty + + if isinstance(obj, type): + if obj_type is None: + obj_type = "class" + func = obj.__init__ + name = name or obj.__name__ + old_doc = obj.__doc__ + + def finalize(wrapper, new_doc): + try: + obj.__doc__ = new_doc + except AttributeError: # Can't set on some extension objects. + pass + obj.__init__ = functools.wraps(obj.__init__)(wrapper) + return obj + + elif isinstance(obj, (property, classproperty)): + if obj_type is None: + obj_type = "attribute" + func = None + name = name or obj.fget.__name__ + old_doc = obj.__doc__ + + class _deprecated_property(type(obj)): + def __get__(self, instance, owner=None): + if instance is not None or owner is not None \ + and isinstance(self, classproperty): + emit_warning() + return super().__get__(instance, owner) + + def __set__(self, instance, value): + if instance is not None: + emit_warning() + return super().__set__(instance, value) + + def __delete__(self, instance): + if instance is not None: + emit_warning() + return super().__delete__(instance) + + def __set_name__(self, owner, set_name): + nonlocal name + if name == "": + name = set_name + + def finalize(_, new_doc): + return _deprecated_property( + fget=obj.fget, fset=obj.fset, fdel=obj.fdel, doc=new_doc) + + else: + if obj_type is None: + obj_type = "function" + func = obj + name = name or obj.__name__ + old_doc = func.__doc__ + + def finalize(wrapper, new_doc): + wrapper = functools.wraps(func)(wrapper) + wrapper.__doc__ = new_doc + return wrapper + + def emit_warning(): + warn_deprecated( + since, message=message, name=name, alternative=alternative, + pending=pending, obj_type=obj_type, addendum=addendum, + removal=removal) + + def wrapper(*args, **kwargs): + emit_warning() + return func(*args, **kwargs) + + old_doc = inspect.cleandoc(old_doc or '').strip('\n') + + notes_header = '\nNotes\n-----' + second_arg = ' '.join([t.strip() for t in + (message, f"Use {alternative} instead." + if alternative else "", addendum) if t]) + new_doc = (f"[*Deprecated*] {old_doc}\n" + f"{notes_header if notes_header not in old_doc else ''}\n" + f".. deprecated:: {since}\n" + f" {second_arg}") + + if not old_doc: + # This is to prevent a spurious 'unexpected unindent' warning from + # docutils when the original docstring was blank. + new_doc += r'\ ' + + return finalize(wrapper, new_doc) + + return deprecate + + +class deprecate_privatize_attribute: + """ + Helper to deprecate public access to an attribute (or method). + + This helper should only be used at class scope, as follows:: + + class Foo: + attr = _deprecate_privatize_attribute(*args, **kwargs) + + where *all* parameters are forwarded to `deprecated`. This form makes + ``attr`` a property which forwards read and write access to ``self._attr`` + (same name but with a leading underscore), with a deprecation warning. + Note that the attribute name is derived from *the name this helper is + assigned to*. This helper also works for deprecating methods. + """ + + def __init__(self, *args, **kwargs): + self.deprecator = deprecated(*args, **kwargs) + + def __set_name__(self, owner, name): + setattr(owner, name, self.deprecator( + property(lambda self: getattr(self, f"_{name}"), + lambda self, value: setattr(self, f"_{name}", value)), + name=name)) + + +# Used by _copy_docstring_and_deprecators to redecorate pyplot wrappers and +# boilerplate.py to retrieve original signatures. It may seem natural to store +# this information as an attribute on the wrapper, but if the wrapper gets +# itself functools.wraps()ed, then such attributes are silently propagated to +# the outer wrapper, which is not desired. +DECORATORS = {} + + +def rename_parameter(since, old, new, func=None): + """ + Decorator indicating that parameter *old* of *func* is renamed to *new*. + + The actual implementation of *func* should use *new*, not *old*. If *old* + is passed to *func*, a DeprecationWarning is emitted, and its value is + used, even if *new* is also passed by keyword (this is to simplify pyplot + wrapper functions, which always pass *new* explicitly to the Axes method). + If *new* is also passed but positionally, a TypeError will be raised by the + underlying function during argument binding. + + Examples + -------- + :: + + @_api.rename_parameter("3.1", "bad_name", "good_name") + def func(good_name): ... + """ + + decorator = functools.partial(rename_parameter, since, old, new) + + if func is None: + return decorator + + signature = inspect.signature(func) + assert old not in signature.parameters, ( + f"Matplotlib internal error: {old!r} cannot be a parameter for " + f"{func.__name__}()") + assert new in signature.parameters, ( + f"Matplotlib internal error: {new!r} must be a parameter for " + f"{func.__name__}()") + + @functools.wraps(func) + def wrapper(*args, **kwargs): + if old in kwargs: + warn_deprecated( + since, message=f"The {old!r} parameter of {func.__name__}() " + f"has been renamed {new!r} since Matplotlib {since}; support " + f"for the old name will be dropped %(removal)s.") + kwargs[new] = kwargs.pop(old) + return func(*args, **kwargs) + + # wrapper() must keep the same documented signature as func(): if we + # instead made both *old* and *new* appear in wrapper()'s signature, they + # would both show up in the pyplot function for an Axes method as well and + # pyplot would explicitly pass both arguments to the Axes method. + + DECORATORS[wrapper] = decorator + return wrapper + + +class _deprecated_parameter_class: + def __repr__(self): + return "" + + +_deprecated_parameter = _deprecated_parameter_class() + + +def delete_parameter(since, name, func=None, **kwargs): + """ + Decorator indicating that parameter *name* of *func* is being deprecated. + + The actual implementation of *func* should keep the *name* parameter in its + signature, or accept a ``**kwargs`` argument (through which *name* would be + passed). + + Parameters that come after the deprecated parameter effectively become + keyword-only (as they cannot be passed positionally without triggering the + DeprecationWarning on the deprecated parameter), and should be marked as + such after the deprecation period has passed and the deprecated parameter + is removed. + + Parameters other than *since*, *name*, and *func* are keyword-only and + forwarded to `.warn_deprecated`. + + Examples + -------- + :: + + @_api.delete_parameter("3.1", "unused") + def func(used_arg, other_arg, unused, more_args): ... + """ + + decorator = functools.partial(delete_parameter, since, name, **kwargs) + + if func is None: + return decorator + + signature = inspect.signature(func) + # Name of `**kwargs` parameter of the decorated function, typically + # "kwargs" if such a parameter exists, or None if the decorated function + # doesn't accept `**kwargs`. + kwargs_name = next((param.name for param in signature.parameters.values() + if param.kind == inspect.Parameter.VAR_KEYWORD), None) + if name in signature.parameters: + kind = signature.parameters[name].kind + is_varargs = kind is inspect.Parameter.VAR_POSITIONAL + is_varkwargs = kind is inspect.Parameter.VAR_KEYWORD + if not is_varargs and not is_varkwargs: + name_idx = ( + # Deprecated parameter can't be passed positionally. + math.inf if kind is inspect.Parameter.KEYWORD_ONLY + # If call site has no more than this number of parameters, the + # deprecated parameter can't have been passed positionally. + else [*signature.parameters].index(name)) + func.__signature__ = signature = signature.replace(parameters=[ + param.replace(default=_deprecated_parameter) + if param.name == name else param + for param in signature.parameters.values()]) + else: + name_idx = -1 # Deprecated parameter can always have been passed. + else: + is_varargs = is_varkwargs = False + # Deprecated parameter can't be passed positionally. + name_idx = math.inf + assert kwargs_name, ( + f"Matplotlib internal error: {name!r} must be a parameter for " + f"{func.__name__}()") + + addendum = kwargs.pop('addendum', None) + + @functools.wraps(func) + def wrapper(*inner_args, **inner_kwargs): + if len(inner_args) <= name_idx and name not in inner_kwargs: + # Early return in the simple, non-deprecated case (much faster than + # calling bind()). + return func(*inner_args, **inner_kwargs) + arguments = signature.bind(*inner_args, **inner_kwargs).arguments + if is_varargs and arguments.get(name): + warn_deprecated( + since, message=f"Additional positional arguments to " + f"{func.__name__}() are deprecated since %(since)s and " + f"support for them will be removed %(removal)s.") + elif is_varkwargs and arguments.get(name): + warn_deprecated( + since, message=f"Additional keyword arguments to " + f"{func.__name__}() are deprecated since %(since)s and " + f"support for them will be removed %(removal)s.") + # We cannot just check `name not in arguments` because the pyplot + # wrappers always pass all arguments explicitly. + elif any(name in d and d[name] != _deprecated_parameter + for d in [arguments, arguments.get(kwargs_name, {})]): + deprecation_addendum = ( + f"If any parameter follows {name!r}, they should be passed as " + f"keyword, not positionally.") + warn_deprecated( + since, + name=repr(name), + obj_type=f"parameter of {func.__name__}()", + addendum=(addendum + " " + deprecation_addendum) if addendum + else deprecation_addendum, + **kwargs) + return func(*inner_args, **inner_kwargs) + + DECORATORS[wrapper] = decorator + return wrapper + + +def make_keyword_only(since, name, func=None): + """ + Decorator indicating that passing parameter *name* (or any of the following + ones) positionally to *func* is being deprecated. + + When used on a method that has a pyplot wrapper, this should be the + outermost decorator, so that :file:`boilerplate.py` can access the original + signature. + """ + + decorator = functools.partial(make_keyword_only, since, name) + + if func is None: + return decorator + + signature = inspect.signature(func) + POK = inspect.Parameter.POSITIONAL_OR_KEYWORD + KWO = inspect.Parameter.KEYWORD_ONLY + assert (name in signature.parameters + and signature.parameters[name].kind == POK), ( + f"Matplotlib internal error: {name!r} must be a positional-or-keyword " + f"parameter for {func.__name__}()") + names = [*signature.parameters] + name_idx = names.index(name) + kwonly = [name for name in names[name_idx:] + if signature.parameters[name].kind == POK] + + @functools.wraps(func) + def wrapper(*args, **kwargs): + # Don't use signature.bind here, as it would fail when stacked with + # rename_parameter and an "old" argument name is passed in + # (signature.bind would fail, but the actual call would succeed). + if len(args) > name_idx: + warn_deprecated( + since, message="Passing the %(name)s %(obj_type)s " + "positionally is deprecated since Matplotlib %(since)s; the " + "parameter will become keyword-only %(removal)s.", + name=name, obj_type=f"parameter of {func.__name__}()") + return func(*args, **kwargs) + + # Don't modify *func*'s signature, as boilerplate.py needs it. + wrapper.__signature__ = signature.replace(parameters=[ + param.replace(kind=KWO) if param.name in kwonly else param + for param in signature.parameters.values()]) + DECORATORS[wrapper] = decorator + return wrapper + + +def deprecate_method_override(method, obj, *, allow_empty=False, **kwargs): + """ + Return ``obj.method`` with a deprecation if it was overridden, else None. + + Parameters + ---------- + method + An unbound method, i.e. an expression of the form + ``Class.method_name``. Remember that within the body of a method, one + can always use ``__class__`` to refer to the class that is currently + being defined. + obj + Either an object of the class where *method* is defined, or a subclass + of that class. + allow_empty : bool, default: False + Whether to allow overrides by "empty" methods without emitting a + warning. + **kwargs + Additional parameters passed to `warn_deprecated` to generate the + deprecation warning; must at least include the "since" key. + """ + + def empty(): pass + def empty_with_docstring(): """doc""" + + name = method.__name__ + bound_child = getattr(obj, name) + bound_base = ( + method # If obj is a class, then we need to use unbound methods. + if isinstance(bound_child, type(empty)) and isinstance(obj, type) + else method.__get__(obj)) + if (bound_child != bound_base + and (not allow_empty + or (getattr(getattr(bound_child, "__code__", None), + "co_code", None) + not in [empty.__code__.co_code, + empty_with_docstring.__code__.co_code]))): + warn_deprecated(**{"name": name, "obj_type": "method", **kwargs}) + return bound_child + return None + + +@contextlib.contextmanager +def suppress_matplotlib_deprecation_warning(): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", MatplotlibDeprecationWarning) + yield diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.pyi new file mode 100644 index 00000000..9619d1b4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_api/deprecation.pyi @@ -0,0 +1,76 @@ +from collections.abc import Callable +import contextlib +from typing import Any, TypedDict, TypeVar, overload +from typing_extensions import ( + ParamSpec, # < Py 3.10 + Unpack, # < Py 3.11 +) + +_P = ParamSpec("_P") +_R = TypeVar("_R") +_T = TypeVar("_T") + +class MatplotlibDeprecationWarning(DeprecationWarning): ... + +class DeprecationKwargs(TypedDict, total=False): + message: str + alternative: str + pending: bool + obj_type: str + addendum: str + removal: str + +class NamedDeprecationKwargs(DeprecationKwargs, total=False): + name: str + +def warn_deprecated(since: str, **kwargs: Unpack[NamedDeprecationKwargs]) -> None: ... +def deprecated( + since: str, **kwargs: Unpack[NamedDeprecationKwargs] +) -> Callable[[_T], _T]: ... + +class deprecate_privatize_attribute(Any): + def __init__(self, since: str, **kwargs: Unpack[NamedDeprecationKwargs]): ... + def __set_name__(self, owner: type[object], name: str) -> None: ... + +DECORATORS: dict[Callable, Callable] = ... + +@overload +def rename_parameter( + since: str, old: str, new: str, func: None = ... +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... +@overload +def rename_parameter( + since: str, old: str, new: str, func: Callable[_P, _R] +) -> Callable[_P, _R]: ... + +class _deprecated_parameter_class: ... + +_deprecated_parameter: _deprecated_parameter_class + +@overload +def delete_parameter( + since: str, name: str, func: None = ..., **kwargs: Unpack[DeprecationKwargs] +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... +@overload +def delete_parameter( + since: str, name: str, func: Callable[_P, _R], **kwargs: Unpack[DeprecationKwargs] +) -> Callable[_P, _R]: ... +@overload +def make_keyword_only( + since: str, name: str, func: None = ... +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... +@overload +def make_keyword_only( + since: str, name: str, func: Callable[_P, _R] +) -> Callable[_P, _R]: ... +def deprecate_method_override( + method: Callable[_P, _R], + obj: object | type, + *, + allow_empty: bool = ..., + since: str, + **kwargs: Unpack[NamedDeprecationKwargs] +) -> Callable[_P, _R]: ... +def suppress_matplotlib_deprecation_warning() -> ( + contextlib.AbstractContextManager[None] +): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_blocking_input.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_blocking_input.py new file mode 100644 index 00000000..45f07757 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_blocking_input.py @@ -0,0 +1,30 @@ +def blocking_input_loop(figure, event_names, timeout, handler): + """ + Run *figure*'s event loop while listening to interactive events. + + The events listed in *event_names* are passed to *handler*. + + This function is used to implement `.Figure.waitforbuttonpress`, + `.Figure.ginput`, and `.Axes.clabel`. + + Parameters + ---------- + figure : `~matplotlib.figure.Figure` + event_names : list of str + The names of the events passed to *handler*. + timeout : float + If positive, the event loop is stopped after *timeout* seconds. + handler : Callable[[Event], Any] + Function called for each event; it can force an early exit of the event + loop by calling ``canvas.stop_event_loop()``. + """ + if figure.canvas.manager: + figure.show() # Ensure that the figure is shown if we are managing it. + # Connect the events to the on_event function call. + cids = [figure.canvas.mpl_connect(name, handler) for name in event_names] + try: + figure.canvas.start_event_loop(timeout) # Start event loop. + finally: # Run even on exception like ctrl-c. + # Disconnect the callbacks. + for cid in cids: + figure.canvas.mpl_disconnect(cid) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..c02c2170cad6d5120cb49f85a4b71f5805de8320 GIT binary patch literal 51379 zcmeI5Z)_Y#8OA4jNxhWJDvKVRhh{YtwKyf?^?ok4zbM;{Kkr;FdG)MtbIY9K9#@+$jSHJ!5>*t_rcP&r#+)mmSUW{@p_( z@#^-;9&?n7saa&PVOl72zRzt~);Z&?roK_?i~Xfyw@@Y8e9|Dsb%Am`E@>3Sl&ts3 zGNIMD)SNlDbsp481=r?Y=+7BX?D;57%^cS-ro3vSnR(^Om^mXi@$ zjA^bU<|)>S^TC0kFKo{ZsAsD#J^ExR^{aBABD}ms)L|Ww=@hj(V}kK&D*LEZDPNE6 z9+jAOea;+y;&%hz z*}DC;uF13g|9JDMZn9~V<2le>7cGzKF{|IC?xZ%cuT&DxXD?+DON^bdwRF2hEK?5r zjBOP}9;pSPSxVoVHfp4zPHY1eBF=O5xNMVJ%v+>2ltug0F~)l0z`~3K0w4eaAOHd& z00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY z0w4eaAOHd&00JNY0w4eaA9@1ybgE^ow)m~@etGJF&oH)1)X#OWd=u-t+_aQEL&w!F z*BA3sk-dF(yEcdYp^dZmfAP-Q?dRHNw|BOs@+`IX6rF2ZO-H;|3Fs$V<8fcy@%j(N z*bcR_s1GmF$;#059o^>T(6R$&Sb=BjHEsobQnxMRIzww)b4N#WbN_@{+^qiY@7GdS4R9F&Vi(=>v1aliFr*}a3=p&XyZ zw_c@`85oim%V>}hdbvmT0Hur>v zT*p)s8o8+nEwFbhO~f+VwM@KeW}nysW6e7;!!-lVp#`L~$7)6d>^|2w_xWzwF=80k zmLu6R4|+j9*?r!@B(_b0ax#=06H!REv`$o<`Qd4^c+ESs**H-QxrcL}m96OX6w`j@ zCB1rWXmfOs)F{IAM%BFddC+ph1DdX)X`!nX%plZUFSJ}o(}P$U7WEMr)^szZxZTAZB)et1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l;QvKH{ja^cfBe7PO3hs+|F2&4tWK%g{N*RN z#O*uf_X*U0jBk|oty|;vhZ5}%OZ$qus%xsG|AUW=zakR6%+-Ot#zKF)`0e8_dok`-hR^~=h5Xl0*Kvke}E zn#JsB zD5rHaY*{UmnkA>ot@LpM^}T?y)av^Hhox5E12`eII{$w`YIWX!5ycYm)cO8T2~8gn zXquvqlsctunTjO4TWa-vgPo*}xGB26l+dq}9%posNz~GG>6PCT_$}4fH)zqmo^ne= z{~Wuf1c{XUumjF{tB4T!oN`qf5qzx)rG&(R9%q2;(JFb_E&nL{%So&rN7b( z^;hdxlKx6B)L*UlSEawwH}d~J_1{4IL+yuGrB?ev_#5IP6E(Askyh({J86H~;m|=g}_f01p_T8cx1ly~gZ56FB>v?+u)2Bz@v#nv~~Tlk^H=(W{1+qSq4R<7KB9TCNkYjO>t^ z)cwr3YtxG?$aHVY^zPr(`>=hN(Y z%6Qn>HQALZ>7i%4p=}j9deXh=?o8kpGwiw-Ub@IKVadzbp__K+TgMOoB8V6KEYumh za&~#0u~ZLjWwqB=k&Pao)LNFJufnA0$JpbP^OQwe!Pv1WEyb3{@X3&ExL-}%=rW9%wlQ+TE8jRVhUPcM1v;>O;e F{ugu3%m)Af literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.pyi new file mode 100644 index 00000000..3a211223 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_c_internal_utils.pyi @@ -0,0 +1 @@ +def display_is_valid() -> bool: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm.py new file mode 100644 index 00000000..b7a7c878 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm.py @@ -0,0 +1,1440 @@ +""" +Nothing here but dictionaries for generating LinearSegmentedColormaps, +and a dictionary of these dictionaries. + +Documentation for each is in pyplot.colormaps(). Please update this +with the purpose and type of your colormap if you add data for one here. +""" + +from functools import partial + +import numpy as np + +_binary_data = { + 'red': ((0., 1., 1.), (1., 0., 0.)), + 'green': ((0., 1., 1.), (1., 0., 0.)), + 'blue': ((0., 1., 1.), (1., 0., 0.)) + } + +_autumn_data = {'red': ((0., 1.0, 1.0), (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)), + 'blue': ((0., 0., 0.), (1.0, 0., 0.))} + +_bone_data = {'red': ((0., 0., 0.), + (0.746032, 0.652778, 0.652778), + (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), + (0.365079, 0.319444, 0.319444), + (0.746032, 0.777778, 0.777778), + (1.0, 1.0, 1.0)), + 'blue': ((0., 0., 0.), + (0.365079, 0.444444, 0.444444), + (1.0, 1.0, 1.0))} + +_cool_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)), + 'green': ((0., 1., 1.), (1.0, 0., 0.)), + 'blue': ((0., 1., 1.), (1.0, 1., 1.))} + +_copper_data = {'red': ((0., 0., 0.), + (0.809524, 1.000000, 1.000000), + (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), + (1.0, 0.7812, 0.7812)), + 'blue': ((0., 0., 0.), + (1.0, 0.4975, 0.4975))} + +def _flag_red(x): return 0.75 * np.sin((x * 31.5 + 0.25) * np.pi) + 0.5 +def _flag_green(x): return np.sin(x * 31.5 * np.pi) +def _flag_blue(x): return 0.75 * np.sin((x * 31.5 - 0.25) * np.pi) + 0.5 +_flag_data = {'red': _flag_red, 'green': _flag_green, 'blue': _flag_blue} + +def _prism_red(x): return 0.75 * np.sin((x * 20.9 + 0.25) * np.pi) + 0.67 +def _prism_green(x): return 0.75 * np.sin((x * 20.9 - 0.25) * np.pi) + 0.33 +def _prism_blue(x): return -1.1 * np.sin((x * 20.9) * np.pi) +_prism_data = {'red': _prism_red, 'green': _prism_green, 'blue': _prism_blue} + +def _ch_helper(gamma, s, r, h, p0, p1, x): + """Helper function for generating picklable cubehelix colormaps.""" + # Apply gamma factor to emphasise low or high intensity values + xg = x ** gamma + # Calculate amplitude and angle of deviation from the black to white + # diagonal in the plane of constant perceived intensity. + a = h * xg * (1 - xg) / 2 + phi = 2 * np.pi * (s / 3 + r * x) + return xg + a * (p0 * np.cos(phi) + p1 * np.sin(phi)) + +def cubehelix(gamma=1.0, s=0.5, r=-1.5, h=1.0): + """ + Return custom data dictionary of (r, g, b) conversion functions, which can + be used with :func:`register_cmap`, for the cubehelix color scheme. + + Unlike most other color schemes cubehelix was designed by D.A. Green to + be monotonically increasing in terms of perceived brightness. + Also, when printed on a black and white postscript printer, the scheme + results in a greyscale with monotonically increasing brightness. + This color scheme is named cubehelix because the (r, g, b) values produced + can be visualised as a squashed helix around the diagonal in the + (r, g, b) color cube. + + For a unit color cube (i.e. 3D coordinates for (r, g, b) each in the + range 0 to 1) the color scheme starts at (r, g, b) = (0, 0, 0), i.e. black, + and finishes at (r, g, b) = (1, 1, 1), i.e. white. For some fraction *x*, + between 0 and 1, the color is the corresponding grey value at that + fraction along the black to white diagonal (x, x, x) plus a color + element. This color element is calculated in a plane of constant + perceived intensity and controlled by the following parameters. + + Parameters + ---------- + gamma : float, default: 1 + Gamma factor emphasizing either low intensity values (gamma < 1), or + high intensity values (gamma > 1). + s : float, default: 0.5 (purple) + The starting color. + r : float, default: -1.5 + The number of r, g, b rotations in color that are made from the start + to the end of the color scheme. The default of -1.5 corresponds to -> + B -> G -> R -> B. + h : float, default: 1 + The hue, i.e. how saturated the colors are. If this parameter is zero + then the color scheme is purely a greyscale. + """ + return {'red': partial(_ch_helper, gamma, s, r, h, -0.14861, 1.78277), + 'green': partial(_ch_helper, gamma, s, r, h, -0.29227, -0.90649), + 'blue': partial(_ch_helper, gamma, s, r, h, 1.97294, 0.0)} + +_cubehelix_data = cubehelix() + +_bwr_data = ((0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0)) +_brg_data = ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)) + +# Gnuplot palette functions +def _g0(x): return 0 +def _g1(x): return 0.5 +def _g2(x): return 1 +def _g3(x): return x +def _g4(x): return x ** 2 +def _g5(x): return x ** 3 +def _g6(x): return x ** 4 +def _g7(x): return np.sqrt(x) +def _g8(x): return np.sqrt(np.sqrt(x)) +def _g9(x): return np.sin(x * np.pi / 2) +def _g10(x): return np.cos(x * np.pi / 2) +def _g11(x): return np.abs(x - 0.5) +def _g12(x): return (2 * x - 1) ** 2 +def _g13(x): return np.sin(x * np.pi) +def _g14(x): return np.abs(np.cos(x * np.pi)) +def _g15(x): return np.sin(x * 2 * np.pi) +def _g16(x): return np.cos(x * 2 * np.pi) +def _g17(x): return np.abs(np.sin(x * 2 * np.pi)) +def _g18(x): return np.abs(np.cos(x * 2 * np.pi)) +def _g19(x): return np.abs(np.sin(x * 4 * np.pi)) +def _g20(x): return np.abs(np.cos(x * 4 * np.pi)) +def _g21(x): return 3 * x +def _g22(x): return 3 * x - 1 +def _g23(x): return 3 * x - 2 +def _g24(x): return np.abs(3 * x - 1) +def _g25(x): return np.abs(3 * x - 2) +def _g26(x): return (3 * x - 1) / 2 +def _g27(x): return (3 * x - 2) / 2 +def _g28(x): return np.abs((3 * x - 1) / 2) +def _g29(x): return np.abs((3 * x - 2) / 2) +def _g30(x): return x / 0.32 - 0.78125 +def _g31(x): return 2 * x - 0.84 +def _g32(x): + ret = np.zeros(len(x)) + m = (x < 0.25) + ret[m] = 4 * x[m] + m = (x >= 0.25) & (x < 0.92) + ret[m] = -2 * x[m] + 1.84 + m = (x >= 0.92) + ret[m] = x[m] / 0.08 - 11.5 + return ret +def _g33(x): return np.abs(2 * x - 0.5) +def _g34(x): return 2 * x +def _g35(x): return 2 * x - 0.5 +def _g36(x): return 2 * x - 1 + +gfunc = {i: globals()[f"_g{i}"] for i in range(37)} + +_gnuplot_data = { + 'red': gfunc[7], + 'green': gfunc[5], + 'blue': gfunc[15], +} + +_gnuplot2_data = { + 'red': gfunc[30], + 'green': gfunc[31], + 'blue': gfunc[32], +} + +_ocean_data = { + 'red': gfunc[23], + 'green': gfunc[28], + 'blue': gfunc[3], +} + +_afmhot_data = { + 'red': gfunc[34], + 'green': gfunc[35], + 'blue': gfunc[36], +} + +_rainbow_data = { + 'red': gfunc[33], + 'green': gfunc[13], + 'blue': gfunc[10], +} + +_seismic_data = ( + (0.0, 0.0, 0.3), (0.0, 0.0, 1.0), + (1.0, 1.0, 1.0), (1.0, 0.0, 0.0), + (0.5, 0.0, 0.0)) + +_terrain_data = ( + (0.00, (0.2, 0.2, 0.6)), + (0.15, (0.0, 0.6, 1.0)), + (0.25, (0.0, 0.8, 0.4)), + (0.50, (1.0, 1.0, 0.6)), + (0.75, (0.5, 0.36, 0.33)), + (1.00, (1.0, 1.0, 1.0))) + +_gray_data = {'red': ((0., 0, 0), (1., 1, 1)), + 'green': ((0., 0, 0), (1., 1, 1)), + 'blue': ((0., 0, 0), (1., 1, 1))} + +_hot_data = {'red': ((0., 0.0416, 0.0416), + (0.365079, 1.000000, 1.000000), + (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), + (0.365079, 0.000000, 0.000000), + (0.746032, 1.000000, 1.000000), + (1.0, 1.0, 1.0)), + 'blue': ((0., 0., 0.), + (0.746032, 0.000000, 0.000000), + (1.0, 1.0, 1.0))} + +_hsv_data = {'red': ((0., 1., 1.), + (0.158730, 1.000000, 1.000000), + (0.174603, 0.968750, 0.968750), + (0.333333, 0.031250, 0.031250), + (0.349206, 0.000000, 0.000000), + (0.666667, 0.000000, 0.000000), + (0.682540, 0.031250, 0.031250), + (0.841270, 0.968750, 0.968750), + (0.857143, 1.000000, 1.000000), + (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), + (0.158730, 0.937500, 0.937500), + (0.174603, 1.000000, 1.000000), + (0.507937, 1.000000, 1.000000), + (0.666667, 0.062500, 0.062500), + (0.682540, 0.000000, 0.000000), + (1.0, 0., 0.)), + 'blue': ((0., 0., 0.), + (0.333333, 0.000000, 0.000000), + (0.349206, 0.062500, 0.062500), + (0.507937, 1.000000, 1.000000), + (0.841270, 1.000000, 1.000000), + (0.857143, 0.937500, 0.937500), + (1.0, 0.09375, 0.09375))} + +_jet_data = {'red': ((0.00, 0, 0), + (0.35, 0, 0), + (0.66, 1, 1), + (0.89, 1, 1), + (1.00, 0.5, 0.5)), + 'green': ((0.000, 0, 0), + (0.125, 0, 0), + (0.375, 1, 1), + (0.640, 1, 1), + (0.910, 0, 0), + (1.000, 0, 0)), + 'blue': ((0.00, 0.5, 0.5), + (0.11, 1, 1), + (0.34, 1, 1), + (0.65, 0, 0), + (1.00, 0, 0))} + +_pink_data = {'red': ((0., 0.1178, 0.1178), (0.015873, 0.195857, 0.195857), + (0.031746, 0.250661, 0.250661), + (0.047619, 0.295468, 0.295468), + (0.063492, 0.334324, 0.334324), + (0.079365, 0.369112, 0.369112), + (0.095238, 0.400892, 0.400892), + (0.111111, 0.430331, 0.430331), + (0.126984, 0.457882, 0.457882), + (0.142857, 0.483867, 0.483867), + (0.158730, 0.508525, 0.508525), + (0.174603, 0.532042, 0.532042), + (0.190476, 0.554563, 0.554563), + (0.206349, 0.576204, 0.576204), + (0.222222, 0.597061, 0.597061), + (0.238095, 0.617213, 0.617213), + (0.253968, 0.636729, 0.636729), + (0.269841, 0.655663, 0.655663), + (0.285714, 0.674066, 0.674066), + (0.301587, 0.691980, 0.691980), + (0.317460, 0.709441, 0.709441), + (0.333333, 0.726483, 0.726483), + (0.349206, 0.743134, 0.743134), + (0.365079, 0.759421, 0.759421), + (0.380952, 0.766356, 0.766356), + (0.396825, 0.773229, 0.773229), + (0.412698, 0.780042, 0.780042), + (0.428571, 0.786796, 0.786796), + (0.444444, 0.793492, 0.793492), + (0.460317, 0.800132, 0.800132), + (0.476190, 0.806718, 0.806718), + (0.492063, 0.813250, 0.813250), + (0.507937, 0.819730, 0.819730), + (0.523810, 0.826160, 0.826160), + (0.539683, 0.832539, 0.832539), + (0.555556, 0.838870, 0.838870), + (0.571429, 0.845154, 0.845154), + (0.587302, 0.851392, 0.851392), + (0.603175, 0.857584, 0.857584), + (0.619048, 0.863731, 0.863731), + (0.634921, 0.869835, 0.869835), + (0.650794, 0.875897, 0.875897), + (0.666667, 0.881917, 0.881917), + (0.682540, 0.887896, 0.887896), + (0.698413, 0.893835, 0.893835), + (0.714286, 0.899735, 0.899735), + (0.730159, 0.905597, 0.905597), + (0.746032, 0.911421, 0.911421), + (0.761905, 0.917208, 0.917208), + (0.777778, 0.922958, 0.922958), + (0.793651, 0.928673, 0.928673), + (0.809524, 0.934353, 0.934353), + (0.825397, 0.939999, 0.939999), + (0.841270, 0.945611, 0.945611), + (0.857143, 0.951190, 0.951190), + (0.873016, 0.956736, 0.956736), + (0.888889, 0.962250, 0.962250), + (0.904762, 0.967733, 0.967733), + (0.920635, 0.973185, 0.973185), + (0.936508, 0.978607, 0.978607), + (0.952381, 0.983999, 0.983999), + (0.968254, 0.989361, 0.989361), + (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), (0.015873, 0.102869, 0.102869), + (0.031746, 0.145479, 0.145479), + (0.047619, 0.178174, 0.178174), + (0.063492, 0.205738, 0.205738), + (0.079365, 0.230022, 0.230022), + (0.095238, 0.251976, 0.251976), + (0.111111, 0.272166, 0.272166), + (0.126984, 0.290957, 0.290957), + (0.142857, 0.308607, 0.308607), + (0.158730, 0.325300, 0.325300), + (0.174603, 0.341178, 0.341178), + (0.190476, 0.356348, 0.356348), + (0.206349, 0.370899, 0.370899), + (0.222222, 0.384900, 0.384900), + (0.238095, 0.398410, 0.398410), + (0.253968, 0.411476, 0.411476), + (0.269841, 0.424139, 0.424139), + (0.285714, 0.436436, 0.436436), + (0.301587, 0.448395, 0.448395), + (0.317460, 0.460044, 0.460044), + (0.333333, 0.471405, 0.471405), + (0.349206, 0.482498, 0.482498), + (0.365079, 0.493342, 0.493342), + (0.380952, 0.517549, 0.517549), + (0.396825, 0.540674, 0.540674), + (0.412698, 0.562849, 0.562849), + (0.428571, 0.584183, 0.584183), + (0.444444, 0.604765, 0.604765), + (0.460317, 0.624669, 0.624669), + (0.476190, 0.643958, 0.643958), + (0.492063, 0.662687, 0.662687), + (0.507937, 0.680900, 0.680900), + (0.523810, 0.698638, 0.698638), + (0.539683, 0.715937, 0.715937), + (0.555556, 0.732828, 0.732828), + (0.571429, 0.749338, 0.749338), + (0.587302, 0.765493, 0.765493), + (0.603175, 0.781313, 0.781313), + (0.619048, 0.796819, 0.796819), + (0.634921, 0.812029, 0.812029), + (0.650794, 0.826960, 0.826960), + (0.666667, 0.841625, 0.841625), + (0.682540, 0.856040, 0.856040), + (0.698413, 0.870216, 0.870216), + (0.714286, 0.884164, 0.884164), + (0.730159, 0.897896, 0.897896), + (0.746032, 0.911421, 0.911421), + (0.761905, 0.917208, 0.917208), + (0.777778, 0.922958, 0.922958), + (0.793651, 0.928673, 0.928673), + (0.809524, 0.934353, 0.934353), + (0.825397, 0.939999, 0.939999), + (0.841270, 0.945611, 0.945611), + (0.857143, 0.951190, 0.951190), + (0.873016, 0.956736, 0.956736), + (0.888889, 0.962250, 0.962250), + (0.904762, 0.967733, 0.967733), + (0.920635, 0.973185, 0.973185), + (0.936508, 0.978607, 0.978607), + (0.952381, 0.983999, 0.983999), + (0.968254, 0.989361, 0.989361), + (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)), + 'blue': ((0., 0., 0.), (0.015873, 0.102869, 0.102869), + (0.031746, 0.145479, 0.145479), + (0.047619, 0.178174, 0.178174), + (0.063492, 0.205738, 0.205738), + (0.079365, 0.230022, 0.230022), + (0.095238, 0.251976, 0.251976), + (0.111111, 0.272166, 0.272166), + (0.126984, 0.290957, 0.290957), + (0.142857, 0.308607, 0.308607), + (0.158730, 0.325300, 0.325300), + (0.174603, 0.341178, 0.341178), + (0.190476, 0.356348, 0.356348), + (0.206349, 0.370899, 0.370899), + (0.222222, 0.384900, 0.384900), + (0.238095, 0.398410, 0.398410), + (0.253968, 0.411476, 0.411476), + (0.269841, 0.424139, 0.424139), + (0.285714, 0.436436, 0.436436), + (0.301587, 0.448395, 0.448395), + (0.317460, 0.460044, 0.460044), + (0.333333, 0.471405, 0.471405), + (0.349206, 0.482498, 0.482498), + (0.365079, 0.493342, 0.493342), + (0.380952, 0.503953, 0.503953), + (0.396825, 0.514344, 0.514344), + (0.412698, 0.524531, 0.524531), + (0.428571, 0.534522, 0.534522), + (0.444444, 0.544331, 0.544331), + (0.460317, 0.553966, 0.553966), + (0.476190, 0.563436, 0.563436), + (0.492063, 0.572750, 0.572750), + (0.507937, 0.581914, 0.581914), + (0.523810, 0.590937, 0.590937), + (0.539683, 0.599824, 0.599824), + (0.555556, 0.608581, 0.608581), + (0.571429, 0.617213, 0.617213), + (0.587302, 0.625727, 0.625727), + (0.603175, 0.634126, 0.634126), + (0.619048, 0.642416, 0.642416), + (0.634921, 0.650600, 0.650600), + (0.650794, 0.658682, 0.658682), + (0.666667, 0.666667, 0.666667), + (0.682540, 0.674556, 0.674556), + (0.698413, 0.682355, 0.682355), + (0.714286, 0.690066, 0.690066), + (0.730159, 0.697691, 0.697691), + (0.746032, 0.705234, 0.705234), + (0.761905, 0.727166, 0.727166), + (0.777778, 0.748455, 0.748455), + (0.793651, 0.769156, 0.769156), + (0.809524, 0.789314, 0.789314), + (0.825397, 0.808969, 0.808969), + (0.841270, 0.828159, 0.828159), + (0.857143, 0.846913, 0.846913), + (0.873016, 0.865261, 0.865261), + (0.888889, 0.883229, 0.883229), + (0.904762, 0.900837, 0.900837), + (0.920635, 0.918109, 0.918109), + (0.936508, 0.935061, 0.935061), + (0.952381, 0.951711, 0.951711), + (0.968254, 0.968075, 0.968075), + (0.984127, 0.984167, 0.984167), (1.0, 1.0, 1.0))} + +_spring_data = {'red': ((0., 1., 1.), (1.0, 1.0, 1.0)), + 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)), + 'blue': ((0., 1., 1.), (1.0, 0.0, 0.0))} + + +_summer_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)), + 'green': ((0., 0.5, 0.5), (1.0, 1.0, 1.0)), + 'blue': ((0., 0.4, 0.4), (1.0, 0.4, 0.4))} + + +_winter_data = {'red': ((0., 0., 0.), (1.0, 0.0, 0.0)), + 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)), + 'blue': ((0., 1., 1.), (1.0, 0.5, 0.5))} + +_nipy_spectral_data = { + 'red': [ + (0.0, 0.0, 0.0), (0.05, 0.4667, 0.4667), + (0.10, 0.5333, 0.5333), (0.15, 0.0, 0.0), + (0.20, 0.0, 0.0), (0.25, 0.0, 0.0), + (0.30, 0.0, 0.0), (0.35, 0.0, 0.0), + (0.40, 0.0, 0.0), (0.45, 0.0, 0.0), + (0.50, 0.0, 0.0), (0.55, 0.0, 0.0), + (0.60, 0.0, 0.0), (0.65, 0.7333, 0.7333), + (0.70, 0.9333, 0.9333), (0.75, 1.0, 1.0), + (0.80, 1.0, 1.0), (0.85, 1.0, 1.0), + (0.90, 0.8667, 0.8667), (0.95, 0.80, 0.80), + (1.0, 0.80, 0.80), + ], + 'green': [ + (0.0, 0.0, 0.0), (0.05, 0.0, 0.0), + (0.10, 0.0, 0.0), (0.15, 0.0, 0.0), + (0.20, 0.0, 0.0), (0.25, 0.4667, 0.4667), + (0.30, 0.6000, 0.6000), (0.35, 0.6667, 0.6667), + (0.40, 0.6667, 0.6667), (0.45, 0.6000, 0.6000), + (0.50, 0.7333, 0.7333), (0.55, 0.8667, 0.8667), + (0.60, 1.0, 1.0), (0.65, 1.0, 1.0), + (0.70, 0.9333, 0.9333), (0.75, 0.8000, 0.8000), + (0.80, 0.6000, 0.6000), (0.85, 0.0, 0.0), + (0.90, 0.0, 0.0), (0.95, 0.0, 0.0), + (1.0, 0.80, 0.80), + ], + 'blue': [ + (0.0, 0.0, 0.0), (0.05, 0.5333, 0.5333), + (0.10, 0.6000, 0.6000), (0.15, 0.6667, 0.6667), + (0.20, 0.8667, 0.8667), (0.25, 0.8667, 0.8667), + (0.30, 0.8667, 0.8667), (0.35, 0.6667, 0.6667), + (0.40, 0.5333, 0.5333), (0.45, 0.0, 0.0), + (0.5, 0.0, 0.0), (0.55, 0.0, 0.0), + (0.60, 0.0, 0.0), (0.65, 0.0, 0.0), + (0.70, 0.0, 0.0), (0.75, 0.0, 0.0), + (0.80, 0.0, 0.0), (0.85, 0.0, 0.0), + (0.90, 0.0, 0.0), (0.95, 0.0, 0.0), + (1.0, 0.80, 0.80), + ], +} + + +# 34 colormaps based on color specifications and designs +# developed by Cynthia Brewer (https://colorbrewer2.org/). +# The ColorBrewer palettes have been included under the terms +# of an Apache-stype license (for details, see the file +# LICENSE_COLORBREWER in the license directory of the matplotlib +# source distribution). + +# RGB values taken from Brewer's Excel sheet, divided by 255 + +_Blues_data = ( + (0.96862745098039216, 0.98431372549019602, 1.0 ), + (0.87058823529411766, 0.92156862745098034, 0.96862745098039216), + (0.77647058823529413, 0.85882352941176465, 0.93725490196078431), + (0.61960784313725492, 0.792156862745098 , 0.88235294117647056), + (0.41960784313725491, 0.68235294117647061, 0.83921568627450982), + (0.25882352941176473, 0.5725490196078431 , 0.77647058823529413), + (0.12941176470588237, 0.44313725490196076, 0.70980392156862748), + (0.03137254901960784, 0.31764705882352939, 0.61176470588235299), + (0.03137254901960784, 0.18823529411764706, 0.41960784313725491) + ) + +_BrBG_data = ( + (0.32941176470588235, 0.18823529411764706, 0.0196078431372549 ), + (0.5490196078431373 , 0.31764705882352939, 0.0392156862745098 ), + (0.74901960784313726, 0.50588235294117645, 0.17647058823529413), + (0.87450980392156863, 0.76078431372549016, 0.49019607843137253), + (0.96470588235294119, 0.90980392156862744, 0.76470588235294112), + (0.96078431372549022, 0.96078431372549022, 0.96078431372549022), + (0.7803921568627451 , 0.91764705882352937, 0.89803921568627454), + (0.50196078431372548, 0.80392156862745101, 0.75686274509803919), + (0.20784313725490197, 0.59215686274509804, 0.5607843137254902 ), + (0.00392156862745098, 0.4 , 0.36862745098039218), + (0.0 , 0.23529411764705882, 0.18823529411764706) + ) + +_BuGn_data = ( + (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807), + (0.89803921568627454, 0.96078431372549022, 0.97647058823529409), + (0.8 , 0.92549019607843142, 0.90196078431372551), + (0.6 , 0.84705882352941175, 0.78823529411764703), + (0.4 , 0.76078431372549016, 0.64313725490196083), + (0.25490196078431371, 0.68235294117647061, 0.46274509803921571), + (0.13725490196078433, 0.54509803921568623, 0.27058823529411763), + (0.0 , 0.42745098039215684, 0.17254901960784313), + (0.0 , 0.26666666666666666, 0.10588235294117647) + ) + +_BuPu_data = ( + (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807), + (0.8784313725490196 , 0.92549019607843142, 0.95686274509803926), + (0.74901960784313726, 0.82745098039215681, 0.90196078431372551), + (0.61960784313725492, 0.73725490196078436, 0.85490196078431369), + (0.5490196078431373 , 0.58823529411764708, 0.77647058823529413), + (0.5490196078431373 , 0.41960784313725491, 0.69411764705882351), + (0.53333333333333333, 0.25490196078431371, 0.61568627450980395), + (0.50588235294117645, 0.05882352941176471, 0.48627450980392156), + (0.30196078431372547, 0.0 , 0.29411764705882354) + ) + +_GnBu_data = ( + (0.96862745098039216, 0.9882352941176471 , 0.94117647058823528), + (0.8784313725490196 , 0.95294117647058818, 0.85882352941176465), + (0.8 , 0.92156862745098034, 0.77254901960784317), + (0.6588235294117647 , 0.8666666666666667 , 0.70980392156862748), + (0.4823529411764706 , 0.8 , 0.7686274509803922 ), + (0.30588235294117649, 0.70196078431372544, 0.82745098039215681), + (0.16862745098039217, 0.5490196078431373 , 0.74509803921568629), + (0.03137254901960784, 0.40784313725490196, 0.67450980392156867), + (0.03137254901960784, 0.25098039215686274, 0.50588235294117645) + ) + +_Greens_data = ( + (0.96862745098039216, 0.9882352941176471 , 0.96078431372549022), + (0.89803921568627454, 0.96078431372549022, 0.8784313725490196 ), + (0.7803921568627451 , 0.9137254901960784 , 0.75294117647058822), + (0.63137254901960782, 0.85098039215686272, 0.60784313725490191), + (0.45490196078431372, 0.7686274509803922 , 0.46274509803921571), + (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116), + (0.13725490196078433, 0.54509803921568623, 0.27058823529411763), + (0.0 , 0.42745098039215684, 0.17254901960784313), + (0.0 , 0.26666666666666666, 0.10588235294117647) + ) + +_Greys_data = ( + (1.0 , 1.0 , 1.0 ), + (0.94117647058823528, 0.94117647058823528, 0.94117647058823528), + (0.85098039215686272, 0.85098039215686272, 0.85098039215686272), + (0.74117647058823533, 0.74117647058823533, 0.74117647058823533), + (0.58823529411764708, 0.58823529411764708, 0.58823529411764708), + (0.45098039215686275, 0.45098039215686275, 0.45098039215686275), + (0.32156862745098042, 0.32156862745098042, 0.32156862745098042), + (0.14509803921568629, 0.14509803921568629, 0.14509803921568629), + (0.0 , 0.0 , 0.0 ) + ) + +_Oranges_data = ( + (1.0 , 0.96078431372549022, 0.92156862745098034), + (0.99607843137254903, 0.90196078431372551, 0.80784313725490198), + (0.99215686274509807, 0.81568627450980391, 0.63529411764705879), + (0.99215686274509807, 0.68235294117647061, 0.41960784313725491), + (0.99215686274509807, 0.55294117647058827, 0.23529411764705882), + (0.94509803921568625, 0.41176470588235292, 0.07450980392156863), + (0.85098039215686272, 0.28235294117647058, 0.00392156862745098), + (0.65098039215686276, 0.21176470588235294, 0.01176470588235294), + (0.49803921568627452, 0.15294117647058825, 0.01568627450980392) + ) + +_OrRd_data = ( + (1.0 , 0.96862745098039216, 0.92549019607843142), + (0.99607843137254903, 0.90980392156862744, 0.78431372549019607), + (0.99215686274509807, 0.83137254901960789, 0.61960784313725492), + (0.99215686274509807, 0.73333333333333328, 0.51764705882352946), + (0.9882352941176471 , 0.55294117647058827, 0.34901960784313724), + (0.93725490196078431, 0.396078431372549 , 0.28235294117647058), + (0.84313725490196079, 0.18823529411764706, 0.12156862745098039), + (0.70196078431372544, 0.0 , 0.0 ), + (0.49803921568627452, 0.0 , 0.0 ) + ) + +_PiYG_data = ( + (0.55686274509803924, 0.00392156862745098, 0.32156862745098042), + (0.77254901960784317, 0.10588235294117647, 0.49019607843137253), + (0.87058823529411766, 0.46666666666666667, 0.68235294117647061), + (0.94509803921568625, 0.71372549019607845, 0.85490196078431369), + (0.99215686274509807, 0.8784313725490196 , 0.93725490196078431), + (0.96862745098039216, 0.96862745098039216, 0.96862745098039216), + (0.90196078431372551, 0.96078431372549022, 0.81568627450980391), + (0.72156862745098038, 0.88235294117647056, 0.52549019607843139), + (0.49803921568627452, 0.73725490196078436, 0.25490196078431371), + (0.30196078431372547, 0.5725490196078431 , 0.12941176470588237), + (0.15294117647058825, 0.39215686274509803, 0.09803921568627451) + ) + +_PRGn_data = ( + (0.25098039215686274, 0.0 , 0.29411764705882354), + (0.46274509803921571, 0.16470588235294117, 0.51372549019607838), + (0.6 , 0.4392156862745098 , 0.6705882352941176 ), + (0.76078431372549016, 0.6470588235294118 , 0.81176470588235294), + (0.90588235294117647, 0.83137254901960789, 0.90980392156862744), + (0.96862745098039216, 0.96862745098039216, 0.96862745098039216), + (0.85098039215686272, 0.94117647058823528, 0.82745098039215681), + (0.65098039215686276, 0.85882352941176465, 0.62745098039215685), + (0.35294117647058826, 0.68235294117647061, 0.38039215686274508), + (0.10588235294117647, 0.47058823529411764, 0.21568627450980393), + (0.0 , 0.26666666666666666, 0.10588235294117647) + ) + +_PuBu_data = ( + (1.0 , 0.96862745098039216, 0.98431372549019602), + (0.92549019607843142, 0.90588235294117647, 0.94901960784313721), + (0.81568627450980391, 0.81960784313725488, 0.90196078431372551), + (0.65098039215686276, 0.74117647058823533, 0.85882352941176465), + (0.45490196078431372, 0.66274509803921566, 0.81176470588235294), + (0.21176470588235294, 0.56470588235294117, 0.75294117647058822), + (0.0196078431372549 , 0.4392156862745098 , 0.69019607843137254), + (0.01568627450980392, 0.35294117647058826, 0.55294117647058827), + (0.00784313725490196, 0.2196078431372549 , 0.34509803921568627) + ) + +_PuBuGn_data = ( + (1.0 , 0.96862745098039216, 0.98431372549019602), + (0.92549019607843142, 0.88627450980392153, 0.94117647058823528), + (0.81568627450980391, 0.81960784313725488, 0.90196078431372551), + (0.65098039215686276, 0.74117647058823533, 0.85882352941176465), + (0.40392156862745099, 0.66274509803921566, 0.81176470588235294), + (0.21176470588235294, 0.56470588235294117, 0.75294117647058822), + (0.00784313725490196, 0.50588235294117645, 0.54117647058823526), + (0.00392156862745098, 0.42352941176470588, 0.34901960784313724), + (0.00392156862745098, 0.27450980392156865, 0.21176470588235294) + ) + +_PuOr_data = ( + (0.49803921568627452, 0.23137254901960785, 0.03137254901960784), + (0.70196078431372544, 0.34509803921568627, 0.02352941176470588), + (0.8784313725490196 , 0.50980392156862742, 0.07843137254901961), + (0.99215686274509807, 0.72156862745098038, 0.38823529411764707), + (0.99607843137254903, 0.8784313725490196 , 0.71372549019607845), + (0.96862745098039216, 0.96862745098039216, 0.96862745098039216), + (0.84705882352941175, 0.85490196078431369, 0.92156862745098034), + (0.69803921568627447, 0.6705882352941176 , 0.82352941176470584), + (0.50196078431372548, 0.45098039215686275, 0.67450980392156867), + (0.32941176470588235, 0.15294117647058825, 0.53333333333333333), + (0.17647058823529413, 0.0 , 0.29411764705882354) + ) + +_PuRd_data = ( + (0.96862745098039216, 0.95686274509803926, 0.97647058823529409), + (0.90588235294117647, 0.88235294117647056, 0.93725490196078431), + (0.83137254901960789, 0.72549019607843135, 0.85490196078431369), + (0.78823529411764703, 0.58039215686274515, 0.7803921568627451 ), + (0.87450980392156863, 0.396078431372549 , 0.69019607843137254), + (0.90588235294117647, 0.16078431372549021, 0.54117647058823526), + (0.80784313725490198, 0.07058823529411765, 0.33725490196078434), + (0.59607843137254901, 0.0 , 0.2627450980392157 ), + (0.40392156862745099, 0.0 , 0.12156862745098039) + ) + +_Purples_data = ( + (0.9882352941176471 , 0.98431372549019602, 0.99215686274509807), + (0.93725490196078431, 0.92941176470588238, 0.96078431372549022), + (0.85490196078431369, 0.85490196078431369, 0.92156862745098034), + (0.73725490196078436, 0.74117647058823533, 0.86274509803921573), + (0.61960784313725492, 0.60392156862745094, 0.78431372549019607), + (0.50196078431372548, 0.49019607843137253, 0.72941176470588232), + (0.41568627450980394, 0.31764705882352939, 0.63921568627450975), + (0.32941176470588235, 0.15294117647058825, 0.5607843137254902 ), + (0.24705882352941178, 0.0 , 0.49019607843137253) + ) + +_RdBu_data = ( + (0.40392156862745099, 0.0 , 0.12156862745098039), + (0.69803921568627447, 0.09411764705882353, 0.16862745098039217), + (0.83921568627450982, 0.37647058823529411, 0.30196078431372547), + (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742), + (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ), + (0.96862745098039216, 0.96862745098039216, 0.96862745098039216), + (0.81960784313725488, 0.89803921568627454, 0.94117647058823528), + (0.5725490196078431 , 0.77254901960784317, 0.87058823529411766), + (0.2627450980392157 , 0.57647058823529407, 0.76470588235294112), + (0.12941176470588237, 0.4 , 0.67450980392156867), + (0.0196078431372549 , 0.18823529411764706, 0.38039215686274508) + ) + +_RdGy_data = ( + (0.40392156862745099, 0.0 , 0.12156862745098039), + (0.69803921568627447, 0.09411764705882353, 0.16862745098039217), + (0.83921568627450982, 0.37647058823529411, 0.30196078431372547), + (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742), + (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ), + (1.0 , 1.0 , 1.0 ), + (0.8784313725490196 , 0.8784313725490196 , 0.8784313725490196 ), + (0.72941176470588232, 0.72941176470588232, 0.72941176470588232), + (0.52941176470588236, 0.52941176470588236, 0.52941176470588236), + (0.30196078431372547, 0.30196078431372547, 0.30196078431372547), + (0.10196078431372549, 0.10196078431372549, 0.10196078431372549) + ) + +_RdPu_data = ( + (1.0 , 0.96862745098039216, 0.95294117647058818), + (0.99215686274509807, 0.8784313725490196 , 0.86666666666666667), + (0.9882352941176471 , 0.77254901960784317, 0.75294117647058822), + (0.98039215686274506, 0.62352941176470589, 0.70980392156862748), + (0.96862745098039216, 0.40784313725490196, 0.63137254901960782), + (0.86666666666666667, 0.20392156862745098, 0.59215686274509804), + (0.68235294117647061, 0.00392156862745098, 0.49411764705882355), + (0.47843137254901963, 0.00392156862745098, 0.46666666666666667), + (0.28627450980392155, 0.0 , 0.41568627450980394) + ) + +_RdYlBu_data = ( + (0.6470588235294118 , 0.0 , 0.14901960784313725), + (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825), + (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ), + (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508), + (0.99607843137254903, 0.8784313725490196 , 0.56470588235294117), + (1.0 , 1.0 , 0.74901960784313726), + (0.8784313725490196 , 0.95294117647058818 , 0.97254901960784312), + (0.6705882352941176 , 0.85098039215686272 , 0.9137254901960784 ), + (0.45490196078431372, 0.67843137254901964 , 0.81960784313725488), + (0.27058823529411763, 0.45882352941176469 , 0.70588235294117652), + (0.19215686274509805, 0.21176470588235294 , 0.58431372549019611) + ) + +_RdYlGn_data = ( + (0.6470588235294118 , 0.0 , 0.14901960784313725), + (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825), + (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ), + (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508), + (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623), + (1.0 , 1.0 , 0.74901960784313726), + (0.85098039215686272, 0.93725490196078431 , 0.54509803921568623), + (0.65098039215686276, 0.85098039215686272 , 0.41568627450980394), + (0.4 , 0.74117647058823533 , 0.38823529411764707), + (0.10196078431372549, 0.59607843137254901 , 0.31372549019607843), + (0.0 , 0.40784313725490196 , 0.21568627450980393) + ) + +_Reds_data = ( + (1.0 , 0.96078431372549022 , 0.94117647058823528), + (0.99607843137254903, 0.8784313725490196 , 0.82352941176470584), + (0.9882352941176471 , 0.73333333333333328 , 0.63137254901960782), + (0.9882352941176471 , 0.5725490196078431 , 0.44705882352941179), + (0.98431372549019602, 0.41568627450980394 , 0.29019607843137257), + (0.93725490196078431, 0.23137254901960785 , 0.17254901960784313), + (0.79607843137254897, 0.094117647058823528, 0.11372549019607843), + (0.6470588235294118 , 0.058823529411764705, 0.08235294117647058), + (0.40392156862745099, 0.0 , 0.05098039215686274) + ) + +_Spectral_data = ( + (0.61960784313725492, 0.003921568627450980, 0.25882352941176473), + (0.83529411764705885, 0.24313725490196078 , 0.30980392156862746), + (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ), + (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508), + (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623), + (1.0 , 1.0 , 0.74901960784313726), + (0.90196078431372551, 0.96078431372549022 , 0.59607843137254901), + (0.6705882352941176 , 0.8666666666666667 , 0.64313725490196083), + (0.4 , 0.76078431372549016 , 0.6470588235294118 ), + (0.19607843137254902, 0.53333333333333333 , 0.74117647058823533), + (0.36862745098039218, 0.30980392156862746 , 0.63529411764705879) + ) + +_YlGn_data = ( + (1.0 , 1.0 , 0.89803921568627454), + (0.96862745098039216, 0.9882352941176471 , 0.72549019607843135), + (0.85098039215686272, 0.94117647058823528 , 0.63921568627450975), + (0.67843137254901964, 0.8666666666666667 , 0.55686274509803924), + (0.47058823529411764, 0.77647058823529413 , 0.47450980392156861), + (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116), + (0.13725490196078433, 0.51764705882352946 , 0.2627450980392157 ), + (0.0 , 0.40784313725490196 , 0.21568627450980393), + (0.0 , 0.27058823529411763 , 0.16078431372549021) + ) + +_YlGnBu_data = ( + (1.0 , 1.0 , 0.85098039215686272), + (0.92941176470588238, 0.97254901960784312 , 0.69411764705882351), + (0.7803921568627451 , 0.9137254901960784 , 0.70588235294117652), + (0.49803921568627452, 0.80392156862745101 , 0.73333333333333328), + (0.25490196078431371, 0.71372549019607845 , 0.7686274509803922 ), + (0.11372549019607843, 0.56862745098039214 , 0.75294117647058822), + (0.13333333333333333, 0.36862745098039218 , 0.6588235294117647 ), + (0.14509803921568629, 0.20392156862745098 , 0.58039215686274515), + (0.03137254901960784, 0.11372549019607843 , 0.34509803921568627) + ) + +_YlOrBr_data = ( + (1.0 , 1.0 , 0.89803921568627454), + (1.0 , 0.96862745098039216 , 0.73725490196078436), + (0.99607843137254903, 0.8901960784313725 , 0.56862745098039214), + (0.99607843137254903, 0.7686274509803922 , 0.30980392156862746), + (0.99607843137254903, 0.6 , 0.16078431372549021), + (0.92549019607843142, 0.4392156862745098 , 0.07843137254901961), + (0.8 , 0.29803921568627451 , 0.00784313725490196), + (0.6 , 0.20392156862745098 , 0.01568627450980392), + (0.4 , 0.14509803921568629 , 0.02352941176470588) + ) + +_YlOrRd_data = ( + (1.0 , 1.0 , 0.8 ), + (1.0 , 0.92941176470588238 , 0.62745098039215685), + (0.99607843137254903, 0.85098039215686272 , 0.46274509803921571), + (0.99607843137254903, 0.69803921568627447 , 0.29803921568627451), + (0.99215686274509807, 0.55294117647058827 , 0.23529411764705882), + (0.9882352941176471 , 0.30588235294117649 , 0.16470588235294117), + (0.8901960784313725 , 0.10196078431372549 , 0.10980392156862745), + (0.74117647058823533, 0.0 , 0.14901960784313725), + (0.50196078431372548, 0.0 , 0.14901960784313725) + ) + + +# ColorBrewer's qualitative maps, implemented using ListedColormap +# for use with mpl.colors.NoNorm + +_Accent_data = ( + (0.49803921568627452, 0.78823529411764703, 0.49803921568627452), + (0.74509803921568629, 0.68235294117647061, 0.83137254901960789), + (0.99215686274509807, 0.75294117647058822, 0.52549019607843139), + (1.0, 1.0, 0.6 ), + (0.2196078431372549, 0.42352941176470588, 0.69019607843137254), + (0.94117647058823528, 0.00784313725490196, 0.49803921568627452), + (0.74901960784313726, 0.35686274509803922, 0.09019607843137254), + (0.4, 0.4, 0.4 ), + ) + +_Dark2_data = ( + (0.10588235294117647, 0.61960784313725492, 0.46666666666666667), + (0.85098039215686272, 0.37254901960784315, 0.00784313725490196), + (0.45882352941176469, 0.4392156862745098, 0.70196078431372544), + (0.90588235294117647, 0.16078431372549021, 0.54117647058823526), + (0.4, 0.65098039215686276, 0.11764705882352941), + (0.90196078431372551, 0.6705882352941176, 0.00784313725490196), + (0.65098039215686276, 0.46274509803921571, 0.11372549019607843), + (0.4, 0.4, 0.4 ), + ) + +_Paired_data = ( + (0.65098039215686276, 0.80784313725490198, 0.8901960784313725 ), + (0.12156862745098039, 0.47058823529411764, 0.70588235294117652), + (0.69803921568627447, 0.87450980392156863, 0.54117647058823526), + (0.2, 0.62745098039215685, 0.17254901960784313), + (0.98431372549019602, 0.60392156862745094, 0.6 ), + (0.8901960784313725, 0.10196078431372549, 0.10980392156862745), + (0.99215686274509807, 0.74901960784313726, 0.43529411764705883), + (1.0, 0.49803921568627452, 0.0 ), + (0.792156862745098, 0.69803921568627447, 0.83921568627450982), + (0.41568627450980394, 0.23921568627450981, 0.60392156862745094), + (1.0, 1.0, 0.6 ), + (0.69411764705882351, 0.34901960784313724, 0.15686274509803921), + ) + +_Pastel1_data = ( + (0.98431372549019602, 0.70588235294117652, 0.68235294117647061), + (0.70196078431372544, 0.80392156862745101, 0.8901960784313725 ), + (0.8, 0.92156862745098034, 0.77254901960784317), + (0.87058823529411766, 0.79607843137254897, 0.89411764705882357), + (0.99607843137254903, 0.85098039215686272, 0.65098039215686276), + (1.0, 1.0, 0.8 ), + (0.89803921568627454, 0.84705882352941175, 0.74117647058823533), + (0.99215686274509807, 0.85490196078431369, 0.92549019607843142), + (0.94901960784313721, 0.94901960784313721, 0.94901960784313721), + ) + +_Pastel2_data = ( + (0.70196078431372544, 0.88627450980392153, 0.80392156862745101), + (0.99215686274509807, 0.80392156862745101, 0.67450980392156867), + (0.79607843137254897, 0.83529411764705885, 0.90980392156862744), + (0.95686274509803926, 0.792156862745098, 0.89411764705882357), + (0.90196078431372551, 0.96078431372549022, 0.78823529411764703), + (1.0, 0.94901960784313721, 0.68235294117647061), + (0.94509803921568625, 0.88627450980392153, 0.8 ), + (0.8, 0.8, 0.8 ), + ) + +_Set1_data = ( + (0.89411764705882357, 0.10196078431372549, 0.10980392156862745), + (0.21568627450980393, 0.49411764705882355, 0.72156862745098038), + (0.30196078431372547, 0.68627450980392157, 0.29019607843137257), + (0.59607843137254901, 0.30588235294117649, 0.63921568627450975), + (1.0, 0.49803921568627452, 0.0 ), + (1.0, 1.0, 0.2 ), + (0.65098039215686276, 0.33725490196078434, 0.15686274509803921), + (0.96862745098039216, 0.50588235294117645, 0.74901960784313726), + (0.6, 0.6, 0.6), + ) + +_Set2_data = ( + (0.4, 0.76078431372549016, 0.6470588235294118 ), + (0.9882352941176471, 0.55294117647058827, 0.3843137254901961 ), + (0.55294117647058827, 0.62745098039215685, 0.79607843137254897), + (0.90588235294117647, 0.54117647058823526, 0.76470588235294112), + (0.65098039215686276, 0.84705882352941175, 0.32941176470588235), + (1.0, 0.85098039215686272, 0.18431372549019609), + (0.89803921568627454, 0.7686274509803922, 0.58039215686274515), + (0.70196078431372544, 0.70196078431372544, 0.70196078431372544), + ) + +_Set3_data = ( + (0.55294117647058827, 0.82745098039215681, 0.7803921568627451 ), + (1.0, 1.0, 0.70196078431372544), + (0.74509803921568629, 0.72941176470588232, 0.85490196078431369), + (0.98431372549019602, 0.50196078431372548, 0.44705882352941179), + (0.50196078431372548, 0.69411764705882351, 0.82745098039215681), + (0.99215686274509807, 0.70588235294117652, 0.3843137254901961 ), + (0.70196078431372544, 0.87058823529411766, 0.41176470588235292), + (0.9882352941176471, 0.80392156862745101, 0.89803921568627454), + (0.85098039215686272, 0.85098039215686272, 0.85098039215686272), + (0.73725490196078436, 0.50196078431372548, 0.74117647058823533), + (0.8, 0.92156862745098034, 0.77254901960784317), + (1.0, 0.92941176470588238, 0.43529411764705883), + ) + + +# The next 7 palettes are from the Yorick scientific visualization package, +# an evolution of the GIST package, both by David H. Munro. +# They are released under a BSD-like license (see LICENSE_YORICK in +# the license directory of the matplotlib source distribution). +# +# Most palette functions have been reduced to simple function descriptions +# by Reinier Heeres, since the rgb components were mostly straight lines. +# gist_earth_data and gist_ncar_data were simplified by a script and some +# manual effort. + +_gist_earth_data = \ +{'red': ( +(0.0, 0.0, 0.0000), +(0.2824, 0.1882, 0.1882), +(0.4588, 0.2714, 0.2714), +(0.5490, 0.4719, 0.4719), +(0.6980, 0.7176, 0.7176), +(0.7882, 0.7553, 0.7553), +(1.0000, 0.9922, 0.9922), +), 'green': ( +(0.0, 0.0, 0.0000), +(0.0275, 0.0000, 0.0000), +(0.1098, 0.1893, 0.1893), +(0.1647, 0.3035, 0.3035), +(0.2078, 0.3841, 0.3841), +(0.2824, 0.5020, 0.5020), +(0.5216, 0.6397, 0.6397), +(0.6980, 0.7171, 0.7171), +(0.7882, 0.6392, 0.6392), +(0.7922, 0.6413, 0.6413), +(0.8000, 0.6447, 0.6447), +(0.8078, 0.6481, 0.6481), +(0.8157, 0.6549, 0.6549), +(0.8667, 0.6991, 0.6991), +(0.8745, 0.7103, 0.7103), +(0.8824, 0.7216, 0.7216), +(0.8902, 0.7323, 0.7323), +(0.8980, 0.7430, 0.7430), +(0.9412, 0.8275, 0.8275), +(0.9569, 0.8635, 0.8635), +(0.9647, 0.8816, 0.8816), +(0.9961, 0.9733, 0.9733), +(1.0000, 0.9843, 0.9843), +), 'blue': ( +(0.0, 0.0, 0.0000), +(0.0039, 0.1684, 0.1684), +(0.0078, 0.2212, 0.2212), +(0.0275, 0.4329, 0.4329), +(0.0314, 0.4549, 0.4549), +(0.2824, 0.5004, 0.5004), +(0.4667, 0.2748, 0.2748), +(0.5451, 0.3205, 0.3205), +(0.7843, 0.3961, 0.3961), +(0.8941, 0.6651, 0.6651), +(1.0000, 0.9843, 0.9843), +)} + +_gist_gray_data = { + 'red': gfunc[3], + 'green': gfunc[3], + 'blue': gfunc[3], +} + +def _gist_heat_red(x): return 1.5 * x +def _gist_heat_green(x): return 2 * x - 1 +def _gist_heat_blue(x): return 4 * x - 3 +_gist_heat_data = { + 'red': _gist_heat_red, 'green': _gist_heat_green, 'blue': _gist_heat_blue} + +_gist_ncar_data = \ +{'red': ( +(0.0, 0.0, 0.0000), +(0.3098, 0.0000, 0.0000), +(0.3725, 0.3993, 0.3993), +(0.4235, 0.5003, 0.5003), +(0.5333, 1.0000, 1.0000), +(0.7922, 1.0000, 1.0000), +(0.8471, 0.6218, 0.6218), +(0.8980, 0.9235, 0.9235), +(1.0000, 0.9961, 0.9961), +), 'green': ( +(0.0, 0.0, 0.0000), +(0.0510, 0.3722, 0.3722), +(0.1059, 0.0000, 0.0000), +(0.1569, 0.7202, 0.7202), +(0.1608, 0.7537, 0.7537), +(0.1647, 0.7752, 0.7752), +(0.2157, 1.0000, 1.0000), +(0.2588, 0.9804, 0.9804), +(0.2706, 0.9804, 0.9804), +(0.3176, 1.0000, 1.0000), +(0.3686, 0.8081, 0.8081), +(0.4275, 1.0000, 1.0000), +(0.5216, 1.0000, 1.0000), +(0.6314, 0.7292, 0.7292), +(0.6863, 0.2796, 0.2796), +(0.7451, 0.0000, 0.0000), +(0.7922, 0.0000, 0.0000), +(0.8431, 0.1753, 0.1753), +(0.8980, 0.5000, 0.5000), +(1.0000, 0.9725, 0.9725), +), 'blue': ( +(0.0, 0.5020, 0.5020), +(0.0510, 0.0222, 0.0222), +(0.1098, 1.0000, 1.0000), +(0.2039, 1.0000, 1.0000), +(0.2627, 0.6145, 0.6145), +(0.3216, 0.0000, 0.0000), +(0.4157, 0.0000, 0.0000), +(0.4745, 0.2342, 0.2342), +(0.5333, 0.0000, 0.0000), +(0.5804, 0.0000, 0.0000), +(0.6314, 0.0549, 0.0549), +(0.6902, 0.0000, 0.0000), +(0.7373, 0.0000, 0.0000), +(0.7922, 0.9738, 0.9738), +(0.8000, 1.0000, 1.0000), +(0.8431, 1.0000, 1.0000), +(0.8980, 0.9341, 0.9341), +(1.0000, 0.9961, 0.9961), +)} + +_gist_rainbow_data = ( + (0.000, (1.00, 0.00, 0.16)), + (0.030, (1.00, 0.00, 0.00)), + (0.215, (1.00, 1.00, 0.00)), + (0.400, (0.00, 1.00, 0.00)), + (0.586, (0.00, 1.00, 1.00)), + (0.770, (0.00, 0.00, 1.00)), + (0.954, (1.00, 0.00, 1.00)), + (1.000, (1.00, 0.00, 0.75)) +) + +_gist_stern_data = { + 'red': ( + (0.000, 0.000, 0.000), (0.0547, 1.000, 1.000), + (0.250, 0.027, 0.250), # (0.2500, 0.250, 0.250), + (1.000, 1.000, 1.000)), + 'green': ((0, 0, 0), (1, 1, 1)), + 'blue': ( + (0.000, 0.000, 0.000), (0.500, 1.000, 1.000), + (0.735, 0.000, 0.000), (1.000, 1.000, 1.000)) +} + +def _gist_yarg(x): return 1 - x +_gist_yarg_data = {'red': _gist_yarg, 'green': _gist_yarg, 'blue': _gist_yarg} + +# This bipolar colormap was generated from CoolWarmFloat33.csv of +# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland. +# +_coolwarm_data = { + 'red': [ + (0.0, 0.2298057, 0.2298057), + (0.03125, 0.26623388, 0.26623388), + (0.0625, 0.30386891, 0.30386891), + (0.09375, 0.342804478, 0.342804478), + (0.125, 0.38301334, 0.38301334), + (0.15625, 0.424369608, 0.424369608), + (0.1875, 0.46666708, 0.46666708), + (0.21875, 0.509635204, 0.509635204), + (0.25, 0.552953156, 0.552953156), + (0.28125, 0.596262162, 0.596262162), + (0.3125, 0.639176211, 0.639176211), + (0.34375, 0.681291281, 0.681291281), + (0.375, 0.722193294, 0.722193294), + (0.40625, 0.761464949, 0.761464949), + (0.4375, 0.798691636, 0.798691636), + (0.46875, 0.833466556, 0.833466556), + (0.5, 0.865395197, 0.865395197), + (0.53125, 0.897787179, 0.897787179), + (0.5625, 0.924127593, 0.924127593), + (0.59375, 0.944468518, 0.944468518), + (0.625, 0.958852946, 0.958852946), + (0.65625, 0.96732803, 0.96732803), + (0.6875, 0.969954137, 0.969954137), + (0.71875, 0.966811177, 0.966811177), + (0.75, 0.958003065, 0.958003065), + (0.78125, 0.943660866, 0.943660866), + (0.8125, 0.923944917, 0.923944917), + (0.84375, 0.89904617, 0.89904617), + (0.875, 0.869186849, 0.869186849), + (0.90625, 0.834620542, 0.834620542), + (0.9375, 0.795631745, 0.795631745), + (0.96875, 0.752534934, 0.752534934), + (1.0, 0.705673158, 0.705673158)], + 'green': [ + (0.0, 0.298717966, 0.298717966), + (0.03125, 0.353094838, 0.353094838), + (0.0625, 0.406535296, 0.406535296), + (0.09375, 0.458757618, 0.458757618), + (0.125, 0.50941904, 0.50941904), + (0.15625, 0.558148092, 0.558148092), + (0.1875, 0.604562568, 0.604562568), + (0.21875, 0.648280772, 0.648280772), + (0.25, 0.688929332, 0.688929332), + (0.28125, 0.726149107, 0.726149107), + (0.3125, 0.759599947, 0.759599947), + (0.34375, 0.788964712, 0.788964712), + (0.375, 0.813952739, 0.813952739), + (0.40625, 0.834302879, 0.834302879), + (0.4375, 0.849786142, 0.849786142), + (0.46875, 0.860207984, 0.860207984), + (0.5, 0.86541021, 0.86541021), + (0.53125, 0.848937047, 0.848937047), + (0.5625, 0.827384882, 0.827384882), + (0.59375, 0.800927443, 0.800927443), + (0.625, 0.769767752, 0.769767752), + (0.65625, 0.734132809, 0.734132809), + (0.6875, 0.694266682, 0.694266682), + (0.71875, 0.650421156, 0.650421156), + (0.75, 0.602842431, 0.602842431), + (0.78125, 0.551750968, 0.551750968), + (0.8125, 0.49730856, 0.49730856), + (0.84375, 0.439559467, 0.439559467), + (0.875, 0.378313092, 0.378313092), + (0.90625, 0.312874446, 0.312874446), + (0.9375, 0.24128379, 0.24128379), + (0.96875, 0.157246067, 0.157246067), + (1.0, 0.01555616, 0.01555616)], + 'blue': [ + (0.0, 0.753683153, 0.753683153), + (0.03125, 0.801466763, 0.801466763), + (0.0625, 0.84495867, 0.84495867), + (0.09375, 0.883725899, 0.883725899), + (0.125, 0.917387822, 0.917387822), + (0.15625, 0.945619588, 0.945619588), + (0.1875, 0.968154911, 0.968154911), + (0.21875, 0.98478814, 0.98478814), + (0.25, 0.995375608, 0.995375608), + (0.28125, 0.999836203, 0.999836203), + (0.3125, 0.998151185, 0.998151185), + (0.34375, 0.990363227, 0.990363227), + (0.375, 0.976574709, 0.976574709), + (0.40625, 0.956945269, 0.956945269), + (0.4375, 0.931688648, 0.931688648), + (0.46875, 0.901068838, 0.901068838), + (0.5, 0.865395561, 0.865395561), + (0.53125, 0.820880546, 0.820880546), + (0.5625, 0.774508472, 0.774508472), + (0.59375, 0.726736146, 0.726736146), + (0.625, 0.678007945, 0.678007945), + (0.65625, 0.628751763, 0.628751763), + (0.6875, 0.579375448, 0.579375448), + (0.71875, 0.530263762, 0.530263762), + (0.75, 0.481775914, 0.481775914), + (0.78125, 0.434243684, 0.434243684), + (0.8125, 0.387970225, 0.387970225), + (0.84375, 0.343229596, 0.343229596), + (0.875, 0.300267182, 0.300267182), + (0.90625, 0.259301199, 0.259301199), + (0.9375, 0.220525627, 0.220525627), + (0.96875, 0.184115123, 0.184115123), + (1.0, 0.150232812, 0.150232812)] + } + +# Implementation of Carey Rappaport's CMRmap. +# See `A Color Map for Effective Black-and-White Rendering of Color-Scale +# Images' by Carey Rappaport +# https://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m +_CMRmap_data = {'red': ((0.000, 0.00, 0.00), + (0.125, 0.15, 0.15), + (0.250, 0.30, 0.30), + (0.375, 0.60, 0.60), + (0.500, 1.00, 1.00), + (0.625, 0.90, 0.90), + (0.750, 0.90, 0.90), + (0.875, 0.90, 0.90), + (1.000, 1.00, 1.00)), + 'green': ((0.000, 0.00, 0.00), + (0.125, 0.15, 0.15), + (0.250, 0.15, 0.15), + (0.375, 0.20, 0.20), + (0.500, 0.25, 0.25), + (0.625, 0.50, 0.50), + (0.750, 0.75, 0.75), + (0.875, 0.90, 0.90), + (1.000, 1.00, 1.00)), + 'blue': ((0.000, 0.00, 0.00), + (0.125, 0.50, 0.50), + (0.250, 0.75, 0.75), + (0.375, 0.50, 0.50), + (0.500, 0.15, 0.15), + (0.625, 0.00, 0.00), + (0.750, 0.10, 0.10), + (0.875, 0.50, 0.50), + (1.000, 1.00, 1.00))} + + +# An MIT licensed, colorblind-friendly heatmap from Wistia: +# https://github.com/wistia/heatmap-palette +# https://wistia.com/learn/culture/heatmaps-for-colorblindness +# +# >>> import matplotlib.colors as c +# >>> colors = ["#e4ff7a", "#ffe81a", "#ffbd00", "#ffa000", "#fc7f00"] +# >>> cm = c.LinearSegmentedColormap.from_list('wistia', colors) +# >>> _wistia_data = cm._segmentdata +# >>> del _wistia_data['alpha'] +# +_wistia_data = { + 'red': [(0.0, 0.8941176470588236, 0.8941176470588236), + (0.25, 1.0, 1.0), + (0.5, 1.0, 1.0), + (0.75, 1.0, 1.0), + (1.0, 0.9882352941176471, 0.9882352941176471)], + 'green': [(0.0, 1.0, 1.0), + (0.25, 0.9098039215686274, 0.9098039215686274), + (0.5, 0.7411764705882353, 0.7411764705882353), + (0.75, 0.6274509803921569, 0.6274509803921569), + (1.0, 0.4980392156862745, 0.4980392156862745)], + 'blue': [(0.0, 0.47843137254901963, 0.47843137254901963), + (0.25, 0.10196078431372549, 0.10196078431372549), + (0.5, 0.0, 0.0), + (0.75, 0.0, 0.0), + (1.0, 0.0, 0.0)], +} + + +# Categorical palettes from Vega: +# https://github.com/vega/vega/wiki/Scales +# (divided by 255) +# + +_tab10_data = ( + (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4 + (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e + (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c + (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728 + (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd + (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b + (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2 + (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f + (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22 + (0.09019607843137255, 0.7450980392156863, 0.8117647058823529), # 17becf +) + +_tab20_data = ( + (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4 + (0.6823529411764706, 0.7803921568627451, 0.9098039215686274 ), # aec7e8 + (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e + (1.0, 0.7333333333333333, 0.47058823529411764 ), # ffbb78 + (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c + (0.596078431372549, 0.8745098039215686, 0.5411764705882353 ), # 98df8a + (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728 + (1.0, 0.596078431372549, 0.5882352941176471 ), # ff9896 + (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd + (0.7725490196078432, 0.6901960784313725, 0.8352941176470589 ), # c5b0d5 + (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b + (0.7686274509803922, 0.611764705882353, 0.5803921568627451 ), # c49c94 + (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2 + (0.9686274509803922, 0.7137254901960784, 0.8235294117647058 ), # f7b6d2 + (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f + (0.7803921568627451, 0.7803921568627451, 0.7803921568627451 ), # c7c7c7 + (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22 + (0.8588235294117647, 0.8588235294117647, 0.5529411764705883 ), # dbdb8d + (0.09019607843137255, 0.7450980392156863, 0.8117647058823529 ), # 17becf + (0.6196078431372549, 0.8549019607843137, 0.8980392156862745), # 9edae5 +) + +_tab20b_data = ( + (0.2235294117647059, 0.23137254901960785, 0.4745098039215686 ), # 393b79 + (0.3215686274509804, 0.32941176470588235, 0.6392156862745098 ), # 5254a3 + (0.4196078431372549, 0.43137254901960786, 0.8117647058823529 ), # 6b6ecf + (0.611764705882353, 0.6196078431372549, 0.8705882352941177 ), # 9c9ede + (0.38823529411764707, 0.4745098039215686, 0.2235294117647059 ), # 637939 + (0.5490196078431373, 0.6352941176470588, 0.3215686274509804 ), # 8ca252 + (0.7098039215686275, 0.8117647058823529, 0.4196078431372549 ), # b5cf6b + (0.807843137254902, 0.8588235294117647, 0.611764705882353 ), # cedb9c + (0.5490196078431373, 0.42745098039215684, 0.19215686274509805), # 8c6d31 + (0.7411764705882353, 0.6196078431372549, 0.2235294117647059 ), # bd9e39 + (0.9058823529411765, 0.7294117647058823, 0.3215686274509804 ), # e7ba52 + (0.9058823529411765, 0.796078431372549, 0.5803921568627451 ), # e7cb94 + (0.5176470588235295, 0.23529411764705882, 0.2235294117647059 ), # 843c39 + (0.6784313725490196, 0.28627450980392155, 0.2901960784313726 ), # ad494a + (0.8392156862745098, 0.3803921568627451, 0.4196078431372549 ), # d6616b + (0.9058823529411765, 0.5882352941176471, 0.611764705882353 ), # e7969c + (0.4823529411764706, 0.2549019607843137, 0.45098039215686275), # 7b4173 + (0.6470588235294118, 0.3176470588235294, 0.5803921568627451 ), # a55194 + (0.807843137254902, 0.42745098039215684, 0.7411764705882353 ), # ce6dbd + (0.8705882352941177, 0.6196078431372549, 0.8392156862745098 ), # de9ed6 +) + +_tab20c_data = ( + (0.19215686274509805, 0.5098039215686274, 0.7411764705882353 ), # 3182bd + (0.4196078431372549, 0.6823529411764706, 0.8392156862745098 ), # 6baed6 + (0.6196078431372549, 0.792156862745098, 0.8823529411764706 ), # 9ecae1 + (0.7764705882352941, 0.8588235294117647, 0.9372549019607843 ), # c6dbef + (0.9019607843137255, 0.3333333333333333, 0.050980392156862744), # e6550d + (0.9921568627450981, 0.5529411764705883, 0.23529411764705882 ), # fd8d3c + (0.9921568627450981, 0.6823529411764706, 0.4196078431372549 ), # fdae6b + (0.9921568627450981, 0.8156862745098039, 0.6352941176470588 ), # fdd0a2 + (0.19215686274509805, 0.6392156862745098, 0.32941176470588235 ), # 31a354 + (0.4549019607843137, 0.7686274509803922, 0.4627450980392157 ), # 74c476 + (0.6313725490196078, 0.8509803921568627, 0.6078431372549019 ), # a1d99b + (0.7803921568627451, 0.9137254901960784, 0.7529411764705882 ), # c7e9c0 + (0.4588235294117647, 0.4196078431372549, 0.6941176470588235 ), # 756bb1 + (0.6196078431372549, 0.6039215686274509, 0.7843137254901961 ), # 9e9ac8 + (0.7372549019607844, 0.7411764705882353, 0.8627450980392157 ), # bcbddc + (0.8549019607843137, 0.8549019607843137, 0.9215686274509803 ), # dadaeb + (0.38823529411764707, 0.38823529411764707, 0.38823529411764707 ), # 636363 + (0.5882352941176471, 0.5882352941176471, 0.5882352941176471 ), # 969696 + (0.7411764705882353, 0.7411764705882353, 0.7411764705882353 ), # bdbdbd + (0.8509803921568627, 0.8509803921568627, 0.8509803921568627 ), # d9d9d9 +) + + +datad = { + 'Blues': _Blues_data, + 'BrBG': _BrBG_data, + 'BuGn': _BuGn_data, + 'BuPu': _BuPu_data, + 'CMRmap': _CMRmap_data, + 'GnBu': _GnBu_data, + 'Greens': _Greens_data, + 'Greys': _Greys_data, + 'OrRd': _OrRd_data, + 'Oranges': _Oranges_data, + 'PRGn': _PRGn_data, + 'PiYG': _PiYG_data, + 'PuBu': _PuBu_data, + 'PuBuGn': _PuBuGn_data, + 'PuOr': _PuOr_data, + 'PuRd': _PuRd_data, + 'Purples': _Purples_data, + 'RdBu': _RdBu_data, + 'RdGy': _RdGy_data, + 'RdPu': _RdPu_data, + 'RdYlBu': _RdYlBu_data, + 'RdYlGn': _RdYlGn_data, + 'Reds': _Reds_data, + 'Spectral': _Spectral_data, + 'Wistia': _wistia_data, + 'YlGn': _YlGn_data, + 'YlGnBu': _YlGnBu_data, + 'YlOrBr': _YlOrBr_data, + 'YlOrRd': _YlOrRd_data, + 'afmhot': _afmhot_data, + 'autumn': _autumn_data, + 'binary': _binary_data, + 'bone': _bone_data, + 'brg': _brg_data, + 'bwr': _bwr_data, + 'cool': _cool_data, + 'coolwarm': _coolwarm_data, + 'copper': _copper_data, + 'cubehelix': _cubehelix_data, + 'flag': _flag_data, + 'gist_earth': _gist_earth_data, + 'gist_gray': _gist_gray_data, + 'gist_heat': _gist_heat_data, + 'gist_ncar': _gist_ncar_data, + 'gist_rainbow': _gist_rainbow_data, + 'gist_stern': _gist_stern_data, + 'gist_yarg': _gist_yarg_data, + 'gnuplot': _gnuplot_data, + 'gnuplot2': _gnuplot2_data, + 'gray': _gray_data, + 'hot': _hot_data, + 'hsv': _hsv_data, + 'jet': _jet_data, + 'nipy_spectral': _nipy_spectral_data, + 'ocean': _ocean_data, + 'pink': _pink_data, + 'prism': _prism_data, + 'rainbow': _rainbow_data, + 'seismic': _seismic_data, + 'spring': _spring_data, + 'summer': _summer_data, + 'terrain': _terrain_data, + 'winter': _winter_data, + # Qualitative + 'Accent': {'listed': _Accent_data}, + 'Dark2': {'listed': _Dark2_data}, + 'Paired': {'listed': _Paired_data}, + 'Pastel1': {'listed': _Pastel1_data}, + 'Pastel2': {'listed': _Pastel2_data}, + 'Set1': {'listed': _Set1_data}, + 'Set2': {'listed': _Set2_data}, + 'Set3': {'listed': _Set3_data}, + 'tab10': {'listed': _tab10_data}, + 'tab20': {'listed': _tab20_data}, + 'tab20b': {'listed': _tab20b_data}, + 'tab20c': {'listed': _tab20c_data}, +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm_listed.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm_listed.py new file mode 100644 index 00000000..a331ad74 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_cm_listed.py @@ -0,0 +1,2071 @@ +from .colors import ListedColormap + +_magma_data = [[0.001462, 0.000466, 0.013866], + [0.002258, 0.001295, 0.018331], + [0.003279, 0.002305, 0.023708], + [0.004512, 0.003490, 0.029965], + [0.005950, 0.004843, 0.037130], + [0.007588, 0.006356, 0.044973], + [0.009426, 0.008022, 0.052844], + [0.011465, 0.009828, 0.060750], + [0.013708, 0.011771, 0.068667], + [0.016156, 0.013840, 0.076603], + [0.018815, 0.016026, 0.084584], + [0.021692, 0.018320, 0.092610], + [0.024792, 0.020715, 0.100676], + [0.028123, 0.023201, 0.108787], + [0.031696, 0.025765, 0.116965], + [0.035520, 0.028397, 0.125209], + [0.039608, 0.031090, 0.133515], + [0.043830, 0.033830, 0.141886], + [0.048062, 0.036607, 0.150327], + [0.052320, 0.039407, 0.158841], + [0.056615, 0.042160, 0.167446], + [0.060949, 0.044794, 0.176129], + [0.065330, 0.047318, 0.184892], + [0.069764, 0.049726, 0.193735], + [0.074257, 0.052017, 0.202660], + [0.078815, 0.054184, 0.211667], + [0.083446, 0.056225, 0.220755], + [0.088155, 0.058133, 0.229922], + [0.092949, 0.059904, 0.239164], + [0.097833, 0.061531, 0.248477], + [0.102815, 0.063010, 0.257854], + [0.107899, 0.064335, 0.267289], + [0.113094, 0.065492, 0.276784], + [0.118405, 0.066479, 0.286321], + [0.123833, 0.067295, 0.295879], + [0.129380, 0.067935, 0.305443], + [0.135053, 0.068391, 0.315000], + [0.140858, 0.068654, 0.324538], + [0.146785, 0.068738, 0.334011], + [0.152839, 0.068637, 0.343404], + [0.159018, 0.068354, 0.352688], + [0.165308, 0.067911, 0.361816], + [0.171713, 0.067305, 0.370771], + [0.178212, 0.066576, 0.379497], + [0.184801, 0.065732, 0.387973], + [0.191460, 0.064818, 0.396152], + [0.198177, 0.063862, 0.404009], + [0.204935, 0.062907, 0.411514], + [0.211718, 0.061992, 0.418647], + [0.218512, 0.061158, 0.425392], + [0.225302, 0.060445, 0.431742], + [0.232077, 0.059889, 0.437695], + [0.238826, 0.059517, 0.443256], + [0.245543, 0.059352, 0.448436], + [0.252220, 0.059415, 0.453248], + [0.258857, 0.059706, 0.457710], + [0.265447, 0.060237, 0.461840], + [0.271994, 0.060994, 0.465660], + [0.278493, 0.061978, 0.469190], + [0.284951, 0.063168, 0.472451], + [0.291366, 0.064553, 0.475462], + [0.297740, 0.066117, 0.478243], + [0.304081, 0.067835, 0.480812], + [0.310382, 0.069702, 0.483186], + [0.316654, 0.071690, 0.485380], + [0.322899, 0.073782, 0.487408], + [0.329114, 0.075972, 0.489287], + [0.335308, 0.078236, 0.491024], + [0.341482, 0.080564, 0.492631], + [0.347636, 0.082946, 0.494121], + [0.353773, 0.085373, 0.495501], + [0.359898, 0.087831, 0.496778], + [0.366012, 0.090314, 0.497960], + [0.372116, 0.092816, 0.499053], + [0.378211, 0.095332, 0.500067], + [0.384299, 0.097855, 0.501002], + [0.390384, 0.100379, 0.501864], + [0.396467, 0.102902, 0.502658], + [0.402548, 0.105420, 0.503386], + [0.408629, 0.107930, 0.504052], + [0.414709, 0.110431, 0.504662], + [0.420791, 0.112920, 0.505215], + [0.426877, 0.115395, 0.505714], + [0.432967, 0.117855, 0.506160], + [0.439062, 0.120298, 0.506555], + [0.445163, 0.122724, 0.506901], + [0.451271, 0.125132, 0.507198], + [0.457386, 0.127522, 0.507448], + [0.463508, 0.129893, 0.507652], + [0.469640, 0.132245, 0.507809], + [0.475780, 0.134577, 0.507921], + [0.481929, 0.136891, 0.507989], + [0.488088, 0.139186, 0.508011], + [0.494258, 0.141462, 0.507988], + [0.500438, 0.143719, 0.507920], + [0.506629, 0.145958, 0.507806], + [0.512831, 0.148179, 0.507648], + [0.519045, 0.150383, 0.507443], + [0.525270, 0.152569, 0.507192], + [0.531507, 0.154739, 0.506895], + [0.537755, 0.156894, 0.506551], + [0.544015, 0.159033, 0.506159], + [0.550287, 0.161158, 0.505719], + [0.556571, 0.163269, 0.505230], + [0.562866, 0.165368, 0.504692], + [0.569172, 0.167454, 0.504105], + [0.575490, 0.169530, 0.503466], + [0.581819, 0.171596, 0.502777], + [0.588158, 0.173652, 0.502035], + [0.594508, 0.175701, 0.501241], + [0.600868, 0.177743, 0.500394], + [0.607238, 0.179779, 0.499492], + [0.613617, 0.181811, 0.498536], + [0.620005, 0.183840, 0.497524], + [0.626401, 0.185867, 0.496456], + [0.632805, 0.187893, 0.495332], + [0.639216, 0.189921, 0.494150], + [0.645633, 0.191952, 0.492910], + [0.652056, 0.193986, 0.491611], + [0.658483, 0.196027, 0.490253], + [0.664915, 0.198075, 0.488836], + [0.671349, 0.200133, 0.487358], + [0.677786, 0.202203, 0.485819], + [0.684224, 0.204286, 0.484219], + [0.690661, 0.206384, 0.482558], + [0.697098, 0.208501, 0.480835], + [0.703532, 0.210638, 0.479049], + [0.709962, 0.212797, 0.477201], + [0.716387, 0.214982, 0.475290], + [0.722805, 0.217194, 0.473316], + [0.729216, 0.219437, 0.471279], + [0.735616, 0.221713, 0.469180], + [0.742004, 0.224025, 0.467018], + [0.748378, 0.226377, 0.464794], + [0.754737, 0.228772, 0.462509], + [0.761077, 0.231214, 0.460162], + [0.767398, 0.233705, 0.457755], + [0.773695, 0.236249, 0.455289], + [0.779968, 0.238851, 0.452765], + [0.786212, 0.241514, 0.450184], + [0.792427, 0.244242, 0.447543], + [0.798608, 0.247040, 0.444848], + [0.804752, 0.249911, 0.442102], + [0.810855, 0.252861, 0.439305], + [0.816914, 0.255895, 0.436461], + [0.822926, 0.259016, 0.433573], + [0.828886, 0.262229, 0.430644], + [0.834791, 0.265540, 0.427671], + [0.840636, 0.268953, 0.424666], + [0.846416, 0.272473, 0.421631], + [0.852126, 0.276106, 0.418573], + [0.857763, 0.279857, 0.415496], + [0.863320, 0.283729, 0.412403], + [0.868793, 0.287728, 0.409303], + [0.874176, 0.291859, 0.406205], + [0.879464, 0.296125, 0.403118], + [0.884651, 0.300530, 0.400047], + [0.889731, 0.305079, 0.397002], + [0.894700, 0.309773, 0.393995], + [0.899552, 0.314616, 0.391037], + [0.904281, 0.319610, 0.388137], + [0.908884, 0.324755, 0.385308], + [0.913354, 0.330052, 0.382563], + [0.917689, 0.335500, 0.379915], + [0.921884, 0.341098, 0.377376], + [0.925937, 0.346844, 0.374959], + [0.929845, 0.352734, 0.372677], + [0.933606, 0.358764, 0.370541], + [0.937221, 0.364929, 0.368567], + [0.940687, 0.371224, 0.366762], + [0.944006, 0.377643, 0.365136], + [0.947180, 0.384178, 0.363701], + [0.950210, 0.390820, 0.362468], + [0.953099, 0.397563, 0.361438], + [0.955849, 0.404400, 0.360619], + [0.958464, 0.411324, 0.360014], + [0.960949, 0.418323, 0.359630], + [0.963310, 0.425390, 0.359469], + [0.965549, 0.432519, 0.359529], + [0.967671, 0.439703, 0.359810], + [0.969680, 0.446936, 0.360311], + [0.971582, 0.454210, 0.361030], + [0.973381, 0.461520, 0.361965], + [0.975082, 0.468861, 0.363111], + [0.976690, 0.476226, 0.364466], + [0.978210, 0.483612, 0.366025], + [0.979645, 0.491014, 0.367783], + [0.981000, 0.498428, 0.369734], + [0.982279, 0.505851, 0.371874], + [0.983485, 0.513280, 0.374198], + [0.984622, 0.520713, 0.376698], + [0.985693, 0.528148, 0.379371], + [0.986700, 0.535582, 0.382210], + [0.987646, 0.543015, 0.385210], + [0.988533, 0.550446, 0.388365], + [0.989363, 0.557873, 0.391671], + [0.990138, 0.565296, 0.395122], + [0.990871, 0.572706, 0.398714], + [0.991558, 0.580107, 0.402441], + [0.992196, 0.587502, 0.406299], + [0.992785, 0.594891, 0.410283], + [0.993326, 0.602275, 0.414390], + [0.993834, 0.609644, 0.418613], + [0.994309, 0.616999, 0.422950], + [0.994738, 0.624350, 0.427397], + [0.995122, 0.631696, 0.431951], + [0.995480, 0.639027, 0.436607], + [0.995810, 0.646344, 0.441361], + [0.996096, 0.653659, 0.446213], + [0.996341, 0.660969, 0.451160], + [0.996580, 0.668256, 0.456192], + [0.996775, 0.675541, 0.461314], + [0.996925, 0.682828, 0.466526], + [0.997077, 0.690088, 0.471811], + [0.997186, 0.697349, 0.477182], + [0.997254, 0.704611, 0.482635], + [0.997325, 0.711848, 0.488154], + [0.997351, 0.719089, 0.493755], + [0.997351, 0.726324, 0.499428], + [0.997341, 0.733545, 0.505167], + [0.997285, 0.740772, 0.510983], + [0.997228, 0.747981, 0.516859], + [0.997138, 0.755190, 0.522806], + [0.997019, 0.762398, 0.528821], + [0.996898, 0.769591, 0.534892], + [0.996727, 0.776795, 0.541039], + [0.996571, 0.783977, 0.547233], + [0.996369, 0.791167, 0.553499], + [0.996162, 0.798348, 0.559820], + [0.995932, 0.805527, 0.566202], + [0.995680, 0.812706, 0.572645], + [0.995424, 0.819875, 0.579140], + [0.995131, 0.827052, 0.585701], + [0.994851, 0.834213, 0.592307], + [0.994524, 0.841387, 0.598983], + [0.994222, 0.848540, 0.605696], + [0.993866, 0.855711, 0.612482], + [0.993545, 0.862859, 0.619299], + [0.993170, 0.870024, 0.626189], + [0.992831, 0.877168, 0.633109], + [0.992440, 0.884330, 0.640099], + [0.992089, 0.891470, 0.647116], + [0.991688, 0.898627, 0.654202], + [0.991332, 0.905763, 0.661309], + [0.990930, 0.912915, 0.668481], + [0.990570, 0.920049, 0.675675], + [0.990175, 0.927196, 0.682926], + [0.989815, 0.934329, 0.690198], + [0.989434, 0.941470, 0.697519], + [0.989077, 0.948604, 0.704863], + [0.988717, 0.955742, 0.712242], + [0.988367, 0.962878, 0.719649], + [0.988033, 0.970012, 0.727077], + [0.987691, 0.977154, 0.734536], + [0.987387, 0.984288, 0.742002], + [0.987053, 0.991438, 0.749504]] + +_inferno_data = [[0.001462, 0.000466, 0.013866], + [0.002267, 0.001270, 0.018570], + [0.003299, 0.002249, 0.024239], + [0.004547, 0.003392, 0.030909], + [0.006006, 0.004692, 0.038558], + [0.007676, 0.006136, 0.046836], + [0.009561, 0.007713, 0.055143], + [0.011663, 0.009417, 0.063460], + [0.013995, 0.011225, 0.071862], + [0.016561, 0.013136, 0.080282], + [0.019373, 0.015133, 0.088767], + [0.022447, 0.017199, 0.097327], + [0.025793, 0.019331, 0.105930], + [0.029432, 0.021503, 0.114621], + [0.033385, 0.023702, 0.123397], + [0.037668, 0.025921, 0.132232], + [0.042253, 0.028139, 0.141141], + [0.046915, 0.030324, 0.150164], + [0.051644, 0.032474, 0.159254], + [0.056449, 0.034569, 0.168414], + [0.061340, 0.036590, 0.177642], + [0.066331, 0.038504, 0.186962], + [0.071429, 0.040294, 0.196354], + [0.076637, 0.041905, 0.205799], + [0.081962, 0.043328, 0.215289], + [0.087411, 0.044556, 0.224813], + [0.092990, 0.045583, 0.234358], + [0.098702, 0.046402, 0.243904], + [0.104551, 0.047008, 0.253430], + [0.110536, 0.047399, 0.262912], + [0.116656, 0.047574, 0.272321], + [0.122908, 0.047536, 0.281624], + [0.129285, 0.047293, 0.290788], + [0.135778, 0.046856, 0.299776], + [0.142378, 0.046242, 0.308553], + [0.149073, 0.045468, 0.317085], + [0.155850, 0.044559, 0.325338], + [0.162689, 0.043554, 0.333277], + [0.169575, 0.042489, 0.340874], + [0.176493, 0.041402, 0.348111], + [0.183429, 0.040329, 0.354971], + [0.190367, 0.039309, 0.361447], + [0.197297, 0.038400, 0.367535], + [0.204209, 0.037632, 0.373238], + [0.211095, 0.037030, 0.378563], + [0.217949, 0.036615, 0.383522], + [0.224763, 0.036405, 0.388129], + [0.231538, 0.036405, 0.392400], + [0.238273, 0.036621, 0.396353], + [0.244967, 0.037055, 0.400007], + [0.251620, 0.037705, 0.403378], + [0.258234, 0.038571, 0.406485], + [0.264810, 0.039647, 0.409345], + [0.271347, 0.040922, 0.411976], + [0.277850, 0.042353, 0.414392], + [0.284321, 0.043933, 0.416608], + [0.290763, 0.045644, 0.418637], + [0.297178, 0.047470, 0.420491], + [0.303568, 0.049396, 0.422182], + [0.309935, 0.051407, 0.423721], + [0.316282, 0.053490, 0.425116], + [0.322610, 0.055634, 0.426377], + [0.328921, 0.057827, 0.427511], + [0.335217, 0.060060, 0.428524], + [0.341500, 0.062325, 0.429425], + [0.347771, 0.064616, 0.430217], + [0.354032, 0.066925, 0.430906], + [0.360284, 0.069247, 0.431497], + [0.366529, 0.071579, 0.431994], + [0.372768, 0.073915, 0.432400], + [0.379001, 0.076253, 0.432719], + [0.385228, 0.078591, 0.432955], + [0.391453, 0.080927, 0.433109], + [0.397674, 0.083257, 0.433183], + [0.403894, 0.085580, 0.433179], + [0.410113, 0.087896, 0.433098], + [0.416331, 0.090203, 0.432943], + [0.422549, 0.092501, 0.432714], + [0.428768, 0.094790, 0.432412], + [0.434987, 0.097069, 0.432039], + [0.441207, 0.099338, 0.431594], + [0.447428, 0.101597, 0.431080], + [0.453651, 0.103848, 0.430498], + [0.459875, 0.106089, 0.429846], + [0.466100, 0.108322, 0.429125], + [0.472328, 0.110547, 0.428334], + [0.478558, 0.112764, 0.427475], + [0.484789, 0.114974, 0.426548], + [0.491022, 0.117179, 0.425552], + [0.497257, 0.119379, 0.424488], + [0.503493, 0.121575, 0.423356], + [0.509730, 0.123769, 0.422156], + [0.515967, 0.125960, 0.420887], + [0.522206, 0.128150, 0.419549], + [0.528444, 0.130341, 0.418142], + [0.534683, 0.132534, 0.416667], + [0.540920, 0.134729, 0.415123], + [0.547157, 0.136929, 0.413511], + [0.553392, 0.139134, 0.411829], + [0.559624, 0.141346, 0.410078], + [0.565854, 0.143567, 0.408258], + [0.572081, 0.145797, 0.406369], + [0.578304, 0.148039, 0.404411], + [0.584521, 0.150294, 0.402385], + [0.590734, 0.152563, 0.400290], + [0.596940, 0.154848, 0.398125], + [0.603139, 0.157151, 0.395891], + [0.609330, 0.159474, 0.393589], + [0.615513, 0.161817, 0.391219], + [0.621685, 0.164184, 0.388781], + [0.627847, 0.166575, 0.386276], + [0.633998, 0.168992, 0.383704], + [0.640135, 0.171438, 0.381065], + [0.646260, 0.173914, 0.378359], + [0.652369, 0.176421, 0.375586], + [0.658463, 0.178962, 0.372748], + [0.664540, 0.181539, 0.369846], + [0.670599, 0.184153, 0.366879], + [0.676638, 0.186807, 0.363849], + [0.682656, 0.189501, 0.360757], + [0.688653, 0.192239, 0.357603], + [0.694627, 0.195021, 0.354388], + [0.700576, 0.197851, 0.351113], + [0.706500, 0.200728, 0.347777], + [0.712396, 0.203656, 0.344383], + [0.718264, 0.206636, 0.340931], + [0.724103, 0.209670, 0.337424], + [0.729909, 0.212759, 0.333861], + [0.735683, 0.215906, 0.330245], + [0.741423, 0.219112, 0.326576], + [0.747127, 0.222378, 0.322856], + [0.752794, 0.225706, 0.319085], + [0.758422, 0.229097, 0.315266], + [0.764010, 0.232554, 0.311399], + [0.769556, 0.236077, 0.307485], + [0.775059, 0.239667, 0.303526], + [0.780517, 0.243327, 0.299523], + [0.785929, 0.247056, 0.295477], + [0.791293, 0.250856, 0.291390], + [0.796607, 0.254728, 0.287264], + [0.801871, 0.258674, 0.283099], + [0.807082, 0.262692, 0.278898], + [0.812239, 0.266786, 0.274661], + [0.817341, 0.270954, 0.270390], + [0.822386, 0.275197, 0.266085], + [0.827372, 0.279517, 0.261750], + [0.832299, 0.283913, 0.257383], + [0.837165, 0.288385, 0.252988], + [0.841969, 0.292933, 0.248564], + [0.846709, 0.297559, 0.244113], + [0.851384, 0.302260, 0.239636], + [0.855992, 0.307038, 0.235133], + [0.860533, 0.311892, 0.230606], + [0.865006, 0.316822, 0.226055], + [0.869409, 0.321827, 0.221482], + [0.873741, 0.326906, 0.216886], + [0.878001, 0.332060, 0.212268], + [0.882188, 0.337287, 0.207628], + [0.886302, 0.342586, 0.202968], + [0.890341, 0.347957, 0.198286], + [0.894305, 0.353399, 0.193584], + [0.898192, 0.358911, 0.188860], + [0.902003, 0.364492, 0.184116], + [0.905735, 0.370140, 0.179350], + [0.909390, 0.375856, 0.174563], + [0.912966, 0.381636, 0.169755], + [0.916462, 0.387481, 0.164924], + [0.919879, 0.393389, 0.160070], + [0.923215, 0.399359, 0.155193], + [0.926470, 0.405389, 0.150292], + [0.929644, 0.411479, 0.145367], + [0.932737, 0.417627, 0.140417], + [0.935747, 0.423831, 0.135440], + [0.938675, 0.430091, 0.130438], + [0.941521, 0.436405, 0.125409], + [0.944285, 0.442772, 0.120354], + [0.946965, 0.449191, 0.115272], + [0.949562, 0.455660, 0.110164], + [0.952075, 0.462178, 0.105031], + [0.954506, 0.468744, 0.099874], + [0.956852, 0.475356, 0.094695], + [0.959114, 0.482014, 0.089499], + [0.961293, 0.488716, 0.084289], + [0.963387, 0.495462, 0.079073], + [0.965397, 0.502249, 0.073859], + [0.967322, 0.509078, 0.068659], + [0.969163, 0.515946, 0.063488], + [0.970919, 0.522853, 0.058367], + [0.972590, 0.529798, 0.053324], + [0.974176, 0.536780, 0.048392], + [0.975677, 0.543798, 0.043618], + [0.977092, 0.550850, 0.039050], + [0.978422, 0.557937, 0.034931], + [0.979666, 0.565057, 0.031409], + [0.980824, 0.572209, 0.028508], + [0.981895, 0.579392, 0.026250], + [0.982881, 0.586606, 0.024661], + [0.983779, 0.593849, 0.023770], + [0.984591, 0.601122, 0.023606], + [0.985315, 0.608422, 0.024202], + [0.985952, 0.615750, 0.025592], + [0.986502, 0.623105, 0.027814], + [0.986964, 0.630485, 0.030908], + [0.987337, 0.637890, 0.034916], + [0.987622, 0.645320, 0.039886], + [0.987819, 0.652773, 0.045581], + [0.987926, 0.660250, 0.051750], + [0.987945, 0.667748, 0.058329], + [0.987874, 0.675267, 0.065257], + [0.987714, 0.682807, 0.072489], + [0.987464, 0.690366, 0.079990], + [0.987124, 0.697944, 0.087731], + [0.986694, 0.705540, 0.095694], + [0.986175, 0.713153, 0.103863], + [0.985566, 0.720782, 0.112229], + [0.984865, 0.728427, 0.120785], + [0.984075, 0.736087, 0.129527], + [0.983196, 0.743758, 0.138453], + [0.982228, 0.751442, 0.147565], + [0.981173, 0.759135, 0.156863], + [0.980032, 0.766837, 0.166353], + [0.978806, 0.774545, 0.176037], + [0.977497, 0.782258, 0.185923], + [0.976108, 0.789974, 0.196018], + [0.974638, 0.797692, 0.206332], + [0.973088, 0.805409, 0.216877], + [0.971468, 0.813122, 0.227658], + [0.969783, 0.820825, 0.238686], + [0.968041, 0.828515, 0.249972], + [0.966243, 0.836191, 0.261534], + [0.964394, 0.843848, 0.273391], + [0.962517, 0.851476, 0.285546], + [0.960626, 0.859069, 0.298010], + [0.958720, 0.866624, 0.310820], + [0.956834, 0.874129, 0.323974], + [0.954997, 0.881569, 0.337475], + [0.953215, 0.888942, 0.351369], + [0.951546, 0.896226, 0.365627], + [0.950018, 0.903409, 0.380271], + [0.948683, 0.910473, 0.395289], + [0.947594, 0.917399, 0.410665], + [0.946809, 0.924168, 0.426373], + [0.946392, 0.930761, 0.442367], + [0.946403, 0.937159, 0.458592], + [0.946903, 0.943348, 0.474970], + [0.947937, 0.949318, 0.491426], + [0.949545, 0.955063, 0.507860], + [0.951740, 0.960587, 0.524203], + [0.954529, 0.965896, 0.540361], + [0.957896, 0.971003, 0.556275], + [0.961812, 0.975924, 0.571925], + [0.966249, 0.980678, 0.587206], + [0.971162, 0.985282, 0.602154], + [0.976511, 0.989753, 0.616760], + [0.982257, 0.994109, 0.631017], + [0.988362, 0.998364, 0.644924]] + +_plasma_data = [[0.050383, 0.029803, 0.527975], + [0.063536, 0.028426, 0.533124], + [0.075353, 0.027206, 0.538007], + [0.086222, 0.026125, 0.542658], + [0.096379, 0.025165, 0.547103], + [0.105980, 0.024309, 0.551368], + [0.115124, 0.023556, 0.555468], + [0.123903, 0.022878, 0.559423], + [0.132381, 0.022258, 0.563250], + [0.140603, 0.021687, 0.566959], + [0.148607, 0.021154, 0.570562], + [0.156421, 0.020651, 0.574065], + [0.164070, 0.020171, 0.577478], + [0.171574, 0.019706, 0.580806], + [0.178950, 0.019252, 0.584054], + [0.186213, 0.018803, 0.587228], + [0.193374, 0.018354, 0.590330], + [0.200445, 0.017902, 0.593364], + [0.207435, 0.017442, 0.596333], + [0.214350, 0.016973, 0.599239], + [0.221197, 0.016497, 0.602083], + [0.227983, 0.016007, 0.604867], + [0.234715, 0.015502, 0.607592], + [0.241396, 0.014979, 0.610259], + [0.248032, 0.014439, 0.612868], + [0.254627, 0.013882, 0.615419], + [0.261183, 0.013308, 0.617911], + [0.267703, 0.012716, 0.620346], + [0.274191, 0.012109, 0.622722], + [0.280648, 0.011488, 0.625038], + [0.287076, 0.010855, 0.627295], + [0.293478, 0.010213, 0.629490], + [0.299855, 0.009561, 0.631624], + [0.306210, 0.008902, 0.633694], + [0.312543, 0.008239, 0.635700], + [0.318856, 0.007576, 0.637640], + [0.325150, 0.006915, 0.639512], + [0.331426, 0.006261, 0.641316], + [0.337683, 0.005618, 0.643049], + [0.343925, 0.004991, 0.644710], + [0.350150, 0.004382, 0.646298], + [0.356359, 0.003798, 0.647810], + [0.362553, 0.003243, 0.649245], + [0.368733, 0.002724, 0.650601], + [0.374897, 0.002245, 0.651876], + [0.381047, 0.001814, 0.653068], + [0.387183, 0.001434, 0.654177], + [0.393304, 0.001114, 0.655199], + [0.399411, 0.000859, 0.656133], + [0.405503, 0.000678, 0.656977], + [0.411580, 0.000577, 0.657730], + [0.417642, 0.000564, 0.658390], + [0.423689, 0.000646, 0.658956], + [0.429719, 0.000831, 0.659425], + [0.435734, 0.001127, 0.659797], + [0.441732, 0.001540, 0.660069], + [0.447714, 0.002080, 0.660240], + [0.453677, 0.002755, 0.660310], + [0.459623, 0.003574, 0.660277], + [0.465550, 0.004545, 0.660139], + [0.471457, 0.005678, 0.659897], + [0.477344, 0.006980, 0.659549], + [0.483210, 0.008460, 0.659095], + [0.489055, 0.010127, 0.658534], + [0.494877, 0.011990, 0.657865], + [0.500678, 0.014055, 0.657088], + [0.506454, 0.016333, 0.656202], + [0.512206, 0.018833, 0.655209], + [0.517933, 0.021563, 0.654109], + [0.523633, 0.024532, 0.652901], + [0.529306, 0.027747, 0.651586], + [0.534952, 0.031217, 0.650165], + [0.540570, 0.034950, 0.648640], + [0.546157, 0.038954, 0.647010], + [0.551715, 0.043136, 0.645277], + [0.557243, 0.047331, 0.643443], + [0.562738, 0.051545, 0.641509], + [0.568201, 0.055778, 0.639477], + [0.573632, 0.060028, 0.637349], + [0.579029, 0.064296, 0.635126], + [0.584391, 0.068579, 0.632812], + [0.589719, 0.072878, 0.630408], + [0.595011, 0.077190, 0.627917], + [0.600266, 0.081516, 0.625342], + [0.605485, 0.085854, 0.622686], + [0.610667, 0.090204, 0.619951], + [0.615812, 0.094564, 0.617140], + [0.620919, 0.098934, 0.614257], + [0.625987, 0.103312, 0.611305], + [0.631017, 0.107699, 0.608287], + [0.636008, 0.112092, 0.605205], + [0.640959, 0.116492, 0.602065], + [0.645872, 0.120898, 0.598867], + [0.650746, 0.125309, 0.595617], + [0.655580, 0.129725, 0.592317], + [0.660374, 0.134144, 0.588971], + [0.665129, 0.138566, 0.585582], + [0.669845, 0.142992, 0.582154], + [0.674522, 0.147419, 0.578688], + [0.679160, 0.151848, 0.575189], + [0.683758, 0.156278, 0.571660], + [0.688318, 0.160709, 0.568103], + [0.692840, 0.165141, 0.564522], + [0.697324, 0.169573, 0.560919], + [0.701769, 0.174005, 0.557296], + [0.706178, 0.178437, 0.553657], + [0.710549, 0.182868, 0.550004], + [0.714883, 0.187299, 0.546338], + [0.719181, 0.191729, 0.542663], + [0.723444, 0.196158, 0.538981], + [0.727670, 0.200586, 0.535293], + [0.731862, 0.205013, 0.531601], + [0.736019, 0.209439, 0.527908], + [0.740143, 0.213864, 0.524216], + [0.744232, 0.218288, 0.520524], + [0.748289, 0.222711, 0.516834], + [0.752312, 0.227133, 0.513149], + [0.756304, 0.231555, 0.509468], + [0.760264, 0.235976, 0.505794], + [0.764193, 0.240396, 0.502126], + [0.768090, 0.244817, 0.498465], + [0.771958, 0.249237, 0.494813], + [0.775796, 0.253658, 0.491171], + [0.779604, 0.258078, 0.487539], + [0.783383, 0.262500, 0.483918], + [0.787133, 0.266922, 0.480307], + [0.790855, 0.271345, 0.476706], + [0.794549, 0.275770, 0.473117], + [0.798216, 0.280197, 0.469538], + [0.801855, 0.284626, 0.465971], + [0.805467, 0.289057, 0.462415], + [0.809052, 0.293491, 0.458870], + [0.812612, 0.297928, 0.455338], + [0.816144, 0.302368, 0.451816], + [0.819651, 0.306812, 0.448306], + [0.823132, 0.311261, 0.444806], + [0.826588, 0.315714, 0.441316], + [0.830018, 0.320172, 0.437836], + [0.833422, 0.324635, 0.434366], + [0.836801, 0.329105, 0.430905], + [0.840155, 0.333580, 0.427455], + [0.843484, 0.338062, 0.424013], + [0.846788, 0.342551, 0.420579], + [0.850066, 0.347048, 0.417153], + [0.853319, 0.351553, 0.413734], + [0.856547, 0.356066, 0.410322], + [0.859750, 0.360588, 0.406917], + [0.862927, 0.365119, 0.403519], + [0.866078, 0.369660, 0.400126], + [0.869203, 0.374212, 0.396738], + [0.872303, 0.378774, 0.393355], + [0.875376, 0.383347, 0.389976], + [0.878423, 0.387932, 0.386600], + [0.881443, 0.392529, 0.383229], + [0.884436, 0.397139, 0.379860], + [0.887402, 0.401762, 0.376494], + [0.890340, 0.406398, 0.373130], + [0.893250, 0.411048, 0.369768], + [0.896131, 0.415712, 0.366407], + [0.898984, 0.420392, 0.363047], + [0.901807, 0.425087, 0.359688], + [0.904601, 0.429797, 0.356329], + [0.907365, 0.434524, 0.352970], + [0.910098, 0.439268, 0.349610], + [0.912800, 0.444029, 0.346251], + [0.915471, 0.448807, 0.342890], + [0.918109, 0.453603, 0.339529], + [0.920714, 0.458417, 0.336166], + [0.923287, 0.463251, 0.332801], + [0.925825, 0.468103, 0.329435], + [0.928329, 0.472975, 0.326067], + [0.930798, 0.477867, 0.322697], + [0.933232, 0.482780, 0.319325], + [0.935630, 0.487712, 0.315952], + [0.937990, 0.492667, 0.312575], + [0.940313, 0.497642, 0.309197], + [0.942598, 0.502639, 0.305816], + [0.944844, 0.507658, 0.302433], + [0.947051, 0.512699, 0.299049], + [0.949217, 0.517763, 0.295662], + [0.951344, 0.522850, 0.292275], + [0.953428, 0.527960, 0.288883], + [0.955470, 0.533093, 0.285490], + [0.957469, 0.538250, 0.282096], + [0.959424, 0.543431, 0.278701], + [0.961336, 0.548636, 0.275305], + [0.963203, 0.553865, 0.271909], + [0.965024, 0.559118, 0.268513], + [0.966798, 0.564396, 0.265118], + [0.968526, 0.569700, 0.261721], + [0.970205, 0.575028, 0.258325], + [0.971835, 0.580382, 0.254931], + [0.973416, 0.585761, 0.251540], + [0.974947, 0.591165, 0.248151], + [0.976428, 0.596595, 0.244767], + [0.977856, 0.602051, 0.241387], + [0.979233, 0.607532, 0.238013], + [0.980556, 0.613039, 0.234646], + [0.981826, 0.618572, 0.231287], + [0.983041, 0.624131, 0.227937], + [0.984199, 0.629718, 0.224595], + [0.985301, 0.635330, 0.221265], + [0.986345, 0.640969, 0.217948], + [0.987332, 0.646633, 0.214648], + [0.988260, 0.652325, 0.211364], + [0.989128, 0.658043, 0.208100], + [0.989935, 0.663787, 0.204859], + [0.990681, 0.669558, 0.201642], + [0.991365, 0.675355, 0.198453], + [0.991985, 0.681179, 0.195295], + [0.992541, 0.687030, 0.192170], + [0.993032, 0.692907, 0.189084], + [0.993456, 0.698810, 0.186041], + [0.993814, 0.704741, 0.183043], + [0.994103, 0.710698, 0.180097], + [0.994324, 0.716681, 0.177208], + [0.994474, 0.722691, 0.174381], + [0.994553, 0.728728, 0.171622], + [0.994561, 0.734791, 0.168938], + [0.994495, 0.740880, 0.166335], + [0.994355, 0.746995, 0.163821], + [0.994141, 0.753137, 0.161404], + [0.993851, 0.759304, 0.159092], + [0.993482, 0.765499, 0.156891], + [0.993033, 0.771720, 0.154808], + [0.992505, 0.777967, 0.152855], + [0.991897, 0.784239, 0.151042], + [0.991209, 0.790537, 0.149377], + [0.990439, 0.796859, 0.147870], + [0.989587, 0.803205, 0.146529], + [0.988648, 0.809579, 0.145357], + [0.987621, 0.815978, 0.144363], + [0.986509, 0.822401, 0.143557], + [0.985314, 0.828846, 0.142945], + [0.984031, 0.835315, 0.142528], + [0.982653, 0.841812, 0.142303], + [0.981190, 0.848329, 0.142279], + [0.979644, 0.854866, 0.142453], + [0.977995, 0.861432, 0.142808], + [0.976265, 0.868016, 0.143351], + [0.974443, 0.874622, 0.144061], + [0.972530, 0.881250, 0.144923], + [0.970533, 0.887896, 0.145919], + [0.968443, 0.894564, 0.147014], + [0.966271, 0.901249, 0.148180], + [0.964021, 0.907950, 0.149370], + [0.961681, 0.914672, 0.150520], + [0.959276, 0.921407, 0.151566], + [0.956808, 0.928152, 0.152409], + [0.954287, 0.934908, 0.152921], + [0.951726, 0.941671, 0.152925], + [0.949151, 0.948435, 0.152178], + [0.946602, 0.955190, 0.150328], + [0.944152, 0.961916, 0.146861], + [0.941896, 0.968590, 0.140956], + [0.940015, 0.975158, 0.131326]] + +_viridis_data = [[0.267004, 0.004874, 0.329415], + [0.268510, 0.009605, 0.335427], + [0.269944, 0.014625, 0.341379], + [0.271305, 0.019942, 0.347269], + [0.272594, 0.025563, 0.353093], + [0.273809, 0.031497, 0.358853], + [0.274952, 0.037752, 0.364543], + [0.276022, 0.044167, 0.370164], + [0.277018, 0.050344, 0.375715], + [0.277941, 0.056324, 0.381191], + [0.278791, 0.062145, 0.386592], + [0.279566, 0.067836, 0.391917], + [0.280267, 0.073417, 0.397163], + [0.280894, 0.078907, 0.402329], + [0.281446, 0.084320, 0.407414], + [0.281924, 0.089666, 0.412415], + [0.282327, 0.094955, 0.417331], + [0.282656, 0.100196, 0.422160], + [0.282910, 0.105393, 0.426902], + [0.283091, 0.110553, 0.431554], + [0.283197, 0.115680, 0.436115], + [0.283229, 0.120777, 0.440584], + [0.283187, 0.125848, 0.444960], + [0.283072, 0.130895, 0.449241], + [0.282884, 0.135920, 0.453427], + [0.282623, 0.140926, 0.457517], + [0.282290, 0.145912, 0.461510], + [0.281887, 0.150881, 0.465405], + [0.281412, 0.155834, 0.469201], + [0.280868, 0.160771, 0.472899], + [0.280255, 0.165693, 0.476498], + [0.279574, 0.170599, 0.479997], + [0.278826, 0.175490, 0.483397], + [0.278012, 0.180367, 0.486697], + [0.277134, 0.185228, 0.489898], + [0.276194, 0.190074, 0.493001], + [0.275191, 0.194905, 0.496005], + [0.274128, 0.199721, 0.498911], + [0.273006, 0.204520, 0.501721], + [0.271828, 0.209303, 0.504434], + [0.270595, 0.214069, 0.507052], + [0.269308, 0.218818, 0.509577], + [0.267968, 0.223549, 0.512008], + [0.266580, 0.228262, 0.514349], + [0.265145, 0.232956, 0.516599], + [0.263663, 0.237631, 0.518762], + [0.262138, 0.242286, 0.520837], + [0.260571, 0.246922, 0.522828], + [0.258965, 0.251537, 0.524736], + [0.257322, 0.256130, 0.526563], + [0.255645, 0.260703, 0.528312], + [0.253935, 0.265254, 0.529983], + [0.252194, 0.269783, 0.531579], + [0.250425, 0.274290, 0.533103], + [0.248629, 0.278775, 0.534556], + [0.246811, 0.283237, 0.535941], + [0.244972, 0.287675, 0.537260], + [0.243113, 0.292092, 0.538516], + [0.241237, 0.296485, 0.539709], + [0.239346, 0.300855, 0.540844], + [0.237441, 0.305202, 0.541921], + [0.235526, 0.309527, 0.542944], + [0.233603, 0.313828, 0.543914], + [0.231674, 0.318106, 0.544834], + [0.229739, 0.322361, 0.545706], + [0.227802, 0.326594, 0.546532], + [0.225863, 0.330805, 0.547314], + [0.223925, 0.334994, 0.548053], + [0.221989, 0.339161, 0.548752], + [0.220057, 0.343307, 0.549413], + [0.218130, 0.347432, 0.550038], + [0.216210, 0.351535, 0.550627], + [0.214298, 0.355619, 0.551184], + [0.212395, 0.359683, 0.551710], + [0.210503, 0.363727, 0.552206], + [0.208623, 0.367752, 0.552675], + [0.206756, 0.371758, 0.553117], + [0.204903, 0.375746, 0.553533], + [0.203063, 0.379716, 0.553925], + [0.201239, 0.383670, 0.554294], + [0.199430, 0.387607, 0.554642], + [0.197636, 0.391528, 0.554969], + [0.195860, 0.395433, 0.555276], + [0.194100, 0.399323, 0.555565], + [0.192357, 0.403199, 0.555836], + [0.190631, 0.407061, 0.556089], + [0.188923, 0.410910, 0.556326], + [0.187231, 0.414746, 0.556547], + [0.185556, 0.418570, 0.556753], + [0.183898, 0.422383, 0.556944], + [0.182256, 0.426184, 0.557120], + [0.180629, 0.429975, 0.557282], + [0.179019, 0.433756, 0.557430], + [0.177423, 0.437527, 0.557565], + [0.175841, 0.441290, 0.557685], + [0.174274, 0.445044, 0.557792], + [0.172719, 0.448791, 0.557885], + [0.171176, 0.452530, 0.557965], + [0.169646, 0.456262, 0.558030], + [0.168126, 0.459988, 0.558082], + [0.166617, 0.463708, 0.558119], + [0.165117, 0.467423, 0.558141], + [0.163625, 0.471133, 0.558148], + [0.162142, 0.474838, 0.558140], + [0.160665, 0.478540, 0.558115], + [0.159194, 0.482237, 0.558073], + [0.157729, 0.485932, 0.558013], + [0.156270, 0.489624, 0.557936], + [0.154815, 0.493313, 0.557840], + [0.153364, 0.497000, 0.557724], + [0.151918, 0.500685, 0.557587], + [0.150476, 0.504369, 0.557430], + [0.149039, 0.508051, 0.557250], + [0.147607, 0.511733, 0.557049], + [0.146180, 0.515413, 0.556823], + [0.144759, 0.519093, 0.556572], + [0.143343, 0.522773, 0.556295], + [0.141935, 0.526453, 0.555991], + [0.140536, 0.530132, 0.555659], + [0.139147, 0.533812, 0.555298], + [0.137770, 0.537492, 0.554906], + [0.136408, 0.541173, 0.554483], + [0.135066, 0.544853, 0.554029], + [0.133743, 0.548535, 0.553541], + [0.132444, 0.552216, 0.553018], + [0.131172, 0.555899, 0.552459], + [0.129933, 0.559582, 0.551864], + [0.128729, 0.563265, 0.551229], + [0.127568, 0.566949, 0.550556], + [0.126453, 0.570633, 0.549841], + [0.125394, 0.574318, 0.549086], + [0.124395, 0.578002, 0.548287], + [0.123463, 0.581687, 0.547445], + [0.122606, 0.585371, 0.546557], + [0.121831, 0.589055, 0.545623], + [0.121148, 0.592739, 0.544641], + [0.120565, 0.596422, 0.543611], + [0.120092, 0.600104, 0.542530], + [0.119738, 0.603785, 0.541400], + [0.119512, 0.607464, 0.540218], + [0.119423, 0.611141, 0.538982], + [0.119483, 0.614817, 0.537692], + [0.119699, 0.618490, 0.536347], + [0.120081, 0.622161, 0.534946], + [0.120638, 0.625828, 0.533488], + [0.121380, 0.629492, 0.531973], + [0.122312, 0.633153, 0.530398], + [0.123444, 0.636809, 0.528763], + [0.124780, 0.640461, 0.527068], + [0.126326, 0.644107, 0.525311], + [0.128087, 0.647749, 0.523491], + [0.130067, 0.651384, 0.521608], + [0.132268, 0.655014, 0.519661], + [0.134692, 0.658636, 0.517649], + [0.137339, 0.662252, 0.515571], + [0.140210, 0.665859, 0.513427], + [0.143303, 0.669459, 0.511215], + [0.146616, 0.673050, 0.508936], + [0.150148, 0.676631, 0.506589], + [0.153894, 0.680203, 0.504172], + [0.157851, 0.683765, 0.501686], + [0.162016, 0.687316, 0.499129], + [0.166383, 0.690856, 0.496502], + [0.170948, 0.694384, 0.493803], + [0.175707, 0.697900, 0.491033], + [0.180653, 0.701402, 0.488189], + [0.185783, 0.704891, 0.485273], + [0.191090, 0.708366, 0.482284], + [0.196571, 0.711827, 0.479221], + [0.202219, 0.715272, 0.476084], + [0.208030, 0.718701, 0.472873], + [0.214000, 0.722114, 0.469588], + [0.220124, 0.725509, 0.466226], + [0.226397, 0.728888, 0.462789], + [0.232815, 0.732247, 0.459277], + [0.239374, 0.735588, 0.455688], + [0.246070, 0.738910, 0.452024], + [0.252899, 0.742211, 0.448284], + [0.259857, 0.745492, 0.444467], + [0.266941, 0.748751, 0.440573], + [0.274149, 0.751988, 0.436601], + [0.281477, 0.755203, 0.432552], + [0.288921, 0.758394, 0.428426], + [0.296479, 0.761561, 0.424223], + [0.304148, 0.764704, 0.419943], + [0.311925, 0.767822, 0.415586], + [0.319809, 0.770914, 0.411152], + [0.327796, 0.773980, 0.406640], + [0.335885, 0.777018, 0.402049], + [0.344074, 0.780029, 0.397381], + [0.352360, 0.783011, 0.392636], + [0.360741, 0.785964, 0.387814], + [0.369214, 0.788888, 0.382914], + [0.377779, 0.791781, 0.377939], + [0.386433, 0.794644, 0.372886], + [0.395174, 0.797475, 0.367757], + [0.404001, 0.800275, 0.362552], + [0.412913, 0.803041, 0.357269], + [0.421908, 0.805774, 0.351910], + [0.430983, 0.808473, 0.346476], + [0.440137, 0.811138, 0.340967], + [0.449368, 0.813768, 0.335384], + [0.458674, 0.816363, 0.329727], + [0.468053, 0.818921, 0.323998], + [0.477504, 0.821444, 0.318195], + [0.487026, 0.823929, 0.312321], + [0.496615, 0.826376, 0.306377], + [0.506271, 0.828786, 0.300362], + [0.515992, 0.831158, 0.294279], + [0.525776, 0.833491, 0.288127], + [0.535621, 0.835785, 0.281908], + [0.545524, 0.838039, 0.275626], + [0.555484, 0.840254, 0.269281], + [0.565498, 0.842430, 0.262877], + [0.575563, 0.844566, 0.256415], + [0.585678, 0.846661, 0.249897], + [0.595839, 0.848717, 0.243329], + [0.606045, 0.850733, 0.236712], + [0.616293, 0.852709, 0.230052], + [0.626579, 0.854645, 0.223353], + [0.636902, 0.856542, 0.216620], + [0.647257, 0.858400, 0.209861], + [0.657642, 0.860219, 0.203082], + [0.668054, 0.861999, 0.196293], + [0.678489, 0.863742, 0.189503], + [0.688944, 0.865448, 0.182725], + [0.699415, 0.867117, 0.175971], + [0.709898, 0.868751, 0.169257], + [0.720391, 0.870350, 0.162603], + [0.730889, 0.871916, 0.156029], + [0.741388, 0.873449, 0.149561], + [0.751884, 0.874951, 0.143228], + [0.762373, 0.876424, 0.137064], + [0.772852, 0.877868, 0.131109], + [0.783315, 0.879285, 0.125405], + [0.793760, 0.880678, 0.120005], + [0.804182, 0.882046, 0.114965], + [0.814576, 0.883393, 0.110347], + [0.824940, 0.884720, 0.106217], + [0.835270, 0.886029, 0.102646], + [0.845561, 0.887322, 0.099702], + [0.855810, 0.888601, 0.097452], + [0.866013, 0.889868, 0.095953], + [0.876168, 0.891125, 0.095250], + [0.886271, 0.892374, 0.095374], + [0.896320, 0.893616, 0.096335], + [0.906311, 0.894855, 0.098125], + [0.916242, 0.896091, 0.100717], + [0.926106, 0.897330, 0.104071], + [0.935904, 0.898570, 0.108131], + [0.945636, 0.899815, 0.112838], + [0.955300, 0.901065, 0.118128], + [0.964894, 0.902323, 0.123941], + [0.974417, 0.903590, 0.130215], + [0.983868, 0.904867, 0.136897], + [0.993248, 0.906157, 0.143936]] + +_cividis_data = [[0.000000, 0.135112, 0.304751], + [0.000000, 0.138068, 0.311105], + [0.000000, 0.141013, 0.317579], + [0.000000, 0.143951, 0.323982], + [0.000000, 0.146877, 0.330479], + [0.000000, 0.149791, 0.337065], + [0.000000, 0.152673, 0.343704], + [0.000000, 0.155377, 0.350500], + [0.000000, 0.157932, 0.357521], + [0.000000, 0.160495, 0.364534], + [0.000000, 0.163058, 0.371608], + [0.000000, 0.165621, 0.378769], + [0.000000, 0.168204, 0.385902], + [0.000000, 0.170800, 0.393100], + [0.000000, 0.173420, 0.400353], + [0.000000, 0.176082, 0.407577], + [0.000000, 0.178802, 0.414764], + [0.000000, 0.181610, 0.421859], + [0.000000, 0.184550, 0.428802], + [0.000000, 0.186915, 0.435532], + [0.000000, 0.188769, 0.439563], + [0.000000, 0.190950, 0.441085], + [0.000000, 0.193366, 0.441561], + [0.003602, 0.195911, 0.441564], + [0.017852, 0.198528, 0.441248], + [0.032110, 0.201199, 0.440785], + [0.046205, 0.203903, 0.440196], + [0.058378, 0.206629, 0.439531], + [0.068968, 0.209372, 0.438863], + [0.078624, 0.212122, 0.438105], + [0.087465, 0.214879, 0.437342], + [0.095645, 0.217643, 0.436593], + [0.103401, 0.220406, 0.435790], + [0.110658, 0.223170, 0.435067], + [0.117612, 0.225935, 0.434308], + [0.124291, 0.228697, 0.433547], + [0.130669, 0.231458, 0.432840], + [0.136830, 0.234216, 0.432148], + [0.142852, 0.236972, 0.431404], + [0.148638, 0.239724, 0.430752], + [0.154261, 0.242475, 0.430120], + [0.159733, 0.245221, 0.429528], + [0.165113, 0.247965, 0.428908], + [0.170362, 0.250707, 0.428325], + [0.175490, 0.253444, 0.427790], + [0.180503, 0.256180, 0.427299], + [0.185453, 0.258914, 0.426788], + [0.190303, 0.261644, 0.426329], + [0.195057, 0.264372, 0.425924], + [0.199764, 0.267099, 0.425497], + [0.204385, 0.269823, 0.425126], + [0.208926, 0.272546, 0.424809], + [0.213431, 0.275266, 0.424480], + [0.217863, 0.277985, 0.424206], + [0.222264, 0.280702, 0.423914], + [0.226598, 0.283419, 0.423678], + [0.230871, 0.286134, 0.423498], + [0.235120, 0.288848, 0.423304], + [0.239312, 0.291562, 0.423167], + [0.243485, 0.294274, 0.423014], + [0.247605, 0.296986, 0.422917], + [0.251675, 0.299698, 0.422873], + [0.255731, 0.302409, 0.422814], + [0.259740, 0.305120, 0.422810], + [0.263738, 0.307831, 0.422789], + [0.267693, 0.310542, 0.422821], + [0.271639, 0.313253, 0.422837], + [0.275513, 0.315965, 0.422979], + [0.279411, 0.318677, 0.423031], + [0.283240, 0.321390, 0.423211], + [0.287065, 0.324103, 0.423373], + [0.290884, 0.326816, 0.423517], + [0.294669, 0.329531, 0.423716], + [0.298421, 0.332247, 0.423973], + [0.302169, 0.334963, 0.424213], + [0.305886, 0.337681, 0.424512], + [0.309601, 0.340399, 0.424790], + [0.313287, 0.343120, 0.425120], + [0.316941, 0.345842, 0.425512], + [0.320595, 0.348565, 0.425889], + [0.324250, 0.351289, 0.426250], + [0.327875, 0.354016, 0.426670], + [0.331474, 0.356744, 0.427144], + [0.335073, 0.359474, 0.427605], + [0.338673, 0.362206, 0.428053], + [0.342246, 0.364939, 0.428559], + [0.345793, 0.367676, 0.429127], + [0.349341, 0.370414, 0.429685], + [0.352892, 0.373153, 0.430226], + [0.356418, 0.375896, 0.430823], + [0.359916, 0.378641, 0.431501], + [0.363446, 0.381388, 0.432075], + [0.366923, 0.384139, 0.432796], + [0.370430, 0.386890, 0.433428], + [0.373884, 0.389646, 0.434209], + [0.377371, 0.392404, 0.434890], + [0.380830, 0.395164, 0.435653], + [0.384268, 0.397928, 0.436475], + [0.387705, 0.400694, 0.437305], + [0.391151, 0.403464, 0.438096], + [0.394568, 0.406236, 0.438986], + [0.397991, 0.409011, 0.439848], + [0.401418, 0.411790, 0.440708], + [0.404820, 0.414572, 0.441642], + [0.408226, 0.417357, 0.442570], + [0.411607, 0.420145, 0.443577], + [0.414992, 0.422937, 0.444578], + [0.418383, 0.425733, 0.445560], + [0.421748, 0.428531, 0.446640], + [0.425120, 0.431334, 0.447692], + [0.428462, 0.434140, 0.448864], + [0.431817, 0.436950, 0.449982], + [0.435168, 0.439763, 0.451134], + [0.438504, 0.442580, 0.452341], + [0.441810, 0.445402, 0.453659], + [0.445148, 0.448226, 0.454885], + [0.448447, 0.451053, 0.456264], + [0.451759, 0.453887, 0.457582], + [0.455072, 0.456718, 0.458976], + [0.458366, 0.459552, 0.460457], + [0.461616, 0.462405, 0.461969], + [0.464947, 0.465241, 0.463395], + [0.468254, 0.468083, 0.464908], + [0.471501, 0.470960, 0.466357], + [0.474812, 0.473832, 0.467681], + [0.478186, 0.476699, 0.468845], + [0.481622, 0.479573, 0.469767], + [0.485141, 0.482451, 0.470384], + [0.488697, 0.485318, 0.471008], + [0.492278, 0.488198, 0.471453], + [0.495913, 0.491076, 0.471751], + [0.499552, 0.493960, 0.472032], + [0.503185, 0.496851, 0.472305], + [0.506866, 0.499743, 0.472432], + [0.510540, 0.502643, 0.472550], + [0.514226, 0.505546, 0.472640], + [0.517920, 0.508454, 0.472707], + [0.521643, 0.511367, 0.472639], + [0.525348, 0.514285, 0.472660], + [0.529086, 0.517207, 0.472543], + [0.532829, 0.520135, 0.472401], + [0.536553, 0.523067, 0.472352], + [0.540307, 0.526005, 0.472163], + [0.544069, 0.528948, 0.471947], + [0.547840, 0.531895, 0.471704], + [0.551612, 0.534849, 0.471439], + [0.555393, 0.537807, 0.471147], + [0.559181, 0.540771, 0.470829], + [0.562972, 0.543741, 0.470488], + [0.566802, 0.546715, 0.469988], + [0.570607, 0.549695, 0.469593], + [0.574417, 0.552682, 0.469172], + [0.578236, 0.555673, 0.468724], + [0.582087, 0.558670, 0.468118], + [0.585916, 0.561674, 0.467618], + [0.589753, 0.564682, 0.467090], + [0.593622, 0.567697, 0.466401], + [0.597469, 0.570718, 0.465821], + [0.601354, 0.573743, 0.465074], + [0.605211, 0.576777, 0.464441], + [0.609105, 0.579816, 0.463638], + [0.612977, 0.582861, 0.462950], + [0.616852, 0.585913, 0.462237], + [0.620765, 0.588970, 0.461351], + [0.624654, 0.592034, 0.460583], + [0.628576, 0.595104, 0.459641], + [0.632506, 0.598180, 0.458668], + [0.636412, 0.601264, 0.457818], + [0.640352, 0.604354, 0.456791], + [0.644270, 0.607450, 0.455886], + [0.648222, 0.610553, 0.454801], + [0.652178, 0.613664, 0.453689], + [0.656114, 0.616780, 0.452702], + [0.660082, 0.619904, 0.451534], + [0.664055, 0.623034, 0.450338], + [0.668008, 0.626171, 0.449270], + [0.671991, 0.629316, 0.448018], + [0.675981, 0.632468, 0.446736], + [0.679979, 0.635626, 0.445424], + [0.683950, 0.638793, 0.444251], + [0.687957, 0.641966, 0.442886], + [0.691971, 0.645145, 0.441491], + [0.695985, 0.648334, 0.440072], + [0.700008, 0.651529, 0.438624], + [0.704037, 0.654731, 0.437147], + [0.708067, 0.657942, 0.435647], + [0.712105, 0.661160, 0.434117], + [0.716177, 0.664384, 0.432386], + [0.720222, 0.667618, 0.430805], + [0.724274, 0.670859, 0.429194], + [0.728334, 0.674107, 0.427554], + [0.732422, 0.677364, 0.425717], + [0.736488, 0.680629, 0.424028], + [0.740589, 0.683900, 0.422131], + [0.744664, 0.687181, 0.420393], + [0.748772, 0.690470, 0.418448], + [0.752886, 0.693766, 0.416472], + [0.756975, 0.697071, 0.414659], + [0.761096, 0.700384, 0.412638], + [0.765223, 0.703705, 0.410587], + [0.769353, 0.707035, 0.408516], + [0.773486, 0.710373, 0.406422], + [0.777651, 0.713719, 0.404112], + [0.781795, 0.717074, 0.401966], + [0.785965, 0.720438, 0.399613], + [0.790116, 0.723810, 0.397423], + [0.794298, 0.727190, 0.395016], + [0.798480, 0.730580, 0.392597], + [0.802667, 0.733978, 0.390153], + [0.806859, 0.737385, 0.387684], + [0.811054, 0.740801, 0.385198], + [0.815274, 0.744226, 0.382504], + [0.819499, 0.747659, 0.379785], + [0.823729, 0.751101, 0.377043], + [0.827959, 0.754553, 0.374292], + [0.832192, 0.758014, 0.371529], + [0.836429, 0.761483, 0.368747], + [0.840693, 0.764962, 0.365746], + [0.844957, 0.768450, 0.362741], + [0.849223, 0.771947, 0.359729], + [0.853515, 0.775454, 0.356500], + [0.857809, 0.778969, 0.353259], + [0.862105, 0.782494, 0.350011], + [0.866421, 0.786028, 0.346571], + [0.870717, 0.789572, 0.343333], + [0.875057, 0.793125, 0.339685], + [0.879378, 0.796687, 0.336241], + [0.883720, 0.800258, 0.332599], + [0.888081, 0.803839, 0.328770], + [0.892440, 0.807430, 0.324968], + [0.896818, 0.811030, 0.320982], + [0.901195, 0.814639, 0.317021], + [0.905589, 0.818257, 0.312889], + [0.910000, 0.821885, 0.308594], + [0.914407, 0.825522, 0.304348], + [0.918828, 0.829168, 0.299960], + [0.923279, 0.832822, 0.295244], + [0.927724, 0.836486, 0.290611], + [0.932180, 0.840159, 0.285880], + [0.936660, 0.843841, 0.280876], + [0.941147, 0.847530, 0.275815], + [0.945654, 0.851228, 0.270532], + [0.950178, 0.854933, 0.265085], + [0.954725, 0.858646, 0.259365], + [0.959284, 0.862365, 0.253563], + [0.963872, 0.866089, 0.247445], + [0.968469, 0.869819, 0.241310], + [0.973114, 0.873550, 0.234677], + [0.977780, 0.877281, 0.227954], + [0.982497, 0.881008, 0.220878], + [0.987293, 0.884718, 0.213336], + [0.992218, 0.888385, 0.205468], + [0.994847, 0.892954, 0.203445], + [0.995249, 0.898384, 0.207561], + [0.995503, 0.903866, 0.212370], + [0.995737, 0.909344, 0.217772]] + +_twilight_data = [ + [0.88575015840754434, 0.85000924943067835, 0.8879736506427196], + [0.88378520195539056, 0.85072940540310626, 0.88723222096949894], + [0.88172231059285788, 0.85127594077653468, 0.88638056925514819], + [0.8795410528270573, 0.85165675407495722, 0.8854143767924102], + [0.87724880858965482, 0.85187028338870274, 0.88434120381311432], + [0.87485347508575972, 0.85191526123023187, 0.88316926967613829], + [0.87233134085124076, 0.85180165478080894, 0.88189704355001619], + [0.86970474853509816, 0.85152403004797894, 0.88053883390003362], + [0.86696015505333579, 0.8510896085314068, 0.87909766977173343], + [0.86408985081463996, 0.85050391167507788, 0.87757925784892632], + [0.86110245436899846, 0.84976754857001258, 0.87599242923439569], + [0.85798259245670372, 0.84888934810281835, 0.87434038553446281], + [0.85472593189256985, 0.84787488124672816, 0.8726282980930582], + [0.85133714570857189, 0.84672735796116472, 0.87086081657350445], + [0.84780710702577922, 0.8454546229209523, 0.86904036783694438], + [0.8441261828674842, 0.84406482711037389, 0.86716973322690072], + [0.84030420805957784, 0.8425605950855084, 0.865250882410458], + [0.83634031809191178, 0.84094796518951942, 0.86328528001070159], + [0.83222705712934408, 0.83923490627754482, 0.86127563500427884], + [0.82796894316013536, 0.83742600751395202, 0.85922399451306786], + [0.82357429680252847, 0.83552487764795436, 0.85713191328514948], + [0.81904654677937527, 0.8335364929949034, 0.85500206287010105], + [0.81438982121143089, 0.83146558694197847, 0.85283759062147024], + [0.8095999819094809, 0.82931896673505456, 0.85064441601050367], + [0.80469164429814577, 0.82709838780560663, 0.84842449296974021], + [0.79967075421267997, 0.82480781812080928, 0.84618210029578533], + [0.79454305089231114, 0.82245116226304615, 0.84392184786827984], + [0.78931445564608915, 0.82003213188702007, 0.8416486380471222], + [0.78399101042764918, 0.81755426400533426, 0.83936747464036732], + [0.77857892008227592, 0.81502089378742548, 0.8370834463093898], + [0.77308416590170936, 0.81243524735466011, 0.83480172950579679], + [0.76751108504417864, 0.8098007598713145, 0.83252816638059668], + [0.76186907937980286, 0.80711949387647486, 0.830266486168872], + [0.75616443584381976, 0.80439408733477935, 0.82802138994719998], + [0.75040346765406696, 0.80162699008965321, 0.82579737851082424], + [0.74459247771890169, 0.79882047719583249, 0.82359867586156521], + [0.73873771700494939, 0.79597665735031009, 0.82142922780433014], + [0.73284543645523459, 0.79309746468844067, 0.81929263384230377], + [0.72692177512829703, 0.7901846863592763, 0.81719217466726379], + [0.72097280665536778, 0.78723995923452639, 0.81513073920879264], + [0.71500403076252128, 0.78426487091581187, 0.81311116559949914], + [0.70902078134539304, 0.78126088716070907, 0.81113591855117928], + [0.7030297722540817, 0.77822904973358131, 0.80920618848056969], + [0.6970365443886174, 0.77517050008066057, 0.80732335380063447], + [0.69104641009309098, 0.77208629460678091, 0.80548841690679074], + [0.68506446154395928, 0.7689774029354699, 0.80370206267176914], + [0.67909554499882152, 0.76584472131395898, 0.8019646617300199], + [0.67314422559426212, 0.76268908733890484, 0.80027628545809526], + [0.66721479803752815, 0.7595112803730375, 0.79863674654537764], + [0.6613112930078745, 0.75631202708719025, 0.7970456043491897], + [0.65543692326454717, 0.75309208756768431, 0.79550271129031047], + [0.64959573004253479, 0.74985201221941766, 0.79400674021499107], + [0.6437910831099849, 0.7465923800833657, 0.79255653201306053], + [0.63802586828545982, 0.74331376714033193, 0.79115100459573173], + [0.6323027138710603, 0.74001672160131404, 0.78978892762640429], + [0.62662402022604591, 0.73670175403699445, 0.78846901316334561], + [0.62099193064817548, 0.73336934798923203, 0.78718994624696581], + [0.61540846411770478, 0.73001995232739691, 0.78595022706750484], + [0.60987543176093062, 0.72665398759758293, 0.78474835732694714], + [0.60439434200274855, 0.7232718614323369, 0.78358295593535587], + [0.5989665814482068, 0.71987394892246725, 0.78245259899346642], + [0.59359335696837223, 0.7164606049658685, 0.78135588237640097], + [0.58827579780555495, 0.71303214646458135, 0.78029141405636515], + [0.58301487036932409, 0.70958887676997473, 0.77925781820476592], + [0.5778116438998202, 0.70613106157153982, 0.77825345121025524], + [0.5726668948158774, 0.7026589535425779, 0.77727702680911992], + [0.56758117853861967, 0.69917279302646274, 0.77632748534275298], + [0.56255515357219343, 0.69567278381629649, 0.77540359142309845], + [0.55758940419605174, 0.69215911458254054, 0.7745041337932782], + [0.55268450589347129, 0.68863194515166382, 0.7736279426902245], + [0.54784098153018634, 0.68509142218509878, 0.77277386473440868], + [0.54305932424018233, 0.68153767253065878, 0.77194079697835083], + [0.53834015575176275, 0.67797081129095405, 0.77112734439057717], + [0.53368389147728401, 0.67439093705212727, 0.7703325054879735], + [0.529090861832473, 0.67079812302806219, 0.76955552292313134], + [0.52456151470593582, 0.66719242996142225, 0.76879541714230948], + [0.52009627392235558, 0.66357391434030388, 0.76805119403344102], + [0.5156955988596057, 0.65994260812897998, 0.76732191489596169], + [0.51135992541601927, 0.65629853981831865, 0.76660663780645333], + [0.50708969576451657, 0.65264172403146448, 0.76590445660835849], + [0.5028853540415561, 0.64897216734095264, 0.76521446718174913], + [0.49874733661356069, 0.6452898684900934, 0.76453578734180083], + [0.4946761847863938, 0.64159484119504429, 0.76386719002130909], + [0.49067224938561221, 0.63788704858847078, 0.76320812763163837], + [0.4867359599430568, 0.63416646251100506, 0.76255780085924041], + [0.4828677867260272, 0.6304330455306234, 0.76191537149895305], + [0.47906816236197386, 0.62668676251860134, 0.76128000375662419], + [0.47533752394906287, 0.62292757283835809, 0.76065085571817748], + [0.47167629518877091, 0.61915543242884641, 0.76002709227883047], + [0.46808490970531597, 0.61537028695790286, 0.75940789891092741], + [0.46456376716303932, 0.61157208822864151, 0.75879242623025811], + [0.46111326647023881, 0.607760777169989, 0.75817986436807139], + [0.45773377230160567, 0.60393630046586455, 0.75756936901859162], + [0.45442563977552913, 0.60009859503858665, 0.75696013660606487], + [0.45118918687617743, 0.59624762051353541, 0.75635120643246645], + [0.44802470933589172, 0.59238331452146575, 0.75574176474107924], + [0.44493246854215379, 0.5885055998308617, 0.7551311041857901], + [0.44191271766696399, 0.58461441100175571, 0.75451838884410671], + [0.43896563958048396, 0.58070969241098491, 0.75390276208285945], + [0.43609138958356369, 0.57679137998186081, 0.7532834105961016], + [0.43329008867358393, 0.57285941625606673, 0.75265946532566674], + [0.43056179073057571, 0.56891374572457176, 0.75203008099312696], + [0.42790652284925834, 0.5649543060909209, 0.75139443521914839], + [0.42532423665011354, 0.56098104959950301, 0.75075164989005116], + [0.42281485675772662, 0.55699392126996583, 0.75010086988227642], + [0.42037822361396326, 0.55299287158108168, 0.7494412559451894], + [0.41801414079233629, 0.54897785421888889, 0.74877193167001121], + [0.4157223260454232, 0.54494882715350401, 0.74809204459000522], + [0.41350245743314729, 0.54090574771098476, 0.74740073297543086], + [0.41135414697304568, 0.53684857765005933, 0.74669712855065784], + [0.4092768899914751, 0.53277730177130322, 0.74598030635707824], + [0.40727018694219069, 0.52869188011057411, 0.74524942637581271], + [0.40533343789303178, 0.52459228174983119, 0.74450365836708132], + [0.40346600333905397, 0.52047847653840029, 0.74374215223567086], + [0.40166714010896104, 0.51635044969688759, 0.7429640345324835], + [0.39993606933454834, 0.51220818143218516, 0.74216844571317986], + [0.3982719152586337, 0.50805166539276136, 0.74135450918099721], + [0.39667374905665609, 0.50388089053847973, 0.74052138580516735], + [0.39514058808207631, 0.49969585326377758, 0.73966820211715711], + [0.39367135736822567, 0.49549655777451179, 0.738794102296364], + [0.39226494876209317, 0.49128300332899261, 0.73789824784475078], + [0.39092017571994903, 0.48705520251223039, 0.73697977133881254], + [0.38963580160340855, 0.48281316715123496, 0.73603782546932739], + [0.38841053300842432, 0.47855691131792805, 0.73507157641157261], + [0.38724301459330251, 0.47428645933635388, 0.73408016787854391], + [0.38613184178892102, 0.4700018340988123, 0.7330627749243106], + [0.38507556793651387, 0.46570306719930193, 0.73201854033690505], + [0.38407269378943537, 0.46139018782416635, 0.73094665432902683], + [0.38312168084402748, 0.45706323581407199, 0.72984626791353258], + [0.38222094988570376, 0.45272225034283325, 0.72871656144003782], + [0.38136887930454161, 0.44836727669277859, 0.72755671317141346], + [0.38056380696565623, 0.44399837208633719, 0.72636587045135315], + [0.37980403744848751, 0.43961558821222629, 0.72514323778761092], + [0.37908789283110761, 0.43521897612544935, 0.72388798691323131], + [0.378413635091359, 0.43080859411413064, 0.72259931993061044], + [0.37777949753513729, 0.4263845142616835, 0.72127639993530235], + [0.37718371844251231, 0.42194680223454828, 0.71991841524475775], + [0.37662448930806297, 0.41749553747893614, 0.71852454736176108], + [0.37610001286385814, 0.41303079952477062, 0.71709396919920232], + [0.37560846919442398, 0.40855267638072096, 0.71562585091587549], + [0.37514802505380473, 0.4040612609993941, 0.7141193695725726], + [0.37471686019302231, 0.3995566498711684, 0.71257368516500463], + [0.37431313199312338, 0.39503894828283309, 0.71098796522377461], + [0.37393499330475782, 0.39050827529375831, 0.70936134293478448], + [0.3735806215098284, 0.38596474386057539, 0.70769297607310577], + [0.37324816143326384, 0.38140848555753937, 0.70598200974806036], + [0.37293578646665032, 0.37683963835219841, 0.70422755780589941], + [0.37264166757849604, 0.37225835004836849, 0.7024287314570723], + [0.37236397858465387, 0.36766477862108266, 0.70058463496520773], + [0.37210089702443822, 0.36305909736982378, 0.69869434615073722], + [0.3718506155898596, 0.35844148285875221, 0.69675695810256544], + [0.37161133234400479, 0.3538121372967869, 0.69477149919380887], + [0.37138124223736607, 0.34917126878479027, 0.69273703471928827], + [0.37115856636209105, 0.34451911410230168, 0.69065253586464992], + [0.37094151551337329, 0.33985591488818123, 0.68851703379505125], + [0.37072833279422668, 0.33518193808489577, 0.68632948169606767], + [0.37051738634484427, 0.33049741244307851, 0.68408888788857214], + [0.37030682071842685, 0.32580269697872455, 0.68179411684486679], + [0.37009487130772695, 0.3210981375964933, 0.67944405399056851], + [0.36987980329025361, 0.31638410101153364, 0.67703755438090574], + [0.36965987626565955, 0.31166098762951971, 0.67457344743419545], + [0.36943334591276228, 0.30692923551862339, 0.67205052849120617], + [0.36919847837592484, 0.30218932176507068, 0.66946754331614522], + [0.36895355306596778, 0.29744175492366276, 0.66682322089824264], + [0.36869682231895268, 0.29268709856150099, 0.66411625298236909], + [0.36842655638020444, 0.28792596437778462, 0.66134526910944602], + [0.36814101479899719, 0.28315901221182987, 0.65850888806972308], + [0.36783843696531082, 0.27838697181297761, 0.65560566838453704], + [0.36751707094367697, 0.27361063317090978, 0.65263411711618635], + [0.36717513650699446, 0.26883085667326956, 0.64959272297892245], + [0.36681085540107988, 0.26404857724525643, 0.64647991652908243], + [0.36642243251550632, 0.25926481158628106, 0.64329409140765537], + [0.36600853966739794, 0.25448043878086224, 0.64003361803368586], + [0.36556698373538982, 0.24969683475296395, 0.63669675187488584], + [0.36509579845886808, 0.24491536803550484, 0.63328173520055586], + [0.36459308890125008, 0.24013747024823828, 0.62978680155026101], + [0.36405693022088509, 0.23536470386204195, 0.62621013451953023], + [0.36348537610385145, 0.23059876218396419, 0.62254988622392882], + [0.36287643560041027, 0.22584149293287031, 0.61880417410823019], + [0.36222809558295926, 0.22109488427338303, 0.61497112346096128], + [0.36153829010998356, 0.21636111429594002, 0.61104880679640927], + [0.36080493826624654, 0.21164251793458128, 0.60703532172064711], + [0.36002681809096376, 0.20694122817889948, 0.60292845431916875], + [0.35920088560930186, 0.20226037920758122, 0.5987265295935138], + [0.35832489966617809, 0.197602942459778, 0.59442768517501066], + [0.35739663292915563, 0.19297208197842461, 0.59003011251063131], + [0.35641381143126327, 0.18837119869242164, 0.5855320765920552], + [0.35537415306906722, 0.18380392577704466, 0.58093191431832802], + [0.35427534960663759, 0.17927413271618647, 0.57622809660668717], + [0.35311574421123737, 0.17478570377561287, 0.57141871523555288], + [0.35189248608873791, 0.17034320478524959, 0.56650284911216653], + [0.35060304441931012, 0.16595129984720861, 0.56147964703993225], + [0.34924513554955644, 0.16161477763045118, 0.55634837474163779], + [0.34781653238777782, 0.15733863511152979, 0.55110853452703257], + [0.34631507175793091, 0.15312802296627787, 0.5457599924248665], + [0.34473901574536375, 0.14898820589826409, 0.54030245920406539], + [0.34308600291572294, 0.14492465359918028, 0.53473704282067103], + [0.34135411074506483, 0.1409427920655632, 0.52906500940336754], + [0.33954168752669694, 0.13704801896718169, 0.52328797535085236], + [0.33764732090671112, 0.13324562282438077, 0.51740807573979475], + [0.33566978565015315, 0.12954074251271822, 0.51142807215168951], + [0.33360804901486002, 0.12593818301005921, 0.50535164796654897], + [0.33146154891145124, 0.12244245263391232, 0.49918274588431072], + [0.32923005203231409, 0.11905764321981127, 0.49292595612342666], + [0.3269137124539796, 0.1157873496841953, 0.48658646495697461], + [0.32451307931207785, 0.11263459791730848, 0.48017007211645196], + [0.32202882276069322, 0.10960114111258401, 0.47368494725726878], + [0.31946262395497965, 0.10668879882392659, 0.46713728801395243], + [0.31681648089023501, 0.10389861387653518, 0.46053414662739794], + [0.31409278414755532, 0.10123077676403242, 0.45388335612058467], + [0.31129434479712365, 0.098684771934052201, 0.44719313715161618], + [0.30842444457210105, 0.096259385340577736, 0.44047194882050544], + [0.30548675819945936, 0.093952764840823738, 0.43372849999361113], + [0.30248536364574252, 0.091761187397303601, 0.42697404043749887], + [0.29942483960214772, 0.089682253716750038, 0.42021619665853854], + [0.29631000388905288, 0.087713250960463951, 0.41346259134143476], + [0.29314593096985248, 0.085850656889620708, 0.40672178082365834], + [0.28993792445176608, 0.08409078829085731, 0.40000214725256295], + [0.28669151388283165, 0.082429873848480689, 0.39331182532243375], + [0.28341239797185225, 0.080864153365499375, 0.38665868550105914], + [0.28010638576975472, 0.079389994802261526, 0.38005028528138707], + [0.27677939615815589, 0.078003941033788216, 0.37349382846504675], + [0.27343739342450812, 0.076702800237496066, 0.36699616136347685], + [0.27008637749114051, 0.075483675584275545, 0.36056376228111864], + [0.26673233211995284, 0.074344018028546205, 0.35420276066240958], + [0.26338121807151404, 0.073281657939897077, 0.34791888996380105], + [0.26003895187439957, 0.072294781043362205, 0.3417175669546984], + [0.25671191651083902, 0.071380106242082242, 0.33560648984600089], + [0.25340685873736807, 0.070533582926851829, 0.3295945757321303], + [0.25012845306199383, 0.069758206429106989, 0.32368100685760637], + [0.24688226237958999, 0.069053639449204451, 0.31786993834254956], + [0.24367372557466271, 0.068419855150922693, 0.31216524050888372], + [0.24050813332295939, 0.067857103814855602, 0.30657054493678321], + [0.23739062429054825, 0.067365888050555517, 0.30108922184065873], + [0.23433055727563878, 0.066935599661639394, 0.29574009929867601], + [0.23132955273021344, 0.066576186939090592, 0.29051361067988485], + [0.2283917709422868, 0.06628997924139618, 0.28541074411068496], + [0.22552164337737857, 0.066078173119395595, 0.28043398847505197], + [0.22272706739121817, 0.065933790675651943, 0.27559714652053702], + [0.22001251100779617, 0.065857918918907604, 0.27090279994325861], + [0.21737845072382705, 0.065859661233562045, 0.26634209349669508], + [0.21482843531473683, 0.065940385613778491, 0.26191675992376573], + [0.21237411048541005, 0.066085024661758446, 0.25765165093569542], + [0.21001214221188125, 0.066308573918947178, 0.2535289048041211], + [0.2077442377448806, 0.06661453200418091, 0.24954644291943817], + [0.20558051999470117, 0.066990462397868739, 0.24572497420147632], + [0.20352007949514977, 0.067444179612424215, 0.24205576625191821], + [0.20156133764129841, 0.067983271026200248, 0.23852974228695395], + [0.19971571438603364, 0.068592710553704722, 0.23517094067076993], + [0.19794834061899208, 0.069314066071660657, 0.23194647381302336], + [0.1960826032659409, 0.070321227242423623, 0.22874673279569585], + [0.19410351363791453, 0.071608304856891569, 0.22558727307410353], + [0.19199449184606268, 0.073182830649273306, 0.22243385243433622], + [0.18975853639094634, 0.075019861862143766, 0.2193005075652994], + [0.18739228342697645, 0.077102096899588329, 0.21618875376309582], + [0.18488035509396164, 0.079425730279723883, 0.21307651648984993], + [0.18774482037046955, 0.077251588468039312, 0.21387448578597812], + [0.19049578401722037, 0.075311278416787641, 0.2146562337112265], + [0.1931548636579131, 0.073606819040117955, 0.21542362939081539], + [0.19571853588267552, 0.072157781039602742, 0.21617499187076789], + [0.19819343656336558, 0.070974625252738788, 0.21690975060032436], + [0.20058760685133747, 0.070064576149984209, 0.21762721310371608], + [0.20290365333558247, 0.069435248580458964, 0.21833167885096033], + [0.20531725273301316, 0.068919592266397572, 0.21911516689288835], + [0.20785704662965598, 0.068484398797025281, 0.22000133917653536], + [0.21052882914958676, 0.06812195249816172, 0.22098759107715404], + [0.2133313859647627, 0.067830148426026665, 0.22207043213024291], + [0.21625279838647882, 0.067616330270516389, 0.22324568672294431], + [0.21930503925136402, 0.067465786362940039, 0.22451023616807558], + [0.22247308588973624, 0.067388214053092838, 0.22585960379408354], + [0.2257539681670791, 0.067382132300147474, 0.22728984778098055], + [0.22915620278592841, 0.067434730871152565, 0.22879681433956656], + [0.23266299920501882, 0.067557104388479783, 0.23037617493752832], + [0.23627495835774248, 0.06774359820987802, 0.23202360805926608], + [0.23999586188690308, 0.067985029964779953, 0.23373434258507808], + [0.24381149720247919, 0.068289851529011875, 0.23550427698321885], + [0.24772092990501099, 0.068653337909486523, 0.2373288009471749], + [0.25172899728289466, 0.069064630826035506, 0.23920260612763083], + [0.25582135547481771, 0.06953231029187984, 0.24112190491594204], + [0.25999463887892144, 0.070053855603861875, 0.24308218808684579], + [0.26425512207060942, 0.070616595622995437, 0.24507758869355967], + [0.26859095948172862, 0.071226716277922458, 0.24710443563450618], + [0.27299701518897301, 0.071883555446163511, 0.24915847093232929], + [0.27747150809142801, 0.072582969899254779, 0.25123493995942769], + [0.28201746297366942, 0.073315693214040967, 0.25332800295084507], + [0.28662309235899847, 0.074088460826808866, 0.25543478673717029], + [0.29128515387578635, 0.074899049847466703, 0.25755101595750435], + [0.2960004726065818, 0.075745336000958424, 0.25967245030364566], + [0.30077276812918691, 0.076617824336164764, 0.26179294097819672], + [0.30559226007249934, 0.077521963107537312, 0.26391006692119662], + [0.31045520848595526, 0.078456871676182177, 0.2660200572779356], + [0.31535870009205808, 0.079420997315243186, 0.26811904076941961], + [0.32029986557994061, 0.080412994737554838, 0.27020322893039511], + [0.32527888860401261, 0.081428390076546092, 0.27226772884656186], + [0.33029174471181438, 0.08246763389003825, 0.27430929404579435], + [0.33533353224455448, 0.083532434119003962, 0.27632534356790039], + [0.34040164359597463, 0.084622236191702671, 0.27831254595259397], + [0.34549355713871799, 0.085736654965126335, 0.28026769921081435], + [0.35060678246032478, 0.08687555176033529, 0.28218770540182386], + [0.35573889947341125, 0.088038974350243354, 0.2840695897279818], + [0.36088752387578377, 0.089227194362745205, 0.28591050458531014], + [0.36605031412464006, 0.090440685427697898, 0.2877077458811747], + [0.37122508431309342, 0.091679997480262732, 0.28945865397633169], + [0.3764103053221462, 0.092945198093777909, 0.29116024157313919], + [0.38160247377467543, 0.094238731263712183, 0.29281107506269488], + [0.38679939079544168, 0.09556181960083443, 0.29440901248173756], + [0.39199887556812907, 0.09691583650296684, 0.29595212005509081], + [0.39719876876325577, 0.098302320968278623, 0.29743856476285779], + [0.40239692379737496, 0.099722930314950553, 0.29886674369733968], + [0.40759120392688708, 0.10117945586419633, 0.30023519507728602], + [0.41277985630360303, 0.1026734006932461, 0.30154226437468967], + [0.41796105205173684, 0.10420644885760968, 0.30278652039631843], + [0.42313214269556043, 0.10578120994917611, 0.3039675809469457], + [0.42829101315789753, 0.1073997763055258, 0.30508479060294547], + [0.4334355841041439, 0.1090642347484701, 0.30613767928289148], + [0.43856378187931538, 0.11077667828375456, 0.30712600062348083], + [0.44367358645071275, 0.11253912421257944, 0.30804973095465449], + [0.44876299173174822, 0.11435355574622549, 0.30890905921943196], + [0.45383005086999889, 0.11622183788331528, 0.30970441249844921], + [0.45887288947308297, 0.11814571137706886, 0.31043636979038808], + [0.46389102840284874, 0.12012561256850712, 0.31110343446582983], + [0.46888111384598413, 0.12216445576414045, 0.31170911458932665], + [0.473841437035254, 0.12426354237989065, 0.31225470169927194], + [0.47877034239726296, 0.12642401401409453, 0.31274172735821959], + [0.48366628618847957, 0.12864679022013889, 0.31317188565991266], + [0.48852847371852987, 0.13093210934893723, 0.31354553695453014], + [0.49335504375145617, 0.13328091630401023, 0.31386561956734976], + [0.49814435462074153, 0.13569380302451714, 0.314135190862664], + [0.50289524974970612, 0.13817086581280427, 0.31435662153833671], + [0.50760681181053691, 0.14071192654913128, 0.31453200120082569], + [0.51227835105321762, 0.14331656120063752, 0.3146630922831542], + [0.51690848800544464, 0.14598463068714407, 0.31475407592280041], + [0.52149652863229956, 0.14871544765633712, 0.31480767954534428], + [0.52604189625477482, 0.15150818660835483, 0.31482653406646727], + [0.53054420489856446, 0.15436183633886777, 0.31481299789187128], + [0.5350027976174474, 0.15727540775107324, 0.31477085207396532], + [0.53941736649199057, 0.16024769309971934, 0.31470295028655965], + [0.54378771313608565, 0.16327738551419116, 0.31461204226295625], + [0.54811370033467621, 0.1663630904279047, 0.31450102990914708], + [0.55239521572711914, 0.16950338809328983, 0.31437291554615371], + [0.55663229034969341, 0.17269677158182117, 0.31423043195101424], + [0.56082499039117173, 0.17594170887918095, 0.31407639883970623], + [0.56497343529017696, 0.17923664950367169, 0.3139136046337036], + [0.56907784784011428, 0.18258004462335425, 0.31374440956796529], + [0.57313845754107873, 0.18597036007065024, 0.31357126868520002], + [0.57715550812992045, 0.18940601489760422, 0.31339704333572083], + [0.58112932761586555, 0.19288548904692518, 0.31322399394183942], + [0.58506024396466882, 0.19640737049066315, 0.31305401163732732], + [0.58894861935544707, 0.19997020971775276, 0.31288922211590126], + [0.59279480536520257, 0.20357251410079796, 0.31273234839304942], + [0.59659918109122367, 0.207212956082026, 0.31258523031121233], + [0.60036213010411577, 0.21089030138947745, 0.31244934410414688], + [0.60408401696732739, 0.21460331490206347, 0.31232652641170694], + [0.60776523994818654, 0.21835070166659282, 0.31221903291870201], + [0.6114062072731884, 0.22213124697023234, 0.31212881396435238], + [0.61500723236391375, 0.22594402043981826, 0.31205680685765741], + [0.61856865258877192, 0.22978799249179921, 0.31200463838728931], + [0.62209079821082613, 0.2336621873300741, 0.31197383273627388], + [0.62557416500434959, 0.23756535071152696, 0.31196698314912269], + [0.62901892016985872, 0.24149689191922535, 0.31198447195645718], + [0.63242534854210275, 0.24545598775548677, 0.31202765974624452], + [0.6357937104834237, 0.24944185818822678, 0.31209793953300591], + [0.6391243387840212, 0.25345365461983138, 0.31219689612063978], + [0.642417577481186, 0.257490519876798, 0.31232631707560987], + [0.64567349382645434, 0.26155203161615281, 0.31248673753935263], + [0.64889230169458245, 0.26563755336209077, 0.31267941819570189], + [0.65207417290277303, 0.26974650525236699, 0.31290560605819168], + [0.65521932609327127, 0.27387826652410152, 0.3131666792687211], + [0.6583280801134499, 0.27803210957665631, 0.3134643447952643], + [0.66140037532601781, 0.28220778870555907, 0.31379912926498488], + [0.66443632469878844, 0.28640483614256179, 0.31417223403606975], + [0.66743603766369131, 0.29062280081258873, 0.31458483752056837], + [0.67039959547676198, 0.29486126309253047, 0.31503813956872212], + [0.67332725564817331, 0.29911962764489264, 0.31553372323982209], + [0.67621897924409746, 0.30339762792450425, 0.3160724937230589], + [0.67907474028157344, 0.30769497879760166, 0.31665545668946665], + [0.68189457150944521, 0.31201133280550686, 0.31728380489244951], + [0.68467850942494535, 0.31634634821222207, 0.31795870784057567], + [0.68742656435169625, 0.32069970535138104, 0.31868137622277692], + [0.6901389321505248, 0.32507091815606004, 0.31945332332898302], + [0.69281544846764931, 0.32945984647042675, 0.3202754315314667], + [0.69545608346891119, 0.33386622163232865, 0.32114884306985791], + [0.6980608153581771, 0.33828976326048621, 0.32207478855218091], + [0.70062962477242097, 0.34273019305341756, 0.32305449047765694], + [0.70316249458814151, 0.34718723719597999, 0.32408913679491225], + [0.70565951122610093, 0.35166052978120937, 0.32518014084085567], + [0.70812059568420482, 0.35614985523380299, 0.32632861885644465], + [0.7105456546582587, 0.36065500290840113, 0.32753574162788762], + [0.71293466839773467, 0.36517570519856757, 0.3288027427038317], + [0.71528760614847287, 0.36971170225223449, 0.3301308728723546], + [0.71760444908133847, 0.37426272710686193, 0.33152138620958932], + [0.71988521490549851, 0.37882848839337313, 0.33297555200245399], + [0.7221299918421461, 0.38340864508963057, 0.33449469983585844], + [0.72433865647781592, 0.38800301593162145, 0.33607995965691828], + [0.72651122900227549, 0.3926113126792577, 0.3377325942005665], + [0.72864773856716547, 0.39723324476747235, 0.33945384341064017], + [0.73074820754845171, 0.401868526884681, 0.3412449533046818], + [0.73281270506268747, 0.4065168468778026, 0.34310715173410822], + [0.73484133598564938, 0.41117787004519513, 0.34504169470809071], + [0.73683422173585866, 0.41585125850290111, 0.34704978520758401], + [0.73879140024599266, 0.42053672992315327, 0.34913260148542435], + [0.74071301619506091, 0.4252339389526239, 0.35129130890802607], + [0.7425992159973317, 0.42994254036133867, 0.35352709245374592], + [0.74445018676570673, 0.43466217184617112, 0.35584108091122535], + [0.74626615789163442, 0.43939245044973502, 0.35823439142300639], + [0.74804739275559562, 0.44413297780351974, 0.36070813602540136], + [0.74979420547170472, 0.44888333481548809, 0.36326337558360278], + [0.75150685045891663, 0.45364314496866825, 0.36590112443835765], + [0.75318566369046569, 0.45841199172949604, 0.36862236642234769], + [0.75483105066959544, 0.46318942799460555, 0.3714280448394211], + [0.75644341577140706, 0.46797501437948458, 0.37431909037543515], + [0.75802325538455839, 0.4727682731566229, 0.37729635531096678], + [0.75957111105340058, 0.47756871222057079, 0.380360657784311], + [0.7610876378057071, 0.48237579130289127, 0.38351275723852291], + [0.76257333554052609, 0.48718906673415824, 0.38675335037837993], + [0.76402885609288662, 0.49200802533379656, 0.39008308392311997], + [0.76545492593330511, 0.49683212909727231, 0.39350254000115381], + [0.76685228950643891, 0.5016608471009063, 0.39701221751773474], + [0.76822176599735303, 0.50649362371287909, 0.40061257089416885], + [0.7695642334401418, 0.5113298901696085, 0.40430398069682483], + [0.77088091962302474, 0.51616892643469103, 0.40808667584648967], + [0.77217257229605551, 0.5210102658711383, 0.41196089987122869], + [0.77344021829889886, 0.52585332093451564, 0.41592679539764366], + [0.77468494746063199, 0.53069749384776732, 0.41998440356963762], + [0.77590790730685699, 0.53554217882461186, 0.42413367909988375], + [0.7771103295521099, 0.54038674910561235, 0.42837450371258479], + [0.77829345807633121, 0.54523059488426595, 0.432706647838971], + [0.77945862731506643, 0.55007308413977274, 0.43712979856444761], + [0.78060774749483774, 0.55491335744890613, 0.44164332426364639], + [0.78174180478981836, 0.55975098052594863, 0.44624687186865436], + [0.78286225264440912, 0.56458533111166875, 0.45093985823706345], + [0.78397060836414478, 0.56941578326710418, 0.45572154742892063], + [0.78506845019606841, 0.5742417003617839, 0.46059116206904965], + [0.78615737132332963, 0.5790624629815756, 0.46554778281918402], + [0.78723904108188347, 0.58387743744557208, 0.47059039582133383], + [0.78831514045623963, 0.58868600173562435, 0.47571791879076081], + [0.78938737766251943, 0.5934875421745599, 0.48092913815357724], + [0.79045776847727878, 0.59828134277062461, 0.48622257801969754], + [0.79152832843475607, 0.60306670593147205, 0.49159667021646397], + [0.79260034304237448, 0.60784322087037024, 0.49705020621532009], + [0.79367559698664958, 0.61261029334072192, 0.50258161291269432], + [0.79475585972654039, 0.61736734400220705, 0.50818921213102985], + [0.79584292379583765, 0.62211378808451145, 0.51387124091909786], + [0.79693854719951607, 0.62684905679296699, 0.5196258425240281], + [0.79804447815136637, 0.63157258225089552, 0.52545108144834785], + [0.7991624518501963, 0.63628379372029187, 0.53134495942561433], + [0.80029415389753977, 0.64098213306749863, 0.53730535185141037], + [0.80144124292560048, 0.64566703459218766, 0.5433300863249918], + [0.80260531146112946, 0.65033793748103852, 0.54941691584603647], + [0.80378792531077625, 0.65499426549472628, 0.55556350867083815], + [0.80499054790810298, 0.65963545027564163, 0.56176745110546977], + [0.80621460526927058, 0.66426089585282289, 0.56802629178649788], + [0.8074614045096935, 0.6688700095398864, 0.57433746373459582], + [0.80873219170089694, 0.67346216702194517, 0.58069834805576737], + [0.81002809466520687, 0.67803672673971815, 0.58710626908082753], + [0.81135014011763329, 0.68259301546243389, 0.59355848909050757], + [0.81269922039881493, 0.68713033714618876, 0.60005214820435104], + [0.81407611046993344, 0.69164794791482131, 0.6065843782630862], + [0.81548146627279483, 0.69614505508308089, 0.61315221209322646], + [0.81691575775055891, 0.70062083014783982, 0.61975260637257923], + [0.81837931164498223, 0.70507438189635097, 0.62638245478933297], + [0.81987230650455289, 0.70950474978787481, 0.63303857040067113], + [0.8213947205565636, 0.7139109141951604, 0.63971766697672761], + [0.82294635110428427, 0.71829177331290062, 0.6464164243818421], + [0.8245268129450285, 0.72264614312088882, 0.65313137915422603], + [0.82613549710580259, 0.72697275518238258, 0.65985900156216504], + [0.8277716072353446, 0.73127023324078089, 0.66659570204682972], + [0.82943407816481474, 0.7355371221572935, 0.67333772009301907], + [0.83112163529096306, 0.73977184647638616, 0.68008125203631464], + [0.83283277185777982, 0.74397271817459876, 0.68682235874648545], + [0.8345656905566583, 0.7481379479992134, 0.69355697649863846], + [0.83631898844737929, 0.75226548952875261, 0.70027999028864962], + [0.83809123476131964, 0.75635314860808633, 0.70698561390212977], + [0.83987839884120874, 0.76039907199779677, 0.71367147811129228], + [0.84167750766845151, 0.76440101200982946, 0.72033299387284622], + [0.84348529222933699, 0.76835660399870176, 0.72696536998972039], + [0.84529810731955113, 0.77226338601044719, 0.73356368240541492], + [0.84711195507965098, 0.77611880236047159, 0.74012275762807056], + [0.84892245563117641, 0.77992021407650147, 0.74663719293664366], + [0.85072697023178789, 0.78366457342383888, 0.7530974636118285], + [0.85251907207708444, 0.78734936133548439, 0.7594994148789691], + [0.85429219611470464, 0.79097196777091994, 0.76583801477914104], + [0.85604022314725403, 0.79452963601550608, 0.77210610037674143], + [0.85775662943504905, 0.79801963142713928, 0.77829571667247499], + [0.8594346370300241, 0.8014392309950078, 0.78439788751383921], + [0.86107117027565516, 0.80478517909812231, 0.79039529663736285], + [0.86265601051127572, 0.80805523804261525, 0.796282666437655], + [0.86418343723941027, 0.81124644224653542, 0.80204612696863953], + [0.86564934325605325, 0.81435544067514909, 0.80766972324164554], + [0.86705314907048503, 0.81737804041911244, 0.81313419626911398], + [0.86839954695818633, 0.82030875512181523, 0.81841638963128993], + [0.86969131502613806, 0.82314158859569164, 0.82350476683173168], + [0.87093846717297507, 0.82586857889438514, 0.82838497261149613], + [0.87215331978454325, 0.82848052823709672, 0.8330486712880828], + [0.87335171360916275, 0.83096715251272624, 0.83748851001197089], + [0.87453793320260187, 0.83331972948645461, 0.84171925358069011], + [0.87571458709961403, 0.8355302318472394, 0.84575537519027078], + [0.87687848451614692, 0.83759238071186537, 0.84961373549150254], + [0.87802298436649007, 0.83950165618540074, 0.85330645352458923], + [0.87913244240792765, 0.84125554884475906, 0.85685572291039636], + [0.88019293315695812, 0.84285224824778615, 0.86027399927156634], + [0.88119169871341951, 0.84429066717717349, 0.86356595168669881], + [0.88211542489401606, 0.84557007254559347, 0.86673765046233331], + [0.88295168595448525, 0.84668970275699273, 0.86979617048190971], + [0.88369127145898041, 0.84764891761519268, 0.87274147101441557], + [0.88432713054113543, 0.84844741572055415, 0.87556785228242973], + [0.88485138159908572, 0.84908426422893801, 0.87828235285372469], + [0.88525897972630474, 0.84955892810989209, 0.88088414794024839], + [0.88554714811952384, 0.84987174283631584, 0.88336206121170946], + [0.88571155122845646, 0.85002186115856315, 0.88572538990087124]] + +_twilight_shifted_data = (_twilight_data[len(_twilight_data)//2:] + + _twilight_data[:len(_twilight_data)//2]) +_twilight_shifted_data.reverse() +_turbo_data = [[0.18995, 0.07176, 0.23217], + [0.19483, 0.08339, 0.26149], + [0.19956, 0.09498, 0.29024], + [0.20415, 0.10652, 0.31844], + [0.20860, 0.11802, 0.34607], + [0.21291, 0.12947, 0.37314], + [0.21708, 0.14087, 0.39964], + [0.22111, 0.15223, 0.42558], + [0.22500, 0.16354, 0.45096], + [0.22875, 0.17481, 0.47578], + [0.23236, 0.18603, 0.50004], + [0.23582, 0.19720, 0.52373], + [0.23915, 0.20833, 0.54686], + [0.24234, 0.21941, 0.56942], + [0.24539, 0.23044, 0.59142], + [0.24830, 0.24143, 0.61286], + [0.25107, 0.25237, 0.63374], + [0.25369, 0.26327, 0.65406], + [0.25618, 0.27412, 0.67381], + [0.25853, 0.28492, 0.69300], + [0.26074, 0.29568, 0.71162], + [0.26280, 0.30639, 0.72968], + [0.26473, 0.31706, 0.74718], + [0.26652, 0.32768, 0.76412], + [0.26816, 0.33825, 0.78050], + [0.26967, 0.34878, 0.79631], + [0.27103, 0.35926, 0.81156], + [0.27226, 0.36970, 0.82624], + [0.27334, 0.38008, 0.84037], + [0.27429, 0.39043, 0.85393], + [0.27509, 0.40072, 0.86692], + [0.27576, 0.41097, 0.87936], + [0.27628, 0.42118, 0.89123], + [0.27667, 0.43134, 0.90254], + [0.27691, 0.44145, 0.91328], + [0.27701, 0.45152, 0.92347], + [0.27698, 0.46153, 0.93309], + [0.27680, 0.47151, 0.94214], + [0.27648, 0.48144, 0.95064], + [0.27603, 0.49132, 0.95857], + [0.27543, 0.50115, 0.96594], + [0.27469, 0.51094, 0.97275], + [0.27381, 0.52069, 0.97899], + [0.27273, 0.53040, 0.98461], + [0.27106, 0.54015, 0.98930], + [0.26878, 0.54995, 0.99303], + [0.26592, 0.55979, 0.99583], + [0.26252, 0.56967, 0.99773], + [0.25862, 0.57958, 0.99876], + [0.25425, 0.58950, 0.99896], + [0.24946, 0.59943, 0.99835], + [0.24427, 0.60937, 0.99697], + [0.23874, 0.61931, 0.99485], + [0.23288, 0.62923, 0.99202], + [0.22676, 0.63913, 0.98851], + [0.22039, 0.64901, 0.98436], + [0.21382, 0.65886, 0.97959], + [0.20708, 0.66866, 0.97423], + [0.20021, 0.67842, 0.96833], + [0.19326, 0.68812, 0.96190], + [0.18625, 0.69775, 0.95498], + [0.17923, 0.70732, 0.94761], + [0.17223, 0.71680, 0.93981], + [0.16529, 0.72620, 0.93161], + [0.15844, 0.73551, 0.92305], + [0.15173, 0.74472, 0.91416], + [0.14519, 0.75381, 0.90496], + [0.13886, 0.76279, 0.89550], + [0.13278, 0.77165, 0.88580], + [0.12698, 0.78037, 0.87590], + [0.12151, 0.78896, 0.86581], + [0.11639, 0.79740, 0.85559], + [0.11167, 0.80569, 0.84525], + [0.10738, 0.81381, 0.83484], + [0.10357, 0.82177, 0.82437], + [0.10026, 0.82955, 0.81389], + [0.09750, 0.83714, 0.80342], + [0.09532, 0.84455, 0.79299], + [0.09377, 0.85175, 0.78264], + [0.09287, 0.85875, 0.77240], + [0.09267, 0.86554, 0.76230], + [0.09320, 0.87211, 0.75237], + [0.09451, 0.87844, 0.74265], + [0.09662, 0.88454, 0.73316], + [0.09958, 0.89040, 0.72393], + [0.10342, 0.89600, 0.71500], + [0.10815, 0.90142, 0.70599], + [0.11374, 0.90673, 0.69651], + [0.12014, 0.91193, 0.68660], + [0.12733, 0.91701, 0.67627], + [0.13526, 0.92197, 0.66556], + [0.14391, 0.92680, 0.65448], + [0.15323, 0.93151, 0.64308], + [0.16319, 0.93609, 0.63137], + [0.17377, 0.94053, 0.61938], + [0.18491, 0.94484, 0.60713], + [0.19659, 0.94901, 0.59466], + [0.20877, 0.95304, 0.58199], + [0.22142, 0.95692, 0.56914], + [0.23449, 0.96065, 0.55614], + [0.24797, 0.96423, 0.54303], + [0.26180, 0.96765, 0.52981], + [0.27597, 0.97092, 0.51653], + [0.29042, 0.97403, 0.50321], + [0.30513, 0.97697, 0.48987], + [0.32006, 0.97974, 0.47654], + [0.33517, 0.98234, 0.46325], + [0.35043, 0.98477, 0.45002], + [0.36581, 0.98702, 0.43688], + [0.38127, 0.98909, 0.42386], + [0.39678, 0.99098, 0.41098], + [0.41229, 0.99268, 0.39826], + [0.42778, 0.99419, 0.38575], + [0.44321, 0.99551, 0.37345], + [0.45854, 0.99663, 0.36140], + [0.47375, 0.99755, 0.34963], + [0.48879, 0.99828, 0.33816], + [0.50362, 0.99879, 0.32701], + [0.51822, 0.99910, 0.31622], + [0.53255, 0.99919, 0.30581], + [0.54658, 0.99907, 0.29581], + [0.56026, 0.99873, 0.28623], + [0.57357, 0.99817, 0.27712], + [0.58646, 0.99739, 0.26849], + [0.59891, 0.99638, 0.26038], + [0.61088, 0.99514, 0.25280], + [0.62233, 0.99366, 0.24579], + [0.63323, 0.99195, 0.23937], + [0.64362, 0.98999, 0.23356], + [0.65394, 0.98775, 0.22835], + [0.66428, 0.98524, 0.22370], + [0.67462, 0.98246, 0.21960], + [0.68494, 0.97941, 0.21602], + [0.69525, 0.97610, 0.21294], + [0.70553, 0.97255, 0.21032], + [0.71577, 0.96875, 0.20815], + [0.72596, 0.96470, 0.20640], + [0.73610, 0.96043, 0.20504], + [0.74617, 0.95593, 0.20406], + [0.75617, 0.95121, 0.20343], + [0.76608, 0.94627, 0.20311], + [0.77591, 0.94113, 0.20310], + [0.78563, 0.93579, 0.20336], + [0.79524, 0.93025, 0.20386], + [0.80473, 0.92452, 0.20459], + [0.81410, 0.91861, 0.20552], + [0.82333, 0.91253, 0.20663], + [0.83241, 0.90627, 0.20788], + [0.84133, 0.89986, 0.20926], + [0.85010, 0.89328, 0.21074], + [0.85868, 0.88655, 0.21230], + [0.86709, 0.87968, 0.21391], + [0.87530, 0.87267, 0.21555], + [0.88331, 0.86553, 0.21719], + [0.89112, 0.85826, 0.21880], + [0.89870, 0.85087, 0.22038], + [0.90605, 0.84337, 0.22188], + [0.91317, 0.83576, 0.22328], + [0.92004, 0.82806, 0.22456], + [0.92666, 0.82025, 0.22570], + [0.93301, 0.81236, 0.22667], + [0.93909, 0.80439, 0.22744], + [0.94489, 0.79634, 0.22800], + [0.95039, 0.78823, 0.22831], + [0.95560, 0.78005, 0.22836], + [0.96049, 0.77181, 0.22811], + [0.96507, 0.76352, 0.22754], + [0.96931, 0.75519, 0.22663], + [0.97323, 0.74682, 0.22536], + [0.97679, 0.73842, 0.22369], + [0.98000, 0.73000, 0.22161], + [0.98289, 0.72140, 0.21918], + [0.98549, 0.71250, 0.21650], + [0.98781, 0.70330, 0.21358], + [0.98986, 0.69382, 0.21043], + [0.99163, 0.68408, 0.20706], + [0.99314, 0.67408, 0.20348], + [0.99438, 0.66386, 0.19971], + [0.99535, 0.65341, 0.19577], + [0.99607, 0.64277, 0.19165], + [0.99654, 0.63193, 0.18738], + [0.99675, 0.62093, 0.18297], + [0.99672, 0.60977, 0.17842], + [0.99644, 0.59846, 0.17376], + [0.99593, 0.58703, 0.16899], + [0.99517, 0.57549, 0.16412], + [0.99419, 0.56386, 0.15918], + [0.99297, 0.55214, 0.15417], + [0.99153, 0.54036, 0.14910], + [0.98987, 0.52854, 0.14398], + [0.98799, 0.51667, 0.13883], + [0.98590, 0.50479, 0.13367], + [0.98360, 0.49291, 0.12849], + [0.98108, 0.48104, 0.12332], + [0.97837, 0.46920, 0.11817], + [0.97545, 0.45740, 0.11305], + [0.97234, 0.44565, 0.10797], + [0.96904, 0.43399, 0.10294], + [0.96555, 0.42241, 0.09798], + [0.96187, 0.41093, 0.09310], + [0.95801, 0.39958, 0.08831], + [0.95398, 0.38836, 0.08362], + [0.94977, 0.37729, 0.07905], + [0.94538, 0.36638, 0.07461], + [0.94084, 0.35566, 0.07031], + [0.93612, 0.34513, 0.06616], + [0.93125, 0.33482, 0.06218], + [0.92623, 0.32473, 0.05837], + [0.92105, 0.31489, 0.05475], + [0.91572, 0.30530, 0.05134], + [0.91024, 0.29599, 0.04814], + [0.90463, 0.28696, 0.04516], + [0.89888, 0.27824, 0.04243], + [0.89298, 0.26981, 0.03993], + [0.88691, 0.26152, 0.03753], + [0.88066, 0.25334, 0.03521], + [0.87422, 0.24526, 0.03297], + [0.86760, 0.23730, 0.03082], + [0.86079, 0.22945, 0.02875], + [0.85380, 0.22170, 0.02677], + [0.84662, 0.21407, 0.02487], + [0.83926, 0.20654, 0.02305], + [0.83172, 0.19912, 0.02131], + [0.82399, 0.19182, 0.01966], + [0.81608, 0.18462, 0.01809], + [0.80799, 0.17753, 0.01660], + [0.79971, 0.17055, 0.01520], + [0.79125, 0.16368, 0.01387], + [0.78260, 0.15693, 0.01264], + [0.77377, 0.15028, 0.01148], + [0.76476, 0.14374, 0.01041], + [0.75556, 0.13731, 0.00942], + [0.74617, 0.13098, 0.00851], + [0.73661, 0.12477, 0.00769], + [0.72686, 0.11867, 0.00695], + [0.71692, 0.11268, 0.00629], + [0.70680, 0.10680, 0.00571], + [0.69650, 0.10102, 0.00522], + [0.68602, 0.09536, 0.00481], + [0.67535, 0.08980, 0.00449], + [0.66449, 0.08436, 0.00424], + [0.65345, 0.07902, 0.00408], + [0.64223, 0.07380, 0.00401], + [0.63082, 0.06868, 0.00401], + [0.61923, 0.06367, 0.00410], + [0.60746, 0.05878, 0.00427], + [0.59550, 0.05399, 0.00453], + [0.58336, 0.04931, 0.00486], + [0.57103, 0.04474, 0.00529], + [0.55852, 0.04028, 0.00579], + [0.54583, 0.03593, 0.00638], + [0.53295, 0.03169, 0.00705], + [0.51989, 0.02756, 0.00780], + [0.50664, 0.02354, 0.00863], + [0.49321, 0.01963, 0.00955], + [0.47960, 0.01583, 0.01055]] + + +cmaps = { + name: ListedColormap(data, name=name) for name, data in [ + ('magma', _magma_data), + ('inferno', _inferno_data), + ('plasma', _plasma_data), + ('viridis', _viridis_data), + ('cividis', _cividis_data), + ('twilight', _twilight_data), + ('twilight_shifted', _twilight_shifted_data), + ('turbo', _turbo_data), + ]} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.py new file mode 100644 index 00000000..44f97adb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.py @@ -0,0 +1,1141 @@ +BASE_COLORS = { + 'b': (0, 0, 1), # blue + 'g': (0, 0.5, 0), # green + 'r': (1, 0, 0), # red + 'c': (0, 0.75, 0.75), # cyan + 'm': (0.75, 0, 0.75), # magenta + 'y': (0.75, 0.75, 0), # yellow + 'k': (0, 0, 0), # black + 'w': (1, 1, 1), # white +} + + +# These colors are from Tableau +TABLEAU_COLORS = { + 'tab:blue': '#1f77b4', + 'tab:orange': '#ff7f0e', + 'tab:green': '#2ca02c', + 'tab:red': '#d62728', + 'tab:purple': '#9467bd', + 'tab:brown': '#8c564b', + 'tab:pink': '#e377c2', + 'tab:gray': '#7f7f7f', + 'tab:olive': '#bcbd22', + 'tab:cyan': '#17becf', +} + + +# This mapping of color names -> hex values is taken from +# a survey run by Randall Munroe see: +# https://blog.xkcd.com/2010/05/03/color-survey-results/ +# for more details. The results are hosted at +# https://xkcd.com/color/rgb/ +# and also available as a text file at +# https://xkcd.com/color/rgb.txt +# +# License: https://creativecommons.org/publicdomain/zero/1.0/ +XKCD_COLORS = { + 'cloudy blue': '#acc2d9', + 'dark pastel green': '#56ae57', + 'dust': '#b2996e', + 'electric lime': '#a8ff04', + 'fresh green': '#69d84f', + 'light eggplant': '#894585', + 'nasty green': '#70b23f', + 'really light blue': '#d4ffff', + 'tea': '#65ab7c', + 'warm purple': '#952e8f', + 'yellowish tan': '#fcfc81', + 'cement': '#a5a391', + 'dark grass green': '#388004', + 'dusty teal': '#4c9085', + 'grey teal': '#5e9b8a', + 'macaroni and cheese': '#efb435', + 'pinkish tan': '#d99b82', + 'spruce': '#0a5f38', + 'strong blue': '#0c06f7', + 'toxic green': '#61de2a', + 'windows blue': '#3778bf', + 'blue blue': '#2242c7', + 'blue with a hint of purple': '#533cc6', + 'booger': '#9bb53c', + 'bright sea green': '#05ffa6', + 'dark green blue': '#1f6357', + 'deep turquoise': '#017374', + 'green teal': '#0cb577', + 'strong pink': '#ff0789', + 'bland': '#afa88b', + 'deep aqua': '#08787f', + 'lavender pink': '#dd85d7', + 'light moss green': '#a6c875', + 'light seafoam green': '#a7ffb5', + 'olive yellow': '#c2b709', + 'pig pink': '#e78ea5', + 'deep lilac': '#966ebd', + 'desert': '#ccad60', + 'dusty lavender': '#ac86a8', + 'purpley grey': '#947e94', + 'purply': '#983fb2', + 'candy pink': '#ff63e9', + 'light pastel green': '#b2fba5', + 'boring green': '#63b365', + 'kiwi green': '#8ee53f', + 'light grey green': '#b7e1a1', + 'orange pink': '#ff6f52', + 'tea green': '#bdf8a3', + 'very light brown': '#d3b683', + 'egg shell': '#fffcc4', + 'eggplant purple': '#430541', + 'powder pink': '#ffb2d0', + 'reddish grey': '#997570', + 'baby shit brown': '#ad900d', + 'liliac': '#c48efd', + 'stormy blue': '#507b9c', + 'ugly brown': '#7d7103', + 'custard': '#fffd78', + 'darkish pink': '#da467d', + 'deep brown': '#410200', + 'greenish beige': '#c9d179', + 'manilla': '#fffa86', + 'off blue': '#5684ae', + 'battleship grey': '#6b7c85', + 'browny green': '#6f6c0a', + 'bruise': '#7e4071', + 'kelley green': '#009337', + 'sickly yellow': '#d0e429', + 'sunny yellow': '#fff917', + 'azul': '#1d5dec', + 'darkgreen': '#054907', + 'green/yellow': '#b5ce08', + 'lichen': '#8fb67b', + 'light light green': '#c8ffb0', + 'pale gold': '#fdde6c', + 'sun yellow': '#ffdf22', + 'tan green': '#a9be70', + 'burple': '#6832e3', + 'butterscotch': '#fdb147', + 'toupe': '#c7ac7d', + 'dark cream': '#fff39a', + 'indian red': '#850e04', + 'light lavendar': '#efc0fe', + 'poison green': '#40fd14', + 'baby puke green': '#b6c406', + 'bright yellow green': '#9dff00', + 'charcoal grey': '#3c4142', + 'squash': '#f2ab15', + 'cinnamon': '#ac4f06', + 'light pea green': '#c4fe82', + 'radioactive green': '#2cfa1f', + 'raw sienna': '#9a6200', + 'baby purple': '#ca9bf7', + 'cocoa': '#875f42', + 'light royal blue': '#3a2efe', + 'orangeish': '#fd8d49', + 'rust brown': '#8b3103', + 'sand brown': '#cba560', + 'swamp': '#698339', + 'tealish green': '#0cdc73', + 'burnt siena': '#b75203', + 'camo': '#7f8f4e', + 'dusk blue': '#26538d', + 'fern': '#63a950', + 'old rose': '#c87f89', + 'pale light green': '#b1fc99', + 'peachy pink': '#ff9a8a', + 'rosy pink': '#f6688e', + 'light bluish green': '#76fda8', + 'light bright green': '#53fe5c', + 'light neon green': '#4efd54', + 'light seafoam': '#a0febf', + 'tiffany blue': '#7bf2da', + 'washed out green': '#bcf5a6', + 'browny orange': '#ca6b02', + 'nice blue': '#107ab0', + 'sapphire': '#2138ab', + 'greyish teal': '#719f91', + 'orangey yellow': '#fdb915', + 'parchment': '#fefcaf', + 'straw': '#fcf679', + 'very dark brown': '#1d0200', + 'terracota': '#cb6843', + 'ugly blue': '#31668a', + 'clear blue': '#247afd', + 'creme': '#ffffb6', + 'foam green': '#90fda9', + 'grey/green': '#86a17d', + 'light gold': '#fddc5c', + 'seafoam blue': '#78d1b6', + 'topaz': '#13bbaf', + 'violet pink': '#fb5ffc', + 'wintergreen': '#20f986', + 'yellow tan': '#ffe36e', + 'dark fuchsia': '#9d0759', + 'indigo blue': '#3a18b1', + 'light yellowish green': '#c2ff89', + 'pale magenta': '#d767ad', + 'rich purple': '#720058', + 'sunflower yellow': '#ffda03', + 'green/blue': '#01c08d', + 'leather': '#ac7434', + 'racing green': '#014600', + 'vivid purple': '#9900fa', + 'dark royal blue': '#02066f', + 'hazel': '#8e7618', + 'muted pink': '#d1768f', + 'booger green': '#96b403', + 'canary': '#fdff63', + 'cool grey': '#95a3a6', + 'dark taupe': '#7f684e', + 'darkish purple': '#751973', + 'true green': '#089404', + 'coral pink': '#ff6163', + 'dark sage': '#598556', + 'dark slate blue': '#214761', + 'flat blue': '#3c73a8', + 'mushroom': '#ba9e88', + 'rich blue': '#021bf9', + 'dirty purple': '#734a65', + 'greenblue': '#23c48b', + 'icky green': '#8fae22', + 'light khaki': '#e6f2a2', + 'warm blue': '#4b57db', + 'dark hot pink': '#d90166', + 'deep sea blue': '#015482', + 'carmine': '#9d0216', + 'dark yellow green': '#728f02', + 'pale peach': '#ffe5ad', + 'plum purple': '#4e0550', + 'golden rod': '#f9bc08', + 'neon red': '#ff073a', + 'old pink': '#c77986', + 'very pale blue': '#d6fffe', + 'blood orange': '#fe4b03', + 'grapefruit': '#fd5956', + 'sand yellow': '#fce166', + 'clay brown': '#b2713d', + 'dark blue grey': '#1f3b4d', + 'flat green': '#699d4c', + 'light green blue': '#56fca2', + 'warm pink': '#fb5581', + 'dodger blue': '#3e82fc', + 'gross green': '#a0bf16', + 'ice': '#d6fffa', + 'metallic blue': '#4f738e', + 'pale salmon': '#ffb19a', + 'sap green': '#5c8b15', + 'algae': '#54ac68', + 'bluey grey': '#89a0b0', + 'greeny grey': '#7ea07a', + 'highlighter green': '#1bfc06', + 'light light blue': '#cafffb', + 'light mint': '#b6ffbb', + 'raw umber': '#a75e09', + 'vivid blue': '#152eff', + 'deep lavender': '#8d5eb7', + 'dull teal': '#5f9e8f', + 'light greenish blue': '#63f7b4', + 'mud green': '#606602', + 'pinky': '#fc86aa', + 'red wine': '#8c0034', + 'shit green': '#758000', + 'tan brown': '#ab7e4c', + 'darkblue': '#030764', + 'rosa': '#fe86a4', + 'lipstick': '#d5174e', + 'pale mauve': '#fed0fc', + 'claret': '#680018', + 'dandelion': '#fedf08', + 'orangered': '#fe420f', + 'poop green': '#6f7c00', + 'ruby': '#ca0147', + 'dark': '#1b2431', + 'greenish turquoise': '#00fbb0', + 'pastel red': '#db5856', + 'piss yellow': '#ddd618', + 'bright cyan': '#41fdfe', + 'dark coral': '#cf524e', + 'algae green': '#21c36f', + 'darkish red': '#a90308', + 'reddy brown': '#6e1005', + 'blush pink': '#fe828c', + 'camouflage green': '#4b6113', + 'lawn green': '#4da409', + 'putty': '#beae8a', + 'vibrant blue': '#0339f8', + 'dark sand': '#a88f59', + 'purple/blue': '#5d21d0', + 'saffron': '#feb209', + 'twilight': '#4e518b', + 'warm brown': '#964e02', + 'bluegrey': '#85a3b2', + 'bubble gum pink': '#ff69af', + 'duck egg blue': '#c3fbf4', + 'greenish cyan': '#2afeb7', + 'petrol': '#005f6a', + 'royal': '#0c1793', + 'butter': '#ffff81', + 'dusty orange': '#f0833a', + 'off yellow': '#f1f33f', + 'pale olive green': '#b1d27b', + 'orangish': '#fc824a', + 'leaf': '#71aa34', + 'light blue grey': '#b7c9e2', + 'dried blood': '#4b0101', + 'lightish purple': '#a552e6', + 'rusty red': '#af2f0d', + 'lavender blue': '#8b88f8', + 'light grass green': '#9af764', + 'light mint green': '#a6fbb2', + 'sunflower': '#ffc512', + 'velvet': '#750851', + 'brick orange': '#c14a09', + 'lightish red': '#fe2f4a', + 'pure blue': '#0203e2', + 'twilight blue': '#0a437a', + 'violet red': '#a50055', + 'yellowy brown': '#ae8b0c', + 'carnation': '#fd798f', + 'muddy yellow': '#bfac05', + 'dark seafoam green': '#3eaf76', + 'deep rose': '#c74767', + 'dusty red': '#b9484e', + 'grey/blue': '#647d8e', + 'lemon lime': '#bffe28', + 'purple/pink': '#d725de', + 'brown yellow': '#b29705', + 'purple brown': '#673a3f', + 'wisteria': '#a87dc2', + 'banana yellow': '#fafe4b', + 'lipstick red': '#c0022f', + 'water blue': '#0e87cc', + 'brown grey': '#8d8468', + 'vibrant purple': '#ad03de', + 'baby green': '#8cff9e', + 'barf green': '#94ac02', + 'eggshell blue': '#c4fff7', + 'sandy yellow': '#fdee73', + 'cool green': '#33b864', + 'pale': '#fff9d0', + 'blue/grey': '#758da3', + 'hot magenta': '#f504c9', + 'greyblue': '#77a1b5', + 'purpley': '#8756e4', + 'baby shit green': '#889717', + 'brownish pink': '#c27e79', + 'dark aquamarine': '#017371', + 'diarrhea': '#9f8303', + 'light mustard': '#f7d560', + 'pale sky blue': '#bdf6fe', + 'turtle green': '#75b84f', + 'bright olive': '#9cbb04', + 'dark grey blue': '#29465b', + 'greeny brown': '#696006', + 'lemon green': '#adf802', + 'light periwinkle': '#c1c6fc', + 'seaweed green': '#35ad6b', + 'sunshine yellow': '#fffd37', + 'ugly purple': '#a442a0', + 'medium pink': '#f36196', + 'puke brown': '#947706', + 'very light pink': '#fff4f2', + 'viridian': '#1e9167', + 'bile': '#b5c306', + 'faded yellow': '#feff7f', + 'very pale green': '#cffdbc', + 'vibrant green': '#0add08', + 'bright lime': '#87fd05', + 'spearmint': '#1ef876', + 'light aquamarine': '#7bfdc7', + 'light sage': '#bcecac', + 'yellowgreen': '#bbf90f', + 'baby poo': '#ab9004', + 'dark seafoam': '#1fb57a', + 'deep teal': '#00555a', + 'heather': '#a484ac', + 'rust orange': '#c45508', + 'dirty blue': '#3f829d', + 'fern green': '#548d44', + 'bright lilac': '#c95efb', + 'weird green': '#3ae57f', + 'peacock blue': '#016795', + 'avocado green': '#87a922', + 'faded orange': '#f0944d', + 'grape purple': '#5d1451', + 'hot green': '#25ff29', + 'lime yellow': '#d0fe1d', + 'mango': '#ffa62b', + 'shamrock': '#01b44c', + 'bubblegum': '#ff6cb5', + 'purplish brown': '#6b4247', + 'vomit yellow': '#c7c10c', + 'pale cyan': '#b7fffa', + 'key lime': '#aeff6e', + 'tomato red': '#ec2d01', + 'lightgreen': '#76ff7b', + 'merlot': '#730039', + 'night blue': '#040348', + 'purpleish pink': '#df4ec8', + 'apple': '#6ecb3c', + 'baby poop green': '#8f9805', + 'green apple': '#5edc1f', + 'heliotrope': '#d94ff5', + 'yellow/green': '#c8fd3d', + 'almost black': '#070d0d', + 'cool blue': '#4984b8', + 'leafy green': '#51b73b', + 'mustard brown': '#ac7e04', + 'dusk': '#4e5481', + 'dull brown': '#876e4b', + 'frog green': '#58bc08', + 'vivid green': '#2fef10', + 'bright light green': '#2dfe54', + 'fluro green': '#0aff02', + 'kiwi': '#9cef43', + 'seaweed': '#18d17b', + 'navy green': '#35530a', + 'ultramarine blue': '#1805db', + 'iris': '#6258c4', + 'pastel orange': '#ff964f', + 'yellowish orange': '#ffab0f', + 'perrywinkle': '#8f8ce7', + 'tealish': '#24bca8', + 'dark plum': '#3f012c', + 'pear': '#cbf85f', + 'pinkish orange': '#ff724c', + 'midnight purple': '#280137', + 'light urple': '#b36ff6', + 'dark mint': '#48c072', + 'greenish tan': '#bccb7a', + 'light burgundy': '#a8415b', + 'turquoise blue': '#06b1c4', + 'ugly pink': '#cd7584', + 'sandy': '#f1da7a', + 'electric pink': '#ff0490', + 'muted purple': '#805b87', + 'mid green': '#50a747', + 'greyish': '#a8a495', + 'neon yellow': '#cfff04', + 'banana': '#ffff7e', + 'carnation pink': '#ff7fa7', + 'tomato': '#ef4026', + 'sea': '#3c9992', + 'muddy brown': '#886806', + 'turquoise green': '#04f489', + 'buff': '#fef69e', + 'fawn': '#cfaf7b', + 'muted blue': '#3b719f', + 'pale rose': '#fdc1c5', + 'dark mint green': '#20c073', + 'amethyst': '#9b5fc0', + 'blue/green': '#0f9b8e', + 'chestnut': '#742802', + 'sick green': '#9db92c', + 'pea': '#a4bf20', + 'rusty orange': '#cd5909', + 'stone': '#ada587', + 'rose red': '#be013c', + 'pale aqua': '#b8ffeb', + 'deep orange': '#dc4d01', + 'earth': '#a2653e', + 'mossy green': '#638b27', + 'grassy green': '#419c03', + 'pale lime green': '#b1ff65', + 'light grey blue': '#9dbcd4', + 'pale grey': '#fdfdfe', + 'asparagus': '#77ab56', + 'blueberry': '#464196', + 'purple red': '#990147', + 'pale lime': '#befd73', + 'greenish teal': '#32bf84', + 'caramel': '#af6f09', + 'deep magenta': '#a0025c', + 'light peach': '#ffd8b1', + 'milk chocolate': '#7f4e1e', + 'ocher': '#bf9b0c', + 'off green': '#6ba353', + 'purply pink': '#f075e6', + 'lightblue': '#7bc8f6', + 'dusky blue': '#475f94', + 'golden': '#f5bf03', + 'light beige': '#fffeb6', + 'butter yellow': '#fffd74', + 'dusky purple': '#895b7b', + 'french blue': '#436bad', + 'ugly yellow': '#d0c101', + 'greeny yellow': '#c6f808', + 'orangish red': '#f43605', + 'shamrock green': '#02c14d', + 'orangish brown': '#b25f03', + 'tree green': '#2a7e19', + 'deep violet': '#490648', + 'gunmetal': '#536267', + 'blue/purple': '#5a06ef', + 'cherry': '#cf0234', + 'sandy brown': '#c4a661', + 'warm grey': '#978a84', + 'dark indigo': '#1f0954', + 'midnight': '#03012d', + 'bluey green': '#2bb179', + 'grey pink': '#c3909b', + 'soft purple': '#a66fb5', + 'blood': '#770001', + 'brown red': '#922b05', + 'medium grey': '#7d7f7c', + 'berry': '#990f4b', + 'poo': '#8f7303', + 'purpley pink': '#c83cb9', + 'light salmon': '#fea993', + 'snot': '#acbb0d', + 'easter purple': '#c071fe', + 'light yellow green': '#ccfd7f', + 'dark navy blue': '#00022e', + 'drab': '#828344', + 'light rose': '#ffc5cb', + 'rouge': '#ab1239', + 'purplish red': '#b0054b', + 'slime green': '#99cc04', + 'baby poop': '#937c00', + 'irish green': '#019529', + 'pink/purple': '#ef1de7', + 'dark navy': '#000435', + 'greeny blue': '#42b395', + 'light plum': '#9d5783', + 'pinkish grey': '#c8aca9', + 'dirty orange': '#c87606', + 'rust red': '#aa2704', + 'pale lilac': '#e4cbff', + 'orangey red': '#fa4224', + 'primary blue': '#0804f9', + 'kermit green': '#5cb200', + 'brownish purple': '#76424e', + 'murky green': '#6c7a0e', + 'wheat': '#fbdd7e', + 'very dark purple': '#2a0134', + 'bottle green': '#044a05', + 'watermelon': '#fd4659', + 'deep sky blue': '#0d75f8', + 'fire engine red': '#fe0002', + 'yellow ochre': '#cb9d06', + 'pumpkin orange': '#fb7d07', + 'pale olive': '#b9cc81', + 'light lilac': '#edc8ff', + 'lightish green': '#61e160', + 'carolina blue': '#8ab8fe', + 'mulberry': '#920a4e', + 'shocking pink': '#fe02a2', + 'auburn': '#9a3001', + 'bright lime green': '#65fe08', + 'celadon': '#befdb7', + 'pinkish brown': '#b17261', + 'poo brown': '#885f01', + 'bright sky blue': '#02ccfe', + 'celery': '#c1fd95', + 'dirt brown': '#836539', + 'strawberry': '#fb2943', + 'dark lime': '#84b701', + 'copper': '#b66325', + 'medium brown': '#7f5112', + 'muted green': '#5fa052', + "robin's egg": '#6dedfd', + 'bright aqua': '#0bf9ea', + 'bright lavender': '#c760ff', + 'ivory': '#ffffcb', + 'very light purple': '#f6cefc', + 'light navy': '#155084', + 'pink red': '#f5054f', + 'olive brown': '#645403', + 'poop brown': '#7a5901', + 'mustard green': '#a8b504', + 'ocean green': '#3d9973', + 'very dark blue': '#000133', + 'dusty green': '#76a973', + 'light navy blue': '#2e5a88', + 'minty green': '#0bf77d', + 'adobe': '#bd6c48', + 'barney': '#ac1db8', + 'jade green': '#2baf6a', + 'bright light blue': '#26f7fd', + 'light lime': '#aefd6c', + 'dark khaki': '#9b8f55', + 'orange yellow': '#ffad01', + 'ocre': '#c69c04', + 'maize': '#f4d054', + 'faded pink': '#de9dac', + 'british racing green': '#05480d', + 'sandstone': '#c9ae74', + 'mud brown': '#60460f', + 'light sea green': '#98f6b0', + 'robin egg blue': '#8af1fe', + 'aqua marine': '#2ee8bb', + 'dark sea green': '#11875d', + 'soft pink': '#fdb0c0', + 'orangey brown': '#b16002', + 'cherry red': '#f7022a', + 'burnt yellow': '#d5ab09', + 'brownish grey': '#86775f', + 'camel': '#c69f59', + 'purplish grey': '#7a687f', + 'marine': '#042e60', + 'greyish pink': '#c88d94', + 'pale turquoise': '#a5fbd5', + 'pastel yellow': '#fffe71', + 'bluey purple': '#6241c7', + 'canary yellow': '#fffe40', + 'faded red': '#d3494e', + 'sepia': '#985e2b', + 'coffee': '#a6814c', + 'bright magenta': '#ff08e8', + 'mocha': '#9d7651', + 'ecru': '#feffca', + 'purpleish': '#98568d', + 'cranberry': '#9e003a', + 'darkish green': '#287c37', + 'brown orange': '#b96902', + 'dusky rose': '#ba6873', + 'melon': '#ff7855', + 'sickly green': '#94b21c', + 'silver': '#c5c9c7', + 'purply blue': '#661aee', + 'purpleish blue': '#6140ef', + 'hospital green': '#9be5aa', + 'shit brown': '#7b5804', + 'mid blue': '#276ab3', + 'amber': '#feb308', + 'easter green': '#8cfd7e', + 'soft blue': '#6488ea', + 'cerulean blue': '#056eee', + 'golden brown': '#b27a01', + 'bright turquoise': '#0ffef9', + 'red pink': '#fa2a55', + 'red purple': '#820747', + 'greyish brown': '#7a6a4f', + 'vermillion': '#f4320c', + 'russet': '#a13905', + 'steel grey': '#6f828a', + 'lighter purple': '#a55af4', + 'bright violet': '#ad0afd', + 'prussian blue': '#004577', + 'slate green': '#658d6d', + 'dirty pink': '#ca7b80', + 'dark blue green': '#005249', + 'pine': '#2b5d34', + 'yellowy green': '#bff128', + 'dark gold': '#b59410', + 'bluish': '#2976bb', + 'darkish blue': '#014182', + 'dull red': '#bb3f3f', + 'pinky red': '#fc2647', + 'bronze': '#a87900', + 'pale teal': '#82cbb2', + 'military green': '#667c3e', + 'barbie pink': '#fe46a5', + 'bubblegum pink': '#fe83cc', + 'pea soup green': '#94a617', + 'dark mustard': '#a88905', + 'shit': '#7f5f00', + 'medium purple': '#9e43a2', + 'very dark green': '#062e03', + 'dirt': '#8a6e45', + 'dusky pink': '#cc7a8b', + 'red violet': '#9e0168', + 'lemon yellow': '#fdff38', + 'pistachio': '#c0fa8b', + 'dull yellow': '#eedc5b', + 'dark lime green': '#7ebd01', + 'denim blue': '#3b5b92', + 'teal blue': '#01889f', + 'lightish blue': '#3d7afd', + 'purpley blue': '#5f34e7', + 'light indigo': '#6d5acf', + 'swamp green': '#748500', + 'brown green': '#706c11', + 'dark maroon': '#3c0008', + 'hot purple': '#cb00f5', + 'dark forest green': '#002d04', + 'faded blue': '#658cbb', + 'drab green': '#749551', + 'light lime green': '#b9ff66', + 'snot green': '#9dc100', + 'yellowish': '#faee66', + 'light blue green': '#7efbb3', + 'bordeaux': '#7b002c', + 'light mauve': '#c292a1', + 'ocean': '#017b92', + 'marigold': '#fcc006', + 'muddy green': '#657432', + 'dull orange': '#d8863b', + 'steel': '#738595', + 'electric purple': '#aa23ff', + 'fluorescent green': '#08ff08', + 'yellowish brown': '#9b7a01', + 'blush': '#f29e8e', + 'soft green': '#6fc276', + 'bright orange': '#ff5b00', + 'lemon': '#fdff52', + 'purple grey': '#866f85', + 'acid green': '#8ffe09', + 'pale lavender': '#eecffe', + 'violet blue': '#510ac9', + 'light forest green': '#4f9153', + 'burnt red': '#9f2305', + 'khaki green': '#728639', + 'cerise': '#de0c62', + 'faded purple': '#916e99', + 'apricot': '#ffb16d', + 'dark olive green': '#3c4d03', + 'grey brown': '#7f7053', + 'green grey': '#77926f', + 'true blue': '#010fcc', + 'pale violet': '#ceaefa', + 'periwinkle blue': '#8f99fb', + 'light sky blue': '#c6fcff', + 'blurple': '#5539cc', + 'green brown': '#544e03', + 'bluegreen': '#017a79', + 'bright teal': '#01f9c6', + 'brownish yellow': '#c9b003', + 'pea soup': '#929901', + 'forest': '#0b5509', + 'barney purple': '#a00498', + 'ultramarine': '#2000b1', + 'purplish': '#94568c', + 'puke yellow': '#c2be0e', + 'bluish grey': '#748b97', + 'dark periwinkle': '#665fd1', + 'dark lilac': '#9c6da5', + 'reddish': '#c44240', + 'light maroon': '#a24857', + 'dusty purple': '#825f87', + 'terra cotta': '#c9643b', + 'avocado': '#90b134', + 'marine blue': '#01386a', + 'teal green': '#25a36f', + 'slate grey': '#59656d', + 'lighter green': '#75fd63', + 'electric green': '#21fc0d', + 'dusty blue': '#5a86ad', + 'golden yellow': '#fec615', + 'bright yellow': '#fffd01', + 'light lavender': '#dfc5fe', + 'umber': '#b26400', + 'poop': '#7f5e00', + 'dark peach': '#de7e5d', + 'jungle green': '#048243', + 'eggshell': '#ffffd4', + 'denim': '#3b638c', + 'yellow brown': '#b79400', + 'dull purple': '#84597e', + 'chocolate brown': '#411900', + 'wine red': '#7b0323', + 'neon blue': '#04d9ff', + 'dirty green': '#667e2c', + 'light tan': '#fbeeac', + 'ice blue': '#d7fffe', + 'cadet blue': '#4e7496', + 'dark mauve': '#874c62', + 'very light blue': '#d5ffff', + 'grey purple': '#826d8c', + 'pastel pink': '#ffbacd', + 'very light green': '#d1ffbd', + 'dark sky blue': '#448ee4', + 'evergreen': '#05472a', + 'dull pink': '#d5869d', + 'aubergine': '#3d0734', + 'mahogany': '#4a0100', + 'reddish orange': '#f8481c', + 'deep green': '#02590f', + 'vomit green': '#89a203', + 'purple pink': '#e03fd8', + 'dusty pink': '#d58a94', + 'faded green': '#7bb274', + 'camo green': '#526525', + 'pinky purple': '#c94cbe', + 'pink purple': '#db4bda', + 'brownish red': '#9e3623', + 'dark rose': '#b5485d', + 'mud': '#735c12', + 'brownish': '#9c6d57', + 'emerald green': '#028f1e', + 'pale brown': '#b1916e', + 'dull blue': '#49759c', + 'burnt umber': '#a0450e', + 'medium green': '#39ad48', + 'clay': '#b66a50', + 'light aqua': '#8cffdb', + 'light olive green': '#a4be5c', + 'brownish orange': '#cb7723', + 'dark aqua': '#05696b', + 'purplish pink': '#ce5dae', + 'dark salmon': '#c85a53', + 'greenish grey': '#96ae8d', + 'jade': '#1fa774', + 'ugly green': '#7a9703', + 'dark beige': '#ac9362', + 'emerald': '#01a049', + 'pale red': '#d9544d', + 'light magenta': '#fa5ff7', + 'sky': '#82cafc', + 'light cyan': '#acfffc', + 'yellow orange': '#fcb001', + 'reddish purple': '#910951', + 'reddish pink': '#fe2c54', + 'orchid': '#c875c4', + 'dirty yellow': '#cdc50a', + 'orange red': '#fd411e', + 'deep red': '#9a0200', + 'orange brown': '#be6400', + 'cobalt blue': '#030aa7', + 'neon pink': '#fe019a', + 'rose pink': '#f7879a', + 'greyish purple': '#887191', + 'raspberry': '#b00149', + 'aqua green': '#12e193', + 'salmon pink': '#fe7b7c', + 'tangerine': '#ff9408', + 'brownish green': '#6a6e09', + 'red brown': '#8b2e16', + 'greenish brown': '#696112', + 'pumpkin': '#e17701', + 'pine green': '#0a481e', + 'charcoal': '#343837', + 'baby pink': '#ffb7ce', + 'cornflower': '#6a79f7', + 'blue violet': '#5d06e9', + 'chocolate': '#3d1c02', + 'greyish green': '#82a67d', + 'scarlet': '#be0119', + 'green yellow': '#c9ff27', + 'dark olive': '#373e02', + 'sienna': '#a9561e', + 'pastel purple': '#caa0ff', + 'terracotta': '#ca6641', + 'aqua blue': '#02d8e9', + 'sage green': '#88b378', + 'blood red': '#980002', + 'deep pink': '#cb0162', + 'grass': '#5cac2d', + 'moss': '#769958', + 'pastel blue': '#a2bffe', + 'bluish green': '#10a674', + 'green blue': '#06b48b', + 'dark tan': '#af884a', + 'greenish blue': '#0b8b87', + 'pale orange': '#ffa756', + 'vomit': '#a2a415', + 'forrest green': '#154406', + 'dark lavender': '#856798', + 'dark violet': '#34013f', + 'purple blue': '#632de9', + 'dark cyan': '#0a888a', + 'olive drab': '#6f7632', + 'pinkish': '#d46a7e', + 'cobalt': '#1e488f', + 'neon purple': '#bc13fe', + 'light turquoise': '#7ef4cc', + 'apple green': '#76cd26', + 'dull green': '#74a662', + 'wine': '#80013f', + 'powder blue': '#b1d1fc', + 'off white': '#ffffe4', + 'electric blue': '#0652ff', + 'dark turquoise': '#045c5a', + 'blue purple': '#5729ce', + 'azure': '#069af3', + 'bright red': '#ff000d', + 'pinkish red': '#f10c45', + 'cornflower blue': '#5170d7', + 'light olive': '#acbf69', + 'grape': '#6c3461', + 'greyish blue': '#5e819d', + 'purplish blue': '#601ef9', + 'yellowish green': '#b0dd16', + 'greenish yellow': '#cdfd02', + 'medium blue': '#2c6fbb', + 'dusty rose': '#c0737a', + 'light violet': '#d6b4fc', + 'midnight blue': '#020035', + 'bluish purple': '#703be7', + 'red orange': '#fd3c06', + 'dark magenta': '#960056', + 'greenish': '#40a368', + 'ocean blue': '#03719c', + 'coral': '#fc5a50', + 'cream': '#ffffc2', + 'reddish brown': '#7f2b0a', + 'burnt sienna': '#b04e0f', + 'brick': '#a03623', + 'sage': '#87ae73', + 'grey green': '#789b73', + 'white': '#ffffff', + "robin's egg blue": '#98eff9', + 'moss green': '#658b38', + 'steel blue': '#5a7d9a', + 'eggplant': '#380835', + 'light yellow': '#fffe7a', + 'leaf green': '#5ca904', + 'light grey': '#d8dcd6', + 'puke': '#a5a502', + 'pinkish purple': '#d648d7', + 'sea blue': '#047495', + 'pale purple': '#b790d4', + 'slate blue': '#5b7c99', + 'blue grey': '#607c8e', + 'hunter green': '#0b4008', + 'fuchsia': '#ed0dd9', + 'crimson': '#8c000f', + 'pale yellow': '#ffff84', + 'ochre': '#bf9005', + 'mustard yellow': '#d2bd0a', + 'light red': '#ff474c', + 'cerulean': '#0485d1', + 'pale pink': '#ffcfdc', + 'deep blue': '#040273', + 'rust': '#a83c09', + 'light teal': '#90e4c1', + 'slate': '#516572', + 'goldenrod': '#fac205', + 'dark yellow': '#d5b60a', + 'dark grey': '#363737', + 'army green': '#4b5d16', + 'grey blue': '#6b8ba4', + 'seafoam': '#80f9ad', + 'puce': '#a57e52', + 'spring green': '#a9f971', + 'dark orange': '#c65102', + 'sand': '#e2ca76', + 'pastel green': '#b0ff9d', + 'mint': '#9ffeb0', + 'light orange': '#fdaa48', + 'bright pink': '#fe01b1', + 'chartreuse': '#c1f80a', + 'deep purple': '#36013f', + 'dark brown': '#341c02', + 'taupe': '#b9a281', + 'pea green': '#8eab12', + 'puke green': '#9aae07', + 'kelly green': '#02ab2e', + 'seafoam green': '#7af9ab', + 'blue green': '#137e6d', + 'khaki': '#aaa662', + 'burgundy': '#610023', + 'dark teal': '#014d4e', + 'brick red': '#8f1402', + 'royal purple': '#4b006e', + 'plum': '#580f41', + 'mint green': '#8fff9f', + 'gold': '#dbb40c', + 'baby blue': '#a2cffe', + 'yellow green': '#c0fb2d', + 'bright purple': '#be03fd', + 'dark red': '#840000', + 'pale blue': '#d0fefe', + 'grass green': '#3f9b0b', + 'navy': '#01153e', + 'aquamarine': '#04d8b2', + 'burnt orange': '#c04e01', + 'neon green': '#0cff0c', + 'bright blue': '#0165fc', + 'rose': '#cf6275', + 'light pink': '#ffd1df', + 'mustard': '#ceb301', + 'indigo': '#380282', + 'lime': '#aaff32', + 'sea green': '#53fca1', + 'periwinkle': '#8e82fe', + 'dark pink': '#cb416b', + 'olive green': '#677a04', + 'peach': '#ffb07c', + 'pale green': '#c7fdb5', + 'light brown': '#ad8150', + 'hot pink': '#ff028d', + 'black': '#000000', + 'lilac': '#cea2fd', + 'navy blue': '#001146', + 'royal blue': '#0504aa', + 'beige': '#e6daa6', + 'salmon': '#ff796c', + 'olive': '#6e750e', + 'maroon': '#650021', + 'bright green': '#01ff07', + 'dark purple': '#35063e', + 'mauve': '#ae7181', + 'forest green': '#06470c', + 'aqua': '#13eac9', + 'cyan': '#00ffff', + 'tan': '#d1b26f', + 'dark blue': '#00035b', + 'lavender': '#c79fef', + 'turquoise': '#06c2ac', + 'dark green': '#033500', + 'violet': '#9a0eea', + 'light purple': '#bf77f6', + 'lime green': '#89fe05', + 'grey': '#929591', + 'sky blue': '#75bbfd', + 'yellow': '#ffff14', + 'magenta': '#c20078', + 'light green': '#96f97b', + 'orange': '#f97306', + 'teal': '#029386', + 'light blue': '#95d0fc', + 'red': '#e50000', + 'brown': '#653700', + 'pink': '#ff81c0', + 'blue': '#0343df', + 'green': '#15b01a', + 'purple': '#7e1e9c'} + +# Normalize name to "xkcd:" to avoid name collisions. +XKCD_COLORS = {'xkcd:' + name: value for name, value in XKCD_COLORS.items()} + + +# https://drafts.csswg.org/css-color-4/#named-colors +CSS4_COLORS = { + 'aliceblue': '#F0F8FF', + 'antiquewhite': '#FAEBD7', + 'aqua': '#00FFFF', + 'aquamarine': '#7FFFD4', + 'azure': '#F0FFFF', + 'beige': '#F5F5DC', + 'bisque': '#FFE4C4', + 'black': '#000000', + 'blanchedalmond': '#FFEBCD', + 'blue': '#0000FF', + 'blueviolet': '#8A2BE2', + 'brown': '#A52A2A', + 'burlywood': '#DEB887', + 'cadetblue': '#5F9EA0', + 'chartreuse': '#7FFF00', + 'chocolate': '#D2691E', + 'coral': '#FF7F50', + 'cornflowerblue': '#6495ED', + 'cornsilk': '#FFF8DC', + 'crimson': '#DC143C', + 'cyan': '#00FFFF', + 'darkblue': '#00008B', + 'darkcyan': '#008B8B', + 'darkgoldenrod': '#B8860B', + 'darkgray': '#A9A9A9', + 'darkgreen': '#006400', + 'darkgrey': '#A9A9A9', + 'darkkhaki': '#BDB76B', + 'darkmagenta': '#8B008B', + 'darkolivegreen': '#556B2F', + 'darkorange': '#FF8C00', + 'darkorchid': '#9932CC', + 'darkred': '#8B0000', + 'darksalmon': '#E9967A', + 'darkseagreen': '#8FBC8F', + 'darkslateblue': '#483D8B', + 'darkslategray': '#2F4F4F', + 'darkslategrey': '#2F4F4F', + 'darkturquoise': '#00CED1', + 'darkviolet': '#9400D3', + 'deeppink': '#FF1493', + 'deepskyblue': '#00BFFF', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1E90FF', + 'firebrick': '#B22222', + 'floralwhite': '#FFFAF0', + 'forestgreen': '#228B22', + 'fuchsia': '#FF00FF', + 'gainsboro': '#DCDCDC', + 'ghostwhite': '#F8F8FF', + 'gold': '#FFD700', + 'goldenrod': '#DAA520', + 'gray': '#808080', + 'green': '#008000', + 'greenyellow': '#ADFF2F', + 'grey': '#808080', + 'honeydew': '#F0FFF0', + 'hotpink': '#FF69B4', + 'indianred': '#CD5C5C', + 'indigo': '#4B0082', + 'ivory': '#FFFFF0', + 'khaki': '#F0E68C', + 'lavender': '#E6E6FA', + 'lavenderblush': '#FFF0F5', + 'lawngreen': '#7CFC00', + 'lemonchiffon': '#FFFACD', + 'lightblue': '#ADD8E6', + 'lightcoral': '#F08080', + 'lightcyan': '#E0FFFF', + 'lightgoldenrodyellow': '#FAFAD2', + 'lightgray': '#D3D3D3', + 'lightgreen': '#90EE90', + 'lightgrey': '#D3D3D3', + 'lightpink': '#FFB6C1', + 'lightsalmon': '#FFA07A', + 'lightseagreen': '#20B2AA', + 'lightskyblue': '#87CEFA', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#B0C4DE', + 'lightyellow': '#FFFFE0', + 'lime': '#00FF00', + 'limegreen': '#32CD32', + 'linen': '#FAF0E6', + 'magenta': '#FF00FF', + 'maroon': '#800000', + 'mediumaquamarine': '#66CDAA', + 'mediumblue': '#0000CD', + 'mediumorchid': '#BA55D3', + 'mediumpurple': '#9370DB', + 'mediumseagreen': '#3CB371', + 'mediumslateblue': '#7B68EE', + 'mediumspringgreen': '#00FA9A', + 'mediumturquoise': '#48D1CC', + 'mediumvioletred': '#C71585', + 'midnightblue': '#191970', + 'mintcream': '#F5FFFA', + 'mistyrose': '#FFE4E1', + 'moccasin': '#FFE4B5', + 'navajowhite': '#FFDEAD', + 'navy': '#000080', + 'oldlace': '#FDF5E6', + 'olive': '#808000', + 'olivedrab': '#6B8E23', + 'orange': '#FFA500', + 'orangered': '#FF4500', + 'orchid': '#DA70D6', + 'palegoldenrod': '#EEE8AA', + 'palegreen': '#98FB98', + 'paleturquoise': '#AFEEEE', + 'palevioletred': '#DB7093', + 'papayawhip': '#FFEFD5', + 'peachpuff': '#FFDAB9', + 'peru': '#CD853F', + 'pink': '#FFC0CB', + 'plum': '#DDA0DD', + 'powderblue': '#B0E0E6', + 'purple': '#800080', + 'rebeccapurple': '#663399', + 'red': '#FF0000', + 'rosybrown': '#BC8F8F', + 'royalblue': '#4169E1', + 'saddlebrown': '#8B4513', + 'salmon': '#FA8072', + 'sandybrown': '#F4A460', + 'seagreen': '#2E8B57', + 'seashell': '#FFF5EE', + 'sienna': '#A0522D', + 'silver': '#C0C0C0', + 'skyblue': '#87CEEB', + 'slateblue': '#6A5ACD', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#FFFAFA', + 'springgreen': '#00FF7F', + 'steelblue': '#4682B4', + 'tan': '#D2B48C', + 'teal': '#008080', + 'thistle': '#D8BFD8', + 'tomato': '#FF6347', + 'turquoise': '#40E0D0', + 'violet': '#EE82EE', + 'wheat': '#F5DEB3', + 'white': '#FFFFFF', + 'whitesmoke': '#F5F5F5', + 'yellow': '#FFFF00', + 'yellowgreen': '#9ACD32'} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.pyi new file mode 100644 index 00000000..feb3de9c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_color_data.pyi @@ -0,0 +1,6 @@ +from .typing import ColorType + +BASE_COLORS: dict[str, ColorType] +TABLEAU_COLORS: dict[str, ColorType] +XKCD_COLORS: dict[str, ColorType] +CSS4_COLORS: dict[str, ColorType] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_constrained_layout.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_constrained_layout.py new file mode 100644 index 00000000..907e7a24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_constrained_layout.py @@ -0,0 +1,794 @@ +""" +Adjust subplot layouts so that there are no overlapping axes or axes +decorations. All axes decorations are dealt with (labels, ticks, titles, +ticklabels) and some dependent artists are also dealt with (colorbar, +suptitle). + +Layout is done via `~matplotlib.gridspec`, with one constraint per gridspec, +so it is possible to have overlapping axes if the gridspecs overlap (i.e. +using `~matplotlib.gridspec.GridSpecFromSubplotSpec`). Axes placed using +``figure.subplots()`` or ``figure.add_subplots()`` will participate in the +layout. Axes manually placed via ``figure.add_axes()`` will not. + +See Tutorial: :ref:`constrainedlayout_guide` + +General idea: +------------- + +First, a figure has a gridspec that divides the figure into nrows and ncols, +with heights and widths set by ``height_ratios`` and ``width_ratios``, +often just set to 1 for an equal grid. + +Subplotspecs that are derived from this gridspec can contain either a +``SubPanel``, a ``GridSpecFromSubplotSpec``, or an ``Axes``. The ``SubPanel`` +and ``GridSpecFromSubplotSpec`` are dealt with recursively and each contain an +analogous layout. + +Each ``GridSpec`` has a ``_layoutgrid`` attached to it. The ``_layoutgrid`` +has the same logical layout as the ``GridSpec``. Each row of the grid spec +has a top and bottom "margin" and each column has a left and right "margin". +The "inner" height of each row is constrained to be the same (or as modified +by ``height_ratio``), and the "inner" width of each column is +constrained to be the same (as modified by ``width_ratio``), where "inner" +is the width or height of each column/row minus the size of the margins. + +Then the size of the margins for each row and column are determined as the +max width of the decorators on each axes that has decorators in that margin. +For instance, a normal axes would have a left margin that includes the +left ticklabels, and the ylabel if it exists. The right margin may include a +colorbar, the bottom margin the xaxis decorations, and the top margin the +title. + +With these constraints, the solver then finds appropriate bounds for the +columns and rows. It's possible that the margins take up the whole figure, +in which case the algorithm is not applied and a warning is raised. + +See the tutorial :ref:`constrainedlayout_guide` +for more discussion of the algorithm with examples. +""" + +import logging + +import numpy as np + +from matplotlib import _api, artist as martist +import matplotlib.transforms as mtransforms +import matplotlib._layoutgrid as mlayoutgrid + + +_log = logging.getLogger(__name__) + + +###################################################### +def do_constrained_layout(fig, h_pad, w_pad, + hspace=None, wspace=None, rect=(0, 0, 1, 1), + compress=False): + """ + Do the constrained_layout. Called at draw time in + ``figure.constrained_layout()`` + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + `.Figure` instance to do the layout in. + + h_pad, w_pad : float + Padding around the axes elements in figure-normalized units. + + hspace, wspace : float + Fraction of the figure to dedicate to space between the + axes. These are evenly spread between the gaps between the axes. + A value of 0.2 for a three-column layout would have a space + of 0.1 of the figure width between each column. + If h/wspace < h/w_pad, then the pads are used instead. + + rect : tuple of 4 floats + Rectangle in figure coordinates to perform constrained layout in + [left, bottom, width, height], each from 0-1. + + compress : bool + Whether to shift Axes so that white space in between them is + removed. This is useful for simple grids of fixed-aspect Axes (e.g. + a grid of images). + + Returns + ------- + layoutgrid : private debugging structure + """ + + renderer = fig._get_renderer() + # make layoutgrid tree... + layoutgrids = make_layoutgrids(fig, None, rect=rect) + if not layoutgrids['hasgrids']: + _api.warn_external('There are no gridspecs with layoutgrids. ' + 'Possibly did not call parent GridSpec with the' + ' "figure" keyword') + return + + for _ in range(2): + # do the algorithm twice. This has to be done because decorations + # change size after the first re-position (i.e. x/yticklabels get + # larger/smaller). This second reposition tends to be much milder, + # so doing twice makes things work OK. + + # make margins for all the axes and subfigures in the + # figure. Add margins for colorbars... + make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad, + w_pad=w_pad, hspace=hspace, wspace=wspace) + make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad, + w_pad=w_pad) + + # if a layout is such that a columns (or rows) margin has no + # constraints, we need to make all such instances in the grid + # match in margin size. + match_submerged_margins(layoutgrids, fig) + + # update all the variables in the layout. + layoutgrids[fig].update_variables() + + warn_collapsed = ('constrained_layout not applied because ' + 'axes sizes collapsed to zero. Try making ' + 'figure larger or axes decorations smaller.') + if check_no_collapsed_axes(layoutgrids, fig): + reposition_axes(layoutgrids, fig, renderer, h_pad=h_pad, + w_pad=w_pad, hspace=hspace, wspace=wspace) + if compress: + layoutgrids = compress_fixed_aspect(layoutgrids, fig) + layoutgrids[fig].update_variables() + if check_no_collapsed_axes(layoutgrids, fig): + reposition_axes(layoutgrids, fig, renderer, h_pad=h_pad, + w_pad=w_pad, hspace=hspace, wspace=wspace) + else: + _api.warn_external(warn_collapsed) + else: + _api.warn_external(warn_collapsed) + reset_margins(layoutgrids, fig) + return layoutgrids + + +def make_layoutgrids(fig, layoutgrids, rect=(0, 0, 1, 1)): + """ + Make the layoutgrid tree. + + (Sub)Figures get a layoutgrid so we can have figure margins. + + Gridspecs that are attached to axes get a layoutgrid so axes + can have margins. + """ + + if layoutgrids is None: + layoutgrids = dict() + layoutgrids['hasgrids'] = False + if not hasattr(fig, '_parent'): + # top figure; pass rect as parent to allow user-specified + # margins + layoutgrids[fig] = mlayoutgrid.LayoutGrid(parent=rect, name='figlb') + else: + # subfigure + gs = fig._subplotspec.get_gridspec() + # it is possible the gridspec containing this subfigure hasn't + # been added to the tree yet: + layoutgrids = make_layoutgrids_gs(layoutgrids, gs) + # add the layoutgrid for the subfigure: + parentlb = layoutgrids[gs] + layoutgrids[fig] = mlayoutgrid.LayoutGrid( + parent=parentlb, + name='panellb', + parent_inner=True, + nrows=1, ncols=1, + parent_pos=(fig._subplotspec.rowspan, + fig._subplotspec.colspan)) + # recursively do all subfigures in this figure... + for sfig in fig.subfigs: + layoutgrids = make_layoutgrids(sfig, layoutgrids) + + # for each axes at the local level add its gridspec: + for ax in fig._localaxes: + gs = ax.get_gridspec() + if gs is not None: + layoutgrids = make_layoutgrids_gs(layoutgrids, gs) + + return layoutgrids + + +def make_layoutgrids_gs(layoutgrids, gs): + """ + Make the layoutgrid for a gridspec (and anything nested in the gridspec) + """ + + if gs in layoutgrids or gs.figure is None: + return layoutgrids + # in order to do constrained_layout there has to be at least *one* + # gridspec in the tree: + layoutgrids['hasgrids'] = True + if not hasattr(gs, '_subplot_spec'): + # normal gridspec + parent = layoutgrids[gs.figure] + layoutgrids[gs] = mlayoutgrid.LayoutGrid( + parent=parent, + parent_inner=True, + name='gridspec', + ncols=gs._ncols, nrows=gs._nrows, + width_ratios=gs.get_width_ratios(), + height_ratios=gs.get_height_ratios()) + else: + # this is a gridspecfromsubplotspec: + subplot_spec = gs._subplot_spec + parentgs = subplot_spec.get_gridspec() + # if a nested gridspec it is possible the parent is not in there yet: + if parentgs not in layoutgrids: + layoutgrids = make_layoutgrids_gs(layoutgrids, parentgs) + subspeclb = layoutgrids[parentgs] + # gridspecfromsubplotspec need an outer container: + # get a unique representation: + rep = (gs, 'top') + if rep not in layoutgrids: + layoutgrids[rep] = mlayoutgrid.LayoutGrid( + parent=subspeclb, + name='top', + nrows=1, ncols=1, + parent_pos=(subplot_spec.rowspan, subplot_spec.colspan)) + layoutgrids[gs] = mlayoutgrid.LayoutGrid( + parent=layoutgrids[rep], + name='gridspec', + nrows=gs._nrows, ncols=gs._ncols, + width_ratios=gs.get_width_ratios(), + height_ratios=gs.get_height_ratios()) + return layoutgrids + + +def check_no_collapsed_axes(layoutgrids, fig): + """ + Check that no axes have collapsed to zero size. + """ + for sfig in fig.subfigs: + ok = check_no_collapsed_axes(layoutgrids, sfig) + if not ok: + return False + for ax in fig.axes: + gs = ax.get_gridspec() + if gs in layoutgrids: # also implies gs is not None. + lg = layoutgrids[gs] + for i in range(gs.nrows): + for j in range(gs.ncols): + bb = lg.get_inner_bbox(i, j) + if bb.width <= 0 or bb.height <= 0: + return False + return True + + +def compress_fixed_aspect(layoutgrids, fig): + gs = None + for ax in fig.axes: + if ax.get_subplotspec() is None: + continue + ax.apply_aspect() + sub = ax.get_subplotspec() + _gs = sub.get_gridspec() + if gs is None: + gs = _gs + extraw = np.zeros(gs.ncols) + extrah = np.zeros(gs.nrows) + elif _gs != gs: + raise ValueError('Cannot do compressed layout if axes are not' + 'all from the same gridspec') + orig = ax.get_position(original=True) + actual = ax.get_position(original=False) + dw = orig.width - actual.width + if dw > 0: + extraw[sub.colspan] = np.maximum(extraw[sub.colspan], dw) + dh = orig.height - actual.height + if dh > 0: + extrah[sub.rowspan] = np.maximum(extrah[sub.rowspan], dh) + + if gs is None: + raise ValueError('Cannot do compressed layout if no axes ' + 'are part of a gridspec.') + w = np.sum(extraw) / 2 + layoutgrids[fig].edit_margin_min('left', w) + layoutgrids[fig].edit_margin_min('right', w) + + h = np.sum(extrah) / 2 + layoutgrids[fig].edit_margin_min('top', h) + layoutgrids[fig].edit_margin_min('bottom', h) + return layoutgrids + + +def get_margin_from_padding(obj, *, w_pad=0, h_pad=0, + hspace=0, wspace=0): + + ss = obj._subplotspec + gs = ss.get_gridspec() + + if hasattr(gs, 'hspace'): + _hspace = (gs.hspace if gs.hspace is not None else hspace) + _wspace = (gs.wspace if gs.wspace is not None else wspace) + else: + _hspace = (gs._hspace if gs._hspace is not None else hspace) + _wspace = (gs._wspace if gs._wspace is not None else wspace) + + _wspace = _wspace / 2 + _hspace = _hspace / 2 + + nrows, ncols = gs.get_geometry() + # there are two margins for each direction. The "cb" + # margins are for pads and colorbars, the non-"cb" are + # for the axes decorations (labels etc). + margin = {'leftcb': w_pad, 'rightcb': w_pad, + 'bottomcb': h_pad, 'topcb': h_pad, + 'left': 0, 'right': 0, + 'top': 0, 'bottom': 0} + if _wspace / ncols > w_pad: + if ss.colspan.start > 0: + margin['leftcb'] = _wspace / ncols + if ss.colspan.stop < ncols: + margin['rightcb'] = _wspace / ncols + if _hspace / nrows > h_pad: + if ss.rowspan.stop < nrows: + margin['bottomcb'] = _hspace / nrows + if ss.rowspan.start > 0: + margin['topcb'] = _hspace / nrows + + return margin + + +def make_layout_margins(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0, + hspace=0, wspace=0): + """ + For each axes, make a margin between the *pos* layoutbox and the + *axes* layoutbox be a minimum size that can accommodate the + decorations on the axis. + + Then make room for colorbars. + + Parameters + ---------- + layoutgrids : dict + fig : `~matplotlib.figure.Figure` + `.Figure` instance to do the layout in. + renderer : `~matplotlib.backend_bases.RendererBase` subclass. + The renderer to use. + w_pad, h_pad : float, default: 0 + Width and height padding (in fraction of figure). + hspace, wspace : float, default: 0 + Width and height padding as fraction of figure size divided by + number of columns or rows. + """ + for sfig in fig.subfigs: # recursively make child panel margins + ss = sfig._subplotspec + gs = ss.get_gridspec() + + make_layout_margins(layoutgrids, sfig, renderer, + w_pad=w_pad, h_pad=h_pad, + hspace=hspace, wspace=wspace) + + margins = get_margin_from_padding(sfig, w_pad=0, h_pad=0, + hspace=hspace, wspace=wspace) + layoutgrids[gs].edit_outer_margin_mins(margins, ss) + + for ax in fig._localaxes: + if not ax.get_subplotspec() or not ax.get_in_layout(): + continue + + ss = ax.get_subplotspec() + gs = ss.get_gridspec() + + if gs not in layoutgrids: + return + + margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad, + hspace=hspace, wspace=wspace) + pos, bbox = get_pos_and_bbox(ax, renderer) + # the margin is the distance between the bounding box of the axes + # and its position (plus the padding from above) + margin['left'] += pos.x0 - bbox.x0 + margin['right'] += bbox.x1 - pos.x1 + # remember that rows are ordered from top: + margin['bottom'] += pos.y0 - bbox.y0 + margin['top'] += bbox.y1 - pos.y1 + + # make margin for colorbars. These margins go in the + # padding margin, versus the margin for axes decorators. + for cbax in ax._colorbars: + # note pad is a fraction of the parent width... + pad = colorbar_get_pad(layoutgrids, cbax) + # colorbars can be child of more than one subplot spec: + cbp_rspan, cbp_cspan = get_cb_parent_spans(cbax) + loc = cbax._colorbar_info['location'] + cbpos, cbbbox = get_pos_and_bbox(cbax, renderer) + if loc == 'right': + if cbp_cspan.stop == ss.colspan.stop: + # only increase if the colorbar is on the right edge + margin['rightcb'] += cbbbox.width + pad + elif loc == 'left': + if cbp_cspan.start == ss.colspan.start: + # only increase if the colorbar is on the left edge + margin['leftcb'] += cbbbox.width + pad + elif loc == 'top': + if cbp_rspan.start == ss.rowspan.start: + margin['topcb'] += cbbbox.height + pad + else: + if cbp_rspan.stop == ss.rowspan.stop: + margin['bottomcb'] += cbbbox.height + pad + # If the colorbars are wider than the parent box in the + # cross direction + if loc in ['top', 'bottom']: + if (cbp_cspan.start == ss.colspan.start and + cbbbox.x0 < bbox.x0): + margin['left'] += bbox.x0 - cbbbox.x0 + if (cbp_cspan.stop == ss.colspan.stop and + cbbbox.x1 > bbox.x1): + margin['right'] += cbbbox.x1 - bbox.x1 + # or taller: + if loc in ['left', 'right']: + if (cbp_rspan.stop == ss.rowspan.stop and + cbbbox.y0 < bbox.y0): + margin['bottom'] += bbox.y0 - cbbbox.y0 + if (cbp_rspan.start == ss.rowspan.start and + cbbbox.y1 > bbox.y1): + margin['top'] += cbbbox.y1 - bbox.y1 + # pass the new margins down to the layout grid for the solution... + layoutgrids[gs].edit_outer_margin_mins(margin, ss) + + # make margins for figure-level legends: + for leg in fig.legends: + inv_trans_fig = None + if leg._outside_loc and leg._bbox_to_anchor is None: + if inv_trans_fig is None: + inv_trans_fig = fig.transFigure.inverted().transform_bbox + bbox = inv_trans_fig(leg.get_tightbbox(renderer)) + w = bbox.width + 2 * w_pad + h = bbox.height + 2 * h_pad + legendloc = leg._outside_loc + if legendloc == 'lower': + layoutgrids[fig].edit_margin_min('bottom', h) + elif legendloc == 'upper': + layoutgrids[fig].edit_margin_min('top', h) + if legendloc == 'right': + layoutgrids[fig].edit_margin_min('right', w) + elif legendloc == 'left': + layoutgrids[fig].edit_margin_min('left', w) + + +def make_margin_suptitles(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0): + # Figure out how large the suptitle is and make the + # top level figure margin larger. + + inv_trans_fig = fig.transFigure.inverted().transform_bbox + # get the h_pad and w_pad as distances in the local subfigure coordinates: + padbox = mtransforms.Bbox([[0, 0], [w_pad, h_pad]]) + padbox = (fig.transFigure - + fig.transSubfigure).transform_bbox(padbox) + h_pad_local = padbox.height + w_pad_local = padbox.width + + for sfig in fig.subfigs: + make_margin_suptitles(layoutgrids, sfig, renderer, + w_pad=w_pad, h_pad=h_pad) + + if fig._suptitle is not None and fig._suptitle.get_in_layout(): + p = fig._suptitle.get_position() + if getattr(fig._suptitle, '_autopos', False): + fig._suptitle.set_position((p[0], 1 - h_pad_local)) + bbox = inv_trans_fig(fig._suptitle.get_tightbbox(renderer)) + layoutgrids[fig].edit_margin_min('top', bbox.height + 2 * h_pad) + + if fig._supxlabel is not None and fig._supxlabel.get_in_layout(): + p = fig._supxlabel.get_position() + if getattr(fig._supxlabel, '_autopos', False): + fig._supxlabel.set_position((p[0], h_pad_local)) + bbox = inv_trans_fig(fig._supxlabel.get_tightbbox(renderer)) + layoutgrids[fig].edit_margin_min('bottom', + bbox.height + 2 * h_pad) + + if fig._supylabel is not None and fig._supylabel.get_in_layout(): + p = fig._supylabel.get_position() + if getattr(fig._supylabel, '_autopos', False): + fig._supylabel.set_position((w_pad_local, p[1])) + bbox = inv_trans_fig(fig._supylabel.get_tightbbox(renderer)) + layoutgrids[fig].edit_margin_min('left', bbox.width + 2 * w_pad) + + +def match_submerged_margins(layoutgrids, fig): + """ + Make the margins that are submerged inside an Axes the same size. + + This allows axes that span two columns (or rows) that are offset + from one another to have the same size. + + This gives the proper layout for something like:: + fig = plt.figure(constrained_layout=True) + axs = fig.subplot_mosaic("AAAB\nCCDD") + + Without this routine, the axes D will be wider than C, because the + margin width between the two columns in C has no width by default, + whereas the margins between the two columns of D are set by the + width of the margin between A and B. However, obviously the user would + like C and D to be the same size, so we need to add constraints to these + "submerged" margins. + + This routine makes all the interior margins the same, and the spacing + between the three columns in A and the two column in C are all set to the + margins between the two columns of D. + + See test_constrained_layout::test_constrained_layout12 for an example. + """ + + for sfig in fig.subfigs: + match_submerged_margins(layoutgrids, sfig) + + axs = [a for a in fig.get_axes() + if a.get_subplotspec() is not None and a.get_in_layout()] + + for ax1 in axs: + ss1 = ax1.get_subplotspec() + if ss1.get_gridspec() not in layoutgrids: + axs.remove(ax1) + continue + lg1 = layoutgrids[ss1.get_gridspec()] + + # interior columns: + if len(ss1.colspan) > 1: + maxsubl = np.max( + lg1.margin_vals['left'][ss1.colspan[1:]] + + lg1.margin_vals['leftcb'][ss1.colspan[1:]] + ) + maxsubr = np.max( + lg1.margin_vals['right'][ss1.colspan[:-1]] + + lg1.margin_vals['rightcb'][ss1.colspan[:-1]] + ) + for ax2 in axs: + ss2 = ax2.get_subplotspec() + lg2 = layoutgrids[ss2.get_gridspec()] + if lg2 is not None and len(ss2.colspan) > 1: + maxsubl2 = np.max( + lg2.margin_vals['left'][ss2.colspan[1:]] + + lg2.margin_vals['leftcb'][ss2.colspan[1:]]) + if maxsubl2 > maxsubl: + maxsubl = maxsubl2 + maxsubr2 = np.max( + lg2.margin_vals['right'][ss2.colspan[:-1]] + + lg2.margin_vals['rightcb'][ss2.colspan[:-1]]) + if maxsubr2 > maxsubr: + maxsubr = maxsubr2 + for i in ss1.colspan[1:]: + lg1.edit_margin_min('left', maxsubl, cell=i) + for i in ss1.colspan[:-1]: + lg1.edit_margin_min('right', maxsubr, cell=i) + + # interior rows: + if len(ss1.rowspan) > 1: + maxsubt = np.max( + lg1.margin_vals['top'][ss1.rowspan[1:]] + + lg1.margin_vals['topcb'][ss1.rowspan[1:]] + ) + maxsubb = np.max( + lg1.margin_vals['bottom'][ss1.rowspan[:-1]] + + lg1.margin_vals['bottomcb'][ss1.rowspan[:-1]] + ) + + for ax2 in axs: + ss2 = ax2.get_subplotspec() + lg2 = layoutgrids[ss2.get_gridspec()] + if lg2 is not None: + if len(ss2.rowspan) > 1: + maxsubt = np.max([np.max( + lg2.margin_vals['top'][ss2.rowspan[1:]] + + lg2.margin_vals['topcb'][ss2.rowspan[1:]] + ), maxsubt]) + maxsubb = np.max([np.max( + lg2.margin_vals['bottom'][ss2.rowspan[:-1]] + + lg2.margin_vals['bottomcb'][ss2.rowspan[:-1]] + ), maxsubb]) + for i in ss1.rowspan[1:]: + lg1.edit_margin_min('top', maxsubt, cell=i) + for i in ss1.rowspan[:-1]: + lg1.edit_margin_min('bottom', maxsubb, cell=i) + + +def get_cb_parent_spans(cbax): + """ + Figure out which subplotspecs this colorbar belongs to. + + Parameters + ---------- + cbax : `~matplotlib.axes.Axes` + Axes for the colorbar. + """ + rowstart = np.inf + rowstop = -np.inf + colstart = np.inf + colstop = -np.inf + for parent in cbax._colorbar_info['parents']: + ss = parent.get_subplotspec() + rowstart = min(ss.rowspan.start, rowstart) + rowstop = max(ss.rowspan.stop, rowstop) + colstart = min(ss.colspan.start, colstart) + colstop = max(ss.colspan.stop, colstop) + + rowspan = range(rowstart, rowstop) + colspan = range(colstart, colstop) + return rowspan, colspan + + +def get_pos_and_bbox(ax, renderer): + """ + Get the position and the bbox for the axes. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + renderer : `~matplotlib.backend_bases.RendererBase` subclass. + + Returns + ------- + pos : `~matplotlib.transforms.Bbox` + Position in figure coordinates. + bbox : `~matplotlib.transforms.Bbox` + Tight bounding box in figure coordinates. + """ + fig = ax.figure + pos = ax.get_position(original=True) + # pos is in panel co-ords, but we need in figure for the layout + pos = pos.transformed(fig.transSubfigure - fig.transFigure) + tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer) + if tightbbox is None: + bbox = pos + else: + bbox = tightbbox.transformed(fig.transFigure.inverted()) + return pos, bbox + + +def reposition_axes(layoutgrids, fig, renderer, *, + w_pad=0, h_pad=0, hspace=0, wspace=0): + """ + Reposition all the axes based on the new inner bounding box. + """ + trans_fig_to_subfig = fig.transFigure - fig.transSubfigure + for sfig in fig.subfigs: + bbox = layoutgrids[sfig].get_outer_bbox() + sfig._redo_transform_rel_fig( + bbox=bbox.transformed(trans_fig_to_subfig)) + reposition_axes(layoutgrids, sfig, renderer, + w_pad=w_pad, h_pad=h_pad, + wspace=wspace, hspace=hspace) + + for ax in fig._localaxes: + if ax.get_subplotspec() is None or not ax.get_in_layout(): + continue + + # grid bbox is in Figure coordinates, but we specify in panel + # coordinates... + ss = ax.get_subplotspec() + gs = ss.get_gridspec() + if gs not in layoutgrids: + return + + bbox = layoutgrids[gs].get_inner_bbox(rows=ss.rowspan, + cols=ss.colspan) + + # transform from figure to panel for set_position: + newbbox = trans_fig_to_subfig.transform_bbox(bbox) + ax._set_position(newbbox) + + # move the colorbars: + # we need to keep track of oldw and oldh if there is more than + # one colorbar: + offset = {'left': 0, 'right': 0, 'bottom': 0, 'top': 0} + for nn, cbax in enumerate(ax._colorbars[::-1]): + if ax == cbax._colorbar_info['parents'][0]: + reposition_colorbar(layoutgrids, cbax, renderer, + offset=offset) + + +def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None): + """ + Place the colorbar in its new place. + + Parameters + ---------- + layoutgrids : dict + cbax : `~matplotlib.axes.Axes` + Axes for the colorbar. + renderer : `~matplotlib.backend_bases.RendererBase` subclass. + The renderer to use. + offset : array-like + Offset the colorbar needs to be pushed to in order to + account for multiple colorbars. + """ + + parents = cbax._colorbar_info['parents'] + gs = parents[0].get_gridspec() + fig = cbax.figure + trans_fig_to_subfig = fig.transFigure - fig.transSubfigure + + cb_rspans, cb_cspans = get_cb_parent_spans(cbax) + bboxparent = layoutgrids[gs].get_bbox_for_cb(rows=cb_rspans, + cols=cb_cspans) + pb = layoutgrids[gs].get_inner_bbox(rows=cb_rspans, cols=cb_cspans) + + location = cbax._colorbar_info['location'] + anchor = cbax._colorbar_info['anchor'] + fraction = cbax._colorbar_info['fraction'] + aspect = cbax._colorbar_info['aspect'] + shrink = cbax._colorbar_info['shrink'] + + cbpos, cbbbox = get_pos_and_bbox(cbax, renderer) + + # Colorbar gets put at extreme edge of outer bbox of the subplotspec + # It needs to be moved in by: 1) a pad 2) its "margin" 3) by + # any colorbars already added at this location: + cbpad = colorbar_get_pad(layoutgrids, cbax) + if location in ('left', 'right'): + # fraction and shrink are fractions of parent + pbcb = pb.shrunk(fraction, shrink).anchored(anchor, pb) + # The colorbar is at the left side of the parent. Need + # to translate to right (or left) + if location == 'right': + lmargin = cbpos.x0 - cbbbox.x0 + dx = bboxparent.x1 - pbcb.x0 + offset['right'] + dx += cbpad + lmargin + offset['right'] += cbbbox.width + cbpad + pbcb = pbcb.translated(dx, 0) + else: + lmargin = cbpos.x0 - cbbbox.x0 + dx = bboxparent.x0 - pbcb.x0 # edge of parent + dx += -cbbbox.width - cbpad + lmargin - offset['left'] + offset['left'] += cbbbox.width + cbpad + pbcb = pbcb.translated(dx, 0) + else: # horizontal axes: + pbcb = pb.shrunk(shrink, fraction).anchored(anchor, pb) + if location == 'top': + bmargin = cbpos.y0 - cbbbox.y0 + dy = bboxparent.y1 - pbcb.y0 + offset['top'] + dy += cbpad + bmargin + offset['top'] += cbbbox.height + cbpad + pbcb = pbcb.translated(0, dy) + else: + bmargin = cbpos.y0 - cbbbox.y0 + dy = bboxparent.y0 - pbcb.y0 + dy += -cbbbox.height - cbpad + bmargin - offset['bottom'] + offset['bottom'] += cbbbox.height + cbpad + pbcb = pbcb.translated(0, dy) + + pbcb = trans_fig_to_subfig.transform_bbox(pbcb) + cbax.set_transform(fig.transSubfigure) + cbax._set_position(pbcb) + cbax.set_anchor(anchor) + if location in ['bottom', 'top']: + aspect = 1 / aspect + cbax.set_box_aspect(aspect) + cbax.set_aspect('auto') + return offset + + +def reset_margins(layoutgrids, fig): + """ + Reset the margins in the layoutboxes of *fig*. + + Margins are usually set as a minimum, so if the figure gets smaller + the minimum needs to be zero in order for it to grow again. + """ + for sfig in fig.subfigs: + reset_margins(layoutgrids, sfig) + for ax in fig.axes: + if ax.get_in_layout(): + gs = ax.get_gridspec() + if gs in layoutgrids: # also implies gs is not None. + layoutgrids[gs].reset_margins() + layoutgrids[fig].reset_margins() + + +def colorbar_get_pad(layoutgrids, cax): + parents = cax._colorbar_info['parents'] + gs = parents[0].get_gridspec() + + cb_rspans, cb_cspans = get_cb_parent_spans(cax) + bboxouter = layoutgrids[gs].get_inner_bbox(rows=cb_rspans, cols=cb_cspans) + + if cax._colorbar_info['location'] in ['right', 'left']: + size = bboxouter.width + else: + size = bboxouter.height + + return cax._colorbar_info['pad'] * size diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.py new file mode 100644 index 00000000..ecd209ca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.py @@ -0,0 +1,97 @@ +import inspect + +from . import _api + + +class Substitution: + """ + A decorator that performs %-substitution on an object's docstring. + + This decorator should be robust even if ``obj.__doc__`` is None (for + example, if -OO was passed to the interpreter). + + Usage: construct a docstring.Substitution with a sequence or dictionary + suitable for performing substitution; then decorate a suitable function + with the constructed object, e.g.:: + + sub_author_name = Substitution(author='Jason') + + @sub_author_name + def some_function(x): + "%(author)s wrote this function" + + # note that some_function.__doc__ is now "Jason wrote this function" + + One can also use positional arguments:: + + sub_first_last_names = Substitution('Edgar Allen', 'Poe') + + @sub_first_last_names + def some_function(x): + "%s %s wrote the Raven" + """ + def __init__(self, *args, **kwargs): + if args and kwargs: + raise TypeError("Only positional or keyword args are allowed") + self.params = args or kwargs + + def __call__(self, func): + if func.__doc__: + func.__doc__ = inspect.cleandoc(func.__doc__) % self.params + return func + + def update(self, *args, **kwargs): + """ + Update ``self.params`` (which must be a dict) with the supplied args. + """ + self.params.update(*args, **kwargs) + + +class _ArtistKwdocLoader(dict): + def __missing__(self, key): + if not key.endswith(":kwdoc"): + raise KeyError(key) + name = key[:-len(":kwdoc")] + from matplotlib.artist import Artist, kwdoc + try: + cls, = [cls for cls in _api.recursive_subclasses(Artist) + if cls.__name__ == name] + except ValueError as e: + raise KeyError(key) from e + return self.setdefault(key, kwdoc(cls)) + + +class _ArtistPropertiesSubstitution(Substitution): + """ + A `.Substitution` with two additional features: + + - Substitutions of the form ``%(classname:kwdoc)s`` (ending with the + literal ":kwdoc" suffix) trigger lookup of an Artist subclass with the + given *classname*, and are substituted with the `.kwdoc` of that class. + - Decorating a class triggers substitution both on the class docstring and + on the class' ``__init__`` docstring (which is a commonly required + pattern for Artist subclasses). + """ + + def __init__(self): + self.params = _ArtistKwdocLoader() + + def __call__(self, obj): + super().__call__(obj) + if isinstance(obj, type) and obj.__init__ != object.__init__: + self(obj.__init__) + return obj + + +def copy(source): + """Copy a docstring from another source function (if present).""" + def do_copy(target): + if source.__doc__: + target.__doc__ = source.__doc__ + return target + return do_copy + + +# Create a decorator that will house the various docstring snippets reused +# throughout Matplotlib. +dedent_interpd = interpd = _ArtistPropertiesSubstitution() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.pyi new file mode 100644 index 00000000..0377dc5f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_docstring.pyi @@ -0,0 +1,29 @@ +from typing import Any, Callable, TypeVar, overload + + +_T = TypeVar('_T') + + +class Substitution: + @overload + def __init__(self, *args: str): ... + @overload + def __init__(self, **kwargs: str): ... + def __call__(self, func: _T) -> _T: ... + def update(self, *args, **kwargs): ... # type: ignore[no-untyped-def] + + +class _ArtistKwdocLoader(dict[str, str]): + def __missing__(self, key: str) -> str: ... + + +class _ArtistPropertiesSubstitution(Substitution): + def __init__(self) -> None: ... + def __call__(self, obj: _T) -> _T: ... + + +def copy(source: Any) -> Callable[[_T], _T]: ... + + +dedent_interpd: _ArtistPropertiesSubstitution +interpd: _ArtistPropertiesSubstitution diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.py new file mode 100644 index 00000000..c8c50f7c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.py @@ -0,0 +1,185 @@ +""" +Enums representing sets of strings that Matplotlib uses as input parameters. + +Matplotlib often uses simple data types like strings or tuples to define a +concept; e.g. the line capstyle can be specified as one of 'butt', 'round', +or 'projecting'. The classes in this module are used internally and serve to +document these concepts formally. + +As an end-user you will not use these classes directly, but only the values +they define. +""" + +from enum import Enum, auto +from matplotlib import _docstring + + +class _AutoStringNameEnum(Enum): + """Automate the ``name = 'name'`` part of making a (str, Enum).""" + + def _generate_next_value_(name, start, count, last_values): + return name + + def __hash__(self): + return str(self).__hash__() + + +class JoinStyle(str, _AutoStringNameEnum): + """ + Define how the connection between two line segments is drawn. + + For a visual impression of each *JoinStyle*, `view these docs online + `, or run `JoinStyle.demo`. + + Lines in Matplotlib are typically defined by a 1D `~.path.Path` and a + finite ``linewidth``, where the underlying 1D `~.path.Path` represents the + center of the stroked line. + + By default, `~.backend_bases.GraphicsContextBase` defines the boundaries of + a stroked line to simply be every point within some radius, + ``linewidth/2``, away from any point of the center line. However, this + results in corners appearing "rounded", which may not be the desired + behavior if you are drawing, for example, a polygon or pointed star. + + **Supported values:** + + .. rst-class:: value-list + + 'miter' + the "arrow-tip" style. Each boundary of the filled-in area will + extend in a straight line parallel to the tangent vector of the + centerline at the point it meets the corner, until they meet in a + sharp point. + 'round' + stokes every point within a radius of ``linewidth/2`` of the center + lines. + 'bevel' + the "squared-off" style. It can be thought of as a rounded corner + where the "circular" part of the corner has been cut off. + + .. note:: + + Very long miter tips are cut off (to form a *bevel*) after a + backend-dependent limit called the "miter limit", which specifies the + maximum allowed ratio of miter length to line width. For example, the + PDF backend uses the default value of 10 specified by the PDF standard, + while the SVG backend does not even specify the miter limit, resulting + in a default value of 4 per the SVG specification. Matplotlib does not + currently allow the user to adjust this parameter. + + A more detailed description of the effect of a miter limit can be found + in the `Mozilla Developer Docs + `_ + + .. plot:: + :alt: Demo of possible JoinStyle's + + from matplotlib._enums import JoinStyle + JoinStyle.demo() + + """ + + miter = auto() + round = auto() + bevel = auto() + + @staticmethod + def demo(): + """Demonstrate how each JoinStyle looks for various join angles.""" + import numpy as np + import matplotlib.pyplot as plt + + def plot_angle(ax, x, y, angle, style): + phi = np.radians(angle) + xx = [x + .5, x, x + .5*np.cos(phi)] + yy = [y, y, y + .5*np.sin(phi)] + ax.plot(xx, yy, lw=12, color='tab:blue', solid_joinstyle=style) + ax.plot(xx, yy, lw=1, color='black') + ax.plot(xx[1], yy[1], 'o', color='tab:red', markersize=3) + + fig, ax = plt.subplots(figsize=(5, 4), constrained_layout=True) + ax.set_title('Join style') + for x, style in enumerate(['miter', 'round', 'bevel']): + ax.text(x, 5, style) + for y, angle in enumerate([20, 45, 60, 90, 120]): + plot_angle(ax, x, y, angle, style) + if x == 0: + ax.text(-1.3, y, f'{angle} degrees') + ax.set_xlim(-1.5, 2.75) + ax.set_ylim(-.5, 5.5) + ax.set_axis_off() + fig.show() + + +JoinStyle.input_description = "{" \ + + ", ".join([f"'{js.name}'" for js in JoinStyle]) \ + + "}" + + +class CapStyle(str, _AutoStringNameEnum): + r""" + Define how the two endpoints (caps) of an unclosed line are drawn. + + How to draw the start and end points of lines that represent a closed curve + (i.e. that end in a `~.path.Path.CLOSEPOLY`) is controlled by the line's + `JoinStyle`. For all other lines, how the start and end points are drawn is + controlled by the *CapStyle*. + + For a visual impression of each *CapStyle*, `view these docs online + ` or run `CapStyle.demo`. + + By default, `~.backend_bases.GraphicsContextBase` draws a stroked line as + squared off at its endpoints. + + **Supported values:** + + .. rst-class:: value-list + + 'butt' + the line is squared off at its endpoint. + 'projecting' + the line is squared off as in *butt*, but the filled in area + extends beyond the endpoint a distance of ``linewidth/2``. + 'round' + like *butt*, but a semicircular cap is added to the end of the + line, of radius ``linewidth/2``. + + .. plot:: + :alt: Demo of possible CapStyle's + + from matplotlib._enums import CapStyle + CapStyle.demo() + + """ + butt = auto() + projecting = auto() + round = auto() + + @staticmethod + def demo(): + """Demonstrate how each CapStyle looks for a thick line segment.""" + import matplotlib.pyplot as plt + + fig = plt.figure(figsize=(4, 1.2)) + ax = fig.add_axes([0, 0, 1, 0.8]) + ax.set_title('Cap style') + + for x, style in enumerate(['butt', 'round', 'projecting']): + ax.text(x+0.25, 0.85, style, ha='center') + xx = [x, x+0.5] + yy = [0, 0] + ax.plot(xx, yy, lw=12, color='tab:blue', solid_capstyle=style) + ax.plot(xx, yy, lw=1, color='black') + ax.plot(xx, yy, 'o', color='tab:red', markersize=3) + + ax.set_ylim(-.5, 1.5) + ax.set_axis_off() + fig.show() + + +CapStyle.input_description = "{" \ + + ", ".join([f"'{cs.name}'" for cs in CapStyle]) \ + + "}" + +_docstring.interpd.update({'JoinStyle': JoinStyle.input_description, + 'CapStyle': CapStyle.input_description}) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.pyi new file mode 100644 index 00000000..351088b3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_enums.pyi @@ -0,0 +1,18 @@ +from enum import Enum + +class _AutoStringNameEnum(Enum): + def __hash__(self) -> int: ... + +class JoinStyle(str, _AutoStringNameEnum): + miter: str + round: str + bevel: str + @staticmethod + def demo() -> None: ... + +class CapStyle(str, _AutoStringNameEnum): + butt: str + projecting: str + round: str + @staticmethod + def demo() -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_fontconfig_pattern.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_fontconfig_pattern.py new file mode 100644 index 00000000..d3933b9f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_fontconfig_pattern.py @@ -0,0 +1,120 @@ +""" +A module for parsing and generating `fontconfig patterns`_. + +.. _fontconfig patterns: + https://www.freedesktop.org/software/fontconfig/fontconfig-user.html +""" + +# This class logically belongs in `matplotlib.font_manager`, but placing it +# there would have created cyclical dependency problems, because it also needs +# to be available from `matplotlib.rcsetup` (for parsing matplotlibrc files). + +from functools import lru_cache, partial +import re + +from pyparsing import ( + Group, Optional, ParseException, Regex, StringEnd, Suppress, ZeroOrMore) + +from matplotlib import _api + + +_family_punc = r'\\\-:,' +_family_unescape = partial(re.compile(r'\\(?=[%s])' % _family_punc).sub, '') +_family_escape = partial(re.compile(r'(?=[%s])' % _family_punc).sub, r'\\') +_value_punc = r'\\=_:,' +_value_unescape = partial(re.compile(r'\\(?=[%s])' % _value_punc).sub, '') +_value_escape = partial(re.compile(r'(?=[%s])' % _value_punc).sub, r'\\') + + +_CONSTANTS = { + 'thin': ('weight', 'light'), + 'extralight': ('weight', 'light'), + 'ultralight': ('weight', 'light'), + 'light': ('weight', 'light'), + 'book': ('weight', 'book'), + 'regular': ('weight', 'regular'), + 'normal': ('weight', 'normal'), + 'medium': ('weight', 'medium'), + 'demibold': ('weight', 'demibold'), + 'semibold': ('weight', 'semibold'), + 'bold': ('weight', 'bold'), + 'extrabold': ('weight', 'extra bold'), + 'black': ('weight', 'black'), + 'heavy': ('weight', 'heavy'), + 'roman': ('slant', 'normal'), + 'italic': ('slant', 'italic'), + 'oblique': ('slant', 'oblique'), + 'ultracondensed': ('width', 'ultra-condensed'), + 'extracondensed': ('width', 'extra-condensed'), + 'condensed': ('width', 'condensed'), + 'semicondensed': ('width', 'semi-condensed'), + 'expanded': ('width', 'expanded'), + 'extraexpanded': ('width', 'extra-expanded'), + 'ultraexpanded': ('width', 'ultra-expanded'), +} + + +@lru_cache # The parser instance is a singleton. +def _make_fontconfig_parser(): + def comma_separated(elem): + return elem + ZeroOrMore(Suppress(",") + elem) + + family = Regex(fr"([^{_family_punc}]|(\\[{_family_punc}]))*") + size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)") + name = Regex(r"[a-z]+") + value = Regex(fr"([^{_value_punc}]|(\\[{_value_punc}]))*") + # replace trailing `| name` by oneOf(_CONSTANTS) in mpl 3.9. + prop = Group((name + Suppress("=") + comma_separated(value)) | name) + return ( + Optional(comma_separated(family)("families")) + + Optional("-" + comma_separated(size)("sizes")) + + ZeroOrMore(":" + prop("properties*")) + + StringEnd() + ) + + +# `parse_fontconfig_pattern` is a bottleneck during the tests because it is +# repeatedly called when the rcParams are reset (to validate the default +# fonts). In practice, the cache size doesn't grow beyond a few dozen entries +# during the test suite. +@lru_cache +def parse_fontconfig_pattern(pattern): + """ + Parse a fontconfig *pattern* into a dict that can initialize a + `.font_manager.FontProperties` object. + """ + parser = _make_fontconfig_parser() + try: + parse = parser.parseString(pattern) + except ParseException as err: + # explain becomes a plain method on pyparsing 3 (err.explain(0)). + raise ValueError("\n" + ParseException.explain(err, 0)) from None + parser.resetCache() + props = {} + if "families" in parse: + props["family"] = [*map(_family_unescape, parse["families"])] + if "sizes" in parse: + props["size"] = [*parse["sizes"]] + for prop in parse.get("properties", []): + if len(prop) == 1: + if prop[0] not in _CONSTANTS: + _api.warn_deprecated( + "3.7", message=f"Support for unknown constants " + f"({prop[0]!r}) is deprecated since %(since)s and " + f"will be removed %(removal)s.") + continue + prop = _CONSTANTS[prop[0]] + k, *v = prop + props.setdefault(k, []).extend(map(_value_unescape, v)) + return props + + +def generate_fontconfig_pattern(d): + """Convert a `.FontProperties` to a fontconfig pattern string.""" + kvs = [(k, getattr(d, f"get_{k}")()) + for k in ["style", "variant", "weight", "stretch", "file", "size"]] + # Families is given first without a leading keyword. Other entries (which + # are necessarily scalar) are given as key=value, skipping Nones. + return (",".join(_family_escape(f) for f in d.get_family()) + + "".join(f":{k}={_value_escape(str(v))}" + for k, v in kvs if v is not None)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_image.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_image.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..574f9f81c3c698bf6b972829c52fd657b8312212 GIT binary patch literal 165192 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

NI1_vzBwH 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 "{id(val)}" ' + f'[label="{key}", fontsize=10];\n') + recurse(val, buf) + + buf = StringIO() + buf.write('digraph G {\n') + recurse(transform, buf) + buf.write('}\n') + subprocess.run( + ['dot', '-T', Path(dest).suffix[1:], '-o', dest], + input=buf.getvalue().encode('utf-8'), check=True) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_layoutgrid.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_layoutgrid.py new file mode 100644 index 00000000..8bef9283 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_layoutgrid.py @@ -0,0 +1,547 @@ +""" +A layoutgrid is a nrows by ncols set of boxes, meant to be used by +`._constrained_layout`, each box is analogous to a subplotspec element of +a gridspec. + +Each box is defined by left[ncols], right[ncols], bottom[nrows] and top[nrows], +and by two editable margins for each side. The main margin gets its value +set by the size of ticklabels, titles, etc on each axes that is in the figure. +The outer margin is the padding around the axes, and space for any +colorbars. + +The "inner" widths and heights of these boxes are then constrained to be the +same (relative the values of `width_ratios[ncols]` and `height_ratios[nrows]`). + +The layoutgrid is then constrained to be contained within a parent layoutgrid, +its column(s) and row(s) specified when it is created. +""" + +import itertools +import kiwisolver as kiwi +import logging +import numpy as np + +import matplotlib as mpl +import matplotlib.patches as mpatches +from matplotlib.transforms import Bbox + +_log = logging.getLogger(__name__) + + +class LayoutGrid: + """ + Analogous to a gridspec, and contained in another LayoutGrid. + """ + + def __init__(self, parent=None, parent_pos=(0, 0), + parent_inner=False, name='', ncols=1, nrows=1, + h_pad=None, w_pad=None, width_ratios=None, + height_ratios=None): + Variable = kiwi.Variable + self.parent_pos = parent_pos + self.parent_inner = parent_inner + self.name = name + seq_id() + if isinstance(parent, LayoutGrid): + self.name = f'{parent.name}.{self.name}' + self.nrows = nrows + self.ncols = ncols + self.height_ratios = np.atleast_1d(height_ratios) + if height_ratios is None: + self.height_ratios = np.ones(nrows) + self.width_ratios = np.atleast_1d(width_ratios) + if width_ratios is None: + self.width_ratios = np.ones(ncols) + + sn = self.name + '_' + if not isinstance(parent, LayoutGrid): + # parent can be a rect if not a LayoutGrid + # allows specifying a rectangle to contain the layout. + self.solver = kiwi.Solver() + else: + parent.add_child(self, *parent_pos) + self.solver = parent.solver + # keep track of artist associated w/ this layout. Can be none + self.artists = np.empty((nrows, ncols), dtype=object) + self.children = np.empty((nrows, ncols), dtype=object) + + self.margins = {} + self.margin_vals = {} + # all the boxes in each column share the same left/right margins: + for todo in ['left', 'right', 'leftcb', 'rightcb']: + # track the value so we can change only if a margin is larger + # than the current value + self.margin_vals[todo] = np.zeros(ncols) + + sol = self.solver + + self.lefts = [Variable(f'{sn}lefts[{i}]') for i in range(ncols)] + self.rights = [Variable(f'{sn}rights[{i}]') for i in range(ncols)] + for todo in ['left', 'right', 'leftcb', 'rightcb']: + self.margins[todo] = [Variable(f'{sn}margins[{todo}][{i}]') + for i in range(ncols)] + for i in range(ncols): + sol.addEditVariable(self.margins[todo][i], 'strong') + + for todo in ['bottom', 'top', 'bottomcb', 'topcb']: + self.margins[todo] = np.empty((nrows), dtype=object) + self.margin_vals[todo] = np.zeros(nrows) + + self.bottoms = [Variable(f'{sn}bottoms[{i}]') for i in range(nrows)] + self.tops = [Variable(f'{sn}tops[{i}]') for i in range(nrows)] + for todo in ['bottom', 'top', 'bottomcb', 'topcb']: + self.margins[todo] = [Variable(f'{sn}margins[{todo}][{i}]') + for i in range(nrows)] + for i in range(nrows): + sol.addEditVariable(self.margins[todo][i], 'strong') + + # set these margins to zero by default. They will be edited as + # children are filled. + self.reset_margins() + self.add_constraints(parent) + + self.h_pad = h_pad + self.w_pad = w_pad + + def __repr__(self): + str = f'LayoutBox: {self.name:25s} {self.nrows}x{self.ncols},\n' + for i in range(self.nrows): + for j in range(self.ncols): + str += f'{i}, {j}: '\ + f'L{self.lefts[j].value():1.3f}, ' \ + f'B{self.bottoms[i].value():1.3f}, ' \ + f'R{self.rights[j].value():1.3f}, ' \ + f'T{self.tops[i].value():1.3f}, ' \ + f'ML{self.margins["left"][j].value():1.3f}, ' \ + f'MR{self.margins["right"][j].value():1.3f}, ' \ + f'MB{self.margins["bottom"][i].value():1.3f}, ' \ + f'MT{self.margins["top"][i].value():1.3f}, \n' + return str + + def reset_margins(self): + """ + Reset all the margins to zero. Must do this after changing + figure size, for instance, because the relative size of the + axes labels etc changes. + """ + for todo in ['left', 'right', 'bottom', 'top', + 'leftcb', 'rightcb', 'bottomcb', 'topcb']: + self.edit_margins(todo, 0.0) + + def add_constraints(self, parent): + # define self-consistent constraints + self.hard_constraints() + # define relationship with parent layoutgrid: + self.parent_constraints(parent) + # define relative widths of the grid cells to each other + # and stack horizontally and vertically. + self.grid_constraints() + + def hard_constraints(self): + """ + These are the redundant constraints, plus ones that make the + rest of the code easier. + """ + for i in range(self.ncols): + hc = [self.rights[i] >= self.lefts[i], + (self.rights[i] - self.margins['right'][i] - + self.margins['rightcb'][i] >= + self.lefts[i] - self.margins['left'][i] - + self.margins['leftcb'][i]) + ] + for c in hc: + self.solver.addConstraint(c | 'required') + + for i in range(self.nrows): + hc = [self.tops[i] >= self.bottoms[i], + (self.tops[i] - self.margins['top'][i] - + self.margins['topcb'][i] >= + self.bottoms[i] - self.margins['bottom'][i] - + self.margins['bottomcb'][i]) + ] + for c in hc: + self.solver.addConstraint(c | 'required') + + def add_child(self, child, i=0, j=0): + # np.ix_ returns the cross product of i and j indices + self.children[np.ix_(np.atleast_1d(i), np.atleast_1d(j))] = child + + def parent_constraints(self, parent): + # constraints that are due to the parent... + # i.e. the first column's left is equal to the + # parent's left, the last column right equal to the + # parent's right... + if not isinstance(parent, LayoutGrid): + # specify a rectangle in figure coordinates + hc = [self.lefts[0] == parent[0], + self.rights[-1] == parent[0] + parent[2], + # top and bottom reversed order... + self.tops[0] == parent[1] + parent[3], + self.bottoms[-1] == parent[1]] + else: + rows, cols = self.parent_pos + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + left = parent.lefts[cols[0]] + right = parent.rights[cols[-1]] + top = parent.tops[rows[0]] + bottom = parent.bottoms[rows[-1]] + if self.parent_inner: + # the layout grid is contained inside the inner + # grid of the parent. + left += parent.margins['left'][cols[0]] + left += parent.margins['leftcb'][cols[0]] + right -= parent.margins['right'][cols[-1]] + right -= parent.margins['rightcb'][cols[-1]] + top -= parent.margins['top'][rows[0]] + top -= parent.margins['topcb'][rows[0]] + bottom += parent.margins['bottom'][rows[-1]] + bottom += parent.margins['bottomcb'][rows[-1]] + hc = [self.lefts[0] == left, + self.rights[-1] == right, + # from top to bottom + self.tops[0] == top, + self.bottoms[-1] == bottom] + for c in hc: + self.solver.addConstraint(c | 'required') + + def grid_constraints(self): + # constrain the ratio of the inner part of the grids + # to be the same (relative to width_ratios) + + # constrain widths: + w = (self.rights[0] - self.margins['right'][0] - + self.margins['rightcb'][0]) + w = (w - self.lefts[0] - self.margins['left'][0] - + self.margins['leftcb'][0]) + w0 = w / self.width_ratios[0] + # from left to right + for i in range(1, self.ncols): + w = (self.rights[i] - self.margins['right'][i] - + self.margins['rightcb'][i]) + w = (w - self.lefts[i] - self.margins['left'][i] - + self.margins['leftcb'][i]) + c = (w == w0 * self.width_ratios[i]) + self.solver.addConstraint(c | 'strong') + # constrain the grid cells to be directly next to each other. + c = (self.rights[i - 1] == self.lefts[i]) + self.solver.addConstraint(c | 'strong') + + # constrain heights: + h = self.tops[0] - self.margins['top'][0] - self.margins['topcb'][0] + h = (h - self.bottoms[0] - self.margins['bottom'][0] - + self.margins['bottomcb'][0]) + h0 = h / self.height_ratios[0] + # from top to bottom: + for i in range(1, self.nrows): + h = (self.tops[i] - self.margins['top'][i] - + self.margins['topcb'][i]) + h = (h - self.bottoms[i] - self.margins['bottom'][i] - + self.margins['bottomcb'][i]) + c = (h == h0 * self.height_ratios[i]) + self.solver.addConstraint(c | 'strong') + # constrain the grid cells to be directly above each other. + c = (self.bottoms[i - 1] == self.tops[i]) + self.solver.addConstraint(c | 'strong') + + # Margin editing: The margins are variable and meant to + # contain things of a fixed size like axes labels, tick labels, titles + # etc + def edit_margin(self, todo, size, cell): + """ + Change the size of the margin for one cell. + + Parameters + ---------- + todo : string (one of 'left', 'right', 'bottom', 'top') + margin to alter. + + size : float + Size of the margin. If it is larger than the existing minimum it + updates the margin size. Fraction of figure size. + + cell : int + Cell column or row to edit. + """ + self.solver.suggestValue(self.margins[todo][cell], size) + self.margin_vals[todo][cell] = size + + def edit_margin_min(self, todo, size, cell=0): + """ + Change the minimum size of the margin for one cell. + + Parameters + ---------- + todo : string (one of 'left', 'right', 'bottom', 'top') + margin to alter. + + size : float + Minimum size of the margin . If it is larger than the + existing minimum it updates the margin size. Fraction of + figure size. + + cell : int + Cell column or row to edit. + """ + + if size > self.margin_vals[todo][cell]: + self.edit_margin(todo, size, cell) + + def edit_margins(self, todo, size): + """ + Change the size of all the margin of all the cells in the layout grid. + + Parameters + ---------- + todo : string (one of 'left', 'right', 'bottom', 'top') + margin to alter. + + size : float + Size to set the margins. Fraction of figure size. + """ + + for i in range(len(self.margin_vals[todo])): + self.edit_margin(todo, size, i) + + def edit_all_margins_min(self, todo, size): + """ + Change the minimum size of all the margin of all + the cells in the layout grid. + + Parameters + ---------- + todo : {'left', 'right', 'bottom', 'top'} + The margin to alter. + + size : float + Minimum size of the margin. If it is larger than the + existing minimum it updates the margin size. Fraction of + figure size. + """ + + for i in range(len(self.margin_vals[todo])): + self.edit_margin_min(todo, size, i) + + def edit_outer_margin_mins(self, margin, ss): + """ + Edit all four margin minimums in one statement. + + Parameters + ---------- + margin : dict + size of margins in a dict with keys 'left', 'right', 'bottom', + 'top' + + ss : SubplotSpec + defines the subplotspec these margins should be applied to + """ + + self.edit_margin_min('left', margin['left'], ss.colspan.start) + self.edit_margin_min('leftcb', margin['leftcb'], ss.colspan.start) + self.edit_margin_min('right', margin['right'], ss.colspan.stop - 1) + self.edit_margin_min('rightcb', margin['rightcb'], ss.colspan.stop - 1) + # rows are from the top down: + self.edit_margin_min('top', margin['top'], ss.rowspan.start) + self.edit_margin_min('topcb', margin['topcb'], ss.rowspan.start) + self.edit_margin_min('bottom', margin['bottom'], ss.rowspan.stop - 1) + self.edit_margin_min('bottomcb', margin['bottomcb'], + ss.rowspan.stop - 1) + + def get_margins(self, todo, col): + """Return the margin at this position""" + return self.margin_vals[todo][col] + + def get_outer_bbox(self, rows=0, cols=0): + """ + Return the outer bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + self.lefts[cols[0]].value(), + self.bottoms[rows[-1]].value(), + self.rights[cols[-1]].value(), + self.tops[rows[0]].value()) + return bbox + + def get_inner_bbox(self, rows=0, cols=0): + """ + Return the inner bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.lefts[cols[0]].value() + + self.margins['left'][cols[0]].value() + + self.margins['leftcb'][cols[0]].value()), + (self.bottoms[rows[-1]].value() + + self.margins['bottom'][rows[-1]].value() + + self.margins['bottomcb'][rows[-1]].value()), + (self.rights[cols[-1]].value() - + self.margins['right'][cols[-1]].value() - + self.margins['rightcb'][cols[-1]].value()), + (self.tops[rows[0]].value() - + self.margins['top'][rows[0]].value() - + self.margins['topcb'][rows[0]].value()) + ) + return bbox + + def get_bbox_for_cb(self, rows=0, cols=0): + """ + Return the bounding box that includes the + decorations but, *not* the colorbar... + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.lefts[cols[0]].value() + + self.margins['leftcb'][cols[0]].value()), + (self.bottoms[rows[-1]].value() + + self.margins['bottomcb'][rows[-1]].value()), + (self.rights[cols[-1]].value() - + self.margins['rightcb'][cols[-1]].value()), + (self.tops[rows[0]].value() - + self.margins['topcb'][rows[0]].value()) + ) + return bbox + + def get_left_margin_bbox(self, rows=0, cols=0): + """ + Return the left margin bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.lefts[cols[0]].value() + + self.margins['leftcb'][cols[0]].value()), + (self.bottoms[rows[-1]].value()), + (self.lefts[cols[0]].value() + + self.margins['leftcb'][cols[0]].value() + + self.margins['left'][cols[0]].value()), + (self.tops[rows[0]].value())) + return bbox + + def get_bottom_margin_bbox(self, rows=0, cols=0): + """ + Return the left margin bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.lefts[cols[0]].value()), + (self.bottoms[rows[-1]].value() + + self.margins['bottomcb'][rows[-1]].value()), + (self.rights[cols[-1]].value()), + (self.bottoms[rows[-1]].value() + + self.margins['bottom'][rows[-1]].value() + + self.margins['bottomcb'][rows[-1]].value() + )) + return bbox + + def get_right_margin_bbox(self, rows=0, cols=0): + """ + Return the left margin bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.rights[cols[-1]].value() - + self.margins['right'][cols[-1]].value() - + self.margins['rightcb'][cols[-1]].value()), + (self.bottoms[rows[-1]].value()), + (self.rights[cols[-1]].value() - + self.margins['rightcb'][cols[-1]].value()), + (self.tops[rows[0]].value())) + return bbox + + def get_top_margin_bbox(self, rows=0, cols=0): + """ + Return the left margin bounding box of the subplot specs + given by rows and cols. rows and cols can be spans. + """ + rows = np.atleast_1d(rows) + cols = np.atleast_1d(cols) + + bbox = Bbox.from_extents( + (self.lefts[cols[0]].value()), + (self.tops[rows[0]].value() - + self.margins['topcb'][rows[0]].value()), + (self.rights[cols[-1]].value()), + (self.tops[rows[0]].value() - + self.margins['topcb'][rows[0]].value() - + self.margins['top'][rows[0]].value())) + return bbox + + def update_variables(self): + """ + Update the variables for the solver attached to this layoutgrid. + """ + self.solver.updateVariables() + +_layoutboxobjnum = itertools.count() + + +def seq_id(): + """Generate a short sequential id for layoutbox objects.""" + return '%06d' % next(_layoutboxobjnum) + + +def plot_children(fig, lg=None, level=0): + """Simple plotting to show where boxes are.""" + if lg is None: + _layoutgrids = fig.get_layout_engine().execute(fig) + lg = _layoutgrids[fig] + colors = mpl.rcParams["axes.prop_cycle"].by_key()["color"] + col = colors[level] + for i in range(lg.nrows): + for j in range(lg.ncols): + bb = lg.get_outer_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bb.p0, bb.width, bb.height, linewidth=1, + edgecolor='0.7', facecolor='0.7', + alpha=0.2, transform=fig.transFigure, + zorder=-3)) + bbi = lg.get_inner_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=2, + edgecolor=col, facecolor='none', + transform=fig.transFigure, zorder=-2)) + + bbi = lg.get_left_margin_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0, + edgecolor='none', alpha=0.2, + facecolor=[0.5, 0.7, 0.5], + transform=fig.transFigure, zorder=-2)) + bbi = lg.get_right_margin_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0, + edgecolor='none', alpha=0.2, + facecolor=[0.7, 0.5, 0.5], + transform=fig.transFigure, zorder=-2)) + bbi = lg.get_bottom_margin_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0, + edgecolor='none', alpha=0.2, + facecolor=[0.5, 0.5, 0.7], + transform=fig.transFigure, zorder=-2)) + bbi = lg.get_top_margin_bbox(rows=i, cols=j) + fig.add_artist( + mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0, + edgecolor='none', alpha=0.2, + facecolor=[0.7, 0.2, 0.7], + transform=fig.transFigure, zorder=-2)) + for ch in lg.children.flat: + if ch is not None: + plot_children(fig, ch, level=level+1) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext.py new file mode 100644 index 00000000..b23cb671 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext.py @@ -0,0 +1,2851 @@ +""" +Implementation details for :mod:`.mathtext`. +""" + +from __future__ import annotations + +import abc +import copy +import enum +import functools +import logging +import os +import re +import types +import unicodedata +import string +import typing as T +from typing import NamedTuple + +import numpy as np +from pyparsing import ( + Empty, Forward, Literal, NotAny, oneOf, OneOrMore, Optional, + ParseBaseException, ParseException, ParseExpression, ParseFatalException, + ParserElement, ParseResults, QuotedString, Regex, StringEnd, ZeroOrMore, + pyparsing_common, Group) + +import matplotlib as mpl +from . import cbook +from ._mathtext_data import ( + latex_to_bakoma, stix_glyph_fixes, stix_virtual_fonts, tex2uni) +from .font_manager import FontProperties, findfont, get_font +from .ft2font import FT2Font, FT2Image, KERNING_DEFAULT + +from packaging.version import parse as parse_version +from pyparsing import __version__ as pyparsing_version +if parse_version(pyparsing_version).major < 3: + from pyparsing import nestedExpr as nested_expr +else: + from pyparsing import nested_expr + +if T.TYPE_CHECKING: + from collections.abc import Iterable + from .ft2font import Glyph + +ParserElement.enablePackrat() +_log = logging.getLogger("matplotlib.mathtext") + + +############################################################################## +# FONTS + + +def get_unicode_index(symbol: str) -> int: # Publicly exported. + r""" + Return the integer index (from the Unicode table) of *symbol*. + + Parameters + ---------- + symbol : str + A single (Unicode) character, a TeX command (e.g. r'\pi') or a Type1 + symbol name (e.g. 'phi'). + """ + try: # This will succeed if symbol is a single Unicode char + return ord(symbol) + except TypeError: + pass + try: # Is symbol a TeX symbol (i.e. \alpha) + return tex2uni[symbol.strip("\\")] + except KeyError as err: + raise ValueError( + f"{symbol!r} is not a valid Unicode character or TeX/Type1 symbol" + ) from err + + +class VectorParse(NamedTuple): + """ + The namedtuple type returned by ``MathTextParser("path").parse(...)``. + + Attributes + ---------- + width, height, depth : float + The global metrics. + glyphs : list + The glyphs including their positions. + rect : list + The list of rectangles. + """ + width: float + height: float + depth: float + glyphs: list[tuple[FT2Font, float, int, float, float]] + rects: list[tuple[float, float, float, float]] + +VectorParse.__module__ = "matplotlib.mathtext" + + +class RasterParse(NamedTuple): + """ + The namedtuple type returned by ``MathTextParser("agg").parse(...)``. + + Attributes + ---------- + ox, oy : float + The offsets are always zero. + width, height, depth : float + The global metrics. + image : FT2Image + A raster image. + """ + ox: float + oy: float + width: float + height: float + depth: float + image: FT2Image + +RasterParse.__module__ = "matplotlib.mathtext" + + +class Output: + r""" + Result of `ship`\ping a box: lists of positioned glyphs and rectangles. + + This class is not exposed to end users, but converted to a `VectorParse` or + a `RasterParse` by `.MathTextParser.parse`. + """ + + def __init__(self, box: Box): + self.box = box + self.glyphs: list[tuple[float, float, FontInfo]] = [] # (ox, oy, info) + self.rects: list[tuple[float, float, float, float]] = [] # (x1, y1, x2, y2) + + def to_vector(self) -> VectorParse: + w, h, d = map( + np.ceil, [self.box.width, self.box.height, self.box.depth]) + gs = [(info.font, info.fontsize, info.num, ox, h - oy + info.offset) + for ox, oy, info in self.glyphs] + rs = [(x1, h - y2, x2 - x1, y2 - y1) + for x1, y1, x2, y2 in self.rects] + return VectorParse(w, h + d, d, gs, rs) + + def to_raster(self, *, antialiased: bool) -> RasterParse: + # Metrics y's and mathtext y's are oriented in opposite directions, + # hence the switch between ymin and ymax. + xmin = min([*[ox + info.metrics.xmin for ox, oy, info in self.glyphs], + *[x1 for x1, y1, x2, y2 in self.rects], 0]) - 1 + ymin = min([*[oy - info.metrics.ymax for ox, oy, info in self.glyphs], + *[y1 for x1, y1, x2, y2 in self.rects], 0]) - 1 + xmax = max([*[ox + info.metrics.xmax for ox, oy, info in self.glyphs], + *[x2 for x1, y1, x2, y2 in self.rects], 0]) + 1 + ymax = max([*[oy - info.metrics.ymin for ox, oy, info in self.glyphs], + *[y2 for x1, y1, x2, y2 in self.rects], 0]) + 1 + w = xmax - xmin + h = ymax - ymin - self.box.depth + d = ymax - ymin - self.box.height + image = FT2Image(np.ceil(w), np.ceil(h + max(d, 0))) + + # Ideally, we could just use self.glyphs and self.rects here, shifting + # their coordinates by (-xmin, -ymin), but this yields slightly + # different results due to floating point slop; shipping twice is the + # old approach and keeps baseline images backcompat. + shifted = ship(self.box, (-xmin, -ymin)) + + for ox, oy, info in shifted.glyphs: + info.font.draw_glyph_to_bitmap( + image, ox, oy - info.metrics.iceberg, info.glyph, + antialiased=antialiased) + for x1, y1, x2, y2 in shifted.rects: + height = max(int(y2 - y1) - 1, 0) + if height == 0: + center = (y2 + y1) / 2 + y = int(center - (height + 1) / 2) + else: + y = int(y1) + image.draw_rect_filled(int(x1), y, np.ceil(x2), y + height) + return RasterParse(0, 0, w, h + d, d, image) + + +class FontMetrics(NamedTuple): + """ + Metrics of a font. + + Attributes + ---------- + advance : float + The advance distance (in points) of the glyph. + height : float + The height of the glyph in points. + width : float + The width of the glyph in points. + xmin, xmax, ymin, ymax : float + The ink rectangle of the glyph. + iceberg : float + The distance from the baseline to the top of the glyph. (This corresponds to + TeX's definition of "height".) + slanted : bool + Whether the glyph should be considered as "slanted" (currently used for kerning + sub/superscripts). + """ + advance: float + height: float + width: float + xmin: float + xmax: float + ymin: float + ymax: float + iceberg: float + slanted: bool + + +class FontInfo(NamedTuple): + font: FT2Font + fontsize: float + postscript_name: str + metrics: FontMetrics + num: int + glyph: Glyph + offset: float + + +class Fonts(abc.ABC): + """ + An abstract base class for a system of fonts to use for mathtext. + + The class must be able to take symbol keys and font file names and + return the character metrics. It also delegates to a backend class + to do the actual drawing. + """ + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + """ + Parameters + ---------- + default_font_prop : `~.font_manager.FontProperties` + The default non-math font, or the base font for Unicode (generic) + font rendering. + load_glyph_flags : int + Flags passed to the glyph loader (e.g. ``FT_Load_Glyph`` and + ``FT_Load_Char`` for FreeType-based fonts). + """ + self.default_font_prop = default_font_prop + self.load_glyph_flags = load_glyph_flags + + def get_kern(self, font1: str, fontclass1: str, sym1: str, fontsize1: float, + font2: str, fontclass2: str, sym2: str, fontsize2: float, + dpi: float) -> float: + """ + Get the kerning distance for font between *sym1* and *sym2*. + + See `~.Fonts.get_metrics` for a detailed description of the parameters. + """ + return 0. + + def _get_font(self, font: str) -> FT2Font: + raise NotImplementedError + + def _get_info(self, font: str, font_class: str, sym: str, fontsize: float, + dpi: float) -> FontInfo: + raise NotImplementedError + + def get_metrics(self, font: str, font_class: str, sym: str, fontsize: float, + dpi: float) -> FontMetrics: + r""" + Parameters + ---------- + font : str + One of the TeX font names: "tt", "it", "rm", "cal", "sf", "bf", + "default", "regular", "bb", "frak", "scr". "default" and "regular" + are synonyms and use the non-math font. + font_class : str + One of the TeX font names (as for *font*), but **not** "bb", + "frak", or "scr". This is used to combine two font classes. The + only supported combination currently is ``get_metrics("frak", "bf", + ...)``. + sym : str + A symbol in raw TeX form, e.g., "1", "x", or "\sigma". + fontsize : float + Font size in points. + dpi : float + Rendering dots-per-inch. + + Returns + ------- + FontMetrics + """ + info = self._get_info(font, font_class, sym, fontsize, dpi) + return info.metrics + + def render_glyph(self, output: Output, ox: float, oy: float, font: str, + font_class: str, sym: str, fontsize: float, dpi: float) -> None: + """ + At position (*ox*, *oy*), draw the glyph specified by the remaining + parameters (see `get_metrics` for their detailed description). + """ + info = self._get_info(font, font_class, sym, fontsize, dpi) + output.glyphs.append((ox, oy, info)) + + def render_rect_filled(self, output: Output, + x1: float, y1: float, x2: float, y2: float) -> None: + """ + Draw a filled rectangle from (*x1*, *y1*) to (*x2*, *y2*). + """ + output.rects.append((x1, y1, x2, y2)) + + def get_xheight(self, font: str, fontsize: float, dpi: float) -> float: + """ + Get the xheight for the given *font* and *fontsize*. + """ + raise NotImplementedError() + + def get_underline_thickness(self, font: str, fontsize: float, dpi: float) -> float: + """ + Get the line thickness that matches the given font. Used as a + base unit for drawing lines such as in a fraction or radical. + """ + raise NotImplementedError() + + def get_sized_alternatives_for_symbol(self, fontname: str, + sym: str) -> list[tuple[str, str]]: + """ + Override if your font provides multiple sizes of the same + symbol. Should return a list of symbols matching *sym* in + various sizes. The expression renderer will select the most + appropriate size for a given situation from this list. + """ + return [(fontname, sym)] + + +class TruetypeFonts(Fonts, metaclass=abc.ABCMeta): + """ + A generic base class for all font setups that use Truetype fonts + (through FT2Font). + """ + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + super().__init__(default_font_prop, load_glyph_flags) + # Per-instance cache. + self._get_info = functools.cache(self._get_info) # type: ignore[method-assign] + self._fonts = {} + self.fontmap: dict[str | int, str] = {} + + filename = findfont(self.default_font_prop) + default_font = get_font(filename) + self._fonts['default'] = default_font + self._fonts['regular'] = default_font + + def _get_font(self, font: str | int) -> FT2Font: + if font in self.fontmap: + basename = self.fontmap[font] + else: + # NOTE: An int is only passed by subclasses which have placed int keys into + # `self.fontmap`, so we must cast this to confirm it to typing. + basename = T.cast(str, font) + cached_font = self._fonts.get(basename) + if cached_font is None and os.path.exists(basename): + cached_font = get_font(basename) + self._fonts[basename] = cached_font + self._fonts[cached_font.postscript_name] = cached_font + self._fonts[cached_font.postscript_name.lower()] = cached_font + return T.cast(FT2Font, cached_font) # FIXME: Not sure this is guaranteed. + + def _get_offset(self, font: FT2Font, glyph: Glyph, fontsize: float, + dpi: float) -> float: + if font.postscript_name == 'Cmex10': + return (glyph.height / 64 / 2) + (fontsize/3 * dpi/72) + return 0. + + def _get_glyph(self, fontname: str, font_class: str, + sym: str) -> tuple[FT2Font, int, bool]: + raise NotImplementedError + + # The return value of _get_info is cached per-instance. + def _get_info(self, fontname: str, font_class: str, sym: str, fontsize: float, + dpi: float) -> FontInfo: + font, num, slanted = self._get_glyph(fontname, font_class, sym) + font.set_size(fontsize, dpi) + glyph = font.load_char(num, flags=self.load_glyph_flags) + + xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox] + offset = self._get_offset(font, glyph, fontsize, dpi) + metrics = FontMetrics( + advance = glyph.linearHoriAdvance/65536.0, + height = glyph.height/64.0, + width = glyph.width/64.0, + xmin = xmin, + xmax = xmax, + ymin = ymin+offset, + ymax = ymax+offset, + # iceberg is the equivalent of TeX's "height" + iceberg = glyph.horiBearingY/64.0 + offset, + slanted = slanted + ) + + return FontInfo( + font = font, + fontsize = fontsize, + postscript_name = font.postscript_name, + metrics = metrics, + num = num, + glyph = glyph, + offset = offset + ) + + def get_xheight(self, fontname: str, fontsize: float, dpi: float) -> float: + font = self._get_font(fontname) + font.set_size(fontsize, dpi) + pclt = font.get_sfnt_table('pclt') + if pclt is None: + # Some fonts don't store the xHeight, so we do a poor man's xHeight + metrics = self.get_metrics( + fontname, mpl.rcParams['mathtext.default'], 'x', fontsize, dpi) + return metrics.iceberg + xHeight = (pclt['xHeight'] / 64.0) * (fontsize / 12.0) * (dpi / 100.0) + return xHeight + + def get_underline_thickness(self, font: str, fontsize: float, dpi: float) -> float: + # This function used to grab underline thickness from the font + # metrics, but that information is just too un-reliable, so it + # is now hardcoded. + return ((0.75 / 12.0) * fontsize * dpi) / 72.0 + + def get_kern(self, font1: str, fontclass1: str, sym1: str, fontsize1: float, + font2: str, fontclass2: str, sym2: str, fontsize2: float, + dpi: float) -> float: + if font1 == font2 and fontsize1 == fontsize2: + info1 = self._get_info(font1, fontclass1, sym1, fontsize1, dpi) + info2 = self._get_info(font2, fontclass2, sym2, fontsize2, dpi) + font = info1.font + return font.get_kerning(info1.num, info2.num, KERNING_DEFAULT) / 64 + return super().get_kern(font1, fontclass1, sym1, fontsize1, + font2, fontclass2, sym2, fontsize2, dpi) + + +class BakomaFonts(TruetypeFonts): + """ + Use the Bakoma TrueType fonts for rendering. + + Symbols are strewn about a number of font files, each of which has + its own proprietary 8-bit encoding. + """ + _fontmap = { + 'cal': 'cmsy10', + 'rm': 'cmr10', + 'tt': 'cmtt10', + 'it': 'cmmi10', + 'bf': 'cmb10', + 'sf': 'cmss10', + 'ex': 'cmex10', + } + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + self._stix_fallback = StixFonts(default_font_prop, load_glyph_flags) + + super().__init__(default_font_prop, load_glyph_flags) + for key, val in self._fontmap.items(): + fullpath = findfont(val) + self.fontmap[key] = fullpath + self.fontmap[val] = fullpath + + _slanted_symbols = set(r"\int \oint".split()) + + def _get_glyph(self, fontname: str, font_class: str, + sym: str) -> tuple[FT2Font, int, bool]: + font = None + if fontname in self.fontmap and sym in latex_to_bakoma: + basename, num = latex_to_bakoma[sym] + slanted = (basename == "cmmi10") or sym in self._slanted_symbols + font = self._get_font(basename) + elif len(sym) == 1: + slanted = (fontname == "it") + font = self._get_font(fontname) + if font is not None: + num = ord(sym) + if font is not None and font.get_char_index(num) != 0: + return font, num, slanted + else: + return self._stix_fallback._get_glyph(fontname, font_class, sym) + + # The Bakoma fonts contain many pre-sized alternatives for the + # delimiters. The AutoSizedChar class will use these alternatives + # and select the best (closest sized) glyph. + _size_alternatives = { + '(': [('rm', '('), ('ex', '\xa1'), ('ex', '\xb3'), + ('ex', '\xb5'), ('ex', '\xc3')], + ')': [('rm', ')'), ('ex', '\xa2'), ('ex', '\xb4'), + ('ex', '\xb6'), ('ex', '\x21')], + '{': [('cal', '{'), ('ex', '\xa9'), ('ex', '\x6e'), + ('ex', '\xbd'), ('ex', '\x28')], + '}': [('cal', '}'), ('ex', '\xaa'), ('ex', '\x6f'), + ('ex', '\xbe'), ('ex', '\x29')], + # The fourth size of '[' is mysteriously missing from the BaKoMa + # font, so I've omitted it for both '[' and ']' + '[': [('rm', '['), ('ex', '\xa3'), ('ex', '\x68'), + ('ex', '\x22')], + ']': [('rm', ']'), ('ex', '\xa4'), ('ex', '\x69'), + ('ex', '\x23')], + r'\lfloor': [('ex', '\xa5'), ('ex', '\x6a'), + ('ex', '\xb9'), ('ex', '\x24')], + r'\rfloor': [('ex', '\xa6'), ('ex', '\x6b'), + ('ex', '\xba'), ('ex', '\x25')], + r'\lceil': [('ex', '\xa7'), ('ex', '\x6c'), + ('ex', '\xbb'), ('ex', '\x26')], + r'\rceil': [('ex', '\xa8'), ('ex', '\x6d'), + ('ex', '\xbc'), ('ex', '\x27')], + r'\langle': [('ex', '\xad'), ('ex', '\x44'), + ('ex', '\xbf'), ('ex', '\x2a')], + r'\rangle': [('ex', '\xae'), ('ex', '\x45'), + ('ex', '\xc0'), ('ex', '\x2b')], + r'\__sqrt__': [('ex', '\x70'), ('ex', '\x71'), + ('ex', '\x72'), ('ex', '\x73')], + r'\backslash': [('ex', '\xb2'), ('ex', '\x2f'), + ('ex', '\xc2'), ('ex', '\x2d')], + r'/': [('rm', '/'), ('ex', '\xb1'), ('ex', '\x2e'), + ('ex', '\xcb'), ('ex', '\x2c')], + r'\widehat': [('rm', '\x5e'), ('ex', '\x62'), ('ex', '\x63'), + ('ex', '\x64')], + r'\widetilde': [('rm', '\x7e'), ('ex', '\x65'), ('ex', '\x66'), + ('ex', '\x67')], + r'<': [('cal', 'h'), ('ex', 'D')], + r'>': [('cal', 'i'), ('ex', 'E')] + } + + for alias, target in [(r'\leftparen', '('), + (r'\rightparent', ')'), + (r'\leftbrace', '{'), + (r'\rightbrace', '}'), + (r'\leftbracket', '['), + (r'\rightbracket', ']'), + (r'\{', '{'), + (r'\}', '}'), + (r'\[', '['), + (r'\]', ']')]: + _size_alternatives[alias] = _size_alternatives[target] + + def get_sized_alternatives_for_symbol(self, fontname: str, + sym: str) -> list[tuple[str, str]]: + return self._size_alternatives.get(sym, [(fontname, sym)]) + + +class UnicodeFonts(TruetypeFonts): + """ + An abstract base class for handling Unicode fonts. + + While some reasonably complete Unicode fonts (such as DejaVu) may + work in some situations, the only Unicode font I'm aware of with a + complete set of math symbols is STIX. + + This class will "fallback" on the Bakoma fonts when a required + symbol cannot be found in the font. + """ + + # Some glyphs are not present in the `cmr10` font, and must be brought in + # from `cmsy10`. Map the Unicode indices of those glyphs to the indices at + # which they are found in `cmsy10`. + _cmr10_substitutions = { + 0x00D7: 0x00A3, # Multiplication sign. + 0x2212: 0x00A1, # Minus sign. + } + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + # This must come first so the backend's owner is set correctly + fallback_rc = mpl.rcParams['mathtext.fallback'] + font_cls: type[TruetypeFonts] | None = { + 'stix': StixFonts, + 'stixsans': StixSansFonts, + 'cm': BakomaFonts + }.get(fallback_rc) + self._fallback_font = (font_cls(default_font_prop, load_glyph_flags) + if font_cls else None) + + super().__init__(default_font_prop, load_glyph_flags) + for texfont in "cal rm tt it bf sf bfit".split(): + prop = mpl.rcParams['mathtext.' + texfont] + font = findfont(prop) + self.fontmap[texfont] = font + prop = FontProperties('cmex10') + font = findfont(prop) + self.fontmap['ex'] = font + + # include STIX sized alternatives for glyphs if fallback is STIX + if isinstance(self._fallback_font, StixFonts): + stixsizedaltfonts = { + 0: 'STIXGeneral', + 1: 'STIXSizeOneSym', + 2: 'STIXSizeTwoSym', + 3: 'STIXSizeThreeSym', + 4: 'STIXSizeFourSym', + 5: 'STIXSizeFiveSym'} + + for size, name in stixsizedaltfonts.items(): + fullpath = findfont(name) + self.fontmap[size] = fullpath + self.fontmap[name] = fullpath + + _slanted_symbols = set(r"\int \oint".split()) + + def _map_virtual_font(self, fontname: str, font_class: str, + uniindex: int) -> tuple[str, int]: + return fontname, uniindex + + def _get_glyph(self, fontname: str, font_class: str, + sym: str) -> tuple[FT2Font, int, bool]: + try: + uniindex = get_unicode_index(sym) + found_symbol = True + except ValueError: + uniindex = ord('?') + found_symbol = False + _log.warning("No TeX to Unicode mapping for %a.", sym) + + fontname, uniindex = self._map_virtual_font( + fontname, font_class, uniindex) + + new_fontname = fontname + + # Only characters in the "Letter" class should be italicized in 'it' + # mode. Greek capital letters should be Roman. + if found_symbol: + if fontname == 'it' and uniindex < 0x10000: + char = chr(uniindex) + if (unicodedata.category(char)[0] != "L" + or unicodedata.name(char).startswith("GREEK CAPITAL")): + new_fontname = 'rm' + + slanted = (new_fontname == 'it') or sym in self._slanted_symbols + found_symbol = False + font = self._get_font(new_fontname) + if font is not None: + if (uniindex in self._cmr10_substitutions + and font.family_name == "cmr10"): + font = get_font( + cbook._get_data_path("fonts/ttf/cmsy10.ttf")) + uniindex = self._cmr10_substitutions[uniindex] + glyphindex = font.get_char_index(uniindex) + if glyphindex != 0: + found_symbol = True + + if not found_symbol: + if self._fallback_font: + if (fontname in ('it', 'regular') + and isinstance(self._fallback_font, StixFonts)): + fontname = 'rm' + + g = self._fallback_font._get_glyph(fontname, font_class, sym) + family = g[0].family_name + if family in list(BakomaFonts._fontmap.values()): + family = "Computer Modern" + _log.info("Substituting symbol %s from %s", sym, family) + return g + + else: + if (fontname in ('it', 'regular') + and isinstance(self, StixFonts)): + return self._get_glyph('rm', font_class, sym) + _log.warning("Font %r does not have a glyph for %a [U+%x], " + "substituting with a dummy symbol.", + new_fontname, sym, uniindex) + font = self._get_font('rm') + uniindex = 0xA4 # currency char, for lack of anything better + slanted = False + + return font, uniindex, slanted + + def get_sized_alternatives_for_symbol(self, fontname: str, + sym: str) -> list[tuple[str, str]]: + if self._fallback_font: + return self._fallback_font.get_sized_alternatives_for_symbol( + fontname, sym) + return [(fontname, sym)] + + +class DejaVuFonts(UnicodeFonts, metaclass=abc.ABCMeta): + _fontmap: dict[str | int, str] = {} + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + # This must come first so the backend's owner is set correctly + if isinstance(self, DejaVuSerifFonts): + self._fallback_font = StixFonts(default_font_prop, load_glyph_flags) + else: + self._fallback_font = StixSansFonts(default_font_prop, load_glyph_flags) + self.bakoma = BakomaFonts(default_font_prop, load_glyph_flags) + TruetypeFonts.__init__(self, default_font_prop, load_glyph_flags) + # Include Stix sized alternatives for glyphs + self._fontmap.update({ + 1: 'STIXSizeOneSym', + 2: 'STIXSizeTwoSym', + 3: 'STIXSizeThreeSym', + 4: 'STIXSizeFourSym', + 5: 'STIXSizeFiveSym', + }) + for key, name in self._fontmap.items(): + fullpath = findfont(name) + self.fontmap[key] = fullpath + self.fontmap[name] = fullpath + + def _get_glyph(self, fontname: str, font_class: str, + sym: str) -> tuple[FT2Font, int, bool]: + # Override prime symbol to use Bakoma. + if sym == r'\prime': + return self.bakoma._get_glyph(fontname, font_class, sym) + else: + # check whether the glyph is available in the display font + uniindex = get_unicode_index(sym) + font = self._get_font('ex') + if font is not None: + glyphindex = font.get_char_index(uniindex) + if glyphindex != 0: + return super()._get_glyph('ex', font_class, sym) + # otherwise return regular glyph + return super()._get_glyph(fontname, font_class, sym) + + +class DejaVuSerifFonts(DejaVuFonts): + """ + A font handling class for the DejaVu Serif fonts + + If a glyph is not found it will fallback to Stix Serif + """ + _fontmap = { + 'rm': 'DejaVu Serif', + 'it': 'DejaVu Serif:italic', + 'bf': 'DejaVu Serif:weight=bold', + 'bfit': 'DejaVu Serif:italic:bold', + 'sf': 'DejaVu Sans', + 'tt': 'DejaVu Sans Mono', + 'ex': 'DejaVu Serif Display', + 0: 'DejaVu Serif', + } + + +class DejaVuSansFonts(DejaVuFonts): + """ + A font handling class for the DejaVu Sans fonts + + If a glyph is not found it will fallback to Stix Sans + """ + _fontmap = { + 'rm': 'DejaVu Sans', + 'it': 'DejaVu Sans:italic', + 'bf': 'DejaVu Sans:weight=bold', + 'bfit': 'DejaVu Sans:italic:bold', + 'sf': 'DejaVu Sans', + 'tt': 'DejaVu Sans Mono', + 'ex': 'DejaVu Sans Display', + 0: 'DejaVu Sans', + } + + +class StixFonts(UnicodeFonts): + """ + A font handling class for the STIX fonts. + + In addition to what UnicodeFonts provides, this class: + + - supports "virtual fonts" which are complete alpha numeric + character sets with different font styles at special Unicode + code points, such as "Blackboard". + + - handles sized alternative characters for the STIXSizeX fonts. + """ + _fontmap: dict[str | int, str] = { + 'rm': 'STIXGeneral', + 'it': 'STIXGeneral:italic', + 'bf': 'STIXGeneral:weight=bold', + 'bfit': 'STIXGeneral:italic:bold', + 'nonunirm': 'STIXNonUnicode', + 'nonuniit': 'STIXNonUnicode:italic', + 'nonunibf': 'STIXNonUnicode:weight=bold', + 0: 'STIXGeneral', + 1: 'STIXSizeOneSym', + 2: 'STIXSizeTwoSym', + 3: 'STIXSizeThreeSym', + 4: 'STIXSizeFourSym', + 5: 'STIXSizeFiveSym', + } + _fallback_font = None + _sans = False + + def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int): + TruetypeFonts.__init__(self, default_font_prop, load_glyph_flags) + for key, name in self._fontmap.items(): + fullpath = findfont(name) + self.fontmap[key] = fullpath + self.fontmap[name] = fullpath + + def _map_virtual_font(self, fontname: str, font_class: str, + uniindex: int) -> tuple[str, int]: + # Handle these "fonts" that are actually embedded in + # other fonts. + font_mapping = stix_virtual_fonts.get(fontname) + if (self._sans and font_mapping is None + and fontname not in ('regular', 'default')): + font_mapping = stix_virtual_fonts['sf'] + doing_sans_conversion = True + else: + doing_sans_conversion = False + + if isinstance(font_mapping, dict): + try: + mapping = font_mapping[font_class] + except KeyError: + mapping = font_mapping['rm'] + elif isinstance(font_mapping, list): + mapping = font_mapping + else: + mapping = None + + if mapping is not None: + # Binary search for the source glyph + lo = 0 + hi = len(mapping) + while lo < hi: + mid = (lo+hi)//2 + range = mapping[mid] + if uniindex < range[0]: + hi = mid + elif uniindex <= range[1]: + break + else: + lo = mid + 1 + + if range[0] <= uniindex <= range[1]: + uniindex = uniindex - range[0] + range[3] + fontname = range[2] + elif not doing_sans_conversion: + # This will generate a dummy character + uniindex = 0x1 + fontname = mpl.rcParams['mathtext.default'] + + # Fix some incorrect glyphs. + if fontname in ('rm', 'it'): + uniindex = stix_glyph_fixes.get(uniindex, uniindex) + + # Handle private use area glyphs + if fontname in ('it', 'rm', 'bf', 'bfit') and 0xe000 <= uniindex <= 0xf8ff: + fontname = 'nonuni' + fontname + + return fontname, uniindex + + @functools.cache + def get_sized_alternatives_for_symbol( # type: ignore[override] + self, + fontname: str, + sym: str) -> list[tuple[str, str]] | list[tuple[int, str]]: + fixes = { + '\\{': '{', '\\}': '}', '\\[': '[', '\\]': ']', + '<': '\N{MATHEMATICAL LEFT ANGLE BRACKET}', + '>': '\N{MATHEMATICAL RIGHT ANGLE BRACKET}', + } + sym = fixes.get(sym, sym) + try: + uniindex = get_unicode_index(sym) + except ValueError: + return [(fontname, sym)] + alternatives = [(i, chr(uniindex)) for i in range(6) + if self._get_font(i).get_char_index(uniindex) != 0] + # The largest size of the radical symbol in STIX has incorrect + # metrics that cause it to be disconnected from the stem. + if sym == r'\__sqrt__': + alternatives = alternatives[:-1] + return alternatives + + +class StixSansFonts(StixFonts): + """ + A font handling class for the STIX fonts (that uses sans-serif + characters by default). + """ + _sans = True + + +############################################################################## +# TeX-LIKE BOX MODEL + +# The following is based directly on the document 'woven' from the +# TeX82 source code. This information is also available in printed +# form: +# +# Knuth, Donald E.. 1986. Computers and Typesetting, Volume B: +# TeX: The Program. Addison-Wesley Professional. +# +# The most relevant "chapters" are: +# Data structures for boxes and their friends +# Shipping pages out (ship()) +# Packaging (hpack() and vpack()) +# Data structures for math mode +# Subroutines for math mode +# Typesetting math formulas +# +# Many of the docstrings below refer to a numbered "node" in that +# book, e.g., node123 +# +# Note that (as TeX) y increases downward, unlike many other parts of +# matplotlib. + +# How much text shrinks when going to the next-smallest level. +SHRINK_FACTOR = 0.7 +# The number of different sizes of chars to use, beyond which they will not +# get any smaller +NUM_SIZE_LEVELS = 6 + + +class FontConstantsBase: + """ + A set of constants that controls how certain things, such as sub- + and superscripts are laid out. These are all metrics that can't + be reliably retrieved from the font metrics in the font itself. + """ + # Percentage of x-height of additional horiz. space after sub/superscripts + script_space: T.ClassVar[float] = 0.05 + + # Percentage of x-height that sub/superscripts drop below the baseline + subdrop: T.ClassVar[float] = 0.4 + + # Percentage of x-height that superscripts are raised from the baseline + sup1: T.ClassVar[float] = 0.7 + + # Percentage of x-height that subscripts drop below the baseline + sub1: T.ClassVar[float] = 0.3 + + # Percentage of x-height that subscripts drop below the baseline when a + # superscript is present + sub2: T.ClassVar[float] = 0.5 + + # Percentage of x-height that sub/superscripts are offset relative to the + # nucleus edge for non-slanted nuclei + delta: T.ClassVar[float] = 0.025 + + # Additional percentage of last character height above 2/3 of the + # x-height that superscripts are offset relative to the subscript + # for slanted nuclei + delta_slanted: T.ClassVar[float] = 0.2 + + # Percentage of x-height that superscripts and subscripts are offset for + # integrals + delta_integral: T.ClassVar[float] = 0.1 + + +class ComputerModernFontConstants(FontConstantsBase): + script_space = 0.075 + subdrop = 0.2 + sup1 = 0.45 + sub1 = 0.2 + sub2 = 0.3 + delta = 0.075 + delta_slanted = 0.3 + delta_integral = 0.3 + + +class STIXFontConstants(FontConstantsBase): + script_space = 0.1 + sup1 = 0.8 + sub2 = 0.6 + delta = 0.05 + delta_slanted = 0.3 + delta_integral = 0.3 + + +class STIXSansFontConstants(FontConstantsBase): + script_space = 0.05 + sup1 = 0.8 + delta_slanted = 0.6 + delta_integral = 0.3 + + +class DejaVuSerifFontConstants(FontConstantsBase): + pass + + +class DejaVuSansFontConstants(FontConstantsBase): + pass + + +# Maps font family names to the FontConstantBase subclass to use +_font_constant_mapping = { + 'DejaVu Sans': DejaVuSansFontConstants, + 'DejaVu Sans Mono': DejaVuSansFontConstants, + 'DejaVu Serif': DejaVuSerifFontConstants, + 'cmb10': ComputerModernFontConstants, + 'cmex10': ComputerModernFontConstants, + 'cmmi10': ComputerModernFontConstants, + 'cmr10': ComputerModernFontConstants, + 'cmss10': ComputerModernFontConstants, + 'cmsy10': ComputerModernFontConstants, + 'cmtt10': ComputerModernFontConstants, + 'STIXGeneral': STIXFontConstants, + 'STIXNonUnicode': STIXFontConstants, + 'STIXSizeFiveSym': STIXFontConstants, + 'STIXSizeFourSym': STIXFontConstants, + 'STIXSizeThreeSym': STIXFontConstants, + 'STIXSizeTwoSym': STIXFontConstants, + 'STIXSizeOneSym': STIXFontConstants, + # Map the fonts we used to ship, just for good measure + 'Bitstream Vera Sans': DejaVuSansFontConstants, + 'Bitstream Vera': DejaVuSansFontConstants, + } + + +def _get_font_constant_set(state: ParserState) -> type[FontConstantsBase]: + constants = _font_constant_mapping.get( + state.fontset._get_font(state.font).family_name, FontConstantsBase) + # STIX sans isn't really its own fonts, just different code points + # in the STIX fonts, so we have to detect this one separately. + if (constants is STIXFontConstants and + isinstance(state.fontset, StixSansFonts)): + return STIXSansFontConstants + return constants + + +class Node: + """A node in the TeX box model.""" + + def __init__(self) -> None: + self.size = 0 + + def __repr__(self) -> str: + return type(self).__name__ + + def get_kerning(self, next: Node | None) -> float: + return 0.0 + + def shrink(self) -> None: + """ + Shrinks one level smaller. There are only three levels of + sizes, after which things will no longer get smaller. + """ + self.size += 1 + + def render(self, output: Output, x: float, y: float) -> None: + """Render this node.""" + + +class Box(Node): + """A node with a physical location.""" + + def __init__(self, width: float, height: float, depth: float) -> None: + super().__init__() + self.width = width + self.height = height + self.depth = depth + + def shrink(self) -> None: + super().shrink() + if self.size < NUM_SIZE_LEVELS: + self.width *= SHRINK_FACTOR + self.height *= SHRINK_FACTOR + self.depth *= SHRINK_FACTOR + + def render(self, output: Output, # type: ignore[override] + x1: float, y1: float, x2: float, y2: float) -> None: + pass + + +class Vbox(Box): + """A box with only height (zero width).""" + + def __init__(self, height: float, depth: float): + super().__init__(0., height, depth) + + +class Hbox(Box): + """A box with only width (zero height and depth).""" + + def __init__(self, width: float): + super().__init__(width, 0., 0.) + + +class Char(Node): + """ + A single character. + + Unlike TeX, the font information and metrics are stored with each `Char` + to make it easier to lookup the font metrics when needed. Note that TeX + boxes have a width, height, and depth, unlike Type1 and TrueType which use + a full bounding box and an advance in the x-direction. The metrics must + be converted to the TeX model, and the advance (if different from width) + must be converted into a `Kern` node when the `Char` is added to its parent + `Hlist`. + """ + + def __init__(self, c: str, state: ParserState): + super().__init__() + self.c = c + self.fontset = state.fontset + self.font = state.font + self.font_class = state.font_class + self.fontsize = state.fontsize + self.dpi = state.dpi + # The real width, height and depth will be set during the + # pack phase, after we know the real fontsize + self._update_metrics() + + def __repr__(self) -> str: + return '`%s`' % self.c + + def _update_metrics(self) -> None: + metrics = self._metrics = self.fontset.get_metrics( + self.font, self.font_class, self.c, self.fontsize, self.dpi) + if self.c == ' ': + self.width = metrics.advance + else: + self.width = metrics.width + self.height = metrics.iceberg + self.depth = -(metrics.iceberg - metrics.height) + + def is_slanted(self) -> bool: + return self._metrics.slanted + + def get_kerning(self, next: Node | None) -> float: + """ + Return the amount of kerning between this and the given character. + + This method is called when characters are strung together into `Hlist` + to create `Kern` nodes. + """ + advance = self._metrics.advance - self.width + kern = 0. + if isinstance(next, Char): + kern = self.fontset.get_kern( + self.font, self.font_class, self.c, self.fontsize, + next.font, next.font_class, next.c, next.fontsize, + self.dpi) + return advance + kern + + def render(self, output: Output, x: float, y: float) -> None: + self.fontset.render_glyph( + output, x, y, + self.font, self.font_class, self.c, self.fontsize, self.dpi) + + def shrink(self) -> None: + super().shrink() + if self.size < NUM_SIZE_LEVELS: + self.fontsize *= SHRINK_FACTOR + self.width *= SHRINK_FACTOR + self.height *= SHRINK_FACTOR + self.depth *= SHRINK_FACTOR + + +class Accent(Char): + """ + The font metrics need to be dealt with differently for accents, + since they are already offset correctly from the baseline in + TrueType fonts. + """ + def _update_metrics(self) -> None: + metrics = self._metrics = self.fontset.get_metrics( + self.font, self.font_class, self.c, self.fontsize, self.dpi) + self.width = metrics.xmax - metrics.xmin + self.height = metrics.ymax - metrics.ymin + self.depth = 0 + + def shrink(self) -> None: + super().shrink() + self._update_metrics() + + def render(self, output: Output, x: float, y: float) -> None: + self.fontset.render_glyph( + output, x - self._metrics.xmin, y + self._metrics.ymin, + self.font, self.font_class, self.c, self.fontsize, self.dpi) + + +class List(Box): + """A list of nodes (either horizontal or vertical).""" + + def __init__(self, elements: T.Sequence[Node]): + super().__init__(0., 0., 0.) + self.shift_amount = 0. # An arbitrary offset + self.children = [*elements] # The child nodes of this list + # The following parameters are set in the vpack and hpack functions + self.glue_set = 0. # The glue setting of this list + self.glue_sign = 0 # 0: normal, -1: shrinking, 1: stretching + self.glue_order = 0 # The order of infinity (0 - 3) for the glue + + def __repr__(self) -> str: + return '{}[{}]'.format( + super().__repr__(), + self.width, self.height, + self.depth, self.shift_amount, + ', '.join([repr(x) for x in self.children])) + + def _set_glue(self, x: float, sign: int, totals: list[float], + error_type: str) -> None: + self.glue_order = o = next( + # Highest order of glue used by the members of this list. + (i for i in range(len(totals))[::-1] if totals[i] != 0), 0) + self.glue_sign = sign + if totals[o] != 0.: + self.glue_set = x / totals[o] + else: + self.glue_sign = 0 + self.glue_ratio = 0. + if o == 0: + if len(self.children): + _log.warning("%s %s: %r", + error_type, type(self).__name__, self) + + def shrink(self) -> None: + for child in self.children: + child.shrink() + super().shrink() + if self.size < NUM_SIZE_LEVELS: + self.shift_amount *= SHRINK_FACTOR + self.glue_set *= SHRINK_FACTOR + + +class Hlist(List): + """A horizontal list of boxes.""" + + def __init__(self, elements: T.Sequence[Node], w: float = 0.0, + m: T.Literal['additional', 'exactly'] = 'additional', + do_kern: bool = True): + super().__init__(elements) + if do_kern: + self.kern() + self.hpack(w=w, m=m) + + def kern(self) -> None: + """ + Insert `Kern` nodes between `Char` nodes to set kerning. + + The `Char` nodes themselves determine the amount of kerning they need + (in `~Char.get_kerning`), and this function just creates the correct + linked list. + """ + new_children = [] + num_children = len(self.children) + if num_children: + for i in range(num_children): + elem = self.children[i] + if i < num_children - 1: + next = self.children[i + 1] + else: + next = None + + new_children.append(elem) + kerning_distance = elem.get_kerning(next) + if kerning_distance != 0.: + kern = Kern(kerning_distance) + new_children.append(kern) + self.children = new_children + + def hpack(self, w: float = 0.0, + m: T.Literal['additional', 'exactly'] = 'additional') -> None: + r""" + Compute the dimensions of the resulting boxes, and adjust the glue if + one of those dimensions is pre-specified. The computed sizes normally + enclose all of the material inside the new box; but some items may + stick out if negative glue is used, if the box is overfull, or if a + ``\vbox`` includes other boxes that have been shifted left. + + Parameters + ---------- + w : float, default: 0 + A width. + m : {'exactly', 'additional'}, default: 'additional' + Whether to produce a box whose width is 'exactly' *w*; or a box + with the natural width of the contents, plus *w* ('additional'). + + Notes + ----- + The defaults produce a box with the natural width of the contents. + """ + # I don't know why these get reset in TeX. Shift_amount is pretty + # much useless if we do. + # self.shift_amount = 0. + h = 0. + d = 0. + x = 0. + total_stretch = [0.] * 4 + total_shrink = [0.] * 4 + for p in self.children: + if isinstance(p, Char): + x += p.width + h = max(h, p.height) + d = max(d, p.depth) + elif isinstance(p, Box): + x += p.width + if not np.isinf(p.height) and not np.isinf(p.depth): + s = getattr(p, 'shift_amount', 0.) + h = max(h, p.height - s) + d = max(d, p.depth + s) + elif isinstance(p, Glue): + glue_spec = p.glue_spec + x += glue_spec.width + total_stretch[glue_spec.stretch_order] += glue_spec.stretch + total_shrink[glue_spec.shrink_order] += glue_spec.shrink + elif isinstance(p, Kern): + x += p.width + self.height = h + self.depth = d + + if m == 'additional': + w += x + self.width = w + x = w - x + + if x == 0.: + self.glue_sign = 0 + self.glue_order = 0 + self.glue_ratio = 0. + return + if x > 0.: + self._set_glue(x, 1, total_stretch, "Overful") + else: + self._set_glue(x, -1, total_shrink, "Underful") + + +class Vlist(List): + """A vertical list of boxes.""" + + def __init__(self, elements: T.Sequence[Node], h: float = 0.0, + m: T.Literal['additional', 'exactly'] = 'additional'): + super().__init__(elements) + self.vpack(h=h, m=m) + + def vpack(self, h: float = 0.0, + m: T.Literal['additional', 'exactly'] = 'additional', + l: float = np.inf) -> None: + """ + Compute the dimensions of the resulting boxes, and to adjust the glue + if one of those dimensions is pre-specified. + + Parameters + ---------- + h : float, default: 0 + A height. + m : {'exactly', 'additional'}, default: 'additional' + Whether to produce a box whose height is 'exactly' *h*; or a box + with the natural height of the contents, plus *h* ('additional'). + l : float, default: np.inf + The maximum height. + + Notes + ----- + The defaults produce a box with the natural height of the contents. + """ + # I don't know why these get reset in TeX. Shift_amount is pretty + # much useless if we do. + # self.shift_amount = 0. + w = 0. + d = 0. + x = 0. + total_stretch = [0.] * 4 + total_shrink = [0.] * 4 + for p in self.children: + if isinstance(p, Box): + x += d + p.height + d = p.depth + if not np.isinf(p.width): + s = getattr(p, 'shift_amount', 0.) + w = max(w, p.width + s) + elif isinstance(p, Glue): + x += d + d = 0. + glue_spec = p.glue_spec + x += glue_spec.width + total_stretch[glue_spec.stretch_order] += glue_spec.stretch + total_shrink[glue_spec.shrink_order] += glue_spec.shrink + elif isinstance(p, Kern): + x += d + p.width + d = 0. + elif isinstance(p, Char): + raise RuntimeError( + "Internal mathtext error: Char node found in Vlist") + + self.width = w + if d > l: + x += d - l + self.depth = l + else: + self.depth = d + + if m == 'additional': + h += x + self.height = h + x = h - x + + if x == 0: + self.glue_sign = 0 + self.glue_order = 0 + self.glue_ratio = 0. + return + + if x > 0.: + self._set_glue(x, 1, total_stretch, "Overful") + else: + self._set_glue(x, -1, total_shrink, "Underful") + + +class Rule(Box): + """ + A solid black rectangle. + + It has *width*, *depth*, and *height* fields just as in an `Hlist`. + However, if any of these dimensions is inf, the actual value will be + determined by running the rule up to the boundary of the innermost + enclosing box. This is called a "running dimension". The width is never + running in an `Hlist`; the height and depth are never running in a `Vlist`. + """ + + def __init__(self, width: float, height: float, depth: float, state: ParserState): + super().__init__(width, height, depth) + self.fontset = state.fontset + + def render(self, output: Output, # type: ignore[override] + x: float, y: float, w: float, h: float) -> None: + self.fontset.render_rect_filled(output, x, y, x + w, y + h) + + +class Hrule(Rule): + """Convenience class to create a horizontal rule.""" + + def __init__(self, state: ParserState, thickness: float | None = None): + if thickness is None: + thickness = state.get_current_underline_thickness() + height = depth = thickness * 0.5 + super().__init__(np.inf, height, depth, state) + + +class Vrule(Rule): + """Convenience class to create a vertical rule.""" + + def __init__(self, state: ParserState): + thickness = state.get_current_underline_thickness() + super().__init__(thickness, np.inf, np.inf, state) + + +class _GlueSpec(NamedTuple): + width: float + stretch: float + stretch_order: int + shrink: float + shrink_order: int + + +_GlueSpec._named = { # type: ignore[attr-defined] + 'fil': _GlueSpec(0., 1., 1, 0., 0), + 'fill': _GlueSpec(0., 1., 2, 0., 0), + 'filll': _GlueSpec(0., 1., 3, 0., 0), + 'neg_fil': _GlueSpec(0., 0., 0, 1., 1), + 'neg_fill': _GlueSpec(0., 0., 0, 1., 2), + 'neg_filll': _GlueSpec(0., 0., 0, 1., 3), + 'empty': _GlueSpec(0., 0., 0, 0., 0), + 'ss': _GlueSpec(0., 1., 1, -1., 1), +} + + +class Glue(Node): + """ + Most of the information in this object is stored in the underlying + ``_GlueSpec`` class, which is shared between multiple glue objects. + (This is a memory optimization which probably doesn't matter anymore, but + it's easier to stick to what TeX does.) + """ + + def __init__(self, + glue_type: _GlueSpec | T.Literal["fil", "fill", "filll", + "neg_fil", "neg_fill", "neg_filll", + "empty", "ss"]): + super().__init__() + if isinstance(glue_type, str): + glue_spec = _GlueSpec._named[glue_type] # type: ignore[attr-defined] + elif isinstance(glue_type, _GlueSpec): + glue_spec = glue_type + else: + raise ValueError("glue_type must be a glue spec name or instance") + self.glue_spec = glue_spec + + def shrink(self) -> None: + super().shrink() + if self.size < NUM_SIZE_LEVELS: + g = self.glue_spec + self.glue_spec = g._replace(width=g.width * SHRINK_FACTOR) + + +class HCentered(Hlist): + """ + A convenience class to create an `Hlist` whose contents are + centered within its enclosing box. + """ + + def __init__(self, elements: list[Node]): + super().__init__([Glue('ss'), *elements, Glue('ss')], do_kern=False) + + +class VCentered(Vlist): + """ + A convenience class to create a `Vlist` whose contents are + centered within its enclosing box. + """ + + def __init__(self, elements: list[Node]): + super().__init__([Glue('ss'), *elements, Glue('ss')]) + + +class Kern(Node): + """ + A `Kern` node has a width field to specify a (normally + negative) amount of spacing. This spacing correction appears in + horizontal lists between letters like A and V when the font + designer said that it looks better to move them closer together or + further apart. A kern node can also appear in a vertical list, + when its *width* denotes additional spacing in the vertical + direction. + """ + + height = 0 + depth = 0 + + def __init__(self, width: float): + super().__init__() + self.width = width + + def __repr__(self) -> str: + return "k%.02f" % self.width + + def shrink(self) -> None: + super().shrink() + if self.size < NUM_SIZE_LEVELS: + self.width *= SHRINK_FACTOR + + +class AutoHeightChar(Hlist): + """ + A character as close to the given height and depth as possible. + + When using a font with multiple height versions of some characters (such as + the BaKoMa fonts), the correct glyph will be selected, otherwise this will + always just return a scaled version of the glyph. + """ + + def __init__(self, c: str, height: float, depth: float, state: ParserState, + always: bool = False, factor: float | None = None): + alternatives = state.fontset.get_sized_alternatives_for_symbol( + state.font, c) + + xHeight = state.fontset.get_xheight( + state.font, state.fontsize, state.dpi) + + state = state.copy() + target_total = height + depth + for fontname, sym in alternatives: + state.font = fontname + char = Char(sym, state) + # Ensure that size 0 is chosen when the text is regular sized but + # with descender glyphs by subtracting 0.2 * xHeight + if char.height + char.depth >= target_total - 0.2 * xHeight: + break + + shift = 0.0 + if state.font != 0 or len(alternatives) == 1: + if factor is None: + factor = target_total / (char.height + char.depth) + state.fontsize *= factor + char = Char(sym, state) + + shift = (depth - char.depth) + + super().__init__([char]) + self.shift_amount = shift + + +class AutoWidthChar(Hlist): + """ + A character as close to the given width as possible. + + When using a font with multiple width versions of some characters (such as + the BaKoMa fonts), the correct glyph will be selected, otherwise this will + always just return a scaled version of the glyph. + """ + + def __init__(self, c: str, width: float, state: ParserState, always: bool = False, + char_class: type[Char] = Char): + alternatives = state.fontset.get_sized_alternatives_for_symbol( + state.font, c) + + state = state.copy() + for fontname, sym in alternatives: + state.font = fontname + char = char_class(sym, state) + if char.width >= width: + break + + factor = width / char.width + state.fontsize *= factor + char = char_class(sym, state) + + super().__init__([char]) + self.width = char.width + + +def ship(box: Box, xy: tuple[float, float] = (0, 0)) -> Output: + """ + Ship out *box* at offset *xy*, converting it to an `Output`. + + Since boxes can be inside of boxes inside of boxes, the main work of `ship` + is done by two mutually recursive routines, `hlist_out` and `vlist_out`, + which traverse the `Hlist` nodes and `Vlist` nodes inside of horizontal + and vertical boxes. The global variables used in TeX to store state as it + processes have become local variables here. + """ + ox, oy = xy + cur_v = 0. + cur_h = 0. + off_h = ox + off_v = oy + box.height + output = Output(box) + + def clamp(value: float) -> float: + return -1e9 if value < -1e9 else +1e9 if value > +1e9 else value + + def hlist_out(box: Hlist) -> None: + nonlocal cur_v, cur_h, off_h, off_v + + cur_g = 0 + cur_glue = 0. + glue_order = box.glue_order + glue_sign = box.glue_sign + base_line = cur_v + left_edge = cur_h + + for p in box.children: + if isinstance(p, Char): + p.render(output, cur_h + off_h, cur_v + off_v) + cur_h += p.width + elif isinstance(p, Kern): + cur_h += p.width + elif isinstance(p, List): + # node623 + if len(p.children) == 0: + cur_h += p.width + else: + edge = cur_h + cur_v = base_line + p.shift_amount + if isinstance(p, Hlist): + hlist_out(p) + elif isinstance(p, Vlist): + # p.vpack(box.height + box.depth, 'exactly') + vlist_out(p) + else: + assert False, "unreachable code" + cur_h = edge + p.width + cur_v = base_line + elif isinstance(p, Box): + # node624 + rule_height = p.height + rule_depth = p.depth + rule_width = p.width + if np.isinf(rule_height): + rule_height = box.height + if np.isinf(rule_depth): + rule_depth = box.depth + if rule_height > 0 and rule_width > 0: + cur_v = base_line + rule_depth + p.render(output, + cur_h + off_h, cur_v + off_v, + rule_width, rule_height) + cur_v = base_line + cur_h += rule_width + elif isinstance(p, Glue): + # node625 + glue_spec = p.glue_spec + rule_width = glue_spec.width - cur_g + if glue_sign != 0: # normal + if glue_sign == 1: # stretching + if glue_spec.stretch_order == glue_order: + cur_glue += glue_spec.stretch + cur_g = round(clamp(box.glue_set * cur_glue)) + elif glue_spec.shrink_order == glue_order: + cur_glue += glue_spec.shrink + cur_g = round(clamp(box.glue_set * cur_glue)) + rule_width += cur_g + cur_h += rule_width + + def vlist_out(box: Vlist) -> None: + nonlocal cur_v, cur_h, off_h, off_v + + cur_g = 0 + cur_glue = 0. + glue_order = box.glue_order + glue_sign = box.glue_sign + left_edge = cur_h + cur_v -= box.height + top_edge = cur_v + + for p in box.children: + if isinstance(p, Kern): + cur_v += p.width + elif isinstance(p, List): + if len(p.children) == 0: + cur_v += p.height + p.depth + else: + cur_v += p.height + cur_h = left_edge + p.shift_amount + save_v = cur_v + p.width = box.width + if isinstance(p, Hlist): + hlist_out(p) + elif isinstance(p, Vlist): + vlist_out(p) + else: + assert False, "unreachable code" + cur_v = save_v + p.depth + cur_h = left_edge + elif isinstance(p, Box): + rule_height = p.height + rule_depth = p.depth + rule_width = p.width + if np.isinf(rule_width): + rule_width = box.width + rule_height += rule_depth + if rule_height > 0 and rule_depth > 0: + cur_v += rule_height + p.render(output, + cur_h + off_h, cur_v + off_v, + rule_width, rule_height) + elif isinstance(p, Glue): + glue_spec = p.glue_spec + rule_height = glue_spec.width - cur_g + if glue_sign != 0: # normal + if glue_sign == 1: # stretching + if glue_spec.stretch_order == glue_order: + cur_glue += glue_spec.stretch + cur_g = round(clamp(box.glue_set * cur_glue)) + elif glue_spec.shrink_order == glue_order: # shrinking + cur_glue += glue_spec.shrink + cur_g = round(clamp(box.glue_set * cur_glue)) + rule_height += cur_g + cur_v += rule_height + elif isinstance(p, Char): + raise RuntimeError( + "Internal mathtext error: Char node found in vlist") + + assert isinstance(box, Hlist) + hlist_out(box) + return output + + +############################################################################## +# PARSER + + +def Error(msg: str) -> ParserElement: + """Helper class to raise parser errors.""" + def raise_error(s: str, loc: int, toks: ParseResults) -> T.Any: + raise ParseFatalException(s, loc, msg) + + return Empty().setParseAction(raise_error) + + +class ParserState: + """ + Parser state. + + States are pushed and popped from a stack as necessary, and the "current" + state is always at the top of the stack. + + Upon entering and leaving a group { } or math/non-math, the stack is pushed + and popped accordingly. + """ + + def __init__(self, fontset: Fonts, font: str, font_class: str, fontsize: float, + dpi: float): + self.fontset = fontset + self._font = font + self.font_class = font_class + self.fontsize = fontsize + self.dpi = dpi + + def copy(self) -> ParserState: + return copy.copy(self) + + @property + def font(self) -> str: + return self._font + + @font.setter + def font(self, name: str) -> None: + if name in ('rm', 'it', 'bf', 'bfit'): + self.font_class = name + self._font = name + + def get_current_underline_thickness(self) -> float: + """Return the underline thickness for this state.""" + return self.fontset.get_underline_thickness( + self.font, self.fontsize, self.dpi) + + +def cmd(expr: str, args: ParserElement) -> ParserElement: + r""" + Helper to define TeX commands. + + ``cmd("\cmd", args)`` is equivalent to + ``"\cmd" - (args | Error("Expected \cmd{arg}{...}"))`` where the names in + the error message are taken from element names in *args*. If *expr* + already includes arguments (e.g. "\cmd{arg}{...}"), then they are stripped + when constructing the parse element, but kept (and *expr* is used as is) in + the error message. + """ + + def names(elt: ParserElement) -> T.Generator[str, None, None]: + if isinstance(elt, ParseExpression): + for expr in elt.exprs: + yield from names(expr) + elif elt.resultsName: + yield elt.resultsName + + csname = expr.split("{", 1)[0] + err = (csname + "".join("{%s}" % name for name in names(args)) + if expr == csname else expr) + return csname - (args | Error(f"Expected {err}")) + + +class Parser: + """ + A pyparsing-based parser for strings containing math expressions. + + Raw text may also appear outside of pairs of ``$``. + + The grammar is based directly on that in TeX, though it cuts a few corners. + """ + + class _MathStyle(enum.Enum): + DISPLAYSTYLE = 0 + TEXTSTYLE = 1 + SCRIPTSTYLE = 2 + SCRIPTSCRIPTSTYLE = 3 + + _binary_operators = set( + '+ * - \N{MINUS SIGN}' + r''' + \pm \sqcap \rhd + \mp \sqcup \unlhd + \times \vee \unrhd + \div \wedge \oplus + \ast \setminus \ominus + \star \wr \otimes + \circ \diamond \oslash + \bullet \bigtriangleup \odot + \cdot \bigtriangledown \bigcirc + \cap \triangleleft \dagger + \cup \triangleright \ddagger + \uplus \lhd \amalg + \dotplus \dotminus \Cap + \Cup \barwedge \boxdot + \boxminus \boxplus \boxtimes + \curlyvee \curlywedge \divideontimes + \doublebarwedge \leftthreetimes \rightthreetimes + \slash \veebar \barvee + \cupdot \intercal \amalg + \circledcirc \circleddash \circledast + \boxbar \obar \merge + \minuscolon \dotsminusdots + '''.split()) + + _relation_symbols = set(r''' + = < > : + \leq \geq \equiv \models + \prec \succ \sim \perp + \preceq \succeq \simeq \mid + \ll \gg \asymp \parallel + \subset \supset \approx \bowtie + \subseteq \supseteq \cong \Join + \sqsubset \sqsupset \neq \smile + \sqsubseteq \sqsupseteq \doteq \frown + \in \ni \propto \vdash + \dashv \dots \doteqdot \leqq + \geqq \lneqq \gneqq \lessgtr + \leqslant \geqslant \eqgtr \eqless + \eqslantless \eqslantgtr \lesseqgtr \backsim + \backsimeq \lesssim \gtrsim \precsim + \precnsim \gnsim \lnsim \succsim + \succnsim \nsim \lesseqqgtr \gtreqqless + \gtreqless \subseteqq \supseteqq \subsetneqq + \supsetneqq \lessapprox \approxeq \gtrapprox + \precapprox \succapprox \precnapprox \succnapprox + \npreccurlyeq \nsucccurlyeq \nsqsubseteq \nsqsupseteq + \sqsubsetneq \sqsupsetneq \nlesssim \ngtrsim + \nlessgtr \ngtrless \lnapprox \gnapprox + \napprox \approxeq \approxident \lll + \ggg \nparallel \Vdash \Vvdash + \nVdash \nvdash \vDash \nvDash + \nVDash \oequal \simneqq \triangle + \triangleq \triangleeq \triangleleft + \triangleright \ntriangleleft \ntriangleright + \trianglelefteq \ntrianglelefteq \trianglerighteq + \ntrianglerighteq \blacktriangleleft \blacktriangleright + \equalparallel \measuredrightangle \varlrtriangle + \Doteq \Bumpeq \Subset \Supset + \backepsilon \because \therefore \bot + \top \bumpeq \circeq \coloneq + \curlyeqprec \curlyeqsucc \eqcirc \eqcolon + \eqsim \fallingdotseq \gtrdot \gtrless + \ltimes \rtimes \lessdot \ne + \ncong \nequiv \ngeq \ngtr + \nleq \nless \nmid \notin + \nprec \nsubset \nsubseteq \nsucc + \nsupset \nsupseteq \pitchfork \preccurlyeq + \risingdotseq \subsetneq \succcurlyeq \supsetneq + \varpropto \vartriangleleft \scurel + \vartriangleright \rightangle \equal \backcong + \eqdef \wedgeq \questeq \between + \veeeq \disin \varisins \isins + \isindot \varisinobar \isinobar \isinvb + \isinE \nisd \varnis \nis + \varniobar \niobar \bagmember \ratio + \Equiv \stareq \measeq \arceq + \rightassert \rightModels \smallin \smallowns + \notsmallowns \nsimeq'''.split()) + + _arrow_symbols = set(r""" + \leftarrow \longleftarrow \uparrow \Leftarrow \Longleftarrow + \Uparrow \rightarrow \longrightarrow \downarrow \Rightarrow + \Longrightarrow \Downarrow \leftrightarrow \updownarrow + \longleftrightarrow \updownarrow \Leftrightarrow + \Longleftrightarrow \Updownarrow \mapsto \longmapsto \nearrow + \hookleftarrow \hookrightarrow \searrow \leftharpoonup + \rightharpoonup \swarrow \leftharpoondown \rightharpoondown + \nwarrow \rightleftharpoons \leadsto \dashrightarrow + \dashleftarrow \leftleftarrows \leftrightarrows \Lleftarrow + \Rrightarrow \twoheadleftarrow \leftarrowtail \looparrowleft + \leftrightharpoons \curvearrowleft \circlearrowleft \Lsh + \upuparrows \upharpoonleft \downharpoonleft \multimap + \leftrightsquigarrow \rightrightarrows \rightleftarrows + \rightrightarrows \rightleftarrows \twoheadrightarrow + \rightarrowtail \looparrowright \rightleftharpoons + \curvearrowright \circlearrowright \Rsh \downdownarrows + \upharpoonright \downharpoonright \rightsquigarrow \nleftarrow + \nrightarrow \nLeftarrow \nRightarrow \nleftrightarrow + \nLeftrightarrow \to \Swarrow \Searrow \Nwarrow \Nearrow + \leftsquigarrow \overleftarrow \overleftrightarrow \cwopencirclearrow + \downzigzagarrow \cupleftarrow \rightzigzagarrow \twoheaddownarrow + \updownarrowbar \twoheaduparrow \rightarrowbar \updownarrows + \barleftarrow \mapsfrom \mapsdown \mapsup \Ldsh \Rdsh + """.split()) + + _spaced_symbols = _binary_operators | _relation_symbols | _arrow_symbols + + _punctuation_symbols = set(r', ; . ! \ldotp \cdotp'.split()) + + _overunder_symbols = set(r''' + \sum \prod \coprod \bigcap \bigcup \bigsqcup \bigvee + \bigwedge \bigodot \bigotimes \bigoplus \biguplus + '''.split()) + + _overunder_functions = set("lim liminf limsup sup max min".split()) + + _dropsub_symbols = set(r'\int \oint \iint \oiint \iiint \oiiint \iiiint'.split()) + + _fontnames = set("rm cal it tt sf bf bfit " + "default bb frak scr regular".split()) + + _function_names = set(""" + arccos csc ker min arcsin deg lg Pr arctan det lim sec arg dim + liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan + coth inf max tanh""".split()) + + _ambi_delims = set(r""" + | \| / \backslash \uparrow \downarrow \updownarrow \Uparrow + \Downarrow \Updownarrow . \vert \Vert""".split()) + _left_delims = set(r""" + ( [ \{ < \lfloor \langle \lceil \lbrace \leftbrace \lbrack \leftparen \lgroup + """.split()) + _right_delims = set(r""" + ) ] \} > \rfloor \rangle \rceil \rbrace \rightbrace \rbrack \rightparen \rgroup + """.split()) + _delims = _left_delims | _right_delims | _ambi_delims + + _small_greek = set([unicodedata.name(chr(i)).split()[-1].lower() for i in + range(ord('\N{GREEK SMALL LETTER ALPHA}'), + ord('\N{GREEK SMALL LETTER OMEGA}') + 1)]) + _latin_alphabets = set(string.ascii_letters) + + def __init__(self) -> None: + p = types.SimpleNamespace() + + def set_names_and_parse_actions() -> None: + for key, val in vars(p).items(): + if not key.startswith('_'): + # Set names on (almost) everything -- very useful for debugging + # token, placeable, and auto_delim are forward references which + # are left without names to ensure useful error messages + if key not in ("token", "placeable", "auto_delim"): + val.setName(key) + # Set actions + if hasattr(self, key): + val.setParseAction(getattr(self, key)) + + # Root definitions. + + # In TeX parlance, a csname is a control sequence name (a "\foo"). + def csnames(group: str, names: Iterable[str]) -> Regex: + ends_with_alpha = [] + ends_with_nonalpha = [] + for name in names: + if name[-1].isalpha(): + ends_with_alpha.append(name) + else: + ends_with_nonalpha.append(name) + return Regex( + r"\\(?P<{group}>(?:{alpha})(?![A-Za-z]){additional}{nonalpha})".format( + group=group, + alpha="|".join(map(re.escape, ends_with_alpha)), + additional="|" if ends_with_nonalpha else "", + nonalpha="|".join(map(re.escape, ends_with_nonalpha)), + ) + ) + + p.float_literal = Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)") + p.space = oneOf(self._space_widths)("space") + + p.style_literal = oneOf( + [str(e.value) for e in self._MathStyle])("style_literal") + + p.symbol = Regex( + r"[a-zA-Z0-9 +\-*/<>=:,.;!\?&'@()\[\]|\U00000080-\U0001ffff]" + r"|\\[%${}\[\]_|]" + + r"|\\(?:{})(?![A-Za-z])".format( + "|".join(map(re.escape, tex2uni))) + )("sym").leaveWhitespace() + p.unknown_symbol = Regex(r"\\[A-Za-z]+")("name") + + p.font = csnames("font", self._fontnames) + p.start_group = Optional(r"\math" + oneOf(self._fontnames)("font")) + "{" + p.end_group = Literal("}") + + p.delim = oneOf(self._delims) + + # Mutually recursive definitions. (Minimizing the number of Forward + # elements is important for speed.) + p.auto_delim = Forward() + p.placeable = Forward() + p.required_group = Forward() + p.optional_group = Forward() + p.token = Forward() + + set_names_and_parse_actions() # for mutually recursive definitions. + + p.optional_group <<= "{" + ZeroOrMore(p.token)("group") + "}" + p.required_group <<= "{" + OneOrMore(p.token)("group") + "}" + + p.customspace = cmd(r"\hspace", "{" + p.float_literal("space") + "}") + + p.accent = ( + csnames("accent", [*self._accent_map, *self._wide_accents]) + - p.placeable("sym")) + + p.function = csnames("name", self._function_names) + + p.group = p.start_group + ZeroOrMore(p.token)("group") + p.end_group + p.unclosed_group = (p.start_group + ZeroOrMore(p.token)("group") + StringEnd()) + + p.frac = cmd(r"\frac", p.required_group("num") + p.required_group("den")) + p.dfrac = cmd(r"\dfrac", p.required_group("num") + p.required_group("den")) + p.binom = cmd(r"\binom", p.required_group("num") + p.required_group("den")) + + p.genfrac = cmd( + r"\genfrac", + "{" + Optional(p.delim)("ldelim") + "}" + + "{" + Optional(p.delim)("rdelim") + "}" + + "{" + p.float_literal("rulesize") + "}" + + "{" + Optional(p.style_literal)("style") + "}" + + p.required_group("num") + + p.required_group("den")) + + p.sqrt = cmd( + r"\sqrt{value}", + Optional("[" + OneOrMore(NotAny("]") + p.token)("root") + "]") + + p.required_group("value")) + + p.overline = cmd(r"\overline", p.required_group("body")) + + p.overset = cmd( + r"\overset", + p.optional_group("annotation") + p.optional_group("body")) + p.underset = cmd( + r"\underset", + p.optional_group("annotation") + p.optional_group("body")) + + p.text = cmd(r"\text", QuotedString('{', '\\', endQuoteChar="}")) + + p.substack = cmd(r"\substack", + nested_expr(opener="{", closer="}", + content=Group(OneOrMore(p.token)) + + ZeroOrMore(Literal("\\\\").suppress()))("parts")) + + p.subsuper = ( + (Optional(p.placeable)("nucleus") + + OneOrMore(oneOf(["_", "^"]) - p.placeable)("subsuper") + + Regex("'*")("apostrophes")) + | Regex("'+")("apostrophes") + | (p.placeable("nucleus") + Regex("'*")("apostrophes")) + ) + + p.simple = p.space | p.customspace | p.font | p.subsuper + + p.token <<= ( + p.simple + | p.auto_delim + | p.unclosed_group + | p.unknown_symbol # Must be last + ) + + p.operatorname = cmd(r"\operatorname", "{" + ZeroOrMore(p.simple)("name") + "}") + + p.boldsymbol = cmd( + r"\boldsymbol", "{" + ZeroOrMore(p.simple)("value") + "}") + + p.placeable <<= ( + p.accent # Must be before symbol as all accents are symbols + | p.symbol # Must be second to catch all named symbols and single + # chars not in a group + | p.function + | p.operatorname + | p.group + | p.frac + | p.dfrac + | p.binom + | p.genfrac + | p.overset + | p.underset + | p.sqrt + | p.overline + | p.text + | p.boldsymbol + | p.substack + ) + + mdelim = r"\middle" - (p.delim("mdelim") | Error("Expected a delimiter")) + p.auto_delim <<= ( + r"\left" - (p.delim("left") | Error("Expected a delimiter")) + + ZeroOrMore(p.simple | p.auto_delim | mdelim)("mid") + + r"\right" - (p.delim("right") | Error("Expected a delimiter")) + ) + + # Leaf definitions. + p.math = OneOrMore(p.token) + p.math_string = QuotedString('$', '\\', unquoteResults=False) + p.non_math = Regex(r"(?:(?:\\[$])|[^$])*").leaveWhitespace() + p.main = ( + p.non_math + ZeroOrMore(p.math_string + p.non_math) + StringEnd() + ) + set_names_and_parse_actions() # for leaf definitions. + + self._expression = p.main + self._math_expression = p.math + + # To add space to nucleus operators after sub/superscripts + self._in_subscript_or_superscript = False + + def parse(self, s: str, fonts_object: Fonts, fontsize: float, dpi: float) -> Hlist: + """ + Parse expression *s* using the given *fonts_object* for + output, at the given *fontsize* and *dpi*. + + Returns the parse tree of `Node` instances. + """ + self._state_stack = [ + ParserState(fonts_object, 'default', 'rm', fontsize, dpi)] + self._em_width_cache: dict[tuple[str, float, float], float] = {} + try: + result = self._expression.parseString(s) + except ParseBaseException as err: + # explain becomes a plain method on pyparsing 3 (err.explain(0)). + raise ValueError("\n" + ParseException.explain(err, 0)) from None + self._state_stack = [] + self._in_subscript_or_superscript = False + # prevent operator spacing from leaking into a new expression + self._em_width_cache = {} + ParserElement.resetCache() + return T.cast(Hlist, result[0]) # Known return type from main. + + def get_state(self) -> ParserState: + """Get the current `State` of the parser.""" + return self._state_stack[-1] + + def pop_state(self) -> None: + """Pop a `State` off of the stack.""" + self._state_stack.pop() + + def push_state(self) -> None: + """Push a new `State` onto the stack, copying the current state.""" + self._state_stack.append(self.get_state().copy()) + + def main(self, toks: ParseResults) -> list[Hlist]: + return [Hlist(toks.asList())] + + def math_string(self, toks: ParseResults) -> ParseResults: + return self._math_expression.parseString(toks[0][1:-1], parseAll=True) + + def math(self, toks: ParseResults) -> T.Any: + hlist = Hlist(toks.asList()) + self.pop_state() + return [hlist] + + def non_math(self, toks: ParseResults) -> T.Any: + s = toks[0].replace(r'\$', '$') + symbols = [Char(c, self.get_state()) for c in s] + hlist = Hlist(symbols) + # We're going into math now, so set font to 'it' + self.push_state() + self.get_state().font = mpl.rcParams['mathtext.default'] + return [hlist] + + float_literal = staticmethod(pyparsing_common.convertToFloat) + + def text(self, toks: ParseResults) -> T.Any: + self.push_state() + state = self.get_state() + state.font = 'rm' + hlist = Hlist([Char(c, state) for c in toks[1]]) + self.pop_state() + return [hlist] + + def _make_space(self, percentage: float) -> Kern: + # In TeX, an em (the unit usually used to measure horizontal lengths) + # is not the width of the character 'm'; it is the same in different + # font styles (e.g. roman or italic). Mathtext, however, uses 'm' in + # the italic style so that horizontal spaces don't depend on the + # current font style. + state = self.get_state() + key = (state.font, state.fontsize, state.dpi) + width = self._em_width_cache.get(key) + if width is None: + metrics = state.fontset.get_metrics( + 'it', mpl.rcParams['mathtext.default'], 'm', + state.fontsize, state.dpi) + width = metrics.advance + self._em_width_cache[key] = width + return Kern(width * percentage) + + _space_widths = { + r'\,': 0.16667, # 3/18 em = 3 mu + r'\thinspace': 0.16667, # 3/18 em = 3 mu + r'\/': 0.16667, # 3/18 em = 3 mu + r'\>': 0.22222, # 4/18 em = 4 mu + r'\:': 0.22222, # 4/18 em = 4 mu + r'\;': 0.27778, # 5/18 em = 5 mu + r'\ ': 0.33333, # 6/18 em = 6 mu + r'~': 0.33333, # 6/18 em = 6 mu, nonbreakable + r'\enspace': 0.5, # 9/18 em = 9 mu + r'\quad': 1, # 1 em = 18 mu + r'\qquad': 2, # 2 em = 36 mu + r'\!': -0.16667, # -3/18 em = -3 mu + } + + def space(self, toks: ParseResults) -> T.Any: + num = self._space_widths[toks["space"]] + box = self._make_space(num) + return [box] + + def customspace(self, toks: ParseResults) -> T.Any: + return [self._make_space(toks["space"])] + + def symbol(self, s: str, loc: int, + toks: ParseResults | dict[str, str]) -> T.Any: + c = toks["sym"] + if c == "-": + # "U+2212 minus sign is the preferred representation of the unary + # and binary minus sign rather than the ASCII-derived U+002D + # hyphen-minus, because minus sign is unambiguous and because it + # is rendered with a more desirable length, usually longer than a + # hyphen." (https://www.unicode.org/reports/tr25/) + c = "\N{MINUS SIGN}" + try: + char = Char(c, self.get_state()) + except ValueError as err: + raise ParseFatalException(s, loc, + "Unknown symbol: %s" % c) from err + + if c in self._spaced_symbols: + # iterate until we find previous character, needed for cases + # such as ${ -2}$, $ -2$, or $ -2$. + prev_char = next((c for c in s[:loc][::-1] if c != ' '), '') + # Binary operators at start of string should not be spaced + # Also, operators in sub- or superscripts should not be spaced + if (self._in_subscript_or_superscript or ( + c in self._binary_operators and ( + len(s[:loc].split()) == 0 or prev_char == '{' or + prev_char in self._left_delims))): + return [char] + else: + return [Hlist([self._make_space(0.2), + char, + self._make_space(0.2)], + do_kern=True)] + elif c in self._punctuation_symbols: + prev_char = next((c for c in s[:loc][::-1] if c != ' '), '') + next_char = next((c for c in s[loc + 1:] if c != ' '), '') + + # Do not space commas between brackets + if c == ',': + if prev_char == '{' and next_char == '}': + return [char] + + # Do not space dots as decimal separators + if c == '.' and prev_char.isdigit() and next_char.isdigit(): + return [char] + else: + return [Hlist([char, self._make_space(0.2)], do_kern=True)] + return [char] + + def unknown_symbol(self, s: str, loc: int, toks: ParseResults) -> T.Any: + raise ParseFatalException(s, loc, f"Unknown symbol: {toks['name']}") + + _accent_map = { + r'hat': r'\circumflexaccent', + r'breve': r'\combiningbreve', + r'bar': r'\combiningoverline', + r'grave': r'\combininggraveaccent', + r'acute': r'\combiningacuteaccent', + r'tilde': r'\combiningtilde', + r'dot': r'\combiningdotabove', + r'ddot': r'\combiningdiaeresis', + r'dddot': r'\combiningthreedotsabove', + r'ddddot': r'\combiningfourdotsabove', + r'vec': r'\combiningrightarrowabove', + r'"': r'\combiningdiaeresis', + r"`": r'\combininggraveaccent', + r"'": r'\combiningacuteaccent', + r'~': r'\combiningtilde', + r'.': r'\combiningdotabove', + r'^': r'\circumflexaccent', + r'overrightarrow': r'\rightarrow', + r'overleftarrow': r'\leftarrow', + r'mathring': r'\circ', + } + + _wide_accents = set(r"widehat widetilde widebar".split()) + + def accent(self, toks: ParseResults) -> T.Any: + state = self.get_state() + thickness = state.get_current_underline_thickness() + accent = toks["accent"] + sym = toks["sym"] + accent_box: Node + if accent in self._wide_accents: + accent_box = AutoWidthChar( + '\\' + accent, sym.width, state, char_class=Accent) + else: + accent_box = Accent(self._accent_map[accent], state) + if accent == 'mathring': + accent_box.shrink() + accent_box.shrink() + centered = HCentered([Hbox(sym.width / 4.0), accent_box]) + centered.hpack(sym.width, 'exactly') + return Vlist([ + centered, + Vbox(0., thickness * 2.0), + Hlist([sym]) + ]) + + def function(self, s: str, loc: int, toks: ParseResults) -> T.Any: + hlist = self.operatorname(s, loc, toks) + hlist.function_name = toks["name"] + return hlist + + def operatorname(self, s: str, loc: int, toks: ParseResults) -> T.Any: + self.push_state() + state = self.get_state() + state.font = 'rm' + hlist_list: list[Node] = [] + # Change the font of Chars, but leave Kerns alone + name = toks["name"] + for c in name: + if isinstance(c, Char): + c.font = 'rm' + c._update_metrics() + hlist_list.append(c) + elif isinstance(c, str): + hlist_list.append(Char(c, state)) + else: + hlist_list.append(c) + next_char_loc = loc + len(name) + 1 + if isinstance(name, ParseResults): + next_char_loc += len('operatorname{}') + next_char = next((c for c in s[next_char_loc:] if c != ' '), '') + delimiters = self._delims | {'^', '_'} + if (next_char not in delimiters and + name not in self._overunder_functions): + # Add thin space except when followed by parenthesis, bracket, etc. + hlist_list += [self._make_space(self._space_widths[r'\,'])] + self.pop_state() + # if followed by a super/subscript, set flag to true + # This flag tells subsuper to add space after this operator + if next_char in {'^', '_'}: + self._in_subscript_or_superscript = True + else: + self._in_subscript_or_superscript = False + + return Hlist(hlist_list) + + def start_group(self, toks: ParseResults) -> T.Any: + self.push_state() + # Deal with LaTeX-style font tokens + if toks.get("font"): + self.get_state().font = toks.get("font") + return [] + + def group(self, toks: ParseResults) -> T.Any: + grp = Hlist(toks.get("group", [])) + return [grp] + + def required_group(self, toks: ParseResults) -> T.Any: + return Hlist(toks.get("group", [])) + + optional_group = required_group + + def end_group(self) -> T.Any: + self.pop_state() + return [] + + def unclosed_group(self, s: str, loc: int, toks: ParseResults) -> T.Any: + raise ParseFatalException(s, len(s), "Expected '}'") + + def font(self, toks: ParseResults) -> T.Any: + self.get_state().font = toks["font"] + return [] + + def is_overunder(self, nucleus: Node) -> bool: + if isinstance(nucleus, Char): + return nucleus.c in self._overunder_symbols + elif isinstance(nucleus, Hlist) and hasattr(nucleus, 'function_name'): + return nucleus.function_name in self._overunder_functions + return False + + def is_dropsub(self, nucleus: Node) -> bool: + if isinstance(nucleus, Char): + return nucleus.c in self._dropsub_symbols + return False + + def is_slanted(self, nucleus: Node) -> bool: + if isinstance(nucleus, Char): + return nucleus.is_slanted() + return False + + def subsuper(self, s: str, loc: int, toks: ParseResults) -> T.Any: + nucleus = toks.get("nucleus", Hbox(0)) + subsuper = toks.get("subsuper", []) + napostrophes = len(toks.get("apostrophes", [])) + + if not subsuper and not napostrophes: + return nucleus + + sub = super = None + while subsuper: + op, arg, *subsuper = subsuper + if op == '_': + if sub is not None: + raise ParseFatalException("Double subscript") + sub = arg + else: + if super is not None: + raise ParseFatalException("Double superscript") + super = arg + + state = self.get_state() + rule_thickness = state.fontset.get_underline_thickness( + state.font, state.fontsize, state.dpi) + xHeight = state.fontset.get_xheight( + state.font, state.fontsize, state.dpi) + + if napostrophes: + if super is None: + super = Hlist([]) + for i in range(napostrophes): + super.children.extend(self.symbol(s, loc, {"sym": "\\prime"})) + # kern() and hpack() needed to get the metrics right after + # extending + super.kern() + super.hpack() + + # Handle over/under symbols, such as sum or prod + if self.is_overunder(nucleus): + vlist = [] + shift = 0. + width = nucleus.width + if super is not None: + super.shrink() + width = max(width, super.width) + if sub is not None: + sub.shrink() + width = max(width, sub.width) + + vgap = rule_thickness * 3.0 + if super is not None: + hlist = HCentered([super]) + hlist.hpack(width, 'exactly') + vlist.extend([hlist, Vbox(0, vgap)]) + hlist = HCentered([nucleus]) + hlist.hpack(width, 'exactly') + vlist.append(hlist) + if sub is not None: + hlist = HCentered([sub]) + hlist.hpack(width, 'exactly') + vlist.extend([Vbox(0, vgap), hlist]) + shift = hlist.height + vgap + nucleus.depth + vlt = Vlist(vlist) + vlt.shift_amount = shift + result = Hlist([vlt]) + return [result] + + # We remove kerning on the last character for consistency (otherwise + # it will compute kerning based on non-shrunk characters and may put + # them too close together when superscripted) + # We change the width of the last character to match the advance to + # consider some fonts with weird metrics: e.g. stix's f has a width of + # 7.75 and a kerning of -4.0 for an advance of 3.72, and we want to put + # the superscript at the advance + last_char = nucleus + if isinstance(nucleus, Hlist): + new_children = nucleus.children + if len(new_children): + # remove last kern + if (isinstance(new_children[-1], Kern) and + hasattr(new_children[-2], '_metrics')): + new_children = new_children[:-1] + last_char = new_children[-1] + if hasattr(last_char, '_metrics'): + last_char.width = last_char._metrics.advance + # create new Hlist without kerning + nucleus = Hlist(new_children, do_kern=False) + else: + if isinstance(nucleus, Char): + last_char.width = last_char._metrics.advance + nucleus = Hlist([nucleus]) + + # Handle regular sub/superscripts + constants = _get_font_constant_set(state) + lc_height = last_char.height + lc_baseline = 0 + if self.is_dropsub(last_char): + lc_baseline = last_char.depth + + # Compute kerning for sub and super + superkern = constants.delta * xHeight + subkern = constants.delta * xHeight + if self.is_slanted(last_char): + superkern += constants.delta * xHeight + superkern += (constants.delta_slanted * + (lc_height - xHeight * 2. / 3.)) + if self.is_dropsub(last_char): + subkern = (3 * constants.delta - + constants.delta_integral) * lc_height + superkern = (3 * constants.delta + + constants.delta_integral) * lc_height + else: + subkern = 0 + + x: List + if super is None: + # node757 + # Note: One of super or sub must be a Node if we're in this function, but + # mypy can't know this, since it can't interpret pyparsing expressions, + # hence the cast. + x = Hlist([Kern(subkern), T.cast(Node, sub)]) + x.shrink() + if self.is_dropsub(last_char): + shift_down = lc_baseline + constants.subdrop * xHeight + else: + shift_down = constants.sub1 * xHeight + x.shift_amount = shift_down + else: + x = Hlist([Kern(superkern), super]) + x.shrink() + if self.is_dropsub(last_char): + shift_up = lc_height - constants.subdrop * xHeight + else: + shift_up = constants.sup1 * xHeight + if sub is None: + x.shift_amount = -shift_up + else: # Both sub and superscript + y = Hlist([Kern(subkern), sub]) + y.shrink() + if self.is_dropsub(last_char): + shift_down = lc_baseline + constants.subdrop * xHeight + else: + shift_down = constants.sub2 * xHeight + # If sub and superscript collide, move super up + clr = (2.0 * rule_thickness - + ((shift_up - x.depth) - (y.height - shift_down))) + if clr > 0.: + shift_up += clr + x = Vlist([ + x, + Kern((shift_up - x.depth) - (y.height - shift_down)), + y]) + x.shift_amount = shift_down + + if not self.is_dropsub(last_char): + x.width += constants.script_space * xHeight + + # Do we need to add a space after the nucleus? + # To find out, check the flag set by operatorname + spaced_nucleus = [nucleus, x] + if self._in_subscript_or_superscript: + spaced_nucleus += [self._make_space(self._space_widths[r'\,'])] + self._in_subscript_or_superscript = False + + result = Hlist(spaced_nucleus) + return [result] + + def _genfrac(self, ldelim: str, rdelim: str, rule: float | None, style: _MathStyle, + num: Hlist, den: Hlist) -> T.Any: + state = self.get_state() + thickness = state.get_current_underline_thickness() + + for _ in range(style.value): + num.shrink() + den.shrink() + cnum = HCentered([num]) + cden = HCentered([den]) + width = max(num.width, den.width) + cnum.hpack(width, 'exactly') + cden.hpack(width, 'exactly') + vlist = Vlist([cnum, # numerator + Vbox(0, thickness * 2.0), # space + Hrule(state, rule), # rule + Vbox(0, thickness * 2.0), # space + cden # denominator + ]) + + # Shift so the fraction line sits in the middle of the + # equals sign + metrics = state.fontset.get_metrics( + state.font, mpl.rcParams['mathtext.default'], + '=', state.fontsize, state.dpi) + shift = (cden.height - + ((metrics.ymax + metrics.ymin) / 2 - + thickness * 3.0)) + vlist.shift_amount = shift + + result = [Hlist([vlist, Hbox(thickness * 2.)])] + if ldelim or rdelim: + if ldelim == '': + ldelim = '.' + if rdelim == '': + rdelim = '.' + return self._auto_sized_delimiter(ldelim, + T.cast(list[T.Union[Box, Char, str]], + result), + rdelim) + return result + + def style_literal(self, toks: ParseResults) -> T.Any: + return self._MathStyle(int(toks["style_literal"])) + + def genfrac(self, toks: ParseResults) -> T.Any: + return self._genfrac( + toks.get("ldelim", ""), toks.get("rdelim", ""), + toks["rulesize"], toks.get("style", self._MathStyle.TEXTSTYLE), + toks["num"], toks["den"]) + + def frac(self, toks: ParseResults) -> T.Any: + return self._genfrac( + "", "", self.get_state().get_current_underline_thickness(), + self._MathStyle.TEXTSTYLE, toks["num"], toks["den"]) + + def dfrac(self, toks: ParseResults) -> T.Any: + return self._genfrac( + "", "", self.get_state().get_current_underline_thickness(), + self._MathStyle.DISPLAYSTYLE, toks["num"], toks["den"]) + + def binom(self, toks: ParseResults) -> T.Any: + return self._genfrac( + "(", ")", 0, + self._MathStyle.TEXTSTYLE, toks["num"], toks["den"]) + + def _genset(self, s: str, loc: int, toks: ParseResults) -> T.Any: + annotation = toks["annotation"] + body = toks["body"] + thickness = self.get_state().get_current_underline_thickness() + + annotation.shrink() + cannotation = HCentered([annotation]) + cbody = HCentered([body]) + width = max(cannotation.width, cbody.width) + cannotation.hpack(width, 'exactly') + cbody.hpack(width, 'exactly') + + vgap = thickness * 3 + if s[loc + 1] == "u": # \underset + vlist = Vlist([cbody, # body + Vbox(0, vgap), # space + cannotation # annotation + ]) + # Shift so the body sits in the same vertical position + vlist.shift_amount = cbody.depth + cannotation.height + vgap + else: # \overset + vlist = Vlist([cannotation, # annotation + Vbox(0, vgap), # space + cbody # body + ]) + + # To add horizontal gap between symbols: wrap the Vlist into + # an Hlist and extend it with an Hbox(0, horizontal_gap) + return vlist + + overset = underset = _genset + + def sqrt(self, toks: ParseResults) -> T.Any: + root = toks.get("root") + body = toks["value"] + state = self.get_state() + thickness = state.get_current_underline_thickness() + + # Determine the height of the body, and add a little extra to + # the height so it doesn't seem cramped + height = body.height - body.shift_amount + thickness * 5.0 + depth = body.depth + body.shift_amount + check = AutoHeightChar(r'\__sqrt__', height, depth, state, always=True) + height = check.height - check.shift_amount + depth = check.depth + check.shift_amount + + # Put a little extra space to the left and right of the body + padded_body = Hlist([Hbox(2 * thickness), body, Hbox(2 * thickness)]) + rightside = Vlist([Hrule(state), Glue('fill'), padded_body]) + # Stretch the glue between the hrule and the body + rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0), + 'exactly', depth) + + # Add the root and shift it upward so it is above the tick. + # The value of 0.6 is a hard-coded hack ;) + if not root: + root = Box(check.width * 0.5, 0., 0.) + else: + root = Hlist(root) + root.shrink() + root.shrink() + + root_vlist = Vlist([Hlist([root])]) + root_vlist.shift_amount = -height * 0.6 + + hlist = Hlist([root_vlist, # Root + # Negative kerning to put root over tick + Kern(-check.width * 0.5), + check, # Check + rightside]) # Body + return [hlist] + + def overline(self, toks: ParseResults) -> T.Any: + body = toks["body"] + + state = self.get_state() + thickness = state.get_current_underline_thickness() + + height = body.height - body.shift_amount + thickness * 3.0 + depth = body.depth + body.shift_amount + + # Place overline above body + rightside = Vlist([Hrule(state), Glue('fill'), Hlist([body])]) + + # Stretch the glue between the hrule and the body + rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0), + 'exactly', depth) + + hlist = Hlist([rightside]) + return [hlist] + + def _auto_sized_delimiter(self, front: str, + middle: list[Box | Char | str], + back: str) -> T.Any: + state = self.get_state() + if len(middle): + height = max([x.height for x in middle if not isinstance(x, str)]) + depth = max([x.depth for x in middle if not isinstance(x, str)]) + factor = None + for idx, el in enumerate(middle): + if isinstance(el, str) and el == '\\middle': + c = T.cast(str, middle[idx + 1]) # Should be one of p.delims. + if c != '.': + middle[idx + 1] = AutoHeightChar( + c, height, depth, state, factor=factor) + else: + middle.remove(c) + del middle[idx] + # There should only be \middle and its delimiter as str, which have + # just been removed. + middle_part = T.cast(list[T.Union[Box, Char]], middle) + else: + height = 0 + depth = 0 + factor = 1.0 + middle_part = [] + + parts: list[Node] = [] + # \left. and \right. aren't supposed to produce any symbols + if front != '.': + parts.append( + AutoHeightChar(front, height, depth, state, factor=factor)) + parts.extend(middle_part) + if back != '.': + parts.append( + AutoHeightChar(back, height, depth, state, factor=factor)) + hlist = Hlist(parts) + return hlist + + def auto_delim(self, toks: ParseResults) -> T.Any: + return self._auto_sized_delimiter( + toks["left"], + # if "mid" in toks ... can be removed when requiring pyparsing 3. + toks["mid"].asList() if "mid" in toks else [], + toks["right"]) + + def boldsymbol(self, toks: ParseResults) -> T.Any: + self.push_state() + state = self.get_state() + hlist: list[Node] = [] + name = toks["value"] + for c in name: + if isinstance(c, Hlist): + k = c.children[1] + if isinstance(k, Char): + k.font = "bf" + k._update_metrics() + hlist.append(c) + elif isinstance(c, Char): + c.font = "bf" + if (c.c in self._latin_alphabets or + c.c[1:] in self._small_greek): + c.font = "bfit" + c._update_metrics() + c._update_metrics() + hlist.append(c) + else: + hlist.append(c) + self.pop_state() + + return Hlist(hlist) + + def substack(self, toks: ParseResults) -> T.Any: + parts = toks["parts"] + state = self.get_state() + thickness = state.get_current_underline_thickness() + + hlist = [Hlist(k) for k in parts[0]] + max_width = max(map(lambda c: c.width, hlist)) + + vlist = [] + for sub in hlist: + cp = HCentered([sub]) + cp.hpack(max_width, 'exactly') + vlist.append(cp) + + stack = [val + for pair in zip(vlist, [Vbox(0, thickness * 2)] * len(vlist)) + for val in pair] + del stack[-1] + vlt = Vlist(stack) + result = [Hlist([vlt])] + return result diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext_data.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext_data.py new file mode 100644 index 00000000..baaee1b8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_mathtext_data.py @@ -0,0 +1,1311 @@ +""" +font data tables for truetype and afm computer modern fonts +""" + +from __future__ import annotations + + +latex_to_bakoma = { + '\\__sqrt__' : ('cmex10', 0x70), + '\\bigcap' : ('cmex10', 0x5c), + '\\bigcup' : ('cmex10', 0x5b), + '\\bigodot' : ('cmex10', 0x4b), + '\\bigoplus' : ('cmex10', 0x4d), + '\\bigotimes' : ('cmex10', 0x4f), + '\\biguplus' : ('cmex10', 0x5d), + '\\bigvee' : ('cmex10', 0x5f), + '\\bigwedge' : ('cmex10', 0x5e), + '\\coprod' : ('cmex10', 0x61), + '\\int' : ('cmex10', 0x5a), + '\\langle' : ('cmex10', 0xad), + '\\leftangle' : ('cmex10', 0xad), + '\\leftbrace' : ('cmex10', 0xa9), + '\\oint' : ('cmex10', 0x49), + '\\prod' : ('cmex10', 0x59), + '\\rangle' : ('cmex10', 0xae), + '\\rightangle' : ('cmex10', 0xae), + '\\rightbrace' : ('cmex10', 0xaa), + '\\sum' : ('cmex10', 0x58), + '\\widehat' : ('cmex10', 0x62), + '\\widetilde' : ('cmex10', 0x65), + '\\{' : ('cmex10', 0xa9), + '\\}' : ('cmex10', 0xaa), + '{' : ('cmex10', 0xa9), + '}' : ('cmex10', 0xaa), + + ',' : ('cmmi10', 0x3b), + '.' : ('cmmi10', 0x3a), + '/' : ('cmmi10', 0x3d), + '<' : ('cmmi10', 0x3c), + '>' : ('cmmi10', 0x3e), + '\\alpha' : ('cmmi10', 0xae), + '\\beta' : ('cmmi10', 0xaf), + '\\chi' : ('cmmi10', 0xc2), + '\\combiningrightarrowabove' : ('cmmi10', 0x7e), + '\\delta' : ('cmmi10', 0xb1), + '\\ell' : ('cmmi10', 0x60), + '\\epsilon' : ('cmmi10', 0xb2), + '\\eta' : ('cmmi10', 0xb4), + '\\flat' : ('cmmi10', 0x5b), + '\\frown' : ('cmmi10', 0x5f), + '\\gamma' : ('cmmi10', 0xb0), + '\\imath' : ('cmmi10', 0x7b), + '\\iota' : ('cmmi10', 0xb6), + '\\jmath' : ('cmmi10', 0x7c), + '\\kappa' : ('cmmi10', 0x2219), + '\\lambda' : ('cmmi10', 0xb8), + '\\leftharpoondown' : ('cmmi10', 0x29), + '\\leftharpoonup' : ('cmmi10', 0x28), + '\\mu' : ('cmmi10', 0xb9), + '\\natural' : ('cmmi10', 0x5c), + '\\nu' : ('cmmi10', 0xba), + '\\omega' : ('cmmi10', 0x21), + '\\phi' : ('cmmi10', 0xc1), + '\\pi' : ('cmmi10', 0xbc), + '\\psi' : ('cmmi10', 0xc3), + '\\rho' : ('cmmi10', 0xbd), + '\\rightharpoondown' : ('cmmi10', 0x2b), + '\\rightharpoonup' : ('cmmi10', 0x2a), + '\\sharp' : ('cmmi10', 0x5d), + '\\sigma' : ('cmmi10', 0xbe), + '\\smile' : ('cmmi10', 0x5e), + '\\tau' : ('cmmi10', 0xbf), + '\\theta' : ('cmmi10', 0xb5), + '\\triangleleft' : ('cmmi10', 0x2f), + '\\triangleright' : ('cmmi10', 0x2e), + '\\upsilon' : ('cmmi10', 0xc0), + '\\varepsilon' : ('cmmi10', 0x22), + '\\varphi' : ('cmmi10', 0x27), + '\\varrho' : ('cmmi10', 0x25), + '\\varsigma' : ('cmmi10', 0x26), + '\\vartheta' : ('cmmi10', 0x23), + '\\wp' : ('cmmi10', 0x7d), + '\\xi' : ('cmmi10', 0xbb), + '\\zeta' : ('cmmi10', 0xb3), + + '!' : ('cmr10', 0x21), + '%' : ('cmr10', 0x25), + '&' : ('cmr10', 0x26), + '(' : ('cmr10', 0x28), + ')' : ('cmr10', 0x29), + '+' : ('cmr10', 0x2b), + '0' : ('cmr10', 0x30), + '1' : ('cmr10', 0x31), + '2' : ('cmr10', 0x32), + '3' : ('cmr10', 0x33), + '4' : ('cmr10', 0x34), + '5' : ('cmr10', 0x35), + '6' : ('cmr10', 0x36), + '7' : ('cmr10', 0x37), + '8' : ('cmr10', 0x38), + '9' : ('cmr10', 0x39), + ':' : ('cmr10', 0x3a), + ';' : ('cmr10', 0x3b), + '=' : ('cmr10', 0x3d), + '?' : ('cmr10', 0x3f), + '@' : ('cmr10', 0x40), + '[' : ('cmr10', 0x5b), + '\\#' : ('cmr10', 0x23), + '\\$' : ('cmr10', 0x24), + '\\%' : ('cmr10', 0x25), + '\\Delta' : ('cmr10', 0xa2), + '\\Gamma' : ('cmr10', 0xa1), + '\\Lambda' : ('cmr10', 0xa4), + '\\Omega' : ('cmr10', 0xad), + '\\Phi' : ('cmr10', 0xa9), + '\\Pi' : ('cmr10', 0xa6), + '\\Psi' : ('cmr10', 0xaa), + '\\Sigma' : ('cmr10', 0xa7), + '\\Theta' : ('cmr10', 0xa3), + '\\Upsilon' : ('cmr10', 0xa8), + '\\Xi' : ('cmr10', 0xa5), + '\\circumflexaccent' : ('cmr10', 0x5e), + '\\combiningacuteaccent' : ('cmr10', 0xb6), + '\\combiningbreve' : ('cmr10', 0xb8), + '\\combiningdiaeresis' : ('cmr10', 0xc4), + '\\combiningdotabove' : ('cmr10', 0x5f), + '\\combininggraveaccent' : ('cmr10', 0xb5), + '\\combiningoverline' : ('cmr10', 0xb9), + '\\combiningtilde' : ('cmr10', 0x7e), + '\\leftbracket' : ('cmr10', 0x5b), + '\\leftparen' : ('cmr10', 0x28), + '\\rightbracket' : ('cmr10', 0x5d), + '\\rightparen' : ('cmr10', 0x29), + '\\widebar' : ('cmr10', 0xb9), + ']' : ('cmr10', 0x5d), + + '*' : ('cmsy10', 0xa4), + '\N{MINUS SIGN}' : ('cmsy10', 0xa1), + '\\Downarrow' : ('cmsy10', 0x2b), + '\\Im' : ('cmsy10', 0x3d), + '\\Leftarrow' : ('cmsy10', 0x28), + '\\Leftrightarrow' : ('cmsy10', 0x2c), + '\\P' : ('cmsy10', 0x7b), + '\\Re' : ('cmsy10', 0x3c), + '\\Rightarrow' : ('cmsy10', 0x29), + '\\S' : ('cmsy10', 0x78), + '\\Uparrow' : ('cmsy10', 0x2a), + '\\Updownarrow' : ('cmsy10', 0x6d), + '\\Vert' : ('cmsy10', 0x6b), + '\\aleph' : ('cmsy10', 0x40), + '\\approx' : ('cmsy10', 0xbc), + '\\ast' : ('cmsy10', 0xa4), + '\\asymp' : ('cmsy10', 0xb3), + '\\backslash' : ('cmsy10', 0x6e), + '\\bigcirc' : ('cmsy10', 0xb0), + '\\bigtriangledown' : ('cmsy10', 0x35), + '\\bigtriangleup' : ('cmsy10', 0x34), + '\\bot' : ('cmsy10', 0x3f), + '\\bullet' : ('cmsy10', 0xb2), + '\\cap' : ('cmsy10', 0x5c), + '\\cdot' : ('cmsy10', 0xa2), + '\\circ' : ('cmsy10', 0xb1), + '\\clubsuit' : ('cmsy10', 0x7c), + '\\cup' : ('cmsy10', 0x5b), + '\\dag' : ('cmsy10', 0x79), + '\\dashv' : ('cmsy10', 0x61), + '\\ddag' : ('cmsy10', 0x7a), + '\\diamond' : ('cmsy10', 0xa6), + '\\diamondsuit' : ('cmsy10', 0x7d), + '\\div' : ('cmsy10', 0xa5), + '\\downarrow' : ('cmsy10', 0x23), + '\\emptyset' : ('cmsy10', 0x3b), + '\\equiv' : ('cmsy10', 0xb4), + '\\exists' : ('cmsy10', 0x39), + '\\forall' : ('cmsy10', 0x38), + '\\geq' : ('cmsy10', 0xb8), + '\\gg' : ('cmsy10', 0xc0), + '\\heartsuit' : ('cmsy10', 0x7e), + '\\in' : ('cmsy10', 0x32), + '\\infty' : ('cmsy10', 0x31), + '\\lbrace' : ('cmsy10', 0x66), + '\\lceil' : ('cmsy10', 0x64), + '\\leftarrow' : ('cmsy10', 0xc3), + '\\leftrightarrow' : ('cmsy10', 0x24), + '\\leq' : ('cmsy10', 0x2219), + '\\lfloor' : ('cmsy10', 0x62), + '\\ll' : ('cmsy10', 0xbf), + '\\mid' : ('cmsy10', 0x6a), + '\\mp' : ('cmsy10', 0xa8), + '\\nabla' : ('cmsy10', 0x72), + '\\nearrow' : ('cmsy10', 0x25), + '\\neg' : ('cmsy10', 0x3a), + '\\ni' : ('cmsy10', 0x33), + '\\nwarrow' : ('cmsy10', 0x2d), + '\\odot' : ('cmsy10', 0xaf), + '\\ominus' : ('cmsy10', 0xaa), + '\\oplus' : ('cmsy10', 0xa9), + '\\oslash' : ('cmsy10', 0xae), + '\\otimes' : ('cmsy10', 0xad), + '\\pm' : ('cmsy10', 0xa7), + '\\prec' : ('cmsy10', 0xc1), + '\\preceq' : ('cmsy10', 0xb9), + '\\prime' : ('cmsy10', 0x30), + '\\propto' : ('cmsy10', 0x2f), + '\\rbrace' : ('cmsy10', 0x67), + '\\rceil' : ('cmsy10', 0x65), + '\\rfloor' : ('cmsy10', 0x63), + '\\rightarrow' : ('cmsy10', 0x21), + '\\searrow' : ('cmsy10', 0x26), + '\\sim' : ('cmsy10', 0xbb), + '\\simeq' : ('cmsy10', 0x27), + '\\slash' : ('cmsy10', 0x36), + '\\spadesuit' : ('cmsy10', 0xc4), + '\\sqcap' : ('cmsy10', 0x75), + '\\sqcup' : ('cmsy10', 0x74), + '\\sqsubseteq' : ('cmsy10', 0x76), + '\\sqsupseteq' : ('cmsy10', 0x77), + '\\subset' : ('cmsy10', 0xbd), + '\\subseteq' : ('cmsy10', 0xb5), + '\\succ' : ('cmsy10', 0xc2), + '\\succeq' : ('cmsy10', 0xba), + '\\supset' : ('cmsy10', 0xbe), + '\\supseteq' : ('cmsy10', 0xb6), + '\\swarrow' : ('cmsy10', 0x2e), + '\\times' : ('cmsy10', 0xa3), + '\\to' : ('cmsy10', 0x21), + '\\top' : ('cmsy10', 0x3e), + '\\uparrow' : ('cmsy10', 0x22), + '\\updownarrow' : ('cmsy10', 0x6c), + '\\uplus' : ('cmsy10', 0x5d), + '\\vdash' : ('cmsy10', 0x60), + '\\vee' : ('cmsy10', 0x5f), + '\\vert' : ('cmsy10', 0x6a), + '\\wedge' : ('cmsy10', 0x5e), + '\\wr' : ('cmsy10', 0x6f), + '\\|' : ('cmsy10', 0x6b), + '|' : ('cmsy10', 0x6a), + + '\\_' : ('cmtt10', 0x5f) +} + +# Automatically generated. + +type12uni = { + 'aring' : 229, + 'quotedblright' : 8221, + 'V' : 86, + 'dollar' : 36, + 'four' : 52, + 'Yacute' : 221, + 'P' : 80, + 'underscore' : 95, + 'p' : 112, + 'Otilde' : 213, + 'perthousand' : 8240, + 'zero' : 48, + 'dotlessi' : 305, + 'Scaron' : 352, + 'zcaron' : 382, + 'egrave' : 232, + 'section' : 167, + 'Icircumflex' : 206, + 'ntilde' : 241, + 'ampersand' : 38, + 'dotaccent' : 729, + 'degree' : 176, + 'K' : 75, + 'acircumflex' : 226, + 'Aring' : 197, + 'k' : 107, + 'smalltilde' : 732, + 'Agrave' : 192, + 'divide' : 247, + 'ocircumflex' : 244, + 'asciitilde' : 126, + 'two' : 50, + 'E' : 69, + 'scaron' : 353, + 'F' : 70, + 'bracketleft' : 91, + 'asciicircum' : 94, + 'f' : 102, + 'ordmasculine' : 186, + 'mu' : 181, + 'paragraph' : 182, + 'nine' : 57, + 'v' : 118, + 'guilsinglleft' : 8249, + 'backslash' : 92, + 'six' : 54, + 'A' : 65, + 'icircumflex' : 238, + 'a' : 97, + 'ogonek' : 731, + 'q' : 113, + 'oacute' : 243, + 'ograve' : 242, + 'edieresis' : 235, + 'comma' : 44, + 'otilde' : 245, + 'guillemotright' : 187, + 'ecircumflex' : 234, + 'greater' : 62, + 'uacute' : 250, + 'L' : 76, + 'bullet' : 8226, + 'cedilla' : 184, + 'ydieresis' : 255, + 'l' : 108, + 'logicalnot' : 172, + 'exclamdown' : 161, + 'endash' : 8211, + 'agrave' : 224, + 'Adieresis' : 196, + 'germandbls' : 223, + 'Odieresis' : 214, + 'space' : 32, + 'quoteright' : 8217, + 'ucircumflex' : 251, + 'G' : 71, + 'quoteleft' : 8216, + 'W' : 87, + 'Q' : 81, + 'g' : 103, + 'w' : 119, + 'question' : 63, + 'one' : 49, + 'ring' : 730, + 'figuredash' : 8210, + 'B' : 66, + 'iacute' : 237, + 'Ydieresis' : 376, + 'R' : 82, + 'b' : 98, + 'r' : 114, + 'Ccedilla' : 199, + 'minus' : 8722, + 'Lslash' : 321, + 'Uacute' : 218, + 'yacute' : 253, + 'Ucircumflex' : 219, + 'quotedbl' : 34, + 'onehalf' : 189, + 'Thorn' : 222, + 'M' : 77, + 'eight' : 56, + 'multiply' : 215, + 'grave' : 96, + 'Ocircumflex' : 212, + 'm' : 109, + 'Ugrave' : 217, + 'guilsinglright' : 8250, + 'Ntilde' : 209, + 'questiondown' : 191, + 'Atilde' : 195, + 'ccedilla' : 231, + 'Z' : 90, + 'copyright' : 169, + 'yen' : 165, + 'Eacute' : 201, + 'H' : 72, + 'X' : 88, + 'Idieresis' : 207, + 'bar' : 124, + 'h' : 104, + 'x' : 120, + 'udieresis' : 252, + 'ordfeminine' : 170, + 'braceleft' : 123, + 'macron' : 175, + 'atilde' : 227, + 'Acircumflex' : 194, + 'Oslash' : 216, + 'C' : 67, + 'quotedblleft' : 8220, + 'S' : 83, + 'exclam' : 33, + 'Zcaron' : 381, + 'equal' : 61, + 's' : 115, + 'eth' : 240, + 'Egrave' : 200, + 'hyphen' : 45, + 'period' : 46, + 'igrave' : 236, + 'colon' : 58, + 'Ecircumflex' : 202, + 'trademark' : 8482, + 'Aacute' : 193, + 'cent' : 162, + 'lslash' : 322, + 'c' : 99, + 'N' : 78, + 'breve' : 728, + 'Oacute' : 211, + 'guillemotleft' : 171, + 'n' : 110, + 'idieresis' : 239, + 'braceright' : 125, + 'seven' : 55, + 'brokenbar' : 166, + 'ugrave' : 249, + 'periodcentered' : 183, + 'sterling' : 163, + 'I' : 73, + 'Y' : 89, + 'Eth' : 208, + 'emdash' : 8212, + 'i' : 105, + 'daggerdbl' : 8225, + 'y' : 121, + 'plusminus' : 177, + 'less' : 60, + 'Udieresis' : 220, + 'D' : 68, + 'five' : 53, + 'T' : 84, + 'oslash' : 248, + 'acute' : 180, + 'd' : 100, + 'OE' : 338, + 'Igrave' : 204, + 't' : 116, + 'parenright' : 41, + 'adieresis' : 228, + 'quotesingle' : 39, + 'twodotenleader' : 8229, + 'slash' : 47, + 'ellipsis' : 8230, + 'numbersign' : 35, + 'odieresis' : 246, + 'O' : 79, + 'oe' : 339, + 'o' : 111, + 'Edieresis' : 203, + 'plus' : 43, + 'dagger' : 8224, + 'three' : 51, + 'hungarumlaut' : 733, + 'parenleft' : 40, + 'fraction' : 8260, + 'registered' : 174, + 'J' : 74, + 'dieresis' : 168, + 'Ograve' : 210, + 'j' : 106, + 'z' : 122, + 'ae' : 230, + 'semicolon' : 59, + 'at' : 64, + 'Iacute' : 205, + 'percent' : 37, + 'bracketright' : 93, + 'AE' : 198, + 'asterisk' : 42, + 'aacute' : 225, + 'U' : 85, + 'eacute' : 233, + 'e' : 101, + 'thorn' : 254, + 'u' : 117, +} + +uni2type1 = {v: k for k, v in type12uni.items()} + +# The script below is to sort and format the tex2uni dict + +## For decimal values: int(hex(v), 16) +# newtex = {k: hex(v) for k, v in tex2uni.items()} +# sd = dict(sorted(newtex.items(), key=lambda item: item[0])) +# +## For formatting the sorted dictionary with proper spacing +## the value '24' comes from finding the longest string in +## the newtex keys with len(max(newtex, key=len)) +# for key in sd: +# print("{0:24} : {1: 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⪚yJAnfxidy6F36 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 P{AT5)vUfk$CoTBD#Bj9| literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_path.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_path.pyi new file mode 100644 index 00000000..45690552 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_path.pyi @@ -0,0 +1,9 @@ +from collections.abc import Sequence + +import numpy as np + +from .transforms import BboxBase + +def affine_transform(points: np.ndarray, trans: np.ndarray) -> np.ndarray: ... +def count_bboxes_overlapping_bbox(bbox: BboxBase, bboxes: Sequence[BboxBase]) -> int: ... +def update_path_extents(path, trans, rect, minpos, ignore): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.py new file mode 100644 index 00000000..d32a69d4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.py @@ -0,0 +1,135 @@ +""" +Manage figures for the pyplot interface. +""" + +import atexit +from collections import OrderedDict + + +class Gcf: + """ + Singleton to maintain the relation between figures and their managers, and + keep track of and "active" figure and manager. + + The canvas of a figure created through pyplot is associated with a figure + manager, which handles the interaction between the figure and the backend. + pyplot keeps track of figure managers using an identifier, the "figure + number" or "manager number" (which can actually be any hashable value); + this number is available as the :attr:`number` attribute of the manager. + + This class is never instantiated; it consists of an `OrderedDict` mapping + figure/manager numbers to managers, and a set of class methods that + manipulate this `OrderedDict`. + + Attributes + ---------- + figs : OrderedDict + `OrderedDict` mapping numbers to managers; the active manager is at the + end. + """ + + figs = OrderedDict() + + @classmethod + def get_fig_manager(cls, num): + """ + If manager number *num* exists, make it the active one and return it; + otherwise return *None*. + """ + manager = cls.figs.get(num, None) + if manager is not None: + cls.set_active(manager) + return manager + + @classmethod + def destroy(cls, num): + """ + Destroy manager *num* -- either a manager instance or a manager number. + + In the interactive backends, this is bound to the window "destroy" and + "delete" events. + + It is recommended to pass a manager instance, to avoid confusion when + two managers share the same number. + """ + if all(hasattr(num, attr) for attr in ["num", "destroy"]): + manager = num + if cls.figs.get(manager.num) is manager: + cls.figs.pop(manager.num) + else: + try: + manager = cls.figs.pop(num) + except KeyError: + return + if hasattr(manager, "_cidgcf"): + manager.canvas.mpl_disconnect(manager._cidgcf) + manager.destroy() + del manager, num + + @classmethod + def destroy_fig(cls, fig): + """Destroy figure *fig*.""" + num = next((manager.num for manager in cls.figs.values() + if manager.canvas.figure == fig), None) + if num is not None: + cls.destroy(num) + + @classmethod + def destroy_all(cls): + """Destroy all figures.""" + for manager in list(cls.figs.values()): + manager.canvas.mpl_disconnect(manager._cidgcf) + manager.destroy() + cls.figs.clear() + + @classmethod + def has_fignum(cls, num): + """Return whether figure number *num* exists.""" + return num in cls.figs + + @classmethod + def get_all_fig_managers(cls): + """Return a list of figure managers.""" + return list(cls.figs.values()) + + @classmethod + def get_num_fig_managers(cls): + """Return the number of figures being managed.""" + return len(cls.figs) + + @classmethod + def get_active(cls): + """Return the active manager, or *None* if there is no manager.""" + return next(reversed(cls.figs.values())) if cls.figs else None + + @classmethod + def _set_new_active_manager(cls, manager): + """Adopt *manager* into pyplot and make it the active manager.""" + if not hasattr(manager, "_cidgcf"): + manager._cidgcf = manager.canvas.mpl_connect( + "button_press_event", lambda event: cls.set_active(manager)) + fig = manager.canvas.figure + fig.number = manager.num + label = fig.get_label() + if label: + manager.set_window_title(label) + cls.set_active(manager) + + @classmethod + def set_active(cls, manager): + """Make *manager* the active manager.""" + cls.figs[manager.num] = manager + cls.figs.move_to_end(manager.num) + + @classmethod + def draw_all(cls, force=False): + """ + Redraw all stale managed figures, or, if *force* is True, all managed + figures. + """ + for manager in cls.get_all_fig_managers(): + if force or manager.canvas.figure.stale: + manager.canvas.draw_idle() + + +atexit.register(Gcf.destroy_all) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.pyi new file mode 100644 index 00000000..bdd8cfba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_pylab_helpers.pyi @@ -0,0 +1,29 @@ +from collections import OrderedDict + +from matplotlib.backend_bases import FigureManagerBase +from matplotlib.figure import Figure + +class Gcf: + figs: OrderedDict[int, FigureManagerBase] + @classmethod + def get_fig_manager(cls, num: int) -> FigureManagerBase | None: ... + @classmethod + def destroy(cls, num: int | FigureManagerBase) -> None: ... + @classmethod + def destroy_fig(cls, fig: Figure) -> None: ... + @classmethod + def destroy_all(cls) -> None: ... + @classmethod + def has_fignum(cls, num: int) -> bool: ... + @classmethod + def get_all_fig_managers(cls) -> list[FigureManagerBase]: ... + @classmethod + def get_num_fig_managers(cls) -> int: ... + @classmethod + def get_active(cls) -> FigureManagerBase | None: ... + @classmethod + def _set_new_active_manager(cls, manager: FigureManagerBase) -> None: ... + @classmethod + def set_active(cls, manager: FigureManagerBase) -> None: ... + @classmethod + def draw_all(cls, force: bool = ...) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..9d8b79e14fcd3ae64e18b0332dafcf4dd9a44992 GIT binary patch literal 458136 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

KO#)0}CeA(J&vF^pOMc^A8K= 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
862IohNGVyFPf?h|?q83kO!oPp@-@LcG5X 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

8dH*-KFQY$mRN2>(XOSfD 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%0D4Rc70 zt7r*CGDT~WBl~D`*yEz_SdM5PwIrt2pdYCyF*l+kTzY5*>PsU2V%o@>pb+iu#*vUe zXa`B}bFI&rIi~3_&bo z8j3grh{1}f4F^5MfyG76$1vd-aQdA&w$RB4WM&yKl37F)kyX?_!YLeG-O=Lw9aP)+ z5m>02KPt)i;!txw%Pa|8sb`0Iw6H2fjbxV6;w±6mx}1RNY(Oz~s1^OkMI#${Wf zfCA%f-?4*A2VGP?A>%QI4OzIYSFo@tA21)I{d91xyECQzOW<1OwsR6hSFq1Z}OVtHS3119Jp!Z~NNj!0 zUCCYfmtOepRU0`ZaeIfZe?zEk3y$Wr1BdxVqu+={?%Y0#clf}5MX&)i^grRn zFe4zqA&GC}YrJCerU(2iu^JL)o_Y=b3Gt7=(QCxpd%Gi^%Ila6DrX%O0AZN8*GU>{ z_(mZN*cYu3Ozb&ni~mY7>rL(wDG;KCE*LDM0%r~G4pg?vP?dCAN27Z?pCA=4O)H*# z*x!bQuJ%lQvV|33?Dkv{Vad}7)6)_!CXcwkxtBou?KY0v>pzZ95^I3UOc0i3t! zfu=~P)=T1>jY*W%MB_WU9dEQ1tiTTQaHxxX!KB{!b=-Z_HA1FT@=Bx|f%T4C_T9L9 z`?k@Y{$S57H{NJXs@Mmp3zssPjs+S-2xzn$b1`Cgfd!Pl35TZkgb0e$3eC3_CL~0A z7XTnDO@E`+NPU6Dn_zHb@U_}Bk{fZt-NX@0cEJa(B`G6lre_l*oIzuOIjy{055+gA z0`;pchxW*}9fF8kT!0ZWe8CH~N%&k<1Uo7!;1m`=#OnX@pmMbBx5a43C*Ijb*1?@3Y)cT#2dwW0;sM9ils)ubMx?vIE`+QKy^H1@w5_qR8GWjBofU_JwD`G&v z%T?>eCO*1)jYAhHq!h8>s8+f?n= zFwZZtKo1zCbyR~6*Tf3Ep^AvjfsQ3PNP<5opf&*uZz7!8DL3BG>5++w*(KR~0Tz;S zvI55<+vb6QV!d^vEIh@Rh|em|Vd*RfF*9_+1sBpWvQc8o5i{~OjW{gpm_ovZvQU;o zqzRC%8W&iK8!j_EVhsD&8NpO7(+8ic>q;{k%~?4G4mA0{7m=w&R}kHc>&&<=iU{jF zj5J+p@O%wJ3w4tHv#LmyV3@+pQO{l7zp-Sc-q!*sf}8xso)%px?AG>S0y4y4f#-85D0@ z7u4jM4_yMEL`+<32ulaci}QROd~*Am!7qstUjii~P`Io$FPG^-UHPr~KyKuhL5%Wv z${+?gEJ3F1)4pBvGn}r|1t@HTPksV>`QWZ9R!V}qxuMQo$Qh~W%Kc4ur#E6BGMGuh zm&lcTNsSg=1!-4J?57ky+t~S85zJ<>?zG2Y+vV>rgTW_al47D?;P%27;8Uz!gJ3b% z0BZ>jirR)L5Y#tdL6xuGWHW8jP(i^1Q-?*>7rt?G0|WQ8^m4!ZEcFhT7)}hT?}KAZ zG+ew)`@nrh(uJhqTF0rA?cnw;V3NpbIgZNa#Zy%@VI;^pm@=NkklsCC8#9$R?j7yl ze#`z_ci!Bucbj(f@7sIht9I?(!zXu9CqfXEAVm~9t1r=$BF2I;B;F@x7yxb0(B4pY zmL$Q%p6&8S!OQUrW>1(h42~h+@J6zW)4{vb{By1IK)8~Zk6ytFZQlk=B1P<`BETud70kL$kcp`tps*xRg5gi0egpr zSH4&`=Yk{lP>P=9&qs5BXka@4u2H>%Kxb5OP(snG%I9l9#rv@zX$Rd25l0^)+d zxW?aJL^$<^7xEsPufbXy+%hz{g|F-quRsHT93J|U=pDPj%VnQu53?(&FO+qd(fjZ& z!l>+7h8kPoB?6!vM%mN2McLC{df`{5Lql@01($O1(sYYn3=O3(#gietxQb7P@MmbV zTnueWuhfgp>Ch%z!I6Y>YFE6`XZYv}y}BYD+K8)7=}Y|rff#~E5tJu1TmhRwTx|vl zc5zj@MINB^kX>y_ufih$MBRLZE8gf8Ah1R}00=_G0{|vI_)f3}27>~XC~wp@Zf4sE zjG*vanu$+=8o?155V*28;_MbAV3hhCYD5NVbO`>tEQJpV`Lod*kA&B(2sj?&Jy||Y z=_jf=(wkI*_X#U^-4$Hs2H}^L;Bq13Fun;U)*a$?c>i*Z|u zis)~ceL%H94y2SWx#6*kZM3$V%OM4TAZ^DB-p}u zQEJY@qQ%IoHz4MG?Xc}>pm4=)pu>+?Bva~n$=;RiwO|ax%DWu6;K>}OkTjrzz85Re zU(TU6y79SGr-*lf+$i=vm?2X4k0eiDI<0gkjxRwr=9LtY+yy2 z&e#OvS1Ly1F{w;y=NY0GRHiE`7El;M^IELs8 z_Kz&*AC~-ZPCZ(x&M-*FkR88P@d}KOd`G+tWl@6a!mwpF5SM3DEW1x_B7ci}q{u`W zYv|_$DWbT&+u+j;Zk*g2ex)y>lXt~*x_#d*h)qm@1+^2n?}lwhASy1fxidcF0qH1m z-zRJn0&$%|wssY~Quqc!!&Y)i1+=?SR{6_*E(|!qsRwGKMhylyi{#Fjt0QC}*h1Eq znjms-5}h+bERpiVKkWNysM7Y#9BSk))UKQ1!eeI(*!UJ(!;T;RB!rUa^cCS%A^X43uw*GFAj0 zw-J~+WbZa66?k)H3lWusrCLc zWk}0L0~QnHd?NI2{++i}U$U!9NJ6g6$mpNMbo6IhFBx40lQJoqm^{Hq3nJcuShx@DgRA*~sTrYK>8aU7I6({LQZb&QPM1~`1p(VlqgbJ=^3bciXg*|MC)QLuu zk#jW{3PjV4LRo-f;d)Uh6o!sH_?+XttI%GvDY43v28!*(f^?w8W{asW%qL=oK+Ii& z8H8ZJFod>Cv1P~Pnp0>^7RZC*;H*JAsA7-rDe_Axpa^+)>Q92gW#k1#(HtZuaXp@H z+yPp{MAGfQ=t5_EJn8t%UC4pGNy^fV3Ax^xDRL4BcVUV4A=D29OL^iy0H2vUHU@I@ zw!os@(21GKdv$Ai_0=M3fse9{dyw-6gC=Zt2DTLXbEspDvQAkBa2`dlZO>>ooft$9 zO2q3m9Z1tcfWfaZ1+zZt>LmvMpfN-g$}|b3V;KcPO2OO@t3g$)`ZbGMwp?1zM(JYG zF$xewnoH}b;p`SJ(FAs_lGV*>!e;}6z$++dmxzp$p!MZORX^^mh>W!)jN-#eVaS!@ zoFjc%t%2^G+RLcURTm32TjQK3X#s81{?t$MJqFH+*+z>xg&;xeOhQF72NM;W^@>F* z55nHeUB-y;6?)V)J}KaKkBtY`2KseN@JI}d5X{;pvT)Yy&S7LWH4%n#R%SruFl=k- zKK;mYm_jo;zEYoq8CMwS@r@f%D?}4tID<(2trR<_A`;37I`m}&Rx|<;;{3!_2OC!W zJz-B^ts8m3mR+K9U@8@X-VD1aVWFP)FmoF{DU~owSolDc_62$>l?%PrOSkU3&y_y&>aa&2%adI_%*Ht64Tsqb^`$vNhMLfD|G& z$C8N+8_>~O;T-lmEEM?k)ck4AMzL5<+s#Ly=2YoR~nC4Ix8d132yT^^Bngc)2_=iaSTLpg<^x zo9z*(-XaG&UBW3JnK~;MEE)@A5+C9?!?YW*bFq;o%m>&$Xb;RR@{R5Vy7-j9AkI=d z?7N6|0VVmD5&*UA7YN2YM`IOqXr;WyM%sX;T97%p41%=B$xP^D4y1aEzz+aq5seb< z(oyAHuq*)v?84*i#ezXPt$zzjW{6d!6xad zb7uMYRuapKaePoSvA@E

)g#OrTk+np`uKaXYA!DtqOd+@)+MPj#)KcY9M7Rbd(>IBFdTMH>!>NtVt+iX{3`jGoT-v_QmT;XIOhBQg@MsAN|? zR{~Wm7co_fN>S{tJf-5EwAV$q&JnaJrv}fVkwIEBD8h>1#k1f&=fz}CQAWf5txmJHCb{@kB|G~IFm?*b{5{M8E!#Y=F( zEvae7srg#gMk%^{8<$2z_mAe}D!uk`?wK2{hzs-Cr$i{H38`JyfLZK}c&hk|4gmAq zf%6VqNUf64eTW4p1GCdm02x1Sk$237pi3N5O;Z%;;ww=Am)jR}5i^#}Fo`AiPO@0D z#e=|LJ6Hr|*i_O`zkpM6NGHon(o|5AC&6OYUFM;&!DKTXJiHEvHtueXsy_|}*pP0! zardr0bJf-XdF%8P%n=LXu^TEhkX`bPdUbH;0>ZtDmVL1eGwahxcjOp?Qd3o&U4U+% z)ZH{>0?HaL0ptwIiU?`UOK~HOuq^=WT=a!wMmDFzq-jUq1I%ORV-fybI~*RpF~nBriTZHNSi&~C=Ymk=qA<)K)}QLg zQJuxIT6T_6h+c569ynr)3#iERfXGBbH4q#$f){E^#UG0IEVUHgxL}lm@6wJgA#xzW z>O>+*PN`cqB7jQvweNgR5s%|bmB}4caP$)`N^iwI6 z-RjtbCMih60tOVkajB|n0m2X|&KI+pksQ2yiN$%q=9yB_7}XDZOiTm}d~9~8RnRr8 ze0W2e9_H6J#K#P%(bN4?Z4mY$mjeS9>NU&<6l%)hVj_>u0s3*7pOhE%C&=?2e!A7WDBU>48 zQ6z!_*I->F^F4xpkjN?)51Zn#?7HKB!*iRGO}N@F@p%GlDLJkwq3(nvk`|L>PS;$W zr=y43Jfe*Dz>*ZZ6)_sS3W?idB|=?u<4KJflKHC(Fu@Q}3^M~`oaumimS-fanUJ1i;tMdefZFw8asjs-pBhliI1&j!IXx)i9alrPHTcx*sH1#<3|V;B)MH}%7wG0w;RBDq& zJmRNis90i5Ms=Wa6Wh)q)c1?xx;j}X=A2>V>!6L)AOxTTNKU%;IJTqK~$3gta6GNy2b=h?g97-;pkkvG@MS)r9al#;T zBr#wQ+`4oB=+0M$Ng6To1snQUwo5tY{x`B)A%Pt=3OX|D703!Ct%2lSyNus@L(P2+ zxl`b4Rue?foOzvJArFil42UwFuRJ$Wh8xt1?a{C+njqZqt)9jS>=-Z8vVOQ0WYl&C z%s%C!ruj)}DvUc@8XU6#3`srRg1uy1lYNd#vNIx7(g{Y?RnQ#N6Z~5L#6l(jxg|Bu z<1-fQkUh+U`q4ql)a%6e`kk*#=D}j$ySly3K*Ils%Kv@q)Mez-vy|SanaZ|asK`@n zB5I1s{IqoH($%5X?@cWc4UK+`aOn8TjdhBW5lf~>LnOZ#1Z0^!$0gtGDpNSJRM!Nt zYXPX{-LlP2q@4>R#Y$?;(s0WF`jFFq)Basja;Y#zzJ0l&hDpyH`BKZ073~zoorPZlbuX^)m9_&oqU8dNyMnExk+aS1@#3E%+9JQ zvnH}(2z`cb&O;N+&qp8ReSoGsrv>Sv!AW;xx0G7ib={d7wgHlHAb}+uLJOY8<5K{v z)3Z{D~VGFH1#Due(II2ieCbloN zlTXF5p@6|G0dT3_P~$b3pmvyTm9<7TEb))Ji?(E4g67!oRK_kU1~-iOpah(5JqAO> z_JFl080{J?q=)ukvK-~2-#bsm5;$h6&>|BZsGUlExBI^#L@XJDw#i@>bh27Z^R1ey3|=q~A{0dy&{zk_jJZA0Dnzh#PC!@V`tl1n`mM>|uHDuqGm z5q~;F06Gy{j(R14pE3nYUf1L#tsxBxsnSTW1f9FPGy-qxBuej&q!1Iu9`N%#I za~c&hhO;7zxoeGwc%~{N9oP!kq=B-5k%XVva!FQ00^mpFs-qQ1n-t^Gth*eE?ZY^_ z6}%5vd;*Z!t>cWq2nveqR_K0ca~~5RHky-3TR}^t*)y=QuLICSzSrw8;MM|gmtFmc zOuuegX3bmQZHVb2pgM|1c%la}^chBMIk{dVKp0_BA^K^%dLuRhEAL6e;X@z6APg;r zcoHmb%s)!hNFT_SbZUMPaeT)=-G;;t%wU6sM%$joe7B>S3;v1@wHlZqc;9&!;IxEz*0UaOaqR2U>isaTgGm~GnQxPmE>HWZN zoTha~Bl|)5WlJ+40jy38--I-W%^;-Bnrb~TBu;c|RjUJ*S51&u0b{f25# zNdQRd;$8u&S|f^akGI0LHMZ2v zlGvEw5}{0E(k+&_SY$>nDNs2Z5h8`U`;emG!BP<_)B&Y0gjHV8eT3-}R}nB`%ojpZ zCq9wo9@0A+gK#Kn>NP!WPFK0QmEigAsz~TBT^>prpW~Ut!qpC!fjW#!7H!xN4?Rrl zYVzAIq$tG)#5iRWpcG(0F;fFdSs%$((7MccRrbV06;#)lIJVBlZj|PI3=Z35*}M;I zomvKj5@Om5nnM@4)!SeWtoy>A7~pl~;blN5h9=WQVp&)+K95;I+xK(6%+U8ZHz846 zjiuPJg-kHXbkD&;kA}|!mxWXo>yc-AiF> ziZW{W$+oj3SSDzST%tD>XA%u1b#jv|E{|hd=hRnA$-WubHG}^zxnqXZDWiuVXUU1^ z>1>&UPG^EsJaQnNkG(WxGY!#A#)C_3q9NjzQGqLX?VoJ=A&10aD;Jq2h0w%S+46+i zV9R>*J9JX+ZI+{dbSE%LCq#`L0_cD%WRw=ZNTX|fw$YFe+ z?~Y{!$~jG>-%tXFWdp;~j7QCo(*>5+>6qH0D1X|aDbj6nu#reE&QjWlLjj<8aTFKv z2~!7M)j=2RUHLqfRv21VvvTj*}WC+vyvIH%-h3FM7)aCR}SUM~X1RGEoVovdH z&o3F=iaZC+c#-dr<%HDP`aJbNtZz*n26!sPY#3(vk2pYbb!M7ZSaO69k(NL=pXKoY zo<4?bCdurzqjg3O_klaG+=)j}0SJYm*+7cb913zr-`#t5(f$?m1ts{b81i8F>tLjL ziyhLVX^JtS)Ks-Sr-gh`16(P~nxipJspzP$UXct*bewE=8)mp5aE|GtI@*Vw6?~U! zZm5AeHHI#GDWy{b0k-zpKxQ#?vBa|Kq24nGy%6Q&3Nbsw7H{A{2z5gC4SFo+p)-il z5u1P=9Zet6*b!0YMdaiJ=LQSqc}OesVCqO2thtv!FGzwEq;W)Z?UkoqZ}6qu%@JJ? zxZcO>fCel|;TKp&ZsI62?c70LlEtP{0Je}ErlQ3tQmTC{R4-*boEel{EJRp^ZA%DM zhmY>xwtZ)L9R}I0N%UU+Q)hB52Y1U-HGG7(@56I&pOf2B%cP(ahy}X5D7h!DKb;!H z2;sSsP!$FN=wh9yXeM9hfrH4>M+mtO zGWPTCEqoS4>SR7$T$tq2fFeg&)m>4vo`{<$Nn?~)=L_$b{HTz*5r#gygYq!08B~ z^AN%DI}I8cj$w}re;fK);-UUDAjbI|%ba0{0Ir1-k6hNHV(|`sBozBDBLLShu-==Pk@AEJ>COlpo(NJ5I>p=y67Gm{Zp%N9 z2P_Y@M2&DZR%@>uM6evB<-k9DWVUqHpsXu}BvE39oC8*`Vh9BQsfW_$2^toq)90LV z;8y3|$HiQ6b{QGW)G0HWLKW*}oWuanU^#{(&g>xf8p|G{GJlz`m|f2Vxzv!v-^coiXH z3P65_9EWjW_Eff$1sYC6W$l<4*1b`9M)&*h3^Z~RHuqSvx2hA(Mhhs|h_981tHnuA z8T()@x;;=bSCsaf(US2KwvEYdiYbp8F5-zIzVn(6g|@nwx^^KOT}zCXJaS-&D2SmE z2YJ#AKF-NwZ@d{IpNP841a<+(ip4Q>`IDGCe&PXx8rh!AA z&6iCIv;v&)dazEDQyg@yL|9cSkrSi1(!(_fO*fG$+tkBHWVhYyCGdRt;w%?qaXAC_ zJLJhzVnqrsqGPbsB6xYWNJYP0LN@a#+0aH%SosK<=h+I~Q5WfuDOy1W=CQ@Oy0irL z?-JUrP>+)*7#G@1ndsBDi-1-im6X+x|`F)63A}t^e>Tvbp#?byY6iq(K8VHR>7N3wO4zuK27zR=$W{h^ktMT{73*o~emf=MfP>Ba@ z;auISFB{SF{-W6LGNJ)jX&)$)1qgL-H--rjJi#Vd!W9ywf8%8-^Bj1 z+~%<+9=5y0dGx+l=mbxPD)|&}lG77{4Ftu6sfqbEcgb>lf&++-UA{gNw$|*dQaKA| z;Ow>x3{|QdQyuwXF0evd&%BlJvv5+-7&(ZMzytEEEWr<=BI_}%K22c)d%&A9<0E5; zj@AajTOm+iTZ*3FCmR#PC$_;5ijx(AIaPiN=yS)}25e_Pg|Xa(%EGXb4* z%tl1Za|_*b)qw7E*rcG25K`!X5GHZzawCV;lWVDz3rnR% z+``i?fgS0cW|lw@VDy2_Y^%6*S@o&@j;ODA)n+9TdT`U+Y=1cCvapz>tF62+wOG;^nyf^TbD6gWD@ z4$U!m*qK<<5CI#@=EKSZLhQnnrR~TWD2};nDDpk)qb|T-AYrygFxqSmjO?-ij}^+R zv=&Gi1OB=(Ac-7uNIcDv5NQKyHMeoi9Oe>uRBA1bs$!o92$5ByJ+V}+**=!62d&4+COsr;NT`6UL#mZikdJG1K?cd#3#y9 zqE!i)6y*=6D)^ICo6?#9A_KQQ ze#nJACH*1>2s^5&6hEy9cc}8HQ~tv-6U*?Vu~@?W64j61v>7~e9<>t?eS^kq*094C z&ZGk`L8~YqQ9k)2cQT2!q_5{Qck%F7JDd|rg$ohz@dJq|nJ%Qt6HK|PixpD~;g1+| zm`e{OorOzUyaFWL{h&1f8-ybS_t&Uw%_#Nc0DO(URh zV}om;Q^DAC2-qa(f0}TrLa5E+M!5NaLLHl5bcyd$Lzk24X~O3==-eiXLYU zh0H#|Bd>T1JNE+-We8nS4#0EMgPUhm^P1E*qN<^fi$9oW@!^=3aY)iD<1XwyB|HrE z%s@{T&InJf@2h$`gFog`ZMGA)KeDC%@cIt|vMqIpl${3ln z1TWA;OTik)>mqW6*BuyU@1=u^J~`8v#HyA$I*oC1w{x@@#F5a6^Wzq=nlGH8NAYaf zSb{c1RB}CtIeD*Eqi7Hjnp|0g!ziYBlXLhJ>BWxlLlhCohby2;g2mOfo_%CE;>LUKlrNW6FXD@*)8o)*|j;sMiI^j`How!K3U89_sS;A_( zsn0=YMlQ$rH$A4(q+6Lvh*ARO$2if_gI=+qHL zt_3nWAOqa1xCXc}!>wy6>fR5T@MXJE=IH=Mrj8rDI+{ys_MG+{shU?i#7!Hq^Wm}{Jhf%Z#1gX#A$agGKhi`?_U|yrp80e0;1;1A3Hcx$oKR5`1 zA7zhkC%*Kp_hFEwpg*NiJopHmw>W=bzHw;YIuRQ-BYm{HtsQ?U*L3Es+i9iBG3 zg4T-Oi2CW5Jv=40H!bITSrQQy&0@PIn`On^>WipeLMi5PhuBIQEN_pg#F(2c78fFG zvpA%UI$Cx;luemS7(K_2WkM5e?Jnr^;Ax1x2&bDes#ao5m9qnpfEsu~q*@oFxHh5p z*=Sc}%n`MYfOE0ui^D^prtJC(RnD`~pp7AZ1?lz`&ph=y63Wb~2I*vbd*H`|$6bp_ z#Bbx}@@Es?ZCh&flc<%xeG5n*S~2ETjR>ei5?n#CGyG2Gae_H*3Q^5yX17TWl@5eT z>(G)>SxzB7g(o+S-Zn3TPnZ$qNGG+SaZ9)EBpOxT9oaI&Q}2x}gI9e|y8*tLDt9G{ zyDND*%bIjpN?7(LE>aj7pCbL2WUfqNbzzr}bYgm`z*rt*JM3>K@f$P=!tm;y`}bOI zxLRvjP#_Bn(IC`jfh`d0@sNT#T`wCP7>q{TlS4z$>{h3O(r|yQ&H8rAflxRP>Z#SM zt+D2-+F3!BDM?;pkBRc8`uE&iY)%au0cXdUeS=q~)qplbJyx0RVeRW7xBe?A2ikyDXbb26s4y7@jq*76(z z$lKw4HQ~-ErNkPG!~n!wahE9G!mHXlPYrqy2edq-j`$EEzUUBBD0;W~TeAQf6FhWX zm-I2+!#^RXa+K~+GQBxV5v>TvZOAwzu4(Z4g6Impb@o;mWuY;9WV$i$!wKC{8%@NI z6fOj>@7Z}9PD0@!3J1eR@8pT#_X%7{@fWbnVLiwgxuP+ zlp8J~BV2RQR*ndxiOX;u!<}X;O2Q64SvmZUfC#mxL1W#Lkv68bzAgk_8RJ@vVm_P| zX|jyAa9o{OL@J%guqhom_d=BCWLlwTX3StZVC4<+6hLc3)&bHmlBV#;M(pJkKnFzF zKiuaY%kavDnY|8rdR6wKKvh652)MemwO`x(V^`Pz|j2sCa5LaHCv3le=v~853KmW`j@L$a1WOqym7M^VQUD#_8U^t& zyBFs|VF=e}V|eDF(-nctbTUBc$4beo;&>eva%JyQF`|Id~4AZqyAOPvzw{8Qo>u$(OeX6J^7lzIyco@2mrwC zqM;7Y05ZW2&CcNIO(;?_=1EXCQPW3b;E7pm%)ZmN?wDpzTo5&nWNMjl+PO+ou0o=o z3@Txh#+CF#z}g%-I;I?QApDcH7Q9T!?T4J|;u*|jnod{=aJDrHJ_X*{kQT>)to7gv zSP~mw%vH$@12Knc#a)g1x>bT#m*r}C89MQ)S7F@@tY21u-)Q!4svvLpntWsNcq1Rn zxDI9tiId$1DDUdfFl-{l)LnW4)ihh&L91%VE&FcVy?xv0PC+Y}L@TCWP$MU|&-#jZ zAqU%gg6dzl7^IlyRZ3ju)LI~G(9Pz|LknzA7HzIj*s>l_+Ghr>lG_q*S3(W_pe#3o zpg{^paK#PJvwqxK+Kd4~7j9|GN`Yrz%kW~`n}|JQ8$l3V7{QV#4@}713`Nz{=uxHT z48XM*n$ynSUnve5@$+0_n;=OQrvle7H_gd(T~mKDZuow?F{UL6!xDQD3}NErA$EWf z55np&^;@N?l(vo@o&NB(xG2dVzeL{fIk4 zSAgM#omhjDvnOUkkbgP&!g|OfHo*KVYj>79_y(IW%(o>HCMgv8ogO9gL%OQ9HNlpf z_{ZZXc}Ziv5W6a_8$xf|+OiO45zYhska8jYr+{E>C?9ATiR?wwfzN0pY)#y}Nvulf zAT_fMap`%Yw5}B*QEtN(AX9`a3$z@{x|W1W$cpTp%qfw_D;UrPC$M%nvDvDFlOQV_ zXc{w9OXf@&MTNm&mgr!3CUGfyy3C&WSu7Kk3fi-nVxHvLy*j`P;@pauMj0m9>+?uE z=B|9R4Qz43Q@r`rHS(KxdL_RhY@;|eeu7&$2pz$ zFjqa>8gwXeZa7p=1!ra5BG5D56L)3ZB5)k0x)jtj5eDd@_n;%N&a&P>UU;Z%ISuMa z=Ut@$=jyB3a@0r<@+4?r7-O5tj6c!4e)Mo>Y#3GK(j%%!oru*k`0QKA;jz|E`81kAUfqT{xQu{C*maT6tiF}9TqdGGav&B_-dm7o z(+>L38`!f7=mHw@r~nGm>+x^(m!Dez@@ZBCK?iE&K)bXlscWo@VF8ONqu4| z5t`fq6E;kdr93ZEcd<}Yn+dWZx@d7fnJtFft<$m`C2)h?AM{)79CSq=wQ%3QMjxYR zw@OZ}OqpT5$Z_|z-Vq$s$l$RoOAV5U8H z*~nqYxG9xt46}&-Yf`S85qbeSCX^2NQbpP1MMV{F&G2fA=LLeXF~Q#RPfYNn~`W6=QT@C zrKC2Oh&oWry3v~;{h)=JHo^o4oQRBk3*=eA9@Gs{+41czPQl91Gfk@6)ikM-nuZ75R7$0SadW!Lr~Ku zvkvSiN}4kNH%t1#!7k`RPj;3>7>waFSl^%Zf_>pzXGICbny7_tkY~OQ%^c5Nd-v|} zgTf+bBaCD6jkO8gn1uwDjc3WZSzTmK@QNPStVcA`BnZ$%OG>7+nLR$;im~oi9B{Ng zjN#>rX{p~Ln;eG(U}^sZ z^*jXz%vGS7r6K~9E^=eG4~p?{r~ukxI^29m5EgOpj@GKYgN*m}i~|}GtQ9XazT{>( z3z!LzCr}Z3N7|eJ#!IciHiD;H#@Gu^%3&$>(u8ozhhfEw?*@TtLwdhIBQ7$yX)jWF zENS|B41gg3==6mKGZnD$Y#}&69Wc?Z3EyC5Ujsf+a|37=&oCI^N+fsu_&n^S=Q4`z za&Bfy7UJ*|Tv*&nUyon@Rt+=D%QB~IWS6V~7`fHg;($M{32KUwi}A(!EF@5eFK_@b zpRdiTN&*WA>Bq#Q%SUkd2)2*roMVT|+H5*Xg}wV`?i@(n#yh3p=ssS{Bv?9nQ&8)p zx5>~ei|1s!L9Gm~5R1qY8C^J&8lI?#`Xdobpt*nN{#*7)p{0n@H!_`q6ga~~2Es_> zu@<#a)4^7@Pm~l(v*-tUxovdc$PJQ7e|uwk8aq>Ih91pt8uKHA@~*wur07gZQ$d0t zhIe(Ik;o64{Mg~mC&-^dvsT29ushb=o+B+NL?*mNeo7o|bD$f%UVykEQX@Vl)FnLs`#)CLu~wfR5dtTBYak|pt z@*Pm@CUhojQSHyDH$!8bWy~35Odw_&(aADWO*D|rPzNel(9vw%uKRTYG%$xSj5lU+ z4pVPZ07t!yeLUOU7)g4i_ zC~bIYAr4mKs%z0|vqyA<34=nIk%XPDn`YP`BT9=Whqx7m0ma83kO5CkyV0N<7!cje zO>~uQX!WBn;>{Dq_V-L7xGCJZ#&6ZXg?NkWi*IGaN&Lk``V6Vgznao$Mrr|CaTedV zzzW%_s)=RVF#s3;E~^Zyifvj3oUH-Gn#2f3uE)~3&7km2Tn1jhQ#Sh(8yHOl#?YqP zF>021UzSWU=dg~VN*M48SsxHPlGN!yx(LamXHJ`XOWi6_?l*%=b?Y~I=>DIV`Oo7_R!b{zkZ z@hbE5%bLhda?0x}f-aJnk)sT@j*Z#<3hVlJXwUbi9lIxMY^ny^*HFrXXj zp$<_|=5bjhg=7em*f-kAcD1XRUM9A+X|WriTklw;@$Qp!a!v_vpkjAmXam!RfeloX z%?xLdY*g8Ct#Bwp3U1vZKEZt>Ey%z`OsEup>3Nw<5!|zF|NgzVu?u?>SDb8Ea*)4z zft;UG$Kl$d2r_7>YNt0Pkp-FWl!2dLGL>P;F6)E@O0Z%WA{?Q!fbkL>))h$AGAb<9 z8z4DZcxng*r`_|$ZO2g|d1hH+v(D%SZOE;R)M2*slS$d=GMy)b*ifuK6wNB}OF6cX$YC;7#LS$ozxMA_W?%6RsXt~QyzL(7CiYNo~0mOHikmlh4q5+h^ zUNxAaRnxc=p3KN{I~$FtbDDw~=a|cHPpD~{tHda8!3jqS5r;hA0SxGb=nily(7cmu z2GbZ03|Z3bI4vKYnXgUJSTVzOfEW3v@RL-M)W>YA5X3C2tc*EzVx|K+XTHM0O5|(t zmR1UMOvx9Rxj;=p-3I~w#o-GF$iLB!2WlQg-G~^{`~fOZDI7Fy4i;?0jMd9pyFwsK z;JdO8lX_&d@-3UeD8g9$n@fKraU-ND^abgTJ}vU0Z$%l=N%<-?UXN-N(Lz^aE)V1; zKpM>B8r7ULEmXGkKM+h@nFb|QXp-dtTuzPs;dGAcx=uTXL;GG zeC+<7%PFeofTRHVA(ffH*)`4?sFGg2f7dB@k8;JzF~ zi3W0lKu*fk4g~>1C!_arwP1U7uD!>hdyP3RO~lq;FipZTU7j|AF~L5ODkb01f{hsC zC161G>=Abun3Xnbkd&5F*mMoc+M)Ah%^O_j-o(C9D6~jWoj?rT;tkcEv+bSUD4S&C zt8{xI=&QQY(3b+zhFq&cU1&s}HbOo=U4HP*K}65e7{e0VF$V}JW(s8sZ~dJz4*dTm zct^?zPr)GY10d0vq&)ct7MgfeeKd}&x238157j7hcU$aXh9dyPo|U5zS+%q(?ZiDq zpjxe(i63|V6pQmUT$n%B9GG~m)USQzLaTRTTuR45Y$KVK51hxdIE*wQ=nD(hXmS)M z?vQOm@teU8>rH*Cc8=I0r?4W+D&Qfbnc0di&2E%nGgV<^?y_#uCf0y+Y$=$MM(K8J zRAbawOd5xvM{+MjabOt^4k?mAL}D03a$`u~MS#4Ep)N!6dtgC)7s3;iN?#|bK9jQ) z`M_4XMLZ*6tM1_|mmc<&X2&3MW0l$d`&8AMlCKYFB`OA_E_>HxB!nV!cBHA?5Q&Nt zoTN_2AH5juM(T)h{E*4)s3O>2Y@yo#UF_HXKr_2An;qzfE;QcYaFzkIP6as}wKB=H zePjf!tb=+JUq>R;5DOflH;?7U(J8@2npnuy=m=CW^OfO)kRFCggaW#N-k50>Sohm) zT8}Oi_Wfp{P`p=!1R&7+_V3hrTM`eCm{yqfORPZB4P~Py4w0e1vLUkATXG-dpDI*c z(F~oiMCBmdBWmhawFE=8xpUBkmsOH&H3&ihx&X_Lg?4wzc~kjUa&SPoEFMX^nX_Hi zuONX`+ySoqvtXF$N6sJW@njq-E$U)uSUU|8m_EzZ%@l}>l%|~nu#j18CvpbOK8(mY zn!#EqKGG4^pL#R}UBDFmqB+hXPUJxyr*LRfXrys%iSg9YCZHHTL$FVWL8aNEtcG{g zBZ3|Vepwt)Yy~F+1!56<*w-u?kF17f9b+S(M`Ip4m{borIGOm#Y=%lZnm;1NFgJ~Z zsW8uk368z5z~h@`Yc6`iN{8J$(nHPa0!v7G64V4%p+sW}t+TxLv5ooawPu*)5LiAU zU=X447tYpD|JhCn2_(agt9B}V!947=q%$S0?;=K#^-aR`-D*+8h@%6BHT>4$KI%I1 z8Ad=0K^d#l7{s zyOH;a#Dw`H7~({Uom{^g@b3wo%la*3)zTP_*YpJj?V{%4-C`0OnRL+b_)UspfJBhE z(wM5~4#+|Pl-t^ytZRuoOfLlR{Qhd}w2a_7E&8kRz5j*RH`lrviwzgLYh-{GUl6t1 z&Mod2P|{n9O>P4+R3tS3Q`e&t=$!S6I&UdpY!857YdD-5nTKzPkYr#}tOeO<|Y5YS*KNxqwNK`!j@)UT4;qhAixCLHK@YZX$#!oC(6d2XWRdI7_X^Fs}0x5K|OFres zlb9K|jm1f}%y>1F7ZzKTNY8!aEzD{;9Dp^%t>Zg}AG8%qG!(No|%@SQp4`^^Rnx5CvH_KLinP!IERCDxF#GH37ixmNZ5hT?G|#9^>G#@wEil4 zRdla3;+2)`boOLk%8sCjXEZ5*%_^LRtX}nGQUukM5EMNbJc>n1zV&t^ad(N&L#Yx7 zfh0=-@Iocu2iSrE3)T)N6AOz_{~3w!rTbl;%dOK72%>N^Y#DN-kX3oRc-O&Cqqjq1&UNb#xNJ?1QeN-sZ2sC zPz3}DX_K~rHVH{eTLvwH0)pPEsGz8TsHnh21VKauFA6G3QB+jWs#OtC5KvJN-&%XG zb+U7)_xj#_|L=SM_j10b=lu5BzdfuyPwObYD28I&xcC~2*mF&-2-RG4der6A{4P0& z=dVUVMFkyfs06t>mR_dV{4iGqyZYo#ec8z9SpjFoJfN`;gc@`gxiINcLgPMJ<}jCn zN(a9z+3+=`8th=zh>arDi##jKxfFsS7?fRjh-7qC&kf;W&_fz-U%1FVk;^sMz(xQv zmB?Q(>r-=lbf0aY$sE6;4KpK#J*OQpP_ho;`C40!19p(+x*&SE2;_A5VQCQ-lcbc` zy1utxu`V`2YWj9)$djQR(PB(v@Elqu8VW$aP*_khiw!(g-s0dvZ?9nC3mPkZXJgRo z1+^R{S31Z3iCG;G*G$?g&9c`h@5w#yyuuEDp-SxbxZ*9jK!-I% ze6Dl?Ccg0Cq^x?NWQyHUn51N1U`kZ+IY5mU`JBu@y7zk7>0u;qi_$JoU zg75-lD#{<)OYO=AiXAZ2GZjwPhB}(?r9=312XBBC0agRrQIqu&rz&I|T>iw+gi3(% zrKr3^g&)=K;T)D&(#-)GYhh&@rH&3lBtY?tENyHiO03@bleu5J!aYb`a*~gJfNn0x z-Z8+U|^gUY$G-fxhhj6(9(iWOuS@;a45(_ccc6tJb%9ALibZo*{PasvNi17j~ z{wujg_=$zmFixo<6uMRDvB7sOYN(jdL*16B>O}6VDO}XAuECp7?LehJ)WHq6Z4iQ< z@&u3SMBpXjW?mMA`k3}lcFH~A~1N1%@BmpbuuDh=lCG zh%*>gcw`@s{Xo5j3qjDug@PZ%4^&WT6+`A4k~YMzF;U5}kbgBeL6yP3wWDWxWr!Cd z=sA;O4CNojFj5Mxpr*g3xIvK)&7EUq5pG%eMvF+F8s5U^Yv`;H4TTJjaMfG$TSLlW zI3d+EnFaKQRbCH1Rf`Ek35Ni<=SAcC@k)n8 z70AOpj0N}}(u8t_eGU6EdLE#>g&NwSUSpAp>V>}{hn2o9u_Tp0*3t2=Tu?v7mWUZ0 zCs^U2G0ZN>ObAtk-#g0%x^rcJLH*qBU)h19@_u=SSLA4lu4J4GHXq11!uCxK^3-ym4ckX-qg?oQtn^Ih9A!S7(@&xy~v`|&}@BRJ@ zdmOYYUTgG*TWB?6Ay-T3GPti-pwPJ#)^rC!K_&Nmlp;bEVd$NZ zq#l0RAJwypOl?`(#V}OZ)(aQBfU*{vN(sFPch%^g@vW>4$+H??hAKm{#ZJNzTFDNl zIcCBUPHd)daag=E$laKZ0mFN-sSX_oPf>#{ebUlk&UG^d)=(K!8pse!X3gI#SM?W* zYW_c3mbPHc3U*6{_E^FOteB?ir++eD%OpJm9o+)|@P)u=HPn$r*8L4!c**_eI1!ln>16#3A$ zcG<-zm#=ULLq|5`Fcr7)irEb8=&5_b^x8r0zXXZl8CE9io3~_4z*!#l;`~_|Zux;W zjGCc57-`yMNLl<+FhGO$Af?849A(afU{{QPYjQ{QTpg;XqB?{|QLGi?_E(s}lO0^K zN{2aLuSvvEN;FOe+mO_d2sA8*yc5oVxeSASu^t(2NjPhx#)VovnLV&mt4l#fO}@bH z04u$KNQ;h0sJ*0|gKRkk5OPF_=Wp07f;}^kM8yG|yjRLDOw&Py46b(6FbtH`*hQyP z401LYw?N677p5ik%{e$3BWQZQQHX3`wLGWf_=HW3&+`jQN~|<&9F!g}+tY(7#I4S43xVtXD@c9eBxk=XUx@Jw0yd8Zsbe{ z9a%nAf?B{u-?1iQ*v8+Eno?UTwjuM&@jlG=;a*&koE>Z2%JLWAqZ7L#VJ8rrWylSN zJH;T&IBN|X{Jg=g@>%SALoGna zgU_deA_&mW#QQyFdZ$Bf%qa_LZi0^^(<-J^2@>dy_O;m1QZw{2AiyvW-aD2)_bw_E zM-Cj!Q?yBdjBp!bBJ}7z0Vp`o2*chQ59%iZm0>x~-uOvX)d3zs(2fTzYkI+uV`?$4 z4{Z1*>wlzj?@eDU59pqSEyklaT&K`POJWE3L~+Q2E3DHdDz5YrJAnSCkoB+)1n9b6 zOHtlU>~NFOzIX$L)(LZgNZ|!8Xfvt|807p^0EYkqZv9f=(M+Ff$~*vb6$5A+`ZPH3rJ+X(mw=+8i1VHagg*HweNddA@Dj`6)* zYQ)M#ycWK;L+xV8x^^lt9VJSkEVpt?P)PxFIbiRu#|Z}l^Fxac@+}lU2nRgl#3ob% z8E^wTUevr3t7X73?#ztQH;vO^7c+hj9_OXC*zv+iSE(zv80(o(t)NLQLb$~bD=erp zP&hKc?Wl?v8TxDkbmzbdv|zNC8P@4x2QF0k!j8-;xHYN`n#M|JU=uV>8@mJ8;}&%c z>U0tL0ICsmD9kEUK|&)7u6c{h2R6Y1eAF~Z6$nNg_9en>w3G;9{N}0jPISjY=jYIO z@fAJjl7Y0cP%kJ>jYFZsT1?hkSOlrw4|-)CYR@Uo?=Mm%#p}-(`tr)W#bR@o-rE;0 zP@3UvesWEm~qsE#!V zbX$~;xa>H?>N-S%Izu8MKwq%eL*nj>z$ffQc{wl3o8|rI2WeEK{lAG@wVVLBRlNd$WaVW@FoR_pp4yXHTQ=EH%ti39Z2{THp(JEkz3Ej~&17)63@El@$rcY; zP@p0ML4|;khniB%?}%0hn#ep7H&lfbIb?8C26Ne@=Z@%V;9%#t99d%#(iyQJSS)g? zO>wjXt48Q5f`Y2v&;qHiHQ|ni^{b{k1fO_L7mDRkD7X@Y-_ntXM9_IB6m)Fi@i`wp zrVRT{(>2O&b;3c$gQWKPgX2ih8N2{IOKs^eFTTBshtItoZ3k0^`M$M9HekRN$@ zzZB-MSnU`l2YOH@<%{hkddKT4I30*>&2*)2DMAS&5Y}NAi_4f&vqh+V(zR%z_6ukP zL@>~GToY!`G3WzBlN#tTsz?dtUg%1L8HC%WhFMf4;GhzXSVhQUVF!)~7~=s_!x1L- zGC?!5DTZ`9Z-&NtsTAf7DGUaia`Z)KrHJf!SIT001#eyPP6o>Q}^e5xNbf`1(aEr6cM<`N+6GFi)j59_54~D2RgJgFjWrH=BOpz}{ z6fhTsr88uBk#*G+Hl)yhlR(pZrwxRk2%Vf#R5C5p7-AMu&vj6ACPLnlc@Ls%gZW+9 z@Qd$56@rX1nn}&@kd*nb9Z%H%vNJ2cHz?K32v=ysH6$3EO!wx4YCz0_p-hU7;TA{m zMSMvX8woU%sh%VYrkcZqt5Dryb)bYyoIRJbTohS!MV!i4tU-4Uy@wvSSWd)B7quUT z@~$}0j!epth60Fb$bDql2dJ^F`qBOt-Q?owm^rsnA1_O2mh zSy$|^w29ru`XUi+FVedYI6XyfQ};oPB%r;5yh)$U=2>mU0&IoJhyCm@l7wb60K2O( zeJ}|fg{Zhy&JaTl7%NU3(^ne{y`q9m7P5x=Q6Gq+1jC1_kV>)HxDF}QNs0yz`oMSpDTW;Lv9h4JT!b7qE30lnf;S(p#K|7IhqqqhawuS@Dvc z4sd2XjzeU{Dk{n(>VV0*66;#dACLsCVLd^hjzvyK`jjCBGgeHinf@QsMX<{}*h64(6DsC*uZHf^TgfuLdha}bEX4!VbI23!H$`L7W zKWvs2zcG^r^@F~|&(*0eb(|E&Ub+QtL~6ImDH57_&+NTqEM6^sAPWJQ2}`l6G>(|U6}H-T}lfkwl%BOJfsCx^Qf{x zspiGOU-=0bc_?`7@WDef@_8Y>BRv{1nJLw!jQ1aoCF5;M3P?)|CaS;|-waL>{G~B20thSh;cmUbai= za$O$!2socmvVfvClyE1s zny0;>X7bC_Ms-gx^_Axn`C~?b=oP6-Ct-#xPg=EgXcy?fX=|9|O{~d9hzl;HjrV(@ z94PMK{4@v(R`sFLnFLd6De2BzHF>we!ef!IECu>+t`xi2{Q=p-QD!fOovj6$9kiql zm}no6HC%bbITP&6Wt9yAeH_Iwru62Zx^;sUagJA{n9Hvf!PF*L#5P}SFL2~Lunx2h z7&si~uf$QKw9F>V_f-pAFzs(!~vKkma>KE^i){) zbb50GshDo5!Ejfw&OxQ@=n76A7q-bwcKF=TnFtR94!LPI3%W+o>Br+yps*X73NL*1 zOlCzWQFwgTmZA+AkUd}|>ccfiJ^*E5x(8KmLfrvpPydZYIN}n7RFn4P*dR1Mp78q@i*lCRQcg_7k{1hMz6~$-7^oPV! zm}3F0CoX>ueA+6>mfA5kIXN~~x`nf2HM<2Jk}T*!z{(orJ7Dk?i_Y14+qyuH4vPS` z?sB*s>MV-&M9c^xUqg~ZPZw6NU}j5nZlFsXfT|qFX&?zP?iP;Vhi6<^1%aMpYN1lF zACBP$AE9syYguJ5SLOl5bn+E!;|Dk3<3AAMu`XQs)`JV3C)7y`IWe>^B_Lg*z{BzT z0yr&YOGNEFNw#jVtP9t0oD7BjC|1nT_&YCo7K#U3Hdopl*Zq2>{;7^xJxJo!)uv1OSkl0y@+ z(uOK-TelkR*N`x_Zs7@{VHt%I3*Tobf&9qoCSmCnwtKo}iWf3+PTQEE4LVk~F}b!e zv$Q^~pN^O7wHV=$LCMzsB*H3`)5AkN4@t02`kz={`ckJ5&F zVBxp7ZM0NLK!zf~DSGOW9q{!gu1HFA;RFzl*B~BXo+0*kz^De-enZPAGLe(u=pBAJ zLnDz1LBK?50CEDz8p@O=yX;v1iSp#~gzyyet1%>=(@@T(8M34|xZ-3&jArdeCUuNM5^y%p?QTbeX0zHVs&b9lDEuRi=* z)`wp$@y=Qw-j!<6TKWJ@n*)}E@cU#Q(j>0(S+%K4t?0fMr#+>uGDqPnYoST29cR^I zrbcN|%^GR73R`JWN7`%kmL+Np<2z~Agw9&+rAeBpB3ZL8OV!M_E}9nKU5m2y(`s!R zu31;!s6`DM4e=PO#gvcJuByISvmDLSqJ7ge^X?g%)-wpvnyJ;QcvLg>-LJ(|AJC%a ze5+Z?PiiLHFIv=u+9q?~I;N<^J|>H^pUJd+jLFjMCR1GLWK&eyR8xa>`KH)2(@f@7 zMW(3bx0%fQ?=+cw_nD$M-Dj$|Wtquz>S2>M`B78M^3|p~$Dc8on>}xeUhuq0tJq+w zb7q?<>iiy)xoWQ|rthbwI_vA3W8$wiTPIv?j#}ErY+BmhY`u_Zj*jUF_l{<*yt6sh znrb#xcQw~qHq30Qy3wrd9%ZgoKGAIIJI!n^C^W}a&N9cA-foUgC^uUU-(l9`?=qVb zmzty6E;pMi9y42xK5o`7tun_}uQ8iTpEgG?f7)zWwa#oh|D3s2+5vF;kl9@Mf!Vb7 zBeS;Yh}pdT6SEfcnYs4SW5BI4N3A?(*4CXjTSxwEHdp^<*3Mrv*Dm2uS~kmKshDFiITu>YN&m2Diz+PE@&_zh+=CYDoQEu?s^u1K@FNye_G(L=y)Rj! zmu|CImhH7@E8nnKHtn;R6W_L2tKYGh+rDctRUQO)4_VCC_bu9`4=hnTKe1?Mj#^B% zDob3mrdCVac2?7-j#lgbPFAhDv$gJ-&Q|NlBx`h5lGVI2*{ZEiwZ?X@-x|H3zqRgixFAsHcTj;)AsxqYw5m;?mOwepYDh0UPbp)biY7%>s>Ou@pNxS_e8p<)4f04N78)) z-JNvz(R~ix7twtg-B;0lJ>9p{eJ|ZB>3)>%$LW5a?kq3Vq4IaG*b7o`K|I}sq6qkx zIPmZ3Ye**^>QBLo{q0BQFaIXpZ+4q}FaK-W9y0$sVT{;`NFXAChy)@Mh)5tJfrtbm z5{O73B7ukmA`*y5AR>W?1R@fMNFXAChy)@Mh)5tJfrtbm5{O73B7ukmA`*y5AR>W? z1R@fMNFXAChy)@Mh)5tJfrtbm5{O73B7ukmA`*y5AR>W?1R@fMNFXAChy)@Mh)5tJ zfrtbm5{O73B7ukm{$G|rgH~C-VN(Y9Vs0Lg-CCR4VBplYL&gs9*~ShSH((41=KB8j ztg=B4U!b_qWzR12xwJ7evkk=@aus>~Wd_61GhP0?LT`z| zcxB&|jPz)XHNj8uYi@Z^;}N?9$CI z-L<c8*yQ8qso2!_)N^@Plpxf)w$~T#$ zBR6MuNweE?OG_O&?wMV>!gIiF&nh zRBhD-{hfH@DJe3V+4DZ%rtFAX~k6#jlr%wM{!{g#OfO9&2<#I zwDRp??%8t-rU!!4?M{ck#0>#YLr?61pd)uWzOv^RJN!<+LzqbfdS>y%H9}|`*hq{7U zUbiPG!r_k>?;tzbhj{%(jv$21-&i-x0w;u#O*b0n3Wi)x)QvIgWt1X2O_<4yPWgS5 z*9oNoU-lF)CAJUpyBtARS2XW0%tz-;bL9r@5W)e$pg-izF!46K*at-_(^Z0mEHHxn zJiwoC&vN(!F8OktdzLF3Ur&&)A$cheYW}I1+&6h35uNt2u0U~-2vC760ymBecC*_> z{+kIw@cQjJj)2Ra>n$qsdWMh8>5`Fwc{5nx_m}hcsDNC3(};>?E#qxN0$q8C>su0kiguolhMspAqzRKe7DD* z>j>r+;G1=!H!g^-ZoVmGp67QNoZB9HDdLF^?KYv*>_v{ibf_VO#P&<0fDiLV9+m;L zSV^XOxyW<43-QGfe&L5uulFy(?&McSTi|7I(D5IiM(fs9R zgaAYU79nz#x~Wds#X9jy zMh)>Mfk9LVwi7@m;@ybBe@7u!$!M})nt1Z36+yuVsUR-WLwrO)S5dBfTgA{b z^m#@0K7-FQ0?=0An+u2nt{}NuZb29dm0H%N?du=2cOL&E<7>UQ?NHDt4#k zl6iso0{j+Oms-x$s)%1ycTwCa%lcY7&4(@P%+=B5O)prN)vBy_!Mfj4apU@l>uN9W zwjg#>?K5?@x39LGvhTDWPOOeTT5o%;3-$I#Z;HCmYLm4*c3q?X3!=A2pNZZXR~fe@ zdYG-!w9{Obupr@7)T#J0*PfYH9Xo7Gv-0Qz=2hnSGp0qB1+}VbZR&g=y2`Sw$6Uc##eO8f!g{uvT~NqE^1iGL-WFiPTDpoRwB%bFnZHH25?NZf&NT!F;B3Ga7H zJdE(*=@Q>UcvzvtZo<2ZBrYSo*CX)~!ux#^uOgi7mv|%L!80X(h2P&M@jHZ%E|B;O z!qs<6{3GGYr4nBvJO>+LxMD$_55|A{eG*?wcFO&uiu zj_{TwiGL;R>>_bYEgApp9uhYqymW-bZ3+8EN}Nu3@*If=6JCCs#1jdhx?f@s;jD)w zzL)U&$0UB1uyeJ5}sNq@g>4L4@q3RzKrjd!xA?o-2WqqI}qOV zvBW(ICwwY#2I11rB(@V?^p(VZ!WVv(_%_13FG#$CaMqs^zf5?46m-F72#90B|c4favg~;6CNBV@m2AZzw1ieg7AcT5?@Ey+CbuggtMUEkJnhjJsV2w zV4NWF48mzwOT3WqnI;lHO1NzciJv2!-Adx^gtI0~yqEBVJc$nxuAV0G3Bs4AOZ*4n z#zhiGH<0mdOZZyC<%C-kUO+g7Fzam`Mws<9ItV9{-p190*WE7t+e^4&p2SB9uOxhy z@G8P_SIO{gC)}Fw0m6L|gHt7UOZSEmK0^3b#L%amx>UZOff(AHRT^~k;F?P~-X!t; zgcAv`BRqldtB9da+&)0sKR|dl;V%fY9?Wxyp$=I@dNC6kN?bv>17N2JiTt~$4^Iz z&zSky_y8B)(0>&ppT}D#h|d`9WB73#fEV*sjC>xSX)yA`_%mjHUuc(AzKW60oXS@*@_D?NMtsK1--!=!;Vl#XsTlb@z8pk+#%Leq zN5c=DuVUo$cytW$88hFC4{+fP{Z}#adHkA7e8y-W{V&A_xbTL26(gU=yME#`M*GND z{j14;9v|O9e8xK8kbkWTM*n#{y^Q#bnZFbt;KCdFuVUo$`1@JnGe-Lu{xh<<()lVz zK9AS85uY*h<6&Hb7h?2Z#ln9Y-|uDr2{V6@q5P;A`8*$RnD~sDA7kLF82LPZaGdyz znSTl&;KCb*U&YAh`G#MK&lv5a{MH-fr()#u{6y5%U|+$^?~4y`;SK#)G4gpnqapDb zqkZ)MFh0PAH{`1r`8@y8n)r;-KJpXs0WQ2DU&YAh`I4^0XN>ld?=-|;#mMLRl>x+O z%=~g_bMQip{;L@IJRdWT_>7rfs+1Sxs~Gt_e>0u{rCVE-jJ_irf&uQ0yycNv+GY0=vjC`KYYe0O)%P61)&+ z!ao%wpXdK<#AnR>YJ7kTZ^&0M@_D{6nfQ#+KIWfOsqhaj=BpU_JipkF_>7s~*HC^{ zjC`Jt97TM_%+H2;S@mDV$mjXX9O5%(zFJ>pf}x6$&-0xn#AnR>$%gW;V&wDu=)=Tk z%zPRy>+(}E@_9aWGw~TSztrHrijmLruWt~aG4pA>XUu%HznKY! zDn>r9S6CX$^23<~*F!oGpE2`kx?0bFDn>r9pY$a@ zW9Anc#xE*HKCicoCO%{4pMg0Rybx!?KNTaN*JoVBXUu$GcR|r9=lF@wnE6ga z{iR~$^ZL(x;xlHxnqM*eDn>r97gZ3SG4s=59u_ae$X7A)d3|X$@fkB;Gn79S3qGw! zZDc-S=8wb&xbTMls~Gvbe)S6R8KZsdzu52rF1#UM#mMLNu6@L3jP{XF&6mzsG4gqR z>?7hcX8sv)124qrzlw$bw4U}A`%jqpi|_$1=BpU_y#98c_>7sqz#xAWBcIpn%+Sxq z{wrhVR~h&!Mn13aT}^z(%-;n4YBl^SMn10xCK8`9^G6!|S26N={jfLj88g2MAK=1U zCj3(|@_D^+Eb$qmeN6w|hW1~@$mjJ*2k{v*zuF3pz=at7S26N=J#!ZE88iQg!G9Ga zpVvR{AwFZ~CmH%rDn>r9mp(>(#>_7;lz$Z?pVwD66Q42j)$v{?7^)cgydL`o@fkCJ zvXEX#ekw*juiqXeK4a$hH}F-Ad|vN8M|{T2-))eeiiQ8QJ{;FXmLFa(X1+S#mkEX{ zMn116w5QZe#*y?O-k88iQqA^)iu`Mkb8 ziTI3}A2gI-6(gV5!@b03%=`=Z02kge;h&0;&+F$)iO(4AWBk?j0{JRNKCibwMSRB0 zw;9r3#mMLN`CY_k%>3i{02kiSe-$I2*Ygh(pE26U@GmpSPsPaR_5bgP&zSi(a04&I z=)VmCT!@j+`voo#pE15i|6>gCS26N=e?k4GU|+$^&o=N?jC|gY(3bd&ncue+1OhI^ z7=9HapZ70xBR*rakKx~9=s&3#`Mlp@An_S9{}evJg*WtH#mMLV5o3tY8119~hYj&p zG4gpo#dP8`W`3N3uVUo${)<_}XUzN~ z_jf!_e8y=1@5Gz;TaM!t%X&-+b2BR*s1 z$KeB9ctgI5kJtXBfl~2f2r3D{8KRV z;|=*o#mMLVGA)SDnE63`fD3P#@K43a=lwOQ#Al55G5#YB<3AN6pZDYRCq855C*lKK zctihHjC|g|a})6yqkZ&0$>6_=kj|Aa{B(o- zRE&JypLLG-jG4a)AK=1UCj3(|@_9d3t>&`)GDiCt|7FujG14B4~qXPMn3N^yN>vbncr8^_3*10`Me)(DDfFHe^_Vf0OCyer()#u z{9q%Du#mMLVdTWW#nE99R0WQ2DU&YAh{e7&k&zSj>@c}Np zWx_udBcJytMzw(WDj4l!{4W^7uVUo$e#Wba&zSj3@c}Npq5mpIKJR~QOMJ#?AN}{? z16+7RzKW60`z6ze&lv3^-)RWHijmLzD+dstvChW_xbTMlI~9z4-jA6{e8y-E{f{@S zf2kPxynnNR_>7tFGt57!82P;4b2jlAGk-sX0WZWDeib91_lGVdK4a!r82S$?Mn3N+ zT|<1v%r7B?jC|g&T1kAy%ug_+zlxF1`&&OJK4a#q{?+6^ z?}t4}e8$XI^DFXIjQ;cf*$c#H%>3gb^+M^VV&wCF+gdFlzbTmchYfrcBfoK7tFY0O z_>7s~A0Obt8-`!S$mjjM9f;2u?PLC5Z;-!=k7sa_V>_#6(gVbN3SJ5W9FwB`j09`KJTY~k@$?6f2p^Kz8-%SBcJzQ?;$>8 z=EoS?Ulk*t_iMjPe8$YD?aI3UDn>r<@BWndjG5mUAK=1UCj3(|@_9e_IpQ-$`?IWL-?{vP3kl2?b^CyEFcp*mrRg8Rnf4WWj&zSkL zb_nrRjC|hD-kJD}nXi^t^k2ouuk=V4dk~*7^VRV_@>Ps{-akKt_>7s~*RX$2#mMLV z_EU+^nE9%_(SH>qpZDjN5uY*h%kcp&ydhu3$mjk1FWaR28KZqn|Ks=o7v7MsV&v=l z|80`b80{lp4KMOljC?*XaGv;#nXjfd@>Ps{K3@>qO8U>3`HdkAcp*l?d2Mwjs&UhUwg;ywm^qXADe;5-8^G2lB5c)0;TZ@{|^82ce=_)Zw`B?E2;}!tZnVeE~mA zk1yeO9Dd)!?*#l#!VlBoNBEtA-%s#63%~R5!}Pcazf17D3_o$q5&eLl8Gcsy;Za9C z-WUr%Jhq5O6><23=ichWFCKoFZg>O{j~!xH9*-AZ1HVS_YYe|@;fHD26n@R%*BpL$ z#IPm&Fil&*uQmMIz^^U*+QIJ_ga?mleht5B_=gV?!|xpY;41$G?s$ar z0{k#fS%6;)elhUFqnFrb{ogDrn`Y1h1MmuEQ(!iTRG%qorW8}55Dl=RaEeftP&Gv$ zq-2T=NWByygBCS1Qgx`2QMd**G7Qt77H-Dc)5uiOodzZ~>9Yc3gC;95sZoa&n1{4i z)ueRnFLhbr3tfwq0Ez}TqdqHC=JwxcvZ_%T9OLMt$+NtqlQ z8x_fsxuQmnO+qTL(B$vwj{}=RVI161JsfDX3fJm}1~seMqBp93Eiwuz)*=IgMlCXx zsx~_1Iu0{m0yWFXr~hDu1L=n zE4X4YXdnQg(hBcFmlZys5-WKx)TG*~kiM!b^z4DgD!bD~TGc?29pQkx2sFu+3Yh1} zbp;)uh%Ov~7D9uaT$fOphfWkZO2b}*M!9^i*XeWzq!)R`{$PPC5CqkTLGmV$3#tV{ ztD&^u^}E3}Z*ef-c7o)`H0bxVBZO;L3 z(BH1Y5TAU74$#wvj^shO@O>EYfciZ3WdVd`7ARyyvmDTA=s_)jAXM|kcP}snv0MtABg^Bb@_~HP~Zyu+JzQCBZ za*ExBkmwjAKvD@ABCk{>iH~m7Pc~54!NY{vo#ZnSdxfv$Av?4-= z;&kV_q)Dz9lwk^Eb_B#e)9d$oyl&x#a6(iGAqc?^0f%6Rup+sT_XREoDucxEhYbC0 zXFdf(7>1+-VE_%5kPA?MW;m%^zROz#Wl7H+f?DYIxWpTS?XET279NLe&cq~CVCZ#` z!#`aWhRcy#pkmOOC`2yh>JETLK0UM`q;&K>WTKQ25oi&KZlU)Aqe@1ZlY||VCg(h_ zA7p5ku6SJT{DK^>pHoo@hhD-tbe`g(B9}j3X4hP=uPo0E>hm0+#t#DCZlu-RS=mZg&=g^!3~+q?cQk3o1FmZ{bQ_p&N>?Q@oL`Ks6zeD=5mSo2nLI zK%hbV(wcaLnmXU*@w=SG9;bsUYec!Ou)?W0DLe&rr$M`{HiR?6P{B~s2qR8-ku5_u z+1TO9FLZ^B{h*R}ChEt8LoiDO?i53AX_4d?AQO#8im~^q`<*7Z*Y<6HEo$ zp?#E&quw`V`G!smaXebZJEUMP?P%UAAgjLM^?3yqL1N7GJ@p?or(w)n- zB6RqS!4R3vEn{8mbD|31nv$mGSD?O_x`H5Fkew$e!-t}FK;tOxBDjBLCX){X66z^Z>nWUs=TLNIMsgMUWaH!Vb3PF-M0#VUltk1mjDezY z4~#-^=p~KB2q^Rp24T01>azWQ}n6(UT=%7KQ+S)G4e3zcxG}$tt5_m{boIEg+MEJUkRF=B9?L`6TEs041 zgZp;77#l*W&J-z(G3zRsMN&7paI6~{L0R@X!Pik)BVn)yLn<%SO*y0h**;+G*Z~vm z1G0t-Imjd%*&X{zfebB`{79YY@TcZ^p)vCZQoE+7_MD#Hb6Vkb&aUab>>m4!ywZ|D z;dP}mi_+lA_oQa0=DKrAk^?x3O72mT7fkCivrB5o@8oVNJyW`-is~~}gfh8nTGuo% z3ixwVA#gI}{!|US*In)Ylw2(}SmaAB40=<%A^{=;VOdnE>4O>~3`YjSdfTb@jv@nL z823j8!s^Ia)IgDeurg#3gN4XIIMg|o9aKd^I97-Zghgu;83<3041{r592p2h&sq$V zBLiU^9`VTc|GI&2_{U>#m=zfp{~t6i{{L(sEO)bM+V7vo?S`E^1%P3jmADeX4EC4R z%N84e%wn%u5Z+9n_g*dfbeheqZwV#izqrvk7JMtGd{W@MM=*f*BzNnTEWg^867XtC zFHGv(^>B67${F6x+Yb~E__D=MQ+B**Ub1OykJTd|Kl1s8+t+WN;C=J^yxrE14;`9r z9z7xI&pBJ>%)0Z_SCiqt_pw+Bdc3_LUN z^ZRyAe)HV#9jg2n<}Lc?!AHt(o|$*UvWwFi2gZN&%(V7?*P7V6JGxKU_}kMzUA5w; z>ysXL9B+NYvX8zjzk6PbjkgW<)%RsyI@tWpnRn#0?A$(i&4Y`}8(#GdUq3PYgP%Vu*|W9%xdlDn`Z;RBfwzXg8$0Hn;?rAG&)Fv~|Dw;+`&OS{ zc;Cl2y|L%Sgy<gzd1CqatPS%zuUl%G|M1hj?S0duhPl0GSN8jM;~R+y{$I}4>iX?B=LT=B ztfQ@d`PZhczS2%K9MCnrQQo%EjT>C`!7oWiW{uuzE^FX^)w1u%-gb}eSo`ekqxa6N zb)m`XXMTO~t3B&K9oYEJkpb(SduM%{)AEUrD=J>8<<4vV!*@;YJpA3nUX_!qPtUz? zPIa4k8=pJq@+G`Cv)R;Nrrv*AYo8qW!#wQEesP}t+lJn`d5|ZrPxt8YZ}%8v%D8ys z@`a@QoRjaA7oYg&qz>B-ymqo;-kbxAJ6?Zm+B1Wm-k$bD`4hImlMY>4v3$%O+gsa* z?|1C3J96IkKVE8QsXNZ~@xJu*RxQ@=AM!xV{Lw4lDn5Aj$8Wt&YUd8#GiT=hSK2KZ z*=KHYbb)WC^KzR@_cZ^h@7Q{K4!jySW$NVoC%eZF_Y@`;jJoEv-Pv2d9=-L)zT@6_ zsq6mQ_n(;PoiNyuH?sXlZ{PYt>u-{SQHviqHTP2UTP{uB_>9-qXW`|_E&&M{w1?7#Yz z*sD!{`u@1dKKG5DpKVQhzTJa~Q76t0I(jgD>e3^>Et?hW+p;vR?LCc}t#glluHm27 z4$I?`_pbahxUF{Q9rccvI`?d7JnWMnj=h|{%`>;hVZyvtv*QfU!dDrRgGXI|E7Sw)wRK>kp*MIo# zcaP7z{;ko!z16qf^ltC%Jyz?FhwlAk!q1Iv9*{WqrOFY>8y&r;ly&U&fM?9f#9r~2 zTbK(Ie4iCu^XAaeE!u9n80=K?^XZpbWdG}t_EGa5KV5B`8ccq0M!o0K&g?#a?#|hd zkDHe;V9v1o->aX#b>pFglfTbxI$~V)pJP64-Lzu)+Bf>#7!-9X=|1tv>OU{PXZg7A3+&51@_SF0Ly;#(H*&{1s zn&%(6?w_AL`N?IXTK>? zKV-M7bN`g|il1(o`typsckViU_jQG1r%p}(bbOh&=xm+3QPycU^!#VbdcmD_j-@WF z6V>fP;hK*|A89@Rm+n8ky8q?LzfT@fH0kpP_nzBSbtLoT_Yc&$;g3}}CN$gF_^Z3> z&+B)q_U0>54IHnwJ}}|Q;>M$9RLyNL?t{S#r{`RJ;_Xg*3;%r4_3D|c|CO70cGIf- z@3)@2TD?P`8x z>Fms>%;Uy4yvy;kyYcZoOVXD$-_harGpA!mP2G2>Y2MD4vUb0B?eqsayZ}wwq}!uk z{?fPTrL&!%ov?E9hRm;?e9d%Xlz&}j?D@wYZ~o}*30sd`7}93InmhOWZvJxMS?eA5 z$DU}uuyN%_Qw4Xsn_tPiD|Ts%75}(u+KSt2 z{nl^CsV&#^o;RrW;+7MJG<$H|+r6#hM_6k=cRJ^-XZtKGnd2xp{Qa6`V~1bTYHh3@ zeB-~8_nwX3c*iTwiPH-@cbU`a%iUY=`{s=uj~so;H$1Cq#4&Sj@Tt6uivl~64!zsi z=l*?R@we-HXAIg{In|PTwf*xBrn$Fu-gUlk^8Cl^CJw&;w(U(nNp8PB;XS-W51XFO z@1FPFh_8LozKNfX4UYcu?!4xC@2)#l`t9+mUgwLNtg1|!w)N3@Pk*$n=#4`sA5Onm z@9ebqVn6${^7i8uZ{IRDeM|n&2m5p$ekM?N=#C$Ec=P-1t9@^?AuA4!8(7+WT42(B z|7vmK<8wVSJtwM*KU#Qp)JWI;i+^;S>X13=T*u_+Cl1}*J2(B{z@L&Dr1#HGDy>?0 zXyN-iU!Sny_La9z>XJ-~7;`>f*v5 zXFt)}UGeMsxRf(DeDb`zXR!0l50>2X*7p@XO-IX5Mt#)zp+o&MA4pz&%#vjLsl<`C zb@aY}4F0{=htan<-;VzA?(bfF{N98~@3q(&=-$eb;%PHMd;QhfOP+bKWO29sO&9O! z{%+$|$2)X;XWK(-KG0{qO2Mx&D_1WzGfj z&Fj|IyZ3F=h$T%*R+Me5b@suo!w;;yVZ(xv9$(p0L$4l}`P4VRxjwx-e&MbTug~0N zO3MHGnJ>GHA02zx@?onTuYUX5*-67beth5qQEO8c#N4;GYuaP4u3lLGlLmimKkc60 z@VR>?)cNq|VSmFBTD z^*XwLS8-s+ffw7oTc`b?Tc`9|ylTd<_!$k>%sxET-1j%@!K<1)v2WoIIS(JKUbCQU zcJ7utFYIXY#uR5>uU|IgJ=FT%p0lSc_-6Hiw2+xNC+y*SO8>It?}r{W=gn1_#}57L(_cQQ7&rQy@0FDIv~5|Y z4?k*q_x$98`8_(mF!b()txU_iY-sjJ(hI3iB}_R~E4_Tjo3Ec6I67s)xprl@#ch6I z(C-^+?X|vAyLspCm$kNq&8B?2?xm+!j)U)ZTt4|pzj`0F?Ywl-^pC%vnBVo=1&uR0 zHrRLB)9|_Irn`;}`?6*Kp2vIbTKvwBtxJ}crv7^O_xt8QaQXB32~k7a&HebcLtT3G zog3)>%Gu2ms_$=o@x8&9+%1z=UX}OIn=h|y`hu;ixzGDm4Wky{{X+T6Iri7T_-Ekw zrnQ-wn=9wv+P!kbZR18=GOf?O@kP&#pDuFVllI5G_s!k)Opln_cU+TpW|HNLlh^O~ zWBRdGrw`mdPg|04a?U+%OZzyB8pXG1GPU^Aly;r&IoM*@CxNQB|NQ*1ude@~JoekV zmwxDVZQ8Db>7EG-W{f!G{-x;;?<|d8aB<45e;(*{qPM;C_uF?pea%z%F6gkb%R^t^ z+;3)!i5~>JFZzAawicJ0$3FD%l$Te}zPbB3Z-cAdn|)U~e*4#Y?~eP2lz)BPajt=V z$*XtyE1UhP9s8wd{fVh_ ze$2mR-ME`9o$`{FR1QpRQM%lh{Ga&$?fcQGYkln=+k1b9SDUvVscT1Uo!IWrKVGOv%Iui$>h{5PPi6f4lP9g_Qa zCzx85bsY8K?`to;e{ATidk;TUzsc#tYk%08u<8Eq?)&Dh6ZLLsl=^VWoMmU8T3D~5 zBD1n8;m)7)=X8E%$i0=Xubc3o_0;_Qdk!{xta;3JDFx~I{sPrKazUh@o-Pq X8|8IAoVqFPx{-J1r(gKx<`4b{T>6wj literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_qhull.pyi new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_text_helpers.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_text_helpers.py new file mode 100644 index 00000000..18bfb550 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_text_helpers.py @@ -0,0 +1,74 @@ +""" +Low-level text helper utilities. +""" + +import dataclasses + +from . import _api +from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING + + +LayoutItem = dataclasses.make_dataclass( + "LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"]) + + +def warn_on_missing_glyph(codepoint): + _api.warn_external( + "Glyph {} ({}) missing from current font.".format( + codepoint, + chr(codepoint).encode("ascii", "namereplace").decode("ascii"))) + block = ("Hebrew" if 0x0590 <= codepoint <= 0x05ff else + "Arabic" if 0x0600 <= codepoint <= 0x06ff else + "Devanagari" if 0x0900 <= codepoint <= 0x097f else + "Bengali" if 0x0980 <= codepoint <= 0x09ff else + "Gurmukhi" if 0x0a00 <= codepoint <= 0x0a7f else + "Gujarati" if 0x0a80 <= codepoint <= 0x0aff else + "Oriya" if 0x0b00 <= codepoint <= 0x0b7f else + "Tamil" if 0x0b80 <= codepoint <= 0x0bff else + "Telugu" if 0x0c00 <= codepoint <= 0x0c7f else + "Kannada" if 0x0c80 <= codepoint <= 0x0cff else + "Malayalam" if 0x0d00 <= codepoint <= 0x0d7f else + "Sinhala" if 0x0d80 <= codepoint <= 0x0dff else + None) + if block: + _api.warn_external( + f"Matplotlib currently does not support {block} natively.") + + +def layout(string, font, *, kern_mode=KERNING_DEFAULT): + """ + Render *string* with *font*. For each character in *string*, yield a + (glyph-index, x-position) pair. When such a pair is yielded, the font's + glyph is set to the corresponding character. + + Parameters + ---------- + string : str + The string to be rendered. + font : FT2Font + The font. + kern_mode : int + A FreeType kerning mode. + + Yields + ------ + glyph_index : int + x_position : float + """ + x = 0 + prev_glyph_idx = None + char_to_font = font._get_fontmap(string) + base_font = font + for char in string: + # This has done the fallback logic + font = char_to_font.get(char, base_font) + glyph_idx = font.get_char_index(ord(char)) + kern = ( + base_font.get_kerning(prev_glyph_idx, glyph_idx, kern_mode) / 64 + if prev_glyph_idx is not None else 0. + ) + x += kern + glyph = font.load_glyph(glyph_idx, flags=LOAD_NO_HINTING) + yield LayoutItem(font, char, glyph_idx, x, kern) + x += glyph.linearHoriAdvance / 65536 + prev_glyph_idx = glyph_idx diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_bbox.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_bbox.py new file mode 100644 index 00000000..db72bbdf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_bbox.py @@ -0,0 +1,84 @@ +""" +Helper module for the *bbox_inches* parameter in `.Figure.savefig`. +""" + +from matplotlib.transforms import Bbox, TransformedBbox, Affine2D + + +def adjust_bbox(fig, bbox_inches, fixed_dpi=None): + """ + Temporarily adjust the figure so that only the specified area + (bbox_inches) is saved. + + It modifies fig.bbox, fig.bbox_inches, + fig.transFigure._boxout, and fig.patch. While the figure size + changes, the scale of the original figure is conserved. A + function which restores the original values are returned. + """ + origBbox = fig.bbox + origBboxInches = fig.bbox_inches + _boxout = fig.transFigure._boxout + + old_aspect = [] + locator_list = [] + sentinel = object() + for ax in fig.axes: + locator = ax.get_axes_locator() + if locator is not None: + ax.apply_aspect(locator(ax, None)) + locator_list.append(locator) + current_pos = ax.get_position(original=False).frozen() + ax.set_axes_locator(lambda a, r, _pos=current_pos: _pos) + # override the method that enforces the aspect ratio on the Axes + if 'apply_aspect' in ax.__dict__: + old_aspect.append(ax.apply_aspect) + else: + old_aspect.append(sentinel) + ax.apply_aspect = lambda pos=None: None + + def restore_bbox(): + for ax, loc, aspect in zip(fig.axes, locator_list, old_aspect): + ax.set_axes_locator(loc) + if aspect is sentinel: + # delete our no-op function which un-hides the original method + del ax.apply_aspect + else: + ax.apply_aspect = aspect + + fig.bbox = origBbox + fig.bbox_inches = origBboxInches + fig.transFigure._boxout = _boxout + fig.transFigure.invalidate() + fig.patch.set_bounds(0, 0, 1, 1) + + if fixed_dpi is None: + fixed_dpi = fig.dpi + tr = Affine2D().scale(fixed_dpi) + dpi_scale = fixed_dpi / fig.dpi + + fig.bbox_inches = Bbox.from_bounds(0, 0, *bbox_inches.size) + x0, y0 = tr.transform(bbox_inches.p0) + w1, h1 = fig.bbox.size * dpi_scale + fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1) + fig.transFigure.invalidate() + + fig.bbox = TransformedBbox(fig.bbox_inches, tr) + + fig.patch.set_bounds(x0 / w1, y0 / h1, + fig.bbox.width / w1, fig.bbox.height / h1) + + return restore_bbox + + +def process_figure_for_rasterizing(fig, bbox_inches_restore, fixed_dpi=None): + """ + A function that needs to be called when figure dpi changes during the + drawing (e.g., rasterizing). It recovers the bbox and re-adjust it with + the new dpi. + """ + + bbox_inches, restore_bbox = bbox_inches_restore + restore_bbox() + r = adjust_bbox(fig, bbox_inches, fixed_dpi) + + return bbox_inches, r diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_layout.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_layout.py new file mode 100644 index 00000000..e99ba49b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tight_layout.py @@ -0,0 +1,301 @@ +""" +Routines to adjust subplot params so that subplots are +nicely fit in the figure. In doing so, only axis labels, tick labels, axes +titles and offsetboxes that are anchored to axes are currently considered. + +Internally, this module assumes that the margins (left margin, etc.) which are +differences between ``Axes.get_tightbbox`` and ``Axes.bbox`` are independent of +Axes position. This may fail if ``Axes.adjustable`` is ``datalim`` as well as +such cases as when left or right margin are affected by xlabel. +""" + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, artist as martist +from matplotlib.font_manager import FontProperties +from matplotlib.transforms import Bbox + + +def _auto_adjust_subplotpars( + fig, renderer, shape, span_pairs, subplot_list, + ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None): + """ + Return a dict of subplot parameters to adjust spacing between subplots + or ``None`` if resulting axes would have zero height or width. + + Note that this function ignores geometry information of subplot itself, but + uses what is given by the *shape* and *subplot_list* parameters. Also, the + results could be incorrect if some subplots have ``adjustable=datalim``. + + Parameters + ---------- + shape : tuple[int, int] + Number of rows and columns of the grid. + span_pairs : list[tuple[slice, slice]] + List of rowspans and colspans occupied by each subplot. + subplot_list : list of subplots + List of subplots that will be used to calculate optimal subplot_params. + pad : float + Padding between the figure edge and the edges of subplots, as a + fraction of the font size. + h_pad, w_pad : float + Padding (height/width) between edges of adjacent subplots, as a + fraction of the font size. Defaults to *pad*. + rect : tuple + (left, bottom, right, top), default: None. + """ + rows, cols = shape + + font_size_inch = (FontProperties( + size=mpl.rcParams["font.size"]).get_size_in_points() / 72) + pad_inch = pad * font_size_inch + vpad_inch = h_pad * font_size_inch if h_pad is not None else pad_inch + hpad_inch = w_pad * font_size_inch if w_pad is not None else pad_inch + + if len(span_pairs) != len(subplot_list) or len(subplot_list) == 0: + raise ValueError + + if rect is None: + margin_left = margin_bottom = margin_right = margin_top = None + else: + margin_left, margin_bottom, _right, _top = rect + margin_right = 1 - _right if _right else None + margin_top = 1 - _top if _top else None + + vspaces = np.zeros((rows + 1, cols)) + hspaces = np.zeros((rows, cols + 1)) + + if ax_bbox_list is None: + ax_bbox_list = [ + Bbox.union([ax.get_position(original=True) for ax in subplots]) + for subplots in subplot_list] + + for subplots, ax_bbox, (rowspan, colspan) in zip( + subplot_list, ax_bbox_list, span_pairs): + if all(not ax.get_visible() for ax in subplots): + continue + + bb = [] + for ax in subplots: + if ax.get_visible(): + bb += [martist._get_tightbbox_for_layout_only(ax, renderer)] + + tight_bbox_raw = Bbox.union(bb) + tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw) + + hspaces[rowspan, colspan.start] += ax_bbox.xmin - tight_bbox.xmin # l + hspaces[rowspan, colspan.stop] += tight_bbox.xmax - ax_bbox.xmax # r + vspaces[rowspan.start, colspan] += tight_bbox.ymax - ax_bbox.ymax # t + vspaces[rowspan.stop, colspan] += ax_bbox.ymin - tight_bbox.ymin # b + + fig_width_inch, fig_height_inch = fig.get_size_inches() + + # margins can be negative for axes with aspect applied, so use max(, 0) to + # make them nonnegative. + if not margin_left: + margin_left = max(hspaces[:, 0].max(), 0) + pad_inch/fig_width_inch + suplabel = fig._supylabel + if suplabel and suplabel.get_in_layout(): + rel_width = fig.transFigure.inverted().transform_bbox( + suplabel.get_window_extent(renderer)).width + margin_left += rel_width + pad_inch/fig_width_inch + if not margin_right: + margin_right = max(hspaces[:, -1].max(), 0) + pad_inch/fig_width_inch + if not margin_top: + margin_top = max(vspaces[0, :].max(), 0) + pad_inch/fig_height_inch + if fig._suptitle and fig._suptitle.get_in_layout(): + rel_height = fig.transFigure.inverted().transform_bbox( + fig._suptitle.get_window_extent(renderer)).height + margin_top += rel_height + pad_inch/fig_height_inch + if not margin_bottom: + margin_bottom = max(vspaces[-1, :].max(), 0) + pad_inch/fig_height_inch + suplabel = fig._supxlabel + if suplabel and suplabel.get_in_layout(): + rel_height = fig.transFigure.inverted().transform_bbox( + suplabel.get_window_extent(renderer)).height + margin_bottom += rel_height + pad_inch/fig_height_inch + + if margin_left + margin_right >= 1: + _api.warn_external('Tight layout not applied. The left and right ' + 'margins cannot be made large enough to ' + 'accommodate all axes decorations.') + return None + if margin_bottom + margin_top >= 1: + _api.warn_external('Tight layout not applied. The bottom and top ' + 'margins cannot be made large enough to ' + 'accommodate all axes decorations.') + return None + + kwargs = dict(left=margin_left, + right=1 - margin_right, + bottom=margin_bottom, + top=1 - margin_top) + + if cols > 1: + hspace = hspaces[:, 1:-1].max() + hpad_inch / fig_width_inch + # axes widths: + h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols + if h_axes < 0: + _api.warn_external('Tight layout not applied. tight_layout ' + 'cannot make axes width small enough to ' + 'accommodate all axes decorations') + return None + else: + kwargs["wspace"] = hspace / h_axes + if rows > 1: + vspace = vspaces[1:-1, :].max() + vpad_inch / fig_height_inch + v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows + if v_axes < 0: + _api.warn_external('Tight layout not applied. tight_layout ' + 'cannot make axes height small enough to ' + 'accommodate all axes decorations.') + return None + else: + kwargs["hspace"] = vspace / v_axes + + return kwargs + + +def get_subplotspec_list(axes_list, grid_spec=None): + """ + Return a list of subplotspec from the given list of axes. + + For an instance of axes that does not support subplotspec, None is inserted + in the list. + + If grid_spec is given, None is inserted for those not from the given + grid_spec. + """ + subplotspec_list = [] + for ax in axes_list: + axes_or_locator = ax.get_axes_locator() + if axes_or_locator is None: + axes_or_locator = ax + + if hasattr(axes_or_locator, "get_subplotspec"): + subplotspec = axes_or_locator.get_subplotspec() + if subplotspec is not None: + subplotspec = subplotspec.get_topmost_subplotspec() + gs = subplotspec.get_gridspec() + if grid_spec is not None: + if gs != grid_spec: + subplotspec = None + elif gs.locally_modified_subplot_params(): + subplotspec = None + else: + subplotspec = None + + subplotspec_list.append(subplotspec) + + return subplotspec_list + + +def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, + pad=1.08, h_pad=None, w_pad=None, rect=None): + """ + Return subplot parameters for tight-layouted-figure with specified padding. + + Parameters + ---------- + fig : Figure + axes_list : list of Axes + subplotspec_list : list of `.SubplotSpec` + The subplotspecs of each axes. + renderer : renderer + pad : float + Padding between the figure edge and the edges of subplots, as a + fraction of the font size. + h_pad, w_pad : float + Padding (height/width) between edges of adjacent subplots. Defaults to + *pad*. + rect : tuple (left, bottom, right, top), default: None. + rectangle in normalized figure coordinates + that the whole subplots area (including labels) will fit into. + Defaults to using the entire figure. + + Returns + ------- + subplotspec or None + subplotspec kwargs to be passed to `.Figure.subplots_adjust` or + None if tight_layout could not be accomplished. + """ + + # Multiple axes can share same subplotspec (e.g., if using axes_grid1); + # we need to group them together. + ss_to_subplots = {ss: [] for ss in subplotspec_list} + for ax, ss in zip(axes_list, subplotspec_list): + ss_to_subplots[ss].append(ax) + if ss_to_subplots.pop(None, None): + _api.warn_external( + "This figure includes Axes that are not compatible with " + "tight_layout, so results might be incorrect.") + if not ss_to_subplots: + return {} + subplot_list = list(ss_to_subplots.values()) + ax_bbox_list = [ss.get_position(fig) for ss in ss_to_subplots] + + max_nrows = max(ss.get_gridspec().nrows for ss in ss_to_subplots) + max_ncols = max(ss.get_gridspec().ncols for ss in ss_to_subplots) + + span_pairs = [] + for ss in ss_to_subplots: + # The intent here is to support axes from different gridspecs where + # one's nrows (or ncols) is a multiple of the other (e.g. 2 and 4), + # but this doesn't actually work because the computed wspace, in + # relative-axes-height, corresponds to different physical spacings for + # the 2-row grid and the 4-row grid. Still, this code is left, mostly + # for backcompat. + rows, cols = ss.get_gridspec().get_geometry() + div_row, mod_row = divmod(max_nrows, rows) + div_col, mod_col = divmod(max_ncols, cols) + if mod_row != 0: + _api.warn_external('tight_layout not applied: number of rows ' + 'in subplot specifications must be ' + 'multiples of one another.') + return {} + if mod_col != 0: + _api.warn_external('tight_layout not applied: number of ' + 'columns in subplot specifications must be ' + 'multiples of one another.') + return {} + span_pairs.append(( + slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row), + slice(ss.colspan.start * div_col, ss.colspan.stop * div_col))) + + kwargs = _auto_adjust_subplotpars(fig, renderer, + shape=(max_nrows, max_ncols), + span_pairs=span_pairs, + subplot_list=subplot_list, + ax_bbox_list=ax_bbox_list, + pad=pad, h_pad=h_pad, w_pad=w_pad) + + # kwargs can be none if tight_layout fails... + if rect is not None and kwargs is not None: + # if rect is given, the whole subplots area (including + # labels) will fit into the rect instead of the + # figure. Note that the rect argument of + # *auto_adjust_subplotpars* specify the area that will be + # covered by the total area of axes.bbox. Thus we call + # auto_adjust_subplotpars twice, where the second run + # with adjusted rect parameters. + + left, bottom, right, top = rect + if left is not None: + left += kwargs["left"] + if bottom is not None: + bottom += kwargs["bottom"] + if right is not None: + right -= (1 - kwargs["right"]) + if top is not None: + top -= (1 - kwargs["top"]) + + kwargs = _auto_adjust_subplotpars(fig, renderer, + shape=(max_nrows, max_ncols), + span_pairs=span_pairs, + subplot_list=subplot_list, + ax_bbox_list=ax_bbox_list, + pad=pad, h_pad=h_pad, w_pad=w_pad, + rect=(left, bottom, right, top)) + + return kwargs diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..63d85010570bd2536263786eb49c40b2fd27170f GIT binary patch literal 275750 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

    uIe^cbwcry$J6m#wU|n3zpUS`z?8+ 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 Qu-7-QUp%t~5C8xG literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.pyi new file mode 100644 index 00000000..cab7fcf2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_tri.pyi @@ -0,0 +1,23 @@ +# This is a private module implemented in C++ +# As such these type stubs are overly generic, but here to allow these types +# as return types for public methods +from typing import Any + +class TrapezoidMapTriFinder: + def __init__(self, *args, **kwargs) -> None: ... + def find_many(self, *args, **kwargs) -> Any: ... + def get_tree_stats(self, *args, **kwargs) -> Any: ... + def initialize(self, *args, **kwargs) -> Any: ... + def print_tree(self, *args, **kwargs) -> Any: ... + +class TriContourGenerator: + def __init__(self, *args, **kwargs) -> None: ... + def create_contour(self, *args, **kwargs) -> Any: ... + def create_filled_contour(self, *args, **kwargs) -> Any: ... + +class Triangulation: + def __init__(self, *args, **kwargs) -> None: ... + def calculate_plane_coefficients(self, *args, **kwargs) -> Any: ... + def get_edges(self, *args, **kwargs) -> Any: ... + def get_neighbors(self, *args, **kwargs) -> Any: ... + def set_mask(self, *args, **kwargs) -> Any: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..19fbcad829ae8a14fe621416db678796c314e5c3 GIT binary patch literal 165337 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

    " % self.uuid)) + try: + self.comm = Comm('matplotlib', data={'id': self.uuid}) + except AttributeError as err: + raise RuntimeError('Unable to create an IPython notebook Comm ' + 'instance. Are you in the IPython ' + 'notebook?') from err + self.comm.on_msg(self.on_message) + + manager = self.manager + self._ext_close = False + + def _on_close(close_message): + self._ext_close = True + manager.remove_comm(close_message['content']['comm_id']) + manager.clearup_closed() + + self.comm.on_close(_on_close) + + def is_open(self): + return not (self._ext_close or self.comm._closed) + + def on_close(self): + # When the socket is closed, deregister the websocket with + # the FigureManager. + if self.is_open(): + try: + self.comm.close() + except KeyError: + # apparently already cleaned it up? + pass + + def send_json(self, content): + self.comm.send({'data': json.dumps(content)}) + + def send_binary(self, blob): + if self.supports_binary: + self.comm.send({'blob': 'image/png'}, buffers=[blob]) + else: + # The comm is ASCII, so we send the image in base64 encoded data + # URL form. + data = b64encode(blob).decode('ascii') + data_uri = f"data:image/png;base64,{data}" + self.comm.send({'data': data_uri}) + + def on_message(self, message): + # The 'supports_binary' message is relevant to the + # websocket itself. The other messages get passed along + # to matplotlib as-is. + + # Every message has a "type" and a "figure_id". + message = json.loads(message['content']['data']) + if message['type'] == 'closing': + self.on_close() + self.manager.clearup_closed() + elif message['type'] == 'supports_binary': + self.supports_binary = message['value'] + else: + self.manager.handle_json(message) + + +@_Backend.export +class _BackendNbAgg(_Backend): + FigureCanvas = FigureCanvasNbAgg + FigureManager = FigureManagerNbAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pdf.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pdf.py new file mode 100644 index 00000000..aa488313 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pdf.py @@ -0,0 +1,2827 @@ +""" +A PDF Matplotlib backend. + +Author: Jouni K Seppänen and others. +""" + +import codecs +from datetime import timezone +from datetime import datetime +from enum import Enum +from functools import total_ordering +from io import BytesIO +import itertools +import logging +import math +import os +import string +import struct +import sys +import time +import types +import warnings +import zlib + +import numpy as np +from PIL import Image + +import matplotlib as mpl +from matplotlib import _api, _text_helpers, _type1font, cbook, dviread +from matplotlib._pylab_helpers import Gcf +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) +from matplotlib.backends.backend_mixed import MixedModeRenderer +from matplotlib.figure import Figure +from matplotlib.font_manager import get_font, fontManager as _fontManager +from matplotlib._afm import AFM +from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, + LOAD_NO_HINTING, KERNING_UNFITTED, FT2Font) +from matplotlib.transforms import Affine2D, BboxBase +from matplotlib.path import Path +from matplotlib.dates import UTC +from matplotlib import _path +from . import _backend_pdf_ps + +_log = logging.getLogger(__name__) + +# Overview +# +# The low-level knowledge about pdf syntax lies mainly in the pdfRepr +# function and the classes Reference, Name, Operator, and Stream. The +# PdfFile class knows about the overall structure of pdf documents. +# It provides a "write" method for writing arbitrary strings in the +# file, and an "output" method that passes objects through the pdfRepr +# function before writing them in the file. The output method is +# called by the RendererPdf class, which contains the various draw_foo +# methods. RendererPdf contains a GraphicsContextPdf instance, and +# each draw_foo calls self.check_gc before outputting commands. This +# method checks whether the pdf graphics state needs to be modified +# and outputs the necessary commands. GraphicsContextPdf represents +# the graphics state, and its "delta" method returns the commands that +# modify the state. + +# Add "pdf.use14corefonts: True" in your configuration file to use only +# the 14 PDF core fonts. These fonts do not need to be embedded; every +# PDF viewing application is required to have them. This results in very +# light PDF files you can use directly in LaTeX or ConTeXt documents +# generated with pdfTeX, without any conversion. + +# These fonts are: Helvetica, Helvetica-Bold, Helvetica-Oblique, +# Helvetica-BoldOblique, Courier, Courier-Bold, Courier-Oblique, +# Courier-BoldOblique, Times-Roman, Times-Bold, Times-Italic, +# Times-BoldItalic, Symbol, ZapfDingbats. +# +# Some tricky points: +# +# 1. The clip path can only be widened by popping from the state +# stack. Thus the state must be pushed onto the stack before narrowing +# the clip path. This is taken care of by GraphicsContextPdf. +# +# 2. Sometimes it is necessary to refer to something (e.g., font, +# image, or extended graphics state, which contains the alpha value) +# in the page stream by a name that needs to be defined outside the +# stream. PdfFile provides the methods fontName, imageObject, and +# alphaState for this purpose. The implementations of these methods +# should perhaps be generalized. + +# TODOs: +# +# * encoding of fonts, including mathtext fonts and Unicode support +# * TTF support has lots of small TODOs, e.g., how do you know if a font +# is serif/sans-serif, or symbolic/non-symbolic? +# * draw_quad_mesh + + +def _fill(strings, linelen=75): + """ + Make one string from sequence of strings, with whitespace in between. + + The whitespace is chosen to form lines of at most *linelen* characters, + if possible. + """ + currpos = 0 + lasti = 0 + result = [] + for i, s in enumerate(strings): + length = len(s) + if currpos + length < linelen: + currpos += length + 1 + else: + result.append(b' '.join(strings[lasti:i])) + lasti = i + currpos = length + result.append(b' '.join(strings[lasti:])) + return b'\n'.join(result) + + +def _create_pdf_info_dict(backend, metadata): + """ + Create a PDF infoDict based on user-supplied metadata. + + A default ``Creator``, ``Producer``, and ``CreationDate`` are added, though + the user metadata may override it. The date may be the current time, or a + time set by the ``SOURCE_DATE_EPOCH`` environment variable. + + Metadata is verified to have the correct keys and their expected types. Any + unknown keys/types will raise a warning. + + Parameters + ---------- + backend : str + The name of the backend to use in the Producer value. + + metadata : dict[str, Union[str, datetime, Name]] + A dictionary of metadata supplied by the user with information + following the PDF specification, also defined in + `~.backend_pdf.PdfPages` below. + + If any value is *None*, then the key will be removed. This can be used + to remove any pre-defined values. + + Returns + ------- + dict[str, Union[str, datetime, Name]] + A validated dictionary of metadata. + """ + + # get source date from SOURCE_DATE_EPOCH, if set + # See https://reproducible-builds.org/specs/source-date-epoch/ + source_date_epoch = os.getenv("SOURCE_DATE_EPOCH") + if source_date_epoch: + source_date = datetime.fromtimestamp(int(source_date_epoch), timezone.utc) + source_date = source_date.replace(tzinfo=UTC) + else: + source_date = datetime.today() + + info = { + 'Creator': f'Matplotlib v{mpl.__version__}, https://matplotlib.org', + 'Producer': f'Matplotlib {backend} backend v{mpl.__version__}', + 'CreationDate': source_date, + **metadata + } + info = {k: v for (k, v) in info.items() if v is not None} + + def is_string_like(x): + return isinstance(x, str) + is_string_like.text_for_warning = "an instance of str" + + def is_date(x): + return isinstance(x, datetime) + is_date.text_for_warning = "an instance of datetime.datetime" + + def check_trapped(x): + if isinstance(x, Name): + return x.name in (b'True', b'False', b'Unknown') + else: + return x in ('True', 'False', 'Unknown') + check_trapped.text_for_warning = 'one of {"True", "False", "Unknown"}' + + keywords = { + 'Title': is_string_like, + 'Author': is_string_like, + 'Subject': is_string_like, + 'Keywords': is_string_like, + 'Creator': is_string_like, + 'Producer': is_string_like, + 'CreationDate': is_date, + 'ModDate': is_date, + 'Trapped': check_trapped, + } + for k in info: + if k not in keywords: + _api.warn_external(f'Unknown infodict keyword: {k!r}. ' + f'Must be one of {set(keywords)!r}.') + elif not keywords[k](info[k]): + _api.warn_external(f'Bad value for infodict keyword {k}. ' + f'Got {info[k]!r} which is not ' + f'{keywords[k].text_for_warning}.') + if 'Trapped' in info: + info['Trapped'] = Name(info['Trapped']) + + return info + + +def _datetime_to_pdf(d): + """ + Convert a datetime to a PDF string representing it. + + Used for PDF and PGF. + """ + r = d.strftime('D:%Y%m%d%H%M%S') + z = d.utcoffset() + if z is not None: + z = z.seconds + else: + if time.daylight: + z = time.altzone + else: + z = time.timezone + if z == 0: + r += 'Z' + elif z < 0: + r += "+%02d'%02d'" % ((-z) // 3600, (-z) % 3600) + else: + r += "-%02d'%02d'" % (z // 3600, z % 3600) + return r + + +def _calculate_quad_point_coordinates(x, y, width, height, angle=0): + """ + Calculate the coordinates of rectangle when rotated by angle around x, y + """ + + angle = math.radians(-angle) + sin_angle = math.sin(angle) + cos_angle = math.cos(angle) + a = x + height * sin_angle + b = y + height * cos_angle + c = x + width * cos_angle + height * sin_angle + d = y - width * sin_angle + height * cos_angle + e = x + width * cos_angle + f = y - width * sin_angle + return ((x, y), (e, f), (c, d), (a, b)) + + +def _get_coordinates_of_block(x, y, width, height, angle=0): + """ + Get the coordinates of rotated rectangle and rectangle that covers the + rotated rectangle. + """ + + vertices = _calculate_quad_point_coordinates(x, y, width, + height, angle) + + # Find min and max values for rectangle + # adjust so that QuadPoints is inside Rect + # PDF docs says that QuadPoints should be ignored if any point lies + # outside Rect, but for Acrobat it is enough that QuadPoints is on the + # border of Rect. + + pad = 0.00001 if angle % 90 else 0 + min_x = min(v[0] for v in vertices) - pad + min_y = min(v[1] for v in vertices) - pad + max_x = max(v[0] for v in vertices) + pad + max_y = max(v[1] for v in vertices) + pad + return (tuple(itertools.chain.from_iterable(vertices)), + (min_x, min_y, max_x, max_y)) + + +def _get_link_annotation(gc, x, y, width, height, angle=0): + """ + Create a link annotation object for embedding URLs. + """ + quadpoints, rect = _get_coordinates_of_block(x, y, width, height, angle) + link_annotation = { + 'Type': Name('Annot'), + 'Subtype': Name('Link'), + 'Rect': rect, + 'Border': [0, 0, 0], + 'A': { + 'S': Name('URI'), + 'URI': gc.get_url(), + }, + } + if angle % 90: + # Add QuadPoints + link_annotation['QuadPoints'] = quadpoints + return link_annotation + + +# PDF strings are supposed to be able to include any eight-bit data, except +# that unbalanced parens and backslashes must be escaped by a backslash. +# However, sf bug #2708559 shows that the carriage return character may get +# read as a newline; these characters correspond to \gamma and \Omega in TeX's +# math font encoding. Escaping them fixes the bug. +_str_escapes = str.maketrans({ + '\\': '\\\\', '(': '\\(', ')': '\\)', '\n': '\\n', '\r': '\\r'}) + + +def pdfRepr(obj): + """Map Python objects to PDF syntax.""" + + # Some objects defined later have their own pdfRepr method. + if hasattr(obj, 'pdfRepr'): + return obj.pdfRepr() + + # Floats. PDF does not have exponential notation (1.0e-10) so we + # need to use %f with some precision. Perhaps the precision + # should adapt to the magnitude of the number? + elif isinstance(obj, (float, np.floating)): + if not np.isfinite(obj): + raise ValueError("Can only output finite numbers in PDF") + r = b"%.10f" % obj + return r.rstrip(b'0').rstrip(b'.') + + # Booleans. Needs to be tested before integers since + # isinstance(True, int) is true. + elif isinstance(obj, bool): + return [b'false', b'true'][obj] + + # Integers are written as such. + elif isinstance(obj, (int, np.integer)): + return b"%d" % obj + + # Non-ASCII Unicode strings are encoded in UTF-16BE with byte-order mark. + elif isinstance(obj, str): + return pdfRepr(obj.encode('ascii') if obj.isascii() + else codecs.BOM_UTF16_BE + obj.encode('UTF-16BE')) + + # Strings are written in parentheses, with backslashes and parens + # escaped. Actually balanced parens are allowed, but it is + # simpler to escape them all. TODO: cut long strings into lines; + # I believe there is some maximum line length in PDF. + # Despite the extra decode/encode, translate is faster than regex. + elif isinstance(obj, bytes): + return ( + b'(' + + obj.decode('latin-1').translate(_str_escapes).encode('latin-1') + + b')') + + # Dictionaries. The keys must be PDF names, so if we find strings + # there, we make Name objects from them. The values may be + # anything, so the caller must ensure that PDF names are + # represented as Name objects. + elif isinstance(obj, dict): + return _fill([ + b"<<", + *[Name(k).pdfRepr() + b" " + pdfRepr(v) for k, v in obj.items()], + b">>", + ]) + + # Lists. + elif isinstance(obj, (list, tuple)): + return _fill([b"[", *[pdfRepr(val) for val in obj], b"]"]) + + # The null keyword. + elif obj is None: + return b'null' + + # A date. + elif isinstance(obj, datetime): + return pdfRepr(_datetime_to_pdf(obj)) + + # A bounding box + elif isinstance(obj, BboxBase): + return _fill([pdfRepr(val) for val in obj.bounds]) + + else: + raise TypeError(f"Don't know a PDF representation for {type(obj)} " + "objects") + + +def _font_supports_glyph(fonttype, glyph): + """ + Returns True if the font is able to provide codepoint *glyph* in a PDF. + + For a Type 3 font, this method returns True only for single-byte + characters. For Type 42 fonts this method return True if the character is + from the Basic Multilingual Plane. + """ + if fonttype == 3: + return glyph <= 255 + if fonttype == 42: + return glyph <= 65535 + raise NotImplementedError() + + +class Reference: + """ + PDF reference object. + + Use PdfFile.reserveObject() to create References. + """ + + def __init__(self, id): + self.id = id + + def __repr__(self): + return "" % self.id + + def pdfRepr(self): + return b"%d 0 R" % self.id + + def write(self, contents, file): + write = file.write + write(b"%d 0 obj\n" % self.id) + write(pdfRepr(contents)) + write(b"\nendobj\n") + + +@total_ordering +class Name: + """PDF name object.""" + __slots__ = ('name',) + _hexify = {c: '#%02x' % c + for c in {*range(256)} - {*range(ord('!'), ord('~') + 1)}} + + def __init__(self, name): + if isinstance(name, Name): + self.name = name.name + else: + if isinstance(name, bytes): + name = name.decode('ascii') + self.name = name.translate(self._hexify).encode('ascii') + + def __repr__(self): + return "" % self.name + + def __str__(self): + return '/' + self.name.decode('ascii') + + def __eq__(self, other): + return isinstance(other, Name) and self.name == other.name + + def __lt__(self, other): + return isinstance(other, Name) and self.name < other.name + + def __hash__(self): + return hash(self.name) + + def pdfRepr(self): + return b'/' + self.name + + +class Verbatim: + """Store verbatim PDF command content for later inclusion in the stream.""" + def __init__(self, x): + self._x = x + + def pdfRepr(self): + return self._x + + +class Op(Enum): + """PDF operators (not an exhaustive list).""" + + close_fill_stroke = b'b' + fill_stroke = b'B' + fill = b'f' + closepath = b'h' + close_stroke = b's' + stroke = b'S' + endpath = b'n' + begin_text = b'BT' + end_text = b'ET' + curveto = b'c' + rectangle = b're' + lineto = b'l' + moveto = b'm' + concat_matrix = b'cm' + use_xobject = b'Do' + setgray_stroke = b'G' + setgray_nonstroke = b'g' + setrgb_stroke = b'RG' + setrgb_nonstroke = b'rg' + setcolorspace_stroke = b'CS' + setcolorspace_nonstroke = b'cs' + setcolor_stroke = b'SCN' + setcolor_nonstroke = b'scn' + setdash = b'd' + setlinejoin = b'j' + setlinecap = b'J' + setgstate = b'gs' + gsave = b'q' + grestore = b'Q' + textpos = b'Td' + selectfont = b'Tf' + textmatrix = b'Tm' + show = b'Tj' + showkern = b'TJ' + setlinewidth = b'w' + clip = b'W' + shading = b'sh' + + def pdfRepr(self): + return self.value + + @classmethod + def paint_path(cls, fill, stroke): + """ + Return the PDF operator to paint a path. + + Parameters + ---------- + fill : bool + Fill the path with the fill color. + stroke : bool + Stroke the outline of the path with the line color. + """ + if stroke: + if fill: + return cls.fill_stroke + else: + return cls.stroke + else: + if fill: + return cls.fill + else: + return cls.endpath + + +class Stream: + """ + PDF stream object. + + This has no pdfRepr method. Instead, call begin(), then output the + contents of the stream by calling write(), and finally call end(). + """ + __slots__ = ('id', 'len', 'pdfFile', 'file', 'compressobj', 'extra', 'pos') + + def __init__(self, id, len, file, extra=None, png=None): + """ + Parameters + ---------- + id : int + Object id of the stream. + len : Reference or None + An unused Reference object for the length of the stream; + None means to use a memory buffer so the length can be inlined. + file : PdfFile + The underlying object to write the stream to. + extra : dict from Name to anything, or None + Extra key-value pairs to include in the stream header. + png : dict or None + If the data is already png encoded, the decode parameters. + """ + self.id = id # object id + self.len = len # id of length object + self.pdfFile = file + self.file = file.fh # file to which the stream is written + self.compressobj = None # compression object + if extra is None: + self.extra = dict() + else: + self.extra = extra.copy() + if png is not None: + self.extra.update({'Filter': Name('FlateDecode'), + 'DecodeParms': png}) + + self.pdfFile.recordXref(self.id) + if mpl.rcParams['pdf.compression'] and not png: + self.compressobj = zlib.compressobj( + mpl.rcParams['pdf.compression']) + if self.len is None: + self.file = BytesIO() + else: + self._writeHeader() + self.pos = self.file.tell() + + def _writeHeader(self): + write = self.file.write + write(b"%d 0 obj\n" % self.id) + dict = self.extra + dict['Length'] = self.len + if mpl.rcParams['pdf.compression']: + dict['Filter'] = Name('FlateDecode') + + write(pdfRepr(dict)) + write(b"\nstream\n") + + def end(self): + """Finalize stream.""" + + self._flush() + if self.len is None: + contents = self.file.getvalue() + self.len = len(contents) + self.file = self.pdfFile.fh + self._writeHeader() + self.file.write(contents) + self.file.write(b"\nendstream\nendobj\n") + else: + length = self.file.tell() - self.pos + self.file.write(b"\nendstream\nendobj\n") + self.pdfFile.writeObject(self.len, length) + + def write(self, data): + """Write some data on the stream.""" + + if self.compressobj is None: + self.file.write(data) + else: + compressed = self.compressobj.compress(data) + self.file.write(compressed) + + def _flush(self): + """Flush the compression object.""" + + if self.compressobj is not None: + compressed = self.compressobj.flush() + self.file.write(compressed) + self.compressobj = None + + +def _get_pdf_charprocs(font_path, glyph_ids): + font = get_font(font_path, hinting_factor=1) + conv = 1000 / font.units_per_EM # Conversion to PS units (1/1000's). + procs = {} + for glyph_id in glyph_ids: + g = font.load_glyph(glyph_id, LOAD_NO_SCALE) + # NOTE: We should be using round(), but instead use + # "(x+.5).astype(int)" to keep backcompat with the old ttconv code + # (this is different for negative x's). + d1 = (np.array([g.horiAdvance, 0, *g.bbox]) * conv + .5).astype(int) + v, c = font.get_path() + v = (v * 64).astype(int) # Back to TrueType's internal units (1/64's). + # Backcompat with old ttconv code: control points between two quads are + # omitted if they are exactly at the midpoint between the control of + # the quad before and the quad after, but ttconv used to interpolate + # *after* conversion to PS units, causing floating point errors. Here + # we reproduce ttconv's logic, detecting these "implicit" points and + # re-interpolating them. Note that occasionally (e.g. with DejaVu Sans + # glyph "0") a point detected as "implicit" is actually explicit, and + # will thus be shifted by 1. + quads, = np.nonzero(c == 3) + quads_on = quads[1::2] + quads_mid_on = np.array( + sorted({*quads_on} & {*(quads - 1)} & {*(quads + 1)}), int) + implicit = quads_mid_on[ + (v[quads_mid_on] # As above, use astype(int), not // division + == ((v[quads_mid_on - 1] + v[quads_mid_on + 1]) / 2).astype(int)) + .all(axis=1)] + if (font.postscript_name, glyph_id) in [ + ("DejaVuSerif-Italic", 77), # j + ("DejaVuSerif-Italic", 135), # \AA + ]: + v[:, 0] -= 1 # Hard-coded backcompat (FreeType shifts glyph by 1). + v = (v * conv + .5).astype(int) # As above re: truncation vs rounding. + v[implicit] = (( # Fix implicit points; again, truncate. + (v[implicit - 1] + v[implicit + 1]) / 2).astype(int)) + procs[font.get_glyph_name(glyph_id)] = ( + " ".join(map(str, d1)).encode("ascii") + b" d1\n" + + _path.convert_to_string( + Path(v, c), None, None, False, None, -1, + # no code for quad Beziers triggers auto-conversion to cubics. + [b"m", b"l", b"", b"c", b"h"], True) + + b"f") + return procs + + +class PdfFile: + """PDF file object.""" + + def __init__(self, filename, metadata=None): + """ + Parameters + ---------- + filename : str or path-like or file-like + Output target; if a string, a file will be opened for writing. + + metadata : dict from strings to strings and dates + Information dictionary object (see PDF reference section 10.2.1 + 'Document Information Dictionary'), e.g.: + ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. + + The standard keys are 'Title', 'Author', 'Subject', 'Keywords', + 'Creator', 'Producer', 'CreationDate', 'ModDate', and + 'Trapped'. Values have been predefined for 'Creator', 'Producer' + and 'CreationDate'. They can be removed by setting them to `None`. + """ + super().__init__() + + self._object_seq = itertools.count(1) # consumed by reserveObject + self.xrefTable = [[0, 65535, 'the zero object']] + self.passed_in_file_object = False + self.original_file_like = None + self.tell_base = 0 + fh, opened = cbook.to_filehandle(filename, "wb", return_opened=True) + if not opened: + try: + self.tell_base = filename.tell() + except OSError: + fh = BytesIO() + self.original_file_like = filename + else: + fh = filename + self.passed_in_file_object = True + + self.fh = fh + self.currentstream = None # stream object to write to, if any + fh.write(b"%PDF-1.4\n") # 1.4 is the first version to have alpha + # Output some eight-bit chars as a comment so various utilities + # recognize the file as binary by looking at the first few + # lines (see note in section 3.4.1 of the PDF reference). + fh.write(b"%\254\334 \253\272\n") + + self.rootObject = self.reserveObject('root') + self.pagesObject = self.reserveObject('pages') + self.pageList = [] + self.fontObject = self.reserveObject('fonts') + self._extGStateObject = self.reserveObject('extended graphics states') + self.hatchObject = self.reserveObject('tiling patterns') + self.gouraudObject = self.reserveObject('Gouraud triangles') + self.XObjectObject = self.reserveObject('external objects') + self.resourceObject = self.reserveObject('resources') + + root = {'Type': Name('Catalog'), + 'Pages': self.pagesObject} + self.writeObject(self.rootObject, root) + + self.infoDict = _create_pdf_info_dict('pdf', metadata or {}) + + self.fontNames = {} # maps filenames to internal font names + self._internal_font_seq = (Name(f'F{i}') for i in itertools.count(1)) + self.dviFontInfo = {} # maps dvi font names to embedding information + # differently encoded Type-1 fonts may share the same descriptor + self.type1Descriptors = {} + self._character_tracker = _backend_pdf_ps.CharacterTracker() + + self.alphaStates = {} # maps alpha values to graphics state objects + self._alpha_state_seq = (Name(f'A{i}') for i in itertools.count(1)) + self._soft_mask_states = {} + self._soft_mask_seq = (Name(f'SM{i}') for i in itertools.count(1)) + self._soft_mask_groups = [] + self.hatchPatterns = {} + self._hatch_pattern_seq = (Name(f'H{i}') for i in itertools.count(1)) + self.gouraudTriangles = [] + + self._images = {} + self._image_seq = (Name(f'I{i}') for i in itertools.count(1)) + + self.markers = {} + self.multi_byte_charprocs = {} + + self.paths = [] + + # A list of annotations for each page. Each entry is a tuple of the + # overall Annots object reference that's inserted into the page object, + # followed by a list of the actual annotations. + self._annotations = [] + # For annotations added before a page is created; mostly for the + # purpose of newTextnote. + self.pageAnnotations = [] + + # The PDF spec recommends to include every procset + procsets = [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()] + + # Write resource dictionary. + # Possibly TODO: more general ExtGState (graphics state dictionaries) + # ColorSpace Pattern Shading Properties + resources = {'Font': self.fontObject, + 'XObject': self.XObjectObject, + 'ExtGState': self._extGStateObject, + 'Pattern': self.hatchObject, + 'Shading': self.gouraudObject, + 'ProcSet': procsets} + self.writeObject(self.resourceObject, resources) + + def newPage(self, width, height): + self.endStream() + + self.width, self.height = width, height + contentObject = self.reserveObject('page contents') + annotsObject = self.reserveObject('annotations') + thePage = {'Type': Name('Page'), + 'Parent': self.pagesObject, + 'Resources': self.resourceObject, + 'MediaBox': [0, 0, 72 * width, 72 * height], + 'Contents': contentObject, + 'Annots': annotsObject, + } + pageObject = self.reserveObject('page') + self.writeObject(pageObject, thePage) + self.pageList.append(pageObject) + self._annotations.append((annotsObject, self.pageAnnotations)) + + self.beginStream(contentObject.id, + self.reserveObject('length of content stream')) + # Initialize the pdf graphics state to match the default Matplotlib + # graphics context (colorspace and joinstyle). + self.output(Name('DeviceRGB'), Op.setcolorspace_stroke) + self.output(Name('DeviceRGB'), Op.setcolorspace_nonstroke) + self.output(GraphicsContextPdf.joinstyles['round'], Op.setlinejoin) + + # Clear the list of annotations for the next page + self.pageAnnotations = [] + + def newTextnote(self, text, positionRect=[-100, -100, 0, 0]): + # Create a new annotation of type text + theNote = {'Type': Name('Annot'), + 'Subtype': Name('Text'), + 'Contents': text, + 'Rect': positionRect, + } + self.pageAnnotations.append(theNote) + + def _get_subsetted_psname(self, ps_name, charmap): + def toStr(n, base): + if n < base: + return string.ascii_uppercase[n] + else: + return ( + toStr(n // base, base) + string.ascii_uppercase[n % base] + ) + + # encode to string using base 26 + hashed = hash(frozenset(charmap.keys())) % ((sys.maxsize + 1) * 2) + prefix = toStr(hashed, 26) + + # get first 6 characters from prefix + return prefix[:6] + "+" + ps_name + + def finalize(self): + """Write out the various deferred objects and the pdf end matter.""" + + self.endStream() + self._write_annotations() + self.writeFonts() + self.writeExtGSTates() + self._write_soft_mask_groups() + self.writeHatches() + self.writeGouraudTriangles() + xobjects = { + name: ob for image, name, ob in self._images.values()} + for tup in self.markers.values(): + xobjects[tup[0]] = tup[1] + for name, value in self.multi_byte_charprocs.items(): + xobjects[name] = value + for name, path, trans, ob, join, cap, padding, filled, stroked \ + in self.paths: + xobjects[name] = ob + self.writeObject(self.XObjectObject, xobjects) + self.writeImages() + self.writeMarkers() + self.writePathCollectionTemplates() + self.writeObject(self.pagesObject, + {'Type': Name('Pages'), + 'Kids': self.pageList, + 'Count': len(self.pageList)}) + self.writeInfoDict() + + # Finalize the file + self.writeXref() + self.writeTrailer() + + def close(self): + """Flush all buffers and free all resources.""" + + self.endStream() + if self.passed_in_file_object: + self.fh.flush() + else: + if self.original_file_like is not None: + self.original_file_like.write(self.fh.getvalue()) + self.fh.close() + + def write(self, data): + if self.currentstream is None: + self.fh.write(data) + else: + self.currentstream.write(data) + + def output(self, *data): + self.write(_fill([pdfRepr(x) for x in data])) + self.write(b'\n') + + def beginStream(self, id, len, extra=None, png=None): + assert self.currentstream is None + self.currentstream = Stream(id, len, self, extra, png) + + def endStream(self): + if self.currentstream is not None: + self.currentstream.end() + self.currentstream = None + + def outputStream(self, ref, data, *, extra=None): + self.beginStream(ref.id, None, extra) + self.currentstream.write(data) + self.endStream() + + def _write_annotations(self): + for annotsObject, annotations in self._annotations: + self.writeObject(annotsObject, annotations) + + def fontName(self, fontprop): + """ + Select a font based on fontprop and return a name suitable for + Op.selectfont. If fontprop is a string, it will be interpreted + as the filename of the font. + """ + + if isinstance(fontprop, str): + filenames = [fontprop] + elif mpl.rcParams['pdf.use14corefonts']: + filenames = _fontManager._find_fonts_by_props( + fontprop, fontext='afm', directory=RendererPdf._afm_font_dir + ) + else: + filenames = _fontManager._find_fonts_by_props(fontprop) + first_Fx = None + for fname in filenames: + Fx = self.fontNames.get(fname) + if not first_Fx: + first_Fx = Fx + if Fx is None: + Fx = next(self._internal_font_seq) + self.fontNames[fname] = Fx + _log.debug('Assigning font %s = %r', Fx, fname) + if not first_Fx: + first_Fx = Fx + + # find_fontsprop's first value always adheres to + # findfont's value, so technically no behaviour change + return first_Fx + + def dviFontName(self, dvifont): + """ + Given a dvi font object, return a name suitable for Op.selectfont. + This registers the font information in ``self.dviFontInfo`` if not yet + registered. + """ + + dvi_info = self.dviFontInfo.get(dvifont.texname) + if dvi_info is not None: + return dvi_info.pdfname + + tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map')) + psfont = tex_font_map[dvifont.texname] + if psfont.filename is None: + raise ValueError( + "No usable font file found for {} (TeX: {}); " + "the font may lack a Type-1 version" + .format(psfont.psname, dvifont.texname)) + + pdfname = next(self._internal_font_seq) + _log.debug('Assigning font %s = %s (dvi)', pdfname, dvifont.texname) + self.dviFontInfo[dvifont.texname] = types.SimpleNamespace( + dvifont=dvifont, + pdfname=pdfname, + fontfile=psfont.filename, + basefont=psfont.psname, + encodingfile=psfont.encoding, + effects=psfont.effects) + return pdfname + + def writeFonts(self): + fonts = {} + for dviname, info in sorted(self.dviFontInfo.items()): + Fx = info.pdfname + _log.debug('Embedding Type-1 font %s from dvi.', dviname) + fonts[Fx] = self._embedTeXFont(info) + for filename in sorted(self.fontNames): + Fx = self.fontNames[filename] + _log.debug('Embedding font %s.', filename) + if filename.endswith('.afm'): + # from pdf.use14corefonts + _log.debug('Writing AFM font.') + fonts[Fx] = self._write_afm_font(filename) + else: + # a normal TrueType font + _log.debug('Writing TrueType font.') + chars = self._character_tracker.used.get(filename) + if chars: + fonts[Fx] = self.embedTTF(filename, chars) + self.writeObject(self.fontObject, fonts) + + def _write_afm_font(self, filename): + with open(filename, 'rb') as fh: + font = AFM(fh) + fontname = font.get_fontname() + fontdict = {'Type': Name('Font'), + 'Subtype': Name('Type1'), + 'BaseFont': Name(fontname), + 'Encoding': Name('WinAnsiEncoding')} + fontdictObject = self.reserveObject('font dictionary') + self.writeObject(fontdictObject, fontdict) + return fontdictObject + + def _embedTeXFont(self, fontinfo): + _log.debug('Embedding TeX font %s - fontinfo=%s', + fontinfo.dvifont.texname, fontinfo.__dict__) + + # Widths + widthsObject = self.reserveObject('font widths') + self.writeObject(widthsObject, fontinfo.dvifont.widths) + + # Font dictionary + fontdictObject = self.reserveObject('font dictionary') + fontdict = { + 'Type': Name('Font'), + 'Subtype': Name('Type1'), + 'FirstChar': 0, + 'LastChar': len(fontinfo.dvifont.widths) - 1, + 'Widths': widthsObject, + } + + # Encoding (if needed) + if fontinfo.encodingfile is not None: + fontdict['Encoding'] = { + 'Type': Name('Encoding'), + 'Differences': [ + 0, *map(Name, dviread._parse_enc(fontinfo.encodingfile))], + } + + # If no file is specified, stop short + if fontinfo.fontfile is None: + _log.warning( + "Because of TeX configuration (pdftex.map, see updmap option " + "pdftexDownloadBase14) the font %s is not embedded. This is " + "deprecated as of PDF 1.5 and it may cause the consumer " + "application to show something that was not intended.", + fontinfo.basefont) + fontdict['BaseFont'] = Name(fontinfo.basefont) + self.writeObject(fontdictObject, fontdict) + return fontdictObject + + # We have a font file to embed - read it in and apply any effects + t1font = _type1font.Type1Font(fontinfo.fontfile) + if fontinfo.effects: + t1font = t1font.transform(fontinfo.effects) + fontdict['BaseFont'] = Name(t1font.prop['FontName']) + + # Font descriptors may be shared between differently encoded + # Type-1 fonts, so only create a new descriptor if there is no + # existing descriptor for this font. + effects = (fontinfo.effects.get('slant', 0.0), + fontinfo.effects.get('extend', 1.0)) + fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects)) + if fontdesc is None: + fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile) + self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc + fontdict['FontDescriptor'] = fontdesc + + self.writeObject(fontdictObject, fontdict) + return fontdictObject + + def createType1Descriptor(self, t1font, fontfile): + # Create and write the font descriptor and the font file + # of a Type-1 font + fontdescObject = self.reserveObject('font descriptor') + fontfileObject = self.reserveObject('font file') + + italic_angle = t1font.prop['ItalicAngle'] + fixed_pitch = t1font.prop['isFixedPitch'] + + flags = 0 + # fixed width + if fixed_pitch: + flags |= 1 << 0 + # TODO: serif + if 0: + flags |= 1 << 1 + # TODO: symbolic (most TeX fonts are) + if 1: + flags |= 1 << 2 + # non-symbolic + else: + flags |= 1 << 5 + # italic + if italic_angle: + flags |= 1 << 6 + # TODO: all caps + if 0: + flags |= 1 << 16 + # TODO: small caps + if 0: + flags |= 1 << 17 + # TODO: force bold + if 0: + flags |= 1 << 18 + + ft2font = get_font(fontfile) + + descriptor = { + 'Type': Name('FontDescriptor'), + 'FontName': Name(t1font.prop['FontName']), + 'Flags': flags, + 'FontBBox': ft2font.bbox, + 'ItalicAngle': italic_angle, + 'Ascent': ft2font.ascender, + 'Descent': ft2font.descender, + 'CapHeight': 1000, # TODO: find this out + 'XHeight': 500, # TODO: this one too + 'FontFile': fontfileObject, + 'FontFamily': t1font.prop['FamilyName'], + 'StemV': 50, # TODO + # (see also revision 3874; but not all TeX distros have AFM files!) + # 'FontWeight': a number where 400 = Regular, 700 = Bold + } + + self.writeObject(fontdescObject, descriptor) + + self.outputStream(fontfileObject, b"".join(t1font.parts[:2]), + extra={'Length1': len(t1font.parts[0]), + 'Length2': len(t1font.parts[1]), + 'Length3': 0}) + + return fontdescObject + + def _get_xobject_glyph_name(self, filename, glyph_name): + Fx = self.fontName(filename) + return "-".join([ + Fx.name.decode(), + os.path.splitext(os.path.basename(filename))[0], + glyph_name]) + + _identityToUnicodeCMap = b"""/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (Adobe) + /Ordering (UCS) + /Supplement 0 +>> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> +endcodespacerange +%d beginbfrange +%s +endbfrange +endcmap +CMapName currentdict /CMap defineresource pop +end +end""" + + def embedTTF(self, filename, characters): + """Embed the TTF font from the named file into the document.""" + + font = get_font(filename) + fonttype = mpl.rcParams['pdf.fonttype'] + + def cvt(length, upe=font.units_per_EM, nearest=True): + """Convert font coordinates to PDF glyph coordinates.""" + value = length / upe * 1000 + if nearest: + return round(value) + # Best(?) to round away from zero for bounding boxes and the like. + if value < 0: + return math.floor(value) + else: + return math.ceil(value) + + def embedTTFType3(font, characters, descriptor): + """The Type 3-specific part of embedding a Truetype font""" + widthsObject = self.reserveObject('font widths') + fontdescObject = self.reserveObject('font descriptor') + fontdictObject = self.reserveObject('font dictionary') + charprocsObject = self.reserveObject('character procs') + differencesArray = [] + firstchar, lastchar = 0, 255 + bbox = [cvt(x, nearest=False) for x in font.bbox] + + fontdict = { + 'Type': Name('Font'), + 'BaseFont': ps_name, + 'FirstChar': firstchar, + 'LastChar': lastchar, + 'FontDescriptor': fontdescObject, + 'Subtype': Name('Type3'), + 'Name': descriptor['FontName'], + 'FontBBox': bbox, + 'FontMatrix': [.001, 0, 0, .001, 0, 0], + 'CharProcs': charprocsObject, + 'Encoding': { + 'Type': Name('Encoding'), + 'Differences': differencesArray}, + 'Widths': widthsObject + } + + from encodings import cp1252 + + # Make the "Widths" array + def get_char_width(charcode): + s = ord(cp1252.decoding_table[charcode]) + width = font.load_char( + s, flags=LOAD_NO_SCALE | LOAD_NO_HINTING).horiAdvance + return cvt(width) + with warnings.catch_warnings(): + # Ignore 'Required glyph missing from current font' warning + # from ft2font: here we're just building the widths table, but + # the missing glyphs may not even be used in the actual string. + warnings.filterwarnings("ignore") + widths = [get_char_width(charcode) + for charcode in range(firstchar, lastchar+1)] + descriptor['MaxWidth'] = max(widths) + + # Make the "Differences" array, sort the ccodes < 255 from + # the multi-byte ccodes, and build the whole set of glyph ids + # that we need from this font. + glyph_ids = [] + differences = [] + multi_byte_chars = set() + for c in characters: + ccode = c + gind = font.get_char_index(ccode) + glyph_ids.append(gind) + glyph_name = font.get_glyph_name(gind) + if ccode <= 255: + differences.append((ccode, glyph_name)) + else: + multi_byte_chars.add(glyph_name) + differences.sort() + + last_c = -2 + for c, name in differences: + if c != last_c + 1: + differencesArray.append(c) + differencesArray.append(Name(name)) + last_c = c + + # Make the charprocs array. + rawcharprocs = _get_pdf_charprocs(filename, glyph_ids) + charprocs = {} + for charname in sorted(rawcharprocs): + stream = rawcharprocs[charname] + charprocDict = {} + # The 2-byte characters are used as XObjects, so they + # need extra info in their dictionary + if charname in multi_byte_chars: + charprocDict = {'Type': Name('XObject'), + 'Subtype': Name('Form'), + 'BBox': bbox} + # Each glyph includes bounding box information, + # but xpdf and ghostscript can't handle it in a + # Form XObject (they segfault!!!), so we remove it + # from the stream here. It's not needed anyway, + # since the Form XObject includes it in its BBox + # value. + stream = stream[stream.find(b"d1") + 2:] + charprocObject = self.reserveObject('charProc') + self.outputStream(charprocObject, stream, extra=charprocDict) + + # Send the glyphs with ccode > 255 to the XObject dictionary, + # and the others to the font itself + if charname in multi_byte_chars: + name = self._get_xobject_glyph_name(filename, charname) + self.multi_byte_charprocs[name] = charprocObject + else: + charprocs[charname] = charprocObject + + # Write everything out + self.writeObject(fontdictObject, fontdict) + self.writeObject(fontdescObject, descriptor) + self.writeObject(widthsObject, widths) + self.writeObject(charprocsObject, charprocs) + + return fontdictObject + + def embedTTFType42(font, characters, descriptor): + """The Type 42-specific part of embedding a Truetype font""" + fontdescObject = self.reserveObject('font descriptor') + cidFontDictObject = self.reserveObject('CID font dictionary') + type0FontDictObject = self.reserveObject('Type 0 font dictionary') + cidToGidMapObject = self.reserveObject('CIDToGIDMap stream') + fontfileObject = self.reserveObject('font file stream') + wObject = self.reserveObject('Type 0 widths') + toUnicodeMapObject = self.reserveObject('ToUnicode map') + + subset_str = "".join(chr(c) for c in characters) + _log.debug("SUBSET %s characters: %s", filename, subset_str) + fontdata = _backend_pdf_ps.get_glyphs_subset(filename, subset_str) + _log.debug( + "SUBSET %s %d -> %d", filename, + os.stat(filename).st_size, fontdata.getbuffer().nbytes + ) + + # We need this ref for XObjects + full_font = font + + # reload the font object from the subset + # (all the necessary data could probably be obtained directly + # using fontLib.ttLib) + font = FT2Font(fontdata) + + cidFontDict = { + 'Type': Name('Font'), + 'Subtype': Name('CIDFontType2'), + 'BaseFont': ps_name, + 'CIDSystemInfo': { + 'Registry': 'Adobe', + 'Ordering': 'Identity', + 'Supplement': 0}, + 'FontDescriptor': fontdescObject, + 'W': wObject, + 'CIDToGIDMap': cidToGidMapObject + } + + type0FontDict = { + 'Type': Name('Font'), + 'Subtype': Name('Type0'), + 'BaseFont': ps_name, + 'Encoding': Name('Identity-H'), + 'DescendantFonts': [cidFontDictObject], + 'ToUnicode': toUnicodeMapObject + } + + # Make fontfile stream + descriptor['FontFile2'] = fontfileObject + self.outputStream( + fontfileObject, fontdata.getvalue(), + extra={'Length1': fontdata.getbuffer().nbytes}) + + # Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap + # at the same time + cid_to_gid_map = ['\0'] * 65536 + widths = [] + max_ccode = 0 + for c in characters: + ccode = c + gind = font.get_char_index(ccode) + glyph = font.load_char(ccode, + flags=LOAD_NO_SCALE | LOAD_NO_HINTING) + widths.append((ccode, cvt(glyph.horiAdvance))) + if ccode < 65536: + cid_to_gid_map[ccode] = chr(gind) + max_ccode = max(ccode, max_ccode) + widths.sort() + cid_to_gid_map = cid_to_gid_map[:max_ccode + 1] + + last_ccode = -2 + w = [] + max_width = 0 + unicode_groups = [] + for ccode, width in widths: + if ccode != last_ccode + 1: + w.append(ccode) + w.append([width]) + unicode_groups.append([ccode, ccode]) + else: + w[-1].append(width) + unicode_groups[-1][1] = ccode + max_width = max(max_width, width) + last_ccode = ccode + + unicode_bfrange = [] + for start, end in unicode_groups: + # Ensure the CID map contains only chars from BMP + if start > 65535: + continue + end = min(65535, end) + + unicode_bfrange.append( + b"<%04x> <%04x> [%s]" % + (start, end, + b" ".join(b"<%04x>" % x for x in range(start, end+1)))) + unicode_cmap = (self._identityToUnicodeCMap % + (len(unicode_groups), b"\n".join(unicode_bfrange))) + + # Add XObjects for unsupported chars + glyph_ids = [] + for ccode in characters: + if not _font_supports_glyph(fonttype, ccode): + gind = full_font.get_char_index(ccode) + glyph_ids.append(gind) + + bbox = [cvt(x, nearest=False) for x in full_font.bbox] + rawcharprocs = _get_pdf_charprocs(filename, glyph_ids) + for charname in sorted(rawcharprocs): + stream = rawcharprocs[charname] + charprocDict = {'Type': Name('XObject'), + 'Subtype': Name('Form'), + 'BBox': bbox} + # Each glyph includes bounding box information, + # but xpdf and ghostscript can't handle it in a + # Form XObject (they segfault!!!), so we remove it + # from the stream here. It's not needed anyway, + # since the Form XObject includes it in its BBox + # value. + stream = stream[stream.find(b"d1") + 2:] + charprocObject = self.reserveObject('charProc') + self.outputStream(charprocObject, stream, extra=charprocDict) + + name = self._get_xobject_glyph_name(filename, charname) + self.multi_byte_charprocs[name] = charprocObject + + # CIDToGIDMap stream + cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be") + self.outputStream(cidToGidMapObject, cid_to_gid_map) + + # ToUnicode CMap + self.outputStream(toUnicodeMapObject, unicode_cmap) + + descriptor['MaxWidth'] = max_width + + # Write everything out + self.writeObject(cidFontDictObject, cidFontDict) + self.writeObject(type0FontDictObject, type0FontDict) + self.writeObject(fontdescObject, descriptor) + self.writeObject(wObject, w) + + return type0FontDictObject + + # Beginning of main embedTTF function... + + ps_name = self._get_subsetted_psname( + font.postscript_name, + font.get_charmap() + ) + ps_name = ps_name.encode('ascii', 'replace') + ps_name = Name(ps_name) + pclt = font.get_sfnt_table('pclt') or {'capHeight': 0, 'xHeight': 0} + post = font.get_sfnt_table('post') or {'italicAngle': (0, 0)} + ff = font.face_flags + sf = font.style_flags + + flags = 0 + symbolic = False # ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10') + if ff & FIXED_WIDTH: + flags |= 1 << 0 + if 0: # TODO: serif + flags |= 1 << 1 + if symbolic: + flags |= 1 << 2 + else: + flags |= 1 << 5 + if sf & ITALIC: + flags |= 1 << 6 + if 0: # TODO: all caps + flags |= 1 << 16 + if 0: # TODO: small caps + flags |= 1 << 17 + if 0: # TODO: force bold + flags |= 1 << 18 + + descriptor = { + 'Type': Name('FontDescriptor'), + 'FontName': ps_name, + 'Flags': flags, + 'FontBBox': [cvt(x, nearest=False) for x in font.bbox], + 'Ascent': cvt(font.ascender, nearest=False), + 'Descent': cvt(font.descender, nearest=False), + 'CapHeight': cvt(pclt['capHeight'], nearest=False), + 'XHeight': cvt(pclt['xHeight']), + 'ItalicAngle': post['italicAngle'][1], # ??? + 'StemV': 0 # ??? + } + + if fonttype == 3: + return embedTTFType3(font, characters, descriptor) + elif fonttype == 42: + return embedTTFType42(font, characters, descriptor) + + def alphaState(self, alpha): + """Return name of an ExtGState that sets alpha to the given value.""" + + state = self.alphaStates.get(alpha, None) + if state is not None: + return state[0] + + name = next(self._alpha_state_seq) + self.alphaStates[alpha] = \ + (name, {'Type': Name('ExtGState'), + 'CA': alpha[0], 'ca': alpha[1]}) + return name + + def _soft_mask_state(self, smask): + """ + Return an ExtGState that sets the soft mask to the given shading. + + Parameters + ---------- + smask : Reference + Reference to a shading in DeviceGray color space, whose luminosity + is to be used as the alpha channel. + + Returns + ------- + Name + """ + + state = self._soft_mask_states.get(smask, None) + if state is not None: + return state[0] + + name = next(self._soft_mask_seq) + groupOb = self.reserveObject('transparency group for soft mask') + self._soft_mask_states[smask] = ( + name, + { + 'Type': Name('ExtGState'), + 'AIS': False, + 'SMask': { + 'Type': Name('Mask'), + 'S': Name('Luminosity'), + 'BC': [1], + 'G': groupOb + } + } + ) + self._soft_mask_groups.append(( + groupOb, + { + 'Type': Name('XObject'), + 'Subtype': Name('Form'), + 'FormType': 1, + 'Group': { + 'S': Name('Transparency'), + 'CS': Name('DeviceGray') + }, + 'Matrix': [1, 0, 0, 1, 0, 0], + 'Resources': {'Shading': {'S': smask}}, + 'BBox': [0, 0, 1, 1] + }, + [Name('S'), Op.shading] + )) + return name + + def writeExtGSTates(self): + self.writeObject( + self._extGStateObject, + dict([ + *self.alphaStates.values(), + *self._soft_mask_states.values() + ]) + ) + + def _write_soft_mask_groups(self): + for ob, attributes, content in self._soft_mask_groups: + self.beginStream(ob.id, None, attributes) + self.output(*content) + self.endStream() + + def hatchPattern(self, hatch_style): + # The colors may come in as numpy arrays, which aren't hashable + if hatch_style is not None: + edge, face, hatch = hatch_style + if edge is not None: + edge = tuple(edge) + if face is not None: + face = tuple(face) + hatch_style = (edge, face, hatch) + + pattern = self.hatchPatterns.get(hatch_style, None) + if pattern is not None: + return pattern + + name = next(self._hatch_pattern_seq) + self.hatchPatterns[hatch_style] = name + return name + + def writeHatches(self): + hatchDict = dict() + sidelen = 72.0 + for hatch_style, name in self.hatchPatterns.items(): + ob = self.reserveObject('hatch pattern') + hatchDict[name] = ob + res = {'Procsets': + [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()]} + self.beginStream( + ob.id, None, + {'Type': Name('Pattern'), + 'PatternType': 1, 'PaintType': 1, 'TilingType': 1, + 'BBox': [0, 0, sidelen, sidelen], + 'XStep': sidelen, 'YStep': sidelen, + 'Resources': res, + # Change origin to match Agg at top-left. + 'Matrix': [1, 0, 0, 1, 0, self.height * 72]}) + + stroke_rgb, fill_rgb, hatch = hatch_style + self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2], + Op.setrgb_stroke) + if fill_rgb is not None: + self.output(fill_rgb[0], fill_rgb[1], fill_rgb[2], + Op.setrgb_nonstroke, + 0, 0, sidelen, sidelen, Op.rectangle, + Op.fill) + + self.output(mpl.rcParams['hatch.linewidth'], Op.setlinewidth) + + self.output(*self.pathOperations( + Path.hatch(hatch), + Affine2D().scale(sidelen), + simplify=False)) + self.output(Op.fill_stroke) + + self.endStream() + self.writeObject(self.hatchObject, hatchDict) + + def addGouraudTriangles(self, points, colors): + """ + Add a Gouraud triangle shading. + + Parameters + ---------- + points : np.ndarray + Triangle vertices, shape (n, 3, 2) + where n = number of triangles, 3 = vertices, 2 = x, y. + colors : np.ndarray + Vertex colors, shape (n, 3, 1) or (n, 3, 4) + as with points, but last dimension is either (gray,) + or (r, g, b, alpha). + + Returns + ------- + Name, Reference + """ + name = Name('GT%d' % len(self.gouraudTriangles)) + ob = self.reserveObject(f'Gouraud triangle {name}') + self.gouraudTriangles.append((name, ob, points, colors)) + return name, ob + + def writeGouraudTriangles(self): + gouraudDict = dict() + for name, ob, points, colors in self.gouraudTriangles: + gouraudDict[name] = ob + shape = points.shape + flat_points = points.reshape((shape[0] * shape[1], 2)) + colordim = colors.shape[2] + assert colordim in (1, 4) + flat_colors = colors.reshape((shape[0] * shape[1], colordim)) + if colordim == 4: + # strip the alpha channel + colordim = 3 + points_min = np.min(flat_points, axis=0) - (1 << 8) + points_max = np.max(flat_points, axis=0) + (1 << 8) + factor = 0xffffffff / (points_max - points_min) + + self.beginStream( + ob.id, None, + {'ShadingType': 4, + 'BitsPerCoordinate': 32, + 'BitsPerComponent': 8, + 'BitsPerFlag': 8, + 'ColorSpace': Name( + 'DeviceRGB' if colordim == 3 else 'DeviceGray' + ), + 'AntiAlias': False, + 'Decode': ([points_min[0], points_max[0], + points_min[1], points_max[1]] + + [0, 1] * colordim), + }) + + streamarr = np.empty( + (shape[0] * shape[1],), + dtype=[('flags', 'u1'), + ('points', '>u4', (2,)), + ('colors', 'u1', (colordim,))]) + streamarr['flags'] = 0 + streamarr['points'] = (flat_points - points_min) * factor + streamarr['colors'] = flat_colors[:, :colordim] * 255.0 + + self.write(streamarr.tobytes()) + self.endStream() + self.writeObject(self.gouraudObject, gouraudDict) + + def imageObject(self, image): + """Return name of an image XObject representing the given image.""" + + entry = self._images.get(id(image), None) + if entry is not None: + return entry[1] + + name = next(self._image_seq) + ob = self.reserveObject(f'image {name}') + self._images[id(image)] = (image, name, ob) + return name + + def _unpack(self, im): + """ + Unpack image array *im* into ``(data, alpha)``, which have shape + ``(height, width, 3)`` (RGB) or ``(height, width, 1)`` (grayscale or + alpha), except that alpha is None if the image is fully opaque. + """ + im = im[::-1] + if im.ndim == 2: + return im, None + else: + rgb = im[:, :, :3] + rgb = np.array(rgb, order='C') + # PDF needs a separate alpha image + if im.shape[2] == 4: + alpha = im[:, :, 3][..., None] + if np.all(alpha == 255): + alpha = None + else: + alpha = np.array(alpha, order='C') + else: + alpha = None + return rgb, alpha + + def _writePng(self, img): + """ + Write the image *img* into the pdf file using png + predictors with Flate compression. + """ + buffer = BytesIO() + img.save(buffer, format="png") + buffer.seek(8) + png_data = b'' + bit_depth = palette = None + while True: + length, type = struct.unpack(b'!L4s', buffer.read(8)) + if type in [b'IHDR', b'PLTE', b'IDAT']: + data = buffer.read(length) + if len(data) != length: + raise RuntimeError("truncated data") + if type == b'IHDR': + bit_depth = int(data[8]) + elif type == b'PLTE': + palette = data + elif type == b'IDAT': + png_data += data + elif type == b'IEND': + break + else: + buffer.seek(length, 1) + buffer.seek(4, 1) # skip CRC + return png_data, bit_depth, palette + + def _writeImg(self, data, id, smask=None): + """ + Write the image *data*, of shape ``(height, width, 1)`` (grayscale) or + ``(height, width, 3)`` (RGB), as pdf object *id* and with the soft mask + (alpha channel) *smask*, which should be either None or a ``(height, + width, 1)`` array. + """ + height, width, color_channels = data.shape + obj = {'Type': Name('XObject'), + 'Subtype': Name('Image'), + 'Width': width, + 'Height': height, + 'ColorSpace': Name({1: 'DeviceGray', 3: 'DeviceRGB'}[color_channels]), + 'BitsPerComponent': 8} + if smask: + obj['SMask'] = smask + if mpl.rcParams['pdf.compression']: + if data.shape[-1] == 1: + data = data.squeeze(axis=-1) + png = {'Predictor': 10, 'Colors': color_channels, 'Columns': width} + img = Image.fromarray(data) + img_colors = img.getcolors(maxcolors=256) + if color_channels == 3 and img_colors is not None: + # Convert to indexed color if there are 256 colors or fewer. This can + # significantly reduce the file size. + num_colors = len(img_colors) + palette = np.array([comp for _, color in img_colors for comp in color], + dtype=np.uint8) + palette24 = ((palette[0::3].astype(np.uint32) << 16) | + (palette[1::3].astype(np.uint32) << 8) | + palette[2::3]) + rgb24 = ((data[:, :, 0].astype(np.uint32) << 16) | + (data[:, :, 1].astype(np.uint32) << 8) | + data[:, :, 2]) + indices = np.argsort(palette24).astype(np.uint8) + rgb8 = indices[np.searchsorted(palette24, rgb24, sorter=indices)] + img = Image.fromarray(rgb8, mode='P') + img.putpalette(palette) + png_data, bit_depth, palette = self._writePng(img) + if bit_depth is None or palette is None: + raise RuntimeError("invalid PNG header") + palette = palette[:num_colors * 3] # Trim padding; remove for Pillow>=9 + obj['ColorSpace'] = [Name('Indexed'), Name('DeviceRGB'), + num_colors - 1, palette] + obj['BitsPerComponent'] = bit_depth + png['Colors'] = 1 + png['BitsPerComponent'] = bit_depth + else: + png_data, _, _ = self._writePng(img) + else: + png = None + self.beginStream( + id, + self.reserveObject('length of image stream'), + obj, + png=png + ) + if png: + self.currentstream.write(png_data) + else: + self.currentstream.write(data.tobytes()) + self.endStream() + + def writeImages(self): + for img, name, ob in self._images.values(): + data, adata = self._unpack(img) + if adata is not None: + smaskObject = self.reserveObject("smask") + self._writeImg(adata, smaskObject.id) + else: + smaskObject = None + self._writeImg(data, ob.id, smaskObject) + + def markerObject(self, path, trans, fill, stroke, lw, joinstyle, + capstyle): + """Return name of a marker XObject representing the given path.""" + # self.markers used by markerObject, writeMarkers, close: + # mapping from (path operations, fill?, stroke?) to + # [name, object reference, bounding box, linewidth] + # This enables different draw_markers calls to share the XObject + # if the gc is sufficiently similar: colors etc can vary, but + # the choices of whether to fill and whether to stroke cannot. + # We need a bounding box enclosing all of the XObject path, + # but since line width may vary, we store the maximum of all + # occurring line widths in self.markers. + # close() is somewhat tightly coupled in that it expects the + # first two components of each value in self.markers to be the + # name and object reference. + pathops = self.pathOperations(path, trans, simplify=False) + key = (tuple(pathops), bool(fill), bool(stroke), joinstyle, capstyle) + result = self.markers.get(key) + if result is None: + name = Name('M%d' % len(self.markers)) + ob = self.reserveObject('marker %d' % len(self.markers)) + bbox = path.get_extents(trans) + self.markers[key] = [name, ob, bbox, lw] + else: + if result[-1] < lw: + result[-1] = lw + name = result[0] + return name + + def writeMarkers(self): + for ((pathops, fill, stroke, joinstyle, capstyle), + (name, ob, bbox, lw)) in self.markers.items(): + # bbox wraps the exact limits of the control points, so half a line + # will appear outside it. If the join style is miter and the line + # is not parallel to the edge, then the line will extend even + # further. From the PDF specification, Section 8.4.3.5, the miter + # limit is miterLength / lineWidth and from Table 52, the default + # is 10. With half the miter length outside, that works out to the + # following padding: + bbox = bbox.padded(lw * 5) + self.beginStream( + ob.id, None, + {'Type': Name('XObject'), 'Subtype': Name('Form'), + 'BBox': list(bbox.extents)}) + self.output(GraphicsContextPdf.joinstyles[joinstyle], + Op.setlinejoin) + self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap) + self.output(*pathops) + self.output(Op.paint_path(fill, stroke)) + self.endStream() + + def pathCollectionObject(self, gc, path, trans, padding, filled, stroked): + name = Name('P%d' % len(self.paths)) + ob = self.reserveObject('path %d' % len(self.paths)) + self.paths.append( + (name, path, trans, ob, gc.get_joinstyle(), gc.get_capstyle(), + padding, filled, stroked)) + return name + + def writePathCollectionTemplates(self): + for (name, path, trans, ob, joinstyle, capstyle, padding, filled, + stroked) in self.paths: + pathops = self.pathOperations(path, trans, simplify=False) + bbox = path.get_extents(trans) + if not np.all(np.isfinite(bbox.extents)): + extents = [0, 0, 0, 0] + else: + bbox = bbox.padded(padding) + extents = list(bbox.extents) + self.beginStream( + ob.id, None, + {'Type': Name('XObject'), 'Subtype': Name('Form'), + 'BBox': extents}) + self.output(GraphicsContextPdf.joinstyles[joinstyle], + Op.setlinejoin) + self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap) + self.output(*pathops) + self.output(Op.paint_path(filled, stroked)) + self.endStream() + + @staticmethod + def pathOperations(path, transform, clip=None, simplify=None, sketch=None): + return [Verbatim(_path.convert_to_string( + path, transform, clip, simplify, sketch, + 6, + [Op.moveto.value, Op.lineto.value, b'', Op.curveto.value, + Op.closepath.value], + True))] + + def writePath(self, path, transform, clip=False, sketch=None): + if clip: + clip = (0.0, 0.0, self.width * 72, self.height * 72) + simplify = path.should_simplify + else: + clip = None + simplify = False + cmds = self.pathOperations(path, transform, clip, simplify=simplify, + sketch=sketch) + self.output(*cmds) + + def reserveObject(self, name=''): + """ + Reserve an ID for an indirect object. + + The name is used for debugging in case we forget to print out + the object with writeObject. + """ + id = next(self._object_seq) + self.xrefTable.append([None, 0, name]) + return Reference(id) + + def recordXref(self, id): + self.xrefTable[id][0] = self.fh.tell() - self.tell_base + + def writeObject(self, object, contents): + self.recordXref(object.id) + object.write(contents, self) + + def writeXref(self): + """Write out the xref table.""" + self.startxref = self.fh.tell() - self.tell_base + self.write(b"xref\n0 %d\n" % len(self.xrefTable)) + for i, (offset, generation, name) in enumerate(self.xrefTable): + if offset is None: + raise AssertionError( + 'No offset for object %d (%s)' % (i, name)) + else: + key = b"f" if name == 'the zero object' else b"n" + text = b"%010d %05d %b \n" % (offset, generation, key) + self.write(text) + + def writeInfoDict(self): + """Write out the info dictionary, checking it for good form""" + + self.infoObject = self.reserveObject('info') + self.writeObject(self.infoObject, self.infoDict) + + def writeTrailer(self): + """Write out the PDF trailer.""" + + self.write(b"trailer\n") + self.write(pdfRepr( + {'Size': len(self.xrefTable), + 'Root': self.rootObject, + 'Info': self.infoObject})) + # Could add 'ID' + self.write(b"\nstartxref\n%d\n%%%%EOF\n" % self.startxref) + + +class RendererPdf(_backend_pdf_ps.RendererPDFPSBase): + + _afm_font_dir = cbook._get_data_path("fonts/pdfcorefonts") + _use_afm_rc_name = "pdf.use14corefonts" + + def __init__(self, file, image_dpi, height, width): + super().__init__(width, height) + self.file = file + self.gc = self.new_gc() + self.image_dpi = image_dpi + + def finalize(self): + self.file.output(*self.gc.finalize()) + + def check_gc(self, gc, fillcolor=None): + orig_fill = getattr(gc, '_fillcolor', (0., 0., 0.)) + gc._fillcolor = fillcolor + + orig_alphas = getattr(gc, '_effective_alphas', (1.0, 1.0)) + + if gc.get_rgb() is None: + # It should not matter what color here since linewidth should be + # 0 unless affected by global settings in rcParams, hence setting + # zero alpha just in case. + gc.set_foreground((0, 0, 0, 0), isRGBA=True) + + if gc._forced_alpha: + gc._effective_alphas = (gc._alpha, gc._alpha) + elif fillcolor is None or len(fillcolor) < 4: + gc._effective_alphas = (gc._rgb[3], 1.0) + else: + gc._effective_alphas = (gc._rgb[3], fillcolor[3]) + + delta = self.gc.delta(gc) + if delta: + self.file.output(*delta) + + # Restore gc to avoid unwanted side effects + gc._fillcolor = orig_fill + gc._effective_alphas = orig_alphas + + def get_image_magnification(self): + return self.image_dpi/72.0 + + def draw_image(self, gc, x, y, im, transform=None): + # docstring inherited + + h, w = im.shape[:2] + if w == 0 or h == 0: + return + + if transform is None: + # If there's no transform, alpha has already been applied + gc.set_alpha(1.0) + + self.check_gc(gc) + + w = 72.0 * w / self.image_dpi + h = 72.0 * h / self.image_dpi + + imob = self.file.imageObject(im) + + if transform is None: + self.file.output(Op.gsave, + w, 0, 0, h, x, y, Op.concat_matrix, + imob, Op.use_xobject, Op.grestore) + else: + tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values() + + self.file.output(Op.gsave, + 1, 0, 0, 1, x, y, Op.concat_matrix, + tr1, tr2, tr3, tr4, tr5, tr6, Op.concat_matrix, + imob, Op.use_xobject, Op.grestore) + + def draw_path(self, gc, path, transform, rgbFace=None): + # docstring inherited + self.check_gc(gc, rgbFace) + self.file.writePath( + path, transform, + rgbFace is None and gc.get_hatch_path() is None, + gc.get_sketch_params()) + self.file.output(self.gc.paint()) + + def draw_path_collection(self, gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position): + # We can only reuse the objects if the presence of fill and + # stroke (and the amount of alpha for each) is the same for + # all of them + can_do_optimization = True + facecolors = np.asarray(facecolors) + edgecolors = np.asarray(edgecolors) + + if not len(facecolors): + filled = False + can_do_optimization = not gc.get_hatch() + else: + if np.all(facecolors[:, 3] == facecolors[0, 3]): + filled = facecolors[0, 3] != 0.0 + else: + can_do_optimization = False + + if not len(edgecolors): + stroked = False + else: + if np.all(np.asarray(linewidths) == 0.0): + stroked = False + elif np.all(edgecolors[:, 3] == edgecolors[0, 3]): + stroked = edgecolors[0, 3] != 0.0 + else: + can_do_optimization = False + + # Is the optimization worth it? Rough calculation: + # cost of emitting a path in-line is len_path * uses_per_path + # cost of XObject is len_path + 5 for the definition, + # uses_per_path for the uses + len_path = len(paths[0].vertices) if len(paths) > 0 else 0 + uses_per_path = self._iter_collection_uses_per_path( + paths, all_transforms, offsets, facecolors, edgecolors) + should_do_optimization = \ + len_path + uses_per_path + 5 < len_path * uses_per_path + + if (not can_do_optimization) or (not should_do_optimization): + return RendererBase.draw_path_collection( + self, gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position) + + padding = np.max(linewidths) + path_codes = [] + for i, (path, transform) in enumerate(self._iter_collection_raw_paths( + master_transform, paths, all_transforms)): + name = self.file.pathCollectionObject( + gc, path, transform, padding, filled, stroked) + path_codes.append(name) + + output = self.file.output + output(*self.gc.push()) + lastx, lasty = 0, 0 + for xo, yo, path_id, gc0, rgbFace in self._iter_collection( + gc, path_codes, offsets, offset_trans, + facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): + + self.check_gc(gc0, rgbFace) + dx, dy = xo - lastx, yo - lasty + output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id, + Op.use_xobject) + lastx, lasty = xo, yo + output(*self.gc.pop()) + + def draw_markers(self, gc, marker_path, marker_trans, path, trans, + rgbFace=None): + # docstring inherited + + # Same logic as in draw_path_collection + len_marker_path = len(marker_path) + uses = len(path) + if len_marker_path * uses < len_marker_path + uses + 5: + RendererBase.draw_markers(self, gc, marker_path, marker_trans, + path, trans, rgbFace) + return + + self.check_gc(gc, rgbFace) + fill = gc.fill(rgbFace) + stroke = gc.stroke() + + output = self.file.output + marker = self.file.markerObject( + marker_path, marker_trans, fill, stroke, self.gc._linewidth, + gc.get_joinstyle(), gc.get_capstyle()) + + output(Op.gsave) + lastx, lasty = 0, 0 + for vertices, code in path.iter_segments( + trans, + clip=(0, 0, self.file.width*72, self.file.height*72), + simplify=False): + if len(vertices): + x, y = vertices[-2:] + if not (0 <= x <= self.file.width * 72 + and 0 <= y <= self.file.height * 72): + continue + dx, dy = x - lastx, y - lasty + output(1, 0, 0, 1, dx, dy, Op.concat_matrix, + marker, Op.use_xobject) + lastx, lasty = x, y + output(Op.grestore) + + def draw_gouraud_triangle(self, gc, points, colors, trans): + self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)), + colors.reshape((1, 3, 4)), trans) + + def draw_gouraud_triangles(self, gc, points, colors, trans): + assert len(points) == len(colors) + if len(points) == 0: + return + assert points.ndim == 3 + assert points.shape[1] == 3 + assert points.shape[2] == 2 + assert colors.ndim == 3 + assert colors.shape[1] == 3 + assert colors.shape[2] in (1, 4) + + shape = points.shape + points = points.reshape((shape[0] * shape[1], 2)) + tpoints = trans.transform(points) + tpoints = tpoints.reshape(shape) + name, _ = self.file.addGouraudTriangles(tpoints, colors) + output = self.file.output + + if colors.shape[2] == 1: + # grayscale + gc.set_alpha(1.0) + self.check_gc(gc) + output(name, Op.shading) + return + + alpha = colors[0, 0, 3] + if np.allclose(alpha, colors[:, :, 3]): + # single alpha value + gc.set_alpha(alpha) + self.check_gc(gc) + output(name, Op.shading) + else: + # varying alpha: use a soft mask + alpha = colors[:, :, 3][:, :, None] + _, smask_ob = self.file.addGouraudTriangles(tpoints, alpha) + gstate = self.file._soft_mask_state(smask_ob) + output(Op.gsave, gstate, Op.setgstate, + name, Op.shading, + Op.grestore) + + def _setup_textpos(self, x, y, angle, oldx=0, oldy=0, oldangle=0): + if angle == oldangle == 0: + self.file.output(x - oldx, y - oldy, Op.textpos) + else: + angle = math.radians(angle) + self.file.output(math.cos(angle), math.sin(angle), + -math.sin(angle), math.cos(angle), + x, y, Op.textmatrix) + self.file.output(0, 0, Op.textpos) + + def draw_mathtext(self, gc, x, y, s, prop, angle): + # TODO: fix positioning and encoding + width, height, descent, glyphs, rects = \ + self._text2path.mathtext_parser.parse(s, 72, prop) + + if gc.get_url() is not None: + self.file._annotations[-1][1].append(_get_link_annotation( + gc, x, y, width, height, angle)) + + fonttype = mpl.rcParams['pdf.fonttype'] + + # Set up a global transformation matrix for the whole math expression + a = math.radians(angle) + self.file.output(Op.gsave) + self.file.output(math.cos(a), math.sin(a), + -math.sin(a), math.cos(a), + x, y, Op.concat_matrix) + + self.check_gc(gc, gc._rgb) + prev_font = None, None + oldx, oldy = 0, 0 + unsupported_chars = [] + + self.file.output(Op.begin_text) + for font, fontsize, num, ox, oy in glyphs: + self.file._character_tracker.track_glyph(font, num) + fontname = font.fname + if not _font_supports_glyph(fonttype, num): + # Unsupported chars (i.e. multibyte in Type 3 or beyond BMP in + # Type 42) must be emitted separately (below). + unsupported_chars.append((font, fontsize, ox, oy, num)) + else: + self._setup_textpos(ox, oy, 0, oldx, oldy) + oldx, oldy = ox, oy + if (fontname, fontsize) != prev_font: + self.file.output(self.file.fontName(fontname), fontsize, + Op.selectfont) + prev_font = fontname, fontsize + self.file.output(self.encode_string(chr(num), fonttype), + Op.show) + self.file.output(Op.end_text) + + for font, fontsize, ox, oy, num in unsupported_chars: + self._draw_xobject_glyph( + font, fontsize, font.get_char_index(num), ox, oy) + + # Draw any horizontal lines in the math layout + for ox, oy, width, height in rects: + self.file.output(Op.gsave, ox, oy, width, height, + Op.rectangle, Op.fill, Op.grestore) + + # Pop off the global transformation + self.file.output(Op.grestore) + + def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): + # docstring inherited + texmanager = self.get_texmanager() + fontsize = prop.get_size_in_points() + dvifile = texmanager.make_dvi(s, fontsize) + with dviread.Dvi(dvifile, 72) as dvi: + page, = dvi + + if gc.get_url() is not None: + self.file._annotations[-1][1].append(_get_link_annotation( + gc, x, y, page.width, page.height, angle)) + + # Gather font information and do some setup for combining + # characters into strings. The variable seq will contain a + # sequence of font and text entries. A font entry is a list + # ['font', name, size] where name is a Name object for the + # font. A text entry is ['text', x, y, glyphs, x+w] where x + # and y are the starting coordinates, w is the width, and + # glyphs is a list; in this phase it will always contain just + # one single-character string, but later it may have longer + # strings interspersed with kern amounts. + oldfont, seq = None, [] + for x1, y1, dvifont, glyph, width in page.text: + if dvifont != oldfont: + pdfname = self.file.dviFontName(dvifont) + seq += [['font', pdfname, dvifont.size]] + oldfont = dvifont + seq += [['text', x1, y1, [bytes([glyph])], x1+width]] + + # Find consecutive text strings with constant y coordinate and + # combine into a sequence of strings and kerns, or just one + # string (if any kerns would be less than 0.1 points). + i, curx, fontsize = 0, 0, None + while i < len(seq)-1: + elt, nxt = seq[i:i+2] + if elt[0] == 'font': + fontsize = elt[2] + elif elt[0] == nxt[0] == 'text' and elt[2] == nxt[2]: + offset = elt[4] - nxt[1] + if abs(offset) < 0.1: + elt[3][-1] += nxt[3][0] + elt[4] += nxt[4]-nxt[1] + else: + elt[3] += [offset*1000.0/fontsize, nxt[3][0]] + elt[4] = nxt[4] + del seq[i+1] + continue + i += 1 + + # Create a transform to map the dvi contents to the canvas. + mytrans = Affine2D().rotate_deg(angle).translate(x, y) + + # Output the text. + self.check_gc(gc, gc._rgb) + self.file.output(Op.begin_text) + curx, cury, oldx, oldy = 0, 0, 0, 0 + for elt in seq: + if elt[0] == 'font': + self.file.output(elt[1], elt[2], Op.selectfont) + elif elt[0] == 'text': + curx, cury = mytrans.transform((elt[1], elt[2])) + self._setup_textpos(curx, cury, angle, oldx, oldy) + oldx, oldy = curx, cury + if len(elt[3]) == 1: + self.file.output(elt[3][0], Op.show) + else: + self.file.output(elt[3], Op.showkern) + else: + assert False + self.file.output(Op.end_text) + + # Then output the boxes (e.g., variable-length lines of square + # roots). + boxgc = self.new_gc() + boxgc.copy_properties(gc) + boxgc.set_linewidth(0) + pathops = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, + Path.CLOSEPOLY] + for x1, y1, h, w in page.boxes: + path = Path([[x1, y1], [x1+w, y1], [x1+w, y1+h], [x1, y1+h], + [0, 0]], pathops) + self.draw_path(boxgc, path, mytrans, gc._rgb) + + def encode_string(self, s, fonttype): + if fonttype in (1, 3): + return s.encode('cp1252', 'replace') + return s.encode('utf-16be', 'replace') + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + # docstring inherited + + # TODO: combine consecutive texts into one BT/ET delimited section + + self.check_gc(gc, gc._rgb) + if ismath: + return self.draw_mathtext(gc, x, y, s, prop, angle) + + fontsize = prop.get_size_in_points() + + if mpl.rcParams['pdf.use14corefonts']: + font = self._get_font_afm(prop) + fonttype = 1 + else: + font = self._get_font_ttf(prop) + self.file._character_tracker.track(font, s) + fonttype = mpl.rcParams['pdf.fonttype'] + + if gc.get_url() is not None: + font.set_text(s) + width, height = font.get_width_height() + self.file._annotations[-1][1].append(_get_link_annotation( + gc, x, y, width / 64, height / 64, angle)) + + # If fonttype is neither 3 nor 42, emit the whole string at once + # without manual kerning. + if fonttype not in [3, 42]: + self.file.output(Op.begin_text, + self.file.fontName(prop), fontsize, Op.selectfont) + self._setup_textpos(x, y, angle) + self.file.output(self.encode_string(s, fonttype), + Op.show, Op.end_text) + + # A sequence of characters is broken into multiple chunks. The chunking + # serves two purposes: + # - For Type 3 fonts, there is no way to access multibyte characters, + # as they cannot have a CIDMap. Therefore, in this case we break + # the string into chunks, where each chunk contains either a string + # of consecutive 1-byte characters or a single multibyte character. + # - A sequence of 1-byte characters is split into chunks to allow for + # kerning adjustments between consecutive chunks. + # + # Each chunk is emitted with a separate command: 1-byte characters use + # the regular text show command (TJ) with appropriate kerning between + # chunks, whereas multibyte characters use the XObject command (Do). + else: + # List of (ft_object, start_x, [prev_kern, char, char, ...]), + # w/o zero kerns. + singlebyte_chunks = [] + # List of (ft_object, start_x, glyph_index). + multibyte_glyphs = [] + prev_was_multibyte = True + prev_font = font + for item in _text_helpers.layout( + s, font, kern_mode=KERNING_UNFITTED): + if _font_supports_glyph(fonttype, ord(item.char)): + if prev_was_multibyte or item.ft_object != prev_font: + singlebyte_chunks.append((item.ft_object, item.x, [])) + prev_font = item.ft_object + if item.prev_kern: + singlebyte_chunks[-1][2].append(item.prev_kern) + singlebyte_chunks[-1][2].append(item.char) + prev_was_multibyte = False + else: + multibyte_glyphs.append( + (item.ft_object, item.x, item.glyph_idx) + ) + prev_was_multibyte = True + # Do the rotation and global translation as a single matrix + # concatenation up front + self.file.output(Op.gsave) + a = math.radians(angle) + self.file.output(math.cos(a), math.sin(a), + -math.sin(a), math.cos(a), + x, y, Op.concat_matrix) + # Emit all the 1-byte characters in a BT/ET group. + + self.file.output(Op.begin_text) + prev_start_x = 0 + for ft_object, start_x, kerns_or_chars in singlebyte_chunks: + ft_name = self.file.fontName(ft_object.fname) + self.file.output(ft_name, fontsize, Op.selectfont) + self._setup_textpos(start_x, 0, 0, prev_start_x, 0, 0) + self.file.output( + # See pdf spec "Text space details" for the 1000/fontsize + # (aka. 1000/T_fs) factor. + [-1000 * next(group) / fontsize if tp == float # a kern + else self.encode_string("".join(group), fonttype) + for tp, group in itertools.groupby(kerns_or_chars, type)], + Op.showkern) + prev_start_x = start_x + self.file.output(Op.end_text) + # Then emit all the multibyte characters, one at a time. + for ft_object, start_x, glyph_idx in multibyte_glyphs: + self._draw_xobject_glyph( + ft_object, fontsize, glyph_idx, start_x, 0 + ) + self.file.output(Op.grestore) + + def _draw_xobject_glyph(self, font, fontsize, glyph_idx, x, y): + """Draw a multibyte character from a Type 3 font as an XObject.""" + glyph_name = font.get_glyph_name(glyph_idx) + name = self.file._get_xobject_glyph_name(font.fname, glyph_name) + self.file.output( + Op.gsave, + 0.001 * fontsize, 0, 0, 0.001 * fontsize, x, y, Op.concat_matrix, + Name(name), Op.use_xobject, + Op.grestore, + ) + + def new_gc(self): + # docstring inherited + return GraphicsContextPdf(self.file) + + +class GraphicsContextPdf(GraphicsContextBase): + + def __init__(self, file): + super().__init__() + self._fillcolor = (0.0, 0.0, 0.0) + self._effective_alphas = (1.0, 1.0) + self.file = file + self.parent = None + + def __repr__(self): + d = dict(self.__dict__) + del d['file'] + del d['parent'] + return repr(d) + + def stroke(self): + """ + Predicate: does the path need to be stroked (its outline drawn)? + This tests for the various conditions that disable stroking + the path, in which case it would presumably be filled. + """ + # _linewidth > 0: in pdf a line of width 0 is drawn at minimum + # possible device width, but e.g., agg doesn't draw at all + return (self._linewidth > 0 and self._alpha > 0 and + (len(self._rgb) <= 3 or self._rgb[3] != 0.0)) + + def fill(self, *args): + """ + Predicate: does the path need to be filled? + + An optional argument can be used to specify an alternative + _fillcolor, as needed by RendererPdf.draw_markers. + """ + if len(args): + _fillcolor = args[0] + else: + _fillcolor = self._fillcolor + return (self._hatch or + (_fillcolor is not None and + (len(_fillcolor) <= 3 or _fillcolor[3] != 0.0))) + + def paint(self): + """ + Return the appropriate pdf operator to cause the path to be + stroked, filled, or both. + """ + return Op.paint_path(self.fill(), self.stroke()) + + capstyles = {'butt': 0, 'round': 1, 'projecting': 2} + joinstyles = {'miter': 0, 'round': 1, 'bevel': 2} + + def capstyle_cmd(self, style): + return [self.capstyles[style], Op.setlinecap] + + def joinstyle_cmd(self, style): + return [self.joinstyles[style], Op.setlinejoin] + + def linewidth_cmd(self, width): + return [width, Op.setlinewidth] + + def dash_cmd(self, dashes): + offset, dash = dashes + if dash is None: + dash = [] + offset = 0 + return [list(dash), offset, Op.setdash] + + def alpha_cmd(self, alpha, forced, effective_alphas): + name = self.file.alphaState(effective_alphas) + return [name, Op.setgstate] + + def hatch_cmd(self, hatch, hatch_color): + if not hatch: + if self._fillcolor is not None: + return self.fillcolor_cmd(self._fillcolor) + else: + return [Name('DeviceRGB'), Op.setcolorspace_nonstroke] + else: + hatch_style = (hatch_color, self._fillcolor, hatch) + name = self.file.hatchPattern(hatch_style) + return [Name('Pattern'), Op.setcolorspace_nonstroke, + name, Op.setcolor_nonstroke] + + def rgb_cmd(self, rgb): + if mpl.rcParams['pdf.inheritcolor']: + return [] + if rgb[0] == rgb[1] == rgb[2]: + return [rgb[0], Op.setgray_stroke] + else: + return [*rgb[:3], Op.setrgb_stroke] + + def fillcolor_cmd(self, rgb): + if rgb is None or mpl.rcParams['pdf.inheritcolor']: + return [] + elif rgb[0] == rgb[1] == rgb[2]: + return [rgb[0], Op.setgray_nonstroke] + else: + return [*rgb[:3], Op.setrgb_nonstroke] + + def push(self): + parent = GraphicsContextPdf(self.file) + parent.copy_properties(self) + parent.parent = self.parent + self.parent = parent + return [Op.gsave] + + def pop(self): + assert self.parent is not None + self.copy_properties(self.parent) + self.parent = self.parent.parent + return [Op.grestore] + + def clip_cmd(self, cliprect, clippath): + """Set clip rectangle. Calls `.pop()` and `.push()`.""" + cmds = [] + # Pop graphics state until we hit the right one or the stack is empty + while ((self._cliprect, self._clippath) != (cliprect, clippath) + and self.parent is not None): + cmds.extend(self.pop()) + # Unless we hit the right one, set the clip polygon + if ((self._cliprect, self._clippath) != (cliprect, clippath) or + self.parent is None): + cmds.extend(self.push()) + if self._cliprect != cliprect: + cmds.extend([cliprect, Op.rectangle, Op.clip, Op.endpath]) + if self._clippath != clippath: + path, affine = clippath.get_transformed_path_and_affine() + cmds.extend( + PdfFile.pathOperations(path, affine, simplify=False) + + [Op.clip, Op.endpath]) + return cmds + + commands = ( + # must come first since may pop + (('_cliprect', '_clippath'), clip_cmd), + (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd), + (('_capstyle',), capstyle_cmd), + (('_fillcolor',), fillcolor_cmd), + (('_joinstyle',), joinstyle_cmd), + (('_linewidth',), linewidth_cmd), + (('_dashes',), dash_cmd), + (('_rgb',), rgb_cmd), + # must come after fillcolor and rgb + (('_hatch', '_hatch_color'), hatch_cmd), + ) + + def delta(self, other): + """ + Copy properties of other into self and return PDF commands + needed to transform *self* into *other*. + """ + cmds = [] + fill_performed = False + for params, cmd in self.commands: + different = False + for p in params: + ours = getattr(self, p) + theirs = getattr(other, p) + try: + if ours is None or theirs is None: + different = ours is not theirs + else: + different = bool(ours != theirs) + except ValueError: + ours = np.asarray(ours) + theirs = np.asarray(theirs) + different = (ours.shape != theirs.shape or + np.any(ours != theirs)) + if different: + break + + # Need to update hatching if we also updated fillcolor + if params == ('_hatch', '_hatch_color') and fill_performed: + different = True + + if different: + if params == ('_fillcolor',): + fill_performed = True + theirs = [getattr(other, p) for p in params] + cmds.extend(cmd(self, *theirs)) + for p in params: + setattr(self, p, getattr(other, p)) + return cmds + + def copy_properties(self, other): + """ + Copy properties of other into self. + """ + super().copy_properties(other) + fillcolor = getattr(other, '_fillcolor', self._fillcolor) + effective_alphas = getattr(other, '_effective_alphas', + self._effective_alphas) + self._fillcolor = fillcolor + self._effective_alphas = effective_alphas + + def finalize(self): + """ + Make sure every pushed graphics state is popped. + """ + cmds = [] + while self.parent is not None: + cmds.extend(self.pop()) + return cmds + + +class PdfPages: + """ + A multi-page PDF file. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> # Initialize: + >>> with PdfPages('foo.pdf') as pdf: + ... # As many times as you like, create a figure fig and save it: + ... fig = plt.figure() + ... pdf.savefig(fig) + ... # When no figure is specified the current figure is saved + ... pdf.savefig() + + Notes + ----- + In reality `PdfPages` is a thin wrapper around `PdfFile`, in order to avoid + confusion when using `~.pyplot.savefig` and forgetting the format argument. + """ + + _UNSET = object() + + def __init__(self, filename, keep_empty=_UNSET, metadata=None): + """ + Create a new PdfPages object. + + Parameters + ---------- + filename : str or path-like or file-like + Plots using `PdfPages.savefig` will be written to a file at this location. + The file is opened when a figure is saved for the first time (overwriting + any older file with the same name). + + keep_empty : bool, optional + If set to False, then empty pdf files will be deleted automatically + when closed. + + metadata : dict, optional + Information dictionary object (see PDF reference section 10.2.1 + 'Document Information Dictionary'), e.g.: + ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. + + The standard keys are 'Title', 'Author', 'Subject', 'Keywords', + 'Creator', 'Producer', 'CreationDate', 'ModDate', and + 'Trapped'. Values have been predefined for 'Creator', 'Producer' + and 'CreationDate'. They can be removed by setting them to `None`. + """ + self._filename = filename + self._metadata = metadata + self._file = None + if keep_empty and keep_empty is not self._UNSET: + _api.warn_deprecated("3.8", message=( + "Keeping empty pdf files is deprecated since %(since)s and support " + "will be removed %(removal)s.")) + self._keep_empty = keep_empty + + keep_empty = _api.deprecate_privatize_attribute("3.8") + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + def _ensure_file(self): + if self._file is None: + self._file = PdfFile(self._filename, metadata=self._metadata) # init. + return self._file + + def close(self): + """ + Finalize this object, making the underlying file a complete + PDF file. + """ + if self._file is not None: + self._file.finalize() + self._file.close() + self._file = None + elif self._keep_empty: # True *or* UNSET. + _api.warn_deprecated("3.8", message=( + "Keeping empty pdf files is deprecated since %(since)s and support " + "will be removed %(removal)s.")) + PdfFile(self._filename, metadata=self._metadata) # touch the file. + + def infodict(self): + """ + Return a modifiable information dictionary object + (see PDF reference section 10.2.1 'Document Information + Dictionary'). + """ + return self._ensure_file().infoDict + + def savefig(self, figure=None, **kwargs): + """ + Save a `.Figure` to this file as a new page. + + Any other keyword arguments are passed to `~.Figure.savefig`. + + Parameters + ---------- + figure : `.Figure` or int, default: the active figure + The figure, or index of the figure, that is saved to the file. + """ + if not isinstance(figure, Figure): + if figure is None: + manager = Gcf.get_active() + else: + manager = Gcf.get_fig_manager(figure) + if manager is None: + raise ValueError(f"No figure {figure}") + figure = manager.canvas.figure + # Force use of pdf backend, as PdfPages is tightly coupled with it. + with cbook._setattr_cm(figure, canvas=FigureCanvasPdf(figure)): + figure.savefig(self, format="pdf", **kwargs) + + def get_pagecount(self): + """Return the current number of pages in the multipage pdf file.""" + return len(self._ensure_file().pageList) + + def attach_note(self, text, positionRect=[-100, -100, 0, 0]): + """ + Add a new text note to the page to be saved next. The optional + positionRect specifies the position of the new note on the + page. It is outside the page per default to make sure it is + invisible on printouts. + """ + self._ensure_file().newTextnote(text, positionRect) + + +class FigureCanvasPdf(FigureCanvasBase): + # docstring inherited + + fixed_dpi = 72 + filetypes = {'pdf': 'Portable Document Format'} + + def get_default_filetype(self): + return 'pdf' + + def print_pdf(self, filename, *, + bbox_inches_restore=None, metadata=None): + + dpi = self.figure.dpi + self.figure.dpi = 72 # there are 72 pdf points to an inch + width, height = self.figure.get_size_inches() + if isinstance(filename, PdfPages): + file = filename._ensure_file() + else: + file = PdfFile(filename, metadata=metadata) + try: + file.newPage(width, height) + renderer = MixedModeRenderer( + self.figure, width, height, dpi, + RendererPdf(file, dpi, height, width), + bbox_inches_restore=bbox_inches_restore) + self.figure.draw(renderer) + renderer.finalize() + if not isinstance(filename, PdfPages): + file.finalize() + finally: + if isinstance(filename, PdfPages): # finish off this page + file.endStream() + else: # we opened the file above; now finish it off + file.close() + + def draw(self): + self.figure.draw_without_rendering() + return super().draw() + + +FigureManagerPdf = FigureManagerBase + + +@_Backend.export +class _BackendPdf(_Backend): + FigureCanvas = FigureCanvasPdf diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pgf.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pgf.py new file mode 100644 index 00000000..ccf4b800 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_pgf.py @@ -0,0 +1,1009 @@ +import codecs +import datetime +import functools +from io import BytesIO +import logging +import math +import os +import pathlib +import shutil +import subprocess +from tempfile import TemporaryDirectory +import weakref + +from PIL import Image + +import matplotlib as mpl +from matplotlib import _api, cbook, font_manager as fm +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, RendererBase +) +from matplotlib.backends.backend_mixed import MixedModeRenderer +from matplotlib.backends.backend_pdf import ( + _create_pdf_info_dict, _datetime_to_pdf) +from matplotlib.path import Path +from matplotlib.figure import Figure +from matplotlib._pylab_helpers import Gcf + +_log = logging.getLogger(__name__) + + +# Note: When formatting floating point values, it is important to use the +# %f/{:f} format rather than %s/{} to avoid triggering scientific notation, +# which is not recognized by TeX. + +def _get_preamble(): + """Prepare a LaTeX preamble based on the rcParams configuration.""" + preamble = [ + # Remove Matplotlib's custom command \mathdefault. (Not using + # \mathnormal instead since this looks odd with Computer Modern.) + r"\def\mathdefault#1{#1}", + # Use displaystyle for all math. + r"\everymath=\expandafter{\the\everymath\displaystyle}", + # Allow pgf.preamble to override the above definitions. + mpl.rcParams["pgf.preamble"], + ] + if mpl.rcParams["pgf.texsystem"] != "pdflatex": + preamble.append("\\usepackage{fontspec}") + if mpl.rcParams["pgf.rcfonts"]: + families = ["serif", "sans\\-serif", "monospace"] + commands = ["setmainfont", "setsansfont", "setmonofont"] + for family, command in zip(families, commands): + # 1) Forward slashes also work on Windows, so don't mess with + # backslashes. 2) The dirname needs to include a separator. + path = pathlib.Path(fm.findfont(family)) + preamble.append(r"\%s{%s}[Path=\detokenize{%s/}]" % ( + command, path.name, path.parent.as_posix())) + preamble.append(mpl.texmanager._usepackage_if_not_loaded( + "underscore", option="strings")) # Documented as "must come last". + return "\n".join(preamble) + + +# It's better to use only one unit for all coordinates, since the +# arithmetic in latex seems to produce inaccurate conversions. +latex_pt_to_in = 1. / 72.27 +latex_in_to_pt = 1. / latex_pt_to_in +mpl_pt_to_in = 1. / 72. +mpl_in_to_pt = 1. / mpl_pt_to_in + + +def _tex_escape(text): + r""" + Do some necessary and/or useful substitutions for texts to be included in + LaTeX documents. + """ + return text.replace("\N{MINUS SIGN}", r"\ensuremath{-}") + + +def _writeln(fh, line): + # Ending lines with a % prevents TeX from inserting spurious spaces + # (https://tex.stackexchange.com/questions/7453). + fh.write(line) + fh.write("%\n") + + +def _escape_and_apply_props(s, prop): + """ + Generate a TeX string that renders string *s* with font properties *prop*, + also applying any required escapes to *s*. + """ + commands = [] + + families = {"serif": r"\rmfamily", "sans": r"\sffamily", + "sans-serif": r"\sffamily", "monospace": r"\ttfamily"} + family = prop.get_family()[0] + if family in families: + commands.append(families[family]) + elif (any(font.name == family for font in fm.fontManager.ttflist) + and mpl.rcParams["pgf.texsystem"] != "pdflatex"): + commands.append(r"\setmainfont{%s}\rmfamily" % family) + else: + _log.warning("Ignoring unknown font: %s", family) + + size = prop.get_size_in_points() + commands.append(r"\fontsize{%f}{%f}" % (size, size * 1.2)) + + styles = {"normal": r"", "italic": r"\itshape", "oblique": r"\slshape"} + commands.append(styles[prop.get_style()]) + + boldstyles = ["semibold", "demibold", "demi", "bold", "heavy", + "extra bold", "black"] + if prop.get_weight() in boldstyles: + commands.append(r"\bfseries") + + commands.append(r"\selectfont") + return ( + "{" + + "".join(commands) + + r"\catcode`\^=\active\def^{\ifmmode\sp\else\^{}\fi}" + # It should normally be enough to set the catcode of % to 12 ("normal + # character"); this works on TeXLive 2021 but not on 2018, so we just + # make it active too. + + r"\catcode`\%=\active\def%{\%}" + + _tex_escape(s) + + "}" + ) + + +def _metadata_to_str(key, value): + """Convert metadata key/value to a form that hyperref accepts.""" + if isinstance(value, datetime.datetime): + value = _datetime_to_pdf(value) + elif key == 'Trapped': + value = value.name.decode('ascii') + else: + value = str(value) + return f'{key}={{{value}}}' + + +def make_pdf_to_png_converter(): + """Return a function that converts a pdf file to a png file.""" + try: + mpl._get_executable_info("pdftocairo") + except mpl.ExecutableNotFoundError: + pass + else: + return lambda pdffile, pngfile, dpi: subprocess.check_output( + ["pdftocairo", "-singlefile", "-transp", "-png", "-r", "%d" % dpi, + pdffile, os.path.splitext(pngfile)[0]], + stderr=subprocess.STDOUT) + try: + gs_info = mpl._get_executable_info("gs") + except mpl.ExecutableNotFoundError: + pass + else: + return lambda pdffile, pngfile, dpi: subprocess.check_output( + [gs_info.executable, + '-dQUIET', '-dSAFER', '-dBATCH', '-dNOPAUSE', '-dNOPROMPT', + '-dUseCIEColor', '-dTextAlphaBits=4', + '-dGraphicsAlphaBits=4', '-dDOINTERPOLATE', + '-sDEVICE=pngalpha', '-sOutputFile=%s' % pngfile, + '-r%d' % dpi, pdffile], + stderr=subprocess.STDOUT) + raise RuntimeError("No suitable pdf to png renderer found.") + + +class LatexError(Exception): + def __init__(self, message, latex_output=""): + super().__init__(message) + self.latex_output = latex_output + + def __str__(self): + s, = self.args + if self.latex_output: + s += "\n" + self.latex_output + return s + + +class LatexManager: + """ + The LatexManager opens an instance of the LaTeX application for + determining the metrics of text elements. The LaTeX environment can be + modified by setting fonts and/or a custom preamble in `.rcParams`. + """ + + @staticmethod + def _build_latex_header(): + latex_header = [ + r"\documentclass{article}", + # Include TeX program name as a comment for cache invalidation. + # TeX does not allow this to be the first line. + rf"% !TeX program = {mpl.rcParams['pgf.texsystem']}", + # Test whether \includegraphics supports interpolate option. + r"\usepackage{graphicx}", + _get_preamble(), + r"\begin{document}", + r"\typeout{pgf_backend_query_start}", + ] + return "\n".join(latex_header) + + @classmethod + def _get_cached_or_new(cls): + """ + Return the previous LatexManager if the header and tex system did not + change, or a new instance otherwise. + """ + return cls._get_cached_or_new_impl(cls._build_latex_header()) + + @classmethod + @functools.lru_cache(1) + def _get_cached_or_new_impl(cls, header): # Helper for _get_cached_or_new. + return cls() + + def _stdin_writeln(self, s): + if self.latex is None: + self._setup_latex_process() + self.latex.stdin.write(s) + self.latex.stdin.write("\n") + self.latex.stdin.flush() + + def _expect(self, s): + s = list(s) + chars = [] + while True: + c = self.latex.stdout.read(1) + chars.append(c) + if chars[-len(s):] == s: + break + if not c: + self.latex.kill() + self.latex = None + raise LatexError("LaTeX process halted", "".join(chars)) + return "".join(chars) + + def _expect_prompt(self): + return self._expect("\n*") + + def __init__(self): + # create a tmp directory for running latex, register it for deletion + self._tmpdir = TemporaryDirectory() + self.tmpdir = self._tmpdir.name + self._finalize_tmpdir = weakref.finalize(self, self._tmpdir.cleanup) + + # test the LaTeX setup to ensure a clean startup of the subprocess + self._setup_latex_process(expect_reply=False) + stdout, stderr = self.latex.communicate("\n\\makeatletter\\@@end\n") + if self.latex.returncode != 0: + raise LatexError( + f"LaTeX errored (probably missing font or error in preamble) " + f"while processing the following input:\n" + f"{self._build_latex_header()}", + stdout) + self.latex = None # Will be set up on first use. + # Per-instance cache. + self._get_box_metrics = functools.lru_cache(self._get_box_metrics) + + def _setup_latex_process(self, *, expect_reply=True): + # Open LaTeX process for real work; register it for deletion. On + # Windows, we must ensure that the subprocess has quit before being + # able to delete the tmpdir in which it runs; in order to do so, we + # must first `kill()` it, and then `communicate()` with it. + try: + self.latex = subprocess.Popen( + [mpl.rcParams["pgf.texsystem"], "-halt-on-error"], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + encoding="utf-8", cwd=self.tmpdir) + except FileNotFoundError as err: + raise RuntimeError( + f"{mpl.rcParams['pgf.texsystem']!r} not found; install it or change " + f"rcParams['pgf.texsystem'] to an available TeX implementation" + ) from err + except OSError as err: + raise RuntimeError( + f"Error starting {mpl.rcParams['pgf.texsystem']!r}") from err + + def finalize_latex(latex): + latex.kill() + latex.communicate() + + self._finalize_latex = weakref.finalize( + self, finalize_latex, self.latex) + # write header with 'pgf_backend_query_start' token + self._stdin_writeln(self._build_latex_header()) + if expect_reply: # read until 'pgf_backend_query_start' token appears + self._expect("*pgf_backend_query_start") + self._expect_prompt() + + def get_width_height_descent(self, text, prop): + """ + Get the width, total height, and descent (in TeX points) for a text + typeset by the current LaTeX environment. + """ + return self._get_box_metrics(_escape_and_apply_props(text, prop)) + + def _get_box_metrics(self, tex): + """ + Get the width, total height and descent (in TeX points) for a TeX + command's output in the current LaTeX environment. + """ + # This method gets wrapped in __init__ for per-instance caching. + self._stdin_writeln( # Send textbox to TeX & request metrics typeout. + # \sbox doesn't handle catcode assignments inside its argument, + # so repeat the assignment of the catcode of "^" and "%" outside. + r"{\catcode`\^=\active\catcode`\%%=\active\sbox0{%s}" + r"\typeout{\the\wd0,\the\ht0,\the\dp0}}" + % tex) + try: + answer = self._expect_prompt() + except LatexError as err: + # Here and below, use '{}' instead of {!r} to avoid doubling all + # backslashes. + raise ValueError("Error measuring {}\nLaTeX Output:\n{}" + .format(tex, err.latex_output)) from err + try: + # Parse metrics from the answer string. Last line is prompt, and + # next-to-last-line is blank line from \typeout. + width, height, offset = answer.splitlines()[-3].split(",") + except Exception as err: + raise ValueError("Error measuring {}\nLaTeX Output:\n{}" + .format(tex, answer)) from err + w, h, o = float(width[:-2]), float(height[:-2]), float(offset[:-2]) + # The height returned from LaTeX goes from base to top; + # the height Matplotlib expects goes from bottom to top. + return w, h + o, o + + +@functools.lru_cache(1) +def _get_image_inclusion_command(): + man = LatexManager._get_cached_or_new() + man._stdin_writeln( + r"\includegraphics[interpolate=true]{%s}" + # Don't mess with backslashes on Windows. + % cbook._get_data_path("images/matplotlib.png").as_posix()) + try: + man._expect_prompt() + return r"\includegraphics" + except LatexError: + # Discard the broken manager. + LatexManager._get_cached_or_new_impl.cache_clear() + return r"\pgfimage" + + +class RendererPgf(RendererBase): + + def __init__(self, figure, fh): + """ + Create a new PGF renderer that translates any drawing instruction + into text commands to be interpreted in a latex pgfpicture environment. + + Attributes + ---------- + figure : `~matplotlib.figure.Figure` + Matplotlib figure to initialize height, width and dpi from. + fh : file-like + File handle for the output of the drawing commands. + """ + + super().__init__() + self.dpi = figure.dpi + self.fh = fh + self.figure = figure + self.image_counter = 0 + + def draw_markers(self, gc, marker_path, marker_trans, path, trans, + rgbFace=None): + # docstring inherited + + _writeln(self.fh, r"\begin{pgfscope}") + + # convert from display units to in + f = 1. / self.dpi + + # set style and clip + self._print_pgf_clip(gc) + self._print_pgf_path_styles(gc, rgbFace) + + # build marker definition + bl, tr = marker_path.get_extents(marker_trans).get_points() + coords = bl[0] * f, bl[1] * f, tr[0] * f, tr[1] * f + _writeln(self.fh, + r"\pgfsys@defobject{currentmarker}" + r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{" % coords) + self._print_pgf_path(None, marker_path, marker_trans) + self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0, + fill=rgbFace is not None) + _writeln(self.fh, r"}") + + maxcoord = 16383 / 72.27 * self.dpi # Max dimensions in LaTeX. + clip = (-maxcoord, -maxcoord, maxcoord, maxcoord) + + # draw marker for each vertex + for point, code in path.iter_segments(trans, simplify=False, + clip=clip): + x, y = point[0] * f, point[1] * f + _writeln(self.fh, r"\begin{pgfscope}") + _writeln(self.fh, r"\pgfsys@transformshift{%fin}{%fin}" % (x, y)) + _writeln(self.fh, r"\pgfsys@useobject{currentmarker}{}") + _writeln(self.fh, r"\end{pgfscope}") + + _writeln(self.fh, r"\end{pgfscope}") + + def draw_path(self, gc, path, transform, rgbFace=None): + # docstring inherited + _writeln(self.fh, r"\begin{pgfscope}") + # draw the path + self._print_pgf_clip(gc) + self._print_pgf_path_styles(gc, rgbFace) + self._print_pgf_path(gc, path, transform, rgbFace) + self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0, + fill=rgbFace is not None) + _writeln(self.fh, r"\end{pgfscope}") + + # if present, draw pattern on top + if gc.get_hatch(): + _writeln(self.fh, r"\begin{pgfscope}") + self._print_pgf_path_styles(gc, rgbFace) + + # combine clip and path for clipping + self._print_pgf_clip(gc) + self._print_pgf_path(gc, path, transform, rgbFace) + _writeln(self.fh, r"\pgfusepath{clip}") + + # build pattern definition + _writeln(self.fh, + r"\pgfsys@defobject{currentpattern}" + r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}{") + _writeln(self.fh, r"\begin{pgfscope}") + _writeln(self.fh, + r"\pgfpathrectangle" + r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}") + _writeln(self.fh, r"\pgfusepath{clip}") + scale = mpl.transforms.Affine2D().scale(self.dpi) + self._print_pgf_path(None, gc.get_hatch_path(), scale) + self._pgf_path_draw(stroke=True) + _writeln(self.fh, r"\end{pgfscope}") + _writeln(self.fh, r"}") + # repeat pattern, filling the bounding rect of the path + f = 1. / self.dpi + (xmin, ymin), (xmax, ymax) = \ + path.get_extents(transform).get_points() + xmin, xmax = f * xmin, f * xmax + ymin, ymax = f * ymin, f * ymax + repx, repy = math.ceil(xmax - xmin), math.ceil(ymax - ymin) + _writeln(self.fh, + r"\pgfsys@transformshift{%fin}{%fin}" % (xmin, ymin)) + for iy in range(repy): + for ix in range(repx): + _writeln(self.fh, r"\pgfsys@useobject{currentpattern}{}") + _writeln(self.fh, r"\pgfsys@transformshift{1in}{0in}") + _writeln(self.fh, r"\pgfsys@transformshift{-%din}{0in}" % repx) + _writeln(self.fh, r"\pgfsys@transformshift{0in}{1in}") + + _writeln(self.fh, r"\end{pgfscope}") + + def _print_pgf_clip(self, gc): + f = 1. / self.dpi + # check for clip box + bbox = gc.get_clip_rectangle() + if bbox: + p1, p2 = bbox.get_points() + w, h = p2 - p1 + coords = p1[0] * f, p1[1] * f, w * f, h * f + _writeln(self.fh, + r"\pgfpathrectangle" + r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" + % coords) + _writeln(self.fh, r"\pgfusepath{clip}") + + # check for clip path + clippath, clippath_trans = gc.get_clip_path() + if clippath is not None: + self._print_pgf_path(gc, clippath, clippath_trans) + _writeln(self.fh, r"\pgfusepath{clip}") + + def _print_pgf_path_styles(self, gc, rgbFace): + # cap style + capstyles = {"butt": r"\pgfsetbuttcap", + "round": r"\pgfsetroundcap", + "projecting": r"\pgfsetrectcap"} + _writeln(self.fh, capstyles[gc.get_capstyle()]) + + # join style + joinstyles = {"miter": r"\pgfsetmiterjoin", + "round": r"\pgfsetroundjoin", + "bevel": r"\pgfsetbeveljoin"} + _writeln(self.fh, joinstyles[gc.get_joinstyle()]) + + # filling + has_fill = rgbFace is not None + + if gc.get_forced_alpha(): + fillopacity = strokeopacity = gc.get_alpha() + else: + strokeopacity = gc.get_rgb()[3] + fillopacity = rgbFace[3] if has_fill and len(rgbFace) > 3 else 1.0 + + if has_fill: + _writeln(self.fh, + r"\definecolor{currentfill}{rgb}{%f,%f,%f}" + % tuple(rgbFace[:3])) + _writeln(self.fh, r"\pgfsetfillcolor{currentfill}") + if has_fill and fillopacity != 1.0: + _writeln(self.fh, r"\pgfsetfillopacity{%f}" % fillopacity) + + # linewidth and color + lw = gc.get_linewidth() * mpl_pt_to_in * latex_in_to_pt + stroke_rgba = gc.get_rgb() + _writeln(self.fh, r"\pgfsetlinewidth{%fpt}" % lw) + _writeln(self.fh, + r"\definecolor{currentstroke}{rgb}{%f,%f,%f}" + % stroke_rgba[:3]) + _writeln(self.fh, r"\pgfsetstrokecolor{currentstroke}") + if strokeopacity != 1.0: + _writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % strokeopacity) + + # line style + dash_offset, dash_list = gc.get_dashes() + if dash_list is None: + _writeln(self.fh, r"\pgfsetdash{}{0pt}") + else: + _writeln(self.fh, + r"\pgfsetdash{%s}{%fpt}" + % ("".join(r"{%fpt}" % dash for dash in dash_list), + dash_offset)) + + def _print_pgf_path(self, gc, path, transform, rgbFace=None): + f = 1. / self.dpi + # check for clip box / ignore clip for filled paths + bbox = gc.get_clip_rectangle() if gc else None + maxcoord = 16383 / 72.27 * self.dpi # Max dimensions in LaTeX. + if bbox and (rgbFace is None): + p1, p2 = bbox.get_points() + clip = (max(p1[0], -maxcoord), max(p1[1], -maxcoord), + min(p2[0], maxcoord), min(p2[1], maxcoord)) + else: + clip = (-maxcoord, -maxcoord, maxcoord, maxcoord) + # build path + for points, code in path.iter_segments(transform, clip=clip): + if code == Path.MOVETO: + x, y = tuple(points) + _writeln(self.fh, + r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" % + (f * x, f * y)) + elif code == Path.CLOSEPOLY: + _writeln(self.fh, r"\pgfpathclose") + elif code == Path.LINETO: + x, y = tuple(points) + _writeln(self.fh, + r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" % + (f * x, f * y)) + elif code == Path.CURVE3: + cx, cy, px, py = tuple(points) + coords = cx * f, cy * f, px * f, py * f + _writeln(self.fh, + r"\pgfpathquadraticcurveto" + r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" + % coords) + elif code == Path.CURVE4: + c1x, c1y, c2x, c2y, px, py = tuple(points) + coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f + _writeln(self.fh, + r"\pgfpathcurveto" + r"{\pgfqpoint{%fin}{%fin}}" + r"{\pgfqpoint{%fin}{%fin}}" + r"{\pgfqpoint{%fin}{%fin}}" + % coords) + + # apply pgf decorators + sketch_params = gc.get_sketch_params() if gc else None + if sketch_params is not None: + # Only "length" directly maps to "segment length" in PGF's API. + # PGF uses "amplitude" to pass the combined deviation in both x- + # and y-direction, while matplotlib only varies the length of the + # wiggle along the line ("randomness" and "length" parameters) + # and has a separate "scale" argument for the amplitude. + # -> Use "randomness" as PRNG seed to allow the user to force the + # same shape on multiple sketched lines + scale, length, randomness = sketch_params + if scale is not None: + # make matplotlib and PGF rendering visually similar + length *= 0.5 + scale *= 2 + # PGF guarantees that repeated loading is a no-op + _writeln(self.fh, r"\usepgfmodule{decorations}") + _writeln(self.fh, r"\usepgflibrary{decorations.pathmorphing}") + _writeln(self.fh, r"\pgfkeys{/pgf/decoration/.cd, " + f"segment length = {(length * f):f}in, " + f"amplitude = {(scale * f):f}in}}") + _writeln(self.fh, f"\\pgfmathsetseed{{{int(randomness)}}}") + _writeln(self.fh, r"\pgfdecoratecurrentpath{random steps}") + + def _pgf_path_draw(self, stroke=True, fill=False): + actions = [] + if stroke: + actions.append("stroke") + if fill: + actions.append("fill") + _writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions)) + + def option_scale_image(self): + # docstring inherited + return True + + def option_image_nocomposite(self): + # docstring inherited + return not mpl.rcParams['image.composite_image'] + + def draw_image(self, gc, x, y, im, transform=None): + # docstring inherited + + h, w = im.shape[:2] + if w == 0 or h == 0: + return + + if not os.path.exists(getattr(self.fh, "name", "")): + raise ValueError( + "streamed pgf-code does not support raster graphics, consider " + "using the pgf-to-pdf option") + + # save the images to png files + path = pathlib.Path(self.fh.name) + fname_img = "%s-img%d.png" % (path.stem, self.image_counter) + Image.fromarray(im[::-1]).save(path.parent / fname_img) + self.image_counter += 1 + + # reference the image in the pgf picture + _writeln(self.fh, r"\begin{pgfscope}") + self._print_pgf_clip(gc) + f = 1. / self.dpi # from display coords to inch + if transform is None: + _writeln(self.fh, + r"\pgfsys@transformshift{%fin}{%fin}" % (x * f, y * f)) + w, h = w * f, h * f + else: + tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values() + _writeln(self.fh, + r"\pgfsys@transformcm{%f}{%f}{%f}{%f}{%fin}{%fin}" % + (tr1 * f, tr2 * f, tr3 * f, tr4 * f, + (tr5 + x) * f, (tr6 + y) * f)) + w = h = 1 # scale is already included in the transform + interp = str(transform is None).lower() # interpolation in PDF reader + _writeln(self.fh, + r"\pgftext[left,bottom]" + r"{%s[interpolate=%s,width=%fin,height=%fin]{%s}}" % + (_get_image_inclusion_command(), + interp, w, h, fname_img)) + _writeln(self.fh, r"\end{pgfscope}") + + def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): + # docstring inherited + self.draw_text(gc, x, y, s, prop, angle, ismath="TeX", mtext=mtext) + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + # docstring inherited + + # prepare string for tex + s = _escape_and_apply_props(s, prop) + + _writeln(self.fh, r"\begin{pgfscope}") + self._print_pgf_clip(gc) + + alpha = gc.get_alpha() + if alpha != 1.0: + _writeln(self.fh, r"\pgfsetfillopacity{%f}" % alpha) + _writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % alpha) + rgb = tuple(gc.get_rgb())[:3] + _writeln(self.fh, r"\definecolor{textcolor}{rgb}{%f,%f,%f}" % rgb) + _writeln(self.fh, r"\pgfsetstrokecolor{textcolor}") + _writeln(self.fh, r"\pgfsetfillcolor{textcolor}") + s = r"\color{textcolor}" + s + + dpi = self.figure.dpi + text_args = [] + if mtext and ( + (angle == 0 or + mtext.get_rotation_mode() == "anchor") and + mtext.get_verticalalignment() != "center_baseline"): + # if text anchoring can be supported, get the original coordinates + # and add alignment information + pos = mtext.get_unitless_position() + x, y = mtext.get_transform().transform(pos) + halign = {"left": "left", "right": "right", "center": ""} + valign = {"top": "top", "bottom": "bottom", + "baseline": "base", "center": ""} + text_args.extend([ + f"x={x/dpi:f}in", + f"y={y/dpi:f}in", + halign[mtext.get_horizontalalignment()], + valign[mtext.get_verticalalignment()], + ]) + else: + # if not, use the text layout provided by Matplotlib. + text_args.append(f"x={x/dpi:f}in, y={y/dpi:f}in, left, base") + + if angle != 0: + text_args.append("rotate=%f" % angle) + + _writeln(self.fh, r"\pgftext[%s]{%s}" % (",".join(text_args), s)) + _writeln(self.fh, r"\end{pgfscope}") + + def get_text_width_height_descent(self, s, prop, ismath): + # docstring inherited + # get text metrics in units of latex pt, convert to display units + w, h, d = (LatexManager._get_cached_or_new() + .get_width_height_descent(s, prop)) + # TODO: this should be latex_pt_to_in instead of mpl_pt_to_in + # but having a little bit more space around the text looks better, + # plus the bounding box reported by LaTeX is VERY narrow + f = mpl_pt_to_in * self.dpi + return w * f, h * f, d * f + + def flipy(self): + # docstring inherited + return False + + def get_canvas_width_height(self): + # docstring inherited + return (self.figure.get_figwidth() * self.dpi, + self.figure.get_figheight() * self.dpi) + + def points_to_pixels(self, points): + # docstring inherited + return points * mpl_pt_to_in * self.dpi + + +class FigureCanvasPgf(FigureCanvasBase): + filetypes = {"pgf": "LaTeX PGF picture", + "pdf": "LaTeX compiled PGF picture", + "png": "Portable Network Graphics", } + + def get_default_filetype(self): + return 'pdf' + + def _print_pgf_to_fh(self, fh, *, bbox_inches_restore=None): + + header_text = """%% Creator: Matplotlib, PGF backend +%% +%% To include the figure in your LaTeX document, write +%% \\input{.pgf} +%% +%% Make sure the required packages are loaded in your preamble +%% \\usepackage{pgf} +%% +%% Also ensure that all the required font packages are loaded; for instance, +%% the lmodern package is sometimes necessary when using math font. +%% \\usepackage{lmodern} +%% +%% Figures using additional raster images can only be included by \\input if +%% they are in the same directory as the main LaTeX file. For loading figures +%% from other directories you can use the `import` package +%% \\usepackage{import} +%% +%% and then include the figures with +%% \\import{}{.pgf} +%% +""" + + # append the preamble used by the backend as a comment for debugging + header_info_preamble = ["%% Matplotlib used the following preamble"] + for line in _get_preamble().splitlines(): + header_info_preamble.append("%% " + line) + header_info_preamble.append("%%") + header_info_preamble = "\n".join(header_info_preamble) + + # get figure size in inch + w, h = self.figure.get_figwidth(), self.figure.get_figheight() + dpi = self.figure.dpi + + # create pgfpicture environment and write the pgf code + fh.write(header_text) + fh.write(header_info_preamble) + fh.write("\n") + _writeln(fh, r"\begingroup") + _writeln(fh, r"\makeatletter") + _writeln(fh, r"\begin{pgfpicture}") + _writeln(fh, + r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" + % (w, h)) + _writeln(fh, r"\pgfusepath{use as bounding box, clip}") + renderer = MixedModeRenderer(self.figure, w, h, dpi, + RendererPgf(self.figure, fh), + bbox_inches_restore=bbox_inches_restore) + self.figure.draw(renderer) + + # end the pgfpicture environment + _writeln(fh, r"\end{pgfpicture}") + _writeln(fh, r"\makeatother") + _writeln(fh, r"\endgroup") + + def print_pgf(self, fname_or_fh, **kwargs): + """ + Output pgf macros for drawing the figure so it can be included and + rendered in latex documents. + """ + with cbook.open_file_cm(fname_or_fh, "w", encoding="utf-8") as file: + if not cbook.file_requires_unicode(file): + file = codecs.getwriter("utf-8")(file) + self._print_pgf_to_fh(file, **kwargs) + + def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs): + """Use LaTeX to compile a pgf generated figure to pdf.""" + w, h = self.figure.get_size_inches() + + info_dict = _create_pdf_info_dict('pgf', metadata or {}) + pdfinfo = ','.join( + _metadata_to_str(k, v) for k, v in info_dict.items()) + + # print figure to pgf and compile it with latex + with TemporaryDirectory() as tmpdir: + tmppath = pathlib.Path(tmpdir) + self.print_pgf(tmppath / "figure.pgf", **kwargs) + (tmppath / "figure.tex").write_text( + "\n".join([ + r"\documentclass[12pt]{article}", + r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo, + r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}" + % (w, h), + r"\usepackage{pgf}", + _get_preamble(), + r"\begin{document}", + r"\centering", + r"\input{figure.pgf}", + r"\end{document}", + ]), encoding="utf-8") + texcommand = mpl.rcParams["pgf.texsystem"] + cbook._check_and_log_subprocess( + [texcommand, "-interaction=nonstopmode", "-halt-on-error", + "figure.tex"], _log, cwd=tmpdir) + with (tmppath / "figure.pdf").open("rb") as orig, \ + cbook.open_file_cm(fname_or_fh, "wb") as dest: + shutil.copyfileobj(orig, dest) # copy file contents to target + + def print_png(self, fname_or_fh, **kwargs): + """Use LaTeX to compile a pgf figure to pdf and convert it to png.""" + converter = make_pdf_to_png_converter() + with TemporaryDirectory() as tmpdir: + tmppath = pathlib.Path(tmpdir) + pdf_path = tmppath / "figure.pdf" + png_path = tmppath / "figure.png" + self.print_pdf(pdf_path, **kwargs) + converter(pdf_path, png_path, dpi=self.figure.dpi) + with png_path.open("rb") as orig, \ + cbook.open_file_cm(fname_or_fh, "wb") as dest: + shutil.copyfileobj(orig, dest) # copy file contents to target + + def get_renderer(self): + return RendererPgf(self.figure, None) + + def draw(self): + self.figure.draw_without_rendering() + return super().draw() + + +FigureManagerPgf = FigureManagerBase + + +@_Backend.export +class _BackendPgf(_Backend): + FigureCanvas = FigureCanvasPgf + + +class PdfPages: + """ + A multi-page PDF file using the pgf backend + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> # Initialize: + >>> with PdfPages('foo.pdf') as pdf: + ... # As many times as you like, create a figure fig and save it: + ... fig = plt.figure() + ... pdf.savefig(fig) + ... # When no figure is specified the current figure is saved + ... pdf.savefig() + """ + + _UNSET = object() + + def __init__(self, filename, *, keep_empty=_UNSET, metadata=None): + """ + Create a new PdfPages object. + + Parameters + ---------- + filename : str or path-like + Plots using `PdfPages.savefig` will be written to a file at this + location. Any older file with the same name is overwritten. + + keep_empty : bool, default: True + If set to False, then empty pdf files will be deleted automatically + when closed. + + metadata : dict, optional + Information dictionary object (see PDF reference section 10.2.1 + 'Document Information Dictionary'), e.g.: + ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. + + The standard keys are 'Title', 'Author', 'Subject', 'Keywords', + 'Creator', 'Producer', 'CreationDate', 'ModDate', and + 'Trapped'. Values have been predefined for 'Creator', 'Producer' + and 'CreationDate'. They can be removed by setting them to `None`. + + Note that some versions of LaTeX engines may ignore the 'Producer' + key and set it to themselves. + """ + self._output_name = filename + self._n_figures = 0 + if keep_empty and keep_empty is not self._UNSET: + _api.warn_deprecated("3.8", message=( + "Keeping empty pdf files is deprecated since %(since)s and support " + "will be removed %(removal)s.")) + self._keep_empty = keep_empty + self._metadata = (metadata or {}).copy() + self._info_dict = _create_pdf_info_dict('pgf', self._metadata) + self._file = BytesIO() + + keep_empty = _api.deprecate_privatize_attribute("3.8") + + def _write_header(self, width_inches, height_inches): + pdfinfo = ','.join( + _metadata_to_str(k, v) for k, v in self._info_dict.items()) + latex_header = "\n".join([ + r"\documentclass[12pt]{article}", + r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo, + r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}" + % (width_inches, height_inches), + r"\usepackage{pgf}", + _get_preamble(), + r"\setlength{\parindent}{0pt}", + r"\begin{document}%", + ]) + self._file.write(latex_header.encode('utf-8')) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + def close(self): + """ + Finalize this object, running LaTeX in a temporary directory + and moving the final pdf file to *filename*. + """ + self._file.write(rb'\end{document}\n') + if self._n_figures > 0: + self._run_latex() + elif self._keep_empty: + _api.warn_deprecated("3.8", message=( + "Keeping empty pdf files is deprecated since %(since)s and support " + "will be removed %(removal)s.")) + open(self._output_name, 'wb').close() + self._file.close() + + def _run_latex(self): + texcommand = mpl.rcParams["pgf.texsystem"] + with TemporaryDirectory() as tmpdir: + tex_source = pathlib.Path(tmpdir, "pdf_pages.tex") + tex_source.write_bytes(self._file.getvalue()) + cbook._check_and_log_subprocess( + [texcommand, "-interaction=nonstopmode", "-halt-on-error", + tex_source], + _log, cwd=tmpdir) + shutil.move(tex_source.with_suffix(".pdf"), self._output_name) + + def savefig(self, figure=None, **kwargs): + """ + Save a `.Figure` to this file as a new page. + + Any other keyword arguments are passed to `~.Figure.savefig`. + + Parameters + ---------- + figure : `.Figure` or int, default: the active figure + The figure, or index of the figure, that is saved to the file. + """ + if not isinstance(figure, Figure): + if figure is None: + manager = Gcf.get_active() + else: + manager = Gcf.get_fig_manager(figure) + if manager is None: + raise ValueError(f"No figure {figure}") + figure = manager.canvas.figure + + with cbook._setattr_cm(figure, canvas=FigureCanvasPgf(figure)): + width, height = figure.get_size_inches() + if self._n_figures == 0: + self._write_header(width, height) + else: + # \pdfpagewidth and \pdfpageheight exist on pdftex, xetex, and + # luatex<0.85; they were renamed to \pagewidth and \pageheight + # on luatex>=0.85. + self._file.write( + ( + r'\newpage' + r'\ifdefined\pdfpagewidth\pdfpagewidth' + fr'\else\pagewidth\fi={width}in' + r'\ifdefined\pdfpageheight\pdfpageheight' + fr'\else\pageheight\fi={height}in' + '%%\n' + ).encode("ascii") + ) + figure.savefig(self._file, format="pgf", **kwargs) + self._n_figures += 1 + + def get_pagecount(self): + """Return the current number of pages in the multipage pdf file.""" + return self._n_figures diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_ps.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_ps.py new file mode 100644 index 00000000..2f9faa0e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_ps.py @@ -0,0 +1,1340 @@ +""" +A PostScript backend, which can produce both PostScript .ps and .eps. +""" + +import codecs +import datetime +from enum import Enum +import functools +from io import StringIO +import itertools +import logging +import os +import pathlib +import shutil +from tempfile import TemporaryDirectory +import time + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook, _path, _text_helpers +from matplotlib._afm import AFM +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, RendererBase) +from matplotlib.cbook import is_writable_file_like, file_requires_unicode +from matplotlib.font_manager import get_font +from matplotlib.ft2font import LOAD_NO_SCALE, FT2Font +from matplotlib._ttconv import convert_ttf_to_ps +from matplotlib._mathtext_data import uni2type1 +from matplotlib.path import Path +from matplotlib.texmanager import TexManager +from matplotlib.transforms import Affine2D +from matplotlib.backends.backend_mixed import MixedModeRenderer +from . import _backend_pdf_ps + + +_log = logging.getLogger(__name__) +debugPS = False + + +@_api.deprecated("3.7") +class PsBackendHelper: + def __init__(self): + self._cached = {} + + +@_api.caching_module_getattr +class __getattr__: + # module-level deprecations + ps_backend_helper = _api.deprecated("3.7", obj_type="")( + property(lambda self: PsBackendHelper())) + psDefs = _api.deprecated("3.8", obj_type="")(property(lambda self: _psDefs)) + + +papersize = {'letter': (8.5, 11), + 'legal': (8.5, 14), + 'ledger': (11, 17), + 'a0': (33.11, 46.81), + 'a1': (23.39, 33.11), + 'a2': (16.54, 23.39), + 'a3': (11.69, 16.54), + 'a4': (8.27, 11.69), + 'a5': (5.83, 8.27), + 'a6': (4.13, 5.83), + 'a7': (2.91, 4.13), + 'a8': (2.05, 2.91), + 'a9': (1.46, 2.05), + 'a10': (1.02, 1.46), + 'b0': (40.55, 57.32), + 'b1': (28.66, 40.55), + 'b2': (20.27, 28.66), + 'b3': (14.33, 20.27), + 'b4': (10.11, 14.33), + 'b5': (7.16, 10.11), + 'b6': (5.04, 7.16), + 'b7': (3.58, 5.04), + 'b8': (2.51, 3.58), + 'b9': (1.76, 2.51), + 'b10': (1.26, 1.76)} + + +def _get_papertype(w, h): + for key, (pw, ph) in sorted(papersize.items(), reverse=True): + if key.startswith('l'): + continue + if w < pw and h < ph: + return key + return 'a0' + + +def _nums_to_str(*args, sep=" "): + return sep.join(f"{arg:1.3f}".rstrip("0").rstrip(".") for arg in args) + + +def _move_path_to_path_or_stream(src, dst): + """ + Move the contents of file at *src* to path-or-filelike *dst*. + + If *dst* is a path, the metadata of *src* are *not* copied. + """ + if is_writable_file_like(dst): + fh = (open(src, encoding='latin-1') + if file_requires_unicode(dst) + else open(src, 'rb')) + with fh: + shutil.copyfileobj(fh, dst) + else: + shutil.move(src, dst, copy_function=shutil.copyfile) + + +def _font_to_ps_type3(font_path, chars): + """ + Subset *chars* from the font at *font_path* into a Type 3 font. + + Parameters + ---------- + font_path : path-like + Path to the font to be subsetted. + chars : str + The characters to include in the subsetted font. + + Returns + ------- + str + The string representation of a Type 3 font, which can be included + verbatim into a PostScript file. + """ + font = get_font(font_path, hinting_factor=1) + glyph_ids = [font.get_char_index(c) for c in chars] + + preamble = """\ +%!PS-Adobe-3.0 Resource-Font +%%Creator: Converted from TrueType to Type 3 by Matplotlib. +10 dict begin +/FontName /{font_name} def +/PaintType 0 def +/FontMatrix [{inv_units_per_em} 0 0 {inv_units_per_em} 0 0] def +/FontBBox [{bbox}] def +/FontType 3 def +/Encoding [{encoding}] def +/CharStrings {num_glyphs} dict dup begin +/.notdef 0 def +""".format(font_name=font.postscript_name, + inv_units_per_em=1 / font.units_per_EM, + bbox=" ".join(map(str, font.bbox)), + encoding=" ".join(f"/{font.get_glyph_name(glyph_id)}" + for glyph_id in glyph_ids), + num_glyphs=len(glyph_ids) + 1) + postamble = """ +end readonly def + +/BuildGlyph { + exch begin + CharStrings exch + 2 copy known not {pop /.notdef} if + true 3 1 roll get exec + end +} _d + +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +} _d + +FontName currentdict end definefont pop +""" + + entries = [] + for glyph_id in glyph_ids: + g = font.load_glyph(glyph_id, LOAD_NO_SCALE) + v, c = font.get_path() + entries.append( + "/%(name)s{%(bbox)s sc\n" % { + "name": font.get_glyph_name(glyph_id), + "bbox": " ".join(map(str, [g.horiAdvance, 0, *g.bbox])), + } + + _path.convert_to_string( + # Convert back to TrueType's internal units (1/64's). + # (Other dimensions are already in these units.) + Path(v * 64, c), None, None, False, None, 0, + # No code for quad Beziers triggers auto-conversion to cubics. + # Drop intermediate closepolys (relying on the outline + # decomposer always explicitly moving to the closing point + # first). + [b"m", b"l", b"", b"c", b""], True).decode("ascii") + + "ce} _d" + ) + + return preamble + "\n".join(entries) + postamble + + +def _font_to_ps_type42(font_path, chars, fh): + """ + Subset *chars* from the font at *font_path* into a Type 42 font at *fh*. + + Parameters + ---------- + font_path : path-like + Path to the font to be subsetted. + chars : str + The characters to include in the subsetted font. + fh : file-like + Where to write the font. + """ + subset_str = ''.join(chr(c) for c in chars) + _log.debug("SUBSET %s characters: %s", font_path, subset_str) + try: + fontdata = _backend_pdf_ps.get_glyphs_subset(font_path, subset_str) + _log.debug("SUBSET %s %d -> %d", font_path, os.stat(font_path).st_size, + fontdata.getbuffer().nbytes) + + # Give ttconv a subsetted font along with updated glyph_ids. + font = FT2Font(fontdata) + glyph_ids = [font.get_char_index(c) for c in chars] + with TemporaryDirectory() as tmpdir: + tmpfile = os.path.join(tmpdir, "tmp.ttf") + + with open(tmpfile, 'wb') as tmp: + tmp.write(fontdata.getvalue()) + + # TODO: allow convert_ttf_to_ps to input file objects (BytesIO) + convert_ttf_to_ps(os.fsencode(tmpfile), fh, 42, glyph_ids) + except RuntimeError: + _log.warning( + "The PostScript backend does not currently " + "support the selected font.") + raise + + +def _log_if_debug_on(meth): + """ + Wrap `RendererPS` method *meth* to emit a PS comment with the method name, + if the global flag `debugPS` is set. + """ + @functools.wraps(meth) + def wrapper(self, *args, **kwargs): + if debugPS: + self._pswriter.write(f"% {meth.__name__}\n") + return meth(self, *args, **kwargs) + + return wrapper + + +class RendererPS(_backend_pdf_ps.RendererPDFPSBase): + """ + The renderer handles all the drawing primitives using a graphics + context instance that controls the colors/styles. + """ + + _afm_font_dir = cbook._get_data_path("fonts/afm") + _use_afm_rc_name = "ps.useafm" + + def __init__(self, width, height, pswriter, imagedpi=72): + # Although postscript itself is dpi independent, we need to inform the + # image code about a requested dpi to generate high resolution images + # and them scale them before embedding them. + super().__init__(width, height) + self._pswriter = pswriter + if mpl.rcParams['text.usetex']: + self.textcnt = 0 + self.psfrag = [] + self.imagedpi = imagedpi + + # current renderer state (None=uninitialised) + self.color = None + self.linewidth = None + self.linejoin = None + self.linecap = None + self.linedash = None + self.fontname = None + self.fontsize = None + self._hatches = {} + self.image_magnification = imagedpi / 72 + self._clip_paths = {} + self._path_collection_id = 0 + + self._character_tracker = _backend_pdf_ps.CharacterTracker() + self._logwarn_once = functools.cache(_log.warning) + + def _is_transparent(self, rgb_or_rgba): + if rgb_or_rgba is None: + return True # Consistent with rgbFace semantics. + elif len(rgb_or_rgba) == 4: + if rgb_or_rgba[3] == 0: + return True + if rgb_or_rgba[3] != 1: + self._logwarn_once( + "The PostScript backend does not support transparency; " + "partially transparent artists will be rendered opaque.") + return False + else: # len() == 3. + return False + + def set_color(self, r, g, b, store=True): + if (r, g, b) != self.color: + self._pswriter.write(f"{_nums_to_str(r)} setgray\n" + if r == g == b else + f"{_nums_to_str(r, g, b)} setrgbcolor\n") + if store: + self.color = (r, g, b) + + def set_linewidth(self, linewidth, store=True): + linewidth = float(linewidth) + if linewidth != self.linewidth: + self._pswriter.write(f"{_nums_to_str(linewidth)} setlinewidth\n") + if store: + self.linewidth = linewidth + + @staticmethod + def _linejoin_cmd(linejoin): + # Support for directly passing integer values is for backcompat. + linejoin = {'miter': 0, 'round': 1, 'bevel': 2, 0: 0, 1: 1, 2: 2}[ + linejoin] + return f"{linejoin:d} setlinejoin\n" + + def set_linejoin(self, linejoin, store=True): + if linejoin != self.linejoin: + self._pswriter.write(self._linejoin_cmd(linejoin)) + if store: + self.linejoin = linejoin + + @staticmethod + def _linecap_cmd(linecap): + # Support for directly passing integer values is for backcompat. + linecap = {'butt': 0, 'round': 1, 'projecting': 2, 0: 0, 1: 1, 2: 2}[ + linecap] + return f"{linecap:d} setlinecap\n" + + def set_linecap(self, linecap, store=True): + if linecap != self.linecap: + self._pswriter.write(self._linecap_cmd(linecap)) + if store: + self.linecap = linecap + + def set_linedash(self, offset, seq, store=True): + if self.linedash is not None: + oldo, oldseq = self.linedash + if np.array_equal(seq, oldseq) and oldo == offset: + return + + self._pswriter.write(f"[{_nums_to_str(*seq)}] {_nums_to_str(offset)} setdash\n" + if seq is not None and len(seq) else + "[] 0 setdash\n") + if store: + self.linedash = (offset, seq) + + def set_font(self, fontname, fontsize, store=True): + if (fontname, fontsize) != (self.fontname, self.fontsize): + self._pswriter.write(f"/{fontname} {fontsize:1.3f} selectfont\n") + if store: + self.fontname = fontname + self.fontsize = fontsize + + def create_hatch(self, hatch): + sidelen = 72 + if hatch in self._hatches: + return self._hatches[hatch] + name = 'H%d' % len(self._hatches) + linewidth = mpl.rcParams['hatch.linewidth'] + pageheight = self.height * 72 + self._pswriter.write(f"""\ + << /PatternType 1 + /PaintType 2 + /TilingType 2 + /BBox[0 0 {sidelen:d} {sidelen:d}] + /XStep {sidelen:d} + /YStep {sidelen:d} + + /PaintProc {{ + pop + {linewidth:g} setlinewidth +{self._convert_path( + Path.hatch(hatch), Affine2D().scale(sidelen), simplify=False)} + gsave + fill + grestore + stroke + }} bind + >> + matrix + 0 {pageheight:g} translate + makepattern + /{name} exch def +""") + self._hatches[hatch] = name + return name + + def get_image_magnification(self): + """ + Get the factor by which to magnify images passed to draw_image. + Allows a backend to have images at a different resolution to other + artists. + """ + return self.image_magnification + + def _convert_path(self, path, transform, clip=False, simplify=None): + if clip: + clip = (0.0, 0.0, self.width * 72.0, self.height * 72.0) + else: + clip = None + return _path.convert_to_string( + path, transform, clip, simplify, None, + 6, [b"m", b"l", b"", b"c", b"cl"], True).decode("ascii") + + def _get_clip_cmd(self, gc): + clip = [] + rect = gc.get_clip_rectangle() + if rect is not None: + clip.append(f"{_nums_to_str(*rect.p0, *rect.size)} rectclip\n") + path, trf = gc.get_clip_path() + if path is not None: + key = (path, id(trf)) + custom_clip_cmd = self._clip_paths.get(key) + if custom_clip_cmd is None: + custom_clip_cmd = "c%d" % len(self._clip_paths) + self._pswriter.write(f"""\ +/{custom_clip_cmd} {{ +{self._convert_path(path, trf, simplify=False)} +clip +newpath +}} bind def +""") + self._clip_paths[key] = custom_clip_cmd + clip.append(f"{custom_clip_cmd}\n") + return "".join(clip) + + @_log_if_debug_on + def draw_image(self, gc, x, y, im, transform=None): + # docstring inherited + + h, w = im.shape[:2] + imagecmd = "false 3 colorimage" + data = im[::-1, :, :3] # Vertically flipped rgb values. + hexdata = data.tobytes().hex("\n", -64) # Linewrap to 128 chars. + + if transform is None: + matrix = "1 0 0 1 0 0" + xscale = w / self.image_magnification + yscale = h / self.image_magnification + else: + matrix = " ".join(map(str, transform.frozen().to_values())) + xscale = 1.0 + yscale = 1.0 + + self._pswriter.write(f"""\ +gsave +{self._get_clip_cmd(gc)} +{x:g} {y:g} translate +[{matrix}] concat +{xscale:g} {yscale:g} scale +/DataString {w:d} string def +{w:d} {h:d} 8 [ {w:d} 0 0 -{h:d} 0 {h:d} ] +{{ +currentfile DataString readhexstring pop +}} bind {imagecmd} +{hexdata} +grestore +""") + + @_log_if_debug_on + def draw_path(self, gc, path, transform, rgbFace=None): + # docstring inherited + clip = rgbFace is None and gc.get_hatch_path() is None + simplify = path.should_simplify and clip + ps = self._convert_path(path, transform, clip=clip, simplify=simplify) + self._draw_ps(ps, gc, rgbFace) + + @_log_if_debug_on + def draw_markers( + self, gc, marker_path, marker_trans, path, trans, rgbFace=None): + # docstring inherited + + ps_color = ( + None + if self._is_transparent(rgbFace) + else f'{_nums_to_str(rgbFace[0])} setgray' + if rgbFace[0] == rgbFace[1] == rgbFace[2] + else f'{_nums_to_str(*rgbFace[:3])} setrgbcolor') + + # construct the generic marker command: + + # don't want the translate to be global + ps_cmd = ['/o {', 'gsave', 'newpath', 'translate'] + + lw = gc.get_linewidth() + alpha = (gc.get_alpha() + if gc.get_forced_alpha() or len(gc.get_rgb()) == 3 + else gc.get_rgb()[3]) + stroke = lw > 0 and alpha > 0 + if stroke: + ps_cmd.append('%.1f setlinewidth' % lw) + ps_cmd.append(self._linejoin_cmd(gc.get_joinstyle())) + ps_cmd.append(self._linecap_cmd(gc.get_capstyle())) + + ps_cmd.append(self._convert_path(marker_path, marker_trans, + simplify=False)) + + if rgbFace: + if stroke: + ps_cmd.append('gsave') + if ps_color: + ps_cmd.extend([ps_color, 'fill']) + if stroke: + ps_cmd.append('grestore') + + if stroke: + ps_cmd.append('stroke') + ps_cmd.extend(['grestore', '} bind def']) + + for vertices, code in path.iter_segments( + trans, + clip=(0, 0, self.width*72, self.height*72), + simplify=False): + if len(vertices): + x, y = vertices[-2:] + ps_cmd.append(f"{x:g} {y:g} o") + + ps = '\n'.join(ps_cmd) + self._draw_ps(ps, gc, rgbFace, fill=False, stroke=False) + + @_log_if_debug_on + def draw_path_collection(self, gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position): + # Is the optimization worth it? Rough calculation: + # cost of emitting a path in-line is + # (len_path + 2) * uses_per_path + # cost of definition+use is + # (len_path + 3) + 3 * uses_per_path + len_path = len(paths[0].vertices) if len(paths) > 0 else 0 + uses_per_path = self._iter_collection_uses_per_path( + paths, all_transforms, offsets, facecolors, edgecolors) + should_do_optimization = \ + len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path + if not should_do_optimization: + return RendererBase.draw_path_collection( + self, gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position) + + path_codes = [] + for i, (path, transform) in enumerate(self._iter_collection_raw_paths( + master_transform, paths, all_transforms)): + name = 'p%d_%d' % (self._path_collection_id, i) + path_bytes = self._convert_path(path, transform, simplify=False) + self._pswriter.write(f"""\ +/{name} {{ +newpath +translate +{path_bytes} +}} bind def +""") + path_codes.append(name) + + for xo, yo, path_id, gc0, rgbFace in self._iter_collection( + gc, path_codes, offsets, offset_trans, + facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): + ps = f"{xo:g} {yo:g} {path_id}" + self._draw_ps(ps, gc0, rgbFace) + + self._path_collection_id += 1 + + @_log_if_debug_on + def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): + # docstring inherited + if self._is_transparent(gc.get_rgb()): + return # Special handling for fully transparent. + + if not hasattr(self, "psfrag"): + self._logwarn_once( + "The PS backend determines usetex status solely based on " + "rcParams['text.usetex'] and does not support having " + "usetex=True only for some elements; this element will thus " + "be rendered as if usetex=False.") + self.draw_text(gc, x, y, s, prop, angle, False, mtext) + return + + w, h, bl = self.get_text_width_height_descent(s, prop, ismath="TeX") + fontsize = prop.get_size_in_points() + thetext = 'psmarker%d' % self.textcnt + color = _nums_to_str(*gc.get_rgb()[:3], sep=',') + fontcmd = {'sans-serif': r'{\sffamily %s}', + 'monospace': r'{\ttfamily %s}'}.get( + mpl.rcParams['font.family'][0], r'{\rmfamily %s}') + s = fontcmd % s + tex = r'\color[rgb]{%s} %s' % (color, s) + + # Stick to bottom-left alignment, so subtract descent from the text-normal + # direction since text is normally positioned by its baseline. + rangle = np.radians(angle + 90) + pos = _nums_to_str(x - bl * np.cos(rangle), y - bl * np.sin(rangle)) + self.psfrag.append( + r'\psfrag{%s}[bl][bl][1][%f]{\fontsize{%f}{%f}%s}' % ( + thetext, angle, fontsize, fontsize*1.25, tex)) + + self._pswriter.write(f"""\ +gsave +{pos} moveto +({thetext}) +show +grestore +""") + self.textcnt += 1 + + @_log_if_debug_on + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + # docstring inherited + + if self._is_transparent(gc.get_rgb()): + return # Special handling for fully transparent. + + if ismath == 'TeX': + return self.draw_tex(gc, x, y, s, prop, angle) + + if ismath: + return self.draw_mathtext(gc, x, y, s, prop, angle) + + stream = [] # list of (ps_name, x, char_name) + + if mpl.rcParams['ps.useafm']: + font = self._get_font_afm(prop) + ps_name = (font.postscript_name.encode("ascii", "replace") + .decode("ascii")) + scale = 0.001 * prop.get_size_in_points() + thisx = 0 + last_name = None # kerns returns 0 for None. + for c in s: + name = uni2type1.get(ord(c), f"uni{ord(c):04X}") + try: + width = font.get_width_from_char_name(name) + except KeyError: + name = 'question' + width = font.get_width_char('?') + kern = font.get_kern_dist_from_name(last_name, name) + last_name = name + thisx += kern * scale + stream.append((ps_name, thisx, name)) + thisx += width * scale + + else: + font = self._get_font_ttf(prop) + self._character_tracker.track(font, s) + for item in _text_helpers.layout(s, font): + ps_name = (item.ft_object.postscript_name + .encode("ascii", "replace").decode("ascii")) + glyph_name = item.ft_object.get_glyph_name(item.glyph_idx) + stream.append((ps_name, item.x, glyph_name)) + self.set_color(*gc.get_rgb()) + + for ps_name, group in itertools. \ + groupby(stream, lambda entry: entry[0]): + self.set_font(ps_name, prop.get_size_in_points(), False) + thetext = "\n".join(f"{x:g} 0 m /{name:s} glyphshow" + for _, x, name in group) + self._pswriter.write(f"""\ +gsave +{self._get_clip_cmd(gc)} +{x:g} {y:g} translate +{angle:g} rotate +{thetext} +grestore +""") + + @_log_if_debug_on + def draw_mathtext(self, gc, x, y, s, prop, angle): + """Draw the math text using matplotlib.mathtext.""" + width, height, descent, glyphs, rects = \ + self._text2path.mathtext_parser.parse(s, 72, prop) + self.set_color(*gc.get_rgb()) + self._pswriter.write( + f"gsave\n" + f"{x:g} {y:g} translate\n" + f"{angle:g} rotate\n") + lastfont = None + for font, fontsize, num, ox, oy in glyphs: + self._character_tracker.track_glyph(font, num) + if (font.postscript_name, fontsize) != lastfont: + lastfont = font.postscript_name, fontsize + self._pswriter.write( + f"/{font.postscript_name} {fontsize} selectfont\n") + glyph_name = ( + font.get_name_char(chr(num)) if isinstance(font, AFM) else + font.get_glyph_name(font.get_char_index(num))) + self._pswriter.write( + f"{ox:g} {oy:g} moveto\n" + f"/{glyph_name} glyphshow\n") + for ox, oy, w, h in rects: + self._pswriter.write(f"{ox} {oy} {w} {h} rectfill\n") + self._pswriter.write("grestore\n") + + @_log_if_debug_on + def draw_gouraud_triangle(self, gc, points, colors, trans): + self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)), + colors.reshape((1, 3, 4)), trans) + + @_log_if_debug_on + def draw_gouraud_triangles(self, gc, points, colors, trans): + assert len(points) == len(colors) + if len(points) == 0: + return + assert points.ndim == 3 + assert points.shape[1] == 3 + assert points.shape[2] == 2 + assert colors.ndim == 3 + assert colors.shape[1] == 3 + assert colors.shape[2] == 4 + + shape = points.shape + flat_points = points.reshape((shape[0] * shape[1], 2)) + flat_points = trans.transform(flat_points) + flat_colors = colors.reshape((shape[0] * shape[1], 4)) + points_min = np.min(flat_points, axis=0) - (1 << 12) + points_max = np.max(flat_points, axis=0) + (1 << 12) + factor = np.ceil((2 ** 32 - 1) / (points_max - points_min)) + + xmin, ymin = points_min + xmax, ymax = points_max + + data = np.empty( + shape[0] * shape[1], + dtype=[('flags', 'u1'), ('points', '2>u4'), ('colors', '3u1')]) + data['flags'] = 0 + data['points'] = (flat_points - points_min) * factor + data['colors'] = flat_colors[:, :3] * 255.0 + hexdata = data.tobytes().hex("\n", -64) # Linewrap to 128 chars. + + self._pswriter.write(f"""\ +gsave +<< /ShadingType 4 + /ColorSpace [/DeviceRGB] + /BitsPerCoordinate 32 + /BitsPerComponent 8 + /BitsPerFlag 8 + /AntiAlias true + /Decode [ {xmin:g} {xmax:g} {ymin:g} {ymax:g} 0 1 0 1 0 1 ] + /DataSource < +{hexdata} +> +>> +shfill +grestore +""") + + def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True): + """ + Emit the PostScript snippet *ps* with all the attributes from *gc* + applied. *ps* must consist of PostScript commands to construct a path. + + The *fill* and/or *stroke* kwargs can be set to False if the *ps* + string already includes filling and/or stroking, in which case + `_draw_ps` is just supplying properties and clipping. + """ + write = self._pswriter.write + mightstroke = (gc.get_linewidth() > 0 + and not self._is_transparent(gc.get_rgb())) + if not mightstroke: + stroke = False + if self._is_transparent(rgbFace): + fill = False + hatch = gc.get_hatch() + + if mightstroke: + self.set_linewidth(gc.get_linewidth()) + self.set_linejoin(gc.get_joinstyle()) + self.set_linecap(gc.get_capstyle()) + self.set_linedash(*gc.get_dashes()) + if mightstroke or hatch: + self.set_color(*gc.get_rgb()[:3]) + write('gsave\n') + + write(self._get_clip_cmd(gc)) + + write(ps.strip()) + write("\n") + + if fill: + if stroke or hatch: + write("gsave\n") + self.set_color(*rgbFace[:3], store=False) + write("fill\n") + if stroke or hatch: + write("grestore\n") + + if hatch: + hatch_name = self.create_hatch(hatch) + write("gsave\n") + write(_nums_to_str(*gc.get_hatch_color()[:3])) + write(f" {hatch_name} setpattern fill grestore\n") + + if stroke: + write("stroke\n") + + write("grestore\n") + + +class _Orientation(Enum): + portrait, landscape = range(2) + + def swap_if_landscape(self, shape): + return shape[::-1] if self.name == "landscape" else shape + + +class FigureCanvasPS(FigureCanvasBase): + fixed_dpi = 72 + filetypes = {'ps': 'Postscript', + 'eps': 'Encapsulated Postscript'} + + def get_default_filetype(self): + return 'ps' + + def _print_ps( + self, fmt, outfile, *, + metadata=None, papertype=None, orientation='portrait', + bbox_inches_restore=None, **kwargs): + + dpi = self.figure.dpi + self.figure.dpi = 72 # Override the dpi kwarg + + dsc_comments = {} + if isinstance(outfile, (str, os.PathLike)): + filename = pathlib.Path(outfile).name + dsc_comments["Title"] = \ + filename.encode("ascii", "replace").decode("ascii") + dsc_comments["Creator"] = (metadata or {}).get( + "Creator", + f"Matplotlib v{mpl.__version__}, https://matplotlib.org/") + # See https://reproducible-builds.org/specs/source-date-epoch/ + source_date_epoch = os.getenv("SOURCE_DATE_EPOCH") + dsc_comments["CreationDate"] = ( + datetime.datetime.fromtimestamp( + int(source_date_epoch), + datetime.timezone.utc).strftime("%a %b %d %H:%M:%S %Y") + if source_date_epoch + else time.ctime()) + dsc_comments = "\n".join( + f"%%{k}: {v}" for k, v in dsc_comments.items()) + + if papertype is None: + papertype = mpl.rcParams['ps.papersize'] + papertype = papertype.lower() + _api.check_in_list(['figure', 'auto', *papersize], papertype=papertype) + + orientation = _api.check_getitem( + _Orientation, orientation=orientation.lower()) + + printer = (self._print_figure_tex + if mpl.rcParams['text.usetex'] else + self._print_figure) + printer(fmt, outfile, dpi=dpi, dsc_comments=dsc_comments, + orientation=orientation, papertype=papertype, + bbox_inches_restore=bbox_inches_restore, **kwargs) + + def _print_figure( + self, fmt, outfile, *, + dpi, dsc_comments, orientation, papertype, + bbox_inches_restore=None): + """ + Render the figure to a filesystem path or a file-like object. + + Parameters are as for `.print_figure`, except that *dsc_comments* is a + string containing Document Structuring Convention comments, + generated from the *metadata* parameter to `.print_figure`. + """ + is_eps = fmt == 'eps' + if not (isinstance(outfile, (str, os.PathLike)) + or is_writable_file_like(outfile)): + raise ValueError("outfile must be a path or a file-like object") + + # find the appropriate papertype + width, height = self.figure.get_size_inches() + if papertype == 'auto': + papertype = _get_papertype(*orientation.swap_if_landscape((width, height))) + + if is_eps or papertype == 'figure': + paper_width, paper_height = width, height + else: + paper_width, paper_height = orientation.swap_if_landscape( + papersize[papertype]) + + # center the figure on the paper + xo = 72 * 0.5 * (paper_width - width) + yo = 72 * 0.5 * (paper_height - height) + + llx = xo + lly = yo + urx = llx + self.figure.bbox.width + ury = lly + self.figure.bbox.height + rotation = 0 + if orientation is _Orientation.landscape: + llx, lly, urx, ury = lly, llx, ury, urx + xo, yo = 72 * paper_height - yo, xo + rotation = 90 + bbox = (llx, lly, urx, ury) + + self._pswriter = StringIO() + + # mixed mode rendering + ps_renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi) + renderer = MixedModeRenderer( + self.figure, width, height, dpi, ps_renderer, + bbox_inches_restore=bbox_inches_restore) + + self.figure.draw(renderer) + + def print_figure_impl(fh): + # write the PostScript headers + if is_eps: + print("%!PS-Adobe-3.0 EPSF-3.0", file=fh) + else: + print("%!PS-Adobe-3.0", file=fh) + if papertype != 'figure': + print(f"%%DocumentPaperSizes: {papertype}", file=fh) + print("%%Pages: 1", file=fh) + print(f"%%LanguageLevel: 3\n" + f"{dsc_comments}\n" + f"%%Orientation: {orientation.name}\n" + f"{get_bbox_header(bbox)[0]}\n" + f"%%EndComments\n", + end="", file=fh) + + Ndict = len(_psDefs) + print("%%BeginProlog", file=fh) + if not mpl.rcParams['ps.useafm']: + Ndict += len(ps_renderer._character_tracker.used) + print("/mpldict %d dict def" % Ndict, file=fh) + print("mpldict begin", file=fh) + print("\n".join(_psDefs), file=fh) + if not mpl.rcParams['ps.useafm']: + for font_path, chars \ + in ps_renderer._character_tracker.used.items(): + if not chars: + continue + fonttype = mpl.rcParams['ps.fonttype'] + # Can't use more than 255 chars from a single Type 3 font. + if len(chars) > 255: + fonttype = 42 + fh.flush() + if fonttype == 3: + fh.write(_font_to_ps_type3(font_path, chars)) + else: # Type 42 only. + _font_to_ps_type42(font_path, chars, fh) + print("end", file=fh) + print("%%EndProlog", file=fh) + + if not is_eps: + print("%%Page: 1 1", file=fh) + print("mpldict begin", file=fh) + + print("%s translate" % _nums_to_str(xo, yo), file=fh) + if rotation: + print("%d rotate" % rotation, file=fh) + print(f"0 0 {_nums_to_str(width*72, height*72)} rectclip", file=fh) + + # write the figure + print(self._pswriter.getvalue(), file=fh) + + # write the trailer + print("end", file=fh) + print("showpage", file=fh) + if not is_eps: + print("%%EOF", file=fh) + fh.flush() + + if mpl.rcParams['ps.usedistiller']: + # We are going to use an external program to process the output. + # Write to a temporary file. + with TemporaryDirectory() as tmpdir: + tmpfile = os.path.join(tmpdir, "tmp.ps") + with open(tmpfile, 'w', encoding='latin-1') as fh: + print_figure_impl(fh) + if mpl.rcParams['ps.usedistiller'] == 'ghostscript': + _try_distill(gs_distill, + tmpfile, is_eps, ptype=papertype, bbox=bbox) + elif mpl.rcParams['ps.usedistiller'] == 'xpdf': + _try_distill(xpdf_distill, + tmpfile, is_eps, ptype=papertype, bbox=bbox) + _move_path_to_path_or_stream(tmpfile, outfile) + + else: # Write directly to outfile. + with cbook.open_file_cm(outfile, "w", encoding="latin-1") as file: + if not file_requires_unicode(file): + file = codecs.getwriter("latin-1")(file) + print_figure_impl(file) + + def _print_figure_tex( + self, fmt, outfile, *, + dpi, dsc_comments, orientation, papertype, + bbox_inches_restore=None): + """ + If :rc:`text.usetex` is True, a temporary pair of tex/eps files + are created to allow tex to manage the text layout via the PSFrags + package. These files are processed to yield the final ps or eps file. + + The rest of the behavior is as for `._print_figure`. + """ + is_eps = fmt == 'eps' + + width, height = self.figure.get_size_inches() + xo = 0 + yo = 0 + + llx = xo + lly = yo + urx = llx + self.figure.bbox.width + ury = lly + self.figure.bbox.height + bbox = (llx, lly, urx, ury) + + self._pswriter = StringIO() + + # mixed mode rendering + ps_renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi) + renderer = MixedModeRenderer(self.figure, + width, height, dpi, ps_renderer, + bbox_inches_restore=bbox_inches_restore) + + self.figure.draw(renderer) + + # write to a temp file, we'll move it to outfile when done + with TemporaryDirectory() as tmpdir: + tmppath = pathlib.Path(tmpdir, "tmp.ps") + tmppath.write_text( + f"""\ +%!PS-Adobe-3.0 EPSF-3.0 +%%LanguageLevel: 3 +{dsc_comments} +{get_bbox_header(bbox)[0]} +%%EndComments +%%BeginProlog +/mpldict {len(_psDefs)} dict def +mpldict begin +{"".join(_psDefs)} +end +%%EndProlog +mpldict begin +{_nums_to_str(xo, yo)} translate +0 0 {_nums_to_str(width*72, height*72)} rectclip +{self._pswriter.getvalue()} +end +showpage +""", + encoding="latin-1") + + if orientation is _Orientation.landscape: # now, ready to rotate + width, height = height, width + bbox = (lly, llx, ury, urx) + + # set the paper size to the figure size if is_eps. The + # resulting ps file has the given size with correct bounding + # box so that there is no need to call 'pstoeps' + if is_eps or papertype == 'figure': + paper_width, paper_height = orientation.swap_if_landscape( + self.figure.get_size_inches()) + else: + if papertype == 'auto': + papertype = _get_papertype(width, height) + paper_width, paper_height = papersize[papertype] + + psfrag_rotated = _convert_psfrags( + tmppath, ps_renderer.psfrag, paper_width, paper_height, + orientation.name) + + if (mpl.rcParams['ps.usedistiller'] == 'ghostscript' + or mpl.rcParams['text.usetex']): + _try_distill(gs_distill, + tmppath, is_eps, ptype=papertype, bbox=bbox, + rotated=psfrag_rotated) + elif mpl.rcParams['ps.usedistiller'] == 'xpdf': + _try_distill(xpdf_distill, + tmppath, is_eps, ptype=papertype, bbox=bbox, + rotated=psfrag_rotated) + + _move_path_to_path_or_stream(tmppath, outfile) + + print_ps = functools.partialmethod(_print_ps, "ps") + print_eps = functools.partialmethod(_print_ps, "eps") + + def draw(self): + self.figure.draw_without_rendering() + return super().draw() + + +def _convert_psfrags(tmppath, psfrags, paper_width, paper_height, orientation): + """ + When we want to use the LaTeX backend with postscript, we write PSFrag tags + to a temporary postscript file, each one marking a position for LaTeX to + render some text. convert_psfrags generates a LaTeX document containing the + commands to convert those tags to text. LaTeX/dvips produces the postscript + file that includes the actual text. + """ + with mpl.rc_context({ + "text.latex.preamble": + mpl.rcParams["text.latex.preamble"] + + mpl.texmanager._usepackage_if_not_loaded("color") + + mpl.texmanager._usepackage_if_not_loaded("graphicx") + + mpl.texmanager._usepackage_if_not_loaded("psfrag") + + r"\geometry{papersize={%(width)sin,%(height)sin},margin=0in}" + % {"width": paper_width, "height": paper_height} + }): + dvifile = TexManager().make_dvi( + "\n" + r"\begin{figure}""\n" + r" \centering\leavevmode""\n" + r" %(psfrags)s""\n" + r" \includegraphics*[angle=%(angle)s]{%(epsfile)s}""\n" + r"\end{figure}" + % { + "psfrags": "\n".join(psfrags), + "angle": 90 if orientation == 'landscape' else 0, + "epsfile": tmppath.resolve().as_posix(), + }, + fontsize=10) # tex's default fontsize. + + with TemporaryDirectory() as tmpdir: + psfile = os.path.join(tmpdir, "tmp.ps") + cbook._check_and_log_subprocess( + ['dvips', '-q', '-R0', '-o', psfile, dvifile], _log) + shutil.move(psfile, tmppath) + + # check if the dvips created a ps in landscape paper. Somehow, + # above latex+dvips results in a ps file in a landscape mode for a + # certain figure sizes (e.g., 8.3in, 5.8in which is a5). And the + # bounding box of the final output got messed up. We check see if + # the generated ps file is in landscape and return this + # information. The return value is used in pstoeps step to recover + # the correct bounding box. 2010-06-05 JJL + with open(tmppath) as fh: + psfrag_rotated = "Landscape" in fh.read(1000) + return psfrag_rotated + + +def _try_distill(func, tmppath, *args, **kwargs): + try: + func(str(tmppath), *args, **kwargs) + except mpl.ExecutableNotFoundError as exc: + _log.warning("%s. Distillation step skipped.", exc) + + +def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): + """ + Use ghostscript's pswrite or epswrite device to distill a file. + This yields smaller files without illegal encapsulated postscript + operators. The output is low-level, converting text to outlines. + """ + + if eps: + paper_option = ["-dEPSCrop"] + elif ptype == "figure": + # The bbox will have its lower-left corner at (0, 0), so upper-right + # corner corresponds with paper size. + paper_option = [f"-dDEVICEWIDTHPOINTS={bbox[2]}", + f"-dDEVICEHEIGHTPOINTS={bbox[3]}"] + else: + paper_option = [f"-sPAPERSIZE={ptype}"] + + psfile = tmpfile + '.ps' + dpi = mpl.rcParams['ps.distiller.res'] + + cbook._check_and_log_subprocess( + [mpl._get_executable_info("gs").executable, + "-dBATCH", "-dNOPAUSE", "-r%d" % dpi, "-sDEVICE=ps2write", + *paper_option, f"-sOutputFile={psfile}", tmpfile], + _log) + + os.remove(tmpfile) + shutil.move(psfile, tmpfile) + + # While it is best if above steps preserve the original bounding + # box, there seem to be cases when it is not. For those cases, + # the original bbox can be restored during the pstoeps step. + + if eps: + # For some versions of gs, above steps result in a ps file where the + # original bbox is no more correct. Do not adjust bbox for now. + pstoeps(tmpfile, bbox, rotated=rotated) + + +def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): + """ + Use ghostscript's ps2pdf and xpdf's/poppler's pdftops to distill a file. + This yields smaller files without illegal encapsulated postscript + operators. This distiller is preferred, generating high-level postscript + output that treats text as text. + """ + mpl._get_executable_info("gs") # Effectively checks for ps2pdf. + mpl._get_executable_info("pdftops") + + if eps: + paper_option = ["-dEPSCrop"] + elif ptype == "figure": + # The bbox will have its lower-left corner at (0, 0), so upper-right + # corner corresponds with paper size. + paper_option = [f"-dDEVICEWIDTHPOINTS#{bbox[2]}", + f"-dDEVICEHEIGHTPOINTS#{bbox[3]}"] + else: + paper_option = [f"-sPAPERSIZE#{ptype}"] + + with TemporaryDirectory() as tmpdir: + tmppdf = pathlib.Path(tmpdir, "tmp.pdf") + tmpps = pathlib.Path(tmpdir, "tmp.ps") + # Pass options as `-foo#bar` instead of `-foo=bar` to keep Windows + # happy (https://ghostscript.com/doc/9.56.1/Use.htm#MS_Windows). + cbook._check_and_log_subprocess( + ["ps2pdf", + "-dAutoFilterColorImages#false", + "-dAutoFilterGrayImages#false", + "-sAutoRotatePages#None", + "-sGrayImageFilter#FlateEncode", + "-sColorImageFilter#FlateEncode", + *paper_option, + tmpfile, tmppdf], _log) + cbook._check_and_log_subprocess( + ["pdftops", "-paper", "match", "-level3", tmppdf, tmpps], _log) + shutil.move(tmpps, tmpfile) + if eps: + pstoeps(tmpfile) + + +def get_bbox_header(lbrt, rotated=False): + """ + Return a postscript header string for the given bbox lbrt=(l, b, r, t). + Optionally, return rotate command. + """ + + l, b, r, t = lbrt + if rotated: + rotate = f"{l+r:.2f} {0:.2f} translate\n90 rotate" + else: + rotate = "" + bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t)) + hires_bbox_info = f'%%HiResBoundingBox: {l:.6f} {b:.6f} {r:.6f} {t:.6f}' + + return '\n'.join([bbox_info, hires_bbox_info]), rotate + + +def pstoeps(tmpfile, bbox=None, rotated=False): + """ + Convert the postscript to encapsulated postscript. The bbox of + the eps file will be replaced with the given *bbox* argument. If + None, original bbox will be used. + """ + + # if rotated==True, the output eps file need to be rotated + if bbox: + bbox_info, rotate = get_bbox_header(bbox, rotated=rotated) + else: + bbox_info, rotate = None, None + + epsfile = tmpfile + '.eps' + with open(epsfile, 'wb') as epsh, open(tmpfile, 'rb') as tmph: + write = epsh.write + # Modify the header: + for line in tmph: + if line.startswith(b'%!PS'): + write(b"%!PS-Adobe-3.0 EPSF-3.0\n") + if bbox: + write(bbox_info.encode('ascii') + b'\n') + elif line.startswith(b'%%EndComments'): + write(line) + write(b'%%BeginProlog\n' + b'save\n' + b'countdictstack\n' + b'mark\n' + b'newpath\n' + b'/showpage {} def\n' + b'/setpagedevice {pop} def\n' + b'%%EndProlog\n' + b'%%Page 1 1\n') + if rotate: + write(rotate.encode('ascii') + b'\n') + break + elif bbox and line.startswith((b'%%Bound', b'%%HiResBound', + b'%%DocumentMedia', b'%%Pages')): + pass + else: + write(line) + # Now rewrite the rest of the file, and modify the trailer. + # This is done in a second loop such that the header of the embedded + # eps file is not modified. + for line in tmph: + if line.startswith(b'%%EOF'): + write(b'cleartomark\n' + b'countdictstack\n' + b'exch sub { end } repeat\n' + b'restore\n' + b'showpage\n' + b'%%EOF\n') + elif line.startswith(b'%%PageBoundingBox'): + pass + else: + write(line) + + os.remove(tmpfile) + shutil.move(epsfile, tmpfile) + + +FigureManagerPS = FigureManagerBase + + +# The following Python dictionary psDefs contains the entries for the +# PostScript dictionary mpldict. This dictionary implements most of +# the matplotlib primitives and some abbreviations. +# +# References: +# https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf +# http://preserve.mactech.com/articles/mactech/Vol.09/09.04/PostscriptTutorial +# http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/ +# + +# The usage comments use the notation of the operator summary +# in the PostScript Language reference manual. +_psDefs = [ + # name proc *_d* - + # Note that this cannot be bound to /d, because when embedding a Type3 font + # we may want to define a "d" glyph using "/d{...} d" which would locally + # overwrite the definition. + "/_d { bind def } bind def", + # x y *m* - + "/m { moveto } _d", + # x y *l* - + "/l { lineto } _d", + # x y *r* - + "/r { rlineto } _d", + # x1 y1 x2 y2 x y *c* - + "/c { curveto } _d", + # *cl* - + "/cl { closepath } _d", + # *ce* - + "/ce { closepath eofill } _d", + # wx wy llx lly urx ury *setcachedevice* - + "/sc { setcachedevice } _d", +] + + +@_Backend.export +class _BackendPS(_Backend): + backend_version = 'Level II' + FigureCanvas = FigureCanvasPS diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt.py new file mode 100644 index 00000000..4b3783bc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt.py @@ -0,0 +1,1022 @@ +import functools +import os +import sys +import traceback + +import matplotlib as mpl +from matplotlib import _api, backend_tools, cbook +from matplotlib._pylab_helpers import Gcf +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2, + TimerBase, cursors, ToolContainerBase, MouseButton, + CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent) +import matplotlib.backends.qt_editor.figureoptions as figureoptions +from . import qt_compat +from .qt_compat import ( + QtCore, QtGui, QtWidgets, __version__, QT_API, + _to_int, _isdeleted, _maybe_allow_interrupt +) + + +# SPECIAL_KEYS are Qt::Key that do *not* return their Unicode name +# instead they have manually specified names. +SPECIAL_KEYS = { + _to_int(getattr(QtCore.Qt.Key, k)): v for k, v in [ + ("Key_Escape", "escape"), + ("Key_Tab", "tab"), + ("Key_Backspace", "backspace"), + ("Key_Return", "enter"), + ("Key_Enter", "enter"), + ("Key_Insert", "insert"), + ("Key_Delete", "delete"), + ("Key_Pause", "pause"), + ("Key_SysReq", "sysreq"), + ("Key_Clear", "clear"), + ("Key_Home", "home"), + ("Key_End", "end"), + ("Key_Left", "left"), + ("Key_Up", "up"), + ("Key_Right", "right"), + ("Key_Down", "down"), + ("Key_PageUp", "pageup"), + ("Key_PageDown", "pagedown"), + ("Key_Shift", "shift"), + # In OSX, the control and super (aka cmd/apple) keys are switched. + ("Key_Control", "control" if sys.platform != "darwin" else "cmd"), + ("Key_Meta", "meta" if sys.platform != "darwin" else "control"), + ("Key_Alt", "alt"), + ("Key_CapsLock", "caps_lock"), + ("Key_F1", "f1"), + ("Key_F2", "f2"), + ("Key_F3", "f3"), + ("Key_F4", "f4"), + ("Key_F5", "f5"), + ("Key_F6", "f6"), + ("Key_F7", "f7"), + ("Key_F8", "f8"), + ("Key_F9", "f9"), + ("Key_F10", "f10"), + ("Key_F10", "f11"), + ("Key_F12", "f12"), + ("Key_Super_L", "super"), + ("Key_Super_R", "super"), + ] +} +# Define which modifier keys are collected on keyboard events. +# Elements are (Qt::KeyboardModifiers, Qt::Key) tuples. +# Order determines the modifier order (ctrl+alt+...) reported by Matplotlib. +_MODIFIER_KEYS = [ + (_to_int(getattr(QtCore.Qt.KeyboardModifier, mod)), + _to_int(getattr(QtCore.Qt.Key, key))) + for mod, key in [ + ("ControlModifier", "Key_Control"), + ("AltModifier", "Key_Alt"), + ("ShiftModifier", "Key_Shift"), + ("MetaModifier", "Key_Meta"), + ] +] +cursord = { + k: getattr(QtCore.Qt.CursorShape, v) for k, v in [ + (cursors.MOVE, "SizeAllCursor"), + (cursors.HAND, "PointingHandCursor"), + (cursors.POINTER, "ArrowCursor"), + (cursors.SELECT_REGION, "CrossCursor"), + (cursors.WAIT, "WaitCursor"), + (cursors.RESIZE_HORIZONTAL, "SizeHorCursor"), + (cursors.RESIZE_VERTICAL, "SizeVerCursor"), + ] +} + + +# lru_cache keeps a reference to the QApplication instance, keeping it from +# being GC'd. +@functools.lru_cache(1) +def _create_qApp(): + app = QtWidgets.QApplication.instance() + + # Create a new QApplication and configure it if none exists yet, as only + # one QApplication can exist at a time. + if app is None: + # display_is_valid returns False only if on Linux and neither X11 + # nor Wayland display can be opened. + if not mpl._c_internal_utils.display_is_valid(): + raise RuntimeError('Invalid DISPLAY variable') + + # Check to make sure a QApplication from a different major version + # of Qt is not instantiated in the process + if QT_API in {'PyQt6', 'PySide6'}: + other_bindings = ('PyQt5', 'PySide2') + qt_version = 6 + elif QT_API in {'PyQt5', 'PySide2'}: + other_bindings = ('PyQt6', 'PySide6') + qt_version = 5 + else: + raise RuntimeError("Should never be here") + + for binding in other_bindings: + mod = sys.modules.get(f'{binding}.QtWidgets') + if mod is not None and mod.QApplication.instance() is not None: + other_core = sys.modules.get(f'{binding}.QtCore') + _api.warn_external( + f'Matplotlib is using {QT_API} which wraps ' + f'{QtCore.qVersion()} however an instantiated ' + f'QApplication from {binding} which wraps ' + f'{other_core.qVersion()} exists. Mixing Qt major ' + 'versions may not work as expected.' + ) + break + if qt_version == 5: + try: + QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) + except AttributeError: # Only for Qt>=5.6, <6. + pass + try: + QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy( + QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) + except AttributeError: # Only for Qt>=5.14. + pass + app = QtWidgets.QApplication(["matplotlib"]) + if sys.platform == "darwin": + image = str(cbook._get_data_path('images/matplotlib.svg')) + icon = QtGui.QIcon(image) + app.setWindowIcon(icon) + app.setQuitOnLastWindowClosed(True) + cbook._setup_new_guiapp() + if qt_version == 5: + app.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) + + return app + + +class TimerQT(TimerBase): + """Subclass of `.TimerBase` using QTimer events.""" + + def __init__(self, *args, **kwargs): + # Create a new timer and connect the timeout() signal to the + # _on_timer method. + self._timer = QtCore.QTimer() + self._timer.timeout.connect(self._on_timer) + super().__init__(*args, **kwargs) + + def __del__(self): + # The check for deletedness is needed to avoid an error at animation + # shutdown with PySide2. + if not _isdeleted(self._timer): + self._timer_stop() + + def _timer_set_single_shot(self): + self._timer.setSingleShot(self._single) + + def _timer_set_interval(self): + self._timer.setInterval(self._interval) + + def _timer_start(self): + self._timer.start() + + def _timer_stop(self): + self._timer.stop() + + +class FigureCanvasQT(FigureCanvasBase, QtWidgets.QWidget): + required_interactive_framework = "qt" + _timer_cls = TimerQT + manager_class = _api.classproperty(lambda cls: FigureManagerQT) + + buttond = { + getattr(QtCore.Qt.MouseButton, k): v for k, v in [ + ("LeftButton", MouseButton.LEFT), + ("RightButton", MouseButton.RIGHT), + ("MiddleButton", MouseButton.MIDDLE), + ("XButton1", MouseButton.BACK), + ("XButton2", MouseButton.FORWARD), + ] + } + + def __init__(self, figure=None): + _create_qApp() + super().__init__(figure=figure) + + self._draw_pending = False + self._is_drawing = False + self._draw_rect_callback = lambda painter: None + self._in_resize_event = False + + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_OpaquePaintEvent) + self.setMouseTracking(True) + self.resize(*self.get_width_height()) + + palette = QtGui.QPalette(QtGui.QColor("white")) + self.setPalette(palette) + + def _update_pixel_ratio(self): + if self._set_device_pixel_ratio( + self.devicePixelRatioF() or 1): # rarely, devicePixelRatioF=0 + # The easiest way to resize the canvas is to emit a resizeEvent + # since we implement all the logic for resizing the canvas for + # that event. + event = QtGui.QResizeEvent(self.size(), self.size()) + self.resizeEvent(event) + + def _update_screen(self, screen): + # Handler for changes to a window's attached screen. + self._update_pixel_ratio() + if screen is not None: + screen.physicalDotsPerInchChanged.connect(self._update_pixel_ratio) + screen.logicalDotsPerInchChanged.connect(self._update_pixel_ratio) + + def showEvent(self, event): + # Set up correct pixel ratio, and connect to any signal changes for it, + # once the window is shown (and thus has these attributes). + window = self.window().windowHandle() + window.screenChanged.connect(self._update_screen) + self._update_screen(window.screen()) + + def set_cursor(self, cursor): + # docstring inherited + self.setCursor(_api.check_getitem(cursord, cursor=cursor)) + + def mouseEventCoords(self, pos=None): + """ + Calculate mouse coordinates in physical pixels. + + Qt uses logical pixels, but the figure is scaled to physical + pixels for rendering. Transform to physical pixels so that + all of the down-stream transforms work as expected. + + Also, the origin is different and needs to be corrected. + """ + if pos is None: + pos = self.mapFromGlobal(QtGui.QCursor.pos()) + elif hasattr(pos, "position"): # qt6 QtGui.QEvent + pos = pos.position() + elif hasattr(pos, "pos"): # qt5 QtCore.QEvent + pos = pos.pos() + # (otherwise, it's already a QPoint) + x = pos.x() + # flip y so y=0 is bottom of canvas + y = self.figure.bbox.height / self.device_pixel_ratio - pos.y() + return x * self.device_pixel_ratio, y * self.device_pixel_ratio + + def enterEvent(self, event): + # Force querying of the modifiers, as the cached modifier state can + # have been invalidated while the window was out of focus. + mods = QtWidgets.QApplication.instance().queryKeyboardModifiers() + LocationEvent("figure_enter_event", self, + *self.mouseEventCoords(event), + modifiers=self._mpl_modifiers(mods), + guiEvent=event)._process() + + def leaveEvent(self, event): + QtWidgets.QApplication.restoreOverrideCursor() + LocationEvent("figure_leave_event", self, + *self.mouseEventCoords(), + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def mousePressEvent(self, event): + button = self.buttond.get(event.button()) + if button is not None: + MouseEvent("button_press_event", self, + *self.mouseEventCoords(event), button, + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def mouseDoubleClickEvent(self, event): + button = self.buttond.get(event.button()) + if button is not None: + MouseEvent("button_press_event", self, + *self.mouseEventCoords(event), button, dblclick=True, + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def mouseMoveEvent(self, event): + MouseEvent("motion_notify_event", self, + *self.mouseEventCoords(event), + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def mouseReleaseEvent(self, event): + button = self.buttond.get(event.button()) + if button is not None: + MouseEvent("button_release_event", self, + *self.mouseEventCoords(event), button, + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def wheelEvent(self, event): + # from QWheelEvent::pixelDelta doc: pixelDelta is sometimes not + # provided (`isNull()`) and is unreliable on X11 ("xcb"). + if (event.pixelDelta().isNull() + or QtWidgets.QApplication.instance().platformName() == "xcb"): + steps = event.angleDelta().y() / 120 + else: + steps = event.pixelDelta().y() + if steps: + MouseEvent("scroll_event", self, + *self.mouseEventCoords(event), step=steps, + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def keyPressEvent(self, event): + key = self._get_key(event) + if key is not None: + KeyEvent("key_press_event", self, + key, *self.mouseEventCoords(), + guiEvent=event)._process() + + def keyReleaseEvent(self, event): + key = self._get_key(event) + if key is not None: + KeyEvent("key_release_event", self, + key, *self.mouseEventCoords(), + guiEvent=event)._process() + + def resizeEvent(self, event): + if self._in_resize_event: # Prevent PyQt6 recursion + return + self._in_resize_event = True + try: + w = event.size().width() * self.device_pixel_ratio + h = event.size().height() * self.device_pixel_ratio + dpival = self.figure.dpi + winch = w / dpival + hinch = h / dpival + self.figure.set_size_inches(winch, hinch, forward=False) + # pass back into Qt to let it finish + QtWidgets.QWidget.resizeEvent(self, event) + # emit our resize events + ResizeEvent("resize_event", self)._process() + self.draw_idle() + finally: + self._in_resize_event = False + + def sizeHint(self): + w, h = self.get_width_height() + return QtCore.QSize(w, h) + + def minumumSizeHint(self): + return QtCore.QSize(10, 10) + + @staticmethod + def _mpl_modifiers(modifiers=None, *, exclude=None): + if modifiers is None: + modifiers = QtWidgets.QApplication.instance().keyboardModifiers() + modifiers = _to_int(modifiers) + # get names of the pressed modifier keys + # 'control' is named 'control' when a standalone key, but 'ctrl' when a + # modifier + # bit twiddling to pick out modifier keys from modifiers bitmask, + # if exclude is a MODIFIER, it should not be duplicated in mods + return [SPECIAL_KEYS[key].replace('control', 'ctrl') + for mask, key in _MODIFIER_KEYS + if exclude != key and modifiers & mask] + + def _get_key(self, event): + event_key = event.key() + mods = self._mpl_modifiers(exclude=event_key) + try: + # for certain keys (enter, left, backspace, etc) use a word for the + # key, rather than Unicode + key = SPECIAL_KEYS[event_key] + except KeyError: + # Unicode defines code points up to 0x10ffff (sys.maxunicode) + # QT will use Key_Codes larger than that for keyboard keys that are + # not Unicode characters (like multimedia keys) + # skip these + # if you really want them, you should add them to SPECIAL_KEYS + if event_key > sys.maxunicode: + return None + + key = chr(event_key) + # qt delivers capitalized letters. fix capitalization + # note that capslock is ignored + if 'shift' in mods: + mods.remove('shift') + else: + key = key.lower() + + return '+'.join(mods + [key]) + + def flush_events(self): + # docstring inherited + QtWidgets.QApplication.instance().processEvents() + + def start_event_loop(self, timeout=0): + # docstring inherited + if hasattr(self, "_event_loop") and self._event_loop.isRunning(): + raise RuntimeError("Event loop already running") + self._event_loop = event_loop = QtCore.QEventLoop() + if timeout > 0: + _ = QtCore.QTimer.singleShot(int(timeout * 1000), event_loop.quit) + + with _maybe_allow_interrupt(event_loop): + qt_compat._exec(event_loop) + + def stop_event_loop(self, event=None): + # docstring inherited + if hasattr(self, "_event_loop"): + self._event_loop.quit() + + def draw(self): + """Render the figure, and queue a request for a Qt draw.""" + # The renderer draw is done here; delaying causes problems with code + # that uses the result of the draw() to update plot elements. + if self._is_drawing: + return + with cbook._setattr_cm(self, _is_drawing=True): + super().draw() + self.update() + + def draw_idle(self): + """Queue redraw of the Agg buffer and request Qt paintEvent.""" + # The Agg draw needs to be handled by the same thread Matplotlib + # modifies the scene graph from. Post Agg draw request to the + # current event loop in order to ensure thread affinity and to + # accumulate multiple draw requests from event handling. + # TODO: queued signal connection might be safer than singleShot + if not (getattr(self, '_draw_pending', False) or + getattr(self, '_is_drawing', False)): + self._draw_pending = True + QtCore.QTimer.singleShot(0, self._draw_idle) + + def blit(self, bbox=None): + # docstring inherited + if bbox is None and self.figure: + bbox = self.figure.bbox # Blit the entire canvas if bbox is None. + # repaint uses logical pixels, not physical pixels like the renderer. + l, b, w, h = [int(pt / self.device_pixel_ratio) for pt in bbox.bounds] + t = b + h + self.repaint(l, self.rect().height() - t, w, h) + + def _draw_idle(self): + with self._idle_draw_cntx(): + if not self._draw_pending: + return + self._draw_pending = False + if self.height() < 0 or self.width() < 0: + return + try: + self.draw() + except Exception: + # Uncaught exceptions are fatal for PyQt5, so catch them. + traceback.print_exc() + + def drawRectangle(self, rect): + # Draw the zoom rectangle to the QPainter. _draw_rect_callback needs + # to be called at the end of paintEvent. + if rect is not None: + x0, y0, w, h = [int(pt / self.device_pixel_ratio) for pt in rect] + x1 = x0 + w + y1 = y0 + h + def _draw_rect_callback(painter): + pen = QtGui.QPen( + QtGui.QColor("black"), + 1 / self.device_pixel_ratio + ) + + pen.setDashPattern([3, 3]) + for color, offset in [ + (QtGui.QColor("black"), 0), + (QtGui.QColor("white"), 3), + ]: + pen.setDashOffset(offset) + pen.setColor(color) + painter.setPen(pen) + # Draw the lines from x0, y0 towards x1, y1 so that the + # dashes don't "jump" when moving the zoom box. + painter.drawLine(x0, y0, x0, y1) + painter.drawLine(x0, y0, x1, y0) + painter.drawLine(x0, y1, x1, y1) + painter.drawLine(x1, y0, x1, y1) + else: + def _draw_rect_callback(painter): + return + self._draw_rect_callback = _draw_rect_callback + self.update() + + +class MainWindow(QtWidgets.QMainWindow): + closing = QtCore.Signal() + + def closeEvent(self, event): + self.closing.emit() + super().closeEvent(event) + + +class FigureManagerQT(FigureManagerBase): + """ + Attributes + ---------- + canvas : `FigureCanvas` + The FigureCanvas instance + num : int or str + The Figure number + toolbar : qt.QToolBar + The qt.QToolBar + window : qt.QMainWindow + The qt.QMainWindow + """ + + def __init__(self, canvas, num): + self.window = MainWindow() + super().__init__(canvas, num) + self.window.closing.connect(self._widgetclosed) + + if sys.platform != "darwin": + image = str(cbook._get_data_path('images/matplotlib.svg')) + icon = QtGui.QIcon(image) + self.window.setWindowIcon(icon) + + self.window._destroying = False + + if self.toolbar: + self.window.addToolBar(self.toolbar) + tbs_height = self.toolbar.sizeHint().height() + else: + tbs_height = 0 + + # resize the main window so it will display the canvas with the + # requested size: + cs = canvas.sizeHint() + cs_height = cs.height() + height = cs_height + tbs_height + self.window.resize(cs.width(), height) + + self.window.setCentralWidget(self.canvas) + + if mpl.is_interactive(): + self.window.show() + self.canvas.draw_idle() + + # Give the keyboard focus to the figure instead of the manager: + # StrongFocus accepts both tab and click to focus and will enable the + # canvas to process event without clicking. + # https://doc.qt.io/qt-5/qt.html#FocusPolicy-enum + self.canvas.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) + self.canvas.setFocus() + + self.window.raise_() + + def full_screen_toggle(self): + if self.window.isFullScreen(): + self.window.showNormal() + else: + self.window.showFullScreen() + + def _widgetclosed(self): + CloseEvent("close_event", self.canvas)._process() + if self.window._destroying: + return + self.window._destroying = True + try: + Gcf.destroy(self) + except AttributeError: + pass + # It seems that when the python session is killed, + # Gcf can get destroyed before the Gcf.destroy + # line is run, leading to a useless AttributeError. + + def resize(self, width, height): + # The Qt methods return sizes in 'virtual' pixels so we do need to + # rescale from physical to logical pixels. + width = int(width / self.canvas.device_pixel_ratio) + height = int(height / self.canvas.device_pixel_ratio) + extra_width = self.window.width() - self.canvas.width() + extra_height = self.window.height() - self.canvas.height() + self.canvas.resize(width, height) + self.window.resize(width + extra_width, height + extra_height) + + @classmethod + def start_main_loop(cls): + qapp = QtWidgets.QApplication.instance() + if qapp: + with _maybe_allow_interrupt(qapp): + qt_compat._exec(qapp) + + def show(self): + self.window.show() + if mpl.rcParams['figure.raise_window']: + self.window.activateWindow() + self.window.raise_() + + def destroy(self, *args): + # check for qApp first, as PySide deletes it in its atexit handler + if QtWidgets.QApplication.instance() is None: + return + if self.window._destroying: + return + self.window._destroying = True + if self.toolbar: + self.toolbar.destroy() + self.window.close() + + def get_window_title(self): + return self.window.windowTitle() + + def set_window_title(self, title): + self.window.setWindowTitle(title) + + +class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar): + _message = QtCore.Signal(str) # Remove once deprecation below elapses. + message = _api.deprecate_privatize_attribute("3.8") + + toolitems = [*NavigationToolbar2.toolitems] + toolitems.insert( + # Add 'customize' action after 'subplots' + [name for name, *_ in toolitems].index("Subplots") + 1, + ("Customize", "Edit axis, curve and image parameters", + "qt4_editor_options", "edit_parameters")) + + def __init__(self, canvas, parent=None, coordinates=True): + """coordinates: should we show the coordinates on the right?""" + QtWidgets.QToolBar.__init__(self, parent) + self.setAllowedAreas(QtCore.Qt.ToolBarArea( + _to_int(QtCore.Qt.ToolBarArea.TopToolBarArea) | + _to_int(QtCore.Qt.ToolBarArea.BottomToolBarArea))) + self.coordinates = coordinates + self._actions = {} # mapping of toolitem method names to QActions. + self._subplot_dialog = None + + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + self.addSeparator() + else: + a = self.addAction(self._icon(image_file + '.png'), + text, getattr(self, callback)) + self._actions[callback] = a + if callback in ['zoom', 'pan']: + a.setCheckable(True) + if tooltip_text is not None: + a.setToolTip(tooltip_text) + + # Add the (x, y) location widget at the right side of the toolbar + # The stretch factor is 1 which means any resizing of the toolbar + # will resize this label instead of the buttons. + if self.coordinates: + self.locLabel = QtWidgets.QLabel("", self) + self.locLabel.setAlignment(QtCore.Qt.AlignmentFlag( + _to_int(QtCore.Qt.AlignmentFlag.AlignRight) | + _to_int(QtCore.Qt.AlignmentFlag.AlignVCenter))) + + self.locLabel.setSizePolicy(QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Ignored, + )) + labelAction = self.addWidget(self.locLabel) + labelAction.setVisible(True) + + NavigationToolbar2.__init__(self, canvas) + + def _icon(self, name): + """ + Construct a `.QIcon` from an image file *name*, including the extension + and relative to Matplotlib's "images" data directory. + """ + # use a high-resolution icon with suffix '_large' if available + # note: user-provided icons may not have '_large' versions + path_regular = cbook._get_data_path('images', name) + path_large = path_regular.with_name( + path_regular.name.replace('.png', '_large.png')) + filename = str(path_large if path_large.exists() else path_regular) + + pm = QtGui.QPixmap(filename) + pm.setDevicePixelRatio( + self.devicePixelRatioF() or 1) # rarely, devicePixelRatioF=0 + if self.palette().color(self.backgroundRole()).value() < 128: + icon_color = self.palette().color(self.foregroundRole()) + mask = pm.createMaskFromColor( + QtGui.QColor('black'), + QtCore.Qt.MaskMode.MaskOutColor) + pm.fill(icon_color) + pm.setMask(mask) + return QtGui.QIcon(pm) + + def edit_parameters(self): + axes = self.canvas.figure.get_axes() + if not axes: + QtWidgets.QMessageBox.warning( + self.canvas.parent(), "Error", "There are no axes to edit.") + return + elif len(axes) == 1: + ax, = axes + else: + titles = [ + ax.get_label() or + ax.get_title() or + ax.get_title("left") or + ax.get_title("right") or + " - ".join(filter(None, [ax.get_xlabel(), ax.get_ylabel()])) or + f"" + for ax in axes] + duplicate_titles = [ + title for title in titles if titles.count(title) > 1] + for i, ax in enumerate(axes): + if titles[i] in duplicate_titles: + titles[i] += f" (id: {id(ax):#x})" # Deduplicate titles. + item, ok = QtWidgets.QInputDialog.getItem( + self.canvas.parent(), + 'Customize', 'Select axes:', titles, 0, False) + if not ok: + return + ax = axes[titles.index(item)] + figureoptions.figure_edit(ax, self) + + def _update_buttons_checked(self): + # sync button checkstates to match active mode + if 'pan' in self._actions: + self._actions['pan'].setChecked(self.mode.name == 'PAN') + if 'zoom' in self._actions: + self._actions['zoom'].setChecked(self.mode.name == 'ZOOM') + + def pan(self, *args): + super().pan(*args) + self._update_buttons_checked() + + def zoom(self, *args): + super().zoom(*args) + self._update_buttons_checked() + + def set_message(self, s): + self._message.emit(s) + if self.coordinates: + self.locLabel.setText(s) + + def draw_rubberband(self, event, x0, y0, x1, y1): + height = self.canvas.figure.bbox.height + y1 = height - y1 + y0 = height - y0 + rect = [int(val) for val in (x0, y0, x1 - x0, y1 - y0)] + self.canvas.drawRectangle(rect) + + def remove_rubberband(self): + self.canvas.drawRectangle(None) + + def configure_subplots(self): + if self._subplot_dialog is None: + self._subplot_dialog = SubplotToolQt( + self.canvas.figure, self.canvas.parent()) + self.canvas.mpl_connect( + "close_event", lambda e: self._subplot_dialog.reject()) + self._subplot_dialog.update_from_current_subplotpars() + self._subplot_dialog.show() + return self._subplot_dialog + + def save_figure(self, *args): + filetypes = self.canvas.get_supported_filetypes_grouped() + sorted_filetypes = sorted(filetypes.items()) + default_filetype = self.canvas.get_default_filetype() + + startpath = os.path.expanduser(mpl.rcParams['savefig.directory']) + start = os.path.join(startpath, self.canvas.get_default_filename()) + filters = [] + selectedFilter = None + for name, exts in sorted_filetypes: + exts_list = " ".join(['*.%s' % ext for ext in exts]) + filter = f'{name} ({exts_list})' + if default_filetype in exts: + selectedFilter = filter + filters.append(filter) + filters = ';;'.join(filters) + + fname, filter = QtWidgets.QFileDialog.getSaveFileName( + self.canvas.parent(), "Choose a filename to save to", start, + filters, selectedFilter) + if fname: + # Save dir for next time, unless empty str (i.e., use cwd). + if startpath != "": + mpl.rcParams['savefig.directory'] = os.path.dirname(fname) + try: + self.canvas.figure.savefig(fname) + except Exception as e: + QtWidgets.QMessageBox.critical( + self, "Error saving file", str(e), + QtWidgets.QMessageBox.StandardButton.Ok, + QtWidgets.QMessageBox.StandardButton.NoButton) + + def set_history_buttons(self): + can_backward = self._nav_stack._pos > 0 + can_forward = self._nav_stack._pos < len(self._nav_stack) - 1 + if 'back' in self._actions: + self._actions['back'].setEnabled(can_backward) + if 'forward' in self._actions: + self._actions['forward'].setEnabled(can_forward) + + +class SubplotToolQt(QtWidgets.QDialog): + def __init__(self, targetfig, parent): + super().__init__() + self.setWindowIcon(QtGui.QIcon( + str(cbook._get_data_path("images/matplotlib.png")))) + self.setObjectName("SubplotTool") + self._spinboxes = {} + main_layout = QtWidgets.QHBoxLayout() + self.setLayout(main_layout) + for group, spinboxes, buttons in [ + ("Borders", + ["top", "bottom", "left", "right"], + [("Export values", self._export_values)]), + ("Spacings", + ["hspace", "wspace"], + [("Tight layout", self._tight_layout), + ("Reset", self._reset), + ("Close", self.close)])]: + layout = QtWidgets.QVBoxLayout() + main_layout.addLayout(layout) + box = QtWidgets.QGroupBox(group) + layout.addWidget(box) + inner = QtWidgets.QFormLayout(box) + for name in spinboxes: + self._spinboxes[name] = spinbox = QtWidgets.QDoubleSpinBox() + spinbox.setRange(0, 1) + spinbox.setDecimals(3) + spinbox.setSingleStep(0.005) + spinbox.setKeyboardTracking(False) + spinbox.valueChanged.connect(self._on_value_changed) + inner.addRow(name, spinbox) + layout.addStretch(1) + for name, method in buttons: + button = QtWidgets.QPushButton(name) + # Don't trigger on , which is used to input values. + button.setAutoDefault(False) + button.clicked.connect(method) + layout.addWidget(button) + if name == "Close": + button.setFocus() + self._figure = targetfig + self._defaults = {} + self._export_values_dialog = None + self.update_from_current_subplotpars() + + def update_from_current_subplotpars(self): + self._defaults = {spinbox: getattr(self._figure.subplotpars, name) + for name, spinbox in self._spinboxes.items()} + self._reset() # Set spinbox current values without triggering signals. + + def _export_values(self): + # Explicitly round to 3 decimals (which is also the spinbox precision) + # to avoid numbers of the form 0.100...001. + self._export_values_dialog = QtWidgets.QDialog() + layout = QtWidgets.QVBoxLayout() + self._export_values_dialog.setLayout(layout) + text = QtWidgets.QPlainTextEdit() + text.setReadOnly(True) + layout.addWidget(text) + text.setPlainText( + ",\n".join(f"{attr}={spinbox.value():.3}" + for attr, spinbox in self._spinboxes.items())) + # Adjust the height of the text widget to fit the whole text, plus + # some padding. + size = text.maximumSize() + size.setHeight( + QtGui.QFontMetrics(text.document().defaultFont()) + .size(0, text.toPlainText()).height() + 20) + text.setMaximumSize(size) + self._export_values_dialog.show() + + def _on_value_changed(self): + spinboxes = self._spinboxes + # Set all mins and maxes, so that this can also be used in _reset(). + for lower, higher in [("bottom", "top"), ("left", "right")]: + spinboxes[higher].setMinimum(spinboxes[lower].value() + .001) + spinboxes[lower].setMaximum(spinboxes[higher].value() - .001) + self._figure.subplots_adjust( + **{attr: spinbox.value() for attr, spinbox in spinboxes.items()}) + self._figure.canvas.draw_idle() + + def _tight_layout(self): + self._figure.tight_layout() + for attr, spinbox in self._spinboxes.items(): + spinbox.blockSignals(True) + spinbox.setValue(getattr(self._figure.subplotpars, attr)) + spinbox.blockSignals(False) + self._figure.canvas.draw_idle() + + def _reset(self): + for spinbox, value in self._defaults.items(): + spinbox.setRange(0, 1) + spinbox.blockSignals(True) + spinbox.setValue(value) + spinbox.blockSignals(False) + self._on_value_changed() + + +class ToolbarQt(ToolContainerBase, QtWidgets.QToolBar): + def __init__(self, toolmanager, parent=None): + ToolContainerBase.__init__(self, toolmanager) + QtWidgets.QToolBar.__init__(self, parent) + self.setAllowedAreas(QtCore.Qt.ToolBarArea( + _to_int(QtCore.Qt.ToolBarArea.TopToolBarArea) | + _to_int(QtCore.Qt.ToolBarArea.BottomToolBarArea))) + message_label = QtWidgets.QLabel("") + message_label.setAlignment(QtCore.Qt.AlignmentFlag( + _to_int(QtCore.Qt.AlignmentFlag.AlignRight) | + _to_int(QtCore.Qt.AlignmentFlag.AlignVCenter))) + message_label.setSizePolicy(QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Ignored, + )) + self._message_action = self.addWidget(message_label) + self._toolitems = {} + self._groups = {} + + def add_toolitem( + self, name, group, position, image_file, description, toggle): + + button = QtWidgets.QToolButton(self) + if image_file: + button.setIcon(NavigationToolbar2QT._icon(self, image_file)) + button.setText(name) + if description: + button.setToolTip(description) + + def handler(): + self.trigger_tool(name) + if toggle: + button.setCheckable(True) + button.toggled.connect(handler) + else: + button.clicked.connect(handler) + + self._toolitems.setdefault(name, []) + self._add_to_group(group, name, button, position) + self._toolitems[name].append((button, handler)) + + def _add_to_group(self, group, name, button, position): + gr = self._groups.get(group, []) + if not gr: + sep = self.insertSeparator(self._message_action) + gr.append(sep) + before = gr[position] + widget = self.insertWidget(before, button) + gr.insert(position, widget) + self._groups[group] = gr + + def toggle_toolitem(self, name, toggled): + if name not in self._toolitems: + return + for button, handler in self._toolitems[name]: + button.toggled.disconnect(handler) + button.setChecked(toggled) + button.toggled.connect(handler) + + def remove_toolitem(self, name): + for button, handler in self._toolitems[name]: + button.setParent(None) + del self._toolitems[name] + + def set_message(self, s): + self.widgetForAction(self._message_action).setText(s) + + +@backend_tools._register_tool_class(FigureCanvasQT) +class ConfigureSubplotsQt(backend_tools.ConfigureSubplotsBase): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._subplot_dialog = None + + def trigger(self, *args): + NavigationToolbar2QT.configure_subplots(self) + + +@backend_tools._register_tool_class(FigureCanvasQT) +class SaveFigureQt(backend_tools.SaveFigureBase): + def trigger(self, *args): + NavigationToolbar2QT.save_figure( + self._make_classic_style_pseudo_toolbar()) + + +@backend_tools._register_tool_class(FigureCanvasQT) +class RubberbandQt(backend_tools.RubberbandBase): + def draw_rubberband(self, x0, y0, x1, y1): + NavigationToolbar2QT.draw_rubberband( + self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1) + + def remove_rubberband(self): + NavigationToolbar2QT.remove_rubberband( + self._make_classic_style_pseudo_toolbar()) + + +@backend_tools._register_tool_class(FigureCanvasQT) +class HelpQt(backend_tools.ToolHelpBase): + def trigger(self, *args): + QtWidgets.QMessageBox.information(None, "Help", self._get_help_html()) + + +@backend_tools._register_tool_class(FigureCanvasQT) +class ToolCopyToClipboardQT(backend_tools.ToolCopyToClipboardBase): + def trigger(self, *args, **kwargs): + pixmap = self.canvas.grab() + QtWidgets.QApplication.instance().clipboard().setPixmap(pixmap) + + +FigureManagerQT._toolbar2_class = NavigationToolbar2QT +FigureManagerQT._toolmanager_toolbar_class = ToolbarQt + + +@_Backend.export +class _BackendQT(_Backend): + backend_version = __version__ + FigureCanvas = FigureCanvasQT + FigureManager = FigureManagerQT + mainloop = FigureManagerQT.start_main_loop diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5.py new file mode 100644 index 00000000..d94062b7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5.py @@ -0,0 +1,28 @@ +from .. import backends + +backends._QT_FORCE_QT5_BINDING = True + + +from .backend_qt import ( # noqa + SPECIAL_KEYS, + # Public API + cursord, _create_qApp, _BackendQT, TimerQT, MainWindow, FigureCanvasQT, + FigureManagerQT, ToolbarQt, NavigationToolbar2QT, SubplotToolQt, + SaveFigureQt, ConfigureSubplotsQt, RubberbandQt, + HelpQt, ToolCopyToClipboardQT, + # internal re-exports + FigureCanvasBase, FigureManagerBase, MouseButton, NavigationToolbar2, + TimerBase, ToolContainerBase, figureoptions, Gcf +) +from . import backend_qt as _backend_qt # noqa + + +@_BackendQT.export +class _BackendQT5(_BackendQT): + pass + + +def __getattr__(name): + if name == 'qApp': + return _backend_qt.qApp + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5agg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5agg.py new file mode 100644 index 00000000..8a92fd51 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5agg.py @@ -0,0 +1,14 @@ +""" +Render to qt from agg +""" +from .. import backends + +backends._QT_FORCE_QT5_BINDING = True +from .backend_qtagg import ( # noqa: F401, E402 # pylint: disable=W0611 + _BackendQTAgg, FigureCanvasQTAgg, FigureManagerQT, NavigationToolbar2QT, + FigureCanvasAgg, FigureCanvasQT) + + +@_BackendQTAgg.export +class _BackendQT5Agg(_BackendQTAgg): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5cairo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5cairo.py new file mode 100644 index 00000000..a4263f59 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qt5cairo.py @@ -0,0 +1,11 @@ +from .. import backends + +backends._QT_FORCE_QT5_BINDING = True +from .backend_qtcairo import ( # noqa: F401, E402 # pylint: disable=W0611 + _BackendQTCairo, FigureCanvasQTCairo, FigureCanvasCairo, FigureCanvasQT +) + + +@_BackendQTCairo.export +class _BackendQT5Cairo(_BackendQTCairo): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtagg.py new file mode 100644 index 00000000..256e50a3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtagg.py @@ -0,0 +1,86 @@ +""" +Render to qt from agg. +""" + +import ctypes + +from matplotlib.transforms import Bbox + +from .qt_compat import QT_API, QtCore, QtGui +from .backend_agg import FigureCanvasAgg +from .backend_qt import _BackendQT, FigureCanvasQT +from .backend_qt import ( # noqa: F401 # pylint: disable=W0611 + FigureManagerQT, NavigationToolbar2QT) + + +class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT): + + def paintEvent(self, event): + """ + Copy the image from the Agg canvas to the qt.drawable. + + In Qt, all drawing should be done inside of here when a widget is + shown onscreen. + """ + self._draw_idle() # Only does something if a draw is pending. + + # If the canvas does not have a renderer, then give up and wait for + # FigureCanvasAgg.draw(self) to be called. + if not hasattr(self, 'renderer'): + return + + painter = QtGui.QPainter(self) + try: + # See documentation of QRect: bottom() and right() are off + # by 1, so use left() + width() and top() + height(). + rect = event.rect() + # scale rect dimensions using the screen dpi ratio to get + # correct values for the Figure coordinates (rather than + # QT5's coords) + width = rect.width() * self.device_pixel_ratio + height = rect.height() * self.device_pixel_ratio + left, top = self.mouseEventCoords(rect.topLeft()) + # shift the "top" by the height of the image to get the + # correct corner for our coordinate system + bottom = top - height + # same with the right side of the image + right = left + width + # create a buffer using the image bounding box + bbox = Bbox([[left, bottom], [right, top]]) + buf = memoryview(self.copy_from_bbox(bbox)) + + if QT_API == "PyQt6": + from PyQt6 import sip + ptr = int(sip.voidptr(buf)) + else: + ptr = buf + + painter.eraseRect(rect) # clear the widget canvas + qimage = QtGui.QImage(ptr, buf.shape[1], buf.shape[0], + QtGui.QImage.Format.Format_RGBA8888) + qimage.setDevicePixelRatio(self.device_pixel_ratio) + # set origin using original QT coordinates + origin = QtCore.QPoint(rect.left(), rect.top()) + painter.drawImage(origin, qimage) + # Adjust the buf reference count to work around a memory + # leak bug in QImage under PySide. + if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12): + ctypes.c_long.from_address(id(buf)).value = 1 + + self._draw_rect_callback(painter) + finally: + painter.end() + + def print_figure(self, *args, **kwargs): + super().print_figure(*args, **kwargs) + # In some cases, Qt will itself trigger a paint event after closing the file + # save dialog. When that happens, we need to be sure that the internal canvas is + # re-drawn. However, if the user is using an automatically-chosen Qt backend but + # saving with a different backend (such as pgf), we do not want to trigger a + # full draw in Qt, so just set the flag for next time. + self._draw_pending = True + + +@_BackendQT.export +class _BackendQTAgg(_BackendQT): + FigureCanvas = FigureCanvasQTAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtcairo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtcairo.py new file mode 100644 index 00000000..72eb2dc7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_qtcairo.py @@ -0,0 +1,46 @@ +import ctypes + +from .backend_cairo import cairo, FigureCanvasCairo +from .backend_qt import _BackendQT, FigureCanvasQT +from .qt_compat import QT_API, QtCore, QtGui + + +class FigureCanvasQTCairo(FigureCanvasCairo, FigureCanvasQT): + def draw(self): + if hasattr(self._renderer.gc, "ctx"): + self._renderer.dpi = self.figure.dpi + self.figure.draw(self._renderer) + super().draw() + + def paintEvent(self, event): + width = int(self.device_pixel_ratio * self.width()) + height = int(self.device_pixel_ratio * self.height()) + if (width, height) != self._renderer.get_canvas_width_height(): + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + self._renderer.set_context(cairo.Context(surface)) + self._renderer.dpi = self.figure.dpi + self.figure.draw(self._renderer) + buf = self._renderer.gc.ctx.get_target().get_data() + if QT_API == "PyQt6": + from PyQt6 import sip + ptr = int(sip.voidptr(buf)) + else: + ptr = buf + qimage = QtGui.QImage( + ptr, width, height, + QtGui.QImage.Format.Format_ARGB32_Premultiplied) + # Adjust the buf reference count to work around a memory leak bug in + # QImage under PySide. + if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12): + ctypes.c_long.from_address(id(buf)).value = 1 + qimage.setDevicePixelRatio(self.device_pixel_ratio) + painter = QtGui.QPainter(self) + painter.eraseRect(event.rect()) + painter.drawImage(0, 0, qimage) + self._draw_rect_callback(painter) + painter.end() + + +@_BackendQT.export +class _BackendQTCairo(_BackendQT): + FigureCanvas = FigureCanvasQTCairo diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_svg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_svg.py new file mode 100644 index 00000000..f62152ed --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_svg.py @@ -0,0 +1,1368 @@ +import base64 +import codecs +import datetime +import gzip +import hashlib +from io import BytesIO +import itertools +import logging +import os +import re +import uuid + +import numpy as np +from PIL import Image + +import matplotlib as mpl +from matplotlib import cbook, font_manager as fm +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, RendererBase) +from matplotlib.backends.backend_mixed import MixedModeRenderer +from matplotlib.colors import rgb2hex +from matplotlib.dates import UTC +from matplotlib.path import Path +from matplotlib import _path +from matplotlib.transforms import Affine2D, Affine2DBase + + +_log = logging.getLogger(__name__) + + +# ---------------------------------------------------------------------- +# SimpleXMLWriter class +# +# Based on an original by Fredrik Lundh, but modified here to: +# 1. Support modern Python idioms +# 2. Remove encoding support (it's handled by the file writer instead) +# 3. Support proper indentation +# 4. Minify things a little bit + +# -------------------------------------------------------------------- +# The SimpleXMLWriter module is +# +# Copyright (c) 2001-2004 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + + +def _escape_cdata(s): + s = s.replace("&", "&") + s = s.replace("<", "<") + s = s.replace(">", ">") + return s + + +_escape_xml_comment = re.compile(r'-(?=-)') + + +def _escape_comment(s): + s = _escape_cdata(s) + return _escape_xml_comment.sub('- ', s) + + +def _escape_attrib(s): + s = s.replace("&", "&") + s = s.replace("'", "'") + s = s.replace('"', """) + s = s.replace("<", "<") + s = s.replace(">", ">") + return s + + +def _quote_escape_attrib(s): + return ('"' + _escape_cdata(s) + '"' if '"' not in s else + "'" + _escape_cdata(s) + "'" if "'" not in s else + '"' + _escape_attrib(s) + '"') + + +def _short_float_fmt(x): + """ + Create a short string representation of a float, which is %f + formatting with trailing zeros and the decimal point removed. + """ + return f'{x:f}'.rstrip('0').rstrip('.') + + +class XMLWriter: + """ + Parameters + ---------- + file : writable text file-like object + """ + + def __init__(self, file): + self.__write = file.write + if hasattr(file, "flush"): + self.flush = file.flush + self.__open = 0 # true if start tag is open + self.__tags = [] + self.__data = [] + self.__indentation = " " * 64 + + def __flush(self, indent=True): + # flush internal buffers + if self.__open: + if indent: + self.__write(">\n") + else: + self.__write(">") + self.__open = 0 + if self.__data: + data = ''.join(self.__data) + self.__write(_escape_cdata(data)) + self.__data = [] + + def start(self, tag, attrib={}, **extra): + """ + Open a new element. Attributes can be given as keyword + arguments, or as a string/string dictionary. The method returns + an opaque identifier that can be passed to the :meth:`close` + method, to close all open elements up to and including this one. + + Parameters + ---------- + tag + Element tag. + attrib + Attribute dictionary. Alternatively, attributes can be given as + keyword arguments. + + Returns + ------- + An element identifier. + """ + self.__flush() + tag = _escape_cdata(tag) + self.__data = [] + self.__tags.append(tag) + self.__write(self.__indentation[:len(self.__tags) - 1]) + self.__write(f"<{tag}") + for k, v in {**attrib, **extra}.items(): + if v: + k = _escape_cdata(k) + v = _quote_escape_attrib(v) + self.__write(f' {k}={v}') + self.__open = 1 + return len(self.__tags) - 1 + + def comment(self, comment): + """ + Add a comment to the output stream. + + Parameters + ---------- + comment : str + Comment text. + """ + self.__flush() + self.__write(self.__indentation[:len(self.__tags)]) + self.__write(f"\n") + + def data(self, text): + """ + Add character data to the output stream. + + Parameters + ---------- + text : str + Character data. + """ + self.__data.append(text) + + def end(self, tag=None, indent=True): + """ + Close the current element (opened by the most recent call to + :meth:`start`). + + Parameters + ---------- + tag + Element tag. If given, the tag must match the start tag. If + omitted, the current element is closed. + indent : bool, default: True + """ + if tag: + assert self.__tags, f"unbalanced end({tag})" + assert _escape_cdata(tag) == self.__tags[-1], \ + f"expected end({self.__tags[-1]}), got {tag}" + else: + assert self.__tags, "unbalanced end()" + tag = self.__tags.pop() + if self.__data: + self.__flush(indent) + elif self.__open: + self.__open = 0 + self.__write("/>\n") + return + if indent: + self.__write(self.__indentation[:len(self.__tags)]) + self.__write(f"\n") + + def close(self, id): + """ + Close open elements, up to (and including) the element identified + by the given identifier. + + Parameters + ---------- + id + Element identifier, as returned by the :meth:`start` method. + """ + while len(self.__tags) > id: + self.end() + + def element(self, tag, text=None, attrib={}, **extra): + """ + Add an entire element. This is the same as calling :meth:`start`, + :meth:`data`, and :meth:`end` in sequence. The *text* argument can be + omitted. + """ + self.start(tag, attrib, **extra) + if text: + self.data(text) + self.end(indent=False) + + def flush(self): + """Flush the output stream.""" + pass # replaced by the constructor + + +def _generate_transform(transform_list): + parts = [] + for type, value in transform_list: + if (type == 'scale' and (value == (1,) or value == (1, 1)) + or type == 'translate' and value == (0, 0) + or type == 'rotate' and value == (0,)): + continue + if type == 'matrix' and isinstance(value, Affine2DBase): + value = value.to_values() + parts.append('{}({})'.format( + type, ' '.join(_short_float_fmt(x) for x in value))) + return ' '.join(parts) + + +def _generate_css(attrib): + return "; ".join(f"{k}: {v}" for k, v in attrib.items()) + + +_capstyle_d = {'projecting': 'square', 'butt': 'butt', 'round': 'round'} + + +def _check_is_str(info, key): + if not isinstance(info, str): + raise TypeError(f'Invalid type for {key} metadata. Expected str, not ' + f'{type(info)}.') + + +def _check_is_iterable_of_str(infos, key): + if np.iterable(infos): + for info in infos: + if not isinstance(info, str): + raise TypeError(f'Invalid type for {key} metadata. Expected ' + f'iterable of str, not {type(info)}.') + else: + raise TypeError(f'Invalid type for {key} metadata. Expected str or ' + f'iterable of str, not {type(infos)}.') + + +class RendererSVG(RendererBase): + def __init__(self, width, height, svgwriter, basename=None, image_dpi=72, + *, metadata=None): + self.width = width + self.height = height + self.writer = XMLWriter(svgwriter) + self.image_dpi = image_dpi # actual dpi at which we rasterize stuff + + if basename is None: + basename = getattr(svgwriter, "name", "") + if not isinstance(basename, str): + basename = "" + self.basename = basename + + self._groupd = {} + self._image_counter = itertools.count() + self._clipd = {} + self._markers = {} + self._path_collection_id = 0 + self._hatchd = {} + self._has_gouraud = False + self._n_gradients = 0 + + super().__init__() + self._glyph_map = dict() + str_height = _short_float_fmt(height) + str_width = _short_float_fmt(width) + svgwriter.write(svgProlog) + self._start_id = self.writer.start( + 'svg', + width=f'{str_width}pt', + height=f'{str_height}pt', + viewBox=f'0 0 {str_width} {str_height}', + xmlns="http://www.w3.org/2000/svg", + version="1.1", + attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"}) + self._write_metadata(metadata) + self._write_default_style() + + def finalize(self): + self._write_clips() + self._write_hatches() + self.writer.close(self._start_id) + self.writer.flush() + + def _write_metadata(self, metadata): + # Add metadata following the Dublin Core Metadata Initiative, and the + # Creative Commons Rights Expression Language. This is mainly for + # compatibility with Inkscape. + if metadata is None: + metadata = {} + metadata = { + 'Format': 'image/svg+xml', + 'Type': 'http://purl.org/dc/dcmitype/StillImage', + 'Creator': + f'Matplotlib v{mpl.__version__}, https://matplotlib.org/', + **metadata + } + writer = self.writer + + if 'Title' in metadata: + title = metadata['Title'] + _check_is_str(title, 'Title') + writer.element('title', text=title) + + # Special handling. + date = metadata.get('Date', None) + if date is not None: + if isinstance(date, str): + dates = [date] + elif isinstance(date, (datetime.datetime, datetime.date)): + dates = [date.isoformat()] + elif np.iterable(date): + dates = [] + for d in date: + if isinstance(d, str): + dates.append(d) + elif isinstance(d, (datetime.datetime, datetime.date)): + dates.append(d.isoformat()) + else: + raise TypeError( + f'Invalid type for Date metadata. ' + f'Expected iterable of str, date, or datetime, ' + f'not {type(d)}.') + else: + raise TypeError(f'Invalid type for Date metadata. ' + f'Expected str, date, datetime, or iterable ' + f'of the same, not {type(date)}.') + metadata['Date'] = '/'.join(dates) + elif 'Date' not in metadata: + # Do not add `Date` if the user explicitly set `Date` to `None` + # Get source date from SOURCE_DATE_EPOCH, if set. + # See https://reproducible-builds.org/specs/source-date-epoch/ + date = os.getenv("SOURCE_DATE_EPOCH") + if date: + date = datetime.datetime.fromtimestamp(int(date), datetime.timezone.utc) + metadata['Date'] = date.replace(tzinfo=UTC).isoformat() + else: + metadata['Date'] = datetime.datetime.today().isoformat() + + mid = None + def ensure_metadata(mid): + if mid is not None: + return mid + mid = writer.start('metadata') + writer.start('rdf:RDF', attrib={ + 'xmlns:dc': "http://purl.org/dc/elements/1.1/", + 'xmlns:cc': "http://creativecommons.org/ns#", + 'xmlns:rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + }) + writer.start('cc:Work') + return mid + + uri = metadata.pop('Type', None) + if uri is not None: + mid = ensure_metadata(mid) + writer.element('dc:type', attrib={'rdf:resource': uri}) + + # Single value only. + for key in ['Title', 'Coverage', 'Date', 'Description', 'Format', + 'Identifier', 'Language', 'Relation', 'Source']: + info = metadata.pop(key, None) + if info is not None: + mid = ensure_metadata(mid) + _check_is_str(info, key) + writer.element(f'dc:{key.lower()}', text=info) + + # Multiple Agent values. + for key in ['Creator', 'Contributor', 'Publisher', 'Rights']: + agents = metadata.pop(key, None) + if agents is None: + continue + + if isinstance(agents, str): + agents = [agents] + + _check_is_iterable_of_str(agents, key) + # Now we know that we have an iterable of str + mid = ensure_metadata(mid) + writer.start(f'dc:{key.lower()}') + for agent in agents: + writer.start('cc:Agent') + writer.element('dc:title', text=agent) + writer.end('cc:Agent') + writer.end(f'dc:{key.lower()}') + + # Multiple values. + keywords = metadata.pop('Keywords', None) + if keywords is not None: + if isinstance(keywords, str): + keywords = [keywords] + _check_is_iterable_of_str(keywords, 'Keywords') + # Now we know that we have an iterable of str + mid = ensure_metadata(mid) + writer.start('dc:subject') + writer.start('rdf:Bag') + for keyword in keywords: + writer.element('rdf:li', text=keyword) + writer.end('rdf:Bag') + writer.end('dc:subject') + + if mid is not None: + writer.close(mid) + + if metadata: + raise ValueError('Unknown metadata key(s) passed to SVG writer: ' + + ','.join(metadata)) + + def _write_default_style(self): + writer = self.writer + default_style = _generate_css({ + 'stroke-linejoin': 'round', + 'stroke-linecap': 'butt'}) + writer.start('defs') + writer.element('style', type='text/css', text='*{%s}' % default_style) + writer.end('defs') + + def _make_id(self, type, content): + salt = mpl.rcParams['svg.hashsalt'] + if salt is None: + salt = str(uuid.uuid4()) + m = hashlib.sha256() + m.update(salt.encode('utf8')) + m.update(str(content).encode('utf8')) + return f'{type}{m.hexdigest()[:10]}' + + def _make_flip_transform(self, transform): + return transform + Affine2D().scale(1, -1).translate(0, self.height) + + def _get_hatch(self, gc, rgbFace): + """ + Create a new hatch pattern + """ + if rgbFace is not None: + rgbFace = tuple(rgbFace) + edge = gc.get_hatch_color() + if edge is not None: + edge = tuple(edge) + dictkey = (gc.get_hatch(), rgbFace, edge) + oid = self._hatchd.get(dictkey) + if oid is None: + oid = self._make_id('h', dictkey) + self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid) + else: + _, oid = oid + return oid + + def _write_hatches(self): + if not len(self._hatchd): + return + HATCH_SIZE = 72 + writer = self.writer + writer.start('defs') + for (path, face, stroke), oid in self._hatchd.values(): + writer.start( + 'pattern', + id=oid, + patternUnits="userSpaceOnUse", + x="0", y="0", width=str(HATCH_SIZE), + height=str(HATCH_SIZE)) + path_data = self._convert_path( + path, + Affine2D() + .scale(HATCH_SIZE).scale(1.0, -1.0).translate(0, HATCH_SIZE), + simplify=False) + if face is None: + fill = 'none' + else: + fill = rgb2hex(face) + writer.element( + 'rect', + x="0", y="0", width=str(HATCH_SIZE+1), + height=str(HATCH_SIZE+1), + fill=fill) + hatch_style = { + 'fill': rgb2hex(stroke), + 'stroke': rgb2hex(stroke), + 'stroke-width': str(mpl.rcParams['hatch.linewidth']), + 'stroke-linecap': 'butt', + 'stroke-linejoin': 'miter' + } + if stroke[3] < 1: + hatch_style['stroke-opacity'] = str(stroke[3]) + writer.element( + 'path', + d=path_data, + style=_generate_css(hatch_style) + ) + writer.end('pattern') + writer.end('defs') + + def _get_style_dict(self, gc, rgbFace): + """Generate a style string from the GraphicsContext and rgbFace.""" + attrib = {} + + forced_alpha = gc.get_forced_alpha() + + if gc.get_hatch() is not None: + attrib['fill'] = f"url(#{self._get_hatch(gc, rgbFace)})" + if (rgbFace is not None and len(rgbFace) == 4 and rgbFace[3] != 1.0 + and not forced_alpha): + attrib['fill-opacity'] = _short_float_fmt(rgbFace[3]) + else: + if rgbFace is None: + attrib['fill'] = 'none' + else: + if tuple(rgbFace[:3]) != (0, 0, 0): + attrib['fill'] = rgb2hex(rgbFace) + if (len(rgbFace) == 4 and rgbFace[3] != 1.0 + and not forced_alpha): + attrib['fill-opacity'] = _short_float_fmt(rgbFace[3]) + + if forced_alpha and gc.get_alpha() != 1.0: + attrib['opacity'] = _short_float_fmt(gc.get_alpha()) + + offset, seq = gc.get_dashes() + if seq is not None: + attrib['stroke-dasharray'] = ','.join( + _short_float_fmt(val) for val in seq) + attrib['stroke-dashoffset'] = _short_float_fmt(float(offset)) + + linewidth = gc.get_linewidth() + if linewidth: + rgb = gc.get_rgb() + attrib['stroke'] = rgb2hex(rgb) + if not forced_alpha and rgb[3] != 1.0: + attrib['stroke-opacity'] = _short_float_fmt(rgb[3]) + if linewidth != 1.0: + attrib['stroke-width'] = _short_float_fmt(linewidth) + if gc.get_joinstyle() != 'round': + attrib['stroke-linejoin'] = gc.get_joinstyle() + if gc.get_capstyle() != 'butt': + attrib['stroke-linecap'] = _capstyle_d[gc.get_capstyle()] + + return attrib + + def _get_style(self, gc, rgbFace): + return _generate_css(self._get_style_dict(gc, rgbFace)) + + def _get_clip_attrs(self, gc): + cliprect = gc.get_clip_rectangle() + clippath, clippath_trans = gc.get_clip_path() + if clippath is not None: + clippath_trans = self._make_flip_transform(clippath_trans) + dictkey = (id(clippath), str(clippath_trans)) + elif cliprect is not None: + x, y, w, h = cliprect.bounds + y = self.height-(y+h) + dictkey = (x, y, w, h) + else: + return {} + clip = self._clipd.get(dictkey) + if clip is None: + oid = self._make_id('p', dictkey) + if clippath is not None: + self._clipd[dictkey] = ((clippath, clippath_trans), oid) + else: + self._clipd[dictkey] = (dictkey, oid) + else: + clip, oid = clip + return {'clip-path': f'url(#{oid})'} + + def _write_clips(self): + if not len(self._clipd): + return + writer = self.writer + writer.start('defs') + for clip, oid in self._clipd.values(): + writer.start('clipPath', id=oid) + if len(clip) == 2: + clippath, clippath_trans = clip + path_data = self._convert_path( + clippath, clippath_trans, simplify=False) + writer.element('path', d=path_data) + else: + x, y, w, h = clip + writer.element( + 'rect', + x=_short_float_fmt(x), + y=_short_float_fmt(y), + width=_short_float_fmt(w), + height=_short_float_fmt(h)) + writer.end('clipPath') + writer.end('defs') + + def open_group(self, s, gid=None): + # docstring inherited + if gid: + self.writer.start('g', id=gid) + else: + self._groupd[s] = self._groupd.get(s, 0) + 1 + self.writer.start('g', id=f"{s}_{self._groupd[s]:d}") + + def close_group(self, s): + # docstring inherited + self.writer.end('g') + + def option_image_nocomposite(self): + # docstring inherited + return not mpl.rcParams['image.composite_image'] + + def _convert_path(self, path, transform=None, clip=None, simplify=None, + sketch=None): + if clip: + clip = (0.0, 0.0, self.width, self.height) + else: + clip = None + return _path.convert_to_string( + path, transform, clip, simplify, sketch, 6, + [b'M', b'L', b'Q', b'C', b'z'], False).decode('ascii') + + def draw_path(self, gc, path, transform, rgbFace=None): + # docstring inherited + trans_and_flip = self._make_flip_transform(transform) + clip = (rgbFace is None and gc.get_hatch_path() is None) + simplify = path.should_simplify and clip + path_data = self._convert_path( + path, trans_and_flip, clip=clip, simplify=simplify, + sketch=gc.get_sketch_params()) + + if gc.get_url() is not None: + self.writer.start('a', {'xlink:href': gc.get_url()}) + self.writer.element('path', d=path_data, **self._get_clip_attrs(gc), + style=self._get_style(gc, rgbFace)) + if gc.get_url() is not None: + self.writer.end('a') + + def draw_markers( + self, gc, marker_path, marker_trans, path, trans, rgbFace=None): + # docstring inherited + + if not len(path.vertices): + return + + writer = self.writer + path_data = self._convert_path( + marker_path, + marker_trans + Affine2D().scale(1.0, -1.0), + simplify=False) + style = self._get_style_dict(gc, rgbFace) + dictkey = (path_data, _generate_css(style)) + oid = self._markers.get(dictkey) + style = _generate_css({k: v for k, v in style.items() + if k.startswith('stroke')}) + + if oid is None: + oid = self._make_id('m', dictkey) + writer.start('defs') + writer.element('path', id=oid, d=path_data, style=style) + writer.end('defs') + self._markers[dictkey] = oid + + writer.start('g', **self._get_clip_attrs(gc)) + trans_and_flip = self._make_flip_transform(trans) + attrib = {'xlink:href': f'#{oid}'} + clip = (0, 0, self.width*72, self.height*72) + for vertices, code in path.iter_segments( + trans_and_flip, clip=clip, simplify=False): + if len(vertices): + x, y = vertices[-2:] + attrib['x'] = _short_float_fmt(x) + attrib['y'] = _short_float_fmt(y) + attrib['style'] = self._get_style(gc, rgbFace) + writer.element('use', attrib=attrib) + writer.end('g') + + def draw_path_collection(self, gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position): + # Is the optimization worth it? Rough calculation: + # cost of emitting a path in-line is + # (len_path + 5) * uses_per_path + # cost of definition+use is + # (len_path + 3) + 9 * uses_per_path + len_path = len(paths[0].vertices) if len(paths) > 0 else 0 + uses_per_path = self._iter_collection_uses_per_path( + paths, all_transforms, offsets, facecolors, edgecolors) + should_do_optimization = \ + len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path + if not should_do_optimization: + return super().draw_path_collection( + gc, master_transform, paths, all_transforms, + offsets, offset_trans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position) + + writer = self.writer + path_codes = [] + writer.start('defs') + for i, (path, transform) in enumerate(self._iter_collection_raw_paths( + master_transform, paths, all_transforms)): + transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0) + d = self._convert_path(path, transform, simplify=False) + oid = 'C{:x}_{:x}_{}'.format( + self._path_collection_id, i, self._make_id('', d)) + writer.element('path', id=oid, d=d) + path_codes.append(oid) + writer.end('defs') + + for xo, yo, path_id, gc0, rgbFace in self._iter_collection( + gc, path_codes, offsets, offset_trans, + facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): + url = gc0.get_url() + if url is not None: + writer.start('a', attrib={'xlink:href': url}) + clip_attrs = self._get_clip_attrs(gc0) + if clip_attrs: + writer.start('g', **clip_attrs) + attrib = { + 'xlink:href': f'#{path_id}', + 'x': _short_float_fmt(xo), + 'y': _short_float_fmt(self.height - yo), + 'style': self._get_style(gc0, rgbFace) + } + writer.element('use', attrib=attrib) + if clip_attrs: + writer.end('g') + if url is not None: + writer.end('a') + + self._path_collection_id += 1 + + def draw_gouraud_triangle(self, gc, points, colors, trans): + # docstring inherited + self._draw_gouraud_triangle(gc, points, colors, trans) + + def _draw_gouraud_triangle(self, gc, points, colors, trans): + # This uses a method described here: + # + # http://www.svgopen.org/2005/papers/Converting3DFaceToSVG/index.html + # + # that uses three overlapping linear gradients to simulate a + # Gouraud triangle. Each gradient goes from fully opaque in + # one corner to fully transparent along the opposite edge. + # The line between the stop points is perpendicular to the + # opposite edge. Underlying these three gradients is a solid + # triangle whose color is the average of all three points. + + writer = self.writer + if not self._has_gouraud: + self._has_gouraud = True + writer.start( + 'filter', + id='colorAdd') + writer.element( + 'feComposite', + attrib={'in': 'SourceGraphic'}, + in2='BackgroundImage', + operator='arithmetic', + k2="1", k3="1") + writer.end('filter') + # feColorMatrix filter to correct opacity + writer.start( + 'filter', + id='colorMat') + writer.element( + 'feColorMatrix', + attrib={'type': 'matrix'}, + values='1 0 0 0 0 \n0 1 0 0 0 \n0 0 1 0 0' + + ' \n1 1 1 1 0 \n0 0 0 0 1 ') + writer.end('filter') + + avg_color = np.average(colors, axis=0) + if avg_color[-1] == 0: + # Skip fully-transparent triangles + return + + trans_and_flip = self._make_flip_transform(trans) + tpoints = trans_and_flip.transform(points) + + writer.start('defs') + for i in range(3): + x1, y1 = tpoints[i] + x2, y2 = tpoints[(i + 1) % 3] + x3, y3 = tpoints[(i + 2) % 3] + rgba_color = colors[i] + + if x2 == x3: + xb = x2 + yb = y1 + elif y2 == y3: + xb = x1 + yb = y2 + else: + m1 = (y2 - y3) / (x2 - x3) + b1 = y2 - (m1 * x2) + m2 = -(1.0 / m1) + b2 = y1 - (m2 * x1) + xb = (-b1 + b2) / (m1 - m2) + yb = m2 * xb + b2 + + writer.start( + 'linearGradient', + id=f"GR{self._n_gradients:x}_{i:d}", + gradientUnits="userSpaceOnUse", + x1=_short_float_fmt(x1), y1=_short_float_fmt(y1), + x2=_short_float_fmt(xb), y2=_short_float_fmt(yb)) + writer.element( + 'stop', + offset='1', + style=_generate_css({ + 'stop-color': rgb2hex(avg_color), + 'stop-opacity': _short_float_fmt(rgba_color[-1])})) + writer.element( + 'stop', + offset='0', + style=_generate_css({'stop-color': rgb2hex(rgba_color), + 'stop-opacity': "0"})) + + writer.end('linearGradient') + + writer.end('defs') + + # triangle formation using "path" + dpath = "M " + _short_float_fmt(x1)+',' + _short_float_fmt(y1) + dpath += " L " + _short_float_fmt(x2) + ',' + _short_float_fmt(y2) + dpath += " " + _short_float_fmt(x3) + ',' + _short_float_fmt(y3) + " Z" + + writer.element( + 'path', + attrib={'d': dpath, + 'fill': rgb2hex(avg_color), + 'fill-opacity': '1', + 'shape-rendering': "crispEdges"}) + + writer.start( + 'g', + attrib={'stroke': "none", + 'stroke-width': "0", + 'shape-rendering': "crispEdges", + 'filter': "url(#colorMat)"}) + + writer.element( + 'path', + attrib={'d': dpath, + 'fill': f'url(#GR{self._n_gradients:x}_0)', + 'shape-rendering': "crispEdges"}) + + writer.element( + 'path', + attrib={'d': dpath, + 'fill': f'url(#GR{self._n_gradients:x}_1)', + 'filter': 'url(#colorAdd)', + 'shape-rendering': "crispEdges"}) + + writer.element( + 'path', + attrib={'d': dpath, + 'fill': f'url(#GR{self._n_gradients:x}_2)', + 'filter': 'url(#colorAdd)', + 'shape-rendering': "crispEdges"}) + + writer.end('g') + + self._n_gradients += 1 + + def draw_gouraud_triangles(self, gc, triangles_array, colors_array, + transform): + self.writer.start('g', **self._get_clip_attrs(gc)) + transform = transform.frozen() + for tri, col in zip(triangles_array, colors_array): + self._draw_gouraud_triangle(gc, tri, col, transform) + self.writer.end('g') + + def option_scale_image(self): + # docstring inherited + return True + + def get_image_magnification(self): + return self.image_dpi / 72.0 + + def draw_image(self, gc, x, y, im, transform=None): + # docstring inherited + + h, w = im.shape[:2] + + if w == 0 or h == 0: + return + + clip_attrs = self._get_clip_attrs(gc) + if clip_attrs: + # Can't apply clip-path directly to the image because the image has + # a transformation, which would also be applied to the clip-path. + self.writer.start('g', **clip_attrs) + + url = gc.get_url() + if url is not None: + self.writer.start('a', attrib={'xlink:href': url}) + + attrib = {} + oid = gc.get_gid() + if mpl.rcParams['svg.image_inline']: + buf = BytesIO() + Image.fromarray(im).save(buf, format="png") + oid = oid or self._make_id('image', buf.getvalue()) + attrib['xlink:href'] = ( + "data:image/png;base64,\n" + + base64.b64encode(buf.getvalue()).decode('ascii')) + else: + if self.basename is None: + raise ValueError("Cannot save image data to filesystem when " + "writing SVG to an in-memory buffer") + filename = f'{self.basename}.image{next(self._image_counter)}.png' + _log.info('Writing image file for inclusion: %s', filename) + Image.fromarray(im).save(filename) + oid = oid or 'Im_' + self._make_id('image', filename) + attrib['xlink:href'] = filename + attrib['id'] = oid + + if transform is None: + w = 72.0 * w / self.image_dpi + h = 72.0 * h / self.image_dpi + + self.writer.element( + 'image', + transform=_generate_transform([ + ('scale', (1, -1)), ('translate', (0, -h))]), + x=_short_float_fmt(x), + y=_short_float_fmt(-(self.height - y - h)), + width=_short_float_fmt(w), height=_short_float_fmt(h), + attrib=attrib) + else: + alpha = gc.get_alpha() + if alpha != 1.0: + attrib['opacity'] = _short_float_fmt(alpha) + + flipped = ( + Affine2D().scale(1.0 / w, 1.0 / h) + + transform + + Affine2D() + .translate(x, y) + .scale(1.0, -1.0) + .translate(0.0, self.height)) + + attrib['transform'] = _generate_transform( + [('matrix', flipped.frozen())]) + attrib['style'] = ( + 'image-rendering:crisp-edges;' + 'image-rendering:pixelated') + self.writer.element( + 'image', + width=_short_float_fmt(w), height=_short_float_fmt(h), + attrib=attrib) + + if url is not None: + self.writer.end('a') + if clip_attrs: + self.writer.end('g') + + def _update_glyph_map_defs(self, glyph_map_new): + """ + Emit definitions for not-yet-defined glyphs, and record them as having + been defined. + """ + writer = self.writer + if glyph_map_new: + writer.start('defs') + for char_id, (vertices, codes) in glyph_map_new.items(): + char_id = self._adjust_char_id(char_id) + # x64 to go back to FreeType's internal (integral) units. + path_data = self._convert_path( + Path(vertices * 64, codes), simplify=False) + writer.element( + 'path', id=char_id, d=path_data, + transform=_generate_transform([('scale', (1 / 64,))])) + writer.end('defs') + self._glyph_map.update(glyph_map_new) + + def _adjust_char_id(self, char_id): + return char_id.replace("%20", "_") + + def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None): + # docstring inherited + writer = self.writer + + writer.comment(s) + + glyph_map = self._glyph_map + + text2path = self._text2path + color = rgb2hex(gc.get_rgb()) + fontsize = prop.get_size_in_points() + + style = {} + if color != '#000000': + style['fill'] = color + alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3] + if alpha != 1: + style['opacity'] = _short_float_fmt(alpha) + font_scale = fontsize / text2path.FONT_SCALE + attrib = { + 'style': _generate_css(style), + 'transform': _generate_transform([ + ('translate', (x, y)), + ('rotate', (-angle,)), + ('scale', (font_scale, -font_scale))]), + } + writer.start('g', attrib=attrib) + + if not ismath: + font = text2path._get_font(prop) + _glyphs = text2path.get_glyphs_with_font( + font, s, glyph_map=glyph_map, return_new_glyphs_only=True) + glyph_info, glyph_map_new, rects = _glyphs + self._update_glyph_map_defs(glyph_map_new) + + for glyph_id, xposition, yposition, scale in glyph_info: + attrib = {'xlink:href': f'#{glyph_id}'} + if xposition != 0.0: + attrib['x'] = _short_float_fmt(xposition) + if yposition != 0.0: + attrib['y'] = _short_float_fmt(yposition) + writer.element('use', attrib=attrib) + + else: + if ismath == "TeX": + _glyphs = text2path.get_glyphs_tex( + prop, s, glyph_map=glyph_map, return_new_glyphs_only=True) + else: + _glyphs = text2path.get_glyphs_mathtext( + prop, s, glyph_map=glyph_map, return_new_glyphs_only=True) + glyph_info, glyph_map_new, rects = _glyphs + self._update_glyph_map_defs(glyph_map_new) + + for char_id, xposition, yposition, scale in glyph_info: + char_id = self._adjust_char_id(char_id) + writer.element( + 'use', + transform=_generate_transform([ + ('translate', (xposition, yposition)), + ('scale', (scale,)), + ]), + attrib={'xlink:href': f'#{char_id}'}) + + for verts, codes in rects: + path = Path(verts, codes) + path_data = self._convert_path(path, simplify=False) + writer.element('path', d=path_data) + + writer.end('g') + + def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None): + writer = self.writer + + color = rgb2hex(gc.get_rgb()) + style = {} + if color != '#000000': + style['fill'] = color + + alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3] + if alpha != 1: + style['opacity'] = _short_float_fmt(alpha) + + if not ismath: + attrib = {} + + font_parts = [] + if prop.get_style() != 'normal': + font_parts.append(prop.get_style()) + if prop.get_variant() != 'normal': + font_parts.append(prop.get_variant()) + weight = fm.weight_dict[prop.get_weight()] + if weight != 400: + font_parts.append(f'{weight}') + + def _normalize_sans(name): + return 'sans-serif' if name in ['sans', 'sans serif'] else name + + def _expand_family_entry(fn): + fn = _normalize_sans(fn) + # prepend generic font families with all configured font names + if fn in fm.font_family_aliases: + # get all of the font names and fix spelling of sans-serif + # (we accept 3 ways CSS only supports 1) + for name in fm.FontManager._expand_aliases(fn): + yield _normalize_sans(name) + # whether a generic name or a family name, it must appear at + # least once + yield fn + + def _get_all_quoted_names(prop): + # only quote specific names, not generic names + return [name if name in fm.font_family_aliases else repr(name) + for entry in prop.get_family() + for name in _expand_family_entry(entry)] + + font_parts.extend([ + f'{_short_float_fmt(prop.get_size())}px', + # ensure expansion, quoting, and dedupe of font names + ", ".join(dict.fromkeys(_get_all_quoted_names(prop))) + ]) + style['font'] = ' '.join(font_parts) + if prop.get_stretch() != 'normal': + style['font-stretch'] = prop.get_stretch() + attrib['style'] = _generate_css(style) + + if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"): + # If text anchoring can be supported, get the original + # coordinates and add alignment information. + + # Get anchor coordinates. + transform = mtext.get_transform() + ax, ay = transform.transform(mtext.get_unitless_position()) + ay = self.height - ay + + # Don't do vertical anchor alignment. Most applications do not + # support 'alignment-baseline' yet. Apply the vertical layout + # to the anchor point manually for now. + angle_rad = np.deg2rad(angle) + dir_vert = np.array([np.sin(angle_rad), np.cos(angle_rad)]) + v_offset = np.dot(dir_vert, [(x - ax), (y - ay)]) + ax = ax + v_offset * dir_vert[0] + ay = ay + v_offset * dir_vert[1] + + ha_mpl_to_svg = {'left': 'start', 'right': 'end', + 'center': 'middle'} + style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()] + + attrib['x'] = _short_float_fmt(ax) + attrib['y'] = _short_float_fmt(ay) + attrib['style'] = _generate_css(style) + attrib['transform'] = _generate_transform([ + ("rotate", (-angle, ax, ay))]) + + else: + attrib['transform'] = _generate_transform([ + ('translate', (x, y)), + ('rotate', (-angle,))]) + + writer.element('text', s, attrib=attrib) + + else: + writer.comment(s) + + width, height, descent, glyphs, rects = \ + self._text2path.mathtext_parser.parse(s, 72, prop) + + # Apply attributes to 'g', not 'text', because we likely have some + # rectangles as well with the same style and transformation. + writer.start('g', + style=_generate_css(style), + transform=_generate_transform([ + ('translate', (x, y)), + ('rotate', (-angle,))]), + ) + + writer.start('text') + + # Sort the characters by font, and output one tspan for each. + spans = {} + for font, fontsize, thetext, new_x, new_y in glyphs: + entry = fm.ttfFontProperty(font) + font_parts = [] + if entry.style != 'normal': + font_parts.append(entry.style) + if entry.variant != 'normal': + font_parts.append(entry.variant) + if entry.weight != 400: + font_parts.append(f'{entry.weight}') + font_parts.extend([ + f'{_short_float_fmt(fontsize)}px', + f'{entry.name!r}', # ensure quoting + ]) + style = {'font': ' '.join(font_parts)} + if entry.stretch != 'normal': + style['font-stretch'] = entry.stretch + style = _generate_css(style) + if thetext == 32: + thetext = 0xa0 # non-breaking space + spans.setdefault(style, []).append((new_x, -new_y, thetext)) + + for style, chars in spans.items(): + chars.sort() + + if len({y for x, y, t in chars}) == 1: # Are all y's the same? + ys = str(chars[0][1]) + else: + ys = ' '.join(str(c[1]) for c in chars) + + attrib = { + 'style': style, + 'x': ' '.join(_short_float_fmt(c[0]) for c in chars), + 'y': ys + } + + writer.element( + 'tspan', + ''.join(chr(c[2]) for c in chars), + attrib=attrib) + + writer.end('text') + + for x, y, width, height in rects: + writer.element( + 'rect', + x=_short_float_fmt(x), + y=_short_float_fmt(-y-1), + width=_short_float_fmt(width), + height=_short_float_fmt(height) + ) + + writer.end('g') + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + # docstring inherited + + clip_attrs = self._get_clip_attrs(gc) + if clip_attrs: + # Cannot apply clip-path directly to the text, because + # it has a transformation + self.writer.start('g', **clip_attrs) + + if gc.get_url() is not None: + self.writer.start('a', {'xlink:href': gc.get_url()}) + + if mpl.rcParams['svg.fonttype'] == 'path': + self._draw_text_as_path(gc, x, y, s, prop, angle, ismath, mtext) + else: + self._draw_text_as_text(gc, x, y, s, prop, angle, ismath, mtext) + + if gc.get_url() is not None: + self.writer.end('a') + + if clip_attrs: + self.writer.end('g') + + def flipy(self): + # docstring inherited + return True + + def get_canvas_width_height(self): + # docstring inherited + return self.width, self.height + + def get_text_width_height_descent(self, s, prop, ismath): + # docstring inherited + return self._text2path.get_text_width_height_descent(s, prop, ismath) + + +class FigureCanvasSVG(FigureCanvasBase): + filetypes = {'svg': 'Scalable Vector Graphics', + 'svgz': 'Scalable Vector Graphics'} + + fixed_dpi = 72 + + def print_svg(self, filename, *, bbox_inches_restore=None, metadata=None): + """ + Parameters + ---------- + filename : str or path-like or file-like + Output target; if a string, a file will be opened for writing. + + metadata : dict[str, Any], optional + Metadata in the SVG file defined as key-value pairs of strings, + datetimes, or lists of strings, e.g., ``{'Creator': 'My software', + 'Contributor': ['Me', 'My Friend'], 'Title': 'Awesome'}``. + + The standard keys and their value types are: + + * *str*: ``'Coverage'``, ``'Description'``, ``'Format'``, + ``'Identifier'``, ``'Language'``, ``'Relation'``, ``'Source'``, + ``'Title'``, and ``'Type'``. + * *str* or *list of str*: ``'Contributor'``, ``'Creator'``, + ``'Keywords'``, ``'Publisher'``, and ``'Rights'``. + * *str*, *date*, *datetime*, or *tuple* of same: ``'Date'``. If a + non-*str*, then it will be formatted as ISO 8601. + + Values have been predefined for ``'Creator'``, ``'Date'``, + ``'Format'``, and ``'Type'``. They can be removed by setting them + to `None`. + + Information is encoded as `Dublin Core Metadata`__. + + .. _DC: https://www.dublincore.org/specifications/dublin-core/ + + __ DC_ + """ + with cbook.open_file_cm(filename, "w", encoding="utf-8") as fh: + if not cbook.file_requires_unicode(fh): + fh = codecs.getwriter('utf-8')(fh) + dpi = self.figure.dpi + self.figure.dpi = 72 + width, height = self.figure.get_size_inches() + w, h = width * 72, height * 72 + renderer = MixedModeRenderer( + self.figure, width, height, dpi, + RendererSVG(w, h, fh, image_dpi=dpi, metadata=metadata), + bbox_inches_restore=bbox_inches_restore) + self.figure.draw(renderer) + renderer.finalize() + + def print_svgz(self, filename, **kwargs): + with cbook.open_file_cm(filename, "wb") as fh, \ + gzip.GzipFile(mode='w', fileobj=fh) as gzipwriter: + return self.print_svg(gzipwriter, **kwargs) + + def get_default_filetype(self): + return 'svg' + + def draw(self): + self.figure.draw_without_rendering() + return super().draw() + + +FigureManagerSVG = FigureManagerBase + + +svgProlog = """\ + + +""" + + +@_Backend.export +class _BackendSVG(_Backend): + backend_version = mpl.__version__ + FigureCanvas = FigureCanvasSVG diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_template.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_template.py new file mode 100644 index 00000000..d997ec16 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_template.py @@ -0,0 +1,213 @@ +""" +A fully functional, do-nothing backend intended as a template for backend +writers. It is fully functional in that you can select it as a backend e.g. +with :: + + import matplotlib + matplotlib.use("template") + +and your program will (should!) run without error, though no output is +produced. This provides a starting point for backend writers; you can +selectively implement drawing methods (`~.RendererTemplate.draw_path`, +`~.RendererTemplate.draw_image`, etc.) and slowly see your figure come to life +instead having to have a full-blown implementation before getting any results. + +Copy this file to a directory outside the Matplotlib source tree, somewhere +where Python can import it (by adding the directory to your ``sys.path`` or by +packaging it as a normal Python package); if the backend is importable as +``import my.backend`` you can then select it using :: + + import matplotlib + matplotlib.use("module://my.backend") + +If your backend implements support for saving figures (i.e. has a `print_xyz` +method), you can register it as the default handler for a given file type:: + + from matplotlib.backend_bases import register_backend + register_backend('xyz', 'my_backend', 'XYZ File Format') + ... + plt.savefig("figure.xyz") +""" + +from matplotlib import _api +from matplotlib._pylab_helpers import Gcf +from matplotlib.backend_bases import ( + FigureCanvasBase, FigureManagerBase, GraphicsContextBase, RendererBase) +from matplotlib.figure import Figure + + +class RendererTemplate(RendererBase): + """ + The renderer handles drawing/rendering operations. + + This is a minimal do-nothing class that can be used to get started when + writing a new backend. Refer to `.backend_bases.RendererBase` for + documentation of the methods. + """ + + def __init__(self, dpi): + super().__init__() + self.dpi = dpi + + def draw_path(self, gc, path, transform, rgbFace=None): + pass + + # draw_markers is optional, and we get more correct relative + # timings by leaving it out. backend implementers concerned with + # performance will probably want to implement it +# def draw_markers(self, gc, marker_path, marker_trans, path, trans, +# rgbFace=None): +# pass + + # draw_path_collection is optional, and we get more correct + # relative timings by leaving it out. backend implementers concerned with + # performance will probably want to implement it +# def draw_path_collection(self, gc, master_transform, paths, +# all_transforms, offsets, offset_trans, +# facecolors, edgecolors, linewidths, linestyles, +# antialiaseds): +# pass + + # draw_quad_mesh is optional, and we get more correct + # relative timings by leaving it out. backend implementers concerned with + # performance will probably want to implement it +# def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, +# coordinates, offsets, offsetTrans, facecolors, +# antialiased, edgecolors): +# pass + + def draw_image(self, gc, x, y, im): + pass + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + pass + + def flipy(self): + # docstring inherited + return True + + def get_canvas_width_height(self): + # docstring inherited + return 100, 100 + + def get_text_width_height_descent(self, s, prop, ismath): + return 1, 1, 1 + + def new_gc(self): + # docstring inherited + return GraphicsContextTemplate() + + def points_to_pixels(self, points): + # if backend doesn't have dpi, e.g., postscript or svg + return points + # elif backend assumes a value for pixels_per_inch + # return points/72.0 * self.dpi.get() * pixels_per_inch/72.0 + # else + # return points/72.0 * self.dpi.get() + + +class GraphicsContextTemplate(GraphicsContextBase): + """ + The graphics context provides the color, line styles, etc. See the cairo + and postscript backends for examples of mapping the graphics context + attributes (cap styles, join styles, line widths, colors) to a particular + backend. In cairo this is done by wrapping a cairo.Context object and + forwarding the appropriate calls to it using a dictionary mapping styles + to gdk constants. In Postscript, all the work is done by the renderer, + mapping line styles to postscript calls. + + If it's more appropriate to do the mapping at the renderer level (as in + the postscript backend), you don't need to override any of the GC methods. + If it's more appropriate to wrap an instance (as in the cairo backend) and + do the mapping here, you'll need to override several of the setter + methods. + + The base GraphicsContext stores colors as an RGB tuple on the unit + interval, e.g., (0.5, 0.0, 1.0). You may need to map this to colors + appropriate for your backend. + """ + + +######################################################################## +# +# The following functions and classes are for pyplot and implement +# window/figure managers, etc. +# +######################################################################## + + +class FigureManagerTemplate(FigureManagerBase): + """ + Helper class for pyplot mode, wraps everything up into a neat bundle. + + For non-interactive backends, the base class is sufficient. For + interactive backends, see the documentation of the `.FigureManagerBase` + class for the list of methods that can/should be overridden. + """ + + +class FigureCanvasTemplate(FigureCanvasBase): + """ + The canvas the figure renders into. Calls the draw and print fig + methods, creates the renderers, etc. + + Note: GUI templates will want to connect events for button presses, + mouse movements and key presses to functions that call the base + class methods button_press_event, button_release_event, + motion_notify_event, key_press_event, and key_release_event. See the + implementations of the interactive backends for examples. + + Attributes + ---------- + figure : `~matplotlib.figure.Figure` + A high-level Figure instance + """ + + # The instantiated manager class. For further customization, + # ``FigureManager.create_with_canvas`` can also be overridden; see the + # wx-based backends for an example. + manager_class = FigureManagerTemplate + + def draw(self): + """ + Draw the figure using the renderer. + + It is important that this method actually walk the artist tree + even if not output is produced because this will trigger + deferred work (like computing limits auto-limits and tick + values) that users may want access to before saving to disk. + """ + renderer = RendererTemplate(self.figure.dpi) + self.figure.draw(renderer) + + # You should provide a print_xxx function for every file format + # you can write. + + # If the file type is not in the base set of filetypes, + # you should add it to the class-scope filetypes dictionary as follows: + filetypes = {**FigureCanvasBase.filetypes, 'foo': 'My magic Foo format'} + + def print_foo(self, filename, **kwargs): + """ + Write out format foo. + + This method is normally called via `.Figure.savefig` and + `.FigureCanvasBase.print_figure`, which take care of setting the figure + facecolor, edgecolor, and dpi to the desired output values, and will + restore them to the original values. Therefore, `print_foo` does not + need to handle these settings. + """ + self.draw() + + def get_default_filetype(self): + return 'foo' + + +######################################################################## +# +# Now just provide the standard names that backend.__init__ is expecting +# +######################################################################## + +FigureCanvas = FigureCanvasTemplate +FigureManager = FigureManagerTemplate diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkagg.py new file mode 100644 index 00000000..f95b6011 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkagg.py @@ -0,0 +1,20 @@ +from . import _backend_tk +from .backend_agg import FigureCanvasAgg +from ._backend_tk import _BackendTk, FigureCanvasTk +from ._backend_tk import ( # noqa: F401 # pylint: disable=W0611 + FigureManagerTk, NavigationToolbar2Tk) + + +class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk): + def draw(self): + super().draw() + self.blit() + + def blit(self, bbox=None): + _backend_tk.blit(self._tkphoto, self.renderer.buffer_rgba(), + (0, 1, 2, 3), bbox=bbox) + + +@_BackendTk.export +class _BackendTkAgg(_BackendTk): + FigureCanvas = FigureCanvasTkAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkcairo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkcairo.py new file mode 100644 index 00000000..a6951c03 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_tkcairo.py @@ -0,0 +1,26 @@ +import sys + +import numpy as np + +from . import _backend_tk +from .backend_cairo import cairo, FigureCanvasCairo +from ._backend_tk import _BackendTk, FigureCanvasTk + + +class FigureCanvasTkCairo(FigureCanvasCairo, FigureCanvasTk): + def draw(self): + width = int(self.figure.bbox.width) + height = int(self.figure.bbox.height) + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + self._renderer.set_context(cairo.Context(surface)) + self._renderer.dpi = self.figure.dpi + self.figure.draw(self._renderer) + buf = np.reshape(surface.get_data(), (height, width, 4)) + _backend_tk.blit( + self._tkphoto, buf, + (2, 1, 0, 3) if sys.byteorder == "little" else (1, 2, 3, 0)) + + +@_BackendTk.export +class _BackendTkCairo(_BackendTk): + FigureCanvas = FigureCanvasTkCairo diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg.py new file mode 100644 index 00000000..14c0b525 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg.py @@ -0,0 +1,334 @@ +"""Displays Agg images in the browser, with interactivity.""" + +# The WebAgg backend is divided into two modules: +# +# - `backend_webagg_core.py` contains code necessary to embed a WebAgg +# plot inside of a web application, and communicate in an abstract +# way over a web socket. +# +# - `backend_webagg.py` contains a concrete implementation of a basic +# application, implemented with tornado. + +from contextlib import contextmanager +import errno +from io import BytesIO +import json +import mimetypes +from pathlib import Path +import random +import sys +import signal +import threading + +try: + import tornado +except ImportError as err: + raise RuntimeError("The WebAgg backend requires Tornado.") from err + +import tornado.web +import tornado.ioloop +import tornado.websocket + +import matplotlib as mpl +from matplotlib.backend_bases import _Backend +from matplotlib._pylab_helpers import Gcf +from . import backend_webagg_core as core +from .backend_webagg_core import ( # noqa: F401 # pylint: disable=W0611 + TimerAsyncio, TimerTornado) + + +@mpl._api.deprecated("3.7") +class ServerThread(threading.Thread): + def run(self): + tornado.ioloop.IOLoop.instance().start() + + +webagg_server_thread = threading.Thread( + target=lambda: tornado.ioloop.IOLoop.instance().start()) + + +class FigureManagerWebAgg(core.FigureManagerWebAgg): + _toolbar2_class = core.NavigationToolbar2WebAgg + + @classmethod + def pyplot_show(cls, *, block=None): + WebAggApplication.initialize() + + url = "http://{address}:{port}{prefix}".format( + address=WebAggApplication.address, + port=WebAggApplication.port, + prefix=WebAggApplication.url_prefix) + + if mpl.rcParams['webagg.open_in_browser']: + import webbrowser + if not webbrowser.open(url): + print(f"To view figure, visit {url}") + else: + print(f"To view figure, visit {url}") + + WebAggApplication.start() + + +class FigureCanvasWebAgg(core.FigureCanvasWebAggCore): + manager_class = FigureManagerWebAgg + + +class WebAggApplication(tornado.web.Application): + initialized = False + started = False + + class FavIcon(tornado.web.RequestHandler): + def get(self): + self.set_header('Content-Type', 'image/png') + self.write(Path(mpl.get_data_path(), + 'images/matplotlib.png').read_bytes()) + + class SingleFigurePage(tornado.web.RequestHandler): + def __init__(self, application, request, *, url_prefix='', **kwargs): + self.url_prefix = url_prefix + super().__init__(application, request, **kwargs) + + def get(self, fignum): + fignum = int(fignum) + manager = Gcf.get_fig_manager(fignum) + + ws_uri = f'ws://{self.request.host}{self.url_prefix}/' + self.render( + "single_figure.html", + prefix=self.url_prefix, + ws_uri=ws_uri, + fig_id=fignum, + toolitems=core.NavigationToolbar2WebAgg.toolitems, + canvas=manager.canvas) + + class AllFiguresPage(tornado.web.RequestHandler): + def __init__(self, application, request, *, url_prefix='', **kwargs): + self.url_prefix = url_prefix + super().__init__(application, request, **kwargs) + + def get(self): + ws_uri = f'ws://{self.request.host}{self.url_prefix}/' + self.render( + "all_figures.html", + prefix=self.url_prefix, + ws_uri=ws_uri, + figures=sorted(Gcf.figs.items()), + toolitems=core.NavigationToolbar2WebAgg.toolitems) + + class MplJs(tornado.web.RequestHandler): + def get(self): + self.set_header('Content-Type', 'application/javascript') + + js_content = core.FigureManagerWebAgg.get_javascript() + + self.write(js_content) + + class Download(tornado.web.RequestHandler): + def get(self, fignum, fmt): + fignum = int(fignum) + manager = Gcf.get_fig_manager(fignum) + self.set_header( + 'Content-Type', mimetypes.types_map.get(fmt, 'binary')) + buff = BytesIO() + manager.canvas.figure.savefig(buff, format=fmt) + self.write(buff.getvalue()) + + class WebSocket(tornado.websocket.WebSocketHandler): + supports_binary = True + + def open(self, fignum): + self.fignum = int(fignum) + self.manager = Gcf.get_fig_manager(self.fignum) + self.manager.add_web_socket(self) + if hasattr(self, 'set_nodelay'): + self.set_nodelay(True) + + def on_close(self): + self.manager.remove_web_socket(self) + + def on_message(self, message): + message = json.loads(message) + # The 'supports_binary' message is on a client-by-client + # basis. The others affect the (shared) canvas as a + # whole. + if message['type'] == 'supports_binary': + self.supports_binary = message['value'] + else: + manager = Gcf.get_fig_manager(self.fignum) + # It is possible for a figure to be closed, + # but a stale figure UI is still sending messages + # from the browser. + if manager is not None: + manager.handle_json(message) + + def send_json(self, content): + self.write_message(json.dumps(content)) + + def send_binary(self, blob): + if self.supports_binary: + self.write_message(blob, binary=True) + else: + data_uri = "data:image/png;base64,{}".format( + blob.encode('base64').replace('\n', '')) + self.write_message(data_uri) + + def __init__(self, url_prefix=''): + if url_prefix: + assert url_prefix[0] == '/' and url_prefix[-1] != '/', \ + 'url_prefix must start with a "/" and not end with one.' + + super().__init__( + [ + # Static files for the CSS and JS + (url_prefix + r'/_static/(.*)', + tornado.web.StaticFileHandler, + {'path': core.FigureManagerWebAgg.get_static_file_path()}), + + # Static images for the toolbar + (url_prefix + r'/_images/(.*)', + tornado.web.StaticFileHandler, + {'path': Path(mpl.get_data_path(), 'images')}), + + # A Matplotlib favicon + (url_prefix + r'/favicon.ico', self.FavIcon), + + # The page that contains all of the pieces + (url_prefix + r'/([0-9]+)', self.SingleFigurePage, + {'url_prefix': url_prefix}), + + # The page that contains all of the figures + (url_prefix + r'/?', self.AllFiguresPage, + {'url_prefix': url_prefix}), + + (url_prefix + r'/js/mpl.js', self.MplJs), + + # Sends images and events to the browser, and receives + # events from the browser + (url_prefix + r'/([0-9]+)/ws', self.WebSocket), + + # Handles the downloading (i.e., saving) of static images + (url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)', + self.Download), + ], + template_path=core.FigureManagerWebAgg.get_static_file_path()) + + @classmethod + def initialize(cls, url_prefix='', port=None, address=None): + if cls.initialized: + return + + # Create the class instance + app = cls(url_prefix=url_prefix) + + cls.url_prefix = url_prefix + + # This port selection algorithm is borrowed, more or less + # verbatim, from IPython. + def random_ports(port, n): + """ + Generate a list of n random ports near the given port. + + The first 5 ports will be sequential, and the remaining n-5 will be + randomly selected in the range [port-2*n, port+2*n]. + """ + for i in range(min(5, n)): + yield port + i + for i in range(n - 5): + yield port + random.randint(-2 * n, 2 * n) + + if address is None: + cls.address = mpl.rcParams['webagg.address'] + else: + cls.address = address + cls.port = mpl.rcParams['webagg.port'] + for port in random_ports(cls.port, + mpl.rcParams['webagg.port_retries']): + try: + app.listen(port, cls.address) + except OSError as e: + if e.errno != errno.EADDRINUSE: + raise + else: + cls.port = port + break + else: + raise SystemExit( + "The webagg server could not be started because an available " + "port could not be found") + + cls.initialized = True + + @classmethod + def start(cls): + import asyncio + try: + asyncio.get_running_loop() + except RuntimeError: + pass + else: + cls.started = True + + if cls.started: + return + + """ + IOLoop.running() was removed as of Tornado 2.4; see for example + https://groups.google.com/forum/#!topic/python-tornado/QLMzkpQBGOY + Thus there is no correct way to check if the loop has already been + launched. We may end up with two concurrently running loops in that + unlucky case with all the expected consequences. + """ + ioloop = tornado.ioloop.IOLoop.instance() + + def shutdown(): + ioloop.stop() + print("Server is stopped") + sys.stdout.flush() + cls.started = False + + @contextmanager + def catch_sigint(): + old_handler = signal.signal( + signal.SIGINT, + lambda sig, frame: ioloop.add_callback_from_signal(shutdown)) + try: + yield + finally: + signal.signal(signal.SIGINT, old_handler) + + # Set the flag to True *before* blocking on ioloop.start() + cls.started = True + + print("Press Ctrl+C to stop WebAgg server") + sys.stdout.flush() + with catch_sigint(): + ioloop.start() + + +def ipython_inline_display(figure): + import tornado.template + + WebAggApplication.initialize() + import asyncio + try: + asyncio.get_running_loop() + except RuntimeError: + if not webagg_server_thread.is_alive(): + webagg_server_thread.start() + + fignum = figure.number + tpl = Path(core.FigureManagerWebAgg.get_static_file_path(), + "ipython_inline_figure.html").read_text() + t = tornado.template.Template(tpl) + return t.generate( + prefix=WebAggApplication.url_prefix, + fig_id=fignum, + toolitems=core.NavigationToolbar2WebAgg.toolitems, + canvas=figure.canvas, + port=WebAggApplication.port).decode('utf-8') + + +@_Backend.export +class _BackendWebAgg(_Backend): + FigureCanvas = FigureCanvasWebAgg + FigureManager = FigureManagerWebAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg_core.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg_core.py new file mode 100644 index 00000000..4ceac169 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_webagg_core.py @@ -0,0 +1,517 @@ +"""Displays Agg images in the browser, with interactivity.""" +# The WebAgg backend is divided into two modules: +# +# - `backend_webagg_core.py` contains code necessary to embed a WebAgg +# plot inside of a web application, and communicate in an abstract +# way over a web socket. +# +# - `backend_webagg.py` contains a concrete implementation of a basic +# application, implemented with asyncio. + +import asyncio +import datetime +from io import BytesIO, StringIO +import json +import logging +import os +from pathlib import Path + +import numpy as np +from PIL import Image + +from matplotlib import _api, backend_bases, backend_tools +from matplotlib.backends import backend_agg +from matplotlib.backend_bases import ( + _Backend, KeyEvent, LocationEvent, MouseEvent, ResizeEvent) + +_log = logging.getLogger(__name__) + +_SPECIAL_KEYS_LUT = {'Alt': 'alt', + 'AltGraph': 'alt', + 'CapsLock': 'caps_lock', + 'Control': 'control', + 'Meta': 'meta', + 'NumLock': 'num_lock', + 'ScrollLock': 'scroll_lock', + 'Shift': 'shift', + 'Super': 'super', + 'Enter': 'enter', + 'Tab': 'tab', + 'ArrowDown': 'down', + 'ArrowLeft': 'left', + 'ArrowRight': 'right', + 'ArrowUp': 'up', + 'End': 'end', + 'Home': 'home', + 'PageDown': 'pagedown', + 'PageUp': 'pageup', + 'Backspace': 'backspace', + 'Delete': 'delete', + 'Insert': 'insert', + 'Escape': 'escape', + 'Pause': 'pause', + 'Select': 'select', + 'Dead': 'dead', + 'F1': 'f1', + 'F2': 'f2', + 'F3': 'f3', + 'F4': 'f4', + 'F5': 'f5', + 'F6': 'f6', + 'F7': 'f7', + 'F8': 'f8', + 'F9': 'f9', + 'F10': 'f10', + 'F11': 'f11', + 'F12': 'f12'} + + +def _handle_key(key): + """Handle key values""" + value = key[key.index('k') + 1:] + if 'shift+' in key: + if len(value) == 1: + key = key.replace('shift+', '') + if value in _SPECIAL_KEYS_LUT: + value = _SPECIAL_KEYS_LUT[value] + key = key[:key.index('k')] + value + return key + + +class TimerTornado(backend_bases.TimerBase): + def __init__(self, *args, **kwargs): + self._timer = None + super().__init__(*args, **kwargs) + + def _timer_start(self): + import tornado + + self._timer_stop() + if self._single: + ioloop = tornado.ioloop.IOLoop.instance() + self._timer = ioloop.add_timeout( + datetime.timedelta(milliseconds=self.interval), + self._on_timer) + else: + self._timer = tornado.ioloop.PeriodicCallback( + self._on_timer, + max(self.interval, 1e-6)) + self._timer.start() + + def _timer_stop(self): + import tornado + + if self._timer is None: + return + elif self._single: + ioloop = tornado.ioloop.IOLoop.instance() + ioloop.remove_timeout(self._timer) + else: + self._timer.stop() + self._timer = None + + def _timer_set_interval(self): + # Only stop and restart it if the timer has already been started + if self._timer is not None: + self._timer_stop() + self._timer_start() + + +class TimerAsyncio(backend_bases.TimerBase): + def __init__(self, *args, **kwargs): + self._task = None + super().__init__(*args, **kwargs) + + async def _timer_task(self, interval): + while True: + try: + await asyncio.sleep(interval) + self._on_timer() + + if self._single: + break + except asyncio.CancelledError: + break + + def _timer_start(self): + self._timer_stop() + + self._task = asyncio.ensure_future( + self._timer_task(max(self.interval / 1_000., 1e-6)) + ) + + def _timer_stop(self): + if self._task is not None: + self._task.cancel() + self._task = None + + def _timer_set_interval(self): + # Only stop and restart it if the timer has already been started + if self._task is not None: + self._timer_stop() + self._timer_start() + + +class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg): + manager_class = _api.classproperty(lambda cls: FigureManagerWebAgg) + _timer_cls = TimerAsyncio + # Webagg and friends having the right methods, but still + # having bugs in practice. Do not advertise that it works until + # we can debug this. + supports_blit = False + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # Set to True when the renderer contains data that is newer + # than the PNG buffer. + self._png_is_old = True + # Set to True by the `refresh` message so that the next frame + # sent to the clients will be a full frame. + self._force_full = True + # The last buffer, for diff mode. + self._last_buff = np.empty((0, 0)) + # Store the current image mode so that at any point, clients can + # request the information. This should be changed by calling + # self.set_image_mode(mode) so that the notification can be given + # to the connected clients. + self._current_image_mode = 'full' + # Track mouse events to fill in the x, y position of key events. + self._last_mouse_xy = (None, None) + + def show(self): + # show the figure window + from matplotlib.pyplot import show + show() + + def draw(self): + self._png_is_old = True + try: + super().draw() + finally: + self.manager.refresh_all() # Swap the frames. + + def blit(self, bbox=None): + self._png_is_old = True + self.manager.refresh_all() + + def draw_idle(self): + self.send_event("draw") + + def set_cursor(self, cursor): + # docstring inherited + cursor = _api.check_getitem({ + backend_tools.Cursors.HAND: 'pointer', + backend_tools.Cursors.POINTER: 'default', + backend_tools.Cursors.SELECT_REGION: 'crosshair', + backend_tools.Cursors.MOVE: 'move', + backend_tools.Cursors.WAIT: 'wait', + backend_tools.Cursors.RESIZE_HORIZONTAL: 'ew-resize', + backend_tools.Cursors.RESIZE_VERTICAL: 'ns-resize', + }, cursor=cursor) + self.send_event('cursor', cursor=cursor) + + def set_image_mode(self, mode): + """ + Set the image mode for any subsequent images which will be sent + to the clients. The modes may currently be either 'full' or 'diff'. + + Note: diff images may not contain transparency, therefore upon + draw this mode may be changed if the resulting image has any + transparent component. + """ + _api.check_in_list(['full', 'diff'], mode=mode) + if self._current_image_mode != mode: + self._current_image_mode = mode + self.handle_send_image_mode(None) + + def get_diff_image(self): + if self._png_is_old: + renderer = self.get_renderer() + + pixels = np.asarray(renderer.buffer_rgba()) + # The buffer is created as type uint32 so that entire + # pixels can be compared in one numpy call, rather than + # needing to compare each plane separately. + buff = pixels.view(np.uint32).squeeze(2) + + if (self._force_full + # If the buffer has changed size we need to do a full draw. + or buff.shape != self._last_buff.shape + # If any pixels have transparency, we need to force a full + # draw as we cannot overlay new on top of old. + or (pixels[:, :, 3] != 255).any()): + self.set_image_mode('full') + output = buff + else: + self.set_image_mode('diff') + diff = buff != self._last_buff + output = np.where(diff, buff, 0) + + # Store the current buffer so we can compute the next diff. + self._last_buff = buff.copy() + self._force_full = False + self._png_is_old = False + + data = output.view(dtype=np.uint8).reshape((*output.shape, 4)) + with BytesIO() as png: + Image.fromarray(data).save(png, format="png") + return png.getvalue() + + def handle_event(self, event): + e_type = event['type'] + handler = getattr(self, f'handle_{e_type}', + self.handle_unknown_event) + return handler(event) + + def handle_unknown_event(self, event): + _log.warning('Unhandled message type %s. %s', event["type"], event) + + def handle_ack(self, event): + # Network latency tends to decrease if traffic is flowing + # in both directions. Therefore, the browser sends back + # an "ack" message after each image frame is received. + # This could also be used as a simple sanity check in the + # future, but for now the performance increase is enough + # to justify it, even if the server does nothing with it. + pass + + def handle_draw(self, event): + self.draw() + + def _handle_mouse(self, event): + x = event['x'] + y = event['y'] + y = self.get_renderer().height - y + self._last_mouse_xy = x, y + # JavaScript button numbers and Matplotlib button numbers are off by 1. + button = event['button'] + 1 + + e_type = event['type'] + modifiers = event['modifiers'] + guiEvent = event.get('guiEvent') + if e_type in ['button_press', 'button_release']: + MouseEvent(e_type + '_event', self, x, y, button, + modifiers=modifiers, guiEvent=guiEvent)._process() + elif e_type == 'dblclick': + MouseEvent('button_press_event', self, x, y, button, dblclick=True, + modifiers=modifiers, guiEvent=guiEvent)._process() + elif e_type == 'scroll': + MouseEvent('scroll_event', self, x, y, step=event['step'], + modifiers=modifiers, guiEvent=guiEvent)._process() + elif e_type == 'motion_notify': + MouseEvent(e_type + '_event', self, x, y, + modifiers=modifiers, guiEvent=guiEvent)._process() + elif e_type in ['figure_enter', 'figure_leave']: + LocationEvent(e_type + '_event', self, x, y, + modifiers=modifiers, guiEvent=guiEvent)._process() + handle_button_press = handle_button_release = handle_dblclick = \ + handle_figure_enter = handle_figure_leave = handle_motion_notify = \ + handle_scroll = _handle_mouse + + def _handle_key(self, event): + KeyEvent(event['type'] + '_event', self, + _handle_key(event['key']), *self._last_mouse_xy, + guiEvent=event.get('guiEvent'))._process() + handle_key_press = handle_key_release = _handle_key + + def handle_toolbar_button(self, event): + # TODO: Be more suspicious of the input + getattr(self.toolbar, event['name'])() + + def handle_refresh(self, event): + figure_label = self.figure.get_label() + if not figure_label: + figure_label = f"Figure {self.manager.num}" + self.send_event('figure_label', label=figure_label) + self._force_full = True + if self.toolbar: + # Normal toolbar init would refresh this, but it happens before the + # browser canvas is set up. + self.toolbar.set_history_buttons() + self.draw_idle() + + def handle_resize(self, event): + x = int(event.get('width', 800)) * self.device_pixel_ratio + y = int(event.get('height', 800)) * self.device_pixel_ratio + fig = self.figure + # An attempt at approximating the figure size in pixels. + fig.set_size_inches(x / fig.dpi, y / fig.dpi, forward=False) + # Acknowledge the resize, and force the viewer to update the + # canvas size to the figure's new size (which is hopefully + # identical or within a pixel or so). + self._png_is_old = True + self.manager.resize(*fig.bbox.size, forward=False) + ResizeEvent('resize_event', self)._process() + self.draw_idle() + + def handle_send_image_mode(self, event): + # The client requests notification of what the current image mode is. + self.send_event('image_mode', mode=self._current_image_mode) + + def handle_set_device_pixel_ratio(self, event): + self._handle_set_device_pixel_ratio(event.get('device_pixel_ratio', 1)) + + def handle_set_dpi_ratio(self, event): + # This handler is for backwards-compatibility with older ipympl. + self._handle_set_device_pixel_ratio(event.get('dpi_ratio', 1)) + + def _handle_set_device_pixel_ratio(self, device_pixel_ratio): + if self._set_device_pixel_ratio(device_pixel_ratio): + self._force_full = True + self.draw_idle() + + def send_event(self, event_type, **kwargs): + if self.manager: + self.manager._send_event(event_type, **kwargs) + + +_ALLOWED_TOOL_ITEMS = { + 'home', + 'back', + 'forward', + 'pan', + 'zoom', + 'download', + None, +} + + +class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2): + + # Use the standard toolbar items + download button + toolitems = [ + (text, tooltip_text, image_file, name_of_method) + for text, tooltip_text, image_file, name_of_method + in (*backend_bases.NavigationToolbar2.toolitems, + ('Download', 'Download plot', 'filesave', 'download')) + if name_of_method in _ALLOWED_TOOL_ITEMS + ] + + def __init__(self, canvas): + self.message = '' + super().__init__(canvas) + + def set_message(self, message): + if message != self.message: + self.canvas.send_event("message", message=message) + self.message = message + + def draw_rubberband(self, event, x0, y0, x1, y1): + self.canvas.send_event("rubberband", x0=x0, y0=y0, x1=x1, y1=y1) + + def remove_rubberband(self): + self.canvas.send_event("rubberband", x0=-1, y0=-1, x1=-1, y1=-1) + + def save_figure(self, *args): + """Save the current figure""" + self.canvas.send_event('save') + + def pan(self): + super().pan() + self.canvas.send_event('navigate_mode', mode=self.mode.name) + + def zoom(self): + super().zoom() + self.canvas.send_event('navigate_mode', mode=self.mode.name) + + def set_history_buttons(self): + can_backward = self._nav_stack._pos > 0 + can_forward = self._nav_stack._pos < len(self._nav_stack) - 1 + self.canvas.send_event('history_buttons', + Back=can_backward, Forward=can_forward) + + +class FigureManagerWebAgg(backend_bases.FigureManagerBase): + # This must be None to not break ipympl + _toolbar2_class = None + ToolbarCls = NavigationToolbar2WebAgg + _window_title = "Matplotlib" + + def __init__(self, canvas, num): + self.web_sockets = set() + super().__init__(canvas, num) + + def show(self): + pass + + def resize(self, w, h, forward=True): + self._send_event( + 'resize', + size=(w / self.canvas.device_pixel_ratio, + h / self.canvas.device_pixel_ratio), + forward=forward) + + def set_window_title(self, title): + self._send_event('figure_label', label=title) + self._window_title = title + + def get_window_title(self): + return self._window_title + + # The following methods are specific to FigureManagerWebAgg + + def add_web_socket(self, web_socket): + assert hasattr(web_socket, 'send_binary') + assert hasattr(web_socket, 'send_json') + self.web_sockets.add(web_socket) + self.resize(*self.canvas.figure.bbox.size) + self._send_event('refresh') + + def remove_web_socket(self, web_socket): + self.web_sockets.remove(web_socket) + + def handle_json(self, content): + self.canvas.handle_event(content) + + def refresh_all(self): + if self.web_sockets: + diff = self.canvas.get_diff_image() + if diff is not None: + for s in self.web_sockets: + s.send_binary(diff) + + @classmethod + def get_javascript(cls, stream=None): + if stream is None: + output = StringIO() + else: + output = stream + + output.write((Path(__file__).parent / "web_backend/js/mpl.js") + .read_text(encoding="utf-8")) + + toolitems = [] + for name, tooltip, image, method in cls.ToolbarCls.toolitems: + if name is None: + toolitems.append(['', '', '', '']) + else: + toolitems.append([name, tooltip, image, method]) + output.write(f"mpl.toolbar_items = {json.dumps(toolitems)};\n\n") + + extensions = [] + for filetype, ext in sorted(FigureCanvasWebAggCore. + get_supported_filetypes_grouped(). + items()): + extensions.append(ext[0]) + output.write(f"mpl.extensions = {json.dumps(extensions)};\n\n") + + output.write("mpl.default_extension = {};".format( + json.dumps(FigureCanvasWebAggCore.get_default_filetype()))) + + if stream is None: + return output.getvalue() + + @classmethod + def get_static_file_path(cls): + return os.path.join(os.path.dirname(__file__), 'web_backend') + + def _send_event(self, event_type, **kwargs): + payload = {'type': event_type, **kwargs} + for s in self.web_sockets: + s.send_json(payload) + + +@_Backend.export +class _BackendWebAggCoreAgg(_Backend): + FigureCanvas = FigureCanvasWebAggCore + FigureManager = FigureManagerWebAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wx.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wx.py new file mode 100644 index 00000000..218be894 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wx.py @@ -0,0 +1,1332 @@ +""" +A wxPython backend for matplotlib. + +Originally contributed by Jeremy O'Donoghue (jeremy@o-donoghue.com) and John +Hunter (jdhunter@ace.bsd.uchicago.edu). + +Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4. +""" + +import functools +import logging +import math +import pathlib +import sys +import weakref + +import numpy as np +import PIL.Image + +import matplotlib as mpl +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, + GraphicsContextBase, MouseButton, NavigationToolbar2, RendererBase, + TimerBase, ToolContainerBase, cursors, + CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent) + +from matplotlib import _api, cbook, backend_tools +from matplotlib._pylab_helpers import Gcf +from matplotlib.path import Path +from matplotlib.transforms import Affine2D + +import wx + +_log = logging.getLogger(__name__) + +# the True dots per inch on the screen; should be display dependent; see +# http://groups.google.com/d/msg/comp.lang.postscript/-/omHAc9FEuAsJ?hl=en +# for some info about screen dpi +PIXELS_PER_INCH = 75 + + +# lru_cache holds a reference to the App and prevents it from being gc'ed. +@functools.lru_cache(1) +def _create_wxapp(): + wxapp = wx.App(False) + wxapp.SetExitOnFrameDelete(True) + cbook._setup_new_guiapp() + return wxapp + + +class TimerWx(TimerBase): + """Subclass of `.TimerBase` using wx.Timer events.""" + + def __init__(self, *args, **kwargs): + self._timer = wx.Timer() + self._timer.Notify = self._on_timer + super().__init__(*args, **kwargs) + + def _timer_start(self): + self._timer.Start(self._interval, self._single) + + def _timer_stop(self): + self._timer.Stop() + + def _timer_set_interval(self): + if self._timer.IsRunning(): + self._timer_start() # Restart with new interval. + + +@_api.deprecated( + "2.0", name="wx", obj_type="backend", removal="the future", + alternative="wxagg", + addendum="See the Matplotlib usage FAQ for more info on backends.") +class RendererWx(RendererBase): + """ + The renderer handles all the drawing primitives using a graphics + context instance that controls the colors/styles. It acts as the + 'renderer' instance used by many classes in the hierarchy. + """ + # In wxPython, drawing is performed on a wxDC instance, which will + # generally be mapped to the client area of the window displaying + # the plot. Under wxPython, the wxDC instance has a wx.Pen which + # describes the colour and weight of any lines drawn, and a wxBrush + # which describes the fill colour of any closed polygon. + + # Font styles, families and weight. + fontweights = { + 100: wx.FONTWEIGHT_LIGHT, + 200: wx.FONTWEIGHT_LIGHT, + 300: wx.FONTWEIGHT_LIGHT, + 400: wx.FONTWEIGHT_NORMAL, + 500: wx.FONTWEIGHT_NORMAL, + 600: wx.FONTWEIGHT_NORMAL, + 700: wx.FONTWEIGHT_BOLD, + 800: wx.FONTWEIGHT_BOLD, + 900: wx.FONTWEIGHT_BOLD, + 'ultralight': wx.FONTWEIGHT_LIGHT, + 'light': wx.FONTWEIGHT_LIGHT, + 'normal': wx.FONTWEIGHT_NORMAL, + 'medium': wx.FONTWEIGHT_NORMAL, + 'semibold': wx.FONTWEIGHT_NORMAL, + 'bold': wx.FONTWEIGHT_BOLD, + 'heavy': wx.FONTWEIGHT_BOLD, + 'ultrabold': wx.FONTWEIGHT_BOLD, + 'black': wx.FONTWEIGHT_BOLD, + } + fontangles = { + 'italic': wx.FONTSTYLE_ITALIC, + 'normal': wx.FONTSTYLE_NORMAL, + 'oblique': wx.FONTSTYLE_SLANT, + } + + # wxPython allows for portable font styles, choosing them appropriately for + # the target platform. Map some standard font names to the portable styles. + # QUESTION: Is it wise to agree to standard fontnames across all backends? + fontnames = { + 'Sans': wx.FONTFAMILY_SWISS, + 'Roman': wx.FONTFAMILY_ROMAN, + 'Script': wx.FONTFAMILY_SCRIPT, + 'Decorative': wx.FONTFAMILY_DECORATIVE, + 'Modern': wx.FONTFAMILY_MODERN, + 'Courier': wx.FONTFAMILY_MODERN, + 'courier': wx.FONTFAMILY_MODERN, + } + + def __init__(self, bitmap, dpi): + """Initialise a wxWindows renderer instance.""" + super().__init__() + _log.debug("%s - __init__()", type(self)) + self.width = bitmap.GetWidth() + self.height = bitmap.GetHeight() + self.bitmap = bitmap + self.fontd = {} + self.dpi = dpi + self.gc = None + + def flipy(self): + # docstring inherited + return True + + def get_text_width_height_descent(self, s, prop, ismath): + # docstring inherited + + if ismath: + s = cbook.strip_math(s) + + if self.gc is None: + gc = self.new_gc() + else: + gc = self.gc + gfx_ctx = gc.gfx_ctx + font = self.get_wx_font(s, prop) + gfx_ctx.SetFont(font, wx.BLACK) + w, h, descent, leading = gfx_ctx.GetFullTextExtent(s) + + return w, h, descent + + def get_canvas_width_height(self): + # docstring inherited + return self.width, self.height + + def handle_clip_rectangle(self, gc): + new_bounds = gc.get_clip_rectangle() + if new_bounds is not None: + new_bounds = new_bounds.bounds + gfx_ctx = gc.gfx_ctx + if gfx_ctx._lastcliprect != new_bounds: + gfx_ctx._lastcliprect = new_bounds + if new_bounds is None: + gfx_ctx.ResetClip() + else: + gfx_ctx.Clip(new_bounds[0], + self.height - new_bounds[1] - new_bounds[3], + new_bounds[2], new_bounds[3]) + + @staticmethod + def convert_path(gfx_ctx, path, transform): + wxpath = gfx_ctx.CreatePath() + for points, code in path.iter_segments(transform): + if code == Path.MOVETO: + wxpath.MoveToPoint(*points) + elif code == Path.LINETO: + wxpath.AddLineToPoint(*points) + elif code == Path.CURVE3: + wxpath.AddQuadCurveToPoint(*points) + elif code == Path.CURVE4: + wxpath.AddCurveToPoint(*points) + elif code == Path.CLOSEPOLY: + wxpath.CloseSubpath() + return wxpath + + def draw_path(self, gc, path, transform, rgbFace=None): + # docstring inherited + gc.select() + self.handle_clip_rectangle(gc) + gfx_ctx = gc.gfx_ctx + transform = transform + \ + Affine2D().scale(1.0, -1.0).translate(0.0, self.height) + wxpath = self.convert_path(gfx_ctx, path, transform) + if rgbFace is not None: + gfx_ctx.SetBrush(wx.Brush(gc.get_wxcolour(rgbFace))) + gfx_ctx.DrawPath(wxpath) + else: + gfx_ctx.StrokePath(wxpath) + gc.unselect() + + def draw_image(self, gc, x, y, im): + bbox = gc.get_clip_rectangle() + if bbox is not None: + l, b, w, h = bbox.bounds + else: + l = 0 + b = 0 + w = self.width + h = self.height + rows, cols = im.shape[:2] + bitmap = wx.Bitmap.FromBufferRGBA(cols, rows, im.tobytes()) + gc.select() + gc.gfx_ctx.DrawBitmap(bitmap, int(l), int(self.height - b), + int(w), int(-h)) + gc.unselect() + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): + # docstring inherited + + if ismath: + s = cbook.strip_math(s) + _log.debug("%s - draw_text()", type(self)) + gc.select() + self.handle_clip_rectangle(gc) + gfx_ctx = gc.gfx_ctx + + font = self.get_wx_font(s, prop) + color = gc.get_wxcolour(gc.get_rgb()) + gfx_ctx.SetFont(font, color) + + w, h, d = self.get_text_width_height_descent(s, prop, ismath) + x = int(x) + y = int(y - h) + + if angle == 0.0: + gfx_ctx.DrawText(s, x, y) + else: + rads = math.radians(angle) + xo = h * math.sin(rads) + yo = h * math.cos(rads) + gfx_ctx.DrawRotatedText(s, x - xo, y - yo, rads) + + gc.unselect() + + def new_gc(self): + # docstring inherited + _log.debug("%s - new_gc()", type(self)) + self.gc = GraphicsContextWx(self.bitmap, self) + self.gc.select() + self.gc.unselect() + return self.gc + + def get_wx_font(self, s, prop): + """Return a wx font. Cache font instances for efficiency.""" + _log.debug("%s - get_wx_font()", type(self)) + key = hash(prop) + font = self.fontd.get(key) + if font is not None: + return font + size = self.points_to_pixels(prop.get_size_in_points()) + # Font colour is determined by the active wx.Pen + # TODO: It may be wise to cache font information + self.fontd[key] = font = wx.Font( # Cache the font and gc. + pointSize=round(size), + family=self.fontnames.get(prop.get_name(), wx.ROMAN), + style=self.fontangles[prop.get_style()], + weight=self.fontweights[prop.get_weight()]) + return font + + def points_to_pixels(self, points): + # docstring inherited + return points * (PIXELS_PER_INCH / 72.0 * self.dpi / 72.0) + + +class GraphicsContextWx(GraphicsContextBase): + """ + The graphics context provides the color, line styles, etc. + + This class stores a reference to a wxMemoryDC, and a + wxGraphicsContext that draws to it. Creating a wxGraphicsContext + seems to be fairly heavy, so these objects are cached based on the + bitmap object that is passed in. + + The base GraphicsContext stores colors as an RGB tuple on the unit + interval, e.g., (0.5, 0.0, 1.0). wxPython uses an int interval, but + since wxPython colour management is rather simple, I have not chosen + to implement a separate colour manager class. + """ + _capd = {'butt': wx.CAP_BUTT, + 'projecting': wx.CAP_PROJECTING, + 'round': wx.CAP_ROUND} + + _joind = {'bevel': wx.JOIN_BEVEL, + 'miter': wx.JOIN_MITER, + 'round': wx.JOIN_ROUND} + + _cache = weakref.WeakKeyDictionary() + + def __init__(self, bitmap, renderer): + super().__init__() + # assert self.Ok(), "wxMemoryDC not OK to use" + _log.debug("%s - __init__(): %s", type(self), bitmap) + + dc, gfx_ctx = self._cache.get(bitmap, (None, None)) + if dc is None: + dc = wx.MemoryDC(bitmap) + gfx_ctx = wx.GraphicsContext.Create(dc) + gfx_ctx._lastcliprect = None + self._cache[bitmap] = dc, gfx_ctx + + self.bitmap = bitmap + self.dc = dc + self.gfx_ctx = gfx_ctx + self._pen = wx.Pen('BLACK', 1, wx.SOLID) + gfx_ctx.SetPen(self._pen) + self.renderer = renderer + + def select(self): + """Select the current bitmap into this wxDC instance.""" + if sys.platform == 'win32': + self.dc.SelectObject(self.bitmap) + self.IsSelected = True + + def unselect(self): + """Select a Null bitmap into this wxDC instance.""" + if sys.platform == 'win32': + self.dc.SelectObject(wx.NullBitmap) + self.IsSelected = False + + def set_foreground(self, fg, isRGBA=None): + # docstring inherited + # Implementation note: wxPython has a separate concept of pen and + # brush - the brush fills any outline trace left by the pen. + # Here we set both to the same colour - if a figure is not to be + # filled, the renderer will set the brush to be transparent + # Same goes for text foreground... + _log.debug("%s - set_foreground()", type(self)) + self.select() + super().set_foreground(fg, isRGBA) + + self._pen.SetColour(self.get_wxcolour(self.get_rgb())) + self.gfx_ctx.SetPen(self._pen) + self.unselect() + + def set_linewidth(self, w): + # docstring inherited + w = float(w) + _log.debug("%s - set_linewidth()", type(self)) + self.select() + if 0 < w < 1: + w = 1 + super().set_linewidth(w) + lw = int(self.renderer.points_to_pixels(self._linewidth)) + if lw == 0: + lw = 1 + self._pen.SetWidth(lw) + self.gfx_ctx.SetPen(self._pen) + self.unselect() + + def set_capstyle(self, cs): + # docstring inherited + _log.debug("%s - set_capstyle()", type(self)) + self.select() + super().set_capstyle(cs) + self._pen.SetCap(GraphicsContextWx._capd[self._capstyle]) + self.gfx_ctx.SetPen(self._pen) + self.unselect() + + def set_joinstyle(self, js): + # docstring inherited + _log.debug("%s - set_joinstyle()", type(self)) + self.select() + super().set_joinstyle(js) + self._pen.SetJoin(GraphicsContextWx._joind[self._joinstyle]) + self.gfx_ctx.SetPen(self._pen) + self.unselect() + + def get_wxcolour(self, color): + """Convert an RGB(A) color to a wx.Colour.""" + _log.debug("%s - get_wx_color()", type(self)) + return wx.Colour(*[int(255 * x) for x in color]) + + +class _FigureCanvasWxBase(FigureCanvasBase, wx.Panel): + """ + The FigureCanvas contains the figure and does event handling. + + In the wxPython backend, it is derived from wxPanel, and (usually) lives + inside a frame instantiated by a FigureManagerWx. The parent window + probably implements a wx.Sizer to control the displayed control size - but + we give a hint as to our preferred minimum size. + """ + + required_interactive_framework = "wx" + _timer_cls = TimerWx + manager_class = _api.classproperty(lambda cls: FigureManagerWx) + + keyvald = { + wx.WXK_CONTROL: 'control', + wx.WXK_SHIFT: 'shift', + wx.WXK_ALT: 'alt', + wx.WXK_CAPITAL: 'caps_lock', + wx.WXK_LEFT: 'left', + wx.WXK_UP: 'up', + wx.WXK_RIGHT: 'right', + wx.WXK_DOWN: 'down', + wx.WXK_ESCAPE: 'escape', + wx.WXK_F1: 'f1', + wx.WXK_F2: 'f2', + wx.WXK_F3: 'f3', + wx.WXK_F4: 'f4', + wx.WXK_F5: 'f5', + wx.WXK_F6: 'f6', + wx.WXK_F7: 'f7', + wx.WXK_F8: 'f8', + wx.WXK_F9: 'f9', + wx.WXK_F10: 'f10', + wx.WXK_F11: 'f11', + wx.WXK_F12: 'f12', + wx.WXK_SCROLL: 'scroll_lock', + wx.WXK_PAUSE: 'break', + wx.WXK_BACK: 'backspace', + wx.WXK_RETURN: 'enter', + wx.WXK_INSERT: 'insert', + wx.WXK_DELETE: 'delete', + wx.WXK_HOME: 'home', + wx.WXK_END: 'end', + wx.WXK_PAGEUP: 'pageup', + wx.WXK_PAGEDOWN: 'pagedown', + wx.WXK_NUMPAD0: '0', + wx.WXK_NUMPAD1: '1', + wx.WXK_NUMPAD2: '2', + wx.WXK_NUMPAD3: '3', + wx.WXK_NUMPAD4: '4', + wx.WXK_NUMPAD5: '5', + wx.WXK_NUMPAD6: '6', + wx.WXK_NUMPAD7: '7', + wx.WXK_NUMPAD8: '8', + wx.WXK_NUMPAD9: '9', + wx.WXK_NUMPAD_ADD: '+', + wx.WXK_NUMPAD_SUBTRACT: '-', + wx.WXK_NUMPAD_MULTIPLY: '*', + wx.WXK_NUMPAD_DIVIDE: '/', + wx.WXK_NUMPAD_DECIMAL: 'dec', + wx.WXK_NUMPAD_ENTER: 'enter', + wx.WXK_NUMPAD_UP: 'up', + wx.WXK_NUMPAD_RIGHT: 'right', + wx.WXK_NUMPAD_DOWN: 'down', + wx.WXK_NUMPAD_LEFT: 'left', + wx.WXK_NUMPAD_PAGEUP: 'pageup', + wx.WXK_NUMPAD_PAGEDOWN: 'pagedown', + wx.WXK_NUMPAD_HOME: 'home', + wx.WXK_NUMPAD_END: 'end', + wx.WXK_NUMPAD_INSERT: 'insert', + wx.WXK_NUMPAD_DELETE: 'delete', + } + + def __init__(self, parent, id, figure=None): + """ + Initialize a FigureWx instance. + + - Initialize the FigureCanvasBase and wxPanel parents. + - Set event handlers for resize, paint, and keyboard and mouse + interaction. + """ + + FigureCanvasBase.__init__(self, figure) + w, h = map(math.ceil, self.figure.bbox.size) + # Set preferred window size hint - helps the sizer, if one is connected + wx.Panel.__init__(self, parent, id, size=wx.Size(w, h)) + # Create the drawing bitmap + self.bitmap = wx.Bitmap(w, h) + _log.debug("%s - __init__() - bitmap w:%d h:%d", type(self), w, h) + self._isDrawn = False + self._rubberband_rect = None + self._rubberband_pen_black = wx.Pen('BLACK', 1, wx.PENSTYLE_SHORT_DASH) + self._rubberband_pen_white = wx.Pen('WHITE', 1, wx.PENSTYLE_SOLID) + + self.Bind(wx.EVT_SIZE, self._on_size) + self.Bind(wx.EVT_PAINT, self._on_paint) + self.Bind(wx.EVT_CHAR_HOOK, self._on_key_down) + self.Bind(wx.EVT_KEY_UP, self._on_key_up) + self.Bind(wx.EVT_LEFT_DOWN, self._on_mouse_button) + self.Bind(wx.EVT_LEFT_DCLICK, self._on_mouse_button) + self.Bind(wx.EVT_LEFT_UP, self._on_mouse_button) + self.Bind(wx.EVT_MIDDLE_DOWN, self._on_mouse_button) + self.Bind(wx.EVT_MIDDLE_DCLICK, self._on_mouse_button) + self.Bind(wx.EVT_MIDDLE_UP, self._on_mouse_button) + self.Bind(wx.EVT_RIGHT_DOWN, self._on_mouse_button) + self.Bind(wx.EVT_RIGHT_DCLICK, self._on_mouse_button) + self.Bind(wx.EVT_RIGHT_UP, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX1_DOWN, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX1_UP, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX2_DOWN, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX2_UP, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX1_DCLICK, self._on_mouse_button) + self.Bind(wx.EVT_MOUSE_AUX2_DCLICK, self._on_mouse_button) + self.Bind(wx.EVT_MOUSEWHEEL, self._on_mouse_wheel) + self.Bind(wx.EVT_MOTION, self._on_motion) + self.Bind(wx.EVT_ENTER_WINDOW, self._on_enter) + self.Bind(wx.EVT_LEAVE_WINDOW, self._on_leave) + + self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self._on_capture_lost) + self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self._on_capture_lost) + + self.SetBackgroundStyle(wx.BG_STYLE_PAINT) # Reduce flicker. + self.SetBackgroundColour(wx.WHITE) + + def Copy_to_Clipboard(self, event=None): + """Copy bitmap of canvas to system clipboard.""" + bmp_obj = wx.BitmapDataObject() + bmp_obj.SetBitmap(self.bitmap) + + if not wx.TheClipboard.IsOpened(): + open_success = wx.TheClipboard.Open() + if open_success: + wx.TheClipboard.SetData(bmp_obj) + wx.TheClipboard.Flush() + wx.TheClipboard.Close() + + def draw_idle(self): + # docstring inherited + _log.debug("%s - draw_idle()", type(self)) + self._isDrawn = False # Force redraw + # Triggering a paint event is all that is needed to defer drawing + # until later. The platform will send the event when it thinks it is + # a good time (usually as soon as there are no other events pending). + self.Refresh(eraseBackground=False) + + def flush_events(self): + # docstring inherited + wx.Yield() + + def start_event_loop(self, timeout=0): + # docstring inherited + if hasattr(self, '_event_loop'): + raise RuntimeError("Event loop already running") + timer = wx.Timer(self, id=wx.ID_ANY) + if timeout > 0: + timer.Start(int(timeout * 1000), oneShot=True) + self.Bind(wx.EVT_TIMER, self.stop_event_loop, id=timer.GetId()) + # Event loop handler for start/stop event loop + self._event_loop = wx.GUIEventLoop() + self._event_loop.Run() + timer.Stop() + + def stop_event_loop(self, event=None): + # docstring inherited + if hasattr(self, '_event_loop'): + if self._event_loop.IsRunning(): + self._event_loop.Exit() + del self._event_loop + + def _get_imagesave_wildcards(self): + """Return the wildcard string for the filesave dialog.""" + default_filetype = self.get_default_filetype() + filetypes = self.get_supported_filetypes_grouped() + sorted_filetypes = sorted(filetypes.items()) + wildcards = [] + extensions = [] + filter_index = 0 + for i, (name, exts) in enumerate(sorted_filetypes): + ext_list = ';'.join(['*.%s' % ext for ext in exts]) + extensions.append(exts[0]) + wildcard = f'{name} ({ext_list})|{ext_list}' + if default_filetype in exts: + filter_index = i + wildcards.append(wildcard) + wildcards = '|'.join(wildcards) + return wildcards, extensions, filter_index + + def gui_repaint(self, drawDC=None): + """ + Update the displayed image on the GUI canvas, using the supplied + wx.PaintDC device context. + """ + _log.debug("%s - gui_repaint()", type(self)) + # The "if self" check avoids a "wrapped C/C++ object has been deleted" + # RuntimeError if doing things after window is closed. + if not (self and self.IsShownOnScreen()): + return + if not drawDC: # not called from OnPaint use a ClientDC + drawDC = wx.ClientDC(self) + # For 'WX' backend on Windows, the bitmap cannot be in use by another + # DC (see GraphicsContextWx._cache). + bmp = (self.bitmap.ConvertToImage().ConvertToBitmap() + if wx.Platform == '__WXMSW__' + and isinstance(self.figure.canvas.get_renderer(), RendererWx) + else self.bitmap) + drawDC.DrawBitmap(bmp, 0, 0) + if self._rubberband_rect is not None: + # Some versions of wx+python don't support numpy.float64 here. + x0, y0, x1, y1 = map(round, self._rubberband_rect) + rect = [(x0, y0, x1, y0), (x1, y0, x1, y1), + (x0, y0, x0, y1), (x0, y1, x1, y1)] + drawDC.DrawLineList(rect, self._rubberband_pen_white) + drawDC.DrawLineList(rect, self._rubberband_pen_black) + + filetypes = { + **FigureCanvasBase.filetypes, + 'bmp': 'Windows bitmap', + 'jpeg': 'JPEG', + 'jpg': 'JPEG', + 'pcx': 'PCX', + 'png': 'Portable Network Graphics', + 'tif': 'Tagged Image Format File', + 'tiff': 'Tagged Image Format File', + 'xpm': 'X pixmap', + } + + def _on_paint(self, event): + """Called when wxPaintEvt is generated.""" + _log.debug("%s - _on_paint()", type(self)) + drawDC = wx.PaintDC(self) + if not self._isDrawn: + self.draw(drawDC=drawDC) + else: + self.gui_repaint(drawDC=drawDC) + drawDC.Destroy() + + def _on_size(self, event): + """ + Called when wxEventSize is generated. + + In this application we attempt to resize to fit the window, so it + is better to take the performance hit and redraw the whole window. + """ + + _log.debug("%s - _on_size()", type(self)) + sz = self.GetParent().GetSizer() + if sz: + si = sz.GetItem(self) + if sz and si and not si.Proportion and not si.Flag & wx.EXPAND: + # managed by a sizer, but with a fixed size + size = self.GetMinSize() + else: + # variable size + size = self.GetClientSize() + # Do not allow size to become smaller than MinSize + size.IncTo(self.GetMinSize()) + if getattr(self, "_width", None): + if size == (self._width, self._height): + # no change in size + return + self._width, self._height = size + self._isDrawn = False + + if self._width <= 1 or self._height <= 1: + return # Empty figure + + # Create a new, correctly sized bitmap + self.bitmap = wx.Bitmap(self._width, self._height) + + dpival = self.figure.dpi + winch = self._width / dpival + hinch = self._height / dpival + self.figure.set_size_inches(winch, hinch, forward=False) + + # Rendering will happen on the associated paint event + # so no need to do anything here except to make sure + # the whole background is repainted. + self.Refresh(eraseBackground=False) + ResizeEvent("resize_event", self)._process() + self.draw_idle() + + @staticmethod + def _mpl_modifiers(event=None, *, exclude=None): + mod_table = [ + ("ctrl", wx.MOD_CONTROL, wx.WXK_CONTROL), + ("alt", wx.MOD_ALT, wx.WXK_ALT), + ("shift", wx.MOD_SHIFT, wx.WXK_SHIFT), + ] + if event is not None: + modifiers = event.GetModifiers() + return [name for name, mod, key in mod_table + if modifiers & mod and exclude != key] + else: + return [name for name, mod, key in mod_table + if wx.GetKeyState(key)] + + def _get_key(self, event): + keyval = event.KeyCode + if keyval in self.keyvald: + key = self.keyvald[keyval] + elif keyval < 256: + key = chr(keyval) + # wx always returns an uppercase, so make it lowercase if the shift + # key is not depressed (NOTE: this will not handle Caps Lock) + if not event.ShiftDown(): + key = key.lower() + else: + return None + mods = self._mpl_modifiers(event, exclude=keyval) + if "shift" in mods and key.isupper(): + mods.remove("shift") + return "+".join([*mods, key]) + + def _mpl_coords(self, pos=None): + """ + Convert a wx position, defaulting to the current cursor position, to + Matplotlib coordinates. + """ + if pos is None: + pos = wx.GetMouseState() + x, y = self.ScreenToClient(pos.X, pos.Y) + else: + x, y = pos.X, pos.Y + # flip y so y=0 is bottom of canvas + return x, self.figure.bbox.height - y + + def _on_key_down(self, event): + """Capture key press.""" + KeyEvent("key_press_event", self, + self._get_key(event), *self._mpl_coords(), + guiEvent=event)._process() + if self: + event.Skip() + + def _on_key_up(self, event): + """Release key.""" + KeyEvent("key_release_event", self, + self._get_key(event), *self._mpl_coords(), + guiEvent=event)._process() + if self: + event.Skip() + + def set_cursor(self, cursor): + # docstring inherited + cursor = wx.Cursor(_api.check_getitem({ + cursors.MOVE: wx.CURSOR_HAND, + cursors.HAND: wx.CURSOR_HAND, + cursors.POINTER: wx.CURSOR_ARROW, + cursors.SELECT_REGION: wx.CURSOR_CROSS, + cursors.WAIT: wx.CURSOR_WAIT, + cursors.RESIZE_HORIZONTAL: wx.CURSOR_SIZEWE, + cursors.RESIZE_VERTICAL: wx.CURSOR_SIZENS, + }, cursor=cursor)) + self.SetCursor(cursor) + self.Refresh() + + def _set_capture(self, capture=True): + """Control wx mouse capture.""" + if self.HasCapture(): + self.ReleaseMouse() + if capture: + self.CaptureMouse() + + def _on_capture_lost(self, event): + """Capture changed or lost""" + self._set_capture(False) + + def _on_mouse_button(self, event): + """Start measuring on an axis.""" + event.Skip() + self._set_capture(event.ButtonDown() or event.ButtonDClick()) + x, y = self._mpl_coords(event) + button_map = { + wx.MOUSE_BTN_LEFT: MouseButton.LEFT, + wx.MOUSE_BTN_MIDDLE: MouseButton.MIDDLE, + wx.MOUSE_BTN_RIGHT: MouseButton.RIGHT, + wx.MOUSE_BTN_AUX1: MouseButton.BACK, + wx.MOUSE_BTN_AUX2: MouseButton.FORWARD, + } + button = event.GetButton() + button = button_map.get(button, button) + modifiers = self._mpl_modifiers(event) + if event.ButtonDown(): + MouseEvent("button_press_event", self, x, y, button, + modifiers=modifiers, guiEvent=event)._process() + elif event.ButtonDClick(): + MouseEvent("button_press_event", self, x, y, button, + dblclick=True, modifiers=modifiers, + guiEvent=event)._process() + elif event.ButtonUp(): + MouseEvent("button_release_event", self, x, y, button, + modifiers=modifiers, guiEvent=event)._process() + + def _on_mouse_wheel(self, event): + """Translate mouse wheel events into matplotlib events""" + x, y = self._mpl_coords(event) + # Convert delta/rotation/rate into a floating point step size + step = event.LinesPerAction * event.WheelRotation / event.WheelDelta + # Done handling event + event.Skip() + # Mac gives two events for every wheel event; skip every second one. + if wx.Platform == '__WXMAC__': + if not hasattr(self, '_skipwheelevent'): + self._skipwheelevent = True + elif self._skipwheelevent: + self._skipwheelevent = False + return # Return without processing event + else: + self._skipwheelevent = True + MouseEvent("scroll_event", self, x, y, step=step, + modifiers=self._mpl_modifiers(event), + guiEvent=event)._process() + + def _on_motion(self, event): + """Start measuring on an axis.""" + event.Skip() + MouseEvent("motion_notify_event", self, + *self._mpl_coords(event), + modifiers=self._mpl_modifiers(event), + guiEvent=event)._process() + + def _on_enter(self, event): + """Mouse has entered the window.""" + event.Skip() + LocationEvent("figure_enter_event", self, + *self._mpl_coords(event), + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + def _on_leave(self, event): + """Mouse has left the window.""" + event.Skip() + LocationEvent("figure_leave_event", self, + *self._mpl_coords(event), + modifiers=self._mpl_modifiers(), + guiEvent=event)._process() + + +class FigureCanvasWx(_FigureCanvasWxBase): + # Rendering to a Wx canvas using the deprecated Wx renderer. + + def draw(self, drawDC=None): + """ + Render the figure using RendererWx instance renderer, or using a + previously defined renderer if none is specified. + """ + _log.debug("%s - draw()", type(self)) + self.renderer = RendererWx(self.bitmap, self.figure.dpi) + self.figure.draw(self.renderer) + self._isDrawn = True + self.gui_repaint(drawDC=drawDC) + + def _print_image(self, filetype, filename): + bitmap = wx.Bitmap(math.ceil(self.figure.bbox.width), + math.ceil(self.figure.bbox.height)) + self.figure.draw(RendererWx(bitmap, self.figure.dpi)) + saved_obj = (bitmap.ConvertToImage() + if cbook.is_writable_file_like(filename) + else bitmap) + if not saved_obj.SaveFile(filename, filetype): + raise RuntimeError(f'Could not save figure to {filename}') + # draw() is required here since bits of state about the last renderer + # are strewn about the artist draw methods. Do not remove the draw + # without first verifying that these have been cleaned up. The artist + # contains() methods will fail otherwise. + if self._isDrawn: + self.draw() + # The "if self" check avoids a "wrapped C/C++ object has been deleted" + # RuntimeError if doing things after window is closed. + if self: + self.Refresh() + + print_bmp = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_BMP) + print_jpeg = print_jpg = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_JPEG) + print_pcx = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_PCX) + print_png = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_PNG) + print_tiff = print_tif = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_TIF) + print_xpm = functools.partialmethod( + _print_image, wx.BITMAP_TYPE_XPM) + + +class FigureFrameWx(wx.Frame): + def __init__(self, num, fig, *, canvas_class): + # On non-Windows platform, explicitly set the position - fix + # positioning bug on some Linux platforms + if wx.Platform == '__WXMSW__': + pos = wx.DefaultPosition + else: + pos = wx.Point(20, 20) + super().__init__(parent=None, id=-1, pos=pos) + # Frame will be sized later by the Fit method + _log.debug("%s - __init__()", type(self)) + _set_frame_icon(self) + + self.canvas = canvas_class(self, -1, fig) + # Auto-attaches itself to self.canvas.manager + manager = FigureManagerWx(self.canvas, num, self) + + toolbar = self.canvas.manager.toolbar + if toolbar is not None: + self.SetToolBar(toolbar) + + # On Windows, canvas sizing must occur after toolbar addition; + # otherwise the toolbar further resizes the canvas. + w, h = map(math.ceil, fig.bbox.size) + self.canvas.SetInitialSize(wx.Size(w, h)) + self.canvas.SetMinSize((2, 2)) + self.canvas.SetFocus() + + self.Fit() + + self.Bind(wx.EVT_CLOSE, self._on_close) + + def _on_close(self, event): + _log.debug("%s - on_close()", type(self)) + CloseEvent("close_event", self.canvas)._process() + self.canvas.stop_event_loop() + # set FigureManagerWx.frame to None to prevent repeated attempts to + # close this frame from FigureManagerWx.destroy() + self.canvas.manager.frame = None + # remove figure manager from Gcf.figs + Gcf.destroy(self.canvas.manager) + try: # See issue 2941338. + self.canvas.mpl_disconnect(self.canvas.toolbar._id_drag) + except AttributeError: # If there's no toolbar. + pass + # Carry on with close event propagation, frame & children destruction + event.Skip() + + +class FigureManagerWx(FigureManagerBase): + """ + Container/controller for the FigureCanvas and GUI frame. + + It is instantiated by Gcf whenever a new figure is created. Gcf is + responsible for managing multiple instances of FigureManagerWx. + + Attributes + ---------- + canvas : `FigureCanvas` + a FigureCanvasWx(wx.Panel) instance + window : wxFrame + a wxFrame instance - wxpython.org/Phoenix/docs/html/Frame.html + """ + + def __init__(self, canvas, num, frame): + _log.debug("%s - __init__()", type(self)) + self.frame = self.window = frame + super().__init__(canvas, num) + + @classmethod + def create_with_canvas(cls, canvas_class, figure, num): + # docstring inherited + wxapp = wx.GetApp() or _create_wxapp() + frame = FigureFrameWx(num, figure, canvas_class=canvas_class) + manager = figure.canvas.manager + if mpl.is_interactive(): + manager.frame.Show() + figure.canvas.draw_idle() + return manager + + @classmethod + def start_main_loop(cls): + if not wx.App.IsMainLoopRunning(): + wxapp = wx.GetApp() + if wxapp is not None: + wxapp.MainLoop() + + def show(self): + # docstring inherited + self.frame.Show() + self.canvas.draw() + if mpl.rcParams['figure.raise_window']: + self.frame.Raise() + + def destroy(self, *args): + # docstring inherited + _log.debug("%s - destroy()", type(self)) + frame = self.frame + if frame: # Else, may have been already deleted, e.g. when closing. + # As this can be called from non-GUI thread from plt.close use + # wx.CallAfter to ensure thread safety. + wx.CallAfter(frame.Close) + + def full_screen_toggle(self): + # docstring inherited + self.frame.ShowFullScreen(not self.frame.IsFullScreen()) + + def get_window_title(self): + # docstring inherited + return self.window.GetTitle() + + def set_window_title(self, title): + # docstring inherited + self.window.SetTitle(title) + + def resize(self, width, height): + # docstring inherited + # Directly using SetClientSize doesn't handle the toolbar on Windows. + self.window.SetSize(self.window.ClientToWindowSize(wx.Size( + math.ceil(width), math.ceil(height)))) + + +def _load_bitmap(filename): + """ + Load a wx.Bitmap from a file in the "images" directory of the Matplotlib + data. + """ + return wx.Bitmap(str(cbook._get_data_path('images', filename))) + + +def _set_frame_icon(frame): + bundle = wx.IconBundle() + for image in ('matplotlib.png', 'matplotlib_large.png'): + icon = wx.Icon(_load_bitmap(image)) + if not icon.IsOk(): + return + bundle.AddIcon(icon) + frame.SetIcons(bundle) + + +class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar): + def __init__(self, canvas, coordinates=True, *, style=wx.TB_BOTTOM): + wx.ToolBar.__init__(self, canvas.GetParent(), -1, style=style) + + if 'wxMac' in wx.PlatformInfo: + self.SetToolBitmapSize((24, 24)) + self.wx_ids = {} + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + self.AddSeparator() + continue + self.wx_ids[text] = ( + self.AddTool( + -1, + bitmap=self._icon(f"{image_file}.png"), + bmpDisabled=wx.NullBitmap, + label=text, shortHelp=tooltip_text, + kind=(wx.ITEM_CHECK if text in ["Pan", "Zoom"] + else wx.ITEM_NORMAL)) + .Id) + self.Bind(wx.EVT_TOOL, getattr(self, callback), + id=self.wx_ids[text]) + + self._coordinates = coordinates + if self._coordinates: + self.AddStretchableSpace() + self._label_text = wx.StaticText(self, style=wx.ALIGN_RIGHT) + self.AddControl(self._label_text) + + self.Realize() + + NavigationToolbar2.__init__(self, canvas) + + @staticmethod + def _icon(name): + """ + Construct a `wx.Bitmap` suitable for use as icon from an image file + *name*, including the extension and relative to Matplotlib's "images" + data directory. + """ + pilimg = PIL.Image.open(cbook._get_data_path("images", name)) + # ensure RGBA as wx BitMap expects RGBA format + image = np.array(pilimg.convert("RGBA")) + try: + dark = wx.SystemSettings.GetAppearance().IsDark() + except AttributeError: # wxpython < 4.1 + # copied from wx's IsUsingDarkBackground / GetLuminance. + bg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW) + fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) + # See wx.Colour.GetLuminance. + bg_lum = (.299 * bg.red + .587 * bg.green + .114 * bg.blue) / 255 + fg_lum = (.299 * fg.red + .587 * fg.green + .114 * fg.blue) / 255 + dark = fg_lum - bg_lum > .2 + if dark: + fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT) + black_mask = (image[..., :3] == 0).all(axis=-1) + image[black_mask, :3] = (fg.Red(), fg.Green(), fg.Blue()) + return wx.Bitmap.FromBufferRGBA( + image.shape[1], image.shape[0], image.tobytes()) + + def _update_buttons_checked(self): + if "Pan" in self.wx_ids: + self.ToggleTool(self.wx_ids["Pan"], self.mode.name == "PAN") + if "Zoom" in self.wx_ids: + self.ToggleTool(self.wx_ids["Zoom"], self.mode.name == "ZOOM") + + def zoom(self, *args): + super().zoom(*args) + self._update_buttons_checked() + + def pan(self, *args): + super().pan(*args) + self._update_buttons_checked() + + def save_figure(self, *args): + # Fetch the required filename and file type. + filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards() + default_file = self.canvas.get_default_filename() + dialog = wx.FileDialog( + self.canvas.GetParent(), "Save to file", + mpl.rcParams["savefig.directory"], default_file, filetypes, + wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) + dialog.SetFilterIndex(filter_index) + if dialog.ShowModal() == wx.ID_OK: + path = pathlib.Path(dialog.GetPath()) + _log.debug('%s - Save file path: %s', type(self), path) + fmt = exts[dialog.GetFilterIndex()] + ext = path.suffix[1:] + if ext in self.canvas.get_supported_filetypes() and fmt != ext: + # looks like they forgot to set the image type drop + # down, going with the extension. + _log.warning('extension %s did not match the selected ' + 'image type %s; going with %s', + ext, fmt, ext) + fmt = ext + # Save dir for next time, unless empty str (which means use cwd). + if mpl.rcParams["savefig.directory"]: + mpl.rcParams["savefig.directory"] = str(path.parent) + try: + self.canvas.figure.savefig(path, format=fmt) + except Exception as e: + dialog = wx.MessageDialog( + parent=self.canvas.GetParent(), message=str(e), + caption='Matplotlib error') + dialog.ShowModal() + dialog.Destroy() + + def draw_rubberband(self, event, x0, y0, x1, y1): + height = self.canvas.figure.bbox.height + self.canvas._rubberband_rect = (x0, height - y0, x1, height - y1) + self.canvas.Refresh() + + def remove_rubberband(self): + self.canvas._rubberband_rect = None + self.canvas.Refresh() + + def set_message(self, s): + if self._coordinates: + self._label_text.SetLabel(s) + + def set_history_buttons(self): + can_backward = self._nav_stack._pos > 0 + can_forward = self._nav_stack._pos < len(self._nav_stack) - 1 + if 'Back' in self.wx_ids: + self.EnableTool(self.wx_ids['Back'], can_backward) + if 'Forward' in self.wx_ids: + self.EnableTool(self.wx_ids['Forward'], can_forward) + + +# tools for matplotlib.backend_managers.ToolManager: + +class ToolbarWx(ToolContainerBase, wx.ToolBar): + def __init__(self, toolmanager, parent=None, style=wx.TB_BOTTOM): + if parent is None: + parent = toolmanager.canvas.GetParent() + ToolContainerBase.__init__(self, toolmanager) + wx.ToolBar.__init__(self, parent, -1, style=style) + self._space = self.AddStretchableSpace() + self._label_text = wx.StaticText(self, style=wx.ALIGN_RIGHT) + self.AddControl(self._label_text) + self._toolitems = {} + self._groups = {} # Mapping of groups to the separator after them. + + def _get_tool_pos(self, tool): + """ + Find the position (index) of a wx.ToolBarToolBase in a ToolBar. + + ``ToolBar.GetToolPos`` is not useful because wx assigns the same Id to + all Separators and StretchableSpaces. + """ + pos, = [pos for pos in range(self.ToolsCount) + if self.GetToolByPos(pos) == tool] + return pos + + def add_toolitem(self, name, group, position, image_file, description, + toggle): + # Find or create the separator that follows this group. + if group not in self._groups: + self._groups[group] = self.InsertSeparator( + self._get_tool_pos(self._space)) + sep = self._groups[group] + # List all separators. + seps = [t for t in map(self.GetToolByPos, range(self.ToolsCount)) + if t.IsSeparator() and not t.IsStretchableSpace()] + # Find where to insert the tool. + if position >= 0: + # Find the start of the group by looking for the separator + # preceding this one; then move forward from it. + start = (0 if sep == seps[0] + else self._get_tool_pos(seps[seps.index(sep) - 1]) + 1) + else: + # Move backwards from this separator. + start = self._get_tool_pos(sep) + 1 + idx = start + position + if image_file: + bmp = NavigationToolbar2Wx._icon(image_file) + kind = wx.ITEM_NORMAL if not toggle else wx.ITEM_CHECK + tool = self.InsertTool(idx, -1, name, bmp, wx.NullBitmap, kind, + description or "") + else: + size = (self.GetTextExtent(name)[0] + 10, -1) + if toggle: + control = wx.ToggleButton(self, -1, name, size=size) + else: + control = wx.Button(self, -1, name, size=size) + tool = self.InsertControl(idx, control, label=name) + self.Realize() + + def handler(event): + self.trigger_tool(name) + + if image_file: + self.Bind(wx.EVT_TOOL, handler, tool) + else: + control.Bind(wx.EVT_LEFT_DOWN, handler) + + self._toolitems.setdefault(name, []) + self._toolitems[name].append((tool, handler)) + + def toggle_toolitem(self, name, toggled): + if name not in self._toolitems: + return + for tool, handler in self._toolitems[name]: + if not tool.IsControl(): + self.ToggleTool(tool.Id, toggled) + else: + tool.GetControl().SetValue(toggled) + self.Refresh() + + def remove_toolitem(self, name): + for tool, handler in self._toolitems[name]: + self.DeleteTool(tool.Id) + del self._toolitems[name] + + def set_message(self, s): + self._label_text.SetLabel(s) + + +@backend_tools._register_tool_class(_FigureCanvasWxBase) +class ConfigureSubplotsWx(backend_tools.ConfigureSubplotsBase): + def trigger(self, *args): + NavigationToolbar2Wx.configure_subplots(self) + + +@backend_tools._register_tool_class(_FigureCanvasWxBase) +class SaveFigureWx(backend_tools.SaveFigureBase): + def trigger(self, *args): + NavigationToolbar2Wx.save_figure( + self._make_classic_style_pseudo_toolbar()) + + +@backend_tools._register_tool_class(_FigureCanvasWxBase) +class RubberbandWx(backend_tools.RubberbandBase): + def draw_rubberband(self, x0, y0, x1, y1): + NavigationToolbar2Wx.draw_rubberband( + self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1) + + def remove_rubberband(self): + NavigationToolbar2Wx.remove_rubberband( + self._make_classic_style_pseudo_toolbar()) + + +class _HelpDialog(wx.Dialog): + _instance = None # a reference to an open dialog singleton + headers = [("Action", "Shortcuts", "Description")] + widths = [100, 140, 300] + + def __init__(self, parent, help_entries): + super().__init__(parent, title="Help", + style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) + + sizer = wx.BoxSizer(wx.VERTICAL) + grid_sizer = wx.FlexGridSizer(0, 3, 8, 6) + # create and add the entries + bold = self.GetFont().MakeBold() + for r, row in enumerate(self.headers + help_entries): + for (col, width) in zip(row, self.widths): + label = wx.StaticText(self, label=col) + if r == 0: + label.SetFont(bold) + label.Wrap(width) + grid_sizer.Add(label, 0, 0, 0) + # finalize layout, create button + sizer.Add(grid_sizer, 0, wx.ALL, 6) + ok = wx.Button(self, wx.ID_OK) + sizer.Add(ok, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 8) + self.SetSizer(sizer) + sizer.Fit(self) + self.Layout() + self.Bind(wx.EVT_CLOSE, self._on_close) + ok.Bind(wx.EVT_BUTTON, self._on_close) + + def _on_close(self, event): + _HelpDialog._instance = None # remove global reference + self.DestroyLater() + event.Skip() + + @classmethod + def show(cls, parent, help_entries): + # if no dialog is shown, create one; otherwise just re-raise it + if cls._instance: + cls._instance.Raise() + return + cls._instance = cls(parent, help_entries) + cls._instance.Show() + + +@backend_tools._register_tool_class(_FigureCanvasWxBase) +class HelpWx(backend_tools.ToolHelpBase): + def trigger(self, *args): + _HelpDialog.show(self.figure.canvas.GetTopLevelParent(), + self._get_help_entries()) + + +@backend_tools._register_tool_class(_FigureCanvasWxBase) +class ToolCopyToClipboardWx(backend_tools.ToolCopyToClipboardBase): + def trigger(self, *args, **kwargs): + if not self.canvas._isDrawn: + self.canvas.draw() + if not self.canvas.bitmap.IsOk() or not wx.TheClipboard.Open(): + return + try: + wx.TheClipboard.SetData(wx.BitmapDataObject(self.canvas.bitmap)) + finally: + wx.TheClipboard.Close() + + +FigureManagerWx._toolbar2_class = NavigationToolbar2Wx +FigureManagerWx._toolmanager_toolbar_class = ToolbarWx + + +@_Backend.export +class _BackendWx(_Backend): + FigureCanvas = FigureCanvasWx + FigureManager = FigureManagerWx + mainloop = FigureManagerWx.start_main_loop diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxagg.py new file mode 100644 index 00000000..a5a9de07 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxagg.py @@ -0,0 +1,43 @@ +import wx + +from .backend_agg import FigureCanvasAgg +from .backend_wx import _BackendWx, _FigureCanvasWxBase +from .backend_wx import ( # noqa: F401 # pylint: disable=W0611 + NavigationToolbar2Wx as NavigationToolbar2WxAgg) + + +class FigureCanvasWxAgg(FigureCanvasAgg, _FigureCanvasWxBase): + def draw(self, drawDC=None): + """ + Render the figure using agg. + """ + FigureCanvasAgg.draw(self) + self.bitmap = _rgba_to_wx_bitmap(self.get_renderer().buffer_rgba()) + self._isDrawn = True + self.gui_repaint(drawDC=drawDC) + + def blit(self, bbox=None): + # docstring inherited + bitmap = _rgba_to_wx_bitmap(self.get_renderer().buffer_rgba()) + if bbox is None: + self.bitmap = bitmap + else: + srcDC = wx.MemoryDC(bitmap) + destDC = wx.MemoryDC(self.bitmap) + x = int(bbox.x0) + y = int(self.bitmap.GetHeight() - bbox.y1) + destDC.Blit(x, y, int(bbox.width), int(bbox.height), srcDC, x, y) + destDC.SelectObject(wx.NullBitmap) + srcDC.SelectObject(wx.NullBitmap) + self.gui_repaint() + + +def _rgba_to_wx_bitmap(rgba): + """Convert an RGBA buffer to a wx.Bitmap.""" + h, w, _ = rgba.shape + return wx.Bitmap.FromBufferRGBA(w, h, rgba) + + +@_BackendWx.export +class _BackendWxAgg(_BackendWx): + FigureCanvas = FigureCanvasWxAgg diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxcairo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxcairo.py new file mode 100644 index 00000000..c53e6af4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/backend_wxcairo.py @@ -0,0 +1,23 @@ +import wx.lib.wxcairo as wxcairo + +from .backend_cairo import cairo, FigureCanvasCairo +from .backend_wx import _BackendWx, _FigureCanvasWxBase +from .backend_wx import ( # noqa: F401 # pylint: disable=W0611 + NavigationToolbar2Wx as NavigationToolbar2WxCairo) + + +class FigureCanvasWxCairo(FigureCanvasCairo, _FigureCanvasWxBase): + def draw(self, drawDC=None): + size = self.figure.bbox.size.astype(int) + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *size) + self._renderer.set_context(cairo.Context(surface)) + self._renderer.dpi = self.figure.dpi + self.figure.draw(self._renderer) + self.bitmap = wxcairo.BitmapFromImageSurface(surface) + self._isDrawn = True + self.gui_repaint(drawDC=drawDC) + + +@_BackendWx.export +class _BackendWxCairo(_BackendWx): + FigureCanvas = FigureCanvasWxCairo diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_compat.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_compat.py new file mode 100644 index 00000000..d587223a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_compat.py @@ -0,0 +1,230 @@ +""" +Qt binding and backend selector. + +The selection logic is as follows: +- if any of PyQt6, PySide6, PyQt5, or PySide2 have already been + imported (checked in that order), use it; +- otherwise, if the QT_API environment variable (used by Enthought) is set, use + it to determine which binding to use; +- otherwise, use whatever the rcParams indicate. +""" + +import operator +import os +import platform +import sys +import signal +import socket +import contextlib + +from packaging.version import parse as parse_version + +import matplotlib as mpl + +from . import _QT_FORCE_QT5_BINDING + +QT_API_PYQT6 = "PyQt6" +QT_API_PYSIDE6 = "PySide6" +QT_API_PYQT5 = "PyQt5" +QT_API_PYSIDE2 = "PySide2" +QT_API_ENV = os.environ.get("QT_API") +if QT_API_ENV is not None: + QT_API_ENV = QT_API_ENV.lower() +_ETS = { # Mapping of QT_API_ENV to requested binding. + "pyqt6": QT_API_PYQT6, "pyside6": QT_API_PYSIDE6, + "pyqt5": QT_API_PYQT5, "pyside2": QT_API_PYSIDE2, +} +# First, check if anything is already imported. +if sys.modules.get("PyQt6.QtCore"): + QT_API = QT_API_PYQT6 +elif sys.modules.get("PySide6.QtCore"): + QT_API = QT_API_PYSIDE6 +elif sys.modules.get("PyQt5.QtCore"): + QT_API = QT_API_PYQT5 +elif sys.modules.get("PySide2.QtCore"): + QT_API = QT_API_PYSIDE2 +# Otherwise, check the QT_API environment variable (from Enthought). This can +# only override the binding, not the backend (in other words, we check that the +# requested backend actually matches). Use _get_backend_or_none to avoid +# triggering backend resolution (which can result in a partially but +# incompletely imported backend_qt5). +elif (mpl.rcParams._get_backend_or_none() or "").lower().startswith("qt5"): + if QT_API_ENV in ["pyqt5", "pyside2"]: + QT_API = _ETS[QT_API_ENV] + else: + _QT_FORCE_QT5_BINDING = True # noqa + QT_API = None +# A non-Qt backend was selected but we still got there (possible, e.g., when +# fully manually embedding Matplotlib in a Qt app without using pyplot). +elif QT_API_ENV is None: + QT_API = None +elif QT_API_ENV in _ETS: + QT_API = _ETS[QT_API_ENV] +else: + raise RuntimeError( + "The environment variable QT_API has the unrecognized value {!r}; " + "valid values are {}".format(QT_API_ENV, ", ".join(_ETS))) + + +def _setup_pyqt5plus(): + global QtCore, QtGui, QtWidgets, __version__ + global _isdeleted, _to_int + + if QT_API == QT_API_PYQT6: + from PyQt6 import QtCore, QtGui, QtWidgets, sip + __version__ = QtCore.PYQT_VERSION_STR + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + QtCore.Property = QtCore.pyqtProperty + _isdeleted = sip.isdeleted + _to_int = operator.attrgetter('value') + elif QT_API == QT_API_PYSIDE6: + from PySide6 import QtCore, QtGui, QtWidgets, __version__ + import shiboken6 + def _isdeleted(obj): return not shiboken6.isValid(obj) + if parse_version(__version__) >= parse_version('6.4'): + _to_int = operator.attrgetter('value') + else: + _to_int = int + elif QT_API == QT_API_PYQT5: + from PyQt5 import QtCore, QtGui, QtWidgets + import sip + __version__ = QtCore.PYQT_VERSION_STR + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + QtCore.Property = QtCore.pyqtProperty + _isdeleted = sip.isdeleted + _to_int = int + elif QT_API == QT_API_PYSIDE2: + from PySide2 import QtCore, QtGui, QtWidgets, __version__ + try: + from PySide2 import shiboken2 + except ImportError: + import shiboken2 + def _isdeleted(obj): + return not shiboken2.isValid(obj) + _to_int = int + else: + raise AssertionError(f"Unexpected QT_API: {QT_API}") + + +if QT_API in [QT_API_PYQT6, QT_API_PYQT5, QT_API_PYSIDE6, QT_API_PYSIDE2]: + _setup_pyqt5plus() +elif QT_API is None: # See above re: dict.__getitem__. + if _QT_FORCE_QT5_BINDING: + _candidates = [ + (_setup_pyqt5plus, QT_API_PYQT5), + (_setup_pyqt5plus, QT_API_PYSIDE2), + ] + else: + _candidates = [ + (_setup_pyqt5plus, QT_API_PYQT6), + (_setup_pyqt5plus, QT_API_PYSIDE6), + (_setup_pyqt5plus, QT_API_PYQT5), + (_setup_pyqt5plus, QT_API_PYSIDE2), + ] + for _setup, QT_API in _candidates: + try: + _setup() + except ImportError: + continue + break + else: + raise ImportError( + "Failed to import any of the following Qt binding modules: {}" + .format(", ".join([QT_API for _, QT_API in _candidates])) + ) +else: # We should not get there. + raise AssertionError(f"Unexpected QT_API: {QT_API}") +_version_info = tuple(QtCore.QLibraryInfo.version().segments()) + + +if _version_info < (5, 12): + raise ImportError( + f"The Qt version imported is " + f"{QtCore.QLibraryInfo.version().toString()} but Matplotlib requires " + f"Qt>=5.12") + + +# Fixes issues with Big Sur +# https://bugreports.qt.io/browse/QTBUG-87014, fixed in qt 5.15.2 +if (sys.platform == 'darwin' and + parse_version(platform.mac_ver()[0]) >= parse_version("10.16") and + _version_info < (5, 15, 2)): + os.environ.setdefault("QT_MAC_WANTS_LAYER", "1") + + +# Backports. + + +def _exec(obj): + # exec on PyQt6, exec_ elsewhere. + obj.exec() if hasattr(obj, "exec") else obj.exec_() + + +@contextlib.contextmanager +def _maybe_allow_interrupt(qapp): + """ + This manager allows to terminate a plot by sending a SIGINT. It is + necessary because the running Qt backend prevents Python interpreter to + run and process signals (i.e., to raise KeyboardInterrupt exception). To + solve this one needs to somehow wake up the interpreter and make it close + the plot window. We do this by using the signal.set_wakeup_fd() function + which organizes a write of the signal number into a socketpair connected + to the QSocketNotifier (since it is part of the Qt backend, it can react + to that write event). Afterwards, the Qt handler empties the socketpair + by a recv() command to re-arm it (we need this if a signal different from + SIGINT was caught by set_wakeup_fd() and we shall continue waiting). If + the SIGINT was caught indeed, after exiting the on_signal() function the + interpreter reacts to the SIGINT according to the handle() function which + had been set up by a signal.signal() call: it causes the qt_object to + exit by calling its quit() method. Finally, we call the old SIGINT + handler with the same arguments that were given to our custom handle() + handler. + + We do this only if the old handler for SIGINT was not None, which means + that a non-python handler was installed, i.e. in Julia, and not SIG_IGN + which means we should ignore the interrupts. + """ + + old_sigint_handler = signal.getsignal(signal.SIGINT) + if old_sigint_handler in (None, signal.SIG_IGN, signal.SIG_DFL): + yield + return + + handler_args = None + wsock, rsock = socket.socketpair() + wsock.setblocking(False) + rsock.setblocking(False) + old_wakeup_fd = signal.set_wakeup_fd(wsock.fileno()) + sn = QtCore.QSocketNotifier(rsock.fileno(), QtCore.QSocketNotifier.Type.Read) + + # We do not actually care about this value other than running some Python code to + # ensure that the interpreter has a chance to handle the signal in Python land. We + # also need to drain the socket because it will be written to as part of the wakeup! + # There are some cases where this may fire too soon / more than once on Windows so + # we should be forgiving about reading an empty socket. + # Clear the socket to re-arm the notifier. + @sn.activated.connect + def _may_clear_sock(*args): + try: + rsock.recv(1) + except BlockingIOError: + pass + + def handle(*args): + nonlocal handler_args + handler_args = args + qapp.quit() + + signal.signal(signal.SIGINT, handle) + try: + yield + finally: + wsock.close() + rsock.close() + sn.setEnabled(False) + signal.set_wakeup_fd(old_wakeup_fd) + signal.signal(signal.SIGINT, old_sigint_handler) + if handler_args is not None: + old_sigint_handler(*handler_args) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/_formlayout.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/_formlayout.py new file mode 100644 index 00000000..fcf73cef --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/_formlayout.py @@ -0,0 +1,592 @@ +""" +formlayout +========== + +Module creating Qt form dialogs/layouts to edit various type of parameters + + +formlayout License Agreement (MIT License) +------------------------------------------ + +Copyright (c) 2009 Pierre Raybaut + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +""" + +# History: +# 1.0.10: added float validator +# (disable "Ok" and "Apply" button when not valid) +# 1.0.7: added support for "Apply" button +# 1.0.6: code cleaning + +__version__ = '1.0.10' +__license__ = __doc__ + +from ast import literal_eval + +import copy +import datetime +import logging +from numbers import Integral, Real + +from matplotlib import _api, colors as mcolors +from matplotlib.backends.qt_compat import _to_int, QtGui, QtWidgets, QtCore + +_log = logging.getLogger(__name__) + +BLACKLIST = {"title", "label"} + + +class ColorButton(QtWidgets.QPushButton): + """ + Color choosing push button + """ + colorChanged = QtCore.Signal(QtGui.QColor) + + def __init__(self, parent=None): + super().__init__(parent) + self.setFixedSize(20, 20) + self.setIconSize(QtCore.QSize(12, 12)) + self.clicked.connect(self.choose_color) + self._color = QtGui.QColor() + + def choose_color(self): + color = QtWidgets.QColorDialog.getColor( + self._color, self.parentWidget(), "", + QtWidgets.QColorDialog.ColorDialogOption.ShowAlphaChannel) + if color.isValid(): + self.set_color(color) + + def get_color(self): + return self._color + + @QtCore.Slot(QtGui.QColor) + def set_color(self, color): + if color != self._color: + self._color = color + self.colorChanged.emit(self._color) + pixmap = QtGui.QPixmap(self.iconSize()) + pixmap.fill(color) + self.setIcon(QtGui.QIcon(pixmap)) + + color = QtCore.Property(QtGui.QColor, get_color, set_color) + + +def to_qcolor(color): + """Create a QColor from a matplotlib color""" + qcolor = QtGui.QColor() + try: + rgba = mcolors.to_rgba(color) + except ValueError: + _api.warn_external(f'Ignoring invalid color {color!r}') + return qcolor # return invalid QColor + qcolor.setRgbF(*rgba) + return qcolor + + +class ColorLayout(QtWidgets.QHBoxLayout): + """Color-specialized QLineEdit layout""" + def __init__(self, color, parent=None): + super().__init__() + assert isinstance(color, QtGui.QColor) + self.lineedit = QtWidgets.QLineEdit( + mcolors.to_hex(color.getRgbF(), keep_alpha=True), parent) + self.lineedit.editingFinished.connect(self.update_color) + self.addWidget(self.lineedit) + self.colorbtn = ColorButton(parent) + self.colorbtn.color = color + self.colorbtn.colorChanged.connect(self.update_text) + self.addWidget(self.colorbtn) + + def update_color(self): + color = self.text() + qcolor = to_qcolor(color) # defaults to black if not qcolor.isValid() + self.colorbtn.color = qcolor + + def update_text(self, color): + self.lineedit.setText(mcolors.to_hex(color.getRgbF(), keep_alpha=True)) + + def text(self): + return self.lineedit.text() + + +def font_is_installed(font): + """Check if font is installed""" + return [fam for fam in QtGui.QFontDatabase().families() + if str(fam) == font] + + +def tuple_to_qfont(tup): + """ + Create a QFont from tuple: + (family [string], size [int], italic [bool], bold [bool]) + """ + if not (isinstance(tup, tuple) and len(tup) == 4 + and font_is_installed(tup[0]) + and isinstance(tup[1], Integral) + and isinstance(tup[2], bool) + and isinstance(tup[3], bool)): + return None + font = QtGui.QFont() + family, size, italic, bold = tup + font.setFamily(family) + font.setPointSize(size) + font.setItalic(italic) + font.setBold(bold) + return font + + +def qfont_to_tuple(font): + return (str(font.family()), int(font.pointSize()), + font.italic(), font.bold()) + + +class FontLayout(QtWidgets.QGridLayout): + """Font selection""" + def __init__(self, value, parent=None): + super().__init__() + font = tuple_to_qfont(value) + assert font is not None + + # Font family + self.family = QtWidgets.QFontComboBox(parent) + self.family.setCurrentFont(font) + self.addWidget(self.family, 0, 0, 1, -1) + + # Font size + self.size = QtWidgets.QComboBox(parent) + self.size.setEditable(True) + sizelist = [*range(6, 12), *range(12, 30, 2), 36, 48, 72] + size = font.pointSize() + if size not in sizelist: + sizelist.append(size) + sizelist.sort() + self.size.addItems([str(s) for s in sizelist]) + self.size.setCurrentIndex(sizelist.index(size)) + self.addWidget(self.size, 1, 0) + + # Italic or not + self.italic = QtWidgets.QCheckBox(self.tr("Italic"), parent) + self.italic.setChecked(font.italic()) + self.addWidget(self.italic, 1, 1) + + # Bold or not + self.bold = QtWidgets.QCheckBox(self.tr("Bold"), parent) + self.bold.setChecked(font.bold()) + self.addWidget(self.bold, 1, 2) + + def get_font(self): + font = self.family.currentFont() + font.setItalic(self.italic.isChecked()) + font.setBold(self.bold.isChecked()) + font.setPointSize(int(self.size.currentText())) + return qfont_to_tuple(font) + + +def is_edit_valid(edit): + text = edit.text() + state = edit.validator().validate(text, 0)[0] + return state == QtGui.QDoubleValidator.State.Acceptable + + +class FormWidget(QtWidgets.QWidget): + update_buttons = QtCore.Signal() + + def __init__(self, data, comment="", with_margin=False, parent=None): + """ + Parameters + ---------- + data : list of (label, value) pairs + The data to be edited in the form. + comment : str, optional + with_margin : bool, default: False + If False, the form elements reach to the border of the widget. + This is the desired behavior if the FormWidget is used as a widget + alongside with other widgets such as a QComboBox, which also do + not have a margin around them. + However, a margin can be desired if the FormWidget is the only + widget within a container, e.g. a tab in a QTabWidget. + parent : QWidget or None + The parent widget. + """ + super().__init__(parent) + self.data = copy.deepcopy(data) + self.widgets = [] + self.formlayout = QtWidgets.QFormLayout(self) + if not with_margin: + self.formlayout.setContentsMargins(0, 0, 0, 0) + if comment: + self.formlayout.addRow(QtWidgets.QLabel(comment)) + self.formlayout.addRow(QtWidgets.QLabel(" ")) + + def get_dialog(self): + """Return FormDialog instance""" + dialog = self.parent() + while not isinstance(dialog, QtWidgets.QDialog): + dialog = dialog.parent() + return dialog + + def setup(self): + for label, value in self.data: + if label is None and value is None: + # Separator: (None, None) + self.formlayout.addRow(QtWidgets.QLabel(" "), + QtWidgets.QLabel(" ")) + self.widgets.append(None) + continue + elif label is None: + # Comment + self.formlayout.addRow(QtWidgets.QLabel(value)) + self.widgets.append(None) + continue + elif tuple_to_qfont(value) is not None: + field = FontLayout(value, self) + elif (label.lower() not in BLACKLIST + and mcolors.is_color_like(value)): + field = ColorLayout(to_qcolor(value), self) + elif isinstance(value, str): + field = QtWidgets.QLineEdit(value, self) + elif isinstance(value, (list, tuple)): + if isinstance(value, tuple): + value = list(value) + # Note: get() below checks the type of value[0] in self.data so + # it is essential that value gets modified in-place. + # This means that the code is actually broken in the case where + # value is a tuple, but fortunately we always pass a list... + selindex = value.pop(0) + field = QtWidgets.QComboBox(self) + if isinstance(value[0], (list, tuple)): + keys = [key for key, _val in value] + value = [val for _key, val in value] + else: + keys = value + field.addItems(value) + if selindex in value: + selindex = value.index(selindex) + elif selindex in keys: + selindex = keys.index(selindex) + elif not isinstance(selindex, Integral): + _log.warning( + "index '%s' is invalid (label: %s, value: %s)", + selindex, label, value) + selindex = 0 + field.setCurrentIndex(selindex) + elif isinstance(value, bool): + field = QtWidgets.QCheckBox(self) + field.setChecked(value) + elif isinstance(value, Integral): + field = QtWidgets.QSpinBox(self) + field.setRange(-10**9, 10**9) + field.setValue(value) + elif isinstance(value, Real): + field = QtWidgets.QLineEdit(repr(value), self) + field.setCursorPosition(0) + field.setValidator(QtGui.QDoubleValidator(field)) + field.validator().setLocale(QtCore.QLocale("C")) + dialog = self.get_dialog() + dialog.register_float_field(field) + field.textChanged.connect(lambda text: dialog.update_buttons()) + elif isinstance(value, datetime.datetime): + field = QtWidgets.QDateTimeEdit(self) + field.setDateTime(value) + elif isinstance(value, datetime.date): + field = QtWidgets.QDateEdit(self) + field.setDate(value) + else: + field = QtWidgets.QLineEdit(repr(value), self) + self.formlayout.addRow(label, field) + self.widgets.append(field) + + def get(self): + valuelist = [] + for index, (label, value) in enumerate(self.data): + field = self.widgets[index] + if label is None: + # Separator / Comment + continue + elif tuple_to_qfont(value) is not None: + value = field.get_font() + elif isinstance(value, str) or mcolors.is_color_like(value): + value = str(field.text()) + elif isinstance(value, (list, tuple)): + index = int(field.currentIndex()) + if isinstance(value[0], (list, tuple)): + value = value[index][0] + else: + value = value[index] + elif isinstance(value, bool): + value = field.isChecked() + elif isinstance(value, Integral): + value = int(field.value()) + elif isinstance(value, Real): + value = float(str(field.text())) + elif isinstance(value, datetime.datetime): + datetime_ = field.dateTime() + if hasattr(datetime_, "toPyDateTime"): + value = datetime_.toPyDateTime() + else: + value = datetime_.toPython() + elif isinstance(value, datetime.date): + date_ = field.date() + if hasattr(date_, "toPyDate"): + value = date_.toPyDate() + else: + value = date_.toPython() + else: + value = literal_eval(str(field.text())) + valuelist.append(value) + return valuelist + + +class FormComboWidget(QtWidgets.QWidget): + update_buttons = QtCore.Signal() + + def __init__(self, datalist, comment="", parent=None): + super().__init__(parent) + layout = QtWidgets.QVBoxLayout() + self.setLayout(layout) + self.combobox = QtWidgets.QComboBox() + layout.addWidget(self.combobox) + + self.stackwidget = QtWidgets.QStackedWidget(self) + layout.addWidget(self.stackwidget) + self.combobox.currentIndexChanged.connect( + self.stackwidget.setCurrentIndex) + + self.widgetlist = [] + for data, title, comment in datalist: + self.combobox.addItem(title) + widget = FormWidget(data, comment=comment, parent=self) + self.stackwidget.addWidget(widget) + self.widgetlist.append(widget) + + def setup(self): + for widget in self.widgetlist: + widget.setup() + + def get(self): + return [widget.get() for widget in self.widgetlist] + + +class FormTabWidget(QtWidgets.QWidget): + update_buttons = QtCore.Signal() + + def __init__(self, datalist, comment="", parent=None): + super().__init__(parent) + layout = QtWidgets.QVBoxLayout() + self.tabwidget = QtWidgets.QTabWidget() + layout.addWidget(self.tabwidget) + layout.setContentsMargins(0, 0, 0, 0) + self.setLayout(layout) + self.widgetlist = [] + for data, title, comment in datalist: + if len(data[0]) == 3: + widget = FormComboWidget(data, comment=comment, parent=self) + else: + widget = FormWidget(data, with_margin=True, comment=comment, + parent=self) + index = self.tabwidget.addTab(widget, title) + self.tabwidget.setTabToolTip(index, comment) + self.widgetlist.append(widget) + + def setup(self): + for widget in self.widgetlist: + widget.setup() + + def get(self): + return [widget.get() for widget in self.widgetlist] + + +class FormDialog(QtWidgets.QDialog): + """Form Dialog""" + def __init__(self, data, title="", comment="", + icon=None, parent=None, apply=None): + super().__init__(parent) + + self.apply_callback = apply + + # Form + if isinstance(data[0][0], (list, tuple)): + self.formwidget = FormTabWidget(data, comment=comment, + parent=self) + elif len(data[0]) == 3: + self.formwidget = FormComboWidget(data, comment=comment, + parent=self) + else: + self.formwidget = FormWidget(data, comment=comment, + parent=self) + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.formwidget) + + self.float_fields = [] + self.formwidget.setup() + + # Button box + self.bbox = bbox = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.StandardButton( + _to_int(QtWidgets.QDialogButtonBox.StandardButton.Ok) | + _to_int(QtWidgets.QDialogButtonBox.StandardButton.Cancel) + )) + self.formwidget.update_buttons.connect(self.update_buttons) + if self.apply_callback is not None: + apply_btn = bbox.addButton( + QtWidgets.QDialogButtonBox.StandardButton.Apply) + apply_btn.clicked.connect(self.apply) + + bbox.accepted.connect(self.accept) + bbox.rejected.connect(self.reject) + layout.addWidget(bbox) + + self.setLayout(layout) + + self.setWindowTitle(title) + if not isinstance(icon, QtGui.QIcon): + icon = QtWidgets.QWidget().style().standardIcon( + QtWidgets.QStyle.SP_MessageBoxQuestion) + self.setWindowIcon(icon) + + def register_float_field(self, field): + self.float_fields.append(field) + + def update_buttons(self): + valid = True + for field in self.float_fields: + if not is_edit_valid(field): + valid = False + for btn_type in ["Ok", "Apply"]: + btn = self.bbox.button( + getattr(QtWidgets.QDialogButtonBox.StandardButton, + btn_type)) + if btn is not None: + btn.setEnabled(valid) + + def accept(self): + self.data = self.formwidget.get() + self.apply_callback(self.data) + super().accept() + + def reject(self): + self.data = None + super().reject() + + def apply(self): + self.apply_callback(self.formwidget.get()) + + def get(self): + """Return form result""" + return self.data + + +def fedit(data, title="", comment="", icon=None, parent=None, apply=None): + """ + Create form dialog + + data: datalist, datagroup + title: str + comment: str + icon: QIcon instance + parent: parent QWidget + apply: apply callback (function) + + datalist: list/tuple of (field_name, field_value) + datagroup: list/tuple of (datalist *or* datagroup, title, comment) + + -> one field for each member of a datalist + -> one tab for each member of a top-level datagroup + -> one page (of a multipage widget, each page can be selected with a combo + box) for each member of a datagroup inside a datagroup + + Supported types for field_value: + - int, float, str, bool + - colors: in Qt-compatible text form, i.e. in hex format or name + (red, ...) (automatically detected from a string) + - list/tuple: + * the first element will be the selected index (or value) + * the other elements can be couples (key, value) or only values + """ + + # Create a QApplication instance if no instance currently exists + # (e.g., if the module is used directly from the interpreter) + if QtWidgets.QApplication.startingUp(): + _app = QtWidgets.QApplication([]) + dialog = FormDialog(data, title, comment, icon, parent, apply) + + if parent is not None: + if hasattr(parent, "_fedit_dialog"): + parent._fedit_dialog.close() + parent._fedit_dialog = dialog + + dialog.show() + + +if __name__ == "__main__": + + _app = QtWidgets.QApplication([]) + + def create_datalist_example(): + return [('str', 'this is a string'), + ('list', [0, '1', '3', '4']), + ('list2', ['--', ('none', 'None'), ('--', 'Dashed'), + ('-.', 'DashDot'), ('-', 'Solid'), + ('steps', 'Steps'), (':', 'Dotted')]), + ('float', 1.2), + (None, 'Other:'), + ('int', 12), + ('font', ('Arial', 10, False, True)), + ('color', '#123409'), + ('bool', True), + ('date', datetime.date(2010, 10, 10)), + ('datetime', datetime.datetime(2010, 10, 10)), + ] + + def create_datagroup_example(): + datalist = create_datalist_example() + return ((datalist, "Category 1", "Category 1 comment"), + (datalist, "Category 2", "Category 2 comment"), + (datalist, "Category 3", "Category 3 comment")) + + # --------- datalist example + datalist = create_datalist_example() + + def apply_test(data): + print("data:", data) + fedit(datalist, title="Example", + comment="This is just an example.", + apply=apply_test) + + _app.exec() + + # --------- datagroup example + datagroup = create_datagroup_example() + fedit(datagroup, "Global title", + apply=apply_test) + _app.exec() + + # --------- datagroup inside a datagroup example + datalist = create_datalist_example() + datagroup = create_datagroup_example() + fedit(((datagroup, "Title 1", "Tab 1 comment"), + (datalist, "Title 2", "Tab 2 comment"), + (datalist, "Title 3", "Tab 3 comment")), + "Global title", + apply=apply_test) + _app.exec() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/figureoptions.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/figureoptions.py new file mode 100644 index 00000000..c744ccc3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/qt_editor/figureoptions.py @@ -0,0 +1,263 @@ +# Copyright © 2009 Pierre Raybaut +# Licensed under the terms of the MIT License +# see the Matplotlib licenses directory for a copy of the license + + +"""Module that provides a GUI-based editor for Matplotlib's figure options.""" + +from itertools import chain +from matplotlib import cbook, cm, colors as mcolors, markers, image as mimage +from matplotlib.backends.qt_compat import QtGui +from matplotlib.backends.qt_editor import _formlayout +from matplotlib.dates import DateConverter, num2date + +LINESTYLES = {'-': 'Solid', + '--': 'Dashed', + '-.': 'DashDot', + ':': 'Dotted', + 'None': 'None', + } + +DRAWSTYLES = { + 'default': 'Default', + 'steps-pre': 'Steps (Pre)', 'steps': 'Steps (Pre)', + 'steps-mid': 'Steps (Mid)', + 'steps-post': 'Steps (Post)'} + +MARKERS = markers.MarkerStyle.markers + + +def figure_edit(axes, parent=None): + """Edit matplotlib figure options""" + sep = (None, None) # separator + + # Get / General + def convert_limits(lim, converter): + """Convert axis limits for correct input editors.""" + if isinstance(converter, DateConverter): + return map(num2date, lim) + # Cast to builtin floats as they have nicer reprs. + return map(float, lim) + + axis_map = axes._axis_map + axis_limits = { + name: tuple(convert_limits( + getattr(axes, f'get_{name}lim')(), axis.converter + )) + for name, axis in axis_map.items() + } + general = [ + ('Title', axes.get_title()), + sep, + *chain.from_iterable([ + ( + (None, f"{name.title()}-Axis"), + ('Min', axis_limits[name][0]), + ('Max', axis_limits[name][1]), + ('Label', axis.get_label().get_text()), + ('Scale', [axis.get_scale(), + 'linear', 'log', 'symlog', 'logit']), + sep, + ) + for name, axis in axis_map.items() + ]), + ('(Re-)Generate automatic legend', False), + ] + + # Save the converter and unit data + axis_converter = { + name: axis.converter + for name, axis in axis_map.items() + } + axis_units = { + name: axis.get_units() + for name, axis in axis_map.items() + } + + # Get / Curves + labeled_lines = [] + for line in axes.get_lines(): + label = line.get_label() + if label == '_nolegend_': + continue + labeled_lines.append((label, line)) + curves = [] + + def prepare_data(d, init): + """ + Prepare entry for FormLayout. + + *d* is a mapping of shorthands to style names (a single style may + have multiple shorthands, in particular the shorthands `None`, + `"None"`, `"none"` and `""` are synonyms); *init* is one shorthand + of the initial style. + + This function returns an list suitable for initializing a + FormLayout combobox, namely `[initial_name, (shorthand, + style_name), (shorthand, style_name), ...]`. + """ + if init not in d: + d = {**d, init: str(init)} + # Drop duplicate shorthands from dict (by overwriting them during + # the dict comprehension). + name2short = {name: short for short, name in d.items()} + # Convert back to {shorthand: name}. + short2name = {short: name for name, short in name2short.items()} + # Find the kept shorthand for the style specified by init. + canonical_init = name2short[d[init]] + # Sort by representation and prepend the initial value. + return ([canonical_init] + + sorted(short2name.items(), + key=lambda short_and_name: short_and_name[1])) + + for label, line in labeled_lines: + color = mcolors.to_hex( + mcolors.to_rgba(line.get_color(), line.get_alpha()), + keep_alpha=True) + ec = mcolors.to_hex( + mcolors.to_rgba(line.get_markeredgecolor(), line.get_alpha()), + keep_alpha=True) + fc = mcolors.to_hex( + mcolors.to_rgba(line.get_markerfacecolor(), line.get_alpha()), + keep_alpha=True) + curvedata = [ + ('Label', label), + sep, + (None, 'Line'), + ('Line style', prepare_data(LINESTYLES, line.get_linestyle())), + ('Draw style', prepare_data(DRAWSTYLES, line.get_drawstyle())), + ('Width', line.get_linewidth()), + ('Color (RGBA)', color), + sep, + (None, 'Marker'), + ('Style', prepare_data(MARKERS, line.get_marker())), + ('Size', line.get_markersize()), + ('Face color (RGBA)', fc), + ('Edge color (RGBA)', ec)] + curves.append([curvedata, label, ""]) + # Is there a curve displayed? + has_curve = bool(curves) + + # Get ScalarMappables. + labeled_mappables = [] + for mappable in [*axes.images, *axes.collections]: + label = mappable.get_label() + if label == '_nolegend_' or mappable.get_array() is None: + continue + labeled_mappables.append((label, mappable)) + mappables = [] + cmaps = [(cmap, name) for name, cmap in sorted(cm._colormaps.items())] + for label, mappable in labeled_mappables: + cmap = mappable.get_cmap() + if cmap not in cm._colormaps.values(): + cmaps = [(cmap, cmap.name), *cmaps] + low, high = mappable.get_clim() + mappabledata = [ + ('Label', label), + ('Colormap', [cmap.name] + cmaps), + ('Min. value', low), + ('Max. value', high), + ] + if hasattr(mappable, "get_interpolation"): # Images. + interpolations = [ + (name, name) for name in sorted(mimage.interpolations_names)] + mappabledata.append(( + 'Interpolation', + [mappable.get_interpolation(), *interpolations])) + mappables.append([mappabledata, label, ""]) + # Is there a scalarmappable displayed? + has_sm = bool(mappables) + + datalist = [(general, "Axes", "")] + if curves: + datalist.append((curves, "Curves", "")) + if mappables: + datalist.append((mappables, "Images, etc.", "")) + + def apply_callback(data): + """A callback to apply changes.""" + orig_limits = { + name: getattr(axes, f"get_{name}lim")() + for name in axis_map + } + + general = data.pop(0) + curves = data.pop(0) if has_curve else [] + mappables = data.pop(0) if has_sm else [] + if data: + raise ValueError("Unexpected field") + + title = general.pop(0) + axes.set_title(title) + generate_legend = general.pop() + + for i, (name, axis) in enumerate(axis_map.items()): + axis_min = general[4*i] + axis_max = general[4*i + 1] + axis_label = general[4*i + 2] + axis_scale = general[4*i + 3] + if axis.get_scale() != axis_scale: + getattr(axes, f"set_{name}scale")(axis_scale) + + axis._set_lim(axis_min, axis_max, auto=False) + axis.set_label_text(axis_label) + + # Restore the unit data + axis.converter = axis_converter[name] + axis.set_units(axis_units[name]) + + # Set / Curves + for index, curve in enumerate(curves): + line = labeled_lines[index][1] + (label, linestyle, drawstyle, linewidth, color, marker, markersize, + markerfacecolor, markeredgecolor) = curve + line.set_label(label) + line.set_linestyle(linestyle) + line.set_drawstyle(drawstyle) + line.set_linewidth(linewidth) + rgba = mcolors.to_rgba(color) + line.set_alpha(None) + line.set_color(rgba) + if marker != 'none': + line.set_marker(marker) + line.set_markersize(markersize) + line.set_markerfacecolor(markerfacecolor) + line.set_markeredgecolor(markeredgecolor) + + # Set ScalarMappables. + for index, mappable_settings in enumerate(mappables): + mappable = labeled_mappables[index][1] + if len(mappable_settings) == 5: + label, cmap, low, high, interpolation = mappable_settings + mappable.set_interpolation(interpolation) + elif len(mappable_settings) == 4: + label, cmap, low, high = mappable_settings + mappable.set_label(label) + mappable.set_cmap(cmap) + mappable.set_clim(*sorted([low, high])) + + # re-generate legend, if checkbox is checked + if generate_legend: + draggable = None + ncols = 1 + if axes.legend_ is not None: + old_legend = axes.get_legend() + draggable = old_legend._draggable is not None + ncols = old_legend._ncols + new_legend = axes.legend(ncols=ncols) + if new_legend: + new_legend.set_draggable(draggable) + + # Redraw + figure = axes.get_figure() + figure.canvas.draw() + for name in axis_map: + if getattr(axes, f"get_{name}lim")() != orig_limits[name]: + figure.canvas.toolbar.push_current() + break + + _formlayout.fedit( + datalist, title="Figure options", parent=parent, + icon=QtGui.QIcon( + str(cbook._get_data_path('images', 'qt4_editor_options.svg'))), + apply=apply_callback) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.eslintrc.js b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.eslintrc.js new file mode 100644 index 00000000..6f3581a1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.eslintrc.js @@ -0,0 +1,32 @@ +module.exports = { + root: true, + ignorePatterns: ["jquery-ui-*/", "node_modules/"], + env: { + browser: true, + jquery: true, + }, + extends: ["eslint:recommended", "prettier"], + globals: { + IPython: "readonly", + MozWebSocket: "readonly", + }, + rules: { + indent: ["error", 2, { SwitchCase: 1 }], + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + }, + ], + quotes: ["error", "double", { avoidEscape: true }], + }, + overrides: [ + { + files: "js/**/*.js", + rules: { + indent: ["error", 4, { SwitchCase: 1 }], + quotes: ["error", "single", { avoidEscape: true }], + }, + }, + ], +}; diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierignore b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierignore new file mode 100644 index 00000000..06a29c66 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierignore @@ -0,0 +1,7 @@ +node_modules/ + +# Vendored dependencies +css/boilerplate.css +css/fbm.css +css/page.css +jquery-ui-*/ diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierrc b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierrc new file mode 100644 index 00000000..fe8d7110 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/.prettierrc @@ -0,0 +1,11 @@ +{ + "overrides": [ + { + "files": "js/**/*.js", + "options": { + "singleQuote": true, + "tabWidth": 4, + } + } + ] +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/all_figures.html b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/all_figures.html new file mode 100644 index 00000000..62f04b65 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/all_figures.html @@ -0,0 +1,52 @@ + + + + + + + + + + + + + MPL | WebAgg current figures + + + +
    + +
    + + + diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/boilerplate.css b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/boilerplate.css new file mode 100644 index 00000000..2b1535f4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/boilerplate.css @@ -0,0 +1,77 @@ +/** + * HTML5 ✰ Boilerplate + * + * style.css contains a reset, font normalization and some base styles. + * + * Credit is left where credit is due. + * Much inspiration was taken from these projects: + * - yui.yahooapis.com/2.8.1/build/base/base.css + * - camendesign.com/design/ + * - praegnanz.de/weblog/htmlcssjs-kickstart + */ + + +/** + * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline) + * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark + * html5doctor.com/html-5-reset-stylesheet/ + */ + +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +sup { vertical-align: super; } +sub { vertical-align: sub; } + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +blockquote, q { quotes: none; } + +blockquote:before, blockquote:after, +q:before, q:after { content: ""; content: none; } + +ins { background-color: #ff9; color: #000; text-decoration: none; } + +mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } + +del { text-decoration: line-through; } + +abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } + +table { border-collapse: collapse; border-spacing: 0; } + +hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } + +input, select { vertical-align: middle; } + + +/** + * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/ + */ + +body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */ +select, input, textarea, button { font:99% sans-serif; } + +/* Normalize monospace sizing: + en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */ +pre, code, kbd, samp { font-family: monospace, sans-serif; } + +em,i { font-style: italic; } +b,strong { font-weight: bold; } diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/fbm.css b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/fbm.css new file mode 100644 index 00000000..ce35d99a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/fbm.css @@ -0,0 +1,97 @@ + +/* Flexible box model classes */ +/* Taken from Alex Russell https://infrequently.org/2009/08/css-3-progress/ */ + +.hbox { + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: stretch; + + display: -moz-box; + -moz-box-orient: horizontal; + -moz-box-align: stretch; + + display: box; + box-orient: horizontal; + box-align: stretch; +} + +.hbox > * { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.vbox { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + + display: -moz-box; + -moz-box-orient: vertical; + -moz-box-align: stretch; + + display: box; + box-orient: vertical; + box-align: stretch; +} + +.vbox > * { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.reverse { + -webkit-box-direction: reverse; + -moz-box-direction: reverse; + box-direction: reverse; +} + +.box-flex0 { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.box-flex1, .box-flex { + -webkit-box-flex: 1; + -moz-box-flex: 1; + box-flex: 1; +} + +.box-flex2 { + -webkit-box-flex: 2; + -moz-box-flex: 2; + box-flex: 2; +} + +.box-group1 { + -webkit-box-flex-group: 1; + -moz-box-flex-group: 1; + box-flex-group: 1; +} + +.box-group2 { + -webkit-box-flex-group: 2; + -moz-box-flex-group: 2; + box-flex-group: 2; +} + +.start { + -webkit-box-pack: start; + -moz-box-pack: start; + box-pack: start; +} + +.end { + -webkit-box-pack: end; + -moz-box-pack: end; + box-pack: end; +} + +.center { + -webkit-box-pack: center; + -moz-box-pack: center; + box-pack: center; +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/mpl.css b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/mpl.css new file mode 100644 index 00000000..e55733d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/mpl.css @@ -0,0 +1,84 @@ +/* General styling */ +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} + +/* Header */ +.ui-widget-header { + border: 1px solid #dddddd; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + background: #e9e9e9; + color: #333333; + font-weight: bold; +} + +/* Toolbar and items */ +.mpl-toolbar { + width: 100%; +} + +.mpl-toolbar div.mpl-button-group { + display: inline-block; +} + +.mpl-button-group + .mpl-button-group { + margin-left: 0.5em; +} + +.mpl-widget { + background-color: #fff; + border: 1px solid #ccc; + display: inline-block; + cursor: pointer; + color: #333; + padding: 6px; + vertical-align: middle; +} + +.mpl-widget:disabled, +.mpl-widget[disabled] { + background-color: #ddd; + border-color: #ddd !important; + cursor: not-allowed; +} + +.mpl-widget:disabled img, +.mpl-widget[disabled] img { + /* Convert black to grey */ + filter: contrast(0%); +} + +.mpl-widget.active img { + /* Convert black to tab:blue, approximately */ + filter: invert(34%) sepia(97%) saturate(468%) hue-rotate(162deg) brightness(96%) contrast(91%); +} + +button.mpl-widget:focus, +button.mpl-widget:hover { + background-color: #ddd; + border-color: #aaa; +} + +.mpl-button-group button.mpl-widget { + margin-left: -1px; +} +.mpl-button-group button.mpl-widget:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + margin-left: 0px; +} +.mpl-button-group button.mpl-widget:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +select.mpl-widget { + cursor: default; +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/page.css b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/page.css new file mode 100644 index 00000000..ded0d922 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/css/page.css @@ -0,0 +1,82 @@ +/** + * Primary styles + * + * Author: IPython Development Team + */ + + +body { + background-color: white; + /* This makes sure that the body covers the entire window and needs to + be in a different element than the display: box in wrapper below */ + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + overflow: visible; +} + + +div#header { + /* Initially hidden to prevent FLOUC */ + display: none; + position: relative; + height: 40px; + padding: 5px; + margin: 0px; + width: 100%; +} + +span#ipython_notebook { + position: absolute; + padding: 2px 2px 2px 5px; +} + +span#ipython_notebook img { + font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; + height: 24px; + text-decoration:none; + display: inline; + color: black; +} + +#site { + width: 100%; + display: none; +} + +/* We set the fonts by hand here to override the values in the theme */ +.ui-widget { + font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif; +} + +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { + font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif; +} + +/* Smaller buttons */ +.ui-button .ui-button-text { + padding: 0.2em 0.8em; + font-size: 77%; +} + +input.ui-button { + padding: 0.3em 0.9em; +} + +span#login_widget { + float: right; +} + +.border-box-sizing { + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +#figure-div { + display: inline-block; + margin: 10px; + vertical-align: top; +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/ipython_inline_figure.html b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/ipython_inline_figure.html new file mode 100644 index 00000000..b941d352 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/ipython_inline_figure.html @@ -0,0 +1,34 @@ + + diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl.js b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl.js new file mode 100644 index 00000000..140f5903 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl.js @@ -0,0 +1,695 @@ +/* Put everything inside the global mpl namespace */ +/* global mpl */ +window.mpl = {}; + +mpl.get_websocket_type = function () { + if (typeof WebSocket !== 'undefined') { + return WebSocket; + } else if (typeof MozWebSocket !== 'undefined') { + return MozWebSocket; + } else { + alert( + 'Your browser does not have WebSocket support. ' + + 'Please try Chrome, Safari or Firefox ≥ 6. ' + + 'Firefox 4 and 5 are also supported but you ' + + 'have to enable WebSockets in about:config.' + ); + } +}; + +mpl.figure = function (figure_id, websocket, ondownload, parent_element) { + this.id = figure_id; + + this.ws = websocket; + + this.supports_binary = this.ws.binaryType !== undefined; + + if (!this.supports_binary) { + var warnings = document.getElementById('mpl-warnings'); + if (warnings) { + warnings.style.display = 'block'; + warnings.textContent = + 'This browser does not support binary websocket messages. ' + + 'Performance may be slow.'; + } + } + + this.imageObj = new Image(); + + this.context = undefined; + this.message = undefined; + this.canvas = undefined; + this.rubberband_canvas = undefined; + this.rubberband_context = undefined; + this.format_dropdown = undefined; + + this.image_mode = 'full'; + + this.root = document.createElement('div'); + this.root.setAttribute('style', 'display: inline-block'); + this._root_extra_style(this.root); + + parent_element.appendChild(this.root); + + this._init_header(this); + this._init_canvas(this); + this._init_toolbar(this); + + var fig = this; + + this.waiting = false; + + this.ws.onopen = function () { + fig.send_message('supports_binary', { value: fig.supports_binary }); + fig.send_message('send_image_mode', {}); + if (fig.ratio !== 1) { + fig.send_message('set_device_pixel_ratio', { + device_pixel_ratio: fig.ratio, + }); + } + fig.send_message('refresh', {}); + }; + + this.imageObj.onload = function () { + if (fig.image_mode === 'full') { + // Full images could contain transparency (where diff images + // almost always do), so we need to clear the canvas so that + // there is no ghosting. + fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height); + } + fig.context.drawImage(fig.imageObj, 0, 0); + }; + + this.imageObj.onunload = function () { + fig.ws.close(); + }; + + this.ws.onmessage = this._make_on_message_function(this); + + this.ondownload = ondownload; +}; + +mpl.figure.prototype._init_header = function () { + var titlebar = document.createElement('div'); + titlebar.classList = + 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix'; + var titletext = document.createElement('div'); + titletext.classList = 'ui-dialog-title'; + titletext.setAttribute( + 'style', + 'width: 100%; text-align: center; padding: 3px;' + ); + titlebar.appendChild(titletext); + this.root.appendChild(titlebar); + this.header = titletext; +}; + +mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {}; + +mpl.figure.prototype._root_extra_style = function (_canvas_div) {}; + +mpl.figure.prototype._init_canvas = function () { + var fig = this; + + var canvas_div = (this.canvas_div = document.createElement('div')); + canvas_div.setAttribute('tabindex', '0'); + canvas_div.setAttribute( + 'style', + 'border: 1px solid #ddd;' + + 'box-sizing: content-box;' + + 'clear: both;' + + 'min-height: 1px;' + + 'min-width: 1px;' + + 'outline: 0;' + + 'overflow: hidden;' + + 'position: relative;' + + 'resize: both;' + + 'z-index: 2;' + ); + + function on_keyboard_event_closure(name) { + return function (event) { + return fig.key_event(event, name); + }; + } + + canvas_div.addEventListener( + 'keydown', + on_keyboard_event_closure('key_press') + ); + canvas_div.addEventListener( + 'keyup', + on_keyboard_event_closure('key_release') + ); + + this._canvas_extra_style(canvas_div); + this.root.appendChild(canvas_div); + + var canvas = (this.canvas = document.createElement('canvas')); + canvas.classList.add('mpl-canvas'); + canvas.setAttribute( + 'style', + 'box-sizing: content-box;' + + 'pointer-events: none;' + + 'position: relative;' + + 'z-index: 0;' + ); + + this.context = canvas.getContext('2d'); + + var backingStore = + this.context.backingStorePixelRatio || + this.context.webkitBackingStorePixelRatio || + this.context.mozBackingStorePixelRatio || + this.context.msBackingStorePixelRatio || + this.context.oBackingStorePixelRatio || + this.context.backingStorePixelRatio || + 1; + + this.ratio = (window.devicePixelRatio || 1) / backingStore; + + var rubberband_canvas = (this.rubberband_canvas = document.createElement( + 'canvas' + )); + rubberband_canvas.setAttribute( + 'style', + 'box-sizing: content-box;' + + 'left: 0;' + + 'pointer-events: none;' + + 'position: absolute;' + + 'top: 0;' + + 'z-index: 1;' + ); + + // Apply a ponyfill if ResizeObserver is not implemented by browser. + if (this.ResizeObserver === undefined) { + if (window.ResizeObserver !== undefined) { + this.ResizeObserver = window.ResizeObserver; + } else { + var obs = _JSXTOOLS_RESIZE_OBSERVER({}); + this.ResizeObserver = obs.ResizeObserver; + } + } + + this.resizeObserverInstance = new this.ResizeObserver(function (entries) { + var nentries = entries.length; + for (var i = 0; i < nentries; i++) { + var entry = entries[i]; + var width, height; + if (entry.contentBoxSize) { + if (entry.contentBoxSize instanceof Array) { + // Chrome 84 implements new version of spec. + width = entry.contentBoxSize[0].inlineSize; + height = entry.contentBoxSize[0].blockSize; + } else { + // Firefox implements old version of spec. + width = entry.contentBoxSize.inlineSize; + height = entry.contentBoxSize.blockSize; + } + } else { + // Chrome <84 implements even older version of spec. + width = entry.contentRect.width; + height = entry.contentRect.height; + } + + // Keep the size of the canvas and rubber band canvas in sync with + // the canvas container. + if (entry.devicePixelContentBoxSize) { + // Chrome 84 implements new version of spec. + canvas.setAttribute( + 'width', + entry.devicePixelContentBoxSize[0].inlineSize + ); + canvas.setAttribute( + 'height', + entry.devicePixelContentBoxSize[0].blockSize + ); + } else { + canvas.setAttribute('width', width * fig.ratio); + canvas.setAttribute('height', height * fig.ratio); + } + /* This rescales the canvas back to display pixels, so that it + * appears correct on HiDPI screens. */ + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + + rubberband_canvas.setAttribute('width', width); + rubberband_canvas.setAttribute('height', height); + + // And update the size in Python. We ignore the initial 0/0 size + // that occurs as the element is placed into the DOM, which should + // otherwise not happen due to the minimum size styling. + if (fig.ws.readyState == 1 && width != 0 && height != 0) { + fig.request_resize(width, height); + } + } + }); + this.resizeObserverInstance.observe(canvas_div); + + function on_mouse_event_closure(name) { + /* User Agent sniffing is bad, but WebKit is busted: + * https://bugs.webkit.org/show_bug.cgi?id=144526 + * https://bugs.webkit.org/show_bug.cgi?id=181818 + * The worst that happens here is that they get an extra browser + * selection when dragging, if this check fails to catch them. + */ + var UA = navigator.userAgent; + var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA); + if(isWebKit) { + return function (event) { + /* This prevents the web browser from automatically changing to + * the text insertion cursor when the button is pressed. We + * want to control all of the cursor setting manually through + * the 'cursor' event from matplotlib */ + event.preventDefault() + return fig.mouse_event(event, name); + }; + } else { + return function (event) { + return fig.mouse_event(event, name); + }; + } + } + + canvas_div.addEventListener( + 'mousedown', + on_mouse_event_closure('button_press') + ); + canvas_div.addEventListener( + 'mouseup', + on_mouse_event_closure('button_release') + ); + canvas_div.addEventListener( + 'dblclick', + on_mouse_event_closure('dblclick') + ); + // Throttle sequential mouse events to 1 every 20ms. + canvas_div.addEventListener( + 'mousemove', + on_mouse_event_closure('motion_notify') + ); + + canvas_div.addEventListener( + 'mouseenter', + on_mouse_event_closure('figure_enter') + ); + canvas_div.addEventListener( + 'mouseleave', + on_mouse_event_closure('figure_leave') + ); + + canvas_div.addEventListener('wheel', function (event) { + if (event.deltaY < 0) { + event.step = 1; + } else { + event.step = -1; + } + on_mouse_event_closure('scroll')(event); + }); + + canvas_div.appendChild(canvas); + canvas_div.appendChild(rubberband_canvas); + + this.rubberband_context = rubberband_canvas.getContext('2d'); + this.rubberband_context.strokeStyle = '#000000'; + + this._resize_canvas = function (width, height, forward) { + if (forward) { + canvas_div.style.width = width + 'px'; + canvas_div.style.height = height + 'px'; + } + }; + + // Disable right mouse context menu. + canvas_div.addEventListener('contextmenu', function (_e) { + event.preventDefault(); + return false; + }); + + function set_focus() { + canvas.focus(); + canvas_div.focus(); + } + + window.setTimeout(set_focus, 100); +}; + +mpl.figure.prototype._init_toolbar = function () { + var fig = this; + + var toolbar = document.createElement('div'); + toolbar.classList = 'mpl-toolbar'; + this.root.appendChild(toolbar); + + function on_click_closure(name) { + return function (_event) { + return fig.toolbar_button_onclick(name); + }; + } + + function on_mouseover_closure(tooltip) { + return function (event) { + if (!event.currentTarget.disabled) { + return fig.toolbar_button_onmouseover(tooltip); + } + }; + } + + fig.buttons = {}; + var buttonGroup = document.createElement('div'); + buttonGroup.classList = 'mpl-button-group'; + for (var toolbar_ind in mpl.toolbar_items) { + var name = mpl.toolbar_items[toolbar_ind][0]; + var tooltip = mpl.toolbar_items[toolbar_ind][1]; + var image = mpl.toolbar_items[toolbar_ind][2]; + var method_name = mpl.toolbar_items[toolbar_ind][3]; + + if (!name) { + /* Instead of a spacer, we start a new button group. */ + if (buttonGroup.hasChildNodes()) { + toolbar.appendChild(buttonGroup); + } + buttonGroup = document.createElement('div'); + buttonGroup.classList = 'mpl-button-group'; + continue; + } + + var button = (fig.buttons[name] = document.createElement('button')); + button.classList = 'mpl-widget'; + button.setAttribute('role', 'button'); + button.setAttribute('aria-disabled', 'false'); + button.addEventListener('click', on_click_closure(method_name)); + button.addEventListener('mouseover', on_mouseover_closure(tooltip)); + + var icon_img = document.createElement('img'); + icon_img.src = '_images/' + image + '.png'; + icon_img.srcset = '_images/' + image + '_large.png 2x'; + icon_img.alt = tooltip; + button.appendChild(icon_img); + + buttonGroup.appendChild(button); + } + + if (buttonGroup.hasChildNodes()) { + toolbar.appendChild(buttonGroup); + } + + var fmt_picker = document.createElement('select'); + fmt_picker.classList = 'mpl-widget'; + toolbar.appendChild(fmt_picker); + this.format_dropdown = fmt_picker; + + for (var ind in mpl.extensions) { + var fmt = mpl.extensions[ind]; + var option = document.createElement('option'); + option.selected = fmt === mpl.default_extension; + option.innerHTML = fmt; + fmt_picker.appendChild(option); + } + + var status_bar = document.createElement('span'); + status_bar.classList = 'mpl-message'; + toolbar.appendChild(status_bar); + this.message = status_bar; +}; + +mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) { + // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, + // which will in turn request a refresh of the image. + this.send_message('resize', { width: x_pixels, height: y_pixels }); +}; + +mpl.figure.prototype.send_message = function (type, properties) { + properties['type'] = type; + properties['figure_id'] = this.id; + this.ws.send(JSON.stringify(properties)); +}; + +mpl.figure.prototype.send_draw_message = function () { + if (!this.waiting) { + this.waiting = true; + this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id })); + } +}; + +mpl.figure.prototype.handle_save = function (fig, _msg) { + var format_dropdown = fig.format_dropdown; + var format = format_dropdown.options[format_dropdown.selectedIndex].value; + fig.ondownload(fig, format); +}; + +mpl.figure.prototype.handle_resize = function (fig, msg) { + var size = msg['size']; + if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) { + fig._resize_canvas(size[0], size[1], msg['forward']); + fig.send_message('refresh', {}); + } +}; + +mpl.figure.prototype.handle_rubberband = function (fig, msg) { + var x0 = msg['x0'] / fig.ratio; + var y0 = (fig.canvas.height - msg['y0']) / fig.ratio; + var x1 = msg['x1'] / fig.ratio; + var y1 = (fig.canvas.height - msg['y1']) / fig.ratio; + x0 = Math.floor(x0) + 0.5; + y0 = Math.floor(y0) + 0.5; + x1 = Math.floor(x1) + 0.5; + y1 = Math.floor(y1) + 0.5; + var min_x = Math.min(x0, x1); + var min_y = Math.min(y0, y1); + var width = Math.abs(x1 - x0); + var height = Math.abs(y1 - y0); + + fig.rubberband_context.clearRect( + 0, + 0, + fig.canvas.width / fig.ratio, + fig.canvas.height / fig.ratio + ); + + fig.rubberband_context.strokeRect(min_x, min_y, width, height); +}; + +mpl.figure.prototype.handle_figure_label = function (fig, msg) { + // Updates the figure title. + fig.header.textContent = msg['label']; +}; + +mpl.figure.prototype.handle_cursor = function (fig, msg) { + fig.canvas_div.style.cursor = msg['cursor']; +}; + +mpl.figure.prototype.handle_message = function (fig, msg) { + fig.message.textContent = msg['message']; +}; + +mpl.figure.prototype.handle_draw = function (fig, _msg) { + // Request the server to send over a new figure. + fig.send_draw_message(); +}; + +mpl.figure.prototype.handle_image_mode = function (fig, msg) { + fig.image_mode = msg['mode']; +}; + +mpl.figure.prototype.handle_history_buttons = function (fig, msg) { + for (var key in msg) { + if (!(key in fig.buttons)) { + continue; + } + fig.buttons[key].disabled = !msg[key]; + fig.buttons[key].setAttribute('aria-disabled', !msg[key]); + } +}; + +mpl.figure.prototype.handle_navigate_mode = function (fig, msg) { + if (msg['mode'] === 'PAN') { + fig.buttons['Pan'].classList.add('active'); + fig.buttons['Zoom'].classList.remove('active'); + } else if (msg['mode'] === 'ZOOM') { + fig.buttons['Pan'].classList.remove('active'); + fig.buttons['Zoom'].classList.add('active'); + } else { + fig.buttons['Pan'].classList.remove('active'); + fig.buttons['Zoom'].classList.remove('active'); + } +}; + +mpl.figure.prototype.updated_canvas_event = function () { + // Called whenever the canvas gets updated. + this.send_message('ack', {}); +}; + +// A function to construct a web socket function for onmessage handling. +// Called in the figure constructor. +mpl.figure.prototype._make_on_message_function = function (fig) { + return function socket_on_message(evt) { + if (evt.data instanceof Blob) { + var img = evt.data; + if (img.type !== 'image/png') { + /* FIXME: We get "Resource interpreted as Image but + * transferred with MIME type text/plain:" errors on + * Chrome. But how to set the MIME type? It doesn't seem + * to be part of the websocket stream */ + img.type = 'image/png'; + } + + /* Free the memory for the previous frames */ + if (fig.imageObj.src) { + (window.URL || window.webkitURL).revokeObjectURL( + fig.imageObj.src + ); + } + + fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( + img + ); + fig.updated_canvas_event(); + fig.waiting = false; + return; + } else if ( + typeof evt.data === 'string' && + evt.data.slice(0, 21) === 'data:image/png;base64' + ) { + fig.imageObj.src = evt.data; + fig.updated_canvas_event(); + fig.waiting = false; + return; + } + + var msg = JSON.parse(evt.data); + var msg_type = msg['type']; + + // Call the "handle_{type}" callback, which takes + // the figure and JSON message as its only arguments. + try { + var callback = fig['handle_' + msg_type]; + } catch (e) { + console.log( + "No handler for the '" + msg_type + "' message type: ", + msg + ); + return; + } + + if (callback) { + try { + // console.log("Handling '" + msg_type + "' message: ", msg); + callback(fig, msg); + } catch (e) { + console.log( + "Exception inside the 'handler_" + msg_type + "' callback:", + e, + e.stack, + msg + ); + } + } + }; +}; + +function getModifiers(event) { + var mods = []; + if (event.ctrlKey) { + mods.push('ctrl'); + } + if (event.altKey) { + mods.push('alt'); + } + if (event.shiftKey) { + mods.push('shift'); + } + if (event.metaKey) { + mods.push('meta'); + } + return mods; +} + +/* + * return a copy of an object with only non-object keys + * we need this to avoid circular references + * https://stackoverflow.com/a/24161582/3208463 + */ +function simpleKeys(original) { + return Object.keys(original).reduce(function (obj, key) { + if (typeof original[key] !== 'object') { + obj[key] = original[key]; + } + return obj; + }, {}); +} + +mpl.figure.prototype.mouse_event = function (event, name) { + if (name === 'button_press') { + this.canvas.focus(); + this.canvas_div.focus(); + } + + // from https://stackoverflow.com/q/1114465 + var boundingRect = this.canvas.getBoundingClientRect(); + var x = (event.clientX - boundingRect.left) * this.ratio; + var y = (event.clientY - boundingRect.top) * this.ratio; + + this.send_message(name, { + x: x, + y: y, + button: event.button, + step: event.step, + modifiers: getModifiers(event), + guiEvent: simpleKeys(event), + }); + + return false; +}; + +mpl.figure.prototype._key_event_extra = function (_event, _name) { + // Handle any extra behaviour associated with a key event +}; + +mpl.figure.prototype.key_event = function (event, name) { + // Prevent repeat events + if (name === 'key_press') { + if (event.key === this._key) { + return; + } else { + this._key = event.key; + } + } + if (name === 'key_release') { + this._key = null; + } + + var value = ''; + if (event.ctrlKey && event.key !== 'Control') { + value += 'ctrl+'; + } + else if (event.altKey && event.key !== 'Alt') { + value += 'alt+'; + } + else if (event.shiftKey && event.key !== 'Shift') { + value += 'shift+'; + } + + value += 'k' + event.key; + + this._key_event_extra(event, name); + + this.send_message(name, { key: value, guiEvent: simpleKeys(event) }); + return false; +}; + +mpl.figure.prototype.toolbar_button_onclick = function (name) { + if (name === 'download') { + this.handle_save(this, null); + } else { + this.send_message('toolbar_button', { name: name }); + } +}; + +mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) { + this.message.textContent = tooltip; +}; + +///////////////// REMAINING CONTENT GENERATED BY embed_js.py ///////////////// +// prettier-ignore +var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError("Constructor requires 'new' operator");i.set(this,e)}function h(){throw new TypeError("Function is not a constructor")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl_tornado.js b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl_tornado.js new file mode 100644 index 00000000..b3cab8b7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/mpl_tornado.js @@ -0,0 +1,8 @@ +/* This .js file contains functions for matplotlib's built-in + tornado-based server, that are not relevant when embedding WebAgg + in another web application. */ + +/* exported mpl_ondownload */ +function mpl_ondownload(figure, format) { + window.open(figure.id + '/download.' + format, '_blank'); +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/nbagg_mpl.js b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/nbagg_mpl.js new file mode 100644 index 00000000..26d79ff4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/js/nbagg_mpl.js @@ -0,0 +1,275 @@ +/* global mpl */ + +var comm_websocket_adapter = function (comm) { + // Create a "websocket"-like object which calls the given IPython comm + // object with the appropriate methods. Currently this is a non binary + // socket, so there is still some room for performance tuning. + var ws = {}; + + ws.binaryType = comm.kernel.ws.binaryType; + ws.readyState = comm.kernel.ws.readyState; + function updateReadyState(_event) { + if (comm.kernel.ws) { + ws.readyState = comm.kernel.ws.readyState; + } else { + ws.readyState = 3; // Closed state. + } + } + comm.kernel.ws.addEventListener('open', updateReadyState); + comm.kernel.ws.addEventListener('close', updateReadyState); + comm.kernel.ws.addEventListener('error', updateReadyState); + + ws.close = function () { + comm.close(); + }; + ws.send = function (m) { + //console.log('sending', m); + comm.send(m); + }; + // Register the callback with on_msg. + comm.on_msg(function (msg) { + //console.log('receiving', msg['content']['data'], msg); + var data = msg['content']['data']; + if (data['blob'] !== undefined) { + data = { + data: new Blob(msg['buffers'], { type: data['blob'] }), + }; + } + // Pass the mpl event to the overridden (by mpl) onmessage function. + ws.onmessage(data); + }); + return ws; +}; + +mpl.mpl_figure_comm = function (comm, msg) { + // This is the function which gets called when the mpl process + // starts-up an IPython Comm through the "matplotlib" channel. + + var id = msg.content.data.id; + // Get hold of the div created by the display call when the Comm + // socket was opened in Python. + var element = document.getElementById(id); + var ws_proxy = comm_websocket_adapter(comm); + + function ondownload(figure, _format) { + window.open(figure.canvas.toDataURL()); + } + + var fig = new mpl.figure(id, ws_proxy, ondownload, element); + + // Call onopen now - mpl needs it, as it is assuming we've passed it a real + // web socket which is closed, not our websocket->open comm proxy. + ws_proxy.onopen(); + + fig.parent_element = element; + fig.cell_info = mpl.find_output_cell("
    "); + if (!fig.cell_info) { + console.error('Failed to find cell for figure', id, fig); + return; + } + fig.cell_info[0].output_area.element.on( + 'cleared', + { fig: fig }, + fig._remove_fig_handler + ); +}; + +mpl.figure.prototype.handle_close = function (fig, msg) { + var width = fig.canvas.width / fig.ratio; + fig.cell_info[0].output_area.element.off( + 'cleared', + fig._remove_fig_handler + ); + fig.resizeObserverInstance.unobserve(fig.canvas_div); + + // Update the output cell to use the data from the current canvas. + fig.push_to_output(); + var dataURL = fig.canvas.toDataURL(); + // Re-enable the keyboard manager in IPython - without this line, in FF, + // the notebook keyboard shortcuts fail. + IPython.keyboard_manager.enable(); + fig.parent_element.innerHTML = + ''; + fig.close_ws(fig, msg); +}; + +mpl.figure.prototype.close_ws = function (fig, msg) { + fig.send_message('closing', msg); + // fig.ws.close() +}; + +mpl.figure.prototype.push_to_output = function (_remove_interactive) { + // Turn the data on the canvas into data in the output cell. + var width = this.canvas.width / this.ratio; + var dataURL = this.canvas.toDataURL(); + this.cell_info[1]['text/html'] = + ''; +}; + +mpl.figure.prototype.updated_canvas_event = function () { + // Tell IPython that the notebook contents must change. + IPython.notebook.set_dirty(true); + this.send_message('ack', {}); + var fig = this; + // Wait a second, then push the new image to the DOM so + // that it is saved nicely (might be nice to debounce this). + setTimeout(function () { + fig.push_to_output(); + }, 1000); +}; + +mpl.figure.prototype._init_toolbar = function () { + var fig = this; + + var toolbar = document.createElement('div'); + toolbar.classList = 'btn-toolbar'; + this.root.appendChild(toolbar); + + function on_click_closure(name) { + return function (_event) { + return fig.toolbar_button_onclick(name); + }; + } + + function on_mouseover_closure(tooltip) { + return function (event) { + if (!event.currentTarget.disabled) { + return fig.toolbar_button_onmouseover(tooltip); + } + }; + } + + fig.buttons = {}; + var buttonGroup = document.createElement('div'); + buttonGroup.classList = 'btn-group'; + var button; + for (var toolbar_ind in mpl.toolbar_items) { + var name = mpl.toolbar_items[toolbar_ind][0]; + var tooltip = mpl.toolbar_items[toolbar_ind][1]; + var image = mpl.toolbar_items[toolbar_ind][2]; + var method_name = mpl.toolbar_items[toolbar_ind][3]; + + if (!name) { + /* Instead of a spacer, we start a new button group. */ + if (buttonGroup.hasChildNodes()) { + toolbar.appendChild(buttonGroup); + } + buttonGroup = document.createElement('div'); + buttonGroup.classList = 'btn-group'; + continue; + } + + button = fig.buttons[name] = document.createElement('button'); + button.classList = 'btn btn-default'; + button.href = '#'; + button.title = name; + button.innerHTML = ''; + button.addEventListener('click', on_click_closure(method_name)); + button.addEventListener('mouseover', on_mouseover_closure(tooltip)); + buttonGroup.appendChild(button); + } + + if (buttonGroup.hasChildNodes()) { + toolbar.appendChild(buttonGroup); + } + + // Add the status bar. + var status_bar = document.createElement('span'); + status_bar.classList = 'mpl-message pull-right'; + toolbar.appendChild(status_bar); + this.message = status_bar; + + // Add the close button to the window. + var buttongrp = document.createElement('div'); + buttongrp.classList = 'btn-group inline pull-right'; + button = document.createElement('button'); + button.classList = 'btn btn-mini btn-primary'; + button.href = '#'; + button.title = 'Stop Interaction'; + button.innerHTML = ''; + button.addEventListener('click', function (_evt) { + fig.handle_close(fig, {}); + }); + button.addEventListener( + 'mouseover', + on_mouseover_closure('Stop Interaction') + ); + buttongrp.appendChild(button); + var titlebar = this.root.querySelector('.ui-dialog-titlebar'); + titlebar.insertBefore(buttongrp, titlebar.firstChild); +}; + +mpl.figure.prototype._remove_fig_handler = function (event) { + var fig = event.data.fig; + if (event.target !== this) { + // Ignore bubbled events from children. + return; + } + fig.close_ws(fig, {}); +}; + +mpl.figure.prototype._root_extra_style = function (el) { + el.style.boxSizing = 'content-box'; // override notebook setting of border-box. +}; + +mpl.figure.prototype._canvas_extra_style = function (el) { + // this is important to make the div 'focusable + el.setAttribute('tabindex', 0); + // reach out to IPython and tell the keyboard manager to turn it's self + // off when our div gets focus + + // location in version 3 + if (IPython.notebook.keyboard_manager) { + IPython.notebook.keyboard_manager.register_events(el); + } else { + // location in version 2 + IPython.keyboard_manager.register_events(el); + } +}; + +mpl.figure.prototype._key_event_extra = function (event, _name) { + // Check for shift+enter + if (event.shiftKey && event.which === 13) { + this.canvas_div.blur(); + // select the cell after this one + var index = IPython.notebook.find_cell_index(this.cell_info[0]); + IPython.notebook.select(index + 1); + } +}; + +mpl.figure.prototype.handle_save = function (fig, _msg) { + fig.ondownload(fig, null); +}; + +mpl.find_output_cell = function (html_output) { + // Return the cell and output element which can be found *uniquely* in the notebook. + // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" + // IPython event is triggered only after the cells have been serialised, which for + // our purposes (turning an active figure into a static one), is too late. + var cells = IPython.notebook.get_cells(); + var ncells = cells.length; + for (var i = 0; i < ncells; i++) { + var cell = cells[i]; + if (cell.cell_type === 'code') { + for (var j = 0; j < cell.output_area.outputs.length; j++) { + var data = cell.output_area.outputs[j]; + if (data.data) { + // IPython >= 3 moved mimebundle to data attribute of output + data = data.data; + } + if (data['text/html'] === html_output) { + return [cell, data, j]; + } + } + } + } +}; + +// Register the function which deals with the matplotlib target/channel. +// The kernel may be null if the page has been refreshed. +if (IPython.notebook.kernel !== null) { + IPython.notebook.kernel.comm_manager.register_target( + 'matplotlib', + mpl.mpl_figure_comm + ); +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/nbagg_uat.ipynb b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/nbagg_uat.ipynb new file mode 100644 index 00000000..e9fc62bc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/nbagg_uat.ipynb @@ -0,0 +1,631 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from imp import reload" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## UAT for NbAgg backend.\n", + "\n", + "The first line simply reloads matplotlib, uses the nbagg backend and then reloads the backend, just to ensure we have the latest modification to the backend code. Note: The underlying JavaScript will not be updated by this process, so a refresh of the browser after clearing the output and saving is necessary to clear everything fully." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib\n", + "reload(matplotlib)\n", + "\n", + "matplotlib.use('nbagg')\n", + "\n", + "import matplotlib.backends.backend_nbagg\n", + "reload(matplotlib.backends.backend_nbagg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 1 - Simple figure creation using pyplot\n", + "\n", + "Should produce a figure window which is interactive with the pan and zoom buttons. (Do not press the close button, but any others may be used)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.backends.backend_webagg_core\n", + "reload(matplotlib.backends.backend_webagg_core)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "plt.interactive(False)\n", + "\n", + "fig1 = plt.figure()\n", + "plt.plot(range(10))\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 2 - Creation of another figure, without the need to do plt.figure.\n", + "\n", + "As above, a new figure should be created." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot([3, 2, 1])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 3 - Connection info\n", + "\n", + "The printout should show that there are two figures which have active CommSockets, and no figures pending show." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 4 - Closing figures\n", + "\n", + "Closing a specific figure instance should turn the figure into a plain image - the UI should have been removed. In this case, scroll back to the first figure and assert this is the case." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.close(fig1)\n", + "plt.close('all')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 5 - No show without plt.show in non-interactive mode\n", + "\n", + "Simply doing a plt.plot should not show a new figure, nor indeed update an existing one (easily verified in UAT 6).\n", + "The output should simply be a list of Line2D instances." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(range(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 6 - Connection information\n", + "\n", + "We just created a new figure, but didn't show it. Connection info should no longer have \"Figure 1\" (as we closed it in UAT 4) and should have figure 2 and 3, with Figure 3 without any connections. There should be 1 figure pending." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 7 - Show of previously created figure\n", + "\n", + "We should be able to show a figure we've previously created. The following should produce two figure windows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.show()\n", + "plt.figure()\n", + "plt.plot(range(5))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 8 - Interactive mode\n", + "\n", + "In interactive mode, creating a line should result in a figure being shown." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.interactive(True)\n", + "plt.figure()\n", + "plt.plot([3, 2, 1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Subsequent lines should be added to the existing figure, rather than creating a new one." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(range(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calling connection_info in interactive mode should not show any pending figures." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Disable interactive mode again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.interactive(False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 9 - Multiple shows\n", + "\n", + "Unlike most of the other matplotlib backends, we may want to see a figure multiple times (with or without synchronisation between the views, though the former is not yet implemented). Assert that plt.gcf().canvas.manager.reshow() results in another figure window which is synchronised upon pan & zoom." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.gcf().canvas.manager.reshow()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 10 - Saving notebook\n", + "\n", + "Saving the notebook (with CTRL+S or File->Save) should result in the saved notebook having static versions of the figures embedded within. The image should be the last update from user interaction and interactive plotting. (check by converting with ``ipython nbconvert ``)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 11 - Creation of a new figure on second show\n", + "\n", + "Create a figure, show it, then create a new axes and show it. The result should be a new figure.\n", + "\n", + "**BUG: Sometimes this doesn't work - not sure why (@pelson).**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure()\n", + "plt.axes()\n", + "plt.show()\n", + "\n", + "plt.plot([1, 2, 3])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 12 - OO interface\n", + "\n", + "Should produce a new figure and plot it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib.backends.backend_nbagg import new_figure_manager,show\n", + "\n", + "manager = new_figure_manager(1000)\n", + "fig = manager.canvas.figure\n", + "ax = fig.add_subplot(1,1,1)\n", + "ax.plot([1,2,3])\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## UAT 13 - Animation\n", + "\n", + "The following should generate an animated line:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.animation as animation\n", + "import numpy as np\n", + "\n", + "fig, ax = plt.subplots()\n", + "\n", + "x = np.arange(0, 2*np.pi, 0.01) # x-array\n", + "line, = ax.plot(x, np.sin(x))\n", + "\n", + "def animate(i):\n", + " line.set_ydata(np.sin(x+i/10.0)) # update the data\n", + " return line,\n", + "\n", + "#Init only required for blitting to give a clean slate.\n", + "def init():\n", + " line.set_ydata(np.ma.array(x, mask=True))\n", + " return line,\n", + "\n", + "ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,\n", + " interval=100., blit=True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 14 - Keyboard shortcuts in IPython after close of figure\n", + "\n", + "After closing the previous figure (with the close button above the figure) the IPython keyboard shortcuts should still function.\n", + "\n", + "### UAT 15 - Figure face colours\n", + "\n", + "The nbagg honours all colours apart from that of the figure.patch. The two plots below should produce a figure with a red background. There should be no yellow figure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib\n", + "matplotlib.rcParams.update({'figure.facecolor': 'red',\n", + " 'savefig.facecolor': 'yellow'})\n", + "plt.figure()\n", + "plt.plot([3, 2, 1])\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 16 - Events\n", + "\n", + "Pressing any keyboard key or mouse button (or scrolling) should cycle the line while the figure has focus. The figure should have focus by default when it is created and re-gain it by clicking on the canvas. Clicking anywhere outside of the figure should release focus, but moving the mouse out of the figure should not release focus." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import itertools\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0,10,10000)\n", + "y = np.sin(x)\n", + "ln, = ax.plot(x,y)\n", + "evt = []\n", + "colors = iter(itertools.cycle(['r', 'g', 'b', 'k', 'c']))\n", + "def on_event(event):\n", + " if event.name.startswith('key'):\n", + " fig.suptitle('%s: %s' % (event.name, event.key))\n", + " elif event.name == 'scroll_event':\n", + " fig.suptitle('%s: %s' % (event.name, event.step))\n", + " else:\n", + " fig.suptitle('%s: %s' % (event.name, event.button))\n", + " evt.append(event)\n", + " ln.set_color(next(colors))\n", + " fig.canvas.draw()\n", + " fig.canvas.draw_idle()\n", + "\n", + "fig.canvas.mpl_connect('button_press_event', on_event)\n", + "fig.canvas.mpl_connect('button_release_event', on_event)\n", + "fig.canvas.mpl_connect('scroll_event', on_event)\n", + "fig.canvas.mpl_connect('key_press_event', on_event)\n", + "fig.canvas.mpl_connect('key_release_event', on_event)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 17 - Timers\n", + "\n", + "Single-shot timers follow a completely different code path in the nbagg backend than regular timers (such as those used in the animation example above.) The next set of tests ensures that both \"regular\" and \"single-shot\" timers work properly.\n", + "\n", + "The following should show a simple clock that updates twice a second:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "\n", + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "\n", + "def update(text):\n", + " text.set(text=time.ctime())\n", + " text.axes.figure.canvas.draw()\n", + " \n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "timer.start()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, the following should only update once and then stop:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center') \n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.single_shot = True\n", + "timer.start()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the next two examples should never show any visible text at all:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.start()\n", + "timer.stop()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.single_shot = True\n", + "timer.start()\n", + "timer.stop()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 18 - stopping figure when removed from DOM\n", + "\n", + "When the div that contains from the figure is removed from the DOM the figure should shut down it's comm, and if the python-side figure has no more active comms, it should destroy the figure. Repeatedly running the cell below should always have the same figure number" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.plot(range(5))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Running the cell below will re-show the figure. After this, re-running the cell above should result in a new figure number." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig.canvas.manager.reshow()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "### UAT 19 - Blitting\n", + "\n", + "Clicking on the figure should plot a green horizontal line moving up the axes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import itertools\n", + "\n", + "cnt = itertools.count()\n", + "bg = None\n", + "\n", + "def onclick_handle(event):\n", + " \"\"\"Should draw elevating green line on each mouse click\"\"\"\n", + " global bg\n", + " if bg is None:\n", + " bg = ax.figure.canvas.copy_from_bbox(ax.bbox) \n", + " ax.figure.canvas.restore_region(bg)\n", + "\n", + " cur_y = (next(cnt) % 10) * 0.1\n", + " ln.set_ydata([cur_y, cur_y])\n", + " ax.draw_artist(ln)\n", + " ax.figure.canvas.blit(ax.bbox)\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.plot([0, 1], [0, 1], 'r')\n", + "ln, = ax.plot([0, 1], [0, 0], 'g', animated=True)\n", + "plt.show()\n", + "ax.figure.canvas.draw()\n", + "\n", + "ax.figure.canvas.mpl_connect('button_press_event', onclick_handle)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/package.json b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/package.json new file mode 100644 index 00000000..95bd8fdf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/package.json @@ -0,0 +1,18 @@ +{ + "devDependencies": { + "eslint": "^6.8.0", + "eslint-config-prettier": "^6.10.1", + "prettier": "^2.0.2" + }, + "scripts": { + "eslint": "eslint . --fix", + "eslint:check": "eslint .", + "lint": "npm run prettier && npm run eslint", + "lint:check": "npm run prettier:check && npm run eslint:check", + "prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\"", + "prettier:check": "prettier --check \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\"" + }, + "dependencies": { + "@jsxtools/resize-observer": "^1.0.4" + } +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/single_figure.html b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/single_figure.html new file mode 100644 index 00000000..ceaaab00 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/backends/web_backend/single_figure.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + matplotlib + + + +
    +
    + + diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.py new file mode 100644 index 00000000..f310f287 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.py @@ -0,0 +1,594 @@ +""" +A module providing some utility functions regarding Bézier path manipulation. +""" + +from functools import lru_cache +import math +import warnings + +import numpy as np + +from matplotlib import _api + + +# same algorithm as 3.8's math.comb +@np.vectorize +@lru_cache(maxsize=128) +def _comb(n, k): + if k > n: + return 0 + k = min(k, n - k) + i = np.arange(1, k + 1) + return np.prod((n + 1 - i)/i).astype(int) + + +class NonIntersectingPathException(ValueError): + pass + + +# some functions + + +def get_intersection(cx1, cy1, cos_t1, sin_t1, + cx2, cy2, cos_t2, sin_t2): + """ + Return the intersection between the line through (*cx1*, *cy1*) at angle + *t1* and the line through (*cx2*, *cy2*) at angle *t2*. + """ + + # line1 => sin_t1 * (x - cx1) - cos_t1 * (y - cy1) = 0. + # line1 => sin_t1 * x + cos_t1 * y = sin_t1*cx1 - cos_t1*cy1 + + line1_rhs = sin_t1 * cx1 - cos_t1 * cy1 + line2_rhs = sin_t2 * cx2 - cos_t2 * cy2 + + # rhs matrix + a, b = sin_t1, -cos_t1 + c, d = sin_t2, -cos_t2 + + ad_bc = a * d - b * c + if abs(ad_bc) < 1e-12: + raise ValueError("Given lines do not intersect. Please verify that " + "the angles are not equal or differ by 180 degrees.") + + # rhs_inverse + a_, b_ = d, -b + c_, d_ = -c, a + a_, b_, c_, d_ = [k / ad_bc for k in [a_, b_, c_, d_]] + + x = a_ * line1_rhs + b_ * line2_rhs + y = c_ * line1_rhs + d_ * line2_rhs + + return x, y + + +def get_normal_points(cx, cy, cos_t, sin_t, length): + """ + For a line passing through (*cx*, *cy*) and having an angle *t*, return + locations of the two points located along its perpendicular line at the + distance of *length*. + """ + + if length == 0.: + return cx, cy, cx, cy + + cos_t1, sin_t1 = sin_t, -cos_t + cos_t2, sin_t2 = -sin_t, cos_t + + x1, y1 = length * cos_t1 + cx, length * sin_t1 + cy + x2, y2 = length * cos_t2 + cx, length * sin_t2 + cy + + return x1, y1, x2, y2 + + +# BEZIER routines + +# subdividing bezier curve +# http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-sub.html + + +def _de_casteljau1(beta, t): + next_beta = beta[:-1] * (1 - t) + beta[1:] * t + return next_beta + + +def split_de_casteljau(beta, t): + """ + Split a Bézier segment defined by its control points *beta* into two + separate segments divided at *t* and return their control points. + """ + beta = np.asarray(beta) + beta_list = [beta] + while True: + beta = _de_casteljau1(beta, t) + beta_list.append(beta) + if len(beta) == 1: + break + left_beta = [beta[0] for beta in beta_list] + right_beta = [beta[-1] for beta in reversed(beta_list)] + + return left_beta, right_beta + + +def find_bezier_t_intersecting_with_closedpath( + bezier_point_at_t, inside_closedpath, t0=0., t1=1., tolerance=0.01): + """ + Find the intersection of the Bézier curve with a closed path. + + The intersection point *t* is approximated by two parameters *t0*, *t1* + such that *t0* <= *t* <= *t1*. + + Search starts from *t0* and *t1* and uses a simple bisecting algorithm + therefore one of the end points must be inside the path while the other + doesn't. The search stops when the distance of the points parametrized by + *t0* and *t1* gets smaller than the given *tolerance*. + + Parameters + ---------- + bezier_point_at_t : callable + A function returning x, y coordinates of the Bézier at parameter *t*. + It must have the signature:: + + bezier_point_at_t(t: float) -> tuple[float, float] + + inside_closedpath : callable + A function returning True if a given point (x, y) is inside the + closed path. It must have the signature:: + + inside_closedpath(point: tuple[float, float]) -> bool + + t0, t1 : float + Start parameters for the search. + + tolerance : float + Maximal allowed distance between the final points. + + Returns + ------- + t0, t1 : float + The Bézier path parameters. + """ + start = bezier_point_at_t(t0) + end = bezier_point_at_t(t1) + + start_inside = inside_closedpath(start) + end_inside = inside_closedpath(end) + + if start_inside == end_inside and start != end: + raise NonIntersectingPathException( + "Both points are on the same side of the closed path") + + while True: + + # return if the distance is smaller than the tolerance + if np.hypot(start[0] - end[0], start[1] - end[1]) < tolerance: + return t0, t1 + + # calculate the middle point + middle_t = 0.5 * (t0 + t1) + middle = bezier_point_at_t(middle_t) + middle_inside = inside_closedpath(middle) + + if start_inside ^ middle_inside: + t1 = middle_t + end = middle + else: + t0 = middle_t + start = middle + start_inside = middle_inside + + +class BezierSegment: + """ + A d-dimensional Bézier segment. + + Parameters + ---------- + control_points : (N, d) array + Location of the *N* control points. + """ + + def __init__(self, control_points): + self._cpoints = np.asarray(control_points) + self._N, self._d = self._cpoints.shape + self._orders = np.arange(self._N) + coeff = [math.factorial(self._N - 1) + // (math.factorial(i) * math.factorial(self._N - 1 - i)) + for i in range(self._N)] + self._px = (self._cpoints.T * coeff).T + + def __call__(self, t): + """ + Evaluate the Bézier curve at point(s) *t* in [0, 1]. + + Parameters + ---------- + t : (k,) array-like + Points at which to evaluate the curve. + + Returns + ------- + (k, d) array + Value of the curve for each point in *t*. + """ + t = np.asarray(t) + return (np.power.outer(1 - t, self._orders[::-1]) + * np.power.outer(t, self._orders)) @ self._px + + def point_at_t(self, t): + """ + Evaluate the curve at a single point, returning a tuple of *d* floats. + """ + return tuple(self(t)) + + @property + def control_points(self): + """The control points of the curve.""" + return self._cpoints + + @property + def dimension(self): + """The dimension of the curve.""" + return self._d + + @property + def degree(self): + """Degree of the polynomial. One less the number of control points.""" + return self._N - 1 + + @property + def polynomial_coefficients(self): + r""" + The polynomial coefficients of the Bézier curve. + + .. warning:: Follows opposite convention from `numpy.polyval`. + + Returns + ------- + (n+1, d) array + Coefficients after expanding in polynomial basis, where :math:`n` + is the degree of the Bézier curve and :math:`d` its dimension. + These are the numbers (:math:`C_j`) such that the curve can be + written :math:`\sum_{j=0}^n C_j t^j`. + + Notes + ----- + The coefficients are calculated as + + .. math:: + + {n \choose j} \sum_{i=0}^j (-1)^{i+j} {j \choose i} P_i + + where :math:`P_i` are the control points of the curve. + """ + n = self.degree + # matplotlib uses n <= 4. overflow plausible starting around n = 15. + if n > 10: + warnings.warn("Polynomial coefficients formula unstable for high " + "order Bezier curves!", RuntimeWarning) + P = self.control_points + j = np.arange(n+1)[:, None] + i = np.arange(n+1)[None, :] # _comb is non-zero for i <= j + prefactor = (-1)**(i + j) * _comb(j, i) # j on axis 0, i on axis 1 + return _comb(n, j) * prefactor @ P # j on axis 0, self.dimension on 1 + + def axis_aligned_extrema(self): + """ + Return the dimension and location of the curve's interior extrema. + + The extrema are the points along the curve where one of its partial + derivatives is zero. + + Returns + ------- + dims : array of int + Index :math:`i` of the partial derivative which is zero at each + interior extrema. + dzeros : array of float + Of same size as dims. The :math:`t` such that :math:`d/dx_i B(t) = + 0` + """ + n = self.degree + if n <= 1: + return np.array([]), np.array([]) + Cj = self.polynomial_coefficients + dCj = np.arange(1, n+1)[:, None] * Cj[1:] + dims = [] + roots = [] + for i, pi in enumerate(dCj.T): + r = np.roots(pi[::-1]) + roots.append(r) + dims.append(np.full_like(r, i)) + roots = np.concatenate(roots) + dims = np.concatenate(dims) + in_range = np.isreal(roots) & (roots >= 0) & (roots <= 1) + return dims[in_range], np.real(roots)[in_range] + + +def split_bezier_intersecting_with_closedpath( + bezier, inside_closedpath, tolerance=0.01): + """ + Split a Bézier curve into two at the intersection with a closed path. + + Parameters + ---------- + bezier : (N, 2) array-like + Control points of the Bézier segment. See `.BezierSegment`. + inside_closedpath : callable + A function returning True if a given point (x, y) is inside the + closed path. See also `.find_bezier_t_intersecting_with_closedpath`. + tolerance : float + The tolerance for the intersection. See also + `.find_bezier_t_intersecting_with_closedpath`. + + Returns + ------- + left, right + Lists of control points for the two Bézier segments. + """ + + bz = BezierSegment(bezier) + bezier_point_at_t = bz.point_at_t + + t0, t1 = find_bezier_t_intersecting_with_closedpath( + bezier_point_at_t, inside_closedpath, tolerance=tolerance) + + _left, _right = split_de_casteljau(bezier, (t0 + t1) / 2.) + return _left, _right + + +# matplotlib specific + + +def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False): + """ + Divide a path into two segments at the point where ``inside(x, y)`` becomes + False. + """ + from .path import Path + path_iter = path.iter_segments() + + ctl_points, command = next(path_iter) + begin_inside = inside(ctl_points[-2:]) # true if begin point is inside + + ctl_points_old = ctl_points + + iold = 0 + i = 1 + + for ctl_points, command in path_iter: + iold = i + i += len(ctl_points) // 2 + if inside(ctl_points[-2:]) != begin_inside: + bezier_path = np.concatenate([ctl_points_old[-2:], ctl_points]) + break + ctl_points_old = ctl_points + else: + raise ValueError("The path does not intersect with the patch") + + bp = bezier_path.reshape((-1, 2)) + left, right = split_bezier_intersecting_with_closedpath( + bp, inside, tolerance) + if len(left) == 2: + codes_left = [Path.LINETO] + codes_right = [Path.MOVETO, Path.LINETO] + elif len(left) == 3: + codes_left = [Path.CURVE3, Path.CURVE3] + codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3] + elif len(left) == 4: + codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4] + codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4] + else: + raise AssertionError("This should never be reached") + + verts_left = left[1:] + verts_right = right[:] + + if path.codes is None: + path_in = Path(np.concatenate([path.vertices[:i], verts_left])) + path_out = Path(np.concatenate([verts_right, path.vertices[i:]])) + + else: + path_in = Path(np.concatenate([path.vertices[:iold], verts_left]), + np.concatenate([path.codes[:iold], codes_left])) + + path_out = Path(np.concatenate([verts_right, path.vertices[i:]]), + np.concatenate([codes_right, path.codes[i:]])) + + if reorder_inout and not begin_inside: + path_in, path_out = path_out, path_in + + return path_in, path_out + + +def inside_circle(cx, cy, r): + """ + Return a function that checks whether a point is in a circle with center + (*cx*, *cy*) and radius *r*. + + The returned function has the signature:: + + f(xy: tuple[float, float]) -> bool + """ + r2 = r ** 2 + + def _f(xy): + x, y = xy + return (x - cx) ** 2 + (y - cy) ** 2 < r2 + return _f + + +# quadratic Bezier lines + +def get_cos_sin(x0, y0, x1, y1): + dx, dy = x1 - x0, y1 - y0 + d = (dx * dx + dy * dy) ** .5 + # Account for divide by zero + if d == 0: + return 0.0, 0.0 + return dx / d, dy / d + + +def check_if_parallel(dx1, dy1, dx2, dy2, tolerance=1.e-5): + """ + Check if two lines are parallel. + + Parameters + ---------- + dx1, dy1, dx2, dy2 : float + The gradients *dy*/*dx* of the two lines. + tolerance : float + The angular tolerance in radians up to which the lines are considered + parallel. + + Returns + ------- + is_parallel + - 1 if two lines are parallel in same direction. + - -1 if two lines are parallel in opposite direction. + - False otherwise. + """ + theta1 = np.arctan2(dx1, dy1) + theta2 = np.arctan2(dx2, dy2) + dtheta = abs(theta1 - theta2) + if dtheta < tolerance: + return 1 + elif abs(dtheta - np.pi) < tolerance: + return -1 + else: + return False + + +def get_parallels(bezier2, width): + """ + Given the quadratic Bézier control points *bezier2*, returns + control points of quadratic Bézier lines roughly parallel to given + one separated by *width*. + """ + + # The parallel Bezier lines are constructed by following ways. + # c1 and c2 are control points representing the start and end of the + # Bezier line. + # cm is the middle point + + c1x, c1y = bezier2[0] + cmx, cmy = bezier2[1] + c2x, c2y = bezier2[2] + + parallel_test = check_if_parallel(c1x - cmx, c1y - cmy, + cmx - c2x, cmy - c2y) + + if parallel_test == -1: + _api.warn_external( + "Lines do not intersect. A straight line is used instead.") + cos_t1, sin_t1 = get_cos_sin(c1x, c1y, c2x, c2y) + cos_t2, sin_t2 = cos_t1, sin_t1 + else: + # t1 and t2 is the angle between c1 and cm, cm, c2. They are + # also an angle of the tangential line of the path at c1 and c2 + cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy) + cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c2x, c2y) + + # find c1_left, c1_right which are located along the lines + # through c1 and perpendicular to the tangential lines of the + # Bezier path at a distance of width. Same thing for c2_left and + # c2_right with respect to c2. + c1x_left, c1y_left, c1x_right, c1y_right = ( + get_normal_points(c1x, c1y, cos_t1, sin_t1, width) + ) + c2x_left, c2y_left, c2x_right, c2y_right = ( + get_normal_points(c2x, c2y, cos_t2, sin_t2, width) + ) + + # find cm_left which is the intersecting point of a line through + # c1_left with angle t1 and a line through c2_left with angle + # t2. Same with cm_right. + try: + cmx_left, cmy_left = get_intersection(c1x_left, c1y_left, cos_t1, + sin_t1, c2x_left, c2y_left, + cos_t2, sin_t2) + cmx_right, cmy_right = get_intersection(c1x_right, c1y_right, cos_t1, + sin_t1, c2x_right, c2y_right, + cos_t2, sin_t2) + except ValueError: + # Special case straight lines, i.e., angle between two lines is + # less than the threshold used by get_intersection (we don't use + # check_if_parallel as the threshold is not the same). + cmx_left, cmy_left = ( + 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left) + ) + cmx_right, cmy_right = ( + 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right) + ) + + # the parallel Bezier lines are created with control points of + # [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right] + path_left = [(c1x_left, c1y_left), + (cmx_left, cmy_left), + (c2x_left, c2y_left)] + path_right = [(c1x_right, c1y_right), + (cmx_right, cmy_right), + (c2x_right, c2y_right)] + + return path_left, path_right + + +def find_control_points(c1x, c1y, mmx, mmy, c2x, c2y): + """ + Find control points of the Bézier curve passing through (*c1x*, *c1y*), + (*mmx*, *mmy*), and (*c2x*, *c2y*), at parametric values 0, 0.5, and 1. + """ + cmx = .5 * (4 * mmx - (c1x + c2x)) + cmy = .5 * (4 * mmy - (c1y + c2y)) + return [(c1x, c1y), (cmx, cmy), (c2x, c2y)] + + +def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.): + """ + Being similar to `get_parallels`, returns control points of two quadratic + Bézier lines having a width roughly parallel to given one separated by + *width*. + """ + + # c1, cm, c2 + c1x, c1y = bezier2[0] + cmx, cmy = bezier2[1] + c3x, c3y = bezier2[2] + + # t1 and t2 is the angle between c1 and cm, cm, c3. + # They are also an angle of the tangential line of the path at c1 and c3 + cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy) + cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c3x, c3y) + + # find c1_left, c1_right which are located along the lines + # through c1 and perpendicular to the tangential lines of the + # Bezier path at a distance of width. Same thing for c3_left and + # c3_right with respect to c3. + c1x_left, c1y_left, c1x_right, c1y_right = ( + get_normal_points(c1x, c1y, cos_t1, sin_t1, width * w1) + ) + c3x_left, c3y_left, c3x_right, c3y_right = ( + get_normal_points(c3x, c3y, cos_t2, sin_t2, width * w2) + ) + + # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and + # c12-c23 + c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5 + c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5 + c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5 + + # tangential angle of c123 (angle between c12 and c23) + cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y) + + c123x_left, c123y_left, c123x_right, c123y_right = ( + get_normal_points(c123x, c123y, cos_t123, sin_t123, width * wm) + ) + + path_left = find_control_points(c1x_left, c1y_left, + c123x_left, c123y_left, + c3x_left, c3y_left) + path_right = find_control_points(c1x_right, c1y_right, + c123x_right, c123y_right, + c3x_right, c3y_right) + + return path_left, path_right diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.pyi new file mode 100644 index 00000000..ad82b873 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/bezier.pyi @@ -0,0 +1,74 @@ +from collections.abc import Callable +from typing import Literal + +import numpy as np +from numpy.typing import ArrayLike + +from .path import Path + +class NonIntersectingPathException(ValueError): ... + +def get_intersection( + cx1: float, + cy1: float, + cos_t1: float, + sin_t1: float, + cx2: float, + cy2: float, + cos_t2: float, + sin_t2: float, +) -> tuple[float, float]: ... +def get_normal_points( + cx: float, cy: float, cos_t: float, sin_t: float, length: float +) -> tuple[float, float, float, float]: ... +def split_de_casteljau(beta: ArrayLike, t: float) -> tuple[np.ndarray, np.ndarray]: ... +def find_bezier_t_intersecting_with_closedpath( + bezier_point_at_t: Callable[[float], tuple[float, float]], + inside_closedpath: Callable[[tuple[float, float]], bool], + t0: float = ..., + t1: float = ..., + tolerance: float = ..., +) -> tuple[float, float]: ... + +# TODO make generic over d, the dimension? ndarraydim +class BezierSegment: + def __init__(self, control_points: ArrayLike) -> None: ... + def __call__(self, t: ArrayLike) -> np.ndarray: ... + def point_at_t(self, t: float) -> tuple[float, ...]: ... + @property + def control_points(self) -> np.ndarray: ... + @property + def dimension(self) -> int: ... + @property + def degree(self) -> int: ... + @property + def polynomial_coefficients(self) -> np.ndarray: ... + def axis_aligned_extrema(self) -> tuple[np.ndarray, np.ndarray]: ... + +def split_bezier_intersecting_with_closedpath( + bezier: ArrayLike, + inside_closedpath: Callable[[tuple[float, float]], bool], + tolerance: float = ..., +) -> tuple[np.ndarray, np.ndarray]: ... +def split_path_inout( + path: Path, + inside: Callable[[tuple[float, float]], bool], + tolerance: float = ..., + reorder_inout: bool = ..., +) -> tuple[Path, Path]: ... +def inside_circle( + cx: float, cy: float, r: float +) -> Callable[[tuple[float, float]], bool]: ... +def get_cos_sin(x0: float, y0: float, x1: float, y1: float) -> tuple[float, float]: ... +def check_if_parallel( + dx1: float, dy1: float, dx2: float, dy2: float, tolerance: float = ... +) -> Literal[-1, False, 1]: ... +def get_parallels( + bezier2: ArrayLike, width: float +) -> tuple[list[tuple[float, float]], list[tuple[float, float]]]: ... +def find_control_points( + c1x: float, c1y: float, mmx: float, mmy: float, c2x: float, c2y: float +) -> list[tuple[float, float]]: ... +def make_wedged_bezier2( + bezier2: ArrayLike, width: float, w1: float = ..., wm: float = ..., w2: float = ... +) -> tuple[list[tuple[float, float]], list[tuple[float, float]]]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/category.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/category.py new file mode 100644 index 00000000..4ac2379e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/category.py @@ -0,0 +1,233 @@ +""" +Plotting of string "category" data: ``plot(['d', 'f', 'a'], [1, 2, 3])`` will +plot three points with x-axis values of 'd', 'f', 'a'. + +See :doc:`/gallery/lines_bars_and_markers/categorical_variables` for an +example. + +The module uses Matplotlib's `matplotlib.units` mechanism to convert from +strings to integers and provides a tick locator, a tick formatter, and the +`.UnitData` class that creates and stores the string-to-integer mapping. +""" + +from collections import OrderedDict +import dateutil.parser +import itertools +import logging + +import numpy as np + +from matplotlib import _api, ticker, units + + +_log = logging.getLogger(__name__) + + +class StrCategoryConverter(units.ConversionInterface): + @staticmethod + def convert(value, unit, axis): + """ + Convert strings in *value* to floats using mapping information stored + in the *unit* object. + + Parameters + ---------- + value : str or iterable + Value or list of values to be converted. + unit : `.UnitData` + An object mapping strings to integers. + axis : `~matplotlib.axis.Axis` + The axis on which the converted value is plotted. + + .. note:: *axis* is unused. + + Returns + ------- + float or `~numpy.ndarray` of float + """ + if unit is None: + raise ValueError( + 'Missing category information for StrCategoryConverter; ' + 'this might be caused by unintendedly mixing categorical and ' + 'numeric data') + StrCategoryConverter._validate_unit(unit) + # dtype = object preserves numerical pass throughs + values = np.atleast_1d(np.array(value, dtype=object)) + # force an update so it also does type checking + unit.update(values) + return np.vectorize(unit._mapping.__getitem__, otypes=[float])(values) + + @staticmethod + def axisinfo(unit, axis): + """ + Set the default axis ticks and labels. + + Parameters + ---------- + unit : `.UnitData` + object string unit information for value + axis : `~matplotlib.axis.Axis` + axis for which information is being set + + .. note:: *axis* is not used + + Returns + ------- + `~matplotlib.units.AxisInfo` + Information to support default tick labeling + + """ + StrCategoryConverter._validate_unit(unit) + # locator and formatter take mapping dict because + # args need to be pass by reference for updates + majloc = StrCategoryLocator(unit._mapping) + majfmt = StrCategoryFormatter(unit._mapping) + return units.AxisInfo(majloc=majloc, majfmt=majfmt) + + @staticmethod + def default_units(data, axis): + """ + Set and update the `~matplotlib.axis.Axis` units. + + Parameters + ---------- + data : str or iterable of str + axis : `~matplotlib.axis.Axis` + axis on which the data is plotted + + Returns + ------- + `.UnitData` + object storing string to integer mapping + """ + # the conversion call stack is default_units -> axis_info -> convert + if axis.units is None: + axis.set_units(UnitData(data)) + else: + axis.units.update(data) + return axis.units + + @staticmethod + def _validate_unit(unit): + if not hasattr(unit, '_mapping'): + raise ValueError( + f'Provided unit "{unit}" is not valid for a categorical ' + 'converter, as it does not have a _mapping attribute.') + + +class StrCategoryLocator(ticker.Locator): + """Tick at every integer mapping of the string data.""" + def __init__(self, units_mapping): + """ + Parameters + ---------- + units_mapping : dict + Mapping of category names (str) to indices (int). + """ + self._units = units_mapping + + def __call__(self): + # docstring inherited + return list(self._units.values()) + + def tick_values(self, vmin, vmax): + # docstring inherited + return self() + + +class StrCategoryFormatter(ticker.Formatter): + """String representation of the data at every tick.""" + def __init__(self, units_mapping): + """ + Parameters + ---------- + units_mapping : dict + Mapping of category names (str) to indices (int). + """ + self._units = units_mapping + + def __call__(self, x, pos=None): + # docstring inherited + return self.format_ticks([x])[0] + + def format_ticks(self, values): + # docstring inherited + r_mapping = {v: self._text(k) for k, v in self._units.items()} + return [r_mapping.get(round(val), '') for val in values] + + @staticmethod + def _text(value): + """Convert text values into utf-8 or ascii strings.""" + if isinstance(value, bytes): + value = value.decode(encoding='utf-8') + elif not isinstance(value, str): + value = str(value) + return value + + +class UnitData: + def __init__(self, data=None): + """ + Create mapping between unique categorical values and integer ids. + + Parameters + ---------- + data : iterable + sequence of string values + """ + self._mapping = OrderedDict() + self._counter = itertools.count() + if data is not None: + self.update(data) + + @staticmethod + def _str_is_convertible(val): + """ + Helper method to check whether a string can be parsed as float or date. + """ + try: + float(val) + except ValueError: + try: + dateutil.parser.parse(val) + except (ValueError, TypeError): + # TypeError if dateutil >= 2.8.1 else ValueError + return False + return True + + def update(self, data): + """ + Map new values to integer identifiers. + + Parameters + ---------- + data : iterable of str or bytes + + Raises + ------ + TypeError + If elements in *data* are neither str nor bytes. + """ + data = np.atleast_1d(np.array(data, dtype=object)) + # check if convertible to number: + convertible = True + for val in OrderedDict.fromkeys(data): + # OrderedDict just iterates over unique values in data. + _api.check_isinstance((str, bytes), value=val) + if convertible: + # this will only be called so long as convertible is True. + convertible = self._str_is_convertible(val) + if val not in self._mapping: + self._mapping[val] = next(self._counter) + if data.size and convertible: + _log.info('Using categorical units to plot a list of strings ' + 'that are all parsable as floats or dates. If these ' + 'strings should be plotted as numbers, cast to the ' + 'appropriate data type before plotting.') + + +# Register the converter with Matplotlib's unit framework +units.registry[str] = StrCategoryConverter() +units.registry[np.str_] = StrCategoryConverter() +units.registry[bytes] = StrCategoryConverter() +units.registry[np.bytes_] = StrCategoryConverter() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.py new file mode 100644 index 00000000..f02486a0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.py @@ -0,0 +1,2350 @@ +""" +A collection of utility functions and classes. Originally, many +(but not all) were from the Python Cookbook -- hence the name cbook. +""" + +import collections +import collections.abc +import contextlib +import functools +import gzip +import itertools +import math +import operator +import os +from pathlib import Path +import shlex +import subprocess +import sys +import time +import traceback +import types +import weakref + +import numpy as np + +try: + from numpy.exceptions import VisibleDeprecationWarning # numpy >= 1.25 +except ImportError: + from numpy import VisibleDeprecationWarning + +import matplotlib +from matplotlib import _api, _c_internal_utils + + +def _get_running_interactive_framework(): + """ + Return the interactive framework whose event loop is currently running, if + any, or "headless" if no event loop can be started, or None. + + Returns + ------- + Optional[str] + One of the following values: "qt", "gtk3", "gtk4", "wx", "tk", + "macosx", "headless", ``None``. + """ + # Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as + # entries can also have been explicitly set to None. + QtWidgets = ( + sys.modules.get("PyQt6.QtWidgets") + or sys.modules.get("PySide6.QtWidgets") + or sys.modules.get("PyQt5.QtWidgets") + or sys.modules.get("PySide2.QtWidgets") + ) + if QtWidgets and QtWidgets.QApplication.instance(): + return "qt" + Gtk = sys.modules.get("gi.repository.Gtk") + if Gtk: + if Gtk.MAJOR_VERSION == 4: + from gi.repository import GLib + if GLib.main_depth(): + return "gtk4" + if Gtk.MAJOR_VERSION == 3 and Gtk.main_level(): + return "gtk3" + wx = sys.modules.get("wx") + if wx and wx.GetApp(): + return "wx" + tkinter = sys.modules.get("tkinter") + if tkinter: + codes = {tkinter.mainloop.__code__, tkinter.Misc.mainloop.__code__} + for frame in sys._current_frames().values(): + while frame: + if frame.f_code in codes: + return "tk" + frame = frame.f_back + # premetively break reference cycle between locals and the frame + del frame + macosx = sys.modules.get("matplotlib.backends._macosx") + if macosx and macosx.event_loop_is_running(): + return "macosx" + if not _c_internal_utils.display_is_valid(): + return "headless" + return None + + +def _exception_printer(exc): + if _get_running_interactive_framework() in ["headless", None]: + raise exc + else: + traceback.print_exc() + + +class _StrongRef: + """ + Wrapper similar to a weakref, but keeping a strong reference to the object. + """ + + def __init__(self, obj): + self._obj = obj + + def __call__(self): + return self._obj + + def __eq__(self, other): + return isinstance(other, _StrongRef) and self._obj == other._obj + + def __hash__(self): + return hash(self._obj) + + +def _weak_or_strong_ref(func, callback): + """ + Return a `WeakMethod` wrapping *func* if possible, else a `_StrongRef`. + """ + try: + return weakref.WeakMethod(func, callback) + except TypeError: + return _StrongRef(func) + + +class CallbackRegistry: + """ + Handle registering, processing, blocking, and disconnecting + for a set of signals and callbacks: + + >>> def oneat(x): + ... print('eat', x) + >>> def ondrink(x): + ... print('drink', x) + + >>> from matplotlib.cbook import CallbackRegistry + >>> callbacks = CallbackRegistry() + + >>> id_eat = callbacks.connect('eat', oneat) + >>> id_drink = callbacks.connect('drink', ondrink) + + >>> callbacks.process('drink', 123) + drink 123 + >>> callbacks.process('eat', 456) + eat 456 + >>> callbacks.process('be merry', 456) # nothing will be called + + >>> callbacks.disconnect(id_eat) + >>> callbacks.process('eat', 456) # nothing will be called + + >>> with callbacks.blocked(signal='drink'): + ... callbacks.process('drink', 123) # nothing will be called + >>> callbacks.process('drink', 123) + drink 123 + + In practice, one should always disconnect all callbacks when they are + no longer needed to avoid dangling references (and thus memory leaks). + However, real code in Matplotlib rarely does so, and due to its design, + it is rather difficult to place this kind of code. To get around this, + and prevent this class of memory leaks, we instead store weak references + to bound methods only, so when the destination object needs to die, the + CallbackRegistry won't keep it alive. + + Parameters + ---------- + exception_handler : callable, optional + If not None, *exception_handler* must be a function that takes an + `Exception` as single parameter. It gets called with any `Exception` + raised by the callbacks during `CallbackRegistry.process`, and may + either re-raise the exception or handle it in another manner. + + The default handler prints the exception (with `traceback.print_exc`) if + an interactive event loop is running; it re-raises the exception if no + interactive event loop is running. + + signals : list, optional + If not None, *signals* is a list of signals that this registry handles: + attempting to `process` or to `connect` to a signal not in the list + throws a `ValueError`. The default, None, does not restrict the + handled signals. + """ + + # We maintain two mappings: + # callbacks: signal -> {cid -> weakref-to-callback} + # _func_cid_map: signal -> {weakref-to-callback -> cid} + + def __init__(self, exception_handler=_exception_printer, *, signals=None): + self._signals = None if signals is None else list(signals) # Copy it. + self.exception_handler = exception_handler + self.callbacks = {} + self._cid_gen = itertools.count() + self._func_cid_map = {} + # A hidden variable that marks cids that need to be pickled. + self._pickled_cids = set() + + def __getstate__(self): + return { + **vars(self), + # In general, callbacks may not be pickled, so we just drop them, + # unless directed otherwise by self._pickled_cids. + "callbacks": {s: {cid: proxy() for cid, proxy in d.items() + if cid in self._pickled_cids} + for s, d in self.callbacks.items()}, + # It is simpler to reconstruct this from callbacks in __setstate__. + "_func_cid_map": None, + "_cid_gen": next(self._cid_gen) + } + + def __setstate__(self, state): + cid_count = state.pop('_cid_gen') + vars(self).update(state) + self.callbacks = { + s: {cid: _weak_or_strong_ref(func, self._remove_proxy) + for cid, func in d.items()} + for s, d in self.callbacks.items()} + self._func_cid_map = { + s: {proxy: cid for cid, proxy in d.items()} + for s, d in self.callbacks.items()} + self._cid_gen = itertools.count(cid_count) + + def connect(self, signal, func): + """Register *func* to be called when signal *signal* is generated.""" + if self._signals is not None: + _api.check_in_list(self._signals, signal=signal) + self._func_cid_map.setdefault(signal, {}) + proxy = _weak_or_strong_ref(func, self._remove_proxy) + if proxy in self._func_cid_map[signal]: + return self._func_cid_map[signal][proxy] + cid = next(self._cid_gen) + self._func_cid_map[signal][proxy] = cid + self.callbacks.setdefault(signal, {}) + self.callbacks[signal][cid] = proxy + return cid + + def _connect_picklable(self, signal, func): + """ + Like `.connect`, but the callback is kept when pickling/unpickling. + + Currently internal-use only. + """ + cid = self.connect(signal, func) + self._pickled_cids.add(cid) + return cid + + # Keep a reference to sys.is_finalizing, as sys may have been cleared out + # at that point. + def _remove_proxy(self, proxy, *, _is_finalizing=sys.is_finalizing): + if _is_finalizing(): + # Weakrefs can't be properly torn down at that point anymore. + return + for signal, proxy_to_cid in list(self._func_cid_map.items()): + cid = proxy_to_cid.pop(proxy, None) + if cid is not None: + del self.callbacks[signal][cid] + self._pickled_cids.discard(cid) + break + else: + # Not found + return + # Clean up empty dicts + if len(self.callbacks[signal]) == 0: + del self.callbacks[signal] + del self._func_cid_map[signal] + + def disconnect(self, cid): + """ + Disconnect the callback registered with callback id *cid*. + + No error is raised if such a callback does not exist. + """ + self._pickled_cids.discard(cid) + # Clean up callbacks + for signal, cid_to_proxy in list(self.callbacks.items()): + proxy = cid_to_proxy.pop(cid, None) + if proxy is not None: + break + else: + # Not found + return + + proxy_to_cid = self._func_cid_map[signal] + for current_proxy, current_cid in list(proxy_to_cid.items()): + if current_cid == cid: + assert proxy is current_proxy + del proxy_to_cid[current_proxy] + # Clean up empty dicts + if len(self.callbacks[signal]) == 0: + del self.callbacks[signal] + del self._func_cid_map[signal] + + def process(self, s, *args, **kwargs): + """ + Process signal *s*. + + All of the functions registered to receive callbacks on *s* will be + called with ``*args`` and ``**kwargs``. + """ + if self._signals is not None: + _api.check_in_list(self._signals, signal=s) + for ref in list(self.callbacks.get(s, {}).values()): + func = ref() + if func is not None: + try: + func(*args, **kwargs) + # this does not capture KeyboardInterrupt, SystemExit, + # and GeneratorExit + except Exception as exc: + if self.exception_handler is not None: + self.exception_handler(exc) + else: + raise + + @contextlib.contextmanager + def blocked(self, *, signal=None): + """ + Block callback signals from being processed. + + A context manager to temporarily block/disable callback signals + from being processed by the registered listeners. + + Parameters + ---------- + signal : str, optional + The callback signal to block. The default is to block all signals. + """ + orig = self.callbacks + try: + if signal is None: + # Empty out the callbacks + self.callbacks = {} + else: + # Only remove the specific signal + self.callbacks = {k: orig[k] for k in orig if k != signal} + yield + finally: + self.callbacks = orig + + +class silent_list(list): + """ + A list with a short ``repr()``. + + This is meant to be used for a homogeneous list of artists, so that they + don't cause long, meaningless output. + + Instead of :: + + [, + , + ] + + one will get :: + +
    + + If ``self.type`` is None, the type name is obtained from the first item in + the list (if any). + """ + + def __init__(self, type, seq=None): + self.type = type + if seq is not None: + self.extend(seq) + + def __repr__(self): + if self.type is not None or len(self) != 0: + tp = self.type if self.type is not None else type(self[0]).__name__ + return f"" + else: + return "" + + +def _local_over_kwdict( + local_var, kwargs, *keys, + warning_cls=_api.MatplotlibDeprecationWarning): + out = local_var + for key in keys: + kwarg_val = kwargs.pop(key, None) + if kwarg_val is not None: + if out is None: + out = kwarg_val + else: + _api.warn_external(f'"{key}" keyword argument will be ignored', + warning_cls) + return out + + +def strip_math(s): + """ + Remove latex formatting from mathtext. + + Only handles fully math and fully non-math strings. + """ + if len(s) >= 2 and s[0] == s[-1] == "$": + s = s[1:-1] + for tex, plain in [ + (r"\times", "x"), # Specifically for Formatter support. + (r"\mathdefault", ""), + (r"\rm", ""), + (r"\cal", ""), + (r"\tt", ""), + (r"\it", ""), + ("\\", ""), + ("{", ""), + ("}", ""), + ]: + s = s.replace(tex, plain) + return s + + +def _strip_comment(s): + """Strip everything from the first unquoted #.""" + pos = 0 + while True: + quote_pos = s.find('"', pos) + hash_pos = s.find('#', pos) + if quote_pos < 0: + without_comment = s if hash_pos < 0 else s[:hash_pos] + return without_comment.strip() + elif 0 <= hash_pos < quote_pos: + return s[:hash_pos].strip() + else: + closing_quote_pos = s.find('"', quote_pos + 1) + if closing_quote_pos < 0: + raise ValueError( + f"Missing closing quote in: {s!r}. If you need a double-" + 'quote inside a string, use escaping: e.g. "the \" char"') + pos = closing_quote_pos + 1 # behind closing quote + + +def is_writable_file_like(obj): + """Return whether *obj* looks like a file object with a *write* method.""" + return callable(getattr(obj, 'write', None)) + + +def file_requires_unicode(x): + """ + Return whether the given writable file-like object requires Unicode to be + written to it. + """ + try: + x.write(b'') + except TypeError: + return True + else: + return False + + +def to_filehandle(fname, flag='r', return_opened=False, encoding=None): + """ + Convert a path to an open file handle or pass-through a file-like object. + + Consider using `open_file_cm` instead, as it allows one to properly close + newly created file objects more easily. + + Parameters + ---------- + fname : str or path-like or file-like + If `str` or `os.PathLike`, the file is opened using the flags specified + by *flag* and *encoding*. If a file-like object, it is passed through. + flag : str, default: 'r' + Passed as the *mode* argument to `open` when *fname* is `str` or + `os.PathLike`; ignored if *fname* is file-like. + return_opened : bool, default: False + If True, return both the file object and a boolean indicating whether + this was a new file (that the caller needs to close). If False, return + only the new file. + encoding : str or None, default: None + Passed as the *mode* argument to `open` when *fname* is `str` or + `os.PathLike`; ignored if *fname* is file-like. + + Returns + ------- + fh : file-like + opened : bool + *opened* is only returned if *return_opened* is True. + """ + if isinstance(fname, os.PathLike): + fname = os.fspath(fname) + if isinstance(fname, str): + if fname.endswith('.gz'): + fh = gzip.open(fname, flag) + elif fname.endswith('.bz2'): + # python may not be compiled with bz2 support, + # bury import until we need it + import bz2 + fh = bz2.BZ2File(fname, flag) + else: + fh = open(fname, flag, encoding=encoding) + opened = True + elif hasattr(fname, 'seek'): + fh = fname + opened = False + else: + raise ValueError('fname must be a PathLike or file handle') + if return_opened: + return fh, opened + return fh + + +def open_file_cm(path_or_file, mode="r", encoding=None): + r"""Pass through file objects and context-manage path-likes.""" + fh, opened = to_filehandle(path_or_file, mode, True, encoding) + return fh if opened else contextlib.nullcontext(fh) + + +def is_scalar_or_string(val): + """Return whether the given object is a scalar or string like.""" + return isinstance(val, str) or not np.iterable(val) + + +@_api.delete_parameter( + "3.8", "np_load", alternative="open(get_sample_data(..., asfileobj=False))") +def get_sample_data(fname, asfileobj=True, *, np_load=True): + """ + Return a sample data file. *fname* is a path relative to the + :file:`mpl-data/sample_data` directory. If *asfileobj* is `True` + return a file object, otherwise just a file path. + + Sample data files are stored in the 'mpl-data/sample_data' directory within + the Matplotlib package. + + If the filename ends in .gz, the file is implicitly ungzipped. If the + filename ends with .npy or .npz, and *asfileobj* is `True`, the file is + loaded with `numpy.load`. + """ + path = _get_data_path('sample_data', fname) + if asfileobj: + suffix = path.suffix.lower() + if suffix == '.gz': + return gzip.open(path) + elif suffix in ['.npy', '.npz']: + if np_load: + return np.load(path) + else: + return path.open('rb') + elif suffix in ['.csv', '.xrc', '.txt']: + return path.open('r') + else: + return path.open('rb') + else: + return str(path) + + +def _get_data_path(*args): + """ + Return the `pathlib.Path` to a resource file provided by Matplotlib. + + ``*args`` specify a path relative to the base data path. + """ + return Path(matplotlib.get_data_path(), *args) + + +def flatten(seq, scalarp=is_scalar_or_string): + """ + Return a generator of flattened nested containers. + + For example: + + >>> from matplotlib.cbook import flatten + >>> l = (('John', ['Hunter']), (1, 23), [[([42, (5, 23)], )]]) + >>> print(list(flatten(l))) + ['John', 'Hunter', 1, 23, 42, 5, 23] + + By: Composite of Holger Krekel and Luther Blissett + From: https://code.activestate.com/recipes/121294/ + and Recipe 1.12 in cookbook + """ + for item in seq: + if scalarp(item) or item is None: + yield item + else: + yield from flatten(item, scalarp) + + +@_api.deprecated("3.8") +class Stack: + """ + Stack of elements with a movable cursor. + + Mimics home/back/forward in a web browser. + """ + + def __init__(self, default=None): + self.clear() + self._default = default + + def __call__(self): + """Return the current element, or None.""" + if not self._elements: + return self._default + else: + return self._elements[self._pos] + + def __len__(self): + return len(self._elements) + + def __getitem__(self, ind): + return self._elements[ind] + + def forward(self): + """Move the position forward and return the current element.""" + self._pos = min(self._pos + 1, len(self._elements) - 1) + return self() + + def back(self): + """Move the position back and return the current element.""" + if self._pos > 0: + self._pos -= 1 + return self() + + def push(self, o): + """ + Push *o* to the stack at current position. Discard all later elements. + + *o* is returned. + """ + self._elements = self._elements[:self._pos + 1] + [o] + self._pos = len(self._elements) - 1 + return self() + + def home(self): + """ + Push the first element onto the top of the stack. + + The first element is returned. + """ + if not self._elements: + return + self.push(self._elements[0]) + return self() + + def empty(self): + """Return whether the stack is empty.""" + return len(self._elements) == 0 + + def clear(self): + """Empty the stack.""" + self._pos = -1 + self._elements = [] + + def bubble(self, o): + """ + Raise all references of *o* to the top of the stack, and return it. + + Raises + ------ + ValueError + If *o* is not in the stack. + """ + if o not in self._elements: + raise ValueError('Given element not contained in the stack') + old_elements = self._elements.copy() + self.clear() + top_elements = [] + for elem in old_elements: + if elem == o: + top_elements.append(elem) + else: + self.push(elem) + for _ in top_elements: + self.push(o) + return o + + def remove(self, o): + """ + Remove *o* from the stack. + + Raises + ------ + ValueError + If *o* is not in the stack. + """ + if o not in self._elements: + raise ValueError('Given element not contained in the stack') + old_elements = self._elements.copy() + self.clear() + for elem in old_elements: + if elem != o: + self.push(elem) + + +class _Stack: + """ + Stack of elements with a movable cursor. + + Mimics home/back/forward in a web browser. + """ + + def __init__(self): + self._pos = -1 + self._elements = [] + + def clear(self): + """Empty the stack.""" + self._pos = -1 + self._elements = [] + + def __call__(self): + """Return the current element, or None.""" + return self._elements[self._pos] if self._elements else None + + def __len__(self): + return len(self._elements) + + def __getitem__(self, ind): + return self._elements[ind] + + def forward(self): + """Move the position forward and return the current element.""" + self._pos = min(self._pos + 1, len(self._elements) - 1) + return self() + + def back(self): + """Move the position back and return the current element.""" + self._pos = max(self._pos - 1, 0) + return self() + + def push(self, o): + """ + Push *o* to the stack after the current position, and return *o*. + + Discard all later elements. + """ + self._elements[self._pos + 1:] = [o] + self._pos = len(self._elements) - 1 + return o + + def home(self): + """ + Push the first element onto the top of the stack. + + The first element is returned. + """ + return self.push(self._elements[0]) if self._elements else None + + +def safe_masked_invalid(x, copy=False): + x = np.array(x, subok=True, copy=copy) + if not x.dtype.isnative: + # If we have already made a copy, do the byteswap in place, else make a + # copy with the byte order swapped. + # Swap to native order. + x = x.byteswap(inplace=copy).view(x.dtype.newbyteorder('N')) + try: + xm = np.ma.masked_where(~(np.isfinite(x)), x, copy=False) + except TypeError: + return x + return xm + + +def print_cycles(objects, outstream=sys.stdout, show_progress=False): + """ + Print loops of cyclic references in the given *objects*. + + It is often useful to pass in ``gc.garbage`` to find the cycles that are + preventing some objects from being garbage collected. + + Parameters + ---------- + objects + A list of objects to find cycles in. + outstream + The stream for output. + show_progress : bool + If True, print the number of objects reached as they are found. + """ + import gc + + def print_path(path): + for i, step in enumerate(path): + # next "wraps around" + next = path[(i + 1) % len(path)] + + outstream.write(" %s -- " % type(step)) + if isinstance(step, dict): + for key, val in step.items(): + if val is next: + outstream.write(f"[{key!r}]") + break + if key is next: + outstream.write(f"[key] = {val!r}") + break + elif isinstance(step, list): + outstream.write("[%d]" % step.index(next)) + elif isinstance(step, tuple): + outstream.write("( tuple )") + else: + outstream.write(repr(step)) + outstream.write(" ->\n") + outstream.write("\n") + + def recurse(obj, start, all, current_path): + if show_progress: + outstream.write("%d\r" % len(all)) + + all[id(obj)] = None + + referents = gc.get_referents(obj) + for referent in referents: + # If we've found our way back to the start, this is + # a cycle, so print it out + if referent is start: + print_path(current_path) + + # Don't go back through the original list of objects, or + # through temporary references to the object, since those + # are just an artifact of the cycle detector itself. + elif referent is objects or isinstance(referent, types.FrameType): + continue + + # We haven't seen this object before, so recurse + elif id(referent) not in all: + recurse(referent, start, all, current_path + [obj]) + + for obj in objects: + outstream.write(f"Examining: {obj!r}\n") + recurse(obj, obj, {}, []) + + +class Grouper: + """ + A disjoint-set data structure. + + Objects can be joined using :meth:`join`, tested for connectedness + using :meth:`joined`, and all disjoint sets can be retrieved by + using the object as an iterator. + + The objects being joined must be hashable and weak-referenceable. + + Examples + -------- + >>> from matplotlib.cbook import Grouper + >>> class Foo: + ... def __init__(self, s): + ... self.s = s + ... def __repr__(self): + ... return self.s + ... + >>> a, b, c, d, e, f = [Foo(x) for x in 'abcdef'] + >>> grp = Grouper() + >>> grp.join(a, b) + >>> grp.join(b, c) + >>> grp.join(d, e) + >>> list(grp) + [[a, b, c], [d, e]] + >>> grp.joined(a, b) + True + >>> grp.joined(a, c) + True + >>> grp.joined(a, d) + False + """ + + def __init__(self, init=()): + self._mapping = weakref.WeakKeyDictionary( + {x: weakref.WeakSet([x]) for x in init}) + + def __getstate__(self): + return { + **vars(self), + # Convert weak refs to strong ones. + "_mapping": {k: set(v) for k, v in self._mapping.items()}, + } + + def __setstate__(self, state): + vars(self).update(state) + # Convert strong refs to weak ones. + self._mapping = weakref.WeakKeyDictionary( + {k: weakref.WeakSet(v) for k, v in self._mapping.items()}) + + def __contains__(self, item): + return item in self._mapping + + @_api.deprecated("3.8", alternative="none, you no longer need to clean a Grouper") + def clean(self): + """Clean dead weak references from the dictionary.""" + + def join(self, a, *args): + """ + Join given arguments into the same set. Accepts one or more arguments. + """ + mapping = self._mapping + set_a = mapping.setdefault(a, weakref.WeakSet([a])) + + for arg in args: + set_b = mapping.get(arg, weakref.WeakSet([arg])) + if set_b is not set_a: + if len(set_b) > len(set_a): + set_a, set_b = set_b, set_a + set_a.update(set_b) + for elem in set_b: + mapping[elem] = set_a + + def joined(self, a, b): + """Return whether *a* and *b* are members of the same set.""" + return (self._mapping.get(a, object()) is self._mapping.get(b)) + + def remove(self, a): + """Remove *a* from the grouper, doing nothing if it is not there.""" + set_a = self._mapping.pop(a, None) + if set_a: + set_a.remove(a) + + def __iter__(self): + """ + Iterate over each of the disjoint sets as a list. + + The iterator is invalid if interleaved with calls to join(). + """ + unique_groups = {id(group): group for group in self._mapping.values()} + for group in unique_groups.values(): + yield [x for x in group] + + def get_siblings(self, a): + """Return all of the items joined with *a*, including itself.""" + siblings = self._mapping.get(a, [a]) + return [x for x in siblings] + + +class GrouperView: + """Immutable view over a `.Grouper`.""" + + def __init__(self, grouper): self._grouper = grouper + def __contains__(self, item): return item in self._grouper + def __iter__(self): return iter(self._grouper) + def joined(self, a, b): return self._grouper.joined(a, b) + def get_siblings(self, a): return self._grouper.get_siblings(a) + + +def simple_linear_interpolation(a, steps): + """ + Resample an array with ``steps - 1`` points between original point pairs. + + Along each column of *a*, ``(steps - 1)`` points are introduced between + each original values; the values are linearly interpolated. + + Parameters + ---------- + a : array, shape (n, ...) + steps : int + + Returns + ------- + array + shape ``((n - 1) * steps + 1, ...)`` + """ + fps = a.reshape((len(a), -1)) + xp = np.arange(len(a)) * steps + x = np.arange((len(a) - 1) * steps + 1) + return (np.column_stack([np.interp(x, xp, fp) for fp in fps.T]) + .reshape((len(x),) + a.shape[1:])) + + +def delete_masked_points(*args): + """ + Find all masked and/or non-finite points in a set of arguments, + and return the arguments with only the unmasked points remaining. + + Arguments can be in any of 5 categories: + + 1) 1-D masked arrays + 2) 1-D ndarrays + 3) ndarrays with more than one dimension + 4) other non-string iterables + 5) anything else + + The first argument must be in one of the first four categories; + any argument with a length differing from that of the first + argument (and hence anything in category 5) then will be + passed through unchanged. + + Masks are obtained from all arguments of the correct length + in categories 1, 2, and 4; a point is bad if masked in a masked + array or if it is a nan or inf. No attempt is made to + extract a mask from categories 2, 3, and 4 if `numpy.isfinite` + does not yield a Boolean array. + + All input arguments that are not passed unchanged are returned + as ndarrays after removing the points or rows corresponding to + masks in any of the arguments. + + A vastly simpler version of this function was originally + written as a helper for Axes.scatter(). + + """ + if not len(args): + return () + if is_scalar_or_string(args[0]): + raise ValueError("First argument must be a sequence") + nrecs = len(args[0]) + margs = [] + seqlist = [False] * len(args) + for i, x in enumerate(args): + if not isinstance(x, str) and np.iterable(x) and len(x) == nrecs: + seqlist[i] = True + if isinstance(x, np.ma.MaskedArray): + if x.ndim > 1: + raise ValueError("Masked arrays must be 1-D") + else: + x = np.asarray(x) + margs.append(x) + masks = [] # List of masks that are True where good. + for i, x in enumerate(margs): + if seqlist[i]: + if x.ndim > 1: + continue # Don't try to get nan locations unless 1-D. + if isinstance(x, np.ma.MaskedArray): + masks.append(~np.ma.getmaskarray(x)) # invert the mask + xd = x.data + else: + xd = x + try: + mask = np.isfinite(xd) + if isinstance(mask, np.ndarray): + masks.append(mask) + except Exception: # Fixme: put in tuple of possible exceptions? + pass + if len(masks): + mask = np.logical_and.reduce(masks) + igood = mask.nonzero()[0] + if len(igood) < nrecs: + for i, x in enumerate(margs): + if seqlist[i]: + margs[i] = x[igood] + for i, x in enumerate(margs): + if seqlist[i] and isinstance(x, np.ma.MaskedArray): + margs[i] = x.filled() + return margs + + +def _combine_masks(*args): + """ + Find all masked and/or non-finite points in a set of arguments, + and return the arguments as masked arrays with a common mask. + + Arguments can be in any of 5 categories: + + 1) 1-D masked arrays + 2) 1-D ndarrays + 3) ndarrays with more than one dimension + 4) other non-string iterables + 5) anything else + + The first argument must be in one of the first four categories; + any argument with a length differing from that of the first + argument (and hence anything in category 5) then will be + passed through unchanged. + + Masks are obtained from all arguments of the correct length + in categories 1, 2, and 4; a point is bad if masked in a masked + array or if it is a nan or inf. No attempt is made to + extract a mask from categories 2 and 4 if `numpy.isfinite` + does not yield a Boolean array. Category 3 is included to + support RGB or RGBA ndarrays, which are assumed to have only + valid values and which are passed through unchanged. + + All input arguments that are not passed unchanged are returned + as masked arrays if any masked points are found, otherwise as + ndarrays. + + """ + if not len(args): + return () + if is_scalar_or_string(args[0]): + raise ValueError("First argument must be a sequence") + nrecs = len(args[0]) + margs = [] # Output args; some may be modified. + seqlist = [False] * len(args) # Flags: True if output will be masked. + masks = [] # List of masks. + for i, x in enumerate(args): + if is_scalar_or_string(x) or len(x) != nrecs: + margs.append(x) # Leave it unmodified. + else: + if isinstance(x, np.ma.MaskedArray) and x.ndim > 1: + raise ValueError("Masked arrays must be 1-D") + try: + x = np.asanyarray(x) + except (VisibleDeprecationWarning, ValueError): + # NumPy 1.19 raises a warning about ragged arrays, but we want + # to accept basically anything here. + x = np.asanyarray(x, dtype=object) + if x.ndim == 1: + x = safe_masked_invalid(x) + seqlist[i] = True + if np.ma.is_masked(x): + masks.append(np.ma.getmaskarray(x)) + margs.append(x) # Possibly modified. + if len(masks): + mask = np.logical_or.reduce(masks) + for i, x in enumerate(margs): + if seqlist[i]: + margs[i] = np.ma.array(x, mask=mask) + return margs + + +def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None, + autorange=False): + r""" + Return a list of dictionaries of statistics used to draw a series of box + and whisker plots using `~.Axes.bxp`. + + Parameters + ---------- + X : array-like + Data that will be represented in the boxplots. Should have 2 or + fewer dimensions. + + whis : float or (float, float), default: 1.5 + The position of the whiskers. + + If a float, the lower whisker is at the lowest datum above + ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum below + ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and third + quartiles. The default value of ``whis = 1.5`` corresponds to Tukey's + original definition of boxplots. + + If a pair of floats, they indicate the percentiles at which to draw the + whiskers (e.g., (5, 95)). In particular, setting this to (0, 100) + results in whiskers covering the whole range of the data. + + In the edge case where ``Q1 == Q3``, *whis* is automatically set to + (0, 100) (cover the whole range of the data) if *autorange* is True. + + Beyond the whiskers, data are considered outliers and are plotted as + individual points. + + bootstrap : int, optional + Number of times the confidence intervals around the median + should be bootstrapped (percentile method). + + labels : array-like, optional + Labels for each dataset. Length must be compatible with + dimensions of *X*. + + autorange : bool, optional (False) + When `True` and the data are distributed such that the 25th and 75th + percentiles are equal, ``whis`` is set to (0, 100) such that the + whisker ends are at the minimum and maximum of the data. + + Returns + ------- + list of dict + A list of dictionaries containing the results for each column + of data. Keys of each dictionary are the following: + + ======== =================================== + Key Value Description + ======== =================================== + label tick label for the boxplot + mean arithmetic mean value + med 50th percentile + q1 first quartile (25th percentile) + q3 third quartile (75th percentile) + iqr interquartile range + cilo lower notch around the median + cihi upper notch around the median + whislo end of the lower whisker + whishi end of the upper whisker + fliers outliers + ======== =================================== + + Notes + ----- + Non-bootstrapping approach to confidence interval uses Gaussian-based + asymptotic approximation: + + .. math:: + + \mathrm{med} \pm 1.57 \times \frac{\mathrm{iqr}}{\sqrt{N}} + + General approach from: + McGill, R., Tukey, J.W., and Larsen, W.A. (1978) "Variations of + Boxplots", The American Statistician, 32:12-16. + """ + + def _bootstrap_median(data, N=5000): + # determine 95% confidence intervals of the median + M = len(data) + percentiles = [2.5, 97.5] + + bs_index = np.random.randint(M, size=(N, M)) + bsData = data[bs_index] + estimate = np.median(bsData, axis=1, overwrite_input=True) + + CI = np.percentile(estimate, percentiles) + return CI + + def _compute_conf_interval(data, med, iqr, bootstrap): + if bootstrap is not None: + # Do a bootstrap estimate of notch locations. + # get conf. intervals around median + CI = _bootstrap_median(data, N=bootstrap) + notch_min = CI[0] + notch_max = CI[1] + else: + + N = len(data) + notch_min = med - 1.57 * iqr / np.sqrt(N) + notch_max = med + 1.57 * iqr / np.sqrt(N) + + return notch_min, notch_max + + # output is a list of dicts + bxpstats = [] + + # convert X to a list of lists + X = _reshape_2D(X, "X") + + ncols = len(X) + if labels is None: + labels = itertools.repeat(None) + elif len(labels) != ncols: + raise ValueError("Dimensions of labels and X must be compatible") + + input_whis = whis + for ii, (x, label) in enumerate(zip(X, labels)): + + # empty dict + stats = {} + if label is not None: + stats['label'] = label + + # restore whis to the input values in case it got changed in the loop + whis = input_whis + + # note tricksiness, append up here and then mutate below + bxpstats.append(stats) + + # if empty, bail + if len(x) == 0: + stats['fliers'] = np.array([]) + stats['mean'] = np.nan + stats['med'] = np.nan + stats['q1'] = np.nan + stats['q3'] = np.nan + stats['iqr'] = np.nan + stats['cilo'] = np.nan + stats['cihi'] = np.nan + stats['whislo'] = np.nan + stats['whishi'] = np.nan + continue + + # up-convert to an array, just to be safe + x = np.asarray(x) + + # arithmetic mean + stats['mean'] = np.mean(x) + + # medians and quartiles + q1, med, q3 = np.percentile(x, [25, 50, 75]) + + # interquartile range + stats['iqr'] = q3 - q1 + if stats['iqr'] == 0 and autorange: + whis = (0, 100) + + # conf. interval around median + stats['cilo'], stats['cihi'] = _compute_conf_interval( + x, med, stats['iqr'], bootstrap + ) + + # lowest/highest non-outliers + if np.iterable(whis) and not isinstance(whis, str): + loval, hival = np.percentile(x, whis) + elif np.isreal(whis): + loval = q1 - whis * stats['iqr'] + hival = q3 + whis * stats['iqr'] + else: + raise ValueError('whis must be a float or list of percentiles') + + # get high extreme + wiskhi = x[x <= hival] + if len(wiskhi) == 0 or np.max(wiskhi) < q3: + stats['whishi'] = q3 + else: + stats['whishi'] = np.max(wiskhi) + + # get low extreme + wisklo = x[x >= loval] + if len(wisklo) == 0 or np.min(wisklo) > q1: + stats['whislo'] = q1 + else: + stats['whislo'] = np.min(wisklo) + + # compute a single array of outliers + stats['fliers'] = np.concatenate([ + x[x < stats['whislo']], + x[x > stats['whishi']], + ]) + + # add in the remaining stats + stats['q1'], stats['med'], stats['q3'] = q1, med, q3 + + return bxpstats + + +#: Maps short codes for line style to their full name used by backends. +ls_mapper = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted'} +#: Maps full names for line styles used by backends to their short codes. +ls_mapper_r = {v: k for k, v in ls_mapper.items()} + + +def contiguous_regions(mask): + """ + Return a list of (ind0, ind1) such that ``mask[ind0:ind1].all()`` is + True and we cover all such regions. + """ + mask = np.asarray(mask, dtype=bool) + + if not mask.size: + return [] + + # Find the indices of region changes, and correct offset + idx, = np.nonzero(mask[:-1] != mask[1:]) + idx += 1 + + # List operations are faster for moderately sized arrays + idx = idx.tolist() + + # Add first and/or last index if needed + if mask[0]: + idx = [0] + idx + if mask[-1]: + idx.append(len(mask)) + + return list(zip(idx[::2], idx[1::2])) + + +def is_math_text(s): + """ + Return whether the string *s* contains math expressions. + + This is done by checking whether *s* contains an even number of + non-escaped dollar signs. + """ + s = str(s) + dollar_count = s.count(r'$') - s.count(r'\$') + even_dollars = (dollar_count > 0 and dollar_count % 2 == 0) + return even_dollars + + +def _to_unmasked_float_array(x): + """ + Convert a sequence to a float array; if input was a masked array, masked + values are converted to nans. + """ + if hasattr(x, 'mask'): + return np.ma.asarray(x, float).filled(np.nan) + else: + return np.asarray(x, float) + + +def _check_1d(x): + """Convert scalars to 1D arrays; pass-through arrays as is.""" + # Unpack in case of e.g. Pandas or xarray object + x = _unpack_to_numpy(x) + # plot requires `shape` and `ndim`. If passed an + # object that doesn't provide them, then force to numpy array. + # Note this will strip unit information. + if (not hasattr(x, 'shape') or + not hasattr(x, 'ndim') or + len(x.shape) < 1): + return np.atleast_1d(x) + else: + return x + + +def _reshape_2D(X, name): + """ + Use Fortran ordering to convert ndarrays and lists of iterables to lists of + 1D arrays. + + Lists of iterables are converted by applying `numpy.asanyarray` to each of + their elements. 1D ndarrays are returned in a singleton list containing + them. 2D ndarrays are converted to the list of their *columns*. + + *name* is used to generate the error message for invalid inputs. + """ + + # Unpack in case of e.g. Pandas or xarray object + X = _unpack_to_numpy(X) + + # Iterate over columns for ndarrays. + if isinstance(X, np.ndarray): + X = X.T + + if len(X) == 0: + return [[]] + elif X.ndim == 1 and np.ndim(X[0]) == 0: + # 1D array of scalars: directly return it. + return [X] + elif X.ndim in [1, 2]: + # 2D array, or 1D array of iterables: flatten them first. + return [np.reshape(x, -1) for x in X] + else: + raise ValueError(f'{name} must have 2 or fewer dimensions') + + # Iterate over list of iterables. + if len(X) == 0: + return [[]] + + result = [] + is_1d = True + for xi in X: + # check if this is iterable, except for strings which we + # treat as singletons. + if not isinstance(xi, str): + try: + iter(xi) + except TypeError: + pass + else: + is_1d = False + xi = np.asanyarray(xi) + nd = np.ndim(xi) + if nd > 1: + raise ValueError(f'{name} must have 2 or fewer dimensions') + result.append(xi.reshape(-1)) + + if is_1d: + # 1D array of scalars: directly return it. + return [np.reshape(result, -1)] + else: + # 2D array, or 1D array of iterables: use flattened version. + return result + + +def violin_stats(X, method, points=100, quantiles=None): + """ + Return a list of dictionaries of data which can be used to draw a series + of violin plots. + + See the ``Returns`` section below to view the required keys of the + dictionary. + + Users can skip this function and pass a user-defined set of dictionaries + with the same keys to `~.axes.Axes.violinplot` instead of using Matplotlib + to do the calculations. See the *Returns* section below for the keys + that must be present in the dictionaries. + + Parameters + ---------- + X : array-like + Sample data that will be used to produce the gaussian kernel density + estimates. Must have 2 or fewer dimensions. + + method : callable + The method used to calculate the kernel density estimate for each + column of data. When called via ``method(v, coords)``, it should + return a vector of the values of the KDE evaluated at the values + specified in coords. + + points : int, default: 100 + Defines the number of points to evaluate each of the gaussian kernel + density estimates at. + + quantiles : array-like, default: None + Defines (if not None) a list of floats in interval [0, 1] for each + column of data, which represents the quantiles that will be rendered + for that column of data. Must have 2 or fewer dimensions. 1D array will + be treated as a singleton list containing them. + + Returns + ------- + list of dict + A list of dictionaries containing the results for each column of data. + The dictionaries contain at least the following: + + - coords: A list of scalars containing the coordinates this particular + kernel density estimate was evaluated at. + - vals: A list of scalars containing the values of the kernel density + estimate at each of the coordinates given in *coords*. + - mean: The mean value for this column of data. + - median: The median value for this column of data. + - min: The minimum value for this column of data. + - max: The maximum value for this column of data. + - quantiles: The quantile values for this column of data. + """ + + # List of dictionaries describing each of the violins. + vpstats = [] + + # Want X to be a list of data sequences + X = _reshape_2D(X, "X") + + # Want quantiles to be as the same shape as data sequences + if quantiles is not None and len(quantiles) != 0: + quantiles = _reshape_2D(quantiles, "quantiles") + # Else, mock quantiles if it's none or empty + else: + quantiles = [[]] * len(X) + + # quantiles should have the same size as dataset + if len(X) != len(quantiles): + raise ValueError("List of violinplot statistics and quantiles values" + " must have the same length") + + # Zip x and quantiles + for (x, q) in zip(X, quantiles): + # Dictionary of results for this distribution + stats = {} + + # Calculate basic stats for the distribution + min_val = np.min(x) + max_val = np.max(x) + quantile_val = np.percentile(x, 100 * q) + + # Evaluate the kernel density estimate + coords = np.linspace(min_val, max_val, points) + stats['vals'] = method(x, coords) + stats['coords'] = coords + + # Store additional statistics for this distribution + stats['mean'] = np.mean(x) + stats['median'] = np.median(x) + stats['min'] = min_val + stats['max'] = max_val + stats['quantiles'] = np.atleast_1d(quantile_val) + + # Append to output + vpstats.append(stats) + + return vpstats + + +def pts_to_prestep(x, *args): + """ + Convert continuous line to pre-steps. + + Given a set of ``N`` points, convert to ``2N - 1`` points, which when + connected linearly give a step function which changes values at the + beginning of the intervals. + + Parameters + ---------- + x : array + The x location of the steps. May be empty. + + y1, ..., yp : array + y arrays to be turned into steps; all must be the same length as ``x``. + + Returns + ------- + array + The x and y values converted to steps in the same order as the input; + can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is + length ``N``, each of these arrays will be length ``2N + 1``. For + ``N=0``, the length will be 0. + + Examples + -------- + >>> x_s, y1_s, y2_s = pts_to_prestep(x, y1, y2) + """ + steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0))) + # In all `pts_to_*step` functions, only assign once using *x* and *args*, + # as converting to an array may be expensive. + steps[0, 0::2] = x + steps[0, 1::2] = steps[0, 0:-2:2] + steps[1:, 0::2] = args + steps[1:, 1::2] = steps[1:, 2::2] + return steps + + +def pts_to_poststep(x, *args): + """ + Convert continuous line to post-steps. + + Given a set of ``N`` points convert to ``2N + 1`` points, which when + connected linearly give a step function which changes values at the end of + the intervals. + + Parameters + ---------- + x : array + The x location of the steps. May be empty. + + y1, ..., yp : array + y arrays to be turned into steps; all must be the same length as ``x``. + + Returns + ------- + array + The x and y values converted to steps in the same order as the input; + can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is + length ``N``, each of these arrays will be length ``2N + 1``. For + ``N=0``, the length will be 0. + + Examples + -------- + >>> x_s, y1_s, y2_s = pts_to_poststep(x, y1, y2) + """ + steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0))) + steps[0, 0::2] = x + steps[0, 1::2] = steps[0, 2::2] + steps[1:, 0::2] = args + steps[1:, 1::2] = steps[1:, 0:-2:2] + return steps + + +def pts_to_midstep(x, *args): + """ + Convert continuous line to mid-steps. + + Given a set of ``N`` points convert to ``2N`` points which when connected + linearly give a step function which changes values at the middle of the + intervals. + + Parameters + ---------- + x : array + The x location of the steps. May be empty. + + y1, ..., yp : array + y arrays to be turned into steps; all must be the same length as + ``x``. + + Returns + ------- + array + The x and y values converted to steps in the same order as the input; + can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is + length ``N``, each of these arrays will be length ``2N``. + + Examples + -------- + >>> x_s, y1_s, y2_s = pts_to_midstep(x, y1, y2) + """ + steps = np.zeros((1 + len(args), 2 * len(x))) + x = np.asanyarray(x) + steps[0, 1:-1:2] = steps[0, 2::2] = (x[:-1] + x[1:]) / 2 + steps[0, :1] = x[:1] # Also works for zero-sized input. + steps[0, -1:] = x[-1:] + steps[1:, 0::2] = args + steps[1:, 1::2] = steps[1:, 0::2] + return steps + + +STEP_LOOKUP_MAP = {'default': lambda x, y: (x, y), + 'steps': pts_to_prestep, + 'steps-pre': pts_to_prestep, + 'steps-post': pts_to_poststep, + 'steps-mid': pts_to_midstep} + + +def index_of(y): + """ + A helper function to create reasonable x values for the given *y*. + + This is used for plotting (x, y) if x values are not explicitly given. + + First try ``y.index`` (assuming *y* is a `pandas.Series`), if that + fails, use ``range(len(y))``. + + This will be extended in the future to deal with more types of + labeled data. + + Parameters + ---------- + y : float or array-like + + Returns + ------- + x, y : ndarray + The x and y values to plot. + """ + try: + return y.index.to_numpy(), y.to_numpy() + except AttributeError: + pass + try: + y = _check_1d(y) + except (VisibleDeprecationWarning, ValueError): + # NumPy 1.19 will warn on ragged input, and we can't actually use it. + pass + else: + return np.arange(y.shape[0], dtype=float), y + raise ValueError('Input could not be cast to an at-least-1D NumPy array') + + +def safe_first_element(obj): + """ + Return the first element in *obj*. + + This is a type-independent way of obtaining the first element, + supporting both index access and the iterator protocol. + """ + return _safe_first_finite(obj, skip_nonfinite=False) + + +def _safe_first_finite(obj, *, skip_nonfinite=True): + """ + Return the first finite element in *obj* if one is available and skip_nonfinite is + True. Otherwise, return the first element. + + This is a method for internal use. + + This is a type-independent way of obtaining the first finite element, supporting + both index access and the iterator protocol. + """ + def safe_isfinite(val): + if val is None: + return False + try: + return math.isfinite(val) + except (TypeError, ValueError): + pass + try: + return np.isfinite(val) if np.isscalar(val) else True + except TypeError: + # This is something that NumPy cannot make heads or tails of, + # assume "finite" + return True + if skip_nonfinite is False: + if isinstance(obj, collections.abc.Iterator): + # needed to accept `array.flat` as input. + # np.flatiter reports as an instance of collections.Iterator + # but can still be indexed via []. + # This has the side effect of re-setting the iterator, but + # that is acceptable. + try: + return obj[0] + except TypeError: + pass + raise RuntimeError("matplotlib does not support generators " + "as input") + return next(iter(obj)) + elif isinstance(obj, np.flatiter): + # TODO do the finite filtering on this + return obj[0] + elif isinstance(obj, collections.abc.Iterator): + raise RuntimeError("matplotlib does not " + "support generators as input") + else: + for val in obj: + if safe_isfinite(val): + return val + return safe_first_element(obj) + + +def sanitize_sequence(data): + """ + Convert dictview objects to list. Other inputs are returned unchanged. + """ + return (list(data) if isinstance(data, collections.abc.MappingView) + else data) + + +def normalize_kwargs(kw, alias_mapping=None): + """ + Helper function to normalize kwarg inputs. + + Parameters + ---------- + kw : dict or None + A dict of keyword arguments. None is explicitly supported and treated + as an empty dict, to support functions with an optional parameter of + the form ``props=None``. + + alias_mapping : dict or Artist subclass or Artist instance, optional + A mapping between a canonical name to a list of aliases, in order of + precedence from lowest to highest. + + If the canonical value is not in the list it is assumed to have the + highest priority. + + If an Artist subclass or instance is passed, use its properties alias + mapping. + + Raises + ------ + TypeError + To match what Python raises if invalid arguments/keyword arguments are + passed to a callable. + """ + from matplotlib.artist import Artist + + if kw is None: + return {} + + # deal with default value of alias_mapping + if alias_mapping is None: + alias_mapping = {} + elif (isinstance(alias_mapping, type) and issubclass(alias_mapping, Artist) + or isinstance(alias_mapping, Artist)): + alias_mapping = getattr(alias_mapping, "_alias_map", {}) + + to_canonical = {alias: canonical + for canonical, alias_list in alias_mapping.items() + for alias in alias_list} + canonical_to_seen = {} + ret = {} # output dictionary + + for k, v in kw.items(): + canonical = to_canonical.get(k, k) + if canonical in canonical_to_seen: + raise TypeError(f"Got both {canonical_to_seen[canonical]!r} and " + f"{k!r}, which are aliases of one another") + canonical_to_seen[canonical] = k + ret[canonical] = v + + return ret + + +@contextlib.contextmanager +def _lock_path(path): + """ + Context manager for locking a path. + + Usage:: + + with _lock_path(path): + ... + + Another thread or process that attempts to lock the same path will wait + until this context manager is exited. + + The lock is implemented by creating a temporary file in the parent + directory, so that directory must exist and be writable. + """ + path = Path(path) + lock_path = path.with_name(path.name + ".matplotlib-lock") + retries = 50 + sleeptime = 0.1 + for _ in range(retries): + try: + with lock_path.open("xb"): + break + except FileExistsError: + time.sleep(sleeptime) + else: + raise TimeoutError("""\ +Lock error: Matplotlib failed to acquire the following lock file: + {} +This maybe due to another process holding this lock file. If you are sure no +other Matplotlib process is running, remove this file and try again.""".format( + lock_path)) + try: + yield + finally: + lock_path.unlink() + + +def _topmost_artist( + artists, + _cached_max=functools.partial(max, key=operator.attrgetter("zorder"))): + """ + Get the topmost artist of a list. + + In case of a tie, return the *last* of the tied artists, as it will be + drawn on top of the others. `max` returns the first maximum in case of + ties, so we need to iterate over the list in reverse order. + """ + return _cached_max(reversed(artists)) + + +def _str_equal(obj, s): + """ + Return whether *obj* is a string equal to string *s*. + + This helper solely exists to handle the case where *obj* is a numpy array, + because in such cases, a naive ``obj == s`` would yield an array, which + cannot be used in a boolean context. + """ + return isinstance(obj, str) and obj == s + + +def _str_lower_equal(obj, s): + """ + Return whether *obj* is a string equal, when lowercased, to string *s*. + + This helper solely exists to handle the case where *obj* is a numpy array, + because in such cases, a naive ``obj == s`` would yield an array, which + cannot be used in a boolean context. + """ + return isinstance(obj, str) and obj.lower() == s + + +def _array_perimeter(arr): + """ + Get the elements on the perimeter of *arr*. + + Parameters + ---------- + arr : ndarray, shape (M, N) + The input array. + + Returns + ------- + ndarray, shape (2*(M - 1) + 2*(N - 1),) + The elements on the perimeter of the array:: + + [arr[0, 0], ..., arr[0, -1], ..., arr[-1, -1], ..., arr[-1, 0], ...] + + Examples + -------- + >>> i, j = np.ogrid[:3, :4] + >>> a = i*10 + j + >>> a + array([[ 0, 1, 2, 3], + [10, 11, 12, 13], + [20, 21, 22, 23]]) + >>> _array_perimeter(a) + array([ 0, 1, 2, 3, 13, 23, 22, 21, 20, 10]) + """ + # note we use Python's half-open ranges to avoid repeating + # the corners + forward = np.s_[0:-1] # [0 ... -1) + backward = np.s_[-1:0:-1] # [-1 ... 0) + return np.concatenate(( + arr[0, forward], + arr[forward, -1], + arr[-1, backward], + arr[backward, 0], + )) + + +def _unfold(arr, axis, size, step): + """ + Append an extra dimension containing sliding windows along *axis*. + + All windows are of size *size* and begin with every *step* elements. + + Parameters + ---------- + arr : ndarray, shape (N_1, ..., N_k) + The input array + axis : int + Axis along which the windows are extracted + size : int + Size of the windows + step : int + Stride between first elements of subsequent windows. + + Returns + ------- + ndarray, shape (N_1, ..., 1 + (N_axis-size)/step, ..., N_k, size) + + Examples + -------- + >>> i, j = np.ogrid[:3, :7] + >>> a = i*10 + j + >>> a + array([[ 0, 1, 2, 3, 4, 5, 6], + [10, 11, 12, 13, 14, 15, 16], + [20, 21, 22, 23, 24, 25, 26]]) + >>> _unfold(a, axis=1, size=3, step=2) + array([[[ 0, 1, 2], + [ 2, 3, 4], + [ 4, 5, 6]], + [[10, 11, 12], + [12, 13, 14], + [14, 15, 16]], + [[20, 21, 22], + [22, 23, 24], + [24, 25, 26]]]) + """ + new_shape = [*arr.shape, size] + new_strides = [*arr.strides, arr.strides[axis]] + new_shape[axis] = (new_shape[axis] - size) // step + 1 + new_strides[axis] = new_strides[axis] * step + return np.lib.stride_tricks.as_strided(arr, + shape=new_shape, + strides=new_strides, + writeable=False) + + +def _array_patch_perimeters(x, rstride, cstride): + """ + Extract perimeters of patches from *arr*. + + Extracted patches are of size (*rstride* + 1) x (*cstride* + 1) and + share perimeters with their neighbors. The ordering of the vertices matches + that returned by ``_array_perimeter``. + + Parameters + ---------- + x : ndarray, shape (N, M) + Input array + rstride : int + Vertical (row) stride between corresponding elements of each patch + cstride : int + Horizontal (column) stride between corresponding elements of each patch + + Returns + ------- + ndarray, shape (N/rstride * M/cstride, 2 * (rstride + cstride)) + """ + assert rstride > 0 and cstride > 0 + assert (x.shape[0] - 1) % rstride == 0 + assert (x.shape[1] - 1) % cstride == 0 + # We build up each perimeter from four half-open intervals. Here is an + # illustrated explanation for rstride == cstride == 3 + # + # T T T R + # L R + # L R + # L B B B + # + # where T means that this element will be in the top array, R for right, + # B for bottom and L for left. Each of the arrays below has a shape of: + # + # (number of perimeters that can be extracted vertically, + # number of perimeters that can be extracted horizontally, + # cstride for top and bottom and rstride for left and right) + # + # Note that _unfold doesn't incur any memory copies, so the only costly + # operation here is the np.concatenate. + top = _unfold(x[:-1:rstride, :-1], 1, cstride, cstride) + bottom = _unfold(x[rstride::rstride, 1:], 1, cstride, cstride)[..., ::-1] + right = _unfold(x[:-1, cstride::cstride], 0, rstride, rstride) + left = _unfold(x[1:, :-1:cstride], 0, rstride, rstride)[..., ::-1] + return (np.concatenate((top, right, bottom, left), axis=2) + .reshape(-1, 2 * (rstride + cstride))) + + +@contextlib.contextmanager +def _setattr_cm(obj, **kwargs): + """ + Temporarily set some attributes; restore original state at context exit. + """ + sentinel = object() + origs = {} + for attr in kwargs: + orig = getattr(obj, attr, sentinel) + if attr in obj.__dict__ or orig is sentinel: + # if we are pulling from the instance dict or the object + # does not have this attribute we can trust the above + origs[attr] = orig + else: + # if the attribute is not in the instance dict it must be + # from the class level + cls_orig = getattr(type(obj), attr) + # if we are dealing with a property (but not a general descriptor) + # we want to set the original value back. + if isinstance(cls_orig, property): + origs[attr] = orig + # otherwise this is _something_ we are going to shadow at + # the instance dict level from higher up in the MRO. We + # are going to assume we can delattr(obj, attr) to clean + # up after ourselves. It is possible that this code will + # fail if used with a non-property custom descriptor which + # implements __set__ (and __delete__ does not act like a + # stack). However, this is an internal tool and we do not + # currently have any custom descriptors. + else: + origs[attr] = sentinel + + try: + for attr, val in kwargs.items(): + setattr(obj, attr, val) + yield + finally: + for attr, orig in origs.items(): + if orig is sentinel: + delattr(obj, attr) + else: + setattr(obj, attr, orig) + + +class _OrderedSet(collections.abc.MutableSet): + def __init__(self): + self._od = collections.OrderedDict() + + def __contains__(self, key): + return key in self._od + + def __iter__(self): + return iter(self._od) + + def __len__(self): + return len(self._od) + + def add(self, key): + self._od.pop(key, None) + self._od[key] = None + + def discard(self, key): + self._od.pop(key, None) + + +# Agg's buffers are unmultiplied RGBA8888, which neither PyQt<=5.1 nor cairo +# support; however, both do support premultiplied ARGB32. + + +def _premultiplied_argb32_to_unmultiplied_rgba8888(buf): + """ + Convert a premultiplied ARGB32 buffer to an unmultiplied RGBA8888 buffer. + """ + rgba = np.take( # .take() ensures C-contiguity of the result. + buf, + [2, 1, 0, 3] if sys.byteorder == "little" else [1, 2, 3, 0], axis=2) + rgb = rgba[..., :-1] + alpha = rgba[..., -1] + # Un-premultiply alpha. The formula is the same as in cairo-png.c. + mask = alpha != 0 + for channel in np.rollaxis(rgb, -1): + channel[mask] = ( + (channel[mask].astype(int) * 255 + alpha[mask] // 2) + // alpha[mask]) + return rgba + + +def _unmultiplied_rgba8888_to_premultiplied_argb32(rgba8888): + """ + Convert an unmultiplied RGBA8888 buffer to a premultiplied ARGB32 buffer. + """ + if sys.byteorder == "little": + argb32 = np.take(rgba8888, [2, 1, 0, 3], axis=2) + rgb24 = argb32[..., :-1] + alpha8 = argb32[..., -1:] + else: + argb32 = np.take(rgba8888, [3, 0, 1, 2], axis=2) + alpha8 = argb32[..., :1] + rgb24 = argb32[..., 1:] + # Only bother premultiplying when the alpha channel is not fully opaque, + # as the cost is not negligible. The unsafe cast is needed to do the + # multiplication in-place in an integer buffer. + if alpha8.min() != 0xff: + np.multiply(rgb24, alpha8 / 0xff, out=rgb24, casting="unsafe") + return argb32 + + +def _get_nonzero_slices(buf): + """ + Return the bounds of the nonzero region of a 2D array as a pair of slices. + + ``buf[_get_nonzero_slices(buf)]`` is the smallest sub-rectangle in *buf* + that encloses all non-zero entries in *buf*. If *buf* is fully zero, then + ``(slice(0, 0), slice(0, 0))`` is returned. + """ + x_nz, = buf.any(axis=0).nonzero() + y_nz, = buf.any(axis=1).nonzero() + if len(x_nz) and len(y_nz): + l, r = x_nz[[0, -1]] + b, t = y_nz[[0, -1]] + return slice(b, t + 1), slice(l, r + 1) + else: + return slice(0, 0), slice(0, 0) + + +def _pformat_subprocess(command): + """Pretty-format a subprocess command for printing/logging purposes.""" + return (command if isinstance(command, str) + else " ".join(shlex.quote(os.fspath(arg)) for arg in command)) + + +def _check_and_log_subprocess(command, logger, **kwargs): + """ + Run *command*, returning its stdout output if it succeeds. + + If it fails (exits with nonzero return code), raise an exception whose text + includes the failed command and captured stdout and stderr output. + + Regardless of the return code, the command is logged at DEBUG level on + *logger*. In case of success, the output is likewise logged. + """ + logger.debug('%s', _pformat_subprocess(command)) + proc = subprocess.run(command, capture_output=True, **kwargs) + if proc.returncode: + stdout = proc.stdout + if isinstance(stdout, bytes): + stdout = stdout.decode() + stderr = proc.stderr + if isinstance(stderr, bytes): + stderr = stderr.decode() + raise RuntimeError( + f"The command\n" + f" {_pformat_subprocess(command)}\n" + f"failed and generated the following output:\n" + f"{stdout}\n" + f"and the following error:\n" + f"{stderr}") + if proc.stdout: + logger.debug("stdout:\n%s", proc.stdout) + if proc.stderr: + logger.debug("stderr:\n%s", proc.stderr) + return proc.stdout + + +def _backend_module_name(name): + """ + Convert a backend name (either a standard backend -- "Agg", "TkAgg", ... -- + or a custom backend -- "module://...") to the corresponding module name). + """ + return (name[9:] if name.startswith("module://") + else f"matplotlib.backends.backend_{name.lower()}") + + +def _setup_new_guiapp(): + """ + Perform OS-dependent setup when Matplotlib creates a new GUI application. + """ + # Windows: If not explicit app user model id has been set yet (so we're not + # already embedded), then set it to "matplotlib", so that taskbar icons are + # correct. + try: + _c_internal_utils.Win32_GetCurrentProcessExplicitAppUserModelID() + except OSError: + _c_internal_utils.Win32_SetCurrentProcessExplicitAppUserModelID( + "matplotlib") + + +def _format_approx(number, precision): + """ + Format the number with at most the number of decimals given as precision. + Remove trailing zeros and possibly the decimal point. + """ + return f'{number:.{precision}f}'.rstrip('0').rstrip('.') or '0' + + +def _g_sig_digits(value, delta): + """ + Return the number of significant digits to %g-format *value*, assuming that + it is known with an error of *delta*. + """ + if delta == 0: + # delta = 0 may occur when trying to format values over a tiny range; + # in that case, replace it by the distance to the closest float. + delta = abs(np.spacing(value)) + # If e.g. value = 45.67 and delta = 0.02, then we want to round to 2 digits + # after the decimal point (floor(log10(0.02)) = -2); 45.67 contributes 2 + # digits before the decimal point (floor(log10(45.67)) + 1 = 2): the total + # is 4 significant digits. A value of 0 contributes 1 "digit" before the + # decimal point. + # For inf or nan, the precision doesn't matter. + return max( + 0, + (math.floor(math.log10(abs(value))) + 1 if value else 1) + - math.floor(math.log10(delta))) if math.isfinite(value) else 0 + + +def _unikey_or_keysym_to_mplkey(unikey, keysym): + """ + Convert a Unicode key or X keysym to a Matplotlib key name. + + The Unicode key is checked first; this avoids having to list most printable + keysyms such as ``EuroSign``. + """ + # For non-printable characters, gtk3 passes "\0" whereas tk passes an "". + if unikey and unikey.isprintable(): + return unikey + key = keysym.lower() + if key.startswith("kp_"): # keypad_x (including kp_enter). + key = key[3:] + if key.startswith("page_"): # page_{up,down} + key = key.replace("page_", "page") + if key.endswith(("_l", "_r")): # alt_l, ctrl_l, shift_l. + key = key[:-2] + if sys.platform == "darwin" and key == "meta": + # meta should be reported as command on mac + key = "cmd" + key = { + "return": "enter", + "prior": "pageup", # Used by tk. + "next": "pagedown", # Used by tk. + }.get(key, key) + return key + + +@functools.cache +def _make_class_factory(mixin_class, fmt, attr_name=None): + """ + Return a function that creates picklable classes inheriting from a mixin. + + After :: + + factory = _make_class_factory(FooMixin, fmt, attr_name) + FooAxes = factory(Axes) + + ``Foo`` is a class that inherits from ``FooMixin`` and ``Axes`` and **is + picklable** (picklability is what differentiates this from a plain call to + `type`). Its ``__name__`` is set to ``fmt.format(Axes.__name__)`` and the + base class is stored in the ``attr_name`` attribute, if not None. + + Moreover, the return value of ``factory`` is memoized: calls with the same + ``Axes`` class always return the same subclass. + """ + + @functools.cache + def class_factory(axes_class): + # if we have already wrapped this class, declare victory! + if issubclass(axes_class, mixin_class): + return axes_class + + # The parameter is named "axes_class" for backcompat but is really just + # a base class; no axes semantics are used. + base_class = axes_class + + class subcls(mixin_class, base_class): + # Better approximation than __module__ = "matplotlib.cbook". + __module__ = mixin_class.__module__ + + def __reduce__(self): + return (_picklable_class_constructor, + (mixin_class, fmt, attr_name, base_class), + self.__getstate__()) + + subcls.__name__ = subcls.__qualname__ = fmt.format(base_class.__name__) + if attr_name is not None: + setattr(subcls, attr_name, base_class) + return subcls + + class_factory.__module__ = mixin_class.__module__ + return class_factory + + +def _picklable_class_constructor(mixin_class, fmt, attr_name, base_class): + """Internal helper for _make_class_factory.""" + factory = _make_class_factory(mixin_class, fmt, attr_name) + cls = factory(base_class) + return cls.__new__(cls) + + +def _unpack_to_numpy(x): + """Internal helper to extract data from e.g. pandas and xarray objects.""" + if isinstance(x, np.ndarray): + # If numpy, return directly + return x + if hasattr(x, 'to_numpy'): + # Assume that any to_numpy() method actually returns a numpy array + return x.to_numpy() + if hasattr(x, 'values'): + xtmp = x.values + # For example a dict has a 'values' attribute, but it is not a property + # so in this case we do not want to return a function + if isinstance(xtmp, np.ndarray): + return xtmp + return x + + +def _auto_format_str(fmt, value): + """ + Apply *value* to the format string *fmt*. + + This works both with unnamed %-style formatting and + unnamed {}-style formatting. %-style formatting has priority. + If *fmt* is %-style formattable that will be used. Otherwise, + {}-formatting is applied. Strings without formatting placeholders + are passed through as is. + + Examples + -------- + >>> _auto_format_str('%.2f m', 0.2) + '0.20 m' + >>> _auto_format_str('{} m', 0.2) + '0.2 m' + >>> _auto_format_str('const', 0.2) + 'const' + >>> _auto_format_str('%d or {}', 0.2) + '0 or {}' + """ + try: + return fmt % (value,) + except (TypeError, ValueError): + return fmt.format(value) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.pyi new file mode 100644 index 00000000..227a23df --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cbook.pyi @@ -0,0 +1,175 @@ +import collections.abc +from collections.abc import Callable, Collection, Generator, Iterable, Iterator +import contextlib +import os +from pathlib import Path + +from matplotlib.artist import Artist + +import numpy as np +from numpy.typing import ArrayLike + +from typing import ( + Any, + Generic, + IO, + Literal, + TypeVar, + overload, +) + +_T = TypeVar("_T") + +def _get_running_interactive_framework() -> str | None: ... + +class CallbackRegistry: + exception_handler: Callable[[Exception], Any] + callbacks: dict[Any, dict[int, Any]] + def __init__( + self, + exception_handler: Callable[[Exception], Any] | None = ..., + *, + signals: Iterable[Any] | None = ..., + ) -> None: ... + def connect(self, signal: Any, func: Callable) -> int: ... + def disconnect(self, cid: int) -> None: ... + def process(self, s: Any, *args, **kwargs) -> None: ... + def blocked( + self, *, signal: Any | None = ... + ) -> contextlib.AbstractContextManager[None]: ... + +class silent_list(list[_T]): + type: str | None + def __init__(self, type: str | None, seq: Iterable[_T] | None = ...) -> None: ... + +def strip_math(s: str) -> str: ... +def is_writable_file_like(obj: Any) -> bool: ... +def file_requires_unicode(x: Any) -> bool: ... +@overload +def to_filehandle( + fname: str | os.PathLike | IO, + flag: str = ..., + return_opened: Literal[False] = ..., + encoding: str | None = ..., +) -> IO: ... +@overload +def to_filehandle( + fname: str | os.PathLike | IO, + flag: str, + return_opened: Literal[True], + encoding: str | None = ..., +) -> tuple[IO, bool]: ... +@overload +def to_filehandle( + fname: str | os.PathLike | IO, + *, # if flag given, will match previous sig + return_opened: Literal[True], + encoding: str | None = ..., +) -> tuple[IO, bool]: ... +def open_file_cm( + path_or_file: str | os.PathLike | IO, + mode: str = ..., + encoding: str | None = ..., +) -> contextlib.AbstractContextManager[IO]: ... +def is_scalar_or_string(val: Any) -> bool: ... +@overload +def get_sample_data( + fname: str | os.PathLike, asfileobj: Literal[True] = ..., *, np_load: Literal[True] +) -> np.ndarray: ... +@overload +def get_sample_data( + fname: str | os.PathLike, + asfileobj: Literal[True] = ..., + *, + np_load: Literal[False] = ..., +) -> IO: ... +@overload +def get_sample_data( + fname: str | os.PathLike, asfileobj: Literal[False], *, np_load: bool = ... +) -> str: ... +def _get_data_path(*args: Path | str) -> Path: ... +def flatten( + seq: Iterable[Any], scalarp: Callable[[Any], bool] = ... +) -> Generator[Any, None, None]: ... + +class Stack(Generic[_T]): + def __init__(self, default: _T | None = ...) -> None: ... + def __call__(self) -> _T: ... + def __len__(self) -> int: ... + def __getitem__(self, ind: int) -> _T: ... + def forward(self) -> _T: ... + def back(self) -> _T: ... + def push(self, o: _T) -> _T: ... + def home(self) -> _T: ... + def empty(self) -> bool: ... + def clear(self) -> None: ... + def bubble(self, o: _T) -> _T: ... + def remove(self, o: _T) -> None: ... + +def safe_masked_invalid(x: ArrayLike, copy: bool = ...) -> np.ndarray: ... +def print_cycles( + objects: Iterable[Any], outstream: IO = ..., show_progress: bool = ... +) -> None: ... + +class Grouper(Generic[_T]): + def __init__(self, init: Iterable[_T] = ...) -> None: ... + def __contains__(self, item: _T) -> bool: ... + def clean(self) -> None: ... + def join(self, a: _T, *args: _T) -> None: ... + def joined(self, a: _T, b: _T) -> bool: ... + def remove(self, a: _T) -> None: ... + def __iter__(self) -> Iterator[list[_T]]: ... + def get_siblings(self, a: _T) -> list[_T]: ... + +class GrouperView(Generic[_T]): + def __init__(self, grouper: Grouper[_T]) -> None: ... + def __contains__(self, item: _T) -> bool: ... + def __iter__(self) -> Iterator[list[_T]]: ... + def joined(self, a: _T, b: _T) -> bool: ... + def get_siblings(self, a: _T) -> list[_T]: ... + +def simple_linear_interpolation(a: ArrayLike, steps: int) -> np.ndarray: ... +def delete_masked_points(*args): ... +def boxplot_stats( + X: ArrayLike, + whis: float | tuple[float, float] = ..., + bootstrap: int | None = ..., + labels: ArrayLike | None = ..., + autorange: bool = ..., +) -> list[dict[str, Any]]: ... + +ls_mapper: dict[str, str] +ls_mapper_r: dict[str, str] + +def contiguous_regions(mask: ArrayLike) -> list[np.ndarray]: ... +def is_math_text(s: str) -> bool: ... +def violin_stats( + X: ArrayLike, method: Callable, points: int = ..., quantiles: ArrayLike | None = ... +) -> list[dict[str, Any]]: ... +def pts_to_prestep(x: ArrayLike, *args: ArrayLike) -> np.ndarray: ... +def pts_to_poststep(x: ArrayLike, *args: ArrayLike) -> np.ndarray: ... +def pts_to_midstep(x: np.ndarray, *args: np.ndarray) -> np.ndarray: ... + +STEP_LOOKUP_MAP: dict[str, Callable] + +def index_of(y: float | ArrayLike) -> tuple[np.ndarray, np.ndarray]: ... +def safe_first_element(obj: Collection[_T]) -> _T: ... +def sanitize_sequence(data): ... +def normalize_kwargs( + kw: dict[str, Any], + alias_mapping: dict[str, list[str]] | type[Artist] | Artist | None = ..., +) -> dict[str, Any]: ... +def _lock_path(path: str | os.PathLike) -> contextlib.AbstractContextManager[None]: ... +def _str_equal(obj: Any, s: str) -> bool: ... +def _setattr_cm(obj: Any, **kwargs) -> contextlib.AbstractContextManager[None]: ... + +class _OrderedSet(collections.abc.MutableSet): + def __init__(self) -> None: ... + def __contains__(self, key) -> bool: ... + def __iter__(self): ... + def __len__(self) -> int: ... + def add(self, key) -> None: ... + def discard(self, key) -> None: ... + +def _backend_module_name(name: str) -> str: ... +def _format_approx(number: float, precision: int) -> str: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.py new file mode 100644 index 00000000..3911986f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.py @@ -0,0 +1,745 @@ +""" +Builtin colormaps, colormap handling utilities, and the `ScalarMappable` mixin. + +.. seealso:: + + :doc:`/gallery/color/colormap_reference` for a list of builtin colormaps. + + :ref:`colormap-manipulation` for examples of how to make + colormaps. + + :ref:`colormaps` an in-depth discussion of choosing + colormaps. + + :ref:`colormapnorms` for more details about data normalization. +""" + +from collections.abc import Mapping +import functools + +import numpy as np +from numpy import ma + +import matplotlib as mpl +from matplotlib import _api, colors, cbook, scale +from matplotlib._cm import datad +from matplotlib._cm_listed import cmaps as cmaps_listed + + +_LUTSIZE = mpl.rcParams['image.lut'] + + +def _gen_cmap_registry(): + """ + Generate a dict mapping standard colormap names to standard colormaps, as + well as the reversed colormaps. + """ + cmap_d = {**cmaps_listed} + for name, spec in datad.items(): + cmap_d[name] = ( # Precache the cmaps at a fixed lutsize.. + colors.LinearSegmentedColormap(name, spec, _LUTSIZE) + if 'red' in spec else + colors.ListedColormap(spec['listed'], name) + if 'listed' in spec else + colors.LinearSegmentedColormap.from_list(name, spec, _LUTSIZE)) + + # Register colormap aliases for gray and grey. + cmap_d['grey'] = cmap_d['gray'] + cmap_d['gist_grey'] = cmap_d['gist_gray'] + cmap_d['gist_yerg'] = cmap_d['gist_yarg'] + cmap_d['Grays'] = cmap_d['Greys'] + + # Generate reversed cmaps. + for cmap in list(cmap_d.values()): + rmap = cmap.reversed() + cmap_d[rmap.name] = rmap + return cmap_d + + +class ColormapRegistry(Mapping): + r""" + Container for colormaps that are known to Matplotlib by name. + + The universal registry instance is `matplotlib.colormaps`. There should be + no need for users to instantiate `.ColormapRegistry` themselves. + + Read access uses a dict-like interface mapping names to `.Colormap`\s:: + + import matplotlib as mpl + cmap = mpl.colormaps['viridis'] + + Returned `.Colormap`\s are copies, so that their modification does not + change the global definition of the colormap. + + Additional colormaps can be added via `.ColormapRegistry.register`:: + + mpl.colormaps.register(my_colormap) + + To get a list of all registered colormaps, you can do:: + + from matplotlib import colormaps + list(colormaps) + """ + def __init__(self, cmaps): + self._cmaps = cmaps + self._builtin_cmaps = tuple(cmaps) + # A shim to allow register_cmap() to force an override + self._allow_override_builtin = False + + def __getitem__(self, item): + try: + return self._cmaps[item].copy() + except KeyError: + raise KeyError(f"{item!r} is not a known colormap name") from None + + def __iter__(self): + return iter(self._cmaps) + + def __len__(self): + return len(self._cmaps) + + def __str__(self): + return ('ColormapRegistry; available colormaps:\n' + + ', '.join(f"'{name}'" for name in self)) + + def __call__(self): + """ + Return a list of the registered colormap names. + + This exists only for backward-compatibility in `.pyplot` which had a + ``plt.colormaps()`` method. The recommended way to get this list is + now ``list(colormaps)``. + """ + return list(self) + + def register(self, cmap, *, name=None, force=False): + """ + Register a new colormap. + + The colormap name can then be used as a string argument to any ``cmap`` + parameter in Matplotlib. It is also available in ``pyplot.get_cmap``. + + The colormap registry stores a copy of the given colormap, so that + future changes to the original colormap instance do not affect the + registered colormap. Think of this as the registry taking a snapshot + of the colormap at registration. + + Parameters + ---------- + cmap : matplotlib.colors.Colormap + The colormap to register. + + name : str, optional + The name for the colormap. If not given, ``cmap.name`` is used. + + force : bool, default: False + If False, a ValueError is raised if trying to overwrite an already + registered name. True supports overwriting registered colormaps + other than the builtin colormaps. + """ + _api.check_isinstance(colors.Colormap, cmap=cmap) + + name = name or cmap.name + if name in self: + if not force: + # don't allow registering an already existing cmap + # unless explicitly asked to + raise ValueError( + f'A colormap named "{name}" is already registered.') + elif (name in self._builtin_cmaps + and not self._allow_override_builtin): + # We don't allow overriding a builtin unless privately + # coming from register_cmap() + raise ValueError("Re-registering the builtin cmap " + f"{name!r} is not allowed.") + + # Warn that we are updating an already existing colormap + _api.warn_external(f"Overwriting the cmap {name!r} " + "that was already in the registry.") + + self._cmaps[name] = cmap.copy() + # Someone may set the extremes of a builtin colormap and want to register it + # with a different name for future lookups. The object would still have the + # builtin name, so we should update it to the registered name + if self._cmaps[name].name != name: + self._cmaps[name].name = name + + def unregister(self, name): + """ + Remove a colormap from the registry. + + You cannot remove built-in colormaps. + + If the named colormap is not registered, returns with no error, raises + if you try to de-register a default colormap. + + .. warning:: + + Colormap names are currently a shared namespace that may be used + by multiple packages. Use `unregister` only if you know you + have registered that name before. In particular, do not + unregister just in case to clean the name before registering a + new colormap. + + Parameters + ---------- + name : str + The name of the colormap to be removed. + + Raises + ------ + ValueError + If you try to remove a default built-in colormap. + """ + if name in self._builtin_cmaps: + raise ValueError(f"cannot unregister {name!r} which is a builtin " + "colormap.") + self._cmaps.pop(name, None) + + def get_cmap(self, cmap): + """ + Return a color map specified through *cmap*. + + Parameters + ---------- + cmap : str or `~matplotlib.colors.Colormap` or None + + - if a `.Colormap`, return it + - if a string, look it up in ``mpl.colormaps`` + - if None, return the Colormap defined in :rc:`image.cmap` + + Returns + ------- + Colormap + """ + # get the default color map + if cmap is None: + return self[mpl.rcParams["image.cmap"]] + + # if the user passed in a Colormap, simply return it + if isinstance(cmap, colors.Colormap): + return cmap + if isinstance(cmap, str): + _api.check_in_list(sorted(_colormaps), cmap=cmap) + # otherwise, it must be a string so look it up + return self[cmap] + raise TypeError( + 'get_cmap expects None or an instance of a str or Colormap . ' + + f'you passed {cmap!r} of type {type(cmap)}' + ) + + +# public access to the colormaps should be via `matplotlib.colormaps`. For now, +# we still create the registry here, but that should stay an implementation +# detail. +_colormaps = ColormapRegistry(_gen_cmap_registry()) +globals().update(_colormaps) + + +@_api.deprecated("3.7", alternative="``matplotlib.colormaps.register(name)``") +def register_cmap(name=None, cmap=None, *, override_builtin=False): + """ + Add a colormap to the set recognized by :func:`get_cmap`. + + Register a new colormap to be accessed by name :: + + LinearSegmentedColormap('swirly', data, lut) + register_cmap(cmap=swirly_cmap) + + Parameters + ---------- + name : str, optional + The name that can be used in :func:`get_cmap` or :rc:`image.cmap` + + If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name` + attribute of the *cmap*. + + cmap : matplotlib.colors.Colormap + Despite being the second argument and having a default value, this + is a required argument. + + override_builtin : bool + + Allow built-in colormaps to be overridden by a user-supplied + colormap. + + Please do not use this unless you are sure you need it. + """ + _api.check_isinstance((str, None), name=name) + if name is None: + try: + name = cmap.name + except AttributeError as err: + raise ValueError("Arguments must include a name or a " + "Colormap") from err + # override_builtin is allowed here for backward compatibility + # this is just a shim to enable that to work privately in + # the global ColormapRegistry + _colormaps._allow_override_builtin = override_builtin + _colormaps.register(cmap, name=name, force=override_builtin) + _colormaps._allow_override_builtin = False + + +def _get_cmap(name=None, lut=None): + """ + Get a colormap instance, defaulting to rc values if *name* is None. + + Parameters + ---------- + name : `~matplotlib.colors.Colormap` or str or None, default: None + If a `.Colormap` instance, it will be returned. Otherwise, the name of + a colormap known to Matplotlib, which will be resampled by *lut*. The + default, None, means :rc:`image.cmap`. + lut : int or None, default: None + If *name* is not already a Colormap instance and *lut* is not None, the + colormap will be resampled to have *lut* entries in the lookup table. + + Returns + ------- + Colormap + """ + if name is None: + name = mpl.rcParams['image.cmap'] + if isinstance(name, colors.Colormap): + return name + _api.check_in_list(sorted(_colormaps), name=name) + if lut is None: + return _colormaps[name] + else: + return _colormaps[name].resampled(lut) + +# do it in two steps like this so we can have an un-deprecated version in +# pyplot. +get_cmap = _api.deprecated( + '3.7', + name='get_cmap', + alternative=( + "``matplotlib.colormaps[name]`` " + + "or ``matplotlib.colormaps.get_cmap(obj)``" + ) +)(_get_cmap) + + +@_api.deprecated("3.7", + alternative="``matplotlib.colormaps.unregister(name)``") +def unregister_cmap(name): + """ + Remove a colormap recognized by :func:`get_cmap`. + + You may not remove built-in colormaps. + + If the named colormap is not registered, returns with no error, raises + if you try to de-register a default colormap. + + .. warning:: + + Colormap names are currently a shared namespace that may be used + by multiple packages. Use `unregister_cmap` only if you know you + have registered that name before. In particular, do not + unregister just in case to clean the name before registering a + new colormap. + + Parameters + ---------- + name : str + The name of the colormap to be un-registered + + Returns + ------- + ColorMap or None + If the colormap was registered, return it if not return `None` + + Raises + ------ + ValueError + If you try to de-register a default built-in colormap. + """ + cmap = _colormaps.get(name, None) + _colormaps.unregister(name) + return cmap + + +def _auto_norm_from_scale(scale_cls): + """ + Automatically generate a norm class from *scale_cls*. + + This differs from `.colors.make_norm_from_scale` in the following points: + + - This function is not a class decorator, but directly returns a norm class + (as if decorating `.Normalize`). + - The scale is automatically constructed with ``nonpositive="mask"``, if it + supports such a parameter, to work around the difference in defaults + between standard scales (which use "clip") and norms (which use "mask"). + + Note that ``make_norm_from_scale`` caches the generated norm classes + (not the instances) and reuses them for later calls. For example, + ``type(_auto_norm_from_scale("log")) == LogNorm``. + """ + # Actually try to construct an instance, to verify whether + # ``nonpositive="mask"`` is supported. + try: + norm = colors.make_norm_from_scale( + functools.partial(scale_cls, nonpositive="mask"))( + colors.Normalize)() + except TypeError: + norm = colors.make_norm_from_scale(scale_cls)( + colors.Normalize)() + return type(norm) + + +class ScalarMappable: + """ + A mixin class to map scalar data to RGBA. + + The ScalarMappable applies data normalization before returning RGBA colors + from the given colormap. + """ + + def __init__(self, norm=None, cmap=None): + """ + Parameters + ---------- + norm : `.Normalize` (or subclass thereof) or str or None + The normalizing object which scales data, typically into the + interval ``[0, 1]``. + If a `str`, a `.Normalize` subclass is dynamically generated based + on the scale with the corresponding name. + If *None*, *norm* defaults to a *colors.Normalize* object which + initializes its scaling based on the first data processed. + cmap : str or `~matplotlib.colors.Colormap` + The colormap used to map normalized data values to RGBA colors. + """ + self._A = None + self._norm = None # So that the setter knows we're initializing. + self.set_norm(norm) # The Normalize instance of this ScalarMappable. + self.cmap = None # So that the setter knows we're initializing. + self.set_cmap(cmap) # The Colormap instance of this ScalarMappable. + #: The last colorbar associated with this ScalarMappable. May be None. + self.colorbar = None + self.callbacks = cbook.CallbackRegistry(signals=["changed"]) + + def _scale_norm(self, norm, vmin, vmax): + """ + Helper for initial scaling. + + Used by public functions that create a ScalarMappable and support + parameters *vmin*, *vmax* and *norm*. This makes sure that a *norm* + will take precedence over *vmin*, *vmax*. + + Note that this method does not set the norm. + """ + if vmin is not None or vmax is not None: + self.set_clim(vmin, vmax) + if isinstance(norm, colors.Normalize): + raise ValueError( + "Passing a Normalize instance simultaneously with " + "vmin/vmax is not supported. Please pass vmin/vmax " + "directly to the norm when creating it.") + + # always resolve the autoscaling so we have concrete limits + # rather than deferring to draw time. + self.autoscale_None() + + def to_rgba(self, x, alpha=None, bytes=False, norm=True): + """ + Return a normalized RGBA array corresponding to *x*. + + In the normal case, *x* is a 1D or 2D sequence of scalars, and + the corresponding `~numpy.ndarray` of RGBA values will be returned, + based on the norm and colormap set for this ScalarMappable. + + There is one special case, for handling images that are already + RGB or RGBA, such as might have been read from an image file. + If *x* is an `~numpy.ndarray` with 3 dimensions, + and the last dimension is either 3 or 4, then it will be + treated as an RGB or RGBA array, and no mapping will be done. + The array can be `~numpy.uint8`, or it can be floats with + values in the 0-1 range; otherwise a ValueError will be raised. + If it is a masked array, any masked elements will be set to 0 alpha. + If the last dimension is 3, the *alpha* kwarg (defaulting to 1) + will be used to fill in the transparency. If the last dimension + is 4, the *alpha* kwarg is ignored; it does not + replace the preexisting alpha. A ValueError will be raised + if the third dimension is other than 3 or 4. + + In either case, if *bytes* is *False* (default), the RGBA + array will be floats in the 0-1 range; if it is *True*, + the returned RGBA array will be `~numpy.uint8` in the 0 to 255 range. + + If norm is False, no normalization of the input data is + performed, and it is assumed to be in the range (0-1). + + """ + # First check for special case, image input: + try: + if x.ndim == 3: + if x.shape[2] == 3: + if alpha is None: + alpha = 1 + if x.dtype == np.uint8: + alpha = np.uint8(alpha * 255) + m, n = x.shape[:2] + xx = np.empty(shape=(m, n, 4), dtype=x.dtype) + xx[:, :, :3] = x + xx[:, :, 3] = alpha + elif x.shape[2] == 4: + xx = x + else: + raise ValueError("Third dimension must be 3 or 4") + if xx.dtype.kind == 'f': + if norm and (xx.max() > 1 or xx.min() < 0): + raise ValueError("Floating point image RGB values " + "must be in the 0..1 range.") + if bytes: + xx = (xx * 255).astype(np.uint8) + elif xx.dtype == np.uint8: + if not bytes: + xx = xx.astype(np.float32) / 255 + else: + raise ValueError("Image RGB array must be uint8 or " + "floating point; found %s" % xx.dtype) + # Account for any masked entries in the original array + # If any of R, G, B, or A are masked for an entry, we set alpha to 0 + if np.ma.is_masked(x): + xx[np.any(np.ma.getmaskarray(x), axis=2), 3] = 0 + return xx + except AttributeError: + # e.g., x is not an ndarray; so try mapping it + pass + + # This is the normal case, mapping a scalar array: + x = ma.asarray(x) + if norm: + x = self.norm(x) + rgba = self.cmap(x, alpha=alpha, bytes=bytes) + return rgba + + def set_array(self, A): + """ + Set the value array from array-like *A*. + + Parameters + ---------- + A : array-like or None + The values that are mapped to colors. + + The base class `.ScalarMappable` does not make any assumptions on + the dimensionality and shape of the value array *A*. + """ + if A is None: + self._A = None + return + + A = cbook.safe_masked_invalid(A, copy=True) + if not np.can_cast(A.dtype, float, "same_kind"): + raise TypeError(f"Image data of dtype {A.dtype} cannot be " + "converted to float") + + self._A = A + + def get_array(self): + """ + Return the array of values, that are mapped to colors. + + The base class `.ScalarMappable` does not make any assumptions on + the dimensionality and shape of the array. + """ + return self._A + + def get_cmap(self): + """Return the `.Colormap` instance.""" + return self.cmap + + def get_clim(self): + """ + Return the values (min, max) that are mapped to the colormap limits. + """ + return self.norm.vmin, self.norm.vmax + + def set_clim(self, vmin=None, vmax=None): + """ + Set the norm limits for image scaling. + + Parameters + ---------- + vmin, vmax : float + The limits. + + The limits may also be passed as a tuple (*vmin*, *vmax*) as a + single positional argument. + + .. ACCEPTS: (vmin: float, vmax: float) + """ + # If the norm's limits are updated self.changed() will be called + # through the callbacks attached to the norm + if vmax is None: + try: + vmin, vmax = vmin + except (TypeError, ValueError): + pass + if vmin is not None: + self.norm.vmin = colors._sanitize_extrema(vmin) + if vmax is not None: + self.norm.vmax = colors._sanitize_extrema(vmax) + + def get_alpha(self): + """ + Returns + ------- + float + Always returns 1. + """ + # This method is intended to be overridden by Artist sub-classes + return 1. + + def set_cmap(self, cmap): + """ + Set the colormap for luminance data. + + Parameters + ---------- + cmap : `.Colormap` or str or None + """ + in_init = self.cmap is None + + self.cmap = _ensure_cmap(cmap) + if not in_init: + self.changed() # Things are not set up properly yet. + + @property + def norm(self): + return self._norm + + @norm.setter + def norm(self, norm): + _api.check_isinstance((colors.Normalize, str, None), norm=norm) + if norm is None: + norm = colors.Normalize() + elif isinstance(norm, str): + try: + scale_cls = scale._scale_mapping[norm] + except KeyError: + raise ValueError( + "Invalid norm str name; the following values are " + f"supported: {', '.join(scale._scale_mapping)}" + ) from None + norm = _auto_norm_from_scale(scale_cls)() + + if norm is self.norm: + # We aren't updating anything + return + + in_init = self.norm is None + # Remove the current callback and connect to the new one + if not in_init: + self.norm.callbacks.disconnect(self._id_norm) + self._norm = norm + self._id_norm = self.norm.callbacks.connect('changed', + self.changed) + if not in_init: + self.changed() + + def set_norm(self, norm): + """ + Set the normalization instance. + + Parameters + ---------- + norm : `.Normalize` or str or None + + Notes + ----- + If there are any colorbars using the mappable for this norm, setting + the norm of the mappable will reset the norm, locator, and formatters + on the colorbar to default. + """ + self.norm = norm + + def autoscale(self): + """ + Autoscale the scalar limits on the norm instance using the + current array + """ + if self._A is None: + raise TypeError('You must first set_array for mappable') + # If the norm's limits are updated self.changed() will be called + # through the callbacks attached to the norm + self.norm.autoscale(self._A) + + def autoscale_None(self): + """ + Autoscale the scalar limits on the norm instance using the + current array, changing only limits that are None + """ + if self._A is None: + raise TypeError('You must first set_array for mappable') + # If the norm's limits are updated self.changed() will be called + # through the callbacks attached to the norm + self.norm.autoscale_None(self._A) + + def changed(self): + """ + Call this whenever the mappable is changed to notify all the + callbackSM listeners to the 'changed' signal. + """ + self.callbacks.process('changed', self) + self.stale = True + + +# The docstrings here must be generic enough to apply to all relevant methods. +mpl._docstring.interpd.update( + cmap_doc="""\ +cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` + The Colormap instance or registered colormap name used to map scalar data + to colors.""", + norm_doc="""\ +norm : str or `~matplotlib.colors.Normalize`, optional + The normalization method used to scale scalar data to the [0, 1] range + before mapping to colors using *cmap*. By default, a linear scaling is + used, mapping the lowest value to 0 and the highest to 1. + + If given, this can be one of the following: + + - An instance of `.Normalize` or one of its subclasses + (see :ref:`colormapnorms`). + - A scale name, i.e. one of "linear", "log", "symlog", "logit", etc. For a + list of available scales, call `matplotlib.scale.get_scale_names()`. + In that case, a suitable `.Normalize` subclass is dynamically generated + and instantiated.""", + vmin_vmax_doc="""\ +vmin, vmax : float, optional + When using scalar data and no explicit *norm*, *vmin* and *vmax* define + the data range that the colormap covers. By default, the colormap covers + the complete value range of the supplied data. It is an error to use + *vmin*/*vmax* when a *norm* instance is given (but using a `str` *norm* + name together with *vmin*/*vmax* is acceptable).""", +) + + +def _ensure_cmap(cmap): + """ + Ensure that we have a `.Colormap` object. + + For internal use to preserve type stability of errors. + + Parameters + ---------- + cmap : None, str, Colormap + + - if a `Colormap`, return it + - if a string, look it up in mpl.colormaps + - if None, look up the default color map in mpl.colormaps + + Returns + ------- + Colormap + + """ + if isinstance(cmap, colors.Colormap): + return cmap + cmap_name = cmap if cmap is not None else mpl.rcParams["image.cmap"] + # use check_in_list to ensure type stability of the exception raised by + # the internal usage of this (ValueError vs KeyError) + if cmap_name not in _colormaps: + _api.check_in_list(sorted(_colormaps), cmap=cmap_name) + return mpl.colormaps[cmap_name] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.pyi new file mode 100644 index 00000000..be8f10b3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/cm.pyi @@ -0,0 +1,54 @@ +from collections.abc import Iterator, Mapping +from matplotlib import cbook, colors +from matplotlib.colorbar import Colorbar + +import numpy as np +from numpy.typing import ArrayLike + +class ColormapRegistry(Mapping[str, colors.Colormap]): + def __init__(self, cmaps: Mapping[str, colors.Colormap]) -> None: ... + def __getitem__(self, item: str) -> colors.Colormap: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __call__(self) -> list[str]: ... + def register( + self, cmap: colors.Colormap, *, name: str | None = ..., force: bool = ... + ) -> None: ... + def unregister(self, name: str) -> None: ... + def get_cmap(self, cmap: str | colors.Colormap) -> colors.Colormap: ... + +_colormaps: ColormapRegistry = ... + +def get_cmap(name: str | colors.Colormap | None = ..., lut: int | None = ...) -> colors.Colormap: ... + +class ScalarMappable: + cmap: colors.Colormap | None + colorbar: Colorbar | None + callbacks: cbook.CallbackRegistry + def __init__( + self, + norm: colors.Normalize | None = ..., + cmap: str | colors.Colormap | None = ..., + ) -> None: ... + def to_rgba( + self, + x: np.ndarray, + alpha: float | ArrayLike | None = ..., + bytes: bool = ..., + norm: bool = ..., + ) -> np.ndarray: ... + def set_array(self, A: ArrayLike | None) -> None: ... + def get_array(self) -> np.ndarray | None: ... + def get_cmap(self) -> colors.Colormap: ... + def get_clim(self) -> tuple[float, float]: ... + def set_clim(self, vmin: float | tuple[float, float] | None = ..., vmax: float | None = ...) -> None: ... + def get_alpha(self) -> float | None: ... + def set_cmap(self, cmap: str | colors.Colormap) -> None: ... + @property + def norm(self) -> colors.Normalize: ... + @norm.setter + def norm(self, norm: colors.Normalize | str | None) -> None: ... + def set_norm(self, norm: colors.Normalize | str | None) -> None: ... + def autoscale(self) -> None: ... + def autoscale_None(self) -> None: ... + def changed(self) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.py new file mode 100644 index 00000000..81db24d0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.py @@ -0,0 +1,2394 @@ +""" +Classes for the efficient drawing of large collections of objects that +share most properties, e.g., a large number of line segments or +polygons. + +The classes are not meant to be as flexible as their single element +counterparts (e.g., you may not be able to select all line styles) but +they are meant to be fast for common use cases (e.g., a large set of solid +line segments). +""" + +import itertools +import math +from numbers import Number, Real +import warnings + +import numpy as np + +import matplotlib as mpl +from . import (_api, _path, artist, cbook, cm, colors as mcolors, _docstring, + hatch as mhatch, lines as mlines, path as mpath, transforms) +from ._enums import JoinStyle, CapStyle + + +# "color" is excluded; it is a compound setter, and its docstring differs +# in LineCollection. +@_api.define_aliases({ + "antialiased": ["antialiaseds", "aa"], + "edgecolor": ["edgecolors", "ec"], + "facecolor": ["facecolors", "fc"], + "linestyle": ["linestyles", "dashes", "ls"], + "linewidth": ["linewidths", "lw"], + "offset_transform": ["transOffset"], +}) +class Collection(artist.Artist, cm.ScalarMappable): + r""" + Base class for Collections. Must be subclassed to be usable. + + A Collection represents a sequence of `.Patch`\es that can be drawn + more efficiently together than individually. For example, when a single + path is being drawn repeatedly at different offsets, the renderer can + typically execute a ``draw_marker()`` call much more efficiently than a + series of repeated calls to ``draw_path()`` with the offsets put in + one-by-one. + + Most properties of a collection can be configured per-element. Therefore, + Collections have "plural" versions of many of the properties of a `.Patch` + (e.g. `.Collection.get_paths` instead of `.Patch.get_path`). Exceptions are + the *zorder*, *hatch*, *pickradius*, *capstyle* and *joinstyle* properties, + which can only be set globally for the whole collection. + + Besides these exceptions, all properties can be specified as single values + (applying to all elements) or sequences of values. The property of the + ``i``\th element of the collection is:: + + prop[i % len(prop)] + + Each Collection can optionally be used as its own `.ScalarMappable` by + passing the *norm* and *cmap* parameters to its constructor. If the + Collection's `.ScalarMappable` matrix ``_A`` has been set (via a call + to `.Collection.set_array`), then at draw time this internal scalar + mappable will be used to set the ``facecolors`` and ``edgecolors``, + ignoring those that were manually passed in. + """ + #: Either a list of 3x3 arrays or an Nx3x3 array (representing N + #: transforms), suitable for the `all_transforms` argument to + #: `~matplotlib.backend_bases.RendererBase.draw_path_collection`; + #: each 3x3 array is used to initialize an + #: `~matplotlib.transforms.Affine2D` object. + #: Each kind of collection defines this based on its arguments. + _transforms = np.empty((0, 3, 3)) + + # Whether to draw an edge by default. Set on a + # subclass-by-subclass basis. + _edge_default = False + + @_docstring.interpd + def __init__(self, *, + edgecolors=None, + facecolors=None, + linewidths=None, + linestyles='solid', + capstyle=None, + joinstyle=None, + antialiaseds=None, + offsets=None, + offset_transform=None, + norm=None, # optional for ScalarMappable + cmap=None, # ditto + pickradius=5.0, + hatch=None, + urls=None, + zorder=1, + **kwargs + ): + """ + Parameters + ---------- + edgecolors : color or list of colors, default: :rc:`patch.edgecolor` + Edge color for each patch making up the collection. The special + value 'face' can be passed to make the edgecolor match the + facecolor. + facecolors : color or list of colors, default: :rc:`patch.facecolor` + Face color for each patch making up the collection. + linewidths : float or list of floats, default: :rc:`patch.linewidth` + Line width for each patch making up the collection. + linestyles : str or tuple or list thereof, default: 'solid' + Valid strings are ['solid', 'dashed', 'dashdot', 'dotted', '-', + '--', '-.', ':']. Dash tuples should be of the form:: + + (offset, onoffseq), + + where *onoffseq* is an even length tuple of on and off ink lengths + in points. For examples, see + :doc:`/gallery/lines_bars_and_markers/linestyles`. + capstyle : `.CapStyle`-like, default: :rc:`patch.capstyle` + Style to use for capping lines for all paths in the collection. + Allowed values are %(CapStyle)s. + joinstyle : `.JoinStyle`-like, default: :rc:`patch.joinstyle` + Style to use for joining lines for all paths in the collection. + Allowed values are %(JoinStyle)s. + antialiaseds : bool or list of bool, default: :rc:`patch.antialiased` + Whether each patch in the collection should be drawn with + antialiasing. + offsets : (float, float) or list thereof, default: (0, 0) + A vector by which to translate each patch after rendering (default + is no translation). The translation is performed in screen (pixel) + coordinates (i.e. after the Artist's transform is applied). + offset_transform : `~.Transform`, default: `.IdentityTransform` + A single transform which will be applied to each *offsets* vector + before it is used. + cmap, norm + Data normalization and colormapping parameters. See + `.ScalarMappable` for a detailed description. + hatch : str, optional + Hatching pattern to use in filled paths, if any. Valid strings are + ['/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*']. See + :doc:`/gallery/shapes_and_collections/hatch_style_reference` for + the meaning of each hatch type. + pickradius : float, default: 5.0 + If ``pickradius <= 0``, then `.Collection.contains` will return + ``True`` whenever the test point is inside of one of the polygons + formed by the control points of a Path in the Collection. On the + other hand, if it is greater than 0, then we instead check if the + test point is contained in a stroke of width ``2*pickradius`` + following any of the Paths in the Collection. + urls : list of str, default: None + A URL for each patch to link to once drawn. Currently only works + for the SVG backend. See :doc:`/gallery/misc/hyperlinks_sgskip` for + examples. + zorder : float, default: 1 + The drawing order, shared by all Patches in the Collection. See + :doc:`/gallery/misc/zorder_demo` for all defaults and examples. + """ + artist.Artist.__init__(self) + cm.ScalarMappable.__init__(self, norm, cmap) + # list of un-scaled dash patterns + # this is needed scaling the dash pattern by linewidth + self._us_linestyles = [(0, None)] + # list of dash patterns + self._linestyles = [(0, None)] + # list of unbroadcast/scaled linewidths + self._us_lw = [0] + self._linewidths = [0] + + self._gapcolor = None # Currently only used by LineCollection. + + # Flags set by _set_mappable_flags: are colors from mapping an array? + self._face_is_mapped = None + self._edge_is_mapped = None + self._mapped_colors = None # calculated in update_scalarmappable + self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color']) + self.set_facecolor(facecolors) + self.set_edgecolor(edgecolors) + self.set_linewidth(linewidths) + self.set_linestyle(linestyles) + self.set_antialiased(antialiaseds) + self.set_pickradius(pickradius) + self.set_urls(urls) + self.set_hatch(hatch) + self.set_zorder(zorder) + + if capstyle: + self.set_capstyle(capstyle) + else: + self._capstyle = None + + if joinstyle: + self.set_joinstyle(joinstyle) + else: + self._joinstyle = None + + if offsets is not None: + offsets = np.asanyarray(offsets, float) + # Broadcast (2,) -> (1, 2) but nothing else. + if offsets.shape == (2,): + offsets = offsets[None, :] + + self._offsets = offsets + self._offset_transform = offset_transform + + self._path_effects = None + self._internal_update(kwargs) + self._paths = None + + def get_paths(self): + return self._paths + + def set_paths(self, paths): + self._paths = paths + self.stale = True + + def get_transforms(self): + return self._transforms + + def get_offset_transform(self): + """Return the `.Transform` instance used by this artist offset.""" + if self._offset_transform is None: + self._offset_transform = transforms.IdentityTransform() + elif (not isinstance(self._offset_transform, transforms.Transform) + and hasattr(self._offset_transform, '_as_mpl_transform')): + self._offset_transform = \ + self._offset_transform._as_mpl_transform(self.axes) + return self._offset_transform + + def set_offset_transform(self, offset_transform): + """ + Set the artist offset transform. + + Parameters + ---------- + offset_transform : `.Transform` + """ + self._offset_transform = offset_transform + + def get_datalim(self, transData): + # Calculate the data limits and return them as a `.Bbox`. + # + # This operation depends on the transforms for the data in the + # collection and whether the collection has offsets: + # + # 1. offsets = None, transform child of transData: use the paths for + # the automatic limits (i.e. for LineCollection in streamline). + # 2. offsets != None: offset_transform is child of transData: + # + # a. transform is child of transData: use the path + offset for + # limits (i.e for bar). + # b. transform is not a child of transData: just use the offsets + # for the limits (i.e. for scatter) + # + # 3. otherwise return a null Bbox. + + transform = self.get_transform() + offset_trf = self.get_offset_transform() + if not (isinstance(offset_trf, transforms.IdentityTransform) + or offset_trf.contains_branch(transData)): + # if the offsets are in some coords other than data, + # then don't use them for autoscaling. + return transforms.Bbox.null() + + paths = self.get_paths() + if not len(paths): + # No paths to transform + return transforms.Bbox.null() + + if not transform.is_affine: + paths = [transform.transform_path_non_affine(p) for p in paths] + # Don't convert transform to transform.get_affine() here because + # we may have transform.contains_branch(transData) but not + # transforms.get_affine().contains_branch(transData). But later, + # be careful to only apply the affine part that remains. + + offsets = self.get_offsets() + + if any(transform.contains_branch_seperately(transData)): + # collections that are just in data units (like quiver) + # can properly have the axes limits set by their shape + + # offset. LineCollections that have no offsets can + # also use this algorithm (like streamplot). + if isinstance(offsets, np.ma.MaskedArray): + offsets = offsets.filled(np.nan) + # get_path_collection_extents handles nan but not masked arrays + return mpath.get_path_collection_extents( + transform.get_affine() - transData, paths, + self.get_transforms(), + offset_trf.transform_non_affine(offsets), + offset_trf.get_affine().frozen()) + + # NOTE: None is the default case where no offsets were passed in + if self._offsets is not None: + # this is for collections that have their paths (shapes) + # in physical, axes-relative, or figure-relative units + # (i.e. like scatter). We can't uniquely set limits based on + # those shapes, so we just set the limits based on their + # location. + offsets = (offset_trf - transData).transform(offsets) + # note A-B means A B^{-1} + offsets = np.ma.masked_invalid(offsets) + if not offsets.mask.all(): + bbox = transforms.Bbox.null() + bbox.update_from_data_xy(offsets) + return bbox + return transforms.Bbox.null() + + def get_window_extent(self, renderer=None): + # TODO: check to ensure that this does not fail for + # cases other than scatter plot legend + return self.get_datalim(transforms.IdentityTransform()) + + def _prepare_points(self): + # Helper for drawing and hit testing. + + transform = self.get_transform() + offset_trf = self.get_offset_transform() + offsets = self.get_offsets() + paths = self.get_paths() + + if self.have_units(): + paths = [] + for path in self.get_paths(): + vertices = path.vertices + xs, ys = vertices[:, 0], vertices[:, 1] + xs = self.convert_xunits(xs) + ys = self.convert_yunits(ys) + paths.append(mpath.Path(np.column_stack([xs, ys]), path.codes)) + xs = self.convert_xunits(offsets[:, 0]) + ys = self.convert_yunits(offsets[:, 1]) + offsets = np.ma.column_stack([xs, ys]) + + if not transform.is_affine: + paths = [transform.transform_path_non_affine(path) + for path in paths] + transform = transform.get_affine() + if not offset_trf.is_affine: + offsets = offset_trf.transform_non_affine(offsets) + # This might have changed an ndarray into a masked array. + offset_trf = offset_trf.get_affine() + + if isinstance(offsets, np.ma.MaskedArray): + offsets = offsets.filled(np.nan) + # Changing from a masked array to nan-filled ndarray + # is probably most efficient at this point. + + return transform, offset_trf, offsets, paths + + @artist.allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + renderer.open_group(self.__class__.__name__, self.get_gid()) + + self.update_scalarmappable() + + transform, offset_trf, offsets, paths = self._prepare_points() + + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_snap(self.get_snap()) + + if self._hatch: + gc.set_hatch(self._hatch) + gc.set_hatch_color(self._hatch_color) + + if self.get_sketch_params() is not None: + gc.set_sketch_params(*self.get_sketch_params()) + + if self.get_path_effects(): + from matplotlib.patheffects import PathEffectRenderer + renderer = PathEffectRenderer(self.get_path_effects(), renderer) + + # If the collection is made up of a single shape/color/stroke, + # it can be rendered once and blitted multiple times, using + # `draw_markers` rather than `draw_path_collection`. This is + # *much* faster for Agg, and results in smaller file sizes in + # PDF/SVG/PS. + + trans = self.get_transforms() + facecolors = self.get_facecolor() + edgecolors = self.get_edgecolor() + do_single_path_optimization = False + if (len(paths) == 1 and len(trans) <= 1 and + len(facecolors) == 1 and len(edgecolors) == 1 and + len(self._linewidths) == 1 and + all(ls[1] is None for ls in self._linestyles) and + len(self._antialiaseds) == 1 and len(self._urls) == 1 and + self.get_hatch() is None): + if len(trans): + combined_transform = transforms.Affine2D(trans[0]) + transform + else: + combined_transform = transform + extents = paths[0].get_extents(combined_transform) + if (extents.width < self.figure.bbox.width + and extents.height < self.figure.bbox.height): + do_single_path_optimization = True + + if self._joinstyle: + gc.set_joinstyle(self._joinstyle) + + if self._capstyle: + gc.set_capstyle(self._capstyle) + + if do_single_path_optimization: + gc.set_foreground(tuple(edgecolors[0])) + gc.set_linewidth(self._linewidths[0]) + gc.set_dashes(*self._linestyles[0]) + gc.set_antialiased(self._antialiaseds[0]) + gc.set_url(self._urls[0]) + renderer.draw_markers( + gc, paths[0], combined_transform.frozen(), + mpath.Path(offsets), offset_trf, tuple(facecolors[0])) + else: + if self._gapcolor is not None: + # First draw paths within the gaps. + ipaths, ilinestyles = self._get_inverse_paths_linestyles() + renderer.draw_path_collection( + gc, transform.frozen(), ipaths, + self.get_transforms(), offsets, offset_trf, + [mcolors.to_rgba("none")], self._gapcolor, + self._linewidths, ilinestyles, + self._antialiaseds, self._urls, + "screen") + + renderer.draw_path_collection( + gc, transform.frozen(), paths, + self.get_transforms(), offsets, offset_trf, + self.get_facecolor(), self.get_edgecolor(), + self._linewidths, self._linestyles, + self._antialiaseds, self._urls, + "screen") # offset_position, kept for backcompat. + + gc.restore() + renderer.close_group(self.__class__.__name__) + self.stale = False + + def set_pickradius(self, pickradius): + """ + Set the pick radius used for containment tests. + + Parameters + ---------- + pickradius : float + Pick radius, in points. + """ + if not isinstance(pickradius, Real): + raise ValueError( + f"pickradius must be a real-valued number, not {pickradius!r}") + self._pickradius = pickradius + + def get_pickradius(self): + return self._pickradius + + def contains(self, mouseevent): + """ + Test whether the mouse event occurred in the collection. + + Returns ``bool, dict(ind=itemlist)``, where every item in itemlist + contains the event. + """ + if self._different_canvas(mouseevent) or not self.get_visible(): + return False, {} + pickradius = ( + float(self._picker) + if isinstance(self._picker, Number) and + self._picker is not True # the bool, not just nonzero or 1 + else self._pickradius) + if self.axes: + self.axes._unstale_viewLim() + transform, offset_trf, offsets, paths = self._prepare_points() + # Tests if the point is contained on one of the polygons formed + # by the control points of each of the paths. A point is considered + # "on" a path if it would lie within a stroke of width 2*pickradius + # following the path. If pickradius <= 0, then we instead simply check + # if the point is *inside* of the path instead. + ind = _path.point_in_path_collection( + mouseevent.x, mouseevent.y, pickradius, + transform.frozen(), paths, self.get_transforms(), + offsets, offset_trf, pickradius <= 0) + return len(ind) > 0, dict(ind=ind) + + def set_urls(self, urls): + """ + Parameters + ---------- + urls : list of str or None + + Notes + ----- + URLs are currently only implemented by the SVG backend. They are + ignored by all other backends. + """ + self._urls = urls if urls is not None else [None] + self.stale = True + + def get_urls(self): + """ + Return a list of URLs, one for each element of the collection. + + The list contains *None* for elements without a URL. See + :doc:`/gallery/misc/hyperlinks_sgskip` for an example. + """ + return self._urls + + def set_hatch(self, hatch): + r""" + Set the hatching pattern + + *hatch* can be one of:: + + / - diagonal hatching + \ - back diagonal + | - vertical + - - horizontal + + - crossed + x - crossed diagonal + o - small circle + O - large circle + . - dots + * - stars + + Letters can be combined, in which case all the specified + hatchings are done. If same letter repeats, it increases the + density of hatching of that pattern. + + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + + Unlike other properties such as linewidth and colors, hatching + can only be specified for the collection as a whole, not separately + for each member. + + Parameters + ---------- + hatch : {'/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*'} + """ + # Use validate_hatch(list) after deprecation. + mhatch._validate_hatch_pattern(hatch) + self._hatch = hatch + self.stale = True + + def get_hatch(self): + """Return the current hatching pattern.""" + return self._hatch + + def set_offsets(self, offsets): + """ + Set the offsets for the collection. + + Parameters + ---------- + offsets : (N, 2) or (2,) array-like + """ + offsets = np.asanyarray(offsets) + if offsets.shape == (2,): # Broadcast (2,) -> (1, 2) but nothing else. + offsets = offsets[None, :] + cstack = (np.ma.column_stack if isinstance(offsets, np.ma.MaskedArray) + else np.column_stack) + self._offsets = cstack( + (np.asanyarray(self.convert_xunits(offsets[:, 0]), float), + np.asanyarray(self.convert_yunits(offsets[:, 1]), float))) + self.stale = True + + def get_offsets(self): + """Return the offsets for the collection.""" + # Default to zeros in the no-offset (None) case + return np.zeros((1, 2)) if self._offsets is None else self._offsets + + def _get_default_linewidth(self): + # This may be overridden in a subclass. + return mpl.rcParams['patch.linewidth'] # validated as float + + def set_linewidth(self, lw): + """ + Set the linewidth(s) for the collection. *lw* can be a scalar + or a sequence; if it is a sequence the patches will cycle + through the sequence + + Parameters + ---------- + lw : float or list of floats + """ + if lw is None: + lw = self._get_default_linewidth() + # get the un-scaled/broadcast lw + self._us_lw = np.atleast_1d(lw) + + # scale all of the dash patterns. + self._linewidths, self._linestyles = self._bcast_lwls( + self._us_lw, self._us_linestyles) + self.stale = True + + def set_linestyle(self, ls): + """ + Set the linestyle(s) for the collection. + + =========================== ================= + linestyle description + =========================== ================= + ``'-'`` or ``'solid'`` solid line + ``'--'`` or ``'dashed'`` dashed line + ``'-.'`` or ``'dashdot'`` dash-dotted line + ``':'`` or ``'dotted'`` dotted line + =========================== ================= + + Alternatively a dash tuple of the following form can be provided:: + + (offset, onoffseq), + + where ``onoffseq`` is an even length tuple of on and off ink in points. + + Parameters + ---------- + ls : str or tuple or list thereof + Valid values for individual linestyles include {'-', '--', '-.', + ':', '', (offset, on-off-seq)}. See `.Line2D.set_linestyle` for a + complete description. + """ + try: + dashes = [mlines._get_dash_pattern(ls)] + except ValueError: + try: + dashes = [mlines._get_dash_pattern(x) for x in ls] + except ValueError as err: + emsg = f'Do not know how to convert {ls!r} to dashes' + raise ValueError(emsg) from err + + # get the list of raw 'unscaled' dash patterns + self._us_linestyles = dashes + + # broadcast and scale the lw and dash patterns + self._linewidths, self._linestyles = self._bcast_lwls( + self._us_lw, self._us_linestyles) + + @_docstring.interpd + def set_capstyle(self, cs): + """ + Set the `.CapStyle` for the collection (for all its elements). + + Parameters + ---------- + cs : `.CapStyle` or %(CapStyle)s + """ + self._capstyle = CapStyle(cs) + + @_docstring.interpd + def get_capstyle(self): + """ + Return the cap style for the collection (for all its elements). + + Returns + ------- + %(CapStyle)s or None + """ + return self._capstyle.name if self._capstyle else None + + @_docstring.interpd + def set_joinstyle(self, js): + """ + Set the `.JoinStyle` for the collection (for all its elements). + + Parameters + ---------- + js : `.JoinStyle` or %(JoinStyle)s + """ + self._joinstyle = JoinStyle(js) + + @_docstring.interpd + def get_joinstyle(self): + """ + Return the join style for the collection (for all its elements). + + Returns + ------- + %(JoinStyle)s or None + """ + return self._joinstyle.name if self._joinstyle else None + + @staticmethod + def _bcast_lwls(linewidths, dashes): + """ + Internal helper function to broadcast + scale ls/lw + + In the collection drawing code, the linewidth and linestyle are cycled + through as circular buffers (via ``v[i % len(v)]``). Thus, if we are + going to scale the dash pattern at set time (not draw time) we need to + do the broadcasting now and expand both lists to be the same length. + + Parameters + ---------- + linewidths : list + line widths of collection + dashes : list + dash specification (offset, (dash pattern tuple)) + + Returns + ------- + linewidths, dashes : list + Will be the same length, dashes are scaled by paired linewidth + """ + if mpl.rcParams['_internal.classic_mode']: + return linewidths, dashes + # make sure they are the same length so we can zip them + if len(dashes) != len(linewidths): + l_dashes = len(dashes) + l_lw = len(linewidths) + gcd = math.gcd(l_dashes, l_lw) + dashes = list(dashes) * (l_lw // gcd) + linewidths = list(linewidths) * (l_dashes // gcd) + + # scale the dash patterns + dashes = [mlines._scale_dashes(o, d, lw) + for (o, d), lw in zip(dashes, linewidths)] + + return linewidths, dashes + + def get_antialiased(self): + """ + Get the antialiasing state for rendering. + + Returns + ------- + array of bools + """ + return self._antialiaseds + + def set_antialiased(self, aa): + """ + Set the antialiasing state for rendering. + + Parameters + ---------- + aa : bool or list of bools + """ + if aa is None: + aa = self._get_default_antialiased() + self._antialiaseds = np.atleast_1d(np.asarray(aa, bool)) + self.stale = True + + def _get_default_antialiased(self): + # This may be overridden in a subclass. + return mpl.rcParams['patch.antialiased'] + + def set_color(self, c): + """ + Set both the edgecolor and the facecolor. + + Parameters + ---------- + c : color or list of RGBA tuples + + See Also + -------- + Collection.set_facecolor, Collection.set_edgecolor + For setting the edge or face color individually. + """ + self.set_facecolor(c) + self.set_edgecolor(c) + + def _get_default_facecolor(self): + # This may be overridden in a subclass. + return mpl.rcParams['patch.facecolor'] + + def _set_facecolor(self, c): + if c is None: + c = self._get_default_facecolor() + + self._facecolors = mcolors.to_rgba_array(c, self._alpha) + self.stale = True + + def set_facecolor(self, c): + """ + Set the facecolor(s) of the collection. *c* can be a color (all patches + have same color), or a sequence of colors; if it is a sequence the + patches will cycle through the sequence. + + If *c* is 'none', the patch will not be filled. + + Parameters + ---------- + c : color or list of colors + """ + if isinstance(c, str) and c.lower() in ("none", "face"): + c = c.lower() + self._original_facecolor = c + self._set_facecolor(c) + + def get_facecolor(self): + return self._facecolors + + def get_edgecolor(self): + if cbook._str_equal(self._edgecolors, 'face'): + return self.get_facecolor() + else: + return self._edgecolors + + def _get_default_edgecolor(self): + # This may be overridden in a subclass. + return mpl.rcParams['patch.edgecolor'] + + def _set_edgecolor(self, c): + set_hatch_color = True + if c is None: + if (mpl.rcParams['patch.force_edgecolor'] + or self._edge_default + or cbook._str_equal(self._original_facecolor, 'none')): + c = self._get_default_edgecolor() + else: + c = 'none' + set_hatch_color = False + if cbook._str_lower_equal(c, 'face'): + self._edgecolors = 'face' + self.stale = True + return + self._edgecolors = mcolors.to_rgba_array(c, self._alpha) + if set_hatch_color and len(self._edgecolors): + self._hatch_color = tuple(self._edgecolors[0]) + self.stale = True + + def set_edgecolor(self, c): + """ + Set the edgecolor(s) of the collection. + + Parameters + ---------- + c : color or list of colors or 'face' + The collection edgecolor(s). If a sequence, the patches cycle + through it. If 'face', match the facecolor. + """ + # We pass through a default value for use in LineCollection. + # This allows us to maintain None as the default indicator in + # _original_edgecolor. + if isinstance(c, str) and c.lower() in ("none", "face"): + c = c.lower() + self._original_edgecolor = c + self._set_edgecolor(c) + + def set_alpha(self, alpha): + """ + Set the transparency of the collection. + + Parameters + ---------- + alpha : float or array of float or None + If not None, *alpha* values must be between 0 and 1, inclusive. + If an array is provided, its length must match the number of + elements in the collection. Masked values and nans are not + supported. + """ + artist.Artist._set_alpha_for_array(self, alpha) + self._set_facecolor(self._original_facecolor) + self._set_edgecolor(self._original_edgecolor) + + set_alpha.__doc__ = artist.Artist._set_alpha_for_array.__doc__ + + def get_linewidth(self): + return self._linewidths + + def get_linestyle(self): + return self._linestyles + + def _set_mappable_flags(self): + """ + Determine whether edges and/or faces are color-mapped. + + This is a helper for update_scalarmappable. + It sets Boolean flags '_edge_is_mapped' and '_face_is_mapped'. + + Returns + ------- + mapping_change : bool + True if either flag is True, or if a flag has changed. + """ + # The flags are initialized to None to ensure this returns True + # the first time it is called. + edge0 = self._edge_is_mapped + face0 = self._face_is_mapped + # After returning, the flags must be Booleans, not None. + self._edge_is_mapped = False + self._face_is_mapped = False + if self._A is not None: + if not cbook._str_equal(self._original_facecolor, 'none'): + self._face_is_mapped = True + if cbook._str_equal(self._original_edgecolor, 'face'): + self._edge_is_mapped = True + else: + if self._original_edgecolor is None: + self._edge_is_mapped = True + + mapped = self._face_is_mapped or self._edge_is_mapped + changed = (edge0 is None or face0 is None + or self._edge_is_mapped != edge0 + or self._face_is_mapped != face0) + return mapped or changed + + def update_scalarmappable(self): + """ + Update colors from the scalar mappable array, if any. + + Assign colors to edges and faces based on the array and/or + colors that were directly set, as appropriate. + """ + if not self._set_mappable_flags(): + return + # Allow possibility to call 'self.set_array(None)'. + if self._A is not None: + # QuadMesh can map 2d arrays (but pcolormesh supplies 1d array) + if self._A.ndim > 1 and not isinstance(self, _MeshData): + raise ValueError('Collections can only map rank 1 arrays') + if np.iterable(self._alpha): + if self._alpha.size != self._A.size: + raise ValueError( + f'Data array shape, {self._A.shape} ' + 'is incompatible with alpha array shape, ' + f'{self._alpha.shape}. ' + 'This can occur with the deprecated ' + 'behavior of the "flat" shading option, ' + 'in which a row and/or column of the data ' + 'array is dropped.') + # pcolormesh, scatter, maybe others flatten their _A + self._alpha = self._alpha.reshape(self._A.shape) + self._mapped_colors = self.to_rgba(self._A, self._alpha) + + if self._face_is_mapped: + self._facecolors = self._mapped_colors + else: + self._set_facecolor(self._original_facecolor) + if self._edge_is_mapped: + self._edgecolors = self._mapped_colors + else: + self._set_edgecolor(self._original_edgecolor) + self.stale = True + + def get_fill(self): + """Return whether face is colored.""" + return not cbook._str_lower_equal(self._original_facecolor, "none") + + def update_from(self, other): + """Copy properties from other to self.""" + + artist.Artist.update_from(self, other) + self._antialiaseds = other._antialiaseds + self._mapped_colors = other._mapped_colors + self._edge_is_mapped = other._edge_is_mapped + self._original_edgecolor = other._original_edgecolor + self._edgecolors = other._edgecolors + self._face_is_mapped = other._face_is_mapped + self._original_facecolor = other._original_facecolor + self._facecolors = other._facecolors + self._linewidths = other._linewidths + self._linestyles = other._linestyles + self._us_linestyles = other._us_linestyles + self._pickradius = other._pickradius + self._hatch = other._hatch + + # update_from for scalarmappable + self._A = other._A + self.norm = other.norm + self.cmap = other.cmap + self.stale = True + + +class _CollectionWithSizes(Collection): + """ + Base class for collections that have an array of sizes. + """ + _factor = 1.0 + + def get_sizes(self): + """ + Return the sizes ('areas') of the elements in the collection. + + Returns + ------- + array + The 'area' of each element. + """ + return self._sizes + + def set_sizes(self, sizes, dpi=72.0): + """ + Set the sizes of each member of the collection. + + Parameters + ---------- + sizes : `numpy.ndarray` or None + The size to set for each element of the collection. The + value is the 'area' of the element. + dpi : float, default: 72 + The dpi of the canvas. + """ + if sizes is None: + self._sizes = np.array([]) + self._transforms = np.empty((0, 3, 3)) + else: + self._sizes = np.asarray(sizes) + self._transforms = np.zeros((len(self._sizes), 3, 3)) + scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor + self._transforms[:, 0, 0] = scale + self._transforms[:, 1, 1] = scale + self._transforms[:, 2, 2] = 1.0 + self.stale = True + + @artist.allow_rasterization + def draw(self, renderer): + self.set_sizes(self._sizes, self.figure.dpi) + super().draw(renderer) + + +class PathCollection(_CollectionWithSizes): + r""" + A collection of `~.path.Path`\s, as created by e.g. `~.Axes.scatter`. + """ + + def __init__(self, paths, sizes=None, **kwargs): + """ + Parameters + ---------- + paths : list of `.path.Path` + The paths that will make up the `.Collection`. + sizes : array-like + The factor by which to scale each drawn `~.path.Path`. One unit + squared in the Path's data space is scaled to be ``sizes**2`` + points when rendered. + **kwargs + Forwarded to `.Collection`. + """ + + super().__init__(**kwargs) + self.set_paths(paths) + self.set_sizes(sizes) + self.stale = True + + def get_paths(self): + return self._paths + + def legend_elements(self, prop="colors", num="auto", + fmt=None, func=lambda x: x, **kwargs): + """ + Create legend handles and labels for a PathCollection. + + Each legend handle is a `.Line2D` representing the Path that was drawn, + and each label is a string what each Path represents. + + This is useful for obtaining a legend for a `~.Axes.scatter` plot; + e.g.:: + + scatter = plt.scatter([1, 2, 3], [4, 5, 6], c=[7, 2, 3]) + plt.legend(*scatter.legend_elements()) + + creates three legend elements, one for each color with the numerical + values passed to *c* as the labels. + + Also see the :ref:`automatedlegendcreation` example. + + Parameters + ---------- + prop : {"colors", "sizes"}, default: "colors" + If "colors", the legend handles will show the different colors of + the collection. If "sizes", the legend will show the different + sizes. To set both, use *kwargs* to directly edit the `.Line2D` + properties. + num : int, None, "auto" (default), array-like, or `~.ticker.Locator` + Target number of elements to create. + If None, use all unique elements of the mappable array. If an + integer, target to use *num* elements in the normed range. + If *"auto"*, try to determine which option better suits the nature + of the data. + The number of created elements may slightly deviate from *num* due + to a `~.ticker.Locator` being used to find useful locations. + If a list or array, use exactly those elements for the legend. + Finally, a `~.ticker.Locator` can be provided. + fmt : str, `~matplotlib.ticker.Formatter`, or None (default) + The format or formatter to use for the labels. If a string must be + a valid input for a `.StrMethodFormatter`. If None (the default), + use a `.ScalarFormatter`. + func : function, default: ``lambda x: x`` + Function to calculate the labels. Often the size (or color) + argument to `~.Axes.scatter` will have been pre-processed by the + user using a function ``s = f(x)`` to make the markers visible; + e.g. ``size = np.log10(x)``. Providing the inverse of this + function here allows that pre-processing to be inverted, so that + the legend labels have the correct values; e.g. ``func = lambda + x: 10**x``. + **kwargs + Allowed keyword arguments are *color* and *size*. E.g. it may be + useful to set the color of the markers if *prop="sizes"* is used; + similarly to set the size of the markers if *prop="colors"* is + used. Any further parameters are passed onto the `.Line2D` + instance. This may be useful to e.g. specify a different + *markeredgecolor* or *alpha* for the legend handles. + + Returns + ------- + handles : list of `.Line2D` + Visual representation of each element of the legend. + labels : list of str + The string labels for elements of the legend. + """ + handles = [] + labels = [] + hasarray = self.get_array() is not None + if fmt is None: + fmt = mpl.ticker.ScalarFormatter(useOffset=False, useMathText=True) + elif isinstance(fmt, str): + fmt = mpl.ticker.StrMethodFormatter(fmt) + fmt.create_dummy_axis() + + if prop == "colors": + if not hasarray: + warnings.warn("Collection without array used. Make sure to " + "specify the values to be colormapped via the " + "`c` argument.") + return handles, labels + u = np.unique(self.get_array()) + size = kwargs.pop("size", mpl.rcParams["lines.markersize"]) + elif prop == "sizes": + u = np.unique(self.get_sizes()) + color = kwargs.pop("color", "k") + else: + raise ValueError("Valid values for `prop` are 'colors' or " + f"'sizes'. You supplied '{prop}' instead.") + + fu = func(u) + fmt.axis.set_view_interval(fu.min(), fu.max()) + fmt.axis.set_data_interval(fu.min(), fu.max()) + if num == "auto": + num = 9 + if len(u) <= num: + num = None + if num is None: + values = u + label_values = func(values) + else: + if prop == "colors": + arr = self.get_array() + elif prop == "sizes": + arr = self.get_sizes() + if isinstance(num, mpl.ticker.Locator): + loc = num + elif np.iterable(num): + loc = mpl.ticker.FixedLocator(num) + else: + num = int(num) + loc = mpl.ticker.MaxNLocator(nbins=num, min_n_ticks=num-1, + steps=[1, 2, 2.5, 3, 5, 6, 8, 10]) + label_values = loc.tick_values(func(arr).min(), func(arr).max()) + cond = ((label_values >= func(arr).min()) & + (label_values <= func(arr).max())) + label_values = label_values[cond] + yarr = np.linspace(arr.min(), arr.max(), 256) + xarr = func(yarr) + ix = np.argsort(xarr) + values = np.interp(label_values, xarr[ix], yarr[ix]) + + kw = {"markeredgewidth": self.get_linewidths()[0], + "alpha": self.get_alpha(), + **kwargs} + + for val, lab in zip(values, label_values): + if prop == "colors": + color = self.cmap(self.norm(val)) + elif prop == "sizes": + size = np.sqrt(val) + if np.isclose(size, 0.0): + continue + h = mlines.Line2D([0], [0], ls="", color=color, ms=size, + marker=self.get_paths()[0], **kw) + handles.append(h) + if hasattr(fmt, "set_locs"): + fmt.set_locs(label_values) + l = fmt(lab) + labels.append(l) + + return handles, labels + + +class PolyCollection(_CollectionWithSizes): + + def __init__(self, verts, sizes=None, *, closed=True, **kwargs): + """ + Parameters + ---------- + verts : list of array-like + The sequence of polygons [*verts0*, *verts1*, ...] where each + element *verts_i* defines the vertices of polygon *i* as a 2D + array-like of shape (M, 2). + sizes : array-like, default: None + Squared scaling factors for the polygons. The coordinates of each + polygon *verts_i* are multiplied by the square-root of the + corresponding entry in *sizes* (i.e., *sizes* specify the scaling + of areas). The scaling is applied before the Artist master + transform. + closed : bool, default: True + Whether the polygon should be closed by adding a CLOSEPOLY + connection at the end. + **kwargs + Forwarded to `.Collection`. + """ + super().__init__(**kwargs) + self.set_sizes(sizes) + self.set_verts(verts, closed) + self.stale = True + + def set_verts(self, verts, closed=True): + """ + Set the vertices of the polygons. + + Parameters + ---------- + verts : list of array-like + The sequence of polygons [*verts0*, *verts1*, ...] where each + element *verts_i* defines the vertices of polygon *i* as a 2D + array-like of shape (M, 2). + closed : bool, default: True + Whether the polygon should be closed by adding a CLOSEPOLY + connection at the end. + """ + self.stale = True + if isinstance(verts, np.ma.MaskedArray): + verts = verts.astype(float).filled(np.nan) + + # No need to do anything fancy if the path isn't closed. + if not closed: + self._paths = [mpath.Path(xy) for xy in verts] + return + + # Fast path for arrays + if isinstance(verts, np.ndarray) and len(verts.shape) == 3: + verts_pad = np.concatenate((verts, verts[:, :1]), axis=1) + # Creating the codes once is much faster than having Path do it + # separately each time by passing closed=True. + codes = np.empty(verts_pad.shape[1], dtype=mpath.Path.code_type) + codes[:] = mpath.Path.LINETO + codes[0] = mpath.Path.MOVETO + codes[-1] = mpath.Path.CLOSEPOLY + self._paths = [mpath.Path(xy, codes) for xy in verts_pad] + return + + self._paths = [] + for xy in verts: + if len(xy): + self._paths.append(mpath.Path._create_closed(xy)) + else: + self._paths.append(mpath.Path(xy)) + + set_paths = set_verts + + def set_verts_and_codes(self, verts, codes): + """Initialize vertices with path codes.""" + if len(verts) != len(codes): + raise ValueError("'codes' must be a 1D list or array " + "with the same length of 'verts'") + self._paths = [mpath.Path(xy, cds) if len(xy) else mpath.Path(xy) + for xy, cds in zip(verts, codes)] + self.stale = True + + @classmethod + @_api.deprecated("3.7", alternative="fill_between") + def span_where(cls, x, ymin, ymax, where, **kwargs): + """ + Return a `.BrokenBarHCollection` that plots horizontal bars from + over the regions in *x* where *where* is True. The bars range + on the y-axis from *ymin* to *ymax* + + *kwargs* are passed on to the collection. + """ + xranges = [] + for ind0, ind1 in cbook.contiguous_regions(where): + xslice = x[ind0:ind1] + if not len(xslice): + continue + xranges.append((xslice[0], xslice[-1] - xslice[0])) + return BrokenBarHCollection(xranges, [ymin, ymax - ymin], **kwargs) + + +@_api.deprecated("3.7") +class BrokenBarHCollection(PolyCollection): + """ + A collection of horizontal bars spanning *yrange* with a sequence of + *xranges*. + """ + def __init__(self, xranges, yrange, **kwargs): + """ + Parameters + ---------- + xranges : list of (float, float) + The sequence of (left-edge-position, width) pairs for each bar. + yrange : (float, float) + The (lower-edge, height) common to all bars. + **kwargs + Forwarded to `.Collection`. + """ + ymin, ywidth = yrange + ymax = ymin + ywidth + verts = [[(xmin, ymin), + (xmin, ymax), + (xmin + xwidth, ymax), + (xmin + xwidth, ymin), + (xmin, ymin)] for xmin, xwidth in xranges] + super().__init__(verts, **kwargs) + + +class RegularPolyCollection(_CollectionWithSizes): + """A collection of n-sided regular polygons.""" + + _path_generator = mpath.Path.unit_regular_polygon + _factor = np.pi ** (-1/2) + + def __init__(self, + numsides, + *, + rotation=0, + sizes=(1,), + **kwargs): + """ + Parameters + ---------- + numsides : int + The number of sides of the polygon. + rotation : float + The rotation of the polygon in radians. + sizes : tuple of float + The area of the circle circumscribing the polygon in points^2. + **kwargs + Forwarded to `.Collection`. + + Examples + -------- + See :doc:`/gallery/event_handling/lasso_demo` for a complete example:: + + offsets = np.random.rand(20, 2) + facecolors = [cm.jet(x) for x in np.random.rand(20)] + + collection = RegularPolyCollection( + numsides=5, # a pentagon + rotation=0, sizes=(50,), + facecolors=facecolors, + edgecolors=("black",), + linewidths=(1,), + offsets=offsets, + offset_transform=ax.transData, + ) + """ + super().__init__(**kwargs) + self.set_sizes(sizes) + self._numsides = numsides + self._paths = [self._path_generator(numsides)] + self._rotation = rotation + self.set_transform(transforms.IdentityTransform()) + + def get_numsides(self): + return self._numsides + + def get_rotation(self): + return self._rotation + + @artist.allow_rasterization + def draw(self, renderer): + self.set_sizes(self._sizes, self.figure.dpi) + self._transforms = [ + transforms.Affine2D(x).rotate(-self._rotation).get_matrix() + for x in self._transforms + ] + # Explicitly not super().draw, because set_sizes must be called before + # updating self._transforms. + Collection.draw(self, renderer) + + +class StarPolygonCollection(RegularPolyCollection): + """Draw a collection of regular stars with *numsides* points.""" + _path_generator = mpath.Path.unit_regular_star + + +class AsteriskPolygonCollection(RegularPolyCollection): + """Draw a collection of regular asterisks with *numsides* points.""" + _path_generator = mpath.Path.unit_regular_asterisk + + +class LineCollection(Collection): + r""" + Represents a sequence of `.Line2D`\s that should be drawn together. + + This class extends `.Collection` to represent a sequence of + `.Line2D`\s instead of just a sequence of `.Patch`\s. + Just as in `.Collection`, each property of a *LineCollection* may be either + a single value or a list of values. This list is then used cyclically for + each element of the LineCollection, so the property of the ``i``\th element + of the collection is:: + + prop[i % len(prop)] + + The properties of each member of a *LineCollection* default to their values + in :rc:`lines.*` instead of :rc:`patch.*`, and the property *colors* is + added in place of *edgecolors*. + """ + + _edge_default = True + + def __init__(self, segments, # Can be None. + *, + zorder=2, # Collection.zorder is 1 + **kwargs + ): + """ + Parameters + ---------- + segments : list of array-like + A sequence (*line0*, *line1*, *line2*) of lines, where each line is a list + of points:: + + lineN = [(x0, y0), (x1, y1), ... (xm, ym)] + + or the equivalent Mx2 numpy array with two columns. Each line + can have a different number of segments. + linewidths : float or list of float, default: :rc:`lines.linewidth` + The width of each line in points. + colors : color or list of color, default: :rc:`lines.color` + A sequence of RGBA tuples (e.g., arbitrary color strings, etc, not + allowed). + antialiaseds : bool or list of bool, default: :rc:`lines.antialiased` + Whether to use antialiasing for each line. + zorder : float, default: 2 + zorder of the lines once drawn. + + facecolors : color or list of color, default: 'none' + When setting *facecolors*, each line is interpreted as a boundary + for an area, implicitly closing the path from the last point to the + first point. The enclosed area is filled with *facecolor*. + In order to manually specify what should count as the "interior" of + each line, please use `.PathCollection` instead, where the + "interior" can be specified by appropriate usage of + `~.path.Path.CLOSEPOLY`. + + **kwargs + Forwarded to `.Collection`. + """ + # Unfortunately, mplot3d needs this explicit setting of 'facecolors'. + kwargs.setdefault('facecolors', 'none') + super().__init__( + zorder=zorder, + **kwargs) + self.set_segments(segments) + + def set_segments(self, segments): + if segments is None: + return + + self._paths = [mpath.Path(seg) if isinstance(seg, np.ma.MaskedArray) + else mpath.Path(np.asarray(seg, float)) + for seg in segments] + self.stale = True + + set_verts = set_segments # for compatibility with PolyCollection + set_paths = set_segments + + def get_segments(self): + """ + Returns + ------- + list + List of segments in the LineCollection. Each list item contains an + array of vertices. + """ + segments = [] + + for path in self._paths: + vertices = [ + vertex + for vertex, _ + # Never simplify here, we want to get the data-space values + # back and there in no way to know the "right" simplification + # threshold so never try. + in path.iter_segments(simplify=False) + ] + vertices = np.asarray(vertices) + segments.append(vertices) + + return segments + + def _get_default_linewidth(self): + return mpl.rcParams['lines.linewidth'] + + def _get_default_antialiased(self): + return mpl.rcParams['lines.antialiased'] + + def _get_default_edgecolor(self): + return mpl.rcParams['lines.color'] + + def _get_default_facecolor(self): + return 'none' + + def set_alpha(self, alpha): + # docstring inherited + super().set_alpha(alpha) + if self._gapcolor is not None: + self.set_gapcolor(self._original_gapcolor) + + def set_color(self, c): + """ + Set the edgecolor(s) of the LineCollection. + + Parameters + ---------- + c : color or list of colors + Single color (all lines have same color), or a + sequence of RGBA tuples; if it is a sequence the lines will + cycle through the sequence. + """ + self.set_edgecolor(c) + + set_colors = set_color + + def get_color(self): + return self._edgecolors + + get_colors = get_color # for compatibility with old versions + + def set_gapcolor(self, gapcolor): + """ + Set a color to fill the gaps in the dashed line style. + + .. note:: + + Striped lines are created by drawing two interleaved dashed lines. + There can be overlaps between those two, which may result in + artifacts when using transparency. + + This functionality is experimental and may change. + + Parameters + ---------- + gapcolor : color or list of colors or None + The color with which to fill the gaps. If None, the gaps are + unfilled. + """ + self._original_gapcolor = gapcolor + self._set_gapcolor(gapcolor) + + def _set_gapcolor(self, gapcolor): + if gapcolor is not None: + gapcolor = mcolors.to_rgba_array(gapcolor, self._alpha) + self._gapcolor = gapcolor + self.stale = True + + def get_gapcolor(self): + return self._gapcolor + + def _get_inverse_paths_linestyles(self): + """ + Returns the path and pattern for the gaps in the non-solid lines. + + This path and pattern is the inverse of the path and pattern used to + construct the non-solid lines. For solid lines, we set the inverse path + to nans to prevent drawing an inverse line. + """ + path_patterns = [ + (mpath.Path(np.full((1, 2), np.nan)), ls) + if ls == (0, None) else + (path, mlines._get_inverse_dash_pattern(*ls)) + for (path, ls) in + zip(self._paths, itertools.cycle(self._linestyles))] + + return zip(*path_patterns) + + +class EventCollection(LineCollection): + """ + A collection of locations along a single axis at which an "event" occurred. + + The events are given by a 1-dimensional array. They do not have an + amplitude and are displayed as parallel lines. + """ + + _edge_default = True + + def __init__(self, + positions, # Cannot be None. + orientation='horizontal', + *, + lineoffset=0, + linelength=1, + linewidth=None, + color=None, + linestyle='solid', + antialiased=None, + **kwargs + ): + """ + Parameters + ---------- + positions : 1D array-like + Each value is an event. + orientation : {'horizontal', 'vertical'}, default: 'horizontal' + The sequence of events is plotted along this direction. + The marker lines of the single events are along the orthogonal + direction. + lineoffset : float, default: 0 + The offset of the center of the markers from the origin, in the + direction orthogonal to *orientation*. + linelength : float, default: 1 + The total height of the marker (i.e. the marker stretches from + ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``). + linewidth : float or list thereof, default: :rc:`lines.linewidth` + The line width of the event lines, in points. + color : color or list of colors, default: :rc:`lines.color` + The color of the event lines. + linestyle : str or tuple or list thereof, default: 'solid' + Valid strings are ['solid', 'dashed', 'dashdot', 'dotted', + '-', '--', '-.', ':']. Dash tuples should be of the form:: + + (offset, onoffseq), + + where *onoffseq* is an even length tuple of on and off ink + in points. + antialiased : bool or list thereof, default: :rc:`lines.antialiased` + Whether to use antialiasing for drawing the lines. + **kwargs + Forwarded to `.LineCollection`. + + Examples + -------- + .. plot:: gallery/lines_bars_and_markers/eventcollection_demo.py + """ + super().__init__([], + linewidths=linewidth, linestyles=linestyle, + colors=color, antialiaseds=antialiased, + **kwargs) + self._is_horizontal = True # Initial value, may be switched below. + self._linelength = linelength + self._lineoffset = lineoffset + self.set_orientation(orientation) + self.set_positions(positions) + + def get_positions(self): + """ + Return an array containing the floating-point values of the positions. + """ + pos = 0 if self.is_horizontal() else 1 + return [segment[0, pos] for segment in self.get_segments()] + + def set_positions(self, positions): + """Set the positions of the events.""" + if positions is None: + positions = [] + if np.ndim(positions) != 1: + raise ValueError('positions must be one-dimensional') + lineoffset = self.get_lineoffset() + linelength = self.get_linelength() + pos_idx = 0 if self.is_horizontal() else 1 + segments = np.empty((len(positions), 2, 2)) + segments[:, :, pos_idx] = np.sort(positions)[:, None] + segments[:, 0, 1 - pos_idx] = lineoffset + linelength / 2 + segments[:, 1, 1 - pos_idx] = lineoffset - linelength / 2 + self.set_segments(segments) + + def add_positions(self, position): + """Add one or more events at the specified positions.""" + if position is None or (hasattr(position, 'len') and + len(position) == 0): + return + positions = self.get_positions() + positions = np.hstack([positions, np.asanyarray(position)]) + self.set_positions(positions) + extend_positions = append_positions = add_positions + + def is_horizontal(self): + """True if the eventcollection is horizontal, False if vertical.""" + return self._is_horizontal + + def get_orientation(self): + """ + Return the orientation of the event line ('horizontal' or 'vertical'). + """ + return 'horizontal' if self.is_horizontal() else 'vertical' + + def switch_orientation(self): + """ + Switch the orientation of the event line, either from vertical to + horizontal or vice versus. + """ + segments = self.get_segments() + for i, segment in enumerate(segments): + segments[i] = np.fliplr(segment) + self.set_segments(segments) + self._is_horizontal = not self.is_horizontal() + self.stale = True + + def set_orientation(self, orientation): + """ + Set the orientation of the event line. + + Parameters + ---------- + orientation : {'horizontal', 'vertical'} + """ + is_horizontal = _api.check_getitem( + {"horizontal": True, "vertical": False}, + orientation=orientation) + if is_horizontal == self.is_horizontal(): + return + self.switch_orientation() + + def get_linelength(self): + """Return the length of the lines used to mark each event.""" + return self._linelength + + def set_linelength(self, linelength): + """Set the length of the lines used to mark each event.""" + if linelength == self.get_linelength(): + return + lineoffset = self.get_lineoffset() + segments = self.get_segments() + pos = 1 if self.is_horizontal() else 0 + for segment in segments: + segment[0, pos] = lineoffset + linelength / 2. + segment[1, pos] = lineoffset - linelength / 2. + self.set_segments(segments) + self._linelength = linelength + + def get_lineoffset(self): + """Return the offset of the lines used to mark each event.""" + return self._lineoffset + + def set_lineoffset(self, lineoffset): + """Set the offset of the lines used to mark each event.""" + if lineoffset == self.get_lineoffset(): + return + linelength = self.get_linelength() + segments = self.get_segments() + pos = 1 if self.is_horizontal() else 0 + for segment in segments: + segment[0, pos] = lineoffset + linelength / 2. + segment[1, pos] = lineoffset - linelength / 2. + self.set_segments(segments) + self._lineoffset = lineoffset + + def get_linewidth(self): + """Get the width of the lines used to mark each event.""" + return super().get_linewidth()[0] + + def get_linewidths(self): + return super().get_linewidth() + + def get_color(self): + """Return the color of the lines used to mark each event.""" + return self.get_colors()[0] + + +class CircleCollection(_CollectionWithSizes): + """A collection of circles, drawn using splines.""" + + _factor = np.pi ** (-1/2) + + def __init__(self, sizes, **kwargs): + """ + Parameters + ---------- + sizes : float or array-like + The area of each circle in points^2. + **kwargs + Forwarded to `.Collection`. + """ + super().__init__(**kwargs) + self.set_sizes(sizes) + self.set_transform(transforms.IdentityTransform()) + self._paths = [mpath.Path.unit_circle()] + + +class EllipseCollection(Collection): + """A collection of ellipses, drawn using splines.""" + + def __init__(self, widths, heights, angles, *, units='points', **kwargs): + """ + Parameters + ---------- + widths : array-like + The lengths of the first axes (e.g., major axis lengths). + heights : array-like + The lengths of second axes. + angles : array-like + The angles of the first axes, degrees CCW from the x-axis. + units : {'points', 'inches', 'dots', 'width', 'height', 'x', 'y', 'xy'} + The units in which majors and minors are given; 'width' and + 'height' refer to the dimensions of the axes, while 'x' and 'y' + refer to the *offsets* data units. 'xy' differs from all others in + that the angle as plotted varies with the aspect ratio, and equals + the specified angle only when the aspect ratio is unity. Hence + it behaves the same as the `~.patches.Ellipse` with + ``axes.transData`` as its transform. + **kwargs + Forwarded to `Collection`. + """ + super().__init__(**kwargs) + self._widths = 0.5 * np.asarray(widths).ravel() + self._heights = 0.5 * np.asarray(heights).ravel() + self._angles = np.deg2rad(angles).ravel() + self._units = units + self.set_transform(transforms.IdentityTransform()) + self._transforms = np.empty((0, 3, 3)) + self._paths = [mpath.Path.unit_circle()] + + def _set_transforms(self): + """Calculate transforms immediately before drawing.""" + + ax = self.axes + fig = self.figure + + if self._units == 'xy': + sc = 1 + elif self._units == 'x': + sc = ax.bbox.width / ax.viewLim.width + elif self._units == 'y': + sc = ax.bbox.height / ax.viewLim.height + elif self._units == 'inches': + sc = fig.dpi + elif self._units == 'points': + sc = fig.dpi / 72.0 + elif self._units == 'width': + sc = ax.bbox.width + elif self._units == 'height': + sc = ax.bbox.height + elif self._units == 'dots': + sc = 1.0 + else: + raise ValueError(f'Unrecognized units: {self._units!r}') + + self._transforms = np.zeros((len(self._widths), 3, 3)) + widths = self._widths * sc + heights = self._heights * sc + sin_angle = np.sin(self._angles) + cos_angle = np.cos(self._angles) + self._transforms[:, 0, 0] = widths * cos_angle + self._transforms[:, 0, 1] = heights * -sin_angle + self._transforms[:, 1, 0] = widths * sin_angle + self._transforms[:, 1, 1] = heights * cos_angle + self._transforms[:, 2, 2] = 1.0 + + _affine = transforms.Affine2D + if self._units == 'xy': + m = ax.transData.get_affine().get_matrix().copy() + m[:2, 2:] = 0 + self.set_transform(_affine(m)) + + @artist.allow_rasterization + def draw(self, renderer): + self._set_transforms() + super().draw(renderer) + + +class PatchCollection(Collection): + """ + A generic collection of patches. + + PatchCollection draws faster than a large number of equivalent individual + Patches. It also makes it easier to assign a colormap to a heterogeneous + collection of patches. + """ + + def __init__(self, patches, *, match_original=False, **kwargs): + """ + Parameters + ---------- + patches : list of `.Patch` + A sequence of Patch objects. This list may include + a heterogeneous assortment of different patch types. + + match_original : bool, default: False + If True, use the colors and linewidths of the original + patches. If False, new colors may be assigned by + providing the standard collection arguments, facecolor, + edgecolor, linewidths, norm or cmap. + + **kwargs + All other parameters are forwarded to `.Collection`. + + If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds* + are None, they default to their `.rcParams` patch setting, in + sequence form. + + Notes + ----- + The use of `~matplotlib.cm.ScalarMappable` functionality is optional. + If the `~matplotlib.cm.ScalarMappable` matrix ``_A`` has been set (via + a call to `~.ScalarMappable.set_array`), at draw time a call to scalar + mappable will be made to set the face colors. + """ + + if match_original: + def determine_facecolor(patch): + if patch.get_fill(): + return patch.get_facecolor() + return [0, 0, 0, 0] + + kwargs['facecolors'] = [determine_facecolor(p) for p in patches] + kwargs['edgecolors'] = [p.get_edgecolor() for p in patches] + kwargs['linewidths'] = [p.get_linewidth() for p in patches] + kwargs['linestyles'] = [p.get_linestyle() for p in patches] + kwargs['antialiaseds'] = [p.get_antialiased() for p in patches] + + super().__init__(**kwargs) + + self.set_paths(patches) + + def set_paths(self, patches): + paths = [p.get_transform().transform_path(p.get_path()) + for p in patches] + self._paths = paths + + +class TriMesh(Collection): + """ + Class for the efficient drawing of a triangular mesh using Gouraud shading. + + A triangular mesh is a `~matplotlib.tri.Triangulation` object. + """ + def __init__(self, triangulation, **kwargs): + super().__init__(**kwargs) + self._triangulation = triangulation + self._shading = 'gouraud' + + self._bbox = transforms.Bbox.unit() + + # Unfortunately this requires a copy, unless Triangulation + # was rewritten. + xy = np.hstack((triangulation.x.reshape(-1, 1), + triangulation.y.reshape(-1, 1))) + self._bbox.update_from_data_xy(xy) + + def get_paths(self): + if self._paths is None: + self.set_paths() + return self._paths + + def set_paths(self): + self._paths = self.convert_mesh_to_paths(self._triangulation) + + @staticmethod + def convert_mesh_to_paths(tri): + """ + Convert a given mesh into a sequence of `.Path` objects. + + This function is primarily of use to implementers of backends that do + not directly support meshes. + """ + triangles = tri.get_masked_triangles() + verts = np.stack((tri.x[triangles], tri.y[triangles]), axis=-1) + return [mpath.Path(x) for x in verts] + + @artist.allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + renderer.open_group(self.__class__.__name__, gid=self.get_gid()) + transform = self.get_transform() + + # Get a list of triangles and the color at each vertex. + tri = self._triangulation + triangles = tri.get_masked_triangles() + + verts = np.stack((tri.x[triangles], tri.y[triangles]), axis=-1) + + self.update_scalarmappable() + colors = self._facecolors[triangles] + + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_linewidth(self.get_linewidth()[0]) + renderer.draw_gouraud_triangles(gc, verts, colors, transform.frozen()) + gc.restore() + renderer.close_group(self.__class__.__name__) + + +class _MeshData: + r""" + Class for managing the two dimensional coordinates of Quadrilateral meshes + and the associated data with them. This class is a mixin and is intended to + be used with another collection that will implement the draw separately. + + A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are + defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is + defined by the vertices :: + + (m+1, n) ----------- (m+1, n+1) + / / + / / + / / + (m, n) -------- (m, n+1) + + The mesh need not be regular and the polygons need not be convex. + + Parameters + ---------- + coordinates : (M+1, N+1, 2) array-like + The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates + of vertex (m, n). + + shading : {'flat', 'gouraud'}, default: 'flat' + """ + def __init__(self, coordinates, *, shading='flat'): + _api.check_shape((None, None, 2), coordinates=coordinates) + self._coordinates = coordinates + self._shading = shading + + def set_array(self, A): + """ + Set the data values. + + Parameters + ---------- + A : array-like + The mesh data. Supported array shapes are: + + - (M, N) or (M*N,): a mesh with scalar data. The values are mapped + to colors using normalization and a colormap. See parameters + *norm*, *cmap*, *vmin*, *vmax*. + - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). + - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), + i.e. including transparency. + + If the values are provided as a 2D grid, the shape must match the + coordinates grid. If the values are 1D, they are reshaped to 2D. + M, N follow from the coordinates grid, where the coordinates grid + shape is (M, N) for 'gouraud' *shading* and (M+1, N+1) for 'flat' + shading. + """ + height, width = self._coordinates.shape[0:-1] + if self._shading == 'flat': + h, w = height - 1, width - 1 + else: + h, w = height, width + ok_shapes = [(h, w, 3), (h, w, 4), (h, w), (h * w,)] + if A is not None: + shape = np.shape(A) + if shape not in ok_shapes: + raise ValueError( + f"For X ({width}) and Y ({height}) with {self._shading} " + f"shading, A should have shape " + f"{' or '.join(map(str, ok_shapes))}, not {A.shape}") + return super().set_array(A) + + def get_coordinates(self): + """ + Return the vertices of the mesh as an (M+1, N+1, 2) array. + + M, N are the number of quadrilaterals in the rows / columns of the + mesh, corresponding to (M+1, N+1) vertices. + The last dimension specifies the components (x, y). + """ + return self._coordinates + + def get_edgecolor(self): + # docstring inherited + # Note that we want to return an array of shape (N*M, 4) + # a flattened RGBA collection + return super().get_edgecolor().reshape(-1, 4) + + def get_facecolor(self): + # docstring inherited + # Note that we want to return an array of shape (N*M, 4) + # a flattened RGBA collection + return super().get_facecolor().reshape(-1, 4) + + @staticmethod + def _convert_mesh_to_paths(coordinates): + """ + Convert a given mesh into a sequence of `.Path` objects. + + This function is primarily of use to implementers of backends that do + not directly support quadmeshes. + """ + if isinstance(coordinates, np.ma.MaskedArray): + c = coordinates.data + else: + c = coordinates + points = np.concatenate([ + c[:-1, :-1], + c[:-1, 1:], + c[1:, 1:], + c[1:, :-1], + c[:-1, :-1] + ], axis=2).reshape((-1, 5, 2)) + return [mpath.Path(x) for x in points] + + def _convert_mesh_to_triangles(self, coordinates): + """ + Convert a given mesh into a sequence of triangles, each point + with its own color. The result can be used to construct a call to + `~.RendererBase.draw_gouraud_triangles`. + """ + if isinstance(coordinates, np.ma.MaskedArray): + p = coordinates.data + else: + p = coordinates + + p_a = p[:-1, :-1] + p_b = p[:-1, 1:] + p_c = p[1:, 1:] + p_d = p[1:, :-1] + p_center = (p_a + p_b + p_c + p_d) / 4.0 + triangles = np.concatenate([ + p_a, p_b, p_center, + p_b, p_c, p_center, + p_c, p_d, p_center, + p_d, p_a, p_center, + ], axis=2).reshape((-1, 3, 2)) + + c = self.get_facecolor().reshape((*coordinates.shape[:2], 4)) + z = self.get_array() + mask = z.mask if np.ma.is_masked(z) else None + if mask is not None: + c[mask, 3] = np.nan + c_a = c[:-1, :-1] + c_b = c[:-1, 1:] + c_c = c[1:, 1:] + c_d = c[1:, :-1] + c_center = (c_a + c_b + c_c + c_d) / 4.0 + colors = np.concatenate([ + c_a, c_b, c_center, + c_b, c_c, c_center, + c_c, c_d, c_center, + c_d, c_a, c_center, + ], axis=2).reshape((-1, 3, 4)) + tmask = np.isnan(colors[..., 2, 3]) + return triangles[~tmask], colors[~tmask] + + +class QuadMesh(_MeshData, Collection): + r""" + Class for the efficient drawing of a quadrilateral mesh. + + A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are + defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is + defined by the vertices :: + + (m+1, n) ----------- (m+1, n+1) + / / + / / + / / + (m, n) -------- (m, n+1) + + The mesh need not be regular and the polygons need not be convex. + + Parameters + ---------- + coordinates : (M+1, N+1, 2) array-like + The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates + of vertex (m, n). + + antialiased : bool, default: True + + shading : {'flat', 'gouraud'}, default: 'flat' + + Notes + ----- + Unlike other `.Collection`\s, the default *pickradius* of `.QuadMesh` is 0, + i.e. `~.Artist.contains` checks whether the test point is within any of the + mesh quadrilaterals. + + """ + + def __init__(self, coordinates, *, antialiased=True, shading='flat', + **kwargs): + kwargs.setdefault("pickradius", 0) + super().__init__(coordinates=coordinates, shading=shading) + Collection.__init__(self, **kwargs) + + self._antialiased = antialiased + self._bbox = transforms.Bbox.unit() + self._bbox.update_from_data_xy(self._coordinates.reshape(-1, 2)) + self.set_mouseover(False) + + def get_paths(self): + if self._paths is None: + self.set_paths() + return self._paths + + def set_paths(self): + self._paths = self._convert_mesh_to_paths(self._coordinates) + self.stale = True + + def get_datalim(self, transData): + return (self.get_transform() - transData).transform_bbox(self._bbox) + + @artist.allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + renderer.open_group(self.__class__.__name__, self.get_gid()) + transform = self.get_transform() + offset_trf = self.get_offset_transform() + offsets = self.get_offsets() + + if self.have_units(): + xs = self.convert_xunits(offsets[:, 0]) + ys = self.convert_yunits(offsets[:, 1]) + offsets = np.column_stack([xs, ys]) + + self.update_scalarmappable() + + if not transform.is_affine: + coordinates = self._coordinates.reshape((-1, 2)) + coordinates = transform.transform(coordinates) + coordinates = coordinates.reshape(self._coordinates.shape) + transform = transforms.IdentityTransform() + else: + coordinates = self._coordinates + + if not offset_trf.is_affine: + offsets = offset_trf.transform_non_affine(offsets) + offset_trf = offset_trf.get_affine() + + gc = renderer.new_gc() + gc.set_snap(self.get_snap()) + self._set_gc_clip(gc) + gc.set_linewidth(self.get_linewidth()[0]) + + if self._shading == 'gouraud': + triangles, colors = self._convert_mesh_to_triangles(coordinates) + renderer.draw_gouraud_triangles( + gc, triangles, colors, transform.frozen()) + else: + renderer.draw_quad_mesh( + gc, transform.frozen(), + coordinates.shape[1] - 1, coordinates.shape[0] - 1, + coordinates, offsets, offset_trf, + # Backends expect flattened rgba arrays (n*m, 4) for fc and ec + self.get_facecolor().reshape((-1, 4)), + self._antialiased, self.get_edgecolors().reshape((-1, 4))) + gc.restore() + renderer.close_group(self.__class__.__name__) + self.stale = False + + def get_cursor_data(self, event): + contained, info = self.contains(event) + if contained and self.get_array() is not None: + return self.get_array().ravel()[info["ind"]] + return None + + +class PolyQuadMesh(_MeshData, PolyCollection): + """ + Class for drawing a quadrilateral mesh as individual Polygons. + + A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are + defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is + defined by the vertices :: + + (m+1, n) ----------- (m+1, n+1) + / / + / / + / / + (m, n) -------- (m, n+1) + + The mesh need not be regular and the polygons need not be convex. + + Parameters + ---------- + coordinates : (M+1, N+1, 2) array-like + The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates + of vertex (m, n). + + Notes + ----- + Unlike `.QuadMesh`, this class will draw each cell as an individual Polygon. + This is significantly slower, but allows for more flexibility when wanting + to add additional properties to the cells, such as hatching. + + Another difference from `.QuadMesh` is that if any of the vertices or data + of a cell are masked, that Polygon will **not** be drawn and it won't be in + the list of paths returned. + """ + + def __init__(self, coordinates, **kwargs): + # We need to keep track of whether we are using deprecated compression + # Update it after the initializers + self._deprecated_compression = False + super().__init__(coordinates=coordinates) + PolyCollection.__init__(self, verts=[], **kwargs) + # Store this during the compression deprecation period + self._original_mask = ~self._get_unmasked_polys() + self._deprecated_compression = np.any(self._original_mask) + # Setting the verts updates the paths of the PolyCollection + # This is called after the initializers to make sure the kwargs + # have all been processed and available for the masking calculations + self._set_unmasked_verts() + + def _get_unmasked_polys(self): + """Get the unmasked regions using the coordinates and array""" + # mask(X) | mask(Y) + mask = np.any(np.ma.getmaskarray(self._coordinates), axis=-1) + + # We want the shape of the polygon, which is the corner of each X/Y array + mask = (mask[0:-1, 0:-1] | mask[1:, 1:] | mask[0:-1, 1:] | mask[1:, 0:-1]) + + if (getattr(self, "_deprecated_compression", False) and + np.any(self._original_mask)): + return ~(mask | self._original_mask) + # Take account of the array data too, temporarily avoiding + # the compression warning and resetting the variable after the call + with cbook._setattr_cm(self, _deprecated_compression=False): + arr = self.get_array() + if arr is not None: + arr = np.ma.getmaskarray(arr) + if arr.ndim == 3: + # RGB(A) case + mask |= np.any(arr, axis=-1) + elif arr.ndim == 2: + mask |= arr + else: + mask |= arr.reshape(self._coordinates[:-1, :-1, :].shape[:2]) + return ~mask + + def _set_unmasked_verts(self): + X = self._coordinates[..., 0] + Y = self._coordinates[..., 1] + + unmask = self._get_unmasked_polys() + X1 = np.ma.filled(X[:-1, :-1])[unmask] + Y1 = np.ma.filled(Y[:-1, :-1])[unmask] + X2 = np.ma.filled(X[1:, :-1])[unmask] + Y2 = np.ma.filled(Y[1:, :-1])[unmask] + X3 = np.ma.filled(X[1:, 1:])[unmask] + Y3 = np.ma.filled(Y[1:, 1:])[unmask] + X4 = np.ma.filled(X[:-1, 1:])[unmask] + Y4 = np.ma.filled(Y[:-1, 1:])[unmask] + npoly = len(X1) + + xy = np.ma.stack([X1, Y1, X2, Y2, X3, Y3, X4, Y4, X1, Y1], axis=-1) + verts = xy.reshape((npoly, 5, 2)) + self.set_verts(verts) + + def get_edgecolor(self): + # docstring inherited + # We only want to return the facecolors of the polygons + # that were drawn. + ec = super().get_edgecolor() + unmasked_polys = self._get_unmasked_polys().ravel() + if len(ec) != len(unmasked_polys): + # Mapping is off + return ec + return ec[unmasked_polys, :] + + def get_facecolor(self): + # docstring inherited + # We only want to return the facecolors of the polygons + # that were drawn. + fc = super().get_facecolor() + unmasked_polys = self._get_unmasked_polys().ravel() + if len(fc) != len(unmasked_polys): + # Mapping is off + return fc + return fc[unmasked_polys, :] + + def set_array(self, A): + # docstring inherited + prev_unmask = self._get_unmasked_polys() + # MPL <3.8 compressed the mask, so we need to handle flattened 1d input + # until the deprecation expires, also only warning when there are masked + # elements and thus compression occurring. + if self._deprecated_compression and np.ndim(A) == 1: + _api.warn_deprecated("3.8", message="Setting a PolyQuadMesh array using " + "the compressed values is deprecated. " + "Pass the full 2D shape of the original array " + f"{prev_unmask.shape} including the masked elements.") + Afull = np.empty(self._original_mask.shape) + Afull[~self._original_mask] = A + # We also want to update the mask with any potential + # new masked elements that came in. But, we don't want + # to update any of the compression from the original + mask = self._original_mask.copy() + mask[~self._original_mask] |= np.ma.getmask(A) + A = np.ma.array(Afull, mask=mask) + return super().set_array(A) + self._deprecated_compression = False + super().set_array(A) + # If the mask has changed at all we need to update + # the set of Polys that we are drawing + if not np.array_equal(prev_unmask, self._get_unmasked_polys()): + self._set_unmasked_verts() + + def get_array(self): + # docstring inherited + # Can remove this entire function once the deprecation period ends + A = super().get_array() + if A is None: + return + if self._deprecated_compression and np.any(np.ma.getmask(A)): + _api.warn_deprecated("3.8", message=( + "Getting the array from a PolyQuadMesh will return the full " + "array in the future (uncompressed). To get this behavior now " + "set the PolyQuadMesh with a 2D array .set_array(data2d).")) + # Setting an array of a polycollection required + # compressing the array + return np.ma.compressed(A) + return A diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.pyi new file mode 100644 index 00000000..01682a55 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/collections.pyi @@ -0,0 +1,242 @@ +from collections.abc import Callable, Iterable, Sequence +from typing import Literal + +import numpy as np +from numpy.typing import ArrayLike, NDArray + +from . import artist, cm, transforms +from .backend_bases import MouseEvent +from .artist import Artist +from .colors import Normalize, Colormap +from .lines import Line2D +from .path import Path +from .patches import Patch +from .ticker import Locator, Formatter +from .tri import Triangulation +from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType + +class Collection(artist.Artist, cm.ScalarMappable): + def __init__( + self, + *, + edgecolors: ColorType | Sequence[ColorType] | None = ..., + facecolors: ColorType | Sequence[ColorType] | None = ..., + linewidths: float | Sequence[float] | None = ..., + linestyles: LineStyleType | Sequence[LineStyleType] = ..., + capstyle: CapStyleType | None = ..., + joinstyle: JoinStyleType | None = ..., + antialiaseds: bool | Sequence[bool] | None = ..., + offsets: tuple[float, float] | Sequence[tuple[float, float]] | None = ..., + offset_transform: transforms.Transform | None = ..., + norm: Normalize | None = ..., + cmap: Colormap | None = ..., + pickradius: float = ..., + hatch: str | None = ..., + urls: Sequence[str] | None = ..., + zorder: float = ..., + **kwargs + ) -> None: ... + def get_paths(self) -> Sequence[Path]: ... + def set_paths(self, paths: Sequence[Path]) -> None: ... + def get_transforms(self) -> Sequence[transforms.Transform]: ... + def get_offset_transform(self) -> transforms.Transform: ... + def set_offset_transform(self, offset_transform: transforms.Transform) -> None: ... + def get_datalim(self, transData: transforms.Transform) -> transforms.Bbox: ... + def set_pickradius(self, pickradius: float) -> None: ... + def get_pickradius(self) -> float: ... + def set_urls(self, urls: Sequence[str | None]) -> None: ... + def get_urls(self) -> Sequence[str | None]: ... + def set_hatch(self, hatch: str) -> None: ... + def get_hatch(self) -> str: ... + def set_offsets(self, offsets: ArrayLike) -> None: ... + def get_offsets(self) -> ArrayLike: ... + def set_linewidth(self, lw: float | Sequence[float]) -> None: ... + def set_linestyle(self, ls: LineStyleType | Sequence[LineStyleType]) -> None: ... + def set_capstyle(self, cs: CapStyleType) -> None: ... + def get_capstyle(self) -> Literal["butt", "projecting", "round"] | None: ... + def set_joinstyle(self, js: JoinStyleType) -> None: ... + def get_joinstyle(self) -> Literal["miter", "round", "bevel"] | None: ... + def set_antialiased(self, aa: bool | Sequence[bool]) -> None: ... + def get_antialiased(self) -> NDArray[np.bool_]: ... + def set_color(self, c: ColorType | Sequence[ColorType]) -> None: ... + def set_facecolor(self, c: ColorType | Sequence[ColorType]) -> None: ... + def get_facecolor(self) -> ColorType | Sequence[ColorType]: ... + def get_edgecolor(self) -> ColorType | Sequence[ColorType]: ... + def set_edgecolor(self, c: ColorType | Sequence[ColorType]) -> None: ... + def set_alpha(self, alpha: float | Sequence[float] | None) -> None: ... + def get_linewidth(self) -> float | Sequence[float]: ... + def get_linestyle(self) -> LineStyleType | Sequence[LineStyleType]: ... + def update_scalarmappable(self) -> None: ... + def get_fill(self) -> bool: ... + def update_from(self, other: Artist) -> None: ... + +class _CollectionWithSizes(Collection): + def get_sizes(self) -> np.ndarray: ... + def set_sizes(self, sizes: ArrayLike | None, dpi: float = ...) -> None: ... + +class PathCollection(_CollectionWithSizes): + def __init__( + self, paths: Sequence[Path], sizes: ArrayLike | None = ..., **kwargs + ) -> None: ... + def set_paths(self, paths: Sequence[Path]) -> None: ... + def get_paths(self) -> Sequence[Path]: ... + def legend_elements( + self, + prop: Literal["colors", "sizes"] = ..., + num: int | Literal["auto"] | ArrayLike | Locator = ..., + fmt: str | Formatter | None = ..., + func: Callable[[ArrayLike], ArrayLike] = ..., + **kwargs, + ) -> tuple[list[Line2D], list[str]]: ... + +class PolyCollection(_CollectionWithSizes): + def __init__( + self, + verts: Sequence[ArrayLike], + sizes: ArrayLike | None = ..., + *, + closed: bool = ..., + **kwargs + ) -> None: ... + def set_verts( + self, verts: Sequence[ArrayLike | Path], closed: bool = ... + ) -> None: ... + def set_paths(self, verts: Sequence[Path], closed: bool = ...) -> None: ... + def set_verts_and_codes( + self, verts: Sequence[ArrayLike | Path], codes: Sequence[int] + ) -> None: ... + +class BrokenBarHCollection(PolyCollection): + def __init__( + self, + xranges: Iterable[tuple[float, float]], + yrange: tuple[float, float], + **kwargs + ) -> None: ... + @classmethod + def span_where( + cls, x: ArrayLike, ymin: float, ymax: float, where: ArrayLike, **kwargs + ) -> BrokenBarHCollection: ... + +class RegularPolyCollection(_CollectionWithSizes): + def __init__( + self, numsides: int, *, rotation: float = ..., sizes: ArrayLike = ..., **kwargs + ) -> None: ... + def get_numsides(self) -> int: ... + def get_rotation(self) -> float: ... + +class StarPolygonCollection(RegularPolyCollection): ... +class AsteriskPolygonCollection(RegularPolyCollection): ... + +class LineCollection(Collection): + def __init__( + self, segments: Sequence[ArrayLike], *, zorder: float = ..., **kwargs + ) -> None: ... + def set_segments(self, segments: Sequence[ArrayLike] | None) -> None: ... + def set_verts(self, segments: Sequence[ArrayLike] | None) -> None: ... + def set_paths(self, segments: Sequence[ArrayLike] | None) -> None: ... # type: ignore[override] + def get_segments(self) -> list[np.ndarray]: ... + def set_color(self, c: ColorType | Sequence[ColorType]) -> None: ... + def set_colors(self, c: ColorType | Sequence[ColorType]) -> None: ... + def set_gapcolor(self, gapcolor: ColorType | Sequence[ColorType] | None) -> None: ... + def get_color(self) -> ColorType | Sequence[ColorType]: ... + def get_colors(self) -> ColorType | Sequence[ColorType]: ... + def get_gapcolor(self) -> ColorType | Sequence[ColorType] | None: ... + + +class EventCollection(LineCollection): + def __init__( + self, + positions: ArrayLike, + orientation: Literal["horizontal", "vertical"] = ..., + *, + lineoffset: float = ..., + linelength: float = ..., + linewidth: float | Sequence[float] | None = ..., + color: ColorType | Sequence[ColorType] | None = ..., + linestyle: LineStyleType | Sequence[LineStyleType] = ..., + antialiased: bool | Sequence[bool] | None = ..., + **kwargs + ) -> None: ... + def get_positions(self) -> list[float]: ... + def set_positions(self, positions: Sequence[float] | None) -> None: ... + def add_positions(self, position: Sequence[float] | None) -> None: ... + def extend_positions(self, position: Sequence[float] | None) -> None: ... + def append_positions(self, position: Sequence[float] | None) -> None: ... + def is_horizontal(self) -> bool: ... + def get_orientation(self) -> Literal["horizontal", "vertical"]: ... + def switch_orientation(self) -> None: ... + def set_orientation( + self, orientation: Literal["horizontal", "vertical"] + ) -> None: ... + def get_linelength(self) -> float | Sequence[float]: ... + def set_linelength(self, linelength: float | Sequence[float]) -> None: ... + def get_lineoffset(self) -> float: ... + def set_lineoffset(self, lineoffset: float) -> None: ... + def get_linewidth(self) -> float: ... + def get_linewidths(self) -> Sequence[float]: ... + def get_color(self) -> ColorType: ... + +class CircleCollection(_CollectionWithSizes): + def __init__(self, sizes: float | ArrayLike, **kwargs) -> None: ... + +class EllipseCollection(Collection): + def __init__( + self, + widths: ArrayLike, + heights: ArrayLike, + angles: ArrayLike, + *, + units: Literal[ + "points", "inches", "dots", "width", "height", "x", "y", "xy" + ] = ..., + **kwargs + ) -> None: ... + +class PatchCollection(Collection): + def __init__( + self, patches: Iterable[Patch], *, match_original: bool = ..., **kwargs + ) -> None: ... + def set_paths(self, patches: Iterable[Patch]) -> None: ... # type: ignore[override] + +class TriMesh(Collection): + def __init__(self, triangulation: Triangulation, **kwargs) -> None: ... + def get_paths(self) -> list[Path]: ... + # Parent class has an argument, perhaps add a noop arg? + def set_paths(self) -> None: ... # type: ignore[override] + @staticmethod + def convert_mesh_to_paths(tri: Triangulation) -> list[Path]: ... + +class _MeshData: + def __init__( + self, + coordinates: ArrayLike, + *, + shading: Literal["flat", "gouraud"] = ..., + ) -> None: ... + def set_array(self, A: ArrayLike | None) -> None: ... + def get_coordinates(self) -> ArrayLike: ... + def get_facecolor(self) -> ColorType | Sequence[ColorType]: ... + def get_edgecolor(self) -> ColorType | Sequence[ColorType]: ... + +class QuadMesh(_MeshData, Collection): + def __init__( + self, + coordinates: ArrayLike, + *, + antialiased: bool = ..., + shading: Literal["flat", "gouraud"] = ..., + **kwargs + ) -> None: ... + def get_paths(self) -> list[Path]: ... + # Parent class has an argument, perhaps add a noop arg? + def set_paths(self) -> None: ... # type: ignore[override] + def get_datalim(self, transData: transforms.Transform) -> transforms.Bbox: ... + def get_cursor_data(self, event: MouseEvent) -> float: ... + +class PolyQuadMesh(_MeshData, PolyCollection): + def __init__( + self, + coordinates: ArrayLike, + **kwargs + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.py new file mode 100644 index 00000000..6c92f379 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.py @@ -0,0 +1,1580 @@ +""" +Colorbars are a visualization of the mapping from scalar values to colors. +In Matplotlib they are drawn into a dedicated `~.axes.Axes`. + +.. note:: + Colorbars are typically created through `.Figure.colorbar` or its pyplot + wrapper `.pyplot.colorbar`, which internally use `.Colorbar` together with + `.make_axes_gridspec` (for `.GridSpec`-positioned axes) or `.make_axes` (for + non-`.GridSpec`-positioned axes). + + End-users most likely won't need to directly use this module's API. +""" + +import logging + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook, collections, cm, colors, contour, ticker +import matplotlib.artist as martist +import matplotlib.patches as mpatches +import matplotlib.path as mpath +import matplotlib.spines as mspines +import matplotlib.transforms as mtransforms +from matplotlib import _docstring + +_log = logging.getLogger(__name__) + +_docstring.interpd.update( + _make_axes_kw_doc=""" +location : None or {'left', 'right', 'top', 'bottom'} + The location, relative to the parent axes, where the colorbar axes + is created. It also determines the *orientation* of the colorbar + (colorbars on the left and right are vertical, colorbars at the top + and bottom are horizontal). If None, the location will come from the + *orientation* if it is set (vertical colorbars on the right, horizontal + ones at the bottom), or default to 'right' if *orientation* is unset. + +orientation : None or {'vertical', 'horizontal'} + The orientation of the colorbar. It is preferable to set the *location* + of the colorbar, as that also determines the *orientation*; passing + incompatible values for *location* and *orientation* raises an exception. + +fraction : float, default: 0.15 + Fraction of original axes to use for colorbar. + +shrink : float, default: 1.0 + Fraction by which to multiply the size of the colorbar. + +aspect : float, default: 20 + Ratio of long to short dimensions. + +pad : float, default: 0.05 if vertical, 0.15 if horizontal + Fraction of original axes between colorbar and new image axes. + +anchor : (float, float), optional + The anchor point of the colorbar axes. + Defaults to (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal. + +panchor : (float, float), or *False*, optional + The anchor point of the colorbar parent axes. If *False*, the parent + axes' anchor will be unchanged. + Defaults to (1.0, 0.5) if vertical; (0.5, 0.0) if horizontal.""", + _colormap_kw_doc=""" +extend : {'neither', 'both', 'min', 'max'} + Make pointed end(s) for out-of-range values (unless 'neither'). These are + set for a given colormap using the colormap set_under and set_over methods. + +extendfrac : {*None*, 'auto', length, lengths} + If set to *None*, both the minimum and maximum triangular colorbar + extensions will have a length of 5% of the interior colorbar length (this + is the default setting). + + If set to 'auto', makes the triangular colorbar extensions the same lengths + as the interior boxes (when *spacing* is set to 'uniform') or the same + lengths as the respective adjacent interior boxes (when *spacing* is set to + 'proportional'). + + If a scalar, indicates the length of both the minimum and maximum + triangular colorbar extensions as a fraction of the interior colorbar + length. A two-element sequence of fractions may also be given, indicating + the lengths of the minimum and maximum colorbar extensions respectively as + a fraction of the interior colorbar length. + +extendrect : bool + If *False* the minimum and maximum colorbar extensions will be triangular + (the default). If *True* the extensions will be rectangular. + +spacing : {'uniform', 'proportional'} + For discrete colorbars (`.BoundaryNorm` or contours), 'uniform' gives each + color the same space; 'proportional' makes the space proportional to the + data interval. + +ticks : None or list of ticks or Locator + If None, ticks are determined automatically from the input. + +format : None or str or Formatter + If None, `~.ticker.ScalarFormatter` is used. + Format strings, e.g., ``"%4.2e"`` or ``"{x:.2e}"``, are supported. + An alternative `~.ticker.Formatter` may be given instead. + +drawedges : bool + Whether to draw lines at color boundaries. + +label : str + The label on the colorbar's long axis. + +boundaries, values : None or a sequence + If unset, the colormap will be displayed on a 0-1 scale. + If sequences, *values* must have a length 1 less than *boundaries*. For + each region delimited by adjacent entries in *boundaries*, the color mapped + to the corresponding value in values will be used. + Normally only useful for indexed colors (i.e. ``norm=NoNorm()``) or other + unusual circumstances.""") + + +def _set_ticks_on_axis_warn(*args, **kwargs): + # a top level function which gets put in at the axes' + # set_xticks and set_yticks by Colorbar.__init__. + _api.warn_external("Use the colorbar set_ticks() method instead.") + + +class _ColorbarSpine(mspines.Spine): + def __init__(self, axes): + self._ax = axes + super().__init__(axes, 'colorbar', mpath.Path(np.empty((0, 2)))) + mpatches.Patch.set_transform(self, axes.transAxes) + + def get_window_extent(self, renderer=None): + # This Spine has no Axis associated with it, and doesn't need to adjust + # its location, so we can directly get the window extent from the + # super-super-class. + return mpatches.Patch.get_window_extent(self, renderer=renderer) + + def set_xy(self, xy): + self._path = mpath.Path(xy, closed=True) + self._xy = xy + self.stale = True + + def draw(self, renderer): + ret = mpatches.Patch.draw(self, renderer) + self.stale = False + return ret + + +class _ColorbarAxesLocator: + """ + Shrink the axes if there are triangular or rectangular extends. + """ + def __init__(self, cbar): + self._cbar = cbar + self._orig_locator = cbar.ax._axes_locator + + def __call__(self, ax, renderer): + if self._orig_locator is not None: + pos = self._orig_locator(ax, renderer) + else: + pos = ax.get_position(original=True) + if self._cbar.extend == 'neither': + return pos + + y, extendlen = self._cbar._proportional_y() + if not self._cbar._extend_lower(): + extendlen[0] = 0 + if not self._cbar._extend_upper(): + extendlen[1] = 0 + len = sum(extendlen) + 1 + shrink = 1 / len + offset = extendlen[0] / len + # we need to reset the aspect ratio of the axes to account + # of the extends... + if hasattr(ax, '_colorbar_info'): + aspect = ax._colorbar_info['aspect'] + else: + aspect = False + # now shrink and/or offset to take into account the + # extend tri/rectangles. + if self._cbar.orientation == 'vertical': + if aspect: + self._cbar.ax.set_box_aspect(aspect*shrink) + pos = pos.shrunk(1, shrink).translated(0, offset * pos.height) + else: + if aspect: + self._cbar.ax.set_box_aspect(1/(aspect * shrink)) + pos = pos.shrunk(shrink, 1).translated(offset * pos.width, 0) + return pos + + def get_subplotspec(self): + # make tight_layout happy.. + return ( + self._cbar.ax.get_subplotspec() + or getattr(self._orig_locator, "get_subplotspec", lambda: None)()) + + +@_docstring.interpd +class Colorbar: + r""" + Draw a colorbar in an existing axes. + + Typically, colorbars are created using `.Figure.colorbar` or + `.pyplot.colorbar` and associated with `.ScalarMappable`\s (such as an + `.AxesImage` generated via `~.axes.Axes.imshow`). + + In order to draw a colorbar not associated with other elements in the + figure, e.g. when showing a colormap by itself, one can create an empty + `.ScalarMappable`, or directly pass *cmap* and *norm* instead of *mappable* + to `Colorbar`. + + Useful public methods are :meth:`set_label` and :meth:`add_lines`. + + Attributes + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` instance in which the colorbar is drawn. + lines : list + A list of `.LineCollection` (empty if no lines were drawn). + dividers : `.LineCollection` + A LineCollection (empty if *drawedges* is ``False``). + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` instance in which the colorbar is drawn. + + mappable : `.ScalarMappable` + The mappable whose colormap and norm will be used. + + To show the under- and over- value colors, the mappable's norm should + be specified as :: + + norm = colors.Normalize(clip=False) + + To show the colors versus index instead of on a 0-1 scale, use:: + + norm=colors.NoNorm() + + cmap : `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` + The colormap to use. This parameter is ignored, unless *mappable* is + None. + + norm : `~matplotlib.colors.Normalize` + The normalization to use. This parameter is ignored, unless *mappable* + is None. + + alpha : float + The colorbar transparency between 0 (transparent) and 1 (opaque). + + orientation : None or {'vertical', 'horizontal'} + If None, use the value determined by *location*. If both + *orientation* and *location* are None then defaults to 'vertical'. + + ticklocation : {'auto', 'left', 'right', 'top', 'bottom'} + The location of the colorbar ticks. The *ticklocation* must match + *orientation*. For example, a horizontal colorbar can only have ticks + at the top or the bottom. If 'auto', the ticks will be the same as + *location*, so a colorbar to the left will have ticks to the left. If + *location* is None, the ticks will be at the bottom for a horizontal + colorbar and at the right for a vertical. + + drawedges : bool + Whether to draw lines at color boundaries. + + + %(_colormap_kw_doc)s + + location : None or {'left', 'right', 'top', 'bottom'} + Set the *orientation* and *ticklocation* of the colorbar using a + single argument. Colorbars on the left and right are vertical, + colorbars at the top and bottom are horizontal. The *ticklocation* is + the same as *location*, so if *location* is 'top', the ticks are on + the top. *orientation* and/or *ticklocation* can be provided as well + and overrides the value set by *location*, but there will be an error + for incompatible combinations. + + .. versionadded:: 3.7 + """ + + n_rasterize = 50 # rasterize solids if number of colors >= n_rasterize + + def __init__(self, ax, mappable=None, *, cmap=None, + norm=None, + alpha=None, + values=None, + boundaries=None, + orientation=None, + ticklocation='auto', + extend=None, + spacing='uniform', # uniform or proportional + ticks=None, + format=None, + drawedges=False, + extendfrac=None, + extendrect=False, + label='', + location=None, + ): + + if mappable is None: + mappable = cm.ScalarMappable(norm=norm, cmap=cmap) + + self.mappable = mappable + cmap = mappable.cmap + norm = mappable.norm + + filled = True + if isinstance(mappable, contour.ContourSet): + cs = mappable + alpha = cs.get_alpha() + boundaries = cs._levels + values = cs.cvalues + extend = cs.extend + filled = cs.filled + if ticks is None: + ticks = ticker.FixedLocator(cs.levels, nbins=10) + elif isinstance(mappable, martist.Artist): + alpha = mappable.get_alpha() + + mappable.colorbar = self + mappable.colorbar_cid = mappable.callbacks.connect( + 'changed', self.update_normal) + + location_orientation = _get_orientation_from_location(location) + + _api.check_in_list( + [None, 'vertical', 'horizontal'], orientation=orientation) + _api.check_in_list( + ['auto', 'left', 'right', 'top', 'bottom'], + ticklocation=ticklocation) + _api.check_in_list( + ['uniform', 'proportional'], spacing=spacing) + + if location_orientation is not None and orientation is not None: + if location_orientation != orientation: + raise TypeError( + "location and orientation are mutually exclusive") + else: + orientation = orientation or location_orientation or "vertical" + + self.ax = ax + self.ax._axes_locator = _ColorbarAxesLocator(self) + + if extend is None: + if (not isinstance(mappable, contour.ContourSet) + and getattr(cmap, 'colorbar_extend', False) is not False): + extend = cmap.colorbar_extend + elif hasattr(norm, 'extend'): + extend = norm.extend + else: + extend = 'neither' + self.alpha = None + # Call set_alpha to handle array-like alphas properly + self.set_alpha(alpha) + self.cmap = cmap + self.norm = norm + self.values = values + self.boundaries = boundaries + self.extend = extend + self._inside = _api.check_getitem( + {'neither': slice(0, None), 'both': slice(1, -1), + 'min': slice(1, None), 'max': slice(0, -1)}, + extend=extend) + self.spacing = spacing + self.orientation = orientation + self.drawedges = drawedges + self._filled = filled + self.extendfrac = extendfrac + self.extendrect = extendrect + self._extend_patches = [] + self.solids = None + self.solids_patches = [] + self.lines = [] + + for spine in self.ax.spines.values(): + spine.set_visible(False) + self.outline = self.ax.spines['outline'] = _ColorbarSpine(self.ax) + + self.dividers = collections.LineCollection( + [], + colors=[mpl.rcParams['axes.edgecolor']], + linewidths=[0.5 * mpl.rcParams['axes.linewidth']], + clip_on=False) + self.ax.add_collection(self.dividers) + + self._locator = None + self._minorlocator = None + self._formatter = None + self._minorformatter = None + + if ticklocation == 'auto': + ticklocation = _get_ticklocation_from_orientation( + orientation) if location is None else location + self.ticklocation = ticklocation + + self.set_label(label) + self._reset_locator_formatter_scale() + + if np.iterable(ticks): + self._locator = ticker.FixedLocator(ticks, nbins=len(ticks)) + else: + self._locator = ticks + + if isinstance(format, str): + # Check format between FormatStrFormatter and StrMethodFormatter + try: + self._formatter = ticker.FormatStrFormatter(format) + _ = self._formatter(0) + except (TypeError, ValueError): + self._formatter = ticker.StrMethodFormatter(format) + else: + self._formatter = format # Assume it is a Formatter or None + self._draw_all() + + if isinstance(mappable, contour.ContourSet) and not mappable.filled: + self.add_lines(mappable) + + # Link the Axes and Colorbar for interactive use + self.ax._colorbar = self + # Don't navigate on any of these types of mappables + if (isinstance(self.norm, (colors.BoundaryNorm, colors.NoNorm)) or + isinstance(self.mappable, contour.ContourSet)): + self.ax.set_navigate(False) + + # These are the functions that set up interactivity on this colorbar + self._interactive_funcs = ["_get_view", "_set_view", + "_set_view_from_bbox", "drag_pan"] + for x in self._interactive_funcs: + setattr(self.ax, x, getattr(self, x)) + # Set the cla function to the cbar's method to override it + self.ax.cla = self._cbar_cla + # Callbacks for the extend calculations to handle inverting the axis + self._extend_cid1 = self.ax.callbacks.connect( + "xlim_changed", self._do_extends) + self._extend_cid2 = self.ax.callbacks.connect( + "ylim_changed", self._do_extends) + + @property + def locator(self): + """Major tick `.Locator` for the colorbar.""" + return self._long_axis().get_major_locator() + + @locator.setter + def locator(self, loc): + self._long_axis().set_major_locator(loc) + self._locator = loc + + @property + def minorlocator(self): + """Minor tick `.Locator` for the colorbar.""" + return self._long_axis().get_minor_locator() + + @minorlocator.setter + def minorlocator(self, loc): + self._long_axis().set_minor_locator(loc) + self._minorlocator = loc + + @property + def formatter(self): + """Major tick label `.Formatter` for the colorbar.""" + return self._long_axis().get_major_formatter() + + @formatter.setter + def formatter(self, fmt): + self._long_axis().set_major_formatter(fmt) + self._formatter = fmt + + @property + def minorformatter(self): + """Minor tick `.Formatter` for the colorbar.""" + return self._long_axis().get_minor_formatter() + + @minorformatter.setter + def minorformatter(self, fmt): + self._long_axis().set_minor_formatter(fmt) + self._minorformatter = fmt + + def _cbar_cla(self): + """Function to clear the interactive colorbar state.""" + for x in self._interactive_funcs: + delattr(self.ax, x) + # We now restore the old cla() back and can call it directly + del self.ax.cla + self.ax.cla() + + def update_normal(self, mappable): + """ + Update solid patches, lines, etc. + + This is meant to be called when the norm of the image or contour plot + to which this colorbar belongs changes. + + If the norm on the mappable is different than before, this resets the + locator and formatter for the axis, so if these have been customized, + they will need to be customized again. However, if the norm only + changes values of *vmin*, *vmax* or *cmap* then the old formatter + and locator will be preserved. + """ + _log.debug('colorbar update normal %r %r', mappable.norm, self.norm) + self.mappable = mappable + self.set_alpha(mappable.get_alpha()) + self.cmap = mappable.cmap + if mappable.norm != self.norm: + self.norm = mappable.norm + self._reset_locator_formatter_scale() + + self._draw_all() + if isinstance(self.mappable, contour.ContourSet): + CS = self.mappable + if not CS.filled: + self.add_lines(CS) + self.stale = True + + def _draw_all(self): + """ + Calculate any free parameters based on the current cmap and norm, + and do all the drawing. + """ + if self.orientation == 'vertical': + if mpl.rcParams['ytick.minor.visible']: + self.minorticks_on() + else: + if mpl.rcParams['xtick.minor.visible']: + self.minorticks_on() + self._long_axis().set(label_position=self.ticklocation, + ticks_position=self.ticklocation) + self._short_axis().set_ticks([]) + self._short_axis().set_ticks([], minor=True) + + # Set self._boundaries and self._values, including extensions. + # self._boundaries are the edges of each square of color, and + # self._values are the value to map into the norm to get the + # color: + self._process_values() + # Set self.vmin and self.vmax to first and last boundary, excluding + # extensions: + self.vmin, self.vmax = self._boundaries[self._inside][[0, -1]] + # Compute the X/Y mesh. + X, Y = self._mesh() + # draw the extend triangles, and shrink the inner axes to accommodate. + # also adds the outline path to self.outline spine: + self._do_extends() + lower, upper = self.vmin, self.vmax + if self._long_axis().get_inverted(): + # If the axis is inverted, we need to swap the vmin/vmax + lower, upper = upper, lower + if self.orientation == 'vertical': + self.ax.set_xlim(0, 1) + self.ax.set_ylim(lower, upper) + else: + self.ax.set_ylim(0, 1) + self.ax.set_xlim(lower, upper) + + # set up the tick locators and formatters. A bit complicated because + # boundary norms + uniform spacing requires a manual locator. + self.update_ticks() + + if self._filled: + ind = np.arange(len(self._values)) + if self._extend_lower(): + ind = ind[1:] + if self._extend_upper(): + ind = ind[:-1] + self._add_solids(X, Y, self._values[ind, np.newaxis]) + + def _add_solids(self, X, Y, C): + """Draw the colors; optionally add separators.""" + # Cleanup previously set artists. + if self.solids is not None: + self.solids.remove() + for solid in self.solids_patches: + solid.remove() + # Add new artist(s), based on mappable type. Use individual patches if + # hatching is needed, pcolormesh otherwise. + mappable = getattr(self, 'mappable', None) + if (isinstance(mappable, contour.ContourSet) + and any(hatch is not None for hatch in mappable.hatches)): + self._add_solids_patches(X, Y, C, mappable) + else: + self.solids = self.ax.pcolormesh( + X, Y, C, cmap=self.cmap, norm=self.norm, alpha=self.alpha, + edgecolors='none', shading='flat') + if not self.drawedges: + if len(self._y) >= self.n_rasterize: + self.solids.set_rasterized(True) + self._update_dividers() + + def _update_dividers(self): + if not self.drawedges: + self.dividers.set_segments([]) + return + # Place all *internal* dividers. + if self.orientation == 'vertical': + lims = self.ax.get_ylim() + bounds = (lims[0] < self._y) & (self._y < lims[1]) + else: + lims = self.ax.get_xlim() + bounds = (lims[0] < self._y) & (self._y < lims[1]) + y = self._y[bounds] + # And then add outer dividers if extensions are on. + if self._extend_lower(): + y = np.insert(y, 0, lims[0]) + if self._extend_upper(): + y = np.append(y, lims[1]) + X, Y = np.meshgrid([0, 1], y) + if self.orientation == 'vertical': + segments = np.dstack([X, Y]) + else: + segments = np.dstack([Y, X]) + self.dividers.set_segments(segments) + + def _add_solids_patches(self, X, Y, C, mappable): + hatches = mappable.hatches * (len(C) + 1) # Have enough hatches. + if self._extend_lower(): + # remove first hatch that goes into the extend patch + hatches = hatches[1:] + patches = [] + for i in range(len(X) - 1): + xy = np.array([[X[i, 0], Y[i, 1]], + [X[i, 1], Y[i, 0]], + [X[i + 1, 1], Y[i + 1, 0]], + [X[i + 1, 0], Y[i + 1, 1]]]) + patch = mpatches.PathPatch(mpath.Path(xy), + facecolor=self.cmap(self.norm(C[i][0])), + hatch=hatches[i], linewidth=0, + antialiased=False, alpha=self.alpha) + self.ax.add_patch(patch) + patches.append(patch) + self.solids_patches = patches + + def _do_extends(self, ax=None): + """ + Add the extend tri/rectangles on the outside of the axes. + + ax is unused, but required due to the callbacks on xlim/ylim changed + """ + # Clean up any previous extend patches + for patch in self._extend_patches: + patch.remove() + self._extend_patches = [] + # extend lengths are fraction of the *inner* part of colorbar, + # not the total colorbar: + _, extendlen = self._proportional_y() + bot = 0 - (extendlen[0] if self._extend_lower() else 0) + top = 1 + (extendlen[1] if self._extend_upper() else 0) + + # xyout is the outline of the colorbar including the extend patches: + if not self.extendrect: + # triangle: + xyout = np.array([[0, 0], [0.5, bot], [1, 0], + [1, 1], [0.5, top], [0, 1], [0, 0]]) + else: + # rectangle: + xyout = np.array([[0, 0], [0, bot], [1, bot], [1, 0], + [1, 1], [1, top], [0, top], [0, 1], + [0, 0]]) + + if self.orientation == 'horizontal': + xyout = xyout[:, ::-1] + + # xyout is the path for the spine: + self.outline.set_xy(xyout) + if not self._filled: + return + + # Make extend triangles or rectangles filled patches. These are + # defined in the outer parent axes' coordinates: + mappable = getattr(self, 'mappable', None) + if (isinstance(mappable, contour.ContourSet) + and any(hatch is not None for hatch in mappable.hatches)): + hatches = mappable.hatches * (len(self._y) + 1) + else: + hatches = [None] * (len(self._y) + 1) + + if self._extend_lower(): + if not self.extendrect: + # triangle + xy = np.array([[0, 0], [0.5, bot], [1, 0]]) + else: + # rectangle + xy = np.array([[0, 0], [0, bot], [1., bot], [1, 0]]) + if self.orientation == 'horizontal': + xy = xy[:, ::-1] + # add the patch + val = -1 if self._long_axis().get_inverted() else 0 + color = self.cmap(self.norm(self._values[val])) + patch = mpatches.PathPatch( + mpath.Path(xy), facecolor=color, alpha=self.alpha, + linewidth=0, antialiased=False, + transform=self.ax.transAxes, + hatch=hatches[0], clip_on=False, + # Place it right behind the standard patches, which is + # needed if we updated the extends + zorder=np.nextafter(self.ax.patch.zorder, -np.inf)) + self.ax.add_patch(patch) + self._extend_patches.append(patch) + # remove first hatch that goes into the extend patch + hatches = hatches[1:] + if self._extend_upper(): + if not self.extendrect: + # triangle + xy = np.array([[0, 1], [0.5, top], [1, 1]]) + else: + # rectangle + xy = np.array([[0, 1], [0, top], [1, top], [1, 1]]) + if self.orientation == 'horizontal': + xy = xy[:, ::-1] + # add the patch + val = 0 if self._long_axis().get_inverted() else -1 + color = self.cmap(self.norm(self._values[val])) + hatch_idx = len(self._y) - 1 + patch = mpatches.PathPatch( + mpath.Path(xy), facecolor=color, alpha=self.alpha, + linewidth=0, antialiased=False, + transform=self.ax.transAxes, hatch=hatches[hatch_idx], + clip_on=False, + # Place it right behind the standard patches, which is + # needed if we updated the extends + zorder=np.nextafter(self.ax.patch.zorder, -np.inf)) + self.ax.add_patch(patch) + self._extend_patches.append(patch) + + self._update_dividers() + + def add_lines(self, *args, **kwargs): + """ + Draw lines on the colorbar. + + The lines are appended to the list :attr:`lines`. + + Parameters + ---------- + levels : array-like + The positions of the lines. + colors : color or list of colors + Either a single color applying to all lines or one color value for + each line. + linewidths : float or array-like + Either a single linewidth applying to all lines or one linewidth + for each line. + erase : bool, default: True + Whether to remove any previously added lines. + + Notes + ----- + Alternatively, this method can also be called with the signature + ``colorbar.add_lines(contour_set, erase=True)``, in which case + *levels*, *colors*, and *linewidths* are taken from *contour_set*. + """ + params = _api.select_matching_signature( + [lambda self, CS, erase=True: locals(), + lambda self, levels, colors, linewidths, erase=True: locals()], + self, *args, **kwargs) + if "CS" in params: + self, cs, erase = params.values() + if not isinstance(cs, contour.ContourSet) or cs.filled: + raise ValueError("If a single artist is passed to add_lines, " + "it must be a ContourSet of lines") + # TODO: Make colorbar lines auto-follow changes in contour lines. + return self.add_lines( + cs.levels, + cs.to_rgba(cs.cvalues, cs.alpha), + cs.get_linewidths(), + erase=erase) + else: + self, levels, colors, linewidths, erase = params.values() + + y = self._locate(levels) + rtol = (self._y[-1] - self._y[0]) * 1e-10 + igood = (y < self._y[-1] + rtol) & (y > self._y[0] - rtol) + y = y[igood] + if np.iterable(colors): + colors = np.asarray(colors)[igood] + if np.iterable(linewidths): + linewidths = np.asarray(linewidths)[igood] + X, Y = np.meshgrid([0, 1], y) + if self.orientation == 'vertical': + xy = np.stack([X, Y], axis=-1) + else: + xy = np.stack([Y, X], axis=-1) + col = collections.LineCollection(xy, linewidths=linewidths, + colors=colors) + + if erase and self.lines: + for lc in self.lines: + lc.remove() + self.lines = [] + self.lines.append(col) + + # make a clip path that is just a linewidth bigger than the axes... + fac = np.max(linewidths) / 72 + xy = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) + inches = self.ax.get_figure().dpi_scale_trans + # do in inches: + xy = inches.inverted().transform(self.ax.transAxes.transform(xy)) + xy[[0, 1, 4], 1] -= fac + xy[[2, 3], 1] += fac + # back to axes units... + xy = self.ax.transAxes.inverted().transform(inches.transform(xy)) + col.set_clip_path(mpath.Path(xy, closed=True), + self.ax.transAxes) + self.ax.add_collection(col) + self.stale = True + + def update_ticks(self): + """ + Set up the ticks and ticklabels. This should not be needed by users. + """ + # Get the locator and formatter; defaults to self._locator if not None. + self._get_ticker_locator_formatter() + self._long_axis().set_major_locator(self._locator) + self._long_axis().set_minor_locator(self._minorlocator) + self._long_axis().set_major_formatter(self._formatter) + + def _get_ticker_locator_formatter(self): + """ + Return the ``locator`` and ``formatter`` of the colorbar. + + If they have not been defined (i.e. are *None*), the formatter and + locator are retrieved from the axis, or from the value of the + boundaries for a boundary norm. + + Called by update_ticks... + """ + locator = self._locator + formatter = self._formatter + minorlocator = self._minorlocator + if isinstance(self.norm, colors.BoundaryNorm): + b = self.norm.boundaries + if locator is None: + locator = ticker.FixedLocator(b, nbins=10) + if minorlocator is None: + minorlocator = ticker.FixedLocator(b) + elif isinstance(self.norm, colors.NoNorm): + if locator is None: + # put ticks on integers between the boundaries of NoNorm + nv = len(self._values) + base = 1 + int(nv / 10) + locator = ticker.IndexLocator(base=base, offset=.5) + elif self.boundaries is not None: + b = self._boundaries[self._inside] + if locator is None: + locator = ticker.FixedLocator(b, nbins=10) + else: # most cases: + if locator is None: + # we haven't set the locator explicitly, so use the default + # for this axis: + locator = self._long_axis().get_major_locator() + if minorlocator is None: + minorlocator = self._long_axis().get_minor_locator() + + if minorlocator is None: + minorlocator = ticker.NullLocator() + + if formatter is None: + formatter = self._long_axis().get_major_formatter() + + self._locator = locator + self._formatter = formatter + self._minorlocator = minorlocator + _log.debug('locator: %r', locator) + + def set_ticks(self, ticks, *, labels=None, minor=False, **kwargs): + """ + Set tick locations. + + Parameters + ---------- + ticks : 1D array-like + List of tick locations. + labels : list of str, optional + List of tick labels. If not set, the labels show the data value. + minor : bool, default: False + If ``False``, set the major ticks; if ``True``, the minor ticks. + **kwargs + `.Text` properties for the labels. These take effect only if you + pass *labels*. In other cases, please use `~.Axes.tick_params`. + """ + if np.iterable(ticks): + self._long_axis().set_ticks(ticks, labels=labels, minor=minor, + **kwargs) + self._locator = self._long_axis().get_major_locator() + else: + self._locator = ticks + self._long_axis().set_major_locator(self._locator) + self.stale = True + + def get_ticks(self, minor=False): + """ + Return the ticks as a list of locations. + + Parameters + ---------- + minor : boolean, default: False + if True return the minor ticks. + """ + if minor: + return self._long_axis().get_minorticklocs() + else: + return self._long_axis().get_majorticklocs() + + def set_ticklabels(self, ticklabels, *, minor=False, **kwargs): + """ + [*Discouraged*] Set tick labels. + + .. admonition:: Discouraged + + The use of this method is discouraged, because of the dependency + on tick positions. In most cases, you'll want to use + ``set_ticks(positions, labels=labels)`` instead. + + If you are using this method, you should always fix the tick + positions before, e.g. by using `.Colorbar.set_ticks` or by + explicitly setting a `~.ticker.FixedLocator` on the long axis + of the colorbar. Otherwise, ticks are free to move and the + labels may end up in unexpected positions. + + Parameters + ---------- + ticklabels : sequence of str or of `.Text` + Texts for labeling each tick location in the sequence set by + `.Colorbar.set_ticks`; the number of labels must match the number + of locations. + + update_ticks : bool, default: True + This keyword argument is ignored and will be removed. + Deprecated + + minor : bool + If True, set minor ticks instead of major ticks. + + **kwargs + `.Text` properties for the labels. + """ + self._long_axis().set_ticklabels(ticklabels, minor=minor, **kwargs) + + def minorticks_on(self): + """ + Turn on colorbar minor ticks. + """ + self.ax.minorticks_on() + self._short_axis().set_minor_locator(ticker.NullLocator()) + + def minorticks_off(self): + """Turn the minor ticks of the colorbar off.""" + self._minorlocator = ticker.NullLocator() + self._long_axis().set_minor_locator(self._minorlocator) + + def set_label(self, label, *, loc=None, **kwargs): + """ + Add a label to the long axis of the colorbar. + + Parameters + ---------- + label : str + The label text. + loc : str, optional + The location of the label. + + - For horizontal orientation one of {'left', 'center', 'right'} + - For vertical orientation one of {'bottom', 'center', 'top'} + + Defaults to :rc:`xaxis.labellocation` or :rc:`yaxis.labellocation` + depending on the orientation. + **kwargs + Keyword arguments are passed to `~.Axes.set_xlabel` / + `~.Axes.set_ylabel`. + Supported keywords are *labelpad* and `.Text` properties. + """ + if self.orientation == "vertical": + self.ax.set_ylabel(label, loc=loc, **kwargs) + else: + self.ax.set_xlabel(label, loc=loc, **kwargs) + self.stale = True + + def set_alpha(self, alpha): + """ + Set the transparency between 0 (transparent) and 1 (opaque). + + If an array is provided, *alpha* will be set to None to use the + transparency values associated with the colormap. + """ + self.alpha = None if isinstance(alpha, np.ndarray) else alpha + + def _set_scale(self, scale, **kwargs): + """ + Set the colorbar long axis scale. + + Parameters + ---------- + scale : {"linear", "log", "symlog", "logit", ...} or `.ScaleBase` + The axis scale type to apply. + + **kwargs + Different keyword arguments are accepted, depending on the scale. + See the respective class keyword arguments: + + - `matplotlib.scale.LinearScale` + - `matplotlib.scale.LogScale` + - `matplotlib.scale.SymmetricalLogScale` + - `matplotlib.scale.LogitScale` + - `matplotlib.scale.FuncScale` + + Notes + ----- + By default, Matplotlib supports the above-mentioned scales. + Additionally, custom scales may be registered using + `matplotlib.scale.register_scale`. These scales can then also + be used here. + """ + self._long_axis()._set_axes_scale(scale, **kwargs) + + def remove(self): + """ + Remove this colorbar from the figure. + + If the colorbar was created with ``use_gridspec=True`` the previous + gridspec is restored. + """ + if hasattr(self.ax, '_colorbar_info'): + parents = self.ax._colorbar_info['parents'] + for a in parents: + if self.ax in a._colorbars: + a._colorbars.remove(self.ax) + + self.ax.remove() + + self.mappable.callbacks.disconnect(self.mappable.colorbar_cid) + self.mappable.colorbar = None + self.mappable.colorbar_cid = None + # Remove the extension callbacks + self.ax.callbacks.disconnect(self._extend_cid1) + self.ax.callbacks.disconnect(self._extend_cid2) + + try: + ax = self.mappable.axes + except AttributeError: + return + try: + gs = ax.get_subplotspec().get_gridspec() + subplotspec = gs.get_topmost_subplotspec() + except AttributeError: + # use_gridspec was False + pos = ax.get_position(original=True) + ax._set_position(pos) + else: + # use_gridspec was True + ax.set_subplotspec(subplotspec) + + def _process_values(self): + """ + Set `_boundaries` and `_values` based on the self.boundaries and + self.values if not None, or based on the size of the colormap and + the vmin/vmax of the norm. + """ + if self.values is not None: + # set self._boundaries from the values... + self._values = np.array(self.values) + if self.boundaries is None: + # bracket values by 1/2 dv: + b = np.zeros(len(self.values) + 1) + b[1:-1] = 0.5 * (self._values[:-1] + self._values[1:]) + b[0] = 2.0 * b[1] - b[2] + b[-1] = 2.0 * b[-2] - b[-3] + self._boundaries = b + return + self._boundaries = np.array(self.boundaries) + return + + # otherwise values are set from the boundaries + if isinstance(self.norm, colors.BoundaryNorm): + b = self.norm.boundaries + elif isinstance(self.norm, colors.NoNorm): + # NoNorm has N blocks, so N+1 boundaries, centered on integers: + b = np.arange(self.cmap.N + 1) - .5 + elif self.boundaries is not None: + b = self.boundaries + else: + # otherwise make the boundaries from the size of the cmap: + N = self.cmap.N + 1 + b, _ = self._uniform_y(N) + # add extra boundaries if needed: + if self._extend_lower(): + b = np.hstack((b[0] - 1, b)) + if self._extend_upper(): + b = np.hstack((b, b[-1] + 1)) + + # transform from 0-1 to vmin-vmax: + if self.mappable.get_array() is not None: + self.mappable.autoscale_None() + if not self.norm.scaled(): + # If we still aren't scaled after autoscaling, use 0, 1 as default + self.norm.vmin = 0 + self.norm.vmax = 1 + self.norm.vmin, self.norm.vmax = mtransforms.nonsingular( + self.norm.vmin, self.norm.vmax, expander=0.1) + if (not isinstance(self.norm, colors.BoundaryNorm) and + (self.boundaries is None)): + b = self.norm.inverse(b) + + self._boundaries = np.asarray(b, dtype=float) + self._values = 0.5 * (self._boundaries[:-1] + self._boundaries[1:]) + if isinstance(self.norm, colors.NoNorm): + self._values = (self._values + 0.00001).astype(np.int16) + + def _mesh(self): + """ + Return the coordinate arrays for the colorbar pcolormesh/patches. + + These are scaled between vmin and vmax, and already handle colorbar + orientation. + """ + y, _ = self._proportional_y() + # Use the vmin and vmax of the colorbar, which may not be the same + # as the norm. There are situations where the colormap has a + # narrower range than the colorbar and we want to accommodate the + # extra contours. + if (isinstance(self.norm, (colors.BoundaryNorm, colors.NoNorm)) + or self.boundaries is not None): + # not using a norm. + y = y * (self.vmax - self.vmin) + self.vmin + else: + # Update the norm values in a context manager as it is only + # a temporary change and we don't want to propagate any signals + # attached to the norm (callbacks.blocked). + with self.norm.callbacks.blocked(), \ + cbook._setattr_cm(self.norm, + vmin=self.vmin, + vmax=self.vmax): + y = self.norm.inverse(y) + self._y = y + X, Y = np.meshgrid([0., 1.], y) + if self.orientation == 'vertical': + return (X, Y) + else: + return (Y, X) + + def _forward_boundaries(self, x): + # map boundaries equally between 0 and 1... + b = self._boundaries + y = np.interp(x, b, np.linspace(0, 1, len(b))) + # the following avoids ticks in the extends: + eps = (b[-1] - b[0]) * 1e-6 + # map these _well_ out of bounds to keep any ticks out + # of the extends region... + y[x < b[0]-eps] = -1 + y[x > b[-1]+eps] = 2 + return y + + def _inverse_boundaries(self, x): + # invert the above... + b = self._boundaries + return np.interp(x, np.linspace(0, 1, len(b)), b) + + def _reset_locator_formatter_scale(self): + """ + Reset the locator et al to defaults. Any user-hardcoded changes + need to be re-entered if this gets called (either at init, or when + the mappable normal gets changed: Colorbar.update_normal) + """ + self._process_values() + self._locator = None + self._minorlocator = None + self._formatter = None + self._minorformatter = None + if (isinstance(self.mappable, contour.ContourSet) and + isinstance(self.norm, colors.LogNorm)): + # if contours have lognorm, give them a log scale... + self._set_scale('log') + elif (self.boundaries is not None or + isinstance(self.norm, colors.BoundaryNorm)): + if self.spacing == 'uniform': + funcs = (self._forward_boundaries, self._inverse_boundaries) + self._set_scale('function', functions=funcs) + elif self.spacing == 'proportional': + self._set_scale('linear') + elif getattr(self.norm, '_scale', None): + # use the norm's scale (if it exists and is not None): + self._set_scale(self.norm._scale) + elif type(self.norm) is colors.Normalize: + # plain Normalize: + self._set_scale('linear') + else: + # norm._scale is None or not an attr: derive the scale from + # the Norm: + funcs = (self.norm, self.norm.inverse) + self._set_scale('function', functions=funcs) + + def _locate(self, x): + """ + Given a set of color data values, return their + corresponding colorbar data coordinates. + """ + if isinstance(self.norm, (colors.NoNorm, colors.BoundaryNorm)): + b = self._boundaries + xn = x + else: + # Do calculations using normalized coordinates so + # as to make the interpolation more accurate. + b = self.norm(self._boundaries, clip=False).filled() + xn = self.norm(x, clip=False).filled() + + bunique = b[self._inside] + yunique = self._y + + z = np.interp(xn, bunique, yunique) + return z + + # trivial helpers + + def _uniform_y(self, N): + """ + Return colorbar data coordinates for *N* uniformly + spaced boundaries, plus extension lengths if required. + """ + automin = automax = 1. / (N - 1.) + extendlength = self._get_extension_lengths(self.extendfrac, + automin, automax, + default=0.05) + y = np.linspace(0, 1, N) + return y, extendlength + + def _proportional_y(self): + """ + Return colorbar data coordinates for the boundaries of + a proportional colorbar, plus extension lengths if required: + """ + if (isinstance(self.norm, colors.BoundaryNorm) or + self.boundaries is not None): + y = (self._boundaries - self._boundaries[self._inside][0]) + y = y / (self._boundaries[self._inside][-1] - + self._boundaries[self._inside][0]) + # need yscaled the same as the axes scale to get + # the extend lengths. + if self.spacing == 'uniform': + yscaled = self._forward_boundaries(self._boundaries) + else: + yscaled = y + else: + y = self.norm(self._boundaries.copy()) + y = np.ma.filled(y, np.nan) + # the norm and the scale should be the same... + yscaled = y + y = y[self._inside] + yscaled = yscaled[self._inside] + # normalize from 0..1: + norm = colors.Normalize(y[0], y[-1]) + y = np.ma.filled(norm(y), np.nan) + norm = colors.Normalize(yscaled[0], yscaled[-1]) + yscaled = np.ma.filled(norm(yscaled), np.nan) + # make the lower and upper extend lengths proportional to the lengths + # of the first and last boundary spacing (if extendfrac='auto'): + automin = yscaled[1] - yscaled[0] + automax = yscaled[-1] - yscaled[-2] + extendlength = [0, 0] + if self._extend_lower() or self._extend_upper(): + extendlength = self._get_extension_lengths( + self.extendfrac, automin, automax, default=0.05) + return y, extendlength + + def _get_extension_lengths(self, frac, automin, automax, default=0.05): + """ + Return the lengths of colorbar extensions. + + This is a helper method for _uniform_y and _proportional_y. + """ + # Set the default value. + extendlength = np.array([default, default]) + if isinstance(frac, str): + _api.check_in_list(['auto'], extendfrac=frac.lower()) + # Use the provided values when 'auto' is required. + extendlength[:] = [automin, automax] + elif frac is not None: + try: + # Try to set min and max extension fractions directly. + extendlength[:] = frac + # If frac is a sequence containing None then NaN may + # be encountered. This is an error. + if np.isnan(extendlength).any(): + raise ValueError() + except (TypeError, ValueError) as err: + # Raise an error on encountering an invalid value for frac. + raise ValueError('invalid value for extendfrac') from err + return extendlength + + def _extend_lower(self): + """Return whether the lower limit is open ended.""" + minmax = "max" if self._long_axis().get_inverted() else "min" + return self.extend in ('both', minmax) + + def _extend_upper(self): + """Return whether the upper limit is open ended.""" + minmax = "min" if self._long_axis().get_inverted() else "max" + return self.extend in ('both', minmax) + + def _long_axis(self): + """Return the long axis""" + if self.orientation == 'vertical': + return self.ax.yaxis + return self.ax.xaxis + + def _short_axis(self): + """Return the short axis""" + if self.orientation == 'vertical': + return self.ax.xaxis + return self.ax.yaxis + + def _get_view(self): + # docstring inherited + # An interactive view for a colorbar is the norm's vmin/vmax + return self.norm.vmin, self.norm.vmax + + def _set_view(self, view): + # docstring inherited + # An interactive view for a colorbar is the norm's vmin/vmax + self.norm.vmin, self.norm.vmax = view + + def _set_view_from_bbox(self, bbox, direction='in', + mode=None, twinx=False, twiny=False): + # docstring inherited + # For colorbars, we use the zoom bbox to scale the norm's vmin/vmax + new_xbound, new_ybound = self.ax._prepare_view_from_bbox( + bbox, direction=direction, mode=mode, twinx=twinx, twiny=twiny) + if self.orientation == 'horizontal': + self.norm.vmin, self.norm.vmax = new_xbound + elif self.orientation == 'vertical': + self.norm.vmin, self.norm.vmax = new_ybound + + def drag_pan(self, button, key, x, y): + # docstring inherited + points = self.ax._get_pan_points(button, key, x, y) + if points is not None: + if self.orientation == 'horizontal': + self.norm.vmin, self.norm.vmax = points[:, 0] + elif self.orientation == 'vertical': + self.norm.vmin, self.norm.vmax = points[:, 1] + + +ColorbarBase = Colorbar # Backcompat API + + +def _normalize_location_orientation(location, orientation): + if location is None: + location = _get_ticklocation_from_orientation(orientation) + loc_settings = _api.check_getitem({ + "left": {"location": "left", "anchor": (1.0, 0.5), + "panchor": (0.0, 0.5), "pad": 0.10}, + "right": {"location": "right", "anchor": (0.0, 0.5), + "panchor": (1.0, 0.5), "pad": 0.05}, + "top": {"location": "top", "anchor": (0.5, 0.0), + "panchor": (0.5, 1.0), "pad": 0.05}, + "bottom": {"location": "bottom", "anchor": (0.5, 1.0), + "panchor": (0.5, 0.0), "pad": 0.15}, + }, location=location) + loc_settings["orientation"] = _get_orientation_from_location(location) + if orientation is not None and orientation != loc_settings["orientation"]: + # Allow the user to pass both if they are consistent. + raise TypeError("location and orientation are mutually exclusive") + return loc_settings + + +def _get_orientation_from_location(location): + return _api.check_getitem( + {None: None, "left": "vertical", "right": "vertical", + "top": "horizontal", "bottom": "horizontal"}, location=location) + + +def _get_ticklocation_from_orientation(orientation): + return _api.check_getitem( + {None: "right", "vertical": "right", "horizontal": "bottom"}, + orientation=orientation) + + +@_docstring.interpd +def make_axes(parents, location=None, orientation=None, fraction=0.15, + shrink=1.0, aspect=20, **kwargs): + """ + Create an `~.axes.Axes` suitable for a colorbar. + + The axes is placed in the figure of the *parents* axes, by resizing and + repositioning *parents*. + + Parameters + ---------- + parents : `~matplotlib.axes.Axes` or iterable or `numpy.ndarray` of `~.axes.Axes` + The Axes to use as parents for placing the colorbar. + %(_make_axes_kw_doc)s + + Returns + ------- + cax : `~matplotlib.axes.Axes` + The child axes. + kwargs : dict + The reduced keyword dictionary to be passed when creating the colorbar + instance. + """ + loc_settings = _normalize_location_orientation(location, orientation) + # put appropriate values into the kwargs dict for passing back to + # the Colorbar class + kwargs['orientation'] = loc_settings['orientation'] + location = kwargs['ticklocation'] = loc_settings['location'] + + anchor = kwargs.pop('anchor', loc_settings['anchor']) + panchor = kwargs.pop('panchor', loc_settings['panchor']) + aspect0 = aspect + # turn parents into a list if it is not already. Note we cannot + # use .flatten or .ravel as these copy the references rather than + # reuse them, leading to a memory leak + if isinstance(parents, np.ndarray): + parents = list(parents.flat) + elif np.iterable(parents): + parents = list(parents) + else: + parents = [parents] + + fig = parents[0].get_figure() + + pad0 = 0.05 if fig.get_constrained_layout() else loc_settings['pad'] + pad = kwargs.pop('pad', pad0) + + if not all(fig is ax.get_figure() for ax in parents): + raise ValueError('Unable to create a colorbar axes as not all ' + 'parents share the same figure.') + + # take a bounding box around all of the given axes + parents_bbox = mtransforms.Bbox.union( + [ax.get_position(original=True).frozen() for ax in parents]) + + pb = parents_bbox + if location in ('left', 'right'): + if location == 'left': + pbcb, _, pb1 = pb.splitx(fraction, fraction + pad) + else: + pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction) + pbcb = pbcb.shrunk(1.0, shrink).anchored(anchor, pbcb) + else: + if location == 'bottom': + pbcb, _, pb1 = pb.splity(fraction, fraction + pad) + else: + pb1, _, pbcb = pb.splity(1 - fraction - pad, 1 - fraction) + pbcb = pbcb.shrunk(shrink, 1.0).anchored(anchor, pbcb) + + # define the aspect ratio in terms of y's per x rather than x's per y + aspect = 1.0 / aspect + + # define a transform which takes us from old axes coordinates to + # new axes coordinates + shrinking_trans = mtransforms.BboxTransform(parents_bbox, pb1) + + # transform each of the axes in parents using the new transform + for ax in parents: + new_posn = shrinking_trans.transform(ax.get_position(original=True)) + new_posn = mtransforms.Bbox(new_posn) + ax._set_position(new_posn) + if panchor is not False: + ax.set_anchor(panchor) + + cax = fig.add_axes(pbcb, label="") + for a in parents: + # tell the parent it has a colorbar + a._colorbars += [cax] + cax._colorbar_info = dict( + parents=parents, + location=location, + shrink=shrink, + anchor=anchor, + panchor=panchor, + fraction=fraction, + aspect=aspect0, + pad=pad) + # and we need to set the aspect ratio by hand... + cax.set_anchor(anchor) + cax.set_box_aspect(aspect) + cax.set_aspect('auto') + + return cax, kwargs + + +@_docstring.interpd +def make_axes_gridspec(parent, *, location=None, orientation=None, + fraction=0.15, shrink=1.0, aspect=20, **kwargs): + """ + Create an `~.axes.Axes` suitable for a colorbar. + + The axes is placed in the figure of the *parent* axes, by resizing and + repositioning *parent*. + + This function is similar to `.make_axes` and mostly compatible with it. + Primary differences are + + - `.make_axes_gridspec` requires the *parent* to have a subplotspec. + - `.make_axes` positions the axes in figure coordinates; + `.make_axes_gridspec` positions it using a subplotspec. + - `.make_axes` updates the position of the parent. `.make_axes_gridspec` + replaces the parent gridspec with a new one. + + Parameters + ---------- + parent : `~matplotlib.axes.Axes` + The Axes to use as parent for placing the colorbar. + %(_make_axes_kw_doc)s + + Returns + ------- + cax : `~matplotlib.axes.Axes` + The child axes. + kwargs : dict + The reduced keyword dictionary to be passed when creating the colorbar + instance. + """ + + loc_settings = _normalize_location_orientation(location, orientation) + kwargs['orientation'] = loc_settings['orientation'] + location = kwargs['ticklocation'] = loc_settings['location'] + + aspect0 = aspect + anchor = kwargs.pop('anchor', loc_settings['anchor']) + panchor = kwargs.pop('panchor', loc_settings['panchor']) + pad = kwargs.pop('pad', loc_settings["pad"]) + wh_space = 2 * pad / (1 - pad) + + if location in ('left', 'right'): + # for shrinking + height_ratios = [ + (1-anchor[1])*(1-shrink), shrink, anchor[1]*(1-shrink)] + + if location == 'left': + gs = parent.get_subplotspec().subgridspec( + 1, 2, wspace=wh_space, + width_ratios=[fraction, 1-fraction-pad]) + ss_main = gs[1] + ss_cb = gs[0].subgridspec( + 3, 1, hspace=0, height_ratios=height_ratios)[1] + else: + gs = parent.get_subplotspec().subgridspec( + 1, 2, wspace=wh_space, + width_ratios=[1-fraction-pad, fraction]) + ss_main = gs[0] + ss_cb = gs[1].subgridspec( + 3, 1, hspace=0, height_ratios=height_ratios)[1] + else: + # for shrinking + width_ratios = [ + anchor[0]*(1-shrink), shrink, (1-anchor[0])*(1-shrink)] + + if location == 'bottom': + gs = parent.get_subplotspec().subgridspec( + 2, 1, hspace=wh_space, + height_ratios=[1-fraction-pad, fraction]) + ss_main = gs[0] + ss_cb = gs[1].subgridspec( + 1, 3, wspace=0, width_ratios=width_ratios)[1] + aspect = 1 / aspect + else: + gs = parent.get_subplotspec().subgridspec( + 2, 1, hspace=wh_space, + height_ratios=[fraction, 1-fraction-pad]) + ss_main = gs[1] + ss_cb = gs[0].subgridspec( + 1, 3, wspace=0, width_ratios=width_ratios)[1] + aspect = 1 / aspect + + parent.set_subplotspec(ss_main) + if panchor is not False: + parent.set_anchor(panchor) + + fig = parent.get_figure() + cax = fig.add_subplot(ss_cb, label="") + cax.set_anchor(anchor) + cax.set_box_aspect(aspect) + cax.set_aspect('auto') + cax._colorbar_info = dict( + location=location, + parents=[parent], + shrink=shrink, + anchor=anchor, + panchor=panchor, + fraction=fraction, + aspect=aspect0, + pad=pad) + + return cax, kwargs diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.pyi new file mode 100644 index 00000000..f71c5759 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colorbar.pyi @@ -0,0 +1,136 @@ +import matplotlib.spines as mspines +from matplotlib import cm, collections, colors, contour +from matplotlib.axes import Axes +from matplotlib.backend_bases import RendererBase +from matplotlib.patches import Patch +from matplotlib.ticker import Locator, Formatter +from matplotlib.transforms import Bbox + +import numpy as np +from numpy.typing import ArrayLike +from collections.abc import Sequence +from typing import Any, Literal, overload +from .typing import ColorType + +class _ColorbarSpine(mspines.Spines): + def __init__(self, axes: Axes): ... + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox:... + def set_xy(self, xy: ArrayLike) -> None: ... + def draw(self, renderer: RendererBase | None) -> None:... + + +class Colorbar: + n_rasterize: int + mappable: cm.ScalarMappable + ax: Axes + alpha: float | None + cmap: colors.Colormap + norm: colors.Normalize + values: Sequence[float] | None + boundaries: Sequence[float] | None + extend: Literal["neither", "both", "min", "max"] + spacing: Literal["uniform", "proportional"] + orientation: Literal["vertical", "horizontal"] + drawedges: bool + extendfrac: Literal["auto"] | float | Sequence[float] | None + extendrect: bool + solids: None | collections.QuadMesh + solids_patches: list[Patch] + lines: list[collections.LineCollection] + outline: _ColorbarSpine + dividers: collections.LineCollection + ticklocation: Literal["left", "right", "top", "bottom"] + def __init__( + self, + ax: Axes, + mappable: cm.ScalarMappable | None = ..., + *, + cmap: str | colors.Colormap | None = ..., + norm: colors.Normalize | None = ..., + alpha: float | None = ..., + values: Sequence[float] | None = ..., + boundaries: Sequence[float] | None = ..., + orientation: Literal["vertical", "horizontal"] | None = ..., + ticklocation: Literal["auto", "left", "right", "top", "bottom"] = ..., + extend: Literal["neither", "both", "min", "max"] | None = ..., + spacing: Literal["uniform", "proportional"] = ..., + ticks: Sequence[float] | Locator | None = ..., + format: str | Formatter | None = ..., + drawedges: bool = ..., + extendfrac: Literal["auto"] | float | Sequence[float] | None = ..., + extendrect: bool = ..., + label: str = ..., + location: Literal["left", "right", "top", "bottom"] | None = ... + ) -> None: ... + @property + def locator(self) -> Locator: ... + @locator.setter + def locator(self, loc: Locator) -> None: ... + @property + def minorlocator(self) -> Locator: ... + @minorlocator.setter + def minorlocator(self, loc: Locator) -> None: ... + @property + def formatter(self) -> Formatter: ... + @formatter.setter + def formatter(self, fmt: Formatter) -> None: ... + @property + def minorformatter(self) -> Formatter: ... + @minorformatter.setter + def minorformatter(self, fmt: Formatter) -> None: ... + def update_normal(self, mappable: cm.ScalarMappable) -> None: ... + @overload + def add_lines(self, CS: contour.ContourSet, erase: bool = ...) -> None: ... + @overload + def add_lines( + self, + levels: ArrayLike, + colors: ColorType | Sequence[ColorType], + linewidths: float | ArrayLike, + erase: bool = ..., + ) -> None: ... + def update_ticks(self) -> None: ... + def set_ticks( + self, + ticks: Sequence[float] | Locator, + *, + labels: Sequence[str] | None = ..., + minor: bool = ..., + **kwargs + ) -> None: ... + def get_ticks(self, minor: bool = ...) -> np.ndarray: ... + def set_ticklabels( + self, + ticklabels: Sequence[str], + *, + minor: bool = ..., + **kwargs + ) -> None: ... + def minorticks_on(self) -> None: ... + def minorticks_off(self) -> None: ... + def set_label(self, label: str, *, loc: str | None = ..., **kwargs) -> None: ... + def set_alpha(self, alpha: float | np.ndarray) -> None: ... + def remove(self) -> None: ... + def drag_pan(self, button: Any, key: Any, x: float, y: float) -> None: ... + +ColorbarBase = Colorbar + +def make_axes( + parents: Axes | list[Axes] | np.ndarray, + location: Literal["left", "right", "top", "bottom"] | None = ..., + orientation: Literal["vertical", "horizontal"] | None = ..., + fraction: float = ..., + shrink: float = ..., + aspect: float = ..., + **kwargs +) -> tuple[Axes, dict[str, Any]]: ... +def make_axes_gridspec( + parent: Axes, + *, + location: Literal["left", "right", "top", "bottom"] | None = ..., + orientation: Literal["vertical", "horizontal"] | None = ..., + fraction: float = ..., + shrink: float = ..., + aspect: float = ..., + **kwargs +) -> tuple[Axes, dict[str, Any]]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.py new file mode 100644 index 00000000..bd89e700 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.py @@ -0,0 +1,2762 @@ +""" +A module for converting numbers or color arguments to *RGB* or *RGBA*. + +*RGB* and *RGBA* are sequences of, respectively, 3 or 4 floats in the +range 0-1. + +This module includes functions and classes for color specification conversions, +and for mapping numbers to colors in a 1-D array of colors called a colormap. + +Mapping data onto colors using a colormap typically involves two steps: a data +array is first mapped onto the range 0-1 using a subclass of `Normalize`, +then this number is mapped to a color using a subclass of `Colormap`. Two +subclasses of `Colormap` provided here: `LinearSegmentedColormap`, which uses +piecewise-linear interpolation to define colormaps, and `ListedColormap`, which +makes a colormap from a list of colors. + +.. seealso:: + + :ref:`colormap-manipulation` for examples of how to + make colormaps and + + :ref:`colormaps` for a list of built-in colormaps. + + :ref:`colormapnorms` for more details about data + normalization + + More colormaps are available at palettable_. + +The module also provides functions for checking whether an object can be +interpreted as a color (`is_color_like`), for converting such an object +to an RGBA tuple (`to_rgba`) or to an HTML-like hex string in the +"#rrggbb" format (`to_hex`), and a sequence of colors to an (n, 4) +RGBA array (`to_rgba_array`). Caching is used for efficiency. + +Colors that Matplotlib recognizes are listed at +:ref:`colors_def`. + +.. _palettable: https://jiffyclub.github.io/palettable/ +.. _xkcd color survey: https://xkcd.com/color/rgb/ +""" + +import base64 +from collections.abc import Sized, Sequence, Mapping +import functools +import importlib +import inspect +import io +import itertools +from numbers import Real +import re + +from PIL import Image +from PIL.PngImagePlugin import PngInfo + +import matplotlib as mpl +import numpy as np +from matplotlib import _api, _cm, cbook, scale +from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS + + +class _ColorMapping(dict): + def __init__(self, mapping): + super().__init__(mapping) + self.cache = {} + + def __setitem__(self, key, value): + super().__setitem__(key, value) + self.cache.clear() + + def __delitem__(self, key): + super().__delitem__(key) + self.cache.clear() + + +_colors_full_map = {} +# Set by reverse priority order. +_colors_full_map.update(XKCD_COLORS) +_colors_full_map.update({k.replace('grey', 'gray'): v + for k, v in XKCD_COLORS.items() + if 'grey' in k}) +_colors_full_map.update(CSS4_COLORS) +_colors_full_map.update(TABLEAU_COLORS) +_colors_full_map.update({k.replace('gray', 'grey'): v + for k, v in TABLEAU_COLORS.items() + if 'gray' in k}) +_colors_full_map.update(BASE_COLORS) +_colors_full_map = _ColorMapping(_colors_full_map) + +_REPR_PNG_SIZE = (512, 64) + + +def get_named_colors_mapping(): + """Return the global mapping of names to named colors.""" + return _colors_full_map + + +class ColorSequenceRegistry(Mapping): + r""" + Container for sequences of colors that are known to Matplotlib by name. + + The universal registry instance is `matplotlib.color_sequences`. There + should be no need for users to instantiate `.ColorSequenceRegistry` + themselves. + + Read access uses a dict-like interface mapping names to lists of colors:: + + import matplotlib as mpl + cmap = mpl.color_sequences['tab10'] + + The returned lists are copies, so that their modification does not change + the global definition of the color sequence. + + Additional color sequences can be added via + `.ColorSequenceRegistry.register`:: + + mpl.color_sequences.register('rgb', ['r', 'g', 'b']) + """ + + _BUILTIN_COLOR_SEQUENCES = { + 'tab10': _cm._tab10_data, + 'tab20': _cm._tab20_data, + 'tab20b': _cm._tab20b_data, + 'tab20c': _cm._tab20c_data, + 'Pastel1': _cm._Pastel1_data, + 'Pastel2': _cm._Pastel2_data, + 'Paired': _cm._Paired_data, + 'Accent': _cm._Accent_data, + 'Dark2': _cm._Dark2_data, + 'Set1': _cm._Set1_data, + 'Set2': _cm._Set1_data, + 'Set3': _cm._Set1_data, + } + + def __init__(self): + self._color_sequences = {**self._BUILTIN_COLOR_SEQUENCES} + + def __getitem__(self, item): + try: + return list(self._color_sequences[item]) + except KeyError: + raise KeyError(f"{item!r} is not a known color sequence name") + + def __iter__(self): + return iter(self._color_sequences) + + def __len__(self): + return len(self._color_sequences) + + def __str__(self): + return ('ColorSequenceRegistry; available colormaps:\n' + + ', '.join(f"'{name}'" for name in self)) + + def register(self, name, color_list): + """ + Register a new color sequence. + + The color sequence registry stores a copy of the given *color_list*, so + that future changes to the original list do not affect the registered + color sequence. Think of this as the registry taking a snapshot + of *color_list* at registration. + + Parameters + ---------- + name : str + The name for the color sequence. + + color_list : list of colors + An iterable returning valid Matplotlib colors when iterating over. + Note however that the returned color sequence will always be a + list regardless of the input type. + + """ + if name in self._BUILTIN_COLOR_SEQUENCES: + raise ValueError(f"{name!r} is a reserved name for a builtin " + "color sequence") + + color_list = list(color_list) # force copy and coerce type to list + for color in color_list: + try: + to_rgba(color) + except ValueError: + raise ValueError( + f"{color!r} is not a valid color specification") + + self._color_sequences[name] = color_list + + def unregister(self, name): + """ + Remove a sequence from the registry. + + You cannot remove built-in color sequences. + + If the name is not registered, returns with no error. + """ + if name in self._BUILTIN_COLOR_SEQUENCES: + raise ValueError( + f"Cannot unregister builtin color sequence {name!r}") + self._color_sequences.pop(name, None) + + +_color_sequences = ColorSequenceRegistry() + + +def _sanitize_extrema(ex): + if ex is None: + return ex + try: + ret = ex.item() + except AttributeError: + ret = float(ex) + return ret + +_nth_color_re = re.compile(r"\AC[0-9]+\Z") + + +def _is_nth_color(c): + """Return whether *c* can be interpreted as an item in the color cycle.""" + return isinstance(c, str) and _nth_color_re.match(c) + + +def is_color_like(c): + """Return whether *c* can be interpreted as an RGB(A) color.""" + # Special-case nth color syntax because it cannot be parsed during setup. + if _is_nth_color(c): + return True + try: + to_rgba(c) + except ValueError: + return False + else: + return True + + +def _has_alpha_channel(c): + """Return whether *c* is a color with an alpha channel.""" + # 4-element sequences are interpreted as r, g, b, a + return not isinstance(c, str) and len(c) == 4 + + +def _check_color_like(**kwargs): + """ + For each *key, value* pair in *kwargs*, check that *value* is color-like. + """ + for k, v in kwargs.items(): + if not is_color_like(v): + raise ValueError(f"{v!r} is not a valid value for {k}") + + +def same_color(c1, c2): + """ + Return whether the colors *c1* and *c2* are the same. + + *c1*, *c2* can be single colors or lists/arrays of colors. + """ + c1 = to_rgba_array(c1) + c2 = to_rgba_array(c2) + n1 = max(c1.shape[0], 1) # 'none' results in shape (0, 4), but is 1-elem + n2 = max(c2.shape[0], 1) # 'none' results in shape (0, 4), but is 1-elem + + if n1 != n2: + raise ValueError('Different number of elements passed.') + # The following shape test is needed to correctly handle comparisons with + # 'none', which results in a shape (0, 4) array and thus cannot be tested + # via value comparison. + return c1.shape == c2.shape and (c1 == c2).all() + + +def to_rgba(c, alpha=None): + """ + Convert *c* to an RGBA color. + + Parameters + ---------- + c : Matplotlib color or ``np.ma.masked`` + + alpha : float, optional + If *alpha* is given, force the alpha value of the returned RGBA tuple + to *alpha*. + + If None, the alpha value from *c* is used. If *c* does not have an + alpha channel, then alpha defaults to 1. + + *alpha* is ignored for the color value ``"none"`` (case-insensitive), + which always maps to ``(0, 0, 0, 0)``. + + Returns + ------- + tuple + Tuple of floats ``(r, g, b, a)``, where each channel (red, green, blue, + alpha) can assume values between 0 and 1. + """ + # Special-case nth color syntax because it should not be cached. + if _is_nth_color(c): + prop_cycler = mpl.rcParams['axes.prop_cycle'] + colors = prop_cycler.by_key().get('color', ['k']) + c = colors[int(c[1:]) % len(colors)] + try: + rgba = _colors_full_map.cache[c, alpha] + except (KeyError, TypeError): # Not in cache, or unhashable. + rgba = None + if rgba is None: # Suppress exception chaining of cache lookup failure. + rgba = _to_rgba_no_colorcycle(c, alpha) + try: + _colors_full_map.cache[c, alpha] = rgba + except TypeError: + pass + return rgba + + +def _to_rgba_no_colorcycle(c, alpha=None): + """ + Convert *c* to an RGBA color, with no support for color-cycle syntax. + + If *alpha* is given, force the alpha value of the returned RGBA tuple + to *alpha*. Otherwise, the alpha value from *c* is used, if it has alpha + information, or defaults to 1. + + *alpha* is ignored for the color value ``"none"`` (case-insensitive), + which always maps to ``(0, 0, 0, 0)``. + """ + if isinstance(c, tuple) and len(c) == 2: + if alpha is None: + c, alpha = c + else: + c = c[0] + if alpha is not None and not 0 <= alpha <= 1: + raise ValueError("'alpha' must be between 0 and 1, inclusive") + orig_c = c + if c is np.ma.masked: + return (0., 0., 0., 0.) + if isinstance(c, str): + if c.lower() == "none": + return (0., 0., 0., 0.) + # Named color. + try: + # This may turn c into a non-string, so we check again below. + c = _colors_full_map[c] + except KeyError: + if len(orig_c) != 1: + try: + c = _colors_full_map[c.lower()] + except KeyError: + pass + if isinstance(c, str): + # hex color in #rrggbb format. + match = re.match(r"\A#[a-fA-F0-9]{6}\Z", c) + if match: + return (tuple(int(n, 16) / 255 + for n in [c[1:3], c[3:5], c[5:7]]) + + (alpha if alpha is not None else 1.,)) + # hex color in #rgb format, shorthand for #rrggbb. + match = re.match(r"\A#[a-fA-F0-9]{3}\Z", c) + if match: + return (tuple(int(n, 16) / 255 + for n in [c[1]*2, c[2]*2, c[3]*2]) + + (alpha if alpha is not None else 1.,)) + # hex color with alpha in #rrggbbaa format. + match = re.match(r"\A#[a-fA-F0-9]{8}\Z", c) + if match: + color = [int(n, 16) / 255 + for n in [c[1:3], c[3:5], c[5:7], c[7:9]]] + if alpha is not None: + color[-1] = alpha + return tuple(color) + # hex color with alpha in #rgba format, shorthand for #rrggbbaa. + match = re.match(r"\A#[a-fA-F0-9]{4}\Z", c) + if match: + color = [int(n, 16) / 255 + for n in [c[1]*2, c[2]*2, c[3]*2, c[4]*2]] + if alpha is not None: + color[-1] = alpha + return tuple(color) + # string gray. + try: + c = float(c) + except ValueError: + pass + else: + if not (0 <= c <= 1): + raise ValueError( + f"Invalid string grayscale value {orig_c!r}. " + f"Value must be within 0-1 range") + return c, c, c, alpha if alpha is not None else 1. + raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + # turn 2-D array into 1-D array + if isinstance(c, np.ndarray): + if c.ndim == 2 and c.shape[0] == 1: + c = c.reshape(-1) + # tuple color. + if not np.iterable(c): + raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + if len(c) not in [3, 4]: + raise ValueError("RGBA sequence should have length 3 or 4") + if not all(isinstance(x, Real) for x in c): + # Checks that don't work: `map(float, ...)`, `np.array(..., float)` and + # `np.array(...).astype(float)` would all convert "0.5" to 0.5. + raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + # Return a tuple to prevent the cached value from being modified. + c = tuple(map(float, c)) + if len(c) == 3 and alpha is None: + alpha = 1 + if alpha is not None: + c = c[:3] + (alpha,) + if any(elem < 0 or elem > 1 for elem in c): + raise ValueError("RGBA values should be within 0-1 range") + return c + + +def to_rgba_array(c, alpha=None): + """ + Convert *c* to a (n, 4) array of RGBA colors. + + Parameters + ---------- + c : Matplotlib color or array of colors + If *c* is a masked array, an `~numpy.ndarray` is returned with a + (0, 0, 0, 0) row for each masked value or row in *c*. + + alpha : float or sequence of floats, optional + If *alpha* is given, force the alpha value of the returned RGBA tuple + to *alpha*. + + If None, the alpha value from *c* is used. If *c* does not have an + alpha channel, then alpha defaults to 1. + + *alpha* is ignored for the color value ``"none"`` (case-insensitive), + which always maps to ``(0, 0, 0, 0)``. + + If *alpha* is a sequence and *c* is a single color, *c* will be + repeated to match the length of *alpha*. + + Returns + ------- + array + (n, 4) array of RGBA colors, where each channel (red, green, blue, + alpha) can assume values between 0 and 1. + """ + if isinstance(c, tuple) and len(c) == 2 and isinstance(c[1], Real): + if alpha is None: + c, alpha = c + else: + c = c[0] + # Special-case inputs that are already arrays, for performance. (If the + # array has the wrong kind or shape, raise the error during one-at-a-time + # conversion.) + if np.iterable(alpha): + alpha = np.asarray(alpha).ravel() + if (isinstance(c, np.ndarray) and c.dtype.kind in "if" + and c.ndim == 2 and c.shape[1] in [3, 4]): + mask = c.mask.any(axis=1) if np.ma.is_masked(c) else None + c = np.ma.getdata(c) + if np.iterable(alpha): + if c.shape[0] == 1 and alpha.shape[0] > 1: + c = np.tile(c, (alpha.shape[0], 1)) + elif c.shape[0] != alpha.shape[0]: + raise ValueError("The number of colors must match the number" + " of alpha values if there are more than one" + " of each.") + if c.shape[1] == 3: + result = np.column_stack([c, np.zeros(len(c))]) + result[:, -1] = alpha if alpha is not None else 1. + elif c.shape[1] == 4: + result = c.copy() + if alpha is not None: + result[:, -1] = alpha + if mask is not None: + result[mask] = 0 + if np.any((result < 0) | (result > 1)): + raise ValueError("RGBA values should be within 0-1 range") + return result + # Handle single values. + # Note that this occurs *after* handling inputs that are already arrays, as + # `to_rgba(c, alpha)` (below) is expensive for such inputs, due to the need + # to format the array in the ValueError message(!). + if cbook._str_lower_equal(c, "none"): + return np.zeros((0, 4), float) + try: + if np.iterable(alpha): + return np.array([to_rgba(c, a) for a in alpha], float) + else: + return np.array([to_rgba(c, alpha)], float) + except TypeError: + pass + except ValueError as e: + if e.args == ("'alpha' must be between 0 and 1, inclusive", ): + # ValueError is from _to_rgba_no_colorcycle(). + raise e + if isinstance(c, str): + raise ValueError(f"{c!r} is not a valid color value.") + + if len(c) == 0: + return np.zeros((0, 4), float) + + # Quick path if the whole sequence can be directly converted to a numpy + # array in one shot. + if isinstance(c, Sequence): + lens = {len(cc) if isinstance(cc, (list, tuple)) else -1 for cc in c} + if lens == {3}: + rgba = np.column_stack([c, np.ones(len(c))]) + elif lens == {4}: + rgba = np.array(c) + else: + rgba = np.array([to_rgba(cc) for cc in c]) + else: + rgba = np.array([to_rgba(cc) for cc in c]) + + if alpha is not None: + rgba[:, 3] = alpha + return rgba + + +def to_rgb(c): + """Convert *c* to an RGB color, silently dropping the alpha channel.""" + return to_rgba(c)[:3] + + +def to_hex(c, keep_alpha=False): + """ + Convert *c* to a hex color. + + Parameters + ---------- + c : :ref:`color ` or `numpy.ma.masked` + + keep_alpha : bool, default: False + If False, use the ``#rrggbb`` format, otherwise use ``#rrggbbaa``. + + Returns + ------- + str + ``#rrggbb`` or ``#rrggbbaa`` hex color string + """ + c = to_rgba(c) + if not keep_alpha: + c = c[:3] + return "#" + "".join(format(round(val * 255), "02x") for val in c) + + +### Backwards-compatible color-conversion API + + +cnames = CSS4_COLORS +hexColorPattern = re.compile(r"\A#[a-fA-F0-9]{6}\Z") +rgb2hex = to_hex +hex2color = to_rgb + + +class ColorConverter: + """ + A class only kept for backwards compatibility. + + Its functionality is entirely provided by module-level functions. + """ + colors = _colors_full_map + cache = _colors_full_map.cache + to_rgb = staticmethod(to_rgb) + to_rgba = staticmethod(to_rgba) + to_rgba_array = staticmethod(to_rgba_array) + + +colorConverter = ColorConverter() + + +### End of backwards-compatible color-conversion API + + +def _create_lookup_table(N, data, gamma=1.0): + r""" + Create an *N* -element 1D lookup table. + + This assumes a mapping :math:`f : [0, 1] \rightarrow [0, 1]`. The returned + data is an array of N values :math:`y = f(x)` where x is sampled from + [0, 1]. + + By default (*gamma* = 1) x is equidistantly sampled from [0, 1]. The + *gamma* correction factor :math:`\gamma` distorts this equidistant + sampling by :math:`x \rightarrow x^\gamma`. + + Parameters + ---------- + N : int + The number of elements of the created lookup table; at least 1. + + data : (M, 3) array-like or callable + Defines the mapping :math:`f`. + + If a (M, 3) array-like, the rows define values (x, y0, y1). The x + values must start with x=0, end with x=1, and all x values be in + increasing order. + + A value between :math:`x_i` and :math:`x_{i+1}` is mapped to the range + :math:`y^1_{i-1} \ldots y^0_i` by linear interpolation. + + For the simple case of a y-continuous mapping, y0 and y1 are identical. + + The two values of y are to allow for discontinuous mapping functions. + E.g. a sawtooth with a period of 0.2 and an amplitude of 1 would be:: + + [(0, 1, 0), (0.2, 1, 0), (0.4, 1, 0), ..., [(1, 1, 0)] + + In the special case of ``N == 1``, by convention the returned value + is y0 for x == 1. + + If *data* is a callable, it must accept and return numpy arrays:: + + data(x : ndarray) -> ndarray + + and map values between 0 - 1 to 0 - 1. + + gamma : float + Gamma correction factor for input distribution x of the mapping. + + See also https://en.wikipedia.org/wiki/Gamma_correction. + + Returns + ------- + array + The lookup table where ``lut[x * (N-1)]`` gives the closest value + for values of x between 0 and 1. + + Notes + ----- + This function is internally used for `.LinearSegmentedColormap`. + """ + + if callable(data): + xind = np.linspace(0, 1, N) ** gamma + lut = np.clip(np.array(data(xind), dtype=float), 0, 1) + return lut + + try: + adata = np.array(data) + except Exception as err: + raise TypeError("data must be convertible to an array") from err + _api.check_shape((None, 3), data=adata) + + x = adata[:, 0] + y0 = adata[:, 1] + y1 = adata[:, 2] + + if x[0] != 0. or x[-1] != 1.0: + raise ValueError( + "data mapping points must start with x=0 and end with x=1") + if (np.diff(x) < 0).any(): + raise ValueError("data mapping points must have x in increasing order") + # begin generation of lookup table + if N == 1: + # convention: use the y = f(x=1) value for a 1-element lookup table + lut = np.array(y0[-1]) + else: + x = x * (N - 1) + xind = (N - 1) * np.linspace(0, 1, N) ** gamma + ind = np.searchsorted(x, xind)[1:-1] + + distance = (xind[1:-1] - x[ind - 1]) / (x[ind] - x[ind - 1]) + lut = np.concatenate([ + [y1[0]], + distance * (y0[ind] - y1[ind - 1]) + y1[ind - 1], + [y0[-1]], + ]) + # ensure that the lut is confined to values between 0 and 1 by clipping it + return np.clip(lut, 0.0, 1.0) + + +class Colormap: + """ + Baseclass for all scalar to RGBA mappings. + + Typically, Colormap instances are used to convert data values (floats) + from the interval ``[0, 1]`` to the RGBA color that the respective + Colormap represents. For scaling of data into the ``[0, 1]`` interval see + `matplotlib.colors.Normalize`. Subclasses of `matplotlib.cm.ScalarMappable` + make heavy use of this ``data -> normalize -> map-to-color`` processing + chain. + """ + + def __init__(self, name, N=256): + """ + Parameters + ---------- + name : str + The name of the colormap. + N : int + The number of RGB quantization levels. + """ + self.name = name + self.N = int(N) # ensure that N is always int + self._rgba_bad = (0.0, 0.0, 0.0, 0.0) # If bad, don't paint anything. + self._rgba_under = None + self._rgba_over = None + self._i_under = self.N + self._i_over = self.N + 1 + self._i_bad = self.N + 2 + self._isinit = False + #: When this colormap exists on a scalar mappable and colorbar_extend + #: is not False, colorbar creation will pick up ``colorbar_extend`` as + #: the default value for the ``extend`` keyword in the + #: `matplotlib.colorbar.Colorbar` constructor. + self.colorbar_extend = False + + def __call__(self, X, alpha=None, bytes=False): + r""" + Parameters + ---------- + X : float or int, `~numpy.ndarray` or scalar + The data value(s) to convert to RGBA. + For floats, *X* should be in the interval ``[0.0, 1.0]`` to + return the RGBA values ``X*100`` percent along the Colormap line. + For integers, *X* should be in the interval ``[0, Colormap.N)`` to + return RGBA values *indexed* from the Colormap with index ``X``. + alpha : float or array-like or None + Alpha must be a scalar between 0 and 1, a sequence of such + floats with shape matching X, or None. + bytes : bool + If False (default), the returned RGBA values will be floats in the + interval ``[0, 1]`` otherwise they will be `numpy.uint8`\s in the + interval ``[0, 255]``. + + Returns + ------- + Tuple of RGBA values if X is scalar, otherwise an array of + RGBA values with a shape of ``X.shape + (4, )``. + """ + if not self._isinit: + self._init() + + xa = np.array(X, copy=True) + if not xa.dtype.isnative: + # Native byteorder is faster. + xa = xa.byteswap().view(xa.dtype.newbyteorder()) + if xa.dtype.kind == "f": + xa *= self.N + # xa == 1 (== N after multiplication) is not out of range. + xa[xa == self.N] = self.N - 1 + # Pre-compute the masks before casting to int (which can truncate + # negative values to zero or wrap large floats to negative ints). + mask_under = xa < 0 + mask_over = xa >= self.N + # If input was masked, get the bad mask from it; else mask out nans. + mask_bad = X.mask if np.ma.is_masked(X) else np.isnan(xa) + with np.errstate(invalid="ignore"): + # We need this cast for unsigned ints as well as floats + xa = xa.astype(int) + xa[mask_under] = self._i_under + xa[mask_over] = self._i_over + xa[mask_bad] = self._i_bad + + lut = self._lut + if bytes: + lut = (lut * 255).astype(np.uint8) + + rgba = lut.take(xa, axis=0, mode='clip') + + if alpha is not None: + alpha = np.clip(alpha, 0, 1) + if bytes: + alpha *= 255 # Will be cast to uint8 upon assignment. + if alpha.shape not in [(), xa.shape]: + raise ValueError( + f"alpha is array-like but its shape {alpha.shape} does " + f"not match that of X {xa.shape}") + rgba[..., -1] = alpha + # If the "bad" color is all zeros, then ignore alpha input. + if (lut[-1] == 0).all(): + rgba[mask_bad] = (0, 0, 0, 0) + + if not np.iterable(X): + rgba = tuple(rgba) + return rgba + + def __copy__(self): + cls = self.__class__ + cmapobject = cls.__new__(cls) + cmapobject.__dict__.update(self.__dict__) + if self._isinit: + cmapobject._lut = np.copy(self._lut) + return cmapobject + + def __eq__(self, other): + if (not isinstance(other, Colormap) or + self.colorbar_extend != other.colorbar_extend): + return False + # To compare lookup tables the Colormaps have to be initialized + if not self._isinit: + self._init() + if not other._isinit: + other._init() + return np.array_equal(self._lut, other._lut) + + def get_bad(self): + """Get the color for masked values.""" + if not self._isinit: + self._init() + return np.array(self._lut[self._i_bad]) + + def set_bad(self, color='k', alpha=None): + """Set the color for masked values.""" + self._rgba_bad = to_rgba(color, alpha) + if self._isinit: + self._set_extremes() + + def get_under(self): + """Get the color for low out-of-range values.""" + if not self._isinit: + self._init() + return np.array(self._lut[self._i_under]) + + def set_under(self, color='k', alpha=None): + """Set the color for low out-of-range values.""" + self._rgba_under = to_rgba(color, alpha) + if self._isinit: + self._set_extremes() + + def get_over(self): + """Get the color for high out-of-range values.""" + if not self._isinit: + self._init() + return np.array(self._lut[self._i_over]) + + def set_over(self, color='k', alpha=None): + """Set the color for high out-of-range values.""" + self._rgba_over = to_rgba(color, alpha) + if self._isinit: + self._set_extremes() + + def set_extremes(self, *, bad=None, under=None, over=None): + """ + Set the colors for masked (*bad*) values and, when ``norm.clip = + False``, low (*under*) and high (*over*) out-of-range values. + """ + if bad is not None: + self.set_bad(bad) + if under is not None: + self.set_under(under) + if over is not None: + self.set_over(over) + + def with_extremes(self, *, bad=None, under=None, over=None): + """ + Return a copy of the colormap, for which the colors for masked (*bad*) + values and, when ``norm.clip = False``, low (*under*) and high (*over*) + out-of-range values, have been set accordingly. + """ + new_cm = self.copy() + new_cm.set_extremes(bad=bad, under=under, over=over) + return new_cm + + def _set_extremes(self): + if self._rgba_under: + self._lut[self._i_under] = self._rgba_under + else: + self._lut[self._i_under] = self._lut[0] + if self._rgba_over: + self._lut[self._i_over] = self._rgba_over + else: + self._lut[self._i_over] = self._lut[self.N - 1] + self._lut[self._i_bad] = self._rgba_bad + + def _init(self): + """Generate the lookup table, ``self._lut``.""" + raise NotImplementedError("Abstract class only") + + def is_gray(self): + """Return whether the colormap is grayscale.""" + if not self._isinit: + self._init() + return (np.all(self._lut[:, 0] == self._lut[:, 1]) and + np.all(self._lut[:, 0] == self._lut[:, 2])) + + def resampled(self, lutsize): + """Return a new colormap with *lutsize* entries.""" + if hasattr(self, '_resample'): + _api.warn_external( + "The ability to resample a color map is now public API " + f"However the class {type(self)} still only implements " + "the previous private _resample method. Please update " + "your class." + ) + return self._resample(lutsize) + + raise NotImplementedError() + + def reversed(self, name=None): + """ + Return a reversed instance of the Colormap. + + .. note:: This function is not implemented for the base class. + + Parameters + ---------- + name : str, optional + The name for the reversed colormap. If None, the + name is set to ``self.name + "_r"``. + + See Also + -------- + LinearSegmentedColormap.reversed + ListedColormap.reversed + """ + raise NotImplementedError() + + def _repr_png_(self): + """Generate a PNG representation of the Colormap.""" + X = np.tile(np.linspace(0, 1, _REPR_PNG_SIZE[0]), + (_REPR_PNG_SIZE[1], 1)) + pixels = self(X, bytes=True) + png_bytes = io.BytesIO() + title = self.name + ' colormap' + author = f'Matplotlib v{mpl.__version__}, https://matplotlib.org' + pnginfo = PngInfo() + pnginfo.add_text('Title', title) + pnginfo.add_text('Description', title) + pnginfo.add_text('Author', author) + pnginfo.add_text('Software', author) + Image.fromarray(pixels).save(png_bytes, format='png', pnginfo=pnginfo) + return png_bytes.getvalue() + + def _repr_html_(self): + """Generate an HTML representation of the Colormap.""" + png_bytes = self._repr_png_() + png_base64 = base64.b64encode(png_bytes).decode('ascii') + def color_block(color): + hex_color = to_hex(color, keep_alpha=True) + return (f'
    ') + + return ('
    ' + f'{self.name} ' + '
    ' + '
    ' + '
    ' + '
    ' + f'{color_block(self.get_under())} under' + '
    ' + '
    ' + f'bad {color_block(self.get_bad())}' + '
    ' + '
    ' + f'over {color_block(self.get_over())}' + '
    ') + + def copy(self): + """Return a copy of the colormap.""" + return self.__copy__() + + +class LinearSegmentedColormap(Colormap): + """ + Colormap objects based on lookup tables using linear segments. + + The lookup table is generated using linear interpolation for each + primary color, with the 0-1 domain divided into any number of + segments. + """ + + def __init__(self, name, segmentdata, N=256, gamma=1.0): + """ + Create colormap from linear mapping segments + + segmentdata argument is a dictionary with a red, green and blue + entries. Each entry should be a list of *x*, *y0*, *y1* tuples, + forming rows in a table. Entries for alpha are optional. + + Example: suppose you want red to increase from 0 to 1 over + the bottom half, green to do the same over the middle half, + and blue over the top half. Then you would use:: + + cdict = {'red': [(0.0, 0.0, 0.0), + (0.5, 1.0, 1.0), + (1.0, 1.0, 1.0)], + + 'green': [(0.0, 0.0, 0.0), + (0.25, 0.0, 0.0), + (0.75, 1.0, 1.0), + (1.0, 1.0, 1.0)], + + 'blue': [(0.0, 0.0, 0.0), + (0.5, 0.0, 0.0), + (1.0, 1.0, 1.0)]} + + Each row in the table for a given color is a sequence of + *x*, *y0*, *y1* tuples. In each sequence, *x* must increase + monotonically from 0 to 1. For any input value *z* falling + between *x[i]* and *x[i+1]*, the output value of a given color + will be linearly interpolated between *y1[i]* and *y0[i+1]*:: + + row i: x y0 y1 + / + / + row i+1: x y0 y1 + + Hence y0 in the first row and y1 in the last row are never used. + + See Also + -------- + LinearSegmentedColormap.from_list + Static method; factory function for generating a smoothly-varying + LinearSegmentedColormap. + """ + # True only if all colors in map are identical; needed for contouring. + self.monochrome = False + super().__init__(name, N) + self._segmentdata = segmentdata + self._gamma = gamma + + def _init(self): + self._lut = np.ones((self.N + 3, 4), float) + self._lut[:-3, 0] = _create_lookup_table( + self.N, self._segmentdata['red'], self._gamma) + self._lut[:-3, 1] = _create_lookup_table( + self.N, self._segmentdata['green'], self._gamma) + self._lut[:-3, 2] = _create_lookup_table( + self.N, self._segmentdata['blue'], self._gamma) + if 'alpha' in self._segmentdata: + self._lut[:-3, 3] = _create_lookup_table( + self.N, self._segmentdata['alpha'], 1) + self._isinit = True + self._set_extremes() + + def set_gamma(self, gamma): + """Set a new gamma value and regenerate colormap.""" + self._gamma = gamma + self._init() + + @staticmethod + def from_list(name, colors, N=256, gamma=1.0): + """ + Create a `LinearSegmentedColormap` from a list of colors. + + Parameters + ---------- + name : str + The name of the colormap. + colors : array-like of colors or array-like of (value, color) + If only colors are given, they are equidistantly mapped from the + range :math:`[0, 1]`; i.e. 0 maps to ``colors[0]`` and 1 maps to + ``colors[-1]``. + If (value, color) pairs are given, the mapping is from *value* + to *color*. This can be used to divide the range unevenly. + N : int + The number of RGB quantization levels. + gamma : float + """ + if not np.iterable(colors): + raise ValueError('colors must be iterable') + + if (isinstance(colors[0], Sized) and len(colors[0]) == 2 + and not isinstance(colors[0], str)): + # List of value, color pairs + vals, colors = zip(*colors) + else: + vals = np.linspace(0, 1, len(colors)) + + r, g, b, a = to_rgba_array(colors).T + cdict = { + "red": np.column_stack([vals, r, r]), + "green": np.column_stack([vals, g, g]), + "blue": np.column_stack([vals, b, b]), + "alpha": np.column_stack([vals, a, a]), + } + + return LinearSegmentedColormap(name, cdict, N, gamma) + + def resampled(self, lutsize): + """Return a new colormap with *lutsize* entries.""" + new_cmap = LinearSegmentedColormap(self.name, self._segmentdata, + lutsize) + new_cmap._rgba_over = self._rgba_over + new_cmap._rgba_under = self._rgba_under + new_cmap._rgba_bad = self._rgba_bad + return new_cmap + + # Helper ensuring picklability of the reversed cmap. + @staticmethod + def _reverser(func, x): + return func(1 - x) + + def reversed(self, name=None): + """ + Return a reversed instance of the Colormap. + + Parameters + ---------- + name : str, optional + The name for the reversed colormap. If None, the + name is set to ``self.name + "_r"``. + + Returns + ------- + LinearSegmentedColormap + The reversed colormap. + """ + if name is None: + name = self.name + "_r" + + # Using a partial object keeps the cmap picklable. + data_r = {key: (functools.partial(self._reverser, data) + if callable(data) else + [(1.0 - x, y1, y0) for x, y0, y1 in reversed(data)]) + for key, data in self._segmentdata.items()} + + new_cmap = LinearSegmentedColormap(name, data_r, self.N, self._gamma) + # Reverse the over/under values too + new_cmap._rgba_over = self._rgba_under + new_cmap._rgba_under = self._rgba_over + new_cmap._rgba_bad = self._rgba_bad + return new_cmap + + +class ListedColormap(Colormap): + """ + Colormap object generated from a list of colors. + + This may be most useful when indexing directly into a colormap, + but it can also be used to generate special colormaps for ordinary + mapping. + + Parameters + ---------- + colors : list, array + Sequence of Matplotlib color specifications (color names or RGB(A) + values). + name : str, optional + String to identify the colormap. + N : int, optional + Number of entries in the map. The default is *None*, in which case + there is one colormap entry for each element in the list of colors. + If :: + + N < len(colors) + + the list will be truncated at *N*. If :: + + N > len(colors) + + the list will be extended by repetition. + """ + def __init__(self, colors, name='from_list', N=None): + self.monochrome = False # Are all colors identical? (for contour.py) + if N is None: + self.colors = colors + N = len(colors) + else: + if isinstance(colors, str): + self.colors = [colors] * N + self.monochrome = True + elif np.iterable(colors): + if len(colors) == 1: + self.monochrome = True + self.colors = list( + itertools.islice(itertools.cycle(colors), N)) + else: + try: + gray = float(colors) + except TypeError: + pass + else: + self.colors = [gray] * N + self.monochrome = True + super().__init__(name, N) + + def _init(self): + self._lut = np.zeros((self.N + 3, 4), float) + self._lut[:-3] = to_rgba_array(self.colors) + self._isinit = True + self._set_extremes() + + def resampled(self, lutsize): + """Return a new colormap with *lutsize* entries.""" + colors = self(np.linspace(0, 1, lutsize)) + new_cmap = ListedColormap(colors, name=self.name) + # Keep the over/under values too + new_cmap._rgba_over = self._rgba_over + new_cmap._rgba_under = self._rgba_under + new_cmap._rgba_bad = self._rgba_bad + return new_cmap + + def reversed(self, name=None): + """ + Return a reversed instance of the Colormap. + + Parameters + ---------- + name : str, optional + The name for the reversed colormap. If None, the + name is set to ``self.name + "_r"``. + + Returns + ------- + ListedColormap + A reversed instance of the colormap. + """ + if name is None: + name = self.name + "_r" + + colors_r = list(reversed(self.colors)) + new_cmap = ListedColormap(colors_r, name=name, N=self.N) + # Reverse the over/under values too + new_cmap._rgba_over = self._rgba_under + new_cmap._rgba_under = self._rgba_over + new_cmap._rgba_bad = self._rgba_bad + return new_cmap + + +class Normalize: + """ + A class which, when called, linearly normalizes data into the + ``[0.0, 1.0]`` interval. + """ + + def __init__(self, vmin=None, vmax=None, clip=False): + """ + Parameters + ---------- + vmin, vmax : float or None + If *vmin* and/or *vmax* is not given, they are initialized from the + minimum and maximum value, respectively, of the first input + processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``. + + clip : bool, default: False + Determines the behavior for mapping values outside the range + ``[vmin, vmax]``. + + If clipping is off, values outside the range ``[vmin, vmax]`` are also + transformed linearly, resulting in values outside ``[0, 1]``. For a + standard use with colormaps, this behavior is desired because colormaps + mark these outside values with specific colors for *over* or *under*. + + If ``True`` values falling outside the range ``[vmin, vmax]``, + are mapped to 0 or 1, whichever is closer. This makes these values + indistinguishable from regular boundary values and can lead to + misinterpretation of the data. + + Notes + ----- + Returns 0 if ``vmin == vmax``. + """ + self._vmin = _sanitize_extrema(vmin) + self._vmax = _sanitize_extrema(vmax) + self._clip = clip + self._scale = None + self.callbacks = cbook.CallbackRegistry(signals=["changed"]) + + @property + def vmin(self): + return self._vmin + + @vmin.setter + def vmin(self, value): + value = _sanitize_extrema(value) + if value != self._vmin: + self._vmin = value + self._changed() + + @property + def vmax(self): + return self._vmax + + @vmax.setter + def vmax(self, value): + value = _sanitize_extrema(value) + if value != self._vmax: + self._vmax = value + self._changed() + + @property + def clip(self): + return self._clip + + @clip.setter + def clip(self, value): + if value != self._clip: + self._clip = value + self._changed() + + def _changed(self): + """ + Call this whenever the norm is changed to notify all the + callback listeners to the 'changed' signal. + """ + self.callbacks.process('changed') + + @staticmethod + def process_value(value): + """ + Homogenize the input *value* for easy and efficient normalization. + + *value* can be a scalar or sequence. + + Returns + ------- + result : masked array + Masked array with the same shape as *value*. + is_scalar : bool + Whether *value* is a scalar. + + Notes + ----- + Float dtypes are preserved; integer types with two bytes or smaller are + converted to np.float32, and larger types are converted to np.float64. + Preserving float32 when possible, and using in-place operations, + greatly improves speed for large arrays. + """ + is_scalar = not np.iterable(value) + if is_scalar: + value = [value] + dtype = np.min_scalar_type(value) + if np.issubdtype(dtype, np.integer) or dtype.type is np.bool_: + # bool_/int8/int16 -> float32; int32/int64 -> float64 + dtype = np.promote_types(dtype, np.float32) + # ensure data passed in as an ndarray subclass are interpreted as + # an ndarray. See issue #6622. + mask = np.ma.getmask(value) + data = np.asarray(value) + result = np.ma.array(data, mask=mask, dtype=dtype, copy=True) + return result, is_scalar + + def __call__(self, value, clip=None): + """ + Normalize *value* data in the ``[vmin, vmax]`` interval into the + ``[0.0, 1.0]`` interval and return it. + + Parameters + ---------- + value + Data to normalize. + clip : bool, optional + See the description of the parameter *clip* in `.Normalize`. + + If ``None``, defaults to ``self.clip`` (which defaults to + ``False``). + + Notes + ----- + If not already initialized, ``self.vmin`` and ``self.vmax`` are + initialized using ``self.autoscale_None(value)``. + """ + if clip is None: + clip = self.clip + + result, is_scalar = self.process_value(value) + + if self.vmin is None or self.vmax is None: + self.autoscale_None(result) + # Convert at least to float, without losing precision. + (vmin,), _ = self.process_value(self.vmin) + (vmax,), _ = self.process_value(self.vmax) + if vmin == vmax: + result.fill(0) # Or should it be all masked? Or 0.5? + elif vmin > vmax: + raise ValueError("minvalue must be less than or equal to maxvalue") + else: + if clip: + mask = np.ma.getmask(result) + result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax), + mask=mask) + # ma division is very slow; we can take a shortcut + resdat = result.data + resdat -= vmin + resdat /= (vmax - vmin) + result = np.ma.array(resdat, mask=result.mask, copy=False) + if is_scalar: + result = result[0] + return result + + def inverse(self, value): + if not self.scaled(): + raise ValueError("Not invertible until both vmin and vmax are set") + (vmin,), _ = self.process_value(self.vmin) + (vmax,), _ = self.process_value(self.vmax) + + if np.iterable(value): + val = np.ma.asarray(value) + return vmin + val * (vmax - vmin) + else: + return vmin + value * (vmax - vmin) + + def autoscale(self, A): + """Set *vmin*, *vmax* to min, max of *A*.""" + with self.callbacks.blocked(): + # Pause callbacks while we are updating so we only get + # a single update signal at the end + self.vmin = self.vmax = None + self.autoscale_None(A) + self._changed() + + def autoscale_None(self, A): + """If vmin or vmax are not set, use the min/max of *A* to set them.""" + A = np.asanyarray(A) + + if isinstance(A, np.ma.MaskedArray): + # we need to make the distinction between an array, False, np.bool_(False) + if A.mask is False or not A.mask.shape: + A = A.data + + if self.vmin is None and A.size: + self.vmin = A.min() + if self.vmax is None and A.size: + self.vmax = A.max() + + def scaled(self): + """Return whether vmin and vmax are set.""" + return self.vmin is not None and self.vmax is not None + + +class TwoSlopeNorm(Normalize): + def __init__(self, vcenter, vmin=None, vmax=None): + """ + Normalize data with a set center. + + Useful when mapping data with an unequal rates of change around a + conceptual center, e.g., data that range from -2 to 4, with 0 as + the midpoint. + + Parameters + ---------- + vcenter : float + The data value that defines ``0.5`` in the normalization. + vmin : float, optional + The data value that defines ``0.0`` in the normalization. + Defaults to the min value of the dataset. + vmax : float, optional + The data value that defines ``1.0`` in the normalization. + Defaults to the max value of the dataset. + + Examples + -------- + This maps data value -4000 to 0., 0 to 0.5, and +10000 to 1.0; data + between is linearly interpolated:: + + >>> import matplotlib.colors as mcolors + >>> offset = mcolors.TwoSlopeNorm(vmin=-4000., + vcenter=0., vmax=10000) + >>> data = [-4000., -2000., 0., 2500., 5000., 7500., 10000.] + >>> offset(data) + array([0., 0.25, 0.5, 0.625, 0.75, 0.875, 1.0]) + """ + + super().__init__(vmin=vmin, vmax=vmax) + self._vcenter = vcenter + if vcenter is not None and vmax is not None and vcenter >= vmax: + raise ValueError('vmin, vcenter, and vmax must be in ' + 'ascending order') + if vcenter is not None and vmin is not None and vcenter <= vmin: + raise ValueError('vmin, vcenter, and vmax must be in ' + 'ascending order') + + @property + def vcenter(self): + return self._vcenter + + @vcenter.setter + def vcenter(self, value): + if value != self._vcenter: + self._vcenter = value + self._changed() + + def autoscale_None(self, A): + """ + Get vmin and vmax. + + If vcenter isn't in the range [vmin, vmax], either vmin or vmax + is expanded so that vcenter lies in the middle of the modified range + [vmin, vmax]. + """ + super().autoscale_None(A) + if self.vmin >= self.vcenter: + self.vmin = self.vcenter - (self.vmax - self.vcenter) + if self.vmax <= self.vcenter: + self.vmax = self.vcenter + (self.vcenter - self.vmin) + + def __call__(self, value, clip=None): + """ + Map value to the interval [0, 1]. The *clip* argument is unused. + """ + result, is_scalar = self.process_value(value) + self.autoscale_None(result) # sets self.vmin, self.vmax if None + + if not self.vmin <= self.vcenter <= self.vmax: + raise ValueError("vmin, vcenter, vmax must increase monotonically") + # note that we must extrapolate for tick locators: + result = np.ma.masked_array( + np.interp(result, [self.vmin, self.vcenter, self.vmax], + [0, 0.5, 1], left=-np.inf, right=np.inf), + mask=np.ma.getmask(result)) + if is_scalar: + result = np.atleast_1d(result)[0] + return result + + def inverse(self, value): + if not self.scaled(): + raise ValueError("Not invertible until both vmin and vmax are set") + (vmin,), _ = self.process_value(self.vmin) + (vmax,), _ = self.process_value(self.vmax) + (vcenter,), _ = self.process_value(self.vcenter) + result = np.interp(value, [0, 0.5, 1], [vmin, vcenter, vmax], + left=-np.inf, right=np.inf) + return result + + +class CenteredNorm(Normalize): + def __init__(self, vcenter=0, halfrange=None, clip=False): + """ + Normalize symmetrical data around a center (0 by default). + + Unlike `TwoSlopeNorm`, `CenteredNorm` applies an equal rate of change + around the center. + + Useful when mapping symmetrical data around a conceptual center + e.g., data that range from -2 to 4, with 0 as the midpoint, and + with equal rates of change around that midpoint. + + Parameters + ---------- + vcenter : float, default: 0 + The data value that defines ``0.5`` in the normalization. + halfrange : float, optional + The range of data values that defines a range of ``0.5`` in the + normalization, so that *vcenter* - *halfrange* is ``0.0`` and + *vcenter* + *halfrange* is ``1.0`` in the normalization. + Defaults to the largest absolute difference to *vcenter* for + the values in the dataset. + clip : bool, default: False + Determines the behavior for mapping values outside the range + ``[vmin, vmax]``. + + If clipping is off, values outside the range ``[vmin, vmax]`` are also + transformed, resulting in values outside ``[0, 1]``. For a + standard use with colormaps, this behavior is desired because colormaps + mark these outside values with specific colors for *over* or *under*. + + If ``True`` values falling outside the range ``[vmin, vmax]``, + are mapped to 0 or 1, whichever is closer. This makes these values + indistinguishable from regular boundary values and can lead to + misinterpretation of the data. + + Examples + -------- + This maps data values -2 to 0.25, 0 to 0.5, and 4 to 1.0 + (assuming equal rates of change above and below 0.0): + + >>> import matplotlib.colors as mcolors + >>> norm = mcolors.CenteredNorm(halfrange=4.0) + >>> data = [-2., 0., 4.] + >>> norm(data) + array([0.25, 0.5 , 1. ]) + """ + super().__init__(vmin=None, vmax=None, clip=clip) + self._vcenter = vcenter + # calling the halfrange setter to set vmin and vmax + self.halfrange = halfrange + + def autoscale(self, A): + """ + Set *halfrange* to ``max(abs(A-vcenter))``, then set *vmin* and *vmax*. + """ + A = np.asanyarray(A) + self.halfrange = max(self._vcenter-A.min(), + A.max()-self._vcenter) + + def autoscale_None(self, A): + """Set *vmin* and *vmax*.""" + A = np.asanyarray(A) + if self.halfrange is None and A.size: + self.autoscale(A) + + @property + def vmin(self): + return self._vmin + + @vmin.setter + def vmin(self, value): + value = _sanitize_extrema(value) + if value != self._vmin: + self._vmin = value + self._vmax = 2*self.vcenter - value + self._changed() + + @property + def vmax(self): + return self._vmax + + @vmax.setter + def vmax(self, value): + value = _sanitize_extrema(value) + if value != self._vmax: + self._vmax = value + self._vmin = 2*self.vcenter - value + self._changed() + + @property + def vcenter(self): + return self._vcenter + + @vcenter.setter + def vcenter(self, vcenter): + if vcenter != self._vcenter: + self._vcenter = vcenter + # Trigger an update of the vmin/vmax values through the setter + self.halfrange = self.halfrange + self._changed() + + @property + def halfrange(self): + if self.vmin is None or self.vmax is None: + return None + return (self.vmax - self.vmin) / 2 + + @halfrange.setter + def halfrange(self, halfrange): + if halfrange is None: + self.vmin = None + self.vmax = None + else: + self.vmin = self.vcenter - abs(halfrange) + self.vmax = self.vcenter + abs(halfrange) + + +def make_norm_from_scale(scale_cls, base_norm_cls=None, *, init=None): + """ + Decorator for building a `.Normalize` subclass from a `~.scale.ScaleBase` + subclass. + + After :: + + @make_norm_from_scale(scale_cls) + class norm_cls(Normalize): + ... + + *norm_cls* is filled with methods so that normalization computations are + forwarded to *scale_cls* (i.e., *scale_cls* is the scale that would be used + for the colorbar of a mappable normalized with *norm_cls*). + + If *init* is not passed, then the constructor signature of *norm_cls* + will be ``norm_cls(vmin=None, vmax=None, clip=False)``; these three + parameters will be forwarded to the base class (``Normalize.__init__``), + and a *scale_cls* object will be initialized with no arguments (other than + a dummy axis). + + If the *scale_cls* constructor takes additional parameters, then *init* + should be passed to `make_norm_from_scale`. It is a callable which is + *only* used for its signature. First, this signature will become the + signature of *norm_cls*. Second, the *norm_cls* constructor will bind the + parameters passed to it using this signature, extract the bound *vmin*, + *vmax*, and *clip* values, pass those to ``Normalize.__init__``, and + forward the remaining bound values (including any defaults defined by the + signature) to the *scale_cls* constructor. + """ + + if base_norm_cls is None: + return functools.partial(make_norm_from_scale, scale_cls, init=init) + + if isinstance(scale_cls, functools.partial): + scale_args = scale_cls.args + scale_kwargs_items = tuple(scale_cls.keywords.items()) + scale_cls = scale_cls.func + else: + scale_args = scale_kwargs_items = () + + if init is None: + def init(vmin=None, vmax=None, clip=False): pass + + return _make_norm_from_scale( + scale_cls, scale_args, scale_kwargs_items, + base_norm_cls, inspect.signature(init)) + + +@functools.cache +def _make_norm_from_scale( + scale_cls, scale_args, scale_kwargs_items, + base_norm_cls, bound_init_signature, +): + """ + Helper for `make_norm_from_scale`. + + This function is split out to enable caching (in particular so that + different unpickles reuse the same class). In order to do so, + + - ``functools.partial`` *scale_cls* is expanded into ``func, args, kwargs`` + to allow memoizing returned norms (partial instances always compare + unequal, but we can check identity based on ``func, args, kwargs``; + - *init* is replaced by *init_signature*, as signatures are picklable, + unlike to arbitrary lambdas. + """ + + class Norm(base_norm_cls): + def __reduce__(self): + cls = type(self) + # If the class is toplevel-accessible, it is possible to directly + # pickle it "by name". This is required to support norm classes + # defined at a module's toplevel, as the inner base_norm_cls is + # otherwise unpicklable (as it gets shadowed by the generated norm + # class). If either import or attribute access fails, fall back to + # the general path. + try: + if cls is getattr(importlib.import_module(cls.__module__), + cls.__qualname__): + return (_create_empty_object_of_class, (cls,), vars(self)) + except (ImportError, AttributeError): + pass + return (_picklable_norm_constructor, + (scale_cls, scale_args, scale_kwargs_items, + base_norm_cls, bound_init_signature), + vars(self)) + + def __init__(self, *args, **kwargs): + ba = bound_init_signature.bind(*args, **kwargs) + ba.apply_defaults() + super().__init__( + **{k: ba.arguments.pop(k) for k in ["vmin", "vmax", "clip"]}) + self._scale = functools.partial( + scale_cls, *scale_args, **dict(scale_kwargs_items))( + axis=None, **ba.arguments) + self._trf = self._scale.get_transform() + + __init__.__signature__ = bound_init_signature.replace(parameters=[ + inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD), + *bound_init_signature.parameters.values()]) + + def __call__(self, value, clip=None): + value, is_scalar = self.process_value(value) + if self.vmin is None or self.vmax is None: + self.autoscale_None(value) + if self.vmin > self.vmax: + raise ValueError("vmin must be less or equal to vmax") + if self.vmin == self.vmax: + return np.full_like(value, 0) + if clip is None: + clip = self.clip + if clip: + value = np.clip(value, self.vmin, self.vmax) + t_value = self._trf.transform(value).reshape(np.shape(value)) + t_vmin, t_vmax = self._trf.transform([self.vmin, self.vmax]) + if not np.isfinite([t_vmin, t_vmax]).all(): + raise ValueError("Invalid vmin or vmax") + t_value -= t_vmin + t_value /= (t_vmax - t_vmin) + t_value = np.ma.masked_invalid(t_value, copy=False) + return t_value[0] if is_scalar else t_value + + def inverse(self, value): + if not self.scaled(): + raise ValueError("Not invertible until scaled") + if self.vmin > self.vmax: + raise ValueError("vmin must be less or equal to vmax") + t_vmin, t_vmax = self._trf.transform([self.vmin, self.vmax]) + if not np.isfinite([t_vmin, t_vmax]).all(): + raise ValueError("Invalid vmin or vmax") + value, is_scalar = self.process_value(value) + rescaled = value * (t_vmax - t_vmin) + rescaled += t_vmin + value = (self._trf + .inverted() + .transform(rescaled) + .reshape(np.shape(value))) + return value[0] if is_scalar else value + + def autoscale_None(self, A): + # i.e. A[np.isfinite(...)], but also for non-array A's + in_trf_domain = np.extract(np.isfinite(self._trf.transform(A)), A) + if in_trf_domain.size == 0: + in_trf_domain = np.ma.masked + return super().autoscale_None(in_trf_domain) + + if base_norm_cls is Normalize: + Norm.__name__ = f"{scale_cls.__name__}Norm" + Norm.__qualname__ = f"{scale_cls.__qualname__}Norm" + else: + Norm.__name__ = base_norm_cls.__name__ + Norm.__qualname__ = base_norm_cls.__qualname__ + Norm.__module__ = base_norm_cls.__module__ + Norm.__doc__ = base_norm_cls.__doc__ + + return Norm + + +def _create_empty_object_of_class(cls): + return cls.__new__(cls) + + +def _picklable_norm_constructor(*args): + return _create_empty_object_of_class(_make_norm_from_scale(*args)) + + +@make_norm_from_scale( + scale.FuncScale, + init=lambda functions, vmin=None, vmax=None, clip=False: None) +class FuncNorm(Normalize): + """ + Arbitrary normalization using functions for the forward and inverse. + + Parameters + ---------- + functions : (callable, callable) + two-tuple of the forward and inverse functions for the normalization. + The forward function must be monotonic. + + Both functions must have the signature :: + + def forward(values: array-like) -> array-like + + vmin, vmax : float or None + If *vmin* and/or *vmax* is not given, they are initialized from the + minimum and maximum value, respectively, of the first input + processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``. + + clip : bool, default: False + Determines the behavior for mapping values outside the range + ``[vmin, vmax]``. + + If clipping is off, values outside the range ``[vmin, vmax]`` are also + transformed by the function, resulting in values outside ``[0, 1]``. For a + standard use with colormaps, this behavior is desired because colormaps + mark these outside values with specific colors for *over* or *under*. + + If ``True`` values falling outside the range ``[vmin, vmax]``, + are mapped to 0 or 1, whichever is closer. This makes these values + indistinguishable from regular boundary values and can lead to + misinterpretation of the data. + """ + + +LogNorm = make_norm_from_scale( + functools.partial(scale.LogScale, nonpositive="mask"))(Normalize) +LogNorm.__name__ = LogNorm.__qualname__ = "LogNorm" +LogNorm.__doc__ = "Normalize a given value to the 0-1 range on a log scale." + + +@make_norm_from_scale( + scale.SymmetricalLogScale, + init=lambda linthresh, linscale=1., vmin=None, vmax=None, clip=False, *, + base=10: None) +class SymLogNorm(Normalize): + """ + The symmetrical logarithmic scale is logarithmic in both the + positive and negative directions from the origin. + + Since the values close to zero tend toward infinity, there is a + need to have a range around zero that is linear. The parameter + *linthresh* allows the user to specify the size of this range + (-*linthresh*, *linthresh*). + + Parameters + ---------- + linthresh : float + The range within which the plot is linear (to avoid having the plot + go to infinity around zero). + linscale : float, default: 1 + This allows the linear range (-*linthresh* to *linthresh*) to be + stretched relative to the logarithmic range. Its value is the + number of decades to use for each half of the linear range. For + example, when *linscale* == 1.0 (the default), the space used for + the positive and negative halves of the linear range will be equal + to one decade in the logarithmic range. + base : float, default: 10 + """ + + @property + def linthresh(self): + return self._scale.linthresh + + @linthresh.setter + def linthresh(self, value): + self._scale.linthresh = value + + +@make_norm_from_scale( + scale.AsinhScale, + init=lambda linear_width=1, vmin=None, vmax=None, clip=False: None) +class AsinhNorm(Normalize): + """ + The inverse hyperbolic sine scale is approximately linear near + the origin, but becomes logarithmic for larger positive + or negative values. Unlike the `SymLogNorm`, the transition between + these linear and logarithmic regions is smooth, which may reduce + the risk of visual artifacts. + + .. note:: + + This API is provisional and may be revised in the future + based on early user feedback. + + Parameters + ---------- + linear_width : float, default: 1 + The effective width of the linear region, beyond which + the transformation becomes asymptotically logarithmic + """ + + @property + def linear_width(self): + return self._scale.linear_width + + @linear_width.setter + def linear_width(self, value): + self._scale.linear_width = value + + +class PowerNorm(Normalize): + r""" + Linearly map a given value to the 0-1 range and then apply + a power-law normalization over that range. + + Parameters + ---------- + gamma : float + Power law exponent. + vmin, vmax : float or None + If *vmin* and/or *vmax* is not given, they are initialized from the + minimum and maximum value, respectively, of the first input + processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``. + clip : bool, default: False + Determines the behavior for mapping values outside the range + ``[vmin, vmax]``. + + If clipping is off, values outside the range ``[vmin, vmax]`` are also + transformed by the power function, resulting in values outside ``[0, 1]``. For + a standard use with colormaps, this behavior is desired because colormaps + mark these outside values with specific colors for *over* or *under*. + + If ``True`` values falling outside the range ``[vmin, vmax]``, + are mapped to 0 or 1, whichever is closer. This makes these values + indistinguishable from regular boundary values and can lead to + misinterpretation of the data. + + Notes + ----- + The normalization formula is + + .. math:: + + \left ( \frac{x - v_{min}}{v_{max} - v_{min}} \right )^{\gamma} + """ + def __init__(self, gamma, vmin=None, vmax=None, clip=False): + super().__init__(vmin, vmax, clip) + self.gamma = gamma + + def __call__(self, value, clip=None): + if clip is None: + clip = self.clip + + result, is_scalar = self.process_value(value) + + self.autoscale_None(result) + gamma = self.gamma + vmin, vmax = self.vmin, self.vmax + if vmin > vmax: + raise ValueError("minvalue must be less than or equal to maxvalue") + elif vmin == vmax: + result.fill(0) + else: + if clip: + mask = np.ma.getmask(result) + result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax), + mask=mask) + resdat = result.data + resdat -= vmin + resdat[resdat < 0] = 0 + np.power(resdat, gamma, resdat) + resdat /= (vmax - vmin) ** gamma + + result = np.ma.array(resdat, mask=result.mask, copy=False) + if is_scalar: + result = result[0] + return result + + def inverse(self, value): + if not self.scaled(): + raise ValueError("Not invertible until scaled") + gamma = self.gamma + vmin, vmax = self.vmin, self.vmax + + if np.iterable(value): + val = np.ma.asarray(value) + return np.ma.power(val, 1. / gamma) * (vmax - vmin) + vmin + else: + return pow(value, 1. / gamma) * (vmax - vmin) + vmin + + +class BoundaryNorm(Normalize): + """ + Generate a colormap index based on discrete intervals. + + Unlike `Normalize` or `LogNorm`, `BoundaryNorm` maps values to integers + instead of to the interval 0-1. + """ + + # Mapping to the 0-1 interval could have been done via piece-wise linear + # interpolation, but using integers seems simpler, and reduces the number + # of conversions back and forth between int and float. + + def __init__(self, boundaries, ncolors, clip=False, *, extend='neither'): + """ + Parameters + ---------- + boundaries : array-like + Monotonically increasing sequence of at least 2 bin edges: data + falling in the n-th bin will be mapped to the n-th color. + + ncolors : int + Number of colors in the colormap to be used. + + clip : bool, optional + If clip is ``True``, out of range values are mapped to 0 if they + are below ``boundaries[0]`` or mapped to ``ncolors - 1`` if they + are above ``boundaries[-1]``. + + If clip is ``False``, out of range values are mapped to -1 if + they are below ``boundaries[0]`` or mapped to *ncolors* if they are + above ``boundaries[-1]``. These are then converted to valid indices + by `Colormap.__call__`. + + extend : {'neither', 'both', 'min', 'max'}, default: 'neither' + Extend the number of bins to include one or both of the + regions beyond the boundaries. For example, if ``extend`` + is 'min', then the color to which the region between the first + pair of boundaries is mapped will be distinct from the first + color in the colormap, and by default a + `~matplotlib.colorbar.Colorbar` will be drawn with + the triangle extension on the left or lower end. + + Notes + ----- + If there are fewer bins (including extensions) than colors, then the + color index is chosen by linearly interpolating the ``[0, nbins - 1]`` + range onto the ``[0, ncolors - 1]`` range, effectively skipping some + colors in the middle of the colormap. + """ + if clip and extend != 'neither': + raise ValueError("'clip=True' is not compatible with 'extend'") + super().__init__(vmin=boundaries[0], vmax=boundaries[-1], clip=clip) + self.boundaries = np.asarray(boundaries) + self.N = len(self.boundaries) + if self.N < 2: + raise ValueError("You must provide at least 2 boundaries " + f"(1 region) but you passed in {boundaries!r}") + self.Ncmap = ncolors + self.extend = extend + + self._scale = None # don't use the default scale. + + self._n_regions = self.N - 1 # number of colors needed + self._offset = 0 + if extend in ('min', 'both'): + self._n_regions += 1 + self._offset = 1 + if extend in ('max', 'both'): + self._n_regions += 1 + if self._n_regions > self.Ncmap: + raise ValueError(f"There are {self._n_regions} color bins " + "including extensions, but ncolors = " + f"{ncolors}; ncolors must equal or exceed the " + "number of bins") + + def __call__(self, value, clip=None): + """ + This method behaves similarly to `.Normalize.__call__`, except that it + returns integers or arrays of int16. + """ + if clip is None: + clip = self.clip + + xx, is_scalar = self.process_value(value) + mask = np.ma.getmaskarray(xx) + # Fill masked values a value above the upper boundary + xx = np.atleast_1d(xx.filled(self.vmax + 1)) + if clip: + np.clip(xx, self.vmin, self.vmax, out=xx) + max_col = self.Ncmap - 1 + else: + max_col = self.Ncmap + # this gives us the bins in the lookup table in the range + # [0, _n_regions - 1] (the offset is set in the init) + iret = np.digitize(xx, self.boundaries) - 1 + self._offset + # if we have more colors than regions, stretch the region + # index computed above to full range of the color bins. This + # will make use of the full range (but skip some of the colors + # in the middle) such that the first region is mapped to the + # first color and the last region is mapped to the last color. + if self.Ncmap > self._n_regions: + if self._n_regions == 1: + # special case the 1 region case, pick the middle color + iret[iret == 0] = (self.Ncmap - 1) // 2 + else: + # otherwise linearly remap the values from the region index + # to the color index spaces + iret = (self.Ncmap - 1) / (self._n_regions - 1) * iret + # cast to 16bit integers in all cases + iret = iret.astype(np.int16) + iret[xx < self.vmin] = -1 + iret[xx >= self.vmax] = max_col + ret = np.ma.array(iret, mask=mask) + if is_scalar: + ret = int(ret[0]) # assume python scalar + return ret + + def inverse(self, value): + """ + Raises + ------ + ValueError + BoundaryNorm is not invertible, so calling this method will always + raise an error + """ + raise ValueError("BoundaryNorm is not invertible") + + +class NoNorm(Normalize): + """ + Dummy replacement for `Normalize`, for the case where we want to use + indices directly in a `~matplotlib.cm.ScalarMappable`. + """ + def __call__(self, value, clip=None): + if np.iterable(value): + return np.ma.array(value) + return value + + def inverse(self, value): + if np.iterable(value): + return np.ma.array(value) + return value + + +def rgb_to_hsv(arr): + """ + Convert an array of float RGB values (in the range [0, 1]) to HSV values. + + Parameters + ---------- + arr : (..., 3) array-like + All values must be in the range [0, 1] + + Returns + ------- + (..., 3) `~numpy.ndarray` + Colors converted to HSV values in range [0, 1] + """ + arr = np.asarray(arr) + + # check length of the last dimension, should be _some_ sort of rgb + if arr.shape[-1] != 3: + raise ValueError("Last dimension of input array must be 3; " + f"shape {arr.shape} was found.") + + in_shape = arr.shape + arr = np.array( + arr, copy=False, + dtype=np.promote_types(arr.dtype, np.float32), # Don't work on ints. + ndmin=2, # In case input was 1D. + ) + out = np.zeros_like(arr) + arr_max = arr.max(-1) + ipos = arr_max > 0 + delta = np.ptp(arr, -1) + s = np.zeros_like(delta) + s[ipos] = delta[ipos] / arr_max[ipos] + ipos = delta > 0 + # red is max + idx = (arr[..., 0] == arr_max) & ipos + out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx] + # green is max + idx = (arr[..., 1] == arr_max) & ipos + out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx] + # blue is max + idx = (arr[..., 2] == arr_max) & ipos + out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx] + + out[..., 0] = (out[..., 0] / 6.0) % 1.0 + out[..., 1] = s + out[..., 2] = arr_max + + return out.reshape(in_shape) + + +def hsv_to_rgb(hsv): + """ + Convert HSV values to RGB. + + Parameters + ---------- + hsv : (..., 3) array-like + All values assumed to be in range [0, 1] + + Returns + ------- + (..., 3) `~numpy.ndarray` + Colors converted to RGB values in range [0, 1] + """ + hsv = np.asarray(hsv) + + # check length of the last dimension, should be _some_ sort of rgb + if hsv.shape[-1] != 3: + raise ValueError("Last dimension of input array must be 3; " + f"shape {hsv.shape} was found.") + + in_shape = hsv.shape + hsv = np.array( + hsv, copy=False, + dtype=np.promote_types(hsv.dtype, np.float32), # Don't work on ints. + ndmin=2, # In case input was 1D. + ) + + h = hsv[..., 0] + s = hsv[..., 1] + v = hsv[..., 2] + + r = np.empty_like(h) + g = np.empty_like(h) + b = np.empty_like(h) + + i = (h * 6.0).astype(int) + f = (h * 6.0) - i + p = v * (1.0 - s) + q = v * (1.0 - s * f) + t = v * (1.0 - s * (1.0 - f)) + + idx = i % 6 == 0 + r[idx] = v[idx] + g[idx] = t[idx] + b[idx] = p[idx] + + idx = i == 1 + r[idx] = q[idx] + g[idx] = v[idx] + b[idx] = p[idx] + + idx = i == 2 + r[idx] = p[idx] + g[idx] = v[idx] + b[idx] = t[idx] + + idx = i == 3 + r[idx] = p[idx] + g[idx] = q[idx] + b[idx] = v[idx] + + idx = i == 4 + r[idx] = t[idx] + g[idx] = p[idx] + b[idx] = v[idx] + + idx = i == 5 + r[idx] = v[idx] + g[idx] = p[idx] + b[idx] = q[idx] + + idx = s == 0 + r[idx] = v[idx] + g[idx] = v[idx] + b[idx] = v[idx] + + rgb = np.stack([r, g, b], axis=-1) + + return rgb.reshape(in_shape) + + +def _vector_magnitude(arr): + # things that don't work here: + # * np.linalg.norm: drops mask from ma.array + # * np.sum: drops mask from ma.array unless entire vector is masked + sum_sq = 0 + for i in range(arr.shape[-1]): + sum_sq += arr[..., i, np.newaxis] ** 2 + return np.sqrt(sum_sq) + + +class LightSource: + """ + Create a light source coming from the specified azimuth and elevation. + Angles are in degrees, with the azimuth measured + clockwise from north and elevation up from the zero plane of the surface. + + `shade` is used to produce "shaded" RGB values for a data array. + `shade_rgb` can be used to combine an RGB image with an elevation map. + `hillshade` produces an illumination map of a surface. + """ + + def __init__(self, azdeg=315, altdeg=45, hsv_min_val=0, hsv_max_val=1, + hsv_min_sat=1, hsv_max_sat=0): + """ + Specify the azimuth (measured clockwise from south) and altitude + (measured up from the plane of the surface) of the light source + in degrees. + + Parameters + ---------- + azdeg : float, default: 315 degrees (from the northwest) + The azimuth (0-360, degrees clockwise from North) of the light + source. + altdeg : float, default: 45 degrees + The altitude (0-90, degrees up from horizontal) of the light + source. + hsv_min_val : number, default: 0 + The minimum value ("v" in "hsv") that the *intensity* map can shift the + output image to. + hsv_max_val : number, default: 1 + The maximum value ("v" in "hsv") that the *intensity* map can shift the + output image to. + hsv_min_sat : number, default: 1 + The minimum saturation value that the *intensity* map can shift the output + image to. + hsv_max_sat : number, default: 0 + The maximum saturation value that the *intensity* map can shift the output + image to. + + Notes + ----- + For backwards compatibility, the parameters *hsv_min_val*, + *hsv_max_val*, *hsv_min_sat*, and *hsv_max_sat* may be supplied at + initialization as well. However, these parameters will only be used if + "blend_mode='hsv'" is passed into `shade` or `shade_rgb`. + See the documentation for `blend_hsv` for more details. + """ + self.azdeg = azdeg + self.altdeg = altdeg + self.hsv_min_val = hsv_min_val + self.hsv_max_val = hsv_max_val + self.hsv_min_sat = hsv_min_sat + self.hsv_max_sat = hsv_max_sat + + @property + def direction(self): + """The unit vector direction towards the light source.""" + # Azimuth is in degrees clockwise from North. Convert to radians + # counterclockwise from East (mathematical notation). + az = np.radians(90 - self.azdeg) + alt = np.radians(self.altdeg) + return np.array([ + np.cos(az) * np.cos(alt), + np.sin(az) * np.cos(alt), + np.sin(alt) + ]) + + def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.): + """ + Calculate the illumination intensity for a surface using the defined + azimuth and elevation for the light source. + + This computes the normal vectors for the surface, and then passes them + on to `shade_normals` + + Parameters + ---------- + elevation : 2D array-like + The height values used to generate an illumination map + vert_exag : number, optional + The amount to exaggerate the elevation values by when calculating + illumination. This can be used either to correct for differences in + units between the x-y coordinate system and the elevation + coordinate system (e.g. decimal degrees vs. meters) or to + exaggerate or de-emphasize topographic effects. + dx : number, optional + The x-spacing (columns) of the input *elevation* grid. + dy : number, optional + The y-spacing (rows) of the input *elevation* grid. + fraction : number, optional + Increases or decreases the contrast of the hillshade. Values + greater than one will cause intermediate values to move closer to + full illumination or shadow (and clipping any values that move + beyond 0 or 1). Note that this is not visually or mathematically + the same as vertical exaggeration. + + Returns + ------- + `~numpy.ndarray` + A 2D array of illumination values between 0-1, where 0 is + completely in shadow and 1 is completely illuminated. + """ + + # Because most image and raster GIS data has the first row in the array + # as the "top" of the image, dy is implicitly negative. This is + # consistent to what `imshow` assumes, as well. + dy = -dy + + # compute the normal vectors from the partial derivatives + e_dy, e_dx = np.gradient(vert_exag * elevation, dy, dx) + + # .view is to keep subclasses + normal = np.empty(elevation.shape + (3,)).view(type(elevation)) + normal[..., 0] = -e_dx + normal[..., 1] = -e_dy + normal[..., 2] = 1 + normal /= _vector_magnitude(normal) + + return self.shade_normals(normal, fraction) + + def shade_normals(self, normals, fraction=1.): + """ + Calculate the illumination intensity for the normal vectors of a + surface using the defined azimuth and elevation for the light source. + + Imagine an artificial sun placed at infinity in some azimuth and + elevation position illuminating our surface. The parts of the surface + that slope toward the sun should brighten while those sides facing away + should become darker. + + Parameters + ---------- + fraction : number, optional + Increases or decreases the contrast of the hillshade. Values + greater than one will cause intermediate values to move closer to + full illumination or shadow (and clipping any values that move + beyond 0 or 1). Note that this is not visually or mathematically + the same as vertical exaggeration. + + Returns + ------- + `~numpy.ndarray` + A 2D array of illumination values between 0-1, where 0 is + completely in shadow and 1 is completely illuminated. + """ + + intensity = normals.dot(self.direction) + + # Apply contrast stretch + imin, imax = intensity.min(), intensity.max() + intensity *= fraction + + # Rescale to 0-1, keeping range before contrast stretch + # If constant slope, keep relative scaling (i.e. flat should be 0.5, + # fully occluded 0, etc.) + if (imax - imin) > 1e-6: + # Strictly speaking, this is incorrect. Negative values should be + # clipped to 0 because they're fully occluded. However, rescaling + # in this manner is consistent with the previous implementation and + # visually appears better than a "hard" clip. + intensity -= imin + intensity /= (imax - imin) + intensity = np.clip(intensity, 0, 1) + + return intensity + + def shade(self, data, cmap, norm=None, blend_mode='overlay', vmin=None, + vmax=None, vert_exag=1, dx=1, dy=1, fraction=1, **kwargs): + """ + Combine colormapped data values with an illumination intensity map + (a.k.a. "hillshade") of the values. + + Parameters + ---------- + data : 2D array-like + The height values used to generate a shaded map. + cmap : `~matplotlib.colors.Colormap` + The colormap used to color the *data* array. Note that this must be + a `~matplotlib.colors.Colormap` instance. For example, rather than + passing in ``cmap='gist_earth'``, use + ``cmap=plt.get_cmap('gist_earth')`` instead. + norm : `~matplotlib.colors.Normalize` instance, optional + The normalization used to scale values before colormapping. If + None, the input will be linearly scaled between its min and max. + blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional + The type of blending used to combine the colormapped data + values with the illumination intensity. Default is + "overlay". Note that for most topographic surfaces, + "overlay" or "soft" appear more visually realistic. If a + user-defined function is supplied, it is expected to + combine an (M, N, 3) RGB array of floats (ranging 0 to 1) with + an (M, N, 1) hillshade array (also 0 to 1). (Call signature + ``func(rgb, illum, **kwargs)``) Additional kwargs supplied + to this function will be passed on to the *blend_mode* + function. + vmin : float or None, optional + The minimum value used in colormapping *data*. If *None* the + minimum value in *data* is used. If *norm* is specified, then this + argument will be ignored. + vmax : float or None, optional + The maximum value used in colormapping *data*. If *None* the + maximum value in *data* is used. If *norm* is specified, then this + argument will be ignored. + vert_exag : number, optional + The amount to exaggerate the elevation values by when calculating + illumination. This can be used either to correct for differences in + units between the x-y coordinate system and the elevation + coordinate system (e.g. decimal degrees vs. meters) or to + exaggerate or de-emphasize topography. + dx : number, optional + The x-spacing (columns) of the input *elevation* grid. + dy : number, optional + The y-spacing (rows) of the input *elevation* grid. + fraction : number, optional + Increases or decreases the contrast of the hillshade. Values + greater than one will cause intermediate values to move closer to + full illumination or shadow (and clipping any values that move + beyond 0 or 1). Note that this is not visually or mathematically + the same as vertical exaggeration. + **kwargs + Additional kwargs are passed on to the *blend_mode* function. + + Returns + ------- + `~numpy.ndarray` + An (M, N, 4) array of floats ranging between 0-1. + """ + if vmin is None: + vmin = data.min() + if vmax is None: + vmax = data.max() + if norm is None: + norm = Normalize(vmin=vmin, vmax=vmax) + + rgb0 = cmap(norm(data)) + rgb1 = self.shade_rgb(rgb0, elevation=data, blend_mode=blend_mode, + vert_exag=vert_exag, dx=dx, dy=dy, + fraction=fraction, **kwargs) + # Don't overwrite the alpha channel, if present. + rgb0[..., :3] = rgb1[..., :3] + return rgb0 + + def shade_rgb(self, rgb, elevation, fraction=1., blend_mode='hsv', + vert_exag=1, dx=1, dy=1, **kwargs): + """ + Use this light source to adjust the colors of the *rgb* input array to + give the impression of a shaded relief map with the given *elevation*. + + Parameters + ---------- + rgb : array-like + An (M, N, 3) RGB array, assumed to be in the range of 0 to 1. + elevation : array-like + An (M, N) array of the height values used to generate a shaded map. + fraction : number + Increases or decreases the contrast of the hillshade. Values + greater than one will cause intermediate values to move closer to + full illumination or shadow (and clipping any values that move + beyond 0 or 1). Note that this is not visually or mathematically + the same as vertical exaggeration. + blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional + The type of blending used to combine the colormapped data values + with the illumination intensity. For backwards compatibility, this + defaults to "hsv". Note that for most topographic surfaces, + "overlay" or "soft" appear more visually realistic. If a + user-defined function is supplied, it is expected to combine an + (M, N, 3) RGB array of floats (ranging 0 to 1) with an (M, N, 1) + hillshade array (also 0 to 1). (Call signature + ``func(rgb, illum, **kwargs)``) + Additional kwargs supplied to this function will be passed on to + the *blend_mode* function. + vert_exag : number, optional + The amount to exaggerate the elevation values by when calculating + illumination. This can be used either to correct for differences in + units between the x-y coordinate system and the elevation + coordinate system (e.g. decimal degrees vs. meters) or to + exaggerate or de-emphasize topography. + dx : number, optional + The x-spacing (columns) of the input *elevation* grid. + dy : number, optional + The y-spacing (rows) of the input *elevation* grid. + **kwargs + Additional kwargs are passed on to the *blend_mode* function. + + Returns + ------- + `~numpy.ndarray` + An (m, n, 3) array of floats ranging between 0-1. + """ + # Calculate the "hillshade" intensity. + intensity = self.hillshade(elevation, vert_exag, dx, dy, fraction) + intensity = intensity[..., np.newaxis] + + # Blend the hillshade and rgb data using the specified mode + lookup = { + 'hsv': self.blend_hsv, + 'soft': self.blend_soft_light, + 'overlay': self.blend_overlay, + } + if blend_mode in lookup: + blend = lookup[blend_mode](rgb, intensity, **kwargs) + else: + try: + blend = blend_mode(rgb, intensity, **kwargs) + except TypeError as err: + raise ValueError('"blend_mode" must be callable or one of ' + f'{lookup.keys}') from err + + # Only apply result where hillshade intensity isn't masked + if np.ma.is_masked(intensity): + mask = intensity.mask[..., 0] + for i in range(3): + blend[..., i][mask] = rgb[..., i][mask] + + return blend + + def blend_hsv(self, rgb, intensity, hsv_max_sat=None, hsv_max_val=None, + hsv_min_val=None, hsv_min_sat=None): + """ + Take the input data array, convert to HSV values in the given colormap, + then adjust those color values to give the impression of a shaded + relief map with a specified light source. RGBA values are returned, + which can then be used to plot the shaded image with imshow. + + The color of the resulting image will be darkened by moving the (s, v) + values (in HSV colorspace) toward (hsv_min_sat, hsv_min_val) in the + shaded regions, or lightened by sliding (s, v) toward (hsv_max_sat, + hsv_max_val) in regions that are illuminated. The default extremes are + chose so that completely shaded points are nearly black (s = 1, v = 0) + and completely illuminated points are nearly white (s = 0, v = 1). + + Parameters + ---------- + rgb : `~numpy.ndarray` + An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image). + intensity : `~numpy.ndarray` + An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image). + hsv_max_sat : number, optional + The maximum saturation value that the *intensity* map can shift the output + image to. If not provided, use the value provided upon initialization. + hsv_min_sat : number, optional + The minimum saturation value that the *intensity* map can shift the output + image to. If not provided, use the value provided upon initialization. + hsv_max_val : number, optional + The maximum value ("v" in "hsv") that the *intensity* map can shift the + output image to. If not provided, use the value provided upon + initialization. + hsv_min_val : number, optional + The minimum value ("v" in "hsv") that the *intensity* map can shift the + output image to. If not provided, use the value provided upon + initialization. + + Returns + ------- + `~numpy.ndarray` + An (M, N, 3) RGB array representing the combined images. + """ + # Backward compatibility... + if hsv_max_sat is None: + hsv_max_sat = self.hsv_max_sat + if hsv_max_val is None: + hsv_max_val = self.hsv_max_val + if hsv_min_sat is None: + hsv_min_sat = self.hsv_min_sat + if hsv_min_val is None: + hsv_min_val = self.hsv_min_val + + # Expects a 2D intensity array scaled between -1 to 1... + intensity = intensity[..., 0] + intensity = 2 * intensity - 1 + + # Convert to rgb, then rgb to hsv + hsv = rgb_to_hsv(rgb[:, :, 0:3]) + hue, sat, val = np.moveaxis(hsv, -1, 0) + + # Modify hsv values (in place) to simulate illumination. + # putmask(A, mask, B) <=> A[mask] = B[mask] + np.putmask(sat, (np.abs(sat) > 1.e-10) & (intensity > 0), + (1 - intensity) * sat + intensity * hsv_max_sat) + np.putmask(sat, (np.abs(sat) > 1.e-10) & (intensity < 0), + (1 + intensity) * sat - intensity * hsv_min_sat) + np.putmask(val, intensity > 0, + (1 - intensity) * val + intensity * hsv_max_val) + np.putmask(val, intensity < 0, + (1 + intensity) * val - intensity * hsv_min_val) + np.clip(hsv[:, :, 1:], 0, 1, out=hsv[:, :, 1:]) + + # Convert modified hsv back to rgb. + return hsv_to_rgb(hsv) + + def blend_soft_light(self, rgb, intensity): + """ + Combine an RGB image with an intensity map using "soft light" blending, + using the "pegtop" formula. + + Parameters + ---------- + rgb : `~numpy.ndarray` + An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image). + intensity : `~numpy.ndarray` + An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image). + + Returns + ------- + `~numpy.ndarray` + An (M, N, 3) RGB array representing the combined images. + """ + return 2 * intensity * rgb + (1 - 2 * intensity) * rgb**2 + + def blend_overlay(self, rgb, intensity): + """ + Combine an RGB image with an intensity map using "overlay" blending. + + Parameters + ---------- + rgb : `~numpy.ndarray` + An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image). + intensity : `~numpy.ndarray` + An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image). + + Returns + ------- + ndarray + An (M, N, 3) RGB array representing the combined images. + """ + low = 2 * intensity * rgb + high = 1 - 2 * (1 - intensity) * (1 - rgb) + return np.where(rgb <= 0.5, low, high) + + +def from_levels_and_colors(levels, colors, extend='neither'): + """ + A helper routine to generate a cmap and a norm instance which + behave similar to contourf's levels and colors arguments. + + Parameters + ---------- + levels : sequence of numbers + The quantization levels used to construct the `BoundaryNorm`. + Value ``v`` is quantized to level ``i`` if ``lev[i] <= v < lev[i+1]``. + colors : sequence of colors + The fill color to use for each level. If *extend* is "neither" there + must be ``n_level - 1`` colors. For an *extend* of "min" or "max" add + one extra color, and for an *extend* of "both" add two colors. + extend : {'neither', 'min', 'max', 'both'}, optional + The behaviour when a value falls out of range of the given levels. + See `~.Axes.contourf` for details. + + Returns + ------- + cmap : `~matplotlib.colors.Colormap` + norm : `~matplotlib.colors.Normalize` + """ + slice_map = { + 'both': slice(1, -1), + 'min': slice(1, None), + 'max': slice(0, -1), + 'neither': slice(0, None), + } + _api.check_in_list(slice_map, extend=extend) + color_slice = slice_map[extend] + + n_data_colors = len(levels) - 1 + n_expected = n_data_colors + color_slice.start - (color_slice.stop or 0) + if len(colors) != n_expected: + raise ValueError( + f'With extend == {extend!r} and {len(levels)} levels, ' + f'expected {n_expected} colors, but got {len(colors)}') + + cmap = ListedColormap(colors[color_slice], N=n_data_colors) + + if extend in ['min', 'both']: + cmap.set_under(colors[0]) + else: + cmap.set_under('none') + + if extend in ['max', 'both']: + cmap.set_over(colors[-1]) + else: + cmap.set_over('none') + + cmap.colorbar_extend = extend + + norm = BoundaryNorm(levels, ncolors=n_data_colors) + return cmap, norm diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.pyi new file mode 100644 index 00000000..9bb1725f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/colors.pyi @@ -0,0 +1,354 @@ +from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence +from matplotlib import cbook, scale +import re + +from typing import Any, Literal, overload +from .typing import ColorType + +import numpy as np +from numpy.typing import ArrayLike + +# Explicitly export colors dictionaries which are imported in the impl +BASE_COLORS: dict[str, ColorType] +CSS4_COLORS: dict[str, ColorType] +TABLEAU_COLORS: dict[str, ColorType] +XKCD_COLORS: dict[str, ColorType] + +class _ColorMapping(dict[str, ColorType]): + cache: dict[tuple[ColorType, float | None], tuple[float, float, float, float]] + def __init__(self, mapping) -> None: ... + def __setitem__(self, key, value) -> None: ... + def __delitem__(self, key) -> None: ... + +def get_named_colors_mapping() -> _ColorMapping: ... + +class ColorSequenceRegistry(Mapping): + def __init__(self) -> None: ... + def __getitem__(self, item: str) -> list[ColorType]: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def register(self, name: str, color_list: Iterable[ColorType]) -> None: ... + def unregister(self, name: str) -> None: ... + +_color_sequences: ColorSequenceRegistry = ... + +def is_color_like(c: Any) -> bool: ... +def same_color(c1: ColorType, c2: ColorType) -> bool: ... +def to_rgba( + c: ColorType, alpha: float | None = ... +) -> tuple[float, float, float, float]: ... +def to_rgba_array( + c: ColorType | ArrayLike, alpha: float | ArrayLike | None = ... +) -> np.ndarray: ... +def to_rgb(c: ColorType) -> tuple[float, float, float]: ... +def to_hex(c: ColorType, keep_alpha: bool = ...) -> str: ... + +cnames: dict[str, ColorType] +hexColorPattern: re.Pattern +rgb2hex = to_hex +hex2color = to_rgb + +class ColorConverter: + colors: _ColorMapping + cache: dict[tuple[ColorType, float | None], tuple[float, float, float, float]] + @staticmethod + def to_rgb(c: ColorType) -> tuple[float, float, float]: ... + @staticmethod + def to_rgba( + c: ColorType, alpha: float | None = ... + ) -> tuple[float, float, float, float]: ... + @staticmethod + def to_rgba_array( + c: ColorType | ArrayLike, alpha: float | ArrayLike | None = ... + ) -> np.ndarray: ... + +colorConverter: ColorConverter + +class Colormap: + name: str + N: int + colorbar_extend: bool + def __init__(self, name: str, N: int = ...) -> None: ... + @overload + def __call__( + self, X: Sequence[float] | np.ndarray, alpha: ArrayLike | None = ..., bytes: bool = ... + ) -> np.ndarray: ... + @overload + def __call__( + self, X: float, alpha: float | None = ..., bytes: bool = ... + ) -> tuple[float, float, float, float]: ... + @overload + def __call__( + self, X: ArrayLike, alpha: ArrayLike | None = ..., bytes: bool = ... + ) -> tuple[float, float, float, float] | np.ndarray: ... + def __copy__(self) -> Colormap: ... + def __eq__(self, other: object) -> bool: ... + def get_bad(self) -> np.ndarray: ... + def set_bad(self, color: ColorType = ..., alpha: float | None = ...) -> None: ... + def get_under(self) -> np.ndarray: ... + def set_under(self, color: ColorType = ..., alpha: float | None = ...) -> None: ... + def get_over(self) -> np.ndarray: ... + def set_over(self, color: ColorType = ..., alpha: float | None = ...) -> None: ... + def set_extremes( + self, + *, + bad: ColorType | None = ..., + under: ColorType | None = ..., + over: ColorType | None = ... + ) -> None: ... + def with_extremes( + self, + *, + bad: ColorType | None = ..., + under: ColorType | None = ..., + over: ColorType | None = ... + ) -> Colormap: ... + def is_gray(self) -> bool: ... + def resampled(self, lutsize: int) -> Colormap: ... + def reversed(self, name: str | None = ...) -> Colormap: ... + def _repr_html_(self) -> str: ... + def _repr_png_(self) -> bytes: ... + def copy(self) -> Colormap: ... + +class LinearSegmentedColormap(Colormap): + monochrome: bool + def __init__( + self, + name: str, + segmentdata: dict[ + Literal["red", "green", "blue", "alpha"], Sequence[tuple[float, ...]] + ], + N: int = ..., + gamma: float = ..., + ) -> None: ... + def set_gamma(self, gamma: float) -> None: ... + @staticmethod + def from_list( + name: str, colors: ArrayLike, N: int = ..., gamma: float = ... + ) -> LinearSegmentedColormap: ... + def resampled(self, lutsize: int) -> LinearSegmentedColormap: ... + def reversed(self, name: str | None = ...) -> LinearSegmentedColormap: ... + +class ListedColormap(Colormap): + monochrome: bool + colors: ArrayLike | ColorType + def __init__( + self, colors: ArrayLike | ColorType, name: str = ..., N: int | None = ... + ) -> None: ... + def resampled(self, lutsize: int) -> ListedColormap: ... + def reversed(self, name: str | None = ...) -> ListedColormap: ... + +class Normalize: + callbacks: cbook.CallbackRegistry + def __init__( + self, vmin: float | None = ..., vmax: float | None = ..., clip: bool = ... + ) -> None: ... + @property + def vmin(self) -> float | None: ... + @vmin.setter + def vmin(self, value: float | None) -> None: ... + @property + def vmax(self) -> float | None: ... + @vmax.setter + def vmax(self, value: float | None) -> None: ... + @property + def clip(self) -> bool: ... + @clip.setter + def clip(self, value: bool) -> None: ... + @staticmethod + def process_value(value: ArrayLike) -> tuple[np.ma.MaskedArray, bool]: ... + @overload + def __call__(self, value: float, clip: bool | None = ...) -> float: ... + @overload + def __call__(self, value: np.ndarray, clip: bool | None = ...) -> np.ma.MaskedArray: ... + @overload + def __call__(self, value: ArrayLike, clip: bool | None = ...) -> ArrayLike: ... + @overload + def inverse(self, value: float) -> float: ... + @overload + def inverse(self, value: np.ndarray) -> np.ma.MaskedArray: ... + @overload + def inverse(self, value: ArrayLike) -> ArrayLike: ... + def autoscale(self, A: ArrayLike) -> None: ... + def autoscale_None(self, A: ArrayLike) -> None: ... + def scaled(self) -> bool: ... + +class TwoSlopeNorm(Normalize): + def __init__( + self, vcenter: float, vmin: float | None = ..., vmax: float | None = ... + ) -> None: ... + @property + def vcenter(self) -> float: ... + @vcenter.setter + def vcenter(self, value: float) -> None: ... + def autoscale_None(self, A: ArrayLike) -> None: ... + +class CenteredNorm(Normalize): + def __init__( + self, vcenter: float = ..., halfrange: float | None = ..., clip: bool = ... + ) -> None: ... + @property + def vcenter(self) -> float: ... + @vcenter.setter + def vcenter(self, vcenter: float) -> None: ... + @property + def halfrange(self) -> float: ... + @halfrange.setter + def halfrange(self, halfrange: float) -> None: ... + +@overload +def make_norm_from_scale( + scale_cls: type[scale.ScaleBase], + base_norm_cls: type[Normalize], + *, + init: Callable | None = ... +) -> type[Normalize]: ... +@overload +def make_norm_from_scale( + scale_cls: type[scale.ScaleBase], + base_norm_cls: None = ..., + *, + init: Callable | None = ... +) -> Callable[[type[Normalize]], type[Normalize]]: ... + +class FuncNorm(Normalize): + def __init__( + self, + functions: tuple[Callable, Callable], + vmin: float | None = ..., + vmax: float | None = ..., + clip: bool = ..., + ) -> None: ... +class LogNorm(Normalize): ... + +class SymLogNorm(Normalize): + def __init__( + self, + linthresh: float, + linscale: float = ..., + vmin: float | None = ..., + vmax: float | None = ..., + clip: bool = ..., + *, + base: float = ..., + ) -> None: ... + @property + def linthresh(self) -> float: ... + @linthresh.setter + def linthresh(self, value: float) -> None: ... + +class AsinhNorm(Normalize): + def __init__( + self, + linear_width: float = ..., + vmin: float | None = ..., + vmax: float | None = ..., + clip: bool = ..., + ) -> None: ... + @property + def linear_width(self) -> float: ... + @linear_width.setter + def linear_width(self, value: float) -> None: ... + +class PowerNorm(Normalize): + gamma: float + def __init__( + self, + gamma: float, + vmin: float | None = ..., + vmax: float | None = ..., + clip: bool = ..., + ) -> None: ... + +class BoundaryNorm(Normalize): + boundaries: np.ndarray + N: int + Ncmap: int + extend: Literal["neither", "both", "min", "max"] + def __init__( + self, + boundaries: ArrayLike, + ncolors: int, + clip: bool = ..., + *, + extend: Literal["neither", "both", "min", "max"] = ... + ) -> None: ... + +class NoNorm(Normalize): ... + +def rgb_to_hsv(arr: ArrayLike) -> np.ndarray: ... +def hsv_to_rgb(hsv: ArrayLike) -> np.ndarray: ... + +class LightSource: + azdeg: float + altdeg: float + hsv_min_val: float + hsv_max_val: float + hsv_min_sat: float + hsv_max_sat: float + def __init__( + self, + azdeg: float = ..., + altdeg: float = ..., + hsv_min_val: float = ..., + hsv_max_val: float = ..., + hsv_min_sat: float = ..., + hsv_max_sat: float = ..., + ) -> None: ... + @property + def direction(self) -> np.ndarray: ... + def hillshade( + self, + elevation: ArrayLike, + vert_exag: float = ..., + dx: float = ..., + dy: float = ..., + fraction: float = ..., + ) -> np.ndarray: ... + def shade_normals( + self, normals: np.ndarray, fraction: float = ... + ) -> np.ndarray: ... + def shade( + self, + data: ArrayLike, + cmap: Colormap, + norm: Normalize | None = ..., + blend_mode: Literal["hsv", "overlay", "soft"] | Callable = ..., + vmin: float | None = ..., + vmax: float | None = ..., + vert_exag: float = ..., + dx: float = ..., + dy: float = ..., + fraction: float = ..., + **kwargs + ) -> np.ndarray: ... + def shade_rgb( + self, + rgb: ArrayLike, + elevation: ArrayLike, + fraction: float = ..., + blend_mode: Literal["hsv", "overlay", "soft"] | Callable = ..., + vert_exag: float = ..., + dx: float = ..., + dy: float = ..., + **kwargs + ) -> np.ndarray: ... + def blend_hsv( + self, + rgb: ArrayLike, + intensity: ArrayLike, + hsv_max_sat: float | None = ..., + hsv_max_val: float | None = ..., + hsv_min_val: float | None = ..., + hsv_min_sat: float | None = ..., + ) -> ArrayLike: ... + def blend_soft_light( + self, rgb: np.ndarray, intensity: np.ndarray + ) -> np.ndarray: ... + def blend_overlay(self, rgb: np.ndarray, intensity: np.ndarray) -> np.ndarray: ... + +def from_levels_and_colors( + levels: Sequence[float], + colors: Sequence[ColorType], + extend: Literal["neither", "min", "max", "both"] = ..., +) -> tuple[ListedColormap, BoundaryNorm]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.py new file mode 100644 index 00000000..0f082e29 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.py @@ -0,0 +1,141 @@ +from matplotlib import cbook +from matplotlib.artist import Artist + + +class Container(tuple): + """ + Base class for containers. + + Containers are classes that collect semantically related Artists such as + the bars of a bar plot. + """ + + def __repr__(self): + return f"<{type(self).__name__} object of {len(self)} artists>" + + def __new__(cls, *args, **kwargs): + return tuple.__new__(cls, args[0]) + + def __init__(self, kl, label=None): + self._callbacks = cbook.CallbackRegistry(signals=["pchanged"]) + self._remove_method = None + self._label = str(label) if label is not None else None + + def remove(self): + for c in cbook.flatten( + self, scalarp=lambda x: isinstance(x, Artist)): + if c is not None: + c.remove() + if self._remove_method: + self._remove_method(self) + + def get_children(self): + return [child for child in cbook.flatten(self) if child is not None] + + get_label = Artist.get_label + set_label = Artist.set_label + add_callback = Artist.add_callback + remove_callback = Artist.remove_callback + pchanged = Artist.pchanged + + +class BarContainer(Container): + """ + Container for the artists of bar plots (e.g. created by `.Axes.bar`). + + The container can be treated as a tuple of the *patches* themselves. + Additionally, you can access these and further parameters by the + attributes. + + Attributes + ---------- + patches : list of :class:`~matplotlib.patches.Rectangle` + The artists of the bars. + + errorbar : None or :class:`~matplotlib.container.ErrorbarContainer` + A container for the error bar artists if error bars are present. + *None* otherwise. + + datavalues : None or array-like + The underlying data values corresponding to the bars. + + orientation : {'vertical', 'horizontal'}, default: None + If 'vertical', the bars are assumed to be vertical. + If 'horizontal', the bars are assumed to be horizontal. + + """ + + def __init__(self, patches, errorbar=None, *, datavalues=None, + orientation=None, **kwargs): + self.patches = patches + self.errorbar = errorbar + self.datavalues = datavalues + self.orientation = orientation + super().__init__(patches, **kwargs) + + +class ErrorbarContainer(Container): + """ + Container for the artists of error bars (e.g. created by `.Axes.errorbar`). + + The container can be treated as the *lines* tuple itself. + Additionally, you can access these and further parameters by the + attributes. + + Attributes + ---------- + lines : tuple + Tuple of ``(data_line, caplines, barlinecols)``. + + - data_line : :class:`~matplotlib.lines.Line2D` instance of + x, y plot markers and/or line. + - caplines : tuple of :class:`~matplotlib.lines.Line2D` instances of + the error bar caps. + - barlinecols : list of :class:`~matplotlib.collections.LineCollection` + with the horizontal and vertical error ranges. + + has_xerr, has_yerr : bool + ``True`` if the errorbar has x/y errors. + + """ + + def __init__(self, lines, has_xerr=False, has_yerr=False, **kwargs): + self.lines = lines + self.has_xerr = has_xerr + self.has_yerr = has_yerr + super().__init__(lines, **kwargs) + + +class StemContainer(Container): + """ + Container for the artists created in a :meth:`.Axes.stem` plot. + + The container can be treated like a namedtuple ``(markerline, stemlines, + baseline)``. + + Attributes + ---------- + markerline : :class:`~matplotlib.lines.Line2D` + The artist of the markers at the stem heads. + + stemlines : list of :class:`~matplotlib.lines.Line2D` + The artists of the vertical lines for all stems. + + baseline : :class:`~matplotlib.lines.Line2D` + The artist of the horizontal baseline. + """ + def __init__(self, markerline_stemlines_baseline, **kwargs): + """ + Parameters + ---------- + markerline_stemlines_baseline : tuple + Tuple of ``(markerline, stemlines, baseline)``. + ``markerline`` contains the `.LineCollection` of the markers, + ``stemlines`` is a `.LineCollection` of the main lines, + ``baseline`` is the `.Line2D` of the baseline. + """ + markerline, stemlines, baseline = markerline_stemlines_baseline + self.markerline = markerline + self.stemlines = stemlines + self.baseline = baseline + super().__init__(markerline_stemlines_baseline, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.pyi new file mode 100644 index 00000000..9cc2e1ac --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/container.pyi @@ -0,0 +1,56 @@ +from matplotlib.artist import Artist +from matplotlib.lines import Line2D +from matplotlib.collections import LineCollection +from matplotlib.patches import Rectangle + +from collections.abc import Callable +from typing import Any, Literal +from numpy.typing import ArrayLike + +class Container(tuple): + def __new__(cls, *args, **kwargs): ... + def __init__(self, kl, label: Any | None = ...) -> None: ... + def remove(self) -> None: ... + def get_children(self) -> list[Artist]: ... + def get_label(self) -> str | None: ... + def set_label(self, s: Any) -> None: ... + def add_callback(self, func: Callable[[Artist], Any]) -> int: ... + def remove_callback(self, oid: int) -> None: ... + def pchanged(self) -> None: ... + +class BarContainer(Container): + patches: list[Rectangle] + errorbar: None | ErrorbarContainer + datavalues: None | ArrayLike + orientation: None | Literal["vertical", "horizontal"] + def __init__( + self, + patches: list[Rectangle], + errorbar: ErrorbarContainer | None = ..., + *, + datavalues: ArrayLike | None = ..., + orientation: Literal["vertical", "horizontal"] | None = ..., + **kwargs + ) -> None: ... + +class ErrorbarContainer(Container): + lines: tuple[Line2D, Line2D, LineCollection] + has_xerr: bool + has_yerr: bool + def __init__( + self, + lines: tuple[Line2D, Line2D, LineCollection], + has_xerr: bool = ..., + has_yerr: bool = ..., + **kwargs + ) -> None: ... + +class StemContainer(Container): + markerline: Line2D + stemlines: LineCollection + baseline: Line2D + def __init__( + self, + markerline_stemlines_baseline: tuple[Line2D, LineCollection, Line2D], + **kwargs + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.py new file mode 100644 index 00000000..6e889968 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.py @@ -0,0 +1,1902 @@ +""" +Classes to support contour plotting and labelling for the Axes class. +""" + +from contextlib import ExitStack +import functools +import math +from numbers import Integral + +import numpy as np +from numpy import ma + +import matplotlib as mpl +from matplotlib import _api, _docstring +from matplotlib.backend_bases import MouseButton +from matplotlib.lines import Line2D +from matplotlib.path import Path +from matplotlib.text import Text +import matplotlib.ticker as ticker +import matplotlib.cm as cm +import matplotlib.colors as mcolors +import matplotlib.collections as mcoll +import matplotlib.font_manager as font_manager +import matplotlib.cbook as cbook +import matplotlib.patches as mpatches +import matplotlib.transforms as mtransforms + + +@_api.deprecated("3.7", alternative="Text.set_transform_rotates_text") +class ClabelText(Text): + """ + Unlike the ordinary text, the get_rotation returns an updated + angle in the pixel coordinate assuming that the input rotation is + an angle in data coordinate (or whatever transform set). + """ + + def get_rotation(self): + new_angle, = self.get_transform().transform_angles( + [super().get_rotation()], [self.get_position()]) + return new_angle + + +def _contour_labeler_event_handler(cs, inline, inline_spacing, event): + canvas = cs.axes.figure.canvas + is_button = event.name == "button_press_event" + is_key = event.name == "key_press_event" + # Quit (even if not in infinite mode; this is consistent with + # MATLAB and sometimes quite useful, but will require the user to + # test how many points were actually returned before using data). + if (is_button and event.button == MouseButton.MIDDLE + or is_key and event.key in ["escape", "enter"]): + canvas.stop_event_loop() + # Pop last click. + elif (is_button and event.button == MouseButton.RIGHT + or is_key and event.key in ["backspace", "delete"]): + # Unfortunately, if one is doing inline labels, then there is currently + # no way to fix the broken contour - once humpty-dumpty is broken, he + # can't be put back together. In inline mode, this does nothing. + if not inline: + cs.pop_label() + canvas.draw() + # Add new click. + elif (is_button and event.button == MouseButton.LEFT + # On macOS/gtk, some keys return None. + or is_key and event.key is not None): + if cs.axes.contains(event)[0]: + cs.add_label_near(event.x, event.y, transform=False, + inline=inline, inline_spacing=inline_spacing) + canvas.draw() + + +class ContourLabeler: + """Mixin to provide labelling capability to `.ContourSet`.""" + + def clabel(self, levels=None, *, + fontsize=None, inline=True, inline_spacing=5, fmt=None, + colors=None, use_clabeltext=False, manual=False, + rightside_up=True, zorder=None): + """ + Label a contour plot. + + Adds labels to line contours in this `.ContourSet` (which inherits from + this mixin class). + + Parameters + ---------- + levels : array-like, optional + A list of level values, that should be labeled. The list must be + a subset of ``cs.levels``. If not given, all levels are labeled. + + fontsize : str or float, default: :rc:`font.size` + Size in points or relative size e.g., 'smaller', 'x-large'. + See `.Text.set_size` for accepted string values. + + colors : color or colors or None, default: None + The label colors: + + - If *None*, the color of each label matches the color of + the corresponding contour. + + - If one string color, e.g., *colors* = 'r' or *colors* = + 'red', all labels will be plotted in this color. + + - If a tuple of colors (string, float, RGB, etc), different labels + will be plotted in different colors in the order specified. + + inline : bool, default: True + If ``True`` the underlying contour is removed where the label is + placed. + + inline_spacing : float, default: 5 + Space in pixels to leave on each side of label when placing inline. + + This spacing will be exact for labels at locations where the + contour is straight, less so for labels on curved contours. + + fmt : `.Formatter` or str or callable or dict, optional + How the levels are formatted: + + - If a `.Formatter`, it is used to format all levels at once, using + its `.Formatter.format_ticks` method. + - If a str, it is interpreted as a %-style format string. + - If a callable, it is called with one level at a time and should + return the corresponding label. + - If a dict, it should directly map levels to labels. + + The default is to use a standard `.ScalarFormatter`. + + manual : bool or iterable, default: False + If ``True``, contour labels will be placed manually using + mouse clicks. Click the first button near a contour to + add a label, click the second button (or potentially both + mouse buttons at once) to finish adding labels. The third + button can be used to remove the last label added, but + only if labels are not inline. Alternatively, the keyboard + can be used to select label locations (enter to end label + placement, delete or backspace act like the third mouse button, + and any other key will select a label location). + + *manual* can also be an iterable object of (x, y) tuples. + Contour labels will be created as if mouse is clicked at each + (x, y) position. + + rightside_up : bool, default: True + If ``True``, label rotations will always be plus + or minus 90 degrees from level. + + use_clabeltext : bool, default: False + If ``True``, use `.Text.set_transform_rotates_text` to ensure that + label rotation is updated whenever the axes aspect changes. + + zorder : float or None, default: ``(2 + contour.get_zorder())`` + zorder of the contour labels. + + Returns + ------- + labels + A list of `.Text` instances for the labels. + """ + + # clabel basically takes the input arguments and uses them to + # add a list of "label specific" attributes to the ContourSet + # object. These attributes are all of the form label* and names + # should be fairly self explanatory. + # + # Once these attributes are set, clabel passes control to the + # labels method (case of automatic label placement) or + # `BlockingContourLabeler` (case of manual label placement). + + if fmt is None: + fmt = ticker.ScalarFormatter(useOffset=False) + fmt.create_dummy_axis() + self.labelFmt = fmt + self._use_clabeltext = use_clabeltext + # Detect if manual selection is desired and remove from argument list. + self.labelManual = manual + self.rightside_up = rightside_up + self._clabel_zorder = 2 + self.get_zorder() if zorder is None else zorder + + if levels is None: + levels = self.levels + indices = list(range(len(self.cvalues))) + else: + levlabs = list(levels) + indices, levels = [], [] + for i, lev in enumerate(self.levels): + if lev in levlabs: + indices.append(i) + levels.append(lev) + if len(levels) < len(levlabs): + raise ValueError(f"Specified levels {levlabs} don't match " + f"available levels {self.levels}") + self.labelLevelList = levels + self.labelIndiceList = indices + + self._label_font_props = font_manager.FontProperties(size=fontsize) + + if colors is None: + self.labelMappable = self + self.labelCValueList = np.take(self.cvalues, self.labelIndiceList) + else: + cmap = mcolors.ListedColormap(colors, N=len(self.labelLevelList)) + self.labelCValueList = list(range(len(self.labelLevelList))) + self.labelMappable = cm.ScalarMappable(cmap=cmap, + norm=mcolors.NoNorm()) + + self.labelXYs = [] + + if np.iterable(manual): + for x, y in manual: + self.add_label_near(x, y, inline, inline_spacing) + elif manual: + print('Select label locations manually using first mouse button.') + print('End manual selection with second mouse button.') + if not inline: + print('Remove last label by clicking third mouse button.') + mpl._blocking_input.blocking_input_loop( + self.axes.figure, ["button_press_event", "key_press_event"], + timeout=-1, handler=functools.partial( + _contour_labeler_event_handler, + self, inline, inline_spacing)) + else: + self.labels(inline, inline_spacing) + + return cbook.silent_list('text.Text', self.labelTexts) + + @_api.deprecated("3.7", alternative="cs.labelTexts[0].get_font()") + @property + def labelFontProps(self): + return self._label_font_props + + @_api.deprecated("3.7", alternative=( + "[cs.labelTexts[0].get_font().get_size()] * len(cs.labelLevelList)")) + @property + def labelFontSizeList(self): + return [self._label_font_props.get_size()] * len(self.labelLevelList) + + @_api.deprecated("3.7", alternative="cs.labelTexts") + @property + def labelTextsList(self): + return cbook.silent_list('text.Text', self.labelTexts) + + def print_label(self, linecontour, labelwidth): + """Return whether a contour is long enough to hold a label.""" + return (len(linecontour) > 10 * labelwidth + or (len(linecontour) + and (np.ptp(linecontour, axis=0) > 1.2 * labelwidth).any())) + + def too_close(self, x, y, lw): + """Return whether a label is already near this location.""" + thresh = (1.2 * lw) ** 2 + return any((x - loc[0]) ** 2 + (y - loc[1]) ** 2 < thresh + for loc in self.labelXYs) + + def _get_nth_label_width(self, nth): + """Return the width of the *nth* label, in pixels.""" + fig = self.axes.figure + renderer = fig._get_renderer() + return (Text(0, 0, + self.get_text(self.labelLevelList[nth], self.labelFmt), + figure=fig, fontproperties=self._label_font_props) + .get_window_extent(renderer).width) + + @_api.deprecated("3.7", alternative="Artist.set") + def set_label_props(self, label, text, color): + """Set the label properties - color, fontsize, text.""" + label.set_text(text) + label.set_color(color) + label.set_fontproperties(self._label_font_props) + label.set_clip_box(self.axes.bbox) + + def get_text(self, lev, fmt): + """Get the text of the label.""" + if isinstance(lev, str): + return lev + elif isinstance(fmt, dict): + return fmt.get(lev, '%1.3f') + elif callable(getattr(fmt, "format_ticks", None)): + return fmt.format_ticks([*self.labelLevelList, lev])[-1] + elif callable(fmt): + return fmt(lev) + else: + return fmt % lev + + def locate_label(self, linecontour, labelwidth): + """ + Find good place to draw a label (relatively flat part of the contour). + """ + ctr_size = len(linecontour) + n_blocks = int(np.ceil(ctr_size / labelwidth)) if labelwidth > 1 else 1 + block_size = ctr_size if n_blocks == 1 else int(labelwidth) + # Split contour into blocks of length ``block_size``, filling the last + # block by cycling the contour start (per `np.resize` semantics). (Due + # to cycling, the index returned is taken modulo ctr_size.) + xx = np.resize(linecontour[:, 0], (n_blocks, block_size)) + yy = np.resize(linecontour[:, 1], (n_blocks, block_size)) + yfirst = yy[:, :1] + ylast = yy[:, -1:] + xfirst = xx[:, :1] + xlast = xx[:, -1:] + s = (yfirst - yy) * (xlast - xfirst) - (xfirst - xx) * (ylast - yfirst) + l = np.hypot(xlast - xfirst, ylast - yfirst) + # Ignore warning that divide by zero throws, as this is a valid option + with np.errstate(divide='ignore', invalid='ignore'): + distances = (abs(s) / l).sum(axis=-1) + # Labels are drawn in the middle of the block (``hbsize``) where the + # contour is the closest (per ``distances``) to a straight line, but + # not `too_close()` to a preexisting label. + hbsize = block_size // 2 + adist = np.argsort(distances) + # If all candidates are `too_close()`, go back to the straightest part + # (``adist[0]``). + for idx in np.append(adist, adist[0]): + x, y = xx[idx, hbsize], yy[idx, hbsize] + if not self.too_close(x, y, labelwidth): + break + return x, y, (idx * block_size + hbsize) % ctr_size + + def _split_path_and_get_label_rotation(self, path, idx, screen_pos, lw, spacing=5): + """ + Prepare for insertion of a label at index *idx* of *path*. + + Parameters + ---------- + path : Path + The path where the label will be inserted, in data space. + idx : int + The vertex index after which the label will be inserted. + screen_pos : (float, float) + The position where the label will be inserted, in screen space. + lw : float + The label width, in screen space. + spacing : float + Extra spacing around the label, in screen space. + + Returns + ------- + path : Path + The path, broken so that the label can be drawn over it. + angle : float + The rotation of the label. + + Notes + ----- + Both tasks are done together to avoid calculating path lengths multiple times, + which is relatively costly. + + The method used here involves computing the path length along the contour in + pixel coordinates and then looking (label width / 2) away from central point to + determine rotation and then to break contour if desired. The extra spacing is + taken into account when breaking the path, but not when computing the angle. + """ + if hasattr(self, "_old_style_split_collections"): + vis = False + for coll in self._old_style_split_collections: + vis |= coll.get_visible() + coll.remove() + self.set_visible(vis) + del self._old_style_split_collections # Invalidate them. + + xys = path.vertices + codes = path.codes + + # Insert a vertex at idx/pos (converting back to data space), if there isn't yet + # a vertex there. With infinite precision one could also always insert the + # extra vertex (it will get masked out by the label below anyways), but floating + # point inaccuracies (the point can have undergone a data->screen->data + # transform loop) can slightly shift the point and e.g. shift the angle computed + # below from exactly zero to nonzero. + pos = self.get_transform().inverted().transform(screen_pos) + if not np.allclose(pos, xys[idx]): + xys = np.insert(xys, idx, pos, axis=0) + codes = np.insert(codes, idx, Path.LINETO) + + # Find the connected component where the label will be inserted. Note that a + # path always starts with a MOVETO, and we consider there's an implicit + # MOVETO (closing the last path) at the end. + movetos = (codes == Path.MOVETO).nonzero()[0] + start = movetos[movetos <= idx][-1] + try: + stop = movetos[movetos > idx][0] + except IndexError: + stop = len(codes) + + # Restrict ourselves to the connected component. + cc_xys = xys[start:stop] + idx -= start + + # If the path is closed, rotate it s.t. it starts at the label. + is_closed_path = codes[stop - 1] == Path.CLOSEPOLY + if is_closed_path: + cc_xys = np.concatenate([cc_xys[idx:-1], cc_xys[:idx+1]]) + idx = 0 + + # Like np.interp, but additionally vectorized over fp. + def interp_vec(x, xp, fp): return [np.interp(x, xp, col) for col in fp.T] + + # Use cumulative path lengths ("cpl") as curvilinear coordinate along contour. + screen_xys = self.get_transform().transform(cc_xys) + path_cpls = np.insert( + np.cumsum(np.hypot(*np.diff(screen_xys, axis=0).T)), 0, 0) + path_cpls -= path_cpls[idx] + + # Use linear interpolation to get end coordinates of label. + target_cpls = np.array([-lw/2, lw/2]) + if is_closed_path: # For closed paths, target from the other end. + target_cpls[0] += (path_cpls[-1] - path_cpls[0]) + (sx0, sx1), (sy0, sy1) = interp_vec(target_cpls, path_cpls, screen_xys) + angle = np.rad2deg(np.arctan2(sy1 - sy0, sx1 - sx0)) # Screen space. + if self.rightside_up: # Fix angle so text is never upside-down + angle = (angle + 90) % 180 - 90 + + target_cpls += [-spacing, +spacing] # Expand range by spacing. + + # Get indices near points of interest; use -1 as out of bounds marker. + i0, i1 = np.interp(target_cpls, path_cpls, range(len(path_cpls)), + left=-1, right=-1) + i0 = math.floor(i0) + i1 = math.ceil(i1) + (x0, x1), (y0, y1) = interp_vec(target_cpls, path_cpls, cc_xys) + + # Actually break contours (dropping zero-len parts). + new_xy_blocks = [] + new_code_blocks = [] + if is_closed_path: + if i0 != -1 and i1 != -1: + # This is probably wrong in the case that the entire contour would + # be discarded, but ensures that a valid path is returned and is + # consistent with behavior of mpl <3.8 + points = cc_xys[i1:i0+1] + new_xy_blocks.extend([[(x1, y1)], points, [(x0, y0)]]) + nlines = len(points) + 1 + new_code_blocks.extend([[Path.MOVETO], [Path.LINETO] * nlines]) + else: + if i0 != -1: + new_xy_blocks.extend([cc_xys[:i0 + 1], [(x0, y0)]]) + new_code_blocks.extend([[Path.MOVETO], [Path.LINETO] * (i0 + 1)]) + if i1 != -1: + new_xy_blocks.extend([[(x1, y1)], cc_xys[i1:]]) + new_code_blocks.extend([ + [Path.MOVETO], [Path.LINETO] * (len(cc_xys) - i1)]) + + # Back to the full path. + xys = np.concatenate([xys[:start], *new_xy_blocks, xys[stop:]]) + codes = np.concatenate([codes[:start], *new_code_blocks, codes[stop:]]) + + return angle, Path(xys, codes) + + @_api.deprecated("3.8") + def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5): + """ + Calculate the appropriate label rotation given the linecontour + coordinates in screen units, the index of the label location and the + label width. + + If *lc* is not None or empty, also break contours and compute + inlining. + + *spacing* is the empty space to leave around the label, in pixels. + + Both tasks are done together to avoid calculating path lengths + multiple times, which is relatively costly. + + The method used here involves computing the path length along the + contour in pixel coordinates and then looking approximately (label + width / 2) away from central point to determine rotation and then to + break contour if desired. + """ + + if lc is None: + lc = [] + # Half the label width + hlw = lw / 2.0 + + # Check if closed and, if so, rotate contour so label is at edge + closed = _is_closed_polygon(slc) + if closed: + slc = np.concatenate([slc[ind:-1], slc[:ind + 1]]) + if len(lc): # Rotate lc also if not empty + lc = np.concatenate([lc[ind:-1], lc[:ind + 1]]) + ind = 0 + + # Calculate path lengths + pl = np.zeros(slc.shape[0], dtype=float) + dx = np.diff(slc, axis=0) + pl[1:] = np.cumsum(np.hypot(dx[:, 0], dx[:, 1])) + pl = pl - pl[ind] + + # Use linear interpolation to get points around label + xi = np.array([-hlw, hlw]) + if closed: # Look at end also for closed contours + dp = np.array([pl[-1], 0]) + else: + dp = np.zeros_like(xi) + + # Get angle of vector between the two ends of the label - must be + # calculated in pixel space for text rotation to work correctly. + (dx,), (dy,) = (np.diff(np.interp(dp + xi, pl, slc_col)) + for slc_col in slc.T) + rotation = np.rad2deg(np.arctan2(dy, dx)) + + if self.rightside_up: + # Fix angle so text is never upside-down + rotation = (rotation + 90) % 180 - 90 + + # Break contour if desired + nlc = [] + if len(lc): + # Expand range by spacing + xi = dp + xi + np.array([-spacing, spacing]) + + # Get (integer) indices near points of interest; use -1 as marker + # for out of bounds. + I = np.interp(xi, pl, np.arange(len(pl)), left=-1, right=-1) + I = [np.floor(I[0]).astype(int), np.ceil(I[1]).astype(int)] + if I[0] != -1: + xy1 = [np.interp(xi[0], pl, lc_col) for lc_col in lc.T] + if I[1] != -1: + xy2 = [np.interp(xi[1], pl, lc_col) for lc_col in lc.T] + + # Actually break contours + if closed: + # This will remove contour if shorter than label + if all(i != -1 for i in I): + nlc.append(np.vstack([xy2, lc[I[1]:I[0]+1], xy1])) + else: + # These will remove pieces of contour if they have length zero + if I[0] != -1: + nlc.append(np.vstack([lc[:I[0]+1], xy1])) + if I[1] != -1: + nlc.append(np.vstack([xy2, lc[I[1]:]])) + + # The current implementation removes contours completely + # covered by labels. Uncomment line below to keep + # original contour if this is the preferred behavior. + # if not len(nlc): nlc = [lc] + + return rotation, nlc + + def add_label(self, x, y, rotation, lev, cvalue): + """Add contour label without `.Text.set_transform_rotates_text`.""" + data_x, data_y = self.axes.transData.inverted().transform((x, y)) + t = Text( + data_x, data_y, + text=self.get_text(lev, self.labelFmt), + rotation=rotation, + horizontalalignment='center', verticalalignment='center', + zorder=self._clabel_zorder, + color=self.labelMappable.to_rgba(cvalue, alpha=self.get_alpha()), + fontproperties=self._label_font_props, + clip_box=self.axes.bbox) + self.labelTexts.append(t) + self.labelCValues.append(cvalue) + self.labelXYs.append((x, y)) + # Add label to plot here - useful for manual mode label selection + self.axes.add_artist(t) + + def add_label_clabeltext(self, x, y, rotation, lev, cvalue): + """Add contour label with `.Text.set_transform_rotates_text`.""" + self.add_label(x, y, rotation, lev, cvalue) + # Grab the last added text, and reconfigure its rotation. + t = self.labelTexts[-1] + data_rotation, = self.axes.transData.inverted().transform_angles( + [rotation], [[x, y]]) + t.set(rotation=data_rotation, transform_rotates_text=True) + + def add_label_near(self, x, y, inline=True, inline_spacing=5, + transform=None): + """ + Add a label near the point ``(x, y)``. + + Parameters + ---------- + x, y : float + The approximate location of the label. + inline : bool, default: True + If *True* remove the segment of the contour beneath the label. + inline_spacing : int, default: 5 + Space in pixels to leave on each side of label when placing + inline. This spacing will be exact for labels at locations where + the contour is straight, less so for labels on curved contours. + transform : `.Transform` or `False`, default: ``self.axes.transData`` + A transform applied to ``(x, y)`` before labeling. The default + causes ``(x, y)`` to be interpreted as data coordinates. `False` + is a synonym for `.IdentityTransform`; i.e. ``(x, y)`` should be + interpreted as display coordinates. + """ + + if transform is None: + transform = self.axes.transData + if transform: + x, y = transform.transform((x, y)) + + idx_level_min, idx_vtx_min, proj = self._find_nearest_contour( + (x, y), self.labelIndiceList) + path = self._paths[idx_level_min] + level = self.labelIndiceList.index(idx_level_min) + label_width = self._get_nth_label_width(level) + rotation, path = self._split_path_and_get_label_rotation( + path, idx_vtx_min, proj, label_width, inline_spacing) + self.add_label(*proj, rotation, self.labelLevelList[idx_level_min], + self.labelCValueList[idx_level_min]) + + if inline: + self._paths[idx_level_min] = path + + def pop_label(self, index=-1): + """Defaults to removing last label, but any index can be supplied""" + self.labelCValues.pop(index) + t = self.labelTexts.pop(index) + t.remove() + + def labels(self, inline, inline_spacing): + + if self._use_clabeltext: + add_label = self.add_label_clabeltext + else: + add_label = self.add_label + + for idx, (icon, lev, cvalue) in enumerate(zip( + self.labelIndiceList, + self.labelLevelList, + self.labelCValueList, + )): + trans = self.get_transform() + label_width = self._get_nth_label_width(idx) + additions = [] + for subpath in self._paths[icon]._iter_connected_components(): + screen_xys = trans.transform(subpath.vertices) + # Check if long enough for a label + if self.print_label(screen_xys, label_width): + x, y, idx = self.locate_label(screen_xys, label_width) + rotation, path = self._split_path_and_get_label_rotation( + subpath, idx, (x, y), + label_width, inline_spacing) + add_label(x, y, rotation, lev, cvalue) # Really add label. + if inline: # If inline, add new contours + additions.append(path) + else: # If not adding label, keep old path + additions.append(subpath) + # After looping over all segments on a contour, replace old path by new one + # if inlining. + if inline: + self._paths[icon] = Path.make_compound_path(*additions) + + def remove(self): + super().remove() + for text in self.labelTexts: + text.remove() + + +def _is_closed_polygon(X): + """ + Return whether first and last object in a sequence are the same. These are + presumably coordinates on a polygonal curve, in which case this function + tests if that curve is closed. + """ + return np.allclose(X[0], X[-1], rtol=1e-10, atol=1e-13) + + +def _find_closest_point_on_path(xys, p): + """ + Parameters + ---------- + xys : (N, 2) array-like + Coordinates of vertices. + p : (float, float) + Coordinates of point. + + Returns + ------- + d2min : float + Minimum square distance of *p* to *xys*. + proj : (float, float) + Projection of *p* onto *xys*. + imin : (int, int) + Consecutive indices of vertices of segment in *xys* where *proj* is. + Segments are considered as including their end-points; i.e. if the + closest point on the path is a node in *xys* with index *i*, this + returns ``(i-1, i)``. For the special case where *xys* is a single + point, this returns ``(0, 0)``. + """ + if len(xys) == 1: + return (((p - xys[0]) ** 2).sum(), xys[0], (0, 0)) + dxys = xys[1:] - xys[:-1] # Individual segment vectors. + norms = (dxys ** 2).sum(axis=1) + norms[norms == 0] = 1 # For zero-length segment, replace 0/0 by 0/1. + rel_projs = np.clip( # Project onto each segment in relative 0-1 coords. + ((p - xys[:-1]) * dxys).sum(axis=1) / norms, + 0, 1)[:, None] + projs = xys[:-1] + rel_projs * dxys # Projs. onto each segment, in (x, y). + d2s = ((projs - p) ** 2).sum(axis=1) # Squared distances. + imin = np.argmin(d2s) + return (d2s[imin], projs[imin], (imin, imin+1)) + + +_docstring.interpd.update(contour_set_attributes=r""" +Attributes +---------- +ax : `~matplotlib.axes.Axes` + The Axes object in which the contours are drawn. + +collections : `.silent_list` of `.PathCollection`\s + The `.Artist`\s representing the contour. This is a list of + `.PathCollection`\s for both line and filled contours. + +levels : array + The values of the contour levels. + +layers : array + Same as levels for line contours; half-way between + levels for filled contours. See ``ContourSet._process_colors``. +""") + + +@_docstring.dedent_interpd +class ContourSet(ContourLabeler, mcoll.Collection): + """ + Store a set of contour lines or filled regions. + + User-callable method: `~.Axes.clabel` + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + + levels : [level0, level1, ..., leveln] + A list of floating point numbers indicating the contour levels. + + allsegs : [level0segs, level1segs, ...] + List of all the polygon segments for all the *levels*. + For contour lines ``len(allsegs) == len(levels)``, and for + filled contour regions ``len(allsegs) = len(levels)-1``. The lists + should look like :: + + level0segs = [polygon0, polygon1, ...] + polygon0 = [[x0, y0], [x1, y1], ...] + + allkinds : ``None`` or [level0kinds, level1kinds, ...] + Optional list of all the polygon vertex kinds (code types), as + described and used in Path. This is used to allow multiply- + connected paths such as holes within filled polygons. + If not ``None``, ``len(allkinds) == len(allsegs)``. The lists + should look like :: + + level0kinds = [polygon0kinds, ...] + polygon0kinds = [vertexcode0, vertexcode1, ...] + + If *allkinds* is not ``None``, usually all polygons for a + particular contour level are grouped together so that + ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``. + + **kwargs + Keyword arguments are as described in the docstring of + `~.Axes.contour`. + + %(contour_set_attributes)s + """ + + def __init__(self, ax, *args, + levels=None, filled=False, linewidths=None, linestyles=None, + hatches=(None,), alpha=None, origin=None, extent=None, + cmap=None, colors=None, norm=None, vmin=None, vmax=None, + extend='neither', antialiased=None, nchunk=0, locator=None, + transform=None, negative_linestyles=None, clip_path=None, + **kwargs): + """ + Draw contour lines or filled regions, depending on + whether keyword arg *filled* is ``False`` (default) or ``True``. + + Call signature:: + + ContourSet(ax, levels, allsegs, [allkinds], **kwargs) + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` object to draw on. + + levels : [level0, level1, ..., leveln] + A list of floating point numbers indicating the contour + levels. + + allsegs : [level0segs, level1segs, ...] + List of all the polygon segments for all the *levels*. + For contour lines ``len(allsegs) == len(levels)``, and for + filled contour regions ``len(allsegs) = len(levels)-1``. The lists + should look like :: + + level0segs = [polygon0, polygon1, ...] + polygon0 = [[x0, y0], [x1, y1], ...] + + allkinds : [level0kinds, level1kinds, ...], optional + Optional list of all the polygon vertex kinds (code types), as + described and used in Path. This is used to allow multiply- + connected paths such as holes within filled polygons. + If not ``None``, ``len(allkinds) == len(allsegs)``. The lists + should look like :: + + level0kinds = [polygon0kinds, ...] + polygon0kinds = [vertexcode0, vertexcode1, ...] + + If *allkinds* is not ``None``, usually all polygons for a + particular contour level are grouped together so that + ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``. + + **kwargs + Keyword arguments are as described in the docstring of + `~.Axes.contour`. + """ + if antialiased is None and filled: + # Eliminate artifacts; we are not stroking the boundaries. + antialiased = False + # The default for line contours will be taken from the + # LineCollection default, which uses :rc:`lines.antialiased`. + super().__init__( + antialiaseds=antialiased, + alpha=alpha, + clip_path=clip_path, + transform=transform, + ) + self.axes = ax + self.levels = levels + self.filled = filled + self.hatches = hatches + self.origin = origin + self.extent = extent + self.colors = colors + self.extend = extend + + self.nchunk = nchunk + self.locator = locator + if (isinstance(norm, mcolors.LogNorm) + or isinstance(self.locator, ticker.LogLocator)): + self.logscale = True + if norm is None: + norm = mcolors.LogNorm() + else: + self.logscale = False + + _api.check_in_list([None, 'lower', 'upper', 'image'], origin=origin) + if self.extent is not None and len(self.extent) != 4: + raise ValueError( + "If given, 'extent' must be None or (x0, x1, y0, y1)") + if self.colors is not None and cmap is not None: + raise ValueError('Either colors or cmap must be None') + if self.origin == 'image': + self.origin = mpl.rcParams['image.origin'] + + self._orig_linestyles = linestyles # Only kept for user access. + self.negative_linestyles = negative_linestyles + # If negative_linestyles was not defined as a keyword argument, define + # negative_linestyles with rcParams + if self.negative_linestyles is None: + self.negative_linestyles = \ + mpl.rcParams['contour.negative_linestyle'] + + kwargs = self._process_args(*args, **kwargs) + self._process_levels() + + self._extend_min = self.extend in ['min', 'both'] + self._extend_max = self.extend in ['max', 'both'] + if self.colors is not None: + ncolors = len(self.levels) + if self.filled: + ncolors -= 1 + i0 = 0 + + # Handle the case where colors are given for the extended + # parts of the contour. + + use_set_under_over = False + # if we are extending the lower end, and we've been given enough + # colors then skip the first color in the resulting cmap. For the + # extend_max case we don't need to worry about passing more colors + # than ncolors as ListedColormap will clip. + total_levels = (ncolors + + int(self._extend_min) + + int(self._extend_max)) + if (len(self.colors) == total_levels and + (self._extend_min or self._extend_max)): + use_set_under_over = True + if self._extend_min: + i0 = 1 + + cmap = mcolors.ListedColormap(self.colors[i0:None], N=ncolors) + + if use_set_under_over: + if self._extend_min: + cmap.set_under(self.colors[0]) + if self._extend_max: + cmap.set_over(self.colors[-1]) + + # label lists must be initialized here + self.labelTexts = [] + self.labelCValues = [] + + self.set_cmap(cmap) + if norm is not None: + self.set_norm(norm) + with self.norm.callbacks.blocked(signal="changed"): + if vmin is not None: + self.norm.vmin = vmin + if vmax is not None: + self.norm.vmax = vmax + self.norm._changed() + self._process_colors() + + if self._paths is None: + self._paths = self._make_paths_from_contour_generator() + + if self.filled: + if linewidths is not None: + _api.warn_external('linewidths is ignored by contourf') + # Lower and upper contour levels. + lowers, uppers = self._get_lowers_and_uppers() + self.set( + edgecolor="none", + # Default zorder taken from Collection + zorder=kwargs.pop("zorder", 1), + ) + + else: + self.set( + facecolor="none", + linewidths=self._process_linewidths(linewidths), + linestyle=self._process_linestyles(linestyles), + # Default zorder taken from LineCollection, which is higher + # than for filled contours so that lines are displayed on top. + zorder=kwargs.pop("zorder", 2), + label="_nolegend_", + ) + + self.axes.add_collection(self, autolim=False) + self.sticky_edges.x[:] = [self._mins[0], self._maxs[0]] + self.sticky_edges.y[:] = [self._mins[1], self._maxs[1]] + self.axes.update_datalim([self._mins, self._maxs]) + self.axes.autoscale_view(tight=True) + + self.changed() # set the colors + + if kwargs: + _api.warn_external( + 'The following kwargs were not used by contour: ' + + ", ".join(map(repr, kwargs)) + ) + + allsegs = property(lambda self: [ + [subp.vertices for subp in p._iter_connected_components()] + for p in self.get_paths()]) + allkinds = property(lambda self: [ + [subp.codes for subp in p._iter_connected_components()] + for p in self.get_paths()]) + tcolors = _api.deprecated("3.8")(property(lambda self: [ + (tuple(rgba),) for rgba in self.to_rgba(self.cvalues, self.alpha)])) + tlinewidths = _api.deprecated("3.8")(property(lambda self: [ + (w,) for w in self.get_linewidths()])) + alpha = property(lambda self: self.get_alpha()) + linestyles = property(lambda self: self._orig_linestyles) + + @_api.deprecated("3.8", alternative="set_antialiased or get_antialiased", + addendum="Note that get_antialiased returns an array.") + @property + def antialiased(self): + return all(self.get_antialiased()) + + @antialiased.setter + def antialiased(self, aa): + self.set_antialiased(aa) + + @_api.deprecated("3.8") + @property + def collections(self): + # On access, make oneself invisible and instead add the old-style collections + # (one PathCollection per level). We do not try to further split contours into + # connected components as we already lost track of what pairs of contours need + # to be considered as single units to draw filled regions with holes. + if not hasattr(self, "_old_style_split_collections"): + self.set_visible(False) + fcs = self.get_facecolor() + ecs = self.get_edgecolor() + lws = self.get_linewidth() + lss = self.get_linestyle() + self._old_style_split_collections = [] + for idx, path in enumerate(self._paths): + pc = mcoll.PathCollection( + [path] if len(path.vertices) else [], + alpha=self.get_alpha(), + antialiaseds=self._antialiaseds[idx % len(self._antialiaseds)], + transform=self.get_transform(), + zorder=self.get_zorder(), + label="_nolegend_", + facecolor=fcs[idx] if len(fcs) else "none", + edgecolor=ecs[idx] if len(ecs) else "none", + linewidths=[lws[idx % len(lws)]], + linestyles=[lss[idx % len(lss)]], + ) + if self.filled: + pc.set(hatch=self.hatches[idx % len(self.hatches)]) + self._old_style_split_collections.append(pc) + for col in self._old_style_split_collections: + self.axes.add_collection(col) + return self._old_style_split_collections + + def get_transform(self): + """Return the `.Transform` instance used by this ContourSet.""" + if self._transform is None: + self._transform = self.axes.transData + elif (not isinstance(self._transform, mtransforms.Transform) + and hasattr(self._transform, '_as_mpl_transform')): + self._transform = self._transform._as_mpl_transform(self.axes) + return self._transform + + def __getstate__(self): + state = self.__dict__.copy() + # the C object _contour_generator cannot currently be pickled. This + # isn't a big issue as it is not actually used once the contour has + # been calculated. + state['_contour_generator'] = None + return state + + def legend_elements(self, variable_name='x', str_format=str): + """ + Return a list of artists and labels suitable for passing through + to `~.Axes.legend` which represent this ContourSet. + + The labels have the form "0 < x <= 1" stating the data ranges which + the artists represent. + + Parameters + ---------- + variable_name : str + The string used inside the inequality used on the labels. + str_format : function: float -> str + Function used to format the numbers in the labels. + + Returns + ------- + artists : list[`.Artist`] + A list of the artists. + labels : list[str] + A list of the labels. + """ + artists = [] + labels = [] + + if self.filled: + lowers, uppers = self._get_lowers_and_uppers() + n_levels = len(self._paths) + for idx in range(n_levels): + artists.append(mpatches.Rectangle( + (0, 0), 1, 1, + facecolor=self.get_facecolor()[idx], + hatch=self.hatches[idx % len(self.hatches)], + )) + lower = str_format(lowers[idx]) + upper = str_format(uppers[idx]) + if idx == 0 and self.extend in ('min', 'both'): + labels.append(fr'${variable_name} \leq {lower}s$') + elif idx == n_levels - 1 and self.extend in ('max', 'both'): + labels.append(fr'${variable_name} > {upper}s$') + else: + labels.append(fr'${lower} < {variable_name} \leq {upper}$') + else: + for idx, level in enumerate(self.levels): + artists.append(Line2D( + [], [], + color=self.get_edgecolor()[idx], + linewidth=self.get_linewidths()[idx], + linestyle=self.get_linestyles()[idx], + )) + labels.append(fr'${variable_name} = {str_format(level)}$') + + return artists, labels + + def _process_args(self, *args, **kwargs): + """ + Process *args* and *kwargs*; override in derived classes. + + Must set self.levels, self.zmin and self.zmax, and update axes limits. + """ + self.levels = args[0] + allsegs = args[1] + allkinds = args[2] if len(args) > 2 else None + self.zmax = np.max(self.levels) + self.zmin = np.min(self.levels) + + if allkinds is None: + allkinds = [[None] * len(segs) for segs in allsegs] + + # Check lengths of levels and allsegs. + if self.filled: + if len(allsegs) != len(self.levels) - 1: + raise ValueError('must be one less number of segments as ' + 'levels') + else: + if len(allsegs) != len(self.levels): + raise ValueError('must be same number of segments as levels') + + # Check length of allkinds. + if len(allkinds) != len(allsegs): + raise ValueError('allkinds has different length to allsegs') + + # Determine x, y bounds and update axes data limits. + flatseglist = [s for seg in allsegs for s in seg] + points = np.concatenate(flatseglist, axis=0) + self._mins = points.min(axis=0) + self._maxs = points.max(axis=0) + + # Each entry in (allsegs, allkinds) is a list of (segs, kinds): segs is a list + # of (N, 2) arrays of xy coordinates, kinds is a list of arrays of corresponding + # pathcodes. However, kinds can also be None; in which case all paths in that + # list are codeless (this case is normalized above). These lists are used to + # construct paths, which then get concatenated. + self._paths = [Path.make_compound_path(*map(Path, segs, kinds)) + for segs, kinds in zip(allsegs, allkinds)] + + return kwargs + + def _make_paths_from_contour_generator(self): + """Compute ``paths`` using C extension.""" + if self._paths is not None: + return self._paths + paths = [] + empty_path = Path(np.empty((0, 2))) + if self.filled: + lowers, uppers = self._get_lowers_and_uppers() + for level, level_upper in zip(lowers, uppers): + vertices, kinds = \ + self._contour_generator.create_filled_contour( + level, level_upper) + paths.append(Path(np.concatenate(vertices), np.concatenate(kinds)) + if len(vertices) else empty_path) + else: + for level in self.levels: + vertices, kinds = self._contour_generator.create_contour(level) + paths.append(Path(np.concatenate(vertices), np.concatenate(kinds)) + if len(vertices) else empty_path) + return paths + + def _get_lowers_and_uppers(self): + """ + Return ``(lowers, uppers)`` for filled contours. + """ + lowers = self._levels[:-1] + if self.zmin == lowers[0]: + # Include minimum values in lowest interval + lowers = lowers.copy() # so we don't change self._levels + if self.logscale: + lowers[0] = 0.99 * self.zmin + else: + lowers[0] -= 1 + uppers = self._levels[1:] + return (lowers, uppers) + + def changed(self): + if not hasattr(self, "cvalues"): + self._process_colors() # Sets cvalues. + # Force an autoscale immediately because self.to_rgba() calls + # autoscale_None() internally with the data passed to it, + # so if vmin/vmax are not set yet, this would override them with + # content from *cvalues* rather than levels like we want + self.norm.autoscale_None(self.levels) + self.set_array(self.cvalues) + self.update_scalarmappable() + alphas = np.broadcast_to(self.get_alpha(), len(self.cvalues)) + for label, cv, alpha in zip(self.labelTexts, self.labelCValues, alphas): + label.set_alpha(alpha) + label.set_color(self.labelMappable.to_rgba(cv)) + super().changed() + + def _autolev(self, N): + """ + Select contour levels to span the data. + + The target number of levels, *N*, is used only when the + scale is not log and default locator is used. + + We need two more levels for filled contours than for + line contours, because for the latter we need to specify + the lower and upper boundary of each range. For example, + a single contour boundary, say at z = 0, requires only + one contour line, but two filled regions, and therefore + three levels to provide boundaries for both regions. + """ + if self.locator is None: + if self.logscale: + self.locator = ticker.LogLocator() + else: + self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1) + + lev = self.locator.tick_values(self.zmin, self.zmax) + + try: + if self.locator._symmetric: + return lev + except AttributeError: + pass + + # Trim excess levels the locator may have supplied. + under = np.nonzero(lev < self.zmin)[0] + i0 = under[-1] if len(under) else 0 + over = np.nonzero(lev > self.zmax)[0] + i1 = over[0] + 1 if len(over) else len(lev) + if self.extend in ('min', 'both'): + i0 += 1 + if self.extend in ('max', 'both'): + i1 -= 1 + + if i1 - i0 < 3: + i0, i1 = 0, len(lev) + + return lev[i0:i1] + + def _process_contour_level_args(self, args, z_dtype): + """ + Determine the contour levels and store in self.levels. + """ + if self.levels is None: + if args: + levels_arg = args[0] + elif np.issubdtype(z_dtype, bool): + if self.filled: + levels_arg = [0, .5, 1] + else: + levels_arg = [.5] + else: + levels_arg = 7 # Default, hard-wired. + else: + levels_arg = self.levels + if isinstance(levels_arg, Integral): + self.levels = self._autolev(levels_arg) + else: + self.levels = np.asarray(levels_arg, np.float64) + if self.filled and len(self.levels) < 2: + raise ValueError("Filled contours require at least 2 levels.") + if len(self.levels) > 1 and np.min(np.diff(self.levels)) <= 0.0: + raise ValueError("Contour levels must be increasing") + + def _process_levels(self): + """ + Assign values to :attr:`layers` based on :attr:`levels`, + adding extended layers as needed if contours are filled. + + For line contours, layers simply coincide with levels; + a line is a thin layer. No extended levels are needed + with line contours. + """ + # Make a private _levels to include extended regions; we + # want to leave the original levels attribute unchanged. + # (Colorbar needs this even for line contours.) + self._levels = list(self.levels) + + if self.logscale: + lower, upper = 1e-250, 1e250 + else: + lower, upper = -1e250, 1e250 + + if self.extend in ('both', 'min'): + self._levels.insert(0, lower) + if self.extend in ('both', 'max'): + self._levels.append(upper) + self._levels = np.asarray(self._levels) + + if not self.filled: + self.layers = self.levels + return + + # Layer values are mid-way between levels in screen space. + if self.logscale: + # Avoid overflow by taking sqrt before multiplying. + self.layers = (np.sqrt(self._levels[:-1]) + * np.sqrt(self._levels[1:])) + else: + self.layers = 0.5 * (self._levels[:-1] + self._levels[1:]) + + def _process_colors(self): + """ + Color argument processing for contouring. + + Note that we base the colormapping on the contour levels + and layers, not on the actual range of the Z values. This + means we don't have to worry about bad values in Z, and we + always have the full dynamic range available for the selected + levels. + + The color is based on the midpoint of the layer, except for + extended end layers. By default, the norm vmin and vmax + are the extreme values of the non-extended levels. Hence, + the layer color extremes are not the extreme values of + the colormap itself, but approach those values as the number + of levels increases. An advantage of this scheme is that + line contours, when added to filled contours, take on + colors that are consistent with those of the filled regions; + for example, a contour line on the boundary between two + regions will have a color intermediate between those + of the regions. + + """ + self.monochrome = self.cmap.monochrome + if self.colors is not None: + # Generate integers for direct indexing. + i0, i1 = 0, len(self.levels) + if self.filled: + i1 -= 1 + # Out of range indices for over and under: + if self.extend in ('both', 'min'): + i0 -= 1 + if self.extend in ('both', 'max'): + i1 += 1 + self.cvalues = list(range(i0, i1)) + self.set_norm(mcolors.NoNorm()) + else: + self.cvalues = self.layers + self.norm.autoscale_None(self.levels) + self.set_array(self.cvalues) + self.update_scalarmappable() + if self.extend in ('both', 'max', 'min'): + self.norm.clip = False + + def _process_linewidths(self, linewidths): + Nlev = len(self.levels) + if linewidths is None: + default_linewidth = mpl.rcParams['contour.linewidth'] + if default_linewidth is None: + default_linewidth = mpl.rcParams['lines.linewidth'] + return [default_linewidth] * Nlev + elif not np.iterable(linewidths): + return [linewidths] * Nlev + else: + linewidths = list(linewidths) + return (linewidths * math.ceil(Nlev / len(linewidths)))[:Nlev] + + def _process_linestyles(self, linestyles): + Nlev = len(self.levels) + if linestyles is None: + tlinestyles = ['solid'] * Nlev + if self.monochrome: + eps = - (self.zmax - self.zmin) * 1e-15 + for i, lev in enumerate(self.levels): + if lev < eps: + tlinestyles[i] = self.negative_linestyles + else: + if isinstance(linestyles, str): + tlinestyles = [linestyles] * Nlev + elif np.iterable(linestyles): + tlinestyles = list(linestyles) + if len(tlinestyles) < Nlev: + nreps = int(np.ceil(Nlev / len(linestyles))) + tlinestyles = tlinestyles * nreps + if len(tlinestyles) > Nlev: + tlinestyles = tlinestyles[:Nlev] + else: + raise ValueError("Unrecognized type for linestyles kwarg") + return tlinestyles + + def _find_nearest_contour(self, xy, indices=None): + """ + Find the point in the unfilled contour plot that is closest (in screen + space) to point *xy*. + + Parameters + ---------- + xy : tuple[float, float] + The reference point (in screen space). + indices : list of int or None, default: None + Indices of contour levels to consider. If None (the default), all levels + are considered. + + Returns + ------- + idx_level_min : int + The index of the contour level closest to *xy*. + idx_vtx_min : int + The index of the `.Path` segment closest to *xy* (at that level). + proj : (float, float) + The point in the contour plot closest to *xy*. + """ + + # Convert each contour segment to pixel coordinates and then compare the given + # point to those coordinates for each contour. This is fast enough in normal + # cases, but speedups may be possible. + + if self.filled: + raise ValueError("Method does not support filled contours") + + if indices is None: + indices = range(len(self._paths)) + + d2min = np.inf + idx_level_min = idx_vtx_min = proj_min = None + + for idx_level in indices: + path = self._paths[idx_level] + idx_vtx_start = 0 + for subpath in path._iter_connected_components(): + if not len(subpath.vertices): + continue + lc = self.get_transform().transform(subpath.vertices) + d2, proj, leg = _find_closest_point_on_path(lc, xy) + if d2 < d2min: + d2min = d2 + idx_level_min = idx_level + idx_vtx_min = leg[1] + idx_vtx_start + proj_min = proj + idx_vtx_start += len(subpath) + + return idx_level_min, idx_vtx_min, proj_min + + def find_nearest_contour(self, x, y, indices=None, pixel=True): + """ + Find the point in the contour plot that is closest to ``(x, y)``. + + This method does not support filled contours. + + Parameters + ---------- + x, y : float + The reference point. + indices : list of int or None, default: None + Indices of contour levels to consider. If None (the default), all + levels are considered. + pixel : bool, default: True + If *True*, measure distance in pixel (screen) space, which is + useful for manual contour labeling; else, measure distance in axes + space. + + Returns + ------- + path : int + The index of the path that is closest to ``(x, y)``. Each path corresponds + to one contour level. + subpath : int + The index within that closest path of the subpath that is closest to + ``(x, y)``. Each subpath corresponds to one unbroken contour line. + index : int + The index of the vertices within that subpath that are closest to + ``(x, y)``. + xmin, ymin : float + The point in the contour plot that is closest to ``(x, y)``. + d2 : float + The squared distance from ``(xmin, ymin)`` to ``(x, y)``. + """ + segment = index = d2 = None + + with ExitStack() as stack: + if not pixel: + # _find_nearest_contour works in pixel space. We want axes space, so + # effectively disable the transformation here by setting to identity. + stack.enter_context(self._cm_set( + transform=mtransforms.IdentityTransform())) + + i_level, i_vtx, (xmin, ymin) = self._find_nearest_contour((x, y), indices) + + if i_level is not None: + cc_cumlens = np.cumsum( + [*map(len, self._paths[i_level]._iter_connected_components())]) + segment = cc_cumlens.searchsorted(i_vtx, "right") + index = i_vtx if segment == 0 else i_vtx - cc_cumlens[segment - 1] + d2 = (xmin-x)**2 + (ymin-y)**2 + + return (i_level, segment, index, xmin, ymin, d2) + + def draw(self, renderer): + paths = self._paths + n_paths = len(paths) + if not self.filled or all(hatch is None for hatch in self.hatches): + super().draw(renderer) + return + # In presence of hatching, draw contours one at a time. + for idx in range(n_paths): + with cbook._setattr_cm(self, _paths=[paths[idx]]), self._cm_set( + hatch=self.hatches[idx % len(self.hatches)], + array=[self.get_array()[idx]], + linewidths=[self.get_linewidths()[idx % len(self.get_linewidths())]], + linestyles=[self.get_linestyles()[idx % len(self.get_linestyles())]], + ): + super().draw(renderer) + + +@_docstring.dedent_interpd +class QuadContourSet(ContourSet): + """ + Create and store a set of contour lines or filled regions. + + This class is typically not instantiated directly by the user but by + `~.Axes.contour` and `~.Axes.contourf`. + + %(contour_set_attributes)s + """ + + def _process_args(self, *args, corner_mask=None, algorithm=None, **kwargs): + """ + Process args and kwargs. + """ + if args and isinstance(args[0], QuadContourSet): + if self.levels is None: + self.levels = args[0].levels + self.zmin = args[0].zmin + self.zmax = args[0].zmax + self._corner_mask = args[0]._corner_mask + contour_generator = args[0]._contour_generator + self._mins = args[0]._mins + self._maxs = args[0]._maxs + self._algorithm = args[0]._algorithm + else: + import contourpy + + if algorithm is None: + algorithm = mpl.rcParams['contour.algorithm'] + mpl.rcParams.validate["contour.algorithm"](algorithm) + self._algorithm = algorithm + + if corner_mask is None: + if self._algorithm == "mpl2005": + # mpl2005 does not support corner_mask=True so if not + # specifically requested then disable it. + corner_mask = False + else: + corner_mask = mpl.rcParams['contour.corner_mask'] + self._corner_mask = corner_mask + + x, y, z = self._contour_args(args, kwargs) + + contour_generator = contourpy.contour_generator( + x, y, z, name=self._algorithm, corner_mask=self._corner_mask, + line_type=contourpy.LineType.SeparateCode, + fill_type=contourpy.FillType.OuterCode, + chunk_size=self.nchunk) + + t = self.get_transform() + + # if the transform is not trans data, and some part of it + # contains transData, transform the xs and ys to data coordinates + if (t != self.axes.transData and + any(t.contains_branch_seperately(self.axes.transData))): + trans_to_data = t - self.axes.transData + pts = np.vstack([x.flat, y.flat]).T + transformed_pts = trans_to_data.transform(pts) + x = transformed_pts[..., 0] + y = transformed_pts[..., 1] + + self._mins = [ma.min(x), ma.min(y)] + self._maxs = [ma.max(x), ma.max(y)] + + self._contour_generator = contour_generator + + return kwargs + + def _contour_args(self, args, kwargs): + if self.filled: + fn = 'contourf' + else: + fn = 'contour' + nargs = len(args) + + if 0 < nargs <= 2: + z, *args = args + z = ma.asarray(z) + x, y = self._initialize_x_y(z) + elif 2 < nargs <= 4: + x, y, z_orig, *args = args + x, y, z = self._check_xyz(x, y, z_orig, kwargs) + + else: + raise _api.nargs_error(fn, takes="from 1 to 4", given=nargs) + z = ma.masked_invalid(z, copy=False) + self.zmax = z.max().astype(float) + self.zmin = z.min().astype(float) + if self.logscale and self.zmin <= 0: + z = ma.masked_where(z <= 0, z) + _api.warn_external('Log scale: values of z <= 0 have been masked') + self.zmin = z.min().astype(float) + self._process_contour_level_args(args, z.dtype) + return (x, y, z) + + def _check_xyz(self, x, y, z, kwargs): + """ + Check that the shapes of the input arrays match; if x and y are 1D, + convert them to 2D using meshgrid. + """ + x, y = self.axes._process_unit_info([("x", x), ("y", y)], kwargs) + + x = np.asarray(x, dtype=np.float64) + y = np.asarray(y, dtype=np.float64) + z = ma.asarray(z) + + if z.ndim != 2: + raise TypeError(f"Input z must be 2D, not {z.ndim}D") + if z.shape[0] < 2 or z.shape[1] < 2: + raise TypeError(f"Input z must be at least a (2, 2) shaped array, " + f"but has shape {z.shape}") + Ny, Nx = z.shape + + if x.ndim != y.ndim: + raise TypeError(f"Number of dimensions of x ({x.ndim}) and y " + f"({y.ndim}) do not match") + if x.ndim == 1: + nx, = x.shape + ny, = y.shape + if nx != Nx: + raise TypeError(f"Length of x ({nx}) must match number of " + f"columns in z ({Nx})") + if ny != Ny: + raise TypeError(f"Length of y ({ny}) must match number of " + f"rows in z ({Ny})") + x, y = np.meshgrid(x, y) + elif x.ndim == 2: + if x.shape != z.shape: + raise TypeError( + f"Shapes of x {x.shape} and z {z.shape} do not match") + if y.shape != z.shape: + raise TypeError( + f"Shapes of y {y.shape} and z {z.shape} do not match") + else: + raise TypeError(f"Inputs x and y must be 1D or 2D, not {x.ndim}D") + + return x, y, z + + def _initialize_x_y(self, z): + """ + Return X, Y arrays such that contour(Z) will match imshow(Z) + if origin is not None. + The center of pixel Z[i, j] depends on origin: + if origin is None, x = j, y = i; + if origin is 'lower', x = j + 0.5, y = i + 0.5; + if origin is 'upper', x = j + 0.5, y = Nrows - i - 0.5 + If extent is not None, x and y will be scaled to match, + as in imshow. + If origin is None and extent is not None, then extent + will give the minimum and maximum values of x and y. + """ + if z.ndim != 2: + raise TypeError(f"Input z must be 2D, not {z.ndim}D") + elif z.shape[0] < 2 or z.shape[1] < 2: + raise TypeError(f"Input z must be at least a (2, 2) shaped array, " + f"but has shape {z.shape}") + else: + Ny, Nx = z.shape + if self.origin is None: # Not for image-matching. + if self.extent is None: + return np.meshgrid(np.arange(Nx), np.arange(Ny)) + else: + x0, x1, y0, y1 = self.extent + x = np.linspace(x0, x1, Nx) + y = np.linspace(y0, y1, Ny) + return np.meshgrid(x, y) + # Match image behavior: + if self.extent is None: + x0, x1, y0, y1 = (0, Nx, 0, Ny) + else: + x0, x1, y0, y1 = self.extent + dx = (x1 - x0) / Nx + dy = (y1 - y0) / Ny + x = x0 + (np.arange(Nx) + 0.5) * dx + y = y0 + (np.arange(Ny) + 0.5) * dy + if self.origin == 'upper': + y = y[::-1] + return np.meshgrid(x, y) + + +_docstring.interpd.update(contour_doc=""" +`.contour` and `.contourf` draw contour lines and filled contours, +respectively. Except as noted, function signatures and return values +are the same for both versions. + +Parameters +---------- +X, Y : array-like, optional + The coordinates of the values in *Z*. + + *X* and *Y* must both be 2D with the same shape as *Z* (e.g. + created via `numpy.meshgrid`), or they must both be 1-D such + that ``len(X) == N`` is the number of columns in *Z* and + ``len(Y) == M`` is the number of rows in *Z*. + + *X* and *Y* must both be ordered monotonically. + + If not given, they are assumed to be integer indices, i.e. + ``X = range(N)``, ``Y = range(M)``. + +Z : (M, N) array-like + The height values over which the contour is drawn. Color-mapping is + controlled by *cmap*, *norm*, *vmin*, and *vmax*. + +levels : int or array-like, optional + Determines the number and positions of the contour lines / regions. + + If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries + to automatically choose no more than *n+1* "nice" contour levels + between minimum and maximum numeric values of *Z*. + + If array-like, draw contour lines at the specified levels. + The values must be in increasing order. + +Returns +------- +`~.contour.QuadContourSet` + +Other Parameters +---------------- +corner_mask : bool, default: :rc:`contour.corner_mask` + Enable/disable corner masking, which only has an effect if *Z* is + a masked array. If ``False``, any quad touching a masked point is + masked out. If ``True``, only the triangular corners of quads + nearest those points are always masked out, other triangular + corners comprising three unmasked points are contoured as usual. + +colors : color string or sequence of colors, optional + The colors of the levels, i.e. the lines for `.contour` and the + areas for `.contourf`. + + The sequence is cycled for the levels in ascending order. If the + sequence is shorter than the number of levels, it's repeated. + + As a shortcut, single color strings may be used in place of + one-element lists, i.e. ``'red'`` instead of ``['red']`` to color + all levels with the same color. This shortcut does only work for + color strings, not for other ways of specifying colors. + + By default (value *None*), the colormap specified by *cmap* + will be used. + +alpha : float, default: 1 + The alpha blending value, between 0 (transparent) and 1 (opaque). + +%(cmap_doc)s + + This parameter is ignored if *colors* is set. + +%(norm_doc)s + + This parameter is ignored if *colors* is set. + +%(vmin_vmax_doc)s + + If *vmin* or *vmax* are not given, the default color scaling is based on + *levels*. + + This parameter is ignored if *colors* is set. + +origin : {*None*, 'upper', 'lower', 'image'}, default: None + Determines the orientation and exact position of *Z* by specifying + the position of ``Z[0, 0]``. This is only relevant, if *X*, *Y* + are not given. + + - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner. + - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner. + - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left + corner. + - 'image': Use the value from :rc:`image.origin`. + +extent : (x0, x1, y0, y1), optional + If *origin* is not *None*, then *extent* is interpreted as in + `.imshow`: it gives the outer pixel boundaries. In this case, the + position of Z[0, 0] is the center of the pixel, not a corner. If + *origin* is *None*, then (*x0*, *y0*) is the position of Z[0, 0], + and (*x1*, *y1*) is the position of Z[-1, -1]. + + This argument is ignored if *X* and *Y* are specified in the call + to contour. + +locator : ticker.Locator subclass, optional + The locator is used to determine the contour levels if they + are not given explicitly via *levels*. + Defaults to `~.ticker.MaxNLocator`. + +extend : {'neither', 'both', 'min', 'max'}, default: 'neither' + Determines the ``contourf``-coloring of values that are outside the + *levels* range. + + If 'neither', values outside the *levels* range are not colored. + If 'min', 'max' or 'both', color the values below, above or below + and above the *levels* range. + + Values below ``min(levels)`` and above ``max(levels)`` are mapped + to the under/over values of the `.Colormap`. Note that most + colormaps do not have dedicated colors for these by default, so + that the over and under values are the edge values of the colormap. + You may want to set these values explicitly using + `.Colormap.set_under` and `.Colormap.set_over`. + + .. note:: + + An existing `.QuadContourSet` does not get notified if + properties of its colormap are changed. Therefore, an explicit + call `.QuadContourSet.changed()` is needed after modifying the + colormap. The explicit call can be left out, if a colorbar is + assigned to the `.QuadContourSet` because it internally calls + `.QuadContourSet.changed()`. + + Example:: + + x = np.arange(1, 10) + y = x.reshape(-1, 1) + h = x * y + + cs = plt.contourf(h, levels=[10, 30, 50], + colors=['#808080', '#A0A0A0', '#C0C0C0'], extend='both') + cs.cmap.set_over('red') + cs.cmap.set_under('blue') + cs.changed() + +xunits, yunits : registered units, optional + Override axis units by specifying an instance of a + :class:`matplotlib.units.ConversionInterface`. + +antialiased : bool, optional + Enable antialiasing, overriding the defaults. For + filled contours, the default is *False*. For line contours, + it is taken from :rc:`lines.antialiased`. + +nchunk : int >= 0, optional + If 0, no subdivision of the domain. Specify a positive integer to + divide the domain into subdomains of *nchunk* by *nchunk* quads. + Chunking reduces the maximum length of polygons generated by the + contouring algorithm which reduces the rendering workload passed + on to the backend and also requires slightly less RAM. It can + however introduce rendering artifacts at chunk boundaries depending + on the backend, the *antialiased* flag and value of *alpha*. + +linewidths : float or array-like, default: :rc:`contour.linewidth` + *Only applies to* `.contour`. + + The line width of the contour lines. + + If a number, all levels will be plotted with this linewidth. + + If a sequence, the levels in ascending order will be plotted with + the linewidths in the order specified. + + If None, this falls back to :rc:`lines.linewidth`. + +linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional + *Only applies to* `.contour`. + + If *linestyles* is *None*, the default is 'solid' unless the lines are + monochrome. In that case, negative contours will instead take their + linestyle from the *negative_linestyles* argument. + + *linestyles* can also be an iterable of the above strings specifying a set + of linestyles to be used. If this iterable is shorter than the number of + contour levels it will be repeated as necessary. + +negative_linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, \ + optional + *Only applies to* `.contour`. + + If *linestyles* is *None* and the lines are monochrome, this argument + specifies the line style for negative contours. + + If *negative_linestyles* is *None*, the default is taken from + :rc:`contour.negative_linestyles`. + + *negative_linestyles* can also be an iterable of the above strings + specifying a set of linestyles to be used. If this iterable is shorter than + the number of contour levels it will be repeated as necessary. + +hatches : list[str], optional + *Only applies to* `.contourf`. + + A list of cross hatch patterns to use on the filled areas. + If None, no hatching will be added to the contour. + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + +algorithm : {'mpl2005', 'mpl2014', 'serial', 'threaded'}, optional + Which contouring algorithm to use to calculate the contour lines and + polygons. The algorithms are implemented in + `ContourPy `_, consult the + `ContourPy documentation `_ for + further information. + + The default is taken from :rc:`contour.algorithm`. + +clip_path : `~matplotlib.patches.Patch` or `.Path` or `.TransformedPath` + Set the clip path. See `~matplotlib.artist.Artist.set_clip_path`. + + .. versionadded:: 3.8 + +data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + +Notes +----- +1. `.contourf` differs from the MATLAB version in that it does not draw + the polygon edges. To draw edges, add line contours with calls to + `.contour`. + +2. `.contourf` fills intervals that are closed at the top; that is, for + boundaries *z1* and *z2*, the filled region is:: + + z1 < Z <= z2 + + except for the lowest interval, which is closed on both sides (i.e. + it includes the lowest value). + +3. `.contour` and `.contourf` use a `marching squares + `_ algorithm to + compute contour locations. More information can be found in + `ContourPy documentation `_. +""" % _docstring.interpd.params) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.pyi new file mode 100644 index 00000000..d7bddfe8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/contour.pyi @@ -0,0 +1,169 @@ +import matplotlib.cm as cm +from matplotlib.artist import Artist +from matplotlib.axes import Axes +from matplotlib.collections import Collection, PathCollection +from matplotlib.colors import Colormap, Normalize +from matplotlib.font_manager import FontProperties +from matplotlib.path import Path +from matplotlib.patches import Patch +from matplotlib.text import Text +from matplotlib.transforms import Transform, TransformedPatchPath, TransformedPath +from matplotlib.ticker import Locator, Formatter + +from numpy.typing import ArrayLike +import numpy as np +from collections.abc import Callable, Iterable, Sequence +from typing import Literal +from .typing import ColorType + +class ClabelText(Text): ... + +class ContourLabeler: + labelFmt: str | Formatter | Callable[[float], str] | dict[float, str] + labelManual: bool | Iterable[tuple[float, float]] + rightside_up: bool + labelLevelList: list[float] + labelIndiceList: list[int] + labelMappable: cm.ScalarMappable + labelCValueList: list[ColorType] + labelXYs: list[tuple[float, float]] + def clabel( + self, + levels: ArrayLike | None = ..., + *, + fontsize: str | float | None = ..., + inline: bool = ..., + inline_spacing: float = ..., + fmt: str | Formatter | Callable[[float], str] | dict[float, str] | None = ..., + colors: ColorType | Sequence[ColorType] | None = ..., + use_clabeltext: bool = ..., + manual: bool | Iterable[tuple[float, float]] = ..., + rightside_up: bool = ..., + zorder: float | None = ... + ) -> list[Text]: ... + @property + def labelFontProps(self) -> FontProperties: ... + @property + def labelFontSizeList(self) -> list[float]: ... + @property + def labelTextsList(self) -> list[Text]: ... + def print_label(self, linecontour: ArrayLike, labelwidth: float) -> bool: ... + def too_close(self, x: float, y: float, lw: float) -> bool: ... + def set_label_props(self, label: Text, text: str, color: ColorType) -> None: ... + def get_text( + self, + lev: float, + fmt: str | Formatter | Callable[[float], str] | dict[float, str], + ) -> str: ... + def locate_label( + self, linecontour: ArrayLike, labelwidth: float + ) -> tuple[float, float, float]: ... + def calc_label_rot_and_inline( + self, + slc: ArrayLike, + ind: int, + lw: float, + lc: ArrayLike | None = ..., + spacing: int = ..., + ) -> tuple[float, list[ArrayLike]]: ... + def add_label( + self, x: float, y: float, rotation: float, lev: float, cvalue: ColorType + ) -> None: ... + def add_label_clabeltext( + self, x: float, y: float, rotation: float, lev: float, cvalue: ColorType + ) -> None: ... + def add_label_near( + self, + x: float, + y: float, + inline: bool = ..., + inline_spacing: int = ..., + transform: Transform | Literal[False] | None = ..., + ) -> None: ... + def pop_label(self, index: int = ...) -> None: ... + def labels(self, inline: bool, inline_spacing: int) -> None: ... + def remove(self) -> None: ... + +class ContourSet(ContourLabeler, Collection): + axes: Axes + levels: Iterable[float] + filled: bool + linewidths: float | ArrayLike | None + hatches: Iterable[str | None] + origin: Literal["upper", "lower", "image"] | None + extent: tuple[float, float, float, float] | None + colors: ColorType | Sequence[ColorType] + extend: Literal["neither", "both", "min", "max"] + nchunk: int + locator: Locator | None + logscale: bool + negative_linestyles: None | Literal[ + "solid", "dashed", "dashdot", "dotted" + ] | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]] + clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None + labelTexts: list[Text] + labelCValues: list[ColorType] + @property + def tcolors(self) -> list[tuple[tuple[float, float, float, float]]]: ... + + # only for not filled + @property + def tlinewidths(self) -> list[tuple[float]]: ... + + @property + def allkinds(self) -> list[list[np.ndarray | None]]: ... + @property + def allsegs(self) -> list[list[np.ndarray]]: ... + @property + def alpha(self) -> float | None: ... + @property + def antialiased(self) -> bool: ... + @antialiased.setter + def antialiased(self, aa: bool | Sequence[bool]) -> None: ... + @property + def collections(self) -> list[PathCollection]: ... + @property + def linestyles(self) -> ( + None | + Literal["solid", "dashed", "dashdot", "dotted"] | + Iterable[Literal["solid", "dashed", "dashdot", "dotted"]] + ): ... + + def __init__( + self, + ax: Axes, + *args, + levels: Iterable[float] | None = ..., + filled: bool = ..., + linewidths: float | ArrayLike | None = ..., + linestyles: Literal["solid", "dashed", "dashdot", "dotted"] + | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]] + | None = ..., + hatches: Iterable[str | None] = ..., + alpha: float | None = ..., + origin: Literal["upper", "lower", "image"] | None = ..., + extent: tuple[float, float, float, float] | None = ..., + cmap: str | Colormap | None = ..., + colors: ColorType | Sequence[ColorType] | None = ..., + norm: str | Normalize | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + extend: Literal["neither", "both", "min", "max"] = ..., + antialiased: bool | None = ..., + nchunk: int = ..., + locator: Locator | None = ..., + transform: Transform | None = ..., + negative_linestyles: Literal["solid", "dashed", "dashdot", "dotted"] + | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]] + | None = ..., + clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None = ..., + **kwargs + ) -> None: ... + def legend_elements( + self, variable_name: str = ..., str_format: Callable[[float], str] = ... + ) -> tuple[list[Artist], list[str]]: ... + def find_nearest_contour( + self, x: float, y: float, indices: Iterable[int] | None = ..., pixel: bool = ... + ) -> tuple[int, int, int, float, float, float]: ... + +class QuadContourSet(ContourSet): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/dates.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dates.py new file mode 100644 index 00000000..a11e0d4f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dates.py @@ -0,0 +1,1894 @@ +""" +Matplotlib provides sophisticated date plotting capabilities, standing on the +shoulders of python :mod:`datetime` and the add-on module dateutil_. + +By default, Matplotlib uses the units machinery described in +`~matplotlib.units` to convert `datetime.datetime`, and `numpy.datetime64` +objects when plotted on an x- or y-axis. The user does not +need to do anything for dates to be formatted, but dates often have strict +formatting needs, so this module provides many tick locators and formatters. +A basic example using `numpy.datetime64` is:: + + import numpy as np + + times = np.arange(np.datetime64('2001-01-02'), + np.datetime64('2002-02-03'), np.timedelta64(75, 'm')) + y = np.random.randn(len(times)) + + fig, ax = plt.subplots() + ax.plot(times, y) + +.. seealso:: + + - :doc:`/gallery/text_labels_and_annotations/date` + - :doc:`/gallery/ticks/date_concise_formatter` + - :doc:`/gallery/ticks/date_demo_convert` + +.. _date-format: + +Matplotlib date format +---------------------- + +Matplotlib represents dates using floating point numbers specifying the number +of days since a default epoch of 1970-01-01 UTC; for example, +1970-01-01, 06:00 is the floating point number 0.25. The formatters and +locators require the use of `datetime.datetime` objects, so only dates between +year 0001 and 9999 can be represented. Microsecond precision +is achievable for (approximately) 70 years on either side of the epoch, and +20 microseconds for the rest of the allowable range of dates (year 0001 to +9999). The epoch can be changed at import time via `.dates.set_epoch` or +:rc:`dates.epoch` to other dates if necessary; see +:doc:`/gallery/ticks/date_precision_and_epochs` for a discussion. + +.. note:: + + Before Matplotlib 3.3, the epoch was 0000-12-31 which lost modern + microsecond precision and also made the default axis limit of 0 an invalid + datetime. In 3.3 the epoch was changed as above. To convert old + ordinal floats to the new epoch, users can do:: + + new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) + + +There are a number of helper functions to convert between :mod:`datetime` +objects and Matplotlib dates: + +.. currentmodule:: matplotlib.dates + +.. autosummary:: + :nosignatures: + + datestr2num + date2num + num2date + num2timedelta + drange + set_epoch + get_epoch + +.. note:: + + Like Python's `datetime.datetime`, Matplotlib uses the Gregorian calendar + for all conversions between dates and floating point numbers. This practice + is not universal, and calendar differences can cause confusing + differences between what Python and Matplotlib give as the number of days + since 0001-01-01 and what other software and databases yield. For + example, the US Naval Observatory uses a calendar that switches + from Julian to Gregorian in October, 1582. Hence, using their + calculator, the number of days between 0001-01-01 and 2006-04-01 is + 732403, whereas using the Gregorian calendar via the datetime + module we find:: + + In [1]: date(2006, 4, 1).toordinal() - date(1, 1, 1).toordinal() + Out[1]: 732401 + +All the Matplotlib date converters, locators and formatters are timezone aware. +If no explicit timezone is provided, :rc:`timezone` is assumed, provided as a +string. If you want to use a different timezone, pass the *tz* keyword +argument of `num2date` to any date tick locators or formatters you create. This +can be either a `datetime.tzinfo` instance or a string with the timezone name +that can be parsed by `~dateutil.tz.gettz`. + +A wide range of specific and general purpose date tick locators and +formatters are provided in this module. See +:mod:`matplotlib.ticker` for general information on tick locators +and formatters. These are described below. + +The dateutil_ module provides additional code to handle date ticking, making it +easy to place ticks on any kinds of dates. See examples below. + +.. _dateutil: https://dateutil.readthedocs.io + +.. _date-locators: + +Date tick locators +------------------ + +Most of the date tick locators can locate single or multiple ticks. For example:: + + # import constants for the days of the week + from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU + + # tick on Mondays every week + loc = WeekdayLocator(byweekday=MO, tz=tz) + + # tick on Mondays and Saturdays + loc = WeekdayLocator(byweekday=(MO, SA)) + +In addition, most of the constructors take an interval argument:: + + # tick on Mondays every second week + loc = WeekdayLocator(byweekday=MO, interval=2) + +The rrule locator allows completely general date ticking:: + + # tick every 5th easter + rule = rrulewrapper(YEARLY, byeaster=1, interval=5) + loc = RRuleLocator(rule) + +The available date tick locators are: + +* `MicrosecondLocator`: Locate microseconds. + +* `SecondLocator`: Locate seconds. + +* `MinuteLocator`: Locate minutes. + +* `HourLocator`: Locate hours. + +* `DayLocator`: Locate specified days of the month. + +* `WeekdayLocator`: Locate days of the week, e.g., MO, TU. + +* `MonthLocator`: Locate months, e.g., 7 for July. + +* `YearLocator`: Locate years that are multiples of base. + +* `RRuleLocator`: Locate using a `rrulewrapper`. + `rrulewrapper` is a simple wrapper around dateutil_'s `dateutil.rrule` + which allow almost arbitrary date tick specifications. + See :doc:`rrule example `. + +* `AutoDateLocator`: On autoscale, this class picks the best `DateLocator` + (e.g., `RRuleLocator`) to set the view limits and the tick locations. If + called with ``interval_multiples=True`` it will make ticks line up with + sensible multiples of the tick intervals. For example, if the interval is + 4 hours, it will pick hours 0, 4, 8, etc. as ticks. This behaviour is not + guaranteed by default. + +.. _date-formatters: + +Date formatters +--------------- + +The available date formatters are: + +* `AutoDateFormatter`: attempts to figure out the best format to use. This is + most useful when used with the `AutoDateLocator`. + +* `ConciseDateFormatter`: also attempts to figure out the best format to use, + and to make the format as compact as possible while still having complete + date information. This is most useful when used with the `AutoDateLocator`. + +* `DateFormatter`: use `~datetime.datetime.strftime` format strings. +""" + +import datetime +import functools +import logging +import re + +from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, + MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, + SECONDLY) +from dateutil.relativedelta import relativedelta +import dateutil.parser +import dateutil.tz +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook, ticker, units + +__all__ = ('datestr2num', 'date2num', 'num2date', 'num2timedelta', 'drange', + 'set_epoch', 'get_epoch', 'DateFormatter', 'ConciseDateFormatter', + 'AutoDateFormatter', 'DateLocator', 'RRuleLocator', + 'AutoDateLocator', 'YearLocator', 'MonthLocator', 'WeekdayLocator', + 'DayLocator', 'HourLocator', 'MinuteLocator', + 'SecondLocator', 'MicrosecondLocator', + 'rrule', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU', + 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', + 'HOURLY', 'MINUTELY', 'SECONDLY', 'MICROSECONDLY', 'relativedelta', + 'DateConverter', 'ConciseDateConverter', 'rrulewrapper') + + +_log = logging.getLogger(__name__) +UTC = datetime.timezone.utc + + +@_api.caching_module_getattr +class __getattr__: + JULIAN_OFFSET = _api.deprecated("3.7")(property(lambda self: 1721424.5)) + # Julian date at 0000-12-31 + # note that the Julian day epoch is achievable w/ + # np.datetime64('-4713-11-24T12:00:00'); datetime64 is proleptic + # Gregorian and BC has a one-year offset. So + # np.datetime64('0000-12-31') - np.datetime64('-4713-11-24T12:00') = + # 1721424.5 + # Ref: https://en.wikipedia.org/wiki/Julian_day + + +def _get_tzinfo(tz=None): + """ + Generate `~datetime.tzinfo` from a string or return `~datetime.tzinfo`. + If None, retrieve the preferred timezone from the rcParams dictionary. + """ + tz = mpl._val_or_rc(tz, 'timezone') + if tz == 'UTC': + return UTC + if isinstance(tz, str): + tzinfo = dateutil.tz.gettz(tz) + if tzinfo is None: + raise ValueError(f"{tz} is not a valid timezone as parsed by" + " dateutil.tz.gettz.") + return tzinfo + if isinstance(tz, datetime.tzinfo): + return tz + raise TypeError(f"tz must be string or tzinfo subclass, not {tz!r}.") + + +# Time-related constants. +EPOCH_OFFSET = float(datetime.datetime(1970, 1, 1).toordinal()) +# EPOCH_OFFSET is not used by matplotlib +MICROSECONDLY = SECONDLY + 1 +HOURS_PER_DAY = 24. +MIN_PER_HOUR = 60. +SEC_PER_MIN = 60. +MONTHS_PER_YEAR = 12. + +DAYS_PER_WEEK = 7. +DAYS_PER_MONTH = 30. +DAYS_PER_YEAR = 365.0 + +MINUTES_PER_DAY = MIN_PER_HOUR * HOURS_PER_DAY + +SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR +SEC_PER_DAY = SEC_PER_HOUR * HOURS_PER_DAY +SEC_PER_WEEK = SEC_PER_DAY * DAYS_PER_WEEK + +MUSECONDS_PER_DAY = 1e6 * SEC_PER_DAY + +MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = ( + MO, TU, WE, TH, FR, SA, SU) +WEEKDAYS = (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) + +# default epoch: passed to np.datetime64... +_epoch = None + + +def _reset_epoch_test_example(): + """ + Reset the Matplotlib date epoch so it can be set again. + + Only for use in tests and examples. + """ + global _epoch + _epoch = None + + +def set_epoch(epoch): + """ + Set the epoch (origin for dates) for datetime calculations. + + The default epoch is :rc:`dates.epoch` (by default 1970-01-01T00:00). + + If microsecond accuracy is desired, the date being plotted needs to be + within approximately 70 years of the epoch. Matplotlib internally + represents dates as days since the epoch, so floating point dynamic + range needs to be within a factor of 2^52. + + `~.dates.set_epoch` must be called before any dates are converted + (i.e. near the import section) or a RuntimeError will be raised. + + See also :doc:`/gallery/ticks/date_precision_and_epochs`. + + Parameters + ---------- + epoch : str + valid UTC date parsable by `numpy.datetime64` (do not include + timezone). + + """ + global _epoch + if _epoch is not None: + raise RuntimeError('set_epoch must be called before dates plotted.') + _epoch = epoch + + +def get_epoch(): + """ + Get the epoch used by `.dates`. + + Returns + ------- + epoch : str + String for the epoch (parsable by `numpy.datetime64`). + """ + global _epoch + + _epoch = mpl._val_or_rc(_epoch, 'date.epoch') + return _epoch + + +def _dt64_to_ordinalf(d): + """ + Convert `numpy.datetime64` or an `numpy.ndarray` of those types to + Gregorian date as UTC float relative to the epoch (see `.get_epoch`). + Roundoff is float64 precision. Practically: microseconds for dates + between 290301 BC, 294241 AD, milliseconds for larger dates + (see `numpy.datetime64`). + """ + + # the "extra" ensures that we at least allow the dynamic range out to + # seconds. That should get out to +/-2e11 years. + dseconds = d.astype('datetime64[s]') + extra = (d - dseconds).astype('timedelta64[ns]') + t0 = np.datetime64(get_epoch(), 's') + dt = (dseconds - t0).astype(np.float64) + dt += extra.astype(np.float64) / 1.0e9 + dt = dt / SEC_PER_DAY + + NaT_int = np.datetime64('NaT').astype(np.int64) + d_int = d.astype(np.int64) + dt[d_int == NaT_int] = np.nan + return dt + + +def _from_ordinalf(x, tz=None): + """ + Convert Gregorian float of the date, preserving hours, minutes, + seconds and microseconds. Return value is a `.datetime`. + + The input date *x* is a float in ordinal days at UTC, and the output will + be the specified `.datetime` object corresponding to that time in + timezone *tz*, or if *tz* is ``None``, in the timezone specified in + :rc:`timezone`. + """ + + tz = _get_tzinfo(tz) + + dt = (np.datetime64(get_epoch()) + + np.timedelta64(int(np.round(x * MUSECONDS_PER_DAY)), 'us')) + if dt < np.datetime64('0001-01-01') or dt >= np.datetime64('10000-01-01'): + raise ValueError(f'Date ordinal {x} converts to {dt} (using ' + f'epoch {get_epoch()}), but Matplotlib dates must be ' + 'between year 0001 and 9999.') + # convert from datetime64 to datetime: + dt = dt.tolist() + + # datetime64 is always UTC: + dt = dt.replace(tzinfo=dateutil.tz.gettz('UTC')) + # but maybe we are working in a different timezone so move. + dt = dt.astimezone(tz) + # fix round off errors + if np.abs(x) > 70 * 365: + # if x is big, round off to nearest twenty microseconds. + # This avoids floating point roundoff error + ms = round(dt.microsecond / 20) * 20 + if ms == 1000000: + dt = dt.replace(microsecond=0) + datetime.timedelta(seconds=1) + else: + dt = dt.replace(microsecond=ms) + + return dt + + +# a version of _from_ordinalf that can operate on numpy arrays +_from_ordinalf_np_vectorized = np.vectorize(_from_ordinalf, otypes="O") +# a version of dateutil.parser.parse that can operate on numpy arrays +_dateutil_parser_parse_np_vectorized = np.vectorize(dateutil.parser.parse) + + +def datestr2num(d, default=None): + """ + Convert a date string to a datenum using `dateutil.parser.parse`. + + Parameters + ---------- + d : str or sequence of str + The dates to convert. + + default : datetime.datetime, optional + The default date to use when fields are missing in *d*. + """ + if isinstance(d, str): + dt = dateutil.parser.parse(d, default=default) + return date2num(dt) + else: + if default is not None: + d = [date2num(dateutil.parser.parse(s, default=default)) + for s in d] + return np.asarray(d) + d = np.asarray(d) + if not d.size: + return d + return date2num(_dateutil_parser_parse_np_vectorized(d)) + + +def date2num(d): + """ + Convert datetime objects to Matplotlib dates. + + Parameters + ---------- + d : `datetime.datetime` or `numpy.datetime64` or sequences of these + + Returns + ------- + float or sequence of floats + Number of days since the epoch. See `.get_epoch` for the + epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`. If + the epoch is "1970-01-01T00:00:00" (default) then noon Jan 1 1970 + ("1970-01-01T12:00:00") returns 0.5. + + Notes + ----- + The Gregorian calendar is assumed; this is not universal practice. + For details see the module docstring. + """ + # Unpack in case of e.g. Pandas or xarray object + d = cbook._unpack_to_numpy(d) + + # make an iterable, but save state to unpack later: + iterable = np.iterable(d) + if not iterable: + d = [d] + + masked = np.ma.is_masked(d) + mask = np.ma.getmask(d) + d = np.asarray(d) + + # convert to datetime64 arrays, if not already: + if not np.issubdtype(d.dtype, np.datetime64): + # datetime arrays + if not d.size: + # deals with an empty array... + return d + tzi = getattr(d[0], 'tzinfo', None) + if tzi is not None: + # make datetime naive: + d = [dt.astimezone(UTC).replace(tzinfo=None) for dt in d] + d = np.asarray(d) + d = d.astype('datetime64[us]') + + d = np.ma.masked_array(d, mask=mask) if masked else d + d = _dt64_to_ordinalf(d) + + return d if iterable else d[0] + + +@_api.deprecated("3.7") +def julian2num(j): + """ + Convert a Julian date (or sequence) to a Matplotlib date (or sequence). + + Parameters + ---------- + j : float or sequence of floats + Julian dates (days relative to 4713 BC Jan 1, 12:00:00 Julian + calendar or 4714 BC Nov 24, 12:00:00, proleptic Gregorian calendar). + + Returns + ------- + float or sequence of floats + Matplotlib dates (days relative to `.get_epoch`). + """ + ep = np.datetime64(get_epoch(), 'h').astype(float) / 24. + ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24. + # Julian offset defined above is relative to 0000-12-31, but we need + # relative to our current epoch: + dt = __getattr__("JULIAN_OFFSET") - ep0 + ep + return np.subtract(j, dt) # Handles both scalar & nonscalar j. + + +@_api.deprecated("3.7") +def num2julian(n): + """ + Convert a Matplotlib date (or sequence) to a Julian date (or sequence). + + Parameters + ---------- + n : float or sequence of floats + Matplotlib dates (days relative to `.get_epoch`). + + Returns + ------- + float or sequence of floats + Julian dates (days relative to 4713 BC Jan 1, 12:00:00). + """ + ep = np.datetime64(get_epoch(), 'h').astype(float) / 24. + ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24. + # Julian offset defined above is relative to 0000-12-31, but we need + # relative to our current epoch: + dt = __getattr__("JULIAN_OFFSET") - ep0 + ep + return np.add(n, dt) # Handles both scalar & nonscalar j. + + +def num2date(x, tz=None): + """ + Convert Matplotlib dates to `~datetime.datetime` objects. + + Parameters + ---------- + x : float or sequence of floats + Number of days (fraction part represents hours, minutes, seconds) + since the epoch. See `.get_epoch` for the + epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Timezone of *x*. If a string, *tz* is passed to `dateutil.tz`. + + Returns + ------- + `~datetime.datetime` or sequence of `~datetime.datetime` + Dates are returned in timezone *tz*. + + If *x* is a sequence, a sequence of `~datetime.datetime` objects will + be returned. + + Notes + ----- + The Gregorian calendar is assumed; this is not universal practice. + For details, see the module docstring. + """ + tz = _get_tzinfo(tz) + return _from_ordinalf_np_vectorized(x, tz).tolist() + + +_ordinalf_to_timedelta_np_vectorized = np.vectorize( + lambda x: datetime.timedelta(days=x), otypes="O") + + +def num2timedelta(x): + """ + Convert number of days to a `~datetime.timedelta` object. + + If *x* is a sequence, a sequence of `~datetime.timedelta` objects will + be returned. + + Parameters + ---------- + x : float, sequence of floats + Number of days. The fraction part represents hours, minutes, seconds. + + Returns + ------- + `datetime.timedelta` or list[`datetime.timedelta`] + """ + return _ordinalf_to_timedelta_np_vectorized(x).tolist() + + +def drange(dstart, dend, delta): + """ + Return a sequence of equally spaced Matplotlib dates. + + The dates start at *dstart* and reach up to, but not including *dend*. + They are spaced by *delta*. + + Parameters + ---------- + dstart, dend : `~datetime.datetime` + The date limits. + delta : `datetime.timedelta` + Spacing of the dates. + + Returns + ------- + `numpy.array` + A list floats representing Matplotlib dates. + + """ + f1 = date2num(dstart) + f2 = date2num(dend) + step = delta.total_seconds() / SEC_PER_DAY + + # calculate the difference between dend and dstart in times of delta + num = int(np.ceil((f2 - f1) / step)) + + # calculate end of the interval which will be generated + dinterval_end = dstart + num * delta + + # ensure, that an half open interval will be generated [dstart, dend) + if dinterval_end >= dend: + # if the endpoint is greater than or equal to dend, + # just subtract one delta + dinterval_end -= delta + num -= 1 + + f2 = date2num(dinterval_end) # new float-endpoint + return np.linspace(f1, f2, num + 1) + + +def _wrap_in_tex(text): + p = r'([a-zA-Z]+)' + ret_text = re.sub(p, r'}$\1$\\mathdefault{', text) + + # Braces ensure symbols are not spaced like binary operators. + ret_text = ret_text.replace('-', '{-}').replace(':', '{:}') + # To not concatenate space between numbers. + ret_text = ret_text.replace(' ', r'\;') + ret_text = '$\\mathdefault{' + ret_text + '}$' + ret_text = ret_text.replace('$\\mathdefault{}$', '') + return ret_text + + +## date tick locators and formatters ### + + +class DateFormatter(ticker.Formatter): + """ + Format a tick (in days since the epoch) with a + `~datetime.datetime.strftime` format string. + """ + + def __init__(self, fmt, tz=None, *, usetex=None): + """ + Parameters + ---------- + fmt : str + `~datetime.datetime.strftime` format string + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + usetex : bool, default: :rc:`text.usetex` + To enable/disable the use of TeX's math mode for rendering the + results of the formatter. + """ + self.tz = _get_tzinfo(tz) + self.fmt = fmt + self._usetex = mpl._val_or_rc(usetex, 'text.usetex') + + def __call__(self, x, pos=0): + result = num2date(x, self.tz).strftime(self.fmt) + return _wrap_in_tex(result) if self._usetex else result + + def set_tzinfo(self, tz): + self.tz = _get_tzinfo(tz) + + +class ConciseDateFormatter(ticker.Formatter): + """ + A `.Formatter` which attempts to figure out the best format to use for the + date, and to make it as compact as possible, but still be complete. This is + most useful when used with the `AutoDateLocator`:: + + >>> locator = AutoDateLocator() + >>> formatter = ConciseDateFormatter(locator) + + Parameters + ---------- + locator : `.ticker.Locator` + Locator that this axis is using. + + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone, passed to `.dates.num2date`. + + formats : list of 6 strings, optional + Format strings for 6 levels of tick labelling: mostly years, + months, days, hours, minutes, and seconds. Strings use + the same format codes as `~datetime.datetime.strftime`. Default is + ``['%Y', '%b', '%d', '%H:%M', '%H:%M', '%S.%f']`` + + zero_formats : list of 6 strings, optional + Format strings for tick labels that are "zeros" for a given tick + level. For instance, if most ticks are months, ticks around 1 Jan 2005 + will be labeled "Dec", "2005", "Feb". The default is + ``['', '%Y', '%b', '%b-%d', '%H:%M', '%H:%M']`` + + offset_formats : list of 6 strings, optional + Format strings for the 6 levels that is applied to the "offset" + string found on the right side of an x-axis, or top of a y-axis. + Combined with the tick labels this should completely specify the + date. The default is:: + + ['', '%Y', '%Y-%b', '%Y-%b-%d', '%Y-%b-%d', '%Y-%b-%d %H:%M'] + + show_offset : bool, default: True + Whether to show the offset or not. + + usetex : bool, default: :rc:`text.usetex` + To enable/disable the use of TeX's math mode for rendering the results + of the formatter. + + Examples + -------- + See :doc:`/gallery/ticks/date_concise_formatter` + + .. plot:: + + import datetime + import matplotlib.dates as mdates + + base = datetime.datetime(2005, 2, 1) + dates = np.array([base + datetime.timedelta(hours=(2 * i)) + for i in range(732)]) + N = len(dates) + np.random.seed(19680801) + y = np.cumsum(np.random.randn(N)) + + fig, ax = plt.subplots(constrained_layout=True) + locator = mdates.AutoDateLocator() + formatter = mdates.ConciseDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + + ax.plot(dates, y) + ax.set_title('Concise Date Formatter') + + """ + + def __init__(self, locator, tz=None, formats=None, offset_formats=None, + zero_formats=None, show_offset=True, *, usetex=None): + """ + Autoformat the date labels. The default format is used to form an + initial string, and then redundant elements are removed. + """ + self._locator = locator + self._tz = tz + self.defaultfmt = '%Y' + # there are 6 levels with each level getting a specific format + # 0: mostly years, 1: months, 2: days, + # 3: hours, 4: minutes, 5: seconds + if formats: + if len(formats) != 6: + raise ValueError('formats argument must be a list of ' + '6 format strings (or None)') + self.formats = formats + else: + self.formats = ['%Y', # ticks are mostly years + '%b', # ticks are mostly months + '%d', # ticks are mostly days + '%H:%M', # hrs + '%H:%M', # min + '%S.%f', # secs + ] + # fmt for zeros ticks at this level. These are + # ticks that should be labeled w/ info the level above. + # like 1 Jan can just be labelled "Jan". 02:02:00 can + # just be labeled 02:02. + if zero_formats: + if len(zero_formats) != 6: + raise ValueError('zero_formats argument must be a list of ' + '6 format strings (or None)') + self.zero_formats = zero_formats + elif formats: + # use the users formats for the zero tick formats + self.zero_formats = [''] + self.formats[:-1] + else: + # make the defaults a bit nicer: + self.zero_formats = [''] + self.formats[:-1] + self.zero_formats[3] = '%b-%d' + + if offset_formats: + if len(offset_formats) != 6: + raise ValueError('offset_formats argument must be a list of ' + '6 format strings (or None)') + self.offset_formats = offset_formats + else: + self.offset_formats = ['', + '%Y', + '%Y-%b', + '%Y-%b-%d', + '%Y-%b-%d', + '%Y-%b-%d %H:%M'] + self.offset_string = '' + self.show_offset = show_offset + self._usetex = mpl._val_or_rc(usetex, 'text.usetex') + + def __call__(self, x, pos=None): + formatter = DateFormatter(self.defaultfmt, self._tz, + usetex=self._usetex) + return formatter(x, pos=pos) + + def format_ticks(self, values): + tickdatetime = [num2date(value, tz=self._tz) for value in values] + tickdate = np.array([tdt.timetuple()[:6] for tdt in tickdatetime]) + + # basic algorithm: + # 1) only display a part of the date if it changes over the ticks. + # 2) don't display the smaller part of the date if: + # it is always the same or if it is the start of the + # year, month, day etc. + # fmt for most ticks at this level + fmts = self.formats + # format beginnings of days, months, years, etc. + zerofmts = self.zero_formats + # offset fmt are for the offset in the upper left of the + # or lower right of the axis. + offsetfmts = self.offset_formats + show_offset = self.show_offset + + # determine the level we will label at: + # mostly 0: years, 1: months, 2: days, + # 3: hours, 4: minutes, 5: seconds, 6: microseconds + for level in range(5, -1, -1): + unique = np.unique(tickdate[:, level]) + if len(unique) > 1: + # if 1 is included in unique, the year is shown in ticks + if level < 2 and np.any(unique == 1): + show_offset = False + break + elif level == 0: + # all tickdate are the same, so only micros might be different + # set to the most precise (6: microseconds doesn't exist...) + level = 5 + + # level is the basic level we will label at. + # now loop through and decide the actual ticklabels + zerovals = [0, 1, 1, 0, 0, 0, 0] + labels = [''] * len(tickdate) + for nn in range(len(tickdate)): + if level < 5: + if tickdate[nn][level] == zerovals[level]: + fmt = zerofmts[level] + else: + fmt = fmts[level] + else: + # special handling for seconds + microseconds + if (tickdatetime[nn].second == tickdatetime[nn].microsecond + == 0): + fmt = zerofmts[level] + else: + fmt = fmts[level] + labels[nn] = tickdatetime[nn].strftime(fmt) + + # special handling of seconds and microseconds: + # strip extra zeros and decimal if possible. + # this is complicated by two factors. 1) we have some level-4 strings + # here (i.e. 03:00, '0.50000', '1.000') 2) we would like to have the + # same number of decimals for each string (i.e. 0.5 and 1.0). + if level >= 5: + trailing_zeros = min( + (len(s) - len(s.rstrip('0')) for s in labels if '.' in s), + default=None) + if trailing_zeros: + for nn in range(len(labels)): + if '.' in labels[nn]: + labels[nn] = labels[nn][:-trailing_zeros].rstrip('.') + + if show_offset: + # set the offset string: + self.offset_string = tickdatetime[-1].strftime(offsetfmts[level]) + if self._usetex: + self.offset_string = _wrap_in_tex(self.offset_string) + else: + self.offset_string = '' + + if self._usetex: + return [_wrap_in_tex(l) for l in labels] + else: + return labels + + def get_offset(self): + return self.offset_string + + def format_data_short(self, value): + return num2date(value, tz=self._tz).strftime('%Y-%m-%d %H:%M:%S') + + +class AutoDateFormatter(ticker.Formatter): + """ + A `.Formatter` which attempts to figure out the best format to use. This + is most useful when used with the `AutoDateLocator`. + + `.AutoDateFormatter` has a ``.scale`` dictionary that maps tick scales (the + interval in days between one major tick) to format strings; this dictionary + defaults to :: + + self.scaled = { + DAYS_PER_YEAR: rcParams['date.autoformatter.year'], + DAYS_PER_MONTH: rcParams['date.autoformatter.month'], + 1: rcParams['date.autoformatter.day'], + 1 / HOURS_PER_DAY: rcParams['date.autoformatter.hour'], + 1 / MINUTES_PER_DAY: rcParams['date.autoformatter.minute'], + 1 / SEC_PER_DAY: rcParams['date.autoformatter.second'], + 1 / MUSECONDS_PER_DAY: rcParams['date.autoformatter.microsecond'], + } + + The formatter uses the format string corresponding to the lowest key in + the dictionary that is greater or equal to the current scale. Dictionary + entries can be customized:: + + locator = AutoDateLocator() + formatter = AutoDateFormatter(locator) + formatter.scaled[1/(24*60)] = '%M:%S' # only show min and sec + + Custom callables can also be used instead of format strings. The following + example shows how to use a custom format function to strip trailing zeros + from decimal seconds and adds the date to the first ticklabel:: + + def my_format_function(x, pos=None): + x = matplotlib.dates.num2date(x) + if pos == 0: + fmt = '%D %H:%M:%S.%f' + else: + fmt = '%H:%M:%S.%f' + label = x.strftime(fmt) + label = label.rstrip("0") + label = label.rstrip(".") + return label + + formatter.scaled[1/(24*60)] = my_format_function + """ + + # This can be improved by providing some user-level direction on + # how to choose the best format (precedence, etc.). + + # Perhaps a 'struct' that has a field for each time-type where a + # zero would indicate "don't show" and a number would indicate + # "show" with some sort of priority. Same priorities could mean + # show all with the same priority. + + # Or more simply, perhaps just a format string for each + # possibility... + + def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d', *, + usetex=None): + """ + Autoformat the date labels. + + Parameters + ---------- + locator : `.ticker.Locator` + Locator that this axis is using. + + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + + defaultfmt : str + The default format to use if none of the values in ``self.scaled`` + are greater than the unit returned by ``locator._get_unit()``. + + usetex : bool, default: :rc:`text.usetex` + To enable/disable the use of TeX's math mode for rendering the + results of the formatter. If any entries in ``self.scaled`` are set + as functions, then it is up to the customized function to enable or + disable TeX's math mode itself. + """ + self._locator = locator + self._tz = tz + self.defaultfmt = defaultfmt + self._formatter = DateFormatter(self.defaultfmt, tz) + rcParams = mpl.rcParams + self._usetex = mpl._val_or_rc(usetex, 'text.usetex') + self.scaled = { + DAYS_PER_YEAR: rcParams['date.autoformatter.year'], + DAYS_PER_MONTH: rcParams['date.autoformatter.month'], + 1: rcParams['date.autoformatter.day'], + 1 / HOURS_PER_DAY: rcParams['date.autoformatter.hour'], + 1 / MINUTES_PER_DAY: rcParams['date.autoformatter.minute'], + 1 / SEC_PER_DAY: rcParams['date.autoformatter.second'], + 1 / MUSECONDS_PER_DAY: rcParams['date.autoformatter.microsecond'] + } + + def _set_locator(self, locator): + self._locator = locator + + def __call__(self, x, pos=None): + try: + locator_unit_scale = float(self._locator._get_unit()) + except AttributeError: + locator_unit_scale = 1 + # Pick the first scale which is greater than the locator unit. + fmt = next((fmt for scale, fmt in sorted(self.scaled.items()) + if scale >= locator_unit_scale), + self.defaultfmt) + + if isinstance(fmt, str): + self._formatter = DateFormatter(fmt, self._tz, usetex=self._usetex) + result = self._formatter(x, pos) + elif callable(fmt): + result = fmt(x, pos) + else: + raise TypeError(f'Unexpected type passed to {self!r}.') + + return result + + +class rrulewrapper: + """ + A simple wrapper around a `dateutil.rrule` allowing flexible + date tick specifications. + """ + def __init__(self, freq, tzinfo=None, **kwargs): + """ + Parameters + ---------- + freq : {YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY} + Tick frequency. These constants are defined in `dateutil.rrule`, + but they are accessible from `matplotlib.dates` as well. + tzinfo : `datetime.tzinfo`, optional + Time zone information. The default is None. + **kwargs + Additional keyword arguments are passed to the `dateutil.rrule`. + """ + kwargs['freq'] = freq + self._base_tzinfo = tzinfo + + self._update_rrule(**kwargs) + + def set(self, **kwargs): + """Set parameters for an existing wrapper.""" + self._construct.update(kwargs) + + self._update_rrule(**self._construct) + + def _update_rrule(self, **kwargs): + tzinfo = self._base_tzinfo + + # rrule does not play nicely with timezones - especially pytz time + # zones, it's best to use naive zones and attach timezones once the + # datetimes are returned + if 'dtstart' in kwargs: + dtstart = kwargs['dtstart'] + if dtstart.tzinfo is not None: + if tzinfo is None: + tzinfo = dtstart.tzinfo + else: + dtstart = dtstart.astimezone(tzinfo) + + kwargs['dtstart'] = dtstart.replace(tzinfo=None) + + if 'until' in kwargs: + until = kwargs['until'] + if until.tzinfo is not None: + if tzinfo is not None: + until = until.astimezone(tzinfo) + else: + raise ValueError('until cannot be aware if dtstart ' + 'is naive and tzinfo is None') + + kwargs['until'] = until.replace(tzinfo=None) + + self._construct = kwargs.copy() + self._tzinfo = tzinfo + self._rrule = rrule(**self._construct) + + def _attach_tzinfo(self, dt, tzinfo): + # pytz zones are attached by "localizing" the datetime + if hasattr(tzinfo, 'localize'): + return tzinfo.localize(dt, is_dst=True) + + return dt.replace(tzinfo=tzinfo) + + def _aware_return_wrapper(self, f, returns_list=False): + """Decorator function that allows rrule methods to handle tzinfo.""" + # This is only necessary if we're actually attaching a tzinfo + if self._tzinfo is None: + return f + + # All datetime arguments must be naive. If they are not naive, they are + # converted to the _tzinfo zone before dropping the zone. + def normalize_arg(arg): + if isinstance(arg, datetime.datetime) and arg.tzinfo is not None: + if arg.tzinfo is not self._tzinfo: + arg = arg.astimezone(self._tzinfo) + + return arg.replace(tzinfo=None) + + return arg + + def normalize_args(args, kwargs): + args = tuple(normalize_arg(arg) for arg in args) + kwargs = {kw: normalize_arg(arg) for kw, arg in kwargs.items()} + + return args, kwargs + + # There are two kinds of functions we care about - ones that return + # dates and ones that return lists of dates. + if not returns_list: + def inner_func(*args, **kwargs): + args, kwargs = normalize_args(args, kwargs) + dt = f(*args, **kwargs) + return self._attach_tzinfo(dt, self._tzinfo) + else: + def inner_func(*args, **kwargs): + args, kwargs = normalize_args(args, kwargs) + dts = f(*args, **kwargs) + return [self._attach_tzinfo(dt, self._tzinfo) for dt in dts] + + return functools.wraps(f)(inner_func) + + def __getattr__(self, name): + if name in self.__dict__: + return self.__dict__[name] + + f = getattr(self._rrule, name) + + if name in {'after', 'before'}: + return self._aware_return_wrapper(f) + elif name in {'xafter', 'xbefore', 'between'}: + return self._aware_return_wrapper(f, returns_list=True) + else: + return f + + def __setstate__(self, state): + self.__dict__.update(state) + + +class DateLocator(ticker.Locator): + """ + Determines the tick locations when plotting dates. + + This class is subclassed by other Locators and + is not meant to be used on its own. + """ + hms0d = {'byhour': 0, 'byminute': 0, 'bysecond': 0} + + def __init__(self, tz=None): + """ + Parameters + ---------- + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + self.tz = _get_tzinfo(tz) + + def set_tzinfo(self, tz): + """ + Set timezone info. + + Parameters + ---------- + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + self.tz = _get_tzinfo(tz) + + def datalim_to_dt(self): + """Convert axis data interval to datetime objects.""" + dmin, dmax = self.axis.get_data_interval() + if dmin > dmax: + dmin, dmax = dmax, dmin + + return num2date(dmin, self.tz), num2date(dmax, self.tz) + + def viewlim_to_dt(self): + """Convert the view interval to datetime objects.""" + vmin, vmax = self.axis.get_view_interval() + if vmin > vmax: + vmin, vmax = vmax, vmin + return num2date(vmin, self.tz), num2date(vmax, self.tz) + + def _get_unit(self): + """ + Return how many days a unit of the locator is; used for + intelligent autoscaling. + """ + return 1 + + def _get_interval(self): + """ + Return the number of units for each tick. + """ + return 1 + + def nonsingular(self, vmin, vmax): + """ + Given the proposed upper and lower extent, adjust the range + if it is too close to being singular (i.e. a range of ~0). + """ + if not np.isfinite(vmin) or not np.isfinite(vmax): + # Except if there is no data, then use 1970 as default. + return (date2num(datetime.date(1970, 1, 1)), + date2num(datetime.date(1970, 1, 2))) + if vmax < vmin: + vmin, vmax = vmax, vmin + unit = self._get_unit() + interval = self._get_interval() + if abs(vmax - vmin) < 1e-6: + vmin -= 2 * unit * interval + vmax += 2 * unit * interval + return vmin, vmax + + +class RRuleLocator(DateLocator): + # use the dateutil rrule instance + + def __init__(self, o, tz=None): + super().__init__(tz) + self.rule = o + + def __call__(self): + # if no data have been set, this will tank with a ValueError + try: + dmin, dmax = self.viewlim_to_dt() + except ValueError: + return [] + + return self.tick_values(dmin, dmax) + + def tick_values(self, vmin, vmax): + start, stop = self._create_rrule(vmin, vmax) + dates = self.rule.between(start, stop, True) + if len(dates) == 0: + return date2num([vmin, vmax]) + return self.raise_if_exceeds(date2num(dates)) + + def _create_rrule(self, vmin, vmax): + # set appropriate rrule dtstart and until and return + # start and end + delta = relativedelta(vmax, vmin) + + # We need to cap at the endpoints of valid datetime + try: + start = vmin - delta + except (ValueError, OverflowError): + # cap + start = datetime.datetime(1, 1, 1, 0, 0, 0, + tzinfo=datetime.timezone.utc) + + try: + stop = vmax + delta + except (ValueError, OverflowError): + # cap + stop = datetime.datetime(9999, 12, 31, 23, 59, 59, + tzinfo=datetime.timezone.utc) + + self.rule.set(dtstart=start, until=stop) + + return vmin, vmax + + def _get_unit(self): + # docstring inherited + freq = self.rule._rrule._freq + return self.get_unit_generic(freq) + + @staticmethod + def get_unit_generic(freq): + if freq == YEARLY: + return DAYS_PER_YEAR + elif freq == MONTHLY: + return DAYS_PER_MONTH + elif freq == WEEKLY: + return DAYS_PER_WEEK + elif freq == DAILY: + return 1.0 + elif freq == HOURLY: + return 1.0 / HOURS_PER_DAY + elif freq == MINUTELY: + return 1.0 / MINUTES_PER_DAY + elif freq == SECONDLY: + return 1.0 / SEC_PER_DAY + else: + # error + return -1 # or should this just return '1'? + + def _get_interval(self): + return self.rule._rrule._interval + + +class AutoDateLocator(DateLocator): + """ + On autoscale, this class picks the best `DateLocator` to set the view + limits and the tick locations. + + Attributes + ---------- + intervald : dict + + Mapping of tick frequencies to multiples allowed for that ticking. + The default is :: + + self.intervald = { + YEARLY : [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500, + 1000, 2000, 4000, 5000, 10000], + MONTHLY : [1, 2, 3, 4, 6], + DAILY : [1, 2, 3, 7, 14, 21], + HOURLY : [1, 2, 3, 4, 6, 12], + MINUTELY: [1, 5, 10, 15, 30], + SECONDLY: [1, 5, 10, 15, 30], + MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, + 1000, 2000, 5000, 10000, 20000, 50000, + 100000, 200000, 500000, 1000000], + } + + where the keys are defined in `dateutil.rrule`. + + The interval is used to specify multiples that are appropriate for + the frequency of ticking. For instance, every 7 days is sensible + for daily ticks, but for minutes/seconds, 15 or 30 make sense. + + When customizing, you should only modify the values for the existing + keys. You should not add or delete entries. + + Example for forcing ticks every 3 hours:: + + locator = AutoDateLocator() + locator.intervald[HOURLY] = [3] # only show every 3 hours + """ + + def __init__(self, tz=None, minticks=5, maxticks=None, + interval_multiples=True): + """ + Parameters + ---------- + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + minticks : int + The minimum number of ticks desired; controls whether ticks occur + yearly, monthly, etc. + maxticks : int + The maximum number of ticks desired; controls the interval between + ticks (ticking every other, every 3, etc.). For fine-grained + control, this can be a dictionary mapping individual rrule + frequency constants (YEARLY, MONTHLY, etc.) to their own maximum + number of ticks. This can be used to keep the number of ticks + appropriate to the format chosen in `AutoDateFormatter`. Any + frequency not specified in this dictionary is given a default + value. + interval_multiples : bool, default: True + Whether ticks should be chosen to be multiple of the interval, + locking them to 'nicer' locations. For example, this will force + the ticks to be at hours 0, 6, 12, 18 when hourly ticking is done + at 6 hour intervals. + """ + super().__init__(tz=tz) + self._freq = YEARLY + self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY, + SECONDLY, MICROSECONDLY] + self.minticks = minticks + + self.maxticks = {YEARLY: 11, MONTHLY: 12, DAILY: 11, HOURLY: 12, + MINUTELY: 11, SECONDLY: 11, MICROSECONDLY: 8} + if maxticks is not None: + try: + self.maxticks.update(maxticks) + except TypeError: + # Assume we were given an integer. Use this as the maximum + # number of ticks for every frequency and create a + # dictionary for this + self.maxticks = dict.fromkeys(self._freqs, maxticks) + self.interval_multiples = interval_multiples + self.intervald = { + YEARLY: [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500, + 1000, 2000, 4000, 5000, 10000], + MONTHLY: [1, 2, 3, 4, 6], + DAILY: [1, 2, 3, 7, 14, 21], + HOURLY: [1, 2, 3, 4, 6, 12], + MINUTELY: [1, 5, 10, 15, 30], + SECONDLY: [1, 5, 10, 15, 30], + MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, + 5000, 10000, 20000, 50000, 100000, 200000, 500000, + 1000000], + } + if interval_multiples: + # Swap "3" for "4" in the DAILY list; If we use 3 we get bad + # tick loc for months w/ 31 days: 1, 4, ..., 28, 31, 1 + # If we use 4 then we get: 1, 5, ... 25, 29, 1 + self.intervald[DAILY] = [1, 2, 4, 7, 14] + + self._byranges = [None, range(1, 13), range(1, 32), + range(0, 24), range(0, 60), range(0, 60), None] + + def __call__(self): + # docstring inherited + dmin, dmax = self.viewlim_to_dt() + locator = self.get_locator(dmin, dmax) + return locator() + + def tick_values(self, vmin, vmax): + return self.get_locator(vmin, vmax).tick_values(vmin, vmax) + + def nonsingular(self, vmin, vmax): + # whatever is thrown at us, we can scale the unit. + # But default nonsingular date plots at an ~4 year period. + if not np.isfinite(vmin) or not np.isfinite(vmax): + # Except if there is no data, then use 1970 as default. + return (date2num(datetime.date(1970, 1, 1)), + date2num(datetime.date(1970, 1, 2))) + if vmax < vmin: + vmin, vmax = vmax, vmin + if vmin == vmax: + vmin = vmin - DAYS_PER_YEAR * 2 + vmax = vmax + DAYS_PER_YEAR * 2 + return vmin, vmax + + def _get_unit(self): + if self._freq in [MICROSECONDLY]: + return 1. / MUSECONDS_PER_DAY + else: + return RRuleLocator.get_unit_generic(self._freq) + + def get_locator(self, dmin, dmax): + """Pick the best locator based on a distance.""" + delta = relativedelta(dmax, dmin) + tdelta = dmax - dmin + + # take absolute difference + if dmin > dmax: + delta = -delta + tdelta = -tdelta + # The following uses a mix of calls to relativedelta and timedelta + # methods because there is incomplete overlap in the functionality of + # these similar functions, and it's best to avoid doing our own math + # whenever possible. + numYears = float(delta.years) + numMonths = numYears * MONTHS_PER_YEAR + delta.months + numDays = tdelta.days # Avoids estimates of days/month, days/year. + numHours = numDays * HOURS_PER_DAY + delta.hours + numMinutes = numHours * MIN_PER_HOUR + delta.minutes + numSeconds = np.floor(tdelta.total_seconds()) + numMicroseconds = np.floor(tdelta.total_seconds() * 1e6) + + nums = [numYears, numMonths, numDays, numHours, numMinutes, + numSeconds, numMicroseconds] + + use_rrule_locator = [True] * 6 + [False] + + # Default setting of bymonth, etc. to pass to rrule + # [unused (for year), bymonth, bymonthday, byhour, byminute, + # bysecond, unused (for microseconds)] + byranges = [None, 1, 1, 0, 0, 0, None] + + # Loop over all the frequencies and try to find one that gives at + # least a minticks tick positions. Once this is found, look for + # an interval from a list specific to that frequency that gives no + # more than maxticks tick positions. Also, set up some ranges + # (bymonth, etc.) as appropriate to be passed to rrulewrapper. + for i, (freq, num) in enumerate(zip(self._freqs, nums)): + # If this particular frequency doesn't give enough ticks, continue + if num < self.minticks: + # Since we're not using this particular frequency, set + # the corresponding by_ to None so the rrule can act as + # appropriate + byranges[i] = None + continue + + # Find the first available interval that doesn't give too many + # ticks + for interval in self.intervald[freq]: + if num <= interval * (self.maxticks[freq] - 1): + break + else: + if not (self.interval_multiples and freq == DAILY): + _api.warn_external( + f"AutoDateLocator was unable to pick an appropriate " + f"interval for this date range. It may be necessary " + f"to add an interval value to the AutoDateLocator's " + f"intervald dictionary. Defaulting to {interval}.") + + # Set some parameters as appropriate + self._freq = freq + + if self._byranges[i] and self.interval_multiples: + byranges[i] = self._byranges[i][::interval] + if i in (DAILY, WEEKLY): + if interval == 14: + # just make first and 15th. Avoids 30th. + byranges[i] = [1, 15] + elif interval == 7: + byranges[i] = [1, 8, 15, 22] + + interval = 1 + else: + byranges[i] = self._byranges[i] + break + else: + interval = 1 + + if (freq == YEARLY) and self.interval_multiples: + locator = YearLocator(interval, tz=self.tz) + elif use_rrule_locator[i]: + _, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges + rrule = rrulewrapper(self._freq, interval=interval, + dtstart=dmin, until=dmax, + bymonth=bymonth, bymonthday=bymonthday, + byhour=byhour, byminute=byminute, + bysecond=bysecond) + + locator = RRuleLocator(rrule, tz=self.tz) + else: + locator = MicrosecondLocator(interval, tz=self.tz) + if date2num(dmin) > 70 * 365 and interval < 1000: + _api.warn_external( + 'Plotting microsecond time intervals for dates far from ' + f'the epoch (time origin: {get_epoch()}) is not well-' + 'supported. See matplotlib.dates.set_epoch to change the ' + 'epoch.') + + locator.set_axis(self.axis) + return locator + + +class YearLocator(RRuleLocator): + """ + Make ticks on a given day of each year that is a multiple of base. + + Examples:: + + # Tick every year on Jan 1st + locator = YearLocator() + + # Tick every 5 years on July 4th + locator = YearLocator(5, month=7, day=4) + """ + def __init__(self, base=1, month=1, day=1, tz=None): + """ + Parameters + ---------- + base : int, default: 1 + Mark ticks every *base* years. + month : int, default: 1 + The month on which to place the ticks, starting from 1. Default is + January. + day : int, default: 1 + The day on which to place the ticks. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + rule = rrulewrapper(YEARLY, interval=base, bymonth=month, + bymonthday=day, **self.hms0d) + super().__init__(rule, tz=tz) + self.base = ticker._Edge_integer(base, 0) + + def _create_rrule(self, vmin, vmax): + # 'start' needs to be a multiple of the interval to create ticks on + # interval multiples when the tick frequency is YEARLY + ymin = max(self.base.le(vmin.year) * self.base.step, 1) + ymax = min(self.base.ge(vmax.year) * self.base.step, 9999) + + c = self.rule._construct + replace = {'year': ymin, + 'month': c.get('bymonth', 1), + 'day': c.get('bymonthday', 1), + 'hour': 0, 'minute': 0, 'second': 0} + + start = vmin.replace(**replace) + stop = start.replace(year=ymax) + self.rule.set(dtstart=start, until=stop) + + return start, stop + + +class MonthLocator(RRuleLocator): + """ + Make ticks on occurrences of each month, e.g., 1, 3, 12. + """ + def __init__(self, bymonth=None, bymonthday=1, interval=1, tz=None): + """ + Parameters + ---------- + bymonth : int or list of int, default: all months + Ticks will be placed on every month in *bymonth*. Default is + ``range(1, 13)``, i.e. every month. + bymonthday : int, default: 1 + The day on which to place the ticks. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + if bymonth is None: + bymonth = range(1, 13) + + rule = rrulewrapper(MONTHLY, bymonth=bymonth, bymonthday=bymonthday, + interval=interval, **self.hms0d) + super().__init__(rule, tz=tz) + + +class WeekdayLocator(RRuleLocator): + """ + Make ticks on occurrences of each weekday. + """ + + def __init__(self, byweekday=1, interval=1, tz=None): + """ + Parameters + ---------- + byweekday : int or list of int, default: all days + Ticks will be placed on every weekday in *byweekday*. Default is + every day. + + Elements of *byweekday* must be one of MO, TU, WE, TH, FR, SA, + SU, the constants from :mod:`dateutil.rrule`, which have been + imported into the :mod:`matplotlib.dates` namespace. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + rule = rrulewrapper(DAILY, byweekday=byweekday, + interval=interval, **self.hms0d) + super().__init__(rule, tz=tz) + + +class DayLocator(RRuleLocator): + """ + Make ticks on occurrences of each day of the month. For example, + 1, 15, 30. + """ + def __init__(self, bymonthday=None, interval=1, tz=None): + """ + Parameters + ---------- + bymonthday : int or list of int, default: all days + Ticks will be placed on every day in *bymonthday*. Default is + ``bymonthday=range(1, 32)``, i.e., every day of the month. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + if interval != int(interval) or interval < 1: + raise ValueError("interval must be an integer greater than 0") + if bymonthday is None: + bymonthday = range(1, 32) + + rule = rrulewrapper(DAILY, bymonthday=bymonthday, + interval=interval, **self.hms0d) + super().__init__(rule, tz=tz) + + +class HourLocator(RRuleLocator): + """ + Make ticks on occurrences of each hour. + """ + def __init__(self, byhour=None, interval=1, tz=None): + """ + Parameters + ---------- + byhour : int or list of int, default: all hours + Ticks will be placed on every hour in *byhour*. Default is + ``byhour=range(24)``, i.e., every hour. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + if byhour is None: + byhour = range(24) + + rule = rrulewrapper(HOURLY, byhour=byhour, interval=interval, + byminute=0, bysecond=0) + super().__init__(rule, tz=tz) + + +class MinuteLocator(RRuleLocator): + """ + Make ticks on occurrences of each minute. + """ + def __init__(self, byminute=None, interval=1, tz=None): + """ + Parameters + ---------- + byminute : int or list of int, default: all minutes + Ticks will be placed on every minute in *byminute*. Default is + ``byminute=range(60)``, i.e., every minute. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + if byminute is None: + byminute = range(60) + + rule = rrulewrapper(MINUTELY, byminute=byminute, interval=interval, + bysecond=0) + super().__init__(rule, tz=tz) + + +class SecondLocator(RRuleLocator): + """ + Make ticks on occurrences of each second. + """ + def __init__(self, bysecond=None, interval=1, tz=None): + """ + Parameters + ---------- + bysecond : int or list of int, default: all seconds + Ticks will be placed on every second in *bysecond*. Default is + ``bysecond = range(60)``, i.e., every second. + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + if bysecond is None: + bysecond = range(60) + + rule = rrulewrapper(SECONDLY, bysecond=bysecond, interval=interval) + super().__init__(rule, tz=tz) + + +class MicrosecondLocator(DateLocator): + """ + Make ticks on regular intervals of one or more microsecond(s). + + .. note:: + + By default, Matplotlib uses a floating point representation of time in + days since the epoch, so plotting data with + microsecond time resolution does not work well for + dates that are far (about 70 years) from the epoch (check with + `~.dates.get_epoch`). + + If you want sub-microsecond resolution time plots, it is strongly + recommended to use floating point seconds, not datetime-like + time representation. + + If you really must use datetime.datetime() or similar and still + need microsecond precision, change the time origin via + `.dates.set_epoch` to something closer to the dates being plotted. + See :doc:`/gallery/ticks/date_precision_and_epochs`. + + """ + def __init__(self, interval=1, tz=None): + """ + Parameters + ---------- + interval : int, default: 1 + The interval between each iteration. For example, if + ``interval=2``, mark every second occurrence. + tz : str or `~datetime.tzinfo`, default: :rc:`timezone` + Ticks timezone. If a string, *tz* is passed to `dateutil.tz`. + """ + super().__init__(tz=tz) + self._interval = interval + self._wrapped_locator = ticker.MultipleLocator(interval) + + def set_axis(self, axis): + self._wrapped_locator.set_axis(axis) + return super().set_axis(axis) + + def __call__(self): + # if no data have been set, this will tank with a ValueError + try: + dmin, dmax = self.viewlim_to_dt() + except ValueError: + return [] + + return self.tick_values(dmin, dmax) + + def tick_values(self, vmin, vmax): + nmin, nmax = date2num((vmin, vmax)) + t0 = np.floor(nmin) + nmax = nmax - t0 + nmin = nmin - t0 + nmin *= MUSECONDS_PER_DAY + nmax *= MUSECONDS_PER_DAY + + ticks = self._wrapped_locator.tick_values(nmin, nmax) + + ticks = ticks / MUSECONDS_PER_DAY + t0 + return ticks + + def _get_unit(self): + # docstring inherited + return 1. / MUSECONDS_PER_DAY + + def _get_interval(self): + # docstring inherited + return self._interval + + +class DateConverter(units.ConversionInterface): + """ + Converter for `datetime.date` and `datetime.datetime` data, or for + date/time data represented as it would be converted by `date2num`. + + The 'unit' tag for such data is None or a `~datetime.tzinfo` instance. + """ + + def __init__(self, *, interval_multiples=True): + self._interval_multiples = interval_multiples + super().__init__() + + def axisinfo(self, unit, axis): + """ + Return the `~matplotlib.units.AxisInfo` for *unit*. + + *unit* is a `~datetime.tzinfo` instance or None. + The *axis* argument is required but not used. + """ + tz = unit + + majloc = AutoDateLocator(tz=tz, + interval_multiples=self._interval_multiples) + majfmt = AutoDateFormatter(majloc, tz=tz) + datemin = datetime.date(1970, 1, 1) + datemax = datetime.date(1970, 1, 2) + + return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='', + default_limits=(datemin, datemax)) + + @staticmethod + def convert(value, unit, axis): + """ + If *value* is not already a number or sequence of numbers, convert it + with `date2num`. + + The *unit* and *axis* arguments are not used. + """ + return date2num(value) + + @staticmethod + def default_units(x, axis): + """ + Return the `~datetime.tzinfo` instance of *x* or of its first element, + or None + """ + if isinstance(x, np.ndarray): + x = x.ravel() + + try: + x = cbook._safe_first_finite(x) + except (TypeError, StopIteration): + pass + + try: + return x.tzinfo + except AttributeError: + pass + return None + + +class ConciseDateConverter(DateConverter): + # docstring inherited + + def __init__(self, formats=None, zero_formats=None, offset_formats=None, + show_offset=True, *, interval_multiples=True): + self._formats = formats + self._zero_formats = zero_formats + self._offset_formats = offset_formats + self._show_offset = show_offset + self._interval_multiples = interval_multiples + super().__init__() + + def axisinfo(self, unit, axis): + # docstring inherited + tz = unit + majloc = AutoDateLocator(tz=tz, + interval_multiples=self._interval_multiples) + majfmt = ConciseDateFormatter(majloc, tz=tz, formats=self._formats, + zero_formats=self._zero_formats, + offset_formats=self._offset_formats, + show_offset=self._show_offset) + datemin = datetime.date(1970, 1, 1) + datemax = datetime.date(1970, 1, 2) + return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='', + default_limits=(datemin, datemax)) + + +class _SwitchableDateConverter: + """ + Helper converter-like object that generates and dispatches to + temporary ConciseDateConverter or DateConverter instances based on + :rc:`date.converter` and :rc:`date.interval_multiples`. + """ + + @staticmethod + def _get_converter(): + converter_cls = { + "concise": ConciseDateConverter, "auto": DateConverter}[ + mpl.rcParams["date.converter"]] + interval_multiples = mpl.rcParams["date.interval_multiples"] + return converter_cls(interval_multiples=interval_multiples) + + def axisinfo(self, *args, **kwargs): + return self._get_converter().axisinfo(*args, **kwargs) + + def default_units(self, *args, **kwargs): + return self._get_converter().default_units(*args, **kwargs) + + def convert(self, *args, **kwargs): + return self._get_converter().convert(*args, **kwargs) + + +units.registry[np.datetime64] = \ + units.registry[datetime.date] = \ + units.registry[datetime.datetime] = \ + _SwitchableDateConverter() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.py new file mode 100644 index 00000000..b2177e50 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.py @@ -0,0 +1,1149 @@ +""" +A module for reading dvi files output by TeX. Several limitations make +this not (currently) useful as a general-purpose dvi preprocessor, but +it is currently used by the pdf backend for processing usetex text. + +Interface:: + + with Dvi(filename, 72) as dvi: + # iterate over pages: + for page in dvi: + w, h, d = page.width, page.height, page.descent + for x, y, font, glyph, width in page.text: + fontname = font.texname + pointsize = font.size + ... + for x, y, height, width in page.boxes: + ... +""" + +from collections import namedtuple +import enum +from functools import lru_cache, partial, wraps +import logging +import os +from pathlib import Path +import re +import struct +import subprocess +import sys + +import numpy as np + +from matplotlib import _api, cbook + +_log = logging.getLogger(__name__) + +# Many dvi related files are looked for by external processes, require +# additional parsing, and are used many times per rendering, which is why they +# are cached using lru_cache(). + +# Dvi is a bytecode format documented in +# https://ctan.org/pkg/dvitype +# https://texdoc.org/serve/dvitype.pdf/0 +# +# The file consists of a preamble, some number of pages, a postamble, +# and a finale. Different opcodes are allowed in different contexts, +# so the Dvi object has a parser state: +# +# pre: expecting the preamble +# outer: between pages (followed by a page or the postamble, +# also e.g. font definitions are allowed) +# page: processing a page +# post_post: state after the postamble (our current implementation +# just stops reading) +# finale: the finale (unimplemented in our current implementation) + +_dvistate = enum.Enum('DviState', 'pre outer inpage post_post finale') + +# The marks on a page consist of text and boxes. A page also has dimensions. +Page = namedtuple('Page', 'text boxes height width descent') +Box = namedtuple('Box', 'x y height width') + + +# Also a namedtuple, for backcompat. +class Text(namedtuple('Text', 'x y font glyph width')): + """ + A glyph in the dvi file. + + The *x* and *y* attributes directly position the glyph. The *font*, + *glyph*, and *width* attributes are kept public for back-compatibility, + but users wanting to draw the glyph themselves are encouraged to instead + load the font specified by `font_path` at `font_size`, warp it with the + effects specified by `font_effects`, and load the glyph specified by + `glyph_name_or_index`. + """ + + def _get_pdftexmap_entry(self): + return PsfontsMap(find_tex_file("pdftex.map"))[self.font.texname] + + @property + def font_path(self): + """The `~pathlib.Path` to the font for this glyph.""" + psfont = self._get_pdftexmap_entry() + if psfont.filename is None: + raise ValueError("No usable font file found for {} ({}); " + "the font may lack a Type-1 version" + .format(psfont.psname.decode("ascii"), + psfont.texname.decode("ascii"))) + return Path(psfont.filename) + + @property + def font_size(self): + """The font size.""" + return self.font.size + + @property + def font_effects(self): + """ + The "font effects" dict for this glyph. + + This dict contains the values for this glyph of SlantFont and + ExtendFont (if any), read off :file:`pdftex.map`. + """ + return self._get_pdftexmap_entry().effects + + @property + def glyph_name_or_index(self): + """ + Either the glyph name or the native charmap glyph index. + + If :file:`pdftex.map` specifies an encoding for this glyph's font, that + is a mapping of glyph indices to Adobe glyph names; use it to convert + dvi indices to glyph names. Callers can then convert glyph names to + glyph indices (with FT_Get_Name_Index/get_name_index), and load the + glyph using FT_Load_Glyph/load_glyph. + + If :file:`pdftex.map` specifies no encoding, the indices directly map + to the font's "native" charmap; glyphs should directly load using + FT_Load_Char/load_char after selecting the native charmap. + """ + entry = self._get_pdftexmap_entry() + return (_parse_enc(entry.encoding)[self.glyph] + if entry.encoding is not None else self.glyph) + + +# Opcode argument parsing +# +# Each of the following functions takes a Dvi object and delta, +# which is the difference between the opcode and the minimum opcode +# with the same meaning. Dvi opcodes often encode the number of +# argument bytes in this delta. + +def _arg_raw(dvi, delta): + """Return *delta* without reading anything more from the dvi file.""" + return delta + + +def _arg(nbytes, signed, dvi, _): + """ + Read *nbytes* bytes, returning the bytes interpreted as a signed integer + if *signed* is true, unsigned otherwise. + """ + return dvi._arg(nbytes, signed) + + +def _arg_slen(dvi, delta): + """ + Read *delta* bytes, returning None if *delta* is zero, and the bytes + interpreted as a signed integer otherwise. + """ + if delta == 0: + return None + return dvi._arg(delta, True) + + +def _arg_slen1(dvi, delta): + """ + Read *delta*+1 bytes, returning the bytes interpreted as signed. + """ + return dvi._arg(delta + 1, True) + + +def _arg_ulen1(dvi, delta): + """ + Read *delta*+1 bytes, returning the bytes interpreted as unsigned. + """ + return dvi._arg(delta + 1, False) + + +def _arg_olen1(dvi, delta): + """ + Read *delta*+1 bytes, returning the bytes interpreted as + unsigned integer for 0<=*delta*<3 and signed if *delta*==3. + """ + return dvi._arg(delta + 1, delta == 3) + + +_arg_mapping = dict(raw=_arg_raw, + u1=partial(_arg, 1, False), + u4=partial(_arg, 4, False), + s4=partial(_arg, 4, True), + slen=_arg_slen, + olen1=_arg_olen1, + slen1=_arg_slen1, + ulen1=_arg_ulen1) + + +def _dispatch(table, min, max=None, state=None, args=('raw',)): + """ + Decorator for dispatch by opcode. Sets the values in *table* + from *min* to *max* to this method, adds a check that the Dvi state + matches *state* if not None, reads arguments from the file according + to *args*. + + Parameters + ---------- + table : dict[int, callable] + The dispatch table to be filled in. + + min, max : int + Range of opcodes that calls the registered function; *max* defaults to + *min*. + + state : _dvistate, optional + State of the Dvi object in which these opcodes are allowed. + + args : list[str], default: ['raw'] + Sequence of argument specifications: + + - 'raw': opcode minus minimum + - 'u1': read one unsigned byte + - 'u4': read four bytes, treat as an unsigned number + - 's4': read four bytes, treat as a signed number + - 'slen': read (opcode - minimum) bytes, treat as signed + - 'slen1': read (opcode - minimum + 1) bytes, treat as signed + - 'ulen1': read (opcode - minimum + 1) bytes, treat as unsigned + - 'olen1': read (opcode - minimum + 1) bytes, treat as unsigned + if under four bytes, signed if four bytes + """ + def decorate(method): + get_args = [_arg_mapping[x] for x in args] + + @wraps(method) + def wrapper(self, byte): + if state is not None and self.state != state: + raise ValueError("state precondition failed") + return method(self, *[f(self, byte-min) for f in get_args]) + if max is None: + table[min] = wrapper + else: + for i in range(min, max+1): + assert table[i] is None + table[i] = wrapper + return wrapper + return decorate + + +class Dvi: + """ + A reader for a dvi ("device-independent") file, as produced by TeX. + + The current implementation can only iterate through pages in order, + and does not even attempt to verify the postamble. + + This class can be used as a context manager to close the underlying + file upon exit. Pages can be read via iteration. Here is an overly + simple way to extract text without trying to detect whitespace:: + + >>> with matplotlib.dviread.Dvi('input.dvi', 72) as dvi: + ... for page in dvi: + ... print(''.join(chr(t.glyph) for t in page.text)) + """ + # dispatch table + _dtable = [None] * 256 + _dispatch = partial(_dispatch, _dtable) + + def __init__(self, filename, dpi): + """ + Read the data from the file named *filename* and convert + TeX's internal units to units of *dpi* per inch. + *dpi* only sets the units and does not limit the resolution. + Use None to return TeX's internal units. + """ + _log.debug('Dvi: %s', filename) + self.file = open(filename, 'rb') + self.dpi = dpi + self.fonts = {} + self.state = _dvistate.pre + + def __enter__(self): + """Context manager enter method, does nothing.""" + return self + + def __exit__(self, etype, evalue, etrace): + """ + Context manager exit method, closes the underlying file if it is open. + """ + self.close() + + def __iter__(self): + """ + Iterate through the pages of the file. + + Yields + ------ + Page + Details of all the text and box objects on the page. + The Page tuple contains lists of Text and Box tuples and + the page dimensions, and the Text and Box tuples contain + coordinates transformed into a standard Cartesian + coordinate system at the dpi value given when initializing. + The coordinates are floating point numbers, but otherwise + precision is not lost and coordinate values are not clipped to + integers. + """ + while self._read(): + yield self._output() + + def close(self): + """Close the underlying file if it is open.""" + if not self.file.closed: + self.file.close() + + def _output(self): + """ + Output the text and boxes belonging to the most recent page. + page = dvi._output() + """ + minx, miny, maxx, maxy = np.inf, np.inf, -np.inf, -np.inf + maxy_pure = -np.inf + for elt in self.text + self.boxes: + if isinstance(elt, Box): + x, y, h, w = elt + e = 0 # zero depth + else: # glyph + x, y, font, g, w = elt + h, e = font._height_depth_of(g) + minx = min(minx, x) + miny = min(miny, y - h) + maxx = max(maxx, x + w) + maxy = max(maxy, y + e) + maxy_pure = max(maxy_pure, y) + if self._baseline_v is not None: + maxy_pure = self._baseline_v # This should normally be the case. + self._baseline_v = None + + if not self.text and not self.boxes: # Avoid infs/nans from inf+/-inf. + return Page(text=[], boxes=[], width=0, height=0, descent=0) + + if self.dpi is None: + # special case for ease of debugging: output raw dvi coordinates + return Page(text=self.text, boxes=self.boxes, + width=maxx-minx, height=maxy_pure-miny, + descent=maxy-maxy_pure) + + # convert from TeX's "scaled points" to dpi units + d = self.dpi / (72.27 * 2**16) + descent = (maxy - maxy_pure) * d + + text = [Text((x-minx)*d, (maxy-y)*d - descent, f, g, w*d) + for (x, y, f, g, w) in self.text] + boxes = [Box((x-minx)*d, (maxy-y)*d - descent, h*d, w*d) + for (x, y, h, w) in self.boxes] + + return Page(text=text, boxes=boxes, width=(maxx-minx)*d, + height=(maxy_pure-miny)*d, descent=descent) + + def _read(self): + """ + Read one page from the file. Return True if successful, + False if there were no more pages. + """ + # Pages appear to start with the sequence + # bop (begin of page) + # xxx comment + # # if using chemformula + # down + # push + # down + # # if using xcolor + # down + # push + # down (possibly multiple) + # push <= here, v is the baseline position. + # etc. + # (dviasm is useful to explore this structure.) + # Thus, we use the vertical position at the first time the stack depth + # reaches 3, while at least three "downs" have been executed (excluding + # those popped out (corresponding to the chemformula preamble)), as the + # baseline (the "down" count is necessary to handle xcolor). + down_stack = [0] + self._baseline_v = None + while True: + byte = self.file.read(1)[0] + self._dtable[byte](self, byte) + name = self._dtable[byte].__name__ + if name == "_push": + down_stack.append(down_stack[-1]) + elif name == "_pop": + down_stack.pop() + elif name == "_down": + down_stack[-1] += 1 + if (self._baseline_v is None + and len(getattr(self, "stack", [])) == 3 + and down_stack[-1] >= 4): + self._baseline_v = self.v + if byte == 140: # end of page + return True + if self.state is _dvistate.post_post: # end of file + self.close() + return False + + def _arg(self, nbytes, signed=False): + """ + Read and return an integer argument *nbytes* long. + Signedness is determined by the *signed* keyword. + """ + buf = self.file.read(nbytes) + value = buf[0] + if signed and value >= 0x80: + value = value - 0x100 + for b in buf[1:]: + value = 0x100*value + b + return value + + @_dispatch(min=0, max=127, state=_dvistate.inpage) + def _set_char_immediate(self, char): + self._put_char_real(char) + self.h += self.fonts[self.f]._width_of(char) + + @_dispatch(min=128, max=131, state=_dvistate.inpage, args=('olen1',)) + def _set_char(self, char): + self._put_char_real(char) + self.h += self.fonts[self.f]._width_of(char) + + @_dispatch(132, state=_dvistate.inpage, args=('s4', 's4')) + def _set_rule(self, a, b): + self._put_rule_real(a, b) + self.h += b + + @_dispatch(min=133, max=136, state=_dvistate.inpage, args=('olen1',)) + def _put_char(self, char): + self._put_char_real(char) + + def _put_char_real(self, char): + font = self.fonts[self.f] + if font._vf is None: + self.text.append(Text(self.h, self.v, font, char, + font._width_of(char))) + else: + scale = font._scale + for x, y, f, g, w in font._vf[char].text: + newf = DviFont(scale=_mul2012(scale, f._scale), + tfm=f._tfm, texname=f.texname, vf=f._vf) + self.text.append(Text(self.h + _mul2012(x, scale), + self.v + _mul2012(y, scale), + newf, g, newf._width_of(g))) + self.boxes.extend([Box(self.h + _mul2012(x, scale), + self.v + _mul2012(y, scale), + _mul2012(a, scale), _mul2012(b, scale)) + for x, y, a, b in font._vf[char].boxes]) + + @_dispatch(137, state=_dvistate.inpage, args=('s4', 's4')) + def _put_rule(self, a, b): + self._put_rule_real(a, b) + + def _put_rule_real(self, a, b): + if a > 0 and b > 0: + self.boxes.append(Box(self.h, self.v, a, b)) + + @_dispatch(138) + def _nop(self, _): + pass + + @_dispatch(139, state=_dvistate.outer, args=('s4',)*11) + def _bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p): + self.state = _dvistate.inpage + self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0 + self.stack = [] + self.text = [] # list of Text objects + self.boxes = [] # list of Box objects + + @_dispatch(140, state=_dvistate.inpage) + def _eop(self, _): + self.state = _dvistate.outer + del self.h, self.v, self.w, self.x, self.y, self.z, self.stack + + @_dispatch(141, state=_dvistate.inpage) + def _push(self, _): + self.stack.append((self.h, self.v, self.w, self.x, self.y, self.z)) + + @_dispatch(142, state=_dvistate.inpage) + def _pop(self, _): + self.h, self.v, self.w, self.x, self.y, self.z = self.stack.pop() + + @_dispatch(min=143, max=146, state=_dvistate.inpage, args=('slen1',)) + def _right(self, b): + self.h += b + + @_dispatch(min=147, max=151, state=_dvistate.inpage, args=('slen',)) + def _right_w(self, new_w): + if new_w is not None: + self.w = new_w + self.h += self.w + + @_dispatch(min=152, max=156, state=_dvistate.inpage, args=('slen',)) + def _right_x(self, new_x): + if new_x is not None: + self.x = new_x + self.h += self.x + + @_dispatch(min=157, max=160, state=_dvistate.inpage, args=('slen1',)) + def _down(self, a): + self.v += a + + @_dispatch(min=161, max=165, state=_dvistate.inpage, args=('slen',)) + def _down_y(self, new_y): + if new_y is not None: + self.y = new_y + self.v += self.y + + @_dispatch(min=166, max=170, state=_dvistate.inpage, args=('slen',)) + def _down_z(self, new_z): + if new_z is not None: + self.z = new_z + self.v += self.z + + @_dispatch(min=171, max=234, state=_dvistate.inpage) + def _fnt_num_immediate(self, k): + self.f = k + + @_dispatch(min=235, max=238, state=_dvistate.inpage, args=('olen1',)) + def _fnt_num(self, new_f): + self.f = new_f + + @_dispatch(min=239, max=242, args=('ulen1',)) + def _xxx(self, datalen): + special = self.file.read(datalen) + _log.debug( + 'Dvi._xxx: encountered special: %s', + ''.join([chr(ch) if 32 <= ch < 127 else '<%02x>' % ch + for ch in special])) + + @_dispatch(min=243, max=246, args=('olen1', 'u4', 'u4', 'u4', 'u1', 'u1')) + def _fnt_def(self, k, c, s, d, a, l): + self._fnt_def_real(k, c, s, d, a, l) + + def _fnt_def_real(self, k, c, s, d, a, l): + n = self.file.read(a + l) + fontname = n[-l:].decode('ascii') + tfm = _tfmfile(fontname) + if c != 0 and tfm.checksum != 0 and c != tfm.checksum: + raise ValueError('tfm checksum mismatch: %s' % n) + try: + vf = _vffile(fontname) + except FileNotFoundError: + vf = None + self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf) + + @_dispatch(247, state=_dvistate.pre, args=('u1', 'u4', 'u4', 'u4', 'u1')) + def _pre(self, i, num, den, mag, k): + self.file.read(k) # comment in the dvi file + if i != 2: + raise ValueError("Unknown dvi format %d" % i) + if num != 25400000 or den != 7227 * 2**16: + raise ValueError("Nonstandard units in dvi file") + # meaning: TeX always uses those exact values, so it + # should be enough for us to support those + # (There are 72.27 pt to an inch so 7227 pt = + # 7227 * 2**16 sp to 100 in. The numerator is multiplied + # by 10^5 to get units of 10**-7 meters.) + if mag != 1000: + raise ValueError("Nonstandard magnification in dvi file") + # meaning: LaTeX seems to frown on setting \mag, so + # I think we can assume this is constant + self.state = _dvistate.outer + + @_dispatch(248, state=_dvistate.outer) + def _post(self, _): + self.state = _dvistate.post_post + # TODO: actually read the postamble and finale? + # currently post_post just triggers closing the file + + @_dispatch(249) + def _post_post(self, _): + raise NotImplementedError + + @_dispatch(min=250, max=255) + def _malformed(self, offset): + raise ValueError(f"unknown command: byte {250 + offset}") + + +class DviFont: + """ + Encapsulation of a font that a DVI file can refer to. + + This class holds a font's texname and size, supports comparison, + and knows the widths of glyphs in the same units as the AFM file. + There are also internal attributes (for use by dviread.py) that + are *not* used for comparison. + + The size is in Adobe points (converted from TeX points). + + Parameters + ---------- + scale : float + Factor by which the font is scaled from its natural size. + tfm : Tfm + TeX font metrics for this font + texname : bytes + Name of the font as used internally by TeX and friends, as an ASCII + bytestring. This is usually very different from any external font + names; `PsfontsMap` can be used to find the external name of the font. + vf : Vf + A TeX "virtual font" file, or None if this font is not virtual. + + Attributes + ---------- + texname : bytes + size : float + Size of the font in Adobe points, converted from the slightly + smaller TeX points. + widths : list + Widths of glyphs in glyph-space units, typically 1/1000ths of + the point size. + + """ + __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm') + + def __init__(self, scale, tfm, texname, vf): + _api.check_isinstance(bytes, texname=texname) + self._scale = scale + self._tfm = tfm + self.texname = texname + self._vf = vf + self.size = scale * (72.0 / (72.27 * 2**16)) + try: + nchars = max(tfm.width) + 1 + except ValueError: + nchars = 0 + self.widths = [(1000*tfm.width.get(char, 0)) >> 20 + for char in range(nchars)] + + def __eq__(self, other): + return (type(self) is type(other) + and self.texname == other.texname and self.size == other.size) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return f"<{type(self).__name__}: {self.texname}>" + + def _width_of(self, char): + """Width of char in dvi units.""" + width = self._tfm.width.get(char, None) + if width is not None: + return _mul2012(width, self._scale) + _log.debug('No width for char %d in font %s.', char, self.texname) + return 0 + + def _height_depth_of(self, char): + """Height and depth of char in dvi units.""" + result = [] + for metric, name in ((self._tfm.height, "height"), + (self._tfm.depth, "depth")): + value = metric.get(char, None) + if value is None: + _log.debug('No %s for char %d in font %s', + name, char, self.texname) + result.append(0) + else: + result.append(_mul2012(value, self._scale)) + # cmsyXX (symbols font) glyph 0 ("minus") has a nonzero descent + # so that TeX aligns equations properly + # (https://tex.stackexchange.com/q/526103/) + # but we actually care about the rasterization depth to align + # the dvipng-generated images. + if re.match(br'^cmsy\d+$', self.texname) and char == 0: + result[-1] = 0 + return result + + +class Vf(Dvi): + r""" + A virtual font (\*.vf file) containing subroutines for dvi files. + + Parameters + ---------- + filename : str or path-like + + Notes + ----- + The virtual font format is a derivative of dvi: + http://mirrors.ctan.org/info/knuth/virtual-fonts + This class reuses some of the machinery of `Dvi` + but replaces the `_read` loop and dispatch mechanism. + + Examples + -------- + :: + + vf = Vf(filename) + glyph = vf[code] + glyph.text, glyph.boxes, glyph.width + """ + + def __init__(self, filename): + super().__init__(filename, 0) + try: + self._first_font = None + self._chars = {} + self._read() + finally: + self.close() + + def __getitem__(self, code): + return self._chars[code] + + def _read(self): + """ + Read one page from the file. Return True if successful, + False if there were no more pages. + """ + packet_char, packet_ends = None, None + packet_len, packet_width = None, None + while True: + byte = self.file.read(1)[0] + # If we are in a packet, execute the dvi instructions + if self.state is _dvistate.inpage: + byte_at = self.file.tell()-1 + if byte_at == packet_ends: + self._finalize_packet(packet_char, packet_width) + packet_len, packet_char, packet_width = None, None, None + # fall through to out-of-packet code + elif byte_at > packet_ends: + raise ValueError("Packet length mismatch in vf file") + else: + if byte in (139, 140) or byte >= 243: + raise ValueError( + "Inappropriate opcode %d in vf file" % byte) + Dvi._dtable[byte](self, byte) + continue + + # We are outside a packet + if byte < 242: # a short packet (length given by byte) + packet_len = byte + packet_char, packet_width = self._arg(1), self._arg(3) + packet_ends = self._init_packet(byte) + self.state = _dvistate.inpage + elif byte == 242: # a long packet + packet_len, packet_char, packet_width = \ + [self._arg(x) for x in (4, 4, 4)] + self._init_packet(packet_len) + elif 243 <= byte <= 246: + k = self._arg(byte - 242, byte == 246) + c, s, d, a, l = [self._arg(x) for x in (4, 4, 4, 1, 1)] + self._fnt_def_real(k, c, s, d, a, l) + if self._first_font is None: + self._first_font = k + elif byte == 247: # preamble + i, k = self._arg(1), self._arg(1) + x = self.file.read(k) + cs, ds = self._arg(4), self._arg(4) + self._pre(i, x, cs, ds) + elif byte == 248: # postamble (just some number of 248s) + break + else: + raise ValueError("Unknown vf opcode %d" % byte) + + def _init_packet(self, pl): + if self.state != _dvistate.outer: + raise ValueError("Misplaced packet in vf file") + self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0 + self.stack, self.text, self.boxes = [], [], [] + self.f = self._first_font + return self.file.tell() + pl + + def _finalize_packet(self, packet_char, packet_width): + self._chars[packet_char] = Page( + text=self.text, boxes=self.boxes, width=packet_width, + height=None, descent=None) + self.state = _dvistate.outer + + def _pre(self, i, x, cs, ds): + if self.state is not _dvistate.pre: + raise ValueError("pre command in middle of vf file") + if i != 202: + raise ValueError("Unknown vf format %d" % i) + if len(x): + _log.debug('vf file comment: %s', x) + self.state = _dvistate.outer + # cs = checksum, ds = design size + + +def _mul2012(num1, num2): + """Multiply two numbers in 20.12 fixed point format.""" + # Separated into a function because >> has surprising precedence + return (num1*num2) >> 20 + + +class Tfm: + """ + A TeX Font Metric file. + + This implementation covers only the bare minimum needed by the Dvi class. + + Parameters + ---------- + filename : str or path-like + + Attributes + ---------- + checksum : int + Used for verifying against the dvi file. + design_size : int + Design size of the font (unknown units) + width, height, depth : dict + Dimensions of each character, need to be scaled by the factor + specified in the dvi file. These are dicts because indexing may + not start from 0. + """ + __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth') + + def __init__(self, filename): + _log.debug('opening tfm file %s', filename) + with open(filename, 'rb') as file: + header1 = file.read(24) + lh, bc, ec, nw, nh, nd = struct.unpack('!6H', header1[2:14]) + _log.debug('lh=%d, bc=%d, ec=%d, nw=%d, nh=%d, nd=%d', + lh, bc, ec, nw, nh, nd) + header2 = file.read(4*lh) + self.checksum, self.design_size = struct.unpack('!2I', header2[:8]) + # there is also encoding information etc. + char_info = file.read(4*(ec-bc+1)) + widths = struct.unpack(f'!{nw}i', file.read(4*nw)) + heights = struct.unpack(f'!{nh}i', file.read(4*nh)) + depths = struct.unpack(f'!{nd}i', file.read(4*nd)) + self.width, self.height, self.depth = {}, {}, {} + for idx, char in enumerate(range(bc, ec+1)): + byte0 = char_info[4*idx] + byte1 = char_info[4*idx+1] + self.width[char] = widths[byte0] + self.height[char] = heights[byte1 >> 4] + self.depth[char] = depths[byte1 & 0xf] + + +PsFont = namedtuple('PsFont', 'texname psname effects encoding filename') + + +class PsfontsMap: + """ + A psfonts.map formatted file, mapping TeX fonts to PS fonts. + + Parameters + ---------- + filename : str or path-like + + Notes + ----- + For historical reasons, TeX knows many Type-1 fonts by different + names than the outside world. (For one thing, the names have to + fit in eight characters.) Also, TeX's native fonts are not Type-1 + but Metafont, which is nontrivial to convert to PostScript except + as a bitmap. While high-quality conversions to Type-1 format exist + and are shipped with modern TeX distributions, we need to know + which Type-1 fonts are the counterparts of which native fonts. For + these reasons a mapping is needed from internal font names to font + file names. + + A texmf tree typically includes mapping files called e.g. + :file:`psfonts.map`, :file:`pdftex.map`, or :file:`dvipdfm.map`. + The file :file:`psfonts.map` is used by :program:`dvips`, + :file:`pdftex.map` by :program:`pdfTeX`, and :file:`dvipdfm.map` + by :program:`dvipdfm`. :file:`psfonts.map` might avoid embedding + the 35 PostScript fonts (i.e., have no filename for them, as in + the Times-Bold example above), while the pdf-related files perhaps + only avoid the "Base 14" pdf fonts. But the user may have + configured these files differently. + + Examples + -------- + >>> map = PsfontsMap(find_tex_file('pdftex.map')) + >>> entry = map[b'ptmbo8r'] + >>> entry.texname + b'ptmbo8r' + >>> entry.psname + b'Times-Bold' + >>> entry.encoding + '/usr/local/texlive/2008/texmf-dist/fonts/enc/dvips/base/8r.enc' + >>> entry.effects + {'slant': 0.16700000000000001} + >>> entry.filename + """ + __slots__ = ('_filename', '_unparsed', '_parsed') + + # Create a filename -> PsfontsMap cache, so that calling + # `PsfontsMap(filename)` with the same filename a second time immediately + # returns the same object. + @lru_cache + def __new__(cls, filename): + self = object.__new__(cls) + self._filename = os.fsdecode(filename) + # Some TeX distributions have enormous pdftex.map files which would + # take hundreds of milliseconds to parse, but it is easy enough to just + # store the unparsed lines (keyed by the first word, which is the + # texname) and parse them on-demand. + with open(filename, 'rb') as file: + self._unparsed = {} + for line in file: + tfmname = line.split(b' ', 1)[0] + self._unparsed.setdefault(tfmname, []).append(line) + self._parsed = {} + return self + + def __getitem__(self, texname): + assert isinstance(texname, bytes) + if texname in self._unparsed: + for line in self._unparsed.pop(texname): + if self._parse_and_cache_line(line): + break + try: + return self._parsed[texname] + except KeyError: + raise LookupError( + f"An associated PostScript font (required by Matplotlib) " + f"could not be found for TeX font {texname.decode('ascii')!r} " + f"in {self._filename!r}; this problem can often be solved by " + f"installing a suitable PostScript font package in your TeX " + f"package manager") from None + + def _parse_and_cache_line(self, line): + """ + Parse a line in the font mapping file. + + The format is (partially) documented at + http://mirrors.ctan.org/systems/doc/pdftex/manual/pdftex-a.pdf + https://tug.org/texinfohtml/dvips.html#psfonts_002emap + Each line can have the following fields: + + - tfmname (first, only required field), + - psname (defaults to tfmname, must come immediately after tfmname if + present), + - fontflags (integer, must come immediately after psname if present, + ignored by us), + - special (SlantFont and ExtendFont, only field that is double-quoted), + - fontfile, encodingfile (optional, prefixed by <, <<, or <[; << always + precedes a font, <[ always precedes an encoding, < can precede either + but then an encoding file must have extension .enc; < and << also + request different font subsetting behaviors but we ignore that; < can + be separated from the filename by whitespace). + + special, fontfile, and encodingfile can appear in any order. + """ + # If the map file specifies multiple encodings for a font, we + # follow pdfTeX in choosing the last one specified. Such + # entries are probably mistakes but they have occurred. + # https://tex.stackexchange.com/q/10826/ + + if not line or line.startswith((b" ", b"%", b"*", b";", b"#")): + return + tfmname = basename = special = encodingfile = fontfile = None + is_subsetted = is_t1 = is_truetype = False + matches = re.finditer(br'"([^"]*)(?:"|$)|(\S+)', line) + for match in matches: + quoted, unquoted = match.groups() + if unquoted: + if unquoted.startswith(b"<<"): # font + fontfile = unquoted[2:] + elif unquoted.startswith(b"<["): # encoding + encodingfile = unquoted[2:] + elif unquoted.startswith(b"<"): # font or encoding + word = ( + # foo + unquoted[1:] + # < by itself => read the next word + or next(filter(None, next(matches).groups()))) + if word.endswith(b".enc"): + encodingfile = word + else: + fontfile = word + is_subsetted = True + elif tfmname is None: + tfmname = unquoted + elif basename is None: + basename = unquoted + elif quoted: + special = quoted + effects = {} + if special: + words = reversed(special.split()) + for word in words: + if word == b"SlantFont": + effects["slant"] = float(next(words)) + elif word == b"ExtendFont": + effects["extend"] = float(next(words)) + + # Verify some properties of the line that would cause it to be ignored + # otherwise. + if fontfile is not None: + if fontfile.endswith((b".ttf", b".ttc")): + is_truetype = True + elif not fontfile.endswith(b".otf"): + is_t1 = True + elif basename is not None: + is_t1 = True + if is_truetype and is_subsetted and encodingfile is None: + return + if not is_t1 and ("slant" in effects or "extend" in effects): + return + if abs(effects.get("slant", 0)) > 1: + return + if abs(effects.get("extend", 0)) > 2: + return + + if basename is None: + basename = tfmname + if encodingfile is not None: + encodingfile = find_tex_file(encodingfile) + if fontfile is not None: + fontfile = find_tex_file(fontfile) + self._parsed[tfmname] = PsFont( + texname=tfmname, psname=basename, effects=effects, + encoding=encodingfile, filename=fontfile) + return True + + +def _parse_enc(path): + r""" + Parse a \*.enc file referenced from a psfonts.map style file. + + The format supported by this function is a tiny subset of PostScript. + + Parameters + ---------- + path : `os.PathLike` + + Returns + ------- + list + The nth entry of the list is the PostScript glyph name of the nth + glyph. + """ + no_comments = re.sub("%.*", "", Path(path).read_text(encoding="ascii")) + array = re.search(r"(?s)\[(.*)\]", no_comments).group(1) + lines = [line for line in array.split() if line] + if all(line.startswith("/") for line in lines): + return [line[1:] for line in lines] + else: + raise ValueError(f"Failed to parse {path} as Postscript encoding") + + +class _LuatexKpsewhich: + @lru_cache # A singleton. + def __new__(cls): + self = object.__new__(cls) + self._proc = self._new_proc() + return self + + def _new_proc(self): + return subprocess.Popen( + ["luatex", "--luaonly", + str(cbook._get_data_path("kpsewhich.lua"))], + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + + def search(self, filename): + if self._proc.poll() is not None: # Dead, restart it. + self._proc = self._new_proc() + self._proc.stdin.write(os.fsencode(filename) + b"\n") + self._proc.stdin.flush() + out = self._proc.stdout.readline().rstrip() + return None if out == b"nil" else os.fsdecode(out) + + +@lru_cache +def find_tex_file(filename): + """ + Find a file in the texmf tree using kpathsea_. + + The kpathsea library, provided by most existing TeX distributions, both + on Unix-like systems and on Windows (MikTeX), is invoked via a long-lived + luatex process if luatex is installed, or via kpsewhich otherwise. + + .. _kpathsea: https://www.tug.org/kpathsea/ + + Parameters + ---------- + filename : str or path-like + + Raises + ------ + FileNotFoundError + If the file is not found. + """ + + # we expect these to always be ascii encoded, but use utf-8 + # out of caution + if isinstance(filename, bytes): + filename = filename.decode('utf-8', errors='replace') + + try: + lk = _LuatexKpsewhich() + except FileNotFoundError: + lk = None # Fallback to directly calling kpsewhich, as below. + + if lk: + path = lk.search(filename) + else: + if sys.platform == 'win32': + # On Windows only, kpathsea can use utf-8 for cmd args and output. + # The `command_line_encoding` environment variable is set to force + # it to always use utf-8 encoding. See Matplotlib issue #11848. + kwargs = {'env': {**os.environ, 'command_line_encoding': 'utf-8'}, + 'encoding': 'utf-8'} + else: # On POSIX, run through the equivalent of os.fsdecode(). + kwargs = {'encoding': sys.getfilesystemencoding(), + 'errors': 'surrogateescape'} + + try: + path = (cbook._check_and_log_subprocess(['kpsewhich', filename], + _log, **kwargs) + .rstrip('\n')) + except (FileNotFoundError, RuntimeError): + path = None + + if path: + return path + else: + raise FileNotFoundError( + f"Matplotlib's TeX implementation searched for a file named " + f"{filename!r} in your texmf tree, but could not find it") + + +@lru_cache +def _fontfile(cls, suffix, texname): + return cls(find_tex_file(texname + suffix)) + + +_tfmfile = partial(_fontfile, Tfm, ".tfm") +_vffile = partial(_fontfile, Vf, ".vf") + + +if __name__ == '__main__': + from argparse import ArgumentParser + import itertools + + parser = ArgumentParser() + parser.add_argument("filename") + parser.add_argument("dpi", nargs="?", type=float, default=None) + args = parser.parse_args() + with Dvi(args.filename, args.dpi) as dvi: + fontmap = PsfontsMap(find_tex_file('pdftex.map')) + for page in dvi: + print(f"=== new page === " + f"(w: {page.width}, h: {page.height}, d: {page.descent})") + for font, group in itertools.groupby( + page.text, lambda text: text.font): + print(f"font: {font.texname.decode('latin-1')!r}\t" + f"scale: {font._scale / 2 ** 20}") + print("x", "y", "glyph", "chr", "w", "(glyphs)", sep="\t") + for text in group: + print(text.x, text.y, text.glyph, + chr(text.glyph) if chr(text.glyph).isprintable() + else ".", + text.width, sep="\t") + if page.boxes: + print("x", "y", "h", "w", "", "(boxes)", sep="\t") + for box in page.boxes: + print(box.x, box.y, box.height, box.width, sep="\t") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.pyi new file mode 100644 index 00000000..bf5cfcbe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/dviread.pyi @@ -0,0 +1,90 @@ +from pathlib import Path +import io +import os +from enum import Enum +from collections.abc import Generator + +from typing import NamedTuple + +class _dvistate(Enum): + pre: int + outer: int + inpage: int + post_post: int + finale: int + +class Page(NamedTuple): + text: list[Text] + boxes: list[Box] + height: int + width: int + descent: int + +class Box(NamedTuple): + x: int + y: int + height: int + width: int + +class Text(NamedTuple): + x: int + y: int + font: DviFont + glyph: int + width: int + @property + def font_path(self) -> Path: ... + @property + def font_size(self) -> float: ... + @property + def font_effects(self) -> dict[str, float]: ... + @property + def glyph_name_or_index(self) -> int | str: ... + +class Dvi: + file: io.BufferedReader + dpi: float | None + fonts: dict[int, DviFont] + state: _dvistate + def __init__(self, filename: str | os.PathLike, dpi: float | None) -> None: ... + # Replace return with Self when py3.9 is dropped + def __enter__(self) -> Dvi: ... + def __exit__(self, etype, evalue, etrace) -> None: ... + def __iter__(self) -> Generator[Page, None, None]: ... + def close(self) -> None: ... + +class DviFont: + texname: bytes + size: float + widths: list[int] + def __init__( + self, scale: float, tfm: Tfm, texname: bytes, vf: Vf | None + ) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + +class Vf(Dvi): + def __init__(self, filename: str | os.PathLike) -> None: ... + def __getitem__(self, code: int) -> Page: ... + +class Tfm: + checksum: int + design_size: int + width: dict[int, int] + height: dict[int, int] + depth: dict[int, int] + def __init__(self, filename: str | os.PathLike) -> None: ... + +class PsFont(NamedTuple): + texname: bytes + psname: bytes + effects: dict[str, float] + encoding: None | bytes + filename: str + +class PsfontsMap: + # Replace return with Self when py3.9 is dropped + def __new__(cls, filename: str | os.PathLike) -> PsfontsMap: ... + def __getitem__(self, texname: bytes) -> PsFont: ... + +def find_tex_file(filename: str | os.PathLike) -> str: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.py new file mode 100644 index 00000000..e8a5f154 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.py @@ -0,0 +1,3626 @@ +""" +`matplotlib.figure` implements the following classes: + +`Figure` + Top level `~matplotlib.artist.Artist`, which holds all plot elements. + Many methods are implemented in `FigureBase`. + +`SubFigure` + A logical figure inside a figure, usually added to a figure (or parent + `SubFigure`) with `Figure.add_subfigure` or `Figure.subfigures` methods + (provisional API v3.4). + +`SubplotParams` + Control the default spacing between subplots. + +Figures are typically created using pyplot methods `~.pyplot.figure`, +`~.pyplot.subplots`, and `~.pyplot.subplot_mosaic`. + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(2, 2), facecolor='lightskyblue', + layout='constrained') + fig.suptitle('Figure') + ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium') + +Some situations call for directly instantiating a `~.figure.Figure` class, +usually inside an application of some sort (see :ref:`user_interfaces` for a +list of examples) . More information about Figures can be found at +:ref:`figure-intro`. +""" + +from contextlib import ExitStack +import inspect +import itertools +import logging +from numbers import Integral +import threading + +import numpy as np + +import matplotlib as mpl +from matplotlib import _blocking_input, backend_bases, _docstring, projections +from matplotlib.artist import ( + Artist, allow_rasterization, _finalize_rasterization) +from matplotlib.backend_bases import ( + DrawEvent, FigureCanvasBase, NonGuiException, MouseButton, _get_renderer) +import matplotlib._api as _api +import matplotlib.cbook as cbook +import matplotlib.colorbar as cbar +import matplotlib.image as mimage + +from matplotlib.axes import Axes +from matplotlib.gridspec import GridSpec +from matplotlib.layout_engine import ( + ConstrainedLayoutEngine, TightLayoutEngine, LayoutEngine, + PlaceHolderLayoutEngine +) +import matplotlib.legend as mlegend +from matplotlib.patches import Rectangle +from matplotlib.text import Text +from matplotlib.transforms import (Affine2D, Bbox, BboxTransformTo, + TransformedBbox) + +_log = logging.getLogger(__name__) + + +def _stale_figure_callback(self, val): + if self.figure: + self.figure.stale = val + + +class _AxesStack: + """ + Helper class to track axes in a figure. + + Axes are tracked both in the order in which they have been added + (``self._axes`` insertion/iteration order) and in the separate "gca" stack + (which is the index to which they map in the ``self._axes`` dict). + """ + + def __init__(self): + self._axes = {} # Mapping of axes to "gca" order. + self._counter = itertools.count() + + def as_list(self): + """List the axes that have been added to the figure.""" + return [*self._axes] # This relies on dict preserving order. + + def remove(self, a): + """Remove the axes from the stack.""" + self._axes.pop(a) + + def bubble(self, a): + """Move an axes, which must already exist in the stack, to the top.""" + if a not in self._axes: + raise ValueError("Axes has not been added yet") + self._axes[a] = next(self._counter) + + def add(self, a): + """Add an axes to the stack, ignoring it if already present.""" + if a not in self._axes: + self._axes[a] = next(self._counter) + + def current(self): + """Return the active axes, or None if the stack is empty.""" + return max(self._axes, key=self._axes.__getitem__, default=None) + + def __getstate__(self): + return { + **vars(self), + "_counter": max(self._axes.values(), default=0) + } + + def __setstate__(self, state): + next_counter = state.pop('_counter') + vars(self).update(state) + self._counter = itertools.count(next_counter) + + +class SubplotParams: + """ + A class to hold the parameters for a subplot. + """ + + def __init__(self, left=None, bottom=None, right=None, top=None, + wspace=None, hspace=None): + """ + Defaults are given by :rc:`figure.subplot.[name]`. + + Parameters + ---------- + left : float + The position of the left edge of the subplots, + as a fraction of the figure width. + right : float + The position of the right edge of the subplots, + as a fraction of the figure width. + bottom : float + The position of the bottom edge of the subplots, + as a fraction of the figure height. + top : float + The position of the top edge of the subplots, + as a fraction of the figure height. + wspace : float + The width of the padding between subplots, + as a fraction of the average Axes width. + hspace : float + The height of the padding between subplots, + as a fraction of the average Axes height. + """ + for key in ["left", "bottom", "right", "top", "wspace", "hspace"]: + setattr(self, key, mpl.rcParams[f"figure.subplot.{key}"]) + self.update(left, bottom, right, top, wspace, hspace) + + def update(self, left=None, bottom=None, right=None, top=None, + wspace=None, hspace=None): + """ + Update the dimensions of the passed parameters. *None* means unchanged. + """ + if ((left if left is not None else self.left) + >= (right if right is not None else self.right)): + raise ValueError('left cannot be >= right') + if ((bottom if bottom is not None else self.bottom) + >= (top if top is not None else self.top)): + raise ValueError('bottom cannot be >= top') + if left is not None: + self.left = left + if right is not None: + self.right = right + if bottom is not None: + self.bottom = bottom + if top is not None: + self.top = top + if wspace is not None: + self.wspace = wspace + if hspace is not None: + self.hspace = hspace + + +class FigureBase(Artist): + """ + Base class for `.Figure` and `.SubFigure` containing the methods that add + artists to the figure or subfigure, create Axes, etc. + """ + def __init__(self, **kwargs): + super().__init__() + # remove the non-figure artist _axes property + # as it makes no sense for a figure to be _in_ an Axes + # this is used by the property methods in the artist base class + # which are over-ridden in this class + del self._axes + + self._suptitle = None + self._supxlabel = None + self._supylabel = None + + # groupers to keep track of x and y labels we want to align. + # see self.align_xlabels and self.align_ylabels and + # axis._get_tick_boxes_siblings + self._align_label_groups = {"x": cbook.Grouper(), "y": cbook.Grouper()} + + self._localaxes = [] # track all axes + self.artists = [] + self.lines = [] + self.patches = [] + self.texts = [] + self.images = [] + self.legends = [] + self.subfigs = [] + self.stale = True + self.suppressComposite = None + self.set(**kwargs) + + def _get_draw_artists(self, renderer): + """Also runs apply_aspect""" + artists = self.get_children() + for sfig in self.subfigs: + artists.remove(sfig) + childa = sfig.get_children() + for child in childa: + if child in artists: + artists.remove(child) + + artists.remove(self.patch) + artists = sorted( + (artist for artist in artists if not artist.get_animated()), + key=lambda artist: artist.get_zorder()) + for ax in self._localaxes: + locator = ax.get_axes_locator() + ax.apply_aspect(locator(ax, renderer) if locator else None) + + for child in ax.get_children(): + if hasattr(child, 'apply_aspect'): + locator = child.get_axes_locator() + child.apply_aspect( + locator(child, renderer) if locator else None) + return artists + + def autofmt_xdate( + self, bottom=0.2, rotation=30, ha='right', which='major'): + """ + Date ticklabels often overlap, so it is useful to rotate them + and right align them. Also, a common use case is a number of + subplots with shared x-axis where the x-axis is date data. The + ticklabels are often long, and it helps to rotate them on the + bottom subplot and turn them off on other subplots, as well as + turn off xlabels. + + Parameters + ---------- + bottom : float, default: 0.2 + The bottom of the subplots for `subplots_adjust`. + rotation : float, default: 30 degrees + The rotation angle of the xtick labels in degrees. + ha : {'left', 'center', 'right'}, default: 'right' + The horizontal alignment of the xticklabels. + which : {'major', 'minor', 'both'}, default: 'major' + Selects which ticklabels to rotate. + """ + _api.check_in_list(['major', 'minor', 'both'], which=which) + allsubplots = all(ax.get_subplotspec() for ax in self.axes) + if len(self.axes) == 1: + for label in self.axes[0].get_xticklabels(which=which): + label.set_ha(ha) + label.set_rotation(rotation) + else: + if allsubplots: + for ax in self.get_axes(): + if ax.get_subplotspec().is_last_row(): + for label in ax.get_xticklabels(which=which): + label.set_ha(ha) + label.set_rotation(rotation) + else: + for label in ax.get_xticklabels(which=which): + label.set_visible(False) + ax.set_xlabel('') + + if allsubplots: + self.subplots_adjust(bottom=bottom) + self.stale = True + + def get_children(self): + """Get a list of artists contained in the figure.""" + return [self.patch, + *self.artists, + *self._localaxes, + *self.lines, + *self.patches, + *self.texts, + *self.images, + *self.legends, + *self.subfigs] + + def contains(self, mouseevent): + """ + Test whether the mouse event occurred on the figure. + + Returns + ------- + bool, {} + """ + if self._different_canvas(mouseevent): + return False, {} + inside = self.bbox.contains(mouseevent.x, mouseevent.y) + return inside, {} + + def get_window_extent(self, renderer=None): + # docstring inherited + return self.bbox + + def _suplabels(self, t, info, **kwargs): + """ + Add a centered %(name)s to the figure. + + Parameters + ---------- + t : str + The %(name)s text. + x : float, default: %(x0)s + The x location of the text in figure coordinates. + y : float, default: %(y0)s + The y location of the text in figure coordinates. + horizontalalignment, ha : {'center', 'left', 'right'}, default: %(ha)s + The horizontal alignment of the text relative to (*x*, *y*). + verticalalignment, va : {'top', 'center', 'bottom', 'baseline'}, \ +default: %(va)s + The vertical alignment of the text relative to (*x*, *y*). + fontsize, size : default: :rc:`figure.%(rc)ssize` + The font size of the text. See `.Text.set_size` for possible + values. + fontweight, weight : default: :rc:`figure.%(rc)sweight` + The font weight of the text. See `.Text.set_weight` for possible + values. + + Returns + ------- + text + The `.Text` instance of the %(name)s. + + Other Parameters + ---------------- + fontproperties : None or dict, optional + A dict of font properties. If *fontproperties* is given the + default values for font size and weight are taken from the + `.FontProperties` defaults. :rc:`figure.%(rc)ssize` and + :rc:`figure.%(rc)sweight` are ignored in this case. + + **kwargs + Additional kwargs are `matplotlib.text.Text` properties. + """ + + suplab = getattr(self, info['name']) + + x = kwargs.pop('x', None) + y = kwargs.pop('y', None) + if info['name'] in ['_supxlabel', '_suptitle']: + autopos = y is None + elif info['name'] == '_supylabel': + autopos = x is None + if x is None: + x = info['x0'] + if y is None: + y = info['y0'] + + if 'horizontalalignment' not in kwargs and 'ha' not in kwargs: + kwargs['horizontalalignment'] = info['ha'] + if 'verticalalignment' not in kwargs and 'va' not in kwargs: + kwargs['verticalalignment'] = info['va'] + if 'rotation' not in kwargs: + kwargs['rotation'] = info['rotation'] + + if 'fontproperties' not in kwargs: + if 'fontsize' not in kwargs and 'size' not in kwargs: + kwargs['size'] = mpl.rcParams[info['size']] + if 'fontweight' not in kwargs and 'weight' not in kwargs: + kwargs['weight'] = mpl.rcParams[info['weight']] + + sup = self.text(x, y, t, **kwargs) + if suplab is not None: + suplab.set_text(t) + suplab.set_position((x, y)) + suplab.update_from(sup) + sup.remove() + else: + suplab = sup + suplab._autopos = autopos + setattr(self, info['name'], suplab) + self.stale = True + return suplab + + @_docstring.Substitution(x0=0.5, y0=0.98, name='suptitle', ha='center', + va='top', rc='title') + @_docstring.copy(_suplabels) + def suptitle(self, t, **kwargs): + # docstring from _suplabels... + info = {'name': '_suptitle', 'x0': 0.5, 'y0': 0.98, + 'ha': 'center', 'va': 'top', 'rotation': 0, + 'size': 'figure.titlesize', 'weight': 'figure.titleweight'} + return self._suplabels(t, info, **kwargs) + + def get_suptitle(self): + """Return the suptitle as string or an empty string if not set.""" + text_obj = self._suptitle + return "" if text_obj is None else text_obj.get_text() + + @_docstring.Substitution(x0=0.5, y0=0.01, name='supxlabel', ha='center', + va='bottom', rc='label') + @_docstring.copy(_suplabels) + def supxlabel(self, t, **kwargs): + # docstring from _suplabels... + info = {'name': '_supxlabel', 'x0': 0.5, 'y0': 0.01, + 'ha': 'center', 'va': 'bottom', 'rotation': 0, + 'size': 'figure.labelsize', 'weight': 'figure.labelweight'} + return self._suplabels(t, info, **kwargs) + + def get_supxlabel(self): + """Return the supxlabel as string or an empty string if not set.""" + text_obj = self._supxlabel + return "" if text_obj is None else text_obj.get_text() + + @_docstring.Substitution(x0=0.02, y0=0.5, name='supylabel', ha='left', + va='center', rc='label') + @_docstring.copy(_suplabels) + def supylabel(self, t, **kwargs): + # docstring from _suplabels... + info = {'name': '_supylabel', 'x0': 0.02, 'y0': 0.5, + 'ha': 'left', 'va': 'center', 'rotation': 'vertical', + 'rotation_mode': 'anchor', 'size': 'figure.labelsize', + 'weight': 'figure.labelweight'} + return self._suplabels(t, info, **kwargs) + + def get_supylabel(self): + """Return the supylabel as string or an empty string if not set.""" + text_obj = self._supylabel + return "" if text_obj is None else text_obj.get_text() + + def get_edgecolor(self): + """Get the edge color of the Figure rectangle.""" + return self.patch.get_edgecolor() + + def get_facecolor(self): + """Get the face color of the Figure rectangle.""" + return self.patch.get_facecolor() + + def get_frameon(self): + """ + Return the figure's background patch visibility, i.e. + whether the figure background will be drawn. Equivalent to + ``Figure.patch.get_visible()``. + """ + return self.patch.get_visible() + + def set_linewidth(self, linewidth): + """ + Set the line width of the Figure rectangle. + + Parameters + ---------- + linewidth : number + """ + self.patch.set_linewidth(linewidth) + + def get_linewidth(self): + """ + Get the line width of the Figure rectangle. + """ + return self.patch.get_linewidth() + + def set_edgecolor(self, color): + """ + Set the edge color of the Figure rectangle. + + Parameters + ---------- + color : color + """ + self.patch.set_edgecolor(color) + + def set_facecolor(self, color): + """ + Set the face color of the Figure rectangle. + + Parameters + ---------- + color : color + """ + self.patch.set_facecolor(color) + + def set_frameon(self, b): + """ + Set the figure's background patch visibility, i.e. + whether the figure background will be drawn. Equivalent to + ``Figure.patch.set_visible()``. + + Parameters + ---------- + b : bool + """ + self.patch.set_visible(b) + self.stale = True + + frameon = property(get_frameon, set_frameon) + + def add_artist(self, artist, clip=False): + """ + Add an `.Artist` to the figure. + + Usually artists are added to `~.axes.Axes` objects using + `.Axes.add_artist`; this method can be used in the rare cases where + one needs to add artists directly to the figure instead. + + Parameters + ---------- + artist : `~matplotlib.artist.Artist` + The artist to add to the figure. If the added artist has no + transform previously set, its transform will be set to + ``figure.transSubfigure``. + clip : bool, default: False + Whether the added artist should be clipped by the figure patch. + + Returns + ------- + `~matplotlib.artist.Artist` + The added artist. + """ + artist.set_figure(self) + self.artists.append(artist) + artist._remove_method = self.artists.remove + + if not artist.is_transform_set(): + artist.set_transform(self.transSubfigure) + + if clip and artist.get_clip_path() is None: + artist.set_clip_path(self.patch) + + self.stale = True + return artist + + @_docstring.dedent_interpd + def add_axes(self, *args, **kwargs): + """ + Add an `~.axes.Axes` to the figure. + + Call signatures:: + + add_axes(rect, projection=None, polar=False, **kwargs) + add_axes(ax) + + Parameters + ---------- + rect : tuple (left, bottom, width, height) + The dimensions (left, bottom, width, height) of the new + `~.axes.Axes`. All quantities are in fractions of figure width and + height. + + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', 'rectilinear', str}, optional + The projection type of the `~.axes.Axes`. *str* is the name of + a custom projection, see `~matplotlib.projections`. The default + None results in a 'rectilinear' projection. + + polar : bool, default: False + If True, equivalent to projection='polar'. + + axes_class : subclass type of `~.axes.Axes`, optional + The `.axes.Axes` subclass that is instantiated. This parameter + is incompatible with *projection* and *polar*. See + :ref:`axisartist_users-guide-index` for examples. + + sharex, sharey : `~matplotlib.axes.Axes`, optional + Share the x or y `~matplotlib.axis` with sharex and/or sharey. + The axis will have the same limits, ticks, and scale as the axis + of the shared axes. + + label : str + A label for the returned Axes. + + Returns + ------- + `~.axes.Axes`, or a subclass of `~.axes.Axes` + The returned axes class depends on the projection used. It is + `~.axes.Axes` if rectilinear projection is used and + `.projections.polar.PolarAxes` if polar projection is used. + + Other Parameters + ---------------- + **kwargs + This method also takes the keyword arguments for + the returned Axes class. The keyword arguments for the + rectilinear Axes class `~.axes.Axes` can be found in + the following table but there might also be other keyword + arguments if another projection is used, see the actual Axes + class. + + %(Axes:kwdoc)s + + Notes + ----- + In rare circumstances, `.add_axes` may be called with a single + argument, an Axes instance already created in the present figure but + not in the figure's list of Axes. + + See Also + -------- + .Figure.add_subplot + .pyplot.subplot + .pyplot.axes + .Figure.subplots + .pyplot.subplots + + Examples + -------- + Some simple examples:: + + rect = l, b, w, h + fig = plt.figure() + fig.add_axes(rect) + fig.add_axes(rect, frameon=False, facecolor='g') + fig.add_axes(rect, polar=True) + ax = fig.add_axes(rect, projection='polar') + fig.delaxes(ax) + fig.add_axes(ax) + """ + + if not len(args) and 'rect' not in kwargs: + raise TypeError( + "add_axes() missing 1 required positional argument: 'rect'") + elif 'rect' in kwargs: + if len(args): + raise TypeError( + "add_axes() got multiple values for argument 'rect'") + args = (kwargs.pop('rect'), ) + + if isinstance(args[0], Axes): + a, *extra_args = args + key = a._projection_init + if a.get_figure() is not self: + raise ValueError( + "The Axes must have been created in the present figure") + else: + rect, *extra_args = args + if not np.isfinite(rect).all(): + raise ValueError(f'all entries in rect must be finite not {rect}') + projection_class, pkw = self._process_projection_requirements(**kwargs) + + # create the new axes using the axes class given + a = projection_class(self, rect, **pkw) + key = (projection_class, pkw) + + if extra_args: + _api.warn_deprecated( + "3.8", + name="Passing more than one positional argument to Figure.add_axes", + addendum="Any additional positional arguments are currently ignored.") + return self._add_axes_internal(a, key) + + @_docstring.dedent_interpd + def add_subplot(self, *args, **kwargs): + """ + Add an `~.axes.Axes` to the figure as part of a subplot arrangement. + + Call signatures:: + + add_subplot(nrows, ncols, index, **kwargs) + add_subplot(pos, **kwargs) + add_subplot(ax) + add_subplot() + + Parameters + ---------- + *args : int, (int, int, *index*), or `.SubplotSpec`, default: (1, 1, 1) + The position of the subplot described by one of + + - Three integers (*nrows*, *ncols*, *index*). The subplot will + take the *index* position on a grid with *nrows* rows and + *ncols* columns. *index* starts at 1 in the upper left corner + and increases to the right. *index* can also be a two-tuple + specifying the (*first*, *last*) indices (1-based, and including + *last*) of the subplot, e.g., ``fig.add_subplot(3, 1, (1, 2))`` + makes a subplot that spans the upper 2/3 of the figure. + - A 3-digit integer. The digits are interpreted as if given + separately as three single-digit integers, i.e. + ``fig.add_subplot(235)`` is the same as + ``fig.add_subplot(2, 3, 5)``. Note that this can only be used + if there are no more than 9 subplots. + - A `.SubplotSpec`. + + In rare circumstances, `.add_subplot` may be called with a single + argument, a subplot Axes instance already created in the + present figure but not in the figure's list of Axes. + + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', 'rectilinear', str}, optional + The projection type of the subplot (`~.axes.Axes`). *str* is the + name of a custom projection, see `~matplotlib.projections`. The + default None results in a 'rectilinear' projection. + + polar : bool, default: False + If True, equivalent to projection='polar'. + + axes_class : subclass type of `~.axes.Axes`, optional + The `.axes.Axes` subclass that is instantiated. This parameter + is incompatible with *projection* and *polar*. See + :ref:`axisartist_users-guide-index` for examples. + + sharex, sharey : `~matplotlib.axes.Axes`, optional + Share the x or y `~matplotlib.axis` with sharex and/or sharey. + The axis will have the same limits, ticks, and scale as the axis + of the shared axes. + + label : str + A label for the returned Axes. + + Returns + ------- + `~.axes.Axes` + + The Axes of the subplot. The returned Axes can actually be an + instance of a subclass, such as `.projections.polar.PolarAxes` for + polar projections. + + Other Parameters + ---------------- + **kwargs + This method also takes the keyword arguments for the returned Axes + base class; except for the *figure* argument. The keyword arguments + for the rectilinear base class `~.axes.Axes` can be found in + the following table but there might also be other keyword + arguments if another projection is used. + + %(Axes:kwdoc)s + + See Also + -------- + .Figure.add_axes + .pyplot.subplot + .pyplot.axes + .Figure.subplots + .pyplot.subplots + + Examples + -------- + :: + + fig = plt.figure() + + fig.add_subplot(231) + ax1 = fig.add_subplot(2, 3, 1) # equivalent but more general + + fig.add_subplot(232, frameon=False) # subplot with no frame + fig.add_subplot(233, projection='polar') # polar subplot + fig.add_subplot(234, sharex=ax1) # subplot sharing x-axis with ax1 + fig.add_subplot(235, facecolor="red") # red subplot + + ax1.remove() # delete ax1 from the figure + fig.add_subplot(ax1) # add ax1 back to the figure + """ + if 'figure' in kwargs: + # Axes itself allows for a 'figure' kwarg, but since we want to + # bind the created Axes to self, it is not allowed here. + raise _api.kwarg_error("add_subplot", "figure") + + if (len(args) == 1 + and isinstance(args[0], mpl.axes._base._AxesBase) + and args[0].get_subplotspec()): + ax = args[0] + key = ax._projection_init + if ax.get_figure() is not self: + raise ValueError("The Axes must have been created in " + "the present figure") + else: + if not args: + args = (1, 1, 1) + # Normalize correct ijk values to (i, j, k) here so that + # add_subplot(211) == add_subplot(2, 1, 1). Invalid values will + # trigger errors later (via SubplotSpec._from_subplot_args). + if (len(args) == 1 and isinstance(args[0], Integral) + and 100 <= args[0] <= 999): + args = tuple(map(int, str(args[0]))) + projection_class, pkw = self._process_projection_requirements(**kwargs) + ax = projection_class(self, *args, **pkw) + key = (projection_class, pkw) + return self._add_axes_internal(ax, key) + + def _add_axes_internal(self, ax, key): + """Private helper for `add_axes` and `add_subplot`.""" + self._axstack.add(ax) + if ax not in self._localaxes: + self._localaxes.append(ax) + self.sca(ax) + ax._remove_method = self.delaxes + # this is to support plt.subplot's re-selection logic + ax._projection_init = key + self.stale = True + ax.stale_callback = _stale_figure_callback + return ax + + def subplots(self, nrows=1, ncols=1, *, sharex=False, sharey=False, + squeeze=True, width_ratios=None, height_ratios=None, + subplot_kw=None, gridspec_kw=None): + """ + Add a set of subplots to this figure. + + This utility wrapper makes it convenient to create common layouts of + subplots in a single call. + + Parameters + ---------- + nrows, ncols : int, default: 1 + Number of rows/columns of the subplot grid. + + sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False + Controls sharing of x-axis (*sharex*) or y-axis (*sharey*): + + - True or 'all': x- or y-axis will be shared among all subplots. + - False or 'none': each subplot x- or y-axis will be independent. + - 'row': each subplot row will share an x- or y-axis. + - 'col': each subplot column will share an x- or y-axis. + + When subplots have a shared x-axis along a column, only the x tick + labels of the bottom subplot are created. Similarly, when subplots + have a shared y-axis along a row, only the y tick labels of the + first column subplot are created. To later turn other subplots' + ticklabels on, use `~matplotlib.axes.Axes.tick_params`. + + When subplots have a shared axis that has units, calling + `.Axis.set_units` will update each axis with the new units. + + squeeze : bool, default: True + - If True, extra dimensions are squeezed out from the returned + array of Axes: + + - if only one subplot is constructed (nrows=ncols=1), the + resulting single Axes object is returned as a scalar. + - for Nx1 or 1xM subplots, the returned object is a 1D numpy + object array of Axes objects. + - for NxM, subplots with N>1 and M>1 are returned as a 2D array. + + - If False, no squeezing at all is done: the returned Axes object + is always a 2D array containing Axes instances, even if it ends + up being 1x1. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. Equivalent + to ``gridspec_kw={'width_ratios': [...]}``. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. Equivalent + to ``gridspec_kw={'height_ratios': [...]}``. + + subplot_kw : dict, optional + Dict with keywords passed to the `.Figure.add_subplot` call used to + create each subplot. + + gridspec_kw : dict, optional + Dict with keywords passed to the + `~matplotlib.gridspec.GridSpec` constructor used to create + the grid the subplots are placed on. + + Returns + ------- + `~.axes.Axes` or array of Axes + Either a single `~matplotlib.axes.Axes` object or an array of Axes + objects if more than one subplot was created. The dimensions of the + resulting array can be controlled with the *squeeze* keyword, see + above. + + See Also + -------- + .pyplot.subplots + .Figure.add_subplot + .pyplot.subplot + + Examples + -------- + :: + + # First create some toy data: + x = np.linspace(0, 2*np.pi, 400) + y = np.sin(x**2) + + # Create a figure + fig = plt.figure() + + # Create a subplot + ax = fig.subplots() + ax.plot(x, y) + ax.set_title('Simple plot') + + # Create two subplots and unpack the output array immediately + ax1, ax2 = fig.subplots(1, 2, sharey=True) + ax1.plot(x, y) + ax1.set_title('Sharing Y axis') + ax2.scatter(x, y) + + # Create four polar Axes and access them through the returned array + axes = fig.subplots(2, 2, subplot_kw=dict(projection='polar')) + axes[0, 0].plot(x, y) + axes[1, 1].scatter(x, y) + + # Share an X-axis with each column of subplots + fig.subplots(2, 2, sharex='col') + + # Share a Y-axis with each row of subplots + fig.subplots(2, 2, sharey='row') + + # Share both X- and Y-axes with all subplots + fig.subplots(2, 2, sharex='all', sharey='all') + + # Note that this is the same as + fig.subplots(2, 2, sharex=True, sharey=True) + """ + gridspec_kw = dict(gridspec_kw or {}) + if height_ratios is not None: + if 'height_ratios' in gridspec_kw: + raise ValueError("'height_ratios' must not be defined both as " + "parameter and as key in 'gridspec_kw'") + gridspec_kw['height_ratios'] = height_ratios + if width_ratios is not None: + if 'width_ratios' in gridspec_kw: + raise ValueError("'width_ratios' must not be defined both as " + "parameter and as key in 'gridspec_kw'") + gridspec_kw['width_ratios'] = width_ratios + + gs = self.add_gridspec(nrows, ncols, figure=self, **gridspec_kw) + axs = gs.subplots(sharex=sharex, sharey=sharey, squeeze=squeeze, + subplot_kw=subplot_kw) + return axs + + def delaxes(self, ax): + """ + Remove the `~.axes.Axes` *ax* from the figure; update the current Axes. + """ + self._remove_axes(ax, owners=[self._axstack, self._localaxes]) + + def _remove_axes(self, ax, owners): + """ + Common helper for removal of standard axes (via delaxes) and of child axes. + + Parameters + ---------- + ax : `~.AxesBase` + The Axes to remove. + owners + List of objects (list or _AxesStack) "owning" the axes, from which the Axes + will be remove()d. + """ + for owner in owners: + owner.remove(ax) + + self._axobservers.process("_axes_change_event", self) + self.stale = True + self.canvas.release_mouse(ax) + + for name in ax._axis_names: # Break link between any shared axes + grouper = ax._shared_axes[name] + siblings = [other for other in grouper.get_siblings(ax) if other is not ax] + if not siblings: # Axes was not shared along this axis; we're done. + continue + grouper.remove(ax) + # Formatters and locators may previously have been associated with the now + # removed axis. Update them to point to an axis still there (we can pick + # any of them, and use the first sibling). + remaining_axis = siblings[0]._axis_map[name] + remaining_axis.get_major_formatter().set_axis(remaining_axis) + remaining_axis.get_major_locator().set_axis(remaining_axis) + remaining_axis.get_minor_formatter().set_axis(remaining_axis) + remaining_axis.get_minor_locator().set_axis(remaining_axis) + + ax._twinned_axes.remove(ax) # Break link between any twinned axes. + + def clear(self, keep_observers=False): + """ + Clear the figure. + + Parameters + ---------- + keep_observers : bool, default: False + Set *keep_observers* to True if, for example, + a gui widget is tracking the Axes in the figure. + """ + self.suppressComposite = None + + # first clear the axes in any subfigures + for subfig in self.subfigs: + subfig.clear(keep_observers=keep_observers) + self.subfigs = [] + + for ax in tuple(self.axes): # Iterate over the copy. + ax.clear() + self.delaxes(ax) # Remove ax from self._axstack. + + self.artists = [] + self.lines = [] + self.patches = [] + self.texts = [] + self.images = [] + self.legends = [] + if not keep_observers: + self._axobservers = cbook.CallbackRegistry() + self._suptitle = None + self._supxlabel = None + self._supylabel = None + + self.stale = True + + # synonym for `clear`. + def clf(self, keep_observers=False): + """ + [*Discouraged*] Alias for the `clear()` method. + + .. admonition:: Discouraged + + The use of ``clf()`` is discouraged. Use ``clear()`` instead. + + Parameters + ---------- + keep_observers : bool, default: False + Set *keep_observers* to True if, for example, + a gui widget is tracking the Axes in the figure. + """ + return self.clear(keep_observers=keep_observers) + + # Note: the docstring below is modified with replace for the pyplot + # version of this function because the method name differs (plt.figlegend) + # the replacements are: + # " legend(" -> " figlegend(" for the signatures + # "fig.legend(" -> "plt.figlegend" for the code examples + # "ax.plot" -> "plt.plot" for consistency in using pyplot when able + @_docstring.dedent_interpd + def legend(self, *args, **kwargs): + """ + Place a legend on the figure. + + Call signatures:: + + legend() + legend(handles, labels) + legend(handles=handles) + legend(labels) + + The call signatures correspond to the following different ways to use + this method: + + **1. Automatic detection of elements to be shown in the legend** + + The elements to be added to the legend are automatically determined, + when you do not pass in any extra arguments. + + In this case, the labels are taken from the artist. You can specify + them either at artist creation or by calling the + :meth:`~.Artist.set_label` method on the artist:: + + ax.plot([1, 2, 3], label='Inline label') + fig.legend() + + or:: + + line, = ax.plot([1, 2, 3]) + line.set_label('Label via method') + fig.legend() + + Specific lines can be excluded from the automatic legend element + selection by defining a label starting with an underscore. + This is default for all artists, so calling `.Figure.legend` without + any arguments and without setting the labels manually will result in + no legend being drawn. + + + **2. Explicitly listing the artists and labels in the legend** + + For full control of which artists have a legend entry, it is possible + to pass an iterable of legend artists followed by an iterable of + legend labels respectively:: + + fig.legend([line1, line2, line3], ['label1', 'label2', 'label3']) + + + **3. Explicitly listing the artists in the legend** + + This is similar to 2, but the labels are taken from the artists' + label properties. Example:: + + line1, = ax1.plot([1, 2, 3], label='label1') + line2, = ax2.plot([1, 2, 3], label='label2') + fig.legend(handles=[line1, line2]) + + + **4. Labeling existing plot elements** + + .. admonition:: Discouraged + + This call signature is discouraged, because the relation between + plot elements and labels is only implicit by their order and can + easily be mixed up. + + To make a legend for all artists on all Axes, call this function with + an iterable of strings, one for each legend item. For example:: + + fig, (ax1, ax2) = plt.subplots(1, 2) + ax1.plot([1, 3, 5], color='blue') + ax2.plot([2, 4, 6], color='red') + fig.legend(['the blues', 'the reds']) + + + Parameters + ---------- + handles : list of `.Artist`, optional + A list of Artists (lines, patches) to be added to the legend. + Use this together with *labels*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + The length of handles and labels should be the same in this + case. If they are not, they are truncated to the smaller length. + + labels : list of str, optional + A list of labels to show next to the artists. + Use this together with *handles*, if you need full control on what + is shown in the legend and the automatic mechanism described above + is not sufficient. + + Returns + ------- + `~matplotlib.legend.Legend` + + Other Parameters + ---------------- + %(_legend_kw_figure)s + + See Also + -------- + .Axes.legend + + Notes + ----- + Some artists are not supported by this function. See + :ref:`legend_guide` for details. + """ + + handles, labels, kwargs = mlegend._parse_legend_args(self.axes, *args, **kwargs) + # explicitly set the bbox transform if the user hasn't. + kwargs.setdefault("bbox_transform", self.transSubfigure) + l = mlegend.Legend(self, handles, labels, **kwargs) + self.legends.append(l) + l._remove_method = self.legends.remove + self.stale = True + return l + + @_docstring.dedent_interpd + def text(self, x, y, s, fontdict=None, **kwargs): + """ + Add text to figure. + + Parameters + ---------- + x, y : float + The position to place the text. By default, this is in figure + coordinates, floats in [0, 1]. The coordinate system can be changed + using the *transform* keyword. + + s : str + The text string. + + fontdict : dict, optional + A dictionary to override the default text properties. If not given, + the defaults are determined by :rc:`font.*`. Properties passed as + *kwargs* override the corresponding ones given in *fontdict*. + + Returns + ------- + `~.text.Text` + + Other Parameters + ---------------- + **kwargs : `~matplotlib.text.Text` properties + Other miscellaneous text parameters. + + %(Text:kwdoc)s + + See Also + -------- + .Axes.text + .pyplot.text + """ + effective_kwargs = { + 'transform': self.transSubfigure, + **(fontdict if fontdict is not None else {}), + **kwargs, + } + text = Text(x=x, y=y, text=s, **effective_kwargs) + text.set_figure(self) + text.stale_callback = _stale_figure_callback + + self.texts.append(text) + text._remove_method = self.texts.remove + self.stale = True + return text + + @_docstring.dedent_interpd + def colorbar( + self, mappable, cax=None, ax=None, use_gridspec=True, **kwargs): + """ + Add a colorbar to a plot. + + Parameters + ---------- + mappable + The `matplotlib.cm.ScalarMappable` (i.e., `.AxesImage`, + `.ContourSet`, etc.) described by this colorbar. This argument is + mandatory for the `.Figure.colorbar` method but optional for the + `.pyplot.colorbar` function, which sets the default to the current + image. + + Note that one can create a `.ScalarMappable` "on-the-fly" to + generate colorbars not attached to a previously drawn artist, e.g. + :: + + fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax) + + cax : `~matplotlib.axes.Axes`, optional + Axes into which the colorbar will be drawn. If `None`, then a new + Axes is created and the space for it will be stolen from the Axes(s) + specified in *ax*. + + ax : `~matplotlib.axes.Axes` or iterable or `numpy.ndarray` of Axes, optional + The one or more parent Axes from which space for a new colorbar Axes + will be stolen. This parameter is only used if *cax* is not set. + + Defaults to the Axes that contains the mappable used to create the + colorbar. + + use_gridspec : bool, optional + If *cax* is ``None``, a new *cax* is created as an instance of + Axes. If *ax* is positioned with a subplotspec and *use_gridspec* + is ``True``, then *cax* is also positioned with a subplotspec. + + Returns + ------- + colorbar : `~matplotlib.colorbar.Colorbar` + + Other Parameters + ---------------- + %(_make_axes_kw_doc)s + %(_colormap_kw_doc)s + + Notes + ----- + If *mappable* is a `~.contour.ContourSet`, its *extend* kwarg is + included automatically. + + The *shrink* kwarg provides a simple way to scale the colorbar with + respect to the axes. Note that if *cax* is specified, it determines the + size of the colorbar, and *shrink* and *aspect* are ignored. + + For more precise control, you can manually specify the positions of the + axes objects in which the mappable and the colorbar are drawn. In this + case, do not use any of the axes properties kwargs. + + It is known that some vector graphics viewers (svg and pdf) render + white gaps between segments of the colorbar. This is due to bugs in + the viewers, not Matplotlib. As a workaround, the colorbar can be + rendered with overlapping segments:: + + cbar = colorbar() + cbar.solids.set_edgecolor("face") + draw() + + However, this has negative consequences in other circumstances, e.g. + with semi-transparent images (alpha < 1) and colorbar extensions; + therefore, this workaround is not used by default (see issue #1188). + + """ + + if ax is None: + ax = getattr(mappable, "axes", None) + + if cax is None: + if ax is None: + raise ValueError( + 'Unable to determine Axes to steal space for Colorbar. ' + 'Either provide the *cax* argument to use as the Axes for ' + 'the Colorbar, provide the *ax* argument to steal space ' + 'from it, or add *mappable* to an Axes.') + fig = ( # Figure of first axes; logic copied from make_axes. + [*ax.flat] if isinstance(ax, np.ndarray) + else [*ax] if np.iterable(ax) + else [ax])[0].figure + current_ax = fig.gca() + if (fig.get_layout_engine() is not None and + not fig.get_layout_engine().colorbar_gridspec): + use_gridspec = False + if (use_gridspec + and isinstance(ax, mpl.axes._base._AxesBase) + and ax.get_subplotspec()): + cax, kwargs = cbar.make_axes_gridspec(ax, **kwargs) + else: + cax, kwargs = cbar.make_axes(ax, **kwargs) + # make_axes calls add_{axes,subplot} which changes gca; undo that. + fig.sca(current_ax) + cax.grid(visible=False, which='both', axis='both') + + NON_COLORBAR_KEYS = [ # remove kws that cannot be passed to Colorbar + 'fraction', 'pad', 'shrink', 'aspect', 'anchor', 'panchor'] + cb = cbar.Colorbar(cax, mappable, **{ + k: v for k, v in kwargs.items() if k not in NON_COLORBAR_KEYS}) + cax.figure.stale = True + return cb + + def subplots_adjust(self, left=None, bottom=None, right=None, top=None, + wspace=None, hspace=None): + """ + Adjust the subplot layout parameters. + + Unset parameters are left unmodified; initial values are given by + :rc:`figure.subplot.[name]`. + + Parameters + ---------- + left : float, optional + The position of the left edge of the subplots, + as a fraction of the figure width. + right : float, optional + The position of the right edge of the subplots, + as a fraction of the figure width. + bottom : float, optional + The position of the bottom edge of the subplots, + as a fraction of the figure height. + top : float, optional + The position of the top edge of the subplots, + as a fraction of the figure height. + wspace : float, optional + The width of the padding between subplots, + as a fraction of the average Axes width. + hspace : float, optional + The height of the padding between subplots, + as a fraction of the average Axes height. + """ + if (self.get_layout_engine() is not None and + not self.get_layout_engine().adjust_compatible): + _api.warn_external( + "This figure was using a layout engine that is " + "incompatible with subplots_adjust and/or tight_layout; " + "not calling subplots_adjust.") + return + self.subplotpars.update(left, bottom, right, top, wspace, hspace) + for ax in self.axes: + if ax.get_subplotspec() is not None: + ax._set_position(ax.get_subplotspec().get_position(self)) + self.stale = True + + def align_xlabels(self, axs=None): + """ + Align the xlabels of subplots in the same subplot column if label + alignment is being done automatically (i.e. the label position is + not manually set). + + Alignment persists for draw events after this is called. + + If a label is on the bottom, it is aligned with labels on Axes that + also have their label on the bottom and that have the same + bottom-most subplot row. If the label is on the top, + it is aligned with labels on Axes with the same top-most row. + + Parameters + ---------- + axs : list of `~matplotlib.axes.Axes` + Optional list of (or `~numpy.ndarray`) `~matplotlib.axes.Axes` + to align the xlabels. + Default is to align all Axes on the figure. + + See Also + -------- + matplotlib.figure.Figure.align_ylabels + matplotlib.figure.Figure.align_labels + + Notes + ----- + This assumes that ``axs`` are from the same `.GridSpec`, so that + their `.SubplotSpec` positions correspond to figure positions. + + Examples + -------- + Example with rotated xtick labels:: + + fig, axs = plt.subplots(1, 2) + for tick in axs[0].get_xticklabels(): + tick.set_rotation(55) + axs[0].set_xlabel('XLabel 0') + axs[1].set_xlabel('XLabel 1') + fig.align_xlabels() + """ + if axs is None: + axs = self.axes + axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None] + for ax in axs: + _log.debug(' Working on: %s', ax.get_xlabel()) + rowspan = ax.get_subplotspec().rowspan + pos = ax.xaxis.get_label_position() # top or bottom + # Search through other axes for label positions that are same as + # this one and that share the appropriate row number. + # Add to a grouper associated with each axes of siblings. + # This list is inspected in `axis.draw` by + # `axis._update_label_position`. + for axc in axs: + if axc.xaxis.get_label_position() == pos: + rowspanc = axc.get_subplotspec().rowspan + if (pos == 'top' and rowspan.start == rowspanc.start or + pos == 'bottom' and rowspan.stop == rowspanc.stop): + # grouper for groups of xlabels to align + self._align_label_groups['x'].join(ax, axc) + + def align_ylabels(self, axs=None): + """ + Align the ylabels of subplots in the same subplot column if label + alignment is being done automatically (i.e. the label position is + not manually set). + + Alignment persists for draw events after this is called. + + If a label is on the left, it is aligned with labels on Axes that + also have their label on the left and that have the same + left-most subplot column. If the label is on the right, + it is aligned with labels on Axes with the same right-most column. + + Parameters + ---------- + axs : list of `~matplotlib.axes.Axes` + Optional list (or `~numpy.ndarray`) of `~matplotlib.axes.Axes` + to align the ylabels. + Default is to align all Axes on the figure. + + See Also + -------- + matplotlib.figure.Figure.align_xlabels + matplotlib.figure.Figure.align_labels + + Notes + ----- + This assumes that ``axs`` are from the same `.GridSpec`, so that + their `.SubplotSpec` positions correspond to figure positions. + + Examples + -------- + Example with large yticks labels:: + + fig, axs = plt.subplots(2, 1) + axs[0].plot(np.arange(0, 1000, 50)) + axs[0].set_ylabel('YLabel 0') + axs[1].set_ylabel('YLabel 1') + fig.align_ylabels() + """ + if axs is None: + axs = self.axes + axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None] + for ax in axs: + _log.debug(' Working on: %s', ax.get_ylabel()) + colspan = ax.get_subplotspec().colspan + pos = ax.yaxis.get_label_position() # left or right + # Search through other axes for label positions that are same as + # this one and that share the appropriate column number. + # Add to a list associated with each axes of siblings. + # This list is inspected in `axis.draw` by + # `axis._update_label_position`. + for axc in axs: + if axc.yaxis.get_label_position() == pos: + colspanc = axc.get_subplotspec().colspan + if (pos == 'left' and colspan.start == colspanc.start or + pos == 'right' and colspan.stop == colspanc.stop): + # grouper for groups of ylabels to align + self._align_label_groups['y'].join(ax, axc) + + def align_labels(self, axs=None): + """ + Align the xlabels and ylabels of subplots with the same subplots + row or column (respectively) if label alignment is being + done automatically (i.e. the label position is not manually set). + + Alignment persists for draw events after this is called. + + Parameters + ---------- + axs : list of `~matplotlib.axes.Axes` + Optional list (or `~numpy.ndarray`) of `~matplotlib.axes.Axes` + to align the labels. + Default is to align all Axes on the figure. + + See Also + -------- + matplotlib.figure.Figure.align_xlabels + + matplotlib.figure.Figure.align_ylabels + """ + self.align_xlabels(axs=axs) + self.align_ylabels(axs=axs) + + def add_gridspec(self, nrows=1, ncols=1, **kwargs): + """ + Return a `.GridSpec` that has this figure as a parent. This allows + complex layout of Axes in the figure. + + Parameters + ---------- + nrows : int, default: 1 + Number of rows in grid. + + ncols : int, default: 1 + Number of columns in grid. + + Returns + ------- + `.GridSpec` + + Other Parameters + ---------------- + **kwargs + Keyword arguments are passed to `.GridSpec`. + + See Also + -------- + matplotlib.pyplot.subplots + + Examples + -------- + Adding a subplot that spans two rows:: + + fig = plt.figure() + gs = fig.add_gridspec(2, 2) + ax1 = fig.add_subplot(gs[0, 0]) + ax2 = fig.add_subplot(gs[1, 0]) + # spans two rows: + ax3 = fig.add_subplot(gs[:, 1]) + + """ + + _ = kwargs.pop('figure', None) # pop in case user has added this... + gs = GridSpec(nrows=nrows, ncols=ncols, figure=self, **kwargs) + return gs + + def subfigures(self, nrows=1, ncols=1, squeeze=True, + wspace=None, hspace=None, + width_ratios=None, height_ratios=None, + **kwargs): + """ + Add a set of subfigures to this figure or subfigure. + + A subfigure has the same artist methods as a figure, and is logically + the same as a figure, but cannot print itself. + See :doc:`/gallery/subplots_axes_and_figures/subfigures`. + + .. note:: + The *subfigure* concept is new in v3.4, and the API is still provisional. + + Parameters + ---------- + nrows, ncols : int, default: 1 + Number of rows/columns of the subfigure grid. + + squeeze : bool, default: True + If True, extra dimensions are squeezed out from the returned + array of subfigures. + + wspace, hspace : float, default: None + The amount of width/height reserved for space between subfigures, + expressed as a fraction of the average subfigure width/height. + If not given, the values will be inferred from rcParams if using + constrained layout (see `~.ConstrainedLayoutEngine`), or zero if + not using a layout engine. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. + """ + gs = GridSpec(nrows=nrows, ncols=ncols, figure=self, + wspace=wspace, hspace=hspace, + width_ratios=width_ratios, + height_ratios=height_ratios, + left=0, right=1, bottom=0, top=1) + + sfarr = np.empty((nrows, ncols), dtype=object) + for i in range(ncols): + for j in range(nrows): + sfarr[j, i] = self.add_subfigure(gs[j, i], **kwargs) + + if self.get_layout_engine() is None and (wspace is not None or + hspace is not None): + # Gridspec wspace and hspace is ignored on subfigure instantiation, + # and no space is left. So need to account for it here if required. + bottoms, tops, lefts, rights = gs.get_grid_positions(self) + for sfrow, bottom, top in zip(sfarr, bottoms, tops): + for sf, left, right in zip(sfrow, lefts, rights): + bbox = Bbox.from_extents(left, bottom, right, top) + sf._redo_transform_rel_fig(bbox=bbox) + + if squeeze: + # Discarding unneeded dimensions that equal 1. If we only have one + # subfigure, just return it instead of a 1-element array. + return sfarr.item() if sfarr.size == 1 else sfarr.squeeze() + else: + # Returned axis array will be always 2-d, even if nrows=ncols=1. + return sfarr + + def add_subfigure(self, subplotspec, **kwargs): + """ + Add a `.SubFigure` to the figure as part of a subplot arrangement. + + Parameters + ---------- + subplotspec : `.gridspec.SubplotSpec` + Defines the region in a parent gridspec where the subfigure will + be placed. + + Returns + ------- + `.SubFigure` + + Other Parameters + ---------------- + **kwargs + Are passed to the `.SubFigure` object. + + See Also + -------- + .Figure.subfigures + """ + sf = SubFigure(self, subplotspec, **kwargs) + self.subfigs += [sf] + return sf + + def sca(self, a): + """Set the current Axes to be *a* and return *a*.""" + self._axstack.bubble(a) + self._axobservers.process("_axes_change_event", self) + return a + + def gca(self): + """ + Get the current Axes. + + If there is currently no Axes on this Figure, a new one is created + using `.Figure.add_subplot`. (To test whether there is currently an + Axes on a Figure, check whether ``figure.axes`` is empty. To test + whether there is currently a Figure on the pyplot figure stack, check + whether `.pyplot.get_fignums()` is empty.) + """ + ax = self._axstack.current() + return ax if ax is not None else self.add_subplot() + + def _gci(self): + # Helper for `~matplotlib.pyplot.gci`. Do not use elsewhere. + """ + Get the current colorable artist. + + Specifically, returns the current `.ScalarMappable` instance (`.Image` + created by `imshow` or `figimage`, `.Collection` created by `pcolor` or + `scatter`, etc.), or *None* if no such instance has been defined. + + The current image is an attribute of the current Axes, or the nearest + earlier Axes in the current figure that contains an image. + + Notes + ----- + Historically, the only colorable artists were images; hence the name + ``gci`` (get current image). + """ + # Look first for an image in the current Axes. + ax = self._axstack.current() + if ax is None: + return None + im = ax._gci() + if im is not None: + return im + # If there is no image in the current Axes, search for + # one in a previously created Axes. Whether this makes + # sense is debatable, but it is the documented behavior. + for ax in reversed(self.axes): + im = ax._gci() + if im is not None: + return im + return None + + def _process_projection_requirements(self, *, axes_class=None, polar=False, + projection=None, **kwargs): + """ + Handle the args/kwargs to add_axes/add_subplot/gca, returning:: + + (axes_proj_class, proj_class_kwargs) + + which can be used for new Axes initialization/identification. + """ + if axes_class is not None: + if polar or projection is not None: + raise ValueError( + "Cannot combine 'axes_class' and 'projection' or 'polar'") + projection_class = axes_class + else: + + if polar: + if projection is not None and projection != 'polar': + raise ValueError( + f"polar={polar}, yet projection={projection!r}. " + "Only one of these arguments should be supplied." + ) + projection = 'polar' + + if isinstance(projection, str) or projection is None: + projection_class = projections.get_projection_class(projection) + elif hasattr(projection, '_as_mpl_axes'): + projection_class, extra_kwargs = projection._as_mpl_axes() + kwargs.update(**extra_kwargs) + else: + raise TypeError( + f"projection must be a string, None or implement a " + f"_as_mpl_axes method, not {projection!r}") + return projection_class, kwargs + + def get_default_bbox_extra_artists(self): + bbox_artists = [artist for artist in self.get_children() + if (artist.get_visible() and artist.get_in_layout())] + for ax in self.axes: + if ax.get_visible(): + bbox_artists.extend(ax.get_default_bbox_extra_artists()) + return bbox_artists + + @_api.make_keyword_only("3.8", "bbox_extra_artists") + def get_tightbbox(self, renderer=None, bbox_extra_artists=None): + """ + Return a (tight) bounding box of the figure *in inches*. + + Note that `.FigureBase` differs from all other artists, which return + their `.Bbox` in pixels. + + Artists that have ``artist.set_in_layout(False)`` are not included + in the bbox. + + Parameters + ---------- + renderer : `.RendererBase` subclass + Renderer that will be used to draw the figures (i.e. + ``fig.canvas.get_renderer()``) + + bbox_extra_artists : list of `.Artist` or ``None`` + List of artists to include in the tight bounding box. If + ``None`` (default), then all artist children of each Axes are + included in the tight bounding box. + + Returns + ------- + `.BboxBase` + containing the bounding box (in figure inches). + """ + + if renderer is None: + renderer = self.figure._get_renderer() + + bb = [] + if bbox_extra_artists is None: + artists = self.get_default_bbox_extra_artists() + else: + artists = bbox_extra_artists + + for a in artists: + bbox = a.get_tightbbox(renderer) + if bbox is not None: + bb.append(bbox) + + for ax in self.axes: + if ax.get_visible(): + # some axes don't take the bbox_extra_artists kwarg so we + # need this conditional.... + try: + bbox = ax.get_tightbbox( + renderer, bbox_extra_artists=bbox_extra_artists) + except TypeError: + bbox = ax.get_tightbbox(renderer) + bb.append(bbox) + bb = [b for b in bb + if (np.isfinite(b.width) and np.isfinite(b.height) + and (b.width != 0 or b.height != 0))] + + isfigure = hasattr(self, 'bbox_inches') + if len(bb) == 0: + if isfigure: + return self.bbox_inches + else: + # subfigures do not have bbox_inches, but do have a bbox + bb = [self.bbox] + + _bbox = Bbox.union(bb) + + if isfigure: + # transform from pixels to inches... + _bbox = TransformedBbox(_bbox, self.dpi_scale_trans.inverted()) + + return _bbox + + @staticmethod + def _norm_per_subplot_kw(per_subplot_kw): + expanded = {} + for k, v in per_subplot_kw.items(): + if isinstance(k, tuple): + for sub_key in k: + if sub_key in expanded: + raise ValueError(f'The key {sub_key!r} appears multiple times.') + expanded[sub_key] = v + else: + if k in expanded: + raise ValueError(f'The key {k!r} appears multiple times.') + expanded[k] = v + return expanded + + @staticmethod + def _normalize_grid_string(layout): + if '\n' not in layout: + # single-line string + return [list(ln) for ln in layout.split(';')] + else: + # multi-line string + layout = inspect.cleandoc(layout) + return [list(ln) for ln in layout.strip('\n').split('\n')] + + def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False, + width_ratios=None, height_ratios=None, + empty_sentinel='.', + subplot_kw=None, per_subplot_kw=None, gridspec_kw=None): + """ + Build a layout of Axes based on ASCII art or nested lists. + + This is a helper function to build complex GridSpec layouts visually. + + See :ref:`mosaic` + for an example and full API documentation + + Parameters + ---------- + mosaic : list of list of {hashable or nested} or str + + A visual layout of how you want your Axes to be arranged + labeled as strings. For example :: + + x = [['A panel', 'A panel', 'edge'], + ['C panel', '.', 'edge']] + + produces 4 Axes: + + - 'A panel' which is 1 row high and spans the first two columns + - 'edge' which is 2 rows high and is on the right edge + - 'C panel' which in 1 row and 1 column wide in the bottom left + - a blank space 1 row and 1 column wide in the bottom center + + Any of the entries in the layout can be a list of lists + of the same form to create nested layouts. + + If input is a str, then it can either be a multi-line string of + the form :: + + ''' + AAE + C.E + ''' + + where each character is a column and each line is a row. Or it + can be a single-line string where rows are separated by ``;``:: + + 'AB;CC' + + The string notation allows only single character Axes labels and + does not support nesting but is very terse. + + The Axes identifiers may be `str` or a non-iterable hashable + object (e.g. `tuple` s may not be used). + + sharex, sharey : bool, default: False + If True, the x-axis (*sharex*) or y-axis (*sharey*) will be shared + among all subplots. In that case, tick label visibility and axis + units behave as for `subplots`. If False, each subplot's x- or + y-axis will be independent. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. Equivalent + to ``gridspec_kw={'width_ratios': [...]}``. In the case of nested + layouts, this argument applies only to the outer layout. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. Equivalent + to ``gridspec_kw={'height_ratios': [...]}``. In the case of nested + layouts, this argument applies only to the outer layout. + + subplot_kw : dict, optional + Dictionary with keywords passed to the `.Figure.add_subplot` call + used to create each subplot. These values may be overridden by + values in *per_subplot_kw*. + + per_subplot_kw : dict, optional + A dictionary mapping the Axes identifiers or tuples of identifiers + to a dictionary of keyword arguments to be passed to the + `.Figure.add_subplot` call used to create each subplot. The values + in these dictionaries have precedence over the values in + *subplot_kw*. + + If *mosaic* is a string, and thus all keys are single characters, + it is possible to use a single string instead of a tuple as keys; + i.e. ``"AB"`` is equivalent to ``("A", "B")``. + + .. versionadded:: 3.7 + + gridspec_kw : dict, optional + Dictionary with keywords passed to the `.GridSpec` constructor used + to create the grid the subplots are placed on. In the case of + nested layouts, this argument applies only to the outer layout. + For more complex layouts, users should use `.Figure.subfigures` + to create the nesting. + + empty_sentinel : object, optional + Entry in the layout to mean "leave this space empty". Defaults + to ``'.'``. Note, if *layout* is a string, it is processed via + `inspect.cleandoc` to remove leading white space, which may + interfere with using white-space as the empty sentinel. + + Returns + ------- + dict[label, Axes] + A dictionary mapping the labels to the Axes objects. The order of + the axes is left-to-right and top-to-bottom of their position in the + total layout. + + """ + subplot_kw = subplot_kw or {} + gridspec_kw = dict(gridspec_kw or {}) + per_subplot_kw = per_subplot_kw or {} + + if height_ratios is not None: + if 'height_ratios' in gridspec_kw: + raise ValueError("'height_ratios' must not be defined both as " + "parameter and as key in 'gridspec_kw'") + gridspec_kw['height_ratios'] = height_ratios + if width_ratios is not None: + if 'width_ratios' in gridspec_kw: + raise ValueError("'width_ratios' must not be defined both as " + "parameter and as key in 'gridspec_kw'") + gridspec_kw['width_ratios'] = width_ratios + + # special-case string input + if isinstance(mosaic, str): + mosaic = self._normalize_grid_string(mosaic) + per_subplot_kw = { + tuple(k): v for k, v in per_subplot_kw.items() + } + + per_subplot_kw = self._norm_per_subplot_kw(per_subplot_kw) + + # Only accept strict bools to allow a possible future API expansion. + _api.check_isinstance(bool, sharex=sharex, sharey=sharey) + + def _make_array(inp): + """ + Convert input into 2D array + + We need to have this internal function rather than + ``np.asarray(..., dtype=object)`` so that a list of lists + of lists does not get converted to an array of dimension > 2. + + Returns + ------- + 2D object array + """ + r0, *rest = inp + if isinstance(r0, str): + raise ValueError('List mosaic specification must be 2D') + for j, r in enumerate(rest, start=1): + if isinstance(r, str): + raise ValueError('List mosaic specification must be 2D') + if len(r0) != len(r): + raise ValueError( + "All of the rows must be the same length, however " + f"the first row ({r0!r}) has length {len(r0)} " + f"and row {j} ({r!r}) has length {len(r)}." + ) + out = np.zeros((len(inp), len(r0)), dtype=object) + for j, r in enumerate(inp): + for k, v in enumerate(r): + out[j, k] = v + return out + + def _identify_keys_and_nested(mosaic): + """ + Given a 2D object array, identify unique IDs and nested mosaics + + Parameters + ---------- + mosaic : 2D object array + + Returns + ------- + unique_ids : tuple + The unique non-sub mosaic entries in this mosaic + nested : dict[tuple[int, int], 2D object array] + """ + # make sure we preserve the user supplied order + unique_ids = cbook._OrderedSet() + nested = {} + for j, row in enumerate(mosaic): + for k, v in enumerate(row): + if v == empty_sentinel: + continue + elif not cbook.is_scalar_or_string(v): + nested[(j, k)] = _make_array(v) + else: + unique_ids.add(v) + + return tuple(unique_ids), nested + + def _do_layout(gs, mosaic, unique_ids, nested): + """ + Recursively do the mosaic. + + Parameters + ---------- + gs : GridSpec + mosaic : 2D object array + The input converted to a 2D array for this level. + unique_ids : tuple + The identified scalar labels at this level of nesting. + nested : dict[tuple[int, int]], 2D object array + The identified nested mosaics, if any. + + Returns + ------- + dict[label, Axes] + A flat dict of all of the Axes created. + """ + output = dict() + + # we need to merge together the Axes at this level and the axes + # in the (recursively) nested sub-mosaics so that we can add + # them to the figure in the "natural" order if you were to + # ravel in c-order all of the Axes that will be created + # + # This will stash the upper left index of each object (axes or + # nested mosaic) at this level + this_level = dict() + + # go through the unique keys, + for name in unique_ids: + # sort out where each axes starts/ends + indx = np.argwhere(mosaic == name) + start_row, start_col = np.min(indx, axis=0) + end_row, end_col = np.max(indx, axis=0) + 1 + # and construct the slice object + slc = (slice(start_row, end_row), slice(start_col, end_col)) + # some light error checking + if (mosaic[slc] != name).any(): + raise ValueError( + f"While trying to layout\n{mosaic!r}\n" + f"we found that the label {name!r} specifies a " + "non-rectangular or non-contiguous area.") + # and stash this slice for later + this_level[(start_row, start_col)] = (name, slc, 'axes') + + # do the same thing for the nested mosaics (simpler because these + # cannot be spans yet!) + for (j, k), nested_mosaic in nested.items(): + this_level[(j, k)] = (None, nested_mosaic, 'nested') + + # now go through the things in this level and add them + # in order left-to-right top-to-bottom + for key in sorted(this_level): + name, arg, method = this_level[key] + # we are doing some hokey function dispatch here based + # on the 'method' string stashed above to sort out if this + # element is an Axes or a nested mosaic. + if method == 'axes': + slc = arg + # add a single axes + if name in output: + raise ValueError(f"There are duplicate keys {name} " + f"in the layout\n{mosaic!r}") + ax = self.add_subplot( + gs[slc], **{ + 'label': str(name), + **subplot_kw, + **per_subplot_kw.get(name, {}) + } + ) + output[name] = ax + elif method == 'nested': + nested_mosaic = arg + j, k = key + # recursively add the nested mosaic + rows, cols = nested_mosaic.shape + nested_output = _do_layout( + gs[j, k].subgridspec(rows, cols), + nested_mosaic, + *_identify_keys_and_nested(nested_mosaic) + ) + overlap = set(output) & set(nested_output) + if overlap: + raise ValueError( + f"There are duplicate keys {overlap} " + f"between the outer layout\n{mosaic!r}\n" + f"and the nested layout\n{nested_mosaic}" + ) + output.update(nested_output) + else: + raise RuntimeError("This should never happen") + return output + + mosaic = _make_array(mosaic) + rows, cols = mosaic.shape + gs = self.add_gridspec(rows, cols, **gridspec_kw) + ret = _do_layout(gs, mosaic, *_identify_keys_and_nested(mosaic)) + ax0 = next(iter(ret.values())) + for ax in ret.values(): + if sharex: + ax.sharex(ax0) + ax._label_outer_xaxis(skip_non_rectangular_axes=True) + if sharey: + ax.sharey(ax0) + ax._label_outer_yaxis(skip_non_rectangular_axes=True) + if extra := set(per_subplot_kw) - set(ret): + raise ValueError( + f"The keys {extra} are in *per_subplot_kw* " + "but not in the mosaic." + ) + return ret + + def _set_artist_props(self, a): + if a != self: + a.set_figure(self) + a.stale_callback = _stale_figure_callback + a.set_transform(self.transSubfigure) + + +@_docstring.interpd +class SubFigure(FigureBase): + """ + Logical figure that can be placed inside a figure. + + Typically instantiated using `.Figure.add_subfigure` or + `.SubFigure.add_subfigure`, or `.SubFigure.subfigures`. A subfigure has + the same methods as a figure except for those particularly tied to the size + or dpi of the figure, and is confined to a prescribed region of the figure. + For example the following puts two subfigures side-by-side:: + + fig = plt.figure() + sfigs = fig.subfigures(1, 2) + axsL = sfigs[0].subplots(1, 2) + axsR = sfigs[1].subplots(2, 1) + + See :doc:`/gallery/subplots_axes_and_figures/subfigures` + + .. note:: + The *subfigure* concept is new in v3.4, and the API is still provisional. + """ + + def __init__(self, parent, subplotspec, *, + facecolor=None, + edgecolor=None, + linewidth=0.0, + frameon=None, + **kwargs): + """ + Parameters + ---------- + parent : `.Figure` or `.SubFigure` + Figure or subfigure that contains the SubFigure. SubFigures + can be nested. + + subplotspec : `.gridspec.SubplotSpec` + Defines the region in a parent gridspec where the subfigure will + be placed. + + facecolor : default: ``"none"`` + The figure patch face color; transparent by default. + + edgecolor : default: :rc:`figure.edgecolor` + The figure patch edge color. + + linewidth : float + The linewidth of the frame (i.e. the edge linewidth of the figure + patch). + + frameon : bool, default: :rc:`figure.frameon` + If ``False``, suppress drawing the figure background patch. + + Other Parameters + ---------------- + **kwargs : `.SubFigure` properties, optional + + %(SubFigure:kwdoc)s + """ + super().__init__(**kwargs) + if facecolor is None: + facecolor = "none" + if edgecolor is None: + edgecolor = mpl.rcParams['figure.edgecolor'] + if frameon is None: + frameon = mpl.rcParams['figure.frameon'] + + self._subplotspec = subplotspec + self._parent = parent + self.figure = parent.figure + + # subfigures use the parent axstack + self._axstack = parent._axstack + self.subplotpars = parent.subplotpars + self.dpi_scale_trans = parent.dpi_scale_trans + self._axobservers = parent._axobservers + self.canvas = parent.canvas + self.transFigure = parent.transFigure + self.bbox_relative = Bbox.null() + self._redo_transform_rel_fig() + self.figbbox = self._parent.figbbox + self.bbox = TransformedBbox(self.bbox_relative, + self._parent.transSubfigure) + self.transSubfigure = BboxTransformTo(self.bbox) + + self.patch = Rectangle( + xy=(0, 0), width=1, height=1, visible=frameon, + facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth, + # Don't let the figure patch influence bbox calculation. + in_layout=False, transform=self.transSubfigure) + self._set_artist_props(self.patch) + self.patch.set_antialiased(False) + + @property + def dpi(self): + return self._parent.dpi + + @dpi.setter + def dpi(self, value): + self._parent.dpi = value + + def get_dpi(self): + """ + Return the resolution of the parent figure in dots-per-inch as a float. + """ + return self._parent.dpi + + def set_dpi(self, val): + """ + Set the resolution of parent figure in dots-per-inch. + + Parameters + ---------- + val : float + """ + self._parent.dpi = val + self.stale = True + + def _get_renderer(self): + return self._parent._get_renderer() + + def _redo_transform_rel_fig(self, bbox=None): + """ + Make the transSubfigure bbox relative to Figure transform. + + Parameters + ---------- + bbox : bbox or None + If not None, then the bbox is used for relative bounding box. + Otherwise, it is calculated from the subplotspec. + """ + if bbox is not None: + self.bbox_relative.p0 = bbox.p0 + self.bbox_relative.p1 = bbox.p1 + return + # need to figure out *where* this subplotspec is. + gs = self._subplotspec.get_gridspec() + wr = np.asarray(gs.get_width_ratios()) + hr = np.asarray(gs.get_height_ratios()) + dx = wr[self._subplotspec.colspan].sum() / wr.sum() + dy = hr[self._subplotspec.rowspan].sum() / hr.sum() + x0 = wr[:self._subplotspec.colspan.start].sum() / wr.sum() + y0 = 1 - hr[:self._subplotspec.rowspan.stop].sum() / hr.sum() + self.bbox_relative.p0 = (x0, y0) + self.bbox_relative.p1 = (x0 + dx, y0 + dy) + + def get_constrained_layout(self): + """ + Return whether constrained layout is being used. + + See :ref:`constrainedlayout_guide`. + """ + return self._parent.get_constrained_layout() + + def get_constrained_layout_pads(self, relative=False): + """ + Get padding for ``constrained_layout``. + + Returns a list of ``w_pad, h_pad`` in inches and + ``wspace`` and ``hspace`` as fractions of the subplot. + + See :ref:`constrainedlayout_guide`. + + Parameters + ---------- + relative : bool + If `True`, then convert from inches to figure relative. + """ + return self._parent.get_constrained_layout_pads(relative=relative) + + def get_layout_engine(self): + return self._parent.get_layout_engine() + + @property + def axes(self): + """ + List of Axes in the SubFigure. You can access and modify the Axes + in the SubFigure through this list. + + Modifying this list has no effect. Instead, use `~.SubFigure.add_axes`, + `~.SubFigure.add_subplot` or `~.SubFigure.delaxes` to add or remove an + Axes. + + Note: The `.SubFigure.axes` property and `~.SubFigure.get_axes` method + are equivalent. + """ + return self._localaxes[:] + + get_axes = axes.fget + + def draw(self, renderer): + # docstring inherited + + # draw the figure bounding box, perhaps none for white figure + if not self.get_visible(): + return + + artists = self._get_draw_artists(renderer) + + try: + renderer.open_group('subfigure', gid=self.get_gid()) + self.patch.draw(renderer) + mimage._draw_list_compositing_images( + renderer, self, artists, self.figure.suppressComposite) + for sfig in self.subfigs: + sfig.draw(renderer) + renderer.close_group('subfigure') + + finally: + self.stale = False + + +@_docstring.interpd +class Figure(FigureBase): + """ + The top level container for all the plot elements. + + Attributes + ---------- + patch + The `.Rectangle` instance representing the figure background patch. + + suppressComposite + For multiple images, the figure will make composite images + depending on the renderer option_image_nocomposite function. If + *suppressComposite* is a boolean, this will override the renderer. + """ + + # we want to cache the fonts and mathtext at a global level so that when + # multiple figures are created we can reuse them. This helps with a bug on + # windows where the creation of too many figures leads to too many open + # file handles and improves the performance of parsing mathtext. However, + # these global caches are not thread safe. The solution here is to let the + # Figure acquire a shared lock at the start of the draw, and release it when it + # is done. This allows multiple renderers to share the cached fonts and + # parsed text, but only one figure can draw at a time and so the font cache + # and mathtext cache are used by only one renderer at a time. + + _render_lock = threading.RLock() + + def __str__(self): + return "Figure(%gx%g)" % tuple(self.bbox.size) + + def __repr__(self): + return "<{clsname} size {h:g}x{w:g} with {naxes} Axes>".format( + clsname=self.__class__.__name__, + h=self.bbox.size[0], w=self.bbox.size[1], + naxes=len(self.axes), + ) + + def __init__(self, + figsize=None, + dpi=None, + *, + facecolor=None, + edgecolor=None, + linewidth=0.0, + frameon=None, + subplotpars=None, # rc figure.subplot.* + tight_layout=None, # rc figure.autolayout + constrained_layout=None, # rc figure.constrained_layout.use + layout=None, + **kwargs + ): + """ + Parameters + ---------- + figsize : 2-tuple of floats, default: :rc:`figure.figsize` + Figure dimension ``(width, height)`` in inches. + + dpi : float, default: :rc:`figure.dpi` + Dots per inch. + + facecolor : default: :rc:`figure.facecolor` + The figure patch facecolor. + + edgecolor : default: :rc:`figure.edgecolor` + The figure patch edge color. + + linewidth : float + The linewidth of the frame (i.e. the edge linewidth of the figure + patch). + + frameon : bool, default: :rc:`figure.frameon` + If ``False``, suppress drawing the figure background patch. + + subplotpars : `SubplotParams` + Subplot parameters. If not given, the default subplot + parameters :rc:`figure.subplot.*` are used. + + tight_layout : bool or dict, default: :rc:`figure.autolayout` + Whether to use the tight layout mechanism. See `.set_tight_layout`. + + .. admonition:: Discouraged + + The use of this parameter is discouraged. Please use + ``layout='tight'`` instead for the common case of + ``tight_layout=True`` and use `.set_tight_layout` otherwise. + + constrained_layout : bool, default: :rc:`figure.constrained_layout.use` + This is equal to ``layout='constrained'``. + + .. admonition:: Discouraged + + The use of this parameter is discouraged. Please use + ``layout='constrained'`` instead. + + layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, \ +None}, default: None + The layout mechanism for positioning of plot elements to avoid + overlapping Axes decorations (labels, ticks, etc). Note that + layout managers can have significant performance penalties. + + - 'constrained': The constrained layout solver adjusts axes sizes + to avoid overlapping axes decorations. Can handle complex plot + layouts and colorbars, and is thus recommended. + + See :ref:`constrainedlayout_guide` for examples. + + - 'compressed': uses the same algorithm as 'constrained', but + removes extra space between fixed-aspect-ratio Axes. Best for + simple grids of axes. + + - 'tight': Use the tight layout mechanism. This is a relatively + simple algorithm that adjusts the subplot parameters so that + decorations do not overlap. + + See :ref:`tight_layout_guide` for examples. + + - 'none': Do not use a layout engine. + + - A `.LayoutEngine` instance. Builtin layout classes are + `.ConstrainedLayoutEngine` and `.TightLayoutEngine`, more easily + accessible by 'constrained' and 'tight'. Passing an instance + allows third parties to provide their own layout engine. + + If not given, fall back to using the parameters *tight_layout* and + *constrained_layout*, including their config defaults + :rc:`figure.autolayout` and :rc:`figure.constrained_layout.use`. + + Other Parameters + ---------------- + **kwargs : `.Figure` properties, optional + + %(Figure:kwdoc)s + """ + super().__init__(**kwargs) + self.figure = self + self._layout_engine = None + + if layout is not None: + if (tight_layout is not None): + _api.warn_external( + "The Figure parameters 'layout' and 'tight_layout' cannot " + "be used together. Please use 'layout' only.") + if (constrained_layout is not None): + _api.warn_external( + "The Figure parameters 'layout' and 'constrained_layout' " + "cannot be used together. Please use 'layout' only.") + self.set_layout_engine(layout=layout) + elif tight_layout is not None: + if constrained_layout is not None: + _api.warn_external( + "The Figure parameters 'tight_layout' and " + "'constrained_layout' cannot be used together. Please use " + "'layout' parameter") + self.set_layout_engine(layout='tight') + if isinstance(tight_layout, dict): + self.get_layout_engine().set(**tight_layout) + elif constrained_layout is not None: + if isinstance(constrained_layout, dict): + self.set_layout_engine(layout='constrained') + self.get_layout_engine().set(**constrained_layout) + elif constrained_layout: + self.set_layout_engine(layout='constrained') + + else: + # everything is None, so use default: + self.set_layout_engine(layout=layout) + + # Callbacks traditionally associated with the canvas (and exposed with + # a proxy property), but that actually need to be on the figure for + # pickling. + self._canvas_callbacks = cbook.CallbackRegistry( + signals=FigureCanvasBase.events) + connect = self._canvas_callbacks._connect_picklable + self._mouse_key_ids = [ + connect('key_press_event', backend_bases._key_handler), + connect('key_release_event', backend_bases._key_handler), + connect('key_release_event', backend_bases._key_handler), + connect('button_press_event', backend_bases._mouse_handler), + connect('button_release_event', backend_bases._mouse_handler), + connect('scroll_event', backend_bases._mouse_handler), + connect('motion_notify_event', backend_bases._mouse_handler), + ] + self._button_pick_id = connect('button_press_event', self.pick) + self._scroll_pick_id = connect('scroll_event', self.pick) + + if figsize is None: + figsize = mpl.rcParams['figure.figsize'] + if dpi is None: + dpi = mpl.rcParams['figure.dpi'] + if facecolor is None: + facecolor = mpl.rcParams['figure.facecolor'] + if edgecolor is None: + edgecolor = mpl.rcParams['figure.edgecolor'] + if frameon is None: + frameon = mpl.rcParams['figure.frameon'] + + if not np.isfinite(figsize).all() or (np.array(figsize) < 0).any(): + raise ValueError('figure size must be positive finite not ' + f'{figsize}') + self.bbox_inches = Bbox.from_bounds(0, 0, *figsize) + + self.dpi_scale_trans = Affine2D().scale(dpi) + # do not use property as it will trigger + self._dpi = dpi + self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans) + self.figbbox = self.bbox + self.transFigure = BboxTransformTo(self.bbox) + self.transSubfigure = self.transFigure + + self.patch = Rectangle( + xy=(0, 0), width=1, height=1, visible=frameon, + facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth, + # Don't let the figure patch influence bbox calculation. + in_layout=False) + self._set_artist_props(self.patch) + self.patch.set_antialiased(False) + + FigureCanvasBase(self) # Set self.canvas. + + if subplotpars is None: + subplotpars = SubplotParams() + + self.subplotpars = subplotpars + + self._axstack = _AxesStack() # track all figure axes and current axes + self.clear() + + def pick(self, mouseevent): + if not self.canvas.widgetlock.locked(): + super().pick(mouseevent) + + def _check_layout_engines_compat(self, old, new): + """ + Helper for set_layout engine + + If the figure has used the old engine and added a colorbar then the + value of colorbar_gridspec must be the same on the new engine. + """ + if old is None or new is None: + return True + if old.colorbar_gridspec == new.colorbar_gridspec: + return True + # colorbar layout different, so check if any colorbars are on the + # figure... + for ax in self.axes: + if hasattr(ax, '_colorbar'): + # colorbars list themselves as a colorbar. + return False + return True + + def set_layout_engine(self, layout=None, **kwargs): + """ + Set the layout engine for this figure. + + Parameters + ---------- + layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, None} + + - 'constrained' will use `~.ConstrainedLayoutEngine` + - 'compressed' will also use `~.ConstrainedLayoutEngine`, but with + a correction that attempts to make a good layout for fixed-aspect + ratio Axes. + - 'tight' uses `~.TightLayoutEngine` + - 'none' removes layout engine. + + If a `.LayoutEngine` instance, that instance will be used. + + If `None`, the behavior is controlled by :rc:`figure.autolayout` + (which if `True` behaves as if 'tight' was passed) and + :rc:`figure.constrained_layout.use` (which if `True` behaves as if + 'constrained' was passed). If both are `True`, + :rc:`figure.autolayout` takes priority. + + Users and libraries can define their own layout engines and pass + the instance directly as well. + + **kwargs + The keyword arguments are passed to the layout engine to set things + like padding and margin sizes. Only used if *layout* is a string. + + """ + if layout is None: + if mpl.rcParams['figure.autolayout']: + layout = 'tight' + elif mpl.rcParams['figure.constrained_layout.use']: + layout = 'constrained' + else: + self._layout_engine = None + return + if layout == 'tight': + new_layout_engine = TightLayoutEngine(**kwargs) + elif layout == 'constrained': + new_layout_engine = ConstrainedLayoutEngine(**kwargs) + elif layout == 'compressed': + new_layout_engine = ConstrainedLayoutEngine(compress=True, + **kwargs) + elif layout == 'none': + if self._layout_engine is not None: + new_layout_engine = PlaceHolderLayoutEngine( + self._layout_engine.adjust_compatible, + self._layout_engine.colorbar_gridspec + ) + else: + new_layout_engine = None + elif isinstance(layout, LayoutEngine): + new_layout_engine = layout + else: + raise ValueError(f"Invalid value for 'layout': {layout!r}") + + if self._check_layout_engines_compat(self._layout_engine, + new_layout_engine): + self._layout_engine = new_layout_engine + else: + raise RuntimeError('Colorbar layout of new layout engine not ' + 'compatible with old engine, and a colorbar ' + 'has been created. Engine not changed.') + + def get_layout_engine(self): + return self._layout_engine + + # TODO: I'd like to dynamically add the _repr_html_ method + # to the figure in the right context, but then IPython doesn't + # use it, for some reason. + + def _repr_html_(self): + # We can't use "isinstance" here, because then we'd end up importing + # webagg unconditionally. + if 'WebAgg' in type(self.canvas).__name__: + from matplotlib.backends import backend_webagg + return backend_webagg.ipython_inline_display(self) + + def show(self, warn=True): + """ + If using a GUI backend with pyplot, display the figure window. + + If the figure was not created using `~.pyplot.figure`, it will lack + a `~.backend_bases.FigureManagerBase`, and this method will raise an + AttributeError. + + .. warning:: + + This does not manage an GUI event loop. Consequently, the figure + may only be shown briefly or not shown at all if you or your + environment are not managing an event loop. + + Use cases for `.Figure.show` include running this from a GUI + application (where there is persistently an event loop running) or + from a shell, like IPython, that install an input hook to allow the + interactive shell to accept input while the figure is also being + shown and interactive. Some, but not all, GUI toolkits will + register an input hook on import. See :ref:`cp_integration` for + more details. + + If you're in a shell without input hook integration or executing a + python script, you should use `matplotlib.pyplot.show` with + ``block=True`` instead, which takes care of starting and running + the event loop for you. + + Parameters + ---------- + warn : bool, default: True + If ``True`` and we are not running headless (i.e. on Linux with an + unset DISPLAY), issue warning when called on a non-GUI backend. + + """ + if self.canvas.manager is None: + raise AttributeError( + "Figure.show works only for figures managed by pyplot, " + "normally created by pyplot.figure()") + try: + self.canvas.manager.show() + except NonGuiException as exc: + if warn: + _api.warn_external(str(exc)) + + @property + def axes(self): + """ + List of Axes in the Figure. You can access and modify the Axes in the + Figure through this list. + + Do not modify the list itself. Instead, use `~Figure.add_axes`, + `~.Figure.add_subplot` or `~.Figure.delaxes` to add or remove an Axes. + + Note: The `.Figure.axes` property and `~.Figure.get_axes` method are + equivalent. + """ + return self._axstack.as_list() + + get_axes = axes.fget + + def _get_renderer(self): + if hasattr(self.canvas, 'get_renderer'): + return self.canvas.get_renderer() + else: + return _get_renderer(self) + + def _get_dpi(self): + return self._dpi + + def _set_dpi(self, dpi, forward=True): + """ + Parameters + ---------- + dpi : float + + forward : bool + Passed on to `~.Figure.set_size_inches` + """ + if dpi == self._dpi: + # We don't want to cause undue events in backends. + return + self._dpi = dpi + self.dpi_scale_trans.clear().scale(dpi) + w, h = self.get_size_inches() + self.set_size_inches(w, h, forward=forward) + + dpi = property(_get_dpi, _set_dpi, doc="The resolution in dots per inch.") + + def get_tight_layout(self): + """Return whether `.tight_layout` is called when drawing.""" + return isinstance(self.get_layout_engine(), TightLayoutEngine) + + @_api.deprecated("3.6", alternative="set_layout_engine", + pending=True) + def set_tight_layout(self, tight): + """ + Set whether and how `.tight_layout` is called when drawing. + + Parameters + ---------- + tight : bool or dict with keys "pad", "w_pad", "h_pad", "rect" or None + If a bool, sets whether to call `.tight_layout` upon drawing. + If ``None``, use :rc:`figure.autolayout` instead. + If a dict, pass it as kwargs to `.tight_layout`, overriding the + default paddings. + """ + if tight is None: + tight = mpl.rcParams['figure.autolayout'] + _tight = 'tight' if bool(tight) else 'none' + _tight_parameters = tight if isinstance(tight, dict) else {} + self.set_layout_engine(_tight, **_tight_parameters) + self.stale = True + + def get_constrained_layout(self): + """ + Return whether constrained layout is being used. + + See :ref:`constrainedlayout_guide`. + """ + return isinstance(self.get_layout_engine(), ConstrainedLayoutEngine) + + @_api.deprecated("3.6", alternative="set_layout_engine('constrained')", + pending=True) + def set_constrained_layout(self, constrained): + """ + Set whether ``constrained_layout`` is used upon drawing. + + If None, :rc:`figure.constrained_layout.use` value will be used. + + When providing a dict containing the keys ``w_pad``, ``h_pad`` + the default ``constrained_layout`` paddings will be + overridden. These pads are in inches and default to 3.0/72.0. + ``w_pad`` is the width padding and ``h_pad`` is the height padding. + + Parameters + ---------- + constrained : bool or dict or None + """ + if constrained is None: + constrained = mpl.rcParams['figure.constrained_layout.use'] + _constrained = 'constrained' if bool(constrained) else 'none' + _parameters = constrained if isinstance(constrained, dict) else {} + self.set_layout_engine(_constrained, **_parameters) + self.stale = True + + @_api.deprecated( + "3.6", alternative="figure.get_layout_engine().set()", + pending=True) + def set_constrained_layout_pads(self, **kwargs): + """ + Set padding for ``constrained_layout``. + + Tip: The parameters can be passed from a dictionary by using + ``fig.set_constrained_layout(**pad_dict)``. + + See :ref:`constrainedlayout_guide`. + + Parameters + ---------- + w_pad : float, default: :rc:`figure.constrained_layout.w_pad` + Width padding in inches. This is the pad around Axes + and is meant to make sure there is enough room for fonts to + look good. Defaults to 3 pts = 0.04167 inches + + h_pad : float, default: :rc:`figure.constrained_layout.h_pad` + Height padding in inches. Defaults to 3 pts. + + wspace : float, default: :rc:`figure.constrained_layout.wspace` + Width padding between subplots, expressed as a fraction of the + subplot width. The total padding ends up being w_pad + wspace. + + hspace : float, default: :rc:`figure.constrained_layout.hspace` + Height padding between subplots, expressed as a fraction of the + subplot width. The total padding ends up being h_pad + hspace. + + """ + if isinstance(self.get_layout_engine(), ConstrainedLayoutEngine): + self.get_layout_engine().set(**kwargs) + + @_api.deprecated("3.6", alternative="fig.get_layout_engine().get()", + pending=True) + def get_constrained_layout_pads(self, relative=False): + """ + Get padding for ``constrained_layout``. + + Returns a list of ``w_pad, h_pad`` in inches and + ``wspace`` and ``hspace`` as fractions of the subplot. + All values are None if ``constrained_layout`` is not used. + + See :ref:`constrainedlayout_guide`. + + Parameters + ---------- + relative : bool + If `True`, then convert from inches to figure relative. + """ + if not isinstance(self.get_layout_engine(), ConstrainedLayoutEngine): + return None, None, None, None + info = self.get_layout_engine().get() + w_pad = info['w_pad'] + h_pad = info['h_pad'] + wspace = info['wspace'] + hspace = info['hspace'] + + if relative and (w_pad is not None or h_pad is not None): + renderer = self._get_renderer() + dpi = renderer.dpi + w_pad = w_pad * dpi / renderer.width + h_pad = h_pad * dpi / renderer.height + + return w_pad, h_pad, wspace, hspace + + def set_canvas(self, canvas): + """ + Set the canvas that contains the figure + + Parameters + ---------- + canvas : FigureCanvas + """ + self.canvas = canvas + + @_docstring.interpd + def figimage(self, X, xo=0, yo=0, alpha=None, norm=None, cmap=None, + vmin=None, vmax=None, origin=None, resize=False, **kwargs): + """ + Add a non-resampled image to the figure. + + The image is attached to the lower or upper left corner depending on + *origin*. + + Parameters + ---------- + X + The image data. This is an array of one of the following shapes: + + - (M, N): an image with scalar data. Color-mapping is controlled + by *cmap*, *norm*, *vmin*, and *vmax*. + - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). + - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), + i.e. including transparency. + + xo, yo : int + The *x*/*y* image offset in pixels. + + alpha : None or float + The alpha blending value. + + %(cmap_doc)s + + This parameter is ignored if *X* is RGB(A). + + %(norm_doc)s + + This parameter is ignored if *X* is RGB(A). + + %(vmin_vmax_doc)s + + This parameter is ignored if *X* is RGB(A). + + origin : {'upper', 'lower'}, default: :rc:`image.origin` + Indicates where the [0, 0] index of the array is in the upper left + or lower left corner of the axes. + + resize : bool + If *True*, resize the figure to match the given image size. + + Returns + ------- + `matplotlib.image.FigureImage` + + Other Parameters + ---------------- + **kwargs + Additional kwargs are `.Artist` kwargs passed on to `.FigureImage`. + + Notes + ----- + figimage complements the Axes image (`~matplotlib.axes.Axes.imshow`) + which will be resampled to fit the current Axes. If you want + a resampled image to fill the entire figure, you can define an + `~matplotlib.axes.Axes` with extent [0, 0, 1, 1]. + + Examples + -------- + :: + + f = plt.figure() + nx = int(f.get_figwidth() * f.dpi) + ny = int(f.get_figheight() * f.dpi) + data = np.random.random((ny, nx)) + f.figimage(data) + plt.show() + """ + if resize: + dpi = self.get_dpi() + figsize = [x / dpi for x in (X.shape[1], X.shape[0])] + self.set_size_inches(figsize, forward=True) + + im = mimage.FigureImage(self, cmap=cmap, norm=norm, + offsetx=xo, offsety=yo, + origin=origin, **kwargs) + im.stale_callback = _stale_figure_callback + + im.set_array(X) + im.set_alpha(alpha) + if norm is None: + im.set_clim(vmin, vmax) + self.images.append(im) + im._remove_method = self.images.remove + self.stale = True + return im + + def set_size_inches(self, w, h=None, forward=True): + """ + Set the figure size in inches. + + Call signatures:: + + fig.set_size_inches(w, h) # OR + fig.set_size_inches((w, h)) + + Parameters + ---------- + w : (float, float) or float + Width and height in inches (if height not specified as a separate + argument) or width. + h : float + Height in inches. + forward : bool, default: True + If ``True``, the canvas size is automatically updated, e.g., + you can resize the figure window from the shell. + + See Also + -------- + matplotlib.figure.Figure.get_size_inches + matplotlib.figure.Figure.set_figwidth + matplotlib.figure.Figure.set_figheight + + Notes + ----- + To transform from pixels to inches divide by `Figure.dpi`. + """ + if h is None: # Got called with a single pair as argument. + w, h = w + size = np.array([w, h]) + if not np.isfinite(size).all() or (size < 0).any(): + raise ValueError(f'figure size must be positive finite not {size}') + self.bbox_inches.p1 = size + if forward: + manager = self.canvas.manager + if manager is not None: + manager.resize(*(size * self.dpi).astype(int)) + self.stale = True + + def get_size_inches(self): + """ + Return the current size of the figure in inches. + + Returns + ------- + ndarray + The size (width, height) of the figure in inches. + + See Also + -------- + matplotlib.figure.Figure.set_size_inches + matplotlib.figure.Figure.get_figwidth + matplotlib.figure.Figure.get_figheight + + Notes + ----- + The size in pixels can be obtained by multiplying with `Figure.dpi`. + """ + return np.array(self.bbox_inches.p1) + + def get_figwidth(self): + """Return the figure width in inches.""" + return self.bbox_inches.width + + def get_figheight(self): + """Return the figure height in inches.""" + return self.bbox_inches.height + + def get_dpi(self): + """Return the resolution in dots per inch as a float.""" + return self.dpi + + def set_dpi(self, val): + """ + Set the resolution of the figure in dots-per-inch. + + Parameters + ---------- + val : float + """ + self.dpi = val + self.stale = True + + def set_figwidth(self, val, forward=True): + """ + Set the width of the figure in inches. + + Parameters + ---------- + val : float + forward : bool + See `set_size_inches`. + + See Also + -------- + matplotlib.figure.Figure.set_figheight + matplotlib.figure.Figure.set_size_inches + """ + self.set_size_inches(val, self.get_figheight(), forward=forward) + + def set_figheight(self, val, forward=True): + """ + Set the height of the figure in inches. + + Parameters + ---------- + val : float + forward : bool + See `set_size_inches`. + + See Also + -------- + matplotlib.figure.Figure.set_figwidth + matplotlib.figure.Figure.set_size_inches + """ + self.set_size_inches(self.get_figwidth(), val, forward=forward) + + def clear(self, keep_observers=False): + # docstring inherited + super().clear(keep_observers=keep_observers) + # FigureBase.clear does not clear toolbars, as + # only Figure can have toolbars + toolbar = self.canvas.toolbar + if toolbar is not None: + toolbar.update() + + @_finalize_rasterization + @allow_rasterization + def draw(self, renderer): + # docstring inherited + if not self.get_visible(): + return + + with self._render_lock: + + artists = self._get_draw_artists(renderer) + try: + renderer.open_group('figure', gid=self.get_gid()) + if self.axes and self.get_layout_engine() is not None: + try: + self.get_layout_engine().execute(self) + except ValueError: + pass + # ValueError can occur when resizing a window. + + self.patch.draw(renderer) + mimage._draw_list_compositing_images( + renderer, self, artists, self.suppressComposite) + + for sfig in self.subfigs: + sfig.draw(renderer) + + renderer.close_group('figure') + finally: + self.stale = False + + DrawEvent("draw_event", self.canvas, renderer)._process() + + def draw_without_rendering(self): + """ + Draw the figure with no output. Useful to get the final size of + artists that require a draw before their size is known (e.g. text). + """ + renderer = _get_renderer(self) + with renderer._draw_disabled(): + self.draw(renderer) + + def draw_artist(self, a): + """ + Draw `.Artist` *a* only. + """ + a.draw(self.canvas.get_renderer()) + + def __getstate__(self): + state = super().__getstate__() + + # The canvas cannot currently be pickled, but this has the benefit + # of meaning that a figure can be detached from one canvas, and + # re-attached to another. + state.pop("canvas") + + # discard any changes to the dpi due to pixel ratio changes + state["_dpi"] = state.get('_original_dpi', state['_dpi']) + + # add version information to the state + state['__mpl_version__'] = mpl.__version__ + + # check whether the figure manager (if any) is registered with pyplot + from matplotlib import _pylab_helpers + if self.canvas.manager in _pylab_helpers.Gcf.figs.values(): + state['_restore_to_pylab'] = True + return state + + def __setstate__(self, state): + version = state.pop('__mpl_version__') + restore_to_pylab = state.pop('_restore_to_pylab', False) + + if version != mpl.__version__: + _api.warn_external( + f"This figure was saved with matplotlib version {version} and " + f"is unlikely to function correctly.") + + self.__dict__ = state + + # re-initialise some of the unstored state information + FigureCanvasBase(self) # Set self.canvas. + + if restore_to_pylab: + # lazy import to avoid circularity + import matplotlib.pyplot as plt + import matplotlib._pylab_helpers as pylab_helpers + allnums = plt.get_fignums() + num = max(allnums) + 1 if allnums else 1 + backend = plt._get_backend_mod() + mgr = backend.new_figure_manager_given_figure(num, self) + pylab_helpers.Gcf._set_new_active_manager(mgr) + plt.draw_if_interactive() + + self.stale = True + + def add_axobserver(self, func): + """Whenever the Axes state change, ``func(self)`` will be called.""" + # Connect a wrapper lambda and not func itself, to avoid it being + # weakref-collected. + self._axobservers.connect("_axes_change_event", lambda arg: func(arg)) + + def savefig(self, fname, *, transparent=None, **kwargs): + """ + Save the current figure. + + Call signature:: + + savefig(fname, *, transparent=None, dpi='figure', format=None, + metadata=None, bbox_inches=None, pad_inches=0.1, + facecolor='auto', edgecolor='auto', backend=None, + **kwargs + ) + + The available output formats depend on the backend being used. + + Parameters + ---------- + fname : str or path-like or binary file-like + A path, or a Python file-like object, or + possibly some backend-dependent object such as + `matplotlib.backends.backend_pdf.PdfPages`. + + If *format* is set, it determines the output format, and the file + is saved as *fname*. Note that *fname* is used verbatim, and there + is no attempt to make the extension, if any, of *fname* match + *format*, and no extension is appended. + + If *format* is not set, then the format is inferred from the + extension of *fname*, if there is one. If *format* is not + set and *fname* has no extension, then the file is saved with + :rc:`savefig.format` and the appropriate extension is appended to + *fname*. + + Other Parameters + ---------------- + transparent : bool, default: :rc:`savefig.transparent` + If *True*, the Axes patches will all be transparent; the + Figure patch will also be transparent unless *facecolor* + and/or *edgecolor* are specified via kwargs. + + If *False* has no effect and the color of the Axes and + Figure patches are unchanged (unless the Figure patch + is specified via the *facecolor* and/or *edgecolor* keyword + arguments in which case those colors are used). + + The transparency of these patches will be restored to their + original values upon exit of this function. + + This is useful, for example, for displaying + a plot on top of a colored background on a web page. + + dpi : float or 'figure', default: :rc:`savefig.dpi` + The resolution in dots per inch. If 'figure', use the figure's + dpi value. + + format : str + The file format, e.g. 'png', 'pdf', 'svg', ... The behavior when + this is unset is documented under *fname*. + + metadata : dict, optional + Key/value pairs to store in the image metadata. The supported keys + and defaults depend on the image format and backend: + + - 'png' with Agg backend: See the parameter ``metadata`` of + `~.FigureCanvasAgg.print_png`. + - 'pdf' with pdf backend: See the parameter ``metadata`` of + `~.backend_pdf.PdfPages`. + - 'svg' with svg backend: See the parameter ``metadata`` of + `~.FigureCanvasSVG.print_svg`. + - 'eps' and 'ps' with PS backend: Only 'Creator' is supported. + + Not supported for 'pgf', 'raw', and 'rgba' as those formats do not support + embedding metadata. + Does not currently support 'jpg', 'tiff', or 'webp', but may include + embedding EXIF metadata in the future. + + bbox_inches : str or `.Bbox`, default: :rc:`savefig.bbox` + Bounding box in inches: only the given portion of the figure is + saved. If 'tight', try to figure out the tight bbox of the figure. + + pad_inches : float or 'layout', default: :rc:`savefig.pad_inches` + Amount of padding in inches around the figure when bbox_inches is + 'tight'. If 'layout' use the padding from the constrained or + compressed layout engine; ignored if one of those engines is not in + use. + + facecolor : color or 'auto', default: :rc:`savefig.facecolor` + The facecolor of the figure. If 'auto', use the current figure + facecolor. + + edgecolor : color or 'auto', default: :rc:`savefig.edgecolor` + The edgecolor of the figure. If 'auto', use the current figure + edgecolor. + + backend : str, optional + Use a non-default backend to render the file, e.g. to render a + png file with the "cairo" backend rather than the default "agg", + or a pdf file with the "pgf" backend rather than the default + "pdf". Note that the default backend is normally sufficient. See + :ref:`the-builtin-backends` for a list of valid backends for each + file format. Custom backends can be referenced as "module://...". + + orientation : {'landscape', 'portrait'} + Currently only supported by the postscript backend. + + papertype : str + One of 'letter', 'legal', 'executive', 'ledger', 'a0' through + 'a10', 'b0' through 'b10'. Only supported for postscript + output. + + bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional + A list of extra artists that will be considered when the + tight bbox is calculated. + + pil_kwargs : dict, optional + Additional keyword arguments that are passed to + `PIL.Image.Image.save` when saving the figure. + + """ + + kwargs.setdefault('dpi', mpl.rcParams['savefig.dpi']) + if transparent is None: + transparent = mpl.rcParams['savefig.transparent'] + + with ExitStack() as stack: + if transparent: + def _recursively_make_subfig_transparent(exit_stack, subfig): + exit_stack.enter_context( + subfig.patch._cm_set( + facecolor="none", edgecolor="none")) + for ax in subfig.axes: + exit_stack.enter_context( + ax.patch._cm_set( + facecolor="none", edgecolor="none")) + for sub_subfig in subfig.subfigs: + _recursively_make_subfig_transparent( + exit_stack, sub_subfig) + + def _recursively_make_axes_transparent(exit_stack, ax): + exit_stack.enter_context( + ax.patch._cm_set(facecolor="none", edgecolor="none")) + for child_ax in ax.child_axes: + exit_stack.enter_context( + child_ax.patch._cm_set( + facecolor="none", edgecolor="none")) + for child_childax in ax.child_axes: + _recursively_make_axes_transparent( + exit_stack, child_childax) + + kwargs.setdefault('facecolor', 'none') + kwargs.setdefault('edgecolor', 'none') + # set subfigure to appear transparent in printed image + for subfig in self.subfigs: + _recursively_make_subfig_transparent(stack, subfig) + # set axes to be transparent + for ax in self.axes: + _recursively_make_axes_transparent(stack, ax) + self.canvas.print_figure(fname, **kwargs) + + def ginput(self, n=1, timeout=30, show_clicks=True, + mouse_add=MouseButton.LEFT, + mouse_pop=MouseButton.RIGHT, + mouse_stop=MouseButton.MIDDLE): + """ + Blocking call to interact with a figure. + + Wait until the user clicks *n* times on the figure, and return the + coordinates of each click in a list. + + There are three possible interactions: + + - Add a point. + - Remove the most recently added point. + - Stop the interaction and return the points added so far. + + The actions are assigned to mouse buttons via the arguments + *mouse_add*, *mouse_pop* and *mouse_stop*. + + Parameters + ---------- + n : int, default: 1 + Number of mouse clicks to accumulate. If negative, accumulate + clicks until the input is terminated manually. + timeout : float, default: 30 seconds + Number of seconds to wait before timing out. If zero or negative + will never time out. + show_clicks : bool, default: True + If True, show a red cross at the location of each click. + mouse_add : `.MouseButton` or None, default: `.MouseButton.LEFT` + Mouse button used to add points. + mouse_pop : `.MouseButton` or None, default: `.MouseButton.RIGHT` + Mouse button used to remove the most recently added point. + mouse_stop : `.MouseButton` or None, default: `.MouseButton.MIDDLE` + Mouse button used to stop input. + + Returns + ------- + list of tuples + A list of the clicked (x, y) coordinates. + + Notes + ----- + The keyboard can also be used to select points in case your mouse + does not have one or more of the buttons. The delete and backspace + keys act like right-clicking (i.e., remove last point), the enter key + terminates input and any other key (not already used by the window + manager) selects a point. + """ + clicks = [] + marks = [] + + def handler(event): + is_button = event.name == "button_press_event" + is_key = event.name == "key_press_event" + # Quit (even if not in infinite mode; this is consistent with + # MATLAB and sometimes quite useful, but will require the user to + # test how many points were actually returned before using data). + if (is_button and event.button == mouse_stop + or is_key and event.key in ["escape", "enter"]): + self.canvas.stop_event_loop() + # Pop last click. + elif (is_button and event.button == mouse_pop + or is_key and event.key in ["backspace", "delete"]): + if clicks: + clicks.pop() + if show_clicks: + marks.pop().remove() + self.canvas.draw() + # Add new click. + elif (is_button and event.button == mouse_add + # On macOS/gtk, some keys return None. + or is_key and event.key is not None): + if event.inaxes: + clicks.append((event.xdata, event.ydata)) + _log.info("input %i: %f, %f", + len(clicks), event.xdata, event.ydata) + if show_clicks: + line = mpl.lines.Line2D([event.xdata], [event.ydata], + marker="+", color="r") + event.inaxes.add_line(line) + marks.append(line) + self.canvas.draw() + if len(clicks) == n and n > 0: + self.canvas.stop_event_loop() + + _blocking_input.blocking_input_loop( + self, ["button_press_event", "key_press_event"], timeout, handler) + + # Cleanup. + for mark in marks: + mark.remove() + self.canvas.draw() + + return clicks + + def waitforbuttonpress(self, timeout=-1): + """ + Blocking call to interact with the figure. + + Wait for user input and return True if a key was pressed, False if a + mouse button was pressed and None if no input was given within + *timeout* seconds. Negative values deactivate *timeout*. + """ + event = None + + def handler(ev): + nonlocal event + event = ev + self.canvas.stop_event_loop() + + _blocking_input.blocking_input_loop( + self, ["button_press_event", "key_press_event"], timeout, handler) + + return None if event is None else event.name == "key_press_event" + + def tight_layout(self, *, pad=1.08, h_pad=None, w_pad=None, rect=None): + """ + Adjust the padding between and around subplots. + + To exclude an artist on the Axes from the bounding box calculation + that determines the subplot parameters (i.e. legend, or annotation), + set ``a.set_in_layout(False)`` for that artist. + + Parameters + ---------- + pad : float, default: 1.08 + Padding between the figure edge and the edges of subplots, + as a fraction of the font size. + h_pad, w_pad : float, default: *pad* + Padding (height/width) between edges of adjacent subplots, + as a fraction of the font size. + rect : tuple (left, bottom, right, top), default: (0, 0, 1, 1) + A rectangle in normalized figure coordinates into which the whole + subplots area (including labels) will fit. + + See Also + -------- + .Figure.set_layout_engine + .pyplot.tight_layout + """ + # note that here we do not permanently set the figures engine to + # tight_layout but rather just perform the layout in place and remove + # any previous engines. + engine = TightLayoutEngine(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) + try: + previous_engine = self.get_layout_engine() + self.set_layout_engine(engine) + engine.execute(self) + if previous_engine is not None and not isinstance( + previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine) + ): + _api.warn_external('The figure layout has changed to tight') + finally: + self.set_layout_engine('none') + + +def figaspect(arg): + """ + Calculate the width and height for a figure with a specified aspect ratio. + + While the height is taken from :rc:`figure.figsize`, the width is + adjusted to match the desired aspect ratio. Additionally, it is ensured + that the width is in the range [4., 16.] and the height is in the range + [2., 16.]. If necessary, the default height is adjusted to ensure this. + + Parameters + ---------- + arg : float or 2D array + If a float, this defines the aspect ratio (i.e. the ratio height / + width). + In case of an array the aspect ratio is number of rows / number of + columns, so that the array could be fitted in the figure undistorted. + + Returns + ------- + width, height : float + The figure size in inches. + + Notes + ----- + If you want to create an Axes within the figure, that still preserves the + aspect ratio, be sure to create it with equal width and height. See + examples below. + + Thanks to Fernando Perez for this function. + + Examples + -------- + Make a figure twice as tall as it is wide:: + + w, h = figaspect(2.) + fig = Figure(figsize=(w, h)) + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) + ax.imshow(A, **kwargs) + + Make a figure with the proper aspect for an array:: + + A = rand(5, 3) + w, h = figaspect(A) + fig = Figure(figsize=(w, h)) + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) + ax.imshow(A, **kwargs) + """ + + isarray = hasattr(arg, 'shape') and not np.isscalar(arg) + + # min/max sizes to respect when autoscaling. If John likes the idea, they + # could become rc parameters, for now they're hardwired. + figsize_min = np.array((4.0, 2.0)) # min length for width/height + figsize_max = np.array((16.0, 16.0)) # max length for width/height + + # Extract the aspect ratio of the array + if isarray: + nr, nc = arg.shape[:2] + arr_ratio = nr / nc + else: + arr_ratio = arg + + # Height of user figure defaults + fig_height = mpl.rcParams['figure.figsize'][1] + + # New size for the figure, keeping the aspect ratio of the caller + newsize = np.array((fig_height / arr_ratio, fig_height)) + + # Sanity checks, don't drop either dimension below figsize_min + newsize /= min(1.0, *(newsize / figsize_min)) + + # Avoid humongous windows as well + newsize /= max(1.0, *(newsize / figsize_max)) + + # Finally, if we have a really funky aspect ratio, break it but respect + # the min/max dimensions (we don't want figures 10 feet tall!) + newsize = np.clip(newsize, figsize_min, figsize_max) + return newsize diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.pyi new file mode 100644 index 00000000..887b6ed5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/figure.pyi @@ -0,0 +1,416 @@ +from collections.abc import Callable, Hashable, Iterable +import os +from typing import Any, IO, Literal, TypeVar, overload + +import numpy as np +from numpy.typing import ArrayLike + +from matplotlib.artist import Artist +from matplotlib.axes import Axes, SubplotBase +from matplotlib.backend_bases import ( + FigureCanvasBase, + MouseButton, + MouseEvent, + RendererBase, +) +from matplotlib.colors import Colormap, Normalize +from matplotlib.colorbar import Colorbar +from matplotlib.cm import ScalarMappable +from matplotlib.gridspec import GridSpec, SubplotSpec +from matplotlib.image import _ImageBase, FigureImage +from matplotlib.layout_engine import LayoutEngine +from matplotlib.legend import Legend +from matplotlib.lines import Line2D +from matplotlib.patches import Rectangle, Patch +from matplotlib.text import Text +from matplotlib.transforms import Affine2D, Bbox, BboxBase, Transform +from .typing import ColorType, HashableList + +_T = TypeVar("_T") + +class SubplotParams: + def __init__( + self, + left: float | None = ..., + bottom: float | None = ..., + right: float | None = ..., + top: float | None = ..., + wspace: float | None = ..., + hspace: float | None = ..., + ) -> None: ... + left: float + right: float + bottom: float + top: float + wspace: float + hspace: float + def update( + self, + left: float | None = ..., + bottom: float | None = ..., + right: float | None = ..., + top: float | None = ..., + wspace: float | None = ..., + hspace: float | None = ..., + ) -> None: ... + +class FigureBase(Artist): + artists: list[Artist] + lines: list[Line2D] + patches: list[Patch] + texts: list[Text] + images: list[_ImageBase] + legends: list[Legend] + subfigs: list[SubFigure] + stale: bool + suppressComposite: bool | None + def __init__(self, **kwargs) -> None: ... + def autofmt_xdate( + self, + bottom: float = ..., + rotation: int = ..., + ha: Literal["left", "center", "right"] = ..., + which: Literal["major", "minor", "both"] = ..., + ) -> None: ... + def get_children(self) -> list[Artist]: ... + def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict[Any, Any]]: ... + def suptitle(self, t: str, **kwargs) -> Text: ... + def get_suptitle(self) -> str: ... + def supxlabel(self, t: str, **kwargs) -> Text: ... + def get_supxlabel(self) -> str: ... + def supylabel(self, t: str, **kwargs) -> Text: ... + def get_supylabel(self) -> str: ... + def get_edgecolor(self) -> ColorType: ... + def get_facecolor(self) -> ColorType: ... + def get_frameon(self) -> bool: ... + def set_linewidth(self, linewidth: float) -> None: ... + def get_linewidth(self) -> float: ... + def set_edgecolor(self, color: ColorType) -> None: ... + def set_facecolor(self, color: ColorType) -> None: ... + def set_frameon(self, b: bool) -> None: ... + @property + def frameon(self) -> bool: ... + @frameon.setter + def frameon(self, b: bool) -> None: ... + def add_artist(self, artist: Artist, clip: bool = ...) -> Artist: ... + @overload + def add_axes(self, ax: Axes) -> Axes: ... + @overload + def add_axes( + self, + rect: tuple[float, float, float, float], + projection: None | str = ..., + polar: bool = ..., + **kwargs + ) -> Axes: ... + + # TODO: docstring indicates SubplotSpec a valid arg, but none of the listed signatures appear to be that + @overload + def add_subplot( + self, nrows: int, ncols: int, index: int | tuple[int, int], **kwargs + ) -> Axes: ... + @overload + def add_subplot(self, pos: int, **kwargs) -> Axes: ... + @overload + def add_subplot(self, ax: Axes, **kwargs) -> Axes: ... + @overload + def add_subplot(self, ax: SubplotSpec, **kwargs) -> Axes: ... + @overload + def add_subplot(self, **kwargs) -> Axes: ... + @overload + def subplots( + self, + nrows: int = ..., + ncols: int = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[False], + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ... + ) -> np.ndarray: ... + @overload + def subplots( + self, + nrows: int = ..., + ncols: int = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ... + ) -> np.ndarray | SubplotBase | Axes: ... + def delaxes(self, ax: Axes) -> None: ... + def clear(self, keep_observers: bool = ...) -> None: ... + def clf(self, keep_observers: bool = ...) -> None: ... + + @overload + def legend(self) -> Legend: ... + @overload + def legend(self, handles: Iterable[Artist], labels: Iterable[str], **kwargs) -> Legend: ... + @overload + def legend(self, *, handles: Iterable[Artist], **kwargs) -> Legend: ... + @overload + def legend(self, labels: Iterable[str], **kwargs) -> Legend: ... + @overload + def legend(self, **kwargs) -> Legend: ... + + def text( + self, + x: float, + y: float, + s: str, + fontdict: dict[str, Any] | None = ..., + **kwargs + ) -> Text: ... + def colorbar( + self, + mappable: ScalarMappable, + cax: Axes | None = ..., + ax: Axes | Iterable[Axes] | None = ..., + use_gridspec: bool = ..., + **kwargs + ) -> Colorbar: ... + def subplots_adjust( + self, + left: float | None = ..., + bottom: float | None = ..., + right: float | None = ..., + top: float | None = ..., + wspace: float | None = ..., + hspace: float | None = ..., + ) -> None: ... + def align_xlabels(self, axs: Iterable[Axes] | None = ...) -> None: ... + def align_ylabels(self, axs: Iterable[Axes] | None = ...) -> None: ... + def align_labels(self, axs: Iterable[Axes] | None = ...) -> None: ... + def add_gridspec(self, nrows: int = ..., ncols: int = ..., **kwargs) -> GridSpec: ... + @overload + def subfigures( + self, + nrows: int = ..., + ncols: int = ..., + squeeze: Literal[False] = ..., + wspace: float | None = ..., + hspace: float | None = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + **kwargs + ) -> np.ndarray: ... + @overload + def subfigures( + self, + nrows: int = ..., + ncols: int = ..., + squeeze: Literal[True] = ..., + wspace: float | None = ..., + hspace: float | None = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + **kwargs + ) -> np.ndarray | SubFigure: ... + def add_subfigure(self, subplotspec: SubplotSpec, **kwargs) -> SubFigure: ... + def sca(self, a: Axes) -> Axes: ... + def gca(self) -> Axes: ... + def _gci(self) -> ScalarMappable | None: ... + def _process_projection_requirements( + self, *, axes_class=None, polar=False, projection=None, **kwargs + ) -> tuple[type[Axes], dict[str, Any]]: ... + def get_default_bbox_extra_artists(self) -> list[Artist]: ... + def get_tightbbox( + self, + renderer: RendererBase | None = ..., + *, + bbox_extra_artists: Iterable[Artist] | None = ..., + ) -> Bbox: ... + @overload + def subplot_mosaic( + self, + mosaic: str, + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: str = ..., + subplot_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + ) -> dict[str, Axes]: ... + @overload + def subplot_mosaic( + self, + mosaic: list[HashableList[_T]], + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: _T = ..., + subplot_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + ) -> dict[_T, Axes]: ... + @overload + def subplot_mosaic( + self, + mosaic: list[HashableList[Hashable]], + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: Any = ..., + subplot_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + ) -> dict[Hashable, Axes]: ... + +class SubFigure(FigureBase): + figure: Figure + subplotpars: SubplotParams + dpi_scale_trans: Affine2D + canvas: FigureCanvasBase + transFigure: Transform + bbox_relative: Bbox + figbbox: BboxBase + bbox: BboxBase + transSubfigure: Transform + patch: Rectangle + def __init__( + self, + parent: Figure | SubFigure, + subplotspec: SubplotSpec, + *, + facecolor: ColorType | None = ..., + edgecolor: ColorType | None = ..., + linewidth: float = ..., + frameon: bool | None = ..., + **kwargs + ) -> None: ... + @property + def dpi(self) -> float: ... + @dpi.setter + def dpi(self, value: float) -> None: ... + def get_dpi(self) -> float: ... + def set_dpi(self, val) -> None: ... + def get_constrained_layout(self) -> bool: ... + def get_constrained_layout_pads( + self, relative: bool = ... + ) -> tuple[float, float, float, float]: ... + def get_layout_engine(self) -> LayoutEngine: ... + @property # type: ignore[misc] + def axes(self) -> list[Axes]: ... # type: ignore[override] + def get_axes(self) -> list[Axes]: ... + +class Figure(FigureBase): + figure: Figure + bbox_inches: Bbox + dpi_scale_trans: Affine2D + bbox: BboxBase + figbbox: BboxBase + transFigure: Transform + transSubfigure: Transform + patch: Rectangle + subplotpars: SubplotParams + def __init__( + self, + figsize: tuple[float, float] | None = ..., + dpi: float | None = ..., + *, + facecolor: ColorType | None = ..., + edgecolor: ColorType | None = ..., + linewidth: float = ..., + frameon: bool | None = ..., + subplotpars: SubplotParams | None = ..., + tight_layout: bool | dict[str, Any] | None = ..., + constrained_layout: bool | dict[str, Any] | None = ..., + layout: Literal["constrained", "compressed", "tight"] + | LayoutEngine + | None = ..., + **kwargs + ) -> None: ... + def pick(self, mouseevent: MouseEvent) -> None: ... + def set_layout_engine( + self, + layout: Literal["constrained", "compressed", "tight", "none"] + | LayoutEngine + | None = ..., + **kwargs + ) -> None: ... + def get_layout_engine(self) -> LayoutEngine | None: ... + def _repr_html_(self) -> str | None: ... + def show(self, warn: bool = ...) -> None: ... + @property # type: ignore[misc] + def axes(self) -> list[Axes]: ... # type: ignore[override] + def get_axes(self) -> list[Axes]: ... + @property + def dpi(self) -> float: ... + @dpi.setter + def dpi(self, dpi: float) -> None: ... + def get_tight_layout(self) -> bool: ... + def get_constrained_layout_pads( + self, relative: bool = ... + ) -> tuple[float, float, float, float]: ... + def get_constrained_layout(self) -> bool: ... + canvas: FigureCanvasBase + def set_canvas(self, canvas: FigureCanvasBase) -> None: ... + def figimage( + self, + X: ArrayLike, + xo: int = ..., + yo: int = ..., + alpha: float | None = ..., + norm: str | Normalize | None = ..., + cmap: str | Colormap | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + origin: Literal["upper", "lower"] | None = ..., + resize: bool = ..., + **kwargs + ) -> FigureImage: ... + def set_size_inches( + self, w: float | tuple[float, float], h: float | None = ..., forward: bool = ... + ) -> None: ... + def get_size_inches(self) -> np.ndarray: ... + def get_figwidth(self) -> float: ... + def get_figheight(self) -> float: ... + def get_dpi(self) -> float: ... + def set_dpi(self, val: float) -> None: ... + def set_figwidth(self, val: float, forward: bool = ...) -> None: ... + def set_figheight(self, val: float, forward: bool = ...) -> None: ... + def clear(self, keep_observers: bool = ...) -> None: ... + def draw_without_rendering(self) -> None: ... + def draw_artist(self, a: Artist) -> None: ... + def add_axobserver(self, func: Callable[[Figure], Any]) -> None: ... + def savefig( + self, + fname: str | os.PathLike | IO, + *, + transparent: bool | None = ..., + **kwargs + ) -> None: ... + def ginput( + self, + n: int = ..., + timeout: float = ..., + show_clicks: bool = ..., + mouse_add: MouseButton = ..., + mouse_pop: MouseButton = ..., + mouse_stop: MouseButton = ..., + ) -> list[tuple[int, int]]: ... + def waitforbuttonpress(self, timeout: float = ...) -> None | bool: ... + def tight_layout( + self, + *, + pad: float = ..., + h_pad: float | None = ..., + w_pad: float | None = ..., + rect: tuple[float, float, float, float] | None = ... + ) -> None: ... + +def figaspect(arg: float | ArrayLike) -> tuple[float, float]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.py new file mode 100644 index 00000000..a91ca4ba --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.py @@ -0,0 +1,1584 @@ +""" +A module for finding, managing, and using fonts across platforms. + +This module provides a single `FontManager` instance, ``fontManager``, that can +be shared across backends and platforms. The `findfont` +function returns the best TrueType (TTF) font file in the local or +system font path that matches the specified `FontProperties` +instance. The `FontManager` also handles Adobe Font Metrics +(AFM) font files for use by the PostScript backend. +The `FontManager.addfont` function adds a custom font from a file without +installing it into your operating system. + +The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1) +font specification `_. +Future versions may implement the Level 2 or 2.1 specifications. +""" + +# KNOWN ISSUES +# +# - documentation +# - font variant is untested +# - font stretch is incomplete +# - font size is incomplete +# - default font algorithm needs improvement and testing +# - setWeights function needs improvement +# - 'light' is an invalid weight value, remove it. + +from base64 import b64encode +from collections import namedtuple +import copy +import dataclasses +from functools import lru_cache +from io import BytesIO +import json +import logging +from numbers import Number +import os +from pathlib import Path +import re +import subprocess +import sys +import threading +from typing import Union + +import matplotlib as mpl +from matplotlib import _api, _afm, cbook, ft2font +from matplotlib._fontconfig_pattern import ( + parse_fontconfig_pattern, generate_fontconfig_pattern) +from matplotlib.rcsetup import _validators + +_log = logging.getLogger(__name__) + +font_scalings = { + 'xx-small': 0.579, + 'x-small': 0.694, + 'small': 0.833, + 'medium': 1.0, + 'large': 1.200, + 'x-large': 1.440, + 'xx-large': 1.728, + 'larger': 1.2, + 'smaller': 0.833, + None: 1.0, +} +stretch_dict = { + 'ultra-condensed': 100, + 'extra-condensed': 200, + 'condensed': 300, + 'semi-condensed': 400, + 'normal': 500, + 'semi-expanded': 600, + 'semi-extended': 600, + 'expanded': 700, + 'extended': 700, + 'extra-expanded': 800, + 'extra-extended': 800, + 'ultra-expanded': 900, + 'ultra-extended': 900, +} +weight_dict = { + 'ultralight': 100, + 'light': 200, + 'normal': 400, + 'regular': 400, + 'book': 400, + 'medium': 500, + 'roman': 500, + 'semibold': 600, + 'demibold': 600, + 'demi': 600, + 'bold': 700, + 'heavy': 800, + 'extra bold': 800, + 'black': 900, +} +_weight_regexes = [ + # From fontconfig's FcFreeTypeQueryFaceInternal; not the same as + # weight_dict! + ("thin", 100), + ("extralight", 200), + ("ultralight", 200), + ("demilight", 350), + ("semilight", 350), + ("light", 300), # Needs to come *after* demi/semilight! + ("book", 380), + ("regular", 400), + ("normal", 400), + ("medium", 500), + ("demibold", 600), + ("demi", 600), + ("semibold", 600), + ("extrabold", 800), + ("superbold", 800), + ("ultrabold", 800), + ("bold", 700), # Needs to come *after* extra/super/ultrabold! + ("ultrablack", 1000), + ("superblack", 1000), + ("extrablack", 1000), + (r"\bultra", 1000), + ("black", 900), # Needs to come *after* ultra/super/extrablack! + ("heavy", 900), +] +font_family_aliases = { + 'serif', + 'sans-serif', + 'sans serif', + 'cursive', + 'fantasy', + 'monospace', + 'sans', +} + +_ExceptionProxy = namedtuple('_ExceptionProxy', ['klass', 'message']) + +# OS Font paths +try: + _HOME = Path.home() +except Exception: # Exceptions thrown by home() are not specified... + _HOME = Path(os.devnull) # Just an arbitrary path with no children. +MSFolders = \ + r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' +MSFontDirectories = [ + r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', + r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts'] +MSUserFontDirectories = [ + str(_HOME / 'AppData/Local/Microsoft/Windows/Fonts'), + str(_HOME / 'AppData/Roaming/Microsoft/Windows/Fonts'), +] +X11FontDirectories = [ + # an old standard installation point + "/usr/X11R6/lib/X11/fonts/TTF/", + "/usr/X11/lib/X11/fonts", + # here is the new standard location for fonts + "/usr/share/fonts/", + # documented as a good place to install new fonts + "/usr/local/share/fonts/", + # common application, not really useful + "/usr/lib/openoffice/share/fonts/truetype/", + # user fonts + str((Path(os.environ.get('XDG_DATA_HOME') or _HOME / ".local/share")) + / "fonts"), + str(_HOME / ".fonts"), +] +OSXFontDirectories = [ + "/Library/Fonts/", + "/Network/Library/Fonts/", + "/System/Library/Fonts/", + # fonts installed via MacPorts + "/opt/local/share/fonts", + # user fonts + str(_HOME / "Library/Fonts"), +] + + +def get_fontext_synonyms(fontext): + """ + Return a list of file extensions that are synonyms for + the given file extension *fileext*. + """ + return { + 'afm': ['afm'], + 'otf': ['otf', 'ttc', 'ttf'], + 'ttc': ['otf', 'ttc', 'ttf'], + 'ttf': ['otf', 'ttc', 'ttf'], + }[fontext] + + +def list_fonts(directory, extensions): + """ + Return a list of all fonts matching any of the extensions, found + recursively under the directory. + """ + extensions = ["." + ext for ext in extensions] + return [os.path.join(dirpath, filename) + # os.walk ignores access errors, unlike Path.glob. + for dirpath, _, filenames in os.walk(directory) + for filename in filenames + if Path(filename).suffix.lower() in extensions] + + +def win32FontDirectory(): + r""" + Return the user-specified font directory for Win32. This is + looked up from the registry key :: + + \\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Fonts + + If the key is not found, ``%WINDIR%\Fonts`` will be returned. + """ + import winreg + try: + with winreg.OpenKey(winreg.HKEY_CURRENT_USER, MSFolders) as user: + return winreg.QueryValueEx(user, 'Fonts')[0] + except OSError: + return os.path.join(os.environ['WINDIR'], 'Fonts') + + +def _get_win32_installed_fonts(): + """List the font paths known to the Windows registry.""" + import winreg + items = set() + # Search and resolve fonts listed in the registry. + for domain, base_dirs in [ + (winreg.HKEY_LOCAL_MACHINE, [win32FontDirectory()]), # System. + (winreg.HKEY_CURRENT_USER, MSUserFontDirectories), # User. + ]: + for base_dir in base_dirs: + for reg_path in MSFontDirectories: + try: + with winreg.OpenKey(domain, reg_path) as local: + for j in range(winreg.QueryInfoKey(local)[1]): + # value may contain the filename of the font or its + # absolute path. + key, value, tp = winreg.EnumValue(local, j) + if not isinstance(value, str): + continue + try: + # If value contains already an absolute path, + # then it is not changed further. + path = Path(base_dir, value).resolve() + except RuntimeError: + # Don't fail with invalid entries. + continue + items.add(path) + except (OSError, MemoryError): + continue + return items + + +@lru_cache +def _get_fontconfig_fonts(): + """Cache and list the font paths known to ``fc-list``.""" + try: + if b'--format' not in subprocess.check_output(['fc-list', '--help']): + _log.warning( # fontconfig 2.7 implemented --format. + 'Matplotlib needs fontconfig>=2.7 to query system fonts.') + return [] + out = subprocess.check_output(['fc-list', '--format=%{file}\\n']) + except (OSError, subprocess.CalledProcessError): + return [] + return [Path(os.fsdecode(fname)) for fname in out.split(b'\n')] + + +def findSystemFonts(fontpaths=None, fontext='ttf'): + """ + Search for fonts in the specified font paths. If no paths are + given, will use a standard set of system paths, as well as the + list of fonts tracked by fontconfig if fontconfig is installed and + available. A list of TrueType fonts are returned by default with + AFM fonts as an option. + """ + fontfiles = set() + fontexts = get_fontext_synonyms(fontext) + + if fontpaths is None: + if sys.platform == 'win32': + installed_fonts = _get_win32_installed_fonts() + fontpaths = [] + else: + installed_fonts = _get_fontconfig_fonts() + if sys.platform == 'darwin': + fontpaths = [*X11FontDirectories, *OSXFontDirectories] + else: + fontpaths = X11FontDirectories + fontfiles.update(str(path) for path in installed_fonts + if path.suffix.lower()[1:] in fontexts) + + elif isinstance(fontpaths, str): + fontpaths = [fontpaths] + + for path in fontpaths: + fontfiles.update(map(os.path.abspath, list_fonts(path, fontexts))) + + return [fname for fname in fontfiles if os.path.exists(fname)] + + +def _fontentry_helper_repr_png(fontent): + from matplotlib.figure import Figure # Circular import. + fig = Figure() + font_path = Path(fontent.fname) if fontent.fname != '' else None + fig.text(0, 0, fontent.name, font=font_path) + with BytesIO() as buf: + fig.savefig(buf, bbox_inches='tight', transparent=True) + return buf.getvalue() + + +def _fontentry_helper_repr_html(fontent): + png_stream = _fontentry_helper_repr_png(fontent) + png_b64 = b64encode(png_stream).decode() + return f"" + + +FontEntry = dataclasses.make_dataclass( + 'FontEntry', [ + ('fname', str, dataclasses.field(default='')), + ('name', str, dataclasses.field(default='')), + ('style', str, dataclasses.field(default='normal')), + ('variant', str, dataclasses.field(default='normal')), + ('weight', Union[str, int], dataclasses.field(default='normal')), + ('stretch', str, dataclasses.field(default='normal')), + ('size', str, dataclasses.field(default='medium')), + ], + namespace={ + '__doc__': """ + A class for storing Font properties. + + It is used when populating the font lookup dictionary. + """, + '_repr_html_': lambda self: _fontentry_helper_repr_html(self), + '_repr_png_': lambda self: _fontentry_helper_repr_png(self), + } +) + + +def ttfFontProperty(font): + """ + Extract information from a TrueType font file. + + Parameters + ---------- + font : `.FT2Font` + The TrueType font file from which information will be extracted. + + Returns + ------- + `FontEntry` + The extracted font properties. + + """ + name = font.family_name + + # Styles are: italic, oblique, and normal (default) + + sfnt = font.get_sfnt() + mac_key = (1, # platform: macintosh + 0, # id: roman + 0) # langid: english + ms_key = (3, # platform: microsoft + 1, # id: unicode_cs + 0x0409) # langid: english_united_states + + # These tables are actually mac_roman-encoded, but mac_roman support may be + # missing in some alternative Python implementations and we are only going + # to look for ASCII substrings, where any ASCII-compatible encoding works + # - or big-endian UTF-16, since important Microsoft fonts use that. + sfnt2 = (sfnt.get((*mac_key, 2), b'').decode('latin-1').lower() or + sfnt.get((*ms_key, 2), b'').decode('utf_16_be').lower()) + sfnt4 = (sfnt.get((*mac_key, 4), b'').decode('latin-1').lower() or + sfnt.get((*ms_key, 4), b'').decode('utf_16_be').lower()) + + if sfnt4.find('oblique') >= 0: + style = 'oblique' + elif sfnt4.find('italic') >= 0: + style = 'italic' + elif sfnt2.find('regular') >= 0: + style = 'normal' + elif font.style_flags & ft2font.ITALIC: + style = 'italic' + else: + style = 'normal' + + # Variants are: small-caps and normal (default) + + # !!!! Untested + if name.lower() in ['capitals', 'small-caps']: + variant = 'small-caps' + else: + variant = 'normal' + + # The weight-guessing algorithm is directly translated from fontconfig + # 2.13.1's FcFreeTypeQueryFaceInternal (fcfreetype.c). + wws_subfamily = 22 + typographic_subfamily = 16 + font_subfamily = 2 + styles = [ + sfnt.get((*mac_key, wws_subfamily), b'').decode('latin-1'), + sfnt.get((*mac_key, typographic_subfamily), b'').decode('latin-1'), + sfnt.get((*mac_key, font_subfamily), b'').decode('latin-1'), + sfnt.get((*ms_key, wws_subfamily), b'').decode('utf-16-be'), + sfnt.get((*ms_key, typographic_subfamily), b'').decode('utf-16-be'), + sfnt.get((*ms_key, font_subfamily), b'').decode('utf-16-be'), + ] + styles = [*filter(None, styles)] or [font.style_name] + + def get_weight(): # From fontconfig's FcFreeTypeQueryFaceInternal. + # OS/2 table weight. + os2 = font.get_sfnt_table("OS/2") + if os2 and os2["version"] != 0xffff: + return os2["usWeightClass"] + # PostScript font info weight. + try: + ps_font_info_weight = ( + font.get_ps_font_info()["weight"].replace(" ", "") or "") + except ValueError: + pass + else: + for regex, weight in _weight_regexes: + if re.fullmatch(regex, ps_font_info_weight, re.I): + return weight + # Style name weight. + for style in styles: + style = style.replace(" ", "") + for regex, weight in _weight_regexes: + if re.search(regex, style, re.I): + return weight + if font.style_flags & ft2font.BOLD: + return 700 # "bold" + return 500 # "medium", not "regular"! + + weight = int(get_weight()) + + # Stretch can be absolute and relative + # Absolute stretches are: ultra-condensed, extra-condensed, condensed, + # semi-condensed, normal, semi-expanded, expanded, extra-expanded, + # and ultra-expanded. + # Relative stretches are: wider, narrower + # Child value is: inherit + + if any(word in sfnt4 for word in ['narrow', 'condensed', 'cond']): + stretch = 'condensed' + elif 'demi cond' in sfnt4: + stretch = 'semi-condensed' + elif any(word in sfnt4 for word in ['wide', 'expanded', 'extended']): + stretch = 'expanded' + else: + stretch = 'normal' + + # Sizes can be absolute and relative. + # Absolute sizes are: xx-small, x-small, small, medium, large, x-large, + # and xx-large. + # Relative sizes are: larger, smaller + # Length value is an absolute font size, e.g., 12pt + # Percentage values are in 'em's. Most robust specification. + + if not font.scalable: + raise NotImplementedError("Non-scalable fonts are not supported") + size = 'scalable' + + return FontEntry(font.fname, name, style, variant, weight, stretch, size) + + +def afmFontProperty(fontpath, font): + """ + Extract information from an AFM font file. + + Parameters + ---------- + fontpath : str + The filename corresponding to *font*. + font : AFM + The AFM font file from which information will be extracted. + + Returns + ------- + `FontEntry` + The extracted font properties. + """ + + name = font.get_familyname() + fontname = font.get_fontname().lower() + + # Styles are: italic, oblique, and normal (default) + + if font.get_angle() != 0 or 'italic' in name.lower(): + style = 'italic' + elif 'oblique' in name.lower(): + style = 'oblique' + else: + style = 'normal' + + # Variants are: small-caps and normal (default) + + # !!!! Untested + if name.lower() in ['capitals', 'small-caps']: + variant = 'small-caps' + else: + variant = 'normal' + + weight = font.get_weight().lower() + if weight not in weight_dict: + weight = 'normal' + + # Stretch can be absolute and relative + # Absolute stretches are: ultra-condensed, extra-condensed, condensed, + # semi-condensed, normal, semi-expanded, expanded, extra-expanded, + # and ultra-expanded. + # Relative stretches are: wider, narrower + # Child value is: inherit + if 'demi cond' in fontname: + stretch = 'semi-condensed' + elif any(word in fontname for word in ['narrow', 'cond']): + stretch = 'condensed' + elif any(word in fontname for word in ['wide', 'expanded', 'extended']): + stretch = 'expanded' + else: + stretch = 'normal' + + # Sizes can be absolute and relative. + # Absolute sizes are: xx-small, x-small, small, medium, large, x-large, + # and xx-large. + # Relative sizes are: larger, smaller + # Length value is an absolute font size, e.g., 12pt + # Percentage values are in 'em's. Most robust specification. + + # All AFM fonts are apparently scalable. + + size = 'scalable' + + return FontEntry(fontpath, name, style, variant, weight, stretch, size) + + +class FontProperties: + """ + A class for storing and manipulating font properties. + + The font properties are the six properties described in the + `W3C Cascading Style Sheet, Level 1 + `_ font + specification and *math_fontfamily* for math fonts: + + - family: A list of font names in decreasing order of priority. + The items may include a generic font family name, either 'sans-serif', + 'serif', 'cursive', 'fantasy', or 'monospace'. In that case, the actual + font to be used will be looked up from the associated rcParam during the + search process in `.findfont`. Default: :rc:`font.family` + + - style: Either 'normal', 'italic' or 'oblique'. + Default: :rc:`font.style` + + - variant: Either 'normal' or 'small-caps'. + Default: :rc:`font.variant` + + - stretch: A numeric value in the range 0-1000 or one of + 'ultra-condensed', 'extra-condensed', 'condensed', + 'semi-condensed', 'normal', 'semi-expanded', 'expanded', + 'extra-expanded' or 'ultra-expanded'. Default: :rc:`font.stretch` + + - weight: A numeric value in the range 0-1000 or one of + 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', + 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', + 'extra bold', 'black'. Default: :rc:`font.weight` + + - size: Either a relative value of 'xx-small', 'x-small', + 'small', 'medium', 'large', 'x-large', 'xx-large' or an + absolute font size, e.g., 10. Default: :rc:`font.size` + + - math_fontfamily: The family of fonts used to render math text. + Supported values are: 'dejavusans', 'dejavuserif', 'cm', + 'stix', 'stixsans' and 'custom'. Default: :rc:`mathtext.fontset` + + Alternatively, a font may be specified using the absolute path to a font + file, by using the *fname* kwarg. However, in this case, it is typically + simpler to just pass the path (as a `pathlib.Path`, not a `str`) to the + *font* kwarg of the `.Text` object. + + The preferred usage of font sizes is to use the relative values, + e.g., 'large', instead of absolute font sizes, e.g., 12. This + approach allows all text sizes to be made larger or smaller based + on the font manager's default font size. + + This class will also accept a fontconfig_ pattern_, if it is the only + argument provided. This support does not depend on fontconfig; we are + merely borrowing its pattern syntax for use here. + + .. _fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/ + .. _pattern: + https://www.freedesktop.org/software/fontconfig/fontconfig-user.html + + Note that Matplotlib's internal font manager and fontconfig use a + different algorithm to lookup fonts, so the results of the same pattern + may be different in Matplotlib than in other applications that use + fontconfig. + """ + + def __init__(self, family=None, style=None, variant=None, weight=None, + stretch=None, size=None, + fname=None, # if set, it's a hardcoded filename to use + math_fontfamily=None): + self.set_family(family) + self.set_style(style) + self.set_variant(variant) + self.set_weight(weight) + self.set_stretch(stretch) + self.set_file(fname) + self.set_size(size) + self.set_math_fontfamily(math_fontfamily) + # Treat family as a fontconfig pattern if it is the only parameter + # provided. Even in that case, call the other setters first to set + # attributes not specified by the pattern to the rcParams defaults. + if (isinstance(family, str) + and style is None and variant is None and weight is None + and stretch is None and size is None and fname is None): + self.set_fontconfig_pattern(family) + + @classmethod + def _from_any(cls, arg): + """ + Generic constructor which can build a `.FontProperties` from any of the + following: + + - a `.FontProperties`: it is passed through as is; + - `None`: a `.FontProperties` using rc values is used; + - an `os.PathLike`: it is used as path to the font file; + - a `str`: it is parsed as a fontconfig pattern; + - a `dict`: it is passed as ``**kwargs`` to `.FontProperties`. + """ + if arg is None: + return cls() + elif isinstance(arg, cls): + return arg + elif isinstance(arg, os.PathLike): + return cls(fname=arg) + elif isinstance(arg, str): + return cls(arg) + else: + return cls(**arg) + + def __hash__(self): + l = (tuple(self.get_family()), + self.get_slant(), + self.get_variant(), + self.get_weight(), + self.get_stretch(), + self.get_size(), + self.get_file(), + self.get_math_fontfamily()) + return hash(l) + + def __eq__(self, other): + return hash(self) == hash(other) + + def __str__(self): + return self.get_fontconfig_pattern() + + def get_family(self): + """ + Return a list of individual font family names or generic family names. + + The font families or generic font families (which will be resolved + from their respective rcParams when searching for a matching font) in + the order of preference. + """ + return self._family + + def get_name(self): + """ + Return the name of the font that best matches the font properties. + """ + return get_font(findfont(self)).family_name + + def get_style(self): + """ + Return the font style. Values are: 'normal', 'italic' or 'oblique'. + """ + return self._slant + + def get_variant(self): + """ + Return the font variant. Values are: 'normal' or 'small-caps'. + """ + return self._variant + + def get_weight(self): + """ + Set the font weight. Options are: A numeric value in the + range 0-1000 or one of 'light', 'normal', 'regular', 'book', + 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', + 'heavy', 'extra bold', 'black' + """ + return self._weight + + def get_stretch(self): + """ + Return the font stretch or width. Options are: 'ultra-condensed', + 'extra-condensed', 'condensed', 'semi-condensed', 'normal', + 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded'. + """ + return self._stretch + + def get_size(self): + """ + Return the font size. + """ + return self._size + + def get_file(self): + """ + Return the filename of the associated font. + """ + return self._file + + def get_fontconfig_pattern(self): + """ + Get a fontconfig_ pattern_ suitable for looking up the font as + specified with fontconfig's ``fc-match`` utility. + + This support does not depend on fontconfig; we are merely borrowing its + pattern syntax for use here. + """ + return generate_fontconfig_pattern(self) + + def set_family(self, family): + """ + Change the font family. Can be either an alias (generic name + is CSS parlance), such as: 'serif', 'sans-serif', 'cursive', + 'fantasy', or 'monospace', a real font name or a list of real + font names. Real font names are not supported when + :rc:`text.usetex` is `True`. Default: :rc:`font.family` + """ + if family is None: + family = mpl.rcParams['font.family'] + if isinstance(family, str): + family = [family] + self._family = family + + def set_style(self, style): + """ + Set the font style. + + Parameters + ---------- + style : {'normal', 'italic', 'oblique'}, default: :rc:`font.style` + """ + if style is None: + style = mpl.rcParams['font.style'] + _api.check_in_list(['normal', 'italic', 'oblique'], style=style) + self._slant = style + + def set_variant(self, variant): + """ + Set the font variant. + + Parameters + ---------- + variant : {'normal', 'small-caps'}, default: :rc:`font.variant` + """ + if variant is None: + variant = mpl.rcParams['font.variant'] + _api.check_in_list(['normal', 'small-caps'], variant=variant) + self._variant = variant + + def set_weight(self, weight): + """ + Set the font weight. + + Parameters + ---------- + weight : int or {'ultralight', 'light', 'normal', 'regular', 'book', \ +'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', \ +'extra bold', 'black'}, default: :rc:`font.weight` + If int, must be in the range 0-1000. + """ + if weight is None: + weight = mpl.rcParams['font.weight'] + if weight in weight_dict: + self._weight = weight + return + try: + weight = int(weight) + except ValueError: + pass + else: + if 0 <= weight <= 1000: + self._weight = weight + return + raise ValueError(f"{weight=} is invalid") + + def set_stretch(self, stretch): + """ + Set the font stretch or width. + + Parameters + ---------- + stretch : int or {'ultra-condensed', 'extra-condensed', 'condensed', \ +'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', \ +'ultra-expanded'}, default: :rc:`font.stretch` + If int, must be in the range 0-1000. + """ + if stretch is None: + stretch = mpl.rcParams['font.stretch'] + if stretch in stretch_dict: + self._stretch = stretch + return + try: + stretch = int(stretch) + except ValueError: + pass + else: + if 0 <= stretch <= 1000: + self._stretch = stretch + return + raise ValueError(f"{stretch=} is invalid") + + def set_size(self, size): + """ + Set the font size. + + Parameters + ---------- + size : float or {'xx-small', 'x-small', 'small', 'medium', \ +'large', 'x-large', 'xx-large'}, default: :rc:`font.size` + If a float, the font size in points. The string values denote + sizes relative to the default font size. + """ + if size is None: + size = mpl.rcParams['font.size'] + try: + size = float(size) + except ValueError: + try: + scale = font_scalings[size] + except KeyError as err: + raise ValueError( + "Size is invalid. Valid font size are " + + ", ".join(map(str, font_scalings))) from err + else: + size = scale * FontManager.get_default_size() + if size < 1.0: + _log.info('Fontsize %1.2f < 1.0 pt not allowed by FreeType. ' + 'Setting fontsize = 1 pt', size) + size = 1.0 + self._size = size + + def set_file(self, file): + """ + Set the filename of the fontfile to use. In this case, all + other properties will be ignored. + """ + self._file = os.fspath(file) if file is not None else None + + def set_fontconfig_pattern(self, pattern): + """ + Set the properties by parsing a fontconfig_ *pattern*. + + This support does not depend on fontconfig; we are merely borrowing its + pattern syntax for use here. + """ + for key, val in parse_fontconfig_pattern(pattern).items(): + if type(val) is list: + getattr(self, "set_" + key)(val[0]) + else: + getattr(self, "set_" + key)(val) + + def get_math_fontfamily(self): + """ + Return the name of the font family used for math text. + + The default font is :rc:`mathtext.fontset`. + """ + return self._math_fontfamily + + def set_math_fontfamily(self, fontfamily): + """ + Set the font family for text in math mode. + + If not set explicitly, :rc:`mathtext.fontset` will be used. + + Parameters + ---------- + fontfamily : str + The name of the font family. + + Available font families are defined in the + :ref:`default matplotlibrc file `. + + See Also + -------- + .text.Text.get_math_fontfamily + """ + if fontfamily is None: + fontfamily = mpl.rcParams['mathtext.fontset'] + else: + valid_fonts = _validators['mathtext.fontset'].valid.values() + # _check_in_list() Validates the parameter math_fontfamily as + # if it were passed to rcParams['mathtext.fontset'] + _api.check_in_list(valid_fonts, math_fontfamily=fontfamily) + self._math_fontfamily = fontfamily + + def copy(self): + """Return a copy of self.""" + return copy.copy(self) + + # Aliases + set_name = set_family + get_slant = get_style + set_slant = set_style + get_size_in_points = get_size + + +class _JSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, FontManager): + return dict(o.__dict__, __class__='FontManager') + elif isinstance(o, FontEntry): + d = dict(o.__dict__, __class__='FontEntry') + try: + # Cache paths of fonts shipped with Matplotlib relative to the + # Matplotlib data path, which helps in the presence of venvs. + d["fname"] = str( + Path(d["fname"]).relative_to(mpl.get_data_path())) + except ValueError: + pass + return d + else: + return super().default(o) + + +def _json_decode(o): + cls = o.pop('__class__', None) + if cls is None: + return o + elif cls == 'FontManager': + r = FontManager.__new__(FontManager) + r.__dict__.update(o) + return r + elif cls == 'FontEntry': + r = FontEntry.__new__(FontEntry) + r.__dict__.update(o) + if not os.path.isabs(r.fname): + r.fname = os.path.join(mpl.get_data_path(), r.fname) + return r + else: + raise ValueError("Don't know how to deserialize __class__=%s" % cls) + + +def json_dump(data, filename): + """ + Dump `FontManager` *data* as JSON to the file named *filename*. + + See Also + -------- + json_load + + Notes + ----- + File paths that are children of the Matplotlib data path (typically, fonts + shipped with Matplotlib) are stored relative to that data path (to remain + valid across virtualenvs). + + This function temporarily locks the output file to prevent multiple + processes from overwriting one another's output. + """ + with cbook._lock_path(filename), open(filename, 'w') as fh: + try: + json.dump(data, fh, cls=_JSONEncoder, indent=2) + except OSError as e: + _log.warning('Could not save font_manager cache %s', e) + + +def json_load(filename): + """ + Load a `FontManager` from the JSON file named *filename*. + + See Also + -------- + json_dump + """ + with open(filename) as fh: + return json.load(fh, object_hook=_json_decode) + + +class FontManager: + """ + On import, the `FontManager` singleton instance creates a list of ttf and + afm fonts and caches their `FontProperties`. The `FontManager.findfont` + method does a nearest neighbor search to find the font that most closely + matches the specification. If no good enough match is found, the default + font is returned. + + Fonts added with the `FontManager.addfont` method will not persist in the + cache; therefore, `addfont` will need to be called every time Matplotlib is + imported. This method should only be used if and when a font cannot be + installed on your operating system by other means. + + Notes + ----- + The `FontManager.addfont` method must be called on the global `FontManager` + instance. + + Example usage:: + + import matplotlib.pyplot as plt + from matplotlib import font_manager + + font_dirs = ["/resources/fonts"] # The path to the custom font file. + font_files = font_manager.findSystemFonts(fontpaths=font_dirs) + + for font_file in font_files: + font_manager.fontManager.addfont(font_file) + """ + # Increment this version number whenever the font cache data + # format or behavior has changed and requires an existing font + # cache files to be rebuilt. + __version__ = 330 + + def __init__(self, size=None, weight='normal'): + self._version = self.__version__ + + self.__default_weight = weight + self.default_size = size + + # Create list of font paths. + paths = [cbook._get_data_path('fonts', subdir) + for subdir in ['ttf', 'afm', 'pdfcorefonts']] + _log.debug('font search path %s', paths) + + self.defaultFamily = { + 'ttf': 'DejaVu Sans', + 'afm': 'Helvetica'} + + self.afmlist = [] + self.ttflist = [] + + # Delay the warning by 5s. + timer = threading.Timer(5, lambda: _log.warning( + 'Matplotlib is building the font cache; this may take a moment.')) + timer.start() + try: + for fontext in ["afm", "ttf"]: + for path in [*findSystemFonts(paths, fontext=fontext), + *findSystemFonts(fontext=fontext)]: + try: + self.addfont(path) + except OSError as exc: + _log.info("Failed to open font file %s: %s", path, exc) + except Exception as exc: + _log.info("Failed to extract font properties from %s: " + "%s", path, exc) + finally: + timer.cancel() + + def addfont(self, path): + """ + Cache the properties of the font at *path* to make it available to the + `FontManager`. The type of font is inferred from the path suffix. + + Parameters + ---------- + path : str or path-like + + Notes + ----- + This method is useful for adding a custom font without installing it in + your operating system. See the `FontManager` singleton instance for + usage and caveats about this function. + """ + # Convert to string in case of a path as + # afmFontProperty and FT2Font expect this + path = os.fsdecode(path) + if Path(path).suffix.lower() == ".afm": + with open(path, "rb") as fh: + font = _afm.AFM(fh) + prop = afmFontProperty(path, font) + self.afmlist.append(prop) + else: + font = ft2font.FT2Font(path) + prop = ttfFontProperty(font) + self.ttflist.append(prop) + self._findfont_cached.cache_clear() + + @property + def defaultFont(self): + # Lazily evaluated (findfont then caches the result) to avoid including + # the venv path in the json serialization. + return {ext: self.findfont(family, fontext=ext) + for ext, family in self.defaultFamily.items()} + + def get_default_weight(self): + """ + Return the default font weight. + """ + return self.__default_weight + + @staticmethod + def get_default_size(): + """ + Return the default font size. + """ + return mpl.rcParams['font.size'] + + def set_default_weight(self, weight): + """ + Set the default font weight. The initial value is 'normal'. + """ + self.__default_weight = weight + + @staticmethod + def _expand_aliases(family): + if family in ('sans', 'sans serif'): + family = 'sans-serif' + return mpl.rcParams['font.' + family] + + # Each of the scoring functions below should return a value between + # 0.0 (perfect match) and 1.0 (terrible match) + def score_family(self, families, family2): + """ + Return a match score between the list of font families in + *families* and the font family name *family2*. + + An exact match at the head of the list returns 0.0. + + A match further down the list will return between 0 and 1. + + No match will return 1.0. + """ + if not isinstance(families, (list, tuple)): + families = [families] + elif len(families) == 0: + return 1.0 + family2 = family2.lower() + step = 1 / len(families) + for i, family1 in enumerate(families): + family1 = family1.lower() + if family1 in font_family_aliases: + options = [*map(str.lower, self._expand_aliases(family1))] + if family2 in options: + idx = options.index(family2) + return (i + (idx / len(options))) * step + elif family1 == family2: + # The score should be weighted by where in the + # list the font was found. + return i * step + return 1.0 + + def score_style(self, style1, style2): + """ + Return a match score between *style1* and *style2*. + + An exact match returns 0.0. + + A match between 'italic' and 'oblique' returns 0.1. + + No match returns 1.0. + """ + if style1 == style2: + return 0.0 + elif (style1 in ('italic', 'oblique') + and style2 in ('italic', 'oblique')): + return 0.1 + return 1.0 + + def score_variant(self, variant1, variant2): + """ + Return a match score between *variant1* and *variant2*. + + An exact match returns 0.0, otherwise 1.0. + """ + if variant1 == variant2: + return 0.0 + else: + return 1.0 + + def score_stretch(self, stretch1, stretch2): + """ + Return a match score between *stretch1* and *stretch2*. + + The result is the absolute value of the difference between the + CSS numeric values of *stretch1* and *stretch2*, normalized + between 0.0 and 1.0. + """ + try: + stretchval1 = int(stretch1) + except ValueError: + stretchval1 = stretch_dict.get(stretch1, 500) + try: + stretchval2 = int(stretch2) + except ValueError: + stretchval2 = stretch_dict.get(stretch2, 500) + return abs(stretchval1 - stretchval2) / 1000.0 + + def score_weight(self, weight1, weight2): + """ + Return a match score between *weight1* and *weight2*. + + The result is 0.0 if both weight1 and weight 2 are given as strings + and have the same value. + + Otherwise, the result is the absolute value of the difference between + the CSS numeric values of *weight1* and *weight2*, normalized between + 0.05 and 1.0. + """ + # exact match of the weight names, e.g. weight1 == weight2 == "regular" + if cbook._str_equal(weight1, weight2): + return 0.0 + w1 = weight1 if isinstance(weight1, Number) else weight_dict[weight1] + w2 = weight2 if isinstance(weight2, Number) else weight_dict[weight2] + return 0.95 * (abs(w1 - w2) / 1000) + 0.05 + + def score_size(self, size1, size2): + """ + Return a match score between *size1* and *size2*. + + If *size2* (the size specified in the font file) is 'scalable', this + function always returns 0.0, since any font size can be generated. + + Otherwise, the result is the absolute distance between *size1* and + *size2*, normalized so that the usual range of font sizes (6pt - + 72pt) will lie between 0.0 and 1.0. + """ + if size2 == 'scalable': + return 0.0 + # Size value should have already been + try: + sizeval1 = float(size1) + except ValueError: + sizeval1 = self.default_size * font_scalings[size1] + try: + sizeval2 = float(size2) + except ValueError: + return 1.0 + return abs(sizeval1 - sizeval2) / 72 + + def findfont(self, prop, fontext='ttf', directory=None, + fallback_to_default=True, rebuild_if_missing=True): + """ + Find a font that most closely matches the given font properties. + + Parameters + ---------- + prop : str or `~matplotlib.font_manager.FontProperties` + The font properties to search for. This can be either a + `.FontProperties` object or a string defining a + `fontconfig patterns`_. + + fontext : {'ttf', 'afm'}, default: 'ttf' + The extension of the font file: + + - 'ttf': TrueType and OpenType fonts (.ttf, .ttc, .otf) + - 'afm': Adobe Font Metrics (.afm) + + directory : str, optional + If given, only search this directory and its subdirectories. + + fallback_to_default : bool + If True, will fall back to the default font family (usually + "DejaVu Sans" or "Helvetica") if the first lookup hard-fails. + + rebuild_if_missing : bool + Whether to rebuild the font cache and search again if the first + match appears to point to a nonexisting font (i.e., the font cache + contains outdated entries). + + Returns + ------- + str + The filename of the best matching font. + + Notes + ----- + This performs a nearest neighbor search. Each font is given a + similarity score to the target font properties. The first font with + the highest score is returned. If no matches below a certain + threshold are found, the default font (usually DejaVu Sans) is + returned. + + The result is cached, so subsequent lookups don't have to + perform the O(n) nearest neighbor search. + + See the `W3C Cascading Style Sheet, Level 1 + `_ documentation + for a description of the font finding algorithm. + + .. _fontconfig patterns: + https://www.freedesktop.org/software/fontconfig/fontconfig-user.html + """ + # Pass the relevant rcParams (and the font manager, as `self`) to + # _findfont_cached so to prevent using a stale cache entry after an + # rcParam was changed. + rc_params = tuple(tuple(mpl.rcParams[key]) for key in [ + "font.serif", "font.sans-serif", "font.cursive", "font.fantasy", + "font.monospace"]) + ret = self._findfont_cached( + prop, fontext, directory, fallback_to_default, rebuild_if_missing, + rc_params) + if isinstance(ret, _ExceptionProxy): + raise ret.klass(ret.message) + return ret + + def get_font_names(self): + """Return the list of available fonts.""" + return list({font.name for font in self.ttflist}) + + def _find_fonts_by_props(self, prop, fontext='ttf', directory=None, + fallback_to_default=True, rebuild_if_missing=True): + """ + Find font families that most closely match the given properties. + + Parameters + ---------- + prop : str or `~matplotlib.font_manager.FontProperties` + The font properties to search for. This can be either a + `.FontProperties` object or a string defining a + `fontconfig patterns`_. + + fontext : {'ttf', 'afm'}, default: 'ttf' + The extension of the font file: + + - 'ttf': TrueType and OpenType fonts (.ttf, .ttc, .otf) + - 'afm': Adobe Font Metrics (.afm) + + directory : str, optional + If given, only search this directory and its subdirectories. + + fallback_to_default : bool + If True, will fall back to the default font family (usually + "DejaVu Sans" or "Helvetica") if none of the families were found. + + rebuild_if_missing : bool + Whether to rebuild the font cache and search again if the first + match appears to point to a nonexisting font (i.e., the font cache + contains outdated entries). + + Returns + ------- + list[str] + The paths of the fonts found + + Notes + ----- + This is an extension/wrapper of the original findfont API, which only + returns a single font for given font properties. Instead, this API + returns a dict containing multiple fonts and their filepaths + which closely match the given font properties. Since this internally + uses the original API, there's no change to the logic of performing the + nearest neighbor search. See `findfont` for more details. + """ + + prop = FontProperties._from_any(prop) + + fpaths = [] + for family in prop.get_family(): + cprop = prop.copy() + cprop.set_family(family) # set current prop's family + + try: + fpaths.append( + self.findfont( + cprop, fontext, directory, + fallback_to_default=False, # don't fallback to default + rebuild_if_missing=rebuild_if_missing, + ) + ) + except ValueError: + if family in font_family_aliases: + _log.warning( + "findfont: Generic family %r not found because " + "none of the following families were found: %s", + family, ", ".join(self._expand_aliases(family)) + ) + else: + _log.warning("findfont: Font family %r not found.", family) + + # only add default family if no other font was found and + # fallback_to_default is enabled + if not fpaths: + if fallback_to_default: + dfamily = self.defaultFamily[fontext] + cprop = prop.copy() + cprop.set_family(dfamily) + fpaths.append( + self.findfont( + cprop, fontext, directory, + fallback_to_default=True, + rebuild_if_missing=rebuild_if_missing, + ) + ) + else: + raise ValueError("Failed to find any font, and fallback " + "to the default font was disabled") + + return fpaths + + @lru_cache(1024) + def _findfont_cached(self, prop, fontext, directory, fallback_to_default, + rebuild_if_missing, rc_params): + + prop = FontProperties._from_any(prop) + + fname = prop.get_file() + if fname is not None: + return fname + + if fontext == 'afm': + fontlist = self.afmlist + else: + fontlist = self.ttflist + + best_score = 1e64 + best_font = None + + _log.debug('findfont: Matching %s.', prop) + for font in fontlist: + if (directory is not None and + Path(directory) not in Path(font.fname).parents): + continue + # Matching family should have top priority, so multiply it by 10. + score = (self.score_family(prop.get_family(), font.name) * 10 + + self.score_style(prop.get_style(), font.style) + + self.score_variant(prop.get_variant(), font.variant) + + self.score_weight(prop.get_weight(), font.weight) + + self.score_stretch(prop.get_stretch(), font.stretch) + + self.score_size(prop.get_size(), font.size)) + _log.debug('findfont: score(%s) = %s', font, score) + if score < best_score: + best_score = score + best_font = font + if score == 0: + break + + if best_font is None or best_score >= 10.0: + if fallback_to_default: + _log.warning( + 'findfont: Font family %s not found. Falling back to %s.', + prop.get_family(), self.defaultFamily[fontext]) + for family in map(str.lower, prop.get_family()): + if family in font_family_aliases: + _log.warning( + "findfont: Generic family %r not found because " + "none of the following families were found: %s", + family, ", ".join(self._expand_aliases(family))) + default_prop = prop.copy() + default_prop.set_family(self.defaultFamily[fontext]) + return self.findfont(default_prop, fontext, directory, + fallback_to_default=False) + else: + # This return instead of raise is intentional, as we wish to + # cache that it was not found, which will not occur if it was + # actually raised. + return _ExceptionProxy( + ValueError, + f"Failed to find font {prop}, and fallback to the default font was disabled" + ) + else: + _log.debug('findfont: Matching %s to %s (%r) with score of %f.', + prop, best_font.name, best_font.fname, best_score) + result = best_font.fname + + if not os.path.isfile(result): + if rebuild_if_missing: + _log.info( + 'findfont: Found a missing font file. Rebuilding cache.') + new_fm = _load_fontmanager(try_read_cache=False) + # Replace self by the new fontmanager, because users may have + # a reference to this specific instance. + # TODO: _load_fontmanager should really be (used by) a method + # modifying the instance in place. + vars(self).update(vars(new_fm)) + return self.findfont( + prop, fontext, directory, rebuild_if_missing=False) + else: + # This return instead of raise is intentional, as we wish to + # cache that it was not found, which will not occur if it was + # actually raised. + return _ExceptionProxy(ValueError, "No valid font could be found") + + return _cached_realpath(result) + + +@lru_cache +def is_opentype_cff_font(filename): + """ + Return whether the given font is a Postscript Compact Font Format Font + embedded in an OpenType wrapper. Used by the PostScript and PDF backends + that cannot subset these fonts. + """ + if os.path.splitext(filename)[1].lower() == '.otf': + with open(filename, 'rb') as fd: + return fd.read(4) == b"OTTO" + else: + return False + + +@lru_cache(64) +def _get_font(font_filepaths, hinting_factor, *, _kerning_factor, thread_id): + first_fontpath, *rest = font_filepaths + return ft2font.FT2Font( + first_fontpath, hinting_factor, + _fallback_list=[ + ft2font.FT2Font( + fpath, hinting_factor, + _kerning_factor=_kerning_factor + ) + for fpath in rest + ], + _kerning_factor=_kerning_factor + ) + + +# FT2Font objects cannot be used across fork()s because they reference the same +# FT_Library object. While invalidating *all* existing FT2Fonts after a fork +# would be too complicated to be worth it, the main way FT2Fonts get reused is +# via the cache of _get_font, which we can empty upon forking (not on Windows, +# which has no fork() or register_at_fork()). +if hasattr(os, "register_at_fork"): + os.register_at_fork(after_in_child=_get_font.cache_clear) + + +@lru_cache(64) +def _cached_realpath(path): + # Resolving the path avoids embedding the font twice in pdf/ps output if a + # single font is selected using two different relative paths. + return os.path.realpath(path) + + +def get_font(font_filepaths, hinting_factor=None): + """ + Get an `.ft2font.FT2Font` object given a list of file paths. + + Parameters + ---------- + font_filepaths : Iterable[str, Path, bytes], str, Path, bytes + Relative or absolute paths to the font files to be used. + + If a single string, bytes, or `pathlib.Path`, then it will be treated + as a list with that entry only. + + If more than one filepath is passed, then the returned FT2Font object + will fall back through the fonts, in the order given, to find a needed + glyph. + + Returns + ------- + `.ft2font.FT2Font` + + """ + if isinstance(font_filepaths, (str, Path, bytes)): + paths = (_cached_realpath(font_filepaths),) + else: + paths = tuple(_cached_realpath(fname) for fname in font_filepaths) + + if hinting_factor is None: + hinting_factor = mpl.rcParams['text.hinting_factor'] + + return _get_font( + # must be a tuple to be cached + paths, + hinting_factor, + _kerning_factor=mpl.rcParams['text.kerning_factor'], + # also key on the thread ID to prevent segfaults with multi-threading + thread_id=threading.get_ident() + ) + + +def _load_fontmanager(*, try_read_cache=True): + fm_path = Path( + mpl.get_cachedir(), f"fontlist-v{FontManager.__version__}.json") + if try_read_cache: + try: + fm = json_load(fm_path) + except Exception: + pass + else: + if getattr(fm, "_version", object()) == FontManager.__version__: + _log.debug("Using fontManager instance from %s", fm_path) + return fm + fm = FontManager() + json_dump(fm, fm_path) + _log.info("generated new fontManager") + return fm + + +fontManager = _load_fontmanager() +findfont = fontManager.findfont +get_font_names = fontManager.get_font_names diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.pyi new file mode 100644 index 00000000..48d0e362 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/font_manager.pyi @@ -0,0 +1,136 @@ +from dataclasses import dataclass +import os + +from matplotlib._afm import AFM +from matplotlib import ft2font + +from pathlib import Path + +from collections.abc import Iterable +from typing import Any, Literal + +font_scalings: dict[str | None, float] +stretch_dict: dict[str, int] +weight_dict: dict[str, int] +font_family_aliases: set[str] +MSFolders: str +MSFontDirectories: list[str] +MSUserFontDirectories: list[str] +X11FontDirectories: list[str] +OSXFontDirectories: list[str] + +def get_fontext_synonyms(fontext: str) -> list[str]: ... +def list_fonts(directory: str, extensions: Iterable[str]) -> list[str]: ... +def win32FontDirectory() -> str: ... +def _get_fontconfig_fonts() -> list[Path]: ... +def findSystemFonts( + fontpaths: Iterable[str | os.PathLike | Path] | None = ..., fontext: str = ... +) -> list[str]: ... +@dataclass +class FontEntry: + fname: str = ... + name: str = ... + style: str = ... + variant: str = ... + weight: str | int = ... + stretch: str = ... + size: str = ... + def _repr_html_(self) -> str: ... + def _repr_png_(self) -> bytes: ... + +def ttfFontProperty(font: ft2font.FT2Font) -> FontEntry: ... +def afmFontProperty(fontpath: str, font: AFM) -> FontEntry: ... + +class FontProperties: + def __init__( + self, + family: str | Iterable[str] | None = ..., + style: Literal["normal", "italic", "oblique"] | None = ..., + variant: Literal["normal", "small-caps"] | None = ..., + weight: int | str | None = ..., + stretch: int | str | None = ..., + size: float | str | None = ..., + fname: str | os.PathLike | Path | None = ..., + math_fontfamily: str | None = ..., + ) -> None: ... + def __hash__(self) -> int: ... + def __eq__(self, other: object) -> bool: ... + def get_family(self) -> list[str]: ... + def get_name(self) -> str: ... + def get_style(self) -> Literal["normal", "italic", "oblique"]: ... + def get_variant(self) -> Literal["normal", "small-caps"]: ... + def get_weight(self) -> int | str: ... + def get_stretch(self) -> int | str: ... + def get_size(self) -> float: ... + def get_file(self) -> str | bytes | None: ... + def get_fontconfig_pattern(self) -> dict[str, list[Any]]: ... + def set_family(self, family: str | Iterable[str] | None) -> None: ... + def set_style( + self, style: Literal["normal", "italic", "oblique"] | None + ) -> None: ... + def set_variant(self, variant: Literal["normal", "small-caps"] | None) -> None: ... + def set_weight(self, weight: int | str | None) -> None: ... + def set_stretch(self, stretch: int | str | None) -> None: ... + def set_size(self, size: float | str | None) -> None: ... + def set_file(self, file: str | os.PathLike | Path | None) -> None: ... + def set_fontconfig_pattern(self, pattern: str) -> None: ... + def get_math_fontfamily(self) -> str: ... + def set_math_fontfamily(self, fontfamily: str | None) -> None: ... + def copy(self) -> FontProperties: ... + # Aliases + set_name = set_family + get_slant = get_style + set_slant = set_style + get_size_in_points = get_size + +def json_dump(data: FontManager, filename: str | Path | os.PathLike) -> None: ... +def json_load(filename: str | Path | os.PathLike) -> FontManager: ... + +class FontManager: + __version__: int + default_size: float | None + defaultFamily: dict[str, str] + afmlist: list[FontEntry] + ttflist: list[FontEntry] + def __init__(self, size: float | None = ..., weight: str = ...) -> None: ... + def addfont(self, path: str | Path | os.PathLike) -> None: ... + @property + def defaultFont(self) -> dict[str, str]: ... + def get_default_weight(self) -> str: ... + @staticmethod + def get_default_size() -> float: ... + def set_default_weight(self, weight: str) -> None: ... + def score_family( + self, families: str | list[str] | tuple[str], family2: str + ) -> float: ... + def score_style(self, style1: str, style2: str) -> float: ... + def score_variant(self, variant1: str, variant2: str) -> float: ... + def score_stretch(self, stretch1: str | int, stretch2: str | int) -> float: ... + def score_weight(self, weight1: str | float, weight2: str | float) -> float: ... + def score_size(self, size1: str | float, size2: str | float) -> float: ... + def findfont( + self, + prop: str | FontProperties, + fontext: Literal["ttf", "afm"] = ..., + directory: str | None = ..., + fallback_to_default: bool = ..., + rebuild_if_missing: bool = ..., + ) -> str: ... + def get_font_names(self) -> list[str]: ... + +def is_opentype_cff_font(filename: str) -> bool: ... +def get_font( + font_filepaths: Iterable[str | Path | bytes] | str | Path | bytes, + hinting_factor: int | None = ..., +) -> ft2font.FT2Font: ... + +fontManager: FontManager + +def findfont( + prop: str | FontProperties, + fontext: Literal["ttf", "afm"] = ..., + directory: str | None = ..., + fallback_to_default: bool = ..., + rebuild_if_missing: bool = ..., +) -> str: ... +def get_font_names() -> list[str]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..97f6d36a0e9ae5979a0034557e26b5fd6d06f53e GIT binary patch literal 788329 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 FrGcff%5vHv4~f$^Pq7vCE`piOe{! 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 Q_VeW)1%A~iUmEfM0a9GAVgLXD literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.pyi new file mode 100644 index 00000000..6a0716e9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ft2font.pyi @@ -0,0 +1,253 @@ +from typing import BinaryIO, Literal, TypedDict, overload + +import numpy as np +from numpy.typing import NDArray + +__freetype_build_type__: str +__freetype_version__: str +BOLD: int +EXTERNAL_STREAM: int +FAST_GLYPHS: int +FIXED_SIZES: int +FIXED_WIDTH: int +GLYPH_NAMES: int +HORIZONTAL: int +ITALIC: int +KERNING: int +KERNING_DEFAULT: int +KERNING_UNFITTED: int +KERNING_UNSCALED: int +LOAD_CROP_BITMAP: int +LOAD_DEFAULT: int +LOAD_FORCE_AUTOHINT: int +LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH: int +LOAD_IGNORE_TRANSFORM: int +LOAD_LINEAR_DESIGN: int +LOAD_MONOCHROME: int +LOAD_NO_AUTOHINT: int +LOAD_NO_BITMAP: int +LOAD_NO_HINTING: int +LOAD_NO_RECURSE: int +LOAD_NO_SCALE: int +LOAD_PEDANTIC: int +LOAD_RENDER: int +LOAD_TARGET_LCD: int +LOAD_TARGET_LCD_V: int +LOAD_TARGET_LIGHT: int +LOAD_TARGET_MONO: int +LOAD_TARGET_NORMAL: int +LOAD_VERTICAL_LAYOUT: int +MULTIPLE_MASTERS: int +SCALABLE: int +SFNT: int +VERTICAL: int + +class _SfntHeadDict(TypedDict): + version: tuple[int, int] + fontRevision: tuple[int, int] + checkSumAdjustment: int + magicNumber: int + flags: int + unitsPerEm: int + created: tuple[int, int] + modified: tuple[int, int] + xMin: int + yMin: int + xMax: int + yMax: int + macStyle: int + lowestRecPPEM: int + fontDirectionHint: int + indexToLocFormat: int + glyphDataFormat: int + +class _SfntMaxpDict(TypedDict): + version: tuple[int, int] + numGlyphs: int + maxPoints: int + maxContours: int + maxComponentPoints: int + maxComponentContours: int + maxZones: int + maxTwilightPoints: int + maxStorage: int + maxFunctionDefs: int + maxInstructionDefs: int + maxStackElements: int + maxSizeOfInstructions: int + maxComponentElements: int + maxComponentDepth: int + +class _SfntOs2Dict(TypedDict): + version: int + xAvgCharWidth: int + usWeightClass: int + usWidthClass: int + fsType: int + ySubscriptXSize: int + ySubscriptYSize: int + ySubscriptXOffset: int + ySubscriptYOffset: int + ySuperscriptXSize: int + ySuperscriptYSize: int + ySuperscriptXOffset: int + ySuperscriptYOffset: int + yStrikeoutSize: int + yStrikeoutPosition: int + sFamilyClass: int + panose: bytes + ulCharRange: tuple[int, int, int, int] + achVendID: bytes + fsSelection: int + fsFirstCharIndex: int + fsLastCharIndex: int + +class _SfntHheaDict(TypedDict): + version: tuple[int, int] + ascent: int + descent: int + lineGap: int + advanceWidthMax: int + minLeftBearing: int + minRightBearing: int + xMaxExtent: int + caretSlopeRise: int + caretSlopeRun: int + caretOffset: int + metricDataFormat: int + numOfLongHorMetrics: int + +class _SfntVheaDict(TypedDict): + version: tuple[int, int] + vertTypoAscender: int + vertTypoDescender: int + vertTypoLineGap: int + advanceHeightMax: int + minTopSideBearing: int + minBottomSizeBearing: int + yMaxExtent: int + caretSlopeRise: int + caretSlopeRun: int + caretOffset: int + metricDataFormat: int + numOfLongVerMetrics: int + +class _SfntPostDict(TypedDict): + format: tuple[int, int] + italicAngle: tuple[int, int] + underlinePosition: int + underlineThickness: int + isFixedPitch: int + minMemType42: int + maxMemType42: int + minMemType1: int + maxMemType1: int + +class _SfntPcltDict(TypedDict): + version: tuple[int, int] + fontNumber: int + pitch: int + xHeight: int + style: int + typeFamily: int + capHeight: int + symbolSet: int + typeFace: bytes + characterComplement: bytes + strokeWeight: int + widthType: int + serifStyle: int + +class FT2Font: + ascender: int + bbox: tuple[int, int, int, int] + descender: int + face_flags: int + family_name: str + fname: str + height: int + max_advance_height: int + max_advance_width: int + num_charmaps: int + num_faces: int + num_fixed_sizes: int + num_glyphs: int + postscript_name: str + scalable: bool + style_flags: int + style_name: str + underline_position: int + underline_thickness: int + units_per_EM: int + + def __init__( + self, + filename: str | BinaryIO, + hinting_factor: int = ..., + *, + _fallback_list: list[FT2Font] | None = ..., + _kerning_factor: int = ... + ) -> None: ... + def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ... + def clear(self) -> None: ... + def draw_glyph_to_bitmap( + self, image: FT2Image, x: float, y: float, glyph: Glyph, antialiased: bool = ... + ) -> None: ... + def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ... + def get_bitmap_offset(self) -> tuple[int, int]: ... + def get_char_index(self, codepoint: int) -> int: ... + def get_charmap(self) -> dict[int, int]: ... + def get_descent(self) -> int: ... + def get_glyph_name(self, index: int) -> str: ... + def get_image(self) -> NDArray[np.uint8]: ... + def get_kerning(self, left: int, right: int, mode: int) -> int: ... + def get_name_index(self, name: str) -> int: ... + def get_num_glyphs(self) -> int: ... + def get_path(self) -> tuple[NDArray[np.float64], NDArray[np.int8]]: ... + def get_ps_font_info( + self, + ) -> tuple[str, str, str, str, str, int, int, int, int]: ... + def get_sfnt(self) -> dict[tuple[int, int, int, int], bytes]: ... + @overload + def get_sfnt_table(self, name: Literal["head"]) -> _SfntHeadDict | None: ... + @overload + def get_sfnt_table(self, name: Literal["maxp"]) -> _SfntMaxpDict | None: ... + @overload + def get_sfnt_table(self, name: Literal["OS/2"]) -> _SfntOs2Dict | None: ... + @overload + def get_sfnt_table(self, name: Literal["hhea"]) -> _SfntHheaDict | None: ... + @overload + def get_sfnt_table(self, name: Literal["vhea"]) -> _SfntVheaDict | None: ... + @overload + def get_sfnt_table(self, name: Literal["post"]) -> _SfntPostDict | None: ... + @overload + def get_sfnt_table(self, name: Literal["pclt"]) -> _SfntPcltDict | None: ... + def get_width_height(self) -> tuple[int, int]: ... + def get_xys(self, antialiased: bool = ...) -> NDArray[np.float64]: ... + def load_char(self, charcode: int, flags: int = ...) -> Glyph: ... + def load_glyph(self, glyphindex: int, flags: int = ...) -> Glyph: ... + def select_charmap(self, i: int) -> None: ... + def set_charmap(self, i: int) -> None: ... + def set_size(self, ptsize: float, dpi: float) -> None: ... + def set_text( + self, string: str, angle: float = ..., flags: int = ... + ) -> NDArray[np.float64]: ... + +class FT2Image: # TODO: When updating mypy>=1.4, subclass from Buffer. + def __init__(self, width: float, height: float) -> None: ... + def draw_rect(self, x0: float, y0: float, x1: float, y1: float) -> None: ... + def draw_rect_filled(self, x0: float, y0: float, x1: float, y1: float) -> None: ... + +class Glyph: + width: int + height: int + horiBearingX: int + horiBearingY: int + horiAdvance: int + linearHoriAdvance: int + vertBearingX: int + vertBearingY: int + vertAdvance: int + + @property + def bbox(self) -> tuple[int, int, int, int]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.py new file mode 100644 index 00000000..b2f1b5d8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.py @@ -0,0 +1,738 @@ +r""" +:mod:`~matplotlib.gridspec` contains classes that help to layout multiple +`~.axes.Axes` in a grid-like pattern within a figure. + +The `GridSpec` specifies the overall grid structure. Individual cells within +the grid are referenced by `SubplotSpec`\s. + +Often, users need not access this module directly, and can use higher-level +methods like `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` and +`~.Figure.subfigures`. See the tutorial :ref:`arranging_axes` for a guide. +""" + +import copy +import logging +from numbers import Integral + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, _pylab_helpers, _tight_layout +from matplotlib.transforms import Bbox + +_log = logging.getLogger(__name__) + + +class GridSpecBase: + """ + A base class of GridSpec that specifies the geometry of the grid + that a subplot will be placed. + """ + + def __init__(self, nrows, ncols, height_ratios=None, width_ratios=None): + """ + Parameters + ---------- + nrows, ncols : int + The number of rows and columns of the grid. + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. + """ + if not isinstance(nrows, Integral) or nrows <= 0: + raise ValueError( + f"Number of rows must be a positive integer, not {nrows!r}") + if not isinstance(ncols, Integral) or ncols <= 0: + raise ValueError( + f"Number of columns must be a positive integer, not {ncols!r}") + self._nrows, self._ncols = nrows, ncols + self.set_height_ratios(height_ratios) + self.set_width_ratios(width_ratios) + + def __repr__(self): + height_arg = (f', height_ratios={self._row_height_ratios!r}' + if len(set(self._row_height_ratios)) != 1 else '') + width_arg = (f', width_ratios={self._col_width_ratios!r}' + if len(set(self._col_width_ratios)) != 1 else '') + return '{clsname}({nrows}, {ncols}{optionals})'.format( + clsname=self.__class__.__name__, + nrows=self._nrows, + ncols=self._ncols, + optionals=height_arg + width_arg, + ) + + nrows = property(lambda self: self._nrows, + doc="The number of rows in the grid.") + ncols = property(lambda self: self._ncols, + doc="The number of columns in the grid.") + + def get_geometry(self): + """ + Return a tuple containing the number of rows and columns in the grid. + """ + return self._nrows, self._ncols + + def get_subplot_params(self, figure=None): + # Must be implemented in subclasses + pass + + def new_subplotspec(self, loc, rowspan=1, colspan=1): + """ + Create and return a `.SubplotSpec` instance. + + Parameters + ---------- + loc : (int, int) + The position of the subplot in the grid as + ``(row_index, column_index)``. + rowspan, colspan : int, default: 1 + The number of rows and columns the subplot should span in the grid. + """ + loc1, loc2 = loc + subplotspec = self[loc1:loc1+rowspan, loc2:loc2+colspan] + return subplotspec + + def set_width_ratios(self, width_ratios): + """ + Set the relative widths of the columns. + + *width_ratios* must be of length *ncols*. Each column gets a relative + width of ``width_ratios[i] / sum(width_ratios)``. + """ + if width_ratios is None: + width_ratios = [1] * self._ncols + elif len(width_ratios) != self._ncols: + raise ValueError('Expected the given number of width ratios to ' + 'match the number of columns of the grid') + self._col_width_ratios = width_ratios + + def get_width_ratios(self): + """ + Return the width ratios. + + This is *None* if no width ratios have been set explicitly. + """ + return self._col_width_ratios + + def set_height_ratios(self, height_ratios): + """ + Set the relative heights of the rows. + + *height_ratios* must be of length *nrows*. Each row gets a relative + height of ``height_ratios[i] / sum(height_ratios)``. + """ + if height_ratios is None: + height_ratios = [1] * self._nrows + elif len(height_ratios) != self._nrows: + raise ValueError('Expected the given number of height ratios to ' + 'match the number of rows of the grid') + self._row_height_ratios = height_ratios + + def get_height_ratios(self): + """ + Return the height ratios. + + This is *None* if no height ratios have been set explicitly. + """ + return self._row_height_ratios + + @_api.delete_parameter("3.7", "raw") + def get_grid_positions(self, fig, raw=False): + """ + Return the positions of the grid cells in figure coordinates. + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + The figure the grid should be applied to. The subplot parameters + (margins and spacing between subplots) are taken from *fig*. + raw : bool, default: False + If *True*, the subplot parameters of the figure are not taken + into account. The grid spans the range [0, 1] in both directions + without margins and there is no space between grid cells. This is + used for constrained_layout. + + Returns + ------- + bottoms, tops, lefts, rights : array + The bottom, top, left, right positions of the grid cells in + figure coordinates. + """ + nrows, ncols = self.get_geometry() + + if raw: + left = 0. + right = 1. + bottom = 0. + top = 1. + wspace = 0. + hspace = 0. + else: + subplot_params = self.get_subplot_params(fig) + left = subplot_params.left + right = subplot_params.right + bottom = subplot_params.bottom + top = subplot_params.top + wspace = subplot_params.wspace + hspace = subplot_params.hspace + tot_width = right - left + tot_height = top - bottom + + # calculate accumulated heights of columns + cell_h = tot_height / (nrows + hspace*(nrows-1)) + sep_h = hspace * cell_h + norm = cell_h * nrows / sum(self._row_height_ratios) + cell_heights = [r * norm for r in self._row_height_ratios] + sep_heights = [0] + ([sep_h] * (nrows-1)) + cell_hs = np.cumsum(np.column_stack([sep_heights, cell_heights]).flat) + + # calculate accumulated widths of rows + cell_w = tot_width / (ncols + wspace*(ncols-1)) + sep_w = wspace * cell_w + norm = cell_w * ncols / sum(self._col_width_ratios) + cell_widths = [r * norm for r in self._col_width_ratios] + sep_widths = [0] + ([sep_w] * (ncols-1)) + cell_ws = np.cumsum(np.column_stack([sep_widths, cell_widths]).flat) + + fig_tops, fig_bottoms = (top - cell_hs).reshape((-1, 2)).T + fig_lefts, fig_rights = (left + cell_ws).reshape((-1, 2)).T + return fig_bottoms, fig_tops, fig_lefts, fig_rights + + @staticmethod + def _check_gridspec_exists(figure, nrows, ncols): + """ + Check if the figure already has a gridspec with these dimensions, + or create a new one + """ + for ax in figure.get_axes(): + gs = ax.get_gridspec() + if gs is not None: + if hasattr(gs, 'get_topmost_subplotspec'): + # This is needed for colorbar gridspec layouts. + # This is probably OK because this whole logic tree + # is for when the user is doing simple things with the + # add_subplot command. For complicated layouts + # like subgridspecs the proper gridspec is passed in... + gs = gs.get_topmost_subplotspec().get_gridspec() + if gs.get_geometry() == (nrows, ncols): + return gs + # else gridspec not found: + return GridSpec(nrows, ncols, figure=figure) + + def __getitem__(self, key): + """Create and return a `.SubplotSpec` instance.""" + nrows, ncols = self.get_geometry() + + def _normalize(key, size, axis): # Includes last index. + orig_key = key + if isinstance(key, slice): + start, stop, _ = key.indices(size) + if stop > start: + return start, stop - 1 + raise IndexError("GridSpec slice would result in no space " + "allocated for subplot") + else: + if key < 0: + key = key + size + if 0 <= key < size: + return key, key + elif axis is not None: + raise IndexError(f"index {orig_key} is out of bounds for " + f"axis {axis} with size {size}") + else: # flat index + raise IndexError(f"index {orig_key} is out of bounds for " + f"GridSpec with size {size}") + + if isinstance(key, tuple): + try: + k1, k2 = key + except ValueError as err: + raise ValueError("Unrecognized subplot spec") from err + num1, num2 = np.ravel_multi_index( + [_normalize(k1, nrows, 0), _normalize(k2, ncols, 1)], + (nrows, ncols)) + else: # Single key + num1, num2 = _normalize(key, nrows * ncols, None) + + return SubplotSpec(self, num1, num2) + + def subplots(self, *, sharex=False, sharey=False, squeeze=True, + subplot_kw=None): + """ + Add all subplots specified by this `GridSpec` to its parent figure. + + See `.Figure.subplots` for detailed documentation. + """ + + figure = self.figure + + if figure is None: + raise ValueError("GridSpec.subplots() only works for GridSpecs " + "created with a parent figure") + + if not isinstance(sharex, str): + sharex = "all" if sharex else "none" + if not isinstance(sharey, str): + sharey = "all" if sharey else "none" + + _api.check_in_list(["all", "row", "col", "none", False, True], + sharex=sharex, sharey=sharey) + if subplot_kw is None: + subplot_kw = {} + # don't mutate kwargs passed by user... + subplot_kw = subplot_kw.copy() + + # Create array to hold all axes. + axarr = np.empty((self._nrows, self._ncols), dtype=object) + for row in range(self._nrows): + for col in range(self._ncols): + shared_with = {"none": None, "all": axarr[0, 0], + "row": axarr[row, 0], "col": axarr[0, col]} + subplot_kw["sharex"] = shared_with[sharex] + subplot_kw["sharey"] = shared_with[sharey] + axarr[row, col] = figure.add_subplot( + self[row, col], **subplot_kw) + + # turn off redundant tick labeling + if sharex in ["col", "all"]: + for ax in axarr.flat: + ax._label_outer_xaxis(skip_non_rectangular_axes=True) + if sharey in ["row", "all"]: + for ax in axarr.flat: + ax._label_outer_yaxis(skip_non_rectangular_axes=True) + + if squeeze: + # Discarding unneeded dimensions that equal 1. If we only have one + # subplot, just return it instead of a 1-element array. + return axarr.item() if axarr.size == 1 else axarr.squeeze() + else: + # Returned axis array will be always 2-d, even if nrows=ncols=1. + return axarr + + +class GridSpec(GridSpecBase): + """ + A grid layout to place subplots within a figure. + + The location of the grid cells is determined in a similar way to + `~.figure.SubplotParams` using *left*, *right*, *top*, *bottom*, *wspace* + and *hspace*. + + Indexing a GridSpec instance returns a `.SubplotSpec`. + """ + def __init__(self, nrows, ncols, figure=None, + left=None, bottom=None, right=None, top=None, + wspace=None, hspace=None, + width_ratios=None, height_ratios=None): + """ + Parameters + ---------- + nrows, ncols : int + The number of rows and columns of the grid. + + figure : `.Figure`, optional + Only used for constrained layout to create a proper layoutgrid. + + left, right, top, bottom : float, optional + Extent of the subplots as a fraction of figure width or height. + Left cannot be larger than right, and bottom cannot be larger than + top. If not given, the values will be inferred from a figure or + rcParams at draw time. See also `GridSpec.get_subplot_params`. + + wspace : float, optional + The amount of width reserved for space between subplots, + expressed as a fraction of the average axis width. + If not given, the values will be inferred from a figure or + rcParams when necessary. See also `GridSpec.get_subplot_params`. + + hspace : float, optional + The amount of height reserved for space between subplots, + expressed as a fraction of the average axis height. + If not given, the values will be inferred from a figure or + rcParams when necessary. See also `GridSpec.get_subplot_params`. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. + + """ + self.left = left + self.bottom = bottom + self.right = right + self.top = top + self.wspace = wspace + self.hspace = hspace + self.figure = figure + + super().__init__(nrows, ncols, + width_ratios=width_ratios, + height_ratios=height_ratios) + + _AllowedKeys = ["left", "bottom", "right", "top", "wspace", "hspace"] + + def update(self, **kwargs): + """ + Update the subplot parameters of the grid. + + Parameters that are not explicitly given are not changed. Setting a + parameter to *None* resets it to :rc:`figure.subplot.*`. + + Parameters + ---------- + left, right, top, bottom : float or None, optional + Extent of the subplots as a fraction of figure width or height. + wspace, hspace : float, optional + Spacing between the subplots as a fraction of the average subplot + width / height. + """ + for k, v in kwargs.items(): + if k in self._AllowedKeys: + setattr(self, k, v) + else: + raise AttributeError(f"{k} is an unknown keyword") + for figmanager in _pylab_helpers.Gcf.figs.values(): + for ax in figmanager.canvas.figure.axes: + if ax.get_subplotspec() is not None: + ss = ax.get_subplotspec().get_topmost_subplotspec() + if ss.get_gridspec() == self: + ax._set_position( + ax.get_subplotspec().get_position(ax.figure)) + + def get_subplot_params(self, figure=None): + """ + Return the `.SubplotParams` for the GridSpec. + + In order of precedence the values are taken from + + - non-*None* attributes of the GridSpec + - the provided *figure* + - :rc:`figure.subplot.*` + + Note that the ``figure`` attribute of the GridSpec is always ignored. + """ + if figure is None: + kw = {k: mpl.rcParams["figure.subplot."+k] + for k in self._AllowedKeys} + subplotpars = mpl.figure.SubplotParams(**kw) + else: + subplotpars = copy.copy(figure.subplotpars) + + subplotpars.update(**{k: getattr(self, k) for k in self._AllowedKeys}) + + return subplotpars + + def locally_modified_subplot_params(self): + """ + Return a list of the names of the subplot parameters explicitly set + in the GridSpec. + + This is a subset of the attributes of `.SubplotParams`. + """ + return [k for k in self._AllowedKeys if getattr(self, k)] + + def tight_layout(self, figure, renderer=None, + pad=1.08, h_pad=None, w_pad=None, rect=None): + """ + Adjust subplot parameters to give specified padding. + + Parameters + ---------- + figure : `.Figure` + The figure. + renderer : `.RendererBase` subclass, optional + The renderer to be used. + pad : float + Padding between the figure edge and the edges of subplots, as a + fraction of the font-size. + h_pad, w_pad : float, optional + Padding (height/width) between edges of adjacent subplots. + Defaults to *pad*. + rect : tuple (left, bottom, right, top), default: None + (left, bottom, right, top) rectangle in normalized figure + coordinates that the whole subplots area (including labels) will + fit into. Default (None) is the whole figure. + """ + if renderer is None: + renderer = figure._get_renderer() + kwargs = _tight_layout.get_tight_layout_figure( + figure, figure.axes, + _tight_layout.get_subplotspec_list(figure.axes, grid_spec=self), + renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) + if kwargs: + self.update(**kwargs) + + +class GridSpecFromSubplotSpec(GridSpecBase): + """ + GridSpec whose subplot layout parameters are inherited from the + location specified by a given SubplotSpec. + """ + def __init__(self, nrows, ncols, + subplot_spec, + wspace=None, hspace=None, + height_ratios=None, width_ratios=None): + """ + Parameters + ---------- + nrows, ncols : int + Number of rows and number of columns of the grid. + subplot_spec : SubplotSpec + Spec from which the layout parameters are inherited. + wspace, hspace : float, optional + See `GridSpec` for more details. If not specified default values + (from the figure or rcParams) are used. + height_ratios : array-like of length *nrows*, optional + See `GridSpecBase` for details. + width_ratios : array-like of length *ncols*, optional + See `GridSpecBase` for details. + """ + self._wspace = wspace + self._hspace = hspace + self._subplot_spec = subplot_spec + self.figure = self._subplot_spec.get_gridspec().figure + super().__init__(nrows, ncols, + width_ratios=width_ratios, + height_ratios=height_ratios) + + def get_subplot_params(self, figure=None): + """Return a dictionary of subplot layout parameters.""" + hspace = (self._hspace if self._hspace is not None + else figure.subplotpars.hspace if figure is not None + else mpl.rcParams["figure.subplot.hspace"]) + wspace = (self._wspace if self._wspace is not None + else figure.subplotpars.wspace if figure is not None + else mpl.rcParams["figure.subplot.wspace"]) + + figbox = self._subplot_spec.get_position(figure) + left, bottom, right, top = figbox.extents + + return mpl.figure.SubplotParams(left=left, right=right, + bottom=bottom, top=top, + wspace=wspace, hspace=hspace) + + def get_topmost_subplotspec(self): + """ + Return the topmost `.SubplotSpec` instance associated with the subplot. + """ + return self._subplot_spec.get_topmost_subplotspec() + + +class SubplotSpec: + """ + The location of a subplot in a `GridSpec`. + + .. note:: + + Likely, you will never instantiate a `SubplotSpec` yourself. Instead, + you will typically obtain one from a `GridSpec` using item-access. + + Parameters + ---------- + gridspec : `~matplotlib.gridspec.GridSpec` + The GridSpec, which the subplot is referencing. + num1, num2 : int + The subplot will occupy the *num1*-th cell of the given + *gridspec*. If *num2* is provided, the subplot will span between + *num1*-th cell and *num2*-th cell **inclusive**. + + The index starts from 0. + """ + def __init__(self, gridspec, num1, num2=None): + self._gridspec = gridspec + self.num1 = num1 + self.num2 = num2 + + def __repr__(self): + return (f"{self.get_gridspec()}[" + f"{self.rowspan.start}:{self.rowspan.stop}, " + f"{self.colspan.start}:{self.colspan.stop}]") + + @staticmethod + def _from_subplot_args(figure, args): + """ + Construct a `.SubplotSpec` from a parent `.Figure` and either + + - a `.SubplotSpec` -- returned as is; + - one or three numbers -- a MATLAB-style subplot specifier. + """ + if len(args) == 1: + arg, = args + if isinstance(arg, SubplotSpec): + return arg + elif not isinstance(arg, Integral): + raise ValueError( + f"Single argument to subplot must be a three-digit " + f"integer, not {arg!r}") + try: + rows, cols, num = map(int, str(arg)) + except ValueError: + raise ValueError( + f"Single argument to subplot must be a three-digit " + f"integer, not {arg!r}") from None + elif len(args) == 3: + rows, cols, num = args + else: + raise _api.nargs_error("subplot", takes="1 or 3", given=len(args)) + + gs = GridSpec._check_gridspec_exists(figure, rows, cols) + if gs is None: + gs = GridSpec(rows, cols, figure=figure) + if isinstance(num, tuple) and len(num) == 2: + if not all(isinstance(n, Integral) for n in num): + raise ValueError( + f"Subplot specifier tuple must contain integers, not {num}" + ) + i, j = num + else: + if not isinstance(num, Integral) or num < 1 or num > rows*cols: + raise ValueError( + f"num must be an integer with 1 <= num <= {rows*cols}, " + f"not {num!r}" + ) + i = j = num + return gs[i-1:j] + + # num2 is a property only to handle the case where it is None and someone + # mutates num1. + + @property + def num2(self): + return self.num1 if self._num2 is None else self._num2 + + @num2.setter + def num2(self, value): + self._num2 = value + + def get_gridspec(self): + return self._gridspec + + def get_geometry(self): + """ + Return the subplot geometry as tuple ``(n_rows, n_cols, start, stop)``. + + The indices *start* and *stop* define the range of the subplot within + the `GridSpec`. *stop* is inclusive (i.e. for a single cell + ``start == stop``). + """ + rows, cols = self.get_gridspec().get_geometry() + return rows, cols, self.num1, self.num2 + + @property + def rowspan(self): + """The rows spanned by this subplot, as a `range` object.""" + ncols = self.get_gridspec().ncols + return range(self.num1 // ncols, self.num2 // ncols + 1) + + @property + def colspan(self): + """The columns spanned by this subplot, as a `range` object.""" + ncols = self.get_gridspec().ncols + # We explicitly support num2 referring to a column on num1's *left*, so + # we must sort the column indices here so that the range makes sense. + c1, c2 = sorted([self.num1 % ncols, self.num2 % ncols]) + return range(c1, c2 + 1) + + def is_first_row(self): + return self.rowspan.start == 0 + + def is_last_row(self): + return self.rowspan.stop == self.get_gridspec().nrows + + def is_first_col(self): + return self.colspan.start == 0 + + def is_last_col(self): + return self.colspan.stop == self.get_gridspec().ncols + + def get_position(self, figure): + """ + Update the subplot position from ``figure.subplotpars``. + """ + gridspec = self.get_gridspec() + nrows, ncols = gridspec.get_geometry() + rows, cols = np.unravel_index([self.num1, self.num2], (nrows, ncols)) + fig_bottoms, fig_tops, fig_lefts, fig_rights = \ + gridspec.get_grid_positions(figure) + + fig_bottom = fig_bottoms[rows].min() + fig_top = fig_tops[rows].max() + fig_left = fig_lefts[cols].min() + fig_right = fig_rights[cols].max() + return Bbox.from_extents(fig_left, fig_bottom, fig_right, fig_top) + + def get_topmost_subplotspec(self): + """ + Return the topmost `SubplotSpec` instance associated with the subplot. + """ + gridspec = self.get_gridspec() + if hasattr(gridspec, "get_topmost_subplotspec"): + return gridspec.get_topmost_subplotspec() + else: + return self + + def __eq__(self, other): + """ + Two SubplotSpecs are considered equal if they refer to the same + position(s) in the same `GridSpec`. + """ + # other may not even have the attributes we are checking. + return ((self._gridspec, self.num1, self.num2) + == (getattr(other, "_gridspec", object()), + getattr(other, "num1", object()), + getattr(other, "num2", object()))) + + def __hash__(self): + return hash((self._gridspec, self.num1, self.num2)) + + def subgridspec(self, nrows, ncols, **kwargs): + """ + Create a GridSpec within this subplot. + + The created `.GridSpecFromSubplotSpec` will have this `SubplotSpec` as + a parent. + + Parameters + ---------- + nrows : int + Number of rows in grid. + + ncols : int + Number of columns in grid. + + Returns + ------- + `.GridSpecFromSubplotSpec` + + Other Parameters + ---------------- + **kwargs + All other parameters are passed to `.GridSpecFromSubplotSpec`. + + See Also + -------- + matplotlib.pyplot.subplots + + Examples + -------- + Adding three subplots in the space occupied by a single subplot:: + + fig = plt.figure() + gs0 = fig.add_gridspec(3, 1) + ax1 = fig.add_subplot(gs0[0]) + ax2 = fig.add_subplot(gs0[1]) + gssub = gs0[2].subgridspec(1, 3) + for i in range(3): + fig.add_subplot(gssub[0, i]) + """ + return GridSpecFromSubplotSpec(nrows, ncols, self, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.pyi new file mode 100644 index 00000000..6e227308 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/gridspec.pyi @@ -0,0 +1,134 @@ +from typing import Any, Literal, overload + +from numpy.typing import ArrayLike +import numpy as np + +from matplotlib.axes import Axes, SubplotBase +from matplotlib.backend_bases import RendererBase +from matplotlib.figure import Figure, SubplotParams +from matplotlib.transforms import Bbox + +class GridSpecBase: + def __init__( + self, + nrows: int, + ncols: int, + height_ratios: ArrayLike | None = ..., + width_ratios: ArrayLike | None = ..., + ) -> None: ... + @property + def nrows(self) -> int: ... + @property + def ncols(self) -> int: ... + def get_geometry(self) -> tuple[int, int]: ... + def get_subplot_params(self, figure: Figure | None = ...) -> SubplotParams: ... + def new_subplotspec( + self, loc: tuple[int, int], rowspan: int = ..., colspan: int = ... + ) -> SubplotSpec: ... + def set_width_ratios(self, width_ratios: ArrayLike | None) -> None: ... + def get_width_ratios(self) -> ArrayLike: ... + def set_height_ratios(self, height_ratios: ArrayLike | None) -> None: ... + def get_height_ratios(self) -> ArrayLike: ... + def get_grid_positions( + self, fig: Figure, raw: bool = ... + ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: ... + @staticmethod + def _check_gridspec_exists(figure: Figure, nrows: int, ncols: int) -> GridSpec: ... + def __getitem__( + self, key: tuple[int | slice, int | slice] | slice | int + ) -> SubplotSpec: ... + @overload + def subplots( + self, + *, + sharex: bool | Literal["all", "row", "col", "none"] = ..., + sharey: bool | Literal["all", "row", "col", "none"] = ..., + squeeze: Literal[False], + subplot_kw: dict[str, Any] | None = ... + ) -> np.ndarray: ... + @overload + def subplots( + self, + *, + sharex: bool | Literal["all", "row", "col", "none"] = ..., + sharey: bool | Literal["all", "row", "col", "none"] = ..., + squeeze: Literal[True] = ..., + subplot_kw: dict[str, Any] | None = ... + ) -> np.ndarray | SubplotBase | Axes: ... + +class GridSpec(GridSpecBase): + left: float | None + bottom: float | None + right: float | None + top: float | None + wspace: float | None + hspace: float | None + figure: Figure | None + def __init__( + self, + nrows: int, + ncols: int, + figure: Figure | None = ..., + left: float | None = ..., + bottom: float | None = ..., + right: float | None = ..., + top: float | None = ..., + wspace: float | None = ..., + hspace: float | None = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + ) -> None: ... + def update(self, **kwargs: float | None) -> None: ... + def locally_modified_subplot_params(self) -> list[str]: ... + def tight_layout( + self, + figure: Figure, + renderer: RendererBase | None = ..., + pad: float = ..., + h_pad: float | None = ..., + w_pad: float | None = ..., + rect: tuple[float, float, float, float] | None = ..., + ) -> None: ... + +class GridSpecFromSubplotSpec(GridSpecBase): + figure: Figure | None + def __init__( + self, + nrows: int, + ncols: int, + subplot_spec: SubplotSpec, + wspace: float | None = ..., + hspace: float | None = ..., + height_ratios: ArrayLike | None = ..., + width_ratios: ArrayLike | None = ..., + ) -> None: ... + def get_topmost_subplotspec(self) -> SubplotSpec: ... + +class SubplotSpec: + num1: int + def __init__( + self, gridspec: GridSpecBase, num1: int, num2: int | None = ... + ) -> None: ... + @staticmethod + def _from_subplot_args(figure, args): ... + @property + def num2(self) -> int: ... + @num2.setter + def num2(self, value: int) -> None: ... + def get_gridspec(self) -> GridSpec: ... + def get_geometry(self) -> tuple[int, int, int, int]: ... + @property + def rowspan(self) -> range: ... + @property + def colspan(self) -> range: ... + def is_first_row(self) -> bool: ... + def is_last_row(self) -> bool: ... + def is_first_col(self) -> bool: ... + def is_last_col(self) -> bool: ... + def get_position(self, figure: Figure) -> Bbox: ... + def get_topmost_subplotspec(self) -> SubplotSpec: ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self) -> int: ... + def subgridspec( + self, nrows: int, ncols: int, **kwargs + ) -> GridSpecFromSubplotSpec: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.py new file mode 100644 index 00000000..9ec88776 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.py @@ -0,0 +1,225 @@ +"""Contains classes for generating hatch patterns.""" + +import numpy as np + +from matplotlib import _api +from matplotlib.path import Path + + +class HatchPatternBase: + """The base class for a hatch pattern.""" + pass + + +class HorizontalHatch(HatchPatternBase): + def __init__(self, hatch, density): + self.num_lines = int((hatch.count('-') + hatch.count('+')) * density) + self.num_vertices = self.num_lines * 2 + + def set_vertices_and_codes(self, vertices, codes): + steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False, + retstep=True) + steps += stepsize / 2. + vertices[0::2, 0] = 0.0 + vertices[0::2, 1] = steps + vertices[1::2, 0] = 1.0 + vertices[1::2, 1] = steps + codes[0::2] = Path.MOVETO + codes[1::2] = Path.LINETO + + +class VerticalHatch(HatchPatternBase): + def __init__(self, hatch, density): + self.num_lines = int((hatch.count('|') + hatch.count('+')) * density) + self.num_vertices = self.num_lines * 2 + + def set_vertices_and_codes(self, vertices, codes): + steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False, + retstep=True) + steps += stepsize / 2. + vertices[0::2, 0] = steps + vertices[0::2, 1] = 0.0 + vertices[1::2, 0] = steps + vertices[1::2, 1] = 1.0 + codes[0::2] = Path.MOVETO + codes[1::2] = Path.LINETO + + +class NorthEastHatch(HatchPatternBase): + def __init__(self, hatch, density): + self.num_lines = int( + (hatch.count('/') + hatch.count('x') + hatch.count('X')) * density) + if self.num_lines: + self.num_vertices = (self.num_lines + 1) * 2 + else: + self.num_vertices = 0 + + def set_vertices_and_codes(self, vertices, codes): + steps = np.linspace(-0.5, 0.5, self.num_lines + 1) + vertices[0::2, 0] = 0.0 + steps + vertices[0::2, 1] = 0.0 - steps + vertices[1::2, 0] = 1.0 + steps + vertices[1::2, 1] = 1.0 - steps + codes[0::2] = Path.MOVETO + codes[1::2] = Path.LINETO + + +class SouthEastHatch(HatchPatternBase): + def __init__(self, hatch, density): + self.num_lines = int( + (hatch.count('\\') + hatch.count('x') + hatch.count('X')) + * density) + if self.num_lines: + self.num_vertices = (self.num_lines + 1) * 2 + else: + self.num_vertices = 0 + + def set_vertices_and_codes(self, vertices, codes): + steps = np.linspace(-0.5, 0.5, self.num_lines + 1) + vertices[0::2, 0] = 0.0 + steps + vertices[0::2, 1] = 1.0 + steps + vertices[1::2, 0] = 1.0 + steps + vertices[1::2, 1] = 0.0 + steps + codes[0::2] = Path.MOVETO + codes[1::2] = Path.LINETO + + +class Shapes(HatchPatternBase): + filled = False + + def __init__(self, hatch, density): + if self.num_rows == 0: + self.num_shapes = 0 + self.num_vertices = 0 + else: + self.num_shapes = ((self.num_rows // 2 + 1) * (self.num_rows + 1) + + (self.num_rows // 2) * self.num_rows) + self.num_vertices = (self.num_shapes * + len(self.shape_vertices) * + (1 if self.filled else 2)) + + def set_vertices_and_codes(self, vertices, codes): + offset = 1.0 / self.num_rows + shape_vertices = self.shape_vertices * offset * self.size + shape_codes = self.shape_codes + if not self.filled: + shape_vertices = np.concatenate( # Forward, then backward. + [shape_vertices, shape_vertices[::-1] * 0.9]) + shape_codes = np.concatenate([shape_codes, shape_codes]) + vertices_parts = [] + codes_parts = [] + for row in range(self.num_rows + 1): + if row % 2 == 0: + cols = np.linspace(0, 1, self.num_rows + 1) + else: + cols = np.linspace(offset / 2, 1 - offset / 2, self.num_rows) + row_pos = row * offset + for col_pos in cols: + vertices_parts.append(shape_vertices + [col_pos, row_pos]) + codes_parts.append(shape_codes) + np.concatenate(vertices_parts, out=vertices) + np.concatenate(codes_parts, out=codes) + + +class Circles(Shapes): + def __init__(self, hatch, density): + path = Path.unit_circle() + self.shape_vertices = path.vertices + self.shape_codes = path.codes + super().__init__(hatch, density) + + +class SmallCircles(Circles): + size = 0.2 + + def __init__(self, hatch, density): + self.num_rows = (hatch.count('o')) * density + super().__init__(hatch, density) + + +class LargeCircles(Circles): + size = 0.35 + + def __init__(self, hatch, density): + self.num_rows = (hatch.count('O')) * density + super().__init__(hatch, density) + + +class SmallFilledCircles(Circles): + size = 0.1 + filled = True + + def __init__(self, hatch, density): + self.num_rows = (hatch.count('.')) * density + super().__init__(hatch, density) + + +class Stars(Shapes): + size = 1.0 / 3.0 + filled = True + + def __init__(self, hatch, density): + self.num_rows = (hatch.count('*')) * density + path = Path.unit_regular_star(5) + self.shape_vertices = path.vertices + self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO, + dtype=Path.code_type) + self.shape_codes[0] = Path.MOVETO + super().__init__(hatch, density) + +_hatch_types = [ + HorizontalHatch, + VerticalHatch, + NorthEastHatch, + SouthEastHatch, + SmallCircles, + LargeCircles, + SmallFilledCircles, + Stars + ] + + +def _validate_hatch_pattern(hatch): + valid_hatch_patterns = set(r'-+|/\xXoO.*') + if hatch is not None: + invalids = set(hatch).difference(valid_hatch_patterns) + if invalids: + valid = ''.join(sorted(valid_hatch_patterns)) + invalids = ''.join(sorted(invalids)) + _api.warn_deprecated( + '3.4', + removal='3.9', # one release after custom hatches (#20690) + message=f'hatch must consist of a string of "{valid}" or ' + 'None, but found the following invalid values ' + f'"{invalids}". Passing invalid values is deprecated ' + 'since %(since)s and will become an error %(removal)s.' + ) + + +def get_path(hatchpattern, density=6): + """ + Given a hatch specifier, *hatchpattern*, generates Path to render + the hatch in a unit square. *density* is the number of lines per + unit square. + """ + density = int(density) + + patterns = [hatch_type(hatchpattern, density) + for hatch_type in _hatch_types] + num_vertices = sum([pattern.num_vertices for pattern in patterns]) + + if num_vertices == 0: + return Path(np.empty((0, 2))) + + vertices = np.empty((num_vertices, 2)) + codes = np.empty(num_vertices, Path.code_type) + + cursor = 0 + for pattern in patterns: + if pattern.num_vertices != 0: + vertices_chunk = vertices[cursor:cursor + pattern.num_vertices] + codes_chunk = codes[cursor:cursor + pattern.num_vertices] + pattern.set_vertices_and_codes(vertices_chunk, codes_chunk) + cursor += pattern.num_vertices + + return Path(vertices, codes) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.pyi new file mode 100644 index 00000000..348cf521 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/hatch.pyi @@ -0,0 +1,68 @@ +from matplotlib.path import Path + +import numpy as np +from numpy.typing import ArrayLike + +class HatchPatternBase: ... + +class HorizontalHatch(HatchPatternBase): + num_lines: int + num_vertices: int + def __init__(self, hatch: str, density: int) -> None: ... + def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ... + +class VerticalHatch(HatchPatternBase): + num_lines: int + num_vertices: int + def __init__(self, hatch: str, density: int) -> None: ... + def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ... + +class NorthEastHatch(HatchPatternBase): + num_lines: int + num_vertices: int + def __init__(self, hatch: str, density: int) -> None: ... + def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ... + +class SouthEastHatch(HatchPatternBase): + num_lines: int + num_vertices: int + def __init__(self, hatch: str, density: int) -> None: ... + def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ... + +class Shapes(HatchPatternBase): + filled: bool + num_shapes: int + num_vertices: int + def __init__(self, hatch: str, density: int) -> None: ... + def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ... + +class Circles(Shapes): + shape_vertices: np.ndarray + shape_codes: np.ndarray + def __init__(self, hatch: str, density: int) -> None: ... + +class SmallCircles(Circles): + size: float + num_rows: int + def __init__(self, hatch: str, density: int) -> None: ... + +class LargeCircles(Circles): + size: float + num_rows: int + def __init__(self, hatch: str, density: int) -> None: ... + +class SmallFilledCircles(Circles): + size: float + filled: bool + num_rows: int + def __init__(self, hatch: str, density: int) -> None: ... + +class Stars(Shapes): + size: float + filled: bool + num_rows: int + shape_vertices: np.ndarray + shape_codes: np.ndarray + def __init__(self, hatch: str, density: int) -> None: ... + +def get_path(hatchpattern: str, density: int = ...) -> Path: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/image.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/image.py new file mode 100644 index 00000000..757f0ba3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/image.py @@ -0,0 +1,1785 @@ +""" +The image module supports basic image loading, rescaling and display +operations. +""" + +import math +import os +import logging +from pathlib import Path +import warnings + +import numpy as np +import PIL.Image +import PIL.PngImagePlugin + +import matplotlib as mpl +from matplotlib import _api, cbook, cm +# For clarity, names from _image are given explicitly in this module +from matplotlib import _image +# For user convenience, the names from _image are also imported into +# the image namespace +from matplotlib._image import * +import matplotlib.artist as martist +from matplotlib.backend_bases import FigureCanvasBase +import matplotlib.colors as mcolors +from matplotlib.transforms import ( + Affine2D, BboxBase, Bbox, BboxTransform, BboxTransformTo, + IdentityTransform, TransformedBbox) + +_log = logging.getLogger(__name__) + +# map interpolation strings to module constants +_interpd_ = { + 'antialiased': _image.NEAREST, # this will use nearest or Hanning... + 'none': _image.NEAREST, # fall back to nearest when not supported + 'nearest': _image.NEAREST, + 'bilinear': _image.BILINEAR, + 'bicubic': _image.BICUBIC, + 'spline16': _image.SPLINE16, + 'spline36': _image.SPLINE36, + 'hanning': _image.HANNING, + 'hamming': _image.HAMMING, + 'hermite': _image.HERMITE, + 'kaiser': _image.KAISER, + 'quadric': _image.QUADRIC, + 'catrom': _image.CATROM, + 'gaussian': _image.GAUSSIAN, + 'bessel': _image.BESSEL, + 'mitchell': _image.MITCHELL, + 'sinc': _image.SINC, + 'lanczos': _image.LANCZOS, + 'blackman': _image.BLACKMAN, +} + +interpolations_names = set(_interpd_) + + +def composite_images(images, renderer, magnification=1.0): + """ + Composite a number of RGBA images into one. The images are + composited in the order in which they appear in the *images* list. + + Parameters + ---------- + images : list of Images + Each must have a `make_image` method. For each image, + `can_composite` should return `True`, though this is not + enforced by this function. Each image must have a purely + affine transformation with no shear. + + renderer : `.RendererBase` + + magnification : float, default: 1 + The additional magnification to apply for the renderer in use. + + Returns + ------- + image : (M, N, 4) `numpy.uint8` array + The composited RGBA image. + offset_x, offset_y : float + The (left, bottom) offset where the composited image should be placed + in the output figure. + """ + if len(images) == 0: + return np.empty((0, 0, 4), dtype=np.uint8), 0, 0 + + parts = [] + bboxes = [] + for image in images: + data, x, y, trans = image.make_image(renderer, magnification) + if data is not None: + x *= magnification + y *= magnification + parts.append((data, x, y, image._get_scalar_alpha())) + bboxes.append( + Bbox([[x, y], [x + data.shape[1], y + data.shape[0]]])) + + if len(parts) == 0: + return np.empty((0, 0, 4), dtype=np.uint8), 0, 0 + + bbox = Bbox.union(bboxes) + + output = np.zeros( + (int(bbox.height), int(bbox.width), 4), dtype=np.uint8) + + for data, x, y, alpha in parts: + trans = Affine2D().translate(x - bbox.x0, y - bbox.y0) + _image.resample(data, output, trans, _image.NEAREST, + resample=False, alpha=alpha) + + return output, bbox.x0 / magnification, bbox.y0 / magnification + + +def _draw_list_compositing_images( + renderer, parent, artists, suppress_composite=None): + """ + Draw a sorted list of artists, compositing images into a single + image where possible. + + For internal Matplotlib use only: It is here to reduce duplication + between `Figure.draw` and `Axes.draw`, but otherwise should not be + generally useful. + """ + has_images = any(isinstance(x, _ImageBase) for x in artists) + + # override the renderer default if suppressComposite is not None + not_composite = (suppress_composite if suppress_composite is not None + else renderer.option_image_nocomposite()) + + if not_composite or not has_images: + for a in artists: + a.draw(renderer) + else: + # Composite any adjacent images together + image_group = [] + mag = renderer.get_image_magnification() + + def flush_images(): + if len(image_group) == 1: + image_group[0].draw(renderer) + elif len(image_group) > 1: + data, l, b = composite_images(image_group, renderer, mag) + if data.size != 0: + gc = renderer.new_gc() + gc.set_clip_rectangle(parent.bbox) + gc.set_clip_path(parent.get_clip_path()) + renderer.draw_image(gc, round(l), round(b), data) + gc.restore() + del image_group[:] + + for a in artists: + if (isinstance(a, _ImageBase) and a.can_composite() and + a.get_clip_on() and not a.get_clip_path()): + image_group.append(a) + else: + flush_images() + a.draw(renderer) + flush_images() + + +def _resample( + image_obj, data, out_shape, transform, *, resample=None, alpha=1): + """ + Convenience wrapper around `._image.resample` to resample *data* to + *out_shape* (with a third dimension if *data* is RGBA) that takes care of + allocating the output array and fetching the relevant properties from the + Image object *image_obj*. + """ + # AGG can only handle coordinates smaller than 24-bit signed integers, + # so raise errors if the input data is larger than _image.resample can + # handle. + msg = ('Data with more than {n} cannot be accurately displayed. ' + 'Downsampling to less than {n} before displaying. ' + 'To remove this warning, manually downsample your data.') + if data.shape[1] > 2**23: + warnings.warn(msg.format(n='2**23 columns')) + step = int(np.ceil(data.shape[1] / 2**23)) + data = data[:, ::step] + transform = Affine2D().scale(step, 1) + transform + if data.shape[0] > 2**24: + warnings.warn(msg.format(n='2**24 rows')) + step = int(np.ceil(data.shape[0] / 2**24)) + data = data[::step, :] + transform = Affine2D().scale(1, step) + transform + # decide if we need to apply anti-aliasing if the data is upsampled: + # compare the number of displayed pixels to the number of + # the data pixels. + interpolation = image_obj.get_interpolation() + if interpolation == 'antialiased': + # don't antialias if upsampling by an integer number or + # if zooming in more than a factor of 3 + pos = np.array([[0, 0], [data.shape[1], data.shape[0]]]) + disp = transform.transform(pos) + dispx = np.abs(np.diff(disp[:, 0])) + dispy = np.abs(np.diff(disp[:, 1])) + if ((dispx > 3 * data.shape[1] or + dispx == data.shape[1] or + dispx == 2 * data.shape[1]) and + (dispy > 3 * data.shape[0] or + dispy == data.shape[0] or + dispy == 2 * data.shape[0])): + interpolation = 'nearest' + else: + interpolation = 'hanning' + out = np.zeros(out_shape + data.shape[2:], data.dtype) # 2D->2D, 3D->3D. + if resample is None: + resample = image_obj.get_resample() + _image.resample(data, out, transform, + _interpd_[interpolation], + resample, + alpha, + image_obj.get_filternorm(), + image_obj.get_filterrad()) + return out + + +def _rgb_to_rgba(A): + """ + Convert an RGB image to RGBA, as required by the image resample C++ + extension. + """ + rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype) + rgba[:, :, :3] = A + if rgba.dtype == np.uint8: + rgba[:, :, 3] = 255 + else: + rgba[:, :, 3] = 1.0 + return rgba + + +class _ImageBase(martist.Artist, cm.ScalarMappable): + """ + Base class for images. + + interpolation and cmap default to their rc settings + + cmap is a colors.Colormap instance + norm is a colors.Normalize instance to map luminance to 0-1 + + extent is data axes (left, right, bottom, top) for making image plots + registered with data plots. Default is to label the pixel + centers with the zero-based row and column indices. + + Additional kwargs are matplotlib.artist properties + """ + zorder = 0 + + def __init__(self, ax, + cmap=None, + norm=None, + interpolation=None, + origin=None, + filternorm=True, + filterrad=4.0, + resample=False, + *, + interpolation_stage=None, + **kwargs + ): + martist.Artist.__init__(self) + cm.ScalarMappable.__init__(self, norm, cmap) + if origin is None: + origin = mpl.rcParams['image.origin'] + _api.check_in_list(["upper", "lower"], origin=origin) + self.origin = origin + self.set_filternorm(filternorm) + self.set_filterrad(filterrad) + self.set_interpolation(interpolation) + self.set_interpolation_stage(interpolation_stage) + self.set_resample(resample) + self.axes = ax + + self._imcache = None + + self._internal_update(kwargs) + + def __str__(self): + try: + shape = self.get_shape() + return f"{type(self).__name__}(shape={shape!r})" + except RuntimeError: + return type(self).__name__ + + def __getstate__(self): + # Save some space on the pickle by not saving the cache. + return {**super().__getstate__(), "_imcache": None} + + def get_size(self): + """Return the size of the image as tuple (numrows, numcols).""" + return self.get_shape()[:2] + + def get_shape(self): + """ + Return the shape of the image as tuple (numrows, numcols, channels). + """ + if self._A is None: + raise RuntimeError('You must first set the image array') + + return self._A.shape + + def set_alpha(self, alpha): + """ + Set the alpha value used for blending - not supported on all backends. + + Parameters + ---------- + alpha : float or 2D array-like or None + """ + martist.Artist._set_alpha_for_array(self, alpha) + if np.ndim(alpha) not in (0, 2): + raise TypeError('alpha must be a float, two-dimensional ' + 'array, or None') + self._imcache = None + + def _get_scalar_alpha(self): + """ + Get a scalar alpha value to be applied to the artist as a whole. + + If the alpha value is a matrix, the method returns 1.0 because pixels + have individual alpha values (see `~._ImageBase._make_image` for + details). If the alpha value is a scalar, the method returns said value + to be applied to the artist as a whole because pixels do not have + individual alpha values. + """ + return 1.0 if self._alpha is None or np.ndim(self._alpha) > 0 \ + else self._alpha + + def changed(self): + """ + Call this whenever the mappable is changed so observers can update. + """ + self._imcache = None + cm.ScalarMappable.changed(self) + + def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, + unsampled=False, round_to_pixel_border=True): + """ + Normalize, rescale, and colormap the image *A* from the given *in_bbox* + (in data space), to the given *out_bbox* (in pixel space) clipped to + the given *clip_bbox* (also in pixel space), and magnified by the + *magnification* factor. + + *A* may be a greyscale image (M, N) with a dtype of `~numpy.float32`, + `~numpy.float64`, `~numpy.float128`, `~numpy.uint16` or `~numpy.uint8`, + or an (M, N, 4) RGBA image with a dtype of `~numpy.float32`, + `~numpy.float64`, `~numpy.float128`, or `~numpy.uint8`. + + If *unsampled* is True, the image will not be scaled, but an + appropriate affine transformation will be returned instead. + + If *round_to_pixel_border* is True, the output image size will be + rounded to the nearest pixel boundary. This makes the images align + correctly with the axes. It should not be used if exact scaling is + needed, such as for `FigureImage`. + + Returns + ------- + image : (M, N, 4) `numpy.uint8` array + The RGBA image, resampled unless *unsampled* is True. + x, y : float + The upper left corner where the image should be drawn, in pixel + space. + trans : `~matplotlib.transforms.Affine2D` + The affine transformation from image to pixel space. + """ + if A is None: + raise RuntimeError('You must first set the image ' + 'array or the image attribute') + if A.size == 0: + raise RuntimeError("_make_image must get a non-empty image. " + "Your Artist's draw method must filter before " + "this method is called.") + + clipped_bbox = Bbox.intersection(out_bbox, clip_bbox) + + if clipped_bbox is None: + return None, 0, 0, None + + out_width_base = clipped_bbox.width * magnification + out_height_base = clipped_bbox.height * magnification + + if out_width_base == 0 or out_height_base == 0: + return None, 0, 0, None + + if self.origin == 'upper': + # Flip the input image using a transform. This avoids the + # problem with flipping the array, which results in a copy + # when it is converted to contiguous in the C wrapper + t0 = Affine2D().translate(0, -A.shape[0]).scale(1, -1) + else: + t0 = IdentityTransform() + + t0 += ( + Affine2D() + .scale( + in_bbox.width / A.shape[1], + in_bbox.height / A.shape[0]) + .translate(in_bbox.x0, in_bbox.y0) + + self.get_transform()) + + t = (t0 + + (Affine2D() + .translate(-clipped_bbox.x0, -clipped_bbox.y0) + .scale(magnification))) + + # So that the image is aligned with the edge of the axes, we want to + # round up the output width to the next integer. This also means + # scaling the transform slightly to account for the extra subpixel. + if ((not unsampled) and t.is_affine and round_to_pixel_border and + (out_width_base % 1.0 != 0.0 or out_height_base % 1.0 != 0.0)): + out_width = math.ceil(out_width_base) + out_height = math.ceil(out_height_base) + extra_width = (out_width - out_width_base) / out_width_base + extra_height = (out_height - out_height_base) / out_height_base + t += Affine2D().scale(1.0 + extra_width, 1.0 + extra_height) + else: + out_width = int(out_width_base) + out_height = int(out_height_base) + out_shape = (out_height, out_width) + + if not unsampled: + if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in (3, 4)): + raise ValueError(f"Invalid shape {A.shape} for image data") + if A.ndim == 2 and self._interpolation_stage != 'rgba': + # if we are a 2D array, then we are running through the + # norm + colormap transformation. However, in general the + # input data is not going to match the size on the screen so we + # have to resample to the correct number of pixels + + # TODO slice input array first + a_min = A.min() + a_max = A.max() + if a_min is np.ma.masked: # All masked; values don't matter. + a_min, a_max = np.int32(0), np.int32(1) + if A.dtype.kind == 'f': # Float dtype: scale to same dtype. + scaled_dtype = np.dtype( + np.float64 if A.dtype.itemsize > 4 else np.float32) + if scaled_dtype.itemsize < A.dtype.itemsize: + _api.warn_external(f"Casting input data from {A.dtype}" + f" to {scaled_dtype} for imshow.") + else: # Int dtype, likely. + # Scale to appropriately sized float: use float32 if the + # dynamic range is small, to limit the memory footprint. + da = a_max.astype(np.float64) - a_min.astype(np.float64) + scaled_dtype = np.float64 if da > 1e8 else np.float32 + + # Scale the input data to [.1, .9]. The Agg interpolators clip + # to [0, 1] internally, and we use a smaller input scale to + # identify the interpolated points that need to be flagged as + # over/under. This may introduce numeric instabilities in very + # broadly scaled data. + + # Always copy, and don't allow array subtypes. + A_scaled = np.array(A, dtype=scaled_dtype) + # Clip scaled data around norm if necessary. This is necessary + # for big numbers at the edge of float64's ability to represent + # changes. Applying a norm first would be good, but ruins the + # interpolation of over numbers. + self.norm.autoscale_None(A) + dv = np.float64(self.norm.vmax) - np.float64(self.norm.vmin) + vmid = np.float64(self.norm.vmin) + dv / 2 + fact = 1e7 if scaled_dtype == np.float64 else 1e4 + newmin = vmid - dv * fact + if newmin < a_min: + newmin = None + else: + a_min = np.float64(newmin) + newmax = vmid + dv * fact + if newmax > a_max: + newmax = None + else: + a_max = np.float64(newmax) + if newmax is not None or newmin is not None: + np.clip(A_scaled, newmin, newmax, out=A_scaled) + + # Rescale the raw data to [offset, 1-offset] so that the + # resampling code will run cleanly. Using dyadic numbers here + # could reduce the error, but would not fully eliminate it and + # breaks a number of tests (due to the slightly different + # error bouncing some pixels across a boundary in the (very + # quantized) colormapping step). + offset = .1 + frac = .8 + # Run vmin/vmax through the same rescaling as the raw data; + # otherwise, data values close or equal to the boundaries can + # end up on the wrong side due to floating point error. + vmin, vmax = self.norm.vmin, self.norm.vmax + if vmin is np.ma.masked: + vmin, vmax = a_min, a_max + vrange = np.array([vmin, vmax], dtype=scaled_dtype) + + A_scaled -= a_min + vrange -= a_min + # .item() handles a_min/a_max being ndarray subclasses. + a_min = a_min.astype(scaled_dtype).item() + a_max = a_max.astype(scaled_dtype).item() + + if a_min != a_max: + A_scaled /= ((a_max - a_min) / frac) + vrange /= ((a_max - a_min) / frac) + A_scaled += offset + vrange += offset + # resample the input data to the correct resolution and shape + A_resampled = _resample(self, A_scaled, out_shape, t) + del A_scaled # Make sure we don't use A_scaled anymore! + # Un-scale the resampled data to approximately the original + # range. Things that interpolated to outside the original range + # will still be outside, but possibly clipped in the case of + # higher order interpolation + drastically changing data. + A_resampled -= offset + vrange -= offset + if a_min != a_max: + A_resampled *= ((a_max - a_min) / frac) + vrange *= ((a_max - a_min) / frac) + A_resampled += a_min + vrange += a_min + # if using NoNorm, cast back to the original datatype + if isinstance(self.norm, mcolors.NoNorm): + A_resampled = A_resampled.astype(A.dtype) + + mask = (np.where(A.mask, np.float32(np.nan), np.float32(1)) + if A.mask.shape == A.shape # nontrivial mask + else np.ones_like(A, np.float32)) + # we always have to interpolate the mask to account for + # non-affine transformations + out_alpha = _resample(self, mask, out_shape, t, resample=True) + del mask # Make sure we don't use mask anymore! + # Agg updates out_alpha in place. If the pixel has no image + # data it will not be updated (and still be 0 as we initialized + # it), if input data that would go into that output pixel than + # it will be `nan`, if all the input data for a pixel is good + # it will be 1, and if there is _some_ good data in that output + # pixel it will be between [0, 1] (such as a rotated image). + out_mask = np.isnan(out_alpha) + out_alpha[out_mask] = 1 + # Apply the pixel-by-pixel alpha values if present + alpha = self.get_alpha() + if alpha is not None and np.ndim(alpha) > 0: + out_alpha *= _resample(self, alpha, out_shape, + t, resample=True) + # mask and run through the norm + resampled_masked = np.ma.masked_array(A_resampled, out_mask) + # we have re-set the vmin/vmax to account for small errors + # that may have moved input values in/out of range + s_vmin, s_vmax = vrange + if isinstance(self.norm, mcolors.LogNorm) and s_vmin <= 0: + # Don't give 0 or negative values to LogNorm + s_vmin = np.finfo(scaled_dtype).eps + # Block the norm from sending an update signal during the + # temporary vmin/vmax change + with self.norm.callbacks.blocked(), \ + cbook._setattr_cm(self.norm, vmin=s_vmin, vmax=s_vmax): + output = self.norm(resampled_masked) + else: + if A.ndim == 2: # _interpolation_stage == 'rgba' + self.norm.autoscale_None(A) + A = self.to_rgba(A) + if A.shape[2] == 3: + A = _rgb_to_rgba(A) + alpha = self._get_scalar_alpha() + output_alpha = _resample( # resample alpha channel + self, A[..., 3], out_shape, t, alpha=alpha) + output = _resample( # resample rgb channels + self, _rgb_to_rgba(A[..., :3]), out_shape, t, alpha=alpha) + output[..., 3] = output_alpha # recombine rgb and alpha + + # output is now either a 2D array of normed (int or float) data + # or an RGBA array of re-sampled input + output = self.to_rgba(output, bytes=True, norm=False) + # output is now a correctly sized RGBA array of uint8 + + # Apply alpha *after* if the input was greyscale without a mask + if A.ndim == 2: + alpha = self._get_scalar_alpha() + alpha_channel = output[:, :, 3] + alpha_channel[:] = ( # Assignment will cast to uint8. + alpha_channel.astype(np.float32) * out_alpha * alpha) + + else: + if self._imcache is None: + self._imcache = self.to_rgba(A, bytes=True, norm=(A.ndim == 2)) + output = self._imcache + + # Subset the input image to only the part that will be displayed. + subset = TransformedBbox(clip_bbox, t0.inverted()).frozen() + output = output[ + int(max(subset.ymin, 0)): + int(min(subset.ymax + 1, output.shape[0])), + int(max(subset.xmin, 0)): + int(min(subset.xmax + 1, output.shape[1]))] + + t = Affine2D().translate( + int(max(subset.xmin, 0)), int(max(subset.ymin, 0))) + t + + return output, clipped_bbox.x0, clipped_bbox.y0, t + + def make_image(self, renderer, magnification=1.0, unsampled=False): + """ + Normalize, rescale, and colormap this image's data for rendering using + *renderer*, with the given *magnification*. + + If *unsampled* is True, the image will not be scaled, but an + appropriate affine transformation will be returned instead. + + Returns + ------- + image : (M, N, 4) `numpy.uint8` array + The RGBA image, resampled unless *unsampled* is True. + x, y : float + The upper left corner where the image should be drawn, in pixel + space. + trans : `~matplotlib.transforms.Affine2D` + The affine transformation from image to pixel space. + """ + raise NotImplementedError('The make_image method must be overridden') + + def _check_unsampled_image(self): + """ + Return whether the image is better to be drawn unsampled. + + The derived class needs to override it. + """ + return False + + @martist.allow_rasterization + def draw(self, renderer, *args, **kwargs): + # if not visible, declare victory and return + if not self.get_visible(): + self.stale = False + return + # for empty images, there is nothing to draw! + if self.get_array().size == 0: + self.stale = False + return + # actually render the image. + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_alpha(self._get_scalar_alpha()) + gc.set_url(self.get_url()) + gc.set_gid(self.get_gid()) + if (renderer.option_scale_image() # Renderer supports transform kwarg. + and self._check_unsampled_image() + and self.get_transform().is_affine): + im, l, b, trans = self.make_image(renderer, unsampled=True) + if im is not None: + trans = Affine2D().scale(im.shape[1], im.shape[0]) + trans + renderer.draw_image(gc, l, b, im, trans) + else: + im, l, b, trans = self.make_image( + renderer, renderer.get_image_magnification()) + if im is not None: + renderer.draw_image(gc, l, b, im) + gc.restore() + self.stale = False + + def contains(self, mouseevent): + """Test whether the mouse event occurred within the image.""" + if (self._different_canvas(mouseevent) + # This doesn't work for figimage. + or not self.axes.contains(mouseevent)[0]): + return False, {} + # TODO: make sure this is consistent with patch and patch + # collection on nonlinear transformed coordinates. + # TODO: consider returning image coordinates (shouldn't + # be too difficult given that the image is rectilinear + trans = self.get_transform().inverted() + x, y = trans.transform([mouseevent.x, mouseevent.y]) + xmin, xmax, ymin, ymax = self.get_extent() + # This checks xmin <= x <= xmax *or* xmax <= x <= xmin. + inside = (x is not None and (x - xmin) * (x - xmax) <= 0 + and y is not None and (y - ymin) * (y - ymax) <= 0) + return inside, {} + + def write_png(self, fname): + """Write the image to png file *fname*.""" + im = self.to_rgba(self._A[::-1] if self.origin == 'lower' else self._A, + bytes=True, norm=True) + PIL.Image.fromarray(im).save(fname, format="png") + + @staticmethod + def _normalize_image_array(A): + """ + Check validity of image-like input *A* and normalize it to a format suitable for + Image subclasses. + """ + A = cbook.safe_masked_invalid(A, copy=True) + if A.dtype != np.uint8 and not np.can_cast(A.dtype, float, "same_kind"): + raise TypeError(f"Image data of dtype {A.dtype} cannot be " + f"converted to float") + if A.ndim == 3 and A.shape[-1] == 1: + A = A.squeeze(-1) # If just (M, N, 1), assume scalar and apply colormap. + if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in [3, 4]): + raise TypeError(f"Invalid shape {A.shape} for image data") + if A.ndim == 3: + # If the input data has values outside the valid range (after + # normalisation), we issue a warning and then clip X to the bounds + # - otherwise casting wraps extreme values, hiding outliers and + # making reliable interpretation impossible. + high = 255 if np.issubdtype(A.dtype, np.integer) else 1 + if A.min() < 0 or high < A.max(): + _log.warning( + 'Clipping input data to the valid range for imshow with ' + 'RGB data ([0..1] for floats or [0..255] for integers).' + ) + A = np.clip(A, 0, high) + # Cast unsupported integer types to uint8 + if A.dtype != np.uint8 and np.issubdtype(A.dtype, np.integer): + A = A.astype(np.uint8) + return A + + def set_data(self, A): + """ + Set the image array. + + Note that this function does *not* update the normalization used. + + Parameters + ---------- + A : array-like or `PIL.Image.Image` + """ + if isinstance(A, PIL.Image.Image): + A = pil_to_array(A) # Needed e.g. to apply png palette. + self._A = self._normalize_image_array(A) + self._imcache = None + self.stale = True + + def set_array(self, A): + """ + Retained for backwards compatibility - use set_data instead. + + Parameters + ---------- + A : array-like + """ + # This also needs to be here to override the inherited + # cm.ScalarMappable.set_array method so it is not invoked by mistake. + self.set_data(A) + + def get_interpolation(self): + """ + Return the interpolation method the image uses when resizing. + + One of 'antialiased', 'nearest', 'bilinear', 'bicubic', 'spline16', + 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', + 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos', + or 'none'. + """ + return self._interpolation + + def set_interpolation(self, s): + """ + Set the interpolation method the image uses when resizing. + + If None, use :rc:`image.interpolation`. If 'none', the image is + shown as is without interpolating. 'none' is only supported in + agg, ps and pdf backends and will fall back to 'nearest' mode + for other backends. + + Parameters + ---------- + s : {'antialiased', 'nearest', 'bilinear', 'bicubic', 'spline16', \ +'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', \ +'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos', 'none'} or None + """ + s = mpl._val_or_rc(s, 'image.interpolation').lower() + _api.check_in_list(interpolations_names, interpolation=s) + self._interpolation = s + self.stale = True + + def set_interpolation_stage(self, s): + """ + Set when interpolation happens during the transform to RGBA. + + Parameters + ---------- + s : {'data', 'rgba'} or None + Whether to apply up/downsampling interpolation in data or RGBA + space. + """ + if s is None: + s = "data" # placeholder for maybe having rcParam + _api.check_in_list(['data', 'rgba'], s=s) + self._interpolation_stage = s + self.stale = True + + def can_composite(self): + """Return whether the image can be composited with its neighbors.""" + trans = self.get_transform() + return ( + self._interpolation != 'none' and + trans.is_affine and + trans.is_separable) + + def set_resample(self, v): + """ + Set whether image resampling is used. + + Parameters + ---------- + v : bool or None + If None, use :rc:`image.resample`. + """ + v = mpl._val_or_rc(v, 'image.resample') + self._resample = v + self.stale = True + + def get_resample(self): + """Return whether image resampling is used.""" + return self._resample + + def set_filternorm(self, filternorm): + """ + Set whether the resize filter normalizes the weights. + + See help for `~.Axes.imshow`. + + Parameters + ---------- + filternorm : bool + """ + self._filternorm = bool(filternorm) + self.stale = True + + def get_filternorm(self): + """Return whether the resize filter normalizes the weights.""" + return self._filternorm + + def set_filterrad(self, filterrad): + """ + Set the resize filter radius only applicable to some + interpolation schemes -- see help for imshow + + Parameters + ---------- + filterrad : positive float + """ + r = float(filterrad) + if r <= 0: + raise ValueError("The filter radius must be a positive number") + self._filterrad = r + self.stale = True + + def get_filterrad(self): + """Return the filterrad setting.""" + return self._filterrad + + +class AxesImage(_ImageBase): + """ + An image attached to an Axes. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The axes the image will belong to. + cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` + The Colormap instance or registered colormap name used to map scalar + data to colors. + norm : str or `~matplotlib.colors.Normalize` + Maps luminance to 0-1. + interpolation : str, default: :rc:`image.interpolation` + Supported values are 'none', 'antialiased', 'nearest', 'bilinear', + 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', + 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', + 'sinc', 'lanczos', 'blackman'. + interpolation_stage : {'data', 'rgba'}, default: 'data' + If 'data', interpolation + is carried out on the data provided by the user. If 'rgba', the + interpolation is carried out after the colormapping has been + applied (visual interpolation). + origin : {'upper', 'lower'}, default: :rc:`image.origin` + Place the [0, 0] index of the array in the upper left or lower left + corner of the axes. The convention 'upper' is typically used for + matrices and images. + extent : tuple, optional + The data axes (left, right, bottom, top) for making image plots + registered with data plots. Default is to label the pixel + centers with the zero-based row and column indices. + filternorm : bool, default: True + A parameter for the antigrain image resize filter + (see the antigrain documentation). + If filternorm is set, the filter normalizes integer values and corrects + the rounding errors. It doesn't do anything with the source floating + point values, it corrects only integers according to the rule of 1.0 + which means that any sum of pixel weights must be equal to 1.0. So, + the filter function must produce a graph of the proper shape. + filterrad : float > 0, default: 4 + The filter radius for filters that have a radius parameter, i.e. when + interpolation is one of: 'sinc', 'lanczos' or 'blackman'. + resample : bool, default: False + When True, use a full resampling method. When False, only resample when + the output image is larger than the input image. + **kwargs : `~matplotlib.artist.Artist` properties + """ + + def __init__(self, ax, + *, + cmap=None, + norm=None, + interpolation=None, + origin=None, + extent=None, + filternorm=True, + filterrad=4.0, + resample=False, + interpolation_stage=None, + **kwargs + ): + + self._extent = extent + + super().__init__( + ax, + cmap=cmap, + norm=norm, + interpolation=interpolation, + origin=origin, + filternorm=filternorm, + filterrad=filterrad, + resample=resample, + interpolation_stage=interpolation_stage, + **kwargs + ) + + def get_window_extent(self, renderer=None): + x0, x1, y0, y1 = self._extent + bbox = Bbox.from_extents([x0, y0, x1, y1]) + return bbox.transformed(self.get_transform()) + + def make_image(self, renderer, magnification=1.0, unsampled=False): + # docstring inherited + trans = self.get_transform() + # image is created in the canvas coordinate. + x1, x2, y1, y2 = self.get_extent() + bbox = Bbox(np.array([[x1, y1], [x2, y2]])) + transformed_bbox = TransformedBbox(bbox, trans) + clip = ((self.get_clip_box() or self.axes.bbox) if self.get_clip_on() + else self.figure.bbox) + return self._make_image(self._A, bbox, transformed_bbox, clip, + magnification, unsampled=unsampled) + + def _check_unsampled_image(self): + """Return whether the image would be better drawn unsampled.""" + return self.get_interpolation() == "none" + + def set_extent(self, extent, **kwargs): + """ + Set the image extent. + + Parameters + ---------- + extent : 4-tuple of float + The position and size of the image as tuple + ``(left, right, bottom, top)`` in data coordinates. + **kwargs + Other parameters from which unit info (i.e., the *xunits*, + *yunits*, *zunits* (for 3D axes), *runits* and *thetaunits* (for + polar axes) entries are applied, if present. + + Notes + ----- + This updates ``ax.dataLim``, and, if autoscaling, sets ``ax.viewLim`` + to tightly fit the image, regardless of ``dataLim``. Autoscaling + state is not changed, so following this with ``ax.autoscale_view()`` + will redo the autoscaling in accord with ``dataLim``. + """ + (xmin, xmax), (ymin, ymax) = self.axes._process_unit_info( + [("x", [extent[0], extent[1]]), + ("y", [extent[2], extent[3]])], + kwargs) + if kwargs: + raise _api.kwarg_error("set_extent", kwargs) + xmin = self.axes._validate_converted_limits( + xmin, self.convert_xunits) + xmax = self.axes._validate_converted_limits( + xmax, self.convert_xunits) + ymin = self.axes._validate_converted_limits( + ymin, self.convert_yunits) + ymax = self.axes._validate_converted_limits( + ymax, self.convert_yunits) + extent = [xmin, xmax, ymin, ymax] + + self._extent = extent + corners = (xmin, ymin), (xmax, ymax) + self.axes.update_datalim(corners) + self.sticky_edges.x[:] = [xmin, xmax] + self.sticky_edges.y[:] = [ymin, ymax] + if self.axes.get_autoscalex_on(): + self.axes.set_xlim((xmin, xmax), auto=None) + if self.axes.get_autoscaley_on(): + self.axes.set_ylim((ymin, ymax), auto=None) + self.stale = True + + def get_extent(self): + """Return the image extent as tuple (left, right, bottom, top).""" + if self._extent is not None: + return self._extent + else: + sz = self.get_size() + numrows, numcols = sz + if self.origin == 'upper': + return (-0.5, numcols-0.5, numrows-0.5, -0.5) + else: + return (-0.5, numcols-0.5, -0.5, numrows-0.5) + + def get_cursor_data(self, event): + """ + Return the image value at the event position or *None* if the event is + outside the image. + + See Also + -------- + matplotlib.artist.Artist.get_cursor_data + """ + xmin, xmax, ymin, ymax = self.get_extent() + if self.origin == 'upper': + ymin, ymax = ymax, ymin + arr = self.get_array() + data_extent = Bbox([[xmin, ymin], [xmax, ymax]]) + array_extent = Bbox([[0, 0], [arr.shape[1], arr.shape[0]]]) + trans = self.get_transform().inverted() + trans += BboxTransform(boxin=data_extent, boxout=array_extent) + point = trans.transform([event.x, event.y]) + if any(np.isnan(point)): + return None + j, i = point.astype(int) + # Clip the coordinates at array bounds + if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): + return None + else: + return arr[i, j] + + +class NonUniformImage(AxesImage): + mouseover = False # This class still needs its own get_cursor_data impl. + + def __init__(self, ax, *, interpolation='nearest', **kwargs): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The axes the image will belong to. + interpolation : {'nearest', 'bilinear'}, default: 'nearest' + The interpolation scheme used in the resampling. + **kwargs + All other keyword arguments are identical to those of `.AxesImage`. + """ + super().__init__(ax, **kwargs) + self.set_interpolation(interpolation) + + def _check_unsampled_image(self): + """Return False. Do not use unsampled image.""" + return False + + def make_image(self, renderer, magnification=1.0, unsampled=False): + # docstring inherited + if self._A is None: + raise RuntimeError('You must first set the image array') + if unsampled: + raise ValueError('unsampled not supported on NonUniformImage') + A = self._A + if A.ndim == 2: + if A.dtype != np.uint8: + A = self.to_rgba(A, bytes=True) + else: + A = np.repeat(A[:, :, np.newaxis], 4, 2) + A[:, :, 3] = 255 + else: + if A.dtype != np.uint8: + A = (255*A).astype(np.uint8) + if A.shape[2] == 3: + B = np.zeros(tuple([*A.shape[0:2], 4]), np.uint8) + B[:, :, 0:3] = A + B[:, :, 3] = 255 + A = B + vl = self.axes.viewLim + l, b, r, t = self.axes.bbox.extents + width = int(((round(r) + 0.5) - (round(l) - 0.5)) * magnification) + height = int(((round(t) + 0.5) - (round(b) - 0.5)) * magnification) + x_pix = np.linspace(vl.x0, vl.x1, width) + y_pix = np.linspace(vl.y0, vl.y1, height) + if self._interpolation == "nearest": + x_mid = (self._Ax[:-1] + self._Ax[1:]) / 2 + y_mid = (self._Ay[:-1] + self._Ay[1:]) / 2 + x_int = x_mid.searchsorted(x_pix) + y_int = y_mid.searchsorted(y_pix) + # The following is equal to `A[y_int[:, None], x_int[None, :]]`, + # but many times faster. Both casting to uint32 (to have an + # effectively 1D array) and manual index flattening matter. + im = ( + np.ascontiguousarray(A).view(np.uint32).ravel()[ + np.add.outer(y_int * A.shape[1], x_int)] + .view(np.uint8).reshape((height, width, 4))) + else: # self._interpolation == "bilinear" + # Use np.interp to compute x_int/x_float has similar speed. + x_int = np.clip( + self._Ax.searchsorted(x_pix) - 1, 0, len(self._Ax) - 2) + y_int = np.clip( + self._Ay.searchsorted(y_pix) - 1, 0, len(self._Ay) - 2) + idx_int = np.add.outer(y_int * A.shape[1], x_int) + x_frac = np.clip( + np.divide(x_pix - self._Ax[x_int], np.diff(self._Ax)[x_int], + dtype=np.float32), # Downcasting helps with speed. + 0, 1) + y_frac = np.clip( + np.divide(y_pix - self._Ay[y_int], np.diff(self._Ay)[y_int], + dtype=np.float32), + 0, 1) + f00 = np.outer(1 - y_frac, 1 - x_frac) + f10 = np.outer(y_frac, 1 - x_frac) + f01 = np.outer(1 - y_frac, x_frac) + f11 = np.outer(y_frac, x_frac) + im = np.empty((height, width, 4), np.uint8) + for chan in range(4): + ac = A[:, :, chan].reshape(-1) # reshape(-1) avoids a copy. + # Shifting the buffer start (`ac[offset:]`) avoids an array + # addition (`ac[idx_int + offset]`). + buf = f00 * ac[idx_int] + buf += f10 * ac[A.shape[1]:][idx_int] + buf += f01 * ac[1:][idx_int] + buf += f11 * ac[A.shape[1] + 1:][idx_int] + im[:, :, chan] = buf # Implicitly casts to uint8. + return im, l, b, IdentityTransform() + + def set_data(self, x, y, A): + """ + Set the grid for the pixel centers, and the pixel values. + + Parameters + ---------- + x, y : 1D array-like + Monotonic arrays of shapes (N,) and (M,), respectively, specifying + pixel centers. + A : array-like + (M, N) `~numpy.ndarray` or masked array of values to be + colormapped, or (M, N, 3) RGB array, or (M, N, 4) RGBA array. + """ + A = self._normalize_image_array(A) + x = np.array(x, np.float32) + y = np.array(y, np.float32) + if not (x.ndim == y.ndim == 1 and A.shape[:2] == y.shape + x.shape): + raise TypeError("Axes don't match array shape") + self._A = A + self._Ax = x + self._Ay = y + self._imcache = None + self.stale = True + + def set_array(self, *args): + raise NotImplementedError('Method not supported') + + def set_interpolation(self, s): + """ + Parameters + ---------- + s : {'nearest', 'bilinear'} or None + If None, use :rc:`image.interpolation`. + """ + if s is not None and s not in ('nearest', 'bilinear'): + raise NotImplementedError('Only nearest neighbor and ' + 'bilinear interpolations are supported') + super().set_interpolation(s) + + def get_extent(self): + if self._A is None: + raise RuntimeError('Must set data first') + return self._Ax[0], self._Ax[-1], self._Ay[0], self._Ay[-1] + + @_api.rename_parameter("3.8", "s", "filternorm") + def set_filternorm(self, filternorm): + pass + + @_api.rename_parameter("3.8", "s", "filterrad") + def set_filterrad(self, filterrad): + pass + + def set_norm(self, norm): + if self._A is not None: + raise RuntimeError('Cannot change colors after loading data') + super().set_norm(norm) + + def set_cmap(self, cmap): + if self._A is not None: + raise RuntimeError('Cannot change colors after loading data') + super().set_cmap(cmap) + + +class PcolorImage(AxesImage): + """ + Make a pcolor-style plot with an irregular rectangular grid. + + This uses a variation of the original irregular image code, + and it is used by pcolorfast for the corresponding grid type. + """ + + def __init__(self, ax, + x=None, + y=None, + A=None, + *, + cmap=None, + norm=None, + **kwargs + ): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The axes the image will belong to. + x, y : 1D array-like, optional + Monotonic arrays of length N+1 and M+1, respectively, specifying + rectangle boundaries. If not given, will default to + ``range(N + 1)`` and ``range(M + 1)``, respectively. + A : array-like + The data to be color-coded. The interpretation depends on the + shape: + + - (M, N) `~numpy.ndarray` or masked array: values to be colormapped + - (M, N, 3): RGB array + - (M, N, 4): RGBA array + + cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` + The Colormap instance or registered colormap name used to map + scalar data to colors. + norm : str or `~matplotlib.colors.Normalize` + Maps luminance to 0-1. + **kwargs : `~matplotlib.artist.Artist` properties + """ + super().__init__(ax, norm=norm, cmap=cmap) + self._internal_update(kwargs) + if A is not None: + self.set_data(x, y, A) + + def make_image(self, renderer, magnification=1.0, unsampled=False): + # docstring inherited + if self._A is None: + raise RuntimeError('You must first set the image array') + if unsampled: + raise ValueError('unsampled not supported on PColorImage') + + if self._imcache is None: + A = self.to_rgba(self._A, bytes=True) + self._imcache = np.pad(A, [(1, 1), (1, 1), (0, 0)], "constant") + padded_A = self._imcache + bg = mcolors.to_rgba(self.axes.patch.get_facecolor(), 0) + bg = (np.array(bg) * 255).astype(np.uint8) + if (padded_A[0, 0] != bg).all(): + padded_A[[0, -1], :] = padded_A[:, [0, -1]] = bg + + l, b, r, t = self.axes.bbox.extents + width = (round(r) + 0.5) - (round(l) - 0.5) + height = (round(t) + 0.5) - (round(b) - 0.5) + width = round(width * magnification) + height = round(height * magnification) + vl = self.axes.viewLim + + x_pix = np.linspace(vl.x0, vl.x1, width) + y_pix = np.linspace(vl.y0, vl.y1, height) + x_int = self._Ax.searchsorted(x_pix) + y_int = self._Ay.searchsorted(y_pix) + im = ( # See comment in NonUniformImage.make_image re: performance. + padded_A.view(np.uint32).ravel()[ + np.add.outer(y_int * padded_A.shape[1], x_int)] + .view(np.uint8).reshape((height, width, 4))) + return im, l, b, IdentityTransform() + + def _check_unsampled_image(self): + return False + + def set_data(self, x, y, A): + """ + Set the grid for the rectangle boundaries, and the data values. + + Parameters + ---------- + x, y : 1D array-like, optional + Monotonic arrays of length N+1 and M+1, respectively, specifying + rectangle boundaries. If not given, will default to + ``range(N + 1)`` and ``range(M + 1)``, respectively. + A : array-like + The data to be color-coded. The interpretation depends on the + shape: + + - (M, N) `~numpy.ndarray` or masked array: values to be colormapped + - (M, N, 3): RGB array + - (M, N, 4): RGBA array + """ + A = self._normalize_image_array(A) + x = np.arange(0., A.shape[1] + 1) if x is None else np.array(x, float).ravel() + y = np.arange(0., A.shape[0] + 1) if y is None else np.array(y, float).ravel() + if A.shape[:2] != (y.size - 1, x.size - 1): + raise ValueError( + "Axes don't match array shape. Got %s, expected %s." % + (A.shape[:2], (y.size - 1, x.size - 1))) + # For efficient cursor readout, ensure x and y are increasing. + if x[-1] < x[0]: + x = x[::-1] + A = A[:, ::-1] + if y[-1] < y[0]: + y = y[::-1] + A = A[::-1] + self._A = A + self._Ax = x + self._Ay = y + self._imcache = None + self.stale = True + + def set_array(self, *args): + raise NotImplementedError('Method not supported') + + def get_cursor_data(self, event): + # docstring inherited + x, y = event.xdata, event.ydata + if (x < self._Ax[0] or x > self._Ax[-1] or + y < self._Ay[0] or y > self._Ay[-1]): + return None + j = np.searchsorted(self._Ax, x) - 1 + i = np.searchsorted(self._Ay, y) - 1 + try: + return self._A[i, j] + except IndexError: + return None + + +class FigureImage(_ImageBase): + """An image attached to a figure.""" + + zorder = 0 + + _interpolation = 'nearest' + + def __init__(self, fig, + *, + cmap=None, + norm=None, + offsetx=0, + offsety=0, + origin=None, + **kwargs + ): + """ + cmap is a colors.Colormap instance + norm is a colors.Normalize instance to map luminance to 0-1 + + kwargs are an optional list of Artist keyword args + """ + super().__init__( + None, + norm=norm, + cmap=cmap, + origin=origin + ) + self.figure = fig + self.ox = offsetx + self.oy = offsety + self._internal_update(kwargs) + self.magnification = 1.0 + + def get_extent(self): + """Return the image extent as tuple (left, right, bottom, top).""" + numrows, numcols = self.get_size() + return (-0.5 + self.ox, numcols-0.5 + self.ox, + -0.5 + self.oy, numrows-0.5 + self.oy) + + def make_image(self, renderer, magnification=1.0, unsampled=False): + # docstring inherited + fac = renderer.dpi/self.figure.dpi + # fac here is to account for pdf, eps, svg backends where + # figure.dpi is set to 72. This means we need to scale the + # image (using magnification) and offset it appropriately. + bbox = Bbox([[self.ox/fac, self.oy/fac], + [(self.ox/fac + self._A.shape[1]), + (self.oy/fac + self._A.shape[0])]]) + width, height = self.figure.get_size_inches() + width *= renderer.dpi + height *= renderer.dpi + clip = Bbox([[0, 0], [width, height]]) + return self._make_image( + self._A, bbox, bbox, clip, magnification=magnification / fac, + unsampled=unsampled, round_to_pixel_border=False) + + def set_data(self, A): + """Set the image array.""" + cm.ScalarMappable.set_array(self, A) + self.stale = True + + +class BboxImage(_ImageBase): + """The Image class whose size is determined by the given bbox.""" + + def __init__(self, bbox, + *, + cmap=None, + norm=None, + interpolation=None, + origin=None, + filternorm=True, + filterrad=4.0, + resample=False, + **kwargs + ): + """ + cmap is a colors.Colormap instance + norm is a colors.Normalize instance to map luminance to 0-1 + + kwargs are an optional list of Artist keyword args + """ + super().__init__( + None, + cmap=cmap, + norm=norm, + interpolation=interpolation, + origin=origin, + filternorm=filternorm, + filterrad=filterrad, + resample=resample, + **kwargs + ) + self.bbox = bbox + + def get_window_extent(self, renderer=None): + if renderer is None: + renderer = self.get_figure()._get_renderer() + + if isinstance(self.bbox, BboxBase): + return self.bbox + elif callable(self.bbox): + return self.bbox(renderer) + else: + raise ValueError("Unknown type of bbox") + + def contains(self, mouseevent): + """Test whether the mouse event occurred within the image.""" + if self._different_canvas(mouseevent) or not self.get_visible(): + return False, {} + x, y = mouseevent.x, mouseevent.y + inside = self.get_window_extent().contains(x, y) + return inside, {} + + def make_image(self, renderer, magnification=1.0, unsampled=False): + # docstring inherited + width, height = renderer.get_canvas_width_height() + bbox_in = self.get_window_extent(renderer).frozen() + bbox_in._points /= [width, height] + bbox_out = self.get_window_extent(renderer) + clip = Bbox([[0, 0], [width, height]]) + self._transform = BboxTransformTo(clip) + return self._make_image( + self._A, + bbox_in, bbox_out, clip, magnification, unsampled=unsampled) + + +def imread(fname, format=None): + """ + Read an image from a file into an array. + + .. note:: + + This function exists for historical reasons. It is recommended to + use `PIL.Image.open` instead for loading images. + + Parameters + ---------- + fname : str or file-like + The image file to read: a filename, a URL or a file-like object opened + in read-binary mode. + + Passing a URL is deprecated. Please open the URL + for reading and pass the result to Pillow, e.g. with + ``np.array(PIL.Image.open(urllib.request.urlopen(url)))``. + format : str, optional + The image file format assumed for reading the data. The image is + loaded as a PNG file if *format* is set to "png", if *fname* is a path + or opened file with a ".png" extension, or if it is a URL. In all + other cases, *format* is ignored and the format is auto-detected by + `PIL.Image.open`. + + Returns + ------- + `numpy.array` + The image data. The returned array has shape + + - (M, N) for grayscale images. + - (M, N, 3) for RGB images. + - (M, N, 4) for RGBA images. + + PNG images are returned as float arrays (0-1). All other formats are + returned as int arrays, with a bit depth determined by the file's + contents. + """ + # hide imports to speed initial import on systems with slow linkers + from urllib import parse + + if format is None: + if isinstance(fname, str): + parsed = parse.urlparse(fname) + # If the string is a URL (Windows paths appear as if they have a + # length-1 scheme), assume png. + if len(parsed.scheme) > 1: + ext = 'png' + else: + ext = Path(fname).suffix.lower()[1:] + elif hasattr(fname, 'geturl'): # Returned by urlopen(). + # We could try to parse the url's path and use the extension, but + # returning png is consistent with the block above. Note that this + # if clause has to come before checking for fname.name as + # urlopen("file:///...") also has a name attribute (with the fixed + # value ""). + ext = 'png' + elif hasattr(fname, 'name'): + ext = Path(fname.name).suffix.lower()[1:] + else: + ext = 'png' + else: + ext = format + img_open = ( + PIL.PngImagePlugin.PngImageFile if ext == 'png' else PIL.Image.open) + if isinstance(fname, str) and len(parse.urlparse(fname).scheme) > 1: + # Pillow doesn't handle URLs directly. + raise ValueError( + "Please open the URL for reading and pass the " + "result to Pillow, e.g. with " + "``np.array(PIL.Image.open(urllib.request.urlopen(url)))``." + ) + with img_open(fname) as image: + return (_pil_png_to_float_array(image) + if isinstance(image, PIL.PngImagePlugin.PngImageFile) else + pil_to_array(image)) + + +def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, + origin=None, dpi=100, *, metadata=None, pil_kwargs=None): + """ + Colormap and save an array as an image file. + + RGB(A) images are passed through. Single channel images will be + colormapped according to *cmap* and *norm*. + + .. note:: + + If you want to save a single channel image as gray scale please use an + image I/O library (such as pillow, tifffile, or imageio) directly. + + Parameters + ---------- + fname : str or path-like or file-like + A path or a file-like object to store the image in. + If *format* is not set, then the output format is inferred from the + extension of *fname*, if any, and from :rc:`savefig.format` otherwise. + If *format* is set, it determines the output format. + arr : array-like + The image data. The shape can be one of + MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA). + vmin, vmax : float, optional + *vmin* and *vmax* set the color scaling for the image by fixing the + values that map to the colormap color limits. If either *vmin* + or *vmax* is None, that limit is determined from the *arr* + min/max value. + cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap` + A Colormap instance or registered colormap name. The colormap + maps scalar data to colors. It is ignored for RGB(A) data. + format : str, optional + The file format, e.g. 'png', 'pdf', 'svg', ... The behavior when this + is unset is documented under *fname*. + origin : {'upper', 'lower'}, default: :rc:`image.origin` + Indicates whether the ``(0, 0)`` index of the array is in the upper + left or lower left corner of the axes. + dpi : float + The DPI to store in the metadata of the file. This does not affect the + resolution of the output image. Depending on file format, this may be + rounded to the nearest integer. + metadata : dict, optional + Metadata in the image file. The supported keys depend on the output + format, see the documentation of the respective backends for more + information. + Currently only supported for "png", "pdf", "ps", "eps", and "svg". + pil_kwargs : dict, optional + Keyword arguments passed to `PIL.Image.Image.save`. If the 'pnginfo' + key is present, it completely overrides *metadata*, including the + default 'Software' key. + """ + from matplotlib.figure import Figure + if isinstance(fname, os.PathLike): + fname = os.fspath(fname) + if format is None: + format = (Path(fname).suffix[1:] if isinstance(fname, str) + else mpl.rcParams["savefig.format"]).lower() + if format in ["pdf", "ps", "eps", "svg"]: + # Vector formats that are not handled by PIL. + if pil_kwargs is not None: + raise ValueError( + f"Cannot use 'pil_kwargs' when saving to {format}") + fig = Figure(dpi=dpi, frameon=False) + fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin, + resize=True) + fig.savefig(fname, dpi=dpi, format=format, transparent=True, + metadata=metadata) + else: + # Don't bother creating an image; this avoids rounding errors on the + # size when dividing and then multiplying by dpi. + if origin is None: + origin = mpl.rcParams["image.origin"] + else: + _api.check_in_list(('upper', 'lower'), origin=origin) + if origin == "lower": + arr = arr[::-1] + if (isinstance(arr, memoryview) and arr.format == "B" + and arr.ndim == 3 and arr.shape[-1] == 4): + # Such an ``arr`` would also be handled fine by sm.to_rgba below + # (after casting with asarray), but it is useful to special-case it + # because that's what backend_agg passes, and can be in fact used + # as is, saving a few operations. + rgba = arr + else: + sm = cm.ScalarMappable(cmap=cmap) + sm.set_clim(vmin, vmax) + rgba = sm.to_rgba(arr, bytes=True) + if pil_kwargs is None: + pil_kwargs = {} + else: + # we modify this below, so make a copy (don't modify caller's dict) + pil_kwargs = pil_kwargs.copy() + pil_shape = (rgba.shape[1], rgba.shape[0]) + image = PIL.Image.frombuffer( + "RGBA", pil_shape, rgba, "raw", "RGBA", 0, 1) + if format == "png": + # Only use the metadata kwarg if pnginfo is not set, because the + # semantics of duplicate keys in pnginfo is unclear. + if "pnginfo" in pil_kwargs: + if metadata: + _api.warn_external("'metadata' is overridden by the " + "'pnginfo' entry in 'pil_kwargs'.") + else: + metadata = { + "Software": (f"Matplotlib version{mpl.__version__}, " + f"https://matplotlib.org/"), + **(metadata if metadata is not None else {}), + } + pil_kwargs["pnginfo"] = pnginfo = PIL.PngImagePlugin.PngInfo() + for k, v in metadata.items(): + if v is not None: + pnginfo.add_text(k, v) + elif metadata is not None: + raise ValueError(f"metadata not supported for format {format!r}") + if format in ["jpg", "jpeg"]: + format = "jpeg" # Pillow doesn't recognize "jpg". + facecolor = mpl.rcParams["savefig.facecolor"] + if cbook._str_equal(facecolor, "auto"): + facecolor = mpl.rcParams["figure.facecolor"] + color = tuple(int(x * 255) for x in mcolors.to_rgb(facecolor)) + background = PIL.Image.new("RGB", pil_shape, color) + background.paste(image, image) + image = background + pil_kwargs.setdefault("format", format) + pil_kwargs.setdefault("dpi", (dpi, dpi)) + image.save(fname, **pil_kwargs) + + +def pil_to_array(pilImage): + """ + Load a `PIL image`_ and return it as a numpy int array. + + .. _PIL image: https://pillow.readthedocs.io/en/latest/reference/Image.html + + Returns + ------- + numpy.array + + The array shape depends on the image type: + + - (M, N) for grayscale images. + - (M, N, 3) for RGB images. + - (M, N, 4) for RGBA images. + """ + if pilImage.mode in ['RGBA', 'RGBX', 'RGB', 'L']: + # return MxNx4 RGBA, MxNx3 RBA, or MxN luminance array + return np.asarray(pilImage) + elif pilImage.mode.startswith('I;16'): + # return MxN luminance array of uint16 + raw = pilImage.tobytes('raw', pilImage.mode) + if pilImage.mode.endswith('B'): + x = np.frombuffer(raw, '>u2') + else: + x = np.frombuffer(raw, ' None: ... + +# +# END names re-exported from matplotlib._image. +# + +interpolations_names: set[str] + +def composite_images( + images: Sequence[_ImageBase], renderer: RendererBase, magnification: float = ... +) -> tuple[np.ndarray, float, float]: ... + +class _ImageBase(martist.Artist, cm.ScalarMappable): + zorder: float + origin: Literal["upper", "lower"] + axes: Axes + def __init__( + self, + ax: Axes, + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + interpolation: str | None = ..., + origin: Literal["upper", "lower"] | None = ..., + filternorm: bool = ..., + filterrad: float = ..., + resample: bool | None = ..., + *, + interpolation_stage: Literal["data", "rgba"] | None = ..., + **kwargs + ) -> None: ... + def get_size(self) -> tuple[int, int]: ... + def set_alpha(self, alpha: float | ArrayLike | None) -> None: ... + def changed(self) -> None: ... + def make_image( + self, renderer: RendererBase, magnification: float = ..., unsampled: bool = ... + ) -> tuple[np.ndarray, float, float, Affine2D]: ... + def draw(self, renderer: RendererBase, *args, **kwargs) -> None: ... + def write_png(self, fname: str | pathlib.Path | BinaryIO) -> None: ... + def set_data(self, A: ArrayLike | None) -> None: ... + def set_array(self, A: ArrayLike | None) -> None: ... + def get_shape(self) -> tuple[int, int, int]: ... + def get_interpolation(self) -> str: ... + def set_interpolation(self, s: str | None) -> None: ... + def set_interpolation_stage(self, s: Literal["data", "rgba"]) -> None: ... + def can_composite(self) -> bool: ... + def set_resample(self, v: bool | None) -> None: ... + def get_resample(self) -> bool: ... + def set_filternorm(self, filternorm: bool) -> None: ... + def get_filternorm(self) -> bool: ... + def set_filterrad(self, filterrad: float) -> None: ... + def get_filterrad(self) -> float: ... + +class AxesImage(_ImageBase): + def __init__( + self, + ax: Axes, + *, + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + interpolation: str | None = ..., + origin: Literal["upper", "lower"] | None = ..., + extent: tuple[float, float, float, float] | None = ..., + filternorm: bool = ..., + filterrad: float = ..., + resample: bool = ..., + interpolation_stage: Literal["data", "rgba"] | None = ..., + **kwargs + ) -> None: ... + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... + def make_image( + self, renderer: RendererBase, magnification: float = ..., unsampled: bool = ... + ) -> tuple[np.ndarray, float, float, Affine2D]: ... + def set_extent( + self, extent: tuple[float, float, float, float], **kwargs + ) -> None: ... + def get_extent(self) -> tuple[float, float, float, float]: ... + def get_cursor_data(self, event: MouseEvent) -> None | float: ... + +class NonUniformImage(AxesImage): + mouseover: bool + def __init__( + self, ax: Axes, *, interpolation: Literal["nearest", "bilinear"] = ..., **kwargs + ) -> None: ... + def set_data(self, x: ArrayLike, y: ArrayLike, A: ArrayLike) -> None: ... # type: ignore[override] + # more limited interpolation available here than base class + def set_interpolation(self, s: Literal["nearest", "bilinear"]) -> None: ... # type: ignore[override] + +class PcolorImage(AxesImage): + def __init__( + self, + ax: Axes, + x: ArrayLike | None = ..., + y: ArrayLike | None = ..., + A: ArrayLike | None = ..., + *, + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + **kwargs + ) -> None: ... + def set_data(self, x: ArrayLike, y: ArrayLike, A: ArrayLike) -> None: ... # type: ignore[override] + +class FigureImage(_ImageBase): + zorder: float + figure: Figure + ox: float + oy: float + magnification: float + def __init__( + self, + fig: Figure, + *, + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + offsetx: int = ..., + offsety: int = ..., + origin: Literal["upper", "lower"] | None = ..., + **kwargs + ) -> None: ... + def get_extent(self) -> tuple[float, float, float, float]: ... + +class BboxImage(_ImageBase): + bbox: BboxBase + def __init__( + self, + bbox: BboxBase | Callable[[RendererBase | None], Bbox], + *, + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + interpolation: str | None = ..., + origin: Literal["upper", "lower"] | None = ..., + filternorm: bool = ..., + filterrad: float = ..., + resample: bool = ..., + **kwargs + ) -> None: ... + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... + +def imread( + fname: str | pathlib.Path | BinaryIO, format: str | None = ... +) -> np.ndarray: ... +def imsave( + fname: str | os.PathLike | BinaryIO, + arr: ArrayLike, + vmin: float | None = ..., + vmax: float | None = ..., + cmap: str | Colormap | None = ..., + format: str | None = ..., + origin: Literal["upper", "lower"] | None = ..., + dpi: float = ..., + *, + metadata: dict[str, str] | None = ..., + pil_kwargs: dict[str, Any] | None = ... +) -> None: ... +def pil_to_array(pilImage: PIL.Image.Image) -> np.ndarray: ... +def thumbnail( + infile: str | BinaryIO, + thumbfile: str | BinaryIO, + scale: float = ..., + interpolation: str = ..., + preview: bool = ..., +) -> Figure: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.py new file mode 100644 index 00000000..d751059f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.py @@ -0,0 +1,304 @@ +""" +Classes to layout elements in a `.Figure`. + +Figures have a ``layout_engine`` property that holds a subclass of +`~.LayoutEngine` defined here (or *None* for no layout). At draw time +``figure.get_layout_engine().execute()`` is called, the goal of which is +usually to rearrange Axes on the figure to produce a pleasing layout. This is +like a ``draw`` callback but with two differences. First, when printing we +disable the layout engine for the final draw. Second, it is useful to know the +layout engine while the figure is being created. In particular, colorbars are +made differently with different layout engines (for historical reasons). + +Matplotlib supplies two layout engines, `.TightLayoutEngine` and +`.ConstrainedLayoutEngine`. Third parties can create their own layout engine +by subclassing `.LayoutEngine`. +""" + +from contextlib import nullcontext + +import matplotlib as mpl + +from matplotlib._constrained_layout import do_constrained_layout +from matplotlib._tight_layout import (get_subplotspec_list, + get_tight_layout_figure) + + +class LayoutEngine: + """ + Base class for Matplotlib layout engines. + + A layout engine can be passed to a figure at instantiation or at any time + with `~.figure.Figure.set_layout_engine`. Once attached to a figure, the + layout engine ``execute`` function is called at draw time by + `~.figure.Figure.draw`, providing a special draw-time hook. + + .. note:: + + However, note that layout engines affect the creation of colorbars, so + `~.figure.Figure.set_layout_engine` should be called before any + colorbars are created. + + Currently, there are two properties of `LayoutEngine` classes that are + consulted while manipulating the figure: + + - ``engine.colorbar_gridspec`` tells `.Figure.colorbar` whether to make the + axes using the gridspec method (see `.colorbar.make_axes_gridspec`) or + not (see `.colorbar.make_axes`); + - ``engine.adjust_compatible`` stops `.Figure.subplots_adjust` from being + run if it is not compatible with the layout engine. + + To implement a custom `LayoutEngine`: + + 1. override ``_adjust_compatible`` and ``_colorbar_gridspec`` + 2. override `LayoutEngine.set` to update *self._params* + 3. override `LayoutEngine.execute` with your implementation + + """ + # override these in subclass + _adjust_compatible = None + _colorbar_gridspec = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self._params = {} + + def set(self, **kwargs): + """ + Set the parameters for the layout engine. + """ + raise NotImplementedError + + @property + def colorbar_gridspec(self): + """ + Return a boolean if the layout engine creates colorbars using a + gridspec. + """ + if self._colorbar_gridspec is None: + raise NotImplementedError + return self._colorbar_gridspec + + @property + def adjust_compatible(self): + """ + Return a boolean if the layout engine is compatible with + `~.Figure.subplots_adjust`. + """ + if self._adjust_compatible is None: + raise NotImplementedError + return self._adjust_compatible + + def get(self): + """ + Return copy of the parameters for the layout engine. + """ + return dict(self._params) + + def execute(self, fig): + """ + Execute the layout on the figure given by *fig*. + """ + # subclasses must implement this. + raise NotImplementedError + + +class PlaceHolderLayoutEngine(LayoutEngine): + """ + This layout engine does not adjust the figure layout at all. + + The purpose of this `.LayoutEngine` is to act as a placeholder when the user removes + a layout engine to ensure an incompatible `.LayoutEngine` cannot be set later. + + Parameters + ---------- + adjust_compatible, colorbar_gridspec : bool + Allow the PlaceHolderLayoutEngine to mirror the behavior of whatever + layout engine it is replacing. + + """ + def __init__(self, adjust_compatible, colorbar_gridspec, **kwargs): + self._adjust_compatible = adjust_compatible + self._colorbar_gridspec = colorbar_gridspec + super().__init__(**kwargs) + + def execute(self, fig): + """ + Do nothing. + """ + return + + +class TightLayoutEngine(LayoutEngine): + """ + Implements the ``tight_layout`` geometry management. See + :ref:`tight_layout_guide` for details. + """ + _adjust_compatible = True + _colorbar_gridspec = True + + def __init__(self, *, pad=1.08, h_pad=None, w_pad=None, + rect=(0, 0, 1, 1), **kwargs): + """ + Initialize tight_layout engine. + + Parameters + ---------- + pad : float, default: 1.08 + Padding between the figure edge and the edges of subplots, as a + fraction of the font size. + h_pad, w_pad : float + Padding (height/width) between edges of adjacent subplots. + Defaults to *pad*. + rect : tuple (left, bottom, right, top), default: (0, 0, 1, 1). + rectangle in normalized figure coordinates that the subplots + (including labels) will fit into. + """ + super().__init__(**kwargs) + for td in ['pad', 'h_pad', 'w_pad', 'rect']: + # initialize these in case None is passed in above: + self._params[td] = None + self.set(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) + + def execute(self, fig): + """ + Execute tight_layout. + + This decides the subplot parameters given the padding that + will allow the axes labels to not be covered by other labels + and axes. + + Parameters + ---------- + fig : `.Figure` to perform layout on. + + See Also + -------- + .figure.Figure.tight_layout + .pyplot.tight_layout + """ + info = self._params + renderer = fig._get_renderer() + with getattr(renderer, "_draw_disabled", nullcontext)(): + kwargs = get_tight_layout_figure( + fig, fig.axes, get_subplotspec_list(fig.axes), renderer, + pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'], + rect=info['rect']) + if kwargs: + fig.subplots_adjust(**kwargs) + + def set(self, *, pad=None, w_pad=None, h_pad=None, rect=None): + """ + Set the pads for tight_layout. + + Parameters + ---------- + pad : float + Padding between the figure edge and the edges of subplots, as a + fraction of the font size. + w_pad, h_pad : float + Padding (width/height) between edges of adjacent subplots. + Defaults to *pad*. + rect : tuple (left, bottom, right, top) + rectangle in normalized figure coordinates that the subplots + (including labels) will fit into. + """ + for td in self.set.__kwdefaults__: + if locals()[td] is not None: + self._params[td] = locals()[td] + + +class ConstrainedLayoutEngine(LayoutEngine): + """ + Implements the ``constrained_layout`` geometry management. See + :ref:`constrainedlayout_guide` for details. + """ + + _adjust_compatible = False + _colorbar_gridspec = False + + def __init__(self, *, h_pad=None, w_pad=None, + hspace=None, wspace=None, rect=(0, 0, 1, 1), + compress=False, **kwargs): + """ + Initialize ``constrained_layout`` settings. + + Parameters + ---------- + h_pad, w_pad : float + Padding around the axes elements in inches. + Default to :rc:`figure.constrained_layout.h_pad` and + :rc:`figure.constrained_layout.w_pad`. + hspace, wspace : float + Fraction of the figure to dedicate to space between the + axes. These are evenly spread between the gaps between the axes. + A value of 0.2 for a three-column layout would have a space + of 0.1 of the figure width between each column. + If h/wspace < h/w_pad, then the pads are used instead. + Default to :rc:`figure.constrained_layout.hspace` and + :rc:`figure.constrained_layout.wspace`. + rect : tuple of 4 floats + Rectangle in figure coordinates to perform constrained layout in + (left, bottom, width, height), each from 0-1. + compress : bool + Whether to shift Axes so that white space in between them is + removed. This is useful for simple grids of fixed-aspect Axes (e.g. + a grid of images). See :ref:`compressed_layout`. + """ + super().__init__(**kwargs) + # set the defaults: + self.set(w_pad=mpl.rcParams['figure.constrained_layout.w_pad'], + h_pad=mpl.rcParams['figure.constrained_layout.h_pad'], + wspace=mpl.rcParams['figure.constrained_layout.wspace'], + hspace=mpl.rcParams['figure.constrained_layout.hspace'], + rect=(0, 0, 1, 1)) + # set anything that was passed in (None will be ignored): + self.set(w_pad=w_pad, h_pad=h_pad, wspace=wspace, hspace=hspace, + rect=rect) + self._compress = compress + + def execute(self, fig): + """ + Perform constrained_layout and move and resize axes accordingly. + + Parameters + ---------- + fig : `.Figure` to perform layout on. + """ + width, height = fig.get_size_inches() + # pads are relative to the current state of the figure... + w_pad = self._params['w_pad'] / width + h_pad = self._params['h_pad'] / height + + return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad, + wspace=self._params['wspace'], + hspace=self._params['hspace'], + rect=self._params['rect'], + compress=self._compress) + + def set(self, *, h_pad=None, w_pad=None, + hspace=None, wspace=None, rect=None): + """ + Set the pads for constrained_layout. + + Parameters + ---------- + h_pad, w_pad : float + Padding around the axes elements in inches. + Default to :rc:`figure.constrained_layout.h_pad` and + :rc:`figure.constrained_layout.w_pad`. + hspace, wspace : float + Fraction of the figure to dedicate to space between the + axes. These are evenly spread between the gaps between the axes. + A value of 0.2 for a three-column layout would have a space + of 0.1 of the figure width between each column. + If h/wspace < h/w_pad, then the pads are used instead. + Default to :rc:`figure.constrained_layout.hspace` and + :rc:`figure.constrained_layout.wspace`. + rect : tuple of 4 floats + Rectangle in figure coordinates to perform constrained layout in + (left, bottom, width, height), each from 0-1. + """ + for td in self.set.__kwdefaults__: + if locals()[td] is not None: + self._params[td] = locals()[td] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.pyi new file mode 100644 index 00000000..5b8c812f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/layout_engine.pyi @@ -0,0 +1,62 @@ +from matplotlib.figure import Figure + +from typing import Any + +class LayoutEngine: + def __init__(self, **kwargs: Any) -> None: ... + def set(self) -> None: ... + @property + def colorbar_gridspec(self) -> bool: ... + @property + def adjust_compatible(self) -> bool: ... + def get(self) -> dict[str, Any]: ... + def execute(self, fig: Figure) -> None: ... + +class PlaceHolderLayoutEngine(LayoutEngine): + def __init__( + self, adjust_compatible: bool, colorbar_gridspec: bool, **kwargs: Any + ) -> None: ... + def execute(self, fig: Figure) -> None: ... + +class TightLayoutEngine(LayoutEngine): + def __init__( + self, + *, + pad: float = ..., + h_pad: float | None = ..., + w_pad: float | None = ..., + rect: tuple[float, float, float, float] = ..., + **kwargs: Any + ) -> None: ... + def execute(self, fig: Figure) -> None: ... + def set( + self, + *, + pad: float | None = ..., + w_pad: float | None = ..., + h_pad: float | None = ..., + rect: tuple[float, float, float, float] | None = ... + ) -> None: ... + +class ConstrainedLayoutEngine(LayoutEngine): + def __init__( + self, + *, + h_pad: float | None = ..., + w_pad: float | None = ..., + hspace: float | None = ..., + wspace: float | None = ..., + rect: tuple[float, float, float, float] = ..., + compress: bool = ..., + **kwargs: Any + ) -> None: ... + def execute(self, fig: Figure) -> Any: ... + def set( + self, + *, + h_pad: float | None = ..., + w_pad: float | None = ..., + hspace: float | None = ..., + wspace: float | None = ..., + rect: tuple[float, float, float, float] | None = ... + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.py new file mode 100644 index 00000000..c52bdbf0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.py @@ -0,0 +1,1384 @@ +""" +The legend module defines the Legend class, which is responsible for +drawing legends associated with axes and/or figures. + +.. important:: + + It is unlikely that you would ever create a Legend instance manually. + Most users would normally create a legend via the `~.Axes.legend` + function. For more details on legends there is also a :ref:`legend guide + `. + +The `Legend` class is a container of legend handles and legend texts. + +The legend handler map specifies how to create legend handles from artists +(lines, patches, etc.) in the axes or figures. Default legend handlers are +defined in the :mod:`~matplotlib.legend_handler` module. While not all artist +types are covered by the default legend handlers, custom legend handlers can be +defined to support arbitrary objects. + +See the :ref`` for more +information. +""" + +import itertools +import logging +import numbers +import time + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, _docstring, colors, offsetbox +from matplotlib.artist import Artist, allow_rasterization +from matplotlib.cbook import silent_list +from matplotlib.font_manager import FontProperties +from matplotlib.lines import Line2D +from matplotlib.patches import (Patch, Rectangle, Shadow, FancyBboxPatch, + StepPatch) +from matplotlib.collections import ( + Collection, CircleCollection, LineCollection, PathCollection, + PolyCollection, RegularPolyCollection) +from matplotlib.text import Text +from matplotlib.transforms import Bbox, BboxBase, TransformedBbox +from matplotlib.transforms import BboxTransformTo, BboxTransformFrom +from matplotlib.offsetbox import ( + AnchoredOffsetbox, DraggableOffsetBox, + HPacker, VPacker, + DrawingArea, TextArea, +) +from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer +from . import legend_handler + + +class DraggableLegend(DraggableOffsetBox): + def __init__(self, legend, use_blit=False, update="loc"): + """ + Wrapper around a `.Legend` to support mouse dragging. + + Parameters + ---------- + legend : `.Legend` + The `.Legend` instance to wrap. + use_blit : bool, optional + Use blitting for faster image composition. For details see + :ref:`func-animation`. + update : {'loc', 'bbox'}, optional + If "loc", update the *loc* parameter of the legend upon finalizing. + If "bbox", update the *bbox_to_anchor* parameter. + """ + self.legend = legend + + _api.check_in_list(["loc", "bbox"], update=update) + self._update = update + + super().__init__(legend, legend._legend_box, use_blit=use_blit) + + def finalize_offset(self): + if self._update == "loc": + self._update_loc(self.get_loc_in_canvas()) + elif self._update == "bbox": + self._update_bbox_to_anchor(self.get_loc_in_canvas()) + + def _update_loc(self, loc_in_canvas): + bbox = self.legend.get_bbox_to_anchor() + # if bbox has zero width or height, the transformation is + # ill-defined. Fall back to the default bbox_to_anchor. + if bbox.width == 0 or bbox.height == 0: + self.legend.set_bbox_to_anchor(None) + bbox = self.legend.get_bbox_to_anchor() + _bbox_transform = BboxTransformFrom(bbox) + self.legend._loc = tuple(_bbox_transform.transform(loc_in_canvas)) + + def _update_bbox_to_anchor(self, loc_in_canvas): + loc_in_bbox = self.legend.axes.transAxes.transform(loc_in_canvas) + self.legend.set_bbox_to_anchor(loc_in_bbox) + + +_legend_kw_doc_base = """ +bbox_to_anchor : `.BboxBase`, 2-tuple, or 4-tuple of floats + Box that is used to position the legend in conjunction with *loc*. + Defaults to `axes.bbox` (if called as a method to `.Axes.legend`) or + `figure.bbox` (if `.Figure.legend`). This argument allows arbitrary + placement of the legend. + + Bbox coordinates are interpreted in the coordinate system given by + *bbox_transform*, with the default transform + Axes or Figure coordinates, depending on which ``legend`` is called. + + If a 4-tuple or `.BboxBase` is given, then it specifies the bbox + ``(x, y, width, height)`` that the legend is placed in. + To put the legend in the best location in the bottom right + quadrant of the axes (or figure):: + + loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.5) + + A 2-tuple ``(x, y)`` places the corner of the legend specified by *loc* at + x, y. For example, to put the legend's upper right-hand corner in the + center of the axes (or figure) the following keywords can be used:: + + loc='upper right', bbox_to_anchor=(0.5, 0.5) + +ncols : int, default: 1 + The number of columns that the legend has. + + For backward compatibility, the spelling *ncol* is also supported + but it is discouraged. If both are given, *ncols* takes precedence. + +prop : None or `~matplotlib.font_manager.FontProperties` or dict + The font properties of the legend. If None (default), the current + :data:`matplotlib.rcParams` will be used. + +fontsize : int or {'xx-small', 'x-small', 'small', 'medium', 'large', \ +'x-large', 'xx-large'} + The font size of the legend. If the value is numeric the size will be the + absolute font size in points. String values are relative to the current + default font size. This argument is only used if *prop* is not specified. + +labelcolor : str or list, default: :rc:`legend.labelcolor` + The color of the text in the legend. Either a valid color string + (for example, 'red'), or a list of color strings. The labelcolor can + also be made to match the color of the line or marker using 'linecolor', + 'markerfacecolor' (or 'mfc'), or 'markeredgecolor' (or 'mec'). + + Labelcolor can be set globally using :rc:`legend.labelcolor`. If None, + use :rc:`text.color`. + +numpoints : int, default: :rc:`legend.numpoints` + The number of marker points in the legend when creating a legend + entry for a `.Line2D` (line). + +scatterpoints : int, default: :rc:`legend.scatterpoints` + The number of marker points in the legend when creating + a legend entry for a `.PathCollection` (scatter plot). + +scatteryoffsets : iterable of floats, default: ``[0.375, 0.5, 0.3125]`` + The vertical offset (relative to the font size) for the markers + created for a scatter plot legend entry. 0.0 is at the base the + legend text, and 1.0 is at the top. To draw all markers at the + same height, set to ``[0.5]``. + +markerscale : float, default: :rc:`legend.markerscale` + The relative size of legend markers compared to the originally drawn ones. + +markerfirst : bool, default: True + If *True*, legend marker is placed to the left of the legend label. + If *False*, legend marker is placed to the right of the legend label. + +reverse : bool, default: False + If *True*, the legend labels are displayed in reverse order from the input. + If *False*, the legend labels are displayed in the same order as the input. + + .. versionadded:: 3.7 + +frameon : bool, default: :rc:`legend.frameon` + Whether the legend should be drawn on a patch (frame). + +fancybox : bool, default: :rc:`legend.fancybox` + Whether round edges should be enabled around the `.FancyBboxPatch` which + makes up the legend's background. + +shadow : None, bool or dict, default: :rc:`legend.shadow` + Whether to draw a shadow behind the legend. + The shadow can be configured using `.Patch` keywords. + Customization via :rc:`legend.shadow` is currently not supported. + +framealpha : float, default: :rc:`legend.framealpha` + The alpha transparency of the legend's background. + If *shadow* is activated and *framealpha* is ``None``, the default value is + ignored. + +facecolor : "inherit" or color, default: :rc:`legend.facecolor` + The legend's background color. + If ``"inherit"``, use :rc:`axes.facecolor`. + +edgecolor : "inherit" or color, default: :rc:`legend.edgecolor` + The legend's background patch edge color. + If ``"inherit"``, use take :rc:`axes.edgecolor`. + +mode : {"expand", None} + If *mode* is set to ``"expand"`` the legend will be horizontally + expanded to fill the axes area (or *bbox_to_anchor* if defines + the legend's size). + +bbox_transform : None or `~matplotlib.transforms.Transform` + The transform for the bounding box (*bbox_to_anchor*). For a value + of ``None`` (default) the Axes' + :data:`~matplotlib.axes.Axes.transAxes` transform will be used. + +title : str or None + The legend's title. Default is no title (``None``). + +title_fontproperties : None or `~matplotlib.font_manager.FontProperties` or dict + The font properties of the legend's title. If None (default), the + *title_fontsize* argument will be used if present; if *title_fontsize* is + also None, the current :rc:`legend.title_fontsize` will be used. + +title_fontsize : int or {'xx-small', 'x-small', 'small', 'medium', 'large', \ +'x-large', 'xx-large'}, default: :rc:`legend.title_fontsize` + The font size of the legend's title. + Note: This cannot be combined with *title_fontproperties*. If you want + to set the fontsize alongside other font properties, use the *size* + parameter in *title_fontproperties*. + +alignment : {'center', 'left', 'right'}, default: 'center' + The alignment of the legend title and the box of entries. The entries + are aligned as a single block, so that markers always lined up. + +borderpad : float, default: :rc:`legend.borderpad` + The fractional whitespace inside the legend border, in font-size units. + +labelspacing : float, default: :rc:`legend.labelspacing` + The vertical space between the legend entries, in font-size units. + +handlelength : float, default: :rc:`legend.handlelength` + The length of the legend handles, in font-size units. + +handleheight : float, default: :rc:`legend.handleheight` + The height of the legend handles, in font-size units. + +handletextpad : float, default: :rc:`legend.handletextpad` + The pad between the legend handle and text, in font-size units. + +borderaxespad : float, default: :rc:`legend.borderaxespad` + The pad between the axes and legend border, in font-size units. + +columnspacing : float, default: :rc:`legend.columnspacing` + The spacing between columns, in font-size units. + +handler_map : dict or None + The custom dictionary mapping instances or types to a legend + handler. This *handler_map* updates the default handler map + found at `matplotlib.legend.Legend.get_legend_handler_map`. + +draggable : bool, default: False + Whether the legend can be dragged with the mouse. +""" + +_loc_doc_base = """ +loc : str or pair of floats, default: {default} + The location of the legend. + + The strings ``'upper left'``, ``'upper right'``, ``'lower left'``, + ``'lower right'`` place the legend at the corresponding corner of the + {parent}. + + The strings ``'upper center'``, ``'lower center'``, ``'center left'``, + ``'center right'`` place the legend at the center of the corresponding edge + of the {parent}. + + The string ``'center'`` places the legend at the center of the {parent}. +{best} + The location can also be a 2-tuple giving the coordinates of the lower-left + corner of the legend in {parent} coordinates (in which case *bbox_to_anchor* + will be ignored). + + For back-compatibility, ``'center right'`` (but no other location) can also + be spelled ``'right'``, and each "string" location can also be given as a + numeric value: + + ================== ============= + Location String Location Code + ================== ============= + 'best' (Axes only) 0 + 'upper right' 1 + 'upper left' 2 + 'lower left' 3 + 'lower right' 4 + 'right' 5 + 'center left' 6 + 'center right' 7 + 'lower center' 8 + 'upper center' 9 + 'center' 10 + ================== ============= + {outside}""" + +_loc_doc_best = """ + The string ``'best'`` places the legend at the location, among the nine + locations defined so far, with the minimum overlap with other drawn + artists. This option can be quite slow for plots with large amounts of + data; your plotting speed may benefit from providing a specific location. +""" + +_legend_kw_axes_st = ( + _loc_doc_base.format(parent='axes', default=':rc:`legend.loc`', + best=_loc_doc_best, outside='') + + _legend_kw_doc_base) +_docstring.interpd.update(_legend_kw_axes=_legend_kw_axes_st) + +_outside_doc = """ + If a figure is using the constrained layout manager, the string codes + of the *loc* keyword argument can get better layout behaviour using the + prefix 'outside'. There is ambiguity at the corners, so 'outside + upper right' will make space for the legend above the rest of the + axes in the layout, and 'outside right upper' will make space on the + right side of the layout. In addition to the values of *loc* + listed above, we have 'outside right upper', 'outside right lower', + 'outside left upper', and 'outside left lower'. See + :ref:`legend_guide` for more details. +""" + +_legend_kw_figure_st = ( + _loc_doc_base.format(parent='figure', default="'upper right'", + best='', outside=_outside_doc) + + _legend_kw_doc_base) +_docstring.interpd.update(_legend_kw_figure=_legend_kw_figure_st) + +_legend_kw_both_st = ( + _loc_doc_base.format(parent='axes/figure', + default=":rc:`legend.loc` for Axes, 'upper right' for Figure", + best=_loc_doc_best, outside=_outside_doc) + + _legend_kw_doc_base) +_docstring.interpd.update(_legend_kw_doc=_legend_kw_both_st) + +_legend_kw_set_loc_st = ( + _loc_doc_base.format(parent='axes/figure', + default=":rc:`legend.loc` for Axes, 'upper right' for Figure", + best=_loc_doc_best, outside=_outside_doc)) +_docstring.interpd.update(_legend_kw_set_loc_doc=_legend_kw_set_loc_st) + + +class Legend(Artist): + """ + Place a legend on the figure/axes. + """ + + # 'best' is only implemented for axes legends + codes = {'best': 0, **AnchoredOffsetbox.codes} + zorder = 5 + + def __str__(self): + return "Legend" + + @_docstring.dedent_interpd + def __init__( + self, parent, handles, labels, + *, + loc=None, + numpoints=None, # number of points in the legend line + markerscale=None, # relative size of legend markers vs. original + markerfirst=True, # left/right ordering of legend marker and label + reverse=False, # reverse ordering of legend marker and label + scatterpoints=None, # number of scatter points + scatteryoffsets=None, + prop=None, # properties for the legend texts + fontsize=None, # keyword to set font size directly + labelcolor=None, # keyword to set the text color + + # spacing & pad defined as a fraction of the font-size + borderpad=None, # whitespace inside the legend border + labelspacing=None, # vertical space between the legend entries + handlelength=None, # length of the legend handles + handleheight=None, # height of the legend handles + handletextpad=None, # pad between the legend handle and text + borderaxespad=None, # pad between the axes and legend border + columnspacing=None, # spacing between columns + + ncols=1, # number of columns + mode=None, # horizontal distribution of columns: None or "expand" + + fancybox=None, # True: fancy box, False: rounded box, None: rcParam + shadow=None, + title=None, # legend title + title_fontsize=None, # legend title font size + framealpha=None, # set frame alpha + edgecolor=None, # frame patch edgecolor + facecolor=None, # frame patch facecolor + + bbox_to_anchor=None, # bbox to which the legend will be anchored + bbox_transform=None, # transform for the bbox + frameon=None, # draw frame + handler_map=None, + title_fontproperties=None, # properties for the legend title + alignment="center", # control the alignment within the legend box + ncol=1, # synonym for ncols (backward compatibility) + draggable=False # whether the legend can be dragged with the mouse + ): + """ + Parameters + ---------- + parent : `~matplotlib.axes.Axes` or `.Figure` + The artist that contains the legend. + + handles : list of (`.Artist` or tuple of `.Artist`) + A list of Artists (lines, patches) to be added to the legend. + + labels : list of str + A list of labels to show next to the artists. The length of handles + and labels should be the same. If they are not, they are truncated + to the length of the shorter list. + + Other Parameters + ---------------- + %(_legend_kw_doc)s + + Attributes + ---------- + legend_handles + List of `.Artist` objects added as legend entries. + + .. versionadded:: 3.7 + """ + # local import only to avoid circularity + from matplotlib.axes import Axes + from matplotlib.figure import FigureBase + + super().__init__() + + if prop is None: + self.prop = FontProperties(size=mpl._val_or_rc(fontsize, "legend.fontsize")) + else: + self.prop = FontProperties._from_any(prop) + if isinstance(prop, dict) and "size" not in prop: + self.prop.set_size(mpl.rcParams["legend.fontsize"]) + + self._fontsize = self.prop.get_size_in_points() + + self.texts = [] + self.legend_handles = [] + self._legend_title_box = None + + #: A dictionary with the extra handler mappings for this Legend + #: instance. + self._custom_handler_map = handler_map + + self.numpoints = mpl._val_or_rc(numpoints, 'legend.numpoints') + self.markerscale = mpl._val_or_rc(markerscale, 'legend.markerscale') + self.scatterpoints = mpl._val_or_rc(scatterpoints, 'legend.scatterpoints') + self.borderpad = mpl._val_or_rc(borderpad, 'legend.borderpad') + self.labelspacing = mpl._val_or_rc(labelspacing, 'legend.labelspacing') + self.handlelength = mpl._val_or_rc(handlelength, 'legend.handlelength') + self.handleheight = mpl._val_or_rc(handleheight, 'legend.handleheight') + self.handletextpad = mpl._val_or_rc(handletextpad, 'legend.handletextpad') + self.borderaxespad = mpl._val_or_rc(borderaxespad, 'legend.borderaxespad') + self.columnspacing = mpl._val_or_rc(columnspacing, 'legend.columnspacing') + self.shadow = mpl._val_or_rc(shadow, 'legend.shadow') + # trim handles and labels if illegal label... + _lab, _hand = [], [] + for label, handle in zip(labels, handles): + if isinstance(label, str) and label.startswith('_'): + _api.warn_deprecated("3.8", message=( + "An artist whose label starts with an underscore was passed to " + "legend(); such artists will no longer be ignored in the future. " + "To suppress this warning, explicitly filter out such artists, " + "e.g. with `[art for art in artists if not " + "art.get_label().startswith('_')]`.")) + else: + _lab.append(label) + _hand.append(handle) + labels, handles = _lab, _hand + + if reverse: + labels.reverse() + handles.reverse() + + if len(handles) < 2: + ncols = 1 + self._ncols = ncols if ncols != 1 else ncol + + if self.numpoints <= 0: + raise ValueError("numpoints must be > 0; it was %d" % numpoints) + + # introduce y-offset for handles of the scatter plot + if scatteryoffsets is None: + self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.]) + else: + self._scatteryoffsets = np.asarray(scatteryoffsets) + reps = self.scatterpoints // len(self._scatteryoffsets) + 1 + self._scatteryoffsets = np.tile(self._scatteryoffsets, + reps)[:self.scatterpoints] + + # _legend_box is a VPacker instance that contains all + # legend items and will be initialized from _init_legend_box() + # method. + self._legend_box = None + + if isinstance(parent, Axes): + self.isaxes = True + self.axes = parent + self.set_figure(parent.figure) + elif isinstance(parent, FigureBase): + self.isaxes = False + self.set_figure(parent) + else: + raise TypeError( + "Legend needs either Axes or FigureBase as parent" + ) + self.parent = parent + + self._mode = mode + self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform) + + # Figure out if self.shadow is valid + # If shadow was None, rcParams loads False + # So it shouldn't be None here + + self._shadow_props = {'ox': 2, 'oy': -2} # default location offsets + if isinstance(self.shadow, dict): + self._shadow_props.update(self.shadow) + self.shadow = True + elif self.shadow in (0, 1, True, False): + self.shadow = bool(self.shadow) + else: + raise ValueError( + 'Legend shadow must be a dict or bool, not ' + f'{self.shadow!r} of type {type(self.shadow)}.' + ) + + # We use FancyBboxPatch to draw a legend frame. The location + # and size of the box will be updated during the drawing time. + + facecolor = mpl._val_or_rc(facecolor, "legend.facecolor") + if facecolor == 'inherit': + facecolor = mpl.rcParams["axes.facecolor"] + + edgecolor = mpl._val_or_rc(edgecolor, "legend.edgecolor") + if edgecolor == 'inherit': + edgecolor = mpl.rcParams["axes.edgecolor"] + + fancybox = mpl._val_or_rc(fancybox, "legend.fancybox") + + self.legendPatch = FancyBboxPatch( + xy=(0, 0), width=1, height=1, + facecolor=facecolor, edgecolor=edgecolor, + # If shadow is used, default to alpha=1 (#8943). + alpha=(framealpha if framealpha is not None + else 1 if shadow + else mpl.rcParams["legend.framealpha"]), + # The width and height of the legendPatch will be set (in draw()) + # to the length that includes the padding. Thus we set pad=0 here. + boxstyle=("round,pad=0,rounding_size=0.2" if fancybox + else "square,pad=0"), + mutation_scale=self._fontsize, + snap=True, + visible=mpl._val_or_rc(frameon, "legend.frameon") + ) + self._set_artist_props(self.legendPatch) + + _api.check_in_list(["center", "left", "right"], alignment=alignment) + self._alignment = alignment + + # init with null renderer + self._init_legend_box(handles, labels, markerfirst) + + # Set legend location + self.set_loc(loc) + + # figure out title font properties: + if title_fontsize is not None and title_fontproperties is not None: + raise ValueError( + "title_fontsize and title_fontproperties can't be specified " + "at the same time. Only use one of them. ") + title_prop_fp = FontProperties._from_any(title_fontproperties) + if isinstance(title_fontproperties, dict): + if "size" not in title_fontproperties: + title_fontsize = mpl.rcParams["legend.title_fontsize"] + title_prop_fp.set_size(title_fontsize) + elif title_fontsize is not None: + title_prop_fp.set_size(title_fontsize) + elif not isinstance(title_fontproperties, FontProperties): + title_fontsize = mpl.rcParams["legend.title_fontsize"] + title_prop_fp.set_size(title_fontsize) + + self.set_title(title, prop=title_prop_fp) + + self._draggable = None + self.set_draggable(state=draggable) + + # set the text color + + color_getters = { # getter function depends on line or patch + 'linecolor': ['get_color', 'get_facecolor'], + 'markerfacecolor': ['get_markerfacecolor', 'get_facecolor'], + 'mfc': ['get_markerfacecolor', 'get_facecolor'], + 'markeredgecolor': ['get_markeredgecolor', 'get_edgecolor'], + 'mec': ['get_markeredgecolor', 'get_edgecolor'], + } + labelcolor = mpl._val_or_rc(labelcolor, 'legend.labelcolor') + if labelcolor is None: + labelcolor = mpl.rcParams['text.color'] + if isinstance(labelcolor, str) and labelcolor in color_getters: + getter_names = color_getters[labelcolor] + for handle, text in zip(self.legend_handles, self.texts): + try: + if handle.get_array() is not None: + continue + except AttributeError: + pass + for getter_name in getter_names: + try: + color = getattr(handle, getter_name)() + if isinstance(color, np.ndarray): + if ( + color.shape[0] == 1 + or np.isclose(color, color[0]).all() + ): + text.set_color(color[0]) + else: + pass + else: + text.set_color(color) + break + except AttributeError: + pass + elif isinstance(labelcolor, str) and labelcolor == 'none': + for text in self.texts: + text.set_color(labelcolor) + elif np.iterable(labelcolor): + for text, color in zip(self.texts, + itertools.cycle( + colors.to_rgba_array(labelcolor))): + text.set_color(color) + else: + raise ValueError(f"Invalid labelcolor: {labelcolor!r}") + + legendHandles = _api.deprecated('3.7', alternative="legend_handles")( + property(lambda self: self.legend_handles)) + + def _set_artist_props(self, a): + """ + Set the boilerplate props for artists added to axes. + """ + a.set_figure(self.figure) + if self.isaxes: + a.axes = self.axes + + a.set_transform(self.get_transform()) + + @_docstring.dedent_interpd + def set_loc(self, loc=None): + """ + Set the location of the legend. + + .. versionadded:: 3.8 + + Parameters + ---------- + %(_legend_kw_set_loc_doc)s + """ + loc0 = loc + self._loc_used_default = loc is None + if loc is None: + loc = mpl.rcParams["legend.loc"] + if not self.isaxes and loc in [0, 'best']: + loc = 'upper right' + + type_err_message = ("loc must be string, coordinate tuple, or" + f" an integer 0-10, not {loc!r}") + + # handle outside legends: + self._outside_loc = None + if isinstance(loc, str): + if loc.split()[0] == 'outside': + # strip outside: + loc = loc.split('outside ')[1] + # strip "center" at the beginning + self._outside_loc = loc.replace('center ', '') + # strip first + self._outside_loc = self._outside_loc.split()[0] + locs = loc.split() + if len(locs) > 1 and locs[0] in ('right', 'left'): + # locs doesn't accept "left upper", etc, so swap + if locs[0] != 'center': + locs = locs[::-1] + loc = locs[0] + ' ' + locs[1] + # check that loc is in acceptable strings + loc = _api.check_getitem(self.codes, loc=loc) + elif np.iterable(loc): + # coerce iterable into tuple + loc = tuple(loc) + # validate the tuple represents Real coordinates + if len(loc) != 2 or not all(isinstance(e, numbers.Real) for e in loc): + raise ValueError(type_err_message) + elif isinstance(loc, int): + # validate the integer represents a string numeric value + if loc < 0 or loc > 10: + raise ValueError(type_err_message) + else: + # all other cases are invalid values of loc + raise ValueError(type_err_message) + + if self.isaxes and self._outside_loc: + raise ValueError( + f"'outside' option for loc='{loc0}' keyword argument only " + "works for figure legends") + + if not self.isaxes and loc == 0: + raise ValueError( + "Automatic legend placement (loc='best') not implemented for " + "figure legend") + + tmp = self._loc_used_default + self._set_loc(loc) + self._loc_used_default = tmp # ignore changes done by _set_loc + + def _set_loc(self, loc): + # find_offset function will be provided to _legend_box and + # _legend_box will draw itself at the location of the return + # value of the find_offset. + self._loc_used_default = False + self._loc_real = loc + self.stale = True + self._legend_box.set_offset(self._findoffset) + + def set_ncols(self, ncols): + """Set the number of columns.""" + self._ncols = ncols + + def _get_loc(self): + return self._loc_real + + _loc = property(_get_loc, _set_loc) + + def _findoffset(self, width, height, xdescent, ydescent, renderer): + """Helper function to locate the legend.""" + + if self._loc == 0: # "best". + x, y = self._find_best_position(width, height, renderer) + elif self._loc in Legend.codes.values(): # Fixed location. + bbox = Bbox.from_bounds(0, 0, width, height) + x, y = self._get_anchored_bbox(self._loc, bbox, + self.get_bbox_to_anchor(), + renderer) + else: # Axes or figure coordinates. + fx, fy = self._loc + bbox = self.get_bbox_to_anchor() + x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy + + return x + xdescent, y + ydescent + + @allow_rasterization + def draw(self, renderer): + # docstring inherited + if not self.get_visible(): + return + + renderer.open_group('legend', gid=self.get_gid()) + + fontsize = renderer.points_to_pixels(self._fontsize) + + # if mode == fill, set the width of the legend_box to the + # width of the parent (minus pads) + if self._mode in ["expand"]: + pad = 2 * (self.borderaxespad + self.borderpad) * fontsize + self._legend_box.set_width(self.get_bbox_to_anchor().width - pad) + + # update the location and size of the legend. This needs to + # be done in any case to clip the figure right. + bbox = self._legend_box.get_window_extent(renderer) + self.legendPatch.set_bounds(bbox.bounds) + self.legendPatch.set_mutation_scale(fontsize) + + # self.shadow is validated in __init__ + # So by here it is a bool and self._shadow_props contains any configs + + if self.shadow: + Shadow(self.legendPatch, **self._shadow_props).draw(renderer) + + self.legendPatch.draw(renderer) + self._legend_box.draw(renderer) + + renderer.close_group('legend') + self.stale = False + + # _default_handler_map defines the default mapping between plot + # elements and the legend handlers. + + _default_handler_map = { + StemContainer: legend_handler.HandlerStem(), + ErrorbarContainer: legend_handler.HandlerErrorbar(), + Line2D: legend_handler.HandlerLine2D(), + Patch: legend_handler.HandlerPatch(), + StepPatch: legend_handler.HandlerStepPatch(), + LineCollection: legend_handler.HandlerLineCollection(), + RegularPolyCollection: legend_handler.HandlerRegularPolyCollection(), + CircleCollection: legend_handler.HandlerCircleCollection(), + BarContainer: legend_handler.HandlerPatch( + update_func=legend_handler.update_from_first_child), + tuple: legend_handler.HandlerTuple(), + PathCollection: legend_handler.HandlerPathCollection(), + PolyCollection: legend_handler.HandlerPolyCollection() + } + + # (get|set|update)_default_handler_maps are public interfaces to + # modify the default handler map. + + @classmethod + def get_default_handler_map(cls): + """Return the global default handler map, shared by all legends.""" + return cls._default_handler_map + + @classmethod + def set_default_handler_map(cls, handler_map): + """Set the global default handler map, shared by all legends.""" + cls._default_handler_map = handler_map + + @classmethod + def update_default_handler_map(cls, handler_map): + """Update the global default handler map, shared by all legends.""" + cls._default_handler_map.update(handler_map) + + def get_legend_handler_map(self): + """Return this legend instance's handler map.""" + default_handler_map = self.get_default_handler_map() + return ({**default_handler_map, **self._custom_handler_map} + if self._custom_handler_map else default_handler_map) + + @staticmethod + def get_legend_handler(legend_handler_map, orig_handle): + """ + Return a legend handler from *legend_handler_map* that + corresponds to *orig_handler*. + + *legend_handler_map* should be a dictionary object (that is + returned by the get_legend_handler_map method). + + It first checks if the *orig_handle* itself is a key in the + *legend_handler_map* and return the associated value. + Otherwise, it checks for each of the classes in its + method-resolution-order. If no matching key is found, it + returns ``None``. + """ + try: + return legend_handler_map[orig_handle] + except (TypeError, KeyError): # TypeError if unhashable. + pass + for handle_type in type(orig_handle).mro(): + try: + return legend_handler_map[handle_type] + except KeyError: + pass + return None + + def _init_legend_box(self, handles, labels, markerfirst=True): + """ + Initialize the legend_box. The legend_box is an instance of + the OffsetBox, which is packed with legend handles and + texts. Once packed, their location is calculated during the + drawing time. + """ + + fontsize = self._fontsize + + # legend_box is a HPacker, horizontally packed with columns. + # Each column is a VPacker, vertically packed with legend items. + # Each legend item is a HPacker packed with: + # - handlebox: a DrawingArea which contains the legend handle. + # - labelbox: a TextArea which contains the legend text. + + text_list = [] # the list of text instances + handle_list = [] # the list of handle instances + handles_and_labels = [] + + # The approximate height and descent of text. These values are + # only used for plotting the legend handle. + descent = 0.35 * fontsize * (self.handleheight - 0.7) # heuristic. + height = fontsize * self.handleheight - descent + # each handle needs to be drawn inside a box of (x, y, w, h) = + # (0, -descent, width, height). And their coordinates should + # be given in the display coordinates. + + # The transformation of each handle will be automatically set + # to self.get_transform(). If the artist does not use its + # default transform (e.g., Collections), you need to + # manually set their transform to the self.get_transform(). + legend_handler_map = self.get_legend_handler_map() + + for orig_handle, label in zip(handles, labels): + handler = self.get_legend_handler(legend_handler_map, orig_handle) + if handler is None: + _api.warn_external( + "Legend does not support handles for " + f"{type(orig_handle).__name__} " + "instances.\nA proxy artist may be used " + "instead.\nSee: https://matplotlib.org/" + "stable/users/explain/axes/legend_guide.html" + "#controlling-the-legend-entries") + # No handle for this artist, so we just defer to None. + handle_list.append(None) + else: + textbox = TextArea(label, multilinebaseline=True, + textprops=dict( + verticalalignment='baseline', + horizontalalignment='left', + fontproperties=self.prop)) + handlebox = DrawingArea(width=self.handlelength * fontsize, + height=height, + xdescent=0., ydescent=descent) + + text_list.append(textbox._text) + # Create the artist for the legend which represents the + # original artist/handle. + handle_list.append(handler.legend_artist(self, orig_handle, + fontsize, handlebox)) + handles_and_labels.append((handlebox, textbox)) + + columnbox = [] + # array_split splits n handles_and_labels into ncols columns, with the + # first n%ncols columns having an extra entry. filter(len, ...) + # handles the case where n < ncols: the last ncols-n columns are empty + # and get filtered out. + for handles_and_labels_column in filter( + len, np.array_split(handles_and_labels, self._ncols)): + # pack handlebox and labelbox into itembox + itemboxes = [HPacker(pad=0, + sep=self.handletextpad * fontsize, + children=[h, t] if markerfirst else [t, h], + align="baseline") + for h, t in handles_and_labels_column] + # pack columnbox + alignment = "baseline" if markerfirst else "right" + columnbox.append(VPacker(pad=0, + sep=self.labelspacing * fontsize, + align=alignment, + children=itemboxes)) + + mode = "expand" if self._mode == "expand" else "fixed" + sep = self.columnspacing * fontsize + self._legend_handle_box = HPacker(pad=0, + sep=sep, align="baseline", + mode=mode, + children=columnbox) + self._legend_title_box = TextArea("") + self._legend_box = VPacker(pad=self.borderpad * fontsize, + sep=self.labelspacing * fontsize, + align=self._alignment, + children=[self._legend_title_box, + self._legend_handle_box]) + self._legend_box.set_figure(self.figure) + self._legend_box.axes = self.axes + self.texts = text_list + self.legend_handles = handle_list + + def _auto_legend_data(self): + """ + Return display coordinates for hit testing for "best" positioning. + + Returns + ------- + bboxes + List of bounding boxes of all patches. + lines + List of `.Path` corresponding to each line. + offsets + List of (x, y) offsets of all collection. + """ + assert self.isaxes # always holds, as this is only called internally + bboxes = [] + lines = [] + offsets = [] + for artist in self.parent._children: + if isinstance(artist, Line2D): + lines.append( + artist.get_transform().transform_path(artist.get_path())) + elif isinstance(artist, Rectangle): + bboxes.append( + artist.get_bbox().transformed(artist.get_data_transform())) + elif isinstance(artist, Patch): + lines.append( + artist.get_transform().transform_path(artist.get_path())) + elif isinstance(artist, Collection): + transform, transOffset, hoffsets, _ = artist._prepare_points() + if len(hoffsets): + for offset in transOffset.transform(hoffsets): + offsets.append(offset) + + return bboxes, lines, offsets + + def get_children(self): + # docstring inherited + return [self._legend_box, self.get_frame()] + + def get_frame(self): + """Return the `~.patches.Rectangle` used to frame the legend.""" + return self.legendPatch + + def get_lines(self): + r"""Return the list of `~.lines.Line2D`\s in the legend.""" + return [h for h in self.legend_handles if isinstance(h, Line2D)] + + def get_patches(self): + r"""Return the list of `~.patches.Patch`\s in the legend.""" + return silent_list('Patch', + [h for h in self.legend_handles + if isinstance(h, Patch)]) + + def get_texts(self): + r"""Return the list of `~.text.Text`\s in the legend.""" + return silent_list('Text', self.texts) + + def set_alignment(self, alignment): + """ + Set the alignment of the legend title and the box of entries. + + The entries are aligned as a single block, so that markers always + lined up. + + Parameters + ---------- + alignment : {'center', 'left', 'right'}. + + """ + _api.check_in_list(["center", "left", "right"], alignment=alignment) + self._alignment = alignment + self._legend_box.align = alignment + + def get_alignment(self): + """Get the alignment value of the legend box""" + return self._legend_box.align + + def set_title(self, title, prop=None): + """ + Set legend title and title style. + + Parameters + ---------- + title : str + The legend title. + + prop : `.font_manager.FontProperties` or `str` or `pathlib.Path` + The font properties of the legend title. + If a `str`, it is interpreted as a fontconfig pattern parsed by + `.FontProperties`. If a `pathlib.Path`, it is interpreted as the + absolute path to a font file. + + """ + self._legend_title_box._text.set_text(title) + if title: + self._legend_title_box._text.set_visible(True) + self._legend_title_box.set_visible(True) + else: + self._legend_title_box._text.set_visible(False) + self._legend_title_box.set_visible(False) + + if prop is not None: + self._legend_title_box._text.set_fontproperties(prop) + + self.stale = True + + def get_title(self): + """Return the `.Text` instance for the legend title.""" + return self._legend_title_box._text + + def get_window_extent(self, renderer=None): + # docstring inherited + if renderer is None: + renderer = self.figure._get_renderer() + return self._legend_box.get_window_extent(renderer=renderer) + + def get_tightbbox(self, renderer=None): + # docstring inherited + return self._legend_box.get_window_extent(renderer) + + def get_frame_on(self): + """Get whether the legend box patch is drawn.""" + return self.legendPatch.get_visible() + + def set_frame_on(self, b): + """ + Set whether the legend box patch is drawn. + + Parameters + ---------- + b : bool + """ + self.legendPatch.set_visible(b) + self.stale = True + + draw_frame = set_frame_on # Backcompat alias. + + def get_bbox_to_anchor(self): + """Return the bbox that the legend will be anchored to.""" + if self._bbox_to_anchor is None: + return self.parent.bbox + else: + return self._bbox_to_anchor + + def set_bbox_to_anchor(self, bbox, transform=None): + """ + Set the bbox that the legend will be anchored to. + + Parameters + ---------- + bbox : `~matplotlib.transforms.BboxBase` or tuple + The bounding box can be specified in the following ways: + + - A `.BboxBase` instance + - A tuple of ``(left, bottom, width, height)`` in the given + transform (normalized axes coordinate if None) + - A tuple of ``(left, bottom)`` where the width and height will be + assumed to be zero. + - *None*, to remove the bbox anchoring, and use the parent bbox. + + transform : `~matplotlib.transforms.Transform`, optional + A transform to apply to the bounding box. If not specified, this + will use a transform to the bounding box of the parent. + """ + if bbox is None: + self._bbox_to_anchor = None + return + elif isinstance(bbox, BboxBase): + self._bbox_to_anchor = bbox + else: + try: + l = len(bbox) + except TypeError as err: + raise ValueError(f"Invalid bbox: {bbox}") from err + + if l == 2: + bbox = [bbox[0], bbox[1], 0, 0] + + self._bbox_to_anchor = Bbox.from_bounds(*bbox) + + if transform is None: + transform = BboxTransformTo(self.parent.bbox) + + self._bbox_to_anchor = TransformedBbox(self._bbox_to_anchor, + transform) + self.stale = True + + def _get_anchored_bbox(self, loc, bbox, parentbbox, renderer): + """ + Place the *bbox* inside the *parentbbox* according to a given + location code. Return the (x, y) coordinate of the bbox. + + Parameters + ---------- + loc : int + A location code in range(1, 11). This corresponds to the possible + values for ``self._loc``, excluding "best". + bbox : `~matplotlib.transforms.Bbox` + bbox to be placed, in display coordinates. + parentbbox : `~matplotlib.transforms.Bbox` + A parent box which will contain the bbox, in display coordinates. + """ + return offsetbox._get_anchored_bbox( + loc, bbox, parentbbox, + self.borderaxespad * renderer.points_to_pixels(self._fontsize)) + + def _find_best_position(self, width, height, renderer, consider=None): + """ + Determine the best location to place the legend. + + *consider* is a list of ``(x, y)`` pairs to consider as a potential + lower-left corner of the legend. All are display coords. + """ + assert self.isaxes # always holds, as this is only called internally + + start_time = time.perf_counter() + + bboxes, lines, offsets = self._auto_legend_data() + + bbox = Bbox.from_bounds(0, 0, width, height) + if consider is None: + consider = [self._get_anchored_bbox(x, bbox, + self.get_bbox_to_anchor(), + renderer) + for x in range(1, len(self.codes))] + + candidates = [] + for idx, (l, b) in enumerate(consider): + legendBox = Bbox.from_bounds(l, b, width, height) + badness = 0 + # XXX TODO: If markers are present, it would be good to take them + # into account when checking vertex overlaps in the next line. + badness = (sum(legendBox.count_contains(line.vertices) + for line in lines) + + legendBox.count_contains(offsets) + + legendBox.count_overlaps(bboxes) + + sum(line.intersects_bbox(legendBox, filled=False) + for line in lines)) + if badness == 0: + return l, b + # Include the index to favor lower codes in case of a tie. + candidates.append((badness, idx, (l, b))) + + _, _, (l, b) = min(candidates) + + if self._loc_used_default and time.perf_counter() - start_time > 1: + _api.warn_external( + 'Creating legend with loc="best" can be slow with large ' + 'amounts of data.') + + return l, b + + @_api.rename_parameter("3.8", "event", "mouseevent") + def contains(self, mouseevent): + return self.legendPatch.contains(mouseevent) + + def set_draggable(self, state, use_blit=False, update='loc'): + """ + Enable or disable mouse dragging support of the legend. + + Parameters + ---------- + state : bool + Whether mouse dragging is enabled. + use_blit : bool, optional + Use blitting for faster image composition. For details see + :ref:`func-animation`. + update : {'loc', 'bbox'}, optional + The legend parameter to be changed when dragged: + + - 'loc': update the *loc* parameter of the legend + - 'bbox': update the *bbox_to_anchor* parameter of the legend + + Returns + ------- + `.DraggableLegend` or *None* + If *state* is ``True`` this returns the `.DraggableLegend` helper + instance. Otherwise this returns *None*. + """ + if state: + if self._draggable is None: + self._draggable = DraggableLegend(self, + use_blit, + update=update) + else: + if self._draggable is not None: + self._draggable.disconnect() + self._draggable = None + return self._draggable + + def get_draggable(self): + """Return ``True`` if the legend is draggable, ``False`` otherwise.""" + return self._draggable is not None + + +# Helper functions to parse legend arguments for both `figure.legend` and +# `axes.legend`: +def _get_legend_handles(axs, legend_handler_map=None): + """Yield artists that can be used as handles in a legend.""" + handles_original = [] + for ax in axs: + handles_original += [ + *(a for a in ax._children + if isinstance(a, (Line2D, Patch, Collection, Text))), + *ax.containers] + # support parasite axes: + if hasattr(ax, 'parasites'): + for axx in ax.parasites: + handles_original += [ + *(a for a in axx._children + if isinstance(a, (Line2D, Patch, Collection, Text))), + *axx.containers] + + handler_map = {**Legend.get_default_handler_map(), + **(legend_handler_map or {})} + has_handler = Legend.get_legend_handler + for handle in handles_original: + label = handle.get_label() + if label != '_nolegend_' and has_handler(handler_map, handle): + yield handle + elif (label and not label.startswith('_') and + not has_handler(handler_map, handle)): + _api.warn_external( + "Legend does not support handles for " + f"{type(handle).__name__} " + "instances.\nSee: https://matplotlib.org/stable/" + "tutorials/intermediate/legend_guide.html" + "#implementing-a-custom-legend-handler") + continue + + +def _get_legend_handles_labels(axs, legend_handler_map=None): + """Return handles and labels for legend.""" + handles = [] + labels = [] + for handle in _get_legend_handles(axs, legend_handler_map): + label = handle.get_label() + if label and not label.startswith('_'): + handles.append(handle) + labels.append(label) + return handles, labels + + +def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs): + """ + Get the handles and labels from the calls to either ``figure.legend`` + or ``axes.legend``. + + The parser is a bit involved because we support:: + + legend() + legend(labels) + legend(handles, labels) + legend(labels=labels) + legend(handles=handles) + legend(handles=handles, labels=labels) + + The behavior for a mixture of positional and keyword handles and labels + is undefined and issues a warning. + + Parameters + ---------- + axs : list of `.Axes` + If handles are not given explicitly, the artists in these Axes are + used as handles. + *args : tuple + Positional parameters passed to ``legend()``. + handles + The value of the keyword argument ``legend(handles=...)``, or *None* + if that keyword argument was not used. + labels + The value of the keyword argument ``legend(labels=...)``, or *None* + if that keyword argument was not used. + **kwargs + All other keyword arguments passed to ``legend()``. + + Returns + ------- + handles : list of (`.Artist` or tuple of `.Artist`) + The legend handles. + labels : list of str + The legend labels. + kwargs : dict + *kwargs* with keywords handles and labels removed. + + """ + log = logging.getLogger(__name__) + + handlers = kwargs.get('handler_map') + + if (handles is not None or labels is not None) and args: + _api.warn_external("You have mixed positional and keyword arguments, " + "some input may be discarded.") + + # if got both handles and labels as kwargs, make same length + if handles and labels: + handles, labels = zip(*zip(handles, labels)) + + elif handles is not None and labels is None: + labels = [handle.get_label() for handle in handles] + + elif labels is not None and handles is None: + # Get as many handles as there are labels. + handles = [handle for handle, label + in zip(_get_legend_handles(axs, handlers), labels)] + + elif len(args) == 0: # 0 args: automatically detect labels and handles. + handles, labels = _get_legend_handles_labels(axs, handlers) + if not handles: + log.warning( + "No artists with labels found to put in legend. Note that " + "artists whose label start with an underscore are ignored " + "when legend() is called with no argument.") + + elif len(args) == 1: # 1 arg: user defined labels, automatic handle detection. + labels, = args + if any(isinstance(l, Artist) for l in labels): + raise TypeError("A single argument passed to legend() must be a " + "list of labels, but found an Artist in there.") + + # Get as many handles as there are labels. + handles = [handle for handle, label + in zip(_get_legend_handles(axs, handlers), labels)] + + elif len(args) == 2: # 2 args: user defined handles and labels. + handles, labels = args[:2] + + else: + raise _api.nargs_error('legend', '0-2', len(args)) + + return handles, labels, kwargs diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.pyi new file mode 100644 index 00000000..d559b06c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend.pyi @@ -0,0 +1,154 @@ +from matplotlib.axes import Axes +from matplotlib.artist import Artist +from matplotlib.backend_bases import MouseEvent +from matplotlib.figure import Figure +from matplotlib.font_manager import FontProperties +from matplotlib.legend_handler import HandlerBase +from matplotlib.lines import Line2D +from matplotlib.offsetbox import ( + DraggableOffsetBox, +) +from matplotlib.patches import FancyBboxPatch, Patch, Rectangle +from matplotlib.text import Text +from matplotlib.transforms import ( + BboxBase, + Transform, +) + + +import pathlib +from collections.abc import Iterable +from typing import Any, Literal, overload +from .typing import ColorType + +class DraggableLegend(DraggableOffsetBox): + legend: Legend + def __init__( + self, legend: Legend, use_blit: bool = ..., update: Literal["loc", "bbox"] = ... + ) -> None: ... + def finalize_offset(self) -> None: ... + +class Legend(Artist): + codes: dict[str, int] + zorder: float + prop: FontProperties + texts: list[Text] + legend_handles: list[Artist | None] + numpoints: int + markerscale: float + scatterpoints: int + borderpad: float + labelspacing: float + handlelength: float + handleheight: float + handletextpad: float + borderaxespad: float + columnspacing: float + shadow: bool + isaxes: bool + axes: Axes + parent: Axes | Figure + legendPatch: FancyBboxPatch + def __init__( + self, + parent: Axes | Figure, + handles: Iterable[Artist | tuple[Artist, ...]], + labels: Iterable[str], + *, + loc: str | tuple[float, float] | int | None = ..., + numpoints: int | None = ..., + markerscale: float | None = ..., + markerfirst: bool = ..., + reverse: bool = ..., + scatterpoints: int | None = ..., + scatteryoffsets: Iterable[float] | None = ..., + prop: FontProperties | dict[str, Any] | None = ..., + fontsize: float | str | None = ..., + labelcolor: ColorType + | Iterable[ColorType] + | Literal["linecolor", "markerfacecolor", "mfc", "markeredgecolor", "mec"] + | None = ..., + borderpad: float | None = ..., + labelspacing: float | None = ..., + handlelength: float | None = ..., + handleheight: float | None = ..., + handletextpad: float | None = ..., + borderaxespad: float | None = ..., + columnspacing: float | None = ..., + ncols: int = ..., + mode: Literal["expand"] | None = ..., + fancybox: bool | None = ..., + shadow: bool | dict[str, Any] | None = ..., + title: str | None = ..., + title_fontsize: float | None = ..., + framealpha: float | None = ..., + edgecolor: Literal["inherit"] | ColorType | None = ..., + facecolor: Literal["inherit"] | ColorType | None = ..., + bbox_to_anchor: BboxBase + | tuple[float, float] + | tuple[float, float, float, float] + | None = ..., + bbox_transform: Transform | None = ..., + frameon: bool | None = ..., + handler_map: dict[Artist | type, HandlerBase] | None = ..., + title_fontproperties: FontProperties | dict[str, Any] | None = ..., + alignment: Literal["center", "left", "right"] = ..., + ncol: int = ..., + draggable: bool = ... + ) -> None: ... + def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict[Any, Any]]: ... + def set_ncols(self, ncols: int) -> None: ... + @classmethod + def get_default_handler_map(cls) -> dict[type, HandlerBase]: ... + @classmethod + def set_default_handler_map(cls, handler_map: dict[type, HandlerBase]) -> None: ... + @classmethod + def update_default_handler_map( + cls, handler_map: dict[type, HandlerBase] + ) -> None: ... + def get_legend_handler_map(self) -> dict[type, HandlerBase]: ... + @staticmethod + def get_legend_handler( + legend_handler_map: dict[type, HandlerBase], orig_handle: Any + ) -> HandlerBase | None: ... + def get_children(self) -> list[Artist]: ... + def get_frame(self) -> Rectangle: ... + def get_lines(self) -> list[Line2D]: ... + def get_patches(self) -> list[Patch]: ... + def get_texts(self) -> list[Text]: ... + def set_alignment(self, alignment: Literal["center", "left", "right"]) -> None: ... + def get_alignment(self) -> Literal["center", "left", "right"]: ... + def set_loc(self, loc: str | tuple[float, float] | int | None = ...) -> None: ... + def set_title( + self, title: str, prop: FontProperties | str | pathlib.Path | None = ... + ) -> None: ... + def get_title(self) -> Text: ... + def get_frame_on(self) -> bool: ... + def set_frame_on(self, b: bool) -> None: ... + draw_frame = set_frame_on + def get_bbox_to_anchor(self) -> BboxBase: ... + def set_bbox_to_anchor( + self, + bbox: BboxBase + | tuple[float, float] + | tuple[float, float, float, float] + | None, + transform: Transform | None = ... + ) -> None: ... + @overload + def set_draggable( + self, + state: Literal[True], + use_blit: bool = ..., + update: Literal["loc", "bbox"] = ..., + ) -> DraggableLegend: ... + @overload + def set_draggable( + self, + state: Literal[False], + use_blit: bool = ..., + update: Literal["loc", "bbox"] = ..., + ) -> None: ... + def get_draggable(self) -> bool: ... + @property + def legendHandles(self) -> list[Artist | None]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.py new file mode 100644 index 00000000..5a929070 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.py @@ -0,0 +1,813 @@ +""" +Default legend handlers. + +.. important:: + + This is a low-level legend API, which most end users do not need. + + We recommend that you are familiar with the :ref:`legend guide + ` before reading this documentation. + +Legend handlers are expected to be a callable object with a following +signature:: + + legend_handler(legend, orig_handle, fontsize, handlebox) + +Where *legend* is the legend itself, *orig_handle* is the original +plot, *fontsize* is the fontsize in pixels, and *handlebox* is an +`.OffsetBox` instance. Within the call, you should create relevant +artists (using relevant properties from the *legend* and/or +*orig_handle*) and add them into the *handlebox*. The artists need to +be scaled according to the *fontsize* (note that the size is in pixels, +i.e., this is dpi-scaled value). + +This module includes definition of several legend handler classes +derived from the base class (HandlerBase) with the following method:: + + def legend_artist(self, legend, orig_handle, fontsize, handlebox) +""" + +from itertools import cycle + +import numpy as np + +from matplotlib import cbook +from matplotlib.lines import Line2D +from matplotlib.patches import Rectangle +import matplotlib.collections as mcoll + + +def update_from_first_child(tgt, src): + first_child = next(iter(src.get_children()), None) + if first_child is not None: + tgt.update_from(first_child) + + +class HandlerBase: + """ + A base class for default legend handlers. + + The derived classes are meant to override *create_artists* method, which + has the following signature:: + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + + The overridden method needs to create artists of the given + transform that fits in the given dimension (xdescent, ydescent, + width, height) that are scaled by fontsize if necessary. + + """ + def __init__(self, xpad=0., ypad=0., update_func=None): + """ + Parameters + ---------- + xpad : float, optional + Padding in x-direction. + ypad : float, optional + Padding in y-direction. + update_func : callable, optional + Function for updating the legend handler properties from another + legend handler, used by `~HandlerBase.update_prop`. + """ + self._xpad, self._ypad = xpad, ypad + self._update_prop_func = update_func + + def _update_prop(self, legend_handle, orig_handle): + if self._update_prop_func is None: + self._default_update_prop(legend_handle, orig_handle) + else: + self._update_prop_func(legend_handle, orig_handle) + + def _default_update_prop(self, legend_handle, orig_handle): + legend_handle.update_from(orig_handle) + + def update_prop(self, legend_handle, orig_handle, legend): + + self._update_prop(legend_handle, orig_handle) + + legend._set_artist_props(legend_handle) + legend_handle.set_clip_box(None) + legend_handle.set_clip_path(None) + + def adjust_drawing_area(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + ): + xdescent = xdescent - self._xpad * fontsize + ydescent = ydescent - self._ypad * fontsize + width = width - self._xpad * fontsize + height = height - self._ypad * fontsize + return xdescent, ydescent, width, height + + def legend_artist(self, legend, orig_handle, + fontsize, handlebox): + """ + Return the artist that this HandlerBase generates for the given + original artist/handle. + + Parameters + ---------- + legend : `~matplotlib.legend.Legend` + The legend for which these legend artists are being created. + orig_handle : :class:`matplotlib.artist.Artist` or similar + The object for which these legend artists are being created. + fontsize : int + The fontsize in pixels. The artists being created should + be scaled according to the given fontsize. + handlebox : `~matplotlib.offsetbox.OffsetBox` + The box which has been created to hold this legend entry's + artists. Artists created in the `legend_artist` method must + be added to this handlebox inside this method. + + """ + xdescent, ydescent, width, height = self.adjust_drawing_area( + legend, orig_handle, + handlebox.xdescent, handlebox.ydescent, + handlebox.width, handlebox.height, + fontsize) + artists = self.create_artists(legend, orig_handle, + xdescent, ydescent, width, height, + fontsize, handlebox.get_transform()) + + # create_artists will return a list of artists. + for a in artists: + handlebox.add_artist(a) + + # we only return the first artist + return artists[0] + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + """ + Return the legend artists generated. + + Parameters + ---------- + legend : `~matplotlib.legend.Legend` + The legend for which these legend artists are being created. + orig_handle : `~matplotlib.artist.Artist` or similar + The object for which these legend artists are being created. + xdescent, ydescent, width, height : int + The rectangle (*xdescent*, *ydescent*, *width*, *height*) that the + legend artists being created should fit within. + fontsize : int + The fontsize in pixels. The legend artists being created should + be scaled according to the given fontsize. + trans : `~matplotlib.transforms.Transform` + The transform that is applied to the legend artists being created. + Typically from unit coordinates in the handler box to screen + coordinates. + """ + raise NotImplementedError('Derived must override') + + +class HandlerNpoints(HandlerBase): + """ + A legend handler that shows *numpoints* points in the legend entry. + """ + + def __init__(self, marker_pad=0.3, numpoints=None, **kwargs): + """ + Parameters + ---------- + marker_pad : float + Padding between points in legend entry. + numpoints : int + Number of points to show in legend entry. + **kwargs + Keyword arguments forwarded to `.HandlerBase`. + """ + super().__init__(**kwargs) + + self._numpoints = numpoints + self._marker_pad = marker_pad + + def get_numpoints(self, legend): + if self._numpoints is None: + return legend.numpoints + else: + return self._numpoints + + def get_xdata(self, legend, xdescent, ydescent, width, height, fontsize): + numpoints = self.get_numpoints(legend) + if numpoints > 1: + # we put some pad here to compensate the size of the marker + pad = self._marker_pad * fontsize + xdata = np.linspace(-xdescent + pad, + -xdescent + width - pad, + numpoints) + xdata_marker = xdata + else: + xdata = [-xdescent, -xdescent + width] + xdata_marker = [-xdescent + 0.5 * width] + return xdata, xdata_marker + + +class HandlerNpointsYoffsets(HandlerNpoints): + """ + A legend handler that shows *numpoints* in the legend, and allows them to + be individually offset in the y-direction. + """ + + def __init__(self, numpoints=None, yoffsets=None, **kwargs): + """ + Parameters + ---------- + numpoints : int + Number of points to show in legend entry. + yoffsets : array of floats + Length *numpoints* list of y offsets for each point in + legend entry. + **kwargs + Keyword arguments forwarded to `.HandlerNpoints`. + """ + super().__init__(numpoints=numpoints, **kwargs) + self._yoffsets = yoffsets + + def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize): + if self._yoffsets is None: + ydata = height * legend._scatteryoffsets + else: + ydata = height * np.asarray(self._yoffsets) + + return ydata + + +class HandlerLine2DCompound(HandlerNpoints): + """ + Original handler for `.Line2D` instances, that relies on combining + a line-only with a marker-only artist. May be deprecated in the future. + """ + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + + ydata = np.full_like(xdata, ((height - ydescent) / 2)) + legline = Line2D(xdata, ydata) + + self.update_prop(legline, orig_handle, legend) + legline.set_drawstyle('default') + legline.set_marker("") + + legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)]) + self.update_prop(legline_marker, orig_handle, legend) + legline_marker.set_linestyle('None') + if legend.markerscale != 1: + newsz = legline_marker.get_markersize() * legend.markerscale + legline_marker.set_markersize(newsz) + # we don't want to add this to the return list because + # the texts and handles are assumed to be in one-to-one + # correspondence. + legline._legmarker = legline_marker + + legline.set_transform(trans) + legline_marker.set_transform(trans) + + return [legline, legline_marker] + + +class HandlerLine2D(HandlerNpoints): + """ + Handler for `.Line2D` instances. + + See Also + -------- + HandlerLine2DCompound : An earlier handler implementation, which used one + artist for the line and another for the marker(s). + """ + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + + markevery = None + if self.get_numpoints(legend) == 1: + # Special case: one wants a single marker in the center + # and a line that extends on both sides. One will use a + # 3 points line, but only mark the #1 (i.e. middle) point. + xdata = np.linspace(xdata[0], xdata[-1], 3) + markevery = [1] + + ydata = np.full_like(xdata, (height - ydescent) / 2) + legline = Line2D(xdata, ydata, markevery=markevery) + + self.update_prop(legline, orig_handle, legend) + + if legend.markerscale != 1: + newsz = legline.get_markersize() * legend.markerscale + legline.set_markersize(newsz) + + legline.set_transform(trans) + + return [legline] + + +class HandlerPatch(HandlerBase): + """ + Handler for `.Patch` instances. + """ + + def __init__(self, patch_func=None, **kwargs): + """ + Parameters + ---------- + patch_func : callable, optional + The function that creates the legend key artist. + *patch_func* should have the signature:: + + def patch_func(legend=legend, orig_handle=orig_handle, + xdescent=xdescent, ydescent=ydescent, + width=width, height=height, fontsize=fontsize) + + Subsequently, the created artist will have its ``update_prop`` + method called and the appropriate transform will be applied. + + **kwargs + Keyword arguments forwarded to `.HandlerBase`. + """ + super().__init__(**kwargs) + self._patch_func = patch_func + + def _create_patch(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize): + if self._patch_func is None: + p = Rectangle(xy=(-xdescent, -ydescent), + width=width, height=height) + else: + p = self._patch_func(legend=legend, orig_handle=orig_handle, + xdescent=xdescent, ydescent=ydescent, + width=width, height=height, fontsize=fontsize) + return p + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, trans): + # docstring inherited + p = self._create_patch(legend, orig_handle, + xdescent, ydescent, width, height, fontsize) + self.update_prop(p, orig_handle, legend) + p.set_transform(trans) + return [p] + + +class HandlerStepPatch(HandlerBase): + """ + Handler for `~.matplotlib.patches.StepPatch` instances. + """ + + @staticmethod + def _create_patch(orig_handle, xdescent, ydescent, width, height): + return Rectangle(xy=(-xdescent, -ydescent), width=width, + height=height, color=orig_handle.get_facecolor()) + + @staticmethod + def _create_line(orig_handle, width, height): + # Unfilled StepPatch should show as a line + legline = Line2D([0, width], [height/2, height/2], + color=orig_handle.get_edgecolor(), + linestyle=orig_handle.get_linestyle(), + linewidth=orig_handle.get_linewidth(), + ) + + # Overwrite manually because patch and line properties don't mix + legline.set_drawstyle('default') + legline.set_marker("") + return legline + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, trans): + # docstring inherited + if orig_handle.get_fill() or (orig_handle.get_hatch() is not None): + p = self._create_patch(orig_handle, xdescent, ydescent, width, + height) + self.update_prop(p, orig_handle, legend) + else: + p = self._create_line(orig_handle, width, height) + p.set_transform(trans) + return [p] + + +class HandlerLineCollection(HandlerLine2D): + """ + Handler for `.LineCollection` instances. + """ + def get_numpoints(self, legend): + if self._numpoints is None: + return legend.scatterpoints + else: + return self._numpoints + + def _default_update_prop(self, legend_handle, orig_handle): + lw = orig_handle.get_linewidths()[0] + dashes = orig_handle._us_linestyles[0] + color = orig_handle.get_colors()[0] + legend_handle.set_color(color) + legend_handle.set_linestyle(dashes) + legend_handle.set_linewidth(lw) + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, trans): + # docstring inherited + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + ydata = np.full_like(xdata, (height - ydescent) / 2) + legline = Line2D(xdata, ydata) + + self.update_prop(legline, orig_handle, legend) + legline.set_transform(trans) + + return [legline] + + +class HandlerRegularPolyCollection(HandlerNpointsYoffsets): + r"""Handler for `.RegularPolyCollection`\s.""" + + def __init__(self, yoffsets=None, sizes=None, **kwargs): + super().__init__(yoffsets=yoffsets, **kwargs) + + self._sizes = sizes + + def get_numpoints(self, legend): + if self._numpoints is None: + return legend.scatterpoints + else: + return self._numpoints + + def get_sizes(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize): + if self._sizes is None: + handle_sizes = orig_handle.get_sizes() + if not len(handle_sizes): + handle_sizes = [1] + size_max = max(handle_sizes) * legend.markerscale ** 2 + size_min = min(handle_sizes) * legend.markerscale ** 2 + + numpoints = self.get_numpoints(legend) + if numpoints < 4: + sizes = [.5 * (size_max + size_min), size_max, + size_min][:numpoints] + else: + rng = (size_max - size_min) + sizes = rng * np.linspace(0, 1, numpoints) + size_min + else: + sizes = self._sizes + + return sizes + + def update_prop(self, legend_handle, orig_handle, legend): + + self._update_prop(legend_handle, orig_handle) + + legend_handle.set_figure(legend.figure) + # legend._set_artist_props(legend_handle) + legend_handle.set_clip_box(None) + legend_handle.set_clip_path(None) + + def create_collection(self, orig_handle, sizes, offsets, offset_transform): + return type(orig_handle)( + orig_handle.get_numsides(), + rotation=orig_handle.get_rotation(), sizes=sizes, + offsets=offsets, offset_transform=offset_transform, + ) + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + + ydata = self.get_ydata(legend, xdescent, ydescent, + width, height, fontsize) + + sizes = self.get_sizes(legend, orig_handle, xdescent, ydescent, + width, height, fontsize) + + p = self.create_collection( + orig_handle, sizes, + offsets=list(zip(xdata_marker, ydata)), offset_transform=trans) + + self.update_prop(p, orig_handle, legend) + p.set_offset_transform(trans) + return [p] + + +class HandlerPathCollection(HandlerRegularPolyCollection): + r"""Handler for `.PathCollection`\s, which are used by `~.Axes.scatter`.""" + + def create_collection(self, orig_handle, sizes, offsets, offset_transform): + return type(orig_handle)( + [orig_handle.get_paths()[0]], sizes=sizes, + offsets=offsets, offset_transform=offset_transform, + ) + + +class HandlerCircleCollection(HandlerRegularPolyCollection): + r"""Handler for `.CircleCollection`\s.""" + + def create_collection(self, orig_handle, sizes, offsets, offset_transform): + return type(orig_handle)( + sizes, offsets=offsets, offset_transform=offset_transform) + + +class HandlerErrorbar(HandlerLine2D): + """Handler for Errorbars.""" + + def __init__(self, xerr_size=0.5, yerr_size=None, + marker_pad=0.3, numpoints=None, **kwargs): + + self._xerr_size = xerr_size + self._yerr_size = yerr_size + + super().__init__(marker_pad=marker_pad, numpoints=numpoints, **kwargs) + + def get_err_size(self, legend, xdescent, ydescent, + width, height, fontsize): + xerr_size = self._xerr_size * fontsize + + if self._yerr_size is None: + yerr_size = xerr_size + else: + yerr_size = self._yerr_size * fontsize + + return xerr_size, yerr_size + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + plotlines, caplines, barlinecols = orig_handle + + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + + ydata = np.full_like(xdata, (height - ydescent) / 2) + legline = Line2D(xdata, ydata) + + xdata_marker = np.asarray(xdata_marker) + ydata_marker = np.asarray(ydata[:len(xdata_marker)]) + + xerr_size, yerr_size = self.get_err_size(legend, xdescent, ydescent, + width, height, fontsize) + + legline_marker = Line2D(xdata_marker, ydata_marker) + + # when plotlines are None (only errorbars are drawn), we just + # make legline invisible. + if plotlines is None: + legline.set_visible(False) + legline_marker.set_visible(False) + else: + self.update_prop(legline, plotlines, legend) + + legline.set_drawstyle('default') + legline.set_marker('none') + + self.update_prop(legline_marker, plotlines, legend) + legline_marker.set_linestyle('None') + + if legend.markerscale != 1: + newsz = legline_marker.get_markersize() * legend.markerscale + legline_marker.set_markersize(newsz) + + handle_barlinecols = [] + handle_caplines = [] + + if orig_handle.has_xerr: + verts = [((x - xerr_size, y), (x + xerr_size, y)) + for x, y in zip(xdata_marker, ydata_marker)] + coll = mcoll.LineCollection(verts) + self.update_prop(coll, barlinecols[0], legend) + handle_barlinecols.append(coll) + + if caplines: + capline_left = Line2D(xdata_marker - xerr_size, ydata_marker) + capline_right = Line2D(xdata_marker + xerr_size, ydata_marker) + self.update_prop(capline_left, caplines[0], legend) + self.update_prop(capline_right, caplines[0], legend) + capline_left.set_marker("|") + capline_right.set_marker("|") + + handle_caplines.append(capline_left) + handle_caplines.append(capline_right) + + if orig_handle.has_yerr: + verts = [((x, y - yerr_size), (x, y + yerr_size)) + for x, y in zip(xdata_marker, ydata_marker)] + coll = mcoll.LineCollection(verts) + self.update_prop(coll, barlinecols[0], legend) + handle_barlinecols.append(coll) + + if caplines: + capline_left = Line2D(xdata_marker, ydata_marker - yerr_size) + capline_right = Line2D(xdata_marker, ydata_marker + yerr_size) + self.update_prop(capline_left, caplines[0], legend) + self.update_prop(capline_right, caplines[0], legend) + capline_left.set_marker("_") + capline_right.set_marker("_") + + handle_caplines.append(capline_left) + handle_caplines.append(capline_right) + + artists = [ + *handle_barlinecols, *handle_caplines, legline, legline_marker, + ] + for artist in artists: + artist.set_transform(trans) + return artists + + +class HandlerStem(HandlerNpointsYoffsets): + """ + Handler for plots produced by `~.Axes.stem`. + """ + + def __init__(self, marker_pad=0.3, numpoints=None, + bottom=None, yoffsets=None, **kwargs): + """ + Parameters + ---------- + marker_pad : float, default: 0.3 + Padding between points in legend entry. + numpoints : int, optional + Number of points to show in legend entry. + bottom : float, optional + + yoffsets : array of floats, optional + Length *numpoints* list of y offsets for each point in + legend entry. + **kwargs + Keyword arguments forwarded to `.HandlerNpointsYoffsets`. + """ + super().__init__(marker_pad=marker_pad, numpoints=numpoints, + yoffsets=yoffsets, **kwargs) + self._bottom = bottom + + def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize): + if self._yoffsets is None: + ydata = height * (0.5 * legend._scatteryoffsets + 0.5) + else: + ydata = height * np.asarray(self._yoffsets) + + return ydata + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + markerline, stemlines, baseline = orig_handle + # Check to see if the stemcontainer is storing lines as a list or a + # LineCollection. Eventually using a list will be removed, and this + # logic can also be removed. + using_linecoll = isinstance(stemlines, mcoll.LineCollection) + + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, + width, height, fontsize) + + ydata = self.get_ydata(legend, xdescent, ydescent, + width, height, fontsize) + + if self._bottom is None: + bottom = 0. + else: + bottom = self._bottom + + leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)]) + self.update_prop(leg_markerline, markerline, legend) + + leg_stemlines = [Line2D([x, x], [bottom, y]) + for x, y in zip(xdata_marker, ydata)] + + if using_linecoll: + # change the function used by update_prop() from the default + # to one that handles LineCollection + with cbook._setattr_cm( + self, _update_prop_func=self._copy_collection_props): + for line in leg_stemlines: + self.update_prop(line, stemlines, legend) + + else: + for lm, m in zip(leg_stemlines, stemlines): + self.update_prop(lm, m, legend) + + leg_baseline = Line2D([np.min(xdata), np.max(xdata)], + [bottom, bottom]) + self.update_prop(leg_baseline, baseline, legend) + + artists = [*leg_stemlines, leg_baseline, leg_markerline] + for artist in artists: + artist.set_transform(trans) + return artists + + def _copy_collection_props(self, legend_handle, orig_handle): + """ + Copy properties from the `.LineCollection` *orig_handle* to the + `.Line2D` *legend_handle*. + """ + legend_handle.set_color(orig_handle.get_color()[0]) + legend_handle.set_linestyle(orig_handle.get_linestyle()[0]) + + +class HandlerTuple(HandlerBase): + """ + Handler for Tuple. + """ + + def __init__(self, ndivide=1, pad=None, **kwargs): + """ + Parameters + ---------- + ndivide : int or None, default: 1 + The number of sections to divide the legend area into. If None, + use the length of the input tuple. + pad : float, default: :rc:`legend.borderpad` + Padding in units of fraction of font size. + **kwargs + Keyword arguments forwarded to `.HandlerBase`. + """ + self._ndivide = ndivide + self._pad = pad + super().__init__(**kwargs) + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, + trans): + # docstring inherited + handler_map = legend.get_legend_handler_map() + + if self._ndivide is None: + ndivide = len(orig_handle) + else: + ndivide = self._ndivide + + if self._pad is None: + pad = legend.borderpad * fontsize + else: + pad = self._pad * fontsize + + if ndivide > 1: + width = (width - pad * (ndivide - 1)) / ndivide + + xds_cycle = cycle(xdescent - (width + pad) * np.arange(ndivide)) + + a_list = [] + for handle1 in orig_handle: + handler = legend.get_legend_handler(handler_map, handle1) + _a_list = handler.create_artists( + legend, handle1, + next(xds_cycle), ydescent, width, height, fontsize, trans) + a_list.extend(_a_list) + + return a_list + + +class HandlerPolyCollection(HandlerBase): + """ + Handler for `.PolyCollection` used in `~.Axes.fill_between` and + `~.Axes.stackplot`. + """ + def _update_prop(self, legend_handle, orig_handle): + def first_color(colors): + if colors.size == 0: + return (0, 0, 0, 0) + return tuple(colors[0]) + + def get_first(prop_array): + if len(prop_array): + return prop_array[0] + else: + return None + + # orig_handle is a PolyCollection and legend_handle is a Patch. + # Directly set Patch color attributes (must be RGBA tuples). + legend_handle._facecolor = first_color(orig_handle.get_facecolor()) + legend_handle._edgecolor = first_color(orig_handle.get_edgecolor()) + legend_handle._original_facecolor = orig_handle._original_facecolor + legend_handle._original_edgecolor = orig_handle._original_edgecolor + legend_handle._fill = orig_handle.get_fill() + legend_handle._hatch = orig_handle.get_hatch() + # Hatch color is anomalous in having no getters and setters. + legend_handle._hatch_color = orig_handle._hatch_color + # Setters are fine for the remaining attributes. + legend_handle.set_linewidth(get_first(orig_handle.get_linewidths())) + legend_handle.set_linestyle(get_first(orig_handle.get_linestyles())) + legend_handle.set_transform(get_first(orig_handle.get_transforms())) + legend_handle.set_figure(orig_handle.get_figure()) + # Alpha is already taken into account by the color attributes. + + def create_artists(self, legend, orig_handle, + xdescent, ydescent, width, height, fontsize, trans): + # docstring inherited + p = Rectangle(xy=(-xdescent, -ydescent), + width=width, height=height) + self.update_prop(p, orig_handle, legend) + p.set_transform(trans) + return [p] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.pyi new file mode 100644 index 00000000..db028a13 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/legend_handler.pyi @@ -0,0 +1,294 @@ +from collections.abc import Callable, Sequence +from matplotlib.artist import Artist +from matplotlib.legend import Legend +from matplotlib.offsetbox import OffsetBox +from matplotlib.transforms import Transform + +from typing import TypeVar + +from numpy.typing import ArrayLike + +def update_from_first_child(tgt: Artist, src: Artist) -> None: ... + +class HandlerBase: + def __init__( + self, + xpad: float = ..., + ypad: float = ..., + update_func: Callable[[Artist, Artist], None] | None = ..., + ) -> None: ... + def update_prop( + self, legend_handle: Artist, orig_handle: Artist, legend: Legend + ) -> None: ... + def adjust_drawing_area( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> tuple[float, float, float, float]: ... + def legend_artist( + self, legend: Legend, orig_handle: Artist, fontsize: float, handlebox: OffsetBox + ) -> Artist: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerNpoints(HandlerBase): + def __init__( + self, marker_pad: float = ..., numpoints: int | None = ..., **kwargs + ) -> None: ... + def get_numpoints(self, legend: Legend) -> int | None: ... + def get_xdata( + self, + legend: Legend, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> tuple[ArrayLike, ArrayLike]: ... + +class HandlerNpointsYoffsets(HandlerNpoints): + def __init__( + self, + numpoints: int | None = ..., + yoffsets: Sequence[float] | None = ..., + **kwargs + ) -> None: ... + def get_ydata( + self, + legend: Legend, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> ArrayLike: ... + +class HandlerLine2DCompound(HandlerNpoints): + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerLine2D(HandlerNpoints): + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerPatch(HandlerBase): + def __init__(self, patch_func: Callable | None = ..., **kwargs) -> None: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerStepPatch(HandlerBase): + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerLineCollection(HandlerLine2D): + def get_numpoints(self, legend: Legend) -> int: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +_T = TypeVar("_T", bound=Artist) + +class HandlerRegularPolyCollection(HandlerNpointsYoffsets): + def __init__( + self, + yoffsets: Sequence[float] | None = ..., + sizes: Sequence[float] | None = ..., + **kwargs + ) -> None: ... + def get_numpoints(self, legend: Legend) -> int: ... + def get_sizes( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> Sequence[float]: ... + def update_prop( + self, legend_handle, orig_handle: Artist, legend: Legend + ) -> None: ... + def create_collection( + self, + orig_handle: _T, + sizes: Sequence[float] | None, + offsets: Sequence[float] | None, + offset_transform: Transform, + ) -> _T: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerPathCollection(HandlerRegularPolyCollection): + def create_collection( + self, + orig_handle: _T, + sizes: Sequence[float] | None, + offsets: Sequence[float] | None, + offset_transform: Transform, + ) -> _T: ... + +class HandlerCircleCollection(HandlerRegularPolyCollection): + def create_collection( + self, + orig_handle: _T, + sizes: Sequence[float] | None, + offsets: Sequence[float] | None, + offset_transform: Transform, + ) -> _T: ... + +class HandlerErrorbar(HandlerLine2D): + def __init__( + self, + xerr_size: float = ..., + yerr_size: float | None = ..., + marker_pad: float = ..., + numpoints: int | None = ..., + **kwargs + ) -> None: ... + def get_err_size( + self, + legend: Legend, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> tuple[float, float]: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerStem(HandlerNpointsYoffsets): + def __init__( + self, + marker_pad: float = ..., + numpoints: int | None = ..., + bottom: float | None = ..., + yoffsets: Sequence[float] | None = ..., + **kwargs + ) -> None: ... + def get_ydata( + self, + legend: Legend, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + ) -> ArrayLike: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerTuple(HandlerBase): + def __init__( + self, ndivide: int | None = ..., pad: float | None = ..., **kwargs + ) -> None: ... + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... + +class HandlerPolyCollection(HandlerBase): + def create_artists( + self, + legend: Legend, + orig_handle: Artist, + xdescent: float, + ydescent: float, + width: float, + height: float, + fontsize: float, + trans: Transform, + ) -> Sequence[Artist]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.py new file mode 100644 index 00000000..92d55a3f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.py @@ -0,0 +1,1677 @@ +""" +2D lines with support for a variety of line styles, markers, colors, etc. +""" + +import copy + +from numbers import Integral, Number, Real +import logging + +import numpy as np + +import matplotlib as mpl +from . import _api, cbook, colors as mcolors, _docstring +from .artist import Artist, allow_rasterization +from .cbook import ( + _to_unmasked_float_array, ls_mapper, ls_mapper_r, STEP_LOOKUP_MAP) +from .markers import MarkerStyle +from .path import Path +from .transforms import Bbox, BboxTransformTo, TransformedPath +from ._enums import JoinStyle, CapStyle + +# Imported here for backward compatibility, even though they don't +# really belong. +from . import _path +from .markers import ( # noqa + CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN, + CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE, + TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN) + +_log = logging.getLogger(__name__) + + +def _get_dash_pattern(style): + """Convert linestyle to dash pattern.""" + # go from short hand -> full strings + if isinstance(style, str): + style = ls_mapper.get(style, style) + # un-dashed styles + if style in ['solid', 'None']: + offset = 0 + dashes = None + # dashed styles + elif style in ['dashed', 'dashdot', 'dotted']: + offset = 0 + dashes = tuple(mpl.rcParams[f'lines.{style}_pattern']) + # + elif isinstance(style, tuple): + offset, dashes = style + if offset is None: + raise ValueError(f'Unrecognized linestyle: {style!r}') + else: + raise ValueError(f'Unrecognized linestyle: {style!r}') + + # normalize offset to be positive and shorter than the dash cycle + if dashes is not None: + dsum = sum(dashes) + if dsum: + offset %= dsum + + return offset, dashes + + +def _get_inverse_dash_pattern(offset, dashes): + """Return the inverse of the given dash pattern, for filling the gaps.""" + # Define the inverse pattern by moving the last gap to the start of the + # sequence. + gaps = dashes[-1:] + dashes[:-1] + # Set the offset so that this new first segment is skipped + # (see backend_bases.GraphicsContextBase.set_dashes for offset definition). + offset_gaps = offset + dashes[-1] + + return offset_gaps, gaps + + +def _scale_dashes(offset, dashes, lw): + if not mpl.rcParams['lines.scale_dashes']: + return offset, dashes + scaled_offset = offset * lw + scaled_dashes = ([x * lw if x is not None else None for x in dashes] + if dashes is not None else None) + return scaled_offset, scaled_dashes + + +def segment_hits(cx, cy, x, y, radius): + """ + Return the indices of the segments in the polyline with coordinates (*cx*, + *cy*) that are within a distance *radius* of the point (*x*, *y*). + """ + # Process single points specially + if len(x) <= 1: + res, = np.nonzero((cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2) + return res + + # We need to lop the last element off a lot. + xr, yr = x[:-1], y[:-1] + + # Only look at line segments whose nearest point to C on the line + # lies within the segment. + dx, dy = x[1:] - xr, y[1:] - yr + Lnorm_sq = dx ** 2 + dy ** 2 # Possibly want to eliminate Lnorm==0 + u = ((cx - xr) * dx + (cy - yr) * dy) / Lnorm_sq + candidates = (u >= 0) & (u <= 1) + + # Note that there is a little area near one side of each point + # which will be near neither segment, and another which will + # be near both, depending on the angle of the lines. The + # following radius test eliminates these ambiguities. + point_hits = (cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2 + candidates = candidates & ~(point_hits[:-1] | point_hits[1:]) + + # For those candidates which remain, determine how far they lie away + # from the line. + px, py = xr + u * dx, yr + u * dy + line_hits = (cx - px) ** 2 + (cy - py) ** 2 <= radius ** 2 + line_hits = line_hits & candidates + points, = point_hits.ravel().nonzero() + lines, = line_hits.ravel().nonzero() + return np.concatenate((points, lines)) + + +def _mark_every_path(markevery, tpath, affine, ax): + """ + Helper function that sorts out how to deal the input + `markevery` and returns the points where markers should be drawn. + + Takes in the `markevery` value and the line path and returns the + sub-sampled path. + """ + # pull out the two bits of data we want from the path + codes, verts = tpath.codes, tpath.vertices + + def _slice_or_none(in_v, slc): + """Helper function to cope with `codes` being an ndarray or `None`.""" + if in_v is None: + return None + return in_v[slc] + + # if just an int, assume starting at 0 and make a tuple + if isinstance(markevery, Integral): + markevery = (0, markevery) + # if just a float, assume starting at 0.0 and make a tuple + elif isinstance(markevery, Real): + markevery = (0.0, markevery) + + if isinstance(markevery, tuple): + if len(markevery) != 2: + raise ValueError('`markevery` is a tuple but its len is not 2; ' + f'markevery={markevery}') + start, step = markevery + # if step is an int, old behavior + if isinstance(step, Integral): + # tuple of 2 int is for backwards compatibility, + if not isinstance(start, Integral): + raise ValueError( + '`markevery` is a tuple with len 2 and second element is ' + 'an int, but the first element is not an int; ' + f'markevery={markevery}') + # just return, we are done here + + return Path(verts[slice(start, None, step)], + _slice_or_none(codes, slice(start, None, step))) + + elif isinstance(step, Real): + if not isinstance(start, Real): + raise ValueError( + '`markevery` is a tuple with len 2 and second element is ' + 'a float, but the first element is not a float or an int; ' + f'markevery={markevery}') + if ax is None: + raise ValueError( + "markevery is specified relative to the axes size, but " + "the line does not have a Axes as parent") + + # calc cumulative distance along path (in display coords): + fin = np.isfinite(verts).all(axis=1) + fverts = verts[fin] + disp_coords = affine.transform(fverts) + + delta = np.empty((len(disp_coords), 2)) + delta[0, :] = 0 + delta[1:, :] = disp_coords[1:, :] - disp_coords[:-1, :] + delta = np.hypot(*delta.T).cumsum() + # calc distance between markers along path based on the axes + # bounding box diagonal being a distance of unity: + (x0, y0), (x1, y1) = ax.transAxes.transform([[0, 0], [1, 1]]) + scale = np.hypot(x1 - x0, y1 - y0) + marker_delta = np.arange(start * scale, delta[-1], step * scale) + # find closest actual data point that is closest to + # the theoretical distance along the path: + inds = np.abs(delta[np.newaxis, :] - marker_delta[:, np.newaxis]) + inds = inds.argmin(axis=1) + inds = np.unique(inds) + # return, we are done here + return Path(fverts[inds], _slice_or_none(codes, inds)) + else: + raise ValueError( + f"markevery={markevery!r} is a tuple with len 2, but its " + f"second element is not an int or a float") + + elif isinstance(markevery, slice): + # mazol tov, it's already a slice, just return + return Path(verts[markevery], _slice_or_none(codes, markevery)) + + elif np.iterable(markevery): + # fancy indexing + try: + return Path(verts[markevery], _slice_or_none(codes, markevery)) + except (ValueError, IndexError) as err: + raise ValueError( + f"markevery={markevery!r} is iterable but not a valid numpy " + f"fancy index") from err + else: + raise ValueError(f"markevery={markevery!r} is not a recognized value") + + +@_docstring.interpd +@_api.define_aliases({ + "antialiased": ["aa"], + "color": ["c"], + "drawstyle": ["ds"], + "linestyle": ["ls"], + "linewidth": ["lw"], + "markeredgecolor": ["mec"], + "markeredgewidth": ["mew"], + "markerfacecolor": ["mfc"], + "markerfacecoloralt": ["mfcalt"], + "markersize": ["ms"], +}) +class Line2D(Artist): + """ + A line - the line can have both a solid linestyle connecting all + the vertices, and a marker at each vertex. Additionally, the + drawing of the solid line is influenced by the drawstyle, e.g., one + can create "stepped" lines in various styles. + """ + + lineStyles = _lineStyles = { # hidden names deprecated + '-': '_draw_solid', + '--': '_draw_dashed', + '-.': '_draw_dash_dot', + ':': '_draw_dotted', + 'None': '_draw_nothing', + ' ': '_draw_nothing', + '': '_draw_nothing', + } + + _drawStyles_l = { + 'default': '_draw_lines', + 'steps-mid': '_draw_steps_mid', + 'steps-pre': '_draw_steps_pre', + 'steps-post': '_draw_steps_post', + } + + _drawStyles_s = { + 'steps': '_draw_steps_pre', + } + + # drawStyles should now be deprecated. + drawStyles = {**_drawStyles_l, **_drawStyles_s} + # Need a list ordered with long names first: + drawStyleKeys = [*_drawStyles_l, *_drawStyles_s] + + # Referenced here to maintain API. These are defined in + # MarkerStyle + markers = MarkerStyle.markers + filled_markers = MarkerStyle.filled_markers + fillStyles = MarkerStyle.fillstyles + + zorder = 2 + + _subslice_optim_min_size = 1000 + + def __str__(self): + if self._label != "": + return f"Line2D({self._label})" + elif self._x is None: + return "Line2D()" + elif len(self._x) > 3: + return "Line2D(({:g},{:g}),({:g},{:g}),...,({:g},{:g}))".format( + self._x[0], self._y[0], + self._x[1], self._y[1], + self._x[-1], self._y[-1]) + else: + return "Line2D(%s)" % ",".join( + map("({:g},{:g})".format, self._x, self._y)) + + def __init__(self, xdata, ydata, *, + linewidth=None, # all Nones default to rc + linestyle=None, + color=None, + gapcolor=None, + marker=None, + markersize=None, + markeredgewidth=None, + markeredgecolor=None, + markerfacecolor=None, + markerfacecoloralt='none', + fillstyle=None, + antialiased=None, + dash_capstyle=None, + solid_capstyle=None, + dash_joinstyle=None, + solid_joinstyle=None, + pickradius=5, + drawstyle=None, + markevery=None, + **kwargs + ): + """ + Create a `.Line2D` instance with *x* and *y* data in sequences of + *xdata*, *ydata*. + + Additional keyword arguments are `.Line2D` properties: + + %(Line2D:kwdoc)s + + See :meth:`set_linestyle` for a description of the line styles, + :meth:`set_marker` for a description of the markers, and + :meth:`set_drawstyle` for a description of the draw styles. + + """ + super().__init__() + + # Convert sequences to NumPy arrays. + if not np.iterable(xdata): + raise RuntimeError('xdata must be a sequence') + if not np.iterable(ydata): + raise RuntimeError('ydata must be a sequence') + + if linewidth is None: + linewidth = mpl.rcParams['lines.linewidth'] + + if linestyle is None: + linestyle = mpl.rcParams['lines.linestyle'] + if marker is None: + marker = mpl.rcParams['lines.marker'] + if color is None: + color = mpl.rcParams['lines.color'] + + if markersize is None: + markersize = mpl.rcParams['lines.markersize'] + if antialiased is None: + antialiased = mpl.rcParams['lines.antialiased'] + if dash_capstyle is None: + dash_capstyle = mpl.rcParams['lines.dash_capstyle'] + if dash_joinstyle is None: + dash_joinstyle = mpl.rcParams['lines.dash_joinstyle'] + if solid_capstyle is None: + solid_capstyle = mpl.rcParams['lines.solid_capstyle'] + if solid_joinstyle is None: + solid_joinstyle = mpl.rcParams['lines.solid_joinstyle'] + + if drawstyle is None: + drawstyle = 'default' + + self._dashcapstyle = None + self._dashjoinstyle = None + self._solidjoinstyle = None + self._solidcapstyle = None + self.set_dash_capstyle(dash_capstyle) + self.set_dash_joinstyle(dash_joinstyle) + self.set_solid_capstyle(solid_capstyle) + self.set_solid_joinstyle(solid_joinstyle) + + self._linestyles = None + self._drawstyle = None + self._linewidth = linewidth + self._unscaled_dash_pattern = (0, None) # offset, dash + self._dash_pattern = (0, None) # offset, dash (scaled by linewidth) + + self.set_linewidth(linewidth) + self.set_linestyle(linestyle) + self.set_drawstyle(drawstyle) + + self._color = None + self.set_color(color) + if marker is None: + marker = 'none' # Default. + if not isinstance(marker, MarkerStyle): + self._marker = MarkerStyle(marker, fillstyle) + else: + self._marker = marker + + self._gapcolor = None + self.set_gapcolor(gapcolor) + + self._markevery = None + self._markersize = None + self._antialiased = None + + self.set_markevery(markevery) + self.set_antialiased(antialiased) + self.set_markersize(markersize) + + self._markeredgecolor = None + self._markeredgewidth = None + self._markerfacecolor = None + self._markerfacecoloralt = None + + self.set_markerfacecolor(markerfacecolor) # Normalizes None to rc. + self.set_markerfacecoloralt(markerfacecoloralt) + self.set_markeredgecolor(markeredgecolor) # Normalizes None to rc. + self.set_markeredgewidth(markeredgewidth) + + # update kwargs before updating data to give the caller a + # chance to init axes (and hence unit support) + self._internal_update(kwargs) + self.pickradius = pickradius + self.ind_offset = 0 + if (isinstance(self._picker, Number) and + not isinstance(self._picker, bool)): + self._pickradius = self._picker + + self._xorig = np.asarray([]) + self._yorig = np.asarray([]) + self._invalidx = True + self._invalidy = True + self._x = None + self._y = None + self._xy = None + self._path = None + self._transformed_path = None + self._subslice = False + self._x_filled = None # used in subslicing; only x is needed + + self.set_data(xdata, ydata) + + def contains(self, mouseevent): + """ + Test whether *mouseevent* occurred on the line. + + An event is deemed to have occurred "on" the line if it is less + than ``self.pickradius`` (default: 5 points) away from it. Use + `~.Line2D.get_pickradius` or `~.Line2D.set_pickradius` to get or set + the pick radius. + + Parameters + ---------- + mouseevent : `~matplotlib.backend_bases.MouseEvent` + + Returns + ------- + contains : bool + Whether any values are within the radius. + details : dict + A dictionary ``{'ind': pointlist}``, where *pointlist* is a + list of points of the line that are within the pickradius around + the event position. + + TODO: sort returned indices by distance + """ + if self._different_canvas(mouseevent): + return False, {} + + # Make sure we have data to plot + if self._invalidy or self._invalidx: + self.recache() + if len(self._xy) == 0: + return False, {} + + # Convert points to pixels + transformed_path = self._get_transformed_path() + path, affine = transformed_path.get_transformed_path_and_affine() + path = affine.transform_path(path) + xy = path.vertices + xt = xy[:, 0] + yt = xy[:, 1] + + # Convert pick radius from points to pixels + if self.figure is None: + _log.warning('no figure set when check if mouse is on line') + pixels = self._pickradius + else: + pixels = self.figure.dpi / 72. * self._pickradius + + # The math involved in checking for containment (here and inside of + # segment_hits) assumes that it is OK to overflow, so temporarily set + # the error flags accordingly. + with np.errstate(all='ignore'): + # Check for collision + if self._linestyle in ['None', None]: + # If no line, return the nearby point(s) + ind, = np.nonzero( + (xt - mouseevent.x) ** 2 + (yt - mouseevent.y) ** 2 + <= pixels ** 2) + else: + # If line, return the nearby segment(s) + ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels) + if self._drawstyle.startswith("steps"): + ind //= 2 + + ind += self.ind_offset + + # Return the point(s) within radius + return len(ind) > 0, dict(ind=ind) + + def get_pickradius(self): + """ + Return the pick radius used for containment tests. + + See `.contains` for more details. + """ + return self._pickradius + + def set_pickradius(self, pickradius): + """ + Set the pick radius used for containment tests. + + See `.contains` for more details. + + Parameters + ---------- + pickradius : float + Pick radius, in points. + """ + if not isinstance(pickradius, Real) or pickradius < 0: + raise ValueError("pick radius should be a distance") + self._pickradius = pickradius + + pickradius = property(get_pickradius, set_pickradius) + + def get_fillstyle(self): + """ + Return the marker fill style. + + See also `~.Line2D.set_fillstyle`. + """ + return self._marker.get_fillstyle() + + def set_fillstyle(self, fs): + """ + Set the marker fill style. + + Parameters + ---------- + fs : {'full', 'left', 'right', 'bottom', 'top', 'none'} + Possible values: + + - 'full': Fill the whole marker with the *markerfacecolor*. + - 'left', 'right', 'bottom', 'top': Fill the marker half at + the given side with the *markerfacecolor*. The other + half of the marker is filled with *markerfacecoloralt*. + - 'none': No filling. + + For examples see :ref:`marker_fill_styles`. + """ + self.set_marker(MarkerStyle(self._marker.get_marker(), fs)) + self.stale = True + + def set_markevery(self, every): + """ + Set the markevery property to subsample the plot when using markers. + + e.g., if ``every=5``, every 5-th marker will be plotted. + + Parameters + ---------- + every : None or int or (int, int) or slice or list[int] or float or \ +(float, float) or list[bool] + Which markers to plot. + + - ``every=None``: every point will be plotted. + - ``every=N``: every N-th marker will be plotted starting with + marker 0. + - ``every=(start, N)``: every N-th marker, starting at index + *start*, will be plotted. + - ``every=slice(start, end, N)``: every N-th marker, starting at + index *start*, up to but not including index *end*, will be + plotted. + - ``every=[i, j, m, ...]``: only markers at the given indices + will be plotted. + - ``every=[True, False, True, ...]``: only positions that are True + will be plotted. The list must have the same length as the data + points. + - ``every=0.1``, (i.e. a float): markers will be spaced at + approximately equal visual distances along the line; the distance + along the line between markers is determined by multiplying the + display-coordinate distance of the axes bounding-box diagonal + by the value of *every*. + - ``every=(0.5, 0.1)`` (i.e. a length-2 tuple of float): similar + to ``every=0.1`` but the first marker will be offset along the + line by 0.5 multiplied by the + display-coordinate-diagonal-distance along the line. + + For examples see + :doc:`/gallery/lines_bars_and_markers/markevery_demo`. + + Notes + ----- + Setting *markevery* will still only draw markers at actual data points. + While the float argument form aims for uniform visual spacing, it has + to coerce from the ideal spacing to the nearest available data point. + Depending on the number and distribution of data points, the result + may still not look evenly spaced. + + When using a start offset to specify the first marker, the offset will + be from the first data point which may be different from the first + the visible data point if the plot is zoomed in. + + If zooming in on a plot when using float arguments then the actual + data points that have markers will change because the distance between + markers is always determined from the display-coordinates + axes-bounding-box-diagonal regardless of the actual axes data limits. + + """ + self._markevery = every + self.stale = True + + def get_markevery(self): + """ + Return the markevery setting for marker subsampling. + + See also `~.Line2D.set_markevery`. + """ + return self._markevery + + def set_picker(self, p): + """ + Set the event picker details for the line. + + Parameters + ---------- + p : float or callable[[Artist, Event], tuple[bool, dict]] + If a float, it is used as the pick radius in points. + """ + if not callable(p): + self.set_pickradius(p) + self._picker = p + + def get_bbox(self): + """Get the bounding box of this line.""" + bbox = Bbox([[0, 0], [0, 0]]) + bbox.update_from_data_xy(self.get_xydata()) + return bbox + + def get_window_extent(self, renderer=None): + bbox = Bbox([[0, 0], [0, 0]]) + trans_data_to_xy = self.get_transform().transform + bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()), + ignore=True) + # correct for marker size, if any + if self._marker: + ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5 + bbox = bbox.padded(ms) + return bbox + + def set_data(self, *args): + """ + Set the x and y data. + + Parameters + ---------- + *args : (2, N) array or two 1D arrays + """ + if len(args) == 1: + (x, y), = args + else: + x, y = args + + self.set_xdata(x) + self.set_ydata(y) + + def recache_always(self): + self.recache(always=True) + + def recache(self, always=False): + if always or self._invalidx: + xconv = self.convert_xunits(self._xorig) + x = _to_unmasked_float_array(xconv).ravel() + else: + x = self._x + if always or self._invalidy: + yconv = self.convert_yunits(self._yorig) + y = _to_unmasked_float_array(yconv).ravel() + else: + y = self._y + + self._xy = np.column_stack(np.broadcast_arrays(x, y)).astype(float) + self._x, self._y = self._xy.T # views + + self._subslice = False + if (self.axes + and len(x) > self._subslice_optim_min_size + and _path.is_sorted_and_has_non_nan(x) + and self.axes.name == 'rectilinear' + and self.axes.get_xscale() == 'linear' + and self._markevery is None + and self.get_clip_on() + and self.get_transform() == self.axes.transData): + self._subslice = True + nanmask = np.isnan(x) + if nanmask.any(): + self._x_filled = self._x.copy() + indices = np.arange(len(x)) + self._x_filled[nanmask] = np.interp( + indices[nanmask], indices[~nanmask], self._x[~nanmask]) + else: + self._x_filled = self._x + + if self._path is not None: + interpolation_steps = self._path._interpolation_steps + else: + interpolation_steps = 1 + xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy.T) + self._path = Path(np.asarray(xy).T, + _interpolation_steps=interpolation_steps) + self._transformed_path = None + self._invalidx = False + self._invalidy = False + + def _transform_path(self, subslice=None): + """ + Put a TransformedPath instance at self._transformed_path; + all invalidation of the transform is then handled by the + TransformedPath instance. + """ + # Masked arrays are now handled by the Path class itself + if subslice is not None: + xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy[subslice, :].T) + _path = Path(np.asarray(xy).T, + _interpolation_steps=self._path._interpolation_steps) + else: + _path = self._path + self._transformed_path = TransformedPath(_path, self.get_transform()) + + def _get_transformed_path(self): + """Return this line's `~matplotlib.transforms.TransformedPath`.""" + if self._transformed_path is None: + self._transform_path() + return self._transformed_path + + def set_transform(self, t): + # docstring inherited + self._invalidx = True + self._invalidy = True + super().set_transform(t) + + @allow_rasterization + def draw(self, renderer): + # docstring inherited + + if not self.get_visible(): + return + + if self._invalidy or self._invalidx: + self.recache() + self.ind_offset = 0 # Needed for contains() method. + if self._subslice and self.axes: + x0, x1 = self.axes.get_xbound() + i0 = self._x_filled.searchsorted(x0, 'left') + i1 = self._x_filled.searchsorted(x1, 'right') + subslice = slice(max(i0 - 1, 0), i1 + 1) + self.ind_offset = subslice.start + self._transform_path(subslice) + else: + subslice = None + + if self.get_path_effects(): + from matplotlib.patheffects import PathEffectRenderer + renderer = PathEffectRenderer(self.get_path_effects(), renderer) + + renderer.open_group('line2d', self.get_gid()) + if self._lineStyles[self._linestyle] != '_draw_nothing': + tpath, affine = (self._get_transformed_path() + .get_transformed_path_and_affine()) + if len(tpath.vertices): + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_url(self.get_url()) + + gc.set_antialiased(self._antialiased) + gc.set_linewidth(self._linewidth) + + if self.is_dashed(): + cap = self._dashcapstyle + join = self._dashjoinstyle + else: + cap = self._solidcapstyle + join = self._solidjoinstyle + gc.set_joinstyle(join) + gc.set_capstyle(cap) + gc.set_snap(self.get_snap()) + if self.get_sketch_params() is not None: + gc.set_sketch_params(*self.get_sketch_params()) + + # We first draw a path within the gaps if needed. + if self.is_dashed() and self._gapcolor is not None: + lc_rgba = mcolors.to_rgba(self._gapcolor, self._alpha) + gc.set_foreground(lc_rgba, isRGBA=True) + + offset_gaps, gaps = _get_inverse_dash_pattern( + *self._dash_pattern) + + gc.set_dashes(offset_gaps, gaps) + renderer.draw_path(gc, tpath, affine.frozen()) + + lc_rgba = mcolors.to_rgba(self._color, self._alpha) + gc.set_foreground(lc_rgba, isRGBA=True) + + gc.set_dashes(*self._dash_pattern) + renderer.draw_path(gc, tpath, affine.frozen()) + gc.restore() + + if self._marker and self._markersize > 0: + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_url(self.get_url()) + gc.set_linewidth(self._markeredgewidth) + gc.set_antialiased(self._antialiased) + + ec_rgba = mcolors.to_rgba( + self.get_markeredgecolor(), self._alpha) + fc_rgba = mcolors.to_rgba( + self._get_markerfacecolor(), self._alpha) + fcalt_rgba = mcolors.to_rgba( + self._get_markerfacecolor(alt=True), self._alpha) + # If the edgecolor is "auto", it is set according to the *line* + # color but inherits the alpha value of the *face* color, if any. + if (cbook._str_equal(self._markeredgecolor, "auto") + and not cbook._str_lower_equal( + self.get_markerfacecolor(), "none")): + ec_rgba = ec_rgba[:3] + (fc_rgba[3],) + gc.set_foreground(ec_rgba, isRGBA=True) + if self.get_sketch_params() is not None: + scale, length, randomness = self.get_sketch_params() + gc.set_sketch_params(scale/2, length/2, 2*randomness) + + marker = self._marker + + # Markers *must* be drawn ignoring the drawstyle (but don't pay the + # recaching if drawstyle is already "default"). + if self.get_drawstyle() != "default": + with cbook._setattr_cm( + self, _drawstyle="default", _transformed_path=None): + self.recache() + self._transform_path(subslice) + tpath, affine = (self._get_transformed_path() + .get_transformed_points_and_affine()) + else: + tpath, affine = (self._get_transformed_path() + .get_transformed_points_and_affine()) + + if len(tpath.vertices): + # subsample the markers if markevery is not None + markevery = self.get_markevery() + if markevery is not None: + subsampled = _mark_every_path( + markevery, tpath, affine, self.axes) + else: + subsampled = tpath + + snap = marker.get_snap_threshold() + if isinstance(snap, Real): + snap = renderer.points_to_pixels(self._markersize) >= snap + gc.set_snap(snap) + gc.set_joinstyle(marker.get_joinstyle()) + gc.set_capstyle(marker.get_capstyle()) + marker_path = marker.get_path() + marker_trans = marker.get_transform() + w = renderer.points_to_pixels(self._markersize) + + if cbook._str_equal(marker.get_marker(), ","): + gc.set_linewidth(0) + else: + # Don't scale for pixels, and don't stroke them + marker_trans = marker_trans.scale(w) + renderer.draw_markers(gc, marker_path, marker_trans, + subsampled, affine.frozen(), + fc_rgba) + + alt_marker_path = marker.get_alt_path() + if alt_marker_path: + alt_marker_trans = marker.get_alt_transform() + alt_marker_trans = alt_marker_trans.scale(w) + renderer.draw_markers( + gc, alt_marker_path, alt_marker_trans, subsampled, + affine.frozen(), fcalt_rgba) + + gc.restore() + + renderer.close_group('line2d') + self.stale = False + + def get_antialiased(self): + """Return whether antialiased rendering is used.""" + return self._antialiased + + def get_color(self): + """ + Return the line color. + + See also `~.Line2D.set_color`. + """ + return self._color + + def get_drawstyle(self): + """ + Return the drawstyle. + + See also `~.Line2D.set_drawstyle`. + """ + return self._drawstyle + + def get_gapcolor(self): + """ + Return the line gapcolor. + + See also `~.Line2D.set_gapcolor`. + """ + return self._gapcolor + + def get_linestyle(self): + """ + Return the linestyle. + + See also `~.Line2D.set_linestyle`. + """ + return self._linestyle + + def get_linewidth(self): + """ + Return the linewidth in points. + + See also `~.Line2D.set_linewidth`. + """ + return self._linewidth + + def get_marker(self): + """ + Return the line marker. + + See also `~.Line2D.set_marker`. + """ + return self._marker.get_marker() + + def get_markeredgecolor(self): + """ + Return the marker edge color. + + See also `~.Line2D.set_markeredgecolor`. + """ + mec = self._markeredgecolor + if cbook._str_equal(mec, 'auto'): + if mpl.rcParams['_internal.classic_mode']: + if self._marker.get_marker() in ('.', ','): + return self._color + if (self._marker.is_filled() + and self._marker.get_fillstyle() != 'none'): + return 'k' # Bad hard-wired default... + return self._color + else: + return mec + + def get_markeredgewidth(self): + """ + Return the marker edge width in points. + + See also `~.Line2D.set_markeredgewidth`. + """ + return self._markeredgewidth + + def _get_markerfacecolor(self, alt=False): + if self._marker.get_fillstyle() == 'none': + return 'none' + fc = self._markerfacecoloralt if alt else self._markerfacecolor + if cbook._str_lower_equal(fc, 'auto'): + return self._color + else: + return fc + + def get_markerfacecolor(self): + """ + Return the marker face color. + + See also `~.Line2D.set_markerfacecolor`. + """ + return self._get_markerfacecolor(alt=False) + + def get_markerfacecoloralt(self): + """ + Return the alternate marker face color. + + See also `~.Line2D.set_markerfacecoloralt`. + """ + return self._get_markerfacecolor(alt=True) + + def get_markersize(self): + """ + Return the marker size in points. + + See also `~.Line2D.set_markersize`. + """ + return self._markersize + + def get_data(self, orig=True): + """ + Return the line data as an ``(xdata, ydata)`` pair. + + If *orig* is *True*, return the original data. + """ + return self.get_xdata(orig=orig), self.get_ydata(orig=orig) + + def get_xdata(self, orig=True): + """ + Return the xdata. + + If *orig* is *True*, return the original data, else the + processed data. + """ + if orig: + return self._xorig + if self._invalidx: + self.recache() + return self._x + + def get_ydata(self, orig=True): + """ + Return the ydata. + + If *orig* is *True*, return the original data, else the + processed data. + """ + if orig: + return self._yorig + if self._invalidy: + self.recache() + return self._y + + def get_path(self): + """Return the `~matplotlib.path.Path` associated with this line.""" + if self._invalidy or self._invalidx: + self.recache() + return self._path + + def get_xydata(self): + """Return the *xy* data as a (N, 2) array.""" + if self._invalidy or self._invalidx: + self.recache() + return self._xy + + def set_antialiased(self, b): + """ + Set whether to use antialiased rendering. + + Parameters + ---------- + b : bool + """ + if self._antialiased != b: + self.stale = True + self._antialiased = b + + def set_color(self, color): + """ + Set the color of the line. + + Parameters + ---------- + color : color + """ + mcolors._check_color_like(color=color) + self._color = color + self.stale = True + + def set_drawstyle(self, drawstyle): + """ + Set the drawstyle of the plot. + + The drawstyle determines how the points are connected. + + Parameters + ---------- + drawstyle : {'default', 'steps', 'steps-pre', 'steps-mid', \ +'steps-post'}, default: 'default' + For 'default', the points are connected with straight lines. + + The steps variants connect the points with step-like lines, + i.e. horizontal lines with vertical steps. They differ in the + location of the step: + + - 'steps-pre': The step is at the beginning of the line segment, + i.e. the line will be at the y-value of point to the right. + - 'steps-mid': The step is halfway between the points. + - 'steps-post: The step is at the end of the line segment, + i.e. the line will be at the y-value of the point to the left. + - 'steps' is equal to 'steps-pre' and is maintained for + backward-compatibility. + + For examples see :doc:`/gallery/lines_bars_and_markers/step_demo`. + """ + if drawstyle is None: + drawstyle = 'default' + _api.check_in_list(self.drawStyles, drawstyle=drawstyle) + if self._drawstyle != drawstyle: + self.stale = True + # invalidate to trigger a recache of the path + self._invalidx = True + self._drawstyle = drawstyle + + def set_gapcolor(self, gapcolor): + """ + Set a color to fill the gaps in the dashed line style. + + .. note:: + + Striped lines are created by drawing two interleaved dashed lines. + There can be overlaps between those two, which may result in + artifacts when using transparency. + + This functionality is experimental and may change. + + Parameters + ---------- + gapcolor : color or None + The color with which to fill the gaps. If None, the gaps are + unfilled. + """ + if gapcolor is not None: + mcolors._check_color_like(color=gapcolor) + self._gapcolor = gapcolor + self.stale = True + + def set_linewidth(self, w): + """ + Set the line width in points. + + Parameters + ---------- + w : float + Line width, in points. + """ + w = float(w) + if self._linewidth != w: + self.stale = True + self._linewidth = w + self._dash_pattern = _scale_dashes(*self._unscaled_dash_pattern, w) + + def set_linestyle(self, ls): + """ + Set the linestyle of the line. + + Parameters + ---------- + ls : {'-', '--', '-.', ':', '', (offset, on-off-seq), ...} + Possible values: + + - A string: + + ========================================== ================= + linestyle description + ========================================== ================= + ``'-'`` or ``'solid'`` solid line + ``'--'`` or ``'dashed'`` dashed line + ``'-.'`` or ``'dashdot'`` dash-dotted line + ``':'`` or ``'dotted'`` dotted line + ``'none'``, ``'None'``, ``' '``, or ``''`` draw nothing + ========================================== ================= + + - Alternatively a dash tuple of the following form can be + provided:: + + (offset, onoffseq) + + where ``onoffseq`` is an even length tuple of on and off ink + in points. See also :meth:`set_dashes`. + + For examples see :doc:`/gallery/lines_bars_and_markers/linestyles`. + """ + if isinstance(ls, str): + if ls in [' ', '', 'none']: + ls = 'None' + _api.check_in_list([*self._lineStyles, *ls_mapper_r], ls=ls) + if ls not in self._lineStyles: + ls = ls_mapper_r[ls] + self._linestyle = ls + else: + self._linestyle = '--' + self._unscaled_dash_pattern = _get_dash_pattern(ls) + self._dash_pattern = _scale_dashes( + *self._unscaled_dash_pattern, self._linewidth) + self.stale = True + + @_docstring.interpd + def set_marker(self, marker): + """ + Set the line marker. + + Parameters + ---------- + marker : marker style string, `~.path.Path` or `~.markers.MarkerStyle` + See `~matplotlib.markers` for full description of possible + arguments. + """ + self._marker = MarkerStyle(marker, self._marker.get_fillstyle()) + self.stale = True + + def _set_markercolor(self, name, has_rcdefault, val): + if val is None: + val = mpl.rcParams[f"lines.{name}"] if has_rcdefault else "auto" + attr = f"_{name}" + current = getattr(self, attr) + if current is None: + self.stale = True + else: + neq = current != val + # Much faster than `np.any(current != val)` if no arrays are used. + if neq.any() if isinstance(neq, np.ndarray) else neq: + self.stale = True + setattr(self, attr, val) + + def set_markeredgecolor(self, ec): + """ + Set the marker edge color. + + Parameters + ---------- + ec : color + """ + self._set_markercolor("markeredgecolor", True, ec) + + def set_markerfacecolor(self, fc): + """ + Set the marker face color. + + Parameters + ---------- + fc : color + """ + self._set_markercolor("markerfacecolor", True, fc) + + def set_markerfacecoloralt(self, fc): + """ + Set the alternate marker face color. + + Parameters + ---------- + fc : color + """ + self._set_markercolor("markerfacecoloralt", False, fc) + + def set_markeredgewidth(self, ew): + """ + Set the marker edge width in points. + + Parameters + ---------- + ew : float + Marker edge width, in points. + """ + if ew is None: + ew = mpl.rcParams['lines.markeredgewidth'] + if self._markeredgewidth != ew: + self.stale = True + self._markeredgewidth = ew + + def set_markersize(self, sz): + """ + Set the marker size in points. + + Parameters + ---------- + sz : float + Marker size, in points. + """ + sz = float(sz) + if self._markersize != sz: + self.stale = True + self._markersize = sz + + def set_xdata(self, x): + """ + Set the data array for x. + + Parameters + ---------- + x : 1D array + """ + if not np.iterable(x): + # When deprecation cycle is completed + # raise RuntimeError('x must be a sequence') + _api.warn_deprecated( + since="3.7", + message="Setting data with a non sequence type " + "is deprecated since %(since)s and will be " + "remove %(removal)s") + x = [x, ] + self._xorig = copy.copy(x) + self._invalidx = True + self.stale = True + + def set_ydata(self, y): + """ + Set the data array for y. + + Parameters + ---------- + y : 1D array + """ + if not np.iterable(y): + # When deprecation cycle is completed + # raise RuntimeError('y must be a sequence') + _api.warn_deprecated( + since="3.7", + message="Setting data with a non sequence type " + "is deprecated since %(since)s and will be " + "remove %(removal)s") + y = [y, ] + self._yorig = copy.copy(y) + self._invalidy = True + self.stale = True + + def set_dashes(self, seq): + """ + Set the dash sequence. + + The dash sequence is a sequence of floats of even length describing + the length of dashes and spaces in points. + + For example, (5, 2, 1, 2) describes a sequence of 5 point and 1 point + dashes separated by 2 point spaces. + + See also `~.Line2D.set_gapcolor`, which allows those spaces to be + filled with a color. + + Parameters + ---------- + seq : sequence of floats (on/off ink in points) or (None, None) + If *seq* is empty or ``(None, None)``, the linestyle will be set + to solid. + """ + if seq == (None, None) or len(seq) == 0: + self.set_linestyle('-') + else: + self.set_linestyle((0, seq)) + + def update_from(self, other): + """Copy properties from *other* to self.""" + super().update_from(other) + self._linestyle = other._linestyle + self._linewidth = other._linewidth + self._color = other._color + self._gapcolor = other._gapcolor + self._markersize = other._markersize + self._markerfacecolor = other._markerfacecolor + self._markerfacecoloralt = other._markerfacecoloralt + self._markeredgecolor = other._markeredgecolor + self._markeredgewidth = other._markeredgewidth + self._unscaled_dash_pattern = other._unscaled_dash_pattern + self._dash_pattern = other._dash_pattern + self._dashcapstyle = other._dashcapstyle + self._dashjoinstyle = other._dashjoinstyle + self._solidcapstyle = other._solidcapstyle + self._solidjoinstyle = other._solidjoinstyle + + self._linestyle = other._linestyle + self._marker = MarkerStyle(marker=other._marker) + self._drawstyle = other._drawstyle + + @_docstring.interpd + def set_dash_joinstyle(self, s): + """ + How to join segments of the line if it `~Line2D.is_dashed`. + + The default joinstyle is :rc:`lines.dash_joinstyle`. + + Parameters + ---------- + s : `.JoinStyle` or %(JoinStyle)s + """ + js = JoinStyle(s) + if self._dashjoinstyle != js: + self.stale = True + self._dashjoinstyle = js + + @_docstring.interpd + def set_solid_joinstyle(self, s): + """ + How to join segments if the line is solid (not `~Line2D.is_dashed`). + + The default joinstyle is :rc:`lines.solid_joinstyle`. + + Parameters + ---------- + s : `.JoinStyle` or %(JoinStyle)s + """ + js = JoinStyle(s) + if self._solidjoinstyle != js: + self.stale = True + self._solidjoinstyle = js + + def get_dash_joinstyle(self): + """ + Return the `.JoinStyle` for dashed lines. + + See also `~.Line2D.set_dash_joinstyle`. + """ + return self._dashjoinstyle.name + + def get_solid_joinstyle(self): + """ + Return the `.JoinStyle` for solid lines. + + See also `~.Line2D.set_solid_joinstyle`. + """ + return self._solidjoinstyle.name + + @_docstring.interpd + def set_dash_capstyle(self, s): + """ + How to draw the end caps if the line is `~Line2D.is_dashed`. + + The default capstyle is :rc:`lines.dash_capstyle`. + + Parameters + ---------- + s : `.CapStyle` or %(CapStyle)s + """ + cs = CapStyle(s) + if self._dashcapstyle != cs: + self.stale = True + self._dashcapstyle = cs + + @_docstring.interpd + def set_solid_capstyle(self, s): + """ + How to draw the end caps if the line is solid (not `~Line2D.is_dashed`) + + The default capstyle is :rc:`lines.solid_capstyle`. + + Parameters + ---------- + s : `.CapStyle` or %(CapStyle)s + """ + cs = CapStyle(s) + if self._solidcapstyle != cs: + self.stale = True + self._solidcapstyle = cs + + def get_dash_capstyle(self): + """ + Return the `.CapStyle` for dashed lines. + + See also `~.Line2D.set_dash_capstyle`. + """ + return self._dashcapstyle.name + + def get_solid_capstyle(self): + """ + Return the `.CapStyle` for solid lines. + + See also `~.Line2D.set_solid_capstyle`. + """ + return self._solidcapstyle.name + + def is_dashed(self): + """ + Return whether line has a dashed linestyle. + + A custom linestyle is assumed to be dashed, we do not inspect the + ``onoffseq`` directly. + + See also `~.Line2D.set_linestyle`. + """ + return self._linestyle in ('--', '-.', ':') + + +class AxLine(Line2D): + """ + A helper class that implements `~.Axes.axline`, by recomputing the artist + transform at draw time. + """ + + def __init__(self, xy1, xy2, slope, **kwargs): + """ + Parameters + ---------- + xy1 : (float, float) + The first set of (x, y) coordinates for the line to pass through. + xy2 : (float, float) or None + The second set of (x, y) coordinates for the line to pass through. + Either *xy2* or *slope* has to be given. + slope : float or None + The slope of the line. Either *xy2* or *slope* has to be given. + """ + super().__init__([0, 1], [0, 1], **kwargs) + + if (xy2 is None and slope is None or + xy2 is not None and slope is not None): + raise TypeError( + "Exactly one of 'xy2' and 'slope' must be given") + + self._slope = slope + self._xy1 = xy1 + self._xy2 = xy2 + + def get_transform(self): + ax = self.axes + points_transform = self._transform - ax.transData + ax.transScale + + if self._xy2 is not None: + # two points were given + (x1, y1), (x2, y2) = \ + points_transform.transform([self._xy1, self._xy2]) + dx = x2 - x1 + dy = y2 - y1 + if np.allclose(x1, x2): + if np.allclose(y1, y2): + raise ValueError( + f"Cannot draw a line through two identical points " + f"(x={(x1, x2)}, y={(y1, y2)})") + slope = np.inf + else: + slope = dy / dx + else: + # one point and a slope were given + x1, y1 = points_transform.transform(self._xy1) + slope = self._slope + (vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim) + # General case: find intersections with view limits in either + # direction, and draw between the middle two points. + if np.isclose(slope, 0): + start = vxlo, y1 + stop = vxhi, y1 + elif np.isinf(slope): + start = x1, vylo + stop = x1, vyhi + else: + _, start, stop, _ = sorted([ + (vxlo, y1 + (vxlo - x1) * slope), + (vxhi, y1 + (vxhi - x1) * slope), + (x1 + (vylo - y1) / slope, vylo), + (x1 + (vyhi - y1) / slope, vyhi), + ]) + return (BboxTransformTo(Bbox([start, stop])) + + ax.transLimits + ax.transAxes) + + def draw(self, renderer): + self._transformed_path = None # Force regen. + super().draw(renderer) + + def get_xy1(self): + """ + Return the *xy1* value of the line. + """ + return self._xy1 + + def get_xy2(self): + """ + Return the *xy2* value of the line. + """ + return self._xy2 + + def get_slope(self): + """ + Return the *slope* value of the line. + """ + return self._slope + + def set_xy1(self, x, y): + """ + Set the *xy1* value of the line. + + Parameters + ---------- + x, y : float + Points for the line to pass through. + """ + self._xy1 = x, y + + def set_xy2(self, x, y): + """ + Set the *xy2* value of the line. + + Parameters + ---------- + x, y : float + Points for the line to pass through. + """ + if self._slope is None: + self._xy2 = x, y + else: + raise ValueError("Cannot set an 'xy2' value while 'slope' is set;" + " they differ but their functionalities overlap") + + def set_slope(self, slope): + """ + Set the *slope* value of the line. + + Parameters + ---------- + slope : float + The slope of the line. + """ + if self._xy2 is None: + self._slope = slope + else: + raise ValueError("Cannot set a 'slope' value while 'xy2' is set;" + " they differ but their functionalities overlap") + + +class VertexSelector: + """ + Manage the callbacks to maintain a list of selected vertices for `.Line2D`. + Derived classes should override the `process_selected` method to do + something with the picks. + + Here is an example which highlights the selected verts with red circles:: + + import numpy as np + import matplotlib.pyplot as plt + import matplotlib.lines as lines + + class HighlightSelected(lines.VertexSelector): + def __init__(self, line, fmt='ro', **kwargs): + super().__init__(line) + self.markers, = self.axes.plot([], [], fmt, **kwargs) + + def process_selected(self, ind, xs, ys): + self.markers.set_data(xs, ys) + self.canvas.draw() + + fig, ax = plt.subplots() + x, y = np.random.rand(2, 30) + line, = ax.plot(x, y, 'bs-', picker=5) + + selector = HighlightSelected(line) + plt.show() + """ + + def __init__(self, line): + """ + Parameters + ---------- + line : `~matplotlib.lines.Line2D` + The line must already have been added to an `~.axes.Axes` and must + have its picker property set. + """ + if line.axes is None: + raise RuntimeError('You must first add the line to the Axes') + if line.get_picker() is None: + raise RuntimeError('You must first set the picker property ' + 'of the line') + self.axes = line.axes + self.line = line + self.cid = self.canvas.callbacks._connect_picklable( + 'pick_event', self.onpick) + self.ind = set() + + canvas = property(lambda self: self.axes.figure.canvas) + + def process_selected(self, ind, xs, ys): + """ + Default "do nothing" implementation of the `process_selected` method. + + Parameters + ---------- + ind : list of int + The indices of the selected vertices. + xs, ys : array-like + The coordinates of the selected vertices. + """ + pass + + def onpick(self, event): + """When the line is picked, update the set of selected indices.""" + if event.artist is not self.line: + return + self.ind ^= set(event.ind) + ind = sorted(self.ind) + xdata, ydata = self.line.get_data() + self.process_selected(ind, xdata[ind], ydata[ind]) + + +lineStyles = Line2D._lineStyles +lineMarkers = MarkerStyle.markers +drawStyles = Line2D.drawStyles +fillStyles = MarkerStyle.fillstyles diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.pyi new file mode 100644 index 00000000..c91e457e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/lines.pyi @@ -0,0 +1,153 @@ +from .artist import Artist +from .axes import Axes +from .backend_bases import MouseEvent, FigureCanvasBase +from .path import Path +from .transforms import Bbox, Transform + +from collections.abc import Callable, Sequence +from typing import Any, Literal, overload +from .typing import ( + ColorType, + DrawStyleType, + FillStyleType, + LineStyleType, + CapStyleType, + JoinStyleType, + MarkEveryType, + MarkerType, +) +from numpy.typing import ArrayLike + +def segment_hits( + cx: ArrayLike, cy: ArrayLike, x: ArrayLike, y: ArrayLike, radius: ArrayLike +) -> ArrayLike: ... + +class Line2D(Artist): + lineStyles: dict[str, str] + drawStyles: dict[str, str] + drawStyleKeys: list[str] + markers: dict[str | int, str] + filled_markers: tuple[str, ...] + fillStyles: tuple[str, ...] + zorder: float + ind_offset: float + def __init__( + self, + xdata: ArrayLike, + ydata: ArrayLike, + *, + linewidth: float | None = ..., + linestyle: LineStyleType | None = ..., + color: ColorType | None = ..., + gapcolor: ColorType | None = ..., + marker: MarkerType | None = ..., + markersize: float | None = ..., + markeredgewidth: float | None = ..., + markeredgecolor: ColorType | None = ..., + markerfacecolor: ColorType | None = ..., + markerfacecoloralt: ColorType = ..., + fillstyle: FillStyleType | None = ..., + antialiased: bool | None = ..., + dash_capstyle: CapStyleType | None = ..., + solid_capstyle: CapStyleType | None = ..., + dash_joinstyle: JoinStyleType | None = ..., + solid_joinstyle: JoinStyleType | None = ..., + pickradius: float = ..., + drawstyle: DrawStyleType | None = ..., + markevery: MarkEveryType | None = ..., + **kwargs + ) -> None: ... + def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict]: ... + def get_pickradius(self) -> float: ... + def set_pickradius(self, pickradius: float) -> None: ... + pickradius: float + def get_fillstyle(self) -> FillStyleType: ... + stale: bool + def set_fillstyle(self, fs: FillStyleType) -> None: ... + def set_markevery(self, every: MarkEveryType) -> None: ... + def get_markevery(self) -> MarkEveryType: ... + def set_picker( + self, p: None | bool | float | Callable[[Artist, MouseEvent], tuple[bool, dict]] + ) -> None: ... + def get_bbox(self) -> Bbox: ... + @overload + def set_data(self, args: ArrayLike) -> None: ... + @overload + def set_data(self, x: ArrayLike, y: ArrayLike) -> None: ... + def recache_always(self) -> None: ... + def recache(self, always: bool = ...) -> None: ... + def get_antialiased(self) -> bool: ... + def get_color(self) -> ColorType: ... + def get_drawstyle(self) -> DrawStyleType: ... + def get_gapcolor(self) -> ColorType: ... + def get_linestyle(self) -> LineStyleType: ... + def get_linewidth(self) -> float: ... + def get_marker(self) -> MarkerType: ... + def get_markeredgecolor(self) -> ColorType: ... + def get_markeredgewidth(self) -> float: ... + def get_markerfacecolor(self) -> ColorType: ... + def get_markerfacecoloralt(self) -> ColorType: ... + def get_markersize(self) -> float: ... + def get_data(self, orig: bool = ...) -> tuple[ArrayLike, ArrayLike]: ... + def get_xdata(self, orig: bool = ...) -> ArrayLike: ... + def get_ydata(self, orig: bool = ...) -> ArrayLike: ... + def get_path(self) -> Path: ... + def get_xydata(self) -> ArrayLike: ... + def set_antialiased(self, b: bool) -> None: ... + def set_color(self, color: ColorType) -> None: ... + def set_drawstyle(self, drawstyle: DrawStyleType | None) -> None: ... + def set_gapcolor(self, gapcolor: ColorType | None) -> None: ... + def set_linewidth(self, w: float) -> None: ... + def set_linestyle(self, ls: LineStyleType) -> None: ... + def set_marker(self, marker: MarkerType) -> None: ... + def set_markeredgecolor(self, ec: ColorType | None) -> None: ... + def set_markerfacecolor(self, fc: ColorType | None) -> None: ... + def set_markerfacecoloralt(self, fc: ColorType | None) -> None: ... + def set_markeredgewidth(self, ew: float | None) -> None: ... + def set_markersize(self, sz: float) -> None: ... + def set_xdata(self, x: ArrayLike) -> None: ... + def set_ydata(self, y: ArrayLike) -> None: ... + def set_dashes(self, seq: Sequence[float] | tuple[None, None]) -> None: ... + def update_from(self, other: Artist) -> None: ... + def set_dash_joinstyle(self, s: JoinStyleType) -> None: ... + def set_solid_joinstyle(self, s: JoinStyleType) -> None: ... + def get_dash_joinstyle(self) -> Literal["miter", "round", "bevel"]: ... + def get_solid_joinstyle(self) -> Literal["miter", "round", "bevel"]: ... + def set_dash_capstyle(self, s: CapStyleType) -> None: ... + def set_solid_capstyle(self, s: CapStyleType) -> None: ... + def get_dash_capstyle(self) -> Literal["butt", "projecting", "round"]: ... + def get_solid_capstyle(self) -> Literal["butt", "projecting", "round"]: ... + def is_dashed(self) -> bool: ... + +class AxLine(Line2D): + def __init__( + self, + xy1: tuple[float, float], + xy2: tuple[float, float] | None, + slope: float | None, + **kwargs + ) -> None: ... + def get_xy1(self) -> tuple[float, float] | None: ... + def get_xy2(self) -> tuple[float, float] | None: ... + def get_slope(self) -> float: ... + def set_xy1(self, x: float, y: float) -> None: ... + def set_xy2(self, x: float, y: float) -> None: ... + def set_slope(self, slope: float) -> None: ... + +class VertexSelector: + axes: Axes + line: Line2D + cid: int + ind: set[int] + def __init__(self, line: Line2D) -> None: ... + @property + def canvas(self) -> FigureCanvasBase: ... + def process_selected( + self, ind: Sequence[int], xs: ArrayLike, ys: ArrayLike + ) -> None: ... + def onpick(self, event: Any) -> None: ... + +lineStyles: dict[str, str] +lineMarkers: dict[str | int, str] +drawStyles: dict[str, str] +fillStyles: tuple[FillStyleType, ...] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.py new file mode 100644 index 00000000..e7096e66 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.py @@ -0,0 +1,917 @@ +r""" +Functions to handle markers; used by the marker functionality of +`~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`, and +`~matplotlib.axes.Axes.errorbar`. + +All possible markers are defined here: + +============================== ====== ========================================= +marker symbol description +============================== ====== ========================================= +``"."`` |m00| point +``","`` |m01| pixel +``"o"`` |m02| circle +``"v"`` |m03| triangle_down +``"^"`` |m04| triangle_up +``"<"`` |m05| triangle_left +``">"`` |m06| triangle_right +``"1"`` |m07| tri_down +``"2"`` |m08| tri_up +``"3"`` |m09| tri_left +``"4"`` |m10| tri_right +``"8"`` |m11| octagon +``"s"`` |m12| square +``"p"`` |m13| pentagon +``"P"`` |m23| plus (filled) +``"*"`` |m14| star +``"h"`` |m15| hexagon1 +``"H"`` |m16| hexagon2 +``"+"`` |m17| plus +``"x"`` |m18| x +``"X"`` |m24| x (filled) +``"D"`` |m19| diamond +``"d"`` |m20| thin_diamond +``"|"`` |m21| vline +``"_"`` |m22| hline +``0`` (``TICKLEFT``) |m25| tickleft +``1`` (``TICKRIGHT``) |m26| tickright +``2`` (``TICKUP``) |m27| tickup +``3`` (``TICKDOWN``) |m28| tickdown +``4`` (``CARETLEFT``) |m29| caretleft +``5`` (``CARETRIGHT``) |m30| caretright +``6`` (``CARETUP``) |m31| caretup +``7`` (``CARETDOWN``) |m32| caretdown +``8`` (``CARETLEFTBASE``) |m33| caretleft (centered at base) +``9`` (``CARETRIGHTBASE``) |m34| caretright (centered at base) +``10`` (``CARETUPBASE``) |m35| caretup (centered at base) +``11`` (``CARETDOWNBASE``) |m36| caretdown (centered at base) +``"none"`` or ``"None"`` nothing +``" "`` or ``""`` nothing +``'$...$'`` |m37| Render the string using mathtext. + E.g ``"$f$"`` for marker showing the + letter ``f``. +``verts`` A list of (x, y) pairs used for Path + vertices. The center of the marker is + located at (0, 0) and the size is + normalized, such that the created path + is encapsulated inside the unit cell. +path A `~matplotlib.path.Path` instance. +``(numsides, 0, angle)`` A regular polygon with ``numsides`` + sides, rotated by ``angle``. +``(numsides, 1, angle)`` A star-like symbol with ``numsides`` + sides, rotated by ``angle``. +``(numsides, 2, angle)`` An asterisk with ``numsides`` sides, + rotated by ``angle``. +============================== ====== ========================================= + +As a deprecated feature, ``None`` also means 'nothing' when directly +constructing a `.MarkerStyle`, but note that there are other contexts where +``marker=None`` instead means "the default marker" (e.g. :rc:`scatter.marker` +for `.Axes.scatter`). + +Note that special symbols can be defined via the +:ref:`STIX math font `, +e.g. ``"$\u266B$"``. For an overview over the STIX font symbols refer to the +`STIX font table `_. +Also see the :doc:`/gallery/text_labels_and_annotations/stix_fonts_demo`. + +Integer numbers from ``0`` to ``11`` create lines and triangles. Those are +equally accessible via capitalized variables, like ``CARETDOWNBASE``. +Hence the following are equivalent:: + + plt.plot([1, 2, 3], marker=11) + plt.plot([1, 2, 3], marker=matplotlib.markers.CARETDOWNBASE) + +Markers join and cap styles can be customized by creating a new instance of +MarkerStyle. +A MarkerStyle can also have a custom `~matplotlib.transforms.Transform` +allowing it to be arbitrarily rotated or offset. + +Examples showing the use of markers: + +* :doc:`/gallery/lines_bars_and_markers/marker_reference` +* :doc:`/gallery/lines_bars_and_markers/scatter_star_poly` +* :doc:`/gallery/lines_bars_and_markers/multivariate_marker_plot` + +.. |m00| image:: /_static/markers/m00.png +.. |m01| image:: /_static/markers/m01.png +.. |m02| image:: /_static/markers/m02.png +.. |m03| image:: /_static/markers/m03.png +.. |m04| image:: /_static/markers/m04.png +.. |m05| image:: /_static/markers/m05.png +.. |m06| image:: /_static/markers/m06.png +.. |m07| image:: /_static/markers/m07.png +.. |m08| image:: /_static/markers/m08.png +.. |m09| image:: /_static/markers/m09.png +.. |m10| image:: /_static/markers/m10.png +.. |m11| image:: /_static/markers/m11.png +.. |m12| image:: /_static/markers/m12.png +.. |m13| image:: /_static/markers/m13.png +.. |m14| image:: /_static/markers/m14.png +.. |m15| image:: /_static/markers/m15.png +.. |m16| image:: /_static/markers/m16.png +.. |m17| image:: /_static/markers/m17.png +.. |m18| image:: /_static/markers/m18.png +.. |m19| image:: /_static/markers/m19.png +.. |m20| image:: /_static/markers/m20.png +.. |m21| image:: /_static/markers/m21.png +.. |m22| image:: /_static/markers/m22.png +.. |m23| image:: /_static/markers/m23.png +.. |m24| image:: /_static/markers/m24.png +.. |m25| image:: /_static/markers/m25.png +.. |m26| image:: /_static/markers/m26.png +.. |m27| image:: /_static/markers/m27.png +.. |m28| image:: /_static/markers/m28.png +.. |m29| image:: /_static/markers/m29.png +.. |m30| image:: /_static/markers/m30.png +.. |m31| image:: /_static/markers/m31.png +.. |m32| image:: /_static/markers/m32.png +.. |m33| image:: /_static/markers/m33.png +.. |m34| image:: /_static/markers/m34.png +.. |m35| image:: /_static/markers/m35.png +.. |m36| image:: /_static/markers/m36.png +.. |m37| image:: /_static/markers/m37.png +""" +import copy + +from collections.abc import Sized + +import numpy as np + +import matplotlib as mpl +from . import _api, cbook +from .path import Path +from .transforms import IdentityTransform, Affine2D +from ._enums import JoinStyle, CapStyle + +# special-purpose marker identifiers: +(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN, + CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN, + CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE) = range(12) + +_empty_path = Path(np.empty((0, 2))) + + +class MarkerStyle: + """ + A class representing marker types. + + Instances are immutable. If you need to change anything, create a new + instance. + + Attributes + ---------- + markers : dict + All known markers. + filled_markers : tuple + All known filled markers. This is a subset of *markers*. + fillstyles : tuple + The supported fillstyles. + """ + + markers = { + '.': 'point', + ',': 'pixel', + 'o': 'circle', + 'v': 'triangle_down', + '^': 'triangle_up', + '<': 'triangle_left', + '>': 'triangle_right', + '1': 'tri_down', + '2': 'tri_up', + '3': 'tri_left', + '4': 'tri_right', + '8': 'octagon', + 's': 'square', + 'p': 'pentagon', + '*': 'star', + 'h': 'hexagon1', + 'H': 'hexagon2', + '+': 'plus', + 'x': 'x', + 'D': 'diamond', + 'd': 'thin_diamond', + '|': 'vline', + '_': 'hline', + 'P': 'plus_filled', + 'X': 'x_filled', + TICKLEFT: 'tickleft', + TICKRIGHT: 'tickright', + TICKUP: 'tickup', + TICKDOWN: 'tickdown', + CARETLEFT: 'caretleft', + CARETRIGHT: 'caretright', + CARETUP: 'caretup', + CARETDOWN: 'caretdown', + CARETLEFTBASE: 'caretleftbase', + CARETRIGHTBASE: 'caretrightbase', + CARETUPBASE: 'caretupbase', + CARETDOWNBASE: 'caretdownbase', + "None": 'nothing', + "none": 'nothing', + ' ': 'nothing', + '': 'nothing' + } + + # Just used for informational purposes. is_filled() + # is calculated in the _set_* functions. + filled_markers = ( + '.', 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', + 'P', 'X') + + fillstyles = ('full', 'left', 'right', 'bottom', 'top', 'none') + _half_fillstyles = ('left', 'right', 'bottom', 'top') + + def __init__(self, marker, + fillstyle=None, transform=None, capstyle=None, joinstyle=None): + """ + Parameters + ---------- + marker : str, array-like, Path, MarkerStyle, or None + - Another instance of *MarkerStyle* copies the details of that + ``marker``. + - *None* means no marker. This is the deprecated default. + - For other possible marker values, see the module docstring + `matplotlib.markers`. + + fillstyle : str, default: :rc:`markers.fillstyle` + One of 'full', 'left', 'right', 'bottom', 'top', 'none'. + + transform : transforms.Transform, default: None + Transform that will be combined with the native transform of the + marker. + + capstyle : `.CapStyle` or %(CapStyle)s, default: None + Cap style that will override the default cap style of the marker. + + joinstyle : `.JoinStyle` or %(JoinStyle)s, default: None + Join style that will override the default join style of the marker. + """ + self._marker_function = None + self._user_transform = transform + self._user_capstyle = CapStyle(capstyle) if capstyle is not None else None + self._user_joinstyle = JoinStyle(joinstyle) if joinstyle is not None else None + self._set_fillstyle(fillstyle) + self._set_marker(marker) + + def _recache(self): + if self._marker_function is None: + return + self._path = _empty_path + self._transform = IdentityTransform() + self._alt_path = None + self._alt_transform = None + self._snap_threshold = None + self._joinstyle = JoinStyle.round + self._capstyle = self._user_capstyle or CapStyle.butt + # Initial guess: Assume the marker is filled unless the fillstyle is + # set to 'none'. The marker function will override this for unfilled + # markers. + self._filled = self._fillstyle != 'none' + self._marker_function() + + def __bool__(self): + return bool(len(self._path.vertices)) + + def is_filled(self): + return self._filled + + def get_fillstyle(self): + return self._fillstyle + + def _set_fillstyle(self, fillstyle): + """ + Set the fillstyle. + + Parameters + ---------- + fillstyle : {'full', 'left', 'right', 'bottom', 'top', 'none'} + The part of the marker surface that is colored with + markerfacecolor. + """ + if fillstyle is None: + fillstyle = mpl.rcParams['markers.fillstyle'] + _api.check_in_list(self.fillstyles, fillstyle=fillstyle) + self._fillstyle = fillstyle + + def get_joinstyle(self): + return self._joinstyle.name + + def get_capstyle(self): + return self._capstyle.name + + def get_marker(self): + return self._marker + + def _set_marker(self, marker): + """ + Set the marker. + + Parameters + ---------- + marker : str, array-like, Path, MarkerStyle, or None, default: None + - Another instance of *MarkerStyle* copies the details of that + ``marker``. + - *None* means no marker. + - For other possible marker values see the module docstring + `matplotlib.markers`. + """ + if isinstance(marker, str) and cbook.is_math_text(marker): + self._marker_function = self._set_mathtext_path + elif isinstance(marker, (int, str)) and marker in self.markers: + self._marker_function = getattr(self, '_set_' + self.markers[marker]) + elif (isinstance(marker, np.ndarray) and marker.ndim == 2 and + marker.shape[1] == 2): + self._marker_function = self._set_vertices + elif isinstance(marker, Path): + self._marker_function = self._set_path_marker + elif (isinstance(marker, Sized) and len(marker) in (2, 3) and + marker[1] in (0, 1, 2)): + self._marker_function = self._set_tuple_marker + elif isinstance(marker, MarkerStyle): + self.__dict__ = copy.deepcopy(marker.__dict__) + else: + try: + Path(marker) + self._marker_function = self._set_vertices + except ValueError as err: + raise ValueError( + f'Unrecognized marker style {marker!r}') from err + + if not isinstance(marker, MarkerStyle): + self._marker = marker + self._recache() + + def get_path(self): + """ + Return a `.Path` for the primary part of the marker. + + For unfilled markers this is the whole marker, for filled markers, + this is the area to be drawn with *markerfacecolor*. + """ + return self._path + + def get_transform(self): + """ + Return the transform to be applied to the `.Path` from + `MarkerStyle.get_path()`. + """ + if self._user_transform is None: + return self._transform.frozen() + else: + return (self._transform + self._user_transform).frozen() + + def get_alt_path(self): + """ + Return a `.Path` for the alternate part of the marker. + + For unfilled markers, this is *None*; for filled markers, this is the + area to be drawn with *markerfacecoloralt*. + """ + return self._alt_path + + def get_alt_transform(self): + """ + Return the transform to be applied to the `.Path` from + `MarkerStyle.get_alt_path()`. + """ + if self._user_transform is None: + return self._alt_transform.frozen() + else: + return (self._alt_transform + self._user_transform).frozen() + + def get_snap_threshold(self): + return self._snap_threshold + + def get_user_transform(self): + """Return user supplied part of marker transform.""" + if self._user_transform is not None: + return self._user_transform.frozen() + + def transformed(self, transform: Affine2D): + """ + Return a new version of this marker with the transform applied. + + Parameters + ---------- + transform : `~matplotlib.transforms.Affine2D`, default: None + Transform will be combined with current user supplied transform. + """ + new_marker = MarkerStyle(self) + if new_marker._user_transform is not None: + new_marker._user_transform += transform + else: + new_marker._user_transform = transform + return new_marker + + def rotated(self, *, deg=None, rad=None): + """ + Return a new version of this marker rotated by specified angle. + + Parameters + ---------- + deg : float, default: None + Rotation angle in degrees. + + rad : float, default: None + Rotation angle in radians. + + .. note:: You must specify exactly one of deg or rad. + """ + if deg is None and rad is None: + raise ValueError('One of deg or rad is required') + if deg is not None and rad is not None: + raise ValueError('Only one of deg and rad can be supplied') + new_marker = MarkerStyle(self) + if new_marker._user_transform is None: + new_marker._user_transform = Affine2D() + + if deg is not None: + new_marker._user_transform.rotate_deg(deg) + if rad is not None: + new_marker._user_transform.rotate(rad) + + return new_marker + + def scaled(self, sx, sy=None): + """ + Return new marker scaled by specified scale factors. + + If *sy* is None, the same scale is applied in both the *x*- and + *y*-directions. + + Parameters + ---------- + sx : float + *X*-direction scaling factor. + sy : float, default: None + *Y*-direction scaling factor. + """ + if sy is None: + sy = sx + + new_marker = MarkerStyle(self) + _transform = new_marker._user_transform or Affine2D() + new_marker._user_transform = _transform.scale(sx, sy) + return new_marker + + def _set_nothing(self): + self._filled = False + + def _set_custom_marker(self, path): + rescale = np.max(np.abs(path.vertices)) # max of x's and y's. + self._transform = Affine2D().scale(0.5 / rescale) + self._path = path + + def _set_path_marker(self): + self._set_custom_marker(self._marker) + + def _set_vertices(self): + self._set_custom_marker(Path(self._marker)) + + def _set_tuple_marker(self): + marker = self._marker + if len(marker) == 2: + numsides, rotation = marker[0], 0.0 + elif len(marker) == 3: + numsides, rotation = marker[0], marker[2] + symstyle = marker[1] + if symstyle == 0: + self._path = Path.unit_regular_polygon(numsides) + self._joinstyle = self._user_joinstyle or JoinStyle.miter + elif symstyle == 1: + self._path = Path.unit_regular_star(numsides) + self._joinstyle = self._user_joinstyle or JoinStyle.bevel + elif symstyle == 2: + self._path = Path.unit_regular_asterisk(numsides) + self._filled = False + self._joinstyle = self._user_joinstyle or JoinStyle.bevel + else: + raise ValueError(f"Unexpected tuple marker: {marker}") + self._transform = Affine2D().scale(0.5).rotate_deg(rotation) + + def _set_mathtext_path(self): + """ + Draw mathtext markers '$...$' using `.TextPath` object. + + Submitted by tcb + """ + from matplotlib.text import TextPath + + # again, the properties could be initialised just once outside + # this function + text = TextPath(xy=(0, 0), s=self.get_marker(), + usetex=mpl.rcParams['text.usetex']) + if len(text.vertices) == 0: + return + + bbox = text.get_extents() + max_dim = max(bbox.width, bbox.height) + self._transform = ( + Affine2D() + .translate(-bbox.xmin + 0.5 * -bbox.width, -bbox.ymin + 0.5 * -bbox.height) + .scale(1.0 / max_dim)) + self._path = text + self._snap = False + + def _half_fill(self): + return self.get_fillstyle() in self._half_fillstyles + + def _set_circle(self, size=1.0): + self._transform = Affine2D().scale(0.5 * size) + self._snap_threshold = np.inf + if not self._half_fill(): + self._path = Path.unit_circle() + else: + self._path = self._alt_path = Path.unit_circle_righthalf() + fs = self.get_fillstyle() + self._transform.rotate_deg( + {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs]) + self._alt_transform = self._transform.frozen().rotate_deg(180.) + + def _set_point(self): + self._set_circle(size=0.5) + + def _set_pixel(self): + self._path = Path.unit_rectangle() + # Ideally, you'd want -0.5, -0.5 here, but then the snapping + # algorithm in the Agg backend will round this to a 2x2 + # rectangle from (-1, -1) to (1, 1). By offsetting it + # slightly, we can force it to be (0, 0) to (1, 1), which both + # makes it only be a single pixel and places it correctly + # aligned to 1-width stroking (i.e. the ticks). This hack is + # the best of a number of bad alternatives, mainly because the + # backends are not aware of what marker is actually being used + # beyond just its path data. + self._transform = Affine2D().translate(-0.49999, -0.49999) + self._snap_threshold = None + + _triangle_path = Path._create_closed([[0, 1], [-1, -1], [1, -1]]) + # Going down halfway looks to small. Golden ratio is too far. + _triangle_path_u = Path._create_closed([[0, 1], [-3/5, -1/5], [3/5, -1/5]]) + _triangle_path_d = Path._create_closed( + [[-3/5, -1/5], [3/5, -1/5], [1, -1], [-1, -1]]) + _triangle_path_l = Path._create_closed([[0, 1], [0, -1], [-1, -1]]) + _triangle_path_r = Path._create_closed([[0, 1], [0, -1], [1, -1]]) + + def _set_triangle(self, rot, skip): + self._transform = Affine2D().scale(0.5).rotate_deg(rot) + self._snap_threshold = 5.0 + + if not self._half_fill(): + self._path = self._triangle_path + else: + mpaths = [self._triangle_path_u, + self._triangle_path_l, + self._triangle_path_d, + self._triangle_path_r] + + fs = self.get_fillstyle() + if fs == 'top': + self._path = mpaths[(0 + skip) % 4] + self._alt_path = mpaths[(2 + skip) % 4] + elif fs == 'bottom': + self._path = mpaths[(2 + skip) % 4] + self._alt_path = mpaths[(0 + skip) % 4] + elif fs == 'left': + self._path = mpaths[(1 + skip) % 4] + self._alt_path = mpaths[(3 + skip) % 4] + else: + self._path = mpaths[(3 + skip) % 4] + self._alt_path = mpaths[(1 + skip) % 4] + + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_triangle_up(self): + return self._set_triangle(0.0, 0) + + def _set_triangle_down(self): + return self._set_triangle(180.0, 2) + + def _set_triangle_left(self): + return self._set_triangle(90.0, 3) + + def _set_triangle_right(self): + return self._set_triangle(270.0, 1) + + def _set_square(self): + self._transform = Affine2D().translate(-0.5, -0.5) + self._snap_threshold = 2.0 + if not self._half_fill(): + self._path = Path.unit_rectangle() + else: + # Build a bottom filled square out of two rectangles, one filled. + self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5], + [0.0, 0.5], [0.0, 0.0]]) + self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0], + [0.0, 1.0], [0.0, 0.5]]) + fs = self.get_fillstyle() + rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs] + self._transform.rotate_deg(rotate) + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_diamond(self): + self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45) + self._snap_threshold = 5.0 + if not self._half_fill(): + self._path = Path.unit_rectangle() + else: + self._path = Path([[0, 0], [1, 0], [1, 1], [0, 0]]) + self._alt_path = Path([[0, 0], [0, 1], [1, 1], [0, 0]]) + fs = self.get_fillstyle() + rotate = {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs] + self._transform.rotate_deg(rotate) + self._alt_transform = self._transform + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_thin_diamond(self): + self._set_diamond() + self._transform.scale(0.6, 1.0) + + def _set_pentagon(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 5.0 + + polypath = Path.unit_regular_polygon(5) + + if not self._half_fill(): + self._path = polypath + else: + verts = polypath.vertices + y = (1 + np.sqrt(5)) / 4. + top = Path(verts[[0, 1, 4, 0]]) + bottom = Path(verts[[1, 2, 3, 4, 1]]) + left = Path([verts[0], verts[1], verts[2], [0, -y], verts[0]]) + right = Path([verts[0], verts[4], verts[3], [0, -y], verts[0]]) + self._path, self._alt_path = { + 'top': (top, bottom), 'bottom': (bottom, top), + 'left': (left, right), 'right': (right, left), + }[self.get_fillstyle()] + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_star(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 5.0 + + polypath = Path.unit_regular_star(5, innerCircle=0.381966) + + if not self._half_fill(): + self._path = polypath + else: + verts = polypath.vertices + top = Path(np.concatenate([verts[0:4], verts[7:10], verts[0:1]])) + bottom = Path(np.concatenate([verts[3:8], verts[3:4]])) + left = Path(np.concatenate([verts[0:6], verts[0:1]])) + right = Path(np.concatenate([verts[0:1], verts[5:10], verts[0:1]])) + self._path, self._alt_path = { + 'top': (top, bottom), 'bottom': (bottom, top), + 'left': (left, right), 'right': (right, left), + }[self.get_fillstyle()] + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.bevel + + def _set_hexagon1(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = None + + polypath = Path.unit_regular_polygon(6) + + if not self._half_fill(): + self._path = polypath + else: + verts = polypath.vertices + # not drawing inside lines + x = np.abs(np.cos(5 * np.pi / 6.)) + top = Path(np.concatenate([[(-x, 0)], verts[[1, 0, 5]], [(x, 0)]])) + bottom = Path(np.concatenate([[(-x, 0)], verts[2:5], [(x, 0)]])) + left = Path(verts[0:4]) + right = Path(verts[[0, 5, 4, 3]]) + self._path, self._alt_path = { + 'top': (top, bottom), 'bottom': (bottom, top), + 'left': (left, right), 'right': (right, left), + }[self.get_fillstyle()] + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_hexagon2(self): + self._transform = Affine2D().scale(0.5).rotate_deg(30) + self._snap_threshold = None + + polypath = Path.unit_regular_polygon(6) + + if not self._half_fill(): + self._path = polypath + else: + verts = polypath.vertices + # not drawing inside lines + x, y = np.sqrt(3) / 4, 3 / 4. + top = Path(verts[[1, 0, 5, 4, 1]]) + bottom = Path(verts[1:5]) + left = Path(np.concatenate([ + [(x, y)], verts[:3], [(-x, -y), (x, y)]])) + right = Path(np.concatenate([ + [(x, y)], verts[5:2:-1], [(-x, -y)]])) + self._path, self._alt_path = { + 'top': (top, bottom), 'bottom': (bottom, top), + 'left': (left, right), 'right': (right, left), + }[self.get_fillstyle()] + self._alt_transform = self._transform + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_octagon(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 5.0 + + polypath = Path.unit_regular_polygon(8) + + if not self._half_fill(): + self._transform.rotate_deg(22.5) + self._path = polypath + else: + x = np.sqrt(2.) / 4. + self._path = self._alt_path = Path( + [[0, -1], [0, 1], [-x, 1], [-1, x], + [-1, -x], [-x, -1], [0, -1]]) + fs = self.get_fillstyle() + self._transform.rotate_deg( + {'left': 0, 'bottom': 90, 'right': 180, 'top': 270}[fs]) + self._alt_transform = self._transform.frozen().rotate_deg(180.0) + + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]]) + + def _set_vline(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._line_marker_path + + def _set_hline(self): + self._set_vline() + self._transform = self._transform.rotate_deg(90) + + _tickhoriz_path = Path([[0.0, 0.0], [1.0, 0.0]]) + + def _set_tickleft(self): + self._transform = Affine2D().scale(-1.0, 1.0) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._tickhoriz_path + + def _set_tickright(self): + self._transform = Affine2D().scale(1.0, 1.0) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._tickhoriz_path + + _tickvert_path = Path([[-0.0, 0.0], [-0.0, 1.0]]) + + def _set_tickup(self): + self._transform = Affine2D().scale(1.0, 1.0) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._tickvert_path + + def _set_tickdown(self): + self._transform = Affine2D().scale(1.0, -1.0) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._tickvert_path + + _tri_path = Path([[0.0, 0.0], [0.0, -1.0], + [0.0, 0.0], [0.8, 0.5], + [0.0, 0.0], [-0.8, 0.5]], + [Path.MOVETO, Path.LINETO, + Path.MOVETO, Path.LINETO, + Path.MOVETO, Path.LINETO]) + + def _set_tri_down(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 5.0 + self._filled = False + self._path = self._tri_path + + def _set_tri_up(self): + self._set_tri_down() + self._transform = self._transform.rotate_deg(180) + + def _set_tri_left(self): + self._set_tri_down() + self._transform = self._transform.rotate_deg(270) + + def _set_tri_right(self): + self._set_tri_down() + self._transform = self._transform.rotate_deg(90) + + _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]]) + + def _set_caretdown(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 3.0 + self._filled = False + self._path = self._caret_path + self._joinstyle = self._user_joinstyle or JoinStyle.miter + + def _set_caretup(self): + self._set_caretdown() + self._transform = self._transform.rotate_deg(180) + + def _set_caretleft(self): + self._set_caretdown() + self._transform = self._transform.rotate_deg(270) + + def _set_caretright(self): + self._set_caretdown() + self._transform = self._transform.rotate_deg(90) + + _caret_path_base = Path([[-1.0, 0.0], [0.0, -1.5], [1.0, 0]]) + + def _set_caretdownbase(self): + self._set_caretdown() + self._path = self._caret_path_base + + def _set_caretupbase(self): + self._set_caretdownbase() + self._transform = self._transform.rotate_deg(180) + + def _set_caretleftbase(self): + self._set_caretdownbase() + self._transform = self._transform.rotate_deg(270) + + def _set_caretrightbase(self): + self._set_caretdownbase() + self._transform = self._transform.rotate_deg(90) + + _plus_path = Path([[-1.0, 0.0], [1.0, 0.0], + [0.0, -1.0], [0.0, 1.0]], + [Path.MOVETO, Path.LINETO, + Path.MOVETO, Path.LINETO]) + + def _set_plus(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 1.0 + self._filled = False + self._path = self._plus_path + + _x_path = Path([[-1.0, -1.0], [1.0, 1.0], + [-1.0, 1.0], [1.0, -1.0]], + [Path.MOVETO, Path.LINETO, + Path.MOVETO, Path.LINETO]) + + def _set_x(self): + self._transform = Affine2D().scale(0.5) + self._snap_threshold = 3.0 + self._filled = False + self._path = self._x_path + + _plus_filled_path = Path._create_closed(np.array([ + (-1, -3), (+1, -3), (+1, -1), (+3, -1), (+3, +1), (+1, +1), + (+1, +3), (-1, +3), (-1, +1), (-3, +1), (-3, -1), (-1, -1)]) / 6) + _plus_filled_path_t = Path._create_closed(np.array([ + (+3, 0), (+3, +1), (+1, +1), (+1, +3), + (-1, +3), (-1, +1), (-3, +1), (-3, 0)]) / 6) + + def _set_plus_filled(self): + self._transform = Affine2D() + self._snap_threshold = 5.0 + self._joinstyle = self._user_joinstyle or JoinStyle.miter + if not self._half_fill(): + self._path = self._plus_filled_path + else: + # Rotate top half path to support all partitions + self._path = self._alt_path = self._plus_filled_path_t + fs = self.get_fillstyle() + self._transform.rotate_deg( + {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs]) + self._alt_transform = self._transform.frozen().rotate_deg(180) + + _x_filled_path = Path._create_closed(np.array([ + (-1, -2), (0, -1), (+1, -2), (+2, -1), (+1, 0), (+2, +1), + (+1, +2), (0, +1), (-1, +2), (-2, +1), (-1, 0), (-2, -1)]) / 4) + _x_filled_path_t = Path._create_closed(np.array([ + (+1, 0), (+2, +1), (+1, +2), (0, +1), + (-1, +2), (-2, +1), (-1, 0)]) / 4) + + def _set_x_filled(self): + self._transform = Affine2D() + self._snap_threshold = 5.0 + self._joinstyle = self._user_joinstyle or JoinStyle.miter + if not self._half_fill(): + self._path = self._x_filled_path + else: + # Rotate top half path to support all partitions + self._path = self._alt_path = self._x_filled_path_t + fs = self.get_fillstyle() + self._transform.rotate_deg( + {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs]) + self._alt_transform = self._transform.frozen().rotate_deg(180) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.pyi new file mode 100644 index 00000000..3ee53883 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/markers.pyi @@ -0,0 +1,51 @@ +from typing import Literal + +from .path import Path +from .transforms import Affine2D, Transform + +from numpy.typing import ArrayLike +from .typing import CapStyleType, FillStyleType, JoinStyleType + +TICKLEFT: int +TICKRIGHT: int +TICKUP: int +TICKDOWN: int +CARETLEFT: int +CARETRIGHT: int +CARETUP: int +CARETDOWN: int +CARETLEFTBASE: int +CARETRIGHTBASE: int +CARETUPBASE: int +CARETDOWNBASE: int + +class MarkerStyle: + markers: dict[str | int, str] + filled_markers: tuple[str, ...] + fillstyles: tuple[FillStyleType, ...] + + def __init__( + self, + marker: str | ArrayLike | Path | MarkerStyle | None, + fillstyle: FillStyleType | None = ..., + transform: Transform | None = ..., + capstyle: CapStyleType | None = ..., + joinstyle: JoinStyleType | None = ..., + ) -> None: ... + def __bool__(self) -> bool: ... + def is_filled(self) -> bool: ... + def get_fillstyle(self) -> FillStyleType: ... + def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ... + def get_capstyle(self) -> Literal["butt", "projecting", "round"]: ... + def get_marker(self) -> str | ArrayLike | Path | None: ... + def get_path(self) -> Path: ... + def get_transform(self) -> Transform: ... + def get_alt_path(self) -> Path | None: ... + def get_alt_transform(self) -> Transform: ... + def get_snap_threshold(self) -> float | None: ... + def get_user_transform(self) -> Transform | None: ... + def transformed(self, transform: Affine2D) -> MarkerStyle: ... + def rotated( + self, *, deg: float | None = ..., rad: float | None = ... + ) -> MarkerStyle: ... + def scaled(self, sx: float, sy: float | None = ...) -> MarkerStyle: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.py new file mode 100644 index 00000000..e25b76c4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.py @@ -0,0 +1,140 @@ +r""" +A module for parsing a subset of the TeX math syntax and rendering it to a +Matplotlib backend. + +For a tutorial of its usage, see :ref:`mathtext`. This +document is primarily concerned with implementation details. + +The module uses pyparsing_ to parse the TeX expression. + +.. _pyparsing: https://pypi.org/project/pyparsing/ + +The Bakoma distribution of the TeX Computer Modern fonts, and STIX +fonts are supported. There is experimental support for using +arbitrary fonts, but results may vary without proper tweaking and +metrics for those fonts. +""" + +import functools +import logging + +import matplotlib as mpl +from matplotlib import _api, _mathtext +from matplotlib.ft2font import LOAD_NO_HINTING +from matplotlib.font_manager import FontProperties +from ._mathtext import ( # noqa: reexported API + RasterParse, VectorParse, get_unicode_index) + +_log = logging.getLogger(__name__) + + +get_unicode_index.__module__ = __name__ + +############################################################################## +# MAIN + + +class MathTextParser: + _parser = None + _font_type_mapping = { + 'cm': _mathtext.BakomaFonts, + 'dejavuserif': _mathtext.DejaVuSerifFonts, + 'dejavusans': _mathtext.DejaVuSansFonts, + 'stix': _mathtext.StixFonts, + 'stixsans': _mathtext.StixSansFonts, + 'custom': _mathtext.UnicodeFonts, + } + + def __init__(self, output): + """ + Create a MathTextParser for the given backend *output*. + + Parameters + ---------- + output : {"path", "agg"} + Whether to return a `VectorParse` ("path") or a + `RasterParse` ("agg", or its synonym "macosx"). + """ + self._output_type = _api.check_getitem( + {"path": "vector", "agg": "raster", "macosx": "raster"}, + output=output.lower()) + + def parse(self, s, dpi=72, prop=None, *, antialiased=None): + """ + Parse the given math expression *s* at the given *dpi*. If *prop* is + provided, it is a `.FontProperties` object specifying the "default" + font to use in the math expression, used for all non-math text. + + The results are cached, so multiple calls to `parse` + with the same expression should be fast. + + Depending on the *output* type, this returns either a `VectorParse` or + a `RasterParse`. + """ + # lru_cache can't decorate parse() directly because prop + # is mutable; key the cache using an internal copy (see + # text._get_text_metrics_with_cache for a similar case). + prop = prop.copy() if prop is not None else None + antialiased = mpl._val_or_rc(antialiased, 'text.antialiased') + return self._parse_cached(s, dpi, prop, antialiased) + + @functools.lru_cache(50) + def _parse_cached(self, s, dpi, prop, antialiased): + from matplotlib.backends import backend_agg + + if prop is None: + prop = FontProperties() + fontset_class = _api.check_getitem( + self._font_type_mapping, fontset=prop.get_math_fontfamily()) + load_glyph_flags = { + "vector": LOAD_NO_HINTING, + "raster": backend_agg.get_hinting_flag(), + }[self._output_type] + fontset = fontset_class(prop, load_glyph_flags) + + fontsize = prop.get_size_in_points() + + if self._parser is None: # Cache the parser globally. + self.__class__._parser = _mathtext.Parser() + + box = self._parser.parse(s, fontset, fontsize, dpi) + output = _mathtext.ship(box) + if self._output_type == "vector": + return output.to_vector() + elif self._output_type == "raster": + return output.to_raster(antialiased=antialiased) + + +def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None, + *, color=None): + """ + Given a math expression, renders it in a closely-clipped bounding + box to an image file. + + Parameters + ---------- + s : str + A math expression. The math portion must be enclosed in dollar signs. + filename_or_obj : str or path-like or file-like + Where to write the image data. + prop : `.FontProperties`, optional + The size and style of the text. + dpi : float, optional + The output dpi. If not set, the dpi is determined as for + `.Figure.savefig`. + format : str, optional + The output format, e.g., 'svg', 'pdf', 'ps' or 'png'. If not set, the + format is determined as for `.Figure.savefig`. + color : str, optional + Foreground color, defaults to :rc:`text.color`. + """ + from matplotlib import figure + + parser = MathTextParser('path') + width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop) + + fig = figure.Figure(figsize=(width / 72.0, height / 72.0)) + fig.text(0, depth/height, s, fontproperties=prop, color=color) + fig.savefig(filename_or_obj, dpi=dpi, format=format) + + return depth diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.pyi new file mode 100644 index 00000000..607501a2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mathtext.pyi @@ -0,0 +1,33 @@ +import os +from typing import Generic, IO, Literal, TypeVar, overload + +from matplotlib.font_manager import FontProperties +from matplotlib.typing import ColorType + +# Re-exported API from _mathtext. +from ._mathtext import ( + RasterParse as RasterParse, + VectorParse as VectorParse, + get_unicode_index as get_unicode_index, +) + +_ParseType = TypeVar("_ParseType", RasterParse, VectorParse) + +class MathTextParser(Generic[_ParseType]): + @overload + def __init__(self: MathTextParser[VectorParse], output: Literal["path"]) -> None: ... + @overload + def __init__(self: MathTextParser[RasterParse], output: Literal["agg", "raster", "macosx"]) -> None: ... + def parse( + self, s: str, dpi: float = ..., prop: FontProperties | None = ..., *, antialiased: bool | None = ... + ) -> _ParseType: ... + +def math_to_image( + s: str, + filename_or_obj: str | os.PathLike | IO, + prop: FontProperties | None = ..., + dpi: float | None = ..., + format: str | None = ..., + *, + color: ColorType | None = ... +) -> float: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.py new file mode 100644 index 00000000..1948e633 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.py @@ -0,0 +1,914 @@ +""" +Numerical Python functions written for compatibility with MATLAB +commands with the same names. Most numerical Python functions can be found in +the `NumPy`_ and `SciPy`_ libraries. What remains here is code for performing +spectral computations and kernel density estimations. + +.. _NumPy: https://numpy.org +.. _SciPy: https://www.scipy.org + +Spectral functions +------------------ + +`cohere` + Coherence (normalized cross spectral density) + +`csd` + Cross spectral density using Welch's average periodogram + +`detrend` + Remove the mean or best fit line from an array + +`psd` + Power spectral density using Welch's average periodogram + +`specgram` + Spectrogram (spectrum over segments of time) + +`complex_spectrum` + Return the complex-valued frequency spectrum of a signal + +`magnitude_spectrum` + Return the magnitude of the frequency spectrum of a signal + +`angle_spectrum` + Return the angle (wrapped phase) of the frequency spectrum of a signal + +`phase_spectrum` + Return the phase (unwrapped angle) of the frequency spectrum of a signal + +`detrend_mean` + Remove the mean from a line. + +`detrend_linear` + Remove the best fit line from a line. + +`detrend_none` + Return the original line. +""" + +import functools +from numbers import Number + +import numpy as np + +from matplotlib import _api, _docstring, cbook + + +def window_hanning(x): + """ + Return *x* times the Hanning (or Hann) window of len(*x*). + + See Also + -------- + window_none : Another window algorithm. + """ + return np.hanning(len(x))*x + + +def window_none(x): + """ + No window function; simply return *x*. + + See Also + -------- + window_hanning : Another window algorithm. + """ + return x + + +def detrend(x, key=None, axis=None): + """ + Return *x* with its trend removed. + + Parameters + ---------- + x : array or sequence + Array or sequence containing the data. + + key : {'default', 'constant', 'mean', 'linear', 'none'} or function + The detrending algorithm to use. 'default', 'mean', and 'constant' are + the same as `detrend_mean`. 'linear' is the same as `detrend_linear`. + 'none' is the same as `detrend_none`. The default is 'mean'. See the + corresponding functions for more details regarding the algorithms. Can + also be a function that carries out the detrend operation. + + axis : int + The axis along which to do the detrending. + + See Also + -------- + detrend_mean : Implementation of the 'mean' algorithm. + detrend_linear : Implementation of the 'linear' algorithm. + detrend_none : Implementation of the 'none' algorithm. + """ + if key is None or key in ['constant', 'mean', 'default']: + return detrend(x, key=detrend_mean, axis=axis) + elif key == 'linear': + return detrend(x, key=detrend_linear, axis=axis) + elif key == 'none': + return detrend(x, key=detrend_none, axis=axis) + elif callable(key): + x = np.asarray(x) + if axis is not None and axis + 1 > x.ndim: + raise ValueError(f'axis(={axis}) out of bounds') + if (axis is None and x.ndim == 0) or (not axis and x.ndim == 1): + return key(x) + # try to use the 'axis' argument if the function supports it, + # otherwise use apply_along_axis to do it + try: + return key(x, axis=axis) + except TypeError: + return np.apply_along_axis(key, axis=axis, arr=x) + else: + raise ValueError( + f"Unknown value for key: {key!r}, must be one of: 'default', " + f"'constant', 'mean', 'linear', or a function") + + +def detrend_mean(x, axis=None): + """ + Return *x* minus the mean(*x*). + + Parameters + ---------- + x : array or sequence + Array or sequence containing the data + Can have any dimensionality + + axis : int + The axis along which to take the mean. See `numpy.mean` for a + description of this argument. + + See Also + -------- + detrend_linear : Another detrend algorithm. + detrend_none : Another detrend algorithm. + detrend : A wrapper around all the detrend algorithms. + """ + x = np.asarray(x) + + if axis is not None and axis+1 > x.ndim: + raise ValueError('axis(=%s) out of bounds' % axis) + + return x - x.mean(axis, keepdims=True) + + +def detrend_none(x, axis=None): + """ + Return *x*: no detrending. + + Parameters + ---------- + x : any object + An object containing the data + + axis : int + This parameter is ignored. + It is included for compatibility with detrend_mean + + See Also + -------- + detrend_mean : Another detrend algorithm. + detrend_linear : Another detrend algorithm. + detrend : A wrapper around all the detrend algorithms. + """ + return x + + +def detrend_linear(y): + """ + Return *x* minus best fit line; 'linear' detrending. + + Parameters + ---------- + y : 0-D or 1-D array or sequence + Array or sequence containing the data + + See Also + -------- + detrend_mean : Another detrend algorithm. + detrend_none : Another detrend algorithm. + detrend : A wrapper around all the detrend algorithms. + """ + # This is faster than an algorithm based on linalg.lstsq. + y = np.asarray(y) + + if y.ndim > 1: + raise ValueError('y cannot have ndim > 1') + + # short-circuit 0-D array. + if not y.ndim: + return np.array(0., dtype=y.dtype) + + x = np.arange(y.size, dtype=float) + + C = np.cov(x, y, bias=1) + b = C[0, 1]/C[0, 0] + + a = y.mean() - b*x.mean() + return y - (b*x + a) + + +def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None, + window=None, noverlap=None, pad_to=None, + sides=None, scale_by_freq=None, mode=None): + """ + Private helper implementing the common parts between the psd, csd, + spectrogram and complex, magnitude, angle, and phase spectrums. + """ + if y is None: + # if y is None use x for y + same_data = True + else: + # The checks for if y is x are so that we can use the same function to + # implement the core of psd(), csd(), and spectrogram() without doing + # extra calculations. We return the unaveraged Pxy, freqs, and t. + same_data = y is x + + if Fs is None: + Fs = 2 + if noverlap is None: + noverlap = 0 + if detrend_func is None: + detrend_func = detrend_none + if window is None: + window = window_hanning + + # if NFFT is set to None use the whole signal + if NFFT is None: + NFFT = 256 + + if noverlap >= NFFT: + raise ValueError('noverlap must be less than NFFT') + + if mode is None or mode == 'default': + mode = 'psd' + _api.check_in_list( + ['default', 'psd', 'complex', 'magnitude', 'angle', 'phase'], + mode=mode) + + if not same_data and mode != 'psd': + raise ValueError("x and y must be equal if mode is not 'psd'") + + # Make sure we're dealing with a numpy array. If y and x were the same + # object to start with, keep them that way + x = np.asarray(x) + if not same_data: + y = np.asarray(y) + + if sides is None or sides == 'default': + if np.iscomplexobj(x): + sides = 'twosided' + else: + sides = 'onesided' + _api.check_in_list(['default', 'onesided', 'twosided'], sides=sides) + + # zero pad x and y up to NFFT if they are shorter than NFFT + if len(x) < NFFT: + n = len(x) + x = np.resize(x, NFFT) + x[n:] = 0 + + if not same_data and len(y) < NFFT: + n = len(y) + y = np.resize(y, NFFT) + y[n:] = 0 + + if pad_to is None: + pad_to = NFFT + + if mode != 'psd': + scale_by_freq = False + elif scale_by_freq is None: + scale_by_freq = True + + # For real x, ignore the negative frequencies unless told otherwise + if sides == 'twosided': + numFreqs = pad_to + if pad_to % 2: + freqcenter = (pad_to - 1)//2 + 1 + else: + freqcenter = pad_to//2 + scaling_factor = 1. + elif sides == 'onesided': + if pad_to % 2: + numFreqs = (pad_to + 1)//2 + else: + numFreqs = pad_to//2 + 1 + scaling_factor = 2. + + if not np.iterable(window): + window = window(np.ones(NFFT, x.dtype)) + if len(window) != NFFT: + raise ValueError( + "The window length must match the data's first dimension") + + result = np.lib.stride_tricks.sliding_window_view( + x, NFFT, axis=0)[::NFFT - noverlap].T + result = detrend(result, detrend_func, axis=0) + result = result * window.reshape((-1, 1)) + result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :] + freqs = np.fft.fftfreq(pad_to, 1/Fs)[:numFreqs] + + if not same_data: + # if same_data is False, mode must be 'psd' + resultY = np.lib.stride_tricks.sliding_window_view( + y, NFFT, axis=0)[::NFFT - noverlap].T + resultY = detrend(resultY, detrend_func, axis=0) + resultY = resultY * window.reshape((-1, 1)) + resultY = np.fft.fft(resultY, n=pad_to, axis=0)[:numFreqs, :] + result = np.conj(result) * resultY + elif mode == 'psd': + result = np.conj(result) * result + elif mode == 'magnitude': + result = np.abs(result) / window.sum() + elif mode == 'angle' or mode == 'phase': + # we unwrap the phase later to handle the onesided vs. twosided case + result = np.angle(result) + elif mode == 'complex': + result /= window.sum() + + if mode == 'psd': + + # Also include scaling factors for one-sided densities and dividing by + # the sampling frequency, if desired. Scale everything, except the DC + # component and the NFFT/2 component: + + # if we have a even number of frequencies, don't scale NFFT/2 + if not NFFT % 2: + slc = slice(1, -1, None) + # if we have an odd number, just don't scale DC + else: + slc = slice(1, None, None) + + result[slc] *= scaling_factor + + # MATLAB divides by the sampling frequency so that density function + # has units of dB/Hz and can be integrated by the plotted frequency + # values. Perform the same scaling here. + if scale_by_freq: + result /= Fs + # Scale the spectrum by the norm of the window to compensate for + # windowing loss; see Bendat & Piersol Sec 11.5.2. + result /= (window**2).sum() + else: + # In this case, preserve power in the segment, not amplitude + result /= window.sum()**2 + + t = np.arange(NFFT/2, len(x) - NFFT/2 + 1, NFFT - noverlap)/Fs + + if sides == 'twosided': + # center the frequency range at zero + freqs = np.roll(freqs, -freqcenter, axis=0) + result = np.roll(result, -freqcenter, axis=0) + elif not pad_to % 2: + # get the last value correctly, it is negative otherwise + freqs[-1] *= -1 + + # we unwrap the phase here to handle the onesided vs. twosided case + if mode == 'phase': + result = np.unwrap(result, axis=0) + + return result, freqs, t + + +def _single_spectrum_helper( + mode, x, Fs=None, window=None, pad_to=None, sides=None): + """ + Private helper implementing the commonality between the complex, magnitude, + angle, and phase spectrums. + """ + _api.check_in_list(['complex', 'magnitude', 'angle', 'phase'], mode=mode) + + if pad_to is None: + pad_to = len(x) + + spec, freqs, _ = _spectral_helper(x=x, y=None, NFFT=len(x), Fs=Fs, + detrend_func=detrend_none, window=window, + noverlap=0, pad_to=pad_to, + sides=sides, + scale_by_freq=False, + mode=mode) + if mode != 'complex': + spec = spec.real + + if spec.ndim == 2 and spec.shape[1] == 1: + spec = spec[:, 0] + + return spec, freqs + + +# Split out these keyword docs so that they can be used elsewhere +_docstring.interpd.update( + Spectral="""\ +Fs : float, default: 2 + The sampling frequency (samples per time unit). It is used to calculate + the Fourier frequencies, *freqs*, in cycles per time unit. + +window : callable or ndarray, default: `.window_hanning` + A function or a vector of length *NFFT*. To create window vectors see + `.window_hanning`, `.window_none`, `numpy.blackman`, `numpy.hamming`, + `numpy.bartlett`, `scipy.signal`, `scipy.signal.get_window`, etc. If a + function is passed as the argument, it must take a data segment as an + argument and return the windowed version of the segment. + +sides : {'default', 'onesided', 'twosided'}, optional + Which sides of the spectrum to return. 'default' is one-sided for real + data and two-sided for complex data. 'onesided' forces the return of a + one-sided spectrum, while 'twosided' forces two-sided.""", + + Single_Spectrum="""\ +pad_to : int, optional + The number of points to which the data segment is padded when performing + the FFT. While not increasing the actual resolution of the spectrum (the + minimum distance between resolvable peaks), this can give more points in + the plot, allowing for more detail. This corresponds to the *n* parameter + in the call to `~numpy.fft.fft`. The default is None, which sets *pad_to* + equal to the length of the input signal (i.e. no padding).""", + + PSD="""\ +pad_to : int, optional + The number of points to which the data segment is padded when performing + the FFT. This can be different from *NFFT*, which specifies the number + of data points used. While not increasing the actual resolution of the + spectrum (the minimum distance between resolvable peaks), this can give + more points in the plot, allowing for more detail. This corresponds to + the *n* parameter in the call to `~numpy.fft.fft`. The default is None, + which sets *pad_to* equal to *NFFT* + +NFFT : int, default: 256 + The number of data points used in each block for the FFT. A power 2 is + most efficient. This should *NOT* be used to get zero padding, or the + scaling of the result will be incorrect; use *pad_to* for this instead. + +detrend : {'none', 'mean', 'linear'} or callable, default: 'none' + The function applied to each segment before fft-ing, designed to remove + the mean or linear trend. Unlike in MATLAB, where the *detrend* parameter + is a vector, in Matplotlib it is a function. The :mod:`~matplotlib.mlab` + module defines `.detrend_none`, `.detrend_mean`, and `.detrend_linear`, + but you can use a custom function as well. You can also use a string to + choose one of the functions: 'none' calls `.detrend_none`. 'mean' calls + `.detrend_mean`. 'linear' calls `.detrend_linear`. + +scale_by_freq : bool, default: True + Whether the resulting density values should be scaled by the scaling + frequency, which gives density in units of 1/Hz. This allows for + integration over the returned frequency values. The default is True for + MATLAB compatibility.""") + + +@_docstring.dedent_interpd +def psd(x, NFFT=None, Fs=None, detrend=None, window=None, + noverlap=None, pad_to=None, sides=None, scale_by_freq=None): + r""" + Compute the power spectral density. + + The power spectral density :math:`P_{xx}` by Welch's average + periodogram method. The vector *x* is divided into *NFFT* length + segments. Each segment is detrended by function *detrend* and + windowed by function *window*. *noverlap* gives the length of + the overlap between segments. The :math:`|\mathrm{fft}(i)|^2` + of each segment :math:`i` are averaged to compute :math:`P_{xx}`. + + If len(*x*) < *NFFT*, it will be zero padded to *NFFT*. + + Parameters + ---------- + x : 1-D array or sequence + Array or sequence containing the data + + %(Spectral)s + + %(PSD)s + + noverlap : int, default: 0 (no overlap) + The number of points of overlap between segments. + + Returns + ------- + Pxx : 1-D array + The values for the power spectrum :math:`P_{xx}` (real valued) + + freqs : 1-D array + The frequencies corresponding to the elements in *Pxx* + + References + ---------- + Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John + Wiley & Sons (1986) + + See Also + -------- + specgram + `specgram` differs in the default overlap; in not returning the mean of + the segment periodograms; and in returning the times of the segments. + + magnitude_spectrum : returns the magnitude spectrum. + + csd : returns the spectral density between two signals. + """ + Pxx, freqs = csd(x=x, y=None, NFFT=NFFT, Fs=Fs, detrend=detrend, + window=window, noverlap=noverlap, pad_to=pad_to, + sides=sides, scale_by_freq=scale_by_freq) + return Pxx.real, freqs + + +@_docstring.dedent_interpd +def csd(x, y, NFFT=None, Fs=None, detrend=None, window=None, + noverlap=None, pad_to=None, sides=None, scale_by_freq=None): + """ + Compute the cross-spectral density. + + The cross spectral density :math:`P_{xy}` by Welch's average + periodogram method. The vectors *x* and *y* are divided into + *NFFT* length segments. Each segment is detrended by function + *detrend* and windowed by function *window*. *noverlap* gives + the length of the overlap between segments. The product of + the direct FFTs of *x* and *y* are averaged over each segment + to compute :math:`P_{xy}`, with a scaling to correct for power + loss due to windowing. + + If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero + padded to *NFFT*. + + Parameters + ---------- + x, y : 1-D arrays or sequences + Arrays or sequences containing the data + + %(Spectral)s + + %(PSD)s + + noverlap : int, default: 0 (no overlap) + The number of points of overlap between segments. + + Returns + ------- + Pxy : 1-D array + The values for the cross spectrum :math:`P_{xy}` before scaling (real + valued) + + freqs : 1-D array + The frequencies corresponding to the elements in *Pxy* + + References + ---------- + Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John + Wiley & Sons (1986) + + See Also + -------- + psd : equivalent to setting ``y = x``. + """ + if NFFT is None: + NFFT = 256 + Pxy, freqs, _ = _spectral_helper(x=x, y=y, NFFT=NFFT, Fs=Fs, + detrend_func=detrend, window=window, + noverlap=noverlap, pad_to=pad_to, + sides=sides, scale_by_freq=scale_by_freq, + mode='psd') + + if Pxy.ndim == 2: + if Pxy.shape[1] > 1: + Pxy = Pxy.mean(axis=1) + else: + Pxy = Pxy[:, 0] + return Pxy, freqs + + +_single_spectrum_docs = """\ +Compute the {quantity} of *x*. +Data is padded to a length of *pad_to* and the windowing function *window* is +applied to the signal. + +Parameters +---------- +x : 1-D array or sequence + Array or sequence containing the data + +{Spectral} + +{Single_Spectrum} + +Returns +------- +spectrum : 1-D array + The {quantity}. +freqs : 1-D array + The frequencies corresponding to the elements in *spectrum*. + +See Also +-------- +psd + Returns the power spectral density. +complex_spectrum + Returns the complex-valued frequency spectrum. +magnitude_spectrum + Returns the absolute value of the `complex_spectrum`. +angle_spectrum + Returns the angle of the `complex_spectrum`. +phase_spectrum + Returns the phase (unwrapped angle) of the `complex_spectrum`. +specgram + Can return the complex spectrum of segments within the signal. +""" + + +complex_spectrum = functools.partial(_single_spectrum_helper, "complex") +complex_spectrum.__doc__ = _single_spectrum_docs.format( + quantity="complex-valued frequency spectrum", + **_docstring.interpd.params) +magnitude_spectrum = functools.partial(_single_spectrum_helper, "magnitude") +magnitude_spectrum.__doc__ = _single_spectrum_docs.format( + quantity="magnitude (absolute value) of the frequency spectrum", + **_docstring.interpd.params) +angle_spectrum = functools.partial(_single_spectrum_helper, "angle") +angle_spectrum.__doc__ = _single_spectrum_docs.format( + quantity="angle of the frequency spectrum (wrapped phase spectrum)", + **_docstring.interpd.params) +phase_spectrum = functools.partial(_single_spectrum_helper, "phase") +phase_spectrum.__doc__ = _single_spectrum_docs.format( + quantity="phase of the frequency spectrum (unwrapped phase spectrum)", + **_docstring.interpd.params) + + +@_docstring.dedent_interpd +def specgram(x, NFFT=None, Fs=None, detrend=None, window=None, + noverlap=None, pad_to=None, sides=None, scale_by_freq=None, + mode=None): + """ + Compute a spectrogram. + + Compute and plot a spectrogram of data in *x*. Data are split into + *NFFT* length segments and the spectrum of each section is + computed. The windowing function *window* is applied to each + segment, and the amount of overlap of each segment is + specified with *noverlap*. + + Parameters + ---------- + x : array-like + 1-D array or sequence. + + %(Spectral)s + + %(PSD)s + + noverlap : int, default: 128 + The number of points of overlap between blocks. + mode : str, default: 'psd' + What sort of spectrum to use: + 'psd' + Returns the power spectral density. + 'complex' + Returns the complex-valued frequency spectrum. + 'magnitude' + Returns the magnitude spectrum. + 'angle' + Returns the phase spectrum without unwrapping. + 'phase' + Returns the phase spectrum with unwrapping. + + Returns + ------- + spectrum : array-like + 2D array, columns are the periodograms of successive segments. + + freqs : array-like + 1-D array, frequencies corresponding to the rows in *spectrum*. + + t : array-like + 1-D array, the times corresponding to midpoints of segments + (i.e the columns in *spectrum*). + + See Also + -------- + psd : differs in the overlap and in the return values. + complex_spectrum : similar, but with complex valued frequencies. + magnitude_spectrum : similar single segment when *mode* is 'magnitude'. + angle_spectrum : similar to single segment when *mode* is 'angle'. + phase_spectrum : similar to single segment when *mode* is 'phase'. + + Notes + ----- + *detrend* and *scale_by_freq* only apply when *mode* is set to 'psd'. + + """ + if noverlap is None: + noverlap = 128 # default in _spectral_helper() is noverlap = 0 + if NFFT is None: + NFFT = 256 # same default as in _spectral_helper() + if len(x) <= NFFT: + _api.warn_external("Only one segment is calculated since parameter " + f"NFFT (={NFFT}) >= signal length (={len(x)}).") + + spec, freqs, t = _spectral_helper(x=x, y=None, NFFT=NFFT, Fs=Fs, + detrend_func=detrend, window=window, + noverlap=noverlap, pad_to=pad_to, + sides=sides, + scale_by_freq=scale_by_freq, + mode=mode) + + if mode != 'complex': + spec = spec.real # Needed since helper implements generically + + return spec, freqs, t + + +@_docstring.dedent_interpd +def cohere(x, y, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, + noverlap=0, pad_to=None, sides='default', scale_by_freq=None): + r""" + The coherence between *x* and *y*. Coherence is the normalized + cross spectral density: + + .. math:: + + C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}} + + Parameters + ---------- + x, y + Array or sequence containing the data + + %(Spectral)s + + %(PSD)s + + noverlap : int, default: 0 (no overlap) + The number of points of overlap between segments. + + Returns + ------- + Cxy : 1-D array + The coherence vector. + freqs : 1-D array + The frequencies for the elements in *Cxy*. + + See Also + -------- + :func:`psd`, :func:`csd` : + For information about the methods used to compute :math:`P_{xy}`, + :math:`P_{xx}` and :math:`P_{yy}`. + """ + if len(x) < 2 * NFFT: + raise ValueError( + "Coherence is calculated by averaging over *NFFT* length " + "segments. Your signal is too short for your choice of *NFFT*.") + Pxx, f = psd(x, NFFT, Fs, detrend, window, noverlap, pad_to, sides, + scale_by_freq) + Pyy, f = psd(y, NFFT, Fs, detrend, window, noverlap, pad_to, sides, + scale_by_freq) + Pxy, f = csd(x, y, NFFT, Fs, detrend, window, noverlap, pad_to, sides, + scale_by_freq) + Cxy = np.abs(Pxy) ** 2 / (Pxx * Pyy) + return Cxy, f + + +class GaussianKDE: + """ + Representation of a kernel-density estimate using Gaussian kernels. + + Parameters + ---------- + dataset : array-like + Datapoints to estimate from. In case of univariate data this is a 1-D + array, otherwise a 2D array with shape (# of dims, # of data). + bw_method : str, scalar or callable, optional + The method used to calculate the estimator bandwidth. This can be + 'scott', 'silverman', a scalar constant or a callable. If a + scalar, this will be used directly as `kde.factor`. If a + callable, it should take a `GaussianKDE` instance as only + parameter and return a scalar. If None (default), 'scott' is used. + + Attributes + ---------- + dataset : ndarray + The dataset passed to the constructor. + dim : int + Number of dimensions. + num_dp : int + Number of datapoints. + factor : float + The bandwidth factor, obtained from `kde.covariance_factor`, with which + the covariance matrix is multiplied. + covariance : ndarray + The covariance matrix of *dataset*, scaled by the calculated bandwidth + (`kde.factor`). + inv_cov : ndarray + The inverse of *covariance*. + + Methods + ------- + kde.evaluate(points) : ndarray + Evaluate the estimated pdf on a provided set of points. + kde(points) : ndarray + Same as kde.evaluate(points) + """ + + # This implementation with minor modification was too good to pass up. + # from scipy: https://github.com/scipy/scipy/blob/master/scipy/stats/kde.py + + def __init__(self, dataset, bw_method=None): + self.dataset = np.atleast_2d(dataset) + if not np.array(self.dataset).size > 1: + raise ValueError("`dataset` input should have multiple elements.") + + self.dim, self.num_dp = np.array(self.dataset).shape + + if bw_method is None: + pass + elif cbook._str_equal(bw_method, 'scott'): + self.covariance_factor = self.scotts_factor + elif cbook._str_equal(bw_method, 'silverman'): + self.covariance_factor = self.silverman_factor + elif isinstance(bw_method, Number): + self._bw_method = 'use constant' + self.covariance_factor = lambda: bw_method + elif callable(bw_method): + self._bw_method = bw_method + self.covariance_factor = lambda: self._bw_method(self) + else: + raise ValueError("`bw_method` should be 'scott', 'silverman', a " + "scalar or a callable") + + # Computes the covariance matrix for each Gaussian kernel using + # covariance_factor(). + + self.factor = self.covariance_factor() + # Cache covariance and inverse covariance of the data + if not hasattr(self, '_data_inv_cov'): + self.data_covariance = np.atleast_2d( + np.cov( + self.dataset, + rowvar=1, + bias=False)) + self.data_inv_cov = np.linalg.inv(self.data_covariance) + + self.covariance = self.data_covariance * self.factor ** 2 + self.inv_cov = self.data_inv_cov / self.factor ** 2 + self.norm_factor = (np.sqrt(np.linalg.det(2 * np.pi * self.covariance)) + * self.num_dp) + + def scotts_factor(self): + return np.power(self.num_dp, -1. / (self.dim + 4)) + + def silverman_factor(self): + return np.power( + self.num_dp * (self.dim + 2.0) / 4.0, -1. / (self.dim + 4)) + + # Default method to calculate bandwidth, can be overwritten by subclass + covariance_factor = scotts_factor + + def evaluate(self, points): + """ + Evaluate the estimated pdf on a set of points. + + Parameters + ---------- + points : (# of dimensions, # of points)-array + Alternatively, a (# of dimensions,) vector can be passed in and + treated as a single point. + + Returns + ------- + (# of points,)-array + The values at each point. + + Raises + ------ + ValueError : if the dimensionality of the input points is different + than the dimensionality of the KDE. + + """ + points = np.atleast_2d(points) + + dim, num_m = np.array(points).shape + if dim != self.dim: + raise ValueError(f"points have dimension {dim}, dataset has " + f"dimension {self.dim}") + + result = np.zeros(num_m) + + if num_m >= self.num_dp: + # there are more points than data, so loop over data + for i in range(self.num_dp): + diff = self.dataset[:, i, np.newaxis] - points + tdiff = np.dot(self.inv_cov, diff) + energy = np.sum(diff * tdiff, axis=0) / 2.0 + result = result + np.exp(-energy) + else: + # loop over points + for i in range(num_m): + diff = self.dataset - points[:, i, np.newaxis] + tdiff = np.dot(self.inv_cov, diff) + energy = np.sum(diff * tdiff, axis=0) / 2.0 + result[i] = np.sum(np.exp(-energy), axis=0) + + result = result / self.norm_factor + + return result + + __call__ = evaluate diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.pyi new file mode 100644 index 00000000..1f23288d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mlab.pyi @@ -0,0 +1,100 @@ +from collections.abc import Callable +import functools +from typing import Literal + +import numpy as np +from numpy.typing import ArrayLike + +def window_hanning(x: ArrayLike) -> ArrayLike: ... +def window_none(x: ArrayLike) -> ArrayLike: ... +def detrend( + x: ArrayLike, + key: Literal["default", "constant", "mean", "linear", "none"] + | Callable[[ArrayLike, int | None], ArrayLike] + | None = ..., + axis: int | None = ..., +) -> ArrayLike: ... +def detrend_mean(x: ArrayLike, axis: int | None = ...) -> ArrayLike: ... +def detrend_none(x: ArrayLike, axis: int | None = ...) -> ArrayLike: ... +def detrend_linear(y: ArrayLike) -> ArrayLike: ... +def psd( + x: ArrayLike, + NFFT: int | None = ..., + Fs: float | None = ..., + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike, int | None], ArrayLike] + | None = ..., + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ..., + noverlap: int | None = ..., + pad_to: int | None = ..., + sides: Literal["default", "onesided", "twosided"] | None = ..., + scale_by_freq: bool | None = ..., +) -> tuple[ArrayLike, ArrayLike]: ... +def csd( + x: ArrayLike, + y: ArrayLike | None, + NFFT: int | None = ..., + Fs: float | None = ..., + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike, int | None], ArrayLike] + | None = ..., + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ..., + noverlap: int | None = ..., + pad_to: int | None = ..., + sides: Literal["default", "onesided", "twosided"] | None = ..., + scale_by_freq: bool | None = ..., +) -> tuple[ArrayLike, ArrayLike]: ... + +complex_spectrum = functools.partial(tuple[ArrayLike, ArrayLike]) +magnitude_spectrum = functools.partial(tuple[ArrayLike, ArrayLike]) +angle_spectrum = functools.partial(tuple[ArrayLike, ArrayLike]) +phase_spectrum = functools.partial(tuple[ArrayLike, ArrayLike]) + +def specgram( + x: ArrayLike, + NFFT: int | None = ..., + Fs: float | None = ..., + detrend: Literal["none", "mean", "linear"] | Callable[[ArrayLike, int | None], ArrayLike] | None = ..., + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ..., + noverlap: int | None = ..., + pad_to: int | None = ..., + sides: Literal["default", "onesided", "twosided"] | None = ..., + scale_by_freq: bool | None = ..., + mode: Literal["psd", "complex", "magnitude", "angle", "phase"] | None = ..., +) -> tuple[ArrayLike, ArrayLike, ArrayLike]: ... +def cohere( + x: ArrayLike, + y: ArrayLike, + NFFT: int = ..., + Fs: float = ..., + detrend: Literal["none", "mean", "linear"] | Callable[[ArrayLike, int | None], ArrayLike] = ..., + window: Callable[[ArrayLike], ArrayLike] | ArrayLike = ..., + noverlap: int = ..., + pad_to: int | None = ..., + sides: Literal["default", "onesided", "twosided"] = ..., + scale_by_freq: bool | None = ..., +) -> tuple[ArrayLike, ArrayLike]: ... + +class GaussianKDE: + dataset: ArrayLike + dim: int + num_dp: int + factor: float + data_covariance: ArrayLike + data_inv_cov: ArrayLike + covariance: ArrayLike + inv_cov: ArrayLike + norm_factor: float + def __init__( + self, + dataset: ArrayLike, + bw_method: Literal["scott", "silverman"] + | float + | Callable[[GaussianKDE], float] + | None = ..., + ) -> None: ... + def scotts_factor(self) -> float: ... + def silverman_factor(self) -> float: ... + def covariance_factor(self) -> float: ... + def evaluate(self, points: ArrayLike) -> np.ndarray: ... + def __call__(self, points: ArrayLike) -> np.ndarray: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmex10.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmex10.afm new file mode 100644 index 00000000..b9e318ff --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmex10.afm @@ -0,0 +1,220 @@ +StartFontMetrics 2.0 +Comment Creation Date: Thu Jun 21 22:23:20 1990 +Comment UniqueID 5000774 +FontName CMEX10 +EncodingScheme FontSpecific +FullName CMEX10 +FamilyName Computer Modern +Weight Medium +ItalicAngle 0 +IsFixedPitch false +Version 1.00 +Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved. +Comment Computer Modern fonts were designed by Donald E. Knuth +FontBBox -24 -2960 1454 772 +XHeight 430.556 +Comment CapHeight 0 +Ascender 750 +Comment Descender -1760 +Descender -2960 +Comment FontID CMEX +Comment DesignSize 10 (pts) +Comment CharacterCodingScheme TeX math extension +Comment Space 0 0 0 +Comment ExtraSpace 0 +Comment Quad 1000 +Comment DefaultRuleThickness 40 +Comment BigOpSpacing 111.111 166.667 200 600 100 +Comment Ascendible characters (74) % macro - PS charname +Comment Ascending 0, 16, 18, 32, 48 % ( - parenleft +Comment Ascending 1, 17, 19, 33, 49 % ) - parenright +Comment Ascending 2, 104, 20, 34, 50 % [ - bracketleft +Comment Ascending 3, 105, 21, 35, 51 % ] - bracketright +Comment Ascending 4, 106, 22, 36, 52 % lfloor - floorleft +Comment Ascending 5, 107, 23, 37, 53 % rfloor - floorright +Comment Ascending 6, 108, 24, 38, 54 % lceil - ceilingleft +Comment Ascending 7, 109, 25, 39, 55 % rceil - ceilingright +Comment Ascending 8, 110, 26, 40, 56 % { - braceleft +Comment Ascending 9, 111, 27, 41, 57 % } - braceright +Comment Ascending 10, 68, 28, 42 % < - anglebracketleft +Comment Ascending 11, 69, 29, 43 % > - anglebracketright +Comment Ascending 14, 46, 30, 44 % / - slash +Comment Ascending 15, 47, 31, 45 % \ - backslash +Comment Ascending 70, 71 % bigsqcup - unionsq +Comment Ascending 72, 73 % oint - contintegral +Comment Ascending 74, 75 % bigodot - circledot +Comment Ascending 76, 77 % bigoplus - circleplus +Comment Ascending 78, 79 % bigotimes - circlemultiply +Comment Ascending 80, 88 % sum - summation +Comment Ascending 81, 89 % prod - product +Comment Ascending 82, 90 % int - integral +Comment Ascending 83, 91 % bigcup - union +Comment Ascending 84, 92 % bigcap - intersection +Comment Ascending 85, 93 % biguplus - unionmulti +Comment Ascending 86, 94 % bigwedge - logicaland +Comment Ascending 87, 95 % bigvee - logicalor +Comment Ascending 96, 97 % coprod - coproduct +Comment Ascending 98, 99, 100 % widehat - hatwide +Comment Ascending 101, 102, 103 % widetilde - tildewide +Comment Ascending 112, 113, 114, 115, 116 % radical - sqrt +Comment Extensible characters (28) +Comment Extensible 12 top 0 mid 0 bot 0 rep 12 % vert - thin bar +Comment Extensible 13 top 0 mid 0 bot 0 rep 13 % Vert - thin double bar +Comment Extensible 48 top 48 mid 0 bot 64 rep 66 % ( - parenleft +Comment Extensible 49 top 49 mid 0 bot 65 rep 67 % ) - parenright +Comment Extensible 50 top 50 mid 0 bot 52 rep 54 % [ - bracketleft +Comment Extensible 51 top 51 mid 0 bot 53 rep 55 % ] - bracketright +Comment Extensible 52 top 0 mid 0 bot 52 rep 54 % lfloor - floorleft +Comment Extensible 53 top 0 mid 0 bot 53 rep 55 % rfloor - floorright +Comment Extensible 54 top 50 mid 0 bot 0 rep 54 % lceil - ceilingleft +Comment Extensible 55 top 51 mid 0 bot 0 rep 55 % rceil - ceilingright +Comment Extensible 56 top 56 mid 60 bot 58 rep 62 % { - braceleft +Comment Extensible 57 top 57 mid 61 bot 59 rep 62 % } - braceright +Comment Extensible 58 top 56 mid 0 bot 58 rep 62 % lgroup +Comment Extensible 59 top 57 mid 0 bot 59 rep 62 % rgroup +Comment Extensible 60 top 0 mid 0 bot 0 rep 63 % arrowvert +Comment Extensible 61 top 0 mid 0 bot 0 rep 119 % Arrowvert +Comment Extensible 62 top 0 mid 0 bot 0 rep 62 % bracevert +Comment Extensible 63 top 120 mid 0 bot 121 rep 63 % updownarrow +Comment Extensible 64 top 56 mid 0 bot 59 rep 62 % lmoustache +Comment Extensible 65 top 57 mid 0 bot 58 rep 62 % rmoustache +Comment Extensible 66 top 0 mid 0 bot 0 rep 66 % parenleftexten +Comment Extensible 67 top 0 mid 0 bot 0 rep 67 % parenrightexten +Comment Extensible 116 top 118 mid 0 bot 116 rep 117 % radical +Comment Extensible 119 top 126 mid 0 bot 127 rep 119 % Updownarrow +Comment Extensible 120 top 120 mid 0 bot 0 rep 63 % uparrow +Comment Extensible 121 top 0 mid 0 bot 121 rep 63 % downarrow +Comment Extensible 126 top 126 mid 0 bot 0 rep 119 % Uparrow +Comment Extensible 127 top 0 mid 0 bot 127 rep 119 % Downarrow +StartCharMetrics 129 +C 0 ; WX 458.333 ; N parenleftbig ; B 152 -1159 413 40 ; +C 1 ; WX 458.333 ; N parenrightbig ; B 44 -1159 305 40 ; +C 2 ; WX 416.667 ; N bracketleftbig ; B 202 -1159 394 40 ; +C 3 ; WX 416.667 ; N bracketrightbig ; B 22 -1159 214 40 ; +C 4 ; WX 472.222 ; N floorleftbig ; B 202 -1159 449 40 ; +C 5 ; WX 472.222 ; N floorrightbig ; B 22 -1159 269 40 ; +C 6 ; WX 472.222 ; N ceilingleftbig ; B 202 -1159 449 40 ; +C 7 ; WX 472.222 ; N ceilingrightbig ; B 22 -1159 269 40 ; +C 8 ; WX 583.333 ; N braceleftbig ; B 113 -1159 469 40 ; +C 9 ; WX 583.333 ; N bracerightbig ; B 113 -1159 469 40 ; +C 10 ; WX 472.222 ; N angbracketleftbig ; B 98 -1160 393 40 ; +C 11 ; WX 472.222 ; N angbracketrightbig ; B 78 -1160 373 40 ; +C 12 ; WX 333.333 ; N vextendsingle ; B 145 -621 188 21 ; +C 13 ; WX 555.556 ; N vextenddouble ; B 145 -621 410 21 ; +C 14 ; WX 577.778 ; N slashbig ; B 56 -1159 521 40 ; +C 15 ; WX 577.778 ; N backslashbig ; B 56 -1159 521 40 ; +C 16 ; WX 597.222 ; N parenleftBig ; B 180 -1759 560 40 ; +C 17 ; WX 597.222 ; N parenrightBig ; B 36 -1759 416 40 ; +C 18 ; WX 736.111 ; N parenleftbigg ; B 208 -2359 700 40 ; +C 19 ; WX 736.111 ; N parenrightbigg ; B 35 -2359 527 40 ; +C 20 ; WX 527.778 ; N bracketleftbigg ; B 250 -2359 513 40 ; +C 21 ; WX 527.778 ; N bracketrightbigg ; B 14 -2359 277 40 ; +C 22 ; WX 583.333 ; N floorleftbigg ; B 250 -2359 568 40 ; +C 23 ; WX 583.333 ; N floorrightbigg ; B 14 -2359 332 40 ; +C 24 ; WX 583.333 ; N ceilingleftbigg ; B 250 -2359 568 40 ; +C 25 ; WX 583.333 ; N ceilingrightbigg ; B 14 -2359 332 40 ; +C 26 ; WX 750 ; N braceleftbigg ; B 131 -2359 618 40 ; +C 27 ; WX 750 ; N bracerightbigg ; B 131 -2359 618 40 ; +C 28 ; WX 750 ; N angbracketleftbigg ; B 125 -2359 652 40 ; +C 29 ; WX 750 ; N angbracketrightbigg ; B 97 -2359 624 40 ; +C 30 ; WX 1044.44 ; N slashbigg ; B 56 -2359 987 40 ; +C 31 ; WX 1044.44 ; N backslashbigg ; B 56 -2359 987 40 ; +C 32 ; WX 791.667 ; N parenleftBigg ; B 236 -2959 757 40 ; +C 33 ; WX 791.667 ; N parenrightBigg ; B 34 -2959 555 40 ; +C 34 ; WX 583.333 ; N bracketleftBigg ; B 275 -2959 571 40 ; +C 35 ; WX 583.333 ; N bracketrightBigg ; B 11 -2959 307 40 ; +C 36 ; WX 638.889 ; N floorleftBigg ; B 275 -2959 627 40 ; +C 37 ; WX 638.889 ; N floorrightBigg ; B 11 -2959 363 40 ; +C 38 ; WX 638.889 ; N ceilingleftBigg ; B 275 -2959 627 40 ; +C 39 ; WX 638.889 ; N ceilingrightBigg ; B 11 -2959 363 40 ; +C 40 ; WX 805.556 ; N braceleftBigg ; B 144 -2959 661 40 ; +C 41 ; WX 805.556 ; N bracerightBigg ; B 144 -2959 661 40 ; +C 42 ; WX 805.556 ; N angbracketleftBigg ; B 139 -2960 697 40 ; +C 43 ; WX 805.556 ; N angbracketrightBigg ; B 108 -2960 666 40 ; +C 44 ; WX 1277.78 ; N slashBigg ; B 56 -2959 1221 40 ; +C 45 ; WX 1277.78 ; N backslashBigg ; B 56 -2959 1221 40 ; +C 46 ; WX 811.111 ; N slashBig ; B 56 -1759 754 40 ; +C 47 ; WX 811.111 ; N backslashBig ; B 56 -1759 754 40 ; +C 48 ; WX 875 ; N parenlefttp ; B 291 -1770 842 39 ; +C 49 ; WX 875 ; N parenrighttp ; B 32 -1770 583 39 ; +C 50 ; WX 666.667 ; N bracketlefttp ; B 326 -1760 659 39 ; +C 51 ; WX 666.667 ; N bracketrighttp ; B 7 -1760 340 39 ; +C 52 ; WX 666.667 ; N bracketleftbt ; B 326 -1759 659 40 ; +C 53 ; WX 666.667 ; N bracketrightbt ; B 7 -1759 340 40 ; +C 54 ; WX 666.667 ; N bracketleftex ; B 326 -601 395 1 ; +C 55 ; WX 666.667 ; N bracketrightex ; B 271 -601 340 1 ; +C 56 ; WX 888.889 ; N bracelefttp ; B 384 -910 718 -1 ; +C 57 ; WX 888.889 ; N bracerighttp ; B 170 -910 504 -1 ; +C 58 ; WX 888.889 ; N braceleftbt ; B 384 -899 718 10 ; +C 59 ; WX 888.889 ; N bracerightbt ; B 170 -899 504 10 ; +C 60 ; WX 888.889 ; N braceleftmid ; B 170 -1810 504 10 ; +C 61 ; WX 888.889 ; N bracerightmid ; B 384 -1810 718 10 ; +C 62 ; WX 888.889 ; N braceex ; B 384 -310 504 10 ; +C 63 ; WX 666.667 ; N arrowvertex ; B 312 -601 355 1 ; +C 64 ; WX 875 ; N parenleftbt ; B 291 -1759 842 50 ; +C 65 ; WX 875 ; N parenrightbt ; B 32 -1759 583 50 ; +C 66 ; WX 875 ; N parenleftex ; B 291 -610 402 10 ; +C 67 ; WX 875 ; N parenrightex ; B 472 -610 583 10 ; +C 68 ; WX 611.111 ; N angbracketleftBig ; B 112 -1759 522 40 ; +C 69 ; WX 611.111 ; N angbracketrightBig ; B 88 -1759 498 40 ; +C 70 ; WX 833.333 ; N unionsqtext ; B 56 -1000 776 0 ; +C 71 ; WX 1111.11 ; N unionsqdisplay ; B 56 -1400 1054 0 ; +C 72 ; WX 472.222 ; N contintegraltext ; B 56 -1111 609 0 ; +C 73 ; WX 555.556 ; N contintegraldisplay ; B 56 -2222 943 0 ; +C 74 ; WX 1111.11 ; N circledottext ; B 56 -1000 1054 0 ; +C 75 ; WX 1511.11 ; N circledotdisplay ; B 56 -1400 1454 0 ; +C 76 ; WX 1111.11 ; N circleplustext ; B 56 -1000 1054 0 ; +C 77 ; WX 1511.11 ; N circleplusdisplay ; B 56 -1400 1454 0 ; +C 78 ; WX 1111.11 ; N circlemultiplytext ; B 56 -1000 1054 0 ; +C 79 ; WX 1511.11 ; N circlemultiplydisplay ; B 56 -1400 1454 0 ; +C 80 ; WX 1055.56 ; N summationtext ; B 56 -1000 999 0 ; +C 81 ; WX 944.444 ; N producttext ; B 56 -1000 887 0 ; +C 82 ; WX 472.222 ; N integraltext ; B 56 -1111 609 0 ; +C 83 ; WX 833.333 ; N uniontext ; B 56 -1000 776 0 ; +C 84 ; WX 833.333 ; N intersectiontext ; B 56 -1000 776 0 ; +C 85 ; WX 833.333 ; N unionmultitext ; B 56 -1000 776 0 ; +C 86 ; WX 833.333 ; N logicalandtext ; B 56 -1000 776 0 ; +C 87 ; WX 833.333 ; N logicalortext ; B 56 -1000 776 0 ; +C 88 ; WX 1444.44 ; N summationdisplay ; B 56 -1400 1387 0 ; +C 89 ; WX 1277.78 ; N productdisplay ; B 56 -1400 1221 0 ; +C 90 ; WX 555.556 ; N integraldisplay ; B 56 -2222 943 0 ; +C 91 ; WX 1111.11 ; N uniondisplay ; B 56 -1400 1054 0 ; +C 92 ; WX 1111.11 ; N intersectiondisplay ; B 56 -1400 1054 0 ; +C 93 ; WX 1111.11 ; N unionmultidisplay ; B 56 -1400 1054 0 ; +C 94 ; WX 1111.11 ; N logicalanddisplay ; B 56 -1400 1054 0 ; +C 95 ; WX 1111.11 ; N logicalordisplay ; B 56 -1400 1054 0 ; +C 96 ; WX 944.444 ; N coproducttext ; B 56 -1000 887 0 ; +C 97 ; WX 1277.78 ; N coproductdisplay ; B 56 -1400 1221 0 ; +C 98 ; WX 555.556 ; N hatwide ; B -5 562 561 744 ; +C 99 ; WX 1000 ; N hatwider ; B -4 575 1003 772 ; +C 100 ; WX 1444.44 ; N hatwidest ; B -3 575 1446 772 ; +C 101 ; WX 555.556 ; N tildewide ; B 0 608 555 722 ; +C 102 ; WX 1000 ; N tildewider ; B 0 624 999 750 ; +C 103 ; WX 1444.44 ; N tildewidest ; B 0 623 1443 750 ; +C 104 ; WX 472.222 ; N bracketleftBig ; B 226 -1759 453 40 ; +C 105 ; WX 472.222 ; N bracketrightBig ; B 18 -1759 245 40 ; +C 106 ; WX 527.778 ; N floorleftBig ; B 226 -1759 509 40 ; +C 107 ; WX 527.778 ; N floorrightBig ; B 18 -1759 301 40 ; +C 108 ; WX 527.778 ; N ceilingleftBig ; B 226 -1759 509 40 ; +C 109 ; WX 527.778 ; N ceilingrightBig ; B 18 -1759 301 40 ; +C 110 ; WX 666.667 ; N braceleftBig ; B 119 -1759 547 40 ; +C 111 ; WX 666.667 ; N bracerightBig ; B 119 -1759 547 40 ; +C 112 ; WX 1000 ; N radicalbig ; B 110 -1160 1020 40 ; +C 113 ; WX 1000 ; N radicalBig ; B 110 -1760 1020 40 ; +C 114 ; WX 1000 ; N radicalbigg ; B 111 -2360 1020 40 ; +C 115 ; WX 1000 ; N radicalBigg ; B 111 -2960 1020 40 ; +C 116 ; WX 1055.56 ; N radicalbt ; B 111 -1800 742 20 ; +C 117 ; WX 1055.56 ; N radicalvertex ; B 702 -620 742 20 ; +C 118 ; WX 1055.56 ; N radicaltp ; B 702 -580 1076 40 ; +C 119 ; WX 777.778 ; N arrowvertexdbl ; B 257 -601 521 1 ; +C 120 ; WX 666.667 ; N arrowtp ; B 111 -600 556 0 ; +C 121 ; WX 666.667 ; N arrowbt ; B 111 -600 556 0 ; +C 122 ; WX 450 ; N bracehtipdownleft ; B -24 -214 460 120 ; +C 123 ; WX 450 ; N bracehtipdownright ; B -10 -214 474 120 ; +C 124 ; WX 450 ; N bracehtipupleft ; B -24 0 460 334 ; +C 125 ; WX 450 ; N bracehtipupright ; B -10 0 474 334 ; +C 126 ; WX 777.778 ; N arrowdbltp ; B 56 -600 722 -1 ; +C 127 ; WX 777.778 ; N arrowdblbt ; B 56 -599 722 0 ; +C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmmi10.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmmi10.afm new file mode 100644 index 00000000..f47d6ba0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmmi10.afm @@ -0,0 +1,326 @@ +StartFontMetrics 2.0 +Comment Creation Date: Thu Jun 21 22:23:22 1990 +Comment UniqueID 5000785 +FontName CMMI10 +EncodingScheme FontSpecific +FullName CMMI10 +FamilyName Computer Modern +Weight Medium +ItalicAngle -14.04 +IsFixedPitch false +Version 1.00A +Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved. +Comment Computer Modern fonts were designed by Donald E. Knuth +FontBBox -32 -250 1048 750 +CapHeight 683.333 +XHeight 430.556 +Ascender 694.444 +Descender -194.444 +Comment FontID CMMI +Comment DesignSize 10 (pts) +Comment CharacterCodingScheme TeX math italic +Comment Space 0 0 0 +Comment Quad 1000 +StartCharMetrics 129 +C 0 ; WX 615.276 ; N Gamma ; B 39 0 723 680 ; +C 1 ; WX 833.333 ; N Delta ; B 49 0 787 716 ; +C 2 ; WX 762.774 ; N Theta ; B 50 -22 739 705 ; +C 3 ; WX 694.444 ; N Lambda ; B 35 0 666 716 ; +C 4 ; WX 742.361 ; N Xi ; B 53 0 777 677 ; +C 5 ; WX 831.25 ; N Pi ; B 39 0 880 680 ; +C 6 ; WX 779.861 ; N Sigma ; B 59 0 807 683 ; +C 7 ; WX 583.333 ; N Upsilon ; B 29 0 700 705 ; +C 8 ; WX 666.667 ; N Phi ; B 24 0 642 683 ; +C 9 ; WX 612.221 ; N Psi ; B 28 0 692 683 ; +C 10 ; WX 772.396 ; N Omega ; B 80 0 785 705 ; +C 11 ; WX 639.7 ; N alpha ; B 41 -11 601 442 ; +C 12 ; WX 565.625 ; N beta ; B 25 -194 590 705 ; +C 13 ; WX 517.73 ; N gamma ; B 18 -215 542 442 ; +C 14 ; WX 444.444 ; N delta ; B 41 -12 452 705 ; +C 15 ; WX 405.902 ; N epsilon1 ; B 47 -11 376 431 ; +C 16 ; WX 437.5 ; N zeta ; B 47 -205 474 697 ; +C 17 ; WX 496.53 ; N eta ; B 29 -216 496 442 ; +C 18 ; WX 469.442 ; N theta ; B 42 -11 455 705 ; +C 19 ; WX 353.935 ; N iota ; B 56 -11 324 442 ; +C 20 ; WX 576.159 ; N kappa ; B 55 -11 546 442 ; +C 21 ; WX 583.333 ; N lambda ; B 53 -13 547 694 ; +C 22 ; WX 602.548 ; N mu ; B 30 -216 572 442 ; +C 23 ; WX 493.981 ; N nu ; B 53 0 524 442 ; +C 24 ; WX 437.5 ; N xi ; B 24 -205 446 697 ; +C 25 ; WX 570.025 ; N pi ; B 27 -11 567 431 ; +C 26 ; WX 517.014 ; N rho ; B 30 -216 502 442 ; +C 27 ; WX 571.429 ; N sigma ; B 38 -11 567 431 ; +C 28 ; WX 437.153 ; N tau ; B 27 -12 511 431 ; +C 29 ; WX 540.278 ; N upsilon ; B 29 -11 524 443 ; +C 30 ; WX 595.833 ; N phi ; B 49 -205 573 694 ; +C 31 ; WX 625.691 ; N chi ; B 32 -205 594 442 ; +C 32 ; WX 651.39 ; N psi ; B 29 -205 635 694 ; +C 33 ; WX 622.453 ; N omega ; B 13 -11 605 443 ; +C 34 ; WX 466.316 ; N epsilon ; B 27 -22 428 453 ; +C 35 ; WX 591.438 ; N theta1 ; B 29 -11 561 705 ; +C 36 ; WX 828.125 ; N pi1 ; B 27 -11 817 431 ; +C 37 ; WX 517.014 ; N rho1 ; B 74 -194 502 442 ; +C 38 ; WX 362.846 ; N sigma1 ; B 32 -108 408 442 ; +C 39 ; WX 654.165 ; N phi1 ; B 50 -218 619 442 ; +C 40 ; WX 1000 ; N arrowlefttophalf ; B 56 230 943 428 ; +C 41 ; WX 1000 ; N arrowleftbothalf ; B 56 72 943 270 ; +C 42 ; WX 1000 ; N arrowrighttophalf ; B 56 230 943 428 ; +C 43 ; WX 1000 ; N arrowrightbothalf ; B 56 72 943 270 ; +C 44 ; WX 277.778 ; N arrowhookleft ; B 56 230 221 464 ; +C 45 ; WX 277.778 ; N arrowhookright ; B 56 230 221 464 ; +C 46 ; WX 500 ; N triangleright ; B 27 -4 472 504 ; +C 47 ; WX 500 ; N triangleleft ; B 27 -4 472 504 ; +C 48 ; WX 500 ; N zerooldstyle ; B 40 -22 459 453 ; +C 49 ; WX 500 ; N oneoldstyle ; B 92 0 418 453 ; +C 50 ; WX 500 ; N twooldstyle ; B 44 0 449 453 ; +C 51 ; WX 500 ; N threeoldstyle ; B 42 -216 457 453 ; +C 52 ; WX 500 ; N fouroldstyle ; B 28 -194 471 464 ; +C 53 ; WX 500 ; N fiveoldstyle ; B 50 -216 449 453 ; +C 54 ; WX 500 ; N sixoldstyle ; B 42 -22 457 666 ; +C 55 ; WX 500 ; N sevenoldstyle ; B 56 -216 485 463 ; +C 56 ; WX 500 ; N eightoldstyle ; B 42 -22 457 666 ; +C 57 ; WX 500 ; N nineoldstyle ; B 42 -216 457 453 ; +C 58 ; WX 277.778 ; N period ; B 86 0 192 106 ; +C 59 ; WX 277.778 ; N comma ; B 86 -193 203 106 ; +C 60 ; WX 777.778 ; N less ; B 83 -39 694 539 ; +C 61 ; WX 500 ; N slash ; B 56 -250 443 750 ; +C 62 ; WX 777.778 ; N greater ; B 83 -39 694 539 ; +C 63 ; WX 500 ; N star ; B 4 16 496 486 ; +C 64 ; WX 530.902 ; N partialdiff ; B 40 -22 566 716 ; +C 65 ; WX 750 ; N A ; B 35 0 722 716 ; +C 66 ; WX 758.508 ; N B ; B 42 0 756 683 ; +C 67 ; WX 714.72 ; N C ; B 51 -22 759 705 ; +C 68 ; WX 827.915 ; N D ; B 41 0 803 683 ; +C 69 ; WX 738.193 ; N E ; B 39 0 765 680 ; +C 70 ; WX 643.055 ; N F ; B 39 0 751 680 ; +C 71 ; WX 786.247 ; N G ; B 51 -22 760 705 ; +C 72 ; WX 831.25 ; N H ; B 39 0 881 683 ; +C 73 ; WX 439.583 ; N I ; B 34 0 498 683 ; +C 74 ; WX 554.512 ; N J ; B 73 -22 633 683 ; +C 75 ; WX 849.305 ; N K ; B 39 0 889 683 ; +C 76 ; WX 680.556 ; N L ; B 39 0 643 683 ; +C 77 ; WX 970.138 ; N M ; B 43 0 1044 683 ; +C 78 ; WX 803.471 ; N N ; B 39 0 881 683 ; +C 79 ; WX 762.774 ; N O ; B 50 -22 739 705 ; +C 80 ; WX 642.012 ; N P ; B 41 0 753 683 ; +C 81 ; WX 790.553 ; N Q ; B 50 -194 739 705 ; +C 82 ; WX 759.288 ; N R ; B 41 -22 755 683 ; +C 83 ; WX 613.193 ; N S ; B 53 -22 645 705 ; +C 84 ; WX 584.375 ; N T ; B 24 0 704 677 ; +C 85 ; WX 682.776 ; N U ; B 68 -22 760 683 ; +C 86 ; WX 583.333 ; N V ; B 56 -22 769 683 ; +C 87 ; WX 944.444 ; N W ; B 55 -22 1048 683 ; +C 88 ; WX 828.472 ; N X ; B 27 0 851 683 ; +C 89 ; WX 580.556 ; N Y ; B 34 0 762 683 ; +C 90 ; WX 682.638 ; N Z ; B 59 0 722 683 ; +C 91 ; WX 388.889 ; N flat ; B 56 -22 332 750 ; +C 92 ; WX 388.889 ; N natural ; B 79 -217 309 728 ; +C 93 ; WX 388.889 ; N sharp ; B 56 -216 332 716 ; +C 94 ; WX 1000 ; N slurbelow ; B 56 133 943 371 ; +C 95 ; WX 1000 ; N slurabove ; B 56 130 943 381 ; +C 96 ; WX 416.667 ; N lscript ; B 11 -12 398 705 ; +C 97 ; WX 528.588 ; N a ; B 40 -11 498 442 ; +C 98 ; WX 429.165 ; N b ; B 47 -11 415 694 ; +C 99 ; WX 432.755 ; N c ; B 41 -11 430 442 ; +C 100 ; WX 520.486 ; N d ; B 40 -11 517 694 ; +C 101 ; WX 465.625 ; N e ; B 46 -11 430 442 ; +C 102 ; WX 489.583 ; N f ; B 53 -205 552 705 ; +C 103 ; WX 476.967 ; N g ; B 16 -205 474 442 ; +C 104 ; WX 576.159 ; N h ; B 55 -11 546 694 ; +C 105 ; WX 344.511 ; N i ; B 29 -11 293 661 ; +C 106 ; WX 411.805 ; N j ; B -13 -205 397 661 ; +C 107 ; WX 520.602 ; N k ; B 55 -11 508 694 ; +C 108 ; WX 298.378 ; N l ; B 46 -11 260 694 ; +C 109 ; WX 878.012 ; N m ; B 29 -11 848 442 ; +C 110 ; WX 600.233 ; N n ; B 29 -11 571 442 ; +C 111 ; WX 484.721 ; N o ; B 41 -11 469 442 ; +C 112 ; WX 503.125 ; N p ; B -32 -194 490 442 ; +C 113 ; WX 446.412 ; N q ; B 40 -194 453 442 ; +C 114 ; WX 451.158 ; N r ; B 29 -11 436 442 ; +C 115 ; WX 468.75 ; N s ; B 52 -11 419 442 ; +C 116 ; WX 361.111 ; N t ; B 23 -11 330 626 ; +C 117 ; WX 572.456 ; N u ; B 29 -11 543 442 ; +C 118 ; WX 484.722 ; N v ; B 29 -11 468 443 ; +C 119 ; WX 715.916 ; N w ; B 29 -11 691 443 ; +C 120 ; WX 571.527 ; N x ; B 29 -11 527 442 ; +C 121 ; WX 490.28 ; N y ; B 29 -205 490 442 ; +C 122 ; WX 465.048 ; N z ; B 43 -11 467 442 ; +C 123 ; WX 322.454 ; N dotlessi ; B 29 -11 293 442 ; +C 124 ; WX 384.028 ; N dotlessj ; B -13 -205 360 442 ; +C 125 ; WX 636.457 ; N weierstrass ; B 76 -216 618 453 ; +C 126 ; WX 500 ; N vector ; B 182 516 625 714 ; +C 127 ; WX 277.778 ; N tie ; B 264 538 651 665 ; +C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ; +EndCharMetrics +Comment The following are bogus kern pairs for TeX positioning of accents +StartKernData +StartKernPairs 166 +KPX Gamma slash -55.556 +KPX Gamma comma -111.111 +KPX Gamma period -111.111 +KPX Gamma tie 83.333 +KPX Delta tie 166.667 +KPX Theta tie 83.333 +KPX Lambda tie 166.667 +KPX Xi tie 83.333 +KPX Pi slash -55.556 +KPX Pi comma -55.556 +KPX Pi period -55.556 +KPX Pi tie 55.556 +KPX Sigma tie 83.333 +KPX Upsilon slash -55.556 +KPX Upsilon comma -111.111 +KPX Upsilon period -111.111 +KPX Upsilon tie 55.556 +KPX Phi tie 83.333 +KPX Psi slash -55.556 +KPX Psi comma -55.556 +KPX Psi period -55.556 +KPX Psi tie 55.556 +KPX Omega tie 83.333 +KPX alpha tie 27.778 +KPX beta tie 83.333 +KPX delta comma -55.556 +KPX delta period -55.556 +KPX delta tie 55.556 +KPX epsilon1 tie 55.556 +KPX zeta tie 83.333 +KPX eta tie 55.556 +KPX theta tie 83.333 +KPX iota tie 55.556 +KPX mu tie 27.778 +KPX nu comma -55.556 +KPX nu period -55.556 +KPX nu tie 27.778 +KPX xi tie 111.111 +KPX rho tie 83.333 +KPX sigma comma -55.556 +KPX sigma period -55.556 +KPX tau comma -55.556 +KPX tau period -55.556 +KPX tau tie 27.778 +KPX upsilon tie 27.778 +KPX phi tie 83.333 +KPX chi tie 55.556 +KPX psi tie 111.111 +KPX epsilon tie 83.333 +KPX theta1 tie 83.333 +KPX rho1 tie 83.333 +KPX sigma1 tie 83.333 +KPX phi1 tie 83.333 +KPX slash Delta -55.556 +KPX slash A -55.556 +KPX slash M -55.556 +KPX slash N -55.556 +KPX slash Y 55.556 +KPX slash Z -55.556 +KPX partialdiff tie 83.333 +KPX A tie 138.889 +KPX B tie 83.333 +KPX C slash -27.778 +KPX C comma -55.556 +KPX C period -55.556 +KPX C tie 83.333 +KPX D tie 55.556 +KPX E tie 83.333 +KPX F slash -55.556 +KPX F comma -111.111 +KPX F period -111.111 +KPX F tie 83.333 +KPX G tie 83.333 +KPX H slash -55.556 +KPX H comma -55.556 +KPX H period -55.556 +KPX H tie 55.556 +KPX I tie 111.111 +KPX J slash -55.556 +KPX J comma -111.111 +KPX J period -111.111 +KPX J tie 166.667 +KPX K slash -55.556 +KPX K comma -55.556 +KPX K period -55.556 +KPX K tie 55.556 +KPX L tie 27.778 +KPX M slash -55.556 +KPX M comma -55.556 +KPX M period -55.556 +KPX M tie 83.333 +KPX N slash -83.333 +KPX N slash -27.778 +KPX N comma -55.556 +KPX N period -55.556 +KPX N tie 83.333 +KPX O tie 83.333 +KPX P slash -55.556 +KPX P comma -111.111 +KPX P period -111.111 +KPX P tie 83.333 +KPX Q tie 83.333 +KPX R tie 83.333 +KPX S slash -55.556 +KPX S comma -55.556 +KPX S period -55.556 +KPX S tie 83.333 +KPX T slash -27.778 +KPX T comma -55.556 +KPX T period -55.556 +KPX T tie 83.333 +KPX U comma -111.111 +KPX U period -111.111 +KPX U slash -55.556 +KPX U tie 27.778 +KPX V comma -166.667 +KPX V period -166.667 +KPX V slash -111.111 +KPX W comma -166.667 +KPX W period -166.667 +KPX W slash -111.111 +KPX X slash -83.333 +KPX X slash -27.778 +KPX X comma -55.556 +KPX X period -55.556 +KPX X tie 83.333 +KPX Y comma -166.667 +KPX Y period -166.667 +KPX Y slash -111.111 +KPX Z slash -55.556 +KPX Z comma -55.556 +KPX Z period -55.556 +KPX Z tie 83.333 +KPX lscript tie 111.111 +KPX c tie 55.556 +KPX d Y 55.556 +KPX d Z -55.556 +KPX d j -111.111 +KPX d f -166.667 +KPX d tie 166.667 +KPX e tie 55.556 +KPX f comma -55.556 +KPX f period -55.556 +KPX f tie 166.667 +KPX g tie 27.778 +KPX h tie -27.778 +KPX j comma -55.556 +KPX j period -55.556 +KPX l tie 83.333 +KPX o tie 55.556 +KPX p tie 83.333 +KPX q tie 83.333 +KPX r comma -55.556 +KPX r period -55.556 +KPX r tie 55.556 +KPX s tie 55.556 +KPX t tie 83.333 +KPX u tie 27.778 +KPX v tie 27.778 +KPX w tie 83.333 +KPX x tie 27.778 +KPX y tie 55.556 +KPX z tie 55.556 +KPX dotlessi tie 27.778 +KPX dotlessj tie 83.333 +KPX weierstrass tie 111.111 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmr10.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmr10.afm new file mode 100644 index 00000000..4d586fe6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmr10.afm @@ -0,0 +1,343 @@ +StartFontMetrics 2.0 +Comment Creation Date: Thu Jun 21 22:23:28 1990 +Comment UniqueID 5000793 +FontName CMR10 +EncodingScheme FontSpecific +FullName CMR10 +FamilyName Computer Modern +Weight Medium +ItalicAngle 0.0 +IsFixedPitch false +Version 1.00B +Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved. +Comment Computer Modern fonts were designed by Donald E. Knuth +FontBBox -40 -250 1009 969 +CapHeight 683.333 +XHeight 430.556 +Ascender 694.444 +Descender -194.444 +Comment FontID CMR +Comment DesignSize 10 (pts) +Comment CharacterCodingScheme TeX text +Comment Space 333.333 166.667 111.111 +Comment ExtraSpace 111.111 +Comment Quad 1000 +StartCharMetrics 129 +C 0 ; WX 625 ; N Gamma ; B 33 0 582 680 ; +C 1 ; WX 833.333 ; N Delta ; B 47 0 785 716 ; +C 2 ; WX 777.778 ; N Theta ; B 56 -22 721 705 ; +C 3 ; WX 694.444 ; N Lambda ; B 32 0 661 716 ; +C 4 ; WX 666.667 ; N Xi ; B 42 0 624 677 ; +C 5 ; WX 750 ; N Pi ; B 33 0 716 680 ; +C 6 ; WX 722.222 ; N Sigma ; B 56 0 665 683 ; +C 7 ; WX 777.778 ; N Upsilon ; B 56 0 721 705 ; +C 8 ; WX 722.222 ; N Phi ; B 56 0 665 683 ; +C 9 ; WX 777.778 ; N Psi ; B 57 0 720 683 ; +C 10 ; WX 722.222 ; N Omega ; B 44 0 677 705 ; +C 11 ; WX 583.333 ; N ff ; B 27 0 628 705 ; L i ffi ; L l ffl ; +C 12 ; WX 555.556 ; N fi ; B 27 0 527 705 ; +C 13 ; WX 555.556 ; N fl ; B 27 0 527 705 ; +C 14 ; WX 833.333 ; N ffi ; B 27 0 804 705 ; +C 15 ; WX 833.333 ; N ffl ; B 27 0 804 705 ; +C 16 ; WX 277.778 ; N dotlessi ; B 33 0 247 442 ; +C 17 ; WX 305.556 ; N dotlessj ; B -40 -205 210 442 ; +C 18 ; WX 500 ; N grave ; B 107 510 293 698 ; +C 19 ; WX 500 ; N acute ; B 206 510 392 698 ; +C 20 ; WX 500 ; N caron ; B 118 516 381 638 ; +C 21 ; WX 500 ; N breve ; B 100 522 399 694 ; +C 22 ; WX 500 ; N macron ; B 69 559 430 590 ; +C 23 ; WX 750 ; N ring ; B 279 541 470 716 ; +C 24 ; WX 444.444 ; N cedilla ; B 131 -203 367 -22 ; +C 25 ; WX 500 ; N germandbls ; B 28 -11 471 705 ; +C 26 ; WX 722.222 ; N ae ; B 45 -11 693 448 ; +C 27 ; WX 777.778 ; N oe ; B 28 -11 749 448 ; +C 28 ; WX 500 ; N oslash ; B 35 -102 464 534 ; +C 29 ; WX 902.778 ; N AE ; B 32 0 874 683 ; +C 30 ; WX 1013.89 ; N OE ; B 70 -22 985 705 ; +C 31 ; WX 777.778 ; N Oslash ; B 56 -56 721 739 ; +C 32 ; WX 277.778 ; N suppress ; B 27 280 262 392 ; +C 33 ; WX 277.778 ; N exclam ; B 86 0 192 716 ; L quoteleft exclamdown ; +C 34 ; WX 500 ; N quotedblright ; B 33 395 347 694 ; +C 35 ; WX 833.333 ; N numbersign ; B 56 -194 776 694 ; +C 36 ; WX 500 ; N dollar ; B 56 -56 443 750 ; +C 37 ; WX 833.333 ; N percent ; B 56 -56 776 750 ; +C 38 ; WX 777.778 ; N ampersand ; B 42 -22 727 716 ; +C 39 ; WX 277.778 ; N quoteright ; B 86 395 206 694 ; L quoteright quotedblright ; +C 40 ; WX 388.889 ; N parenleft ; B 99 -250 331 750 ; +C 41 ; WX 388.889 ; N parenright ; B 57 -250 289 750 ; +C 42 ; WX 500 ; N asterisk ; B 65 319 434 750 ; +C 43 ; WX 777.778 ; N plus ; B 56 -83 721 583 ; +C 44 ; WX 277.778 ; N comma ; B 86 -193 203 106 ; +C 45 ; WX 333.333 ; N hyphen ; B 11 187 276 245 ; L hyphen endash ; +C 46 ; WX 277.778 ; N period ; B 86 0 192 106 ; +C 47 ; WX 500 ; N slash ; B 56 -250 443 750 ; +C 48 ; WX 500 ; N zero ; B 39 -22 460 666 ; +C 49 ; WX 500 ; N one ; B 89 0 419 666 ; +C 50 ; WX 500 ; N two ; B 50 0 449 666 ; +C 51 ; WX 500 ; N three ; B 42 -22 457 666 ; +C 52 ; WX 500 ; N four ; B 28 0 471 677 ; +C 53 ; WX 500 ; N five ; B 50 -22 449 666 ; +C 54 ; WX 500 ; N six ; B 42 -22 457 666 ; +C 55 ; WX 500 ; N seven ; B 56 -22 485 676 ; +C 56 ; WX 500 ; N eight ; B 42 -22 457 666 ; +C 57 ; WX 500 ; N nine ; B 42 -22 457 666 ; +C 58 ; WX 277.778 ; N colon ; B 86 0 192 431 ; +C 59 ; WX 277.778 ; N semicolon ; B 86 -193 195 431 ; +C 60 ; WX 277.778 ; N exclamdown ; B 86 -216 192 500 ; +C 61 ; WX 777.778 ; N equal ; B 56 133 721 367 ; +C 62 ; WX 472.222 ; N questiondown ; B 56 -205 415 500 ; +C 63 ; WX 472.222 ; N question ; B 56 0 415 705 ; L quoteleft questiondown ; +C 64 ; WX 777.778 ; N at ; B 56 -11 721 705 ; +C 65 ; WX 750 ; N A ; B 32 0 717 716 ; +C 66 ; WX 708.333 ; N B ; B 36 0 651 683 ; +C 67 ; WX 722.222 ; N C ; B 56 -22 665 705 ; +C 68 ; WX 763.889 ; N D ; B 35 0 707 683 ; +C 69 ; WX 680.556 ; N E ; B 33 0 652 680 ; +C 70 ; WX 652.778 ; N F ; B 33 0 610 680 ; +C 71 ; WX 784.722 ; N G ; B 56 -22 735 705 ; +C 72 ; WX 750 ; N H ; B 33 0 716 683 ; +C 73 ; WX 361.111 ; N I ; B 28 0 333 683 ; +C 74 ; WX 513.889 ; N J ; B 41 -22 465 683 ; +C 75 ; WX 777.778 ; N K ; B 33 0 736 683 ; +C 76 ; WX 625 ; N L ; B 33 0 582 683 ; +C 77 ; WX 916.667 ; N M ; B 37 0 879 683 ; +C 78 ; WX 750 ; N N ; B 33 0 716 683 ; +C 79 ; WX 777.778 ; N O ; B 56 -22 721 705 ; +C 80 ; WX 680.556 ; N P ; B 35 0 624 683 ; +C 81 ; WX 777.778 ; N Q ; B 56 -194 727 705 ; +C 82 ; WX 736.111 ; N R ; B 35 -22 732 683 ; +C 83 ; WX 555.556 ; N S ; B 56 -22 499 705 ; +C 84 ; WX 722.222 ; N T ; B 36 0 685 677 ; +C 85 ; WX 750 ; N U ; B 33 -22 716 683 ; +C 86 ; WX 750 ; N V ; B 19 -22 730 683 ; +C 87 ; WX 1027.78 ; N W ; B 18 -22 1009 683 ; +C 88 ; WX 750 ; N X ; B 24 0 726 683 ; +C 89 ; WX 750 ; N Y ; B 11 0 738 683 ; +C 90 ; WX 611.111 ; N Z ; B 56 0 560 683 ; +C 91 ; WX 277.778 ; N bracketleft ; B 118 -250 255 750 ; +C 92 ; WX 500 ; N quotedblleft ; B 152 394 466 693 ; +C 93 ; WX 277.778 ; N bracketright ; B 22 -250 159 750 ; +C 94 ; WX 500 ; N circumflex ; B 116 540 383 694 ; +C 95 ; WX 277.778 ; N dotaccent ; B 85 563 192 669 ; +C 96 ; WX 277.778 ; N quoteleft ; B 72 394 192 693 ; L quoteleft quotedblleft ; +C 97 ; WX 500 ; N a ; B 42 -11 493 448 ; +C 98 ; WX 555.556 ; N b ; B 28 -11 521 694 ; +C 99 ; WX 444.444 ; N c ; B 34 -11 415 448 ; +C 100 ; WX 555.556 ; N d ; B 34 -11 527 694 ; +C 101 ; WX 444.444 ; N e ; B 28 -11 415 448 ; +C 102 ; WX 305.556 ; N f ; B 33 0 357 705 ; L i fi ; L f ff ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -206 485 453 ; +C 104 ; WX 555.556 ; N h ; B 32 0 535 694 ; +C 105 ; WX 277.778 ; N i ; B 33 0 247 669 ; +C 106 ; WX 305.556 ; N j ; B -40 -205 210 669 ; +C 107 ; WX 527.778 ; N k ; B 28 0 511 694 ; +C 108 ; WX 277.778 ; N l ; B 33 0 255 694 ; +C 109 ; WX 833.333 ; N m ; B 32 0 813 442 ; +C 110 ; WX 555.556 ; N n ; B 32 0 535 442 ; +C 111 ; WX 500 ; N o ; B 28 -11 471 448 ; +C 112 ; WX 555.556 ; N p ; B 28 -194 521 442 ; +C 113 ; WX 527.778 ; N q ; B 34 -194 527 442 ; +C 114 ; WX 391.667 ; N r ; B 28 0 364 442 ; +C 115 ; WX 394.444 ; N s ; B 33 -11 360 448 ; +C 116 ; WX 388.889 ; N t ; B 19 -11 332 615 ; +C 117 ; WX 555.556 ; N u ; B 32 -11 535 442 ; +C 118 ; WX 527.778 ; N v ; B 19 -11 508 431 ; +C 119 ; WX 722.222 ; N w ; B 18 -11 703 431 ; +C 120 ; WX 527.778 ; N x ; B 12 0 516 431 ; +C 121 ; WX 527.778 ; N y ; B 19 -205 508 431 ; +C 122 ; WX 444.444 ; N z ; B 28 0 401 431 ; +C 123 ; WX 500 ; N endash ; B 0 255 499 277 ; L hyphen emdash ; +C 124 ; WX 1000 ; N emdash ; B 0 255 999 277 ; +C 125 ; WX 500 ; N hungarumlaut ; B 128 513 420 699 ; +C 126 ; WX 500 ; N tilde ; B 83 575 416 668 ; +C 127 ; WX 500 ; N dieresis ; B 103 569 396 669 ; +C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 183 +KPX ff quoteright 77.778 +KPX ff question 77.778 +KPX ff exclam 77.778 +KPX ff parenright 77.778 +KPX ff bracketright 77.778 +KPX suppress l -277.778 +KPX suppress L -319.444 +KPX quoteright question 111.111 +KPX quoteright exclam 111.111 +KPX A t -27.778 +KPX A C -27.778 +KPX A O -27.778 +KPX A G -27.778 +KPX A U -27.778 +KPX A Q -27.778 +KPX A T -83.333 +KPX A Y -83.333 +KPX A V -111.111 +KPX A W -111.111 +KPX D X -27.778 +KPX D W -27.778 +KPX D A -27.778 +KPX D V -27.778 +KPX D Y -27.778 +KPX F o -83.333 +KPX F e -83.333 +KPX F u -83.333 +KPX F r -83.333 +KPX F a -83.333 +KPX F A -111.111 +KPX F O -27.778 +KPX F C -27.778 +KPX F G -27.778 +KPX F Q -27.778 +KPX I I 27.778 +KPX K O -27.778 +KPX K C -27.778 +KPX K G -27.778 +KPX K Q -27.778 +KPX L T -83.333 +KPX L Y -83.333 +KPX L V -111.111 +KPX L W -111.111 +KPX O X -27.778 +KPX O W -27.778 +KPX O A -27.778 +KPX O V -27.778 +KPX O Y -27.778 +KPX P A -83.333 +KPX P o -27.778 +KPX P e -27.778 +KPX P a -27.778 +KPX P period -83.333 +KPX P comma -83.333 +KPX R t -27.778 +KPX R C -27.778 +KPX R O -27.778 +KPX R G -27.778 +KPX R U -27.778 +KPX R Q -27.778 +KPX R T -83.333 +KPX R Y -83.333 +KPX R V -111.111 +KPX R W -111.111 +KPX T y -27.778 +KPX T e -83.333 +KPX T o -83.333 +KPX T r -83.333 +KPX T a -83.333 +KPX T A -83.333 +KPX T u -83.333 +KPX V o -83.333 +KPX V e -83.333 +KPX V u -83.333 +KPX V r -83.333 +KPX V a -83.333 +KPX V A -111.111 +KPX V O -27.778 +KPX V C -27.778 +KPX V G -27.778 +KPX V Q -27.778 +KPX W o -83.333 +KPX W e -83.333 +KPX W u -83.333 +KPX W r -83.333 +KPX W a -83.333 +KPX W A -111.111 +KPX W O -27.778 +KPX W C -27.778 +KPX W G -27.778 +KPX W Q -27.778 +KPX X O -27.778 +KPX X C -27.778 +KPX X G -27.778 +KPX X Q -27.778 +KPX Y e -83.333 +KPX Y o -83.333 +KPX Y r -83.333 +KPX Y a -83.333 +KPX Y A -83.333 +KPX Y u -83.333 +KPX a v -27.778 +KPX a j 55.556 +KPX a y -27.778 +KPX a w -27.778 +KPX b e 27.778 +KPX b o 27.778 +KPX b x -27.778 +KPX b d 27.778 +KPX b c 27.778 +KPX b q 27.778 +KPX b v -27.778 +KPX b j 55.556 +KPX b y -27.778 +KPX b w -27.778 +KPX c h -27.778 +KPX c k -27.778 +KPX f quoteright 77.778 +KPX f question 77.778 +KPX f exclam 77.778 +KPX f parenright 77.778 +KPX f bracketright 77.778 +KPX g j 27.778 +KPX h t -27.778 +KPX h u -27.778 +KPX h b -27.778 +KPX h y -27.778 +KPX h v -27.778 +KPX h w -27.778 +KPX k a -55.556 +KPX k e -27.778 +KPX k a -27.778 +KPX k o -27.778 +KPX k c -27.778 +KPX m t -27.778 +KPX m u -27.778 +KPX m b -27.778 +KPX m y -27.778 +KPX m v -27.778 +KPX m w -27.778 +KPX n t -27.778 +KPX n u -27.778 +KPX n b -27.778 +KPX n y -27.778 +KPX n v -27.778 +KPX n w -27.778 +KPX o e 27.778 +KPX o o 27.778 +KPX o x -27.778 +KPX o d 27.778 +KPX o c 27.778 +KPX o q 27.778 +KPX o v -27.778 +KPX o j 55.556 +KPX o y -27.778 +KPX o w -27.778 +KPX p e 27.778 +KPX p o 27.778 +KPX p x -27.778 +KPX p d 27.778 +KPX p c 27.778 +KPX p q 27.778 +KPX p v -27.778 +KPX p j 55.556 +KPX p y -27.778 +KPX p w -27.778 +KPX t y -27.778 +KPX t w -27.778 +KPX u w -27.778 +KPX v a -55.556 +KPX v e -27.778 +KPX v a -27.778 +KPX v o -27.778 +KPX v c -27.778 +KPX w e -27.778 +KPX w a -27.778 +KPX w o -27.778 +KPX w c -27.778 +KPX y o -27.778 +KPX y e -27.778 +KPX y a -27.778 +KPX y period -83.333 +KPX y comma -83.333 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmsy10.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmsy10.afm new file mode 100644 index 00000000..09e9487d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmsy10.afm @@ -0,0 +1,195 @@ +StartFontMetrics 2.0 +Comment Creation Date: Thu Jun 21 22:23:44 1990 +Comment UniqueID 5000820 +FontName CMSY10 +EncodingScheme FontSpecific +FullName CMSY10 +FamilyName Computer Modern +Weight Medium +ItalicAngle -14.035 +IsFixedPitch false +Version 1.00 +Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved. +Comment Computer Modern fonts were designed by Donald E. Knuth +FontBBox -29 -960 1116 775 +CapHeight 683.333 +XHeight 430.556 +Ascender 694.444 +Descender -960 +Comment FontID CMSY +Comment DesignSize 10 (pts) +Comment CharacterCodingScheme TeX math symbols +Comment Space 0 0 0 +Comment ExtraSpace 0 +Comment Quad 1000 +Comment Num 676.508 393.732 443.731 +Comment Denom 685.951 344.841 +Comment Sup 412.892 362.892 288.889 +Comment Sub 150 247.217 +Comment Supdrop 386.108 +Comment Subdrop 50 +Comment Delim 2390 1010 +Comment Axisheight 250 +StartCharMetrics 129 +C 0 ; WX 777.778 ; N minus ; B 83 230 694 270 ; +C 1 ; WX 277.778 ; N periodcentered ; B 86 197 192 303 ; +C 2 ; WX 777.778 ; N multiply ; B 147 9 630 491 ; +C 3 ; WX 500 ; N asteriskmath ; B 65 34 434 465 ; +C 4 ; WX 777.778 ; N divide ; B 56 -30 722 530 ; +C 5 ; WX 500 ; N diamondmath ; B 11 11 489 489 ; +C 6 ; WX 777.778 ; N plusminus ; B 56 0 721 666 ; +C 7 ; WX 777.778 ; N minusplus ; B 56 -166 721 500 ; +C 8 ; WX 777.778 ; N circleplus ; B 56 -83 721 583 ; +C 9 ; WX 777.778 ; N circleminus ; B 56 -83 721 583 ; +C 10 ; WX 777.778 ; N circlemultiply ; B 56 -83 721 583 ; +C 11 ; WX 777.778 ; N circledivide ; B 56 -83 721 583 ; +C 12 ; WX 777.778 ; N circledot ; B 56 -83 721 583 ; +C 13 ; WX 1000 ; N circlecopyrt ; B 56 -216 943 716 ; +C 14 ; WX 500 ; N openbullet ; B 56 56 443 444 ; +C 15 ; WX 500 ; N bullet ; B 56 56 443 444 ; +C 16 ; WX 777.778 ; N equivasymptotic ; B 56 16 721 484 ; +C 17 ; WX 777.778 ; N equivalence ; B 56 36 721 464 ; +C 18 ; WX 777.778 ; N reflexsubset ; B 83 -137 694 636 ; +C 19 ; WX 777.778 ; N reflexsuperset ; B 83 -137 694 636 ; +C 20 ; WX 777.778 ; N lessequal ; B 83 -137 694 636 ; +C 21 ; WX 777.778 ; N greaterequal ; B 83 -137 694 636 ; +C 22 ; WX 777.778 ; N precedesequal ; B 83 -137 694 636 ; +C 23 ; WX 777.778 ; N followsequal ; B 83 -137 694 636 ; +C 24 ; WX 777.778 ; N similar ; B 56 133 721 367 ; +C 25 ; WX 777.778 ; N approxequal ; B 56 56 721 483 ; +C 26 ; WX 777.778 ; N propersubset ; B 83 -40 694 540 ; +C 27 ; WX 777.778 ; N propersuperset ; B 83 -40 694 540 ; +C 28 ; WX 1000 ; N lessmuch ; B 56 -66 943 566 ; +C 29 ; WX 1000 ; N greatermuch ; B 56 -66 943 566 ; +C 30 ; WX 777.778 ; N precedes ; B 83 -40 694 539 ; +C 31 ; WX 777.778 ; N follows ; B 83 -40 694 539 ; +C 32 ; WX 1000 ; N arrowleft ; B 57 72 943 428 ; +C 33 ; WX 1000 ; N arrowright ; B 56 72 942 428 ; +C 34 ; WX 500 ; N arrowup ; B 72 -194 428 693 ; +C 35 ; WX 500 ; N arrowdown ; B 72 -193 428 694 ; +C 36 ; WX 1000 ; N arrowboth ; B 57 72 942 428 ; +C 37 ; WX 1000 ; N arrownortheast ; B 56 -193 946 697 ; +C 38 ; WX 1000 ; N arrowsoutheast ; B 56 -197 946 693 ; +C 39 ; WX 777.778 ; N similarequal ; B 56 36 721 464 ; +C 40 ; WX 1000 ; N arrowdblleft ; B 57 -25 943 525 ; +C 41 ; WX 1000 ; N arrowdblright ; B 56 -25 942 525 ; +C 42 ; WX 611.111 ; N arrowdblup ; B 30 -194 580 694 ; +C 43 ; WX 611.111 ; N arrowdbldown ; B 30 -194 580 694 ; +C 44 ; WX 1000 ; N arrowdblboth ; B 35 -25 964 525 ; +C 45 ; WX 1000 ; N arrownorthwest ; B 53 -193 943 697 ; +C 46 ; WX 1000 ; N arrowsouthwest ; B 53 -197 943 693 ; +C 47 ; WX 777.778 ; N proportional ; B 56 -11 722 442 ; +C 48 ; WX 275 ; N prime ; B 29 45 262 559 ; +C 49 ; WX 1000 ; N infinity ; B 56 -11 943 442 ; +C 50 ; WX 666.667 ; N element ; B 83 -40 583 540 ; +C 51 ; WX 666.667 ; N owner ; B 83 -40 583 540 ; +C 52 ; WX 888.889 ; N triangle ; B 59 0 829 716 ; +C 53 ; WX 888.889 ; N triangleinv ; B 59 -216 829 500 ; +C 54 ; WX 0 ; N negationslash ; B 139 -216 638 716 ; +C 55 ; WX 0 ; N mapsto ; B 56 64 124 436 ; +C 56 ; WX 555.556 ; N universal ; B 0 -22 556 694 ; +C 57 ; WX 555.556 ; N existential ; B 56 0 499 694 ; +C 58 ; WX 666.667 ; N logicalnot ; B 56 89 610 356 ; +C 59 ; WX 500 ; N emptyset ; B 47 -78 452 772 ; +C 60 ; WX 722.222 ; N Rfractur ; B 46 -22 714 716 ; +C 61 ; WX 722.222 ; N Ifractur ; B 56 -11 693 705 ; +C 62 ; WX 777.778 ; N latticetop ; B 56 0 722 666 ; +C 63 ; WX 777.778 ; N perpendicular ; B 56 0 722 666 ; +C 64 ; WX 611.111 ; N aleph ; B 56 0 554 693 ; +C 65 ; WX 798.469 ; N A ; B 27 -50 798 722 ; +C 66 ; WX 656.808 ; N B ; B 30 -22 665 706 ; +C 67 ; WX 526.527 ; N C ; B 12 -24 534 705 ; +C 68 ; WX 771.391 ; N D ; B 20 0 766 683 ; +C 69 ; WX 527.778 ; N E ; B 28 -22 565 705 ; +C 70 ; WX 718.75 ; N F ; B 17 -33 829 683 ; +C 71 ; WX 594.864 ; N G ; B 44 -119 601 705 ; +C 72 ; WX 844.516 ; N H ; B 20 -47 818 683 ; +C 73 ; WX 544.513 ; N I ; B -24 0 635 683 ; +C 74 ; WX 677.778 ; N J ; B 47 -119 840 683 ; +C 75 ; WX 761.949 ; N K ; B 30 -22 733 705 ; +C 76 ; WX 689.723 ; N L ; B 31 -22 656 705 ; +C 77 ; WX 1200.9 ; N M ; B 27 -50 1116 705 ; +C 78 ; WX 820.489 ; N N ; B -29 -50 978 775 ; +C 79 ; WX 796.112 ; N O ; B 57 -22 777 705 ; +C 80 ; WX 695.558 ; N P ; B 20 -50 733 683 ; +C 81 ; WX 816.667 ; N Q ; B 113 -124 788 705 ; +C 82 ; WX 847.502 ; N R ; B 20 -22 837 683 ; +C 83 ; WX 605.556 ; N S ; B 18 -22 642 705 ; +C 84 ; WX 544.643 ; N T ; B 29 0 798 717 ; +C 85 ; WX 625.83 ; N U ; B -17 -28 688 683 ; +C 86 ; WX 612.781 ; N V ; B 35 -45 660 683 ; +C 87 ; WX 987.782 ; N W ; B 35 -45 1036 683 ; +C 88 ; WX 713.295 ; N X ; B 50 0 808 683 ; +C 89 ; WX 668.335 ; N Y ; B 31 -135 717 683 ; +C 90 ; WX 724.724 ; N Z ; B 37 0 767 683 ; +C 91 ; WX 666.667 ; N union ; B 56 -22 610 598 ; +C 92 ; WX 666.667 ; N intersection ; B 56 -22 610 598 ; +C 93 ; WX 666.667 ; N unionmulti ; B 56 -22 610 598 ; +C 94 ; WX 666.667 ; N logicaland ; B 56 -22 610 598 ; +C 95 ; WX 666.667 ; N logicalor ; B 56 -22 610 598 ; +C 96 ; WX 611.111 ; N turnstileleft ; B 56 0 554 694 ; +C 97 ; WX 611.111 ; N turnstileright ; B 56 0 554 694 ; +C 98 ; WX 444.444 ; N floorleft ; B 174 -250 422 750 ; +C 99 ; WX 444.444 ; N floorright ; B 21 -250 269 750 ; +C 100 ; WX 444.444 ; N ceilingleft ; B 174 -250 422 750 ; +C 101 ; WX 444.444 ; N ceilingright ; B 21 -250 269 750 ; +C 102 ; WX 500 ; N braceleft ; B 72 -250 427 750 ; +C 103 ; WX 500 ; N braceright ; B 72 -250 427 750 ; +C 104 ; WX 388.889 ; N angbracketleft ; B 110 -250 332 750 ; +C 105 ; WX 388.889 ; N angbracketright ; B 56 -250 278 750 ; +C 106 ; WX 277.778 ; N bar ; B 119 -250 159 750 ; +C 107 ; WX 500 ; N bardbl ; B 132 -250 367 750 ; +C 108 ; WX 500 ; N arrowbothv ; B 72 -272 428 772 ; +C 109 ; WX 611.111 ; N arrowdblbothv ; B 30 -272 580 772 ; +C 110 ; WX 500 ; N backslash ; B 56 -250 443 750 ; +C 111 ; WX 277.778 ; N wreathproduct ; B 56 -83 221 583 ; +C 112 ; WX 833.333 ; N radical ; B 73 -960 853 40 ; +C 113 ; WX 750 ; N coproduct ; B 36 0 713 683 ; +C 114 ; WX 833.333 ; N nabla ; B 47 -33 785 683 ; +C 115 ; WX 416.667 ; N integral ; B 56 -216 471 716 ; +C 116 ; WX 666.667 ; N unionsq ; B 61 0 605 598 ; +C 117 ; WX 666.667 ; N intersectionsq ; B 61 0 605 598 ; +C 118 ; WX 777.778 ; N subsetsqequal ; B 83 -137 714 636 ; +C 119 ; WX 777.778 ; N supersetsqequal ; B 63 -137 694 636 ; +C 120 ; WX 444.444 ; N section ; B 69 -205 374 705 ; +C 121 ; WX 444.444 ; N dagger ; B 56 -216 387 705 ; +C 122 ; WX 444.444 ; N daggerdbl ; B 56 -205 387 705 ; +C 123 ; WX 611.111 ; N paragraph ; B 56 -194 582 694 ; +C 124 ; WX 777.778 ; N club ; B 28 -130 750 727 ; +C 125 ; WX 777.778 ; N diamond ; B 56 -163 722 727 ; +C 126 ; WX 777.778 ; N heart ; B 56 -33 722 716 ; +C 127 ; WX 777.778 ; N spade ; B 56 -130 722 727 ; +C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ; +EndCharMetrics +Comment The following are bogus kern pairs for TeX positioning of accents +StartKernData +StartKernPairs 26 +KPX A prime 194.444 +KPX B prime 138.889 +KPX C prime 138.889 +KPX D prime 83.333 +KPX E prime 111.111 +KPX F prime 111.111 +KPX G prime 111.111 +KPX H prime 111.111 +KPX I prime 27.778 +KPX J prime 166.667 +KPX K prime 55.556 +KPX L prime 138.889 +KPX M prime 138.889 +KPX N prime 83.333 +KPX O prime 111.111 +KPX P prime 83.333 +KPX Q prime 111.111 +KPX R prime 83.333 +KPX S prime 138.889 +KPX T prime 27.778 +KPX U prime 83.333 +KPX V prime 27.778 +KPX W prime 83.333 +KPX X prime 138.889 +KPX Y prime 83.333 +KPX Z prime 138.889 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmtt10.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmtt10.afm new file mode 100644 index 00000000..d6ec19b0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/cmtt10.afm @@ -0,0 +1,156 @@ +StartFontMetrics 2.0 +Comment Creation Date: Thu Jun 21 22:23:51 1990 +Comment UniqueID 5000832 +FontName CMTT10 +EncodingScheme FontSpecific +FullName CMTT10 +FamilyName Computer Modern +Weight Medium +ItalicAngle 0.0 +IsFixedPitch true +Version 1.00B +Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved. +Comment Computer Modern fonts were designed by Donald E. Knuth +FontBBox -4 -235 731 800 +CapHeight 611.111 +XHeight 430.556 +Ascender 611.111 +Descender -222.222 +Comment FontID CMTT +Comment DesignSize 10 (pts) +Comment CharacterCodingScheme TeX typewriter text +Comment Space 525 0 0 +Comment ExtraSpace 525 +Comment Quad 1050 +StartCharMetrics 129 +C 0 ; WX 525 ; N Gamma ; B 32 0 488 611 ; +C 1 ; WX 525 ; N Delta ; B 34 0 490 623 ; +C 2 ; WX 525 ; N Theta ; B 56 -11 468 622 ; +C 3 ; WX 525 ; N Lambda ; B 29 0 495 623 ; +C 4 ; WX 525 ; N Xi ; B 33 0 491 611 ; +C 5 ; WX 525 ; N Pi ; B 22 0 502 611 ; +C 6 ; WX 525 ; N Sigma ; B 40 0 484 611 ; +C 7 ; WX 525 ; N Upsilon ; B 38 0 486 622 ; +C 8 ; WX 525 ; N Phi ; B 40 0 484 611 ; +C 9 ; WX 525 ; N Psi ; B 38 0 486 611 ; +C 10 ; WX 525 ; N Omega ; B 32 0 492 622 ; +C 11 ; WX 525 ; N arrowup ; B 59 0 465 611 ; +C 12 ; WX 525 ; N arrowdown ; B 59 0 465 611 ; +C 13 ; WX 525 ; N quotesingle ; B 217 328 309 622 ; +C 14 ; WX 525 ; N exclamdown ; B 212 -233 312 389 ; +C 15 ; WX 525 ; N questiondown ; B 62 -228 462 389 ; +C 16 ; WX 525 ; N dotlessi ; B 78 0 455 431 ; +C 17 ; WX 525 ; N dotlessj ; B 48 -228 368 431 ; +C 18 ; WX 525 ; N grave ; B 117 477 329 611 ; +C 19 ; WX 525 ; N acute ; B 195 477 407 611 ; +C 20 ; WX 525 ; N caron ; B 101 454 423 572 ; +C 21 ; WX 525 ; N breve ; B 86 498 438 611 ; +C 22 ; WX 525 ; N macron ; B 73 514 451 577 ; +C 23 ; WX 525 ; N ring ; B 181 499 343 619 ; +C 24 ; WX 525 ; N cedilla ; B 162 -208 428 45 ; +C 25 ; WX 525 ; N germandbls ; B 17 -6 495 617 ; +C 26 ; WX 525 ; N ae ; B 33 -6 504 440 ; +C 27 ; WX 525 ; N oe ; B 19 -6 505 440 ; +C 28 ; WX 525 ; N oslash ; B 43 -140 481 571 ; +C 29 ; WX 525 ; N AE ; B 23 0 499 611 ; +C 30 ; WX 525 ; N OE ; B 29 -11 502 622 ; +C 31 ; WX 525 ; N Oslash ; B 56 -85 468 696 ; +C 32 ; WX 525 ; N visiblespace ; B 44 -132 480 240 ; +C 33 ; WX 525 ; N exclam ; B 212 0 312 622 ; L quoteleft exclamdown ; +C 34 ; WX 525 ; N quotedbl ; B 126 328 398 622 ; +C 35 ; WX 525 ; N numbersign ; B 35 0 489 611 ; +C 36 ; WX 525 ; N dollar ; B 58 -83 466 694 ; +C 37 ; WX 525 ; N percent ; B 35 -83 489 694 ; +C 38 ; WX 525 ; N ampersand ; B 28 -11 490 622 ; +C 39 ; WX 525 ; N quoteright ; B 180 302 341 611 ; +C 40 ; WX 525 ; N parenleft ; B 173 -82 437 694 ; +C 41 ; WX 525 ; N parenright ; B 88 -82 352 694 ; +C 42 ; WX 525 ; N asterisk ; B 68 90 456 521 ; +C 43 ; WX 525 ; N plus ; B 38 81 486 531 ; +C 44 ; WX 525 ; N comma ; B 180 -139 346 125 ; +C 45 ; WX 525 ; N hyphen ; B 56 271 468 341 ; +C 46 ; WX 525 ; N period ; B 200 0 325 125 ; +C 47 ; WX 525 ; N slash ; B 58 -83 466 694 ; +C 48 ; WX 525 ; N zero ; B 50 -11 474 622 ; +C 49 ; WX 525 ; N one ; B 105 0 442 622 ; +C 50 ; WX 525 ; N two ; B 52 0 472 622 ; +C 51 ; WX 525 ; N three ; B 44 -11 480 622 ; +C 52 ; WX 525 ; N four ; B 29 0 495 623 ; +C 53 ; WX 525 ; N five ; B 52 -11 472 611 ; +C 54 ; WX 525 ; N six ; B 53 -11 471 622 ; +C 55 ; WX 525 ; N seven ; B 44 -11 480 627 ; +C 56 ; WX 525 ; N eight ; B 44 -11 480 622 ; +C 57 ; WX 525 ; N nine ; B 53 -11 471 622 ; +C 58 ; WX 525 ; N colon ; B 200 0 325 431 ; +C 59 ; WX 525 ; N semicolon ; B 180 -139 330 431 ; +C 60 ; WX 525 ; N less ; B 56 56 468 556 ; +C 61 ; WX 525 ; N equal ; B 38 195 486 417 ; +C 62 ; WX 525 ; N greater ; B 56 56 468 556 ; +C 63 ; WX 525 ; N question ; B 62 0 462 617 ; L quoteleft questiondown ; +C 64 ; WX 525 ; N at ; B 44 -6 480 617 ; +C 65 ; WX 525 ; N A ; B 27 0 497 623 ; +C 66 ; WX 525 ; N B ; B 23 0 482 611 ; +C 67 ; WX 525 ; N C ; B 40 -11 484 622 ; +C 68 ; WX 525 ; N D ; B 19 0 485 611 ; +C 69 ; WX 525 ; N E ; B 26 0 502 611 ; +C 70 ; WX 525 ; N F ; B 28 0 490 611 ; +C 71 ; WX 525 ; N G ; B 38 -11 496 622 ; +C 72 ; WX 525 ; N H ; B 22 0 502 611 ; +C 73 ; WX 525 ; N I ; B 79 0 446 611 ; +C 74 ; WX 525 ; N J ; B 71 -11 478 611 ; +C 75 ; WX 525 ; N K ; B 26 0 495 611 ; +C 76 ; WX 525 ; N L ; B 32 0 488 611 ; +C 77 ; WX 525 ; N M ; B 17 0 507 611 ; +C 78 ; WX 525 ; N N ; B 28 0 496 611 ; +C 79 ; WX 525 ; N O ; B 56 -11 468 622 ; +C 80 ; WX 525 ; N P ; B 26 0 480 611 ; +C 81 ; WX 525 ; N Q ; B 56 -139 468 622 ; +C 82 ; WX 525 ; N R ; B 22 -11 522 611 ; +C 83 ; WX 525 ; N S ; B 52 -11 472 622 ; +C 84 ; WX 525 ; N T ; B 26 0 498 611 ; +C 85 ; WX 525 ; N U ; B 4 -11 520 611 ; +C 86 ; WX 525 ; N V ; B 18 -8 506 611 ; +C 87 ; WX 525 ; N W ; B 11 -8 513 611 ; +C 88 ; WX 525 ; N X ; B 27 0 496 611 ; +C 89 ; WX 525 ; N Y ; B 19 0 505 611 ; +C 90 ; WX 525 ; N Z ; B 48 0 481 611 ; +C 91 ; WX 525 ; N bracketleft ; B 222 -83 483 694 ; +C 92 ; WX 525 ; N backslash ; B 58 -83 466 694 ; +C 93 ; WX 525 ; N bracketright ; B 41 -83 302 694 ; +C 94 ; WX 525 ; N asciicircum ; B 100 471 424 611 ; +C 95 ; WX 525 ; N underscore ; B 56 -95 468 -25 ; +C 96 ; WX 525 ; N quoteleft ; B 183 372 344 681 ; +C 97 ; WX 525 ; N a ; B 55 -6 524 440 ; +C 98 ; WX 525 ; N b ; B 12 -6 488 611 ; +C 99 ; WX 525 ; N c ; B 73 -6 466 440 ; +C 100 ; WX 525 ; N d ; B 36 -6 512 611 ; +C 101 ; WX 525 ; N e ; B 55 -6 464 440 ; +C 102 ; WX 525 ; N f ; B 42 0 437 617 ; +C 103 ; WX 525 ; N g ; B 29 -229 509 442 ; +C 104 ; WX 525 ; N h ; B 12 0 512 611 ; +C 105 ; WX 525 ; N i ; B 78 0 455 612 ; +C 106 ; WX 525 ; N j ; B 48 -228 368 612 ; +C 107 ; WX 525 ; N k ; B 21 0 508 611 ; +C 108 ; WX 525 ; N l ; B 58 0 467 611 ; +C 109 ; WX 525 ; N m ; B -4 0 516 437 ; +C 110 ; WX 525 ; N n ; B 12 0 512 437 ; +C 111 ; WX 525 ; N o ; B 57 -6 467 440 ; +C 112 ; WX 525 ; N p ; B 12 -222 488 437 ; +C 113 ; WX 525 ; N q ; B 40 -222 537 437 ; +C 114 ; WX 525 ; N r ; B 32 0 487 437 ; +C 115 ; WX 525 ; N s ; B 72 -6 459 440 ; +C 116 ; WX 525 ; N t ; B 25 -6 449 554 ; +C 117 ; WX 525 ; N u ; B 12 -6 512 431 ; +C 118 ; WX 525 ; N v ; B 24 -4 500 431 ; +C 119 ; WX 525 ; N w ; B 16 -4 508 431 ; +C 120 ; WX 525 ; N x ; B 27 0 496 431 ; +C 121 ; WX 525 ; N y ; B 26 -228 500 431 ; +C 122 ; WX 525 ; N z ; B 33 0 475 431 ; +C 123 ; WX 525 ; N braceleft ; B 57 -83 467 694 ; +C 124 ; WX 525 ; N bar ; B 227 -83 297 694 ; +C 125 ; WX 525 ; N braceright ; B 57 -83 467 694 ; +C 126 ; WX 525 ; N asciitilde ; B 87 491 437 611 ; +C 127 ; WX 525 ; N dieresis ; B 110 512 414 612 ; +C -1 ; WX 525 ; N space ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagd8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagd8a.afm new file mode 100644 index 00000000..69eebba1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagd8a.afm @@ -0,0 +1,576 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Mar 4 13:46:34 1991 +Comment UniqueID 34370 +Comment VMusage 24954 31846 +FontName AvantGarde-Demi +FullName ITC Avant Garde Gothic Demi +FamilyName ITC Avant Garde Gothic +Weight Demi +ItalicAngle 0 +IsFixedPitch false +FontBBox -123 -251 1222 1021 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 740 +XHeight 555 +Ascender 740 +Descender -185 +StartCharMetrics 228 +C 32 ; WX 280 ; N space ; B 0 0 0 0 ; +C 33 ; WX 280 ; N exclam ; B 73 0 206 740 ; +C 34 ; WX 360 ; N quotedbl ; B 19 444 341 740 ; +C 35 ; WX 560 ; N numbersign ; B 29 0 525 700 ; +C 36 ; WX 560 ; N dollar ; B 58 -86 501 857 ; +C 37 ; WX 860 ; N percent ; B 36 -15 822 755 ; +C 38 ; WX 680 ; N ampersand ; B 34 -15 665 755 ; +C 39 ; WX 280 ; N quoteright ; B 72 466 205 740 ; +C 40 ; WX 380 ; N parenleft ; B 74 -157 350 754 ; +C 41 ; WX 380 ; N parenright ; B 37 -157 313 754 ; +C 42 ; WX 440 ; N asterisk ; B 67 457 374 755 ; +C 43 ; WX 600 ; N plus ; B 48 0 552 506 ; +C 44 ; WX 280 ; N comma ; B 73 -141 206 133 ; +C 45 ; WX 420 ; N hyphen ; B 71 230 349 348 ; +C 46 ; WX 280 ; N period ; B 73 0 206 133 ; +C 47 ; WX 460 ; N slash ; B 6 -100 454 740 ; +C 48 ; WX 560 ; N zero ; B 32 -15 529 755 ; +C 49 ; WX 560 ; N one ; B 137 0 363 740 ; +C 50 ; WX 560 ; N two ; B 36 0 523 755 ; +C 51 ; WX 560 ; N three ; B 28 -15 532 755 ; +C 52 ; WX 560 ; N four ; B 15 0 545 740 ; +C 53 ; WX 560 ; N five ; B 25 -15 535 740 ; +C 54 ; WX 560 ; N six ; B 23 -15 536 739 ; +C 55 ; WX 560 ; N seven ; B 62 0 498 740 ; +C 56 ; WX 560 ; N eight ; B 33 -15 527 755 ; +C 57 ; WX 560 ; N nine ; B 24 0 537 754 ; +C 58 ; WX 280 ; N colon ; B 73 0 206 555 ; +C 59 ; WX 280 ; N semicolon ; B 73 -141 206 555 ; +C 60 ; WX 600 ; N less ; B 46 -8 554 514 ; +C 61 ; WX 600 ; N equal ; B 48 81 552 425 ; +C 62 ; WX 600 ; N greater ; B 46 -8 554 514 ; +C 63 ; WX 560 ; N question ; B 38 0 491 755 ; +C 64 ; WX 740 ; N at ; B 50 -12 750 712 ; +C 65 ; WX 740 ; N A ; B 7 0 732 740 ; +C 66 ; WX 580 ; N B ; B 70 0 551 740 ; +C 67 ; WX 780 ; N C ; B 34 -15 766 755 ; +C 68 ; WX 700 ; N D ; B 63 0 657 740 ; +C 69 ; WX 520 ; N E ; B 61 0 459 740 ; +C 70 ; WX 480 ; N F ; B 61 0 438 740 ; +C 71 ; WX 840 ; N G ; B 27 -15 817 755 ; +C 72 ; WX 680 ; N H ; B 71 0 610 740 ; +C 73 ; WX 280 ; N I ; B 72 0 209 740 ; +C 74 ; WX 480 ; N J ; B 2 -15 409 740 ; +C 75 ; WX 620 ; N K ; B 89 0 620 740 ; +C 76 ; WX 440 ; N L ; B 72 0 435 740 ; +C 77 ; WX 900 ; N M ; B 63 0 837 740 ; +C 78 ; WX 740 ; N N ; B 70 0 671 740 ; +C 79 ; WX 840 ; N O ; B 33 -15 807 755 ; +C 80 ; WX 560 ; N P ; B 72 0 545 740 ; +C 81 ; WX 840 ; N Q ; B 32 -15 824 755 ; +C 82 ; WX 580 ; N R ; B 64 0 565 740 ; +C 83 ; WX 520 ; N S ; B 12 -15 493 755 ; +C 84 ; WX 420 ; N T ; B 6 0 418 740 ; +C 85 ; WX 640 ; N U ; B 55 -15 585 740 ; +C 86 ; WX 700 ; N V ; B 8 0 695 740 ; +C 87 ; WX 900 ; N W ; B 7 0 899 740 ; +C 88 ; WX 680 ; N X ; B 4 0 676 740 ; +C 89 ; WX 620 ; N Y ; B -2 0 622 740 ; +C 90 ; WX 500 ; N Z ; B 19 0 481 740 ; +C 91 ; WX 320 ; N bracketleft ; B 66 -157 284 754 ; +C 92 ; WX 640 ; N backslash ; B 96 -100 544 740 ; +C 93 ; WX 320 ; N bracketright ; B 36 -157 254 754 ; +C 94 ; WX 600 ; N asciicircum ; B 73 375 527 740 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 280 ; N quoteleft ; B 72 466 205 740 ; +C 97 ; WX 660 ; N a ; B 27 -18 613 574 ; +C 98 ; WX 660 ; N b ; B 47 -18 632 740 ; +C 99 ; WX 640 ; N c ; B 37 -18 610 574 ; +C 100 ; WX 660 ; N d ; B 34 -18 618 740 ; +C 101 ; WX 640 ; N e ; B 31 -18 610 577 ; +C 102 ; WX 280 ; N f ; B 15 0 280 755 ; L i fi ; L l fl ; +C 103 ; WX 660 ; N g ; B 32 -226 623 574 ; +C 104 ; WX 600 ; N h ; B 54 0 546 740 ; +C 105 ; WX 240 ; N i ; B 53 0 186 740 ; +C 106 ; WX 260 ; N j ; B 16 -185 205 740 ; +C 107 ; WX 580 ; N k ; B 80 0 571 740 ; +C 108 ; WX 240 ; N l ; B 54 0 187 740 ; +C 109 ; WX 940 ; N m ; B 54 0 887 574 ; +C 110 ; WX 600 ; N n ; B 54 0 547 574 ; +C 111 ; WX 640 ; N o ; B 25 -18 615 574 ; +C 112 ; WX 660 ; N p ; B 47 -185 629 574 ; +C 113 ; WX 660 ; N q ; B 31 -185 613 574 ; +C 114 ; WX 320 ; N r ; B 63 0 317 574 ; +C 115 ; WX 440 ; N s ; B 19 -18 421 574 ; +C 116 ; WX 300 ; N t ; B 21 0 299 740 ; +C 117 ; WX 600 ; N u ; B 50 -18 544 555 ; +C 118 ; WX 560 ; N v ; B 3 0 556 555 ; +C 119 ; WX 800 ; N w ; B 11 0 789 555 ; +C 120 ; WX 560 ; N x ; B 3 0 556 555 ; +C 121 ; WX 580 ; N y ; B 8 -185 571 555 ; +C 122 ; WX 460 ; N z ; B 20 0 442 555 ; +C 123 ; WX 340 ; N braceleft ; B -3 -191 317 747 ; +C 124 ; WX 600 ; N bar ; B 233 -100 366 740 ; +C 125 ; WX 340 ; N braceright ; B 23 -191 343 747 ; +C 126 ; WX 600 ; N asciitilde ; B 67 160 533 347 ; +C 161 ; WX 280 ; N exclamdown ; B 74 -185 207 555 ; +C 162 ; WX 560 ; N cent ; B 43 39 517 715 ; +C 163 ; WX 560 ; N sterling ; B -2 0 562 755 ; +C 164 ; WX 160 ; N fraction ; B -123 0 282 740 ; +C 165 ; WX 560 ; N yen ; B -10 0 570 740 ; +C 166 ; WX 560 ; N florin ; B 0 -151 512 824 ; +C 167 ; WX 560 ; N section ; B 28 -158 530 755 ; +C 168 ; WX 560 ; N currency ; B 27 69 534 577 ; +C 169 ; WX 220 ; N quotesingle ; B 44 444 177 740 ; +C 170 ; WX 480 ; N quotedblleft ; B 70 466 410 740 ; +C 171 ; WX 460 ; N guillemotleft ; B 61 108 400 469 ; +C 172 ; WX 240 ; N guilsinglleft ; B 50 108 190 469 ; +C 173 ; WX 240 ; N guilsinglright ; B 50 108 190 469 ; +C 174 ; WX 520 ; N fi ; B 25 0 461 755 ; +C 175 ; WX 520 ; N fl ; B 25 0 461 755 ; +C 177 ; WX 500 ; N endash ; B 35 230 465 348 ; +C 178 ; WX 560 ; N dagger ; B 51 -142 509 740 ; +C 179 ; WX 560 ; N daggerdbl ; B 51 -142 509 740 ; +C 180 ; WX 280 ; N periodcentered ; B 73 187 206 320 ; +C 182 ; WX 600 ; N paragraph ; B -7 -103 607 740 ; +C 183 ; WX 600 ; N bullet ; B 148 222 453 532 ; +C 184 ; WX 280 ; N quotesinglbase ; B 72 -141 205 133 ; +C 185 ; WX 480 ; N quotedblbase ; B 70 -141 410 133 ; +C 186 ; WX 480 ; N quotedblright ; B 70 466 410 740 ; +C 187 ; WX 460 ; N guillemotright ; B 61 108 400 469 ; +C 188 ; WX 1000 ; N ellipsis ; B 100 0 899 133 ; +C 189 ; WX 1280 ; N perthousand ; B 36 -15 1222 755 ; +C 191 ; WX 560 ; N questiondown ; B 68 -200 521 555 ; +C 193 ; WX 420 ; N grave ; B 50 624 329 851 ; +C 194 ; WX 420 ; N acute ; B 91 624 370 849 ; +C 195 ; WX 540 ; N circumflex ; B 71 636 470 774 ; +C 196 ; WX 480 ; N tilde ; B 44 636 437 767 ; +C 197 ; WX 420 ; N macron ; B 72 648 349 759 ; +C 198 ; WX 480 ; N breve ; B 42 633 439 770 ; +C 199 ; WX 280 ; N dotaccent ; B 74 636 207 769 ; +C 200 ; WX 500 ; N dieresis ; B 78 636 422 769 ; +C 202 ; WX 360 ; N ring ; B 73 619 288 834 ; +C 203 ; WX 340 ; N cedilla ; B 98 -251 298 6 ; +C 205 ; WX 700 ; N hungarumlaut ; B 132 610 609 862 ; +C 206 ; WX 340 ; N ogonek ; B 79 -195 262 9 ; +C 207 ; WX 540 ; N caron ; B 71 636 470 774 ; +C 208 ; WX 1000 ; N emdash ; B 35 230 965 348 ; +C 225 ; WX 900 ; N AE ; B -5 0 824 740 ; +C 227 ; WX 360 ; N ordfeminine ; B 19 438 334 755 ; +C 232 ; WX 480 ; N Lslash ; B 26 0 460 740 ; +C 233 ; WX 840 ; N Oslash ; B 33 -71 807 814 ; +C 234 ; WX 1060 ; N OE ; B 37 -15 1007 755 ; +C 235 ; WX 360 ; N ordmasculine ; B 23 438 338 755 ; +C 241 ; WX 1080 ; N ae ; B 29 -18 1048 574 ; +C 245 ; WX 240 ; N dotlessi ; B 53 0 186 555 ; +C 248 ; WX 320 ; N lslash ; B 34 0 305 740 ; +C 249 ; WX 660 ; N oslash ; B 35 -50 625 608 ; +C 250 ; WX 1080 ; N oe ; B 30 -18 1050 574 ; +C 251 ; WX 600 ; N germandbls ; B 51 -18 585 755 ; +C -1 ; WX 640 ; N ecircumflex ; B 31 -18 610 774 ; +C -1 ; WX 640 ; N edieresis ; B 31 -18 610 769 ; +C -1 ; WX 660 ; N aacute ; B 27 -18 613 849 ; +C -1 ; WX 740 ; N registered ; B -12 -12 752 752 ; +C -1 ; WX 240 ; N icircumflex ; B -79 0 320 774 ; +C -1 ; WX 600 ; N udieresis ; B 50 -18 544 769 ; +C -1 ; WX 640 ; N ograve ; B 25 -18 615 851 ; +C -1 ; WX 600 ; N uacute ; B 50 -18 544 849 ; +C -1 ; WX 600 ; N ucircumflex ; B 50 -18 544 774 ; +C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ; +C -1 ; WX 240 ; N igrave ; B -65 0 214 851 ; +C -1 ; WX 280 ; N Icircumflex ; B -59 0 340 944 ; +C -1 ; WX 640 ; N ccedilla ; B 37 -251 610 574 ; +C -1 ; WX 660 ; N adieresis ; B 27 -18 613 769 ; +C -1 ; WX 520 ; N Ecircumflex ; B 61 0 460 944 ; +C -1 ; WX 440 ; N scaron ; B 19 -18 421 774 ; +C -1 ; WX 660 ; N thorn ; B 47 -185 629 740 ; +C -1 ; WX 1000 ; N trademark ; B 9 296 821 740 ; +C -1 ; WX 640 ; N egrave ; B 31 -18 610 851 ; +C -1 ; WX 336 ; N threesuperior ; B 8 287 328 749 ; +C -1 ; WX 460 ; N zcaron ; B 20 0 455 774 ; +C -1 ; WX 660 ; N atilde ; B 27 -18 613 767 ; +C -1 ; WX 660 ; N aring ; B 27 -18 613 834 ; +C -1 ; WX 640 ; N ocircumflex ; B 25 -18 615 774 ; +C -1 ; WX 520 ; N Edieresis ; B 61 0 459 939 ; +C -1 ; WX 840 ; N threequarters ; B 18 0 803 749 ; +C -1 ; WX 580 ; N ydieresis ; B 8 -185 571 769 ; +C -1 ; WX 580 ; N yacute ; B 8 -185 571 849 ; +C -1 ; WX 240 ; N iacute ; B 26 0 305 849 ; +C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ; +C -1 ; WX 640 ; N Uacute ; B 55 -15 585 1019 ; +C -1 ; WX 640 ; N eacute ; B 31 -18 610 849 ; +C -1 ; WX 840 ; N Ograve ; B 33 -15 807 1021 ; +C -1 ; WX 660 ; N agrave ; B 27 -18 613 851 ; +C -1 ; WX 640 ; N Udieresis ; B 55 -15 585 939 ; +C -1 ; WX 660 ; N acircumflex ; B 27 -18 613 774 ; +C -1 ; WX 280 ; N Igrave ; B -45 0 234 1021 ; +C -1 ; WX 336 ; N twosuperior ; B 13 296 322 749 ; +C -1 ; WX 640 ; N Ugrave ; B 55 -15 585 1021 ; +C -1 ; WX 840 ; N onequarter ; B 92 0 746 740 ; +C -1 ; WX 640 ; N Ucircumflex ; B 55 -15 585 944 ; +C -1 ; WX 520 ; N Scaron ; B 12 -15 493 944 ; +C -1 ; WX 280 ; N Idieresis ; B -32 0 312 939 ; +C -1 ; WX 240 ; N idieresis ; B -52 0 292 769 ; +C -1 ; WX 520 ; N Egrave ; B 61 0 459 1021 ; +C -1 ; WX 840 ; N Oacute ; B 33 -15 807 1019 ; +C -1 ; WX 600 ; N divide ; B 48 -20 552 526 ; +C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ; +C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ; +C -1 ; WX 840 ; N Odieresis ; B 33 -15 807 939 ; +C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ; +C -1 ; WX 740 ; N Ntilde ; B 70 0 671 937 ; +C -1 ; WX 500 ; N Zcaron ; B 19 0 481 944 ; +C -1 ; WX 560 ; N Thorn ; B 72 0 545 740 ; +C -1 ; WX 280 ; N Iacute ; B 46 0 325 1019 ; +C -1 ; WX 600 ; N plusminus ; B 48 -62 552 556 ; +C -1 ; WX 600 ; N multiply ; B 59 12 541 494 ; +C -1 ; WX 520 ; N Eacute ; B 61 0 459 1019 ; +C -1 ; WX 620 ; N Ydieresis ; B -2 0 622 939 ; +C -1 ; WX 336 ; N onesuperior ; B 72 296 223 740 ; +C -1 ; WX 600 ; N ugrave ; B 50 -18 544 851 ; +C -1 ; WX 600 ; N logicalnot ; B 48 108 552 425 ; +C -1 ; WX 600 ; N ntilde ; B 54 0 547 767 ; +C -1 ; WX 840 ; N Otilde ; B 33 -15 807 937 ; +C -1 ; WX 640 ; N otilde ; B 25 -18 615 767 ; +C -1 ; WX 780 ; N Ccedilla ; B 34 -251 766 755 ; +C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ; +C -1 ; WX 840 ; N onehalf ; B 62 0 771 740 ; +C -1 ; WX 742 ; N Eth ; B 25 0 691 740 ; +C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; +C -1 ; WX 620 ; N Yacute ; B -2 0 622 1019 ; +C -1 ; WX 840 ; N Ocircumflex ; B 33 -15 807 944 ; +C -1 ; WX 640 ; N oacute ; B 25 -18 615 849 ; +C -1 ; WX 576 ; N mu ; B 38 -187 539 555 ; +C -1 ; WX 600 ; N minus ; B 48 193 552 313 ; +C -1 ; WX 640 ; N eth ; B 27 -18 616 754 ; +C -1 ; WX 640 ; N odieresis ; B 25 -18 615 769 ; +C -1 ; WX 740 ; N copyright ; B -12 -12 752 752 ; +C -1 ; WX 600 ; N brokenbar ; B 233 -100 366 740 ; +EndCharMetrics +StartKernData +StartKernPairs 218 + +KPX A y -50 +KPX A w -65 +KPX A v -70 +KPX A u -20 +KPX A quoteright -90 +KPX A Y -80 +KPX A W -60 +KPX A V -102 +KPX A U -40 +KPX A T -25 +KPX A Q -50 +KPX A O -50 +KPX A G -40 +KPX A C -40 + +KPX B A -10 + +KPX C A -40 + +KPX D period -20 +KPX D comma -20 +KPX D Y -45 +KPX D W -25 +KPX D V -50 +KPX D A -50 + +KPX F period -129 +KPX F e -20 +KPX F comma -162 +KPX F a -20 +KPX F A -75 + +KPX G period -20 +KPX G comma -20 +KPX G Y -15 + +KPX J period -15 +KPX J a -20 +KPX J A -30 + +KPX K y -20 +KPX K u -15 +KPX K o -45 +KPX K e -40 +KPX K O -30 + +KPX L y -23 +KPX L quoteright -30 +KPX L quotedblright -30 +KPX L Y -80 +KPX L W -55 +KPX L V -85 +KPX L T -46 + +KPX O period -30 +KPX O comma -30 +KPX O Y -30 +KPX O X -30 +KPX O W -20 +KPX O V -45 +KPX O T -15 +KPX O A -60 + +KPX P period -200 +KPX P o -20 +KPX P e -20 +KPX P comma -220 +KPX P a -20 +KPX P A -100 + +KPX Q comma 20 + +KPX R W 25 +KPX R V -10 +KPX R U 25 +KPX R T 40 +KPX R O 25 + +KPX S comma 20 + +KPX T y -10 +KPX T w -55 +KPX T u -46 +KPX T semicolon -29 +KPX T r -30 +KPX T period -91 +KPX T o -49 +KPX T hyphen -75 +KPX T e -49 +KPX T comma -82 +KPX T colon -15 +KPX T a -70 +KPX T O -15 +KPX T A -25 + +KPX U period -20 +KPX U comma -20 +KPX U A -40 + +KPX V u -55 +KPX V semicolon -33 +KPX V period -145 +KPX V o -101 +KPX V i -15 +KPX V hyphen -75 +KPX V e -101 +KPX V comma -145 +KPX V colon -18 +KPX V a -95 +KPX V O -45 +KPX V G -20 +KPX V A -102 + +KPX W y -15 +KPX W u -30 +KPX W semicolon -33 +KPX W period -106 +KPX W o -46 +KPX W i -10 +KPX W hyphen -35 +KPX W e -47 +KPX W comma -106 +KPX W colon -15 +KPX W a -50 +KPX W O -20 +KPX W A -58 + +KPX Y u -52 +KPX Y semicolon -23 +KPX Y period -145 +KPX Y o -89 +KPX Y hyphen -100 +KPX Y e -89 +KPX Y comma -145 +KPX Y colon -10 +KPX Y a -93 +KPX Y O -30 +KPX Y A -80 + +KPX a t 5 +KPX a p 20 +KPX a b 5 + +KPX b y -20 +KPX b v -20 + +KPX c y -20 +KPX c l -15 +KPX c k -15 + +KPX comma space -50 +KPX comma quoteright -70 +KPX comma quotedblright -70 + +KPX e y -20 +KPX e x -20 +KPX e w -20 +KPX e v -20 + +KPX f period -40 +KPX f o -20 +KPX f l -15 +KPX f i -15 +KPX f f -20 +KPX f dotlessi -15 +KPX f comma -40 +KPX f a -15 + +KPX g i 25 +KPX g a 15 + +KPX h y -30 + +KPX k y -5 +KPX k o -30 +KPX k e -40 + +KPX m y -20 +KPX m u -20 + +KPX n y -15 +KPX n v -30 + +KPX o y -20 +KPX o x -30 +KPX o w -20 +KPX o v -30 + +KPX p y -20 + +KPX period space -50 +KPX period quoteright -70 +KPX period quotedblright -70 + +KPX quotedblleft A -50 + +KPX quotedblright space -50 + +KPX quoteleft quoteleft -80 +KPX quoteleft A -50 + +KPX quoteright v -10 +KPX quoteright t 10 +KPX quoteright space -50 +KPX quoteright s -15 +KPX quoteright r -20 +KPX quoteright quoteright -80 +KPX quoteright d -50 + +KPX r y 40 +KPX r v 40 +KPX r u 20 +KPX r t 20 +KPX r s 20 +KPX r q -8 +KPX r period -73 +KPX r p 20 +KPX r o -15 +KPX r n 21 +KPX r m 15 +KPX r l 20 +KPX r k 5 +KPX r i 20 +KPX r hyphen -60 +KPX r g 1 +KPX r e -4 +KPX r d -6 +KPX r comma -75 +KPX r c -7 + +KPX s period 20 +KPX s comma 20 + +KPX space quoteleft -50 +KPX space quotedblleft -50 +KPX space Y -60 +KPX space W -25 +KPX space V -80 +KPX space T -25 +KPX space A -20 + +KPX v period -90 +KPX v o -20 +KPX v e -20 +KPX v comma -90 +KPX v a -30 + +KPX w period -90 +KPX w o -30 +KPX w e -20 +KPX w comma -90 +KPX w a -30 + +KPX x e -20 + +KPX y period -100 +KPX y o -30 +KPX y e -20 +KPX y comma -100 +KPX y c -35 +KPX y a -30 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 100 170 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 120 170 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 170 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 190 135 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 170 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 50 170 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex -10 170 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 10 170 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 50 170 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -45 170 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -130 170 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -110 170 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -95 170 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 170 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 170 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 170 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 170 170 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 170 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 170 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron -10 170 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 145 170 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 50 170 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 70 170 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 75 170 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 135 170 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 60 170 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 5 170 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagdo8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagdo8a.afm new file mode 100644 index 00000000..c348b117 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagdo8a.afm @@ -0,0 +1,576 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Mar 4 13:49:44 1991 +Comment UniqueID 34373 +Comment VMusage 6550 39938 +FontName AvantGarde-DemiOblique +FullName ITC Avant Garde Gothic Demi Oblique +FamilyName ITC Avant Garde Gothic +Weight Demi +ItalicAngle -10.5 +IsFixedPitch false +FontBBox -123 -251 1256 1021 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 740 +XHeight 555 +Ascender 740 +Descender -185 +StartCharMetrics 228 +C 32 ; WX 280 ; N space ; B 0 0 0 0 ; +C 33 ; WX 280 ; N exclam ; B 73 0 343 740 ; +C 34 ; WX 360 ; N quotedbl ; B 127 444 478 740 ; +C 35 ; WX 560 ; N numbersign ; B 66 0 618 700 ; +C 36 ; WX 560 ; N dollar ; B 99 -86 582 857 ; +C 37 ; WX 860 ; N percent ; B 139 -15 856 755 ; +C 38 ; WX 680 ; N ampersand ; B 71 -15 742 755 ; +C 39 ; WX 280 ; N quoteright ; B 159 466 342 740 ; +C 40 ; WX 380 ; N parenleft ; B 120 -157 490 754 ; +C 41 ; WX 380 ; N parenright ; B 8 -157 378 754 ; +C 42 ; WX 440 ; N asterisk ; B 174 457 492 755 ; +C 43 ; WX 600 ; N plus ; B 84 0 610 506 ; +C 44 ; WX 280 ; N comma ; B 48 -141 231 133 ; +C 45 ; WX 420 ; N hyphen ; B 114 230 413 348 ; +C 46 ; WX 280 ; N period ; B 73 0 231 133 ; +C 47 ; WX 460 ; N slash ; B -13 -100 591 740 ; +C 48 ; WX 560 ; N zero ; B 70 -15 628 755 ; +C 49 ; WX 560 ; N one ; B 230 0 500 740 ; +C 50 ; WX 560 ; N two ; B 44 0 622 755 ; +C 51 ; WX 560 ; N three ; B 67 -15 585 755 ; +C 52 ; WX 560 ; N four ; B 36 0 604 740 ; +C 53 ; WX 560 ; N five ; B 64 -15 600 740 ; +C 54 ; WX 560 ; N six ; B 64 -15 587 739 ; +C 55 ; WX 560 ; N seven ; B 83 0 635 740 ; +C 56 ; WX 560 ; N eight ; B 71 -15 590 755 ; +C 57 ; WX 560 ; N nine ; B 110 0 633 754 ; +C 58 ; WX 280 ; N colon ; B 73 0 309 555 ; +C 59 ; WX 280 ; N semicolon ; B 48 -141 309 555 ; +C 60 ; WX 600 ; N less ; B 84 -8 649 514 ; +C 61 ; WX 600 ; N equal ; B 63 81 631 425 ; +C 62 ; WX 600 ; N greater ; B 45 -8 610 514 ; +C 63 ; WX 560 ; N question ; B 135 0 593 755 ; +C 64 ; WX 740 ; N at ; B 109 -12 832 712 ; +C 65 ; WX 740 ; N A ; B 7 0 732 740 ; +C 66 ; WX 580 ; N B ; B 70 0 610 740 ; +C 67 ; WX 780 ; N C ; B 97 -15 864 755 ; +C 68 ; WX 700 ; N D ; B 63 0 732 740 ; +C 69 ; WX 520 ; N E ; B 61 0 596 740 ; +C 70 ; WX 480 ; N F ; B 61 0 575 740 ; +C 71 ; WX 840 ; N G ; B 89 -15 887 755 ; +C 72 ; WX 680 ; N H ; B 71 0 747 740 ; +C 73 ; WX 280 ; N I ; B 72 0 346 740 ; +C 74 ; WX 480 ; N J ; B 34 -15 546 740 ; +C 75 ; WX 620 ; N K ; B 89 0 757 740 ; +C 76 ; WX 440 ; N L ; B 72 0 459 740 ; +C 77 ; WX 900 ; N M ; B 63 0 974 740 ; +C 78 ; WX 740 ; N N ; B 70 0 808 740 ; +C 79 ; WX 840 ; N O ; B 95 -15 882 755 ; +C 80 ; WX 560 ; N P ; B 72 0 645 740 ; +C 81 ; WX 840 ; N Q ; B 94 -15 882 755 ; +C 82 ; WX 580 ; N R ; B 64 0 656 740 ; +C 83 ; WX 520 ; N S ; B 49 -15 578 755 ; +C 84 ; WX 420 ; N T ; B 119 0 555 740 ; +C 85 ; WX 640 ; N U ; B 97 -15 722 740 ; +C 86 ; WX 700 ; N V ; B 145 0 832 740 ; +C 87 ; WX 900 ; N W ; B 144 0 1036 740 ; +C 88 ; WX 680 ; N X ; B 4 0 813 740 ; +C 89 ; WX 620 ; N Y ; B 135 0 759 740 ; +C 90 ; WX 500 ; N Z ; B 19 0 599 740 ; +C 91 ; WX 320 ; N bracketleft ; B 89 -157 424 754 ; +C 92 ; WX 640 ; N backslash ; B 233 -100 525 740 ; +C 93 ; WX 320 ; N bracketright ; B 7 -157 342 754 ; +C 94 ; WX 600 ; N asciicircum ; B 142 375 596 740 ; +C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ; +C 96 ; WX 280 ; N quoteleft ; B 158 466 341 740 ; +C 97 ; WX 660 ; N a ; B 73 -18 716 574 ; +C 98 ; WX 660 ; N b ; B 47 -18 689 740 ; +C 99 ; WX 640 ; N c ; B 84 -18 679 574 ; +C 100 ; WX 660 ; N d ; B 80 -18 755 740 ; +C 101 ; WX 640 ; N e ; B 77 -18 667 577 ; +C 102 ; WX 280 ; N f ; B 62 0 420 755 ; L i fi ; L l fl ; +C 103 ; WX 660 ; N g ; B 33 -226 726 574 ; +C 104 ; WX 600 ; N h ; B 54 0 614 740 ; +C 105 ; WX 240 ; N i ; B 53 0 323 740 ; +C 106 ; WX 260 ; N j ; B -18 -185 342 740 ; +C 107 ; WX 580 ; N k ; B 80 0 648 740 ; +C 108 ; WX 240 ; N l ; B 54 0 324 740 ; +C 109 ; WX 940 ; N m ; B 54 0 954 574 ; +C 110 ; WX 600 ; N n ; B 54 0 613 574 ; +C 111 ; WX 640 ; N o ; B 71 -18 672 574 ; +C 112 ; WX 660 ; N p ; B 13 -185 686 574 ; +C 113 ; WX 660 ; N q ; B 78 -185 716 574 ; +C 114 ; WX 320 ; N r ; B 63 0 423 574 ; +C 115 ; WX 440 ; N s ; B 49 -18 483 574 ; +C 116 ; WX 300 ; N t ; B 86 0 402 740 ; +C 117 ; WX 600 ; N u ; B 87 -18 647 555 ; +C 118 ; WX 560 ; N v ; B 106 0 659 555 ; +C 119 ; WX 800 ; N w ; B 114 0 892 555 ; +C 120 ; WX 560 ; N x ; B 3 0 632 555 ; +C 121 ; WX 580 ; N y ; B 75 -185 674 555 ; +C 122 ; WX 460 ; N z ; B 20 0 528 555 ; +C 123 ; WX 340 ; N braceleft ; B 40 -191 455 747 ; +C 124 ; WX 600 ; N bar ; B 214 -100 503 740 ; +C 125 ; WX 340 ; N braceright ; B -12 -191 405 747 ; +C 126 ; WX 600 ; N asciitilde ; B 114 160 579 347 ; +C 161 ; WX 280 ; N exclamdown ; B 40 -185 310 555 ; +C 162 ; WX 560 ; N cent ; B 110 39 599 715 ; +C 163 ; WX 560 ; N sterling ; B 38 0 615 755 ; +C 164 ; WX 160 ; N fraction ; B -123 0 419 740 ; +C 165 ; WX 560 ; N yen ; B 83 0 707 740 ; +C 166 ; WX 560 ; N florin ; B -27 -151 664 824 ; +C 167 ; WX 560 ; N section ; B 65 -158 602 755 ; +C 168 ; WX 560 ; N currency ; B 53 69 628 577 ; +C 169 ; WX 220 ; N quotesingle ; B 152 444 314 740 ; +C 170 ; WX 480 ; N quotedblleft ; B 156 466 546 740 ; +C 171 ; WX 460 ; N guillemotleft ; B 105 108 487 469 ; +C 172 ; WX 240 ; N guilsinglleft ; B 94 108 277 469 ; +C 173 ; WX 240 ; N guilsinglright ; B 70 108 253 469 ; +C 174 ; WX 520 ; N fi ; B 72 0 598 755 ; +C 175 ; WX 520 ; N fl ; B 72 0 598 755 ; +C 177 ; WX 500 ; N endash ; B 78 230 529 348 ; +C 178 ; WX 560 ; N dagger ; B 133 -142 612 740 ; +C 179 ; WX 560 ; N daggerdbl ; B 63 -142 618 740 ; +C 180 ; WX 280 ; N periodcentered ; B 108 187 265 320 ; +C 182 ; WX 600 ; N paragraph ; B 90 -103 744 740 ; +C 183 ; WX 600 ; N bullet ; B 215 222 526 532 ; +C 184 ; WX 280 ; N quotesinglbase ; B 47 -141 230 133 ; +C 185 ; WX 480 ; N quotedblbase ; B 45 -141 435 133 ; +C 186 ; WX 480 ; N quotedblright ; B 157 466 547 740 ; +C 187 ; WX 460 ; N guillemotright ; B 81 108 463 469 ; +C 188 ; WX 1000 ; N ellipsis ; B 100 0 924 133 ; +C 189 ; WX 1280 ; N perthousand ; B 139 -15 1256 755 ; +C 191 ; WX 560 ; N questiondown ; B 69 -200 527 555 ; +C 193 ; WX 420 ; N grave ; B 189 624 462 851 ; +C 194 ; WX 420 ; N acute ; B 224 624 508 849 ; +C 195 ; WX 540 ; N circumflex ; B 189 636 588 774 ; +C 196 ; WX 480 ; N tilde ; B 178 636 564 767 ; +C 197 ; WX 420 ; N macron ; B 192 648 490 759 ; +C 198 ; WX 480 ; N breve ; B 185 633 582 770 ; +C 199 ; WX 280 ; N dotaccent ; B 192 636 350 769 ; +C 200 ; WX 500 ; N dieresis ; B 196 636 565 769 ; +C 202 ; WX 360 ; N ring ; B 206 619 424 834 ; +C 203 ; WX 340 ; N cedilla ; B 67 -251 272 6 ; +C 205 ; WX 700 ; N hungarumlaut ; B 258 610 754 862 ; +C 206 ; WX 340 ; N ogonek ; B 59 -195 243 9 ; +C 207 ; WX 540 ; N caron ; B 214 636 613 774 ; +C 208 ; WX 1000 ; N emdash ; B 78 230 1029 348 ; +C 225 ; WX 900 ; N AE ; B -5 0 961 740 ; +C 227 ; WX 360 ; N ordfeminine ; B 127 438 472 755 ; +C 232 ; WX 480 ; N Lslash ; B 68 0 484 740 ; +C 233 ; WX 840 ; N Oslash ; B 94 -71 891 814 ; +C 234 ; WX 1060 ; N OE ; B 98 -15 1144 755 ; +C 235 ; WX 360 ; N ordmasculine ; B 131 438 451 755 ; +C 241 ; WX 1080 ; N ae ; B 75 -18 1105 574 ; +C 245 ; WX 240 ; N dotlessi ; B 53 0 289 555 ; +C 248 ; WX 320 ; N lslash ; B 74 0 404 740 ; +C 249 ; WX 660 ; N oslash ; B 81 -50 685 608 ; +C 250 ; WX 1080 ; N oe ; B 76 -18 1108 574 ; +C 251 ; WX 600 ; N germandbls ; B 51 -18 629 755 ; +C -1 ; WX 640 ; N ecircumflex ; B 77 -18 667 774 ; +C -1 ; WX 640 ; N edieresis ; B 77 -18 667 769 ; +C -1 ; WX 660 ; N aacute ; B 73 -18 716 849 ; +C -1 ; WX 740 ; N registered ; B 50 -12 827 752 ; +C -1 ; WX 240 ; N icircumflex ; B 39 0 438 774 ; +C -1 ; WX 600 ; N udieresis ; B 87 -18 647 769 ; +C -1 ; WX 640 ; N ograve ; B 71 -18 672 851 ; +C -1 ; WX 600 ; N uacute ; B 87 -18 647 849 ; +C -1 ; WX 600 ; N ucircumflex ; B 87 -18 647 774 ; +C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ; +C -1 ; WX 240 ; N igrave ; B 53 0 347 851 ; +C -1 ; WX 280 ; N Icircumflex ; B 72 0 489 944 ; +C -1 ; WX 640 ; N ccedilla ; B 83 -251 679 574 ; +C -1 ; WX 660 ; N adieresis ; B 73 -18 716 769 ; +C -1 ; WX 520 ; N Ecircumflex ; B 61 0 609 944 ; +C -1 ; WX 440 ; N scaron ; B 49 -18 563 774 ; +C -1 ; WX 660 ; N thorn ; B 13 -185 686 740 ; +C -1 ; WX 1000 ; N trademark ; B 131 296 958 740 ; +C -1 ; WX 640 ; N egrave ; B 77 -18 667 851 ; +C -1 ; WX 336 ; N threesuperior ; B 87 287 413 749 ; +C -1 ; WX 460 ; N zcaron ; B 20 0 598 774 ; +C -1 ; WX 660 ; N atilde ; B 73 -18 716 767 ; +C -1 ; WX 660 ; N aring ; B 73 -18 716 834 ; +C -1 ; WX 640 ; N ocircumflex ; B 71 -18 672 774 ; +C -1 ; WX 520 ; N Edieresis ; B 61 0 606 939 ; +C -1 ; WX 840 ; N threequarters ; B 97 0 836 749 ; +C -1 ; WX 580 ; N ydieresis ; B 75 -185 674 769 ; +C -1 ; WX 580 ; N yacute ; B 75 -185 674 849 ; +C -1 ; WX 240 ; N iacute ; B 53 0 443 849 ; +C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ; +C -1 ; WX 640 ; N Uacute ; B 97 -15 722 1019 ; +C -1 ; WX 640 ; N eacute ; B 77 -18 667 849 ; +C -1 ; WX 840 ; N Ograve ; B 95 -15 882 1021 ; +C -1 ; WX 660 ; N agrave ; B 73 -18 716 851 ; +C -1 ; WX 640 ; N Udieresis ; B 97 -15 722 939 ; +C -1 ; WX 660 ; N acircumflex ; B 73 -18 716 774 ; +C -1 ; WX 280 ; N Igrave ; B 72 0 398 1021 ; +C -1 ; WX 336 ; N twosuperior ; B 73 296 436 749 ; +C -1 ; WX 640 ; N Ugrave ; B 97 -15 722 1021 ; +C -1 ; WX 840 ; N onequarter ; B 187 0 779 740 ; +C -1 ; WX 640 ; N Ucircumflex ; B 97 -15 722 944 ; +C -1 ; WX 520 ; N Scaron ; B 49 -15 635 944 ; +C -1 ; WX 280 ; N Idieresis ; B 72 0 486 939 ; +C -1 ; WX 240 ; N idieresis ; B 53 0 435 769 ; +C -1 ; WX 520 ; N Egrave ; B 61 0 596 1021 ; +C -1 ; WX 840 ; N Oacute ; B 95 -15 882 1019 ; +C -1 ; WX 600 ; N divide ; B 84 -20 610 526 ; +C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ; +C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ; +C -1 ; WX 840 ; N Odieresis ; B 95 -15 882 939 ; +C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ; +C -1 ; WX 740 ; N Ntilde ; B 70 0 808 937 ; +C -1 ; WX 500 ; N Zcaron ; B 19 0 650 944 ; +C -1 ; WX 560 ; N Thorn ; B 72 0 619 740 ; +C -1 ; WX 280 ; N Iacute ; B 72 0 494 1019 ; +C -1 ; WX 600 ; N plusminus ; B 37 -62 626 556 ; +C -1 ; WX 600 ; N multiply ; B 76 12 617 494 ; +C -1 ; WX 520 ; N Eacute ; B 61 0 596 1019 ; +C -1 ; WX 620 ; N Ydieresis ; B 135 0 759 939 ; +C -1 ; WX 336 ; N onesuperior ; B 182 296 360 740 ; +C -1 ; WX 600 ; N ugrave ; B 87 -18 647 851 ; +C -1 ; WX 600 ; N logicalnot ; B 105 108 631 425 ; +C -1 ; WX 600 ; N ntilde ; B 54 0 624 767 ; +C -1 ; WX 840 ; N Otilde ; B 95 -15 882 937 ; +C -1 ; WX 640 ; N otilde ; B 71 -18 672 767 ; +C -1 ; WX 780 ; N Ccedilla ; B 97 -251 864 755 ; +C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ; +C -1 ; WX 840 ; N onehalf ; B 157 0 830 740 ; +C -1 ; WX 742 ; N Eth ; B 83 0 766 740 ; +C -1 ; WX 400 ; N degree ; B 160 426 451 712 ; +C -1 ; WX 620 ; N Yacute ; B 135 0 759 1019 ; +C -1 ; WX 840 ; N Ocircumflex ; B 95 -15 882 944 ; +C -1 ; WX 640 ; N oacute ; B 71 -18 672 849 ; +C -1 ; WX 576 ; N mu ; B 3 -187 642 555 ; +C -1 ; WX 600 ; N minus ; B 84 193 610 313 ; +C -1 ; WX 640 ; N eth ; B 73 -18 699 754 ; +C -1 ; WX 640 ; N odieresis ; B 71 -18 672 769 ; +C -1 ; WX 740 ; N copyright ; B 50 -12 827 752 ; +C -1 ; WX 600 ; N brokenbar ; B 214 -100 503 740 ; +EndCharMetrics +StartKernData +StartKernPairs 218 + +KPX A y -50 +KPX A w -65 +KPX A v -70 +KPX A u -20 +KPX A quoteright -90 +KPX A Y -80 +KPX A W -60 +KPX A V -102 +KPX A U -40 +KPX A T -25 +KPX A Q -50 +KPX A O -50 +KPX A G -40 +KPX A C -40 + +KPX B A -10 + +KPX C A -40 + +KPX D period -20 +KPX D comma -20 +KPX D Y -45 +KPX D W -25 +KPX D V -50 +KPX D A -50 + +KPX F period -129 +KPX F e -20 +KPX F comma -162 +KPX F a -20 +KPX F A -75 + +KPX G period -20 +KPX G comma -20 +KPX G Y -15 + +KPX J period -15 +KPX J a -20 +KPX J A -30 + +KPX K y -20 +KPX K u -15 +KPX K o -45 +KPX K e -40 +KPX K O -30 + +KPX L y -23 +KPX L quoteright -30 +KPX L quotedblright -30 +KPX L Y -80 +KPX L W -55 +KPX L V -85 +KPX L T -46 + +KPX O period -30 +KPX O comma -30 +KPX O Y -30 +KPX O X -30 +KPX O W -20 +KPX O V -45 +KPX O T -15 +KPX O A -60 + +KPX P period -200 +KPX P o -20 +KPX P e -20 +KPX P comma -220 +KPX P a -20 +KPX P A -100 + +KPX Q comma 20 + +KPX R W 25 +KPX R V -10 +KPX R U 25 +KPX R T 40 +KPX R O 25 + +KPX S comma 20 + +KPX T y -10 +KPX T w -55 +KPX T u -46 +KPX T semicolon -29 +KPX T r -30 +KPX T period -91 +KPX T o -49 +KPX T hyphen -75 +KPX T e -49 +KPX T comma -82 +KPX T colon -15 +KPX T a -70 +KPX T O -15 +KPX T A -25 + +KPX U period -20 +KPX U comma -20 +KPX U A -40 + +KPX V u -55 +KPX V semicolon -33 +KPX V period -145 +KPX V o -101 +KPX V i -15 +KPX V hyphen -75 +KPX V e -101 +KPX V comma -145 +KPX V colon -18 +KPX V a -95 +KPX V O -45 +KPX V G -20 +KPX V A -102 + +KPX W y -15 +KPX W u -30 +KPX W semicolon -33 +KPX W period -106 +KPX W o -46 +KPX W i -10 +KPX W hyphen -35 +KPX W e -47 +KPX W comma -106 +KPX W colon -15 +KPX W a -50 +KPX W O -20 +KPX W A -58 + +KPX Y u -52 +KPX Y semicolon -23 +KPX Y period -145 +KPX Y o -89 +KPX Y hyphen -100 +KPX Y e -89 +KPX Y comma -145 +KPX Y colon -10 +KPX Y a -93 +KPX Y O -30 +KPX Y A -80 + +KPX a t 5 +KPX a p 20 +KPX a b 5 + +KPX b y -20 +KPX b v -20 + +KPX c y -20 +KPX c l -15 +KPX c k -15 + +KPX comma space -50 +KPX comma quoteright -70 +KPX comma quotedblright -70 + +KPX e y -20 +KPX e x -20 +KPX e w -20 +KPX e v -20 + +KPX f period -40 +KPX f o -20 +KPX f l -15 +KPX f i -15 +KPX f f -20 +KPX f dotlessi -15 +KPX f comma -40 +KPX f a -15 + +KPX g i 25 +KPX g a 15 + +KPX h y -30 + +KPX k y -5 +KPX k o -30 +KPX k e -40 + +KPX m y -20 +KPX m u -20 + +KPX n y -15 +KPX n v -30 + +KPX o y -20 +KPX o x -30 +KPX o w -20 +KPX o v -30 + +KPX p y -20 + +KPX period space -50 +KPX period quoteright -70 +KPX period quotedblright -70 + +KPX quotedblleft A -50 + +KPX quotedblright space -50 + +KPX quoteleft quoteleft -80 +KPX quoteleft A -50 + +KPX quoteright v -10 +KPX quoteright t 10 +KPX quoteright space -50 +KPX quoteright s -15 +KPX quoteright r -20 +KPX quoteright quoteright -80 +KPX quoteright d -50 + +KPX r y 40 +KPX r v 40 +KPX r u 20 +KPX r t 20 +KPX r s 20 +KPX r q -8 +KPX r period -73 +KPX r p 20 +KPX r o -15 +KPX r n 21 +KPX r m 15 +KPX r l 20 +KPX r k 5 +KPX r i 20 +KPX r hyphen -60 +KPX r g 1 +KPX r e -4 +KPX r d -6 +KPX r comma -75 +KPX r c -7 + +KPX s period 20 +KPX s comma 20 + +KPX space quoteleft -50 +KPX space quotedblleft -50 +KPX space Y -60 +KPX space W -25 +KPX space V -80 +KPX space T -25 +KPX space A -20 + +KPX v period -90 +KPX v o -20 +KPX v e -20 +KPX v comma -90 +KPX v a -30 + +KPX w period -90 +KPX w o -30 +KPX w e -20 +KPX w comma -90 +KPX w a -30 + +KPX x e -20 + +KPX y period -100 +KPX y o -30 +KPX y e -20 +KPX y comma -100 +KPX y c -35 +KPX y a -30 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 170 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 132 170 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 170 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 170 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 215 135 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 162 170 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 82 170 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 22 170 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 42 170 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 82 170 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -13 170 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -98 170 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -78 170 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -63 170 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 162 170 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 242 170 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 182 170 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 202 170 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 242 170 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 212 170 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 22 170 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 177 170 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 82 170 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 102 170 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 107 170 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 170 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 92 170 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 37 170 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagk8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagk8a.afm new file mode 100644 index 00000000..53b03bbb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagk8a.afm @@ -0,0 +1,573 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Mar 4 13:37:31 1991 +Comment UniqueID 34364 +Comment VMusage 24225 31117 +FontName AvantGarde-Book +FullName ITC Avant Garde Gothic Book +FamilyName ITC Avant Garde Gothic +Weight Book +ItalicAngle 0 +IsFixedPitch false +FontBBox -113 -222 1148 955 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 740 +XHeight 547 +Ascender 740 +Descender -192 +StartCharMetrics 228 +C 32 ; WX 277 ; N space ; B 0 0 0 0 ; +C 33 ; WX 295 ; N exclam ; B 111 0 185 740 ; +C 34 ; WX 309 ; N quotedbl ; B 36 444 273 740 ; +C 35 ; WX 554 ; N numbersign ; B 33 0 521 740 ; +C 36 ; WX 554 ; N dollar ; B 70 -70 485 811 ; +C 37 ; WX 775 ; N percent ; B 21 -13 753 751 ; +C 38 ; WX 757 ; N ampersand ; B 56 -12 736 753 ; +C 39 ; WX 351 ; N quoteright ; B 94 546 256 740 ; +C 40 ; WX 369 ; N parenleft ; B 47 -205 355 757 ; +C 41 ; WX 369 ; N parenright ; B 14 -205 322 757 ; +C 42 ; WX 425 ; N asterisk ; B 58 446 367 740 ; +C 43 ; WX 606 ; N plus ; B 51 0 555 506 ; +C 44 ; WX 277 ; N comma ; B 14 -67 176 126 ; +C 45 ; WX 332 ; N hyphen ; B 30 248 302 315 ; +C 46 ; WX 277 ; N period ; B 102 0 176 126 ; +C 47 ; WX 437 ; N slash ; B 44 -100 403 740 ; +C 48 ; WX 554 ; N zero ; B 29 -13 525 753 ; +C 49 ; WX 554 ; N one ; B 135 0 336 740 ; +C 50 ; WX 554 ; N two ; B 40 0 514 753 ; +C 51 ; WX 554 ; N three ; B 34 -13 506 753 ; +C 52 ; WX 554 ; N four ; B 14 0 528 740 ; +C 53 ; WX 554 ; N five ; B 26 -13 530 740 ; +C 54 ; WX 554 ; N six ; B 24 -13 530 739 ; +C 55 ; WX 554 ; N seven ; B 63 0 491 740 ; +C 56 ; WX 554 ; N eight ; B 41 -13 513 753 ; +C 57 ; WX 554 ; N nine ; B 24 0 530 752 ; +C 58 ; WX 277 ; N colon ; B 102 0 176 548 ; +C 59 ; WX 277 ; N semicolon ; B 14 -67 176 548 ; +C 60 ; WX 606 ; N less ; B 46 -8 554 514 ; +C 61 ; WX 606 ; N equal ; B 51 118 555 388 ; +C 62 ; WX 606 ; N greater ; B 52 -8 560 514 ; +C 63 ; WX 591 ; N question ; B 64 0 526 752 ; +C 64 ; WX 867 ; N at ; B 65 -13 803 753 ; +C 65 ; WX 740 ; N A ; B 12 0 729 740 ; +C 66 ; WX 574 ; N B ; B 74 0 544 740 ; +C 67 ; WX 813 ; N C ; B 43 -13 771 752 ; +C 68 ; WX 744 ; N D ; B 74 0 699 740 ; +C 69 ; WX 536 ; N E ; B 70 0 475 740 ; +C 70 ; WX 485 ; N F ; B 70 0 444 740 ; +C 71 ; WX 872 ; N G ; B 40 -13 828 753 ; +C 72 ; WX 683 ; N H ; B 76 0 607 740 ; +C 73 ; WX 226 ; N I ; B 76 0 150 740 ; +C 74 ; WX 482 ; N J ; B 6 -13 402 740 ; +C 75 ; WX 591 ; N K ; B 81 0 591 740 ; +C 76 ; WX 462 ; N L ; B 82 0 462 740 ; +C 77 ; WX 919 ; N M ; B 76 0 843 740 ; +C 78 ; WX 740 ; N N ; B 75 0 664 740 ; +C 79 ; WX 869 ; N O ; B 43 -13 826 753 ; +C 80 ; WX 592 ; N P ; B 75 0 564 740 ; +C 81 ; WX 871 ; N Q ; B 40 -13 837 753 ; +C 82 ; WX 607 ; N R ; B 70 0 572 740 ; +C 83 ; WX 498 ; N S ; B 22 -13 473 753 ; +C 84 ; WX 426 ; N T ; B 6 0 419 740 ; +C 85 ; WX 655 ; N U ; B 75 -13 579 740 ; +C 86 ; WX 702 ; N V ; B 8 0 693 740 ; +C 87 ; WX 960 ; N W ; B 11 0 950 740 ; +C 88 ; WX 609 ; N X ; B 8 0 602 740 ; +C 89 ; WX 592 ; N Y ; B 1 0 592 740 ; +C 90 ; WX 480 ; N Z ; B 12 0 470 740 ; +C 91 ; WX 351 ; N bracketleft ; B 133 -179 337 753 ; +C 92 ; WX 605 ; N backslash ; B 118 -100 477 740 ; +C 93 ; WX 351 ; N bracketright ; B 14 -179 218 753 ; +C 94 ; WX 606 ; N asciicircum ; B 53 307 553 740 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 351 ; N quoteleft ; B 95 546 257 740 ; +C 97 ; WX 683 ; N a ; B 42 -13 621 561 ; +C 98 ; WX 682 ; N b ; B 68 -13 647 740 ; +C 99 ; WX 647 ; N c ; B 41 -13 607 561 ; +C 100 ; WX 685 ; N d ; B 39 -13 618 740 ; +C 101 ; WX 650 ; N e ; B 38 -13 608 561 ; +C 102 ; WX 314 ; N f ; B 19 0 314 753 ; L i fi ; L l fl ; +C 103 ; WX 673 ; N g ; B 37 -215 606 561 ; +C 104 ; WX 610 ; N h ; B 62 0 543 740 ; +C 105 ; WX 200 ; N i ; B 65 0 135 740 ; +C 106 ; WX 203 ; N j ; B -44 -192 137 740 ; +C 107 ; WX 502 ; N k ; B 70 0 498 740 ; +C 108 ; WX 200 ; N l ; B 65 0 135 740 ; +C 109 ; WX 938 ; N m ; B 66 0 872 561 ; +C 110 ; WX 610 ; N n ; B 65 0 546 561 ; +C 111 ; WX 655 ; N o ; B 42 -13 614 561 ; +C 112 ; WX 682 ; N p ; B 64 -192 643 561 ; +C 113 ; WX 682 ; N q ; B 37 -192 616 561 ; +C 114 ; WX 301 ; N r ; B 65 0 291 561 ; +C 115 ; WX 388 ; N s ; B 24 -13 364 561 ; +C 116 ; WX 339 ; N t ; B 14 0 330 740 ; +C 117 ; WX 608 ; N u ; B 62 -13 541 547 ; +C 118 ; WX 554 ; N v ; B 7 0 546 547 ; +C 119 ; WX 831 ; N w ; B 13 0 820 547 ; +C 120 ; WX 480 ; N x ; B 12 0 468 547 ; +C 121 ; WX 536 ; N y ; B 15 -192 523 547 ; +C 122 ; WX 425 ; N z ; B 10 0 415 547 ; +C 123 ; WX 351 ; N braceleft ; B 70 -189 331 740 ; +C 124 ; WX 672 ; N bar ; B 299 -100 373 740 ; +C 125 ; WX 351 ; N braceright ; B 20 -189 281 740 ; +C 126 ; WX 606 ; N asciitilde ; B 72 179 534 319 ; +C 161 ; WX 295 ; N exclamdown ; B 110 -192 184 548 ; +C 162 ; WX 554 ; N cent ; B 48 62 510 707 ; +C 163 ; WX 554 ; N sterling ; B 4 0 552 753 ; +C 164 ; WX 166 ; N fraction ; B -113 0 280 740 ; +C 165 ; WX 554 ; N yen ; B 4 0 550 740 ; +C 166 ; WX 554 ; N florin ; B -12 -153 518 818 ; +C 167 ; WX 615 ; N section ; B 85 -141 529 753 ; +C 168 ; WX 554 ; N currency ; B 8 42 546 580 ; +C 169 ; WX 198 ; N quotesingle ; B 59 444 140 740 ; +C 170 ; WX 502 ; N quotedblleft ; B 97 546 406 740 ; +C 171 ; WX 425 ; N guillemotleft ; B 40 81 386 481 ; +C 172 ; WX 251 ; N guilsinglleft ; B 40 81 212 481 ; +C 173 ; WX 251 ; N guilsinglright ; B 39 81 211 481 ; +C 174 ; WX 487 ; N fi ; B 19 0 422 753 ; +C 175 ; WX 485 ; N fl ; B 19 0 420 753 ; +C 177 ; WX 500 ; N endash ; B 35 248 465 315 ; +C 178 ; WX 553 ; N dagger ; B 59 -133 493 740 ; +C 179 ; WX 553 ; N daggerdbl ; B 59 -133 493 740 ; +C 180 ; WX 277 ; N periodcentered ; B 102 190 176 316 ; +C 182 ; WX 564 ; N paragraph ; B 22 -110 551 740 ; +C 183 ; WX 606 ; N bullet ; B 150 222 455 532 ; +C 184 ; WX 354 ; N quotesinglbase ; B 89 -68 251 126 ; +C 185 ; WX 502 ; N quotedblbase ; B 89 -68 399 126 ; +C 186 ; WX 484 ; N quotedblright ; B 96 546 405 740 ; +C 187 ; WX 425 ; N guillemotright ; B 39 81 385 481 ; +C 188 ; WX 1000 ; N ellipsis ; B 130 0 870 126 ; +C 189 ; WX 1174 ; N perthousand ; B 25 -13 1148 751 ; +C 191 ; WX 591 ; N questiondown ; B 65 -205 527 548 ; +C 193 ; WX 378 ; N grave ; B 69 619 300 786 ; +C 194 ; WX 375 ; N acute ; B 78 619 309 786 ; +C 195 ; WX 502 ; N circumflex ; B 74 639 428 764 ; +C 196 ; WX 439 ; N tilde ; B 47 651 392 754 ; +C 197 ; WX 485 ; N macron ; B 73 669 411 736 ; +C 198 ; WX 453 ; N breve ; B 52 651 401 754 ; +C 199 ; WX 222 ; N dotaccent ; B 74 639 148 765 ; +C 200 ; WX 369 ; N dieresis ; B 73 639 295 765 ; +C 202 ; WX 332 ; N ring ; B 62 600 269 807 ; +C 203 ; WX 324 ; N cedilla ; B 80 -222 254 0 ; +C 205 ; WX 552 ; N hungarumlaut ; B 119 605 453 800 ; +C 206 ; WX 302 ; N ogonek ; B 73 -191 228 0 ; +C 207 ; WX 502 ; N caron ; B 68 639 423 764 ; +C 208 ; WX 1000 ; N emdash ; B 35 248 965 315 ; +C 225 ; WX 992 ; N AE ; B -20 0 907 740 ; +C 227 ; WX 369 ; N ordfeminine ; B -3 407 356 753 ; +C 232 ; WX 517 ; N Lslash ; B 59 0 517 740 ; +C 233 ; WX 868 ; N Oslash ; B 43 -83 826 819 ; +C 234 ; WX 1194 ; N OE ; B 45 -13 1142 753 ; +C 235 ; WX 369 ; N ordmasculine ; B 12 407 356 753 ; +C 241 ; WX 1157 ; N ae ; B 34 -13 1113 561 ; +C 245 ; WX 200 ; N dotlessi ; B 65 0 135 547 ; +C 248 ; WX 300 ; N lslash ; B 43 0 259 740 ; +C 249 ; WX 653 ; N oslash ; B 41 -64 613 614 ; +C 250 ; WX 1137 ; N oe ; B 34 -13 1104 561 ; +C 251 ; WX 554 ; N germandbls ; B 61 -13 525 753 ; +C -1 ; WX 650 ; N ecircumflex ; B 38 -13 608 764 ; +C -1 ; WX 650 ; N edieresis ; B 38 -13 608 765 ; +C -1 ; WX 683 ; N aacute ; B 42 -13 621 786 ; +C -1 ; WX 747 ; N registered ; B -9 -12 755 752 ; +C -1 ; WX 200 ; N icircumflex ; B -77 0 277 764 ; +C -1 ; WX 608 ; N udieresis ; B 62 -13 541 765 ; +C -1 ; WX 655 ; N ograve ; B 42 -13 614 786 ; +C -1 ; WX 608 ; N uacute ; B 62 -13 541 786 ; +C -1 ; WX 608 ; N ucircumflex ; B 62 -13 541 764 ; +C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ; +C -1 ; WX 200 ; N igrave ; B -60 0 171 786 ; +C -1 ; WX 226 ; N Icircumflex ; B -64 0 290 927 ; +C -1 ; WX 647 ; N ccedilla ; B 41 -222 607 561 ; +C -1 ; WX 683 ; N adieresis ; B 42 -13 621 765 ; +C -1 ; WX 536 ; N Ecircumflex ; B 70 0 475 927 ; +C -1 ; WX 388 ; N scaron ; B 11 -13 366 764 ; +C -1 ; WX 682 ; N thorn ; B 64 -192 643 740 ; +C -1 ; WX 1000 ; N trademark ; B 9 296 816 740 ; +C -1 ; WX 650 ; N egrave ; B 38 -13 608 786 ; +C -1 ; WX 332 ; N threesuperior ; B 18 289 318 747 ; +C -1 ; WX 425 ; N zcaron ; B 10 0 415 764 ; +C -1 ; WX 683 ; N atilde ; B 42 -13 621 754 ; +C -1 ; WX 683 ; N aring ; B 42 -13 621 807 ; +C -1 ; WX 655 ; N ocircumflex ; B 42 -13 614 764 ; +C -1 ; WX 536 ; N Edieresis ; B 70 0 475 928 ; +C -1 ; WX 831 ; N threequarters ; B 46 0 784 747 ; +C -1 ; WX 536 ; N ydieresis ; B 15 -192 523 765 ; +C -1 ; WX 536 ; N yacute ; B 15 -192 523 786 ; +C -1 ; WX 200 ; N iacute ; B 31 0 262 786 ; +C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ; +C -1 ; WX 655 ; N Uacute ; B 75 -13 579 949 ; +C -1 ; WX 650 ; N eacute ; B 38 -13 608 786 ; +C -1 ; WX 869 ; N Ograve ; B 43 -13 826 949 ; +C -1 ; WX 683 ; N agrave ; B 42 -13 621 786 ; +C -1 ; WX 655 ; N Udieresis ; B 75 -13 579 928 ; +C -1 ; WX 683 ; N acircumflex ; B 42 -13 621 764 ; +C -1 ; WX 226 ; N Igrave ; B -47 0 184 949 ; +C -1 ; WX 332 ; N twosuperior ; B 19 296 318 747 ; +C -1 ; WX 655 ; N Ugrave ; B 75 -13 579 949 ; +C -1 ; WX 831 ; N onequarter ; B 100 0 729 740 ; +C -1 ; WX 655 ; N Ucircumflex ; B 75 -13 579 927 ; +C -1 ; WX 498 ; N Scaron ; B 22 -13 473 927 ; +C -1 ; WX 226 ; N Idieresis ; B 2 0 224 928 ; +C -1 ; WX 200 ; N idieresis ; B -11 0 211 765 ; +C -1 ; WX 536 ; N Egrave ; B 70 0 475 949 ; +C -1 ; WX 869 ; N Oacute ; B 43 -13 826 949 ; +C -1 ; WX 606 ; N divide ; B 51 -13 555 519 ; +C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ; +C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ; +C -1 ; WX 869 ; N Odieresis ; B 43 -13 826 928 ; +C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ; +C -1 ; WX 740 ; N Ntilde ; B 75 0 664 917 ; +C -1 ; WX 480 ; N Zcaron ; B 12 0 470 927 ; +C -1 ; WX 592 ; N Thorn ; B 60 0 549 740 ; +C -1 ; WX 226 ; N Iacute ; B 44 0 275 949 ; +C -1 ; WX 606 ; N plusminus ; B 51 -24 555 518 ; +C -1 ; WX 606 ; N multiply ; B 74 24 533 482 ; +C -1 ; WX 536 ; N Eacute ; B 70 0 475 949 ; +C -1 ; WX 592 ; N Ydieresis ; B 1 0 592 928 ; +C -1 ; WX 332 ; N onesuperior ; B 63 296 198 740 ; +C -1 ; WX 608 ; N ugrave ; B 62 -13 541 786 ; +C -1 ; WX 606 ; N logicalnot ; B 51 109 555 388 ; +C -1 ; WX 610 ; N ntilde ; B 65 0 546 754 ; +C -1 ; WX 869 ; N Otilde ; B 43 -13 826 917 ; +C -1 ; WX 655 ; N otilde ; B 42 -13 614 754 ; +C -1 ; WX 813 ; N Ccedilla ; B 43 -222 771 752 ; +C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ; +C -1 ; WX 831 ; N onehalf ; B 81 0 750 740 ; +C -1 ; WX 790 ; N Eth ; B 40 0 739 740 ; +C -1 ; WX 400 ; N degree ; B 56 421 344 709 ; +C -1 ; WX 592 ; N Yacute ; B 1 0 592 949 ; +C -1 ; WX 869 ; N Ocircumflex ; B 43 -13 826 927 ; +C -1 ; WX 655 ; N oacute ; B 42 -13 614 786 ; +C -1 ; WX 608 ; N mu ; B 80 -184 527 547 ; +C -1 ; WX 606 ; N minus ; B 51 219 555 287 ; +C -1 ; WX 655 ; N eth ; B 42 -12 614 753 ; +C -1 ; WX 655 ; N odieresis ; B 42 -13 614 765 ; +C -1 ; WX 747 ; N copyright ; B -9 -12 755 752 ; +C -1 ; WX 672 ; N brokenbar ; B 299 -100 373 740 ; +EndCharMetrics +StartKernData +StartKernPairs 216 + +KPX A y -62 +KPX A w -65 +KPX A v -70 +KPX A u -20 +KPX A quoteright -100 +KPX A quotedblright -100 +KPX A Y -92 +KPX A W -60 +KPX A V -102 +KPX A U -40 +KPX A T -45 +KPX A Q -40 +KPX A O -50 +KPX A G -40 +KPX A C -40 + +KPX B A -10 + +KPX C A -40 + +KPX D period -20 +KPX D comma -20 +KPX D Y -30 +KPX D W -10 +KPX D V -50 +KPX D A -50 + +KPX F period -160 +KPX F e -20 +KPX F comma -180 +KPX F a -20 +KPX F A -75 + +KPX G period -20 +KPX G comma -20 +KPX G Y -20 + +KPX J period -15 +KPX J a -20 +KPX J A -30 + +KPX K o -15 +KPX K e -20 +KPX K O -20 + +KPX L y -23 +KPX L quoteright -130 +KPX L quotedblright -130 +KPX L Y -91 +KPX L W -67 +KPX L V -113 +KPX L T -46 + +KPX O period -30 +KPX O comma -30 +KPX O Y -30 +KPX O X -30 +KPX O W -20 +KPX O V -60 +KPX O T -30 +KPX O A -60 + +KPX P period -300 +KPX P o -60 +KPX P e -20 +KPX P comma -280 +KPX P a -20 +KPX P A -114 + +KPX Q comma 20 + +KPX R Y -10 +KPX R W 10 +KPX R V -10 +KPX R T 6 + +KPX S comma 20 + +KPX T y -50 +KPX T w -55 +KPX T u -46 +KPX T semicolon -29 +KPX T r -30 +KPX T period -91 +KPX T o -70 +KPX T i 10 +KPX T hyphen -75 +KPX T e -49 +KPX T comma -82 +KPX T colon -15 +KPX T a -90 +KPX T O -30 +KPX T A -45 + +KPX U period -20 +KPX U comma -20 +KPX U A -40 + +KPX V u -40 +KPX V semicolon -33 +KPX V period -165 +KPX V o -101 +KPX V i -5 +KPX V hyphen -75 +KPX V e -101 +KPX V comma -145 +KPX V colon -18 +KPX V a -104 +KPX V O -60 +KPX V G -20 +KPX V A -102 + +KPX W y -2 +KPX W u -30 +KPX W semicolon -33 +KPX W period -106 +KPX W o -46 +KPX W i 6 +KPX W hyphen -35 +KPX W e -47 +KPX W comma -106 +KPX W colon -15 +KPX W a -50 +KPX W O -20 +KPX W A -58 + +KPX Y u -52 +KPX Y semicolon -23 +KPX Y period -175 +KPX Y o -89 +KPX Y hyphen -85 +KPX Y e -89 +KPX Y comma -145 +KPX Y colon -10 +KPX Y a -93 +KPX Y O -30 +KPX Y A -92 + +KPX a p 20 +KPX a b 20 + +KPX b y -20 +KPX b v -20 + +KPX c y -20 +KPX c k -15 + +KPX comma space -110 +KPX comma quoteright -120 +KPX comma quotedblright -120 + +KPX e y -20 +KPX e w -20 +KPX e v -20 + +KPX f period -50 +KPX f o -40 +KPX f l -30 +KPX f i -34 +KPX f f -60 +KPX f e -20 +KPX f dotlessi -34 +KPX f comma -50 +KPX f a -40 + +KPX g a -15 + +KPX h y -30 + +KPX k y -5 +KPX k e -15 + +KPX m y -20 +KPX m u -20 +KPX m a -20 + +KPX n y -15 +KPX n v -20 + +KPX o y -20 +KPX o x -15 +KPX o w -20 +KPX o v -30 + +KPX p y -20 + +KPX period space -110 +KPX period quoteright -120 +KPX period quotedblright -120 + +KPX quotedblleft quoteleft -35 +KPX quotedblleft A -100 + +KPX quotedblright space -110 + +KPX quoteleft quoteleft -203 +KPX quoteleft A -100 + +KPX quoteright v -30 +KPX quoteright t 10 +KPX quoteright space -110 +KPX quoteright s -15 +KPX quoteright r -20 +KPX quoteright quoteright -203 +KPX quoteright quotedblright -35 +KPX quoteright d -110 + +KPX r y 40 +KPX r v 40 +KPX r u 20 +KPX r t 20 +KPX r s 20 +KPX r q -8 +KPX r period -73 +KPX r p 20 +KPX r o -20 +KPX r n 21 +KPX r m 28 +KPX r l 20 +KPX r k 20 +KPX r i 20 +KPX r hyphen -60 +KPX r g -15 +KPX r e -4 +KPX r d -6 +KPX r comma -75 +KPX r c -20 +KPX r a -20 + +KPX s period 20 +KPX s comma 20 + +KPX space quoteleft -110 +KPX space quotedblleft -110 +KPX space Y -60 +KPX space W -25 +KPX space V -50 +KPX space T -25 +KPX space A -20 + +KPX v period -130 +KPX v o -30 +KPX v e -20 +KPX v comma -100 +KPX v a -30 + +KPX w period -100 +KPX w o -30 +KPX w h 15 +KPX w e -20 +KPX w comma -90 +KPX w a -30 + +KPX y period -125 +KPX y o -30 +KPX y e -20 +KPX y comma -110 +KPX y a -30 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 183 163 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 119 163 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 186 163 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 181 163 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 204 148 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 151 163 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 81 163 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 17 163 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 163 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 79 163 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -34 163 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -138 163 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -71 163 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -116 163 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 151 163 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 247 163 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 184 163 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 163 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 246 163 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 163 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron -2 163 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 163 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 77 163 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 143 163 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 119 163 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 129 163 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 163 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron -11 163 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagko8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagko8a.afm new file mode 100644 index 00000000..e0e75f38 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pagko8a.afm @@ -0,0 +1,573 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Mar 4 13:41:11 1991 +Comment UniqueID 34367 +Comment VMusage 6555 39267 +FontName AvantGarde-BookOblique +FullName ITC Avant Garde Gothic Book Oblique +FamilyName ITC Avant Garde Gothic +Weight Book +ItalicAngle -10.5 +IsFixedPitch false +FontBBox -113 -222 1279 955 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 740 +XHeight 547 +Ascender 740 +Descender -192 +StartCharMetrics 228 +C 32 ; WX 277 ; N space ; B 0 0 0 0 ; +C 33 ; WX 295 ; N exclam ; B 111 0 322 740 ; +C 34 ; WX 309 ; N quotedbl ; B 130 444 410 740 ; +C 35 ; WX 554 ; N numbersign ; B 71 0 620 740 ; +C 36 ; WX 554 ; N dollar ; B 107 -70 581 811 ; +C 37 ; WX 775 ; N percent ; B 124 -13 787 751 ; +C 38 ; WX 757 ; N ampersand ; B 92 -12 775 753 ; +C 39 ; WX 351 ; N quoteright ; B 195 546 393 740 ; +C 40 ; WX 369 ; N parenleft ; B 89 -205 495 757 ; +C 41 ; WX 369 ; N parenright ; B -24 -205 382 757 ; +C 42 ; WX 425 ; N asterisk ; B 170 446 479 740 ; +C 43 ; WX 606 ; N plus ; B 92 0 608 506 ; +C 44 ; WX 277 ; N comma ; B 2 -67 199 126 ; +C 45 ; WX 332 ; N hyphen ; B 76 248 360 315 ; +C 46 ; WX 277 ; N period ; B 102 0 199 126 ; +C 47 ; WX 437 ; N slash ; B 25 -100 540 740 ; +C 48 ; WX 554 ; N zero ; B 71 -13 622 753 ; +C 49 ; WX 554 ; N one ; B 260 0 473 740 ; +C 50 ; WX 554 ; N two ; B 40 0 615 753 ; +C 51 ; WX 554 ; N three ; B 73 -13 565 753 ; +C 52 ; WX 554 ; N four ; B 39 0 598 740 ; +C 53 ; WX 554 ; N five ; B 69 -13 605 740 ; +C 54 ; WX 554 ; N six ; B 65 -13 580 739 ; +C 55 ; WX 554 ; N seven ; B 110 0 628 740 ; +C 56 ; WX 554 ; N eight ; B 77 -13 580 753 ; +C 57 ; WX 554 ; N nine ; B 111 0 626 752 ; +C 58 ; WX 277 ; N colon ; B 102 0 278 548 ; +C 59 ; WX 277 ; N semicolon ; B 2 -67 278 548 ; +C 60 ; WX 606 ; N less ; B 87 -8 649 514 ; +C 61 ; WX 606 ; N equal ; B 73 118 627 388 ; +C 62 ; WX 606 ; N greater ; B 51 -8 613 514 ; +C 63 ; WX 591 ; N question ; B 158 0 628 752 ; +C 64 ; WX 867 ; N at ; B 126 -13 888 753 ; +C 65 ; WX 740 ; N A ; B 12 0 729 740 ; +C 66 ; WX 574 ; N B ; B 74 0 606 740 ; +C 67 ; WX 813 ; N C ; B 105 -13 870 752 ; +C 68 ; WX 744 ; N D ; B 74 0 773 740 ; +C 69 ; WX 536 ; N E ; B 70 0 612 740 ; +C 70 ; WX 485 ; N F ; B 70 0 581 740 ; +C 71 ; WX 872 ; N G ; B 103 -13 891 753 ; +C 72 ; WX 683 ; N H ; B 76 0 744 740 ; +C 73 ; WX 226 ; N I ; B 76 0 287 740 ; +C 74 ; WX 482 ; N J ; B 37 -13 539 740 ; +C 75 ; WX 591 ; N K ; B 81 0 728 740 ; +C 76 ; WX 462 ; N L ; B 82 0 474 740 ; +C 77 ; WX 919 ; N M ; B 76 0 980 740 ; +C 78 ; WX 740 ; N N ; B 75 0 801 740 ; +C 79 ; WX 869 ; N O ; B 105 -13 901 753 ; +C 80 ; WX 592 ; N P ; B 75 0 664 740 ; +C 81 ; WX 871 ; N Q ; B 102 -13 912 753 ; +C 82 ; WX 607 ; N R ; B 70 0 669 740 ; +C 83 ; WX 498 ; N S ; B 57 -13 561 753 ; +C 84 ; WX 426 ; N T ; B 131 0 556 740 ; +C 85 ; WX 655 ; N U ; B 118 -13 716 740 ; +C 86 ; WX 702 ; N V ; B 145 0 830 740 ; +C 87 ; WX 960 ; N W ; B 148 0 1087 740 ; +C 88 ; WX 609 ; N X ; B 8 0 724 740 ; +C 89 ; WX 592 ; N Y ; B 138 0 729 740 ; +C 90 ; WX 480 ; N Z ; B 12 0 596 740 ; +C 91 ; WX 351 ; N bracketleft ; B 145 -179 477 753 ; +C 92 ; WX 605 ; N backslash ; B 255 -100 458 740 ; +C 93 ; WX 351 ; N bracketright ; B -19 -179 312 753 ; +C 94 ; WX 606 ; N asciicircum ; B 110 307 610 740 ; +C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ; +C 96 ; WX 351 ; N quoteleft ; B 232 546 358 740 ; +C 97 ; WX 683 ; N a ; B 88 -13 722 561 ; +C 98 ; WX 682 ; N b ; B 68 -13 703 740 ; +C 99 ; WX 647 ; N c ; B 87 -13 678 561 ; +C 100 ; WX 685 ; N d ; B 85 -13 755 740 ; +C 101 ; WX 650 ; N e ; B 84 -13 664 561 ; +C 102 ; WX 314 ; N f ; B 104 0 454 753 ; L i fi ; L l fl ; +C 103 ; WX 673 ; N g ; B 56 -215 707 561 ; +C 104 ; WX 610 ; N h ; B 62 0 606 740 ; +C 105 ; WX 200 ; N i ; B 65 0 272 740 ; +C 106 ; WX 203 ; N j ; B -80 -192 274 740 ; +C 107 ; WX 502 ; N k ; B 70 0 588 740 ; +C 108 ; WX 200 ; N l ; B 65 0 272 740 ; +C 109 ; WX 938 ; N m ; B 66 0 938 561 ; +C 110 ; WX 610 ; N n ; B 65 0 609 561 ; +C 111 ; WX 655 ; N o ; B 88 -13 669 561 ; +C 112 ; WX 682 ; N p ; B 28 -192 699 561 ; +C 113 ; WX 682 ; N q ; B 83 -192 717 561 ; +C 114 ; WX 301 ; N r ; B 65 0 395 561 ; +C 115 ; WX 388 ; N s ; B 49 -13 424 561 ; +C 116 ; WX 339 ; N t ; B 104 0 431 740 ; +C 117 ; WX 608 ; N u ; B 100 -13 642 547 ; +C 118 ; WX 554 ; N v ; B 108 0 647 547 ; +C 119 ; WX 831 ; N w ; B 114 0 921 547 ; +C 120 ; WX 480 ; N x ; B 12 0 569 547 ; +C 121 ; WX 536 ; N y ; B 97 -192 624 547 ; +C 122 ; WX 425 ; N z ; B 10 0 498 547 ; +C 123 ; WX 351 ; N braceleft ; B 115 -189 468 740 ; +C 124 ; WX 672 ; N bar ; B 280 -100 510 740 ; +C 125 ; WX 351 ; N braceright ; B -15 -189 338 740 ; +C 126 ; WX 606 ; N asciitilde ; B 114 179 584 319 ; +C 161 ; WX 295 ; N exclamdown ; B 74 -192 286 548 ; +C 162 ; WX 554 ; N cent ; B 115 62 596 707 ; +C 163 ; WX 554 ; N sterling ; B 29 0 614 753 ; +C 164 ; WX 166 ; N fraction ; B -113 0 417 740 ; +C 165 ; WX 554 ; N yen ; B 75 0 687 740 ; +C 166 ; WX 554 ; N florin ; B -39 -153 669 818 ; +C 167 ; WX 615 ; N section ; B 118 -141 597 753 ; +C 168 ; WX 554 ; N currency ; B 24 42 645 580 ; +C 169 ; WX 198 ; N quotesingle ; B 153 444 277 740 ; +C 170 ; WX 502 ; N quotedblleft ; B 234 546 507 740 ; +C 171 ; WX 425 ; N guillemotleft ; B 92 81 469 481 ; +C 172 ; WX 251 ; N guilsinglleft ; B 92 81 295 481 ; +C 173 ; WX 251 ; N guilsinglright ; B 60 81 263 481 ; +C 174 ; WX 487 ; N fi ; B 104 0 559 753 ; +C 175 ; WX 485 ; N fl ; B 104 0 557 753 ; +C 177 ; WX 500 ; N endash ; B 81 248 523 315 ; +C 178 ; WX 553 ; N dagger ; B 146 -133 593 740 ; +C 179 ; WX 553 ; N daggerdbl ; B 72 -133 593 740 ; +C 180 ; WX 277 ; N periodcentered ; B 137 190 235 316 ; +C 182 ; WX 564 ; N paragraph ; B 119 -110 688 740 ; +C 183 ; WX 606 ; N bullet ; B 217 222 528 532 ; +C 184 ; WX 354 ; N quotesinglbase ; B 76 -68 274 126 ; +C 185 ; WX 502 ; N quotedblbase ; B 76 -68 422 126 ; +C 186 ; WX 484 ; N quotedblright ; B 197 546 542 740 ; +C 187 ; WX 425 ; N guillemotright ; B 60 81 437 481 ; +C 188 ; WX 1000 ; N ellipsis ; B 130 0 893 126 ; +C 189 ; WX 1174 ; N perthousand ; B 128 -13 1182 751 ; +C 191 ; WX 591 ; N questiondown ; B 64 -205 534 548 ; +C 193 ; WX 378 ; N grave ; B 204 619 425 786 ; +C 194 ; WX 375 ; N acute ; B 203 619 444 786 ; +C 195 ; WX 502 ; N circumflex ; B 192 639 546 764 ; +C 196 ; WX 439 ; N tilde ; B 179 651 520 754 ; +C 197 ; WX 485 ; N macron ; B 197 669 547 736 ; +C 198 ; WX 453 ; N breve ; B 192 651 541 754 ; +C 199 ; WX 222 ; N dotaccent ; B 192 639 290 765 ; +C 200 ; WX 369 ; N dieresis ; B 191 639 437 765 ; +C 202 ; WX 332 ; N ring ; B 191 600 401 807 ; +C 203 ; WX 324 ; N cedilla ; B 52 -222 231 0 ; +C 205 ; WX 552 ; N hungarumlaut ; B 239 605 594 800 ; +C 206 ; WX 302 ; N ogonek ; B 53 -191 202 0 ; +C 207 ; WX 502 ; N caron ; B 210 639 565 764 ; +C 208 ; WX 1000 ; N emdash ; B 81 248 1023 315 ; +C 225 ; WX 992 ; N AE ; B -20 0 1044 740 ; +C 227 ; WX 369 ; N ordfeminine ; B 102 407 494 753 ; +C 232 ; WX 517 ; N Lslash ; B 107 0 529 740 ; +C 233 ; WX 868 ; N Oslash ; B 76 -83 929 819 ; +C 234 ; WX 1194 ; N OE ; B 107 -13 1279 753 ; +C 235 ; WX 369 ; N ordmasculine ; B 116 407 466 753 ; +C 241 ; WX 1157 ; N ae ; B 80 -13 1169 561 ; +C 245 ; WX 200 ; N dotlessi ; B 65 0 236 547 ; +C 248 ; WX 300 ; N lslash ; B 95 0 354 740 ; +C 249 ; WX 653 ; N oslash ; B 51 -64 703 614 ; +C 250 ; WX 1137 ; N oe ; B 80 -13 1160 561 ; +C 251 ; WX 554 ; N germandbls ; B 61 -13 578 753 ; +C -1 ; WX 650 ; N ecircumflex ; B 84 -13 664 764 ; +C -1 ; WX 650 ; N edieresis ; B 84 -13 664 765 ; +C -1 ; WX 683 ; N aacute ; B 88 -13 722 786 ; +C -1 ; WX 747 ; N registered ; B 53 -12 830 752 ; +C -1 ; WX 200 ; N icircumflex ; B 41 0 395 764 ; +C -1 ; WX 608 ; N udieresis ; B 100 -13 642 765 ; +C -1 ; WX 655 ; N ograve ; B 88 -13 669 786 ; +C -1 ; WX 608 ; N uacute ; B 100 -13 642 786 ; +C -1 ; WX 608 ; N ucircumflex ; B 100 -13 642 764 ; +C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ; +C -1 ; WX 200 ; N igrave ; B 65 0 296 786 ; +C -1 ; WX 226 ; N Icircumflex ; B 76 0 439 927 ; +C -1 ; WX 647 ; N ccedilla ; B 87 -222 678 561 ; +C -1 ; WX 683 ; N adieresis ; B 88 -13 722 765 ; +C -1 ; WX 536 ; N Ecircumflex ; B 70 0 612 927 ; +C -1 ; WX 388 ; N scaron ; B 49 -13 508 764 ; +C -1 ; WX 682 ; N thorn ; B 28 -192 699 740 ; +C -1 ; WX 1000 ; N trademark ; B 137 296 953 740 ; +C -1 ; WX 650 ; N egrave ; B 84 -13 664 786 ; +C -1 ; WX 332 ; N threesuperior ; B 98 289 408 747 ; +C -1 ; WX 425 ; N zcaron ; B 10 0 527 764 ; +C -1 ; WX 683 ; N atilde ; B 88 -13 722 754 ; +C -1 ; WX 683 ; N aring ; B 88 -13 722 807 ; +C -1 ; WX 655 ; N ocircumflex ; B 88 -13 669 764 ; +C -1 ; WX 536 ; N Edieresis ; B 70 0 612 928 ; +C -1 ; WX 831 ; N threequarters ; B 126 0 825 747 ; +C -1 ; WX 536 ; N ydieresis ; B 97 -192 624 765 ; +C -1 ; WX 536 ; N yacute ; B 97 -192 624 786 ; +C -1 ; WX 200 ; N iacute ; B 65 0 397 786 ; +C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ; +C -1 ; WX 655 ; N Uacute ; B 118 -13 716 949 ; +C -1 ; WX 650 ; N eacute ; B 84 -13 664 786 ; +C -1 ; WX 869 ; N Ograve ; B 105 -13 901 949 ; +C -1 ; WX 683 ; N agrave ; B 88 -13 722 786 ; +C -1 ; WX 655 ; N Udieresis ; B 118 -13 716 928 ; +C -1 ; WX 683 ; N acircumflex ; B 88 -13 722 764 ; +C -1 ; WX 226 ; N Igrave ; B 76 0 340 949 ; +C -1 ; WX 332 ; N twosuperior ; B 74 296 433 747 ; +C -1 ; WX 655 ; N Ugrave ; B 118 -13 716 949 ; +C -1 ; WX 831 ; N onequarter ; B 183 0 770 740 ; +C -1 ; WX 655 ; N Ucircumflex ; B 118 -13 716 927 ; +C -1 ; WX 498 ; N Scaron ; B 57 -13 593 927 ; +C -1 ; WX 226 ; N Idieresis ; B 76 0 396 928 ; +C -1 ; WX 200 ; N idieresis ; B 65 0 353 765 ; +C -1 ; WX 536 ; N Egrave ; B 70 0 612 949 ; +C -1 ; WX 869 ; N Oacute ; B 105 -13 901 949 ; +C -1 ; WX 606 ; N divide ; B 92 -13 608 519 ; +C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ; +C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ; +C -1 ; WX 869 ; N Odieresis ; B 105 -13 901 928 ; +C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ; +C -1 ; WX 740 ; N Ntilde ; B 75 0 801 917 ; +C -1 ; WX 480 ; N Zcaron ; B 12 0 596 927 ; +C -1 ; WX 592 ; N Thorn ; B 60 0 621 740 ; +C -1 ; WX 226 ; N Iacute ; B 76 0 440 949 ; +C -1 ; WX 606 ; N plusminus ; B 47 -24 618 518 ; +C -1 ; WX 606 ; N multiply ; B 87 24 612 482 ; +C -1 ; WX 536 ; N Eacute ; B 70 0 612 949 ; +C -1 ; WX 592 ; N Ydieresis ; B 138 0 729 928 ; +C -1 ; WX 332 ; N onesuperior ; B 190 296 335 740 ; +C -1 ; WX 608 ; N ugrave ; B 100 -13 642 786 ; +C -1 ; WX 606 ; N logicalnot ; B 110 109 627 388 ; +C -1 ; WX 610 ; N ntilde ; B 65 0 609 754 ; +C -1 ; WX 869 ; N Otilde ; B 105 -13 901 917 ; +C -1 ; WX 655 ; N otilde ; B 88 -13 669 754 ; +C -1 ; WX 813 ; N Ccedilla ; B 105 -222 870 752 ; +C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ; +C -1 ; WX 831 ; N onehalf ; B 164 0 810 740 ; +C -1 ; WX 790 ; N Eth ; B 104 0 813 740 ; +C -1 ; WX 400 ; N degree ; B 158 421 451 709 ; +C -1 ; WX 592 ; N Yacute ; B 138 0 729 949 ; +C -1 ; WX 869 ; N Ocircumflex ; B 105 -13 901 927 ; +C -1 ; WX 655 ; N oacute ; B 88 -13 669 786 ; +C -1 ; WX 608 ; N mu ; B 46 -184 628 547 ; +C -1 ; WX 606 ; N minus ; B 92 219 608 287 ; +C -1 ; WX 655 ; N eth ; B 88 -12 675 753 ; +C -1 ; WX 655 ; N odieresis ; B 88 -13 669 765 ; +C -1 ; WX 747 ; N copyright ; B 53 -12 830 752 ; +C -1 ; WX 672 ; N brokenbar ; B 280 -100 510 740 ; +EndCharMetrics +StartKernData +StartKernPairs 216 + +KPX A y -62 +KPX A w -65 +KPX A v -70 +KPX A u -20 +KPX A quoteright -100 +KPX A quotedblright -100 +KPX A Y -92 +KPX A W -60 +KPX A V -102 +KPX A U -40 +KPX A T -45 +KPX A Q -40 +KPX A O -50 +KPX A G -40 +KPX A C -40 + +KPX B A -10 + +KPX C A -40 + +KPX D period -20 +KPX D comma -20 +KPX D Y -30 +KPX D W -10 +KPX D V -50 +KPX D A -50 + +KPX F period -160 +KPX F e -20 +KPX F comma -180 +KPX F a -20 +KPX F A -75 + +KPX G period -20 +KPX G comma -20 +KPX G Y -20 + +KPX J period -15 +KPX J a -20 +KPX J A -30 + +KPX K o -15 +KPX K e -20 +KPX K O -20 + +KPX L y -23 +KPX L quoteright -130 +KPX L quotedblright -130 +KPX L Y -91 +KPX L W -67 +KPX L V -113 +KPX L T -46 + +KPX O period -30 +KPX O comma -30 +KPX O Y -30 +KPX O X -30 +KPX O W -20 +KPX O V -60 +KPX O T -30 +KPX O A -60 + +KPX P period -300 +KPX P o -60 +KPX P e -20 +KPX P comma -280 +KPX P a -20 +KPX P A -114 + +KPX Q comma 20 + +KPX R Y -10 +KPX R W 10 +KPX R V -10 +KPX R T 6 + +KPX S comma 20 + +KPX T y -50 +KPX T w -55 +KPX T u -46 +KPX T semicolon -29 +KPX T r -30 +KPX T period -91 +KPX T o -70 +KPX T i 10 +KPX T hyphen -75 +KPX T e -49 +KPX T comma -82 +KPX T colon -15 +KPX T a -90 +KPX T O -30 +KPX T A -45 + +KPX U period -20 +KPX U comma -20 +KPX U A -40 + +KPX V u -40 +KPX V semicolon -33 +KPX V period -165 +KPX V o -101 +KPX V i -5 +KPX V hyphen -75 +KPX V e -101 +KPX V comma -145 +KPX V colon -18 +KPX V a -104 +KPX V O -60 +KPX V G -20 +KPX V A -102 + +KPX W y -2 +KPX W u -30 +KPX W semicolon -33 +KPX W period -106 +KPX W o -46 +KPX W i 6 +KPX W hyphen -35 +KPX W e -47 +KPX W comma -106 +KPX W colon -15 +KPX W a -50 +KPX W O -20 +KPX W A -58 + +KPX Y u -52 +KPX Y semicolon -23 +KPX Y period -175 +KPX Y o -89 +KPX Y hyphen -85 +KPX Y e -89 +KPX Y comma -145 +KPX Y colon -10 +KPX Y a -93 +KPX Y O -30 +KPX Y A -92 + +KPX a p 20 +KPX a b 20 + +KPX b y -20 +KPX b v -20 + +KPX c y -20 +KPX c k -15 + +KPX comma space -110 +KPX comma quoteright -120 +KPX comma quotedblright -120 + +KPX e y -20 +KPX e w -20 +KPX e v -20 + +KPX f period -50 +KPX f o -40 +KPX f l -30 +KPX f i -34 +KPX f f -60 +KPX f e -20 +KPX f dotlessi -34 +KPX f comma -50 +KPX f a -40 + +KPX g a -15 + +KPX h y -30 + +KPX k y -5 +KPX k e -15 + +KPX m y -20 +KPX m u -20 +KPX m a -20 + +KPX n y -15 +KPX n v -20 + +KPX o y -20 +KPX o x -15 +KPX o w -20 +KPX o v -30 + +KPX p y -20 + +KPX period space -110 +KPX period quoteright -120 +KPX period quotedblright -120 + +KPX quotedblleft quoteleft -35 +KPX quotedblleft A -100 + +KPX quotedblright space -110 + +KPX quoteleft quoteleft -203 +KPX quoteleft A -100 + +KPX quoteright v -30 +KPX quoteright t 10 +KPX quoteright space -110 +KPX quoteright s -15 +KPX quoteright r -20 +KPX quoteright quoteright -203 +KPX quoteright quotedblright -35 +KPX quoteright d -110 + +KPX r y 40 +KPX r v 40 +KPX r u 20 +KPX r t 20 +KPX r s 20 +KPX r q -8 +KPX r period -73 +KPX r p 20 +KPX r o -20 +KPX r n 21 +KPX r m 28 +KPX r l 20 +KPX r k 20 +KPX r i 20 +KPX r hyphen -60 +KPX r g -15 +KPX r e -4 +KPX r d -6 +KPX r comma -75 +KPX r c -20 +KPX r a -20 + +KPX s period 20 +KPX s comma 20 + +KPX space quoteleft -110 +KPX space quotedblleft -110 +KPX space Y -60 +KPX space W -25 +KPX space V -50 +KPX space T -25 +KPX space A -20 + +KPX v period -130 +KPX v o -30 +KPX v e -20 +KPX v comma -100 +KPX v a -30 + +KPX w period -100 +KPX w o -30 +KPX w h 15 +KPX w e -20 +KPX w comma -90 +KPX w a -30 + +KPX y period -125 +KPX y o -30 +KPX y e -20 +KPX y comma -110 +KPX y a -30 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 163 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 149 163 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 216 163 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 211 163 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 231 148 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 181 163 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 111 163 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 47 163 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 114 163 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 109 163 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -4 163 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -108 163 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -41 163 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -86 163 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 163 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 277 163 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 214 163 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 280 163 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 276 163 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 245 163 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 28 163 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 190 163 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 107 163 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 173 163 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 149 163 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 159 163 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 163 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 19 163 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkd8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkd8a.afm new file mode 100644 index 00000000..036be6d8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkd8a.afm @@ -0,0 +1,415 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Jan 21 16:13:29 1992 +Comment UniqueID 37831 +Comment VMusage 31983 38875 +FontName Bookman-Demi +FullName ITC Bookman Demi +FamilyName ITC Bookman +Weight Demi +ItalicAngle 0 +IsFixedPitch false +FontBBox -194 -250 1346 934 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.004 +Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 502 +Ascender 725 +Descender -212 +StartCharMetrics 228 +C 32 ; WX 340 ; N space ; B 0 0 0 0 ; +C 33 ; WX 360 ; N exclam ; B 82 -8 282 698 ; +C 34 ; WX 420 ; N quotedbl ; B 11 379 369 698 ; +C 35 ; WX 660 ; N numbersign ; B 84 0 576 681 ; +C 36 ; WX 660 ; N dollar ; B 48 -119 620 805 ; +C 37 ; WX 940 ; N percent ; B 12 -8 924 698 ; +C 38 ; WX 800 ; N ampersand ; B 21 -17 772 698 ; +C 39 ; WX 320 ; N quoteright ; B 82 440 242 698 ; +C 40 ; WX 320 ; N parenleft ; B 48 -150 289 749 ; +C 41 ; WX 320 ; N parenright ; B 20 -150 262 749 ; +C 42 ; WX 460 ; N asterisk ; B 62 317 405 697 ; +C 43 ; WX 600 ; N plus ; B 51 9 555 514 ; +C 44 ; WX 340 ; N comma ; B 78 -124 257 162 ; +C 45 ; WX 360 ; N hyphen ; B 20 210 340 318 ; +C 46 ; WX 340 ; N period ; B 76 -8 258 172 ; +C 47 ; WX 600 ; N slash ; B 50 -149 555 725 ; +C 48 ; WX 660 ; N zero ; B 30 -17 639 698 ; +C 49 ; WX 660 ; N one ; B 137 0 568 681 ; +C 50 ; WX 660 ; N two ; B 41 0 628 698 ; +C 51 ; WX 660 ; N three ; B 37 -17 631 698 ; +C 52 ; WX 660 ; N four ; B 19 0 649 681 ; +C 53 ; WX 660 ; N five ; B 44 -17 623 723 ; +C 54 ; WX 660 ; N six ; B 34 -17 634 698 ; +C 55 ; WX 660 ; N seven ; B 36 0 632 681 ; +C 56 ; WX 660 ; N eight ; B 36 -17 633 698 ; +C 57 ; WX 660 ; N nine ; B 33 -17 636 698 ; +C 58 ; WX 340 ; N colon ; B 76 -8 258 515 ; +C 59 ; WX 340 ; N semicolon ; B 75 -124 259 515 ; +C 60 ; WX 600 ; N less ; B 49 -9 558 542 ; +C 61 ; WX 600 ; N equal ; B 51 109 555 421 ; +C 62 ; WX 600 ; N greater ; B 48 -9 557 542 ; +C 63 ; WX 660 ; N question ; B 61 -8 608 698 ; +C 64 ; WX 820 ; N at ; B 60 -17 758 698 ; +C 65 ; WX 720 ; N A ; B -34 0 763 681 ; +C 66 ; WX 720 ; N B ; B 20 0 693 681 ; +C 67 ; WX 740 ; N C ; B 35 -17 724 698 ; +C 68 ; WX 780 ; N D ; B 20 0 748 681 ; +C 69 ; WX 720 ; N E ; B 20 0 724 681 ; +C 70 ; WX 680 ; N F ; B 20 0 686 681 ; +C 71 ; WX 780 ; N G ; B 35 -17 773 698 ; +C 72 ; WX 820 ; N H ; B 20 0 800 681 ; +C 73 ; WX 400 ; N I ; B 20 0 379 681 ; +C 74 ; WX 640 ; N J ; B -12 -17 622 681 ; +C 75 ; WX 800 ; N K ; B 20 0 796 681 ; +C 76 ; WX 640 ; N L ; B 20 0 668 681 ; +C 77 ; WX 940 ; N M ; B 20 0 924 681 ; +C 78 ; WX 740 ; N N ; B 20 0 724 681 ; +C 79 ; WX 800 ; N O ; B 35 -17 769 698 ; +C 80 ; WX 660 ; N P ; B 20 0 658 681 ; +C 81 ; WX 800 ; N Q ; B 35 -226 775 698 ; +C 82 ; WX 780 ; N R ; B 20 0 783 681 ; +C 83 ; WX 660 ; N S ; B 21 -17 639 698 ; +C 84 ; WX 700 ; N T ; B -4 0 703 681 ; +C 85 ; WX 740 ; N U ; B 15 -17 724 681 ; +C 86 ; WX 720 ; N V ; B -20 0 730 681 ; +C 87 ; WX 940 ; N W ; B -20 0 963 681 ; +C 88 ; WX 780 ; N X ; B 1 0 770 681 ; +C 89 ; WX 700 ; N Y ; B -20 0 718 681 ; +C 90 ; WX 640 ; N Z ; B 6 0 635 681 ; +C 91 ; WX 300 ; N bracketleft ; B 75 -138 285 725 ; +C 92 ; WX 600 ; N backslash ; B 50 0 555 725 ; +C 93 ; WX 300 ; N bracketright ; B 21 -138 231 725 ; +C 94 ; WX 600 ; N asciicircum ; B 52 281 554 681 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 320 ; N quoteleft ; B 82 440 242 698 ; +C 97 ; WX 580 ; N a ; B 28 -8 588 515 ; +C 98 ; WX 600 ; N b ; B -20 -8 568 725 ; +C 99 ; WX 580 ; N c ; B 31 -8 550 515 ; +C 100 ; WX 640 ; N d ; B 31 -8 622 725 ; +C 101 ; WX 580 ; N e ; B 31 -8 548 515 ; +C 102 ; WX 380 ; N f ; B 22 0 461 741 ; L i fi ; L l fl ; +C 103 ; WX 580 ; N g ; B 9 -243 583 595 ; +C 104 ; WX 680 ; N h ; B 22 0 654 725 ; +C 105 ; WX 360 ; N i ; B 22 0 335 729 ; +C 106 ; WX 340 ; N j ; B -94 -221 278 729 ; +C 107 ; WX 660 ; N k ; B 22 0 643 725 ; +C 108 ; WX 340 ; N l ; B 9 0 322 725 ; +C 109 ; WX 1000 ; N m ; B 22 0 980 515 ; +C 110 ; WX 680 ; N n ; B 22 0 652 515 ; +C 111 ; WX 620 ; N o ; B 31 -8 585 515 ; +C 112 ; WX 640 ; N p ; B 22 -212 611 515 ; +C 113 ; WX 620 ; N q ; B 31 -212 633 515 ; +C 114 ; WX 460 ; N r ; B 22 0 462 502 ; +C 115 ; WX 520 ; N s ; B 22 -8 492 515 ; +C 116 ; WX 460 ; N t ; B 22 -8 445 660 ; +C 117 ; WX 660 ; N u ; B 22 -8 653 502 ; +C 118 ; WX 600 ; N v ; B -6 0 593 502 ; +C 119 ; WX 800 ; N w ; B -6 0 810 502 ; +C 120 ; WX 600 ; N x ; B 8 0 591 502 ; +C 121 ; WX 620 ; N y ; B 6 -221 613 502 ; +C 122 ; WX 560 ; N z ; B 22 0 547 502 ; +C 123 ; WX 320 ; N braceleft ; B 14 -139 301 726 ; +C 124 ; WX 600 ; N bar ; B 243 -250 362 750 ; +C 125 ; WX 320 ; N braceright ; B 15 -140 302 725 ; +C 126 ; WX 600 ; N asciitilde ; B 51 162 555 368 ; +C 161 ; WX 360 ; N exclamdown ; B 84 -191 284 515 ; +C 162 ; WX 660 ; N cent ; B 133 17 535 674 ; +C 163 ; WX 660 ; N sterling ; B 10 -17 659 698 ; +C 164 ; WX 120 ; N fraction ; B -194 0 312 681 ; +C 165 ; WX 660 ; N yen ; B -28 0 696 681 ; +C 166 ; WX 660 ; N florin ; B -46 -209 674 749 ; +C 167 ; WX 600 ; N section ; B 36 -153 560 698 ; +C 168 ; WX 660 ; N currency ; B 77 88 584 593 ; +C 169 ; WX 240 ; N quotesingle ; B 42 379 178 698 ; +C 170 ; WX 540 ; N quotedblleft ; B 82 439 449 698 ; +C 171 ; WX 400 ; N guillemotleft ; B 34 101 360 457 ; +C 172 ; WX 220 ; N guilsinglleft ; B 34 101 188 457 ; +C 173 ; WX 220 ; N guilsinglright ; B 34 101 188 457 ; +C 174 ; WX 740 ; N fi ; B 22 0 710 741 ; +C 175 ; WX 740 ; N fl ; B 22 0 710 741 ; +C 177 ; WX 500 ; N endash ; B -25 212 525 318 ; +C 178 ; WX 440 ; N dagger ; B 33 -156 398 698 ; +C 179 ; WX 380 ; N daggerdbl ; B 8 -156 380 698 ; +C 180 ; WX 340 ; N periodcentered ; B 76 175 258 355 ; +C 182 ; WX 800 ; N paragraph ; B 51 0 698 681 ; +C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ; +C 184 ; WX 320 ; N quotesinglbase ; B 82 -114 242 144 ; +C 185 ; WX 540 ; N quotedblbase ; B 82 -114 450 144 ; +C 186 ; WX 540 ; N quotedblright ; B 82 440 449 698 ; +C 187 ; WX 400 ; N guillemotright ; B 34 101 360 457 ; +C 188 ; WX 1000 ; N ellipsis ; B 76 -8 924 172 ; +C 189 ; WX 1360 ; N perthousand ; B 12 -8 1346 698 ; +C 191 ; WX 660 ; N questiondown ; B 62 -191 609 515 ; +C 193 ; WX 400 ; N grave ; B 68 547 327 730 ; +C 194 ; WX 400 ; N acute ; B 68 547 327 731 ; +C 195 ; WX 500 ; N circumflex ; B 68 555 430 731 ; +C 196 ; WX 480 ; N tilde ; B 69 556 421 691 ; +C 197 ; WX 460 ; N macron ; B 68 577 383 663 ; +C 198 ; WX 500 ; N breve ; B 68 553 429 722 ; +C 199 ; WX 320 ; N dotaccent ; B 68 536 259 730 ; +C 200 ; WX 500 ; N dieresis ; B 68 560 441 698 ; +C 202 ; WX 340 ; N ring ; B 68 552 275 755 ; +C 203 ; WX 360 ; N cedilla ; B 68 -213 284 0 ; +C 205 ; WX 440 ; N hungarumlaut ; B 68 554 365 741 ; +C 206 ; WX 320 ; N ogonek ; B 68 -163 246 0 ; +C 207 ; WX 500 ; N caron ; B 68 541 430 717 ; +C 208 ; WX 1000 ; N emdash ; B -25 212 1025 318 ; +C 225 ; WX 1140 ; N AE ; B -34 0 1149 681 ; +C 227 ; WX 400 ; N ordfeminine ; B 27 383 396 698 ; +C 232 ; WX 640 ; N Lslash ; B 20 0 668 681 ; +C 233 ; WX 800 ; N Oslash ; B 35 -110 771 781 ; +C 234 ; WX 1220 ; N OE ; B 35 -17 1219 698 ; +C 235 ; WX 400 ; N ordmasculine ; B 17 383 383 698 ; +C 241 ; WX 880 ; N ae ; B 28 -8 852 515 ; +C 245 ; WX 360 ; N dotlessi ; B 22 0 335 502 ; +C 248 ; WX 340 ; N lslash ; B 9 0 322 725 ; +C 249 ; WX 620 ; N oslash ; B 31 -40 586 551 ; +C 250 ; WX 940 ; N oe ; B 31 -8 908 515 ; +C 251 ; WX 660 ; N germandbls ; B -61 -91 644 699 ; +C -1 ; WX 580 ; N ecircumflex ; B 31 -8 548 731 ; +C -1 ; WX 580 ; N edieresis ; B 31 -8 548 698 ; +C -1 ; WX 580 ; N aacute ; B 28 -8 588 731 ; +C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ; +C -1 ; WX 360 ; N icircumflex ; B -2 0 360 731 ; +C -1 ; WX 660 ; N udieresis ; B 22 -8 653 698 ; +C -1 ; WX 620 ; N ograve ; B 31 -8 585 730 ; +C -1 ; WX 660 ; N uacute ; B 22 -8 653 731 ; +C -1 ; WX 660 ; N ucircumflex ; B 22 -8 653 731 ; +C -1 ; WX 720 ; N Aacute ; B -34 0 763 910 ; +C -1 ; WX 360 ; N igrave ; B 22 0 335 730 ; +C -1 ; WX 400 ; N Icircumflex ; B 18 0 380 910 ; +C -1 ; WX 580 ; N ccedilla ; B 31 -213 550 515 ; +C -1 ; WX 580 ; N adieresis ; B 28 -8 588 698 ; +C -1 ; WX 720 ; N Ecircumflex ; B 20 0 724 910 ; +C -1 ; WX 520 ; N scaron ; B 22 -8 492 717 ; +C -1 ; WX 640 ; N thorn ; B 22 -212 611 725 ; +C -1 ; WX 980 ; N trademark ; B 42 277 982 681 ; +C -1 ; WX 580 ; N egrave ; B 31 -8 548 730 ; +C -1 ; WX 396 ; N threesuperior ; B 5 269 391 698 ; +C -1 ; WX 560 ; N zcaron ; B 22 0 547 717 ; +C -1 ; WX 580 ; N atilde ; B 28 -8 588 691 ; +C -1 ; WX 580 ; N aring ; B 28 -8 588 755 ; +C -1 ; WX 620 ; N ocircumflex ; B 31 -8 585 731 ; +C -1 ; WX 720 ; N Edieresis ; B 20 0 724 877 ; +C -1 ; WX 990 ; N threequarters ; B 15 0 967 692 ; +C -1 ; WX 620 ; N ydieresis ; B 6 -221 613 698 ; +C -1 ; WX 620 ; N yacute ; B 6 -221 613 731 ; +C -1 ; WX 360 ; N iacute ; B 22 0 335 731 ; +C -1 ; WX 720 ; N Acircumflex ; B -34 0 763 910 ; +C -1 ; WX 740 ; N Uacute ; B 15 -17 724 910 ; +C -1 ; WX 580 ; N eacute ; B 31 -8 548 731 ; +C -1 ; WX 800 ; N Ograve ; B 35 -17 769 909 ; +C -1 ; WX 580 ; N agrave ; B 28 -8 588 730 ; +C -1 ; WX 740 ; N Udieresis ; B 15 -17 724 877 ; +C -1 ; WX 580 ; N acircumflex ; B 28 -8 588 731 ; +C -1 ; WX 400 ; N Igrave ; B 20 0 379 909 ; +C -1 ; WX 396 ; N twosuperior ; B 14 279 396 698 ; +C -1 ; WX 740 ; N Ugrave ; B 15 -17 724 909 ; +C -1 ; WX 990 ; N onequarter ; B 65 0 967 681 ; +C -1 ; WX 740 ; N Ucircumflex ; B 15 -17 724 910 ; +C -1 ; WX 660 ; N Scaron ; B 21 -17 639 896 ; +C -1 ; WX 400 ; N Idieresis ; B 18 0 391 877 ; +C -1 ; WX 360 ; N idieresis ; B -2 0 371 698 ; +C -1 ; WX 720 ; N Egrave ; B 20 0 724 909 ; +C -1 ; WX 800 ; N Oacute ; B 35 -17 769 910 ; +C -1 ; WX 600 ; N divide ; B 51 9 555 521 ; +C -1 ; WX 720 ; N Atilde ; B -34 0 763 870 ; +C -1 ; WX 720 ; N Aring ; B -34 0 763 934 ; +C -1 ; WX 800 ; N Odieresis ; B 35 -17 769 877 ; +C -1 ; WX 720 ; N Adieresis ; B -34 0 763 877 ; +C -1 ; WX 740 ; N Ntilde ; B 20 0 724 870 ; +C -1 ; WX 640 ; N Zcaron ; B 6 0 635 896 ; +C -1 ; WX 660 ; N Thorn ; B 20 0 658 681 ; +C -1 ; WX 400 ; N Iacute ; B 20 0 379 910 ; +C -1 ; WX 600 ; N plusminus ; B 51 0 555 514 ; +C -1 ; WX 600 ; N multiply ; B 48 10 552 514 ; +C -1 ; WX 720 ; N Eacute ; B 20 0 724 910 ; +C -1 ; WX 700 ; N Ydieresis ; B -20 0 718 877 ; +C -1 ; WX 396 ; N onesuperior ; B 65 279 345 687 ; +C -1 ; WX 660 ; N ugrave ; B 22 -8 653 730 ; +C -1 ; WX 600 ; N logicalnot ; B 51 129 555 421 ; +C -1 ; WX 680 ; N ntilde ; B 22 0 652 691 ; +C -1 ; WX 800 ; N Otilde ; B 35 -17 769 870 ; +C -1 ; WX 620 ; N otilde ; B 31 -8 585 691 ; +C -1 ; WX 740 ; N Ccedilla ; B 35 -213 724 698 ; +C -1 ; WX 720 ; N Agrave ; B -34 0 763 909 ; +C -1 ; WX 990 ; N onehalf ; B 65 0 980 681 ; +C -1 ; WX 780 ; N Eth ; B 20 0 748 681 ; +C -1 ; WX 400 ; N degree ; B 50 398 350 698 ; +C -1 ; WX 700 ; N Yacute ; B -20 0 718 910 ; +C -1 ; WX 800 ; N Ocircumflex ; B 35 -17 769 910 ; +C -1 ; WX 620 ; N oacute ; B 31 -8 585 731 ; +C -1 ; WX 660 ; N mu ; B 22 -221 653 502 ; +C -1 ; WX 600 ; N minus ; B 51 207 555 323 ; +C -1 ; WX 620 ; N eth ; B 31 -8 585 741 ; +C -1 ; WX 620 ; N odieresis ; B 31 -8 585 698 ; +C -1 ; WX 740 ; N copyright ; B 23 -17 723 698 ; +C -1 ; WX 600 ; N brokenbar ; B 243 -175 362 675 ; +EndCharMetrics +StartKernData +StartKernPairs 90 + +KPX A y -1 +KPX A w -9 +KPX A v -8 +KPX A Y -52 +KPX A W -20 +KPX A V -68 +KPX A T -40 + +KPX F period -132 +KPX F comma -130 +KPX F A -59 + +KPX L y 19 +KPX L Y -35 +KPX L W -41 +KPX L V -50 +KPX L T -4 + +KPX P period -128 +KPX P comma -129 +KPX P A -46 + +KPX R y -8 +KPX R Y -20 +KPX R W -24 +KPX R V -29 +KPX R T -4 + +KPX T semicolon 5 +KPX T s -10 +KPX T r 27 +KPX T period -122 +KPX T o -28 +KPX T i 27 +KPX T hyphen -10 +KPX T e -29 +KPX T comma -122 +KPX T colon 7 +KPX T c -29 +KPX T a -24 +KPX T A -42 + +KPX V y 12 +KPX V u -11 +KPX V semicolon -38 +KPX V r -15 +KPX V period -105 +KPX V o -79 +KPX V i 15 +KPX V hyphen -10 +KPX V e -80 +KPX V comma -103 +KPX V colon -37 +KPX V a -74 +KPX V A -88 + +KPX W y 12 +KPX W u -11 +KPX W semicolon -38 +KPX W r -15 +KPX W period -105 +KPX W o -78 +KPX W i 15 +KPX W hyphen -10 +KPX W e -79 +KPX W comma -103 +KPX W colon -37 +KPX W a -73 +KPX W A -60 + +KPX Y v 24 +KPX Y u -13 +KPX Y semicolon -34 +KPX Y q -66 +KPX Y period -105 +KPX Y p -23 +KPX Y o -66 +KPX Y i 2 +KPX Y hyphen -10 +KPX Y e -67 +KPX Y comma -103 +KPX Y colon -32 +KPX Y a -60 +KPX Y A -56 + +KPX f f 21 + +KPX r q -9 +KPX r period -102 +KPX r o -9 +KPX r n 20 +KPX r m 20 +KPX r hyphen -10 +KPX r h -23 +KPX r g -9 +KPX r f 20 +KPX r e -10 +KPX r d -10 +KPX r comma -101 +KPX r c -9 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 179 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 110 179 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 110 179 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 179 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 190 179 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 179 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 179 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 110 179 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 110 179 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 179 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 179 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -50 179 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -50 179 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 179 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 179 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 179 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 179 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 150 179 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 179 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 160 179 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 80 179 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 170 179 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 120 179 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 120 179 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 179 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 179 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 100 179 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 179 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 90 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 40 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 40 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 90 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 100 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 30 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 40 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -70 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -70 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 60 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 50 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 10 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 130 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 80 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 130 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 110 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm new file mode 100644 index 00000000..c2da47a2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm @@ -0,0 +1,417 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Jan 21 16:12:43 1992 +Comment UniqueID 37832 +Comment VMusage 32139 39031 +FontName Bookman-DemiItalic +FullName ITC Bookman Demi Italic +FamilyName ITC Bookman +Weight Demi +ItalicAngle -10 +IsFixedPitch false +FontBBox -231 -250 1333 941 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.004 +Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 515 +Ascender 732 +Descender -213 +StartCharMetrics 228 +C 32 ; WX 340 ; N space ; B 0 0 0 0 ; +C 33 ; WX 320 ; N exclam ; B 86 -8 366 698 ; +C 34 ; WX 380 ; N quotedbl ; B 140 371 507 697 ; +C 35 ; WX 680 ; N numbersign ; B 157 0 649 681 ; +C 36 ; WX 680 ; N dollar ; B 45 -164 697 790 ; +C 37 ; WX 880 ; N percent ; B 106 -17 899 698 ; +C 38 ; WX 980 ; N ampersand ; B 48 -17 1016 698 ; +C 39 ; WX 320 ; N quoteright ; B 171 420 349 698 ; +C 40 ; WX 260 ; N parenleft ; B 31 -134 388 741 ; +C 41 ; WX 260 ; N parenright ; B -35 -134 322 741 ; +C 42 ; WX 460 ; N asterisk ; B 126 346 508 698 ; +C 43 ; WX 600 ; N plus ; B 91 9 595 514 ; +C 44 ; WX 340 ; N comma ; B 100 -124 298 185 ; +C 45 ; WX 280 ; N hyphen ; B 59 218 319 313 ; +C 46 ; WX 340 ; N period ; B 106 -8 296 177 ; +C 47 ; WX 360 ; N slash ; B 9 -106 502 742 ; +C 48 ; WX 680 ; N zero ; B 87 -17 703 698 ; +C 49 ; WX 680 ; N one ; B 123 0 565 681 ; +C 50 ; WX 680 ; N two ; B 67 0 674 698 ; +C 51 ; WX 680 ; N three ; B 72 -17 683 698 ; +C 52 ; WX 680 ; N four ; B 63 0 708 681 ; +C 53 ; WX 680 ; N five ; B 78 -17 669 681 ; +C 54 ; WX 680 ; N six ; B 88 -17 704 698 ; +C 55 ; WX 680 ; N seven ; B 123 0 739 681 ; +C 56 ; WX 680 ; N eight ; B 68 -17 686 698 ; +C 57 ; WX 680 ; N nine ; B 71 -17 712 698 ; +C 58 ; WX 340 ; N colon ; B 106 -8 356 515 ; +C 59 ; WX 340 ; N semicolon ; B 100 -124 352 515 ; +C 60 ; WX 620 ; N less ; B 79 -9 588 540 ; +C 61 ; WX 600 ; N equal ; B 91 109 595 421 ; +C 62 ; WX 620 ; N greater ; B 89 -9 598 540 ; +C 63 ; WX 620 ; N question ; B 145 -8 668 698 ; +C 64 ; WX 780 ; N at ; B 80 -17 790 698 ; +C 65 ; WX 720 ; N A ; B -27 0 769 681 ; +C 66 ; WX 720 ; N B ; B 14 0 762 681 ; +C 67 ; WX 700 ; N C ; B 78 -17 754 698 ; +C 68 ; WX 760 ; N D ; B 14 0 805 681 ; +C 69 ; WX 720 ; N E ; B 14 0 777 681 ; +C 70 ; WX 660 ; N F ; B 14 0 763 681 ; +C 71 ; WX 760 ; N G ; B 77 -17 828 698 ; +C 72 ; WX 800 ; N H ; B 14 0 910 681 ; +C 73 ; WX 380 ; N I ; B 14 0 485 681 ; +C 74 ; WX 620 ; N J ; B 8 -17 721 681 ; +C 75 ; WX 780 ; N K ; B 14 0 879 681 ; +C 76 ; WX 640 ; N L ; B 14 0 725 681 ; +C 77 ; WX 860 ; N M ; B 14 0 970 681 ; +C 78 ; WX 740 ; N N ; B 14 0 845 681 ; +C 79 ; WX 760 ; N O ; B 78 -17 806 698 ; +C 80 ; WX 640 ; N P ; B -6 0 724 681 ; +C 81 ; WX 760 ; N Q ; B 37 -213 805 698 ; +C 82 ; WX 740 ; N R ; B 14 0 765 681 ; +C 83 ; WX 700 ; N S ; B 59 -17 731 698 ; +C 84 ; WX 700 ; N T ; B 70 0 802 681 ; +C 85 ; WX 740 ; N U ; B 112 -17 855 681 ; +C 86 ; WX 660 ; N V ; B 72 0 819 681 ; +C 87 ; WX 1000 ; N W ; B 72 0 1090 681 ; +C 88 ; WX 740 ; N X ; B -7 0 835 681 ; +C 89 ; WX 660 ; N Y ; B 72 0 817 681 ; +C 90 ; WX 680 ; N Z ; B 23 0 740 681 ; +C 91 ; WX 260 ; N bracketleft ; B 9 -118 374 741 ; +C 92 ; WX 580 ; N backslash ; B 73 0 575 741 ; +C 93 ; WX 260 ; N bracketright ; B -18 -118 347 741 ; +C 94 ; WX 620 ; N asciicircum ; B 92 281 594 681 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 320 ; N quoteleft ; B 155 420 333 698 ; +C 97 ; WX 680 ; N a ; B 84 -8 735 515 ; +C 98 ; WX 600 ; N b ; B 57 -8 633 732 ; +C 99 ; WX 560 ; N c ; B 58 -8 597 515 ; +C 100 ; WX 680 ; N d ; B 60 -8 714 732 ; +C 101 ; WX 560 ; N e ; B 59 -8 596 515 ; +C 102 ; WX 420 ; N f ; B -192 -213 641 741 ; L i fi ; L l fl ; +C 103 ; WX 620 ; N g ; B 21 -213 669 515 ; +C 104 ; WX 700 ; N h ; B 93 -8 736 732 ; +C 105 ; WX 380 ; N i ; B 83 -8 420 755 ; +C 106 ; WX 320 ; N j ; B -160 -213 392 755 ; +C 107 ; WX 700 ; N k ; B 97 -8 732 732 ; +C 108 ; WX 380 ; N l ; B 109 -8 410 732 ; +C 109 ; WX 960 ; N m ; B 83 -8 996 515 ; +C 110 ; WX 680 ; N n ; B 83 -8 715 515 ; +C 111 ; WX 600 ; N o ; B 59 -8 627 515 ; +C 112 ; WX 660 ; N p ; B -24 -213 682 515 ; +C 113 ; WX 620 ; N q ; B 60 -213 640 515 ; +C 114 ; WX 500 ; N r ; B 84 0 582 515 ; +C 115 ; WX 540 ; N s ; B 32 -8 573 515 ; +C 116 ; WX 440 ; N t ; B 106 -8 488 658 ; +C 117 ; WX 680 ; N u ; B 83 -8 720 507 ; +C 118 ; WX 540 ; N v ; B 56 -8 572 515 ; +C 119 ; WX 860 ; N w ; B 56 -8 891 515 ; +C 120 ; WX 620 ; N x ; B 10 -8 654 515 ; +C 121 ; WX 600 ; N y ; B 25 -213 642 507 ; +C 122 ; WX 560 ; N z ; B 36 -8 586 515 ; +C 123 ; WX 300 ; N braceleft ; B 49 -123 413 742 ; +C 124 ; WX 620 ; N bar ; B 303 -250 422 750 ; +C 125 ; WX 300 ; N braceright ; B -8 -114 356 751 ; +C 126 ; WX 620 ; N asciitilde ; B 101 162 605 368 ; +C 161 ; WX 320 ; N exclamdown ; B 64 -191 344 515 ; +C 162 ; WX 680 ; N cent ; B 161 25 616 718 ; +C 163 ; WX 680 ; N sterling ; B 0 -17 787 698 ; +C 164 ; WX 120 ; N fraction ; B -144 0 382 681 ; +C 165 ; WX 680 ; N yen ; B 92 0 782 681 ; +C 166 ; WX 680 ; N florin ; B -28 -199 743 741 ; +C 167 ; WX 620 ; N section ; B 46 -137 638 698 ; +C 168 ; WX 680 ; N currency ; B 148 85 637 571 ; +C 169 ; WX 180 ; N quotesingle ; B 126 370 295 696 ; +C 170 ; WX 520 ; N quotedblleft ; B 156 420 545 698 ; +C 171 ; WX 380 ; N guillemotleft ; B 62 84 406 503 ; +C 172 ; WX 220 ; N guilsinglleft ; B 62 84 249 503 ; +C 173 ; WX 220 ; N guilsinglright ; B 62 84 249 503 ; +C 174 ; WX 820 ; N fi ; B -191 -213 850 741 ; +C 175 ; WX 820 ; N fl ; B -191 -213 850 741 ; +C 177 ; WX 500 ; N endash ; B 40 219 573 311 ; +C 178 ; WX 420 ; N dagger ; B 89 -137 466 698 ; +C 179 ; WX 420 ; N daggerdbl ; B 79 -137 486 698 ; +C 180 ; WX 340 ; N periodcentered ; B 126 173 316 358 ; +C 182 ; WX 680 ; N paragraph ; B 137 0 715 681 ; +C 183 ; WX 360 ; N bullet ; B 60 170 404 511 ; +C 184 ; WX 300 ; N quotesinglbase ; B 106 -112 284 166 ; +C 185 ; WX 520 ; N quotedblbase ; B 106 -112 495 166 ; +C 186 ; WX 520 ; N quotedblright ; B 171 420 560 698 ; +C 187 ; WX 380 ; N guillemotright ; B 62 84 406 503 ; +C 188 ; WX 1000 ; N ellipsis ; B 86 -8 942 177 ; +C 189 ; WX 1360 ; N perthousand ; B 106 -17 1333 698 ; +C 191 ; WX 620 ; N questiondown ; B 83 -189 606 515 ; +C 193 ; WX 380 ; N grave ; B 193 566 424 771 ; +C 194 ; WX 340 ; N acute ; B 176 566 407 771 ; +C 195 ; WX 480 ; N circumflex ; B 183 582 523 749 ; +C 196 ; WX 480 ; N tilde ; B 178 587 533 709 ; +C 197 ; WX 480 ; N macron ; B 177 603 531 691 ; +C 198 ; WX 460 ; N breve ; B 177 577 516 707 ; +C 199 ; WX 380 ; N dotaccent ; B 180 570 345 734 ; +C 200 ; WX 520 ; N dieresis ; B 180 570 569 734 ; +C 202 ; WX 360 ; N ring ; B 185 558 406 775 ; +C 203 ; WX 360 ; N cedilla ; B 68 -220 289 -8 ; +C 205 ; WX 560 ; N hungarumlaut ; B 181 560 616 775 ; +C 206 ; WX 320 ; N ogonek ; B 68 -182 253 0 ; +C 207 ; WX 480 ; N caron ; B 183 582 523 749 ; +C 208 ; WX 1000 ; N emdash ; B 40 219 1073 311 ; +C 225 ; WX 1140 ; N AE ; B -27 0 1207 681 ; +C 227 ; WX 440 ; N ordfeminine ; B 118 400 495 685 ; +C 232 ; WX 640 ; N Lslash ; B 14 0 724 681 ; +C 233 ; WX 760 ; N Oslash ; B 21 -29 847 725 ; +C 234 ; WX 1180 ; N OE ; B 94 -17 1245 698 ; +C 235 ; WX 440 ; N ordmasculine ; B 127 400 455 685 ; +C 241 ; WX 880 ; N ae ; B 39 -8 913 515 ; +C 245 ; WX 380 ; N dotlessi ; B 83 -8 420 507 ; +C 248 ; WX 380 ; N lslash ; B 63 -8 412 732 ; +C 249 ; WX 600 ; N oslash ; B 17 -54 661 571 ; +C 250 ; WX 920 ; N oe ; B 48 -8 961 515 ; +C 251 ; WX 660 ; N germandbls ; B -231 -213 702 741 ; +C -1 ; WX 560 ; N ecircumflex ; B 59 -8 596 749 ; +C -1 ; WX 560 ; N edieresis ; B 59 -8 596 734 ; +C -1 ; WX 680 ; N aacute ; B 84 -8 735 771 ; +C -1 ; WX 780 ; N registered ; B 83 -17 783 698 ; +C -1 ; WX 380 ; N icircumflex ; B 83 -8 433 749 ; +C -1 ; WX 680 ; N udieresis ; B 83 -8 720 734 ; +C -1 ; WX 600 ; N ograve ; B 59 -8 627 771 ; +C -1 ; WX 680 ; N uacute ; B 83 -8 720 771 ; +C -1 ; WX 680 ; N ucircumflex ; B 83 -8 720 749 ; +C -1 ; WX 720 ; N Aacute ; B -27 0 769 937 ; +C -1 ; WX 380 ; N igrave ; B 83 -8 424 771 ; +C -1 ; WX 380 ; N Icircumflex ; B 14 0 493 915 ; +C -1 ; WX 560 ; N ccedilla ; B 58 -220 597 515 ; +C -1 ; WX 680 ; N adieresis ; B 84 -8 735 734 ; +C -1 ; WX 720 ; N Ecircumflex ; B 14 0 777 915 ; +C -1 ; WX 540 ; N scaron ; B 32 -8 573 749 ; +C -1 ; WX 660 ; N thorn ; B -24 -213 682 732 ; +C -1 ; WX 940 ; N trademark ; B 42 277 982 681 ; +C -1 ; WX 560 ; N egrave ; B 59 -8 596 771 ; +C -1 ; WX 408 ; N threesuperior ; B 86 269 483 698 ; +C -1 ; WX 560 ; N zcaron ; B 36 -8 586 749 ; +C -1 ; WX 680 ; N atilde ; B 84 -8 735 709 ; +C -1 ; WX 680 ; N aring ; B 84 -8 735 775 ; +C -1 ; WX 600 ; N ocircumflex ; B 59 -8 627 749 ; +C -1 ; WX 720 ; N Edieresis ; B 14 0 777 900 ; +C -1 ; WX 1020 ; N threequarters ; B 86 0 1054 691 ; +C -1 ; WX 600 ; N ydieresis ; B 25 -213 642 734 ; +C -1 ; WX 600 ; N yacute ; B 25 -213 642 771 ; +C -1 ; WX 380 ; N iacute ; B 83 -8 420 771 ; +C -1 ; WX 720 ; N Acircumflex ; B -27 0 769 915 ; +C -1 ; WX 740 ; N Uacute ; B 112 -17 855 937 ; +C -1 ; WX 560 ; N eacute ; B 59 -8 596 771 ; +C -1 ; WX 760 ; N Ograve ; B 78 -17 806 937 ; +C -1 ; WX 680 ; N agrave ; B 84 -8 735 771 ; +C -1 ; WX 740 ; N Udieresis ; B 112 -17 855 900 ; +C -1 ; WX 680 ; N acircumflex ; B 84 -8 735 749 ; +C -1 ; WX 380 ; N Igrave ; B 14 0 485 937 ; +C -1 ; WX 408 ; N twosuperior ; B 91 279 485 698 ; +C -1 ; WX 740 ; N Ugrave ; B 112 -17 855 937 ; +C -1 ; WX 1020 ; N onequarter ; B 118 0 1054 681 ; +C -1 ; WX 740 ; N Ucircumflex ; B 112 -17 855 915 ; +C -1 ; WX 700 ; N Scaron ; B 59 -17 731 915 ; +C -1 ; WX 380 ; N Idieresis ; B 14 0 499 900 ; +C -1 ; WX 380 ; N idieresis ; B 83 -8 479 734 ; +C -1 ; WX 720 ; N Egrave ; B 14 0 777 937 ; +C -1 ; WX 760 ; N Oacute ; B 78 -17 806 937 ; +C -1 ; WX 600 ; N divide ; B 91 9 595 521 ; +C -1 ; WX 720 ; N Atilde ; B -27 0 769 875 ; +C -1 ; WX 720 ; N Aring ; B -27 0 769 941 ; +C -1 ; WX 760 ; N Odieresis ; B 78 -17 806 900 ; +C -1 ; WX 720 ; N Adieresis ; B -27 0 769 900 ; +C -1 ; WX 740 ; N Ntilde ; B 14 0 845 875 ; +C -1 ; WX 680 ; N Zcaron ; B 23 0 740 915 ; +C -1 ; WX 640 ; N Thorn ; B -6 0 701 681 ; +C -1 ; WX 380 ; N Iacute ; B 14 0 485 937 ; +C -1 ; WX 600 ; N plusminus ; B 91 0 595 514 ; +C -1 ; WX 600 ; N multiply ; B 91 10 595 514 ; +C -1 ; WX 720 ; N Eacute ; B 14 0 777 937 ; +C -1 ; WX 660 ; N Ydieresis ; B 72 0 817 900 ; +C -1 ; WX 408 ; N onesuperior ; B 118 279 406 688 ; +C -1 ; WX 680 ; N ugrave ; B 83 -8 720 771 ; +C -1 ; WX 620 ; N logicalnot ; B 81 129 585 421 ; +C -1 ; WX 680 ; N ntilde ; B 83 -8 715 709 ; +C -1 ; WX 760 ; N Otilde ; B 78 -17 806 875 ; +C -1 ; WX 600 ; N otilde ; B 59 -8 627 709 ; +C -1 ; WX 700 ; N Ccedilla ; B 78 -220 754 698 ; +C -1 ; WX 720 ; N Agrave ; B -27 0 769 937 ; +C -1 ; WX 1020 ; N onehalf ; B 118 0 1036 681 ; +C -1 ; WX 760 ; N Eth ; B 14 0 805 681 ; +C -1 ; WX 400 ; N degree ; B 130 398 430 698 ; +C -1 ; WX 660 ; N Yacute ; B 72 0 817 937 ; +C -1 ; WX 760 ; N Ocircumflex ; B 78 -17 806 915 ; +C -1 ; WX 600 ; N oacute ; B 59 -8 627 771 ; +C -1 ; WX 680 ; N mu ; B 54 -213 720 507 ; +C -1 ; WX 600 ; N minus ; B 91 207 595 323 ; +C -1 ; WX 600 ; N eth ; B 59 -8 662 741 ; +C -1 ; WX 600 ; N odieresis ; B 59 -8 627 734 ; +C -1 ; WX 780 ; N copyright ; B 83 -17 783 698 ; +C -1 ; WX 620 ; N brokenbar ; B 303 -175 422 675 ; +EndCharMetrics +StartKernData +StartKernPairs 92 + +KPX A y 20 +KPX A w 20 +KPX A v 20 +KPX A Y -25 +KPX A W -35 +KPX A V -40 +KPX A T -17 + +KPX F period -105 +KPX F comma -98 +KPX F A -35 + +KPX L y 62 +KPX L Y -5 +KPX L W -15 +KPX L V -19 +KPX L T -26 + +KPX P period -105 +KPX P comma -98 +KPX P A -31 + +KPX R y 27 +KPX R Y 4 +KPX R W -4 +KPX R V -8 +KPX R T -3 + +KPX T y 56 +KPX T w 69 +KPX T u 42 +KPX T semicolon 31 +KPX T s -1 +KPX T r 41 +KPX T period -107 +KPX T o -5 +KPX T i 42 +KPX T hyphen -20 +KPX T e -10 +KPX T comma -100 +KPX T colon 26 +KPX T c -8 +KPX T a -8 +KPX T A -42 + +KPX V y 17 +KPX V u -1 +KPX V semicolon -22 +KPX V r 2 +KPX V period -115 +KPX V o -50 +KPX V i 32 +KPX V hyphen -20 +KPX V e -50 +KPX V comma -137 +KPX V colon -28 +KPX V a -50 +KPX V A -50 + +KPX W y -51 +KPX W u -69 +KPX W semicolon -81 +KPX W r -66 +KPX W period -183 +KPX W o -100 +KPX W i -36 +KPX W hyphen -22 +KPX W e -100 +KPX W comma -201 +KPX W colon -86 +KPX W a -100 +KPX W A -77 + +KPX Y v 26 +KPX Y u -1 +KPX Y semicolon -4 +KPX Y q -43 +KPX Y period -113 +KPX Y o -41 +KPX Y i 20 +KPX Y hyphen -20 +KPX Y e -46 +KPX Y comma -106 +KPX Y colon -9 +KPX Y a -45 +KPX Y A -30 + +KPX f f 10 + +KPX r q -3 +KPX r period -120 +KPX r o -1 +KPX r n 39 +KPX r m 39 +KPX r hyphen -20 +KPX r h -35 +KPX r g -23 +KPX r f 42 +KPX r e -6 +KPX r d -3 +KPX r comma -113 +KPX r c -5 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 190 166 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 120 166 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 100 166 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 170 166 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 200 166 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 166 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 190 166 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 120 166 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 100 166 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 170 166 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 166 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 166 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -70 166 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 166 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 166 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 166 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 140 166 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 140 166 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 190 166 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 140 166 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 110 166 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 200 166 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 130 166 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 130 166 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 166 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 160 166 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 70 166 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 100 166 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 170 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 100 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 150 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 160 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 100 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 60 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 20 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -90 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 130 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 150 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 130 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkl8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkl8a.afm new file mode 100644 index 00000000..8b79ea71 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkl8a.afm @@ -0,0 +1,407 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Jan 21 16:15:53 1992 +Comment UniqueID 37833 +Comment VMusage 32321 39213 +FontName Bookman-Light +FullName ITC Bookman Light +FamilyName ITC Bookman +Weight Light +ItalicAngle 0 +IsFixedPitch false +FontBBox -188 -251 1266 908 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.004 +Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 484 +Ascender 717 +Descender -228 +StartCharMetrics 228 +C 32 ; WX 320 ; N space ; B 0 0 0 0 ; +C 33 ; WX 300 ; N exclam ; B 75 -8 219 698 ; +C 34 ; WX 380 ; N quotedbl ; B 56 458 323 698 ; +C 35 ; WX 620 ; N numbersign ; B 65 0 556 681 ; +C 36 ; WX 620 ; N dollar ; B 34 -109 593 791 ; +C 37 ; WX 900 ; N percent ; B 22 -8 873 698 ; +C 38 ; WX 800 ; N ampersand ; B 45 -17 787 698 ; +C 39 ; WX 220 ; N quoteright ; B 46 480 178 698 ; +C 40 ; WX 300 ; N parenleft ; B 76 -145 278 727 ; +C 41 ; WX 300 ; N parenright ; B 17 -146 219 727 ; +C 42 ; WX 440 ; N asterisk ; B 54 325 391 698 ; +C 43 ; WX 600 ; N plus ; B 51 8 555 513 ; +C 44 ; WX 320 ; N comma ; B 90 -114 223 114 ; +C 45 ; WX 400 ; N hyphen ; B 50 232 350 292 ; +C 46 ; WX 320 ; N period ; B 92 -8 220 123 ; +C 47 ; WX 600 ; N slash ; B 74 -149 532 717 ; +C 48 ; WX 620 ; N zero ; B 40 -17 586 698 ; +C 49 ; WX 620 ; N one ; B 160 0 501 681 ; +C 50 ; WX 620 ; N two ; B 42 0 576 698 ; +C 51 ; WX 620 ; N three ; B 40 -17 576 698 ; +C 52 ; WX 620 ; N four ; B 25 0 600 681 ; +C 53 ; WX 620 ; N five ; B 60 -17 584 717 ; +C 54 ; WX 620 ; N six ; B 45 -17 590 698 ; +C 55 ; WX 620 ; N seven ; B 60 0 586 681 ; +C 56 ; WX 620 ; N eight ; B 44 -17 583 698 ; +C 57 ; WX 620 ; N nine ; B 37 -17 576 698 ; +C 58 ; WX 320 ; N colon ; B 92 -8 220 494 ; +C 59 ; WX 320 ; N semicolon ; B 90 -114 223 494 ; +C 60 ; WX 600 ; N less ; B 49 -2 558 526 ; +C 61 ; WX 600 ; N equal ; B 51 126 555 398 ; +C 62 ; WX 600 ; N greater ; B 48 -2 557 526 ; +C 63 ; WX 540 ; N question ; B 27 -8 514 698 ; +C 64 ; WX 820 ; N at ; B 55 -17 755 698 ; +C 65 ; WX 680 ; N A ; B -37 0 714 681 ; +C 66 ; WX 740 ; N B ; B 31 0 702 681 ; +C 67 ; WX 740 ; N C ; B 44 -17 702 698 ; +C 68 ; WX 800 ; N D ; B 31 0 752 681 ; +C 69 ; WX 720 ; N E ; B 31 0 705 681 ; +C 70 ; WX 640 ; N F ; B 31 0 654 681 ; +C 71 ; WX 800 ; N G ; B 44 -17 778 698 ; +C 72 ; WX 800 ; N H ; B 31 0 769 681 ; +C 73 ; WX 340 ; N I ; B 31 0 301 681 ; +C 74 ; WX 600 ; N J ; B -23 -17 567 681 ; +C 75 ; WX 720 ; N K ; B 31 0 750 681 ; +C 76 ; WX 600 ; N L ; B 31 0 629 681 ; +C 77 ; WX 920 ; N M ; B 26 0 894 681 ; +C 78 ; WX 740 ; N N ; B 26 0 722 681 ; +C 79 ; WX 800 ; N O ; B 44 -17 758 698 ; +C 80 ; WX 620 ; N P ; B 31 0 613 681 ; +C 81 ; WX 820 ; N Q ; B 44 -189 769 698 ; +C 82 ; WX 720 ; N R ; B 31 0 757 681 ; +C 83 ; WX 660 ; N S ; B 28 -17 634 698 ; +C 84 ; WX 620 ; N T ; B -37 0 656 681 ; +C 85 ; WX 780 ; N U ; B 25 -17 754 681 ; +C 86 ; WX 700 ; N V ; B -30 0 725 681 ; +C 87 ; WX 960 ; N W ; B -30 0 984 681 ; +C 88 ; WX 720 ; N X ; B -30 0 755 681 ; +C 89 ; WX 640 ; N Y ; B -30 0 666 681 ; +C 90 ; WX 640 ; N Z ; B 10 0 656 681 ; +C 91 ; WX 300 ; N bracketleft ; B 92 -136 258 717 ; +C 92 ; WX 600 ; N backslash ; B 74 0 532 717 ; +C 93 ; WX 300 ; N bracketright ; B 41 -136 207 717 ; +C 94 ; WX 600 ; N asciicircum ; B 52 276 554 681 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 220 ; N quoteleft ; B 46 479 178 698 ; +C 97 ; WX 580 ; N a ; B 35 -8 587 494 ; +C 98 ; WX 620 ; N b ; B -2 -8 582 717 ; +C 99 ; WX 520 ; N c ; B 37 -8 498 494 ; +C 100 ; WX 620 ; N d ; B 37 -8 591 717 ; +C 101 ; WX 520 ; N e ; B 37 -8 491 494 ; +C 102 ; WX 320 ; N f ; B 20 0 414 734 ; L i fi ; L l fl ; +C 103 ; WX 540 ; N g ; B 17 -243 542 567 ; +C 104 ; WX 660 ; N h ; B 20 0 643 717 ; +C 105 ; WX 300 ; N i ; B 20 0 288 654 ; +C 106 ; WX 300 ; N j ; B -109 -251 214 654 ; +C 107 ; WX 620 ; N k ; B 20 0 628 717 ; +C 108 ; WX 300 ; N l ; B 20 0 286 717 ; +C 109 ; WX 940 ; N m ; B 17 0 928 494 ; +C 110 ; WX 660 ; N n ; B 20 0 649 494 ; +C 111 ; WX 560 ; N o ; B 37 -8 526 494 ; +C 112 ; WX 620 ; N p ; B 20 -228 583 494 ; +C 113 ; WX 580 ; N q ; B 37 -228 589 494 ; +C 114 ; WX 440 ; N r ; B 20 0 447 494 ; +C 115 ; WX 520 ; N s ; B 40 -8 487 494 ; +C 116 ; WX 380 ; N t ; B 20 -8 388 667 ; +C 117 ; WX 680 ; N u ; B 20 -8 653 484 ; +C 118 ; WX 520 ; N v ; B -23 0 534 484 ; +C 119 ; WX 780 ; N w ; B -19 0 804 484 ; +C 120 ; WX 560 ; N x ; B -16 0 576 484 ; +C 121 ; WX 540 ; N y ; B -23 -236 549 484 ; +C 122 ; WX 480 ; N z ; B 7 0 476 484 ; +C 123 ; WX 280 ; N braceleft ; B 21 -136 260 717 ; +C 124 ; WX 600 ; N bar ; B 264 -250 342 750 ; +C 125 ; WX 280 ; N braceright ; B 21 -136 260 717 ; +C 126 ; WX 600 ; N asciitilde ; B 52 173 556 352 ; +C 161 ; WX 300 ; N exclamdown ; B 75 -214 219 494 ; +C 162 ; WX 620 ; N cent ; B 116 20 511 651 ; +C 163 ; WX 620 ; N sterling ; B 8 -17 631 698 ; +C 164 ; WX 140 ; N fraction ; B -188 0 335 681 ; +C 165 ; WX 620 ; N yen ; B -22 0 647 681 ; +C 166 ; WX 620 ; N florin ; B -29 -155 633 749 ; +C 167 ; WX 520 ; N section ; B 33 -178 486 698 ; +C 168 ; WX 620 ; N currency ; B 58 89 563 591 ; +C 169 ; WX 220 ; N quotesingle ; B 67 458 153 698 ; +C 170 ; WX 400 ; N quotedblleft ; B 46 479 348 698 ; +C 171 ; WX 360 ; N guillemotleft ; B 51 89 312 437 ; +C 172 ; WX 240 ; N guilsinglleft ; B 51 89 189 437 ; +C 173 ; WX 240 ; N guilsinglright ; B 51 89 189 437 ; +C 174 ; WX 620 ; N fi ; B 20 0 608 734 ; +C 175 ; WX 620 ; N fl ; B 20 0 606 734 ; +C 177 ; WX 500 ; N endash ; B -15 232 515 292 ; +C 178 ; WX 540 ; N dagger ; B 79 -156 455 698 ; +C 179 ; WX 540 ; N daggerdbl ; B 79 -156 455 698 ; +C 180 ; WX 320 ; N periodcentered ; B 92 196 220 327 ; +C 182 ; WX 600 ; N paragraph ; B 14 0 577 681 ; +C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ; +C 184 ; WX 220 ; N quotesinglbase ; B 46 -108 178 110 ; +C 185 ; WX 400 ; N quotedblbase ; B 46 -108 348 110 ; +C 186 ; WX 400 ; N quotedblright ; B 46 480 348 698 ; +C 187 ; WX 360 ; N guillemotright ; B 51 89 312 437 ; +C 188 ; WX 1000 ; N ellipsis ; B 101 -8 898 123 ; +C 189 ; WX 1280 ; N perthousand ; B 22 -8 1266 698 ; +C 191 ; WX 540 ; N questiondown ; B 23 -217 510 494 ; +C 193 ; WX 340 ; N grave ; B 68 571 274 689 ; +C 194 ; WX 340 ; N acute ; B 68 571 274 689 ; +C 195 ; WX 420 ; N circumflex ; B 68 567 352 685 ; +C 196 ; WX 440 ; N tilde ; B 68 572 375 661 ; +C 197 ; WX 440 ; N macron ; B 68 587 364 635 ; +C 198 ; WX 460 ; N breve ; B 68 568 396 687 ; +C 199 ; WX 260 ; N dotaccent ; B 68 552 186 672 ; +C 200 ; WX 420 ; N dieresis ; B 68 552 349 674 ; +C 202 ; WX 320 ; N ring ; B 68 546 252 731 ; +C 203 ; WX 320 ; N cedilla ; B 68 -200 257 0 ; +C 205 ; WX 380 ; N hungarumlaut ; B 68 538 311 698 ; +C 206 ; WX 320 ; N ogonek ; B 68 -145 245 0 ; +C 207 ; WX 420 ; N caron ; B 68 554 352 672 ; +C 208 ; WX 1000 ; N emdash ; B -15 232 1015 292 ; +C 225 ; WX 1260 ; N AE ; B -36 0 1250 681 ; +C 227 ; WX 420 ; N ordfeminine ; B 49 395 393 698 ; +C 232 ; WX 600 ; N Lslash ; B 31 0 629 681 ; +C 233 ; WX 800 ; N Oslash ; B 44 -53 758 733 ; +C 234 ; WX 1240 ; N OE ; B 44 -17 1214 698 ; +C 235 ; WX 420 ; N ordmasculine ; B 56 394 361 698 ; +C 241 ; WX 860 ; N ae ; B 35 -8 832 494 ; +C 245 ; WX 300 ; N dotlessi ; B 20 0 288 484 ; +C 248 ; WX 320 ; N lslash ; B 20 0 291 717 ; +C 249 ; WX 560 ; N oslash ; B 37 -40 526 534 ; +C 250 ; WX 900 ; N oe ; B 37 -8 876 494 ; +C 251 ; WX 660 ; N germandbls ; B -109 -110 614 698 ; +C -1 ; WX 520 ; N ecircumflex ; B 37 -8 491 685 ; +C -1 ; WX 520 ; N edieresis ; B 37 -8 491 674 ; +C -1 ; WX 580 ; N aacute ; B 35 -8 587 689 ; +C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ; +C -1 ; WX 300 ; N icircumflex ; B 8 0 292 685 ; +C -1 ; WX 680 ; N udieresis ; B 20 -8 653 674 ; +C -1 ; WX 560 ; N ograve ; B 37 -8 526 689 ; +C -1 ; WX 680 ; N uacute ; B 20 -8 653 689 ; +C -1 ; WX 680 ; N ucircumflex ; B 20 -8 653 685 ; +C -1 ; WX 680 ; N Aacute ; B -37 0 714 866 ; +C -1 ; WX 300 ; N igrave ; B 20 0 288 689 ; +C -1 ; WX 340 ; N Icircumflex ; B 28 0 312 862 ; +C -1 ; WX 520 ; N ccedilla ; B 37 -200 498 494 ; +C -1 ; WX 580 ; N adieresis ; B 35 -8 587 674 ; +C -1 ; WX 720 ; N Ecircumflex ; B 31 0 705 862 ; +C -1 ; WX 520 ; N scaron ; B 40 -8 487 672 ; +C -1 ; WX 620 ; N thorn ; B 20 -228 583 717 ; +C -1 ; WX 980 ; N trademark ; B 34 277 930 681 ; +C -1 ; WX 520 ; N egrave ; B 37 -8 491 689 ; +C -1 ; WX 372 ; N threesuperior ; B 12 269 360 698 ; +C -1 ; WX 480 ; N zcaron ; B 7 0 476 672 ; +C -1 ; WX 580 ; N atilde ; B 35 -8 587 661 ; +C -1 ; WX 580 ; N aring ; B 35 -8 587 731 ; +C -1 ; WX 560 ; N ocircumflex ; B 37 -8 526 685 ; +C -1 ; WX 720 ; N Edieresis ; B 31 0 705 851 ; +C -1 ; WX 930 ; N threequarters ; B 52 0 889 691 ; +C -1 ; WX 540 ; N ydieresis ; B -23 -236 549 674 ; +C -1 ; WX 540 ; N yacute ; B -23 -236 549 689 ; +C -1 ; WX 300 ; N iacute ; B 20 0 288 689 ; +C -1 ; WX 680 ; N Acircumflex ; B -37 0 714 862 ; +C -1 ; WX 780 ; N Uacute ; B 25 -17 754 866 ; +C -1 ; WX 520 ; N eacute ; B 37 -8 491 689 ; +C -1 ; WX 800 ; N Ograve ; B 44 -17 758 866 ; +C -1 ; WX 580 ; N agrave ; B 35 -8 587 689 ; +C -1 ; WX 780 ; N Udieresis ; B 25 -17 754 851 ; +C -1 ; WX 580 ; N acircumflex ; B 35 -8 587 685 ; +C -1 ; WX 340 ; N Igrave ; B 31 0 301 866 ; +C -1 ; WX 372 ; N twosuperior ; B 20 279 367 698 ; +C -1 ; WX 780 ; N Ugrave ; B 25 -17 754 866 ; +C -1 ; WX 930 ; N onequarter ; B 80 0 869 681 ; +C -1 ; WX 780 ; N Ucircumflex ; B 25 -17 754 862 ; +C -1 ; WX 660 ; N Scaron ; B 28 -17 634 849 ; +C -1 ; WX 340 ; N Idieresis ; B 28 0 309 851 ; +C -1 ; WX 300 ; N idieresis ; B 8 0 289 674 ; +C -1 ; WX 720 ; N Egrave ; B 31 0 705 866 ; +C -1 ; WX 800 ; N Oacute ; B 44 -17 758 866 ; +C -1 ; WX 600 ; N divide ; B 51 10 555 514 ; +C -1 ; WX 680 ; N Atilde ; B -37 0 714 838 ; +C -1 ; WX 680 ; N Aring ; B -37 0 714 908 ; +C -1 ; WX 800 ; N Odieresis ; B 44 -17 758 851 ; +C -1 ; WX 680 ; N Adieresis ; B -37 0 714 851 ; +C -1 ; WX 740 ; N Ntilde ; B 26 0 722 838 ; +C -1 ; WX 640 ; N Zcaron ; B 10 0 656 849 ; +C -1 ; WX 620 ; N Thorn ; B 31 0 613 681 ; +C -1 ; WX 340 ; N Iacute ; B 31 0 301 866 ; +C -1 ; WX 600 ; N plusminus ; B 51 0 555 513 ; +C -1 ; WX 600 ; N multiply ; B 51 9 555 513 ; +C -1 ; WX 720 ; N Eacute ; B 31 0 705 866 ; +C -1 ; WX 640 ; N Ydieresis ; B -30 0 666 851 ; +C -1 ; WX 372 ; N onesuperior ; B 80 279 302 688 ; +C -1 ; WX 680 ; N ugrave ; B 20 -8 653 689 ; +C -1 ; WX 600 ; N logicalnot ; B 51 128 555 398 ; +C -1 ; WX 660 ; N ntilde ; B 20 0 649 661 ; +C -1 ; WX 800 ; N Otilde ; B 44 -17 758 838 ; +C -1 ; WX 560 ; N otilde ; B 37 -8 526 661 ; +C -1 ; WX 740 ; N Ccedilla ; B 44 -200 702 698 ; +C -1 ; WX 680 ; N Agrave ; B -37 0 714 866 ; +C -1 ; WX 930 ; N onehalf ; B 80 0 885 681 ; +C -1 ; WX 800 ; N Eth ; B 31 0 752 681 ; +C -1 ; WX 400 ; N degree ; B 50 398 350 698 ; +C -1 ; WX 640 ; N Yacute ; B -30 0 666 866 ; +C -1 ; WX 800 ; N Ocircumflex ; B 44 -17 758 862 ; +C -1 ; WX 560 ; N oacute ; B 37 -8 526 689 ; +C -1 ; WX 680 ; N mu ; B 20 -251 653 484 ; +C -1 ; WX 600 ; N minus ; B 51 224 555 300 ; +C -1 ; WX 560 ; N eth ; B 37 -8 526 734 ; +C -1 ; WX 560 ; N odieresis ; B 37 -8 526 674 ; +C -1 ; WX 740 ; N copyright ; B 24 -17 724 698 ; +C -1 ; WX 600 ; N brokenbar ; B 264 -175 342 675 ; +EndCharMetrics +StartKernData +StartKernPairs 82 + +KPX A y 32 +KPX A w 4 +KPX A v 7 +KPX A Y -35 +KPX A W -40 +KPX A V -56 +KPX A T 1 + +KPX F period -46 +KPX F comma -41 +KPX F A -21 + +KPX L y 79 +KPX L Y 13 +KPX L W 1 +KPX L V -4 +KPX L T 28 + +KPX P period -60 +KPX P comma -55 +KPX P A -8 + +KPX R y 59 +KPX R Y 26 +KPX R W 13 +KPX R V 8 +KPX R T 71 + +KPX T s 16 +KPX T r 38 +KPX T period -33 +KPX T o 15 +KPX T i 42 +KPX T hyphen 90 +KPX T e 13 +KPX T comma -28 +KPX T c 14 +KPX T a 17 +KPX T A 1 + +KPX V y 15 +KPX V u -38 +KPX V r -41 +KPX V period -40 +KPX V o -71 +KPX V i -20 +KPX V hyphen 11 +KPX V e -72 +KPX V comma -34 +KPX V a -69 +KPX V A -66 + +KPX W y 15 +KPX W u -38 +KPX W r -41 +KPX W period -40 +KPX W o -68 +KPX W i -20 +KPX W hyphen 11 +KPX W e -69 +KPX W comma -34 +KPX W a -66 +KPX W A -64 + +KPX Y v 15 +KPX Y u -38 +KPX Y q -55 +KPX Y period -40 +KPX Y p -31 +KPX Y o -57 +KPX Y i -37 +KPX Y hyphen 11 +KPX Y e -58 +KPX Y comma -34 +KPX Y a -54 +KPX Y A -53 + +KPX f f 29 + +KPX r q 9 +KPX r period -64 +KPX r o 8 +KPX r n 31 +KPX r m 31 +KPX r hyphen 70 +KPX r h -21 +KPX r g -4 +KPX r f 33 +KPX r e 7 +KPX r d 7 +KPX r comma -58 +KPX r c 7 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 130 177 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 140 177 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 180 177 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 177 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 220 177 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 150 177 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 177 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 177 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -40 177 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -40 177 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -20 177 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 150 177 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 260 177 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 190 177 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 177 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 177 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 177 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 177 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 177 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 190 177 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 177 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 110 177 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 110 177 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 130 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 70 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 50 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -60 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -60 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 110 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 70 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 50 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 130 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 130 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 170 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 100 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkli8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkli8a.afm new file mode 100644 index 00000000..419c319a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pbkli8a.afm @@ -0,0 +1,410 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Jan 21 16:12:06 1992 +Comment UniqueID 37830 +Comment VMusage 33139 40031 +FontName Bookman-LightItalic +FullName ITC Bookman Light Italic +FamilyName ITC Bookman +Weight Light +ItalicAngle -10 +IsFixedPitch false +FontBBox -228 -250 1269 883 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.004 +Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 494 +Ascender 717 +Descender -212 +StartCharMetrics 228 +C 32 ; WX 300 ; N space ; B 0 0 0 0 ; +C 33 ; WX 320 ; N exclam ; B 103 -8 342 698 ; +C 34 ; WX 360 ; N quotedbl ; B 107 468 402 698 ; +C 35 ; WX 620 ; N numbersign ; B 107 0 598 681 ; +C 36 ; WX 620 ; N dollar ; B 78 -85 619 762 ; +C 37 ; WX 800 ; N percent ; B 56 -8 811 691 ; +C 38 ; WX 820 ; N ampersand ; B 65 -18 848 698 ; +C 39 ; WX 280 ; N quoteright ; B 148 470 288 698 ; +C 40 ; WX 280 ; N parenleft ; B 96 -146 383 727 ; +C 41 ; WX 280 ; N parenright ; B -8 -146 279 727 ; +C 42 ; WX 440 ; N asterisk ; B 139 324 505 698 ; +C 43 ; WX 600 ; N plus ; B 91 43 595 548 ; +C 44 ; WX 300 ; N comma ; B 88 -115 227 112 ; +C 45 ; WX 320 ; N hyphen ; B 78 269 336 325 ; +C 46 ; WX 300 ; N period ; B 96 -8 231 127 ; +C 47 ; WX 600 ; N slash ; B 104 -149 562 717 ; +C 48 ; WX 620 ; N zero ; B 86 -17 646 698 ; +C 49 ; WX 620 ; N one ; B 154 0 500 681 ; +C 50 ; WX 620 ; N two ; B 66 0 636 698 ; +C 51 ; WX 620 ; N three ; B 55 -17 622 698 ; +C 52 ; WX 620 ; N four ; B 69 0 634 681 ; +C 53 ; WX 620 ; N five ; B 70 -17 614 681 ; +C 54 ; WX 620 ; N six ; B 89 -17 657 698 ; +C 55 ; WX 620 ; N seven ; B 143 0 672 681 ; +C 56 ; WX 620 ; N eight ; B 61 -17 655 698 ; +C 57 ; WX 620 ; N nine ; B 77 -17 649 698 ; +C 58 ; WX 300 ; N colon ; B 96 -8 292 494 ; +C 59 ; WX 300 ; N semicolon ; B 88 -114 292 494 ; +C 60 ; WX 600 ; N less ; B 79 33 588 561 ; +C 61 ; WX 600 ; N equal ; B 91 161 595 433 ; +C 62 ; WX 600 ; N greater ; B 93 33 602 561 ; +C 63 ; WX 540 ; N question ; B 114 -8 604 698 ; +C 64 ; WX 780 ; N at ; B 102 -17 802 698 ; +C 65 ; WX 700 ; N A ; B -25 0 720 681 ; +C 66 ; WX 720 ; N B ; B 21 0 746 681 ; +C 67 ; WX 720 ; N C ; B 88 -17 746 698 ; +C 68 ; WX 740 ; N D ; B 21 0 782 681 ; +C 69 ; WX 680 ; N E ; B 21 0 736 681 ; +C 70 ; WX 620 ; N F ; B 21 0 743 681 ; +C 71 ; WX 760 ; N G ; B 88 -17 813 698 ; +C 72 ; WX 800 ; N H ; B 21 0 888 681 ; +C 73 ; WX 320 ; N I ; B 21 0 412 681 ; +C 74 ; WX 560 ; N J ; B -2 -17 666 681 ; +C 75 ; WX 720 ; N K ; B 21 0 804 681 ; +C 76 ; WX 580 ; N L ; B 21 0 656 681 ; +C 77 ; WX 860 ; N M ; B 18 0 956 681 ; +C 78 ; WX 720 ; N N ; B 18 0 823 681 ; +C 79 ; WX 760 ; N O ; B 88 -17 799 698 ; +C 80 ; WX 600 ; N P ; B 21 0 681 681 ; +C 81 ; WX 780 ; N Q ; B 61 -191 812 698 ; +C 82 ; WX 700 ; N R ; B 21 0 736 681 ; +C 83 ; WX 640 ; N S ; B 61 -17 668 698 ; +C 84 ; WX 600 ; N T ; B 50 0 725 681 ; +C 85 ; WX 720 ; N U ; B 118 -17 842 681 ; +C 86 ; WX 680 ; N V ; B 87 0 815 681 ; +C 87 ; WX 960 ; N W ; B 87 0 1095 681 ; +C 88 ; WX 700 ; N X ; B -25 0 815 681 ; +C 89 ; WX 660 ; N Y ; B 87 0 809 681 ; +C 90 ; WX 580 ; N Z ; B 8 0 695 681 ; +C 91 ; WX 260 ; N bracketleft ; B 56 -136 351 717 ; +C 92 ; WX 600 ; N backslash ; B 84 0 542 717 ; +C 93 ; WX 260 ; N bracketright ; B 15 -136 309 717 ; +C 94 ; WX 600 ; N asciicircum ; B 97 276 599 681 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 280 ; N quoteleft ; B 191 470 330 698 ; +C 97 ; WX 620 ; N a ; B 71 -8 686 494 ; +C 98 ; WX 600 ; N b ; B 88 -8 621 717 ; +C 99 ; WX 480 ; N c ; B 65 -8 522 494 ; +C 100 ; WX 640 ; N d ; B 65 -8 695 717 ; +C 101 ; WX 540 ; N e ; B 65 -8 575 494 ; +C 102 ; WX 340 ; N f ; B -160 -218 557 725 ; L i fi ; L l fl ; +C 103 ; WX 560 ; N g ; B 4 -221 581 494 ; +C 104 ; WX 620 ; N h ; B 88 -8 689 717 ; +C 105 ; WX 280 ; N i ; B 88 -8 351 663 ; +C 106 ; WX 280 ; N j ; B -200 -221 308 663 ; +C 107 ; WX 600 ; N k ; B 88 -8 657 717 ; +C 108 ; WX 280 ; N l ; B 100 -8 342 717 ; +C 109 ; WX 880 ; N m ; B 88 -8 952 494 ; +C 110 ; WX 620 ; N n ; B 88 -8 673 494 ; +C 111 ; WX 540 ; N o ; B 65 -8 572 494 ; +C 112 ; WX 600 ; N p ; B -24 -212 620 494 ; +C 113 ; WX 560 ; N q ; B 65 -212 584 494 ; +C 114 ; WX 400 ; N r ; B 88 0 481 494 ; +C 115 ; WX 540 ; N s ; B 65 -8 547 494 ; +C 116 ; WX 340 ; N t ; B 88 -8 411 664 ; +C 117 ; WX 620 ; N u ; B 88 -8 686 484 ; +C 118 ; WX 540 ; N v ; B 88 -8 562 494 ; +C 119 ; WX 880 ; N w ; B 88 -8 893 494 ; +C 120 ; WX 540 ; N x ; B 9 -8 626 494 ; +C 121 ; WX 600 ; N y ; B 60 -221 609 484 ; +C 122 ; WX 520 ; N z ; B 38 -8 561 494 ; +C 123 ; WX 360 ; N braceleft ; B 122 -191 442 717 ; +C 124 ; WX 600 ; N bar ; B 294 -250 372 750 ; +C 125 ; WX 380 ; N braceright ; B 13 -191 333 717 ; +C 126 ; WX 600 ; N asciitilde ; B 91 207 595 386 ; +C 161 ; WX 320 ; N exclamdown ; B 73 -213 301 494 ; +C 162 ; WX 620 ; N cent ; B 148 -29 596 715 ; +C 163 ; WX 620 ; N sterling ; B 4 -17 702 698 ; +C 164 ; WX 20 ; N fraction ; B -228 0 323 681 ; +C 165 ; WX 620 ; N yen ; B 71 0 735 681 ; +C 166 ; WX 620 ; N florin ; B -26 -218 692 725 ; +C 167 ; WX 620 ; N section ; B 38 -178 638 698 ; +C 168 ; WX 620 ; N currency ; B 100 89 605 591 ; +C 169 ; WX 200 ; N quotesingle ; B 99 473 247 698 ; +C 170 ; WX 440 ; N quotedblleft ; B 191 470 493 698 ; +C 171 ; WX 300 ; N guillemotleft ; B 70 129 313 434 ; +C 172 ; WX 180 ; N guilsinglleft ; B 75 129 208 434 ; +C 173 ; WX 180 ; N guilsinglright ; B 70 129 203 434 ; +C 174 ; WX 640 ; N fi ; B -159 -222 709 725 ; +C 175 ; WX 660 ; N fl ; B -159 -218 713 725 ; +C 177 ; WX 500 ; N endash ; B 33 269 561 325 ; +C 178 ; WX 620 ; N dagger ; B 192 -130 570 698 ; +C 179 ; WX 620 ; N daggerdbl ; B 144 -122 566 698 ; +C 180 ; WX 300 ; N periodcentered ; B 137 229 272 364 ; +C 182 ; WX 620 ; N paragraph ; B 112 0 718 681 ; +C 183 ; WX 460 ; N bullet ; B 100 170 444 511 ; +C 184 ; WX 320 ; N quotesinglbase ; B 87 -114 226 113 ; +C 185 ; WX 480 ; N quotedblbase ; B 87 -114 390 113 ; +C 186 ; WX 440 ; N quotedblright ; B 148 470 451 698 ; +C 187 ; WX 300 ; N guillemotright ; B 60 129 303 434 ; +C 188 ; WX 1000 ; N ellipsis ; B 99 -8 900 127 ; +C 189 ; WX 1180 ; N perthousand ; B 56 -8 1199 691 ; +C 191 ; WX 540 ; N questiondown ; B 18 -212 508 494 ; +C 193 ; WX 340 ; N grave ; B 182 551 377 706 ; +C 194 ; WX 320 ; N acute ; B 178 551 373 706 ; +C 195 ; WX 440 ; N circumflex ; B 176 571 479 685 ; +C 196 ; WX 440 ; N tilde ; B 180 586 488 671 ; +C 197 ; WX 440 ; N macron ; B 178 599 484 658 ; +C 198 ; WX 440 ; N breve ; B 191 577 500 680 ; +C 199 ; WX 260 ; N dotaccent ; B 169 543 290 664 ; +C 200 ; WX 420 ; N dieresis ; B 185 569 467 688 ; +C 202 ; WX 300 ; N ring ; B 178 551 334 706 ; +C 203 ; WX 320 ; N cedilla ; B 45 -178 240 0 ; +C 205 ; WX 340 ; N hungarumlaut ; B 167 547 402 738 ; +C 206 ; WX 260 ; N ogonek ; B 51 -173 184 0 ; +C 207 ; WX 440 ; N caron ; B 178 571 481 684 ; +C 208 ; WX 1000 ; N emdash ; B 33 269 1061 325 ; +C 225 ; WX 1220 ; N AE ; B -45 0 1269 681 ; +C 227 ; WX 440 ; N ordfeminine ; B 130 396 513 698 ; +C 232 ; WX 580 ; N Lslash ; B 21 0 656 681 ; +C 233 ; WX 760 ; N Oslash ; B 88 -95 799 777 ; +C 234 ; WX 1180 ; N OE ; B 88 -17 1237 698 ; +C 235 ; WX 400 ; N ordmasculine ; B 139 396 455 698 ; +C 241 ; WX 880 ; N ae ; B 71 -8 918 494 ; +C 245 ; WX 280 ; N dotlessi ; B 88 -8 351 484 ; +C 248 ; WX 340 ; N lslash ; B 50 -8 398 717 ; +C 249 ; WX 540 ; N oslash ; B 65 -49 571 532 ; +C 250 ; WX 900 ; N oe ; B 65 -8 948 494 ; +C 251 ; WX 620 ; N germandbls ; B -121 -111 653 698 ; +C -1 ; WX 540 ; N ecircumflex ; B 65 -8 575 685 ; +C -1 ; WX 540 ; N edieresis ; B 65 -8 575 688 ; +C -1 ; WX 620 ; N aacute ; B 71 -8 686 706 ; +C -1 ; WX 740 ; N registered ; B 84 -17 784 698 ; +C -1 ; WX 280 ; N icircumflex ; B 76 -8 379 685 ; +C -1 ; WX 620 ; N udieresis ; B 88 -8 686 688 ; +C -1 ; WX 540 ; N ograve ; B 65 -8 572 706 ; +C -1 ; WX 620 ; N uacute ; B 88 -8 686 706 ; +C -1 ; WX 620 ; N ucircumflex ; B 88 -8 686 685 ; +C -1 ; WX 700 ; N Aacute ; B -25 0 720 883 ; +C -1 ; WX 280 ; N igrave ; B 88 -8 351 706 ; +C -1 ; WX 320 ; N Icircumflex ; B 21 0 449 862 ; +C -1 ; WX 480 ; N ccedilla ; B 65 -178 522 494 ; +C -1 ; WX 620 ; N adieresis ; B 71 -8 686 688 ; +C -1 ; WX 680 ; N Ecircumflex ; B 21 0 736 862 ; +C -1 ; WX 540 ; N scaron ; B 65 -8 547 684 ; +C -1 ; WX 600 ; N thorn ; B -24 -212 620 717 ; +C -1 ; WX 980 ; N trademark ; B 69 277 965 681 ; +C -1 ; WX 540 ; N egrave ; B 65 -8 575 706 ; +C -1 ; WX 372 ; N threesuperior ; B 70 269 439 698 ; +C -1 ; WX 520 ; N zcaron ; B 38 -8 561 684 ; +C -1 ; WX 620 ; N atilde ; B 71 -8 686 671 ; +C -1 ; WX 620 ; N aring ; B 71 -8 686 706 ; +C -1 ; WX 540 ; N ocircumflex ; B 65 -8 572 685 ; +C -1 ; WX 680 ; N Edieresis ; B 21 0 736 865 ; +C -1 ; WX 930 ; N threequarters ; B 99 0 913 691 ; +C -1 ; WX 600 ; N ydieresis ; B 60 -221 609 688 ; +C -1 ; WX 600 ; N yacute ; B 60 -221 609 706 ; +C -1 ; WX 280 ; N iacute ; B 88 -8 351 706 ; +C -1 ; WX 700 ; N Acircumflex ; B -25 0 720 862 ; +C -1 ; WX 720 ; N Uacute ; B 118 -17 842 883 ; +C -1 ; WX 540 ; N eacute ; B 65 -8 575 706 ; +C -1 ; WX 760 ; N Ograve ; B 88 -17 799 883 ; +C -1 ; WX 620 ; N agrave ; B 71 -8 686 706 ; +C -1 ; WX 720 ; N Udieresis ; B 118 -17 842 865 ; +C -1 ; WX 620 ; N acircumflex ; B 71 -8 686 685 ; +C -1 ; WX 320 ; N Igrave ; B 21 0 412 883 ; +C -1 ; WX 372 ; N twosuperior ; B 68 279 439 698 ; +C -1 ; WX 720 ; N Ugrave ; B 118 -17 842 883 ; +C -1 ; WX 930 ; N onequarter ; B 91 0 913 681 ; +C -1 ; WX 720 ; N Ucircumflex ; B 118 -17 842 862 ; +C -1 ; WX 640 ; N Scaron ; B 61 -17 668 861 ; +C -1 ; WX 320 ; N Idieresis ; B 21 0 447 865 ; +C -1 ; WX 280 ; N idieresis ; B 88 -8 377 688 ; +C -1 ; WX 680 ; N Egrave ; B 21 0 736 883 ; +C -1 ; WX 760 ; N Oacute ; B 88 -17 799 883 ; +C -1 ; WX 600 ; N divide ; B 91 46 595 548 ; +C -1 ; WX 700 ; N Atilde ; B -25 0 720 848 ; +C -1 ; WX 700 ; N Aring ; B -25 0 720 883 ; +C -1 ; WX 760 ; N Odieresis ; B 88 -17 799 865 ; +C -1 ; WX 700 ; N Adieresis ; B -25 0 720 865 ; +C -1 ; WX 720 ; N Ntilde ; B 18 0 823 848 ; +C -1 ; WX 580 ; N Zcaron ; B 8 0 695 861 ; +C -1 ; WX 600 ; N Thorn ; B 21 0 656 681 ; +C -1 ; WX 320 ; N Iacute ; B 21 0 412 883 ; +C -1 ; WX 600 ; N plusminus ; B 91 0 595 548 ; +C -1 ; WX 600 ; N multiply ; B 91 44 595 548 ; +C -1 ; WX 680 ; N Eacute ; B 21 0 736 883 ; +C -1 ; WX 660 ; N Ydieresis ; B 87 0 809 865 ; +C -1 ; WX 372 ; N onesuperior ; B 114 279 339 688 ; +C -1 ; WX 620 ; N ugrave ; B 88 -8 686 706 ; +C -1 ; WX 600 ; N logicalnot ; B 91 163 595 433 ; +C -1 ; WX 620 ; N ntilde ; B 88 -8 673 671 ; +C -1 ; WX 760 ; N Otilde ; B 88 -17 799 848 ; +C -1 ; WX 540 ; N otilde ; B 65 -8 572 671 ; +C -1 ; WX 720 ; N Ccedilla ; B 88 -178 746 698 ; +C -1 ; WX 700 ; N Agrave ; B -25 0 720 883 ; +C -1 ; WX 930 ; N onehalf ; B 91 0 925 681 ; +C -1 ; WX 740 ; N Eth ; B 21 0 782 681 ; +C -1 ; WX 400 ; N degree ; B 120 398 420 698 ; +C -1 ; WX 660 ; N Yacute ; B 87 0 809 883 ; +C -1 ; WX 760 ; N Ocircumflex ; B 88 -17 799 862 ; +C -1 ; WX 540 ; N oacute ; B 65 -8 572 706 ; +C -1 ; WX 620 ; N mu ; B 53 -221 686 484 ; +C -1 ; WX 600 ; N minus ; B 91 259 595 335 ; +C -1 ; WX 540 ; N eth ; B 65 -8 642 725 ; +C -1 ; WX 540 ; N odieresis ; B 65 -8 572 688 ; +C -1 ; WX 740 ; N copyright ; B 84 -17 784 698 ; +C -1 ; WX 600 ; N brokenbar ; B 294 -175 372 675 ; +EndCharMetrics +StartKernData +StartKernPairs 85 + +KPX A Y -62 +KPX A W -73 +KPX A V -78 +KPX A T -5 + +KPX F period -97 +KPX F comma -98 +KPX F A -16 + +KPX L y 20 +KPX L Y 7 +KPX L W 9 +KPX L V 4 + +KPX P period -105 +KPX P comma -106 +KPX P A -30 + +KPX R Y 11 +KPX R W 2 +KPX R V 2 +KPX R T 65 + +KPX T semicolon 48 +KPX T s -7 +KPX T r 67 +KPX T period -78 +KPX T o 14 +KPX T i 71 +KPX T hyphen 20 +KPX T e 10 +KPX T comma -79 +KPX T colon 48 +KPX T c 16 +KPX T a 9 +KPX T A -14 + +KPX V y -14 +KPX V u -10 +KPX V semicolon -44 +KPX V r -20 +KPX V period -100 +KPX V o -70 +KPX V i 3 +KPX V hyphen 20 +KPX V e -70 +KPX V comma -109 +KPX V colon -35 +KPX V a -70 +KPX V A -70 + +KPX W y -14 +KPX W u -20 +KPX W semicolon -42 +KPX W r -30 +KPX W period -100 +KPX W o -60 +KPX W i 3 +KPX W hyphen 20 +KPX W e -60 +KPX W comma -109 +KPX W colon -35 +KPX W a -60 +KPX W A -60 + +KPX Y v -19 +KPX Y u -31 +KPX Y semicolon -40 +KPX Y q -72 +KPX Y period -100 +KPX Y p -37 +KPX Y o -75 +KPX Y i -11 +KPX Y hyphen 20 +KPX Y e -78 +KPX Y comma -109 +KPX Y colon -35 +KPX Y a -79 +KPX Y A -82 + +KPX f f -19 + +KPX r q -14 +KPX r period -134 +KPX r o -10 +KPX r n 38 +KPX r m 37 +KPX r hyphen 20 +KPX r h -20 +KPX r g -3 +KPX r f -9 +KPX r e -15 +KPX r d -9 +KPX r comma -143 +KPX r c -8 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 140 177 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 177 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 220 177 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 177 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 210 177 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 140 177 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 150 177 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 30 177 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 177 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -20 177 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -30 177 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 177 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 177 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 200 177 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 177 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 190 177 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 100 177 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 230 177 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 170 177 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 177 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 200 177 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 140 177 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 177 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 70 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 110 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 140 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 60 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 30 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 80 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -40 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -100 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -60 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 80 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 20 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 80 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 30 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 120 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 60 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 70 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 110 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 140 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 70 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 20 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrb8a.afm new file mode 100644 index 00000000..baf3a515 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrb8a.afm @@ -0,0 +1,344 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Tue Sep 17 14:02:41 1991 +Comment UniqueID 36384 +Comment VMusage 31992 40360 +FontName Courier-Bold +FullName Courier Bold +FamilyName Courier +Weight Bold +ItalicAngle 0 +IsFixedPitch true +FontBBox -113 -250 749 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.004 +Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 626 +Descender -142 +StartCharMetrics 260 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; +C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; +C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; +C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; +C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; +C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; +C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ; +C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; +C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; +C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; +C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; +C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; +C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; +C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; +C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; +C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; +C 49 ; WX 600 ; N one ; B 81 0 539 616 ; +C 50 ; WX 600 ; N two ; B 61 0 499 616 ; +C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; +C 52 ; WX 600 ; N four ; B 53 0 507 616 ; +C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; +C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; +C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; +C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; +C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; +C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; +C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; +C 60 ; WX 600 ; N less ; B 66 15 523 501 ; +C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; +C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; +C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; +C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; +C 65 ; WX 600 ; N A ; B -9 0 609 562 ; +C 66 ; WX 600 ; N B ; B 30 0 573 562 ; +C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; +C 68 ; WX 600 ; N D ; B 30 0 594 562 ; +C 69 ; WX 600 ; N E ; B 25 0 560 562 ; +C 70 ; WX 600 ; N F ; B 39 0 570 562 ; +C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; +C 72 ; WX 600 ; N H ; B 20 0 580 562 ; +C 73 ; WX 600 ; N I ; B 77 0 523 562 ; +C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; +C 75 ; WX 600 ; N K ; B 21 0 599 562 ; +C 76 ; WX 600 ; N L ; B 39 0 578 562 ; +C 77 ; WX 600 ; N M ; B -2 0 602 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; +C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; +C 80 ; WX 600 ; N P ; B 48 0 559 562 ; +C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; +C 82 ; WX 600 ; N R ; B 24 0 599 562 ; +C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; +C 84 ; WX 600 ; N T ; B 21 0 579 562 ; +C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; +C 86 ; WX 600 ; N V ; B -13 0 613 562 ; +C 87 ; WX 600 ; N W ; B -18 0 618 562 ; +C 88 ; WX 600 ; N X ; B 12 0 588 562 ; +C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; +C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; +C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; +C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; +C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; +C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; +C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; +C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; +C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; +C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; +C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; +C 104 ; WX 600 ; N h ; B 5 0 592 626 ; +C 105 ; WX 600 ; N i ; B 77 0 523 658 ; +C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; +C 107 ; WX 600 ; N k ; B 20 0 585 626 ; +C 108 ; WX 600 ; N l ; B 77 0 523 626 ; +C 109 ; WX 600 ; N m ; B -22 0 626 454 ; +C 110 ; WX 600 ; N n ; B 18 0 592 454 ; +C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; +C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; +C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; +C 114 ; WX 600 ; N r ; B 47 0 580 454 ; +C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; +C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; +C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; +C 118 ; WX 600 ; N v ; B -1 0 601 439 ; +C 119 ; WX 600 ; N w ; B -18 0 618 439 ; +C 120 ; WX 600 ; N x ; B 6 0 594 439 ; +C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; +C 122 ; WX 600 ; N z ; B 81 0 520 439 ; +C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; +C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; +C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; +C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; +C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; +C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; +C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; +C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ; +C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; +C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ; +C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; +C 168 ; WX 600 ; N currency ; B 54 49 546 517 ; +C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 593 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 593 626 ; +C 177 ; WX 600 ; N endash ; B 65 203 535 313 ; +C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; +C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; +C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; +C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; +C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; +C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; +C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; +C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; +C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; +C 193 ; WX 600 ; N grave ; B 132 508 395 661 ; +C 194 ; WX 600 ; N acute ; B 205 508 468 661 ; +C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ; +C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ; +C 197 ; WX 600 ; N macron ; B 88 505 512 585 ; +C 198 ; WX 600 ; N breve ; B 83 468 517 631 ; +C 199 ; WX 600 ; N dotaccent ; B 230 485 370 625 ; +C 200 ; WX 600 ; N dieresis ; B 128 485 472 625 ; +C 202 ; WX 600 ; N ring ; B 198 481 402 678 ; +C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; +C 206 ; WX 600 ; N ogonek ; B 169 -199 367 0 ; +C 207 ; WX 600 ; N caron ; B 103 493 497 667 ; +C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 602 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ; +C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; +C 234 ; WX 600 ; N OE ; B -25 0 595 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; +C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ; +C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ; +C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; +C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 748 ; +C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; +C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; +C -1 ; WX 600 ; N merge ; B 137 -15 464 487 ; +C -1 ; WX 600 ; N degree ; B 86 243 474 616 ; +C -1 ; WX 600 ; N dectab ; B 8 0 592 320 ; +C -1 ; WX 600 ; N ll ; B -12 0 600 626 ; +C -1 ; WX 600 ; N IJ ; B -8 -18 622 562 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ; +C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; +C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; +C -1 ; WX 600 ; N left ; B 65 44 535 371 ; +C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; +C -1 ; WX 600 ; N up ; B 136 0 463 447 ; +C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ; +C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; +C -1 ; WX 600 ; N tab ; B 19 0 581 562 ; +C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; +C -1 ; WX 600 ; N divide ; B 71 16 529 500 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; +C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ; +C -1 ; WX 600 ; N down ; B 137 -15 464 439 ; +C -1 ; WX 600 ; N center ; B 40 14 560 580 ; +C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; +C -1 ; WX 600 ; N ij ; B 6 -146 574 658 ; +C -1 ; WX 600 ; N edieresis ; B 40 -15 563 625 ; +C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ; +C -1 ; WX 600 ; N odieresis ; B 30 -15 570 625 ; +C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ; +C -1 ; WX 600 ; N prescription ; B 24 -15 599 562 ; +C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ; +C -1 ; WX 600 ; N largebullet ; B 248 229 352 333 ; +C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; +C -1 ; WX 600 ; N notegraphic ; B 77 -15 523 572 ; +C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 748 ; +C -1 ; WX 600 ; N Gcaron ; B 22 -18 594 790 ; +C -1 ; WX 600 ; N arrowdown ; B 144 -15 456 608 ; +C -1 ; WX 600 ; N format ; B 5 -146 115 601 ; +C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 523 748 ; +C -1 ; WX 600 ; N adieresis ; B 35 -15 570 625 ; +C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; +C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ; +C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; +C -1 ; WX 600 ; N LL ; B -45 0 645 562 ; +C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; +C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; +C -1 ; WX 600 ; N Idot ; B 77 0 523 748 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ; +C -1 ; WX 600 ; N indent ; B 65 45 535 372 ; +C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ; +C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ; +C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ; +C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ; +C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; +C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ; +C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ; +C -1 ; WX 600 ; N lira ; B 72 -28 558 611 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ; +C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 748 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 625 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 523 625 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 609 748 ; +C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ; +C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ; +C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ; +C -1 ; WX 600 ; N return ; B 19 0 581 562 ; +C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ; +C -1 ; WX 600 ; N square ; B 19 0 581 562 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N stop ; B 19 0 581 562 ; +C -1 ; WX 600 ; N udieresis ; B -1 -15 569 625 ; +C -1 ; WX 600 ; N arrowup ; B 144 3 456 626 ; +C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 560 748 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ; +C -1 ; WX 600 ; N arrowboth ; B -24 143 624 455 ; +C -1 ; WX 600 ; N gcaron ; B 30 -146 580 667 ; +C -1 ; WX 600 ; N arrowleft ; B -24 143 634 455 ; +C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; +C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; +C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; +C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ; +C -1 ; WX 600 ; N arrowright ; B -34 143 624 455 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ; +C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ; +C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ; +C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ; +C -1 ; WX 600 ; N icircumflex ; B 63 0 523 657 ; +EndCharMetrics +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 30 123 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 123 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -20 123 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave -50 123 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring -10 123 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde -30 123 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 123 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 123 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 123 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 123 ; +CC Gcaron 2 ; PCC G 0 0 ; PCC caron 10 123 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 123 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 123 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 123 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 123 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 123 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 123 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 123 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 123 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 123 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 123 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 123 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 123 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 123 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 123 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 123 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 123 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 123 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 123 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; +CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm new file mode 100644 index 00000000..6e2c7422 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm @@ -0,0 +1,344 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Tue Sep 17 14:13:24 1991 +Comment UniqueID 36389 +Comment VMusage 10055 54684 +FontName Courier-BoldOblique +FullName Courier Bold Oblique +FamilyName Courier +Weight Bold +ItalicAngle -12 +IsFixedPitch true +FontBBox -56 -250 868 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.004 +Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 626 +Descender -142 +StartCharMetrics 260 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 216 -15 495 572 ; +C 34 ; WX 600 ; N quotedbl ; B 212 277 584 562 ; +C 35 ; WX 600 ; N numbersign ; B 88 -45 640 651 ; +C 36 ; WX 600 ; N dollar ; B 87 -126 629 666 ; +C 37 ; WX 600 ; N percent ; B 102 -15 624 616 ; +C 38 ; WX 600 ; N ampersand ; B 62 -15 594 543 ; +C 39 ; WX 600 ; N quoteright ; B 230 277 542 562 ; +C 40 ; WX 600 ; N parenleft ; B 266 -102 592 616 ; +C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; +C 42 ; WX 600 ; N asterisk ; B 179 219 597 601 ; +C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; +C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; +C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; +C 46 ; WX 600 ; N period ; B 207 -15 426 171 ; +C 47 ; WX 600 ; N slash ; B 91 -77 626 626 ; +C 48 ; WX 600 ; N zero ; B 136 -15 592 616 ; +C 49 ; WX 600 ; N one ; B 93 0 561 616 ; +C 50 ; WX 600 ; N two ; B 61 0 593 616 ; +C 51 ; WX 600 ; N three ; B 72 -15 571 616 ; +C 52 ; WX 600 ; N four ; B 82 0 558 616 ; +C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; +C 54 ; WX 600 ; N six ; B 136 -15 652 616 ; +C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; +C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; +C 57 ; WX 600 ; N nine ; B 76 -15 592 616 ; +C 58 ; WX 600 ; N colon ; B 206 -15 479 425 ; +C 59 ; WX 600 ; N semicolon ; B 99 -111 480 425 ; +C 60 ; WX 600 ; N less ; B 121 15 612 501 ; +C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; +C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; +C 63 ; WX 600 ; N question ; B 183 -14 591 580 ; +C 64 ; WX 600 ; N at ; B 66 -15 641 616 ; +C 65 ; WX 600 ; N A ; B -9 0 631 562 ; +C 66 ; WX 600 ; N B ; B 30 0 629 562 ; +C 67 ; WX 600 ; N C ; B 75 -18 674 580 ; +C 68 ; WX 600 ; N D ; B 30 0 664 562 ; +C 69 ; WX 600 ; N E ; B 25 0 669 562 ; +C 70 ; WX 600 ; N F ; B 39 0 683 562 ; +C 71 ; WX 600 ; N G ; B 75 -18 674 580 ; +C 72 ; WX 600 ; N H ; B 20 0 699 562 ; +C 73 ; WX 600 ; N I ; B 77 0 642 562 ; +C 74 ; WX 600 ; N J ; B 59 -18 720 562 ; +C 75 ; WX 600 ; N K ; B 21 0 691 562 ; +C 76 ; WX 600 ; N L ; B 39 0 635 562 ; +C 77 ; WX 600 ; N M ; B -2 0 721 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 729 562 ; +C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; +C 80 ; WX 600 ; N P ; B 48 0 642 562 ; +C 81 ; WX 600 ; N Q ; B 84 -138 636 580 ; +C 82 ; WX 600 ; N R ; B 24 0 617 562 ; +C 83 ; WX 600 ; N S ; B 54 -22 672 582 ; +C 84 ; WX 600 ; N T ; B 86 0 678 562 ; +C 85 ; WX 600 ; N U ; B 101 -18 715 562 ; +C 86 ; WX 600 ; N V ; B 84 0 732 562 ; +C 87 ; WX 600 ; N W ; B 84 0 737 562 ; +C 88 ; WX 600 ; N X ; B 12 0 689 562 ; +C 89 ; WX 600 ; N Y ; B 109 0 708 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 636 562 ; +C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; +C 92 ; WX 600 ; N backslash ; B 223 -77 496 626 ; +C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; +C 94 ; WX 600 ; N asciicircum ; B 171 250 555 616 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; +C 97 ; WX 600 ; N a ; B 62 -15 592 454 ; +C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; +C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; +C 100 ; WX 600 ; N d ; B 61 -15 644 626 ; +C 101 ; WX 600 ; N e ; B 81 -15 604 454 ; +C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 41 -146 673 454 ; +C 104 ; WX 600 ; N h ; B 18 0 614 626 ; +C 105 ; WX 600 ; N i ; B 77 0 545 658 ; +C 106 ; WX 600 ; N j ; B 37 -146 580 658 ; +C 107 ; WX 600 ; N k ; B 33 0 642 626 ; +C 108 ; WX 600 ; N l ; B 77 0 545 626 ; +C 109 ; WX 600 ; N m ; B -22 0 648 454 ; +C 110 ; WX 600 ; N n ; B 18 0 614 454 ; +C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; +C 112 ; WX 600 ; N p ; B -31 -142 622 454 ; +C 113 ; WX 600 ; N q ; B 61 -142 684 454 ; +C 114 ; WX 600 ; N r ; B 47 0 654 454 ; +C 115 ; WX 600 ; N s ; B 67 -17 607 459 ; +C 116 ; WX 600 ; N t ; B 118 -15 566 562 ; +C 117 ; WX 600 ; N u ; B 70 -15 591 439 ; +C 118 ; WX 600 ; N v ; B 70 0 694 439 ; +C 119 ; WX 600 ; N w ; B 53 0 711 439 ; +C 120 ; WX 600 ; N x ; B 6 0 670 439 ; +C 121 ; WX 600 ; N y ; B -20 -142 694 439 ; +C 122 ; WX 600 ; N z ; B 81 0 613 439 ; +C 123 ; WX 600 ; N braceleft ; B 204 -102 595 616 ; +C 124 ; WX 600 ; N bar ; B 202 -250 504 750 ; +C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; +C 126 ; WX 600 ; N asciitilde ; B 120 153 589 356 ; +C 161 ; WX 600 ; N exclamdown ; B 197 -146 477 449 ; +C 162 ; WX 600 ; N cent ; B 121 -49 604 614 ; +C 163 ; WX 600 ; N sterling ; B 107 -28 650 611 ; +C 164 ; WX 600 ; N fraction ; B 22 -60 707 661 ; +C 165 ; WX 600 ; N yen ; B 98 0 709 562 ; +C 166 ; WX 600 ; N florin ; B -56 -131 701 616 ; +C 167 ; WX 600 ; N section ; B 74 -70 619 580 ; +C 168 ; WX 600 ; N currency ; B 77 49 643 517 ; +C 169 ; WX 600 ; N quotesingle ; B 304 277 492 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 63 70 638 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 196 70 544 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 166 70 514 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 643 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 643 626 ; +C 177 ; WX 600 ; N endash ; B 108 203 602 313 ; +C 178 ; WX 600 ; N dagger ; B 176 -70 586 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 122 -70 586 580 ; +C 180 ; WX 600 ; N periodcentered ; B 249 165 461 351 ; +C 182 ; WX 600 ; N paragraph ; B 61 -70 699 580 ; +C 183 ; WX 600 ; N bullet ; B 197 132 523 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 145 -142 457 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 35 -142 559 143 ; +C 186 ; WX 600 ; N quotedblright ; B 120 277 644 562 ; +C 187 ; WX 600 ; N guillemotright ; B 72 70 647 446 ; +C 188 ; WX 600 ; N ellipsis ; B 35 -15 586 116 ; +C 189 ; WX 600 ; N perthousand ; B -44 -15 742 616 ; +C 191 ; WX 600 ; N questiondown ; B 101 -146 509 449 ; +C 193 ; WX 600 ; N grave ; B 272 508 503 661 ; +C 194 ; WX 600 ; N acute ; B 313 508 608 661 ; +C 195 ; WX 600 ; N circumflex ; B 212 483 606 657 ; +C 196 ; WX 600 ; N tilde ; B 200 493 642 636 ; +C 197 ; WX 600 ; N macron ; B 195 505 636 585 ; +C 198 ; WX 600 ; N breve ; B 217 468 651 631 ; +C 199 ; WX 600 ; N dotaccent ; B 346 485 490 625 ; +C 200 ; WX 600 ; N dieresis ; B 244 485 592 625 ; +C 202 ; WX 600 ; N ring ; B 319 481 528 678 ; +C 203 ; WX 600 ; N cedilla ; B 169 -206 367 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 172 488 728 661 ; +C 206 ; WX 600 ; N ogonek ; B 144 -199 350 0 ; +C 207 ; WX 600 ; N caron ; B 238 493 632 667 ; +C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 707 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 189 196 526 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 635 562 ; +C 233 ; WX 600 ; N Oslash ; B 48 -22 672 584 ; +C 234 ; WX 600 ; N OE ; B 26 0 700 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 189 196 542 580 ; +C 241 ; WX 600 ; N ae ; B 21 -15 651 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 545 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 578 626 ; +C 249 ; WX 600 ; N oslash ; B 55 -24 637 463 ; +C 250 ; WX 600 ; N oe ; B 19 -15 661 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 628 626 ; +C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 748 ; +C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; +C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; +C -1 ; WX 600 ; N merge ; B 168 -15 533 487 ; +C -1 ; WX 600 ; N degree ; B 173 243 569 616 ; +C -1 ; WX 600 ; N dectab ; B 8 0 615 320 ; +C -1 ; WX 600 ; N ll ; B 1 0 653 626 ; +C -1 ; WX 600 ; N IJ ; B -8 -18 741 562 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 669 784 ; +C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; +C -1 ; WX 600 ; N ucircumflex ; B 70 -15 591 657 ; +C -1 ; WX 600 ; N left ; B 109 44 589 371 ; +C -1 ; WX 600 ; N threesuperior ; B 193 222 525 616 ; +C -1 ; WX 600 ; N up ; B 196 0 523 447 ; +C -1 ; WX 600 ; N multiply ; B 105 39 606 478 ; +C -1 ; WX 600 ; N Scaron ; B 54 -22 672 790 ; +C -1 ; WX 600 ; N tab ; B 19 0 641 562 ; +C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 715 780 ; +C -1 ; WX 600 ; N divide ; B 114 16 596 500 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 631 780 ; +C -1 ; WX 600 ; N eacute ; B 81 -15 608 661 ; +C -1 ; WX 600 ; N uacute ; B 70 -15 608 661 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 665 784 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N twosuperior ; B 192 230 541 616 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 669 780 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 642 636 ; +C -1 ; WX 600 ; N down ; B 168 -15 496 439 ; +C -1 ; WX 600 ; N center ; B 103 14 623 580 ; +C -1 ; WX 600 ; N onesuperior ; B 213 230 514 616 ; +C -1 ; WX 600 ; N ij ; B 6 -146 714 658 ; +C -1 ; WX 600 ; N edieresis ; B 81 -15 604 625 ; +C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ; +C -1 ; WX 600 ; N odieresis ; B 71 -15 622 625 ; +C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N threequarters ; B 8 -60 698 661 ; +C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ; +C -1 ; WX 600 ; N prescription ; B 24 -15 632 562 ; +C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ; +C -1 ; WX 600 ; N largebullet ; B 307 229 413 333 ; +C -1 ; WX 600 ; N egrave ; B 81 -15 604 661 ; +C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; +C -1 ; WX 600 ; N notegraphic ; B 91 -15 619 572 ; +C -1 ; WX 600 ; N Udieresis ; B 101 -18 715 748 ; +C -1 ; WX 600 ; N Gcaron ; B 75 -18 674 790 ; +C -1 ; WX 600 ; N arrowdown ; B 174 -15 486 608 ; +C -1 ; WX 600 ; N format ; B -26 -146 243 601 ; +C -1 ; WX 600 ; N Otilde ; B 74 -18 668 759 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 642 748 ; +C -1 ; WX 600 ; N adieresis ; B 62 -15 592 625 ; +C -1 ; WX 600 ; N ecircumflex ; B 81 -15 606 657 ; +C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ; +C -1 ; WX 600 ; N onequarter ; B 14 -60 706 661 ; +C -1 ; WX 600 ; N LL ; B -45 0 694 562 ; +C -1 ; WX 600 ; N agrave ; B 62 -15 592 661 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; +C -1 ; WX 600 ; N Scedilla ; B 54 -206 672 582 ; +C -1 ; WX 600 ; N Idot ; B 77 0 642 748 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 642 784 ; +C -1 ; WX 600 ; N indent ; B 99 45 579 372 ; +C -1 ; WX 600 ; N Ugrave ; B 101 -18 715 784 ; +C -1 ; WX 600 ; N scaron ; B 67 -17 632 667 ; +C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ; +C -1 ; WX 600 ; N Aring ; B -9 0 631 801 ; +C -1 ; WX 600 ; N Ccedilla ; B 74 -206 674 580 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 642 784 ; +C -1 ; WX 600 ; N brokenbar ; B 218 -175 488 675 ; +C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N otilde ; B 71 -15 642 636 ; +C -1 ; WX 600 ; N Yacute ; B 109 0 708 784 ; +C -1 ; WX 600 ; N lira ; B 107 -28 650 611 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 642 780 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 638 759 ; +C -1 ; WX 600 ; N Uacute ; B 101 -18 715 784 ; +C -1 ; WX 600 ; N Ydieresis ; B 109 0 708 748 ; +C -1 ; WX 600 ; N ydieresis ; B -20 -142 694 625 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 552 625 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 631 748 ; +C -1 ; WX 600 ; N mu ; B 50 -142 591 439 ; +C -1 ; WX 600 ; N trademark ; B 86 230 868 562 ; +C -1 ; WX 600 ; N oacute ; B 71 -15 622 661 ; +C -1 ; WX 600 ; N acircumflex ; B 62 -15 592 657 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 631 784 ; +C -1 ; WX 600 ; N return ; B 79 0 700 562 ; +C -1 ; WX 600 ; N atilde ; B 62 -15 642 636 ; +C -1 ; WX 600 ; N square ; B 19 0 700 562 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N stop ; B 19 0 700 562 ; +C -1 ; WX 600 ; N udieresis ; B 70 -15 591 625 ; +C -1 ; WX 600 ; N arrowup ; B 244 3 556 626 ; +C -1 ; WX 600 ; N igrave ; B 77 0 545 661 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 669 748 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 632 667 ; +C -1 ; WX 600 ; N arrowboth ; B 40 143 688 455 ; +C -1 ; WX 600 ; N gcaron ; B 41 -146 673 667 ; +C -1 ; WX 600 ; N arrowleft ; B 40 143 708 455 ; +C -1 ; WX 600 ; N aacute ; B 62 -15 608 661 ; +C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; +C -1 ; WX 600 ; N scedilla ; B 67 -206 607 459 ; +C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ; +C -1 ; WX 600 ; N onehalf ; B 23 -60 715 661 ; +C -1 ; WX 600 ; N ugrave ; B 70 -15 591 661 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 729 759 ; +C -1 ; WX 600 ; N iacute ; B 77 0 608 661 ; +C -1 ; WX 600 ; N arrowright ; B 20 143 688 455 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 619 562 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 669 784 ; +C -1 ; WX 600 ; N thorn ; B -31 -142 622 626 ; +C -1 ; WX 600 ; N aring ; B 62 -15 592 678 ; +C -1 ; WX 600 ; N yacute ; B -20 -142 694 661 ; +C -1 ; WX 600 ; N icircumflex ; B 77 0 566 657 ; +EndCharMetrics +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 56 123 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 123 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 6 123 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave -24 123 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 16 123 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde -4 123 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 123 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 123 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 26 123 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 123 ; +CC Gcaron 2 ; PCC G 0 0 ; PCC caron 36 123 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 123 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 123 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 26 123 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 123 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 26 123 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 123 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 123 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 26 123 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 123 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 26 123 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 26 123 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 123 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 123 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 26 123 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 123 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 123 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 26 123 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 26 123 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; +CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrr8a.afm new file mode 100644 index 00000000..f60ec943 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrr8a.afm @@ -0,0 +1,344 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Tue Sep 17 07:47:21 1991 +Comment UniqueID 36347 +Comment VMusage 31037 39405 +FontName Courier +FullName Courier +FamilyName Courier +Weight Medium +ItalicAngle 0 +IsFixedPitch true +FontBBox -28 -250 628 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.004 +Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StartCharMetrics 260 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; +C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; +C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; +C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; +C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; +C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; +C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ; +C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; +C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; +C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; +C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; +C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; +C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; +C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; +C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; +C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; +C 49 ; WX 600 ; N one ; B 96 0 505 622 ; +C 50 ; WX 600 ; N two ; B 70 0 471 622 ; +C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; +C 52 ; WX 600 ; N four ; B 78 0 500 622 ; +C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; +C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; +C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; +C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; +C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; +C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; +C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; +C 60 ; WX 600 ; N less ; B 41 42 519 472 ; +C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; +C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; +C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; +C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; +C 65 ; WX 600 ; N A ; B 3 0 597 562 ; +C 66 ; WX 600 ; N B ; B 43 0 559 562 ; +C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; +C 68 ; WX 600 ; N D ; B 43 0 574 562 ; +C 69 ; WX 600 ; N E ; B 53 0 550 562 ; +C 70 ; WX 600 ; N F ; B 53 0 545 562 ; +C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; +C 72 ; WX 600 ; N H ; B 32 0 568 562 ; +C 73 ; WX 600 ; N I ; B 96 0 504 562 ; +C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; +C 75 ; WX 600 ; N K ; B 38 0 582 562 ; +C 76 ; WX 600 ; N L ; B 47 0 554 562 ; +C 77 ; WX 600 ; N M ; B 4 0 596 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; +C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; +C 80 ; WX 600 ; N P ; B 79 0 558 562 ; +C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; +C 82 ; WX 600 ; N R ; B 38 0 588 562 ; +C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; +C 84 ; WX 600 ; N T ; B 38 0 563 562 ; +C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; +C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; +C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; +C 88 ; WX 600 ; N X ; B 23 0 577 562 ; +C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; +C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; +C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; +C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; +C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; +C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; +C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; +C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; +C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; +C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; +C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; +C 104 ; WX 600 ; N h ; B 18 0 582 629 ; +C 105 ; WX 600 ; N i ; B 95 0 505 657 ; +C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; +C 107 ; WX 600 ; N k ; B 43 0 580 629 ; +C 108 ; WX 600 ; N l ; B 95 0 505 629 ; +C 109 ; WX 600 ; N m ; B -5 0 605 441 ; +C 110 ; WX 600 ; N n ; B 26 0 575 441 ; +C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; +C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; +C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; +C 114 ; WX 600 ; N r ; B 60 0 559 441 ; +C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; +C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; +C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; +C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; +C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; +C 120 ; WX 600 ; N x ; B 20 0 580 426 ; +C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; +C 122 ; WX 600 ; N z ; B 99 0 502 426 ; +C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; +C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; +C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; +C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; +C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; +C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; +C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; +C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ; +C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; +C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ; +C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; +C 168 ; WX 600 ; N currency ; B 73 58 527 506 ; +C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 597 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 597 629 ; +C 177 ; WX 600 ; N endash ; B 75 231 525 285 ; +C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; +C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; +C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; +C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; +C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; +C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; +C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; +C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; +C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; +C 193 ; WX 600 ; N grave ; B 151 497 378 672 ; +C 194 ; WX 600 ; N acute ; B 242 497 469 672 ; +C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ; +C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ; +C 197 ; WX 600 ; N macron ; B 120 525 480 565 ; +C 198 ; WX 600 ; N breve ; B 153 501 447 609 ; +C 199 ; WX 600 ; N dotaccent ; B 249 477 352 580 ; +C 200 ; WX 600 ; N dieresis ; B 148 492 453 595 ; +C 202 ; WX 600 ; N ring ; B 218 463 382 627 ; +C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; +C 206 ; WX 600 ; N ogonek ; B 227 -151 370 0 ; +C 207 ; WX 600 ; N caron ; B 124 492 476 669 ; +C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 550 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ; +C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; +C 234 ; WX 600 ; N OE ; B 7 0 567 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; +C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ; +C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ; +C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; +C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 731 ; +C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; +C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; +C -1 ; WX 600 ; N merge ; B 160 -15 440 436 ; +C -1 ; WX 600 ; N degree ; B 123 269 477 622 ; +C -1 ; WX 600 ; N dectab ; B 18 0 582 227 ; +C -1 ; WX 600 ; N ll ; B 18 0 567 629 ; +C -1 ; WX 600 ; N IJ ; B 32 -18 583 562 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 550 793 ; +C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 775 ; +C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; +C -1 ; WX 600 ; N left ; B 70 68 530 348 ; +C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; +C -1 ; WX 600 ; N up ; B 160 0 440 437 ; +C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ; +C -1 ; WX 600 ; N Scaron ; B 72 -20 529 805 ; +C -1 ; WX 600 ; N tab ; B 19 0 581 562 ; +C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 775 ; +C -1 ; WX 600 ; N divide ; B 87 48 513 467 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 775 ; +C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 597 793 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 775 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ; +C -1 ; WX 600 ; N down ; B 160 -15 440 426 ; +C -1 ; WX 600 ; N center ; B 40 14 560 580 ; +C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; +C -1 ; WX 600 ; N ij ; B 37 -157 490 657 ; +C -1 ; WX 600 ; N edieresis ; B 66 -15 548 595 ; +C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ; +C -1 ; WX 600 ; N odieresis ; B 62 -15 538 595 ; +C -1 ; WX 600 ; N Ograve ; B 43 -18 557 793 ; +C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; +C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ; +C -1 ; WX 600 ; N prescription ; B 27 -15 577 562 ; +C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ; +C -1 ; WX 600 ; N largebullet ; B 261 220 339 297 ; +C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; +C -1 ; WX 600 ; N notegraphic ; B 136 -15 464 572 ; +C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 731 ; +C -1 ; WX 600 ; N Gcaron ; B 31 -18 575 805 ; +C -1 ; WX 600 ; N arrowdown ; B 116 -15 484 608 ; +C -1 ; WX 600 ; N format ; B 5 -157 56 607 ; +C -1 ; WX 600 ; N Otilde ; B 43 -18 557 732 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 504 731 ; +C -1 ; WX 600 ; N adieresis ; B 53 -15 559 595 ; +C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; +C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ; +C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; +C -1 ; WX 600 ; N LL ; B 8 0 592 562 ; +C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 514 805 ; +C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; +C -1 ; WX 600 ; N Idot ; B 96 0 504 716 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 504 793 ; +C -1 ; WX 600 ; N indent ; B 70 68 530 348 ; +C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 793 ; +C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ; +C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ; +C -1 ; WX 600 ; N Aring ; B 3 0 597 753 ; +C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 504 793 ; +C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; +C -1 ; WX 600 ; N Oacute ; B 43 -18 557 793 ; +C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ; +C -1 ; WX 600 ; N Yacute ; B 24 0 576 793 ; +C -1 ; WX 600 ; N lira ; B 73 -21 521 611 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 775 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 597 732 ; +C -1 ; WX 600 ; N Uacute ; B 17 -18 583 793 ; +C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 731 ; +C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 595 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 505 595 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 597 731 ; +C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ; +C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ; +C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 597 793 ; +C -1 ; WX 600 ; N return ; B 19 0 581 562 ; +C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ; +C -1 ; WX 600 ; N square ; B 19 0 581 562 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N stop ; B 19 0 581 562 ; +C -1 ; WX 600 ; N udieresis ; B 21 -15 562 595 ; +C -1 ; WX 600 ; N arrowup ; B 116 0 484 623 ; +C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 550 731 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ; +C -1 ; WX 600 ; N arrowboth ; B -28 115 628 483 ; +C -1 ; WX 600 ; N gcaron ; B 45 -157 566 669 ; +C -1 ; WX 600 ; N arrowleft ; B -24 115 624 483 ; +C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; +C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; +C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; +C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 732 ; +C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ; +C -1 ; WX 600 ; N arrowright ; B -24 115 624 483 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 550 793 ; +C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ; +C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ; +C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ; +C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; +EndCharMetrics +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 20 121 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 121 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -30 136 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave -30 121 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring -15 126 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 126 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 121 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 121 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 136 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 121 ; +CC Gcaron 2 ; PCC G 0 0 ; PCC caron 0 136 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 121 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 121 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 136 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 121 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 126 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 121 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 121 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 136 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 121 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 126 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 30 136 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 121 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 121 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 136 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 121 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 121 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 136 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 136 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; +CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrro8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrro8a.afm new file mode 100644 index 00000000..b053a4ca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pcrro8a.afm @@ -0,0 +1,344 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Tue Sep 17 09:42:19 1991 +Comment UniqueID 36350 +Comment VMusage 9174 52297 +FontName Courier-Oblique +FullName Courier Oblique +FamilyName Courier +Weight Medium +ItalicAngle -12 +IsFixedPitch true +FontBBox -28 -250 742 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.004 +Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StartCharMetrics 260 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; +C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; +C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; +C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; +C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; +C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; +C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ; +C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; +C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; +C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; +C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; +C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; +C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; +C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; +C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; +C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; +C 49 ; WX 600 ; N one ; B 98 0 515 622 ; +C 50 ; WX 600 ; N two ; B 70 0 568 622 ; +C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; +C 52 ; WX 600 ; N four ; B 108 0 541 622 ; +C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; +C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; +C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; +C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; +C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; +C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; +C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; +C 60 ; WX 600 ; N less ; B 96 42 610 472 ; +C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; +C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; +C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; +C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; +C 65 ; WX 600 ; N A ; B 3 0 607 562 ; +C 66 ; WX 600 ; N B ; B 43 0 616 562 ; +C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; +C 68 ; WX 600 ; N D ; B 43 0 645 562 ; +C 69 ; WX 600 ; N E ; B 53 0 660 562 ; +C 70 ; WX 600 ; N F ; B 53 0 660 562 ; +C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; +C 72 ; WX 600 ; N H ; B 32 0 687 562 ; +C 73 ; WX 600 ; N I ; B 96 0 623 562 ; +C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; +C 75 ; WX 600 ; N K ; B 38 0 671 562 ; +C 76 ; WX 600 ; N L ; B 47 0 607 562 ; +C 77 ; WX 600 ; N M ; B 4 0 715 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; +C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; +C 80 ; WX 600 ; N P ; B 79 0 644 562 ; +C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; +C 82 ; WX 600 ; N R ; B 38 0 598 562 ; +C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; +C 84 ; WX 600 ; N T ; B 108 0 665 562 ; +C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; +C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; +C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; +C 88 ; WX 600 ; N X ; B 23 0 675 562 ; +C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; +C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; +C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; +C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; +C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; +C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; +C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; +C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; +C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; +C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; +C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; +C 104 ; WX 600 ; N h ; B 33 0 592 629 ; +C 105 ; WX 600 ; N i ; B 95 0 515 657 ; +C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; +C 107 ; WX 600 ; N k ; B 58 0 633 629 ; +C 108 ; WX 600 ; N l ; B 95 0 515 629 ; +C 109 ; WX 600 ; N m ; B -5 0 615 441 ; +C 110 ; WX 600 ; N n ; B 26 0 585 441 ; +C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; +C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; +C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; +C 114 ; WX 600 ; N r ; B 60 0 636 441 ; +C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; +C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; +C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; +C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; +C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; +C 120 ; WX 600 ; N x ; B 20 0 655 426 ; +C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; +C 122 ; WX 600 ; N z ; B 99 0 593 426 ; +C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; +C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; +C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; +C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; +C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; +C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; +C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; +C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ; +C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; +C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ; +C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; +C 168 ; WX 600 ; N currency ; B 94 58 628 506 ; +C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 619 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 619 629 ; +C 177 ; WX 600 ; N endash ; B 124 231 586 285 ; +C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; +C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; +C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; +C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; +C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; +C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; +C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; +C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; +C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; +C 193 ; WX 600 ; N grave ; B 294 497 484 672 ; +C 194 ; WX 600 ; N acute ; B 348 497 612 672 ; +C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ; +C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ; +C 197 ; WX 600 ; N macron ; B 232 525 600 565 ; +C 198 ; WX 600 ; N breve ; B 279 501 576 609 ; +C 199 ; WX 600 ; N dotaccent ; B 360 477 466 580 ; +C 200 ; WX 600 ; N dieresis ; B 262 492 570 595 ; +C 202 ; WX 600 ; N ring ; B 332 463 500 627 ; +C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; +C 206 ; WX 600 ; N ogonek ; B 207 -151 348 0 ; +C 207 ; WX 600 ; N caron ; B 262 492 614 669 ; +C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 655 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ; +C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; +C 234 ; WX 600 ; N OE ; B 59 0 672 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; +C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 583 629 ; +C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ; +C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; +C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 731 ; +C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; +C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; +C -1 ; WX 600 ; N merge ; B 187 -15 503 436 ; +C -1 ; WX 600 ; N degree ; B 214 269 576 622 ; +C -1 ; WX 600 ; N dectab ; B 18 0 593 227 ; +C -1 ; WX 600 ; N ll ; B 33 0 616 629 ; +C -1 ; WX 600 ; N IJ ; B 32 -18 702 562 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 668 793 ; +C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 775 ; +C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; +C -1 ; WX 600 ; N left ; B 114 68 580 348 ; +C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; +C -1 ; WX 600 ; N up ; B 223 0 503 437 ; +C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ; +C -1 ; WX 600 ; N Scaron ; B 76 -20 673 805 ; +C -1 ; WX 600 ; N tab ; B 19 0 641 562 ; +C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 775 ; +C -1 ; WX 600 ; N divide ; B 136 48 573 467 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 775 ; +C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 658 793 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 775 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ; +C -1 ; WX 600 ; N down ; B 187 -15 467 426 ; +C -1 ; WX 600 ; N center ; B 103 14 623 580 ; +C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; +C -1 ; WX 600 ; N ij ; B 37 -157 630 657 ; +C -1 ; WX 600 ; N edieresis ; B 106 -15 598 595 ; +C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ; +C -1 ; WX 600 ; N odieresis ; B 102 -15 588 595 ; +C -1 ; WX 600 ; N Ograve ; B 94 -18 625 793 ; +C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; +C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ; +C -1 ; WX 600 ; N prescription ; B 27 -15 617 562 ; +C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ; +C -1 ; WX 600 ; N largebullet ; B 315 220 395 297 ; +C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ; +C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; +C -1 ; WX 600 ; N notegraphic ; B 143 -15 564 572 ; +C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 731 ; +C -1 ; WX 600 ; N Gcaron ; B 83 -18 645 805 ; +C -1 ; WX 600 ; N arrowdown ; B 152 -15 520 608 ; +C -1 ; WX 600 ; N format ; B -28 -157 185 607 ; +C -1 ; WX 600 ; N Otilde ; B 94 -18 656 732 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 623 731 ; +C -1 ; WX 600 ; N adieresis ; B 76 -15 570 595 ; +C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; +C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ; +C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; +C -1 ; WX 600 ; N LL ; B 8 0 647 562 ; +C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 643 805 ; +C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; +C -1 ; WX 600 ; N Idot ; B 96 0 623 716 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 638 793 ; +C -1 ; WX 600 ; N indent ; B 108 68 574 348 ; +C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 793 ; +C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ; +C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ; +C -1 ; WX 600 ; N Aring ; B 3 0 607 753 ; +C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 623 793 ; +C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; +C -1 ; WX 600 ; N Oacute ; B 94 -18 638 793 ; +C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ; +C -1 ; WX 600 ; N Yacute ; B 133 0 695 793 ; +C -1 ; WX 600 ; N lira ; B 118 -21 621 611 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 775 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 656 732 ; +C -1 ; WX 600 ; N Uacute ; B 125 -18 702 793 ; +C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 731 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 595 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 540 595 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 607 731 ; +C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ; +C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ; +C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ; +C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 607 793 ; +C -1 ; WX 600 ; N return ; B 79 0 700 562 ; +C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ; +C -1 ; WX 600 ; N square ; B 19 0 700 562 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N stop ; B 19 0 700 562 ; +C -1 ; WX 600 ; N udieresis ; B 101 -15 572 595 ; +C -1 ; WX 600 ; N arrowup ; B 209 0 577 623 ; +C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 660 731 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ; +C -1 ; WX 600 ; N arrowboth ; B 36 115 692 483 ; +C -1 ; WX 600 ; N gcaron ; B 61 -157 657 669 ; +C -1 ; WX 600 ; N arrowleft ; B 40 115 693 483 ; +C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ; +C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; +C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; +C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ; +C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; +C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 732 ; +C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ; +C -1 ; WX 600 ; N arrowright ; B 34 115 688 483 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 660 793 ; +C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ; +C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ; +C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ; +C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; +EndCharMetrics +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 46 121 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 121 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -1 136 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave -4 121 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 12 126 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 27 126 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 121 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 121 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 29 136 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 121 ; +CC Gcaron 2 ; PCC G 0 0 ; PCC caron 29 136 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 121 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 121 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 29 136 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 121 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 27 126 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 121 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 121 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 29 136 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 121 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 27 126 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 59 136 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 121 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 121 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 29 136 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 121 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 121 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 29 136 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 29 136 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; +CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8a.afm new file mode 100644 index 00000000..a1e1b33c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8a.afm @@ -0,0 +1,570 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu Mar 15 09:43:00 1990 +Comment UniqueID 28357 +Comment VMusage 26878 33770 +FontName Helvetica-Bold +FullName Helvetica Bold +FamilyName Helvetica +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -170 -228 1003 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ; +C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ; +C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ; +C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ; +C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ; +C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ; +C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ; +C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ; +C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ; +C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ; +C 43 ; WX 584 ; N plus ; B 40 0 544 506 ; +C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ; +C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ; +C 46 ; WX 278 ; N period ; B 64 0 214 146 ; +C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ; +C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ; +C 49 ; WX 556 ; N one ; B 69 0 378 710 ; +C 50 ; WX 556 ; N two ; B 26 0 511 710 ; +C 51 ; WX 556 ; N three ; B 27 -19 516 710 ; +C 52 ; WX 556 ; N four ; B 27 0 526 710 ; +C 53 ; WX 556 ; N five ; B 27 -19 516 698 ; +C 54 ; WX 556 ; N six ; B 31 -19 520 710 ; +C 55 ; WX 556 ; N seven ; B 25 0 528 698 ; +C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ; +C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 242 512 ; +C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ; +C 60 ; WX 584 ; N less ; B 38 -8 546 514 ; +C 61 ; WX 584 ; N equal ; B 40 87 544 419 ; +C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ; +C 63 ; WX 611 ; N question ; B 60 0 556 727 ; +C 64 ; WX 975 ; N at ; B 118 -19 856 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 669 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 684 737 ; +C 68 ; WX 722 ; N D ; B 76 0 685 718 ; +C 69 ; WX 667 ; N E ; B 76 0 621 718 ; +C 70 ; WX 611 ; N F ; B 76 0 587 718 ; +C 71 ; WX 778 ; N G ; B 44 -19 713 737 ; +C 72 ; WX 722 ; N H ; B 71 0 651 718 ; +C 73 ; WX 278 ; N I ; B 64 0 214 718 ; +C 74 ; WX 556 ; N J ; B 22 -18 484 718 ; +C 75 ; WX 722 ; N K ; B 87 0 722 718 ; +C 76 ; WX 611 ; N L ; B 76 0 583 718 ; +C 77 ; WX 833 ; N M ; B 69 0 765 718 ; +C 78 ; WX 722 ; N N ; B 69 0 654 718 ; +C 79 ; WX 778 ; N O ; B 44 -19 734 737 ; +C 80 ; WX 667 ; N P ; B 76 0 627 718 ; +C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ; +C 82 ; WX 722 ; N R ; B 76 0 677 718 ; +C 83 ; WX 667 ; N S ; B 39 -19 629 737 ; +C 84 ; WX 611 ; N T ; B 14 0 598 718 ; +C 85 ; WX 722 ; N U ; B 72 -19 651 718 ; +C 86 ; WX 667 ; N V ; B 19 0 648 718 ; +C 87 ; WX 944 ; N W ; B 16 0 929 718 ; +C 88 ; WX 667 ; N X ; B 14 0 653 718 ; +C 89 ; WX 667 ; N Y ; B 15 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 586 718 ; +C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ; +C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ; +C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ; +C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ; +C 97 ; WX 556 ; N a ; B 29 -14 527 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 578 718 ; +C 99 ; WX 556 ; N c ; B 34 -14 524 546 ; +C 100 ; WX 611 ; N d ; B 34 -14 551 718 ; +C 101 ; WX 556 ; N e ; B 23 -14 528 546 ; +C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 40 -217 553 546 ; +C 104 ; WX 611 ; N h ; B 65 0 546 718 ; +C 105 ; WX 278 ; N i ; B 69 0 209 725 ; +C 106 ; WX 278 ; N j ; B 3 -214 209 725 ; +C 107 ; WX 556 ; N k ; B 69 0 562 718 ; +C 108 ; WX 278 ; N l ; B 69 0 209 718 ; +C 109 ; WX 889 ; N m ; B 64 0 826 546 ; +C 110 ; WX 611 ; N n ; B 65 0 546 546 ; +C 111 ; WX 611 ; N o ; B 34 -14 578 546 ; +C 112 ; WX 611 ; N p ; B 62 -207 578 546 ; +C 113 ; WX 611 ; N q ; B 34 -207 552 546 ; +C 114 ; WX 389 ; N r ; B 64 0 373 546 ; +C 115 ; WX 556 ; N s ; B 30 -14 519 546 ; +C 116 ; WX 333 ; N t ; B 10 -6 309 676 ; +C 117 ; WX 611 ; N u ; B 66 -14 545 532 ; +C 118 ; WX 556 ; N v ; B 13 0 543 532 ; +C 119 ; WX 778 ; N w ; B 10 0 769 532 ; +C 120 ; WX 556 ; N x ; B 15 0 541 532 ; +C 121 ; WX 556 ; N y ; B 10 -214 539 532 ; +C 122 ; WX 500 ; N z ; B 20 0 480 532 ; +C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ; +C 124 ; WX 280 ; N bar ; B 84 -19 196 737 ; +C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ; +C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ; +C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ; +C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ; +C 165 ; WX 556 ; N yen ; B -9 0 565 698 ; +C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ; +C 167 ; WX 556 ; N section ; B 34 -184 522 727 ; +C 168 ; WX 556 ; N currency ; B -3 76 559 636 ; +C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ; +C 174 ; WX 611 ; N fi ; B 10 0 542 727 ; +C 175 ; WX 611 ; N fl ; B 10 0 542 727 ; +C 177 ; WX 556 ; N endash ; B 0 227 556 333 ; +C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ; +C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ; +C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ; +C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ; +C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ; +C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ; +C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ; +C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ; +C 193 ; WX 333 ; N grave ; B -23 604 225 750 ; +C 194 ; WX 333 ; N acute ; B 108 604 356 750 ; +C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ; +C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ; +C 197 ; WX 333 ; N macron ; B -6 604 339 678 ; +C 198 ; WX 333 ; N breve ; B -2 604 335 750 ; +C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ; +C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ; +C 202 ; WX 333 ; N ring ; B 59 568 275 776 ; +C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ; +C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ; +C 207 ; WX 333 ; N caron ; B -10 604 343 750 ; +C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 22 276 347 737 ; +C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ; +C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ; +C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 6 276 360 737 ; +C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ; +C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ; +C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ; +C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ; +C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ; +C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ; +C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ; +C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ; +C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ; +C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ; +C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ; +C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ; +C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ; +C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ; +C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ; +C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ; +C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ; +C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ; +C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ; +C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ; +C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ; +C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ; +C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ; +C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ; +C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ; +C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ; +C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ; +C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ; +C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ; +C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ; +C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ; +C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ; +C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ; +C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ; +C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ; +C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ; +C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ; +C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ; +C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ; +C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ; +C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ; +C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ; +C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ; +C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ; +C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ; +C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ; +C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ; +C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ; +C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ; +C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ; +C -1 ; WX 584 ; N minus ; B 40 197 544 309 ; +C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ; +C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ; +C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ; +C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; +C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ; +C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ; +C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ; +C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ; +C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ; +C -1 ; WX 280 ; N brokenbar ; B 84 -19 196 737 ; +C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ; +EndCharMetrics +StartKernData +StartKernPairs 209 + +KPX A y -30 +KPX A w -30 +KPX A v -40 +KPX A u -30 +KPX A Y -110 +KPX A W -60 +KPX A V -80 +KPX A U -50 +KPX A T -90 +KPX A Q -40 +KPX A O -40 +KPX A G -50 +KPX A C -40 + +KPX B U -10 +KPX B A -30 + +KPX D period -30 +KPX D comma -30 +KPX D Y -70 +KPX D W -40 +KPX D V -40 +KPX D A -40 + +KPX F period -100 +KPX F comma -100 +KPX F a -20 +KPX F A -80 + +KPX J u -20 +KPX J period -20 +KPX J comma -20 +KPX J A -20 + +KPX K y -40 +KPX K u -30 +KPX K o -35 +KPX K e -15 +KPX K O -30 + +KPX L y -30 +KPX L quoteright -140 +KPX L quotedblright -140 +KPX L Y -120 +KPX L W -80 +KPX L V -110 +KPX L T -90 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -50 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -50 + +KPX P period -120 +KPX P o -40 +KPX P e -30 +KPX P comma -120 +KPX P a -30 +KPX P A -100 + +KPX Q period 20 +KPX Q comma 20 +KPX Q U -10 + +KPX R Y -50 +KPX R W -40 +KPX R V -50 +KPX R U -20 +KPX R T -20 +KPX R O -20 + +KPX T y -60 +KPX T w -60 +KPX T u -90 +KPX T semicolon -40 +KPX T r -80 +KPX T period -80 +KPX T o -80 +KPX T hyphen -120 +KPX T e -60 +KPX T comma -80 +KPX T colon -40 +KPX T a -80 +KPX T O -40 +KPX T A -90 + +KPX U period -30 +KPX U comma -30 +KPX U A -50 + +KPX V u -60 +KPX V semicolon -40 +KPX V period -120 +KPX V o -90 +KPX V hyphen -80 +KPX V e -50 +KPX V comma -120 +KPX V colon -40 +KPX V a -60 +KPX V O -50 +KPX V G -50 +KPX V A -80 + +KPX W y -20 +KPX W u -45 +KPX W semicolon -10 +KPX W period -80 +KPX W o -60 +KPX W hyphen -40 +KPX W e -35 +KPX W comma -80 +KPX W colon -10 +KPX W a -40 +KPX W O -20 +KPX W A -60 + +KPX Y u -100 +KPX Y semicolon -50 +KPX Y period -100 +KPX Y o -100 +KPX Y e -80 +KPX Y comma -100 +KPX Y colon -50 +KPX Y a -90 +KPX Y O -70 +KPX Y A -110 + +KPX a y -20 +KPX a w -15 +KPX a v -15 +KPX a g -10 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b l -10 + +KPX c y -10 +KPX c l -20 +KPX c k -20 +KPX c h -10 + +KPX colon space -40 + +KPX comma space -40 +KPX comma quoteright -120 +KPX comma quotedblright -120 + +KPX d y -15 +KPX d w -15 +KPX d v -15 +KPX d d -10 + +KPX e y -15 +KPX e x -15 +KPX e w -15 +KPX e v -15 +KPX e period 20 +KPX e comma 10 + +KPX f quoteright 30 +KPX f quotedblright 30 +KPX f period -10 +KPX f o -20 +KPX f e -10 +KPX f comma -10 + +KPX g g -10 +KPX g e 10 + +KPX h y -20 + +KPX k o -15 + +KPX l y -15 +KPX l w -15 + +KPX m y -30 +KPX m u -20 + +KPX n y -20 +KPX n v -40 +KPX n u -10 + +KPX o y -20 +KPX o x -30 +KPX o w -15 +KPX o v -20 + +KPX p y -15 + +KPX period space -40 +KPX period quoteright -120 +KPX period quotedblright -120 + +KPX quotedblright space -80 + +KPX quoteleft quoteleft -46 + +KPX quoteright v -20 +KPX quoteright space -80 +KPX quoteright s -60 +KPX quoteright r -40 +KPX quoteright quoteright -46 +KPX quoteright l -20 +KPX quoteright d -80 + +KPX r y 10 +KPX r v 10 +KPX r t 20 +KPX r s -15 +KPX r q -20 +KPX r period -60 +KPX r o -20 +KPX r hyphen -20 +KPX r g -15 +KPX r d -20 +KPX r comma -60 +KPX r c -20 + +KPX s w -15 + +KPX semicolon space -40 + +KPX space quoteleft -60 +KPX space quotedblleft -80 +KPX space Y -120 +KPX space W -80 +KPX space V -80 +KPX space T -100 + +KPX v period -80 +KPX v o -30 +KPX v comma -80 +KPX v a -20 + +KPX w period -40 +KPX w o -20 +KPX w comma -40 + +KPX x e -10 + +KPX y period -80 +KPX y o -25 +KPX y e -10 +KPX y comma -80 +KPX y a -30 + +KPX z e 10 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 186 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 186 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 186 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 186 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 195 186 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 186 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 186 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 186 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 186 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 186 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 186 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 186 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 186 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 186 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 186 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 186 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 186 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 186 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 186 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 186 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 186 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 186 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 186 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 186 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 186 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8an.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8an.afm new file mode 100644 index 00000000..b7c69698 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvb8an.afm @@ -0,0 +1,570 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu Mar 15 11:47:27 1990 +Comment UniqueID 28398 +Comment VMusage 7614 43068 +FontName Helvetica-Narrow-Bold +FullName Helvetica Narrow Bold +FamilyName Helvetica +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -139 -228 822 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 228 ; N space ; B 0 0 0 0 ; +C 33 ; WX 273 ; N exclam ; B 74 0 200 718 ; +C 34 ; WX 389 ; N quotedbl ; B 80 447 308 718 ; +C 35 ; WX 456 ; N numbersign ; B 15 0 441 698 ; +C 36 ; WX 456 ; N dollar ; B 25 -115 429 775 ; +C 37 ; WX 729 ; N percent ; B 23 -19 706 710 ; +C 38 ; WX 592 ; N ampersand ; B 44 -19 575 718 ; +C 39 ; WX 228 ; N quoteright ; B 57 445 171 718 ; +C 40 ; WX 273 ; N parenleft ; B 29 -208 257 734 ; +C 41 ; WX 273 ; N parenright ; B 16 -208 244 734 ; +C 42 ; WX 319 ; N asterisk ; B 22 387 297 718 ; +C 43 ; WX 479 ; N plus ; B 33 0 446 506 ; +C 44 ; WX 228 ; N comma ; B 52 -168 175 146 ; +C 45 ; WX 273 ; N hyphen ; B 22 215 251 345 ; +C 46 ; WX 228 ; N period ; B 52 0 175 146 ; +C 47 ; WX 228 ; N slash ; B -27 -19 255 737 ; +C 48 ; WX 456 ; N zero ; B 26 -19 430 710 ; +C 49 ; WX 456 ; N one ; B 57 0 310 710 ; +C 50 ; WX 456 ; N two ; B 21 0 419 710 ; +C 51 ; WX 456 ; N three ; B 22 -19 423 710 ; +C 52 ; WX 456 ; N four ; B 22 0 431 710 ; +C 53 ; WX 456 ; N five ; B 22 -19 423 698 ; +C 54 ; WX 456 ; N six ; B 25 -19 426 710 ; +C 55 ; WX 456 ; N seven ; B 20 0 433 698 ; +C 56 ; WX 456 ; N eight ; B 26 -19 430 710 ; +C 57 ; WX 456 ; N nine ; B 25 -19 428 710 ; +C 58 ; WX 273 ; N colon ; B 75 0 198 512 ; +C 59 ; WX 273 ; N semicolon ; B 75 -168 198 512 ; +C 60 ; WX 479 ; N less ; B 31 -8 448 514 ; +C 61 ; WX 479 ; N equal ; B 33 87 446 419 ; +C 62 ; WX 479 ; N greater ; B 31 -8 448 514 ; +C 63 ; WX 501 ; N question ; B 49 0 456 727 ; +C 64 ; WX 800 ; N at ; B 97 -19 702 737 ; +C 65 ; WX 592 ; N A ; B 16 0 576 718 ; +C 66 ; WX 592 ; N B ; B 62 0 549 718 ; +C 67 ; WX 592 ; N C ; B 36 -19 561 737 ; +C 68 ; WX 592 ; N D ; B 62 0 562 718 ; +C 69 ; WX 547 ; N E ; B 62 0 509 718 ; +C 70 ; WX 501 ; N F ; B 62 0 481 718 ; +C 71 ; WX 638 ; N G ; B 36 -19 585 737 ; +C 72 ; WX 592 ; N H ; B 58 0 534 718 ; +C 73 ; WX 228 ; N I ; B 52 0 175 718 ; +C 74 ; WX 456 ; N J ; B 18 -18 397 718 ; +C 75 ; WX 592 ; N K ; B 71 0 592 718 ; +C 76 ; WX 501 ; N L ; B 62 0 478 718 ; +C 77 ; WX 683 ; N M ; B 57 0 627 718 ; +C 78 ; WX 592 ; N N ; B 57 0 536 718 ; +C 79 ; WX 638 ; N O ; B 36 -19 602 737 ; +C 80 ; WX 547 ; N P ; B 62 0 514 718 ; +C 81 ; WX 638 ; N Q ; B 36 -52 604 737 ; +C 82 ; WX 592 ; N R ; B 62 0 555 718 ; +C 83 ; WX 547 ; N S ; B 32 -19 516 737 ; +C 84 ; WX 501 ; N T ; B 11 0 490 718 ; +C 85 ; WX 592 ; N U ; B 59 -19 534 718 ; +C 86 ; WX 547 ; N V ; B 16 0 531 718 ; +C 87 ; WX 774 ; N W ; B 13 0 762 718 ; +C 88 ; WX 547 ; N X ; B 11 0 535 718 ; +C 89 ; WX 547 ; N Y ; B 12 0 535 718 ; +C 90 ; WX 501 ; N Z ; B 20 0 481 718 ; +C 91 ; WX 273 ; N bracketleft ; B 52 -196 253 722 ; +C 92 ; WX 228 ; N backslash ; B -27 -19 255 737 ; +C 93 ; WX 273 ; N bracketright ; B 20 -196 221 722 ; +C 94 ; WX 479 ; N asciicircum ; B 51 323 428 698 ; +C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ; +C 96 ; WX 228 ; N quoteleft ; B 57 454 171 727 ; +C 97 ; WX 456 ; N a ; B 24 -14 432 546 ; +C 98 ; WX 501 ; N b ; B 50 -14 474 718 ; +C 99 ; WX 456 ; N c ; B 28 -14 430 546 ; +C 100 ; WX 501 ; N d ; B 28 -14 452 718 ; +C 101 ; WX 456 ; N e ; B 19 -14 433 546 ; +C 102 ; WX 273 ; N f ; B 8 0 261 727 ; L i fi ; L l fl ; +C 103 ; WX 501 ; N g ; B 33 -217 453 546 ; +C 104 ; WX 501 ; N h ; B 53 0 448 718 ; +C 105 ; WX 228 ; N i ; B 57 0 171 725 ; +C 106 ; WX 228 ; N j ; B 2 -214 171 725 ; +C 107 ; WX 456 ; N k ; B 57 0 461 718 ; +C 108 ; WX 228 ; N l ; B 57 0 171 718 ; +C 109 ; WX 729 ; N m ; B 52 0 677 546 ; +C 110 ; WX 501 ; N n ; B 53 0 448 546 ; +C 111 ; WX 501 ; N o ; B 28 -14 474 546 ; +C 112 ; WX 501 ; N p ; B 51 -207 474 546 ; +C 113 ; WX 501 ; N q ; B 28 -207 453 546 ; +C 114 ; WX 319 ; N r ; B 52 0 306 546 ; +C 115 ; WX 456 ; N s ; B 25 -14 426 546 ; +C 116 ; WX 273 ; N t ; B 8 -6 253 676 ; +C 117 ; WX 501 ; N u ; B 54 -14 447 532 ; +C 118 ; WX 456 ; N v ; B 11 0 445 532 ; +C 119 ; WX 638 ; N w ; B 8 0 631 532 ; +C 120 ; WX 456 ; N x ; B 12 0 444 532 ; +C 121 ; WX 456 ; N y ; B 8 -214 442 532 ; +C 122 ; WX 410 ; N z ; B 16 0 394 532 ; +C 123 ; WX 319 ; N braceleft ; B 39 -196 299 722 ; +C 124 ; WX 230 ; N bar ; B 69 -19 161 737 ; +C 125 ; WX 319 ; N braceright ; B 20 -196 280 722 ; +C 126 ; WX 479 ; N asciitilde ; B 50 163 429 343 ; +C 161 ; WX 273 ; N exclamdown ; B 74 -186 200 532 ; +C 162 ; WX 456 ; N cent ; B 28 -118 430 628 ; +C 163 ; WX 456 ; N sterling ; B 23 -16 444 718 ; +C 164 ; WX 137 ; N fraction ; B -139 -19 276 710 ; +C 165 ; WX 456 ; N yen ; B -7 0 463 698 ; +C 166 ; WX 456 ; N florin ; B -8 -210 423 737 ; +C 167 ; WX 456 ; N section ; B 28 -184 428 727 ; +C 168 ; WX 456 ; N currency ; B -2 76 458 636 ; +C 169 ; WX 195 ; N quotesingle ; B 57 447 138 718 ; +C 170 ; WX 410 ; N quotedblleft ; B 52 454 358 727 ; +C 171 ; WX 456 ; N guillemotleft ; B 72 76 384 484 ; +C 172 ; WX 273 ; N guilsinglleft ; B 68 76 205 484 ; +C 173 ; WX 273 ; N guilsinglright ; B 68 76 205 484 ; +C 174 ; WX 501 ; N fi ; B 8 0 444 727 ; +C 175 ; WX 501 ; N fl ; B 8 0 444 727 ; +C 177 ; WX 456 ; N endash ; B 0 227 456 333 ; +C 178 ; WX 456 ; N dagger ; B 30 -171 426 718 ; +C 179 ; WX 456 ; N daggerdbl ; B 30 -171 426 718 ; +C 180 ; WX 228 ; N periodcentered ; B 48 172 180 334 ; +C 182 ; WX 456 ; N paragraph ; B -7 -191 442 700 ; +C 183 ; WX 287 ; N bullet ; B 8 194 279 524 ; +C 184 ; WX 228 ; N quotesinglbase ; B 57 -146 171 127 ; +C 185 ; WX 410 ; N quotedblbase ; B 52 -146 358 127 ; +C 186 ; WX 410 ; N quotedblright ; B 52 445 358 718 ; +C 187 ; WX 456 ; N guillemotright ; B 72 76 384 484 ; +C 188 ; WX 820 ; N ellipsis ; B 75 0 745 146 ; +C 189 ; WX 820 ; N perthousand ; B -2 -19 822 710 ; +C 191 ; WX 501 ; N questiondown ; B 45 -195 452 532 ; +C 193 ; WX 273 ; N grave ; B -19 604 184 750 ; +C 194 ; WX 273 ; N acute ; B 89 604 292 750 ; +C 195 ; WX 273 ; N circumflex ; B -8 604 281 750 ; +C 196 ; WX 273 ; N tilde ; B -14 610 287 737 ; +C 197 ; WX 273 ; N macron ; B -5 604 278 678 ; +C 198 ; WX 273 ; N breve ; B -2 604 275 750 ; +C 199 ; WX 273 ; N dotaccent ; B 85 614 189 729 ; +C 200 ; WX 273 ; N dieresis ; B 5 614 268 729 ; +C 202 ; WX 273 ; N ring ; B 48 568 225 776 ; +C 203 ; WX 273 ; N cedilla ; B 5 -228 201 0 ; +C 205 ; WX 273 ; N hungarumlaut ; B 7 604 399 750 ; +C 206 ; WX 273 ; N ogonek ; B 58 -228 249 0 ; +C 207 ; WX 273 ; N caron ; B -8 604 281 750 ; +C 208 ; WX 820 ; N emdash ; B 0 227 820 333 ; +C 225 ; WX 820 ; N AE ; B 4 0 782 718 ; +C 227 ; WX 303 ; N ordfeminine ; B 18 276 285 737 ; +C 232 ; WX 501 ; N Lslash ; B -16 0 478 718 ; +C 233 ; WX 638 ; N Oslash ; B 27 -27 610 745 ; +C 234 ; WX 820 ; N OE ; B 30 -19 788 737 ; +C 235 ; WX 299 ; N ordmasculine ; B 5 276 295 737 ; +C 241 ; WX 729 ; N ae ; B 24 -14 704 546 ; +C 245 ; WX 228 ; N dotlessi ; B 57 0 171 532 ; +C 248 ; WX 228 ; N lslash ; B -15 0 243 718 ; +C 249 ; WX 501 ; N oslash ; B 18 -29 483 560 ; +C 250 ; WX 774 ; N oe ; B 28 -14 748 546 ; +C 251 ; WX 501 ; N germandbls ; B 57 -14 475 731 ; +C -1 ; WX 501 ; N Zcaron ; B 20 0 481 936 ; +C -1 ; WX 456 ; N ccedilla ; B 28 -228 430 546 ; +C -1 ; WX 456 ; N ydieresis ; B 8 -214 442 729 ; +C -1 ; WX 456 ; N atilde ; B 24 -14 432 737 ; +C -1 ; WX 228 ; N icircumflex ; B -30 0 259 750 ; +C -1 ; WX 273 ; N threesuperior ; B 7 271 267 710 ; +C -1 ; WX 456 ; N ecircumflex ; B 19 -14 433 750 ; +C -1 ; WX 501 ; N thorn ; B 51 -208 474 718 ; +C -1 ; WX 456 ; N egrave ; B 19 -14 433 750 ; +C -1 ; WX 273 ; N twosuperior ; B 7 283 266 710 ; +C -1 ; WX 456 ; N eacute ; B 19 -14 433 750 ; +C -1 ; WX 501 ; N otilde ; B 28 -14 474 737 ; +C -1 ; WX 592 ; N Aacute ; B 16 0 576 936 ; +C -1 ; WX 501 ; N ocircumflex ; B 28 -14 474 750 ; +C -1 ; WX 456 ; N yacute ; B 8 -214 442 750 ; +C -1 ; WX 501 ; N udieresis ; B 54 -14 447 729 ; +C -1 ; WX 684 ; N threequarters ; B 13 -19 655 710 ; +C -1 ; WX 456 ; N acircumflex ; B 24 -14 432 750 ; +C -1 ; WX 592 ; N Eth ; B -4 0 562 718 ; +C -1 ; WX 456 ; N edieresis ; B 19 -14 433 729 ; +C -1 ; WX 501 ; N ugrave ; B 54 -14 447 750 ; +C -1 ; WX 820 ; N trademark ; B 36 306 784 718 ; +C -1 ; WX 501 ; N ograve ; B 28 -14 474 750 ; +C -1 ; WX 456 ; N scaron ; B 25 -14 426 750 ; +C -1 ; WX 228 ; N Idieresis ; B -17 0 246 915 ; +C -1 ; WX 501 ; N uacute ; B 54 -14 447 750 ; +C -1 ; WX 456 ; N agrave ; B 24 -14 432 750 ; +C -1 ; WX 501 ; N ntilde ; B 53 0 448 737 ; +C -1 ; WX 456 ; N aring ; B 24 -14 432 776 ; +C -1 ; WX 410 ; N zcaron ; B 16 0 394 750 ; +C -1 ; WX 228 ; N Icircumflex ; B -30 0 259 936 ; +C -1 ; WX 592 ; N Ntilde ; B 57 0 536 923 ; +C -1 ; WX 501 ; N ucircumflex ; B 54 -14 447 750 ; +C -1 ; WX 547 ; N Ecircumflex ; B 62 0 509 936 ; +C -1 ; WX 228 ; N Iacute ; B 52 0 270 936 ; +C -1 ; WX 592 ; N Ccedilla ; B 36 -228 561 737 ; +C -1 ; WX 638 ; N Odieresis ; B 36 -19 602 915 ; +C -1 ; WX 547 ; N Scaron ; B 32 -19 516 936 ; +C -1 ; WX 547 ; N Edieresis ; B 62 0 509 915 ; +C -1 ; WX 228 ; N Igrave ; B -41 0 175 936 ; +C -1 ; WX 456 ; N adieresis ; B 24 -14 432 729 ; +C -1 ; WX 638 ; N Ograve ; B 36 -19 602 936 ; +C -1 ; WX 547 ; N Egrave ; B 62 0 509 936 ; +C -1 ; WX 547 ; N Ydieresis ; B 12 0 535 915 ; +C -1 ; WX 604 ; N registered ; B -9 -19 613 737 ; +C -1 ; WX 638 ; N Otilde ; B 36 -19 602 923 ; +C -1 ; WX 684 ; N onequarter ; B 21 -19 628 710 ; +C -1 ; WX 592 ; N Ugrave ; B 59 -19 534 936 ; +C -1 ; WX 592 ; N Ucircumflex ; B 59 -19 534 936 ; +C -1 ; WX 547 ; N Thorn ; B 62 0 514 718 ; +C -1 ; WX 479 ; N divide ; B 33 -42 446 548 ; +C -1 ; WX 592 ; N Atilde ; B 16 0 576 923 ; +C -1 ; WX 592 ; N Uacute ; B 59 -19 534 936 ; +C -1 ; WX 638 ; N Ocircumflex ; B 36 -19 602 936 ; +C -1 ; WX 479 ; N logicalnot ; B 33 108 446 419 ; +C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ; +C -1 ; WX 228 ; N idieresis ; B -17 0 246 729 ; +C -1 ; WX 228 ; N iacute ; B 57 0 270 750 ; +C -1 ; WX 456 ; N aacute ; B 24 -14 432 750 ; +C -1 ; WX 479 ; N plusminus ; B 33 0 446 506 ; +C -1 ; WX 479 ; N multiply ; B 33 1 447 505 ; +C -1 ; WX 592 ; N Udieresis ; B 59 -19 534 915 ; +C -1 ; WX 479 ; N minus ; B 33 197 446 309 ; +C -1 ; WX 273 ; N onesuperior ; B 21 283 194 710 ; +C -1 ; WX 547 ; N Eacute ; B 62 0 509 936 ; +C -1 ; WX 592 ; N Acircumflex ; B 16 0 576 936 ; +C -1 ; WX 604 ; N copyright ; B -9 -19 614 737 ; +C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ; +C -1 ; WX 501 ; N odieresis ; B 28 -14 474 729 ; +C -1 ; WX 501 ; N oacute ; B 28 -14 474 750 ; +C -1 ; WX 328 ; N degree ; B 47 426 281 712 ; +C -1 ; WX 228 ; N igrave ; B -41 0 171 750 ; +C -1 ; WX 501 ; N mu ; B 54 -207 447 532 ; +C -1 ; WX 638 ; N Oacute ; B 36 -19 602 936 ; +C -1 ; WX 501 ; N eth ; B 28 -14 474 737 ; +C -1 ; WX 592 ; N Adieresis ; B 16 0 576 915 ; +C -1 ; WX 547 ; N Yacute ; B 12 0 535 936 ; +C -1 ; WX 230 ; N brokenbar ; B 69 -19 161 737 ; +C -1 ; WX 684 ; N onehalf ; B 21 -19 651 710 ; +EndCharMetrics +StartKernData +StartKernPairs 209 + +KPX A y -24 +KPX A w -24 +KPX A v -32 +KPX A u -24 +KPX A Y -89 +KPX A W -48 +KPX A V -65 +KPX A U -40 +KPX A T -73 +KPX A Q -32 +KPX A O -32 +KPX A G -40 +KPX A C -32 + +KPX B U -7 +KPX B A -24 + +KPX D period -24 +KPX D comma -24 +KPX D Y -56 +KPX D W -32 +KPX D V -32 +KPX D A -32 + +KPX F period -81 +KPX F comma -81 +KPX F a -15 +KPX F A -65 + +KPX J u -15 +KPX J period -15 +KPX J comma -15 +KPX J A -15 + +KPX K y -32 +KPX K u -24 +KPX K o -28 +KPX K e -11 +KPX K O -24 + +KPX L y -24 +KPX L quoteright -114 +KPX L quotedblright -114 +KPX L Y -97 +KPX L W -65 +KPX L V -89 +KPX L T -73 + +KPX O period -32 +KPX O comma -32 +KPX O Y -56 +KPX O X -40 +KPX O W -40 +KPX O V -40 +KPX O T -32 +KPX O A -40 + +KPX P period -97 +KPX P o -32 +KPX P e -24 +KPX P comma -97 +KPX P a -24 +KPX P A -81 + +KPX Q period 16 +KPX Q comma 16 +KPX Q U -7 + +KPX R Y -40 +KPX R W -32 +KPX R V -40 +KPX R U -15 +KPX R T -15 +KPX R O -15 + +KPX T y -48 +KPX T w -48 +KPX T u -73 +KPX T semicolon -32 +KPX T r -65 +KPX T period -65 +KPX T o -65 +KPX T hyphen -97 +KPX T e -48 +KPX T comma -65 +KPX T colon -32 +KPX T a -65 +KPX T O -32 +KPX T A -73 + +KPX U period -24 +KPX U comma -24 +KPX U A -40 + +KPX V u -48 +KPX V semicolon -32 +KPX V period -97 +KPX V o -73 +KPX V hyphen -65 +KPX V e -40 +KPX V comma -97 +KPX V colon -32 +KPX V a -48 +KPX V O -40 +KPX V G -40 +KPX V A -65 + +KPX W y -15 +KPX W u -36 +KPX W semicolon -7 +KPX W period -65 +KPX W o -48 +KPX W hyphen -32 +KPX W e -28 +KPX W comma -65 +KPX W colon -7 +KPX W a -32 +KPX W O -15 +KPX W A -48 + +KPX Y u -81 +KPX Y semicolon -40 +KPX Y period -81 +KPX Y o -81 +KPX Y e -65 +KPX Y comma -81 +KPX Y colon -40 +KPX Y a -73 +KPX Y O -56 +KPX Y A -89 + +KPX a y -15 +KPX a w -11 +KPX a v -11 +KPX a g -7 + +KPX b y -15 +KPX b v -15 +KPX b u -15 +KPX b l -7 + +KPX c y -7 +KPX c l -15 +KPX c k -15 +KPX c h -7 + +KPX colon space -32 + +KPX comma space -32 +KPX comma quoteright -97 +KPX comma quotedblright -97 + +KPX d y -11 +KPX d w -11 +KPX d v -11 +KPX d d -7 + +KPX e y -11 +KPX e x -11 +KPX e w -11 +KPX e v -11 +KPX e period 16 +KPX e comma 8 + +KPX f quoteright 25 +KPX f quotedblright 25 +KPX f period -7 +KPX f o -15 +KPX f e -7 +KPX f comma -7 + +KPX g g -7 +KPX g e 8 + +KPX h y -15 + +KPX k o -11 + +KPX l y -11 +KPX l w -11 + +KPX m y -24 +KPX m u -15 + +KPX n y -15 +KPX n v -32 +KPX n u -7 + +KPX o y -15 +KPX o x -24 +KPX o w -11 +KPX o v -15 + +KPX p y -11 + +KPX period space -32 +KPX period quoteright -97 +KPX period quotedblright -97 + +KPX quotedblright space -65 + +KPX quoteleft quoteleft -37 + +KPX quoteright v -15 +KPX quoteright space -65 +KPX quoteright s -48 +KPX quoteright r -32 +KPX quoteright quoteright -37 +KPX quoteright l -15 +KPX quoteright d -65 + +KPX r y 8 +KPX r v 8 +KPX r t 16 +KPX r s -11 +KPX r q -15 +KPX r period -48 +KPX r o -15 +KPX r hyphen -15 +KPX r g -11 +KPX r d -15 +KPX r comma -48 +KPX r c -15 + +KPX s w -11 + +KPX semicolon space -32 + +KPX space quoteleft -48 +KPX space quotedblleft -65 +KPX space Y -97 +KPX space W -65 +KPX space V -65 +KPX space T -81 + +KPX v period -65 +KPX v o -24 +KPX v comma -65 +KPX v a -15 + +KPX w period -32 +KPX w o -15 +KPX w comma -32 + +KPX x e -7 + +KPX y period -65 +KPX y o -20 +KPX y e -7 +KPX y comma -65 +KPX y a -24 + +KPX z e 8 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 186 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 160 186 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 160 186 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 186 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 160 186 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 160 186 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 186 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 186 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 186 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 186 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 186 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 186 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 186 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 186 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 160 186 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 186 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 186 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 186 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 186 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 186 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 186 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 186 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 186 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 186 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 186 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 186 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 186 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 186 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8a.afm new file mode 100644 index 00000000..b6cff415 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8a.afm @@ -0,0 +1,570 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu Mar 15 10:44:33 1990 +Comment UniqueID 28371 +Comment VMusage 7614 43068 +FontName Helvetica-BoldOblique +FullName Helvetica Bold Oblique +FamilyName Helvetica +Weight Bold +ItalicAngle -12 +IsFixedPitch false +FontBBox -174 -228 1114 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ; +C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ; +C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ; +C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ; +C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ; +C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ; +C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ; +C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ; +C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ; +C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ; +C 43 ; WX 584 ; N plus ; B 82 0 610 506 ; +C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ; +C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ; +C 46 ; WX 278 ; N period ; B 64 0 245 146 ; +C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ; +C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ; +C 49 ; WX 556 ; N one ; B 173 0 529 710 ; +C 50 ; WX 556 ; N two ; B 26 0 619 710 ; +C 51 ; WX 556 ; N three ; B 65 -19 608 710 ; +C 52 ; WX 556 ; N four ; B 60 0 598 710 ; +C 53 ; WX 556 ; N five ; B 64 -19 636 698 ; +C 54 ; WX 556 ; N six ; B 85 -19 619 710 ; +C 55 ; WX 556 ; N seven ; B 125 0 676 698 ; +C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ; +C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 351 512 ; +C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ; +C 60 ; WX 584 ; N less ; B 82 -8 655 514 ; +C 61 ; WX 584 ; N equal ; B 58 87 633 419 ; +C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ; +C 63 ; WX 611 ; N question ; B 165 0 671 727 ; +C 64 ; WX 975 ; N at ; B 186 -19 954 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 764 718 ; +C 67 ; WX 722 ; N C ; B 107 -19 789 737 ; +C 68 ; WX 722 ; N D ; B 76 0 777 718 ; +C 69 ; WX 667 ; N E ; B 76 0 757 718 ; +C 70 ; WX 611 ; N F ; B 76 0 740 718 ; +C 71 ; WX 778 ; N G ; B 108 -19 817 737 ; +C 72 ; WX 722 ; N H ; B 71 0 804 718 ; +C 73 ; WX 278 ; N I ; B 64 0 367 718 ; +C 74 ; WX 556 ; N J ; B 60 -18 637 718 ; +C 75 ; WX 722 ; N K ; B 87 0 858 718 ; +C 76 ; WX 611 ; N L ; B 76 0 611 718 ; +C 77 ; WX 833 ; N M ; B 69 0 918 718 ; +C 78 ; WX 722 ; N N ; B 69 0 807 718 ; +C 79 ; WX 778 ; N O ; B 107 -19 823 737 ; +C 80 ; WX 667 ; N P ; B 76 0 738 718 ; +C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ; +C 82 ; WX 722 ; N R ; B 76 0 778 718 ; +C 83 ; WX 667 ; N S ; B 81 -19 718 737 ; +C 84 ; WX 611 ; N T ; B 140 0 751 718 ; +C 85 ; WX 722 ; N U ; B 116 -19 804 718 ; +C 86 ; WX 667 ; N V ; B 172 0 801 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1082 718 ; +C 88 ; WX 667 ; N X ; B 14 0 791 718 ; +C 89 ; WX 667 ; N Y ; B 168 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 737 718 ; +C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ; +C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ; +C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ; +C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ; +C 97 ; WX 556 ; N a ; B 55 -14 583 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 645 718 ; +C 99 ; WX 556 ; N c ; B 79 -14 599 546 ; +C 100 ; WX 611 ; N d ; B 82 -14 704 718 ; +C 101 ; WX 556 ; N e ; B 70 -14 593 546 ; +C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 38 -217 666 546 ; +C 104 ; WX 611 ; N h ; B 65 0 629 718 ; +C 105 ; WX 278 ; N i ; B 69 0 363 725 ; +C 106 ; WX 278 ; N j ; B -42 -214 363 725 ; +C 107 ; WX 556 ; N k ; B 69 0 670 718 ; +C 108 ; WX 278 ; N l ; B 69 0 362 718 ; +C 109 ; WX 889 ; N m ; B 64 0 909 546 ; +C 110 ; WX 611 ; N n ; B 65 0 629 546 ; +C 111 ; WX 611 ; N o ; B 82 -14 643 546 ; +C 112 ; WX 611 ; N p ; B 18 -207 645 546 ; +C 113 ; WX 611 ; N q ; B 80 -207 665 546 ; +C 114 ; WX 389 ; N r ; B 64 0 489 546 ; +C 115 ; WX 556 ; N s ; B 63 -14 584 546 ; +C 116 ; WX 333 ; N t ; B 100 -6 422 676 ; +C 117 ; WX 611 ; N u ; B 98 -14 658 532 ; +C 118 ; WX 556 ; N v ; B 126 0 656 532 ; +C 119 ; WX 778 ; N w ; B 123 0 882 532 ; +C 120 ; WX 556 ; N x ; B 15 0 648 532 ; +C 121 ; WX 556 ; N y ; B 42 -214 652 532 ; +C 122 ; WX 500 ; N z ; B 20 0 583 532 ; +C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ; +C 124 ; WX 280 ; N bar ; B 80 -19 353 737 ; +C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ; +C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ; +C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ; +C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ; +C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ; +C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ; +C 165 ; WX 556 ; N yen ; B 60 0 713 698 ; +C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ; +C 167 ; WX 556 ; N section ; B 61 -184 598 727 ; +C 168 ; WX 556 ; N currency ; B 27 76 680 636 ; +C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ; +C 174 ; WX 611 ; N fi ; B 87 0 696 727 ; +C 175 ; WX 611 ; N fl ; B 87 0 695 727 ; +C 177 ; WX 556 ; N endash ; B 48 227 627 333 ; +C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ; +C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ; +C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ; +C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ; +C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ; +C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ; +C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ; +C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ; +C 193 ; WX 333 ; N grave ; B 136 604 353 750 ; +C 194 ; WX 333 ; N acute ; B 236 604 515 750 ; +C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ; +C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ; +C 197 ; WX 333 ; N macron ; B 122 604 483 678 ; +C 198 ; WX 333 ; N breve ; B 156 604 494 750 ; +C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ; +C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ; +C 202 ; WX 333 ; N ring ; B 200 568 420 776 ; +C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ; +C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ; +C 207 ; WX 333 ; N caron ; B 149 604 502 750 ; +C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 92 276 465 737 ; +C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ; +C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ; +C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 92 276 485 737 ; +C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ; +C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ; +C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ; +C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ; +C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ; +C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ; +C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ; +C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ; +C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ; +C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ; +C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ; +C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ; +C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ; +C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ; +C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ; +C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ; +C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ; +C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ; +C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ; +C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ; +C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ; +C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ; +C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ; +C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ; +C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ; +C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ; +C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ; +C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ; +C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ; +C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ; +C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ; +C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ; +C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ; +C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ; +C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ; +C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ; +C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ; +C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ; +C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ; +C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ; +C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ; +C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ; +C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ; +C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ; +C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ; +C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ; +C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ; +C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ; +C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ; +C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ; +C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ; +C -1 ; WX 584 ; N minus ; B 82 197 610 309 ; +C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ; +C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ; +C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ; +C -1 ; WX 400 ; N degree ; B 175 426 467 712 ; +C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ; +C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ; +C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ; +C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ; +C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ; +C -1 ; WX 280 ; N brokenbar ; B 80 -19 353 737 ; +C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ; +EndCharMetrics +StartKernData +StartKernPairs 209 + +KPX A y -30 +KPX A w -30 +KPX A v -40 +KPX A u -30 +KPX A Y -110 +KPX A W -60 +KPX A V -80 +KPX A U -50 +KPX A T -90 +KPX A Q -40 +KPX A O -40 +KPX A G -50 +KPX A C -40 + +KPX B U -10 +KPX B A -30 + +KPX D period -30 +KPX D comma -30 +KPX D Y -70 +KPX D W -40 +KPX D V -40 +KPX D A -40 + +KPX F period -100 +KPX F comma -100 +KPX F a -20 +KPX F A -80 + +KPX J u -20 +KPX J period -20 +KPX J comma -20 +KPX J A -20 + +KPX K y -40 +KPX K u -30 +KPX K o -35 +KPX K e -15 +KPX K O -30 + +KPX L y -30 +KPX L quoteright -140 +KPX L quotedblright -140 +KPX L Y -120 +KPX L W -80 +KPX L V -110 +KPX L T -90 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -50 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -50 + +KPX P period -120 +KPX P o -40 +KPX P e -30 +KPX P comma -120 +KPX P a -30 +KPX P A -100 + +KPX Q period 20 +KPX Q comma 20 +KPX Q U -10 + +KPX R Y -50 +KPX R W -40 +KPX R V -50 +KPX R U -20 +KPX R T -20 +KPX R O -20 + +KPX T y -60 +KPX T w -60 +KPX T u -90 +KPX T semicolon -40 +KPX T r -80 +KPX T period -80 +KPX T o -80 +KPX T hyphen -120 +KPX T e -60 +KPX T comma -80 +KPX T colon -40 +KPX T a -80 +KPX T O -40 +KPX T A -90 + +KPX U period -30 +KPX U comma -30 +KPX U A -50 + +KPX V u -60 +KPX V semicolon -40 +KPX V period -120 +KPX V o -90 +KPX V hyphen -80 +KPX V e -50 +KPX V comma -120 +KPX V colon -40 +KPX V a -60 +KPX V O -50 +KPX V G -50 +KPX V A -80 + +KPX W y -20 +KPX W u -45 +KPX W semicolon -10 +KPX W period -80 +KPX W o -60 +KPX W hyphen -40 +KPX W e -35 +KPX W comma -80 +KPX W colon -10 +KPX W a -40 +KPX W O -20 +KPX W A -60 + +KPX Y u -100 +KPX Y semicolon -50 +KPX Y period -100 +KPX Y o -100 +KPX Y e -80 +KPX Y comma -100 +KPX Y colon -50 +KPX Y a -90 +KPX Y O -70 +KPX Y A -110 + +KPX a y -20 +KPX a w -15 +KPX a v -15 +KPX a g -10 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b l -10 + +KPX c y -10 +KPX c l -20 +KPX c k -20 +KPX c h -10 + +KPX colon space -40 + +KPX comma space -40 +KPX comma quoteright -120 +KPX comma quotedblright -120 + +KPX d y -15 +KPX d w -15 +KPX d v -15 +KPX d d -10 + +KPX e y -15 +KPX e x -15 +KPX e w -15 +KPX e v -15 +KPX e period 20 +KPX e comma 10 + +KPX f quoteright 30 +KPX f quotedblright 30 +KPX f period -10 +KPX f o -20 +KPX f e -10 +KPX f comma -10 + +KPX g g -10 +KPX g e 10 + +KPX h y -20 + +KPX k o -15 + +KPX l y -15 +KPX l w -15 + +KPX m y -30 +KPX m u -20 + +KPX n y -20 +KPX n v -40 +KPX n u -10 + +KPX o y -20 +KPX o x -30 +KPX o w -15 +KPX o v -20 + +KPX p y -15 + +KPX period space -40 +KPX period quoteright -120 +KPX period quotedblright -120 + +KPX quotedblright space -80 + +KPX quoteleft quoteleft -46 + +KPX quoteright v -20 +KPX quoteright space -80 +KPX quoteright s -60 +KPX quoteright r -40 +KPX quoteright quoteright -46 +KPX quoteright l -20 +KPX quoteright d -80 + +KPX r y 10 +KPX r v 10 +KPX r t 20 +KPX r s -15 +KPX r q -20 +KPX r period -60 +KPX r o -20 +KPX r hyphen -20 +KPX r g -15 +KPX r d -20 +KPX r comma -60 +KPX r c -20 + +KPX s w -15 + +KPX semicolon space -40 + +KPX space quoteleft -60 +KPX space quotedblleft -80 +KPX space Y -120 +KPX space W -80 +KPX space V -80 +KPX space T -100 + +KPX v period -80 +KPX v o -30 +KPX v comma -80 +KPX v a -20 + +KPX w period -40 +KPX w o -20 +KPX w comma -40 + +KPX x e -10 + +KPX y period -80 +KPX y o -25 +KPX y e -10 +KPX y comma -80 +KPX y a -30 + +KPX z e 10 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 235 186 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 235 186 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 235 186 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 186 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 235 186 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 235 186 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 207 186 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 207 186 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 207 186 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 207 186 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 13 186 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 235 186 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 263 186 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 186 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 263 186 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 263 186 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 186 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 207 186 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 186 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 186 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 186 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 186 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 207 186 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 207 186 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 186 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8an.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8an.afm new file mode 100644 index 00000000..1a380019 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvbo8an.afm @@ -0,0 +1,570 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu Mar 15 12:08:57 1990 +Comment UniqueID 28407 +Comment VMusage 7614 43068 +FontName Helvetica-Narrow-BoldOblique +FullName Helvetica Narrow Bold Oblique +FamilyName Helvetica +Weight Bold +ItalicAngle -12 +IsFixedPitch false +FontBBox -143 -228 913 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 228 ; N space ; B 0 0 0 0 ; +C 33 ; WX 273 ; N exclam ; B 77 0 325 718 ; +C 34 ; WX 389 ; N quotedbl ; B 158 447 433 718 ; +C 35 ; WX 456 ; N numbersign ; B 49 0 528 698 ; +C 36 ; WX 456 ; N dollar ; B 55 -115 510 775 ; +C 37 ; WX 729 ; N percent ; B 112 -19 739 710 ; +C 38 ; WX 592 ; N ampersand ; B 73 -19 600 718 ; +C 39 ; WX 228 ; N quoteright ; B 137 445 297 718 ; +C 40 ; WX 273 ; N parenleft ; B 62 -208 385 734 ; +C 41 ; WX 273 ; N parenright ; B -21 -208 302 734 ; +C 42 ; WX 319 ; N asterisk ; B 120 387 394 718 ; +C 43 ; WX 479 ; N plus ; B 67 0 500 506 ; +C 44 ; WX 228 ; N comma ; B 23 -168 201 146 ; +C 45 ; WX 273 ; N hyphen ; B 60 215 311 345 ; +C 46 ; WX 228 ; N period ; B 52 0 201 146 ; +C 47 ; WX 228 ; N slash ; B -30 -19 383 737 ; +C 48 ; WX 456 ; N zero ; B 71 -19 506 710 ; +C 49 ; WX 456 ; N one ; B 142 0 434 710 ; +C 50 ; WX 456 ; N two ; B 21 0 508 710 ; +C 51 ; WX 456 ; N three ; B 54 -19 499 710 ; +C 52 ; WX 456 ; N four ; B 50 0 490 710 ; +C 53 ; WX 456 ; N five ; B 53 -19 522 698 ; +C 54 ; WX 456 ; N six ; B 70 -19 507 710 ; +C 55 ; WX 456 ; N seven ; B 102 0 555 698 ; +C 56 ; WX 456 ; N eight ; B 57 -19 505 710 ; +C 57 ; WX 456 ; N nine ; B 64 -19 504 710 ; +C 58 ; WX 273 ; N colon ; B 75 0 288 512 ; +C 59 ; WX 273 ; N semicolon ; B 46 -168 288 512 ; +C 60 ; WX 479 ; N less ; B 67 -8 537 514 ; +C 61 ; WX 479 ; N equal ; B 48 87 519 419 ; +C 62 ; WX 479 ; N greater ; B 30 -8 500 514 ; +C 63 ; WX 501 ; N question ; B 135 0 550 727 ; +C 64 ; WX 800 ; N at ; B 152 -19 782 737 ; +C 65 ; WX 592 ; N A ; B 16 0 576 718 ; +C 66 ; WX 592 ; N B ; B 62 0 626 718 ; +C 67 ; WX 592 ; N C ; B 88 -19 647 737 ; +C 68 ; WX 592 ; N D ; B 62 0 637 718 ; +C 69 ; WX 547 ; N E ; B 62 0 620 718 ; +C 70 ; WX 501 ; N F ; B 62 0 606 718 ; +C 71 ; WX 638 ; N G ; B 89 -19 670 737 ; +C 72 ; WX 592 ; N H ; B 58 0 659 718 ; +C 73 ; WX 228 ; N I ; B 52 0 301 718 ; +C 74 ; WX 456 ; N J ; B 49 -18 522 718 ; +C 75 ; WX 592 ; N K ; B 71 0 703 718 ; +C 76 ; WX 501 ; N L ; B 62 0 501 718 ; +C 77 ; WX 683 ; N M ; B 57 0 752 718 ; +C 78 ; WX 592 ; N N ; B 57 0 661 718 ; +C 79 ; WX 638 ; N O ; B 88 -19 675 737 ; +C 80 ; WX 547 ; N P ; B 62 0 605 718 ; +C 81 ; WX 638 ; N Q ; B 88 -52 675 737 ; +C 82 ; WX 592 ; N R ; B 62 0 638 718 ; +C 83 ; WX 547 ; N S ; B 66 -19 588 737 ; +C 84 ; WX 501 ; N T ; B 114 0 615 718 ; +C 85 ; WX 592 ; N U ; B 96 -19 659 718 ; +C 86 ; WX 547 ; N V ; B 141 0 656 718 ; +C 87 ; WX 774 ; N W ; B 138 0 887 718 ; +C 88 ; WX 547 ; N X ; B 11 0 648 718 ; +C 89 ; WX 547 ; N Y ; B 137 0 661 718 ; +C 90 ; WX 501 ; N Z ; B 20 0 604 718 ; +C 91 ; WX 273 ; N bracketleft ; B 17 -196 379 722 ; +C 92 ; WX 228 ; N backslash ; B 101 -19 252 737 ; +C 93 ; WX 273 ; N bracketright ; B -14 -196 347 722 ; +C 94 ; WX 479 ; N asciicircum ; B 107 323 484 698 ; +C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ; +C 96 ; WX 228 ; N quoteleft ; B 136 454 296 727 ; +C 97 ; WX 456 ; N a ; B 45 -14 478 546 ; +C 98 ; WX 501 ; N b ; B 50 -14 529 718 ; +C 99 ; WX 456 ; N c ; B 65 -14 491 546 ; +C 100 ; WX 501 ; N d ; B 67 -14 577 718 ; +C 101 ; WX 456 ; N e ; B 58 -14 486 546 ; +C 102 ; WX 273 ; N f ; B 71 0 385 727 ; L i fi ; L l fl ; +C 103 ; WX 501 ; N g ; B 31 -217 546 546 ; +C 104 ; WX 501 ; N h ; B 53 0 516 718 ; +C 105 ; WX 228 ; N i ; B 57 0 298 725 ; +C 106 ; WX 228 ; N j ; B -35 -214 298 725 ; +C 107 ; WX 456 ; N k ; B 57 0 549 718 ; +C 108 ; WX 228 ; N l ; B 57 0 297 718 ; +C 109 ; WX 729 ; N m ; B 52 0 746 546 ; +C 110 ; WX 501 ; N n ; B 53 0 516 546 ; +C 111 ; WX 501 ; N o ; B 67 -14 527 546 ; +C 112 ; WX 501 ; N p ; B 15 -207 529 546 ; +C 113 ; WX 501 ; N q ; B 66 -207 545 546 ; +C 114 ; WX 319 ; N r ; B 52 0 401 546 ; +C 115 ; WX 456 ; N s ; B 52 -14 479 546 ; +C 116 ; WX 273 ; N t ; B 82 -6 346 676 ; +C 117 ; WX 501 ; N u ; B 80 -14 540 532 ; +C 118 ; WX 456 ; N v ; B 103 0 538 532 ; +C 119 ; WX 638 ; N w ; B 101 0 723 532 ; +C 120 ; WX 456 ; N x ; B 12 0 531 532 ; +C 121 ; WX 456 ; N y ; B 34 -214 535 532 ; +C 122 ; WX 410 ; N z ; B 16 0 478 532 ; +C 123 ; WX 319 ; N braceleft ; B 77 -196 425 722 ; +C 124 ; WX 230 ; N bar ; B 66 -19 289 737 ; +C 125 ; WX 319 ; N braceright ; B -14 -196 333 722 ; +C 126 ; WX 479 ; N asciitilde ; B 94 163 473 343 ; +C 161 ; WX 273 ; N exclamdown ; B 41 -186 290 532 ; +C 162 ; WX 456 ; N cent ; B 65 -118 491 628 ; +C 163 ; WX 456 ; N sterling ; B 41 -16 520 718 ; +C 164 ; WX 137 ; N fraction ; B -143 -19 399 710 ; +C 165 ; WX 456 ; N yen ; B 49 0 585 698 ; +C 166 ; WX 456 ; N florin ; B -41 -210 548 737 ; +C 167 ; WX 456 ; N section ; B 50 -184 491 727 ; +C 168 ; WX 456 ; N currency ; B 22 76 558 636 ; +C 169 ; WX 195 ; N quotesingle ; B 135 447 263 718 ; +C 170 ; WX 410 ; N quotedblleft ; B 132 454 482 727 ; +C 171 ; WX 456 ; N guillemotleft ; B 111 76 468 484 ; +C 172 ; WX 273 ; N guilsinglleft ; B 106 76 289 484 ; +C 173 ; WX 273 ; N guilsinglright ; B 81 76 264 484 ; +C 174 ; WX 501 ; N fi ; B 71 0 571 727 ; +C 175 ; WX 501 ; N fl ; B 71 0 570 727 ; +C 177 ; WX 456 ; N endash ; B 40 227 514 333 ; +C 178 ; WX 456 ; N dagger ; B 97 -171 513 718 ; +C 179 ; WX 456 ; N daggerdbl ; B 38 -171 515 718 ; +C 180 ; WX 228 ; N periodcentered ; B 90 172 226 334 ; +C 182 ; WX 456 ; N paragraph ; B 80 -191 564 700 ; +C 183 ; WX 287 ; N bullet ; B 68 194 345 524 ; +C 184 ; WX 228 ; N quotesinglbase ; B 34 -146 194 127 ; +C 185 ; WX 410 ; N quotedblbase ; B 29 -146 380 127 ; +C 186 ; WX 410 ; N quotedblright ; B 132 445 483 718 ; +C 187 ; WX 456 ; N guillemotright ; B 85 76 443 484 ; +C 188 ; WX 820 ; N ellipsis ; B 75 0 770 146 ; +C 189 ; WX 820 ; N perthousand ; B 62 -19 851 710 ; +C 191 ; WX 501 ; N questiondown ; B 44 -195 459 532 ; +C 193 ; WX 273 ; N grave ; B 112 604 290 750 ; +C 194 ; WX 273 ; N acute ; B 194 604 423 750 ; +C 195 ; WX 273 ; N circumflex ; B 97 604 387 750 ; +C 196 ; WX 273 ; N tilde ; B 92 610 415 737 ; +C 197 ; WX 273 ; N macron ; B 100 604 396 678 ; +C 198 ; WX 273 ; N breve ; B 128 604 405 750 ; +C 199 ; WX 273 ; N dotaccent ; B 192 614 316 729 ; +C 200 ; WX 273 ; N dieresis ; B 112 614 395 729 ; +C 202 ; WX 273 ; N ring ; B 164 568 344 776 ; +C 203 ; WX 273 ; N cedilla ; B -30 -228 180 0 ; +C 205 ; WX 273 ; N hungarumlaut ; B 113 604 529 750 ; +C 206 ; WX 273 ; N ogonek ; B 33 -228 216 0 ; +C 207 ; WX 273 ; N caron ; B 123 604 412 750 ; +C 208 ; WX 820 ; N emdash ; B 40 227 878 333 ; +C 225 ; WX 820 ; N AE ; B 4 0 902 718 ; +C 227 ; WX 303 ; N ordfeminine ; B 75 276 381 737 ; +C 232 ; WX 501 ; N Lslash ; B 28 0 501 718 ; +C 233 ; WX 638 ; N Oslash ; B 29 -27 733 745 ; +C 234 ; WX 820 ; N OE ; B 81 -19 913 737 ; +C 235 ; WX 299 ; N ordmasculine ; B 75 276 398 737 ; +C 241 ; WX 729 ; N ae ; B 46 -14 757 546 ; +C 245 ; WX 228 ; N dotlessi ; B 57 0 264 532 ; +C 248 ; WX 228 ; N lslash ; B 33 0 334 718 ; +C 249 ; WX 501 ; N oslash ; B 18 -29 575 560 ; +C 250 ; WX 774 ; N oe ; B 67 -14 801 546 ; +C 251 ; WX 501 ; N germandbls ; B 57 -14 539 731 ; +C -1 ; WX 501 ; N Zcaron ; B 20 0 604 936 ; +C -1 ; WX 456 ; N ccedilla ; B 65 -228 491 546 ; +C -1 ; WX 456 ; N ydieresis ; B 34 -214 535 729 ; +C -1 ; WX 456 ; N atilde ; B 45 -14 507 737 ; +C -1 ; WX 228 ; N icircumflex ; B 57 0 364 750 ; +C -1 ; WX 273 ; N threesuperior ; B 75 271 361 710 ; +C -1 ; WX 456 ; N ecircumflex ; B 58 -14 486 750 ; +C -1 ; WX 501 ; N thorn ; B 15 -208 529 718 ; +C -1 ; WX 456 ; N egrave ; B 58 -14 486 750 ; +C -1 ; WX 273 ; N twosuperior ; B 57 283 368 710 ; +C -1 ; WX 456 ; N eacute ; B 58 -14 514 750 ; +C -1 ; WX 501 ; N otilde ; B 67 -14 529 737 ; +C -1 ; WX 592 ; N Aacute ; B 16 0 615 936 ; +C -1 ; WX 501 ; N ocircumflex ; B 67 -14 527 750 ; +C -1 ; WX 456 ; N yacute ; B 34 -214 535 750 ; +C -1 ; WX 501 ; N udieresis ; B 80 -14 540 729 ; +C -1 ; WX 684 ; N threequarters ; B 82 -19 688 710 ; +C -1 ; WX 456 ; N acircumflex ; B 45 -14 478 750 ; +C -1 ; WX 592 ; N Eth ; B 51 0 637 718 ; +C -1 ; WX 456 ; N edieresis ; B 58 -14 487 729 ; +C -1 ; WX 501 ; N ugrave ; B 80 -14 540 750 ; +C -1 ; WX 820 ; N trademark ; B 146 306 909 718 ; +C -1 ; WX 501 ; N ograve ; B 67 -14 527 750 ; +C -1 ; WX 456 ; N scaron ; B 52 -14 504 750 ; +C -1 ; WX 228 ; N Idieresis ; B 52 0 405 915 ; +C -1 ; WX 501 ; N uacute ; B 80 -14 540 750 ; +C -1 ; WX 456 ; N agrave ; B 45 -14 478 750 ; +C -1 ; WX 501 ; N ntilde ; B 53 0 529 737 ; +C -1 ; WX 456 ; N aring ; B 45 -14 478 776 ; +C -1 ; WX 410 ; N zcaron ; B 16 0 481 750 ; +C -1 ; WX 228 ; N Icircumflex ; B 52 0 397 936 ; +C -1 ; WX 592 ; N Ntilde ; B 57 0 661 923 ; +C -1 ; WX 501 ; N ucircumflex ; B 80 -14 540 750 ; +C -1 ; WX 547 ; N Ecircumflex ; B 62 0 620 936 ; +C -1 ; WX 228 ; N Iacute ; B 52 0 433 936 ; +C -1 ; WX 592 ; N Ccedilla ; B 88 -228 647 737 ; +C -1 ; WX 638 ; N Odieresis ; B 88 -19 675 915 ; +C -1 ; WX 547 ; N Scaron ; B 66 -19 588 936 ; +C -1 ; WX 547 ; N Edieresis ; B 62 0 620 915 ; +C -1 ; WX 228 ; N Igrave ; B 52 0 301 936 ; +C -1 ; WX 456 ; N adieresis ; B 45 -14 487 729 ; +C -1 ; WX 638 ; N Ograve ; B 88 -19 675 936 ; +C -1 ; WX 547 ; N Egrave ; B 62 0 620 936 ; +C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 915 ; +C -1 ; WX 604 ; N registered ; B 45 -19 684 737 ; +C -1 ; WX 638 ; N Otilde ; B 88 -19 675 923 ; +C -1 ; WX 684 ; N onequarter ; B 108 -19 661 710 ; +C -1 ; WX 592 ; N Ugrave ; B 96 -19 659 936 ; +C -1 ; WX 592 ; N Ucircumflex ; B 96 -19 659 936 ; +C -1 ; WX 547 ; N Thorn ; B 62 0 588 718 ; +C -1 ; WX 479 ; N divide ; B 67 -42 500 548 ; +C -1 ; WX 592 ; N Atilde ; B 16 0 608 923 ; +C -1 ; WX 592 ; N Uacute ; B 96 -19 659 936 ; +C -1 ; WX 638 ; N Ocircumflex ; B 88 -19 675 936 ; +C -1 ; WX 479 ; N logicalnot ; B 86 108 519 419 ; +C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ; +C -1 ; WX 228 ; N idieresis ; B 57 0 373 729 ; +C -1 ; WX 228 ; N iacute ; B 57 0 400 750 ; +C -1 ; WX 456 ; N aacute ; B 45 -14 514 750 ; +C -1 ; WX 479 ; N plusminus ; B 33 0 512 506 ; +C -1 ; WX 479 ; N multiply ; B 47 1 520 505 ; +C -1 ; WX 592 ; N Udieresis ; B 96 -19 659 915 ; +C -1 ; WX 479 ; N minus ; B 67 197 500 309 ; +C -1 ; WX 273 ; N onesuperior ; B 121 283 318 710 ; +C -1 ; WX 547 ; N Eacute ; B 62 0 620 936 ; +C -1 ; WX 592 ; N Acircumflex ; B 16 0 579 936 ; +C -1 ; WX 604 ; N copyright ; B 46 -19 685 737 ; +C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ; +C -1 ; WX 501 ; N odieresis ; B 67 -14 527 729 ; +C -1 ; WX 501 ; N oacute ; B 67 -14 537 750 ; +C -1 ; WX 328 ; N degree ; B 143 426 383 712 ; +C -1 ; WX 228 ; N igrave ; B 57 0 268 750 ; +C -1 ; WX 501 ; N mu ; B 18 -207 540 532 ; +C -1 ; WX 638 ; N Oacute ; B 88 -19 675 936 ; +C -1 ; WX 501 ; N eth ; B 67 -14 549 737 ; +C -1 ; WX 592 ; N Adieresis ; B 16 0 588 915 ; +C -1 ; WX 547 ; N Yacute ; B 137 0 661 936 ; +C -1 ; WX 230 ; N brokenbar ; B 66 -19 289 737 ; +C -1 ; WX 684 ; N onehalf ; B 108 -19 704 710 ; +EndCharMetrics +StartKernData +StartKernPairs 209 + +KPX A y -30 +KPX A w -30 +KPX A v -40 +KPX A u -30 +KPX A Y -110 +KPX A W -60 +KPX A V -80 +KPX A U -50 +KPX A T -90 +KPX A Q -40 +KPX A O -40 +KPX A G -50 +KPX A C -40 + +KPX B U -10 +KPX B A -30 + +KPX D period -30 +KPX D comma -30 +KPX D Y -70 +KPX D W -40 +KPX D V -40 +KPX D A -40 + +KPX F period -100 +KPX F comma -100 +KPX F a -20 +KPX F A -80 + +KPX J u -20 +KPX J period -20 +KPX J comma -20 +KPX J A -20 + +KPX K y -40 +KPX K u -30 +KPX K o -35 +KPX K e -15 +KPX K O -30 + +KPX L y -30 +KPX L quoteright -140 +KPX L quotedblright -140 +KPX L Y -120 +KPX L W -80 +KPX L V -110 +KPX L T -90 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -50 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -50 + +KPX P period -120 +KPX P o -40 +KPX P e -30 +KPX P comma -120 +KPX P a -30 +KPX P A -100 + +KPX Q period 20 +KPX Q comma 20 +KPX Q U -10 + +KPX R Y -50 +KPX R W -40 +KPX R V -50 +KPX R U -20 +KPX R T -20 +KPX R O -20 + +KPX T y -60 +KPX T w -60 +KPX T u -90 +KPX T semicolon -40 +KPX T r -80 +KPX T period -80 +KPX T o -80 +KPX T hyphen -120 +KPX T e -60 +KPX T comma -80 +KPX T colon -40 +KPX T a -80 +KPX T O -40 +KPX T A -90 + +KPX U period -30 +KPX U comma -30 +KPX U A -50 + +KPX V u -60 +KPX V semicolon -40 +KPX V period -120 +KPX V o -90 +KPX V hyphen -80 +KPX V e -50 +KPX V comma -120 +KPX V colon -40 +KPX V a -60 +KPX V O -50 +KPX V G -50 +KPX V A -80 + +KPX W y -20 +KPX W u -45 +KPX W semicolon -10 +KPX W period -80 +KPX W o -60 +KPX W hyphen -40 +KPX W e -35 +KPX W comma -80 +KPX W colon -10 +KPX W a -40 +KPX W O -20 +KPX W A -60 + +KPX Y u -100 +KPX Y semicolon -50 +KPX Y period -100 +KPX Y o -100 +KPX Y e -80 +KPX Y comma -100 +KPX Y colon -50 +KPX Y a -90 +KPX Y O -70 +KPX Y A -110 + +KPX a y -20 +KPX a w -15 +KPX a v -15 +KPX a g -10 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b l -10 + +KPX c y -10 +KPX c l -20 +KPX c k -20 +KPX c h -10 + +KPX colon space -40 + +KPX comma space -40 +KPX comma quoteright -120 +KPX comma quotedblright -120 + +KPX d y -15 +KPX d w -15 +KPX d v -15 +KPX d d -10 + +KPX e y -15 +KPX e x -15 +KPX e w -15 +KPX e v -15 +KPX e period 20 +KPX e comma 10 + +KPX f quoteright 30 +KPX f quotedblright 30 +KPX f period -10 +KPX f o -20 +KPX f e -10 +KPX f comma -10 + +KPX g g -10 +KPX g e 10 + +KPX h y -20 + +KPX k o -15 + +KPX l y -15 +KPX l w -15 + +KPX m y -30 +KPX m u -20 + +KPX n y -20 +KPX n v -40 +KPX n u -10 + +KPX o y -20 +KPX o x -30 +KPX o w -15 +KPX o v -20 + +KPX p y -15 + +KPX period space -40 +KPX period quoteright -120 +KPX period quotedblright -120 + +KPX quotedblright space -80 + +KPX quoteleft quoteleft -46 + +KPX quoteright v -20 +KPX quoteright space -80 +KPX quoteright s -60 +KPX quoteright r -40 +KPX quoteright quoteright -46 +KPX quoteright l -20 +KPX quoteright d -80 + +KPX r y 10 +KPX r v 10 +KPX r t 20 +KPX r s -15 +KPX r q -20 +KPX r period -60 +KPX r o -20 +KPX r hyphen -20 +KPX r g -15 +KPX r d -20 +KPX r comma -60 +KPX r c -20 + +KPX s w -15 + +KPX semicolon space -40 + +KPX space quoteleft -60 +KPX space quotedblleft -80 +KPX space Y -120 +KPX space W -80 +KPX space V -80 +KPX space T -100 + +KPX v period -80 +KPX v o -30 +KPX v comma -80 +KPX v a -20 + +KPX w period -40 +KPX w o -20 +KPX w comma -40 + +KPX x e -10 + +KPX y period -80 +KPX y o -25 +KPX y e -10 +KPX y comma -80 +KPX y a -30 + +KPX z e 10 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 186 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 192 186 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 192 186 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 186 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 192 186 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 192 186 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 169 186 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 186 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 169 186 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 169 186 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 186 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 10 186 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 10 186 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 186 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 192 186 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 215 186 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 215 186 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 186 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 215 186 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 186 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 169 186 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 192 186 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 192 186 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 192 186 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 192 186 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 169 186 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 186 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 146 186 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvl8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvl8a.afm new file mode 100644 index 00000000..b02ffacb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvl8a.afm @@ -0,0 +1,445 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date:Mon Jan 11 16:46:06 PST 1988 +FontName Helvetica-Light +EncodingScheme AdobeStandardEncoding +FullName Helvetica Light +FamilyName Helvetica +Weight Light +ItalicAngle 0.0 +IsFixedPitch false +UnderlinePosition -90 +UnderlineThickness 58 +Version 001.002 +Notice Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype Company. +FontBBox -164 -212 1000 979 +CapHeight 720 +XHeight 518 +Descender -204 +Ascender 720 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 130 0 203 720 ; +C 34 ; WX 278 ; N quotedbl ; B 57 494 220 720 ; +C 35 ; WX 556 ; N numbersign ; B 27 0 530 698 ; +C 36 ; WX 556 ; N dollar ; B 37 -95 518 766 ; +C 37 ; WX 889 ; N percent ; B 67 -14 821 705 ; +C 38 ; WX 667 ; N ampersand ; B 41 -19 644 720 ; +C 39 ; WX 222 ; N quoteright ; B 80 495 153 720 ; +C 40 ; WX 333 ; N parenleft ; B 55 -191 277 739 ; +C 41 ; WX 333 ; N parenright ; B 56 -191 278 739 ; +C 42 ; WX 389 ; N asterisk ; B 44 434 344 720 ; +C 43 ; WX 660 ; N plus ; B 80 0 580 500 ; +C 44 ; WX 278 ; N comma ; B 102 -137 175 88 ; +C 45 ; WX 333 ; N hyphen ; B 40 229 293 291 ; +C 46 ; WX 278 ; N period ; B 102 0 175 88 ; +C 47 ; WX 278 ; N slash ; B -3 -90 288 739 ; +C 48 ; WX 556 ; N zero ; B 39 -14 516 705 ; +C 49 ; WX 556 ; N one ; B 120 0 366 705 ; +C 50 ; WX 556 ; N two ; B 48 0 515 705 ; +C 51 ; WX 556 ; N three ; B 34 -14 512 705 ; +C 52 ; WX 556 ; N four ; B 36 0 520 698 ; +C 53 ; WX 556 ; N five ; B 35 -14 506 698 ; +C 54 ; WX 556 ; N six ; B 41 -14 514 705 ; +C 55 ; WX 556 ; N seven ; B 59 0 508 698 ; +C 56 ; WX 556 ; N eight ; B 44 -14 512 705 ; +C 57 ; WX 556 ; N nine ; B 41 -14 515 705 ; +C 58 ; WX 278 ; N colon ; B 102 0 175 492 ; +C 59 ; WX 278 ; N semicolon ; B 102 -137 175 492 ; +C 60 ; WX 660 ; N less ; B 80 -6 580 505 ; +C 61 ; WX 660 ; N equal ; B 80 124 580 378 ; +C 62 ; WX 660 ; N greater ; B 80 -6 580 505 ; +C 63 ; WX 500 ; N question ; B 37 0 472 739 ; +C 64 ; WX 800 ; N at ; B 40 -19 760 739 ; +C 65 ; WX 667 ; N A ; B 15 0 651 720 ; +C 66 ; WX 667 ; N B ; B 81 0 610 720 ; +C 67 ; WX 722 ; N C ; B 48 -19 670 739 ; +C 68 ; WX 722 ; N D ; B 81 0 669 720 ; +C 69 ; WX 611 ; N E ; B 81 0 570 720 ; +C 70 ; WX 556 ; N F ; B 74 0 538 720 ; +C 71 ; WX 778 ; N G ; B 53 -19 695 739 ; +C 72 ; WX 722 ; N H ; B 80 0 642 720 ; +C 73 ; WX 278 ; N I ; B 105 0 173 720 ; +C 74 ; WX 500 ; N J ; B 22 -19 415 720 ; +C 75 ; WX 667 ; N K ; B 85 0 649 720 ; +C 76 ; WX 556 ; N L ; B 81 0 535 720 ; +C 77 ; WX 833 ; N M ; B 78 0 755 720 ; +C 78 ; WX 722 ; N N ; B 79 0 642 720 ; +C 79 ; WX 778 ; N O ; B 53 -19 724 739 ; +C 80 ; WX 611 ; N P ; B 78 0 576 720 ; +C 81 ; WX 778 ; N Q ; B 48 -52 719 739 ; +C 82 ; WX 667 ; N R ; B 80 0 612 720 ; +C 83 ; WX 611 ; N S ; B 43 -19 567 739 ; +C 84 ; WX 556 ; N T ; B 16 0 540 720 ; +C 85 ; WX 722 ; N U ; B 82 -19 640 720 ; +C 86 ; WX 611 ; N V ; B 18 0 593 720 ; +C 87 ; WX 889 ; N W ; B 14 0 875 720 ; +C 88 ; WX 611 ; N X ; B 18 0 592 720 ; +C 89 ; WX 611 ; N Y ; B 12 0 598 720 ; +C 90 ; WX 611 ; N Z ; B 31 0 579 720 ; +C 91 ; WX 333 ; N bracketleft ; B 91 -191 282 739 ; +C 92 ; WX 278 ; N backslash ; B -46 0 324 739 ; +C 93 ; WX 333 ; N bracketright ; B 51 -191 242 739 ; +C 94 ; WX 660 ; N asciicircum ; B 73 245 586 698 ; +C 95 ; WX 500 ; N underscore ; B 0 -119 500 -61 ; +C 96 ; WX 222 ; N quoteleft ; B 69 495 142 720 ; +C 97 ; WX 556 ; N a ; B 46 -14 534 532 ; +C 98 ; WX 611 ; N b ; B 79 -14 555 720 ; +C 99 ; WX 556 ; N c ; B 47 -14 508 532 ; +C 100 ; WX 611 ; N d ; B 56 -14 532 720 ; +C 101 ; WX 556 ; N e ; B 45 -14 511 532 ; +C 102 ; WX 278 ; N f ; B 20 0 257 734 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 56 -212 532 532 ; +C 104 ; WX 556 ; N h ; B 72 0 483 720 ; +C 105 ; WX 222 ; N i ; B 78 0 144 720 ; +C 106 ; WX 222 ; N j ; B 5 -204 151 720 ; +C 107 ; WX 500 ; N k ; B 68 0 487 720 ; +C 108 ; WX 222 ; N l ; B 81 0 141 720 ; +C 109 ; WX 833 ; N m ; B 64 0 768 532 ; +C 110 ; WX 556 ; N n ; B 72 0 483 532 ; +C 111 ; WX 556 ; N o ; B 38 -14 518 532 ; +C 112 ; WX 611 ; N p ; B 79 -204 555 532 ; +C 113 ; WX 611 ; N q ; B 56 -204 532 532 ; +C 114 ; WX 333 ; N r ; B 75 0 306 532 ; +C 115 ; WX 500 ; N s ; B 46 -14 454 532 ; +C 116 ; WX 278 ; N t ; B 20 -14 254 662 ; +C 117 ; WX 556 ; N u ; B 72 -14 483 518 ; +C 118 ; WX 500 ; N v ; B 17 0 483 518 ; +C 119 ; WX 722 ; N w ; B 15 0 707 518 ; +C 120 ; WX 500 ; N x ; B 18 0 481 518 ; +C 121 ; WX 500 ; N y ; B 18 -204 482 518 ; +C 122 ; WX 500 ; N z ; B 33 0 467 518 ; +C 123 ; WX 333 ; N braceleft ; B 45 -191 279 739 ; +C 124 ; WX 222 ; N bar ; B 81 0 141 739 ; +C 125 ; WX 333 ; N braceright ; B 51 -187 285 743 ; +C 126 ; WX 660 ; N asciitilde ; B 80 174 580 339 ; +C 161 ; WX 333 ; N exclamdown ; B 130 -187 203 532 ; +C 162 ; WX 556 ; N cent ; B 45 -141 506 647 ; +C 163 ; WX 556 ; N sterling ; B 25 -14 530 705 ; +C 164 ; WX 167 ; N fraction ; B -164 -14 331 705 ; +C 165 ; WX 556 ; N yen ; B 4 0 552 720 ; +C 166 ; WX 556 ; N florin ; B 13 -196 539 734 ; +C 167 ; WX 556 ; N section ; B 48 -181 508 739 ; +C 168 ; WX 556 ; N currency ; B 27 50 529 553 ; +C 169 ; WX 222 ; N quotesingle ; B 85 494 137 720 ; +C 170 ; WX 389 ; N quotedblleft ; B 86 495 310 720 ; +C 171 ; WX 556 ; N guillemotleft ; B 113 117 443 404 ; +C 172 ; WX 389 ; N guilsinglleft ; B 121 117 267 404 ; +C 173 ; WX 389 ; N guilsinglright ; B 122 117 268 404 ; +C 174 ; WX 500 ; N fi ; B 13 0 435 734 ; +C 175 ; WX 500 ; N fl ; B 13 0 432 734 ; +C 177 ; WX 500 ; N endash ; B 0 238 500 282 ; +C 178 ; WX 556 ; N dagger ; B 37 -166 519 720 ; +C 179 ; WX 556 ; N daggerdbl ; B 37 -166 519 720 ; +C 180 ; WX 278 ; N periodcentered ; B 90 301 187 398 ; +C 182 ; WX 650 ; N paragraph ; B 66 -146 506 720 ; +C 183 ; WX 500 ; N bullet ; B 70 180 430 540 ; +C 184 ; WX 222 ; N quotesinglbase ; B 80 -137 153 88 ; +C 185 ; WX 389 ; N quotedblbase ; B 79 -137 303 88 ; +C 186 ; WX 389 ; N quotedblright ; B 79 495 303 720 ; +C 187 ; WX 556 ; N guillemotright ; B 113 117 443 404 ; +C 188 ; WX 1000 ; N ellipsis ; B 131 0 870 88 ; +C 189 ; WX 1000 ; N perthousand ; B 14 -14 985 705 ; +C 191 ; WX 500 ; N questiondown ; B 28 -207 463 532 ; +C 193 ; WX 333 ; N grave ; B 45 574 234 713 ; +C 194 ; WX 333 ; N acute ; B 109 574 297 713 ; +C 195 ; WX 333 ; N circumflex ; B 24 574 318 713 ; +C 196 ; WX 333 ; N tilde ; B 16 586 329 688 ; +C 197 ; WX 333 ; N macron ; B 23 612 319 657 ; +C 198 ; WX 333 ; N breve ; B 28 580 316 706 ; +C 199 ; WX 333 ; N dotaccent ; B 134 584 199 686 ; +C 200 ; WX 333 ; N dieresis ; B 60 584 284 686 ; +C 202 ; WX 333 ; N ring ; B 67 578 266 777 ; +C 203 ; WX 333 ; N cedilla ; B 54 -207 257 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 109 574 459 713 ; +C 206 ; WX 333 ; N ogonek ; B 74 -190 228 0 ; +C 207 ; WX 333 ; N caron ; B 24 574 318 713 ; +C 208 ; WX 1000 ; N emdash ; B 0 238 1000 282 ; +C 225 ; WX 1000 ; N AE ; B 5 0 960 720 ; +C 227 ; WX 334 ; N ordfeminine ; B 8 307 325 739 ; +C 232 ; WX 556 ; N Lslash ; B 0 0 535 720 ; +C 233 ; WX 778 ; N Oslash ; B 42 -37 736 747 ; +C 234 ; WX 1000 ; N OE ; B 41 -19 967 739 ; +C 235 ; WX 334 ; N ordmasculine ; B 11 307 323 739 ; +C 241 ; WX 889 ; N ae ; B 39 -14 847 532 ; +C 245 ; WX 222 ; N dotlessi ; B 78 0 138 518 ; +C 248 ; WX 222 ; N lslash ; B 10 0 212 720 ; +C 249 ; WX 556 ; N oslash ; B 35 -23 521 541 ; +C 250 ; WX 944 ; N oe ; B 36 -14 904 532 ; +C 251 ; WX 500 ; N germandbls ; B 52 -14 459 734 ; +C -1 ; WX 667 ; N Aacute ; B 15 0 651 915 ; +C -1 ; WX 667 ; N Acircumflex ; B 15 0 651 915 ; +C -1 ; WX 667 ; N Adieresis ; B 15 0 651 888 ; +C -1 ; WX 667 ; N Agrave ; B 15 0 651 915 ; +C -1 ; WX 667 ; N Aring ; B 15 0 651 979 ; +C -1 ; WX 667 ; N Atilde ; B 15 0 651 890 ; +C -1 ; WX 722 ; N Ccedilla ; B 48 -207 670 739 ; +C -1 ; WX 611 ; N Eacute ; B 81 0 570 915 ; +C -1 ; WX 611 ; N Ecircumflex ; B 81 0 570 915 ; +C -1 ; WX 611 ; N Edieresis ; B 81 0 570 888 ; +C -1 ; WX 611 ; N Egrave ; B 81 0 570 915 ; +C -1 ; WX 722 ; N Eth ; B 10 0 669 720 ; +C -1 ; WX 278 ; N Iacute ; B 62 0 250 915 ; +C -1 ; WX 278 ; N Icircumflex ; B -23 0 271 915 ; +C -1 ; WX 278 ; N Idieresis ; B 13 0 237 888 ; +C -1 ; WX 278 ; N Igrave ; B 18 0 207 915 ; +C -1 ; WX 722 ; N Ntilde ; B 79 0 642 890 ; +C -1 ; WX 778 ; N Oacute ; B 53 -19 724 915 ; +C -1 ; WX 778 ; N Ocircumflex ; B 53 -19 724 915 ; +C -1 ; WX 778 ; N Odieresis ; B 53 -19 724 888 ; +C -1 ; WX 778 ; N Ograve ; B 53 -19 724 915 ; +C -1 ; WX 778 ; N Otilde ; B 53 -19 724 890 ; +C -1 ; WX 611 ; N Scaron ; B 43 -19 567 915 ; +C -1 ; WX 611 ; N Thorn ; B 78 0 576 720 ; +C -1 ; WX 722 ; N Uacute ; B 82 -19 640 915 ; +C -1 ; WX 722 ; N Ucircumflex ; B 82 -19 640 915 ; +C -1 ; WX 722 ; N Udieresis ; B 82 -19 640 888 ; +C -1 ; WX 722 ; N Ugrave ; B 82 -19 640 915 ; +C -1 ; WX 611 ; N Yacute ; B 12 0 598 915 ; +C -1 ; WX 611 ; N Ydieresis ; B 12 0 598 888 ; +C -1 ; WX 611 ; N Zcaron ; B 31 0 579 915 ; +C -1 ; WX 556 ; N aacute ; B 46 -14 534 713 ; +C -1 ; WX 556 ; N acircumflex ; B 46 -14 534 713 ; +C -1 ; WX 556 ; N adieresis ; B 46 -14 534 686 ; +C -1 ; WX 556 ; N agrave ; B 46 -14 534 713 ; +C -1 ; WX 556 ; N aring ; B 46 -14 534 777 ; +C -1 ; WX 556 ; N atilde ; B 46 -14 534 688 ; +C -1 ; WX 222 ; N brokenbar ; B 81 0 141 739 ; +C -1 ; WX 556 ; N ccedilla ; B 47 -207 508 532 ; +C -1 ; WX 800 ; N copyright ; B 21 -19 779 739 ; +C -1 ; WX 400 ; N degree ; B 50 405 350 705 ; +C -1 ; WX 660 ; N divide ; B 80 0 580 500 ; +C -1 ; WX 556 ; N eacute ; B 45 -14 511 713 ; +C -1 ; WX 556 ; N ecircumflex ; B 45 -14 511 713 ; +C -1 ; WX 556 ; N edieresis ; B 45 -14 511 686 ; +C -1 ; WX 556 ; N egrave ; B 45 -14 511 713 ; +C -1 ; WX 556 ; N eth ; B 38 -14 518 739 ; +C -1 ; WX 222 ; N iacute ; B 34 0 222 713 ; +C -1 ; WX 222 ; N icircumflex ; B -51 0 243 713 ; +C -1 ; WX 222 ; N idieresis ; B -15 0 209 686 ; +C -1 ; WX 222 ; N igrave ; B -10 0 179 713 ; +C -1 ; WX 660 ; N logicalnot ; B 80 112 580 378 ; +C -1 ; WX 660 ; N minus ; B 80 220 580 280 ; +C -1 ; WX 556 ; N mu ; B 72 -204 483 518 ; +C -1 ; WX 660 ; N multiply ; B 83 6 578 500 ; +C -1 ; WX 556 ; N ntilde ; B 72 0 483 688 ; +C -1 ; WX 556 ; N oacute ; B 38 -14 518 713 ; +C -1 ; WX 556 ; N ocircumflex ; B 38 -14 518 713 ; +C -1 ; WX 556 ; N odieresis ; B 38 -14 518 686 ; +C -1 ; WX 556 ; N ograve ; B 38 -14 518 713 ; +C -1 ; WX 834 ; N onehalf ; B 40 -14 794 739 ; +C -1 ; WX 834 ; N onequarter ; B 40 -14 794 739 ; +C -1 ; WX 333 ; N onesuperior ; B 87 316 247 739 ; +C -1 ; WX 556 ; N otilde ; B 38 -14 518 688 ; +C -1 ; WX 660 ; N plusminus ; B 80 0 580 500 ; +C -1 ; WX 800 ; N registered ; B 21 -19 779 739 ; +C -1 ; WX 500 ; N scaron ; B 46 -14 454 713 ; +C -1 ; WX 611 ; N thorn ; B 79 -204 555 720 ; +C -1 ; WX 834 ; N threequarters ; B 40 -14 794 739 ; +C -1 ; WX 333 ; N threesuperior ; B 11 308 322 739 ; +C -1 ; WX 940 ; N trademark ; B 29 299 859 720 ; +C -1 ; WX 333 ; N twosuperior ; B 15 316 318 739 ; +C -1 ; WX 556 ; N uacute ; B 72 -14 483 713 ; +C -1 ; WX 556 ; N ucircumflex ; B 72 -14 483 713 ; +C -1 ; WX 556 ; N udieresis ; B 72 -14 483 686 ; +C -1 ; WX 556 ; N ugrave ; B 72 -14 483 713 ; +C -1 ; WX 500 ; N yacute ; B 18 -204 482 713 ; +C -1 ; WX 500 ; N ydieresis ; B 18 -204 482 686 ; +C -1 ; WX 500 ; N zcaron ; B 33 0 467 713 ; +EndCharMetrics +StartKernData +StartKernPairs 115 + +KPX A y -18 +KPX A w -18 +KPX A v -18 +KPX A quoteright -74 +KPX A Y -74 +KPX A W -37 +KPX A V -74 +KPX A T -92 + +KPX F period -129 +KPX F comma -129 +KPX F A -55 + +KPX L y -37 +KPX L quoteright -74 +KPX L Y -111 +KPX L W -55 +KPX L V -92 +KPX L T -92 + +KPX P period -129 +KPX P comma -129 +KPX P A -74 + +KPX R y 0 +KPX R Y -37 +KPX R W -18 +KPX R V -18 +KPX R T -18 + +KPX T y -84 +KPX T w -84 +KPX T u -92 +KPX T semicolon -111 +KPX T s -111 +KPX T r -92 +KPX T period -111 +KPX T o -111 +KPX T i 0 +KPX T hyphen -129 +KPX T e -111 +KPX T comma -111 +KPX T colon -111 +KPX T c -111 +KPX T a -111 +KPX T A -92 + +KPX V y -18 +KPX V u -37 +KPX V semicolon -74 +KPX V r -37 +KPX V period -129 +KPX V o -55 +KPX V i -18 +KPX V hyphen -55 +KPX V e -55 +KPX V comma -129 +KPX V colon -74 +KPX V a -55 +KPX V A -74 + +KPX W y 0 +KPX W u -18 +KPX W semicolon -18 +KPX W r -18 +KPX W period -74 +KPX W o -18 +KPX W i 0 +KPX W hyphen 0 +KPX W e -18 +KPX W comma -74 +KPX W colon -18 +KPX W a -37 +KPX W A -37 + +KPX Y v -40 +KPX Y u -37 +KPX Y semicolon -92 +KPX Y q -92 +KPX Y period -111 +KPX Y p -37 +KPX Y o -92 +KPX Y i -20 +KPX Y hyphen -111 +KPX Y e -92 +KPX Y comma -111 +KPX Y colon -92 +KPX Y a -92 +KPX Y A -74 + +KPX f quoteright 18 +KPX f f -18 + +KPX quoteleft quoteleft -18 + +KPX quoteright t -18 +KPX quoteright s -74 +KPX quoteright quoteright -18 + +KPX r z 0 +KPX r y 18 +KPX r x 0 +KPX r w 0 +KPX r v 0 +KPX r u 0 +KPX r t 18 +KPX r r 0 +KPX r quoteright 0 +KPX r q -18 +KPX r period -92 +KPX r o -18 +KPX r n 18 +KPX r m 18 +KPX r hyphen -55 +KPX r h 0 +KPX r g 0 +KPX r f 18 +KPX r e -18 +KPX r d -18 +KPX r comma -92 +KPX r c -18 + +KPX v period -74 +KPX v comma -74 + +KPX w period -55 +KPX w comma -55 + +KPX y period -92 +KPX y comma -92 +EndKernPairs +EndKernData +StartComposites 58 +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 202 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 202 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 139 202 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 83 0 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 202 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 202 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 202 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 202 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 202 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -47 202 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -47 202 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -47 202 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 202 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -75 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -75 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -75 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 202 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 202 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 202 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 202 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ; +CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 202 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 202 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 202 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 202 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 202 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 202 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 202 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 202 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 202 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 202 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 202 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 187 202 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvlo8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvlo8a.afm new file mode 100644 index 00000000..96612d12 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvlo8a.afm @@ -0,0 +1,445 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date:Mon Jan 11 17:38:44 PST 1988 +FontName Helvetica-LightOblique +EncodingScheme AdobeStandardEncoding +FullName Helvetica Light Oblique +FamilyName Helvetica +Weight Light +ItalicAngle -12.0 +IsFixedPitch false +UnderlinePosition -90 +UnderlineThickness 58 +Version 001.002 +Notice Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype Company. +FontBBox -167 -212 1110 979 +CapHeight 720 +XHeight 518 +Descender -204 +Ascender 720 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 130 0 356 720 ; +C 34 ; WX 278 ; N quotedbl ; B 162 494 373 720 ; +C 35 ; WX 556 ; N numbersign ; B 75 0 633 698 ; +C 36 ; WX 556 ; N dollar ; B 75 -95 613 766 ; +C 37 ; WX 889 ; N percent ; B 176 -14 860 705 ; +C 38 ; WX 667 ; N ampersand ; B 77 -19 646 720 ; +C 39 ; WX 222 ; N quoteright ; B 185 495 306 720 ; +C 40 ; WX 333 ; N parenleft ; B 97 -191 434 739 ; +C 41 ; WX 333 ; N parenright ; B 15 -191 353 739 ; +C 42 ; WX 389 ; N asterisk ; B 172 434 472 720 ; +C 43 ; WX 660 ; N plus ; B 127 0 640 500 ; +C 44 ; WX 278 ; N comma ; B 73 -137 194 88 ; +C 45 ; WX 333 ; N hyphen ; B 89 229 355 291 ; +C 46 ; WX 278 ; N period ; B 102 0 194 88 ; +C 47 ; WX 278 ; N slash ; B -22 -90 445 739 ; +C 48 ; WX 556 ; N zero ; B 93 -14 609 705 ; +C 49 ; WX 556 ; N one ; B 231 0 516 705 ; +C 50 ; WX 556 ; N two ; B 48 0 628 705 ; +C 51 ; WX 556 ; N three ; B 74 -14 605 705 ; +C 52 ; WX 556 ; N four ; B 73 0 570 698 ; +C 53 ; WX 556 ; N five ; B 71 -14 616 698 ; +C 54 ; WX 556 ; N six ; B 94 -14 617 705 ; +C 55 ; WX 556 ; N seven ; B 152 0 656 698 ; +C 56 ; WX 556 ; N eight ; B 80 -14 601 705 ; +C 57 ; WX 556 ; N nine ; B 84 -14 607 705 ; +C 58 ; WX 278 ; N colon ; B 102 0 280 492 ; +C 59 ; WX 278 ; N semicolon ; B 73 -137 280 492 ; +C 60 ; WX 660 ; N less ; B 129 -6 687 505 ; +C 61 ; WX 660 ; N equal ; B 106 124 660 378 ; +C 62 ; WX 660 ; N greater ; B 79 -6 640 505 ; +C 63 ; WX 500 ; N question ; B 148 0 594 739 ; +C 64 ; WX 800 ; N at ; B 108 -19 857 739 ; +C 65 ; WX 667 ; N A ; B 15 0 651 720 ; +C 66 ; WX 667 ; N B ; B 81 0 697 720 ; +C 67 ; WX 722 ; N C ; B 111 -19 771 739 ; +C 68 ; WX 722 ; N D ; B 81 0 758 720 ; +C 69 ; WX 611 ; N E ; B 81 0 713 720 ; +C 70 ; WX 556 ; N F ; B 74 0 691 720 ; +C 71 ; WX 778 ; N G ; B 116 -19 796 739 ; +C 72 ; WX 722 ; N H ; B 80 0 795 720 ; +C 73 ; WX 278 ; N I ; B 105 0 326 720 ; +C 74 ; WX 500 ; N J ; B 58 -19 568 720 ; +C 75 ; WX 667 ; N K ; B 85 0 752 720 ; +C 76 ; WX 556 ; N L ; B 81 0 547 720 ; +C 77 ; WX 833 ; N M ; B 78 0 908 720 ; +C 78 ; WX 722 ; N N ; B 79 0 795 720 ; +C 79 ; WX 778 ; N O ; B 117 -19 812 739 ; +C 80 ; WX 611 ; N P ; B 78 0 693 720 ; +C 81 ; WX 778 ; N Q ; B 112 -52 808 739 ; +C 82 ; WX 667 ; N R ; B 80 0 726 720 ; +C 83 ; WX 611 ; N S ; B 82 -19 663 739 ; +C 84 ; WX 556 ; N T ; B 157 0 693 720 ; +C 85 ; WX 722 ; N U ; B 129 -19 793 720 ; +C 86 ; WX 611 ; N V ; B 171 0 746 720 ; +C 87 ; WX 889 ; N W ; B 167 0 1028 720 ; +C 88 ; WX 611 ; N X ; B 18 0 734 720 ; +C 89 ; WX 611 ; N Y ; B 165 0 751 720 ; +C 90 ; WX 611 ; N Z ; B 31 0 729 720 ; +C 91 ; WX 333 ; N bracketleft ; B 50 -191 439 739 ; +C 92 ; WX 278 ; N backslash ; B 111 0 324 739 ; +C 93 ; WX 333 ; N bracketright ; B 10 -191 399 739 ; +C 94 ; WX 660 ; N asciicircum ; B 125 245 638 698 ; +C 95 ; WX 500 ; N underscore ; B -25 -119 487 -61 ; +C 96 ; WX 222 ; N quoteleft ; B 174 495 295 720 ; +C 97 ; WX 556 ; N a ; B 71 -14 555 532 ; +C 98 ; WX 611 ; N b ; B 79 -14 619 720 ; +C 99 ; WX 556 ; N c ; B 92 -14 576 532 ; +C 100 ; WX 611 ; N d ; B 101 -14 685 720 ; +C 101 ; WX 556 ; N e ; B 90 -14 575 532 ; +C 102 ; WX 278 ; N f ; B 97 0 412 734 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 56 -212 642 532 ; +C 104 ; WX 556 ; N h ; B 72 0 565 720 ; +C 105 ; WX 222 ; N i ; B 81 0 297 720 ; +C 106 ; WX 222 ; N j ; B -38 -204 304 720 ; +C 107 ; WX 500 ; N k ; B 68 0 574 720 ; +C 108 ; WX 222 ; N l ; B 81 0 294 720 ; +C 109 ; WX 833 ; N m ; B 64 0 848 532 ; +C 110 ; WX 556 ; N n ; B 72 0 565 532 ; +C 111 ; WX 556 ; N o ; B 84 -14 582 532 ; +C 112 ; WX 611 ; N p ; B 36 -204 620 532 ; +C 113 ; WX 611 ; N q ; B 102 -204 642 532 ; +C 114 ; WX 333 ; N r ; B 75 0 419 532 ; +C 115 ; WX 500 ; N s ; B 78 -14 519 532 ; +C 116 ; WX 278 ; N t ; B 108 -14 360 662 ; +C 117 ; WX 556 ; N u ; B 103 -14 593 518 ; +C 118 ; WX 500 ; N v ; B 127 0 593 518 ; +C 119 ; WX 722 ; N w ; B 125 0 817 518 ; +C 120 ; WX 500 ; N x ; B 18 0 584 518 ; +C 121 ; WX 500 ; N y ; B 26 -204 592 518 ; +C 122 ; WX 500 ; N z ; B 33 0 564 518 ; +C 123 ; WX 333 ; N braceleft ; B 103 -191 436 739 ; +C 124 ; WX 222 ; N bar ; B 81 0 298 739 ; +C 125 ; WX 333 ; N braceright ; B 12 -187 344 743 ; +C 126 ; WX 660 ; N asciitilde ; B 127 174 645 339 ; +C 161 ; WX 333 ; N exclamdown ; B 90 -187 316 532 ; +C 162 ; WX 556 ; N cent ; B 90 -141 574 647 ; +C 163 ; WX 556 ; N sterling ; B 51 -14 613 705 ; +C 164 ; WX 167 ; N fraction ; B -167 -14 481 705 ; +C 165 ; WX 556 ; N yen ; B 110 0 705 720 ; +C 166 ; WX 556 ; N florin ; B -26 -196 691 734 ; +C 167 ; WX 556 ; N section ; B 91 -181 581 739 ; +C 168 ; WX 556 ; N currency ; B 55 50 629 553 ; +C 169 ; WX 222 ; N quotesingle ; B 190 494 290 720 ; +C 170 ; WX 389 ; N quotedblleft ; B 191 495 463 720 ; +C 171 ; WX 556 ; N guillemotleft ; B 161 117 529 404 ; +C 172 ; WX 389 ; N guilsinglleft ; B 169 117 353 404 ; +C 173 ; WX 389 ; N guilsinglright ; B 147 117 330 404 ; +C 174 ; WX 500 ; N fi ; B 92 0 588 734 ; +C 175 ; WX 500 ; N fl ; B 92 0 585 734 ; +C 177 ; WX 500 ; N endash ; B 51 238 560 282 ; +C 178 ; WX 556 ; N dagger ; B 130 -166 623 720 ; +C 179 ; WX 556 ; N daggerdbl ; B 49 -166 625 720 ; +C 180 ; WX 278 ; N periodcentered ; B 163 301 262 398 ; +C 182 ; WX 650 ; N paragraph ; B 174 -146 659 720 ; +C 183 ; WX 500 ; N bullet ; B 142 180 510 540 ; +C 184 ; WX 222 ; N quotesinglbase ; B 51 -137 172 88 ; +C 185 ; WX 389 ; N quotedblbase ; B 50 -137 322 88 ; +C 186 ; WX 389 ; N quotedblright ; B 184 495 456 720 ; +C 187 ; WX 556 ; N guillemotright ; B 138 117 505 404 ; +C 188 ; WX 1000 ; N ellipsis ; B 131 0 889 88 ; +C 189 ; WX 1000 ; N perthousand ; B 83 -14 1020 705 ; +C 191 ; WX 500 ; N questiondown ; B 19 -207 465 532 ; +C 193 ; WX 333 ; N grave ; B 197 574 356 713 ; +C 194 ; WX 333 ; N acute ; B 231 574 449 713 ; +C 195 ; WX 333 ; N circumflex ; B 146 574 440 713 ; +C 196 ; WX 333 ; N tilde ; B 141 586 475 688 ; +C 197 ; WX 333 ; N macron ; B 153 612 459 657 ; +C 198 ; WX 333 ; N breve ; B 177 580 466 706 ; +C 199 ; WX 333 ; N dotaccent ; B 258 584 345 686 ; +C 200 ; WX 333 ; N dieresis ; B 184 584 430 686 ; +C 202 ; WX 333 ; N ring ; B 209 578 412 777 ; +C 203 ; WX 333 ; N cedilla ; B 14 -207 233 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 231 574 611 713 ; +C 206 ; WX 333 ; N ogonek ; B 50 -190 199 0 ; +C 207 ; WX 333 ; N caron ; B 176 574 470 713 ; +C 208 ; WX 1000 ; N emdash ; B 51 238 1060 282 ; +C 225 ; WX 1000 ; N AE ; B 5 0 1101 720 ; +C 227 ; WX 334 ; N ordfeminine ; B 73 307 423 739 ; +C 232 ; WX 556 ; N Lslash ; B 68 0 547 720 ; +C 233 ; WX 778 ; N Oslash ; B 41 -37 887 747 ; +C 234 ; WX 1000 ; N OE ; B 104 -19 1110 739 ; +C 235 ; WX 334 ; N ordmasculine ; B 76 307 450 739 ; +C 241 ; WX 889 ; N ae ; B 63 -14 913 532 ; +C 245 ; WX 222 ; N dotlessi ; B 78 0 248 518 ; +C 248 ; WX 222 ; N lslash ; B 74 0 316 720 ; +C 249 ; WX 556 ; N oslash ; B 36 -23 629 541 ; +C 250 ; WX 944 ; N oe ; B 82 -14 970 532 ; +C 251 ; WX 500 ; N germandbls ; B 52 -14 554 734 ; +C -1 ; WX 667 ; N Aacute ; B 15 0 659 915 ; +C -1 ; WX 667 ; N Acircumflex ; B 15 0 651 915 ; +C -1 ; WX 667 ; N Adieresis ; B 15 0 651 888 ; +C -1 ; WX 667 ; N Agrave ; B 15 0 651 915 ; +C -1 ; WX 667 ; N Aring ; B 15 0 651 979 ; +C -1 ; WX 667 ; N Atilde ; B 15 0 685 890 ; +C -1 ; WX 722 ; N Ccedilla ; B 111 -207 771 739 ; +C -1 ; WX 611 ; N Eacute ; B 81 0 713 915 ; +C -1 ; WX 611 ; N Ecircumflex ; B 81 0 713 915 ; +C -1 ; WX 611 ; N Edieresis ; B 81 0 713 888 ; +C -1 ; WX 611 ; N Egrave ; B 81 0 713 915 ; +C -1 ; WX 722 ; N Eth ; B 81 0 758 720 ; +C -1 ; WX 278 ; N Iacute ; B 105 0 445 915 ; +C -1 ; WX 278 ; N Icircumflex ; B 105 0 436 915 ; +C -1 ; WX 278 ; N Idieresis ; B 105 0 426 888 ; +C -1 ; WX 278 ; N Igrave ; B 105 0 372 915 ; +C -1 ; WX 722 ; N Ntilde ; B 79 0 795 890 ; +C -1 ; WX 778 ; N Oacute ; B 117 -19 812 915 ; +C -1 ; WX 778 ; N Ocircumflex ; B 117 -19 812 915 ; +C -1 ; WX 778 ; N Odieresis ; B 117 -19 812 888 ; +C -1 ; WX 778 ; N Ograve ; B 117 -19 812 915 ; +C -1 ; WX 778 ; N Otilde ; B 117 -19 812 890 ; +C -1 ; WX 611 ; N Scaron ; B 82 -19 663 915 ; +C -1 ; WX 611 ; N Thorn ; B 78 0 661 720 ; +C -1 ; WX 722 ; N Uacute ; B 129 -19 793 915 ; +C -1 ; WX 722 ; N Ucircumflex ; B 129 -19 793 915 ; +C -1 ; WX 722 ; N Udieresis ; B 129 -19 793 888 ; +C -1 ; WX 722 ; N Ugrave ; B 129 -19 793 915 ; +C -1 ; WX 611 ; N Yacute ; B 165 0 751 915 ; +C -1 ; WX 611 ; N Ydieresis ; B 165 0 751 888 ; +C -1 ; WX 611 ; N Zcaron ; B 31 0 729 915 ; +C -1 ; WX 556 ; N aacute ; B 71 -14 561 713 ; +C -1 ; WX 556 ; N acircumflex ; B 71 -14 555 713 ; +C -1 ; WX 556 ; N adieresis ; B 71 -14 555 686 ; +C -1 ; WX 556 ; N agrave ; B 71 -14 555 713 ; +C -1 ; WX 556 ; N aring ; B 71 -14 555 777 ; +C -1 ; WX 556 ; N atilde ; B 71 -14 587 688 ; +C -1 ; WX 222 ; N brokenbar ; B 81 0 298 739 ; +C -1 ; WX 556 ; N ccedilla ; B 92 -207 576 532 ; +C -1 ; WX 800 ; N copyright ; B 89 -19 864 739 ; +C -1 ; WX 400 ; N degree ; B 165 405 471 705 ; +C -1 ; WX 660 ; N divide ; B 127 0 640 500 ; +C -1 ; WX 556 ; N eacute ; B 90 -14 575 713 ; +C -1 ; WX 556 ; N ecircumflex ; B 90 -14 575 713 ; +C -1 ; WX 556 ; N edieresis ; B 90 -14 575 686 ; +C -1 ; WX 556 ; N egrave ; B 90 -14 575 713 ; +C -1 ; WX 556 ; N eth ; B 84 -14 582 739 ; +C -1 ; WX 222 ; N iacute ; B 78 0 374 713 ; +C -1 ; WX 222 ; N icircumflex ; B 71 0 365 713 ; +C -1 ; WX 222 ; N idieresis ; B 78 0 355 686 ; +C -1 ; WX 222 ; N igrave ; B 78 0 301 713 ; +C -1 ; WX 660 ; N logicalnot ; B 148 112 660 378 ; +C -1 ; WX 660 ; N minus ; B 127 220 640 280 ; +C -1 ; WX 556 ; N mu ; B 29 -204 593 518 ; +C -1 ; WX 660 ; N multiply ; B 92 6 677 500 ; +C -1 ; WX 556 ; N ntilde ; B 72 0 587 688 ; +C -1 ; WX 556 ; N oacute ; B 84 -14 582 713 ; +C -1 ; WX 556 ; N ocircumflex ; B 84 -14 582 713 ; +C -1 ; WX 556 ; N odieresis ; B 84 -14 582 686 ; +C -1 ; WX 556 ; N ograve ; B 84 -14 582 713 ; +C -1 ; WX 834 ; N onehalf ; B 125 -14 862 739 ; +C -1 ; WX 834 ; N onequarter ; B 165 -14 823 739 ; +C -1 ; WX 333 ; N onesuperior ; B 221 316 404 739 ; +C -1 ; WX 556 ; N otilde ; B 84 -14 587 688 ; +C -1 ; WX 660 ; N plusminus ; B 80 0 650 500 ; +C -1 ; WX 800 ; N registered ; B 89 -19 864 739 ; +C -1 ; WX 500 ; N scaron ; B 78 -14 554 713 ; +C -1 ; WX 611 ; N thorn ; B 36 -204 620 720 ; +C -1 ; WX 834 ; N threequarters ; B 131 -14 853 739 ; +C -1 ; WX 333 ; N threesuperior ; B 102 308 444 739 ; +C -1 ; WX 940 ; N trademark ; B 174 299 1012 720 ; +C -1 ; WX 333 ; N twosuperior ; B 82 316 453 739 ; +C -1 ; WX 556 ; N uacute ; B 103 -14 593 713 ; +C -1 ; WX 556 ; N ucircumflex ; B 103 -14 593 713 ; +C -1 ; WX 556 ; N udieresis ; B 103 -14 593 686 ; +C -1 ; WX 556 ; N ugrave ; B 103 -14 593 713 ; +C -1 ; WX 500 ; N yacute ; B 26 -204 592 713 ; +C -1 ; WX 500 ; N ydieresis ; B 26 -204 592 686 ; +C -1 ; WX 500 ; N zcaron ; B 33 0 564 713 ; +EndCharMetrics +StartKernData +StartKernPairs 115 + +KPX A y -18 +KPX A w -18 +KPX A v -18 +KPX A quoteright -74 +KPX A Y -74 +KPX A W -37 +KPX A V -74 +KPX A T -92 + +KPX F period -129 +KPX F comma -129 +KPX F A -55 + +KPX L y -37 +KPX L quoteright -74 +KPX L Y -111 +KPX L W -55 +KPX L V -92 +KPX L T -92 + +KPX P period -129 +KPX P comma -129 +KPX P A -74 + +KPX R y 0 +KPX R Y -37 +KPX R W -18 +KPX R V -18 +KPX R T -18 + +KPX T y -84 +KPX T w -84 +KPX T u -92 +KPX T semicolon -111 +KPX T s -111 +KPX T r -92 +KPX T period -111 +KPX T o -111 +KPX T i 0 +KPX T hyphen -129 +KPX T e -111 +KPX T comma -111 +KPX T colon -111 +KPX T c -111 +KPX T a -111 +KPX T A -92 + +KPX V y -18 +KPX V u -37 +KPX V semicolon -74 +KPX V r -37 +KPX V period -129 +KPX V o -55 +KPX V i -18 +KPX V hyphen -55 +KPX V e -55 +KPX V comma -129 +KPX V colon -74 +KPX V a -55 +KPX V A -74 + +KPX W y 0 +KPX W u -18 +KPX W semicolon -18 +KPX W r -18 +KPX W period -74 +KPX W o -18 +KPX W i 0 +KPX W hyphen 0 +KPX W e -18 +KPX W comma -74 +KPX W colon -18 +KPX W a -37 +KPX W A -37 + +KPX Y v -40 +KPX Y u -37 +KPX Y semicolon -92 +KPX Y q -92 +KPX Y period -111 +KPX Y p -37 +KPX Y o -92 +KPX Y i -20 +KPX Y hyphen -111 +KPX Y e -92 +KPX Y comma -111 +KPX Y colon -92 +KPX Y a -92 +KPX Y A -74 + +KPX f quoteright 18 +KPX f f -18 + +KPX quoteleft quoteleft -18 + +KPX quoteright t -18 +KPX quoteright s -74 +KPX quoteright quoteright -18 + +KPX r z 0 +KPX r y 18 +KPX r x 0 +KPX r w 0 +KPX r v 0 +KPX r u 0 +KPX r t 18 +KPX r r 0 +KPX r quoteright 0 +KPX r q -18 +KPX r period -92 +KPX r o -18 +KPX r n 18 +KPX r m 18 +KPX r hyphen -55 +KPX r h 0 +KPX r g 0 +KPX r f 18 +KPX r e -18 +KPX r d -18 +KPX r comma -92 +KPX r c -18 + +KPX v period -74 +KPX v comma -74 + +KPX w period -55 +KPX w comma -55 + +KPX y period -92 +KPX y comma -92 +EndKernPairs +EndKernData +StartComposites 58 +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 202 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 202 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 139 202 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 83 0 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 202 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 202 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 202 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 202 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 202 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -47 202 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -47 202 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -47 202 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 202 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -75 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -75 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -75 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 202 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 202 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 202 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 202 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ; +CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 202 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 202 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 202 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 202 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 202 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 202 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 202 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 202 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 202 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 202 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 202 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 187 202 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm new file mode 100644 index 00000000..1eb3b448 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm @@ -0,0 +1,612 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu Mar 15 08:58:00 1990 +Comment UniqueID 28352 +Comment VMusage 26389 33281 +FontName Helvetica +FullName Helvetica +FamilyName Helvetica +Weight Medium +ItalicAngle 0 +IsFixedPitch false +FontBBox -166 -225 1000 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ; +C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ; +C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ; +C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ; +C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ; +C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ; +C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; +C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ; +C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ; +C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ; +C 43 ; WX 584 ; N plus ; B 39 0 545 505 ; +C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ; +C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ; +C 46 ; WX 278 ; N period ; B 87 0 191 106 ; +C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ; +C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ; +C 49 ; WX 556 ; N one ; B 101 0 359 703 ; +C 50 ; WX 556 ; N two ; B 26 0 507 703 ; +C 51 ; WX 556 ; N three ; B 34 -19 522 703 ; +C 52 ; WX 556 ; N four ; B 25 0 523 703 ; +C 53 ; WX 556 ; N five ; B 32 -19 514 688 ; +C 54 ; WX 556 ; N six ; B 38 -19 518 703 ; +C 55 ; WX 556 ; N seven ; B 37 0 523 688 ; +C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ; +C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 191 516 ; +C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ; +C 60 ; WX 584 ; N less ; B 48 11 536 495 ; +C 61 ; WX 584 ; N equal ; B 39 115 545 390 ; +C 62 ; WX 584 ; N greater ; B 48 11 536 495 ; +C 63 ; WX 556 ; N question ; B 56 0 492 727 ; +C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 627 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 681 737 ; +C 68 ; WX 722 ; N D ; B 81 0 674 718 ; +C 69 ; WX 667 ; N E ; B 86 0 616 718 ; +C 70 ; WX 611 ; N F ; B 86 0 583 718 ; +C 71 ; WX 778 ; N G ; B 48 -19 704 737 ; +C 72 ; WX 722 ; N H ; B 77 0 646 718 ; +C 73 ; WX 278 ; N I ; B 91 0 188 718 ; +C 74 ; WX 500 ; N J ; B 17 -19 428 718 ; +C 75 ; WX 667 ; N K ; B 76 0 663 718 ; +C 76 ; WX 556 ; N L ; B 76 0 537 718 ; +C 77 ; WX 833 ; N M ; B 73 0 761 718 ; +C 78 ; WX 722 ; N N ; B 76 0 646 718 ; +C 79 ; WX 778 ; N O ; B 39 -19 739 737 ; +C 80 ; WX 667 ; N P ; B 86 0 622 718 ; +C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ; +C 82 ; WX 722 ; N R ; B 88 0 684 718 ; +C 83 ; WX 667 ; N S ; B 49 -19 620 737 ; +C 84 ; WX 611 ; N T ; B 14 0 597 718 ; +C 85 ; WX 722 ; N U ; B 79 -19 644 718 ; +C 86 ; WX 667 ; N V ; B 20 0 647 718 ; +C 87 ; WX 944 ; N W ; B 16 0 928 718 ; +C 88 ; WX 667 ; N X ; B 19 0 648 718 ; +C 89 ; WX 667 ; N Y ; B 14 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 588 718 ; +C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ; +C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ; +C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ; +C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ; +C 97 ; WX 556 ; N a ; B 36 -15 530 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 517 718 ; +C 99 ; WX 500 ; N c ; B 30 -15 477 538 ; +C 100 ; WX 556 ; N d ; B 35 -15 499 718 ; +C 101 ; WX 556 ; N e ; B 40 -15 516 538 ; +C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 40 -220 499 538 ; +C 104 ; WX 556 ; N h ; B 65 0 491 718 ; +C 105 ; WX 222 ; N i ; B 67 0 155 718 ; +C 106 ; WX 222 ; N j ; B -16 -210 155 718 ; +C 107 ; WX 500 ; N k ; B 67 0 501 718 ; +C 108 ; WX 222 ; N l ; B 67 0 155 718 ; +C 109 ; WX 833 ; N m ; B 65 0 769 538 ; +C 110 ; WX 556 ; N n ; B 65 0 491 538 ; +C 111 ; WX 556 ; N o ; B 35 -14 521 538 ; +C 112 ; WX 556 ; N p ; B 58 -207 517 538 ; +C 113 ; WX 556 ; N q ; B 35 -207 494 538 ; +C 114 ; WX 333 ; N r ; B 77 0 332 538 ; +C 115 ; WX 500 ; N s ; B 32 -15 464 538 ; +C 116 ; WX 278 ; N t ; B 14 -7 257 669 ; +C 117 ; WX 556 ; N u ; B 68 -15 489 523 ; +C 118 ; WX 500 ; N v ; B 8 0 492 523 ; +C 119 ; WX 722 ; N w ; B 14 0 709 523 ; +C 120 ; WX 500 ; N x ; B 11 0 490 523 ; +C 121 ; WX 500 ; N y ; B 11 -214 489 523 ; +C 122 ; WX 500 ; N z ; B 31 0 469 523 ; +C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ; +C 124 ; WX 260 ; N bar ; B 94 -19 167 737 ; +C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ; +C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ; +C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ; +C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ; +C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ; +C 165 ; WX 556 ; N yen ; B 3 0 553 688 ; +C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ; +C 167 ; WX 556 ; N section ; B 43 -191 512 737 ; +C 168 ; WX 556 ; N currency ; B 28 99 528 603 ; +C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ; +C 174 ; WX 500 ; N fi ; B 14 0 434 728 ; +C 175 ; WX 500 ; N fl ; B 14 0 432 728 ; +C 177 ; WX 556 ; N endash ; B 0 240 556 313 ; +C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ; +C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ; +C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ; +C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ; +C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ; +C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ; +C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ; +C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ; +C 193 ; WX 333 ; N grave ; B 14 593 211 734 ; +C 194 ; WX 333 ; N acute ; B 122 593 319 734 ; +C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ; +C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ; +C 197 ; WX 333 ; N macron ; B 10 627 323 684 ; +C 198 ; WX 333 ; N breve ; B 13 595 321 731 ; +C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ; +C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ; +C 202 ; WX 333 ; N ring ; B 75 572 259 756 ; +C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ; +C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ; +C 207 ; WX 333 ; N caron ; B 21 593 312 734 ; +C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 24 304 346 737 ; +C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ; +C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ; +C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 25 304 341 737 ; +C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ; +C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ; +C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ; +C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ; +C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ; +C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ; +C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ; +C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ; +C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ; +C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ; +C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ; +C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ; +C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ; +C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ; +C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ; +C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ; +C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ; +C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ; +C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ; +C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ; +C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ; +C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ; +C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ; +C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ; +C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ; +C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ; +C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ; +C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ; +C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ; +C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ; +C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ; +C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ; +C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ; +C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ; +C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ; +C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ; +C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ; +C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ; +C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ; +C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ; +C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ; +C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ; +C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ; +C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ; +C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ; +C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ; +C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ; +C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ; +C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ; +C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ; +C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ; +C -1 ; WX 584 ; N minus ; B 39 216 545 289 ; +C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ; +C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ; +C -1 ; WX 400 ; N degree ; B 54 411 346 703 ; +C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ; +C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ; +C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ; +C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ; +C -1 ; WX 260 ; N brokenbar ; B 94 -19 167 737 ; +C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ; +EndCharMetrics +StartKernData +StartKernPairs 250 + +KPX A y -40 +KPX A w -40 +KPX A v -40 +KPX A u -30 +KPX A Y -100 +KPX A W -50 +KPX A V -70 +KPX A U -50 +KPX A T -120 +KPX A Q -30 +KPX A O -30 +KPX A G -30 +KPX A C -30 + +KPX B period -20 +KPX B comma -20 +KPX B U -10 + +KPX C period -30 +KPX C comma -30 + +KPX D period -70 +KPX D comma -70 +KPX D Y -90 +KPX D W -40 +KPX D V -70 +KPX D A -40 + +KPX F r -45 +KPX F period -150 +KPX F o -30 +KPX F e -30 +KPX F comma -150 +KPX F a -50 +KPX F A -80 + +KPX J u -20 +KPX J period -30 +KPX J comma -30 +KPX J a -20 +KPX J A -20 + +KPX K y -50 +KPX K u -30 +KPX K o -40 +KPX K e -40 +KPX K O -50 + +KPX L y -30 +KPX L quoteright -160 +KPX L quotedblright -140 +KPX L Y -140 +KPX L W -70 +KPX L V -110 +KPX L T -110 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -60 +KPX O W -30 +KPX O V -50 +KPX O T -40 +KPX O A -20 + +KPX P period -180 +KPX P o -50 +KPX P e -50 +KPX P comma -180 +KPX P a -40 +KPX P A -120 + +KPX Q U -10 + +KPX R Y -50 +KPX R W -30 +KPX R V -50 +KPX R U -40 +KPX R T -30 +KPX R O -20 + +KPX S period -20 +KPX S comma -20 + +KPX T y -120 +KPX T w -120 +KPX T u -120 +KPX T semicolon -20 +KPX T r -120 +KPX T period -120 +KPX T o -120 +KPX T hyphen -140 +KPX T e -120 +KPX T comma -120 +KPX T colon -20 +KPX T a -120 +KPX T O -40 +KPX T A -120 + +KPX U period -40 +KPX U comma -40 +KPX U A -40 + +KPX V u -70 +KPX V semicolon -40 +KPX V period -125 +KPX V o -80 +KPX V hyphen -80 +KPX V e -80 +KPX V comma -125 +KPX V colon -40 +KPX V a -70 +KPX V O -40 +KPX V G -40 +KPX V A -80 + +KPX W y -20 +KPX W u -30 +KPX W period -80 +KPX W o -30 +KPX W hyphen -40 +KPX W e -30 +KPX W comma -80 +KPX W a -40 +KPX W O -20 +KPX W A -50 + +KPX Y u -110 +KPX Y semicolon -60 +KPX Y period -140 +KPX Y o -140 +KPX Y i -20 +KPX Y hyphen -140 +KPX Y e -140 +KPX Y comma -140 +KPX Y colon -60 +KPX Y a -140 +KPX Y O -85 +KPX Y A -110 + +KPX a y -30 +KPX a w -20 +KPX a v -20 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b period -40 +KPX b l -20 +KPX b comma -40 +KPX b b -10 + +KPX c k -20 +KPX c comma -15 + +KPX colon space -50 + +KPX comma quoteright -100 +KPX comma quotedblright -100 + +KPX e y -20 +KPX e x -30 +KPX e w -20 +KPX e v -30 +KPX e period -15 +KPX e comma -15 + +KPX f quoteright 50 +KPX f quotedblright 60 +KPX f period -30 +KPX f o -30 +KPX f e -30 +KPX f dotlessi -28 +KPX f comma -30 +KPX f a -30 + +KPX g r -10 + +KPX h y -30 + +KPX k o -20 +KPX k e -20 + +KPX m y -15 +KPX m u -10 + +KPX n y -15 +KPX n v -20 +KPX n u -10 + +KPX o y -30 +KPX o x -30 +KPX o w -15 +KPX o v -15 +KPX o period -40 +KPX o comma -40 + +KPX oslash z -55 +KPX oslash y -70 +KPX oslash x -85 +KPX oslash w -70 +KPX oslash v -70 +KPX oslash u -55 +KPX oslash t -55 +KPX oslash s -55 +KPX oslash r -55 +KPX oslash q -55 +KPX oslash period -95 +KPX oslash p -55 +KPX oslash o -55 +KPX oslash n -55 +KPX oslash m -55 +KPX oslash l -55 +KPX oslash k -55 +KPX oslash j -55 +KPX oslash i -55 +KPX oslash h -55 +KPX oslash g -55 +KPX oslash f -55 +KPX oslash e -55 +KPX oslash d -55 +KPX oslash comma -95 +KPX oslash c -55 +KPX oslash b -55 +KPX oslash a -55 + +KPX p y -30 +KPX p period -35 +KPX p comma -35 + +KPX period space -60 +KPX period quoteright -100 +KPX period quotedblright -100 + +KPX quotedblright space -40 + +KPX quoteleft quoteleft -57 + +KPX quoteright space -70 +KPX quoteright s -50 +KPX quoteright r -50 +KPX quoteright quoteright -57 +KPX quoteright d -50 + +KPX r y 30 +KPX r v 30 +KPX r u 15 +KPX r t 40 +KPX r semicolon 30 +KPX r period -50 +KPX r p 30 +KPX r n 25 +KPX r m 25 +KPX r l 15 +KPX r k 15 +KPX r i 15 +KPX r comma -50 +KPX r colon 30 +KPX r a -10 + +KPX s w -30 +KPX s period -15 +KPX s comma -15 + +KPX semicolon space -50 + +KPX space quoteleft -60 +KPX space quotedblleft -30 +KPX space Y -90 +KPX space W -40 +KPX space V -50 +KPX space T -50 + +KPX v period -80 +KPX v o -25 +KPX v e -25 +KPX v comma -80 +KPX v a -25 + +KPX w period -60 +KPX w o -10 +KPX w e -10 +KPX w comma -60 +KPX w a -15 + +KPX x e -30 + +KPX y period -100 +KPX y o -20 +KPX y e -20 +KPX y comma -100 +KPX y a -20 + +KPX z o -15 +KPX z e -15 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 195 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 195 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 195 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 195 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 195 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 195 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 195 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 195 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 195 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 195 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 195 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 195 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 195 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 205 195 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 195 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 195 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 195 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 195 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 195 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 195 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 195 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 195 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 195 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 195 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 195 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 195 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 195 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8an.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8an.afm new file mode 100644 index 00000000..5a08aa8c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvr8an.afm @@ -0,0 +1,612 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu Mar 15 11:04:57 1990 +Comment UniqueID 28380 +Comment VMusage 7572 42473 +FontName Helvetica-Narrow +FullName Helvetica Narrow +FamilyName Helvetica +Weight Medium +ItalicAngle 0 +IsFixedPitch false +FontBBox -136 -225 820 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 228 ; N space ; B 0 0 0 0 ; +C 33 ; WX 228 ; N exclam ; B 74 0 153 718 ; +C 34 ; WX 291 ; N quotedbl ; B 57 463 234 718 ; +C 35 ; WX 456 ; N numbersign ; B 23 0 434 688 ; +C 36 ; WX 456 ; N dollar ; B 26 -115 426 775 ; +C 37 ; WX 729 ; N percent ; B 32 -19 697 703 ; +C 38 ; WX 547 ; N ampersand ; B 36 -15 529 718 ; +C 39 ; WX 182 ; N quoteright ; B 43 463 129 718 ; +C 40 ; WX 273 ; N parenleft ; B 56 -207 245 733 ; +C 41 ; WX 273 ; N parenright ; B 28 -207 217 733 ; +C 42 ; WX 319 ; N asterisk ; B 32 431 286 718 ; +C 43 ; WX 479 ; N plus ; B 32 0 447 505 ; +C 44 ; WX 228 ; N comma ; B 71 -147 157 106 ; +C 45 ; WX 273 ; N hyphen ; B 36 232 237 322 ; +C 46 ; WX 228 ; N period ; B 71 0 157 106 ; +C 47 ; WX 228 ; N slash ; B -14 -19 242 737 ; +C 48 ; WX 456 ; N zero ; B 30 -19 426 703 ; +C 49 ; WX 456 ; N one ; B 83 0 294 703 ; +C 50 ; WX 456 ; N two ; B 21 0 416 703 ; +C 51 ; WX 456 ; N three ; B 28 -19 428 703 ; +C 52 ; WX 456 ; N four ; B 20 0 429 703 ; +C 53 ; WX 456 ; N five ; B 26 -19 421 688 ; +C 54 ; WX 456 ; N six ; B 31 -19 425 703 ; +C 55 ; WX 456 ; N seven ; B 30 0 429 688 ; +C 56 ; WX 456 ; N eight ; B 31 -19 424 703 ; +C 57 ; WX 456 ; N nine ; B 34 -19 421 703 ; +C 58 ; WX 228 ; N colon ; B 71 0 157 516 ; +C 59 ; WX 228 ; N semicolon ; B 71 -147 157 516 ; +C 60 ; WX 479 ; N less ; B 39 11 440 495 ; +C 61 ; WX 479 ; N equal ; B 32 115 447 390 ; +C 62 ; WX 479 ; N greater ; B 39 11 440 495 ; +C 63 ; WX 456 ; N question ; B 46 0 403 727 ; +C 64 ; WX 832 ; N at ; B 121 -19 712 737 ; +C 65 ; WX 547 ; N A ; B 11 0 536 718 ; +C 66 ; WX 547 ; N B ; B 61 0 514 718 ; +C 67 ; WX 592 ; N C ; B 36 -19 558 737 ; +C 68 ; WX 592 ; N D ; B 66 0 553 718 ; +C 69 ; WX 547 ; N E ; B 71 0 505 718 ; +C 70 ; WX 501 ; N F ; B 71 0 478 718 ; +C 71 ; WX 638 ; N G ; B 39 -19 577 737 ; +C 72 ; WX 592 ; N H ; B 63 0 530 718 ; +C 73 ; WX 228 ; N I ; B 75 0 154 718 ; +C 74 ; WX 410 ; N J ; B 14 -19 351 718 ; +C 75 ; WX 547 ; N K ; B 62 0 544 718 ; +C 76 ; WX 456 ; N L ; B 62 0 440 718 ; +C 77 ; WX 683 ; N M ; B 60 0 624 718 ; +C 78 ; WX 592 ; N N ; B 62 0 530 718 ; +C 79 ; WX 638 ; N O ; B 32 -19 606 737 ; +C 80 ; WX 547 ; N P ; B 71 0 510 718 ; +C 81 ; WX 638 ; N Q ; B 32 -56 606 737 ; +C 82 ; WX 592 ; N R ; B 72 0 561 718 ; +C 83 ; WX 547 ; N S ; B 40 -19 508 737 ; +C 84 ; WX 501 ; N T ; B 11 0 490 718 ; +C 85 ; WX 592 ; N U ; B 65 -19 528 718 ; +C 86 ; WX 547 ; N V ; B 16 0 531 718 ; +C 87 ; WX 774 ; N W ; B 13 0 761 718 ; +C 88 ; WX 547 ; N X ; B 16 0 531 718 ; +C 89 ; WX 547 ; N Y ; B 11 0 535 718 ; +C 90 ; WX 501 ; N Z ; B 19 0 482 718 ; +C 91 ; WX 228 ; N bracketleft ; B 52 -196 205 722 ; +C 92 ; WX 228 ; N backslash ; B -14 -19 242 737 ; +C 93 ; WX 228 ; N bracketright ; B 23 -196 176 722 ; +C 94 ; WX 385 ; N asciicircum ; B -11 264 396 688 ; +C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ; +C 96 ; WX 182 ; N quoteleft ; B 53 470 139 725 ; +C 97 ; WX 456 ; N a ; B 30 -15 435 538 ; +C 98 ; WX 456 ; N b ; B 48 -15 424 718 ; +C 99 ; WX 410 ; N c ; B 25 -15 391 538 ; +C 100 ; WX 456 ; N d ; B 29 -15 409 718 ; +C 101 ; WX 456 ; N e ; B 33 -15 423 538 ; +C 102 ; WX 228 ; N f ; B 11 0 215 728 ; L i fi ; L l fl ; +C 103 ; WX 456 ; N g ; B 33 -220 409 538 ; +C 104 ; WX 456 ; N h ; B 53 0 403 718 ; +C 105 ; WX 182 ; N i ; B 55 0 127 718 ; +C 106 ; WX 182 ; N j ; B -13 -210 127 718 ; +C 107 ; WX 410 ; N k ; B 55 0 411 718 ; +C 108 ; WX 182 ; N l ; B 55 0 127 718 ; +C 109 ; WX 683 ; N m ; B 53 0 631 538 ; +C 110 ; WX 456 ; N n ; B 53 0 403 538 ; +C 111 ; WX 456 ; N o ; B 29 -14 427 538 ; +C 112 ; WX 456 ; N p ; B 48 -207 424 538 ; +C 113 ; WX 456 ; N q ; B 29 -207 405 538 ; +C 114 ; WX 273 ; N r ; B 63 0 272 538 ; +C 115 ; WX 410 ; N s ; B 26 -15 380 538 ; +C 116 ; WX 228 ; N t ; B 11 -7 211 669 ; +C 117 ; WX 456 ; N u ; B 56 -15 401 523 ; +C 118 ; WX 410 ; N v ; B 7 0 403 523 ; +C 119 ; WX 592 ; N w ; B 11 0 581 523 ; +C 120 ; WX 410 ; N x ; B 9 0 402 523 ; +C 121 ; WX 410 ; N y ; B 9 -214 401 523 ; +C 122 ; WX 410 ; N z ; B 25 0 385 523 ; +C 123 ; WX 274 ; N braceleft ; B 34 -196 239 722 ; +C 124 ; WX 213 ; N bar ; B 77 -19 137 737 ; +C 125 ; WX 274 ; N braceright ; B 34 -196 239 722 ; +C 126 ; WX 479 ; N asciitilde ; B 50 180 429 326 ; +C 161 ; WX 273 ; N exclamdown ; B 97 -195 176 523 ; +C 162 ; WX 456 ; N cent ; B 42 -115 421 623 ; +C 163 ; WX 456 ; N sterling ; B 27 -16 442 718 ; +C 164 ; WX 137 ; N fraction ; B -136 -19 273 703 ; +C 165 ; WX 456 ; N yen ; B 2 0 453 688 ; +C 166 ; WX 456 ; N florin ; B -9 -207 411 737 ; +C 167 ; WX 456 ; N section ; B 35 -191 420 737 ; +C 168 ; WX 456 ; N currency ; B 23 99 433 603 ; +C 169 ; WX 157 ; N quotesingle ; B 48 463 108 718 ; +C 170 ; WX 273 ; N quotedblleft ; B 31 470 252 725 ; +C 171 ; WX 456 ; N guillemotleft ; B 80 108 376 446 ; +C 172 ; WX 273 ; N guilsinglleft ; B 72 108 201 446 ; +C 173 ; WX 273 ; N guilsinglright ; B 72 108 201 446 ; +C 174 ; WX 410 ; N fi ; B 11 0 356 728 ; +C 175 ; WX 410 ; N fl ; B 11 0 354 728 ; +C 177 ; WX 456 ; N endash ; B 0 240 456 313 ; +C 178 ; WX 456 ; N dagger ; B 35 -159 421 718 ; +C 179 ; WX 456 ; N daggerdbl ; B 35 -159 421 718 ; +C 180 ; WX 228 ; N periodcentered ; B 63 190 166 315 ; +C 182 ; WX 440 ; N paragraph ; B 15 -173 408 718 ; +C 183 ; WX 287 ; N bullet ; B 15 202 273 517 ; +C 184 ; WX 182 ; N quotesinglbase ; B 43 -149 129 106 ; +C 185 ; WX 273 ; N quotedblbase ; B 21 -149 242 106 ; +C 186 ; WX 273 ; N quotedblright ; B 21 463 242 718 ; +C 187 ; WX 456 ; N guillemotright ; B 80 108 376 446 ; +C 188 ; WX 820 ; N ellipsis ; B 94 0 726 106 ; +C 189 ; WX 820 ; N perthousand ; B 6 -19 815 703 ; +C 191 ; WX 501 ; N questiondown ; B 75 -201 432 525 ; +C 193 ; WX 273 ; N grave ; B 11 593 173 734 ; +C 194 ; WX 273 ; N acute ; B 100 593 262 734 ; +C 195 ; WX 273 ; N circumflex ; B 17 593 256 734 ; +C 196 ; WX 273 ; N tilde ; B -3 606 276 722 ; +C 197 ; WX 273 ; N macron ; B 8 627 265 684 ; +C 198 ; WX 273 ; N breve ; B 11 595 263 731 ; +C 199 ; WX 273 ; N dotaccent ; B 99 604 174 706 ; +C 200 ; WX 273 ; N dieresis ; B 33 604 240 706 ; +C 202 ; WX 273 ; N ring ; B 61 572 212 756 ; +C 203 ; WX 273 ; N cedilla ; B 37 -225 212 0 ; +C 205 ; WX 273 ; N hungarumlaut ; B 25 593 335 734 ; +C 206 ; WX 273 ; N ogonek ; B 60 -225 235 0 ; +C 207 ; WX 273 ; N caron ; B 17 593 256 734 ; +C 208 ; WX 820 ; N emdash ; B 0 240 820 313 ; +C 225 ; WX 820 ; N AE ; B 7 0 780 718 ; +C 227 ; WX 303 ; N ordfeminine ; B 20 304 284 737 ; +C 232 ; WX 456 ; N Lslash ; B -16 0 440 718 ; +C 233 ; WX 638 ; N Oslash ; B 32 -19 607 737 ; +C 234 ; WX 820 ; N OE ; B 30 -19 791 737 ; +C 235 ; WX 299 ; N ordmasculine ; B 20 304 280 737 ; +C 241 ; WX 729 ; N ae ; B 30 -15 695 538 ; +C 245 ; WX 228 ; N dotlessi ; B 78 0 150 523 ; +C 248 ; WX 182 ; N lslash ; B -16 0 198 718 ; +C 249 ; WX 501 ; N oslash ; B 23 -22 440 545 ; +C 250 ; WX 774 ; N oe ; B 29 -15 740 538 ; +C 251 ; WX 501 ; N germandbls ; B 55 -15 468 728 ; +C -1 ; WX 501 ; N Zcaron ; B 19 0 482 929 ; +C -1 ; WX 410 ; N ccedilla ; B 25 -225 391 538 ; +C -1 ; WX 410 ; N ydieresis ; B 9 -214 401 706 ; +C -1 ; WX 456 ; N atilde ; B 30 -15 435 722 ; +C -1 ; WX 228 ; N icircumflex ; B -5 0 234 734 ; +C -1 ; WX 273 ; N threesuperior ; B 4 270 266 703 ; +C -1 ; WX 456 ; N ecircumflex ; B 33 -15 423 734 ; +C -1 ; WX 456 ; N thorn ; B 48 -207 424 718 ; +C -1 ; WX 456 ; N egrave ; B 33 -15 423 734 ; +C -1 ; WX 273 ; N twosuperior ; B 3 281 265 703 ; +C -1 ; WX 456 ; N eacute ; B 33 -15 423 734 ; +C -1 ; WX 456 ; N otilde ; B 29 -14 427 722 ; +C -1 ; WX 547 ; N Aacute ; B 11 0 536 929 ; +C -1 ; WX 456 ; N ocircumflex ; B 29 -14 427 734 ; +C -1 ; WX 410 ; N yacute ; B 9 -214 401 734 ; +C -1 ; WX 456 ; N udieresis ; B 56 -15 401 706 ; +C -1 ; WX 684 ; N threequarters ; B 37 -19 664 703 ; +C -1 ; WX 456 ; N acircumflex ; B 30 -15 435 734 ; +C -1 ; WX 592 ; N Eth ; B 0 0 553 718 ; +C -1 ; WX 456 ; N edieresis ; B 33 -15 423 706 ; +C -1 ; WX 456 ; N ugrave ; B 56 -15 401 734 ; +C -1 ; WX 820 ; N trademark ; B 38 306 740 718 ; +C -1 ; WX 456 ; N ograve ; B 29 -14 427 734 ; +C -1 ; WX 410 ; N scaron ; B 26 -15 380 734 ; +C -1 ; WX 228 ; N Idieresis ; B 11 0 218 901 ; +C -1 ; WX 456 ; N uacute ; B 56 -15 401 734 ; +C -1 ; WX 456 ; N agrave ; B 30 -15 435 734 ; +C -1 ; WX 456 ; N ntilde ; B 53 0 403 722 ; +C -1 ; WX 456 ; N aring ; B 30 -15 435 756 ; +C -1 ; WX 410 ; N zcaron ; B 25 0 385 734 ; +C -1 ; WX 228 ; N Icircumflex ; B -5 0 234 929 ; +C -1 ; WX 592 ; N Ntilde ; B 62 0 530 917 ; +C -1 ; WX 456 ; N ucircumflex ; B 56 -15 401 734 ; +C -1 ; WX 547 ; N Ecircumflex ; B 71 0 505 929 ; +C -1 ; WX 228 ; N Iacute ; B 75 0 239 929 ; +C -1 ; WX 592 ; N Ccedilla ; B 36 -225 558 737 ; +C -1 ; WX 638 ; N Odieresis ; B 32 -19 606 901 ; +C -1 ; WX 547 ; N Scaron ; B 40 -19 508 929 ; +C -1 ; WX 547 ; N Edieresis ; B 71 0 505 901 ; +C -1 ; WX 228 ; N Igrave ; B -11 0 154 929 ; +C -1 ; WX 456 ; N adieresis ; B 30 -15 435 706 ; +C -1 ; WX 638 ; N Ograve ; B 32 -19 606 929 ; +C -1 ; WX 547 ; N Egrave ; B 71 0 505 929 ; +C -1 ; WX 547 ; N Ydieresis ; B 11 0 535 901 ; +C -1 ; WX 604 ; N registered ; B -11 -19 617 737 ; +C -1 ; WX 638 ; N Otilde ; B 32 -19 606 917 ; +C -1 ; WX 684 ; N onequarter ; B 60 -19 620 703 ; +C -1 ; WX 592 ; N Ugrave ; B 65 -19 528 929 ; +C -1 ; WX 592 ; N Ucircumflex ; B 65 -19 528 929 ; +C -1 ; WX 547 ; N Thorn ; B 71 0 510 718 ; +C -1 ; WX 479 ; N divide ; B 32 -19 447 524 ; +C -1 ; WX 547 ; N Atilde ; B 11 0 536 917 ; +C -1 ; WX 592 ; N Uacute ; B 65 -19 528 929 ; +C -1 ; WX 638 ; N Ocircumflex ; B 32 -19 606 929 ; +C -1 ; WX 479 ; N logicalnot ; B 32 108 447 390 ; +C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ; +C -1 ; WX 228 ; N idieresis ; B 11 0 218 706 ; +C -1 ; WX 228 ; N iacute ; B 78 0 239 734 ; +C -1 ; WX 456 ; N aacute ; B 30 -15 435 734 ; +C -1 ; WX 479 ; N plusminus ; B 32 0 447 506 ; +C -1 ; WX 479 ; N multiply ; B 32 0 447 506 ; +C -1 ; WX 592 ; N Udieresis ; B 65 -19 528 901 ; +C -1 ; WX 479 ; N minus ; B 32 216 447 289 ; +C -1 ; WX 273 ; N onesuperior ; B 35 281 182 703 ; +C -1 ; WX 547 ; N Eacute ; B 71 0 505 929 ; +C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ; +C -1 ; WX 604 ; N copyright ; B -11 -19 617 737 ; +C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ; +C -1 ; WX 456 ; N odieresis ; B 29 -14 427 706 ; +C -1 ; WX 456 ; N oacute ; B 29 -14 427 734 ; +C -1 ; WX 328 ; N degree ; B 44 411 284 703 ; +C -1 ; WX 228 ; N igrave ; B -11 0 151 734 ; +C -1 ; WX 456 ; N mu ; B 56 -207 401 523 ; +C -1 ; WX 638 ; N Oacute ; B 32 -19 606 929 ; +C -1 ; WX 456 ; N eth ; B 29 -15 428 737 ; +C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ; +C -1 ; WX 547 ; N Yacute ; B 11 0 535 929 ; +C -1 ; WX 213 ; N brokenbar ; B 77 -19 137 737 ; +C -1 ; WX 684 ; N onehalf ; B 35 -19 634 703 ; +EndCharMetrics +StartKernData +StartKernPairs 250 + +KPX A y -32 +KPX A w -32 +KPX A v -32 +KPX A u -24 +KPX A Y -81 +KPX A W -40 +KPX A V -56 +KPX A U -40 +KPX A T -97 +KPX A Q -24 +KPX A O -24 +KPX A G -24 +KPX A C -24 + +KPX B period -15 +KPX B comma -15 +KPX B U -7 + +KPX C period -24 +KPX C comma -24 + +KPX D period -56 +KPX D comma -56 +KPX D Y -73 +KPX D W -32 +KPX D V -56 +KPX D A -32 + +KPX F r -36 +KPX F period -122 +KPX F o -24 +KPX F e -24 +KPX F comma -122 +KPX F a -40 +KPX F A -65 + +KPX J u -15 +KPX J period -24 +KPX J comma -24 +KPX J a -15 +KPX J A -15 + +KPX K y -40 +KPX K u -24 +KPX K o -32 +KPX K e -32 +KPX K O -40 + +KPX L y -24 +KPX L quoteright -130 +KPX L quotedblright -114 +KPX L Y -114 +KPX L W -56 +KPX L V -89 +KPX L T -89 + +KPX O period -32 +KPX O comma -32 +KPX O Y -56 +KPX O X -48 +KPX O W -24 +KPX O V -40 +KPX O T -32 +KPX O A -15 + +KPX P period -147 +KPX P o -40 +KPX P e -40 +KPX P comma -147 +KPX P a -32 +KPX P A -97 + +KPX Q U -7 + +KPX R Y -40 +KPX R W -24 +KPX R V -40 +KPX R U -32 +KPX R T -24 +KPX R O -15 + +KPX S period -15 +KPX S comma -15 + +KPX T y -97 +KPX T w -97 +KPX T u -97 +KPX T semicolon -15 +KPX T r -97 +KPX T period -97 +KPX T o -97 +KPX T hyphen -114 +KPX T e -97 +KPX T comma -97 +KPX T colon -15 +KPX T a -97 +KPX T O -32 +KPX T A -97 + +KPX U period -32 +KPX U comma -32 +KPX U A -32 + +KPX V u -56 +KPX V semicolon -32 +KPX V period -102 +KPX V o -65 +KPX V hyphen -65 +KPX V e -65 +KPX V comma -102 +KPX V colon -32 +KPX V a -56 +KPX V O -32 +KPX V G -32 +KPX V A -65 + +KPX W y -15 +KPX W u -24 +KPX W period -65 +KPX W o -24 +KPX W hyphen -32 +KPX W e -24 +KPX W comma -65 +KPX W a -32 +KPX W O -15 +KPX W A -40 + +KPX Y u -89 +KPX Y semicolon -48 +KPX Y period -114 +KPX Y o -114 +KPX Y i -15 +KPX Y hyphen -114 +KPX Y e -114 +KPX Y comma -114 +KPX Y colon -48 +KPX Y a -114 +KPX Y O -69 +KPX Y A -89 + +KPX a y -24 +KPX a w -15 +KPX a v -15 + +KPX b y -15 +KPX b v -15 +KPX b u -15 +KPX b period -32 +KPX b l -15 +KPX b comma -32 +KPX b b -7 + +KPX c k -15 +KPX c comma -11 + +KPX colon space -40 + +KPX comma quoteright -81 +KPX comma quotedblright -81 + +KPX e y -15 +KPX e x -24 +KPX e w -15 +KPX e v -24 +KPX e period -11 +KPX e comma -11 + +KPX f quoteright 41 +KPX f quotedblright 49 +KPX f period -24 +KPX f o -24 +KPX f e -24 +KPX f dotlessi -22 +KPX f comma -24 +KPX f a -24 + +KPX g r -7 + +KPX h y -24 + +KPX k o -15 +KPX k e -15 + +KPX m y -11 +KPX m u -7 + +KPX n y -11 +KPX n v -15 +KPX n u -7 + +KPX o y -24 +KPX o x -24 +KPX o w -11 +KPX o v -11 +KPX o period -32 +KPX o comma -32 + +KPX oslash z -44 +KPX oslash y -56 +KPX oslash x -69 +KPX oslash w -56 +KPX oslash v -56 +KPX oslash u -44 +KPX oslash t -44 +KPX oslash s -44 +KPX oslash r -44 +KPX oslash q -44 +KPX oslash period -77 +KPX oslash p -44 +KPX oslash o -44 +KPX oslash n -44 +KPX oslash m -44 +KPX oslash l -44 +KPX oslash k -44 +KPX oslash j -44 +KPX oslash i -44 +KPX oslash h -44 +KPX oslash g -44 +KPX oslash f -44 +KPX oslash e -44 +KPX oslash d -44 +KPX oslash comma -77 +KPX oslash c -44 +KPX oslash b -44 +KPX oslash a -44 + +KPX p y -24 +KPX p period -28 +KPX p comma -28 + +KPX period space -48 +KPX period quoteright -81 +KPX period quotedblright -81 + +KPX quotedblright space -32 + +KPX quoteleft quoteleft -46 + +KPX quoteright space -56 +KPX quoteright s -40 +KPX quoteright r -40 +KPX quoteright quoteright -46 +KPX quoteright d -40 + +KPX r y 25 +KPX r v 25 +KPX r u 12 +KPX r t 33 +KPX r semicolon 25 +KPX r period -40 +KPX r p 25 +KPX r n 21 +KPX r m 21 +KPX r l 12 +KPX r k 12 +KPX r i 12 +KPX r comma -40 +KPX r colon 25 +KPX r a -7 + +KPX s w -24 +KPX s period -11 +KPX s comma -11 + +KPX semicolon space -40 + +KPX space quoteleft -48 +KPX space quotedblleft -24 +KPX space Y -73 +KPX space W -32 +KPX space V -40 +KPX space T -40 + +KPX v period -65 +KPX v o -20 +KPX v e -20 +KPX v comma -65 +KPX v a -20 + +KPX w period -48 +KPX w o -7 +KPX w e -7 +KPX w comma -48 +KPX w a -11 + +KPX x e -24 + +KPX y period -81 +KPX y o -15 +KPX y e -15 +KPX y comma -81 +KPX y a -15 + +KPX z o -11 +KPX z e -11 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 137 195 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 195 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 137 195 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 137 195 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 137 175 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 137 195 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 195 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 195 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 195 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 195 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 195 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 195 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 195 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 195 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 168 195 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 195 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 195 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 195 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 195 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 195 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 195 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 195 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 195 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 195 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 195 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 195 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 195 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 195 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8a.afm new file mode 100644 index 00000000..3d69eb7c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8a.afm @@ -0,0 +1,612 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu Mar 15 10:24:18 1990 +Comment UniqueID 28362 +Comment VMusage 7572 42473 +FontName Helvetica-Oblique +FullName Helvetica Oblique +FamilyName Helvetica +Weight Medium +ItalicAngle -12 +IsFixedPitch false +FontBBox -170 -225 1116 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ; +C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ; +C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ; +C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ; +C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ; +C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ; +C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ; +C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ; +C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ; +C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ; +C 43 ; WX 584 ; N plus ; B 85 0 606 505 ; +C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ; +C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ; +C 46 ; WX 278 ; N period ; B 87 0 214 106 ; +C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ; +C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ; +C 49 ; WX 556 ; N one ; B 207 0 508 703 ; +C 50 ; WX 556 ; N two ; B 26 0 617 703 ; +C 51 ; WX 556 ; N three ; B 75 -19 610 703 ; +C 52 ; WX 556 ; N four ; B 61 0 576 703 ; +C 53 ; WX 556 ; N five ; B 68 -19 621 688 ; +C 54 ; WX 556 ; N six ; B 91 -19 615 703 ; +C 55 ; WX 556 ; N seven ; B 137 0 669 688 ; +C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ; +C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 301 516 ; +C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ; +C 60 ; WX 584 ; N less ; B 94 11 641 495 ; +C 61 ; WX 584 ; N equal ; B 63 115 628 390 ; +C 62 ; WX 584 ; N greater ; B 50 11 597 495 ; +C 63 ; WX 556 ; N question ; B 161 0 610 727 ; +C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 712 718 ; +C 67 ; WX 722 ; N C ; B 108 -19 782 737 ; +C 68 ; WX 722 ; N D ; B 81 0 764 718 ; +C 69 ; WX 667 ; N E ; B 86 0 762 718 ; +C 70 ; WX 611 ; N F ; B 86 0 736 718 ; +C 71 ; WX 778 ; N G ; B 111 -19 799 737 ; +C 72 ; WX 722 ; N H ; B 77 0 799 718 ; +C 73 ; WX 278 ; N I ; B 91 0 341 718 ; +C 74 ; WX 500 ; N J ; B 47 -19 581 718 ; +C 75 ; WX 667 ; N K ; B 76 0 808 718 ; +C 76 ; WX 556 ; N L ; B 76 0 555 718 ; +C 77 ; WX 833 ; N M ; B 73 0 914 718 ; +C 78 ; WX 722 ; N N ; B 76 0 799 718 ; +C 79 ; WX 778 ; N O ; B 105 -19 826 737 ; +C 80 ; WX 667 ; N P ; B 86 0 737 718 ; +C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ; +C 82 ; WX 722 ; N R ; B 88 0 773 718 ; +C 83 ; WX 667 ; N S ; B 90 -19 713 737 ; +C 84 ; WX 611 ; N T ; B 148 0 750 718 ; +C 85 ; WX 722 ; N U ; B 123 -19 797 718 ; +C 86 ; WX 667 ; N V ; B 173 0 800 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1081 718 ; +C 88 ; WX 667 ; N X ; B 19 0 790 718 ; +C 89 ; WX 667 ; N Y ; B 167 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 741 718 ; +C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ; +C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ; +C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ; +C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ; +C 97 ; WX 556 ; N a ; B 61 -15 559 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 584 718 ; +C 99 ; WX 500 ; N c ; B 74 -15 553 538 ; +C 100 ; WX 556 ; N d ; B 84 -15 652 718 ; +C 101 ; WX 556 ; N e ; B 84 -15 578 538 ; +C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 42 -220 610 538 ; +C 104 ; WX 556 ; N h ; B 65 0 573 718 ; +C 105 ; WX 222 ; N i ; B 67 0 308 718 ; +C 106 ; WX 222 ; N j ; B -60 -210 308 718 ; +C 107 ; WX 500 ; N k ; B 67 0 600 718 ; +C 108 ; WX 222 ; N l ; B 67 0 308 718 ; +C 109 ; WX 833 ; N m ; B 65 0 852 538 ; +C 110 ; WX 556 ; N n ; B 65 0 573 538 ; +C 111 ; WX 556 ; N o ; B 83 -14 585 538 ; +C 112 ; WX 556 ; N p ; B 14 -207 584 538 ; +C 113 ; WX 556 ; N q ; B 84 -207 605 538 ; +C 114 ; WX 333 ; N r ; B 77 0 446 538 ; +C 115 ; WX 500 ; N s ; B 63 -15 529 538 ; +C 116 ; WX 278 ; N t ; B 102 -7 368 669 ; +C 117 ; WX 556 ; N u ; B 94 -15 600 523 ; +C 118 ; WX 500 ; N v ; B 119 0 603 523 ; +C 119 ; WX 722 ; N w ; B 125 0 820 523 ; +C 120 ; WX 500 ; N x ; B 11 0 594 523 ; +C 121 ; WX 500 ; N y ; B 15 -214 600 523 ; +C 122 ; WX 500 ; N z ; B 31 0 571 523 ; +C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ; +C 124 ; WX 260 ; N bar ; B 90 -19 324 737 ; +C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ; +C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ; +C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ; +C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ; +C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ; +C 165 ; WX 556 ; N yen ; B 81 0 699 688 ; +C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ; +C 167 ; WX 556 ; N section ; B 76 -191 584 737 ; +C 168 ; WX 556 ; N currency ; B 60 99 646 603 ; +C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ; +C 174 ; WX 500 ; N fi ; B 86 0 587 728 ; +C 175 ; WX 500 ; N fl ; B 86 0 585 728 ; +C 177 ; WX 556 ; N endash ; B 51 240 623 313 ; +C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ; +C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ; +C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ; +C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ; +C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ; +C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ; +C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ; +C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ; +C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ; +C 193 ; WX 333 ; N grave ; B 170 593 337 734 ; +C 194 ; WX 333 ; N acute ; B 248 593 475 734 ; +C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ; +C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ; +C 197 ; WX 333 ; N macron ; B 143 627 468 684 ; +C 198 ; WX 333 ; N breve ; B 167 595 476 731 ; +C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ; +C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ; +C 202 ; WX 333 ; N ring ; B 214 572 402 756 ; +C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ; +C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ; +C 207 ; WX 333 ; N caron ; B 177 593 468 734 ; +C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 100 304 449 737 ; +C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ; +C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ; +C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 100 304 468 737 ; +C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ; +C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ; +C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ; +C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ; +C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ; +C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ; +C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ; +C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ; +C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ; +C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ; +C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ; +C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ; +C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ; +C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ; +C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ; +C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ; +C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ; +C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ; +C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ; +C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ; +C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ; +C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ; +C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ; +C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ; +C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ; +C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ; +C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ; +C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ; +C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ; +C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ; +C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ; +C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ; +C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ; +C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ; +C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ; +C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ; +C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ; +C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ; +C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ; +C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ; +C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ; +C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ; +C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ; +C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ; +C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ; +C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ; +C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ; +C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ; +C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ; +C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ; +C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ; +C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ; +C -1 ; WX 584 ; N minus ; B 85 216 606 289 ; +C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ; +C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ; +C -1 ; WX 400 ; N degree ; B 169 411 468 703 ; +C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ; +C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ; +C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ; +C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ; +C -1 ; WX 260 ; N brokenbar ; B 90 -19 324 737 ; +C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ; +EndCharMetrics +StartKernData +StartKernPairs 250 + +KPX A y -40 +KPX A w -40 +KPX A v -40 +KPX A u -30 +KPX A Y -100 +KPX A W -50 +KPX A V -70 +KPX A U -50 +KPX A T -120 +KPX A Q -30 +KPX A O -30 +KPX A G -30 +KPX A C -30 + +KPX B period -20 +KPX B comma -20 +KPX B U -10 + +KPX C period -30 +KPX C comma -30 + +KPX D period -70 +KPX D comma -70 +KPX D Y -90 +KPX D W -40 +KPX D V -70 +KPX D A -40 + +KPX F r -45 +KPX F period -150 +KPX F o -30 +KPX F e -30 +KPX F comma -150 +KPX F a -50 +KPX F A -80 + +KPX J u -20 +KPX J period -30 +KPX J comma -30 +KPX J a -20 +KPX J A -20 + +KPX K y -50 +KPX K u -30 +KPX K o -40 +KPX K e -40 +KPX K O -50 + +KPX L y -30 +KPX L quoteright -160 +KPX L quotedblright -140 +KPX L Y -140 +KPX L W -70 +KPX L V -110 +KPX L T -110 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -60 +KPX O W -30 +KPX O V -50 +KPX O T -40 +KPX O A -20 + +KPX P period -180 +KPX P o -50 +KPX P e -50 +KPX P comma -180 +KPX P a -40 +KPX P A -120 + +KPX Q U -10 + +KPX R Y -50 +KPX R W -30 +KPX R V -50 +KPX R U -40 +KPX R T -30 +KPX R O -20 + +KPX S period -20 +KPX S comma -20 + +KPX T y -120 +KPX T w -120 +KPX T u -120 +KPX T semicolon -20 +KPX T r -120 +KPX T period -120 +KPX T o -120 +KPX T hyphen -140 +KPX T e -120 +KPX T comma -120 +KPX T colon -20 +KPX T a -120 +KPX T O -40 +KPX T A -120 + +KPX U period -40 +KPX U comma -40 +KPX U A -40 + +KPX V u -70 +KPX V semicolon -40 +KPX V period -125 +KPX V o -80 +KPX V hyphen -80 +KPX V e -80 +KPX V comma -125 +KPX V colon -40 +KPX V a -70 +KPX V O -40 +KPX V G -40 +KPX V A -80 + +KPX W y -20 +KPX W u -30 +KPX W period -80 +KPX W o -30 +KPX W hyphen -40 +KPX W e -30 +KPX W comma -80 +KPX W a -40 +KPX W O -20 +KPX W A -50 + +KPX Y u -110 +KPX Y semicolon -60 +KPX Y period -140 +KPX Y o -140 +KPX Y i -20 +KPX Y hyphen -140 +KPX Y e -140 +KPX Y comma -140 +KPX Y colon -60 +KPX Y a -140 +KPX Y O -85 +KPX Y A -110 + +KPX a y -30 +KPX a w -20 +KPX a v -20 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b period -40 +KPX b l -20 +KPX b comma -40 +KPX b b -10 + +KPX c k -20 +KPX c comma -15 + +KPX colon space -50 + +KPX comma quoteright -100 +KPX comma quotedblright -100 + +KPX e y -20 +KPX e x -30 +KPX e w -20 +KPX e v -30 +KPX e period -15 +KPX e comma -15 + +KPX f quoteright 50 +KPX f quotedblright 60 +KPX f period -30 +KPX f o -30 +KPX f e -30 +KPX f dotlessi -28 +KPX f comma -30 +KPX f a -30 + +KPX g r -10 + +KPX h y -30 + +KPX k o -20 +KPX k e -20 + +KPX m y -15 +KPX m u -10 + +KPX n y -15 +KPX n v -20 +KPX n u -10 + +KPX o y -30 +KPX o x -30 +KPX o w -15 +KPX o v -15 +KPX o period -40 +KPX o comma -40 + +KPX oslash z -55 +KPX oslash y -70 +KPX oslash x -85 +KPX oslash w -70 +KPX oslash v -70 +KPX oslash u -55 +KPX oslash t -55 +KPX oslash s -55 +KPX oslash r -55 +KPX oslash q -55 +KPX oslash period -95 +KPX oslash p -55 +KPX oslash o -55 +KPX oslash n -55 +KPX oslash m -55 +KPX oslash l -55 +KPX oslash k -55 +KPX oslash j -55 +KPX oslash i -55 +KPX oslash h -55 +KPX oslash g -55 +KPX oslash f -55 +KPX oslash e -55 +KPX oslash d -55 +KPX oslash comma -95 +KPX oslash c -55 +KPX oslash b -55 +KPX oslash a -55 + +KPX p y -30 +KPX p period -35 +KPX p comma -35 + +KPX period space -60 +KPX period quoteright -100 +KPX period quotedblright -100 + +KPX quotedblright space -40 + +KPX quoteleft quoteleft -57 + +KPX quoteright space -70 +KPX quoteright s -50 +KPX quoteright r -50 +KPX quoteright quoteright -57 +KPX quoteright d -50 + +KPX r y 30 +KPX r v 30 +KPX r u 15 +KPX r t 40 +KPX r semicolon 30 +KPX r period -50 +KPX r p 30 +KPX r n 25 +KPX r m 25 +KPX r l 15 +KPX r k 15 +KPX r i 15 +KPX r comma -50 +KPX r colon 30 +KPX r a -10 + +KPX s w -30 +KPX s period -15 +KPX s comma -15 + +KPX semicolon space -50 + +KPX space quoteleft -60 +KPX space quotedblleft -30 +KPX space Y -90 +KPX space W -40 +KPX space V -50 +KPX space T -50 + +KPX v period -80 +KPX v o -25 +KPX v e -25 +KPX v comma -80 +KPX v a -25 + +KPX w period -60 +KPX w o -10 +KPX w e -10 +KPX w comma -60 +KPX w a -15 + +KPX x e -30 + +KPX y period -100 +KPX y o -20 +KPX y e -20 +KPX y comma -100 +KPX y a -20 + +KPX z o -15 +KPX z e -15 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 208 195 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 208 195 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 208 195 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 208 195 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 204 175 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 208 195 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 208 195 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 208 195 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 208 195 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 208 195 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 195 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 195 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 195 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 195 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 246 195 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 264 195 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 264 195 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 264 195 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 264 195 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 264 195 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 208 195 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 236 195 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 236 195 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 236 195 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 236 195 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 208 195 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 208 195 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 180 195 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8an.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8an.afm new file mode 100644 index 00000000..f757319a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/phvro8an.afm @@ -0,0 +1,612 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu Mar 15 11:25:48 1990 +Comment UniqueID 28389 +Comment VMusage 7572 42473 +FontName Helvetica-Narrow-Oblique +FullName Helvetica Narrow Oblique +FamilyName Helvetica +Weight Medium +ItalicAngle -12 +IsFixedPitch false +FontBBox -139 -225 915 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StartCharMetrics 228 +C 32 ; WX 228 ; N space ; B 0 0 0 0 ; +C 33 ; WX 228 ; N exclam ; B 74 0 278 718 ; +C 34 ; WX 291 ; N quotedbl ; B 138 463 359 718 ; +C 35 ; WX 456 ; N numbersign ; B 60 0 517 688 ; +C 36 ; WX 456 ; N dollar ; B 57 -115 506 775 ; +C 37 ; WX 729 ; N percent ; B 120 -19 729 703 ; +C 38 ; WX 547 ; N ampersand ; B 63 -15 530 718 ; +C 39 ; WX 182 ; N quoteright ; B 124 463 254 718 ; +C 40 ; WX 273 ; N parenleft ; B 89 -207 372 733 ; +C 41 ; WX 273 ; N parenright ; B -7 -207 276 733 ; +C 42 ; WX 319 ; N asterisk ; B 135 431 389 718 ; +C 43 ; WX 479 ; N plus ; B 70 0 497 505 ; +C 44 ; WX 228 ; N comma ; B 46 -147 175 106 ; +C 45 ; WX 273 ; N hyphen ; B 77 232 293 322 ; +C 46 ; WX 228 ; N period ; B 71 0 175 106 ; +C 47 ; WX 228 ; N slash ; B -17 -19 370 737 ; +C 48 ; WX 456 ; N zero ; B 77 -19 499 703 ; +C 49 ; WX 456 ; N one ; B 170 0 417 703 ; +C 50 ; WX 456 ; N two ; B 21 0 506 703 ; +C 51 ; WX 456 ; N three ; B 61 -19 500 703 ; +C 52 ; WX 456 ; N four ; B 50 0 472 703 ; +C 53 ; WX 456 ; N five ; B 55 -19 509 688 ; +C 54 ; WX 456 ; N six ; B 74 -19 504 703 ; +C 55 ; WX 456 ; N seven ; B 112 0 549 688 ; +C 56 ; WX 456 ; N eight ; B 60 -19 497 703 ; +C 57 ; WX 456 ; N nine ; B 67 -19 499 703 ; +C 58 ; WX 228 ; N colon ; B 71 0 247 516 ; +C 59 ; WX 228 ; N semicolon ; B 46 -147 247 516 ; +C 60 ; WX 479 ; N less ; B 77 11 526 495 ; +C 61 ; WX 479 ; N equal ; B 52 115 515 390 ; +C 62 ; WX 479 ; N greater ; B 41 11 490 495 ; +C 63 ; WX 456 ; N question ; B 132 0 500 727 ; +C 64 ; WX 832 ; N at ; B 176 -19 791 737 ; +C 65 ; WX 547 ; N A ; B 11 0 536 718 ; +C 66 ; WX 547 ; N B ; B 61 0 583 718 ; +C 67 ; WX 592 ; N C ; B 88 -19 640 737 ; +C 68 ; WX 592 ; N D ; B 66 0 626 718 ; +C 69 ; WX 547 ; N E ; B 71 0 625 718 ; +C 70 ; WX 501 ; N F ; B 71 0 603 718 ; +C 71 ; WX 638 ; N G ; B 91 -19 655 737 ; +C 72 ; WX 592 ; N H ; B 63 0 655 718 ; +C 73 ; WX 228 ; N I ; B 75 0 279 718 ; +C 74 ; WX 410 ; N J ; B 39 -19 476 718 ; +C 75 ; WX 547 ; N K ; B 62 0 662 718 ; +C 76 ; WX 456 ; N L ; B 62 0 455 718 ; +C 77 ; WX 683 ; N M ; B 60 0 749 718 ; +C 78 ; WX 592 ; N N ; B 62 0 655 718 ; +C 79 ; WX 638 ; N O ; B 86 -19 677 737 ; +C 80 ; WX 547 ; N P ; B 71 0 604 718 ; +C 81 ; WX 638 ; N Q ; B 86 -56 677 737 ; +C 82 ; WX 592 ; N R ; B 72 0 634 718 ; +C 83 ; WX 547 ; N S ; B 74 -19 584 737 ; +C 84 ; WX 501 ; N T ; B 122 0 615 718 ; +C 85 ; WX 592 ; N U ; B 101 -19 653 718 ; +C 86 ; WX 547 ; N V ; B 142 0 656 718 ; +C 87 ; WX 774 ; N W ; B 138 0 886 718 ; +C 88 ; WX 547 ; N X ; B 16 0 647 718 ; +C 89 ; WX 547 ; N Y ; B 137 0 661 718 ; +C 90 ; WX 501 ; N Z ; B 19 0 607 718 ; +C 91 ; WX 228 ; N bracketleft ; B 17 -196 331 722 ; +C 92 ; WX 228 ; N backslash ; B 115 -19 239 737 ; +C 93 ; WX 228 ; N bracketright ; B -11 -196 302 722 ; +C 94 ; WX 385 ; N asciicircum ; B 35 264 442 688 ; +C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ; +C 96 ; WX 182 ; N quoteleft ; B 135 470 265 725 ; +C 97 ; WX 456 ; N a ; B 50 -15 458 538 ; +C 98 ; WX 456 ; N b ; B 48 -15 479 718 ; +C 99 ; WX 410 ; N c ; B 61 -15 454 538 ; +C 100 ; WX 456 ; N d ; B 69 -15 534 718 ; +C 101 ; WX 456 ; N e ; B 69 -15 474 538 ; +C 102 ; WX 228 ; N f ; B 71 0 341 728 ; L i fi ; L l fl ; +C 103 ; WX 456 ; N g ; B 34 -220 500 538 ; +C 104 ; WX 456 ; N h ; B 53 0 470 718 ; +C 105 ; WX 182 ; N i ; B 55 0 252 718 ; +C 106 ; WX 182 ; N j ; B -49 -210 252 718 ; +C 107 ; WX 410 ; N k ; B 55 0 492 718 ; +C 108 ; WX 182 ; N l ; B 55 0 252 718 ; +C 109 ; WX 683 ; N m ; B 53 0 699 538 ; +C 110 ; WX 456 ; N n ; B 53 0 470 538 ; +C 111 ; WX 456 ; N o ; B 68 -14 479 538 ; +C 112 ; WX 456 ; N p ; B 11 -207 479 538 ; +C 113 ; WX 456 ; N q ; B 69 -207 496 538 ; +C 114 ; WX 273 ; N r ; B 63 0 365 538 ; +C 115 ; WX 410 ; N s ; B 52 -15 434 538 ; +C 116 ; WX 228 ; N t ; B 84 -7 302 669 ; +C 117 ; WX 456 ; N u ; B 77 -15 492 523 ; +C 118 ; WX 410 ; N v ; B 98 0 495 523 ; +C 119 ; WX 592 ; N w ; B 103 0 673 523 ; +C 120 ; WX 410 ; N x ; B 9 0 487 523 ; +C 121 ; WX 410 ; N y ; B 12 -214 492 523 ; +C 122 ; WX 410 ; N z ; B 25 0 468 523 ; +C 123 ; WX 274 ; N braceleft ; B 75 -196 365 722 ; +C 124 ; WX 213 ; N bar ; B 74 -19 265 737 ; +C 125 ; WX 274 ; N braceright ; B 0 -196 291 722 ; +C 126 ; WX 479 ; N asciitilde ; B 91 180 476 326 ; +C 161 ; WX 273 ; N exclamdown ; B 63 -195 267 523 ; +C 162 ; WX 456 ; N cent ; B 78 -115 479 623 ; +C 163 ; WX 456 ; N sterling ; B 40 -16 520 718 ; +C 164 ; WX 137 ; N fraction ; B -139 -19 396 703 ; +C 165 ; WX 456 ; N yen ; B 67 0 573 688 ; +C 166 ; WX 456 ; N florin ; B -43 -207 537 737 ; +C 167 ; WX 456 ; N section ; B 63 -191 479 737 ; +C 168 ; WX 456 ; N currency ; B 49 99 530 603 ; +C 169 ; WX 157 ; N quotesingle ; B 129 463 233 718 ; +C 170 ; WX 273 ; N quotedblleft ; B 113 470 378 725 ; +C 171 ; WX 456 ; N guillemotleft ; B 120 108 454 446 ; +C 172 ; WX 273 ; N guilsinglleft ; B 112 108 279 446 ; +C 173 ; WX 273 ; N guilsinglright ; B 91 108 257 446 ; +C 174 ; WX 410 ; N fi ; B 71 0 481 728 ; +C 175 ; WX 410 ; N fl ; B 71 0 479 728 ; +C 177 ; WX 456 ; N endash ; B 42 240 510 313 ; +C 178 ; WX 456 ; N dagger ; B 110 -159 510 718 ; +C 179 ; WX 456 ; N daggerdbl ; B 43 -159 511 718 ; +C 180 ; WX 228 ; N periodcentered ; B 106 190 211 315 ; +C 182 ; WX 440 ; N paragraph ; B 103 -173 533 718 ; +C 183 ; WX 287 ; N bullet ; B 74 202 339 517 ; +C 184 ; WX 182 ; N quotesinglbase ; B 17 -149 147 106 ; +C 185 ; WX 273 ; N quotedblbase ; B -5 -149 260 106 ; +C 186 ; WX 273 ; N quotedblright ; B 102 463 367 718 ; +C 187 ; WX 456 ; N guillemotright ; B 98 108 433 446 ; +C 188 ; WX 820 ; N ellipsis ; B 94 0 744 106 ; +C 189 ; WX 820 ; N perthousand ; B 72 -19 844 703 ; +C 191 ; WX 501 ; N questiondown ; B 70 -201 438 525 ; +C 193 ; WX 273 ; N grave ; B 139 593 276 734 ; +C 194 ; WX 273 ; N acute ; B 203 593 390 734 ; +C 195 ; WX 273 ; N circumflex ; B 121 593 359 734 ; +C 196 ; WX 273 ; N tilde ; B 102 606 402 722 ; +C 197 ; WX 273 ; N macron ; B 117 627 384 684 ; +C 198 ; WX 273 ; N breve ; B 137 595 391 731 ; +C 199 ; WX 273 ; N dotaccent ; B 204 604 297 706 ; +C 200 ; WX 273 ; N dieresis ; B 138 604 363 706 ; +C 202 ; WX 273 ; N ring ; B 175 572 330 756 ; +C 203 ; WX 273 ; N cedilla ; B 2 -225 191 0 ; +C 205 ; WX 273 ; N hungarumlaut ; B 129 593 463 734 ; +C 206 ; WX 273 ; N ogonek ; B 35 -225 204 0 ; +C 207 ; WX 273 ; N caron ; B 145 593 384 734 ; +C 208 ; WX 820 ; N emdash ; B 42 240 875 313 ; +C 225 ; WX 820 ; N AE ; B 7 0 899 718 ; +C 227 ; WX 303 ; N ordfeminine ; B 82 304 368 737 ; +C 232 ; WX 456 ; N Lslash ; B 34 0 455 718 ; +C 233 ; WX 638 ; N Oslash ; B 35 -19 730 737 ; +C 234 ; WX 820 ; N OE ; B 80 -19 915 737 ; +C 235 ; WX 299 ; N ordmasculine ; B 82 304 384 737 ; +C 241 ; WX 729 ; N ae ; B 50 -15 746 538 ; +C 245 ; WX 228 ; N dotlessi ; B 78 0 241 523 ; +C 248 ; WX 182 ; N lslash ; B 34 0 284 718 ; +C 249 ; WX 501 ; N oslash ; B 24 -22 531 545 ; +C 250 ; WX 774 ; N oe ; B 68 -15 791 538 ; +C 251 ; WX 501 ; N germandbls ; B 55 -15 539 728 ; +C -1 ; WX 501 ; N Zcaron ; B 19 0 607 929 ; +C -1 ; WX 410 ; N ccedilla ; B 61 -225 454 538 ; +C -1 ; WX 410 ; N ydieresis ; B 12 -214 492 706 ; +C -1 ; WX 456 ; N atilde ; B 50 -15 486 722 ; +C -1 ; WX 228 ; N icircumflex ; B 78 0 337 734 ; +C -1 ; WX 273 ; N threesuperior ; B 74 270 358 703 ; +C -1 ; WX 456 ; N ecircumflex ; B 69 -15 474 734 ; +C -1 ; WX 456 ; N thorn ; B 11 -207 479 718 ; +C -1 ; WX 456 ; N egrave ; B 69 -15 474 734 ; +C -1 ; WX 273 ; N twosuperior ; B 52 281 368 703 ; +C -1 ; WX 456 ; N eacute ; B 69 -15 481 734 ; +C -1 ; WX 456 ; N otilde ; B 68 -14 494 722 ; +C -1 ; WX 547 ; N Aacute ; B 11 0 560 929 ; +C -1 ; WX 456 ; N ocircumflex ; B 68 -14 479 734 ; +C -1 ; WX 410 ; N yacute ; B 12 -214 492 734 ; +C -1 ; WX 456 ; N udieresis ; B 77 -15 492 706 ; +C -1 ; WX 684 ; N threequarters ; B 106 -19 706 703 ; +C -1 ; WX 456 ; N acircumflex ; B 50 -15 458 734 ; +C -1 ; WX 592 ; N Eth ; B 57 0 626 718 ; +C -1 ; WX 456 ; N edieresis ; B 69 -15 474 706 ; +C -1 ; WX 456 ; N ugrave ; B 77 -15 492 734 ; +C -1 ; WX 820 ; N trademark ; B 152 306 866 718 ; +C -1 ; WX 456 ; N ograve ; B 68 -14 479 734 ; +C -1 ; WX 410 ; N scaron ; B 52 -15 453 734 ; +C -1 ; WX 228 ; N Idieresis ; B 75 0 375 901 ; +C -1 ; WX 456 ; N uacute ; B 77 -15 492 734 ; +C -1 ; WX 456 ; N agrave ; B 50 -15 458 734 ; +C -1 ; WX 456 ; N ntilde ; B 53 0 486 722 ; +C -1 ; WX 456 ; N aring ; B 50 -15 458 756 ; +C -1 ; WX 410 ; N zcaron ; B 25 0 468 734 ; +C -1 ; WX 228 ; N Icircumflex ; B 75 0 371 929 ; +C -1 ; WX 592 ; N Ntilde ; B 62 0 655 917 ; +C -1 ; WX 456 ; N ucircumflex ; B 77 -15 492 734 ; +C -1 ; WX 547 ; N Ecircumflex ; B 71 0 625 929 ; +C -1 ; WX 228 ; N Iacute ; B 75 0 401 929 ; +C -1 ; WX 592 ; N Ccedilla ; B 88 -225 640 737 ; +C -1 ; WX 638 ; N Odieresis ; B 86 -19 677 901 ; +C -1 ; WX 547 ; N Scaron ; B 74 -19 584 929 ; +C -1 ; WX 547 ; N Edieresis ; B 71 0 625 901 ; +C -1 ; WX 228 ; N Igrave ; B 75 0 288 929 ; +C -1 ; WX 456 ; N adieresis ; B 50 -15 458 706 ; +C -1 ; WX 638 ; N Ograve ; B 86 -19 677 929 ; +C -1 ; WX 547 ; N Egrave ; B 71 0 625 929 ; +C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 901 ; +C -1 ; WX 604 ; N registered ; B 44 -19 687 737 ; +C -1 ; WX 638 ; N Otilde ; B 86 -19 677 917 ; +C -1 ; WX 684 ; N onequarter ; B 123 -19 658 703 ; +C -1 ; WX 592 ; N Ugrave ; B 101 -19 653 929 ; +C -1 ; WX 592 ; N Ucircumflex ; B 101 -19 653 929 ; +C -1 ; WX 547 ; N Thorn ; B 71 0 584 718 ; +C -1 ; WX 479 ; N divide ; B 70 -19 497 524 ; +C -1 ; WX 547 ; N Atilde ; B 11 0 573 917 ; +C -1 ; WX 592 ; N Uacute ; B 101 -19 653 929 ; +C -1 ; WX 638 ; N Ocircumflex ; B 86 -19 677 929 ; +C -1 ; WX 479 ; N logicalnot ; B 87 108 515 390 ; +C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ; +C -1 ; WX 228 ; N idieresis ; B 78 0 341 706 ; +C -1 ; WX 228 ; N iacute ; B 78 0 367 734 ; +C -1 ; WX 456 ; N aacute ; B 50 -15 481 734 ; +C -1 ; WX 479 ; N plusminus ; B 32 0 507 506 ; +C -1 ; WX 479 ; N multiply ; B 41 0 526 506 ; +C -1 ; WX 592 ; N Udieresis ; B 101 -19 653 901 ; +C -1 ; WX 479 ; N minus ; B 70 216 497 289 ; +C -1 ; WX 273 ; N onesuperior ; B 136 281 305 703 ; +C -1 ; WX 547 ; N Eacute ; B 71 0 625 929 ; +C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ; +C -1 ; WX 604 ; N copyright ; B 44 -19 687 737 ; +C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ; +C -1 ; WX 456 ; N odieresis ; B 68 -14 479 706 ; +C -1 ; WX 456 ; N oacute ; B 68 -14 481 734 ; +C -1 ; WX 328 ; N degree ; B 138 411 384 703 ; +C -1 ; WX 228 ; N igrave ; B 78 0 254 734 ; +C -1 ; WX 456 ; N mu ; B 20 -207 492 523 ; +C -1 ; WX 638 ; N Oacute ; B 86 -19 677 929 ; +C -1 ; WX 456 ; N eth ; B 67 -15 506 737 ; +C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ; +C -1 ; WX 547 ; N Yacute ; B 137 0 661 929 ; +C -1 ; WX 213 ; N brokenbar ; B 74 -19 265 737 ; +C -1 ; WX 684 ; N onehalf ; B 93 -19 688 703 ; +EndCharMetrics +StartKernData +StartKernPairs 250 + +KPX A y -40 +KPX A w -40 +KPX A v -40 +KPX A u -30 +KPX A Y -100 +KPX A W -50 +KPX A V -70 +KPX A U -50 +KPX A T -120 +KPX A Q -30 +KPX A O -30 +KPX A G -30 +KPX A C -30 + +KPX B period -20 +KPX B comma -20 +KPX B U -10 + +KPX C period -30 +KPX C comma -30 + +KPX D period -70 +KPX D comma -70 +KPX D Y -90 +KPX D W -40 +KPX D V -70 +KPX D A -40 + +KPX F r -45 +KPX F period -150 +KPX F o -30 +KPX F e -30 +KPX F comma -150 +KPX F a -50 +KPX F A -80 + +KPX J u -20 +KPX J period -30 +KPX J comma -30 +KPX J a -20 +KPX J A -20 + +KPX K y -50 +KPX K u -30 +KPX K o -40 +KPX K e -40 +KPX K O -50 + +KPX L y -30 +KPX L quoteright -160 +KPX L quotedblright -140 +KPX L Y -140 +KPX L W -70 +KPX L V -110 +KPX L T -110 + +KPX O period -40 +KPX O comma -40 +KPX O Y -70 +KPX O X -60 +KPX O W -30 +KPX O V -50 +KPX O T -40 +KPX O A -20 + +KPX P period -180 +KPX P o -50 +KPX P e -50 +KPX P comma -180 +KPX P a -40 +KPX P A -120 + +KPX Q U -10 + +KPX R Y -50 +KPX R W -30 +KPX R V -50 +KPX R U -40 +KPX R T -30 +KPX R O -20 + +KPX S period -20 +KPX S comma -20 + +KPX T y -120 +KPX T w -120 +KPX T u -120 +KPX T semicolon -20 +KPX T r -120 +KPX T period -120 +KPX T o -120 +KPX T hyphen -140 +KPX T e -120 +KPX T comma -120 +KPX T colon -20 +KPX T a -120 +KPX T O -40 +KPX T A -120 + +KPX U period -40 +KPX U comma -40 +KPX U A -40 + +KPX V u -70 +KPX V semicolon -40 +KPX V period -125 +KPX V o -80 +KPX V hyphen -80 +KPX V e -80 +KPX V comma -125 +KPX V colon -40 +KPX V a -70 +KPX V O -40 +KPX V G -40 +KPX V A -80 + +KPX W y -20 +KPX W u -30 +KPX W period -80 +KPX W o -30 +KPX W hyphen -40 +KPX W e -30 +KPX W comma -80 +KPX W a -40 +KPX W O -20 +KPX W A -50 + +KPX Y u -110 +KPX Y semicolon -60 +KPX Y period -140 +KPX Y o -140 +KPX Y i -20 +KPX Y hyphen -140 +KPX Y e -140 +KPX Y comma -140 +KPX Y colon -60 +KPX Y a -140 +KPX Y O -85 +KPX Y A -110 + +KPX a y -30 +KPX a w -20 +KPX a v -20 + +KPX b y -20 +KPX b v -20 +KPX b u -20 +KPX b period -40 +KPX b l -20 +KPX b comma -40 +KPX b b -10 + +KPX c k -20 +KPX c comma -15 + +KPX colon space -50 + +KPX comma quoteright -100 +KPX comma quotedblright -100 + +KPX e y -20 +KPX e x -30 +KPX e w -20 +KPX e v -30 +KPX e period -15 +KPX e comma -15 + +KPX f quoteright 50 +KPX f quotedblright 60 +KPX f period -30 +KPX f o -30 +KPX f e -30 +KPX f dotlessi -28 +KPX f comma -30 +KPX f a -30 + +KPX g r -10 + +KPX h y -30 + +KPX k o -20 +KPX k e -20 + +KPX m y -15 +KPX m u -10 + +KPX n y -15 +KPX n v -20 +KPX n u -10 + +KPX o y -30 +KPX o x -30 +KPX o w -15 +KPX o v -15 +KPX o period -40 +KPX o comma -40 + +KPX oslash z -55 +KPX oslash y -70 +KPX oslash x -85 +KPX oslash w -70 +KPX oslash v -70 +KPX oslash u -55 +KPX oslash t -55 +KPX oslash s -55 +KPX oslash r -55 +KPX oslash q -55 +KPX oslash period -95 +KPX oslash p -55 +KPX oslash o -55 +KPX oslash n -55 +KPX oslash m -55 +KPX oslash l -55 +KPX oslash k -55 +KPX oslash j -55 +KPX oslash i -55 +KPX oslash h -55 +KPX oslash g -55 +KPX oslash f -55 +KPX oslash e -55 +KPX oslash d -55 +KPX oslash comma -95 +KPX oslash c -55 +KPX oslash b -55 +KPX oslash a -55 + +KPX p y -30 +KPX p period -35 +KPX p comma -35 + +KPX period space -60 +KPX period quoteright -100 +KPX period quotedblright -100 + +KPX quotedblright space -40 + +KPX quoteleft quoteleft -57 + +KPX quoteright space -70 +KPX quoteright s -50 +KPX quoteright r -50 +KPX quoteright quoteright -57 +KPX quoteright d -50 + +KPX r y 30 +KPX r v 30 +KPX r u 15 +KPX r t 40 +KPX r semicolon 30 +KPX r period -50 +KPX r p 30 +KPX r n 25 +KPX r m 25 +KPX r l 15 +KPX r k 15 +KPX r i 15 +KPX r comma -50 +KPX r colon 30 +KPX r a -10 + +KPX s w -30 +KPX s period -15 +KPX s comma -15 + +KPX semicolon space -50 + +KPX space quoteleft -60 +KPX space quotedblleft -30 +KPX space Y -90 +KPX space W -40 +KPX space V -50 +KPX space T -50 + +KPX v period -80 +KPX v o -25 +KPX v e -25 +KPX v comma -80 +KPX v a -25 + +KPX w period -60 +KPX w o -10 +KPX w e -10 +KPX w comma -60 +KPX w a -15 + +KPX x e -30 + +KPX y period -100 +KPX y o -20 +KPX y e -20 +KPX y comma -100 +KPX y a -20 + +KPX z o -15 +KPX z e -15 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 171 195 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 171 195 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 171 195 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 171 195 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 171 195 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 171 195 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 171 195 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 171 195 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 171 195 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 12 195 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 12 195 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 12 195 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 12 195 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 202 195 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 217 195 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 217 195 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 217 195 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 217 195 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 217 195 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 171 195 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 195 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 195 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 195 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 195 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 171 195 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 171 195 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 148 195 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncb8a.afm new file mode 100644 index 00000000..ba1fed6d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncb8a.afm @@ -0,0 +1,472 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue May 28 16:48:12 1991 +Comment UniqueID 35031 +Comment VMusage 30773 37665 +FontName NewCenturySchlbk-Bold +FullName New Century Schoolbook Bold +FamilyName New Century Schoolbook +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -165 -250 1000 988 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.009 +Notice Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 722 +XHeight 475 +Ascender 737 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 287 ; N space ; B 0 0 0 0 ; +C 33 ; WX 296 ; N exclam ; B 53 -15 243 737 ; +C 34 ; WX 333 ; N quotedbl ; B 0 378 333 737 ; +C 35 ; WX 574 ; N numbersign ; B 36 0 538 690 ; +C 36 ; WX 574 ; N dollar ; B 25 -141 549 810 ; +C 37 ; WX 833 ; N percent ; B 14 -15 819 705 ; +C 38 ; WX 852 ; N ampersand ; B 34 -15 818 737 ; +C 39 ; WX 241 ; N quoteright ; B 22 378 220 737 ; +C 40 ; WX 389 ; N parenleft ; B 77 -117 345 745 ; +C 41 ; WX 389 ; N parenright ; B 44 -117 312 745 ; +C 42 ; WX 500 ; N asterisk ; B 54 302 446 737 ; +C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; +C 44 ; WX 278 ; N comma ; B 40 -184 238 175 ; +C 45 ; WX 333 ; N hyphen ; B 42 174 291 302 ; +C 46 ; WX 278 ; N period ; B 44 -15 234 175 ; +C 47 ; WX 278 ; N slash ; B -42 -15 320 737 ; +C 48 ; WX 574 ; N zero ; B 27 -15 547 705 ; +C 49 ; WX 574 ; N one ; B 83 0 491 705 ; +C 50 ; WX 574 ; N two ; B 19 0 531 705 ; +C 51 ; WX 574 ; N three ; B 23 -15 531 705 ; +C 52 ; WX 574 ; N four ; B 19 0 547 705 ; +C 53 ; WX 574 ; N five ; B 32 -15 534 705 ; +C 54 ; WX 574 ; N six ; B 27 -15 547 705 ; +C 55 ; WX 574 ; N seven ; B 45 -15 547 705 ; +C 56 ; WX 574 ; N eight ; B 27 -15 548 705 ; +C 57 ; WX 574 ; N nine ; B 27 -15 547 705 ; +C 58 ; WX 278 ; N colon ; B 44 -15 234 485 ; +C 59 ; WX 278 ; N semicolon ; B 40 -184 238 485 ; +C 60 ; WX 606 ; N less ; B 50 -9 556 515 ; +C 61 ; WX 606 ; N equal ; B 50 103 556 403 ; +C 62 ; WX 606 ; N greater ; B 50 -9 556 515 ; +C 63 ; WX 500 ; N question ; B 23 -15 477 737 ; +C 64 ; WX 747 ; N at ; B -2 -15 750 737 ; +C 65 ; WX 759 ; N A ; B -19 0 778 737 ; +C 66 ; WX 778 ; N B ; B 19 0 739 722 ; +C 67 ; WX 778 ; N C ; B 39 -15 723 737 ; +C 68 ; WX 833 ; N D ; B 19 0 794 722 ; +C 69 ; WX 759 ; N E ; B 19 0 708 722 ; +C 70 ; WX 722 ; N F ; B 19 0 697 722 ; +C 71 ; WX 833 ; N G ; B 39 -15 818 737 ; +C 72 ; WX 870 ; N H ; B 19 0 851 722 ; +C 73 ; WX 444 ; N I ; B 29 0 415 722 ; +C 74 ; WX 648 ; N J ; B 6 -15 642 722 ; +C 75 ; WX 815 ; N K ; B 19 0 822 722 ; +C 76 ; WX 722 ; N L ; B 19 0 703 722 ; +C 77 ; WX 981 ; N M ; B 10 0 971 722 ; +C 78 ; WX 833 ; N N ; B 5 -10 828 722 ; +C 79 ; WX 833 ; N O ; B 39 -15 794 737 ; +C 80 ; WX 759 ; N P ; B 24 0 735 722 ; +C 81 ; WX 833 ; N Q ; B 39 -189 808 737 ; +C 82 ; WX 815 ; N R ; B 19 -15 815 722 ; +C 83 ; WX 667 ; N S ; B 51 -15 634 737 ; +C 84 ; WX 722 ; N T ; B 16 0 706 722 ; +C 85 ; WX 833 ; N U ; B 14 -15 825 722 ; +C 86 ; WX 759 ; N V ; B -19 -10 778 722 ; +C 87 ; WX 981 ; N W ; B 7 -10 974 722 ; +C 88 ; WX 722 ; N X ; B -12 0 734 722 ; +C 89 ; WX 722 ; N Y ; B -12 0 734 722 ; +C 90 ; WX 667 ; N Z ; B 28 0 639 722 ; +C 91 ; WX 389 ; N bracketleft ; B 84 -109 339 737 ; +C 92 ; WX 606 ; N backslash ; B 122 -15 484 737 ; +C 93 ; WX 389 ; N bracketright ; B 50 -109 305 737 ; +C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 241 ; N quoteleft ; B 22 378 220 737 ; +C 97 ; WX 611 ; N a ; B 40 -15 601 485 ; +C 98 ; WX 648 ; N b ; B 4 -15 616 737 ; +C 99 ; WX 556 ; N c ; B 32 -15 524 485 ; +C 100 ; WX 667 ; N d ; B 32 -15 644 737 ; +C 101 ; WX 574 ; N e ; B 32 -15 542 485 ; +C 102 ; WX 389 ; N f ; B 11 0 461 737 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 30 -205 623 535 ; +C 104 ; WX 685 ; N h ; B 17 0 662 737 ; +C 105 ; WX 370 ; N i ; B 26 0 338 737 ; +C 106 ; WX 352 ; N j ; B -86 -205 271 737 ; +C 107 ; WX 667 ; N k ; B 17 0 662 737 ; +C 108 ; WX 352 ; N l ; B 17 0 329 737 ; +C 109 ; WX 963 ; N m ; B 17 0 940 485 ; +C 110 ; WX 685 ; N n ; B 17 0 662 485 ; +C 111 ; WX 611 ; N o ; B 32 -15 579 485 ; +C 112 ; WX 667 ; N p ; B 17 -205 629 485 ; +C 113 ; WX 648 ; N q ; B 32 -205 638 485 ; +C 114 ; WX 519 ; N r ; B 17 0 516 485 ; +C 115 ; WX 500 ; N s ; B 48 -15 476 485 ; +C 116 ; WX 426 ; N t ; B 21 -15 405 675 ; +C 117 ; WX 685 ; N u ; B 17 -15 668 475 ; +C 118 ; WX 611 ; N v ; B 12 -10 599 475 ; +C 119 ; WX 889 ; N w ; B 16 -10 873 475 ; +C 120 ; WX 611 ; N x ; B 12 0 599 475 ; +C 121 ; WX 611 ; N y ; B 12 -205 599 475 ; +C 122 ; WX 537 ; N z ; B 38 0 499 475 ; +C 123 ; WX 389 ; N braceleft ; B 36 -109 313 737 ; +C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ; +C 125 ; WX 389 ; N braceright ; B 76 -109 353 737 ; +C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ; +C 161 ; WX 296 ; N exclamdown ; B 53 -205 243 547 ; +C 162 ; WX 574 ; N cent ; B 32 -102 528 572 ; +C 163 ; WX 574 ; N sterling ; B 16 -15 558 705 ; +C 164 ; WX 167 ; N fraction ; B -165 -15 332 705 ; +C 165 ; WX 574 ; N yen ; B -10 0 584 690 ; +C 166 ; WX 574 ; N florin ; B 14 -205 548 737 ; +C 167 ; WX 500 ; N section ; B 62 -86 438 737 ; +C 168 ; WX 574 ; N currency ; B 27 84 547 605 ; +C 169 ; WX 241 ; N quotesingle ; B 53 378 189 737 ; +C 170 ; WX 481 ; N quotedblleft ; B 22 378 459 737 ; +C 171 ; WX 500 ; N guillemotleft ; B 46 79 454 397 ; +C 172 ; WX 333 ; N guilsinglleft ; B 62 79 271 397 ; +C 173 ; WX 333 ; N guilsinglright ; B 62 79 271 397 ; +C 174 ; WX 685 ; N fi ; B 11 0 666 737 ; +C 175 ; WX 685 ; N fl ; B 11 0 666 737 ; +C 177 ; WX 500 ; N endash ; B 0 184 500 292 ; +C 178 ; WX 500 ; N dagger ; B 39 -101 461 737 ; +C 179 ; WX 500 ; N daggerdbl ; B 39 -89 461 737 ; +C 180 ; WX 278 ; N periodcentered ; B 53 200 225 372 ; +C 182 ; WX 747 ; N paragraph ; B 96 -71 631 722 ; +C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; +C 184 ; WX 241 ; N quotesinglbase ; B 22 -184 220 175 ; +C 185 ; WX 481 ; N quotedblbase ; B 22 -184 459 175 ; +C 186 ; WX 481 ; N quotedblright ; B 22 378 459 737 ; +C 187 ; WX 500 ; N guillemotright ; B 46 79 454 397 ; +C 188 ; WX 1000 ; N ellipsis ; B 72 -15 928 175 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -15 993 705 ; +C 191 ; WX 500 ; N questiondown ; B 23 -205 477 547 ; +C 193 ; WX 333 ; N grave ; B 2 547 249 737 ; +C 194 ; WX 333 ; N acute ; B 84 547 331 737 ; +C 195 ; WX 333 ; N circumflex ; B -10 547 344 725 ; +C 196 ; WX 333 ; N tilde ; B -24 563 357 705 ; +C 197 ; WX 333 ; N macron ; B -6 582 339 664 ; +C 198 ; WX 333 ; N breve ; B 9 547 324 714 ; +C 199 ; WX 333 ; N dotaccent ; B 95 552 237 694 ; +C 200 ; WX 333 ; N dieresis ; B -12 552 345 694 ; +C 202 ; WX 333 ; N ring ; B 58 545 274 761 ; +C 203 ; WX 333 ; N cedilla ; B 17 -224 248 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -16 547 431 737 ; +C 206 ; WX 333 ; N ogonek ; B 168 -163 346 3 ; +C 207 ; WX 333 ; N caron ; B -10 547 344 725 ; +C 208 ; WX 1000 ; N emdash ; B 0 184 1000 292 ; +C 225 ; WX 981 ; N AE ; B -29 0 963 722 ; +C 227 ; WX 367 ; N ordfeminine ; B 1 407 393 705 ; +C 232 ; WX 722 ; N Lslash ; B 19 0 703 722 ; +C 233 ; WX 833 ; N Oslash ; B 39 -53 794 775 ; +C 234 ; WX 1000 ; N OE ; B 0 0 982 722 ; +C 235 ; WX 367 ; N ordmasculine ; B 1 407 366 705 ; +C 241 ; WX 870 ; N ae ; B 32 -15 838 485 ; +C 245 ; WX 370 ; N dotlessi ; B 26 0 338 475 ; +C 248 ; WX 352 ; N lslash ; B 17 0 329 737 ; +C 249 ; WX 611 ; N oslash ; B 32 -103 579 573 ; +C 250 ; WX 907 ; N oe ; B 32 -15 875 485 ; +C 251 ; WX 611 ; N germandbls ; B -2 -15 580 737 ; +C -1 ; WX 574 ; N ecircumflex ; B 32 -15 542 725 ; +C -1 ; WX 574 ; N edieresis ; B 32 -15 542 694 ; +C -1 ; WX 611 ; N aacute ; B 40 -15 601 737 ; +C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; +C -1 ; WX 370 ; N icircumflex ; B 9 0 363 725 ; +C -1 ; WX 685 ; N udieresis ; B 17 -15 668 694 ; +C -1 ; WX 611 ; N ograve ; B 32 -15 579 737 ; +C -1 ; WX 685 ; N uacute ; B 17 -15 668 737 ; +C -1 ; WX 685 ; N ucircumflex ; B 17 -15 668 725 ; +C -1 ; WX 759 ; N Aacute ; B -19 0 778 964 ; +C -1 ; WX 370 ; N igrave ; B 21 0 338 737 ; +C -1 ; WX 444 ; N Icircumflex ; B 29 0 415 952 ; +C -1 ; WX 556 ; N ccedilla ; B 32 -224 524 485 ; +C -1 ; WX 611 ; N adieresis ; B 40 -15 601 694 ; +C -1 ; WX 759 ; N Ecircumflex ; B 19 0 708 952 ; +C -1 ; WX 500 ; N scaron ; B 48 -15 476 725 ; +C -1 ; WX 667 ; N thorn ; B 17 -205 629 737 ; +C -1 ; WX 1000 ; N trademark ; B 6 317 982 722 ; +C -1 ; WX 574 ; N egrave ; B 32 -15 542 737 ; +C -1 ; WX 344 ; N threesuperior ; B -3 273 355 705 ; +C -1 ; WX 537 ; N zcaron ; B 38 0 499 725 ; +C -1 ; WX 611 ; N atilde ; B 40 -15 601 705 ; +C -1 ; WX 611 ; N aring ; B 40 -15 601 761 ; +C -1 ; WX 611 ; N ocircumflex ; B 32 -15 579 725 ; +C -1 ; WX 759 ; N Edieresis ; B 19 0 708 921 ; +C -1 ; WX 861 ; N threequarters ; B 15 -15 838 705 ; +C -1 ; WX 611 ; N ydieresis ; B 12 -205 599 694 ; +C -1 ; WX 611 ; N yacute ; B 12 -205 599 737 ; +C -1 ; WX 370 ; N iacute ; B 26 0 350 737 ; +C -1 ; WX 759 ; N Acircumflex ; B -19 0 778 952 ; +C -1 ; WX 833 ; N Uacute ; B 14 -15 825 964 ; +C -1 ; WX 574 ; N eacute ; B 32 -15 542 737 ; +C -1 ; WX 833 ; N Ograve ; B 39 -15 794 964 ; +C -1 ; WX 611 ; N agrave ; B 40 -15 601 737 ; +C -1 ; WX 833 ; N Udieresis ; B 14 -15 825 921 ; +C -1 ; WX 611 ; N acircumflex ; B 40 -15 601 725 ; +C -1 ; WX 444 ; N Igrave ; B 29 0 415 964 ; +C -1 ; WX 344 ; N twosuperior ; B -3 282 350 705 ; +C -1 ; WX 833 ; N Ugrave ; B 14 -15 825 964 ; +C -1 ; WX 861 ; N onequarter ; B 31 -15 838 705 ; +C -1 ; WX 833 ; N Ucircumflex ; B 14 -15 825 952 ; +C -1 ; WX 667 ; N Scaron ; B 51 -15 634 952 ; +C -1 ; WX 444 ; N Idieresis ; B 29 0 415 921 ; +C -1 ; WX 370 ; N idieresis ; B 7 0 364 694 ; +C -1 ; WX 759 ; N Egrave ; B 19 0 708 964 ; +C -1 ; WX 833 ; N Oacute ; B 39 -15 794 964 ; +C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ; +C -1 ; WX 759 ; N Atilde ; B -19 0 778 932 ; +C -1 ; WX 759 ; N Aring ; B -19 0 778 988 ; +C -1 ; WX 833 ; N Odieresis ; B 39 -15 794 921 ; +C -1 ; WX 759 ; N Adieresis ; B -19 0 778 921 ; +C -1 ; WX 833 ; N Ntilde ; B 5 -10 828 932 ; +C -1 ; WX 667 ; N Zcaron ; B 28 0 639 952 ; +C -1 ; WX 759 ; N Thorn ; B 24 0 735 722 ; +C -1 ; WX 444 ; N Iacute ; B 29 0 415 964 ; +C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; +C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ; +C -1 ; WX 759 ; N Eacute ; B 19 0 708 964 ; +C -1 ; WX 722 ; N Ydieresis ; B -12 0 734 921 ; +C -1 ; WX 344 ; N onesuperior ; B 31 282 309 705 ; +C -1 ; WX 685 ; N ugrave ; B 17 -15 668 737 ; +C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ; +C -1 ; WX 685 ; N ntilde ; B 17 0 662 705 ; +C -1 ; WX 833 ; N Otilde ; B 39 -15 794 932 ; +C -1 ; WX 611 ; N otilde ; B 32 -15 579 705 ; +C -1 ; WX 778 ; N Ccedilla ; B 39 -224 723 737 ; +C -1 ; WX 759 ; N Agrave ; B -19 0 778 964 ; +C -1 ; WX 861 ; N onehalf ; B 31 -15 838 705 ; +C -1 ; WX 833 ; N Eth ; B 19 0 794 722 ; +C -1 ; WX 400 ; N degree ; B 57 419 343 705 ; +C -1 ; WX 722 ; N Yacute ; B -12 0 734 964 ; +C -1 ; WX 833 ; N Ocircumflex ; B 39 -15 794 952 ; +C -1 ; WX 611 ; N oacute ; B 32 -15 579 737 ; +C -1 ; WX 685 ; N mu ; B 17 -205 668 475 ; +C -1 ; WX 606 ; N minus ; B 50 199 556 307 ; +C -1 ; WX 611 ; N eth ; B 32 -15 579 737 ; +C -1 ; WX 611 ; N odieresis ; B 32 -15 579 694 ; +C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; +C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ; +EndCharMetrics +StartKernData +StartKernPairs 128 + +KPX A y -18 +KPX A w -18 +KPX A v -18 +KPX A quoteright -74 +KPX A quotedblright -74 +KPX A Y -91 +KPX A W -74 +KPX A V -74 +KPX A U -18 +KPX A T -55 + +KPX C period -18 +KPX C comma -18 + +KPX D period -25 +KPX D comma -25 + +KPX F r -18 +KPX F period -125 +KPX F o -55 +KPX F i -18 +KPX F e -55 +KPX F comma -125 +KPX F a -74 + +KPX J u -18 +KPX J period -55 +KPX J o -18 +KPX J e -18 +KPX J comma -55 +KPX J a -18 +KPX J A -18 + +KPX K y -25 +KPX K u -18 + +KPX L y -25 +KPX L quoteright -100 +KPX L quotedblright -100 +KPX L Y -74 +KPX L W -74 +KPX L V -100 +KPX L T -100 + +KPX N period -18 +KPX N comma -18 + +KPX O period -25 +KPX O comma -25 +KPX O T 10 + +KPX P period -150 +KPX P o -55 +KPX P e -55 +KPX P comma -150 +KPX P a -55 +KPX P A -74 + +KPX S period -18 +KPX S comma -18 + +KPX T u -18 +KPX T r -18 +KPX T period -100 +KPX T o -74 +KPX T i -18 +KPX T hyphen -125 +KPX T e -74 +KPX T comma -100 +KPX T a -74 +KPX T O 10 +KPX T A -55 + +KPX U period -25 +KPX U comma -25 +KPX U A -18 + +KPX V u -55 +KPX V semicolon -37 +KPX V period -125 +KPX V o -74 +KPX V i -18 +KPX V hyphen -100 +KPX V e -74 +KPX V comma -125 +KPX V colon -37 +KPX V a -74 +KPX V A -74 + +KPX W y -25 +KPX W u -37 +KPX W semicolon -55 +KPX W period -100 +KPX W o -74 +KPX W i -18 +KPX W hyphen -100 +KPX W e -74 +KPX W comma -100 +KPX W colon -55 +KPX W a -74 +KPX W A -74 + +KPX Y u -55 +KPX Y semicolon -25 +KPX Y period -100 +KPX Y o -100 +KPX Y i -18 +KPX Y hyphen -125 +KPX Y e -100 +KPX Y comma -100 +KPX Y colon -25 +KPX Y a -100 +KPX Y A -91 + +KPX colon space -18 + +KPX comma space -18 +KPX comma quoteright -18 +KPX comma quotedblright -18 + +KPX f quoteright 75 +KPX f quotedblright 75 + +KPX period space -18 +KPX period quoteright -18 +KPX period quotedblright -18 + +KPX quotedblleft A -74 + +KPX quotedblright space -18 + +KPX quoteleft A -74 + +KPX quoteright s -25 +KPX quoteright d -25 + +KPX r period -74 +KPX r comma -74 + +KPX semicolon space -18 + +KPX space quoteleft -18 +KPX space quotedblleft -18 +KPX space Y -18 +KPX space W -18 +KPX space V -18 +KPX space T -18 +KPX space A -18 + +KPX v period -100 +KPX v comma -100 + +KPX w period -100 +KPX w comma -100 + +KPX y period -100 +KPX y comma -100 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 227 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 213 227 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 213 227 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 213 227 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 213 227 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 213 227 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 213 227 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 213 227 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 213 227 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 213 227 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 56 227 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 56 227 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 56 227 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 56 227 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 227 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 227 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 227 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 227 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 227 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 227 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 227 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 227 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 250 227 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 250 227 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 250 227 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 227 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 227 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 227 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 139 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 139 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 139 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 139 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 139 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 139 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 121 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 121 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 121 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 121 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 19 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 19 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 19 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 19 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 139 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 139 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 102 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncbi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncbi8a.afm new file mode 100644 index 00000000..7871147e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncbi8a.afm @@ -0,0 +1,602 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue May 28 16:56:07 1991 +Comment UniqueID 35034 +Comment VMusage 31030 37922 +FontName NewCenturySchlbk-BoldItalic +FullName New Century Schoolbook Bold Italic +FamilyName New Century Schoolbook +Weight Bold +ItalicAngle -16 +IsFixedPitch false +FontBBox -205 -250 1147 991 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 722 +XHeight 477 +Ascender 737 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 287 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 0 -15 333 737 ; +C 34 ; WX 400 ; N quotedbl ; B 66 388 428 737 ; +C 35 ; WX 574 ; N numbersign ; B 30 0 544 690 ; +C 36 ; WX 574 ; N dollar ; B 9 -120 565 810 ; +C 37 ; WX 889 ; N percent ; B 54 -28 835 727 ; +C 38 ; WX 889 ; N ampersand ; B 32 -15 823 737 ; +C 39 ; WX 259 ; N quoteright ; B 48 388 275 737 ; +C 40 ; WX 407 ; N parenleft ; B 72 -117 454 745 ; +C 41 ; WX 407 ; N parenright ; B -70 -117 310 745 ; +C 42 ; WX 500 ; N asterisk ; B 58 301 498 737 ; +C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; +C 44 ; WX 287 ; N comma ; B -57 -192 170 157 ; +C 45 ; WX 333 ; N hyphen ; B 2 177 263 299 ; +C 46 ; WX 287 ; N period ; B -20 -15 152 157 ; +C 47 ; WX 278 ; N slash ; B -41 -15 320 737 ; +C 48 ; WX 574 ; N zero ; B 21 -15 553 705 ; +C 49 ; WX 574 ; N one ; B 25 0 489 705 ; +C 50 ; WX 574 ; N two ; B -38 -3 538 705 ; +C 51 ; WX 574 ; N three ; B -7 -15 536 705 ; +C 52 ; WX 574 ; N four ; B -13 0 544 705 ; +C 53 ; WX 574 ; N five ; B 0 -15 574 705 ; +C 54 ; WX 574 ; N six ; B 31 -15 574 705 ; +C 55 ; WX 574 ; N seven ; B 64 -15 593 705 ; +C 56 ; WX 574 ; N eight ; B 0 -15 552 705 ; +C 57 ; WX 574 ; N nine ; B 0 -15 543 705 ; +C 58 ; WX 287 ; N colon ; B -20 -15 237 477 ; +C 59 ; WX 287 ; N semicolon ; B -57 -192 237 477 ; +C 60 ; WX 606 ; N less ; B 50 -9 556 515 ; +C 61 ; WX 606 ; N equal ; B 50 103 556 403 ; +C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ; +C 63 ; WX 481 ; N question ; B 79 -15 451 737 ; +C 64 ; WX 747 ; N at ; B -4 -15 751 737 ; +C 65 ; WX 741 ; N A ; B -75 0 716 737 ; +C 66 ; WX 759 ; N B ; B -50 0 721 722 ; +C 67 ; WX 759 ; N C ; B 37 -15 759 737 ; +C 68 ; WX 833 ; N D ; B -47 0 796 722 ; +C 69 ; WX 741 ; N E ; B -41 0 730 722 ; +C 70 ; WX 704 ; N F ; B -41 0 730 722 ; +C 71 ; WX 815 ; N G ; B 37 -15 805 737 ; +C 72 ; WX 870 ; N H ; B -41 0 911 722 ; +C 73 ; WX 444 ; N I ; B -41 0 485 722 ; +C 74 ; WX 667 ; N J ; B -20 -15 708 722 ; +C 75 ; WX 778 ; N K ; B -41 0 832 722 ; +C 76 ; WX 704 ; N L ; B -41 0 670 722 ; +C 77 ; WX 944 ; N M ; B -44 0 988 722 ; +C 78 ; WX 852 ; N N ; B -61 -10 913 722 ; +C 79 ; WX 833 ; N O ; B 37 -15 796 737 ; +C 80 ; WX 741 ; N P ; B -41 0 730 722 ; +C 81 ; WX 833 ; N Q ; B 37 -189 796 737 ; +C 82 ; WX 796 ; N R ; B -41 -15 749 722 ; +C 83 ; WX 685 ; N S ; B 1 -15 666 737 ; +C 84 ; WX 722 ; N T ; B 41 0 759 722 ; +C 85 ; WX 833 ; N U ; B 88 -15 900 722 ; +C 86 ; WX 741 ; N V ; B 32 -10 802 722 ; +C 87 ; WX 944 ; N W ; B 40 -10 1000 722 ; +C 88 ; WX 741 ; N X ; B -82 0 801 722 ; +C 89 ; WX 704 ; N Y ; B 13 0 775 722 ; +C 90 ; WX 704 ; N Z ; B -33 0 711 722 ; +C 91 ; WX 407 ; N bracketleft ; B 1 -109 464 737 ; +C 92 ; WX 606 ; N backslash ; B 161 -15 445 737 ; +C 93 ; WX 407 ; N bracketright ; B -101 -109 362 737 ; +C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 259 ; N quoteleft ; B 47 388 274 737 ; +C 97 ; WX 667 ; N a ; B 6 -15 636 477 ; +C 98 ; WX 611 ; N b ; B 29 -15 557 737 ; +C 99 ; WX 537 ; N c ; B 0 -15 482 477 ; +C 100 ; WX 667 ; N d ; B 0 -15 660 737 ; +C 101 ; WX 519 ; N e ; B 0 -15 479 477 ; +C 102 ; WX 389 ; N f ; B -48 -205 550 737 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B -63 -205 604 528 ; +C 104 ; WX 685 ; N h ; B 0 -15 639 737 ; +C 105 ; WX 389 ; N i ; B 32 -15 345 737 ; +C 106 ; WX 370 ; N j ; B -205 -205 347 737 ; +C 107 ; WX 648 ; N k ; B -11 -15 578 737 ; +C 108 ; WX 389 ; N l ; B 32 -15 375 737 ; +C 109 ; WX 944 ; N m ; B 0 -15 909 477 ; +C 110 ; WX 685 ; N n ; B 0 -15 639 477 ; +C 111 ; WX 574 ; N o ; B 0 -15 530 477 ; +C 112 ; WX 648 ; N p ; B -119 -205 590 477 ; +C 113 ; WX 630 ; N q ; B 0 -205 587 477 ; +C 114 ; WX 519 ; N r ; B 0 0 527 486 ; +C 115 ; WX 481 ; N s ; B 0 -15 435 477 ; +C 116 ; WX 407 ; N t ; B 24 -15 403 650 ; +C 117 ; WX 685 ; N u ; B 30 -15 635 477 ; +C 118 ; WX 556 ; N v ; B 30 -15 496 477 ; +C 119 ; WX 833 ; N w ; B 30 -15 773 477 ; +C 120 ; WX 574 ; N x ; B -46 -15 574 477 ; +C 121 ; WX 519 ; N y ; B -66 -205 493 477 ; +C 122 ; WX 519 ; N z ; B -19 -15 473 477 ; +C 123 ; WX 407 ; N braceleft ; B 52 -109 408 737 ; +C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ; +C 125 ; WX 407 ; N braceright ; B -25 -109 331 737 ; +C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ; +C 161 ; WX 333 ; N exclamdown ; B -44 -205 289 547 ; +C 162 ; WX 574 ; N cent ; B 30 -144 512 578 ; +C 163 ; WX 574 ; N sterling ; B -18 -15 566 705 ; +C 164 ; WX 167 ; N fraction ; B -166 -15 333 705 ; +C 165 ; WX 574 ; N yen ; B 17 0 629 690 ; +C 166 ; WX 574 ; N florin ; B -43 -205 575 737 ; +C 167 ; WX 500 ; N section ; B -30 -146 515 737 ; +C 168 ; WX 574 ; N currency ; B 27 84 547 605 ; +C 169 ; WX 287 ; N quotesingle ; B 112 388 250 737 ; +C 170 ; WX 481 ; N quotedblleft ; B 54 388 521 737 ; +C 171 ; WX 481 ; N guillemotleft ; B -35 69 449 407 ; +C 172 ; WX 278 ; N guilsinglleft ; B -25 69 244 407 ; +C 173 ; WX 278 ; N guilsinglright ; B -26 69 243 407 ; +C 174 ; WX 685 ; N fi ; B -70 -205 641 737 ; +C 175 ; WX 685 ; N fl ; B -70 -205 671 737 ; +C 177 ; WX 500 ; N endash ; B -47 189 479 287 ; +C 178 ; WX 500 ; N dagger ; B 48 -146 508 737 ; +C 179 ; WX 500 ; N daggerdbl ; B -60 -150 508 737 ; +C 180 ; WX 287 ; N periodcentered ; B 57 200 229 372 ; +C 182 ; WX 650 ; N paragraph ; B 25 -131 681 722 ; +C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; +C 184 ; WX 259 ; N quotesinglbase ; B -57 -192 170 157 ; +C 185 ; WX 481 ; N quotedblbase ; B -57 -192 412 157 ; +C 186 ; WX 481 ; N quotedblright ; B 43 388 510 737 ; +C 187 ; WX 481 ; N guillemotright ; B -31 69 453 407 ; +C 188 ; WX 1000 ; N ellipsis ; B 81 -15 919 157 ; +C 189 ; WX 1167 ; N perthousand ; B 20 -28 1147 727 ; +C 191 ; WX 481 ; N questiondown ; B 0 -205 372 547 ; +C 193 ; WX 333 ; N grave ; B 74 538 294 722 ; +C 194 ; WX 333 ; N acute ; B 123 538 372 722 ; +C 195 ; WX 333 ; N circumflex ; B 23 533 365 705 ; +C 196 ; WX 333 ; N tilde ; B 28 561 398 690 ; +C 197 ; WX 333 ; N macron ; B 47 573 404 649 ; +C 198 ; WX 333 ; N breve ; B 67 535 390 698 ; +C 199 ; WX 333 ; N dotaccent ; B 145 546 289 690 ; +C 200 ; WX 333 ; N dieresis ; B 33 546 393 690 ; +C 202 ; WX 333 ; N ring ; B 111 522 335 746 ; +C 203 ; WX 333 ; N cedilla ; B -21 -220 225 3 ; +C 205 ; WX 333 ; N hungarumlaut ; B 15 538 480 722 ; +C 206 ; WX 333 ; N ogonek ; B 68 -155 246 -10 ; +C 207 ; WX 333 ; N caron ; B 60 531 403 705 ; +C 208 ; WX 1000 ; N emdash ; B -47 189 979 287 ; +C 225 ; WX 889 ; N AE ; B -86 0 915 722 ; +C 227 ; WX 412 ; N ordfeminine ; B 47 407 460 705 ; +C 232 ; WX 704 ; N Lslash ; B -41 0 670 722 ; +C 233 ; WX 833 ; N Oslash ; B 35 -68 798 790 ; +C 234 ; WX 963 ; N OE ; B 29 0 989 722 ; +C 235 ; WX 356 ; N ordmasculine ; B 42 407 394 705 ; +C 241 ; WX 815 ; N ae ; B -18 -15 775 477 ; +C 245 ; WX 389 ; N dotlessi ; B 32 -15 345 477 ; +C 248 ; WX 389 ; N lslash ; B 5 -15 390 737 ; +C 249 ; WX 574 ; N oslash ; B 0 -121 530 583 ; +C 250 ; WX 852 ; N oe ; B -6 -15 812 477 ; +C 251 ; WX 574 ; N germandbls ; B -91 -205 540 737 ; +C -1 ; WX 519 ; N ecircumflex ; B 0 -15 479 705 ; +C -1 ; WX 519 ; N edieresis ; B 0 -15 486 690 ; +C -1 ; WX 667 ; N aacute ; B 6 -15 636 722 ; +C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; +C -1 ; WX 389 ; N icircumflex ; B 21 -15 363 698 ; +C -1 ; WX 685 ; N udieresis ; B 30 -15 635 690 ; +C -1 ; WX 574 ; N ograve ; B 0 -15 530 722 ; +C -1 ; WX 685 ; N uacute ; B 30 -15 635 722 ; +C -1 ; WX 685 ; N ucircumflex ; B 30 -15 635 705 ; +C -1 ; WX 741 ; N Aacute ; B -75 0 716 947 ; +C -1 ; WX 389 ; N igrave ; B 32 -15 345 715 ; +C -1 ; WX 444 ; N Icircumflex ; B -41 0 485 930 ; +C -1 ; WX 537 ; N ccedilla ; B 0 -220 482 477 ; +C -1 ; WX 667 ; N adieresis ; B 6 -15 636 690 ; +C -1 ; WX 741 ; N Ecircumflex ; B -41 0 730 930 ; +C -1 ; WX 481 ; N scaron ; B 0 -15 477 705 ; +C -1 ; WX 648 ; N thorn ; B -119 -205 590 737 ; +C -1 ; WX 950 ; N trademark ; B 42 317 1017 722 ; +C -1 ; WX 519 ; N egrave ; B 0 -15 479 722 ; +C -1 ; WX 344 ; N threesuperior ; B 3 273 361 705 ; +C -1 ; WX 519 ; N zcaron ; B -19 -15 473 695 ; +C -1 ; WX 667 ; N atilde ; B 6 -15 636 690 ; +C -1 ; WX 667 ; N aring ; B 6 -15 636 746 ; +C -1 ; WX 574 ; N ocircumflex ; B 0 -15 530 705 ; +C -1 ; WX 741 ; N Edieresis ; B -41 0 730 915 ; +C -1 ; WX 861 ; N threequarters ; B 35 -15 789 705 ; +C -1 ; WX 519 ; N ydieresis ; B -66 -205 493 690 ; +C -1 ; WX 519 ; N yacute ; B -66 -205 493 722 ; +C -1 ; WX 389 ; N iacute ; B 32 -15 370 715 ; +C -1 ; WX 741 ; N Acircumflex ; B -75 0 716 930 ; +C -1 ; WX 833 ; N Uacute ; B 88 -15 900 947 ; +C -1 ; WX 519 ; N eacute ; B 0 -15 479 722 ; +C -1 ; WX 833 ; N Ograve ; B 37 -15 796 947 ; +C -1 ; WX 667 ; N agrave ; B 6 -15 636 722 ; +C -1 ; WX 833 ; N Udieresis ; B 88 -15 900 915 ; +C -1 ; WX 667 ; N acircumflex ; B 6 -15 636 705 ; +C -1 ; WX 444 ; N Igrave ; B -41 0 485 947 ; +C -1 ; WX 344 ; N twosuperior ; B -17 280 362 705 ; +C -1 ; WX 833 ; N Ugrave ; B 88 -15 900 947 ; +C -1 ; WX 861 ; N onequarter ; B 17 -15 789 705 ; +C -1 ; WX 833 ; N Ucircumflex ; B 88 -15 900 930 ; +C -1 ; WX 685 ; N Scaron ; B 1 -15 666 930 ; +C -1 ; WX 444 ; N Idieresis ; B -41 0 509 915 ; +C -1 ; WX 389 ; N idieresis ; B 31 -15 391 683 ; +C -1 ; WX 741 ; N Egrave ; B -41 0 730 947 ; +C -1 ; WX 833 ; N Oacute ; B 37 -15 796 947 ; +C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ; +C -1 ; WX 741 ; N Atilde ; B -75 0 716 915 ; +C -1 ; WX 741 ; N Aring ; B -75 0 716 991 ; +C -1 ; WX 833 ; N Odieresis ; B 37 -15 796 915 ; +C -1 ; WX 741 ; N Adieresis ; B -75 0 716 915 ; +C -1 ; WX 852 ; N Ntilde ; B -61 -10 913 915 ; +C -1 ; WX 704 ; N Zcaron ; B -33 0 711 930 ; +C -1 ; WX 741 ; N Thorn ; B -41 0 690 722 ; +C -1 ; WX 444 ; N Iacute ; B -41 0 488 947 ; +C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; +C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ; +C -1 ; WX 741 ; N Eacute ; B -41 0 730 947 ; +C -1 ; WX 704 ; N Ydieresis ; B 13 0 775 915 ; +C -1 ; WX 344 ; N onesuperior ; B 19 282 326 705 ; +C -1 ; WX 685 ; N ugrave ; B 30 -15 635 722 ; +C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ; +C -1 ; WX 685 ; N ntilde ; B 0 -15 639 690 ; +C -1 ; WX 833 ; N Otilde ; B 37 -15 796 915 ; +C -1 ; WX 574 ; N otilde ; B 0 -15 530 690 ; +C -1 ; WX 759 ; N Ccedilla ; B 37 -220 759 737 ; +C -1 ; WX 741 ; N Agrave ; B -75 0 716 947 ; +C -1 ; WX 861 ; N onehalf ; B 17 -15 798 705 ; +C -1 ; WX 833 ; N Eth ; B -47 0 796 722 ; +C -1 ; WX 400 ; N degree ; B 86 419 372 705 ; +C -1 ; WX 704 ; N Yacute ; B 13 0 775 947 ; +C -1 ; WX 833 ; N Ocircumflex ; B 37 -15 796 930 ; +C -1 ; WX 574 ; N oacute ; B 0 -15 530 722 ; +C -1 ; WX 685 ; N mu ; B -89 -205 635 477 ; +C -1 ; WX 606 ; N minus ; B 50 199 556 307 ; +C -1 ; WX 574 ; N eth ; B 0 -15 530 752 ; +C -1 ; WX 574 ; N odieresis ; B 0 -15 530 690 ; +C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; +C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ; +EndCharMetrics +StartKernData +StartKernPairs 239 + +KPX A y -33 +KPX A w -25 +KPX A v -10 +KPX A u -15 +KPX A quoteright -95 +KPX A quotedblright -95 +KPX A Y -70 +KPX A W -84 +KPX A V -100 +KPX A U -32 +KPX A T 5 +KPX A Q 5 +KPX A O 5 +KPX A G 5 +KPX A C 5 + +KPX B period 15 +KPX B comma 15 +KPX B U 15 +KPX B A -11 + +KPX C A -5 + +KPX D period -11 +KPX D comma -11 +KPX D Y 6 +KPX D W -11 +KPX D V -18 + +KPX F r -27 +KPX F period -91 +KPX F o -47 +KPX F i -41 +KPX F e -41 +KPX F comma -91 +KPX F a -47 +KPX F A -79 + +KPX J u -39 +KPX J period -74 +KPX J o -40 +KPX J e -33 +KPX J comma -74 +KPX J a -40 +KPX J A -30 + +KPX K y -48 +KPX K u -4 +KPX K o -4 +KPX K e 18 + +KPX L y -30 +KPX L quoteright -100 +KPX L quotedblright -100 +KPX L Y -55 +KPX L W -69 +KPX L V -97 +KPX L T -75 + +KPX N period -49 +KPX N comma -49 + +KPX O period -18 +KPX O comma -18 +KPX O X -18 +KPX O W -15 +KPX O V -24 +KPX O A -5 + +KPX P period -100 +KPX P o -40 +KPX P e -33 +KPX P comma -100 +KPX P a -40 +KPX P A -80 + +KPX R W -14 +KPX R V -24 + +KPX S period -18 +KPX S comma -18 + +KPX T y -30 +KPX T w -30 +KPX T u -22 +KPX T r -9 +KPX T period -55 +KPX T o -40 +KPX T i -22 +KPX T hyphen -75 +KPX T h -9 +KPX T e -33 +KPX T comma -55 +KPX T a -40 +KPX T O 11 +KPX T A -60 + +KPX U period -25 +KPX U comma -25 +KPX U A -42 + +KPX V u -70 +KPX V semicolon 6 +KPX V period -94 +KPX V o -71 +KPX V i -35 +KPX V hyphen -94 +KPX V e -66 +KPX V comma -94 +KPX V colon -49 +KPX V a -55 +KPX V O -19 +KPX V G -12 +KPX V A -100 + +KPX W y -41 +KPX W u -25 +KPX W semicolon -22 +KPX W period -86 +KPX W o -33 +KPX W i -27 +KPX W hyphen -61 +KPX W h 5 +KPX W e -39 +KPX W comma -86 +KPX W colon -22 +KPX W a -33 +KPX W O -11 +KPX W A -66 + +KPX Y u -58 +KPX Y semicolon -55 +KPX Y period -91 +KPX Y o -77 +KPX Y i -22 +KPX Y hyphen -91 +KPX Y e -71 +KPX Y comma -91 +KPX Y colon -55 +KPX Y a -77 +KPX Y A -79 + +KPX a y -8 +KPX a w -8 +KPX a v 6 + +KPX b y -6 +KPX b v 8 +KPX b period 6 +KPX b comma 6 + +KPX c y -20 +KPX c period -8 +KPX c l -13 +KPX c k -8 +KPX c h -18 +KPX c comma -8 + +KPX colon space -18 + +KPX comma space -18 +KPX comma quoteright -18 +KPX comma quotedblright -18 + +KPX d y -15 +KPX d w -15 + +KPX e y -15 +KPX e x -5 +KPX e w -15 +KPX e p -11 +KPX e g -4 +KPX e b -8 + +KPX f quoteright 105 +KPX f quotedblright 105 +KPX f period -28 +KPX f o 7 +KPX f l 7 +KPX f i 7 +KPX f e 14 +KPX f dotlessi 7 +KPX f comma -28 +KPX f a 8 + +KPX g y -11 +KPX g r 11 +KPX g period -5 +KPX g comma -5 + +KPX h y -20 + +KPX i v 7 + +KPX k y -15 +KPX k o -22 +KPX k e -16 + +KPX l y -7 +KPX l w -7 + +KPX m y -20 +KPX m u -11 + +KPX n y -20 +KPX n v -7 +KPX n u -11 + +KPX o y -11 +KPX o w -8 +KPX o v 6 + +KPX p y -4 +KPX p period 8 +KPX p comma 8 + +KPX period space -18 +KPX period quoteright -18 +KPX period quotedblright -18 + +KPX quotedblleft quoteleft 20 +KPX quotedblleft A -60 + +KPX quotedblright space -18 + +KPX quoteleft A -80 + +KPX quoteright v -16 +KPX quoteright t -22 +KPX quoteright s -46 +KPX quoteright r -9 +KPX quoteright l -22 +KPX quoteright d -41 + +KPX r y -20 +KPX r v -7 +KPX r u -11 +KPX r t -11 +KPX r semicolon 9 +KPX r s -20 +KPX r quoteright 9 +KPX r period -90 +KPX r p -17 +KPX r o -11 +KPX r l -14 +KPX r k 9 +KPX r i -14 +KPX r hyphen -16 +KPX r g -11 +KPX r e -7 +KPX r d -7 +KPX r comma -90 +KPX r colon 9 +KPX r a -11 + +KPX s period 11 +KPX s comma 11 + +KPX semicolon space -18 + +KPX space quotedblleft -18 +KPX space Y -18 +KPX space W -33 +KPX space V -24 +KPX space T -18 +KPX space A -22 + +KPX v period -11 +KPX v o -6 +KPX v comma -11 +KPX v a -6 + +KPX w period -17 +KPX w o -14 +KPX w e -8 +KPX w comma -17 +KPX w a -14 + +KPX x e 5 + +KPX y period -25 +KPX y o 8 +KPX y e 15 +KPX y comma -25 +KPX y a 8 + +KPX z e 4 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 259 225 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 259 225 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 259 225 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 259 225 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 229 245 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 259 225 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 296 225 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 296 225 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 296 225 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 296 225 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 116 225 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 116 225 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 116 225 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 116 225 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 326 225 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 315 225 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 315 225 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 315 225 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 315 225 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 315 225 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 206 225 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 340 225 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 340 225 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 340 225 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 340 225 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 246 225 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 225 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 226 225 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 167 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 167 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 167 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 167 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 167 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 167 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 93 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 93 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 93 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 93 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -2 -7 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -2 -7 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -2 -7 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -2 -7 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 121 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 121 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 121 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 121 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 121 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 74 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 93 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 93 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 63 -10 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncr8a.afm new file mode 100644 index 00000000..b9f616cb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncr8a.afm @@ -0,0 +1,524 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue May 28 16:31:51 1991 +Comment UniqueID 35025 +Comment VMusage 30420 37312 +FontName NewCenturySchlbk-Roman +FullName New Century Schoolbook Roman +FamilyName New Century Schoolbook +Weight Roman +ItalicAngle 0 +IsFixedPitch false +FontBBox -195 -250 1000 965 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 722 +XHeight 464 +Ascender 737 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 296 ; N exclam ; B 86 -15 210 737 ; +C 34 ; WX 389 ; N quotedbl ; B 61 443 328 737 ; +C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ; +C 36 ; WX 556 ; N dollar ; B 45 -138 511 813 ; +C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ; +C 38 ; WX 815 ; N ampersand ; B 51 -15 775 737 ; +C 39 ; WX 204 ; N quoteright ; B 25 443 179 737 ; +C 40 ; WX 333 ; N parenleft ; B 40 -117 279 745 ; +C 41 ; WX 333 ; N parenright ; B 54 -117 293 745 ; +C 42 ; WX 500 ; N asterisk ; B 57 306 443 737 ; +C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; +C 44 ; WX 278 ; N comma ; B 62 -185 216 109 ; +C 45 ; WX 333 ; N hyphen ; B 42 199 291 277 ; +C 46 ; WX 278 ; N period ; B 77 -15 201 109 ; +C 47 ; WX 278 ; N slash ; B -32 -15 310 737 ; +C 48 ; WX 556 ; N zero ; B 42 -15 514 705 ; +C 49 ; WX 556 ; N one ; B 100 0 496 705 ; +C 50 ; WX 556 ; N two ; B 35 0 505 705 ; +C 51 ; WX 556 ; N three ; B 42 -15 498 705 ; +C 52 ; WX 556 ; N four ; B 28 0 528 705 ; +C 53 ; WX 556 ; N five ; B 46 -15 502 705 ; +C 54 ; WX 556 ; N six ; B 41 -15 515 705 ; +C 55 ; WX 556 ; N seven ; B 59 -15 508 705 ; +C 56 ; WX 556 ; N eight ; B 42 -15 514 705 ; +C 57 ; WX 556 ; N nine ; B 41 -15 515 705 ; +C 58 ; WX 278 ; N colon ; B 77 -15 201 474 ; +C 59 ; WX 278 ; N semicolon ; B 62 -185 216 474 ; +C 60 ; WX 606 ; N less ; B 50 -8 556 514 ; +C 61 ; WX 606 ; N equal ; B 50 117 556 389 ; +C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ; +C 63 ; WX 444 ; N question ; B 29 -15 415 737 ; +C 64 ; WX 737 ; N at ; B -8 -15 744 737 ; +C 65 ; WX 722 ; N A ; B -8 0 730 737 ; +C 66 ; WX 722 ; N B ; B 29 0 669 722 ; +C 67 ; WX 722 ; N C ; B 45 -15 668 737 ; +C 68 ; WX 778 ; N D ; B 29 0 733 722 ; +C 69 ; WX 722 ; N E ; B 29 0 663 722 ; +C 70 ; WX 667 ; N F ; B 29 0 638 722 ; +C 71 ; WX 778 ; N G ; B 45 -15 775 737 ; +C 72 ; WX 833 ; N H ; B 29 0 804 722 ; +C 73 ; WX 407 ; N I ; B 38 0 369 722 ; +C 74 ; WX 556 ; N J ; B 5 -15 540 722 ; +C 75 ; WX 778 ; N K ; B 29 0 803 722 ; +C 76 ; WX 667 ; N L ; B 29 0 644 722 ; +C 77 ; WX 944 ; N M ; B 29 0 915 722 ; +C 78 ; WX 815 ; N N ; B 24 -15 791 722 ; +C 79 ; WX 778 ; N O ; B 45 -15 733 737 ; +C 80 ; WX 667 ; N P ; B 29 0 650 722 ; +C 81 ; WX 778 ; N Q ; B 45 -190 748 737 ; +C 82 ; WX 722 ; N R ; B 29 -15 713 722 ; +C 83 ; WX 630 ; N S ; B 47 -15 583 737 ; +C 84 ; WX 667 ; N T ; B 19 0 648 722 ; +C 85 ; WX 815 ; N U ; B 16 -15 799 722 ; +C 86 ; WX 722 ; N V ; B -8 -10 730 722 ; +C 87 ; WX 981 ; N W ; B 5 -10 976 722 ; +C 88 ; WX 704 ; N X ; B -8 0 712 722 ; +C 89 ; WX 704 ; N Y ; B -11 0 715 722 ; +C 90 ; WX 611 ; N Z ; B 24 0 576 722 ; +C 91 ; WX 333 ; N bracketleft ; B 126 -109 315 737 ; +C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ; +C 93 ; WX 333 ; N bracketright ; B 18 -109 207 737 ; +C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 204 ; N quoteleft ; B 25 443 179 737 ; +C 97 ; WX 556 ; N a ; B 44 -15 542 479 ; +C 98 ; WX 556 ; N b ; B 10 -15 522 737 ; +C 99 ; WX 444 ; N c ; B 34 -15 426 479 ; +C 100 ; WX 574 ; N d ; B 34 -15 552 737 ; +C 101 ; WX 500 ; N e ; B 34 -15 466 479 ; +C 102 ; WX 333 ; N f ; B 18 0 437 737 ; L i fi ; L l fl ; +C 103 ; WX 537 ; N g ; B 23 -205 542 494 ; +C 104 ; WX 611 ; N h ; B 7 0 592 737 ; +C 105 ; WX 315 ; N i ; B 18 0 286 722 ; +C 106 ; WX 296 ; N j ; B -86 -205 216 722 ; +C 107 ; WX 593 ; N k ; B 10 0 589 737 ; +C 108 ; WX 315 ; N l ; B 18 0 286 737 ; +C 109 ; WX 889 ; N m ; B 26 0 863 479 ; +C 110 ; WX 611 ; N n ; B 22 0 589 479 ; +C 111 ; WX 500 ; N o ; B 34 -15 466 479 ; +C 112 ; WX 574 ; N p ; B 22 -205 540 479 ; +C 113 ; WX 556 ; N q ; B 34 -205 552 479 ; +C 114 ; WX 444 ; N r ; B 18 0 434 479 ; +C 115 ; WX 463 ; N s ; B 46 -15 417 479 ; +C 116 ; WX 389 ; N t ; B 18 -15 371 666 ; +C 117 ; WX 611 ; N u ; B 22 -15 589 464 ; +C 118 ; WX 537 ; N v ; B -6 -10 515 464 ; +C 119 ; WX 778 ; N w ; B 1 -10 749 464 ; +C 120 ; WX 537 ; N x ; B 8 0 529 464 ; +C 121 ; WX 537 ; N y ; B 4 -205 533 464 ; +C 122 ; WX 481 ; N z ; B 42 0 439 464 ; +C 123 ; WX 333 ; N braceleft ; B 54 -109 279 737 ; +C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ; +C 125 ; WX 333 ; N braceright ; B 54 -109 279 737 ; +C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ; +C 161 ; WX 296 ; N exclamdown ; B 86 -205 210 547 ; +C 162 ; WX 556 ; N cent ; B 74 -141 482 584 ; +C 163 ; WX 556 ; N sterling ; B 18 -15 538 705 ; +C 164 ; WX 167 ; N fraction ; B -195 -15 362 705 ; +C 165 ; WX 556 ; N yen ; B -1 0 557 690 ; +C 166 ; WX 556 ; N florin ; B 0 -205 538 737 ; +C 167 ; WX 500 ; N section ; B 55 -147 445 737 ; +C 168 ; WX 556 ; N currency ; B 26 93 530 597 ; +C 169 ; WX 204 ; N quotesingle ; B 59 443 145 737 ; +C 170 ; WX 389 ; N quotedblleft ; B 25 443 364 737 ; +C 171 ; WX 426 ; N guillemotleft ; B 39 78 387 398 ; +C 172 ; WX 259 ; N guilsinglleft ; B 39 78 220 398 ; +C 173 ; WX 259 ; N guilsinglright ; B 39 78 220 398 ; +C 174 ; WX 611 ; N fi ; B 18 0 582 737 ; +C 175 ; WX 611 ; N fl ; B 18 0 582 737 ; +C 177 ; WX 556 ; N endash ; B 0 208 556 268 ; +C 178 ; WX 500 ; N dagger ; B 42 -147 458 737 ; +C 179 ; WX 500 ; N daggerdbl ; B 42 -149 458 737 ; +C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ; +C 182 ; WX 606 ; N paragraph ; B 60 -132 546 722 ; +C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; +C 184 ; WX 204 ; N quotesinglbase ; B 25 -185 179 109 ; +C 185 ; WX 389 ; N quotedblbase ; B 25 -185 364 109 ; +C 186 ; WX 389 ; N quotedblright ; B 25 443 364 737 ; +C 187 ; WX 426 ; N guillemotright ; B 39 78 387 398 ; +C 188 ; WX 1000 ; N ellipsis ; B 105 -15 895 109 ; +C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ; +C 191 ; WX 444 ; N questiondown ; B 29 -205 415 547 ; +C 193 ; WX 333 ; N grave ; B 17 528 242 699 ; +C 194 ; WX 333 ; N acute ; B 91 528 316 699 ; +C 195 ; WX 333 ; N circumflex ; B 10 528 323 695 ; +C 196 ; WX 333 ; N tilde ; B 1 553 332 655 ; +C 197 ; WX 333 ; N macron ; B 10 568 323 623 ; +C 198 ; WX 333 ; N breve ; B 25 528 308 685 ; +C 199 ; WX 333 ; N dotaccent ; B 116 543 218 645 ; +C 200 ; WX 333 ; N dieresis ; B 16 543 317 645 ; +C 202 ; WX 333 ; N ring ; B 66 522 266 722 ; +C 203 ; WX 333 ; N cedilla ; B 29 -215 237 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -9 528 416 699 ; +C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ; +C 207 ; WX 333 ; N caron ; B 10 528 323 695 ; +C 208 ; WX 1000 ; N emdash ; B 0 208 1000 268 ; +C 225 ; WX 1000 ; N AE ; B 0 0 962 722 ; +C 227 ; WX 334 ; N ordfeminine ; B -4 407 338 705 ; +C 232 ; WX 667 ; N Lslash ; B 29 0 644 722 ; +C 233 ; WX 778 ; N Oslash ; B 45 -56 733 778 ; +C 234 ; WX 1000 ; N OE ; B 21 0 979 722 ; +C 235 ; WX 300 ; N ordmasculine ; B 4 407 296 705 ; +C 241 ; WX 796 ; N ae ; B 34 -15 762 479 ; +C 245 ; WX 315 ; N dotlessi ; B 18 0 286 464 ; +C 248 ; WX 315 ; N lslash ; B 18 0 286 737 ; +C 249 ; WX 500 ; N oslash ; B 34 -97 466 561 ; +C 250 ; WX 833 ; N oe ; B 34 -15 799 479 ; +C 251 ; WX 574 ; N germandbls ; B 30 -15 537 737 ; +C -1 ; WX 500 ; N ecircumflex ; B 34 -15 466 695 ; +C -1 ; WX 500 ; N edieresis ; B 34 -15 466 645 ; +C -1 ; WX 556 ; N aacute ; B 44 -15 542 699 ; +C -1 ; WX 737 ; N registered ; B -8 -15 744 737 ; +C -1 ; WX 315 ; N icircumflex ; B 1 0 314 695 ; +C -1 ; WX 611 ; N udieresis ; B 22 -15 589 645 ; +C -1 ; WX 500 ; N ograve ; B 34 -15 466 699 ; +C -1 ; WX 611 ; N uacute ; B 22 -15 589 699 ; +C -1 ; WX 611 ; N ucircumflex ; B 22 -15 589 695 ; +C -1 ; WX 722 ; N Aacute ; B -8 0 730 937 ; +C -1 ; WX 315 ; N igrave ; B 8 0 286 699 ; +C -1 ; WX 407 ; N Icircumflex ; B 38 0 369 933 ; +C -1 ; WX 444 ; N ccedilla ; B 34 -215 426 479 ; +C -1 ; WX 556 ; N adieresis ; B 44 -15 542 645 ; +C -1 ; WX 722 ; N Ecircumflex ; B 29 0 663 933 ; +C -1 ; WX 463 ; N scaron ; B 46 -15 417 695 ; +C -1 ; WX 574 ; N thorn ; B 22 -205 540 737 ; +C -1 ; WX 1000 ; N trademark ; B 32 318 968 722 ; +C -1 ; WX 500 ; N egrave ; B 34 -15 466 699 ; +C -1 ; WX 333 ; N threesuperior ; B 18 273 315 705 ; +C -1 ; WX 481 ; N zcaron ; B 42 0 439 695 ; +C -1 ; WX 556 ; N atilde ; B 44 -15 542 655 ; +C -1 ; WX 556 ; N aring ; B 44 -15 542 732 ; +C -1 ; WX 500 ; N ocircumflex ; B 34 -15 466 695 ; +C -1 ; WX 722 ; N Edieresis ; B 29 0 663 883 ; +C -1 ; WX 834 ; N threequarters ; B 28 -15 795 705 ; +C -1 ; WX 537 ; N ydieresis ; B 4 -205 533 645 ; +C -1 ; WX 537 ; N yacute ; B 4 -205 533 699 ; +C -1 ; WX 315 ; N iacute ; B 18 0 307 699 ; +C -1 ; WX 722 ; N Acircumflex ; B -8 0 730 933 ; +C -1 ; WX 815 ; N Uacute ; B 16 -15 799 937 ; +C -1 ; WX 500 ; N eacute ; B 34 -15 466 699 ; +C -1 ; WX 778 ; N Ograve ; B 45 -15 733 937 ; +C -1 ; WX 556 ; N agrave ; B 44 -15 542 699 ; +C -1 ; WX 815 ; N Udieresis ; B 16 -15 799 883 ; +C -1 ; WX 556 ; N acircumflex ; B 44 -15 542 695 ; +C -1 ; WX 407 ; N Igrave ; B 38 0 369 937 ; +C -1 ; WX 333 ; N twosuperior ; B 14 282 319 705 ; +C -1 ; WX 815 ; N Ugrave ; B 16 -15 799 937 ; +C -1 ; WX 834 ; N onequarter ; B 39 -15 795 705 ; +C -1 ; WX 815 ; N Ucircumflex ; B 16 -15 799 933 ; +C -1 ; WX 630 ; N Scaron ; B 47 -15 583 933 ; +C -1 ; WX 407 ; N Idieresis ; B 38 0 369 883 ; +C -1 ; WX 315 ; N idieresis ; B 7 0 308 645 ; +C -1 ; WX 722 ; N Egrave ; B 29 0 663 937 ; +C -1 ; WX 778 ; N Oacute ; B 45 -15 733 937 ; +C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ; +C -1 ; WX 722 ; N Atilde ; B -8 0 730 893 ; +C -1 ; WX 722 ; N Aring ; B -8 0 730 965 ; +C -1 ; WX 778 ; N Odieresis ; B 45 -15 733 883 ; +C -1 ; WX 722 ; N Adieresis ; B -8 0 730 883 ; +C -1 ; WX 815 ; N Ntilde ; B 24 -15 791 893 ; +C -1 ; WX 611 ; N Zcaron ; B 24 0 576 933 ; +C -1 ; WX 667 ; N Thorn ; B 29 0 650 722 ; +C -1 ; WX 407 ; N Iacute ; B 38 0 369 937 ; +C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; +C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ; +C -1 ; WX 722 ; N Eacute ; B 29 0 663 937 ; +C -1 ; WX 704 ; N Ydieresis ; B -11 0 715 883 ; +C -1 ; WX 333 ; N onesuperior ; B 39 282 294 705 ; +C -1 ; WX 611 ; N ugrave ; B 22 -15 589 699 ; +C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ; +C -1 ; WX 611 ; N ntilde ; B 22 0 589 655 ; +C -1 ; WX 778 ; N Otilde ; B 45 -15 733 893 ; +C -1 ; WX 500 ; N otilde ; B 34 -15 466 655 ; +C -1 ; WX 722 ; N Ccedilla ; B 45 -215 668 737 ; +C -1 ; WX 722 ; N Agrave ; B -8 0 730 937 ; +C -1 ; WX 834 ; N onehalf ; B 39 -15 820 705 ; +C -1 ; WX 778 ; N Eth ; B 29 0 733 722 ; +C -1 ; WX 400 ; N degree ; B 57 419 343 705 ; +C -1 ; WX 704 ; N Yacute ; B -11 0 715 937 ; +C -1 ; WX 778 ; N Ocircumflex ; B 45 -15 733 933 ; +C -1 ; WX 500 ; N oacute ; B 34 -15 466 699 ; +C -1 ; WX 611 ; N mu ; B 22 -205 589 464 ; +C -1 ; WX 606 ; N minus ; B 50 217 556 289 ; +C -1 ; WX 500 ; N eth ; B 34 -15 466 752 ; +C -1 ; WX 500 ; N odieresis ; B 34 -15 466 645 ; +C -1 ; WX 737 ; N copyright ; B -8 -15 744 737 ; +C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ; +EndCharMetrics +StartKernData +StartKernPairs 169 + +KPX A y -37 +KPX A w -25 +KPX A v -37 +KPX A quoteright -74 +KPX A quotedblright -74 +KPX A Y -75 +KPX A W -50 +KPX A V -75 +KPX A U -30 +KPX A T -18 + +KPX B period -37 +KPX B comma -37 +KPX B A -18 + +KPX C period -37 +KPX C comma -37 +KPX C A -18 + +KPX D period -37 +KPX D comma -37 +KPX D Y -18 +KPX D V -18 + +KPX F r -10 +KPX F period -125 +KPX F o -55 +KPX F i -10 +KPX F e -55 +KPX F comma -125 +KPX F a -65 +KPX F A -50 + +KPX G period -37 +KPX G comma -37 + +KPX J u -25 +KPX J period -74 +KPX J o -25 +KPX J e -25 +KPX J comma -74 +KPX J a -25 +KPX J A -18 + +KPX K y -25 +KPX K o 10 +KPX K e 10 + +KPX L y -25 +KPX L quoteright -100 +KPX L quotedblright -100 +KPX L Y -74 +KPX L W -74 +KPX L V -91 +KPX L T -75 + +KPX N period -55 +KPX N comma -55 + +KPX O period -37 +KPX O comma -37 +KPX O Y -18 +KPX O V -18 +KPX O T 10 + +KPX P period -125 +KPX P o -37 +KPX P e -37 +KPX P comma -125 +KPX P a -37 +KPX P A -55 + +KPX Q period -25 +KPX Q comma -25 + +KPX S period -37 +KPX S comma -37 + +KPX T semicolon -37 +KPX T period -125 +KPX T o -55 +KPX T hyphen -100 +KPX T e -55 +KPX T comma -125 +KPX T colon -37 +KPX T a -55 +KPX T O 10 +KPX T A -18 + +KPX U period -100 +KPX U comma -100 +KPX U A -30 + +KPX V u -75 +KPX V semicolon -75 +KPX V period -125 +KPX V o -75 +KPX V i -18 +KPX V hyphen -100 +KPX V e -75 +KPX V comma -125 +KPX V colon -75 +KPX V a -85 +KPX V O -18 +KPX V A -74 + +KPX W y -55 +KPX W u -55 +KPX W semicolon -100 +KPX W period -125 +KPX W o -60 +KPX W i -18 +KPX W hyphen -100 +KPX W e -60 +KPX W comma -125 +KPX W colon -100 +KPX W a -75 +KPX W A -50 + +KPX Y u -91 +KPX Y semicolon -75 +KPX Y period -100 +KPX Y o -100 +KPX Y i -18 +KPX Y hyphen -125 +KPX Y e -100 +KPX Y comma -100 +KPX Y colon -75 +KPX Y a -100 +KPX Y O -18 +KPX Y A -75 + +KPX a y -10 +KPX a w -10 +KPX a v -10 + +KPX b period -18 +KPX b comma -18 + +KPX c period -18 +KPX c l -7 +KPX c k -7 +KPX c h -7 +KPX c comma -18 + +KPX colon space -37 + +KPX comma space -37 +KPX comma quoteright -37 +KPX comma quotedblright -37 + +KPX e period -18 +KPX e comma -18 + +KPX f quoteright 100 +KPX f quotedblright 100 +KPX f period -37 +KPX f comma -37 + +KPX g period -25 +KPX g comma -25 + +KPX o period -18 +KPX o comma -18 + +KPX p period -18 +KPX p comma -18 + +KPX period space -37 +KPX period quoteright -37 +KPX period quotedblright -37 + +KPX quotedblleft A -74 + +KPX quotedblright space -37 + +KPX quoteleft quoteleft -25 +KPX quoteleft A -74 + +KPX quoteright s -25 +KPX quoteright quoteright -25 +KPX quoteright d -37 + +KPX r period -100 +KPX r hyphen -37 +KPX r comma -100 + +KPX s period -25 +KPX s comma -25 + +KPX semicolon space -37 + +KPX space quoteleft -37 +KPX space quotedblleft -37 +KPX space Y -37 +KPX space W -37 +KPX space V -37 +KPX space T -37 +KPX space A -37 + +KPX v period -125 +KPX v comma -125 + +KPX w period -125 +KPX w comma -125 +KPX w a -18 + +KPX y period -125 +KPX y comma -125 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 238 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 238 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 238 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 238 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 195 243 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 238 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 195 238 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 195 238 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 195 238 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 195 238 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 37 238 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 37 238 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 37 238 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 37 238 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 241 238 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 238 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 238 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 238 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 238 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 238 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 149 238 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 241 238 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 241 238 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 241 238 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 241 238 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 216 238 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 186 238 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 238 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 112 10 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -9 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -9 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -9 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -9 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 65 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 102 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 102 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 74 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncri8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncri8a.afm new file mode 100644 index 00000000..6dfd6a25 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pncri8a.afm @@ -0,0 +1,536 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue May 28 16:40:04 1991 +Comment UniqueID 35028 +Comment VMusage 31423 38315 +FontName NewCenturySchlbk-Italic +FullName New Century Schoolbook Italic +FamilyName New Century Schoolbook +Weight Medium +ItalicAngle -16 +IsFixedPitch false +FontBBox -166 -250 994 958 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.006 +Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 722 +XHeight 466 +Ascender 737 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 17 -15 303 737 ; +C 34 ; WX 400 ; N quotedbl ; B 127 463 363 737 ; +C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ; +C 36 ; WX 556 ; N dollar ; B 4 -142 536 808 ; +C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ; +C 38 ; WX 852 ; N ampersand ; B 24 -15 773 737 ; +C 39 ; WX 204 ; N quoteright ; B 39 463 229 737 ; +C 40 ; WX 333 ; N parenleft ; B 53 -117 411 745 ; +C 41 ; WX 333 ; N parenright ; B -93 -117 265 745 ; +C 42 ; WX 500 ; N asterisk ; B 80 318 500 737 ; +C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; +C 44 ; WX 278 ; N comma ; B -39 -165 151 109 ; +C 45 ; WX 333 ; N hyphen ; B 32 202 259 274 ; +C 46 ; WX 278 ; N period ; B 17 -15 141 109 ; +C 47 ; WX 606 ; N slash ; B 132 -15 474 737 ; +C 48 ; WX 556 ; N zero ; B 30 -15 526 705 ; +C 49 ; WX 556 ; N one ; B 50 0 459 705 ; +C 50 ; WX 556 ; N two ; B -37 0 506 705 ; +C 51 ; WX 556 ; N three ; B -2 -15 506 705 ; +C 52 ; WX 556 ; N four ; B -8 0 512 705 ; +C 53 ; WX 556 ; N five ; B 4 -15 540 705 ; +C 54 ; WX 556 ; N six ; B 36 -15 548 705 ; +C 55 ; WX 556 ; N seven ; B 69 -15 561 705 ; +C 56 ; WX 556 ; N eight ; B 6 -15 526 705 ; +C 57 ; WX 556 ; N nine ; B 8 -15 520 705 ; +C 58 ; WX 278 ; N colon ; B 17 -15 229 466 ; +C 59 ; WX 278 ; N semicolon ; B -39 -165 229 466 ; +C 60 ; WX 606 ; N less ; B 36 -8 542 514 ; +C 61 ; WX 606 ; N equal ; B 50 117 556 389 ; +C 62 ; WX 606 ; N greater ; B 64 -8 570 514 ; +C 63 ; WX 444 ; N question ; B 102 -15 417 737 ; +C 64 ; WX 747 ; N at ; B -2 -15 750 737 ; +C 65 ; WX 704 ; N A ; B -87 0 668 737 ; +C 66 ; WX 722 ; N B ; B -33 0 670 722 ; +C 67 ; WX 722 ; N C ; B 40 -15 712 737 ; +C 68 ; WX 778 ; N D ; B -33 0 738 722 ; +C 69 ; WX 722 ; N E ; B -33 0 700 722 ; +C 70 ; WX 667 ; N F ; B -33 0 700 722 ; +C 71 ; WX 778 ; N G ; B 40 -15 763 737 ; +C 72 ; WX 833 ; N H ; B -33 0 866 722 ; +C 73 ; WX 407 ; N I ; B -33 0 435 722 ; +C 74 ; WX 611 ; N J ; B -14 -15 651 722 ; +C 75 ; WX 741 ; N K ; B -33 0 816 722 ; +C 76 ; WX 667 ; N L ; B -33 0 627 722 ; +C 77 ; WX 944 ; N M ; B -33 0 977 722 ; +C 78 ; WX 815 ; N N ; B -51 -15 866 722 ; +C 79 ; WX 778 ; N O ; B 40 -15 738 737 ; +C 80 ; WX 667 ; N P ; B -33 0 667 722 ; +C 81 ; WX 778 ; N Q ; B 40 -190 738 737 ; +C 82 ; WX 741 ; N R ; B -45 -15 692 722 ; +C 83 ; WX 667 ; N S ; B -6 -15 638 737 ; +C 84 ; WX 685 ; N T ; B 40 0 725 722 ; +C 85 ; WX 815 ; N U ; B 93 -15 867 722 ; +C 86 ; WX 704 ; N V ; B 36 -10 779 722 ; +C 87 ; WX 926 ; N W ; B 53 -10 978 722 ; +C 88 ; WX 704 ; N X ; B -75 0 779 722 ; +C 89 ; WX 685 ; N Y ; B 31 0 760 722 ; +C 90 ; WX 667 ; N Z ; B -25 0 667 722 ; +C 91 ; WX 333 ; N bracketleft ; B -55 -109 388 737 ; +C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ; +C 93 ; WX 333 ; N bracketright ; B -77 -109 366 737 ; +C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 204 ; N quoteleft ; B 39 463 229 737 ; +C 97 ; WX 574 ; N a ; B 2 -15 524 466 ; +C 98 ; WX 556 ; N b ; B 32 -15 488 737 ; +C 99 ; WX 444 ; N c ; B 2 -15 394 466 ; +C 100 ; WX 611 ; N d ; B 2 -15 585 737 ; +C 101 ; WX 444 ; N e ; B -6 -15 388 466 ; +C 102 ; WX 333 ; N f ; B -68 -205 470 737 ; L i fi ; L l fl ; +C 103 ; WX 537 ; N g ; B -79 -205 523 497 ; +C 104 ; WX 611 ; N h ; B 14 -15 562 737 ; +C 105 ; WX 333 ; N i ; B 29 -15 282 715 ; +C 106 ; WX 315 ; N j ; B -166 -205 318 715 ; +C 107 ; WX 556 ; N k ; B 0 -15 497 737 ; +C 108 ; WX 333 ; N l ; B 14 -15 292 737 ; +C 109 ; WX 889 ; N m ; B 14 -15 840 466 ; +C 110 ; WX 611 ; N n ; B 14 -15 562 466 ; +C 111 ; WX 500 ; N o ; B 2 -15 450 466 ; +C 112 ; WX 574 ; N p ; B -101 -205 506 466 ; +C 113 ; WX 556 ; N q ; B 2 -205 500 466 ; +C 114 ; WX 444 ; N r ; B 10 0 434 466 ; +C 115 ; WX 444 ; N s ; B 2 -15 394 466 ; +C 116 ; WX 352 ; N t ; B 24 -15 328 619 ; +C 117 ; WX 611 ; N u ; B 44 -15 556 466 ; +C 118 ; WX 519 ; N v ; B 31 -15 447 466 ; +C 119 ; WX 778 ; N w ; B 31 -15 706 466 ; +C 120 ; WX 500 ; N x ; B -33 -15 471 466 ; +C 121 ; WX 500 ; N y ; B -83 -205 450 466 ; +C 122 ; WX 463 ; N z ; B -33 -15 416 466 ; +C 123 ; WX 333 ; N braceleft ; B 38 -109 394 737 ; +C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ; +C 125 ; WX 333 ; N braceright ; B -87 -109 269 737 ; +C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ; +C 161 ; WX 333 ; N exclamdown ; B -22 -205 264 547 ; +C 162 ; WX 556 ; N cent ; B 62 -144 486 580 ; +C 163 ; WX 556 ; N sterling ; B -13 -15 544 705 ; +C 164 ; WX 167 ; N fraction ; B -134 -15 301 705 ; +C 165 ; WX 556 ; N yen ; B 40 0 624 690 ; +C 166 ; WX 556 ; N florin ; B -58 -205 569 737 ; +C 167 ; WX 500 ; N section ; B -10 -147 480 737 ; +C 168 ; WX 556 ; N currency ; B 26 93 530 597 ; +C 169 ; WX 278 ; N quotesingle ; B 151 463 237 737 ; +C 170 ; WX 389 ; N quotedblleft ; B 39 463 406 737 ; +C 171 ; WX 426 ; N guillemotleft ; B -15 74 402 402 ; +C 172 ; WX 333 ; N guilsinglleft ; B 40 74 259 402 ; +C 173 ; WX 333 ; N guilsinglright ; B 40 74 259 402 ; +C 174 ; WX 611 ; N fi ; B -68 -205 555 737 ; +C 175 ; WX 611 ; N fl ; B -68 -205 587 737 ; +C 177 ; WX 500 ; N endash ; B -27 208 487 268 ; +C 178 ; WX 500 ; N dagger ; B 51 -147 506 737 ; +C 179 ; WX 500 ; N daggerdbl ; B -54 -147 506 737 ; +C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ; +C 182 ; WX 650 ; N paragraph ; B 48 -132 665 722 ; +C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; +C 184 ; WX 204 ; N quotesinglbase ; B -78 -165 112 109 ; +C 185 ; WX 389 ; N quotedblbase ; B -78 -165 289 109 ; +C 186 ; WX 389 ; N quotedblright ; B 39 463 406 737 ; +C 187 ; WX 426 ; N guillemotright ; B -15 74 402 402 ; +C 188 ; WX 1000 ; N ellipsis ; B 59 -15 849 109 ; +C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ; +C 191 ; WX 444 ; N questiondown ; B -3 -205 312 547 ; +C 193 ; WX 333 ; N grave ; B 71 518 262 690 ; +C 194 ; WX 333 ; N acute ; B 132 518 355 690 ; +C 195 ; WX 333 ; N circumflex ; B 37 518 331 690 ; +C 196 ; WX 333 ; N tilde ; B 52 547 383 649 ; +C 197 ; WX 333 ; N macron ; B 52 560 363 610 ; +C 198 ; WX 333 ; N breve ; B 69 518 370 677 ; +C 199 ; WX 333 ; N dotaccent ; B 146 544 248 646 ; +C 200 ; WX 333 ; N dieresis ; B 59 544 359 646 ; +C 202 ; WX 333 ; N ring ; B 114 512 314 712 ; +C 203 ; WX 333 ; N cedilla ; B 3 -215 215 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 32 518 455 690 ; +C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ; +C 207 ; WX 333 ; N caron ; B 73 518 378 690 ; +C 208 ; WX 1000 ; N emdash ; B -27 208 987 268 ; +C 225 ; WX 870 ; N AE ; B -87 0 888 722 ; +C 227 ; WX 422 ; N ordfeminine ; B 72 416 420 705 ; +C 232 ; WX 667 ; N Lslash ; B -33 0 627 722 ; +C 233 ; WX 778 ; N Oslash ; B 16 -68 748 780 ; +C 234 ; WX 981 ; N OE ; B 40 0 975 722 ; +C 235 ; WX 372 ; N ordmasculine ; B 66 416 370 705 ; +C 241 ; WX 722 ; N ae ; B -18 -15 666 466 ; +C 245 ; WX 333 ; N dotlessi ; B 29 -15 282 466 ; +C 248 ; WX 333 ; N lslash ; B -25 -15 340 737 ; +C 249 ; WX 500 ; N oslash ; B 2 -121 450 549 ; +C 250 ; WX 778 ; N oe ; B 2 -15 722 466 ; +C 251 ; WX 556 ; N germandbls ; B -76 -205 525 737 ; +C -1 ; WX 444 ; N ecircumflex ; B -6 -15 388 690 ; +C -1 ; WX 444 ; N edieresis ; B -6 -15 415 646 ; +C -1 ; WX 574 ; N aacute ; B 2 -15 524 690 ; +C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; +C -1 ; WX 333 ; N icircumflex ; B 29 -15 331 690 ; +C -1 ; WX 611 ; N udieresis ; B 44 -15 556 646 ; +C -1 ; WX 500 ; N ograve ; B 2 -15 450 690 ; +C -1 ; WX 611 ; N uacute ; B 44 -15 556 690 ; +C -1 ; WX 611 ; N ucircumflex ; B 44 -15 556 690 ; +C -1 ; WX 704 ; N Aacute ; B -87 0 668 946 ; +C -1 ; WX 333 ; N igrave ; B 29 -15 282 690 ; +C -1 ; WX 407 ; N Icircumflex ; B -33 0 435 946 ; +C -1 ; WX 444 ; N ccedilla ; B 2 -215 394 466 ; +C -1 ; WX 574 ; N adieresis ; B 2 -15 524 646 ; +C -1 ; WX 722 ; N Ecircumflex ; B -33 0 700 946 ; +C -1 ; WX 444 ; N scaron ; B 2 -15 434 690 ; +C -1 ; WX 574 ; N thorn ; B -101 -205 506 737 ; +C -1 ; WX 950 ; N trademark ; B 32 318 968 722 ; +C -1 ; WX 444 ; N egrave ; B -6 -15 388 690 ; +C -1 ; WX 333 ; N threesuperior ; B 22 273 359 705 ; +C -1 ; WX 463 ; N zcaron ; B -33 -15 443 690 ; +C -1 ; WX 574 ; N atilde ; B 2 -15 524 649 ; +C -1 ; WX 574 ; N aring ; B 2 -15 524 712 ; +C -1 ; WX 500 ; N ocircumflex ; B 2 -15 450 690 ; +C -1 ; WX 722 ; N Edieresis ; B -33 0 700 902 ; +C -1 ; WX 834 ; N threequarters ; B 22 -15 782 705 ; +C -1 ; WX 500 ; N ydieresis ; B -83 -205 450 646 ; +C -1 ; WX 500 ; N yacute ; B -83 -205 450 690 ; +C -1 ; WX 333 ; N iacute ; B 29 -15 355 690 ; +C -1 ; WX 704 ; N Acircumflex ; B -87 0 668 946 ; +C -1 ; WX 815 ; N Uacute ; B 93 -15 867 946 ; +C -1 ; WX 444 ; N eacute ; B -6 -15 411 690 ; +C -1 ; WX 778 ; N Ograve ; B 40 -15 738 946 ; +C -1 ; WX 574 ; N agrave ; B 2 -15 524 690 ; +C -1 ; WX 815 ; N Udieresis ; B 93 -15 867 902 ; +C -1 ; WX 574 ; N acircumflex ; B 2 -15 524 690 ; +C -1 ; WX 407 ; N Igrave ; B -33 0 435 946 ; +C -1 ; WX 333 ; N twosuperior ; B 0 282 359 705 ; +C -1 ; WX 815 ; N Ugrave ; B 93 -15 867 946 ; +C -1 ; WX 834 ; N onequarter ; B 34 -15 782 705 ; +C -1 ; WX 815 ; N Ucircumflex ; B 93 -15 867 946 ; +C -1 ; WX 667 ; N Scaron ; B -6 -15 638 946 ; +C -1 ; WX 407 ; N Idieresis ; B -33 0 456 902 ; +C -1 ; WX 333 ; N idieresis ; B 29 -15 359 646 ; +C -1 ; WX 722 ; N Egrave ; B -33 0 700 946 ; +C -1 ; WX 778 ; N Oacute ; B 40 -15 738 946 ; +C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ; +C -1 ; WX 704 ; N Atilde ; B -87 0 668 905 ; +C -1 ; WX 704 ; N Aring ; B -87 0 668 958 ; +C -1 ; WX 778 ; N Odieresis ; B 40 -15 738 902 ; +C -1 ; WX 704 ; N Adieresis ; B -87 0 668 902 ; +C -1 ; WX 815 ; N Ntilde ; B -51 -15 866 905 ; +C -1 ; WX 667 ; N Zcaron ; B -25 0 667 946 ; +C -1 ; WX 667 ; N Thorn ; B -33 0 627 722 ; +C -1 ; WX 407 ; N Iacute ; B -33 0 452 946 ; +C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; +C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ; +C -1 ; WX 722 ; N Eacute ; B -33 0 700 946 ; +C -1 ; WX 685 ; N Ydieresis ; B 31 0 760 902 ; +C -1 ; WX 333 ; N onesuperior ; B 34 282 311 705 ; +C -1 ; WX 611 ; N ugrave ; B 44 -15 556 690 ; +C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ; +C -1 ; WX 611 ; N ntilde ; B 14 -15 562 649 ; +C -1 ; WX 778 ; N Otilde ; B 40 -15 738 905 ; +C -1 ; WX 500 ; N otilde ; B 2 -15 467 649 ; +C -1 ; WX 722 ; N Ccedilla ; B 40 -215 712 737 ; +C -1 ; WX 704 ; N Agrave ; B -87 0 668 946 ; +C -1 ; WX 834 ; N onehalf ; B 34 -15 776 705 ; +C -1 ; WX 778 ; N Eth ; B -33 0 738 722 ; +C -1 ; WX 400 ; N degree ; B 86 419 372 705 ; +C -1 ; WX 685 ; N Yacute ; B 31 0 760 946 ; +C -1 ; WX 778 ; N Ocircumflex ; B 40 -15 738 946 ; +C -1 ; WX 500 ; N oacute ; B 2 -15 450 690 ; +C -1 ; WX 611 ; N mu ; B -60 -205 556 466 ; +C -1 ; WX 606 ; N minus ; B 50 217 556 289 ; +C -1 ; WX 500 ; N eth ; B 2 -15 450 737 ; +C -1 ; WX 500 ; N odieresis ; B 2 -15 450 646 ; +C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; +C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ; +EndCharMetrics +StartKernData +StartKernPairs 181 + +KPX A y -55 +KPX A w -18 +KPX A v -18 +KPX A u -18 +KPX A quoteright -125 +KPX A quotedblright -125 +KPX A Y -55 +KPX A W -74 +KPX A V -74 +KPX A U -37 +KPX A T -30 +KPX A Q -18 +KPX A O -18 +KPX A G -18 +KPX A C -18 + +KPX B period -50 +KPX B comma -50 + +KPX C period -50 +KPX C comma -50 + +KPX D period -50 +KPX D comma -50 +KPX D Y -18 +KPX D W -18 +KPX D V -18 + +KPX F r -55 +KPX F period -125 +KPX F o -55 +KPX F i -10 +KPX F e -55 +KPX F comma -125 +KPX F a -55 +KPX F A -35 + +KPX G period -50 +KPX G comma -50 + +KPX J u -18 +KPX J period -100 +KPX J o -37 +KPX J e -37 +KPX J comma -100 +KPX J a -37 +KPX J A -18 + +KPX L y -50 +KPX L quoteright -125 +KPX L quotedblright -125 +KPX L Y -100 +KPX L W -100 +KPX L V -100 +KPX L T -100 + +KPX N period -60 +KPX N comma -60 + +KPX O period -50 +KPX O comma -50 +KPX O Y -18 +KPX O X -18 +KPX O V -18 +KPX O T 18 + +KPX P period -125 +KPX P o -55 +KPX P e -55 +KPX P comma -125 +KPX P a -55 +KPX P A -50 + +KPX Q period -20 +KPX Q comma -20 + +KPX R Y -18 +KPX R W -18 +KPX R V -18 +KPX R U -18 + +KPX S period -50 +KPX S comma -50 + +KPX T y -50 +KPX T w -50 +KPX T u -50 +KPX T semicolon -50 +KPX T r -50 +KPX T period -100 +KPX T o -74 +KPX T i -18 +KPX T hyphen -100 +KPX T h -25 +KPX T e -74 +KPX T comma -100 +KPX T colon -50 +KPX T a -74 +KPX T O 18 + +KPX U period -100 +KPX U comma -100 +KPX U A -18 + +KPX V u -75 +KPX V semicolon -75 +KPX V period -100 +KPX V o -75 +KPX V i -50 +KPX V hyphen -100 +KPX V e -75 +KPX V comma -100 +KPX V colon -75 +KPX V a -75 +KPX V A -37 + +KPX W y -55 +KPX W u -55 +KPX W semicolon -75 +KPX W period -100 +KPX W o -55 +KPX W i -20 +KPX W hyphen -75 +KPX W h -20 +KPX W e -55 +KPX W comma -100 +KPX W colon -75 +KPX W a -55 +KPX W A -55 + +KPX Y u -100 +KPX Y semicolon -75 +KPX Y period -100 +KPX Y o -100 +KPX Y i -25 +KPX Y hyphen -100 +KPX Y e -100 +KPX Y comma -100 +KPX Y colon -75 +KPX Y a -100 +KPX Y A -55 + +KPX b period -50 +KPX b comma -50 +KPX b b -10 + +KPX c period -50 +KPX c k -18 +KPX c h -18 +KPX c comma -50 + +KPX colon space -37 + +KPX comma space -37 +KPX comma quoteright -37 +KPX comma quotedblright -37 + +KPX e period -37 +KPX e comma -37 + +KPX f quoteright 75 +KPX f quotedblright 75 +KPX f period -75 +KPX f o -10 +KPX f comma -75 + +KPX g period -50 +KPX g comma -50 + +KPX l y -10 + +KPX o period -50 +KPX o comma -50 + +KPX p period -50 +KPX p comma -50 + +KPX period space -37 +KPX period quoteright -37 +KPX period quotedblright -37 + +KPX quotedblleft A -75 + +KPX quotedblright space -37 + +KPX quoteleft quoteleft -37 +KPX quoteleft A -75 + +KPX quoteright s -25 +KPX quoteright quoteright -37 +KPX quoteright d -37 + +KPX r semicolon -25 +KPX r s -10 +KPX r period -125 +KPX r k -18 +KPX r hyphen -75 +KPX r comma -125 +KPX r colon -25 + +KPX s period -50 +KPX s comma -50 + +KPX semicolon space -37 + +KPX space quoteleft -37 +KPX space quotedblleft -37 +KPX space Y -37 +KPX space W -37 +KPX space V -37 +KPX space T -37 +KPX space A -37 + +KPX v period -75 +KPX v comma -75 + +KPX w period -75 +KPX w comma -75 + +KPX y period -75 +KPX y comma -75 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 246 256 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 246 256 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 231 256 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 246 256 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 216 246 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 231 256 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 255 256 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 255 256 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 255 256 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 255 256 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 97 256 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 97 256 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 97 256 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 97 256 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 301 256 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 256 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 283 256 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 283 256 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 283 256 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 283 256 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 227 256 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 301 256 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 301 256 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 301 256 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 301 256 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 256 256 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 256 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 227 256 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 121 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 121 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 121 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 121 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 121 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 121 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 65 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplb8a.afm new file mode 100644 index 00000000..de7698d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplb8a.afm @@ -0,0 +1,434 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jul 2 22:26:30 1990 +Comment UniqueID 31793 +Comment VMusage 36031 46923 +FontName Palatino-Bold +FullName Palatino Bold +FamilyName Palatino +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -152 -266 1000 924 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.005 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 471 +Ascender 720 +Descender -258 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 63 -12 219 688 ; +C 34 ; WX 402 ; N quotedbl ; B 22 376 380 695 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ; +C 36 ; WX 500 ; N dollar ; B 28 -114 472 721 ; +C 37 ; WX 889 ; N percent ; B 61 -9 828 714 ; +C 38 ; WX 833 ; N ampersand ; B 52 -17 813 684 ; +C 39 ; WX 278 ; N quoteright ; B 29 405 249 695 ; +C 40 ; WX 333 ; N parenleft ; B 65 -104 305 723 ; +C 41 ; WX 333 ; N parenright ; B 28 -104 268 723 ; +C 42 ; WX 444 ; N asterisk ; B 44 332 399 695 ; +C 43 ; WX 606 ; N plus ; B 51 0 555 505 ; +C 44 ; WX 250 ; N comma ; B -6 -166 227 141 ; +C 45 ; WX 333 ; N hyphen ; B 16 195 317 305 ; +C 46 ; WX 250 ; N period ; B 47 -12 203 144 ; +C 47 ; WX 296 ; N slash ; B -9 -17 305 720 ; +C 48 ; WX 500 ; N zero ; B 33 -17 468 660 ; +C 49 ; WX 500 ; N one ; B 35 -3 455 670 ; +C 50 ; WX 500 ; N two ; B 25 -3 472 660 ; +C 51 ; WX 500 ; N three ; B 22 -17 458 660 ; +C 52 ; WX 500 ; N four ; B 12 -3 473 672 ; +C 53 ; WX 500 ; N five ; B 42 -17 472 656 ; +C 54 ; WX 500 ; N six ; B 37 -17 469 660 ; +C 55 ; WX 500 ; N seven ; B 46 -3 493 656 ; +C 56 ; WX 500 ; N eight ; B 34 -17 467 660 ; +C 57 ; WX 500 ; N nine ; B 31 -17 463 660 ; +C 58 ; WX 250 ; N colon ; B 47 -12 203 454 ; +C 59 ; WX 250 ; N semicolon ; B -6 -166 227 454 ; +C 60 ; WX 606 ; N less ; B 49 -15 558 519 ; +C 61 ; WX 606 ; N equal ; B 51 114 555 396 ; +C 62 ; WX 606 ; N greater ; B 49 -15 558 519 ; +C 63 ; WX 444 ; N question ; B 43 -12 411 687 ; +C 64 ; WX 747 ; N at ; B 42 -12 704 681 ; +C 65 ; WX 778 ; N A ; B 24 -3 757 686 ; +C 66 ; WX 667 ; N B ; B 39 -3 611 681 ; +C 67 ; WX 722 ; N C ; B 44 -17 695 695 ; +C 68 ; WX 833 ; N D ; B 35 -3 786 681 ; +C 69 ; WX 611 ; N E ; B 39 -4 577 681 ; +C 70 ; WX 556 ; N F ; B 28 -3 539 681 ; +C 71 ; WX 833 ; N G ; B 47 -17 776 695 ; +C 72 ; WX 833 ; N H ; B 36 -3 796 681 ; +C 73 ; WX 389 ; N I ; B 39 -3 350 681 ; +C 74 ; WX 389 ; N J ; B -11 -213 350 681 ; +C 75 ; WX 778 ; N K ; B 39 -3 763 681 ; +C 76 ; WX 611 ; N L ; B 39 -4 577 681 ; +C 77 ; WX 1000 ; N M ; B 32 -10 968 681 ; +C 78 ; WX 833 ; N N ; B 35 -16 798 681 ; +C 79 ; WX 833 ; N O ; B 47 -17 787 695 ; +C 80 ; WX 611 ; N P ; B 39 -3 594 681 ; +C 81 ; WX 833 ; N Q ; B 47 -184 787 695 ; +C 82 ; WX 722 ; N R ; B 39 -3 708 681 ; +C 83 ; WX 611 ; N S ; B 57 -17 559 695 ; +C 84 ; WX 667 ; N T ; B 17 -3 650 681 ; +C 85 ; WX 778 ; N U ; B 26 -17 760 681 ; +C 86 ; WX 778 ; N V ; B 20 -3 763 681 ; +C 87 ; WX 1000 ; N W ; B 17 -3 988 686 ; +C 88 ; WX 667 ; N X ; B 17 -3 650 695 ; +C 89 ; WX 667 ; N Y ; B 15 -3 660 695 ; +C 90 ; WX 667 ; N Z ; B 24 -3 627 681 ; +C 91 ; WX 333 ; N bracketleft ; B 73 -104 291 720 ; +C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ; +C 93 ; WX 333 ; N bracketright ; B 42 -104 260 720 ; +C 94 ; WX 606 ; N asciicircum ; B 52 275 554 678 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 29 405 249 695 ; +C 97 ; WX 500 ; N a ; B 40 -17 478 471 ; +C 98 ; WX 611 ; N b ; B 10 -17 556 720 ; +C 99 ; WX 444 ; N c ; B 37 -17 414 471 ; +C 100 ; WX 611 ; N d ; B 42 -17 577 720 ; +C 101 ; WX 500 ; N e ; B 42 -17 461 471 ; +C 102 ; WX 389 ; N f ; B 34 -3 381 720 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 26 -266 535 471 ; +C 104 ; WX 611 ; N h ; B 24 -3 587 720 ; +C 105 ; WX 333 ; N i ; B 34 -3 298 706 ; +C 106 ; WX 333 ; N j ; B 3 -266 241 706 ; +C 107 ; WX 611 ; N k ; B 21 -3 597 720 ; +C 108 ; WX 333 ; N l ; B 24 -3 296 720 ; +C 109 ; WX 889 ; N m ; B 24 -3 864 471 ; +C 110 ; WX 611 ; N n ; B 24 -3 587 471 ; +C 111 ; WX 556 ; N o ; B 40 -17 517 471 ; +C 112 ; WX 611 ; N p ; B 29 -258 567 471 ; +C 113 ; WX 611 ; N q ; B 52 -258 589 471 ; +C 114 ; WX 389 ; N r ; B 30 -3 389 471 ; +C 115 ; WX 444 ; N s ; B 39 -17 405 471 ; +C 116 ; WX 333 ; N t ; B 22 -17 324 632 ; +C 117 ; WX 611 ; N u ; B 25 -17 583 471 ; +C 118 ; WX 556 ; N v ; B 11 -3 545 459 ; +C 119 ; WX 833 ; N w ; B 13 -3 820 471 ; +C 120 ; WX 500 ; N x ; B 20 -3 483 471 ; +C 121 ; WX 556 ; N y ; B 10 -266 546 459 ; +C 122 ; WX 500 ; N z ; B 16 -3 464 459 ; +C 123 ; WX 310 ; N braceleft ; B 5 -117 288 725 ; +C 124 ; WX 606 ; N bar ; B 260 0 346 720 ; +C 125 ; WX 310 ; N braceright ; B 22 -117 305 725 ; +C 126 ; WX 606 ; N asciitilde ; B 51 155 555 342 ; +C 161 ; WX 278 ; N exclamdown ; B 59 -227 215 471 ; +C 162 ; WX 500 ; N cent ; B 73 -106 450 554 ; +C 163 ; WX 500 ; N sterling ; B -2 -19 501 676 ; +C 164 ; WX 167 ; N fraction ; B -152 0 320 660 ; +C 165 ; WX 500 ; N yen ; B 17 -3 483 695 ; +C 166 ; WX 500 ; N florin ; B 11 -242 490 703 ; +C 167 ; WX 500 ; N section ; B 30 -217 471 695 ; +C 168 ; WX 500 ; N currency ; B 32 96 468 533 ; +C 169 ; WX 227 ; N quotesingle ; B 45 376 181 695 ; +C 170 ; WX 500 ; N quotedblleft ; B 34 405 466 695 ; +C 171 ; WX 500 ; N guillemotleft ; B 36 44 463 438 ; +C 172 ; WX 389 ; N guilsinglleft ; B 82 44 307 438 ; +C 173 ; WX 389 ; N guilsinglright ; B 82 44 307 438 ; +C 174 ; WX 611 ; N fi ; B 10 -3 595 720 ; +C 175 ; WX 611 ; N fl ; B 17 -3 593 720 ; +C 177 ; WX 500 ; N endash ; B 0 208 500 291 ; +C 178 ; WX 500 ; N dagger ; B 29 -6 472 682 ; +C 179 ; WX 500 ; N daggerdbl ; B 32 -245 468 682 ; +C 180 ; WX 250 ; N periodcentered ; B 47 179 203 335 ; +C 182 ; WX 641 ; N paragraph ; B 19 -161 599 683 ; +C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; +C 184 ; WX 333 ; N quotesinglbase ; B 56 -160 276 130 ; +C 185 ; WX 500 ; N quotedblbase ; B 34 -160 466 130 ; +C 186 ; WX 500 ; N quotedblright ; B 34 405 466 695 ; +C 187 ; WX 500 ; N guillemotright ; B 37 44 464 438 ; +C 188 ; WX 1000 ; N ellipsis ; B 89 -12 911 144 ; +C 189 ; WX 1000 ; N perthousand ; B 33 -9 982 724 ; +C 191 ; WX 444 ; N questiondown ; B 33 -231 401 471 ; +C 193 ; WX 333 ; N grave ; B 18 506 256 691 ; +C 194 ; WX 333 ; N acute ; B 78 506 316 691 ; +C 195 ; WX 333 ; N circumflex ; B -2 506 335 681 ; +C 196 ; WX 333 ; N tilde ; B -16 535 349 661 ; +C 197 ; WX 333 ; N macron ; B 1 538 332 609 ; +C 198 ; WX 333 ; N breve ; B 15 506 318 669 ; +C 199 ; WX 333 ; N dotaccent ; B 100 537 234 671 ; +C 200 ; WX 333 ; N dieresis ; B -8 537 341 671 ; +C 202 ; WX 333 ; N ring ; B 67 500 267 700 ; +C 203 ; WX 333 ; N cedilla ; B 73 -225 300 -7 ; +C 205 ; WX 333 ; N hungarumlaut ; B -56 506 390 691 ; +C 206 ; WX 333 ; N ogonek ; B 60 -246 274 -17 ; +C 207 ; WX 333 ; N caron ; B -2 510 335 685 ; +C 208 ; WX 1000 ; N emdash ; B 0 208 1000 291 ; +C 225 ; WX 1000 ; N AE ; B 12 -4 954 681 ; +C 227 ; WX 438 ; N ordfeminine ; B 77 367 361 660 ; +C 232 ; WX 611 ; N Lslash ; B 16 -4 577 681 ; +C 233 ; WX 833 ; N Oslash ; B 32 -20 808 698 ; +C 234 ; WX 1000 ; N OE ; B 43 -17 985 695 ; +C 235 ; WX 488 ; N ordmasculine ; B 89 367 399 660 ; +C 241 ; WX 778 ; N ae ; B 46 -17 731 471 ; +C 245 ; WX 333 ; N dotlessi ; B 34 -3 298 471 ; +C 248 ; WX 333 ; N lslash ; B -4 -3 334 720 ; +C 249 ; WX 556 ; N oslash ; B 23 -18 534 471 ; +C 250 ; WX 833 ; N oe ; B 48 -17 799 471 ; +C 251 ; WX 611 ; N germandbls ; B 30 -17 565 720 ; +C -1 ; WX 667 ; N Zcaron ; B 24 -3 627 909 ; +C -1 ; WX 444 ; N ccedilla ; B 37 -225 414 471 ; +C -1 ; WX 556 ; N ydieresis ; B 10 -266 546 691 ; +C -1 ; WX 500 ; N atilde ; B 40 -17 478 673 ; +C -1 ; WX 333 ; N icircumflex ; B -2 -3 335 701 ; +C -1 ; WX 300 ; N threesuperior ; B 9 261 292 667 ; +C -1 ; WX 500 ; N ecircumflex ; B 42 -17 461 701 ; +C -1 ; WX 611 ; N thorn ; B 17 -258 563 720 ; +C -1 ; WX 500 ; N egrave ; B 42 -17 461 711 ; +C -1 ; WX 300 ; N twosuperior ; B 5 261 295 660 ; +C -1 ; WX 500 ; N eacute ; B 42 -17 461 711 ; +C -1 ; WX 556 ; N otilde ; B 40 -17 517 673 ; +C -1 ; WX 778 ; N Aacute ; B 24 -3 757 915 ; +C -1 ; WX 556 ; N ocircumflex ; B 40 -17 517 701 ; +C -1 ; WX 556 ; N yacute ; B 10 -266 546 711 ; +C -1 ; WX 611 ; N udieresis ; B 25 -17 583 691 ; +C -1 ; WX 750 ; N threequarters ; B 15 -2 735 667 ; +C -1 ; WX 500 ; N acircumflex ; B 40 -17 478 701 ; +C -1 ; WX 833 ; N Eth ; B 10 -3 786 681 ; +C -1 ; WX 500 ; N edieresis ; B 42 -17 461 691 ; +C -1 ; WX 611 ; N ugrave ; B 25 -17 583 711 ; +C -1 ; WX 998 ; N trademark ; B 38 274 961 678 ; +C -1 ; WX 556 ; N ograve ; B 40 -17 517 711 ; +C -1 ; WX 444 ; N scaron ; B 39 -17 405 693 ; +C -1 ; WX 389 ; N Idieresis ; B 20 -3 369 895 ; +C -1 ; WX 611 ; N uacute ; B 25 -17 583 711 ; +C -1 ; WX 500 ; N agrave ; B 40 -17 478 711 ; +C -1 ; WX 611 ; N ntilde ; B 24 -3 587 673 ; +C -1 ; WX 500 ; N aring ; B 40 -17 478 700 ; +C -1 ; WX 500 ; N zcaron ; B 16 -3 464 693 ; +C -1 ; WX 389 ; N Icircumflex ; B 26 -3 363 905 ; +C -1 ; WX 833 ; N Ntilde ; B 35 -16 798 885 ; +C -1 ; WX 611 ; N ucircumflex ; B 25 -17 583 701 ; +C -1 ; WX 611 ; N Ecircumflex ; B 39 -4 577 905 ; +C -1 ; WX 389 ; N Iacute ; B 39 -3 350 915 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -225 695 695 ; +C -1 ; WX 833 ; N Odieresis ; B 47 -17 787 895 ; +C -1 ; WX 611 ; N Scaron ; B 57 -17 559 909 ; +C -1 ; WX 611 ; N Edieresis ; B 39 -4 577 895 ; +C -1 ; WX 389 ; N Igrave ; B 39 -3 350 915 ; +C -1 ; WX 500 ; N adieresis ; B 40 -17 478 691 ; +C -1 ; WX 833 ; N Ograve ; B 47 -17 787 915 ; +C -1 ; WX 611 ; N Egrave ; B 39 -4 577 915 ; +C -1 ; WX 667 ; N Ydieresis ; B 15 -3 660 895 ; +C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ; +C -1 ; WX 833 ; N Otilde ; B 47 -17 787 885 ; +C -1 ; WX 750 ; N onequarter ; B 19 -2 735 665 ; +C -1 ; WX 778 ; N Ugrave ; B 26 -17 760 915 ; +C -1 ; WX 778 ; N Ucircumflex ; B 26 -17 760 905 ; +C -1 ; WX 611 ; N Thorn ; B 39 -3 574 681 ; +C -1 ; WX 606 ; N divide ; B 51 0 555 510 ; +C -1 ; WX 778 ; N Atilde ; B 24 -3 757 885 ; +C -1 ; WX 778 ; N Uacute ; B 26 -17 760 915 ; +C -1 ; WX 833 ; N Ocircumflex ; B 47 -17 787 905 ; +C -1 ; WX 606 ; N logicalnot ; B 51 114 555 396 ; +C -1 ; WX 778 ; N Aring ; B 24 -3 757 924 ; +C -1 ; WX 333 ; N idieresis ; B -8 -3 341 691 ; +C -1 ; WX 333 ; N iacute ; B 34 -3 316 711 ; +C -1 ; WX 500 ; N aacute ; B 40 -17 478 711 ; +C -1 ; WX 606 ; N plusminus ; B 51 0 555 505 ; +C -1 ; WX 606 ; N multiply ; B 72 21 534 483 ; +C -1 ; WX 778 ; N Udieresis ; B 26 -17 760 895 ; +C -1 ; WX 606 ; N minus ; B 51 212 555 298 ; +C -1 ; WX 300 ; N onesuperior ; B 14 261 287 665 ; +C -1 ; WX 611 ; N Eacute ; B 39 -4 577 915 ; +C -1 ; WX 778 ; N Acircumflex ; B 24 -3 757 905 ; +C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ; +C -1 ; WX 778 ; N Agrave ; B 24 -3 757 915 ; +C -1 ; WX 556 ; N odieresis ; B 40 -17 517 691 ; +C -1 ; WX 556 ; N oacute ; B 40 -17 517 711 ; +C -1 ; WX 400 ; N degree ; B 50 360 350 660 ; +C -1 ; WX 333 ; N igrave ; B 18 -3 298 711 ; +C -1 ; WX 611 ; N mu ; B 25 -225 583 471 ; +C -1 ; WX 833 ; N Oacute ; B 47 -17 787 915 ; +C -1 ; WX 556 ; N eth ; B 40 -17 517 720 ; +C -1 ; WX 778 ; N Adieresis ; B 24 -3 757 895 ; +C -1 ; WX 667 ; N Yacute ; B 15 -3 660 915 ; +C -1 ; WX 606 ; N brokenbar ; B 260 0 346 720 ; +C -1 ; WX 750 ; N onehalf ; B 9 -2 745 665 ; +EndCharMetrics +StartKernData +StartKernPairs 101 + +KPX A y -70 +KPX A w -70 +KPX A v -70 +KPX A space -18 +KPX A quoteright -92 +KPX A Y -111 +KPX A W -90 +KPX A V -129 +KPX A T -92 + +KPX F period -111 +KPX F comma -111 +KPX F A -55 + +KPX L y -74 +KPX L space -18 +KPX L quoteright -74 +KPX L Y -92 +KPX L W -92 +KPX L V -92 +KPX L T -74 + +KPX P period -129 +KPX P comma -129 +KPX P A -74 + +KPX R y -30 +KPX R Y -55 +KPX R W -37 +KPX R V -74 +KPX R T -55 + +KPX T y -90 +KPX T w -90 +KPX T u -129 +KPX T semicolon -74 +KPX T s -111 +KPX T r -111 +KPX T period -92 +KPX T o -111 +KPX T i -55 +KPX T hyphen -92 +KPX T e -111 +KPX T comma -92 +KPX T colon -74 +KPX T c -129 +KPX T a -111 +KPX T A -92 + +KPX V y -90 +KPX V u -92 +KPX V semicolon -74 +KPX V r -111 +KPX V period -129 +KPX V o -111 +KPX V i -55 +KPX V hyphen -92 +KPX V e -111 +KPX V comma -129 +KPX V colon -74 +KPX V a -111 +KPX V A -129 + +KPX W y -74 +KPX W u -74 +KPX W semicolon -37 +KPX W r -74 +KPX W period -37 +KPX W o -74 +KPX W i -37 +KPX W hyphen -37 +KPX W e -74 +KPX W comma -92 +KPX W colon -37 +KPX W a -74 +KPX W A -90 + +KPX Y v -74 +KPX Y u -74 +KPX Y semicolon -55 +KPX Y q -92 +KPX Y period -74 +KPX Y p -74 +KPX Y o -74 +KPX Y i -55 +KPX Y hyphen -74 +KPX Y e -74 +KPX Y comma -74 +KPX Y colon -55 +KPX Y a -74 +KPX Y A -55 + +KPX f quoteright 37 +KPX f f -18 + +KPX one one -37 + +KPX quoteleft quoteleft -55 + +KPX quoteright t -18 +KPX quoteright space -55 +KPX quoteright s -55 +KPX quoteright quoteright -55 + +KPX r quoteright 55 +KPX r period -55 +KPX r hyphen -18 +KPX r comma -55 + +KPX v period -111 +KPX v comma -111 + +KPX w period -92 +KPX w comma -92 + +KPX y period -92 +KPX y comma -92 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 223 224 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 211 224 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 224 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 224 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 223 224 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 224 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 224 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 224 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 224 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 224 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 224 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 224 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 224 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 224 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 224 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 224 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 224 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 224 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 224 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 224 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 224 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 224 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 224 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 224 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 224 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 211 224 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 199 224 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 224 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 20 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 20 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 84 20 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 12 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 84 20 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 96 20 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 20 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 84 20 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 20 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 12 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 20 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 56 8 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 151 20 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 20 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 20 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 131 20 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 124 20 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplbi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplbi8a.afm new file mode 100644 index 00000000..e161d049 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplbi8a.afm @@ -0,0 +1,441 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jul 2 22:48:39 1990 +Comment UniqueID 31799 +Comment VMusage 37656 48548 +FontName Palatino-BoldItalic +FullName Palatino Bold Italic +FamilyName Palatino +Weight Bold +ItalicAngle -10 +IsFixedPitch false +FontBBox -170 -271 1073 926 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.005 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 681 +XHeight 469 +Ascender 726 +Descender -271 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 58 -17 322 695 ; +C 34 ; WX 500 ; N quotedbl ; B 137 467 493 720 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ; +C 36 ; WX 500 ; N dollar ; B 20 -108 477 737 ; +C 37 ; WX 889 ; N percent ; B 56 -17 790 697 ; +C 38 ; WX 833 ; N ampersand ; B 74 -17 811 695 ; +C 39 ; WX 278 ; N quoteright ; B 76 431 302 720 ; +C 40 ; WX 333 ; N parenleft ; B 58 -129 368 723 ; +C 41 ; WX 333 ; N parenright ; B -12 -129 298 723 ; +C 42 ; WX 444 ; N asterisk ; B 84 332 439 695 ; +C 43 ; WX 606 ; N plus ; B 50 -5 556 501 ; +C 44 ; WX 250 ; N comma ; B -33 -164 208 147 ; +C 45 ; WX 389 ; N hyphen ; B 37 198 362 300 ; +C 46 ; WX 250 ; N period ; B 48 -17 187 135 ; +C 47 ; WX 315 ; N slash ; B 1 -17 315 720 ; +C 48 ; WX 500 ; N zero ; B 42 -17 490 683 ; +C 49 ; WX 500 ; N one ; B 41 -3 434 678 ; +C 50 ; WX 500 ; N two ; B 1 -3 454 683 ; +C 51 ; WX 500 ; N three ; B 8 -17 450 683 ; +C 52 ; WX 500 ; N four ; B 3 -3 487 683 ; +C 53 ; WX 500 ; N five ; B 14 -17 481 675 ; +C 54 ; WX 500 ; N six ; B 39 -17 488 683 ; +C 55 ; WX 500 ; N seven ; B 69 -3 544 674 ; +C 56 ; WX 500 ; N eight ; B 26 -17 484 683 ; +C 57 ; WX 500 ; N nine ; B 27 -17 491 683 ; +C 58 ; WX 250 ; N colon ; B 38 -17 236 452 ; +C 59 ; WX 250 ; N semicolon ; B -33 -164 247 452 ; +C 60 ; WX 606 ; N less ; B 49 -21 558 517 ; +C 61 ; WX 606 ; N equal ; B 51 106 555 390 ; +C 62 ; WX 606 ; N greater ; B 48 -21 557 517 ; +C 63 ; WX 444 ; N question ; B 91 -17 450 695 ; +C 64 ; WX 833 ; N at ; B 82 -12 744 681 ; +C 65 ; WX 722 ; N A ; B -35 -3 685 683 ; +C 66 ; WX 667 ; N B ; B 8 -3 629 681 ; +C 67 ; WX 685 ; N C ; B 69 -17 695 695 ; +C 68 ; WX 778 ; N D ; B 0 -3 747 682 ; +C 69 ; WX 611 ; N E ; B 11 -3 606 681 ; +C 70 ; WX 556 ; N F ; B -6 -3 593 681 ; +C 71 ; WX 778 ; N G ; B 72 -17 750 695 ; +C 72 ; WX 778 ; N H ; B -12 -3 826 681 ; +C 73 ; WX 389 ; N I ; B -1 -3 412 681 ; +C 74 ; WX 389 ; N J ; B -29 -207 417 681 ; +C 75 ; WX 722 ; N K ; B -10 -3 746 681 ; +C 76 ; WX 611 ; N L ; B 26 -3 578 681 ; +C 77 ; WX 944 ; N M ; B -23 -17 985 681 ; +C 78 ; WX 778 ; N N ; B -2 -3 829 681 ; +C 79 ; WX 833 ; N O ; B 76 -17 794 695 ; +C 80 ; WX 667 ; N P ; B 11 -3 673 681 ; +C 81 ; WX 833 ; N Q ; B 76 -222 794 695 ; +C 82 ; WX 722 ; N R ; B 4 -3 697 681 ; +C 83 ; WX 556 ; N S ; B 50 -17 517 695 ; +C 84 ; WX 611 ; N T ; B 56 -3 674 681 ; +C 85 ; WX 778 ; N U ; B 83 -17 825 681 ; +C 86 ; WX 667 ; N V ; B 67 -3 745 681 ; +C 87 ; WX 1000 ; N W ; B 67 -3 1073 689 ; +C 88 ; WX 722 ; N X ; B -9 -3 772 681 ; +C 89 ; WX 611 ; N Y ; B 54 -3 675 695 ; +C 90 ; WX 667 ; N Z ; B 1 -3 676 681 ; +C 91 ; WX 333 ; N bracketleft ; B 45 -102 381 723 ; +C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ; +C 93 ; WX 333 ; N bracketright ; B -21 -102 315 723 ; +C 94 ; WX 606 ; N asciicircum ; B 63 275 543 678 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 65 431 291 720 ; +C 97 ; WX 556 ; N a ; B 44 -17 519 470 ; +C 98 ; WX 537 ; N b ; B 44 -17 494 726 ; +C 99 ; WX 444 ; N c ; B 32 -17 436 469 ; +C 100 ; WX 556 ; N d ; B 38 -17 550 726 ; +C 101 ; WX 444 ; N e ; B 28 -17 418 469 ; +C 102 ; WX 333 ; N f ; B -130 -271 449 726 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B -50 -271 529 469 ; +C 104 ; WX 556 ; N h ; B 22 -17 522 726 ; +C 105 ; WX 333 ; N i ; B 26 -17 312 695 ; +C 106 ; WX 333 ; N j ; B -64 -271 323 695 ; +C 107 ; WX 556 ; N k ; B 34 -17 528 726 ; +C 108 ; WX 333 ; N l ; B 64 -17 318 726 ; +C 109 ; WX 833 ; N m ; B 19 -17 803 469 ; +C 110 ; WX 556 ; N n ; B 17 -17 521 469 ; +C 111 ; WX 556 ; N o ; B 48 -17 502 469 ; +C 112 ; WX 556 ; N p ; B -21 -271 516 469 ; +C 113 ; WX 537 ; N q ; B 32 -271 513 469 ; +C 114 ; WX 389 ; N r ; B 20 -17 411 469 ; +C 115 ; WX 444 ; N s ; B 25 -17 406 469 ; +C 116 ; WX 389 ; N t ; B 42 -17 409 636 ; +C 117 ; WX 556 ; N u ; B 22 -17 521 469 ; +C 118 ; WX 556 ; N v ; B 19 -17 513 469 ; +C 119 ; WX 833 ; N w ; B 27 -17 802 469 ; +C 120 ; WX 500 ; N x ; B -8 -17 500 469 ; +C 121 ; WX 556 ; N y ; B 13 -271 541 469 ; +C 122 ; WX 500 ; N z ; B 31 -17 470 469 ; +C 123 ; WX 333 ; N braceleft ; B 18 -105 334 720 ; +C 124 ; WX 606 ; N bar ; B 259 0 347 720 ; +C 125 ; WX 333 ; N braceright ; B -1 -105 315 720 ; +C 126 ; WX 606 ; N asciitilde ; B 51 151 555 346 ; +C 161 ; WX 333 ; N exclamdown ; B 2 -225 259 479 ; +C 162 ; WX 500 ; N cent ; B 52 -105 456 547 ; +C 163 ; WX 500 ; N sterling ; B 21 -5 501 683 ; +C 164 ; WX 167 ; N fraction ; B -170 0 338 683 ; +C 165 ; WX 500 ; N yen ; B 11 -3 538 695 ; +C 166 ; WX 500 ; N florin ; B 8 -242 479 690 ; +C 167 ; WX 556 ; N section ; B 47 -151 497 695 ; +C 168 ; WX 500 ; N currency ; B 32 96 468 533 ; +C 169 ; WX 250 ; N quotesingle ; B 127 467 293 720 ; +C 170 ; WX 500 ; N quotedblleft ; B 65 431 511 720 ; +C 171 ; WX 500 ; N guillemotleft ; B 35 43 458 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 60 43 292 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 35 40 267 443 ; +C 174 ; WX 611 ; N fi ; B -130 -271 588 726 ; +C 175 ; WX 611 ; N fl ; B -130 -271 631 726 ; +C 177 ; WX 500 ; N endash ; B -12 214 512 282 ; +C 178 ; WX 556 ; N dagger ; B 67 -3 499 685 ; +C 179 ; WX 556 ; N daggerdbl ; B 33 -153 537 693 ; +C 180 ; WX 250 ; N periodcentered ; B 67 172 206 324 ; +C 182 ; WX 556 ; N paragraph ; B 14 -204 629 681 ; +C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; +C 184 ; WX 250 ; N quotesinglbase ; B -3 -144 220 145 ; +C 185 ; WX 500 ; N quotedblbase ; B -18 -144 424 145 ; +C 186 ; WX 500 ; N quotedblright ; B 73 431 519 720 ; +C 187 ; WX 500 ; N guillemotright ; B 35 40 458 443 ; +C 188 ; WX 1000 ; N ellipsis ; B 91 -17 896 135 ; +C 189 ; WX 1000 ; N perthousand ; B 65 -17 912 691 ; +C 191 ; WX 444 ; N questiondown ; B -12 -226 347 479 ; +C 193 ; WX 333 ; N grave ; B 110 518 322 699 ; +C 194 ; WX 333 ; N acute ; B 153 518 392 699 ; +C 195 ; WX 333 ; N circumflex ; B 88 510 415 684 ; +C 196 ; WX 333 ; N tilde ; B 82 535 441 654 ; +C 197 ; WX 333 ; N macron ; B 76 538 418 608 ; +C 198 ; WX 333 ; N breve ; B 96 518 412 680 ; +C 199 ; WX 333 ; N dotaccent ; B 202 537 325 668 ; +C 200 ; WX 333 ; N dieresis ; B 90 537 426 668 ; +C 202 ; WX 556 ; N ring ; B 277 514 477 714 ; +C 203 ; WX 333 ; N cedilla ; B 12 -218 248 5 ; +C 205 ; WX 333 ; N hungarumlaut ; B -28 518 409 699 ; +C 206 ; WX 333 ; N ogonek ; B 32 -206 238 -17 ; +C 207 ; WX 333 ; N caron ; B 113 510 445 684 ; +C 208 ; WX 1000 ; N emdash ; B -12 214 1012 282 ; +C 225 ; WX 944 ; N AE ; B -29 -3 927 681 ; +C 227 ; WX 333 ; N ordfeminine ; B 47 391 355 684 ; +C 232 ; WX 611 ; N Lslash ; B 6 -3 578 681 ; +C 233 ; WX 833 ; N Oslash ; B 57 -54 797 730 ; +C 234 ; WX 944 ; N OE ; B 39 -17 961 695 ; +C 235 ; WX 333 ; N ordmasculine ; B 51 391 346 683 ; +C 241 ; WX 738 ; N ae ; B 44 -17 711 469 ; +C 245 ; WX 333 ; N dotlessi ; B 26 -17 293 469 ; +C 248 ; WX 333 ; N lslash ; B 13 -17 365 726 ; +C 249 ; WX 556 ; N oslash ; B 14 -50 522 506 ; +C 250 ; WX 778 ; N oe ; B 48 -17 755 469 ; +C 251 ; WX 556 ; N germandbls ; B -131 -271 549 726 ; +C -1 ; WX 667 ; N Zcaron ; B 1 -3 676 896 ; +C -1 ; WX 444 ; N ccedilla ; B 32 -218 436 469 ; +C -1 ; WX 556 ; N ydieresis ; B 13 -271 541 688 ; +C -1 ; WX 556 ; N atilde ; B 44 -17 553 666 ; +C -1 ; WX 333 ; N icircumflex ; B 26 -17 403 704 ; +C -1 ; WX 300 ; N threesuperior ; B 23 263 310 683 ; +C -1 ; WX 444 ; N ecircumflex ; B 28 -17 471 704 ; +C -1 ; WX 556 ; N thorn ; B -21 -271 516 726 ; +C -1 ; WX 444 ; N egrave ; B 28 -17 418 719 ; +C -1 ; WX 300 ; N twosuperior ; B 26 271 321 683 ; +C -1 ; WX 444 ; N eacute ; B 28 -17 448 719 ; +C -1 ; WX 556 ; N otilde ; B 48 -17 553 666 ; +C -1 ; WX 722 ; N Aacute ; B -35 -3 685 911 ; +C -1 ; WX 556 ; N ocircumflex ; B 48 -17 515 704 ; +C -1 ; WX 556 ; N yacute ; B 13 -271 541 719 ; +C -1 ; WX 556 ; N udieresis ; B 22 -17 538 688 ; +C -1 ; WX 750 ; N threequarters ; B 18 -2 732 683 ; +C -1 ; WX 556 ; N acircumflex ; B 44 -17 527 704 ; +C -1 ; WX 778 ; N Eth ; B 0 -3 747 682 ; +C -1 ; WX 444 ; N edieresis ; B 28 -17 482 688 ; +C -1 ; WX 556 ; N ugrave ; B 22 -17 521 719 ; +C -1 ; WX 1000 ; N trademark ; B 38 274 961 678 ; +C -1 ; WX 556 ; N ograve ; B 48 -17 502 719 ; +C -1 ; WX 444 ; N scaron ; B 25 -17 489 692 ; +C -1 ; WX 389 ; N Idieresis ; B -1 -3 454 880 ; +C -1 ; WX 556 ; N uacute ; B 22 -17 521 719 ; +C -1 ; WX 556 ; N agrave ; B 44 -17 519 719 ; +C -1 ; WX 556 ; N ntilde ; B 17 -17 553 666 ; +C -1 ; WX 556 ; N aring ; B 44 -17 519 714 ; +C -1 ; WX 500 ; N zcaron ; B 31 -17 517 692 ; +C -1 ; WX 389 ; N Icircumflex ; B -1 -3 443 896 ; +C -1 ; WX 778 ; N Ntilde ; B -2 -3 829 866 ; +C -1 ; WX 556 ; N ucircumflex ; B 22 -17 521 704 ; +C -1 ; WX 611 ; N Ecircumflex ; B 11 -3 606 896 ; +C -1 ; WX 389 ; N Iacute ; B -1 -3 420 911 ; +C -1 ; WX 685 ; N Ccedilla ; B 69 -218 695 695 ; +C -1 ; WX 833 ; N Odieresis ; B 76 -17 794 880 ; +C -1 ; WX 556 ; N Scaron ; B 50 -17 557 896 ; +C -1 ; WX 611 ; N Edieresis ; B 11 -3 606 880 ; +C -1 ; WX 389 ; N Igrave ; B -1 -3 412 911 ; +C -1 ; WX 556 ; N adieresis ; B 44 -17 538 688 ; +C -1 ; WX 833 ; N Ograve ; B 76 -17 794 911 ; +C -1 ; WX 611 ; N Egrave ; B 11 -3 606 911 ; +C -1 ; WX 611 ; N Ydieresis ; B 54 -3 675 880 ; +C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ; +C -1 ; WX 833 ; N Otilde ; B 76 -17 794 866 ; +C -1 ; WX 750 ; N onequarter ; B 18 -2 732 683 ; +C -1 ; WX 778 ; N Ugrave ; B 83 -17 825 911 ; +C -1 ; WX 778 ; N Ucircumflex ; B 83 -17 825 896 ; +C -1 ; WX 667 ; N Thorn ; B 11 -3 644 681 ; +C -1 ; WX 606 ; N divide ; B 50 -5 556 501 ; +C -1 ; WX 722 ; N Atilde ; B -35 -3 685 866 ; +C -1 ; WX 778 ; N Uacute ; B 83 -17 825 911 ; +C -1 ; WX 833 ; N Ocircumflex ; B 76 -17 794 896 ; +C -1 ; WX 606 ; N logicalnot ; B 51 107 555 390 ; +C -1 ; WX 722 ; N Aring ; B -35 -3 685 926 ; +C -1 ; WX 333 ; N idieresis ; B 26 -17 426 688 ; +C -1 ; WX 333 ; N iacute ; B 26 -17 392 719 ; +C -1 ; WX 556 ; N aacute ; B 44 -17 519 719 ; +C -1 ; WX 606 ; N plusminus ; B 50 0 556 501 ; +C -1 ; WX 606 ; N multiply ; B 72 17 534 479 ; +C -1 ; WX 778 ; N Udieresis ; B 83 -17 825 880 ; +C -1 ; WX 606 ; N minus ; B 51 204 555 292 ; +C -1 ; WX 300 ; N onesuperior ; B 41 271 298 680 ; +C -1 ; WX 611 ; N Eacute ; B 11 -3 606 911 ; +C -1 ; WX 722 ; N Acircumflex ; B -35 -3 685 896 ; +C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ; +C -1 ; WX 722 ; N Agrave ; B -35 -3 685 911 ; +C -1 ; WX 556 ; N odieresis ; B 48 -17 538 688 ; +C -1 ; WX 556 ; N oacute ; B 48 -17 504 719 ; +C -1 ; WX 400 ; N degree ; B 50 383 350 683 ; +C -1 ; WX 333 ; N igrave ; B 26 -17 322 719 ; +C -1 ; WX 556 ; N mu ; B -15 -232 521 469 ; +C -1 ; WX 833 ; N Oacute ; B 76 -17 794 911 ; +C -1 ; WX 556 ; N eth ; B 48 -17 546 726 ; +C -1 ; WX 722 ; N Adieresis ; B -35 -3 685 880 ; +C -1 ; WX 611 ; N Yacute ; B 54 -3 675 911 ; +C -1 ; WX 606 ; N brokenbar ; B 259 0 347 720 ; +C -1 ; WX 750 ; N onehalf ; B 14 -2 736 683 ; +EndCharMetrics +StartKernData +StartKernPairs 108 + +KPX A y -55 +KPX A w -37 +KPX A v -55 +KPX A space -55 +KPX A quoteright -55 +KPX A Y -74 +KPX A W -74 +KPX A V -74 +KPX A T -55 + +KPX F space -18 +KPX F period -111 +KPX F comma -111 +KPX F A -74 + +KPX L y -37 +KPX L space -18 +KPX L quoteright -55 +KPX L Y -74 +KPX L W -74 +KPX L V -74 +KPX L T -74 + +KPX P space -55 +KPX P period -129 +KPX P comma -129 +KPX P A -92 + +KPX R y -20 +KPX R Y -37 +KPX R W -55 +KPX R V -55 +KPX R T -37 + +KPX T y -80 +KPX T w -50 +KPX T u -92 +KPX T semicolon -55 +KPX T s -92 +KPX T r -92 +KPX T period -55 +KPX T o -111 +KPX T i -74 +KPX T hyphen -92 +KPX T e -111 +KPX T comma -55 +KPX T colon -55 +KPX T c -92 +KPX T a -111 +KPX T O -18 +KPX T A -55 + +KPX V y -50 +KPX V u -50 +KPX V semicolon -37 +KPX V r -74 +KPX V period -111 +KPX V o -74 +KPX V i -50 +KPX V hyphen -37 +KPX V e -74 +KPX V comma -111 +KPX V colon -37 +KPX V a -92 +KPX V A -74 + +KPX W y -30 +KPX W u -30 +KPX W semicolon -18 +KPX W r -30 +KPX W period -55 +KPX W o -55 +KPX W i -30 +KPX W e -55 +KPX W comma -55 +KPX W colon -28 +KPX W a -74 +KPX W A -74 + +KPX Y v -30 +KPX Y u -50 +KPX Y semicolon -55 +KPX Y q -92 +KPX Y period -55 +KPX Y p -74 +KPX Y o -111 +KPX Y i -54 +KPX Y hyphen -55 +KPX Y e -92 +KPX Y comma -55 +KPX Y colon -55 +KPX Y a -111 +KPX Y A -55 + +KPX f quoteright 37 +KPX f f -37 + +KPX one one -55 + +KPX quoteleft quoteleft -55 + +KPX quoteright t -18 +KPX quoteright space -37 +KPX quoteright s -37 +KPX quoteright quoteright -55 + +KPX r quoteright 55 +KPX r q -18 +KPX r period -55 +KPX r o -18 +KPX r h -18 +KPX r g -18 +KPX r e -18 +KPX r comma -55 +KPX r c -18 + +KPX v period -55 +KPX v comma -55 + +KPX w period -55 +KPX w comma -55 + +KPX y period -37 +KPX y comma -37 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 83 212 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 212 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 212 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 212 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 212 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 223 212 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 212 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 212 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 212 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 212 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 212 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 223 212 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 223 212 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 212 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 211 212 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 151 212 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 212 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 212 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 112 20 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 20 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 20 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 112 20 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 12 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 56 20 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 20 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 20 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 56 20 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -12 20 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 100 20 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 44 8 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 112 20 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 20 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 20 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 112 20 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 72 8 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplr8a.afm new file mode 100644 index 00000000..6566b16e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplr8a.afm @@ -0,0 +1,445 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jul 2 22:14:17 1990 +Comment UniqueID 31790 +Comment VMusage 36445 47337 +FontName Palatino-Roman +FullName Palatino Roman +FamilyName Palatino +Weight Roman +ItalicAngle 0 +IsFixedPitch false +FontBBox -166 -283 1021 927 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.005 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 469 +Ascender 726 +Descender -281 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 81 -5 197 694 ; +C 34 ; WX 371 ; N quotedbl ; B 52 469 319 709 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 495 684 ; +C 36 ; WX 500 ; N dollar ; B 30 -116 471 731 ; +C 37 ; WX 840 ; N percent ; B 39 -20 802 709 ; +C 38 ; WX 778 ; N ampersand ; B 43 -20 753 689 ; +C 39 ; WX 278 ; N quoteright ; B 45 446 233 709 ; +C 40 ; WX 333 ; N parenleft ; B 60 -215 301 726 ; +C 41 ; WX 333 ; N parenright ; B 32 -215 273 726 ; +C 42 ; WX 389 ; N asterisk ; B 32 342 359 689 ; +C 43 ; WX 606 ; N plus ; B 51 7 555 512 ; +C 44 ; WX 250 ; N comma ; B 16 -155 218 123 ; +C 45 ; WX 333 ; N hyphen ; B 17 215 312 287 ; +C 46 ; WX 250 ; N period ; B 67 -5 183 111 ; +C 47 ; WX 606 ; N slash ; B 87 -119 519 726 ; +C 48 ; WX 500 ; N zero ; B 29 -20 465 689 ; +C 49 ; WX 500 ; N one ; B 60 -3 418 694 ; +C 50 ; WX 500 ; N two ; B 16 -3 468 689 ; +C 51 ; WX 500 ; N three ; B 15 -20 462 689 ; +C 52 ; WX 500 ; N four ; B 2 -3 472 694 ; +C 53 ; WX 500 ; N five ; B 13 -20 459 689 ; +C 54 ; WX 500 ; N six ; B 32 -20 468 689 ; +C 55 ; WX 500 ; N seven ; B 44 -3 497 689 ; +C 56 ; WX 500 ; N eight ; B 30 -20 464 689 ; +C 57 ; WX 500 ; N nine ; B 20 -20 457 689 ; +C 58 ; WX 250 ; N colon ; B 66 -5 182 456 ; +C 59 ; WX 250 ; N semicolon ; B 16 -153 218 456 ; +C 60 ; WX 606 ; N less ; B 57 0 558 522 ; +C 61 ; WX 606 ; N equal ; B 51 136 555 386 ; +C 62 ; WX 606 ; N greater ; B 48 0 549 522 ; +C 63 ; WX 444 ; N question ; B 43 -5 395 694 ; +C 64 ; WX 747 ; N at ; B 24 -20 724 694 ; +C 65 ; WX 778 ; N A ; B 15 -3 756 700 ; +C 66 ; WX 611 ; N B ; B 26 -3 576 692 ; +C 67 ; WX 709 ; N C ; B 22 -20 670 709 ; +C 68 ; WX 774 ; N D ; B 22 -3 751 692 ; +C 69 ; WX 611 ; N E ; B 22 -3 572 692 ; +C 70 ; WX 556 ; N F ; B 22 -3 536 692 ; +C 71 ; WX 763 ; N G ; B 22 -20 728 709 ; +C 72 ; WX 832 ; N H ; B 22 -3 810 692 ; +C 73 ; WX 337 ; N I ; B 22 -3 315 692 ; +C 74 ; WX 333 ; N J ; B -15 -194 311 692 ; +C 75 ; WX 726 ; N K ; B 22 -3 719 692 ; +C 76 ; WX 611 ; N L ; B 22 -3 586 692 ; +C 77 ; WX 946 ; N M ; B 16 -13 926 692 ; +C 78 ; WX 831 ; N N ; B 17 -20 813 692 ; +C 79 ; WX 786 ; N O ; B 22 -20 764 709 ; +C 80 ; WX 604 ; N P ; B 22 -3 580 692 ; +C 81 ; WX 786 ; N Q ; B 22 -176 764 709 ; +C 82 ; WX 668 ; N R ; B 22 -3 669 692 ; +C 83 ; WX 525 ; N S ; B 24 -20 503 709 ; +C 84 ; WX 613 ; N T ; B 18 -3 595 692 ; +C 85 ; WX 778 ; N U ; B 12 -20 759 692 ; +C 86 ; WX 722 ; N V ; B 8 -9 706 692 ; +C 87 ; WX 1000 ; N W ; B 8 -9 984 700 ; +C 88 ; WX 667 ; N X ; B 14 -3 648 700 ; +C 89 ; WX 667 ; N Y ; B 9 -3 654 704 ; +C 90 ; WX 667 ; N Z ; B 15 -3 638 692 ; +C 91 ; WX 333 ; N bracketleft ; B 79 -184 288 726 ; +C 92 ; WX 606 ; N backslash ; B 81 0 512 726 ; +C 93 ; WX 333 ; N bracketright ; B 45 -184 254 726 ; +C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 45 446 233 709 ; +C 97 ; WX 500 ; N a ; B 32 -12 471 469 ; +C 98 ; WX 553 ; N b ; B -15 -12 508 726 ; +C 99 ; WX 444 ; N c ; B 26 -20 413 469 ; +C 100 ; WX 611 ; N d ; B 35 -12 579 726 ; +C 101 ; WX 479 ; N e ; B 26 -20 448 469 ; +C 102 ; WX 333 ; N f ; B 23 -3 341 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 32 -283 544 469 ; +C 104 ; WX 582 ; N h ; B 6 -3 572 726 ; +C 105 ; WX 291 ; N i ; B 21 -3 271 687 ; +C 106 ; WX 234 ; N j ; B -40 -283 167 688 ; +C 107 ; WX 556 ; N k ; B 21 -12 549 726 ; +C 108 ; WX 291 ; N l ; B 21 -3 271 726 ; +C 109 ; WX 883 ; N m ; B 16 -3 869 469 ; +C 110 ; WX 582 ; N n ; B 6 -3 572 469 ; +C 111 ; WX 546 ; N o ; B 32 -20 514 469 ; +C 112 ; WX 601 ; N p ; B 8 -281 554 469 ; +C 113 ; WX 560 ; N q ; B 35 -281 560 469 ; +C 114 ; WX 395 ; N r ; B 21 -3 374 469 ; +C 115 ; WX 424 ; N s ; B 30 -20 391 469 ; +C 116 ; WX 326 ; N t ; B 22 -12 319 621 ; +C 117 ; WX 603 ; N u ; B 18 -12 581 469 ; +C 118 ; WX 565 ; N v ; B 6 -7 539 459 ; +C 119 ; WX 834 ; N w ; B 6 -7 808 469 ; +C 120 ; WX 516 ; N x ; B 20 -3 496 469 ; +C 121 ; WX 556 ; N y ; B 12 -283 544 459 ; +C 122 ; WX 500 ; N z ; B 16 -3 466 462 ; +C 123 ; WX 333 ; N braceleft ; B 58 -175 289 726 ; +C 124 ; WX 606 ; N bar ; B 275 0 331 726 ; +C 125 ; WX 333 ; N braceright ; B 44 -175 275 726 ; +C 126 ; WX 606 ; N asciitilde ; B 51 176 555 347 ; +C 161 ; WX 278 ; N exclamdown ; B 81 -225 197 469 ; +C 162 ; WX 500 ; N cent ; B 61 -101 448 562 ; +C 163 ; WX 500 ; N sterling ; B 12 -13 478 694 ; +C 164 ; WX 167 ; N fraction ; B -166 0 337 689 ; +C 165 ; WX 500 ; N yen ; B 5 -3 496 701 ; +C 166 ; WX 500 ; N florin ; B 0 -262 473 706 ; +C 167 ; WX 500 ; N section ; B 26 -219 465 709 ; +C 168 ; WX 500 ; N currency ; B 30 96 470 531 ; +C 169 ; WX 208 ; N quotesingle ; B 61 469 147 709 ; +C 170 ; WX 500 ; N quotedblleft ; B 51 446 449 709 ; +C 171 ; WX 500 ; N guillemotleft ; B 50 71 450 428 ; +C 172 ; WX 331 ; N guilsinglleft ; B 66 71 265 428 ; +C 173 ; WX 331 ; N guilsinglright ; B 66 71 265 428 ; +C 174 ; WX 605 ; N fi ; B 23 -3 587 728 ; +C 175 ; WX 608 ; N fl ; B 23 -3 590 728 ; +C 177 ; WX 500 ; N endash ; B 0 219 500 277 ; +C 178 ; WX 500 ; N dagger ; B 34 -5 466 694 ; +C 179 ; WX 500 ; N daggerdbl ; B 34 -249 466 694 ; +C 180 ; WX 250 ; N periodcentered ; B 67 203 183 319 ; +C 182 ; WX 628 ; N paragraph ; B 39 -150 589 694 ; +C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; +C 184 ; WX 278 ; N quotesinglbase ; B 22 -153 210 110 ; +C 185 ; WX 500 ; N quotedblbase ; B 51 -153 449 110 ; +C 186 ; WX 500 ; N quotedblright ; B 51 446 449 709 ; +C 187 ; WX 500 ; N guillemotright ; B 50 71 450 428 ; +C 188 ; WX 1000 ; N ellipsis ; B 109 -5 891 111 ; +C 189 ; WX 1144 ; N perthousand ; B 123 -20 1021 709 ; +C 191 ; WX 444 ; N questiondown ; B 43 -231 395 469 ; +C 193 ; WX 333 ; N grave ; B 31 506 255 677 ; +C 194 ; WX 333 ; N acute ; B 78 506 302 677 ; +C 195 ; WX 333 ; N circumflex ; B 11 510 323 677 ; +C 196 ; WX 333 ; N tilde ; B 2 535 332 640 ; +C 197 ; WX 333 ; N macron ; B 11 538 323 591 ; +C 198 ; WX 333 ; N breve ; B 26 506 308 664 ; +C 199 ; WX 250 ; N dotaccent ; B 75 537 175 637 ; +C 200 ; WX 333 ; N dieresis ; B 17 537 316 637 ; +C 202 ; WX 333 ; N ring ; B 67 496 267 696 ; +C 203 ; WX 333 ; N cedilla ; B 96 -225 304 -10 ; +C 205 ; WX 380 ; N hungarumlaut ; B 3 506 377 687 ; +C 206 ; WX 313 ; N ogonek ; B 68 -165 245 -20 ; +C 207 ; WX 333 ; N caron ; B 11 510 323 677 ; +C 208 ; WX 1000 ; N emdash ; B 0 219 1000 277 ; +C 225 ; WX 944 ; N AE ; B -10 -3 908 692 ; +C 227 ; WX 333 ; N ordfeminine ; B 24 422 310 709 ; +C 232 ; WX 611 ; N Lslash ; B 6 -3 586 692 ; +C 233 ; WX 833 ; N Oslash ; B 30 -20 797 709 ; +C 234 ; WX 998 ; N OE ; B 22 -20 962 709 ; +C 235 ; WX 333 ; N ordmasculine ; B 10 416 323 709 ; +C 241 ; WX 758 ; N ae ; B 30 -20 732 469 ; +C 245 ; WX 287 ; N dotlessi ; B 21 -3 271 469 ; +C 248 ; WX 291 ; N lslash ; B -14 -3 306 726 ; +C 249 ; WX 556 ; N oslash ; B 16 -23 530 474 ; +C 250 ; WX 827 ; N oe ; B 32 -20 800 469 ; +C 251 ; WX 556 ; N germandbls ; B 23 -9 519 731 ; +C -1 ; WX 667 ; N Zcaron ; B 15 -3 638 908 ; +C -1 ; WX 444 ; N ccedilla ; B 26 -225 413 469 ; +C -1 ; WX 556 ; N ydieresis ; B 12 -283 544 657 ; +C -1 ; WX 500 ; N atilde ; B 32 -12 471 652 ; +C -1 ; WX 287 ; N icircumflex ; B -12 -3 300 697 ; +C -1 ; WX 300 ; N threesuperior ; B 1 266 299 689 ; +C -1 ; WX 479 ; N ecircumflex ; B 26 -20 448 697 ; +C -1 ; WX 601 ; N thorn ; B -2 -281 544 726 ; +C -1 ; WX 479 ; N egrave ; B 26 -20 448 697 ; +C -1 ; WX 300 ; N twosuperior ; B 0 273 301 689 ; +C -1 ; WX 479 ; N eacute ; B 26 -20 448 697 ; +C -1 ; WX 546 ; N otilde ; B 32 -20 514 652 ; +C -1 ; WX 778 ; N Aacute ; B 15 -3 756 908 ; +C -1 ; WX 546 ; N ocircumflex ; B 32 -20 514 697 ; +C -1 ; WX 556 ; N yacute ; B 12 -283 544 697 ; +C -1 ; WX 603 ; N udieresis ; B 18 -12 581 657 ; +C -1 ; WX 750 ; N threequarters ; B 15 -3 735 689 ; +C -1 ; WX 500 ; N acircumflex ; B 32 -12 471 697 ; +C -1 ; WX 774 ; N Eth ; B 14 -3 751 692 ; +C -1 ; WX 479 ; N edieresis ; B 26 -20 448 657 ; +C -1 ; WX 603 ; N ugrave ; B 18 -12 581 697 ; +C -1 ; WX 979 ; N trademark ; B 40 285 939 689 ; +C -1 ; WX 546 ; N ograve ; B 32 -20 514 697 ; +C -1 ; WX 424 ; N scaron ; B 30 -20 391 685 ; +C -1 ; WX 337 ; N Idieresis ; B 19 -3 318 868 ; +C -1 ; WX 603 ; N uacute ; B 18 -12 581 697 ; +C -1 ; WX 500 ; N agrave ; B 32 -12 471 697 ; +C -1 ; WX 582 ; N ntilde ; B 6 -3 572 652 ; +C -1 ; WX 500 ; N aring ; B 32 -12 471 716 ; +C -1 ; WX 500 ; N zcaron ; B 16 -3 466 685 ; +C -1 ; WX 337 ; N Icircumflex ; B 13 -3 325 908 ; +C -1 ; WX 831 ; N Ntilde ; B 17 -20 813 871 ; +C -1 ; WX 603 ; N ucircumflex ; B 18 -12 581 697 ; +C -1 ; WX 611 ; N Ecircumflex ; B 22 -3 572 908 ; +C -1 ; WX 337 ; N Iacute ; B 22 -3 315 908 ; +C -1 ; WX 709 ; N Ccedilla ; B 22 -225 670 709 ; +C -1 ; WX 786 ; N Odieresis ; B 22 -20 764 868 ; +C -1 ; WX 525 ; N Scaron ; B 24 -20 503 908 ; +C -1 ; WX 611 ; N Edieresis ; B 22 -3 572 868 ; +C -1 ; WX 337 ; N Igrave ; B 22 -3 315 908 ; +C -1 ; WX 500 ; N adieresis ; B 32 -12 471 657 ; +C -1 ; WX 786 ; N Ograve ; B 22 -20 764 908 ; +C -1 ; WX 611 ; N Egrave ; B 22 -3 572 908 ; +C -1 ; WX 667 ; N Ydieresis ; B 9 -3 654 868 ; +C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ; +C -1 ; WX 786 ; N Otilde ; B 22 -20 764 883 ; +C -1 ; WX 750 ; N onequarter ; B 30 -3 727 692 ; +C -1 ; WX 778 ; N Ugrave ; B 12 -20 759 908 ; +C -1 ; WX 778 ; N Ucircumflex ; B 12 -20 759 908 ; +C -1 ; WX 604 ; N Thorn ; B 32 -3 574 692 ; +C -1 ; WX 606 ; N divide ; B 51 10 555 512 ; +C -1 ; WX 778 ; N Atilde ; B 15 -3 756 871 ; +C -1 ; WX 778 ; N Uacute ; B 12 -20 759 908 ; +C -1 ; WX 786 ; N Ocircumflex ; B 22 -20 764 908 ; +C -1 ; WX 606 ; N logicalnot ; B 51 120 551 386 ; +C -1 ; WX 778 ; N Aring ; B 15 -3 756 927 ; +C -1 ; WX 287 ; N idieresis ; B -6 -3 293 657 ; +C -1 ; WX 287 ; N iacute ; B 21 -3 279 697 ; +C -1 ; WX 500 ; N aacute ; B 32 -12 471 697 ; +C -1 ; WX 606 ; N plusminus ; B 51 0 555 512 ; +C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ; +C -1 ; WX 778 ; N Udieresis ; B 12 -20 759 868 ; +C -1 ; WX 606 ; N minus ; B 51 233 555 289 ; +C -1 ; WX 300 ; N onesuperior ; B 31 273 269 692 ; +C -1 ; WX 611 ; N Eacute ; B 22 -3 572 908 ; +C -1 ; WX 778 ; N Acircumflex ; B 15 -3 756 908 ; +C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ; +C -1 ; WX 778 ; N Agrave ; B 15 -3 756 908 ; +C -1 ; WX 546 ; N odieresis ; B 32 -20 514 657 ; +C -1 ; WX 546 ; N oacute ; B 32 -20 514 697 ; +C -1 ; WX 400 ; N degree ; B 50 389 350 689 ; +C -1 ; WX 287 ; N igrave ; B 8 -3 271 697 ; +C -1 ; WX 603 ; N mu ; B 18 -236 581 469 ; +C -1 ; WX 786 ; N Oacute ; B 22 -20 764 908 ; +C -1 ; WX 546 ; N eth ; B 32 -20 504 728 ; +C -1 ; WX 778 ; N Adieresis ; B 15 -3 756 868 ; +C -1 ; WX 667 ; N Yacute ; B 9 -3 654 908 ; +C -1 ; WX 606 ; N brokenbar ; B 275 0 331 726 ; +C -1 ; WX 750 ; N onehalf ; B 15 -3 735 692 ; +EndCharMetrics +StartKernData +StartKernPairs 111 + +KPX A y -74 +KPX A w -74 +KPX A v -92 +KPX A space -55 +KPX A quoteright -74 +KPX A Y -111 +KPX A W -74 +KPX A V -111 +KPX A T -74 + +KPX F period -92 +KPX F comma -92 +KPX F A -74 + +KPX L y -55 +KPX L space -37 +KPX L quoteright -74 +KPX L Y -92 +KPX L W -74 +KPX L V -92 +KPX L T -74 + +KPX P space -18 +KPX P period -129 +KPX P comma -129 +KPX P A -92 + +KPX R y -37 +KPX R Y -37 +KPX R W -37 +KPX R V -55 +KPX R T -37 + +KPX T y -90 +KPX T w -90 +KPX T u -90 +KPX T semicolon -55 +KPX T s -90 +KPX T r -90 +KPX T period -74 +KPX T o -92 +KPX T i -55 +KPX T hyphen -55 +KPX T e -92 +KPX T comma -74 +KPX T colon -55 +KPX T c -111 +KPX T a -92 +KPX T O -18 +KPX T A -74 + +KPX V y -92 +KPX V u -92 +KPX V semicolon -55 +KPX V r -92 +KPX V period -129 +KPX V o -111 +KPX V i -55 +KPX V hyphen -74 +KPX V e -111 +KPX V comma -129 +KPX V colon -55 +KPX V a -92 +KPX V A -111 + +KPX W y -50 +KPX W u -50 +KPX W semicolon -18 +KPX W r -74 +KPX W period -92 +KPX W o -92 +KPX W i -55 +KPX W hyphen -55 +KPX W e -92 +KPX W comma -92 +KPX W colon -18 +KPX W a -92 +KPX W A -92 + +KPX Y v -90 +KPX Y u -90 +KPX Y space -18 +KPX Y semicolon -74 +KPX Y q -90 +KPX Y period -111 +KPX Y p -111 +KPX Y o -92 +KPX Y i -55 +KPX Y hyphen -92 +KPX Y e -92 +KPX Y comma -111 +KPX Y colon -74 +KPX Y a -92 +KPX Y A -92 + +KPX f quoteright 55 +KPX f f -18 + +KPX one one -55 + +KPX quoteleft quoteleft -37 + +KPX quoteright quoteright -37 + +KPX r u -8 +KPX r quoteright 74 +KPX r q -18 +KPX r period -74 +KPX r o -18 +KPX r hyphen -18 +KPX r h -18 +KPX r g -18 +KPX r e -18 +KPX r d -18 +KPX r comma -74 +KPX r c -18 + +KPX space Y -18 +KPX space A -37 + +KPX v period -111 +KPX v comma -111 + +KPX w period -92 +KPX w comma -92 + +KPX y period -111 +KPX y comma -111 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 229 231 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 223 231 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 231 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 231 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 223 231 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 231 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 231 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 231 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 231 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 231 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 2 231 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 2 231 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 2 231 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 2 231 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 249 231 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 227 231 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 227 231 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 227 231 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 227 231 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 227 243 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 96 231 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 255 231 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 247 231 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 231 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 231 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 203 231 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 191 231 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 231 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 72 20 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 72 20 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 60 20 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 72 20 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 72 12 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 97 20 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 85 20 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 73 20 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 73 20 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -23 20 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -23 20 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -23 20 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -23 20 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 113 12 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 107 20 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 107 20 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 107 20 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 95 20 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 107 12 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 46 8 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 159 20 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 135 20 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 135 20 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 20 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplri8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplri8a.afm new file mode 100644 index 00000000..01bdcf05 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pplri8a.afm @@ -0,0 +1,439 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jul 2 22:37:33 1990 +Comment UniqueID 31796 +Comment VMusage 37415 48307 +FontName Palatino-Italic +FullName Palatino Italic +FamilyName Palatino +Weight Medium +ItalicAngle -10 +IsFixedPitch false +FontBBox -170 -276 1010 918 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.005 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 482 +Ascender 733 +Descender -276 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 76 -8 292 733 ; +C 34 ; WX 500 ; N quotedbl ; B 140 508 455 733 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 495 692 ; +C 36 ; WX 500 ; N dollar ; B 15 -113 452 733 ; +C 37 ; WX 889 ; N percent ; B 74 -7 809 710 ; +C 38 ; WX 778 ; N ampersand ; B 47 -18 766 692 ; +C 39 ; WX 278 ; N quoteright ; B 78 488 258 733 ; +C 40 ; WX 333 ; N parenleft ; B 54 -106 331 733 ; +C 41 ; WX 333 ; N parenright ; B 2 -106 279 733 ; +C 42 ; WX 389 ; N asterisk ; B 76 368 400 706 ; +C 43 ; WX 606 ; N plus ; B 51 0 555 504 ; +C 44 ; WX 250 ; N comma ; B 8 -143 203 123 ; +C 45 ; WX 333 ; N hyphen ; B 19 223 304 281 ; +C 46 ; WX 250 ; N period ; B 53 -5 158 112 ; +C 47 ; WX 296 ; N slash ; B -40 -119 392 733 ; +C 48 ; WX 500 ; N zero ; B 36 -11 480 699 ; +C 49 ; WX 500 ; N one ; B 54 -3 398 699 ; +C 50 ; WX 500 ; N two ; B 12 -3 437 699 ; +C 51 ; WX 500 ; N three ; B 22 -11 447 699 ; +C 52 ; WX 500 ; N four ; B 15 -3 478 699 ; +C 53 ; WX 500 ; N five ; B 14 -11 491 693 ; +C 54 ; WX 500 ; N six ; B 49 -11 469 699 ; +C 55 ; WX 500 ; N seven ; B 53 -3 502 692 ; +C 56 ; WX 500 ; N eight ; B 36 -11 469 699 ; +C 57 ; WX 500 ; N nine ; B 32 -11 468 699 ; +C 58 ; WX 250 ; N colon ; B 44 -5 207 458 ; +C 59 ; WX 250 ; N semicolon ; B -9 -146 219 456 ; +C 60 ; WX 606 ; N less ; B 53 -6 554 516 ; +C 61 ; WX 606 ; N equal ; B 51 126 555 378 ; +C 62 ; WX 606 ; N greater ; B 53 -6 554 516 ; +C 63 ; WX 500 ; N question ; B 114 -8 427 706 ; +C 64 ; WX 747 ; N at ; B 27 -18 718 706 ; +C 65 ; WX 722 ; N A ; B -19 -3 677 705 ; +C 66 ; WX 611 ; N B ; B 26 -6 559 692 ; +C 67 ; WX 667 ; N C ; B 45 -18 651 706 ; +C 68 ; WX 778 ; N D ; B 28 -3 741 692 ; +C 69 ; WX 611 ; N E ; B 30 -3 570 692 ; +C 70 ; WX 556 ; N F ; B 0 -3 548 692 ; +C 71 ; WX 722 ; N G ; B 50 -18 694 706 ; +C 72 ; WX 778 ; N H ; B -3 -3 800 692 ; +C 73 ; WX 333 ; N I ; B 7 -3 354 692 ; +C 74 ; WX 333 ; N J ; B -35 -206 358 692 ; +C 75 ; WX 667 ; N K ; B 13 -3 683 692 ; +C 76 ; WX 556 ; N L ; B 16 -3 523 692 ; +C 77 ; WX 944 ; N M ; B -19 -18 940 692 ; +C 78 ; WX 778 ; N N ; B 2 -11 804 692 ; +C 79 ; WX 778 ; N O ; B 53 -18 748 706 ; +C 80 ; WX 611 ; N P ; B 9 -3 594 692 ; +C 81 ; WX 778 ; N Q ; B 53 -201 748 706 ; +C 82 ; WX 667 ; N R ; B 9 -3 639 692 ; +C 83 ; WX 556 ; N S ; B 42 -18 506 706 ; +C 84 ; WX 611 ; N T ; B 53 -3 635 692 ; +C 85 ; WX 778 ; N U ; B 88 -18 798 692 ; +C 86 ; WX 722 ; N V ; B 75 -8 754 692 ; +C 87 ; WX 944 ; N W ; B 71 -8 980 700 ; +C 88 ; WX 722 ; N X ; B 20 -3 734 692 ; +C 89 ; WX 667 ; N Y ; B 52 -3 675 705 ; +C 90 ; WX 667 ; N Z ; B 20 -3 637 692 ; +C 91 ; WX 333 ; N bracketleft ; B 18 -100 326 733 ; +C 92 ; WX 606 ; N backslash ; B 81 0 513 733 ; +C 93 ; WX 333 ; N bracketright ; B 7 -100 315 733 ; +C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 78 488 258 733 ; +C 97 ; WX 444 ; N a ; B 4 -11 406 482 ; +C 98 ; WX 463 ; N b ; B 37 -11 433 733 ; +C 99 ; WX 407 ; N c ; B 25 -11 389 482 ; +C 100 ; WX 500 ; N d ; B 17 -11 483 733 ; +C 101 ; WX 389 ; N e ; B 15 -11 374 482 ; +C 102 ; WX 278 ; N f ; B -162 -276 413 733 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B -37 -276 498 482 ; +C 104 ; WX 500 ; N h ; B 10 -9 471 733 ; +C 105 ; WX 278 ; N i ; B 34 -9 264 712 ; +C 106 ; WX 278 ; N j ; B -70 -276 265 712 ; +C 107 ; WX 444 ; N k ; B 8 -9 449 733 ; +C 108 ; WX 278 ; N l ; B 36 -9 251 733 ; +C 109 ; WX 778 ; N m ; B 24 -9 740 482 ; +C 110 ; WX 556 ; N n ; B 24 -9 514 482 ; +C 111 ; WX 444 ; N o ; B 17 -11 411 482 ; +C 112 ; WX 500 ; N p ; B -7 -276 465 482 ; +C 113 ; WX 463 ; N q ; B 24 -276 432 482 ; +C 114 ; WX 389 ; N r ; B 26 -9 384 482 ; +C 115 ; WX 389 ; N s ; B 9 -11 345 482 ; +C 116 ; WX 333 ; N t ; B 41 -9 310 646 ; +C 117 ; WX 556 ; N u ; B 32 -11 512 482 ; +C 118 ; WX 500 ; N v ; B 21 -11 477 482 ; +C 119 ; WX 722 ; N w ; B 21 -11 699 482 ; +C 120 ; WX 500 ; N x ; B 9 -11 484 482 ; +C 121 ; WX 500 ; N y ; B -8 -276 490 482 ; +C 122 ; WX 444 ; N z ; B -1 -11 416 482 ; +C 123 ; WX 333 ; N braceleft ; B 15 -100 319 733 ; +C 124 ; WX 606 ; N bar ; B 275 0 331 733 ; +C 125 ; WX 333 ; N braceright ; B 14 -100 318 733 ; +C 126 ; WX 606 ; N asciitilde ; B 51 168 555 339 ; +C 161 ; WX 333 ; N exclamdown ; B 15 -276 233 467 ; +C 162 ; WX 500 ; N cent ; B 56 -96 418 551 ; +C 163 ; WX 500 ; N sterling ; B 2 -18 479 708 ; +C 164 ; WX 167 ; N fraction ; B -170 0 337 699 ; +C 165 ; WX 500 ; N yen ; B 35 -3 512 699 ; +C 166 ; WX 500 ; N florin ; B 5 -276 470 708 ; +C 167 ; WX 500 ; N section ; B 14 -220 463 706 ; +C 168 ; WX 500 ; N currency ; B 14 115 486 577 ; +C 169 ; WX 333 ; N quotesingle ; B 140 508 288 733 ; +C 170 ; WX 500 ; N quotedblleft ; B 98 488 475 733 ; +C 171 ; WX 500 ; N guillemotleft ; B 57 70 437 440 ; +C 172 ; WX 333 ; N guilsinglleft ; B 57 70 270 440 ; +C 173 ; WX 333 ; N guilsinglright ; B 63 70 276 440 ; +C 174 ; WX 528 ; N fi ; B -162 -276 502 733 ; +C 175 ; WX 545 ; N fl ; B -162 -276 520 733 ; +C 177 ; WX 500 ; N endash ; B -10 228 510 278 ; +C 178 ; WX 500 ; N dagger ; B 48 0 469 692 ; +C 179 ; WX 500 ; N daggerdbl ; B 10 -162 494 692 ; +C 180 ; WX 250 ; N periodcentered ; B 53 195 158 312 ; +C 182 ; WX 500 ; N paragraph ; B 33 -224 611 692 ; +C 183 ; WX 500 ; N bullet ; B 86 182 430 526 ; +C 184 ; WX 278 ; N quotesinglbase ; B 27 -122 211 120 ; +C 185 ; WX 500 ; N quotedblbase ; B 43 -122 424 120 ; +C 186 ; WX 500 ; N quotedblright ; B 98 488 475 733 ; +C 187 ; WX 500 ; N guillemotright ; B 63 70 443 440 ; +C 188 ; WX 1000 ; N ellipsis ; B 102 -5 873 112 ; +C 189 ; WX 1000 ; N perthousand ; B 72 -6 929 717 ; +C 191 ; WX 500 ; N questiondown ; B 57 -246 370 467 ; +C 193 ; WX 333 ; N grave ; B 86 518 310 687 ; +C 194 ; WX 333 ; N acute ; B 122 518 346 687 ; +C 195 ; WX 333 ; N circumflex ; B 56 510 350 679 ; +C 196 ; WX 333 ; N tilde ; B 63 535 390 638 ; +C 197 ; WX 333 ; N macron ; B 74 538 386 589 ; +C 198 ; WX 333 ; N breve ; B 92 518 393 677 ; +C 199 ; WX 333 ; N dotaccent ; B 175 537 283 645 ; +C 200 ; WX 333 ; N dieresis ; B 78 537 378 637 ; +C 202 ; WX 333 ; N ring ; B 159 508 359 708 ; +C 203 ; WX 333 ; N cedilla ; B -9 -216 202 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 46 518 385 730 ; +C 206 ; WX 333 ; N ogonek ; B 38 -207 196 -18 ; +C 207 ; WX 333 ; N caron ; B 104 510 409 679 ; +C 208 ; WX 1000 ; N emdash ; B -10 228 1010 278 ; +C 225 ; WX 941 ; N AE ; B -4 -3 902 692 ; +C 227 ; WX 333 ; N ordfeminine ; B 60 404 321 699 ; +C 232 ; WX 556 ; N Lslash ; B -16 -3 523 692 ; +C 233 ; WX 778 ; N Oslash ; B 32 -39 762 721 ; +C 234 ; WX 1028 ; N OE ; B 56 -18 989 706 ; +C 235 ; WX 333 ; N ordmasculine ; B 66 404 322 699 ; +C 241 ; WX 638 ; N ae ; B 1 -11 623 482 ; +C 245 ; WX 278 ; N dotlessi ; B 34 -9 241 482 ; +C 248 ; WX 278 ; N lslash ; B -10 -9 302 733 ; +C 249 ; WX 444 ; N oslash ; B -18 -24 460 510 ; +C 250 ; WX 669 ; N oe ; B 17 -11 654 482 ; +C 251 ; WX 500 ; N germandbls ; B -160 -276 488 733 ; +C -1 ; WX 667 ; N Zcaron ; B 20 -3 637 907 ; +C -1 ; WX 407 ; N ccedilla ; B 25 -216 389 482 ; +C -1 ; WX 500 ; N ydieresis ; B -8 -276 490 657 ; +C -1 ; WX 444 ; N atilde ; B 4 -11 446 650 ; +C -1 ; WX 278 ; N icircumflex ; B 29 -9 323 699 ; +C -1 ; WX 300 ; N threesuperior ; B 28 273 304 699 ; +C -1 ; WX 389 ; N ecircumflex ; B 15 -11 398 699 ; +C -1 ; WX 500 ; N thorn ; B -39 -276 433 733 ; +C -1 ; WX 389 ; N egrave ; B 15 -11 374 707 ; +C -1 ; WX 300 ; N twosuperior ; B 13 278 290 699 ; +C -1 ; WX 389 ; N eacute ; B 15 -11 394 707 ; +C -1 ; WX 444 ; N otilde ; B 17 -11 446 650 ; +C -1 ; WX 722 ; N Aacute ; B -19 -3 677 897 ; +C -1 ; WX 444 ; N ocircumflex ; B 17 -11 411 699 ; +C -1 ; WX 500 ; N yacute ; B -8 -276 490 707 ; +C -1 ; WX 556 ; N udieresis ; B 32 -11 512 657 ; +C -1 ; WX 750 ; N threequarters ; B 35 -2 715 699 ; +C -1 ; WX 444 ; N acircumflex ; B 4 -11 406 699 ; +C -1 ; WX 778 ; N Eth ; B 19 -3 741 692 ; +C -1 ; WX 389 ; N edieresis ; B 15 -11 406 657 ; +C -1 ; WX 556 ; N ugrave ; B 32 -11 512 707 ; +C -1 ; WX 1000 ; N trademark ; B 52 285 951 689 ; +C -1 ; WX 444 ; N ograve ; B 17 -11 411 707 ; +C -1 ; WX 389 ; N scaron ; B 9 -11 419 687 ; +C -1 ; WX 333 ; N Idieresis ; B 7 -3 418 847 ; +C -1 ; WX 556 ; N uacute ; B 32 -11 512 707 ; +C -1 ; WX 444 ; N agrave ; B 4 -11 406 707 ; +C -1 ; WX 556 ; N ntilde ; B 24 -9 514 650 ; +C -1 ; WX 444 ; N aring ; B 4 -11 406 728 ; +C -1 ; WX 444 ; N zcaron ; B -1 -11 447 687 ; +C -1 ; WX 333 ; N Icircumflex ; B 7 -3 390 889 ; +C -1 ; WX 778 ; N Ntilde ; B 2 -11 804 866 ; +C -1 ; WX 556 ; N ucircumflex ; B 32 -11 512 699 ; +C -1 ; WX 611 ; N Ecircumflex ; B 30 -3 570 889 ; +C -1 ; WX 333 ; N Iacute ; B 7 -3 406 897 ; +C -1 ; WX 667 ; N Ccedilla ; B 45 -216 651 706 ; +C -1 ; WX 778 ; N Odieresis ; B 53 -18 748 847 ; +C -1 ; WX 556 ; N Scaron ; B 42 -18 539 907 ; +C -1 ; WX 611 ; N Edieresis ; B 30 -3 570 847 ; +C -1 ; WX 333 ; N Igrave ; B 7 -3 354 897 ; +C -1 ; WX 444 ; N adieresis ; B 4 -11 434 657 ; +C -1 ; WX 778 ; N Ograve ; B 53 -18 748 897 ; +C -1 ; WX 611 ; N Egrave ; B 30 -3 570 897 ; +C -1 ; WX 667 ; N Ydieresis ; B 52 -3 675 847 ; +C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ; +C -1 ; WX 778 ; N Otilde ; B 53 -18 748 866 ; +C -1 ; WX 750 ; N onequarter ; B 31 -2 715 699 ; +C -1 ; WX 778 ; N Ugrave ; B 88 -18 798 897 ; +C -1 ; WX 778 ; N Ucircumflex ; B 88 -18 798 889 ; +C -1 ; WX 611 ; N Thorn ; B 9 -3 570 692 ; +C -1 ; WX 606 ; N divide ; B 51 0 555 504 ; +C -1 ; WX 722 ; N Atilde ; B -19 -3 677 866 ; +C -1 ; WX 778 ; N Uacute ; B 88 -18 798 897 ; +C -1 ; WX 778 ; N Ocircumflex ; B 53 -18 748 889 ; +C -1 ; WX 606 ; N logicalnot ; B 51 118 555 378 ; +C -1 ; WX 722 ; N Aring ; B -19 -3 677 918 ; +C -1 ; WX 278 ; N idieresis ; B 34 -9 351 657 ; +C -1 ; WX 278 ; N iacute ; B 34 -9 331 707 ; +C -1 ; WX 444 ; N aacute ; B 4 -11 414 707 ; +C -1 ; WX 606 ; N plusminus ; B 51 0 555 504 ; +C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ; +C -1 ; WX 778 ; N Udieresis ; B 88 -18 798 847 ; +C -1 ; WX 606 ; N minus ; B 51 224 555 280 ; +C -1 ; WX 300 ; N onesuperior ; B 61 278 285 699 ; +C -1 ; WX 611 ; N Eacute ; B 30 -3 570 897 ; +C -1 ; WX 722 ; N Acircumflex ; B -19 -3 677 889 ; +C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ; +C -1 ; WX 722 ; N Agrave ; B -19 -3 677 897 ; +C -1 ; WX 444 ; N odieresis ; B 17 -11 434 657 ; +C -1 ; WX 444 ; N oacute ; B 17 -11 414 707 ; +C -1 ; WX 400 ; N degree ; B 90 389 390 689 ; +C -1 ; WX 278 ; N igrave ; B 34 -9 271 707 ; +C -1 ; WX 556 ; N mu ; B 15 -226 512 482 ; +C -1 ; WX 778 ; N Oacute ; B 53 -18 748 897 ; +C -1 ; WX 444 ; N eth ; B 17 -11 478 733 ; +C -1 ; WX 722 ; N Adieresis ; B -19 -3 677 847 ; +C -1 ; WX 667 ; N Yacute ; B 52 -3 675 897 ; +C -1 ; WX 606 ; N brokenbar ; B 275 0 331 733 ; +C -1 ; WX 750 ; N onehalf ; B 31 -2 721 699 ; +EndCharMetrics +StartKernData +StartKernPairs 106 + +KPX A y -55 +KPX A w -37 +KPX A v -37 +KPX A space -37 +KPX A quoteright -55 +KPX A Y -55 +KPX A W -55 +KPX A V -74 +KPX A T -55 + +KPX F period -111 +KPX F comma -111 +KPX F A -111 + +KPX L y -37 +KPX L space -18 +KPX L quoteright -37 +KPX L Y -74 +KPX L W -74 +KPX L V -74 +KPX L T -74 + +KPX P period -129 +KPX P comma -129 +KPX P A -129 + +KPX R y -37 +KPX R Y -55 +KPX R W -55 +KPX R V -74 +KPX R T -55 + +KPX T y -92 +KPX T w -92 +KPX T u -111 +KPX T semicolon -74 +KPX T s -111 +KPX T r -111 +KPX T period -74 +KPX T o -111 +KPX T i -55 +KPX T hyphen -55 +KPX T e -111 +KPX T comma -74 +KPX T colon -74 +KPX T c -111 +KPX T a -111 +KPX T O -18 +KPX T A -92 + +KPX V y -74 +KPX V u -74 +KPX V semicolon -37 +KPX V r -92 +KPX V period -129 +KPX V o -74 +KPX V i -74 +KPX V hyphen -55 +KPX V e -92 +KPX V comma -129 +KPX V colon -37 +KPX V a -74 +KPX V A -210 + +KPX W y -20 +KPX W u -20 +KPX W semicolon -18 +KPX W r -20 +KPX W period -55 +KPX W o -20 +KPX W i -20 +KPX W hyphen -18 +KPX W e -20 +KPX W comma -55 +KPX W colon -18 +KPX W a -20 +KPX W A -92 + +KPX Y v -74 +KPX Y u -92 +KPX Y semicolon -74 +KPX Y q -92 +KPX Y period -92 +KPX Y p -74 +KPX Y o -111 +KPX Y i -55 +KPX Y hyphen -74 +KPX Y e -111 +KPX Y comma -92 +KPX Y colon -74 +KPX Y a -92 +KPX Y A -92 + +KPX f quoteright 55 + +KPX one one -55 + +KPX quoteleft quoteleft -74 + +KPX quoteright t -37 +KPX quoteright space -55 +KPX quoteright s -55 +KPX quoteright quoteright -74 + +KPX r quoteright 37 +KPX r q -18 +KPX r period -74 +KPX r o -18 +KPX r h -18 +KPX r g -18 +KPX r e -18 +KPX r comma -74 +KPX r c -18 + +KPX v period -55 +KPX v comma -55 + +KPX w period -55 +KPX w comma -55 + +KPX y period -37 +KPX y comma -37 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 271 210 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 261 210 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 255 210 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 210 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 235 210 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 255 228 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 199 210 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 179 210 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 179 210 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 210 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 60 210 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 210 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 40 210 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 263 228 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 210 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 210 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 255 210 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 251 210 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 228 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 130 228 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 277 210 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 255 210 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 210 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 210 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 227 210 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 187 210 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 228 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 68 20 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 20 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 20 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 44 20 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 36 20 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 12 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 37 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 48 20 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 48 20 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 28 20 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 16 20 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -15 20 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 20 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 20 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -39 20 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 68 20 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 56 20 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 56 20 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 36 20 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 56 12 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 10 8 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 124 20 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 20 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 100 20 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 96 20 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 20 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 38 8 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/psyr.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/psyr.afm new file mode 100644 index 00000000..1cdbdae6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/psyr.afm @@ -0,0 +1,209 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Wed Jan 17 21:48:26 1990 +Comment UniqueID 27004 +Comment VMusage 28489 37622 +FontName Symbol +FullName Symbol +FamilyName Symbol +Weight Medium +ItalicAngle 0 +IsFixedPitch false +FontBBox -180 -293 1090 1010 +UnderlinePosition -98 +UnderlineThickness 54 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. +EncodingScheme FontSpecific +StartCharMetrics 189 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ; +C 34 ; WX 713 ; N universal ; B 31 0 681 705 ; +C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ; +C 36 ; WX 549 ; N existential ; B 25 0 478 707 ; +C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ; +C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ; +C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ; +C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ; +C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ; +C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ; +C 43 ; WX 549 ; N plus ; B 10 0 539 533 ; +C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ; +C 45 ; WX 549 ; N minus ; B 11 233 535 288 ; +C 46 ; WX 250 ; N period ; B 69 -17 181 95 ; +C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ; +C 48 ; WX 500 ; N zero ; B 23 -17 471 685 ; +C 49 ; WX 500 ; N one ; B 117 0 390 673 ; +C 50 ; WX 500 ; N two ; B 25 0 475 686 ; +C 51 ; WX 500 ; N three ; B 39 -17 435 685 ; +C 52 ; WX 500 ; N four ; B 16 0 469 685 ; +C 53 ; WX 500 ; N five ; B 29 -17 443 685 ; +C 54 ; WX 500 ; N six ; B 36 -17 467 685 ; +C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ; +C 56 ; WX 500 ; N eight ; B 54 -18 440 685 ; +C 57 ; WX 500 ; N nine ; B 31 -18 460 685 ; +C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ; +C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ; +C 60 ; WX 549 ; N less ; B 26 0 523 522 ; +C 61 ; WX 549 ; N equal ; B 11 141 537 390 ; +C 62 ; WX 549 ; N greater ; B 26 0 523 522 ; +C 63 ; WX 444 ; N question ; B 70 -17 412 686 ; +C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ; +C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ; +C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ; +C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ; +C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ; +C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ; +C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ; +C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ; +C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ; +C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ; +C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ; +C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ; +C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ; +C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ; +C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ; +C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ; +C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ; +C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ; +C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ; +C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ; +C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ; +C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ; +C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ; +C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ; +C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ; +C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ; +C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ; +C 92 ; WX 863 ; N therefore ; B 163 0 701 478 ; +C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ; +C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ; +C 95 ; WX 500 ; N underscore ; B -2 -252 502 -206 ; +C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ; +C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ; +C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ; +C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ; +C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ; +C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ; +C 102 ; WX 521 ; N phi ; B 27 -224 490 671 ; +C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ; +C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ; +C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ; +C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ; +C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ; +C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ; +C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ; +C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ; +C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ; +C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ; +C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ; +C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ; +C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ; +C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ; +C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ; +C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ; +C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ; +C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ; +C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ; +C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ; +C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ; +C 124 ; WX 200 ; N bar ; B 65 -177 135 673 ; +C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ; +C 126 ; WX 549 ; N similar ; B 17 203 529 307 ; +C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ; +C 162 ; WX 247 ; N minute ; B 27 459 228 735 ; +C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ; +C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ; +C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ; +C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ; +C 167 ; WX 753 ; N club ; B 86 -26 660 533 ; +C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ; +C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ; +C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ; +C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ; +C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ; +C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ; +C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ; +C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ; +C 176 ; WX 400 ; N degree ; B 50 385 350 685 ; +C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ; +C 178 ; WX 411 ; N second ; B 20 459 413 737 ; +C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ; +C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ; +C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ; +C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ; +C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ; +C 184 ; WX 549 ; N divide ; B 10 71 536 456 ; +C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ; +C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ; +C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ; +C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ; +C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ; +C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ; +C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ; +C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ; +C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ; +C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ; +C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ; +C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ; +C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ; +C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ; +C 200 ; WX 768 ; N union ; B 40 -17 732 492 ; +C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ; +C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ; +C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ; +C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ; +C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ; +C 206 ; WX 713 ; N element ; B 45 0 505 468 ; +C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ; +C 208 ; WX 768 ; N angle ; B 26 0 738 673 ; +C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ; +C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ; +C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ; +C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ; +C 213 ; WX 823 ; N product ; B 25 -101 803 751 ; +C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ; +C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ; +C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ; +C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ; +C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ; +C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ; +C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ; +C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ; +C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ; +C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ; +C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ; +C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ; +C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ; +C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ; +C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ; +C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ; +C 230 ; WX 384 ; N parenlefttp ; B 40 -293 436 926 ; +C 231 ; WX 384 ; N parenleftex ; B 40 -85 92 925 ; +C 232 ; WX 384 ; N parenleftbt ; B 40 -293 436 926 ; +C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 341 926 ; +C 234 ; WX 384 ; N bracketleftex ; B 0 -79 55 925 ; +C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 340 926 ; +C 236 ; WX 494 ; N bracelefttp ; B 201 -75 439 926 ; +C 237 ; WX 494 ; N braceleftmid ; B 14 -85 255 935 ; +C 238 ; WX 494 ; N braceleftbt ; B 201 -70 439 926 ; +C 239 ; WX 494 ; N braceex ; B 201 -80 255 935 ; +C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ; +C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ; +C 243 ; WX 686 ; N integraltp ; B 332 -83 715 921 ; +C 244 ; WX 686 ; N integralex ; B 332 -88 415 975 ; +C 245 ; WX 686 ; N integralbt ; B 39 -81 415 921 ; +C 246 ; WX 384 ; N parenrighttp ; B 54 -293 450 926 ; +C 247 ; WX 384 ; N parenrightex ; B 398 -85 450 925 ; +C 248 ; WX 384 ; N parenrightbt ; B 54 -293 450 926 ; +C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 360 926 ; +C 250 ; WX 384 ; N bracketrightex ; B 305 -79 360 925 ; +C 251 ; WX 384 ; N bracketrightbt ; B 20 -80 360 926 ; +C 252 ; WX 494 ; N bracerighttp ; B 17 -75 255 926 ; +C 253 ; WX 494 ; N bracerightmid ; B 201 -85 442 935 ; +C 254 ; WX 494 ; N bracerightbt ; B 17 -70 255 926 ; +C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmb8a.afm new file mode 100644 index 00000000..55207f94 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmb8a.afm @@ -0,0 +1,648 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Mar 20 12:17:14 1990 +Comment UniqueID 28417 +Comment VMusage 30458 37350 +FontName Times-Bold +FullName Times Bold +FamilyName Times +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -168 -218 1000 935 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 676 +XHeight 461 +Ascender 676 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ; +C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ; +C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ; +C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ; +C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ; +C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ; +C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ; +C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ; +C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ; +C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ; +C 46 ; WX 250 ; N period ; B 41 -13 210 156 ; +C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ; +C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ; +C 49 ; WX 500 ; N one ; B 65 0 442 688 ; +C 50 ; WX 500 ; N two ; B 17 0 478 688 ; +C 51 ; WX 500 ; N three ; B 16 -14 468 688 ; +C 52 ; WX 500 ; N four ; B 19 0 475 688 ; +C 53 ; WX 500 ; N five ; B 22 -8 470 676 ; +C 54 ; WX 500 ; N six ; B 28 -13 475 688 ; +C 55 ; WX 500 ; N seven ; B 17 0 477 676 ; +C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ; +C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ; +C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ; +C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 57 -13 445 689 ; +C 64 ; WX 930 ; N at ; B 108 -19 822 691 ; +C 65 ; WX 722 ; N A ; B 9 0 689 690 ; +C 66 ; WX 667 ; N B ; B 16 0 619 676 ; +C 67 ; WX 722 ; N C ; B 49 -19 687 691 ; +C 68 ; WX 722 ; N D ; B 14 0 690 676 ; +C 69 ; WX 667 ; N E ; B 16 0 641 676 ; +C 70 ; WX 611 ; N F ; B 16 0 583 676 ; +C 71 ; WX 778 ; N G ; B 37 -19 755 691 ; +C 72 ; WX 778 ; N H ; B 21 0 759 676 ; +C 73 ; WX 389 ; N I ; B 20 0 370 676 ; +C 74 ; WX 500 ; N J ; B 3 -96 479 676 ; +C 75 ; WX 778 ; N K ; B 30 0 769 676 ; +C 76 ; WX 667 ; N L ; B 19 0 638 676 ; +C 77 ; WX 944 ; N M ; B 14 0 921 676 ; +C 78 ; WX 722 ; N N ; B 16 -18 701 676 ; +C 79 ; WX 778 ; N O ; B 35 -19 743 691 ; +C 80 ; WX 611 ; N P ; B 16 0 600 676 ; +C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ; +C 82 ; WX 722 ; N R ; B 26 0 715 676 ; +C 83 ; WX 556 ; N S ; B 35 -19 513 692 ; +C 84 ; WX 667 ; N T ; B 31 0 636 676 ; +C 85 ; WX 722 ; N U ; B 16 -19 701 676 ; +C 86 ; WX 722 ; N V ; B 16 -18 701 676 ; +C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ; +C 88 ; WX 722 ; N X ; B 16 0 699 676 ; +C 89 ; WX 722 ; N Y ; B 15 0 699 676 ; +C 90 ; WX 667 ; N Z ; B 28 0 634 676 ; +C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ; +C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ; +C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ; +C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ; +C 97 ; WX 500 ; N a ; B 25 -14 488 473 ; +C 98 ; WX 556 ; N b ; B 17 -14 521 676 ; +C 99 ; WX 444 ; N c ; B 25 -14 430 473 ; +C 100 ; WX 556 ; N d ; B 25 -14 534 676 ; +C 101 ; WX 444 ; N e ; B 25 -14 426 473 ; +C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -206 483 473 ; +C 104 ; WX 556 ; N h ; B 16 0 534 676 ; +C 105 ; WX 278 ; N i ; B 16 0 255 691 ; +C 106 ; WX 333 ; N j ; B -57 -203 263 691 ; +C 107 ; WX 556 ; N k ; B 22 0 543 676 ; +C 108 ; WX 278 ; N l ; B 16 0 255 676 ; +C 109 ; WX 833 ; N m ; B 16 0 814 473 ; +C 110 ; WX 556 ; N n ; B 21 0 539 473 ; +C 111 ; WX 500 ; N o ; B 25 -14 476 473 ; +C 112 ; WX 556 ; N p ; B 19 -205 524 473 ; +C 113 ; WX 556 ; N q ; B 34 -205 536 473 ; +C 114 ; WX 444 ; N r ; B 29 0 434 473 ; +C 115 ; WX 389 ; N s ; B 25 -14 361 473 ; +C 116 ; WX 333 ; N t ; B 20 -12 332 630 ; +C 117 ; WX 556 ; N u ; B 16 -14 537 461 ; +C 118 ; WX 500 ; N v ; B 21 -14 485 461 ; +C 119 ; WX 722 ; N w ; B 23 -14 707 461 ; +C 120 ; WX 500 ; N x ; B 12 0 484 461 ; +C 121 ; WX 500 ; N y ; B 16 -205 480 461 ; +C 122 ; WX 444 ; N z ; B 21 0 420 461 ; +C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ; +C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ; +C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ; +C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ; +C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ; +C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ; +C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ; +C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ; +C 165 ; WX 500 ; N yen ; B -64 0 547 676 ; +C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ; +C 167 ; WX 500 ; N section ; B 57 -132 443 691 ; +C 168 ; WX 500 ; N currency ; B -26 61 526 613 ; +C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ; +C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ; +C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ; +C 174 ; WX 556 ; N fi ; B 14 0 536 691 ; +C 175 ; WX 556 ; N fl ; B 14 0 536 691 ; +C 177 ; WX 500 ; N endash ; B 0 181 500 271 ; +C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ; +C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ; +C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ; +C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ; +C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ; +C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ; +C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ; +C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ; +C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ; +C 193 ; WX 333 ; N grave ; B 8 528 246 713 ; +C 194 ; WX 333 ; N acute ; B 86 528 324 713 ; +C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ; +C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ; +C 197 ; WX 333 ; N macron ; B 1 565 331 637 ; +C 198 ; WX 333 ; N breve ; B 15 528 318 691 ; +C 199 ; WX 333 ; N dotaccent ; B 103 537 230 667 ; +C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ; +C 202 ; WX 333 ; N ring ; B 60 527 273 740 ; +C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ; +C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ; +C 207 ; WX 333 ; N caron ; B -2 528 335 704 ; +C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ; +C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ; +C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ; +C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ; +C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ; +C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ; +C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ; +C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ; +C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ; +C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ; +C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ; +C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ; +C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ; +C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ; +C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ; +C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ; +C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ; +C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ; +C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ; +C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ; +C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ; +C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ; +C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ; +C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ; +C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ; +C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ; +C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ; +C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ; +C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ; +C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ; +C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ; +C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ; +C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ; +C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ; +C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ; +C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ; +C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ; +C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ; +C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ; +C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ; +C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ; +C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ; +C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ; +C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ; +C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ; +C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ; +C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ; +C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ; +C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ; +C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ; +C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ; +C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ; +C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ; +C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ; +C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ; +C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ; +C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ; +C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ; +C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ; +C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ; +C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ; +C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ; +C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ; +C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ; +C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ; +C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ; +C -1 ; WX 278 ; N idieresis ; B -36 0 301 667 ; +C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ; +C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ; +C -1 ; WX 570 ; N minus ; B 33 209 537 297 ; +C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ; +C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ; +C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ; +C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ; +C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ; +C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ; +C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ; +C -1 ; WX 400 ; N degree ; B 57 402 343 688 ; +C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ; +C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ; +C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ; +C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ; +C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ; +C -1 ; WX 722 ; N Yacute ; B 15 0 699 928 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ; +C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ; +EndCharMetrics +StartKernData +StartKernPairs 283 + +KPX A y -74 +KPX A w -90 +KPX A v -100 +KPX A u -50 +KPX A quoteright -74 +KPX A quotedblright 0 +KPX A p -25 +KPX A Y -100 +KPX A W -130 +KPX A V -145 +KPX A U -50 +KPX A T -95 +KPX A Q -45 +KPX A O -45 +KPX A G -55 +KPX A C -55 + +KPX B period 0 +KPX B comma 0 +KPX B U -10 +KPX B A -30 + +KPX D period -20 +KPX D comma 0 +KPX D Y -40 +KPX D W -40 +KPX D V -40 +KPX D A -35 + +KPX F r 0 +KPX F period -110 +KPX F o -25 +KPX F i 0 +KPX F e -25 +KPX F comma -92 +KPX F a -25 +KPX F A -90 + +KPX G period 0 +KPX G comma 0 + +KPX J u -15 +KPX J period -20 +KPX J o -15 +KPX J e -15 +KPX J comma 0 +KPX J a -15 +KPX J A -30 + +KPX K y -45 +KPX K u -15 +KPX K o -25 +KPX K e -25 +KPX K O -30 + +KPX L y -55 +KPX L quoteright -110 +KPX L quotedblright -20 +KPX L Y -92 +KPX L W -92 +KPX L V -92 +KPX L T -92 + +KPX N period 0 +KPX N comma 0 +KPX N A -20 + +KPX O period 0 +KPX O comma 0 +KPX O Y -50 +KPX O X -40 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -40 + +KPX P period -110 +KPX P o -20 +KPX P e -20 +KPX P comma -92 +KPX P a -10 +KPX P A -74 + +KPX Q period -20 +KPX Q comma 0 +KPX Q U -10 + +KPX R Y -35 +KPX R W -35 +KPX R V -55 +KPX R U -30 +KPX R T -40 +KPX R O -30 + +KPX S period 0 +KPX S comma 0 + +KPX T y -74 +KPX T w -74 +KPX T u -92 +KPX T semicolon -74 +KPX T r -74 +KPX T period -90 +KPX T o -92 +KPX T i -18 +KPX T hyphen -92 +KPX T h 0 +KPX T e -92 +KPX T comma -74 +KPX T colon -74 +KPX T a -92 +KPX T O -18 +KPX T A -90 + +KPX U period -50 +KPX U comma -50 +KPX U A -60 + +KPX V u -92 +KPX V semicolon -92 +KPX V period -145 +KPX V o -100 +KPX V i -37 +KPX V hyphen -74 +KPX V e -100 +KPX V comma -129 +KPX V colon -92 +KPX V a -92 +KPX V O -45 +KPX V G -30 +KPX V A -135 + +KPX W y -60 +KPX W u -50 +KPX W semicolon -55 +KPX W period -92 +KPX W o -75 +KPX W i -18 +KPX W hyphen -37 +KPX W h 0 +KPX W e -65 +KPX W comma -92 +KPX W colon -55 +KPX W a -65 +KPX W O -10 +KPX W A -120 + +KPX Y u -92 +KPX Y semicolon -92 +KPX Y period -92 +KPX Y o -111 +KPX Y i -37 +KPX Y hyphen -92 +KPX Y e -111 +KPX Y comma -92 +KPX Y colon -92 +KPX Y a -85 +KPX Y O -35 +KPX Y A -110 + +KPX a y 0 +KPX a w 0 +KPX a v -25 +KPX a t 0 +KPX a p 0 +KPX a g 0 +KPX a b 0 + +KPX b y 0 +KPX b v -15 +KPX b u -20 +KPX b period -40 +KPX b l 0 +KPX b comma 0 +KPX b b -10 + +KPX c y 0 +KPX c period 0 +KPX c l 0 +KPX c k 0 +KPX c h 0 +KPX c comma 0 + +KPX colon space 0 + +KPX comma space 0 +KPX comma quoteright -55 +KPX comma quotedblright -45 + +KPX d y 0 +KPX d w -15 +KPX d v 0 +KPX d period 0 +KPX d d 0 +KPX d comma 0 + +KPX e y 0 +KPX e x 0 +KPX e w 0 +KPX e v -15 +KPX e period 0 +KPX e p 0 +KPX e g 0 +KPX e comma 0 +KPX e b 0 + +KPX f quoteright 55 +KPX f quotedblright 50 +KPX f period -15 +KPX f o -25 +KPX f l 0 +KPX f i -25 +KPX f f 0 +KPX f e 0 +KPX f dotlessi -35 +KPX f comma -15 +KPX f a 0 + +KPX g y 0 +KPX g r 0 +KPX g period -15 +KPX g o 0 +KPX g i 0 +KPX g g 0 +KPX g e 0 +KPX g comma 0 +KPX g a 0 + +KPX h y -15 + +KPX i v -10 + +KPX k y -15 +KPX k o -15 +KPX k e -10 + +KPX l y 0 +KPX l w 0 + +KPX m y 0 +KPX m u 0 + +KPX n y 0 +KPX n v -40 +KPX n u 0 + +KPX o y 0 +KPX o x 0 +KPX o w -10 +KPX o v -10 +KPX o g 0 + +KPX p y 0 + +KPX period quoteright -55 +KPX period quotedblright -55 + +KPX quotedblleft quoteleft 0 +KPX quotedblleft A -10 + +KPX quotedblright space 0 + +KPX quoteleft quoteleft -63 +KPX quoteleft A -10 + +KPX quoteright v -20 +KPX quoteright t 0 +KPX quoteright space -74 +KPX quoteright s -37 +KPX quoteright r -20 +KPX quoteright quoteright -63 +KPX quoteright quotedblright 0 +KPX quoteright l 0 +KPX quoteright d -20 + +KPX r y 0 +KPX r v -10 +KPX r u 0 +KPX r t 0 +KPX r s 0 +KPX r r 0 +KPX r q -18 +KPX r period -100 +KPX r p -10 +KPX r o -18 +KPX r n -15 +KPX r m 0 +KPX r l 0 +KPX r k 0 +KPX r i 0 +KPX r hyphen -37 +KPX r g -10 +KPX r e -18 +KPX r d 0 +KPX r comma -92 +KPX r c -18 +KPX r a 0 + +KPX s w 0 + +KPX space quoteleft 0 +KPX space quotedblleft 0 +KPX space Y -55 +KPX space W -30 +KPX space V -45 +KPX space T -30 +KPX space A -55 + +KPX v period -70 +KPX v o -10 +KPX v e -10 +KPX v comma -55 +KPX v a -10 + +KPX w period -70 +KPX w o -10 +KPX w h 0 +KPX w e 0 +KPX w comma -55 +KPX w a 0 + +KPX x e 0 + +KPX y period -70 +KPX y o -25 +KPX y e -10 +KPX y comma -55 +KPX y a 0 + +KPX z o 0 +KPX z e 0 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 188 210 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 188 210 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 188 210 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 188 210 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 180 195 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 188 210 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 208 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 210 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 210 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 210 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 210 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 210 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 210 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 210 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 210 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 210 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 210 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 210 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 210 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 210 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 210 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 222 210 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 222 210 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 222 210 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 222 210 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 210 215 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 215 210 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 210 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 77 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 77 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 77 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 77 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 77 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 77 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 62 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 62 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 62 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 62 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 105 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 105 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 105 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 105 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm new file mode 100644 index 00000000..25ab54ea --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm @@ -0,0 +1,648 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Mar 20 13:14:55 1990 +Comment UniqueID 28425 +Comment VMusage 32721 39613 +FontName Times-BoldItalic +FullName Times Bold Italic +FamilyName Times +Weight Bold +ItalicAngle -15 +IsFixedPitch false +FontBBox -200 -218 996 921 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.009 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 669 +XHeight 462 +Ascender 699 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ; +C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ; +C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ; +C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ; +C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ; +C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ; +C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ; +C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ; +C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ; +C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ; +C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ; +C 46 ; WX 250 ; N period ; B -9 -13 139 135 ; +C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ; +C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ; +C 49 ; WX 500 ; N one ; B 5 0 419 683 ; +C 50 ; WX 500 ; N two ; B -27 0 446 683 ; +C 51 ; WX 500 ; N three ; B -15 -13 450 683 ; +C 52 ; WX 500 ; N four ; B -15 0 503 683 ; +C 53 ; WX 500 ; N five ; B -11 -13 487 669 ; +C 54 ; WX 500 ; N six ; B 23 -15 509 679 ; +C 55 ; WX 500 ; N seven ; B 52 0 525 669 ; +C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ; +C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ; +C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ; +C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 79 -13 470 684 ; +C 64 ; WX 832 ; N at ; B 63 -18 770 685 ; +C 65 ; WX 667 ; N A ; B -67 0 593 683 ; +C 66 ; WX 667 ; N B ; B -24 0 624 669 ; +C 67 ; WX 667 ; N C ; B 32 -18 677 685 ; +C 68 ; WX 722 ; N D ; B -46 0 685 669 ; +C 69 ; WX 667 ; N E ; B -27 0 653 669 ; +C 70 ; WX 667 ; N F ; B -13 0 660 669 ; +C 71 ; WX 722 ; N G ; B 21 -18 706 685 ; +C 72 ; WX 778 ; N H ; B -24 0 799 669 ; +C 73 ; WX 389 ; N I ; B -32 0 406 669 ; +C 74 ; WX 500 ; N J ; B -46 -99 524 669 ; +C 75 ; WX 667 ; N K ; B -21 0 702 669 ; +C 76 ; WX 611 ; N L ; B -22 0 590 669 ; +C 77 ; WX 889 ; N M ; B -29 -12 917 669 ; +C 78 ; WX 722 ; N N ; B -27 -15 748 669 ; +C 79 ; WX 722 ; N O ; B 27 -18 691 685 ; +C 80 ; WX 611 ; N P ; B -27 0 613 669 ; +C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ; +C 82 ; WX 667 ; N R ; B -29 0 623 669 ; +C 83 ; WX 556 ; N S ; B 2 -18 526 685 ; +C 84 ; WX 611 ; N T ; B 50 0 650 669 ; +C 85 ; WX 722 ; N U ; B 67 -18 744 669 ; +C 86 ; WX 667 ; N V ; B 65 -18 715 669 ; +C 87 ; WX 889 ; N W ; B 65 -18 940 669 ; +C 88 ; WX 667 ; N X ; B -24 0 694 669 ; +C 89 ; WX 611 ; N Y ; B 73 0 659 669 ; +C 90 ; WX 611 ; N Z ; B -11 0 590 669 ; +C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ; +C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ; +C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ; +C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ; +C 97 ; WX 500 ; N a ; B -21 -14 455 462 ; +C 98 ; WX 500 ; N b ; B -14 -13 444 699 ; +C 99 ; WX 444 ; N c ; B -5 -13 392 462 ; +C 100 ; WX 500 ; N d ; B -21 -13 517 699 ; +C 101 ; WX 444 ; N e ; B 5 -13 398 462 ; +C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B -52 -203 478 462 ; +C 104 ; WX 556 ; N h ; B -13 -9 498 699 ; +C 105 ; WX 278 ; N i ; B 2 -9 263 684 ; +C 106 ; WX 278 ; N j ; B -189 -207 279 684 ; +C 107 ; WX 500 ; N k ; B -23 -8 483 699 ; +C 108 ; WX 278 ; N l ; B 2 -9 290 699 ; +C 109 ; WX 778 ; N m ; B -14 -9 722 462 ; +C 110 ; WX 556 ; N n ; B -6 -9 493 462 ; +C 111 ; WX 500 ; N o ; B -3 -13 441 462 ; +C 112 ; WX 500 ; N p ; B -120 -205 446 462 ; +C 113 ; WX 500 ; N q ; B 1 -205 471 462 ; +C 114 ; WX 389 ; N r ; B -21 0 389 462 ; +C 115 ; WX 389 ; N s ; B -19 -13 333 462 ; +C 116 ; WX 278 ; N t ; B -11 -9 281 594 ; +C 117 ; WX 556 ; N u ; B 15 -9 492 462 ; +C 118 ; WX 444 ; N v ; B 16 -13 401 462 ; +C 119 ; WX 667 ; N w ; B 16 -13 614 462 ; +C 120 ; WX 500 ; N x ; B -46 -13 469 462 ; +C 121 ; WX 444 ; N y ; B -94 -205 392 462 ; +C 122 ; WX 389 ; N z ; B -43 -78 368 449 ; +C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ; +C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ; +C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ; +C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ; +C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ; +C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ; +C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ; +C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ; +C 165 ; WX 500 ; N yen ; B 33 0 628 669 ; +C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ; +C 167 ; WX 500 ; N section ; B 36 -143 459 685 ; +C 168 ; WX 500 ; N currency ; B -26 34 526 586 ; +C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ; +C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ; +C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ; +C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ; +C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ; +C 177 ; WX 500 ; N endash ; B -40 178 477 269 ; +C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ; +C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ; +C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ; +C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ; +C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ; +C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ; +C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ; +C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ; +C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ; +C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ; +C 193 ; WX 333 ; N grave ; B 85 516 297 697 ; +C 194 ; WX 333 ; N acute ; B 139 516 379 697 ; +C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ; +C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ; +C 197 ; WX 333 ; N macron ; B 51 553 393 623 ; +C 198 ; WX 333 ; N breve ; B 71 516 387 678 ; +C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ; +C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ; +C 202 ; WX 333 ; N ring ; B 127 516 340 729 ; +C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ; +C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ; +C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ; +C 207 ; WX 333 ; N caron ; B 79 516 411 690 ; +C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ; +C 225 ; WX 944 ; N AE ; B -64 0 918 669 ; +C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ; +C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ; +C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ; +C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ; +C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ; +C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ; +C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ; +C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ; +C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ; +C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ; +C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ; +C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ; +C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ; +C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ; +C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ; +C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ; +C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ; +C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ; +C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ; +C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ; +C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ; +C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ; +C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ; +C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ; +C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ; +C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ; +C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ; +C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ; +C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ; +C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ; +C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ; +C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ; +C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ; +C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ; +C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ; +C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ; +C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ; +C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ; +C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ; +C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ; +C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ; +C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ; +C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ; +C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ; +C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ; +C -1 ; WX 389 ; N Iacute ; B -32 0 412 904 ; +C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ; +C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ; +C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ; +C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ; +C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ; +C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ; +C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ; +C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ; +C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ; +C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ; +C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ; +C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ; +C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ; +C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ; +C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ; +C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ; +C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ; +C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ; +C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ; +C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ; +C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ; +C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ; +C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ; +C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ; +C -1 ; WX 606 ; N minus ; B 51 209 555 297 ; +C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ; +C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ; +C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ; +C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ; +C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ; +C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ; +C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ; +C -1 ; WX 400 ; N degree ; B 83 397 369 683 ; +C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ; +C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ; +C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ; +C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ; +C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ; +C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ; +C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ; +EndCharMetrics +StartKernData +StartKernPairs 283 + +KPX A y -74 +KPX A w -74 +KPX A v -74 +KPX A u -30 +KPX A quoteright -74 +KPX A quotedblright 0 +KPX A p 0 +KPX A Y -70 +KPX A W -100 +KPX A V -95 +KPX A U -50 +KPX A T -55 +KPX A Q -55 +KPX A O -50 +KPX A G -60 +KPX A C -65 + +KPX B period 0 +KPX B comma 0 +KPX B U -10 +KPX B A -25 + +KPX D period 0 +KPX D comma 0 +KPX D Y -50 +KPX D W -40 +KPX D V -50 +KPX D A -25 + +KPX F r -50 +KPX F period -129 +KPX F o -70 +KPX F i -40 +KPX F e -100 +KPX F comma -129 +KPX F a -95 +KPX F A -100 + +KPX G period 0 +KPX G comma 0 + +KPX J u -40 +KPX J period -10 +KPX J o -40 +KPX J e -40 +KPX J comma -10 +KPX J a -40 +KPX J A -25 + +KPX K y -20 +KPX K u -20 +KPX K o -25 +KPX K e -25 +KPX K O -30 + +KPX L y -37 +KPX L quoteright -55 +KPX L quotedblright 0 +KPX L Y -37 +KPX L W -37 +KPX L V -37 +KPX L T -18 + +KPX N period 0 +KPX N comma 0 +KPX N A -30 + +KPX O period 0 +KPX O comma 0 +KPX O Y -50 +KPX O X -40 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -40 + +KPX P period -129 +KPX P o -55 +KPX P e -50 +KPX P comma -129 +KPX P a -40 +KPX P A -85 + +KPX Q period 0 +KPX Q comma 0 +KPX Q U -10 + +KPX R Y -18 +KPX R W -18 +KPX R V -18 +KPX R U -40 +KPX R T -30 +KPX R O -40 + +KPX S period 0 +KPX S comma 0 + +KPX T y -37 +KPX T w -37 +KPX T u -37 +KPX T semicolon -74 +KPX T r -37 +KPX T period -92 +KPX T o -95 +KPX T i -37 +KPX T hyphen -92 +KPX T h 0 +KPX T e -92 +KPX T comma -92 +KPX T colon -74 +KPX T a -92 +KPX T O -18 +KPX T A -55 + +KPX U period 0 +KPX U comma 0 +KPX U A -45 + +KPX V u -55 +KPX V semicolon -74 +KPX V period -129 +KPX V o -111 +KPX V i -55 +KPX V hyphen -70 +KPX V e -111 +KPX V comma -129 +KPX V colon -74 +KPX V a -111 +KPX V O -30 +KPX V G -10 +KPX V A -85 + +KPX W y -55 +KPX W u -55 +KPX W semicolon -55 +KPX W period -74 +KPX W o -80 +KPX W i -37 +KPX W hyphen -50 +KPX W h 0 +KPX W e -90 +KPX W comma -74 +KPX W colon -55 +KPX W a -85 +KPX W O -15 +KPX W A -74 + +KPX Y u -92 +KPX Y semicolon -92 +KPX Y period -74 +KPX Y o -111 +KPX Y i -55 +KPX Y hyphen -92 +KPX Y e -111 +KPX Y comma -92 +KPX Y colon -92 +KPX Y a -92 +KPX Y O -25 +KPX Y A -74 + +KPX a y 0 +KPX a w 0 +KPX a v 0 +KPX a t 0 +KPX a p 0 +KPX a g 0 +KPX a b 0 + +KPX b y 0 +KPX b v 0 +KPX b u -20 +KPX b period -40 +KPX b l 0 +KPX b comma 0 +KPX b b -10 + +KPX c y 0 +KPX c period 0 +KPX c l 0 +KPX c k -10 +KPX c h -10 +KPX c comma 0 + +KPX colon space 0 + +KPX comma space 0 +KPX comma quoteright -95 +KPX comma quotedblright -95 + +KPX d y 0 +KPX d w 0 +KPX d v 0 +KPX d period 0 +KPX d d 0 +KPX d comma 0 + +KPX e y 0 +KPX e x 0 +KPX e w 0 +KPX e v 0 +KPX e period 0 +KPX e p 0 +KPX e g 0 +KPX e comma 0 +KPX e b -10 + +KPX f quoteright 55 +KPX f quotedblright 0 +KPX f period -10 +KPX f o -10 +KPX f l 0 +KPX f i 0 +KPX f f -18 +KPX f e -10 +KPX f dotlessi -30 +KPX f comma -10 +KPX f a 0 + +KPX g y 0 +KPX g r 0 +KPX g period 0 +KPX g o 0 +KPX g i 0 +KPX g g 0 +KPX g e 0 +KPX g comma 0 +KPX g a 0 + +KPX h y 0 + +KPX i v 0 + +KPX k y 0 +KPX k o -10 +KPX k e -30 + +KPX l y 0 +KPX l w 0 + +KPX m y 0 +KPX m u 0 + +KPX n y 0 +KPX n v -40 +KPX n u 0 + +KPX o y -10 +KPX o x -10 +KPX o w -25 +KPX o v -15 +KPX o g 0 + +KPX p y 0 + +KPX period quoteright -95 +KPX period quotedblright -95 + +KPX quotedblleft quoteleft 0 +KPX quotedblleft A 0 + +KPX quotedblright space 0 + +KPX quoteleft quoteleft -74 +KPX quoteleft A 0 + +KPX quoteright v -15 +KPX quoteright t -37 +KPX quoteright space -74 +KPX quoteright s -74 +KPX quoteright r -15 +KPX quoteright quoteright -74 +KPX quoteright quotedblright 0 +KPX quoteright l 0 +KPX quoteright d -15 + +KPX r y 0 +KPX r v 0 +KPX r u 0 +KPX r t 0 +KPX r s 0 +KPX r r 0 +KPX r q 0 +KPX r period -65 +KPX r p 0 +KPX r o 0 +KPX r n 0 +KPX r m 0 +KPX r l 0 +KPX r k 0 +KPX r i 0 +KPX r hyphen 0 +KPX r g 0 +KPX r e 0 +KPX r d 0 +KPX r comma -65 +KPX r c 0 +KPX r a 0 + +KPX s w 0 + +KPX space quoteleft 0 +KPX space quotedblleft 0 +KPX space Y -70 +KPX space W -70 +KPX space V -70 +KPX space T 0 +KPX space A -37 + +KPX v period -37 +KPX v o -15 +KPX v e -15 +KPX v comma -37 +KPX v a 0 + +KPX w period -37 +KPX w o -15 +KPX w h 0 +KPX w e -10 +KPX w comma -37 +KPX w a -10 + +KPX x e -10 + +KPX y period -37 +KPX y o 0 +KPX y e 0 +KPX y comma -37 +KPX y a 0 + +KPX z o 0 +KPX z e 0 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 172 207 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 207 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 207 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 172 207 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 157 192 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 207 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 172 207 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 187 207 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 187 207 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 172 207 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 33 207 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 53 207 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 48 207 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 33 207 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 207 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 207 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 207 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 207 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 207 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 207 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 207 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 210 207 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 230 207 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 230 207 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 200 207 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 154 207 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 207 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 207 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 74 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 74 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 46 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -42 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -37 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -37 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 97 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 69 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 74 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 97 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 102 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 41 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 13 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmr8a.afm new file mode 100644 index 00000000..e5092b5c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmr8a.afm @@ -0,0 +1,648 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Mar 20 12:15:44 1990 +Comment UniqueID 28416 +Comment VMusage 30487 37379 +FontName Times-Roman +FullName Times Roman +FamilyName Times +Weight Roman +ItalicAngle 0 +IsFixedPitch false +FontBBox -168 -218 1000 898 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 662 +XHeight 450 +Ascender 683 +Descender -217 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ; +C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ; +C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ; +C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ; +C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ; +C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ; +C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ; +C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ; +C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ; +C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ; +C 43 ; WX 564 ; N plus ; B 30 0 534 506 ; +C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ; +C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ; +C 46 ; WX 250 ; N period ; B 70 -11 181 100 ; +C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ; +C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ; +C 49 ; WX 500 ; N one ; B 111 0 394 676 ; +C 50 ; WX 500 ; N two ; B 30 0 475 676 ; +C 51 ; WX 500 ; N three ; B 43 -14 431 676 ; +C 52 ; WX 500 ; N four ; B 12 0 472 676 ; +C 53 ; WX 500 ; N five ; B 32 -14 438 688 ; +C 54 ; WX 500 ; N six ; B 34 -14 468 684 ; +C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ; +C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ; +C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ; +C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ; +C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ; +C 60 ; WX 564 ; N less ; B 28 -8 536 514 ; +C 61 ; WX 564 ; N equal ; B 30 120 534 386 ; +C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ; +C 63 ; WX 444 ; N question ; B 68 -8 414 676 ; +C 64 ; WX 921 ; N at ; B 116 -14 809 676 ; +C 65 ; WX 722 ; N A ; B 15 0 706 674 ; +C 66 ; WX 667 ; N B ; B 17 0 593 662 ; +C 67 ; WX 667 ; N C ; B 28 -14 633 676 ; +C 68 ; WX 722 ; N D ; B 16 0 685 662 ; +C 69 ; WX 611 ; N E ; B 12 0 597 662 ; +C 70 ; WX 556 ; N F ; B 12 0 546 662 ; +C 71 ; WX 722 ; N G ; B 32 -14 709 676 ; +C 72 ; WX 722 ; N H ; B 19 0 702 662 ; +C 73 ; WX 333 ; N I ; B 18 0 315 662 ; +C 74 ; WX 389 ; N J ; B 10 -14 370 662 ; +C 75 ; WX 722 ; N K ; B 34 0 723 662 ; +C 76 ; WX 611 ; N L ; B 12 0 598 662 ; +C 77 ; WX 889 ; N M ; B 12 0 863 662 ; +C 78 ; WX 722 ; N N ; B 12 -11 707 662 ; +C 79 ; WX 722 ; N O ; B 34 -14 688 676 ; +C 80 ; WX 556 ; N P ; B 16 0 542 662 ; +C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ; +C 82 ; WX 667 ; N R ; B 17 0 659 662 ; +C 83 ; WX 556 ; N S ; B 42 -14 491 676 ; +C 84 ; WX 611 ; N T ; B 17 0 593 662 ; +C 85 ; WX 722 ; N U ; B 14 -14 705 662 ; +C 86 ; WX 722 ; N V ; B 16 -11 697 662 ; +C 87 ; WX 944 ; N W ; B 5 -11 932 662 ; +C 88 ; WX 722 ; N X ; B 10 0 704 662 ; +C 89 ; WX 722 ; N Y ; B 22 0 703 662 ; +C 90 ; WX 611 ; N Z ; B 9 0 597 662 ; +C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ; +C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ; +C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ; +C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ; +C 97 ; WX 444 ; N a ; B 37 -10 442 460 ; +C 98 ; WX 500 ; N b ; B 3 -10 468 683 ; +C 99 ; WX 444 ; N c ; B 25 -10 412 460 ; +C 100 ; WX 500 ; N d ; B 27 -10 491 683 ; +C 101 ; WX 444 ; N e ; B 25 -10 424 460 ; +C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -218 470 460 ; +C 104 ; WX 500 ; N h ; B 9 0 487 683 ; +C 105 ; WX 278 ; N i ; B 16 0 253 683 ; +C 106 ; WX 278 ; N j ; B -70 -218 194 683 ; +C 107 ; WX 500 ; N k ; B 7 0 505 683 ; +C 108 ; WX 278 ; N l ; B 19 0 257 683 ; +C 109 ; WX 778 ; N m ; B 16 0 775 460 ; +C 110 ; WX 500 ; N n ; B 16 0 485 460 ; +C 111 ; WX 500 ; N o ; B 29 -10 470 460 ; +C 112 ; WX 500 ; N p ; B 5 -217 470 460 ; +C 113 ; WX 500 ; N q ; B 24 -217 488 460 ; +C 114 ; WX 333 ; N r ; B 5 0 335 460 ; +C 115 ; WX 389 ; N s ; B 51 -10 348 460 ; +C 116 ; WX 278 ; N t ; B 13 -10 279 579 ; +C 117 ; WX 500 ; N u ; B 9 -10 479 450 ; +C 118 ; WX 500 ; N v ; B 19 -14 477 450 ; +C 119 ; WX 722 ; N w ; B 21 -14 694 450 ; +C 120 ; WX 500 ; N x ; B 17 0 479 450 ; +C 121 ; WX 500 ; N y ; B 14 -218 475 450 ; +C 122 ; WX 444 ; N z ; B 27 0 418 450 ; +C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ; +C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ; +C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ; +C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ; +C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ; +C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ; +C 165 ; WX 500 ; N yen ; B -53 0 512 662 ; +C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ; +C 167 ; WX 500 ; N section ; B 70 -148 426 676 ; +C 168 ; WX 500 ; N currency ; B -22 58 522 602 ; +C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ; +C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ; +C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ; +C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ; +C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ; +C 174 ; WX 556 ; N fi ; B 31 0 521 683 ; +C 175 ; WX 556 ; N fl ; B 32 0 521 683 ; +C 177 ; WX 500 ; N endash ; B 0 201 500 250 ; +C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ; +C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ; +C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ; +C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ; +C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ; +C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ; +C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ; +C 193 ; WX 333 ; N grave ; B 19 507 242 678 ; +C 194 ; WX 333 ; N acute ; B 93 507 317 678 ; +C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ; +C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ; +C 197 ; WX 333 ; N macron ; B 11 547 322 601 ; +C 198 ; WX 333 ; N breve ; B 26 507 307 664 ; +C 199 ; WX 333 ; N dotaccent ; B 118 523 216 623 ; +C 200 ; WX 333 ; N dieresis ; B 18 523 315 623 ; +C 202 ; WX 333 ; N ring ; B 67 512 266 711 ; +C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ; +C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ; +C 207 ; WX 333 ; N caron ; B 11 507 322 674 ; +C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ; +C 225 ; WX 889 ; N AE ; B 0 0 863 662 ; +C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ; +C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ; +C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ; +C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ; +C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ; +C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ; +C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ; +C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ; +C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ; +C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ; +C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ; +C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ; +C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ; +C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ; +C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ; +C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ; +C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ; +C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ; +C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ; +C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ; +C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ; +C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ; +C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ; +C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ; +C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ; +C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ; +C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ; +C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ; +C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ; +C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ; +C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ; +C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ; +C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ; +C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ; +C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ; +C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ; +C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ; +C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ; +C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ; +C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ; +C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ; +C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ; +C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ; +C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ; +C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ; +C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ; +C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ; +C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ; +C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ; +C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ; +C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ; +C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ; +C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ; +C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ; +C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ; +C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ; +C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ; +C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ; +C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ; +C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ; +C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ; +C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ; +C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ; +C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ; +C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ; +C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ; +C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ; +C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ; +C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ; +C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ; +C -1 ; WX 564 ; N minus ; B 30 220 534 286 ; +C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ; +C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ; +C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ; +C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ; +C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ; +C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ; +C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ; +C -1 ; WX 400 ; N degree ; B 57 390 343 676 ; +C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ; +C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ; +C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ; +C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ; +C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ; +C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ; +C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ; +C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ; +EndCharMetrics +StartKernData +StartKernPairs 283 + +KPX A y -92 +KPX A w -92 +KPX A v -74 +KPX A u 0 +KPX A quoteright -111 +KPX A quotedblright 0 +KPX A p 0 +KPX A Y -105 +KPX A W -90 +KPX A V -135 +KPX A U -55 +KPX A T -111 +KPX A Q -55 +KPX A O -55 +KPX A G -40 +KPX A C -40 + +KPX B period 0 +KPX B comma 0 +KPX B U -10 +KPX B A -35 + +KPX D period 0 +KPX D comma 0 +KPX D Y -55 +KPX D W -30 +KPX D V -40 +KPX D A -40 + +KPX F r 0 +KPX F period -80 +KPX F o -15 +KPX F i 0 +KPX F e 0 +KPX F comma -80 +KPX F a -15 +KPX F A -74 + +KPX G period 0 +KPX G comma 0 + +KPX J u 0 +KPX J period 0 +KPX J o 0 +KPX J e 0 +KPX J comma 0 +KPX J a 0 +KPX J A -60 + +KPX K y -25 +KPX K u -15 +KPX K o -35 +KPX K e -25 +KPX K O -30 + +KPX L y -55 +KPX L quoteright -92 +KPX L quotedblright 0 +KPX L Y -100 +KPX L W -74 +KPX L V -100 +KPX L T -92 + +KPX N period 0 +KPX N comma 0 +KPX N A -35 + +KPX O period 0 +KPX O comma 0 +KPX O Y -50 +KPX O X -40 +KPX O W -35 +KPX O V -50 +KPX O T -40 +KPX O A -35 + +KPX P period -111 +KPX P o 0 +KPX P e 0 +KPX P comma -111 +KPX P a -15 +KPX P A -92 + +KPX Q period 0 +KPX Q comma 0 +KPX Q U -10 + +KPX R Y -65 +KPX R W -55 +KPX R V -80 +KPX R U -40 +KPX R T -60 +KPX R O -40 + +KPX S period 0 +KPX S comma 0 + +KPX T y -80 +KPX T w -80 +KPX T u -45 +KPX T semicolon -55 +KPX T r -35 +KPX T period -74 +KPX T o -80 +KPX T i -35 +KPX T hyphen -92 +KPX T h 0 +KPX T e -70 +KPX T comma -74 +KPX T colon -50 +KPX T a -80 +KPX T O -18 +KPX T A -93 + +KPX U period 0 +KPX U comma 0 +KPX U A -40 + +KPX V u -75 +KPX V semicolon -74 +KPX V period -129 +KPX V o -129 +KPX V i -60 +KPX V hyphen -100 +KPX V e -111 +KPX V comma -129 +KPX V colon -74 +KPX V a -111 +KPX V O -40 +KPX V G -15 +KPX V A -135 + +KPX W y -73 +KPX W u -50 +KPX W semicolon -37 +KPX W period -92 +KPX W o -80 +KPX W i -40 +KPX W hyphen -65 +KPX W h 0 +KPX W e -80 +KPX W comma -92 +KPX W colon -37 +KPX W a -80 +KPX W O -10 +KPX W A -120 + +KPX Y u -111 +KPX Y semicolon -92 +KPX Y period -129 +KPX Y o -110 +KPX Y i -55 +KPX Y hyphen -111 +KPX Y e -100 +KPX Y comma -129 +KPX Y colon -92 +KPX Y a -100 +KPX Y O -30 +KPX Y A -120 + +KPX a y 0 +KPX a w -15 +KPX a v -20 +KPX a t 0 +KPX a p 0 +KPX a g 0 +KPX a b 0 + +KPX b y 0 +KPX b v -15 +KPX b u -20 +KPX b period -40 +KPX b l 0 +KPX b comma 0 +KPX b b 0 + +KPX c y -15 +KPX c period 0 +KPX c l 0 +KPX c k 0 +KPX c h 0 +KPX c comma 0 + +KPX colon space 0 + +KPX comma space 0 +KPX comma quoteright -70 +KPX comma quotedblright -70 + +KPX d y 0 +KPX d w 0 +KPX d v 0 +KPX d period 0 +KPX d d 0 +KPX d comma 0 + +KPX e y -15 +KPX e x -15 +KPX e w -25 +KPX e v -25 +KPX e period 0 +KPX e p 0 +KPX e g -15 +KPX e comma 0 +KPX e b 0 + +KPX f quoteright 55 +KPX f quotedblright 0 +KPX f period 0 +KPX f o 0 +KPX f l 0 +KPX f i -20 +KPX f f -25 +KPX f e 0 +KPX f dotlessi -50 +KPX f comma 0 +KPX f a -10 + +KPX g y 0 +KPX g r 0 +KPX g period 0 +KPX g o 0 +KPX g i 0 +KPX g g 0 +KPX g e 0 +KPX g comma 0 +KPX g a -5 + +KPX h y -5 + +KPX i v -25 + +KPX k y -15 +KPX k o -10 +KPX k e -10 + +KPX l y 0 +KPX l w -10 + +KPX m y 0 +KPX m u 0 + +KPX n y -15 +KPX n v -40 +KPX n u 0 + +KPX o y -10 +KPX o x 0 +KPX o w -25 +KPX o v -15 +KPX o g 0 + +KPX p y -10 + +KPX period quoteright -70 +KPX period quotedblright -70 + +KPX quotedblleft quoteleft 0 +KPX quotedblleft A -80 + +KPX quotedblright space 0 + +KPX quoteleft quoteleft -74 +KPX quoteleft A -80 + +KPX quoteright v -50 +KPX quoteright t -18 +KPX quoteright space -74 +KPX quoteright s -55 +KPX quoteright r -50 +KPX quoteright quoteright -74 +KPX quoteright quotedblright 0 +KPX quoteright l -10 +KPX quoteright d -50 + +KPX r y 0 +KPX r v 0 +KPX r u 0 +KPX r t 0 +KPX r s 0 +KPX r r 0 +KPX r q 0 +KPX r period -55 +KPX r p 0 +KPX r o 0 +KPX r n 0 +KPX r m 0 +KPX r l 0 +KPX r k 0 +KPX r i 0 +KPX r hyphen -20 +KPX r g -18 +KPX r e 0 +KPX r d 0 +KPX r comma -40 +KPX r c 0 +KPX r a 0 + +KPX s w 0 + +KPX space quoteleft 0 +KPX space quotedblleft 0 +KPX space Y -90 +KPX space W -30 +KPX space V -50 +KPX space T -18 +KPX space A -55 + +KPX v period -65 +KPX v o -20 +KPX v e -15 +KPX v comma -65 +KPX v a -25 + +KPX w period -65 +KPX w o -10 +KPX w h 0 +KPX w e 0 +KPX w comma -65 +KPX w a -10 + +KPX x e -15 + +KPX y period -65 +KPX y o 0 +KPX y e 0 +KPX y comma -65 +KPX y a 0 + +KPX z o 0 +KPX z e 0 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 185 187 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 212 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 212 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 212 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 212 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 212 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 195 212 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 195 212 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 195 212 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 195 212 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 212 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 212 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 212 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 212 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 212 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 212 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 56 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmri8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmri8a.afm new file mode 100644 index 00000000..6d7a003b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/ptmri8a.afm @@ -0,0 +1,648 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Tue Mar 20 13:14:56 1990 +Comment UniqueID 28427 +Comment VMusage 32912 39804 +FontName Times-Italic +FullName Times Italic +FamilyName Times +Weight Medium +ItalicAngle -15.5 +IsFixedPitch false +FontBBox -169 -217 1010 883 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 653 +XHeight 441 +Ascender 683 +Descender -205 +StartCharMetrics 228 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ; +C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ; +C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ; +C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ; +C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ; +C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ; +C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ; +C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ; +C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ; +C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ; +C 43 ; WX 675 ; N plus ; B 86 0 590 506 ; +C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ; +C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ; +C 46 ; WX 250 ; N period ; B 27 -11 138 100 ; +C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ; +C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ; +C 49 ; WX 500 ; N one ; B 49 0 409 676 ; +C 50 ; WX 500 ; N two ; B 12 0 452 676 ; +C 51 ; WX 500 ; N three ; B 15 -7 465 676 ; +C 52 ; WX 500 ; N four ; B 1 0 479 676 ; +C 53 ; WX 500 ; N five ; B 15 -7 491 666 ; +C 54 ; WX 500 ; N six ; B 30 -7 521 686 ; +C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ; +C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ; +C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ; +C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ; +C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ; +C 60 ; WX 675 ; N less ; B 84 -8 592 514 ; +C 61 ; WX 675 ; N equal ; B 86 120 590 386 ; +C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ; +C 63 ; WX 500 ; N question ; B 132 -12 472 664 ; +C 64 ; WX 920 ; N at ; B 118 -18 806 666 ; +C 65 ; WX 611 ; N A ; B -51 0 564 668 ; +C 66 ; WX 611 ; N B ; B -8 0 588 653 ; +C 67 ; WX 667 ; N C ; B 66 -18 689 666 ; +C 68 ; WX 722 ; N D ; B -8 0 700 653 ; +C 69 ; WX 611 ; N E ; B -1 0 634 653 ; +C 70 ; WX 611 ; N F ; B 8 0 645 653 ; +C 71 ; WX 722 ; N G ; B 52 -18 722 666 ; +C 72 ; WX 722 ; N H ; B -8 0 767 653 ; +C 73 ; WX 333 ; N I ; B -8 0 384 653 ; +C 74 ; WX 444 ; N J ; B -6 -18 491 653 ; +C 75 ; WX 667 ; N K ; B 7 0 722 653 ; +C 76 ; WX 556 ; N L ; B -8 0 559 653 ; +C 77 ; WX 833 ; N M ; B -18 0 873 653 ; +C 78 ; WX 667 ; N N ; B -20 -15 727 653 ; +C 79 ; WX 722 ; N O ; B 60 -18 699 666 ; +C 80 ; WX 611 ; N P ; B 0 0 605 653 ; +C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ; +C 82 ; WX 611 ; N R ; B -13 0 588 653 ; +C 83 ; WX 500 ; N S ; B 17 -18 508 667 ; +C 84 ; WX 556 ; N T ; B 59 0 633 653 ; +C 85 ; WX 722 ; N U ; B 102 -18 765 653 ; +C 86 ; WX 611 ; N V ; B 76 -18 688 653 ; +C 87 ; WX 833 ; N W ; B 71 -18 906 653 ; +C 88 ; WX 611 ; N X ; B -29 0 655 653 ; +C 89 ; WX 556 ; N Y ; B 78 0 633 653 ; +C 90 ; WX 556 ; N Z ; B -6 0 606 653 ; +C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ; +C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ; +C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ; +C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ; +C 97 ; WX 500 ; N a ; B 17 -11 476 441 ; +C 98 ; WX 500 ; N b ; B 23 -11 473 683 ; +C 99 ; WX 444 ; N c ; B 30 -11 425 441 ; +C 100 ; WX 500 ; N d ; B 15 -13 527 683 ; +C 101 ; WX 444 ; N e ; B 31 -11 412 441 ; +C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 8 -206 472 441 ; +C 104 ; WX 500 ; N h ; B 19 -9 478 683 ; +C 105 ; WX 278 ; N i ; B 49 -11 264 654 ; +C 106 ; WX 278 ; N j ; B -124 -207 276 654 ; +C 107 ; WX 444 ; N k ; B 14 -11 461 683 ; +C 108 ; WX 278 ; N l ; B 41 -11 279 683 ; +C 109 ; WX 722 ; N m ; B 12 -9 704 441 ; +C 110 ; WX 500 ; N n ; B 14 -9 474 441 ; +C 111 ; WX 500 ; N o ; B 27 -11 468 441 ; +C 112 ; WX 500 ; N p ; B -75 -205 469 441 ; +C 113 ; WX 500 ; N q ; B 25 -209 483 441 ; +C 114 ; WX 389 ; N r ; B 45 0 412 441 ; +C 115 ; WX 389 ; N s ; B 16 -13 366 442 ; +C 116 ; WX 278 ; N t ; B 37 -11 296 546 ; +C 117 ; WX 500 ; N u ; B 42 -11 475 441 ; +C 118 ; WX 444 ; N v ; B 21 -18 426 441 ; +C 119 ; WX 667 ; N w ; B 16 -18 648 441 ; +C 120 ; WX 444 ; N x ; B -27 -11 447 441 ; +C 121 ; WX 444 ; N y ; B -24 -206 426 441 ; +C 122 ; WX 389 ; N z ; B -2 -81 380 428 ; +C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ; +C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ; +C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ; +C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ; +C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ; +C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ; +C 165 ; WX 500 ; N yen ; B 27 0 603 653 ; +C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ; +C 167 ; WX 500 ; N section ; B 53 -162 461 666 ; +C 168 ; WX 500 ; N currency ; B -22 53 522 597 ; +C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ; +C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ; +C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ; +C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ; +C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ; +C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ; +C 177 ; WX 500 ; N endash ; B -6 197 505 243 ; +C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ; +C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ; +C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ; +C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ; +C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ; +C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ; +C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ; +C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ; +C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ; +C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ; +C 193 ; WX 333 ; N grave ; B 121 492 311 664 ; +C 194 ; WX 333 ; N acute ; B 180 494 403 664 ; +C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ; +C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ; +C 197 ; WX 333 ; N macron ; B 99 532 411 583 ; +C 198 ; WX 333 ; N breve ; B 117 492 418 650 ; +C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ; +C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ; +C 202 ; WX 333 ; N ring ; B 155 492 355 691 ; +C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ; +C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ; +C 207 ; WX 333 ; N caron ; B 121 492 426 661 ; +C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ; +C 225 ; WX 889 ; N AE ; B -27 0 911 653 ; +C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ; +C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ; +C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ; +C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ; +C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ; +C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ; +C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ; +C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ; +C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ; +C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ; +C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ; +C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ; +C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ; +C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ; +C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ; +C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ; +C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ; +C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ; +C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ; +C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ; +C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ; +C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ; +C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ; +C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ; +C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ; +C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ; +C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ; +C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ; +C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ; +C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ; +C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ; +C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ; +C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ; +C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ; +C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ; +C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ; +C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ; +C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ; +C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ; +C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ; +C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ; +C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ; +C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ; +C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ; +C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ; +C -1 ; WX 333 ; N Iacute ; B -8 0 413 876 ; +C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ; +C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ; +C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ; +C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ; +C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ; +C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ; +C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ; +C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ; +C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ; +C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ; +C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ; +C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ; +C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ; +C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ; +C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ; +C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ; +C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ; +C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ; +C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ; +C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ; +C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ; +C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ; +C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ; +C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ; +C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ; +C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ; +C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ; +C -1 ; WX 675 ; N minus ; B 86 220 590 286 ; +C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ; +C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ; +C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ; +C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ; +C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ; +C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ; +C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ; +C -1 ; WX 400 ; N degree ; B 101 390 387 676 ; +C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ; +C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ; +C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ; +C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ; +C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ; +C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ; +C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ; +C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ; +EndCharMetrics +StartKernData +StartKernPairs 283 + +KPX A y -55 +KPX A w -55 +KPX A v -55 +KPX A u -20 +KPX A quoteright -37 +KPX A quotedblright 0 +KPX A p 0 +KPX A Y -55 +KPX A W -95 +KPX A V -105 +KPX A U -50 +KPX A T -37 +KPX A Q -40 +KPX A O -40 +KPX A G -35 +KPX A C -30 + +KPX B period 0 +KPX B comma 0 +KPX B U -10 +KPX B A -25 + +KPX D period 0 +KPX D comma 0 +KPX D Y -40 +KPX D W -40 +KPX D V -40 +KPX D A -35 + +KPX F r -55 +KPX F period -135 +KPX F o -105 +KPX F i -45 +KPX F e -75 +KPX F comma -135 +KPX F a -75 +KPX F A -115 + +KPX G period 0 +KPX G comma 0 + +KPX J u -35 +KPX J period -25 +KPX J o -25 +KPX J e -25 +KPX J comma -25 +KPX J a -35 +KPX J A -40 + +KPX K y -40 +KPX K u -40 +KPX K o -40 +KPX K e -35 +KPX K O -50 + +KPX L y -30 +KPX L quoteright -37 +KPX L quotedblright 0 +KPX L Y -20 +KPX L W -55 +KPX L V -55 +KPX L T -20 + +KPX N period 0 +KPX N comma 0 +KPX N A -27 + +KPX O period 0 +KPX O comma 0 +KPX O Y -50 +KPX O X -40 +KPX O W -50 +KPX O V -50 +KPX O T -40 +KPX O A -55 + +KPX P period -135 +KPX P o -80 +KPX P e -80 +KPX P comma -135 +KPX P a -80 +KPX P A -90 + +KPX Q period 0 +KPX Q comma 0 +KPX Q U -10 + +KPX R Y -18 +KPX R W -18 +KPX R V -18 +KPX R U -40 +KPX R T 0 +KPX R O -40 + +KPX S period 0 +KPX S comma 0 + +KPX T y -74 +KPX T w -74 +KPX T u -55 +KPX T semicolon -65 +KPX T r -55 +KPX T period -74 +KPX T o -92 +KPX T i -55 +KPX T hyphen -74 +KPX T h 0 +KPX T e -92 +KPX T comma -74 +KPX T colon -55 +KPX T a -92 +KPX T O -18 +KPX T A -50 + +KPX U period -25 +KPX U comma -25 +KPX U A -40 + +KPX V u -74 +KPX V semicolon -74 +KPX V period -129 +KPX V o -111 +KPX V i -74 +KPX V hyphen -55 +KPX V e -111 +KPX V comma -129 +KPX V colon -65 +KPX V a -111 +KPX V O -30 +KPX V G 0 +KPX V A -60 + +KPX W y -70 +KPX W u -55 +KPX W semicolon -65 +KPX W period -92 +KPX W o -92 +KPX W i -55 +KPX W hyphen -37 +KPX W h 0 +KPX W e -92 +KPX W comma -92 +KPX W colon -65 +KPX W a -92 +KPX W O -25 +KPX W A -60 + +KPX Y u -92 +KPX Y semicolon -65 +KPX Y period -92 +KPX Y o -92 +KPX Y i -74 +KPX Y hyphen -74 +KPX Y e -92 +KPX Y comma -92 +KPX Y colon -65 +KPX Y a -92 +KPX Y O -15 +KPX Y A -50 + +KPX a y 0 +KPX a w 0 +KPX a v 0 +KPX a t 0 +KPX a p 0 +KPX a g -10 +KPX a b 0 + +KPX b y 0 +KPX b v 0 +KPX b u -20 +KPX b period -40 +KPX b l 0 +KPX b comma 0 +KPX b b 0 + +KPX c y 0 +KPX c period 0 +KPX c l 0 +KPX c k -20 +KPX c h -15 +KPX c comma 0 + +KPX colon space 0 + +KPX comma space 0 +KPX comma quoteright -140 +KPX comma quotedblright -140 + +KPX d y 0 +KPX d w 0 +KPX d v 0 +KPX d period 0 +KPX d d 0 +KPX d comma 0 + +KPX e y -30 +KPX e x -20 +KPX e w -15 +KPX e v -15 +KPX e period -15 +KPX e p 0 +KPX e g -40 +KPX e comma -10 +KPX e b 0 + +KPX f quoteright 92 +KPX f quotedblright 0 +KPX f period -15 +KPX f o 0 +KPX f l 0 +KPX f i -20 +KPX f f -18 +KPX f e 0 +KPX f dotlessi -60 +KPX f comma -10 +KPX f a 0 + +KPX g y 0 +KPX g r 0 +KPX g period -15 +KPX g o 0 +KPX g i 0 +KPX g g -10 +KPX g e -10 +KPX g comma -10 +KPX g a 0 + +KPX h y 0 + +KPX i v 0 + +KPX k y -10 +KPX k o -10 +KPX k e -10 + +KPX l y 0 +KPX l w 0 + +KPX m y 0 +KPX m u 0 + +KPX n y 0 +KPX n v -40 +KPX n u 0 + +KPX o y 0 +KPX o x 0 +KPX o w 0 +KPX o v -10 +KPX o g -10 + +KPX p y 0 + +KPX period quoteright -140 +KPX period quotedblright -140 + +KPX quotedblleft quoteleft 0 +KPX quotedblleft A 0 + +KPX quotedblright space 0 + +KPX quoteleft quoteleft -111 +KPX quoteleft A 0 + +KPX quoteright v -10 +KPX quoteright t -30 +KPX quoteright space -111 +KPX quoteright s -40 +KPX quoteright r -25 +KPX quoteright quoteright -111 +KPX quoteright quotedblright 0 +KPX quoteright l 0 +KPX quoteright d -25 + +KPX r y 0 +KPX r v 0 +KPX r u 0 +KPX r t 0 +KPX r s -10 +KPX r r 0 +KPX r q -37 +KPX r period -111 +KPX r p 0 +KPX r o -45 +KPX r n 0 +KPX r m 0 +KPX r l 0 +KPX r k 0 +KPX r i 0 +KPX r hyphen -20 +KPX r g -37 +KPX r e -37 +KPX r d -37 +KPX r comma -111 +KPX r c -37 +KPX r a -15 + +KPX s w 0 + +KPX space quoteleft 0 +KPX space quotedblleft 0 +KPX space Y -75 +KPX space W -40 +KPX space V -35 +KPX space T -18 +KPX space A -18 + +KPX v period -74 +KPX v o 0 +KPX v e 0 +KPX v comma -74 +KPX v a 0 + +KPX w period -74 +KPX w o 0 +KPX w h 0 +KPX w e 0 +KPX w comma -74 +KPX w a 0 + +KPX x e 0 + +KPX y period -55 +KPX y o 0 +KPX y e 0 +KPX y comma -55 +KPX y a 0 + +KPX z o 0 +KPX z e 0 +EndKernPairs +EndKernData +StartComposites 58 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 139 212 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 144 212 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 139 212 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 149 212 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 129 192 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 139 212 ; +CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 149 212 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 212 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 159 212 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 149 212 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 212 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 212 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 30 212 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 212 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 177 212 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 212 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 230 212 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 205 212 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 212 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 94 212 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 215 212 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 225 212 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 215 212 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 132 212 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 212 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 112 212 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; +CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -57 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -52 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 49 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 74 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde 69 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 74 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 74 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 74 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 36 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 8 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putb8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putb8a.afm new file mode 100644 index 00000000..2eaa540d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putb8a.afm @@ -0,0 +1,1005 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Fri Jan 17 15:08:52 1992 +Comment UniqueID 37705 +Comment VMusage 33078 39970 +FontName Utopia-Bold +FullName Utopia Bold +FamilyName Utopia +Weight Bold +ItalicAngle 0 +IsFixedPitch false +FontBBox -155 -250 1249 916 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.002 +Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 490 +Ascender 742 +Descender -230 +StartCharMetrics 228 +C 32 ; WX 210 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 47 -12 231 707 ; +C 34 ; WX 473 ; N quotedbl ; B 71 407 402 707 ; +C 35 ; WX 560 ; N numbersign ; B 14 0 547 668 ; +C 36 ; WX 560 ; N dollar ; B 38 -104 524 748 ; +C 37 ; WX 887 ; N percent ; B 40 -31 847 701 ; +C 38 ; WX 748 ; N ampersand ; B 45 -12 734 680 ; +C 39 ; WX 252 ; N quoteright ; B 40 387 212 707 ; +C 40 ; WX 365 ; N parenleft ; B 99 -135 344 699 ; +C 41 ; WX 365 ; N parenright ; B 21 -135 266 699 ; +C 42 ; WX 442 ; N asterisk ; B 40 315 402 707 ; +C 43 ; WX 600 ; N plus ; B 58 0 542 490 ; +C 44 ; WX 280 ; N comma ; B 40 -167 226 180 ; +C 45 ; WX 392 ; N hyphen ; B 65 203 328 298 ; +C 46 ; WX 280 ; N period ; B 48 -12 232 174 ; +C 47 ; WX 378 ; N slash ; B 34 -15 344 707 ; +C 48 ; WX 560 ; N zero ; B 31 -12 530 680 ; +C 49 ; WX 560 ; N one ; B 102 0 459 680 ; +C 50 ; WX 560 ; N two ; B 30 0 539 680 ; +C 51 ; WX 560 ; N three ; B 27 -12 519 680 ; +C 52 ; WX 560 ; N four ; B 19 0 533 668 ; +C 53 ; WX 560 ; N five ; B 43 -12 519 668 ; +C 54 ; WX 560 ; N six ; B 30 -12 537 680 ; +C 55 ; WX 560 ; N seven ; B 34 -12 530 668 ; +C 56 ; WX 560 ; N eight ; B 27 -12 533 680 ; +C 57 ; WX 560 ; N nine ; B 34 -12 523 680 ; +C 58 ; WX 280 ; N colon ; B 48 -12 232 490 ; +C 59 ; WX 280 ; N semicolon ; B 40 -167 232 490 ; +C 60 ; WX 600 ; N less ; B 61 5 539 493 ; +C 61 ; WX 600 ; N equal ; B 58 103 542 397 ; +C 62 ; WX 600 ; N greater ; B 61 5 539 493 ; +C 63 ; WX 456 ; N question ; B 20 -12 433 707 ; +C 64 ; WX 833 ; N at ; B 45 -15 797 707 ; +C 65 ; WX 644 ; N A ; B -28 0 663 692 ; +C 66 ; WX 683 ; N B ; B 33 0 645 692 ; +C 67 ; WX 689 ; N C ; B 42 -15 654 707 ; +C 68 ; WX 777 ; N D ; B 33 0 735 692 ; +C 69 ; WX 629 ; N E ; B 33 0 604 692 ; +C 70 ; WX 593 ; N F ; B 37 0 568 692 ; +C 71 ; WX 726 ; N G ; B 42 -15 709 707 ; +C 72 ; WX 807 ; N H ; B 33 0 774 692 ; +C 73 ; WX 384 ; N I ; B 33 0 351 692 ; +C 74 ; WX 386 ; N J ; B 6 -114 361 692 ; +C 75 ; WX 707 ; N K ; B 33 -6 719 692 ; +C 76 ; WX 585 ; N L ; B 33 0 584 692 ; +C 77 ; WX 918 ; N M ; B 23 0 885 692 ; +C 78 ; WX 739 ; N N ; B 25 0 719 692 ; +C 79 ; WX 768 ; N O ; B 42 -15 726 707 ; +C 80 ; WX 650 ; N P ; B 33 0 623 692 ; +C 81 ; WX 768 ; N Q ; B 42 -193 726 707 ; +C 82 ; WX 684 ; N R ; B 33 0 686 692 ; +C 83 ; WX 561 ; N S ; B 42 -15 533 707 ; +C 84 ; WX 624 ; N T ; B 15 0 609 692 ; +C 85 ; WX 786 ; N U ; B 29 -15 757 692 ; +C 86 ; WX 645 ; N V ; B -16 0 679 692 ; +C 87 ; WX 933 ; N W ; B -10 0 960 692 ; +C 88 ; WX 634 ; N X ; B -19 0 671 692 ; +C 89 ; WX 617 ; N Y ; B -12 0 655 692 ; +C 90 ; WX 614 ; N Z ; B 0 0 606 692 ; +C 91 ; WX 335 ; N bracketleft ; B 123 -128 308 692 ; +C 92 ; WX 379 ; N backslash ; B 34 -15 345 707 ; +C 93 ; WX 335 ; N bracketright ; B 27 -128 212 692 ; +C 94 ; WX 600 ; N asciicircum ; B 56 215 544 668 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 252 ; N quoteleft ; B 40 399 212 719 ; +C 97 ; WX 544 ; N a ; B 41 -12 561 502 ; +C 98 ; WX 605 ; N b ; B 15 -12 571 742 ; +C 99 ; WX 494 ; N c ; B 34 -12 484 502 ; +C 100 ; WX 605 ; N d ; B 34 -12 596 742 ; +C 101 ; WX 519 ; N e ; B 34 -12 505 502 ; +C 102 ; WX 342 ; N f ; B 27 0 421 742 ; L i fi ; L l fl ; +C 103 ; WX 533 ; N g ; B 25 -242 546 512 ; +C 104 ; WX 631 ; N h ; B 19 0 622 742 ; +C 105 ; WX 316 ; N i ; B 26 0 307 720 ; +C 106 ; WX 316 ; N j ; B -12 -232 260 720 ; +C 107 ; WX 582 ; N k ; B 19 0 595 742 ; +C 108 ; WX 309 ; N l ; B 19 0 300 742 ; +C 109 ; WX 948 ; N m ; B 26 0 939 502 ; +C 110 ; WX 638 ; N n ; B 26 0 629 502 ; +C 111 ; WX 585 ; N o ; B 34 -12 551 502 ; +C 112 ; WX 615 ; N p ; B 19 -230 581 502 ; +C 113 ; WX 597 ; N q ; B 34 -230 596 502 ; +C 114 ; WX 440 ; N r ; B 26 0 442 502 ; +C 115 ; WX 446 ; N s ; B 38 -12 425 502 ; +C 116 ; WX 370 ; N t ; B 32 -12 373 616 ; +C 117 ; WX 629 ; N u ; B 23 -12 620 502 ; +C 118 ; WX 520 ; N v ; B -8 0 546 490 ; +C 119 ; WX 774 ; N w ; B -10 0 802 490 ; +C 120 ; WX 522 ; N x ; B -15 0 550 490 ; +C 121 ; WX 524 ; N y ; B -12 -242 557 490 ; +C 122 ; WX 483 ; N z ; B -1 0 480 490 ; +C 123 ; WX 365 ; N braceleft ; B 74 -128 325 692 ; +C 124 ; WX 284 ; N bar ; B 94 -250 190 750 ; +C 125 ; WX 365 ; N braceright ; B 40 -128 291 692 ; +C 126 ; WX 600 ; N asciitilde ; B 50 158 551 339 ; +C 161 ; WX 278 ; N exclamdown ; B 47 -217 231 502 ; +C 162 ; WX 560 ; N cent ; B 39 -15 546 678 ; +C 163 ; WX 560 ; N sterling ; B 21 0 555 679 ; +C 164 ; WX 100 ; N fraction ; B -155 -27 255 695 ; +C 165 ; WX 560 ; N yen ; B 3 0 562 668 ; +C 166 ; WX 560 ; N florin ; B -40 -135 562 691 ; +C 167 ; WX 566 ; N section ; B 35 -115 531 707 ; +C 168 ; WX 560 ; N currency ; B 21 73 539 596 ; +C 169 ; WX 252 ; N quotesingle ; B 57 407 196 707 ; +C 170 ; WX 473 ; N quotedblleft ; B 40 399 433 719 ; +C 171 ; WX 487 ; N guillemotleft ; B 40 37 452 464 ; +C 172 ; WX 287 ; N guilsinglleft ; B 40 37 252 464 ; +C 173 ; WX 287 ; N guilsinglright ; B 35 37 247 464 ; +C 174 ; WX 639 ; N fi ; B 27 0 630 742 ; +C 175 ; WX 639 ; N fl ; B 27 0 630 742 ; +C 177 ; WX 500 ; N endash ; B 0 209 500 292 ; +C 178 ; WX 510 ; N dagger ; B 35 -125 475 707 ; +C 179 ; WX 486 ; N daggerdbl ; B 35 -119 451 707 ; +C 180 ; WX 280 ; N periodcentered ; B 48 156 232 342 ; +C 182 ; WX 552 ; N paragraph ; B 35 -101 527 692 ; +C 183 ; WX 455 ; N bullet ; B 50 174 405 529 ; +C 184 ; WX 252 ; N quotesinglbase ; B 40 -153 212 167 ; +C 185 ; WX 473 ; N quotedblbase ; B 40 -153 433 167 ; +C 186 ; WX 473 ; N quotedblright ; B 40 387 433 707 ; +C 187 ; WX 487 ; N guillemotright ; B 35 37 447 464 ; +C 188 ; WX 1000 ; N ellipsis ; B 75 -12 925 174 ; +C 189 ; WX 1289 ; N perthousand ; B 40 -31 1249 701 ; +C 191 ; WX 456 ; N questiondown ; B 23 -217 436 502 ; +C 193 ; WX 430 ; N grave ; B 40 511 312 740 ; +C 194 ; WX 430 ; N acute ; B 119 511 391 740 ; +C 195 ; WX 430 ; N circumflex ; B 28 520 402 747 ; +C 196 ; WX 430 ; N tilde ; B 2 553 427 706 ; +C 197 ; WX 430 ; N macron ; B 60 587 371 674 ; +C 198 ; WX 430 ; N breve ; B 56 556 375 716 ; +C 199 ; WX 430 ; N dotaccent ; B 136 561 294 710 ; +C 200 ; WX 430 ; N dieresis ; B 16 561 414 710 ; +C 202 ; WX 430 ; N ring ; B 96 540 334 762 ; +C 203 ; WX 430 ; N cedilla ; B 136 -246 335 0 ; +C 205 ; WX 430 ; N hungarumlaut ; B 64 521 446 751 ; +C 206 ; WX 430 ; N ogonek ; B 105 -246 325 0 ; +C 207 ; WX 430 ; N caron ; B 28 520 402 747 ; +C 208 ; WX 1000 ; N emdash ; B 0 209 1000 292 ; +C 225 ; WX 879 ; N AE ; B -77 0 854 692 ; +C 227 ; WX 405 ; N ordfeminine ; B 28 265 395 590 ; +C 232 ; WX 591 ; N Lslash ; B 30 0 590 692 ; +C 233 ; WX 768 ; N Oslash ; B 42 -61 726 747 ; +C 234 ; WX 1049 ; N OE ; B 42 0 1024 692 ; +C 235 ; WX 427 ; N ordmasculine ; B 28 265 399 590 ; +C 241 ; WX 806 ; N ae ; B 41 -12 792 502 ; +C 245 ; WX 316 ; N dotlessi ; B 26 0 307 502 ; +C 248 ; WX 321 ; N lslash ; B 16 0 332 742 ; +C 249 ; WX 585 ; N oslash ; B 34 -51 551 535 ; +C 250 ; WX 866 ; N oe ; B 34 -12 852 502 ; +C 251 ; WX 662 ; N germandbls ; B 29 -12 647 742 ; +C -1 ; WX 402 ; N onesuperior ; B 71 272 324 680 ; +C -1 ; WX 600 ; N minus ; B 58 210 542 290 ; +C -1 ; WX 396 ; N degree ; B 35 360 361 680 ; +C -1 ; WX 585 ; N oacute ; B 34 -12 551 755 ; +C -1 ; WX 768 ; N Odieresis ; B 42 -15 726 881 ; +C -1 ; WX 585 ; N odieresis ; B 34 -12 551 710 ; +C -1 ; WX 629 ; N Eacute ; B 33 0 604 904 ; +C -1 ; WX 629 ; N ucircumflex ; B 23 -12 620 747 ; +C -1 ; WX 900 ; N onequarter ; B 73 -27 814 695 ; +C -1 ; WX 600 ; N logicalnot ; B 58 95 542 397 ; +C -1 ; WX 629 ; N Ecircumflex ; B 33 0 604 905 ; +C -1 ; WX 900 ; N onehalf ; B 53 -27 849 695 ; +C -1 ; WX 768 ; N Otilde ; B 42 -15 726 876 ; +C -1 ; WX 629 ; N uacute ; B 23 -12 620 740 ; +C -1 ; WX 519 ; N eacute ; B 34 -12 505 755 ; +C -1 ; WX 316 ; N iacute ; B 26 0 369 740 ; +C -1 ; WX 629 ; N Egrave ; B 33 0 604 904 ; +C -1 ; WX 316 ; N icircumflex ; B -28 0 346 747 ; +C -1 ; WX 629 ; N mu ; B 23 -242 620 502 ; +C -1 ; WX 284 ; N brokenbar ; B 94 -175 190 675 ; +C -1 ; WX 609 ; N thorn ; B 13 -230 575 722 ; +C -1 ; WX 644 ; N Aring ; B -28 0 663 872 ; +C -1 ; WX 524 ; N yacute ; B -12 -242 557 740 ; +C -1 ; WX 617 ; N Ydieresis ; B -12 0 655 881 ; +C -1 ; WX 1090 ; N trademark ; B 38 277 1028 692 ; +C -1 ; WX 800 ; N registered ; B 36 -15 764 707 ; +C -1 ; WX 585 ; N ocircumflex ; B 34 -12 551 747 ; +C -1 ; WX 644 ; N Agrave ; B -28 0 663 904 ; +C -1 ; WX 561 ; N Scaron ; B 42 -15 533 916 ; +C -1 ; WX 786 ; N Ugrave ; B 29 -15 757 904 ; +C -1 ; WX 629 ; N Edieresis ; B 33 0 604 881 ; +C -1 ; WX 786 ; N Uacute ; B 29 -15 757 904 ; +C -1 ; WX 585 ; N otilde ; B 34 -12 551 706 ; +C -1 ; WX 638 ; N ntilde ; B 26 0 629 706 ; +C -1 ; WX 524 ; N ydieresis ; B -12 -242 557 710 ; +C -1 ; WX 644 ; N Aacute ; B -28 0 663 904 ; +C -1 ; WX 585 ; N eth ; B 34 -12 551 742 ; +C -1 ; WX 544 ; N acircumflex ; B 41 -12 561 747 ; +C -1 ; WX 544 ; N aring ; B 41 -12 561 762 ; +C -1 ; WX 768 ; N Ograve ; B 42 -15 726 904 ; +C -1 ; WX 494 ; N ccedilla ; B 34 -246 484 502 ; +C -1 ; WX 600 ; N multiply ; B 75 20 525 476 ; +C -1 ; WX 600 ; N divide ; B 58 6 542 494 ; +C -1 ; WX 402 ; N twosuperior ; B 29 272 382 680 ; +C -1 ; WX 739 ; N Ntilde ; B 25 0 719 876 ; +C -1 ; WX 629 ; N ugrave ; B 23 -12 620 740 ; +C -1 ; WX 786 ; N Ucircumflex ; B 29 -15 757 905 ; +C -1 ; WX 644 ; N Atilde ; B -28 0 663 876 ; +C -1 ; WX 483 ; N zcaron ; B -1 0 480 747 ; +C -1 ; WX 316 ; N idieresis ; B -37 0 361 710 ; +C -1 ; WX 644 ; N Acircumflex ; B -28 0 663 905 ; +C -1 ; WX 384 ; N Icircumflex ; B 4 0 380 905 ; +C -1 ; WX 617 ; N Yacute ; B -12 0 655 904 ; +C -1 ; WX 768 ; N Oacute ; B 42 -15 726 904 ; +C -1 ; WX 644 ; N Adieresis ; B -28 0 663 881 ; +C -1 ; WX 614 ; N Zcaron ; B 0 0 606 916 ; +C -1 ; WX 544 ; N agrave ; B 41 -12 561 755 ; +C -1 ; WX 402 ; N threesuperior ; B 30 265 368 680 ; +C -1 ; WX 585 ; N ograve ; B 34 -12 551 755 ; +C -1 ; WX 900 ; N threequarters ; B 40 -27 842 695 ; +C -1 ; WX 783 ; N Eth ; B 35 0 741 692 ; +C -1 ; WX 600 ; N plusminus ; B 58 0 542 549 ; +C -1 ; WX 629 ; N udieresis ; B 23 -12 620 710 ; +C -1 ; WX 519 ; N edieresis ; B 34 -12 505 710 ; +C -1 ; WX 544 ; N aacute ; B 41 -12 561 755 ; +C -1 ; WX 316 ; N igrave ; B -47 0 307 740 ; +C -1 ; WX 384 ; N Idieresis ; B -13 0 397 881 ; +C -1 ; WX 544 ; N adieresis ; B 41 -12 561 710 ; +C -1 ; WX 384 ; N Iacute ; B 33 0 423 904 ; +C -1 ; WX 800 ; N copyright ; B 36 -15 764 707 ; +C -1 ; WX 384 ; N Igrave ; B -31 0 351 904 ; +C -1 ; WX 689 ; N Ccedilla ; B 42 -246 654 707 ; +C -1 ; WX 446 ; N scaron ; B 38 -12 425 747 ; +C -1 ; WX 519 ; N egrave ; B 34 -12 505 755 ; +C -1 ; WX 768 ; N Ocircumflex ; B 42 -15 726 905 ; +C -1 ; WX 640 ; N Thorn ; B 33 0 622 692 ; +C -1 ; WX 544 ; N atilde ; B 41 -12 561 706 ; +C -1 ; WX 786 ; N Udieresis ; B 29 -15 757 881 ; +C -1 ; WX 519 ; N ecircumflex ; B 34 -12 505 747 ; +EndCharMetrics +StartKernData +StartKernPairs 685 + +KPX A z 25 +KPX A y -40 +KPX A w -42 +KPX A v -48 +KPX A u -18 +KPX A t -12 +KPX A s 6 +KPX A quoteright -110 +KPX A quotedblright -80 +KPX A q -6 +KPX A p -18 +KPX A o -12 +KPX A e -6 +KPX A d -12 +KPX A c -12 +KPX A b -12 +KPX A a -6 +KPX A Y -64 +KPX A X -18 +KPX A W -54 +KPX A V -70 +KPX A U -40 +KPX A T -58 +KPX A Q -18 +KPX A O -18 +KPX A G -18 +KPX A C -18 + +KPX B y -18 +KPX B u -12 +KPX B r -12 +KPX B o -6 +KPX B l -15 +KPX B k -15 +KPX B i -12 +KPX B h -15 +KPX B e -6 +KPX B b -10 +KPX B a -12 +KPX B W -20 +KPX B V -20 +KPX B U -25 +KPX B T -20 + +KPX C z -5 +KPX C y -24 +KPX C u -18 +KPX C r -6 +KPX C o -12 +KPX C e -12 +KPX C a -16 +KPX C Q -6 +KPX C O -6 +KPX C G -6 +KPX C C -6 + +KPX D u -12 +KPX D r -12 +KPX D period -40 +KPX D o -5 +KPX D i -12 +KPX D h -18 +KPX D e -5 +KPX D comma -40 +KPX D a -15 +KPX D Y -60 +KPX D W -40 +KPX D V -40 + +KPX E y -30 +KPX E w -24 +KPX E v -24 +KPX E u -12 +KPX E t -18 +KPX E s -12 +KPX E r -4 +KPX E q -6 +KPX E period 10 +KPX E p -18 +KPX E o -6 +KPX E n -4 +KPX E m -4 +KPX E j -6 +KPX E i -6 +KPX E g -6 +KPX E e -6 +KPX E d -6 +KPX E comma 10 +KPX E c -6 +KPX E b -5 +KPX E a -4 +KPX E Y -6 +KPX E W -6 +KPX E V -6 + +KPX F y -18 +KPX F u -12 +KPX F r -36 +KPX F quoteright 20 +KPX F quotedblright 20 +KPX F period -150 +KPX F o -36 +KPX F l -12 +KPX F i -22 +KPX F e -36 +KPX F comma -150 +KPX F a -48 +KPX F A -60 + +KPX G y -12 +KPX G u -12 +KPX G r -18 +KPX G quotedblright -20 +KPX G n -18 +KPX G l -6 +KPX G i -12 +KPX G h -12 +KPX G a -12 + +KPX H y -24 +KPX H u -26 +KPX H o -30 +KPX H i -18 +KPX H e -30 +KPX H a -25 + +KPX I z -6 +KPX I y -6 +KPX I x -6 +KPX I w -18 +KPX I v -24 +KPX I u -26 +KPX I t -24 +KPX I s -18 +KPX I r -12 +KPX I p -26 +KPX I o -30 +KPX I n -18 +KPX I m -18 +KPX I l -6 +KPX I k -6 +KPX I h -6 +KPX I g -6 +KPX I f -6 +KPX I e -30 +KPX I d -30 +KPX I c -30 +KPX I b -6 +KPX I a -24 + +KPX J y -20 +KPX J u -36 +KPX J o -35 +KPX J i -20 +KPX J e -35 +KPX J bracketright 15 +KPX J braceright 15 +KPX J a -36 + +KPX K y -70 +KPX K w -60 +KPX K v -80 +KPX K u -42 +KPX K o -30 +KPX K l 10 +KPX K i 6 +KPX K h 10 +KPX K e -18 +KPX K a -6 +KPX K Q -36 +KPX K O -36 +KPX K G -36 +KPX K C -36 +KPX K A 20 + +KPX L y -52 +KPX L w -58 +KPX L u -12 +KPX L quoteright -130 +KPX L quotedblright -130 +KPX L l 6 +KPX L j -6 +KPX L Y -70 +KPX L W -78 +KPX L V -95 +KPX L U -32 +KPX L T -80 +KPX L Q -12 +KPX L O -12 +KPX L G -12 +KPX L C -12 +KPX L A 30 + +KPX M y -24 +KPX M u -36 +KPX M o -30 +KPX M n -6 +KPX M j -12 +KPX M i -12 +KPX M e -30 +KPX M d -30 +KPX M c -30 +KPX M a -25 + +KPX N y -24 +KPX N u -30 +KPX N o -30 +KPX N i -24 +KPX N e -30 +KPX N a -30 + +KPX O z -6 +KPX O u -6 +KPX O t -6 +KPX O s -6 +KPX O r -10 +KPX O q -6 +KPX O period -40 +KPX O p -10 +KPX O o -6 +KPX O n -10 +KPX O m -10 +KPX O l -15 +KPX O k -15 +KPX O i -6 +KPX O h -15 +KPX O g -6 +KPX O e -6 +KPX O d -6 +KPX O comma -40 +KPX O c -6 +KPX O b -15 +KPX O a -12 +KPX O Y -50 +KPX O X -40 +KPX O W -35 +KPX O V -35 +KPX O T -40 +KPX O A -30 + +KPX P y 10 +KPX P u -18 +KPX P t -6 +KPX P s -30 +KPX P r -12 +KPX P quoteright 20 +KPX P quotedblright 20 +KPX P period -200 +KPX P o -36 +KPX P n -12 +KPX P l -15 +KPX P i -6 +KPX P hyphen -30 +KPX P h -15 +KPX P e -36 +KPX P comma -200 +KPX P a -36 +KPX P I -20 +KPX P H -20 +KPX P E -20 +KPX P A -85 + +KPX Q u -6 +KPX Q a -18 +KPX Q Y -50 +KPX Q X -40 +KPX Q W -35 +KPX Q V -35 +KPX Q U -25 +KPX Q T -40 +KPX Q A -30 + +KPX R y -20 +KPX R u -12 +KPX R t -25 +KPX R quoteright -10 +KPX R quotedblright -10 +KPX R o -12 +KPX R e -18 +KPX R a -6 +KPX R Y -32 +KPX R X 20 +KPX R W -18 +KPX R V -26 +KPX R U -30 +KPX R T -20 +KPX R Q -10 +KPX R O -10 +KPX R G -10 +KPX R C -10 + +KPX S y -35 +KPX S w -30 +KPX S v -40 +KPX S u -24 +KPX S t -24 +KPX S r -10 +KPX S quoteright -15 +KPX S quotedblright -15 +KPX S p -24 +KPX S n -24 +KPX S m -24 +KPX S l -18 +KPX S k -24 +KPX S j -30 +KPX S i -12 +KPX S h -12 +KPX S a -18 + +KPX T z -64 +KPX T y -74 +KPX T w -72 +KPX T u -74 +KPX T semicolon -50 +KPX T s -82 +KPX T r -74 +KPX T quoteright 24 +KPX T quotedblright 24 +KPX T period -95 +KPX T parenright 40 +KPX T o -90 +KPX T m -72 +KPX T i -28 +KPX T hyphen -110 +KPX T endash -40 +KPX T emdash -60 +KPX T e -80 +KPX T comma -95 +KPX T bracketright 40 +KPX T braceright 30 +KPX T a -90 +KPX T Y 12 +KPX T X 10 +KPX T W 15 +KPX T V 6 +KPX T T 30 +KPX T S -12 +KPX T Q -25 +KPX T O -25 +KPX T G -25 +KPX T C -25 +KPX T A -52 + +KPX U z -35 +KPX U y -30 +KPX U x -30 +KPX U v -30 +KPX U t -36 +KPX U s -45 +KPX U r -50 +KPX U p -50 +KPX U n -50 +KPX U m -50 +KPX U l -12 +KPX U k -12 +KPX U i -22 +KPX U h -6 +KPX U g -40 +KPX U f -20 +KPX U d -40 +KPX U c -40 +KPX U b -12 +KPX U a -50 +KPX U A -50 + +KPX V y -36 +KPX V u -50 +KPX V semicolon -45 +KPX V r -75 +KPX V quoteright 50 +KPX V quotedblright 36 +KPX V period -135 +KPX V parenright 80 +KPX V o -70 +KPX V i 20 +KPX V hyphen -90 +KPX V emdash -20 +KPX V e -70 +KPX V comma -135 +KPX V colon -45 +KPX V bracketright 80 +KPX V braceright 80 +KPX V a -70 +KPX V Q -20 +KPX V O -20 +KPX V G -20 +KPX V C -20 +KPX V A -60 + +KPX W y -50 +KPX W u -46 +KPX W t -30 +KPX W semicolon -40 +KPX W r -50 +KPX W quoteright 40 +KPX W quotedblright 24 +KPX W period -100 +KPX W parenright 80 +KPX W o -60 +KPX W m -50 +KPX W i 5 +KPX W hyphen -70 +KPX W h 20 +KPX W e -60 +KPX W d -60 +KPX W comma -100 +KPX W colon -40 +KPX W bracketright 80 +KPX W braceright 70 +KPX W a -75 +KPX W T 30 +KPX W Q -20 +KPX W O -20 +KPX W G -20 +KPX W C -20 +KPX W A -58 + +KPX X y -40 +KPX X u -24 +KPX X quoteright 15 +KPX X e -6 +KPX X a -6 +KPX X Q -24 +KPX X O -30 +KPX X G -30 +KPX X C -30 +KPX X A 20 + +KPX Y v -50 +KPX Y u -65 +KPX Y t -46 +KPX Y semicolon -37 +KPX Y quoteright 50 +KPX Y quotedblright 36 +KPX Y q -100 +KPX Y period -90 +KPX Y parenright 60 +KPX Y o -90 +KPX Y l 25 +KPX Y i 15 +KPX Y hyphen -100 +KPX Y endash -30 +KPX Y emdash -50 +KPX Y e -90 +KPX Y d -90 +KPX Y comma -90 +KPX Y colon -60 +KPX Y bracketright 80 +KPX Y braceright 64 +KPX Y a -80 +KPX Y Y 12 +KPX Y X 12 +KPX Y W 12 +KPX Y V 12 +KPX Y T 30 +KPX Y Q -40 +KPX Y O -40 +KPX Y G -40 +KPX Y C -40 +KPX Y A -55 + +KPX Z y -36 +KPX Z w -36 +KPX Z u -6 +KPX Z o -12 +KPX Z i -12 +KPX Z e -6 +KPX Z a -6 +KPX Z Q -18 +KPX Z O -18 +KPX Z G -18 +KPX Z C -18 +KPX Z A 25 + +KPX a quoteright -45 +KPX a quotedblright -40 + +KPX b y -15 +KPX b w -20 +KPX b v -20 +KPX b quoteright -45 +KPX b quotedblright -40 +KPX b period -10 +KPX b comma -10 + +KPX braceleft Y 64 +KPX braceleft W 64 +KPX braceleft V 64 +KPX braceleft T 25 +KPX braceleft J 50 + +KPX bracketleft Y 64 +KPX bracketleft W 64 +KPX bracketleft V 64 +KPX bracketleft T 35 +KPX bracketleft J 60 + +KPX c quoteright -5 + +KPX colon space -20 + +KPX comma space -40 +KPX comma quoteright -100 +KPX comma quotedblright -100 + +KPX d quoteright -24 +KPX d quotedblright -24 + +KPX e z -4 +KPX e quoteright -25 +KPX e quotedblright -20 + +KPX f quotesingle 70 +KPX f quoteright 68 +KPX f quotedblright 68 +KPX f period -10 +KPX f parenright 110 +KPX f comma -20 +KPX f bracketright 100 +KPX f braceright 80 + +KPX g y 20 +KPX g p 20 +KPX g f 20 +KPX g comma 10 + +KPX h quoteright -60 +KPX h quotedblright -60 + +KPX i quoteright -20 +KPX i quotedblright -20 + +KPX j quoteright -20 +KPX j quotedblright -20 +KPX j period -10 +KPX j comma -10 + +KPX k quoteright -30 +KPX k quotedblright -30 + +KPX l quoteright -24 +KPX l quotedblright -24 + +KPX m quoteright -60 +KPX m quotedblright -60 + +KPX n quoteright -60 +KPX n quotedblright -60 + +KPX o z -12 +KPX o y -25 +KPX o x -18 +KPX o w -30 +KPX o v -30 +KPX o quoteright -45 +KPX o quotedblright -40 +KPX o period -10 +KPX o comma -10 + +KPX p z -10 +KPX p y -15 +KPX p w -15 +KPX p quoteright -45 +KPX p quotedblright -60 +KPX p period -10 +KPX p comma -10 + +KPX parenleft Y 64 +KPX parenleft W 64 +KPX parenleft V 64 +KPX parenleft T 50 +KPX parenleft J 50 + +KPX period space -40 +KPX period quoteright -100 +KPX period quotedblright -100 + +KPX q quoteright -50 +KPX q quotedblright -50 +KPX q period -10 +KPX q comma -10 + +KPX quotedblleft z -26 +KPX quotedblleft w 10 +KPX quotedblleft u -40 +KPX quotedblleft t -40 +KPX quotedblleft s -32 +KPX quotedblleft r -40 +KPX quotedblleft q -70 +KPX quotedblleft p -40 +KPX quotedblleft o -70 +KPX quotedblleft n -40 +KPX quotedblleft m -40 +KPX quotedblleft g -50 +KPX quotedblleft f -30 +KPX quotedblleft e -70 +KPX quotedblleft d -70 +KPX quotedblleft c -70 +KPX quotedblleft a -60 +KPX quotedblleft Y 30 +KPX quotedblleft X 20 +KPX quotedblleft W 40 +KPX quotedblleft V 40 +KPX quotedblleft T 18 +KPX quotedblleft J -24 +KPX quotedblleft A -122 + +KPX quotedblright space -40 +KPX quotedblright period -100 +KPX quotedblright comma -100 + +KPX quoteleft z -26 +KPX quoteleft y -5 +KPX quoteleft x -5 +KPX quoteleft w 5 +KPX quoteleft v -5 +KPX quoteleft u -25 +KPX quoteleft t -25 +KPX quoteleft s -40 +KPX quoteleft r -40 +KPX quoteleft quoteleft -30 +KPX quoteleft q -70 +KPX quoteleft p -40 +KPX quoteleft o -70 +KPX quoteleft n -40 +KPX quoteleft m -40 +KPX quoteleft g -50 +KPX quoteleft f -10 +KPX quoteleft e -70 +KPX quoteleft d -70 +KPX quoteleft c -70 +KPX quoteleft a -60 +KPX quoteleft Y 35 +KPX quoteleft X 30 +KPX quoteleft W 35 +KPX quoteleft V 35 +KPX quoteleft T 35 +KPX quoteleft J -24 +KPX quoteleft A -122 + +KPX quoteright v -20 +KPX quoteright t -50 +KPX quoteright space -40 +KPX quoteright s -70 +KPX quoteright r -42 +KPX quoteright quoteright -30 +KPX quoteright period -100 +KPX quoteright m -42 +KPX quoteright l -6 +KPX quoteright d -100 +KPX quoteright comma -100 + +KPX r z 20 +KPX r y 18 +KPX r x 12 +KPX r w 30 +KPX r v 30 +KPX r u 8 +KPX r t 8 +KPX r semicolon 20 +KPX r quoteright -20 +KPX r quotedblright -10 +KPX r q -6 +KPX r period -60 +KPX r o -6 +KPX r n 8 +KPX r m 8 +KPX r l -10 +KPX r k -10 +KPX r i 8 +KPX r hyphen -60 +KPX r h -10 +KPX r g 5 +KPX r f 8 +KPX r emdash -20 +KPX r e -20 +KPX r d -20 +KPX r comma -80 +KPX r colon 20 +KPX r c -20 + +KPX s quoteright -40 +KPX s quotedblright -40 + +KPX semicolon space -20 + +KPX space quotesinglbase -100 +KPX space quoteleft -40 +KPX space quotedblleft -40 +KPX space quotedblbase -100 +KPX space Y -60 +KPX space W -60 +KPX space V -60 +KPX space T -40 + +KPX t period 15 +KPX t comma 10 + +KPX u quoteright -60 +KPX u quotedblright -60 + +KPX v semicolon 20 +KPX v quoteright 5 +KPX v quotedblright 10 +KPX v q -15 +KPX v period -75 +KPX v o -15 +KPX v e -15 +KPX v d -15 +KPX v comma -90 +KPX v colon 20 +KPX v c -15 +KPX v a -15 + +KPX w semicolon 20 +KPX w quoteright 15 +KPX w quotedblright 20 +KPX w q -10 +KPX w period -60 +KPX w o -10 +KPX w e -10 +KPX w d -10 +KPX w comma -68 +KPX w colon 20 +KPX w c -10 + +KPX x quoteright -25 +KPX x quotedblright -20 +KPX x q -6 +KPX x o -6 +KPX x e -12 +KPX x d -12 +KPX x c -12 + +KPX y semicolon 20 +KPX y quoteright 5 +KPX y quotedblright 10 +KPX y period -72 +KPX y hyphen -20 +KPX y comma -72 +KPX y colon 20 + +KPX z quoteright -20 +KPX z quotedblright -20 +KPX z o -6 +KPX z e -6 +KPX z d -6 +KPX z c -6 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putbi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putbi8a.afm new file mode 100644 index 00000000..5e838485 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putbi8a.afm @@ -0,0 +1,1017 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Fri Jan 17 15:47:44 1992 +Comment UniqueID 37716 +Comment VMusage 34427 41319 +FontName Utopia-BoldItalic +FullName Utopia Bold Italic +FamilyName Utopia +Weight Bold +ItalicAngle -13 +IsFixedPitch false +FontBBox -176 -250 1262 916 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.002 +Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 502 +Ascender 742 +Descender -242 +StartCharMetrics 228 +C 32 ; WX 210 ; N space ; B 0 0 0 0 ; +C 33 ; WX 285 ; N exclam ; B 35 -12 336 707 ; +C 34 ; WX 455 ; N quotedbl ; B 142 407 496 707 ; +C 35 ; WX 560 ; N numbersign ; B 37 0 606 668 ; +C 36 ; WX 560 ; N dollar ; B 32 -104 588 748 ; +C 37 ; WX 896 ; N percent ; B 106 -31 861 702 ; +C 38 ; WX 752 ; N ampersand ; B 62 -12 736 680 ; +C 39 ; WX 246 ; N quoteright ; B 95 387 294 707 ; +C 40 ; WX 350 ; N parenleft ; B 87 -135 438 699 ; +C 41 ; WX 350 ; N parenright ; B -32 -135 319 699 ; +C 42 ; WX 500 ; N asterisk ; B 121 315 528 707 ; +C 43 ; WX 600 ; N plus ; B 83 0 567 490 ; +C 44 ; WX 280 ; N comma ; B -9 -167 207 180 ; +C 45 ; WX 392 ; N hyphen ; B 71 203 354 298 ; +C 46 ; WX 280 ; N period ; B 32 -12 212 166 ; +C 47 ; WX 260 ; N slash ; B -16 -15 370 707 ; +C 48 ; WX 560 ; N zero ; B 57 -12 583 680 ; +C 49 ; WX 560 ; N one ; B 72 0 470 680 ; +C 50 ; WX 560 ; N two ; B 4 0 578 680 ; +C 51 ; WX 560 ; N three ; B 21 -12 567 680 ; +C 52 ; WX 560 ; N four ; B 28 0 557 668 ; +C 53 ; WX 560 ; N five ; B 23 -12 593 668 ; +C 54 ; WX 560 ; N six ; B 56 -12 586 680 ; +C 55 ; WX 560 ; N seven ; B 112 -12 632 668 ; +C 56 ; WX 560 ; N eight ; B 37 -12 584 680 ; +C 57 ; WX 560 ; N nine ; B 48 -12 570 680 ; +C 58 ; WX 280 ; N colon ; B 32 -12 280 490 ; +C 59 ; WX 280 ; N semicolon ; B -9 -167 280 490 ; +C 60 ; WX 600 ; N less ; B 66 5 544 495 ; +C 61 ; WX 600 ; N equal ; B 83 103 567 397 ; +C 62 ; WX 600 ; N greater ; B 86 5 564 495 ; +C 63 ; WX 454 ; N question ; B 115 -12 515 707 ; +C 64 ; WX 828 ; N at ; B 90 -15 842 707 ; +C 65 ; WX 634 ; N A ; B -59 0 639 692 ; +C 66 ; WX 680 ; N B ; B 5 0 689 692 ; +C 67 ; WX 672 ; N C ; B 76 -15 742 707 ; +C 68 ; WX 774 ; N D ; B 5 0 784 692 ; +C 69 ; WX 622 ; N E ; B 5 0 687 692 ; +C 70 ; WX 585 ; N F ; B 5 0 683 692 ; +C 71 ; WX 726 ; N G ; B 76 -15 756 707 ; +C 72 ; WX 800 ; N H ; B 5 0 880 692 ; +C 73 ; WX 386 ; N I ; B 5 0 466 692 ; +C 74 ; WX 388 ; N J ; B -50 -114 477 692 ; +C 75 ; WX 688 ; N K ; B 5 -6 823 692 ; +C 76 ; WX 586 ; N L ; B 5 0 591 692 ; +C 77 ; WX 921 ; N M ; B 0 0 998 692 ; +C 78 ; WX 741 ; N N ; B -5 0 838 692 ; +C 79 ; WX 761 ; N O ; B 78 -15 768 707 ; +C 80 ; WX 660 ; N P ; B 5 0 694 692 ; +C 81 ; WX 761 ; N Q ; B 78 -193 768 707 ; +C 82 ; WX 681 ; N R ; B 5 0 696 692 ; +C 83 ; WX 551 ; N S ; B 31 -15 570 707 ; +C 84 ; WX 616 ; N T ; B 91 0 722 692 ; +C 85 ; WX 776 ; N U ; B 115 -15 867 692 ; +C 86 ; WX 630 ; N V ; B 92 0 783 692 ; +C 87 ; WX 920 ; N W ; B 80 0 1062 692 ; +C 88 ; WX 630 ; N X ; B -56 0 744 692 ; +C 89 ; WX 622 ; N Y ; B 92 0 765 692 ; +C 90 ; WX 618 ; N Z ; B -30 0 714 692 ; +C 91 ; WX 350 ; N bracketleft ; B 56 -128 428 692 ; +C 92 ; WX 460 ; N backslash ; B 114 -15 425 707 ; +C 93 ; WX 350 ; N bracketright ; B -22 -128 350 692 ; +C 94 ; WX 600 ; N asciicircum ; B 79 215 567 668 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 246 ; N quoteleft ; B 114 399 313 719 ; +C 97 ; WX 596 ; N a ; B 26 -12 612 502 ; +C 98 ; WX 586 ; N b ; B 34 -12 592 742 ; +C 99 ; WX 456 ; N c ; B 38 -12 498 502 ; +C 100 ; WX 609 ; N d ; B 29 -12 651 742 ; +C 101 ; WX 476 ; N e ; B 38 -12 497 502 ; +C 102 ; WX 348 ; N f ; B -129 -242 553 742 ; L i fi ; L l fl ; +C 103 ; WX 522 ; N g ; B -14 -242 609 512 ; +C 104 ; WX 629 ; N h ; B 44 -12 631 742 ; +C 105 ; WX 339 ; N i ; B 66 -12 357 720 ; +C 106 ; WX 333 ; N j ; B -120 -242 364 720 ; +C 107 ; WX 570 ; N k ; B 39 -12 604 742 ; +C 108 ; WX 327 ; N l ; B 62 -12 360 742 ; +C 109 ; WX 914 ; N m ; B 46 -12 917 502 ; +C 110 ; WX 635 ; N n ; B 45 -12 639 502 ; +C 111 ; WX 562 ; N o ; B 42 -12 556 502 ; +C 112 ; WX 606 ; N p ; B 0 -242 613 502 ; +C 113 ; WX 584 ; N q ; B 29 -242 604 513 ; +C 114 ; WX 440 ; N r ; B 51 -12 497 502 ; +C 115 ; WX 417 ; N s ; B 10 -12 432 502 ; +C 116 ; WX 359 ; N t ; B 68 -12 428 641 ; +C 117 ; WX 634 ; N u ; B 71 -12 643 502 ; +C 118 ; WX 518 ; N v ; B 68 -12 547 502 ; +C 119 ; WX 795 ; N w ; B 70 -12 826 502 ; +C 120 ; WX 516 ; N x ; B -26 -12 546 502 ; +C 121 ; WX 489 ; N y ; B -49 -242 532 502 ; +C 122 ; WX 466 ; N z ; B -17 -12 506 490 ; +C 123 ; WX 340 ; N braceleft ; B 90 -128 439 692 ; +C 124 ; WX 265 ; N bar ; B 117 -250 221 750 ; +C 125 ; WX 340 ; N braceright ; B -42 -128 307 692 ; +C 126 ; WX 600 ; N asciitilde ; B 70 157 571 338 ; +C 161 ; WX 285 ; N exclamdown ; B -13 -217 288 502 ; +C 162 ; WX 560 ; N cent ; B 80 -21 611 668 ; +C 163 ; WX 560 ; N sterling ; B -4 0 583 679 ; +C 164 ; WX 100 ; N fraction ; B -176 -27 370 695 ; +C 165 ; WX 560 ; N yen ; B 65 0 676 668 ; +C 166 ; WX 560 ; N florin ; B -16 -135 635 691 ; +C 167 ; WX 568 ; N section ; B 64 -115 559 707 ; +C 168 ; WX 560 ; N currency ; B 60 73 578 596 ; +C 169 ; WX 246 ; N quotesingle ; B 134 376 285 707 ; +C 170 ; WX 455 ; N quotedblleft ; B 114 399 522 719 ; +C 171 ; WX 560 ; N guillemotleft ; B 90 37 533 464 ; +C 172 ; WX 360 ; N guilsinglleft ; B 90 37 333 464 ; +C 173 ; WX 360 ; N guilsinglright ; B 58 37 301 464 ; +C 174 ; WX 651 ; N fi ; B -129 -242 655 742 ; +C 175 ; WX 652 ; N fl ; B -129 -242 685 742 ; +C 177 ; WX 500 ; N endash ; B 12 209 531 292 ; +C 178 ; WX 514 ; N dagger ; B 101 -125 545 707 ; +C 179 ; WX 490 ; N daggerdbl ; B 32 -119 528 707 ; +C 180 ; WX 280 ; N periodcentered ; B 67 161 247 339 ; +C 182 ; WX 580 ; N paragraph ; B 110 -101 653 692 ; +C 183 ; WX 465 ; N bullet ; B 99 174 454 529 ; +C 184 ; WX 246 ; N quotesinglbase ; B -17 -153 182 167 ; +C 185 ; WX 455 ; N quotedblbase ; B -17 -153 391 167 ; +C 186 ; WX 455 ; N quotedblright ; B 95 387 503 707 ; +C 187 ; WX 560 ; N guillemotright ; B 58 37 502 464 ; +C 188 ; WX 1000 ; N ellipsis ; B 85 -12 931 166 ; +C 189 ; WX 1297 ; N perthousand ; B 106 -31 1262 702 ; +C 191 ; WX 454 ; N questiondown ; B -10 -217 391 502 ; +C 193 ; WX 400 ; N grave ; B 109 511 381 740 ; +C 194 ; WX 400 ; N acute ; B 186 511 458 740 ; +C 195 ; WX 400 ; N circumflex ; B 93 520 471 747 ; +C 196 ; WX 400 ; N tilde ; B 94 549 502 697 ; +C 197 ; WX 400 ; N macron ; B 133 592 459 664 ; +C 198 ; WX 400 ; N breve ; B 146 556 469 714 ; +C 199 ; WX 402 ; N dotaccent ; B 220 561 378 710 ; +C 200 ; WX 400 ; N dieresis ; B 106 561 504 710 ; +C 202 ; WX 400 ; N ring ; B 166 529 423 762 ; +C 203 ; WX 400 ; N cedilla ; B 85 -246 292 0 ; +C 205 ; WX 400 ; N hungarumlaut ; B 158 546 482 750 ; +C 206 ; WX 350 ; N ogonek ; B 38 -246 253 0 ; +C 207 ; WX 400 ; N caron ; B 130 520 508 747 ; +C 208 ; WX 1000 ; N emdash ; B 12 209 1031 292 ; +C 225 ; WX 890 ; N AE ; B -107 0 958 692 ; +C 227 ; WX 444 ; N ordfeminine ; B 62 265 482 590 ; +C 232 ; WX 592 ; N Lslash ; B 11 0 597 692 ; +C 233 ; WX 761 ; N Oslash ; B 77 -51 769 734 ; +C 234 ; WX 1016 ; N OE ; B 76 0 1084 692 ; +C 235 ; WX 412 ; N ordmasculine ; B 86 265 446 590 ; +C 241 ; WX 789 ; N ae ; B 26 -12 810 509 ; +C 245 ; WX 339 ; N dotlessi ; B 66 -12 343 502 ; +C 248 ; WX 339 ; N lslash ; B 18 -12 420 742 ; +C 249 ; WX 562 ; N oslash ; B 42 -69 556 549 ; +C 250 ; WX 811 ; N oe ; B 42 -12 832 502 ; +C 251 ; WX 628 ; N germandbls ; B -129 -242 692 742 ; +C -1 ; WX 402 ; N onesuperior ; B 84 272 361 680 ; +C -1 ; WX 600 ; N minus ; B 83 210 567 290 ; +C -1 ; WX 375 ; N degree ; B 93 360 425 680 ; +C -1 ; WX 562 ; N oacute ; B 42 -12 572 755 ; +C -1 ; WX 761 ; N Odieresis ; B 78 -15 768 881 ; +C -1 ; WX 562 ; N odieresis ; B 42 -12 585 710 ; +C -1 ; WX 622 ; N Eacute ; B 5 0 687 904 ; +C -1 ; WX 634 ; N ucircumflex ; B 71 -12 643 747 ; +C -1 ; WX 940 ; N onequarter ; B 104 -27 849 695 ; +C -1 ; WX 600 ; N logicalnot ; B 83 95 567 397 ; +C -1 ; WX 622 ; N Ecircumflex ; B 5 0 687 905 ; +C -1 ; WX 940 ; N onehalf ; B 90 -27 898 695 ; +C -1 ; WX 761 ; N Otilde ; B 78 -15 768 876 ; +C -1 ; WX 634 ; N uacute ; B 71 -12 643 740 ; +C -1 ; WX 476 ; N eacute ; B 38 -12 545 755 ; +C -1 ; WX 339 ; N iacute ; B 66 -12 438 740 ; +C -1 ; WX 622 ; N Egrave ; B 5 0 687 904 ; +C -1 ; WX 339 ; N icircumflex ; B 38 -12 416 747 ; +C -1 ; WX 634 ; N mu ; B -3 -230 643 502 ; +C -1 ; WX 265 ; N brokenbar ; B 117 -175 221 675 ; +C -1 ; WX 600 ; N thorn ; B -6 -242 607 700 ; +C -1 ; WX 634 ; N Aring ; B -59 0 639 879 ; +C -1 ; WX 489 ; N yacute ; B -49 -242 553 740 ; +C -1 ; WX 622 ; N Ydieresis ; B 92 0 765 881 ; +C -1 ; WX 1100 ; N trademark ; B 103 277 1093 692 ; +C -1 ; WX 824 ; N registered ; B 91 -15 819 707 ; +C -1 ; WX 562 ; N ocircumflex ; B 42 -12 556 747 ; +C -1 ; WX 634 ; N Agrave ; B -59 0 639 904 ; +C -1 ; WX 551 ; N Scaron ; B 31 -15 612 916 ; +C -1 ; WX 776 ; N Ugrave ; B 115 -15 867 904 ; +C -1 ; WX 622 ; N Edieresis ; B 5 0 687 881 ; +C -1 ; WX 776 ; N Uacute ; B 115 -15 867 904 ; +C -1 ; WX 562 ; N otilde ; B 42 -12 583 697 ; +C -1 ; WX 635 ; N ntilde ; B 45 -12 639 697 ; +C -1 ; WX 489 ; N ydieresis ; B -49 -242 532 710 ; +C -1 ; WX 634 ; N Aacute ; B -59 0 678 904 ; +C -1 ; WX 562 ; N eth ; B 42 -12 558 742 ; +C -1 ; WX 596 ; N acircumflex ; B 26 -12 612 747 ; +C -1 ; WX 596 ; N aring ; B 26 -12 612 762 ; +C -1 ; WX 761 ; N Ograve ; B 78 -15 768 904 ; +C -1 ; WX 456 ; N ccedilla ; B 38 -246 498 502 ; +C -1 ; WX 600 ; N multiply ; B 110 22 560 478 ; +C -1 ; WX 600 ; N divide ; B 63 7 547 493 ; +C -1 ; WX 402 ; N twosuperior ; B 29 272 423 680 ; +C -1 ; WX 741 ; N Ntilde ; B -5 0 838 876 ; +C -1 ; WX 634 ; N ugrave ; B 71 -12 643 740 ; +C -1 ; WX 776 ; N Ucircumflex ; B 115 -15 867 905 ; +C -1 ; WX 634 ; N Atilde ; B -59 0 662 876 ; +C -1 ; WX 466 ; N zcaron ; B -17 -12 526 747 ; +C -1 ; WX 339 ; N idieresis ; B 46 -12 444 710 ; +C -1 ; WX 634 ; N Acircumflex ; B -59 0 639 905 ; +C -1 ; WX 386 ; N Icircumflex ; B 5 0 506 905 ; +C -1 ; WX 622 ; N Yacute ; B 92 0 765 904 ; +C -1 ; WX 761 ; N Oacute ; B 78 -15 768 904 ; +C -1 ; WX 634 ; N Adieresis ; B -59 0 652 881 ; +C -1 ; WX 618 ; N Zcaron ; B -30 0 714 916 ; +C -1 ; WX 596 ; N agrave ; B 26 -12 612 755 ; +C -1 ; WX 402 ; N threesuperior ; B 59 265 421 680 ; +C -1 ; WX 562 ; N ograve ; B 42 -12 556 755 ; +C -1 ; WX 940 ; N threequarters ; B 95 -27 876 695 ; +C -1 ; WX 780 ; N Eth ; B 11 0 790 692 ; +C -1 ; WX 600 ; N plusminus ; B 83 0 567 549 ; +C -1 ; WX 634 ; N udieresis ; B 71 -12 643 710 ; +C -1 ; WX 476 ; N edieresis ; B 38 -12 542 710 ; +C -1 ; WX 596 ; N aacute ; B 26 -12 621 755 ; +C -1 ; WX 339 ; N igrave ; B 39 -12 343 740 ; +C -1 ; WX 386 ; N Idieresis ; B 5 0 533 881 ; +C -1 ; WX 596 ; N adieresis ; B 26 -12 612 710 ; +C -1 ; WX 386 ; N Iacute ; B 5 0 549 904 ; +C -1 ; WX 824 ; N copyright ; B 91 -15 819 707 ; +C -1 ; WX 386 ; N Igrave ; B 5 0 466 904 ; +C -1 ; WX 672 ; N Ccedilla ; B 76 -246 742 707 ; +C -1 ; WX 417 ; N scaron ; B 10 -12 522 747 ; +C -1 ; WX 476 ; N egrave ; B 38 -12 497 755 ; +C -1 ; WX 761 ; N Ocircumflex ; B 78 -15 768 905 ; +C -1 ; WX 629 ; N Thorn ; B 5 0 660 692 ; +C -1 ; WX 596 ; N atilde ; B 26 -12 612 697 ; +C -1 ; WX 776 ; N Udieresis ; B 115 -15 867 881 ; +C -1 ; WX 476 ; N ecircumflex ; B 38 -12 524 747 ; +EndCharMetrics +StartKernData +StartKernPairs 697 + +KPX A z 18 +KPX A y -40 +KPX A x 16 +KPX A w -30 +KPX A v -30 +KPX A u -18 +KPX A t -6 +KPX A s 6 +KPX A r -6 +KPX A quoteright -92 +KPX A quotedblright -92 +KPX A p -6 +KPX A o -18 +KPX A n -12 +KPX A m -12 +KPX A l -18 +KPX A h -6 +KPX A d 4 +KPX A c -6 +KPX A b -6 +KPX A a 10 +KPX A Y -56 +KPX A X -8 +KPX A W -46 +KPX A V -75 +KPX A U -50 +KPX A T -60 +KPX A Q -30 +KPX A O -30 +KPX A G -30 +KPX A C -30 + +KPX B y -6 +KPX B u -12 +KPX B r -6 +KPX B quoteright -20 +KPX B quotedblright -32 +KPX B o 6 +KPX B l -20 +KPX B k -10 +KPX B i -12 +KPX B h -15 +KPX B e 4 +KPX B a 10 +KPX B W -30 +KPX B V -45 +KPX B U -30 +KPX B T -20 + +KPX C z -6 +KPX C y -18 +KPX C u -12 +KPX C r -12 +KPX C quoteright 12 +KPX C quotedblright 20 +KPX C i -6 +KPX C e -6 +KPX C a -6 +KPX C Q -12 +KPX C O -12 +KPX C G -12 +KPX C C -12 + +KPX D y 18 +KPX D quoteright -20 +KPX D quotedblright -20 +KPX D period -20 +KPX D o 6 +KPX D h -15 +KPX D e 6 +KPX D comma -20 +KPX D a 6 +KPX D Y -80 +KPX D W -40 +KPX D V -65 + +KPX E z -6 +KPX E y -24 +KPX E x 15 +KPX E w -30 +KPX E v -18 +KPX E u -24 +KPX E t -18 +KPX E s -6 +KPX E r -6 +KPX E quoteright 10 +KPX E q 10 +KPX E period 15 +KPX E p -12 +KPX E n -12 +KPX E m -12 +KPX E l -6 +KPX E j -6 +KPX E i -12 +KPX E g -12 +KPX E d 10 +KPX E comma 15 +KPX E a 10 + +KPX F y -12 +KPX F u -24 +KPX F r -12 +KPX F quoteright 40 +KPX F quotedblright 35 +KPX F period -120 +KPX F o -24 +KPX F i -6 +KPX F e -24 +KPX F comma -110 +KPX F a -30 +KPX F A -45 + +KPX G y -25 +KPX G u -22 +KPX G r -22 +KPX G quoteright -30 +KPX G quotedblright -30 +KPX G n -22 +KPX G l -24 +KPX G i -12 +KPX G h -18 +KPX G e 5 + +KPX H y -18 +KPX H u -30 +KPX H o -25 +KPX H i -25 +KPX H e -25 +KPX H a -25 + +KPX I z -20 +KPX I y -6 +KPX I x -6 +KPX I w -30 +KPX I v -30 +KPX I u -30 +KPX I t -18 +KPX I s -18 +KPX I r -12 +KPX I p -18 +KPX I o -25 +KPX I n -18 +KPX I m -18 +KPX I l -6 +KPX I k -6 +KPX I j -20 +KPX I i -10 +KPX I g -24 +KPX I f -6 +KPX I e -25 +KPX I d -15 +KPX I c -25 +KPX I b -6 +KPX I a -15 + +KPX J y -12 +KPX J u -32 +KPX J quoteright 6 +KPX J quotedblright 6 +KPX J o -36 +KPX J i -30 +KPX J e -30 +KPX J braceright 15 +KPX J a -36 + +KPX K y -70 +KPX K w -36 +KPX K v -30 +KPX K u -30 +KPX K r -24 +KPX K quoteright 36 +KPX K quotedblright 36 +KPX K o -30 +KPX K n -24 +KPX K l 10 +KPX K i -12 +KPX K h 15 +KPX K e -30 +KPX K a -12 +KPX K Q -50 +KPX K O -50 +KPX K G -50 +KPX K C -50 +KPX K A 15 + +KPX L y -70 +KPX L w -30 +KPX L u -18 +KPX L quoteright -110 +KPX L quotedblright -110 +KPX L l -16 +KPX L j -18 +KPX L i -18 +KPX L Y -80 +KPX L W -78 +KPX L V -110 +KPX L U -42 +KPX L T -100 +KPX L Q -48 +KPX L O -48 +KPX L G -48 +KPX L C -48 +KPX L A 40 + +KPX M y -18 +KPX M u -24 +KPX M quoteright 6 +KPX M quotedblright 6 +KPX M o -25 +KPX M n -20 +KPX M j -35 +KPX M i -20 +KPX M e -25 +KPX M d -20 +KPX M c -25 +KPX M a -20 + +KPX N y -18 +KPX N u -24 +KPX N o -18 +KPX N i -12 +KPX N e -16 +KPX N a -22 + +KPX O z -6 +KPX O y 12 +KPX O u -6 +KPX O t -6 +KPX O s -6 +KPX O r -6 +KPX O quoteright -20 +KPX O quotedblright -20 +KPX O q 6 +KPX O period -10 +KPX O p -6 +KPX O n -6 +KPX O m -6 +KPX O l -15 +KPX O k -10 +KPX O j -6 +KPX O h -10 +KPX O g -6 +KPX O e 6 +KPX O d 6 +KPX O comma -10 +KPX O a 6 +KPX O Y -70 +KPX O X -30 +KPX O W -35 +KPX O V -50 +KPX O T -42 +KPX O A -8 + +KPX P y 6 +KPX P u -18 +KPX P t -6 +KPX P s -24 +KPX P r -6 +KPX P quoteright -12 +KPX P period -170 +KPX P o -24 +KPX P n -12 +KPX P l -20 +KPX P h -20 +KPX P e -24 +KPX P comma -170 +KPX P a -40 +KPX P I -45 +KPX P H -45 +KPX P E -45 +KPX P A -70 + +KPX Q u -6 +KPX Q quoteright -20 +KPX Q quotedblright -38 +KPX Q a -6 +KPX Q Y -70 +KPX Q X -12 +KPX Q W -35 +KPX Q V -50 +KPX Q U -30 +KPX Q T -36 +KPX Q A -18 + +KPX R y -6 +KPX R u -12 +KPX R quoteright -22 +KPX R quotedblright -22 +KPX R o -20 +KPX R e -12 +KPX R Y -45 +KPX R X 15 +KPX R W -25 +KPX R V -35 +KPX R U -40 +KPX R T -18 +KPX R Q -8 +KPX R O -8 +KPX R G -8 +KPX R C -8 +KPX R A 15 + +KPX S y -30 +KPX S w -30 +KPX S v -20 +KPX S u -18 +KPX S t -18 +KPX S r -20 +KPX S quoteright -38 +KPX S quotedblright -50 +KPX S p -18 +KPX S n -24 +KPX S m -24 +KPX S l -20 +KPX S k -18 +KPX S j -25 +KPX S i -20 +KPX S h -12 +KPX S e -6 + +KPX T z -48 +KPX T y -52 +KPX T w -54 +KPX T u -54 +KPX T semicolon -6 +KPX T s -60 +KPX T r -54 +KPX T quoteright 36 +KPX T quotedblright 36 +KPX T period -70 +KPX T parenright 25 +KPX T o -78 +KPX T m -54 +KPX T i -22 +KPX T hyphen -100 +KPX T h 6 +KPX T endash -40 +KPX T emdash -40 +KPX T e -78 +KPX T comma -90 +KPX T bracketright 20 +KPX T braceright 30 +KPX T a -78 +KPX T Y 12 +KPX T X 18 +KPX T W 30 +KPX T V 20 +KPX T T 40 +KPX T Q -6 +KPX T O -6 +KPX T G -6 +KPX T C -6 +KPX T A -40 + +KPX U z -18 +KPX U x -30 +KPX U v -20 +KPX U t -24 +KPX U s -40 +KPX U r -30 +KPX U p -30 +KPX U n -30 +KPX U m -30 +KPX U l -12 +KPX U k -12 +KPX U i -24 +KPX U h -6 +KPX U g -30 +KPX U f -10 +KPX U d -30 +KPX U c -30 +KPX U b -6 +KPX U a -30 +KPX U A -40 + +KPX V y -34 +KPX V u -42 +KPX V semicolon -45 +KPX V r -55 +KPX V quoteright 46 +KPX V quotedblright 60 +KPX V period -110 +KPX V parenright 64 +KPX V o -55 +KPX V i 15 +KPX V hyphen -60 +KPX V endash -20 +KPX V emdash -20 +KPX V e -55 +KPX V comma -110 +KPX V colon -18 +KPX V bracketright 64 +KPX V braceright 64 +KPX V a -80 +KPX V T 12 +KPX V A -70 + +KPX W y -36 +KPX W u -30 +KPX W t -10 +KPX W semicolon -12 +KPX W r -30 +KPX W quoteright 42 +KPX W quotedblright 55 +KPX W period -80 +KPX W parenright 55 +KPX W o -55 +KPX W m -30 +KPX W i 5 +KPX W hyphen -40 +KPX W h 16 +KPX W e -55 +KPX W d -60 +KPX W comma -80 +KPX W colon -12 +KPX W bracketright 64 +KPX W braceright 64 +KPX W a -60 +KPX W T 30 +KPX W Q -5 +KPX W O -5 +KPX W G -5 +KPX W C -5 +KPX W A -45 + +KPX X y -40 +KPX X u -30 +KPX X r -6 +KPX X quoteright 24 +KPX X quotedblright 40 +KPX X i -6 +KPX X e -18 +KPX X a -6 +KPX X Y -6 +KPX X W -6 +KPX X Q -45 +KPX X O -45 +KPX X G -45 +KPX X C -45 + +KPX Y v -60 +KPX Y u -70 +KPX Y t -32 +KPX Y semicolon -20 +KPX Y quoteright 56 +KPX Y quotedblright 70 +KPX Y q -100 +KPX Y period -80 +KPX Y parenright 5 +KPX Y o -95 +KPX Y l 15 +KPX Y i 15 +KPX Y hyphen -110 +KPX Y endash -40 +KPX Y emdash -40 +KPX Y e -95 +KPX Y d -85 +KPX Y comma -80 +KPX Y colon -20 +KPX Y bracketright 64 +KPX Y braceright 64 +KPX Y a -85 +KPX Y Y 12 +KPX Y X 12 +KPX Y W 12 +KPX Y V 6 +KPX Y T 30 +KPX Y Q -25 +KPX Y O -25 +KPX Y G -25 +KPX Y C -25 +KPX Y A -40 + +KPX Z y -36 +KPX Z w -36 +KPX Z u -12 +KPX Z quoteright 18 +KPX Z quotedblright 18 +KPX Z o -6 +KPX Z i -12 +KPX Z e -6 +KPX Z a -6 +KPX Z Q -20 +KPX Z O -20 +KPX Z G -20 +KPX Z C -20 +KPX Z A 30 + +KPX a quoteright -54 +KPX a quotedblright -54 + +KPX b y -6 +KPX b w -5 +KPX b v -5 +KPX b quoteright -30 +KPX b quotedblright -30 +KPX b period -15 +KPX b comma -15 + +KPX braceleft Y 64 +KPX braceleft W 64 +KPX braceleft V 64 +KPX braceleft T 40 +KPX braceleft J 60 + +KPX bracketleft Y 60 +KPX bracketleft W 64 +KPX bracketleft V 64 +KPX bracketleft T 35 +KPX bracketleft J 30 + +KPX c quoteright 5 +KPX c quotedblright 5 + +KPX colon space -30 + +KPX comma space -40 +KPX comma quoteright -100 +KPX comma quotedblright -100 + +KPX d quoteright -12 +KPX d quotedblright -12 +KPX d period 15 +KPX d comma 15 + +KPX e y 6 +KPX e x -10 +KPX e w -10 +KPX e v -10 +KPX e quoteright -25 +KPX e quotedblright -25 + +KPX f quoteright 120 +KPX f quotedblright 120 +KPX f period -30 +KPX f parenright 100 +KPX f comma -30 +KPX f bracketright 110 +KPX f braceright 110 + +KPX g y 50 +KPX g quotedblright -20 +KPX g p 30 +KPX g f 42 +KPX g comma 20 + +KPX h quoteright -78 +KPX h quotedblright -78 + +KPX i quoteright -20 +KPX i quotedblright -20 + +KPX j quoteright -20 +KPX j quotedblright -20 +KPX j period -20 +KPX j comma -20 + +KPX k quoteright -38 +KPX k quotedblright -38 + +KPX l quoteright -12 +KPX l quotedblright -12 + +KPX m quoteright -78 +KPX m quotedblright -78 + +KPX n quoteright -88 +KPX n quotedblright -88 + +KPX o y -12 +KPX o x -20 +KPX o w -25 +KPX o v -25 +KPX o quoteright -50 +KPX o quotedblright -50 +KPX o period -10 +KPX o comma -10 + +KPX p w -6 +KPX p quoteright -30 +KPX p quotedblright -52 +KPX p period -15 +KPX p comma -15 + +KPX parenleft Y 64 +KPX parenleft W 64 +KPX parenleft V 64 +KPX parenleft T 30 +KPX parenleft J 50 + +KPX period space -40 +KPX period quoteright -100 +KPX period quotedblright -100 + +KPX q quoteright -40 +KPX q quotedblright -40 +KPX q period -10 +KPX q comma -5 + +KPX quotedblleft z -30 +KPX quotedblleft x -60 +KPX quotedblleft w -12 +KPX quotedblleft v -12 +KPX quotedblleft u -12 +KPX quotedblleft t 5 +KPX quotedblleft s -30 +KPX quotedblleft r -12 +KPX quotedblleft q -50 +KPX quotedblleft p -12 +KPX quotedblleft o -30 +KPX quotedblleft n -12 +KPX quotedblleft m -12 +KPX quotedblleft l 10 +KPX quotedblleft k 10 +KPX quotedblleft h 10 +KPX quotedblleft g -30 +KPX quotedblleft e -30 +KPX quotedblleft d -50 +KPX quotedblleft c -30 +KPX quotedblleft b 24 +KPX quotedblleft a -50 +KPX quotedblleft Y 30 +KPX quotedblleft X 45 +KPX quotedblleft W 55 +KPX quotedblleft V 40 +KPX quotedblleft T 36 +KPX quotedblleft A -100 + +KPX quotedblright space -50 +KPX quotedblright period -200 +KPX quotedblright comma -200 + +KPX quoteleft z -30 +KPX quoteleft y 30 +KPX quoteleft x -10 +KPX quoteleft w -12 +KPX quoteleft u -12 +KPX quoteleft t -30 +KPX quoteleft s -30 +KPX quoteleft r -12 +KPX quoteleft q -30 +KPX quoteleft p -12 +KPX quoteleft o -30 +KPX quoteleft n -12 +KPX quoteleft m -12 +KPX quoteleft l 10 +KPX quoteleft k 10 +KPX quoteleft h 10 +KPX quoteleft g -30 +KPX quoteleft e -30 +KPX quoteleft d -30 +KPX quoteleft c -30 +KPX quoteleft b 24 +KPX quoteleft a -30 +KPX quoteleft Y 12 +KPX quoteleft X 46 +KPX quoteleft W 46 +KPX quoteleft V 28 +KPX quoteleft T 36 +KPX quoteleft A -100 + +KPX quoteright v -20 +KPX quoteright space -50 +KPX quoteright s -45 +KPX quoteright r -12 +KPX quoteright period -140 +KPX quoteright m -12 +KPX quoteright l -12 +KPX quoteright d -65 +KPX quoteright comma -140 + +KPX r z 20 +KPX r y 18 +KPX r x 12 +KPX r w 6 +KPX r v 6 +KPX r t 8 +KPX r semicolon 20 +KPX r quoteright -6 +KPX r quotedblright -6 +KPX r q -24 +KPX r period -100 +KPX r o -6 +KPX r l -12 +KPX r k -12 +KPX r hyphen -40 +KPX r h -10 +KPX r f 8 +KPX r endash -20 +KPX r e -26 +KPX r d -25 +KPX r comma -100 +KPX r colon 20 +KPX r c -12 +KPX r a -25 + +KPX s quoteright -25 +KPX s quotedblright -30 + +KPX semicolon space -30 + +KPX space quotesinglbase -60 +KPX space quoteleft -60 +KPX space quotedblleft -60 +KPX space quotedblbase -60 +KPX space Y -70 +KPX space W -50 +KPX space V -70 +KPX space T -50 +KPX space A -50 + +KPX t quoteright 15 +KPX t quotedblright 15 +KPX t period 15 +KPX t comma 15 + +KPX u quoteright -65 +KPX u quotedblright -78 +KPX u period 20 +KPX u comma 20 + +KPX v quoteright -10 +KPX v quotedblright -10 +KPX v q -6 +KPX v period -62 +KPX v o -6 +KPX v e -6 +KPX v d -6 +KPX v comma -62 +KPX v c -6 +KPX v a -6 + +KPX w quoteright -10 +KPX w quotedblright -10 +KPX w period -40 +KPX w comma -50 + +KPX x y 12 +KPX x w -6 +KPX x quoteright -30 +KPX x quotedblright -30 +KPX x q -6 +KPX x o -6 +KPX x e -6 +KPX x d -6 +KPX x c -6 + +KPX y quoteright -10 +KPX y quotedblright -10 +KPX y q -10 +KPX y period -56 +KPX y d -10 +KPX y comma -56 + +KPX z quoteright -40 +KPX z quotedblright -40 +KPX z o -6 +KPX z e -6 +KPX z d -6 +KPX z c -6 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putr8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putr8a.afm new file mode 100644 index 00000000..be1bb781 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putr8a.afm @@ -0,0 +1,1029 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Fri Jan 17 13:38:17 1992 +Comment UniqueID 37674 +Comment VMusage 32991 39883 +FontName Utopia-Regular +FullName Utopia Regular +FamilyName Utopia +Weight Regular +ItalicAngle 0 +IsFixedPitch false +FontBBox -158 -250 1158 890 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.002 +Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 490 +Ascender 742 +Descender -230 +StartCharMetrics 228 +C 32 ; WX 225 ; N space ; B 0 0 0 0 ; +C 33 ; WX 242 ; N exclam ; B 58 -12 184 707 ; +C 34 ; WX 458 ; N quotedbl ; B 101 464 358 742 ; +C 35 ; WX 530 ; N numbersign ; B 11 0 519 668 ; +C 36 ; WX 530 ; N dollar ; B 44 -102 487 743 ; +C 37 ; WX 838 ; N percent ; B 50 -25 788 700 ; +C 38 ; WX 706 ; N ampersand ; B 46 -12 692 680 ; +C 39 ; WX 278 ; N quoteright ; B 72 472 207 742 ; +C 40 ; WX 350 ; N parenleft ; B 105 -128 325 692 ; +C 41 ; WX 350 ; N parenright ; B 25 -128 245 692 ; +C 42 ; WX 412 ; N asterisk ; B 50 356 363 707 ; +C 43 ; WX 570 ; N plus ; B 43 0 527 490 ; +C 44 ; WX 265 ; N comma ; B 51 -141 193 141 ; +C 45 ; WX 392 ; N hyphen ; B 74 216 319 286 ; +C 46 ; WX 265 ; N period ; B 70 -12 196 116 ; +C 47 ; WX 460 ; N slash ; B 92 -15 369 707 ; +C 48 ; WX 530 ; N zero ; B 41 -12 489 680 ; +C 49 ; WX 530 ; N one ; B 109 0 437 680 ; +C 50 ; WX 530 ; N two ; B 27 0 485 680 ; +C 51 ; WX 530 ; N three ; B 27 -12 473 680 ; +C 52 ; WX 530 ; N four ; B 19 0 493 668 ; +C 53 ; WX 530 ; N five ; B 40 -12 480 668 ; +C 54 ; WX 530 ; N six ; B 44 -12 499 680 ; +C 55 ; WX 530 ; N seven ; B 41 -12 497 668 ; +C 56 ; WX 530 ; N eight ; B 42 -12 488 680 ; +C 57 ; WX 530 ; N nine ; B 36 -12 477 680 ; +C 58 ; WX 265 ; N colon ; B 70 -12 196 490 ; +C 59 ; WX 265 ; N semicolon ; B 51 -141 196 490 ; +C 60 ; WX 570 ; N less ; B 46 1 524 499 ; +C 61 ; WX 570 ; N equal ; B 43 111 527 389 ; +C 62 ; WX 570 ; N greater ; B 46 1 524 499 ; +C 63 ; WX 389 ; N question ; B 29 -12 359 707 ; +C 64 ; WX 793 ; N at ; B 46 -15 755 707 ; +C 65 ; WX 635 ; N A ; B -29 0 650 692 ; +C 66 ; WX 646 ; N B ; B 35 0 595 692 ; +C 67 ; WX 684 ; N C ; B 48 -15 649 707 ; +C 68 ; WX 779 ; N D ; B 35 0 731 692 ; +C 69 ; WX 606 ; N E ; B 35 0 577 692 ; +C 70 ; WX 580 ; N F ; B 35 0 543 692 ; +C 71 ; WX 734 ; N G ; B 48 -15 725 707 ; +C 72 ; WX 798 ; N H ; B 35 0 763 692 ; +C 73 ; WX 349 ; N I ; B 35 0 314 692 ; +C 74 ; WX 350 ; N J ; B 0 -114 323 692 ; +C 75 ; WX 658 ; N K ; B 35 -5 671 692 ; +C 76 ; WX 568 ; N L ; B 35 0 566 692 ; +C 77 ; WX 944 ; N M ; B 33 0 909 692 ; +C 78 ; WX 780 ; N N ; B 34 0 753 692 ; +C 79 ; WX 762 ; N O ; B 48 -15 714 707 ; +C 80 ; WX 600 ; N P ; B 35 0 574 692 ; +C 81 ; WX 762 ; N Q ; B 48 -193 714 707 ; +C 82 ; WX 644 ; N R ; B 35 0 638 692 ; +C 83 ; WX 541 ; N S ; B 50 -15 504 707 ; +C 84 ; WX 621 ; N T ; B 22 0 599 692 ; +C 85 ; WX 791 ; N U ; B 29 -15 762 692 ; +C 86 ; WX 634 ; N V ; B -18 0 678 692 ; +C 87 ; WX 940 ; N W ; B -13 0 977 692 ; +C 88 ; WX 624 ; N X ; B -19 0 657 692 ; +C 89 ; WX 588 ; N Y ; B -12 0 632 692 ; +C 90 ; WX 610 ; N Z ; B 9 0 594 692 ; +C 91 ; WX 330 ; N bracketleft ; B 133 -128 292 692 ; +C 92 ; WX 460 ; N backslash ; B 91 -15 369 707 ; +C 93 ; WX 330 ; N bracketright ; B 38 -128 197 692 ; +C 94 ; WX 570 ; N asciicircum ; B 56 228 514 668 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 72 478 207 748 ; +C 97 ; WX 523 ; N a ; B 49 -12 525 502 ; +C 98 ; WX 598 ; N b ; B 20 -12 549 742 ; +C 99 ; WX 496 ; N c ; B 49 -12 473 502 ; +C 100 ; WX 598 ; N d ; B 49 -12 583 742 ; +C 101 ; WX 514 ; N e ; B 49 -12 481 502 ; +C 102 ; WX 319 ; N f ; B 30 0 389 742 ; L i fi ; L l fl ; +C 103 ; WX 520 ; N g ; B 42 -242 525 512 ; +C 104 ; WX 607 ; N h ; B 21 0 592 742 ; +C 105 ; WX 291 ; N i ; B 32 0 276 715 ; +C 106 ; WX 280 ; N j ; B -33 -242 214 715 ; +C 107 ; WX 524 ; N k ; B 20 -5 538 742 ; +C 108 ; WX 279 ; N l ; B 20 0 264 742 ; +C 109 ; WX 923 ; N m ; B 32 0 908 502 ; +C 110 ; WX 619 ; N n ; B 32 0 604 502 ; +C 111 ; WX 577 ; N o ; B 49 -12 528 502 ; +C 112 ; WX 608 ; N p ; B 25 -230 559 502 ; +C 113 ; WX 591 ; N q ; B 49 -230 583 502 ; +C 114 ; WX 389 ; N r ; B 32 0 386 502 ; +C 115 ; WX 436 ; N s ; B 47 -12 400 502 ; +C 116 ; WX 344 ; N t ; B 31 -12 342 616 ; +C 117 ; WX 606 ; N u ; B 26 -12 591 502 ; +C 118 ; WX 504 ; N v ; B 1 0 529 490 ; +C 119 ; WX 768 ; N w ; B -2 0 792 490 ; +C 120 ; WX 486 ; N x ; B 1 0 509 490 ; +C 121 ; WX 506 ; N y ; B -5 -242 528 490 ; +C 122 ; WX 480 ; N z ; B 19 0 462 490 ; +C 123 ; WX 340 ; N braceleft ; B 79 -128 298 692 ; +C 124 ; WX 228 ; N bar ; B 80 -250 148 750 ; +C 125 ; WX 340 ; N braceright ; B 42 -128 261 692 ; +C 126 ; WX 570 ; N asciitilde ; B 73 175 497 317 ; +C 161 ; WX 242 ; N exclamdown ; B 58 -217 184 502 ; +C 162 ; WX 530 ; N cent ; B 37 -10 487 675 ; +C 163 ; WX 530 ; N sterling ; B 27 0 510 680 ; +C 164 ; WX 150 ; N fraction ; B -158 -27 308 695 ; +C 165 ; WX 530 ; N yen ; B -2 0 525 668 ; +C 166 ; WX 530 ; N florin ; B -2 -135 522 691 ; +C 167 ; WX 554 ; N section ; B 46 -115 507 707 ; +C 168 ; WX 530 ; N currency ; B 25 90 505 578 ; +C 169 ; WX 278 ; N quotesingle ; B 93 464 185 742 ; +C 170 ; WX 458 ; N quotedblleft ; B 72 478 387 748 ; +C 171 ; WX 442 ; N guillemotleft ; B 41 41 401 435 ; +C 172 ; WX 257 ; N guilsinglleft ; B 41 41 216 435 ; +C 173 ; WX 257 ; N guilsinglright ; B 41 41 216 435 ; +C 174 ; WX 610 ; N fi ; B 30 0 595 742 ; +C 175 ; WX 610 ; N fl ; B 30 0 595 742 ; +C 177 ; WX 500 ; N endash ; B 0 221 500 279 ; +C 178 ; WX 504 ; N dagger ; B 45 -125 459 717 ; +C 179 ; WX 488 ; N daggerdbl ; B 45 -119 443 717 ; +C 180 ; WX 265 ; N periodcentered ; B 70 188 196 316 ; +C 182 ; WX 555 ; N paragraph ; B 64 -101 529 692 ; +C 183 ; WX 409 ; N bullet ; B 45 192 364 512 ; +C 184 ; WX 278 ; N quotesinglbase ; B 72 -125 207 145 ; +C 185 ; WX 458 ; N quotedblbase ; B 72 -125 387 145 ; +C 186 ; WX 458 ; N quotedblright ; B 72 472 387 742 ; +C 187 ; WX 442 ; N guillemotright ; B 41 41 401 435 ; +C 188 ; WX 1000 ; N ellipsis ; B 104 -12 896 116 ; +C 189 ; WX 1208 ; N perthousand ; B 50 -25 1158 700 ; +C 191 ; WX 389 ; N questiondown ; B 30 -217 360 502 ; +C 193 ; WX 400 ; N grave ; B 49 542 271 723 ; +C 194 ; WX 400 ; N acute ; B 129 542 351 723 ; +C 195 ; WX 400 ; N circumflex ; B 47 541 353 720 ; +C 196 ; WX 400 ; N tilde ; B 22 563 377 682 ; +C 197 ; WX 400 ; N macron ; B 56 597 344 656 ; +C 198 ; WX 400 ; N breve ; B 63 568 337 704 ; +C 199 ; WX 400 ; N dotaccent ; B 140 570 260 683 ; +C 200 ; WX 400 ; N dieresis ; B 36 570 364 683 ; +C 202 ; WX 400 ; N ring ; B 92 550 308 752 ; +C 203 ; WX 400 ; N cedilla ; B 163 -230 329 0 ; +C 205 ; WX 400 ; N hungarumlaut ; B 101 546 380 750 ; +C 206 ; WX 400 ; N ogonek ; B 103 -230 295 0 ; +C 207 ; WX 400 ; N caron ; B 47 541 353 720 ; +C 208 ; WX 1000 ; N emdash ; B 0 221 1000 279 ; +C 225 ; WX 876 ; N AE ; B -63 0 847 692 ; +C 227 ; WX 390 ; N ordfeminine ; B 40 265 364 590 ; +C 232 ; WX 574 ; N Lslash ; B 36 0 572 692 ; +C 233 ; WX 762 ; N Oslash ; B 48 -53 714 739 ; +C 234 ; WX 1025 ; N OE ; B 48 0 996 692 ; +C 235 ; WX 398 ; N ordmasculine ; B 35 265 363 590 ; +C 241 ; WX 797 ; N ae ; B 49 -12 764 502 ; +C 245 ; WX 291 ; N dotlessi ; B 32 0 276 502 ; +C 248 ; WX 294 ; N lslash ; B 14 0 293 742 ; +C 249 ; WX 577 ; N oslash ; B 49 -41 528 532 ; +C 250 ; WX 882 ; N oe ; B 49 -12 849 502 ; +C 251 ; WX 601 ; N germandbls ; B 22 -12 573 742 ; +C -1 ; WX 380 ; N onesuperior ; B 81 272 307 680 ; +C -1 ; WX 570 ; N minus ; B 43 221 527 279 ; +C -1 ; WX 350 ; N degree ; B 37 404 313 680 ; +C -1 ; WX 577 ; N oacute ; B 49 -12 528 723 ; +C -1 ; WX 762 ; N Odieresis ; B 48 -15 714 841 ; +C -1 ; WX 577 ; N odieresis ; B 49 -12 528 683 ; +C -1 ; WX 606 ; N Eacute ; B 35 0 577 890 ; +C -1 ; WX 606 ; N ucircumflex ; B 26 -12 591 720 ; +C -1 ; WX 860 ; N onequarter ; B 65 -27 795 695 ; +C -1 ; WX 570 ; N logicalnot ; B 43 102 527 389 ; +C -1 ; WX 606 ; N Ecircumflex ; B 35 0 577 876 ; +C -1 ; WX 860 ; N onehalf ; B 58 -27 807 695 ; +C -1 ; WX 762 ; N Otilde ; B 48 -15 714 842 ; +C -1 ; WX 606 ; N uacute ; B 26 -12 591 723 ; +C -1 ; WX 514 ; N eacute ; B 49 -12 481 723 ; +C -1 ; WX 291 ; N iacute ; B 32 0 317 723 ; +C -1 ; WX 606 ; N Egrave ; B 35 0 577 890 ; +C -1 ; WX 291 ; N icircumflex ; B -3 0 304 720 ; +C -1 ; WX 606 ; N mu ; B 26 -246 591 502 ; +C -1 ; WX 228 ; N brokenbar ; B 80 -175 148 675 ; +C -1 ; WX 606 ; N thorn ; B 23 -230 557 722 ; +C -1 ; WX 627 ; N Aring ; B -32 0 647 861 ; +C -1 ; WX 506 ; N yacute ; B -5 -242 528 723 ; +C -1 ; WX 588 ; N Ydieresis ; B -12 0 632 841 ; +C -1 ; WX 1100 ; N trademark ; B 45 277 1048 692 ; +C -1 ; WX 818 ; N registered ; B 45 -15 773 707 ; +C -1 ; WX 577 ; N ocircumflex ; B 49 -12 528 720 ; +C -1 ; WX 635 ; N Agrave ; B -29 0 650 890 ; +C -1 ; WX 541 ; N Scaron ; B 50 -15 504 882 ; +C -1 ; WX 791 ; N Ugrave ; B 29 -15 762 890 ; +C -1 ; WX 606 ; N Edieresis ; B 35 0 577 841 ; +C -1 ; WX 791 ; N Uacute ; B 29 -15 762 890 ; +C -1 ; WX 577 ; N otilde ; B 49 -12 528 682 ; +C -1 ; WX 619 ; N ntilde ; B 32 0 604 682 ; +C -1 ; WX 506 ; N ydieresis ; B -5 -242 528 683 ; +C -1 ; WX 635 ; N Aacute ; B -29 0 650 890 ; +C -1 ; WX 577 ; N eth ; B 49 -12 528 742 ; +C -1 ; WX 523 ; N acircumflex ; B 49 -12 525 720 ; +C -1 ; WX 523 ; N aring ; B 49 -12 525 752 ; +C -1 ; WX 762 ; N Ograve ; B 48 -15 714 890 ; +C -1 ; WX 496 ; N ccedilla ; B 49 -230 473 502 ; +C -1 ; WX 570 ; N multiply ; B 63 22 507 478 ; +C -1 ; WX 570 ; N divide ; B 43 26 527 474 ; +C -1 ; WX 380 ; N twosuperior ; B 32 272 348 680 ; +C -1 ; WX 780 ; N Ntilde ; B 34 0 753 842 ; +C -1 ; WX 606 ; N ugrave ; B 26 -12 591 723 ; +C -1 ; WX 791 ; N Ucircumflex ; B 29 -15 762 876 ; +C -1 ; WX 635 ; N Atilde ; B -29 0 650 842 ; +C -1 ; WX 480 ; N zcaron ; B 19 0 462 720 ; +C -1 ; WX 291 ; N idieresis ; B -19 0 310 683 ; +C -1 ; WX 635 ; N Acircumflex ; B -29 0 650 876 ; +C -1 ; WX 349 ; N Icircumflex ; B 22 0 328 876 ; +C -1 ; WX 588 ; N Yacute ; B -12 0 632 890 ; +C -1 ; WX 762 ; N Oacute ; B 48 -15 714 890 ; +C -1 ; WX 635 ; N Adieresis ; B -29 0 650 841 ; +C -1 ; WX 610 ; N Zcaron ; B 9 0 594 882 ; +C -1 ; WX 523 ; N agrave ; B 49 -12 525 723 ; +C -1 ; WX 380 ; N threesuperior ; B 36 265 339 680 ; +C -1 ; WX 577 ; N ograve ; B 49 -12 528 723 ; +C -1 ; WX 860 ; N threequarters ; B 50 -27 808 695 ; +C -1 ; WX 785 ; N Eth ; B 20 0 737 692 ; +C -1 ; WX 570 ; N plusminus ; B 43 0 527 556 ; +C -1 ; WX 606 ; N udieresis ; B 26 -12 591 683 ; +C -1 ; WX 514 ; N edieresis ; B 49 -12 481 683 ; +C -1 ; WX 523 ; N aacute ; B 49 -12 525 723 ; +C -1 ; WX 291 ; N igrave ; B -35 0 276 723 ; +C -1 ; WX 349 ; N Idieresis ; B 13 0 337 841 ; +C -1 ; WX 523 ; N adieresis ; B 49 -12 525 683 ; +C -1 ; WX 349 ; N Iacute ; B 35 0 371 890 ; +C -1 ; WX 818 ; N copyright ; B 45 -15 773 707 ; +C -1 ; WX 349 ; N Igrave ; B -17 0 314 890 ; +C -1 ; WX 680 ; N Ccedilla ; B 48 -230 649 707 ; +C -1 ; WX 436 ; N scaron ; B 47 -12 400 720 ; +C -1 ; WX 514 ; N egrave ; B 49 -12 481 723 ; +C -1 ; WX 762 ; N Ocircumflex ; B 48 -15 714 876 ; +C -1 ; WX 593 ; N Thorn ; B 35 0 556 692 ; +C -1 ; WX 523 ; N atilde ; B 49 -12 525 682 ; +C -1 ; WX 791 ; N Udieresis ; B 29 -15 762 841 ; +C -1 ; WX 514 ; N ecircumflex ; B 49 -12 481 720 ; +EndCharMetrics +StartKernData +StartKernPairs 712 + +KPX A z 6 +KPX A y -50 +KPX A w -45 +KPX A v -60 +KPX A u -25 +KPX A t -12 +KPX A quoteright -120 +KPX A quotedblright -120 +KPX A q -6 +KPX A p -18 +KPX A o -12 +KPX A e -6 +KPX A d -12 +KPX A c -12 +KPX A b -12 +KPX A Y -70 +KPX A X -6 +KPX A W -58 +KPX A V -72 +KPX A U -50 +KPX A T -70 +KPX A Q -24 +KPX A O -24 +KPX A G -24 +KPX A C -24 + +KPX B y -18 +KPX B u -12 +KPX B r -12 +KPX B period -30 +KPX B o -6 +KPX B l -12 +KPX B i -12 +KPX B h -12 +KPX B e -6 +KPX B comma -20 +KPX B a -12 +KPX B W -25 +KPX B V -20 +KPX B U -20 +KPX B T -20 + +KPX C z -18 +KPX C y -24 +KPX C u -18 +KPX C r -6 +KPX C o -12 +KPX C e -12 +KPX C a -12 +KPX C Q -6 +KPX C O -6 +KPX C G -6 +KPX C C -6 + +KPX D y 6 +KPX D u -12 +KPX D r -12 +KPX D quoteright -20 +KPX D quotedblright -20 +KPX D period -60 +KPX D i -6 +KPX D h -12 +KPX D e -6 +KPX D comma -50 +KPX D a -6 +KPX D Y -45 +KPX D W -35 +KPX D V -35 + +KPX E z -6 +KPX E y -30 +KPX E x -6 +KPX E w -24 +KPX E v -24 +KPX E u -12 +KPX E t -18 +KPX E r -4 +KPX E q -6 +KPX E p -18 +KPX E o -6 +KPX E n -4 +KPX E m -4 +KPX E l 5 +KPX E k 5 +KPX E j -6 +KPX E i -6 +KPX E g -6 +KPX E f -12 +KPX E e -6 +KPX E d -6 +KPX E c -6 +KPX E b -12 +KPX E Y -6 +KPX E W -6 +KPX E V -6 + +KPX F y -18 +KPX F u -12 +KPX F r -20 +KPX F period -180 +KPX F o -36 +KPX F l -12 +KPX F i -10 +KPX F endash 20 +KPX F e -36 +KPX F comma -180 +KPX F a -48 +KPX F A -60 + +KPX G y -18 +KPX G u -12 +KPX G r -5 +KPX G o 5 +KPX G n -5 +KPX G l -6 +KPX G i -12 +KPX G h -12 +KPX G e 5 +KPX G a -12 + +KPX H y -24 +KPX H u -26 +KPX H o -30 +KPX H i -18 +KPX H e -30 +KPX H a -24 + +KPX I z -6 +KPX I y -6 +KPX I x -6 +KPX I w -18 +KPX I v -24 +KPX I u -26 +KPX I t -24 +KPX I s -18 +KPX I r -12 +KPX I p -26 +KPX I o -30 +KPX I n -18 +KPX I m -18 +KPX I l -6 +KPX I k -6 +KPX I h -6 +KPX I g -10 +KPX I f -6 +KPX I e -30 +KPX I d -30 +KPX I c -30 +KPX I b -6 +KPX I a -24 + +KPX J y -12 +KPX J u -36 +KPX J o -30 +KPX J i -20 +KPX J e -30 +KPX J bracketright 20 +KPX J braceright 20 +KPX J a -36 + +KPX K y -60 +KPX K w -70 +KPX K v -70 +KPX K u -42 +KPX K o -30 +KPX K i 6 +KPX K e -24 +KPX K a -12 +KPX K Q -42 +KPX K O -42 +KPX K G -42 +KPX K C -42 + +KPX L y -52 +KPX L w -58 +KPX L u -12 +KPX L quoteright -130 +KPX L quotedblright -50 +KPX L l 6 +KPX L j -6 +KPX L Y -70 +KPX L W -90 +KPX L V -100 +KPX L U -24 +KPX L T -100 +KPX L Q -18 +KPX L O -10 +KPX L G -18 +KPX L C -18 +KPX L A 12 + +KPX M y -24 +KPX M u -36 +KPX M o -30 +KPX M n -6 +KPX M j -12 +KPX M i -12 +KPX M e -30 +KPX M d -30 +KPX M c -30 +KPX M a -12 + +KPX N y -24 +KPX N u -30 +KPX N o -30 +KPX N i -24 +KPX N e -30 +KPX N a -30 + +KPX O z -6 +KPX O u -6 +KPX O t -6 +KPX O s -6 +KPX O q -6 +KPX O period -60 +KPX O p -6 +KPX O o -6 +KPX O n -5 +KPX O m -5 +KPX O l -6 +KPX O k -6 +KPX O i -5 +KPX O h -12 +KPX O g -6 +KPX O e -6 +KPX O d -6 +KPX O comma -50 +KPX O c -6 +KPX O a -12 +KPX O Y -55 +KPX O X -24 +KPX O W -30 +KPX O V -18 +KPX O T -30 +KPX O A -18 + +KPX P u -12 +KPX P t -6 +KPX P s -24 +KPX P r -12 +KPX P period -200 +KPX P o -30 +KPX P n -12 +KPX P l -6 +KPX P hyphen -40 +KPX P h -6 +KPX P e -30 +KPX P comma -200 +KPX P a -36 +KPX P I -6 +KPX P H -12 +KPX P E -6 +KPX P A -55 + +KPX Q u -6 +KPX Q a -18 +KPX Q Y -30 +KPX Q X -24 +KPX Q W -24 +KPX Q V -18 +KPX Q U -30 +KPX Q T -24 +KPX Q A -18 + +KPX R y -20 +KPX R u -12 +KPX R quoteright -20 +KPX R quotedblright -20 +KPX R o -20 +KPX R hyphen -30 +KPX R e -20 +KPX R d -20 +KPX R a -12 +KPX R Y -45 +KPX R W -24 +KPX R V -32 +KPX R U -30 +KPX R T -32 +KPX R Q -24 +KPX R O -24 +KPX R G -24 +KPX R C -24 + +KPX S y -25 +KPX S w -30 +KPX S v -30 +KPX S u -24 +KPX S t -24 +KPX S r -20 +KPX S quoteright -10 +KPX S quotedblright -10 +KPX S q -5 +KPX S p -24 +KPX S o -12 +KPX S n -20 +KPX S m -20 +KPX S l -18 +KPX S k -24 +KPX S j -12 +KPX S i -20 +KPX S h -12 +KPX S e -12 +KPX S a -18 + +KPX T z -64 +KPX T y -84 +KPX T w -100 +KPX T u -82 +KPX T semicolon -56 +KPX T s -82 +KPX T r -82 +KPX T quoteright 24 +KPX T period -110 +KPX T parenright 54 +KPX T o -100 +KPX T m -82 +KPX T i -34 +KPX T hyphen -100 +KPX T endash -50 +KPX T emdash -50 +KPX T e -100 +KPX T comma -110 +KPX T colon -50 +KPX T bracketright 54 +KPX T braceright 54 +KPX T a -100 +KPX T Y 12 +KPX T X 18 +KPX T W 6 +KPX T V 6 +KPX T T 12 +KPX T S -12 +KPX T Q -18 +KPX T O -18 +KPX T G -18 +KPX T C -18 +KPX T A -65 + +KPX U z -30 +KPX U y -20 +KPX U x -30 +KPX U v -20 +KPX U t -36 +KPX U s -40 +KPX U r -40 +KPX U p -42 +KPX U n -40 +KPX U m -40 +KPX U l -12 +KPX U k -12 +KPX U i -28 +KPX U h -6 +KPX U g -50 +KPX U f -12 +KPX U d -45 +KPX U c -45 +KPX U b -12 +KPX U a -40 +KPX U A -40 + +KPX V y -36 +KPX V u -40 +KPX V semicolon -45 +KPX V r -70 +KPX V quoteright 36 +KPX V quotedblright 20 +KPX V period -140 +KPX V parenright 85 +KPX V o -70 +KPX V i 6 +KPX V hyphen -60 +KPX V endash -20 +KPX V emdash -20 +KPX V e -70 +KPX V comma -140 +KPX V colon -45 +KPX V bracketright 64 +KPX V braceright 64 +KPX V a -60 +KPX V T 6 +KPX V Q -12 +KPX V O -12 +KPX V G -12 +KPX V C -12 +KPX V A -60 + +KPX W y -50 +KPX W u -46 +KPX W semicolon -40 +KPX W r -45 +KPX W quoteright 36 +KPX W quotedblright 20 +KPX W period -110 +KPX W parenright 85 +KPX W o -65 +KPX W m -45 +KPX W i -10 +KPX W hyphen -40 +KPX W e -65 +KPX W d -65 +KPX W comma -100 +KPX W colon -40 +KPX W bracketright 64 +KPX W braceright 64 +KPX W a -60 +KPX W T 18 +KPX W Q -6 +KPX W O -6 +KPX W G -6 +KPX W C -6 +KPX W A -48 + +KPX X y -18 +KPX X u -24 +KPX X quoteright 15 +KPX X e -6 +KPX X a -6 +KPX X Q -24 +KPX X O -30 +KPX X G -30 +KPX X C -30 +KPX X A 6 + +KPX Y v -50 +KPX Y u -54 +KPX Y t -46 +KPX Y semicolon -37 +KPX Y quoteright 36 +KPX Y quotedblright 20 +KPX Y q -100 +KPX Y period -90 +KPX Y parenright 60 +KPX Y o -90 +KPX Y l 10 +KPX Y hyphen -50 +KPX Y emdash -20 +KPX Y e -90 +KPX Y d -90 +KPX Y comma -90 +KPX Y colon -50 +KPX Y bracketright 64 +KPX Y braceright 64 +KPX Y a -68 +KPX Y Y 12 +KPX Y X 12 +KPX Y W 12 +KPX Y V 12 +KPX Y T 12 +KPX Y Q -18 +KPX Y O -18 +KPX Y G -18 +KPX Y C -18 +KPX Y A -32 + +KPX Z y -36 +KPX Z w -36 +KPX Z u -6 +KPX Z o -12 +KPX Z i -12 +KPX Z e -6 +KPX Z a -6 +KPX Z Q -20 +KPX Z O -20 +KPX Z G -30 +KPX Z C -20 +KPX Z A 20 + +KPX a quoteright -70 +KPX a quotedblright -80 + +KPX b y -25 +KPX b w -30 +KPX b v -35 +KPX b quoteright -70 +KPX b quotedblright -70 +KPX b period -40 +KPX b comma -40 + +KPX braceleft Y 64 +KPX braceleft W 64 +KPX braceleft V 64 +KPX braceleft T 54 +KPX braceleft J 80 + +KPX bracketleft Y 64 +KPX bracketleft W 64 +KPX bracketleft V 64 +KPX bracketleft T 54 +KPX bracketleft J 80 + +KPX c quoteright -28 +KPX c quotedblright -28 +KPX c period -10 + +KPX comma quoteright -50 +KPX comma quotedblright -50 + +KPX d quoteright -24 +KPX d quotedblright -24 + +KPX e z -4 +KPX e quoteright -60 +KPX e quotedblright -60 +KPX e period -20 +KPX e comma -20 + +KPX f quotesingle 30 +KPX f quoteright 65 +KPX f quotedblright 56 +KPX f quotedbl 30 +KPX f parenright 100 +KPX f bracketright 100 +KPX f braceright 100 + +KPX g quoteright -18 +KPX g quotedblright -10 + +KPX h quoteright -80 +KPX h quotedblright -80 + +KPX j quoteright -20 +KPX j quotedblright -20 +KPX j period -30 +KPX j comma -30 + +KPX k quoteright -40 +KPX k quotedblright -40 + +KPX l quoteright -10 +KPX l quotedblright -10 + +KPX m quoteright -80 +KPX m quotedblright -80 + +KPX n quoteright -80 +KPX n quotedblright -80 + +KPX o z -12 +KPX o y -30 +KPX o x -18 +KPX o w -30 +KPX o v -30 +KPX o quoteright -70 +KPX o quotedblright -70 +KPX o period -40 +KPX o comma -40 + +KPX p z -20 +KPX p y -25 +KPX p w -30 +KPX p quoteright -70 +KPX p quotedblright -70 +KPX p period -40 +KPX p comma -40 + +KPX parenleft Y 64 +KPX parenleft W 64 +KPX parenleft V 64 +KPX parenleft T 64 +KPX parenleft J 80 + +KPX period quoteright -50 +KPX period quotedblright -50 + +KPX q quoteright -50 +KPX q quotedblright -50 +KPX q period -20 +KPX q comma -10 + +KPX quotedblleft z -60 +KPX quotedblleft y -30 +KPX quotedblleft x -40 +KPX quotedblleft w -20 +KPX quotedblleft v -20 +KPX quotedblleft u -40 +KPX quotedblleft t -40 +KPX quotedblleft s -50 +KPX quotedblleft r -50 +KPX quotedblleft q -80 +KPX quotedblleft p -50 +KPX quotedblleft o -80 +KPX quotedblleft n -50 +KPX quotedblleft m -50 +KPX quotedblleft g -70 +KPX quotedblleft f -50 +KPX quotedblleft e -80 +KPX quotedblleft d -80 +KPX quotedblleft c -80 +KPX quotedblleft a -70 +KPX quotedblleft Z -20 +KPX quotedblleft Y 12 +KPX quotedblleft W 18 +KPX quotedblleft V 18 +KPX quotedblleft U -20 +KPX quotedblleft T 10 +KPX quotedblleft S -20 +KPX quotedblleft R -20 +KPX quotedblleft Q -20 +KPX quotedblleft P -20 +KPX quotedblleft O -30 +KPX quotedblleft N -20 +KPX quotedblleft M -20 +KPX quotedblleft L -20 +KPX quotedblleft K -20 +KPX quotedblleft J -40 +KPX quotedblleft I -20 +KPX quotedblleft H -20 +KPX quotedblleft G -30 +KPX quotedblleft F -20 +KPX quotedblleft E -20 +KPX quotedblleft D -20 +KPX quotedblleft C -30 +KPX quotedblleft B -20 +KPX quotedblleft A -130 + +KPX quotedblright period -130 +KPX quotedblright comma -130 + +KPX quoteleft z -40 +KPX quoteleft y -35 +KPX quoteleft x -30 +KPX quoteleft w -20 +KPX quoteleft v -20 +KPX quoteleft u -50 +KPX quoteleft t -40 +KPX quoteleft s -45 +KPX quoteleft r -50 +KPX quoteleft quoteleft -72 +KPX quoteleft q -70 +KPX quoteleft p -50 +KPX quoteleft o -70 +KPX quoteleft n -50 +KPX quoteleft m -50 +KPX quoteleft g -65 +KPX quoteleft f -40 +KPX quoteleft e -70 +KPX quoteleft d -70 +KPX quoteleft c -70 +KPX quoteleft a -60 +KPX quoteleft Z -20 +KPX quoteleft Y 18 +KPX quoteleft X 12 +KPX quoteleft W 18 +KPX quoteleft V 18 +KPX quoteleft U -20 +KPX quoteleft T 10 +KPX quoteleft R -20 +KPX quoteleft Q -20 +KPX quoteleft P -20 +KPX quoteleft O -30 +KPX quoteleft N -20 +KPX quoteleft M -20 +KPX quoteleft L -20 +KPX quoteleft K -20 +KPX quoteleft J -40 +KPX quoteleft I -20 +KPX quoteleft H -20 +KPX quoteleft G -40 +KPX quoteleft F -20 +KPX quoteleft E -20 +KPX quoteleft D -20 +KPX quoteleft C -30 +KPX quoteleft B -20 +KPX quoteleft A -130 + +KPX quoteright v -40 +KPX quoteright t -75 +KPX quoteright s -110 +KPX quoteright r -70 +KPX quoteright quoteright -72 +KPX quoteright period -130 +KPX quoteright m -70 +KPX quoteright l -6 +KPX quoteright d -120 +KPX quoteright comma -130 + +KPX r z 10 +KPX r y 18 +KPX r x 12 +KPX r w 18 +KPX r v 18 +KPX r u 8 +KPX r t 8 +KPX r semicolon 10 +KPX r quoteright -20 +KPX r quotedblright -20 +KPX r q -6 +KPX r period -60 +KPX r o -6 +KPX r n 8 +KPX r m 8 +KPX r k -6 +KPX r i 8 +KPX r hyphen -20 +KPX r h 6 +KPX r g -6 +KPX r f 8 +KPX r e -20 +KPX r d -20 +KPX r comma -60 +KPX r colon 10 +KPX r c -20 +KPX r a -10 + +KPX s quoteright -40 +KPX s quotedblright -40 +KPX s period -20 +KPX s comma -10 + +KPX space quotesinglbase -60 +KPX space quoteleft -40 +KPX space quotedblleft -40 +KPX space quotedblbase -60 +KPX space Y -60 +KPX space W -60 +KPX space V -60 +KPX space T -36 + +KPX t quoteright -18 +KPX t quotedblright -18 + +KPX u quoteright -30 +KPX u quotedblright -30 + +KPX v semicolon 10 +KPX v quoteright 20 +KPX v quotedblright 20 +KPX v q -10 +KPX v period -90 +KPX v o -5 +KPX v e -5 +KPX v d -10 +KPX v comma -90 +KPX v colon 10 +KPX v c -6 +KPX v a -6 + +KPX w semicolon 10 +KPX w quoteright 20 +KPX w quotedblright 20 +KPX w q -6 +KPX w period -80 +KPX w e -6 +KPX w d -6 +KPX w comma -75 +KPX w colon 10 +KPX w c -6 + +KPX x quoteright -10 +KPX x quotedblright -20 +KPX x q -6 +KPX x o -6 +KPX x d -12 +KPX x c -12 + +KPX y semicolon 10 +KPX y q -6 +KPX y period -95 +KPX y o -6 +KPX y hyphen -30 +KPX y e -6 +KPX y d -6 +KPX y comma -85 +KPX y colon 10 +KPX y c -6 + +KPX z quoteright -20 +KPX z quotedblright -30 +KPX z o -6 +KPX z e -6 +KPX z d -6 +KPX z c -6 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putri8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putri8a.afm new file mode 100644 index 00000000..b3dd45b5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/putri8a.afm @@ -0,0 +1,1008 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Fri Jan 17 13:15:45 1992 +Comment UniqueID 37666 +Comment VMusage 34143 41035 +FontName Utopia-Italic +FullName Utopia Italic +FamilyName Utopia +Weight Regular +ItalicAngle -13 +IsFixedPitch false +FontBBox -201 -250 1170 890 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.002 +Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated. +EncodingScheme AdobeStandardEncoding +CapHeight 692 +XHeight 502 +Ascender 742 +Descender -242 +StartCharMetrics 228 +C 32 ; WX 225 ; N space ; B 0 0 0 0 ; +C 33 ; WX 240 ; N exclam ; B 34 -12 290 707 ; +C 34 ; WX 402 ; N quotedbl ; B 171 469 454 742 ; +C 35 ; WX 530 ; N numbersign ; B 54 0 585 668 ; +C 36 ; WX 530 ; N dollar ; B 31 -109 551 743 ; +C 37 ; WX 826 ; N percent ; B 98 -25 795 702 ; +C 38 ; WX 725 ; N ampersand ; B 60 -12 703 680 ; +C 39 ; WX 216 ; N quoteright ; B 112 482 265 742 ; +C 40 ; WX 350 ; N parenleft ; B 106 -128 458 692 ; +C 41 ; WX 350 ; N parenright ; B -46 -128 306 692 ; +C 42 ; WX 412 ; N asterisk ; B 106 356 458 707 ; +C 43 ; WX 570 ; N plus ; B 58 0 542 490 ; +C 44 ; WX 265 ; N comma ; B 11 -134 173 142 ; +C 45 ; WX 392 ; N hyphen ; B 82 216 341 286 ; +C 46 ; WX 265 ; N period ; B 47 -12 169 113 ; +C 47 ; WX 270 ; N slash ; B 0 -15 341 707 ; +C 48 ; WX 530 ; N zero ; B 60 -12 541 680 ; +C 49 ; WX 530 ; N one ; B 74 0 429 680 ; +C 50 ; WX 530 ; N two ; B -2 0 538 680 ; +C 51 ; WX 530 ; N three ; B 19 -12 524 680 ; +C 52 ; WX 530 ; N four ; B 32 0 509 668 ; +C 53 ; WX 530 ; N five ; B 24 -12 550 668 ; +C 54 ; WX 530 ; N six ; B 56 -12 551 680 ; +C 55 ; WX 530 ; N seven ; B 130 -12 600 668 ; +C 56 ; WX 530 ; N eight ; B 46 -12 535 680 ; +C 57 ; WX 530 ; N nine ; B 51 -12 536 680 ; +C 58 ; WX 265 ; N colon ; B 47 -12 248 490 ; +C 59 ; WX 265 ; N semicolon ; B 11 -134 248 490 ; +C 60 ; WX 570 ; N less ; B 51 1 529 497 ; +C 61 ; WX 570 ; N equal ; B 58 111 542 389 ; +C 62 ; WX 570 ; N greater ; B 51 1 529 497 ; +C 63 ; WX 425 ; N question ; B 115 -12 456 707 ; +C 64 ; WX 794 ; N at ; B 88 -15 797 707 ; +C 65 ; WX 624 ; N A ; B -58 0 623 692 ; +C 66 ; WX 632 ; N B ; B 3 0 636 692 ; +C 67 ; WX 661 ; N C ; B 79 -15 723 707 ; +C 68 ; WX 763 ; N D ; B 5 0 767 692 ; +C 69 ; WX 596 ; N E ; B 3 0 657 692 ; +C 70 ; WX 571 ; N F ; B 3 0 660 692 ; +C 71 ; WX 709 ; N G ; B 79 -15 737 707 ; +C 72 ; WX 775 ; N H ; B 5 0 857 692 ; +C 73 ; WX 345 ; N I ; B 5 0 428 692 ; +C 74 ; WX 352 ; N J ; B -78 -119 436 692 ; +C 75 ; WX 650 ; N K ; B 5 -5 786 692 ; +C 76 ; WX 565 ; N L ; B 5 0 568 692 ; +C 77 ; WX 920 ; N M ; B -4 0 1002 692 ; +C 78 ; WX 763 ; N N ; B -4 0 855 692 ; +C 79 ; WX 753 ; N O ; B 79 -15 754 707 ; +C 80 ; WX 614 ; N P ; B 5 0 646 692 ; +C 81 ; WX 753 ; N Q ; B 79 -203 754 707 ; +C 82 ; WX 640 ; N R ; B 5 0 642 692 ; +C 83 ; WX 533 ; N S ; B 34 -15 542 707 ; +C 84 ; WX 606 ; N T ; B 102 0 708 692 ; +C 85 ; WX 794 ; N U ; B 131 -15 880 692 ; +C 86 ; WX 637 ; N V ; B 96 0 786 692 ; +C 87 ; WX 946 ; N W ; B 86 0 1075 692 ; +C 88 ; WX 632 ; N X ; B -36 0 735 692 ; +C 89 ; WX 591 ; N Y ; B 96 0 744 692 ; +C 90 ; WX 622 ; N Z ; B -20 0 703 692 ; +C 91 ; WX 330 ; N bracketleft ; B 69 -128 414 692 ; +C 92 ; WX 390 ; N backslash ; B 89 -15 371 707 ; +C 93 ; WX 330 ; N bracketright ; B -21 -128 324 692 ; +C 94 ; WX 570 ; N asciicircum ; B 83 228 547 668 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 216 ; N quoteleft ; B 130 488 283 748 ; +C 97 ; WX 561 ; N a ; B 31 -12 563 502 ; +C 98 ; WX 559 ; N b ; B 47 -12 557 742 ; +C 99 ; WX 441 ; N c ; B 46 -12 465 502 ; +C 100 ; WX 587 ; N d ; B 37 -12 612 742 ; +C 101 ; WX 453 ; N e ; B 45 -12 471 502 ; +C 102 ; WX 315 ; N f ; B -107 -242 504 742 ; L i fi ; L l fl ; +C 103 ; WX 499 ; N g ; B -5 -242 573 512 ; +C 104 ; WX 607 ; N h ; B 57 -12 588 742 ; +C 105 ; WX 317 ; N i ; B 79 -12 328 715 ; +C 106 ; WX 309 ; N j ; B -95 -242 330 715 ; +C 107 ; WX 545 ; N k ; B 57 -12 567 742 ; +C 108 ; WX 306 ; N l ; B 76 -12 331 742 ; +C 109 ; WX 912 ; N m ; B 63 -12 894 502 ; +C 110 ; WX 618 ; N n ; B 63 -12 600 502 ; +C 111 ; WX 537 ; N o ; B 49 -12 522 502 ; +C 112 ; WX 590 ; N p ; B 22 -242 586 502 ; +C 113 ; WX 559 ; N q ; B 38 -242 567 525 ; +C 114 ; WX 402 ; N r ; B 69 -12 448 502 ; +C 115 ; WX 389 ; N s ; B 19 -12 397 502 ; +C 116 ; WX 341 ; N t ; B 84 -12 404 616 ; +C 117 ; WX 618 ; N u ; B 89 -12 609 502 ; +C 118 ; WX 510 ; N v ; B 84 -12 528 502 ; +C 119 ; WX 785 ; N w ; B 87 -12 808 502 ; +C 120 ; WX 516 ; N x ; B -4 -12 531 502 ; +C 121 ; WX 468 ; N y ; B -40 -242 505 502 ; +C 122 ; WX 468 ; N z ; B 4 -12 483 490 ; +C 123 ; WX 340 ; N braceleft ; B 100 -128 423 692 ; +C 124 ; WX 270 ; N bar ; B 130 -250 198 750 ; +C 125 ; WX 340 ; N braceright ; B -20 -128 302 692 ; +C 126 ; WX 570 ; N asciitilde ; B 98 176 522 318 ; +C 161 ; WX 240 ; N exclamdown ; B -18 -217 238 502 ; +C 162 ; WX 530 ; N cent ; B 94 -21 563 669 ; +C 163 ; WX 530 ; N sterling ; B 9 0 549 680 ; +C 164 ; WX 100 ; N fraction ; B -201 -24 369 698 ; +C 165 ; WX 530 ; N yen ; B 72 0 645 668 ; +C 166 ; WX 530 ; N florin ; B 4 -135 588 691 ; +C 167 ; WX 530 ; N section ; B 55 -115 533 707 ; +C 168 ; WX 530 ; N currency ; B 56 90 536 578 ; +C 169 ; WX 216 ; N quotesingle ; B 161 469 274 742 ; +C 170 ; WX 402 ; N quotedblleft ; B 134 488 473 748 ; +C 171 ; WX 462 ; N guillemotleft ; B 79 41 470 435 ; +C 172 ; WX 277 ; N guilsinglleft ; B 71 41 267 435 ; +C 173 ; WX 277 ; N guilsinglright ; B 44 41 240 435 ; +C 174 ; WX 607 ; N fi ; B -107 -242 589 742 ; +C 175 ; WX 603 ; N fl ; B -107 -242 628 742 ; +C 177 ; WX 500 ; N endash ; B 12 221 524 279 ; +C 178 ; WX 500 ; N dagger ; B 101 -125 519 717 ; +C 179 ; WX 490 ; N daggerdbl ; B 39 -119 509 717 ; +C 180 ; WX 265 ; N periodcentered ; B 89 187 211 312 ; +C 182 ; WX 560 ; N paragraph ; B 109 -101 637 692 ; +C 183 ; WX 500 ; N bullet ; B 110 192 429 512 ; +C 184 ; WX 216 ; N quotesinglbase ; B -7 -109 146 151 ; +C 185 ; WX 402 ; N quotedblbase ; B -7 -109 332 151 ; +C 186 ; WX 402 ; N quotedblright ; B 107 484 446 744 ; +C 187 ; WX 462 ; N guillemotright ; B 29 41 420 435 ; +C 188 ; WX 1000 ; N ellipsis ; B 85 -12 873 113 ; +C 189 ; WX 1200 ; N perthousand ; B 98 -25 1170 702 ; +C 191 ; WX 425 ; N questiondown ; B 3 -217 344 502 ; +C 193 ; WX 400 ; N grave ; B 146 542 368 723 ; +C 194 ; WX 400 ; N acute ; B 214 542 436 723 ; +C 195 ; WX 400 ; N circumflex ; B 187 546 484 720 ; +C 196 ; WX 400 ; N tilde ; B 137 563 492 682 ; +C 197 ; WX 400 ; N macron ; B 193 597 489 656 ; +C 198 ; WX 400 ; N breve ; B 227 568 501 698 ; +C 199 ; WX 402 ; N dotaccent ; B 252 570 359 680 ; +C 200 ; WX 400 ; N dieresis ; B 172 572 487 682 ; +C 202 ; WX 400 ; N ring ; B 186 550 402 752 ; +C 203 ; WX 400 ; N cedilla ; B 62 -230 241 0 ; +C 205 ; WX 400 ; N hungarumlaut ; B 176 546 455 750 ; +C 206 ; WX 350 ; N ogonek ; B 68 -219 248 0 ; +C 207 ; WX 400 ; N caron ; B 213 557 510 731 ; +C 208 ; WX 1000 ; N emdash ; B 12 221 1024 279 ; +C 225 ; WX 880 ; N AE ; B -88 0 941 692 ; +C 227 ; WX 425 ; N ordfeminine ; B 77 265 460 590 ; +C 232 ; WX 571 ; N Lslash ; B 11 0 574 692 ; +C 233 ; WX 753 ; N Oslash ; B 79 -45 754 736 ; +C 234 ; WX 1020 ; N OE ; B 79 0 1081 692 ; +C 235 ; WX 389 ; N ordmasculine ; B 86 265 420 590 ; +C 241 ; WX 779 ; N ae ; B 34 -12 797 514 ; +C 245 ; WX 317 ; N dotlessi ; B 79 -12 299 502 ; +C 248 ; WX 318 ; N lslash ; B 45 -12 376 742 ; +C 249 ; WX 537 ; N oslash ; B 49 -39 522 529 ; +C 250 ; WX 806 ; N oe ; B 49 -12 824 502 ; +C 251 ; WX 577 ; N germandbls ; B -107 -242 630 742 ; +C -1 ; WX 370 ; N onesuperior ; B 90 272 326 680 ; +C -1 ; WX 570 ; N minus ; B 58 221 542 279 ; +C -1 ; WX 400 ; N degree ; B 152 404 428 680 ; +C -1 ; WX 537 ; N oacute ; B 49 -12 530 723 ; +C -1 ; WX 753 ; N Odieresis ; B 79 -15 754 848 ; +C -1 ; WX 537 ; N odieresis ; B 49 -12 532 682 ; +C -1 ; WX 596 ; N Eacute ; B 3 0 657 890 ; +C -1 ; WX 618 ; N ucircumflex ; B 89 -12 609 720 ; +C -1 ; WX 890 ; N onequarter ; B 97 -24 805 698 ; +C -1 ; WX 570 ; N logicalnot ; B 58 102 542 389 ; +C -1 ; WX 596 ; N Ecircumflex ; B 3 0 657 876 ; +C -1 ; WX 890 ; N onehalf ; B 71 -24 812 698 ; +C -1 ; WX 753 ; N Otilde ; B 79 -15 754 842 ; +C -1 ; WX 618 ; N uacute ; B 89 -12 609 723 ; +C -1 ; WX 453 ; N eacute ; B 45 -12 508 723 ; +C -1 ; WX 317 ; N iacute ; B 79 -12 398 723 ; +C -1 ; WX 596 ; N Egrave ; B 3 0 657 890 ; +C -1 ; WX 317 ; N icircumflex ; B 79 -12 383 720 ; +C -1 ; WX 618 ; N mu ; B 11 -232 609 502 ; +C -1 ; WX 270 ; N brokenbar ; B 130 -175 198 675 ; +C -1 ; WX 584 ; N thorn ; B 16 -242 580 700 ; +C -1 ; WX 624 ; N Aring ; B -58 0 623 861 ; +C -1 ; WX 468 ; N yacute ; B -40 -242 505 723 ; +C -1 ; WX 591 ; N Ydieresis ; B 96 0 744 848 ; +C -1 ; WX 1100 ; N trademark ; B 91 277 1094 692 ; +C -1 ; WX 836 ; N registered ; B 91 -15 819 707 ; +C -1 ; WX 537 ; N ocircumflex ; B 49 -12 522 720 ; +C -1 ; WX 624 ; N Agrave ; B -58 0 623 890 ; +C -1 ; WX 533 ; N Scaron ; B 34 -15 561 888 ; +C -1 ; WX 794 ; N Ugrave ; B 131 -15 880 890 ; +C -1 ; WX 596 ; N Edieresis ; B 3 0 657 848 ; +C -1 ; WX 794 ; N Uacute ; B 131 -15 880 890 ; +C -1 ; WX 537 ; N otilde ; B 49 -12 525 682 ; +C -1 ; WX 618 ; N ntilde ; B 63 -12 600 682 ; +C -1 ; WX 468 ; N ydieresis ; B -40 -242 513 682 ; +C -1 ; WX 624 ; N Aacute ; B -58 0 642 890 ; +C -1 ; WX 537 ; N eth ; B 47 -12 521 742 ; +C -1 ; WX 561 ; N acircumflex ; B 31 -12 563 720 ; +C -1 ; WX 561 ; N aring ; B 31 -12 563 752 ; +C -1 ; WX 753 ; N Ograve ; B 79 -15 754 890 ; +C -1 ; WX 441 ; N ccedilla ; B 46 -230 465 502 ; +C -1 ; WX 570 ; N multiply ; B 88 22 532 478 ; +C -1 ; WX 570 ; N divide ; B 58 25 542 475 ; +C -1 ; WX 370 ; N twosuperior ; B 35 272 399 680 ; +C -1 ; WX 763 ; N Ntilde ; B -4 0 855 842 ; +C -1 ; WX 618 ; N ugrave ; B 89 -12 609 723 ; +C -1 ; WX 794 ; N Ucircumflex ; B 131 -15 880 876 ; +C -1 ; WX 624 ; N Atilde ; B -58 0 623 842 ; +C -1 ; WX 468 ; N zcaron ; B 4 -12 484 731 ; +C -1 ; WX 317 ; N idieresis ; B 79 -12 398 682 ; +C -1 ; WX 624 ; N Acircumflex ; B -58 0 623 876 ; +C -1 ; WX 345 ; N Icircumflex ; B 5 0 453 876 ; +C -1 ; WX 591 ; N Yacute ; B 96 0 744 890 ; +C -1 ; WX 753 ; N Oacute ; B 79 -15 754 890 ; +C -1 ; WX 624 ; N Adieresis ; B -58 0 623 848 ; +C -1 ; WX 622 ; N Zcaron ; B -20 0 703 888 ; +C -1 ; WX 561 ; N agrave ; B 31 -12 563 723 ; +C -1 ; WX 370 ; N threesuperior ; B 59 265 389 680 ; +C -1 ; WX 537 ; N ograve ; B 49 -12 522 723 ; +C -1 ; WX 890 ; N threequarters ; B 105 -24 816 698 ; +C -1 ; WX 770 ; N Eth ; B 12 0 774 692 ; +C -1 ; WX 570 ; N plusminus ; B 58 0 542 556 ; +C -1 ; WX 618 ; N udieresis ; B 89 -12 609 682 ; +C -1 ; WX 453 ; N edieresis ; B 45 -12 490 682 ; +C -1 ; WX 561 ; N aacute ; B 31 -12 571 723 ; +C -1 ; WX 317 ; N igrave ; B 55 -12 299 723 ; +C -1 ; WX 345 ; N Idieresis ; B 5 0 461 848 ; +C -1 ; WX 561 ; N adieresis ; B 31 -12 563 682 ; +C -1 ; WX 345 ; N Iacute ; B 5 0 506 890 ; +C -1 ; WX 836 ; N copyright ; B 91 -15 819 707 ; +C -1 ; WX 345 ; N Igrave ; B 5 0 428 890 ; +C -1 ; WX 661 ; N Ccedilla ; B 79 -230 723 707 ; +C -1 ; WX 389 ; N scaron ; B 19 -12 457 731 ; +C -1 ; WX 453 ; N egrave ; B 45 -12 471 723 ; +C -1 ; WX 753 ; N Ocircumflex ; B 79 -15 754 876 ; +C -1 ; WX 604 ; N Thorn ; B 5 0 616 692 ; +C -1 ; WX 561 ; N atilde ; B 31 -12 563 682 ; +C -1 ; WX 794 ; N Udieresis ; B 131 -15 880 848 ; +C -1 ; WX 453 ; N ecircumflex ; B 45 -12 475 720 ; +EndCharMetrics +StartKernData +StartKernPairs 690 + +KPX A y -20 +KPX A x 10 +KPX A w -30 +KPX A v -30 +KPX A u -10 +KPX A t -6 +KPX A s 15 +KPX A r -12 +KPX A quoteright -110 +KPX A quotedblright -110 +KPX A q 10 +KPX A p -12 +KPX A o -10 +KPX A n -18 +KPX A m -18 +KPX A l -18 +KPX A j 6 +KPX A h -6 +KPX A d 10 +KPX A c -6 +KPX A b -6 +KPX A a 12 +KPX A Y -76 +KPX A X -8 +KPX A W -80 +KPX A V -90 +KPX A U -60 +KPX A T -72 +KPX A Q -30 +KPX A O -30 +KPX A G -30 +KPX A C -30 + +KPX B y -6 +KPX B u -20 +KPX B r -15 +KPX B quoteright -40 +KPX B quotedblright -30 +KPX B o 6 +KPX B l -20 +KPX B k -15 +KPX B i -12 +KPX B h -15 +KPX B e 6 +KPX B a 12 +KPX B W -20 +KPX B V -50 +KPX B U -50 +KPX B T -20 + +KPX C z -6 +KPX C y -18 +KPX C u -18 +KPX C quotedblright 20 +KPX C i -5 +KPX C e -6 +KPX C a -6 + +KPX D y 18 +KPX D u -10 +KPX D quoteright -40 +KPX D quotedblright -50 +KPX D period -30 +KPX D o 6 +KPX D i 6 +KPX D h -25 +KPX D e 6 +KPX D comma -20 +KPX D a 6 +KPX D Y -70 +KPX D W -50 +KPX D V -60 + +KPX E z -6 +KPX E y -18 +KPX E x 5 +KPX E w -20 +KPX E v -18 +KPX E u -24 +KPX E t -18 +KPX E s 5 +KPX E r -6 +KPX E quoteright 10 +KPX E quotedblright 10 +KPX E q 10 +KPX E period 10 +KPX E p -12 +KPX E o -6 +KPX E n -12 +KPX E m -12 +KPX E l -12 +KPX E k -10 +KPX E j -6 +KPX E i -12 +KPX E g -12 +KPX E e 5 +KPX E d 10 +KPX E comma 10 +KPX E b -6 + +KPX F y -12 +KPX F u -30 +KPX F r -18 +KPX F quoteright 15 +KPX F quotedblright 35 +KPX F period -180 +KPX F o -30 +KPX F l -6 +KPX F i -12 +KPX F e -30 +KPX F comma -170 +KPX F a -30 +KPX F A -45 + +KPX G y -16 +KPX G u -22 +KPX G r -22 +KPX G quoteright -20 +KPX G quotedblright -20 +KPX G o 10 +KPX G n -22 +KPX G l -24 +KPX G i -12 +KPX G h -18 +KPX G e 10 +KPX G a 5 + +KPX H y -18 +KPX H u -30 +KPX H quoteright 10 +KPX H quotedblright 10 +KPX H o -12 +KPX H i -12 +KPX H e -12 +KPX H a -12 + +KPX I z -20 +KPX I y -6 +KPX I x -6 +KPX I w -30 +KPX I v -30 +KPX I u -30 +KPX I t -18 +KPX I s -18 +KPX I r -12 +KPX I quoteright 10 +KPX I quotedblright 10 +KPX I p -18 +KPX I o -12 +KPX I n -18 +KPX I m -18 +KPX I l -6 +KPX I k -6 +KPX I g -12 +KPX I f -6 +KPX I d -6 +KPX I c -12 +KPX I b -6 +KPX I a -6 + +KPX J y -12 +KPX J u -36 +KPX J quoteright 6 +KPX J quotedblright 15 +KPX J o -36 +KPX J i -30 +KPX J e -36 +KPX J braceright 10 +KPX J a -36 + +KPX K y -40 +KPX K w -30 +KPX K v -20 +KPX K u -24 +KPX K r -12 +KPX K quoteright 25 +KPX K quotedblright 40 +KPX K o -24 +KPX K n -18 +KPX K i -6 +KPX K h 6 +KPX K e -12 +KPX K a -6 +KPX K Q -24 +KPX K O -24 +KPX K G -24 +KPX K C -24 + +KPX L y -55 +KPX L w -30 +KPX L u -18 +KPX L quoteright -110 +KPX L quotedblright -110 +KPX L l -16 +KPX L j -18 +KPX L i -18 +KPX L a 10 +KPX L Y -80 +KPX L W -90 +KPX L V -110 +KPX L U -42 +KPX L T -80 +KPX L Q -48 +KPX L O -48 +KPX L G -48 +KPX L C -48 +KPX L A 30 + +KPX M y -18 +KPX M u -24 +KPX M quoteright 6 +KPX M quotedblright 15 +KPX M o -25 +KPX M n -12 +KPX M j -18 +KPX M i -12 +KPX M e -20 +KPX M d -10 +KPX M c -20 +KPX M a -6 + +KPX N y -18 +KPX N u -24 +KPX N quoteright 10 +KPX N quotedblright 10 +KPX N o -25 +KPX N i -12 +KPX N e -20 +KPX N a -22 + +KPX O z -6 +KPX O y 12 +KPX O w -10 +KPX O v -10 +KPX O u -6 +KPX O t -6 +KPX O s -6 +KPX O r -6 +KPX O quoteright -40 +KPX O quotedblright -40 +KPX O q 5 +KPX O period -20 +KPX O p -6 +KPX O n -6 +KPX O m -6 +KPX O l -20 +KPX O k -10 +KPX O j -6 +KPX O h -10 +KPX O g -6 +KPX O e 5 +KPX O d 6 +KPX O comma -10 +KPX O c 5 +KPX O b -6 +KPX O a 5 +KPX O Y -75 +KPX O X -30 +KPX O W -40 +KPX O V -60 +KPX O T -48 +KPX O A -18 + +KPX P y 6 +KPX P u -18 +KPX P t -6 +KPX P s -24 +KPX P r -6 +KPX P period -220 +KPX P o -24 +KPX P n -12 +KPX P l -25 +KPX P h -15 +KPX P e -24 +KPX P comma -220 +KPX P a -24 +KPX P I -30 +KPX P H -30 +KPX P E -30 +KPX P A -75 + +KPX Q u -6 +KPX Q quoteright -40 +KPX Q quotedblright -50 +KPX Q a -6 +KPX Q Y -70 +KPX Q X -12 +KPX Q W -35 +KPX Q V -60 +KPX Q U -35 +KPX Q T -36 +KPX Q A -18 + +KPX R y -14 +KPX R u -12 +KPX R quoteright -30 +KPX R quotedblright -20 +KPX R o -12 +KPX R hyphen -20 +KPX R e -12 +KPX R Y -50 +KPX R W -30 +KPX R V -40 +KPX R U -40 +KPX R T -30 +KPX R Q -10 +KPX R O -10 +KPX R G -10 +KPX R C -10 +KPX R A -6 + +KPX S y -30 +KPX S w -30 +KPX S v -30 +KPX S u -18 +KPX S t -30 +KPX S r -20 +KPX S quoteright -38 +KPX S quotedblright -30 +KPX S p -18 +KPX S n -24 +KPX S m -24 +KPX S l -30 +KPX S k -24 +KPX S j -25 +KPX S i -30 +KPX S h -30 +KPX S e -6 + +KPX T z -70 +KPX T y -60 +KPX T w -64 +KPX T u -74 +KPX T semicolon -36 +KPX T s -72 +KPX T r -64 +KPX T quoteright 45 +KPX T quotedblright 50 +KPX T period -100 +KPX T parenright 54 +KPX T o -90 +KPX T m -64 +KPX T i -34 +KPX T hyphen -100 +KPX T endash -60 +KPX T emdash -60 +KPX T e -90 +KPX T comma -110 +KPX T colon -10 +KPX T bracketright 45 +KPX T braceright 54 +KPX T a -90 +KPX T Y 12 +KPX T X 18 +KPX T W 6 +KPX T T 18 +KPX T Q -12 +KPX T O -12 +KPX T G -12 +KPX T C -12 +KPX T A -56 + +KPX U z -30 +KPX U x -40 +KPX U t -24 +KPX U s -30 +KPX U r -30 +KPX U quoteright 10 +KPX U quotedblright 10 +KPX U p -40 +KPX U n -45 +KPX U m -45 +KPX U l -12 +KPX U k -12 +KPX U i -24 +KPX U h -6 +KPX U g -30 +KPX U d -40 +KPX U c -35 +KPX U b -6 +KPX U a -40 +KPX U A -45 + +KPX V y -46 +KPX V u -42 +KPX V semicolon -35 +KPX V r -50 +KPX V quoteright 75 +KPX V quotedblright 70 +KPX V period -130 +KPX V parenright 64 +KPX V o -62 +KPX V i -10 +KPX V hyphen -60 +KPX V endash -20 +KPX V emdash -20 +KPX V e -52 +KPX V comma -120 +KPX V colon -18 +KPX V bracketright 64 +KPX V braceright 64 +KPX V a -60 +KPX V T 6 +KPX V A -70 + +KPX W y -42 +KPX W u -56 +KPX W t -20 +KPX W semicolon -28 +KPX W r -40 +KPX W quoteright 55 +KPX W quotedblright 60 +KPX W period -108 +KPX W parenright 64 +KPX W o -60 +KPX W m -35 +KPX W i -10 +KPX W hyphen -40 +KPX W endash -2 +KPX W emdash -10 +KPX W e -54 +KPX W d -50 +KPX W comma -108 +KPX W colon -28 +KPX W bracketright 55 +KPX W braceright 64 +KPX W a -60 +KPX W T 12 +KPX W Q -10 +KPX W O -10 +KPX W G -10 +KPX W C -10 +KPX W A -58 + +KPX X y -35 +KPX X u -30 +KPX X r -6 +KPX X quoteright 35 +KPX X quotedblright 15 +KPX X i -6 +KPX X e -10 +KPX X a 5 +KPX X Y -6 +KPX X W -6 +KPX X Q -30 +KPX X O -30 +KPX X G -30 +KPX X C -30 +KPX X A -18 + +KPX Y v -50 +KPX Y u -58 +KPX Y t -32 +KPX Y semicolon -36 +KPX Y quoteright 65 +KPX Y quotedblright 70 +KPX Y q -100 +KPX Y period -90 +KPX Y parenright 60 +KPX Y o -72 +KPX Y l 10 +KPX Y hyphen -95 +KPX Y endash -20 +KPX Y emdash -20 +KPX Y e -72 +KPX Y d -80 +KPX Y comma -80 +KPX Y colon -36 +KPX Y bracketright 64 +KPX Y braceright 75 +KPX Y a -82 +KPX Y Y 12 +KPX Y X 12 +KPX Y W 12 +KPX Y V 6 +KPX Y T 25 +KPX Y Q -5 +KPX Y O -5 +KPX Y G -5 +KPX Y C -5 +KPX Y A -36 + +KPX Z y -36 +KPX Z w -36 +KPX Z u -12 +KPX Z quoteright 10 +KPX Z quotedblright 10 +KPX Z o -6 +KPX Z i -12 +KPX Z e -6 +KPX Z a -6 +KPX Z Q -30 +KPX Z O -30 +KPX Z G -30 +KPX Z C -30 +KPX Z A 12 + +KPX a quoteright -40 +KPX a quotedblright -40 + +KPX b y -6 +KPX b w -15 +KPX b v -15 +KPX b quoteright -50 +KPX b quotedblright -50 +KPX b period -40 +KPX b comma -30 + +KPX braceleft Y 64 +KPX braceleft W 64 +KPX braceleft V 64 +KPX braceleft T 54 +KPX braceleft J 80 + +KPX bracketleft Y 64 +KPX bracketleft W 64 +KPX bracketleft V 64 +KPX bracketleft T 54 +KPX bracketleft J 80 + +KPX c quoteright -20 +KPX c quotedblright -20 + +KPX colon space -30 + +KPX comma space -40 +KPX comma quoteright -80 +KPX comma quotedblright -80 + +KPX d quoteright -12 +KPX d quotedblright -12 + +KPX e x -10 +KPX e w -10 +KPX e quoteright -30 +KPX e quotedblright -30 + +KPX f quoteright 110 +KPX f quotedblright 110 +KPX f period -20 +KPX f parenright 100 +KPX f comma -20 +KPX f bracketright 90 +KPX f braceright 90 + +KPX g y 30 +KPX g p 12 +KPX g f 42 + +KPX h quoteright -80 +KPX h quotedblright -80 + +KPX j quoteright -20 +KPX j quotedblright -20 +KPX j period -35 +KPX j comma -20 + +KPX k quoteright -30 +KPX k quotedblright -50 + +KPX m quoteright -80 +KPX m quotedblright -80 + +KPX n quoteright -80 +KPX n quotedblright -80 + +KPX o z -10 +KPX o y -20 +KPX o x -20 +KPX o w -30 +KPX o v -35 +KPX o quoteright -60 +KPX o quotedblright -50 +KPX o period -30 +KPX o comma -20 + +KPX p z -10 +KPX p w -15 +KPX p quoteright -50 +KPX p quotedblright -70 +KPX p period -30 +KPX p comma -20 + +KPX parenleft Y 75 +KPX parenleft W 75 +KPX parenleft V 75 +KPX parenleft T 64 +KPX parenleft J 80 + +KPX period space -40 +KPX period quoteright -80 +KPX period quotedblright -80 + +KPX q quoteright -20 +KPX q quotedblright -30 +KPX q period -20 +KPX q comma -10 + +KPX quotedblleft z -30 +KPX quotedblleft x -40 +KPX quotedblleft w -12 +KPX quotedblleft v -12 +KPX quotedblleft u -12 +KPX quotedblleft t -12 +KPX quotedblleft s -30 +KPX quotedblleft r -12 +KPX quotedblleft q -40 +KPX quotedblleft p -12 +KPX quotedblleft o -30 +KPX quotedblleft n -12 +KPX quotedblleft m -12 +KPX quotedblleft l 10 +KPX quotedblleft k 10 +KPX quotedblleft h 10 +KPX quotedblleft g -30 +KPX quotedblleft e -40 +KPX quotedblleft d -40 +KPX quotedblleft c -40 +KPX quotedblleft b 24 +KPX quotedblleft a -60 +KPX quotedblleft Y 12 +KPX quotedblleft X 28 +KPX quotedblleft W 28 +KPX quotedblleft V 28 +KPX quotedblleft T 36 +KPX quotedblleft A -90 + +KPX quotedblright space -40 +KPX quotedblright period -100 +KPX quotedblright comma -100 + +KPX quoteleft z -30 +KPX quoteleft y -10 +KPX quoteleft x -40 +KPX quoteleft w -12 +KPX quoteleft v -12 +KPX quoteleft u -12 +KPX quoteleft t -12 +KPX quoteleft s -30 +KPX quoteleft r -12 +KPX quoteleft quoteleft -18 +KPX quoteleft q -30 +KPX quoteleft p -12 +KPX quoteleft o -30 +KPX quoteleft n -12 +KPX quoteleft m -12 +KPX quoteleft l 10 +KPX quoteleft k 10 +KPX quoteleft h 10 +KPX quoteleft g -30 +KPX quoteleft e -30 +KPX quoteleft d -30 +KPX quoteleft c -30 +KPX quoteleft b 24 +KPX quoteleft a -45 +KPX quoteleft Y 12 +KPX quoteleft X 28 +KPX quoteleft W 28 +KPX quoteleft V 28 +KPX quoteleft T 36 +KPX quoteleft A -90 + +KPX quoteright v -35 +KPX quoteright t -35 +KPX quoteright space -40 +KPX quoteright s -55 +KPX quoteright r -25 +KPX quoteright quoteright -18 +KPX quoteright period -100 +KPX quoteright m -25 +KPX quoteright l -12 +KPX quoteright d -70 +KPX quoteright comma -100 + +KPX r y 18 +KPX r w 6 +KPX r v 6 +KPX r t 8 +KPX r quotedblright -15 +KPX r q -24 +KPX r period -120 +KPX r o -6 +KPX r l -20 +KPX r k -20 +KPX r hyphen -30 +KPX r h -20 +KPX r f 8 +KPX r emdash -20 +KPX r e -26 +KPX r d -26 +KPX r comma -110 +KPX r c -12 +KPX r a -20 + +KPX s quoteright -40 +KPX s quotedblright -45 + +KPX semicolon space -30 + +KPX space quotesinglbase -30 +KPX space quoteleft -40 +KPX space quotedblleft -40 +KPX space quotedblbase -30 +KPX space Y -70 +KPX space W -70 +KPX space V -70 + +KPX t quoteright 10 +KPX t quotedblright -10 + +KPX u quoteright -55 +KPX u quotedblright -50 + +KPX v quoteright -20 +KPX v quotedblright -30 +KPX v q -6 +KPX v period -70 +KPX v o -6 +KPX v e -6 +KPX v d -6 +KPX v comma -70 +KPX v c -6 +KPX v a -6 + +KPX w quoteright -20 +KPX w quotedblright -30 +KPX w period -62 +KPX w comma -62 + +KPX x y 12 +KPX x w -6 +KPX x quoteright -40 +KPX x quotedblright -50 +KPX x q -6 +KPX x o -6 +KPX x e -6 +KPX x d -6 +KPX x c -6 + +KPX y quoteright -10 +KPX y quotedblright -20 +KPX y period -70 +KPX y emdash 40 +KPX y comma -60 + +KPX z quoteright -40 +KPX z quotedblright -50 +KPX z o -6 +KPX z e -6 +KPX z d -6 +KPX z c -6 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm new file mode 100644 index 00000000..6efb57ab --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm @@ -0,0 +1,480 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Fri Dec 28 16:35:46 1990 +Comment UniqueID 33936 +Comment VMusage 34559 41451 +FontName ZapfChancery-MediumItalic +FullName ITC Zapf Chancery Medium Italic +FamilyName ITC Zapf Chancery +Weight Medium +ItalicAngle -14 +IsFixedPitch false +FontBBox -181 -314 1065 831 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.007 +Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Chancery is a registered trademark of International Typeface Corporation. +EncodingScheme AdobeStandardEncoding +CapHeight 708 +XHeight 438 +Ascender 714 +Descender -314 +StartCharMetrics 228 +C 32 ; WX 220 ; N space ; B 0 0 0 0 ; +C 33 ; WX 280 ; N exclam ; B 119 -14 353 610 ; +C 34 ; WX 220 ; N quotedbl ; B 120 343 333 610 ; +C 35 ; WX 440 ; N numbersign ; B 83 0 521 594 ; +C 36 ; WX 440 ; N dollar ; B 60 -144 508 709 ; +C 37 ; WX 680 ; N percent ; B 132 -160 710 700 ; +C 38 ; WX 780 ; N ampersand ; B 126 -16 915 610 ; +C 39 ; WX 240 ; N quoteright ; B 168 343 338 610 ; +C 40 ; WX 260 ; N parenleft ; B 96 -216 411 664 ; +C 41 ; WX 220 ; N parenright ; B -13 -216 302 664 ; +C 42 ; WX 420 ; N asterisk ; B 139 263 479 610 ; +C 43 ; WX 520 ; N plus ; B 117 0 543 426 ; +C 44 ; WX 220 ; N comma ; B 25 -140 213 148 ; +C 45 ; WX 280 ; N hyphen ; B 69 190 334 248 ; +C 46 ; WX 220 ; N period ; B 102 -14 228 128 ; +C 47 ; WX 340 ; N slash ; B 74 -16 458 610 ; +C 48 ; WX 440 ; N zero ; B 79 -16 538 610 ; +C 49 ; WX 440 ; N one ; B 41 0 428 610 ; +C 50 ; WX 440 ; N two ; B 17 -16 485 610 ; +C 51 ; WX 440 ; N three ; B 1 -16 485 610 ; +C 52 ; WX 440 ; N four ; B 77 -35 499 610 ; +C 53 ; WX 440 ; N five ; B 60 -16 595 679 ; +C 54 ; WX 440 ; N six ; B 90 -16 556 610 ; +C 55 ; WX 440 ; N seven ; B 157 -33 561 645 ; +C 56 ; WX 440 ; N eight ; B 65 -16 529 610 ; +C 57 ; WX 440 ; N nine ; B 32 -16 517 610 ; +C 58 ; WX 260 ; N colon ; B 98 -14 296 438 ; +C 59 ; WX 240 ; N semicolon ; B 29 -140 299 438 ; +C 60 ; WX 520 ; N less ; B 139 0 527 468 ; +C 61 ; WX 520 ; N equal ; B 117 86 543 340 ; +C 62 ; WX 520 ; N greater ; B 139 0 527 468 ; +C 63 ; WX 380 ; N question ; B 150 -14 455 610 ; +C 64 ; WX 700 ; N at ; B 127 -16 753 610 ; +C 65 ; WX 620 ; N A ; B 13 -16 697 632 ; +C 66 ; WX 600 ; N B ; B 85 -6 674 640 ; +C 67 ; WX 520 ; N C ; B 93 -16 631 610 ; +C 68 ; WX 700 ; N D ; B 86 -6 768 640 ; +C 69 ; WX 620 ; N E ; B 91 -12 709 618 ; +C 70 ; WX 580 ; N F ; B 120 -118 793 629 ; +C 71 ; WX 620 ; N G ; B 148 -242 709 610 ; +C 72 ; WX 680 ; N H ; B 18 -16 878 708 ; +C 73 ; WX 380 ; N I ; B 99 0 504 594 ; +C 74 ; WX 400 ; N J ; B -14 -147 538 594 ; +C 75 ; WX 660 ; N K ; B 53 -153 844 610 ; +C 76 ; WX 580 ; N L ; B 53 -16 657 610 ; +C 77 ; WX 840 ; N M ; B 58 -16 1020 722 ; +C 78 ; WX 700 ; N N ; B 85 -168 915 708 ; +C 79 ; WX 600 ; N O ; B 94 -16 660 610 ; +C 80 ; WX 540 ; N P ; B 42 0 658 628 ; +C 81 ; WX 600 ; N Q ; B 84 -177 775 610 ; +C 82 ; WX 600 ; N R ; B 58 -168 805 640 ; +C 83 ; WX 460 ; N S ; B 45 -81 558 610 ; +C 84 ; WX 500 ; N T ; B 63 0 744 667 ; +C 85 ; WX 740 ; N U ; B 126 -16 792 617 ; +C 86 ; WX 640 ; N V ; B 124 -16 810 714 ; +C 87 ; WX 880 ; N W ; B 94 -16 1046 723 ; +C 88 ; WX 560 ; N X ; B -30 -16 699 610 ; +C 89 ; WX 560 ; N Y ; B 41 -168 774 647 ; +C 90 ; WX 620 ; N Z ; B 42 -19 669 624 ; +C 91 ; WX 240 ; N bracketleft ; B -13 -207 405 655 ; +C 92 ; WX 480 ; N backslash ; B 140 -16 524 610 ; +C 93 ; WX 320 ; N bracketright ; B -27 -207 391 655 ; +C 94 ; WX 520 ; N asciicircum ; B 132 239 532 594 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 240 ; N quoteleft ; B 169 343 339 610 ; +C 97 ; WX 420 ; N a ; B 92 -15 485 438 ; +C 98 ; WX 420 ; N b ; B 82 -23 492 714 ; +C 99 ; WX 340 ; N c ; B 87 -14 406 438 ; +C 100 ; WX 440 ; N d ; B 102 -14 651 714 ; +C 101 ; WX 340 ; N e ; B 87 -14 403 438 ; +C 102 ; WX 320 ; N f ; B -119 -314 547 714 ; L i fi ; L l fl ; +C 103 ; WX 400 ; N g ; B -108 -314 503 438 ; +C 104 ; WX 440 ; N h ; B 55 -14 524 714 ; +C 105 ; WX 240 ; N i ; B 100 -14 341 635 ; +C 106 ; WX 220 ; N j ; B -112 -314 332 635 ; +C 107 ; WX 440 ; N k ; B 87 -184 628 714 ; +C 108 ; WX 240 ; N l ; B 102 -14 480 714 ; +C 109 ; WX 620 ; N m ; B 86 -14 704 438 ; +C 110 ; WX 460 ; N n ; B 101 -14 544 438 ; +C 111 ; WX 400 ; N o ; B 87 -14 449 438 ; +C 112 ; WX 440 ; N p ; B -23 -314 484 432 ; +C 113 ; WX 400 ; N q ; B 87 -300 490 510 ; +C 114 ; WX 300 ; N r ; B 101 -14 424 438 ; +C 115 ; WX 320 ; N s ; B 46 -14 403 438 ; +C 116 ; WX 320 ; N t ; B 106 -14 426 539 ; +C 117 ; WX 460 ; N u ; B 102 -14 528 438 ; +C 118 ; WX 440 ; N v ; B 87 -14 533 488 ; +C 119 ; WX 680 ; N w ; B 87 -14 782 488 ; +C 120 ; WX 420 ; N x ; B 70 -195 589 438 ; +C 121 ; WX 400 ; N y ; B -24 -314 483 438 ; +C 122 ; WX 440 ; N z ; B 26 -14 508 445 ; +C 123 ; WX 240 ; N braceleft ; B 55 -207 383 655 ; +C 124 ; WX 520 ; N bar ; B 320 -16 378 714 ; +C 125 ; WX 240 ; N braceright ; B -10 -207 318 655 ; +C 126 ; WX 520 ; N asciitilde ; B 123 186 539 320 ; +C 161 ; WX 280 ; N exclamdown ; B 72 -186 306 438 ; +C 162 ; WX 440 ; N cent ; B 122 -134 476 543 ; +C 163 ; WX 440 ; N sterling ; B -16 -52 506 610 ; +C 164 ; WX 60 ; N fraction ; B -181 -16 320 610 ; +C 165 ; WX 440 ; N yen ; B -1 -168 613 647 ; +C 166 ; WX 440 ; N florin ; B -64 -314 582 610 ; +C 167 ; WX 420 ; N section ; B 53 -215 514 610 ; +C 168 ; WX 440 ; N currency ; B 50 85 474 509 ; +C 169 ; WX 160 ; N quotesingle ; B 145 343 215 610 ; +C 170 ; WX 340 ; N quotedblleft ; B 169 343 464 610 ; +C 171 ; WX 340 ; N guillemotleft ; B 98 24 356 414 ; +C 172 ; WX 240 ; N guilsinglleft ; B 98 24 258 414 ; +C 173 ; WX 260 ; N guilsinglright ; B 106 24 266 414 ; +C 174 ; WX 520 ; N fi ; B -124 -314 605 714 ; +C 175 ; WX 520 ; N fl ; B -124 -314 670 714 ; +C 177 ; WX 500 ; N endash ; B 51 199 565 239 ; +C 178 ; WX 460 ; N dagger ; B 138 -37 568 610 ; +C 179 ; WX 480 ; N daggerdbl ; B 138 -59 533 610 ; +C 180 ; WX 220 ; N periodcentered ; B 139 208 241 310 ; +C 182 ; WX 500 ; N paragraph ; B 105 -199 638 594 ; +C 183 ; WX 600 ; N bullet ; B 228 149 524 445 ; +C 184 ; WX 180 ; N quotesinglbase ; B 21 -121 191 146 ; +C 185 ; WX 280 ; N quotedblbase ; B -14 -121 281 146 ; +C 186 ; WX 360 ; N quotedblright ; B 158 343 453 610 ; +C 187 ; WX 380 ; N guillemotright ; B 117 24 375 414 ; +C 188 ; WX 1000 ; N ellipsis ; B 124 -14 916 128 ; +C 189 ; WX 960 ; N perthousand ; B 112 -160 1005 700 ; +C 191 ; WX 400 ; N questiondown ; B 82 -186 387 438 ; +C 193 ; WX 220 ; N grave ; B 193 492 339 659 ; +C 194 ; WX 300 ; N acute ; B 265 492 422 659 ; +C 195 ; WX 340 ; N circumflex ; B 223 482 443 649 ; +C 196 ; WX 440 ; N tilde ; B 243 543 522 619 ; +C 197 ; WX 440 ; N macron ; B 222 544 465 578 ; +C 198 ; WX 440 ; N breve ; B 253 522 501 631 ; +C 199 ; WX 220 ; N dotaccent ; B 236 522 328 610 ; +C 200 ; WX 360 ; N dieresis ; B 243 522 469 610 ; +C 202 ; WX 300 ; N ring ; B 240 483 416 659 ; +C 203 ; WX 300 ; N cedilla ; B 12 -191 184 6 ; +C 205 ; WX 400 ; N hungarumlaut ; B 208 492 495 659 ; +C 206 ; WX 280 ; N ogonek ; B 38 -191 233 6 ; +C 207 ; WX 340 ; N caron ; B 254 492 474 659 ; +C 208 ; WX 1000 ; N emdash ; B 51 199 1065 239 ; +C 225 ; WX 740 ; N AE ; B -21 -16 799 594 ; +C 227 ; WX 260 ; N ordfeminine ; B 111 338 386 610 ; +C 232 ; WX 580 ; N Lslash ; B 49 -16 657 610 ; +C 233 ; WX 660 ; N Oslash ; B 83 -78 751 672 ; +C 234 ; WX 820 ; N OE ; B 63 -16 909 610 ; +C 235 ; WX 260 ; N ordmasculine ; B 128 339 373 610 ; +C 241 ; WX 540 ; N ae ; B 67 -14 624 468 ; +C 245 ; WX 240 ; N dotlessi ; B 100 -14 306 438 ; +C 248 ; WX 300 ; N lslash ; B 121 -14 515 714 ; +C 249 ; WX 440 ; N oslash ; B 46 -64 540 488 ; +C 250 ; WX 560 ; N oe ; B 78 -14 628 438 ; +C 251 ; WX 420 ; N germandbls ; B -127 -314 542 714 ; +C -1 ; WX 340 ; N ecircumflex ; B 87 -14 433 649 ; +C -1 ; WX 340 ; N edieresis ; B 87 -14 449 610 ; +C -1 ; WX 420 ; N aacute ; B 92 -15 492 659 ; +C -1 ; WX 740 ; N registered ; B 137 -16 763 610 ; +C -1 ; WX 240 ; N icircumflex ; B 100 -14 363 649 ; +C -1 ; WX 460 ; N udieresis ; B 102 -14 528 610 ; +C -1 ; WX 400 ; N ograve ; B 87 -14 449 659 ; +C -1 ; WX 460 ; N uacute ; B 102 -14 528 659 ; +C -1 ; WX 460 ; N ucircumflex ; B 102 -14 528 649 ; +C -1 ; WX 620 ; N Aacute ; B 13 -16 702 821 ; +C -1 ; WX 240 ; N igrave ; B 100 -14 306 659 ; +C -1 ; WX 380 ; N Icircumflex ; B 99 0 504 821 ; +C -1 ; WX 340 ; N ccedilla ; B 62 -191 406 438 ; +C -1 ; WX 420 ; N adieresis ; B 92 -15 485 610 ; +C -1 ; WX 620 ; N Ecircumflex ; B 91 -12 709 821 ; +C -1 ; WX 320 ; N scaron ; B 46 -14 464 659 ; +C -1 ; WX 440 ; N thorn ; B -38 -314 505 714 ; +C -1 ; WX 1000 ; N trademark ; B 127 187 1046 594 ; +C -1 ; WX 340 ; N egrave ; B 87 -14 403 659 ; +C -1 ; WX 264 ; N threesuperior ; B 59 234 348 610 ; +C -1 ; WX 440 ; N zcaron ; B 26 -14 514 659 ; +C -1 ; WX 420 ; N atilde ; B 92 -15 522 619 ; +C -1 ; WX 420 ; N aring ; B 92 -15 485 659 ; +C -1 ; WX 400 ; N ocircumflex ; B 87 -14 453 649 ; +C -1 ; WX 620 ; N Edieresis ; B 91 -12 709 762 ; +C -1 ; WX 660 ; N threequarters ; B 39 -16 706 610 ; +C -1 ; WX 400 ; N ydieresis ; B -24 -314 483 610 ; +C -1 ; WX 400 ; N yacute ; B -24 -314 483 659 ; +C -1 ; WX 240 ; N iacute ; B 100 -14 392 659 ; +C -1 ; WX 620 ; N Acircumflex ; B 13 -16 697 821 ; +C -1 ; WX 740 ; N Uacute ; B 126 -16 792 821 ; +C -1 ; WX 340 ; N eacute ; B 87 -14 462 659 ; +C -1 ; WX 600 ; N Ograve ; B 94 -16 660 821 ; +C -1 ; WX 420 ; N agrave ; B 92 -15 485 659 ; +C -1 ; WX 740 ; N Udieresis ; B 126 -16 792 762 ; +C -1 ; WX 420 ; N acircumflex ; B 92 -15 485 649 ; +C -1 ; WX 380 ; N Igrave ; B 99 0 504 821 ; +C -1 ; WX 264 ; N twosuperior ; B 72 234 354 610 ; +C -1 ; WX 740 ; N Ugrave ; B 126 -16 792 821 ; +C -1 ; WX 660 ; N onequarter ; B 56 -16 702 610 ; +C -1 ; WX 740 ; N Ucircumflex ; B 126 -16 792 821 ; +C -1 ; WX 460 ; N Scaron ; B 45 -81 594 831 ; +C -1 ; WX 380 ; N Idieresis ; B 99 0 519 762 ; +C -1 ; WX 240 ; N idieresis ; B 100 -14 369 610 ; +C -1 ; WX 620 ; N Egrave ; B 91 -12 709 821 ; +C -1 ; WX 600 ; N Oacute ; B 94 -16 660 821 ; +C -1 ; WX 520 ; N divide ; B 117 -14 543 440 ; +C -1 ; WX 620 ; N Atilde ; B 13 -16 702 771 ; +C -1 ; WX 620 ; N Aring ; B 13 -16 697 831 ; +C -1 ; WX 600 ; N Odieresis ; B 94 -16 660 762 ; +C -1 ; WX 620 ; N Adieresis ; B 13 -16 709 762 ; +C -1 ; WX 700 ; N Ntilde ; B 85 -168 915 761 ; +C -1 ; WX 620 ; N Zcaron ; B 42 -19 669 831 ; +C -1 ; WX 540 ; N Thorn ; B 52 0 647 623 ; +C -1 ; WX 380 ; N Iacute ; B 99 0 532 821 ; +C -1 ; WX 520 ; N plusminus ; B 117 0 543 436 ; +C -1 ; WX 520 ; N multiply ; B 133 16 527 410 ; +C -1 ; WX 620 ; N Eacute ; B 91 -12 709 821 ; +C -1 ; WX 560 ; N Ydieresis ; B 41 -168 774 762 ; +C -1 ; WX 264 ; N onesuperior ; B 83 244 311 610 ; +C -1 ; WX 460 ; N ugrave ; B 102 -14 528 659 ; +C -1 ; WX 520 ; N logicalnot ; B 117 86 543 340 ; +C -1 ; WX 460 ; N ntilde ; B 101 -14 544 619 ; +C -1 ; WX 600 ; N Otilde ; B 94 -16 660 761 ; +C -1 ; WX 400 ; N otilde ; B 87 -14 502 619 ; +C -1 ; WX 520 ; N Ccedilla ; B 93 -191 631 610 ; +C -1 ; WX 620 ; N Agrave ; B 13 -16 697 821 ; +C -1 ; WX 660 ; N onehalf ; B 56 -16 702 610 ; +C -1 ; WX 700 ; N Eth ; B 86 -6 768 640 ; +C -1 ; WX 400 ; N degree ; B 171 324 457 610 ; +C -1 ; WX 560 ; N Yacute ; B 41 -168 774 821 ; +C -1 ; WX 600 ; N Ocircumflex ; B 94 -16 660 821 ; +C -1 ; WX 400 ; N oacute ; B 87 -14 482 659 ; +C -1 ; WX 460 ; N mu ; B 7 -314 523 438 ; +C -1 ; WX 520 ; N minus ; B 117 184 543 242 ; +C -1 ; WX 400 ; N eth ; B 87 -14 522 714 ; +C -1 ; WX 400 ; N odieresis ; B 87 -14 479 610 ; +C -1 ; WX 740 ; N copyright ; B 137 -16 763 610 ; +C -1 ; WX 520 ; N brokenbar ; B 320 -16 378 714 ; +EndCharMetrics +StartKernData +StartKernPairs 131 + +KPX A quoteright -40 +KPX A quotedblright -40 +KPX A U -10 +KPX A T 10 +KPX A Q 10 +KPX A O 10 +KPX A G -30 +KPX A C 20 + +KPX D period -30 +KPX D comma -20 +KPX D Y 10 +KPX D A -10 + +KPX F period -40 +KPX F i 10 +KPX F comma -30 + +KPX G period -20 +KPX G comma -10 + +KPX J period -20 +KPX J comma -10 + +KPX K u -20 +KPX K o -20 +KPX K e -20 + +KPX L y -10 +KPX L quoteright -25 +KPX L quotedblright -25 +KPX L W -10 +KPX L V -20 + +KPX O period -20 +KPX O comma -10 +KPX O Y 10 +KPX O T 20 +KPX O A -20 + +KPX P period -50 +KPX P o -10 +KPX P e -10 +KPX P comma -40 +KPX P a -20 +KPX P A -10 + +KPX Q U -10 + +KPX R Y 10 +KPX R W 10 +KPX R T 20 + +KPX T o -20 +KPX T i 20 +KPX T hyphen -20 +KPX T h 20 +KPX T e -20 +KPX T a -20 +KPX T O 30 +KPX T A 10 + +KPX V period -100 +KPX V o -20 +KPX V e -20 +KPX V comma -90 +KPX V a -20 +KPX V O 10 +KPX V G -20 + +KPX W period -50 +KPX W o -20 +KPX W i 10 +KPX W h 10 +KPX W e -20 +KPX W comma -40 +KPX W a -20 +KPX W O 10 + +KPX Y u -20 +KPX Y period -50 +KPX Y o -50 +KPX Y i 10 +KPX Y e -40 +KPX Y comma -40 +KPX Y a -60 + +KPX b period -30 +KPX b l -20 +KPX b comma -20 +KPX b b -20 + +KPX c k -10 + +KPX comma quoteright -70 +KPX comma quotedblright -70 + +KPX d w -20 +KPX d v -10 +KPX d d -40 + +KPX e y 10 + +KPX f quoteright 30 +KPX f quotedblright 30 +KPX f period -50 +KPX f f -50 +KPX f e -10 +KPX f comma -40 +KPX f a -20 + +KPX g y 10 +KPX g period -30 +KPX g i 10 +KPX g e 10 +KPX g comma -20 +KPX g a 10 + +KPX k y 10 +KPX k o -10 +KPX k e -20 + +KPX m y 10 +KPX m u 10 + +KPX n y 20 + +KPX o period -30 +KPX o comma -20 + +KPX p period -30 +KPX p p -10 +KPX p comma -20 + +KPX period quoteright -80 +KPX period quotedblright -80 + +KPX quotedblleft quoteleft 20 +KPX quotedblleft A 10 + +KPX quoteleft quoteleft -115 +KPX quoteleft A 10 + +KPX quoteright v 30 +KPX quoteright t 20 +KPX quoteright s -25 +KPX quoteright r 30 +KPX quoteright quoteright -115 +KPX quoteright quotedblright 20 +KPX quoteright l 20 + +KPX r period -50 +KPX r i 10 +KPX r comma -40 + +KPX s period -20 +KPX s comma -10 + +KPX v period -30 +KPX v comma -20 + +KPX w period -30 +KPX w o 10 +KPX w h 20 +KPX w comma -20 +EndKernPairs +EndKernData +StartComposites 56 +CC Aacute 2 ; PCC A 0 0 ; PCC acute 280 162 ; +CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 240 172 ; +CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 240 152 ; +CC Agrave 2 ; PCC A 0 0 ; PCC grave 250 162 ; +CC Aring 2 ; PCC A 0 0 ; PCC ring 260 172 ; +CC Atilde 2 ; PCC A 0 0 ; PCC tilde 180 152 ; +CC Eacute 2 ; PCC E 0 0 ; PCC acute 230 162 ; +CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 180 172 ; +CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 170 152 ; +CC Egrave 2 ; PCC E 0 0 ; PCC grave 220 162 ; +CC Iacute 2 ; PCC I 0 0 ; PCC acute 110 162 ; +CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 60 172 ; +CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 50 152 ; +CC Igrave 2 ; PCC I 0 0 ; PCC grave 100 162 ; +CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 142 ; +CC Oacute 2 ; PCC O 0 0 ; PCC acute 160 162 ; +CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 130 172 ; +CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 120 152 ; +CC Ograve 2 ; PCC O 0 0 ; PCC grave 150 162 ; +CC Otilde 2 ; PCC O 0 0 ; PCC tilde 90 142 ; +CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 172 ; +CC Uacute 2 ; PCC U 0 0 ; PCC acute 310 162 ; +CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 260 172 ; +CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 260 152 ; +CC Ugrave 2 ; PCC U 0 0 ; PCC grave 270 162 ; +CC Yacute 2 ; PCC Y 0 0 ; PCC acute 220 162 ; +CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 170 152 ; +CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 130 172 ; +CC aacute 2 ; PCC a 0 0 ; PCC acute 70 0 ; +CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 20 0 ; +CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 10 0 ; +CC agrave 2 ; PCC a 0 0 ; PCC grave 80 0 ; +CC aring 2 ; PCC a 0 0 ; PCC ring 60 0 ; +CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; +CC eacute 2 ; PCC e 0 0 ; PCC acute 40 0 ; +CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex -10 0 ; +CC edieresis 2 ; PCC e 0 0 ; PCC dieresis -20 0 ; +CC egrave 2 ; PCC e 0 0 ; PCC grave 30 0 ; +CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -30 0 ; +CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -80 0 ; +CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -100 0 ; +CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -40 0 ; +CC ntilde 2 ; PCC n 0 0 ; PCC tilde 10 0 ; +CC oacute 2 ; PCC o 0 0 ; PCC acute 60 0 ; +CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 10 0 ; +CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 10 0 ; +CC ograve 2 ; PCC o 0 0 ; PCC grave 60 0 ; +CC otilde 2 ; PCC o 0 0 ; PCC tilde -20 0 ; +CC scaron 2 ; PCC s 0 0 ; PCC caron -10 0 ; +CC uacute 2 ; PCC u 0 0 ; PCC acute 70 0 ; +CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; +CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 20 0 ; +CC ugrave 2 ; PCC u 0 0 ; PCC grave 50 0 ; +CC yacute 2 ; PCC y 0 0 ; PCC acute 60 0 ; +CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ; +CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ; +EndComposites +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzdr.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzdr.afm new file mode 100644 index 00000000..6b98e8d3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/afm/pzdr.afm @@ -0,0 +1,222 @@ +StartFontMetrics 2.0 +Comment Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Fri Dec 1 12:57:42 1989 +Comment UniqueID 26200 +Comment VMusage 39281 49041 +FontName ZapfDingbats +FullName ITC Zapf Dingbats +FamilyName ITC Zapf Dingbats +Weight Medium +ItalicAngle 0 +IsFixedPitch false +FontBBox -1 -143 981 820 +UnderlinePosition -98 +UnderlineThickness 54 +Version 001.004 +Notice Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation. +EncodingScheme FontSpecific +StartCharMetrics 202 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ; +C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ; +C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ; +C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ; +C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ; +C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ; +C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ; +C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ; +C 41 ; WX 690 ; N a117 ; B 35 138 655 553 ; +C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ; +C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ; +C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ; +C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ; +C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ; +C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ; +C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ; +C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ; +C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ; +C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ; +C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ; +C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ; +C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ; +C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ; +C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ; +C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ; +C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ; +C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ; +C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ; +C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ; +C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ; +C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ; +C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ; +C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ; +C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ; +C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ; +C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ; +C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ; +C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ; +C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ; +C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ; +C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ; +C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ; +C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ; +C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ; +C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ; +C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ; +C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ; +C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ; +C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ; +C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ; +C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ; +C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ; +C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ; +C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ; +C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ; +C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ; +C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ; +C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ; +C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ; +C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ; +C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ; +C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ; +C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ; +C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ; +C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ; +C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ; +C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ; +C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ; +C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ; +C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ; +C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ; +C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ; +C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ; +C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ; +C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ; +C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ; +C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ; +C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ; +C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ; +C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ; +C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ; +C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ; +C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ; +C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ; +C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ; +C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ; +C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ; +C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ; +C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ; +C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ; +C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ; +C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ; +C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ; +C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ; +C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ; +C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ; +C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ; +C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ; +C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ; +C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ; +C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ; +C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ; +C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ; +C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ; +C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ; +C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ; +C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ; +C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ; +C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ; +C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ; +C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ; +C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ; +C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ; +C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ; +C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ; +C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ; +C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ; +C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ; +C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ; +C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ; +C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ; +C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ; +C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ; +C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ; +C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ; +C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ; +C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ; +C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ; +C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ; +C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ; +C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ; +C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ; +C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ; +C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ; +C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ; +C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ; +C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ; +C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ; +C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ; +C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ; +C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ; +C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ; +C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ; +C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ; +C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ; +C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ; +C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ; +C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ; +C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ; +C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ; +C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ; +C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ; +C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ; +C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ; +C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ; +C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ; +C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ; +C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ; +C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ; +C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ; +C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ; +C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ; +C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ; +C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ; +C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ; +C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ; +C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ; +C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ; +C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ; +C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ; +C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ; +C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ; +C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ; +C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ; +C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ; +C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ; +C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ; +C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ; +C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ; +C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ; +C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ; +C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ; +C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ; +C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ; +C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ; +C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ; +C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ; +C -1 ; WX 410 ; N a86 ; B 35 0 375 692 ; +C -1 ; WX 509 ; N a85 ; B 35 0 475 692 ; +C -1 ; WX 334 ; N a95 ; B 35 0 299 692 ; +C -1 ; WX 509 ; N a205 ; B 35 0 475 692 ; +C -1 ; WX 390 ; N a89 ; B 35 -14 356 705 ; +C -1 ; WX 234 ; N a87 ; B 35 -14 199 705 ; +C -1 ; WX 276 ; N a91 ; B 35 0 242 692 ; +C -1 ; WX 390 ; N a90 ; B 35 -14 355 705 ; +C -1 ; WX 410 ; N a206 ; B 35 0 375 692 ; +C -1 ; WX 317 ; N a94 ; B 35 0 283 692 ; +C -1 ; WX 317 ; N a93 ; B 35 0 283 692 ; +C -1 ; WX 276 ; N a92 ; B 35 0 242 692 ; +C -1 ; WX 334 ; N a96 ; B 35 0 299 692 ; +C -1 ; WX 234 ; N a88 ; B 35 -14 199 705 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm new file mode 100644 index 00000000..eb80542b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm @@ -0,0 +1,342 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:00 1997 +Comment UniqueID 43048 +Comment VMusage 41139 52164 +FontName Courier-Bold +FullName Courier Bold +FamilyName Courier +Weight Bold +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -113 -250 749 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; +C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; +C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; +C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; +C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; +C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; +C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ; +C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; +C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; +C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; +C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; +C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; +C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; +C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; +C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; +C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; +C 49 ; WX 600 ; N one ; B 81 0 539 616 ; +C 50 ; WX 600 ; N two ; B 61 0 499 616 ; +C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; +C 52 ; WX 600 ; N four ; B 53 0 507 616 ; +C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; +C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; +C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; +C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; +C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; +C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; +C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; +C 60 ; WX 600 ; N less ; B 66 15 523 501 ; +C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; +C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; +C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; +C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; +C 65 ; WX 600 ; N A ; B -9 0 609 562 ; +C 66 ; WX 600 ; N B ; B 30 0 573 562 ; +C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; +C 68 ; WX 600 ; N D ; B 30 0 594 562 ; +C 69 ; WX 600 ; N E ; B 25 0 560 562 ; +C 70 ; WX 600 ; N F ; B 39 0 570 562 ; +C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; +C 72 ; WX 600 ; N H ; B 20 0 580 562 ; +C 73 ; WX 600 ; N I ; B 77 0 523 562 ; +C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; +C 75 ; WX 600 ; N K ; B 21 0 599 562 ; +C 76 ; WX 600 ; N L ; B 39 0 578 562 ; +C 77 ; WX 600 ; N M ; B -2 0 602 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; +C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; +C 80 ; WX 600 ; N P ; B 48 0 559 562 ; +C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; +C 82 ; WX 600 ; N R ; B 24 0 599 562 ; +C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; +C 84 ; WX 600 ; N T ; B 21 0 579 562 ; +C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; +C 86 ; WX 600 ; N V ; B -13 0 613 562 ; +C 87 ; WX 600 ; N W ; B -18 0 618 562 ; +C 88 ; WX 600 ; N X ; B 12 0 588 562 ; +C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; +C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; +C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; +C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; +C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; +C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; +C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; +C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; +C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; +C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; +C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; +C 104 ; WX 600 ; N h ; B 5 0 592 626 ; +C 105 ; WX 600 ; N i ; B 77 0 523 658 ; +C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; +C 107 ; WX 600 ; N k ; B 20 0 585 626 ; +C 108 ; WX 600 ; N l ; B 77 0 523 626 ; +C 109 ; WX 600 ; N m ; B -22 0 626 454 ; +C 110 ; WX 600 ; N n ; B 18 0 592 454 ; +C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; +C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; +C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; +C 114 ; WX 600 ; N r ; B 47 0 580 454 ; +C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; +C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; +C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; +C 118 ; WX 600 ; N v ; B -1 0 601 439 ; +C 119 ; WX 600 ; N w ; B -18 0 618 439 ; +C 120 ; WX 600 ; N x ; B 6 0 594 439 ; +C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; +C 122 ; WX 600 ; N z ; B 81 0 520 439 ; +C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; +C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; +C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; +C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; +C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; +C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; +C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; +C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ; +C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; +C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ; +C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; +C 168 ; WX 600 ; N currency ; B 54 49 546 517 ; +C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 593 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 593 626 ; +C 177 ; WX 600 ; N endash ; B 65 203 535 313 ; +C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; +C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; +C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; +C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; +C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; +C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; +C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; +C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; +C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; +C 193 ; WX 600 ; N grave ; B 132 508 395 661 ; +C 194 ; WX 600 ; N acute ; B 205 508 468 661 ; +C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ; +C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ; +C 197 ; WX 600 ; N macron ; B 88 505 512 585 ; +C 198 ; WX 600 ; N breve ; B 83 468 517 631 ; +C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ; +C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ; +C 202 ; WX 600 ; N ring ; B 198 481 402 678 ; +C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; +C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ; +C 207 ; WX 600 ; N caron ; B 103 493 497 667 ; +C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 602 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ; +C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; +C 234 ; WX 600 ; N OE ; B -25 0 595 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; +C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ; +C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ; +C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ; +C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ; +C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ; +C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ; +C -1 ; WX 600 ; N divide ; B 71 16 529 500 ; +C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; +C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; +C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ; +C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; +C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ; +C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ; +C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ; +C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ; +C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ; +C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ; +C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ; +C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ; +C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ; +C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ; +C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ; +C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; +C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ; +C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ; +C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; +C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ; +C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ; +C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ; +C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ; +C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ; +C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ; +C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ; +C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; +C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ; +C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ; +C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ; +C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ; +C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; +C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ; +C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ; +C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ; +C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ; +C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ; +C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 580 661 ; +C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ; +C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ; +C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ; +C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ; +C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ; +C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ; +C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ; +C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ; +C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; +C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ; +C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; +C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ; +C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ; +C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ; +C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ; +C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ; +C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ; +C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ; +C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ; +C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ; +C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ; +C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ; +C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; +C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ; +C -1 ; WX 600 ; N degree ; B 86 243 474 616 ; +C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ; +C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; +C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ; +C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ; +C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ; +C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ; +C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; +C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ; +C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ; +C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ; +C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ; +C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm new file mode 100644 index 00000000..29d3b8b1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm @@ -0,0 +1,342 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:46 1997 +Comment UniqueID 43049 +Comment VMusage 17529 79244 +FontName Courier-BoldOblique +FullName Courier Bold Oblique +FamilyName Courier +Weight Bold +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -57 -250 869 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ; +C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ; +C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ; +C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ; +C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ; +C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ; +C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ; +C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ; +C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; +C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ; +C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; +C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; +C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; +C 46 ; WX 600 ; N period ; B 206 -15 427 171 ; +C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ; +C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ; +C 49 ; WX 600 ; N one ; B 93 0 562 616 ; +C 50 ; WX 600 ; N two ; B 61 0 594 616 ; +C 51 ; WX 600 ; N three ; B 71 -15 571 616 ; +C 52 ; WX 600 ; N four ; B 81 0 559 616 ; +C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; +C 54 ; WX 600 ; N six ; B 135 -15 652 616 ; +C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; +C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; +C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ; +C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ; +C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ; +C 60 ; WX 600 ; N less ; B 120 15 613 501 ; +C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; +C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; +C 63 ; WX 600 ; N question ; B 183 -14 592 580 ; +C 64 ; WX 600 ; N at ; B 65 -15 642 616 ; +C 65 ; WX 600 ; N A ; B -9 0 632 562 ; +C 66 ; WX 600 ; N B ; B 30 0 630 562 ; +C 67 ; WX 600 ; N C ; B 74 -18 675 580 ; +C 68 ; WX 600 ; N D ; B 30 0 664 562 ; +C 69 ; WX 600 ; N E ; B 25 0 670 562 ; +C 70 ; WX 600 ; N F ; B 39 0 684 562 ; +C 71 ; WX 600 ; N G ; B 74 -18 675 580 ; +C 72 ; WX 600 ; N H ; B 20 0 700 562 ; +C 73 ; WX 600 ; N I ; B 77 0 643 562 ; +C 74 ; WX 600 ; N J ; B 58 -18 721 562 ; +C 75 ; WX 600 ; N K ; B 21 0 692 562 ; +C 76 ; WX 600 ; N L ; B 39 0 636 562 ; +C 77 ; WX 600 ; N M ; B -2 0 722 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 730 562 ; +C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; +C 80 ; WX 600 ; N P ; B 48 0 643 562 ; +C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ; +C 82 ; WX 600 ; N R ; B 24 0 617 562 ; +C 83 ; WX 600 ; N S ; B 54 -22 673 582 ; +C 84 ; WX 600 ; N T ; B 86 0 679 562 ; +C 85 ; WX 600 ; N U ; B 101 -18 716 562 ; +C 86 ; WX 600 ; N V ; B 84 0 733 562 ; +C 87 ; WX 600 ; N W ; B 79 0 738 562 ; +C 88 ; WX 600 ; N X ; B 12 0 690 562 ; +C 89 ; WX 600 ; N Y ; B 109 0 709 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 637 562 ; +C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; +C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ; +C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; +C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; +C 97 ; WX 600 ; N a ; B 61 -15 593 454 ; +C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; +C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; +C 100 ; WX 600 ; N d ; B 60 -15 645 626 ; +C 101 ; WX 600 ; N e ; B 81 -15 605 454 ; +C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 40 -146 674 454 ; +C 104 ; WX 600 ; N h ; B 18 0 615 626 ; +C 105 ; WX 600 ; N i ; B 77 0 546 658 ; +C 106 ; WX 600 ; N j ; B 36 -146 580 658 ; +C 107 ; WX 600 ; N k ; B 33 0 643 626 ; +C 108 ; WX 600 ; N l ; B 77 0 546 626 ; +C 109 ; WX 600 ; N m ; B -22 0 649 454 ; +C 110 ; WX 600 ; N n ; B 18 0 615 454 ; +C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; +C 112 ; WX 600 ; N p ; B -32 -142 622 454 ; +C 113 ; WX 600 ; N q ; B 60 -142 685 454 ; +C 114 ; WX 600 ; N r ; B 47 0 655 454 ; +C 115 ; WX 600 ; N s ; B 66 -17 608 459 ; +C 116 ; WX 600 ; N t ; B 118 -15 567 562 ; +C 117 ; WX 600 ; N u ; B 70 -15 592 439 ; +C 118 ; WX 600 ; N v ; B 70 0 695 439 ; +C 119 ; WX 600 ; N w ; B 53 0 712 439 ; +C 120 ; WX 600 ; N x ; B 6 0 671 439 ; +C 121 ; WX 600 ; N y ; B -21 -142 695 439 ; +C 122 ; WX 600 ; N z ; B 81 0 614 439 ; +C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ; +C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ; +C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; +C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ; +C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ; +C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ; +C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ; +C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ; +C 165 ; WX 600 ; N yen ; B 98 0 710 562 ; +C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ; +C 167 ; WX 600 ; N section ; B 74 -70 620 580 ; +C 168 ; WX 600 ; N currency ; B 77 49 644 517 ; +C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 644 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 644 626 ; +C 177 ; WX 600 ; N endash ; B 108 203 602 313 ; +C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ; +C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ; +C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ; +C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ; +C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ; +C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ; +C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ; +C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ; +C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ; +C 193 ; WX 600 ; N grave ; B 272 508 503 661 ; +C 194 ; WX 600 ; N acute ; B 312 508 609 661 ; +C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ; +C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ; +C 197 ; WX 600 ; N macron ; B 195 505 637 585 ; +C 198 ; WX 600 ; N breve ; B 217 468 652 631 ; +C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ; +C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ; +C 202 ; WX 600 ; N ring ; B 319 481 528 678 ; +C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ; +C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ; +C 207 ; WX 600 ; N caron ; B 238 493 633 667 ; +C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 708 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ; +C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ; +C 234 ; WX 600 ; N OE ; B 26 0 701 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ; +C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ; +C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ; +C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ; +C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ; +C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ; +C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ; +C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ; +C -1 ; WX 600 ; N divide ; B 114 16 596 500 ; +C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ; +C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ; +C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ; +C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ; +C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ; +C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ; +C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ; +C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ; +C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ; +C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ; +C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ; +C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ; +C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ; +C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ; +C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ; +C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ; +C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ; +C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ; +C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ; +C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ; +C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ; +C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ; +C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ; +C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ; +C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ; +C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ; +C -1 ; WX 600 ; N threesuperior ; B 193 222 526 616 ; +C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ; +C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ; +C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ; +C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ; +C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ; +C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ; +C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ; +C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ; +C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ; +C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ; +C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ; +C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ; +C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 655 661 ; +C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ; +C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ; +C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ; +C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ; +C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ; +C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ; +C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ; +C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ; +C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ; +C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; +C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ; +C -1 ; WX 600 ; N twosuperior ; B 191 230 542 616 ; +C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ; +C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ; +C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ; +C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ; +C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ; +C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ; +C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ; +C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ; +C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ; +C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ; +C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ; +C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ; +C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ; +C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ; +C -1 ; WX 600 ; N degree ; B 173 243 570 616 ; +C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ; +C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ; +C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ; +C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ; +C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ; +C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ; +C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ; +C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ; +C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; +C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ; +C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ; +C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ; +C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ; +C -1 ; WX 600 ; N onesuperior ; B 212 230 514 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm new file mode 100644 index 00000000..3dc163f7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm @@ -0,0 +1,342 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 17:37:52 1997 +Comment UniqueID 43051 +Comment VMusage 16248 75829 +FontName Courier-Oblique +FullName Courier Oblique +FamilyName Courier +Weight Medium +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -27 -250 849 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; +C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; +C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; +C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; +C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; +C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; +C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ; +C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; +C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; +C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; +C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; +C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; +C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; +C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; +C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; +C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; +C 49 ; WX 600 ; N one ; B 98 0 515 622 ; +C 50 ; WX 600 ; N two ; B 70 0 568 622 ; +C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; +C 52 ; WX 600 ; N four ; B 108 0 541 622 ; +C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; +C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; +C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; +C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; +C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; +C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; +C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; +C 60 ; WX 600 ; N less ; B 96 42 610 472 ; +C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; +C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; +C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; +C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; +C 65 ; WX 600 ; N A ; B 3 0 607 562 ; +C 66 ; WX 600 ; N B ; B 43 0 616 562 ; +C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; +C 68 ; WX 600 ; N D ; B 43 0 645 562 ; +C 69 ; WX 600 ; N E ; B 53 0 660 562 ; +C 70 ; WX 600 ; N F ; B 53 0 660 562 ; +C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; +C 72 ; WX 600 ; N H ; B 32 0 687 562 ; +C 73 ; WX 600 ; N I ; B 96 0 623 562 ; +C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; +C 75 ; WX 600 ; N K ; B 38 0 671 562 ; +C 76 ; WX 600 ; N L ; B 47 0 607 562 ; +C 77 ; WX 600 ; N M ; B 4 0 715 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; +C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; +C 80 ; WX 600 ; N P ; B 79 0 644 562 ; +C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; +C 82 ; WX 600 ; N R ; B 38 0 598 562 ; +C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; +C 84 ; WX 600 ; N T ; B 108 0 665 562 ; +C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; +C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; +C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; +C 88 ; WX 600 ; N X ; B 23 0 675 562 ; +C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; +C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; +C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; +C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; +C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; +C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; +C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; +C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; +C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; +C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; +C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; +C 104 ; WX 600 ; N h ; B 33 0 592 629 ; +C 105 ; WX 600 ; N i ; B 95 0 515 657 ; +C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; +C 107 ; WX 600 ; N k ; B 58 0 633 629 ; +C 108 ; WX 600 ; N l ; B 95 0 515 629 ; +C 109 ; WX 600 ; N m ; B -5 0 615 441 ; +C 110 ; WX 600 ; N n ; B 26 0 585 441 ; +C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; +C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; +C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; +C 114 ; WX 600 ; N r ; B 60 0 636 441 ; +C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; +C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; +C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; +C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; +C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; +C 120 ; WX 600 ; N x ; B 20 0 655 426 ; +C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; +C 122 ; WX 600 ; N z ; B 99 0 593 426 ; +C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; +C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; +C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; +C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; +C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; +C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; +C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; +C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ; +C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; +C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ; +C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; +C 168 ; WX 600 ; N currency ; B 94 58 628 506 ; +C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 619 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 619 629 ; +C 177 ; WX 600 ; N endash ; B 124 231 586 285 ; +C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; +C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; +C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; +C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; +C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; +C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; +C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; +C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; +C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; +C 193 ; WX 600 ; N grave ; B 294 497 484 672 ; +C 194 ; WX 600 ; N acute ; B 348 497 612 672 ; +C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ; +C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ; +C 197 ; WX 600 ; N macron ; B 232 525 600 565 ; +C 198 ; WX 600 ; N breve ; B 279 501 576 609 ; +C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ; +C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ; +C 202 ; WX 600 ; N ring ; B 332 463 500 627 ; +C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; +C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ; +C 207 ; WX 600 ; N caron ; B 262 492 614 669 ; +C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 655 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ; +C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; +C 234 ; WX 600 ; N OE ; B 59 0 672 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; +C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ; +C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ; +C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ; +C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ; +C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ; +C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ; +C -1 ; WX 600 ; N divide ; B 136 48 573 467 ; +C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ; +C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ; +C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ; +C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ; +C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; +C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ; +C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ; +C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ; +C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ; +C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ; +C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ; +C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ; +C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ; +C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ; +C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ; +C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ; +C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ; +C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; +C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ; +C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; +C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ; +C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ; +C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ; +C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ; +C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ; +C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ; +C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ; +C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; +C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ; +C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ; +C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ; +C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ; +C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ; +C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ; +C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ; +C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ; +C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ; +C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ; +C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ; +C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 636 672 ; +C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ; +C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ; +C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ; +C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ; +C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ; +C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ; +C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ; +C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ; +C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ; +C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ; +C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ; +C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ; +C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; +C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ; +C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ; +C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ; +C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ; +C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; +C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ; +C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ; +C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ; +C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ; +C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ; +C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ; +C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ; +C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; +C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ; +C -1 ; WX 600 ; N degree ; B 214 269 576 622 ; +C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ; +C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ; +C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; +C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ; +C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ; +C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ; +C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ; +C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ; +C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; +C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ; +C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ; +C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ; +C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ; +C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm new file mode 100644 index 00000000..2f7be81d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm @@ -0,0 +1,342 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 17:27:09 1997 +Comment UniqueID 43050 +Comment VMusage 39754 50779 +FontName Courier +FullName Courier +FamilyName Courier +Weight Medium +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -23 -250 715 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; +C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; +C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; +C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; +C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; +C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; +C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ; +C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; +C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; +C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; +C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; +C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; +C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; +C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; +C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; +C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; +C 49 ; WX 600 ; N one ; B 96 0 505 622 ; +C 50 ; WX 600 ; N two ; B 70 0 471 622 ; +C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; +C 52 ; WX 600 ; N four ; B 78 0 500 622 ; +C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; +C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; +C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; +C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; +C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; +C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; +C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; +C 60 ; WX 600 ; N less ; B 41 42 519 472 ; +C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; +C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; +C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; +C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; +C 65 ; WX 600 ; N A ; B 3 0 597 562 ; +C 66 ; WX 600 ; N B ; B 43 0 559 562 ; +C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; +C 68 ; WX 600 ; N D ; B 43 0 574 562 ; +C 69 ; WX 600 ; N E ; B 53 0 550 562 ; +C 70 ; WX 600 ; N F ; B 53 0 545 562 ; +C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; +C 72 ; WX 600 ; N H ; B 32 0 568 562 ; +C 73 ; WX 600 ; N I ; B 96 0 504 562 ; +C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; +C 75 ; WX 600 ; N K ; B 38 0 582 562 ; +C 76 ; WX 600 ; N L ; B 47 0 554 562 ; +C 77 ; WX 600 ; N M ; B 4 0 596 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; +C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; +C 80 ; WX 600 ; N P ; B 79 0 558 562 ; +C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; +C 82 ; WX 600 ; N R ; B 38 0 588 562 ; +C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; +C 84 ; WX 600 ; N T ; B 38 0 563 562 ; +C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; +C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; +C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; +C 88 ; WX 600 ; N X ; B 23 0 577 562 ; +C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; +C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; +C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; +C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; +C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; +C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; +C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; +C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; +C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; +C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; +C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; +C 104 ; WX 600 ; N h ; B 18 0 582 629 ; +C 105 ; WX 600 ; N i ; B 95 0 505 657 ; +C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; +C 107 ; WX 600 ; N k ; B 43 0 580 629 ; +C 108 ; WX 600 ; N l ; B 95 0 505 629 ; +C 109 ; WX 600 ; N m ; B -5 0 605 441 ; +C 110 ; WX 600 ; N n ; B 26 0 575 441 ; +C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; +C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; +C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; +C 114 ; WX 600 ; N r ; B 60 0 559 441 ; +C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; +C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; +C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; +C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; +C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; +C 120 ; WX 600 ; N x ; B 20 0 580 426 ; +C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; +C 122 ; WX 600 ; N z ; B 99 0 502 426 ; +C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; +C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; +C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; +C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; +C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; +C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; +C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; +C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ; +C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; +C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ; +C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; +C 168 ; WX 600 ; N currency ; B 73 58 527 506 ; +C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 597 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 597 629 ; +C 177 ; WX 600 ; N endash ; B 75 231 525 285 ; +C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; +C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; +C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; +C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; +C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; +C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; +C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; +C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; +C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; +C 193 ; WX 600 ; N grave ; B 151 497 378 672 ; +C 194 ; WX 600 ; N acute ; B 242 497 469 672 ; +C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ; +C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ; +C 197 ; WX 600 ; N macron ; B 120 525 480 565 ; +C 198 ; WX 600 ; N breve ; B 153 501 447 609 ; +C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ; +C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ; +C 202 ; WX 600 ; N ring ; B 218 463 382 627 ; +C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; +C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ; +C 207 ; WX 600 ; N caron ; B 124 492 476 669 ; +C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 550 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ; +C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; +C 234 ; WX 600 ; N OE ; B 7 0 567 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; +C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ; +C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ; +C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ; +C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ; +C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ; +C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ; +C -1 ; WX 600 ; N divide ; B 87 48 513 467 ; +C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ; +C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ; +C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ; +C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; +C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ; +C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ; +C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ; +C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ; +C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ; +C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ; +C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ; +C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ; +C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ; +C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ; +C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ; +C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; +C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ; +C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; +C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ; +C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ; +C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ; +C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ; +C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ; +C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ; +C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ; +C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; +C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ; +C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ; +C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ; +C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ; +C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ; +C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ; +C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ; +C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ; +C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ; +C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ; +C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 559 672 ; +C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ; +C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ; +C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ; +C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ; +C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ; +C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ; +C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ; +C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ; +C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ; +C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ; +C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ; +C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; +C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ; +C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ; +C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ; +C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ; +C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; +C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ; +C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ; +C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ; +C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ; +C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ; +C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ; +C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ; +C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; +C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ; +C -1 ; WX 600 ; N degree ; B 123 269 477 622 ; +C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ; +C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ; +C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ; +C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ; +C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ; +C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ; +C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; +C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ; +C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ; +C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ; +C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ; +C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm new file mode 100644 index 00000000..837c594e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm @@ -0,0 +1,2827 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:43:52 1997 +Comment UniqueID 43052 +Comment VMusage 37169 48194 +FontName Helvetica-Bold +FullName Helvetica Bold +FamilyName Helvetica +Weight Bold +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -170 -228 1003 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StdHW 118 +StdVW 140 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ; +C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ; +C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ; +C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ; +C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ; +C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ; +C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ; +C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ; +C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ; +C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ; +C 43 ; WX 584 ; N plus ; B 40 0 544 506 ; +C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ; +C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ; +C 46 ; WX 278 ; N period ; B 64 0 214 146 ; +C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ; +C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ; +C 49 ; WX 556 ; N one ; B 69 0 378 710 ; +C 50 ; WX 556 ; N two ; B 26 0 511 710 ; +C 51 ; WX 556 ; N three ; B 27 -19 516 710 ; +C 52 ; WX 556 ; N four ; B 27 0 526 710 ; +C 53 ; WX 556 ; N five ; B 27 -19 516 698 ; +C 54 ; WX 556 ; N six ; B 31 -19 520 710 ; +C 55 ; WX 556 ; N seven ; B 25 0 528 698 ; +C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ; +C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 242 512 ; +C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ; +C 60 ; WX 584 ; N less ; B 38 -8 546 514 ; +C 61 ; WX 584 ; N equal ; B 40 87 544 419 ; +C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ; +C 63 ; WX 611 ; N question ; B 60 0 556 727 ; +C 64 ; WX 975 ; N at ; B 118 -19 856 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 669 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 684 737 ; +C 68 ; WX 722 ; N D ; B 76 0 685 718 ; +C 69 ; WX 667 ; N E ; B 76 0 621 718 ; +C 70 ; WX 611 ; N F ; B 76 0 587 718 ; +C 71 ; WX 778 ; N G ; B 44 -19 713 737 ; +C 72 ; WX 722 ; N H ; B 71 0 651 718 ; +C 73 ; WX 278 ; N I ; B 64 0 214 718 ; +C 74 ; WX 556 ; N J ; B 22 -18 484 718 ; +C 75 ; WX 722 ; N K ; B 87 0 722 718 ; +C 76 ; WX 611 ; N L ; B 76 0 583 718 ; +C 77 ; WX 833 ; N M ; B 69 0 765 718 ; +C 78 ; WX 722 ; N N ; B 69 0 654 718 ; +C 79 ; WX 778 ; N O ; B 44 -19 734 737 ; +C 80 ; WX 667 ; N P ; B 76 0 627 718 ; +C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ; +C 82 ; WX 722 ; N R ; B 76 0 677 718 ; +C 83 ; WX 667 ; N S ; B 39 -19 629 737 ; +C 84 ; WX 611 ; N T ; B 14 0 598 718 ; +C 85 ; WX 722 ; N U ; B 72 -19 651 718 ; +C 86 ; WX 667 ; N V ; B 19 0 648 718 ; +C 87 ; WX 944 ; N W ; B 16 0 929 718 ; +C 88 ; WX 667 ; N X ; B 14 0 653 718 ; +C 89 ; WX 667 ; N Y ; B 15 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 586 718 ; +C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ; +C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ; +C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ; +C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ; +C 97 ; WX 556 ; N a ; B 29 -14 527 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 578 718 ; +C 99 ; WX 556 ; N c ; B 34 -14 524 546 ; +C 100 ; WX 611 ; N d ; B 34 -14 551 718 ; +C 101 ; WX 556 ; N e ; B 23 -14 528 546 ; +C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 40 -217 553 546 ; +C 104 ; WX 611 ; N h ; B 65 0 546 718 ; +C 105 ; WX 278 ; N i ; B 69 0 209 725 ; +C 106 ; WX 278 ; N j ; B 3 -214 209 725 ; +C 107 ; WX 556 ; N k ; B 69 0 562 718 ; +C 108 ; WX 278 ; N l ; B 69 0 209 718 ; +C 109 ; WX 889 ; N m ; B 64 0 826 546 ; +C 110 ; WX 611 ; N n ; B 65 0 546 546 ; +C 111 ; WX 611 ; N o ; B 34 -14 578 546 ; +C 112 ; WX 611 ; N p ; B 62 -207 578 546 ; +C 113 ; WX 611 ; N q ; B 34 -207 552 546 ; +C 114 ; WX 389 ; N r ; B 64 0 373 546 ; +C 115 ; WX 556 ; N s ; B 30 -14 519 546 ; +C 116 ; WX 333 ; N t ; B 10 -6 309 676 ; +C 117 ; WX 611 ; N u ; B 66 -14 545 532 ; +C 118 ; WX 556 ; N v ; B 13 0 543 532 ; +C 119 ; WX 778 ; N w ; B 10 0 769 532 ; +C 120 ; WX 556 ; N x ; B 15 0 541 532 ; +C 121 ; WX 556 ; N y ; B 10 -214 539 532 ; +C 122 ; WX 500 ; N z ; B 20 0 480 532 ; +C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ; +C 124 ; WX 280 ; N bar ; B 84 -225 196 775 ; +C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ; +C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ; +C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ; +C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ; +C 165 ; WX 556 ; N yen ; B -9 0 565 698 ; +C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ; +C 167 ; WX 556 ; N section ; B 34 -184 522 727 ; +C 168 ; WX 556 ; N currency ; B -3 76 559 636 ; +C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ; +C 174 ; WX 611 ; N fi ; B 10 0 542 727 ; +C 175 ; WX 611 ; N fl ; B 10 0 542 727 ; +C 177 ; WX 556 ; N endash ; B 0 227 556 333 ; +C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ; +C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ; +C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ; +C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ; +C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ; +C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ; +C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ; +C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ; +C 193 ; WX 333 ; N grave ; B -23 604 225 750 ; +C 194 ; WX 333 ; N acute ; B 108 604 356 750 ; +C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ; +C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ; +C 197 ; WX 333 ; N macron ; B -6 604 339 678 ; +C 198 ; WX 333 ; N breve ; B -2 604 335 750 ; +C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ; +C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ; +C 202 ; WX 333 ; N ring ; B 59 568 275 776 ; +C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ; +C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ; +C 207 ; WX 333 ; N caron ; B -10 604 343 750 ; +C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 22 401 347 737 ; +C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ; +C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ; +C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 6 401 360 737 ; +C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ; +C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ; +C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ; +C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ; +C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ; +C -1 ; WX 556 ; N abreve ; B 29 -14 527 750 ; +C -1 ; WX 611 ; N uhungarumlaut ; B 66 -14 625 750 ; +C -1 ; WX 556 ; N ecaron ; B 23 -14 528 750 ; +C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ; +C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ; +C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ; +C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ; +C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ; +C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ; +C -1 ; WX 556 ; N scommaaccent ; B 30 -228 519 546 ; +C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ; +C -1 ; WX 722 ; N Uring ; B 72 -19 651 962 ; +C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ; +C -1 ; WX 556 ; N aogonek ; B 29 -224 545 546 ; +C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ; +C -1 ; WX 611 ; N uogonek ; B 66 -228 545 532 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ; +C -1 ; WX 722 ; N Dcroat ; B -5 0 685 718 ; +C -1 ; WX 250 ; N commaaccent ; B 64 -228 199 -50 ; +C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ; +C -1 ; WX 667 ; N Emacron ; B 76 0 621 864 ; +C -1 ; WX 556 ; N ccaron ; B 34 -14 524 750 ; +C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 654 718 ; +C -1 ; WX 278 ; N lacute ; B 69 0 329 936 ; +C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 14 -228 598 718 ; +C -1 ; WX 722 ; N Cacute ; B 44 -19 684 936 ; +C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ; +C -1 ; WX 667 ; N Edotaccent ; B 76 0 621 915 ; +C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ; +C -1 ; WX 556 ; N scedilla ; B 30 -228 519 546 ; +C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 722 ; N Rcaron ; B 76 0 677 936 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 44 -228 713 737 ; +C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ; +C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ; +C -1 ; WX 722 ; N Amacron ; B 20 0 702 864 ; +C -1 ; WX 389 ; N rcaron ; B 18 0 373 750 ; +C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ; +C -1 ; WX 611 ; N Zdotaccent ; B 25 0 586 915 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ; +C -1 ; WX 778 ; N Omacron ; B 44 -19 734 864 ; +C -1 ; WX 722 ; N Racute ; B 76 0 677 936 ; +C -1 ; WX 667 ; N Sacute ; B 39 -19 629 936 ; +C -1 ; WX 743 ; N dcaron ; B 34 -14 750 718 ; +C -1 ; WX 722 ; N Umacron ; B 72 -19 651 864 ; +C -1 ; WX 611 ; N uring ; B 66 -14 545 776 ; +C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ; +C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Abreve ; B 20 0 702 936 ; +C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ; +C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ; +C -1 ; WX 611 ; N Tcaron ; B 14 0 598 936 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ; +C -1 ; WX 722 ; N Nacute ; B 69 0 654 936 ; +C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ; +C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ; +C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ; +C -1 ; WX 556 ; N cacute ; B 34 -14 524 750 ; +C -1 ; WX 611 ; N nacute ; B 65 0 546 750 ; +C -1 ; WX 611 ; N umacron ; B 66 -14 545 678 ; +C -1 ; WX 722 ; N Ncaron ; B 69 0 654 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ; +C -1 ; WX 280 ; N brokenbar ; B 84 -150 196 700 ; +C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ; +C -1 ; WX 778 ; N Gbreve ; B 44 -19 713 936 ; +C -1 ; WX 278 ; N Idotaccent ; B 64 0 214 915 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ; +C -1 ; WX 389 ; N racute ; B 64 0 384 750 ; +C -1 ; WX 611 ; N omacron ; B 34 -14 578 678 ; +C -1 ; WX 611 ; N Zacute ; B 25 0 586 936 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ; +C -1 ; WX 278 ; N lcommaaccent ; B 69 -228 213 718 ; +C -1 ; WX 389 ; N tcaron ; B 10 -6 421 878 ; +C -1 ; WX 556 ; N eogonek ; B 23 -228 528 546 ; +C -1 ; WX 722 ; N Uogonek ; B 72 -228 651 718 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ; +C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ; +C -1 ; WX 500 ; N zacute ; B 20 0 480 750 ; +C -1 ; WX 278 ; N iogonek ; B 16 -224 249 725 ; +C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ; +C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ; +C -1 ; WX 556 ; N amacron ; B 29 -14 527 678 ; +C -1 ; WX 556 ; N sacute ; B 30 -14 519 750 ; +C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ; +C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ; +C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ; +C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ; +C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ; +C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ; +C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ; +C -1 ; WX 611 ; N ohungarumlaut ; B 34 -14 625 750 ; +C -1 ; WX 667 ; N Eogonek ; B 76 -224 639 718 ; +C -1 ; WX 611 ; N dcroat ; B 34 -14 650 718 ; +C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ; +C -1 ; WX 667 ; N Scedilla ; B 39 -228 629 737 ; +C -1 ; WX 400 ; N lcaron ; B 69 0 408 718 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 722 718 ; +C -1 ; WX 611 ; N Lacute ; B 76 0 583 936 ; +C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ; +C -1 ; WX 556 ; N edotaccent ; B 23 -14 528 729 ; +C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ; +C -1 ; WX 278 ; N Imacron ; B -33 0 312 864 ; +C -1 ; WX 611 ; N Lcaron ; B 76 0 583 718 ; +C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 72 -19 681 936 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ; +C -1 ; WX 556 ; N emacron ; B 23 -14 528 678 ; +C -1 ; WX 611 ; N gbreve ; B 40 -217 553 750 ; +C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ; +C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ; +C -1 ; WX 667 ; N Scommaaccent ; B 39 -228 629 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 44 -19 734 936 ; +C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; +C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ; +C -1 ; WX 722 ; N Ccaron ; B 44 -19 684 936 ; +C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B 76 0 685 936 ; +C -1 ; WX 389 ; N rcommaaccent ; B 64 -228 373 546 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ; +C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 677 718 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 583 718 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ; +C -1 ; WX 722 ; N Aogonek ; B 20 -224 742 718 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ; +C -1 ; WX 500 ; N zdotaccent ; B 20 0 480 729 ; +C -1 ; WX 667 ; N Ecaron ; B 76 0 621 936 ; +C -1 ; WX 278 ; N Iogonek ; B -11 -228 222 718 ; +C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 562 718 ; +C -1 ; WX 584 ; N minus ; B 40 197 544 309 ; +C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ; +C -1 ; WX 611 ; N ncaron ; B 65 0 546 750 ; +C -1 ; WX 333 ; N tcommaaccent ; B 10 -228 309 676 ; +C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ; +C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ; +C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 611 ; N gcommaaccent ; B 40 -217 553 850 ; +C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ; +C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 546 546 ; +C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ; +C -1 ; WX 278 ; N imacron ; B -8 0 285 678 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2481 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -50 +KPX A Gbreve -50 +KPX A Gcommaaccent -50 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -90 +KPX A Tcaron -90 +KPX A Tcommaaccent -90 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -80 +KPX A W -60 +KPX A Y -110 +KPX A Yacute -110 +KPX A Ydieresis -110 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -30 +KPX A y -30 +KPX A yacute -30 +KPX A ydieresis -30 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -50 +KPX Aacute Gbreve -50 +KPX Aacute Gcommaaccent -50 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -90 +KPX Aacute Tcaron -90 +KPX Aacute Tcommaaccent -90 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -80 +KPX Aacute W -60 +KPX Aacute Y -110 +KPX Aacute Yacute -110 +KPX Aacute Ydieresis -110 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -30 +KPX Aacute y -30 +KPX Aacute yacute -30 +KPX Aacute ydieresis -30 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -50 +KPX Abreve Gbreve -50 +KPX Abreve Gcommaaccent -50 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -90 +KPX Abreve Tcaron -90 +KPX Abreve Tcommaaccent -90 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -80 +KPX Abreve W -60 +KPX Abreve Y -110 +KPX Abreve Yacute -110 +KPX Abreve Ydieresis -110 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -30 +KPX Abreve y -30 +KPX Abreve yacute -30 +KPX Abreve ydieresis -30 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -50 +KPX Acircumflex Gbreve -50 +KPX Acircumflex Gcommaaccent -50 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -90 +KPX Acircumflex Tcaron -90 +KPX Acircumflex Tcommaaccent -90 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -80 +KPX Acircumflex W -60 +KPX Acircumflex Y -110 +KPX Acircumflex Yacute -110 +KPX Acircumflex Ydieresis -110 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -30 +KPX Acircumflex y -30 +KPX Acircumflex yacute -30 +KPX Acircumflex ydieresis -30 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -50 +KPX Adieresis Gbreve -50 +KPX Adieresis Gcommaaccent -50 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -90 +KPX Adieresis Tcaron -90 +KPX Adieresis Tcommaaccent -90 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -80 +KPX Adieresis W -60 +KPX Adieresis Y -110 +KPX Adieresis Yacute -110 +KPX Adieresis Ydieresis -110 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -30 +KPX Adieresis y -30 +KPX Adieresis yacute -30 +KPX Adieresis ydieresis -30 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -50 +KPX Agrave Gbreve -50 +KPX Agrave Gcommaaccent -50 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -90 +KPX Agrave Tcaron -90 +KPX Agrave Tcommaaccent -90 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -80 +KPX Agrave W -60 +KPX Agrave Y -110 +KPX Agrave Yacute -110 +KPX Agrave Ydieresis -110 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -30 +KPX Agrave y -30 +KPX Agrave yacute -30 +KPX Agrave ydieresis -30 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -50 +KPX Amacron Gbreve -50 +KPX Amacron Gcommaaccent -50 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -90 +KPX Amacron Tcaron -90 +KPX Amacron Tcommaaccent -90 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -80 +KPX Amacron W -60 +KPX Amacron Y -110 +KPX Amacron Yacute -110 +KPX Amacron Ydieresis -110 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -30 +KPX Amacron y -30 +KPX Amacron yacute -30 +KPX Amacron ydieresis -30 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -50 +KPX Aogonek Gbreve -50 +KPX Aogonek Gcommaaccent -50 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -90 +KPX Aogonek Tcaron -90 +KPX Aogonek Tcommaaccent -90 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -80 +KPX Aogonek W -60 +KPX Aogonek Y -110 +KPX Aogonek Yacute -110 +KPX Aogonek Ydieresis -110 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -30 +KPX Aogonek y -30 +KPX Aogonek yacute -30 +KPX Aogonek ydieresis -30 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -50 +KPX Aring Gbreve -50 +KPX Aring Gcommaaccent -50 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -90 +KPX Aring Tcaron -90 +KPX Aring Tcommaaccent -90 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -80 +KPX Aring W -60 +KPX Aring Y -110 +KPX Aring Yacute -110 +KPX Aring Ydieresis -110 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -30 +KPX Aring y -30 +KPX Aring yacute -30 +KPX Aring ydieresis -30 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -50 +KPX Atilde Gbreve -50 +KPX Atilde Gcommaaccent -50 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -90 +KPX Atilde Tcaron -90 +KPX Atilde Tcommaaccent -90 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -80 +KPX Atilde W -60 +KPX Atilde Y -110 +KPX Atilde Yacute -110 +KPX Atilde Ydieresis -110 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -30 +KPX Atilde y -30 +KPX Atilde yacute -30 +KPX Atilde ydieresis -30 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -40 +KPX D Y -70 +KPX D Yacute -70 +KPX D Ydieresis -70 +KPX D comma -30 +KPX D period -30 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -70 +KPX Dcaron Yacute -70 +KPX Dcaron Ydieresis -70 +KPX Dcaron comma -30 +KPX Dcaron period -30 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -70 +KPX Dcroat Yacute -70 +KPX Dcroat Ydieresis -70 +KPX Dcroat comma -30 +KPX Dcroat period -30 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -20 +KPX F aacute -20 +KPX F abreve -20 +KPX F acircumflex -20 +KPX F adieresis -20 +KPX F agrave -20 +KPX F amacron -20 +KPX F aogonek -20 +KPX F aring -20 +KPX F atilde -20 +KPX F comma -100 +KPX F period -100 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J comma -20 +KPX J period -20 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -15 +KPX K eacute -15 +KPX K ecaron -15 +KPX K ecircumflex -15 +KPX K edieresis -15 +KPX K edotaccent -15 +KPX K egrave -15 +KPX K emacron -15 +KPX K eogonek -15 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -15 +KPX Kcommaaccent eacute -15 +KPX Kcommaaccent ecaron -15 +KPX Kcommaaccent ecircumflex -15 +KPX Kcommaaccent edieresis -15 +KPX Kcommaaccent edotaccent -15 +KPX Kcommaaccent egrave -15 +KPX Kcommaaccent emacron -15 +KPX Kcommaaccent eogonek -15 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -90 +KPX L Tcaron -90 +KPX L Tcommaaccent -90 +KPX L V -110 +KPX L W -80 +KPX L Y -120 +KPX L Yacute -120 +KPX L Ydieresis -120 +KPX L quotedblright -140 +KPX L quoteright -140 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -90 +KPX Lacute Tcaron -90 +KPX Lacute Tcommaaccent -90 +KPX Lacute V -110 +KPX Lacute W -80 +KPX Lacute Y -120 +KPX Lacute Yacute -120 +KPX Lacute Ydieresis -120 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -140 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -90 +KPX Lcommaaccent Tcaron -90 +KPX Lcommaaccent Tcommaaccent -90 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -80 +KPX Lcommaaccent Y -120 +KPX Lcommaaccent Yacute -120 +KPX Lcommaaccent Ydieresis -120 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -140 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -90 +KPX Lslash Tcaron -90 +KPX Lslash Tcommaaccent -90 +KPX Lslash V -110 +KPX Lslash W -80 +KPX Lslash Y -120 +KPX Lslash Yacute -120 +KPX Lslash Ydieresis -120 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -140 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -50 +KPX O Aacute -50 +KPX O Abreve -50 +KPX O Acircumflex -50 +KPX O Adieresis -50 +KPX O Agrave -50 +KPX O Amacron -50 +KPX O Aogonek -50 +KPX O Aring -50 +KPX O Atilde -50 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -50 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -50 +KPX Oacute Aacute -50 +KPX Oacute Abreve -50 +KPX Oacute Acircumflex -50 +KPX Oacute Adieresis -50 +KPX Oacute Agrave -50 +KPX Oacute Amacron -50 +KPX Oacute Aogonek -50 +KPX Oacute Aring -50 +KPX Oacute Atilde -50 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -50 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -50 +KPX Ocircumflex Aacute -50 +KPX Ocircumflex Abreve -50 +KPX Ocircumflex Acircumflex -50 +KPX Ocircumflex Adieresis -50 +KPX Ocircumflex Agrave -50 +KPX Ocircumflex Amacron -50 +KPX Ocircumflex Aogonek -50 +KPX Ocircumflex Aring -50 +KPX Ocircumflex Atilde -50 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -50 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -50 +KPX Odieresis Aacute -50 +KPX Odieresis Abreve -50 +KPX Odieresis Acircumflex -50 +KPX Odieresis Adieresis -50 +KPX Odieresis Agrave -50 +KPX Odieresis Amacron -50 +KPX Odieresis Aogonek -50 +KPX Odieresis Aring -50 +KPX Odieresis Atilde -50 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -50 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -50 +KPX Ograve Aacute -50 +KPX Ograve Abreve -50 +KPX Ograve Acircumflex -50 +KPX Ograve Adieresis -50 +KPX Ograve Agrave -50 +KPX Ograve Amacron -50 +KPX Ograve Aogonek -50 +KPX Ograve Aring -50 +KPX Ograve Atilde -50 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -50 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -50 +KPX Ohungarumlaut Aacute -50 +KPX Ohungarumlaut Abreve -50 +KPX Ohungarumlaut Acircumflex -50 +KPX Ohungarumlaut Adieresis -50 +KPX Ohungarumlaut Agrave -50 +KPX Ohungarumlaut Amacron -50 +KPX Ohungarumlaut Aogonek -50 +KPX Ohungarumlaut Aring -50 +KPX Ohungarumlaut Atilde -50 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -50 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -50 +KPX Omacron Aacute -50 +KPX Omacron Abreve -50 +KPX Omacron Acircumflex -50 +KPX Omacron Adieresis -50 +KPX Omacron Agrave -50 +KPX Omacron Amacron -50 +KPX Omacron Aogonek -50 +KPX Omacron Aring -50 +KPX Omacron Atilde -50 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -50 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -50 +KPX Oslash Aacute -50 +KPX Oslash Abreve -50 +KPX Oslash Acircumflex -50 +KPX Oslash Adieresis -50 +KPX Oslash Agrave -50 +KPX Oslash Amacron -50 +KPX Oslash Aogonek -50 +KPX Oslash Aring -50 +KPX Oslash Atilde -50 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -50 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -50 +KPX Otilde Aacute -50 +KPX Otilde Abreve -50 +KPX Otilde Acircumflex -50 +KPX Otilde Adieresis -50 +KPX Otilde Agrave -50 +KPX Otilde Amacron -50 +KPX Otilde Aogonek -50 +KPX Otilde Aring -50 +KPX Otilde Atilde -50 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -50 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -100 +KPX P Aacute -100 +KPX P Abreve -100 +KPX P Acircumflex -100 +KPX P Adieresis -100 +KPX P Agrave -100 +KPX P Amacron -100 +KPX P Aogonek -100 +KPX P Aring -100 +KPX P Atilde -100 +KPX P a -30 +KPX P aacute -30 +KPX P abreve -30 +KPX P acircumflex -30 +KPX P adieresis -30 +KPX P agrave -30 +KPX P amacron -30 +KPX P aogonek -30 +KPX P aring -30 +KPX P atilde -30 +KPX P comma -120 +KPX P e -30 +KPX P eacute -30 +KPX P ecaron -30 +KPX P ecircumflex -30 +KPX P edieresis -30 +KPX P edotaccent -30 +KPX P egrave -30 +KPX P emacron -30 +KPX P eogonek -30 +KPX P o -40 +KPX P oacute -40 +KPX P ocircumflex -40 +KPX P odieresis -40 +KPX P ograve -40 +KPX P ohungarumlaut -40 +KPX P omacron -40 +KPX P oslash -40 +KPX P otilde -40 +KPX P period -120 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q comma 20 +KPX Q period 20 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -20 +KPX R Tcaron -20 +KPX R Tcommaaccent -20 +KPX R U -20 +KPX R Uacute -20 +KPX R Ucircumflex -20 +KPX R Udieresis -20 +KPX R Ugrave -20 +KPX R Uhungarumlaut -20 +KPX R Umacron -20 +KPX R Uogonek -20 +KPX R Uring -20 +KPX R V -50 +KPX R W -40 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -20 +KPX Racute Tcaron -20 +KPX Racute Tcommaaccent -20 +KPX Racute U -20 +KPX Racute Uacute -20 +KPX Racute Ucircumflex -20 +KPX Racute Udieresis -20 +KPX Racute Ugrave -20 +KPX Racute Uhungarumlaut -20 +KPX Racute Umacron -20 +KPX Racute Uogonek -20 +KPX Racute Uring -20 +KPX Racute V -50 +KPX Racute W -40 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -20 +KPX Rcaron Tcaron -20 +KPX Rcaron Tcommaaccent -20 +KPX Rcaron U -20 +KPX Rcaron Uacute -20 +KPX Rcaron Ucircumflex -20 +KPX Rcaron Udieresis -20 +KPX Rcaron Ugrave -20 +KPX Rcaron Uhungarumlaut -20 +KPX Rcaron Umacron -20 +KPX Rcaron Uogonek -20 +KPX Rcaron Uring -20 +KPX Rcaron V -50 +KPX Rcaron W -40 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -20 +KPX Rcommaaccent Tcaron -20 +KPX Rcommaaccent Tcommaaccent -20 +KPX Rcommaaccent U -20 +KPX Rcommaaccent Uacute -20 +KPX Rcommaaccent Ucircumflex -20 +KPX Rcommaaccent Udieresis -20 +KPX Rcommaaccent Ugrave -20 +KPX Rcommaaccent Uhungarumlaut -20 +KPX Rcommaaccent Umacron -20 +KPX Rcommaaccent Uogonek -20 +KPX Rcommaaccent Uring -20 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -40 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -80 +KPX T agrave -80 +KPX T amacron -80 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -80 +KPX T colon -40 +KPX T comma -80 +KPX T e -60 +KPX T eacute -60 +KPX T ecaron -60 +KPX T ecircumflex -60 +KPX T edieresis -60 +KPX T edotaccent -60 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -60 +KPX T hyphen -120 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -80 +KPX T r -80 +KPX T racute -80 +KPX T rcommaaccent -80 +KPX T semicolon -40 +KPX T u -90 +KPX T uacute -90 +KPX T ucircumflex -90 +KPX T udieresis -90 +KPX T ugrave -90 +KPX T uhungarumlaut -90 +KPX T umacron -90 +KPX T uogonek -90 +KPX T uring -90 +KPX T w -60 +KPX T y -60 +KPX T yacute -60 +KPX T ydieresis -60 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -80 +KPX Tcaron agrave -80 +KPX Tcaron amacron -80 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -80 +KPX Tcaron colon -40 +KPX Tcaron comma -80 +KPX Tcaron e -60 +KPX Tcaron eacute -60 +KPX Tcaron ecaron -60 +KPX Tcaron ecircumflex -60 +KPX Tcaron edieresis -60 +KPX Tcaron edotaccent -60 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -60 +KPX Tcaron hyphen -120 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -80 +KPX Tcaron r -80 +KPX Tcaron racute -80 +KPX Tcaron rcommaaccent -80 +KPX Tcaron semicolon -40 +KPX Tcaron u -90 +KPX Tcaron uacute -90 +KPX Tcaron ucircumflex -90 +KPX Tcaron udieresis -90 +KPX Tcaron ugrave -90 +KPX Tcaron uhungarumlaut -90 +KPX Tcaron umacron -90 +KPX Tcaron uogonek -90 +KPX Tcaron uring -90 +KPX Tcaron w -60 +KPX Tcaron y -60 +KPX Tcaron yacute -60 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -80 +KPX Tcommaaccent agrave -80 +KPX Tcommaaccent amacron -80 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -80 +KPX Tcommaaccent colon -40 +KPX Tcommaaccent comma -80 +KPX Tcommaaccent e -60 +KPX Tcommaaccent eacute -60 +KPX Tcommaaccent ecaron -60 +KPX Tcommaaccent ecircumflex -60 +KPX Tcommaaccent edieresis -60 +KPX Tcommaaccent edotaccent -60 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -60 +KPX Tcommaaccent hyphen -120 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -80 +KPX Tcommaaccent r -80 +KPX Tcommaaccent racute -80 +KPX Tcommaaccent rcommaaccent -80 +KPX Tcommaaccent semicolon -40 +KPX Tcommaaccent u -90 +KPX Tcommaaccent uacute -90 +KPX Tcommaaccent ucircumflex -90 +KPX Tcommaaccent udieresis -90 +KPX Tcommaaccent ugrave -90 +KPX Tcommaaccent uhungarumlaut -90 +KPX Tcommaaccent umacron -90 +KPX Tcommaaccent uogonek -90 +KPX Tcommaaccent uring -90 +KPX Tcommaaccent w -60 +KPX Tcommaaccent y -60 +KPX Tcommaaccent yacute -60 +KPX Tcommaaccent ydieresis -60 +KPX U A -50 +KPX U Aacute -50 +KPX U Abreve -50 +KPX U Acircumflex -50 +KPX U Adieresis -50 +KPX U Agrave -50 +KPX U Amacron -50 +KPX U Aogonek -50 +KPX U Aring -50 +KPX U Atilde -50 +KPX U comma -30 +KPX U period -30 +KPX Uacute A -50 +KPX Uacute Aacute -50 +KPX Uacute Abreve -50 +KPX Uacute Acircumflex -50 +KPX Uacute Adieresis -50 +KPX Uacute Agrave -50 +KPX Uacute Amacron -50 +KPX Uacute Aogonek -50 +KPX Uacute Aring -50 +KPX Uacute Atilde -50 +KPX Uacute comma -30 +KPX Uacute period -30 +KPX Ucircumflex A -50 +KPX Ucircumflex Aacute -50 +KPX Ucircumflex Abreve -50 +KPX Ucircumflex Acircumflex -50 +KPX Ucircumflex Adieresis -50 +KPX Ucircumflex Agrave -50 +KPX Ucircumflex Amacron -50 +KPX Ucircumflex Aogonek -50 +KPX Ucircumflex Aring -50 +KPX Ucircumflex Atilde -50 +KPX Ucircumflex comma -30 +KPX Ucircumflex period -30 +KPX Udieresis A -50 +KPX Udieresis Aacute -50 +KPX Udieresis Abreve -50 +KPX Udieresis Acircumflex -50 +KPX Udieresis Adieresis -50 +KPX Udieresis Agrave -50 +KPX Udieresis Amacron -50 +KPX Udieresis Aogonek -50 +KPX Udieresis Aring -50 +KPX Udieresis Atilde -50 +KPX Udieresis comma -30 +KPX Udieresis period -30 +KPX Ugrave A -50 +KPX Ugrave Aacute -50 +KPX Ugrave Abreve -50 +KPX Ugrave Acircumflex -50 +KPX Ugrave Adieresis -50 +KPX Ugrave Agrave -50 +KPX Ugrave Amacron -50 +KPX Ugrave Aogonek -50 +KPX Ugrave Aring -50 +KPX Ugrave Atilde -50 +KPX Ugrave comma -30 +KPX Ugrave period -30 +KPX Uhungarumlaut A -50 +KPX Uhungarumlaut Aacute -50 +KPX Uhungarumlaut Abreve -50 +KPX Uhungarumlaut Acircumflex -50 +KPX Uhungarumlaut Adieresis -50 +KPX Uhungarumlaut Agrave -50 +KPX Uhungarumlaut Amacron -50 +KPX Uhungarumlaut Aogonek -50 +KPX Uhungarumlaut Aring -50 +KPX Uhungarumlaut Atilde -50 +KPX Uhungarumlaut comma -30 +KPX Uhungarumlaut period -30 +KPX Umacron A -50 +KPX Umacron Aacute -50 +KPX Umacron Abreve -50 +KPX Umacron Acircumflex -50 +KPX Umacron Adieresis -50 +KPX Umacron Agrave -50 +KPX Umacron Amacron -50 +KPX Umacron Aogonek -50 +KPX Umacron Aring -50 +KPX Umacron Atilde -50 +KPX Umacron comma -30 +KPX Umacron period -30 +KPX Uogonek A -50 +KPX Uogonek Aacute -50 +KPX Uogonek Abreve -50 +KPX Uogonek Acircumflex -50 +KPX Uogonek Adieresis -50 +KPX Uogonek Agrave -50 +KPX Uogonek Amacron -50 +KPX Uogonek Aogonek -50 +KPX Uogonek Aring -50 +KPX Uogonek Atilde -50 +KPX Uogonek comma -30 +KPX Uogonek period -30 +KPX Uring A -50 +KPX Uring Aacute -50 +KPX Uring Abreve -50 +KPX Uring Acircumflex -50 +KPX Uring Adieresis -50 +KPX Uring Agrave -50 +KPX Uring Amacron -50 +KPX Uring Aogonek -50 +KPX Uring Aring -50 +KPX Uring Atilde -50 +KPX Uring comma -30 +KPX Uring period -30 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -50 +KPX V Gbreve -50 +KPX V Gcommaaccent -50 +KPX V O -50 +KPX V Oacute -50 +KPX V Ocircumflex -50 +KPX V Odieresis -50 +KPX V Ograve -50 +KPX V Ohungarumlaut -50 +KPX V Omacron -50 +KPX V Oslash -50 +KPX V Otilde -50 +KPX V a -60 +KPX V aacute -60 +KPX V abreve -60 +KPX V acircumflex -60 +KPX V adieresis -60 +KPX V agrave -60 +KPX V amacron -60 +KPX V aogonek -60 +KPX V aring -60 +KPX V atilde -60 +KPX V colon -40 +KPX V comma -120 +KPX V e -50 +KPX V eacute -50 +KPX V ecaron -50 +KPX V ecircumflex -50 +KPX V edieresis -50 +KPX V edotaccent -50 +KPX V egrave -50 +KPX V emacron -50 +KPX V eogonek -50 +KPX V hyphen -80 +KPX V o -90 +KPX V oacute -90 +KPX V ocircumflex -90 +KPX V odieresis -90 +KPX V ograve -90 +KPX V ohungarumlaut -90 +KPX V omacron -90 +KPX V oslash -90 +KPX V otilde -90 +KPX V period -120 +KPX V semicolon -40 +KPX V u -60 +KPX V uacute -60 +KPX V ucircumflex -60 +KPX V udieresis -60 +KPX V ugrave -60 +KPX V uhungarumlaut -60 +KPX V umacron -60 +KPX V uogonek -60 +KPX V uring -60 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W colon -10 +KPX W comma -80 +KPX W e -35 +KPX W eacute -35 +KPX W ecaron -35 +KPX W ecircumflex -35 +KPX W edieresis -35 +KPX W edotaccent -35 +KPX W egrave -35 +KPX W emacron -35 +KPX W eogonek -35 +KPX W hyphen -40 +KPX W o -60 +KPX W oacute -60 +KPX W ocircumflex -60 +KPX W odieresis -60 +KPX W ograve -60 +KPX W ohungarumlaut -60 +KPX W omacron -60 +KPX W oslash -60 +KPX W otilde -60 +KPX W period -80 +KPX W semicolon -10 +KPX W u -45 +KPX W uacute -45 +KPX W ucircumflex -45 +KPX W udieresis -45 +KPX W ugrave -45 +KPX W uhungarumlaut -45 +KPX W umacron -45 +KPX W uogonek -45 +KPX W uring -45 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -70 +KPX Y Oacute -70 +KPX Y Ocircumflex -70 +KPX Y Odieresis -70 +KPX Y Ograve -70 +KPX Y Ohungarumlaut -70 +KPX Y Omacron -70 +KPX Y Oslash -70 +KPX Y Otilde -70 +KPX Y a -90 +KPX Y aacute -90 +KPX Y abreve -90 +KPX Y acircumflex -90 +KPX Y adieresis -90 +KPX Y agrave -90 +KPX Y amacron -90 +KPX Y aogonek -90 +KPX Y aring -90 +KPX Y atilde -90 +KPX Y colon -50 +KPX Y comma -100 +KPX Y e -80 +KPX Y eacute -80 +KPX Y ecaron -80 +KPX Y ecircumflex -80 +KPX Y edieresis -80 +KPX Y edotaccent -80 +KPX Y egrave -80 +KPX Y emacron -80 +KPX Y eogonek -80 +KPX Y o -100 +KPX Y oacute -100 +KPX Y ocircumflex -100 +KPX Y odieresis -100 +KPX Y ograve -100 +KPX Y ohungarumlaut -100 +KPX Y omacron -100 +KPX Y oslash -100 +KPX Y otilde -100 +KPX Y period -100 +KPX Y semicolon -50 +KPX Y u -100 +KPX Y uacute -100 +KPX Y ucircumflex -100 +KPX Y udieresis -100 +KPX Y ugrave -100 +KPX Y uhungarumlaut -100 +KPX Y umacron -100 +KPX Y uogonek -100 +KPX Y uring -100 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -70 +KPX Yacute Oacute -70 +KPX Yacute Ocircumflex -70 +KPX Yacute Odieresis -70 +KPX Yacute Ograve -70 +KPX Yacute Ohungarumlaut -70 +KPX Yacute Omacron -70 +KPX Yacute Oslash -70 +KPX Yacute Otilde -70 +KPX Yacute a -90 +KPX Yacute aacute -90 +KPX Yacute abreve -90 +KPX Yacute acircumflex -90 +KPX Yacute adieresis -90 +KPX Yacute agrave -90 +KPX Yacute amacron -90 +KPX Yacute aogonek -90 +KPX Yacute aring -90 +KPX Yacute atilde -90 +KPX Yacute colon -50 +KPX Yacute comma -100 +KPX Yacute e -80 +KPX Yacute eacute -80 +KPX Yacute ecaron -80 +KPX Yacute ecircumflex -80 +KPX Yacute edieresis -80 +KPX Yacute edotaccent -80 +KPX Yacute egrave -80 +KPX Yacute emacron -80 +KPX Yacute eogonek -80 +KPX Yacute o -100 +KPX Yacute oacute -100 +KPX Yacute ocircumflex -100 +KPX Yacute odieresis -100 +KPX Yacute ograve -100 +KPX Yacute ohungarumlaut -100 +KPX Yacute omacron -100 +KPX Yacute oslash -100 +KPX Yacute otilde -100 +KPX Yacute period -100 +KPX Yacute semicolon -50 +KPX Yacute u -100 +KPX Yacute uacute -100 +KPX Yacute ucircumflex -100 +KPX Yacute udieresis -100 +KPX Yacute ugrave -100 +KPX Yacute uhungarumlaut -100 +KPX Yacute umacron -100 +KPX Yacute uogonek -100 +KPX Yacute uring -100 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -70 +KPX Ydieresis Oacute -70 +KPX Ydieresis Ocircumflex -70 +KPX Ydieresis Odieresis -70 +KPX Ydieresis Ograve -70 +KPX Ydieresis Ohungarumlaut -70 +KPX Ydieresis Omacron -70 +KPX Ydieresis Oslash -70 +KPX Ydieresis Otilde -70 +KPX Ydieresis a -90 +KPX Ydieresis aacute -90 +KPX Ydieresis abreve -90 +KPX Ydieresis acircumflex -90 +KPX Ydieresis adieresis -90 +KPX Ydieresis agrave -90 +KPX Ydieresis amacron -90 +KPX Ydieresis aogonek -90 +KPX Ydieresis aring -90 +KPX Ydieresis atilde -90 +KPX Ydieresis colon -50 +KPX Ydieresis comma -100 +KPX Ydieresis e -80 +KPX Ydieresis eacute -80 +KPX Ydieresis ecaron -80 +KPX Ydieresis ecircumflex -80 +KPX Ydieresis edieresis -80 +KPX Ydieresis edotaccent -80 +KPX Ydieresis egrave -80 +KPX Ydieresis emacron -80 +KPX Ydieresis eogonek -80 +KPX Ydieresis o -100 +KPX Ydieresis oacute -100 +KPX Ydieresis ocircumflex -100 +KPX Ydieresis odieresis -100 +KPX Ydieresis ograve -100 +KPX Ydieresis ohungarumlaut -100 +KPX Ydieresis omacron -100 +KPX Ydieresis oslash -100 +KPX Ydieresis otilde -100 +KPX Ydieresis period -100 +KPX Ydieresis semicolon -50 +KPX Ydieresis u -100 +KPX Ydieresis uacute -100 +KPX Ydieresis ucircumflex -100 +KPX Ydieresis udieresis -100 +KPX Ydieresis ugrave -100 +KPX Ydieresis uhungarumlaut -100 +KPX Ydieresis umacron -100 +KPX Ydieresis uogonek -100 +KPX Ydieresis uring -100 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX a v -15 +KPX a w -15 +KPX a y -20 +KPX a yacute -20 +KPX a ydieresis -20 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX aacute v -15 +KPX aacute w -15 +KPX aacute y -20 +KPX aacute yacute -20 +KPX aacute ydieresis -20 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX abreve v -15 +KPX abreve w -15 +KPX abreve y -20 +KPX abreve yacute -20 +KPX abreve ydieresis -20 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX acircumflex v -15 +KPX acircumflex w -15 +KPX acircumflex y -20 +KPX acircumflex yacute -20 +KPX acircumflex ydieresis -20 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX adieresis v -15 +KPX adieresis w -15 +KPX adieresis y -20 +KPX adieresis yacute -20 +KPX adieresis ydieresis -20 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX agrave v -15 +KPX agrave w -15 +KPX agrave y -20 +KPX agrave yacute -20 +KPX agrave ydieresis -20 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX amacron v -15 +KPX amacron w -15 +KPX amacron y -20 +KPX amacron yacute -20 +KPX amacron ydieresis -20 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aogonek v -15 +KPX aogonek w -15 +KPX aogonek y -20 +KPX aogonek yacute -20 +KPX aogonek ydieresis -20 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX aring v -15 +KPX aring w -15 +KPX aring y -20 +KPX aring yacute -20 +KPX aring ydieresis -20 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX atilde v -15 +KPX atilde w -15 +KPX atilde y -20 +KPX atilde yacute -20 +KPX atilde ydieresis -20 +KPX b l -10 +KPX b lacute -10 +KPX b lcommaaccent -10 +KPX b lslash -10 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c h -10 +KPX c k -20 +KPX c kcommaaccent -20 +KPX c l -20 +KPX c lacute -20 +KPX c lcommaaccent -20 +KPX c lslash -20 +KPX c y -10 +KPX c yacute -10 +KPX c ydieresis -10 +KPX cacute h -10 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX cacute l -20 +KPX cacute lacute -20 +KPX cacute lcommaaccent -20 +KPX cacute lslash -20 +KPX cacute y -10 +KPX cacute yacute -10 +KPX cacute ydieresis -10 +KPX ccaron h -10 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccaron l -20 +KPX ccaron lacute -20 +KPX ccaron lcommaaccent -20 +KPX ccaron lslash -20 +KPX ccaron y -10 +KPX ccaron yacute -10 +KPX ccaron ydieresis -10 +KPX ccedilla h -10 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX ccedilla l -20 +KPX ccedilla lacute -20 +KPX ccedilla lcommaaccent -20 +KPX ccedilla lslash -20 +KPX ccedilla y -10 +KPX ccedilla yacute -10 +KPX ccedilla ydieresis -10 +KPX colon space -40 +KPX comma quotedblright -120 +KPX comma quoteright -120 +KPX comma space -40 +KPX d d -10 +KPX d dcroat -10 +KPX d v -15 +KPX d w -15 +KPX d y -15 +KPX d yacute -15 +KPX d ydieresis -15 +KPX dcroat d -10 +KPX dcroat dcroat -10 +KPX dcroat v -15 +KPX dcroat w -15 +KPX dcroat y -15 +KPX dcroat yacute -15 +KPX dcroat ydieresis -15 +KPX e comma 10 +KPX e period 20 +KPX e v -15 +KPX e w -15 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute comma 10 +KPX eacute period 20 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron comma 10 +KPX ecaron period 20 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex comma 10 +KPX ecircumflex period 20 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis comma 10 +KPX edieresis period 20 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent comma 10 +KPX edotaccent period 20 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave comma 10 +KPX egrave period 20 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron comma 10 +KPX emacron period 20 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek comma 10 +KPX eogonek period 20 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f comma -10 +KPX f e -10 +KPX f eacute -10 +KPX f ecaron -10 +KPX f ecircumflex -10 +KPX f edieresis -10 +KPX f edotaccent -10 +KPX f egrave -10 +KPX f emacron -10 +KPX f eogonek -10 +KPX f o -20 +KPX f oacute -20 +KPX f ocircumflex -20 +KPX f odieresis -20 +KPX f ograve -20 +KPX f ohungarumlaut -20 +KPX f omacron -20 +KPX f oslash -20 +KPX f otilde -20 +KPX f period -10 +KPX f quotedblright 30 +KPX f quoteright 30 +KPX g e 10 +KPX g eacute 10 +KPX g ecaron 10 +KPX g ecircumflex 10 +KPX g edieresis 10 +KPX g edotaccent 10 +KPX g egrave 10 +KPX g emacron 10 +KPX g eogonek 10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX gbreve e 10 +KPX gbreve eacute 10 +KPX gbreve ecaron 10 +KPX gbreve ecircumflex 10 +KPX gbreve edieresis 10 +KPX gbreve edotaccent 10 +KPX gbreve egrave 10 +KPX gbreve emacron 10 +KPX gbreve eogonek 10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gcommaaccent e 10 +KPX gcommaaccent eacute 10 +KPX gcommaaccent ecaron 10 +KPX gcommaaccent ecircumflex 10 +KPX gcommaaccent edieresis 10 +KPX gcommaaccent edotaccent 10 +KPX gcommaaccent egrave 10 +KPX gcommaaccent emacron 10 +KPX gcommaaccent eogonek 10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX h y -20 +KPX h yacute -20 +KPX h ydieresis -20 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX l w -15 +KPX l y -15 +KPX l yacute -15 +KPX l ydieresis -15 +KPX lacute w -15 +KPX lacute y -15 +KPX lacute yacute -15 +KPX lacute ydieresis -15 +KPX lcommaaccent w -15 +KPX lcommaaccent y -15 +KPX lcommaaccent yacute -15 +KPX lcommaaccent ydieresis -15 +KPX lslash w -15 +KPX lslash y -15 +KPX lslash yacute -15 +KPX lslash ydieresis -15 +KPX m u -20 +KPX m uacute -20 +KPX m ucircumflex -20 +KPX m udieresis -20 +KPX m ugrave -20 +KPX m uhungarumlaut -20 +KPX m umacron -20 +KPX m uogonek -20 +KPX m uring -20 +KPX m y -30 +KPX m yacute -30 +KPX m ydieresis -30 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -40 +KPX n y -20 +KPX n yacute -20 +KPX n ydieresis -20 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -40 +KPX nacute y -20 +KPX nacute yacute -20 +KPX nacute ydieresis -20 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -40 +KPX ncaron y -20 +KPX ncaron yacute -20 +KPX ncaron ydieresis -20 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -40 +KPX ncommaaccent y -20 +KPX ncommaaccent yacute -20 +KPX ncommaaccent ydieresis -20 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -40 +KPX ntilde y -20 +KPX ntilde yacute -20 +KPX ntilde ydieresis -20 +KPX o v -20 +KPX o w -15 +KPX o x -30 +KPX o y -20 +KPX o yacute -20 +KPX o ydieresis -20 +KPX oacute v -20 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -20 +KPX oacute yacute -20 +KPX oacute ydieresis -20 +KPX ocircumflex v -20 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -20 +KPX ocircumflex yacute -20 +KPX ocircumflex ydieresis -20 +KPX odieresis v -20 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -20 +KPX odieresis yacute -20 +KPX odieresis ydieresis -20 +KPX ograve v -20 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -20 +KPX ograve yacute -20 +KPX ograve ydieresis -20 +KPX ohungarumlaut v -20 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -20 +KPX ohungarumlaut yacute -20 +KPX ohungarumlaut ydieresis -20 +KPX omacron v -20 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -20 +KPX omacron yacute -20 +KPX omacron ydieresis -20 +KPX oslash v -20 +KPX oslash w -15 +KPX oslash x -30 +KPX oslash y -20 +KPX oslash yacute -20 +KPX oslash ydieresis -20 +KPX otilde v -20 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -20 +KPX otilde yacute -20 +KPX otilde ydieresis -20 +KPX p y -15 +KPX p yacute -15 +KPX p ydieresis -15 +KPX period quotedblright -120 +KPX period quoteright -120 +KPX period space -40 +KPX quotedblright space -80 +KPX quoteleft quoteleft -46 +KPX quoteright d -80 +KPX quoteright dcroat -80 +KPX quoteright l -20 +KPX quoteright lacute -20 +KPX quoteright lcommaaccent -20 +KPX quoteright lslash -20 +KPX quoteright quoteright -46 +KPX quoteright r -40 +KPX quoteright racute -40 +KPX quoteright rcaron -40 +KPX quoteright rcommaaccent -40 +KPX quoteright s -60 +KPX quoteright sacute -60 +KPX quoteright scaron -60 +KPX quoteright scedilla -60 +KPX quoteright scommaaccent -60 +KPX quoteright space -80 +KPX quoteright v -20 +KPX r c -20 +KPX r cacute -20 +KPX r ccaron -20 +KPX r ccedilla -20 +KPX r comma -60 +KPX r d -20 +KPX r dcroat -20 +KPX r g -15 +KPX r gbreve -15 +KPX r gcommaaccent -15 +KPX r hyphen -20 +KPX r o -20 +KPX r oacute -20 +KPX r ocircumflex -20 +KPX r odieresis -20 +KPX r ograve -20 +KPX r ohungarumlaut -20 +KPX r omacron -20 +KPX r oslash -20 +KPX r otilde -20 +KPX r period -60 +KPX r q -20 +KPX r s -15 +KPX r sacute -15 +KPX r scaron -15 +KPX r scedilla -15 +KPX r scommaaccent -15 +KPX r t 20 +KPX r tcommaaccent 20 +KPX r v 10 +KPX r y 10 +KPX r yacute 10 +KPX r ydieresis 10 +KPX racute c -20 +KPX racute cacute -20 +KPX racute ccaron -20 +KPX racute ccedilla -20 +KPX racute comma -60 +KPX racute d -20 +KPX racute dcroat -20 +KPX racute g -15 +KPX racute gbreve -15 +KPX racute gcommaaccent -15 +KPX racute hyphen -20 +KPX racute o -20 +KPX racute oacute -20 +KPX racute ocircumflex -20 +KPX racute odieresis -20 +KPX racute ograve -20 +KPX racute ohungarumlaut -20 +KPX racute omacron -20 +KPX racute oslash -20 +KPX racute otilde -20 +KPX racute period -60 +KPX racute q -20 +KPX racute s -15 +KPX racute sacute -15 +KPX racute scaron -15 +KPX racute scedilla -15 +KPX racute scommaaccent -15 +KPX racute t 20 +KPX racute tcommaaccent 20 +KPX racute v 10 +KPX racute y 10 +KPX racute yacute 10 +KPX racute ydieresis 10 +KPX rcaron c -20 +KPX rcaron cacute -20 +KPX rcaron ccaron -20 +KPX rcaron ccedilla -20 +KPX rcaron comma -60 +KPX rcaron d -20 +KPX rcaron dcroat -20 +KPX rcaron g -15 +KPX rcaron gbreve -15 +KPX rcaron gcommaaccent -15 +KPX rcaron hyphen -20 +KPX rcaron o -20 +KPX rcaron oacute -20 +KPX rcaron ocircumflex -20 +KPX rcaron odieresis -20 +KPX rcaron ograve -20 +KPX rcaron ohungarumlaut -20 +KPX rcaron omacron -20 +KPX rcaron oslash -20 +KPX rcaron otilde -20 +KPX rcaron period -60 +KPX rcaron q -20 +KPX rcaron s -15 +KPX rcaron sacute -15 +KPX rcaron scaron -15 +KPX rcaron scedilla -15 +KPX rcaron scommaaccent -15 +KPX rcaron t 20 +KPX rcaron tcommaaccent 20 +KPX rcaron v 10 +KPX rcaron y 10 +KPX rcaron yacute 10 +KPX rcaron ydieresis 10 +KPX rcommaaccent c -20 +KPX rcommaaccent cacute -20 +KPX rcommaaccent ccaron -20 +KPX rcommaaccent ccedilla -20 +KPX rcommaaccent comma -60 +KPX rcommaaccent d -20 +KPX rcommaaccent dcroat -20 +KPX rcommaaccent g -15 +KPX rcommaaccent gbreve -15 +KPX rcommaaccent gcommaaccent -15 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -20 +KPX rcommaaccent oacute -20 +KPX rcommaaccent ocircumflex -20 +KPX rcommaaccent odieresis -20 +KPX rcommaaccent ograve -20 +KPX rcommaaccent ohungarumlaut -20 +KPX rcommaaccent omacron -20 +KPX rcommaaccent oslash -20 +KPX rcommaaccent otilde -20 +KPX rcommaaccent period -60 +KPX rcommaaccent q -20 +KPX rcommaaccent s -15 +KPX rcommaaccent sacute -15 +KPX rcommaaccent scaron -15 +KPX rcommaaccent scedilla -15 +KPX rcommaaccent scommaaccent -15 +KPX rcommaaccent t 20 +KPX rcommaaccent tcommaaccent 20 +KPX rcommaaccent v 10 +KPX rcommaaccent y 10 +KPX rcommaaccent yacute 10 +KPX rcommaaccent ydieresis 10 +KPX s w -15 +KPX sacute w -15 +KPX scaron w -15 +KPX scedilla w -15 +KPX scommaaccent w -15 +KPX semicolon space -40 +KPX space T -100 +KPX space Tcaron -100 +KPX space Tcommaaccent -100 +KPX space V -80 +KPX space W -80 +KPX space Y -120 +KPX space Yacute -120 +KPX space Ydieresis -120 +KPX space quotedblleft -80 +KPX space quoteleft -60 +KPX v a -20 +KPX v aacute -20 +KPX v abreve -20 +KPX v acircumflex -20 +KPX v adieresis -20 +KPX v agrave -20 +KPX v amacron -20 +KPX v aogonek -20 +KPX v aring -20 +KPX v atilde -20 +KPX v comma -80 +KPX v o -30 +KPX v oacute -30 +KPX v ocircumflex -30 +KPX v odieresis -30 +KPX v ograve -30 +KPX v ohungarumlaut -30 +KPX v omacron -30 +KPX v oslash -30 +KPX v otilde -30 +KPX v period -80 +KPX w comma -40 +KPX w o -20 +KPX w oacute -20 +KPX w ocircumflex -20 +KPX w odieresis -20 +KPX w ograve -20 +KPX w ohungarumlaut -20 +KPX w omacron -20 +KPX w oslash -20 +KPX w otilde -20 +KPX w period -40 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y a -30 +KPX y aacute -30 +KPX y abreve -30 +KPX y acircumflex -30 +KPX y adieresis -30 +KPX y agrave -30 +KPX y amacron -30 +KPX y aogonek -30 +KPX y aring -30 +KPX y atilde -30 +KPX y comma -80 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -80 +KPX yacute a -30 +KPX yacute aacute -30 +KPX yacute abreve -30 +KPX yacute acircumflex -30 +KPX yacute adieresis -30 +KPX yacute agrave -30 +KPX yacute amacron -30 +KPX yacute aogonek -30 +KPX yacute aring -30 +KPX yacute atilde -30 +KPX yacute comma -80 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -80 +KPX ydieresis a -30 +KPX ydieresis aacute -30 +KPX ydieresis abreve -30 +KPX ydieresis acircumflex -30 +KPX ydieresis adieresis -30 +KPX ydieresis agrave -30 +KPX ydieresis amacron -30 +KPX ydieresis aogonek -30 +KPX ydieresis aring -30 +KPX ydieresis atilde -30 +KPX ydieresis comma -80 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -80 +KPX z e 10 +KPX z eacute 10 +KPX z ecaron 10 +KPX z ecircumflex 10 +KPX z edieresis 10 +KPX z edotaccent 10 +KPX z egrave 10 +KPX z emacron 10 +KPX z eogonek 10 +KPX zacute e 10 +KPX zacute eacute 10 +KPX zacute ecaron 10 +KPX zacute ecircumflex 10 +KPX zacute edieresis 10 +KPX zacute edotaccent 10 +KPX zacute egrave 10 +KPX zacute emacron 10 +KPX zacute eogonek 10 +KPX zcaron e 10 +KPX zcaron eacute 10 +KPX zcaron ecaron 10 +KPX zcaron ecircumflex 10 +KPX zcaron edieresis 10 +KPX zcaron edotaccent 10 +KPX zcaron egrave 10 +KPX zcaron emacron 10 +KPX zcaron eogonek 10 +KPX zdotaccent e 10 +KPX zdotaccent eacute 10 +KPX zdotaccent ecaron 10 +KPX zdotaccent ecircumflex 10 +KPX zdotaccent edieresis 10 +KPX zdotaccent edotaccent 10 +KPX zdotaccent egrave 10 +KPX zdotaccent emacron 10 +KPX zdotaccent eogonek 10 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm new file mode 100644 index 00000000..1715b210 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm @@ -0,0 +1,2827 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:45:12 1997 +Comment UniqueID 43053 +Comment VMusage 14482 68586 +FontName Helvetica-BoldOblique +FullName Helvetica Bold Oblique +FamilyName Helvetica +Weight Bold +ItalicAngle -12 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -174 -228 1114 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StdHW 118 +StdVW 140 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ; +C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ; +C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ; +C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ; +C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ; +C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ; +C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ; +C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ; +C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ; +C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ; +C 43 ; WX 584 ; N plus ; B 82 0 610 506 ; +C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ; +C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ; +C 46 ; WX 278 ; N period ; B 64 0 245 146 ; +C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ; +C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ; +C 49 ; WX 556 ; N one ; B 173 0 529 710 ; +C 50 ; WX 556 ; N two ; B 26 0 619 710 ; +C 51 ; WX 556 ; N three ; B 65 -19 608 710 ; +C 52 ; WX 556 ; N four ; B 60 0 598 710 ; +C 53 ; WX 556 ; N five ; B 64 -19 636 698 ; +C 54 ; WX 556 ; N six ; B 85 -19 619 710 ; +C 55 ; WX 556 ; N seven ; B 125 0 676 698 ; +C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ; +C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 351 512 ; +C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ; +C 60 ; WX 584 ; N less ; B 82 -8 655 514 ; +C 61 ; WX 584 ; N equal ; B 58 87 633 419 ; +C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ; +C 63 ; WX 611 ; N question ; B 165 0 671 727 ; +C 64 ; WX 975 ; N at ; B 186 -19 954 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 764 718 ; +C 67 ; WX 722 ; N C ; B 107 -19 789 737 ; +C 68 ; WX 722 ; N D ; B 76 0 777 718 ; +C 69 ; WX 667 ; N E ; B 76 0 757 718 ; +C 70 ; WX 611 ; N F ; B 76 0 740 718 ; +C 71 ; WX 778 ; N G ; B 108 -19 817 737 ; +C 72 ; WX 722 ; N H ; B 71 0 804 718 ; +C 73 ; WX 278 ; N I ; B 64 0 367 718 ; +C 74 ; WX 556 ; N J ; B 60 -18 637 718 ; +C 75 ; WX 722 ; N K ; B 87 0 858 718 ; +C 76 ; WX 611 ; N L ; B 76 0 611 718 ; +C 77 ; WX 833 ; N M ; B 69 0 918 718 ; +C 78 ; WX 722 ; N N ; B 69 0 807 718 ; +C 79 ; WX 778 ; N O ; B 107 -19 823 737 ; +C 80 ; WX 667 ; N P ; B 76 0 738 718 ; +C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ; +C 82 ; WX 722 ; N R ; B 76 0 778 718 ; +C 83 ; WX 667 ; N S ; B 81 -19 718 737 ; +C 84 ; WX 611 ; N T ; B 140 0 751 718 ; +C 85 ; WX 722 ; N U ; B 116 -19 804 718 ; +C 86 ; WX 667 ; N V ; B 172 0 801 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1082 718 ; +C 88 ; WX 667 ; N X ; B 14 0 791 718 ; +C 89 ; WX 667 ; N Y ; B 168 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 737 718 ; +C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ; +C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ; +C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ; +C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ; +C 97 ; WX 556 ; N a ; B 55 -14 583 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 645 718 ; +C 99 ; WX 556 ; N c ; B 79 -14 599 546 ; +C 100 ; WX 611 ; N d ; B 82 -14 704 718 ; +C 101 ; WX 556 ; N e ; B 70 -14 593 546 ; +C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 38 -217 666 546 ; +C 104 ; WX 611 ; N h ; B 65 0 629 718 ; +C 105 ; WX 278 ; N i ; B 69 0 363 725 ; +C 106 ; WX 278 ; N j ; B -42 -214 363 725 ; +C 107 ; WX 556 ; N k ; B 69 0 670 718 ; +C 108 ; WX 278 ; N l ; B 69 0 362 718 ; +C 109 ; WX 889 ; N m ; B 64 0 909 546 ; +C 110 ; WX 611 ; N n ; B 65 0 629 546 ; +C 111 ; WX 611 ; N o ; B 82 -14 643 546 ; +C 112 ; WX 611 ; N p ; B 18 -207 645 546 ; +C 113 ; WX 611 ; N q ; B 80 -207 665 546 ; +C 114 ; WX 389 ; N r ; B 64 0 489 546 ; +C 115 ; WX 556 ; N s ; B 63 -14 584 546 ; +C 116 ; WX 333 ; N t ; B 100 -6 422 676 ; +C 117 ; WX 611 ; N u ; B 98 -14 658 532 ; +C 118 ; WX 556 ; N v ; B 126 0 656 532 ; +C 119 ; WX 778 ; N w ; B 123 0 882 532 ; +C 120 ; WX 556 ; N x ; B 15 0 648 532 ; +C 121 ; WX 556 ; N y ; B 42 -214 652 532 ; +C 122 ; WX 500 ; N z ; B 20 0 583 532 ; +C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ; +C 124 ; WX 280 ; N bar ; B 36 -225 361 775 ; +C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ; +C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ; +C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ; +C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ; +C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ; +C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ; +C 165 ; WX 556 ; N yen ; B 60 0 713 698 ; +C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ; +C 167 ; WX 556 ; N section ; B 61 -184 598 727 ; +C 168 ; WX 556 ; N currency ; B 27 76 680 636 ; +C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ; +C 174 ; WX 611 ; N fi ; B 87 0 696 727 ; +C 175 ; WX 611 ; N fl ; B 87 0 695 727 ; +C 177 ; WX 556 ; N endash ; B 48 227 627 333 ; +C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ; +C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ; +C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ; +C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ; +C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ; +C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ; +C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ; +C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ; +C 193 ; WX 333 ; N grave ; B 136 604 353 750 ; +C 194 ; WX 333 ; N acute ; B 236 604 515 750 ; +C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ; +C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ; +C 197 ; WX 333 ; N macron ; B 122 604 483 678 ; +C 198 ; WX 333 ; N breve ; B 156 604 494 750 ; +C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ; +C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ; +C 202 ; WX 333 ; N ring ; B 200 568 420 776 ; +C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ; +C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ; +C 207 ; WX 333 ; N caron ; B 149 604 502 750 ; +C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 125 401 465 737 ; +C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ; +C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ; +C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 123 401 485 737 ; +C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ; +C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ; +C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ; +C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ; +C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ; +C -1 ; WX 556 ; N abreve ; B 55 -14 606 750 ; +C -1 ; WX 611 ; N uhungarumlaut ; B 98 -14 784 750 ; +C -1 ; WX 556 ; N ecaron ; B 70 -14 614 750 ; +C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ; +C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ; +C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ; +C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ; +C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ; +C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ; +C -1 ; WX 556 ; N scommaaccent ; B 63 -228 584 546 ; +C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ; +C -1 ; WX 722 ; N Uring ; B 116 -19 804 962 ; +C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ; +C -1 ; WX 556 ; N aogonek ; B 55 -224 583 546 ; +C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ; +C -1 ; WX 611 ; N uogonek ; B 98 -228 658 532 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ; +C -1 ; WX 722 ; N Dcroat ; B 62 0 777 718 ; +C -1 ; WX 250 ; N commaaccent ; B 16 -228 188 -50 ; +C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ; +C -1 ; WX 667 ; N Emacron ; B 76 0 757 864 ; +C -1 ; WX 556 ; N ccaron ; B 79 -14 614 750 ; +C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 807 718 ; +C -1 ; WX 278 ; N lacute ; B 69 0 528 936 ; +C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 140 -228 751 718 ; +C -1 ; WX 722 ; N Cacute ; B 107 -19 789 936 ; +C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ; +C -1 ; WX 667 ; N Edotaccent ; B 76 0 757 915 ; +C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ; +C -1 ; WX 556 ; N scedilla ; B 63 -228 584 546 ; +C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ; +C -1 ; WX 494 ; N lozenge ; B 90 0 564 745 ; +C -1 ; WX 722 ; N Rcaron ; B 76 0 778 936 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 108 -228 817 737 ; +C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ; +C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ; +C -1 ; WX 722 ; N Amacron ; B 20 0 718 864 ; +C -1 ; WX 389 ; N rcaron ; B 64 0 530 750 ; +C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ; +C -1 ; WX 611 ; N Zdotaccent ; B 25 0 737 915 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ; +C -1 ; WX 778 ; N Omacron ; B 107 -19 823 864 ; +C -1 ; WX 722 ; N Racute ; B 76 0 778 936 ; +C -1 ; WX 667 ; N Sacute ; B 81 -19 722 936 ; +C -1 ; WX 743 ; N dcaron ; B 82 -14 903 718 ; +C -1 ; WX 722 ; N Umacron ; B 116 -19 804 864 ; +C -1 ; WX 611 ; N uring ; B 98 -14 658 776 ; +C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ; +C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Abreve ; B 20 0 729 936 ; +C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ; +C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ; +C -1 ; WX 611 ; N Tcaron ; B 140 0 751 936 ; +C -1 ; WX 494 ; N partialdiff ; B 43 -21 585 750 ; +C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ; +C -1 ; WX 722 ; N Nacute ; B 69 0 807 936 ; +C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ; +C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ; +C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ; +C -1 ; WX 556 ; N cacute ; B 79 -14 627 750 ; +C -1 ; WX 611 ; N nacute ; B 65 0 654 750 ; +C -1 ; WX 611 ; N umacron ; B 98 -14 658 678 ; +C -1 ; WX 722 ; N Ncaron ; B 69 0 807 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ; +C -1 ; WX 280 ; N brokenbar ; B 52 -150 345 700 ; +C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ; +C -1 ; WX 778 ; N Gbreve ; B 108 -19 817 936 ; +C -1 ; WX 278 ; N Idotaccent ; B 64 0 397 915 ; +C -1 ; WX 600 ; N summation ; B 14 -10 670 706 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ; +C -1 ; WX 389 ; N racute ; B 64 0 543 750 ; +C -1 ; WX 611 ; N omacron ; B 82 -14 643 678 ; +C -1 ; WX 611 ; N Zacute ; B 25 0 737 936 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 629 704 ; +C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ; +C -1 ; WX 278 ; N lcommaaccent ; B 30 -228 362 718 ; +C -1 ; WX 389 ; N tcaron ; B 100 -6 608 878 ; +C -1 ; WX 556 ; N eogonek ; B 70 -228 593 546 ; +C -1 ; WX 722 ; N Uogonek ; B 116 -228 804 718 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ; +C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ; +C -1 ; WX 500 ; N zacute ; B 20 0 599 750 ; +C -1 ; WX 278 ; N iogonek ; B -14 -224 363 725 ; +C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ; +C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ; +C -1 ; WX 556 ; N amacron ; B 55 -14 595 678 ; +C -1 ; WX 556 ; N sacute ; B 63 -14 627 750 ; +C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ; +C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ; +C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ; +C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ; +C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ; +C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ; +C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ; +C -1 ; WX 611 ; N ohungarumlaut ; B 82 -14 784 750 ; +C -1 ; WX 667 ; N Eogonek ; B 76 -224 757 718 ; +C -1 ; WX 611 ; N dcroat ; B 82 -14 789 718 ; +C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ; +C -1 ; WX 667 ; N Scedilla ; B 81 -228 718 737 ; +C -1 ; WX 400 ; N lcaron ; B 69 0 561 718 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 858 718 ; +C -1 ; WX 611 ; N Lacute ; B 76 0 611 936 ; +C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ; +C -1 ; WX 556 ; N edotaccent ; B 70 -14 593 729 ; +C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ; +C -1 ; WX 278 ; N Imacron ; B 64 0 496 864 ; +C -1 ; WX 611 ; N Lcaron ; B 76 0 643 718 ; +C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 676 704 ; +C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 116 -19 880 936 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ; +C -1 ; WX 556 ; N emacron ; B 70 -14 595 678 ; +C -1 ; WX 611 ; N gbreve ; B 38 -217 666 750 ; +C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ; +C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ; +C -1 ; WX 667 ; N Scommaaccent ; B 81 -228 718 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 107 -19 908 936 ; +C -1 ; WX 400 ; N degree ; B 175 426 467 712 ; +C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ; +C -1 ; WX 722 ; N Ccaron ; B 107 -19 789 936 ; +C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ; +C -1 ; WX 549 ; N radical ; B 112 -46 689 850 ; +C -1 ; WX 722 ; N Dcaron ; B 76 0 777 936 ; +C -1 ; WX 389 ; N rcommaaccent ; B 26 -228 489 546 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ; +C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 778 718 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 611 718 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ; +C -1 ; WX 722 ; N Aogonek ; B 20 -224 702 718 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ; +C -1 ; WX 500 ; N zdotaccent ; B 20 0 583 729 ; +C -1 ; WX 667 ; N Ecaron ; B 76 0 757 936 ; +C -1 ; WX 278 ; N Iogonek ; B -41 -228 367 718 ; +C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 670 718 ; +C -1 ; WX 584 ; N minus ; B 82 197 610 309 ; +C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ; +C -1 ; WX 611 ; N ncaron ; B 65 0 641 750 ; +C -1 ; WX 333 ; N tcommaaccent ; B 58 -228 422 676 ; +C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ; +C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ; +C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ; +C -1 ; WX 549 ; N notequal ; B 32 -49 630 570 ; +C -1 ; WX 611 ; N gcommaaccent ; B 38 -217 666 850 ; +C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ; +C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 629 546 ; +C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ; +C -1 ; WX 278 ; N imacron ; B 69 0 429 678 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2481 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -50 +KPX A Gbreve -50 +KPX A Gcommaaccent -50 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -90 +KPX A Tcaron -90 +KPX A Tcommaaccent -90 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -80 +KPX A W -60 +KPX A Y -110 +KPX A Yacute -110 +KPX A Ydieresis -110 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -30 +KPX A y -30 +KPX A yacute -30 +KPX A ydieresis -30 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -50 +KPX Aacute Gbreve -50 +KPX Aacute Gcommaaccent -50 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -90 +KPX Aacute Tcaron -90 +KPX Aacute Tcommaaccent -90 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -80 +KPX Aacute W -60 +KPX Aacute Y -110 +KPX Aacute Yacute -110 +KPX Aacute Ydieresis -110 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -30 +KPX Aacute y -30 +KPX Aacute yacute -30 +KPX Aacute ydieresis -30 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -50 +KPX Abreve Gbreve -50 +KPX Abreve Gcommaaccent -50 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -90 +KPX Abreve Tcaron -90 +KPX Abreve Tcommaaccent -90 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -80 +KPX Abreve W -60 +KPX Abreve Y -110 +KPX Abreve Yacute -110 +KPX Abreve Ydieresis -110 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -30 +KPX Abreve y -30 +KPX Abreve yacute -30 +KPX Abreve ydieresis -30 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -50 +KPX Acircumflex Gbreve -50 +KPX Acircumflex Gcommaaccent -50 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -90 +KPX Acircumflex Tcaron -90 +KPX Acircumflex Tcommaaccent -90 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -80 +KPX Acircumflex W -60 +KPX Acircumflex Y -110 +KPX Acircumflex Yacute -110 +KPX Acircumflex Ydieresis -110 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -30 +KPX Acircumflex y -30 +KPX Acircumflex yacute -30 +KPX Acircumflex ydieresis -30 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -50 +KPX Adieresis Gbreve -50 +KPX Adieresis Gcommaaccent -50 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -90 +KPX Adieresis Tcaron -90 +KPX Adieresis Tcommaaccent -90 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -80 +KPX Adieresis W -60 +KPX Adieresis Y -110 +KPX Adieresis Yacute -110 +KPX Adieresis Ydieresis -110 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -30 +KPX Adieresis y -30 +KPX Adieresis yacute -30 +KPX Adieresis ydieresis -30 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -50 +KPX Agrave Gbreve -50 +KPX Agrave Gcommaaccent -50 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -90 +KPX Agrave Tcaron -90 +KPX Agrave Tcommaaccent -90 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -80 +KPX Agrave W -60 +KPX Agrave Y -110 +KPX Agrave Yacute -110 +KPX Agrave Ydieresis -110 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -30 +KPX Agrave y -30 +KPX Agrave yacute -30 +KPX Agrave ydieresis -30 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -50 +KPX Amacron Gbreve -50 +KPX Amacron Gcommaaccent -50 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -90 +KPX Amacron Tcaron -90 +KPX Amacron Tcommaaccent -90 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -80 +KPX Amacron W -60 +KPX Amacron Y -110 +KPX Amacron Yacute -110 +KPX Amacron Ydieresis -110 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -30 +KPX Amacron y -30 +KPX Amacron yacute -30 +KPX Amacron ydieresis -30 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -50 +KPX Aogonek Gbreve -50 +KPX Aogonek Gcommaaccent -50 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -90 +KPX Aogonek Tcaron -90 +KPX Aogonek Tcommaaccent -90 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -80 +KPX Aogonek W -60 +KPX Aogonek Y -110 +KPX Aogonek Yacute -110 +KPX Aogonek Ydieresis -110 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -30 +KPX Aogonek y -30 +KPX Aogonek yacute -30 +KPX Aogonek ydieresis -30 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -50 +KPX Aring Gbreve -50 +KPX Aring Gcommaaccent -50 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -90 +KPX Aring Tcaron -90 +KPX Aring Tcommaaccent -90 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -80 +KPX Aring W -60 +KPX Aring Y -110 +KPX Aring Yacute -110 +KPX Aring Ydieresis -110 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -30 +KPX Aring y -30 +KPX Aring yacute -30 +KPX Aring ydieresis -30 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -50 +KPX Atilde Gbreve -50 +KPX Atilde Gcommaaccent -50 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -90 +KPX Atilde Tcaron -90 +KPX Atilde Tcommaaccent -90 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -80 +KPX Atilde W -60 +KPX Atilde Y -110 +KPX Atilde Yacute -110 +KPX Atilde Ydieresis -110 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -30 +KPX Atilde y -30 +KPX Atilde yacute -30 +KPX Atilde ydieresis -30 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -40 +KPX D Y -70 +KPX D Yacute -70 +KPX D Ydieresis -70 +KPX D comma -30 +KPX D period -30 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -70 +KPX Dcaron Yacute -70 +KPX Dcaron Ydieresis -70 +KPX Dcaron comma -30 +KPX Dcaron period -30 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -70 +KPX Dcroat Yacute -70 +KPX Dcroat Ydieresis -70 +KPX Dcroat comma -30 +KPX Dcroat period -30 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -20 +KPX F aacute -20 +KPX F abreve -20 +KPX F acircumflex -20 +KPX F adieresis -20 +KPX F agrave -20 +KPX F amacron -20 +KPX F aogonek -20 +KPX F aring -20 +KPX F atilde -20 +KPX F comma -100 +KPX F period -100 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J comma -20 +KPX J period -20 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -15 +KPX K eacute -15 +KPX K ecaron -15 +KPX K ecircumflex -15 +KPX K edieresis -15 +KPX K edotaccent -15 +KPX K egrave -15 +KPX K emacron -15 +KPX K eogonek -15 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -15 +KPX Kcommaaccent eacute -15 +KPX Kcommaaccent ecaron -15 +KPX Kcommaaccent ecircumflex -15 +KPX Kcommaaccent edieresis -15 +KPX Kcommaaccent edotaccent -15 +KPX Kcommaaccent egrave -15 +KPX Kcommaaccent emacron -15 +KPX Kcommaaccent eogonek -15 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -90 +KPX L Tcaron -90 +KPX L Tcommaaccent -90 +KPX L V -110 +KPX L W -80 +KPX L Y -120 +KPX L Yacute -120 +KPX L Ydieresis -120 +KPX L quotedblright -140 +KPX L quoteright -140 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -90 +KPX Lacute Tcaron -90 +KPX Lacute Tcommaaccent -90 +KPX Lacute V -110 +KPX Lacute W -80 +KPX Lacute Y -120 +KPX Lacute Yacute -120 +KPX Lacute Ydieresis -120 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -140 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -90 +KPX Lcommaaccent Tcaron -90 +KPX Lcommaaccent Tcommaaccent -90 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -80 +KPX Lcommaaccent Y -120 +KPX Lcommaaccent Yacute -120 +KPX Lcommaaccent Ydieresis -120 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -140 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -90 +KPX Lslash Tcaron -90 +KPX Lslash Tcommaaccent -90 +KPX Lslash V -110 +KPX Lslash W -80 +KPX Lslash Y -120 +KPX Lslash Yacute -120 +KPX Lslash Ydieresis -120 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -140 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -50 +KPX O Aacute -50 +KPX O Abreve -50 +KPX O Acircumflex -50 +KPX O Adieresis -50 +KPX O Agrave -50 +KPX O Amacron -50 +KPX O Aogonek -50 +KPX O Aring -50 +KPX O Atilde -50 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -50 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -50 +KPX Oacute Aacute -50 +KPX Oacute Abreve -50 +KPX Oacute Acircumflex -50 +KPX Oacute Adieresis -50 +KPX Oacute Agrave -50 +KPX Oacute Amacron -50 +KPX Oacute Aogonek -50 +KPX Oacute Aring -50 +KPX Oacute Atilde -50 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -50 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -50 +KPX Ocircumflex Aacute -50 +KPX Ocircumflex Abreve -50 +KPX Ocircumflex Acircumflex -50 +KPX Ocircumflex Adieresis -50 +KPX Ocircumflex Agrave -50 +KPX Ocircumflex Amacron -50 +KPX Ocircumflex Aogonek -50 +KPX Ocircumflex Aring -50 +KPX Ocircumflex Atilde -50 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -50 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -50 +KPX Odieresis Aacute -50 +KPX Odieresis Abreve -50 +KPX Odieresis Acircumflex -50 +KPX Odieresis Adieresis -50 +KPX Odieresis Agrave -50 +KPX Odieresis Amacron -50 +KPX Odieresis Aogonek -50 +KPX Odieresis Aring -50 +KPX Odieresis Atilde -50 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -50 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -50 +KPX Ograve Aacute -50 +KPX Ograve Abreve -50 +KPX Ograve Acircumflex -50 +KPX Ograve Adieresis -50 +KPX Ograve Agrave -50 +KPX Ograve Amacron -50 +KPX Ograve Aogonek -50 +KPX Ograve Aring -50 +KPX Ograve Atilde -50 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -50 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -50 +KPX Ohungarumlaut Aacute -50 +KPX Ohungarumlaut Abreve -50 +KPX Ohungarumlaut Acircumflex -50 +KPX Ohungarumlaut Adieresis -50 +KPX Ohungarumlaut Agrave -50 +KPX Ohungarumlaut Amacron -50 +KPX Ohungarumlaut Aogonek -50 +KPX Ohungarumlaut Aring -50 +KPX Ohungarumlaut Atilde -50 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -50 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -50 +KPX Omacron Aacute -50 +KPX Omacron Abreve -50 +KPX Omacron Acircumflex -50 +KPX Omacron Adieresis -50 +KPX Omacron Agrave -50 +KPX Omacron Amacron -50 +KPX Omacron Aogonek -50 +KPX Omacron Aring -50 +KPX Omacron Atilde -50 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -50 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -50 +KPX Oslash Aacute -50 +KPX Oslash Abreve -50 +KPX Oslash Acircumflex -50 +KPX Oslash Adieresis -50 +KPX Oslash Agrave -50 +KPX Oslash Amacron -50 +KPX Oslash Aogonek -50 +KPX Oslash Aring -50 +KPX Oslash Atilde -50 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -50 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -50 +KPX Otilde Aacute -50 +KPX Otilde Abreve -50 +KPX Otilde Acircumflex -50 +KPX Otilde Adieresis -50 +KPX Otilde Agrave -50 +KPX Otilde Amacron -50 +KPX Otilde Aogonek -50 +KPX Otilde Aring -50 +KPX Otilde Atilde -50 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -50 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -100 +KPX P Aacute -100 +KPX P Abreve -100 +KPX P Acircumflex -100 +KPX P Adieresis -100 +KPX P Agrave -100 +KPX P Amacron -100 +KPX P Aogonek -100 +KPX P Aring -100 +KPX P Atilde -100 +KPX P a -30 +KPX P aacute -30 +KPX P abreve -30 +KPX P acircumflex -30 +KPX P adieresis -30 +KPX P agrave -30 +KPX P amacron -30 +KPX P aogonek -30 +KPX P aring -30 +KPX P atilde -30 +KPX P comma -120 +KPX P e -30 +KPX P eacute -30 +KPX P ecaron -30 +KPX P ecircumflex -30 +KPX P edieresis -30 +KPX P edotaccent -30 +KPX P egrave -30 +KPX P emacron -30 +KPX P eogonek -30 +KPX P o -40 +KPX P oacute -40 +KPX P ocircumflex -40 +KPX P odieresis -40 +KPX P ograve -40 +KPX P ohungarumlaut -40 +KPX P omacron -40 +KPX P oslash -40 +KPX P otilde -40 +KPX P period -120 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q comma 20 +KPX Q period 20 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -20 +KPX R Tcaron -20 +KPX R Tcommaaccent -20 +KPX R U -20 +KPX R Uacute -20 +KPX R Ucircumflex -20 +KPX R Udieresis -20 +KPX R Ugrave -20 +KPX R Uhungarumlaut -20 +KPX R Umacron -20 +KPX R Uogonek -20 +KPX R Uring -20 +KPX R V -50 +KPX R W -40 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -20 +KPX Racute Tcaron -20 +KPX Racute Tcommaaccent -20 +KPX Racute U -20 +KPX Racute Uacute -20 +KPX Racute Ucircumflex -20 +KPX Racute Udieresis -20 +KPX Racute Ugrave -20 +KPX Racute Uhungarumlaut -20 +KPX Racute Umacron -20 +KPX Racute Uogonek -20 +KPX Racute Uring -20 +KPX Racute V -50 +KPX Racute W -40 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -20 +KPX Rcaron Tcaron -20 +KPX Rcaron Tcommaaccent -20 +KPX Rcaron U -20 +KPX Rcaron Uacute -20 +KPX Rcaron Ucircumflex -20 +KPX Rcaron Udieresis -20 +KPX Rcaron Ugrave -20 +KPX Rcaron Uhungarumlaut -20 +KPX Rcaron Umacron -20 +KPX Rcaron Uogonek -20 +KPX Rcaron Uring -20 +KPX Rcaron V -50 +KPX Rcaron W -40 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -20 +KPX Rcommaaccent Tcaron -20 +KPX Rcommaaccent Tcommaaccent -20 +KPX Rcommaaccent U -20 +KPX Rcommaaccent Uacute -20 +KPX Rcommaaccent Ucircumflex -20 +KPX Rcommaaccent Udieresis -20 +KPX Rcommaaccent Ugrave -20 +KPX Rcommaaccent Uhungarumlaut -20 +KPX Rcommaaccent Umacron -20 +KPX Rcommaaccent Uogonek -20 +KPX Rcommaaccent Uring -20 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -40 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -80 +KPX T agrave -80 +KPX T amacron -80 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -80 +KPX T colon -40 +KPX T comma -80 +KPX T e -60 +KPX T eacute -60 +KPX T ecaron -60 +KPX T ecircumflex -60 +KPX T edieresis -60 +KPX T edotaccent -60 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -60 +KPX T hyphen -120 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -80 +KPX T r -80 +KPX T racute -80 +KPX T rcommaaccent -80 +KPX T semicolon -40 +KPX T u -90 +KPX T uacute -90 +KPX T ucircumflex -90 +KPX T udieresis -90 +KPX T ugrave -90 +KPX T uhungarumlaut -90 +KPX T umacron -90 +KPX T uogonek -90 +KPX T uring -90 +KPX T w -60 +KPX T y -60 +KPX T yacute -60 +KPX T ydieresis -60 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -80 +KPX Tcaron agrave -80 +KPX Tcaron amacron -80 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -80 +KPX Tcaron colon -40 +KPX Tcaron comma -80 +KPX Tcaron e -60 +KPX Tcaron eacute -60 +KPX Tcaron ecaron -60 +KPX Tcaron ecircumflex -60 +KPX Tcaron edieresis -60 +KPX Tcaron edotaccent -60 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -60 +KPX Tcaron hyphen -120 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -80 +KPX Tcaron r -80 +KPX Tcaron racute -80 +KPX Tcaron rcommaaccent -80 +KPX Tcaron semicolon -40 +KPX Tcaron u -90 +KPX Tcaron uacute -90 +KPX Tcaron ucircumflex -90 +KPX Tcaron udieresis -90 +KPX Tcaron ugrave -90 +KPX Tcaron uhungarumlaut -90 +KPX Tcaron umacron -90 +KPX Tcaron uogonek -90 +KPX Tcaron uring -90 +KPX Tcaron w -60 +KPX Tcaron y -60 +KPX Tcaron yacute -60 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -80 +KPX Tcommaaccent agrave -80 +KPX Tcommaaccent amacron -80 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -80 +KPX Tcommaaccent colon -40 +KPX Tcommaaccent comma -80 +KPX Tcommaaccent e -60 +KPX Tcommaaccent eacute -60 +KPX Tcommaaccent ecaron -60 +KPX Tcommaaccent ecircumflex -60 +KPX Tcommaaccent edieresis -60 +KPX Tcommaaccent edotaccent -60 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -60 +KPX Tcommaaccent hyphen -120 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -80 +KPX Tcommaaccent r -80 +KPX Tcommaaccent racute -80 +KPX Tcommaaccent rcommaaccent -80 +KPX Tcommaaccent semicolon -40 +KPX Tcommaaccent u -90 +KPX Tcommaaccent uacute -90 +KPX Tcommaaccent ucircumflex -90 +KPX Tcommaaccent udieresis -90 +KPX Tcommaaccent ugrave -90 +KPX Tcommaaccent uhungarumlaut -90 +KPX Tcommaaccent umacron -90 +KPX Tcommaaccent uogonek -90 +KPX Tcommaaccent uring -90 +KPX Tcommaaccent w -60 +KPX Tcommaaccent y -60 +KPX Tcommaaccent yacute -60 +KPX Tcommaaccent ydieresis -60 +KPX U A -50 +KPX U Aacute -50 +KPX U Abreve -50 +KPX U Acircumflex -50 +KPX U Adieresis -50 +KPX U Agrave -50 +KPX U Amacron -50 +KPX U Aogonek -50 +KPX U Aring -50 +KPX U Atilde -50 +KPX U comma -30 +KPX U period -30 +KPX Uacute A -50 +KPX Uacute Aacute -50 +KPX Uacute Abreve -50 +KPX Uacute Acircumflex -50 +KPX Uacute Adieresis -50 +KPX Uacute Agrave -50 +KPX Uacute Amacron -50 +KPX Uacute Aogonek -50 +KPX Uacute Aring -50 +KPX Uacute Atilde -50 +KPX Uacute comma -30 +KPX Uacute period -30 +KPX Ucircumflex A -50 +KPX Ucircumflex Aacute -50 +KPX Ucircumflex Abreve -50 +KPX Ucircumflex Acircumflex -50 +KPX Ucircumflex Adieresis -50 +KPX Ucircumflex Agrave -50 +KPX Ucircumflex Amacron -50 +KPX Ucircumflex Aogonek -50 +KPX Ucircumflex Aring -50 +KPX Ucircumflex Atilde -50 +KPX Ucircumflex comma -30 +KPX Ucircumflex period -30 +KPX Udieresis A -50 +KPX Udieresis Aacute -50 +KPX Udieresis Abreve -50 +KPX Udieresis Acircumflex -50 +KPX Udieresis Adieresis -50 +KPX Udieresis Agrave -50 +KPX Udieresis Amacron -50 +KPX Udieresis Aogonek -50 +KPX Udieresis Aring -50 +KPX Udieresis Atilde -50 +KPX Udieresis comma -30 +KPX Udieresis period -30 +KPX Ugrave A -50 +KPX Ugrave Aacute -50 +KPX Ugrave Abreve -50 +KPX Ugrave Acircumflex -50 +KPX Ugrave Adieresis -50 +KPX Ugrave Agrave -50 +KPX Ugrave Amacron -50 +KPX Ugrave Aogonek -50 +KPX Ugrave Aring -50 +KPX Ugrave Atilde -50 +KPX Ugrave comma -30 +KPX Ugrave period -30 +KPX Uhungarumlaut A -50 +KPX Uhungarumlaut Aacute -50 +KPX Uhungarumlaut Abreve -50 +KPX Uhungarumlaut Acircumflex -50 +KPX Uhungarumlaut Adieresis -50 +KPX Uhungarumlaut Agrave -50 +KPX Uhungarumlaut Amacron -50 +KPX Uhungarumlaut Aogonek -50 +KPX Uhungarumlaut Aring -50 +KPX Uhungarumlaut Atilde -50 +KPX Uhungarumlaut comma -30 +KPX Uhungarumlaut period -30 +KPX Umacron A -50 +KPX Umacron Aacute -50 +KPX Umacron Abreve -50 +KPX Umacron Acircumflex -50 +KPX Umacron Adieresis -50 +KPX Umacron Agrave -50 +KPX Umacron Amacron -50 +KPX Umacron Aogonek -50 +KPX Umacron Aring -50 +KPX Umacron Atilde -50 +KPX Umacron comma -30 +KPX Umacron period -30 +KPX Uogonek A -50 +KPX Uogonek Aacute -50 +KPX Uogonek Abreve -50 +KPX Uogonek Acircumflex -50 +KPX Uogonek Adieresis -50 +KPX Uogonek Agrave -50 +KPX Uogonek Amacron -50 +KPX Uogonek Aogonek -50 +KPX Uogonek Aring -50 +KPX Uogonek Atilde -50 +KPX Uogonek comma -30 +KPX Uogonek period -30 +KPX Uring A -50 +KPX Uring Aacute -50 +KPX Uring Abreve -50 +KPX Uring Acircumflex -50 +KPX Uring Adieresis -50 +KPX Uring Agrave -50 +KPX Uring Amacron -50 +KPX Uring Aogonek -50 +KPX Uring Aring -50 +KPX Uring Atilde -50 +KPX Uring comma -30 +KPX Uring period -30 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -50 +KPX V Gbreve -50 +KPX V Gcommaaccent -50 +KPX V O -50 +KPX V Oacute -50 +KPX V Ocircumflex -50 +KPX V Odieresis -50 +KPX V Ograve -50 +KPX V Ohungarumlaut -50 +KPX V Omacron -50 +KPX V Oslash -50 +KPX V Otilde -50 +KPX V a -60 +KPX V aacute -60 +KPX V abreve -60 +KPX V acircumflex -60 +KPX V adieresis -60 +KPX V agrave -60 +KPX V amacron -60 +KPX V aogonek -60 +KPX V aring -60 +KPX V atilde -60 +KPX V colon -40 +KPX V comma -120 +KPX V e -50 +KPX V eacute -50 +KPX V ecaron -50 +KPX V ecircumflex -50 +KPX V edieresis -50 +KPX V edotaccent -50 +KPX V egrave -50 +KPX V emacron -50 +KPX V eogonek -50 +KPX V hyphen -80 +KPX V o -90 +KPX V oacute -90 +KPX V ocircumflex -90 +KPX V odieresis -90 +KPX V ograve -90 +KPX V ohungarumlaut -90 +KPX V omacron -90 +KPX V oslash -90 +KPX V otilde -90 +KPX V period -120 +KPX V semicolon -40 +KPX V u -60 +KPX V uacute -60 +KPX V ucircumflex -60 +KPX V udieresis -60 +KPX V ugrave -60 +KPX V uhungarumlaut -60 +KPX V umacron -60 +KPX V uogonek -60 +KPX V uring -60 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W colon -10 +KPX W comma -80 +KPX W e -35 +KPX W eacute -35 +KPX W ecaron -35 +KPX W ecircumflex -35 +KPX W edieresis -35 +KPX W edotaccent -35 +KPX W egrave -35 +KPX W emacron -35 +KPX W eogonek -35 +KPX W hyphen -40 +KPX W o -60 +KPX W oacute -60 +KPX W ocircumflex -60 +KPX W odieresis -60 +KPX W ograve -60 +KPX W ohungarumlaut -60 +KPX W omacron -60 +KPX W oslash -60 +KPX W otilde -60 +KPX W period -80 +KPX W semicolon -10 +KPX W u -45 +KPX W uacute -45 +KPX W ucircumflex -45 +KPX W udieresis -45 +KPX W ugrave -45 +KPX W uhungarumlaut -45 +KPX W umacron -45 +KPX W uogonek -45 +KPX W uring -45 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -70 +KPX Y Oacute -70 +KPX Y Ocircumflex -70 +KPX Y Odieresis -70 +KPX Y Ograve -70 +KPX Y Ohungarumlaut -70 +KPX Y Omacron -70 +KPX Y Oslash -70 +KPX Y Otilde -70 +KPX Y a -90 +KPX Y aacute -90 +KPX Y abreve -90 +KPX Y acircumflex -90 +KPX Y adieresis -90 +KPX Y agrave -90 +KPX Y amacron -90 +KPX Y aogonek -90 +KPX Y aring -90 +KPX Y atilde -90 +KPX Y colon -50 +KPX Y comma -100 +KPX Y e -80 +KPX Y eacute -80 +KPX Y ecaron -80 +KPX Y ecircumflex -80 +KPX Y edieresis -80 +KPX Y edotaccent -80 +KPX Y egrave -80 +KPX Y emacron -80 +KPX Y eogonek -80 +KPX Y o -100 +KPX Y oacute -100 +KPX Y ocircumflex -100 +KPX Y odieresis -100 +KPX Y ograve -100 +KPX Y ohungarumlaut -100 +KPX Y omacron -100 +KPX Y oslash -100 +KPX Y otilde -100 +KPX Y period -100 +KPX Y semicolon -50 +KPX Y u -100 +KPX Y uacute -100 +KPX Y ucircumflex -100 +KPX Y udieresis -100 +KPX Y ugrave -100 +KPX Y uhungarumlaut -100 +KPX Y umacron -100 +KPX Y uogonek -100 +KPX Y uring -100 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -70 +KPX Yacute Oacute -70 +KPX Yacute Ocircumflex -70 +KPX Yacute Odieresis -70 +KPX Yacute Ograve -70 +KPX Yacute Ohungarumlaut -70 +KPX Yacute Omacron -70 +KPX Yacute Oslash -70 +KPX Yacute Otilde -70 +KPX Yacute a -90 +KPX Yacute aacute -90 +KPX Yacute abreve -90 +KPX Yacute acircumflex -90 +KPX Yacute adieresis -90 +KPX Yacute agrave -90 +KPX Yacute amacron -90 +KPX Yacute aogonek -90 +KPX Yacute aring -90 +KPX Yacute atilde -90 +KPX Yacute colon -50 +KPX Yacute comma -100 +KPX Yacute e -80 +KPX Yacute eacute -80 +KPX Yacute ecaron -80 +KPX Yacute ecircumflex -80 +KPX Yacute edieresis -80 +KPX Yacute edotaccent -80 +KPX Yacute egrave -80 +KPX Yacute emacron -80 +KPX Yacute eogonek -80 +KPX Yacute o -100 +KPX Yacute oacute -100 +KPX Yacute ocircumflex -100 +KPX Yacute odieresis -100 +KPX Yacute ograve -100 +KPX Yacute ohungarumlaut -100 +KPX Yacute omacron -100 +KPX Yacute oslash -100 +KPX Yacute otilde -100 +KPX Yacute period -100 +KPX Yacute semicolon -50 +KPX Yacute u -100 +KPX Yacute uacute -100 +KPX Yacute ucircumflex -100 +KPX Yacute udieresis -100 +KPX Yacute ugrave -100 +KPX Yacute uhungarumlaut -100 +KPX Yacute umacron -100 +KPX Yacute uogonek -100 +KPX Yacute uring -100 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -70 +KPX Ydieresis Oacute -70 +KPX Ydieresis Ocircumflex -70 +KPX Ydieresis Odieresis -70 +KPX Ydieresis Ograve -70 +KPX Ydieresis Ohungarumlaut -70 +KPX Ydieresis Omacron -70 +KPX Ydieresis Oslash -70 +KPX Ydieresis Otilde -70 +KPX Ydieresis a -90 +KPX Ydieresis aacute -90 +KPX Ydieresis abreve -90 +KPX Ydieresis acircumflex -90 +KPX Ydieresis adieresis -90 +KPX Ydieresis agrave -90 +KPX Ydieresis amacron -90 +KPX Ydieresis aogonek -90 +KPX Ydieresis aring -90 +KPX Ydieresis atilde -90 +KPX Ydieresis colon -50 +KPX Ydieresis comma -100 +KPX Ydieresis e -80 +KPX Ydieresis eacute -80 +KPX Ydieresis ecaron -80 +KPX Ydieresis ecircumflex -80 +KPX Ydieresis edieresis -80 +KPX Ydieresis edotaccent -80 +KPX Ydieresis egrave -80 +KPX Ydieresis emacron -80 +KPX Ydieresis eogonek -80 +KPX Ydieresis o -100 +KPX Ydieresis oacute -100 +KPX Ydieresis ocircumflex -100 +KPX Ydieresis odieresis -100 +KPX Ydieresis ograve -100 +KPX Ydieresis ohungarumlaut -100 +KPX Ydieresis omacron -100 +KPX Ydieresis oslash -100 +KPX Ydieresis otilde -100 +KPX Ydieresis period -100 +KPX Ydieresis semicolon -50 +KPX Ydieresis u -100 +KPX Ydieresis uacute -100 +KPX Ydieresis ucircumflex -100 +KPX Ydieresis udieresis -100 +KPX Ydieresis ugrave -100 +KPX Ydieresis uhungarumlaut -100 +KPX Ydieresis umacron -100 +KPX Ydieresis uogonek -100 +KPX Ydieresis uring -100 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX a v -15 +KPX a w -15 +KPX a y -20 +KPX a yacute -20 +KPX a ydieresis -20 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX aacute v -15 +KPX aacute w -15 +KPX aacute y -20 +KPX aacute yacute -20 +KPX aacute ydieresis -20 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX abreve v -15 +KPX abreve w -15 +KPX abreve y -20 +KPX abreve yacute -20 +KPX abreve ydieresis -20 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX acircumflex v -15 +KPX acircumflex w -15 +KPX acircumflex y -20 +KPX acircumflex yacute -20 +KPX acircumflex ydieresis -20 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX adieresis v -15 +KPX adieresis w -15 +KPX adieresis y -20 +KPX adieresis yacute -20 +KPX adieresis ydieresis -20 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX agrave v -15 +KPX agrave w -15 +KPX agrave y -20 +KPX agrave yacute -20 +KPX agrave ydieresis -20 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX amacron v -15 +KPX amacron w -15 +KPX amacron y -20 +KPX amacron yacute -20 +KPX amacron ydieresis -20 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aogonek v -15 +KPX aogonek w -15 +KPX aogonek y -20 +KPX aogonek yacute -20 +KPX aogonek ydieresis -20 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX aring v -15 +KPX aring w -15 +KPX aring y -20 +KPX aring yacute -20 +KPX aring ydieresis -20 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX atilde v -15 +KPX atilde w -15 +KPX atilde y -20 +KPX atilde yacute -20 +KPX atilde ydieresis -20 +KPX b l -10 +KPX b lacute -10 +KPX b lcommaaccent -10 +KPX b lslash -10 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c h -10 +KPX c k -20 +KPX c kcommaaccent -20 +KPX c l -20 +KPX c lacute -20 +KPX c lcommaaccent -20 +KPX c lslash -20 +KPX c y -10 +KPX c yacute -10 +KPX c ydieresis -10 +KPX cacute h -10 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX cacute l -20 +KPX cacute lacute -20 +KPX cacute lcommaaccent -20 +KPX cacute lslash -20 +KPX cacute y -10 +KPX cacute yacute -10 +KPX cacute ydieresis -10 +KPX ccaron h -10 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccaron l -20 +KPX ccaron lacute -20 +KPX ccaron lcommaaccent -20 +KPX ccaron lslash -20 +KPX ccaron y -10 +KPX ccaron yacute -10 +KPX ccaron ydieresis -10 +KPX ccedilla h -10 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX ccedilla l -20 +KPX ccedilla lacute -20 +KPX ccedilla lcommaaccent -20 +KPX ccedilla lslash -20 +KPX ccedilla y -10 +KPX ccedilla yacute -10 +KPX ccedilla ydieresis -10 +KPX colon space -40 +KPX comma quotedblright -120 +KPX comma quoteright -120 +KPX comma space -40 +KPX d d -10 +KPX d dcroat -10 +KPX d v -15 +KPX d w -15 +KPX d y -15 +KPX d yacute -15 +KPX d ydieresis -15 +KPX dcroat d -10 +KPX dcroat dcroat -10 +KPX dcroat v -15 +KPX dcroat w -15 +KPX dcroat y -15 +KPX dcroat yacute -15 +KPX dcroat ydieresis -15 +KPX e comma 10 +KPX e period 20 +KPX e v -15 +KPX e w -15 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute comma 10 +KPX eacute period 20 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron comma 10 +KPX ecaron period 20 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex comma 10 +KPX ecircumflex period 20 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis comma 10 +KPX edieresis period 20 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent comma 10 +KPX edotaccent period 20 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave comma 10 +KPX egrave period 20 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron comma 10 +KPX emacron period 20 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek comma 10 +KPX eogonek period 20 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f comma -10 +KPX f e -10 +KPX f eacute -10 +KPX f ecaron -10 +KPX f ecircumflex -10 +KPX f edieresis -10 +KPX f edotaccent -10 +KPX f egrave -10 +KPX f emacron -10 +KPX f eogonek -10 +KPX f o -20 +KPX f oacute -20 +KPX f ocircumflex -20 +KPX f odieresis -20 +KPX f ograve -20 +KPX f ohungarumlaut -20 +KPX f omacron -20 +KPX f oslash -20 +KPX f otilde -20 +KPX f period -10 +KPX f quotedblright 30 +KPX f quoteright 30 +KPX g e 10 +KPX g eacute 10 +KPX g ecaron 10 +KPX g ecircumflex 10 +KPX g edieresis 10 +KPX g edotaccent 10 +KPX g egrave 10 +KPX g emacron 10 +KPX g eogonek 10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX gbreve e 10 +KPX gbreve eacute 10 +KPX gbreve ecaron 10 +KPX gbreve ecircumflex 10 +KPX gbreve edieresis 10 +KPX gbreve edotaccent 10 +KPX gbreve egrave 10 +KPX gbreve emacron 10 +KPX gbreve eogonek 10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gcommaaccent e 10 +KPX gcommaaccent eacute 10 +KPX gcommaaccent ecaron 10 +KPX gcommaaccent ecircumflex 10 +KPX gcommaaccent edieresis 10 +KPX gcommaaccent edotaccent 10 +KPX gcommaaccent egrave 10 +KPX gcommaaccent emacron 10 +KPX gcommaaccent eogonek 10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX h y -20 +KPX h yacute -20 +KPX h ydieresis -20 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX l w -15 +KPX l y -15 +KPX l yacute -15 +KPX l ydieresis -15 +KPX lacute w -15 +KPX lacute y -15 +KPX lacute yacute -15 +KPX lacute ydieresis -15 +KPX lcommaaccent w -15 +KPX lcommaaccent y -15 +KPX lcommaaccent yacute -15 +KPX lcommaaccent ydieresis -15 +KPX lslash w -15 +KPX lslash y -15 +KPX lslash yacute -15 +KPX lslash ydieresis -15 +KPX m u -20 +KPX m uacute -20 +KPX m ucircumflex -20 +KPX m udieresis -20 +KPX m ugrave -20 +KPX m uhungarumlaut -20 +KPX m umacron -20 +KPX m uogonek -20 +KPX m uring -20 +KPX m y -30 +KPX m yacute -30 +KPX m ydieresis -30 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -40 +KPX n y -20 +KPX n yacute -20 +KPX n ydieresis -20 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -40 +KPX nacute y -20 +KPX nacute yacute -20 +KPX nacute ydieresis -20 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -40 +KPX ncaron y -20 +KPX ncaron yacute -20 +KPX ncaron ydieresis -20 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -40 +KPX ncommaaccent y -20 +KPX ncommaaccent yacute -20 +KPX ncommaaccent ydieresis -20 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -40 +KPX ntilde y -20 +KPX ntilde yacute -20 +KPX ntilde ydieresis -20 +KPX o v -20 +KPX o w -15 +KPX o x -30 +KPX o y -20 +KPX o yacute -20 +KPX o ydieresis -20 +KPX oacute v -20 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -20 +KPX oacute yacute -20 +KPX oacute ydieresis -20 +KPX ocircumflex v -20 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -20 +KPX ocircumflex yacute -20 +KPX ocircumflex ydieresis -20 +KPX odieresis v -20 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -20 +KPX odieresis yacute -20 +KPX odieresis ydieresis -20 +KPX ograve v -20 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -20 +KPX ograve yacute -20 +KPX ograve ydieresis -20 +KPX ohungarumlaut v -20 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -20 +KPX ohungarumlaut yacute -20 +KPX ohungarumlaut ydieresis -20 +KPX omacron v -20 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -20 +KPX omacron yacute -20 +KPX omacron ydieresis -20 +KPX oslash v -20 +KPX oslash w -15 +KPX oslash x -30 +KPX oslash y -20 +KPX oslash yacute -20 +KPX oslash ydieresis -20 +KPX otilde v -20 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -20 +KPX otilde yacute -20 +KPX otilde ydieresis -20 +KPX p y -15 +KPX p yacute -15 +KPX p ydieresis -15 +KPX period quotedblright -120 +KPX period quoteright -120 +KPX period space -40 +KPX quotedblright space -80 +KPX quoteleft quoteleft -46 +KPX quoteright d -80 +KPX quoteright dcroat -80 +KPX quoteright l -20 +KPX quoteright lacute -20 +KPX quoteright lcommaaccent -20 +KPX quoteright lslash -20 +KPX quoteright quoteright -46 +KPX quoteright r -40 +KPX quoteright racute -40 +KPX quoteright rcaron -40 +KPX quoteright rcommaaccent -40 +KPX quoteright s -60 +KPX quoteright sacute -60 +KPX quoteright scaron -60 +KPX quoteright scedilla -60 +KPX quoteright scommaaccent -60 +KPX quoteright space -80 +KPX quoteright v -20 +KPX r c -20 +KPX r cacute -20 +KPX r ccaron -20 +KPX r ccedilla -20 +KPX r comma -60 +KPX r d -20 +KPX r dcroat -20 +KPX r g -15 +KPX r gbreve -15 +KPX r gcommaaccent -15 +KPX r hyphen -20 +KPX r o -20 +KPX r oacute -20 +KPX r ocircumflex -20 +KPX r odieresis -20 +KPX r ograve -20 +KPX r ohungarumlaut -20 +KPX r omacron -20 +KPX r oslash -20 +KPX r otilde -20 +KPX r period -60 +KPX r q -20 +KPX r s -15 +KPX r sacute -15 +KPX r scaron -15 +KPX r scedilla -15 +KPX r scommaaccent -15 +KPX r t 20 +KPX r tcommaaccent 20 +KPX r v 10 +KPX r y 10 +KPX r yacute 10 +KPX r ydieresis 10 +KPX racute c -20 +KPX racute cacute -20 +KPX racute ccaron -20 +KPX racute ccedilla -20 +KPX racute comma -60 +KPX racute d -20 +KPX racute dcroat -20 +KPX racute g -15 +KPX racute gbreve -15 +KPX racute gcommaaccent -15 +KPX racute hyphen -20 +KPX racute o -20 +KPX racute oacute -20 +KPX racute ocircumflex -20 +KPX racute odieresis -20 +KPX racute ograve -20 +KPX racute ohungarumlaut -20 +KPX racute omacron -20 +KPX racute oslash -20 +KPX racute otilde -20 +KPX racute period -60 +KPX racute q -20 +KPX racute s -15 +KPX racute sacute -15 +KPX racute scaron -15 +KPX racute scedilla -15 +KPX racute scommaaccent -15 +KPX racute t 20 +KPX racute tcommaaccent 20 +KPX racute v 10 +KPX racute y 10 +KPX racute yacute 10 +KPX racute ydieresis 10 +KPX rcaron c -20 +KPX rcaron cacute -20 +KPX rcaron ccaron -20 +KPX rcaron ccedilla -20 +KPX rcaron comma -60 +KPX rcaron d -20 +KPX rcaron dcroat -20 +KPX rcaron g -15 +KPX rcaron gbreve -15 +KPX rcaron gcommaaccent -15 +KPX rcaron hyphen -20 +KPX rcaron o -20 +KPX rcaron oacute -20 +KPX rcaron ocircumflex -20 +KPX rcaron odieresis -20 +KPX rcaron ograve -20 +KPX rcaron ohungarumlaut -20 +KPX rcaron omacron -20 +KPX rcaron oslash -20 +KPX rcaron otilde -20 +KPX rcaron period -60 +KPX rcaron q -20 +KPX rcaron s -15 +KPX rcaron sacute -15 +KPX rcaron scaron -15 +KPX rcaron scedilla -15 +KPX rcaron scommaaccent -15 +KPX rcaron t 20 +KPX rcaron tcommaaccent 20 +KPX rcaron v 10 +KPX rcaron y 10 +KPX rcaron yacute 10 +KPX rcaron ydieresis 10 +KPX rcommaaccent c -20 +KPX rcommaaccent cacute -20 +KPX rcommaaccent ccaron -20 +KPX rcommaaccent ccedilla -20 +KPX rcommaaccent comma -60 +KPX rcommaaccent d -20 +KPX rcommaaccent dcroat -20 +KPX rcommaaccent g -15 +KPX rcommaaccent gbreve -15 +KPX rcommaaccent gcommaaccent -15 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -20 +KPX rcommaaccent oacute -20 +KPX rcommaaccent ocircumflex -20 +KPX rcommaaccent odieresis -20 +KPX rcommaaccent ograve -20 +KPX rcommaaccent ohungarumlaut -20 +KPX rcommaaccent omacron -20 +KPX rcommaaccent oslash -20 +KPX rcommaaccent otilde -20 +KPX rcommaaccent period -60 +KPX rcommaaccent q -20 +KPX rcommaaccent s -15 +KPX rcommaaccent sacute -15 +KPX rcommaaccent scaron -15 +KPX rcommaaccent scedilla -15 +KPX rcommaaccent scommaaccent -15 +KPX rcommaaccent t 20 +KPX rcommaaccent tcommaaccent 20 +KPX rcommaaccent v 10 +KPX rcommaaccent y 10 +KPX rcommaaccent yacute 10 +KPX rcommaaccent ydieresis 10 +KPX s w -15 +KPX sacute w -15 +KPX scaron w -15 +KPX scedilla w -15 +KPX scommaaccent w -15 +KPX semicolon space -40 +KPX space T -100 +KPX space Tcaron -100 +KPX space Tcommaaccent -100 +KPX space V -80 +KPX space W -80 +KPX space Y -120 +KPX space Yacute -120 +KPX space Ydieresis -120 +KPX space quotedblleft -80 +KPX space quoteleft -60 +KPX v a -20 +KPX v aacute -20 +KPX v abreve -20 +KPX v acircumflex -20 +KPX v adieresis -20 +KPX v agrave -20 +KPX v amacron -20 +KPX v aogonek -20 +KPX v aring -20 +KPX v atilde -20 +KPX v comma -80 +KPX v o -30 +KPX v oacute -30 +KPX v ocircumflex -30 +KPX v odieresis -30 +KPX v ograve -30 +KPX v ohungarumlaut -30 +KPX v omacron -30 +KPX v oslash -30 +KPX v otilde -30 +KPX v period -80 +KPX w comma -40 +KPX w o -20 +KPX w oacute -20 +KPX w ocircumflex -20 +KPX w odieresis -20 +KPX w ograve -20 +KPX w ohungarumlaut -20 +KPX w omacron -20 +KPX w oslash -20 +KPX w otilde -20 +KPX w period -40 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y a -30 +KPX y aacute -30 +KPX y abreve -30 +KPX y acircumflex -30 +KPX y adieresis -30 +KPX y agrave -30 +KPX y amacron -30 +KPX y aogonek -30 +KPX y aring -30 +KPX y atilde -30 +KPX y comma -80 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -80 +KPX yacute a -30 +KPX yacute aacute -30 +KPX yacute abreve -30 +KPX yacute acircumflex -30 +KPX yacute adieresis -30 +KPX yacute agrave -30 +KPX yacute amacron -30 +KPX yacute aogonek -30 +KPX yacute aring -30 +KPX yacute atilde -30 +KPX yacute comma -80 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -80 +KPX ydieresis a -30 +KPX ydieresis aacute -30 +KPX ydieresis abreve -30 +KPX ydieresis acircumflex -30 +KPX ydieresis adieresis -30 +KPX ydieresis agrave -30 +KPX ydieresis amacron -30 +KPX ydieresis aogonek -30 +KPX ydieresis aring -30 +KPX ydieresis atilde -30 +KPX ydieresis comma -80 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -80 +KPX z e 10 +KPX z eacute 10 +KPX z ecaron 10 +KPX z ecircumflex 10 +KPX z edieresis 10 +KPX z edotaccent 10 +KPX z egrave 10 +KPX z emacron 10 +KPX z eogonek 10 +KPX zacute e 10 +KPX zacute eacute 10 +KPX zacute ecaron 10 +KPX zacute ecircumflex 10 +KPX zacute edieresis 10 +KPX zacute edotaccent 10 +KPX zacute egrave 10 +KPX zacute emacron 10 +KPX zacute eogonek 10 +KPX zcaron e 10 +KPX zcaron eacute 10 +KPX zcaron ecaron 10 +KPX zcaron ecircumflex 10 +KPX zcaron edieresis 10 +KPX zcaron edotaccent 10 +KPX zcaron egrave 10 +KPX zcaron emacron 10 +KPX zcaron eogonek 10 +KPX zdotaccent e 10 +KPX zdotaccent eacute 10 +KPX zdotaccent ecaron 10 +KPX zdotaccent ecircumflex 10 +KPX zdotaccent edieresis 10 +KPX zdotaccent edotaccent 10 +KPX zdotaccent egrave 10 +KPX zdotaccent emacron 10 +KPX zdotaccent eogonek 10 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm new file mode 100644 index 00000000..7a7af001 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm @@ -0,0 +1,3051 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:44:31 1997 +Comment UniqueID 43055 +Comment VMusage 14960 69346 +FontName Helvetica-Oblique +FullName Helvetica Oblique +FamilyName Helvetica +Weight Medium +ItalicAngle -12 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -170 -225 1116 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StdHW 76 +StdVW 88 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ; +C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ; +C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ; +C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ; +C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ; +C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ; +C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ; +C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ; +C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ; +C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ; +C 43 ; WX 584 ; N plus ; B 85 0 606 505 ; +C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ; +C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ; +C 46 ; WX 278 ; N period ; B 87 0 214 106 ; +C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ; +C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ; +C 49 ; WX 556 ; N one ; B 207 0 508 703 ; +C 50 ; WX 556 ; N two ; B 26 0 617 703 ; +C 51 ; WX 556 ; N three ; B 75 -19 610 703 ; +C 52 ; WX 556 ; N four ; B 61 0 576 703 ; +C 53 ; WX 556 ; N five ; B 68 -19 621 688 ; +C 54 ; WX 556 ; N six ; B 91 -19 615 703 ; +C 55 ; WX 556 ; N seven ; B 137 0 669 688 ; +C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ; +C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 301 516 ; +C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ; +C 60 ; WX 584 ; N less ; B 94 11 641 495 ; +C 61 ; WX 584 ; N equal ; B 63 115 628 390 ; +C 62 ; WX 584 ; N greater ; B 50 11 597 495 ; +C 63 ; WX 556 ; N question ; B 161 0 610 727 ; +C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 712 718 ; +C 67 ; WX 722 ; N C ; B 108 -19 782 737 ; +C 68 ; WX 722 ; N D ; B 81 0 764 718 ; +C 69 ; WX 667 ; N E ; B 86 0 762 718 ; +C 70 ; WX 611 ; N F ; B 86 0 736 718 ; +C 71 ; WX 778 ; N G ; B 111 -19 799 737 ; +C 72 ; WX 722 ; N H ; B 77 0 799 718 ; +C 73 ; WX 278 ; N I ; B 91 0 341 718 ; +C 74 ; WX 500 ; N J ; B 47 -19 581 718 ; +C 75 ; WX 667 ; N K ; B 76 0 808 718 ; +C 76 ; WX 556 ; N L ; B 76 0 555 718 ; +C 77 ; WX 833 ; N M ; B 73 0 914 718 ; +C 78 ; WX 722 ; N N ; B 76 0 799 718 ; +C 79 ; WX 778 ; N O ; B 105 -19 826 737 ; +C 80 ; WX 667 ; N P ; B 86 0 737 718 ; +C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ; +C 82 ; WX 722 ; N R ; B 88 0 773 718 ; +C 83 ; WX 667 ; N S ; B 90 -19 713 737 ; +C 84 ; WX 611 ; N T ; B 148 0 750 718 ; +C 85 ; WX 722 ; N U ; B 123 -19 797 718 ; +C 86 ; WX 667 ; N V ; B 173 0 800 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1081 718 ; +C 88 ; WX 667 ; N X ; B 19 0 790 718 ; +C 89 ; WX 667 ; N Y ; B 167 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 741 718 ; +C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ; +C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ; +C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ; +C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ; +C 97 ; WX 556 ; N a ; B 61 -15 559 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 584 718 ; +C 99 ; WX 500 ; N c ; B 74 -15 553 538 ; +C 100 ; WX 556 ; N d ; B 84 -15 652 718 ; +C 101 ; WX 556 ; N e ; B 84 -15 578 538 ; +C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 42 -220 610 538 ; +C 104 ; WX 556 ; N h ; B 65 0 573 718 ; +C 105 ; WX 222 ; N i ; B 67 0 308 718 ; +C 106 ; WX 222 ; N j ; B -60 -210 308 718 ; +C 107 ; WX 500 ; N k ; B 67 0 600 718 ; +C 108 ; WX 222 ; N l ; B 67 0 308 718 ; +C 109 ; WX 833 ; N m ; B 65 0 852 538 ; +C 110 ; WX 556 ; N n ; B 65 0 573 538 ; +C 111 ; WX 556 ; N o ; B 83 -14 585 538 ; +C 112 ; WX 556 ; N p ; B 14 -207 584 538 ; +C 113 ; WX 556 ; N q ; B 84 -207 605 538 ; +C 114 ; WX 333 ; N r ; B 77 0 446 538 ; +C 115 ; WX 500 ; N s ; B 63 -15 529 538 ; +C 116 ; WX 278 ; N t ; B 102 -7 368 669 ; +C 117 ; WX 556 ; N u ; B 94 -15 600 523 ; +C 118 ; WX 500 ; N v ; B 119 0 603 523 ; +C 119 ; WX 722 ; N w ; B 125 0 820 523 ; +C 120 ; WX 500 ; N x ; B 11 0 594 523 ; +C 121 ; WX 500 ; N y ; B 15 -214 600 523 ; +C 122 ; WX 500 ; N z ; B 31 0 571 523 ; +C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ; +C 124 ; WX 260 ; N bar ; B 46 -225 332 775 ; +C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ; +C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ; +C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ; +C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ; +C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ; +C 165 ; WX 556 ; N yen ; B 81 0 699 688 ; +C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ; +C 167 ; WX 556 ; N section ; B 76 -191 584 737 ; +C 168 ; WX 556 ; N currency ; B 60 99 646 603 ; +C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ; +C 174 ; WX 500 ; N fi ; B 86 0 587 728 ; +C 175 ; WX 500 ; N fl ; B 86 0 585 728 ; +C 177 ; WX 556 ; N endash ; B 51 240 623 313 ; +C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ; +C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ; +C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ; +C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ; +C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ; +C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ; +C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ; +C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ; +C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ; +C 193 ; WX 333 ; N grave ; B 170 593 337 734 ; +C 194 ; WX 333 ; N acute ; B 248 593 475 734 ; +C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ; +C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ; +C 197 ; WX 333 ; N macron ; B 143 627 468 684 ; +C 198 ; WX 333 ; N breve ; B 167 595 476 731 ; +C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ; +C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ; +C 202 ; WX 333 ; N ring ; B 214 572 402 756 ; +C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ; +C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ; +C 207 ; WX 333 ; N caron ; B 177 593 468 734 ; +C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 127 405 449 737 ; +C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ; +C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ; +C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 141 405 468 737 ; +C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ; +C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ; +C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ; +C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ; +C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ; +C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ; +C -1 ; WX 556 ; N abreve ; B 61 -15 578 731 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 94 -15 677 734 ; +C -1 ; WX 556 ; N ecaron ; B 84 -15 580 734 ; +C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ; +C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ; +C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ; +C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ; +C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ; +C -1 ; WX 500 ; N scommaaccent ; B 63 -225 529 538 ; +C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ; +C -1 ; WX 722 ; N Uring ; B 123 -19 797 931 ; +C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ; +C -1 ; WX 556 ; N aogonek ; B 61 -220 559 538 ; +C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ; +C -1 ; WX 556 ; N uogonek ; B 94 -225 600 523 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ; +C -1 ; WX 722 ; N Dcroat ; B 69 0 764 718 ; +C -1 ; WX 250 ; N commaaccent ; B 39 -225 172 -40 ; +C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ; +C -1 ; WX 667 ; N Emacron ; B 86 0 762 879 ; +C -1 ; WX 500 ; N ccaron ; B 74 -15 553 734 ; +C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 799 718 ; +C -1 ; WX 222 ; N lacute ; B 67 0 461 929 ; +C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 148 -225 750 718 ; +C -1 ; WX 722 ; N Cacute ; B 108 -19 782 929 ; +C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ; +C -1 ; WX 667 ; N Edotaccent ; B 86 0 762 901 ; +C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ; +C -1 ; WX 500 ; N scedilla ; B 63 -225 529 538 ; +C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ; +C -1 ; WX 471 ; N lozenge ; B 88 0 540 728 ; +C -1 ; WX 722 ; N Rcaron ; B 88 0 773 929 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 111 -225 799 737 ; +C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ; +C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ; +C -1 ; WX 667 ; N Amacron ; B 14 0 677 879 ; +C -1 ; WX 333 ; N rcaron ; B 77 0 508 734 ; +C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ; +C -1 ; WX 611 ; N Zdotaccent ; B 23 0 741 901 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ; +C -1 ; WX 778 ; N Omacron ; B 105 -19 826 879 ; +C -1 ; WX 722 ; N Racute ; B 88 0 773 929 ; +C -1 ; WX 667 ; N Sacute ; B 90 -19 713 929 ; +C -1 ; WX 643 ; N dcaron ; B 84 -15 808 718 ; +C -1 ; WX 722 ; N Umacron ; B 123 -19 797 879 ; +C -1 ; WX 556 ; N uring ; B 94 -15 600 756 ; +C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ; +C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Abreve ; B 14 0 685 926 ; +C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ; +C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ; +C -1 ; WX 611 ; N Tcaron ; B 148 0 750 929 ; +C -1 ; WX 476 ; N partialdiff ; B 41 -38 550 714 ; +C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ; +C -1 ; WX 722 ; N Nacute ; B 76 0 799 929 ; +C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ; +C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ; +C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ; +C -1 ; WX 500 ; N cacute ; B 74 -15 559 734 ; +C -1 ; WX 556 ; N nacute ; B 65 0 587 734 ; +C -1 ; WX 556 ; N umacron ; B 94 -15 600 684 ; +C -1 ; WX 722 ; N Ncaron ; B 76 0 799 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ; +C -1 ; WX 260 ; N brokenbar ; B 62 -150 316 700 ; +C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ; +C -1 ; WX 778 ; N Gbreve ; B 111 -19 799 926 ; +C -1 ; WX 278 ; N Idotaccent ; B 91 0 377 901 ; +C -1 ; WX 600 ; N summation ; B 15 -10 671 706 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ; +C -1 ; WX 333 ; N racute ; B 77 0 475 734 ; +C -1 ; WX 556 ; N omacron ; B 83 -14 585 684 ; +C -1 ; WX 611 ; N Zacute ; B 23 0 741 929 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 620 674 ; +C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ; +C -1 ; WX 222 ; N lcommaaccent ; B 25 -225 308 718 ; +C -1 ; WX 317 ; N tcaron ; B 102 -7 501 808 ; +C -1 ; WX 556 ; N eogonek ; B 84 -225 578 538 ; +C -1 ; WX 722 ; N Uogonek ; B 123 -225 797 718 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ; +C -1 ; WX 500 ; N zacute ; B 31 0 571 734 ; +C -1 ; WX 222 ; N iogonek ; B -61 -225 308 718 ; +C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ; +C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ; +C -1 ; WX 556 ; N amacron ; B 61 -15 580 684 ; +C -1 ; WX 500 ; N sacute ; B 63 -15 559 734 ; +C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ; +C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ; +C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ; +C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ; +C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ; +C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ; +C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ; +C -1 ; WX 556 ; N ohungarumlaut ; B 83 -14 677 734 ; +C -1 ; WX 667 ; N Eogonek ; B 86 -220 762 718 ; +C -1 ; WX 556 ; N dcroat ; B 84 -15 689 718 ; +C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ; +C -1 ; WX 667 ; N Scedilla ; B 90 -225 713 737 ; +C -1 ; WX 299 ; N lcaron ; B 67 0 464 718 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 808 718 ; +C -1 ; WX 556 ; N Lacute ; B 76 0 555 929 ; +C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ; +C -1 ; WX 556 ; N edotaccent ; B 84 -15 578 706 ; +C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ; +C -1 ; WX 278 ; N Imacron ; B 91 0 483 879 ; +C -1 ; WX 556 ; N Lcaron ; B 76 0 570 718 ; +C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 666 674 ; +C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 123 -19 801 929 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ; +C -1 ; WX 556 ; N emacron ; B 84 -15 580 684 ; +C -1 ; WX 556 ; N gbreve ; B 42 -220 610 731 ; +C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ; +C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ; +C -1 ; WX 667 ; N Scommaaccent ; B 90 -225 713 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 105 -19 829 929 ; +C -1 ; WX 400 ; N degree ; B 169 411 468 703 ; +C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ; +C -1 ; WX 722 ; N Ccaron ; B 108 -19 782 929 ; +C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ; +C -1 ; WX 453 ; N radical ; B 79 -80 617 762 ; +C -1 ; WX 722 ; N Dcaron ; B 81 0 764 929 ; +C -1 ; WX 333 ; N rcommaaccent ; B 30 -225 446 538 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ; +C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 773 718 ; +C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 555 718 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ; +C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ; +C -1 ; WX 500 ; N zdotaccent ; B 31 0 571 706 ; +C -1 ; WX 667 ; N Ecaron ; B 86 0 762 929 ; +C -1 ; WX 278 ; N Iogonek ; B -33 -225 341 718 ; +C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 600 718 ; +C -1 ; WX 584 ; N minus ; B 85 216 606 289 ; +C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ; +C -1 ; WX 556 ; N ncaron ; B 65 0 580 734 ; +C -1 ; WX 278 ; N tcommaaccent ; B 63 -225 368 669 ; +C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ; +C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ; +C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ; +C -1 ; WX 549 ; N notequal ; B 34 -35 623 551 ; +C -1 ; WX 556 ; N gcommaaccent ; B 42 -220 610 822 ; +C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ; +C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 573 538 ; +C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ; +C -1 ; WX 278 ; N imacron ; B 95 0 417 684 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2705 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -30 +KPX A Gbreve -30 +KPX A Gcommaaccent -30 +KPX A O -30 +KPX A Oacute -30 +KPX A Ocircumflex -30 +KPX A Odieresis -30 +KPX A Ograve -30 +KPX A Ohungarumlaut -30 +KPX A Omacron -30 +KPX A Oslash -30 +KPX A Otilde -30 +KPX A Q -30 +KPX A T -120 +KPX A Tcaron -120 +KPX A Tcommaaccent -120 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -70 +KPX A W -50 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -40 +KPX A y -40 +KPX A yacute -40 +KPX A ydieresis -40 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -30 +KPX Aacute Gbreve -30 +KPX Aacute Gcommaaccent -30 +KPX Aacute O -30 +KPX Aacute Oacute -30 +KPX Aacute Ocircumflex -30 +KPX Aacute Odieresis -30 +KPX Aacute Ograve -30 +KPX Aacute Ohungarumlaut -30 +KPX Aacute Omacron -30 +KPX Aacute Oslash -30 +KPX Aacute Otilde -30 +KPX Aacute Q -30 +KPX Aacute T -120 +KPX Aacute Tcaron -120 +KPX Aacute Tcommaaccent -120 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -70 +KPX Aacute W -50 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -40 +KPX Aacute y -40 +KPX Aacute yacute -40 +KPX Aacute ydieresis -40 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -30 +KPX Abreve Gbreve -30 +KPX Abreve Gcommaaccent -30 +KPX Abreve O -30 +KPX Abreve Oacute -30 +KPX Abreve Ocircumflex -30 +KPX Abreve Odieresis -30 +KPX Abreve Ograve -30 +KPX Abreve Ohungarumlaut -30 +KPX Abreve Omacron -30 +KPX Abreve Oslash -30 +KPX Abreve Otilde -30 +KPX Abreve Q -30 +KPX Abreve T -120 +KPX Abreve Tcaron -120 +KPX Abreve Tcommaaccent -120 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -70 +KPX Abreve W -50 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -40 +KPX Abreve y -40 +KPX Abreve yacute -40 +KPX Abreve ydieresis -40 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -30 +KPX Acircumflex Gbreve -30 +KPX Acircumflex Gcommaaccent -30 +KPX Acircumflex O -30 +KPX Acircumflex Oacute -30 +KPX Acircumflex Ocircumflex -30 +KPX Acircumflex Odieresis -30 +KPX Acircumflex Ograve -30 +KPX Acircumflex Ohungarumlaut -30 +KPX Acircumflex Omacron -30 +KPX Acircumflex Oslash -30 +KPX Acircumflex Otilde -30 +KPX Acircumflex Q -30 +KPX Acircumflex T -120 +KPX Acircumflex Tcaron -120 +KPX Acircumflex Tcommaaccent -120 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -70 +KPX Acircumflex W -50 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -40 +KPX Acircumflex y -40 +KPX Acircumflex yacute -40 +KPX Acircumflex ydieresis -40 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -30 +KPX Adieresis Gbreve -30 +KPX Adieresis Gcommaaccent -30 +KPX Adieresis O -30 +KPX Adieresis Oacute -30 +KPX Adieresis Ocircumflex -30 +KPX Adieresis Odieresis -30 +KPX Adieresis Ograve -30 +KPX Adieresis Ohungarumlaut -30 +KPX Adieresis Omacron -30 +KPX Adieresis Oslash -30 +KPX Adieresis Otilde -30 +KPX Adieresis Q -30 +KPX Adieresis T -120 +KPX Adieresis Tcaron -120 +KPX Adieresis Tcommaaccent -120 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -70 +KPX Adieresis W -50 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -40 +KPX Adieresis y -40 +KPX Adieresis yacute -40 +KPX Adieresis ydieresis -40 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -30 +KPX Agrave Gbreve -30 +KPX Agrave Gcommaaccent -30 +KPX Agrave O -30 +KPX Agrave Oacute -30 +KPX Agrave Ocircumflex -30 +KPX Agrave Odieresis -30 +KPX Agrave Ograve -30 +KPX Agrave Ohungarumlaut -30 +KPX Agrave Omacron -30 +KPX Agrave Oslash -30 +KPX Agrave Otilde -30 +KPX Agrave Q -30 +KPX Agrave T -120 +KPX Agrave Tcaron -120 +KPX Agrave Tcommaaccent -120 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -70 +KPX Agrave W -50 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -40 +KPX Agrave y -40 +KPX Agrave yacute -40 +KPX Agrave ydieresis -40 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -30 +KPX Amacron Gbreve -30 +KPX Amacron Gcommaaccent -30 +KPX Amacron O -30 +KPX Amacron Oacute -30 +KPX Amacron Ocircumflex -30 +KPX Amacron Odieresis -30 +KPX Amacron Ograve -30 +KPX Amacron Ohungarumlaut -30 +KPX Amacron Omacron -30 +KPX Amacron Oslash -30 +KPX Amacron Otilde -30 +KPX Amacron Q -30 +KPX Amacron T -120 +KPX Amacron Tcaron -120 +KPX Amacron Tcommaaccent -120 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -70 +KPX Amacron W -50 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -40 +KPX Amacron y -40 +KPX Amacron yacute -40 +KPX Amacron ydieresis -40 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -30 +KPX Aogonek Gbreve -30 +KPX Aogonek Gcommaaccent -30 +KPX Aogonek O -30 +KPX Aogonek Oacute -30 +KPX Aogonek Ocircumflex -30 +KPX Aogonek Odieresis -30 +KPX Aogonek Ograve -30 +KPX Aogonek Ohungarumlaut -30 +KPX Aogonek Omacron -30 +KPX Aogonek Oslash -30 +KPX Aogonek Otilde -30 +KPX Aogonek Q -30 +KPX Aogonek T -120 +KPX Aogonek Tcaron -120 +KPX Aogonek Tcommaaccent -120 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -70 +KPX Aogonek W -50 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -40 +KPX Aogonek y -40 +KPX Aogonek yacute -40 +KPX Aogonek ydieresis -40 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -30 +KPX Aring Gbreve -30 +KPX Aring Gcommaaccent -30 +KPX Aring O -30 +KPX Aring Oacute -30 +KPX Aring Ocircumflex -30 +KPX Aring Odieresis -30 +KPX Aring Ograve -30 +KPX Aring Ohungarumlaut -30 +KPX Aring Omacron -30 +KPX Aring Oslash -30 +KPX Aring Otilde -30 +KPX Aring Q -30 +KPX Aring T -120 +KPX Aring Tcaron -120 +KPX Aring Tcommaaccent -120 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -70 +KPX Aring W -50 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -40 +KPX Aring y -40 +KPX Aring yacute -40 +KPX Aring ydieresis -40 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -30 +KPX Atilde Gbreve -30 +KPX Atilde Gcommaaccent -30 +KPX Atilde O -30 +KPX Atilde Oacute -30 +KPX Atilde Ocircumflex -30 +KPX Atilde Odieresis -30 +KPX Atilde Ograve -30 +KPX Atilde Ohungarumlaut -30 +KPX Atilde Omacron -30 +KPX Atilde Oslash -30 +KPX Atilde Otilde -30 +KPX Atilde Q -30 +KPX Atilde T -120 +KPX Atilde Tcaron -120 +KPX Atilde Tcommaaccent -120 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -70 +KPX Atilde W -50 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -40 +KPX Atilde y -40 +KPX Atilde yacute -40 +KPX Atilde ydieresis -40 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX B comma -20 +KPX B period -20 +KPX C comma -30 +KPX C period -30 +KPX Cacute comma -30 +KPX Cacute period -30 +KPX Ccaron comma -30 +KPX Ccaron period -30 +KPX Ccedilla comma -30 +KPX Ccedilla period -30 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -70 +KPX D W -40 +KPX D Y -90 +KPX D Yacute -90 +KPX D Ydieresis -90 +KPX D comma -70 +KPX D period -70 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -70 +KPX Dcaron W -40 +KPX Dcaron Y -90 +KPX Dcaron Yacute -90 +KPX Dcaron Ydieresis -90 +KPX Dcaron comma -70 +KPX Dcaron period -70 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -70 +KPX Dcroat W -40 +KPX Dcroat Y -90 +KPX Dcroat Yacute -90 +KPX Dcroat Ydieresis -90 +KPX Dcroat comma -70 +KPX Dcroat period -70 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -50 +KPX F aacute -50 +KPX F abreve -50 +KPX F acircumflex -50 +KPX F adieresis -50 +KPX F agrave -50 +KPX F amacron -50 +KPX F aogonek -50 +KPX F aring -50 +KPX F atilde -50 +KPX F comma -150 +KPX F e -30 +KPX F eacute -30 +KPX F ecaron -30 +KPX F ecircumflex -30 +KPX F edieresis -30 +KPX F edotaccent -30 +KPX F egrave -30 +KPX F emacron -30 +KPX F eogonek -30 +KPX F o -30 +KPX F oacute -30 +KPX F ocircumflex -30 +KPX F odieresis -30 +KPX F ograve -30 +KPX F ohungarumlaut -30 +KPX F omacron -30 +KPX F oslash -30 +KPX F otilde -30 +KPX F period -150 +KPX F r -45 +KPX F racute -45 +KPX F rcaron -45 +KPX F rcommaaccent -45 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J a -20 +KPX J aacute -20 +KPX J abreve -20 +KPX J acircumflex -20 +KPX J adieresis -20 +KPX J agrave -20 +KPX J amacron -20 +KPX J aogonek -20 +KPX J aring -20 +KPX J atilde -20 +KPX J comma -30 +KPX J period -30 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -40 +KPX K eacute -40 +KPX K ecaron -40 +KPX K ecircumflex -40 +KPX K edieresis -40 +KPX K edotaccent -40 +KPX K egrave -40 +KPX K emacron -40 +KPX K eogonek -40 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -50 +KPX K yacute -50 +KPX K ydieresis -50 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -40 +KPX Kcommaaccent eacute -40 +KPX Kcommaaccent ecaron -40 +KPX Kcommaaccent ecircumflex -40 +KPX Kcommaaccent edieresis -40 +KPX Kcommaaccent edotaccent -40 +KPX Kcommaaccent egrave -40 +KPX Kcommaaccent emacron -40 +KPX Kcommaaccent eogonek -40 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -50 +KPX Kcommaaccent yacute -50 +KPX Kcommaaccent ydieresis -50 +KPX L T -110 +KPX L Tcaron -110 +KPX L Tcommaaccent -110 +KPX L V -110 +KPX L W -70 +KPX L Y -140 +KPX L Yacute -140 +KPX L Ydieresis -140 +KPX L quotedblright -140 +KPX L quoteright -160 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -110 +KPX Lacute Tcaron -110 +KPX Lacute Tcommaaccent -110 +KPX Lacute V -110 +KPX Lacute W -70 +KPX Lacute Y -140 +KPX Lacute Yacute -140 +KPX Lacute Ydieresis -140 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -160 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcaron T -110 +KPX Lcaron Tcaron -110 +KPX Lcaron Tcommaaccent -110 +KPX Lcaron V -110 +KPX Lcaron W -70 +KPX Lcaron Y -140 +KPX Lcaron Yacute -140 +KPX Lcaron Ydieresis -140 +KPX Lcaron quotedblright -140 +KPX Lcaron quoteright -160 +KPX Lcaron y -30 +KPX Lcaron yacute -30 +KPX Lcaron ydieresis -30 +KPX Lcommaaccent T -110 +KPX Lcommaaccent Tcaron -110 +KPX Lcommaaccent Tcommaaccent -110 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -70 +KPX Lcommaaccent Y -140 +KPX Lcommaaccent Yacute -140 +KPX Lcommaaccent Ydieresis -140 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -160 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -110 +KPX Lslash Tcaron -110 +KPX Lslash Tcommaaccent -110 +KPX Lslash V -110 +KPX Lslash W -70 +KPX Lslash Y -140 +KPX Lslash Yacute -140 +KPX Lslash Ydieresis -140 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -160 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -20 +KPX O Aacute -20 +KPX O Abreve -20 +KPX O Acircumflex -20 +KPX O Adieresis -20 +KPX O Agrave -20 +KPX O Amacron -20 +KPX O Aogonek -20 +KPX O Aring -20 +KPX O Atilde -20 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -30 +KPX O X -60 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -20 +KPX Oacute Aacute -20 +KPX Oacute Abreve -20 +KPX Oacute Acircumflex -20 +KPX Oacute Adieresis -20 +KPX Oacute Agrave -20 +KPX Oacute Amacron -20 +KPX Oacute Aogonek -20 +KPX Oacute Aring -20 +KPX Oacute Atilde -20 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -30 +KPX Oacute X -60 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -20 +KPX Ocircumflex Aacute -20 +KPX Ocircumflex Abreve -20 +KPX Ocircumflex Acircumflex -20 +KPX Ocircumflex Adieresis -20 +KPX Ocircumflex Agrave -20 +KPX Ocircumflex Amacron -20 +KPX Ocircumflex Aogonek -20 +KPX Ocircumflex Aring -20 +KPX Ocircumflex Atilde -20 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -30 +KPX Ocircumflex X -60 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -20 +KPX Odieresis Aacute -20 +KPX Odieresis Abreve -20 +KPX Odieresis Acircumflex -20 +KPX Odieresis Adieresis -20 +KPX Odieresis Agrave -20 +KPX Odieresis Amacron -20 +KPX Odieresis Aogonek -20 +KPX Odieresis Aring -20 +KPX Odieresis Atilde -20 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -30 +KPX Odieresis X -60 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -20 +KPX Ograve Aacute -20 +KPX Ograve Abreve -20 +KPX Ograve Acircumflex -20 +KPX Ograve Adieresis -20 +KPX Ograve Agrave -20 +KPX Ograve Amacron -20 +KPX Ograve Aogonek -20 +KPX Ograve Aring -20 +KPX Ograve Atilde -20 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -30 +KPX Ograve X -60 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -20 +KPX Ohungarumlaut Aacute -20 +KPX Ohungarumlaut Abreve -20 +KPX Ohungarumlaut Acircumflex -20 +KPX Ohungarumlaut Adieresis -20 +KPX Ohungarumlaut Agrave -20 +KPX Ohungarumlaut Amacron -20 +KPX Ohungarumlaut Aogonek -20 +KPX Ohungarumlaut Aring -20 +KPX Ohungarumlaut Atilde -20 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -30 +KPX Ohungarumlaut X -60 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -20 +KPX Omacron Aacute -20 +KPX Omacron Abreve -20 +KPX Omacron Acircumflex -20 +KPX Omacron Adieresis -20 +KPX Omacron Agrave -20 +KPX Omacron Amacron -20 +KPX Omacron Aogonek -20 +KPX Omacron Aring -20 +KPX Omacron Atilde -20 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -30 +KPX Omacron X -60 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -20 +KPX Oslash Aacute -20 +KPX Oslash Abreve -20 +KPX Oslash Acircumflex -20 +KPX Oslash Adieresis -20 +KPX Oslash Agrave -20 +KPX Oslash Amacron -20 +KPX Oslash Aogonek -20 +KPX Oslash Aring -20 +KPX Oslash Atilde -20 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -30 +KPX Oslash X -60 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -20 +KPX Otilde Aacute -20 +KPX Otilde Abreve -20 +KPX Otilde Acircumflex -20 +KPX Otilde Adieresis -20 +KPX Otilde Agrave -20 +KPX Otilde Amacron -20 +KPX Otilde Aogonek -20 +KPX Otilde Aring -20 +KPX Otilde Atilde -20 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -30 +KPX Otilde X -60 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -120 +KPX P Aacute -120 +KPX P Abreve -120 +KPX P Acircumflex -120 +KPX P Adieresis -120 +KPX P Agrave -120 +KPX P Amacron -120 +KPX P Aogonek -120 +KPX P Aring -120 +KPX P Atilde -120 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -180 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -50 +KPX P oacute -50 +KPX P ocircumflex -50 +KPX P odieresis -50 +KPX P ograve -50 +KPX P ohungarumlaut -50 +KPX P omacron -50 +KPX P oslash -50 +KPX P otilde -50 +KPX P period -180 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -50 +KPX R W -30 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -50 +KPX Racute W -30 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -50 +KPX Rcaron W -30 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -30 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX S comma -20 +KPX S period -20 +KPX Sacute comma -20 +KPX Sacute period -20 +KPX Scaron comma -20 +KPX Scaron period -20 +KPX Scedilla comma -20 +KPX Scedilla period -20 +KPX Scommaaccent comma -20 +KPX Scommaaccent period -20 +KPX T A -120 +KPX T Aacute -120 +KPX T Abreve -120 +KPX T Acircumflex -120 +KPX T Adieresis -120 +KPX T Agrave -120 +KPX T Amacron -120 +KPX T Aogonek -120 +KPX T Aring -120 +KPX T Atilde -120 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -120 +KPX T aacute -120 +KPX T abreve -60 +KPX T acircumflex -120 +KPX T adieresis -120 +KPX T agrave -120 +KPX T amacron -60 +KPX T aogonek -120 +KPX T aring -120 +KPX T atilde -60 +KPX T colon -20 +KPX T comma -120 +KPX T e -120 +KPX T eacute -120 +KPX T ecaron -120 +KPX T ecircumflex -120 +KPX T edieresis -120 +KPX T edotaccent -120 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -120 +KPX T hyphen -140 +KPX T o -120 +KPX T oacute -120 +KPX T ocircumflex -120 +KPX T odieresis -120 +KPX T ograve -120 +KPX T ohungarumlaut -120 +KPX T omacron -60 +KPX T oslash -120 +KPX T otilde -60 +KPX T period -120 +KPX T r -120 +KPX T racute -120 +KPX T rcaron -120 +KPX T rcommaaccent -120 +KPX T semicolon -20 +KPX T u -120 +KPX T uacute -120 +KPX T ucircumflex -120 +KPX T udieresis -120 +KPX T ugrave -120 +KPX T uhungarumlaut -120 +KPX T umacron -60 +KPX T uogonek -120 +KPX T uring -120 +KPX T w -120 +KPX T y -120 +KPX T yacute -120 +KPX T ydieresis -60 +KPX Tcaron A -120 +KPX Tcaron Aacute -120 +KPX Tcaron Abreve -120 +KPX Tcaron Acircumflex -120 +KPX Tcaron Adieresis -120 +KPX Tcaron Agrave -120 +KPX Tcaron Amacron -120 +KPX Tcaron Aogonek -120 +KPX Tcaron Aring -120 +KPX Tcaron Atilde -120 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -120 +KPX Tcaron aacute -120 +KPX Tcaron abreve -60 +KPX Tcaron acircumflex -120 +KPX Tcaron adieresis -120 +KPX Tcaron agrave -120 +KPX Tcaron amacron -60 +KPX Tcaron aogonek -120 +KPX Tcaron aring -120 +KPX Tcaron atilde -60 +KPX Tcaron colon -20 +KPX Tcaron comma -120 +KPX Tcaron e -120 +KPX Tcaron eacute -120 +KPX Tcaron ecaron -120 +KPX Tcaron ecircumflex -120 +KPX Tcaron edieresis -120 +KPX Tcaron edotaccent -120 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -120 +KPX Tcaron hyphen -140 +KPX Tcaron o -120 +KPX Tcaron oacute -120 +KPX Tcaron ocircumflex -120 +KPX Tcaron odieresis -120 +KPX Tcaron ograve -120 +KPX Tcaron ohungarumlaut -120 +KPX Tcaron omacron -60 +KPX Tcaron oslash -120 +KPX Tcaron otilde -60 +KPX Tcaron period -120 +KPX Tcaron r -120 +KPX Tcaron racute -120 +KPX Tcaron rcaron -120 +KPX Tcaron rcommaaccent -120 +KPX Tcaron semicolon -20 +KPX Tcaron u -120 +KPX Tcaron uacute -120 +KPX Tcaron ucircumflex -120 +KPX Tcaron udieresis -120 +KPX Tcaron ugrave -120 +KPX Tcaron uhungarumlaut -120 +KPX Tcaron umacron -60 +KPX Tcaron uogonek -120 +KPX Tcaron uring -120 +KPX Tcaron w -120 +KPX Tcaron y -120 +KPX Tcaron yacute -120 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -120 +KPX Tcommaaccent Aacute -120 +KPX Tcommaaccent Abreve -120 +KPX Tcommaaccent Acircumflex -120 +KPX Tcommaaccent Adieresis -120 +KPX Tcommaaccent Agrave -120 +KPX Tcommaaccent Amacron -120 +KPX Tcommaaccent Aogonek -120 +KPX Tcommaaccent Aring -120 +KPX Tcommaaccent Atilde -120 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -120 +KPX Tcommaaccent aacute -120 +KPX Tcommaaccent abreve -60 +KPX Tcommaaccent acircumflex -120 +KPX Tcommaaccent adieresis -120 +KPX Tcommaaccent agrave -120 +KPX Tcommaaccent amacron -60 +KPX Tcommaaccent aogonek -120 +KPX Tcommaaccent aring -120 +KPX Tcommaaccent atilde -60 +KPX Tcommaaccent colon -20 +KPX Tcommaaccent comma -120 +KPX Tcommaaccent e -120 +KPX Tcommaaccent eacute -120 +KPX Tcommaaccent ecaron -120 +KPX Tcommaaccent ecircumflex -120 +KPX Tcommaaccent edieresis -120 +KPX Tcommaaccent edotaccent -120 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -120 +KPX Tcommaaccent hyphen -140 +KPX Tcommaaccent o -120 +KPX Tcommaaccent oacute -120 +KPX Tcommaaccent ocircumflex -120 +KPX Tcommaaccent odieresis -120 +KPX Tcommaaccent ograve -120 +KPX Tcommaaccent ohungarumlaut -120 +KPX Tcommaaccent omacron -60 +KPX Tcommaaccent oslash -120 +KPX Tcommaaccent otilde -60 +KPX Tcommaaccent period -120 +KPX Tcommaaccent r -120 +KPX Tcommaaccent racute -120 +KPX Tcommaaccent rcaron -120 +KPX Tcommaaccent rcommaaccent -120 +KPX Tcommaaccent semicolon -20 +KPX Tcommaaccent u -120 +KPX Tcommaaccent uacute -120 +KPX Tcommaaccent ucircumflex -120 +KPX Tcommaaccent udieresis -120 +KPX Tcommaaccent ugrave -120 +KPX Tcommaaccent uhungarumlaut -120 +KPX Tcommaaccent umacron -60 +KPX Tcommaaccent uogonek -120 +KPX Tcommaaccent uring -120 +KPX Tcommaaccent w -120 +KPX Tcommaaccent y -120 +KPX Tcommaaccent yacute -120 +KPX Tcommaaccent ydieresis -60 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -40 +KPX U period -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -40 +KPX Uacute period -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -40 +KPX Ucircumflex period -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -40 +KPX Udieresis period -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -40 +KPX Ugrave period -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -40 +KPX Uhungarumlaut period -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -40 +KPX Umacron period -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -40 +KPX Uogonek period -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -40 +KPX Uring period -40 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -40 +KPX V Gbreve -40 +KPX V Gcommaaccent -40 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -70 +KPX V aacute -70 +KPX V abreve -70 +KPX V acircumflex -70 +KPX V adieresis -70 +KPX V agrave -70 +KPX V amacron -70 +KPX V aogonek -70 +KPX V aring -70 +KPX V atilde -70 +KPX V colon -40 +KPX V comma -125 +KPX V e -80 +KPX V eacute -80 +KPX V ecaron -80 +KPX V ecircumflex -80 +KPX V edieresis -80 +KPX V edotaccent -80 +KPX V egrave -80 +KPX V emacron -80 +KPX V eogonek -80 +KPX V hyphen -80 +KPX V o -80 +KPX V oacute -80 +KPX V ocircumflex -80 +KPX V odieresis -80 +KPX V ograve -80 +KPX V ohungarumlaut -80 +KPX V omacron -80 +KPX V oslash -80 +KPX V otilde -80 +KPX V period -125 +KPX V semicolon -40 +KPX V u -70 +KPX V uacute -70 +KPX V ucircumflex -70 +KPX V udieresis -70 +KPX V ugrave -70 +KPX V uhungarumlaut -70 +KPX V umacron -70 +KPX V uogonek -70 +KPX V uring -70 +KPX W A -50 +KPX W Aacute -50 +KPX W Abreve -50 +KPX W Acircumflex -50 +KPX W Adieresis -50 +KPX W Agrave -50 +KPX W Amacron -50 +KPX W Aogonek -50 +KPX W Aring -50 +KPX W Atilde -50 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W comma -80 +KPX W e -30 +KPX W eacute -30 +KPX W ecaron -30 +KPX W ecircumflex -30 +KPX W edieresis -30 +KPX W edotaccent -30 +KPX W egrave -30 +KPX W emacron -30 +KPX W eogonek -30 +KPX W hyphen -40 +KPX W o -30 +KPX W oacute -30 +KPX W ocircumflex -30 +KPX W odieresis -30 +KPX W ograve -30 +KPX W ohungarumlaut -30 +KPX W omacron -30 +KPX W oslash -30 +KPX W otilde -30 +KPX W period -80 +KPX W u -30 +KPX W uacute -30 +KPX W ucircumflex -30 +KPX W udieresis -30 +KPX W ugrave -30 +KPX W uhungarumlaut -30 +KPX W umacron -30 +KPX W uogonek -30 +KPX W uring -30 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -85 +KPX Y Oacute -85 +KPX Y Ocircumflex -85 +KPX Y Odieresis -85 +KPX Y Ograve -85 +KPX Y Ohungarumlaut -85 +KPX Y Omacron -85 +KPX Y Oslash -85 +KPX Y Otilde -85 +KPX Y a -140 +KPX Y aacute -140 +KPX Y abreve -70 +KPX Y acircumflex -140 +KPX Y adieresis -140 +KPX Y agrave -140 +KPX Y amacron -70 +KPX Y aogonek -140 +KPX Y aring -140 +KPX Y atilde -140 +KPX Y colon -60 +KPX Y comma -140 +KPX Y e -140 +KPX Y eacute -140 +KPX Y ecaron -140 +KPX Y ecircumflex -140 +KPX Y edieresis -140 +KPX Y edotaccent -140 +KPX Y egrave -140 +KPX Y emacron -70 +KPX Y eogonek -140 +KPX Y hyphen -140 +KPX Y i -20 +KPX Y iacute -20 +KPX Y iogonek -20 +KPX Y o -140 +KPX Y oacute -140 +KPX Y ocircumflex -140 +KPX Y odieresis -140 +KPX Y ograve -140 +KPX Y ohungarumlaut -140 +KPX Y omacron -140 +KPX Y oslash -140 +KPX Y otilde -140 +KPX Y period -140 +KPX Y semicolon -60 +KPX Y u -110 +KPX Y uacute -110 +KPX Y ucircumflex -110 +KPX Y udieresis -110 +KPX Y ugrave -110 +KPX Y uhungarumlaut -110 +KPX Y umacron -110 +KPX Y uogonek -110 +KPX Y uring -110 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -85 +KPX Yacute Oacute -85 +KPX Yacute Ocircumflex -85 +KPX Yacute Odieresis -85 +KPX Yacute Ograve -85 +KPX Yacute Ohungarumlaut -85 +KPX Yacute Omacron -85 +KPX Yacute Oslash -85 +KPX Yacute Otilde -85 +KPX Yacute a -140 +KPX Yacute aacute -140 +KPX Yacute abreve -70 +KPX Yacute acircumflex -140 +KPX Yacute adieresis -140 +KPX Yacute agrave -140 +KPX Yacute amacron -70 +KPX Yacute aogonek -140 +KPX Yacute aring -140 +KPX Yacute atilde -70 +KPX Yacute colon -60 +KPX Yacute comma -140 +KPX Yacute e -140 +KPX Yacute eacute -140 +KPX Yacute ecaron -140 +KPX Yacute ecircumflex -140 +KPX Yacute edieresis -140 +KPX Yacute edotaccent -140 +KPX Yacute egrave -140 +KPX Yacute emacron -70 +KPX Yacute eogonek -140 +KPX Yacute hyphen -140 +KPX Yacute i -20 +KPX Yacute iacute -20 +KPX Yacute iogonek -20 +KPX Yacute o -140 +KPX Yacute oacute -140 +KPX Yacute ocircumflex -140 +KPX Yacute odieresis -140 +KPX Yacute ograve -140 +KPX Yacute ohungarumlaut -140 +KPX Yacute omacron -70 +KPX Yacute oslash -140 +KPX Yacute otilde -140 +KPX Yacute period -140 +KPX Yacute semicolon -60 +KPX Yacute u -110 +KPX Yacute uacute -110 +KPX Yacute ucircumflex -110 +KPX Yacute udieresis -110 +KPX Yacute ugrave -110 +KPX Yacute uhungarumlaut -110 +KPX Yacute umacron -110 +KPX Yacute uogonek -110 +KPX Yacute uring -110 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -85 +KPX Ydieresis Oacute -85 +KPX Ydieresis Ocircumflex -85 +KPX Ydieresis Odieresis -85 +KPX Ydieresis Ograve -85 +KPX Ydieresis Ohungarumlaut -85 +KPX Ydieresis Omacron -85 +KPX Ydieresis Oslash -85 +KPX Ydieresis Otilde -85 +KPX Ydieresis a -140 +KPX Ydieresis aacute -140 +KPX Ydieresis abreve -70 +KPX Ydieresis acircumflex -140 +KPX Ydieresis adieresis -140 +KPX Ydieresis agrave -140 +KPX Ydieresis amacron -70 +KPX Ydieresis aogonek -140 +KPX Ydieresis aring -140 +KPX Ydieresis atilde -70 +KPX Ydieresis colon -60 +KPX Ydieresis comma -140 +KPX Ydieresis e -140 +KPX Ydieresis eacute -140 +KPX Ydieresis ecaron -140 +KPX Ydieresis ecircumflex -140 +KPX Ydieresis edieresis -140 +KPX Ydieresis edotaccent -140 +KPX Ydieresis egrave -140 +KPX Ydieresis emacron -70 +KPX Ydieresis eogonek -140 +KPX Ydieresis hyphen -140 +KPX Ydieresis i -20 +KPX Ydieresis iacute -20 +KPX Ydieresis iogonek -20 +KPX Ydieresis o -140 +KPX Ydieresis oacute -140 +KPX Ydieresis ocircumflex -140 +KPX Ydieresis odieresis -140 +KPX Ydieresis ograve -140 +KPX Ydieresis ohungarumlaut -140 +KPX Ydieresis omacron -140 +KPX Ydieresis oslash -140 +KPX Ydieresis otilde -140 +KPX Ydieresis period -140 +KPX Ydieresis semicolon -60 +KPX Ydieresis u -110 +KPX Ydieresis uacute -110 +KPX Ydieresis ucircumflex -110 +KPX Ydieresis udieresis -110 +KPX Ydieresis ugrave -110 +KPX Ydieresis uhungarumlaut -110 +KPX Ydieresis umacron -110 +KPX Ydieresis uogonek -110 +KPX Ydieresis uring -110 +KPX a v -20 +KPX a w -20 +KPX a y -30 +KPX a yacute -30 +KPX a ydieresis -30 +KPX aacute v -20 +KPX aacute w -20 +KPX aacute y -30 +KPX aacute yacute -30 +KPX aacute ydieresis -30 +KPX abreve v -20 +KPX abreve w -20 +KPX abreve y -30 +KPX abreve yacute -30 +KPX abreve ydieresis -30 +KPX acircumflex v -20 +KPX acircumflex w -20 +KPX acircumflex y -30 +KPX acircumflex yacute -30 +KPX acircumflex ydieresis -30 +KPX adieresis v -20 +KPX adieresis w -20 +KPX adieresis y -30 +KPX adieresis yacute -30 +KPX adieresis ydieresis -30 +KPX agrave v -20 +KPX agrave w -20 +KPX agrave y -30 +KPX agrave yacute -30 +KPX agrave ydieresis -30 +KPX amacron v -20 +KPX amacron w -20 +KPX amacron y -30 +KPX amacron yacute -30 +KPX amacron ydieresis -30 +KPX aogonek v -20 +KPX aogonek w -20 +KPX aogonek y -30 +KPX aogonek yacute -30 +KPX aogonek ydieresis -30 +KPX aring v -20 +KPX aring w -20 +KPX aring y -30 +KPX aring yacute -30 +KPX aring ydieresis -30 +KPX atilde v -20 +KPX atilde w -20 +KPX atilde y -30 +KPX atilde yacute -30 +KPX atilde ydieresis -30 +KPX b b -10 +KPX b comma -40 +KPX b l -20 +KPX b lacute -20 +KPX b lcommaaccent -20 +KPX b lslash -20 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c comma -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute comma -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron comma -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla comma -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX colon space -50 +KPX comma quotedblright -100 +KPX comma quoteright -100 +KPX e comma -15 +KPX e period -15 +KPX e v -30 +KPX e w -20 +KPX e x -30 +KPX e y -20 +KPX e yacute -20 +KPX e ydieresis -20 +KPX eacute comma -15 +KPX eacute period -15 +KPX eacute v -30 +KPX eacute w -20 +KPX eacute x -30 +KPX eacute y -20 +KPX eacute yacute -20 +KPX eacute ydieresis -20 +KPX ecaron comma -15 +KPX ecaron period -15 +KPX ecaron v -30 +KPX ecaron w -20 +KPX ecaron x -30 +KPX ecaron y -20 +KPX ecaron yacute -20 +KPX ecaron ydieresis -20 +KPX ecircumflex comma -15 +KPX ecircumflex period -15 +KPX ecircumflex v -30 +KPX ecircumflex w -20 +KPX ecircumflex x -30 +KPX ecircumflex y -20 +KPX ecircumflex yacute -20 +KPX ecircumflex ydieresis -20 +KPX edieresis comma -15 +KPX edieresis period -15 +KPX edieresis v -30 +KPX edieresis w -20 +KPX edieresis x -30 +KPX edieresis y -20 +KPX edieresis yacute -20 +KPX edieresis ydieresis -20 +KPX edotaccent comma -15 +KPX edotaccent period -15 +KPX edotaccent v -30 +KPX edotaccent w -20 +KPX edotaccent x -30 +KPX edotaccent y -20 +KPX edotaccent yacute -20 +KPX edotaccent ydieresis -20 +KPX egrave comma -15 +KPX egrave period -15 +KPX egrave v -30 +KPX egrave w -20 +KPX egrave x -30 +KPX egrave y -20 +KPX egrave yacute -20 +KPX egrave ydieresis -20 +KPX emacron comma -15 +KPX emacron period -15 +KPX emacron v -30 +KPX emacron w -20 +KPX emacron x -30 +KPX emacron y -20 +KPX emacron yacute -20 +KPX emacron ydieresis -20 +KPX eogonek comma -15 +KPX eogonek period -15 +KPX eogonek v -30 +KPX eogonek w -20 +KPX eogonek x -30 +KPX eogonek y -20 +KPX eogonek yacute -20 +KPX eogonek ydieresis -20 +KPX f a -30 +KPX f aacute -30 +KPX f abreve -30 +KPX f acircumflex -30 +KPX f adieresis -30 +KPX f agrave -30 +KPX f amacron -30 +KPX f aogonek -30 +KPX f aring -30 +KPX f atilde -30 +KPX f comma -30 +KPX f dotlessi -28 +KPX f e -30 +KPX f eacute -30 +KPX f ecaron -30 +KPX f ecircumflex -30 +KPX f edieresis -30 +KPX f edotaccent -30 +KPX f egrave -30 +KPX f emacron -30 +KPX f eogonek -30 +KPX f o -30 +KPX f oacute -30 +KPX f ocircumflex -30 +KPX f odieresis -30 +KPX f ograve -30 +KPX f ohungarumlaut -30 +KPX f omacron -30 +KPX f oslash -30 +KPX f otilde -30 +KPX f period -30 +KPX f quotedblright 60 +KPX f quoteright 50 +KPX g r -10 +KPX g racute -10 +KPX g rcaron -10 +KPX g rcommaaccent -10 +KPX gbreve r -10 +KPX gbreve racute -10 +KPX gbreve rcaron -10 +KPX gbreve rcommaaccent -10 +KPX gcommaaccent r -10 +KPX gcommaaccent racute -10 +KPX gcommaaccent rcaron -10 +KPX gcommaaccent rcommaaccent -10 +KPX h y -30 +KPX h yacute -30 +KPX h ydieresis -30 +KPX k e -20 +KPX k eacute -20 +KPX k ecaron -20 +KPX k ecircumflex -20 +KPX k edieresis -20 +KPX k edotaccent -20 +KPX k egrave -20 +KPX k emacron -20 +KPX k eogonek -20 +KPX k o -20 +KPX k oacute -20 +KPX k ocircumflex -20 +KPX k odieresis -20 +KPX k ograve -20 +KPX k ohungarumlaut -20 +KPX k omacron -20 +KPX k oslash -20 +KPX k otilde -20 +KPX kcommaaccent e -20 +KPX kcommaaccent eacute -20 +KPX kcommaaccent ecaron -20 +KPX kcommaaccent ecircumflex -20 +KPX kcommaaccent edieresis -20 +KPX kcommaaccent edotaccent -20 +KPX kcommaaccent egrave -20 +KPX kcommaaccent emacron -20 +KPX kcommaaccent eogonek -20 +KPX kcommaaccent o -20 +KPX kcommaaccent oacute -20 +KPX kcommaaccent ocircumflex -20 +KPX kcommaaccent odieresis -20 +KPX kcommaaccent ograve -20 +KPX kcommaaccent ohungarumlaut -20 +KPX kcommaaccent omacron -20 +KPX kcommaaccent oslash -20 +KPX kcommaaccent otilde -20 +KPX m u -10 +KPX m uacute -10 +KPX m ucircumflex -10 +KPX m udieresis -10 +KPX m ugrave -10 +KPX m uhungarumlaut -10 +KPX m umacron -10 +KPX m uogonek -10 +KPX m uring -10 +KPX m y -15 +KPX m yacute -15 +KPX m ydieresis -15 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -20 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -20 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -20 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -20 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -20 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o comma -40 +KPX o period -40 +KPX o v -15 +KPX o w -15 +KPX o x -30 +KPX o y -30 +KPX o yacute -30 +KPX o ydieresis -30 +KPX oacute comma -40 +KPX oacute period -40 +KPX oacute v -15 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -30 +KPX oacute yacute -30 +KPX oacute ydieresis -30 +KPX ocircumflex comma -40 +KPX ocircumflex period -40 +KPX ocircumflex v -15 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -30 +KPX ocircumflex yacute -30 +KPX ocircumflex ydieresis -30 +KPX odieresis comma -40 +KPX odieresis period -40 +KPX odieresis v -15 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -30 +KPX odieresis yacute -30 +KPX odieresis ydieresis -30 +KPX ograve comma -40 +KPX ograve period -40 +KPX ograve v -15 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -30 +KPX ograve yacute -30 +KPX ograve ydieresis -30 +KPX ohungarumlaut comma -40 +KPX ohungarumlaut period -40 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -30 +KPX ohungarumlaut yacute -30 +KPX ohungarumlaut ydieresis -30 +KPX omacron comma -40 +KPX omacron period -40 +KPX omacron v -15 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -30 +KPX omacron yacute -30 +KPX omacron ydieresis -30 +KPX oslash a -55 +KPX oslash aacute -55 +KPX oslash abreve -55 +KPX oslash acircumflex -55 +KPX oslash adieresis -55 +KPX oslash agrave -55 +KPX oslash amacron -55 +KPX oslash aogonek -55 +KPX oslash aring -55 +KPX oslash atilde -55 +KPX oslash b -55 +KPX oslash c -55 +KPX oslash cacute -55 +KPX oslash ccaron -55 +KPX oslash ccedilla -55 +KPX oslash comma -95 +KPX oslash d -55 +KPX oslash dcroat -55 +KPX oslash e -55 +KPX oslash eacute -55 +KPX oslash ecaron -55 +KPX oslash ecircumflex -55 +KPX oslash edieresis -55 +KPX oslash edotaccent -55 +KPX oslash egrave -55 +KPX oslash emacron -55 +KPX oslash eogonek -55 +KPX oslash f -55 +KPX oslash g -55 +KPX oslash gbreve -55 +KPX oslash gcommaaccent -55 +KPX oslash h -55 +KPX oslash i -55 +KPX oslash iacute -55 +KPX oslash icircumflex -55 +KPX oslash idieresis -55 +KPX oslash igrave -55 +KPX oslash imacron -55 +KPX oslash iogonek -55 +KPX oslash j -55 +KPX oslash k -55 +KPX oslash kcommaaccent -55 +KPX oslash l -55 +KPX oslash lacute -55 +KPX oslash lcommaaccent -55 +KPX oslash lslash -55 +KPX oslash m -55 +KPX oslash n -55 +KPX oslash nacute -55 +KPX oslash ncaron -55 +KPX oslash ncommaaccent -55 +KPX oslash ntilde -55 +KPX oslash o -55 +KPX oslash oacute -55 +KPX oslash ocircumflex -55 +KPX oslash odieresis -55 +KPX oslash ograve -55 +KPX oslash ohungarumlaut -55 +KPX oslash omacron -55 +KPX oslash oslash -55 +KPX oslash otilde -55 +KPX oslash p -55 +KPX oslash period -95 +KPX oslash q -55 +KPX oslash r -55 +KPX oslash racute -55 +KPX oslash rcaron -55 +KPX oslash rcommaaccent -55 +KPX oslash s -55 +KPX oslash sacute -55 +KPX oslash scaron -55 +KPX oslash scedilla -55 +KPX oslash scommaaccent -55 +KPX oslash t -55 +KPX oslash tcommaaccent -55 +KPX oslash u -55 +KPX oslash uacute -55 +KPX oslash ucircumflex -55 +KPX oslash udieresis -55 +KPX oslash ugrave -55 +KPX oslash uhungarumlaut -55 +KPX oslash umacron -55 +KPX oslash uogonek -55 +KPX oslash uring -55 +KPX oslash v -70 +KPX oslash w -70 +KPX oslash x -85 +KPX oslash y -70 +KPX oslash yacute -70 +KPX oslash ydieresis -70 +KPX oslash z -55 +KPX oslash zacute -55 +KPX oslash zcaron -55 +KPX oslash zdotaccent -55 +KPX otilde comma -40 +KPX otilde period -40 +KPX otilde v -15 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -30 +KPX otilde yacute -30 +KPX otilde ydieresis -30 +KPX p comma -35 +KPX p period -35 +KPX p y -30 +KPX p yacute -30 +KPX p ydieresis -30 +KPX period quotedblright -100 +KPX period quoteright -100 +KPX period space -60 +KPX quotedblright space -40 +KPX quoteleft quoteleft -57 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright quoteright -57 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -50 +KPX quoteright sacute -50 +KPX quoteright scaron -50 +KPX quoteright scedilla -50 +KPX quoteright scommaaccent -50 +KPX quoteright space -70 +KPX r a -10 +KPX r aacute -10 +KPX r abreve -10 +KPX r acircumflex -10 +KPX r adieresis -10 +KPX r agrave -10 +KPX r amacron -10 +KPX r aogonek -10 +KPX r aring -10 +KPX r atilde -10 +KPX r colon 30 +KPX r comma -50 +KPX r i 15 +KPX r iacute 15 +KPX r icircumflex 15 +KPX r idieresis 15 +KPX r igrave 15 +KPX r imacron 15 +KPX r iogonek 15 +KPX r k 15 +KPX r kcommaaccent 15 +KPX r l 15 +KPX r lacute 15 +KPX r lcommaaccent 15 +KPX r lslash 15 +KPX r m 25 +KPX r n 25 +KPX r nacute 25 +KPX r ncaron 25 +KPX r ncommaaccent 25 +KPX r ntilde 25 +KPX r p 30 +KPX r period -50 +KPX r semicolon 30 +KPX r t 40 +KPX r tcommaaccent 40 +KPX r u 15 +KPX r uacute 15 +KPX r ucircumflex 15 +KPX r udieresis 15 +KPX r ugrave 15 +KPX r uhungarumlaut 15 +KPX r umacron 15 +KPX r uogonek 15 +KPX r uring 15 +KPX r v 30 +KPX r y 30 +KPX r yacute 30 +KPX r ydieresis 30 +KPX racute a -10 +KPX racute aacute -10 +KPX racute abreve -10 +KPX racute acircumflex -10 +KPX racute adieresis -10 +KPX racute agrave -10 +KPX racute amacron -10 +KPX racute aogonek -10 +KPX racute aring -10 +KPX racute atilde -10 +KPX racute colon 30 +KPX racute comma -50 +KPX racute i 15 +KPX racute iacute 15 +KPX racute icircumflex 15 +KPX racute idieresis 15 +KPX racute igrave 15 +KPX racute imacron 15 +KPX racute iogonek 15 +KPX racute k 15 +KPX racute kcommaaccent 15 +KPX racute l 15 +KPX racute lacute 15 +KPX racute lcommaaccent 15 +KPX racute lslash 15 +KPX racute m 25 +KPX racute n 25 +KPX racute nacute 25 +KPX racute ncaron 25 +KPX racute ncommaaccent 25 +KPX racute ntilde 25 +KPX racute p 30 +KPX racute period -50 +KPX racute semicolon 30 +KPX racute t 40 +KPX racute tcommaaccent 40 +KPX racute u 15 +KPX racute uacute 15 +KPX racute ucircumflex 15 +KPX racute udieresis 15 +KPX racute ugrave 15 +KPX racute uhungarumlaut 15 +KPX racute umacron 15 +KPX racute uogonek 15 +KPX racute uring 15 +KPX racute v 30 +KPX racute y 30 +KPX racute yacute 30 +KPX racute ydieresis 30 +KPX rcaron a -10 +KPX rcaron aacute -10 +KPX rcaron abreve -10 +KPX rcaron acircumflex -10 +KPX rcaron adieresis -10 +KPX rcaron agrave -10 +KPX rcaron amacron -10 +KPX rcaron aogonek -10 +KPX rcaron aring -10 +KPX rcaron atilde -10 +KPX rcaron colon 30 +KPX rcaron comma -50 +KPX rcaron i 15 +KPX rcaron iacute 15 +KPX rcaron icircumflex 15 +KPX rcaron idieresis 15 +KPX rcaron igrave 15 +KPX rcaron imacron 15 +KPX rcaron iogonek 15 +KPX rcaron k 15 +KPX rcaron kcommaaccent 15 +KPX rcaron l 15 +KPX rcaron lacute 15 +KPX rcaron lcommaaccent 15 +KPX rcaron lslash 15 +KPX rcaron m 25 +KPX rcaron n 25 +KPX rcaron nacute 25 +KPX rcaron ncaron 25 +KPX rcaron ncommaaccent 25 +KPX rcaron ntilde 25 +KPX rcaron p 30 +KPX rcaron period -50 +KPX rcaron semicolon 30 +KPX rcaron t 40 +KPX rcaron tcommaaccent 40 +KPX rcaron u 15 +KPX rcaron uacute 15 +KPX rcaron ucircumflex 15 +KPX rcaron udieresis 15 +KPX rcaron ugrave 15 +KPX rcaron uhungarumlaut 15 +KPX rcaron umacron 15 +KPX rcaron uogonek 15 +KPX rcaron uring 15 +KPX rcaron v 30 +KPX rcaron y 30 +KPX rcaron yacute 30 +KPX rcaron ydieresis 30 +KPX rcommaaccent a -10 +KPX rcommaaccent aacute -10 +KPX rcommaaccent abreve -10 +KPX rcommaaccent acircumflex -10 +KPX rcommaaccent adieresis -10 +KPX rcommaaccent agrave -10 +KPX rcommaaccent amacron -10 +KPX rcommaaccent aogonek -10 +KPX rcommaaccent aring -10 +KPX rcommaaccent atilde -10 +KPX rcommaaccent colon 30 +KPX rcommaaccent comma -50 +KPX rcommaaccent i 15 +KPX rcommaaccent iacute 15 +KPX rcommaaccent icircumflex 15 +KPX rcommaaccent idieresis 15 +KPX rcommaaccent igrave 15 +KPX rcommaaccent imacron 15 +KPX rcommaaccent iogonek 15 +KPX rcommaaccent k 15 +KPX rcommaaccent kcommaaccent 15 +KPX rcommaaccent l 15 +KPX rcommaaccent lacute 15 +KPX rcommaaccent lcommaaccent 15 +KPX rcommaaccent lslash 15 +KPX rcommaaccent m 25 +KPX rcommaaccent n 25 +KPX rcommaaccent nacute 25 +KPX rcommaaccent ncaron 25 +KPX rcommaaccent ncommaaccent 25 +KPX rcommaaccent ntilde 25 +KPX rcommaaccent p 30 +KPX rcommaaccent period -50 +KPX rcommaaccent semicolon 30 +KPX rcommaaccent t 40 +KPX rcommaaccent tcommaaccent 40 +KPX rcommaaccent u 15 +KPX rcommaaccent uacute 15 +KPX rcommaaccent ucircumflex 15 +KPX rcommaaccent udieresis 15 +KPX rcommaaccent ugrave 15 +KPX rcommaaccent uhungarumlaut 15 +KPX rcommaaccent umacron 15 +KPX rcommaaccent uogonek 15 +KPX rcommaaccent uring 15 +KPX rcommaaccent v 30 +KPX rcommaaccent y 30 +KPX rcommaaccent yacute 30 +KPX rcommaaccent ydieresis 30 +KPX s comma -15 +KPX s period -15 +KPX s w -30 +KPX sacute comma -15 +KPX sacute period -15 +KPX sacute w -30 +KPX scaron comma -15 +KPX scaron period -15 +KPX scaron w -30 +KPX scedilla comma -15 +KPX scedilla period -15 +KPX scedilla w -30 +KPX scommaaccent comma -15 +KPX scommaaccent period -15 +KPX scommaaccent w -30 +KPX semicolon space -50 +KPX space T -50 +KPX space Tcaron -50 +KPX space Tcommaaccent -50 +KPX space V -50 +KPX space W -40 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX space quotedblleft -30 +KPX space quoteleft -60 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -80 +KPX v e -25 +KPX v eacute -25 +KPX v ecaron -25 +KPX v ecircumflex -25 +KPX v edieresis -25 +KPX v edotaccent -25 +KPX v egrave -25 +KPX v emacron -25 +KPX v eogonek -25 +KPX v o -25 +KPX v oacute -25 +KPX v ocircumflex -25 +KPX v odieresis -25 +KPX v ograve -25 +KPX v ohungarumlaut -25 +KPX v omacron -25 +KPX v oslash -25 +KPX v otilde -25 +KPX v period -80 +KPX w a -15 +KPX w aacute -15 +KPX w abreve -15 +KPX w acircumflex -15 +KPX w adieresis -15 +KPX w agrave -15 +KPX w amacron -15 +KPX w aogonek -15 +KPX w aring -15 +KPX w atilde -15 +KPX w comma -60 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -60 +KPX x e -30 +KPX x eacute -30 +KPX x ecaron -30 +KPX x ecircumflex -30 +KPX x edieresis -30 +KPX x edotaccent -30 +KPX x egrave -30 +KPX x emacron -30 +KPX x eogonek -30 +KPX y a -20 +KPX y aacute -20 +KPX y abreve -20 +KPX y acircumflex -20 +KPX y adieresis -20 +KPX y agrave -20 +KPX y amacron -20 +KPX y aogonek -20 +KPX y aring -20 +KPX y atilde -20 +KPX y comma -100 +KPX y e -20 +KPX y eacute -20 +KPX y ecaron -20 +KPX y ecircumflex -20 +KPX y edieresis -20 +KPX y edotaccent -20 +KPX y egrave -20 +KPX y emacron -20 +KPX y eogonek -20 +KPX y o -20 +KPX y oacute -20 +KPX y ocircumflex -20 +KPX y odieresis -20 +KPX y ograve -20 +KPX y ohungarumlaut -20 +KPX y omacron -20 +KPX y oslash -20 +KPX y otilde -20 +KPX y period -100 +KPX yacute a -20 +KPX yacute aacute -20 +KPX yacute abreve -20 +KPX yacute acircumflex -20 +KPX yacute adieresis -20 +KPX yacute agrave -20 +KPX yacute amacron -20 +KPX yacute aogonek -20 +KPX yacute aring -20 +KPX yacute atilde -20 +KPX yacute comma -100 +KPX yacute e -20 +KPX yacute eacute -20 +KPX yacute ecaron -20 +KPX yacute ecircumflex -20 +KPX yacute edieresis -20 +KPX yacute edotaccent -20 +KPX yacute egrave -20 +KPX yacute emacron -20 +KPX yacute eogonek -20 +KPX yacute o -20 +KPX yacute oacute -20 +KPX yacute ocircumflex -20 +KPX yacute odieresis -20 +KPX yacute ograve -20 +KPX yacute ohungarumlaut -20 +KPX yacute omacron -20 +KPX yacute oslash -20 +KPX yacute otilde -20 +KPX yacute period -100 +KPX ydieresis a -20 +KPX ydieresis aacute -20 +KPX ydieresis abreve -20 +KPX ydieresis acircumflex -20 +KPX ydieresis adieresis -20 +KPX ydieresis agrave -20 +KPX ydieresis amacron -20 +KPX ydieresis aogonek -20 +KPX ydieresis aring -20 +KPX ydieresis atilde -20 +KPX ydieresis comma -100 +KPX ydieresis e -20 +KPX ydieresis eacute -20 +KPX ydieresis ecaron -20 +KPX ydieresis ecircumflex -20 +KPX ydieresis edieresis -20 +KPX ydieresis edotaccent -20 +KPX ydieresis egrave -20 +KPX ydieresis emacron -20 +KPX ydieresis eogonek -20 +KPX ydieresis o -20 +KPX ydieresis oacute -20 +KPX ydieresis ocircumflex -20 +KPX ydieresis odieresis -20 +KPX ydieresis ograve -20 +KPX ydieresis ohungarumlaut -20 +KPX ydieresis omacron -20 +KPX ydieresis oslash -20 +KPX ydieresis otilde -20 +KPX ydieresis period -100 +KPX z e -15 +KPX z eacute -15 +KPX z ecaron -15 +KPX z ecircumflex -15 +KPX z edieresis -15 +KPX z edotaccent -15 +KPX z egrave -15 +KPX z emacron -15 +KPX z eogonek -15 +KPX z o -15 +KPX z oacute -15 +KPX z ocircumflex -15 +KPX z odieresis -15 +KPX z ograve -15 +KPX z ohungarumlaut -15 +KPX z omacron -15 +KPX z oslash -15 +KPX z otilde -15 +KPX zacute e -15 +KPX zacute eacute -15 +KPX zacute ecaron -15 +KPX zacute ecircumflex -15 +KPX zacute edieresis -15 +KPX zacute edotaccent -15 +KPX zacute egrave -15 +KPX zacute emacron -15 +KPX zacute eogonek -15 +KPX zacute o -15 +KPX zacute oacute -15 +KPX zacute ocircumflex -15 +KPX zacute odieresis -15 +KPX zacute ograve -15 +KPX zacute ohungarumlaut -15 +KPX zacute omacron -15 +KPX zacute oslash -15 +KPX zacute otilde -15 +KPX zcaron e -15 +KPX zcaron eacute -15 +KPX zcaron ecaron -15 +KPX zcaron ecircumflex -15 +KPX zcaron edieresis -15 +KPX zcaron edotaccent -15 +KPX zcaron egrave -15 +KPX zcaron emacron -15 +KPX zcaron eogonek -15 +KPX zcaron o -15 +KPX zcaron oacute -15 +KPX zcaron ocircumflex -15 +KPX zcaron odieresis -15 +KPX zcaron ograve -15 +KPX zcaron ohungarumlaut -15 +KPX zcaron omacron -15 +KPX zcaron oslash -15 +KPX zcaron otilde -15 +KPX zdotaccent e -15 +KPX zdotaccent eacute -15 +KPX zdotaccent ecaron -15 +KPX zdotaccent ecircumflex -15 +KPX zdotaccent edieresis -15 +KPX zdotaccent edotaccent -15 +KPX zdotaccent egrave -15 +KPX zdotaccent emacron -15 +KPX zdotaccent eogonek -15 +KPX zdotaccent o -15 +KPX zdotaccent oacute -15 +KPX zdotaccent ocircumflex -15 +KPX zdotaccent odieresis -15 +KPX zdotaccent ograve -15 +KPX zdotaccent ohungarumlaut -15 +KPX zdotaccent omacron -15 +KPX zdotaccent oslash -15 +KPX zdotaccent otilde -15 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm new file mode 100644 index 00000000..bd32af54 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm @@ -0,0 +1,3051 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:38:23 1997 +Comment UniqueID 43054 +Comment VMusage 37069 48094 +FontName Helvetica +FullName Helvetica +FamilyName Helvetica +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -166 -225 1000 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StdHW 76 +StdVW 88 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ; +C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ; +C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ; +C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ; +C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ; +C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ; +C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; +C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ; +C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ; +C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ; +C 43 ; WX 584 ; N plus ; B 39 0 545 505 ; +C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ; +C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ; +C 46 ; WX 278 ; N period ; B 87 0 191 106 ; +C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ; +C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ; +C 49 ; WX 556 ; N one ; B 101 0 359 703 ; +C 50 ; WX 556 ; N two ; B 26 0 507 703 ; +C 51 ; WX 556 ; N three ; B 34 -19 522 703 ; +C 52 ; WX 556 ; N four ; B 25 0 523 703 ; +C 53 ; WX 556 ; N five ; B 32 -19 514 688 ; +C 54 ; WX 556 ; N six ; B 38 -19 518 703 ; +C 55 ; WX 556 ; N seven ; B 37 0 523 688 ; +C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ; +C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 191 516 ; +C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ; +C 60 ; WX 584 ; N less ; B 48 11 536 495 ; +C 61 ; WX 584 ; N equal ; B 39 115 545 390 ; +C 62 ; WX 584 ; N greater ; B 48 11 536 495 ; +C 63 ; WX 556 ; N question ; B 56 0 492 727 ; +C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 627 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 681 737 ; +C 68 ; WX 722 ; N D ; B 81 0 674 718 ; +C 69 ; WX 667 ; N E ; B 86 0 616 718 ; +C 70 ; WX 611 ; N F ; B 86 0 583 718 ; +C 71 ; WX 778 ; N G ; B 48 -19 704 737 ; +C 72 ; WX 722 ; N H ; B 77 0 646 718 ; +C 73 ; WX 278 ; N I ; B 91 0 188 718 ; +C 74 ; WX 500 ; N J ; B 17 -19 428 718 ; +C 75 ; WX 667 ; N K ; B 76 0 663 718 ; +C 76 ; WX 556 ; N L ; B 76 0 537 718 ; +C 77 ; WX 833 ; N M ; B 73 0 761 718 ; +C 78 ; WX 722 ; N N ; B 76 0 646 718 ; +C 79 ; WX 778 ; N O ; B 39 -19 739 737 ; +C 80 ; WX 667 ; N P ; B 86 0 622 718 ; +C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ; +C 82 ; WX 722 ; N R ; B 88 0 684 718 ; +C 83 ; WX 667 ; N S ; B 49 -19 620 737 ; +C 84 ; WX 611 ; N T ; B 14 0 597 718 ; +C 85 ; WX 722 ; N U ; B 79 -19 644 718 ; +C 86 ; WX 667 ; N V ; B 20 0 647 718 ; +C 87 ; WX 944 ; N W ; B 16 0 928 718 ; +C 88 ; WX 667 ; N X ; B 19 0 648 718 ; +C 89 ; WX 667 ; N Y ; B 14 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 588 718 ; +C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ; +C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ; +C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ; +C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ; +C 97 ; WX 556 ; N a ; B 36 -15 530 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 517 718 ; +C 99 ; WX 500 ; N c ; B 30 -15 477 538 ; +C 100 ; WX 556 ; N d ; B 35 -15 499 718 ; +C 101 ; WX 556 ; N e ; B 40 -15 516 538 ; +C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 40 -220 499 538 ; +C 104 ; WX 556 ; N h ; B 65 0 491 718 ; +C 105 ; WX 222 ; N i ; B 67 0 155 718 ; +C 106 ; WX 222 ; N j ; B -16 -210 155 718 ; +C 107 ; WX 500 ; N k ; B 67 0 501 718 ; +C 108 ; WX 222 ; N l ; B 67 0 155 718 ; +C 109 ; WX 833 ; N m ; B 65 0 769 538 ; +C 110 ; WX 556 ; N n ; B 65 0 491 538 ; +C 111 ; WX 556 ; N o ; B 35 -14 521 538 ; +C 112 ; WX 556 ; N p ; B 58 -207 517 538 ; +C 113 ; WX 556 ; N q ; B 35 -207 494 538 ; +C 114 ; WX 333 ; N r ; B 77 0 332 538 ; +C 115 ; WX 500 ; N s ; B 32 -15 464 538 ; +C 116 ; WX 278 ; N t ; B 14 -7 257 669 ; +C 117 ; WX 556 ; N u ; B 68 -15 489 523 ; +C 118 ; WX 500 ; N v ; B 8 0 492 523 ; +C 119 ; WX 722 ; N w ; B 14 0 709 523 ; +C 120 ; WX 500 ; N x ; B 11 0 490 523 ; +C 121 ; WX 500 ; N y ; B 11 -214 489 523 ; +C 122 ; WX 500 ; N z ; B 31 0 469 523 ; +C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ; +C 124 ; WX 260 ; N bar ; B 94 -225 167 775 ; +C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ; +C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ; +C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ; +C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ; +C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ; +C 165 ; WX 556 ; N yen ; B 3 0 553 688 ; +C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ; +C 167 ; WX 556 ; N section ; B 43 -191 512 737 ; +C 168 ; WX 556 ; N currency ; B 28 99 528 603 ; +C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ; +C 174 ; WX 500 ; N fi ; B 14 0 434 728 ; +C 175 ; WX 500 ; N fl ; B 14 0 432 728 ; +C 177 ; WX 556 ; N endash ; B 0 240 556 313 ; +C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ; +C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ; +C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ; +C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ; +C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ; +C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ; +C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ; +C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ; +C 193 ; WX 333 ; N grave ; B 14 593 211 734 ; +C 194 ; WX 333 ; N acute ; B 122 593 319 734 ; +C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ; +C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ; +C 197 ; WX 333 ; N macron ; B 10 627 323 684 ; +C 198 ; WX 333 ; N breve ; B 13 595 321 731 ; +C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ; +C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ; +C 202 ; WX 333 ; N ring ; B 75 572 259 756 ; +C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ; +C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ; +C 207 ; WX 333 ; N caron ; B 21 593 312 734 ; +C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 24 405 346 737 ; +C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ; +C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ; +C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 25 405 341 737 ; +C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ; +C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ; +C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ; +C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ; +C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ; +C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ; +C -1 ; WX 556 ; N abreve ; B 36 -15 530 731 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 68 -15 521 734 ; +C -1 ; WX 556 ; N ecaron ; B 40 -15 516 734 ; +C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ; +C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ; +C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ; +C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ; +C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ; +C -1 ; WX 500 ; N scommaaccent ; B 32 -225 464 538 ; +C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ; +C -1 ; WX 722 ; N Uring ; B 79 -19 644 931 ; +C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ; +C -1 ; WX 556 ; N aogonek ; B 36 -220 547 538 ; +C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ; +C -1 ; WX 556 ; N uogonek ; B 68 -225 519 523 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ; +C -1 ; WX 722 ; N Dcroat ; B 0 0 674 718 ; +C -1 ; WX 250 ; N commaaccent ; B 87 -225 181 -40 ; +C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ; +C -1 ; WX 667 ; N Emacron ; B 86 0 616 879 ; +C -1 ; WX 500 ; N ccaron ; B 30 -15 477 734 ; +C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 646 718 ; +C -1 ; WX 222 ; N lacute ; B 67 0 264 929 ; +C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 14 -225 597 718 ; +C -1 ; WX 722 ; N Cacute ; B 44 -19 681 929 ; +C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ; +C -1 ; WX 667 ; N Edotaccent ; B 86 0 616 901 ; +C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ; +C -1 ; WX 500 ; N scedilla ; B 32 -225 464 538 ; +C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ; +C -1 ; WX 471 ; N lozenge ; B 10 0 462 728 ; +C -1 ; WX 722 ; N Rcaron ; B 88 0 684 929 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 48 -225 704 737 ; +C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ; +C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ; +C -1 ; WX 667 ; N Amacron ; B 14 0 654 879 ; +C -1 ; WX 333 ; N rcaron ; B 61 0 352 734 ; +C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ; +C -1 ; WX 611 ; N Zdotaccent ; B 23 0 588 901 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ; +C -1 ; WX 778 ; N Omacron ; B 39 -19 739 879 ; +C -1 ; WX 722 ; N Racute ; B 88 0 684 929 ; +C -1 ; WX 667 ; N Sacute ; B 49 -19 620 929 ; +C -1 ; WX 643 ; N dcaron ; B 35 -15 655 718 ; +C -1 ; WX 722 ; N Umacron ; B 79 -19 644 879 ; +C -1 ; WX 556 ; N uring ; B 68 -15 489 756 ; +C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ; +C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Abreve ; B 14 0 654 926 ; +C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ; +C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ; +C -1 ; WX 611 ; N Tcaron ; B 14 0 597 929 ; +C -1 ; WX 476 ; N partialdiff ; B 13 -38 463 714 ; +C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ; +C -1 ; WX 722 ; N Nacute ; B 76 0 646 929 ; +C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ; +C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ; +C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ; +C -1 ; WX 500 ; N cacute ; B 30 -15 477 734 ; +C -1 ; WX 556 ; N nacute ; B 65 0 491 734 ; +C -1 ; WX 556 ; N umacron ; B 68 -15 489 684 ; +C -1 ; WX 722 ; N Ncaron ; B 76 0 646 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ; +C -1 ; WX 260 ; N brokenbar ; B 94 -150 167 700 ; +C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ; +C -1 ; WX 778 ; N Gbreve ; B 48 -19 704 926 ; +C -1 ; WX 278 ; N Idotaccent ; B 91 0 188 901 ; +C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ; +C -1 ; WX 333 ; N racute ; B 77 0 332 734 ; +C -1 ; WX 556 ; N omacron ; B 35 -14 521 684 ; +C -1 ; WX 611 ; N Zacute ; B 23 0 588 929 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 674 ; +C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ; +C -1 ; WX 222 ; N lcommaaccent ; B 67 -225 167 718 ; +C -1 ; WX 317 ; N tcaron ; B 14 -7 329 808 ; +C -1 ; WX 556 ; N eogonek ; B 40 -225 516 538 ; +C -1 ; WX 722 ; N Uogonek ; B 79 -225 644 718 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ; +C -1 ; WX 500 ; N zacute ; B 31 0 469 734 ; +C -1 ; WX 222 ; N iogonek ; B -31 -225 183 718 ; +C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ; +C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ; +C -1 ; WX 556 ; N amacron ; B 36 -15 530 684 ; +C -1 ; WX 500 ; N sacute ; B 32 -15 464 734 ; +C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ; +C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ; +C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ; +C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ; +C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ; +C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ; +C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ; +C -1 ; WX 556 ; N ohungarumlaut ; B 35 -14 521 734 ; +C -1 ; WX 667 ; N Eogonek ; B 86 -220 633 718 ; +C -1 ; WX 556 ; N dcroat ; B 35 -15 550 718 ; +C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ; +C -1 ; WX 667 ; N Scedilla ; B 49 -225 620 737 ; +C -1 ; WX 299 ; N lcaron ; B 67 0 311 718 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 663 718 ; +C -1 ; WX 556 ; N Lacute ; B 76 0 537 929 ; +C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ; +C -1 ; WX 556 ; N edotaccent ; B 40 -15 516 706 ; +C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ; +C -1 ; WX 278 ; N Imacron ; B -17 0 296 879 ; +C -1 ; WX 556 ; N Lcaron ; B 76 0 537 718 ; +C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 674 ; +C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 79 -19 644 929 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ; +C -1 ; WX 556 ; N emacron ; B 40 -15 516 684 ; +C -1 ; WX 556 ; N gbreve ; B 40 -220 499 731 ; +C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ; +C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ; +C -1 ; WX 667 ; N Scommaaccent ; B 49 -225 620 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 39 -19 739 929 ; +C -1 ; WX 400 ; N degree ; B 54 411 346 703 ; +C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ; +C -1 ; WX 722 ; N Ccaron ; B 44 -19 681 929 ; +C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ; +C -1 ; WX 453 ; N radical ; B -4 -80 458 762 ; +C -1 ; WX 722 ; N Dcaron ; B 81 0 674 929 ; +C -1 ; WX 333 ; N rcommaaccent ; B 77 -225 332 538 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ; +C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 684 718 ; +C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 537 718 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ; +C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ; +C -1 ; WX 500 ; N zdotaccent ; B 31 0 469 706 ; +C -1 ; WX 667 ; N Ecaron ; B 86 0 616 929 ; +C -1 ; WX 278 ; N Iogonek ; B -3 -225 211 718 ; +C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 501 718 ; +C -1 ; WX 584 ; N minus ; B 39 216 545 289 ; +C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ; +C -1 ; WX 556 ; N ncaron ; B 65 0 491 734 ; +C -1 ; WX 278 ; N tcommaaccent ; B 14 -225 257 669 ; +C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ; +C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ; +C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ; +C -1 ; WX 549 ; N notequal ; B 12 -35 537 551 ; +C -1 ; WX 556 ; N gcommaaccent ; B 40 -220 499 822 ; +C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ; +C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 491 538 ; +C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ; +C -1 ; WX 278 ; N imacron ; B 5 0 272 684 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2705 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -30 +KPX A Gbreve -30 +KPX A Gcommaaccent -30 +KPX A O -30 +KPX A Oacute -30 +KPX A Ocircumflex -30 +KPX A Odieresis -30 +KPX A Ograve -30 +KPX A Ohungarumlaut -30 +KPX A Omacron -30 +KPX A Oslash -30 +KPX A Otilde -30 +KPX A Q -30 +KPX A T -120 +KPX A Tcaron -120 +KPX A Tcommaaccent -120 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -70 +KPX A W -50 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -40 +KPX A y -40 +KPX A yacute -40 +KPX A ydieresis -40 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -30 +KPX Aacute Gbreve -30 +KPX Aacute Gcommaaccent -30 +KPX Aacute O -30 +KPX Aacute Oacute -30 +KPX Aacute Ocircumflex -30 +KPX Aacute Odieresis -30 +KPX Aacute Ograve -30 +KPX Aacute Ohungarumlaut -30 +KPX Aacute Omacron -30 +KPX Aacute Oslash -30 +KPX Aacute Otilde -30 +KPX Aacute Q -30 +KPX Aacute T -120 +KPX Aacute Tcaron -120 +KPX Aacute Tcommaaccent -120 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -70 +KPX Aacute W -50 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -40 +KPX Aacute y -40 +KPX Aacute yacute -40 +KPX Aacute ydieresis -40 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -30 +KPX Abreve Gbreve -30 +KPX Abreve Gcommaaccent -30 +KPX Abreve O -30 +KPX Abreve Oacute -30 +KPX Abreve Ocircumflex -30 +KPX Abreve Odieresis -30 +KPX Abreve Ograve -30 +KPX Abreve Ohungarumlaut -30 +KPX Abreve Omacron -30 +KPX Abreve Oslash -30 +KPX Abreve Otilde -30 +KPX Abreve Q -30 +KPX Abreve T -120 +KPX Abreve Tcaron -120 +KPX Abreve Tcommaaccent -120 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -70 +KPX Abreve W -50 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -40 +KPX Abreve y -40 +KPX Abreve yacute -40 +KPX Abreve ydieresis -40 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -30 +KPX Acircumflex Gbreve -30 +KPX Acircumflex Gcommaaccent -30 +KPX Acircumflex O -30 +KPX Acircumflex Oacute -30 +KPX Acircumflex Ocircumflex -30 +KPX Acircumflex Odieresis -30 +KPX Acircumflex Ograve -30 +KPX Acircumflex Ohungarumlaut -30 +KPX Acircumflex Omacron -30 +KPX Acircumflex Oslash -30 +KPX Acircumflex Otilde -30 +KPX Acircumflex Q -30 +KPX Acircumflex T -120 +KPX Acircumflex Tcaron -120 +KPX Acircumflex Tcommaaccent -120 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -70 +KPX Acircumflex W -50 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -40 +KPX Acircumflex y -40 +KPX Acircumflex yacute -40 +KPX Acircumflex ydieresis -40 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -30 +KPX Adieresis Gbreve -30 +KPX Adieresis Gcommaaccent -30 +KPX Adieresis O -30 +KPX Adieresis Oacute -30 +KPX Adieresis Ocircumflex -30 +KPX Adieresis Odieresis -30 +KPX Adieresis Ograve -30 +KPX Adieresis Ohungarumlaut -30 +KPX Adieresis Omacron -30 +KPX Adieresis Oslash -30 +KPX Adieresis Otilde -30 +KPX Adieresis Q -30 +KPX Adieresis T -120 +KPX Adieresis Tcaron -120 +KPX Adieresis Tcommaaccent -120 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -70 +KPX Adieresis W -50 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -40 +KPX Adieresis y -40 +KPX Adieresis yacute -40 +KPX Adieresis ydieresis -40 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -30 +KPX Agrave Gbreve -30 +KPX Agrave Gcommaaccent -30 +KPX Agrave O -30 +KPX Agrave Oacute -30 +KPX Agrave Ocircumflex -30 +KPX Agrave Odieresis -30 +KPX Agrave Ograve -30 +KPX Agrave Ohungarumlaut -30 +KPX Agrave Omacron -30 +KPX Agrave Oslash -30 +KPX Agrave Otilde -30 +KPX Agrave Q -30 +KPX Agrave T -120 +KPX Agrave Tcaron -120 +KPX Agrave Tcommaaccent -120 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -70 +KPX Agrave W -50 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -40 +KPX Agrave y -40 +KPX Agrave yacute -40 +KPX Agrave ydieresis -40 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -30 +KPX Amacron Gbreve -30 +KPX Amacron Gcommaaccent -30 +KPX Amacron O -30 +KPX Amacron Oacute -30 +KPX Amacron Ocircumflex -30 +KPX Amacron Odieresis -30 +KPX Amacron Ograve -30 +KPX Amacron Ohungarumlaut -30 +KPX Amacron Omacron -30 +KPX Amacron Oslash -30 +KPX Amacron Otilde -30 +KPX Amacron Q -30 +KPX Amacron T -120 +KPX Amacron Tcaron -120 +KPX Amacron Tcommaaccent -120 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -70 +KPX Amacron W -50 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -40 +KPX Amacron y -40 +KPX Amacron yacute -40 +KPX Amacron ydieresis -40 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -30 +KPX Aogonek Gbreve -30 +KPX Aogonek Gcommaaccent -30 +KPX Aogonek O -30 +KPX Aogonek Oacute -30 +KPX Aogonek Ocircumflex -30 +KPX Aogonek Odieresis -30 +KPX Aogonek Ograve -30 +KPX Aogonek Ohungarumlaut -30 +KPX Aogonek Omacron -30 +KPX Aogonek Oslash -30 +KPX Aogonek Otilde -30 +KPX Aogonek Q -30 +KPX Aogonek T -120 +KPX Aogonek Tcaron -120 +KPX Aogonek Tcommaaccent -120 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -70 +KPX Aogonek W -50 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -40 +KPX Aogonek y -40 +KPX Aogonek yacute -40 +KPX Aogonek ydieresis -40 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -30 +KPX Aring Gbreve -30 +KPX Aring Gcommaaccent -30 +KPX Aring O -30 +KPX Aring Oacute -30 +KPX Aring Ocircumflex -30 +KPX Aring Odieresis -30 +KPX Aring Ograve -30 +KPX Aring Ohungarumlaut -30 +KPX Aring Omacron -30 +KPX Aring Oslash -30 +KPX Aring Otilde -30 +KPX Aring Q -30 +KPX Aring T -120 +KPX Aring Tcaron -120 +KPX Aring Tcommaaccent -120 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -70 +KPX Aring W -50 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -40 +KPX Aring y -40 +KPX Aring yacute -40 +KPX Aring ydieresis -40 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -30 +KPX Atilde Gbreve -30 +KPX Atilde Gcommaaccent -30 +KPX Atilde O -30 +KPX Atilde Oacute -30 +KPX Atilde Ocircumflex -30 +KPX Atilde Odieresis -30 +KPX Atilde Ograve -30 +KPX Atilde Ohungarumlaut -30 +KPX Atilde Omacron -30 +KPX Atilde Oslash -30 +KPX Atilde Otilde -30 +KPX Atilde Q -30 +KPX Atilde T -120 +KPX Atilde Tcaron -120 +KPX Atilde Tcommaaccent -120 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -70 +KPX Atilde W -50 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -40 +KPX Atilde y -40 +KPX Atilde yacute -40 +KPX Atilde ydieresis -40 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX B comma -20 +KPX B period -20 +KPX C comma -30 +KPX C period -30 +KPX Cacute comma -30 +KPX Cacute period -30 +KPX Ccaron comma -30 +KPX Ccaron period -30 +KPX Ccedilla comma -30 +KPX Ccedilla period -30 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -70 +KPX D W -40 +KPX D Y -90 +KPX D Yacute -90 +KPX D Ydieresis -90 +KPX D comma -70 +KPX D period -70 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -70 +KPX Dcaron W -40 +KPX Dcaron Y -90 +KPX Dcaron Yacute -90 +KPX Dcaron Ydieresis -90 +KPX Dcaron comma -70 +KPX Dcaron period -70 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -70 +KPX Dcroat W -40 +KPX Dcroat Y -90 +KPX Dcroat Yacute -90 +KPX Dcroat Ydieresis -90 +KPX Dcroat comma -70 +KPX Dcroat period -70 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -50 +KPX F aacute -50 +KPX F abreve -50 +KPX F acircumflex -50 +KPX F adieresis -50 +KPX F agrave -50 +KPX F amacron -50 +KPX F aogonek -50 +KPX F aring -50 +KPX F atilde -50 +KPX F comma -150 +KPX F e -30 +KPX F eacute -30 +KPX F ecaron -30 +KPX F ecircumflex -30 +KPX F edieresis -30 +KPX F edotaccent -30 +KPX F egrave -30 +KPX F emacron -30 +KPX F eogonek -30 +KPX F o -30 +KPX F oacute -30 +KPX F ocircumflex -30 +KPX F odieresis -30 +KPX F ograve -30 +KPX F ohungarumlaut -30 +KPX F omacron -30 +KPX F oslash -30 +KPX F otilde -30 +KPX F period -150 +KPX F r -45 +KPX F racute -45 +KPX F rcaron -45 +KPX F rcommaaccent -45 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J a -20 +KPX J aacute -20 +KPX J abreve -20 +KPX J acircumflex -20 +KPX J adieresis -20 +KPX J agrave -20 +KPX J amacron -20 +KPX J aogonek -20 +KPX J aring -20 +KPX J atilde -20 +KPX J comma -30 +KPX J period -30 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -40 +KPX K eacute -40 +KPX K ecaron -40 +KPX K ecircumflex -40 +KPX K edieresis -40 +KPX K edotaccent -40 +KPX K egrave -40 +KPX K emacron -40 +KPX K eogonek -40 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -50 +KPX K yacute -50 +KPX K ydieresis -50 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -40 +KPX Kcommaaccent eacute -40 +KPX Kcommaaccent ecaron -40 +KPX Kcommaaccent ecircumflex -40 +KPX Kcommaaccent edieresis -40 +KPX Kcommaaccent edotaccent -40 +KPX Kcommaaccent egrave -40 +KPX Kcommaaccent emacron -40 +KPX Kcommaaccent eogonek -40 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -50 +KPX Kcommaaccent yacute -50 +KPX Kcommaaccent ydieresis -50 +KPX L T -110 +KPX L Tcaron -110 +KPX L Tcommaaccent -110 +KPX L V -110 +KPX L W -70 +KPX L Y -140 +KPX L Yacute -140 +KPX L Ydieresis -140 +KPX L quotedblright -140 +KPX L quoteright -160 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -110 +KPX Lacute Tcaron -110 +KPX Lacute Tcommaaccent -110 +KPX Lacute V -110 +KPX Lacute W -70 +KPX Lacute Y -140 +KPX Lacute Yacute -140 +KPX Lacute Ydieresis -140 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -160 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcaron T -110 +KPX Lcaron Tcaron -110 +KPX Lcaron Tcommaaccent -110 +KPX Lcaron V -110 +KPX Lcaron W -70 +KPX Lcaron Y -140 +KPX Lcaron Yacute -140 +KPX Lcaron Ydieresis -140 +KPX Lcaron quotedblright -140 +KPX Lcaron quoteright -160 +KPX Lcaron y -30 +KPX Lcaron yacute -30 +KPX Lcaron ydieresis -30 +KPX Lcommaaccent T -110 +KPX Lcommaaccent Tcaron -110 +KPX Lcommaaccent Tcommaaccent -110 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -70 +KPX Lcommaaccent Y -140 +KPX Lcommaaccent Yacute -140 +KPX Lcommaaccent Ydieresis -140 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -160 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -110 +KPX Lslash Tcaron -110 +KPX Lslash Tcommaaccent -110 +KPX Lslash V -110 +KPX Lslash W -70 +KPX Lslash Y -140 +KPX Lslash Yacute -140 +KPX Lslash Ydieresis -140 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -160 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -20 +KPX O Aacute -20 +KPX O Abreve -20 +KPX O Acircumflex -20 +KPX O Adieresis -20 +KPX O Agrave -20 +KPX O Amacron -20 +KPX O Aogonek -20 +KPX O Aring -20 +KPX O Atilde -20 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -30 +KPX O X -60 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -20 +KPX Oacute Aacute -20 +KPX Oacute Abreve -20 +KPX Oacute Acircumflex -20 +KPX Oacute Adieresis -20 +KPX Oacute Agrave -20 +KPX Oacute Amacron -20 +KPX Oacute Aogonek -20 +KPX Oacute Aring -20 +KPX Oacute Atilde -20 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -30 +KPX Oacute X -60 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -20 +KPX Ocircumflex Aacute -20 +KPX Ocircumflex Abreve -20 +KPX Ocircumflex Acircumflex -20 +KPX Ocircumflex Adieresis -20 +KPX Ocircumflex Agrave -20 +KPX Ocircumflex Amacron -20 +KPX Ocircumflex Aogonek -20 +KPX Ocircumflex Aring -20 +KPX Ocircumflex Atilde -20 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -30 +KPX Ocircumflex X -60 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -20 +KPX Odieresis Aacute -20 +KPX Odieresis Abreve -20 +KPX Odieresis Acircumflex -20 +KPX Odieresis Adieresis -20 +KPX Odieresis Agrave -20 +KPX Odieresis Amacron -20 +KPX Odieresis Aogonek -20 +KPX Odieresis Aring -20 +KPX Odieresis Atilde -20 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -30 +KPX Odieresis X -60 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -20 +KPX Ograve Aacute -20 +KPX Ograve Abreve -20 +KPX Ograve Acircumflex -20 +KPX Ograve Adieresis -20 +KPX Ograve Agrave -20 +KPX Ograve Amacron -20 +KPX Ograve Aogonek -20 +KPX Ograve Aring -20 +KPX Ograve Atilde -20 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -30 +KPX Ograve X -60 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -20 +KPX Ohungarumlaut Aacute -20 +KPX Ohungarumlaut Abreve -20 +KPX Ohungarumlaut Acircumflex -20 +KPX Ohungarumlaut Adieresis -20 +KPX Ohungarumlaut Agrave -20 +KPX Ohungarumlaut Amacron -20 +KPX Ohungarumlaut Aogonek -20 +KPX Ohungarumlaut Aring -20 +KPX Ohungarumlaut Atilde -20 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -30 +KPX Ohungarumlaut X -60 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -20 +KPX Omacron Aacute -20 +KPX Omacron Abreve -20 +KPX Omacron Acircumflex -20 +KPX Omacron Adieresis -20 +KPX Omacron Agrave -20 +KPX Omacron Amacron -20 +KPX Omacron Aogonek -20 +KPX Omacron Aring -20 +KPX Omacron Atilde -20 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -30 +KPX Omacron X -60 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -20 +KPX Oslash Aacute -20 +KPX Oslash Abreve -20 +KPX Oslash Acircumflex -20 +KPX Oslash Adieresis -20 +KPX Oslash Agrave -20 +KPX Oslash Amacron -20 +KPX Oslash Aogonek -20 +KPX Oslash Aring -20 +KPX Oslash Atilde -20 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -30 +KPX Oslash X -60 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -20 +KPX Otilde Aacute -20 +KPX Otilde Abreve -20 +KPX Otilde Acircumflex -20 +KPX Otilde Adieresis -20 +KPX Otilde Agrave -20 +KPX Otilde Amacron -20 +KPX Otilde Aogonek -20 +KPX Otilde Aring -20 +KPX Otilde Atilde -20 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -30 +KPX Otilde X -60 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -120 +KPX P Aacute -120 +KPX P Abreve -120 +KPX P Acircumflex -120 +KPX P Adieresis -120 +KPX P Agrave -120 +KPX P Amacron -120 +KPX P Aogonek -120 +KPX P Aring -120 +KPX P Atilde -120 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -180 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -50 +KPX P oacute -50 +KPX P ocircumflex -50 +KPX P odieresis -50 +KPX P ograve -50 +KPX P ohungarumlaut -50 +KPX P omacron -50 +KPX P oslash -50 +KPX P otilde -50 +KPX P period -180 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -50 +KPX R W -30 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -50 +KPX Racute W -30 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -50 +KPX Rcaron W -30 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -30 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX S comma -20 +KPX S period -20 +KPX Sacute comma -20 +KPX Sacute period -20 +KPX Scaron comma -20 +KPX Scaron period -20 +KPX Scedilla comma -20 +KPX Scedilla period -20 +KPX Scommaaccent comma -20 +KPX Scommaaccent period -20 +KPX T A -120 +KPX T Aacute -120 +KPX T Abreve -120 +KPX T Acircumflex -120 +KPX T Adieresis -120 +KPX T Agrave -120 +KPX T Amacron -120 +KPX T Aogonek -120 +KPX T Aring -120 +KPX T Atilde -120 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -120 +KPX T aacute -120 +KPX T abreve -60 +KPX T acircumflex -120 +KPX T adieresis -120 +KPX T agrave -120 +KPX T amacron -60 +KPX T aogonek -120 +KPX T aring -120 +KPX T atilde -60 +KPX T colon -20 +KPX T comma -120 +KPX T e -120 +KPX T eacute -120 +KPX T ecaron -120 +KPX T ecircumflex -120 +KPX T edieresis -120 +KPX T edotaccent -120 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -120 +KPX T hyphen -140 +KPX T o -120 +KPX T oacute -120 +KPX T ocircumflex -120 +KPX T odieresis -120 +KPX T ograve -120 +KPX T ohungarumlaut -120 +KPX T omacron -60 +KPX T oslash -120 +KPX T otilde -60 +KPX T period -120 +KPX T r -120 +KPX T racute -120 +KPX T rcaron -120 +KPX T rcommaaccent -120 +KPX T semicolon -20 +KPX T u -120 +KPX T uacute -120 +KPX T ucircumflex -120 +KPX T udieresis -120 +KPX T ugrave -120 +KPX T uhungarumlaut -120 +KPX T umacron -60 +KPX T uogonek -120 +KPX T uring -120 +KPX T w -120 +KPX T y -120 +KPX T yacute -120 +KPX T ydieresis -60 +KPX Tcaron A -120 +KPX Tcaron Aacute -120 +KPX Tcaron Abreve -120 +KPX Tcaron Acircumflex -120 +KPX Tcaron Adieresis -120 +KPX Tcaron Agrave -120 +KPX Tcaron Amacron -120 +KPX Tcaron Aogonek -120 +KPX Tcaron Aring -120 +KPX Tcaron Atilde -120 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -120 +KPX Tcaron aacute -120 +KPX Tcaron abreve -60 +KPX Tcaron acircumflex -120 +KPX Tcaron adieresis -120 +KPX Tcaron agrave -120 +KPX Tcaron amacron -60 +KPX Tcaron aogonek -120 +KPX Tcaron aring -120 +KPX Tcaron atilde -60 +KPX Tcaron colon -20 +KPX Tcaron comma -120 +KPX Tcaron e -120 +KPX Tcaron eacute -120 +KPX Tcaron ecaron -120 +KPX Tcaron ecircumflex -120 +KPX Tcaron edieresis -120 +KPX Tcaron edotaccent -120 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -120 +KPX Tcaron hyphen -140 +KPX Tcaron o -120 +KPX Tcaron oacute -120 +KPX Tcaron ocircumflex -120 +KPX Tcaron odieresis -120 +KPX Tcaron ograve -120 +KPX Tcaron ohungarumlaut -120 +KPX Tcaron omacron -60 +KPX Tcaron oslash -120 +KPX Tcaron otilde -60 +KPX Tcaron period -120 +KPX Tcaron r -120 +KPX Tcaron racute -120 +KPX Tcaron rcaron -120 +KPX Tcaron rcommaaccent -120 +KPX Tcaron semicolon -20 +KPX Tcaron u -120 +KPX Tcaron uacute -120 +KPX Tcaron ucircumflex -120 +KPX Tcaron udieresis -120 +KPX Tcaron ugrave -120 +KPX Tcaron uhungarumlaut -120 +KPX Tcaron umacron -60 +KPX Tcaron uogonek -120 +KPX Tcaron uring -120 +KPX Tcaron w -120 +KPX Tcaron y -120 +KPX Tcaron yacute -120 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -120 +KPX Tcommaaccent Aacute -120 +KPX Tcommaaccent Abreve -120 +KPX Tcommaaccent Acircumflex -120 +KPX Tcommaaccent Adieresis -120 +KPX Tcommaaccent Agrave -120 +KPX Tcommaaccent Amacron -120 +KPX Tcommaaccent Aogonek -120 +KPX Tcommaaccent Aring -120 +KPX Tcommaaccent Atilde -120 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -120 +KPX Tcommaaccent aacute -120 +KPX Tcommaaccent abreve -60 +KPX Tcommaaccent acircumflex -120 +KPX Tcommaaccent adieresis -120 +KPX Tcommaaccent agrave -120 +KPX Tcommaaccent amacron -60 +KPX Tcommaaccent aogonek -120 +KPX Tcommaaccent aring -120 +KPX Tcommaaccent atilde -60 +KPX Tcommaaccent colon -20 +KPX Tcommaaccent comma -120 +KPX Tcommaaccent e -120 +KPX Tcommaaccent eacute -120 +KPX Tcommaaccent ecaron -120 +KPX Tcommaaccent ecircumflex -120 +KPX Tcommaaccent edieresis -120 +KPX Tcommaaccent edotaccent -120 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -120 +KPX Tcommaaccent hyphen -140 +KPX Tcommaaccent o -120 +KPX Tcommaaccent oacute -120 +KPX Tcommaaccent ocircumflex -120 +KPX Tcommaaccent odieresis -120 +KPX Tcommaaccent ograve -120 +KPX Tcommaaccent ohungarumlaut -120 +KPX Tcommaaccent omacron -60 +KPX Tcommaaccent oslash -120 +KPX Tcommaaccent otilde -60 +KPX Tcommaaccent period -120 +KPX Tcommaaccent r -120 +KPX Tcommaaccent racute -120 +KPX Tcommaaccent rcaron -120 +KPX Tcommaaccent rcommaaccent -120 +KPX Tcommaaccent semicolon -20 +KPX Tcommaaccent u -120 +KPX Tcommaaccent uacute -120 +KPX Tcommaaccent ucircumflex -120 +KPX Tcommaaccent udieresis -120 +KPX Tcommaaccent ugrave -120 +KPX Tcommaaccent uhungarumlaut -120 +KPX Tcommaaccent umacron -60 +KPX Tcommaaccent uogonek -120 +KPX Tcommaaccent uring -120 +KPX Tcommaaccent w -120 +KPX Tcommaaccent y -120 +KPX Tcommaaccent yacute -120 +KPX Tcommaaccent ydieresis -60 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -40 +KPX U period -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -40 +KPX Uacute period -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -40 +KPX Ucircumflex period -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -40 +KPX Udieresis period -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -40 +KPX Ugrave period -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -40 +KPX Uhungarumlaut period -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -40 +KPX Umacron period -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -40 +KPX Uogonek period -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -40 +KPX Uring period -40 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -40 +KPX V Gbreve -40 +KPX V Gcommaaccent -40 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -70 +KPX V aacute -70 +KPX V abreve -70 +KPX V acircumflex -70 +KPX V adieresis -70 +KPX V agrave -70 +KPX V amacron -70 +KPX V aogonek -70 +KPX V aring -70 +KPX V atilde -70 +KPX V colon -40 +KPX V comma -125 +KPX V e -80 +KPX V eacute -80 +KPX V ecaron -80 +KPX V ecircumflex -80 +KPX V edieresis -80 +KPX V edotaccent -80 +KPX V egrave -80 +KPX V emacron -80 +KPX V eogonek -80 +KPX V hyphen -80 +KPX V o -80 +KPX V oacute -80 +KPX V ocircumflex -80 +KPX V odieresis -80 +KPX V ograve -80 +KPX V ohungarumlaut -80 +KPX V omacron -80 +KPX V oslash -80 +KPX V otilde -80 +KPX V period -125 +KPX V semicolon -40 +KPX V u -70 +KPX V uacute -70 +KPX V ucircumflex -70 +KPX V udieresis -70 +KPX V ugrave -70 +KPX V uhungarumlaut -70 +KPX V umacron -70 +KPX V uogonek -70 +KPX V uring -70 +KPX W A -50 +KPX W Aacute -50 +KPX W Abreve -50 +KPX W Acircumflex -50 +KPX W Adieresis -50 +KPX W Agrave -50 +KPX W Amacron -50 +KPX W Aogonek -50 +KPX W Aring -50 +KPX W Atilde -50 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W comma -80 +KPX W e -30 +KPX W eacute -30 +KPX W ecaron -30 +KPX W ecircumflex -30 +KPX W edieresis -30 +KPX W edotaccent -30 +KPX W egrave -30 +KPX W emacron -30 +KPX W eogonek -30 +KPX W hyphen -40 +KPX W o -30 +KPX W oacute -30 +KPX W ocircumflex -30 +KPX W odieresis -30 +KPX W ograve -30 +KPX W ohungarumlaut -30 +KPX W omacron -30 +KPX W oslash -30 +KPX W otilde -30 +KPX W period -80 +KPX W u -30 +KPX W uacute -30 +KPX W ucircumflex -30 +KPX W udieresis -30 +KPX W ugrave -30 +KPX W uhungarumlaut -30 +KPX W umacron -30 +KPX W uogonek -30 +KPX W uring -30 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -85 +KPX Y Oacute -85 +KPX Y Ocircumflex -85 +KPX Y Odieresis -85 +KPX Y Ograve -85 +KPX Y Ohungarumlaut -85 +KPX Y Omacron -85 +KPX Y Oslash -85 +KPX Y Otilde -85 +KPX Y a -140 +KPX Y aacute -140 +KPX Y abreve -70 +KPX Y acircumflex -140 +KPX Y adieresis -140 +KPX Y agrave -140 +KPX Y amacron -70 +KPX Y aogonek -140 +KPX Y aring -140 +KPX Y atilde -140 +KPX Y colon -60 +KPX Y comma -140 +KPX Y e -140 +KPX Y eacute -140 +KPX Y ecaron -140 +KPX Y ecircumflex -140 +KPX Y edieresis -140 +KPX Y edotaccent -140 +KPX Y egrave -140 +KPX Y emacron -70 +KPX Y eogonek -140 +KPX Y hyphen -140 +KPX Y i -20 +KPX Y iacute -20 +KPX Y iogonek -20 +KPX Y o -140 +KPX Y oacute -140 +KPX Y ocircumflex -140 +KPX Y odieresis -140 +KPX Y ograve -140 +KPX Y ohungarumlaut -140 +KPX Y omacron -140 +KPX Y oslash -140 +KPX Y otilde -140 +KPX Y period -140 +KPX Y semicolon -60 +KPX Y u -110 +KPX Y uacute -110 +KPX Y ucircumflex -110 +KPX Y udieresis -110 +KPX Y ugrave -110 +KPX Y uhungarumlaut -110 +KPX Y umacron -110 +KPX Y uogonek -110 +KPX Y uring -110 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -85 +KPX Yacute Oacute -85 +KPX Yacute Ocircumflex -85 +KPX Yacute Odieresis -85 +KPX Yacute Ograve -85 +KPX Yacute Ohungarumlaut -85 +KPX Yacute Omacron -85 +KPX Yacute Oslash -85 +KPX Yacute Otilde -85 +KPX Yacute a -140 +KPX Yacute aacute -140 +KPX Yacute abreve -70 +KPX Yacute acircumflex -140 +KPX Yacute adieresis -140 +KPX Yacute agrave -140 +KPX Yacute amacron -70 +KPX Yacute aogonek -140 +KPX Yacute aring -140 +KPX Yacute atilde -70 +KPX Yacute colon -60 +KPX Yacute comma -140 +KPX Yacute e -140 +KPX Yacute eacute -140 +KPX Yacute ecaron -140 +KPX Yacute ecircumflex -140 +KPX Yacute edieresis -140 +KPX Yacute edotaccent -140 +KPX Yacute egrave -140 +KPX Yacute emacron -70 +KPX Yacute eogonek -140 +KPX Yacute hyphen -140 +KPX Yacute i -20 +KPX Yacute iacute -20 +KPX Yacute iogonek -20 +KPX Yacute o -140 +KPX Yacute oacute -140 +KPX Yacute ocircumflex -140 +KPX Yacute odieresis -140 +KPX Yacute ograve -140 +KPX Yacute ohungarumlaut -140 +KPX Yacute omacron -70 +KPX Yacute oslash -140 +KPX Yacute otilde -140 +KPX Yacute period -140 +KPX Yacute semicolon -60 +KPX Yacute u -110 +KPX Yacute uacute -110 +KPX Yacute ucircumflex -110 +KPX Yacute udieresis -110 +KPX Yacute ugrave -110 +KPX Yacute uhungarumlaut -110 +KPX Yacute umacron -110 +KPX Yacute uogonek -110 +KPX Yacute uring -110 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -85 +KPX Ydieresis Oacute -85 +KPX Ydieresis Ocircumflex -85 +KPX Ydieresis Odieresis -85 +KPX Ydieresis Ograve -85 +KPX Ydieresis Ohungarumlaut -85 +KPX Ydieresis Omacron -85 +KPX Ydieresis Oslash -85 +KPX Ydieresis Otilde -85 +KPX Ydieresis a -140 +KPX Ydieresis aacute -140 +KPX Ydieresis abreve -70 +KPX Ydieresis acircumflex -140 +KPX Ydieresis adieresis -140 +KPX Ydieresis agrave -140 +KPX Ydieresis amacron -70 +KPX Ydieresis aogonek -140 +KPX Ydieresis aring -140 +KPX Ydieresis atilde -70 +KPX Ydieresis colon -60 +KPX Ydieresis comma -140 +KPX Ydieresis e -140 +KPX Ydieresis eacute -140 +KPX Ydieresis ecaron -140 +KPX Ydieresis ecircumflex -140 +KPX Ydieresis edieresis -140 +KPX Ydieresis edotaccent -140 +KPX Ydieresis egrave -140 +KPX Ydieresis emacron -70 +KPX Ydieresis eogonek -140 +KPX Ydieresis hyphen -140 +KPX Ydieresis i -20 +KPX Ydieresis iacute -20 +KPX Ydieresis iogonek -20 +KPX Ydieresis o -140 +KPX Ydieresis oacute -140 +KPX Ydieresis ocircumflex -140 +KPX Ydieresis odieresis -140 +KPX Ydieresis ograve -140 +KPX Ydieresis ohungarumlaut -140 +KPX Ydieresis omacron -140 +KPX Ydieresis oslash -140 +KPX Ydieresis otilde -140 +KPX Ydieresis period -140 +KPX Ydieresis semicolon -60 +KPX Ydieresis u -110 +KPX Ydieresis uacute -110 +KPX Ydieresis ucircumflex -110 +KPX Ydieresis udieresis -110 +KPX Ydieresis ugrave -110 +KPX Ydieresis uhungarumlaut -110 +KPX Ydieresis umacron -110 +KPX Ydieresis uogonek -110 +KPX Ydieresis uring -110 +KPX a v -20 +KPX a w -20 +KPX a y -30 +KPX a yacute -30 +KPX a ydieresis -30 +KPX aacute v -20 +KPX aacute w -20 +KPX aacute y -30 +KPX aacute yacute -30 +KPX aacute ydieresis -30 +KPX abreve v -20 +KPX abreve w -20 +KPX abreve y -30 +KPX abreve yacute -30 +KPX abreve ydieresis -30 +KPX acircumflex v -20 +KPX acircumflex w -20 +KPX acircumflex y -30 +KPX acircumflex yacute -30 +KPX acircumflex ydieresis -30 +KPX adieresis v -20 +KPX adieresis w -20 +KPX adieresis y -30 +KPX adieresis yacute -30 +KPX adieresis ydieresis -30 +KPX agrave v -20 +KPX agrave w -20 +KPX agrave y -30 +KPX agrave yacute -30 +KPX agrave ydieresis -30 +KPX amacron v -20 +KPX amacron w -20 +KPX amacron y -30 +KPX amacron yacute -30 +KPX amacron ydieresis -30 +KPX aogonek v -20 +KPX aogonek w -20 +KPX aogonek y -30 +KPX aogonek yacute -30 +KPX aogonek ydieresis -30 +KPX aring v -20 +KPX aring w -20 +KPX aring y -30 +KPX aring yacute -30 +KPX aring ydieresis -30 +KPX atilde v -20 +KPX atilde w -20 +KPX atilde y -30 +KPX atilde yacute -30 +KPX atilde ydieresis -30 +KPX b b -10 +KPX b comma -40 +KPX b l -20 +KPX b lacute -20 +KPX b lcommaaccent -20 +KPX b lslash -20 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c comma -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute comma -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron comma -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla comma -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX colon space -50 +KPX comma quotedblright -100 +KPX comma quoteright -100 +KPX e comma -15 +KPX e period -15 +KPX e v -30 +KPX e w -20 +KPX e x -30 +KPX e y -20 +KPX e yacute -20 +KPX e ydieresis -20 +KPX eacute comma -15 +KPX eacute period -15 +KPX eacute v -30 +KPX eacute w -20 +KPX eacute x -30 +KPX eacute y -20 +KPX eacute yacute -20 +KPX eacute ydieresis -20 +KPX ecaron comma -15 +KPX ecaron period -15 +KPX ecaron v -30 +KPX ecaron w -20 +KPX ecaron x -30 +KPX ecaron y -20 +KPX ecaron yacute -20 +KPX ecaron ydieresis -20 +KPX ecircumflex comma -15 +KPX ecircumflex period -15 +KPX ecircumflex v -30 +KPX ecircumflex w -20 +KPX ecircumflex x -30 +KPX ecircumflex y -20 +KPX ecircumflex yacute -20 +KPX ecircumflex ydieresis -20 +KPX edieresis comma -15 +KPX edieresis period -15 +KPX edieresis v -30 +KPX edieresis w -20 +KPX edieresis x -30 +KPX edieresis y -20 +KPX edieresis yacute -20 +KPX edieresis ydieresis -20 +KPX edotaccent comma -15 +KPX edotaccent period -15 +KPX edotaccent v -30 +KPX edotaccent w -20 +KPX edotaccent x -30 +KPX edotaccent y -20 +KPX edotaccent yacute -20 +KPX edotaccent ydieresis -20 +KPX egrave comma -15 +KPX egrave period -15 +KPX egrave v -30 +KPX egrave w -20 +KPX egrave x -30 +KPX egrave y -20 +KPX egrave yacute -20 +KPX egrave ydieresis -20 +KPX emacron comma -15 +KPX emacron period -15 +KPX emacron v -30 +KPX emacron w -20 +KPX emacron x -30 +KPX emacron y -20 +KPX emacron yacute -20 +KPX emacron ydieresis -20 +KPX eogonek comma -15 +KPX eogonek period -15 +KPX eogonek v -30 +KPX eogonek w -20 +KPX eogonek x -30 +KPX eogonek y -20 +KPX eogonek yacute -20 +KPX eogonek ydieresis -20 +KPX f a -30 +KPX f aacute -30 +KPX f abreve -30 +KPX f acircumflex -30 +KPX f adieresis -30 +KPX f agrave -30 +KPX f amacron -30 +KPX f aogonek -30 +KPX f aring -30 +KPX f atilde -30 +KPX f comma -30 +KPX f dotlessi -28 +KPX f e -30 +KPX f eacute -30 +KPX f ecaron -30 +KPX f ecircumflex -30 +KPX f edieresis -30 +KPX f edotaccent -30 +KPX f egrave -30 +KPX f emacron -30 +KPX f eogonek -30 +KPX f o -30 +KPX f oacute -30 +KPX f ocircumflex -30 +KPX f odieresis -30 +KPX f ograve -30 +KPX f ohungarumlaut -30 +KPX f omacron -30 +KPX f oslash -30 +KPX f otilde -30 +KPX f period -30 +KPX f quotedblright 60 +KPX f quoteright 50 +KPX g r -10 +KPX g racute -10 +KPX g rcaron -10 +KPX g rcommaaccent -10 +KPX gbreve r -10 +KPX gbreve racute -10 +KPX gbreve rcaron -10 +KPX gbreve rcommaaccent -10 +KPX gcommaaccent r -10 +KPX gcommaaccent racute -10 +KPX gcommaaccent rcaron -10 +KPX gcommaaccent rcommaaccent -10 +KPX h y -30 +KPX h yacute -30 +KPX h ydieresis -30 +KPX k e -20 +KPX k eacute -20 +KPX k ecaron -20 +KPX k ecircumflex -20 +KPX k edieresis -20 +KPX k edotaccent -20 +KPX k egrave -20 +KPX k emacron -20 +KPX k eogonek -20 +KPX k o -20 +KPX k oacute -20 +KPX k ocircumflex -20 +KPX k odieresis -20 +KPX k ograve -20 +KPX k ohungarumlaut -20 +KPX k omacron -20 +KPX k oslash -20 +KPX k otilde -20 +KPX kcommaaccent e -20 +KPX kcommaaccent eacute -20 +KPX kcommaaccent ecaron -20 +KPX kcommaaccent ecircumflex -20 +KPX kcommaaccent edieresis -20 +KPX kcommaaccent edotaccent -20 +KPX kcommaaccent egrave -20 +KPX kcommaaccent emacron -20 +KPX kcommaaccent eogonek -20 +KPX kcommaaccent o -20 +KPX kcommaaccent oacute -20 +KPX kcommaaccent ocircumflex -20 +KPX kcommaaccent odieresis -20 +KPX kcommaaccent ograve -20 +KPX kcommaaccent ohungarumlaut -20 +KPX kcommaaccent omacron -20 +KPX kcommaaccent oslash -20 +KPX kcommaaccent otilde -20 +KPX m u -10 +KPX m uacute -10 +KPX m ucircumflex -10 +KPX m udieresis -10 +KPX m ugrave -10 +KPX m uhungarumlaut -10 +KPX m umacron -10 +KPX m uogonek -10 +KPX m uring -10 +KPX m y -15 +KPX m yacute -15 +KPX m ydieresis -15 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -20 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -20 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -20 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -20 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -20 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o comma -40 +KPX o period -40 +KPX o v -15 +KPX o w -15 +KPX o x -30 +KPX o y -30 +KPX o yacute -30 +KPX o ydieresis -30 +KPX oacute comma -40 +KPX oacute period -40 +KPX oacute v -15 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -30 +KPX oacute yacute -30 +KPX oacute ydieresis -30 +KPX ocircumflex comma -40 +KPX ocircumflex period -40 +KPX ocircumflex v -15 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -30 +KPX ocircumflex yacute -30 +KPX ocircumflex ydieresis -30 +KPX odieresis comma -40 +KPX odieresis period -40 +KPX odieresis v -15 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -30 +KPX odieresis yacute -30 +KPX odieresis ydieresis -30 +KPX ograve comma -40 +KPX ograve period -40 +KPX ograve v -15 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -30 +KPX ograve yacute -30 +KPX ograve ydieresis -30 +KPX ohungarumlaut comma -40 +KPX ohungarumlaut period -40 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -30 +KPX ohungarumlaut yacute -30 +KPX ohungarumlaut ydieresis -30 +KPX omacron comma -40 +KPX omacron period -40 +KPX omacron v -15 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -30 +KPX omacron yacute -30 +KPX omacron ydieresis -30 +KPX oslash a -55 +KPX oslash aacute -55 +KPX oslash abreve -55 +KPX oslash acircumflex -55 +KPX oslash adieresis -55 +KPX oslash agrave -55 +KPX oslash amacron -55 +KPX oslash aogonek -55 +KPX oslash aring -55 +KPX oslash atilde -55 +KPX oslash b -55 +KPX oslash c -55 +KPX oslash cacute -55 +KPX oslash ccaron -55 +KPX oslash ccedilla -55 +KPX oslash comma -95 +KPX oslash d -55 +KPX oslash dcroat -55 +KPX oslash e -55 +KPX oslash eacute -55 +KPX oslash ecaron -55 +KPX oslash ecircumflex -55 +KPX oslash edieresis -55 +KPX oslash edotaccent -55 +KPX oslash egrave -55 +KPX oslash emacron -55 +KPX oslash eogonek -55 +KPX oslash f -55 +KPX oslash g -55 +KPX oslash gbreve -55 +KPX oslash gcommaaccent -55 +KPX oslash h -55 +KPX oslash i -55 +KPX oslash iacute -55 +KPX oslash icircumflex -55 +KPX oslash idieresis -55 +KPX oslash igrave -55 +KPX oslash imacron -55 +KPX oslash iogonek -55 +KPX oslash j -55 +KPX oslash k -55 +KPX oslash kcommaaccent -55 +KPX oslash l -55 +KPX oslash lacute -55 +KPX oslash lcommaaccent -55 +KPX oslash lslash -55 +KPX oslash m -55 +KPX oslash n -55 +KPX oslash nacute -55 +KPX oslash ncaron -55 +KPX oslash ncommaaccent -55 +KPX oslash ntilde -55 +KPX oslash o -55 +KPX oslash oacute -55 +KPX oslash ocircumflex -55 +KPX oslash odieresis -55 +KPX oslash ograve -55 +KPX oslash ohungarumlaut -55 +KPX oslash omacron -55 +KPX oslash oslash -55 +KPX oslash otilde -55 +KPX oslash p -55 +KPX oslash period -95 +KPX oslash q -55 +KPX oslash r -55 +KPX oslash racute -55 +KPX oslash rcaron -55 +KPX oslash rcommaaccent -55 +KPX oslash s -55 +KPX oslash sacute -55 +KPX oslash scaron -55 +KPX oslash scedilla -55 +KPX oslash scommaaccent -55 +KPX oslash t -55 +KPX oslash tcommaaccent -55 +KPX oslash u -55 +KPX oslash uacute -55 +KPX oslash ucircumflex -55 +KPX oslash udieresis -55 +KPX oslash ugrave -55 +KPX oslash uhungarumlaut -55 +KPX oslash umacron -55 +KPX oslash uogonek -55 +KPX oslash uring -55 +KPX oslash v -70 +KPX oslash w -70 +KPX oslash x -85 +KPX oslash y -70 +KPX oslash yacute -70 +KPX oslash ydieresis -70 +KPX oslash z -55 +KPX oslash zacute -55 +KPX oslash zcaron -55 +KPX oslash zdotaccent -55 +KPX otilde comma -40 +KPX otilde period -40 +KPX otilde v -15 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -30 +KPX otilde yacute -30 +KPX otilde ydieresis -30 +KPX p comma -35 +KPX p period -35 +KPX p y -30 +KPX p yacute -30 +KPX p ydieresis -30 +KPX period quotedblright -100 +KPX period quoteright -100 +KPX period space -60 +KPX quotedblright space -40 +KPX quoteleft quoteleft -57 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright quoteright -57 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -50 +KPX quoteright sacute -50 +KPX quoteright scaron -50 +KPX quoteright scedilla -50 +KPX quoteright scommaaccent -50 +KPX quoteright space -70 +KPX r a -10 +KPX r aacute -10 +KPX r abreve -10 +KPX r acircumflex -10 +KPX r adieresis -10 +KPX r agrave -10 +KPX r amacron -10 +KPX r aogonek -10 +KPX r aring -10 +KPX r atilde -10 +KPX r colon 30 +KPX r comma -50 +KPX r i 15 +KPX r iacute 15 +KPX r icircumflex 15 +KPX r idieresis 15 +KPX r igrave 15 +KPX r imacron 15 +KPX r iogonek 15 +KPX r k 15 +KPX r kcommaaccent 15 +KPX r l 15 +KPX r lacute 15 +KPX r lcommaaccent 15 +KPX r lslash 15 +KPX r m 25 +KPX r n 25 +KPX r nacute 25 +KPX r ncaron 25 +KPX r ncommaaccent 25 +KPX r ntilde 25 +KPX r p 30 +KPX r period -50 +KPX r semicolon 30 +KPX r t 40 +KPX r tcommaaccent 40 +KPX r u 15 +KPX r uacute 15 +KPX r ucircumflex 15 +KPX r udieresis 15 +KPX r ugrave 15 +KPX r uhungarumlaut 15 +KPX r umacron 15 +KPX r uogonek 15 +KPX r uring 15 +KPX r v 30 +KPX r y 30 +KPX r yacute 30 +KPX r ydieresis 30 +KPX racute a -10 +KPX racute aacute -10 +KPX racute abreve -10 +KPX racute acircumflex -10 +KPX racute adieresis -10 +KPX racute agrave -10 +KPX racute amacron -10 +KPX racute aogonek -10 +KPX racute aring -10 +KPX racute atilde -10 +KPX racute colon 30 +KPX racute comma -50 +KPX racute i 15 +KPX racute iacute 15 +KPX racute icircumflex 15 +KPX racute idieresis 15 +KPX racute igrave 15 +KPX racute imacron 15 +KPX racute iogonek 15 +KPX racute k 15 +KPX racute kcommaaccent 15 +KPX racute l 15 +KPX racute lacute 15 +KPX racute lcommaaccent 15 +KPX racute lslash 15 +KPX racute m 25 +KPX racute n 25 +KPX racute nacute 25 +KPX racute ncaron 25 +KPX racute ncommaaccent 25 +KPX racute ntilde 25 +KPX racute p 30 +KPX racute period -50 +KPX racute semicolon 30 +KPX racute t 40 +KPX racute tcommaaccent 40 +KPX racute u 15 +KPX racute uacute 15 +KPX racute ucircumflex 15 +KPX racute udieresis 15 +KPX racute ugrave 15 +KPX racute uhungarumlaut 15 +KPX racute umacron 15 +KPX racute uogonek 15 +KPX racute uring 15 +KPX racute v 30 +KPX racute y 30 +KPX racute yacute 30 +KPX racute ydieresis 30 +KPX rcaron a -10 +KPX rcaron aacute -10 +KPX rcaron abreve -10 +KPX rcaron acircumflex -10 +KPX rcaron adieresis -10 +KPX rcaron agrave -10 +KPX rcaron amacron -10 +KPX rcaron aogonek -10 +KPX rcaron aring -10 +KPX rcaron atilde -10 +KPX rcaron colon 30 +KPX rcaron comma -50 +KPX rcaron i 15 +KPX rcaron iacute 15 +KPX rcaron icircumflex 15 +KPX rcaron idieresis 15 +KPX rcaron igrave 15 +KPX rcaron imacron 15 +KPX rcaron iogonek 15 +KPX rcaron k 15 +KPX rcaron kcommaaccent 15 +KPX rcaron l 15 +KPX rcaron lacute 15 +KPX rcaron lcommaaccent 15 +KPX rcaron lslash 15 +KPX rcaron m 25 +KPX rcaron n 25 +KPX rcaron nacute 25 +KPX rcaron ncaron 25 +KPX rcaron ncommaaccent 25 +KPX rcaron ntilde 25 +KPX rcaron p 30 +KPX rcaron period -50 +KPX rcaron semicolon 30 +KPX rcaron t 40 +KPX rcaron tcommaaccent 40 +KPX rcaron u 15 +KPX rcaron uacute 15 +KPX rcaron ucircumflex 15 +KPX rcaron udieresis 15 +KPX rcaron ugrave 15 +KPX rcaron uhungarumlaut 15 +KPX rcaron umacron 15 +KPX rcaron uogonek 15 +KPX rcaron uring 15 +KPX rcaron v 30 +KPX rcaron y 30 +KPX rcaron yacute 30 +KPX rcaron ydieresis 30 +KPX rcommaaccent a -10 +KPX rcommaaccent aacute -10 +KPX rcommaaccent abreve -10 +KPX rcommaaccent acircumflex -10 +KPX rcommaaccent adieresis -10 +KPX rcommaaccent agrave -10 +KPX rcommaaccent amacron -10 +KPX rcommaaccent aogonek -10 +KPX rcommaaccent aring -10 +KPX rcommaaccent atilde -10 +KPX rcommaaccent colon 30 +KPX rcommaaccent comma -50 +KPX rcommaaccent i 15 +KPX rcommaaccent iacute 15 +KPX rcommaaccent icircumflex 15 +KPX rcommaaccent idieresis 15 +KPX rcommaaccent igrave 15 +KPX rcommaaccent imacron 15 +KPX rcommaaccent iogonek 15 +KPX rcommaaccent k 15 +KPX rcommaaccent kcommaaccent 15 +KPX rcommaaccent l 15 +KPX rcommaaccent lacute 15 +KPX rcommaaccent lcommaaccent 15 +KPX rcommaaccent lslash 15 +KPX rcommaaccent m 25 +KPX rcommaaccent n 25 +KPX rcommaaccent nacute 25 +KPX rcommaaccent ncaron 25 +KPX rcommaaccent ncommaaccent 25 +KPX rcommaaccent ntilde 25 +KPX rcommaaccent p 30 +KPX rcommaaccent period -50 +KPX rcommaaccent semicolon 30 +KPX rcommaaccent t 40 +KPX rcommaaccent tcommaaccent 40 +KPX rcommaaccent u 15 +KPX rcommaaccent uacute 15 +KPX rcommaaccent ucircumflex 15 +KPX rcommaaccent udieresis 15 +KPX rcommaaccent ugrave 15 +KPX rcommaaccent uhungarumlaut 15 +KPX rcommaaccent umacron 15 +KPX rcommaaccent uogonek 15 +KPX rcommaaccent uring 15 +KPX rcommaaccent v 30 +KPX rcommaaccent y 30 +KPX rcommaaccent yacute 30 +KPX rcommaaccent ydieresis 30 +KPX s comma -15 +KPX s period -15 +KPX s w -30 +KPX sacute comma -15 +KPX sacute period -15 +KPX sacute w -30 +KPX scaron comma -15 +KPX scaron period -15 +KPX scaron w -30 +KPX scedilla comma -15 +KPX scedilla period -15 +KPX scedilla w -30 +KPX scommaaccent comma -15 +KPX scommaaccent period -15 +KPX scommaaccent w -30 +KPX semicolon space -50 +KPX space T -50 +KPX space Tcaron -50 +KPX space Tcommaaccent -50 +KPX space V -50 +KPX space W -40 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX space quotedblleft -30 +KPX space quoteleft -60 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -80 +KPX v e -25 +KPX v eacute -25 +KPX v ecaron -25 +KPX v ecircumflex -25 +KPX v edieresis -25 +KPX v edotaccent -25 +KPX v egrave -25 +KPX v emacron -25 +KPX v eogonek -25 +KPX v o -25 +KPX v oacute -25 +KPX v ocircumflex -25 +KPX v odieresis -25 +KPX v ograve -25 +KPX v ohungarumlaut -25 +KPX v omacron -25 +KPX v oslash -25 +KPX v otilde -25 +KPX v period -80 +KPX w a -15 +KPX w aacute -15 +KPX w abreve -15 +KPX w acircumflex -15 +KPX w adieresis -15 +KPX w agrave -15 +KPX w amacron -15 +KPX w aogonek -15 +KPX w aring -15 +KPX w atilde -15 +KPX w comma -60 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -60 +KPX x e -30 +KPX x eacute -30 +KPX x ecaron -30 +KPX x ecircumflex -30 +KPX x edieresis -30 +KPX x edotaccent -30 +KPX x egrave -30 +KPX x emacron -30 +KPX x eogonek -30 +KPX y a -20 +KPX y aacute -20 +KPX y abreve -20 +KPX y acircumflex -20 +KPX y adieresis -20 +KPX y agrave -20 +KPX y amacron -20 +KPX y aogonek -20 +KPX y aring -20 +KPX y atilde -20 +KPX y comma -100 +KPX y e -20 +KPX y eacute -20 +KPX y ecaron -20 +KPX y ecircumflex -20 +KPX y edieresis -20 +KPX y edotaccent -20 +KPX y egrave -20 +KPX y emacron -20 +KPX y eogonek -20 +KPX y o -20 +KPX y oacute -20 +KPX y ocircumflex -20 +KPX y odieresis -20 +KPX y ograve -20 +KPX y ohungarumlaut -20 +KPX y omacron -20 +KPX y oslash -20 +KPX y otilde -20 +KPX y period -100 +KPX yacute a -20 +KPX yacute aacute -20 +KPX yacute abreve -20 +KPX yacute acircumflex -20 +KPX yacute adieresis -20 +KPX yacute agrave -20 +KPX yacute amacron -20 +KPX yacute aogonek -20 +KPX yacute aring -20 +KPX yacute atilde -20 +KPX yacute comma -100 +KPX yacute e -20 +KPX yacute eacute -20 +KPX yacute ecaron -20 +KPX yacute ecircumflex -20 +KPX yacute edieresis -20 +KPX yacute edotaccent -20 +KPX yacute egrave -20 +KPX yacute emacron -20 +KPX yacute eogonek -20 +KPX yacute o -20 +KPX yacute oacute -20 +KPX yacute ocircumflex -20 +KPX yacute odieresis -20 +KPX yacute ograve -20 +KPX yacute ohungarumlaut -20 +KPX yacute omacron -20 +KPX yacute oslash -20 +KPX yacute otilde -20 +KPX yacute period -100 +KPX ydieresis a -20 +KPX ydieresis aacute -20 +KPX ydieresis abreve -20 +KPX ydieresis acircumflex -20 +KPX ydieresis adieresis -20 +KPX ydieresis agrave -20 +KPX ydieresis amacron -20 +KPX ydieresis aogonek -20 +KPX ydieresis aring -20 +KPX ydieresis atilde -20 +KPX ydieresis comma -100 +KPX ydieresis e -20 +KPX ydieresis eacute -20 +KPX ydieresis ecaron -20 +KPX ydieresis ecircumflex -20 +KPX ydieresis edieresis -20 +KPX ydieresis edotaccent -20 +KPX ydieresis egrave -20 +KPX ydieresis emacron -20 +KPX ydieresis eogonek -20 +KPX ydieresis o -20 +KPX ydieresis oacute -20 +KPX ydieresis ocircumflex -20 +KPX ydieresis odieresis -20 +KPX ydieresis ograve -20 +KPX ydieresis ohungarumlaut -20 +KPX ydieresis omacron -20 +KPX ydieresis oslash -20 +KPX ydieresis otilde -20 +KPX ydieresis period -100 +KPX z e -15 +KPX z eacute -15 +KPX z ecaron -15 +KPX z ecircumflex -15 +KPX z edieresis -15 +KPX z edotaccent -15 +KPX z egrave -15 +KPX z emacron -15 +KPX z eogonek -15 +KPX z o -15 +KPX z oacute -15 +KPX z ocircumflex -15 +KPX z odieresis -15 +KPX z ograve -15 +KPX z ohungarumlaut -15 +KPX z omacron -15 +KPX z oslash -15 +KPX z otilde -15 +KPX zacute e -15 +KPX zacute eacute -15 +KPX zacute ecaron -15 +KPX zacute ecircumflex -15 +KPX zacute edieresis -15 +KPX zacute edotaccent -15 +KPX zacute egrave -15 +KPX zacute emacron -15 +KPX zacute eogonek -15 +KPX zacute o -15 +KPX zacute oacute -15 +KPX zacute ocircumflex -15 +KPX zacute odieresis -15 +KPX zacute ograve -15 +KPX zacute ohungarumlaut -15 +KPX zacute omacron -15 +KPX zacute oslash -15 +KPX zacute otilde -15 +KPX zcaron e -15 +KPX zcaron eacute -15 +KPX zcaron ecaron -15 +KPX zcaron ecircumflex -15 +KPX zcaron edieresis -15 +KPX zcaron edotaccent -15 +KPX zcaron egrave -15 +KPX zcaron emacron -15 +KPX zcaron eogonek -15 +KPX zcaron o -15 +KPX zcaron oacute -15 +KPX zcaron ocircumflex -15 +KPX zcaron odieresis -15 +KPX zcaron ograve -15 +KPX zcaron ohungarumlaut -15 +KPX zcaron omacron -15 +KPX zcaron oslash -15 +KPX zcaron otilde -15 +KPX zdotaccent e -15 +KPX zdotaccent eacute -15 +KPX zdotaccent ecaron -15 +KPX zdotaccent ecircumflex -15 +KPX zdotaccent edieresis -15 +KPX zdotaccent edotaccent -15 +KPX zdotaccent egrave -15 +KPX zdotaccent emacron -15 +KPX zdotaccent eogonek -15 +KPX zdotaccent o -15 +KPX zdotaccent oacute -15 +KPX zdotaccent ocircumflex -15 +KPX zdotaccent odieresis -15 +KPX zdotaccent ograve -15 +KPX zdotaccent ohungarumlaut -15 +KPX zdotaccent omacron -15 +KPX zdotaccent oslash -15 +KPX zdotaccent otilde -15 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm new file mode 100644 index 00000000..6a5386a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm @@ -0,0 +1,213 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu May 1 15:12:25 1997 +Comment UniqueID 43064 +Comment VMusage 30820 39997 +FontName Symbol +FullName Symbol +FamilyName Symbol +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet Special +FontBBox -180 -293 1090 1010 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.008 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. +EncodingScheme FontSpecific +StdHW 92 +StdVW 85 +StartCharMetrics 190 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ; +C 34 ; WX 713 ; N universal ; B 31 0 681 705 ; +C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ; +C 36 ; WX 549 ; N existential ; B 25 0 478 707 ; +C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ; +C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ; +C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ; +C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ; +C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ; +C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ; +C 43 ; WX 549 ; N plus ; B 10 0 539 533 ; +C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ; +C 45 ; WX 549 ; N minus ; B 11 233 535 288 ; +C 46 ; WX 250 ; N period ; B 69 -17 181 95 ; +C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ; +C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ; +C 49 ; WX 500 ; N one ; B 117 0 390 673 ; +C 50 ; WX 500 ; N two ; B 25 0 475 685 ; +C 51 ; WX 500 ; N three ; B 43 -14 435 685 ; +C 52 ; WX 500 ; N four ; B 15 0 469 685 ; +C 53 ; WX 500 ; N five ; B 32 -14 445 690 ; +C 54 ; WX 500 ; N six ; B 34 -14 468 685 ; +C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ; +C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ; +C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ; +C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ; +C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ; +C 60 ; WX 549 ; N less ; B 26 0 523 522 ; +C 61 ; WX 549 ; N equal ; B 11 141 537 390 ; +C 62 ; WX 549 ; N greater ; B 26 0 523 522 ; +C 63 ; WX 444 ; N question ; B 70 -17 412 686 ; +C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ; +C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ; +C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ; +C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ; +C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ; +C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ; +C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ; +C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ; +C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ; +C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ; +C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ; +C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ; +C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ; +C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ; +C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ; +C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ; +C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ; +C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ; +C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ; +C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ; +C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ; +C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ; +C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ; +C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ; +C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ; +C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ; +C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ; +C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ; +C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ; +C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ; +C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ; +C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ; +C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ; +C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ; +C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ; +C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ; +C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ; +C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ; +C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ; +C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ; +C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ; +C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ; +C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ; +C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ; +C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ; +C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ; +C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ; +C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ; +C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ; +C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ; +C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ; +C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ; +C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ; +C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ; +C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ; +C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ; +C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ; +C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ; +C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ; +C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ; +C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ; +C 126 ; WX 549 ; N similar ; B 17 203 529 307 ; +C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ; +C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ; +C 162 ; WX 247 ; N minute ; B 27 459 228 735 ; +C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ; +C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ; +C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ; +C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ; +C 167 ; WX 753 ; N club ; B 86 -26 660 533 ; +C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ; +C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ; +C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ; +C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ; +C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ; +C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ; +C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ; +C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ; +C 176 ; WX 400 ; N degree ; B 50 385 350 685 ; +C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ; +C 178 ; WX 411 ; N second ; B 20 459 413 737 ; +C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ; +C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ; +C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ; +C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ; +C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ; +C 184 ; WX 549 ; N divide ; B 10 71 536 456 ; +C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ; +C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ; +C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ; +C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ; +C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ; +C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ; +C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ; +C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ; +C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ; +C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ; +C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ; +C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ; +C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ; +C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ; +C 200 ; WX 768 ; N union ; B 40 -17 732 492 ; +C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ; +C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ; +C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ; +C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ; +C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ; +C 206 ; WX 713 ; N element ; B 45 0 505 468 ; +C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ; +C 208 ; WX 768 ; N angle ; B 26 0 738 673 ; +C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ; +C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ; +C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ; +C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ; +C 213 ; WX 823 ; N product ; B 25 -101 803 751 ; +C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ; +C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ; +C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ; +C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ; +C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ; +C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ; +C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ; +C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ; +C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ; +C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ; +C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ; +C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ; +C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ; +C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ; +C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ; +C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ; +C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ; +C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ; +C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ; +C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ; +C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ; +C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ; +C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ; +C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ; +C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ; +C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ; +C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ; +C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ; +C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ; +C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ; +C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ; +C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ; +C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ; +C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ; +C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ; +C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ; +C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ; +C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ; +C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ; +C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ; +C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm new file mode 100644 index 00000000..559ebaeb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm @@ -0,0 +1,2588 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:52:56 1997 +Comment UniqueID 43065 +Comment VMusage 41636 52661 +FontName Times-Bold +FullName Times Bold +FamilyName Times +Weight Bold +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -168 -218 1000 935 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 676 +XHeight 461 +Ascender 683 +Descender -217 +StdHW 44 +StdVW 139 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ; +C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ; +C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ; +C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ; +C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ; +C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ; +C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ; +C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ; +C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ; +C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ; +C 46 ; WX 250 ; N period ; B 41 -13 210 156 ; +C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ; +C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ; +C 49 ; WX 500 ; N one ; B 65 0 442 688 ; +C 50 ; WX 500 ; N two ; B 17 0 478 688 ; +C 51 ; WX 500 ; N three ; B 16 -14 468 688 ; +C 52 ; WX 500 ; N four ; B 19 0 475 688 ; +C 53 ; WX 500 ; N five ; B 22 -8 470 676 ; +C 54 ; WX 500 ; N six ; B 28 -13 475 688 ; +C 55 ; WX 500 ; N seven ; B 17 0 477 676 ; +C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ; +C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ; +C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ; +C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 57 -13 445 689 ; +C 64 ; WX 930 ; N at ; B 108 -19 822 691 ; +C 65 ; WX 722 ; N A ; B 9 0 689 690 ; +C 66 ; WX 667 ; N B ; B 16 0 619 676 ; +C 67 ; WX 722 ; N C ; B 49 -19 687 691 ; +C 68 ; WX 722 ; N D ; B 14 0 690 676 ; +C 69 ; WX 667 ; N E ; B 16 0 641 676 ; +C 70 ; WX 611 ; N F ; B 16 0 583 676 ; +C 71 ; WX 778 ; N G ; B 37 -19 755 691 ; +C 72 ; WX 778 ; N H ; B 21 0 759 676 ; +C 73 ; WX 389 ; N I ; B 20 0 370 676 ; +C 74 ; WX 500 ; N J ; B 3 -96 479 676 ; +C 75 ; WX 778 ; N K ; B 30 0 769 676 ; +C 76 ; WX 667 ; N L ; B 19 0 638 676 ; +C 77 ; WX 944 ; N M ; B 14 0 921 676 ; +C 78 ; WX 722 ; N N ; B 16 -18 701 676 ; +C 79 ; WX 778 ; N O ; B 35 -19 743 691 ; +C 80 ; WX 611 ; N P ; B 16 0 600 676 ; +C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ; +C 82 ; WX 722 ; N R ; B 26 0 715 676 ; +C 83 ; WX 556 ; N S ; B 35 -19 513 692 ; +C 84 ; WX 667 ; N T ; B 31 0 636 676 ; +C 85 ; WX 722 ; N U ; B 16 -19 701 676 ; +C 86 ; WX 722 ; N V ; B 16 -18 701 676 ; +C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ; +C 88 ; WX 722 ; N X ; B 16 0 699 676 ; +C 89 ; WX 722 ; N Y ; B 15 0 699 676 ; +C 90 ; WX 667 ; N Z ; B 28 0 634 676 ; +C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ; +C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ; +C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ; +C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ; +C 97 ; WX 500 ; N a ; B 25 -14 488 473 ; +C 98 ; WX 556 ; N b ; B 17 -14 521 676 ; +C 99 ; WX 444 ; N c ; B 25 -14 430 473 ; +C 100 ; WX 556 ; N d ; B 25 -14 534 676 ; +C 101 ; WX 444 ; N e ; B 25 -14 426 473 ; +C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -206 483 473 ; +C 104 ; WX 556 ; N h ; B 16 0 534 676 ; +C 105 ; WX 278 ; N i ; B 16 0 255 691 ; +C 106 ; WX 333 ; N j ; B -57 -203 263 691 ; +C 107 ; WX 556 ; N k ; B 22 0 543 676 ; +C 108 ; WX 278 ; N l ; B 16 0 255 676 ; +C 109 ; WX 833 ; N m ; B 16 0 814 473 ; +C 110 ; WX 556 ; N n ; B 21 0 539 473 ; +C 111 ; WX 500 ; N o ; B 25 -14 476 473 ; +C 112 ; WX 556 ; N p ; B 19 -205 524 473 ; +C 113 ; WX 556 ; N q ; B 34 -205 536 473 ; +C 114 ; WX 444 ; N r ; B 29 0 434 473 ; +C 115 ; WX 389 ; N s ; B 25 -14 361 473 ; +C 116 ; WX 333 ; N t ; B 20 -12 332 630 ; +C 117 ; WX 556 ; N u ; B 16 -14 537 461 ; +C 118 ; WX 500 ; N v ; B 21 -14 485 461 ; +C 119 ; WX 722 ; N w ; B 23 -14 707 461 ; +C 120 ; WX 500 ; N x ; B 12 0 484 461 ; +C 121 ; WX 500 ; N y ; B 16 -205 480 461 ; +C 122 ; WX 444 ; N z ; B 21 0 420 461 ; +C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ; +C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; +C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ; +C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ; +C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ; +C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ; +C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ; +C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ; +C 165 ; WX 500 ; N yen ; B -64 0 547 676 ; +C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ; +C 167 ; WX 500 ; N section ; B 57 -132 443 691 ; +C 168 ; WX 500 ; N currency ; B -26 61 526 613 ; +C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ; +C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ; +C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ; +C 174 ; WX 556 ; N fi ; B 14 0 536 691 ; +C 175 ; WX 556 ; N fl ; B 14 0 536 691 ; +C 177 ; WX 500 ; N endash ; B 0 181 500 271 ; +C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ; +C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ; +C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ; +C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ; +C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ; +C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ; +C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ; +C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ; +C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ; +C 193 ; WX 333 ; N grave ; B 8 528 246 713 ; +C 194 ; WX 333 ; N acute ; B 86 528 324 713 ; +C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ; +C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ; +C 197 ; WX 333 ; N macron ; B 1 565 331 637 ; +C 198 ; WX 333 ; N breve ; B 15 528 318 691 ; +C 199 ; WX 333 ; N dotaccent ; B 103 536 258 691 ; +C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ; +C 202 ; WX 333 ; N ring ; B 60 527 273 740 ; +C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ; +C 206 ; WX 333 ; N ogonek ; B 90 -193 319 24 ; +C 207 ; WX 333 ; N caron ; B -2 528 335 704 ; +C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ; +C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ; +C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ; +C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ; +C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ; +C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ; +C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ; +C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ; +C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ; +C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ; +C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ; +C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ; +C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ; +C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ; +C -1 ; WX 500 ; N abreve ; B 25 -14 488 691 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 16 -14 557 713 ; +C -1 ; WX 444 ; N ecaron ; B 25 -14 426 704 ; +C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ; +C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ; +C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ; +C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ; +C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ; +C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ; +C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ; +C -1 ; WX 389 ; N scommaaccent ; B 25 -218 361 473 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ; +C -1 ; WX 722 ; N Uring ; B 16 -19 701 935 ; +C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ; +C -1 ; WX 500 ; N aogonek ; B 25 -193 504 473 ; +C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ; +C -1 ; WX 556 ; N uogonek ; B 16 -193 539 461 ; +C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ; +C -1 ; WX 722 ; N Dcroat ; B 6 0 690 676 ; +C -1 ; WX 250 ; N commaaccent ; B 47 -218 203 -50 ; +C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ; +C -1 ; WX 667 ; N Emacron ; B 16 0 641 847 ; +C -1 ; WX 444 ; N ccaron ; B 25 -14 430 704 ; +C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 16 -188 701 676 ; +C -1 ; WX 278 ; N lacute ; B 16 0 297 923 ; +C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ; +C -1 ; WX 667 ; N Tcommaaccent ; B 31 -218 636 676 ; +C -1 ; WX 722 ; N Cacute ; B 49 -19 687 923 ; +C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ; +C -1 ; WX 667 ; N Edotaccent ; B 16 0 641 901 ; +C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ; +C -1 ; WX 389 ; N scedilla ; B 25 -218 361 473 ; +C -1 ; WX 278 ; N iacute ; B 16 0 289 713 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 722 ; N Rcaron ; B 26 0 715 914 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 37 -218 755 691 ; +C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ; +C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ; +C -1 ; WX 722 ; N Amacron ; B 9 0 689 847 ; +C -1 ; WX 444 ; N rcaron ; B 29 0 434 704 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ; +C -1 ; WX 667 ; N Zdotaccent ; B 28 0 634 901 ; +C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ; +C -1 ; WX 778 ; N Omacron ; B 35 -19 743 847 ; +C -1 ; WX 722 ; N Racute ; B 26 0 715 923 ; +C -1 ; WX 556 ; N Sacute ; B 35 -19 513 923 ; +C -1 ; WX 672 ; N dcaron ; B 25 -14 681 682 ; +C -1 ; WX 722 ; N Umacron ; B 16 -19 701 847 ; +C -1 ; WX 556 ; N uring ; B 16 -14 537 740 ; +C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ; +C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ; +C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ; +C -1 ; WX 722 ; N Abreve ; B 9 0 689 901 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ; +C -1 ; WX 667 ; N Tcaron ; B 31 0 636 914 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ; +C -1 ; WX 722 ; N Nacute ; B 16 -18 701 923 ; +C -1 ; WX 278 ; N icircumflex ; B -37 0 300 704 ; +C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ; +C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ; +C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ; +C -1 ; WX 444 ; N cacute ; B 25 -14 430 713 ; +C -1 ; WX 556 ; N nacute ; B 21 0 539 713 ; +C -1 ; WX 556 ; N umacron ; B 16 -14 537 637 ; +C -1 ; WX 722 ; N Ncaron ; B 16 -18 701 914 ; +C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; +C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ; +C -1 ; WX 778 ; N Gbreve ; B 37 -19 755 901 ; +C -1 ; WX 389 ; N Idotaccent ; B 20 0 370 901 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ; +C -1 ; WX 444 ; N racute ; B 29 0 434 713 ; +C -1 ; WX 500 ; N omacron ; B 25 -14 476 637 ; +C -1 ; WX 667 ; N Zacute ; B 28 0 634 923 ; +C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ; +C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ; +C -1 ; WX 278 ; N lcommaaccent ; B 16 -218 255 676 ; +C -1 ; WX 416 ; N tcaron ; B 20 -12 425 815 ; +C -1 ; WX 444 ; N eogonek ; B 25 -193 426 473 ; +C -1 ; WX 722 ; N Uogonek ; B 16 -193 701 676 ; +C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ; +C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ; +C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ; +C -1 ; WX 444 ; N zacute ; B 21 0 420 713 ; +C -1 ; WX 278 ; N iogonek ; B 16 -193 274 691 ; +C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ; +C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ; +C -1 ; WX 500 ; N amacron ; B 25 -14 488 637 ; +C -1 ; WX 389 ; N sacute ; B 25 -14 361 713 ; +C -1 ; WX 278 ; N idieresis ; B -37 0 300 667 ; +C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ; +C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ; +C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ; +C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ; +C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ; +C -1 ; WX 278 ; N igrave ; B -27 0 255 713 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 25 -14 529 713 ; +C -1 ; WX 667 ; N Eogonek ; B 16 -193 644 676 ; +C -1 ; WX 556 ; N dcroat ; B 25 -14 534 676 ; +C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ; +C -1 ; WX 556 ; N Scedilla ; B 35 -218 513 692 ; +C -1 ; WX 394 ; N lcaron ; B 16 0 412 682 ; +C -1 ; WX 778 ; N Kcommaaccent ; B 30 -218 769 676 ; +C -1 ; WX 667 ; N Lacute ; B 19 0 638 923 ; +C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ; +C -1 ; WX 444 ; N edotaccent ; B 25 -14 426 691 ; +C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ; +C -1 ; WX 389 ; N Imacron ; B 20 0 370 847 ; +C -1 ; WX 667 ; N Lcaron ; B 19 0 652 682 ; +C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ; +C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 16 -19 701 923 ; +C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ; +C -1 ; WX 444 ; N emacron ; B 25 -14 426 637 ; +C -1 ; WX 500 ; N gbreve ; B 28 -206 483 691 ; +C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ; +C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ; +C -1 ; WX 556 ; N Scommaaccent ; B 35 -218 513 692 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 35 -19 743 923 ; +C -1 ; WX 400 ; N degree ; B 57 402 343 688 ; +C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ; +C -1 ; WX 722 ; N Ccaron ; B 49 -19 687 914 ; +C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B 14 0 690 914 ; +C -1 ; WX 444 ; N rcommaaccent ; B 29 -218 434 473 ; +C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ; +C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 26 -218 715 676 ; +C -1 ; WX 667 ; N Lcommaaccent ; B 19 -218 638 676 ; +C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ; +C -1 ; WX 722 ; N Aogonek ; B 9 -193 699 690 ; +C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ; +C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ; +C -1 ; WX 444 ; N zdotaccent ; B 21 0 420 691 ; +C -1 ; WX 667 ; N Ecaron ; B 16 0 641 914 ; +C -1 ; WX 389 ; N Iogonek ; B 20 -193 370 676 ; +C -1 ; WX 556 ; N kcommaaccent ; B 22 -218 543 676 ; +C -1 ; WX 570 ; N minus ; B 33 209 537 297 ; +C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ; +C -1 ; WX 556 ; N ncaron ; B 21 0 539 704 ; +C -1 ; WX 333 ; N tcommaaccent ; B 20 -218 332 630 ; +C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ; +C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ; +C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 500 ; N gcommaaccent ; B 28 -206 483 829 ; +C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ; +C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ; +C -1 ; WX 556 ; N ncommaaccent ; B 21 -218 539 473 ; +C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ; +C -1 ; WX 278 ; N imacron ; B -8 0 272 637 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2242 +KPX A C -55 +KPX A Cacute -55 +KPX A Ccaron -55 +KPX A Ccedilla -55 +KPX A G -55 +KPX A Gbreve -55 +KPX A Gcommaaccent -55 +KPX A O -45 +KPX A Oacute -45 +KPX A Ocircumflex -45 +KPX A Odieresis -45 +KPX A Ograve -45 +KPX A Ohungarumlaut -45 +KPX A Omacron -45 +KPX A Oslash -45 +KPX A Otilde -45 +KPX A Q -45 +KPX A T -95 +KPX A Tcaron -95 +KPX A Tcommaaccent -95 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -145 +KPX A W -130 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A p -25 +KPX A quoteright -74 +KPX A u -50 +KPX A uacute -50 +KPX A ucircumflex -50 +KPX A udieresis -50 +KPX A ugrave -50 +KPX A uhungarumlaut -50 +KPX A umacron -50 +KPX A uogonek -50 +KPX A uring -50 +KPX A v -100 +KPX A w -90 +KPX A y -74 +KPX A yacute -74 +KPX A ydieresis -74 +KPX Aacute C -55 +KPX Aacute Cacute -55 +KPX Aacute Ccaron -55 +KPX Aacute Ccedilla -55 +KPX Aacute G -55 +KPX Aacute Gbreve -55 +KPX Aacute Gcommaaccent -55 +KPX Aacute O -45 +KPX Aacute Oacute -45 +KPX Aacute Ocircumflex -45 +KPX Aacute Odieresis -45 +KPX Aacute Ograve -45 +KPX Aacute Ohungarumlaut -45 +KPX Aacute Omacron -45 +KPX Aacute Oslash -45 +KPX Aacute Otilde -45 +KPX Aacute Q -45 +KPX Aacute T -95 +KPX Aacute Tcaron -95 +KPX Aacute Tcommaaccent -95 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -145 +KPX Aacute W -130 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute p -25 +KPX Aacute quoteright -74 +KPX Aacute u -50 +KPX Aacute uacute -50 +KPX Aacute ucircumflex -50 +KPX Aacute udieresis -50 +KPX Aacute ugrave -50 +KPX Aacute uhungarumlaut -50 +KPX Aacute umacron -50 +KPX Aacute uogonek -50 +KPX Aacute uring -50 +KPX Aacute v -100 +KPX Aacute w -90 +KPX Aacute y -74 +KPX Aacute yacute -74 +KPX Aacute ydieresis -74 +KPX Abreve C -55 +KPX Abreve Cacute -55 +KPX Abreve Ccaron -55 +KPX Abreve Ccedilla -55 +KPX Abreve G -55 +KPX Abreve Gbreve -55 +KPX Abreve Gcommaaccent -55 +KPX Abreve O -45 +KPX Abreve Oacute -45 +KPX Abreve Ocircumflex -45 +KPX Abreve Odieresis -45 +KPX Abreve Ograve -45 +KPX Abreve Ohungarumlaut -45 +KPX Abreve Omacron -45 +KPX Abreve Oslash -45 +KPX Abreve Otilde -45 +KPX Abreve Q -45 +KPX Abreve T -95 +KPX Abreve Tcaron -95 +KPX Abreve Tcommaaccent -95 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -145 +KPX Abreve W -130 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve p -25 +KPX Abreve quoteright -74 +KPX Abreve u -50 +KPX Abreve uacute -50 +KPX Abreve ucircumflex -50 +KPX Abreve udieresis -50 +KPX Abreve ugrave -50 +KPX Abreve uhungarumlaut -50 +KPX Abreve umacron -50 +KPX Abreve uogonek -50 +KPX Abreve uring -50 +KPX Abreve v -100 +KPX Abreve w -90 +KPX Abreve y -74 +KPX Abreve yacute -74 +KPX Abreve ydieresis -74 +KPX Acircumflex C -55 +KPX Acircumflex Cacute -55 +KPX Acircumflex Ccaron -55 +KPX Acircumflex Ccedilla -55 +KPX Acircumflex G -55 +KPX Acircumflex Gbreve -55 +KPX Acircumflex Gcommaaccent -55 +KPX Acircumflex O -45 +KPX Acircumflex Oacute -45 +KPX Acircumflex Ocircumflex -45 +KPX Acircumflex Odieresis -45 +KPX Acircumflex Ograve -45 +KPX Acircumflex Ohungarumlaut -45 +KPX Acircumflex Omacron -45 +KPX Acircumflex Oslash -45 +KPX Acircumflex Otilde -45 +KPX Acircumflex Q -45 +KPX Acircumflex T -95 +KPX Acircumflex Tcaron -95 +KPX Acircumflex Tcommaaccent -95 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -145 +KPX Acircumflex W -130 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex p -25 +KPX Acircumflex quoteright -74 +KPX Acircumflex u -50 +KPX Acircumflex uacute -50 +KPX Acircumflex ucircumflex -50 +KPX Acircumflex udieresis -50 +KPX Acircumflex ugrave -50 +KPX Acircumflex uhungarumlaut -50 +KPX Acircumflex umacron -50 +KPX Acircumflex uogonek -50 +KPX Acircumflex uring -50 +KPX Acircumflex v -100 +KPX Acircumflex w -90 +KPX Acircumflex y -74 +KPX Acircumflex yacute -74 +KPX Acircumflex ydieresis -74 +KPX Adieresis C -55 +KPX Adieresis Cacute -55 +KPX Adieresis Ccaron -55 +KPX Adieresis Ccedilla -55 +KPX Adieresis G -55 +KPX Adieresis Gbreve -55 +KPX Adieresis Gcommaaccent -55 +KPX Adieresis O -45 +KPX Adieresis Oacute -45 +KPX Adieresis Ocircumflex -45 +KPX Adieresis Odieresis -45 +KPX Adieresis Ograve -45 +KPX Adieresis Ohungarumlaut -45 +KPX Adieresis Omacron -45 +KPX Adieresis Oslash -45 +KPX Adieresis Otilde -45 +KPX Adieresis Q -45 +KPX Adieresis T -95 +KPX Adieresis Tcaron -95 +KPX Adieresis Tcommaaccent -95 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -145 +KPX Adieresis W -130 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis p -25 +KPX Adieresis quoteright -74 +KPX Adieresis u -50 +KPX Adieresis uacute -50 +KPX Adieresis ucircumflex -50 +KPX Adieresis udieresis -50 +KPX Adieresis ugrave -50 +KPX Adieresis uhungarumlaut -50 +KPX Adieresis umacron -50 +KPX Adieresis uogonek -50 +KPX Adieresis uring -50 +KPX Adieresis v -100 +KPX Adieresis w -90 +KPX Adieresis y -74 +KPX Adieresis yacute -74 +KPX Adieresis ydieresis -74 +KPX Agrave C -55 +KPX Agrave Cacute -55 +KPX Agrave Ccaron -55 +KPX Agrave Ccedilla -55 +KPX Agrave G -55 +KPX Agrave Gbreve -55 +KPX Agrave Gcommaaccent -55 +KPX Agrave O -45 +KPX Agrave Oacute -45 +KPX Agrave Ocircumflex -45 +KPX Agrave Odieresis -45 +KPX Agrave Ograve -45 +KPX Agrave Ohungarumlaut -45 +KPX Agrave Omacron -45 +KPX Agrave Oslash -45 +KPX Agrave Otilde -45 +KPX Agrave Q -45 +KPX Agrave T -95 +KPX Agrave Tcaron -95 +KPX Agrave Tcommaaccent -95 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -145 +KPX Agrave W -130 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave p -25 +KPX Agrave quoteright -74 +KPX Agrave u -50 +KPX Agrave uacute -50 +KPX Agrave ucircumflex -50 +KPX Agrave udieresis -50 +KPX Agrave ugrave -50 +KPX Agrave uhungarumlaut -50 +KPX Agrave umacron -50 +KPX Agrave uogonek -50 +KPX Agrave uring -50 +KPX Agrave v -100 +KPX Agrave w -90 +KPX Agrave y -74 +KPX Agrave yacute -74 +KPX Agrave ydieresis -74 +KPX Amacron C -55 +KPX Amacron Cacute -55 +KPX Amacron Ccaron -55 +KPX Amacron Ccedilla -55 +KPX Amacron G -55 +KPX Amacron Gbreve -55 +KPX Amacron Gcommaaccent -55 +KPX Amacron O -45 +KPX Amacron Oacute -45 +KPX Amacron Ocircumflex -45 +KPX Amacron Odieresis -45 +KPX Amacron Ograve -45 +KPX Amacron Ohungarumlaut -45 +KPX Amacron Omacron -45 +KPX Amacron Oslash -45 +KPX Amacron Otilde -45 +KPX Amacron Q -45 +KPX Amacron T -95 +KPX Amacron Tcaron -95 +KPX Amacron Tcommaaccent -95 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -145 +KPX Amacron W -130 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron p -25 +KPX Amacron quoteright -74 +KPX Amacron u -50 +KPX Amacron uacute -50 +KPX Amacron ucircumflex -50 +KPX Amacron udieresis -50 +KPX Amacron ugrave -50 +KPX Amacron uhungarumlaut -50 +KPX Amacron umacron -50 +KPX Amacron uogonek -50 +KPX Amacron uring -50 +KPX Amacron v -100 +KPX Amacron w -90 +KPX Amacron y -74 +KPX Amacron yacute -74 +KPX Amacron ydieresis -74 +KPX Aogonek C -55 +KPX Aogonek Cacute -55 +KPX Aogonek Ccaron -55 +KPX Aogonek Ccedilla -55 +KPX Aogonek G -55 +KPX Aogonek Gbreve -55 +KPX Aogonek Gcommaaccent -55 +KPX Aogonek O -45 +KPX Aogonek Oacute -45 +KPX Aogonek Ocircumflex -45 +KPX Aogonek Odieresis -45 +KPX Aogonek Ograve -45 +KPX Aogonek Ohungarumlaut -45 +KPX Aogonek Omacron -45 +KPX Aogonek Oslash -45 +KPX Aogonek Otilde -45 +KPX Aogonek Q -45 +KPX Aogonek T -95 +KPX Aogonek Tcaron -95 +KPX Aogonek Tcommaaccent -95 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -145 +KPX Aogonek W -130 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek p -25 +KPX Aogonek quoteright -74 +KPX Aogonek u -50 +KPX Aogonek uacute -50 +KPX Aogonek ucircumflex -50 +KPX Aogonek udieresis -50 +KPX Aogonek ugrave -50 +KPX Aogonek uhungarumlaut -50 +KPX Aogonek umacron -50 +KPX Aogonek uogonek -50 +KPX Aogonek uring -50 +KPX Aogonek v -100 +KPX Aogonek w -90 +KPX Aogonek y -34 +KPX Aogonek yacute -34 +KPX Aogonek ydieresis -34 +KPX Aring C -55 +KPX Aring Cacute -55 +KPX Aring Ccaron -55 +KPX Aring Ccedilla -55 +KPX Aring G -55 +KPX Aring Gbreve -55 +KPX Aring Gcommaaccent -55 +KPX Aring O -45 +KPX Aring Oacute -45 +KPX Aring Ocircumflex -45 +KPX Aring Odieresis -45 +KPX Aring Ograve -45 +KPX Aring Ohungarumlaut -45 +KPX Aring Omacron -45 +KPX Aring Oslash -45 +KPX Aring Otilde -45 +KPX Aring Q -45 +KPX Aring T -95 +KPX Aring Tcaron -95 +KPX Aring Tcommaaccent -95 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -145 +KPX Aring W -130 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring p -25 +KPX Aring quoteright -74 +KPX Aring u -50 +KPX Aring uacute -50 +KPX Aring ucircumflex -50 +KPX Aring udieresis -50 +KPX Aring ugrave -50 +KPX Aring uhungarumlaut -50 +KPX Aring umacron -50 +KPX Aring uogonek -50 +KPX Aring uring -50 +KPX Aring v -100 +KPX Aring w -90 +KPX Aring y -74 +KPX Aring yacute -74 +KPX Aring ydieresis -74 +KPX Atilde C -55 +KPX Atilde Cacute -55 +KPX Atilde Ccaron -55 +KPX Atilde Ccedilla -55 +KPX Atilde G -55 +KPX Atilde Gbreve -55 +KPX Atilde Gcommaaccent -55 +KPX Atilde O -45 +KPX Atilde Oacute -45 +KPX Atilde Ocircumflex -45 +KPX Atilde Odieresis -45 +KPX Atilde Ograve -45 +KPX Atilde Ohungarumlaut -45 +KPX Atilde Omacron -45 +KPX Atilde Oslash -45 +KPX Atilde Otilde -45 +KPX Atilde Q -45 +KPX Atilde T -95 +KPX Atilde Tcaron -95 +KPX Atilde Tcommaaccent -95 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -145 +KPX Atilde W -130 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde p -25 +KPX Atilde quoteright -74 +KPX Atilde u -50 +KPX Atilde uacute -50 +KPX Atilde ucircumflex -50 +KPX Atilde udieresis -50 +KPX Atilde ugrave -50 +KPX Atilde uhungarumlaut -50 +KPX Atilde umacron -50 +KPX Atilde uogonek -50 +KPX Atilde uring -50 +KPX Atilde v -100 +KPX Atilde w -90 +KPX Atilde y -74 +KPX Atilde yacute -74 +KPX Atilde ydieresis -74 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -35 +KPX D Aacute -35 +KPX D Abreve -35 +KPX D Acircumflex -35 +KPX D Adieresis -35 +KPX D Agrave -35 +KPX D Amacron -35 +KPX D Aogonek -35 +KPX D Aring -35 +KPX D Atilde -35 +KPX D V -40 +KPX D W -40 +KPX D Y -40 +KPX D Yacute -40 +KPX D Ydieresis -40 +KPX D period -20 +KPX Dcaron A -35 +KPX Dcaron Aacute -35 +KPX Dcaron Abreve -35 +KPX Dcaron Acircumflex -35 +KPX Dcaron Adieresis -35 +KPX Dcaron Agrave -35 +KPX Dcaron Amacron -35 +KPX Dcaron Aogonek -35 +KPX Dcaron Aring -35 +KPX Dcaron Atilde -35 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -40 +KPX Dcaron Yacute -40 +KPX Dcaron Ydieresis -40 +KPX Dcaron period -20 +KPX Dcroat A -35 +KPX Dcroat Aacute -35 +KPX Dcroat Abreve -35 +KPX Dcroat Acircumflex -35 +KPX Dcroat Adieresis -35 +KPX Dcroat Agrave -35 +KPX Dcroat Amacron -35 +KPX Dcroat Aogonek -35 +KPX Dcroat Aring -35 +KPX Dcroat Atilde -35 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -40 +KPX Dcroat Yacute -40 +KPX Dcroat Ydieresis -40 +KPX Dcroat period -20 +KPX F A -90 +KPX F Aacute -90 +KPX F Abreve -90 +KPX F Acircumflex -90 +KPX F Adieresis -90 +KPX F Agrave -90 +KPX F Amacron -90 +KPX F Aogonek -90 +KPX F Aring -90 +KPX F Atilde -90 +KPX F a -25 +KPX F aacute -25 +KPX F abreve -25 +KPX F acircumflex -25 +KPX F adieresis -25 +KPX F agrave -25 +KPX F amacron -25 +KPX F aogonek -25 +KPX F aring -25 +KPX F atilde -25 +KPX F comma -92 +KPX F e -25 +KPX F eacute -25 +KPX F ecaron -25 +KPX F ecircumflex -25 +KPX F edieresis -25 +KPX F edotaccent -25 +KPX F egrave -25 +KPX F emacron -25 +KPX F eogonek -25 +KPX F o -25 +KPX F oacute -25 +KPX F ocircumflex -25 +KPX F odieresis -25 +KPX F ograve -25 +KPX F ohungarumlaut -25 +KPX F omacron -25 +KPX F oslash -25 +KPX F otilde -25 +KPX F period -110 +KPX J A -30 +KPX J Aacute -30 +KPX J Abreve -30 +KPX J Acircumflex -30 +KPX J Adieresis -30 +KPX J Agrave -30 +KPX J Amacron -30 +KPX J Aogonek -30 +KPX J Aring -30 +KPX J Atilde -30 +KPX J a -15 +KPX J aacute -15 +KPX J abreve -15 +KPX J acircumflex -15 +KPX J adieresis -15 +KPX J agrave -15 +KPX J amacron -15 +KPX J aogonek -15 +KPX J aring -15 +KPX J atilde -15 +KPX J e -15 +KPX J eacute -15 +KPX J ecaron -15 +KPX J ecircumflex -15 +KPX J edieresis -15 +KPX J edotaccent -15 +KPX J egrave -15 +KPX J emacron -15 +KPX J eogonek -15 +KPX J o -15 +KPX J oacute -15 +KPX J ocircumflex -15 +KPX J odieresis -15 +KPX J ograve -15 +KPX J ohungarumlaut -15 +KPX J omacron -15 +KPX J oslash -15 +KPX J otilde -15 +KPX J period -20 +KPX J u -15 +KPX J uacute -15 +KPX J ucircumflex -15 +KPX J udieresis -15 +KPX J ugrave -15 +KPX J uhungarumlaut -15 +KPX J umacron -15 +KPX J uogonek -15 +KPX J uring -15 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -25 +KPX K oacute -25 +KPX K ocircumflex -25 +KPX K odieresis -25 +KPX K ograve -25 +KPX K ohungarumlaut -25 +KPX K omacron -25 +KPX K oslash -25 +KPX K otilde -25 +KPX K u -15 +KPX K uacute -15 +KPX K ucircumflex -15 +KPX K udieresis -15 +KPX K ugrave -15 +KPX K uhungarumlaut -15 +KPX K umacron -15 +KPX K uogonek -15 +KPX K uring -15 +KPX K y -45 +KPX K yacute -45 +KPX K ydieresis -45 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -25 +KPX Kcommaaccent oacute -25 +KPX Kcommaaccent ocircumflex -25 +KPX Kcommaaccent odieresis -25 +KPX Kcommaaccent ograve -25 +KPX Kcommaaccent ohungarumlaut -25 +KPX Kcommaaccent omacron -25 +KPX Kcommaaccent oslash -25 +KPX Kcommaaccent otilde -25 +KPX Kcommaaccent u -15 +KPX Kcommaaccent uacute -15 +KPX Kcommaaccent ucircumflex -15 +KPX Kcommaaccent udieresis -15 +KPX Kcommaaccent ugrave -15 +KPX Kcommaaccent uhungarumlaut -15 +KPX Kcommaaccent umacron -15 +KPX Kcommaaccent uogonek -15 +KPX Kcommaaccent uring -15 +KPX Kcommaaccent y -45 +KPX Kcommaaccent yacute -45 +KPX Kcommaaccent ydieresis -45 +KPX L T -92 +KPX L Tcaron -92 +KPX L Tcommaaccent -92 +KPX L V -92 +KPX L W -92 +KPX L Y -92 +KPX L Yacute -92 +KPX L Ydieresis -92 +KPX L quotedblright -20 +KPX L quoteright -110 +KPX L y -55 +KPX L yacute -55 +KPX L ydieresis -55 +KPX Lacute T -92 +KPX Lacute Tcaron -92 +KPX Lacute Tcommaaccent -92 +KPX Lacute V -92 +KPX Lacute W -92 +KPX Lacute Y -92 +KPX Lacute Yacute -92 +KPX Lacute Ydieresis -92 +KPX Lacute quotedblright -20 +KPX Lacute quoteright -110 +KPX Lacute y -55 +KPX Lacute yacute -55 +KPX Lacute ydieresis -55 +KPX Lcommaaccent T -92 +KPX Lcommaaccent Tcaron -92 +KPX Lcommaaccent Tcommaaccent -92 +KPX Lcommaaccent V -92 +KPX Lcommaaccent W -92 +KPX Lcommaaccent Y -92 +KPX Lcommaaccent Yacute -92 +KPX Lcommaaccent Ydieresis -92 +KPX Lcommaaccent quotedblright -20 +KPX Lcommaaccent quoteright -110 +KPX Lcommaaccent y -55 +KPX Lcommaaccent yacute -55 +KPX Lcommaaccent ydieresis -55 +KPX Lslash T -92 +KPX Lslash Tcaron -92 +KPX Lslash Tcommaaccent -92 +KPX Lslash V -92 +KPX Lslash W -92 +KPX Lslash Y -92 +KPX Lslash Yacute -92 +KPX Lslash Ydieresis -92 +KPX Lslash quotedblright -20 +KPX Lslash quoteright -110 +KPX Lslash y -55 +KPX Lslash yacute -55 +KPX Lslash ydieresis -55 +KPX N A -20 +KPX N Aacute -20 +KPX N Abreve -20 +KPX N Acircumflex -20 +KPX N Adieresis -20 +KPX N Agrave -20 +KPX N Amacron -20 +KPX N Aogonek -20 +KPX N Aring -20 +KPX N Atilde -20 +KPX Nacute A -20 +KPX Nacute Aacute -20 +KPX Nacute Abreve -20 +KPX Nacute Acircumflex -20 +KPX Nacute Adieresis -20 +KPX Nacute Agrave -20 +KPX Nacute Amacron -20 +KPX Nacute Aogonek -20 +KPX Nacute Aring -20 +KPX Nacute Atilde -20 +KPX Ncaron A -20 +KPX Ncaron Aacute -20 +KPX Ncaron Abreve -20 +KPX Ncaron Acircumflex -20 +KPX Ncaron Adieresis -20 +KPX Ncaron Agrave -20 +KPX Ncaron Amacron -20 +KPX Ncaron Aogonek -20 +KPX Ncaron Aring -20 +KPX Ncaron Atilde -20 +KPX Ncommaaccent A -20 +KPX Ncommaaccent Aacute -20 +KPX Ncommaaccent Abreve -20 +KPX Ncommaaccent Acircumflex -20 +KPX Ncommaaccent Adieresis -20 +KPX Ncommaaccent Agrave -20 +KPX Ncommaaccent Amacron -20 +KPX Ncommaaccent Aogonek -20 +KPX Ncommaaccent Aring -20 +KPX Ncommaaccent Atilde -20 +KPX Ntilde A -20 +KPX Ntilde Aacute -20 +KPX Ntilde Abreve -20 +KPX Ntilde Acircumflex -20 +KPX Ntilde Adieresis -20 +KPX Ntilde Agrave -20 +KPX Ntilde Amacron -20 +KPX Ntilde Aogonek -20 +KPX Ntilde Aring -20 +KPX Ntilde Atilde -20 +KPX O A -40 +KPX O Aacute -40 +KPX O Abreve -40 +KPX O Acircumflex -40 +KPX O Adieresis -40 +KPX O Agrave -40 +KPX O Amacron -40 +KPX O Aogonek -40 +KPX O Aring -40 +KPX O Atilde -40 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -40 +KPX Oacute Aacute -40 +KPX Oacute Abreve -40 +KPX Oacute Acircumflex -40 +KPX Oacute Adieresis -40 +KPX Oacute Agrave -40 +KPX Oacute Amacron -40 +KPX Oacute Aogonek -40 +KPX Oacute Aring -40 +KPX Oacute Atilde -40 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -40 +KPX Ocircumflex Aacute -40 +KPX Ocircumflex Abreve -40 +KPX Ocircumflex Acircumflex -40 +KPX Ocircumflex Adieresis -40 +KPX Ocircumflex Agrave -40 +KPX Ocircumflex Amacron -40 +KPX Ocircumflex Aogonek -40 +KPX Ocircumflex Aring -40 +KPX Ocircumflex Atilde -40 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -40 +KPX Odieresis Aacute -40 +KPX Odieresis Abreve -40 +KPX Odieresis Acircumflex -40 +KPX Odieresis Adieresis -40 +KPX Odieresis Agrave -40 +KPX Odieresis Amacron -40 +KPX Odieresis Aogonek -40 +KPX Odieresis Aring -40 +KPX Odieresis Atilde -40 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -40 +KPX Ograve Aacute -40 +KPX Ograve Abreve -40 +KPX Ograve Acircumflex -40 +KPX Ograve Adieresis -40 +KPX Ograve Agrave -40 +KPX Ograve Amacron -40 +KPX Ograve Aogonek -40 +KPX Ograve Aring -40 +KPX Ograve Atilde -40 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -40 +KPX Ohungarumlaut Aacute -40 +KPX Ohungarumlaut Abreve -40 +KPX Ohungarumlaut Acircumflex -40 +KPX Ohungarumlaut Adieresis -40 +KPX Ohungarumlaut Agrave -40 +KPX Ohungarumlaut Amacron -40 +KPX Ohungarumlaut Aogonek -40 +KPX Ohungarumlaut Aring -40 +KPX Ohungarumlaut Atilde -40 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -40 +KPX Omacron Aacute -40 +KPX Omacron Abreve -40 +KPX Omacron Acircumflex -40 +KPX Omacron Adieresis -40 +KPX Omacron Agrave -40 +KPX Omacron Amacron -40 +KPX Omacron Aogonek -40 +KPX Omacron Aring -40 +KPX Omacron Atilde -40 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -40 +KPX Oslash Aacute -40 +KPX Oslash Abreve -40 +KPX Oslash Acircumflex -40 +KPX Oslash Adieresis -40 +KPX Oslash Agrave -40 +KPX Oslash Amacron -40 +KPX Oslash Aogonek -40 +KPX Oslash Aring -40 +KPX Oslash Atilde -40 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -40 +KPX Otilde Aacute -40 +KPX Otilde Abreve -40 +KPX Otilde Acircumflex -40 +KPX Otilde Adieresis -40 +KPX Otilde Agrave -40 +KPX Otilde Amacron -40 +KPX Otilde Aogonek -40 +KPX Otilde Aring -40 +KPX Otilde Atilde -40 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -74 +KPX P Aacute -74 +KPX P Abreve -74 +KPX P Acircumflex -74 +KPX P Adieresis -74 +KPX P Agrave -74 +KPX P Amacron -74 +KPX P Aogonek -74 +KPX P Aring -74 +KPX P Atilde -74 +KPX P a -10 +KPX P aacute -10 +KPX P abreve -10 +KPX P acircumflex -10 +KPX P adieresis -10 +KPX P agrave -10 +KPX P amacron -10 +KPX P aogonek -10 +KPX P aring -10 +KPX P atilde -10 +KPX P comma -92 +KPX P e -20 +KPX P eacute -20 +KPX P ecaron -20 +KPX P ecircumflex -20 +KPX P edieresis -20 +KPX P edotaccent -20 +KPX P egrave -20 +KPX P emacron -20 +KPX P eogonek -20 +KPX P o -20 +KPX P oacute -20 +KPX P ocircumflex -20 +KPX P odieresis -20 +KPX P ograve -20 +KPX P ohungarumlaut -20 +KPX P omacron -20 +KPX P oslash -20 +KPX P otilde -20 +KPX P period -110 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q period -20 +KPX R O -30 +KPX R Oacute -30 +KPX R Ocircumflex -30 +KPX R Odieresis -30 +KPX R Ograve -30 +KPX R Ohungarumlaut -30 +KPX R Omacron -30 +KPX R Oslash -30 +KPX R Otilde -30 +KPX R T -40 +KPX R Tcaron -40 +KPX R Tcommaaccent -40 +KPX R U -30 +KPX R Uacute -30 +KPX R Ucircumflex -30 +KPX R Udieresis -30 +KPX R Ugrave -30 +KPX R Uhungarumlaut -30 +KPX R Umacron -30 +KPX R Uogonek -30 +KPX R Uring -30 +KPX R V -55 +KPX R W -35 +KPX R Y -35 +KPX R Yacute -35 +KPX R Ydieresis -35 +KPX Racute O -30 +KPX Racute Oacute -30 +KPX Racute Ocircumflex -30 +KPX Racute Odieresis -30 +KPX Racute Ograve -30 +KPX Racute Ohungarumlaut -30 +KPX Racute Omacron -30 +KPX Racute Oslash -30 +KPX Racute Otilde -30 +KPX Racute T -40 +KPX Racute Tcaron -40 +KPX Racute Tcommaaccent -40 +KPX Racute U -30 +KPX Racute Uacute -30 +KPX Racute Ucircumflex -30 +KPX Racute Udieresis -30 +KPX Racute Ugrave -30 +KPX Racute Uhungarumlaut -30 +KPX Racute Umacron -30 +KPX Racute Uogonek -30 +KPX Racute Uring -30 +KPX Racute V -55 +KPX Racute W -35 +KPX Racute Y -35 +KPX Racute Yacute -35 +KPX Racute Ydieresis -35 +KPX Rcaron O -30 +KPX Rcaron Oacute -30 +KPX Rcaron Ocircumflex -30 +KPX Rcaron Odieresis -30 +KPX Rcaron Ograve -30 +KPX Rcaron Ohungarumlaut -30 +KPX Rcaron Omacron -30 +KPX Rcaron Oslash -30 +KPX Rcaron Otilde -30 +KPX Rcaron T -40 +KPX Rcaron Tcaron -40 +KPX Rcaron Tcommaaccent -40 +KPX Rcaron U -30 +KPX Rcaron Uacute -30 +KPX Rcaron Ucircumflex -30 +KPX Rcaron Udieresis -30 +KPX Rcaron Ugrave -30 +KPX Rcaron Uhungarumlaut -30 +KPX Rcaron Umacron -30 +KPX Rcaron Uogonek -30 +KPX Rcaron Uring -30 +KPX Rcaron V -55 +KPX Rcaron W -35 +KPX Rcaron Y -35 +KPX Rcaron Yacute -35 +KPX Rcaron Ydieresis -35 +KPX Rcommaaccent O -30 +KPX Rcommaaccent Oacute -30 +KPX Rcommaaccent Ocircumflex -30 +KPX Rcommaaccent Odieresis -30 +KPX Rcommaaccent Ograve -30 +KPX Rcommaaccent Ohungarumlaut -30 +KPX Rcommaaccent Omacron -30 +KPX Rcommaaccent Oslash -30 +KPX Rcommaaccent Otilde -30 +KPX Rcommaaccent T -40 +KPX Rcommaaccent Tcaron -40 +KPX Rcommaaccent Tcommaaccent -40 +KPX Rcommaaccent U -30 +KPX Rcommaaccent Uacute -30 +KPX Rcommaaccent Ucircumflex -30 +KPX Rcommaaccent Udieresis -30 +KPX Rcommaaccent Ugrave -30 +KPX Rcommaaccent Uhungarumlaut -30 +KPX Rcommaaccent Umacron -30 +KPX Rcommaaccent Uogonek -30 +KPX Rcommaaccent Uring -30 +KPX Rcommaaccent V -55 +KPX Rcommaaccent W -35 +KPX Rcommaaccent Y -35 +KPX Rcommaaccent Yacute -35 +KPX Rcommaaccent Ydieresis -35 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -52 +KPX T acircumflex -52 +KPX T adieresis -52 +KPX T agrave -52 +KPX T amacron -52 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -52 +KPX T colon -74 +KPX T comma -74 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -92 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -92 +KPX T i -18 +KPX T iacute -18 +KPX T iogonek -18 +KPX T o -92 +KPX T oacute -92 +KPX T ocircumflex -92 +KPX T odieresis -92 +KPX T ograve -92 +KPX T ohungarumlaut -92 +KPX T omacron -92 +KPX T oslash -92 +KPX T otilde -92 +KPX T period -90 +KPX T r -74 +KPX T racute -74 +KPX T rcaron -74 +KPX T rcommaaccent -74 +KPX T semicolon -74 +KPX T u -92 +KPX T uacute -92 +KPX T ucircumflex -92 +KPX T udieresis -92 +KPX T ugrave -92 +KPX T uhungarumlaut -92 +KPX T umacron -92 +KPX T uogonek -92 +KPX T uring -92 +KPX T w -74 +KPX T y -34 +KPX T yacute -34 +KPX T ydieresis -34 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -52 +KPX Tcaron acircumflex -52 +KPX Tcaron adieresis -52 +KPX Tcaron agrave -52 +KPX Tcaron amacron -52 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -52 +KPX Tcaron colon -74 +KPX Tcaron comma -74 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -92 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -92 +KPX Tcaron i -18 +KPX Tcaron iacute -18 +KPX Tcaron iogonek -18 +KPX Tcaron o -92 +KPX Tcaron oacute -92 +KPX Tcaron ocircumflex -92 +KPX Tcaron odieresis -92 +KPX Tcaron ograve -92 +KPX Tcaron ohungarumlaut -92 +KPX Tcaron omacron -92 +KPX Tcaron oslash -92 +KPX Tcaron otilde -92 +KPX Tcaron period -90 +KPX Tcaron r -74 +KPX Tcaron racute -74 +KPX Tcaron rcaron -74 +KPX Tcaron rcommaaccent -74 +KPX Tcaron semicolon -74 +KPX Tcaron u -92 +KPX Tcaron uacute -92 +KPX Tcaron ucircumflex -92 +KPX Tcaron udieresis -92 +KPX Tcaron ugrave -92 +KPX Tcaron uhungarumlaut -92 +KPX Tcaron umacron -92 +KPX Tcaron uogonek -92 +KPX Tcaron uring -92 +KPX Tcaron w -74 +KPX Tcaron y -34 +KPX Tcaron yacute -34 +KPX Tcaron ydieresis -34 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -52 +KPX Tcommaaccent acircumflex -52 +KPX Tcommaaccent adieresis -52 +KPX Tcommaaccent agrave -52 +KPX Tcommaaccent amacron -52 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -52 +KPX Tcommaaccent colon -74 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -92 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -18 +KPX Tcommaaccent iacute -18 +KPX Tcommaaccent iogonek -18 +KPX Tcommaaccent o -92 +KPX Tcommaaccent oacute -92 +KPX Tcommaaccent ocircumflex -92 +KPX Tcommaaccent odieresis -92 +KPX Tcommaaccent ograve -92 +KPX Tcommaaccent ohungarumlaut -92 +KPX Tcommaaccent omacron -92 +KPX Tcommaaccent oslash -92 +KPX Tcommaaccent otilde -92 +KPX Tcommaaccent period -90 +KPX Tcommaaccent r -74 +KPX Tcommaaccent racute -74 +KPX Tcommaaccent rcaron -74 +KPX Tcommaaccent rcommaaccent -74 +KPX Tcommaaccent semicolon -74 +KPX Tcommaaccent u -92 +KPX Tcommaaccent uacute -92 +KPX Tcommaaccent ucircumflex -92 +KPX Tcommaaccent udieresis -92 +KPX Tcommaaccent ugrave -92 +KPX Tcommaaccent uhungarumlaut -92 +KPX Tcommaaccent umacron -92 +KPX Tcommaaccent uogonek -92 +KPX Tcommaaccent uring -92 +KPX Tcommaaccent w -74 +KPX Tcommaaccent y -34 +KPX Tcommaaccent yacute -34 +KPX Tcommaaccent ydieresis -34 +KPX U A -60 +KPX U Aacute -60 +KPX U Abreve -60 +KPX U Acircumflex -60 +KPX U Adieresis -60 +KPX U Agrave -60 +KPX U Amacron -60 +KPX U Aogonek -60 +KPX U Aring -60 +KPX U Atilde -60 +KPX U comma -50 +KPX U period -50 +KPX Uacute A -60 +KPX Uacute Aacute -60 +KPX Uacute Abreve -60 +KPX Uacute Acircumflex -60 +KPX Uacute Adieresis -60 +KPX Uacute Agrave -60 +KPX Uacute Amacron -60 +KPX Uacute Aogonek -60 +KPX Uacute Aring -60 +KPX Uacute Atilde -60 +KPX Uacute comma -50 +KPX Uacute period -50 +KPX Ucircumflex A -60 +KPX Ucircumflex Aacute -60 +KPX Ucircumflex Abreve -60 +KPX Ucircumflex Acircumflex -60 +KPX Ucircumflex Adieresis -60 +KPX Ucircumflex Agrave -60 +KPX Ucircumflex Amacron -60 +KPX Ucircumflex Aogonek -60 +KPX Ucircumflex Aring -60 +KPX Ucircumflex Atilde -60 +KPX Ucircumflex comma -50 +KPX Ucircumflex period -50 +KPX Udieresis A -60 +KPX Udieresis Aacute -60 +KPX Udieresis Abreve -60 +KPX Udieresis Acircumflex -60 +KPX Udieresis Adieresis -60 +KPX Udieresis Agrave -60 +KPX Udieresis Amacron -60 +KPX Udieresis Aogonek -60 +KPX Udieresis Aring -60 +KPX Udieresis Atilde -60 +KPX Udieresis comma -50 +KPX Udieresis period -50 +KPX Ugrave A -60 +KPX Ugrave Aacute -60 +KPX Ugrave Abreve -60 +KPX Ugrave Acircumflex -60 +KPX Ugrave Adieresis -60 +KPX Ugrave Agrave -60 +KPX Ugrave Amacron -60 +KPX Ugrave Aogonek -60 +KPX Ugrave Aring -60 +KPX Ugrave Atilde -60 +KPX Ugrave comma -50 +KPX Ugrave period -50 +KPX Uhungarumlaut A -60 +KPX Uhungarumlaut Aacute -60 +KPX Uhungarumlaut Abreve -60 +KPX Uhungarumlaut Acircumflex -60 +KPX Uhungarumlaut Adieresis -60 +KPX Uhungarumlaut Agrave -60 +KPX Uhungarumlaut Amacron -60 +KPX Uhungarumlaut Aogonek -60 +KPX Uhungarumlaut Aring -60 +KPX Uhungarumlaut Atilde -60 +KPX Uhungarumlaut comma -50 +KPX Uhungarumlaut period -50 +KPX Umacron A -60 +KPX Umacron Aacute -60 +KPX Umacron Abreve -60 +KPX Umacron Acircumflex -60 +KPX Umacron Adieresis -60 +KPX Umacron Agrave -60 +KPX Umacron Amacron -60 +KPX Umacron Aogonek -60 +KPX Umacron Aring -60 +KPX Umacron Atilde -60 +KPX Umacron comma -50 +KPX Umacron period -50 +KPX Uogonek A -60 +KPX Uogonek Aacute -60 +KPX Uogonek Abreve -60 +KPX Uogonek Acircumflex -60 +KPX Uogonek Adieresis -60 +KPX Uogonek Agrave -60 +KPX Uogonek Amacron -60 +KPX Uogonek Aogonek -60 +KPX Uogonek Aring -60 +KPX Uogonek Atilde -60 +KPX Uogonek comma -50 +KPX Uogonek period -50 +KPX Uring A -60 +KPX Uring Aacute -60 +KPX Uring Abreve -60 +KPX Uring Acircumflex -60 +KPX Uring Adieresis -60 +KPX Uring Agrave -60 +KPX Uring Amacron -60 +KPX Uring Aogonek -60 +KPX Uring Aring -60 +KPX Uring Atilde -60 +KPX Uring comma -50 +KPX Uring period -50 +KPX V A -135 +KPX V Aacute -135 +KPX V Abreve -135 +KPX V Acircumflex -135 +KPX V Adieresis -135 +KPX V Agrave -135 +KPX V Amacron -135 +KPX V Aogonek -135 +KPX V Aring -135 +KPX V Atilde -135 +KPX V G -30 +KPX V Gbreve -30 +KPX V Gcommaaccent -30 +KPX V O -45 +KPX V Oacute -45 +KPX V Ocircumflex -45 +KPX V Odieresis -45 +KPX V Ograve -45 +KPX V Ohungarumlaut -45 +KPX V Omacron -45 +KPX V Oslash -45 +KPX V Otilde -45 +KPX V a -92 +KPX V aacute -92 +KPX V abreve -92 +KPX V acircumflex -92 +KPX V adieresis -92 +KPX V agrave -92 +KPX V amacron -92 +KPX V aogonek -92 +KPX V aring -92 +KPX V atilde -92 +KPX V colon -92 +KPX V comma -129 +KPX V e -100 +KPX V eacute -100 +KPX V ecaron -100 +KPX V ecircumflex -100 +KPX V edieresis -100 +KPX V edotaccent -100 +KPX V egrave -100 +KPX V emacron -100 +KPX V eogonek -100 +KPX V hyphen -74 +KPX V i -37 +KPX V iacute -37 +KPX V icircumflex -37 +KPX V idieresis -37 +KPX V igrave -37 +KPX V imacron -37 +KPX V iogonek -37 +KPX V o -100 +KPX V oacute -100 +KPX V ocircumflex -100 +KPX V odieresis -100 +KPX V ograve -100 +KPX V ohungarumlaut -100 +KPX V omacron -100 +KPX V oslash -100 +KPX V otilde -100 +KPX V period -145 +KPX V semicolon -92 +KPX V u -92 +KPX V uacute -92 +KPX V ucircumflex -92 +KPX V udieresis -92 +KPX V ugrave -92 +KPX V uhungarumlaut -92 +KPX V umacron -92 +KPX V uogonek -92 +KPX V uring -92 +KPX W A -120 +KPX W Aacute -120 +KPX W Abreve -120 +KPX W Acircumflex -120 +KPX W Adieresis -120 +KPX W Agrave -120 +KPX W Amacron -120 +KPX W Aogonek -120 +KPX W Aring -120 +KPX W Atilde -120 +KPX W O -10 +KPX W Oacute -10 +KPX W Ocircumflex -10 +KPX W Odieresis -10 +KPX W Ograve -10 +KPX W Ohungarumlaut -10 +KPX W Omacron -10 +KPX W Oslash -10 +KPX W Otilde -10 +KPX W a -65 +KPX W aacute -65 +KPX W abreve -65 +KPX W acircumflex -65 +KPX W adieresis -65 +KPX W agrave -65 +KPX W amacron -65 +KPX W aogonek -65 +KPX W aring -65 +KPX W atilde -65 +KPX W colon -55 +KPX W comma -92 +KPX W e -65 +KPX W eacute -65 +KPX W ecaron -65 +KPX W ecircumflex -65 +KPX W edieresis -65 +KPX W edotaccent -65 +KPX W egrave -65 +KPX W emacron -65 +KPX W eogonek -65 +KPX W hyphen -37 +KPX W i -18 +KPX W iacute -18 +KPX W iogonek -18 +KPX W o -75 +KPX W oacute -75 +KPX W ocircumflex -75 +KPX W odieresis -75 +KPX W ograve -75 +KPX W ohungarumlaut -75 +KPX W omacron -75 +KPX W oslash -75 +KPX W otilde -75 +KPX W period -92 +KPX W semicolon -55 +KPX W u -50 +KPX W uacute -50 +KPX W ucircumflex -50 +KPX W udieresis -50 +KPX W ugrave -50 +KPX W uhungarumlaut -50 +KPX W umacron -50 +KPX W uogonek -50 +KPX W uring -50 +KPX W y -60 +KPX W yacute -60 +KPX W ydieresis -60 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -35 +KPX Y Oacute -35 +KPX Y Ocircumflex -35 +KPX Y Odieresis -35 +KPX Y Ograve -35 +KPX Y Ohungarumlaut -35 +KPX Y Omacron -35 +KPX Y Oslash -35 +KPX Y Otilde -35 +KPX Y a -85 +KPX Y aacute -85 +KPX Y abreve -85 +KPX Y acircumflex -85 +KPX Y adieresis -85 +KPX Y agrave -85 +KPX Y amacron -85 +KPX Y aogonek -85 +KPX Y aring -85 +KPX Y atilde -85 +KPX Y colon -92 +KPX Y comma -92 +KPX Y e -111 +KPX Y eacute -111 +KPX Y ecaron -111 +KPX Y ecircumflex -111 +KPX Y edieresis -71 +KPX Y edotaccent -111 +KPX Y egrave -71 +KPX Y emacron -71 +KPX Y eogonek -111 +KPX Y hyphen -92 +KPX Y i -37 +KPX Y iacute -37 +KPX Y iogonek -37 +KPX Y o -111 +KPX Y oacute -111 +KPX Y ocircumflex -111 +KPX Y odieresis -111 +KPX Y ograve -111 +KPX Y ohungarumlaut -111 +KPX Y omacron -111 +KPX Y oslash -111 +KPX Y otilde -111 +KPX Y period -92 +KPX Y semicolon -92 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -35 +KPX Yacute Oacute -35 +KPX Yacute Ocircumflex -35 +KPX Yacute Odieresis -35 +KPX Yacute Ograve -35 +KPX Yacute Ohungarumlaut -35 +KPX Yacute Omacron -35 +KPX Yacute Oslash -35 +KPX Yacute Otilde -35 +KPX Yacute a -85 +KPX Yacute aacute -85 +KPX Yacute abreve -85 +KPX Yacute acircumflex -85 +KPX Yacute adieresis -85 +KPX Yacute agrave -85 +KPX Yacute amacron -85 +KPX Yacute aogonek -85 +KPX Yacute aring -85 +KPX Yacute atilde -85 +KPX Yacute colon -92 +KPX Yacute comma -92 +KPX Yacute e -111 +KPX Yacute eacute -111 +KPX Yacute ecaron -111 +KPX Yacute ecircumflex -111 +KPX Yacute edieresis -71 +KPX Yacute edotaccent -111 +KPX Yacute egrave -71 +KPX Yacute emacron -71 +KPX Yacute eogonek -111 +KPX Yacute hyphen -92 +KPX Yacute i -37 +KPX Yacute iacute -37 +KPX Yacute iogonek -37 +KPX Yacute o -111 +KPX Yacute oacute -111 +KPX Yacute ocircumflex -111 +KPX Yacute odieresis -111 +KPX Yacute ograve -111 +KPX Yacute ohungarumlaut -111 +KPX Yacute omacron -111 +KPX Yacute oslash -111 +KPX Yacute otilde -111 +KPX Yacute period -92 +KPX Yacute semicolon -92 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -35 +KPX Ydieresis Oacute -35 +KPX Ydieresis Ocircumflex -35 +KPX Ydieresis Odieresis -35 +KPX Ydieresis Ograve -35 +KPX Ydieresis Ohungarumlaut -35 +KPX Ydieresis Omacron -35 +KPX Ydieresis Oslash -35 +KPX Ydieresis Otilde -35 +KPX Ydieresis a -85 +KPX Ydieresis aacute -85 +KPX Ydieresis abreve -85 +KPX Ydieresis acircumflex -85 +KPX Ydieresis adieresis -85 +KPX Ydieresis agrave -85 +KPX Ydieresis amacron -85 +KPX Ydieresis aogonek -85 +KPX Ydieresis aring -85 +KPX Ydieresis atilde -85 +KPX Ydieresis colon -92 +KPX Ydieresis comma -92 +KPX Ydieresis e -111 +KPX Ydieresis eacute -111 +KPX Ydieresis ecaron -111 +KPX Ydieresis ecircumflex -111 +KPX Ydieresis edieresis -71 +KPX Ydieresis edotaccent -111 +KPX Ydieresis egrave -71 +KPX Ydieresis emacron -71 +KPX Ydieresis eogonek -111 +KPX Ydieresis hyphen -92 +KPX Ydieresis i -37 +KPX Ydieresis iacute -37 +KPX Ydieresis iogonek -37 +KPX Ydieresis o -111 +KPX Ydieresis oacute -111 +KPX Ydieresis ocircumflex -111 +KPX Ydieresis odieresis -111 +KPX Ydieresis ograve -111 +KPX Ydieresis ohungarumlaut -111 +KPX Ydieresis omacron -111 +KPX Ydieresis oslash -111 +KPX Ydieresis otilde -111 +KPX Ydieresis period -92 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX a v -25 +KPX aacute v -25 +KPX abreve v -25 +KPX acircumflex v -25 +KPX adieresis v -25 +KPX agrave v -25 +KPX amacron v -25 +KPX aogonek v -25 +KPX aring v -25 +KPX atilde v -25 +KPX b b -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -15 +KPX comma quotedblright -45 +KPX comma quoteright -55 +KPX d w -15 +KPX dcroat w -15 +KPX e v -15 +KPX eacute v -15 +KPX ecaron v -15 +KPX ecircumflex v -15 +KPX edieresis v -15 +KPX edotaccent v -15 +KPX egrave v -15 +KPX emacron v -15 +KPX eogonek v -15 +KPX f comma -15 +KPX f dotlessi -35 +KPX f i -25 +KPX f o -25 +KPX f oacute -25 +KPX f ocircumflex -25 +KPX f odieresis -25 +KPX f ograve -25 +KPX f ohungarumlaut -25 +KPX f omacron -25 +KPX f oslash -25 +KPX f otilde -25 +KPX f period -15 +KPX f quotedblright 50 +KPX f quoteright 55 +KPX g period -15 +KPX gbreve period -15 +KPX gcommaaccent period -15 +KPX h y -15 +KPX h yacute -15 +KPX h ydieresis -15 +KPX i v -10 +KPX iacute v -10 +KPX icircumflex v -10 +KPX idieresis v -10 +KPX igrave v -10 +KPX imacron v -10 +KPX iogonek v -10 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX k y -15 +KPX k yacute -15 +KPX k ydieresis -15 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX kcommaaccent y -15 +KPX kcommaaccent yacute -15 +KPX kcommaaccent ydieresis -15 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o v -10 +KPX o w -10 +KPX oacute v -10 +KPX oacute w -10 +KPX ocircumflex v -10 +KPX ocircumflex w -10 +KPX odieresis v -10 +KPX odieresis w -10 +KPX ograve v -10 +KPX ograve w -10 +KPX ohungarumlaut v -10 +KPX ohungarumlaut w -10 +KPX omacron v -10 +KPX omacron w -10 +KPX oslash v -10 +KPX oslash w -10 +KPX otilde v -10 +KPX otilde w -10 +KPX period quotedblright -55 +KPX period quoteright -55 +KPX quotedblleft A -10 +KPX quotedblleft Aacute -10 +KPX quotedblleft Abreve -10 +KPX quotedblleft Acircumflex -10 +KPX quotedblleft Adieresis -10 +KPX quotedblleft Agrave -10 +KPX quotedblleft Amacron -10 +KPX quotedblleft Aogonek -10 +KPX quotedblleft Aring -10 +KPX quotedblleft Atilde -10 +KPX quoteleft A -10 +KPX quoteleft Aacute -10 +KPX quoteleft Abreve -10 +KPX quoteleft Acircumflex -10 +KPX quoteleft Adieresis -10 +KPX quoteleft Agrave -10 +KPX quoteleft Amacron -10 +KPX quoteleft Aogonek -10 +KPX quoteleft Aring -10 +KPX quoteleft Atilde -10 +KPX quoteleft quoteleft -63 +KPX quoteright d -20 +KPX quoteright dcroat -20 +KPX quoteright quoteright -63 +KPX quoteright r -20 +KPX quoteright racute -20 +KPX quoteright rcaron -20 +KPX quoteright rcommaaccent -20 +KPX quoteright s -37 +KPX quoteright sacute -37 +KPX quoteright scaron -37 +KPX quoteright scedilla -37 +KPX quoteright scommaaccent -37 +KPX quoteright space -74 +KPX quoteright v -20 +KPX r c -18 +KPX r cacute -18 +KPX r ccaron -18 +KPX r ccedilla -18 +KPX r comma -92 +KPX r e -18 +KPX r eacute -18 +KPX r ecaron -18 +KPX r ecircumflex -18 +KPX r edieresis -18 +KPX r edotaccent -18 +KPX r egrave -18 +KPX r emacron -18 +KPX r eogonek -18 +KPX r g -10 +KPX r gbreve -10 +KPX r gcommaaccent -10 +KPX r hyphen -37 +KPX r n -15 +KPX r nacute -15 +KPX r ncaron -15 +KPX r ncommaaccent -15 +KPX r ntilde -15 +KPX r o -18 +KPX r oacute -18 +KPX r ocircumflex -18 +KPX r odieresis -18 +KPX r ograve -18 +KPX r ohungarumlaut -18 +KPX r omacron -18 +KPX r oslash -18 +KPX r otilde -18 +KPX r p -10 +KPX r period -100 +KPX r q -18 +KPX r v -10 +KPX racute c -18 +KPX racute cacute -18 +KPX racute ccaron -18 +KPX racute ccedilla -18 +KPX racute comma -92 +KPX racute e -18 +KPX racute eacute -18 +KPX racute ecaron -18 +KPX racute ecircumflex -18 +KPX racute edieresis -18 +KPX racute edotaccent -18 +KPX racute egrave -18 +KPX racute emacron -18 +KPX racute eogonek -18 +KPX racute g -10 +KPX racute gbreve -10 +KPX racute gcommaaccent -10 +KPX racute hyphen -37 +KPX racute n -15 +KPX racute nacute -15 +KPX racute ncaron -15 +KPX racute ncommaaccent -15 +KPX racute ntilde -15 +KPX racute o -18 +KPX racute oacute -18 +KPX racute ocircumflex -18 +KPX racute odieresis -18 +KPX racute ograve -18 +KPX racute ohungarumlaut -18 +KPX racute omacron -18 +KPX racute oslash -18 +KPX racute otilde -18 +KPX racute p -10 +KPX racute period -100 +KPX racute q -18 +KPX racute v -10 +KPX rcaron c -18 +KPX rcaron cacute -18 +KPX rcaron ccaron -18 +KPX rcaron ccedilla -18 +KPX rcaron comma -92 +KPX rcaron e -18 +KPX rcaron eacute -18 +KPX rcaron ecaron -18 +KPX rcaron ecircumflex -18 +KPX rcaron edieresis -18 +KPX rcaron edotaccent -18 +KPX rcaron egrave -18 +KPX rcaron emacron -18 +KPX rcaron eogonek -18 +KPX rcaron g -10 +KPX rcaron gbreve -10 +KPX rcaron gcommaaccent -10 +KPX rcaron hyphen -37 +KPX rcaron n -15 +KPX rcaron nacute -15 +KPX rcaron ncaron -15 +KPX rcaron ncommaaccent -15 +KPX rcaron ntilde -15 +KPX rcaron o -18 +KPX rcaron oacute -18 +KPX rcaron ocircumflex -18 +KPX rcaron odieresis -18 +KPX rcaron ograve -18 +KPX rcaron ohungarumlaut -18 +KPX rcaron omacron -18 +KPX rcaron oslash -18 +KPX rcaron otilde -18 +KPX rcaron p -10 +KPX rcaron period -100 +KPX rcaron q -18 +KPX rcaron v -10 +KPX rcommaaccent c -18 +KPX rcommaaccent cacute -18 +KPX rcommaaccent ccaron -18 +KPX rcommaaccent ccedilla -18 +KPX rcommaaccent comma -92 +KPX rcommaaccent e -18 +KPX rcommaaccent eacute -18 +KPX rcommaaccent ecaron -18 +KPX rcommaaccent ecircumflex -18 +KPX rcommaaccent edieresis -18 +KPX rcommaaccent edotaccent -18 +KPX rcommaaccent egrave -18 +KPX rcommaaccent emacron -18 +KPX rcommaaccent eogonek -18 +KPX rcommaaccent g -10 +KPX rcommaaccent gbreve -10 +KPX rcommaaccent gcommaaccent -10 +KPX rcommaaccent hyphen -37 +KPX rcommaaccent n -15 +KPX rcommaaccent nacute -15 +KPX rcommaaccent ncaron -15 +KPX rcommaaccent ncommaaccent -15 +KPX rcommaaccent ntilde -15 +KPX rcommaaccent o -18 +KPX rcommaaccent oacute -18 +KPX rcommaaccent ocircumflex -18 +KPX rcommaaccent odieresis -18 +KPX rcommaaccent ograve -18 +KPX rcommaaccent ohungarumlaut -18 +KPX rcommaaccent omacron -18 +KPX rcommaaccent oslash -18 +KPX rcommaaccent otilde -18 +KPX rcommaaccent p -10 +KPX rcommaaccent period -100 +KPX rcommaaccent q -18 +KPX rcommaaccent v -10 +KPX space A -55 +KPX space Aacute -55 +KPX space Abreve -55 +KPX space Acircumflex -55 +KPX space Adieresis -55 +KPX space Agrave -55 +KPX space Amacron -55 +KPX space Aogonek -55 +KPX space Aring -55 +KPX space Atilde -55 +KPX space T -30 +KPX space Tcaron -30 +KPX space Tcommaaccent -30 +KPX space V -45 +KPX space W -30 +KPX space Y -55 +KPX space Yacute -55 +KPX space Ydieresis -55 +KPX v a -10 +KPX v aacute -10 +KPX v abreve -10 +KPX v acircumflex -10 +KPX v adieresis -10 +KPX v agrave -10 +KPX v amacron -10 +KPX v aogonek -10 +KPX v aring -10 +KPX v atilde -10 +KPX v comma -55 +KPX v e -10 +KPX v eacute -10 +KPX v ecaron -10 +KPX v ecircumflex -10 +KPX v edieresis -10 +KPX v edotaccent -10 +KPX v egrave -10 +KPX v emacron -10 +KPX v eogonek -10 +KPX v o -10 +KPX v oacute -10 +KPX v ocircumflex -10 +KPX v odieresis -10 +KPX v ograve -10 +KPX v ohungarumlaut -10 +KPX v omacron -10 +KPX v oslash -10 +KPX v otilde -10 +KPX v period -70 +KPX w comma -55 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -70 +KPX y comma -55 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -70 +KPX yacute comma -55 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -70 +KPX ydieresis comma -55 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -70 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm new file mode 100644 index 00000000..2301dfd2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm @@ -0,0 +1,2384 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 13:04:06 1997 +Comment UniqueID 43066 +Comment VMusage 45874 56899 +FontName Times-BoldItalic +FullName Times Bold Italic +FamilyName Times +Weight Bold +ItalicAngle -15 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -200 -218 996 921 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 669 +XHeight 462 +Ascender 683 +Descender -217 +StdHW 42 +StdVW 121 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ; +C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ; +C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ; +C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ; +C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ; +C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ; +C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ; +C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ; +C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ; +C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ; +C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ; +C 46 ; WX 250 ; N period ; B -9 -13 139 135 ; +C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ; +C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ; +C 49 ; WX 500 ; N one ; B 5 0 419 683 ; +C 50 ; WX 500 ; N two ; B -27 0 446 683 ; +C 51 ; WX 500 ; N three ; B -15 -13 450 683 ; +C 52 ; WX 500 ; N four ; B -15 0 503 683 ; +C 53 ; WX 500 ; N five ; B -11 -13 487 669 ; +C 54 ; WX 500 ; N six ; B 23 -15 509 679 ; +C 55 ; WX 500 ; N seven ; B 52 0 525 669 ; +C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ; +C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ; +C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ; +C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 79 -13 470 684 ; +C 64 ; WX 832 ; N at ; B 63 -18 770 685 ; +C 65 ; WX 667 ; N A ; B -67 0 593 683 ; +C 66 ; WX 667 ; N B ; B -24 0 624 669 ; +C 67 ; WX 667 ; N C ; B 32 -18 677 685 ; +C 68 ; WX 722 ; N D ; B -46 0 685 669 ; +C 69 ; WX 667 ; N E ; B -27 0 653 669 ; +C 70 ; WX 667 ; N F ; B -13 0 660 669 ; +C 71 ; WX 722 ; N G ; B 21 -18 706 685 ; +C 72 ; WX 778 ; N H ; B -24 0 799 669 ; +C 73 ; WX 389 ; N I ; B -32 0 406 669 ; +C 74 ; WX 500 ; N J ; B -46 -99 524 669 ; +C 75 ; WX 667 ; N K ; B -21 0 702 669 ; +C 76 ; WX 611 ; N L ; B -22 0 590 669 ; +C 77 ; WX 889 ; N M ; B -29 -12 917 669 ; +C 78 ; WX 722 ; N N ; B -27 -15 748 669 ; +C 79 ; WX 722 ; N O ; B 27 -18 691 685 ; +C 80 ; WX 611 ; N P ; B -27 0 613 669 ; +C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ; +C 82 ; WX 667 ; N R ; B -29 0 623 669 ; +C 83 ; WX 556 ; N S ; B 2 -18 526 685 ; +C 84 ; WX 611 ; N T ; B 50 0 650 669 ; +C 85 ; WX 722 ; N U ; B 67 -18 744 669 ; +C 86 ; WX 667 ; N V ; B 65 -18 715 669 ; +C 87 ; WX 889 ; N W ; B 65 -18 940 669 ; +C 88 ; WX 667 ; N X ; B -24 0 694 669 ; +C 89 ; WX 611 ; N Y ; B 73 0 659 669 ; +C 90 ; WX 611 ; N Z ; B -11 0 590 669 ; +C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ; +C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ; +C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ; +C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ; +C 97 ; WX 500 ; N a ; B -21 -14 455 462 ; +C 98 ; WX 500 ; N b ; B -14 -13 444 699 ; +C 99 ; WX 444 ; N c ; B -5 -13 392 462 ; +C 100 ; WX 500 ; N d ; B -21 -13 517 699 ; +C 101 ; WX 444 ; N e ; B 5 -13 398 462 ; +C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B -52 -203 478 462 ; +C 104 ; WX 556 ; N h ; B -13 -9 498 699 ; +C 105 ; WX 278 ; N i ; B 2 -9 263 684 ; +C 106 ; WX 278 ; N j ; B -189 -207 279 684 ; +C 107 ; WX 500 ; N k ; B -23 -8 483 699 ; +C 108 ; WX 278 ; N l ; B 2 -9 290 699 ; +C 109 ; WX 778 ; N m ; B -14 -9 722 462 ; +C 110 ; WX 556 ; N n ; B -6 -9 493 462 ; +C 111 ; WX 500 ; N o ; B -3 -13 441 462 ; +C 112 ; WX 500 ; N p ; B -120 -205 446 462 ; +C 113 ; WX 500 ; N q ; B 1 -205 471 462 ; +C 114 ; WX 389 ; N r ; B -21 0 389 462 ; +C 115 ; WX 389 ; N s ; B -19 -13 333 462 ; +C 116 ; WX 278 ; N t ; B -11 -9 281 594 ; +C 117 ; WX 556 ; N u ; B 15 -9 492 462 ; +C 118 ; WX 444 ; N v ; B 16 -13 401 462 ; +C 119 ; WX 667 ; N w ; B 16 -13 614 462 ; +C 120 ; WX 500 ; N x ; B -46 -13 469 462 ; +C 121 ; WX 444 ; N y ; B -94 -205 392 462 ; +C 122 ; WX 389 ; N z ; B -43 -78 368 449 ; +C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ; +C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; +C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ; +C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ; +C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ; +C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ; +C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ; +C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ; +C 165 ; WX 500 ; N yen ; B 33 0 628 669 ; +C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ; +C 167 ; WX 500 ; N section ; B 36 -143 459 685 ; +C 168 ; WX 500 ; N currency ; B -26 34 526 586 ; +C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ; +C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ; +C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ; +C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ; +C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ; +C 177 ; WX 500 ; N endash ; B -40 178 477 269 ; +C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ; +C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ; +C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ; +C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ; +C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ; +C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ; +C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ; +C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ; +C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ; +C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ; +C 193 ; WX 333 ; N grave ; B 85 516 297 697 ; +C 194 ; WX 333 ; N acute ; B 139 516 379 697 ; +C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ; +C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ; +C 197 ; WX 333 ; N macron ; B 51 553 393 623 ; +C 198 ; WX 333 ; N breve ; B 71 516 387 678 ; +C 199 ; WX 333 ; N dotaccent ; B 163 550 298 684 ; +C 200 ; WX 333 ; N dieresis ; B 55 550 402 684 ; +C 202 ; WX 333 ; N ring ; B 127 516 340 729 ; +C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ; +C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ; +C 206 ; WX 333 ; N ogonek ; B 15 -183 244 34 ; +C 207 ; WX 333 ; N caron ; B 79 516 411 690 ; +C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ; +C 225 ; WX 944 ; N AE ; B -64 0 918 669 ; +C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ; +C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ; +C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ; +C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ; +C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ; +C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ; +C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ; +C 248 ; WX 278 ; N lslash ; B -7 -9 307 699 ; +C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ; +C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ; +C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ; +C -1 ; WX 389 ; N Idieresis ; B -32 0 450 862 ; +C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ; +C -1 ; WX 500 ; N abreve ; B -21 -14 471 678 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 15 -9 610 697 ; +C -1 ; WX 444 ; N ecaron ; B 5 -13 467 690 ; +C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ; +C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ; +C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ; +C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ; +C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ; +C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ; +C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ; +C -1 ; WX 389 ; N scommaaccent ; B -19 -218 333 462 ; +C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ; +C -1 ; WX 722 ; N Uring ; B 67 -18 744 921 ; +C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ; +C -1 ; WX 500 ; N aogonek ; B -21 -183 455 462 ; +C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ; +C -1 ; WX 556 ; N uogonek ; B 15 -183 492 462 ; +C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ; +C -1 ; WX 722 ; N Dcroat ; B -31 0 700 669 ; +C -1 ; WX 250 ; N commaaccent ; B -36 -218 131 -50 ; +C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ; +C -1 ; WX 667 ; N Emacron ; B -27 0 653 830 ; +C -1 ; WX 444 ; N ccaron ; B -5 -13 467 690 ; +C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ; +C -1 ; WX 722 ; N Ncommaaccent ; B -27 -218 748 669 ; +C -1 ; WX 278 ; N lacute ; B 2 -9 392 904 ; +C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 50 -218 650 669 ; +C -1 ; WX 667 ; N Cacute ; B 32 -18 677 904 ; +C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ; +C -1 ; WX 667 ; N Edotaccent ; B -27 0 653 862 ; +C -1 ; WX 389 ; N scaron ; B -19 -13 424 690 ; +C -1 ; WX 389 ; N scedilla ; B -19 -218 333 462 ; +C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 667 ; N Rcaron ; B -29 0 623 897 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 21 -218 706 685 ; +C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ; +C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ; +C -1 ; WX 667 ; N Amacron ; B -67 0 593 830 ; +C -1 ; WX 389 ; N rcaron ; B -21 0 424 690 ; +C -1 ; WX 444 ; N ccedilla ; B -5 -218 392 462 ; +C -1 ; WX 611 ; N Zdotaccent ; B -11 0 590 862 ; +C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ; +C -1 ; WX 722 ; N Omacron ; B 27 -18 691 830 ; +C -1 ; WX 667 ; N Racute ; B -29 0 623 904 ; +C -1 ; WX 556 ; N Sacute ; B 2 -18 531 904 ; +C -1 ; WX 608 ; N dcaron ; B -21 -13 675 708 ; +C -1 ; WX 722 ; N Umacron ; B 67 -18 744 830 ; +C -1 ; WX 556 ; N uring ; B 15 -9 492 729 ; +C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ; +C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ; +C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ; +C -1 ; WX 667 ; N Abreve ; B -67 0 593 885 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ; +C -1 ; WX 611 ; N Tcaron ; B 50 0 650 897 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 444 ; N ydieresis ; B -94 -205 443 655 ; +C -1 ; WX 722 ; N Nacute ; B -27 -15 748 904 ; +C -1 ; WX 278 ; N icircumflex ; B -3 -9 324 690 ; +C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ; +C -1 ; WX 500 ; N adieresis ; B -21 -14 476 655 ; +C -1 ; WX 444 ; N edieresis ; B 5 -13 448 655 ; +C -1 ; WX 444 ; N cacute ; B -5 -13 435 697 ; +C -1 ; WX 556 ; N nacute ; B -6 -9 493 697 ; +C -1 ; WX 556 ; N umacron ; B 15 -9 492 623 ; +C -1 ; WX 722 ; N Ncaron ; B -27 -15 748 897 ; +C -1 ; WX 389 ; N Iacute ; B -32 0 432 904 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; +C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ; +C -1 ; WX 722 ; N Gbreve ; B 21 -18 706 885 ; +C -1 ; WX 389 ; N Idotaccent ; B -32 0 406 862 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ; +C -1 ; WX 389 ; N racute ; B -21 0 407 697 ; +C -1 ; WX 500 ; N omacron ; B -3 -13 462 623 ; +C -1 ; WX 611 ; N Zacute ; B -11 0 590 904 ; +C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ; +C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ; +C -1 ; WX 278 ; N lcommaaccent ; B -42 -218 290 699 ; +C -1 ; WX 366 ; N tcaron ; B -11 -9 434 754 ; +C -1 ; WX 444 ; N eogonek ; B 5 -183 398 462 ; +C -1 ; WX 722 ; N Uogonek ; B 67 -183 744 669 ; +C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ; +C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ; +C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ; +C -1 ; WX 389 ; N zacute ; B -43 -78 407 697 ; +C -1 ; WX 278 ; N iogonek ; B -20 -183 263 684 ; +C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ; +C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ; +C -1 ; WX 500 ; N amacron ; B -21 -14 467 623 ; +C -1 ; WX 389 ; N sacute ; B -19 -13 407 697 ; +C -1 ; WX 278 ; N idieresis ; B 2 -9 364 655 ; +C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ; +C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ; +C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ; +C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ; +C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ; +C -1 ; WX 278 ; N igrave ; B 2 -9 259 697 ; +C -1 ; WX 500 ; N ohungarumlaut ; B -3 -13 582 697 ; +C -1 ; WX 667 ; N Eogonek ; B -27 -183 653 669 ; +C -1 ; WX 500 ; N dcroat ; B -21 -13 552 699 ; +C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ; +C -1 ; WX 556 ; N Scedilla ; B 2 -218 526 685 ; +C -1 ; WX 382 ; N lcaron ; B 2 -9 448 708 ; +C -1 ; WX 667 ; N Kcommaaccent ; B -21 -218 702 669 ; +C -1 ; WX 611 ; N Lacute ; B -22 0 590 904 ; +C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ; +C -1 ; WX 444 ; N edotaccent ; B 5 -13 398 655 ; +C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ; +C -1 ; WX 389 ; N Imacron ; B -32 0 461 830 ; +C -1 ; WX 611 ; N Lcaron ; B -22 0 671 718 ; +C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ; +C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 67 -18 744 904 ; +C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ; +C -1 ; WX 444 ; N emacron ; B 5 -13 439 623 ; +C -1 ; WX 500 ; N gbreve ; B -52 -203 478 678 ; +C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ; +C -1 ; WX 556 ; N Scaron ; B 2 -18 553 897 ; +C -1 ; WX 556 ; N Scommaaccent ; B 2 -218 526 685 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 27 -18 723 904 ; +C -1 ; WX 400 ; N degree ; B 83 397 369 683 ; +C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ; +C -1 ; WX 667 ; N Ccaron ; B 32 -18 677 897 ; +C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B -46 0 685 897 ; +C -1 ; WX 389 ; N rcommaaccent ; B -67 -218 389 462 ; +C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ; +C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ; +C -1 ; WX 667 ; N Rcommaaccent ; B -29 -218 623 669 ; +C -1 ; WX 611 ; N Lcommaaccent ; B -22 -218 590 669 ; +C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ; +C -1 ; WX 667 ; N Aogonek ; B -67 -183 604 683 ; +C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ; +C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ; +C -1 ; WX 389 ; N zdotaccent ; B -43 -78 368 655 ; +C -1 ; WX 667 ; N Ecaron ; B -27 0 653 897 ; +C -1 ; WX 389 ; N Iogonek ; B -32 -183 406 669 ; +C -1 ; WX 500 ; N kcommaaccent ; B -23 -218 483 699 ; +C -1 ; WX 606 ; N minus ; B 51 209 555 297 ; +C -1 ; WX 389 ; N Icircumflex ; B -32 0 450 897 ; +C -1 ; WX 556 ; N ncaron ; B -6 -9 523 690 ; +C -1 ; WX 278 ; N tcommaaccent ; B -62 -218 281 594 ; +C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ; +C -1 ; WX 500 ; N odieresis ; B -3 -13 471 655 ; +C -1 ; WX 556 ; N udieresis ; B 15 -9 499 655 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 500 ; N gcommaaccent ; B -52 -203 478 767 ; +C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ; +C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ; +C -1 ; WX 556 ; N ncommaaccent ; B -6 -218 493 462 ; +C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ; +C -1 ; WX 278 ; N imacron ; B 2 -9 294 623 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2038 +KPX A C -65 +KPX A Cacute -65 +KPX A Ccaron -65 +KPX A Ccedilla -65 +KPX A G -60 +KPX A Gbreve -60 +KPX A Gcommaaccent -60 +KPX A O -50 +KPX A Oacute -50 +KPX A Ocircumflex -50 +KPX A Odieresis -50 +KPX A Ograve -50 +KPX A Ohungarumlaut -50 +KPX A Omacron -50 +KPX A Oslash -50 +KPX A Otilde -50 +KPX A Q -55 +KPX A T -55 +KPX A Tcaron -55 +KPX A Tcommaaccent -55 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -95 +KPX A W -100 +KPX A Y -70 +KPX A Yacute -70 +KPX A Ydieresis -70 +KPX A quoteright -74 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -74 +KPX A w -74 +KPX A y -74 +KPX A yacute -74 +KPX A ydieresis -74 +KPX Aacute C -65 +KPX Aacute Cacute -65 +KPX Aacute Ccaron -65 +KPX Aacute Ccedilla -65 +KPX Aacute G -60 +KPX Aacute Gbreve -60 +KPX Aacute Gcommaaccent -60 +KPX Aacute O -50 +KPX Aacute Oacute -50 +KPX Aacute Ocircumflex -50 +KPX Aacute Odieresis -50 +KPX Aacute Ograve -50 +KPX Aacute Ohungarumlaut -50 +KPX Aacute Omacron -50 +KPX Aacute Oslash -50 +KPX Aacute Otilde -50 +KPX Aacute Q -55 +KPX Aacute T -55 +KPX Aacute Tcaron -55 +KPX Aacute Tcommaaccent -55 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -95 +KPX Aacute W -100 +KPX Aacute Y -70 +KPX Aacute Yacute -70 +KPX Aacute Ydieresis -70 +KPX Aacute quoteright -74 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -74 +KPX Aacute w -74 +KPX Aacute y -74 +KPX Aacute yacute -74 +KPX Aacute ydieresis -74 +KPX Abreve C -65 +KPX Abreve Cacute -65 +KPX Abreve Ccaron -65 +KPX Abreve Ccedilla -65 +KPX Abreve G -60 +KPX Abreve Gbreve -60 +KPX Abreve Gcommaaccent -60 +KPX Abreve O -50 +KPX Abreve Oacute -50 +KPX Abreve Ocircumflex -50 +KPX Abreve Odieresis -50 +KPX Abreve Ograve -50 +KPX Abreve Ohungarumlaut -50 +KPX Abreve Omacron -50 +KPX Abreve Oslash -50 +KPX Abreve Otilde -50 +KPX Abreve Q -55 +KPX Abreve T -55 +KPX Abreve Tcaron -55 +KPX Abreve Tcommaaccent -55 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -95 +KPX Abreve W -100 +KPX Abreve Y -70 +KPX Abreve Yacute -70 +KPX Abreve Ydieresis -70 +KPX Abreve quoteright -74 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -74 +KPX Abreve w -74 +KPX Abreve y -74 +KPX Abreve yacute -74 +KPX Abreve ydieresis -74 +KPX Acircumflex C -65 +KPX Acircumflex Cacute -65 +KPX Acircumflex Ccaron -65 +KPX Acircumflex Ccedilla -65 +KPX Acircumflex G -60 +KPX Acircumflex Gbreve -60 +KPX Acircumflex Gcommaaccent -60 +KPX Acircumflex O -50 +KPX Acircumflex Oacute -50 +KPX Acircumflex Ocircumflex -50 +KPX Acircumflex Odieresis -50 +KPX Acircumflex Ograve -50 +KPX Acircumflex Ohungarumlaut -50 +KPX Acircumflex Omacron -50 +KPX Acircumflex Oslash -50 +KPX Acircumflex Otilde -50 +KPX Acircumflex Q -55 +KPX Acircumflex T -55 +KPX Acircumflex Tcaron -55 +KPX Acircumflex Tcommaaccent -55 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -95 +KPX Acircumflex W -100 +KPX Acircumflex Y -70 +KPX Acircumflex Yacute -70 +KPX Acircumflex Ydieresis -70 +KPX Acircumflex quoteright -74 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -74 +KPX Acircumflex w -74 +KPX Acircumflex y -74 +KPX Acircumflex yacute -74 +KPX Acircumflex ydieresis -74 +KPX Adieresis C -65 +KPX Adieresis Cacute -65 +KPX Adieresis Ccaron -65 +KPX Adieresis Ccedilla -65 +KPX Adieresis G -60 +KPX Adieresis Gbreve -60 +KPX Adieresis Gcommaaccent -60 +KPX Adieresis O -50 +KPX Adieresis Oacute -50 +KPX Adieresis Ocircumflex -50 +KPX Adieresis Odieresis -50 +KPX Adieresis Ograve -50 +KPX Adieresis Ohungarumlaut -50 +KPX Adieresis Omacron -50 +KPX Adieresis Oslash -50 +KPX Adieresis Otilde -50 +KPX Adieresis Q -55 +KPX Adieresis T -55 +KPX Adieresis Tcaron -55 +KPX Adieresis Tcommaaccent -55 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -95 +KPX Adieresis W -100 +KPX Adieresis Y -70 +KPX Adieresis Yacute -70 +KPX Adieresis Ydieresis -70 +KPX Adieresis quoteright -74 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -74 +KPX Adieresis w -74 +KPX Adieresis y -74 +KPX Adieresis yacute -74 +KPX Adieresis ydieresis -74 +KPX Agrave C -65 +KPX Agrave Cacute -65 +KPX Agrave Ccaron -65 +KPX Agrave Ccedilla -65 +KPX Agrave G -60 +KPX Agrave Gbreve -60 +KPX Agrave Gcommaaccent -60 +KPX Agrave O -50 +KPX Agrave Oacute -50 +KPX Agrave Ocircumflex -50 +KPX Agrave Odieresis -50 +KPX Agrave Ograve -50 +KPX Agrave Ohungarumlaut -50 +KPX Agrave Omacron -50 +KPX Agrave Oslash -50 +KPX Agrave Otilde -50 +KPX Agrave Q -55 +KPX Agrave T -55 +KPX Agrave Tcaron -55 +KPX Agrave Tcommaaccent -55 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -95 +KPX Agrave W -100 +KPX Agrave Y -70 +KPX Agrave Yacute -70 +KPX Agrave Ydieresis -70 +KPX Agrave quoteright -74 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -74 +KPX Agrave w -74 +KPX Agrave y -74 +KPX Agrave yacute -74 +KPX Agrave ydieresis -74 +KPX Amacron C -65 +KPX Amacron Cacute -65 +KPX Amacron Ccaron -65 +KPX Amacron Ccedilla -65 +KPX Amacron G -60 +KPX Amacron Gbreve -60 +KPX Amacron Gcommaaccent -60 +KPX Amacron O -50 +KPX Amacron Oacute -50 +KPX Amacron Ocircumflex -50 +KPX Amacron Odieresis -50 +KPX Amacron Ograve -50 +KPX Amacron Ohungarumlaut -50 +KPX Amacron Omacron -50 +KPX Amacron Oslash -50 +KPX Amacron Otilde -50 +KPX Amacron Q -55 +KPX Amacron T -55 +KPX Amacron Tcaron -55 +KPX Amacron Tcommaaccent -55 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -95 +KPX Amacron W -100 +KPX Amacron Y -70 +KPX Amacron Yacute -70 +KPX Amacron Ydieresis -70 +KPX Amacron quoteright -74 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -74 +KPX Amacron w -74 +KPX Amacron y -74 +KPX Amacron yacute -74 +KPX Amacron ydieresis -74 +KPX Aogonek C -65 +KPX Aogonek Cacute -65 +KPX Aogonek Ccaron -65 +KPX Aogonek Ccedilla -65 +KPX Aogonek G -60 +KPX Aogonek Gbreve -60 +KPX Aogonek Gcommaaccent -60 +KPX Aogonek O -50 +KPX Aogonek Oacute -50 +KPX Aogonek Ocircumflex -50 +KPX Aogonek Odieresis -50 +KPX Aogonek Ograve -50 +KPX Aogonek Ohungarumlaut -50 +KPX Aogonek Omacron -50 +KPX Aogonek Oslash -50 +KPX Aogonek Otilde -50 +KPX Aogonek Q -55 +KPX Aogonek T -55 +KPX Aogonek Tcaron -55 +KPX Aogonek Tcommaaccent -55 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -95 +KPX Aogonek W -100 +KPX Aogonek Y -70 +KPX Aogonek Yacute -70 +KPX Aogonek Ydieresis -70 +KPX Aogonek quoteright -74 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -74 +KPX Aogonek w -74 +KPX Aogonek y -34 +KPX Aogonek yacute -34 +KPX Aogonek ydieresis -34 +KPX Aring C -65 +KPX Aring Cacute -65 +KPX Aring Ccaron -65 +KPX Aring Ccedilla -65 +KPX Aring G -60 +KPX Aring Gbreve -60 +KPX Aring Gcommaaccent -60 +KPX Aring O -50 +KPX Aring Oacute -50 +KPX Aring Ocircumflex -50 +KPX Aring Odieresis -50 +KPX Aring Ograve -50 +KPX Aring Ohungarumlaut -50 +KPX Aring Omacron -50 +KPX Aring Oslash -50 +KPX Aring Otilde -50 +KPX Aring Q -55 +KPX Aring T -55 +KPX Aring Tcaron -55 +KPX Aring Tcommaaccent -55 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -95 +KPX Aring W -100 +KPX Aring Y -70 +KPX Aring Yacute -70 +KPX Aring Ydieresis -70 +KPX Aring quoteright -74 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -74 +KPX Aring w -74 +KPX Aring y -74 +KPX Aring yacute -74 +KPX Aring ydieresis -74 +KPX Atilde C -65 +KPX Atilde Cacute -65 +KPX Atilde Ccaron -65 +KPX Atilde Ccedilla -65 +KPX Atilde G -60 +KPX Atilde Gbreve -60 +KPX Atilde Gcommaaccent -60 +KPX Atilde O -50 +KPX Atilde Oacute -50 +KPX Atilde Ocircumflex -50 +KPX Atilde Odieresis -50 +KPX Atilde Ograve -50 +KPX Atilde Ohungarumlaut -50 +KPX Atilde Omacron -50 +KPX Atilde Oslash -50 +KPX Atilde Otilde -50 +KPX Atilde Q -55 +KPX Atilde T -55 +KPX Atilde Tcaron -55 +KPX Atilde Tcommaaccent -55 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -95 +KPX Atilde W -100 +KPX Atilde Y -70 +KPX Atilde Yacute -70 +KPX Atilde Ydieresis -70 +KPX Atilde quoteright -74 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -74 +KPX Atilde w -74 +KPX Atilde y -74 +KPX Atilde yacute -74 +KPX Atilde ydieresis -74 +KPX B A -25 +KPX B Aacute -25 +KPX B Abreve -25 +KPX B Acircumflex -25 +KPX B Adieresis -25 +KPX B Agrave -25 +KPX B Amacron -25 +KPX B Aogonek -25 +KPX B Aring -25 +KPX B Atilde -25 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -25 +KPX D Aacute -25 +KPX D Abreve -25 +KPX D Acircumflex -25 +KPX D Adieresis -25 +KPX D Agrave -25 +KPX D Amacron -25 +KPX D Aogonek -25 +KPX D Aring -25 +KPX D Atilde -25 +KPX D V -50 +KPX D W -40 +KPX D Y -50 +KPX D Yacute -50 +KPX D Ydieresis -50 +KPX Dcaron A -25 +KPX Dcaron Aacute -25 +KPX Dcaron Abreve -25 +KPX Dcaron Acircumflex -25 +KPX Dcaron Adieresis -25 +KPX Dcaron Agrave -25 +KPX Dcaron Amacron -25 +KPX Dcaron Aogonek -25 +KPX Dcaron Aring -25 +KPX Dcaron Atilde -25 +KPX Dcaron V -50 +KPX Dcaron W -40 +KPX Dcaron Y -50 +KPX Dcaron Yacute -50 +KPX Dcaron Ydieresis -50 +KPX Dcroat A -25 +KPX Dcroat Aacute -25 +KPX Dcroat Abreve -25 +KPX Dcroat Acircumflex -25 +KPX Dcroat Adieresis -25 +KPX Dcroat Agrave -25 +KPX Dcroat Amacron -25 +KPX Dcroat Aogonek -25 +KPX Dcroat Aring -25 +KPX Dcroat Atilde -25 +KPX Dcroat V -50 +KPX Dcroat W -40 +KPX Dcroat Y -50 +KPX Dcroat Yacute -50 +KPX Dcroat Ydieresis -50 +KPX F A -100 +KPX F Aacute -100 +KPX F Abreve -100 +KPX F Acircumflex -100 +KPX F Adieresis -100 +KPX F Agrave -100 +KPX F Amacron -100 +KPX F Aogonek -100 +KPX F Aring -100 +KPX F Atilde -100 +KPX F a -95 +KPX F aacute -95 +KPX F abreve -95 +KPX F acircumflex -95 +KPX F adieresis -95 +KPX F agrave -95 +KPX F amacron -95 +KPX F aogonek -95 +KPX F aring -95 +KPX F atilde -95 +KPX F comma -129 +KPX F e -100 +KPX F eacute -100 +KPX F ecaron -100 +KPX F ecircumflex -100 +KPX F edieresis -100 +KPX F edotaccent -100 +KPX F egrave -100 +KPX F emacron -100 +KPX F eogonek -100 +KPX F i -40 +KPX F iacute -40 +KPX F icircumflex -40 +KPX F idieresis -40 +KPX F igrave -40 +KPX F imacron -40 +KPX F iogonek -40 +KPX F o -70 +KPX F oacute -70 +KPX F ocircumflex -70 +KPX F odieresis -70 +KPX F ograve -70 +KPX F ohungarumlaut -70 +KPX F omacron -70 +KPX F oslash -70 +KPX F otilde -70 +KPX F period -129 +KPX F r -50 +KPX F racute -50 +KPX F rcaron -50 +KPX F rcommaaccent -50 +KPX J A -25 +KPX J Aacute -25 +KPX J Abreve -25 +KPX J Acircumflex -25 +KPX J Adieresis -25 +KPX J Agrave -25 +KPX J Amacron -25 +KPX J Aogonek -25 +KPX J Aring -25 +KPX J Atilde -25 +KPX J a -40 +KPX J aacute -40 +KPX J abreve -40 +KPX J acircumflex -40 +KPX J adieresis -40 +KPX J agrave -40 +KPX J amacron -40 +KPX J aogonek -40 +KPX J aring -40 +KPX J atilde -40 +KPX J comma -10 +KPX J e -40 +KPX J eacute -40 +KPX J ecaron -40 +KPX J ecircumflex -40 +KPX J edieresis -40 +KPX J edotaccent -40 +KPX J egrave -40 +KPX J emacron -40 +KPX J eogonek -40 +KPX J o -40 +KPX J oacute -40 +KPX J ocircumflex -40 +KPX J odieresis -40 +KPX J ograve -40 +KPX J ohungarumlaut -40 +KPX J omacron -40 +KPX J oslash -40 +KPX J otilde -40 +KPX J period -10 +KPX J u -40 +KPX J uacute -40 +KPX J ucircumflex -40 +KPX J udieresis -40 +KPX J ugrave -40 +KPX J uhungarumlaut -40 +KPX J umacron -40 +KPX J uogonek -40 +KPX J uring -40 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -25 +KPX K oacute -25 +KPX K ocircumflex -25 +KPX K odieresis -25 +KPX K ograve -25 +KPX K ohungarumlaut -25 +KPX K omacron -25 +KPX K oslash -25 +KPX K otilde -25 +KPX K u -20 +KPX K uacute -20 +KPX K ucircumflex -20 +KPX K udieresis -20 +KPX K ugrave -20 +KPX K uhungarumlaut -20 +KPX K umacron -20 +KPX K uogonek -20 +KPX K uring -20 +KPX K y -20 +KPX K yacute -20 +KPX K ydieresis -20 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -25 +KPX Kcommaaccent oacute -25 +KPX Kcommaaccent ocircumflex -25 +KPX Kcommaaccent odieresis -25 +KPX Kcommaaccent ograve -25 +KPX Kcommaaccent ohungarumlaut -25 +KPX Kcommaaccent omacron -25 +KPX Kcommaaccent oslash -25 +KPX Kcommaaccent otilde -25 +KPX Kcommaaccent u -20 +KPX Kcommaaccent uacute -20 +KPX Kcommaaccent ucircumflex -20 +KPX Kcommaaccent udieresis -20 +KPX Kcommaaccent ugrave -20 +KPX Kcommaaccent uhungarumlaut -20 +KPX Kcommaaccent umacron -20 +KPX Kcommaaccent uogonek -20 +KPX Kcommaaccent uring -20 +KPX Kcommaaccent y -20 +KPX Kcommaaccent yacute -20 +KPX Kcommaaccent ydieresis -20 +KPX L T -18 +KPX L Tcaron -18 +KPX L Tcommaaccent -18 +KPX L V -37 +KPX L W -37 +KPX L Y -37 +KPX L Yacute -37 +KPX L Ydieresis -37 +KPX L quoteright -55 +KPX L y -37 +KPX L yacute -37 +KPX L ydieresis -37 +KPX Lacute T -18 +KPX Lacute Tcaron -18 +KPX Lacute Tcommaaccent -18 +KPX Lacute V -37 +KPX Lacute W -37 +KPX Lacute Y -37 +KPX Lacute Yacute -37 +KPX Lacute Ydieresis -37 +KPX Lacute quoteright -55 +KPX Lacute y -37 +KPX Lacute yacute -37 +KPX Lacute ydieresis -37 +KPX Lcommaaccent T -18 +KPX Lcommaaccent Tcaron -18 +KPX Lcommaaccent Tcommaaccent -18 +KPX Lcommaaccent V -37 +KPX Lcommaaccent W -37 +KPX Lcommaaccent Y -37 +KPX Lcommaaccent Yacute -37 +KPX Lcommaaccent Ydieresis -37 +KPX Lcommaaccent quoteright -55 +KPX Lcommaaccent y -37 +KPX Lcommaaccent yacute -37 +KPX Lcommaaccent ydieresis -37 +KPX Lslash T -18 +KPX Lslash Tcaron -18 +KPX Lslash Tcommaaccent -18 +KPX Lslash V -37 +KPX Lslash W -37 +KPX Lslash Y -37 +KPX Lslash Yacute -37 +KPX Lslash Ydieresis -37 +KPX Lslash quoteright -55 +KPX Lslash y -37 +KPX Lslash yacute -37 +KPX Lslash ydieresis -37 +KPX N A -30 +KPX N Aacute -30 +KPX N Abreve -30 +KPX N Acircumflex -30 +KPX N Adieresis -30 +KPX N Agrave -30 +KPX N Amacron -30 +KPX N Aogonek -30 +KPX N Aring -30 +KPX N Atilde -30 +KPX Nacute A -30 +KPX Nacute Aacute -30 +KPX Nacute Abreve -30 +KPX Nacute Acircumflex -30 +KPX Nacute Adieresis -30 +KPX Nacute Agrave -30 +KPX Nacute Amacron -30 +KPX Nacute Aogonek -30 +KPX Nacute Aring -30 +KPX Nacute Atilde -30 +KPX Ncaron A -30 +KPX Ncaron Aacute -30 +KPX Ncaron Abreve -30 +KPX Ncaron Acircumflex -30 +KPX Ncaron Adieresis -30 +KPX Ncaron Agrave -30 +KPX Ncaron Amacron -30 +KPX Ncaron Aogonek -30 +KPX Ncaron Aring -30 +KPX Ncaron Atilde -30 +KPX Ncommaaccent A -30 +KPX Ncommaaccent Aacute -30 +KPX Ncommaaccent Abreve -30 +KPX Ncommaaccent Acircumflex -30 +KPX Ncommaaccent Adieresis -30 +KPX Ncommaaccent Agrave -30 +KPX Ncommaaccent Amacron -30 +KPX Ncommaaccent Aogonek -30 +KPX Ncommaaccent Aring -30 +KPX Ncommaaccent Atilde -30 +KPX Ntilde A -30 +KPX Ntilde Aacute -30 +KPX Ntilde Abreve -30 +KPX Ntilde Acircumflex -30 +KPX Ntilde Adieresis -30 +KPX Ntilde Agrave -30 +KPX Ntilde Amacron -30 +KPX Ntilde Aogonek -30 +KPX Ntilde Aring -30 +KPX Ntilde Atilde -30 +KPX O A -40 +KPX O Aacute -40 +KPX O Abreve -40 +KPX O Acircumflex -40 +KPX O Adieresis -40 +KPX O Agrave -40 +KPX O Amacron -40 +KPX O Aogonek -40 +KPX O Aring -40 +KPX O Atilde -40 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -40 +KPX Oacute Aacute -40 +KPX Oacute Abreve -40 +KPX Oacute Acircumflex -40 +KPX Oacute Adieresis -40 +KPX Oacute Agrave -40 +KPX Oacute Amacron -40 +KPX Oacute Aogonek -40 +KPX Oacute Aring -40 +KPX Oacute Atilde -40 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -40 +KPX Ocircumflex Aacute -40 +KPX Ocircumflex Abreve -40 +KPX Ocircumflex Acircumflex -40 +KPX Ocircumflex Adieresis -40 +KPX Ocircumflex Agrave -40 +KPX Ocircumflex Amacron -40 +KPX Ocircumflex Aogonek -40 +KPX Ocircumflex Aring -40 +KPX Ocircumflex Atilde -40 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -40 +KPX Odieresis Aacute -40 +KPX Odieresis Abreve -40 +KPX Odieresis Acircumflex -40 +KPX Odieresis Adieresis -40 +KPX Odieresis Agrave -40 +KPX Odieresis Amacron -40 +KPX Odieresis Aogonek -40 +KPX Odieresis Aring -40 +KPX Odieresis Atilde -40 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -40 +KPX Ograve Aacute -40 +KPX Ograve Abreve -40 +KPX Ograve Acircumflex -40 +KPX Ograve Adieresis -40 +KPX Ograve Agrave -40 +KPX Ograve Amacron -40 +KPX Ograve Aogonek -40 +KPX Ograve Aring -40 +KPX Ograve Atilde -40 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -40 +KPX Ohungarumlaut Aacute -40 +KPX Ohungarumlaut Abreve -40 +KPX Ohungarumlaut Acircumflex -40 +KPX Ohungarumlaut Adieresis -40 +KPX Ohungarumlaut Agrave -40 +KPX Ohungarumlaut Amacron -40 +KPX Ohungarumlaut Aogonek -40 +KPX Ohungarumlaut Aring -40 +KPX Ohungarumlaut Atilde -40 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -40 +KPX Omacron Aacute -40 +KPX Omacron Abreve -40 +KPX Omacron Acircumflex -40 +KPX Omacron Adieresis -40 +KPX Omacron Agrave -40 +KPX Omacron Amacron -40 +KPX Omacron Aogonek -40 +KPX Omacron Aring -40 +KPX Omacron Atilde -40 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -40 +KPX Oslash Aacute -40 +KPX Oslash Abreve -40 +KPX Oslash Acircumflex -40 +KPX Oslash Adieresis -40 +KPX Oslash Agrave -40 +KPX Oslash Amacron -40 +KPX Oslash Aogonek -40 +KPX Oslash Aring -40 +KPX Oslash Atilde -40 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -40 +KPX Otilde Aacute -40 +KPX Otilde Abreve -40 +KPX Otilde Acircumflex -40 +KPX Otilde Adieresis -40 +KPX Otilde Agrave -40 +KPX Otilde Amacron -40 +KPX Otilde Aogonek -40 +KPX Otilde Aring -40 +KPX Otilde Atilde -40 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -85 +KPX P Aacute -85 +KPX P Abreve -85 +KPX P Acircumflex -85 +KPX P Adieresis -85 +KPX P Agrave -85 +KPX P Amacron -85 +KPX P Aogonek -85 +KPX P Aring -85 +KPX P Atilde -85 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -129 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -55 +KPX P oacute -55 +KPX P ocircumflex -55 +KPX P odieresis -55 +KPX P ograve -55 +KPX P ohungarumlaut -55 +KPX P omacron -55 +KPX P oslash -55 +KPX P otilde -55 +KPX P period -129 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -18 +KPX R W -18 +KPX R Y -18 +KPX R Yacute -18 +KPX R Ydieresis -18 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -18 +KPX Racute W -18 +KPX Racute Y -18 +KPX Racute Yacute -18 +KPX Racute Ydieresis -18 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -18 +KPX Rcaron W -18 +KPX Rcaron Y -18 +KPX Rcaron Yacute -18 +KPX Rcaron Ydieresis -18 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -18 +KPX Rcommaaccent W -18 +KPX Rcommaaccent Y -18 +KPX Rcommaaccent Yacute -18 +KPX Rcommaaccent Ydieresis -18 +KPX T A -55 +KPX T Aacute -55 +KPX T Abreve -55 +KPX T Acircumflex -55 +KPX T Adieresis -55 +KPX T Agrave -55 +KPX T Amacron -55 +KPX T Aogonek -55 +KPX T Aring -55 +KPX T Atilde -55 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -92 +KPX T acircumflex -92 +KPX T adieresis -92 +KPX T agrave -92 +KPX T amacron -92 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -92 +KPX T colon -74 +KPX T comma -92 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -92 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -92 +KPX T i -37 +KPX T iacute -37 +KPX T iogonek -37 +KPX T o -95 +KPX T oacute -95 +KPX T ocircumflex -95 +KPX T odieresis -95 +KPX T ograve -95 +KPX T ohungarumlaut -95 +KPX T omacron -95 +KPX T oslash -95 +KPX T otilde -95 +KPX T period -92 +KPX T r -37 +KPX T racute -37 +KPX T rcaron -37 +KPX T rcommaaccent -37 +KPX T semicolon -74 +KPX T u -37 +KPX T uacute -37 +KPX T ucircumflex -37 +KPX T udieresis -37 +KPX T ugrave -37 +KPX T uhungarumlaut -37 +KPX T umacron -37 +KPX T uogonek -37 +KPX T uring -37 +KPX T w -37 +KPX T y -37 +KPX T yacute -37 +KPX T ydieresis -37 +KPX Tcaron A -55 +KPX Tcaron Aacute -55 +KPX Tcaron Abreve -55 +KPX Tcaron Acircumflex -55 +KPX Tcaron Adieresis -55 +KPX Tcaron Agrave -55 +KPX Tcaron Amacron -55 +KPX Tcaron Aogonek -55 +KPX Tcaron Aring -55 +KPX Tcaron Atilde -55 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -92 +KPX Tcaron acircumflex -92 +KPX Tcaron adieresis -92 +KPX Tcaron agrave -92 +KPX Tcaron amacron -92 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -92 +KPX Tcaron colon -74 +KPX Tcaron comma -92 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -92 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -92 +KPX Tcaron i -37 +KPX Tcaron iacute -37 +KPX Tcaron iogonek -37 +KPX Tcaron o -95 +KPX Tcaron oacute -95 +KPX Tcaron ocircumflex -95 +KPX Tcaron odieresis -95 +KPX Tcaron ograve -95 +KPX Tcaron ohungarumlaut -95 +KPX Tcaron omacron -95 +KPX Tcaron oslash -95 +KPX Tcaron otilde -95 +KPX Tcaron period -92 +KPX Tcaron r -37 +KPX Tcaron racute -37 +KPX Tcaron rcaron -37 +KPX Tcaron rcommaaccent -37 +KPX Tcaron semicolon -74 +KPX Tcaron u -37 +KPX Tcaron uacute -37 +KPX Tcaron ucircumflex -37 +KPX Tcaron udieresis -37 +KPX Tcaron ugrave -37 +KPX Tcaron uhungarumlaut -37 +KPX Tcaron umacron -37 +KPX Tcaron uogonek -37 +KPX Tcaron uring -37 +KPX Tcaron w -37 +KPX Tcaron y -37 +KPX Tcaron yacute -37 +KPX Tcaron ydieresis -37 +KPX Tcommaaccent A -55 +KPX Tcommaaccent Aacute -55 +KPX Tcommaaccent Abreve -55 +KPX Tcommaaccent Acircumflex -55 +KPX Tcommaaccent Adieresis -55 +KPX Tcommaaccent Agrave -55 +KPX Tcommaaccent Amacron -55 +KPX Tcommaaccent Aogonek -55 +KPX Tcommaaccent Aring -55 +KPX Tcommaaccent Atilde -55 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -92 +KPX Tcommaaccent acircumflex -92 +KPX Tcommaaccent adieresis -92 +KPX Tcommaaccent agrave -92 +KPX Tcommaaccent amacron -92 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -92 +KPX Tcommaaccent colon -74 +KPX Tcommaaccent comma -92 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -92 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -37 +KPX Tcommaaccent iacute -37 +KPX Tcommaaccent iogonek -37 +KPX Tcommaaccent o -95 +KPX Tcommaaccent oacute -95 +KPX Tcommaaccent ocircumflex -95 +KPX Tcommaaccent odieresis -95 +KPX Tcommaaccent ograve -95 +KPX Tcommaaccent ohungarumlaut -95 +KPX Tcommaaccent omacron -95 +KPX Tcommaaccent oslash -95 +KPX Tcommaaccent otilde -95 +KPX Tcommaaccent period -92 +KPX Tcommaaccent r -37 +KPX Tcommaaccent racute -37 +KPX Tcommaaccent rcaron -37 +KPX Tcommaaccent rcommaaccent -37 +KPX Tcommaaccent semicolon -74 +KPX Tcommaaccent u -37 +KPX Tcommaaccent uacute -37 +KPX Tcommaaccent ucircumflex -37 +KPX Tcommaaccent udieresis -37 +KPX Tcommaaccent ugrave -37 +KPX Tcommaaccent uhungarumlaut -37 +KPX Tcommaaccent umacron -37 +KPX Tcommaaccent uogonek -37 +KPX Tcommaaccent uring -37 +KPX Tcommaaccent w -37 +KPX Tcommaaccent y -37 +KPX Tcommaaccent yacute -37 +KPX Tcommaaccent ydieresis -37 +KPX U A -45 +KPX U Aacute -45 +KPX U Abreve -45 +KPX U Acircumflex -45 +KPX U Adieresis -45 +KPX U Agrave -45 +KPX U Amacron -45 +KPX U Aogonek -45 +KPX U Aring -45 +KPX U Atilde -45 +KPX Uacute A -45 +KPX Uacute Aacute -45 +KPX Uacute Abreve -45 +KPX Uacute Acircumflex -45 +KPX Uacute Adieresis -45 +KPX Uacute Agrave -45 +KPX Uacute Amacron -45 +KPX Uacute Aogonek -45 +KPX Uacute Aring -45 +KPX Uacute Atilde -45 +KPX Ucircumflex A -45 +KPX Ucircumflex Aacute -45 +KPX Ucircumflex Abreve -45 +KPX Ucircumflex Acircumflex -45 +KPX Ucircumflex Adieresis -45 +KPX Ucircumflex Agrave -45 +KPX Ucircumflex Amacron -45 +KPX Ucircumflex Aogonek -45 +KPX Ucircumflex Aring -45 +KPX Ucircumflex Atilde -45 +KPX Udieresis A -45 +KPX Udieresis Aacute -45 +KPX Udieresis Abreve -45 +KPX Udieresis Acircumflex -45 +KPX Udieresis Adieresis -45 +KPX Udieresis Agrave -45 +KPX Udieresis Amacron -45 +KPX Udieresis Aogonek -45 +KPX Udieresis Aring -45 +KPX Udieresis Atilde -45 +KPX Ugrave A -45 +KPX Ugrave Aacute -45 +KPX Ugrave Abreve -45 +KPX Ugrave Acircumflex -45 +KPX Ugrave Adieresis -45 +KPX Ugrave Agrave -45 +KPX Ugrave Amacron -45 +KPX Ugrave Aogonek -45 +KPX Ugrave Aring -45 +KPX Ugrave Atilde -45 +KPX Uhungarumlaut A -45 +KPX Uhungarumlaut Aacute -45 +KPX Uhungarumlaut Abreve -45 +KPX Uhungarumlaut Acircumflex -45 +KPX Uhungarumlaut Adieresis -45 +KPX Uhungarumlaut Agrave -45 +KPX Uhungarumlaut Amacron -45 +KPX Uhungarumlaut Aogonek -45 +KPX Uhungarumlaut Aring -45 +KPX Uhungarumlaut Atilde -45 +KPX Umacron A -45 +KPX Umacron Aacute -45 +KPX Umacron Abreve -45 +KPX Umacron Acircumflex -45 +KPX Umacron Adieresis -45 +KPX Umacron Agrave -45 +KPX Umacron Amacron -45 +KPX Umacron Aogonek -45 +KPX Umacron Aring -45 +KPX Umacron Atilde -45 +KPX Uogonek A -45 +KPX Uogonek Aacute -45 +KPX Uogonek Abreve -45 +KPX Uogonek Acircumflex -45 +KPX Uogonek Adieresis -45 +KPX Uogonek Agrave -45 +KPX Uogonek Amacron -45 +KPX Uogonek Aogonek -45 +KPX Uogonek Aring -45 +KPX Uogonek Atilde -45 +KPX Uring A -45 +KPX Uring Aacute -45 +KPX Uring Abreve -45 +KPX Uring Acircumflex -45 +KPX Uring Adieresis -45 +KPX Uring Agrave -45 +KPX Uring Amacron -45 +KPX Uring Aogonek -45 +KPX Uring Aring -45 +KPX Uring Atilde -45 +KPX V A -85 +KPX V Aacute -85 +KPX V Abreve -85 +KPX V Acircumflex -85 +KPX V Adieresis -85 +KPX V Agrave -85 +KPX V Amacron -85 +KPX V Aogonek -85 +KPX V Aring -85 +KPX V Atilde -85 +KPX V G -10 +KPX V Gbreve -10 +KPX V Gcommaaccent -10 +KPX V O -30 +KPX V Oacute -30 +KPX V Ocircumflex -30 +KPX V Odieresis -30 +KPX V Ograve -30 +KPX V Ohungarumlaut -30 +KPX V Omacron -30 +KPX V Oslash -30 +KPX V Otilde -30 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -111 +KPX V adieresis -111 +KPX V agrave -111 +KPX V amacron -111 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -111 +KPX V colon -74 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -111 +KPX V ecircumflex -111 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -70 +KPX V i -55 +KPX V iacute -55 +KPX V iogonek -55 +KPX V o -111 +KPX V oacute -111 +KPX V ocircumflex -111 +KPX V odieresis -111 +KPX V ograve -111 +KPX V ohungarumlaut -111 +KPX V omacron -111 +KPX V oslash -111 +KPX V otilde -111 +KPX V period -129 +KPX V semicolon -74 +KPX V u -55 +KPX V uacute -55 +KPX V ucircumflex -55 +KPX V udieresis -55 +KPX V ugrave -55 +KPX V uhungarumlaut -55 +KPX V umacron -55 +KPX V uogonek -55 +KPX V uring -55 +KPX W A -74 +KPX W Aacute -74 +KPX W Abreve -74 +KPX W Acircumflex -74 +KPX W Adieresis -74 +KPX W Agrave -74 +KPX W Amacron -74 +KPX W Aogonek -74 +KPX W Aring -74 +KPX W Atilde -74 +KPX W O -15 +KPX W Oacute -15 +KPX W Ocircumflex -15 +KPX W Odieresis -15 +KPX W Ograve -15 +KPX W Ohungarumlaut -15 +KPX W Omacron -15 +KPX W Oslash -15 +KPX W Otilde -15 +KPX W a -85 +KPX W aacute -85 +KPX W abreve -85 +KPX W acircumflex -85 +KPX W adieresis -85 +KPX W agrave -85 +KPX W amacron -85 +KPX W aogonek -85 +KPX W aring -85 +KPX W atilde -85 +KPX W colon -55 +KPX W comma -74 +KPX W e -90 +KPX W eacute -90 +KPX W ecaron -90 +KPX W ecircumflex -90 +KPX W edieresis -50 +KPX W edotaccent -90 +KPX W egrave -50 +KPX W emacron -50 +KPX W eogonek -90 +KPX W hyphen -50 +KPX W i -37 +KPX W iacute -37 +KPX W iogonek -37 +KPX W o -80 +KPX W oacute -80 +KPX W ocircumflex -80 +KPX W odieresis -80 +KPX W ograve -80 +KPX W ohungarumlaut -80 +KPX W omacron -80 +KPX W oslash -80 +KPX W otilde -80 +KPX W period -74 +KPX W semicolon -55 +KPX W u -55 +KPX W uacute -55 +KPX W ucircumflex -55 +KPX W udieresis -55 +KPX W ugrave -55 +KPX W uhungarumlaut -55 +KPX W umacron -55 +KPX W uogonek -55 +KPX W uring -55 +KPX W y -55 +KPX W yacute -55 +KPX W ydieresis -55 +KPX Y A -74 +KPX Y Aacute -74 +KPX Y Abreve -74 +KPX Y Acircumflex -74 +KPX Y Adieresis -74 +KPX Y Agrave -74 +KPX Y Amacron -74 +KPX Y Aogonek -74 +KPX Y Aring -74 +KPX Y Atilde -74 +KPX Y O -25 +KPX Y Oacute -25 +KPX Y Ocircumflex -25 +KPX Y Odieresis -25 +KPX Y Ograve -25 +KPX Y Ohungarumlaut -25 +KPX Y Omacron -25 +KPX Y Oslash -25 +KPX Y Otilde -25 +KPX Y a -92 +KPX Y aacute -92 +KPX Y abreve -92 +KPX Y acircumflex -92 +KPX Y adieresis -92 +KPX Y agrave -92 +KPX Y amacron -92 +KPX Y aogonek -92 +KPX Y aring -92 +KPX Y atilde -92 +KPX Y colon -92 +KPX Y comma -92 +KPX Y e -111 +KPX Y eacute -111 +KPX Y ecaron -111 +KPX Y ecircumflex -71 +KPX Y edieresis -71 +KPX Y edotaccent -111 +KPX Y egrave -71 +KPX Y emacron -71 +KPX Y eogonek -111 +KPX Y hyphen -92 +KPX Y i -55 +KPX Y iacute -55 +KPX Y iogonek -55 +KPX Y o -111 +KPX Y oacute -111 +KPX Y ocircumflex -111 +KPX Y odieresis -111 +KPX Y ograve -111 +KPX Y ohungarumlaut -111 +KPX Y omacron -111 +KPX Y oslash -111 +KPX Y otilde -111 +KPX Y period -74 +KPX Y semicolon -92 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -74 +KPX Yacute Aacute -74 +KPX Yacute Abreve -74 +KPX Yacute Acircumflex -74 +KPX Yacute Adieresis -74 +KPX Yacute Agrave -74 +KPX Yacute Amacron -74 +KPX Yacute Aogonek -74 +KPX Yacute Aring -74 +KPX Yacute Atilde -74 +KPX Yacute O -25 +KPX Yacute Oacute -25 +KPX Yacute Ocircumflex -25 +KPX Yacute Odieresis -25 +KPX Yacute Ograve -25 +KPX Yacute Ohungarumlaut -25 +KPX Yacute Omacron -25 +KPX Yacute Oslash -25 +KPX Yacute Otilde -25 +KPX Yacute a -92 +KPX Yacute aacute -92 +KPX Yacute abreve -92 +KPX Yacute acircumflex -92 +KPX Yacute adieresis -92 +KPX Yacute agrave -92 +KPX Yacute amacron -92 +KPX Yacute aogonek -92 +KPX Yacute aring -92 +KPX Yacute atilde -92 +KPX Yacute colon -92 +KPX Yacute comma -92 +KPX Yacute e -111 +KPX Yacute eacute -111 +KPX Yacute ecaron -111 +KPX Yacute ecircumflex -71 +KPX Yacute edieresis -71 +KPX Yacute edotaccent -111 +KPX Yacute egrave -71 +KPX Yacute emacron -71 +KPX Yacute eogonek -111 +KPX Yacute hyphen -92 +KPX Yacute i -55 +KPX Yacute iacute -55 +KPX Yacute iogonek -55 +KPX Yacute o -111 +KPX Yacute oacute -111 +KPX Yacute ocircumflex -111 +KPX Yacute odieresis -111 +KPX Yacute ograve -111 +KPX Yacute ohungarumlaut -111 +KPX Yacute omacron -111 +KPX Yacute oslash -111 +KPX Yacute otilde -111 +KPX Yacute period -74 +KPX Yacute semicolon -92 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -74 +KPX Ydieresis Aacute -74 +KPX Ydieresis Abreve -74 +KPX Ydieresis Acircumflex -74 +KPX Ydieresis Adieresis -74 +KPX Ydieresis Agrave -74 +KPX Ydieresis Amacron -74 +KPX Ydieresis Aogonek -74 +KPX Ydieresis Aring -74 +KPX Ydieresis Atilde -74 +KPX Ydieresis O -25 +KPX Ydieresis Oacute -25 +KPX Ydieresis Ocircumflex -25 +KPX Ydieresis Odieresis -25 +KPX Ydieresis Ograve -25 +KPX Ydieresis Ohungarumlaut -25 +KPX Ydieresis Omacron -25 +KPX Ydieresis Oslash -25 +KPX Ydieresis Otilde -25 +KPX Ydieresis a -92 +KPX Ydieresis aacute -92 +KPX Ydieresis abreve -92 +KPX Ydieresis acircumflex -92 +KPX Ydieresis adieresis -92 +KPX Ydieresis agrave -92 +KPX Ydieresis amacron -92 +KPX Ydieresis aogonek -92 +KPX Ydieresis aring -92 +KPX Ydieresis atilde -92 +KPX Ydieresis colon -92 +KPX Ydieresis comma -92 +KPX Ydieresis e -111 +KPX Ydieresis eacute -111 +KPX Ydieresis ecaron -111 +KPX Ydieresis ecircumflex -71 +KPX Ydieresis edieresis -71 +KPX Ydieresis edotaccent -111 +KPX Ydieresis egrave -71 +KPX Ydieresis emacron -71 +KPX Ydieresis eogonek -111 +KPX Ydieresis hyphen -92 +KPX Ydieresis i -55 +KPX Ydieresis iacute -55 +KPX Ydieresis iogonek -55 +KPX Ydieresis o -111 +KPX Ydieresis oacute -111 +KPX Ydieresis ocircumflex -111 +KPX Ydieresis odieresis -111 +KPX Ydieresis ograve -111 +KPX Ydieresis ohungarumlaut -111 +KPX Ydieresis omacron -111 +KPX Ydieresis oslash -111 +KPX Ydieresis otilde -111 +KPX Ydieresis period -74 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX b b -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX c h -10 +KPX c k -10 +KPX c kcommaaccent -10 +KPX cacute h -10 +KPX cacute k -10 +KPX cacute kcommaaccent -10 +KPX ccaron h -10 +KPX ccaron k -10 +KPX ccaron kcommaaccent -10 +KPX ccedilla h -10 +KPX ccedilla k -10 +KPX ccedilla kcommaaccent -10 +KPX comma quotedblright -95 +KPX comma quoteright -95 +KPX e b -10 +KPX eacute b -10 +KPX ecaron b -10 +KPX ecircumflex b -10 +KPX edieresis b -10 +KPX edotaccent b -10 +KPX egrave b -10 +KPX emacron b -10 +KPX eogonek b -10 +KPX f comma -10 +KPX f dotlessi -30 +KPX f e -10 +KPX f eacute -10 +KPX f edotaccent -10 +KPX f eogonek -10 +KPX f f -18 +KPX f o -10 +KPX f oacute -10 +KPX f ocircumflex -10 +KPX f ograve -10 +KPX f ohungarumlaut -10 +KPX f oslash -10 +KPX f otilde -10 +KPX f period -10 +KPX f quoteright 55 +KPX k e -30 +KPX k eacute -30 +KPX k ecaron -30 +KPX k ecircumflex -30 +KPX k edieresis -30 +KPX k edotaccent -30 +KPX k egrave -30 +KPX k emacron -30 +KPX k eogonek -30 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX kcommaaccent e -30 +KPX kcommaaccent eacute -30 +KPX kcommaaccent ecaron -30 +KPX kcommaaccent ecircumflex -30 +KPX kcommaaccent edieresis -30 +KPX kcommaaccent edotaccent -30 +KPX kcommaaccent egrave -30 +KPX kcommaaccent emacron -30 +KPX kcommaaccent eogonek -30 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o v -15 +KPX o w -25 +KPX o x -10 +KPX o y -10 +KPX o yacute -10 +KPX o ydieresis -10 +KPX oacute v -15 +KPX oacute w -25 +KPX oacute x -10 +KPX oacute y -10 +KPX oacute yacute -10 +KPX oacute ydieresis -10 +KPX ocircumflex v -15 +KPX ocircumflex w -25 +KPX ocircumflex x -10 +KPX ocircumflex y -10 +KPX ocircumflex yacute -10 +KPX ocircumflex ydieresis -10 +KPX odieresis v -15 +KPX odieresis w -25 +KPX odieresis x -10 +KPX odieresis y -10 +KPX odieresis yacute -10 +KPX odieresis ydieresis -10 +KPX ograve v -15 +KPX ograve w -25 +KPX ograve x -10 +KPX ograve y -10 +KPX ograve yacute -10 +KPX ograve ydieresis -10 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -25 +KPX ohungarumlaut x -10 +KPX ohungarumlaut y -10 +KPX ohungarumlaut yacute -10 +KPX ohungarumlaut ydieresis -10 +KPX omacron v -15 +KPX omacron w -25 +KPX omacron x -10 +KPX omacron y -10 +KPX omacron yacute -10 +KPX omacron ydieresis -10 +KPX oslash v -15 +KPX oslash w -25 +KPX oslash x -10 +KPX oslash y -10 +KPX oslash yacute -10 +KPX oslash ydieresis -10 +KPX otilde v -15 +KPX otilde w -25 +KPX otilde x -10 +KPX otilde y -10 +KPX otilde yacute -10 +KPX otilde ydieresis -10 +KPX period quotedblright -95 +KPX period quoteright -95 +KPX quoteleft quoteleft -74 +KPX quoteright d -15 +KPX quoteright dcroat -15 +KPX quoteright quoteright -74 +KPX quoteright r -15 +KPX quoteright racute -15 +KPX quoteright rcaron -15 +KPX quoteright rcommaaccent -15 +KPX quoteright s -74 +KPX quoteright sacute -74 +KPX quoteright scaron -74 +KPX quoteright scedilla -74 +KPX quoteright scommaaccent -74 +KPX quoteright space -74 +KPX quoteright t -37 +KPX quoteright tcommaaccent -37 +KPX quoteright v -15 +KPX r comma -65 +KPX r period -65 +KPX racute comma -65 +KPX racute period -65 +KPX rcaron comma -65 +KPX rcaron period -65 +KPX rcommaaccent comma -65 +KPX rcommaaccent period -65 +KPX space A -37 +KPX space Aacute -37 +KPX space Abreve -37 +KPX space Acircumflex -37 +KPX space Adieresis -37 +KPX space Agrave -37 +KPX space Amacron -37 +KPX space Aogonek -37 +KPX space Aring -37 +KPX space Atilde -37 +KPX space V -70 +KPX space W -70 +KPX space Y -70 +KPX space Yacute -70 +KPX space Ydieresis -70 +KPX v comma -37 +KPX v e -15 +KPX v eacute -15 +KPX v ecaron -15 +KPX v ecircumflex -15 +KPX v edieresis -15 +KPX v edotaccent -15 +KPX v egrave -15 +KPX v emacron -15 +KPX v eogonek -15 +KPX v o -15 +KPX v oacute -15 +KPX v ocircumflex -15 +KPX v odieresis -15 +KPX v ograve -15 +KPX v ohungarumlaut -15 +KPX v omacron -15 +KPX v oslash -15 +KPX v otilde -15 +KPX v period -37 +KPX w a -10 +KPX w aacute -10 +KPX w abreve -10 +KPX w acircumflex -10 +KPX w adieresis -10 +KPX w agrave -10 +KPX w amacron -10 +KPX w aogonek -10 +KPX w aring -10 +KPX w atilde -10 +KPX w comma -37 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -15 +KPX w oacute -15 +KPX w ocircumflex -15 +KPX w odieresis -15 +KPX w ograve -15 +KPX w ohungarumlaut -15 +KPX w omacron -15 +KPX w oslash -15 +KPX w otilde -15 +KPX w period -37 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y comma -37 +KPX y period -37 +KPX yacute comma -37 +KPX yacute period -37 +KPX ydieresis comma -37 +KPX ydieresis period -37 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm new file mode 100644 index 00000000..b0eaee40 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm @@ -0,0 +1,2667 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:56:55 1997 +Comment UniqueID 43067 +Comment VMusage 47727 58752 +FontName Times-Italic +FullName Times Italic +FamilyName Times +Weight Medium +ItalicAngle -15.5 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -169 -217 1010 883 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 653 +XHeight 441 +Ascender 683 +Descender -217 +StdHW 32 +StdVW 76 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ; +C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ; +C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ; +C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ; +C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ; +C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ; +C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ; +C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ; +C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ; +C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ; +C 43 ; WX 675 ; N plus ; B 86 0 590 506 ; +C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ; +C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ; +C 46 ; WX 250 ; N period ; B 27 -11 138 100 ; +C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ; +C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ; +C 49 ; WX 500 ; N one ; B 49 0 409 676 ; +C 50 ; WX 500 ; N two ; B 12 0 452 676 ; +C 51 ; WX 500 ; N three ; B 15 -7 465 676 ; +C 52 ; WX 500 ; N four ; B 1 0 479 676 ; +C 53 ; WX 500 ; N five ; B 15 -7 491 666 ; +C 54 ; WX 500 ; N six ; B 30 -7 521 686 ; +C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ; +C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ; +C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ; +C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ; +C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ; +C 60 ; WX 675 ; N less ; B 84 -8 592 514 ; +C 61 ; WX 675 ; N equal ; B 86 120 590 386 ; +C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ; +C 63 ; WX 500 ; N question ; B 132 -12 472 664 ; +C 64 ; WX 920 ; N at ; B 118 -18 806 666 ; +C 65 ; WX 611 ; N A ; B -51 0 564 668 ; +C 66 ; WX 611 ; N B ; B -8 0 588 653 ; +C 67 ; WX 667 ; N C ; B 66 -18 689 666 ; +C 68 ; WX 722 ; N D ; B -8 0 700 653 ; +C 69 ; WX 611 ; N E ; B -1 0 634 653 ; +C 70 ; WX 611 ; N F ; B 8 0 645 653 ; +C 71 ; WX 722 ; N G ; B 52 -18 722 666 ; +C 72 ; WX 722 ; N H ; B -8 0 767 653 ; +C 73 ; WX 333 ; N I ; B -8 0 384 653 ; +C 74 ; WX 444 ; N J ; B -6 -18 491 653 ; +C 75 ; WX 667 ; N K ; B 7 0 722 653 ; +C 76 ; WX 556 ; N L ; B -8 0 559 653 ; +C 77 ; WX 833 ; N M ; B -18 0 873 653 ; +C 78 ; WX 667 ; N N ; B -20 -15 727 653 ; +C 79 ; WX 722 ; N O ; B 60 -18 699 666 ; +C 80 ; WX 611 ; N P ; B 0 0 605 653 ; +C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ; +C 82 ; WX 611 ; N R ; B -13 0 588 653 ; +C 83 ; WX 500 ; N S ; B 17 -18 508 667 ; +C 84 ; WX 556 ; N T ; B 59 0 633 653 ; +C 85 ; WX 722 ; N U ; B 102 -18 765 653 ; +C 86 ; WX 611 ; N V ; B 76 -18 688 653 ; +C 87 ; WX 833 ; N W ; B 71 -18 906 653 ; +C 88 ; WX 611 ; N X ; B -29 0 655 653 ; +C 89 ; WX 556 ; N Y ; B 78 0 633 653 ; +C 90 ; WX 556 ; N Z ; B -6 0 606 653 ; +C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ; +C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ; +C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ; +C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ; +C 97 ; WX 500 ; N a ; B 17 -11 476 441 ; +C 98 ; WX 500 ; N b ; B 23 -11 473 683 ; +C 99 ; WX 444 ; N c ; B 30 -11 425 441 ; +C 100 ; WX 500 ; N d ; B 15 -13 527 683 ; +C 101 ; WX 444 ; N e ; B 31 -11 412 441 ; +C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 8 -206 472 441 ; +C 104 ; WX 500 ; N h ; B 19 -9 478 683 ; +C 105 ; WX 278 ; N i ; B 49 -11 264 654 ; +C 106 ; WX 278 ; N j ; B -124 -207 276 654 ; +C 107 ; WX 444 ; N k ; B 14 -11 461 683 ; +C 108 ; WX 278 ; N l ; B 41 -11 279 683 ; +C 109 ; WX 722 ; N m ; B 12 -9 704 441 ; +C 110 ; WX 500 ; N n ; B 14 -9 474 441 ; +C 111 ; WX 500 ; N o ; B 27 -11 468 441 ; +C 112 ; WX 500 ; N p ; B -75 -205 469 441 ; +C 113 ; WX 500 ; N q ; B 25 -209 483 441 ; +C 114 ; WX 389 ; N r ; B 45 0 412 441 ; +C 115 ; WX 389 ; N s ; B 16 -13 366 442 ; +C 116 ; WX 278 ; N t ; B 37 -11 296 546 ; +C 117 ; WX 500 ; N u ; B 42 -11 475 441 ; +C 118 ; WX 444 ; N v ; B 21 -18 426 441 ; +C 119 ; WX 667 ; N w ; B 16 -18 648 441 ; +C 120 ; WX 444 ; N x ; B -27 -11 447 441 ; +C 121 ; WX 444 ; N y ; B -24 -206 426 441 ; +C 122 ; WX 389 ; N z ; B -2 -81 380 428 ; +C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ; +C 124 ; WX 275 ; N bar ; B 105 -217 171 783 ; +C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ; +C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ; +C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ; +C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ; +C 165 ; WX 500 ; N yen ; B 27 0 603 653 ; +C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ; +C 167 ; WX 500 ; N section ; B 53 -162 461 666 ; +C 168 ; WX 500 ; N currency ; B -22 53 522 597 ; +C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ; +C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ; +C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ; +C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ; +C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ; +C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ; +C 177 ; WX 500 ; N endash ; B -6 197 505 243 ; +C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ; +C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ; +C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ; +C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ; +C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ; +C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ; +C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ; +C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ; +C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ; +C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ; +C 193 ; WX 333 ; N grave ; B 121 492 311 664 ; +C 194 ; WX 333 ; N acute ; B 180 494 403 664 ; +C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ; +C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ; +C 197 ; WX 333 ; N macron ; B 99 532 411 583 ; +C 198 ; WX 333 ; N breve ; B 117 492 418 650 ; +C 199 ; WX 333 ; N dotaccent ; B 207 548 305 646 ; +C 200 ; WX 333 ; N dieresis ; B 107 548 405 646 ; +C 202 ; WX 333 ; N ring ; B 155 492 355 691 ; +C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ; +C 206 ; WX 333 ; N ogonek ; B 20 -169 203 40 ; +C 207 ; WX 333 ; N caron ; B 121 492 426 661 ; +C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ; +C 225 ; WX 889 ; N AE ; B -27 0 911 653 ; +C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ; +C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ; +C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ; +C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ; +C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ; +C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ; +C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ; +C 248 ; WX 278 ; N lslash ; B 41 -11 312 683 ; +C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ; +C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ; +C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ; +C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ; +C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ; +C -1 ; WX 500 ; N abreve ; B 17 -11 502 650 ; +C -1 ; WX 500 ; N uhungarumlaut ; B 42 -11 580 664 ; +C -1 ; WX 444 ; N ecaron ; B 31 -11 482 661 ; +C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ; +C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ; +C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ; +C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ; +C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ; +C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ; +C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ; +C -1 ; WX 389 ; N scommaaccent ; B 16 -217 366 442 ; +C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ; +C -1 ; WX 722 ; N Uring ; B 102 -18 765 883 ; +C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ; +C -1 ; WX 500 ; N aogonek ; B 17 -169 476 441 ; +C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ; +C -1 ; WX 500 ; N uogonek ; B 42 -169 477 441 ; +C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ; +C -1 ; WX 722 ; N Dcroat ; B -8 0 700 653 ; +C -1 ; WX 250 ; N commaaccent ; B 8 -217 133 -50 ; +C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ; +C -1 ; WX 611 ; N Emacron ; B -1 0 634 795 ; +C -1 ; WX 444 ; N ccaron ; B 30 -11 482 661 ; +C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ; +C -1 ; WX 667 ; N Ncommaaccent ; B -20 -187 727 653 ; +C -1 ; WX 278 ; N lacute ; B 41 -11 395 876 ; +C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ; +C -1 ; WX 556 ; N Tcommaaccent ; B 59 -217 633 653 ; +C -1 ; WX 667 ; N Cacute ; B 66 -18 690 876 ; +C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ; +C -1 ; WX 611 ; N Edotaccent ; B -1 0 634 818 ; +C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ; +C -1 ; WX 389 ; N scedilla ; B 16 -217 366 442 ; +C -1 ; WX 278 ; N iacute ; B 49 -11 355 664 ; +C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; +C -1 ; WX 611 ; N Rcaron ; B -13 0 588 873 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 52 -217 722 666 ; +C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ; +C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ; +C -1 ; WX 611 ; N Amacron ; B -51 0 564 795 ; +C -1 ; WX 389 ; N rcaron ; B 45 0 434 661 ; +C -1 ; WX 444 ; N ccedilla ; B 30 -217 425 441 ; +C -1 ; WX 556 ; N Zdotaccent ; B -6 0 606 818 ; +C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ; +C -1 ; WX 722 ; N Omacron ; B 60 -18 699 795 ; +C -1 ; WX 611 ; N Racute ; B -13 0 588 876 ; +C -1 ; WX 500 ; N Sacute ; B 17 -18 508 876 ; +C -1 ; WX 544 ; N dcaron ; B 15 -13 658 683 ; +C -1 ; WX 722 ; N Umacron ; B 102 -18 765 795 ; +C -1 ; WX 500 ; N uring ; B 42 -11 475 691 ; +C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ; +C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ; +C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ; +C -1 ; WX 611 ; N Abreve ; B -51 0 564 862 ; +C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ; +C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ; +C -1 ; WX 556 ; N Tcaron ; B 59 0 633 873 ; +C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ; +C -1 ; WX 667 ; N Nacute ; B -20 -15 727 876 ; +C -1 ; WX 278 ; N icircumflex ; B 33 -11 327 661 ; +C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ; +C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ; +C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ; +C -1 ; WX 444 ; N cacute ; B 30 -11 459 664 ; +C -1 ; WX 500 ; N nacute ; B 14 -9 477 664 ; +C -1 ; WX 500 ; N umacron ; B 42 -11 485 583 ; +C -1 ; WX 667 ; N Ncaron ; B -20 -15 727 873 ; +C -1 ; WX 333 ; N Iacute ; B -8 0 433 876 ; +C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ; +C -1 ; WX 275 ; N brokenbar ; B 105 -142 171 708 ; +C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ; +C -1 ; WX 722 ; N Gbreve ; B 52 -18 722 862 ; +C -1 ; WX 333 ; N Idotaccent ; B -8 0 384 818 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ; +C -1 ; WX 389 ; N racute ; B 45 0 431 664 ; +C -1 ; WX 500 ; N omacron ; B 27 -11 495 583 ; +C -1 ; WX 556 ; N Zacute ; B -6 0 606 876 ; +C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 658 ; +C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ; +C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ; +C -1 ; WX 278 ; N lcommaaccent ; B 22 -217 279 683 ; +C -1 ; WX 300 ; N tcaron ; B 37 -11 407 681 ; +C -1 ; WX 444 ; N eogonek ; B 31 -169 412 441 ; +C -1 ; WX 722 ; N Uogonek ; B 102 -184 765 653 ; +C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ; +C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ; +C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ; +C -1 ; WX 389 ; N zacute ; B -2 -81 431 664 ; +C -1 ; WX 278 ; N iogonek ; B 49 -169 264 654 ; +C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ; +C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ; +C -1 ; WX 500 ; N amacron ; B 17 -11 495 583 ; +C -1 ; WX 389 ; N sacute ; B 16 -13 431 664 ; +C -1 ; WX 278 ; N idieresis ; B 49 -11 352 606 ; +C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ; +C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ; +C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ; +C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ; +C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ; +C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 27 -11 590 664 ; +C -1 ; WX 611 ; N Eogonek ; B -1 -169 634 653 ; +C -1 ; WX 500 ; N dcroat ; B 15 -13 572 683 ; +C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ; +C -1 ; WX 500 ; N Scedilla ; B 17 -217 508 667 ; +C -1 ; WX 300 ; N lcaron ; B 41 -11 407 683 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 7 -217 722 653 ; +C -1 ; WX 556 ; N Lacute ; B -8 0 559 876 ; +C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ; +C -1 ; WX 444 ; N edotaccent ; B 31 -11 412 606 ; +C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ; +C -1 ; WX 333 ; N Imacron ; B -8 0 441 795 ; +C -1 ; WX 611 ; N Lcaron ; B -8 0 586 653 ; +C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 658 ; +C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ; +C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 102 -18 765 876 ; +C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ; +C -1 ; WX 444 ; N emacron ; B 31 -11 457 583 ; +C -1 ; WX 500 ; N gbreve ; B 8 -206 487 650 ; +C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ; +C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ; +C -1 ; WX 500 ; N Scommaaccent ; B 17 -217 508 667 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 60 -18 699 876 ; +C -1 ; WX 400 ; N degree ; B 101 390 387 676 ; +C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ; +C -1 ; WX 667 ; N Ccaron ; B 66 -18 689 873 ; +C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ; +C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; +C -1 ; WX 722 ; N Dcaron ; B -8 0 700 873 ; +C -1 ; WX 389 ; N rcommaaccent ; B -3 -217 412 441 ; +C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ; +C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ; +C -1 ; WX 611 ; N Rcommaaccent ; B -13 -187 588 653 ; +C -1 ; WX 556 ; N Lcommaaccent ; B -8 -217 559 653 ; +C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ; +C -1 ; WX 611 ; N Aogonek ; B -51 -169 566 668 ; +C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ; +C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ; +C -1 ; WX 389 ; N zdotaccent ; B -2 -81 380 606 ; +C -1 ; WX 611 ; N Ecaron ; B -1 0 634 873 ; +C -1 ; WX 333 ; N Iogonek ; B -8 -169 384 653 ; +C -1 ; WX 444 ; N kcommaaccent ; B 14 -187 461 683 ; +C -1 ; WX 675 ; N minus ; B 86 220 590 286 ; +C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ; +C -1 ; WX 500 ; N ncaron ; B 14 -9 510 661 ; +C -1 ; WX 278 ; N tcommaaccent ; B 2 -217 296 546 ; +C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ; +C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ; +C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ; +C -1 ; WX 549 ; N notequal ; B 12 -29 537 541 ; +C -1 ; WX 500 ; N gcommaaccent ; B 8 -206 472 706 ; +C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ; +C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ; +C -1 ; WX 500 ; N ncommaaccent ; B 14 -187 474 441 ; +C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ; +C -1 ; WX 278 ; N imacron ; B 46 -11 311 583 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2321 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -35 +KPX A Gbreve -35 +KPX A Gcommaaccent -35 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -37 +KPX A Tcaron -37 +KPX A Tcommaaccent -37 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -105 +KPX A W -95 +KPX A Y -55 +KPX A Yacute -55 +KPX A Ydieresis -55 +KPX A quoteright -37 +KPX A u -20 +KPX A uacute -20 +KPX A ucircumflex -20 +KPX A udieresis -20 +KPX A ugrave -20 +KPX A uhungarumlaut -20 +KPX A umacron -20 +KPX A uogonek -20 +KPX A uring -20 +KPX A v -55 +KPX A w -55 +KPX A y -55 +KPX A yacute -55 +KPX A ydieresis -55 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -35 +KPX Aacute Gbreve -35 +KPX Aacute Gcommaaccent -35 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -37 +KPX Aacute Tcaron -37 +KPX Aacute Tcommaaccent -37 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -105 +KPX Aacute W -95 +KPX Aacute Y -55 +KPX Aacute Yacute -55 +KPX Aacute Ydieresis -55 +KPX Aacute quoteright -37 +KPX Aacute u -20 +KPX Aacute uacute -20 +KPX Aacute ucircumflex -20 +KPX Aacute udieresis -20 +KPX Aacute ugrave -20 +KPX Aacute uhungarumlaut -20 +KPX Aacute umacron -20 +KPX Aacute uogonek -20 +KPX Aacute uring -20 +KPX Aacute v -55 +KPX Aacute w -55 +KPX Aacute y -55 +KPX Aacute yacute -55 +KPX Aacute ydieresis -55 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -35 +KPX Abreve Gbreve -35 +KPX Abreve Gcommaaccent -35 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -37 +KPX Abreve Tcaron -37 +KPX Abreve Tcommaaccent -37 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -105 +KPX Abreve W -95 +KPX Abreve Y -55 +KPX Abreve Yacute -55 +KPX Abreve Ydieresis -55 +KPX Abreve quoteright -37 +KPX Abreve u -20 +KPX Abreve uacute -20 +KPX Abreve ucircumflex -20 +KPX Abreve udieresis -20 +KPX Abreve ugrave -20 +KPX Abreve uhungarumlaut -20 +KPX Abreve umacron -20 +KPX Abreve uogonek -20 +KPX Abreve uring -20 +KPX Abreve v -55 +KPX Abreve w -55 +KPX Abreve y -55 +KPX Abreve yacute -55 +KPX Abreve ydieresis -55 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -35 +KPX Acircumflex Gbreve -35 +KPX Acircumflex Gcommaaccent -35 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -37 +KPX Acircumflex Tcaron -37 +KPX Acircumflex Tcommaaccent -37 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -105 +KPX Acircumflex W -95 +KPX Acircumflex Y -55 +KPX Acircumflex Yacute -55 +KPX Acircumflex Ydieresis -55 +KPX Acircumflex quoteright -37 +KPX Acircumflex u -20 +KPX Acircumflex uacute -20 +KPX Acircumflex ucircumflex -20 +KPX Acircumflex udieresis -20 +KPX Acircumflex ugrave -20 +KPX Acircumflex uhungarumlaut -20 +KPX Acircumflex umacron -20 +KPX Acircumflex uogonek -20 +KPX Acircumflex uring -20 +KPX Acircumflex v -55 +KPX Acircumflex w -55 +KPX Acircumflex y -55 +KPX Acircumflex yacute -55 +KPX Acircumflex ydieresis -55 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -35 +KPX Adieresis Gbreve -35 +KPX Adieresis Gcommaaccent -35 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -37 +KPX Adieresis Tcaron -37 +KPX Adieresis Tcommaaccent -37 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -105 +KPX Adieresis W -95 +KPX Adieresis Y -55 +KPX Adieresis Yacute -55 +KPX Adieresis Ydieresis -55 +KPX Adieresis quoteright -37 +KPX Adieresis u -20 +KPX Adieresis uacute -20 +KPX Adieresis ucircumflex -20 +KPX Adieresis udieresis -20 +KPX Adieresis ugrave -20 +KPX Adieresis uhungarumlaut -20 +KPX Adieresis umacron -20 +KPX Adieresis uogonek -20 +KPX Adieresis uring -20 +KPX Adieresis v -55 +KPX Adieresis w -55 +KPX Adieresis y -55 +KPX Adieresis yacute -55 +KPX Adieresis ydieresis -55 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -35 +KPX Agrave Gbreve -35 +KPX Agrave Gcommaaccent -35 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -37 +KPX Agrave Tcaron -37 +KPX Agrave Tcommaaccent -37 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -105 +KPX Agrave W -95 +KPX Agrave Y -55 +KPX Agrave Yacute -55 +KPX Agrave Ydieresis -55 +KPX Agrave quoteright -37 +KPX Agrave u -20 +KPX Agrave uacute -20 +KPX Agrave ucircumflex -20 +KPX Agrave udieresis -20 +KPX Agrave ugrave -20 +KPX Agrave uhungarumlaut -20 +KPX Agrave umacron -20 +KPX Agrave uogonek -20 +KPX Agrave uring -20 +KPX Agrave v -55 +KPX Agrave w -55 +KPX Agrave y -55 +KPX Agrave yacute -55 +KPX Agrave ydieresis -55 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -35 +KPX Amacron Gbreve -35 +KPX Amacron Gcommaaccent -35 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -37 +KPX Amacron Tcaron -37 +KPX Amacron Tcommaaccent -37 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -105 +KPX Amacron W -95 +KPX Amacron Y -55 +KPX Amacron Yacute -55 +KPX Amacron Ydieresis -55 +KPX Amacron quoteright -37 +KPX Amacron u -20 +KPX Amacron uacute -20 +KPX Amacron ucircumflex -20 +KPX Amacron udieresis -20 +KPX Amacron ugrave -20 +KPX Amacron uhungarumlaut -20 +KPX Amacron umacron -20 +KPX Amacron uogonek -20 +KPX Amacron uring -20 +KPX Amacron v -55 +KPX Amacron w -55 +KPX Amacron y -55 +KPX Amacron yacute -55 +KPX Amacron ydieresis -55 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -35 +KPX Aogonek Gbreve -35 +KPX Aogonek Gcommaaccent -35 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -37 +KPX Aogonek Tcaron -37 +KPX Aogonek Tcommaaccent -37 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -105 +KPX Aogonek W -95 +KPX Aogonek Y -55 +KPX Aogonek Yacute -55 +KPX Aogonek Ydieresis -55 +KPX Aogonek quoteright -37 +KPX Aogonek u -20 +KPX Aogonek uacute -20 +KPX Aogonek ucircumflex -20 +KPX Aogonek udieresis -20 +KPX Aogonek ugrave -20 +KPX Aogonek uhungarumlaut -20 +KPX Aogonek umacron -20 +KPX Aogonek uogonek -20 +KPX Aogonek uring -20 +KPX Aogonek v -55 +KPX Aogonek w -55 +KPX Aogonek y -55 +KPX Aogonek yacute -55 +KPX Aogonek ydieresis -55 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -35 +KPX Aring Gbreve -35 +KPX Aring Gcommaaccent -35 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -37 +KPX Aring Tcaron -37 +KPX Aring Tcommaaccent -37 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -105 +KPX Aring W -95 +KPX Aring Y -55 +KPX Aring Yacute -55 +KPX Aring Ydieresis -55 +KPX Aring quoteright -37 +KPX Aring u -20 +KPX Aring uacute -20 +KPX Aring ucircumflex -20 +KPX Aring udieresis -20 +KPX Aring ugrave -20 +KPX Aring uhungarumlaut -20 +KPX Aring umacron -20 +KPX Aring uogonek -20 +KPX Aring uring -20 +KPX Aring v -55 +KPX Aring w -55 +KPX Aring y -55 +KPX Aring yacute -55 +KPX Aring ydieresis -55 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -35 +KPX Atilde Gbreve -35 +KPX Atilde Gcommaaccent -35 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -37 +KPX Atilde Tcaron -37 +KPX Atilde Tcommaaccent -37 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -105 +KPX Atilde W -95 +KPX Atilde Y -55 +KPX Atilde Yacute -55 +KPX Atilde Ydieresis -55 +KPX Atilde quoteright -37 +KPX Atilde u -20 +KPX Atilde uacute -20 +KPX Atilde ucircumflex -20 +KPX Atilde udieresis -20 +KPX Atilde ugrave -20 +KPX Atilde uhungarumlaut -20 +KPX Atilde umacron -20 +KPX Atilde uogonek -20 +KPX Atilde uring -20 +KPX Atilde v -55 +KPX Atilde w -55 +KPX Atilde y -55 +KPX Atilde yacute -55 +KPX Atilde ydieresis -55 +KPX B A -25 +KPX B Aacute -25 +KPX B Abreve -25 +KPX B Acircumflex -25 +KPX B Adieresis -25 +KPX B Agrave -25 +KPX B Amacron -25 +KPX B Aogonek -25 +KPX B Aring -25 +KPX B Atilde -25 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -35 +KPX D Aacute -35 +KPX D Abreve -35 +KPX D Acircumflex -35 +KPX D Adieresis -35 +KPX D Agrave -35 +KPX D Amacron -35 +KPX D Aogonek -35 +KPX D Aring -35 +KPX D Atilde -35 +KPX D V -40 +KPX D W -40 +KPX D Y -40 +KPX D Yacute -40 +KPX D Ydieresis -40 +KPX Dcaron A -35 +KPX Dcaron Aacute -35 +KPX Dcaron Abreve -35 +KPX Dcaron Acircumflex -35 +KPX Dcaron Adieresis -35 +KPX Dcaron Agrave -35 +KPX Dcaron Amacron -35 +KPX Dcaron Aogonek -35 +KPX Dcaron Aring -35 +KPX Dcaron Atilde -35 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -40 +KPX Dcaron Yacute -40 +KPX Dcaron Ydieresis -40 +KPX Dcroat A -35 +KPX Dcroat Aacute -35 +KPX Dcroat Abreve -35 +KPX Dcroat Acircumflex -35 +KPX Dcroat Adieresis -35 +KPX Dcroat Agrave -35 +KPX Dcroat Amacron -35 +KPX Dcroat Aogonek -35 +KPX Dcroat Aring -35 +KPX Dcroat Atilde -35 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -40 +KPX Dcroat Yacute -40 +KPX Dcroat Ydieresis -40 +KPX F A -115 +KPX F Aacute -115 +KPX F Abreve -115 +KPX F Acircumflex -115 +KPX F Adieresis -115 +KPX F Agrave -115 +KPX F Amacron -115 +KPX F Aogonek -115 +KPX F Aring -115 +KPX F Atilde -115 +KPX F a -75 +KPX F aacute -75 +KPX F abreve -75 +KPX F acircumflex -75 +KPX F adieresis -75 +KPX F agrave -75 +KPX F amacron -75 +KPX F aogonek -75 +KPX F aring -75 +KPX F atilde -75 +KPX F comma -135 +KPX F e -75 +KPX F eacute -75 +KPX F ecaron -75 +KPX F ecircumflex -75 +KPX F edieresis -75 +KPX F edotaccent -75 +KPX F egrave -75 +KPX F emacron -75 +KPX F eogonek -75 +KPX F i -45 +KPX F iacute -45 +KPX F icircumflex -45 +KPX F idieresis -45 +KPX F igrave -45 +KPX F imacron -45 +KPX F iogonek -45 +KPX F o -105 +KPX F oacute -105 +KPX F ocircumflex -105 +KPX F odieresis -105 +KPX F ograve -105 +KPX F ohungarumlaut -105 +KPX F omacron -105 +KPX F oslash -105 +KPX F otilde -105 +KPX F period -135 +KPX F r -55 +KPX F racute -55 +KPX F rcaron -55 +KPX F rcommaaccent -55 +KPX J A -40 +KPX J Aacute -40 +KPX J Abreve -40 +KPX J Acircumflex -40 +KPX J Adieresis -40 +KPX J Agrave -40 +KPX J Amacron -40 +KPX J Aogonek -40 +KPX J Aring -40 +KPX J Atilde -40 +KPX J a -35 +KPX J aacute -35 +KPX J abreve -35 +KPX J acircumflex -35 +KPX J adieresis -35 +KPX J agrave -35 +KPX J amacron -35 +KPX J aogonek -35 +KPX J aring -35 +KPX J atilde -35 +KPX J comma -25 +KPX J e -25 +KPX J eacute -25 +KPX J ecaron -25 +KPX J ecircumflex -25 +KPX J edieresis -25 +KPX J edotaccent -25 +KPX J egrave -25 +KPX J emacron -25 +KPX J eogonek -25 +KPX J o -25 +KPX J oacute -25 +KPX J ocircumflex -25 +KPX J odieresis -25 +KPX J ograve -25 +KPX J ohungarumlaut -25 +KPX J omacron -25 +KPX J oslash -25 +KPX J otilde -25 +KPX J period -25 +KPX J u -35 +KPX J uacute -35 +KPX J ucircumflex -35 +KPX J udieresis -35 +KPX J ugrave -35 +KPX J uhungarumlaut -35 +KPX J umacron -35 +KPX J uogonek -35 +KPX J uring -35 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -35 +KPX K eacute -35 +KPX K ecaron -35 +KPX K ecircumflex -35 +KPX K edieresis -35 +KPX K edotaccent -35 +KPX K egrave -35 +KPX K emacron -35 +KPX K eogonek -35 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -40 +KPX K uacute -40 +KPX K ucircumflex -40 +KPX K udieresis -40 +KPX K ugrave -40 +KPX K uhungarumlaut -40 +KPX K umacron -40 +KPX K uogonek -40 +KPX K uring -40 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -35 +KPX Kcommaaccent eacute -35 +KPX Kcommaaccent ecaron -35 +KPX Kcommaaccent ecircumflex -35 +KPX Kcommaaccent edieresis -35 +KPX Kcommaaccent edotaccent -35 +KPX Kcommaaccent egrave -35 +KPX Kcommaaccent emacron -35 +KPX Kcommaaccent eogonek -35 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -40 +KPX Kcommaaccent uacute -40 +KPX Kcommaaccent ucircumflex -40 +KPX Kcommaaccent udieresis -40 +KPX Kcommaaccent ugrave -40 +KPX Kcommaaccent uhungarumlaut -40 +KPX Kcommaaccent umacron -40 +KPX Kcommaaccent uogonek -40 +KPX Kcommaaccent uring -40 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -20 +KPX L Tcaron -20 +KPX L Tcommaaccent -20 +KPX L V -55 +KPX L W -55 +KPX L Y -20 +KPX L Yacute -20 +KPX L Ydieresis -20 +KPX L quoteright -37 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -20 +KPX Lacute Tcaron -20 +KPX Lacute Tcommaaccent -20 +KPX Lacute V -55 +KPX Lacute W -55 +KPX Lacute Y -20 +KPX Lacute Yacute -20 +KPX Lacute Ydieresis -20 +KPX Lacute quoteright -37 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -20 +KPX Lcommaaccent Tcaron -20 +KPX Lcommaaccent Tcommaaccent -20 +KPX Lcommaaccent V -55 +KPX Lcommaaccent W -55 +KPX Lcommaaccent Y -20 +KPX Lcommaaccent Yacute -20 +KPX Lcommaaccent Ydieresis -20 +KPX Lcommaaccent quoteright -37 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -20 +KPX Lslash Tcaron -20 +KPX Lslash Tcommaaccent -20 +KPX Lslash V -55 +KPX Lslash W -55 +KPX Lslash Y -20 +KPX Lslash Yacute -20 +KPX Lslash Ydieresis -20 +KPX Lslash quoteright -37 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX N A -27 +KPX N Aacute -27 +KPX N Abreve -27 +KPX N Acircumflex -27 +KPX N Adieresis -27 +KPX N Agrave -27 +KPX N Amacron -27 +KPX N Aogonek -27 +KPX N Aring -27 +KPX N Atilde -27 +KPX Nacute A -27 +KPX Nacute Aacute -27 +KPX Nacute Abreve -27 +KPX Nacute Acircumflex -27 +KPX Nacute Adieresis -27 +KPX Nacute Agrave -27 +KPX Nacute Amacron -27 +KPX Nacute Aogonek -27 +KPX Nacute Aring -27 +KPX Nacute Atilde -27 +KPX Ncaron A -27 +KPX Ncaron Aacute -27 +KPX Ncaron Abreve -27 +KPX Ncaron Acircumflex -27 +KPX Ncaron Adieresis -27 +KPX Ncaron Agrave -27 +KPX Ncaron Amacron -27 +KPX Ncaron Aogonek -27 +KPX Ncaron Aring -27 +KPX Ncaron Atilde -27 +KPX Ncommaaccent A -27 +KPX Ncommaaccent Aacute -27 +KPX Ncommaaccent Abreve -27 +KPX Ncommaaccent Acircumflex -27 +KPX Ncommaaccent Adieresis -27 +KPX Ncommaaccent Agrave -27 +KPX Ncommaaccent Amacron -27 +KPX Ncommaaccent Aogonek -27 +KPX Ncommaaccent Aring -27 +KPX Ncommaaccent Atilde -27 +KPX Ntilde A -27 +KPX Ntilde Aacute -27 +KPX Ntilde Abreve -27 +KPX Ntilde Acircumflex -27 +KPX Ntilde Adieresis -27 +KPX Ntilde Agrave -27 +KPX Ntilde Amacron -27 +KPX Ntilde Aogonek -27 +KPX Ntilde Aring -27 +KPX Ntilde Atilde -27 +KPX O A -55 +KPX O Aacute -55 +KPX O Abreve -55 +KPX O Acircumflex -55 +KPX O Adieresis -55 +KPX O Agrave -55 +KPX O Amacron -55 +KPX O Aogonek -55 +KPX O Aring -55 +KPX O Atilde -55 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -55 +KPX Oacute Aacute -55 +KPX Oacute Abreve -55 +KPX Oacute Acircumflex -55 +KPX Oacute Adieresis -55 +KPX Oacute Agrave -55 +KPX Oacute Amacron -55 +KPX Oacute Aogonek -55 +KPX Oacute Aring -55 +KPX Oacute Atilde -55 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -55 +KPX Ocircumflex Aacute -55 +KPX Ocircumflex Abreve -55 +KPX Ocircumflex Acircumflex -55 +KPX Ocircumflex Adieresis -55 +KPX Ocircumflex Agrave -55 +KPX Ocircumflex Amacron -55 +KPX Ocircumflex Aogonek -55 +KPX Ocircumflex Aring -55 +KPX Ocircumflex Atilde -55 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -55 +KPX Odieresis Aacute -55 +KPX Odieresis Abreve -55 +KPX Odieresis Acircumflex -55 +KPX Odieresis Adieresis -55 +KPX Odieresis Agrave -55 +KPX Odieresis Amacron -55 +KPX Odieresis Aogonek -55 +KPX Odieresis Aring -55 +KPX Odieresis Atilde -55 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -55 +KPX Ograve Aacute -55 +KPX Ograve Abreve -55 +KPX Ograve Acircumflex -55 +KPX Ograve Adieresis -55 +KPX Ograve Agrave -55 +KPX Ograve Amacron -55 +KPX Ograve Aogonek -55 +KPX Ograve Aring -55 +KPX Ograve Atilde -55 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -55 +KPX Ohungarumlaut Aacute -55 +KPX Ohungarumlaut Abreve -55 +KPX Ohungarumlaut Acircumflex -55 +KPX Ohungarumlaut Adieresis -55 +KPX Ohungarumlaut Agrave -55 +KPX Ohungarumlaut Amacron -55 +KPX Ohungarumlaut Aogonek -55 +KPX Ohungarumlaut Aring -55 +KPX Ohungarumlaut Atilde -55 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -55 +KPX Omacron Aacute -55 +KPX Omacron Abreve -55 +KPX Omacron Acircumflex -55 +KPX Omacron Adieresis -55 +KPX Omacron Agrave -55 +KPX Omacron Amacron -55 +KPX Omacron Aogonek -55 +KPX Omacron Aring -55 +KPX Omacron Atilde -55 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -55 +KPX Oslash Aacute -55 +KPX Oslash Abreve -55 +KPX Oslash Acircumflex -55 +KPX Oslash Adieresis -55 +KPX Oslash Agrave -55 +KPX Oslash Amacron -55 +KPX Oslash Aogonek -55 +KPX Oslash Aring -55 +KPX Oslash Atilde -55 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -55 +KPX Otilde Aacute -55 +KPX Otilde Abreve -55 +KPX Otilde Acircumflex -55 +KPX Otilde Adieresis -55 +KPX Otilde Agrave -55 +KPX Otilde Amacron -55 +KPX Otilde Aogonek -55 +KPX Otilde Aring -55 +KPX Otilde Atilde -55 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -90 +KPX P Aacute -90 +KPX P Abreve -90 +KPX P Acircumflex -90 +KPX P Adieresis -90 +KPX P Agrave -90 +KPX P Amacron -90 +KPX P Aogonek -90 +KPX P Aring -90 +KPX P Atilde -90 +KPX P a -80 +KPX P aacute -80 +KPX P abreve -80 +KPX P acircumflex -80 +KPX P adieresis -80 +KPX P agrave -80 +KPX P amacron -80 +KPX P aogonek -80 +KPX P aring -80 +KPX P atilde -80 +KPX P comma -135 +KPX P e -80 +KPX P eacute -80 +KPX P ecaron -80 +KPX P ecircumflex -80 +KPX P edieresis -80 +KPX P edotaccent -80 +KPX P egrave -80 +KPX P emacron -80 +KPX P eogonek -80 +KPX P o -80 +KPX P oacute -80 +KPX P ocircumflex -80 +KPX P odieresis -80 +KPX P ograve -80 +KPX P ohungarumlaut -80 +KPX P omacron -80 +KPX P oslash -80 +KPX P otilde -80 +KPX P period -135 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -18 +KPX R W -18 +KPX R Y -18 +KPX R Yacute -18 +KPX R Ydieresis -18 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -18 +KPX Racute W -18 +KPX Racute Y -18 +KPX Racute Yacute -18 +KPX Racute Ydieresis -18 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -18 +KPX Rcaron W -18 +KPX Rcaron Y -18 +KPX Rcaron Yacute -18 +KPX Rcaron Ydieresis -18 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -18 +KPX Rcommaaccent W -18 +KPX Rcommaaccent Y -18 +KPX Rcommaaccent Yacute -18 +KPX Rcommaaccent Ydieresis -18 +KPX T A -50 +KPX T Aacute -50 +KPX T Abreve -50 +KPX T Acircumflex -50 +KPX T Adieresis -50 +KPX T Agrave -50 +KPX T Amacron -50 +KPX T Aogonek -50 +KPX T Aring -50 +KPX T Atilde -50 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -92 +KPX T acircumflex -92 +KPX T adieresis -92 +KPX T agrave -92 +KPX T amacron -92 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -92 +KPX T colon -55 +KPX T comma -74 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -52 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -74 +KPX T i -55 +KPX T iacute -55 +KPX T iogonek -55 +KPX T o -92 +KPX T oacute -92 +KPX T ocircumflex -92 +KPX T odieresis -92 +KPX T ograve -92 +KPX T ohungarumlaut -92 +KPX T omacron -92 +KPX T oslash -92 +KPX T otilde -92 +KPX T period -74 +KPX T r -55 +KPX T racute -55 +KPX T rcaron -55 +KPX T rcommaaccent -55 +KPX T semicolon -65 +KPX T u -55 +KPX T uacute -55 +KPX T ucircumflex -55 +KPX T udieresis -55 +KPX T ugrave -55 +KPX T uhungarumlaut -55 +KPX T umacron -55 +KPX T uogonek -55 +KPX T uring -55 +KPX T w -74 +KPX T y -74 +KPX T yacute -74 +KPX T ydieresis -34 +KPX Tcaron A -50 +KPX Tcaron Aacute -50 +KPX Tcaron Abreve -50 +KPX Tcaron Acircumflex -50 +KPX Tcaron Adieresis -50 +KPX Tcaron Agrave -50 +KPX Tcaron Amacron -50 +KPX Tcaron Aogonek -50 +KPX Tcaron Aring -50 +KPX Tcaron Atilde -50 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -92 +KPX Tcaron acircumflex -92 +KPX Tcaron adieresis -92 +KPX Tcaron agrave -92 +KPX Tcaron amacron -92 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -92 +KPX Tcaron colon -55 +KPX Tcaron comma -74 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -52 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -74 +KPX Tcaron i -55 +KPX Tcaron iacute -55 +KPX Tcaron iogonek -55 +KPX Tcaron o -92 +KPX Tcaron oacute -92 +KPX Tcaron ocircumflex -92 +KPX Tcaron odieresis -92 +KPX Tcaron ograve -92 +KPX Tcaron ohungarumlaut -92 +KPX Tcaron omacron -92 +KPX Tcaron oslash -92 +KPX Tcaron otilde -92 +KPX Tcaron period -74 +KPX Tcaron r -55 +KPX Tcaron racute -55 +KPX Tcaron rcaron -55 +KPX Tcaron rcommaaccent -55 +KPX Tcaron semicolon -65 +KPX Tcaron u -55 +KPX Tcaron uacute -55 +KPX Tcaron ucircumflex -55 +KPX Tcaron udieresis -55 +KPX Tcaron ugrave -55 +KPX Tcaron uhungarumlaut -55 +KPX Tcaron umacron -55 +KPX Tcaron uogonek -55 +KPX Tcaron uring -55 +KPX Tcaron w -74 +KPX Tcaron y -74 +KPX Tcaron yacute -74 +KPX Tcaron ydieresis -34 +KPX Tcommaaccent A -50 +KPX Tcommaaccent Aacute -50 +KPX Tcommaaccent Abreve -50 +KPX Tcommaaccent Acircumflex -50 +KPX Tcommaaccent Adieresis -50 +KPX Tcommaaccent Agrave -50 +KPX Tcommaaccent Amacron -50 +KPX Tcommaaccent Aogonek -50 +KPX Tcommaaccent Aring -50 +KPX Tcommaaccent Atilde -50 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -92 +KPX Tcommaaccent acircumflex -92 +KPX Tcommaaccent adieresis -92 +KPX Tcommaaccent agrave -92 +KPX Tcommaaccent amacron -92 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -92 +KPX Tcommaaccent colon -55 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -52 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -74 +KPX Tcommaaccent i -55 +KPX Tcommaaccent iacute -55 +KPX Tcommaaccent iogonek -55 +KPX Tcommaaccent o -92 +KPX Tcommaaccent oacute -92 +KPX Tcommaaccent ocircumflex -92 +KPX Tcommaaccent odieresis -92 +KPX Tcommaaccent ograve -92 +KPX Tcommaaccent ohungarumlaut -92 +KPX Tcommaaccent omacron -92 +KPX Tcommaaccent oslash -92 +KPX Tcommaaccent otilde -92 +KPX Tcommaaccent period -74 +KPX Tcommaaccent r -55 +KPX Tcommaaccent racute -55 +KPX Tcommaaccent rcaron -55 +KPX Tcommaaccent rcommaaccent -55 +KPX Tcommaaccent semicolon -65 +KPX Tcommaaccent u -55 +KPX Tcommaaccent uacute -55 +KPX Tcommaaccent ucircumflex -55 +KPX Tcommaaccent udieresis -55 +KPX Tcommaaccent ugrave -55 +KPX Tcommaaccent uhungarumlaut -55 +KPX Tcommaaccent umacron -55 +KPX Tcommaaccent uogonek -55 +KPX Tcommaaccent uring -55 +KPX Tcommaaccent w -74 +KPX Tcommaaccent y -74 +KPX Tcommaaccent yacute -74 +KPX Tcommaaccent ydieresis -34 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -25 +KPX U period -25 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -25 +KPX Uacute period -25 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -25 +KPX Ucircumflex period -25 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -25 +KPX Udieresis period -25 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -25 +KPX Ugrave period -25 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -25 +KPX Uhungarumlaut period -25 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -25 +KPX Umacron period -25 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -25 +KPX Uogonek period -25 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -25 +KPX Uring period -25 +KPX V A -60 +KPX V Aacute -60 +KPX V Abreve -60 +KPX V Acircumflex -60 +KPX V Adieresis -60 +KPX V Agrave -60 +KPX V Amacron -60 +KPX V Aogonek -60 +KPX V Aring -60 +KPX V Atilde -60 +KPX V O -30 +KPX V Oacute -30 +KPX V Ocircumflex -30 +KPX V Odieresis -30 +KPX V Ograve -30 +KPX V Ohungarumlaut -30 +KPX V Omacron -30 +KPX V Oslash -30 +KPX V Otilde -30 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -111 +KPX V adieresis -111 +KPX V agrave -111 +KPX V amacron -111 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -111 +KPX V colon -65 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -111 +KPX V ecircumflex -111 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -55 +KPX V i -74 +KPX V iacute -74 +KPX V icircumflex -34 +KPX V idieresis -34 +KPX V igrave -34 +KPX V imacron -34 +KPX V iogonek -74 +KPX V o -111 +KPX V oacute -111 +KPX V ocircumflex -111 +KPX V odieresis -111 +KPX V ograve -111 +KPX V ohungarumlaut -111 +KPX V omacron -111 +KPX V oslash -111 +KPX V otilde -111 +KPX V period -129 +KPX V semicolon -74 +KPX V u -74 +KPX V uacute -74 +KPX V ucircumflex -74 +KPX V udieresis -74 +KPX V ugrave -74 +KPX V uhungarumlaut -74 +KPX V umacron -74 +KPX V uogonek -74 +KPX V uring -74 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -25 +KPX W Oacute -25 +KPX W Ocircumflex -25 +KPX W Odieresis -25 +KPX W Ograve -25 +KPX W Ohungarumlaut -25 +KPX W Omacron -25 +KPX W Oslash -25 +KPX W Otilde -25 +KPX W a -92 +KPX W aacute -92 +KPX W abreve -92 +KPX W acircumflex -92 +KPX W adieresis -92 +KPX W agrave -92 +KPX W amacron -92 +KPX W aogonek -92 +KPX W aring -92 +KPX W atilde -92 +KPX W colon -65 +KPX W comma -92 +KPX W e -92 +KPX W eacute -92 +KPX W ecaron -92 +KPX W ecircumflex -92 +KPX W edieresis -52 +KPX W edotaccent -92 +KPX W egrave -52 +KPX W emacron -52 +KPX W eogonek -92 +KPX W hyphen -37 +KPX W i -55 +KPX W iacute -55 +KPX W iogonek -55 +KPX W o -92 +KPX W oacute -92 +KPX W ocircumflex -92 +KPX W odieresis -92 +KPX W ograve -92 +KPX W ohungarumlaut -92 +KPX W omacron -92 +KPX W oslash -92 +KPX W otilde -92 +KPX W period -92 +KPX W semicolon -65 +KPX W u -55 +KPX W uacute -55 +KPX W ucircumflex -55 +KPX W udieresis -55 +KPX W ugrave -55 +KPX W uhungarumlaut -55 +KPX W umacron -55 +KPX W uogonek -55 +KPX W uring -55 +KPX W y -70 +KPX W yacute -70 +KPX W ydieresis -70 +KPX Y A -50 +KPX Y Aacute -50 +KPX Y Abreve -50 +KPX Y Acircumflex -50 +KPX Y Adieresis -50 +KPX Y Agrave -50 +KPX Y Amacron -50 +KPX Y Aogonek -50 +KPX Y Aring -50 +KPX Y Atilde -50 +KPX Y O -15 +KPX Y Oacute -15 +KPX Y Ocircumflex -15 +KPX Y Odieresis -15 +KPX Y Ograve -15 +KPX Y Ohungarumlaut -15 +KPX Y Omacron -15 +KPX Y Oslash -15 +KPX Y Otilde -15 +KPX Y a -92 +KPX Y aacute -92 +KPX Y abreve -92 +KPX Y acircumflex -92 +KPX Y adieresis -92 +KPX Y agrave -92 +KPX Y amacron -92 +KPX Y aogonek -92 +KPX Y aring -92 +KPX Y atilde -92 +KPX Y colon -65 +KPX Y comma -92 +KPX Y e -92 +KPX Y eacute -92 +KPX Y ecaron -92 +KPX Y ecircumflex -92 +KPX Y edieresis -52 +KPX Y edotaccent -92 +KPX Y egrave -52 +KPX Y emacron -52 +KPX Y eogonek -92 +KPX Y hyphen -74 +KPX Y i -74 +KPX Y iacute -74 +KPX Y icircumflex -34 +KPX Y idieresis -34 +KPX Y igrave -34 +KPX Y imacron -34 +KPX Y iogonek -74 +KPX Y o -92 +KPX Y oacute -92 +KPX Y ocircumflex -92 +KPX Y odieresis -92 +KPX Y ograve -92 +KPX Y ohungarumlaut -92 +KPX Y omacron -92 +KPX Y oslash -92 +KPX Y otilde -92 +KPX Y period -92 +KPX Y semicolon -65 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -50 +KPX Yacute Aacute -50 +KPX Yacute Abreve -50 +KPX Yacute Acircumflex -50 +KPX Yacute Adieresis -50 +KPX Yacute Agrave -50 +KPX Yacute Amacron -50 +KPX Yacute Aogonek -50 +KPX Yacute Aring -50 +KPX Yacute Atilde -50 +KPX Yacute O -15 +KPX Yacute Oacute -15 +KPX Yacute Ocircumflex -15 +KPX Yacute Odieresis -15 +KPX Yacute Ograve -15 +KPX Yacute Ohungarumlaut -15 +KPX Yacute Omacron -15 +KPX Yacute Oslash -15 +KPX Yacute Otilde -15 +KPX Yacute a -92 +KPX Yacute aacute -92 +KPX Yacute abreve -92 +KPX Yacute acircumflex -92 +KPX Yacute adieresis -92 +KPX Yacute agrave -92 +KPX Yacute amacron -92 +KPX Yacute aogonek -92 +KPX Yacute aring -92 +KPX Yacute atilde -92 +KPX Yacute colon -65 +KPX Yacute comma -92 +KPX Yacute e -92 +KPX Yacute eacute -92 +KPX Yacute ecaron -92 +KPX Yacute ecircumflex -92 +KPX Yacute edieresis -52 +KPX Yacute edotaccent -92 +KPX Yacute egrave -52 +KPX Yacute emacron -52 +KPX Yacute eogonek -92 +KPX Yacute hyphen -74 +KPX Yacute i -74 +KPX Yacute iacute -74 +KPX Yacute icircumflex -34 +KPX Yacute idieresis -34 +KPX Yacute igrave -34 +KPX Yacute imacron -34 +KPX Yacute iogonek -74 +KPX Yacute o -92 +KPX Yacute oacute -92 +KPX Yacute ocircumflex -92 +KPX Yacute odieresis -92 +KPX Yacute ograve -92 +KPX Yacute ohungarumlaut -92 +KPX Yacute omacron -92 +KPX Yacute oslash -92 +KPX Yacute otilde -92 +KPX Yacute period -92 +KPX Yacute semicolon -65 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -50 +KPX Ydieresis Aacute -50 +KPX Ydieresis Abreve -50 +KPX Ydieresis Acircumflex -50 +KPX Ydieresis Adieresis -50 +KPX Ydieresis Agrave -50 +KPX Ydieresis Amacron -50 +KPX Ydieresis Aogonek -50 +KPX Ydieresis Aring -50 +KPX Ydieresis Atilde -50 +KPX Ydieresis O -15 +KPX Ydieresis Oacute -15 +KPX Ydieresis Ocircumflex -15 +KPX Ydieresis Odieresis -15 +KPX Ydieresis Ograve -15 +KPX Ydieresis Ohungarumlaut -15 +KPX Ydieresis Omacron -15 +KPX Ydieresis Oslash -15 +KPX Ydieresis Otilde -15 +KPX Ydieresis a -92 +KPX Ydieresis aacute -92 +KPX Ydieresis abreve -92 +KPX Ydieresis acircumflex -92 +KPX Ydieresis adieresis -92 +KPX Ydieresis agrave -92 +KPX Ydieresis amacron -92 +KPX Ydieresis aogonek -92 +KPX Ydieresis aring -92 +KPX Ydieresis atilde -92 +KPX Ydieresis colon -65 +KPX Ydieresis comma -92 +KPX Ydieresis e -92 +KPX Ydieresis eacute -92 +KPX Ydieresis ecaron -92 +KPX Ydieresis ecircumflex -92 +KPX Ydieresis edieresis -52 +KPX Ydieresis edotaccent -92 +KPX Ydieresis egrave -52 +KPX Ydieresis emacron -52 +KPX Ydieresis eogonek -92 +KPX Ydieresis hyphen -74 +KPX Ydieresis i -74 +KPX Ydieresis iacute -74 +KPX Ydieresis icircumflex -34 +KPX Ydieresis idieresis -34 +KPX Ydieresis igrave -34 +KPX Ydieresis imacron -34 +KPX Ydieresis iogonek -74 +KPX Ydieresis o -92 +KPX Ydieresis oacute -92 +KPX Ydieresis ocircumflex -92 +KPX Ydieresis odieresis -92 +KPX Ydieresis ograve -92 +KPX Ydieresis ohungarumlaut -92 +KPX Ydieresis omacron -92 +KPX Ydieresis oslash -92 +KPX Ydieresis otilde -92 +KPX Ydieresis period -92 +KPX Ydieresis semicolon -65 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX c h -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute h -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron h -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla h -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX comma quotedblright -140 +KPX comma quoteright -140 +KPX e comma -10 +KPX e g -40 +KPX e gbreve -40 +KPX e gcommaaccent -40 +KPX e period -15 +KPX e v -15 +KPX e w -15 +KPX e x -20 +KPX e y -30 +KPX e yacute -30 +KPX e ydieresis -30 +KPX eacute comma -10 +KPX eacute g -40 +KPX eacute gbreve -40 +KPX eacute gcommaaccent -40 +KPX eacute period -15 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -20 +KPX eacute y -30 +KPX eacute yacute -30 +KPX eacute ydieresis -30 +KPX ecaron comma -10 +KPX ecaron g -40 +KPX ecaron gbreve -40 +KPX ecaron gcommaaccent -40 +KPX ecaron period -15 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -20 +KPX ecaron y -30 +KPX ecaron yacute -30 +KPX ecaron ydieresis -30 +KPX ecircumflex comma -10 +KPX ecircumflex g -40 +KPX ecircumflex gbreve -40 +KPX ecircumflex gcommaaccent -40 +KPX ecircumflex period -15 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -20 +KPX ecircumflex y -30 +KPX ecircumflex yacute -30 +KPX ecircumflex ydieresis -30 +KPX edieresis comma -10 +KPX edieresis g -40 +KPX edieresis gbreve -40 +KPX edieresis gcommaaccent -40 +KPX edieresis period -15 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -20 +KPX edieresis y -30 +KPX edieresis yacute -30 +KPX edieresis ydieresis -30 +KPX edotaccent comma -10 +KPX edotaccent g -40 +KPX edotaccent gbreve -40 +KPX edotaccent gcommaaccent -40 +KPX edotaccent period -15 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -20 +KPX edotaccent y -30 +KPX edotaccent yacute -30 +KPX edotaccent ydieresis -30 +KPX egrave comma -10 +KPX egrave g -40 +KPX egrave gbreve -40 +KPX egrave gcommaaccent -40 +KPX egrave period -15 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -20 +KPX egrave y -30 +KPX egrave yacute -30 +KPX egrave ydieresis -30 +KPX emacron comma -10 +KPX emacron g -40 +KPX emacron gbreve -40 +KPX emacron gcommaaccent -40 +KPX emacron period -15 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -20 +KPX emacron y -30 +KPX emacron yacute -30 +KPX emacron ydieresis -30 +KPX eogonek comma -10 +KPX eogonek g -40 +KPX eogonek gbreve -40 +KPX eogonek gcommaaccent -40 +KPX eogonek period -15 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -20 +KPX eogonek y -30 +KPX eogonek yacute -30 +KPX eogonek ydieresis -30 +KPX f comma -10 +KPX f dotlessi -60 +KPX f f -18 +KPX f i -20 +KPX f iogonek -20 +KPX f period -15 +KPX f quoteright 92 +KPX g comma -10 +KPX g e -10 +KPX g eacute -10 +KPX g ecaron -10 +KPX g ecircumflex -10 +KPX g edieresis -10 +KPX g edotaccent -10 +KPX g egrave -10 +KPX g emacron -10 +KPX g eogonek -10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX g period -15 +KPX gbreve comma -10 +KPX gbreve e -10 +KPX gbreve eacute -10 +KPX gbreve ecaron -10 +KPX gbreve ecircumflex -10 +KPX gbreve edieresis -10 +KPX gbreve edotaccent -10 +KPX gbreve egrave -10 +KPX gbreve emacron -10 +KPX gbreve eogonek -10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gbreve period -15 +KPX gcommaaccent comma -10 +KPX gcommaaccent e -10 +KPX gcommaaccent eacute -10 +KPX gcommaaccent ecaron -10 +KPX gcommaaccent ecircumflex -10 +KPX gcommaaccent edieresis -10 +KPX gcommaaccent edotaccent -10 +KPX gcommaaccent egrave -10 +KPX gcommaaccent emacron -10 +KPX gcommaaccent eogonek -10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX gcommaaccent period -15 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX k y -10 +KPX k yacute -10 +KPX k ydieresis -10 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX kcommaaccent y -10 +KPX kcommaaccent yacute -10 +KPX kcommaaccent ydieresis -10 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o g -10 +KPX o gbreve -10 +KPX o gcommaaccent -10 +KPX o v -10 +KPX oacute g -10 +KPX oacute gbreve -10 +KPX oacute gcommaaccent -10 +KPX oacute v -10 +KPX ocircumflex g -10 +KPX ocircumflex gbreve -10 +KPX ocircumflex gcommaaccent -10 +KPX ocircumflex v -10 +KPX odieresis g -10 +KPX odieresis gbreve -10 +KPX odieresis gcommaaccent -10 +KPX odieresis v -10 +KPX ograve g -10 +KPX ograve gbreve -10 +KPX ograve gcommaaccent -10 +KPX ograve v -10 +KPX ohungarumlaut g -10 +KPX ohungarumlaut gbreve -10 +KPX ohungarumlaut gcommaaccent -10 +KPX ohungarumlaut v -10 +KPX omacron g -10 +KPX omacron gbreve -10 +KPX omacron gcommaaccent -10 +KPX omacron v -10 +KPX oslash g -10 +KPX oslash gbreve -10 +KPX oslash gcommaaccent -10 +KPX oslash v -10 +KPX otilde g -10 +KPX otilde gbreve -10 +KPX otilde gcommaaccent -10 +KPX otilde v -10 +KPX period quotedblright -140 +KPX period quoteright -140 +KPX quoteleft quoteleft -111 +KPX quoteright d -25 +KPX quoteright dcroat -25 +KPX quoteright quoteright -111 +KPX quoteright r -25 +KPX quoteright racute -25 +KPX quoteright rcaron -25 +KPX quoteright rcommaaccent -25 +KPX quoteright s -40 +KPX quoteright sacute -40 +KPX quoteright scaron -40 +KPX quoteright scedilla -40 +KPX quoteright scommaaccent -40 +KPX quoteright space -111 +KPX quoteright t -30 +KPX quoteright tcommaaccent -30 +KPX quoteright v -10 +KPX r a -15 +KPX r aacute -15 +KPX r abreve -15 +KPX r acircumflex -15 +KPX r adieresis -15 +KPX r agrave -15 +KPX r amacron -15 +KPX r aogonek -15 +KPX r aring -15 +KPX r atilde -15 +KPX r c -37 +KPX r cacute -37 +KPX r ccaron -37 +KPX r ccedilla -37 +KPX r comma -111 +KPX r d -37 +KPX r dcroat -37 +KPX r e -37 +KPX r eacute -37 +KPX r ecaron -37 +KPX r ecircumflex -37 +KPX r edieresis -37 +KPX r edotaccent -37 +KPX r egrave -37 +KPX r emacron -37 +KPX r eogonek -37 +KPX r g -37 +KPX r gbreve -37 +KPX r gcommaaccent -37 +KPX r hyphen -20 +KPX r o -45 +KPX r oacute -45 +KPX r ocircumflex -45 +KPX r odieresis -45 +KPX r ograve -45 +KPX r ohungarumlaut -45 +KPX r omacron -45 +KPX r oslash -45 +KPX r otilde -45 +KPX r period -111 +KPX r q -37 +KPX r s -10 +KPX r sacute -10 +KPX r scaron -10 +KPX r scedilla -10 +KPX r scommaaccent -10 +KPX racute a -15 +KPX racute aacute -15 +KPX racute abreve -15 +KPX racute acircumflex -15 +KPX racute adieresis -15 +KPX racute agrave -15 +KPX racute amacron -15 +KPX racute aogonek -15 +KPX racute aring -15 +KPX racute atilde -15 +KPX racute c -37 +KPX racute cacute -37 +KPX racute ccaron -37 +KPX racute ccedilla -37 +KPX racute comma -111 +KPX racute d -37 +KPX racute dcroat -37 +KPX racute e -37 +KPX racute eacute -37 +KPX racute ecaron -37 +KPX racute ecircumflex -37 +KPX racute edieresis -37 +KPX racute edotaccent -37 +KPX racute egrave -37 +KPX racute emacron -37 +KPX racute eogonek -37 +KPX racute g -37 +KPX racute gbreve -37 +KPX racute gcommaaccent -37 +KPX racute hyphen -20 +KPX racute o -45 +KPX racute oacute -45 +KPX racute ocircumflex -45 +KPX racute odieresis -45 +KPX racute ograve -45 +KPX racute ohungarumlaut -45 +KPX racute omacron -45 +KPX racute oslash -45 +KPX racute otilde -45 +KPX racute period -111 +KPX racute q -37 +KPX racute s -10 +KPX racute sacute -10 +KPX racute scaron -10 +KPX racute scedilla -10 +KPX racute scommaaccent -10 +KPX rcaron a -15 +KPX rcaron aacute -15 +KPX rcaron abreve -15 +KPX rcaron acircumflex -15 +KPX rcaron adieresis -15 +KPX rcaron agrave -15 +KPX rcaron amacron -15 +KPX rcaron aogonek -15 +KPX rcaron aring -15 +KPX rcaron atilde -15 +KPX rcaron c -37 +KPX rcaron cacute -37 +KPX rcaron ccaron -37 +KPX rcaron ccedilla -37 +KPX rcaron comma -111 +KPX rcaron d -37 +KPX rcaron dcroat -37 +KPX rcaron e -37 +KPX rcaron eacute -37 +KPX rcaron ecaron -37 +KPX rcaron ecircumflex -37 +KPX rcaron edieresis -37 +KPX rcaron edotaccent -37 +KPX rcaron egrave -37 +KPX rcaron emacron -37 +KPX rcaron eogonek -37 +KPX rcaron g -37 +KPX rcaron gbreve -37 +KPX rcaron gcommaaccent -37 +KPX rcaron hyphen -20 +KPX rcaron o -45 +KPX rcaron oacute -45 +KPX rcaron ocircumflex -45 +KPX rcaron odieresis -45 +KPX rcaron ograve -45 +KPX rcaron ohungarumlaut -45 +KPX rcaron omacron -45 +KPX rcaron oslash -45 +KPX rcaron otilde -45 +KPX rcaron period -111 +KPX rcaron q -37 +KPX rcaron s -10 +KPX rcaron sacute -10 +KPX rcaron scaron -10 +KPX rcaron scedilla -10 +KPX rcaron scommaaccent -10 +KPX rcommaaccent a -15 +KPX rcommaaccent aacute -15 +KPX rcommaaccent abreve -15 +KPX rcommaaccent acircumflex -15 +KPX rcommaaccent adieresis -15 +KPX rcommaaccent agrave -15 +KPX rcommaaccent amacron -15 +KPX rcommaaccent aogonek -15 +KPX rcommaaccent aring -15 +KPX rcommaaccent atilde -15 +KPX rcommaaccent c -37 +KPX rcommaaccent cacute -37 +KPX rcommaaccent ccaron -37 +KPX rcommaaccent ccedilla -37 +KPX rcommaaccent comma -111 +KPX rcommaaccent d -37 +KPX rcommaaccent dcroat -37 +KPX rcommaaccent e -37 +KPX rcommaaccent eacute -37 +KPX rcommaaccent ecaron -37 +KPX rcommaaccent ecircumflex -37 +KPX rcommaaccent edieresis -37 +KPX rcommaaccent edotaccent -37 +KPX rcommaaccent egrave -37 +KPX rcommaaccent emacron -37 +KPX rcommaaccent eogonek -37 +KPX rcommaaccent g -37 +KPX rcommaaccent gbreve -37 +KPX rcommaaccent gcommaaccent -37 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -45 +KPX rcommaaccent oacute -45 +KPX rcommaaccent ocircumflex -45 +KPX rcommaaccent odieresis -45 +KPX rcommaaccent ograve -45 +KPX rcommaaccent ohungarumlaut -45 +KPX rcommaaccent omacron -45 +KPX rcommaaccent oslash -45 +KPX rcommaaccent otilde -45 +KPX rcommaaccent period -111 +KPX rcommaaccent q -37 +KPX rcommaaccent s -10 +KPX rcommaaccent sacute -10 +KPX rcommaaccent scaron -10 +KPX rcommaaccent scedilla -10 +KPX rcommaaccent scommaaccent -10 +KPX space A -18 +KPX space Aacute -18 +KPX space Abreve -18 +KPX space Acircumflex -18 +KPX space Adieresis -18 +KPX space Agrave -18 +KPX space Amacron -18 +KPX space Aogonek -18 +KPX space Aring -18 +KPX space Atilde -18 +KPX space T -18 +KPX space Tcaron -18 +KPX space Tcommaaccent -18 +KPX space V -35 +KPX space W -40 +KPX space Y -75 +KPX space Yacute -75 +KPX space Ydieresis -75 +KPX v comma -74 +KPX v period -74 +KPX w comma -74 +KPX w period -74 +KPX y comma -55 +KPX y period -55 +KPX yacute comma -55 +KPX yacute period -55 +KPX ydieresis comma -55 +KPX ydieresis period -55 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm new file mode 100644 index 00000000..a0953f28 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm @@ -0,0 +1,2419 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:49:17 1997 +Comment UniqueID 43068 +Comment VMusage 43909 54934 +FontName Times-Roman +FullName Times Roman +FamilyName Times +Weight Roman +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -168 -218 1000 898 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 662 +XHeight 450 +Ascender 683 +Descender -217 +StdHW 28 +StdVW 84 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ; +C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ; +C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ; +C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ; +C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ; +C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ; +C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ; +C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ; +C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ; +C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ; +C 43 ; WX 564 ; N plus ; B 30 0 534 506 ; +C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ; +C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ; +C 46 ; WX 250 ; N period ; B 70 -11 181 100 ; +C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ; +C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ; +C 49 ; WX 500 ; N one ; B 111 0 394 676 ; +C 50 ; WX 500 ; N two ; B 30 0 475 676 ; +C 51 ; WX 500 ; N three ; B 43 -14 431 676 ; +C 52 ; WX 500 ; N four ; B 12 0 472 676 ; +C 53 ; WX 500 ; N five ; B 32 -14 438 688 ; +C 54 ; WX 500 ; N six ; B 34 -14 468 684 ; +C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ; +C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ; +C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ; +C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ; +C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ; +C 60 ; WX 564 ; N less ; B 28 -8 536 514 ; +C 61 ; WX 564 ; N equal ; B 30 120 534 386 ; +C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ; +C 63 ; WX 444 ; N question ; B 68 -8 414 676 ; +C 64 ; WX 921 ; N at ; B 116 -14 809 676 ; +C 65 ; WX 722 ; N A ; B 15 0 706 674 ; +C 66 ; WX 667 ; N B ; B 17 0 593 662 ; +C 67 ; WX 667 ; N C ; B 28 -14 633 676 ; +C 68 ; WX 722 ; N D ; B 16 0 685 662 ; +C 69 ; WX 611 ; N E ; B 12 0 597 662 ; +C 70 ; WX 556 ; N F ; B 12 0 546 662 ; +C 71 ; WX 722 ; N G ; B 32 -14 709 676 ; +C 72 ; WX 722 ; N H ; B 19 0 702 662 ; +C 73 ; WX 333 ; N I ; B 18 0 315 662 ; +C 74 ; WX 389 ; N J ; B 10 -14 370 662 ; +C 75 ; WX 722 ; N K ; B 34 0 723 662 ; +C 76 ; WX 611 ; N L ; B 12 0 598 662 ; +C 77 ; WX 889 ; N M ; B 12 0 863 662 ; +C 78 ; WX 722 ; N N ; B 12 -11 707 662 ; +C 79 ; WX 722 ; N O ; B 34 -14 688 676 ; +C 80 ; WX 556 ; N P ; B 16 0 542 662 ; +C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ; +C 82 ; WX 667 ; N R ; B 17 0 659 662 ; +C 83 ; WX 556 ; N S ; B 42 -14 491 676 ; +C 84 ; WX 611 ; N T ; B 17 0 593 662 ; +C 85 ; WX 722 ; N U ; B 14 -14 705 662 ; +C 86 ; WX 722 ; N V ; B 16 -11 697 662 ; +C 87 ; WX 944 ; N W ; B 5 -11 932 662 ; +C 88 ; WX 722 ; N X ; B 10 0 704 662 ; +C 89 ; WX 722 ; N Y ; B 22 0 703 662 ; +C 90 ; WX 611 ; N Z ; B 9 0 597 662 ; +C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ; +C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ; +C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ; +C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ; +C 97 ; WX 444 ; N a ; B 37 -10 442 460 ; +C 98 ; WX 500 ; N b ; B 3 -10 468 683 ; +C 99 ; WX 444 ; N c ; B 25 -10 412 460 ; +C 100 ; WX 500 ; N d ; B 27 -10 491 683 ; +C 101 ; WX 444 ; N e ; B 25 -10 424 460 ; +C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -218 470 460 ; +C 104 ; WX 500 ; N h ; B 9 0 487 683 ; +C 105 ; WX 278 ; N i ; B 16 0 253 683 ; +C 106 ; WX 278 ; N j ; B -70 -218 194 683 ; +C 107 ; WX 500 ; N k ; B 7 0 505 683 ; +C 108 ; WX 278 ; N l ; B 19 0 257 683 ; +C 109 ; WX 778 ; N m ; B 16 0 775 460 ; +C 110 ; WX 500 ; N n ; B 16 0 485 460 ; +C 111 ; WX 500 ; N o ; B 29 -10 470 460 ; +C 112 ; WX 500 ; N p ; B 5 -217 470 460 ; +C 113 ; WX 500 ; N q ; B 24 -217 488 460 ; +C 114 ; WX 333 ; N r ; B 5 0 335 460 ; +C 115 ; WX 389 ; N s ; B 51 -10 348 460 ; +C 116 ; WX 278 ; N t ; B 13 -10 279 579 ; +C 117 ; WX 500 ; N u ; B 9 -10 479 450 ; +C 118 ; WX 500 ; N v ; B 19 -14 477 450 ; +C 119 ; WX 722 ; N w ; B 21 -14 694 450 ; +C 120 ; WX 500 ; N x ; B 17 0 479 450 ; +C 121 ; WX 500 ; N y ; B 14 -218 475 450 ; +C 122 ; WX 444 ; N z ; B 27 0 418 450 ; +C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ; +C 124 ; WX 200 ; N bar ; B 67 -218 133 782 ; +C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ; +C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ; +C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ; +C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ; +C 165 ; WX 500 ; N yen ; B -53 0 512 662 ; +C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ; +C 167 ; WX 500 ; N section ; B 70 -148 426 676 ; +C 168 ; WX 500 ; N currency ; B -22 58 522 602 ; +C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ; +C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ; +C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ; +C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ; +C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ; +C 174 ; WX 556 ; N fi ; B 31 0 521 683 ; +C 175 ; WX 556 ; N fl ; B 32 0 521 683 ; +C 177 ; WX 500 ; N endash ; B 0 201 500 250 ; +C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ; +C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ; +C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ; +C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ; +C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ; +C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ; +C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ; +C 193 ; WX 333 ; N grave ; B 19 507 242 678 ; +C 194 ; WX 333 ; N acute ; B 93 507 317 678 ; +C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ; +C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ; +C 197 ; WX 333 ; N macron ; B 11 547 322 601 ; +C 198 ; WX 333 ; N breve ; B 26 507 307 664 ; +C 199 ; WX 333 ; N dotaccent ; B 118 581 216 681 ; +C 200 ; WX 333 ; N dieresis ; B 18 581 315 681 ; +C 202 ; WX 333 ; N ring ; B 67 512 266 711 ; +C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ; +C 206 ; WX 333 ; N ogonek ; B 62 -165 243 0 ; +C 207 ; WX 333 ; N caron ; B 11 507 322 674 ; +C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ; +C 225 ; WX 889 ; N AE ; B 0 0 863 662 ; +C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ; +C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ; +C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ; +C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ; +C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ; +C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ; +C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ; +C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ; +C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ; +C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ; +C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ; +C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ; +C -1 ; WX 444 ; N abreve ; B 37 -10 442 664 ; +C -1 ; WX 500 ; N uhungarumlaut ; B 9 -10 501 678 ; +C -1 ; WX 444 ; N ecaron ; B 25 -10 424 674 ; +C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ; +C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ; +C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ; +C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ; +C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ; +C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ; +C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ; +C -1 ; WX 389 ; N scommaaccent ; B 51 -218 348 460 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ; +C -1 ; WX 722 ; N Uring ; B 14 -14 705 898 ; +C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ; +C -1 ; WX 444 ; N aogonek ; B 37 -165 469 460 ; +C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ; +C -1 ; WX 500 ; N uogonek ; B 9 -155 487 450 ; +C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ; +C -1 ; WX 722 ; N Dcroat ; B 16 0 685 662 ; +C -1 ; WX 250 ; N commaaccent ; B 59 -218 184 -50 ; +C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ; +C -1 ; WX 611 ; N Emacron ; B 12 0 597 813 ; +C -1 ; WX 444 ; N ccaron ; B 25 -10 412 674 ; +C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 12 -198 707 662 ; +C -1 ; WX 278 ; N lacute ; B 19 0 290 890 ; +C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 17 -218 593 662 ; +C -1 ; WX 667 ; N Cacute ; B 28 -14 633 890 ; +C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ; +C -1 ; WX 611 ; N Edotaccent ; B 12 0 597 835 ; +C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ; +C -1 ; WX 389 ; N scedilla ; B 51 -215 348 460 ; +C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ; +C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; +C -1 ; WX 667 ; N Rcaron ; B 17 0 659 886 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 32 -218 709 676 ; +C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ; +C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ; +C -1 ; WX 722 ; N Amacron ; B 15 0 706 813 ; +C -1 ; WX 333 ; N rcaron ; B 5 0 335 674 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ; +C -1 ; WX 611 ; N Zdotaccent ; B 9 0 597 835 ; +C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ; +C -1 ; WX 722 ; N Omacron ; B 34 -14 688 813 ; +C -1 ; WX 667 ; N Racute ; B 17 0 659 890 ; +C -1 ; WX 556 ; N Sacute ; B 42 -14 491 890 ; +C -1 ; WX 588 ; N dcaron ; B 27 -10 589 695 ; +C -1 ; WX 722 ; N Umacron ; B 14 -14 705 813 ; +C -1 ; WX 500 ; N uring ; B 9 -10 479 711 ; +C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ; +C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ; +C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ; +C -1 ; WX 722 ; N Abreve ; B 15 0 706 876 ; +C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ; +C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ; +C -1 ; WX 611 ; N Tcaron ; B 17 0 593 886 ; +C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ; +C -1 ; WX 722 ; N Nacute ; B 12 -11 707 890 ; +C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ; +C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ; +C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ; +C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ; +C -1 ; WX 444 ; N cacute ; B 25 -10 413 678 ; +C -1 ; WX 500 ; N nacute ; B 16 0 485 678 ; +C -1 ; WX 500 ; N umacron ; B 9 -10 479 601 ; +C -1 ; WX 722 ; N Ncaron ; B 12 -11 707 886 ; +C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ; +C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ; +C -1 ; WX 200 ; N brokenbar ; B 67 -143 133 707 ; +C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ; +C -1 ; WX 722 ; N Gbreve ; B 32 -14 709 876 ; +C -1 ; WX 333 ; N Idotaccent ; B 18 0 315 835 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ; +C -1 ; WX 333 ; N racute ; B 5 0 335 678 ; +C -1 ; WX 500 ; N omacron ; B 29 -10 470 601 ; +C -1 ; WX 611 ; N Zacute ; B 9 0 597 890 ; +C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 666 ; +C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ; +C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ; +C -1 ; WX 278 ; N lcommaaccent ; B 19 -218 257 683 ; +C -1 ; WX 326 ; N tcaron ; B 13 -10 318 722 ; +C -1 ; WX 444 ; N eogonek ; B 25 -165 424 460 ; +C -1 ; WX 722 ; N Uogonek ; B 14 -165 705 662 ; +C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ; +C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ; +C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ; +C -1 ; WX 444 ; N zacute ; B 27 0 418 678 ; +C -1 ; WX 278 ; N iogonek ; B 16 -165 265 683 ; +C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ; +C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ; +C -1 ; WX 444 ; N amacron ; B 37 -10 442 601 ; +C -1 ; WX 389 ; N sacute ; B 51 -10 348 678 ; +C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ; +C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ; +C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ; +C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ; +C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ; +C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ; +C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 29 -10 491 678 ; +C -1 ; WX 611 ; N Eogonek ; B 12 -165 597 662 ; +C -1 ; WX 500 ; N dcroat ; B 27 -10 500 683 ; +C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ; +C -1 ; WX 556 ; N Scedilla ; B 42 -215 491 676 ; +C -1 ; WX 344 ; N lcaron ; B 19 0 347 695 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 34 -198 723 662 ; +C -1 ; WX 611 ; N Lacute ; B 12 0 598 890 ; +C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ; +C -1 ; WX 444 ; N edotaccent ; B 25 -10 424 623 ; +C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ; +C -1 ; WX 333 ; N Imacron ; B 11 0 322 813 ; +C -1 ; WX 611 ; N Lcaron ; B 12 0 598 676 ; +C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 666 ; +C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ; +C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 14 -14 705 890 ; +C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ; +C -1 ; WX 444 ; N emacron ; B 25 -10 424 601 ; +C -1 ; WX 500 ; N gbreve ; B 28 -218 470 664 ; +C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ; +C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ; +C -1 ; WX 556 ; N Scommaaccent ; B 42 -218 491 676 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 34 -14 688 890 ; +C -1 ; WX 400 ; N degree ; B 57 390 343 676 ; +C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ; +C -1 ; WX 667 ; N Ccaron ; B 28 -14 633 886 ; +C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ; +C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; +C -1 ; WX 722 ; N Dcaron ; B 16 0 685 886 ; +C -1 ; WX 333 ; N rcommaaccent ; B 5 -218 335 460 ; +C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ; +C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ; +C -1 ; WX 667 ; N Rcommaaccent ; B 17 -198 659 662 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 12 -218 598 662 ; +C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ; +C -1 ; WX 722 ; N Aogonek ; B 15 -165 738 674 ; +C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ; +C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ; +C -1 ; WX 444 ; N zdotaccent ; B 27 0 418 623 ; +C -1 ; WX 611 ; N Ecaron ; B 12 0 597 886 ; +C -1 ; WX 333 ; N Iogonek ; B 18 -165 315 662 ; +C -1 ; WX 500 ; N kcommaaccent ; B 7 -218 505 683 ; +C -1 ; WX 564 ; N minus ; B 30 220 534 286 ; +C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ; +C -1 ; WX 500 ; N ncaron ; B 16 0 485 674 ; +C -1 ; WX 278 ; N tcommaaccent ; B 13 -218 279 579 ; +C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ; +C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ; +C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ; +C -1 ; WX 549 ; N notequal ; B 12 -31 537 547 ; +C -1 ; WX 500 ; N gcommaaccent ; B 28 -218 470 749 ; +C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ; +C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ; +C -1 ; WX 500 ; N ncommaaccent ; B 16 -218 485 460 ; +C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ; +C -1 ; WX 278 ; N imacron ; B 6 0 271 601 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2073 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -40 +KPX A Gbreve -40 +KPX A Gcommaaccent -40 +KPX A O -55 +KPX A Oacute -55 +KPX A Ocircumflex -55 +KPX A Odieresis -55 +KPX A Ograve -55 +KPX A Ohungarumlaut -55 +KPX A Omacron -55 +KPX A Oslash -55 +KPX A Otilde -55 +KPX A Q -55 +KPX A T -111 +KPX A Tcaron -111 +KPX A Tcommaaccent -111 +KPX A U -55 +KPX A Uacute -55 +KPX A Ucircumflex -55 +KPX A Udieresis -55 +KPX A Ugrave -55 +KPX A Uhungarumlaut -55 +KPX A Umacron -55 +KPX A Uogonek -55 +KPX A Uring -55 +KPX A V -135 +KPX A W -90 +KPX A Y -105 +KPX A Yacute -105 +KPX A Ydieresis -105 +KPX A quoteright -111 +KPX A v -74 +KPX A w -92 +KPX A y -92 +KPX A yacute -92 +KPX A ydieresis -92 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -40 +KPX Aacute Gbreve -40 +KPX Aacute Gcommaaccent -40 +KPX Aacute O -55 +KPX Aacute Oacute -55 +KPX Aacute Ocircumflex -55 +KPX Aacute Odieresis -55 +KPX Aacute Ograve -55 +KPX Aacute Ohungarumlaut -55 +KPX Aacute Omacron -55 +KPX Aacute Oslash -55 +KPX Aacute Otilde -55 +KPX Aacute Q -55 +KPX Aacute T -111 +KPX Aacute Tcaron -111 +KPX Aacute Tcommaaccent -111 +KPX Aacute U -55 +KPX Aacute Uacute -55 +KPX Aacute Ucircumflex -55 +KPX Aacute Udieresis -55 +KPX Aacute Ugrave -55 +KPX Aacute Uhungarumlaut -55 +KPX Aacute Umacron -55 +KPX Aacute Uogonek -55 +KPX Aacute Uring -55 +KPX Aacute V -135 +KPX Aacute W -90 +KPX Aacute Y -105 +KPX Aacute Yacute -105 +KPX Aacute Ydieresis -105 +KPX Aacute quoteright -111 +KPX Aacute v -74 +KPX Aacute w -92 +KPX Aacute y -92 +KPX Aacute yacute -92 +KPX Aacute ydieresis -92 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -40 +KPX Abreve Gbreve -40 +KPX Abreve Gcommaaccent -40 +KPX Abreve O -55 +KPX Abreve Oacute -55 +KPX Abreve Ocircumflex -55 +KPX Abreve Odieresis -55 +KPX Abreve Ograve -55 +KPX Abreve Ohungarumlaut -55 +KPX Abreve Omacron -55 +KPX Abreve Oslash -55 +KPX Abreve Otilde -55 +KPX Abreve Q -55 +KPX Abreve T -111 +KPX Abreve Tcaron -111 +KPX Abreve Tcommaaccent -111 +KPX Abreve U -55 +KPX Abreve Uacute -55 +KPX Abreve Ucircumflex -55 +KPX Abreve Udieresis -55 +KPX Abreve Ugrave -55 +KPX Abreve Uhungarumlaut -55 +KPX Abreve Umacron -55 +KPX Abreve Uogonek -55 +KPX Abreve Uring -55 +KPX Abreve V -135 +KPX Abreve W -90 +KPX Abreve Y -105 +KPX Abreve Yacute -105 +KPX Abreve Ydieresis -105 +KPX Abreve quoteright -111 +KPX Abreve v -74 +KPX Abreve w -92 +KPX Abreve y -92 +KPX Abreve yacute -92 +KPX Abreve ydieresis -92 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -40 +KPX Acircumflex Gbreve -40 +KPX Acircumflex Gcommaaccent -40 +KPX Acircumflex O -55 +KPX Acircumflex Oacute -55 +KPX Acircumflex Ocircumflex -55 +KPX Acircumflex Odieresis -55 +KPX Acircumflex Ograve -55 +KPX Acircumflex Ohungarumlaut -55 +KPX Acircumflex Omacron -55 +KPX Acircumflex Oslash -55 +KPX Acircumflex Otilde -55 +KPX Acircumflex Q -55 +KPX Acircumflex T -111 +KPX Acircumflex Tcaron -111 +KPX Acircumflex Tcommaaccent -111 +KPX Acircumflex U -55 +KPX Acircumflex Uacute -55 +KPX Acircumflex Ucircumflex -55 +KPX Acircumflex Udieresis -55 +KPX Acircumflex Ugrave -55 +KPX Acircumflex Uhungarumlaut -55 +KPX Acircumflex Umacron -55 +KPX Acircumflex Uogonek -55 +KPX Acircumflex Uring -55 +KPX Acircumflex V -135 +KPX Acircumflex W -90 +KPX Acircumflex Y -105 +KPX Acircumflex Yacute -105 +KPX Acircumflex Ydieresis -105 +KPX Acircumflex quoteright -111 +KPX Acircumflex v -74 +KPX Acircumflex w -92 +KPX Acircumflex y -92 +KPX Acircumflex yacute -92 +KPX Acircumflex ydieresis -92 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -40 +KPX Adieresis Gbreve -40 +KPX Adieresis Gcommaaccent -40 +KPX Adieresis O -55 +KPX Adieresis Oacute -55 +KPX Adieresis Ocircumflex -55 +KPX Adieresis Odieresis -55 +KPX Adieresis Ograve -55 +KPX Adieresis Ohungarumlaut -55 +KPX Adieresis Omacron -55 +KPX Adieresis Oslash -55 +KPX Adieresis Otilde -55 +KPX Adieresis Q -55 +KPX Adieresis T -111 +KPX Adieresis Tcaron -111 +KPX Adieresis Tcommaaccent -111 +KPX Adieresis U -55 +KPX Adieresis Uacute -55 +KPX Adieresis Ucircumflex -55 +KPX Adieresis Udieresis -55 +KPX Adieresis Ugrave -55 +KPX Adieresis Uhungarumlaut -55 +KPX Adieresis Umacron -55 +KPX Adieresis Uogonek -55 +KPX Adieresis Uring -55 +KPX Adieresis V -135 +KPX Adieresis W -90 +KPX Adieresis Y -105 +KPX Adieresis Yacute -105 +KPX Adieresis Ydieresis -105 +KPX Adieresis quoteright -111 +KPX Adieresis v -74 +KPX Adieresis w -92 +KPX Adieresis y -92 +KPX Adieresis yacute -92 +KPX Adieresis ydieresis -92 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -40 +KPX Agrave Gbreve -40 +KPX Agrave Gcommaaccent -40 +KPX Agrave O -55 +KPX Agrave Oacute -55 +KPX Agrave Ocircumflex -55 +KPX Agrave Odieresis -55 +KPX Agrave Ograve -55 +KPX Agrave Ohungarumlaut -55 +KPX Agrave Omacron -55 +KPX Agrave Oslash -55 +KPX Agrave Otilde -55 +KPX Agrave Q -55 +KPX Agrave T -111 +KPX Agrave Tcaron -111 +KPX Agrave Tcommaaccent -111 +KPX Agrave U -55 +KPX Agrave Uacute -55 +KPX Agrave Ucircumflex -55 +KPX Agrave Udieresis -55 +KPX Agrave Ugrave -55 +KPX Agrave Uhungarumlaut -55 +KPX Agrave Umacron -55 +KPX Agrave Uogonek -55 +KPX Agrave Uring -55 +KPX Agrave V -135 +KPX Agrave W -90 +KPX Agrave Y -105 +KPX Agrave Yacute -105 +KPX Agrave Ydieresis -105 +KPX Agrave quoteright -111 +KPX Agrave v -74 +KPX Agrave w -92 +KPX Agrave y -92 +KPX Agrave yacute -92 +KPX Agrave ydieresis -92 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -40 +KPX Amacron Gbreve -40 +KPX Amacron Gcommaaccent -40 +KPX Amacron O -55 +KPX Amacron Oacute -55 +KPX Amacron Ocircumflex -55 +KPX Amacron Odieresis -55 +KPX Amacron Ograve -55 +KPX Amacron Ohungarumlaut -55 +KPX Amacron Omacron -55 +KPX Amacron Oslash -55 +KPX Amacron Otilde -55 +KPX Amacron Q -55 +KPX Amacron T -111 +KPX Amacron Tcaron -111 +KPX Amacron Tcommaaccent -111 +KPX Amacron U -55 +KPX Amacron Uacute -55 +KPX Amacron Ucircumflex -55 +KPX Amacron Udieresis -55 +KPX Amacron Ugrave -55 +KPX Amacron Uhungarumlaut -55 +KPX Amacron Umacron -55 +KPX Amacron Uogonek -55 +KPX Amacron Uring -55 +KPX Amacron V -135 +KPX Amacron W -90 +KPX Amacron Y -105 +KPX Amacron Yacute -105 +KPX Amacron Ydieresis -105 +KPX Amacron quoteright -111 +KPX Amacron v -74 +KPX Amacron w -92 +KPX Amacron y -92 +KPX Amacron yacute -92 +KPX Amacron ydieresis -92 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -40 +KPX Aogonek Gbreve -40 +KPX Aogonek Gcommaaccent -40 +KPX Aogonek O -55 +KPX Aogonek Oacute -55 +KPX Aogonek Ocircumflex -55 +KPX Aogonek Odieresis -55 +KPX Aogonek Ograve -55 +KPX Aogonek Ohungarumlaut -55 +KPX Aogonek Omacron -55 +KPX Aogonek Oslash -55 +KPX Aogonek Otilde -55 +KPX Aogonek Q -55 +KPX Aogonek T -111 +KPX Aogonek Tcaron -111 +KPX Aogonek Tcommaaccent -111 +KPX Aogonek U -55 +KPX Aogonek Uacute -55 +KPX Aogonek Ucircumflex -55 +KPX Aogonek Udieresis -55 +KPX Aogonek Ugrave -55 +KPX Aogonek Uhungarumlaut -55 +KPX Aogonek Umacron -55 +KPX Aogonek Uogonek -55 +KPX Aogonek Uring -55 +KPX Aogonek V -135 +KPX Aogonek W -90 +KPX Aogonek Y -105 +KPX Aogonek Yacute -105 +KPX Aogonek Ydieresis -105 +KPX Aogonek quoteright -111 +KPX Aogonek v -74 +KPX Aogonek w -52 +KPX Aogonek y -52 +KPX Aogonek yacute -52 +KPX Aogonek ydieresis -52 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -40 +KPX Aring Gbreve -40 +KPX Aring Gcommaaccent -40 +KPX Aring O -55 +KPX Aring Oacute -55 +KPX Aring Ocircumflex -55 +KPX Aring Odieresis -55 +KPX Aring Ograve -55 +KPX Aring Ohungarumlaut -55 +KPX Aring Omacron -55 +KPX Aring Oslash -55 +KPX Aring Otilde -55 +KPX Aring Q -55 +KPX Aring T -111 +KPX Aring Tcaron -111 +KPX Aring Tcommaaccent -111 +KPX Aring U -55 +KPX Aring Uacute -55 +KPX Aring Ucircumflex -55 +KPX Aring Udieresis -55 +KPX Aring Ugrave -55 +KPX Aring Uhungarumlaut -55 +KPX Aring Umacron -55 +KPX Aring Uogonek -55 +KPX Aring Uring -55 +KPX Aring V -135 +KPX Aring W -90 +KPX Aring Y -105 +KPX Aring Yacute -105 +KPX Aring Ydieresis -105 +KPX Aring quoteright -111 +KPX Aring v -74 +KPX Aring w -92 +KPX Aring y -92 +KPX Aring yacute -92 +KPX Aring ydieresis -92 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -40 +KPX Atilde Gbreve -40 +KPX Atilde Gcommaaccent -40 +KPX Atilde O -55 +KPX Atilde Oacute -55 +KPX Atilde Ocircumflex -55 +KPX Atilde Odieresis -55 +KPX Atilde Ograve -55 +KPX Atilde Ohungarumlaut -55 +KPX Atilde Omacron -55 +KPX Atilde Oslash -55 +KPX Atilde Otilde -55 +KPX Atilde Q -55 +KPX Atilde T -111 +KPX Atilde Tcaron -111 +KPX Atilde Tcommaaccent -111 +KPX Atilde U -55 +KPX Atilde Uacute -55 +KPX Atilde Ucircumflex -55 +KPX Atilde Udieresis -55 +KPX Atilde Ugrave -55 +KPX Atilde Uhungarumlaut -55 +KPX Atilde Umacron -55 +KPX Atilde Uogonek -55 +KPX Atilde Uring -55 +KPX Atilde V -135 +KPX Atilde W -90 +KPX Atilde Y -105 +KPX Atilde Yacute -105 +KPX Atilde Ydieresis -105 +KPX Atilde quoteright -111 +KPX Atilde v -74 +KPX Atilde w -92 +KPX Atilde y -92 +KPX Atilde yacute -92 +KPX Atilde ydieresis -92 +KPX B A -35 +KPX B Aacute -35 +KPX B Abreve -35 +KPX B Acircumflex -35 +KPX B Adieresis -35 +KPX B Agrave -35 +KPX B Amacron -35 +KPX B Aogonek -35 +KPX B Aring -35 +KPX B Atilde -35 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -30 +KPX D Y -55 +KPX D Yacute -55 +KPX D Ydieresis -55 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -30 +KPX Dcaron Y -55 +KPX Dcaron Yacute -55 +KPX Dcaron Ydieresis -55 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -30 +KPX Dcroat Y -55 +KPX Dcroat Yacute -55 +KPX Dcroat Ydieresis -55 +KPX F A -74 +KPX F Aacute -74 +KPX F Abreve -74 +KPX F Acircumflex -74 +KPX F Adieresis -74 +KPX F Agrave -74 +KPX F Amacron -74 +KPX F Aogonek -74 +KPX F Aring -74 +KPX F Atilde -74 +KPX F a -15 +KPX F aacute -15 +KPX F abreve -15 +KPX F acircumflex -15 +KPX F adieresis -15 +KPX F agrave -15 +KPX F amacron -15 +KPX F aogonek -15 +KPX F aring -15 +KPX F atilde -15 +KPX F comma -80 +KPX F o -15 +KPX F oacute -15 +KPX F ocircumflex -15 +KPX F odieresis -15 +KPX F ograve -15 +KPX F ohungarumlaut -15 +KPX F omacron -15 +KPX F oslash -15 +KPX F otilde -15 +KPX F period -80 +KPX J A -60 +KPX J Aacute -60 +KPX J Abreve -60 +KPX J Acircumflex -60 +KPX J Adieresis -60 +KPX J Agrave -60 +KPX J Amacron -60 +KPX J Aogonek -60 +KPX J Aring -60 +KPX J Atilde -60 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -15 +KPX K uacute -15 +KPX K ucircumflex -15 +KPX K udieresis -15 +KPX K ugrave -15 +KPX K uhungarumlaut -15 +KPX K umacron -15 +KPX K uogonek -15 +KPX K uring -15 +KPX K y -25 +KPX K yacute -25 +KPX K ydieresis -25 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -15 +KPX Kcommaaccent uacute -15 +KPX Kcommaaccent ucircumflex -15 +KPX Kcommaaccent udieresis -15 +KPX Kcommaaccent ugrave -15 +KPX Kcommaaccent uhungarumlaut -15 +KPX Kcommaaccent umacron -15 +KPX Kcommaaccent uogonek -15 +KPX Kcommaaccent uring -15 +KPX Kcommaaccent y -25 +KPX Kcommaaccent yacute -25 +KPX Kcommaaccent ydieresis -25 +KPX L T -92 +KPX L Tcaron -92 +KPX L Tcommaaccent -92 +KPX L V -100 +KPX L W -74 +KPX L Y -100 +KPX L Yacute -100 +KPX L Ydieresis -100 +KPX L quoteright -92 +KPX L y -55 +KPX L yacute -55 +KPX L ydieresis -55 +KPX Lacute T -92 +KPX Lacute Tcaron -92 +KPX Lacute Tcommaaccent -92 +KPX Lacute V -100 +KPX Lacute W -74 +KPX Lacute Y -100 +KPX Lacute Yacute -100 +KPX Lacute Ydieresis -100 +KPX Lacute quoteright -92 +KPX Lacute y -55 +KPX Lacute yacute -55 +KPX Lacute ydieresis -55 +KPX Lcaron quoteright -92 +KPX Lcaron y -55 +KPX Lcaron yacute -55 +KPX Lcaron ydieresis -55 +KPX Lcommaaccent T -92 +KPX Lcommaaccent Tcaron -92 +KPX Lcommaaccent Tcommaaccent -92 +KPX Lcommaaccent V -100 +KPX Lcommaaccent W -74 +KPX Lcommaaccent Y -100 +KPX Lcommaaccent Yacute -100 +KPX Lcommaaccent Ydieresis -100 +KPX Lcommaaccent quoteright -92 +KPX Lcommaaccent y -55 +KPX Lcommaaccent yacute -55 +KPX Lcommaaccent ydieresis -55 +KPX Lslash T -92 +KPX Lslash Tcaron -92 +KPX Lslash Tcommaaccent -92 +KPX Lslash V -100 +KPX Lslash W -74 +KPX Lslash Y -100 +KPX Lslash Yacute -100 +KPX Lslash Ydieresis -100 +KPX Lslash quoteright -92 +KPX Lslash y -55 +KPX Lslash yacute -55 +KPX Lslash ydieresis -55 +KPX N A -35 +KPX N Aacute -35 +KPX N Abreve -35 +KPX N Acircumflex -35 +KPX N Adieresis -35 +KPX N Agrave -35 +KPX N Amacron -35 +KPX N Aogonek -35 +KPX N Aring -35 +KPX N Atilde -35 +KPX Nacute A -35 +KPX Nacute Aacute -35 +KPX Nacute Abreve -35 +KPX Nacute Acircumflex -35 +KPX Nacute Adieresis -35 +KPX Nacute Agrave -35 +KPX Nacute Amacron -35 +KPX Nacute Aogonek -35 +KPX Nacute Aring -35 +KPX Nacute Atilde -35 +KPX Ncaron A -35 +KPX Ncaron Aacute -35 +KPX Ncaron Abreve -35 +KPX Ncaron Acircumflex -35 +KPX Ncaron Adieresis -35 +KPX Ncaron Agrave -35 +KPX Ncaron Amacron -35 +KPX Ncaron Aogonek -35 +KPX Ncaron Aring -35 +KPX Ncaron Atilde -35 +KPX Ncommaaccent A -35 +KPX Ncommaaccent Aacute -35 +KPX Ncommaaccent Abreve -35 +KPX Ncommaaccent Acircumflex -35 +KPX Ncommaaccent Adieresis -35 +KPX Ncommaaccent Agrave -35 +KPX Ncommaaccent Amacron -35 +KPX Ncommaaccent Aogonek -35 +KPX Ncommaaccent Aring -35 +KPX Ncommaaccent Atilde -35 +KPX Ntilde A -35 +KPX Ntilde Aacute -35 +KPX Ntilde Abreve -35 +KPX Ntilde Acircumflex -35 +KPX Ntilde Adieresis -35 +KPX Ntilde Agrave -35 +KPX Ntilde Amacron -35 +KPX Ntilde Aogonek -35 +KPX Ntilde Aring -35 +KPX Ntilde Atilde -35 +KPX O A -35 +KPX O Aacute -35 +KPX O Abreve -35 +KPX O Acircumflex -35 +KPX O Adieresis -35 +KPX O Agrave -35 +KPX O Amacron -35 +KPX O Aogonek -35 +KPX O Aring -35 +KPX O Atilde -35 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -35 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -35 +KPX Oacute Aacute -35 +KPX Oacute Abreve -35 +KPX Oacute Acircumflex -35 +KPX Oacute Adieresis -35 +KPX Oacute Agrave -35 +KPX Oacute Amacron -35 +KPX Oacute Aogonek -35 +KPX Oacute Aring -35 +KPX Oacute Atilde -35 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -35 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -35 +KPX Ocircumflex Aacute -35 +KPX Ocircumflex Abreve -35 +KPX Ocircumflex Acircumflex -35 +KPX Ocircumflex Adieresis -35 +KPX Ocircumflex Agrave -35 +KPX Ocircumflex Amacron -35 +KPX Ocircumflex Aogonek -35 +KPX Ocircumflex Aring -35 +KPX Ocircumflex Atilde -35 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -35 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -35 +KPX Odieresis Aacute -35 +KPX Odieresis Abreve -35 +KPX Odieresis Acircumflex -35 +KPX Odieresis Adieresis -35 +KPX Odieresis Agrave -35 +KPX Odieresis Amacron -35 +KPX Odieresis Aogonek -35 +KPX Odieresis Aring -35 +KPX Odieresis Atilde -35 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -35 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -35 +KPX Ograve Aacute -35 +KPX Ograve Abreve -35 +KPX Ograve Acircumflex -35 +KPX Ograve Adieresis -35 +KPX Ograve Agrave -35 +KPX Ograve Amacron -35 +KPX Ograve Aogonek -35 +KPX Ograve Aring -35 +KPX Ograve Atilde -35 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -35 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -35 +KPX Ohungarumlaut Aacute -35 +KPX Ohungarumlaut Abreve -35 +KPX Ohungarumlaut Acircumflex -35 +KPX Ohungarumlaut Adieresis -35 +KPX Ohungarumlaut Agrave -35 +KPX Ohungarumlaut Amacron -35 +KPX Ohungarumlaut Aogonek -35 +KPX Ohungarumlaut Aring -35 +KPX Ohungarumlaut Atilde -35 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -35 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -35 +KPX Omacron Aacute -35 +KPX Omacron Abreve -35 +KPX Omacron Acircumflex -35 +KPX Omacron Adieresis -35 +KPX Omacron Agrave -35 +KPX Omacron Amacron -35 +KPX Omacron Aogonek -35 +KPX Omacron Aring -35 +KPX Omacron Atilde -35 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -35 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -35 +KPX Oslash Aacute -35 +KPX Oslash Abreve -35 +KPX Oslash Acircumflex -35 +KPX Oslash Adieresis -35 +KPX Oslash Agrave -35 +KPX Oslash Amacron -35 +KPX Oslash Aogonek -35 +KPX Oslash Aring -35 +KPX Oslash Atilde -35 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -35 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -35 +KPX Otilde Aacute -35 +KPX Otilde Abreve -35 +KPX Otilde Acircumflex -35 +KPX Otilde Adieresis -35 +KPX Otilde Agrave -35 +KPX Otilde Amacron -35 +KPX Otilde Aogonek -35 +KPX Otilde Aring -35 +KPX Otilde Atilde -35 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -35 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -92 +KPX P Aacute -92 +KPX P Abreve -92 +KPX P Acircumflex -92 +KPX P Adieresis -92 +KPX P Agrave -92 +KPX P Amacron -92 +KPX P Aogonek -92 +KPX P Aring -92 +KPX P Atilde -92 +KPX P a -15 +KPX P aacute -15 +KPX P abreve -15 +KPX P acircumflex -15 +KPX P adieresis -15 +KPX P agrave -15 +KPX P amacron -15 +KPX P aogonek -15 +KPX P aring -15 +KPX P atilde -15 +KPX P comma -111 +KPX P period -111 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R T -60 +KPX R Tcaron -60 +KPX R Tcommaaccent -60 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -80 +KPX R W -55 +KPX R Y -65 +KPX R Yacute -65 +KPX R Ydieresis -65 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute T -60 +KPX Racute Tcaron -60 +KPX Racute Tcommaaccent -60 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -80 +KPX Racute W -55 +KPX Racute Y -65 +KPX Racute Yacute -65 +KPX Racute Ydieresis -65 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron T -60 +KPX Rcaron Tcaron -60 +KPX Rcaron Tcommaaccent -60 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -80 +KPX Rcaron W -55 +KPX Rcaron Y -65 +KPX Rcaron Yacute -65 +KPX Rcaron Ydieresis -65 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent T -60 +KPX Rcommaaccent Tcaron -60 +KPX Rcommaaccent Tcommaaccent -60 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -80 +KPX Rcommaaccent W -55 +KPX Rcommaaccent Y -65 +KPX Rcommaaccent Yacute -65 +KPX Rcommaaccent Ydieresis -65 +KPX T A -93 +KPX T Aacute -93 +KPX T Abreve -93 +KPX T Acircumflex -93 +KPX T Adieresis -93 +KPX T Agrave -93 +KPX T Amacron -93 +KPX T Aogonek -93 +KPX T Aring -93 +KPX T Atilde -93 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -40 +KPX T agrave -40 +KPX T amacron -40 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -40 +KPX T colon -50 +KPX T comma -74 +KPX T e -70 +KPX T eacute -70 +KPX T ecaron -70 +KPX T ecircumflex -70 +KPX T edieresis -30 +KPX T edotaccent -70 +KPX T egrave -70 +KPX T emacron -30 +KPX T eogonek -70 +KPX T hyphen -92 +KPX T i -35 +KPX T iacute -35 +KPX T iogonek -35 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -74 +KPX T r -35 +KPX T racute -35 +KPX T rcaron -35 +KPX T rcommaaccent -35 +KPX T semicolon -55 +KPX T u -45 +KPX T uacute -45 +KPX T ucircumflex -45 +KPX T udieresis -45 +KPX T ugrave -45 +KPX T uhungarumlaut -45 +KPX T umacron -45 +KPX T uogonek -45 +KPX T uring -45 +KPX T w -80 +KPX T y -80 +KPX T yacute -80 +KPX T ydieresis -80 +KPX Tcaron A -93 +KPX Tcaron Aacute -93 +KPX Tcaron Abreve -93 +KPX Tcaron Acircumflex -93 +KPX Tcaron Adieresis -93 +KPX Tcaron Agrave -93 +KPX Tcaron Amacron -93 +KPX Tcaron Aogonek -93 +KPX Tcaron Aring -93 +KPX Tcaron Atilde -93 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -40 +KPX Tcaron agrave -40 +KPX Tcaron amacron -40 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -40 +KPX Tcaron colon -50 +KPX Tcaron comma -74 +KPX Tcaron e -70 +KPX Tcaron eacute -70 +KPX Tcaron ecaron -70 +KPX Tcaron ecircumflex -30 +KPX Tcaron edieresis -30 +KPX Tcaron edotaccent -70 +KPX Tcaron egrave -70 +KPX Tcaron emacron -30 +KPX Tcaron eogonek -70 +KPX Tcaron hyphen -92 +KPX Tcaron i -35 +KPX Tcaron iacute -35 +KPX Tcaron iogonek -35 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -74 +KPX Tcaron r -35 +KPX Tcaron racute -35 +KPX Tcaron rcaron -35 +KPX Tcaron rcommaaccent -35 +KPX Tcaron semicolon -55 +KPX Tcaron u -45 +KPX Tcaron uacute -45 +KPX Tcaron ucircumflex -45 +KPX Tcaron udieresis -45 +KPX Tcaron ugrave -45 +KPX Tcaron uhungarumlaut -45 +KPX Tcaron umacron -45 +KPX Tcaron uogonek -45 +KPX Tcaron uring -45 +KPX Tcaron w -80 +KPX Tcaron y -80 +KPX Tcaron yacute -80 +KPX Tcaron ydieresis -80 +KPX Tcommaaccent A -93 +KPX Tcommaaccent Aacute -93 +KPX Tcommaaccent Abreve -93 +KPX Tcommaaccent Acircumflex -93 +KPX Tcommaaccent Adieresis -93 +KPX Tcommaaccent Agrave -93 +KPX Tcommaaccent Amacron -93 +KPX Tcommaaccent Aogonek -93 +KPX Tcommaaccent Aring -93 +KPX Tcommaaccent Atilde -93 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -40 +KPX Tcommaaccent agrave -40 +KPX Tcommaaccent amacron -40 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -40 +KPX Tcommaaccent colon -50 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -70 +KPX Tcommaaccent eacute -70 +KPX Tcommaaccent ecaron -70 +KPX Tcommaaccent ecircumflex -30 +KPX Tcommaaccent edieresis -30 +KPX Tcommaaccent edotaccent -70 +KPX Tcommaaccent egrave -30 +KPX Tcommaaccent emacron -70 +KPX Tcommaaccent eogonek -70 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -35 +KPX Tcommaaccent iacute -35 +KPX Tcommaaccent iogonek -35 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -74 +KPX Tcommaaccent r -35 +KPX Tcommaaccent racute -35 +KPX Tcommaaccent rcaron -35 +KPX Tcommaaccent rcommaaccent -35 +KPX Tcommaaccent semicolon -55 +KPX Tcommaaccent u -45 +KPX Tcommaaccent uacute -45 +KPX Tcommaaccent ucircumflex -45 +KPX Tcommaaccent udieresis -45 +KPX Tcommaaccent ugrave -45 +KPX Tcommaaccent uhungarumlaut -45 +KPX Tcommaaccent umacron -45 +KPX Tcommaaccent uogonek -45 +KPX Tcommaaccent uring -45 +KPX Tcommaaccent w -80 +KPX Tcommaaccent y -80 +KPX Tcommaaccent yacute -80 +KPX Tcommaaccent ydieresis -80 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX V A -135 +KPX V Aacute -135 +KPX V Abreve -135 +KPX V Acircumflex -135 +KPX V Adieresis -135 +KPX V Agrave -135 +KPX V Amacron -135 +KPX V Aogonek -135 +KPX V Aring -135 +KPX V Atilde -135 +KPX V G -15 +KPX V Gbreve -15 +KPX V Gcommaaccent -15 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -71 +KPX V adieresis -71 +KPX V agrave -71 +KPX V amacron -71 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -71 +KPX V colon -74 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -71 +KPX V ecircumflex -71 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -100 +KPX V i -60 +KPX V iacute -60 +KPX V icircumflex -20 +KPX V idieresis -20 +KPX V igrave -20 +KPX V imacron -20 +KPX V iogonek -60 +KPX V o -129 +KPX V oacute -129 +KPX V ocircumflex -129 +KPX V odieresis -89 +KPX V ograve -89 +KPX V ohungarumlaut -129 +KPX V omacron -89 +KPX V oslash -129 +KPX V otilde -89 +KPX V period -129 +KPX V semicolon -74 +KPX V u -75 +KPX V uacute -75 +KPX V ucircumflex -75 +KPX V udieresis -75 +KPX V ugrave -75 +KPX V uhungarumlaut -75 +KPX V umacron -75 +KPX V uogonek -75 +KPX V uring -75 +KPX W A -120 +KPX W Aacute -120 +KPX W Abreve -120 +KPX W Acircumflex -120 +KPX W Adieresis -120 +KPX W Agrave -120 +KPX W Amacron -120 +KPX W Aogonek -120 +KPX W Aring -120 +KPX W Atilde -120 +KPX W O -10 +KPX W Oacute -10 +KPX W Ocircumflex -10 +KPX W Odieresis -10 +KPX W Ograve -10 +KPX W Ohungarumlaut -10 +KPX W Omacron -10 +KPX W Oslash -10 +KPX W Otilde -10 +KPX W a -80 +KPX W aacute -80 +KPX W abreve -80 +KPX W acircumflex -80 +KPX W adieresis -80 +KPX W agrave -80 +KPX W amacron -80 +KPX W aogonek -80 +KPX W aring -80 +KPX W atilde -80 +KPX W colon -37 +KPX W comma -92 +KPX W e -80 +KPX W eacute -80 +KPX W ecaron -80 +KPX W ecircumflex -80 +KPX W edieresis -40 +KPX W edotaccent -80 +KPX W egrave -40 +KPX W emacron -40 +KPX W eogonek -80 +KPX W hyphen -65 +KPX W i -40 +KPX W iacute -40 +KPX W iogonek -40 +KPX W o -80 +KPX W oacute -80 +KPX W ocircumflex -80 +KPX W odieresis -80 +KPX W ograve -80 +KPX W ohungarumlaut -80 +KPX W omacron -80 +KPX W oslash -80 +KPX W otilde -80 +KPX W period -92 +KPX W semicolon -37 +KPX W u -50 +KPX W uacute -50 +KPX W ucircumflex -50 +KPX W udieresis -50 +KPX W ugrave -50 +KPX W uhungarumlaut -50 +KPX W umacron -50 +KPX W uogonek -50 +KPX W uring -50 +KPX W y -73 +KPX W yacute -73 +KPX W ydieresis -73 +KPX Y A -120 +KPX Y Aacute -120 +KPX Y Abreve -120 +KPX Y Acircumflex -120 +KPX Y Adieresis -120 +KPX Y Agrave -120 +KPX Y Amacron -120 +KPX Y Aogonek -120 +KPX Y Aring -120 +KPX Y Atilde -120 +KPX Y O -30 +KPX Y Oacute -30 +KPX Y Ocircumflex -30 +KPX Y Odieresis -30 +KPX Y Ograve -30 +KPX Y Ohungarumlaut -30 +KPX Y Omacron -30 +KPX Y Oslash -30 +KPX Y Otilde -30 +KPX Y a -100 +KPX Y aacute -100 +KPX Y abreve -100 +KPX Y acircumflex -100 +KPX Y adieresis -60 +KPX Y agrave -60 +KPX Y amacron -60 +KPX Y aogonek -100 +KPX Y aring -100 +KPX Y atilde -60 +KPX Y colon -92 +KPX Y comma -129 +KPX Y e -100 +KPX Y eacute -100 +KPX Y ecaron -100 +KPX Y ecircumflex -100 +KPX Y edieresis -60 +KPX Y edotaccent -100 +KPX Y egrave -60 +KPX Y emacron -60 +KPX Y eogonek -100 +KPX Y hyphen -111 +KPX Y i -55 +KPX Y iacute -55 +KPX Y iogonek -55 +KPX Y o -110 +KPX Y oacute -110 +KPX Y ocircumflex -110 +KPX Y odieresis -70 +KPX Y ograve -70 +KPX Y ohungarumlaut -110 +KPX Y omacron -70 +KPX Y oslash -110 +KPX Y otilde -70 +KPX Y period -129 +KPX Y semicolon -92 +KPX Y u -111 +KPX Y uacute -111 +KPX Y ucircumflex -111 +KPX Y udieresis -71 +KPX Y ugrave -71 +KPX Y uhungarumlaut -111 +KPX Y umacron -71 +KPX Y uogonek -111 +KPX Y uring -111 +KPX Yacute A -120 +KPX Yacute Aacute -120 +KPX Yacute Abreve -120 +KPX Yacute Acircumflex -120 +KPX Yacute Adieresis -120 +KPX Yacute Agrave -120 +KPX Yacute Amacron -120 +KPX Yacute Aogonek -120 +KPX Yacute Aring -120 +KPX Yacute Atilde -120 +KPX Yacute O -30 +KPX Yacute Oacute -30 +KPX Yacute Ocircumflex -30 +KPX Yacute Odieresis -30 +KPX Yacute Ograve -30 +KPX Yacute Ohungarumlaut -30 +KPX Yacute Omacron -30 +KPX Yacute Oslash -30 +KPX Yacute Otilde -30 +KPX Yacute a -100 +KPX Yacute aacute -100 +KPX Yacute abreve -100 +KPX Yacute acircumflex -100 +KPX Yacute adieresis -60 +KPX Yacute agrave -60 +KPX Yacute amacron -60 +KPX Yacute aogonek -100 +KPX Yacute aring -100 +KPX Yacute atilde -60 +KPX Yacute colon -92 +KPX Yacute comma -129 +KPX Yacute e -100 +KPX Yacute eacute -100 +KPX Yacute ecaron -100 +KPX Yacute ecircumflex -100 +KPX Yacute edieresis -60 +KPX Yacute edotaccent -100 +KPX Yacute egrave -60 +KPX Yacute emacron -60 +KPX Yacute eogonek -100 +KPX Yacute hyphen -111 +KPX Yacute i -55 +KPX Yacute iacute -55 +KPX Yacute iogonek -55 +KPX Yacute o -110 +KPX Yacute oacute -110 +KPX Yacute ocircumflex -110 +KPX Yacute odieresis -70 +KPX Yacute ograve -70 +KPX Yacute ohungarumlaut -110 +KPX Yacute omacron -70 +KPX Yacute oslash -110 +KPX Yacute otilde -70 +KPX Yacute period -129 +KPX Yacute semicolon -92 +KPX Yacute u -111 +KPX Yacute uacute -111 +KPX Yacute ucircumflex -111 +KPX Yacute udieresis -71 +KPX Yacute ugrave -71 +KPX Yacute uhungarumlaut -111 +KPX Yacute umacron -71 +KPX Yacute uogonek -111 +KPX Yacute uring -111 +KPX Ydieresis A -120 +KPX Ydieresis Aacute -120 +KPX Ydieresis Abreve -120 +KPX Ydieresis Acircumflex -120 +KPX Ydieresis Adieresis -120 +KPX Ydieresis Agrave -120 +KPX Ydieresis Amacron -120 +KPX Ydieresis Aogonek -120 +KPX Ydieresis Aring -120 +KPX Ydieresis Atilde -120 +KPX Ydieresis O -30 +KPX Ydieresis Oacute -30 +KPX Ydieresis Ocircumflex -30 +KPX Ydieresis Odieresis -30 +KPX Ydieresis Ograve -30 +KPX Ydieresis Ohungarumlaut -30 +KPX Ydieresis Omacron -30 +KPX Ydieresis Oslash -30 +KPX Ydieresis Otilde -30 +KPX Ydieresis a -100 +KPX Ydieresis aacute -100 +KPX Ydieresis abreve -100 +KPX Ydieresis acircumflex -100 +KPX Ydieresis adieresis -60 +KPX Ydieresis agrave -60 +KPX Ydieresis amacron -60 +KPX Ydieresis aogonek -100 +KPX Ydieresis aring -100 +KPX Ydieresis atilde -100 +KPX Ydieresis colon -92 +KPX Ydieresis comma -129 +KPX Ydieresis e -100 +KPX Ydieresis eacute -100 +KPX Ydieresis ecaron -100 +KPX Ydieresis ecircumflex -100 +KPX Ydieresis edieresis -60 +KPX Ydieresis edotaccent -100 +KPX Ydieresis egrave -60 +KPX Ydieresis emacron -60 +KPX Ydieresis eogonek -100 +KPX Ydieresis hyphen -111 +KPX Ydieresis i -55 +KPX Ydieresis iacute -55 +KPX Ydieresis iogonek -55 +KPX Ydieresis o -110 +KPX Ydieresis oacute -110 +KPX Ydieresis ocircumflex -110 +KPX Ydieresis odieresis -70 +KPX Ydieresis ograve -70 +KPX Ydieresis ohungarumlaut -110 +KPX Ydieresis omacron -70 +KPX Ydieresis oslash -110 +KPX Ydieresis otilde -70 +KPX Ydieresis period -129 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -111 +KPX Ydieresis uacute -111 +KPX Ydieresis ucircumflex -111 +KPX Ydieresis udieresis -71 +KPX Ydieresis ugrave -71 +KPX Ydieresis uhungarumlaut -111 +KPX Ydieresis umacron -71 +KPX Ydieresis uogonek -111 +KPX Ydieresis uring -111 +KPX a v -20 +KPX a w -15 +KPX aacute v -20 +KPX aacute w -15 +KPX abreve v -20 +KPX abreve w -15 +KPX acircumflex v -20 +KPX acircumflex w -15 +KPX adieresis v -20 +KPX adieresis w -15 +KPX agrave v -20 +KPX agrave w -15 +KPX amacron v -20 +KPX amacron w -15 +KPX aogonek v -20 +KPX aogonek w -15 +KPX aring v -20 +KPX aring w -15 +KPX atilde v -20 +KPX atilde w -15 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -15 +KPX c y -15 +KPX c yacute -15 +KPX c ydieresis -15 +KPX cacute y -15 +KPX cacute yacute -15 +KPX cacute ydieresis -15 +KPX ccaron y -15 +KPX ccaron yacute -15 +KPX ccaron ydieresis -15 +KPX ccedilla y -15 +KPX ccedilla yacute -15 +KPX ccedilla ydieresis -15 +KPX comma quotedblright -70 +KPX comma quoteright -70 +KPX e g -15 +KPX e gbreve -15 +KPX e gcommaaccent -15 +KPX e v -25 +KPX e w -25 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute g -15 +KPX eacute gbreve -15 +KPX eacute gcommaaccent -15 +KPX eacute v -25 +KPX eacute w -25 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron g -15 +KPX ecaron gbreve -15 +KPX ecaron gcommaaccent -15 +KPX ecaron v -25 +KPX ecaron w -25 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex g -15 +KPX ecircumflex gbreve -15 +KPX ecircumflex gcommaaccent -15 +KPX ecircumflex v -25 +KPX ecircumflex w -25 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis g -15 +KPX edieresis gbreve -15 +KPX edieresis gcommaaccent -15 +KPX edieresis v -25 +KPX edieresis w -25 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent g -15 +KPX edotaccent gbreve -15 +KPX edotaccent gcommaaccent -15 +KPX edotaccent v -25 +KPX edotaccent w -25 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave g -15 +KPX egrave gbreve -15 +KPX egrave gcommaaccent -15 +KPX egrave v -25 +KPX egrave w -25 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron g -15 +KPX emacron gbreve -15 +KPX emacron gcommaaccent -15 +KPX emacron v -25 +KPX emacron w -25 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek g -15 +KPX eogonek gbreve -15 +KPX eogonek gcommaaccent -15 +KPX eogonek v -25 +KPX eogonek w -25 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f a -10 +KPX f aacute -10 +KPX f abreve -10 +KPX f acircumflex -10 +KPX f adieresis -10 +KPX f agrave -10 +KPX f amacron -10 +KPX f aogonek -10 +KPX f aring -10 +KPX f atilde -10 +KPX f dotlessi -50 +KPX f f -25 +KPX f i -20 +KPX f iacute -20 +KPX f quoteright 55 +KPX g a -5 +KPX g aacute -5 +KPX g abreve -5 +KPX g acircumflex -5 +KPX g adieresis -5 +KPX g agrave -5 +KPX g amacron -5 +KPX g aogonek -5 +KPX g aring -5 +KPX g atilde -5 +KPX gbreve a -5 +KPX gbreve aacute -5 +KPX gbreve abreve -5 +KPX gbreve acircumflex -5 +KPX gbreve adieresis -5 +KPX gbreve agrave -5 +KPX gbreve amacron -5 +KPX gbreve aogonek -5 +KPX gbreve aring -5 +KPX gbreve atilde -5 +KPX gcommaaccent a -5 +KPX gcommaaccent aacute -5 +KPX gcommaaccent abreve -5 +KPX gcommaaccent acircumflex -5 +KPX gcommaaccent adieresis -5 +KPX gcommaaccent agrave -5 +KPX gcommaaccent amacron -5 +KPX gcommaaccent aogonek -5 +KPX gcommaaccent aring -5 +KPX gcommaaccent atilde -5 +KPX h y -5 +KPX h yacute -5 +KPX h ydieresis -5 +KPX i v -25 +KPX iacute v -25 +KPX icircumflex v -25 +KPX idieresis v -25 +KPX igrave v -25 +KPX imacron v -25 +KPX iogonek v -25 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX k y -15 +KPX k yacute -15 +KPX k ydieresis -15 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX kcommaaccent y -15 +KPX kcommaaccent yacute -15 +KPX kcommaaccent ydieresis -15 +KPX l w -10 +KPX lacute w -10 +KPX lcommaaccent w -10 +KPX lslash w -10 +KPX n v -40 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute v -40 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron v -40 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent v -40 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde v -40 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o v -15 +KPX o w -25 +KPX o y -10 +KPX o yacute -10 +KPX o ydieresis -10 +KPX oacute v -15 +KPX oacute w -25 +KPX oacute y -10 +KPX oacute yacute -10 +KPX oacute ydieresis -10 +KPX ocircumflex v -15 +KPX ocircumflex w -25 +KPX ocircumflex y -10 +KPX ocircumflex yacute -10 +KPX ocircumflex ydieresis -10 +KPX odieresis v -15 +KPX odieresis w -25 +KPX odieresis y -10 +KPX odieresis yacute -10 +KPX odieresis ydieresis -10 +KPX ograve v -15 +KPX ograve w -25 +KPX ograve y -10 +KPX ograve yacute -10 +KPX ograve ydieresis -10 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -25 +KPX ohungarumlaut y -10 +KPX ohungarumlaut yacute -10 +KPX ohungarumlaut ydieresis -10 +KPX omacron v -15 +KPX omacron w -25 +KPX omacron y -10 +KPX omacron yacute -10 +KPX omacron ydieresis -10 +KPX oslash v -15 +KPX oslash w -25 +KPX oslash y -10 +KPX oslash yacute -10 +KPX oslash ydieresis -10 +KPX otilde v -15 +KPX otilde w -25 +KPX otilde y -10 +KPX otilde yacute -10 +KPX otilde ydieresis -10 +KPX p y -10 +KPX p yacute -10 +KPX p ydieresis -10 +KPX period quotedblright -70 +KPX period quoteright -70 +KPX quotedblleft A -80 +KPX quotedblleft Aacute -80 +KPX quotedblleft Abreve -80 +KPX quotedblleft Acircumflex -80 +KPX quotedblleft Adieresis -80 +KPX quotedblleft Agrave -80 +KPX quotedblleft Amacron -80 +KPX quotedblleft Aogonek -80 +KPX quotedblleft Aring -80 +KPX quotedblleft Atilde -80 +KPX quoteleft A -80 +KPX quoteleft Aacute -80 +KPX quoteleft Abreve -80 +KPX quoteleft Acircumflex -80 +KPX quoteleft Adieresis -80 +KPX quoteleft Agrave -80 +KPX quoteleft Amacron -80 +KPX quoteleft Aogonek -80 +KPX quoteleft Aring -80 +KPX quoteleft Atilde -80 +KPX quoteleft quoteleft -74 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright l -10 +KPX quoteright lacute -10 +KPX quoteright lcommaaccent -10 +KPX quoteright lslash -10 +KPX quoteright quoteright -74 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -55 +KPX quoteright sacute -55 +KPX quoteright scaron -55 +KPX quoteright scedilla -55 +KPX quoteright scommaaccent -55 +KPX quoteright space -74 +KPX quoteright t -18 +KPX quoteright tcommaaccent -18 +KPX quoteright v -50 +KPX r comma -40 +KPX r g -18 +KPX r gbreve -18 +KPX r gcommaaccent -18 +KPX r hyphen -20 +KPX r period -55 +KPX racute comma -40 +KPX racute g -18 +KPX racute gbreve -18 +KPX racute gcommaaccent -18 +KPX racute hyphen -20 +KPX racute period -55 +KPX rcaron comma -40 +KPX rcaron g -18 +KPX rcaron gbreve -18 +KPX rcaron gcommaaccent -18 +KPX rcaron hyphen -20 +KPX rcaron period -55 +KPX rcommaaccent comma -40 +KPX rcommaaccent g -18 +KPX rcommaaccent gbreve -18 +KPX rcommaaccent gcommaaccent -18 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent period -55 +KPX space A -55 +KPX space Aacute -55 +KPX space Abreve -55 +KPX space Acircumflex -55 +KPX space Adieresis -55 +KPX space Agrave -55 +KPX space Amacron -55 +KPX space Aogonek -55 +KPX space Aring -55 +KPX space Atilde -55 +KPX space T -18 +KPX space Tcaron -18 +KPX space Tcommaaccent -18 +KPX space V -50 +KPX space W -30 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -65 +KPX v e -15 +KPX v eacute -15 +KPX v ecaron -15 +KPX v ecircumflex -15 +KPX v edieresis -15 +KPX v edotaccent -15 +KPX v egrave -15 +KPX v emacron -15 +KPX v eogonek -15 +KPX v o -20 +KPX v oacute -20 +KPX v ocircumflex -20 +KPX v odieresis -20 +KPX v ograve -20 +KPX v ohungarumlaut -20 +KPX v omacron -20 +KPX v oslash -20 +KPX v otilde -20 +KPX v period -65 +KPX w a -10 +KPX w aacute -10 +KPX w abreve -10 +KPX w acircumflex -10 +KPX w adieresis -10 +KPX w agrave -10 +KPX w amacron -10 +KPX w aogonek -10 +KPX w aring -10 +KPX w atilde -10 +KPX w comma -65 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -65 +KPX x e -15 +KPX x eacute -15 +KPX x ecaron -15 +KPX x ecircumflex -15 +KPX x edieresis -15 +KPX x edotaccent -15 +KPX x egrave -15 +KPX x emacron -15 +KPX x eogonek -15 +KPX y comma -65 +KPX y period -65 +KPX yacute comma -65 +KPX yacute period -65 +KPX ydieresis comma -65 +KPX ydieresis period -65 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm new file mode 100644 index 00000000..b2745053 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm @@ -0,0 +1,225 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 15:14:13 1997 +Comment UniqueID 43082 +Comment VMusage 45775 55535 +FontName ZapfDingbats +FullName ITC Zapf Dingbats +FamilyName ZapfDingbats +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet Special +FontBBox -1 -143 981 820 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation. +EncodingScheme FontSpecific +StdHW 28 +StdVW 90 +StartCharMetrics 202 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ; +C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ; +C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ; +C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ; +C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ; +C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ; +C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ; +C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ; +C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ; +C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ; +C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ; +C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ; +C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ; +C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ; +C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ; +C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ; +C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ; +C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ; +C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ; +C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ; +C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ; +C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ; +C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ; +C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ; +C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ; +C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ; +C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ; +C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ; +C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ; +C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ; +C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ; +C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ; +C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ; +C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ; +C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ; +C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ; +C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ; +C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ; +C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ; +C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ; +C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ; +C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ; +C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ; +C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ; +C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ; +C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ; +C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ; +C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ; +C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ; +C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ; +C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ; +C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ; +C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ; +C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ; +C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ; +C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ; +C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ; +C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ; +C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ; +C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ; +C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ; +C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ; +C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ; +C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ; +C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ; +C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ; +C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ; +C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ; +C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ; +C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ; +C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ; +C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ; +C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ; +C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ; +C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ; +C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ; +C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ; +C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ; +C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ; +C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ; +C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ; +C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ; +C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ; +C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ; +C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ; +C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ; +C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ; +C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ; +C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ; +C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ; +C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ; +C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ; +C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ; +C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ; +C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ; +C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ; +C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ; +C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ; +C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ; +C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ; +C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ; +C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ; +C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ; +C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ; +C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ; +C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ; +C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ; +C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ; +C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ; +C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ; +C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ; +C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ; +C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ; +C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ; +C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ; +C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ; +C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ; +C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ; +C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ; +C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ; +C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ; +C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ; +C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ; +C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ; +C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ; +C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ; +C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ; +C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ; +C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ; +C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ; +C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ; +C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ; +C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ; +C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ; +C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ; +C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ; +C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ; +C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ; +C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ; +C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ; +C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ; +C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ; +C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ; +C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ; +C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ; +C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ; +C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ; +C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ; +C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ; +C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ; +C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ; +C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ; +C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ; +C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ; +C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ; +C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ; +C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ; +C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ; +C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ; +C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ; +C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ; +C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ; +C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ; +C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ; +C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ; +C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ; +C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ; +C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ; +C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ; +C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ; +C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ; +C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ; +C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ; +C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ; +C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ; +C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ; +C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ; +C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ; +C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ; +C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ; +C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ; +C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ; +C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ; +C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ; +C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ; +C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ; +C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ; +C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ; +C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ; +C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ; +C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ; +C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ; +C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ; +C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ; +C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ; +C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ; +C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ; +C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ; +C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ; +C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ; +C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ; +EndCharMetrics +EndFontMetrics diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt new file mode 100644 index 00000000..047ae70a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt @@ -0,0 +1,15 @@ +Font Metrics for the 14 PDF Core Fonts +====================================== + +This directory contains font metrics for the 14 PDF Core Fonts, +downloaded from Adobe. The title and this paragraph were added by +Matplotlib developers. The download URL was +. + +This file and the 14 PostScript(R) AFM files it accompanies may be used, copied, +and distributed for any purpose and without charge, with or without modification, +provided that all copyright notices are retained; that the AFM files are not +distributed without this file; that all modifications to this file or any of +the AFM files are prominently noted in the modified file(s); and that this +paragraph is not modified. Adobe Systems has no responsibility or obligation +to support the use of the AFM files. diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1f22f07c99bd4d4b8fba9e00094df4e58e69def1 GIT binary patch literal 704128 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�CW!CpozuanGZeC%5`IbVr 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≪r~lU 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∈%7QJq;i8K#b+|5wF+Cp5F83MfB|jqIc? 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 X@&bL~RRwF@!VF2r2B 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∓6-eC*V* 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..300ea68b6c7e86999b09b109330037705e09aaaf GIT binary patch literal 633840 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%0DnXHkV4^S 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5267218852f631928716a8005d7bf4b492aaf83d GIT binary patch literal 756072 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf new file mode 100644 index 0000000000000000000000000000000000000000..36758a2e70b6eb05ef8f8694828ed0eb157be3d3 GIT binary patch literal 25712 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 Ap#T5? literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cbcdd31d6002ad441ca5cc3b5d6aa8d32b97eb7d GIT binary patch literal 331536 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%0Ao}tN9>a(?{=eZus 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 Zd9?L`zvW#&f4P15|N5`(f7rTB{{fZB(eD5N literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..da513440a2b2ac4746af4bbb62ba57c01fcce210 GIT binary patch literal 253116 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0185ce95a51d7cd86ada7c90709f34f10d6336f8 GIT binary patch literal 251472 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 T|3Cb%;s4Or|5sNVH8lJW2n!o+ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..278cd7813974104fdcc1a873afbbd01a49d1e567 GIT binary patch literal 340240 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 NzcpXwQ+e{5{{zns&|3fi literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d683eb282bc0e2ae21f0d45f47b639e400f295ac GIT binary patch literal 355692 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%0DDH$29EQ*D$8B&(#3< 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 XA`=chc9Avz|NO7t|2x$l*6;rS#0H8Y literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b4831f76548d5e8be363827f5b6dcf8e869a6f8c GIT binary patch literal 347064 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 RHvj+Uzrz1_vOTEqzW|lXvfTgx literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..45b508b829b3ccf15b22d646e40e681d2f67ddda GIT binary patch literal 345612 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 HOQrt@zTvnc literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39dd3946d3d06442d8d25556e7c1c37663893688 GIT binary patch literal 379740 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%0DJS2FJp9Jb%x)yot(+{vdxzT7fF3-4srL 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%0AvJ)d;>$ifg#_(kZ%Al0(cR?ivV5( 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1623714d223f2b4ae5460269cf3afa34e91dd811 GIT binary patch literal 14300 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU new file mode 100644 index 00000000..254e2cc4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU @@ -0,0 +1,99 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX new file mode 100644 index 00000000..6034d947 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX @@ -0,0 +1,124 @@ +The STIX fonts distributed with matplotlib have been modified from +their canonical form. They have been converted from OTF to TTF format +using Fontforge and this script: + + #!/usr/bin/env fontforge + i=1 + while ( i<$argc ) + Open($argv[i]) + Generate($argv[i]:r + ".ttf") + i = i+1 + endloop + +The original STIX Font License begins below. + +----------------------------------------------------------- + +STIX Font License + +24 May 2010 + +Copyright (c) 2001-2010 by the STI Pub Companies, consisting of the American +Institute of Physics, the American Chemical Society, the American Mathematical +Society, the American Physical Society, Elsevier, Inc., and The Institute of +Electrical and Electronic Engineers, Inc. (www.stixfonts.org), with Reserved +Font Name STIX Fonts, STIX Fonts (TM) is a trademark of The Institute of +Electrical and Electronics Engineers, Inc. + +Portions copyright (c) 1998-2003 by MicroPress, Inc. (www.micropress-inc.com), +with Reserved Font Name TM Math. To obtain additional mathematical fonts, please +contact MicroPress, Inc., 68-30 Harrow Street, Forest Hills, NY 11375, USA, +Phone: (718) 575-1816. + +Portions copyright (c) 1990 by Elsevier, Inc. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf new file mode 100644 index 0000000000000000000000000000000000000000..86994000378a785f89b1b9b89124b803dd0889b0 GIT binary patch literal 448228 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 H^9}zFmf_QC literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ba80b537eb71fa0d86a8158c45ca18a1a152c59b GIT binary patch literal 237360 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5957dabb140f5fb539f6ed08bbc971560b60cf14 GIT binary patch literal 181152 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 QSeAm1(^=MoJ$E$!A8M{V@Bjb+ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2830b6b9a2f33f48744eeef235eecca0b850799e GIT binary patch literal 175040 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a70c797d092dee1819ec9dcdffa2e6c62b92e12b GIT binary patch literal 59108 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccbd9a6011694d06644eb3e4a97f377145eebf19 GIT binary patch literal 30512 zcmdVD30z#|)jxipI}F1P!!R=p%*rq`?8^)@!%iT9KmrMbEE5uwunbEA3;~iDccaFo zYOI>LCu(i$Quj7>sk_y<YqU1DiHX6gHC9urwN<(NzUSUMKw|9szW@LG|9pP`;N`B* z+0S{-InTYwF^=Qnx$`&$*V@pqv}M`#|NN5Uwxr;yasIse2JSU3lH)dig>&oT_CojS z`29OLjs<YOu6w9+q|9nHa9l(w$0@q{I>$z)rT~fC{2A^?^$l+Aowsjq91f3gT+Q+R zU}w))nSU9>y@S|%{kRY_kCgx(;mhnF8b5t#rL`RAk8m7+&S0p!^ZwyI`#DZ^Gp^MQ zb)G)LeZsZj82C8raOY6a_2F-v9M||J$GHxSgvQ2S_($Xm95-?&$3@n0#2dEqgkz~| z6Dz;wVilj@3b)Vq)@9-S)EkorBK9e6$8%8}Pgn5|W0ZGK9spnWO}!x`MC=nGN%y4R zd&DcZa*Ieh_(vm|cx?`y;vdgn#Q%;{;__FFr1!0~$8idKQG8<Nmm+EAm}_6!6yU6! zb>eyc^QlNCDDUR8&a;ZJ!%xxKx6%n~!Jdw>Mck^$invda#edGVp0v%w`CM@Cq>YZT z(X|!wM#tg?NNXj?(r?x>b)4g9<5tlg&n-D=n~iG~?#(`LRWL3cV|(PSo6qACSQ?ju zEf?1k*;QN_E9ZRdF3!hibIrU1bSgn#7M?kS^Ro}Q8dd>uzRbNX?hj8L;15q7!zS%x zximhO3t{tOvtY}?R*X%HEeac5gN<^lS^d-$zZKhlE}FlIOX3Hy?dNRb@lBjj5yNS* z+1W)?2eCKv&vDU;2e<@0lf+-lWzju)hVRDt9?pny7XEE6K{1a@re_qHurT-ye+y^j zZ<_iC|Mk=x{QF!w!B=QFH~${DkiU#u$o_==7hFC&3$j|zxfQ86-^Dd3uI3ivxqSXf zY<Zl4Kgu=mW1L#?A+|Iwg}<EB^C7^wfUD%IIXB=KaO~zsaK4?ZWc6I7;&L3*`EtOZ z=Ww63WAETf*pqmE17!L+7pX|*bo{lPf&Fpn8=i4le7v}IU|)hQ7n^C;F`Y{r>;ymb z53GutQL;^bHO}BUoRN#*=U{(1qDmwe2V1`N2s@%aVn5<Il6}N~q~*wxBdd?BIns5c z@5soJi;moOWbctb9Xa|z><5V-v>)w0+IMur(a_Pcqg#%idGy?)7aYC#=oLq=Iy!lD zYJyEDCX^GZiRg*giTH`c3H5|#LOY?KFifORm?kU}wh8-$W5P9&J&`*RoEVrGn%FpT z*2GUH_DtL{@$|&=h)tYG4R<6#q$W$GruE1wP_ynx&yk@c=YX0AjvP302-GBe(E20P z?D&5{&1Dl;Ox!;4%ZcZvrluyQdaO#zzb&6wKDPYDa=`MO<r&MPmPahVwd}P#Xt~33 zspU*dhb3SsvJ{v<Hyt(|G`(kf*YvjOP19?pmrXC4o;N*ZdeXGS)MjcmEjBGOwV0Ys z3r!15O{PZEd{cv|-ZalN*HmY!HO(>An5s=xrb<(Vi8oFezc>Ed_=WMP@dM*w<00dp zB@IG4|Cjt@h^k~t^p8<&4M%423SE>;FMRrc_deo(gS-S-?rQEz?rF><i`aeaBi_u{ z@#FmU{O@={QKVR}I7e}{;#Z1S75|FJjA)HGE8<yYq;j5eoAM#$`;ofHMUm%4J`j0C z6{l)c1yud2(^c=Njz`5s8KYXG#-n}_^?9@}`ugaDF$FOf##|lqi<rk^_Q!l0%g3h0 zE{YwDy*~EM*iYk(aZBUY$2}1DQ9K`?6mO1S6aPT`rwK_3T?scPe3sapcvj;6q`0Id zNmnHuQ5)53)OV{tN;W62N&cNCQ*(*tofLP<wv;!uY1%>UmD+c;U+I!{i*#MOOLPzE z_UZnq&(mM4zfXTq|7~hc>Y~)q)Mrx#L%E^X@QC4PT2z`jZC%>sX^*A-E8UmAI{k(8 z<3^*g+_>I&nelhV1IBMn1*XlWm(6kJR`ZqSr_F+;+Oo^?FR~Ox*3`#}tN1R8RZ6?s zqqwTS-@u<qI>9||VZ=WEX>p#msqJc8#6DqPKf9F=O#Xx4M9=VCt8g#BTjAj>Tm~T6 zRCd4J>k&7l*Wq_~m41&xuT?2*TARwIaH;s+!l=E;zU6BBZ{C<Ie9nq2!h@`LVN?4r zKUu_l!UJ|TcB3Qq{Y{$!<AFn`2QKQpCb0Wo!e<MzdWEULI6pthA>*CW^1JzuI6arf zaSkQ$s=PIfHW8;vuT`oXg^ci>>21o{bZyDLkBWp(S;5?<<|D%EC9L<x(@djxKYV3L zp!QcQ0zG@q3|w?%vMX!*uWq?3d(A0uC><)h#^u%fUEs^3@@o^BQtMDDnMw~FKV8_g zbkE+b_gPVGlkerf7P3^~tt_@ecy7z8pWgNz(>DZKFYL_P{@$-w26}g&5xD5W>)4T! ztp6xK$21<j)}@l<C*qoxU!(9>c80$x@4P*84u4Z4OYa}gTq{ZMZ)arv;*qOM0}X%d z3=F;n+1<RXR^n?OWOol_7tNJH%_)%?PH&0Nt<!rFm_0*A1$Bj0Y4aEG_6(K1nt9x2 zg<j)P=sa%r`}{fi`0oK<<Y^02(@K~|c+SH{gx(d+E6%&ybBL*GlNJ?fS~Gmg&K8ZU zP+t~tY4de)%2xh7Ye9k4lAk}i;?k(Wz+m8!NAT;CXpioaHQS<7;~ffS6P`gxW87Tf zm;617rQBSc{0MCxzcWmlem0p*CetsE1I7F%BDJW@%u0j@%xqZLQrB3w>p}DDpJp$# zN_4sxrmGhfrAQ~{`MH^0jf07?IK@DN&g?U_vU^rsYF!st7kK9#{JN+ZH0LdgaqF=+ zrW=@FxKnw_ic3}N?BpBHsSd?6{H?H16MVw~n{+{_4lmQjGcqHMY(}`Fct+T*&ud%R z(kImMi-cy@q`#NtT->tpnQ!N@YT;)q{HZq<Y6A8LUwbZ#MFgJSQP`Yy0gFAnEHJ$N zvJah<!JUN9!MypfO|4QPxdyofnXg9`&s-|SGm{UoUkmr7J|;YSVaxEnA1x5xWJ?X! zdCOY5*(-vf-u0;<1fJYgv?S|t;rsU%270dD9@tfs5HR2Q{L3k3%B!KDsSf^b@TY+X z+BJ5C&1-YP`xPDytX1#f?|$T}MOO)Xn5XKWFXD(T5e`*-v_bfSso~sAEqoCe7vapC zdJFcL&Do~)thIY*^y&p%uSW}*+G#cB`5T%nlAf|lgySr!fh7sY7g$=EX~m_cOCK(T zLejPeIywRmxJB8l0Ik=7)<mLKic@MEgyGSGZUrJAf1R+WWI@SJ){Ea)J-CC-`R;FP z(tq+3zVPzP1H$?2T;Y6@@hRYV!LL_@rBK@yfO9?|Y`K1i@E&W#(S3m}I{+uZ&JA3C zxsWXaV%)r`$H8+omrt^bB)7Bsog}>!J(+Z*3Wq+AoAd?8)Y_dc6`1$=J^Vd)xw?yN z<%^c_%DWEpLkY3Ye8pj0b6R|hTB1~U9cGc^$vS6_;_!xLn&Dd&@d0Jzn-QLjz_Nt? zYhu-bn3O{?9t3O9fJ~ieu!4rLyZ;Do8-I^*OTprT-y99bMP?R65JHp1)7qF234~Dy z-5XY|3cSb{IReXKgI6Ra2Q<kyh&ZM`5OwPkb&EJ6GAjBkPwdH()7n+$2+>Cs&Q@>v z+PcQJ9BrG;r*JMQb-Bxh$Jk(2W7b0l8WkBDvmvI9nM%4ARNe4c>LvcJ`I4f4!Rz9Z zqDV(;c`v(*{}ywa3Rr<bi;dkS>}3mR;~#4LeIq@`2~V;GQ(L6xl;P*ZXXv>%8Xj$c z?O<jU7EV7GOV%Sn6roN(9UdW$K~gh$VAhz#6G#1U<jiPsJdaw^%T80&b2^&em<JY8 z$RyoR7`8An20gLm&dpe2wV8^NH0g?*gwg^_PF8wcN@}L?8@5nUe{Mp&E=^losY#C0 zeci|buF%I$6L|();zT7z$S`o2oCKRS69B_3h%qyW-fFx?0+}wtCmF2*z4s|>94bJn zCo!wo<!MDVb0`vgpVOG;aF)3CJB(>gSBdjAQ74CSEgk3S@}4vV9Zl0K%0c=6P!5-# zBnHsCWNHV0vtll1=d#HMl{V2Z3m9g?3O36s;d<iStMk|}IYz2HD!We4-z>aaQB+)C zSzdeFw!CcNYIaR_eRls9*?a#~#q`4O%Pbbm#vi24=}Y`+=1`(LK6&%ijx!f*xveMA zgZ~281}=?d=PjKRsL3JOg=w*IPA(6!Q<<4IB{G*y&%hocXqK}uPXTl3?JC#+uP$01 zyyL7hbLw-}Us?6a@hahM=88Aw2;13i&~%#c^&_$Mh36is>aOkMFCI5twd%}UK*P28 z;d_Z1;eq0Xi4)f@okfQkQpqBjAPkEV@p}=C<Pc0@Sp0E#6EMGc?PdmXd^czFjvbr7 z`)&?X3g6Az9<N-JaOa%~YvOx?(Yr@NyJLc330(WxHOjWCW7kxnWA#JaOe@Mj1q#6W z2|pgKN2`zopsi-?Izl|>1f(Ef&UfDdYvrAHR<7YM4#w;bjqHvNN^FZd5FV&%Qyv2a z6bD+T(vV9Ym2yd?12{2RVsn6HhgOLn{AOOtB_|t&Nv5E!QQC>8zZtlE^wrNs1EW`t zW^Fw7%ErLPo5T}#`sxA^zHWA|3iv9oU)(Su1BZyAkRhQJ{?#am{~B48@Glm1<M8R@ zpT9m57`YPLt;2!PYoCp0jbAx_d(k?AE8IUj_nsxI6KNOKbu#@Y^FVC<X5js?G0e^1 z5F4+KN^JZQsbkveeBfIp+|A#mC<*8Kv+zmMQp&uD_!KTJf7dK|okDIm4jkIL73ls5 zVcoPbF#77Tjaj4L09{l5YDq7%a(p@eu3^9>=iktZiqa~`?V6URWw#zKMkY{L*W`cY z(_)q`ykKO@g;A&J@>{1^dP7#%9VjObJ<<{AyW{M@Wovi7p^pEdZs2lMLr|g=t|MG3 zrAn+@M#>uV*Z-vHoxf!X$5=sA<B|`)&0-lh-d3{t{s*rp3{-x&CNOX|a{Gy??!fTb z=cY9LOoabK+mftHvMunSRXYB&ZEbvo1al>%^cj>Q9^AC?Dwx&}>6dMb>?&+qBqiwL z6t=Z_{Il0Wf#F+a`+EKJ@c?Wq1-6C0<ka8z_xXn@4mk8w7l_FT%{_V@r6H7&i1QJS zbb2$c`+fY==D8Pi-0-BTz9IIhtL87W8a1)$23`Kb)r<T1BS)0Qy0*MI)!Ek@+G~Du zrSF=@><OCmW7Xb{Jy-b7XvxUQ&;xG|uVJ_G$Hkh{P8P;)`?`@;@ptY#ggAlw!r$3# zQ?E-kDFr2VoABJ%jl$m>cZ&DBasSqt`&tjXRd}xPYvJ#Qr27d|UiLBgqMAaTqLODR zk6Wk3i8cih)vGRX=Hi}C5A@Z{t48drW`4|!ct)(1YFG)eZUWQn<MiAO)r&HWhKz)0 zt3jWn4QkTAwChSsmF67J+V-`M(o7X^)fMFQuVa4_vX<sIm*%BsSnyz?N}ZX-4y7as z4_gcosi_g^8LTmH@e+%(I5*vHNlntIVw2{c1_cn`Iow;^7kn;<X1E{9pjk=_8nh|8 z3igG1QE%_!r0CqT@|@_mR^PrlP~dVDN#k-c?zl8g0}g0f@e-57V{X#o-rhy(=$!Jh z+-N?R1{OJ7Fe~6o<Vv|K+5411`Jo3jqVARHJw54v+{1pc2l2XW>K|+c{{V+hGUboc z^F45=MCqi!O!)BB4?(SHuc&HYT2<ce^EvD#$crP~_RJ!;J%hJZwzpSRE?HXc^!c0p zej(IQT$E|2v>o>C1MCR?I@GGj+cmNl5}AfHQ9?Qi*2O!L(i27&=GW!rXIS#tPu?#u zBqgRkC%k0K%d5*Lc0ez|8I$3l8k>RSIt9#kWSCFM`)f{ytvV%+X5g5>YDpUB;0kf9 zid12al=2`@s)x{BUJqH8i^?0aHotF%6E@+lC^QvVYL=|1Gv=gevwo#9?$+eZt1;=5 zoM8%fMyldV%=-09R*dP4R~ykf7fRAJ%>S(Wx}7GSFgC+8FWUG~#cud8gvrR5t3=CH z!E|Nw=E>SYl$JzES3Qbp$+Dx5r>K+l7DIws_p~-XD#3K4XKqnxvUXdTm~9$fXLvX_ zBRxU6-=I}!G!c;+J^QIKNvSzfT~)Nts1qKUCP<`*f0m!*syQTgVR}#s%#b4!c+v%; zkBT9kp5l*4rhbM@{@Ew>Nx3O$x+LwR+N2bHVo9R*skG$e^cxhpjgG=(Ye|N?T&@3n z7SSnbdz({IBHu|Rnt83^=}dEG!kglmGR5#wdP;<*vcc+fS*pA*q-og<6AJht#{|Xo z$Z<0$S0kT7<Ul3_Pt+r?_xUMgK&E;mCs4ROV@AO_-}i0oH&nIh3x%%@v6}d_oZmN> z<+`&r$)qW+Z=B!hiczxbvUHItDZEl;v$56!lOpqNR#Z2)?EAOE!sIzW=$H#x7Qjy- zODPzG1Tk$wl?B99Lh2-6cZq2n#cr6~Y!!P_67@!_-kh0T>7M7$&yJ6bj!n^}Els!K zif_K(WJ`*US0(4k6!MqkY17iPY-&SUu5WI#Qh(uqNw2Xcr&YK-b#cn1$+j?s<hwPX z>|y>(u81qgkrqNyM4k|FDSUa{m~KHnDVZX$1))}Slo`3PhczkDn;iyyUPf-ZF2%@4 zDb4!Cb*=<e%8T))q;g+$vcVdr@JkJ^HVDslrKj1AdUL8eGMXu)>vBF>r;X+{8m3UI zTsyBzi%*DUn#omRY8hh0Tdaa*BT}Fi#;j8z{GL_36%b?4+gy-+!*=2xqM?Jjq}bRu zfxxSQK#&!ob3(xu^(40eFm_1KQQfJYhD6YqKOh_oaBS*;u%G{myC17RoXwsQfzDb) z1>?W^@bM|GqAsc9+<W#83|w}{hF@-&X9P?(bxhc=P)W~2)0tufH!BpXx{4|8@ec<E z_TF=Dhp_*S%kDSM+we<*4`RMzhh+E#3YSMGB9NX;s;giaM$c}z153Stj{vEXo=2Z8 zLWG~m|2|C0hmT|N_K--<{dk_|(x(2&j<a82j<7)<a*VG=IdA4wCDbcSK>b1~K{d~g zZ{4(cG~L@(Q@YA$yf8+Woo4rF)rAgot}f>FRcD{M+CG0?ZqD4MjMU2NoW^!r@!|?= zSvA<k92CN@JFxbt=D2L;b(34!GZLB0j}Yo%cL;}@;}Rod@}mE0KrY3c@lkxV!71G9 zO2b$$#=gsbPV1`}TP?*sml!{^DG3THo%|m5uCVrojXAD0c8_kPa@9~;S#dyrw$~V0 zYz?mM@HR*LtLN01JcU+IV!T<R$ud>W-e-4m=w~>j8ikw<RU-m{<ZE^>O|KcMFtSM2 zKDY7VvDKM|3}f~ZO+j^NaiD!yL7u*^Xyw|H+n8=?Y3sN}n;fStpHtd4KfR^$w8oSI zU#mB_9<t5>zT@l;)Yb8*$S5PSdznY=K@Gu<FWmk$)AuZV>-NmsZ*OGh3Fo~3KFO^Z zWBvr*t%y%jEjdl28Cn8$1v~<T-==y-bN2n0ZRsd7XQmr6G)0+?N=Hp?X0E4-Rp?oJ zbL7sEB_lSSK31#IYZ`p{jRhuE^yf>+2DDTEV*liO(Vsx8lOaP?kpxJz_KX4^^3ag7 z$e~Fr>;*P(ZdRUi&5k%rQLATeUxoP}1FhvYbK<<}yd1t)uj@T6A=F|hDbF(%G_NSQ zV!yCxL4T^lz4-KnlH8-f(|6!08rT$QHd2So&%Qgj;rSOz3*&u-?B|m^`BX#x4e&n8 z)K~0p{2F8?7O}r3Tc}@F6S6o+MM3mY&?ZU|A6;Qm|F*tw%l6wZ3avWr+(7-h#<S*B z&M%y^lrL=J;}pvm&dJTbv~2aNn!f6l%RCEe8w*;}sur-6vZA?JWgeICNtVByk5UxR zbGM<Z067_^eC!{fJB8Lq^sotkBm_il267jWqA4k$#)2p(zppZKU|WvOT)Cln<4{dc zh556-<ch+a{P}a$SxGOas{2-|@`DYHL-~#EIamLIZOLhwTkTm9ibH$_uGQ>A_9fQT zBgs~nojPqEy|iOr`gZR0-CugYwB!5g>$iN14dWQC{IUkb7sNjJij6f0kFxpqi*l!X z{24R%_%kLi;?ETC@mw_45gtTj%0S<OM$*(*;v(&cdYAHNzs5tocq$PbE|rIWP<Ya6 z&=x%Gd-$GsizDx4dnVRcJGc36?sR5bgy&YS`ISMzCnlLT2(9daj8?Tqqc9jE^BQ>D zUs$=Y{VyHf&ky{AXj5`Yz`p_bY3(Ujo(UzNlzS)gR4n#R&_{)|T`HeS?5~=bTWdG* zqIH63cK5QutF~Rz>FfN7-{$bJDt~Ui&pohURdMmqYD1Yh-DWe}%B#EC5Q|;g&^~bN zm?6@f!`{xbMHr$7w`O%!EIfB}TF&7jgXz!awrv@i=GNvj(x8*1sbanjG^UgOnH_ef zpu$3I?M#zLeQ2hEJw|Hzw$xZ{>POnf&~o4M=lr(J687h8Uv`o3=&QxcoL2THf3bG* zUA4mS#v3992Xf5{LwEP&2kbMoo~8?E(FUBi0cR|iz$KGr2pjXDm#omZRDPGj!`~(> z0Q_rNma#10+o)W=sMvi|?;CIM51sS2@P)AL@yGu?ETDf&^lSO^0V|&(szW8UiBBM0 zD>4Pc_NeKI5+NiRICqE~nHYb5marO<4f!&_&Bfs6LPNa2Y$z{Rm6oRR_}uoQO|^y$ zz3{-8Q}0ZF^G#8>S?sV=WbLH|^W%ko$JW&f_bsT8+PcY_>Pso{+=O;Xs`&%(%Qz!w zJOeZ$5``&*OHopW7$^4lsXVP#`S~-_g&|OK20LqWl6iiW!Kh=Wfu7Tai?$4x#-=1B zM8zrN_%FXab}We>j)+;%_C|Mi(&Ub;C{3av!4l`h8%vO{7WlpazGAL~@-T6Jsbcn1 zC>A*nszi+w$&E+{CPqsC72ZT<2Mpm}pM79cqCWtdp7mNYJgn85**lz^vk*k>_c(0+ zZ<jYMF+`f29}0hoi!?wms&p4SoNZJZ3=yX6S6NInY2OfG&Jt{{bQN3u`s;-+5{-7) zz{j9b3(u&9kf!GW$RwN$`W51u0?c2U4iSX(cBkDXItY&aBtgs;E)SfSUsAMc{fjqO zmM-(HUKxD(meS(v>(^$NF7GI5j#ekB(&7@*qBE-3xP0v$1<l&z=(NPdv{-G5LN%6i zPw3_s)UO}TxpQdG3yEDq(qHVi-gxKoNAwwfe|c@`=@YhlZn?Sj5vIxX%=K2=b&xSX zb#O|{ehvC{G=n2+gVbcN@zpS~X0iDdAP`U8<|v<n0J9w$httn$vp4w6sS1^FhVa)S zQv}IOp<2nF&o)OGx`oLLBCSYTc+NbfRWQIWq5N6Yptl6e#nV`(O<YuA4MUKgQDP!v zIz6HpKnM>NnhitENkwfS;U&K{!^_%y89yuKV|jZGwD_yJ9n0KIlVlT?JFq|)6BBRU z{%EwQN~JNE9YA&uRoV&<|NK(ML|sOCmTeV&mBPL*FgyTJz`moQ%iBRK?0a^Ub=eg( zZTuk2^0!ln)#Tshd%l$)HQEtl9qE5Ct~%FuW2Ym>B8FG}xG=!}v|o5(adJvB1=#$0 z-gbz&h0Bk1Q0l}bKt4ABCu$r?I%<WTLc6R9WK?qHn9dN~H6DmbGVL3LU;8t@PdA<8 zyZ*VXs!uDd8UD##Pxub#Ui#i|GnX5b8Tst^<j?AnHIJ~@gu?Qi2%t9=u|H%(Tf$9j z-{d!LcEAwfC>55Lxs<SFia}3+mQ>EnWr8>nmpzuz0yWX$M4<x`R2s4i<cDM|{1a}Y z@zXbaoxkzhN^Ec6aTa2z!QRpLkio&<VTdvnOzveyAr=m0DPZq58eV4k-NF)<>&aCe zIQ>0g+?|6=19HfM?AHP}W>_hXdf^O6<;4VK`WU5_yqH+PF!zYbCB?<?F~3$AK)hXV zh_d8XR%h7LRR)79&9SKZ<++Il)(1Q3F+`a&J=Mil1Kl#3)>I!WGDjiGe^Q*eOPhJv znY?r1bKTv~<yv=Y9Ea_?U1EcT{9G&hxk;4GDg9hUEB0_?X^u(a+lxBj$`z&Se0?i> zU%tiT&rUn!EMMLsym~Op+uos2ZORsX_OIXO{BjsR+x_h1v5Z@9{DlzWH5vB^FTj7a zkPF2?7gfZvh1eBl7WUGxeMn-Fjf2_MQqWU;s&Zu040n$h^`3(O{z~Cac<m92cD!ct zWp$F0=D6v2H!I5VtA#qe&?(wQ05sUdH5}An@Lx*qA`{sRA=3r9m<1>(wrSOFwBLOy zgy4*l^>eFpTUPQ`?^$r*n{09VB#W0-%<&Zby2r54ZM@9yzre0gos&OQxl*s@|7h2# z#E=phos-S(DYq*PaUo&Rm*sZhtE-h4n%Zd{#R%EZoS7zd%9%o%HKUPRiL(Hzbp;hi zeni?_ra@A4zE!wunQ!@{Oovxg-hwo$(sVgbU1WCVTVmf|oMPM?IH!SDRo-|biRH5u zN!{JQUuO}#k=i2HeNROQKfi=xCh}e_e-`kX#FcblQHfzw!cJjxW=2F3<l@gVsax0D zYK3npdb*NwPFoRgQnB9xeb>8%YBT%u7VF2tr)6fP$gwhr#z)J_m%6)mjq)gVDMl3Y zzXLw%iD)5LlvPqZ60;j16#E}?Aw&*}oR|Mya=f|3pX-RVReTQv$aW?>f~!pC1l@eg z`1wgYeZ{%%41TvksV;0jr~M%kFswikwelywcs?dI#k%!o*1sv0;$j4sJXNf41Ai_$ z41TfOprVvIfwzlfO!Hl!@RmT@RQ8acs{H6Lsnp~UE`?f5z4iRX9rYuvbNl)Wa=gOV zpv#(`Y$*!{N-8?nmqsLJnpu8!z@EdGukL@fW?4&(LUkafu&b_ettTzfWQiminQ|d- z^mbH~uk@txsmaNjC`0$#D`I`R8-*`dt@))zxR#9t``4~OmMzD$$3eRn-LSb*Tn9Zg z1JR136xnK+0tposn~}<hjgi?ikOn5MP$A8Nr<I_p(5CQ@3%@d!XxjsEDho9Fb4Q;3 z{ulJ-bk<=>*CsA(j?+W4_m<6_)4JE5nYOQrkKr?Q!oIr223}#%+Ae&TCp|}`8V@0R z((wiZ&+z)1e*95JDTdP15fc95voJomQxUHy&Q4NKKD1{;8j5qWy;$f16D?OK_V%=* zRA*EnaYPm&6^CRPXhZAat~!re){94>C7qxjtMn)ET7@Ci6p^=ZWr?j~3JP)B)!E*T zg*g$%bldXMOkaVh6<@Y*cY)9DUoL#+(WNT+UmL1S5%ucIj^flSWZU5*yD!vxR#ryM zkF}N?R#mjuu45UJdW3Cj*VQg9Uv=lX5jq_)!i&E9p=eVc(u!X+5-hcfFGEq}pKhhW zmBnUTB9cq=5|mQ@p2B}9>{pFvKO0d5qW2k8=8PNou1ojrtgOiP6}7FttdqYs)21>A zEf42bEm`#&<Ev}t3AyXvc;oj)CR5@y-CJ)<>K@O$aOv91^(J#+EPF8Ps-7ocFIM<A z&Br;&SSl&f$&Ef#^2j@-u!kxibUIyro!&1tC8`-ri0C5w(dp%Ek8g2#=GaZi=D0M) z-Jz`fV&}4rndT&4T6%I?ytX}3vG1aHPIvzOLA{~u?3D}VEKk&wpQccqrpmQtx)Nd? z3ZXCE=BzB}FxJFo&(T;@bxAKW%kHf&4)Pt7kFk5A7j2(kH+Rol5zT(2R<QM{e}MMg zpgjZB7ZdHS67>5NSW3sdG;QsEjpzVkj1-AR7>D2~Ddl(Prl%MRHw?v(o|O<~gK@u+ zZHn6(lVf3ld|&=U!)eKu)Tm0A$D0_z-}0n#p}`U-OyvoGkSyAg#~yR)jmika`t`ye z82W&wKj%GLs!E6=`q<PPpzogw1EL5Q%_yZpwV;ob`t~qc6|*y?i-9^66)waul6E4~ z`cc+8_<ssd8Z`-yteD;f#RUZw4?QZ}?qiFE52IPF(UO@<mkV=i9(w8p-(Hj~<-!VQ zYC@tpWl63zv)X%W<ebUFd`xE|yUUSovZgG_vD&K3_C(g=9kmbFl0Bw_wih5f>CFJC z#e&xyeaQ%36wb*oeSS@b3b|P%h1weCQ7L@L@!3V18+Km&*Nd-wD|X5Dl*K-u&zR`% zNsgLRP}#ZGuz1HZozJl#bY60RzxSb^Trzc6e3px4|18I4{rC1`$2!)r2YI}n8JW1k zIKLr!&F#X|XJ(ZzCwcw<p(a$&iU<Dze+N3YvFKBx&+3AxG#(Aagfv#cfAI0#Z)+EP zG;!hHrF$<AvYzLk=kJ)joll+o<aw4OybC@fIkcYmTL2>tYfn_a=b*>HX>4wCJ<2q) z8Pihqb*j9W$F+!OC!X5z&g??gTDzg8u}%0IO_kp{ZCSx2%Z3eEEx8WoNR$gl@3r!G zSXazl?k-&a5<mZmguE<k$>XobzTb8zp|mj9{l`y~UlCO#ccP~q^oSf~GqwC8h8BlN ztlB64#YYM6ums^tmM2^Zunq4w{9tUf*c%c@(i^?fNQ{aQzCVcJ7`En<2I0-HFdzp7 zmyfmJ`><w8`3yQelz-1GYN-lXhDr^WK?RIeXS>$tK%N07;_qwPe%eo;e`e=~(;M71 z{nxv5mb7h{Y_<rOICFB?TA{|f|LR?@`df>uyq3wSwB&ah-oD~RRR+5|V{2LY>BMg< zaOHttvF~o9zB@=}c?S<RfH_H7qCL7nUnZVQpfy6Q+>-0M{M3N<t2G$n<1?=c_MUF3 zwa;Cyj@s3V(L#J@_u@6iwqnMIgh=-5$&XPL60aoVDN)8r=-I(;6e>XQsF_}+QK&48 z-h<|+zI)7m@F45UfBBkyRXdErZ(CV`Mff|wzQp_`4+<Bvh2GC{B(;GLyhX;Z1xzJ% zFQF`tTGH6s$&U}RD&g!IZbbZw`FNJzQ$(5ruI(^ayBaIf9xAnf9<M8EHH!HM`SbsD z7PH%*dGen94Xwh&BMTp7*9b!_B>WW8`7`g3B!s4@z=*d9QI8)%kFi)qCS9JeYU@%X zz$s8mN!oO%DWmvk-_EOFesR~;FYjvIRozfmQPET<eAUVp?Rw?St9QNrcDXRreCB3h z2m8)q5tP=Y?3&gy#|RfM;`%B7Ys^-(Dyk}gP5{sxK~ohHG*LkjVk=sS<P56PDfA$q zAOZ;h0vjGx0RK;mV)E6FR2LS+E0R-kbnb|Q{*GQ>&$-PWUAeKid}(b?U29ui&Z@H; zI>&4I%F_0(_R?g9DRWV1coA=N$K)lLV-h1=8EQ+4E+&~@etG#yx1pxlt9EM*(S_N1 zr`eM2ZZ4ePms>meG0RwxJ1;BGQRTGScy*=C*IJZUn@5I$J}!P;1ier^;ZVom2c1$f zhKu$c+{X_JU&3=B@ih%$!-U>pmp5Zf3ZzYTnZQ%_1NFmOs6L|M@ROVUD|-ifS9%X- z<a)ao3)@>^^Ma#nWwF8FSy|2wOx~eQZ}PD}PX3yY6o#F(B0b1f_@}4ofr)q!+)xs0 z_@_Ub_~_%O*^}SyUG`fT!fI@<@+D!a$i^{N@r`U_dQe6NCPN5AfsJVt-`w=Y2G;+@ z4TsNCobv*<-<{rehH%B!wygvfYbQCfoz1c}1S+2VM!^7Ij#EfVqL~fdN2b9{ik8VY zcOG2Fk}<o)?tZ;X`1V@iymjpSW5<|-oqOnz@QLu4=s7&z$Kv=2z=@^^jvf%4-$o(a z3*xl=#AgSE?-|?2KQ!^=X|F(J0L9|jb>xGSw;yL&!n1!OTa4h`Q(y8P_8z{yav}df z$IfQ=x}^EN8ukX0PvFIgU8};G3q^zpX*Xt9df(WmLYW0Ed0ymw%UaeIG_*Ao*bSL} zU3qNDvIqX!;4J175?F&~abi@W%k$exyPdh~nhL5?lOnar=@pv9ikQN4o_O~qUsVF1 zSZubuvbrWFR(U0>tvEl~ZGdq_aFw914SXh`TW7<&1BkG4mVt~8?_MyqILnC6DK3qB z+%6JEME-)#O`-0Vq8HfJW{agKIX1hxG+XyXC4a})IXk+0ceoK1h5f=GQdZ~XED`?9 z7Dv`)kLN5&kmXBqiGy6|y+gd^Gka}Tk8H6ZLXHL13MEAY_MRs$zIyxcjvb-u0aHwZ zH#S3U%Ql+~dV?+BmTVRNTJ?ZKlRCV8Xm~r`iB8E$C`>U##|zIS#-!;A7c!f3L;tid zrGj6r*xSPd0z6tIg5U{Nfw(lHpgBa%r`nx9M~eQObN2Q3U(_}FN28S=nPbo@cQptX zu(KPCYkOhWG0D{#LcgeI4?kbjvkm>~63ORis-lcooDRH_)*)TJSDYD88AAQy{N+>0 z^Va;pcum{Jyi!GyennQ9KBuiaw0Yfv{B4z$+p4pZ;uBM{OJ9b#(Y$iZS(WMXdwETo zIr?_@j^3`Ta?FC0T`ORsKn+l*5bjqksbM*qww&D4$QBipyYnUBJrUd^rXapYYQeYs zf`ep$BnLHLvaf&NK0dpnd2NH$_*EslPJO=c9X!t6(fqeB%-%@h5ov;vU=9H$`5R_H z<T`k75@E)nSLt0Uy$EgSqq9`|_OX=g8|u%=9r&X1dF4~EjgeQ%MvlK|{iQrr!FQ>) zhz6_(eDO=vVa-6TQnTpSZp&+^<wIV`J6<ouh<=4<6|InWIxNVADqQ5ogy0Axon}do zm!~Lg6<rJZg@cLwDO&ff!OuRH)0Vqfr!dtQH?IMspV|$df>+g^zq9L<xBZ>H=5%Lf zIIZCMbBjAlc=Yr1@(5&7wZc=g<Ov$oh!*G+gJKjrv(Sg}N)mOtlOWUF70v5pnO4+0 zMI3;C++3m(ek(zyx$;Xs8*o*~{<IXoIqAI^x1Q!nmD(v8jZ2&+vv<6|W5@e(RTpGr zW~v?L8>`sTgWE4UxP4gox}<I86k8M-DLkagVzD?A{oTX20d^8-w$n;76W?w@RRMn& zU$)Z!(Bml$LGa9N?jMHB=kfbqe8pn6^hBqS&+DJ8WcTM>yrFkT@p1mffbd8Ciu~*) z!a=q~A$t5%e8S|HqR!k?l8;b!V<p^5tSHZT1zxCA0MRMkVjrK^(j6M^Z_Z^eHdHoL zXQxD?r9i%5e(iYij@}Iy=a?sdMVMHHX#Dp@E~#eOnkCu!D}Y<FttUiXX(`4bXP#CS z*$5$KPpFdg{-scoeo+oPP|4n%$Jo}gBkZ;6j4UKKvfg>FWa>-ycfj&<Er6vez_PQH zUr^pa`Kb$)vELl!aU-b!I}}i*3<D=}hJjuYJ6@2OrOP)bXrrQ2VhxJS9A8>Xmv2dV zLaH^gM41|u5|fgoOHIr!s;@6PudQkIqKFbYjAZF)O@Su1u`t%DPE3rCR>#CCV_A|e z%WErbHfBU=?c#7vWL!if?@TfpGwbqNmKF-Pu=GN6f!R`Mj?=NkOrzazF0o?5B>5P? z(@pR_am~Y_g;oj_RmiG6Uc7Hf@ev^kEj@PA%KU;#yE>wy<F>rz%Zs<vu4!<p)BGic zFErfe`Jh2~IzE|C*9!BS5O4hWlAw^i2LBMFEoMGR+XxTHL8_#T61GKCT;V>xu)TTR zKJt==%C9P|PT!hl<`D+SON6Z?{3zB0KLM?gAlM4HQaz!_<!2HQ>#cLvl>Kb~x%}Br zZmijeFzLazi>;R+fF`W)D6|+$(Mrlcs5lb=oREKL`#vmDl>DV<-y*){;YIwSs~Sq{ zg}*kGH4x0>$MO4S)+25rZL)Dlx!Re4AFljRBP(e26Q5ZjKRWaKq3gQdeDnLh9bNn8 z|Ep#4^2?uLaTi|r=<DI}Q{TWx3>cq^i~)IvSnWvlM77e7bySaEOtcK|7+Pv_+R}29 z=A<VXv~dZ_L|*vh!ySC*wq5g{WUozrTvL~2%TF;zBu1ylI+g6>fBzdFJ4Oo+LVj6* z{9ago=$~tlPU5w8O2gQD!s2~<*`9s-mNdLLzk$^@Gzd>g#9`dj*X$^N7vd82tCH{* zWRlN~HyFf*8(y?Hx^3^aZF?<^J@e=HG_v=Fqp!Te%&!O!kKA(0$Qk$Ei!qGrz^`Wk z18XS`3Ocq7CteK18>MOr1awFpEu154tKm27+2nZP&+*C0@jdR+c(pn{w^66k#>A`F z#3yGc=(-|a&0espu}`ik(Im%D?o|U1&A{&h4?1bH@YJwsDZE6A-Fje@yp!qz^wMxb zh}pZqd2@Vn^ewKe65afYw7gi2E7joI+|qS+T7@&~C$FgEo$<+S__hM*<DzcM%5SK( z&uPy{*QA>=GE58CoxUokxjD<ZT@8xKzZjPb*&PNwRjA^{wy6_SKQ(h^(Lk?;h*#uA zQrwo?W(Zd#96u!UQiap&a}^m9h@!FiEn~$wzPbxKJgXb&LV~rSxT&ewABT92m-#M> z;1~KbOB~5MlRd*cuW5OmXIZ-8w6bNJ(&m>Csi{f%t>qPqlj9<zqg6a?1MjEe{gu1X zZzz-`CpH)8y~jw21`?51QWd&p(|W?hnxbHTQ^#Y)99lXOmz*3o|C{(^<=>)`tKyRv z#H$};&%Fa(jft8P)rP~gs3>-8BE;RFoXj?vg}X>rC6Lv-{BG*kX=bv~X;nc=;))VU zP$UYgfj*B-d^t1H{!p&Bed8r-7mm0LsV+@yuED#wDznuUo1i6a;rkT)=GVNGa{kIy z=XNb18Ki5B87ph&EiX;Leb6e>Mlmt0Gb7e`rr$M_vtzOxajjZ>_ed$Gcs|PKBDL)B zxvMsW_H3$L;B>pR(VB{2ynp`kt-@YDa!yuZV|`vx!`rL3J#otwug$MC+cHdMb;>#2 z*%!<)w6=C!(lH<1qiK7&57`Z7E4&^~uj>%bWV{hQTNQ3S7-xs01~yup=HAZz$z+-M zrHNu*gyM5yo?C=J?9r#E>u+NAt!lbi7oVJzj93`vPlvTl#DwtMbkx9uCy1>^$l6H` zjyJ0HGmZ`hJI-sZDVx9L&MouH<}4nqT3%VXyt$#PzP_vBsrD^f+RIN%Np2}>>g#JN zYDrExZU5@Jy4AI>l()5&m$kLcmaUm`Hzv-SGYZyG44Cl@75d%~EcHfxUUs-{>w-DU zNW01L>Aux*{)QD>FI+vaVLgj4&2%rQ&n;?Ti&yRL#JkI+++^L^J=qtmTD|ReRfe|3 z5O5QP27Ch<k8cByiSH*!-|32979kSihb&9{<XAuZ(4#gh(bkclreo=|Uc5wV7LGPf z0cyEf`Ytphcjl;3Wl1n3YNDi1dEGVPQ`WfRQpd)?Z+{!O#epwIHQUAC2d21)l;{K% zeah?DCLPYE7yTT(Cn<i*h(?;UG(dI;dc|)V#llHE#^=&lrjfpw2GQaWNDwsBXO6yw zF1AeAQPx;??@Mm4S^nIyz;EYs^e%I(e4b=-CAbku_@#|&Q#InnR<FgDxyaat?@PND z6rM@+-<m;RLRv#CJwY2ohstDR;d~^|Vubzim*BbhQN&>m-^4&h;y-qoLMI<%Eid9J z`IzS-A`ZyM3NBOWl8+-ejdEN*R&w#mJLKa?T>q1Ntm0Nj-YFkPb6u)e<l~r#Kd8gc z#B!;+qw@7Q&ZPIt$MF#pHj{juz~wksz&lt3I%Wz=kECO~>l1OCe9UuE5wFX~3a&BY zkbE4$IhD=wv64$uULqey;`&4Kv5I>{`MG=?%{{N8w+skZO!VDR1@dt$SEPGDK91wc zb>GRy@zF2nm&wNo+)^jQ`dx?{;kI(4+yK|d^>gFMth2aoL@X=%&_(zuMm<VL#n`M| z7oN4^seUeqeLJ_5Yr?*j+k`t-5!w*ob#lXi7v#q94u%!bLO378l`)JQz;Pe0hPYn* z4nwNthVVR5(JhW9ScGFpzA}hs+cBma=Ru6xDnkD8(M=*o!Zr@t#xW+0u@!K)iqv$= z^!+%L7SJNy9TJZu>i(y+%*NQsoqBXVu8)Dr%_4uJB6q|?H~RJ@Ly~9@_Df~S|2TgH zDTs07)6yi2;qkNYl2(W#D_4)BJ{%8YBxym?TNpp-H-xJsO-YlIPJhg9it)D@%J6QI zWH&{~p~804BH|kblvcna`}p6$G-H?lNs3m)>OoQZGqyek$|O37>&>93ht^5vhDNrI z4)pbpTeG^et?r_t;(T{eagnuat986TXvH7$vbJvOvd#?+jdTtV1jq8Ms4d3^#>NMR z`>df}@uAwG;OIbi=dg8de{cu~gVy#?_dsxbYu<^sn}#uLeA9T42DbKZ9UJHdJVG-K zp`{b2L!IOQ0g5zmHj?_mvEb%`;Aoz;X}G%}&)PZMV_gcUC*Z3e40ewbnS<he=`=Jv z&~2?B?i&~m21h{)jkmUjM#l%hBsiTdo8q#vQpl#rL$YZZ=pGHVjt0m6>p`L{PbAS= zJ2+?+r9Nf_jNs_zU=MU5g_r>TARC$9GTCH9P*e~%@h8>LE?)+ULp?aJ!$X7gH_7Tk zgZSMbju}Up-3ddZATWxTq5c!Z{Am#72zUhud9-m2q2ckC&av^}X!(gK^9fOTaY0c5 zp8D?rK8a`%0>>>EiK7@vY+7d{Uk)um^w$3cEMW?*)1nzev|kDVQM{-4Op$`3@+kHs zVv2jC+y-2e;`RR*@rSVf=LjUq%t~4q%Uar!Z5<f1c3Q_rJA2?3qZ`O`{`;mqcCu}A zV4uR^iDAi#iESqQZov~Y5m+&4QJ9p%IEko7yfYIR!-1A2y;1x~p?K#0h=_;6Jc*Y= zx-_NIL>v@V-zbW@R}}rQ82nETYcxd@WD3Z%@1X)?#`|QC-!d@XZ|xlzCg<+y8IatU z!a#RubQFFsy7S0rX!Af%u!sD2ZYVfxZ4CAH4s{OaS;O9G%^D4k4~zzTfTI@ZX#TZ| z#9O%~m|ICO<XALIZGnhF*prCJhG`z~ir2{jt$4pCDB4xnnn=XGqM*pm!t)EwawN8X z+$DbwVQ!+VV;-(jjHW9iV!kkpF=Vmy`-ehm2MnT?)EE@$BP=9#$;u^Fi~!mguG1_z zj^mk}MDmuI?4}P~hQRU2^o%TVI>Q0Mn0YG9<%pOa4T6?2arUP9^*?7tq*S7gW=Nuc zT$T=TPh)#UN`_|9`ajQ~$cSo@Wwpb2NOwPkK-!Tqw*Q<%NsyW_r~eqF7Lk4_pOf@V zSsqF2#GFoo)bbx_`mb^+2}0{Mgp;j;I1Rh#kMl>P{%1MVsbd&X(*(<;pKMGek`15e zH&#)@6fQPFtDUePDJ)2Nr&YA`Ap{92FALk~OioSqJPOFPKb3b#ahsw#*^=bHM6Gmv z1+I1BjBJ?fOv=Z|k0~Tlz>_ll*}fvtN488f(|k)ojJ!(HD#?zng*lk<L-KG6pxw9| z*20Xh({;%zek?8oxqwI&jU_peHYv=K9Z@9`5U+%%{V`GEwV+V4v=eI;syD)Nm7w&A zG!1ZPU>}Y}Bq_-Q`@t*C&r&K8rgcz^O!P#LND0X}%)2z7&Xyc;H`@YdBy=KevttNZ z1Vw@{T#8T<<ufxgMO)ID6bWfhbdyfVPKZ+};*H}eil1aB`JkMlF-cFNaXrqdZXi2d zD(k%u<0YM(Sg)Npg0M?Cr3flbZe&lSZ;IUngS0^V5s^}&j_!Ah5*fo&qz#Jq;cH<F z3E?@iLZWmGqlrq=1HmI3B_29O%ELZFnv&!-0L@6YMpX2Q&k^3R{f~*TBn{8l=7|xT zU{J*xrbptD5(bhV&3<%G@~;`lC#I_T;Eg0CQ8nXjl9xz&+XC)S^e0L#C<2q$cHti3 zBI}~~PZkl529oEGijqE&BN|N>NBd0}D{(s824_o`I3*m?%oD~&^*mL7BtfEa6q4`3 zk)-9>)-s!~A96Djvxpjr5`q{`t-{_w)=e}>6)8#nL|IDQNZKIEdQR}E*?7rTMgfg5 zSiwKlyJY(`155TpoRTe{Jkv^9xMcIQrTasBBmP(XfCqv|aZu8E*xJGzhNIQVaaYPs zW@l9{P-+FuWC!8eV77mg6r~!L_@UTE7J|B|c61<U?Fm|!Y#Kn>l4sr0AF>Xhh$t)b zTDNqLSsU>;yD4#Q8tx5^QgMk2V`;D(E3|{5zOB}I!Og+J(8y45c--1KK9dZ#qlO*s z4(3^hkbENvNB)Sv&W#jvJaj^B+&3E9G?Is^5=cb^gI4hpp&Z%NH8?QVkFw^Zx_LA> zLY3d}ILO%?9JBV0hK5cog-<S~ty#5m+q3g#YULBkTe+OZLrtx-A39Y*jfYxJfOK+6 zjR#ukfpA_-%=P>?%jsD)hc&CIzP>)Y01}pUV}(FNn?^hPkcCs-KNKA5BH2KqVq2jn zI0{A1r~?x0w4y#n<AJ2PBG_f^rOJqOJkZ^51qewifH&43+BAsdK4?XaKPV#*bvQoI zi!xvA3Xs;t9>8o{2nM?QJBRzA>Ch;3JOX)A{Z$~=>9`=aKqOl6NFN#@XNXob27bo- zH;oOTUM8r6TXCT$G&&|?N97ha8A*V|aTuCpA)S4rL3%c1g&@T8ZWx@w2>W5SUBT|q z5E<V1mf+y#VE)!%=O{s3kAkK^tOEN&utvy*0LwQ-g9khmI>X?5s})pX8|m-tLTS^T zXC2!*)D;?}BN9jmLr1M+Bf;(gfPxrCJG<dSW7bW?1DvRHc&oLyvpYCWc*e*hBx%Zq zO<f>@Lkb)XcA~XI`Vt?OI~Dm|odil$8wdq&Tf%zkK^tjwpbHHl+=n1UIcyG&ZVe+E z8wb7Pn~0U!<PHpj#2{J}J=T%V(ebT-I6By~1uRQqk#J3;ksDS3VioH|l2#BcD|CJO ztTL5A12#HGdn7#4*pcAq(7?EL(=a@AlpKGy(;|jIBCu7EJ1w^Y>k6tw3Bzb`FbK}W z>LIfV+wOFza*bIx4~Pv9N#CeRA;iIfGsJcfb*RS?vCFZ(SctiUehS3dZGbx+^I|xQ zEfD9aK91`jA0H_%EZnkXO9AZhbWsciuvgqUB`B%kOod)}S{OsBL=z*mVx@FyHc<5T z5CW;`l|O(+8LX4aWD44p5=c|t>>hy>@+p;}DS`@9nv%jPhBQG?nlO86AXqekQ8_%5 z@`Mv$nq;I@U7GI3L?KW?5Q1=qF)dIEM>I%jOn4HS5f&90lrj;HnRGLpTo61dg`_En z+WR!IS;gsw=%*r4N=2l}R!X~<iYeO<pOTW|*~ySJ)rP5RM;hM@=!=0zn%o*heu%ba z;Gd1L@+2Kn>O-m02sj}sh~7c$DP`${xpag2G3-x#t`N^lWmf@?`mxoBBPm5$3kW?} zbRPx;g65RZ7o&mJjL)BDCqH4zPo`4hn5<zYZ40N8WMvYUBxNc9iN7C8Z6@uN$|sua zrP6~^2BNGFG=`HysU(`M-!MKYEs>H|N+bzuFQi53JKdYjkEA1#I9Wniw`3voBwY&^ z9AVu_7ESV(+AgFsO7Eo9pRAXz&{IP=rbJAFLVNO*lNS`iRG+FHN!BXyLAEKCu9Aew zT4&&%N(y1hDGjEif9C0vJxD4wBpK6FlK&A05^l-M=|0)rX7Q?&Vun*?YMuTkYnRH_ z*$r8Go>G0OxkPdqg=FYA;S786j8{r2sZ<bC+>x|TG9mp?+>#P%Nk+tTSYQ7Y-C6i> zqy_LOc97jk_O)E(mTZnZHv^50*;=L&p8B3r(MM5;#`cP1Bt20a>x7O@w6_1L{z(U9 z10;7UT4y?}Vfzf1Ehi`6GZ8LqIZ~-C6~~e{h9z`z3y`Qhae<R8Kw6p$kD)?|>?mAp zO0Ah0A00ix%QC<L;UtMjy3K$*Pt9HUIu(f&;Z9}m;dnq0PUif-!;NI)RJM$X@hI%0 zWP3A~GgH8Xqcc%6<Le|RvNz&rlSqjKw-;w*kzsv>Tg4O|rTLcZh3<F43#565<Vek? zaQQ<XP4lM|10|Xy>ZGziOy!U$=S6sWCc1<rLexp}AxIRBP9-m*p6HRf^_xVDGoDI# zPSiBXARJqy`J0N*Fg-I(su>uwmtSZWB^eI^4|$K&QX@YPx7g?^m9q5YAnc2LIUFly zm+=w}R2b5cH2;J-KDA{LB&qR2wn*^FyJlkj%*-X}QKDc_#z2ys9cL-0k-R}_*-(j1 zUMa;)Y2FI!kg%NWsggBNR<i+PD9@QKSIGyvfP-{M<7e}J@{C4ziHh0uo!D}a<P*M6 zb0X=1O6V~p?nsoSwG$+&qsT<Ng9Do>M@Bk}L{`eGk-raz#DtgXrC=wDFr>+2$cB4D zTZRWiojvjh`T3zuW2maB%%SXlj0&2ufuWJXpcOSpa2Rlr%MXo7iF^1GDkrIG09eYU z+nbuLi${<hH=y{lHp>Gm<$QOndvsuAe5_z>V34xi!tSB5Lit+Z2ujU@k^YgIF|-EO z4)jzFV}a3${o;n^Y6&R;4}%mJ+r&~tERG1}80yvT8EVB+3FV|%?DYi42Kt7@>Si=7 z9~47K{ZR?^U}*37md;VRDgj5RLPc(^xG2>^Ql-#6FhYeD$`cf8!=Z6N7z%BsM^Ma8 zFG7oT*7QOk3YKwHF(`&-dIz$Ks2)S1m1iB0OG8;fDDpt@3AGvu?t#r>3xbNM4JV16 zY8DbX)UjzC)gV^WMna=_97Z9kQmUI#n~$RKMGf68Q6w$upA0)Iqb1aXQXG<z*LgFt zC6>E8M^Qy}T5-1*l^rBO|64RkJwL`j6@XaImzVk=Pbvk&)s|>*VnYX2@0K9cD4LO6 z$)j+QUS^O=R|t80>qwBQTr?j<jgCsVGeAq{5V*~NMyAox@utDqa;H(CK(55YCH@Q= zSbpc&*rwS^7wbVuwxZVIdl2g;kP@=?ZW<Q(66<di_Q4+T+1Ul3>Fpfrr|uQ`Cl&T$ zJ&jVG*c&RaE`n#mT!@g+Fz6Yz4uxju8i03W0dx}zS<#QeOv56mET`60SWL3o#RX_8 z=Z8ACQe$NdZvfEh>A?6{aIiN|v<j(%00<;w_zxkTC9J%#pTqFT>ce$D01)}%uo6Vs zOpS;jv<SOKBZW9b14ULUx^JD`8{o_mtq^S&-q`>)X_)M2G)VFRxzGnabWSY^1i4dJ z!IW8@x}Yw^3{DYp6t&TbGe&_3YY10o*T*Lm-Gxxg=vq0V74(k};aU7S4*EBB5q*1i zihsA_8pBigEDzt1L@*_bWGWWLqFD@!WpVgyE`cSoB&KG`_((4We^p7x^emMbSQ<-b zMto3XW)@~;HkQHcEE8YqIhl)Pv22#Za#<e!CP@J+WJRo)xtWKRFfa2lKPzSUzt`bU zCRE}(1Ntz14y$E#Y%ZI}>RAJu&l*`1Tfi2wX4b+MvBj*FwXr3voh@a{*mAal1=vc~ z!B(-=>@>E9t!3+2C+lL}tcL|zFY9CdY=Et28`vQJD%&s%;qM7;WTR}1jk8T`Guy&W zXIt4B>`ZnRJDZ)u&SmGZ^Vv3b0lSc0#J01G*(K~!b{YE#yPRFYu4FsdRqUq>f6AX- z%XYF|>^gQmyMf)vZelmHTU6-P6cyDL(Z0T@D7-J0&+FxVgS0P}?-$GW-5%+>+bi!& z<$am7_xPoK$vkQAmB)MK@m{xly-wcGmG?4UpZvT}e%>cP?<<j>^T~L9KKWe6=acdI z!f<5z{W3hieBCc!FO{#C%6Lj;Jf$*!r82%!8DFjZT%A0wE_^PJtCPpo$>Zweadk4C z^JF>AljSt8R-%8NO!qvQzIifz^)jA%8Be{0r?^OxTXB)}d~uQVe6cL&Vp-0`vYd;( z5?yXzcrVGz?UUfRebRWmhb+?L_RIJE@_kueZdoqwQu%(VM7O(C9$zNW>u!**H%Qk# zMH2m<A_=~yNRo@ENP^=jlH}o$`SKJ=<2^E89@*|Z#q#)Kd3>=vzE~b#EYa&Jmd6*% z_}wyo*>3R-mB=Svyq5R!c(*)Wwl9xQzAoF9$1lV2OZMt1mGtK+mB-2Q@RUk=@yK%V z$a3+N$>Yl;J$lMye##_!@s!DQl}YyEDU<0dlkCP*Ceu?U<1Lf%mdW&#$$Xc|_{(Je zYh`@3GQL_FU#$$kR)$|I!>^U$*UIo~W%#u+{8|})tqfoG2aoIzo;n$y><=E<A3U-@ zcw~R@)XDhkWc+n9{yG_dos7Ru#$PAnuaoiD$@u3=cITNZ^EVf-<I@a*zxK(CZ(t|j mO#CBD;<<v`gR2p^Ce1U99)3}H;4tlff8*6RiRV)fZ}~qs2loO1 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e75e09e6c0c376e117789e9287d1a95de9acb009 GIT binary patch literal 41272 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 VEAz!4bNj6qpZ}ixeDilV{y*gL!+Zb$ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c27d42fb250a5881efeccbf9c9dabca18efe958b GIT binary patch literal 46752 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 aJ2X$nzw$G><GX+P&->~4^jlxM?Ee5{i9^=_ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f81717ec1d0c057dcf1be2b9ac4e282fdfbe7987 GIT binary patch literal 13656 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 Hzg_r0+*1Ba literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..855dec982374b3f452120cbc47e5a892ef51c02b GIT binary patch literal 12228 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 R|HbRe^ILY9`_&g#{ucum)*1i+ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f955ca2ad1ba36cd36e185671843448854d517dc GIT binary patch literal 15972 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 M%T9{>g|8j{KQNtsdjJ3c literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6ffd35778fd8eebf304a4842edd92ee49398567a GIT binary patch literal 12556 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf new file mode 100644 index 0000000000000000000000000000000000000000..01ed101cd477dfb112616440bdb6a8a54a30cb67 GIT binary patch literal 19760 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1ccf365e8f1635df3d0672a92c416dca0e8ef033 GIT binary patch literal 12192 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bf2b66af7620441b260a339358adf5c9628a4d4e GIT binary patch literal 15836 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bd5f93f0e48d5d993b349c160cb2efac071e8599 GIT binary patch literal 12116 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 a?%3z>>-){`{2Q<5X8T_=_sdUz{(k|K5Uex+ literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf new file mode 100644 index 0000000000000000000000000000000000000000..73b9930f6cf7388f3337355ffc5cc0035c053e34 GIT binary patch literal 15704 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmb10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmb10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..189bdf0f0a01c2fb07e436ee4e348ae681b5dd97 GIT binary patch literal 25680 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 Jiv|$#e*tY@-gW>0 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmex10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmex10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e4b468dcd37369fba8329f015fa644d9053848da GIT binary patch literal 21092 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8d326610412db20c62cd2f9aa0cfc06f334ab648 GIT binary patch literal 32560 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 MzGIk1O~P^i2Zhsw9{>OV literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmr10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmr10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8bc44966a84421629220f03a87d1cf479733d2aa GIT binary patch literal 26348 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmss10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmss10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ef70532c71098c1ebb1e1666ae89ecc70ac8708a GIT binary patch literal 20376 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..45d8421a5b118b1f49132337f80fb7730521483a GIT binary patch literal 29396 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf new file mode 100644 index 0000000000000000000000000000000000000000..15bdb68b3f7165c68547949e0b2c0263a7438add GIT binary patch literal 28136 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back-symbolic.svg new file mode 100644 index 00000000..a933ef8c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back-symbolic.svg @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 65.144375 35.006875 +C 65.144375 32.425 63.43375 30.15125 60.703125 30.15125 +L 33.991875 30.15125 +L 45.105625 19.0375 +C 46.019375 18.12375 46.550625 16.87 46.550625 15.584375 +C 46.550625 14.288125 46.019375 13.034375 45.105625 12.13125 +L 42.258125 9.315625 +C 41.344375 8.4125 40.133125 7.88125 38.8475 7.88125 +C 37.55125 7.88125 36.2975 8.4125 35.394375 9.315625 +L 10.69125 33.986875 +C 9.82 34.900625 9.28875 36.14375 9.28875 37.44 +C 9.28875 38.725625 9.82 39.979375 10.69125 40.850625 +L 35.394375 65.59625 +C 36.2975 66.4675 37.55125 66.99875 38.8475 66.99875 +C 40.133125 66.99875 41.386875 66.4675 42.258125 65.59625 +L 45.105625 62.70625 +C 46.019375 61.835 46.550625 60.58125 46.550625 59.295625 +C 46.550625 58.01 46.019375 56.75625 45.105625 55.885 +L 33.991875 44.72875 +L 60.703125 44.72875 +C 63.43375 44.72875 65.144375 42.444375 65.144375 39.8625 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.pdf new file mode 100644 index 0000000000000000000000000000000000000000..79709d8f435ef2031ee4129b2180e725dd1a8d21 GIT binary patch literal 1623 zcmZuyZA@EL7+!|kvbzZrI}A?Z*)jq+={@)M>lPUaZCAp^vaV$gotoUXr|rdZZ@E2X z#SaYoF`07-gF$pLBH5DRBr*|DKsN=Zn{gUr9FxsC{bP*qL#LZsF`m;8%BVL@ZqJkV z>pbuKytmL{vzKyOJyY0!4ZJnRZ~y|uUC)%41J)t>Q5f(9aRRosIfMXf6|opp{Gg(O zL9&+`3X2@JMRAo2ix>fY!pW}480ZrJ9U{g^m4SgC8P=gH9v8x3AIW30llUl#0bAWb za$1saYw}$Uo&>BbAbKU)4~z--x?S#i<iWrc51uZEg9J!jpi-6<940A<zm=4NWO6bm z0#vC=Bn0R+tuDaYP?O|A&MK0coN8534u?b)$)4ua%@g({5xWz4CDEcpNnD!D#M2+i z;GhmT#g`L>m5Ayg1X6|;2&9}YVviP+s@5(A2|<9h2ML2V<WanY@ERohaR6|%FHY(h z#wrpUnCQ$NSEW1!)_!o4dFsabl^cYS(?hpgHqOZ7Gq(nvvH9%wVB4`ac;naT?3r_; zU$2S%GP&x7$=FZd_RRl0_gifEiR)huv^2lJ?4PUXV^vx6`Xe8meXi_w*2?^~du^uf zaIEQzW5W8pKfdbgzW?0=0m~LielV|Ocyg*XccfK4GnjSw@X`7`oke*6>hj+3X~#EB z1#j$bzaki%7w66%t@rP}tF2(;iK%Or`%Jz0e~nKZdfPGF68>!8n{_$sI~oI)M=d*+ zm)10DUiy3J_vKlQvt5sE^3^%|0_XT!eR}IBEwW~^b<;!V%j$YY^FD3uZyJL`-xW+% z=UmVnjC7sc?k_HDxHmVu`|d-V%`dlgS&Ku{9~QdxjYp1ac3XZt<tyysHA5Y_kH2!N zV|wfCvtxsnOQSO@f|}0B3-8oiQjX^wdC_957<x6op<>yA?19TWix2i+>7DD}EY+Jg z%uJ{cR9{>-z4iN|{S%jexZeK!zbkGIoameHSr@%$y!6laDqf4N>im4<D%C);A4xUD z`$QY66U-@v(D_gHI6bFSAgRVza)~*tBv?{sX(h29k-&8BD*2Qd_y1-bF<UfSRA?D_ zseCd(DxwUK>ONJWRf&+vCTVv_UaF_K%A9oQ6Kf%{Dbly&?r<gpizP+2(Zx_~E8`(& zght45yv_hkrBGi4VNnUgTB)6)g5m}dhk^<YN^Zbu4O(9H@Y;|P#++HF(|S=8+~Rke zOa_rRJ`4gFhsszs?V?pwKM6+Gi#OsSa#|cM<n;l!=y{qnt7H*TQ5E?Z2sj-B7am|V z7<2~U0}B{OsG|>%Qy2#gWC7fXLBUAaT#5-~2Q0zNLWUg&VTK(Cd9ovx_(CJ;?Gj8U zkU3j|@tN_UpwG<9(SD|Uu_{VIq{hDh)v`|k@n(_*=2R3q1My|%lAb|?FiK(=iz<#& P$ngUCjudX&WoP~a6%7Oo literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.png new file mode 100644 index 0000000000000000000000000000000000000000..e3c4b5815487bc1e5fef303915d494e3aaf015d4 GIT binary patch literal 380 zcmV-?0fYXDP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET49!W$&R7i=nl(9+!K@f(&KM_I2^j3;Z z-XSkwXKxWw1uM-}zJ^%a3yC&9fN1X%<N-`!V`F!Qu?Uf4&EC#slYxO{kAJ?onc0z< zu}y1jHTpULNvD#I-2yXnJ8%Weff5+FG!24Z16J`laF)`!N+f9n+y&PypqE`DU=(D& z^cirHRiZ@jZdMO~A~$#xu&Ll?hQgODsQ_*xE&BjI6K(wlhGsVX*JR)_l6g~qj*V%N z$j)nr%R>lw*$|-oI|U_b17q^aQv&DFDM~=zfg_+(<GY?Q-Kl}R0S8&{paPlHK=!i$ z4#+F8mj$Rm9wU&Ols>tx&Flxb0G?KS{z~cHJ7vY6+{0qkG}=XVCaDedS<L!_ImC?s a>)0<tWZPr&hifhX0000<MNUMnLSTX<IhY{; literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.svg new file mode 100644 index 00000000..a933ef8c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back.svg @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 65.144375 35.006875 +C 65.144375 32.425 63.43375 30.15125 60.703125 30.15125 +L 33.991875 30.15125 +L 45.105625 19.0375 +C 46.019375 18.12375 46.550625 16.87 46.550625 15.584375 +C 46.550625 14.288125 46.019375 13.034375 45.105625 12.13125 +L 42.258125 9.315625 +C 41.344375 8.4125 40.133125 7.88125 38.8475 7.88125 +C 37.55125 7.88125 36.2975 8.4125 35.394375 9.315625 +L 10.69125 33.986875 +C 9.82 34.900625 9.28875 36.14375 9.28875 37.44 +C 9.28875 38.725625 9.82 39.979375 10.69125 40.850625 +L 35.394375 65.59625 +C 36.2975 66.4675 37.55125 66.99875 38.8475 66.99875 +C 40.133125 66.99875 41.386875 66.4675 42.258125 65.59625 +L 45.105625 62.70625 +C 46.019375 61.835 46.550625 60.58125 46.550625 59.295625 +C 46.550625 58.01 46.019375 56.75625 45.105625 55.885 +L 33.991875 44.72875 +L 60.703125 44.72875 +C 63.43375 44.72875 65.144375 42.444375 65.144375 39.8625 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/back_large.png new file mode 100644 index 0000000000000000000000000000000000000000..e44a70a9cd230e86135e1f27492fc649bc464f00 GIT binary patch literal 620 zcmV-y0+aoTP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PE4oO5oRA_<inY~LKK^TXh(O_%gnKptS zjo74!1e;)IBmNuW`Ejj(fgq#`q!&pQB3N1|*jf73h&E>e;&I@e*ofzAad+grkG-AQ z8TUQ#2XC{xv-3RrF|*4U5uumUmo`AsybGkAo)`EKx&vd(Ctx0U0Dg-|*=q+P60Cql z;0cgg6@jl_`v?f1Z2)hqGBBfBAOgN#_rMpG0>E+?_<9|x6R?1<SDzXIV8s$XujURo zzzdL7A>atV;qA^RgkMb)K9PV1cxM4E@J<52nihC#0d4SB0vh2(1XF{Hj4>t$eD8YT z>y&^$mTlUl0vrKbBJ$X>H^!CEVSnXA)Q<HdqzJxV)6I+>e<_VIbJ#yNq4T+UL)1U< zQa}*b^fzya68IPp#9N{S_TG#lep-giD1lAjBpi!ViY;5Zj6xaUnDj><0q%f7>zP=I z#3k@8$xNI9_JOIc2menASO6|8+O$grD2T{&+r1XwLK&*>gw2)v2TZ8=m`f-zu0o(D zG3+4m7Z_6^&>(TDLBhSEo5VFRszN}EMDi0<CC)4*^1z4+fdmq}KKhO|k;REIW*9gC zCSx|K00Yu#f{Gb$Yh)r)0A_*nm`(1I!h`2UJ`uSkzQhk-oq8{-KSSqqe*U-dur}cB zCAO6K1@wFCCzL=<VhH#N+yGa=x=(noqflDu`IY*f7kB|GJHVa3+gAzz0000<MNUMn GLSTYdj|ag3 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave-symbolic.svg new file mode 100644 index 00000000..ad8372d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave-symbolic.svg @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 21.4225 61.72875 +L 21.4225 47.161875 +L 50.566875 47.161875 +L 50.566875 61.72875 +z +M 55.4225 61.72875 +L 55.4225 45.94 +C 55.4225 43.931875 53.796875 42.295625 51.78875 42.295625 +L 20.21125 42.295625 +C 18.203125 42.295625 16.566875 43.931875 16.566875 45.94 +L 16.566875 61.72875 +L 11.71125 61.72875 +L 11.71125 13.161875 +L 16.566875 13.161875 +L 16.566875 28.94 +C 16.566875 30.95875 18.203125 32.584375 20.21125 32.584375 +L 42.066875 32.584375 +C 44.085625 32.584375 45.71125 30.95875 45.71125 28.94 +L 45.71125 13.161875 +C 46.47625 13.161875 47.953125 13.7675 48.484375 14.29875 +L 59.14125 24.955625 +C 59.640625 25.455 60.28875 27.00625 60.28875 27.72875 +L 60.28875 61.72875 +z +M 40.855625 26.5175 +C 40.855625 27.155 40.281875 27.72875 39.644375 27.72875 +L 32.355625 27.72875 +C 31.7075 27.72875 31.144375 27.155 31.144375 26.5175 +L 31.144375 14.373125 +C 31.144375 13.725 31.7075 13.161875 32.355625 13.161875 +L 39.644375 13.161875 +C 40.281875 13.161875 40.855625 13.725 40.855625 14.373125 +z +M 65.144375 27.72875 +C 65.144375 25.720625 64.0075 22.9475 62.5625 21.5025 +L 51.9375 10.8775 +C 50.4925 9.443125 47.719375 8.295625 45.71125 8.295625 +L 10.5 8.295625 +C 8.491875 8.295625 6.855625 9.931875 6.855625 11.94 +L 6.855625 62.94 +C 6.855625 64.95875 8.491875 66.584375 10.5 66.584375 +L 61.5 66.584375 +C 63.508125 66.584375 65.144375 64.95875 65.144375 62.94 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.pdf new file mode 100644 index 0000000000000000000000000000000000000000..794a1152f602306c0326b0bac9b194323c521d83 GIT binary patch literal 1734 zcmZuy4Nw$S9G}Us+|rShQ5w`Ih9B{<`}Wv7k5D){PQb70pmYd|y}iBj<k&s;-r>R6 zm{vfVH7Ti(PAVWJ#*F1RAz|`i4w;xtX`+oE%}5p+YDPlu-Ejh5J2$iUe)Io$@Av+{ z-$oeqhG-ZQOGWJa1=Jj)AYg!OUO~mj1KP;jL>FK&VghtVfl~x@5|4O?Yy)%WQlexb zfwPAsBzw^Obi^YO#QKs9vV?%j_ut4PBq|c%$daOsiY%my2)u^-=nc5O=s|!^&BHzC z4ZM>E-l-rP(CN#0i(Rq-wJ&|y67vdCKtSUyKDZsoV8DL>og~S~g<IhKB)k<-!Yi$> zz<fn^I{`UnQaYgZV!mAvP4jVUyvk5`$>rn~Q4$LLC-=qUM)V@lV&~_{9$c3+)3D@+ zI~Yj<^7Ca9U9wvdFoA@jM+6d1hp<OB<KL~p?!W{A+Tg$p>P11eV8R!Qk_{~fklc%j zB)X6y@_Cf!g1dBq6b7Hw-;aBDapH#OK0m|i-un4BYIMtcXHPXJu6|fr*-<_2sfiUA z<&)-*!i#U!6#R4Y-u1S)-t`TuPT%7{Js#iRw=#aso2w7Ce6sRN!lFB#?RVFn8THfT z%NrjA1ziq#eQfqClkZ-dc;<z<g$I9ct=>MK-CVFMD)aK<iVtFs_MZ!VW8B`pnz*tL zubE#uVw}FUymI7swbipqx8?3*tCVTQx5wU?w4+E>Frlk=cUW~-nOWGn`P-;N=Nns3 zPYG_T84-C$c#+SjgVSfUbsh+#GJ}tl-~2e*Iq`OPXZVCU8=pR!bs~D%fza)vn)~_j zg=;U>=r?^GoSJc<?1{h35m$S&&T}s-_5GP8RXf~;cc;u;pOIk9XnIg$N?Ub3?9as7 zEt9P~FaBFnvG0r6chVYr98X?d+N4|kM^SO+XJg9GMeDl9Td$=A-%Rctv#$I7yiw}* zg<;lU6khad*U|Kz$os9e$IFjpMU8B<|D8Yet1oYvtPiK1GVCcEQNQ6>2)jjoJNVaI z`O|Jx-`|-N=jf^2AJMe9F27}A@`Z!DPW*5<J8e$;_xEa=Q+m#B;G-^a!ZSGyd#!UC zuGpESRUwCS!novw4);_|k!LrXpSuZ-?)$N0|MTb8)i%xJ*T9sZ_O4a7Z_d|GZAb~- z)2-@l+m=w5HEA!A+`#n@h|fC~WPUh?@e7j3ZD6DZWkK}lpEDiwjlB+I1F{|zE-mmF zCS$H+{bBI`!ypbDGRj2P0ey*D13;qL0Fc;>e}_r38w&}yU0}Bm`FcfdA{z6#kk6O~ zPX~u3V|^gIEa{04&D6)S3{*2}20~WFF`8&5b_T=Dm_^Y^Bu-Yq%sd`B9Wrv*%>c%5 zF{~o6F;3ZqpjM@dv55Ihq|L0+a6GGy0?QF{#?ka(N{p=7a53y=7Po-aJG7e9Vg+Vi z$i<g6YY0&uMYK{3fGUc4^Z+%-sW@N-k1&X-BM*@L7=&u<0>d#ztHJj2IHtw6G8}`9 zHXsf{7#Ig*v8N5sWf(QS+s81~Y&>U=VJs8SgVAyU7-ZQY=RgW?cZiDjgOe&*W#GL` k?3X54CNtpm&UAaBhzTPkx)84*FNIL0<*0~=<Ru2`KfXLf;{X5v literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.png new file mode 100644 index 0000000000000000000000000000000000000000..919e40bf58297a9abc727b7fbce9f53cf039ba5e GIT binary patch literal 458 zcmV;*0X6=KP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET4Y)M2xR7i={mc2>?K@^3*8-lSB1i><u z7SRU?7J>%tY{WuPt8}SSSZZtIJJ{I>f{Nk`*a=oav<+IM5)_qyKgS}oxURF=WN`x? z80K>K&N*}M{H;kMOXM<T2l9boW;vh?4D~U-4O~fjkByLoE7K036zvX}3wWX}T%u{< z1*ifCp1B;lZ&hI5`Sx7K=Vn$(%HSAyaQ3EWrnOM)y7MgnC7=bo0+ntVq=KXyU><k^ z&Z3$8$u9DUOr;U97&|Po2o!*N;Lk?`9X>q1Ei+qlcF`9nsbOaKz(kV35wHr3Mf~Hg zZv&^mrDv=NW#|=<)C6W?#QQ?#SH<A&qA<*C5;)=a8pPodSdrA|NdQ=)b3!kG=LGU$ zI%i-R=vg2rT}{$;H+C~C0!?Dd{r?wvpu0#w!OZHwtn+P{Su25K)b(XIcEoWx*6%xh zn{+Rluk8lB7XGU+vl9Ki$v(URw~{`Ap8{Fn3j^G`Q#DGO)&Kwi07*qoM6N<$f}_yC AC;$Ke literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.svg new file mode 100644 index 00000000..ad8372d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave.svg @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 21.4225 61.72875 +L 21.4225 47.161875 +L 50.566875 47.161875 +L 50.566875 61.72875 +z +M 55.4225 61.72875 +L 55.4225 45.94 +C 55.4225 43.931875 53.796875 42.295625 51.78875 42.295625 +L 20.21125 42.295625 +C 18.203125 42.295625 16.566875 43.931875 16.566875 45.94 +L 16.566875 61.72875 +L 11.71125 61.72875 +L 11.71125 13.161875 +L 16.566875 13.161875 +L 16.566875 28.94 +C 16.566875 30.95875 18.203125 32.584375 20.21125 32.584375 +L 42.066875 32.584375 +C 44.085625 32.584375 45.71125 30.95875 45.71125 28.94 +L 45.71125 13.161875 +C 46.47625 13.161875 47.953125 13.7675 48.484375 14.29875 +L 59.14125 24.955625 +C 59.640625 25.455 60.28875 27.00625 60.28875 27.72875 +L 60.28875 61.72875 +z +M 40.855625 26.5175 +C 40.855625 27.155 40.281875 27.72875 39.644375 27.72875 +L 32.355625 27.72875 +C 31.7075 27.72875 31.144375 27.155 31.144375 26.5175 +L 31.144375 14.373125 +C 31.144375 13.725 31.7075 13.161875 32.355625 13.161875 +L 39.644375 13.161875 +C 40.281875 13.161875 40.855625 13.725 40.855625 14.373125 +z +M 65.144375 27.72875 +C 65.144375 25.720625 64.0075 22.9475 62.5625 21.5025 +L 51.9375 10.8775 +C 50.4925 9.443125 47.719375 8.295625 45.71125 8.295625 +L 10.5 8.295625 +C 8.491875 8.295625 6.855625 9.931875 6.855625 11.94 +L 6.855625 62.94 +C 6.855625 64.95875 8.491875 66.584375 10.5 66.584375 +L 61.5 66.584375 +C 63.508125 66.584375 65.144375 64.95875 65.144375 62.94 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/filesave_large.png new file mode 100644 index 0000000000000000000000000000000000000000..a39b55a6166ba51063ad780cb1f4ea09d08dc1a4 GIT binary patch literal 720 zcmV;>0x$iEP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PEa!Eu%RA_<in!jrmK@i73lW1N-qDDb0 zv9QwAhNyplY1AT>og!G+h}dXhC02s}fT`{5G#Fng77`E(e}GzA2$82E>Vx=WEbb)x z*1fykyZ5qpa9>#1otxR2@69s1+@7c^O~zR40IH%T5F3pru+1eDk!j!zuxEt6e*y1- z6;<t*o<&s$8ZZq!26T&B54Z(P*|GRE7lE@|7`)k@0<)n6TuW%T(f<LwG{*CQ<YhF) zE8x2&n*rvG@j9>z=%nKXperILRP~F8j|7ekTxRpFJhPtlDSngBovBWUzcBQ!0{ehf z%YKc3OpKxmea(1LYClueb>K9xVu<HSGBNApEP5GL)eT^Yk|d%NfNCUaK>*5=s0{(g zC9x_ZQ!blY5r9k*3&3@ke(ear0Ew<4z91qKw(ckh<ZX1`{!$X>fZwTTFR*CqIS+Fc zaa2TZ1K%w9PT)w$M5_8hMBV|1Qqg`}CzL=Rm@LrQ4qWk^%Lf}qf82f;x`gfq>Sv(` zJQ~JCp&7UYd<2e{u>FV6z)e+sQ__9_K|!SFnH$4!JS^0*jE0~k5F0Il*a)gZA~H_$ z1))kA&B9OM32;qS|M(h(25|>CA7~STW55pJqOU>d5?Tt>FM}W-p&2mGLCe6~K>I8l zW;3%zXRQHLS;zNOwOg!K3=ug=$)(x&D%28)jg~-cv;<<K@dR8OnR)X)CnB$namVN{ zi->)RQ5G|1-|~4dBR0TIpl9?aNw#?x4tR$bhOr!<z5gVRo0JalkT~~bdF=r(VaF@3 ze<ehu1Ds;C*Q~x!;1h5^{oFVJCxIrR@l~kt1pWdk$hVv8J*c1n0000<MNUMnLSTYQ CEH@DV literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward-symbolic.svg new file mode 100644 index 00000000..1f407136 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward-symbolic.svg @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 62.71125 37.44 +C 62.71125 36.14375 62.2225 34.900625 61.30875 34.01875 +L 36.605625 9.315625 +C 35.691875 8.4125 34.438125 7.88125 33.1525 7.88125 +C 31.866875 7.88125 30.645 8.4125 29.741875 9.315625 +L 26.894375 12.163125 +C 25.980625 13.034375 25.449375 14.288125 25.449375 15.584375 +C 25.449375 16.87 25.980625 18.12375 26.894375 18.995 +L 38.008125 30.15125 +L 11.296875 30.15125 +C 8.56625 30.15125 6.855625 32.425 6.855625 35.006875 +L 6.855625 39.8625 +C 6.855625 42.444375 8.56625 44.72875 11.296875 44.72875 +L 38.008125 44.72875 +L 26.894375 55.8425 +C 25.980625 56.75625 25.449375 58.01 25.449375 59.295625 +C 25.449375 60.58125 25.980625 61.835 26.894375 62.74875 +L 29.741875 65.59625 +C 30.645 66.4675 31.866875 66.99875 33.1525 66.99875 +C 34.438125 66.99875 35.691875 66.4675 36.605625 65.59625 +L 61.30875 40.893125 +C 62.2225 39.979375 62.71125 38.725625 62.71125 37.44 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ce4a1bcb1321efbc3836dc6358c0e5fe0ecca68d GIT binary patch literal 1630 zcmZuye@t6d6vj-qtn7zQ)R+ytpbQG7@7|WSwBk%@X~WpE+M+ZeWISGPOSksD=JoPp zgv4bKg*Xz1b7H2$jIp3Ym`*_^;^xF`(=BE*veh|F%rY`#79;VGq3FH+0Uh<F$?N@c z&i(HF&iT&Eby#ghNL{SR9lilhoK_$JfmFXsQCbQ(2k*mSprMEpa8-Lk7;qMz@BzsO zwro*g(Zd2uk`l^Wh}}haf<bXC$tH;eXk-5!JRw*XfsQQ|oI{ob7bc*F@>p$jf80U< zR}rL~W%0Kq{;mMEfO9qQ9>3@V`dGSqNBu4=5MYRIzH}S}DUi5;SrjD_rW7>aLXUz) zx-!N#u**_o2(W8fT!6FUCcl84c1lfGRWdJzL%fVdVNc@bv3N?vZO0xzUnaHCeHocS z!+w;(!4gP9FDDL5jj})mWC|?`$TUq-j~ym)TAM#W1p=HcKozuNLGn<+w_(vo8USK- zak9iPkue`sv_xuMW^qOKn#uXcCeNJRyLMB}ix)rN=^peC1i3dNcW3%e_H6As)Bc?P zoN8j@+egmVe(_GT;h%p^vah*y;_tS=n=^l&`f=)P;lgU;>__9}FMqagY;r}L(lWcI z`U6pQdu&zD-nXtzcYM3SU9s{@xBG#$mWDhuFnZ|ejsqrV*gI~{$k-{25#<#A{oM?C zwDbI6=I;K3Lmz+D@qNU4?8p`2R*vdA=a|dCuytkSP@ikm6bU~3U}aGdj<}C@e`={4 z&i$l7?VfHeJap}{QTXenQ+4~gR8spx_?fGG_I{J!;{CPr=Ih%ZO}}@!cdqQc?y~m} zkMrw?!0ktr>4#tWupr{zoD;d)v~e2*(_`23j$ec|)xx?b+Z*7s>phvFy7`>!uBpnr z{wFqn-ShZh{++JUPWzp#=d(OVkM)jRIbh$=`rSxD^Gw^6`nY%CkA?l4BBspVlRr%M z&1U^}Yh8c$!E>*z`etr;?1kD_PprQ1^Cj)2r>a!SpMIH`*WakUcQ-wfb~9}utvdU3 zFSA0tEOApr%f;%dHR=;aVK#`DdZ}HRPZISvqgXqdDHgZelA$<(r!Z?jvnCOS{yz-S zu%s4aeoNtHE=mEJmr_7x|HKI`QX_3}N?YmoFk3~<=48Den+~yov2;6hUo!1m;+I4# zn-BR`lLjI^)I)?cS{*bL!Qwm!^OOqC!r~+u<Og{Y3P>d2uLnr2Q)^^FqYg=7f{a?N z+Jl>5p|9Rx(D53*3N#QBGI88eidvF=bTc|-JdFZ%Rq}2jj~CSQ!fskDWs*=WGWIGU zKw1S{e1Kl3)9Qd1EMkaC#~vUiFa&i}x%)9#VxXm6ju~k!mSIL?N*sbHB@RJt3NM8E zlsKp@p?$WDLj&muT85SAQh5<dx(AVYe*nwT4?%_Kl|ZzZbdEVCiS<Bqrn&sBm<q;3 V3=>`^Q3;X8h!nZG<vVPO{{W)U1UUcz literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..59400feb49df053526e5c549079dcf0e40298cbd GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf<Z~8yL>4nJ zFmC{1M)f27YZ(|A**#qxLp(aSPO<l63KVGHFZkzjgX~5FhsUZqI~x^0@?6VF&H2hO z?|{HNg%TARm-PwW8poKz<Yw3In>qciXWh~2lYjQzoI6u}mDlXTYpZs%D=2MODtfNA zA}i>C$PFego9Lo{MZC|xA9$A#_iCx9L!e=~qfUeL18wo7w+9Wxlk&xS8uImz@SJEZ zX||MSmOoIMw8?tn?{GoK(EC~686sS?KCj}~uW;u{+@hlFGl!fxZkVz}%%9T~Z}RYm z%#&BbJ9_*C3;4eLzsPVS;_Tk)0@gJ)&*u4_Gupn-Rea~Oumi#CDogp3J_Z+WXORmj zoqfja+k?B&m710kD$Xu)H~U}3gr4=zWP5T<|IZn|3+&ULJOhRkgQu&X%Q~loCIAhH Bj}HI< literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.svg new file mode 100644 index 00000000..1f407136 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward.svg @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 62.71125 37.44 +C 62.71125 36.14375 62.2225 34.900625 61.30875 34.01875 +L 36.605625 9.315625 +C 35.691875 8.4125 34.438125 7.88125 33.1525 7.88125 +C 31.866875 7.88125 30.645 8.4125 29.741875 9.315625 +L 26.894375 12.163125 +C 25.980625 13.034375 25.449375 14.288125 25.449375 15.584375 +C 25.449375 16.87 25.980625 18.12375 26.894375 18.995 +L 38.008125 30.15125 +L 11.296875 30.15125 +C 8.56625 30.15125 6.855625 32.425 6.855625 35.006875 +L 6.855625 39.8625 +C 6.855625 42.444375 8.56625 44.72875 11.296875 44.72875 +L 38.008125 44.72875 +L 26.894375 55.8425 +C 25.980625 56.75625 25.449375 58.01 25.449375 59.295625 +C 25.449375 60.58125 25.980625 61.835 26.894375 62.74875 +L 29.741875 65.59625 +C 30.645 66.4675 31.866875 66.99875 33.1525 66.99875 +C 34.438125 66.99875 35.691875 66.4675 36.605625 65.59625 +L 61.30875 40.893125 +C 62.2225 39.979375 62.71125 38.725625 62.71125 37.44 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/forward_large.png new file mode 100644 index 0000000000000000000000000000000000000000..de65815bba205d862508648dc1fe0d0ed2b058a3 GIT binary patch literal 593 zcmV-X0<QguP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PD^GQTORA_<im%mC}K@^9-V|Eb>BL>zt zNMS2Tilke}6WFH`B#<YtH~tBBnmj}x1PdGc^lonxBtjq|NhJnPihCC}?A*O`ch8yG z3;tlLIlK4!X6DYF5mlwlS;!4AYaRr0r}Y9I>pv8c6<`Zk0zRwiSL<i|7gaTDzzg6f zpk=!Qwk@AA_Do~=KO^wNb`R{#wE*y}0^VK1O5n=`cvlGv_-+Ken}pR2T<4Oo5_r=< zz*NF+Dq$~&gqc7o@iw)DsX!^QpHjkHpp-aBCE+4aN*tz;a1$scj=UvY1xkr`o)W?1 zw1_MMuYgV9QK+V2eglsqYXvwJ5mfa<ZFOM81URGFsCl%gnFt9yp9A=4iO`jDqjuWT zWw@MPRuzN<EY`eb1bAK5*_KQFT2)6#KpjD*%|%s5NZ^Mf$TS%M$CbT-UFZqLzMXpq zQs5HkHU1I<ec)=|;Z+qWfyW{u3qX(AccpdU6R_OiHv^!rs^4oXozFq*zzq%~?|zs| z0q-V|3f@H^CA_&nYIswD9PnlWz|$P?mICKF;8iDl$YLWRUEr4D*c+4hk5oh~j?;gE zUy-$@@L(XI#T34eC^d&40$98Q9pEDg*1XG0TqEHIZz?b%u}g6j{|1}@t6uOXyHM`5 f<x*dn)(iXt2s5;W{a@ub00000NkvXXu0mjfz83Yx literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.pdf new file mode 100644 index 0000000000000000000000000000000000000000..13088169ee504507746571ce23c1686181e40576 GIT binary patch literal 4172 zcmds4eN+_J6~_j(*&@bTNi?QDtAIqAotfR)53(w-3oKe;Veu=Lq{A{SE6dJ0JBy%6 zgHmjPo<qLWMr;gXnqw47^l$*%N=g(zNXkd5r=iF>Xf!rG*c?C56OyLyy_tnsmZr@g zJ*TI`GQ01-H}Bs2yZ8RyooJgSHJ&0ERdmZp)0j#FNWkZ9Rhdjc{X@><6bpeCin3Jz z0ClR%Eph_<cC#X9;T(KEr&_g2<r4*tEmoBt%&lD;*-1uN?yov~@ZG9wH$GhX=*>B{ zr59(^_s=>PTb~hqzN>7X(=>G6cOXamo{xwwbRXJ0_FhrtZ+9GjDtdJBlDMKMllKkP z%$J_I@yj_MWe%iO&#0(23Zq-C-~Flm4l|s1veDUaG_RYzIy7?WxXb%QUC%E5$+=%G zZEE}Kkhfu$r*_29w!QOuRb|xYVH<hoii-2(%jUsf$T8#%`iA~cS_7I#BYNCz>}X1< zm}VEDlfYy`0(hxe5)OdcoCHWh57Z78e?#}>c^?Cq08)}vy(u$qE9VgLbEP_<L(>4x z!H=w0Kdu+3bIQCNP}^81hi$O20_PC{71&d~j>~tk$$Tl;0!1XCXaoMw#jDM{M}*6L z00mHrR+_;3y$T1U{joG)vmI&`SdY((bUDfbVl$LmxDuCx%T7y1LfM~e&d2)&2j>F_ zuWW@M1~^7IB7`J8vhUb9IgvD4Jen$t5WseSo`@kx<%MFrGWlP5`(Jbox`1_m(-e@x z3h(39ps|r*orlHgUs@ijyqiZn($jnXTfeBup4Z<NR_dI&JTx^?e*9Yy8O{F<h!n0O zO3p4h$84+!ImUx)#%lydlxT9zD8XHx(>vR`A}&4tqTNbt=v6o8EX(+#y*E>9v#M{< zHqu6FPlR1NoKvZ7N+iNIt%+z1#hXH96b$$})>nk_g%yzG_7<{ukOokGEAt&ydhnCu z`64}zHUe0IRE&@=C_DrCL;8`FZU+Ud+lMJsrUT?{U|YFpD5=y?fymI{`jYmL3PiyM z5*ci=i<}oQ6pb}*4jSdS+%At(v4@Ryc|^r{9V-ehL^6nZAkCmVK`JlWprvUbshXe! zRQf@LM^ONNr0~fRlxqX1OW}-#R{_-&Q3-G{beW<8M2UBr49(Y{Ob9aUSHLVOGXE1S z11O27l_{NTU+c-C9vSSg-<|Fq^lWb(3%6RW;ro7`qJ8cMuUaCi&fGhC+hLAs&~x`& z-+pdolW=GF*7fUu`Fm`;srv)9zwET>!Uwtg7xnz?H@fV>13j;%z0+sf{pZe)lV&t! zni}#gzEt&KOxD&5a|V*v5o4!*ea3Cxd-RDvWW}%9+?HImA^yzaJx%EcHNAzicOO3y z_2IU6V}5^RL*0_4WI55-RQ$c_)VlMRhqlCZ*Jr%8@OK;EfB7;!<CUjYC0>tV>bfl6 z*H^ySaG<cVxy2^7e7ZAg<npOQbFTDtZ4u`2&kyWjV+J3u%N^ZS=lgirXO1i@Z>hZd z_Lcq1YDQwKj~P~1mMrYa&#y7`-Cq3A(t+^yH~8|hv+jzWkNO{LjMY!OwC@z}EYA4k zYJ7z$tK=O*Q(H6G5j8fpZKvqobS(3)#U;n62hNz-u?JBxSqH+8)K2UA$HLs9;rn+U zd@+4n?&<H_hq~A2423PYx#&(u$CJ5YV*R-#3GXj?xPt3-os5sD@n30g9sYdLo)cu| zkHf7m`x?al)!pq6H`^0eR9~2By7bD}0y;~7Zs_#vxB6~I%&jeGd4Bz8^MADVt)gGe zT$6F~&3W_RR42XAnf6li>ZJ9y_Q<pP$Om7PzgS;4{8;Md#SL*6BfAn75To}-oICci zw;KCLr|nqLcBb|5mQM=0;@V#Ko*kmj>E=f^Piw5*o@AiHQ=e{rP;$C*?#A0G`H4k) z|CD=gSKDWW%kOV7P$eIgS<8v<L=9Yiwt3d4H?K0!^dBj@=I*K3eS!T+Mb)?GiRQtl zyY_1nUQ4+3?BBjj_pq%UR_l$ZDJo6T3+YJXc&SbFfVg7DnN874Of*BmB#vs1r7(Hp zM#*R}&>BYWmgIp%^i$D2#Q^x3Abgn>DdoYK>i0NA7w^H9EfJiBFNPe3+agM)B{PYJ zgq9(VuuFn}a+gG5F=Ze%Mo2S+4$s4Wj%Kt*c})i7XJ}kNx3WX~M!LUNi5VM$EToJ& z5}qyuBiSn1ImrfPcNJuV)C)}Ee_)jl@wn7?Qpl5R*~w(y4;y0)25le%uBUiVOOK?O z_7Q3dBtp+T`9Q*1qCA|Wu#6uhdJUmB8uS{3I7!kPqs9p0@lUAQ$bfi*jxbV2y-^Ej zhM;r?$_S562#H>+)9Pf4?S*VUJh+f9c%j2amf%FdKuA++Gw<dFyO(vqZaS!o9iQg~ z$#>|d{72|@jE-g`UGlmBhJcbze@P7QYFH64Js?h^;OC?pjvJhVcqt%*+Xv1p=_Eqk zy$|EH)`e|Q2E`160vmqi2FixO4BxUuUI5D+tV`elMNlL`gJp%H=uJ?=_Yo*`3aq!# z<?s=_;Eaot;v(?*eg}MO`_CVnaDYbe1bbj+Mb^#ZIN)~`A5IlzZ&WI91u7EIlxm`B z06K<&JWv2+nMRAYMi=k|WF)PF88S&mB0`uXqqQN=QW^~;vq|fWBt&<TOk)Vu!Gy{v zEe%_j;AbgXA7TroCm~x-S_cz&vW#Z*Fo}ZK(F_x^pN2w>!K8J1I#g!RhWJLq3Yz?^ zMr#Pwp;PJ*1=i)}1pMY^ckSR%+)$2Z^SlUf{G|pq-BSQ_4!7edL46`Ch&a+3old8U Kj!wx;Rs9o0FU4s9 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.png new file mode 100644 index 0000000000000000000000000000000000000000..d956c5fd72aed98763c20370c025835202484fa8 GIT binary patch literal 979 zcmV;^11$WBP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000WV@Og>004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00004XF*Lt006O$eEU(800001 zb5ch_0Itp)=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_fl`9S#0009j zNkl<Zc-qBP%}Z2K6hHUQeNTPPhdN>^l2+K1CW>GPt=!n6RxJh#F>2i(&?cf~5N(R6 zO@!EH4BECxszoJAkU@%;VOkpKXfyg|-p9S~cHXEnlOJ!KMRec|mwWG=-#NegJLdrW zV<TRNv6%E(P03DhcpDHB0V%7uj@Be0Ux<_w>U`CBG)hF#07GMmE|B6XE*m^UlyV7w zANO~MM-K!Li+xskWBoM;WKS_vP#~|^_r?3sXseaK@7w9zI$V2Q5;#*V*An1}2>By@ zy_eq(4?oCK#_}(@k>k~_y&ULfn!TBuZdx`|fogv!dG2WI>~20thuK(n1y_%9nQhtA zv9%5_TIS=6!DW?JN`E<9O|1t!9`(HIYZn0KIN+@}A25Z1k1?Q(deh}N{eJ-ry<2UQ zAe%k?69R#X0F;!eKq)OCei9iPjW^^npwM3E5q&-a!RiqBEBv4-j2Esj(vf>)3N5Y- zwk>I-m4*1vAf+s`%a9VAQ6*3rK-oLsFhw3fw#Rb-jy!~j*~1sJpPDyH)N+?|EvP|N zO$frZVJLC=ClqwY(w<Dc@8VoYMN*Cij>So+Ow*(7-7^`NWV7noUg)c4s$5Z(%vx9i zER)0fZylWjScU~e3t)r@W^-a%T(KRLIFilMX?3SBwn-OF;3L;;Z`Np`M0`UJa+MNk zU@e*{NG+>S8m<B(Wr7i3kv^atYyre^aK%AE>gq$`WS%PZEPw-KlH{rA!imnAosmo} z%~egTB#sFofDy_sMNWV8)+(LOstBW)I!HUPObfWhL15H{O-yD1)P<#S<Y}cq*92~J za356K1pu(aVjIt8u-O60kau-rOvriW6QWS~&$eeowj|ZL&}&4V-Zx>?iEZ29eu4{+ z2}V9(^dq}^k&Eb***9_dW3N9pRyQQ-P;I5QZPoaL>-$lIg?KlA!tEM3gA>2XX<E6J z8IeT|1o92_cmpR}a^HdD+Vh8Z?7rUHBcj4cpq5W!2x@^zqZ4ojk(PTG&uT_dLqC&^ zq4wadQ|PD#w<@=XKGN|OYiB}~@s|VbwL1JS`vVaHR1$j>^~L}I002ovPDHLkV1j<( BsGtA< literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.svg new file mode 100644 index 00000000..f246f51e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/hand.svg @@ -0,0 +1,130 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" +[ + <!ATTLIST svg + xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"> +]> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + xml:space="preserve" + width="128pt" + height="128pt" + viewBox="0 0 507.946 507.946" + id="svg49" + sodipodi:version="0.27" + sodipodi:docname="/mnt/windows/themes/Work/Blue-Sphere/edit_add.svg" + sodipodi:docbase="/mnt/windows/themes/Work/Blue-Sphere/" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs + id="defs62"> + <radialGradient + id="radialGradient93" + cx="218.9404" + cy="219.7715" + r="150.7063" + fx="218.9404" + fy="219.7715" + gradientUnits="userSpaceOnUse" + style="stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;"> + <stop + offset="0.000000" + style="stop-color:#25a6ca;stop-opacity:1;" + id="stop94" /> + <stop + offset="1.000000" + style="stop-color:#2ea6b9;stop-opacity:0.843137;" + id="stop95" /> + </radialGradient> + <radialGradient + id="aigrd1" + cx="218.9404" + cy="219.7715" + r="150.7063" + fx="218.9404" + fy="219.7715" + gradientUnits="userSpaceOnUse" + style="stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;"> + <stop + offset="0" + style="stop-color:#73ffff;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;" + id="stop53" /> + <stop + offset="0.2809" + style="stop-color:#2EA6B9;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;" + id="stop54" /> + <stop + offset="1" + style="stop-color:#006b8b;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;" + id="stop55" /> + </radialGradient> + <linearGradient + xlink:href="#aigrd1" + id="linearGradient91" + x1="-0.295723" + y1="-0.264591" + x2="0.622574" + y2="0.365762" + gradientUnits="objectBoundingBox" + gradientTransform="matrix(0.996114,0,0,1.0039,0.496124,0.492186)" + spreadMethod="pad" /> + <radialGradient + xlink:href="#aigrd1" + id="radialGradient92" + cx="-8.09344e-05" + cy="-7.68867e-05" + fx="-8.09344e-05" + fy="-7.68867e-05" + r="0.789127" + gradientUnits="objectBoundingBox" + gradientTransform="matrix(1.06784,0,0,0.936469,0.342219,0.344712)" + spreadMethod="pad" /> + <radialGradient + xlink:href="#aigrd1" + id="radialGradient1594" + cx="1.37157e-25" + cy="4.82783e-26" + fx="1.37157e-25" + fy="4.82783e-26" + r="0.766358" + gradientUnits="objectBoundingBox" + gradientTransform="matrix(0.920679,-0.0285824,0.0336168,1.08511,0.373436,0.384854)" + spreadMethod="pad" /> + </defs> + <sodipodi:namedview + id="base"> + <sodipodi:guide + orientation="vertical" + position="73.690849" + id="sodipodi:guide127" /> + <sodipodi:guide + orientation="vertical" + position="101.148262" + id="sodipodi:guide22" /> + <sodipodi:guide + orientation="vertical" + position="57.943218" + id="sodipodi:guide23" /> + <sodipodi:guide + orientation="vertical" + position="30.889589" + id="sodipodi:guide1593" /> + <sodipodi:guide + orientation="horizontal" + position="61.981071" + id="sodipodi:guide1662" /> + </sodipodi:namedview> + <path + style="font-size:12;stroke:none;stroke-width:0.979268;stroke-opacity:0.986014;fill:#a4c9ee;fill-opacity:0.7;" + d="M134.757,263.776c0,66.739,54.298,121.04,121.039,121.04c66.739,0,121.039-54.301,121.039-121.04c0-66.741-54.3-121.039-121.039-121.039c-66.741,0-121.039,54.298-121.039,121.039z" + id="path51" + transform="matrix(1.89511,0,0,1.91236,-231.458,-247.971)" /> + <path + style="font-size:12;opacity:0.7;fill:url(#radialGradient1594);stroke:#1c6772;stroke-width:3.86972;stroke-opacity:0.988235;" + d="M 246.07 280.233 L 164.809 283.331 C 151.201 283.417 145.222 268.094 145.5 257.812 C 144.854 249.607 148.852 232.142 164.429 230.994 L 244.216 229.011 L 241.953 153.421 C 241.796 138.289 257.675 128.71 267.404 129.607 C 278.285 128.656 290.708 137.925 291.688 150.233 L 293.169 229.483 L 373.02 227.669 C 386.182 226.629 395.032 239.215 395.06 249.825 C 395.088 260.706 394.781 274.802 375.372 275.169 L 295.928 277.056 L 298.139 360.561 C 298.225 371.398 285.104 379.184 276.67 378.906 C 268.465 379.552 248.69 376.94 247.542 361.363 L 246.07 280.233 z " + id="path124" + sodipodi:nodetypes="ccccccccccccccccc" + transform="matrix(1.2536,0.0388772,-0.0388772,1.2536,-66.3537,-65.4059)" /> +</svg> \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help-symbolic.svg new file mode 100644 index 00000000..484bdbcb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help-symbolic.svg @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 43.283438 55.959375 +C 43.283438 55.12 42.603437 54.44 41.764063 54.44 +L 32.658437 54.44 +C 31.829687 54.44 31.139063 55.12 31.139063 55.959375 +L 31.139063 65.065 +C 31.139063 65.904375 31.829687 66.584375 32.658437 66.584375 +L 41.764063 66.584375 +C 42.603437 66.584375 43.283438 65.904375 43.283438 65.065 +z +M 55.279063 33.19 +C 55.279063 24.49875 46.173438 18.0175 38.045313 18.0175 +C 30.310312 18.0175 24.540937 21.31125 20.439687 28.11125 +C 20.025312 28.79125 20.174062 29.62 20.822187 30.119375 +L 27.048437 34.858125 +C 27.345937 35.049375 27.654062 35.16625 27.994062 35.16625 +C 28.408437 35.16625 28.865313 34.9325 29.173437 34.560625 +C 31.404688 31.745 32.318438 30.841875 33.232187 30.19375 +C 34.060937 29.62 35.622812 29.08875 37.333438 29.08875 +C 40.404062 29.08875 43.177188 30.990625 43.177188 33.115625 +C 43.177188 35.54875 41.955313 36.791875 39.033438 38.12 +C 35.697187 39.639375 31.139063 43.591875 31.139063 48.181875 +L 31.139063 49.8925 +C 31.139063 50.72125 31.670313 52.0175 32.509687 52.0175 +L 41.615313 52.0175 +C 42.486563 52.0175 43.134687 51.029375 43.134687 50.19 +C 43.134687 49.095625 44.537188 46.47125 46.779063 45.185625 +C 50.380938 43.166875 55.279063 40.404375 55.279063 33.19 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.pdf new file mode 100644 index 0000000000000000000000000000000000000000..38178d05b2725addadec9f4c005a1a764f1096d1 GIT binary patch literal 1813 zcmah~3rtg27|x;&*NlgQIp+fpOyr?(AARsrCbX0x7+6799kAWo9%@~CZ+Ckk1!Wly zK^)V_f=*u9WH=GnA_7s7IY!X94HAtEG0rGNCr)t!2`YP?(^5e&*-ew%^W}e>^PT_u zu3xfB9ZZGDBz_IoK>cY61xUcN+azn&03w+&Kr5gTq5(u|js*fj$%u@JH-M-p3FP!R zFl<^vtWAtd5g8EznIlQfb0UyB{wFh{2n7zv@lrx03%o7`ir`(;N2Nyfp-lutyczY3 znS3iJ-|-+F5Gh+3y^%8jg(F>?#BPH+5ro={Pi==H5#T&PG{^Cx6}3S5O0*Top;fq} zK%Bs5SpYt!G6fJSm~GTSO&n^CR;dERSuKnJIbDwP<c@gMh}Z!2Mka>0p}M$PD2;!p zLo!YfoqTDamCq7%h(OHHQvxxk)7ZnCaqd=aG$Dcjp*A4~RZz$45#foDGl*LOh3`d! z6Rn~E8MDN8)%<z)-W2NPUE?`>CgxUO>DhN;u1|M$FuSoZ|JW~?D{OgttH!Qp6kHDK z?F);FYRzdo@{RkM_V4+ewt)%5L{nbZWAotsob6A>Mkap0b!&9={QZ$?`q6in=bi6% z-@$$S;a_hJxe^z4483}>@9)}@gFk43*0X69+_iv%hua4_Jmpqx!Il?GKa0G%JT9^Q zrHW;DO1;LnMgG?22kD`6x$D5M-W}s!{>{y4m!g-rwoGh~{8`s<qwKKeW^s04<ms=K zV{ZIV09RBrZ~LA&Sy|fqLgR|H%|{oE6y>|D4hVarb;0=V#`T@$sb{M{UDz_`tE-9S z_vh9o_wG+mJEEx6?+iaTP-;>E?Ezai968gqtStLMRbl74m7CXkWcLf&hyq#Pk*bra zNx9ZzwYDv>r{u#sTNdBW@AuVJ&c7~=NvqmFy0Fsd<Mz7Xo;AqL_sH#TDo<~+y_T@D zPSJLB>D@06Epbs6pYH4M)&}&EMq<+{`Gq@`H66X4b?Tqyk*@ut!TXkWtQp=I-UQt? zyNtS3Y^ZZ@e!K3tTTPGe#k}emms^KkDK$SH{L$ihx4m^!&xr@ajW<5=(O&td-(>-t z8BP?Cg{i(LTNbVG9?$nIVN1IAvdb6$F_dvndHmA77jjPpd6)PsZg1FiQkqfoX5MCx z1Gg>pkLDM>qj{LXE`O5d(NXf}h}WENm!)6+Vv#xHVdqCw@2TQ{`@`Ss8e3a?_95$1 zk2N|uFOzDu&k-Itxh&kNV64x{8JyA)7O-<LqbY|@q7gRf15-*TbPR&AE~05?81?)x z3WZIZeQX4?`eJ#{0<p+vf!LRvJ5=&nNO`Djf>Dq4Zg&9<7Nx_s98NZMI_jBZBq-6y zb1H0H0jda^q(aFsil$^TQYH^3W&R}TA1EP|IF1)UfSD03CSEidSwM%7A#{j^w~8_a zEe+AbY;u)B$4VK<ka~7C*eZ&a2!fc(2;l_-s)gK7pQS@;pI*$O&jc)^`vBe5{}c|K zMx#xDnGzCEQVIF=0SdWXDhHY1DMle;@dG#~h7O4AYX(Nri0he{3^~{gjFQccqZH4H z3qua~Y%WPE(9O@lq+w_ZXJ9lryB<l-?n{SGJBKJRMiUh5->-NslLz*zM)s@Wc|0L@ dD^4-yLPQuQ(JC^6Xr~Yz34I0qVw2R8{{W}EW2OKA literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.png new file mode 100644 index 0000000000000000000000000000000000000000..a52fbbe819e2fcbb1c1d5f8f143fc8d069688b3a GIT binary patch literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf<Z~8yL>4nJ zFmC{1M)f27Yk`76C9V-A!TD(=<%vb947rIV1v&X8IhjccWvNBQnfZANMtTN%MtTML z#U&<YM#g$6sbvP*>B&jPiK&SODM>mC86_nJR{Ht~oqG92>H6!I&RfjDz$oMC;uzx5 z`F6@iFJ?y(*Ymt}PEDaloIF?8a{Q9ydQ{(WW636gEnW(~S@jMA{|{;XY-~sp7Sx?) z(_PD*cq7Fqn~5u~VnhD4>hlKq<tb@7L0fy5{b&Bi=WuD_l4?(3&zVciJ)J$@uDE$d zY+8N-!;ML=n4)F~GJa8h=o+ia+|WE}f#C;+J#4SvA1KpuIKVog@`P-_=W^Z$mJM^% z<R`YvGH-YNapzYsgT;Cl4MwwuH~~B6vU(l{s{>n7%&t$}w@9Jpe7mLmAJ!PXuc{1r zO&`P;h<;ugBl>m0`&l<N(k8vv)AIa%VBvP-2N%yQGrWJz>*Y?r2IG3O2hD$$M@uho zwR_=Yy?RF7@zS@alxkN7wZ*W{x+i5|wE6s2##OJR_vU^TTHB|58yE`=p00i_>zopr E02Lj!oB#j- literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.svg new file mode 100644 index 00000000..484bdbcb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help.svg @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 43.283438 55.959375 +C 43.283438 55.12 42.603437 54.44 41.764063 54.44 +L 32.658437 54.44 +C 31.829687 54.44 31.139063 55.12 31.139063 55.959375 +L 31.139063 65.065 +C 31.139063 65.904375 31.829687 66.584375 32.658437 66.584375 +L 41.764063 66.584375 +C 42.603437 66.584375 43.283438 65.904375 43.283438 65.065 +z +M 55.279063 33.19 +C 55.279063 24.49875 46.173438 18.0175 38.045313 18.0175 +C 30.310312 18.0175 24.540937 21.31125 20.439687 28.11125 +C 20.025312 28.79125 20.174062 29.62 20.822187 30.119375 +L 27.048437 34.858125 +C 27.345937 35.049375 27.654062 35.16625 27.994062 35.16625 +C 28.408437 35.16625 28.865313 34.9325 29.173437 34.560625 +C 31.404688 31.745 32.318438 30.841875 33.232187 30.19375 +C 34.060937 29.62 35.622812 29.08875 37.333438 29.08875 +C 40.404062 29.08875 43.177188 30.990625 43.177188 33.115625 +C 43.177188 35.54875 41.955313 36.791875 39.033438 38.12 +C 35.697187 39.639375 31.139063 43.591875 31.139063 48.181875 +L 31.139063 49.8925 +C 31.139063 50.72125 31.670313 52.0175 32.509687 52.0175 +L 41.615313 52.0175 +C 42.486563 52.0175 43.134687 51.029375 43.134687 50.19 +C 43.134687 49.095625 44.537188 46.47125 46.779063 45.185625 +C 50.380938 43.166875 55.279063 40.404375 55.279063 33.19 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/help_large.png new file mode 100644 index 0000000000000000000000000000000000000000..3f3d4dfed7e99421bd024c14046bf4616b4ca2ff GIT binary patch literal 747 zcmV<H0u=p;P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PCQglUFbW?9;ba!ELWdLnqbZ~5MbZlv2 zAa-SPb7^mGATlm6E;24~Z*z1sHZn6VWMy_RD`#V3Ght<6Fl1sZAZT=Sa5^t9ZDDk9 zY;SaIX<{yKa%V5DrJkbz00J*bL_t(&f$f+vXcR#dhQF5>qZlEAow3ozPGS*Kh@=uh zt29YU!QR5c(o#^cu@D3i!6G7pMU;S|f`x@3Xc1C~VANnE8bvE}zs2r?guR>H+qXM8 z*dHDo`)=m{|CxC+vulzVWDLa?P!+9#*k}#JMr$B8S_84s8i<V@-W{6RBrpS<0H%TQ zlxG820~Ue1lGa@aCAkDJ3A_MQApQc&z^Tf-4#G!)o4{s4@mu2xFdW4IuoGD7Q~3Y! z9N62a0bm4p=pa6eNBzu16$95C#b<G`5d*+fg*D$Rz61NpXz6zwog#dOd?i_8Z%Jxp z1~{Gm?uKz-9=K6hNuM(?3|s~}<d5VcuqUV8QQ%XTHd#Dqqy|z!XMk^81Uv?YdbF7f z7+5Kzq0&`C(h_hCc%4341r{WAdNlhI=+??;sC<=>^wG?Y0}H@YNgIJCvw{4NvH}_j zl94@6cqh8lSPhgAKTEP3g~V?H2e*v@l5O#R0pVHPDa}!%`28eBT~z!tV02p;0Coef zN{GKl)0eq`feQtNuLE<HxM~nT0(>qY{x&dHmCyZ^5;y`J2>j=Xq_ZAmb-dJ%1@eD@ zb6#Y182BB?zmc@&MdrSQB)v1UtH7b0bO*TZ$!BTd4J_*TF0_kelqYi1*?s?(8=v<K znAtSRA=V8aBpvqRtD}fReY$cE{I}88Ky0)Ia_}pV|LI9q%Ry#lC+U6;yp;6bjcd?P d;<g52;~!CowO}ORTRZ>&002ovPDHLkV1l@aH3$Fz literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home-symbolic.svg new file mode 100644 index 00000000..3c4ccce3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home-symbolic.svg @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 57.860938 45.94 +C 57.860938 45.865625 57.860938 45.79125 57.818438 45.716875 +L 35.994687 27.72875 +L 14.181562 45.716875 +C 14.181562 45.79125 14.139062 45.865625 14.139062 45.94 +L 14.139062 64.15125 +C 14.139062 65.479375 15.244062 66.584375 16.572187 66.584375 +L 31.139063 66.584375 +L 31.139063 52.0175 +L 40.860938 52.0175 +L 40.860938 66.584375 +L 55.427813 66.584375 +C 56.755938 66.584375 57.860938 65.479375 57.860938 64.15125 +z +M 66.318438 43.32625 +C 66.732813 42.826875 66.658438 42.03 66.169688 41.615625 +L 57.860938 34.709375 +L 57.860938 19.22875 +C 57.860938 18.54875 57.329688 18.0175 56.639063 18.0175 +L 49.360938 18.0175 +C 48.670312 18.0175 48.139062 18.54875 48.139062 19.22875 +L 48.139062 26.62375 +L 38.884687 18.88875 +C 37.290937 17.560625 34.709063 17.560625 33.115313 18.88875 +L 5.830312 41.615625 +C 5.341562 42.03 5.267187 42.826875 5.681562 43.32625 +L 8.029687 46.13125 +C 8.220937 46.354375 8.529062 46.51375 8.826562 46.545625 +C 9.166562 46.588125 9.474687 46.47125 9.740312 46.28 +L 35.994687 24.3925 +L 62.259687 46.28 +C 62.482813 46.47125 62.748438 46.545625 63.056562 46.545625 +C 63.088437 46.545625 63.130938 46.545625 63.173438 46.545625 +C 63.470938 46.51375 63.779063 46.354375 63.970313 46.13125 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f9c6439b9b84bfdf40a2570d6971951b94977841 GIT binary patch literal 1737 zcmZuy3rtg27}g*fDnz3W=N93}f?$N+M;}l?C$tnxQA*1;vJS)T?F9<u-g0|jMYl|G zIwb*@1syVV*2fTWn$-k|E)%j0AyWyF02w;Bj7^;yHs*whb33OG0r95E?fLRQzw>|p zjW%es@sw09i9T}!v|Nx-fCPf2M3RyM2m@2ZIRT9jBOr3C92_9j3}oy=5m>)o!tqvY zm^jTL-32pDkbxYK`<%1_4}r}0-@rh~i9Ar?ql7Ss0&C(RFrz#gEsD>%ARu&QC}*1g zt@gilARiE>V#aFYi-6MSo|kPY;aCU~yuqi+p-2P-8c5}N0Xk6%<gZ4ha6CGxd;u~< zp~3-hn`#pvG+d>P<%}69H9F;r4DWO>BFD2;fzEyQC=s!Vv)Y(6!G+@DWC=9>p$rD> z00Vp(Ij2w|vWP&;&@%!tr_<QO#RRI=+U$rRKxplVK@G<WRz!Ff#}~n3K;e5aVn-(w zIi^hF`k|~|UpGvK?jBFtwYlS~i2+agj{Dn!*`x>HLE-jCk56u?JQTjMU~-}E-zU1J zk@1IP%_D95zW#N5;%QIxt+DSv9lZ7Wqrr1+y;c8hH2?8=4=Ek5+}pdZ;L>~9ci+nG z$oV<mW8QDRn5_$ar*9#bJ5--_>{@X6SoJ4F=<?3m)#ZP8-&`8ffBIPc!MQ;<O-$_O ztfz}7vdo=YSIf>TEMdPhd_6>6{nKgX$JL;%J!*SgScs!}<#+qKa(>ge+t2g|{TNx$ zY&ibc{3>(AljZAA=x?xZT<TvIy!4{x$k_-_w*0eUw)*sjtEE@&935y{c4g1-iad8- zo1)?O23@TDl~Z}PAa_{z#g@r$_w>wJo4sqnOY^pA=f&km=A2tz(6G4nE_Arpl?Nv+ zS#-W}YaAaF+JCsUq9f?#s7EmBz#aG1%bod6HO9x?Z@>1-hWUjhwM%yHci*?hch*d1 zh9z_~w<N{aTwB$8e)P774$mwdK62eL_pm<YwkPJJFaKG3yv8%2SApH0y86kHl^=F( zxlH%F;KPQr59(DX64MtAWoDl3_~LxKVL{hWV@Scq-qE8w4)oPoPK`Q~qmr$W$?|)_ z)QVSOY)<v2Lrp^`&-OhQtnNRFa%S~l`;n`ant^cco6v(1!7Z(g_ug!Mch&p)yM*b& z91B*Re**ma^G*gHAq6Q5Xc8;VKUGu8z>*A%S}Nt6{8WVbl|7|hf@KhlCq0!8m{Bh_ zqmbFOX~xo?l@|+k7Kmj#3&fiyP@!6=Kw3g+^)@S3uvgbcEHmFC^6jRn?x-2gNFvZC z@EW{|Vl_!LNhwJsNl~;+K_<kL@)(kgStB9T*iH~ZY#9R`b^+RL7C=cAQd(qbsY7r= zN+pv?tz0F!w#br@pkQca94Lm+kwg$vE>b}(Lc!2NvsSQ3z|*5StcAeBu%+m-)=VSH zC31xl5>PS;`RoBog+itPh2R-RA?ol0_y9&xN_34gF;bO?mcvYpB1y!@a~MU=wxj45 z*vZlS%=9HmCA!<^Fj?YkJDNn>?m0V^a&}&tp4JBx8JnFGz26)iUnl_YWuld76a+j2 e-t}p+ZRHSQm_#RJMChfElBp6U(b4JITFL+DnLv#I literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.png new file mode 100644 index 0000000000000000000000000000000000000000..6e5fdebb357c5fe4e87fa01756bfe33b40ac25f4 GIT binary patch literal 468 zcmV;_0W1EAP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET4c1c7*R7i>K)UivJQ4|L7-$^6IB{#>G znj(i*AxbjZYH!P-$Oiip8eAF*YP0?UA#{nB=9&VhYOWzEE!#}X)8G|u@2B7QS_%mr zIPl(cIM4IkbIyAsGaaNIIZ*Wf1c!?tA}&P4$B6hG5tpm@hlt3C*o=sYj>63B>9~On zWbq%EF1asN{7Oe{58ysLtN<QhraI4JwHra~_M=6_am?XjQGW~HFn~=w#<51()y!Pz z*&>|8yP|3t=W(}EdJkh*s$%V0gz>7cZ*T@r8$gL?IE}?BHr15?H>+VjFW`$ifM+FO z6!Yc$6L&fYY_02~s_;I};ZqmzZC@#Ks)zps{WZaG>E}8oaUI`VfN%Q-rf>~wrNtw^ zZBay=#bCMSOMhmUY^`lyX1>C%LvE|Q=^b0tzXx@*cu~H`aJx;>UI<=i<{U)C(Y6Ht z&TG1#1gn36_q7?=@v)1DQy6N5-)H7Z$q(a1BfplJZ(9-Ur~LxE8&S2c-0X$`0000< KMNUMnLSTaA*3XUr literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.svg new file mode 100644 index 00000000..3c4ccce3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home.svg @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 57.860938 45.94 +C 57.860938 45.865625 57.860938 45.79125 57.818438 45.716875 +L 35.994687 27.72875 +L 14.181562 45.716875 +C 14.181562 45.79125 14.139062 45.865625 14.139062 45.94 +L 14.139062 64.15125 +C 14.139062 65.479375 15.244062 66.584375 16.572187 66.584375 +L 31.139063 66.584375 +L 31.139063 52.0175 +L 40.860938 52.0175 +L 40.860938 66.584375 +L 55.427813 66.584375 +C 56.755938 66.584375 57.860938 65.479375 57.860938 64.15125 +z +M 66.318438 43.32625 +C 66.732813 42.826875 66.658438 42.03 66.169688 41.615625 +L 57.860938 34.709375 +L 57.860938 19.22875 +C 57.860938 18.54875 57.329688 18.0175 56.639063 18.0175 +L 49.360938 18.0175 +C 48.670312 18.0175 48.139062 18.54875 48.139062 19.22875 +L 48.139062 26.62375 +L 38.884687 18.88875 +C 37.290937 17.560625 34.709063 17.560625 33.115313 18.88875 +L 5.830312 41.615625 +C 5.341562 42.03 5.267187 42.826875 5.681562 43.32625 +L 8.029687 46.13125 +C 8.220937 46.354375 8.529062 46.51375 8.826562 46.545625 +C 9.166562 46.588125 9.474687 46.47125 9.740312 46.28 +L 35.994687 24.3925 +L 62.259687 46.28 +C 62.482813 46.47125 62.748438 46.545625 63.056562 46.545625 +C 63.088437 46.545625 63.130938 46.545625 63.173438 46.545625 +C 63.470938 46.51375 63.779063 46.354375 63.970313 46.13125 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/home_large.png new file mode 100644 index 0000000000000000000000000000000000000000..3357bfeb9011141ebce16febf6539f610f12ecc9 GIT binary patch literal 790 zcmV+x1L^#UP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PExJg7oRA_<im^)|`Q51&16N4Bv_=@;| z2tiB=6?}lAg``jrHXxW(TG<(}5Fb?(EEMc)1S?|~!GMSs!A3+AC5WWaCWwL&gDCh6 zKC{PS?&><ZclNq_cPAn9!+~M$KXd+n=KMP|E2_#&MqSzhDn(`>ZDa=0MrI&wWCqek zW*}`;#ej%3iO3BR`DUtLM3y+XgCe4_niP?4uV$(mw1D-%b3kJ?3bb1I?<`yeF8K5d zdIv-#2RsB?EX(VFVG-FKvS%;@B61wK2{b0q76Sv`<Kcq<BQqDcjC~CHfa{L6i@+Qz z9HC0ZHv#u7&GSHy;RtZfA@VlxF%<*2!#V-%H=K<?o7p}He07MetpOkhe6lnh12!AZ zKHxL(0oZHyZ3o6vH2|CdCM^wzft7~SW5%ek_6s;>)|!Elnj0VrYp<hOA21JSFxxIs zz2-a%aECj*0bn_B-_j%xoHCr%z$1?<I|QsCIo#n402_c8mIf0*r{Qb^UVF~A0xyA0 z=GX(+!~G1)ll#9603Eo)x~0rtm*NZ1RU+K)fjwmz08Zi#>nftB`1vw~$4Bst87Eh` ze*#Cm4G@LwilgCGqOdjsw<;80T>Zd&lEZxos82KiECmJ~SL(Fkv;a>6iZ9d%u*Tet zvkuN3U{R8RPRl{Xv)YdP-6cf50d|%McSn+eI-)nq0{Inx!+IF_QAP2E`VJg&g!>vG zr82M(c#H|F*>|)C!sFF#dN&v8X^88sCk9ph0&I=#Zj1A3fK~ui9b>AVKgd4n)5eq$ z3V^pnA2~L(1It1-tA>H6s@i2+5RnJKj*!h}{0L<R(ne+=ZOj@2T2&Qx<b6oK2JTW@ z6M5VZ!+#*=jjuFOWEZfO=z}8(<ElE~I7g1?ABiL=FsiCUUb=h@OjpdB5KmkD1_wzH UrJnNuK>z>%07*qoM6N<$f|>C}$p8QV literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6c44566ad819ba31e93bf50d3b7c2b9fa1bb8f64 GIT binary patch literal 22852 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.png new file mode 100644 index 0000000000000000000000000000000000000000..8eedfa7cc8fc7d68be0e1781421f845ef4f54db0 GIT binary patch literal 1283 zcmV+e1^oJnP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET7rAb6VR7i=HR&8ukWfXqyY*#v9TUT5L zDEPtD5wL4(jBKsAR>KUMsYHnhAA*w2*)Hms87jo^amzGnL<1Y!95F*iMi>j-)=YZ^ z*NzP67Y599ForTl(r#T{SGux${2^Ofc3Z=fyve<J&v~Alyyrd7%McL~fngY_R;zt3 zH#b)$m&-E%z~}P~yWMVQS6A05A_^tUk0+qh>6CiCzC@)`6|PvZVo`c}ddz+x5I}c# z_ce#ZVX<1R)f~sU1c`_!W&sczjYgBp<?^03AEU+(U!iS<k5MQTqIht--Cl#izyc7@ z;EVo|$z*d`mbDCA>7$y`)pU7%GEoWW+B#5IXIoqWBBF3OOf1V<WHQ-YK>+|_mSrtG z&r?Iy$8>WeLsWw4b>#DpVhFDe^v$S>=Xo-jOdZjcObZx|MpHN(o(??l{_AvWOO!x) zQ4E=>x`@8|@mVr=9-2{!!C+ux1PTfYly0}%8yy%LAE)ZgTH=fE2&~T`p67{(=yHEA zHT=4ay2l@<FAi)GJd=Wg0wob42>|qZeThP$kVhZ>EU6SlI}hXN_)-8scBCJDy}tth zezrGYdH!vj`XL*}P2bLF9ECz5*XeY{0FcBmOo~dSDg=Oz6Sb(_t%0Sr9z4$@YvF@f z`d&4-u?0}1-h$_slOQ4laUS;L^RVuveUL~bg59ZBs|y*1k>01(YM-yHtSpsCBsl*Q zi;a1mm=ijQmR1X{-3TF1_bU2%IYO5>+)TP3K1nkE9&5of5ADISoTmiI0U$FoGu>vh z*+jXyxvJFEQ~*Fy_zwU;mYlFb(}Uqa51PI_gp>!?;>OZaj9jqdqCJe9>`lmfdR1I< z07y$qgHowfi>9uBBocv`d@(^8slYmo6M>);=E3D?>Aj9CX9lrY@i2~?cj4Ig+Y^e& z<?;-X&_?7o(EFDNy+aFdTeJwl$@w_k<HbN^49vto*ioE^oF|nD$)_Ol`Fz6wAQp=; zFrJU27c(K6{Ro~==#lqA7QVK$pwrxj9fob_8**a88${#Y3T!U_3=0>oO-SzZ`G%p@ zYF`{39TmL(o7nBNaeoyJ`$vd~sN%?0+SRm^&UCiY!I$S#<K7CIoSYQQ_51y#(P#<* zK-%8kJ|Gk{b+L$uB9REa)BHAVZ7L@sqUL=&>9;q<wEx}JH0<@x$Zc<LzY0K_L_{H{ z(`gYZkzttW?{l7Wn5B>)fKd<;))+p8ef}D}6={R{1062(bj9R491aT+g^~ckYPD8- zJf7GVx(jFjJd5-tX`lr>t`A-Z!!X#es~(M$d00RD0!F@j1LlTr00173$H#G84S@ef z1;=r&`uh6XiHV800;+5kWX<#N=+$f_OOgQq(v%de`lJCT#+G2^oFVkL)xhufqpq&* z;Isjez_`9w*gION>b2!`$$6GombE}=T+<!HF_}yqQ)ByH5DW$r8%}g3Wo2c1?jGNX z;C8#cMx${z1S~V5>Fad5VzpXbn4h1&cxqlvArJ__ZnqCO91aV|aW(NwKd!)Z0K-T% t8qG?jQmKx9wzym_hs|a?P5<+3`4^p@EBvCxN5=pF002ovPDHLkV1lx`QPKba literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.svg new file mode 100644 index 00000000..95d1b612 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib.svg @@ -0,0 +1,3171 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="axes_1"> + <g id="patch_2"> + <path d="M 36 70.2 +C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052 +C 66.596472 53.769632 70.2 45.069946 70.2 36 +C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948 +C 53.769632 5.403528 45.069946 1.8 36 1.8 +C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948 +C 5.403528 18.230368 1.8 26.930054 1.8 36 +C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052 +C 18.230368 66.596472 26.930054 70.2 36 70.2 +z +" style="fill:#ffffff;"/> + </g> + <g id="matplotlib.axis_1"> + <g id="xtick_1"> + <g id="line2d_1"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 70.2 36 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_2"> + <g id="line2d_2"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 60.183052 11.816948 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_3"> + <g id="line2d_3"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 1.8 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_4"> + <g id="line2d_4"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 11.816948 11.816948 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_5"> + <g id="line2d_5"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 1.8 36 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_6"> + <g id="line2d_6"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 11.816948 60.183052 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_7"> + <g id="line2d_7"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 70.2 +" style="fill:none;"/> + </g> + </g> + <g id="xtick_8"> + <g id="line2d_8"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 60.183052 60.183052 +" style="fill:none;"/> + </g> + </g> + </g> + <g id="matplotlib.axis_2"> + <g id="ytick_1"> + <g id="line2d_9"> + <path clip-path="url(#p2b9aa5bb59)" d="M 39.8 36 +L 39.687124 35.080697 +L 39.355201 34.216008 +L 38.82395 33.457304 +L 38.124933 32.849657 +L 37.299677 32.429168 +L 36.397208 32.220817 +L 35.471142 32.236981 +L 34.576495 32.476701 +L 33.766416 32.925735 +L 33.089031 33.557407 +L 32.584583 34.33419 +L 32.283039 35.209936 +L 32.202315 36.132618 +L 32.347206 37.047422 +L 32.709103 37.9 +L 33.266509 38.639702 +L 33.986307 39.222583 +L 34.825735 39.614015 +L 35.734925 39.790743 +L 36.659863 39.742269 +L 37.545599 39.471473 +L 38.339514 38.994441 +L 38.994441 38.339514 +L 39.471473 37.545599 +L 39.742269 36.659863 +L 39.8 36 +L 39.8 36 +" style="fill:none;"/> + </g> + </g> + <g id="ytick_2"> + <g id="line2d_10"> + <path clip-path="url(#p2b9aa5bb59)" d="M 47.4 36 +L 47.289056 34.413427 +L 46.958383 32.857734 +L 46.414418 31.363202 +L 45.667748 29.95892 +L 44.732907 28.672221 +L 43.628089 27.528149 +L 42.374799 26.548972 +L 40.997431 25.753748 +L 39.522794 25.157956 +L 37.979589 24.773192 +L 36.397854 24.606945 +L 34.808376 24.66245 +L 33.24209 24.938629 +L 31.729485 25.430104 +L 30.3 26.12731 +L 28.981459 27.016677 +L 27.799526 28.080895 +L 26.777206 29.299248 +L 25.934397 30.648024 +L 25.287504 32.10097 +L 24.849117 33.629807 +L 24.62777 35.204776 +L 24.62777 36.795224 +L 24.849117 38.370193 +L 25.287504 39.89903 +L 25.934397 41.351976 +L 26.777206 42.700752 +L 27.799526 43.919105 +L 28.981459 44.983323 +L 30.3 45.87269 +L 31.729485 46.569896 +L 33.24209 47.061371 +L 34.808376 47.33755 +L 36.397854 47.393055 +L 37.979589 47.226808 +L 39.522794 46.842044 +L 40.997431 46.246252 +L 42.374799 45.451028 +L 43.628089 44.471851 +L 44.732907 43.327779 +L 45.667748 42.04108 +L 46.414418 40.636798 +L 46.958383 39.142266 +L 47.289056 37.586573 +L 47.4 36 +L 47.4 36 +" style="fill:none;"/> + </g> + </g> + <g id="ytick_3"> + <g id="line2d_11"> + <path clip-path="url(#p2b9aa5bb59)" d="M 55 36 +L 54.895916 34.013959 +L 54.584804 32.049678 +L 54.070074 30.128677 +L 53.357364 28.272004 +L 52.454483 26.5 +L 51.371323 24.83208 +L 50.119752 23.286518 +L 48.713482 21.880248 +L 47.16792 20.628677 +L 45.5 19.545517 +L 43.727996 18.642636 +L 41.871323 17.929926 +L 39.950322 17.415196 +L 37.986041 17.104084 +L 36 17 +L 34.013959 17.104084 +L 32.049678 17.415196 +L 30.128677 17.929926 +L 28.272004 18.642636 +L 26.5 19.545517 +L 24.83208 20.628677 +L 23.286518 21.880248 +L 21.880248 23.286518 +L 20.628677 24.83208 +L 19.545517 26.5 +L 18.642636 28.272004 +L 17.929926 30.128677 +L 17.415196 32.049678 +L 17.104084 34.013959 +L 17 36 +L 17.104084 37.986041 +L 17.415196 39.950322 +L 17.929926 41.871323 +L 18.642636 43.727996 +L 19.545517 45.5 +L 20.628677 47.16792 +L 21.880248 48.713482 +L 23.286518 50.119752 +L 24.83208 51.371323 +L 26.5 52.454483 +L 28.272004 53.357364 +L 30.128677 54.070074 +L 32.049678 54.584804 +L 34.013959 54.895916 +L 36 55 +L 37.986041 54.895916 +L 39.950322 54.584804 +L 41.871323 54.070074 +L 43.727996 53.357364 +L 45.5 52.454483 +L 47.16792 51.371323 +L 48.713482 50.119752 +L 50.119752 48.713482 +L 51.371323 47.16792 +L 52.454483 45.5 +L 53.357364 43.727996 +L 54.070074 41.871323 +L 54.584804 39.950322 +L 54.895916 37.986041 +L 55 36 +L 55 36 +" style="fill:none;"/> + </g> + </g> + <g id="ytick_4"> + <g id="line2d_12"> + <path clip-path="url(#p2b9aa5bb59)" d="M 62.6 36 +L 62.454282 33.219543 +L 62.018726 30.469549 +L 61.298103 27.780148 +L 60.300309 25.180805 +L 59.036276 22.7 +L 57.519852 20.364912 +L 55.767652 18.201126 +L 53.798874 16.232348 +L 51.635088 14.480148 +L 49.3 12.963724 +L 46.819195 11.699691 +L 44.219852 10.701897 +L 41.530451 9.981274 +L 38.780457 9.545718 +L 36 9.4 +L 33.219543 9.545718 +L 30.469549 9.981274 +L 27.780148 10.701897 +L 25.180805 11.699691 +L 22.7 12.963724 +L 20.364912 14.480148 +L 18.201126 16.232348 +L 16.232348 18.201126 +L 14.480148 20.364912 +L 12.963724 22.7 +L 11.699691 25.180805 +L 10.701897 27.780148 +L 9.981274 30.469549 +L 9.545718 33.219543 +L 9.4 36 +L 9.545718 38.780457 +L 9.981274 41.530451 +L 10.701897 44.219852 +L 11.699691 46.819195 +L 12.963724 49.3 +L 14.480148 51.635088 +L 16.232348 53.798874 +L 18.201126 55.767652 +L 20.364912 57.519852 +L 22.7 59.036276 +L 25.180805 60.300309 +L 27.780148 61.298103 +L 30.469549 62.018726 +L 33.219543 62.454282 +L 36 62.6 +L 38.780457 62.454282 +L 41.530451 62.018726 +L 44.219852 61.298103 +L 46.819195 60.300309 +L 49.3 59.036276 +L 51.635088 57.519852 +L 53.798874 55.767652 +L 55.767652 53.798874 +L 57.519852 51.635088 +L 59.036276 49.3 +L 60.300309 46.819195 +L 61.298103 44.219852 +L 62.018726 41.530451 +L 62.454282 38.780457 +L 62.6 36 +L 62.6 36 +" style="fill:none;"/> + </g> + </g> + </g> + <g id="patch_3"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36.07228 35.976515 +L 36.144561 35.953029 +L 36.216841 35.929544 +L 36.289121 35.906059 +L 36.361401 35.882574 +L 36.433682 35.859088 +L 36.505962 35.835603 +L 36.578242 35.812118 +L 36.650523 35.788632 +L 36.722803 35.765147 +L 36.795083 35.741662 +L 36.867364 35.718177 +L 36.939644 35.694691 +L 37.011924 35.671206 +L 37.084204 35.647721 +L 37.156485 35.624235 +L 37.228765 35.60075 +L 37.301045 35.577265 +L 37.373326 35.553779 +L 37.445606 35.530294 +L 37.517886 35.506809 +L 37.590166 35.483324 +L 37.662447 35.459838 +L 37.734727 35.436353 +L 37.807007 35.412868 +L 37.879288 35.389382 +L 37.951568 35.365897 +L 38.023848 35.342412 +L 38.096129 35.318927 +L 38.168409 35.295441 +L 38.240689 35.271956 +L 38.312969 35.248471 +L 38.38525 35.224985 +L 38.45753 35.2015 +L 38.52981 35.178015 +L 38.602091 35.15453 +L 38.674371 35.131044 +L 38.746651 35.107559 +L 38.818932 35.084074 +L 38.891212 35.060588 +L 38.963492 35.037103 +L 39.035772 35.013618 +L 39.108053 34.990132 +L 39.180333 34.966647 +L 39.252613 34.943162 +L 39.324894 34.919677 +L 39.397174 34.896191 +L 39.469454 34.872706 +L 39.541734 34.849221 +L 39.614015 34.825735 +L 39.686295 34.80225 +L 39.758575 34.778765 +L 39.830856 34.75528 +L 39.903136 34.731794 +L 39.975416 34.708309 +L 40.047697 34.684824 +L 40.119977 34.661338 +L 40.192257 34.637853 +L 40.264537 34.614368 +L 40.336818 34.590883 +L 40.409098 34.567397 +L 40.481378 34.543912 +L 40.553659 34.520427 +L 40.625939 34.496941 +L 40.698219 34.473456 +L 40.770499 34.449971 +L 40.84278 34.426485 +L 40.91506 34.403 +L 40.98734 34.379515 +L 41.059621 34.35603 +L 41.131901 34.332544 +L 41.204181 34.309059 +L 41.276462 34.285574 +L 41.348742 34.262088 +L 41.421022 34.238603 +L 41.493302 34.215118 +L 41.565583 34.191633 +L 41.637863 34.168147 +L 41.710143 34.144662 +L 41.782424 34.121177 +L 41.854704 34.097691 +L 41.926984 34.074206 +L 41.999265 34.050721 +L 42.071545 34.027236 +L 42.143825 34.00375 +L 42.216105 33.980265 +L 42.288386 33.95678 +L 42.360666 33.933294 +L 42.432946 33.909809 +L 42.505227 33.886324 +L 42.577507 33.862838 +L 42.649787 33.839353 +L 42.722067 33.815868 +L 42.794348 33.792383 +L 42.866628 33.768897 +L 42.938908 33.745412 +L 43.011189 33.721927 +L 43.083469 33.698441 +L 43.155749 33.674956 +L 43.22803 33.651471 +L 43.235372 33.67419 +L 43.242643 33.696932 +L 43.249843 33.719697 +L 43.256971 33.742484 +L 43.264027 33.765294 +L 43.271012 33.788125 +L 43.277925 33.810979 +L 43.284766 33.833854 +L 43.291535 33.85675 +L 43.298232 33.879668 +L 43.304857 33.902606 +L 43.31141 33.925565 +L 43.317891 33.948545 +L 43.3243 33.971545 +L 43.330636 33.994565 +L 43.3369 34.017605 +L 43.343092 34.040664 +L 43.349211 34.063742 +L 43.355258 34.08684 +L 43.361232 34.109957 +L 43.367133 34.133092 +L 43.372962 34.156246 +L 43.378718 34.179418 +L 43.384401 34.202608 +L 43.390011 34.225815 +L 43.395549 34.24904 +L 43.401013 34.272283 +L 43.406404 34.295542 +L 43.411722 34.318818 +L 43.416967 34.342111 +L 43.422139 34.365421 +L 43.427238 34.388746 +L 43.432263 34.412087 +L 43.437215 34.435444 +L 43.442093 34.458817 +L 43.446898 34.482204 +L 43.45163 34.505607 +L 43.456288 34.529024 +L 43.460872 34.552456 +L 43.465383 34.575902 +L 43.46982 34.599362 +L 43.474184 34.622836 +L 43.478473 34.646324 +L 43.482689 34.669825 +L 43.486831 34.693339 +L 43.490899 34.716866 +L 43.494893 34.740405 +L 43.498813 34.763958 +L 43.502659 34.787522 +L 43.506431 34.811098 +L 43.510129 34.834686 +L 43.513753 34.858286 +L 43.517303 34.881896 +L 43.520779 34.905518 +L 43.52418 34.929151 +L 43.527507 34.952794 +L 43.53076 34.976447 +L 43.533938 35.000111 +L 43.537042 35.023784 +L 43.540072 35.047467 +L 43.543027 35.07116 +L 43.545908 35.094862 +L 43.548714 35.118572 +L 43.551446 35.142291 +L 43.554103 35.166019 +L 43.556686 35.189755 +L 43.559194 35.213499 +L 43.561628 35.237251 +L 43.563987 35.26101 +L 43.566271 35.284777 +L 43.568481 35.30855 +L 43.570615 35.332331 +L 43.572676 35.356118 +L 43.574661 35.379911 +L 43.576572 35.403711 +L 43.578408 35.427516 +L 43.580169 35.451327 +L 43.581855 35.475144 +L 43.583467 35.498965 +L 43.585003 35.522792 +L 43.586465 35.546623 +L 43.587852 35.570459 +L 43.589164 35.594299 +L 43.590401 35.618143 +L 43.591563 35.641991 +L 43.59265 35.665842 +L 43.593663 35.689697 +L 43.5946 35.713555 +L 43.595462 35.737415 +L 43.59625 35.761278 +L 43.596962 35.785144 +L 43.5976 35.809011 +L 43.598162 35.832881 +L 43.59865 35.856752 +L 43.599062 35.880624 +L 43.5994 35.904498 +L 43.599662 35.928373 +L 43.59985 35.952248 +L 43.599962 35.976124 +L 43.6 36 +L 43.524 36 +L 43.448 36 +L 43.372 36 +L 43.296 36 +L 43.22 36 +L 43.144 36 +L 43.068 36 +L 42.992 36 +L 42.916 36 +L 42.84 36 +L 42.764 36 +L 42.688 36 +L 42.612 36 +L 42.536 36 +L 42.46 36 +L 42.384 36 +L 42.308 36 +L 42.232 36 +L 42.156 36 +L 42.08 36 +L 42.004 36 +L 41.928 36 +L 41.852 36 +L 41.776 36 +L 41.7 36 +L 41.624 36 +L 41.548 36 +L 41.472 36 +L 41.396 36 +L 41.32 36 +L 41.244 36 +L 41.168 36 +L 41.092 36 +L 41.016 36 +L 40.94 36 +L 40.864 36 +L 40.788 36 +L 40.712 36 +L 40.636 36 +L 40.56 36 +L 40.484 36 +L 40.408 36 +L 40.332 36 +L 40.256 36 +L 40.18 36 +L 40.104 36 +L 40.028 36 +L 39.952 36 +L 39.876 36 +L 39.8 36 +L 39.724 36 +L 39.648 36 +L 39.572 36 +L 39.496 36 +L 39.42 36 +L 39.344 36 +L 39.268 36 +L 39.192 36 +L 39.116 36 +L 39.04 36 +L 38.964 36 +L 38.888 36 +L 38.812 36 +L 38.736 36 +L 38.66 36 +L 38.584 36 +L 38.508 36 +L 38.432 36 +L 38.356 36 +L 38.28 36 +L 38.204 36 +L 38.128 36 +L 38.052 36 +L 37.976 36 +L 37.9 36 +L 37.824 36 +L 37.748 36 +L 37.672 36 +L 37.596 36 +L 37.52 36 +L 37.444 36 +L 37.368 36 +L 37.292 36 +L 37.216 36 +L 37.14 36 +L 37.064 36 +L 36.988 36 +L 36.912 36 +L 36.836 36 +L 36.76 36 +L 36.684 36 +L 36.608 36 +L 36.532 36 +L 36.456 36 +L 36.38 36 +L 36.304 36 +L 36.228 36 +L 36.152 36 +L 36.076 36 +z +" style="fill:#004cff;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_4"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36.080113 35.786538 +L 36.160227 35.573077 +L 36.24034 35.359615 +L 36.320454 35.146154 +L 36.400567 34.932692 +L 36.480681 34.719231 +L 36.560794 34.505769 +L 36.640908 34.292308 +L 36.721021 34.078846 +L 36.801135 33.865384 +L 36.881248 33.651923 +L 36.961362 33.438461 +L 37.041475 33.225 +L 37.121588 33.011538 +L 37.201702 32.798077 +L 37.281815 32.584615 +L 37.361929 32.371154 +L 37.442042 32.157692 +L 37.522156 31.944231 +L 37.602269 31.730769 +L 37.682383 31.517307 +L 37.762496 31.303846 +L 37.84261 31.090384 +L 37.922723 30.876923 +L 38.002836 30.663461 +L 38.08295 30.45 +L 38.163063 30.236538 +L 38.243177 30.023077 +L 38.32329 29.809615 +L 38.403404 29.596153 +L 38.483517 29.382692 +L 38.563631 29.16923 +L 38.643744 28.955769 +L 38.723858 28.742307 +L 38.803971 28.528846 +L 38.884085 28.315384 +L 38.964198 28.101923 +L 39.044311 27.888461 +L 39.124425 27.675 +L 39.204538 27.461538 +L 39.284652 27.248076 +L 39.364765 27.034615 +L 39.444879 26.821153 +L 39.524992 26.607692 +L 39.605106 26.39423 +L 39.685219 26.180769 +L 39.765333 25.967307 +L 39.845446 25.753846 +L 39.92556 25.540384 +L 40.005673 25.326922 +L 40.085786 25.113461 +L 40.1659 24.899999 +L 40.246013 24.686538 +L 40.326127 24.473076 +L 40.40624 24.259615 +L 40.486354 24.046153 +L 40.566467 23.832692 +L 40.646581 23.61923 +L 40.726694 23.405769 +L 40.806808 23.192307 +L 40.886921 22.978845 +L 40.967035 22.765384 +L 41.047148 22.551922 +L 41.127261 22.338461 +L 41.207375 22.124999 +L 41.287488 21.911538 +L 41.367602 21.698076 +L 41.447715 21.484615 +L 41.527829 21.271153 +L 41.607942 21.057691 +L 41.688056 20.84423 +L 41.768169 20.630768 +L 41.848283 20.417307 +L 41.928396 20.203845 +L 42.008509 19.990384 +L 42.088623 19.776922 +L 42.168736 19.563461 +L 42.24885 19.349999 +L 42.328963 19.136538 +L 42.409077 18.923076 +L 42.48919 18.709614 +L 42.569304 18.496153 +L 42.649417 18.282691 +L 42.729531 18.06923 +L 42.809644 17.855768 +L 42.889758 17.642307 +L 42.969871 17.428845 +L 43.049984 17.215384 +L 43.130098 17.001922 +L 43.210211 16.78846 +L 43.290325 16.574999 +L 43.370438 16.361537 +L 43.450552 16.148076 +L 43.530665 15.934614 +L 43.610779 15.721153 +L 43.690892 15.507691 +L 43.771006 15.29423 +L 43.851119 15.080768 +L 43.931233 14.867306 +L 44.011346 14.653845 +L 44.078367 14.679119 +L 44.145309 14.704603 +L 44.21217 14.730297 +L 44.27895 14.756201 +L 44.345648 14.782315 +L 44.412265 14.808638 +L 44.478798 14.835171 +L 44.545247 14.861912 +L 44.611612 14.888862 +L 44.677892 14.91602 +L 44.744086 14.943387 +L 44.810194 14.970961 +L 44.876215 14.998743 +L 44.942149 15.026732 +L 45.007994 15.054928 +L 45.07375 15.083331 +L 45.139417 15.11194 +L 45.204994 15.140755 +L 45.270479 15.169776 +L 45.335874 15.199003 +L 45.401176 15.228435 +L 45.466385 15.258073 +L 45.531501 15.287914 +L 45.596523 15.317961 +L 45.66145 15.348211 +L 45.726281 15.378665 +L 45.791017 15.409323 +L 45.855656 15.440184 +L 45.920198 15.471248 +L 45.984642 15.502514 +L 46.048987 15.533983 +L 46.113234 15.565654 +L 46.17738 15.597526 +L 46.241426 15.6296 +L 46.305371 15.661875 +L 46.369214 15.69435 +L 46.432955 15.727026 +L 46.496593 15.759903 +L 46.560127 15.792978 +L 46.623557 15.826254 +L 46.686882 15.859728 +L 46.750102 15.893401 +L 46.813215 15.927273 +L 46.876222 15.961343 +L 46.939122 15.99561 +L 47.001913 16.030075 +L 47.064596 16.064737 +L 47.12717 16.099596 +L 47.189634 16.134651 +L 47.251987 16.169902 +L 47.31423 16.205349 +L 47.376361 16.240991 +L 47.438379 16.276829 +L 47.500285 16.312861 +L 47.562077 16.349087 +L 47.623755 16.385507 +L 47.685318 16.422121 +L 47.746766 16.458928 +L 47.808098 16.495928 +L 47.869314 16.533121 +L 47.930412 16.570505 +L 47.991393 16.608081 +L 48.052255 16.645849 +L 48.112998 16.683808 +L 48.173622 16.721957 +L 48.234125 16.760297 +L 48.294508 16.798826 +L 48.35477 16.837545 +L 48.414909 16.876454 +L 48.474926 16.91555 +L 48.53482 16.954836 +L 48.59459 16.994309 +L 48.654236 17.03397 +L 48.713757 17.073818 +L 48.773153 17.113852 +L 48.832422 17.154074 +L 48.891565 17.194481 +L 48.950581 17.235074 +L 49.009468 17.275852 +L 49.068228 17.316814 +L 49.126858 17.357962 +L 49.185359 17.399293 +L 49.24373 17.440807 +L 49.30197 17.482505 +L 49.360078 17.524386 +L 49.418055 17.566449 +L 49.475899 17.608694 +L 49.533611 17.651121 +L 49.591189 17.693728 +L 49.648632 17.736516 +L 49.705941 17.779485 +L 49.763115 17.822633 +L 49.820153 17.865961 +L 49.877054 17.909468 +L 49.933819 17.953153 +L 49.990446 17.997016 +L 50.046935 18.041057 +L 50.103285 18.085276 +L 50.159496 18.129671 +L 50.215567 18.174242 +L 50.073412 18.3525 +L 49.931256 18.530757 +L 49.7891 18.709015 +L 49.646945 18.887273 +L 49.504789 19.06553 +L 49.362633 19.243788 +L 49.220478 19.422045 +L 49.078322 19.600303 +L 48.936166 19.77856 +L 48.794011 19.956818 +L 48.651855 20.135076 +L 48.509699 20.313333 +L 48.367544 20.491591 +L 48.225388 20.669848 +L 48.083232 20.848106 +L 47.941077 21.026363 +L 47.798921 21.204621 +L 47.656765 21.382879 +L 47.51461 21.561136 +L 47.372454 21.739394 +L 47.230298 21.917651 +L 47.088143 22.095909 +L 46.945987 22.274166 +L 46.803831 22.452424 +L 46.661676 22.630682 +L 46.51952 22.808939 +L 46.377364 22.987197 +L 46.235209 23.165454 +L 46.093053 23.343712 +L 45.950897 23.52197 +L 45.808742 23.700227 +L 45.666586 23.878485 +L 45.52443 24.056742 +L 45.382275 24.235 +L 45.240119 24.413257 +L 45.097963 24.591515 +L 44.955808 24.769773 +L 44.813652 24.94803 +L 44.671496 25.126288 +L 44.52934 25.304545 +L 44.387185 25.482803 +L 44.245029 25.66106 +L 44.102873 25.839318 +L 43.960718 26.017576 +L 43.818562 26.195833 +L 43.676406 26.374091 +L 43.534251 26.552348 +L 43.392095 26.730606 +L 43.249939 26.908864 +L 43.107784 27.087121 +L 42.965628 27.265379 +L 42.823472 27.443636 +L 42.681317 27.621894 +L 42.539161 27.800151 +L 42.397005 27.978409 +L 42.25485 28.156667 +L 42.112694 28.334924 +L 41.970538 28.513182 +L 41.828383 28.691439 +L 41.686227 28.869697 +L 41.544071 29.047954 +L 41.401916 29.226212 +L 41.25976 29.40447 +L 41.117604 29.582727 +L 40.975449 29.760985 +L 40.833293 29.939242 +L 40.691137 30.1175 +L 40.548982 30.295758 +L 40.406826 30.474015 +L 40.26467 30.652273 +L 40.122515 30.83053 +L 39.980359 31.008788 +L 39.838203 31.187045 +L 39.696048 31.365303 +L 39.553892 31.543561 +L 39.411736 31.721818 +L 39.269581 31.900076 +L 39.127425 32.078333 +L 38.985269 32.256591 +L 38.843113 32.434848 +L 38.700958 32.613106 +L 38.558802 32.791364 +L 38.416646 32.969621 +L 38.274491 33.147879 +L 38.132335 33.326136 +L 37.990179 33.504394 +L 37.848024 33.682651 +L 37.705868 33.860909 +L 37.563712 34.039167 +L 37.421557 34.217424 +L 37.279401 34.395682 +L 37.137245 34.573939 +L 36.99509 34.752197 +L 36.852934 34.930455 +L 36.710778 35.108712 +L 36.568623 35.28697 +L 36.426467 35.465227 +L 36.284311 35.643485 +L 36.142156 35.821742 +z +" style="fill:#ceff29;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_5"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 35.805174 35.766636 +L 35.610348 35.533272 +L 35.415521 35.299908 +L 35.220695 35.066544 +L 35.025869 34.83318 +L 34.831043 34.599816 +L 34.636217 34.366452 +L 34.441391 34.133088 +L 34.246564 33.899724 +L 34.051738 33.66636 +L 33.856912 33.432996 +L 33.662086 33.199632 +L 33.46726 32.966268 +L 33.272433 32.732904 +L 33.077607 32.49954 +L 32.882781 32.266176 +L 32.687955 32.032812 +L 32.493129 31.799448 +L 32.298302 31.566084 +L 32.103476 31.33272 +L 31.90865 31.099356 +L 31.713824 30.865992 +L 31.518998 30.632628 +L 31.324172 30.399264 +L 31.129345 30.1659 +L 30.934519 29.932536 +L 30.739693 29.699172 +L 30.544867 29.465808 +L 30.350041 29.232444 +L 30.155214 28.99908 +L 29.960388 28.765716 +L 29.765562 28.532352 +L 29.570736 28.298988 +L 29.37591 28.065624 +L 29.181083 27.83226 +L 28.986257 27.598896 +L 28.791431 27.365532 +L 28.596605 27.132168 +L 28.401779 26.898804 +L 28.206953 26.66544 +L 28.012126 26.432076 +L 27.8173 26.198712 +L 27.622474 25.965348 +L 27.427648 25.731984 +L 27.232822 25.49862 +L 27.037995 25.265256 +L 26.843169 25.031892 +L 26.648343 24.798528 +L 26.453517 24.565164 +L 26.258691 24.3318 +L 26.063864 24.098436 +L 25.869038 23.865072 +L 25.674212 23.631708 +L 25.479386 23.398344 +L 25.28456 23.16498 +L 25.089734 22.931616 +L 24.894907 22.698252 +L 24.700081 22.464888 +L 24.505255 22.231524 +L 24.310429 21.99816 +L 24.115603 21.764796 +L 23.920776 21.531432 +L 23.72595 21.298068 +L 23.531124 21.064704 +L 23.336298 20.83134 +L 23.141472 20.597976 +L 22.946645 20.364612 +L 22.751819 20.131248 +L 22.556993 19.897884 +L 22.362167 19.66452 +L 22.167341 19.431156 +L 21.972515 19.197792 +L 21.777688 18.964428 +L 21.582862 18.731064 +L 21.388036 18.4977 +L 21.19321 18.264336 +L 20.998384 18.030972 +L 20.803557 17.797608 +L 20.608731 17.564244 +L 20.413905 17.33088 +L 20.219079 17.097516 +L 20.024253 16.864152 +L 19.829427 16.630788 +L 19.6346 16.397424 +L 19.439774 16.16406 +L 19.244948 15.930696 +L 19.050122 15.697332 +L 18.855296 15.463968 +L 18.660469 15.230604 +L 18.465643 14.99724 +L 18.270817 14.763876 +L 18.075991 14.530512 +L 17.881165 14.297148 +L 17.686338 14.063784 +L 17.491512 13.83042 +L 17.296686 13.597056 +L 17.10186 13.363692 +L 16.907034 13.130328 +L 16.712208 12.896964 +L 16.517381 12.6636 +L 16.627567 12.57205 +L 16.738184 12.48102 +L 16.849228 12.390512 +L 16.960697 12.300529 +L 17.072589 12.211071 +L 17.184902 12.122143 +L 17.297632 12.033744 +L 17.410777 11.945878 +L 17.524336 11.858545 +L 17.638304 11.771749 +L 17.752681 11.685491 +L 17.867462 11.599773 +L 17.982647 11.514597 +L 18.098231 11.429964 +L 18.214213 11.345877 +L 18.33059 11.262338 +L 18.447359 11.179347 +L 18.564518 11.096908 +L 18.682064 11.015022 +L 18.799995 10.933691 +L 18.918308 10.852917 +L 19.037 10.772701 +L 19.156069 10.693045 +L 19.275511 10.613951 +L 19.395326 10.535421 +L 19.515509 10.457456 +L 19.636058 10.380059 +L 19.75697 10.30323 +L 19.878243 10.226972 +L 19.999874 10.151287 +L 20.121861 10.076175 +L 20.2442 10.001639 +L 20.366888 9.927681 +L 20.489924 9.854301 +L 20.613305 9.781502 +L 20.737027 9.709286 +L 20.861088 9.637653 +L 20.985485 9.566605 +L 21.110216 9.496145 +L 21.235277 9.426273 +L 21.360667 9.356991 +L 21.486381 9.288301 +L 21.612418 9.220204 +L 21.738774 9.152702 +L 21.865446 9.085796 +L 21.992433 9.019487 +L 22.119731 8.953778 +L 22.247337 8.888669 +L 22.375248 8.824163 +L 22.503462 8.760259 +L 22.631976 8.696961 +L 22.760786 8.634269 +L 22.889891 8.572185 +L 23.019286 8.51071 +L 23.14897 8.449845 +L 23.278939 8.389592 +L 23.409191 8.329952 +L 23.539723 8.270927 +L 23.670531 8.212518 +L 23.801612 8.154725 +L 23.932965 8.097551 +L 24.064586 8.040996 +L 24.196472 7.985063 +L 24.328619 7.929751 +L 24.461026 7.875063 +L 24.59369 7.820999 +L 24.726606 7.767561 +L 24.859773 7.71475 +L 24.993187 7.662568 +L 25.126846 7.611014 +L 25.260746 7.560091 +L 25.394885 7.509799 +L 25.529259 7.46014 +L 25.663866 7.411115 +L 25.798702 7.362725 +L 25.933765 7.314971 +L 26.069051 7.267853 +L 26.204558 7.221374 +L 26.340282 7.175534 +L 26.476221 7.130334 +L 26.612371 7.085775 +L 26.74873 7.041858 +L 26.885295 6.998584 +L 27.022061 6.955954 +L 27.159027 6.913969 +L 27.29619 6.87263 +L 27.433545 6.831938 +L 27.571091 6.791893 +L 27.708824 6.752498 +L 27.846741 6.713751 +L 27.984839 6.675655 +L 28.123116 6.63821 +L 28.261567 6.601418 +L 28.40019 6.565278 +L 28.538981 6.529791 +L 28.677939 6.494959 +L 28.817059 6.460783 +L 28.956338 6.427262 +L 29.095774 6.394398 +L 29.235364 6.362191 +L 29.30301 6.65857 +L 29.370656 6.954948 +L 29.438303 7.251326 +L 29.505949 7.547704 +L 29.573595 7.844082 +L 29.641242 8.14046 +L 29.708888 8.436838 +L 29.776535 8.733216 +L 29.844181 9.029594 +L 29.911827 9.325972 +L 29.979474 9.62235 +L 30.04712 9.918728 +L 30.114766 10.215107 +L 30.182413 10.511485 +L 30.250059 10.807863 +L 30.317705 11.104241 +L 30.385352 11.400619 +L 30.452998 11.696997 +L 30.520645 11.993375 +L 30.588291 12.289753 +L 30.655937 12.586131 +L 30.723584 12.882509 +L 30.79123 13.178887 +L 30.858876 13.475266 +L 30.926523 13.771644 +L 30.994169 14.068022 +L 31.061815 14.3644 +L 31.129462 14.660778 +L 31.197108 14.957156 +L 31.264755 15.253534 +L 31.332401 15.549912 +L 31.400047 15.84629 +L 31.467694 16.142668 +L 31.53534 16.439046 +L 31.602986 16.735424 +L 31.670633 17.031803 +L 31.738279 17.328181 +L 31.805925 17.624559 +L 31.873572 17.920937 +L 31.941218 18.217315 +L 32.008865 18.513693 +L 32.076511 18.810071 +L 32.144157 19.106449 +L 32.211804 19.402827 +L 32.27945 19.699205 +L 32.347096 19.995583 +L 32.414743 20.291961 +L 32.482389 20.58834 +L 32.550035 20.884718 +L 32.617682 21.181096 +L 32.685328 21.477474 +L 32.752975 21.773852 +L 32.820621 22.07023 +L 32.888267 22.366608 +L 32.955914 22.662986 +L 33.02356 22.959364 +L 33.091206 23.255742 +L 33.158853 23.55212 +L 33.226499 23.848499 +L 33.294145 24.144877 +L 33.361792 24.441255 +L 33.429438 24.737633 +L 33.497085 25.034011 +L 33.564731 25.330389 +L 33.632377 25.626767 +L 33.700024 25.923145 +L 33.76767 26.219523 +L 33.835316 26.515901 +L 33.902963 26.812279 +L 33.970609 27.108657 +L 34.038255 27.405036 +L 34.105902 27.701414 +L 34.173548 27.997792 +L 34.241195 28.29417 +L 34.308841 28.590548 +L 34.376487 28.886926 +L 34.444134 29.183304 +L 34.51178 29.479682 +L 34.579426 29.77606 +L 34.647073 30.072438 +L 34.714719 30.368816 +L 34.782365 30.665194 +L 34.850012 30.961573 +L 34.917658 31.257951 +L 34.985305 31.554329 +L 35.052951 31.850707 +L 35.120597 32.147085 +L 35.188244 32.443463 +L 35.25589 32.739841 +L 35.323536 33.036219 +L 35.391183 33.332597 +L 35.458829 33.628975 +L 35.526475 33.925353 +L 35.594122 34.221731 +L 35.661768 34.51811 +L 35.729415 34.814488 +L 35.797061 35.110866 +L 35.864707 35.407244 +L 35.932354 35.703622 +z +" style="fill:#ff6800;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_6"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 35.738275 36.047496 +L 35.476549 36.094992 +L 35.214824 36.142488 +L 34.953099 36.189985 +L 34.691374 36.237481 +L 34.429648 36.284977 +L 34.167923 36.332473 +L 33.906198 36.379969 +L 33.644473 36.427465 +L 33.382747 36.474961 +L 33.121022 36.522457 +L 32.859297 36.569954 +L 32.597571 36.61745 +L 32.335846 36.664946 +L 32.074121 36.712442 +L 31.812396 36.759938 +L 31.55067 36.807434 +L 31.288945 36.85493 +L 31.02722 36.902427 +L 30.765495 36.949923 +L 30.503769 36.997419 +L 30.242044 37.044915 +L 29.980319 37.092411 +L 29.718594 37.139907 +L 29.456868 37.187403 +L 29.195143 37.234899 +L 28.933418 37.282396 +L 28.671692 37.329892 +L 28.409967 37.377388 +L 28.148242 37.424884 +L 27.886517 37.47238 +L 27.624791 37.519876 +L 27.363066 37.567372 +L 27.101341 37.614869 +L 26.839616 37.662365 +L 26.57789 37.709861 +L 26.316165 37.757357 +L 26.05444 37.804853 +L 25.792714 37.852349 +L 25.530989 37.899845 +L 25.269264 37.947341 +L 25.007539 37.994838 +L 24.745813 38.042334 +L 24.484088 38.08983 +L 24.222363 38.137326 +L 23.960638 38.184822 +L 23.698912 38.232318 +L 23.437187 38.279814 +L 23.175462 38.327311 +L 22.913736 38.374807 +L 22.652011 38.422303 +L 22.390286 38.469799 +L 22.128561 38.517295 +L 21.866835 38.564791 +L 21.60511 38.612287 +L 21.343385 38.659784 +L 21.08166 38.70728 +L 20.819934 38.754776 +L 20.558209 38.802272 +L 20.296484 38.849768 +L 20.034758 38.897264 +L 19.773033 38.94476 +L 19.511308 38.992256 +L 19.249583 39.039753 +L 18.987857 39.087249 +L 18.726132 39.134745 +L 18.464407 39.182241 +L 18.202682 39.229737 +L 17.940956 39.277233 +L 17.679231 39.324729 +L 17.417506 39.372226 +L 17.155781 39.419722 +L 16.894055 39.467218 +L 16.63233 39.514714 +L 16.370605 39.56221 +L 16.108879 39.609706 +L 15.847154 39.657202 +L 15.585429 39.704698 +L 15.323704 39.752195 +L 15.061978 39.799691 +L 14.800253 39.847187 +L 14.538528 39.894683 +L 14.276803 39.942179 +L 14.015077 39.989675 +L 13.753352 40.037171 +L 13.491627 40.084668 +L 13.229901 40.132164 +L 12.968176 40.17966 +L 12.706451 40.227156 +L 12.444726 40.274652 +L 12.183 40.322148 +L 11.921275 40.369644 +L 11.65955 40.41714 +L 11.397825 40.464637 +L 11.136099 40.512133 +L 10.874374 40.559629 +L 10.612649 40.607125 +L 10.350923 40.654621 +L 10.089198 40.702117 +L 9.827473 40.749613 +L 9.798147 40.585074 +L 9.769856 40.420353 +L 9.7426 40.255458 +L 9.71638 40.090395 +L 9.691199 39.925171 +L 9.667055 39.759791 +L 9.643952 39.594263 +L 9.621889 39.428594 +L 9.600867 39.262789 +L 9.580888 39.096855 +L 9.561951 38.930798 +L 9.544058 38.764626 +L 9.52721 38.598345 +L 9.511407 38.431962 +L 9.496649 38.265482 +L 9.482938 38.098913 +L 9.470274 37.932261 +L 9.458657 37.765533 +L 9.448088 37.598735 +L 9.438567 37.431874 +L 9.430094 37.264956 +L 9.422671 37.097989 +L 9.416297 36.930978 +L 9.410972 36.76393 +L 9.406697 36.596853 +L 9.403472 36.429751 +L 9.401297 36.262633 +L 9.400171 36.095504 +L 9.400096 35.928372 +L 9.401072 35.761242 +L 9.403097 35.594122 +L 9.406172 35.427018 +L 9.410297 35.259936 +L 9.415472 35.092884 +L 9.421696 34.925867 +L 9.42897 34.758893 +L 9.437292 34.591968 +L 9.446663 34.425099 +L 9.457083 34.258291 +L 9.46855 34.091553 +L 9.481065 33.92489 +L 9.494627 33.758308 +L 9.509235 33.591815 +L 9.524889 33.425418 +L 9.541588 33.259121 +L 9.559331 33.092934 +L 9.578119 32.92686 +L 9.597949 32.760909 +L 9.618822 32.595085 +L 9.640736 32.429395 +L 9.663691 32.263847 +L 9.687686 32.098445 +L 9.712719 31.933198 +L 9.738791 31.768112 +L 9.765898 31.603193 +L 9.794042 31.438447 +L 9.82322 31.273881 +L 9.853432 31.109502 +L 9.884676 30.945316 +L 9.91695 30.781329 +L 9.950255 30.617548 +L 9.984588 30.45398 +L 10.019948 30.290631 +L 10.056333 30.127508 +L 10.093743 29.964616 +L 10.132176 29.801962 +L 10.17163 29.639553 +L 10.212103 29.477395 +L 10.253595 29.315495 +L 10.296102 29.153859 +L 10.339625 28.992493 +L 10.384161 28.831403 +L 10.429708 28.670597 +L 10.476264 28.510079 +L 10.523828 28.349858 +L 10.572398 28.189938 +L 10.621972 28.030327 +L 10.672547 27.871031 +L 10.724123 27.712055 +L 10.776696 27.553407 +L 10.830265 27.395092 +L 10.884828 27.237117 +L 10.940382 27.079487 +L 10.996925 26.92221 +L 11.054456 26.765292 +L 11.112971 26.608737 +L 11.172469 26.452554 +L 11.232947 26.296748 +L 11.294403 26.141324 +L 11.356834 25.98629 +L 11.420238 25.831651 +L 11.484613 25.677414 +L 11.549955 25.523584 +L 11.616262 25.370167 +L 11.683533 25.217171 +L 11.751763 25.0646 +L 11.82095 24.91246 +L 11.891092 24.760759 +L 11.962185 24.609501 +L 12.034228 24.458693 +L 12.273886 24.574106 +L 12.513544 24.689519 +L 12.753201 24.804932 +L 12.992859 24.920345 +L 13.232517 25.035758 +L 13.472174 25.151171 +L 13.711832 25.266584 +L 13.95149 25.381997 +L 14.191148 25.49741 +L 14.430805 25.612823 +L 14.670463 25.728236 +L 14.910121 25.843649 +L 15.149778 25.959063 +L 15.389436 26.074476 +L 15.629094 26.189889 +L 15.868752 26.305302 +L 16.108409 26.420715 +L 16.348067 26.536128 +L 16.587725 26.651541 +L 16.827382 26.766954 +L 17.06704 26.882367 +L 17.306698 26.99778 +L 17.546356 27.113193 +L 17.786013 27.228606 +L 18.025671 27.344019 +L 18.265329 27.459432 +L 18.504987 27.574846 +L 18.744644 27.690259 +L 18.984302 27.805672 +L 19.22396 27.921085 +L 19.463617 28.036498 +L 19.703275 28.151911 +L 19.942933 28.267324 +L 20.182591 28.382737 +L 20.422248 28.49815 +L 20.661906 28.613563 +L 20.901564 28.728976 +L 21.141221 28.844389 +L 21.380879 28.959802 +L 21.620537 29.075216 +L 21.860195 29.190629 +L 22.099852 29.306042 +L 22.33951 29.421455 +L 22.579168 29.536868 +L 22.818825 29.652281 +L 23.058483 29.767694 +L 23.298141 29.883107 +L 23.537799 29.99852 +L 23.777456 30.113933 +L 24.017114 30.229346 +L 24.256772 30.344759 +L 24.496429 30.460172 +L 24.736087 30.575585 +L 24.975745 30.690999 +L 25.215403 30.806412 +L 25.45506 30.921825 +L 25.694718 31.037238 +L 25.934376 31.152651 +L 26.174034 31.268064 +L 26.413691 31.383477 +L 26.653349 31.49889 +L 26.893007 31.614303 +L 27.132664 31.729716 +L 27.372322 31.845129 +L 27.61198 31.960542 +L 27.851638 32.075955 +L 28.091295 32.191369 +L 28.330953 32.306782 +L 28.570611 32.422195 +L 28.810268 32.537608 +L 29.049926 32.653021 +L 29.289584 32.768434 +L 29.529242 32.883847 +L 29.768899 32.99926 +L 30.008557 33.114673 +L 30.248215 33.230086 +L 30.487872 33.345499 +L 30.72753 33.460912 +L 30.967188 33.576325 +L 31.206846 33.691739 +L 31.446503 33.807152 +L 31.686161 33.922565 +L 31.925819 34.037978 +L 32.165476 34.153391 +L 32.405134 34.268804 +L 32.644792 34.384217 +L 32.88445 34.49963 +L 33.124107 34.615043 +L 33.363765 34.730456 +L 33.603423 34.845869 +L 33.843081 34.961282 +L 34.082738 35.076695 +L 34.322396 35.192108 +L 34.562054 35.307522 +L 34.801711 35.422935 +L 35.041369 35.538348 +L 35.281027 35.653761 +L 35.520685 35.769174 +L 35.760342 35.884587 +z +" style="fill:#ffc400;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_7"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 35.875056 36.086562 +L 35.750111 36.173123 +L 35.625167 36.259685 +L 35.500223 36.346247 +L 35.375278 36.432808 +L 35.250334 36.51937 +L 35.12539 36.605932 +L 35.000445 36.692493 +L 34.875501 36.779055 +L 34.750557 36.865616 +L 34.625613 36.952178 +L 34.500668 37.03874 +L 34.375724 37.125301 +L 34.25078 37.211863 +L 34.125835 37.298425 +L 34.000891 37.384986 +L 33.875947 37.471548 +L 33.751002 37.55811 +L 33.626058 37.644671 +L 33.501114 37.731233 +L 33.376169 37.817795 +L 33.251225 37.904356 +L 33.126281 37.990918 +L 33.001336 38.077479 +L 32.876392 38.164041 +L 32.751448 38.250603 +L 32.626503 38.337164 +L 32.501559 38.423726 +L 32.376615 38.510288 +L 32.251671 38.596849 +L 32.126726 38.683411 +L 32.001782 38.769973 +L 31.876838 38.856534 +L 31.751893 38.943096 +L 31.626949 39.029658 +L 31.502005 39.116219 +L 31.37706 39.202781 +L 31.252116 39.289342 +L 31.127172 39.375904 +L 31.002227 39.462466 +L 30.877283 39.549027 +L 30.752339 39.635589 +L 30.627394 39.722151 +L 30.50245 39.808712 +L 30.377506 39.895274 +L 30.252561 39.981836 +L 30.127617 40.068397 +L 30.002673 40.154959 +L 29.877729 40.241521 +L 29.752784 40.328082 +L 29.62784 40.414644 +L 29.502896 40.501205 +L 29.377951 40.587767 +L 29.253007 40.674329 +L 29.128063 40.76089 +L 29.003118 40.847452 +L 28.878174 40.934014 +L 28.75323 41.020575 +L 28.628285 41.107137 +L 28.503341 41.193699 +L 28.378397 41.28026 +L 28.253452 41.366822 +L 28.128508 41.453384 +L 28.003564 41.539945 +L 27.878619 41.626507 +L 27.753675 41.713068 +L 27.628731 41.79963 +L 27.503787 41.886192 +L 27.378842 41.972753 +L 27.253898 42.059315 +L 27.128954 42.145877 +L 27.004009 42.232438 +L 26.879065 42.319 +L 26.754121 42.405562 +L 26.629176 42.492123 +L 26.504232 42.578685 +L 26.379288 42.665247 +L 26.254343 42.751808 +L 26.129399 42.83837 +L 26.004455 42.924931 +L 25.87951 43.011493 +L 25.754566 43.098055 +L 25.629622 43.184616 +L 25.504678 43.271178 +L 25.379733 43.35774 +L 25.254789 43.444301 +L 25.129845 43.530863 +L 25.0049 43.617425 +L 24.879956 43.703986 +L 24.755012 43.790548 +L 24.630067 43.87711 +L 24.505123 43.963671 +L 24.380179 44.050233 +L 24.255234 44.136794 +L 24.13029 44.223356 +L 24.005346 44.309918 +L 23.880401 44.396479 +L 23.755457 44.483041 +L 23.630513 44.569603 +L 23.505568 44.656164 +L 23.491987 44.636527 +L 23.478436 44.616869 +L 23.464916 44.59719 +L 23.451427 44.577489 +L 23.437969 44.557767 +L 23.424542 44.538024 +L 23.411146 44.51826 +L 23.397781 44.498475 +L 23.384447 44.478669 +L 23.371145 44.458842 +L 23.357873 44.438995 +L 23.344633 44.419126 +L 23.331424 44.399237 +L 23.318246 44.379327 +L 23.305099 44.359396 +L 23.291984 44.339444 +L 23.2789 44.319472 +L 23.265848 44.29948 +L 23.252827 44.279467 +L 23.239837 44.259433 +L 23.226879 44.23938 +L 23.213952 44.219305 +L 23.201057 44.199211 +L 23.188194 44.179096 +L 23.175362 44.158962 +L 23.162562 44.138807 +L 23.149793 44.118632 +L 23.137056 44.098437 +L 23.124351 44.078222 +L 23.111678 44.057987 +L 23.099036 44.037732 +L 23.086426 44.017457 +L 23.073849 43.997163 +L 23.061303 43.976848 +L 23.048789 43.956514 +L 23.036306 43.936161 +L 23.023856 43.915788 +L 23.011438 43.895395 +L 22.999052 43.874983 +L 22.986698 43.854551 +L 22.974376 43.834101 +L 22.962087 43.81363 +L 22.949829 43.793141 +L 22.937604 43.772632 +L 22.925411 43.752104 +L 22.91325 43.731557 +L 22.901121 43.710991 +L 22.889025 43.690406 +L 22.876961 43.669802 +L 22.86493 43.649178 +L 22.852931 43.628536 +L 22.840964 43.607876 +L 22.82903 43.587196 +L 22.817128 43.566498 +L 22.805259 43.545781 +L 22.793422 43.525045 +L 22.781618 43.504291 +L 22.769847 43.483519 +L 22.758108 43.462728 +L 22.746402 43.441918 +L 22.734729 43.42109 +L 22.723088 43.400244 +L 22.71148 43.37938 +L 22.699905 43.358497 +L 22.688363 43.337596 +L 22.676853 43.316677 +L 22.665377 43.29574 +L 22.653933 43.274785 +L 22.642522 43.253812 +L 22.631145 43.232821 +L 22.6198 43.211813 +L 22.608488 43.190786 +L 22.597209 43.169742 +L 22.585964 43.14868 +L 22.574751 43.127601 +L 22.563572 43.106504 +L 22.552425 43.085389 +L 22.541312 43.064257 +L 22.530232 43.043107 +L 22.519186 43.02194 +L 22.508172 43.000756 +L 22.497192 42.979555 +L 22.486245 42.958336 +L 22.475332 42.9371 +L 22.464452 42.915847 +L 22.453605 42.894577 +L 22.442792 42.87329 +L 22.432012 42.851985 +L 22.421266 42.830664 +L 22.410553 42.809327 +L 22.399874 42.787972 +L 22.389228 42.766601 +L 22.378616 42.745213 +L 22.368037 42.723808 +L 22.357492 42.702386 +L 22.346981 42.680949 +L 22.336504 42.659494 +L 22.32606 42.638023 +L 22.31565 42.616536 +L 22.305273 42.595033 +L 22.44222 42.529083 +L 22.579168 42.463132 +L 22.716115 42.397182 +L 22.853062 42.331232 +L 22.99001 42.265281 +L 23.126957 42.199331 +L 23.263904 42.133381 +L 23.400851 42.06743 +L 23.537799 42.00148 +L 23.674746 41.93553 +L 23.811693 41.869579 +L 23.94864 41.803629 +L 24.085588 41.737679 +L 24.222535 41.671728 +L 24.359482 41.605778 +L 24.496429 41.539828 +L 24.633377 41.473877 +L 24.770324 41.407927 +L 24.907271 41.341977 +L 25.044219 41.276026 +L 25.181166 41.210076 +L 25.318113 41.144126 +L 25.45506 41.078175 +L 25.592008 41.012225 +L 25.728955 40.946275 +L 25.865902 40.880324 +L 26.002849 40.814374 +L 26.139797 40.748424 +L 26.276744 40.682473 +L 26.413691 40.616523 +L 26.550639 40.550573 +L 26.687586 40.484622 +L 26.824533 40.418672 +L 26.96148 40.352722 +L 27.098428 40.286771 +L 27.235375 40.220821 +L 27.372322 40.154871 +L 27.509269 40.08892 +L 27.646217 40.02297 +L 27.783164 39.95702 +L 27.920111 39.891069 +L 28.057058 39.825119 +L 28.194006 39.759169 +L 28.330953 39.693218 +L 28.4679 39.627268 +L 28.604848 39.561318 +L 28.741795 39.495367 +L 28.878742 39.429417 +L 29.015689 39.363467 +L 29.152637 39.297516 +L 29.289584 39.231566 +L 29.426531 39.165616 +L 29.563478 39.099665 +L 29.700426 39.033715 +L 29.837373 38.967765 +L 29.97432 38.901814 +L 30.111267 38.835864 +L 30.248215 38.769914 +L 30.385162 38.703963 +L 30.522109 38.638013 +L 30.659057 38.572063 +L 30.796004 38.506112 +L 30.932951 38.440162 +L 31.069898 38.374212 +L 31.206846 38.308261 +L 31.343793 38.242311 +L 31.48074 38.176361 +L 31.617687 38.110411 +L 31.754635 38.04446 +L 31.891582 37.97851 +L 32.028529 37.91256 +L 32.165476 37.846609 +L 32.302424 37.780659 +L 32.439371 37.714709 +L 32.576318 37.648758 +L 32.713266 37.582808 +L 32.850213 37.516858 +L 32.98716 37.450907 +L 33.124107 37.384957 +L 33.261055 37.319007 +L 33.398002 37.253056 +L 33.534949 37.187106 +L 33.671896 37.121156 +L 33.808844 37.055205 +L 33.945791 36.989255 +L 34.082738 36.923305 +L 34.219686 36.857354 +L 34.356633 36.791404 +L 34.49358 36.725454 +L 34.630527 36.659503 +L 34.767475 36.593553 +L 34.904422 36.527603 +L 35.041369 36.461652 +L 35.178316 36.395702 +L 35.315264 36.329752 +L 35.452211 36.263801 +L 35.589158 36.197851 +L 35.726105 36.131901 +L 35.863053 36.06595 +z +" style="fill:#29ffce;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_8"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36.031826 36.187315 +L 36.063652 36.374631 +L 36.095479 36.561946 +L 36.127305 36.749262 +L 36.159131 36.936577 +L 36.190957 37.123893 +L 36.222783 37.311208 +L 36.254609 37.498524 +L 36.286436 37.685839 +L 36.318262 37.873155 +L 36.350088 38.06047 +L 36.381914 38.247786 +L 36.41374 38.435101 +L 36.445567 38.622417 +L 36.477393 38.809732 +L 36.509219 38.997048 +L 36.541045 39.184363 +L 36.572871 39.371679 +L 36.604697 39.558994 +L 36.636524 39.74631 +L 36.66835 39.933625 +L 36.700176 40.120941 +L 36.732002 40.308256 +L 36.763828 40.495572 +L 36.795655 40.682887 +L 36.827481 40.870203 +L 36.859307 41.057518 +L 36.891133 41.244834 +L 36.922959 41.432149 +L 36.954785 41.619465 +L 36.986612 41.80678 +L 37.018438 41.994096 +L 37.050264 42.181411 +L 37.08209 42.368727 +L 37.113916 42.556042 +L 37.145743 42.743358 +L 37.177569 42.930673 +L 37.209395 43.117989 +L 37.241221 43.305304 +L 37.273047 43.49262 +L 37.304873 43.679935 +L 37.3367 43.867251 +L 37.368526 44.054566 +L 37.400352 44.241882 +L 37.432178 44.429197 +L 37.464004 44.616513 +L 37.495831 44.803828 +L 37.527657 44.991144 +L 37.559483 45.178459 +L 37.591309 45.365775 +L 37.623135 45.55309 +L 37.654961 45.740406 +L 37.686788 45.927721 +L 37.718614 46.115037 +L 37.75044 46.302352 +L 37.782266 46.489668 +L 37.814092 46.676983 +L 37.845919 46.864299 +L 37.877745 47.051614 +L 37.909571 47.23893 +L 37.941397 47.426245 +L 37.973223 47.613561 +L 38.005049 47.800876 +L 38.036876 47.988192 +L 38.068702 48.175507 +L 38.100528 48.362823 +L 38.132354 48.550138 +L 38.16418 48.737454 +L 38.196007 48.924769 +L 38.227833 49.112085 +L 38.259659 49.2994 +L 38.291485 49.486716 +L 38.323311 49.674031 +L 38.355137 49.861347 +L 38.386964 50.048662 +L 38.41879 50.235978 +L 38.450616 50.423293 +L 38.482442 50.610608 +L 38.514268 50.797924 +L 38.546095 50.985239 +L 38.577921 51.172555 +L 38.609747 51.35987 +L 38.641573 51.547186 +L 38.673399 51.734501 +L 38.705226 51.921817 +L 38.737052 52.109132 +L 38.768878 52.296448 +L 38.800704 52.483763 +L 38.83253 52.671079 +L 38.864356 52.858394 +L 38.896183 53.04571 +L 38.928009 53.233025 +L 38.959835 53.420341 +L 38.991661 53.607656 +L 39.023487 53.794972 +L 39.055314 53.982287 +L 39.08714 54.169603 +L 39.118966 54.356918 +L 39.150792 54.544234 +L 39.182618 54.731549 +L 39.109035 54.743903 +L 39.035404 54.755968 +L 38.961727 54.767743 +L 38.888003 54.779229 +L 38.814235 54.790425 +L 38.740424 54.801332 +L 38.66657 54.811948 +L 38.592676 54.822275 +L 38.518741 54.832311 +L 38.444767 54.842057 +L 38.370756 54.851512 +L 38.296708 54.860677 +L 38.222625 54.869551 +L 38.148508 54.878133 +L 38.074357 54.886425 +L 38.000174 54.894425 +L 37.925961 54.902134 +L 37.851718 54.909552 +L 37.777446 54.916677 +L 37.703147 54.923512 +L 37.628821 54.930054 +L 37.554471 54.936304 +L 37.480096 54.942263 +L 37.405699 54.947929 +L 37.33128 54.953303 +L 37.256841 54.958385 +L 37.182382 54.963174 +L 37.107905 54.967671 +L 37.03341 54.971876 +L 36.9589 54.975787 +L 36.884375 54.979407 +L 36.809837 54.982733 +L 36.735286 54.985767 +L 36.660723 54.988508 +L 36.586151 54.990956 +L 36.511569 54.993112 +L 36.436979 54.994974 +L 36.362383 54.996544 +L 36.287781 54.99782 +L 36.213175 54.998804 +L 36.138565 54.999495 +L 36.063954 54.999892 +L 35.989341 54.999997 +L 35.914728 54.999809 +L 35.840117 54.999327 +L 35.765509 54.998553 +L 35.690903 54.997486 +L 35.616303 54.996125 +L 35.541709 54.994472 +L 35.467121 54.992526 +L 35.392542 54.990287 +L 35.317972 54.987755 +L 35.243413 54.98493 +L 35.168865 54.981813 +L 35.09433 54.978403 +L 35.01981 54.9747 +L 34.945304 54.970704 +L 34.870814 54.966416 +L 34.796342 54.961836 +L 34.721889 54.956963 +L 34.647455 54.951797 +L 34.573042 54.94634 +L 34.498651 54.94059 +L 34.424284 54.934548 +L 34.34994 54.928214 +L 34.275622 54.921589 +L 34.201331 54.914671 +L 34.127067 54.907462 +L 34.052832 54.899961 +L 33.978627 54.892169 +L 33.904454 54.884086 +L 33.830313 54.875711 +L 33.756205 54.867045 +L 33.682131 54.858088 +L 33.608094 54.84884 +L 33.534093 54.839302 +L 33.460131 54.829473 +L 33.386207 54.819354 +L 33.312324 54.808945 +L 33.238483 54.798245 +L 33.164684 54.787256 +L 33.090928 54.775977 +L 33.017218 54.764408 +L 32.943553 54.75255 +L 32.869936 54.740403 +L 32.796367 54.727967 +L 32.722847 54.715242 +L 32.649378 54.702228 +L 32.575961 54.688926 +L 32.502596 54.675336 +L 32.429285 54.661458 +L 32.35603 54.647292 +L 32.28283 54.632838 +L 32.209688 54.618097 +L 32.136604 54.603069 +L 32.06358 54.587754 +L 31.990617 54.572152 +L 31.917715 54.556265 +L 31.844877 54.54009 +L 31.772102 54.52363 +L 31.814381 54.338394 +L 31.85666 54.153158 +L 31.898939 53.967921 +L 31.941218 53.782685 +L 31.983497 53.597449 +L 32.025776 53.412213 +L 32.068055 53.226976 +L 32.110334 53.04174 +L 32.152613 52.856504 +L 32.194892 52.671267 +L 32.237171 52.486031 +L 32.27945 52.300795 +L 32.321729 52.115558 +L 32.364008 51.930322 +L 32.406287 51.745086 +L 32.448566 51.559849 +L 32.490845 51.374613 +L 32.533124 51.189377 +L 32.575403 51.004141 +L 32.617682 50.818904 +L 32.659961 50.633668 +L 32.70224 50.448432 +L 32.744519 50.263195 +L 32.786798 50.077959 +L 32.829077 49.892723 +L 32.871356 49.707486 +L 32.913635 49.52225 +L 32.955914 49.337014 +L 32.998193 49.151778 +L 33.040472 48.966541 +L 33.082751 48.781305 +L 33.12503 48.596069 +L 33.167309 48.410832 +L 33.209587 48.225596 +L 33.251866 48.04036 +L 33.294145 47.855123 +L 33.336424 47.669887 +L 33.378703 47.484651 +L 33.420982 47.299415 +L 33.463261 47.114178 +L 33.50554 46.928942 +L 33.547819 46.743706 +L 33.590098 46.558469 +L 33.632377 46.373233 +L 33.674656 46.187997 +L 33.716935 46.00276 +L 33.759214 45.817524 +L 33.801493 45.632288 +L 33.843772 45.447051 +L 33.886051 45.261815 +L 33.92833 45.076579 +L 33.970609 44.891343 +L 34.012888 44.706106 +L 34.055167 44.52087 +L 34.097446 44.335634 +L 34.139725 44.150397 +L 34.182004 43.965161 +L 34.224283 43.779925 +L 34.266562 43.594688 +L 34.308841 43.409452 +L 34.35112 43.224216 +L 34.393399 43.03898 +L 34.435678 42.853743 +L 34.477957 42.668507 +L 34.520236 42.483271 +L 34.562515 42.298034 +L 34.604794 42.112798 +L 34.647073 41.927562 +L 34.689352 41.742325 +L 34.731631 41.557089 +L 34.77391 41.371853 +L 34.816189 41.186616 +L 34.858468 41.00138 +L 34.900747 40.816144 +L 34.943026 40.630908 +L 34.985305 40.445671 +L 35.027584 40.260435 +L 35.069862 40.075199 +L 35.112141 39.889962 +L 35.15442 39.704726 +L 35.196699 39.51949 +L 35.238978 39.334253 +L 35.281257 39.149017 +L 35.323536 38.963781 +L 35.365815 38.778545 +L 35.408094 38.593308 +L 35.450373 38.408072 +L 35.492652 38.222836 +L 35.534931 38.037599 +L 35.57721 37.852363 +L 35.619489 37.667127 +L 35.661768 37.48189 +L 35.704047 37.296654 +L 35.746326 37.111418 +L 35.788605 36.926182 +L 35.830884 36.740945 +L 35.873163 36.555709 +L 35.915442 36.370473 +L 35.957721 36.185236 +z +" style="fill:#7dff7a;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_9"> + <path clip-path="url(#p2b9aa5bb59)" d="M 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36 36 +L 36.239788 36.186862 +L 36.479577 36.373725 +L 36.719365 36.560587 +L 36.959154 36.747449 +L 37.198942 36.934311 +L 37.43873 37.121174 +L 37.678519 37.308036 +L 37.918307 37.494898 +L 38.158096 37.681761 +L 38.397884 37.868623 +L 38.637673 38.055485 +L 38.877461 38.242348 +L 39.117249 38.42921 +L 39.357038 38.616072 +L 39.596826 38.802934 +L 39.836615 38.989797 +L 40.076403 39.176659 +L 40.316191 39.363521 +L 40.55598 39.550384 +L 40.795768 39.737246 +L 41.035557 39.924108 +L 41.275345 40.110971 +L 41.515133 40.297833 +L 41.754922 40.484695 +L 41.99471 40.671557 +L 42.234499 40.85842 +L 42.474287 41.045282 +L 42.714075 41.232144 +L 42.953864 41.419007 +L 43.193652 41.605869 +L 43.433441 41.792731 +L 43.673229 41.979594 +L 43.913018 42.166456 +L 44.152806 42.353318 +L 44.392594 42.54018 +L 44.632383 42.727043 +L 44.872171 42.913905 +L 45.11196 43.100767 +L 45.351748 43.28763 +L 45.591536 43.474492 +L 45.831325 43.661354 +L 46.071113 43.848217 +L 46.310902 44.035079 +L 46.55069 44.221941 +L 46.790478 44.408803 +L 47.030267 44.595666 +L 47.270055 44.782528 +L 47.509844 44.96939 +L 47.749632 45.156253 +L 47.98942 45.343115 +L 48.229209 45.529977 +L 48.468997 45.71684 +L 48.708786 45.903702 +L 48.948574 46.090564 +L 49.188363 46.277426 +L 49.428151 46.464289 +L 49.667939 46.651151 +L 49.907728 46.838013 +L 50.147516 47.024876 +L 50.387305 47.211738 +L 50.627093 47.3986 +L 50.866881 47.585462 +L 51.10667 47.772325 +L 51.346458 47.959187 +L 51.586247 48.146049 +L 51.826035 48.332912 +L 52.065823 48.519774 +L 52.305612 48.706636 +L 52.5454 48.893499 +L 52.785189 49.080361 +L 53.024977 49.267223 +L 53.264766 49.454085 +L 53.504554 49.640948 +L 53.744342 49.82781 +L 53.984131 50.014672 +L 54.223919 50.201535 +L 54.463708 50.388397 +L 54.703496 50.575259 +L 54.943284 50.762122 +L 55.183073 50.948984 +L 55.422861 51.135846 +L 55.66265 51.322708 +L 55.902438 51.509571 +L 56.142226 51.696433 +L 56.382015 51.883295 +L 56.621803 52.070158 +L 56.861592 52.25702 +L 57.10138 52.443882 +L 57.341168 52.630745 +L 57.580957 52.817607 +L 57.820745 53.004469 +L 58.060534 53.191331 +L 58.300322 53.378194 +L 58.540111 53.565056 +L 58.779899 53.751918 +L 59.019687 53.938781 +L 59.259476 54.125643 +L 59.499264 54.312505 +L 59.739053 54.499368 +L 59.978841 54.68623 +L 59.934746 54.742677 +L 59.890518 54.79902 +L 59.846158 54.855258 +L 59.801665 54.911392 +L 59.75704 54.967421 +L 59.712283 55.023344 +L 59.667395 55.079162 +L 59.622375 55.134874 +L 59.577224 55.19048 +L 59.531942 55.245979 +L 59.486529 55.301371 +L 59.440987 55.356657 +L 59.395313 55.411834 +L 59.34951 55.466904 +L 59.303578 55.521866 +L 59.257516 55.57672 +L 59.211325 55.631464 +L 59.165005 55.6861 +L 59.118556 55.740627 +L 59.07198 55.795044 +L 59.025275 55.849351 +L 58.978442 55.903548 +L 58.931481 55.957634 +L 58.884394 56.01161 +L 58.837179 56.065474 +L 58.789837 56.119227 +L 58.742369 56.172869 +L 58.694775 56.226398 +L 58.647055 56.279815 +L 58.599209 56.33312 +L 58.551237 56.386311 +L 58.503141 56.43939 +L 58.454919 56.492355 +L 58.406573 56.545206 +L 58.358102 56.597943 +L 58.309507 56.650566 +L 58.260789 56.703074 +L 58.211947 56.755467 +L 58.162981 56.807745 +L 58.113892 56.859908 +L 58.064681 56.911955 +L 58.015347 56.963885 +L 57.965891 57.015699 +L 57.916313 57.067397 +L 57.866614 57.118978 +L 57.816792 57.170441 +L 57.76685 57.221787 +L 57.716787 57.273015 +L 57.666604 57.324124 +L 57.6163 57.375116 +L 57.565876 57.425989 +L 57.515332 57.476743 +L 57.464669 57.527377 +L 57.413887 57.577892 +L 57.362986 57.628288 +L 57.311966 57.678563 +L 57.260828 57.728718 +L 57.209572 57.778752 +L 57.158198 57.828666 +L 57.106707 57.878458 +L 57.055099 57.928129 +L 57.003373 57.977678 +L 56.951531 58.027105 +L 56.899573 58.076409 +L 56.847499 58.125591 +L 56.795309 58.174651 +L 56.743003 58.223587 +L 56.690583 58.2724 +L 56.638047 58.321089 +L 56.585397 58.369654 +L 56.532633 58.418095 +L 56.479754 58.466412 +L 56.426762 58.514604 +L 56.373657 58.562671 +L 56.320438 58.610612 +L 56.267107 58.658428 +L 56.213663 58.706119 +L 56.160107 58.753683 +L 56.106439 58.801121 +L 56.052659 58.848432 +L 55.998769 58.895617 +L 55.944767 58.942674 +L 55.890654 58.989604 +L 55.836431 59.036406 +L 55.782097 59.083081 +L 55.727654 59.129627 +L 55.673102 59.176045 +L 55.61844 59.222334 +L 55.563669 59.268495 +L 55.50879 59.314526 +L 55.453802 59.360428 +L 55.398706 59.4062 +L 55.343503 59.451842 +L 55.288192 59.497354 +L 55.232775 59.542735 +L 55.17725 59.587986 +L 55.121619 59.633106 +L 55.065882 59.678094 +L 55.010039 59.722952 +L 54.95409 59.767677 +L 54.764549 59.53 +L 54.575008 59.292324 +L 54.385467 59.054647 +L 54.195926 58.81697 +L 54.006385 58.579293 +L 53.816845 58.341616 +L 53.627304 58.10394 +L 53.437763 57.866263 +L 53.248222 57.628586 +L 53.058681 57.390909 +L 52.86914 57.153233 +L 52.679599 56.915556 +L 52.490058 56.677879 +L 52.300517 56.440202 +L 52.110976 56.202526 +L 51.921436 55.964849 +L 51.731895 55.727172 +L 51.542354 55.489495 +L 51.352813 55.251818 +L 51.163272 55.014142 +L 50.973731 54.776465 +L 50.78419 54.538788 +L 50.594649 54.301111 +L 50.405108 54.063435 +L 50.215567 53.825758 +L 50.026027 53.588081 +L 49.836486 53.350404 +L 49.646945 53.112727 +L 49.457404 52.875051 +L 49.267863 52.637374 +L 49.078322 52.399697 +L 48.888781 52.16202 +L 48.69924 51.924344 +L 48.509699 51.686667 +L 48.320158 51.44899 +L 48.130618 51.211313 +L 47.941077 50.973637 +L 47.751536 50.73596 +L 47.561995 50.498283 +L 47.372454 50.260606 +L 47.182913 50.022929 +L 46.993372 49.785253 +L 46.803831 49.547576 +L 46.61429 49.309899 +L 46.424749 49.072222 +L 46.235209 48.834546 +L 46.045668 48.596869 +L 45.856127 48.359192 +L 45.666586 48.121515 +L 45.477045 47.883839 +L 45.287504 47.646162 +L 45.097963 47.408485 +L 44.908422 47.170808 +L 44.718881 46.933131 +L 44.52934 46.695455 +L 44.3398 46.457778 +L 44.150259 46.220101 +L 43.960718 45.982424 +L 43.771177 45.744748 +L 43.581636 45.507071 +L 43.392095 45.269394 +L 43.202554 45.031717 +L 43.013013 44.794041 +L 42.823472 44.556364 +L 42.633931 44.318687 +L 42.444391 44.08101 +L 42.25485 43.843333 +L 42.065309 43.605657 +L 41.875768 43.36798 +L 41.686227 43.130303 +L 41.496686 42.892626 +L 41.307145 42.65495 +L 41.117604 42.417273 +L 40.928063 42.179596 +L 40.738522 41.941919 +L 40.548982 41.704242 +L 40.359441 41.466566 +L 40.1699 41.228889 +L 39.980359 40.991212 +L 39.790818 40.753535 +L 39.601277 40.515859 +L 39.411736 40.278182 +L 39.222195 40.040505 +L 39.032654 39.802828 +L 38.843113 39.565152 +L 38.653573 39.327475 +L 38.464032 39.089798 +L 38.274491 38.852121 +L 38.08495 38.614444 +L 37.895409 38.376768 +L 37.705868 38.139091 +L 37.516327 37.901414 +L 37.326786 37.663737 +L 37.137245 37.426061 +L 36.947704 37.188384 +L 36.758164 36.950707 +L 36.568623 36.71303 +L 36.379082 36.475354 +L 36.189541 36.237677 +z +" style="fill:#ff6800;stroke:#000000;stroke-linejoin:miter;"/> + </g> + <g id="patch_10"> + <path d="M 36 70.2 +C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052 +C 66.596472 53.769632 70.2 45.069946 70.2 36 +C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948 +C 53.769632 5.403528 45.069946 1.8 36 1.8 +C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948 +C 5.403528 18.230368 1.8 26.930054 1.8 36 +C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052 +C 18.230368 66.596472 26.930054 70.2 36 70.2 +z +" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/> + </g> + </g> + </g> + <defs> + <clipPath id="p2b9aa5bb59"> + <path d="M 36 70.2 +C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052 +C 66.596472 53.769632 70.2 45.069946 70.2 36 +C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948 +C 53.769632 5.403528 45.069946 1.8 36 1.8 +C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948 +C 5.403528 18.230368 1.8 26.930054 1.8 36 +C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052 +C 18.230368 66.596472 26.930054 70.2 36 70.2 +z +"/> + </clipPath> + </defs> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/matplotlib_large.png new file mode 100644 index 0000000000000000000000000000000000000000..c7dcfe6cb8255b332d9c6d15d8049ec63c3141e5 GIT binary patch literal 3088 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move-symbolic.svg new file mode 100644 index 00000000..aa7198cf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move-symbolic.svg @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 70 37.44 +C 70 36.8025 69.734375 36.18625 69.2775 35.74 +L 59.56625 26.018125 +C 59.109375 25.56125 58.50375 25.295625 57.855625 25.295625 +C 56.5275 25.295625 55.433125 26.400625 55.433125 27.72875 +L 55.433125 32.584375 +L 40.855625 32.584375 +L 40.855625 18.0175 +L 45.71125 18.0175 +C 47.039375 18.0175 48.144375 16.9125 48.144375 15.584375 +C 48.144375 14.93625 47.87875 14.330625 47.421875 13.87375 +L 37.710625 4.1625 +C 37.25375 3.705625 36.648125 3.44 36 3.44 +C 35.351875 3.44 34.74625 3.705625 34.289375 4.1625 +L 24.578125 13.87375 +C 24.12125 14.330625 23.855625 14.93625 23.855625 15.584375 +C 23.855625 16.9125 24.960625 18.0175 26.28875 18.0175 +L 31.144375 18.0175 +L 31.144375 32.584375 +L 16.566875 32.584375 +L 16.566875 27.72875 +C 16.566875 26.400625 15.4725 25.295625 14.144375 25.295625 +C 13.49625 25.295625 12.890625 25.56125 12.43375 26.018125 +L 2.7225 35.74 +C 2.265625 36.18625 2 36.8025 2 37.44 +C 2 38.088125 2.265625 38.69375 2.7225 39.150625 +L 12.43375 48.861875 +C 12.890625 49.31875 13.49625 49.584375 14.144375 49.584375 +C 15.4725 49.584375 16.566875 48.49 16.566875 47.161875 +L 16.566875 42.295625 +L 31.144375 42.295625 +L 31.144375 56.873125 +L 26.28875 56.873125 +C 24.960625 56.873125 23.855625 57.9675 23.855625 59.295625 +C 23.855625 59.94375 24.12125 60.549375 24.578125 61.00625 +L 34.289375 70.7175 +C 34.74625 71.174375 35.351875 71.44 36 71.44 +C 36.648125 71.44 37.25375 71.174375 37.710625 70.7175 +L 47.421875 61.00625 +C 47.87875 60.549375 48.144375 59.94375 48.144375 59.295625 +C 48.144375 57.9675 47.039375 56.873125 45.71125 56.873125 +L 40.855625 56.873125 +L 40.855625 42.295625 +L 55.433125 42.295625 +L 55.433125 47.161875 +C 55.433125 48.49 56.5275 49.584375 57.855625 49.584375 +C 58.50375 49.584375 59.109375 49.31875 59.56625 48.861875 +L 69.2775 39.150625 +C 69.734375 38.69375 70 38.088125 70 37.44 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d883d9224a6e61436205a18182f5e66708312976 GIT binary patch literal 1867 zcmZuyYfuwc7!{;GA|h6*{;=f=A^{5fViSl+frJ3jj%fl^2Va|H6Qi)3*(?}Dv?DFr zQXRGEsN=K!0rk;Z>tkTV6p$$$t%^{sfTE&w3WcIhM+>IYdlMoE?qp_j&wS5wzwd0A zR;7+6Vqzs>C)>e^Y6$^wz#G;|5)uHWWh|^6kPy)UEVIzY0!+z>OfGK$iHQ=HGa<vc z5e}&iF-<QrA`4<YPHLVL0p<CxWkit`I6$ML1k(z<QO}AX2j)?!VSLsh0xTmB=1duS zD~H}0U<JVRYZ#N2vjCaLed!XzTGl86xjXo9IRp*?Zv)93$BTBD0{SaqDJ%z1@ty!_ z0-tXKs7<9FU@Er2YGie3Ff}}73JhnrF#^jO3%#9t>|rA8L)K(vQg{c9i;~Gn^n)3+ z$U*e-rDN@UzF>p|B8FZOh&Ua=9xBFLt=gIk2?Cfp7c!_~jl2mGzL@1K;u=7pd(k0B zyC|?sp2X3bpS6g)i~G0t1SR@}cK^+m`SKl6v#qT^_0CVSyLL#+%FF!HSJ&)H-&H@i zq3uM`KwaCFwyp~wzjX2!7oM-+uW#P`?)8q~RTnycExhksG4;hkSBZ1R(T$rF&nLcD z*Wd5k)AzXP_O&c$gQ}{fz4u9|zP~VP!EgIQwBw>}fzp<MAc^b6gQo%YTTYc*`JxYs z3wG9=)E_G!DB#LnpJjHHW_{Np%*<)He_9*x+`eD;WkR3y(#x%3pNjh<XRp^JXICuR zwDK8oAhfqAO>o-Yiu_l)%zqyJaNfrIA<jSEkv2bjFf%CN_~mVjd-e$5?jCnENWCF0 z_?vlwQ7QckD}BpaI{ku#j_B=Q&l<mTmF_Fy>__L8ij%|l8}^n|AF9+$pBcP5FSDom zPn*x%l@GH+6$=`5g=GmUmg~BZG-dh}#fvRJ);Ky7l2T7aI42$2Q+;AW>B)x9o2j=G zQ?q8swGH(*GHQO=(R|UoCnQZXxZ=p1%HIF#O3(O&F;^7hs`OK92mDk9LKRmOaW!#D zYw_u}5YqC*Fn?FbG?ODWuxdGRt*urT9=}OZM*2mj{Ltn5$Z&PH%s&7V_S!Xb`x=+? z>D}EC^*3)6KRuV-Zwz|=WFHBvl7|zHul1*`b0;6U)lu8MURnHk=)GeWvu0TfS3R-I zwYqkoBw|~jWg5dRr__U2*Uj3Hm(tr*6+ig<U+3;T{-XX)`i&&hr0q?NPunL=XStnS z&ZBj^r^Xs}6^E05Cg<EvnO&WIv$QX~GV)RBO3i`hdoAYg>yB%R6Ze)3G*&kLL!2?k z9lW%xm9EG+eEv?3>u&R{oRydBtAek&#<x@JYth~h&ESv%xMvd$v5ca;s(^NWXs(BM z6N!R%*pms*?j=KPNLz;012ZxZM!S|wdd-M8n-S1##6BT$8Iu=D#uyL@#~2W4owq_I zpAWYgrd?z;Aq{aWiw-TiM+!aaINTlanloHd(aLiwB!*Izg2V|KF2f0eq-b0ojmL)L zczA>aQzAQF0Ma~0wB_<*uGIjD7&?X&jAV?Bw~ItPMa7ud0zArMkjrU?l)Vquh@wq_ zVZ$ylykLRBpro4ejZi{HMzfjBz`z*S!OMymL6k#a%@Q0ClmvhE02xhFG%$l#7y+q6 z58%8QLB_*t9EA~R1V&>N<YN>@Qe*8%`VDq+I6trZ;<yan?I?_j8*4}6P;XziBk=gK zc`15CAELlmb6LUt)yv?_JaAto6m1>PqZx1uxZb*fg@hpz?II(HZVCySjFW_gr7lrR F{s+sqfx`d* literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.png new file mode 100644 index 0000000000000000000000000000000000000000..4fbbaef41bbadaab211d778f32f6febf31e5251c GIT binary patch literal 481 zcmV<70UrK|P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET4gGod|R7i=nl{-rVK@^3*6M_nX5JGA# z>;<(ELGY1(px9Z7U9dB)wYJ*WYomolx+oS#E3Nbo2!fS}5ET^US~%)B$!>O6JaF0F z`#5KI=FW`FjQ>O~O|qmVNz17e%q)=sHNc$J6W3)RPbHF-Jh6!47Fm*jHc*I2c>{`O z_8P?zyU6ybJ_<|&4KH-$d?Rt>UnEJ_VTYfo*-cv4@duJ7B^6^w)di9YlBPm`E=Z~Y z=fGN80bmt4l~nI4;K;Y!=RgL5e)rt?B@)q!PrzMZ&tCkcOT0~&76zCgy3hY=GXO>4 z;vdMbfU?XCNhRPI7<V(*0QQ18UIFIZ`x&qu#21_aTm!RacJKFj3Al9Xn`!p}u<nh# z(y<TB>=CE}2SAhbH~|j7NA8gKGn~j`26D`-1++qcstYFzVoy^5N&CPsFbGtf`vJHC zZh?6-dylHmM+H0#0b_x$?5uZvf>YG*uCUK5J?j%5)uBit@}4)E54RbcKp#-`TQLqF XUOpjj<Y(e+00000NkvXXu0mjfXMx2= literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.svg new file mode 100644 index 00000000..aa7198cf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move.svg @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 70 37.44 +C 70 36.8025 69.734375 36.18625 69.2775 35.74 +L 59.56625 26.018125 +C 59.109375 25.56125 58.50375 25.295625 57.855625 25.295625 +C 56.5275 25.295625 55.433125 26.400625 55.433125 27.72875 +L 55.433125 32.584375 +L 40.855625 32.584375 +L 40.855625 18.0175 +L 45.71125 18.0175 +C 47.039375 18.0175 48.144375 16.9125 48.144375 15.584375 +C 48.144375 14.93625 47.87875 14.330625 47.421875 13.87375 +L 37.710625 4.1625 +C 37.25375 3.705625 36.648125 3.44 36 3.44 +C 35.351875 3.44 34.74625 3.705625 34.289375 4.1625 +L 24.578125 13.87375 +C 24.12125 14.330625 23.855625 14.93625 23.855625 15.584375 +C 23.855625 16.9125 24.960625 18.0175 26.28875 18.0175 +L 31.144375 18.0175 +L 31.144375 32.584375 +L 16.566875 32.584375 +L 16.566875 27.72875 +C 16.566875 26.400625 15.4725 25.295625 14.144375 25.295625 +C 13.49625 25.295625 12.890625 25.56125 12.43375 26.018125 +L 2.7225 35.74 +C 2.265625 36.18625 2 36.8025 2 37.44 +C 2 38.088125 2.265625 38.69375 2.7225 39.150625 +L 12.43375 48.861875 +C 12.890625 49.31875 13.49625 49.584375 14.144375 49.584375 +C 15.4725 49.584375 16.566875 48.49 16.566875 47.161875 +L 16.566875 42.295625 +L 31.144375 42.295625 +L 31.144375 56.873125 +L 26.28875 56.873125 +C 24.960625 56.873125 23.855625 57.9675 23.855625 59.295625 +C 23.855625 59.94375 24.12125 60.549375 24.578125 61.00625 +L 34.289375 70.7175 +C 34.74625 71.174375 35.351875 71.44 36 71.44 +C 36.648125 71.44 37.25375 71.174375 37.710625 70.7175 +L 47.421875 61.00625 +C 47.87875 60.549375 48.144375 59.94375 48.144375 59.295625 +C 48.144375 57.9675 47.039375 56.873125 45.71125 56.873125 +L 40.855625 56.873125 +L 40.855625 42.295625 +L 55.433125 42.295625 +L 55.433125 47.161875 +C 55.433125 48.49 56.5275 49.584375 57.855625 49.584375 +C 58.50375 49.584375 59.109375 49.31875 59.56625 48.861875 +L 69.2775 39.150625 +C 69.734375 38.69375 70 38.088125 70 37.44 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/move_large.png new file mode 100644 index 0000000000000000000000000000000000000000..96351c115f0b504c28b10ad7518915638373eeb8 GIT binary patch literal 767 zcmV<b0s#GqP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PEp-DtRRA_<in7wNhK^Vq=Pm;?)1VJu> zNu`1|mKJG6v9L{H3jc_Jwz=L?>;*xH9}vXG+JC^p3lbF-tx`mb;EAY-uf^_}z1+?2 z-p=f<D?TuAJ3H^b&ogt(`yn%<$(X8}fG=js`mm%~U=`R0ZkyR&DUQr6_yF3#Q^4Y} z0klf-RRQ@@MN~z;G!a#jFGWPv<b#W-gM3gCzT^cwDL{TO?)wT*Or#Jb%>z4yKM-Ng z%)S*h_Kn1!fyW;9>ptWGzY_qEG!2{tTJh8paM!VX1?a`Ue*hoM?3a&!?^MFf_JMbU zXGx1G%RidgD_@^UG(MU8FQ9Iu3Xs&6^hi=)(v7M}N$N`aD(Rl2R_fvjBJ3V8l_R)a z#2vVna@fx?LBt+=0+QN9_xqK^^fV<FKnb)DJud?fTqiLiz(Kxl3`C4<;Lt=4@~0&I z%y71l@@`Sm=?wd$j`?Nap`;Z{mZt%-%Bsf(Ff){mHi-O)h=G8ce*vjUM>ly3b!Z;u zfj=j30(edRyP9|OfX+}wMs#~LK|~KYKDHv0v;aH<&N`0m8d0Y$4d;Na<J}tYHpBi1 zaL4g(6S!n%2UXyhP@Z-YvlXNg#~ijpJMT;-%xoLD0KCcAsVXtL^D)NeLJkoIc$I%S zakvTWBo8U+bV9^dJhg6Rb(n|!e&L`|@PZWbkda-Q*|wzfL`8d*f2pg$8Q{H{eNS7M znI6Y&kFBhAArYT+E}#E)N!bK6UO<TM^cwI9*o{XYcOdI0*6je->u&CLV)8zywYj?s zy!5bt?%Uk;5)fZ^mnjw_HVM%<@cj=KOvT40W`%r*_{fAJf{_m@Ag73+<bw;y5D}bw xDFPfKN+ECN83)o3m#4Rg^7~aY^Nkl{@f%rAWT}OsKx+U1002ovPDHLkV1hF5S{48R literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a92f2cc3aaee87f45926546bcc135f40a357160a GIT binary patch literal 1568 zcmZuxe`p(39N!Ov^ER9~>J;mEN<&j(bNB9YNmJKtZL)M(tId)MTcx_o<u$!Fy_em+ zbZMasDk1}iT6HMXwYFAgo2e+MtSV}YtfKP=`$0Ex`$uHxKqy_6;g9$7qlw9mgS+?T z`}uy~`+Ps2XAS!Nwb0?@tm&V?^eGMk0pLgvw{<JvgGvmUK%|in;M)fh2=HEoC~+JE z+qQ8?kFvzNBEZfRX$}*GAmGe`{8%SI%KirxLXe>YnJqa!Xkayr2zZS4@%d?elp=r+ z^wFM8xvw|(4S-I-hr5-irpJIQ3*Xxo=|L(1?o9E*cA!85`2#fSIwmG<LGfO?6{ORZ zCtIM|z{vz)$Ml8)??e5XibBn_HC?qEif$$p1L^8O{^Z$w+K7J`MKz@fr)XW)%q_B) zb_g;6$@3LLCQceEC6F<+LLlR`h&{HM{BHePoDu|hf1EPtLn@9^!dsCZBi#V9xr7+d zBnDFYxYWhuNQ*uzZ164DKjjGetCl)Hv|Sl`cmErKwQn6;b#3XP@ybib*0`#+zwqko zw(IVLgXqw}pI30|P{WP+(VxHD{>0*6>fqwytmTgx`!Kq?{<!7)qtoW)6JX*?%fhE$ zpItul(k}Tx?Ys$UhRlPlCy{3idH207Y`p%!>AsGCCJv9=TArTyX7%HpdhbHJt+zdV zS+Sxgcffm3z*mm!p4{@q?<1e5=k>&a!-1E7Sr;Cwv~T?3#fGNHT=SbF-`>3&aa`3L zTAHf(?4<q3>GvO*+%xsncxXf0T^;|vbAEWtA}`!mF?H(Bmf<axmK(AD3!66gc%QGB zId>~}^!P2WU7M>Is`_o$nscArb30sKwWD@FkkfnCI)4<%=)ecFwnx*|&!jJ2<sF-Q z;&-^m8}3iPH#rfEtF5ZBZvEtiOSf&B?)d2AXGhQcz4}-CbA*XGM{G{k8N%6QB*~eV zIumkkSOvi`rROKu2(yA}q_Lb~3YOqig@&1c8pV7Xym=a=X+<Jojw$QQd{7o-ZYT>f z1Lt?>#Yrkr+O|cDGGk=y5@PDj`a5g+!s+1uz*Koe!@7?-+~%tn1?Uo70)(O@3+`IM zSuF_FH5~6{dDsB9K7}OWn8dXRfDYLq8mj0>V3R<PBsrp}U$Dm_Znvz6t_MLkA&GjP zFF+jFh|yy7o`@z@>WkuPiD(yyC~7YqR!tF6DFbzJ0)P@HtUSOa%aRPbz)B2K>evJH zm6*pvIWCFSv9p)PB&vaum`5tl^T;>Jb5p65U<FrsU#YGfD+=@yDZ#ouWqqL_7u6$% wqQ#Msxyl227Y3PO(wiuRG1EZiRtjr_h!Vy~G>Kx6424h>J)G6Lv(3-_2iA4qYybcN literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.png new file mode 100644 index 0000000000000000000000000000000000000000..792ec81244e3b8f3fe3cd28ef4898d934a1d73a3 GIT binary patch literal 380 zcmV-?0fYXDP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET49!W$&R7i=nmZ46>KomvK-Qo}{_6I=X z086r(Z@_{_5x#(g;6UK85DXHx5`lv+Soj3O>b;0gVYWM^UFf{zn)fE>w0V=JvQ5q! zWTgWGNn2S3z*$bgS|1Qe7r?02HgMUC0C)pV68%XpOSXLtT%~5c2qcYx!z_XTe+1V5 zB#=}{I+Zl+2)_f4<8u$TNd+i?d&(Q}3=E^$7?_1wm0O?)^CMulQBZ?BmbAfZoMk}+ zyvl1=cv8>;Po)vQBxrzt0tdkRs_+HDFYvuE->gYm;okzv>)Hs94p)*+aNFg_&h}i= zl%JXb`?jB=9=4~Fwt)}Zb2?VMgY(pr|0fHA(Aek;ZW{qFz)jcJUA08H&}=1OC#xX$ aZ_5|SEVtE#bgR$+0000<MNUMnLSTYBjGUPO literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.svg new file mode 100644 index 00000000..0b46bf80 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options.svg @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 74.855625 61.72875 +L 2 61.72875 +L 2 8.295625 +L -2.855625 8.295625 +L -2.855625 66.584375 +L 74.855625 66.584375 +z +M 70 14.373125 +C 70 13.693125 69.46875 13.161875 68.78875 13.161875 +L 52.2775 13.161875 +C 51.215 13.161875 50.651875 14.4475 51.44875 15.244375 +L 56.03875 19.834375 +L 38.433125 37.44 +L 29.593125 28.6 +C 29.09375 28.11125 28.339375 28.11125 27.84 28.6 +L 5.644375 50.795625 +L 12.933125 58.084375 +L 28.71125 42.295625 +L 37.561875 51.14625 +C 38.050625 51.635 38.805 51.635 39.304375 51.14625 +L 63.3275 27.123125 +L 67.9175 31.713125 +C 68.714375 32.51 70 31.93625 70 30.87375 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/qt4_editor_options_large.png new file mode 100644 index 0000000000000000000000000000000000000000..46d52c91c9bfe19b86b24fd92326c31b52a03ece GIT binary patch literal 619 zcmV-x0+juUP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PE4M{{nRA_<in7vCJK^TXhR|Fy871u^c zkuG2nQiY_8*!dUa!%h&c&EFs<U5I5$NtGszDXb+n#xh+<V=3gU^_SvyVbR^Y`8sD- z{J}KGygSds&g{#LNutkL$PEyidx6~Pzkr#&H?t?XK|-?td;p&11_@2?x6op4fI4RO z5Lj`XF5tJMaWMkG0kG;Ze;;^L(iYkQE<NTCprA7#=_{}aT=~=$BLE<2A9#m{L{S1& z4uC(dlZz5CvmtN@Ja(-qMxX)z)TgcpflzoTKp+Ml5(=2vQU&8v;|hNaY}4^|67W_M zp@T_NIReJO3&)xva8j*5ZTtiVRn2QA%}&7g`tNX*Km)#BaHd2Ee51CO_!ceD0zXqC z2EOr(m%yVafhq8v5-H$YIQ#`1;BQFG13pN=1HK*?z{Wh_y#)f`eTFx@B=<gGW&_{{ z@Z7b=BgeqHq_J<IlR&BP;2_`u{|or!xqcLUoz63W`<_1mhE>h3!~Ebq?|g_u;2X8G zB$B{)3dF!WNF;-A6-WU;MItHu4FTXmD)<(O<nUc@;BzYY#xvJ|<<#)g&On!hH~hRu zYafs_0`{)`d<v{dI&Z7VmCi<XP2v=IRT@0ZxSf_XGPA$HmlEN@;d))t$J+o2P4;V* z*cg+q%Ng)5GfPlvf!^j$Y@w~(5HYd39rrc8-$K0?_z!Suk2@Llp?m-U002ovPDHLk FV1kGd4Z#2a literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots-symbolic.svg new file mode 100644 index 00000000..e87d2c9b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots-symbolic.svg @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 20.21125 56.873125 +L 6.855625 56.873125 +L 6.855625 61.72875 +L 20.21125 61.72875 +z +M 33.566875 52.0175 +L 23.855625 52.0175 +C 22.5275 52.0175 21.4225 53.111875 21.4225 54.44 +L 21.4225 64.161875 +C 21.4225 65.49 22.5275 66.584375 23.855625 66.584375 +L 33.566875 66.584375 +C 34.895 66.584375 36 65.49 36 64.161875 +L 36 54.44 +C 36 53.111875 34.895 52.0175 33.566875 52.0175 +M 39.644375 37.44 +L 6.855625 37.44 +L 6.855625 42.295625 +L 39.644375 42.295625 +z +M 15.355625 18.0175 +L 6.855625 18.0175 +L 6.855625 22.873125 +L 15.355625 22.873125 +z +M 65.144375 56.873125 +L 37.21125 56.873125 +L 37.21125 61.72875 +L 65.144375 61.72875 +z +M 28.71125 13.161875 +L 19 13.161875 +C 17.671875 13.161875 16.566875 14.25625 16.566875 15.584375 +L 16.566875 25.295625 +C 16.566875 26.62375 17.671875 27.72875 19 27.72875 +L 28.71125 27.72875 +C 30.039375 27.72875 31.144375 26.62375 31.144375 25.295625 +L 31.144375 15.584375 +C 31.144375 14.25625 30.039375 13.161875 28.71125 13.161875 +M 53 32.584375 +L 43.28875 32.584375 +C 41.960625 32.584375 40.855625 33.689375 40.855625 35.0175 +L 40.855625 44.72875 +C 40.855625 46.056875 41.960625 47.161875 43.28875 47.161875 +L 53 47.161875 +C 54.328125 47.161875 55.4225 46.056875 55.4225 44.72875 +L 55.4225 35.0175 +C 55.4225 33.689375 54.328125 32.584375 53 32.584375 +M 65.144375 37.44 +L 56.644375 37.44 +L 56.644375 42.295625 +L 65.144375 42.295625 +z +M 65.144375 18.0175 +L 32.355625 18.0175 +L 32.355625 22.873125 +L 65.144375 22.873125 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f404665579a0b1916174203f13f7339a75a347a5 GIT binary patch literal 1714 zcmZuy4@?tR7@wHHybvLATgC+T#B_j2@2=%~Eo+KUC?W%!mJk+X<k}vktlZV>6@iUK zru^AtB9brxH@3mh4L2kNoGx)eoWaC^*@SJ5I3#MAWJAG?3`f{|E#+T#X>xtPeBbwb z@AtmncM^TFE|!$WVUly>pz9Jw0s`=+B229YxSp}HP9TGb0pM9>4i?~AMr7=~6=*aV z%UMvMa!o=?shDaM8Ic8Xo+KU5i9qi8uV+M&6*xelC5Gz--fUz=kPCT|b+A5LDgr#M z7;+{pzqQNnG>`{yV<BU)aaN%4r04866|rU!(C*@^+aU=Ecn^@salGh+6fj>4x59F8 zrScR=6?m5epkr!{08eI1Y-ZMw3aQ~LOJF#sgArKHT;@HwCms^v8LY*|B=M!NE+V64 z=m#0}C_(h<Wni7WOE5zLkwPm1B2Cw*hc@Hgt<GkL0s&lShYBXMX5In?e~sm=Vj&>W zy%<oUQxsUH7%RP9+?dX7Cj+bJ)m52$rWbSiqb4f4iM^9A3ABI9bj{8W_8#9328Ld~ znxBwAJbrg}u(|$B&x6dRwrkB@7ym7PI&XdJX~m+gKQd=BDC%QP#nR3ENTr58{9VVy znJWP)GrN9T44jB9|FAB7Dk)IXu<u&S?RTF0`T35+hJf6jBre#m)6^R|ex5oxSE&v7 zR9PRbygV7EONiJt*7SGdC+|iZr~K=%F{RYSgfzD2?mk^xe?&c8XbcZ2dA1?Ed%-kR z_(yp8**U&skKtHsd)|)Bnm+55ZYrX=T9r+AZw(u*uFBf>_Tc3Bxr<ke$~QlJLum-= z-4?2;{NY$eeC)xNJK)E-8;72pKRPQ*_^6?-3LEX6jQK}GyGG|WWu16kU3u>;xSz1_ z{Vn!SX5i#_2y5%VdFpfZ`-V$@O-(%BS67o(GHA)|Y}Q|Xp*Xag4CEv?X0e{2BDL}H zIF)z(`cA`<rH2<bxk}<Yzfj%_58k}+fSL{t>kl2F+wV7Yy?CI4DI5MWIR6`e>=nB$ zyQ%HbLDhlmqfsM%uXfb#sEgQ=@q5mpGOhmZR<iZ@w|=LahSC>)yTuvXV_MU`D*t8d z>r;1<-qXx<KI&^7XuHrC^Vz&UV&vB?GtcDLMk<~ldo5q}veDcvfO;iPNqEhNthL-e zs}?}s^Y&CC>1pvqh%H-q)ugzYfiP<6M42~?{Qoc#hOKE^<Y6CP<V+tB`O^nPBgMNz zE$@P+fwbv13$m))zy{<e&&2Tzq1Dro>yn`tL>tc~qnQ(x94{kC1)(5FQYNPeI+low zB#6jp4A-JKUI0<WjOeiQqTOZ!q?D4%1hY));GH6=lFOwQwuFeWnrND0WQyIOP!t{U zIKG-9<pnD&1}B%rWrj{&Tg_o904B!#CcLcZHA0mNYyn09QjQTT4^U8)oB{=41tXz! z=mDG;Bgr`E`1Kf}qTndmh|zF_tj9=#_K712m2Vs=gY#>BE<q^Z-EP3-O4w%`Fd5;) zL8#<D7^GNp4pCric2;nIT++A#9=I<P&PD^zqaJY2Nu#Ztg@PdwogyQMZV5>_O<@vA I%6=X89}zDwrvLx| literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.png new file mode 100644 index 0000000000000000000000000000000000000000..bb0318c40e72343d52227ef29048224b5c7177ae GIT binary patch literal 445 zcmV;u0Yd(XP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET4Ur9tkR7i>4l}{@~VHC!H&vZ@7hLTB2 zc4DKHk{BCX+hJ{I<pU^7A3zpn$rr#Em{P++DJ4;M7D$L}actfh@11+6d)?f~TTh+$ zbnf~4-1ExJ$nz9(_5ObYNGeOZlyv2AA!#B@fWUJ)0`$7;3^3ecJ1eO(rQc^WI|IPX za7@|*%wfxu8>q(U+M(9)8+-+21K4-+P)t_Wz*5QzZkkdfk`G`Wc=s}T1Lopvlc2nR zv>@3edL(rK3qaASK7d^_dx;olDI2H|9qekHtxwZ+pq#RZqZnPEq`H$&%xne1E$RkJ zDFYN^bOrDGo~AZqix!EtXzj;XB&iEnCOqVAGrNu0{_1-msVeEt!=WU7CxFkQal%7> z0;XGZC16Zae}dmfGdl*_E;|G2z&Y8LUM(_YNmIapm&F6H35>R6Hwg?TRB&%*2cZhu n&~XQN^>B(K#-CYsxxdMuDB^0ix|8Qv00000NkvXXu0mjf9r?Kn literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.svg new file mode 100644 index 00000000..e87d2c9b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots.svg @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 20.21125 56.873125 +L 6.855625 56.873125 +L 6.855625 61.72875 +L 20.21125 61.72875 +z +M 33.566875 52.0175 +L 23.855625 52.0175 +C 22.5275 52.0175 21.4225 53.111875 21.4225 54.44 +L 21.4225 64.161875 +C 21.4225 65.49 22.5275 66.584375 23.855625 66.584375 +L 33.566875 66.584375 +C 34.895 66.584375 36 65.49 36 64.161875 +L 36 54.44 +C 36 53.111875 34.895 52.0175 33.566875 52.0175 +M 39.644375 37.44 +L 6.855625 37.44 +L 6.855625 42.295625 +L 39.644375 42.295625 +z +M 15.355625 18.0175 +L 6.855625 18.0175 +L 6.855625 22.873125 +L 15.355625 22.873125 +z +M 65.144375 56.873125 +L 37.21125 56.873125 +L 37.21125 61.72875 +L 65.144375 61.72875 +z +M 28.71125 13.161875 +L 19 13.161875 +C 17.671875 13.161875 16.566875 14.25625 16.566875 15.584375 +L 16.566875 25.295625 +C 16.566875 26.62375 17.671875 27.72875 19 27.72875 +L 28.71125 27.72875 +C 30.039375 27.72875 31.144375 26.62375 31.144375 25.295625 +L 31.144375 15.584375 +C 31.144375 14.25625 30.039375 13.161875 28.71125 13.161875 +M 53 32.584375 +L 43.28875 32.584375 +C 41.960625 32.584375 40.855625 33.689375 40.855625 35.0175 +L 40.855625 44.72875 +C 40.855625 46.056875 41.960625 47.161875 43.28875 47.161875 +L 53 47.161875 +C 54.328125 47.161875 55.4225 46.056875 55.4225 44.72875 +L 55.4225 35.0175 +C 55.4225 33.689375 54.328125 32.584375 53 32.584375 +M 65.144375 37.44 +L 56.644375 37.44 +L 56.644375 42.295625 +L 65.144375 42.295625 +z +M 65.144375 18.0175 +L 32.355625 18.0175 +L 32.355625 22.873125 +L 65.144375 22.873125 +z +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/subplots_large.png new file mode 100644 index 0000000000000000000000000000000000000000..4440af1759ee448e56727ad09e6861eab94ecca5 GIT binary patch literal 662 zcmV;H0%`q;P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PEI7vi7RA_<im_2J0Q51%s*Uu>8C$X}$ zvrw=TML}f2+D0raECM2GW2GRb5p41c>}<5r#wJaO5G?!&7RJItj2g7q4HmCmST{2} z=g!@oVdFk<n=|jcb1wIuJ7-3=nPhgfoj@+r3AD|00&O#$K->IZ6Oc3~sVm7PV@=Ze zaV1-rQ_7oI(mHUcLbhnTla*Bhsat4oKr>S(k-F>}3`n{L+%3@Fj+zef$YsIy>;Ax& z2>>U63kC72trPLc<<($d;!mNX6<7ft7Q{a%_?CI(@_sOodJ1)^F4A|lFD52do764z zbwrwxk-7qBfX9@t!gt`l?X?l)7Rzb+N!c<*r_flDv=i7@a(Tn{pA^4FS3pt+_&sFw zB;85!Y_bL<EdiG*WZ!Hbk9sy;1A79RNW-{EQ8RY~c#vWe<Y`nW=`8TP$iw!_{y<R? z&jP2@atkq=pgmBM!xoQid5kVGo?d<#xE|DgEXiScFwpcVv;v%~ko~e9{`P2k3w;@p zW|OAh#B;z;;8@A^E-;^BIBn+ICTj~x+7BEox!kk8p5q_FcC7()fF9r>W4^9`bkwc^ zNpFFx6|xQ6WBt*UQv<sLnn?4OMNu<%6L?f{-?QigB%K1@B<5Ad6WcHP14TuA1UOk? zbTr|iGXcLShX(`O@)%tNZdKg(0k|A|#%jPXO5UHje{Pf(fh!d<+aBvG=a{bsG@mm3 wL*%@P?*Tu6vJdbcu#n*&V%p5L&BRaOFPMf1EJN4dC;$Ke07*qoM6N<$f>ymE2mk;8 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg new file mode 100644 index 00000000..f4b69b23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 48.139062 32.589687 +C 48.139062 41.960938 40.510312 49.589687 31.139063 49.589687 +C 21.767812 49.589687 14.139062 41.960938 14.139062 32.589687 +C 14.139062 23.218437 21.767812 15.589687 31.139063 15.589687 +C 40.510312 15.589687 48.139062 23.218437 48.139062 32.589687 +M 67.572187 64.156562 +C 67.572187 62.870937 67.040937 61.617188 66.169688 60.745937 +L 53.154062 47.730312 +C 56.224688 43.289062 57.860938 37.976562 57.860938 32.589687 +C 57.860938 17.820937 45.907813 5.867812 31.139063 5.867812 +C 16.380937 5.867812 4.427812 17.820937 4.427812 32.589687 +C 4.427812 47.347812 16.380937 59.300937 31.139063 59.300937 +C 36.525937 59.300937 41.838437 57.664687 46.279687 54.594062 +L 59.295313 67.577812 +C 60.166562 68.480937 61.420313 69.012187 62.716563 69.012187 +C 65.372813 69.012187 67.572187 66.812812 67.572187 64.156562 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.pdf b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.pdf new file mode 100644 index 0000000000000000000000000000000000000000..22add33bb8f9f99112681f4ddc52ec96dca8c537 GIT binary patch literal 1609 zcmZuxeM}Q)98Q)w%!SR6Igu^s>juLQ?A?1udlU&$T8qR1wMD@ZmR+werBd$ByBAiN zEH2Dt;>aR1Cd8>EbGQT-Bxq2aL<zbq`^ww|Da>Uqi*f$pvM^mX68FCSfJ%31a=j<N zkN16k&-2T6Ih-4zDUZoMJp=kj7zj9^dUrF0g@AQQeq;ciAa1}`wQ2~kb_q*C)enk_ z7^L`UV17cvmJlxWU<o6T7fo`i3I;;-ze~ax=?XB@Plk2rs_a1+)RI09C#jD@7_enc zq-RO&ZI8XnKpkK`4U#XQ_<<#wUQ_AajbseONb!Z^K#l<M3)mDz#Rh3X^6lg(NFiU= zXn|5)ZPoz2rriTr2Wkn($X!ZWldmdWQVdPfks`OoZyt>&jo5PJ3rHnuh}5OcM4tXg z2NzAialYKhP@8p`5J(xCCy;WQz#ctJ{It$MkPrk|XOJ-HK(gv1guj9mKW+e!&c#g= z4Xh)ni3x?9+}o5)m^yuLdC}Y6_T1^ORxG(STD>wW&@rhzadwhzdf1h+bzjEK-mLEK z+`C=JN4K`MS6VOq^5|&RPuG7KzO#Ar2Y2od58Mr%N}WsJadpq?l+jI>Tj#((Pd`<c zI`HYL+~GYre_p$Np|*Tt>XXt&Fw)yIBn}@bG}4|M-?6&q<qh{cGf$40wSn}ixkDE+ z*qWbjys-aZIQ`!*Yi@u1;My}`lQ?p5>irXcwY#cJH;mW!&2(B|s@!qxYM)U&l{S&p z^I7GkrAO9h=N>roZrA4>or8z@H?^Jbz4TU2$kTPGUpqMksz8S4`bR_GOfR{3ex~8d z>2SD0%3JZM{qNbqoU`z2@n(2-bi03Y*WNXIi>rTo)*+<zPkmT%xbgV8+K`;GOZ&bc zsQ$SB=ywkWTZ|L;#<b_pU#VGB=UiU?#>8u1^h#rWv&UW>8t;Dc;j3Mje{JiVskRkY z)c^6$ncv5Dp1Sqzru4d%nad7Tt{S(^mdq|&+Hme5Refv%G5tp-Lq{lx=C~)Q;$u@? zP$soReAG4=Ri2GtF=s7!hm|D)Q>EGXco_WuFi64@)I_b7)R!7238c130;$vEC$y{0 zM9ZY@wt$a1DB>$Om3ed#M0dl&?cig{M4~vLDh|2|);bD!4q7-12O%$*IdLPGm&0*6 z>loHf<5V52ZIZASRB<ri1<+(R@w&{LG}XY+DhMVYYT-8cy`pHAcuOv5z*s9_*@YC7 zs{2VXvQT`@GBHqMHO*HKypr5VhP5t%sF05884f^!;pQJ;F`ET5s0Z^HB-GIdC~*vO zLK4R1o5{Q%kK^)1GVVo~RZNbvT9e`+2gw{4<#Lu}Ovq2J$8%)cEXvInlHwp|O}Gcv xr9cqrk)2<r)T<yeOtP}vs!BBwSzn$&8zO{J5)CZrI6@)hMUKhN-cspg{sVxa0OtSz literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.png new file mode 100644 index 0000000000000000000000000000000000000000..12afa252481c3d00f5486cca5d9016638c7c0e9a GIT binary patch literal 530 zcmV+t0`2{YP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000B9000B90Vl){tpET4v`IukR7i=nmAy(_Q4q&}|0pQfX|Z5o zlUNvR6)OcrLLiVLg%XHO)bw_OD87KCNRtPMjfKHS5VT1iKqE@Pq)3zq3Yvvo$71h= zxo7Xk3DJRp%iRCR-Z^t-WoA5NJbF;|G6P9nlIA4sN;;MFN78pmJCdGDQj~+4wI#3& z{06KfzX7v({ESwP_=gH%pSQq5v_Xz|6Zj0g0bT-&z}~-@c=5@AcnCZ$XyG_;;jnd} zR%Nj52**Hw>8Ha8aOF6wg$BR?&~V_ns>4fo?;YnS&{<@#;DF~qSERvU(AJR<liq_q zH@OF9RxcWBA7*w0+_+M2h)E4BrxqJ3c+QBOx!O}nJyFWiFwpHvr){95mo-|WmiF>p z<QaT)oRg|C{X}*mo>YiW0e>B5qsm~6>_q$^XDX6DzXGlu_L72o6Oz{g69e{vC14&{ zp>@MU%r!6_yX^8zVlvmHsK0LuerdR?*2!*wHj}bL6z~k#0=@zVz!zWxm;gEw-0L!v z%2A9Q*U;n!81<{-zrxHmY5iw3lTtVEB7J#p3Cz&C8^3@dGegOXdy8bvG}4862fM!j UB#x~4YybcN07*qoM6N<$f@tI9jQ{`u literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.svg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.svg new file mode 100644 index 00000000..f4b69b23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.org/) --> +<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <style type="text/css"> +*{stroke-linecap:butt;stroke-linejoin:round;} + </style> + </defs> + <g id="figure_1"> + <g id="patch_1"> + <path d="M 0 72 +L 72 72 +L 72 0 +L 0 0 +z +" style="fill:none;opacity:0;"/> + </g> + <g id="text_1"> + <path d="M 48.139062 32.589687 +C 48.139062 41.960938 40.510312 49.589687 31.139063 49.589687 +C 21.767812 49.589687 14.139062 41.960938 14.139062 32.589687 +C 14.139062 23.218437 21.767812 15.589687 31.139063 15.589687 +C 40.510312 15.589687 48.139062 23.218437 48.139062 32.589687 +M 67.572187 64.156562 +C 67.572187 62.870937 67.040937 61.617188 66.169688 60.745937 +L 53.154062 47.730312 +C 56.224688 43.289062 57.860938 37.976562 57.860938 32.589687 +C 57.860938 17.820937 45.907813 5.867812 31.139063 5.867812 +C 16.380937 5.867812 4.427812 17.820937 4.427812 32.589687 +C 4.427812 47.347812 16.380937 59.300937 31.139063 59.300937 +C 36.525937 59.300937 41.838437 57.664687 46.279687 54.594062 +L 59.295313 67.577812 +C 60.166562 68.480937 61.420313 69.012187 62.716563 69.012187 +C 65.372813 69.012187 67.572187 66.812812 67.572187 64.156562 +"/> + </g> + </g> +</svg> diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect_large.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/images/zoom_to_rect_large.png new file mode 100644 index 0000000000000000000000000000000000000000..5963603bb681f76a1f2ce3e3fc120b5a089c27fa GIT binary patch literal 1016 zcmV<U0|)$xP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW zd<bNS00009a7bBm000MJ000MJ0hPnJwg3PFnn^@KRA_<KnM+7jQ51&1ZF+qaQAAm( z4JsTInxIlRDTGKG6a`HR8Uzj+L=BoWh=_`aCSlR22fYZQ20eyB1-;YWSfMFVVMzok zMGti~*ta;|?%rqbbB=lYVNLE{_h0|N-{%}9BK*(D8*2e^@!uQBPl`w>RRoj*g}@Ln zAR@g<@f+(#T?0y~3BVel0jLM&^LK~z0<Gz|BqD9mr5Ye2UIA1BEkGY2o^c0Q2c&%K z8ufSxF9i0Xr-!fb%xDMd|Cs@x7I>b3@L&uAdw_ybH2^dMUlJA{jEiwhjJ5dKCXBm~ zQmP8L3zTF{7>S4I1^NiRxbuP8=-p`vFv)@Al!&Z%$Qubm&ljY{*m`XkI1W^YjA9AU z40MI?39vemDFo~cDbx)t_9_J9fx{uZy};C127of)howk6P#SsB!IlschvFL8Wg&kX zM|_~hc1w)`U}7W#KnnO^AzvC-e7a5^aLZC>Q&a;hEu`m?5Fe;jWvSKX%9DAWUW6Gf zmNsvQ$TQ%&p}ATqRqVo(X`s%K*DWG99ku!3gyHvmpvHwD(?G2u@1Cn7Pu#b(nL2X> z{uoe7rGUwXyeA%_eDD(ZZfGlYAqb8@p(Ss?Rgn)wWEl8rXfAT$2pSl)<fU9iMSzKW z$mP#L1K-dma5hx>C~}2TY9{)MkqsYRIQ|$Ay*WQM<kkC0bB2xgl?y@UF4Stst5HhL za+2hS6_&OaE(Dnd9vJe*0UKQiU7?hk0<1MOcZf)r6H&(TJ`KICWjo&cfLRG%B@P<u z2(UlWT_{a_+CqF4$V)(cBl>~JRA)gP0}Cz00vwBD0)5(lw(wu};xiPv5@O;k9(VQt zZ&Qf)VLaa#nF`GaDI~xfV3o^g0Oi1u5IzA;dUuMY=sJgjf__-v0W3>z0x9(2R0V7R z&I3Okx%z>IL=2=&>~<`iWO$iynYTG@!gcX&#e6=DsR^GQq#AgfkhnqM0Ps4l3Eyq7 z0N4z4#t?o6n3v|Oh-<>jK){FsmID`no)7`U=tt6R!0aqs6%HL@G!gj|QxHn2GW6AW zCQyui82N<062B6W{*eEdqu)@>v7`+EO(Jr8#II3CU^D`K*tv{EUF<0|$|gEOOx#F( z3MGm3bh-x2wWQ^X$Pnb<hi(yhhyEziX-Mh$Ego{v0Dy?RN1N!#(!4h_IcEcy4je_l mF@Fv;kIFVWmdME|<bz+3Z%>7dLd3}c0000<MNUMnLSTYkG_ME% literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/kpsewhich.lua b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/kpsewhich.lua new file mode 100644 index 00000000..8e9172a4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/kpsewhich.lua @@ -0,0 +1,3 @@ +-- see dviread._LuatexKpsewhich +kpse.set_program_name("latex") +while true do print(kpse.lookup(io.read():gsub("\r", ""))); io.flush(); end diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc new file mode 100644 index 00000000..5014aa44 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc @@ -0,0 +1,798 @@ +#### MATPLOTLIBRC FORMAT + +## NOTE FOR END USERS: DO NOT EDIT THIS FILE! +## +## This is a sample Matplotlib configuration file - you can find a copy +## of it on your system in site-packages/matplotlib/mpl-data/matplotlibrc +## (relative to your Python installation location). +## DO NOT EDIT IT! +## +## If you wish to change your default style, copy this file to one of the +## following locations: +## Unix/Linux: +## $HOME/.config/matplotlib/matplotlibrc OR +## $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set) +## Other platforms: +## $HOME/.matplotlib/matplotlibrc +## and edit that copy. +## +## See https://matplotlib.org/stable/users/explain/customizing.html#customizing-with-matplotlibrc-files +## for more details on the paths which are checked for the configuration file. +## +## Blank lines, or lines starting with a comment symbol, are ignored, as are +## trailing comments. Other lines must have the format: +## key: val # optional comment +## +## Formatting: Use PEP8-like style (as enforced in the rest of the codebase). +## All lines start with an additional '#', so that removing all leading '#'s +## yields a valid style file. +## +## Colors: for the color values below, you can either use +## - a Matplotlib color string, such as r, k, or b +## - an RGB tuple, such as (1.0, 0.5, 0.0) +## - a double-quoted hex string, such as "#ff00ff". +## The unquoted string ff00ff is also supported for backward +## compatibility, but is discouraged. +## - a scalar grayscale intensity such as 0.75 +## - a legal html color name, e.g., red, blue, darkslategray +## +## String values may optionally be enclosed in double quotes, which allows +## using the comment character # in the string. +## +## This file (and other style files) must be encoded as utf-8. +## +## Matplotlib configuration are currently divided into following parts: +## - BACKENDS +## - LINES +## - PATCHES +## - HATCHES +## - BOXPLOT +## - FONT +## - TEXT +## - LaTeX +## - AXES +## - DATES +## - TICKS +## - GRIDS +## - LEGEND +## - FIGURE +## - IMAGES +## - CONTOUR PLOTS +## - ERRORBAR PLOTS +## - HISTOGRAM PLOTS +## - SCATTER PLOTS +## - AGG RENDERING +## - PATHS +## - SAVING FIGURES +## - INTERACTIVE KEYMAPS +## - ANIMATION + +##### CONFIGURATION BEGINS HERE + + +## *************************************************************************** +## * BACKENDS * +## *************************************************************************** +## The default backend. If you omit this parameter, the first working +## backend from the following list is used: +## MacOSX QtAgg Gtk4Agg Gtk3Agg TkAgg WxAgg Agg +## Other choices include: +## QtCairo GTK4Cairo GTK3Cairo TkCairo WxCairo Cairo +## Qt5Agg Qt5Cairo Wx # deprecated. +## PS PDF SVG Template +## You can also deploy your own backend outside of Matplotlib by referring to +## the module name (which must be in the PYTHONPATH) as 'module://my_backend'. +##backend: Agg + +## The port to use for the web server in the WebAgg backend. +#webagg.port: 8988 + +## The address on which the WebAgg web server should be reachable +#webagg.address: 127.0.0.1 + +## If webagg.port is unavailable, a number of other random ports will +## be tried until one that is available is found. +#webagg.port_retries: 50 + +## When True, open the web browser to the plot that is shown +#webagg.open_in_browser: True + +## If you are running pyplot inside a GUI and your backend choice +## conflicts, we will automatically try to find a compatible one for +## you if backend_fallback is True +#backend_fallback: True + +#interactive: False +#figure.hooks: # list of dotted.module.name:dotted.callable.name +#toolbar: toolbar2 # {None, toolbar2, toolmanager} +#timezone: UTC # a pytz timezone string, e.g., US/Central or Europe/Paris + + +## *************************************************************************** +## * LINES * +## *************************************************************************** +## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.lines +## for more information on line properties. +#lines.linewidth: 1.5 # line width in points +#lines.linestyle: - # solid line +#lines.color: C0 # has no affect on plot(); see axes.prop_cycle +#lines.marker: None # the default marker +#lines.markerfacecolor: auto # the default marker face color +#lines.markeredgecolor: auto # the default marker edge color +#lines.markeredgewidth: 1.0 # the line width around the marker symbol +#lines.markersize: 6 # marker size, in points +#lines.dash_joinstyle: round # {miter, round, bevel} +#lines.dash_capstyle: butt # {butt, round, projecting} +#lines.solid_joinstyle: round # {miter, round, bevel} +#lines.solid_capstyle: projecting # {butt, round, projecting} +#lines.antialiased: True # render lines in antialiased (no jaggies) + +## The three standard dash patterns. These are scaled by the linewidth. +#lines.dashed_pattern: 3.7, 1.6 +#lines.dashdot_pattern: 6.4, 1.6, 1, 1.6 +#lines.dotted_pattern: 1, 1.65 +#lines.scale_dashes: True + +#markers.fillstyle: full # {full, left, right, bottom, top, none} + +#pcolor.shading: auto +#pcolormesh.snap: True # Whether to snap the mesh to pixel boundaries. This is + # provided solely to allow old test images to remain + # unchanged. Set to False to obtain the previous behavior. + +## *************************************************************************** +## * PATCHES * +## *************************************************************************** +## Patches are graphical objects that fill 2D space, like polygons or circles. +## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.patches +## for more information on patch properties. +#patch.linewidth: 1.0 # edge width in points. +#patch.facecolor: C0 +#patch.edgecolor: black # if forced, or patch is not filled +#patch.force_edgecolor: False # True to always use edgecolor +#patch.antialiased: True # render patches in antialiased (no jaggies) + + +## *************************************************************************** +## * HATCHES * +## *************************************************************************** +#hatch.color: black +#hatch.linewidth: 1.0 + + +## *************************************************************************** +## * BOXPLOT * +## *************************************************************************** +#boxplot.notch: False +#boxplot.vertical: True +#boxplot.whiskers: 1.5 +#boxplot.bootstrap: None +#boxplot.patchartist: False +#boxplot.showmeans: False +#boxplot.showcaps: True +#boxplot.showbox: True +#boxplot.showfliers: True +#boxplot.meanline: False + +#boxplot.flierprops.color: black +#boxplot.flierprops.marker: o +#boxplot.flierprops.markerfacecolor: none +#boxplot.flierprops.markeredgecolor: black +#boxplot.flierprops.markeredgewidth: 1.0 +#boxplot.flierprops.markersize: 6 +#boxplot.flierprops.linestyle: none +#boxplot.flierprops.linewidth: 1.0 + +#boxplot.boxprops.color: black +#boxplot.boxprops.linewidth: 1.0 +#boxplot.boxprops.linestyle: - + +#boxplot.whiskerprops.color: black +#boxplot.whiskerprops.linewidth: 1.0 +#boxplot.whiskerprops.linestyle: - + +#boxplot.capprops.color: black +#boxplot.capprops.linewidth: 1.0 +#boxplot.capprops.linestyle: - + +#boxplot.medianprops.color: C1 +#boxplot.medianprops.linewidth: 1.0 +#boxplot.medianprops.linestyle: - + +#boxplot.meanprops.color: C2 +#boxplot.meanprops.marker: ^ +#boxplot.meanprops.markerfacecolor: C2 +#boxplot.meanprops.markeredgecolor: C2 +#boxplot.meanprops.markersize: 6 +#boxplot.meanprops.linestyle: -- +#boxplot.meanprops.linewidth: 1.0 + + +## *************************************************************************** +## * FONT * +## *************************************************************************** +## The font properties used by `text.Text`. +## See https://matplotlib.org/stable/api/font_manager_api.html for more information +## on font properties. The 6 font properties used for font matching are +## given below with their default values. +## +## The font.family property can take either a single or multiple entries of any +## combination of concrete font names (not supported when rendering text with +## usetex) or the following five generic values: +## - 'serif' (e.g., Times), +## - 'sans-serif' (e.g., Helvetica), +## - 'cursive' (e.g., Zapf-Chancery), +## - 'fantasy' (e.g., Western), and +## - 'monospace' (e.g., Courier). +## Each of these values has a corresponding default list of font names +## (font.serif, etc.); the first available font in the list is used. Note that +## for font.serif, font.sans-serif, and font.monospace, the first element of +## the list (a DejaVu font) will always be used because DejaVu is shipped with +## Matplotlib and is thus guaranteed to be available; the other entries are +## left as examples of other possible values. +## +## The font.style property has three values: normal (or roman), italic +## or oblique. The oblique style will be used for italic, if it is not +## present. +## +## The font.variant property has two values: normal or small-caps. For +## TrueType fonts, which are scalable fonts, small-caps is equivalent +## to using a font size of 'smaller', or about 83 % of the current font +## size. +## +## The font.weight property has effectively 13 values: normal, bold, +## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as +## 400, and bold is 700. bolder and lighter are relative values with +## respect to the current weight. +## +## The font.stretch property has 11 values: ultra-condensed, +## extra-condensed, condensed, semi-condensed, normal, semi-expanded, +## expanded, extra-expanded, ultra-expanded, wider, and narrower. This +## property is not currently implemented. +## +## The font.size property is the default font size for text, given in points. +## 10 pt is the standard value. +## +## Note that font.size controls default text sizes. To configure +## special text sizes tick labels, axes, labels, title, etc., see the rc +## settings for axes and ticks. Special text sizes can be defined +## relative to font.size, using the following values: xx-small, x-small, +## small, medium, large, x-large, xx-large, larger, or smaller + +#font.family: sans-serif +#font.style: normal +#font.variant: normal +#font.weight: normal +#font.stretch: normal +#font.size: 10.0 + +#font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif +#font.sans-serif: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif +#font.cursive: Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, Comic Neue, Comic Sans MS, cursive +#font.fantasy: Chicago, Charcoal, Impact, Western, xkcd script, fantasy +#font.monospace: DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace + + +## *************************************************************************** +## * TEXT * +## *************************************************************************** +## The text properties used by `text.Text`. +## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.text +## for more information on text properties +#text.color: black + +## FreeType hinting flag ("foo" corresponds to FT_LOAD_FOO); may be one of the +## following (Proprietary Matplotlib-specific synonyms are given in parentheses, +## but their use is discouraged): +## - default: Use the font's native hinter if possible, else FreeType's auto-hinter. +## ("either" is a synonym). +## - no_autohint: Use the font's native hinter if possible, else don't hint. +## ("native" is a synonym.) +## - force_autohint: Use FreeType's auto-hinter. ("auto" is a synonym.) +## - no_hinting: Disable hinting. ("none" is a synonym.) +#text.hinting: force_autohint + +#text.hinting_factor: 8 # Specifies the amount of softness for hinting in the + # horizontal direction. A value of 1 will hint to full + # pixels. A value of 2 will hint to half pixels etc. +#text.kerning_factor: 0 # Specifies the scaling factor for kerning values. This + # is provided solely to allow old test images to remain + # unchanged. Set to 6 to obtain previous behavior. + # Values other than 0 or 6 have no defined meaning. +#text.antialiased: True # If True (default), the text will be antialiased. + # This only affects raster outputs. +#text.parse_math: True # Use mathtext if there is an even number of unescaped + # dollar signs. + + +## *************************************************************************** +## * LaTeX * +## *************************************************************************** +## For more information on LaTeX properties, see +## https://matplotlib.org/stable/users/explain/text/usetex.html +#text.usetex: False # use latex for all text handling. The following fonts + # are supported through the usual rc parameter settings: + # new century schoolbook, bookman, times, palatino, + # zapf chancery, charter, serif, sans-serif, helvetica, + # avant garde, courier, monospace, computer modern roman, + # computer modern sans serif, computer modern typewriter +#text.latex.preamble: # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES + # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP + # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO. + # text.latex.preamble is a single line of LaTeX code that + # will be passed on to the LaTeX system. It may contain + # any code that is valid for the LaTeX "preamble", i.e. + # between the "\documentclass" and "\begin{document}" + # statements. + # Note that it has to be put on a single line, which may + # become quite long. + # The following packages are always loaded with usetex, + # so beware of package collisions: + # geometry, inputenc, type1cm. + # PostScript (PSNFSS) font packages may also be + # loaded, depending on your font settings. + +## The following settings allow you to select the fonts in math mode. +#mathtext.fontset: dejavusans # Should be 'dejavusans' (default), + # 'dejavuserif', 'cm' (Computer Modern), 'stix', + # 'stixsans' or 'custom' +## "mathtext.fontset: custom" is defined by the mathtext.bf, .cal, .it, ... +## settings which map a TeX font name to a fontconfig font pattern. (These +## settings are not used for other font sets.) +#mathtext.bf: sans:bold +#mathtext.bfit: sans:italic:bold +#mathtext.cal: cursive +#mathtext.it: sans:italic +#mathtext.rm: sans +#mathtext.sf: sans +#mathtext.tt: monospace +#mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix' + # 'stixsans'] when a symbol cannot be found in one of the + # custom math fonts. Select 'None' to not perform fallback + # and replace the missing character by a dummy symbol. +#mathtext.default: it # The default font to use for math. + # Can be any of the LaTeX font names, including + # the special name "regular" for the same font + # used in regular text. + + +## *************************************************************************** +## * AXES * +## *************************************************************************** +## Following are default face and edge colors, default tick sizes, +## default font sizes for tick labels, and so on. See +## https://matplotlib.org/stable/api/axes_api.html#module-matplotlib.axes +#axes.facecolor: white # axes background color +#axes.edgecolor: black # axes edge color +#axes.linewidth: 0.8 # edge line width +#axes.grid: False # display grid or not +#axes.grid.axis: both # which axis the grid should apply to +#axes.grid.which: major # grid lines at {major, minor, both} ticks +#axes.titlelocation: center # alignment of the title: {left, right, center} +#axes.titlesize: large # font size of the axes title +#axes.titleweight: normal # font weight of title +#axes.titlecolor: auto # color of the axes title, auto falls back to + # text.color as default value +#axes.titley: None # position title (axes relative units). None implies auto +#axes.titlepad: 6.0 # pad between axes and title in points +#axes.labelsize: medium # font size of the x and y labels +#axes.labelpad: 4.0 # space between label and axis +#axes.labelweight: normal # weight of the x and y labels +#axes.labelcolor: black +#axes.axisbelow: line # draw axis gridlines and ticks: + # - below patches (True) + # - above patches but below lines ('line') + # - above all (False) + +#axes.formatter.limits: -5, 6 # use scientific notation if log10 + # of the axis range is smaller than the + # first or larger than the second +#axes.formatter.use_locale: False # When True, format tick labels + # according to the user's locale. + # For example, use ',' as a decimal + # separator in the fr_FR locale. +#axes.formatter.use_mathtext: False # When True, use mathtext for scientific + # notation. +#axes.formatter.min_exponent: 0 # minimum exponent to format in scientific notation +#axes.formatter.useoffset: True # If True, the tick label formatter + # will default to labeling ticks relative + # to an offset when the data range is + # small compared to the minimum absolute + # value of the data. +#axes.formatter.offset_threshold: 4 # When useoffset is True, the offset + # will be used when it can remove + # at least this number of significant + # digits from tick labels. + +#axes.spines.left: True # display axis spines +#axes.spines.bottom: True +#axes.spines.top: True +#axes.spines.right: True + +#axes.unicode_minus: True # use Unicode for the minus symbol rather than hyphen. See + # https://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes +#axes.prop_cycle: cycler('color', ['1f77b4', 'ff7f0e', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf']) + # color cycle for plot lines as list of string color specs: + # single letter, long name, or web-style hex + # As opposed to all other parameters in this file, the color + # values must be enclosed in quotes for this parameter, + # e.g. '1f77b4', instead of 1f77b4. + # See also https://matplotlib.org/stable/users/explain/artists/color_cycle.html + # for more details on prop_cycle usage. +#axes.xmargin: .05 # x margin. See `axes.Axes.margins` +#axes.ymargin: .05 # y margin. See `axes.Axes.margins` +#axes.zmargin: .05 # z margin. See `axes.Axes.margins` +#axes.autolimit_mode: data # If "data", use axes.xmargin and axes.ymargin as is. + # If "round_numbers", after application of margins, axis + # limits are further expanded to the nearest "round" number. +#polaraxes.grid: True # display grid on polar axes +#axes3d.grid: True # display grid on 3D axes + +#axes3d.xaxis.panecolor: (0.95, 0.95, 0.95, 0.5) # background pane on 3D axes +#axes3d.yaxis.panecolor: (0.90, 0.90, 0.90, 0.5) # background pane on 3D axes +#axes3d.zaxis.panecolor: (0.925, 0.925, 0.925, 0.5) # background pane on 3D axes + +## *************************************************************************** +## * AXIS * +## *************************************************************************** +#xaxis.labellocation: center # alignment of the xaxis label: {left, right, center} +#yaxis.labellocation: center # alignment of the yaxis label: {bottom, top, center} + + +## *************************************************************************** +## * DATES * +## *************************************************************************** +## These control the default format strings used in AutoDateFormatter. +## Any valid format datetime format string can be used (see the python +## `datetime` for details). For example, by using: +## - '%x' will use the locale date representation +## - '%X' will use the locale time representation +## - '%c' will use the full locale datetime representation +## These values map to the scales: +## {'year': 365, 'month': 30, 'day': 1, 'hour': 1/24, 'minute': 1 / (24 * 60)} + +#date.autoformatter.year: %Y +#date.autoformatter.month: %Y-%m +#date.autoformatter.day: %Y-%m-%d +#date.autoformatter.hour: %m-%d %H +#date.autoformatter.minute: %d %H:%M +#date.autoformatter.second: %H:%M:%S +#date.autoformatter.microsecond: %M:%S.%f +## The reference date for Matplotlib's internal date representation +## See https://matplotlib.org/stable/gallery/ticks/date_precision_and_epochs.html +#date.epoch: 1970-01-01T00:00:00 +## 'auto', 'concise': +#date.converter: auto +## For auto converter whether to use interval_multiples: +#date.interval_multiples: True + +## *************************************************************************** +## * TICKS * +## *************************************************************************** +## See https://matplotlib.org/stable/api/axis_api.html#matplotlib.axis.Tick +#xtick.top: False # draw ticks on the top side +#xtick.bottom: True # draw ticks on the bottom side +#xtick.labeltop: False # draw label on the top +#xtick.labelbottom: True # draw label on the bottom +#xtick.major.size: 3.5 # major tick size in points +#xtick.minor.size: 2 # minor tick size in points +#xtick.major.width: 0.8 # major tick width in points +#xtick.minor.width: 0.6 # minor tick width in points +#xtick.major.pad: 3.5 # distance to major tick label in points +#xtick.minor.pad: 3.4 # distance to the minor tick label in points +#xtick.color: black # color of the ticks +#xtick.labelcolor: inherit # color of the tick labels or inherit from xtick.color +#xtick.labelsize: medium # font size of the tick labels +#xtick.direction: out # direction: {in, out, inout} +#xtick.minor.visible: False # visibility of minor ticks on x-axis +#xtick.major.top: True # draw x axis top major ticks +#xtick.major.bottom: True # draw x axis bottom major ticks +#xtick.minor.top: True # draw x axis top minor ticks +#xtick.minor.bottom: True # draw x axis bottom minor ticks +#xtick.minor.ndivs: auto # number of minor ticks between the major ticks on x-axis +#xtick.alignment: center # alignment of xticks + +#ytick.left: True # draw ticks on the left side +#ytick.right: False # draw ticks on the right side +#ytick.labelleft: True # draw tick labels on the left side +#ytick.labelright: False # draw tick labels on the right side +#ytick.major.size: 3.5 # major tick size in points +#ytick.minor.size: 2 # minor tick size in points +#ytick.major.width: 0.8 # major tick width in points +#ytick.minor.width: 0.6 # minor tick width in points +#ytick.major.pad: 3.5 # distance to major tick label in points +#ytick.minor.pad: 3.4 # distance to the minor tick label in points +#ytick.color: black # color of the ticks +#ytick.labelcolor: inherit # color of the tick labels or inherit from ytick.color +#ytick.labelsize: medium # font size of the tick labels +#ytick.direction: out # direction: {in, out, inout} +#ytick.minor.visible: False # visibility of minor ticks on y-axis +#ytick.major.left: True # draw y axis left major ticks +#ytick.major.right: True # draw y axis right major ticks +#ytick.minor.left: True # draw y axis left minor ticks +#ytick.minor.right: True # draw y axis right minor ticks +#ytick.minor.ndivs: auto # number of minor ticks between the major ticks on y-axis +#ytick.alignment: center_baseline # alignment of yticks + + +## *************************************************************************** +## * GRIDS * +## *************************************************************************** +#grid.color: "#b0b0b0" # grid color +#grid.linestyle: - # solid +#grid.linewidth: 0.8 # in points +#grid.alpha: 1.0 # transparency, between 0.0 and 1.0 + + +## *************************************************************************** +## * LEGEND * +## *************************************************************************** +#legend.loc: best +#legend.frameon: True # if True, draw the legend on a background patch +#legend.framealpha: 0.8 # legend patch transparency +#legend.facecolor: inherit # inherit from axes.facecolor; or color spec +#legend.edgecolor: 0.8 # background patch boundary color +#legend.fancybox: True # if True, use a rounded box for the + # legend background, else a rectangle +#legend.shadow: False # if True, give background a shadow effect +#legend.numpoints: 1 # the number of marker points in the legend line +#legend.scatterpoints: 1 # number of scatter points +#legend.markerscale: 1.0 # the relative size of legend markers vs. original +#legend.fontsize: medium +#legend.labelcolor: None +#legend.title_fontsize: None # None sets to the same as the default axes. + +## Dimensions as fraction of font size: +#legend.borderpad: 0.4 # border whitespace +#legend.labelspacing: 0.5 # the vertical space between the legend entries +#legend.handlelength: 2.0 # the length of the legend lines +#legend.handleheight: 0.7 # the height of the legend handle +#legend.handletextpad: 0.8 # the space between the legend line and legend text +#legend.borderaxespad: 0.5 # the border between the axes and legend edge +#legend.columnspacing: 2.0 # column separation + + +## *************************************************************************** +## * FIGURE * +## *************************************************************************** +## See https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure +#figure.titlesize: large # size of the figure title (``Figure.suptitle()``) +#figure.titleweight: normal # weight of the figure title +#figure.labelsize: large # size of the figure label (``Figure.sup[x|y]label()``) +#figure.labelweight: normal # weight of the figure label +#figure.figsize: 6.4, 4.8 # figure size in inches +#figure.dpi: 100 # figure dots per inch +#figure.facecolor: white # figure face color +#figure.edgecolor: white # figure edge color +#figure.frameon: True # enable figure frame +#figure.max_open_warning: 20 # The maximum number of figures to open through + # the pyplot interface before emitting a warning. + # If less than one this feature is disabled. +#figure.raise_window : True # Raise the GUI window to front when show() is called. + +## The figure subplot parameters. All dimensions are a fraction of the figure width and height. +#figure.subplot.left: 0.125 # the left side of the subplots of the figure +#figure.subplot.right: 0.9 # the right side of the subplots of the figure +#figure.subplot.bottom: 0.11 # the bottom of the subplots of the figure +#figure.subplot.top: 0.88 # the top of the subplots of the figure +#figure.subplot.wspace: 0.2 # the amount of width reserved for space between subplots, + # expressed as a fraction of the average axis width +#figure.subplot.hspace: 0.2 # the amount of height reserved for space between subplots, + # expressed as a fraction of the average axis height + +## Figure layout +#figure.autolayout: False # When True, automatically adjust subplot + # parameters to make the plot fit the figure + # using `tight_layout` +#figure.constrained_layout.use: False # When True, automatically make plot + # elements fit on the figure. (Not + # compatible with `autolayout`, above). +## Padding (in inches) around axes; defaults to 3/72 inches, i.e. 3 points. +#figure.constrained_layout.h_pad: 0.04167 +#figure.constrained_layout.w_pad: 0.04167 +## Spacing between subplots, relative to the subplot sizes. Much smaller than for +## tight_layout (figure.subplot.hspace, figure.subplot.wspace) as constrained_layout +## already takes surrounding texts (titles, labels, # ticklabels) into account. +#figure.constrained_layout.hspace: 0.02 +#figure.constrained_layout.wspace: 0.02 + + +## *************************************************************************** +## * IMAGES * +## *************************************************************************** +#image.aspect: equal # {equal, auto} or a number +#image.interpolation: antialiased # see help(imshow) for options +#image.cmap: viridis # A colormap name (plasma, magma, etc.) +#image.lut: 256 # the size of the colormap lookup table +#image.origin: upper # {lower, upper} +#image.resample: True +#image.composite_image: True # When True, all the images on a set of axes are + # combined into a single composite image before + # saving a figure as a vector graphics file, + # such as a PDF. + + +## *************************************************************************** +## * CONTOUR PLOTS * +## *************************************************************************** +#contour.negative_linestyle: dashed # string or on-off ink sequence +#contour.corner_mask: True # {True, False} +#contour.linewidth: None # {float, None} Size of the contour line + # widths. If set to None, it falls back to + # `line.linewidth`. +#contour.algorithm: mpl2014 # {mpl2005, mpl2014, serial, threaded} + + +## *************************************************************************** +## * ERRORBAR PLOTS * +## *************************************************************************** +#errorbar.capsize: 0 # length of end cap on error bars in pixels + + +## *************************************************************************** +## * HISTOGRAM PLOTS * +## *************************************************************************** +#hist.bins: 10 # The default number of histogram bins or 'auto'. + + +## *************************************************************************** +## * SCATTER PLOTS * +## *************************************************************************** +#scatter.marker: o # The default marker type for scatter plots. +#scatter.edgecolors: face # The default edge colors for scatter plots. + + +## *************************************************************************** +## * AGG RENDERING * +## *************************************************************************** +## Warning: experimental, 2008/10/10 +#agg.path.chunksize: 0 # 0 to disable; values in the range + # 10000 to 100000 can improve speed slightly + # and prevent an Agg rendering failure + # when plotting very large data sets, + # especially if they are very gappy. + # It may cause minor artifacts, though. + # A value of 20000 is probably a good + # starting point. + + +## *************************************************************************** +## * PATHS * +## *************************************************************************** +#path.simplify: True # When True, simplify paths by removing "invisible" + # points to reduce file size and increase rendering + # speed +#path.simplify_threshold: 0.111111111111 # The threshold of similarity below + # which vertices will be removed in + # the simplification process. +#path.snap: True # When True, rectilinear axis-aligned paths will be snapped + # to the nearest pixel when certain criteria are met. + # When False, paths will never be snapped. +#path.sketch: None # May be None, or a 3-tuple of the form: + # (scale, length, randomness). + # - *scale* is the amplitude of the wiggle + # perpendicular to the line (in pixels). + # - *length* is the length of the wiggle along the + # line (in pixels). + # - *randomness* is the factor by which the length is + # randomly scaled. +#path.effects: + + +## *************************************************************************** +## * SAVING FIGURES * +## *************************************************************************** +## The default savefig parameters can be different from the display parameters +## e.g., you may want a higher resolution, or to make the figure +## background white +#savefig.dpi: figure # figure dots per inch or 'figure' +#savefig.facecolor: auto # figure face color when saving +#savefig.edgecolor: auto # figure edge color when saving +#savefig.format: png # {png, ps, pdf, svg} +#savefig.bbox: standard # {tight, standard} + # 'tight' is incompatible with generating frames + # for animation +#savefig.pad_inches: 0.1 # padding to be used, when bbox is set to 'tight' +#savefig.directory: ~ # default directory in savefig dialog, gets updated after + # interactive saves, unless set to the empty string (i.e. + # the current directory); use '.' to start at the current + # directory but update after interactive saves +#savefig.transparent: False # whether figures are saved with a transparent + # background by default +#savefig.orientation: portrait # orientation of saved figure, for PostScript output only + +### macosx backend params +#macosx.window_mode : system # How to open new figures (system, tab, window) + # system uses the MacOS system preferences + +### tk backend params +#tk.window_focus: False # Maintain shell focus for TkAgg + +### ps backend params +#ps.papersize: letter # {figure, letter, legal, ledger, A0-A10, B0-B10} +#ps.useafm: False # use AFM fonts, results in small files +#ps.usedistiller: False # {ghostscript, xpdf, None} + # Experimental: may produce smaller files. + # xpdf intended for production of publication quality files, + # but requires ghostscript, xpdf and ps2eps +#ps.distiller.res: 6000 # dpi +#ps.fonttype: 3 # Output Type 3 (Type3) or Type 42 (TrueType) + +### PDF backend params +#pdf.compression: 6 # integer from 0 to 9 + # 0 disables compression (good for debugging) +#pdf.fonttype: 3 # Output Type 3 (Type3) or Type 42 (TrueType) +#pdf.use14corefonts: False +#pdf.inheritcolor: False + +### SVG backend params +#svg.image_inline: True # Write raster image data directly into the SVG file +#svg.fonttype: path # How to handle SVG fonts: + # path: Embed characters as paths -- supported + # by most SVG renderers + # None: Assume fonts are installed on the + # machine where the SVG will be viewed. +#svg.hashsalt: None # If not None, use this string as hash salt instead of uuid4 + +### pgf parameter +## See https://matplotlib.org/stable/tutorials/text/pgf.html for more information. +#pgf.rcfonts: True +#pgf.preamble: # See text.latex.preamble for documentation +#pgf.texsystem: xelatex + +### docstring params +#docstring.hardcopy: False # set this when you want to generate hardcopy docstring + + +## *************************************************************************** +## * INTERACTIVE KEYMAPS * +## *************************************************************************** +## Event keys to interact with figures/plots via keyboard. +## See https://matplotlib.org/stable/users/explain/interactive.html for more +## details on interactive navigation. Customize these settings according to +## your needs. Leave the field(s) empty if you don't need a key-map. (i.e., +## fullscreen : '') +#keymap.fullscreen: f, ctrl+f # toggling +#keymap.home: h, r, home # home or reset mnemonic +#keymap.back: left, c, backspace, MouseButton.BACK # forward / backward keys +#keymap.forward: right, v, MouseButton.FORWARD # for quick navigation +#keymap.pan: p # pan mnemonic +#keymap.zoom: o # zoom mnemonic +#keymap.save: s, ctrl+s # saving current figure +#keymap.help: f1 # display help about active tools +#keymap.quit: ctrl+w, cmd+w, q # close the current figure +#keymap.quit_all: # close all figures +#keymap.grid: g # switching on/off major grids in current axes +#keymap.grid_minor: G # switching on/off minor grids in current axes +#keymap.yscale: l # toggle scaling of y-axes ('log'/'linear') +#keymap.xscale: k, L # toggle scaling of x-axes ('log'/'linear') +#keymap.copy: ctrl+c, cmd+c # copy figure to clipboard + + +## *************************************************************************** +## * ANIMATION * +## *************************************************************************** +#animation.html: none # How to display the animation as HTML in + # the IPython notebook: + # - 'html5' uses HTML5 video tag + # - 'jshtml' creates a JavaScript animation +#animation.writer: ffmpeg # MovieWriter 'backend' to use +#animation.codec: h264 # Codec to use for writing movie +#animation.bitrate: -1 # Controls size/quality trade-off for movie. + # -1 implies let utility auto-determine +#animation.frame_format: png # Controls frame format used by temp files + +## Path to ffmpeg binary. Unqualified paths are resolved by subprocess.Popen. +#animation.ffmpeg_path: ffmpeg +## Additional arguments to pass to ffmpeg. +#animation.ffmpeg_args: + +## Path to ImageMagick's convert binary. Unqualified paths are resolved by +## subprocess.Popen, except that on Windows, we look up an install of +## ImageMagick in the registry (as convert is also the name of a system tool). +#animation.convert_path: convert +## Additional arguments to pass to convert. +#animation.convert_args: -layers, OptimizePlus +# +#animation.embed_limit: 20.0 # Limit, in MB, of size of base64 encoded + # animation in HTML (i.e. IPython notebook) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/plot_directive/plot_directive.css b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/plot_directive/plot_directive.css new file mode 100644 index 00000000..d45593c9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/plot_directive/plot_directive.css @@ -0,0 +1,16 @@ +/* + * plot_directive.css + * ~~~~~~~~~~~~ + * + * Stylesheet controlling images created using the `plot` directive within + * Sphinx. + * + * :copyright: Copyright 2020-* by the Matplotlib development team. + * :license: Matplotlib, see LICENSE for details. + * + */ + +img.plot-directive { + border: 0; + max-width: 100%; +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png new file mode 100644 index 0000000000000000000000000000000000000000..2b1aff4e3c4b050e2f00a1ed34dbfee8a4558db2 GIT binary patch literal 13634 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/README.txt b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/README.txt new file mode 100644 index 00000000..75a53495 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/README.txt @@ -0,0 +1,2 @@ +This is the sample data needed for some of matplotlib's examples and +docs. See matplotlib.cbook.get_sample_data for more info. diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Stocks.csv b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Stocks.csv new file mode 100644 index 00000000..575d353d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/Stocks.csv @@ -0,0 +1,526 @@ +# Data source: https://finance.yahoo.com +Date,IBM,AAPL,MSFT,XRX,AMZN,DELL,GOOGL,ADBE,^GSPC,^IXIC +1990-01-01,10.970438003540039,0.24251236021518707,0.40375930070877075,11.202081680297852,,,,1.379060983657837,329.0799865722656,415.79998779296875 +1990-02-01,11.554415702819824,0.24251236021518707,0.43104037642478943,10.39472484588623,,,,1.7790844440460205,331.8900146484375,425.79998779296875 +1990-02-05,,,,,,,,,, +1990-03-01,11.951693534851074,0.28801724314689636,0.4834197461605072,11.394058227539062,,,,2.2348830699920654,339.94000244140625,435.5 +1990-04-01,12.275476455688477,0.2817564308643341,0.5063362717628479,10.139430046081543,,,,2.2531447410583496,330.79998779296875,420.1000061035156 +1990-05-01,13.514284133911133,0.295173317193985,0.6372847557067871,9.704153060913086,,,,2.0985164642333984,361.2300109863281,459.0 +1990-05-04,,,,,,,,,, +1990-06-01,13.380948066711426,0.3211067020893097,0.6634747385978699,9.749448776245117,,,,2.164785146713257,358.0199890136719,462.29998779296875 +1990-07-01,12.697657585144043,0.3013734817504883,0.5805402994155884,9.489465713500977,,,,2.069063901901245,356.1499938964844,438.20001220703125 +1990-08-01,11.601561546325684,0.26549553871154785,0.5368908047676086,8.553519248962402,,,,1.4750508069992065,322.55999755859375,381.20001220703125 +1990-08-06,,,,,,,,,, +1990-09-01,12.251119613647461,0.20872052013874054,0.5499854683876038,7.255113124847412,,,,1.1210384368896484,306.04998779296875,344.5 +1990-10-01,12.15034294128418,0.22131578624248505,0.5565334558486938,6.248927116394043,,,,1.416249394416809,304.0,329.79998779296875 +1990-11-01,13.08609390258789,0.26449888944625854,0.6307373642921448,7.361023426055908,,,,1.4900128841400146,322.2200012207031,359.1000061035156 +1990-11-05,,,,,,,,,, +1990-12-01,13.161062240600586,0.31051647663116455,0.6569272875785828,7.519896507263184,,,,1.7186784744262695,330.2200012207031,373.79998779296875 +1991-01-01,14.762505531311035,0.40078282356262207,0.8566243648529053,10.554410934448242,,,,2.242394208908081,343.92999267578125,414.20001220703125 +1991-02-01,14.995450973510742,0.4134202301502228,0.9057300686836243,12.286416053771973,,,,2.8402483463287354,367.07000732421875,453.1000061035156 +1991-02-04,,,,,,,,,, +1991-03-01,13.39067268371582,0.49208223819732666,0.92646324634552,12.511940002441406,,,,3.1869795322418213,375.2200012207031,482.29998779296875 +1991-04-01,12.111870765686035,0.39800751209259033,0.8642628788948059,12.511940002441406,,,,3.0589873790740967,375.3399963378906,484.7200012207031 +1991-05-01,12.479341506958008,0.34011581540107727,0.9581103920936584,12.73144817352295,,,,2.9850986003875732,389.8299865722656,506.1099853515625 +1991-05-06,,,,,,,,,, +1991-06-01,11.555957794189453,0.30108359456062317,0.89208984375,11.853414535522461,,,,2.5565452575683594,371.1600036621094,475.9200134277344 +1991-07-01,12.04675579071045,0.33554431796073914,0.9624748229980469,12.397871017456055,,,,3.1678967475891113,387.80999755859375,502.0400085449219 +1991-08-01,11.526222229003906,0.3845158815383911,1.1163398027420044,13.037229537963867,,,,3.012463331222534,395.42999267578125,525.6799926757812 +1991-08-06,,,,,,,,,, +1991-09-01,12.478833198547363,0.3599340617656708,1.1654454469680786,13.740047454833984,,,,3.0346662998199463,387.8599853515625,526.8800048828125 +1991-10-01,11.83155345916748,0.37447676062583923,1.2292828559875488,14.41578483581543,,,,3.1431360244750977,392.45001220703125,542.97998046875 +1991-11-01,11.139124870300293,0.36902356147766113,1.2734787464141846,13.965290069580078,,,,2.846613883972168,375.2200012207031,523.9000244140625 +1991-11-04,,,,,,,,,, +1991-12-01,10.851117134094238,0.4109107553958893,1.4568067789077759,15.42939281463623,,,,3.8844411373138428,417.0899963378906,586.3400268554688 +1992-01-01,10.973037719726562,0.4719553291797638,1.5746610164642334,17.584869384765625,,,,3.639812469482422,408.7799987792969,620.2100219726562 +1992-02-01,10.592026710510254,0.49199995398521423,1.61721932888031,18.04088020324707,,,,3.3547844886779785,412.70001220703125,633.469970703125 +1992-02-06,,,,,,,,,, +1992-03-01,10.317353248596191,0.4253714978694916,1.5517452955245972,16.302349090576172,,,,3.043056011199951,403.69000244140625,603.77001953125 +1992-04-01,11.213163375854492,0.43906375765800476,1.4437123537063599,17.062589645385742,,,,2.631263494491577,414.95001220703125,578.6799926757812 +1992-05-01,11.213163375854492,0.4363253116607666,1.5844820737838745,17.263996124267578,,,,2.705594062805176,415.3500061035156,585.3099975585938 +1992-05-07,,,,,,,,,, +1992-06-01,12.25231647491455,0.3505205810070038,1.3749638795852661,16.055517196655273,,,,2.705594062805176,408.1400146484375,563.5999755859375 +1992-07-01,11.861115455627441,0.34207984805107117,1.4289811849594116,17.38025665283203,,,,2.263554334640503,424.2099914550781,580.8300170898438 +1992-08-01,10.84400749206543,0.33659130334854126,1.4633547067642212,17.525571823120117,,,,1.9359338283538818,414.0299987792969,563.1199951171875 +1992-08-06,,,,,,,,,, +1992-09-01,10.243829727172852,0.3310767114162445,1.58120858669281,18.464359283447266,,,,1.6753284931182861,417.79998779296875,583.27001953125 +1992-10-01,8.483662605285645,0.38518592715263367,1.7432584762573242,17.436922073364258,,,,2.12785267829895,418.67999267578125,605.1699829101562 +1992-11-01,8.658098220825195,0.42187052965164185,1.8291932344436646,18.493711471557617,,,,2.030792474746704,431.3500061035156,652.72998046875 +1992-11-05,,,,,,,,,, +1992-12-01,6.505843639373779,0.43931084871292114,1.6769649982452393,18.788379669189453,,,,1.8814688920974731,435.7099914550781,676.9500122070312 +1993-01-01,6.651134490966797,0.43747296929359436,1.6990629434585571,20.329378128051758,,,,2.4787611961364746,438.7799987792969,696.3400268554688 +1993-02-01,7.022435188293457,0.38968151807785034,1.6376806497573853,19.618152618408203,,,,2.670894145965576,443.3800048828125,670.77001953125 +1993-02-04,,,,,,,,,, +1993-03-01,6.6405534744262695,0.37947842478752136,1.8169171810150146,19.766319274902344,,,,2.573633909225464,451.6700134277344,690.1300048828125 +1993-04-01,6.346868991851807,0.3776364326477051,1.6794201135635376,18.451818466186523,,,,3.434307336807251,440.19000244140625,661.4199829101562 +1993-05-01,6.885295867919922,0.4172421991825104,1.8193715810775757,18.12286949157715,,,,3.959200859069824,450.19000244140625,700.530029296875 +1993-05-06,,,,,,,,,, +1993-06-01,6.51603364944458,0.29166528582572937,1.7285257577896118,19.299583435058594,,,,3.7042527198791504,450.5299987792969,703.9500122070312 +1993-07-01,5.872671604156494,0.2049039751291275,1.453533411026001,17.638439178466797,,,,2.9742372035980225,448.1300048828125,704.7000122070312 +1993-08-01,6.037637233734131,0.19567380845546722,1.4756313562393188,17.759246826171875,,,,2.5536391735076904,463.55999755859375,742.8400268554688 +1993-08-05,,,,,,,,,, +1993-09-01,5.574150562286377,0.1733584851026535,1.620492935180664,17.849544525146484,,,,2.1931254863739014,458.92999267578125,762.780029296875 +1993-10-01,6.105024337768555,0.22805523872375488,1.5738422870635986,19.34462547302246,,,,2.6137242317199707,467.8299865722656,779.260009765625 +1993-11-01,7.150176048278809,0.2336171418428421,1.5713871717453003,20.107433319091797,,,,2.786593437194824,461.7900085449219,754.3900146484375 +1993-11-04,,,,,,,,,, +1993-12-01,7.535686016082764,0.21771006286144257,1.5836634635925293,22.01595687866211,,,,2.68115496635437,466.45001220703125,776.7999877929688 +1994-01-01,7.535686016082764,0.24376071989536285,1.672054648399353,24.171361923217773,,,,3.64516544342041,481.6099853515625,800.469970703125 +1994-02-01,7.052198886871338,0.27167221903800964,1.620492935180664,23.894229888916016,,,,3.5310842990875244,467.1400146484375,792.5 +1994-02-04,,,,,,,,,, +1994-03-01,7.31842041015625,0.24837146699428558,1.6646885871887207,23.706161499023438,,,,2.9274797439575195,445.7699890136719,743.4600219726562 +1994-04-01,7.703606128692627,0.22409436106681824,1.8169171810150146,24.543949127197266,,,,3.2354440689086914,450.9100036621094,733.8400268554688 +1994-05-01,8.440468788146973,0.21849241852760315,2.1115520000457764,24.947307586669922,,,,3.4773480892181396,456.5,735.1900024414062 +1994-05-05,,,,,,,,,, +1994-06-01,7.905290126800537,0.19873161613941193,2.028071165084839,24.444643020629883,,,,3.2959203720092773,444.2699890136719,705.9600219726562 +1994-07-01,8.325791358947754,0.2526327669620514,2.023160934448242,25.569963455200195,,,,3.756444215774536,458.260009765625,722.1599731445312 +1994-08-01,9.217235565185547,0.27138155698776245,2.2834222316741943,26.789077758789062,,,,3.847325563430786,475.489990234375,765.6199951171875 +1994-08-04,,,,,,,,,, +1994-09-01,9.405942916870117,0.25350791215896606,2.2048532962799072,26.88198471069336,,,,3.9382081031799316,462.7099914550781,764.2899780273438 +1994-10-01,10.064526557922363,0.324998676776886,2.474935293197632,25.811735153198242,,,,4.368794918060303,472.3500061035156,777.489990234375 +1994-11-01,9.557921409606934,0.28031668066978455,2.470024824142456,24.741479873657227,,,,4.004726409912109,453.69000244140625,750.3200073242188 +1994-11-04,,,,,,,,,, +1994-12-01,9.9633207321167,0.2943686842918396,2.401276111602783,25.12115478515625,,,,3.6103241443634033,459.2699890136719,751.9600219726562 +1995-01-01,9.77692985534668,0.3047473132610321,2.332528591156006,27.753808975219727,,,,3.5117223262786865,470.4200134277344,755.2000122070312 +1995-02-01,10.200541496276855,0.29814332723617554,2.474935293197632,28.13443946838379,,,,4.345465660095215,487.3900146484375,793.72998046875 +1995-02-06,,,,,,,,,, +1995-03-01,11.169903755187988,0.2667955756187439,2.7941226959228516,29.989917755126953,,,,6.016797065734863,500.7099914550781,817.2100219726562 +1995-04-01,12.870043754577637,0.2895018756389618,3.2115228176116943,31.52293586730957,,,,7.08742618560791,514.7100219726562,843.97998046875 +1995-05-01,12.649023056030273,0.31457316875457764,3.326920747756958,28.96788215637207,,,,6.326970100402832,533.4000244140625,864.5800170898438 +1995-05-04,,,,,,,,,, +1995-06-01,13.091790199279785,0.3524453043937683,3.5503528118133545,30.15083122253418,,,,7.057007789611816,544.75,933.4500122070312 +1995-07-01,14.847586631774902,0.3415350615978241,3.5552642345428467,30.697277069091797,,,,7.513277530670166,562.0599975585938,1001.2100219726562 +1995-08-01,14.09753131866455,0.32635587453842163,3.6338343620300293,31.08300018310547,,,,6.210629463195801,561.8800048828125,1020.1099853515625 +1995-08-08,,,,,,,,,, +1995-09-01,12.916881561279297,0.28348639607429504,3.5552642345428467,34.767181396484375,,,,6.301961898803711,584.4099731445312,1043.5400390625 +1995-10-01,13.292764663696289,0.27635207772254944,3.92846941947937,33.5381965637207,,,,6.941293239593506,581.5,1036.06005859375 +1995-11-01,13.207347869873047,0.2901458144187927,3.4226772785186768,35.478694915771484,,,,8.243063926696777,605.3699951171875,1059.199951171875 +1995-11-08,,,,,,,,,, +1995-12-01,12.52143669128418,0.24333631992340088,3.447230815887451,35.68303298950195,,,,7.557409763336182,615.9299926757812,1052.1300048828125 +1996-01-01,14.868143081665039,0.21089188754558563,3.6338343620300293,32.199371337890625,,,,4.14438533782959,636.02001953125,1059.7900390625 +1996-02-01,16.80373764038086,0.2099376916885376,3.876908779144287,33.924922943115234,,,,4.089058876037598,640.4299926757812,1100.050048828125 +1996-02-07,,,,,,,,,, +1996-03-01,15.278267860412598,0.1875123232603073,4.051232814788818,32.900360107421875,,,,3.936483860015869,645.5,1101.4000244140625 +1996-04-01,14.797598838806152,0.1860809624195099,4.448990821838379,38.40559768676758,,,,5.248644828796387,654.1699829101562,1190.52001953125 +1996-05-01,14.660264015197754,0.1994406133890152,4.6650567054748535,41.25652313232422,,,,4.538435459136963,669.1199951171875,1243.4300537109375 +1996-05-08,,,,,,,,,, +1996-06-01,13.641029357910156,0.1603158563375473,4.719073295593262,42.07575225830078,,,,4.385625839233398,670.6300048828125,1185.02001953125 +1996-07-01,14.812233924865723,0.1679503321647644,4.630680561065674,39.836021423339844,,,,3.7132644653320312,639.9500122070312,1080.5899658203125 +1996-08-01,15.759532928466797,0.18512675166130066,4.812370777130127,43.394588470458984,,,,4.269299030303955,651.989990234375,1141.5 +1996-08-07,,,,,,,,,, +1996-09-01,17.209583282470703,0.16938161849975586,5.180670261383057,42.40607833862305,,,,4.5600385665893555,687.3300170898438,1226.9200439453125 +1996-10-01,17.831613540649414,0.17558389902114868,5.391822814941406,36.86507034301758,,,,4.244296073913574,705.27001953125,1221.510009765625 +1996-11-01,22.03032875061035,0.184172585606575,6.162785530090332,38.95176315307617,,,,4.841867923736572,757.02001953125,1292.6099853515625 +1996-11-06,,,,,,,,,, +1996-12-01,20.998197555541992,0.15936164557933807,6.491794109344482,41.83340072631836,,,,4.581387996673584,740.739990234375,1291.030029296875 +1997-01-01,21.743183135986328,0.12691716849803925,8.01407527923584,46.8797492980957,,,,4.642676830291748,786.1599731445312,1379.8499755859375 +1997-02-01,19.924028396606445,0.1240537017583847,7.660515785217285,49.97840881347656,,,,4.47982120513916,790.8200073242188,1309.0 +1997-02-06,,,,,,,,,, +1997-03-01,19.067983627319336,0.13932174444198608,7.203826904296875,45.4803581237793,,,,4.924733638763428,757.1199951171875,1221.699951171875 +1997-04-01,22.298084259033203,0.12977975606918335,9.546177864074707,49.431339263916016,,,,4.807621955871582,801.3400268554688,1260.760009765625 +1997-05-01,24.034704208374023,0.12691716849803925,9.742606163024902,54.45485305786133,,,,5.483453750610352,848.280029296875,1400.3199462890625 +1997-05-07,,,,,,,,,, +1997-05-28,,,,,,,,,, +1997-06-01,25.13742446899414,0.10878564417362213,9.929201126098633,63.396705627441406,0.07708299905061722,,,4.3084282875061035,885.1400146484375,1442.0699462890625 +1997-07-01,29.45465660095215,0.1335965245962143,11.107746124267578,66.42845916748047,0.11979199945926666,,,4.592585563659668,954.3099975585938,1593.81005859375 +1997-08-01,28.23609161376953,0.1660410314798355,10.385887145996094,60.97687911987305,0.11692699790000916,,,4.851738929748535,899.469970703125,1587.3199462890625 +1997-08-07,,,,,,,,,, +1997-09-01,29.579116821289062,0.16556398570537567,10.395710945129395,67.9932632446289,0.21692700684070587,,,6.2071452140808105,947.280029296875,1685.68994140625 +1997-10-01,27.48627281188965,0.13001829385757446,10.214018821716309,64.32245635986328,0.25416699051856995,,,5.889601707458496,914.6199951171875,1593.6099853515625 +1997-11-01,30.555805206298828,0.13550494611263275,11.117568969726562,63.00460433959961,0.20624999701976776,,,5.180382251739502,955.4000244140625,1600.550048828125 +1997-11-06,,,,,,,,,, +1997-12-01,29.25237274169922,0.10019782930612564,10.155089378356934,59.91267013549805,0.2510420083999634,,,5.087874889373779,970.4299926757812,1570.3499755859375 +1998-01-01,27.609769821166992,0.1397988647222519,11.721570014953613,65.44635009765625,0.24583299458026886,,,4.750911235809326,980.280029296875,1619.3599853515625 +1998-02-01,29.19993782043457,0.1803557574748993,13.317505836486816,72.36756134033203,0.3208329975605011,,,5.452751159667969,1049.3399658203125,1770.510009765625 +1998-02-06,,,,,,,,,, +1998-03-01,29.10112953186035,0.2099376916885376,14.06391716003418,86.66805267333984,0.35637998580932617,,,5.576151371002197,1101.75,1835.6800537109375 +1998-04-01,32.4630012512207,0.20898354053497314,14.162128448486328,92.79229736328125,0.3822920024394989,,,6.177727699279785,1111.75,1868.4100341796875 +1998-05-01,32.918251037597656,0.2032574564218521,13.327329635620117,84.10579681396484,0.3671880066394806,,,4.930263519287109,1090.8199462890625,1778.8699951171875 +1998-05-06,,,,,,,,,, +1998-06-01,32.225502014160156,0.2190026193857193,17.029911041259766,83.08383178710938,0.831250011920929,,,5.238887786865234,1133.8399658203125,1894.739990234375 +1998-07-01,37.19002914428711,0.26433059573173523,17.27544403076172,86.6082992553711,0.9239580035209656,,,3.988961935043335,1120.6700439453125,1872.3900146484375 +1998-08-01,31.611520767211914,0.23808826506137848,15.075493812561035,72.04536437988281,0.6979169845581055,,,3.2419238090515137,957.280029296875,1499.25 +1998-08-06,,,,,,,,,, +1998-09-01,36.12905502319336,0.2910497486591339,17.295076370239258,69.53275299072266,0.9302080273628235,,,4.283971786499023,1017.010009765625,1693.8399658203125 +1998-10-01,41.75224685668945,0.2834153473377228,16.637067794799805,80.36154174804688,1.0536459684371948,,,4.59221076965332,1098.6700439453125,1771.3900146484375 +1998-11-01,46.4265251159668,0.2438134402036667,19.170928955078125,88.54693603515625,1.600000023841858,,,5.535391330718994,1163.6300048828125,1949.5400390625 +1998-11-06,,,,,,,,,, +1998-12-01,51.91548538208008,0.3125200569629669,21.793180465698242,97.19573974609375,2.6770830154418945,,,5.782783031463623,1229.22998046875,2192.68994140625 +1999-01-01,51.59874725341797,0.3144294023513794,27.499271392822266,102.47120666503906,2.92343807220459,,,5.912916660308838,1279.6400146484375,2505.889892578125 +1999-02-01,47.797481536865234,0.2657618522644043,23.5904541015625,91.21175384521484,3.203125,,,4.984185218811035,1238.3299560546875,2288.030029296875 +1999-02-08,,,,,,,,,, +1999-03-01,49.97552490234375,0.27435049414634705,28.16712188720703,88.21611785888672,4.304687976837158,,,7.027392387390137,1286.3699951171875,2461.39990234375 +1999-04-01,58.98025894165039,0.35116779804229736,25.554689407348633,97.44929504394531,4.301562786102295,,,7.854666709899902,1335.1800537109375,2542.860107421875 +1999-05-01,65.41220092773438,0.3363769054412842,25.35825538635254,93.19886779785156,2.96875,,,9.187017440795898,1301.8399658203125,2470.52001953125 +1999-05-06,,,,,,,,,, +1999-05-27,,,,,,,,,, +1999-06-01,72.96644592285156,0.35355332493782043,28.343910217285156,97.96764373779297,3.128124952316284,,,10.182408332824707,1372.7099609375,2686.1201171875 +1999-07-01,70.95524597167969,0.4251234233379364,26.96893310546875,81.35432434082031,2.50156307220459,,,10.634023666381836,1328.719970703125,2638.489990234375 +1999-08-01,70.32015991210938,0.49812400341033936,29.090301513671875,79.7938461303711,3.109375,,,12.354691505432129,1320.4100341796875,2739.35009765625 +1999-08-06,,,,,,,,,, +1999-09-01,68.37564849853516,0.48333317041397095,28.46175193786621,69.8066177368164,3.996875047683716,,,14.07535457611084,1282.7099609375,2746.159912109375 +1999-10-01,55.519859313964844,0.6116815209388733,29.090301513671875,47.42917251586914,3.53125,,,17.35419464111328,1362.9300537109375,2966.429931640625 +1999-11-01,58.239349365234375,0.747186541557312,28.613975524902344,45.75767135620117,4.253125190734863,,,17.044021606445312,1388.9100341796875,3336.159912109375 +1999-11-08,,,,,,,,,, +1999-12-01,61.04003143310547,0.7848799824714661,36.6919059753418,37.92245101928711,3.8062500953674316,,,16.687326431274414,1469.25,4069.31005859375 +2000-01-01,63.515560150146484,0.7920366525650024,30.75990104675293,35.14961242675781,3.2281250953674316,,,13.668244361877441,1394.4599609375,3940.35009765625 +2000-02-01,58.14006042480469,0.8750578165054321,28.088550567626953,36.62297058105469,3.4437499046325684,,,25.31960105895996,1366.4200439453125,4696.68994140625 +2000-02-08,,,,,,,,,, +2000-03-01,67.05181884765625,1.0368047952651978,33.39197540283203,43.779178619384766,3.3499999046325684,,,27.631258010864258,1498.5799560546875,4572.830078125 +2000-04-01,63.157623291015625,0.947104275226593,21.920852661132812,45.03520965576172,2.7593750953674316,,,30.027847290039062,1452.4300537109375,3860.659912109375 +2000-05-01,60.785640716552734,0.6412634253501892,19.661985397338867,46.097347259521484,2.4156250953674316,,,27.948402404785156,1420.5999755859375,3400.909912109375 +2000-05-08,,,,,,,,,, +2000-06-01,62.13500213623047,0.7996708750724792,25.142194747924805,35.529056549072266,1.8156249523162842,,,32.277984619140625,1454.5999755859375,3966.110107421875 +2000-07-01,63.65913009643555,0.7758141756057739,21.940492630004883,25.79067039489746,1.506250023841858,,,28.43518829345703,1430.8299560546875,3766.989990234375 +2000-08-01,74.86860656738281,0.9304049015045166,21.940492630004883,27.82395362854004,2.075000047683716,,,32.28449630737305,1517.6800537109375,4206.35009765625 +2000-08-08,,,,,,,,,, +2000-09-01,63.94328689575195,0.3931553065776825,18.95485496520996,25.980575561523438,1.921875,,,38.555137634277344,1436.510009765625,3672.820068359375 +2000-10-01,55.92375183105469,0.29868337512016296,21.645862579345703,14.6140718460083,1.8312499523162842,,,37.785430908203125,1429.4000244140625,3369.6298828125 +2000-11-01,53.08496856689453,0.2519250810146332,18.03167152404785,12.016016960144043,1.234375,,,31.482683181762695,1314.949951171875,2597.929931640625 +2000-11-08,,,,,,,,,, +2000-12-01,48.32046127319336,0.22711420059204102,13.631781578063965,8.067792892456055,0.778124988079071,,,28.90570068359375,1320.280029296875,2470.52001953125 +2001-01-01,63.6693229675293,0.33017459511756897,19.190568923950195,14.251648902893066,0.8656250238418579,,,21.702556610107422,1366.010009765625,2772.72998046875 +2001-02-01,56.790767669677734,0.2786443829536438,18.54237174987793,10.536102294921875,0.5093749761581421,,,14.440549850463867,1239.93994140625,2151.830078125 +2001-02-07,,,,,,,,,, +2001-03-01,54.73835754394531,0.3369686007499695,17.18704605102539,10.535667419433594,0.5115000009536743,,,17.375865936279297,1160.3299560546875,1840.260009765625 +2001-04-01,65.52893829345703,0.38918623328208923,21.292295455932617,15.900238990783691,0.7889999747276306,,,22.32872772216797,1249.4599609375,2116.239990234375 +2001-05-01,63.62804412841797,0.3046000301837921,21.741714477539062,17.430465698242188,0.8345000147819519,,,19.768779754638672,1255.8199462890625,2110.489990234375 +2001-05-08,,,,,,,,,, +2001-06-01,64.6737060546875,0.35498547554016113,22.942251205444336,16.83243751525879,0.7074999809265137,,,23.362648010253906,1224.3800048828125,2160.5400390625 +2001-07-01,59.949947357177734,0.28688937425613403,20.80202293395996,14.035829544067383,0.6244999766349792,,,18.640790939331055,1211.22998046875,2027.1300048828125 +2001-08-01,56.952762603759766,0.2832247018814087,17.929533004760742,16.18165397644043,0.44699999690055847,,,16.711578369140625,1133.5799560546875,1805.4300537109375 +2001-08-08,,,,,,,,,, +2001-09-01,52.33213424682617,0.23680917918682098,16.081575393676758,13.6312894821167,0.2985000014305115,,,11.92334270477295,1040.93994140625,1498.800048828125 +2001-10-01,61.660858154296875,0.26810887455940247,18.275238037109375,12.312134742736816,0.3490000069141388,,,13.133195877075195,1059.780029296875,1690.199951171875 +2001-11-01,65.95150756835938,0.3252120614051819,20.17975616455078,14.774558067321777,0.5659999847412109,,,15.958827018737793,1139.449951171875,1930.5799560546875 +2001-11-07,,,,,,,,,, +2001-12-01,69.1006088256836,0.3343726694583893,20.820878982543945,18.32748794555664,0.5410000085830688,,,15.446427345275879,1148.0799560546875,1950.4000244140625 +2002-01-01,61.63407897949219,0.37742963433265686,20.022619247436523,19.928070068359375,0.7095000147819519,,,16.771486282348633,1130.199951171875,1934.030029296875 +2002-02-01,56.052799224853516,0.3313194811344147,18.334945678710938,17.07868194580078,0.7049999833106995,,,18.105239868164062,1106.72998046875,1731.489990234375 +2002-02-06,,,,,,,,,, +2002-03-01,59.49020767211914,0.3613981306552887,18.95407485961914,18.907917022705078,0.7149999737739563,,,20.051130294799805,1147.3900146484375,1845.3499755859375 +2002-04-01,47.912540435791016,0.3705587685108185,16.424144744873047,15.56605339050293,0.8345000147819519,,,19.893611907958984,1076.9200439453125,1688.22998046875 +2002-05-01,46.01911926269531,0.35574817657470703,15.999865531921387,15.777122497558594,0.9114999771118164,,,17.971961975097656,1067.1400146484375,1615.72998046875 +2002-05-08,,,,,,,,,, +2002-06-01,41.26642990112305,0.2705524265766144,17.190977096557617,10.55325984954834,0.8125,,,14.188389778137207,989.8200073242188,1463.2099609375 +2002-07-01,40.349422454833984,0.23299239575862885,15.079033851623535,12.224191665649414,0.7225000262260437,,,11.933782577514648,911.6199951171875,1328.260009765625 +2002-08-01,43.203697204589844,0.22520573437213898,15.424735069274902,12.329721450805664,0.746999979019165,,,10.01123046875,916.0700073242188,1314.8499755859375 +2002-08-07,,,,,,,,,, +2002-09-01,33.49409484863281,0.22138899564743042,13.746496200561523,8.706437110900879,0.796500027179718,,,9.513158798217773,815.280029296875,1172.06005859375 +2002-10-01,45.344242095947266,0.24535933136940002,16.804426193237305,11.678934097290039,0.9679999947547913,,,11.782204627990723,885.760009765625,1329.75 +2002-11-01,49.92806625366211,0.23665708303451538,18.127525329589844,15.337401390075684,1.1675000190734863,,,14.71778678894043,936.3099975585938,1478.780029296875 +2002-11-06,,,,,,,,,, +2002-12-01,44.5990104675293,0.2187930941581726,16.248149871826172,14.15894889831543,0.9445000290870667,,,12.360349655151367,879.8200073242188,1335.510009765625 +2003-01-01,45.00184631347656,0.21925139427185059,14.91561222076416,15.56605339050293,1.0924999713897705,,,13.167760848999023,855.7000122070312,1320.9100341796875 +2003-02-01,44.85797119140625,0.22917553782463074,14.896756172180176,15.829883575439453,1.1004999876022339,,,13.712512969970703,841.1500244140625,1337.52001953125 +2003-02-06,,,,,,,,,, +2003-03-01,45.22197723388672,0.2158920168876648,15.266251564025879,15.302220344543457,1.3014999628067017,,,15.372973442077637,848.1799926757812,1341.1700439453125 +2003-04-01,48.95253372192383,0.21711383759975433,16.123830795288086,17.342517852783203,1.434499979019165,,,17.22471046447754,916.9199829101562,1464.31005859375 +2003-05-01,50.76301956176758,0.2740640342235565,15.518482208251953,19.224523544311523,1.7944999933242798,,,17.618791580200195,963.5900268554688,1595.9100341796875 +2003-05-07,,,,,,,,,, +2003-06-01,47.655845642089844,0.29101142287254333,16.16796875,18.626508712768555,1.815999984741211,,,15.997578620910645,974.5,1622.800048828125 +2003-07-01,46.933773040771484,0.32185351848602295,16.653514862060547,18.995861053466797,2.0820000171661377,,,16.333431243896484,990.3099975585938,1735.02001953125 +2003-08-01,47.37279510498047,0.34521347284317017,16.722881317138672,18.960683822631836,2.315999984741211,,,19.37755012512207,1008.010009765625,1810.449951171875 +2003-08-06,,,,,,,,,, +2003-09-01,51.1259651184082,0.3163566291332245,17.530014038085938,18.046072006225586,2.4214999675750732,,,19.657007217407227,995.969970703125,1786.93994140625 +2003-10-01,51.79159927368164,0.3494885563850403,16.48325538635254,18.468202590942383,2.7214999198913574,,,21.84463119506836,1050.7099609375,1932.2099609375 +2003-11-01,52.405128479003906,0.3192576766014099,16.303056716918945,21.423110961914062,2.698499917984009,,,20.621614456176758,1058.199951171875,1960.260009765625 +2003-11-06,,,,,,,,,, +2003-12-01,53.74093246459961,0.32628077268600464,17.35569190979004,24.272485733032227,2.63100004196167,,,19.5084171295166,1111.9200439453125,2003.3699951171875 +2004-01-01,57.53900146484375,0.3444499373435974,17.533241271972656,25.74994659423828,2.5199999809265137,,,19.119047164916992,1131.1300048828125,2066.14990234375 +2004-02-01,55.95598602294922,0.36521488428115845,16.82303810119629,24.87051010131836,2.1505000591278076,,,18.600963592529297,1144.93994140625,2029.8199462890625 +2004-02-06,,,,,,,,,, +2004-03-01,53.3401985168457,0.4128514230251312,15.808448791503906,25.6268310546875,2.1640000343322754,,,19.62464141845703,1126.2099609375,1994.219970703125 +2004-04-01,51.208683013916016,0.39361342787742615,16.56939125061035,23.6217041015625,2.180000066757202,,,20.729951858520508,1107.300048828125,1920.1500244140625 +2004-05-01,51.45262145996094,0.4284247159957886,16.632802963256836,23.815183639526367,2.424999952316284,,,22.293439865112305,1120.6800537109375,1986.739990234375 +2004-05-06,,,,,,,,,, +2004-06-01,51.300846099853516,0.4968261420726776,18.110280990600586,25.503700256347656,2.7200000286102295,,,23.227535247802734,1140.8399658203125,2047.7900390625 +2004-07-01,50.672325134277344,0.4937727451324463,18.065902709960938,24.378023147583008,1.9459999799728394,,,21.075881958007812,1101.719970703125,1887.3599853515625 +2004-08-01,49.28722381591797,0.5265995860099792,17.31130027770996,23.6217041015625,1.906999945640564,,,22.91964340209961,1104.239990234375,1838.0999755859375 +2004-08-06,,,,,,,,,, +2004-09-01,50.00397872924805,0.5916416049003601,17.5849609375,24.764976501464844,2.0429999828338623,,64.8648681640625,24.718441009521484,1114.5799560546875,1896.8399658203125 +2004-10-01,52.34260559082031,0.800052285194397,17.788476943969727,25.978591918945312,1.7065000534057617,,95.41541290283203,28.003637313842773,1130.199951171875,1974.989990234375 +2004-11-01,54.96117401123047,1.0237311124801636,17.050731658935547,26.945974349975586,1.9839999675750732,,91.0810775756836,30.26772117614746,1173.8199462890625,2096.81005859375 +2004-11-08,,,,,,,,,, +2004-12-01,57.60344696044922,0.9832708239555359,18.939943313598633,29.918479919433594,2.2144999504089355,,96.49149322509766,31.357276916503906,1211.9200439453125,2175.43994140625 +2005-01-01,54.58831024169922,1.1741228103637695,18.628063201904297,27.930959701538086,2.1610000133514404,,97.90790557861328,28.444419860839844,1181.27001953125,2062.409912109375 +2005-02-01,54.09749221801758,1.3698610067367554,17.83417510986328,27.438472747802734,1.7589999437332153,,94.0890884399414,30.86894416809082,1203.5999755859375,2051.719970703125 +2005-02-08,,,,,,,,,, +2005-03-01,53.49815368652344,1.2724499702453613,17.18527603149414,26.6469669342041,1.7135000228881836,,90.34534454345703,33.57841110229492,1180.5899658203125,1999.22998046875 +2005-04-01,44.7164421081543,1.1011403799057007,17.988739013671875,23.305103302001953,1.6180000305175781,,110.110107421875,29.735000610351562,1156.8499755859375,1921.6500244140625 +2005-05-01,44.23051071166992,1.2141252756118774,18.3442440032959,23.867952346801758,1.7755000591278076,,138.77377319335938,33.119998931884766,1191.5,2068.219970703125 +2005-05-06,,,,,,,,,, +2005-06-01,43.555538177490234,1.124043345451355,17.71768569946289,24.254899978637695,1.6545000076293945,,147.22222900390625,28.610000610351562,1191.3299560546875,2056.9599609375 +2005-07-01,48.991188049316406,1.3023751974105835,18.26690673828125,23.234752655029297,2.257499933242798,,144.02401733398438,29.639999389648438,1234.1800537109375,2184.830078125 +2005-08-01,47.3240966796875,1.431849479675293,19.529403686523438,23.58652687072754,2.134999990463257,,143.1431427001953,27.040000915527344,1220.3299560546875,2152.090087890625 +2005-08-08,,,,,,,,,, +2005-09-01,47.202552795410156,1.6370543241500854,18.40694236755371,24.00865936279297,2.265000104904175,,158.3883819580078,29.850000381469727,1228.81005859375,2151.68994140625 +2005-10-01,48.1793098449707,1.7585887908935547,18.385473251342773,23.867952346801758,1.9930000305175781,,186.25625610351562,32.25,1207.010009765625,2120.300048828125 +2005-11-01,52.309974670410156,2.0709757804870605,19.80194664001465,24.976051330566406,2.4230000972747803,,202.65765380859375,32.61000061035156,1249.47998046875,2232.820068359375 +2005-11-08,,,,,,,,,, +2005-12-01,48.483585357666016,2.1952593326568604,18.762245178222656,25.76755142211914,2.3575000762939453,,207.63763427734375,36.959999084472656,1248.2900390625,2205.320068359375 +2006-01-01,47.95273208618164,2.305800437927246,20.19721794128418,25.169517517089844,2.240999937057495,,216.5465545654297,39.72999954223633,1280.0799560546875,2305.820068359375 +2006-02-01,47.32752227783203,2.0914342403411865,19.27882957458496,26.207246780395508,1.871999979019165,,181.49148559570312,38.54999923706055,1280.6600341796875,2281.389892578125 +2006-02-08,,,,,,,,,, +2006-03-01,48.76497268676758,1.9152405261993408,19.588937759399414,26.734920501708984,1.8265000581741333,,195.1951904296875,34.95000076293945,1294.8699951171875,2339.7900390625 +2006-04-01,48.6880989074707,2.149454355239868,17.385986328125,24.694625854492188,1.7604999542236328,,209.17918395996094,39.20000076293945,1310.6099853515625,2322.570068359375 +2006-05-01,47.24531936645508,1.8251585960388184,16.306108474731445,24.149375915527344,1.7304999828338623,,186.09609985351562,28.6299991607666,1270.0899658203125,2178.8798828125 +2006-05-08,,,,,,,,,, +2006-06-01,45.58832931518555,1.7488168478012085,16.83946990966797,24.465961456298828,1.934000015258789,,209.8748779296875,30.360000610351562,1270.199951171875,2172.090087890625 +2006-07-01,45.938453674316406,2.075251340866089,17.388734817504883,24.78256607055664,1.344499945640564,,193.49349975585938,28.510000228881836,1276.6600341796875,2091.469970703125 +2006-08-01,48.051090240478516,2.0718915462493896,18.574007034301758,26.048952102661133,1.5414999723434448,,189.45445251464844,32.439998626708984,1303.8199462890625,2183.75 +2006-08-08,,,,,,,,,, +2006-09-01,48.820682525634766,2.350689172744751,19.839282989501953,27.368104934692383,1.6059999465942383,,201.15115356445312,37.459999084472656,1335.8499755859375,2258.429931640625 +2006-10-01,55.01115798950195,2.475886821746826,20.82581329345703,29.90088653564453,1.9045000076293945,,238.4334259033203,38.25,1377.93994140625,2366.7099609375 +2006-11-01,54.766883850097656,2.798962354660034,21.29731559753418,29.021446228027344,2.0169999599456787,,242.64764404296875,40.15999984741211,1400.6300048828125,2431.77001953125 +2006-11-08,,,,,,,,,, +2006-12-01,58.07079315185547,2.5907039642333984,21.73406219482422,29.812957763671875,1.9730000495910645,,230.47047424316406,41.119998931884766,1418.300048828125,2415.2900390625 +2007-01-01,59.266300201416016,2.617882013320923,22.461923599243164,30.252676010131836,1.8834999799728394,,251.00100708007812,38.869998931884766,1438.239990234375,2463.929931640625 +2007-02-01,55.55428695678711,2.583681344985962,20.50397491455078,30.37578582763672,1.9570000171661377,,224.949951171875,39.25,1406.8199462890625,2416.14990234375 +2007-02-07,,,,,,,,,, +2007-03-01,56.51309585571289,2.8371317386627197,20.3559513092041,29.707414627075195,1.9895000457763672,,229.30931091308594,41.70000076293945,1420.8599853515625,2421.639892578125 +2007-04-01,61.27952575683594,3.0475287437438965,21.867843627929688,32.539215087890625,3.066499948501587,,235.92591857910156,41.560001373291016,1482.3699951171875,2525.090087890625 +2007-05-01,63.91150665283203,3.700700044631958,22.415639877319336,33.18999099731445,3.4570000171661377,,249.20420837402344,44.060001373291016,1530.6199951171875,2604.52001953125 +2007-05-08,,,,,,,,,, +2007-06-01,63.347747802734375,3.7266552448272705,21.59428596496582,32.5040397644043,3.4205000400543213,,261.6116027832031,40.150001525878906,1503.3499755859375,2603.22998046875 +2007-07-01,66.59786987304688,4.023471355438232,21.242568969726562,30.70998764038086,3.927000045776367,,255.2552490234375,40.290000915527344,1455.27001953125,2546.27001953125 +2007-08-01,70.23324584960938,4.228675365447998,21.052053451538086,30.12954330444336,3.995500087738037,,257.88287353515625,42.75,1473.989990234375,2596.360107421875 +2007-08-08,,,,,,,,,, +2007-09-01,71.1520004272461,4.68641471862793,21.662628173828125,30.49891471862793,4.65749979019165,,283.9189147949219,43.65999984741211,1526.75,2701.5 +2007-10-01,70.13726806640625,5.800380706787109,27.067256927490234,30.674802780151367,4.457499980926514,,353.8538513183594,47.900001525878906,1549.3800048828125,2859.1201171875 +2007-11-01,63.529457092285156,5.564334392547607,24.70686912536621,29.6898193359375,4.5279998779296875,,346.8468322753906,42.13999938964844,1481.1400146484375,2660.9599609375 +2007-11-07,,,,,,,,,, +2007-12-01,65.52474212646484,6.048642158508301,26.26405906677246,28.4762020111084,4.631999969482422,,346.0860900878906,42.72999954223633,1468.3599853515625,2652.280029296875 +2008-01-01,64.92465209960938,4.133399963378906,24.050800323486328,27.21040916442871,3.884999990463257,,282.43243408203125,34.93000030517578,1378.550048828125,2389.860107421875 +2008-02-01,69.0161361694336,3.8176541328430176,20.066930770874023,25.923078536987305,3.2235000133514404,,235.82582092285156,33.650001525878906,1330.6300048828125,2271.47998046875 +2008-02-06,,,,,,,,,, +2008-03-01,70.05885314941406,4.381966590881348,21.01883316040039,26.399211883544922,3.565000057220459,,220.45545959472656,35.59000015258789,1322.699951171875,2279.10009765625 +2008-04-01,73.44194030761719,5.311798572540283,21.122520446777344,24.706567764282227,3.93149995803833,,287.43243408203125,37.290000915527344,1385.5899658203125,2412.800048828125 +2008-05-01,78.75386810302734,5.763737201690674,20.974388122558594,24.016834259033203,4.080999851226807,,293.1932067871094,44.060001373291016,1400.3800048828125,2522.659912109375 +2008-05-07,,,,,,,,,, +2008-06-01,72.41636657714844,5.11300802230835,20.449499130249023,23.981456756591797,3.6665000915527344,,263.4734802246094,39.38999938964844,1280.0,2292.97998046875 +2008-07-01,78.18988800048828,4.853753566741943,19.118900299072266,24.197914123535156,3.816999912261963,,237.1121063232422,41.349998474121094,1267.3800048828125,2325.550048828125 +2008-08-01,74.37141418457031,5.176827907562256,20.285959243774414,24.712379455566406,4.040500164031982,,231.8768768310547,42.83000183105469,1282.8299560546875,2367.52001953125 +2008-08-06,,,,,,,,,, +2008-09-01,71.73551177978516,3.470762014389038,19.91908073425293,20.454687118530273,3.638000011444092,,200.46046447753906,39.470001220703125,1166.3599853515625,2091.8798828125 +2008-10-01,57.02163314819336,3.2854056358337402,16.66515350341797,14.2785062789917,2.861999988555908,,179.85986328125,26.639999389648438,968.75,1720.949951171875 +2008-11-01,50.04803466796875,2.8298041820526123,15.090431213378906,12.444729804992676,2.134999990463257,,146.6266326904297,23.15999984741211,896.239990234375,1535.5699462890625 +2008-11-06,,,,,,,,,, +2008-12-01,51.90673828125,2.6062774658203125,14.606595039367676,14.189484596252441,2.563999891281128,,153.97897338867188,21.290000915527344,903.25,1577.030029296875 +2009-01-01,56.52627944946289,2.7522425651550293,12.848398208618164,11.888165473937988,2.940999984741211,,169.43443298339844,19.309999465942383,825.8800048828125,1476.4200439453125 +2009-02-01,56.76066589355469,2.7272019386291504,12.13459587097168,9.274202346801758,3.239500045776367,,169.16416931152344,16.700000762939453,735.0900268554688,1377.8399658203125 +2009-02-06,,,,,,,,,, +2009-03-01,60.08320999145508,3.209982395172119,13.897279739379883,8.146258354187012,3.671999931335449,,174.20420837402344,21.389999389648438,797.8699951171875,1528.5899658203125 +2009-04-01,64.00231170654297,3.8423893451690674,15.3270902633667,11.028571128845215,4.026000022888184,,198.1831817626953,27.350000381469727,872.8099975585938,1717.300048828125 +2009-05-01,65.90607452392578,4.147140979766846,15.803704261779785,12.274019241333008,3.8994998931884766,,208.82382202148438,28.18000030517578,919.1400146484375,1774.3299560546875 +2009-05-06,,,,,,,,,, +2009-06-01,65.09091186523438,4.349293231964111,18.0966796875,11.69642448425293,4.183000087738037,,211.00601196289062,28.299999237060547,919.3200073242188,1835.0400390625 +2009-07-01,73.51245880126953,4.989336013793945,17.906352996826172,14.879191398620605,4.288000106811523,,221.7467498779297,32.41999816894531,987.47998046875,1978.5 +2009-08-01,73.58724975585938,5.1365203857421875,18.766645431518555,15.714898109436035,4.059500217437744,,231.06607055664062,31.420000076293945,1020.6199951171875,2009.06005859375 +2009-08-06,,,,,,,,,, +2009-09-01,74.90744018554688,5.659914016723633,19.69136619567871,14.061647415161133,4.668000221252441,,248.1731719970703,33.040000915527344,1057.0799560546875,2122.419921875 +2009-10-01,75.53370666503906,5.756102561950684,21.230228424072266,13.72740650177002,5.940499782562256,,268.3283386230469,32.939998626708984,1036.18994140625,2045.1099853515625 +2009-11-01,79.12847900390625,6.1045241355896,22.51645278930664,14.055986404418945,6.795499801635742,,291.7917785644531,35.08000183105469,1095.6300048828125,2144.60009765625 +2009-11-06,,,,,,,,,, +2009-12-01,82.34589385986328,6.434925556182861,23.438796997070312,15.443329811096191,6.72599983215332,,310.30029296875,36.779998779296875,1115.0999755859375,2269.14990234375 +2010-01-01,76.99246215820312,5.86481237411499,21.670120239257812,15.999075889587402,6.270500183105469,,265.2352294921875,32.29999923706055,1073.8699951171875,2147.35009765625 +2010-02-01,79.99315643310547,6.248349666595459,22.04693031311035,17.19167137145996,5.920000076293945,,263.6636657714844,34.650001525878906,1104.489990234375,2238.260009765625 +2010-02-08,,,,,,,,,, +2010-03-01,81.0396728515625,7.176041126251221,22.629026412963867,17.88887596130371,6.78849983215332,,283.8438415527344,35.369998931884766,1169.4300537109375,2397.9599609375 +2010-04-01,81.51359558105469,7.972740650177002,23.594758987426758,20.0878963470459,6.855000019073486,,263.11309814453125,33.599998474121094,1186.68994140625,2461.18994140625 +2010-05-01,79.1503677368164,7.84417724609375,19.932706832885742,17.157638549804688,6.2729997634887695,,243.0580596923828,32.08000183105469,1089.4100341796875,2257.0400390625 +2010-05-06,,,,,,,,,, +2010-06-01,78.42550659179688,7.680809020996094,17.857412338256836,14.817129135131836,5.4629998207092285,,222.69769287109375,26.43000030517578,1030.7099609375,2109.239990234375 +2010-07-01,81.55033874511719,7.855478763580322,20.03040885925293,18.038850784301758,5.894499778747559,,242.66766357421875,28.719999313354492,1101.5999755859375,2254.699951171875 +2010-08-01,78.20323944091797,7.4233856201171875,18.214401245117188,15.64971923828125,6.241499900817871,,225.2352294921875,27.700000762939453,1049.3299560546875,2114.030029296875 +2010-08-06,,,,,,,,,, +2010-09-01,85.6181411743164,8.664690971374512,19.10737419128418,19.168588638305664,7.853000164031982,,263.1581726074219,26.149999618530273,1141.199951171875,2368.6201171875 +2010-10-01,91.65619659423828,9.190831184387207,20.808244705200195,21.757949829101562,8.261500358581543,,307.15716552734375,28.149999618530273,1183.260009765625,2507.409912109375 +2010-11-01,90.290283203125,9.501388549804688,19.70814323425293,21.311634063720703,8.770000457763672,,278.1331481933594,27.799999237060547,1180.550048828125,2498.22998046875 +2010-11-08,,,,,,,,,, +2010-12-01,94.08943176269531,9.84980583190918,21.909496307373047,21.423206329345703,9.0,,297.28228759765625,30.780000686645508,1257.6400146484375,2652.8701171875 +2011-01-01,103.8599853515625,10.361597061157227,21.76820182800293,19.823131561279297,8.482000350952148,,300.48046875,33.04999923706055,1286.1199951171875,2700.080078125 +2011-02-01,103.78302001953125,10.785745620727539,20.865453720092773,20.065792083740234,8.66450023651123,,307.00701904296875,34.5,1327.219970703125,2782.27001953125 +2011-02-08,,,,,,,,,, +2011-03-01,104.95984649658203,10.64222526550293,20.04909324645996,19.879127502441406,9.006500244140625,,293.6736755371094,33.15999984741211,1325.8299560546875,2781.070068359375 +2011-04-01,109.79368591308594,10.691693305969238,20.467607498168945,18.910266876220703,9.790499687194824,,272.32232666015625,33.54999923706055,1363.6099853515625,2873.5400390625 +2011-05-01,108.73165130615234,10.621461868286133,19.7490291595459,19.135168075561523,9.834500312805176,,264.7747802734375,34.630001068115234,1345.199951171875,2835.300048828125 +2011-05-06,,,,,,,,,, +2011-06-01,110.91179656982422,10.25013542175293,20.665348052978516,19.510000228881836,10.224499702453613,,253.4434356689453,31.450000762939453,1320.6400146484375,2773.52001953125 +2011-07-01,117.571044921875,11.923834800720215,21.778095245361328,17.562105178833008,11.12600040435791,,302.14715576171875,27.709999084472656,1292.280029296875,2756.3798828125 +2011-08-01,111.14454650878906,11.75130844116211,21.142244338989258,15.623312950134277,10.761500358581543,,270.7507629394531,25.239999771118164,1218.8900146484375,2579.4599609375 +2011-08-08,,,,,,,,,, +2011-09-01,113.55061340332031,11.644124984741211,19.90796661376953,13.119815826416016,10.81149959564209,,257.77777099609375,24.170000076293945,1131.4200439453125,2415.39990234375 +2011-10-01,119.88819122314453,12.360504150390625,21.299680709838867,15.485393524169922,10.67549991607666,,296.6166076660156,29.40999984741211,1253.300048828125,2684.409912109375 +2011-11-01,122.07645416259766,11.670994758605957,20.459848403930664,15.42860221862793,9.614500045776367,,299.9949951171875,27.420000076293945,1246.9599609375,2620.340087890625 +2011-11-08,,,,,,,,,, +2011-12-01,119.88117218017578,12.367225646972656,20.92014503479004,15.068914413452148,8.654999732971191,,323.2732849121094,28.270000457763672,1257.5999755859375,2605.14990234375 +2012-01-01,125.56623077392578,13.939234733581543,23.79706382751465,14.749091148376465,9.722000122070312,,290.3453369140625,30.950000762939453,1312.4100341796875,2813.840087890625 +2012-02-01,128.25875854492188,16.564136505126953,25.57801628112793,15.662582397460938,8.98449993133545,,309.4344482421875,32.88999938964844,1365.6800537109375,2966.889892578125 +2012-02-08,,,,,,,,,, +2012-03-01,136.5597381591797,18.308074951171875,26.1682071685791,15.377117156982422,10.125499725341797,,320.9409484863281,34.310001373291016,1408.469970703125,3091.570068359375 +2012-04-01,135.53221130371094,17.83262062072754,25.97353172302246,14.882647514343262,11.595000267028809,,302.72772216796875,33.54999923706055,1397.9100341796875,3046.360107421875 +2012-05-01,126.25150299072266,17.64176368713379,23.677928924560547,13.811394691467285,10.645500183105469,,290.7207336425781,31.049999237060547,1310.3299560546875,2827.340087890625 +2012-05-08,,,,,,,,,, +2012-06-01,128.5418243408203,17.83323097229004,24.976381301879883,15.054808616638184,11.417499542236328,,290.3253173828125,32.369998931884766,1362.1600341796875,2935.050048828125 +2012-07-01,128.80467224121094,18.650381088256836,24.06191635131836,13.332178115844727,11.664999961853027,,316.8017883300781,30.8799991607666,1379.3199462890625,2939.52001953125 +2012-08-01,128.06199645996094,20.314008712768555,25.1641845703125,14.178669929504395,12.41349983215332,,342.88787841796875,31.270000457763672,1406.5799560546875,3066.9599609375 +2012-08-08,,,,,,,,,, +2012-09-01,136.92532348632812,20.458269119262695,24.459667205810547,14.120949745178223,12.715999603271484,,377.62762451171875,32.439998626708984,1440.6700439453125,3116.22998046875 +2012-10-01,128.39756774902344,18.256948471069336,23.456958770751953,12.4627103805542,11.644499778747559,,340.490478515625,34.029998779296875,1412.1600341796875,2977.22998046875 +2012-11-01,125.45381927490234,17.94904899597168,21.878910064697266,13.178736686706543,12.602499961853027,,349.5345458984375,34.61000061035156,1416.1800537109375,3010.239990234375 +2012-11-07,,,,,,,,,, +2012-12-01,126.98394775390625,16.39484405517578,22.13326644897461,13.19808578491211,12.543499946594238,,354.0440368652344,37.68000030517578,1426.18994140625,3019.510009765625 +2013-01-01,134.6208953857422,14.03252124786377,22.746475219726562,15.598185539245605,13.274999618530273,,378.2232360839844,37.83000183105469,1498.1099853515625,3142.1298828125 +2013-02-01,133.1359405517578,13.598445892333984,23.036500930786133,15.79291820526123,13.213500022888184,,401.0010070800781,39.310001373291016,1514.6800537109375,3160.18994140625 +2013-02-06,,,,,,,,,, +2013-03-01,141.99786376953125,13.716739654541016,23.903995513916016,16.74711036682129,13.32450008392334,,397.49249267578125,43.52000045776367,1569.18994140625,3267.52001953125 +2013-04-01,134.8347625732422,13.720457077026367,27.655447006225586,16.822824478149414,12.690500259399414,,412.69769287109375,45.08000183105469,1597.5699462890625,3328.7900390625 +2013-05-01,138.48284912109375,13.935823440551758,29.15936851501465,17.234567642211914,13.460000038146973,,436.0460510253906,42.90999984741211,1630.739990234375,3455.909912109375 +2013-05-08,,,,,,,,,, +2013-06-01,127.82191467285156,12.368638038635254,29.060949325561523,17.783567428588867,13.884499549865723,,440.6256408691406,45.560001373291016,1606.280029296875,3403.25 +2013-07-01,130.45040893554688,14.115401268005371,26.789243698120117,19.142587661743164,15.060999870300293,,444.3193054199219,47.279998779296875,1685.72998046875,3626.3701171875 +2013-08-01,121.90938568115234,15.19745922088623,28.101774215698242,19.695158004760742,14.048999786376953,,423.8738708496094,45.75,1632.969970703125,3589.8701171875 +2013-08-07,,,,,,,,,, +2013-09-01,124.47478485107422,14.96906566619873,28.19812774658203,20.306934356689453,15.631999969482422,,438.3934020996094,51.939998626708984,1681.550048828125,3771.47998046875 +2013-10-01,120.46192169189453,16.41180992126465,30.002870559692383,19.72601890563965,18.201499938964844,,515.8057861328125,54.220001220703125,1756.5400390625,3919.7099609375 +2013-11-01,120.77778625488281,17.45956802368164,32.30753707885742,22.58371353149414,19.680999755859375,,530.3253173828125,56.779998779296875,1805.81005859375,4059.889892578125 +2013-11-06,,,,,,,,,, +2013-12-01,126.7584228515625,17.71782684326172,31.937856674194336,24.151473999023438,19.93950080871582,,560.9158935546875,59.880001068115234,1848.3599853515625,4176.58984375 +2014-01-01,119.39906311035156,15.80967903137207,32.304969787597656,21.634523391723633,17.934499740600586,,591.0760498046875,59.189998626708984,1782.5899658203125,4103.8798828125 +2014-02-01,125.13655090332031,16.61942481994629,32.70622634887695,21.913677215576172,18.104999542236328,,608.4334106445312,68.62999725341797,1859.449951171875,4308.1201171875 +2014-02-06,,,,,,,,,, +2014-03-01,130.79644775390625,17.052499771118164,35.256614685058594,22.53180694580078,16.818500518798828,,557.8128051757812,65.73999786376953,1872.3399658203125,4198.990234375 +2014-04-01,133.50091552734375,18.747455596923828,34.7491340637207,24.246538162231445,15.206500053405762,,534.8800048828125,61.689998626708984,1883.949951171875,4114.56005859375 +2014-05-01,125.27215576171875,20.11072540283203,35.21359634399414,24.767969131469727,15.6274995803833,,571.6500244140625,64.54000091552734,1923.5699462890625,4242.6201171875 +2014-05-07,,,,,,,,,, +2014-06-01,123.88963317871094,20.782461166381836,36.12032699584961,24.94846534729004,16.23900032043457,,584.6699829101562,72.36000061035156,1960.22998046875,4408.18017578125 +2014-07-01,130.99761962890625,21.37957000732422,37.38497543334961,26.72607421875,15.649499893188477,,579.5499877929688,69.25,1930.6700439453125,4369.77001953125 +2014-08-01,131.4281463623047,22.922651290893555,39.35124206542969,27.834640502929688,16.95199966430664,,582.3599853515625,71.9000015258789,2003.3699951171875,4580.27001953125 +2014-08-06,,,,,,,,,, +2014-09-01,130.50729370117188,22.643360137939453,40.40761947631836,26.66560935974121,16.121999740600586,,588.4099731445312,69.19000244140625,1972.2900390625,4493.39013671875 +2014-10-01,113.0242691040039,24.27278709411621,40.92185974121094,26.89417266845703,15.27299976348877,,567.8699951171875,70.12000274658203,2018.050048828125,4630.740234375 +2014-11-01,111.49117279052734,26.729284286499023,41.67144012451172,28.27128028869629,16.93199920654297,,549.0800170898438,73.68000030517578,2067.56005859375,4791.6298828125 +2014-11-06,,,,,,,,,, +2014-12-01,111.05672454833984,24.915250778198242,40.74142074584961,28.068769454956055,15.517499923706055,,530.6599731445312,72.69999694824219,2058.89990234375,4736.0498046875 +2015-01-01,106.12132263183594,26.445661544799805,35.434940338134766,26.79075813293457,17.726499557495117,,537.5499877929688,70.12999725341797,1994.989990234375,4635.240234375 +2015-02-01,112.09505462646484,28.996322631835938,38.460933685302734,27.767194747924805,19.007999420166016,,562.6300048828125,79.0999984741211,2104.5,4963.52978515625 +2015-02-06,,,,,,,,,, +2015-03-01,111.87759399414062,28.197509765625,35.91679000854492,26.139816284179688,18.604999542236328,,554.7000122070312,73.94000244140625,2067.889892578125,4900.8798828125 +2015-04-01,119.3988265991211,28.360668182373047,42.96587371826172,23.521541595458984,21.089000701904297,,548.77001953125,76.05999755859375,2085.510009765625,4941.419921875 +2015-05-01,118.25563049316406,29.523195266723633,41.39352035522461,23.3579158782959,21.46150016784668,,545.3200073242188,79.08999633789062,2107.389892578125,5070.02978515625 +2015-05-06,,,,,,,,,, +2015-06-01,114.24130249023438,28.542850494384766,39.253108978271484,21.762542724609375,21.704500198364258,,540.0399780273438,81.01000213623047,2063.110107421875,4986.8701171875 +2015-07-01,113.77072143554688,27.60302734375,41.520286560058594,22.683992385864258,26.8075008392334,,657.5,81.98999786376953,2103.840087890625,5128.27978515625 +2015-08-01,103.86784362792969,25.65966796875,38.692989349365234,20.93431854248047,25.644500732421875,,647.8200073242188,78.56999969482422,1972.1800537109375,4776.509765625 +2015-08-06,,,,,,,,,, +2015-09-01,102.66226959228516,25.21347999572754,39.61040496826172,20.028608322143555,25.594499588012695,,638.3699951171875,82.22000122070312,1920.030029296875,4620.16015625 +2015-10-01,99.1993637084961,27.31651496887207,47.11008071899414,19.46390151977539,31.295000076293945,,737.3900146484375,88.66000366210938,2079.360107421875,5053.75 +2015-11-01,98.7319564819336,27.042200088500977,48.64043045043945,21.868392944335938,33.2400016784668,,762.8499755859375,91.45999908447266,2080.409912109375,5108.669921875 +2015-11-06,,,,,,,,,, +2015-12-01,98.37144470214844,24.16438102722168,49.98638916015625,22.03421974182129,33.794498443603516,,778.010009765625,93.94000244140625,2043.93994140625,5007.41015625 +2016-01-01,89.20050811767578,22.3461971282959,49.63501739501953,20.343839645385742,29.350000381469727,,761.3499755859375,89.12999725341797,1940.239990234375,4613.9501953125 +2016-02-01,93.6608657836914,22.196985244750977,45.841888427734375,20.051719665527344,27.625999450683594,,717.219970703125,85.1500015258789,1932.22998046875,4557.9501953125 +2016-02-08,,,,,,,,,, +2016-03-01,109.36297607421875,25.15644073486328,50.11842727661133,23.285871505737305,29.68199920654297,,762.9000244140625,93.80000305175781,2059.739990234375,4869.85009765625 +2016-04-01,105.3841552734375,21.636524200439453,45.25450134277344,20.178363800048828,32.97949981689453,,707.8800048828125,94.22000122070312,2065.300048828125,4775.35986328125 +2016-05-01,111.01663208007812,23.049110412597656,48.094825744628906,20.956079483032227,36.13949966430664,,748.8499755859375,99.47000122070312,2096.949951171875,4948.0498046875 +2016-05-06,,,,,,,,,, +2016-06-01,110.65898895263672,22.20018196105957,46.75897216796875,19.947153091430664,35.78099822998047,,703.530029296875,95.79000091552734,2098.860107421875,4842.669921875 +2016-07-01,117.10401916503906,24.199600219726562,51.79398727416992,21.839828491210938,37.94049835205078,,791.3400268554688,97.86000061035156,2173.60009765625,5162.1298828125 +2016-08-01,115.83541107177734,24.638490676879883,52.506752014160156,20.885658264160156,38.45800018310547,,789.8499755859375,102.30999755859375,2170.949951171875,5213.22021484375 +2016-08-08,,,,,,,,,, +2016-09-01,116.81381225585938,26.394628524780273,52.96271896362305,21.479366302490234,41.865501403808594,13.321450233459473,804.0599975585938,108.54000091552734,2168.27001953125,5312.0 +2016-10-01,113.019287109375,26.509033203125,55.095947265625,20.878395080566406,39.49100112915039,13.680961608886719,809.9000244140625,107.51000213623047,2126.14990234375,5189.14013671875 +2016-11-01,119.29200744628906,25.803936004638672,55.40858840942383,19.980859756469727,37.528499603271484,14.926712036132812,775.8800048828125,102.80999755859375,2198.81005859375,5323.68017578125 +2016-11-08,,,,,,,,,, +2016-12-01,123.1717300415039,27.180198669433594,57.52321243286133,18.655929565429688,37.493499755859375,15.31966781616211,792.4500122070312,102.94999694824219,2238.830078125,5383.1201171875 +2017-01-01,129.5013427734375,28.47795867919922,59.84672927856445,22.670724868774414,41.17399978637695,17.554771423339844,820.1900024414062,113.37999725341797,2278.8701171875,5614.7900390625 +2017-02-01,133.43417358398438,32.148292541503906,59.22650909423828,24.339130401611328,42.25199890136719,17.69411849975586,844.9299926757812,118.33999633789062,2363.639892578125,5825.43994140625 +2017-02-08,,,,,,,,,, +2017-03-01,130.24111938476562,33.85976028442383,61.33644485473633,24.011991500854492,44.32699966430664,17.858545303344727,847.7999877929688,130.1300048828125,2362.719970703125,5911.740234375 +2017-04-01,119.88253784179688,33.85739517211914,63.75787353515625,23.72492027282715,46.2495002746582,18.70298194885254,924.52001953125,133.74000549316406,2384.199951171875,6047.60986328125 +2017-05-01,114.1535415649414,36.00456237792969,65.0430908203125,23.328956604003906,49.73099899291992,19.338397979736328,987.0900268554688,141.86000061035156,2411.800048828125,6198.52001953125 +2017-05-08,,,,,,,,,, +2017-06-01,116.17494201660156,34.084716796875,64.56354522705078,23.700172424316406,48.400001525878906,17.030832290649414,929.6799926757812,141.44000244140625,2423.409912109375,6140.419921875 +2017-07-01,109.25714874267578,35.19940948486328,68.0947265625,25.520694732666016,49.388999938964844,17.911497116088867,945.5,146.49000549316406,2470.300048828125,6348.1201171875 +2017-08-01,108.01860809326172,38.81330490112305,70.03360748291016,26.852062225341797,49.029998779296875,20.882347106933594,955.239990234375,155.16000366210938,2471.64990234375,6428.66015625 +2017-08-08,,,,,,,,,, +2017-09-01,110.72441864013672,36.6182861328125,70.14307403564453,27.700807571411133,48.067501068115234,21.517763137817383,973.719970703125,149.17999267578125,2519.360107421875,6495.9599609375 +2017-10-01,117.57792663574219,40.163211822509766,78.32596588134766,25.408233642578125,55.263999938964844,23.067289352416992,1033.0400390625,175.16000366210938,2575.260009765625,6727.669921875 +2017-11-01,117.50923919677734,40.83085632324219,79.2582015991211,24.86334991455078,58.837501525878906,21.80481719970703,1036.1700439453125,181.47000122070312,2647.580078125,6873.97021484375 +2017-11-09,,,,,,,,,, +2017-12-01,118.25981140136719,40.3528938293457,80.95279693603516,24.43583106994629,58.4734992980957,22.65203857421875,1053.4000244140625,175.24000549316406,2673.610107421875,6903.39013671875 +2018-01-01,126.18390655517578,39.9236946105957,89.91493225097656,28.855159759521484,72.54450225830078,19.982173919677734,1182.219970703125,199.75999450683594,2823.81005859375,7411.47998046875 +2018-02-01,120.11751556396484,42.472713470458984,88.74141693115234,25.634004592895508,75.62249755859375,20.7039852142334,1103.9200439453125,209.1300048828125,2713.830078125,7273.009765625 +2018-02-08,,,,,,,,,, +2018-03-01,119.43197631835938,40.170265197753906,86.7812271118164,24.33201026916504,72.36699676513672,20.402997970581055,1037.1400146484375,216.0800018310547,2640.8701171875,7063.4501953125 +2018-04-01,112.83880615234375,39.566917419433594,88.92057037353516,26.82056999206543,78.30650329589844,20.00168228149414,1018.5800170898438,221.60000610351562,2648.050048828125,7066.27001953125 +2018-05-01,109.99760437011719,44.7408332824707,93.97891998291016,23.179109573364258,81.48100280761719,22.479249954223633,1100.0,249.27999877929688,2705.27001953125,7442.1201171875 +2018-05-09,,,,,,,,,, +2018-06-01,109.95153045654297,44.4903450012207,94.16664123535156,20.467208862304688,84.98999786376953,23.571720123291016,1129.18994140625,243.80999755859375,2718.3701171875,7510.2998046875 +2018-07-01,114.06781768798828,45.73533630371094,101.30004119873047,22.375450134277344,88.87200164794922,25.784528732299805,1227.219970703125,244.67999267578125,2816.2900390625,7671.7900390625 +2018-08-01,115.2877197265625,54.709842681884766,107.2684097290039,24.00385284423828,100.635498046875,26.8017520904541,1231.800048828125,263.510009765625,2901.52001953125,8109.5400390625 +2018-08-09,,,,,,,,,, +2018-09-01,120.2962646484375,54.445865631103516,109.63678741455078,23.24565315246582,100.1500015258789,27.066509246826172,1207.0799560546875,269.95001220703125,2913.97998046875,8046.35009765625 +2018-10-01,91.83122253417969,52.78649139404297,102.38966369628906,24.236047744750977,79.90049743652344,25.190916061401367,1090.5799560546875,245.75999450683594,2711.739990234375,7305.89990234375 +2018-11-01,98.86396026611328,43.07142639160156,106.3008041381836,23.4099178314209,84.50849914550781,29.396371841430664,1109.6500244140625,250.88999938964844,2760.169921875,7330.5400390625 +2018-11-08,,,,,,,,,, +2018-12-01,91.58279418945312,38.17780685424805,97.78714752197266,17.18350601196289,75.09850311279297,24.59708595275879,1044.9599609375,226.24000549316406,2506.85009765625,6635.27978515625 +2019-01-01,108.30086517333984,40.28346252441406,100.5406265258789,24.84735679626465,85.9365005493164,24.456159591674805,1125.8900146484375,247.82000732421875,2704.10009765625,7281.740234375 +2019-02-01,111.28997039794922,41.90748596191406,107.85758972167969,27.216707229614258,81.99150085449219,28.095136642456055,1126.550048828125,262.5,2784.489990234375,7532.52978515625 +2019-02-07,,,,,,,,,, +2019-03-01,115.00740814208984,46.17075729370117,114.03240966796875,28.167972564697266,89.0374984741211,29.539655685424805,1176.8900146484375,266.489990234375,2834.39990234375,7729.31982421875 +2019-04-01,114.33090209960938,48.77644348144531,126.27296447753906,29.61660385131836,96.32599639892578,33.9285774230957,1198.9599609375,289.25,2945.830078125,8095.39013671875 +2019-05-01,103.50668334960938,42.55390930175781,119.58222198486328,27.175188064575195,88.75350189208984,29.972509384155273,1106.5,270.8999938964844,2752.06005859375,7453.14990234375 +2019-05-09,,,,,,,,,, +2019-06-01,113.73433685302734,48.293270111083984,130.00108337402344,31.43656349182129,94.68150329589844,25.56848907470703,1082.800048828125,294.6499938964844,2941.760009765625,8006.240234375 +2019-07-01,122.26231384277344,51.98261260986328,132.24281311035156,28.701255798339844,93.33899688720703,29.061506271362305,1218.199951171875,298.8599853515625,2980.3798828125,8175.419921875 +2019-08-01,111.7796401977539,50.93339920043945,133.78579711914062,25.92054557800293,88.81449890136719,25.9359073638916,1190.530029296875,284.510009765625,2926.4599609375,7962.8798828125 +2019-08-08,,,,,,,,,, +2019-09-01,121.34967803955078,54.85721969604492,135.37051391601562,26.743131637573242,86.79550170898438,26.10200309753418,1221.1400146484375,276.25,2976.739990234375,7999.33984375 +2019-10-01,111.59463500976562,60.929054260253906,139.59625244140625,30.58913803100586,88.83300018310547,26.620418548583984,1258.800048828125,277.92999267578125,3037.56005859375,8292.3603515625 +2019-11-01,112.19547271728516,65.45783996582031,147.39544677734375,35.09682083129883,90.04000091552734,24.40582847595215,1304.0899658203125,309.5299987792969,3140.97998046875,8665.4697265625 +2019-11-07,,,,,,,,,, +2019-12-01,113.17443084716797,72.13994598388672,154.07154846191406,33.23965072631836,92.39199829101562,25.86544418334961,1339.3900146484375,329.80999755859375,3230.780029296875,8972.599609375 +2020-01-01,121.35601806640625,76.03622436523438,166.31326293945312,32.28398132324219,100.43599700927734,24.546754837036133,1432.780029296875,351.1400146484375,3225.52001953125,9150.9404296875 +2020-02-01,109.88997650146484,67.1553726196289,158.28240966796875,29.225305557250977,94.1875,20.364192962646484,1339.25,345.1199951171875,2954.219970703125,8567.3701171875 +2020-02-07,,,,,,,,,, +2020-03-01,94.6399154663086,62.61878204345703,154.502197265625,17.190288543701172,97.48600006103516,19.90617561340332,1161.949951171875,318.239990234375,2584.590087890625,7700.10009765625 +2020-04-01,107.12150573730469,72.34808349609375,175.5648956298828,16.6003360748291,123.69999694824219,21.486589431762695,1346.699951171875,353.6400146484375,2912.429931640625,8889.5498046875 +2020-05-01,106.55841827392578,78.29256439208984,179.52272033691406,14.412978172302246,122.11849975585938,24.98464012145996,1433.52001953125,386.6000061035156,3044.31005859375,9489.8701171875 +2020-05-07,,,,,,,,,, +2020-06-01,104.41674041748047,90.0749740600586,199.92588806152344,13.877481460571289,137.9409942626953,27.652219772338867,1418.050048828125,435.30999755859375,3100.2900390625,10058.76953125 +2020-07-01,106.29290008544922,104.9491958618164,201.3994598388672,15.366937637329102,158.23399353027344,30.11343765258789,1487.949951171875,444.32000732421875,3271.1201171875,10745.26953125 +2020-08-01,106.61280059814453,127.44819641113281,221.55807495117188,17.406635284423828,172.54800415039062,33.25917053222656,1629.530029296875,513.3900146484375,3500.31005859375,11775.4599609375 +2020-08-07,,,,,,,,,, +2020-09-01,106.57222747802734,114.5876235961914,207.12527465820312,17.323570251464844,157.43649291992188,34.06950759887695,1465.5999755859375,490.42999267578125,3363.0,11167.509765625 +2020-10-01,97.80435180664062,107.71099090576172,199.38504028320312,16.259458541870117,151.8074951171875,30.329862594604492,1616.1099853515625,447.1000061035156,3269.9599609375,10911.58984375 +2020-11-01,108.19266510009766,117.79344177246094,210.8082733154297,20.478687286376953,158.40199279785156,34.74394989013672,1754.4000244140625,478.4700012207031,3621.6298828125,12198.740234375 +2020-11-09,,,,,,,,,, +2020-12-01,111.85865020751953,131.51597595214844,219.60447692871094,21.694869995117188,162.84649658203125,36.88808059692383,1752.6400146484375,500.1199951171875,3756.070068359375,12888.2802734375 +2021-01-01,105.84272766113281,130.7924346923828,229.0237274169922,19.891191482543945,160.30999755859375,36.6867561340332,1827.3599853515625,458.7699890136719,3714.239990234375,13070.6904296875 +2021-02-01,105.68277740478516,120.18710327148438,229.4384002685547,24.100215911865234,154.64649963378906,40.80388259887695,2021.9100341796875,459.6700134277344,3811.14990234375,13192.349609375 +2021-02-09,,,,,,,,,, +2021-03-01,119.9990005493164,121.25013732910156,233.32164001464844,22.955739974975586,154.70399475097656,44.367366790771484,2062.52001953125,475.3699951171875,3972.889892578125,13246.8701171875 +2021-04-01,127.76121520996094,130.49156188964844,249.56121826171875,23.070621490478516,173.37100219726562,49.49113082885742,2353.5,508.3399963378906,4181.169921875,13962.6796875 +2021-05-01,129.4361114501953,123.6920166015625,247.08718872070312,22.41118812561035,161.15350341796875,49.64715576171875,2356.85009765625,504.5799865722656,4204.10986328125,13748.740234375 +2021-05-07,,,,,,,,,, +2021-06-01,133.47738647460938,136.1819610595703,268.70587158203125,22.44941520690918,172.00799560546875,50.16557312011719,2441.7900390625,585.6400146484375,4297.5,14503.9501953125 +2021-07-01,128.35101318359375,145.03138732910156,282.6023864746094,23.305561065673828,166.37950134277344,48.63045883178711,2694.530029296875,621.6300048828125,4395.259765625,14672.6796875 +2021-08-01,127.78646087646484,150.96749877929688,299.4349365234375,21.74091148376465,173.5395050048828,49.053245544433594,2893.949951171875,663.7000122070312,4522.68017578125,15259.240234375 +2021-08-09,,,,,,,,,, +2021-09-01,127.95899963378906,140.906982421875,280.1719665527344,19.48086166381836,164.2519989013672,52.36507034301758,2673.52001953125,575.719970703125,4307.5400390625,14448.580078125 +2021-10-01,115.22111511230469,149.1721954345703,329.56378173828125,17.397972106933594,168.6215057373047,55.35980224609375,2960.919921875,650.3599853515625,4605.3798828125,15498.3896484375 +2021-11-01,112.8140869140625,164.60723876953125,328.5401611328125,18.003969192504883,175.35350036621094,56.077186584472656,2837.949951171875,669.8499755859375,4567.0,15537.6904296875 +2021-11-04,,,,,,,,,, +2021-11-09,,,,,,,,,, +2021-12-01,130.48629760742188,177.08387756347656,334.8461608886719,22.1286563873291,166.7169952392578,55.77927017211914,2897.0400390625,567.0599975585938,4766.18017578125,15644.9697265625 +2022-01-01,130.3984375,174.30149841308594,309.6171875,20.856517791748047,149.57350158691406,56.41482162475586,2706.070068359375,534.2999877929688,4515.5498046875,14239.8798828125 +2022-02-01,119.60104370117188,164.66795349121094,297.4805908203125,19.47332763671875,153.56300354003906,50.60551452636719,2701.139892578125,467.67999267578125,4373.93994140625,13751.400390625 +2022-02-10,,,,,,,,,, +2022-03-01,128.46168518066406,174.3538360595703,307.59356689453125,19.927804946899414,162.99749755859375,49.84086990356445,2781.35009765625,455.6199951171875,4530.41015625,14220.51953125 +2022-04-01,130.6254425048828,157.418701171875,276.8751220703125,17.399999618530273,124.28150177001953,46.68299102783203,2282.18994140625,395.95001220703125,4131.93017578125,12334.6396484375 +2022-05-01,137.1759796142578,148.6216278076172,271.2382507324219,18.81999969482422,120.20950317382812,49.939998626708984,2275.239990234375,416.4800109863281,4132.14990234375,12081.3896484375 +2022-05-09,,,,,,,,,, +2022-06-01,141.86000061035156,137.44000244140625,256.4800109863281,15.819999694824219,107.4000015258789,48.939998626708984,2240.14990234375,365.6300048828125,3821.550048828125,11181.5400390625 +2022-06-28,141.86000061035156,137.44000244140625,256.4800109863281,15.819999694824219,107.4000015258789,48.939998626708984,2240.14990234375,365.6300048828125,3821.550048828125,11181.5400390625 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy new file mode 100644 index 0000000000000000000000000000000000000000..b6b8dacdd0daecd53ef685f2a2dc29c98d5c6861 GIT binary patch literal 1880 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 KO;kS~2K^t3sh|G< literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv new file mode 100644 index 00000000..521da145 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv @@ -0,0 +1,11 @@ + 0 0 0 + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 +10 100 1000 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/eeg.dat b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/eeg.dat new file mode 100644 index 0000000000000000000000000000000000000000..c666c65053bfa37d63c9bdc1e5337e18484ec688 GIT binary patch literal 25600 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 K!XE3L)$l(+tI0zE literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc new file mode 100644 index 00000000..220656d7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc @@ -0,0 +1,65 @@ +<?xml version="1.0" ?> +<resource> + <object class="wxFrame" name="MainFrame"> + <title>embedding_in_wx3</title> + <object class="wxPanel" name="MainPanel"> + <object class="wxBoxSizer"> + <orient>wxVERTICAL</orient> + <object class="sizeritem"> + <object class="wxStaticText"> + <label>Check out this whizz-bang stuff!</label> + <style>wxALIGN_CENTRE</style> + </object> + <option>0</option> + <flag>wxALL|wxEXPAND</flag> + <border>5</border> + </object> + <object class="sizeritem"> + <object class="wxBoxSizer"> + <orient>wxHORIZONTAL</orient> + <object class="sizeritem"> + <object class="wxButton" name="whiz_button"> + <label>whiz</label> + </object> + <option>0</option> + <flag>wxALL|wxEXPAND</flag> + <border>2</border> + </object> + <object class="sizeritem"> + <object class="wxButton" name="bang_button"> + <label>bang</label> + </object> + <option>0</option> + <flag>wxALL|wxEXPAND</flag> + <border>2</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name=""> + <label>bang count:</label> + <style>wxALIGN_RIGHT</style> + </object> + <option>1</option> + <flag>wxALL|wxEXPAND</flag> + <border>2</border> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="bang_count"> + <value>0</value> + </object> + <option>0</option> + <flag>wxEXPAND</flag> + </object> + </object> + <option>0</option> + <flag>wxLEFT|wxRIGHT|wxEXPAND</flag> + <border>5</border> + </object> + <object class="sizeritem"> + <object class="wxPanel" name="plot_container_panel"/> + <option>1</option> + <flag>wxEXPAND</flag> + </object> + </object> + </object> + </object> +</resource> \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/goog.npz b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/goog.npz new file mode 100644 index 0000000000000000000000000000000000000000..6cbfd68ba9af2a5f38fc55bf1c109e3ee152f6d4 GIT binary patch literal 22845 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 ZH~RR}1!a}r@2&<<BzWb3kmOaX{uiqL^i2Q& literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/grace_hopper.jpg b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/grace_hopper.jpg new file mode 100644 index 0000000000000000000000000000000000000000..478720d6694a56b8962630e6dde8a230fc937049 GIT binary patch literal 61306 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz new file mode 100644 index 0000000000000000000000000000000000000000..d25028648b1d553f43fba4b1dce7c05ba4372b72 GIT binary patch literal 174061 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/logo2.png b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/logo2.png new file mode 100644 index 0000000000000000000000000000000000000000..72843ab1febbed35a00fc5c248f308f66d38cc24 GIT binary patch literal 22279 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/membrane.dat b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/membrane.dat new file mode 100644 index 0000000000000000000000000000000000000000..68f5e6b219448dac694aacba66b819564ba33467 GIT binary patch literal 48000 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 To$lVsq)YEPX4&#+{U`qyd@GW` literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/msft.csv b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/msft.csv new file mode 100644 index 00000000..727b1bef --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/msft.csv @@ -0,0 +1,66 @@ +Date,Open,High,Low,Close,Volume,Adj. Close* +19-Sep-03,29.76,29.97,29.52,29.96,92433800,29.79 +18-Sep-03,28.49,29.51,28.42,29.50,67268096,29.34 +17-Sep-03,28.76,28.95,28.47,28.50,47221600,28.34 +16-Sep-03,28.41,28.95,28.32,28.90,52060600,28.74 +15-Sep-03,28.37,28.61,28.33,28.36,41432300,28.20 +12-Sep-03,27.48,28.40,27.45,28.34,55777200,28.18 +11-Sep-03,27.66,28.11,27.59,27.84,37813300,27.68 +10-Sep-03,28.03,28.18,27.48,27.55,54763500,27.40 +9-Sep-03,28.65,28.71,28.31,28.37,44315200,28.21 +8-Sep-03,28.39,28.92,28.34,28.84,46105300,28.68 +5-Sep-03,28.23,28.75,28.17,28.38,64024500,28.22 +4-Sep-03,28.10,28.47,27.99,28.43,59840800,28.27 +3-Sep-03,27.42,28.40,27.38,28.30,109437800,28.14 +2-Sep-03,26.70,27.30,26.47,27.26,74168896,27.11 +29-Aug-03,26.46,26.55,26.35,26.52,34503000,26.37 +28-Aug-03,26.50,26.58,26.24,26.51,46211200,26.36 +27-Aug-03,26.51,26.58,26.30,26.42,30633900,26.27 +26-Aug-03,26.31,26.67,25.96,26.57,47546000,26.42 +25-Aug-03,26.31,26.54,26.23,26.50,36132900,26.35 +22-Aug-03,26.78,26.95,26.21,26.22,65846300,26.07 +21-Aug-03,26.65,26.73,26.13,26.24,63802700,26.09 +20-Aug-03,26.30,26.53,26.00,26.45,56739300,26.30 +19-Aug-03,25.85,26.65,25.77,26.62,72952896,26.47 +18-Aug-03,25.56,25.83,25.46,25.70,45817400,25.56 +15-Aug-03,25.61,25.66,25.43,25.54,27607900,25.40 +14-Aug-03,25.66,25.71,25.52,25.63,37338300,25.49 +13-Aug-03,25.79,25.89,25.50,25.60,39636900,25.46 +12-Aug-03,25.71,25.77,25.45,25.73,38208400,25.59 +11-Aug-03,25.61,25.99,25.54,25.61,36433900,25.47 +8-Aug-03,25.88,25.98,25.50,25.58,33241400,25.44 +7-Aug-03,25.72,25.81,25.45,25.71,44258500,25.57 +6-Aug-03,25.54,26.19,25.43,25.65,56294900,25.51 +5-Aug-03,26.31,26.54,25.60,25.66,58825800,25.52 +4-Aug-03,26.15,26.41,25.75,26.18,51825600,26.03 +1-Aug-03,26.33,26.51,26.12,26.17,42649700,26.02 +31-Jul-03,26.60,26.99,26.31,26.41,64504800,26.26 +30-Jul-03,26.46,26.57,26.17,26.23,41240300,26.08 +29-Jul-03,26.88,26.90,26.24,26.47,62391100,26.32 +28-Jul-03,26.94,27.00,26.49,26.61,52658300,26.46 +25-Jul-03,26.28,26.95,26.07,26.89,54173000,26.74 +24-Jul-03,26.78,26.92,25.98,26.00,53556600,25.85 +23-Jul-03,26.42,26.65,26.14,26.45,49828200,26.30 +22-Jul-03,26.28,26.56,26.13,26.38,51791000,26.23 +21-Jul-03,26.87,26.91,26.00,26.04,48480800,25.89 +18-Jul-03,27.11,27.23,26.75,26.89,63388400,26.74 +17-Jul-03,27.14,27.27,26.54,26.69,72805000,26.54 +16-Jul-03,27.56,27.62,27.20,27.52,49838900,27.37 +15-Jul-03,27.47,27.53,27.10,27.27,53567600,27.12 +14-Jul-03,27.63,27.81,27.05,27.40,60464400,27.25 +11-Jul-03,26.95,27.45,26.89,27.31,50377300,27.16 +10-Jul-03,27.25,27.42,26.59,26.91,55350800,26.76 +9-Jul-03,27.56,27.70,27.25,27.47,62300700,27.32 +8-Jul-03,27.26,27.80,27.25,27.70,61896800,27.55 +7-Jul-03,27.02,27.55,26.95,27.42,88960800,27.27 +3-Jul-03,26.69,26.95,26.41,26.50,39440900,26.35 +2-Jul-03,26.50,26.93,26.45,26.88,94069296,26.73 +1-Jul-03,25.59,26.20,25.39,26.15,60926000,26.00 +30-Jun-03,25.94,26.12,25.50,25.64,48073100,25.50 +27-Jun-03,25.95,26.34,25.53,25.63,76040304,25.49 +26-Jun-03,25.39,26.51,25.21,25.75,51758100,25.61 +25-Jun-03,25.64,25.99,25.14,25.26,60483500,25.12 +24-Jun-03,25.65,26.04,25.52,25.70,51820300,25.56 +23-Jun-03,26.14,26.24,25.49,25.78,52584500,25.64 +20-Jun-03,26.34,26.38,26.01,26.33,86048896,26.18 +19-Jun-03,26.09,26.39,26.01,26.07,63626900,25.92 \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz new file mode 100644 index 0000000000000000000000000000000000000000..347db4c0697c37bb9776fc1e916848829ad851ea GIT binary patch literal 33229 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 S9~wXH@&5x3G`)iW00ID_YlYeX literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz new file mode 100644 index 0000000000000000000000000000000000000000..9f9b085fa29bf590f1a3083c7c80baf0295528f3 GIT binary patch literal 45224 zcmb`w3%pfTx%WR2L{v;n%uLONf_Om%#k^rG=GuTJCMKk&=0foX8%4#uVJ)_ZNQg*^ zhPUO`h!6?yL`sXbkcgwEW~OGgA`cRI$kbyV^w|6Tj=3gGw%g8m-~S&!zt1zqnB)5V z#`BEJoNGJ$xQ?B=N6Eh)(Fxz!{hzr9qDXWhal%F8FFNqT@mK!f>m!dJerkv4JJHp> zN1t=)*_ZS_GS_>+x&3?h$@M<>qDv-RGU~!JFS=y(Ii?R8)qLqWq+fdesPX3z-{**a zeRBN{?z?ZF+%>uXw}0D2<)1E(%8x9MiuZ!q%cK1G<x%cB@I&I0mPeISNIP_S6unT3 zqLaXWU|+Bo*d6Quz5|{DkAo)gWzYkB3G4>U*9~+AA6BDiEqEEM0{4R!a0<wSZlJOZ zO@Y!cqG(2pw!lt>C|ZM@1r8wG5ex?VgY7{9TvUik*MkLMDYzE=8LTNpl_Q#>{C-VQ z=|ker67SU%RW1Z4k^W8OK;(hoYfVvoCh~OBwj%#+g(&}R;s+4l6C6%>JJR2wo}0j9 z;4Ux+P;cphq%Wn%2~Q=wGjJTDAK~M{e8!Nb^&z}?(5Cq8>ZWj-r<FV{z`SW%kd-Lv zpGjLuJ*$X62WEp6aa6fuc~mdKXUp=aa^-Tyiu^kAOgJ45`Vo$nN2OP4QE6c<ioOAQ zf}O!GU|X;qxB@Hyr-S~W5AeCz2{;erHv;ceqv%CY0rS9Aa6UL3bOG{PZ1C&Y*MfKB zC|VEH&A>twZ3VUiqrjzLOK=c43=9Gnqu-g}W}yBb0zU_@!B+%7ZxJq$?{egIfV}w= znxg!XV0U=jmORsW&b%tk22X+Y<T1TUxRqyebp|*I9MOP$zCj;1fF6WLAX82z5|)EB z-kuy${q*yNnK~>Jp_>S9+m;_s-7k{&Wv~KN<EVT~VyDps4PNE<D{$H$^jaR3c7x;h zYviv*rFqDH;0vG&_@tWf+mUcDp07fl0KN`}19>*D+&T};w>8)XtfuTr@F=(wlz{dt zzl-R99@u~R?Gs1QQqZA5Jzxo8Ih5z^(KXyf*MN(_am3~G7Vr^vx=&M-&x5Z5>@L4I z+<h^LS4gk)fv-;}r!Nrj6}Y?y`7pR1Sl5eyxe}cT4h4Gw=iCm+jt#6JuH8%l`kbyH z<=}C`+Ep4?&S(=i&3T{AW7zSBw01aE7k2}>od@7F^lKgRHTb;|KCfCH<<CcsLSnc1 z!2o_syOOpG{Qka%Uj&DNFM=Lmd(a7N0pz&@atx5y%WF|-GI9jy2Am5%*Upb>U_E7C z2hRXGo(c5P-9VP#sr1>te+cHp$ynqWdkMbqWWv~yHYmrXDd3ObPe7Z+UW1SRHC%Ur z&o4AZ`3^uEhX2yffE;4m`7KF%i!gpY@cez`uE4pqHF5(||1k?_i_M_55$=g>0&=k% zklR=2bC#>qNlW8XGT}5$sg9J^mrc)x^<&2E%a-&@y~wTYrhRqJ(YF$7Ze=nYeg{6U zAlwWF6aNDED{Z|B?g7VweSzz#HYvYb0l8fRl*V0qwcks?IADMKf^%z8>272*(8uox zJ`bE9^1J|?59D{|vcv~DhTG}4eIFLnej(8@KBzPq9_}PAxA0N=70|}!fSbS*U=er> zXy5qoFds$|J`8AwCxC%qXJA?ZICs>Sb|8oHFroqZu`gL&XT$R8JX{ORSI;MTyH`J5 zMlSk;Y<a^Uw3D}Oo-}S>cLy!h(+M~yUIV+3wk^PC6lW}t^6*=_9A0O#4&MW>-y+R5 z_x@TG-3R1KU%N{K@}iI38f*#HRTF=^En)3+Pw>rJRJs9qH5d!NNBmmkATX8i9OP)Q z4{%LhOdVH%2;`P+8n-%A$M#=;*1HfzhXBXX3+ebyggb4v45kr32?^(6T|5>khy6fD za1qc~9)R2$Xm106I$8x5g6&C{-&BwF22W}HU&-P0w;Raj=~-p0Ae)wkqeeS(c;4E8 z&n7m~(|m2EHY~qN=YBelb%dR-`s_0cQ4Ve^-vcKskBZaamc3S~33MU+e2p&EqUdaJ zD98cVQn4M-_TH@~{H{leV@Z=|Id-pgRzn&-0r0$ZFY-=sA=nRmOgVk@`QZ5sw@q>4 z|2{#g`z;H}-eo7`65>erNTqwg+rT~ZT%K(Qp5yr%pnu&1s0ZiCT;QB(tFLTaJIKb< z@Q0bcO{tQnl3=arhT$cP!)xfBe7gbV^WY^=0_&8S{4H(b*=PC_<Jmpc%cMCz$J8Bk z1#+yOoWHH$V#a+nT%NZ)%ClDvIDmLh(7EBCSJKDpz*oTmU@y=ebOrLb75K24_~<u~ zy@($LJ|TQ0QValj&;(AYvEG4cgk7sY2ORgE;24nQcXXVbe~v07wu<e!myNCl;{fTU zAA`HVbb!wecIvntzhi7^$gIAy;ajSS?phi$`^>$;Y_Jx*0*CXF^5WcftiwSL3<LFc zI6ft2KJly-Oa$f=4+GN%fDxeCaJ)I+*?y$qEWdNfKMc4Qi2j7Tf+jEp_#A&#xe(hu zZh4eH0@(w(A97D5{yF-j7L{HGvl!1|K<@ScyEY)d8>)#7uSPm%;T~)tI0HBzz6^Q- zeLVJDx)Dqv+z+fE|LtHr$b)X66G+G8TCyfi{PN&Ja<=^u@@CStOSvu(m-jQk2jqPX zXs;rzN2#BbFXxncbv```s$dmxuD*=i8o3DhCfJhjj==qf<Mmlb;CP<|_PrID?sK_M z*HGK)1LSlT=nv#pU+go}M}ur1<tH0|BNLb3lw;R-*ZQ73m)j`~Y5Do!WiS$c-7k9< z`W)z#a2jo>Me>{90XzOD{e2Lyo(7-W1*z?-qaA?bdZ(J~>(!C^k>f9rUH~J3>$YV~ z`vz!%->JxBz%%4+0gkl~(ANcik&aW2?gmRi2Y8g*M+#ANDmWYL2zCWWfnLC|k<W9| zMm-ftTUkx!p}LnxdDs~^SLJRe;CPg#?cRWSgy}-AExV3-Hh?Nv2v&o%4tchnDM0=l zpLx_xE6|pGHV0(6%!WPV8h<fvKackASjA}23|hbpa5`8OhdoI+3+;~0Vz;F?(feX> z3;jD2yiwz<Ncy9M_XpabzB$#4e7VnZoG*gqU<G&$n5MlB1kQo=#MObEjs_=zkzgTd zj#Yc=4mR@3*c{*NIGLNL70@5t;)|o9;0Q1ZXv5}N3MK-5R8~*JY6&O3km_IEACQ4O z_5gCK^qFJT?<n^L{TgA%ZT=3xF)jgeX4o-0kDVh*=gbDujhkPa|AhDga0+NU&TOB9 zjW*Wv+p$siY}x0##Zfd3ECt&al6|ARZcW&^y%o@h?T-ESfxnO7^d0b9`0RiU-(5@e ze;)EmPy~+Eemi%+1oi~G0qyeRD(e$i)qr|92o%7(qzy(o-w#1v)4*xS<3N@4hk<L6 zcAFyI%M6Rdn(BEr_}@d28%X;AtN@O)6UdI=uzcEwqrhQ6-VV*g(`PB4N_iCK6PB~Q zVaLA{kY9D+e097_!HYodwk2JjQ{U!%NueE22UEc@U_ACY3poSWU+1R2HXTRmhtqgg z_95Th;0<tGf&PJ)2_KKV1{+ufrV!o|ct7<wxP1jI1vk|a+jU>-+&vcT3gm2i&<Qw( zZoqML2Kwih!1G`&aQ#(J+OFX(fo0U;iL`M8xDL3kn@^vmZ{7{aZ&wiZq>LNiQ@XK` zoOh=e5}UmUc{Iq5*|54+pUx}V34ON@LqTtl@})co?Aw5SaPFC&BIWo9($eyBxD|1E z)E=F)b3hBQ?-ih5{t#%_`XzO<7kS;E9ZvWPFb&*JT%Pq?={TC=P2n_6S<#j=Yp*sv zgS;Kl%S{D*1Q-Mc6aPE+G`S|$+NP+o1<+pc!_jl#esBqJud6=fLz~q`cLvT|d2)P? zQ{IGg`4u3?j_1pysW0cgP#0@Rw=UxsgE8<s328p(#RQ;^-eKI`k#d}l@#I2scX%Rl zcc9&-&s-n&2JX@K2l9FXI35fIa(y(gUAdAs`BY}Z@@ijF&eQr+>D+k@IF8i~7+=wV z{ape~dlNhdhJi<c{c?O$!6`uBQ~`Ynn|?a59nWo@;!R^)(g=sOxZ$tOSI#ppc(zp` zxu@xX90-QO@3mkFcnbUk|GYE)`9EvCW1$aoz?tA+pbicMI{^7q?wFDCn({1v&Sm|S z^R^dp*WSUvXK$0{9C#NDB0dhF^OF0l>j~@goYVR+Iqm~`f>gJyG4+FmK;M+6Ppl^U zP}d3h6mmNXoCs3R<V|~(Pj!6&=nZUF7&d)Zkk;K+%3~GCq2sjeIbb1p9Qe#Ua_?Bx zhun1s+QfE1T}&pfZ+0G^Pq+m*57PErYo~(jINSQ_JpAq!b7usH3kz@snD^m6wuWqN zU^%vY;PNQn6YPi`UrqZxz)nE_3<qJYl}E8X&?l#y+h=(e>PX)t<Wc|a8r=oRuXFkh zz!<|lmTgf_=}s`4u<gmOV|C2wc$F&|@3eUHv@&_rb%Amtf%Ecga4N9hsV&N%W7-8c zKeqz*QJw2=)st=XY{)dMj;on8)8$eQl@Ei(%M$<U+!XUb6_{r&*Z}Nje_*@vJ{MTt zF|Gp65$C}OU>jXyo&&>ek%!k5YX>FkR;iGz#oNK@o7gMwQ+$6?>E0BT-Y4z9I18}` zmwrzBM*;PrE`&S^?O-3E&eV}Ss~=&%wFjR&KOKYP68dTP+wT*WbM<Mu^T)ZNo|!k{ zuHypYGl;9V*}$>g9e;X^&X<>Yz6bI|a0ZZ9!zTfK#t}e!-3#;rj>Yz!Uvt{2v#lP} z_|^sL0BPLwW-E2b&k|rio@>ZC$lHNZe_H|SNqsdDRyWS^M}c)L0*f2r^O0W!X*=zW z+h_R<zY}Bh3Fd;?U|+c10bY4;oxcKk8FF+}6kUdX9|Aw7eR)c`-IcIwZraBzr}88} zax3It|F(hj6y{OS)+y&=O#}E(?>ItRaNu2ZxU-}$VGg9@Y%5=*y!|>BoCf6f1W?Gp z{nWm|ap+fGq>Rw#yJj`&^!-EB8=M2KNl<D*?g-L6*ApHHKG;+)?3qdf$s^FY&?aYr z7BB-egQ;LX=vYg5bZ*J1_Phc(FJ^){;27{czQ8?HT4!6C&v08N+!Rv>n9#sjeDPs? zn=lD(FNNC?fOn$7X65HwKp!cm&N=N?X<RP#&vL2Gl-jO+7v|{=%x_#yj|PVW)Af(5 ztBJIp^T4HWIvIH}_#WXOCNer1DSz6%eqG%e*Dg;5K9^f@d;>m{*CT*!+duW!3iN$# zbd~=czH4P6yo)HYMwQlrkHDM)Yc%q9VEVma5@|ian)p-ow5>P9ZF4#}1#|_6(U&KY z`tl0)@4sw+^ve<WEN=0`o7rtSpS+iHFV;O~Jp<D?W88-Qej9EtXo~XRMe;pL=`ZxV zAMI;<y?}mGJ5@j0-<C+x0ce-+0)48_%(E-dpYH)IuWp6)^#*$ZxmC*jI?5e|JP4SM z{gp~!2ABz^k~Xf9b{+Bt;&31QuJhmma2^;1wB6&uP#~|?xgBVsjmN=P31{?J`nV94 z{)!HEWBj`^cGs#7=mDRW2Y$m7_AB?2?`<IGi%Gj2bOb#>roIqvjz68I{kDRoU=8RW zC;Q^@@X_|3!un<|OSpB9k=B27rmb$K<15?`m`7QM<Gzis^{)ZruwT9>%14aJHQ4VK z7Eq5o$dlae0JJ|jv~TNyoakFzYxHy4h2a&za&jm31)fvn+PHknVaop@gi{V|$GU9G z@I|$#^nGwWkY~9S@Ey)jmy<_s<#;U6hED>=fun)*ZWb5~QXMs9et*W?oAG`bbYsjL z&_id^x`G2q8-(12^iK-G2EzH`LBhWVuO<jSd+P#oCr;{@SN)<=Kbf|<u$tKF{m45( z9UjtWpC#L#eayEa{&YEQwI`5Q>+RGCFDAY%eOpR=4wwx(5Z{5mKY{d)u?zUPnw(u< zN4n0be>tpxRbY7|tb88mb9}xdW#v;|Q!cY|XVSL?hXUt-d^%sO(>X5mVcP8^AjdZ( z;c$0$S@JCKdm7=9-~{jq<vJjpYp!>$Ee#!Nr+L1`sPqKP<@`aQAK<&Hz-tH6o$EUT z?RR_l{e2;Pj}x7WoC*F2m<y%{{S}ahfQ2!02}}dpPRd)CYGM!1Ag6*fJ(cMh$NAvi zXtVUnrnu>Hx!H5l<o5Okw{`e6tUu76KLl$V=t{mmU;tPRw4ryZ38(5kwN3Rde^nqC zi^1cKxc0Idm?yPobuE|MgPp+EV5^4IZ<;R5x1>>aK2kWBMv;C2I2)V?<n?lJCOD@d z_dy;2oG<qKVala?Xh=B=-&Gxq90qqMBF{sf)d1g0=Jx{ZJ;FDW`yuh!emhr@=lkLG z0T9j>$QKHs4Znpf-9UInoY+b;GHtuKEV)<iN1tBG^hsT3xk~eYO19xQ``o&X=iyXn zzpnu6b*?zqP6rdfY~cKx0!9FzYquW&d6hqXj8J#-pfr6hFkQ~y0q+BCT`8|}sMJ2S z>6Bmj6mn~tb7&Tr4dyhYT<r^nf<fR|Fc|2A)3tR0c_%h78ky07=lT3LaHgH&k1I`} zKp1GJehZsF3h8tC){b{V%IzWG^ThW=g77|>b*uE>z&+NYLeka&$iu*#II#<L7y1A< zUFc5*=)<NXP2YjMQ^=z&W%?Sz+FUkmGI@3)|Kc|3=JB60pHE<Ya@h=4gEzoZa3XzW zzYxCBeU7^9t95RuCOX#^<ubLYlw;-HAmzg6>w%of)#?U}?*-NoU(>+5jc3LU+m>@h zekOn^z<RCo6X4u1&o0Ohkm@X*2U&e&!}=)4x&aI=VE>HqHXt|bp~ClbE0BKz?_s0* zWY**Sp#WYhI|6vG>_MDwoc(S&-1ALp)U_0uwx?c41O2Q1(DWi<_dheMiBC!MZb!LR zo;CTLeE$mV@!DQ~=fxE2vtFhBm<4(<zn!D*o$*x_=6Klqe?%YT=tZy;$mQGyT9GMc z5uO2*OTf!uO+&6mz5-SN`L#aNg!5ok1FlQ9^EgQP)gG-=j;&v5J#PcsHZ3#G($jE+ zpUkF(Z>;trZGD`~YdH{)1JmXF0x*uU^8S6m+FI$49`<ZXzL(YB@#p!i(aSSD$3KUC z^QDCUop7cPA?$og)6#X-cz)TY^tt5enaP*t|6j|>rn=HH*4Kglv?Aw&Rp3Q%9OGfW z)~{s@UttWcF%Ku}P2k|oYO;U2A9*KG&tf*10`!gAr*^g#atok8{)D(Tr|)$yy@9xO ztpgu`^<Xu4t${Vjxj;^vK?|^cc{FU=c;MN$F{bdI>l*s|26I$jyDj~HmN;C=S^i6m zNjt>f`W;rdufR7s#(ZC%X{*QcyaO0a*nO9KYJ79PBVqSn?4$G8aY;LW8$3ciM}eye z{|<R9NOi275^o+iZB*^kY1uOWH{md68vM@0X8WR(wESiCWgYGJqi@W;((A-~!KLfZ z7{>54Y1b3yjPE`p=wD8r2dzL}Zvj&qQ2*MQ{`6tcfpN&2TvdTQ3b}nZBjwmU+VetS z-R8d?r0Zyr@abR}7y+6<Iu2y%75d3qS*p?JzY~VrJbR{!=htbZy#-!_N9-@}d7d+F zbRKE%0Lsc){u@ABWgb*U6L#(8w<@l=?z2n(3Fd<7l>Hun(*V~`^cMX7{CHEpQoo$( zXXx{pwPb8<)7!>(qRzHySs##nwg`Vv+2j*kYoe3EzMuzv=1k|l!nvrPDn}D${1yC= zW6ez^uKu;JDwqqFf*D{MNO{n%gmx$Y@+I%)Zw1Ri1z68|V4dP+@FFnJ3a|i72j>I% zbY30<`hz|o9owPweI=MpU)dXl{jGBne)U78Kk)22#^!HHIs^H_R{efGthub2rRTv@ zz%`fiZQ$DdwESYz>LA~N{4eo*i=?b~9pRhkUC>`gus%i?Ann(`l4sYFyGQr7o8@a8 z|E#sRVXx_a**XqKC-*0M@w=qxXt061s(DC!RM>00irkiQq7V1_K`;2S@-+PQ4U9+I zeFn4w`I-&nQU2t&8Khj_Nm%~Z0J&QW9tU!0o`=D6jksyzQ6Q)KgA&kY<ySt1&xXaD zbmG1Q-TFI{aL4c~`izZ+y9V}1+F>4_8u-71IKMdwcNh5D;9LKTy#Gdd{k3;iza@`% z8=QeEL%_b2=WOJhD6JzOKHoVIY~1<LLi>fJ57ExZ=Q4fUjJGyCIj;7e_s^8Sds8^{ zjWuLb8TdUU8>jwLHr45RD!=*}eQ$Ic@g0dT19uT#Pu=v}aJZ8@i7}2PpB%`U+_VBY zm;mJ3bLKi^XJiksf$%`&R$xBiUP$jp%y&2OX~1&UXT4Q06C4A2g5kh9xfrYkZS`?P zA=#hKVvgQSKes{Of1uCodBWY3ym`jq9zFbqkF!hg+1e!cQI)SDbCkh;!yWTSlr0n1 zR(tTA{c*VG7*5!GO4ee1d04{-kk*0tB>FHCERFF~U=GOk^MAY7jqt1f%a+ZCN6|($ zUaD*!_x-S3q<Qek;kR;}eZo86-I0Hy@8}}jL%xB|<`ZY0hxvOBHas1E<wCAn!5pCd zDn9@_*OIe}Jj&}5(mnx}*^;=t?gCa5UkBt@o4*B=!R<g>9R{@1o^hhHw9m@*q-_98 z!BK@|@7t9yb5p+>ej}!Bx)vM%HL@RE$m7$EF`i5OOvZHrY3w(`y80H9I}3lqQu+tu zc71Z6%o?SS_q-hLXwCBhSV-FkfhujcfC&wZK-$metDAJavHt@%riI^noPaJCk?$4Y zJl>d(^8U-l|EF*_%FoQyF_1pq4JOmaUf@OeT*J6}!lCQQ0f7Cc>yq=deqB>kyp?Au zw|7&Q+$y!@$AKK~0p$5;us@LJLEs3`8_4ZzK(60KIzIWG3|z;DgL$CMcuK!4B>S1? zV(O(|Q;4r3d<gP%<Q~aftgr_R=ayykTYfyha*rHr4x0`9Z;_;Xmt5(=v&I?M_uS#P z4ch3jJo9d&56>BY>0R3N{_zglbI<b{ZO#D`Kr?V3^{KTKp4yC~-MD&jUN_dxkjFh# zb{{p~b(u8bzqa*8luy(9(4X1BwM%<=8E)B|gflPt3H-We`H1J&knUPE3Jl?y{<IY+ zg|_P&x*A0Evm5v#I10$G_9{98ZTu7P26!2~2$ll*9Rajo*I3th`#+XGJOzFR9xWvM z1^0v4YFJ~r6ZHN!*ii@g<Qs$vKGfg*m3~7W_d<IUX5Z-gr43iuD}{Zu@jc;A|2+iA zv1>5=xwj1KEB5VPDzvc`?Q9R$#mO2w4Jo%N+Unc*UgX~_y|Ve<q46yIuDGM)s3p3n z;A<=7&GNgk9?}EPZRSp$GLJU&X5Inx?Ok}ifqLcg7mRBV<8dvvt>cI@-=iye_GiGH zuHd`FUf6ji7c;<YFb(Ku<?1D%eTvn<b$ENw0cfwL$*Xf>1+a|$S_ImzRmajUzS8f$ z^6Z66PZEBQzV!y4N0@t|Z~7qTYD*k^cIj5qwfBqZGke_NcYjWJFynLYv^V^D2F`;X zpy7XAk4iIWi@lWZ1oO<3=m_euJ^jRa;4q+mUZkxV;IsHO&sIQPJ13O>+sIQJel|<5 zgshu=6A<jS!F$U6XVqt)CW2M)%Xs86=+JY3dw$mD=nbCzH}ZnUcrW7_>sYYeyQ`ac zokF+;OlV+MCNB4Dz%$@=PzSGo<v?zq2TL0GB671aGXB;$>D#sRkNFqQo(~}J0k;6c z(eX&1-A7oz1Rw4R!`ia~`53&q4*v(^fZzOSj6<L6Sr>Z``^hDgWv=M=!#D6JA_s$` zDgS-&7w|Oj4E7-DBazOjoj}U3vTgtO;`!2S`oK@;X<Np45gya@h_J|I(AIvt4NCI6 zK70u5%Um!8ECJ3%^`f3UEA5f=OWSrIk-wO=_a^jmA^gf&)^0}=PmywL+&z-<7H|uY zQ+Zwm<~8s>axQohe1SI8F)6(}y*p0UIQ3niFIBi=Ee-ot^joTfpYiM>B>p(uEpAO7 z?_%K8_kCgQ<$M(GD+<Jq0s3U^cPO$49Lt$@DW?Yk+dGvyZ=|jv<fFdujUjg=Va>P` zow$d4gm|h;Y$e-&%WlpsW6F-NZTNX~a7Zojb@vnQ3+l`8YoH8Dpa}9n`%TMtrCoI; z$NE1x9zohHpnc2+bAY;>23o*n^i4cR_-e+8PU@w`{%U45;aHyKPcBbyNW&vC7(loQ zD7Di?U^<u#^y%KSPeeX!xSjFi|HAj!W9dVLKBuDd-vai0!A930*&_tMy$E>|eP#@v z`CMbe`pSC%@8YyU&&ZVn0qc(E9@o~u?KzYiNtqU~0Ia7hdA+9$?}gTqW?QULwjDTj zP1nE4>p<kY$k%}5*onBhYi~^Lr7fs#`X+48TH@!_a~^a9^<|ql&Jj-el|wNFxc^Ea z$300K4Vu9O&;%Bu8|>FP@4Ba-F8vqr5uA-?fSK5@yi5Ttpc%-mQl8{iE|tT8+=~97 z3g!dT7lXFrT-Z*UbMr;;IQ_bg{#;3a=F%T{kt^T%R5}yJKD}=aYvl#V9l#38RLJW& z$Gm@|EPLwG%U}-Aj{-fwp~SJraPPtWR)za^?NuM{``vKQ<$2h>+kQyqdhj2dJ;Hkk z^{ejMj^}?9-=~_~-|tdm9Rf#!FM&5nzaN|r%oBkMycRRuTK|j~+W=F*N;n<ffcAVl z=tTN}26`fycis_%?@+ksasTJOHN4;EZlic3X)~$`<TJ}}mALD&e9EyH5AFodfjU?T zMuP?Mr}eR%^v|+m$0E;bfa{6#P8)uf{%W7>`TaXa`W(~bBD~Kr-`n61q_MBi_QT!3 zygD}Q-E!fZ9KR903b;OF<KAWHg9F#_9R4QKImm0kc<Q>1I@Is!Am#FuOn6u(oIcM= zd6UC8!FILed*Lr5JA;=<Q*Y;k!-4$jr?uU*j_z^Nb`w%=h4w4QO8GVI!wm4#;T+Go zG3ZOb!&)5fu(+>rPZDfbUR!{2I4FW!z*1nprZ+Gb`6S4G8#*~o>^tpeR`y|R?b)$; zI?|8(;R0QIXAx~p-2F6Xpz!_M9|=DN{sQ1E*!zy;yNEDrVfdY>d!h@--+?+_XKoB* zOxpK(!1Hb%><zG2-zNlHj*)}#T~oM!FA*kRz888piMrM^7Im18q1Xs_B|S}RPj*8m z>Pc=t0o&A)-vLBOxt#|l19j^>@NQ}*h(KE3V%m~JVc32co(fWav(J1!44=ll^t=%E z(c{pII&r^oDPiV&XjlI{y3u|fnFAw087u&czzSgh-v?=*l(zYNym?yoc{kd~#?!F- zgLlDc^sf{A+(Cc5qw-!!JJW`LPa6KlcMR^IgAI>@Pi>q%V%Rgw=c&MZX(e+xcLQPe zT9t9gW^e#F0}%JUN(H|i;;!9$Qa5W@SZjCt7vo6#ot3v#6Ta?8s+*2Ad?=7t<BNfL z#)D&kdhG(*^UZzHqqZua>Qw$xyh2!{apgSFDNfD^-$PIAC)~5DJHJ5*`%v~I!G24$ zc?z%(UjzfdFks*8V+GjftlehEY1sUS$L(|ZS$=vK`m`%xpBwh|oMp8o_pzamhY<dE z!mGjU<b&JN4;X`76?pb4<M5ply!y?4{%q{>`@~sOi_?hfo4*5&2PY7Zk>5me4i0*F zlloZGOS7oEDbx32Cfs(MX<VHQttEQ-n6N&%OC$ag@iIvDslC=4kXvmx57N4n<$UsO z)!IP`mp$Vs?5UJ}GU!BDuAKu@!EVI2rT>S4eHqKo0s8aoo4Xl)OVwn4$xjoI+rA(V zeD*lF6YNIcGyMsB8~y2n)SF3fH_U#j-So8F#nf>*b<G5<x9*kmzW?|JaBqyC4ex00 zAw5SNj>5N*+&_BO^Zjpyyx|?U{`NTVZNT~8aOD!Db-Aa)Ke%@b-zxo(c8>z1GyThF z!fF4qQeC_c&aNfjhvkra0N=A{yK<{t<UqDu;B#5RZ4nuP>~q6&<8V(A&OB2HyB`<^ z2DCwc;+=r}>bn<%?Fz|zkrNo(wde_-RsI3|o?lIDPk!@Y9}t0V4OwZYAJg#rk5SLl z)OkFTyNOTr^#Ib*<EPTwjwy}1_F<ou4sfsohyix0zs(;FCqJRSX9`idg*5rX&xY^k zPC>$5aWYa~w<9m-9N+up<^St|y8N!rxPBsh<9suHW4=e~D(%DnB-PL7YxufaR4O4) z2M2?LKzFc~=eL6#&_=CKpR4o?B*#K-jdM!e*mkEl**7ml&IWVAEHD8~0q8u;L;E`d zGy`qj`n!R8KKwQ<>`P`aMtqWIrEovorMhWtIGk`-a17WD=v%Vm{*bzW>$u<ehj0ED zA+vc5A5GdJne=N2kIcl$<Ndzh)ud&^9Txiq@5l4*Z6nYZz)|oQ?3eX9+G*Z<N$fhT zrC(vL-bNZchi@WXgO<_1<=`LG_f^t&CC#(ct@OdZvA+vCYTNJ6ifgyp>ckp#ASZ#7 zz#y;>&~~3Bk8_~iI^Z&gF5BbQ{QB8GKpy2-pZ73mZOEm_xnMMq^A^w@XuEZ|ErUE5 zhV8kgaW@;@U-zjdYi?hp;b(yU$NsvW^aQp)F;429*Qigw;Qpu|b!iJbgLcP7S<>~r z6>KWa6W+fbobXioX`}4L)a6?H9QZZ79Kk)zwQ$3JDx8P@lRCad_*~N1Gln}#>I}Af zA?f{q?{N=DGH=4)DPRrpT|;<ZRHmJiz+PZJeeVkFb1DsgT;15mw6EbkoqD*gh95!B z24jIfx(Rp=dYf|EZkKk-mnu=PRc+RAR!`cZoXM3O!%yJO{=EiPXQVz(?wtdcv)}8$ z2cR!}<nsyMfa8zR;X8$7t?ge;?i;TlpFTa?ej2vEK0traA8CK;)OR)Yyh%Mn0eL;g zhIj0LCH;dW&2;(kJx=%zVSn=IS99=v=%zfr^9p}s5Psb==l7(HcM|)7nE1BHlL70h z_ZQ)v5@XPRhxdZ!<sKuf&*$;{@6?B14}Z7gG$eD;cU9qia|``<Jo-5Gl#a8^n9{Iv zcr}^pm(;imt3}ZR;1+Nt_%=8ad>%YczVktO*{1Ss>k9rj!>`ZfMV)Im`bPUA&r^W* zy9&tj8lXLC$8&)Cx6A}2>sojxCO3KN6wHJ0`?6v+;r2`PF*~ko_!Y`EQO`=`czp9i z)b}#+Zp7g=za_fVAKpQDAo?AQp1p%=C10bSJbDlJ5vysJeBn0&>;uA`V79G6q|Jq2 zx#Hffat&a;^*%LlcQw+r^lX4#hk5!5Ww7_~zTjTu0`ODXJ{zzuguli71d?^h^K;-> zy{Jpark?DB;cQ<FyH`5A#=afgRg0oKkT)PFfDzz8umxB|zI{Npd>%cQ8_1^1qj7W@ z_*L466rJKk-`c76S_SG`TU`QfCvTm4#ahCbF}8;jgm}L3Yyf#rsWKPnpZ+D=hitf+ zeAd$+iB7^E<xhpg9++3*4wN%Tc%Si0xbf~}?@hiqeB-BHS@*)<aK)#3$6|VTH`|#w z_Zp%7-t==lc$?>*bKy3eXGaodovpKvDssN9OhitlopFTwBYOh;L**>;OhHDp54ZVF zg!cvdX#0E^aP4(0>UA;5jx`(ZhE6^N=hir%)ws_?%JcULW6#krpx;(^uFqXSw!Gnd zgWqyPW}l<W;1BJG{W%?&CeJIu2*NYKY|skiwi$HeS)Tet8EE79r||x4QDIZM`36)! z-KT6H40{)$JczRLd=5O}Z}T0%7U=O4{!X}e20hSY9w<4JhIerA7WQ)Z-mss=m#TB0 zg*{Ri@?!7qwNl;q4!CkI`3lJ$Q}|Ajy_5Uk$^_CTv7fq=IBRj`3go58F9G>=@3lAe z-A}vBwXo-+p77g*f6xa0A&f_zI;K4OX**uy!_mv@V0bP3rZH+o-e1FZz%+0nh=J## zm&i96)R(nW*Fe%hzQM(?IPtsMrd(>P+T$xg?pncaK#uz$2LSVZNL(I<BMr;D^C55l zslSYr|JQ(F$7i|r#`YO$u4lpj?}Glli}22Xy9C!z@Bi|bq2JMfd!g|Cak{UWg09~} z*BwcJkTCu;+#7vJn&(^X`2p%q+r64R><^re;X9l&sPnso_XpT(aXN9=fT6(smNv}( zIK1oMjk?~a{0rbO)UhMat%v^k?l<^m^_RBwS@Owh@V)+?F`82gf8U@qm$3X!0cU~! zpfgxR-eW*|CdxOsEH|X_6wPtMgSOcMW&v$gJ{JS~CbYe&Kv}1}Qs}4kLE8iO5(9_} z^X4<{^d&CepEbUA()~SYSo5w&ci3ZC57D3BDEfU(Weaq?H~PO8`89OPy?w=fl(v36 z`PR`N?$Yu_;_QF(2a|RmWwBT5+t?TS?tN9BJ#kqdd^y0!`u{`-caRrT?*M?$&|d9_ zd%3WGb6)I4{B`Q6f>!}+lXrLF%%Seuj_r1I(Kc<1TJX!^?*!ahWBw6u1vi7Mz}JE2 zC2f2%$ettf4Lz5UDZ<?!b|y!o<78cRuQUOqHf&yb84mJ<<=r(G{}|?ib6_H2`Mnri z0EoNS@V6I%b2;q;@|3qt>ux)?YCCC-Jlcl8Aqd~hOhu=zk=!fzt~H!Xu<Nk?4Tp=X zdFDQ8JD$&@57Q{SCvi9rdnEj+-#UhS<uj4CaWc}okw?huJm5acy_&zh$jw9!0@@<} zJlOaF#3SO)5&Us@Z@3ouWAHdwOnoDPYm{?educn~G=66lebkcQsn4i!ekME*DYwXt zwmX{eSAe#AKV`as;<C-_mB%_d)~@75U#Z@mUvfAMIR*3t&aXUqMZF=%ljbvgWw@K_ zf$RsE58-bjw=%Xl#N8*~hOQ1m2l_?VMRn@k%>c@$W6Mh0ZNw|Am1#JY-rf8A9pBS= zJ}sAs<2!xd<2POP7IY5Jo_E7<D6pse$;9!+;axiCpYX0|8S-WD7=0NEY*P--CXI7V zr6c8NKYt}YVIk6W7QXYB0Q|G>#=_j4OMdyB1@JM>?GSz*`2*tGuC}s%)40;HY?M>0 ziNC$Bmh6$`c4dt@0v;i(?ZSC99t;7VH(sI4DIlx6G~7a4?u(uSYk+I#9ALV93VD~u ze1lWx#PCM?N~At~HK70D8wb~ygTMwjokSWo6TU?ljIK^X7cU^OnH-!{Vszb$=V^aF zLux15oPYm5%^UVod!yeisOL1KduQ&3D_g?tEaK?jJ#TIb&#`0eD}Ol9NB@F)^cnqu z^J_OCr)m3B2yaQ>vGw%tBh+uCuA3--Zc<0s3;&Mio_E+chHrn5Lmt}z<%3?<P}gXX z+KBo~+ezgW)nt!6q83H>);ME<6@;HgK9L~U?k%KocNP5d-pB|nqU_-yw`}uzn`pBc z$d6%dwG()S_PZk|0R5<(uO&^6^`&)qmS58>^9I<V5YD4vPx=mFZFXnmOUO}R4*=)k z%#Sbgycyn;o=3ROvvi#QLb?YHzX^aN_szja7t!_6K;FJh8n#^7g6GVm%GZH=TlZO0 zXhXlE&O3s1y!e&ivrccww0*~pZwdcD1?zO*G>$f?H{6@p=PQ9W*#m3^JooE=#cN<1 zNb74)>Qm=|PPK%un~)FInEyb2E8t1eehTJ-+dvC&4(tQuwnF*oAP2I(S)0^0<;<}2 zS2#}jJgSh~oyom(;6w7rdtXq7U&}sB`mTj2d}qtN4Zl->gYceZHRXMFEAj%cg1qF( z4?<7wcSey9U+Ou-zmpVvNIPqi`>0e$VJ|~mpKLkzqTvpy8<Mrrcl6;K<(0H|C~e~> z!~39xw99;OuNC%U`fGfM>qOWK$U{%i2{`^L7{qhd%<#RH{`W_OYhXTTq1@m`*$>FO zCIfwdb*1&S<u$J1FMymL489HIbzzNrFz_sR2K<V&B}sZzMryZm`%SPnNYA>ZDt;A2 zAj@ysu6CGj*rS}u<5VE0_EF#M{Cpg_EpjQc6L4NIN5dV%&kM=@&(TQsi}Dxl;#uFq zy$ACpeBUhxL(sAN&=Y{?jBhsa|0mnTVX(2ZZw=|3@EwAC*l^}-p^oo>y(y1vdcPFz zbzMU%;2HRI?)dCneD!tYy9!Xoy9~>Ob=!G>j|pRHVN7$tI{JDeb^IAD13yf{VK4O_ zdB*~M0QrKQ>fh9nb7VA7f2mH}j3dm`(`!-mU2q-XyrXRfK7Wl|1s)~sVXz4N7~BnR z0+va+tyhyf$kH<IBS9T30>&#9Bz*2eU)pP5f2GZK2OGe7j1S$Wdkuec9?rD#i%!CC zY_L_&8NSnW?7nyLe#bR0%ya7WuFrb`?*hU(gS~6;)fXU{4{2Y#`|)h5J*H`u5#;GY zeLcXw;2h%LLtX=V1LjIN|KK~qyF7Rg?{MFu9>Tt>3wM{=v%Khc4k5fdaNnWdklQ2Z zBYP>&I@)URzsDgz;n_eW`{`h-^BegsCnkbEU?n<Hr+M_-o^C&1OZG<dkw1gWe*@0} zd~x(562BZh0`3KJugy*aR{(vocDuHk{B7S7JPxBxb`{CHK4b-cyYRd(c!Otc`>+}w zrWcam<8<XYYo_0$_%6i#L-?NTEXL11ChSR=r(xgt0eLtR`rE4T+p^i@#ilDA$TyVw z_G*;Pk;nTz?;b{>^RJWt?>xii)4sUAhVNk3XVU(S`X^Eb?!$SunX<go@$Wpyb@<MS zeR24G&}7QFx03^Xj`LMcSxdv3(}DJ|OWzlVeVz6vx7*QfKYR(c?i|t&=Og5!<Z}#F z@@Th8>(*BFch2)yKwr>SpT>*iQx2&`(G9i4MzvM_@GpTJ%PsN9wYC*Z2Q6SC7z2iZ zo<N^G6KJpPwbfo4bJ)F*-|)Nd^IeGN4&PaZ-x?r2PX>Nh5k3PwUPyc_&wJAMwQ&3z z>DW?v63<xMJTruQKGwjX#}Ak{A5!-l)UBP%i+e2U3-94(k}uOY_ey@-;@`P5UE2@u zbMU9(u3#PY45Xcl$P-hKb+-cT6FUoMlpiC>7v4=>fGqQD9MUo9&#x!G6?mC3V4t3! ziZ>@?3-9IOI?N%@W&4s(JDmplfF_XX?`Gkgy00d8g<WgO-}rG1+Uo;gIcf0d9iwNS zNPn!&@+`U&Oa<qIuY+U2;oys4Ep?6u+4~FYeWH-`rJfJcbDlQjUehywxWjedu{UFW zvk>NOIJa<q^bS(K^nvaZJxAux2UnBVc|907ZuI26dboq#g6GEq_DsI-40~tS-}lLb z&kf&!;%|MQuD!d5_DthDw^UEzo$Hr)M*fh-Tncwk`1|m!;V9$`)_@zxa}ec!LEkv% z+Q&RHzc<j&x~HQ4aKC|n3GX(Zq0idxsbCNo$(XCWub)mn{E5Fgao?@a$}<+f9|%5q z0ORb|j*UjOgp0F~Uj|<V=K^f7^dMLOenK2OjaC3`HhPG(Dah{w@&##p0?-eC1$-Vj zKR$%h1z;*@Z%%Dr_*8oSjAWnUocBB2^7V|R7l23i7UBO_%9`eP%kClN%Wp}-?=ntf z{P@c7Ek66#;PdMF<nOUxK^>jJ5c0VH!G~6I<YA5Tj@~_$Yh^e;x~5{s;lBOP)Xnp3 z|I2fDb_pC#MMjj{9w}c(1LltR8M&6Gus72u_|7l<4*o)(<G({+X*+y3VOxg~W*rFo zCB_}@z4QzJV0`4S-$5ScK+wU4B%j~PhCPULIIG)B(EB%m-yaM>ei!@zV1MBr;-|=Y zK>p<YS^(F9<L60#g0Nf;14A;9*Y2P*c%Hha18p|j_P+|d4)I*S6W&kn!I<?|=Mp~< zj3Lf?C_g#Yp`e3Xd43+@HHF~ADi@&x>^FQrN;urhIIrDT#iSoh+J}_E&T|XMyCb~e z-?W49{n^E&6#<--ryzHyOn0PqqrEr!Z#mxqmEo}nyju+4%aF%)*mrZ~R??Vn{&qar z-Cl(COODU-1;9Sedh;FV*JJdf1{Q*+=p*yS@8WWIk%uw*n;?CMcN&3L_aGAhYf#cJ z_Av5tAs7w54Q>SYfJL?B9^x^=^4cGyTr7s8NjzT#o+bTepnZC0TnEmRZp60%w-c7z zGDyqInSI6I=}$wtebcTpdD5_Zlwygz@`Jw)@4Y6FrjP0ewqUHBC*;okm3xlxJ5Kak zzn<rpgC6A3PV|fJH&$VzgLpoPH0(v5%QsT)E$Vo-5cVjZ8+|wDw`u-np-#QQKQAE9 zKhgJP=z0ou52en-$UB($56Syu<o78D>NioQiL~2DD<ggW7-g7q;oKv~aGRTqJcPW? zC&ugkJM=|vAEGVRV9V60!?~Ov30!M0qOa~f+w;ZE=>L3hE*Jx_%ix3OCo<e4wWIH# zcWkrtG-aF%JwciEvdCH;!O?IK?)}+^wJGlz-Mehpp*$Qp#<qDj#`Oo3_a44Ho3WEW z{0)$flw+;S;S=54I=8ippyNKIT}qmJqb&*Jcgy!6&!P<T!?iB>X!fCDpLGIh_}y@a z(H(gtupMm&yO2LQ3+tP<w-dn62YcF$yhj20=e!B;Zg`fL3pn@pN_F~}gWF;Y5^l<K z3Exkc`QqRB3-5Q7+U|*<FJabF*YfatJ$$rhU)Lo6|Jcq^*WGaMc3mO4@7QRs8GUy_ zcTGUQEQW*Q!HGbw&zGZ2{<dN5@oVJMuC>v&&)ddFqOZB|x&wV=>_IR6=_mH_nPu~F zc&6>v@1~67Mt5a=oqGyxQ=Npr<s;A2ss9qv&IR~#eOY}G`R5a#n520p<vGf;kiOe} zPm#H!4!t+@9@x9#@EbjRqrN!Ik-5|}1+<V4pX%>11F!l7=2LjzIt2L*>bRDClL`Cm z9OTu&xkbEq3(ppiPJi_K<#~je2jRP!1E}|p=!w0t-^_$}ynB*oD*a@Rg|k*4B=bAm zNqP1ek?5#h9m?wnpq;qx9tQRU`+$_6X3Be3YR~@V_%nQ}-;spBd)25X{Jn>R8OJX4 zcM^SMyq+mSzD6GVy|G=>yk|i=*X#F@|1j_^#tPrwDY^bsIs^AfpQEms=;W(}j|KZD zdd@wG#9p+e@E+zhzM1Grcx%$oec)ajM)&^Rl%l%dg1CB==Q=iw-IUcYb0_S%wjnIe zrS55zu|Fq)Q^|J|{kt7`FVB$fnaj8G>~O#w(q|V*&;2OLQ(i&%PU@BK;k5T2W1z2L zUF9qh_72~r?D+uQg>R*1q1$u7!~cTYhE9V%^YGal<Un^&O3o&m={lP~4ZC0R-Cr7S z$nc(x`5pH4jWqYA!G_es8H|Z>hWkF|?56Sqle?8R^{L-rzk5>V3c~u^Q2_s|?p$A8 zm%}|DHW+w%fOOhY&wd}_cPakOyl_wC8m=!qE9r+kmeo1+=1(Et+J;}YY-jR)lV?lG zvjQpqUn8CQ<XP5nxGxTMA-z{D&LvIG=&OD|?Dv_M?wOqn`irvl{gix57|$=sdnI}4 zQ@Hm!j=Vp_KkUl$>qvuJ{dhPJau4I3X85*|bKEA~WqhsnnAKrFIPD8|16zQsO@0yn z+$&}C6D}<y?R4-Y&s}#L&%@sg;QSEo8wM9Pru$t<k-mog&Pe37^nDUz>YU{_)5lDE z-qUz@m_si){Tu!&?5TTE=N&vdFVTzpUDtHahQ;|n-)k7@zBK$6{b}@eHTm$P`pP0Y zR)67aihjf1fO_hr*Xgg{s|8#C4tXC1tfe{n?%$)-|2PKsa$&CwFXdUJ!L4PT7uurt zjec|NdvtwHojKy)(5gR9{^iI;<Yj!$!!S?LU-(VJp`<bQ+-rpL_{4C}aWc={Q)P72 zZn!i290XiP_0M~P&w;KDS%Npu)G2olZVHF{#$(8rv0vXSZuD(m*qk@dX~oHmhxzV% zt1>zdd&`c*3*ef~^QUbp{r<=IGG%pkA?47q?|l5WD2G178R-Jztb_XE`qKa|>b8ZB z<um;K+GDAQxsZE=^7vZq)jIXlo=3D*eSaO^-3Nu=MbfTor+colw)PNt9;CijbbSN3 z4KN47_Z3Hw58IY=ZM6OX;a0*wMB=C2-@6a<oqdtM)t{rz#en%5-V^Ojp2gJ19^UT{ zf=?g7v(J&P-Ew9N-z2Pu+s4|J)l;|&Oz-c<V|V+*kNYauVSV(M!8YLF8uzrw%>3}4 zHI0{k%d@*dPw*)9m~SWApU*fCq(7&EFK*(?{eSpd59r@>fWO~y%weC@i@e|Cx!8(v zICnGcreV*&-ZN?!^6TDNpBwhY-FVg=z*$)T=J6c6)y^vWlYTk%&Zd9psD2~md0xh5 ziml|a4tQ~|W85{iXnDE39?AUiyjh%ytR`{iSnwhEUwwmhdI#hC2g?LsZynAr+V<YE zjGqY{)!>c!mir0#75S0gRfK%ZCGSDQo>4BZq|f*p|0Z#`quv#%-FkoF9dcGrN7hJ# zi~GT1@Fw^QY5LgFKpWN%&m`S_S)*)tk1?mPF<yF#JU<8Lf+Bg-Hde>Uw;@f8^EAft z>ZUS&uNLle&gR)f#>2SPdHrU_G8!FWGhu#f2kHqOyPw!tH*NTvAN_DxyB?z~Hs)M$ zFYY{X4U~8HzhTdOZ^DWDIBiV*cyADVym_7^j4kRr^tJU?@;^;o@SS@cDW7nst+|G4 z=S7~CZJYEWbJTU-{j_tyXU@|cT-gWDKz<uj{1J7~hcMT+qc6|%-tZ>k@UQ*qbHZ8i zVB~J#V)6@g<(*sjwqiS^+-?P0;ikRw&@FJW9J~#7sqr2WXuA_Y3m5}-0}Z~ydzLqu zJ2MKK(!A^V378Cyp`DalCGRv!H^I+D`Z#WLZZ_uAuUteP#^JloFxMHYoYvt;e^^9c zVNU}0*|V{>t-i|-BY(~_=8%3>+fl#TPH_rh*0%C8(y{OGUf}cer59~>CEk(e@MIm@ zuYW7ly=?H+%$NF8fOWh6BG1r$k#@>=QSL(0<|2ns{#x>%3z!#j>7BGvzU%s7d0WBr z(@Fa&ar*3<5Wb<nPTVKCw+ij7M3Ub%A>3&>9>PWXs7@-3IsDDt4sgJEJ-jc-a$9fg zgMH_AMKyUxuqE6a2;_DWxDnh|3;$1*aDOOQXTs|<fc;+h8y%#DJIL>lw-4w72GCxX z-*@46MIrFx-Th|IviS@@PF~h>^_}09ar8otM8@DM#y1r?7GQ51>p33X;DhVvH>}${ zS9irp#LJXtO)$N<9Jve~;`j6ko{7TxJ)H0kJf}=<HS!tqF)!-aqjwmdt>x48wfrn; z*l_M%!V7tJIL~e+Je}~t)VGknsDHTCHm$>c>u1Z%OZR4#uTq|Ql>0GhNY8fOtvT;J z>(xom)p*97aQ=jK3x8z)!d;8~E~EdGz>DbGb8eQ~RHqSK%!AwKK}W({ff!r`?x}_U z|5fP+gk66dWy0QJNnz99bjOeTz9@bEDd}3@AI?5x-1r;kMw-X_Q+;Y0Z!5!DV>Dwr z23<8XPIysIo~7KAZI=Hu>hDAPL5bdi?V!stJb7=Z{)<n57kCa=<?HFouNVjW&K$NH z>|_k-Yr&($7m!yjir_%v_atrCe@2*j<b8%V?Yi$-%rz$bJvj6n?u+w0CtrRP`Dv@J zFSvkw*C3Ce{C%XuecAbES#;`oxl9?$*@q&0>qEjh?+WrUPr^B1Tk_wF9(MrVr=AYx zwOMmhj<<jt?RIOx-YMKOUjb(ifhUNk`H<n8>-!7g-POi)@0It<<kMHM_HTTC0%67+ zzN?Mea6+Aak6CGE4Cv4Cc*ac2`kPDrTDg^H%>A&gp{rnfgNgrWQ{GVK0{G&58t#11 zrS_XYj`~MX$6ds40gDNvJJ&<sv1xy0+Re>H;?L`^HuQc!atZn2AkQ50UZip*dGMd| zZr*YU+(~*z`tdU3p2|2E(1&N4Ypl)TjMPFN?B2T+*9PaT@23No&l6`(`Aud8&RqY^ z>)b5Dd*~1T%Dq_l|D#c7p8ke?&y(nN18vR#J;7r5)o(U|;Tf*0RlW%T1K>y>>zZ4^ zXMaMzlw0pYdQ;zP$YGiEW2%YmM{Vvr@Ua`qS`YVJ;dfHbxkjC?jcGXCCp~~}(Z73Z z_dV&eaKG~%o-wz*w=H6iVNI1YbdZCakQW~jzHK-W{r&-c?Lht>;1u#Ocgib~iz$zu z>y)YVMz24^f1tm*YaY+*%$MSC$p@!((#y!4eB(Dfi-+Hb$lG^GW8V2&0q-8e-li*K zgjapE_UtqFeEORrWAkk6y9M{p;l1Kf)FE%o?QnL)u8a8n^3O<P4ivHB;!WhmKPZdT z6Yes0BmeKv<JEwDYj`K5{nCE;4p^D;HoKbao83RV)-I@pcL*DwYx@&`<<l~$>_%D7 zQ`&Ev{kUt%#_xBWPprS;JLpW?-aBRMbbhJ_&mj6s@0Y^w5U0b}57FCK89QrGZW%hm zcdB#ky-u3Hp9_18576;L<UN5j>>}JleVcM{QHR?)+-bk{dwJHKJm^2f-$#B3{++xa zhmJi587{v~_z~pw<nM%TZ>B$Yf|WpDHiEHXyY6r63&{(Q;ho1M>XBRL0o;}ECeE1k z2jNcZ%jBaE-n;vbE3E1Fk#7d+hf(G%Byg`-C(Scr_%04^L%Y||_FUS&8?=DYKs!$P zX|A&80(-;j^)=p!fJX>>9!m4H<!vs{z6L6k8xPWa|CciCH*QGAn%3c-x%ex__fs&7 z@f^r_4kE3E@V4kdj*nxk=sEc7rATyDoX)cc3t=5{ucYr&kM3W}_&d)M;T^y-(mo;W zkDx~S7fA0xeGd}<4fXt;=YK-}8i|d2Pf>rJ`0s(XjepOzBJl-&GZKE|FqHPLrC)uh z<452Z<e@*F-}D=G=7sHhe;V#Yj_3Ju;@GL@So`UHqTi^8`N!M{^EFSof#f+PsmDFM z{vdn@JBc=*V!XV=40p^6k@{$TbIQY%Ds~CJ09Wple^g7>T5Z^KZkn$l{o4qo)=#Im z&G)~FyOtH_GB))EkG|iwocoy^oE1U1e>#(ASCDoS@>0ge9fWsra-aJ%`Rau4BmEzR z#K+9Vb{V_xhV;3vr{Ua59Yy?LnKIqB8XVRCM4V^ddApY7sH2QsFWO>oREGcDn>^PJ zEf3fF^`iFtQ&6TH-1+X%_lV&>4sN_V4D(_h`JHc^EzIXRSB`R&4QHt%2{T8$3(4zW z@WcMbPkwXM?f#&Q?+Wj@dLRdYy+Kc~6?tdTZU^8VM^3fd*`O7qoV8Sw?_cEcT6l9G zwTSQxa5z}R^E5BAbPH*jc=&F(M<IOQ6~6TzNI3iae+Y-WclB`{W5FNiu1)xLZ>?{t zzXWb1eGzf|Z*DPp(QjV9cOp%le?%U1=e>KlyJ7DfzH59DU44t^=&ATi@;pZQ`Gi|Z zTa%P4S15M|b?rm^2RvI(zW2cDq)e_(7@ph*g*z$2?ybW+AbrZ7=y`D=e6y9CN?!bL z;1XH<H|l(vIDCZPt@NcW`mB!)zZW=`y6&aSo#bPFr{^O1)u(y>4)0mcK^{OI|D>Id z0Y1t7b@--rHC(!GP6Mu+eZcs}eriRP`zzoXl{===e6WzP+#Uhu@$7t1W?fBrno8X8 z4uwRQ-1UUt<-Cb5JD^|r^^O4l5$<X`(l6H~%Q#=sdNR`UfP0*<jy_2Kcc>GeQ&wM9 za4+M375oCATlX@-R}DmmPl1)-X3}<~{q=EpFY0gPD(FeO4gMM5T7HW#`nH|=8<fG< zYA603H`~v_Z|;S}uKR8|IH_B`j{w+9?t02ROkU=oc3CICdndo2_8mZR74eD4M|noL z_#41{a;*v9RP0Ik0>U}Q_-DrW8_MA`Tyt{FLBFZ-n}o0zWKM*$&rwKqxi4T1ajzJD z^K=F}-45uNwb^0d_RK!{Wq5i6d<mU@s}{a_E6pKn+F{6}K!$_xt#OHcv_8P}0}9Fe zgi*A|88+OntKTC?-x_!}!GDBre!oO|rY`4lHm+~-T%nyRy#ow)#9wCY^8P#0D@fL( zatqIfq6_DQwgg{gI4)nu*r(Cn<4J#fC*@sa{b$rsP5kZiTjP)6IjpB}<e5lY(r#T( z>(<43kXuWc-y$jJy{OP$!}mASh|^xUFZ?Fs@{X+^ar{bsIr%Q54*Dy%^=FaROZ~z3 zTi5O6f$#FYq%ltW8Gdv59C8YJ{2b}>{3`K}sJlD)w*Z|<XD)e$3*Rj7i1hs8erf_( znc=p7jXhp9IRjl)<F1hSb>L*MGw2Q?a5#A~yo7Jr(>V6w-+Bn&ne0RR-=OU$NIMZ+ zM*83AoAdN1gl{G-Er;|x=lxxp<~J;!4fIp>Cm6dNPek5LKIivb(#zy|gfx6?aT!3* zav#=b^cD6P8`!t18_tjJLBqL`IZ=nR^2_A?2X$!c*jMoD&+!bqDKiIhe<NK^*CFNR z71IBU_<s_{&)R+%(^aIeAf5FfwDl{_uJ`gBU*KHwyc6!kZY9rrFqN^K3I>z@0D$YF z`R7soLV%C)eMtCT`VsoQ3-Lk3-z+451MYRCHmh&`9eNxG_63YJ?5Cz6`+#!eOuB%u z+_LX2-3DgYn1jeEK%VuXoxw`-oDWKE&a(3KMx6Yn!?|}8ed<sDkAyF5R=?;ygy+`c zWcqpvIB^q~a_V=Z;kVHZ&U4!B492Xzy#SU`ADjgquoc&2b>*DTy+%6v&Mib@A7%HP zchW9ncFu=y%^pC~zWe1Oyo7gk&r|Ooz`K-PgOoRTuEV8wg08pqUjf5#74DNakoP|b zGp{_ac+cd!N9UGjuF`e1a}IIx=a?JT6V7Su72NxW_l*Z4uO`kIi;S`CJf1@s|L$FL zxSOPp?%lP6V5<iZ#&*NEkar;O0r<%9jSK5x_+61_%*TPY+t6c>>#D(SOLy0}<E$lr z*ROy)66_5=<hk$RX9Ddv&)WNPys3^sh2-}ww3FX~e%ye}A)h9FF#RCz+9Kb++YI)> z*s|~P!d-QyPvIQHe!;)d;(k~gaNdXe$0gM99ARyUxu5$x@|Wa6$Lh>?diqGu*x}xn zITh~4@a;M3kuUFv%gX@u6yY@oZ?5ZMkNYRm-y}|+uqVEQxHd-JIc(oK5`2f{ucPi2 zwDlJ-2dv@j1()T2lII=D{1M3<D%T0$1Ak+Yzo3ujl7_wK?gh+M_wViz%kp{vWoXZD zc^rdt#yhw0_boUBx_1fd&Sdm^DA*Nr0CJ*l_C7&f-jAG94ZgR8FZPTR-VOPl=oL`G zPCLcPT~?j2wp#>Q9wt%mAg~J<2_FS?JBs%I8{k{Q@5Zs`@D0O2#&9oVxQ{WxS@?f= zWa`S+8-9E9ImXzNe2gu854bC1???FusOL$roO<wib?p$n<PYKbR!I2u9?5rt@~fSP zZ(^}u?-7iv%W%j1?@iG=oQZ~mGWEF!^4@;<mV=XXkaqZQw5k35i0Ar_R>JUFB&~8R z<Gqr$9s(aThnq=f{%HHb-?N_RbM)PETmCt5+V-AUU*`M>-!KoS4E1}~3%~ihg1V0< z+?lbs7uQ~Y4Q>bD2Q2`e!|$xOM!pD7^4kj1JBd39?^a8E@l0f@>*3YpF6$U%n$|{! z?~oWz_zm4P)W4c_PCl4>`s8qr^H=(C7kHC#kL20W^!a?`#o)VOXY#hGH_Y+N8EXr9 z$0XzR9g63`@ILPr^n$L6FYye$l_!zTy6m^e;XTR|JVWp9QT!e)-0_})+?}-F&<|`P zXP(z-<FCjMk%Y^C0dS}O%jiG&=#SZhvHx1si9HxL?t8!DTAshwsP`h;WIp-rOL%8< z40U6h??mK(kGyY!-+-S0xU5$w`#S)SVZL`K9ox;_MSXeF&I0frzJ<RTStR~>>VFj- zVyo^U!Z-NXbNHPJe$l@t9sWNB?wQ31km_{*8ukrN1_y#PoxA>x;cjrO&9ZaYm`1+v zyVu^d-vmc{6q36k_o**|r_kf6Jll)D$uU00zpbL*%*|j-k0DuW!d(;NPV224%$UZb zhe<r2Mn3YE7a;FNVh81U0Kes)C+H47!tXCfkbWO&%aQnM`S$<O67KEpr!LBPc5*M` zdD3@l#nnh`v%ZGsgyq2Zy?!^~9?dh9JonYE;n}lMc>`(hfF<O0?wn4YuhY(j<ZmSn zT?D&zUUcRx^(N`qvS%^xshm^AS13<kZ700LWX*64j<rI4?j6JX&dZR;@oXE~_ys!D zUS|N$1Kh`k-+La1Wc>@jSC-p{!9*aB-fif6<681g=;LbgTgvdeS)Qj{N2Is&t-0%K zIExj~<wELl9XK8=A-p|(xE}lgxF`5AdOemg+)kPAfioGedx@(U!#6kaYn$P_aM$WH zczy|G%H+i!D`yi{N7~n~kc&w>kMQ*XzPn*F?rV!rlfE-L`FDIXoQ1gn$KH*22c6#< zOib!5{|4PxDDON$pWXx4|BU=6lDf)Oo;T)z^}6PlUqCX~!r$2JOr6>wb1>}nt|L5) z=g$y_W9>D^v-(?<!&l^%5~eNQ{|!H`W2f#IjsJQ?BhTtJvA6|x1hylk`JxNYyI{g) zqt7|;!tq!B;OirgAAV|w=sVHXy+@yO>Dia`J~G#Pz`6Z<_sR7>_o7QCTr%pyGcUSi z^f{&v8P$C0Iiz2D{;2Wi5Z|ZY!F~Je+b4HT?*IAUHbXj%DLmVCOyQ)R#uVzik13qH z_n5+e95|+M)nQ|xX-r|tF=Gllo;ap3=hQKU+*xA^4~`jAIONhXh04`q3PUDSb~<Hm zrR-glolDt;lzoD-70Rxp><g5Am9ncTyN<H&QT8Lsb{b2&V`+CR?T)40v9vpucE{50 zSlS&+yJKm0EbWe^-LbSgmUhR|E@h`v_EyT?McKKOT}as{C|jZIO3J=K*;gsMnzHLC z`yORKqHL#T+HI!YX4-A0-DcWtrrl=RZKmC3+HI!YX4-A0-DcWtrrl=RrR;Rd-b&fK zC_9(33n}{qWh<0jN!b@D`zmEuQ+6F?-=pkDl<hQ*cE{1~INBXYyW?ng9PM&E%8#Sn zakM**cE{1~INBXYyW?ng9PLteI%RLA>|K<dOWB2#eS)$T%C4mB3zU78va2b(j<WAj z_M>ry&8On;I=nvl?GAj#1G+jDM@{(uXC@xe@BiaO%xzQamXBxm&d29{H6I^7G9Pzr z&d1NS<l|d@n2%3cl#h4)Wj=oW5Bd1^_w(^d+YXAm?l~x~96l(XaKfOt*SUk@7bXsh zuld2Cc<=dx;%6#@;_<&56n}pGp!lIqaeVx)alEEq9A9%x9Pe;u9N%|Y93MJ8j+eE@ z@o_(k<KO-|j!#_^$G`tLj?dV!5Wlu>AwD@@h+p_-As#%g5HGp55brmq5dUydA@2Ok zLVWQb3h^uN72>0}X^P9arZ_sRDL&))rg-t$O>wuYn&NY25}w->cX_HQKIJz}@qK@3 zivRl0rudLA4359kXK?(pcyRoWQwGO}UNkr!cirH4?j3{U*B=@jcU?I+KKhNp@!0nV z$G2@WBz`J4B>wYPhQwPRKP2Ao>>=@xD~H6RZyFL`^P?g0Ek7R;|M-O=@z38H60iF2 zA@R#Q4vkmuJ2YN9aA^FukwfFZj~yDnJ85XV{<fj<UmqMAzgZg^|NhmX@w0y$8V^6N z!xr5;ZgNp4d}H^2<{sb^dC*0#)%aIpo^YVMX#7R`s<x%tI<`%vhEUIDZmw<7wi9tv a(H9=vd|D1aZp+R-?Z|)B8ol*XWB&({QJmWV literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle new file mode 100644 index 00000000..41872131 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle @@ -0,0 +1,53 @@ +# Solarized color palette taken from https://ethanschoonover.com/solarized/ +# Inspired by, and copied from ggthemes https://github.com/jrnold/ggthemes + +#TODO: +# 1. Padding to title from face +# 2. Remove top & right ticks +# 3. Give Title a Magenta Color(?) + +#base00 ='#657b83' +#base01 ='#93a1a1' +#base2 ='#eee8d5' +#base3 ='#fdf6e3' +#base01 ='#586e75' +#Magenta ='#d33682' +#Blue ='#268bd2' +#cyan ='#2aa198' +#violet ='#6c71c4' +#green ='#859900' +#orange ='#cb4b16' + +figure.facecolor : FDF6E3 + +patch.antialiased : True + +lines.linewidth : 2.0 +lines.solid_capstyle: butt + +axes.titlesize : 16 +axes.labelsize : 12 +axes.labelcolor : 657b83 +axes.facecolor : eee8d5 +axes.edgecolor : eee8d5 +axes.axisbelow : True +axes.prop_cycle : cycler('color', ['268BD2', '2AA198', '859900', 'B58900', 'CB4B16', 'DC322F', 'D33682', '6C71C4']) +# Blue +# Cyan +# Green +# Yellow +# Orange +# Red +# Magenta +# Violet +axes.grid : True +grid.color : fdf6e3 # grid color +grid.linestyle : - # line +grid.linewidth : 1 # in points + +### TICKS +xtick.color : 657b83 +xtick.direction : out + +ytick.color : 657b83 +ytick.direction : out diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle new file mode 100644 index 00000000..96f62f4b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle @@ -0,0 +1,6 @@ +# This patch should go on top of the "classic" style and exists solely to avoid +# changing baseline images. + +text.kerning_factor : 6 + +ytick.alignment: center_baseline diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle new file mode 100644 index 00000000..911658fe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle @@ -0,0 +1,19 @@ +# This style is used for the plot_types gallery. It is considered private. + +axes.grid: False +axes.axisbelow: True + +figure.figsize: 2, 2 +# make it so the axes labels don't show up. Obviously +# not good style for any quantitative analysis: +figure.subplot.left: 0.01 +figure.subplot.right: 0.99 +figure.subplot.bottom: 0.01 +figure.subplot.top: 0.99 + +xtick.major.size: 0.0 +ytick.major.size: 0.0 + +# colors: +image.cmap : Blues +axes.prop_cycle: cycler('color', ['1f77b4', '82bbdb', 'ccdff1']) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle new file mode 100644 index 00000000..75c95bf1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle @@ -0,0 +1,19 @@ +# This style is used for the plot_types gallery. It is considered part of the private API. + +axes.grid: True +axes.axisbelow: True + +figure.figsize: 2, 2 +# make it so the axes labels don't show up. Obviously +# not good style for any quantitative analysis: +figure.subplot.left: 0.01 +figure.subplot.right: 0.99 +figure.subplot.bottom: 0.01 +figure.subplot.top: 0.99 + +xtick.major.size: 0.0 +ytick.major.size: 0.0 + +# colors: +image.cmap : Blues +axes.prop_cycle: cycler('color', ['1f77b4', '58a1cf', 'abd0e6']) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/bmh.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/bmh.mplstyle new file mode 100644 index 00000000..1b449cc0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/bmh.mplstyle @@ -0,0 +1,29 @@ +#Author: Cameron Davidson-Pilon, original styles from Bayesian Methods for Hackers +# https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/ + +lines.linewidth : 2.0 + +patch.linewidth: 0.5 +patch.facecolor: blue +patch.edgecolor: eeeeee +patch.antialiased: True + +text.hinting_factor : 8 + +mathtext.fontset : cm + +axes.facecolor: eeeeee +axes.edgecolor: bcbcbc +axes.grid : True +axes.titlesize: x-large +axes.labelsize: large +axes.prop_cycle: cycler('color', ['348ABD', 'A60628', '7A68A6', '467821', 'D55E00', 'CC79A7', '56B4E9', '009E73', 'F0E442', '0072B2']) + +grid.color: b2b2b2 +grid.linestyle: -- +grid.linewidth: 0.5 + +legend.fancybox: True + +xtick.direction: in +ytick.direction: in diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/classic.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/classic.mplstyle new file mode 100644 index 00000000..e1768e5a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/classic.mplstyle @@ -0,0 +1,492 @@ +### Classic matplotlib plotting style as of v1.5 + + +### LINES +# See https://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more +# information on line properties. +lines.linewidth : 1.0 # line width in points +lines.linestyle : - # solid line +lines.color : b # has no affect on plot(); see axes.prop_cycle +lines.marker : None # the default marker +lines.markerfacecolor : auto # the default markerfacecolor +lines.markeredgecolor : auto # the default markeredgecolor +lines.markeredgewidth : 0.5 # the line width around the marker symbol +lines.markersize : 6 # markersize, in points +lines.dash_joinstyle : round # miter|round|bevel +lines.dash_capstyle : butt # butt|round|projecting +lines.solid_joinstyle : round # miter|round|bevel +lines.solid_capstyle : projecting # butt|round|projecting +lines.antialiased : True # render lines in antialiased (no jaggies) +lines.dashed_pattern : 6, 6 +lines.dashdot_pattern : 3, 5, 1, 5 +lines.dotted_pattern : 1, 3 +lines.scale_dashes: False + +### Marker props +markers.fillstyle: full + +### PATCHES +# Patches are graphical objects that fill 2D space, like polygons or +# circles. See +# https://matplotlib.org/api/artist_api.html#module-matplotlib.patches +# information on patch properties +patch.linewidth : 1.0 # edge width in points +patch.facecolor : b +patch.force_edgecolor : True +patch.edgecolor : k +patch.antialiased : True # render patches in antialiased (no jaggies) + +hatch.color : k +hatch.linewidth : 1.0 + +hist.bins : 10 + +### FONT +# +# font properties used by text.Text. See +# https://matplotlib.org/api/font_manager_api.html for more +# information on font properties. The 6 font properties used for font +# matching are given below with their default values. +# +# The font.family property has five values: 'serif' (e.g., Times), +# 'sans-serif' (e.g., Helvetica), 'cursive' (e.g., Zapf-Chancery), +# 'fantasy' (e.g., Western), and 'monospace' (e.g., Courier). Each of +# these font families has a default list of font names in decreasing +# order of priority associated with them. When text.usetex is False, +# font.family may also be one or more concrete font names. +# +# The font.style property has three values: normal (or roman), italic +# or oblique. The oblique style will be used for italic, if it is not +# present. +# +# The font.variant property has two values: normal or small-caps. For +# TrueType fonts, which are scalable fonts, small-caps is equivalent +# to using a font size of 'smaller', or about 83% of the current font +# size. +# +# The font.weight property has effectively 13 values: normal, bold, +# bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as +# 400, and bold is 700. bolder and lighter are relative values with +# respect to the current weight. +# +# The font.stretch property has 11 values: ultra-condensed, +# extra-condensed, condensed, semi-condensed, normal, semi-expanded, +# expanded, extra-expanded, ultra-expanded, wider, and narrower. This +# property is not currently implemented. +# +# The font.size property is the default font size for text, given in pts. +# 12pt is the standard value. +# +font.family : sans-serif +font.style : normal +font.variant : normal +font.weight : normal +font.stretch : normal +# note that font.size controls default text sizes. To configure +# special text sizes tick labels, axes, labels, title, etc, see the rc +# settings for axes and ticks. Special text sizes can be defined +# relative to font.size, using the following values: xx-small, x-small, +# small, medium, large, x-large, xx-large, larger, or smaller +font.size : 12.0 +font.serif : DejaVu Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif +font.sans-serif: DejaVu Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif +font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive +font.fantasy : Comic Sans MS, Chicago, Charcoal, ImpactWestern, xkcd script, fantasy +font.monospace : DejaVu Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace + +### TEXT +# text properties used by text.Text. See +# https://matplotlib.org/api/artist_api.html#module-matplotlib.text for more +# information on text properties + +text.color : k + +### LaTeX customizations. See http://www.scipy.org/Wiki/Cookbook/Matplotlib/UsingTex +text.usetex : False # use latex for all text handling. The following fonts + # are supported through the usual rc parameter settings: + # new century schoolbook, bookman, times, palatino, + # zapf chancery, charter, serif, sans-serif, helvetica, + # avant garde, courier, monospace, computer modern roman, + # computer modern sans serif, computer modern typewriter + # If another font is desired which can loaded using the + # LaTeX \usepackage command, please inquire at the + # matplotlib mailing list +text.latex.preamble : # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES + # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP + # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO. + # text.latex.preamble is a single line of LaTeX code that + # will be passed on to the LaTeX system. It may contain + # any code that is valid for the LaTeX "preamble", i.e. + # between the "\documentclass" and "\begin{document}" + # statements. + # Note that it has to be put on a single line, which may + # become quite long. + # The following packages are always loaded with usetex, so + # beware of package collisions: color, geometry, graphicx, + # type1cm, textcomp. + # Adobe Postscript (PSSNFS) font packages may also be + # loaded, depending on your font settings. + +text.hinting : auto # May be one of the following: + # 'none': Perform no hinting + # 'auto': Use freetype's autohinter + # 'native': Use the hinting information in the + # font file, if available, and if your + # freetype library supports it + # 'either': Use the native hinting information, + # or the autohinter if none is available. + # For backward compatibility, this value may also be + # True === 'auto' or False === 'none'. +text.hinting_factor : 8 # Specifies the amount of softness for hinting in the + # horizontal direction. A value of 1 will hint to full + # pixels. A value of 2 will hint to half pixels etc. + +text.antialiased : True # If True (default), the text will be antialiased. + # This only affects the Agg backend. + +# The following settings allow you to select the fonts in math mode. +# They map from a TeX font name to a fontconfig font pattern. +# These settings are only used if mathtext.fontset is 'custom'. +# Note that this "custom" mode is unsupported and may go away in the +# future. +mathtext.cal : cursive +mathtext.rm : serif +mathtext.tt : monospace +mathtext.it : serif:italic +mathtext.bf : serif:bold +mathtext.sf : sans\-serif +mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix', + # 'stixsans' or 'custom' +mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix' + # 'stixsans'] when a symbol cannot be found in one of the + # custom math fonts. Select 'None' to not perform fallback + # and replace the missing character by a dummy. + +mathtext.default : it # The default font to use for math. + # Can be any of the LaTeX font names, including + # the special name "regular" for the same font + # used in regular text. + +### AXES +# default face and edge color, default tick sizes, +# default fontsizes for ticklabels, and so on. See +# https://matplotlib.org/api/axes_api.html#module-matplotlib.axes +axes.facecolor : w # axes background color +axes.edgecolor : k # axes edge color +axes.linewidth : 1.0 # edge linewidth +axes.grid : False # display grid or not +axes.grid.which : major +axes.grid.axis : both +axes.titlesize : large # fontsize of the axes title +axes.titley : 1.0 # at the top, no autopositioning. +axes.titlepad : 5.0 # pad between axes and title in points +axes.titleweight : normal # font weight for axes title +axes.labelsize : medium # fontsize of the x any y labels +axes.labelpad : 5.0 # space between label and axis +axes.labelweight : normal # weight of the x and y labels +axes.labelcolor : k +axes.axisbelow : False # whether axis gridlines and ticks are below + # the axes elements (lines, text, etc) + +axes.formatter.limits : -7, 7 # use scientific notation if log10 + # of the axis range is smaller than the + # first or larger than the second +axes.formatter.use_locale : False # When True, format tick labels + # according to the user's locale. + # For example, use ',' as a decimal + # separator in the fr_FR locale. +axes.formatter.use_mathtext : False # When True, use mathtext for scientific + # notation. +axes.formatter.useoffset : True # If True, the tick label formatter + # will default to labeling ticks relative + # to an offset when the data range is very + # small compared to the minimum absolute + # value of the data. +axes.formatter.offset_threshold : 2 # When useoffset is True, the offset + # will be used when it can remove + # at least this number of significant + # digits from tick labels. + +axes.unicode_minus : True # use Unicode for the minus symbol + # rather than hyphen. See + # https://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes +axes.prop_cycle : cycler('color', 'bgrcmyk') + # color cycle for plot lines + # as list of string colorspecs: + # single letter, long name, or + # web-style hex +axes.autolimit_mode : round_numbers +axes.xmargin : 0 # x margin. See `axes.Axes.margins` +axes.ymargin : 0 # y margin See `axes.Axes.margins` +axes.spines.bottom : True +axes.spines.left : True +axes.spines.right : True +axes.spines.top : True +polaraxes.grid : True # display grid on polar axes +axes3d.grid : True # display grid on 3d axes + +date.autoformatter.year : %Y +date.autoformatter.month : %b %Y +date.autoformatter.day : %b %d %Y +date.autoformatter.hour : %H:%M:%S +date.autoformatter.minute : %H:%M:%S.%f +date.autoformatter.second : %H:%M:%S.%f +date.autoformatter.microsecond : %H:%M:%S.%f +date.converter: auto # 'auto', 'concise' + +### TICKS +# see https://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick + +xtick.top : True # draw ticks on the top side +xtick.bottom : True # draw ticks on the bottom side +xtick.major.size : 4 # major tick size in points +xtick.minor.size : 2 # minor tick size in points +xtick.minor.visible : False +xtick.major.width : 0.5 # major tick width in points +xtick.minor.width : 0.5 # minor tick width in points +xtick.major.pad : 4 # distance to major tick label in points +xtick.minor.pad : 4 # distance to the minor tick label in points +xtick.color : k # color of the tick labels +xtick.labelsize : medium # fontsize of the tick labels +xtick.direction : in # direction: in, out, or inout +xtick.major.top : True # draw x axis top major ticks +xtick.major.bottom : True # draw x axis bottom major ticks +xtick.minor.top : True # draw x axis top minor ticks +xtick.minor.bottom : True # draw x axis bottom minor ticks +xtick.alignment : center + +ytick.left : True # draw ticks on the left side +ytick.right : True # draw ticks on the right side +ytick.major.size : 4 # major tick size in points +ytick.minor.size : 2 # minor tick size in points +ytick.minor.visible : False +ytick.major.width : 0.5 # major tick width in points +ytick.minor.width : 0.5 # minor tick width in points +ytick.major.pad : 4 # distance to major tick label in points +ytick.minor.pad : 4 # distance to the minor tick label in points +ytick.color : k # color of the tick labels +ytick.labelsize : medium # fontsize of the tick labels +ytick.direction : in # direction: in, out, or inout +ytick.major.left : True # draw y axis left major ticks +ytick.major.right : True # draw y axis right major ticks +ytick.minor.left : True # draw y axis left minor ticks +ytick.minor.right : True # draw y axis right minor ticks +ytick.alignment : center + +### GRIDS +grid.color : k # grid color +grid.linestyle : : # dotted +grid.linewidth : 0.5 # in points +grid.alpha : 1.0 # transparency, between 0.0 and 1.0 + +### Legend +legend.fancybox : False # if True, use a rounded box for the + # legend, else a rectangle +legend.loc : upper right +legend.numpoints : 2 # the number of points in the legend line +legend.fontsize : large +legend.borderpad : 0.4 # border whitespace in fontsize units +legend.markerscale : 1.0 # the relative size of legend markers vs. original +# the following dimensions are in axes coords +legend.labelspacing : 0.5 # the vertical space between the legend entries in fraction of fontsize +legend.handlelength : 2. # the length of the legend lines in fraction of fontsize +legend.handleheight : 0.7 # the height of the legend handle in fraction of fontsize +legend.handletextpad : 0.8 # the space between the legend line and legend text in fraction of fontsize +legend.borderaxespad : 0.5 # the border between the axes and legend edge in fraction of fontsize +legend.columnspacing : 2. # the border between the axes and legend edge in fraction of fontsize +legend.shadow : False +legend.frameon : True # whether or not to draw a frame around legend +legend.framealpha : None # opacity of legend frame +legend.scatterpoints : 3 # number of scatter points +legend.facecolor : inherit # legend background color (when 'inherit' uses axes.facecolor) +legend.edgecolor : inherit # legend edge color (when 'inherit' uses axes.edgecolor) + + + +### FIGURE +# See https://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure +figure.titlesize : medium # size of the figure title +figure.titleweight : normal # weight of the figure title +figure.labelsize: medium # size of the figure label +figure.labelweight: normal # weight of the figure label +figure.figsize : 8, 6 # figure size in inches +figure.dpi : 80 # figure dots per inch +figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray +figure.edgecolor : w # figure edgecolor +figure.autolayout : False # When True, automatically adjust subplot + # parameters to make the plot fit the figure +figure.frameon : True + +# The figure subplot parameters. All dimensions are a fraction of the +# figure width or height +figure.subplot.left : 0.125 # the left side of the subplots of the figure +figure.subplot.right : 0.9 # the right side of the subplots of the figure +figure.subplot.bottom : 0.1 # the bottom of the subplots of the figure +figure.subplot.top : 0.9 # the top of the subplots of the figure +figure.subplot.wspace : 0.2 # the amount of width reserved for space between subplots, + # expressed as a fraction of the average axis width +figure.subplot.hspace : 0.2 # the amount of height reserved for space between subplots, + # expressed as a fraction of the average axis height + +### IMAGES +image.aspect : equal # equal | auto | a number +image.interpolation : bilinear # see help(imshow) for options +image.cmap : jet # gray | jet | ... +image.lut : 256 # the size of the colormap lookup table +image.origin : upper # lower | upper +image.resample : False +image.composite_image : True + +### CONTOUR PLOTS +contour.negative_linestyle : dashed # dashed | solid +contour.corner_mask : True + +# errorbar props +errorbar.capsize: 3 + +# scatter props +scatter.marker: o + +### Boxplots +boxplot.bootstrap: None +boxplot.boxprops.color: b +boxplot.boxprops.linestyle: - +boxplot.boxprops.linewidth: 1.0 +boxplot.capprops.color: k +boxplot.capprops.linestyle: - +boxplot.capprops.linewidth: 1.0 +boxplot.flierprops.color: b +boxplot.flierprops.linestyle: none +boxplot.flierprops.linewidth: 1.0 +boxplot.flierprops.marker: + +boxplot.flierprops.markeredgecolor: k +boxplot.flierprops.markerfacecolor: auto +boxplot.flierprops.markersize: 6.0 +boxplot.meanline: False +boxplot.meanprops.color: r +boxplot.meanprops.linestyle: - +boxplot.meanprops.linewidth: 1.0 +boxplot.medianprops.color: r +boxplot.meanprops.marker: s +boxplot.meanprops.markerfacecolor: r +boxplot.meanprops.markeredgecolor: k +boxplot.meanprops.markersize: 6.0 +boxplot.medianprops.linestyle: - +boxplot.medianprops.linewidth: 1.0 +boxplot.notch: False +boxplot.patchartist: False +boxplot.showbox: True +boxplot.showcaps: True +boxplot.showfliers: True +boxplot.showmeans: False +boxplot.vertical: True +boxplot.whiskerprops.color: b +boxplot.whiskerprops.linestyle: -- +boxplot.whiskerprops.linewidth: 1.0 +boxplot.whiskers: 1.5 + +### Agg rendering +### Warning: experimental, 2008/10/10 +agg.path.chunksize : 0 # 0 to disable; values in the range + # 10000 to 100000 can improve speed slightly + # and prevent an Agg rendering failure + # when plotting very large data sets, + # especially if they are very gappy. + # It may cause minor artifacts, though. + # A value of 20000 is probably a good + # starting point. +### SAVING FIGURES +path.simplify : True # When True, simplify paths by removing "invisible" + # points to reduce file size and increase rendering + # speed +path.simplify_threshold : 0.1111111111111111 + # The threshold of similarity below which + # vertices will be removed in the simplification + # process +path.snap : True # When True, rectilinear axis-aligned paths will be snapped to + # the nearest pixel when certain criteria are met. When False, + # paths will never be snapped. +path.sketch : None # May be none, or a 3-tuple of the form (scale, length, + # randomness). + # *scale* is the amplitude of the wiggle + # perpendicular to the line (in pixels). *length* + # is the length of the wiggle along the line (in + # pixels). *randomness* is the factor by which + # the length is randomly scaled. + +# the default savefig params can be different from the display params +# e.g., you may want a higher resolution, or to make the figure +# background white +savefig.dpi : 100 # figure dots per inch +savefig.facecolor : w # figure facecolor when saving +savefig.edgecolor : w # figure edgecolor when saving +savefig.format : png # png, ps, pdf, svg +savefig.bbox : standard # 'tight' or 'standard'. + # 'tight' is incompatible with pipe-based animation + # backends (e.g. 'ffmpeg') but will work with those + # based on temporary files (e.g. 'ffmpeg_file') +savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight' +savefig.transparent : False # setting that controls whether figures are saved with a + # transparent background by default +savefig.orientation : portrait + +# ps backend params +ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10 +ps.useafm : False # use of afm fonts, results in small files +ps.usedistiller : False # can be: None, ghostscript or xpdf + # Experimental: may produce smaller files. + # xpdf intended for production of publication quality files, + # but requires ghostscript, xpdf and ps2eps +ps.distiller.res : 6000 # dpi +ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) + +# pdf backend params +pdf.compression : 6 # integer from 0 to 9 + # 0 disables compression (good for debugging) +pdf.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) +pdf.inheritcolor : False +pdf.use14corefonts : False + +# pgf backend params +pgf.texsystem : xelatex +pgf.rcfonts : True +pgf.preamble : + +# svg backend params +svg.image_inline : True # write raster image data directly into the svg file +svg.fonttype : path # How to handle SVG fonts: +# 'none': Assume fonts are installed on the machine where the SVG will be viewed. +# 'path': Embed characters as paths -- supported by most SVG renderers + +# Event keys to interact with figures/plots via keyboard. +# Customize these settings according to your needs. +# Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '') + +keymap.fullscreen : f, ctrl+f # toggling +keymap.home : h, r, home # home or reset mnemonic +keymap.back : left, c, backspace # forward / backward keys to enable +keymap.forward : right, v # left handed quick navigation +keymap.pan : p # pan mnemonic +keymap.zoom : o # zoom mnemonic +keymap.save : s, ctrl+s # saving current figure +keymap.quit : ctrl+w, cmd+w # close the current figure +keymap.grid : g # switching on/off a grid in current axes +keymap.yscale : l # toggle scaling of y-axes ('log'/'linear') +keymap.xscale : k, L # toggle scaling of x-axes ('log'/'linear') + +###ANIMATION settings +animation.writer : ffmpeg # MovieWriter 'backend' to use +animation.codec : mpeg4 # Codec to use for writing movie +animation.bitrate: -1 # Controls size/quality tradeoff for movie. + # -1 implies let utility auto-determine +animation.frame_format: png # Controls frame format used by temp files +animation.ffmpeg_path: ffmpeg # Path to ffmpeg binary. Without full path + # $PATH is searched +animation.ffmpeg_args: # Additional arguments to pass to ffmpeg +animation.convert_path: convert # Path to ImageMagick's convert binary. + # On Windows use the full path since convert + # is also the name of a system tool. +animation.convert_args: +animation.html: none + +_internal.classic_mode: True diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/dark_background.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/dark_background.mplstyle new file mode 100644 index 00000000..c4b7741a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/dark_background.mplstyle @@ -0,0 +1,29 @@ +# Set black background default line colors to white. + +lines.color: white +patch.edgecolor: white + +text.color: white + +axes.facecolor: black +axes.edgecolor: white +axes.labelcolor: white +axes.prop_cycle: cycler('color', ['8dd3c7', 'feffb3', 'bfbbd9', 'fa8174', '81b1d2', 'fdb462', 'b3de69', 'bc82bd', 'ccebc4', 'ffed6f']) + +xtick.color: white +ytick.color: white + +grid.color: white + +figure.facecolor: black +figure.edgecolor: black + +savefig.facecolor: black +savefig.edgecolor: black + +### Boxplots +boxplot.boxprops.color: white +boxplot.capprops.color: white +boxplot.flierprops.color: white +boxplot.flierprops.markeredgecolor: white +boxplot.whiskerprops.color: white diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fast.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fast.mplstyle new file mode 100644 index 00000000..1f7be7d4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fast.mplstyle @@ -0,0 +1,11 @@ +# a small set of changes that will make your plotting FAST (1). +# +# (1) in some cases + +# Maximally simplify lines. +path.simplify: True +path.simplify_threshold: 1.0 + +# chunk up large lines into smaller lines! +# simple trick to avoid those pesky O(>n) algorithms! +agg.path.chunksize: 10000 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle new file mode 100644 index 00000000..738db39f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle @@ -0,0 +1,40 @@ +#Author: Cameron Davidson-Pilon, replicated styles from FiveThirtyEight.com +# See https://www.dataorigami.net/blogs/fivethirtyeight-mpl + +lines.linewidth: 4 +lines.solid_capstyle: butt + +legend.fancybox: true + +axes.prop_cycle: cycler('color', ['008fd5', 'fc4f30', 'e5ae38', '6d904f', '8b8b8b', '810f7c']) +axes.facecolor: f0f0f0 +axes.labelsize: large +axes.axisbelow: true +axes.grid: true +axes.edgecolor: f0f0f0 +axes.linewidth: 3.0 +axes.titlesize: x-large + +patch.edgecolor: f0f0f0 +patch.linewidth: 0.5 + +svg.fonttype: path + +grid.linestyle: - +grid.linewidth: 1.0 +grid.color: cbcbcb + +xtick.major.size: 0 +xtick.minor.size: 0 +ytick.major.size: 0 +ytick.minor.size: 0 + +font.size:14.0 + +savefig.edgecolor: f0f0f0 +savefig.facecolor: f0f0f0 + +figure.subplot.left: 0.08 +figure.subplot.right: 0.95 +figure.subplot.bottom: 0.07 +figure.facecolor: f0f0f0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/ggplot.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/ggplot.mplstyle new file mode 100644 index 00000000..d1b3ba2e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/ggplot.mplstyle @@ -0,0 +1,39 @@ +# from https://everyhue.me/posts/sane-color-scheme-for-matplotlib/ + +patch.linewidth: 0.5 +patch.facecolor: 348ABD # blue +patch.edgecolor: EEEEEE +patch.antialiased: True + +font.size: 10.0 + +axes.facecolor: E5E5E5 +axes.edgecolor: white +axes.linewidth: 1 +axes.grid: True +axes.titlesize: x-large +axes.labelsize: large +axes.labelcolor: 555555 +axes.axisbelow: True # grid/ticks are below elements (e.g., lines, text) + +axes.prop_cycle: cycler('color', ['E24A33', '348ABD', '988ED5', '777777', 'FBC15E', '8EBA42', 'FFB5B8']) + # E24A33 : red + # 348ABD : blue + # 988ED5 : purple + # 777777 : gray + # FBC15E : yellow + # 8EBA42 : green + # FFB5B8 : pink + +xtick.color: 555555 +xtick.direction: out + +ytick.color: 555555 +ytick.direction: out + +grid.color: white +grid.linestyle: - # solid line + +figure.facecolor: white +figure.edgecolor: 0.50 + diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/grayscale.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/grayscale.mplstyle new file mode 100644 index 00000000..6a1114e4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/grayscale.mplstyle @@ -0,0 +1,29 @@ +# Set all colors to grayscale +# Note: strings of float values are interpreted by matplotlib as gray values. + + +lines.color: black +patch.facecolor: gray +patch.edgecolor: black + +text.color: black + +axes.facecolor: white +axes.edgecolor: black +axes.labelcolor: black +# black to light gray +axes.prop_cycle: cycler('color', ['0.00', '0.40', '0.60', '0.70']) + +xtick.color: black +ytick.color: black + +grid.color: black + +figure.facecolor: 0.75 +figure.edgecolor: white + +image.cmap: gray + +savefig.facecolor: white +savefig.edgecolor: white + diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle new file mode 100644 index 00000000..5e9e9493 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle @@ -0,0 +1,3 @@ +# Seaborn bright palette +axes.prop_cycle: cycler('color', ['003FFF', '03ED3A', 'E8000B', '8A2BE2', 'FFC400', '00D7FF']) +patch.facecolor: 003FFF diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle new file mode 100644 index 00000000..e13b7aad --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle @@ -0,0 +1,3 @@ +# Seaborn colorblind palette +axes.prop_cycle: cycler('color', ['0072B2', '009E73', 'D55E00', 'CC79A7', 'F0E442', '56B4E9']) +patch.facecolor: 0072B2 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle new file mode 100644 index 00000000..30160ae2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle @@ -0,0 +1,3 @@ +# Seaborn dark palette +axes.prop_cycle: cycler('color', ['001C7F', '017517', '8C0900', '7600A1', 'B8860B', '006374']) +patch.facecolor: 001C7F diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle new file mode 100644 index 00000000..55b50b5b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle @@ -0,0 +1,30 @@ +# Seaborn common parameters +# .15 = dark_gray +# .8 = light_gray +figure.facecolor: white +text.color: .15 +axes.labelcolor: .15 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 +xtick.direction: out +ytick.direction: out +xtick.color: .15 +ytick.color: .15 +axes.axisbelow: True +image.cmap: Greys +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif +grid.linestyle: - +lines.solid_capstyle: round + +# Seaborn dark parameters +axes.grid: False +axes.facecolor: EAEAF2 +axes.edgecolor: white +axes.linewidth: 0 +grid.color: white +xtick.major.size: 0 +ytick.major.size: 0 +xtick.minor.size: 0 +ytick.minor.size: 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle new file mode 100644 index 00000000..0f5d955d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle @@ -0,0 +1,30 @@ +# Seaborn common parameters +# .15 = dark_gray +# .8 = light_gray +figure.facecolor: white +text.color: .15 +axes.labelcolor: .15 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 +xtick.direction: out +ytick.direction: out +xtick.color: .15 +ytick.color: .15 +axes.axisbelow: True +image.cmap: Greys +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif +grid.linestyle: - +lines.solid_capstyle: round + +# Seaborn darkgrid parameters +axes.grid: True +axes.facecolor: EAEAF2 +axes.edgecolor: white +axes.linewidth: 0 +grid.color: white +xtick.major.size: 0 +ytick.major.size: 0 +xtick.minor.size: 0 +ytick.minor.size: 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle new file mode 100644 index 00000000..5d6b7c56 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle @@ -0,0 +1,3 @@ +# Seaborn deep palette +axes.prop_cycle: cycler('color', ['4C72B0', '55A868', 'C44E52', '8172B2', 'CCB974', '64B5CD']) +patch.facecolor: 4C72B0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle new file mode 100644 index 00000000..4a71646c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle @@ -0,0 +1,3 @@ +# Seaborn muted palette +axes.prop_cycle: cycler('color', ['4878CF', '6ACC65', 'D65F5F', 'B47CC7', 'C4AD66', '77BEDB']) +patch.facecolor: 4878CF diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle new file mode 100644 index 00000000..18bcf3e1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle @@ -0,0 +1,21 @@ +# Seaborn notebook context +figure.figsize: 8.0, 5.5 +axes.labelsize: 11 +axes.titlesize: 12 +xtick.labelsize: 10 +ytick.labelsize: 10 +legend.fontsize: 10 + +grid.linewidth: 1 +lines.linewidth: 1.75 +patch.linewidth: .3 +lines.markersize: 7 +lines.markeredgewidth: 0 + +xtick.major.width: 1 +ytick.major.width: 1 +xtick.minor.width: .5 +ytick.minor.width: .5 + +xtick.major.pad: 7 +ytick.major.pad: 7 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle new file mode 100644 index 00000000..3326be43 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle @@ -0,0 +1,21 @@ +# Seaborn paper context +figure.figsize: 6.4, 4.4 +axes.labelsize: 8.8 +axes.titlesize: 9.6 +xtick.labelsize: 8 +ytick.labelsize: 8 +legend.fontsize: 8 + +grid.linewidth: 0.8 +lines.linewidth: 1.4 +patch.linewidth: 0.24 +lines.markersize: 5.6 +lines.markeredgewidth: 0 + +xtick.major.width: 0.8 +ytick.major.width: 0.8 +xtick.minor.width: 0.4 +ytick.minor.width: 0.4 + +xtick.major.pad: 5.6 +ytick.major.pad: 5.6 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle new file mode 100644 index 00000000..dff67482 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle @@ -0,0 +1,3 @@ +# Seaborn pastel palette +axes.prop_cycle: cycler('color', ['92C6FF', '97F0AA', 'FF9F9A', 'D0BBFF', 'FFFEA3', 'B0E0E6']) +patch.facecolor: 92C6FF diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle new file mode 100644 index 00000000..47f23700 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle @@ -0,0 +1,21 @@ +# Seaborn poster context +figure.figsize: 12.8, 8.8 +axes.labelsize: 17.6 +axes.titlesize: 19.2 +xtick.labelsize: 16 +ytick.labelsize: 16 +legend.fontsize: 16 + +grid.linewidth: 1.6 +lines.linewidth: 2.8 +patch.linewidth: 0.48 +lines.markersize: 11.2 +lines.markeredgewidth: 0 + +xtick.major.width: 1.6 +ytick.major.width: 1.6 +xtick.minor.width: 0.8 +ytick.minor.width: 0.8 + +xtick.major.pad: 11.2 +ytick.major.pad: 11.2 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle new file mode 100644 index 00000000..29a77c53 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle @@ -0,0 +1,21 @@ +# Seaborn talk context +figure.figsize: 10.4, 7.15 +axes.labelsize: 14.3 +axes.titlesize: 15.6 +xtick.labelsize: 13 +ytick.labelsize: 13 +legend.fontsize: 13 + +grid.linewidth: 1.3 +lines.linewidth: 2.275 +patch.linewidth: 0.39 +lines.markersize: 9.1 +lines.markeredgewidth: 0 + +xtick.major.width: 1.3 +ytick.major.width: 1.3 +xtick.minor.width: 0.65 +ytick.minor.width: 0.65 + +xtick.major.pad: 9.1 +ytick.major.pad: 9.1 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle new file mode 100644 index 00000000..c2a1cab9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle @@ -0,0 +1,30 @@ +# Seaborn common parameters +# .15 = dark_gray +# .8 = light_gray +figure.facecolor: white +text.color: .15 +axes.labelcolor: .15 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 +xtick.direction: out +ytick.direction: out +xtick.color: .15 +ytick.color: .15 +axes.axisbelow: True +image.cmap: Greys +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif +grid.linestyle: - +lines.solid_capstyle: round + +# Seaborn white parameters +axes.grid: False +axes.facecolor: white +axes.edgecolor: .15 +axes.linewidth: 1.25 +grid.color: .8 +xtick.major.size: 6 +ytick.major.size: 6 +xtick.minor.size: 3 +ytick.minor.size: 3 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle new file mode 100644 index 00000000..dcbe3acf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle @@ -0,0 +1,30 @@ +# Seaborn common parameters +# .15 = dark_gray +# .8 = light_gray +figure.facecolor: white +text.color: .15 +axes.labelcolor: .15 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 +xtick.direction: out +ytick.direction: out +xtick.color: .15 +ytick.color: .15 +axes.axisbelow: True +image.cmap: Greys +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif +grid.linestyle: - +lines.solid_capstyle: round + +# Seaborn white parameters +axes.grid: False +axes.facecolor: white +axes.edgecolor: .15 +axes.linewidth: 1.25 +grid.color: .8 +xtick.major.size: 0 +ytick.major.size: 0 +xtick.minor.size: 0 +ytick.minor.size: 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle new file mode 100644 index 00000000..612e2181 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle @@ -0,0 +1,30 @@ +# Seaborn common parameters +# .15 = dark_gray +# .8 = light_gray +figure.facecolor: white +text.color: .15 +axes.labelcolor: .15 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 +xtick.direction: out +ytick.direction: out +xtick.color: .15 +ytick.color: .15 +axes.axisbelow: True +image.cmap: Greys +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif +grid.linestyle: - +lines.solid_capstyle: round + +# Seaborn whitegrid parameters +axes.grid: True +axes.facecolor: white +axes.edgecolor: .8 +axes.linewidth: 1 +grid.color: .8 +xtick.major.size: 0 +ytick.major.size: 0 +xtick.minor.size: 0 +ytick.minor.size: 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle new file mode 100644 index 00000000..94b1bc83 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle @@ -0,0 +1,57 @@ +# default seaborn aesthetic +# darkgrid + deep palette + notebook context + +axes.axisbelow: True +axes.edgecolor: white +axes.facecolor: EAEAF2 +axes.grid: True +axes.labelcolor: .15 +axes.labelsize: 11 +axes.linewidth: 0 +axes.prop_cycle: cycler('color', ['4C72B0', '55A868', 'C44E52', '8172B2', 'CCB974', '64B5CD']) +axes.titlesize: 12 + +figure.facecolor: white +figure.figsize: 8.0, 5.5 + +font.family: sans-serif +font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif + +grid.color: white +grid.linestyle: - +grid.linewidth: 1 + +image.cmap: Greys + +legend.fontsize: 10 +legend.frameon: False +legend.numpoints: 1 +legend.scatterpoints: 1 + +lines.linewidth: 1.75 +lines.markeredgewidth: 0 +lines.markersize: 7 +lines.solid_capstyle: round + +patch.facecolor: 4C72B0 +patch.linewidth: .3 + +text.color: .15 + +xtick.color: .15 +xtick.direction: out +xtick.labelsize: 10 +xtick.major.pad: 7 +xtick.major.size: 0 +xtick.major.width: 1 +xtick.minor.size: 0 +xtick.minor.width: .5 + +ytick.color: .15 +ytick.direction: out +ytick.labelsize: 10 +ytick.major.pad: 7 +ytick.major.size: 0 +ytick.major.width: 1 +ytick.minor.size: 0 +ytick.minor.width: .5 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle new file mode 100644 index 00000000..2d8cb020 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle @@ -0,0 +1,3 @@ +# Tableau colorblind 10 palette +axes.prop_cycle: cycler('color', ['006BA4', 'FF800E', 'ABABAB', '595959', '5F9ED1', 'C85200', '898989', 'A2C8EC', 'FFBC79', 'CFCFCF']) +patch.facecolor: 006BA4 \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.py new file mode 100644 index 00000000..bb117c38 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.py @@ -0,0 +1,1604 @@ +r""" +Container classes for `.Artist`\s. + +`OffsetBox` + The base of all container artists defined in this module. + +`AnchoredOffsetbox`, `AnchoredText` + Anchor and align an arbitrary `.Artist` or a text relative to the parent + axes or a specific anchor point. + +`DrawingArea` + A container with fixed width and height. Children have a fixed position + inside the container and may be clipped. + +`HPacker`, `VPacker` + Containers for layouting their children vertically or horizontally. + +`PaddedBox` + A container to add a padding around an `.Artist`. + +`TextArea` + Contains a single `.Text` instance. +""" + +import functools + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, _docstring +import matplotlib.artist as martist +import matplotlib.path as mpath +import matplotlib.text as mtext +import matplotlib.transforms as mtransforms +from matplotlib.font_manager import FontProperties +from matplotlib.image import BboxImage +from matplotlib.patches import ( + FancyBboxPatch, FancyArrowPatch, bbox_artist as mbbox_artist) +from matplotlib.transforms import Bbox, BboxBase, TransformedBbox + + +DEBUG = False + + +def _compat_get_offset(meth): + """ + Decorator for the get_offset method of OffsetBox and subclasses, that + allows supporting both the new signature (self, bbox, renderer) and the old + signature (self, width, height, xdescent, ydescent, renderer). + """ + sigs = [lambda self, width, height, xdescent, ydescent, renderer: locals(), + lambda self, bbox, renderer: locals()] + + @functools.wraps(meth) + def get_offset(self, *args, **kwargs): + params = _api.select_matching_signature(sigs, self, *args, **kwargs) + bbox = (params["bbox"] if "bbox" in params else + Bbox.from_bounds(-params["xdescent"], -params["ydescent"], + params["width"], params["height"])) + return meth(params["self"], bbox, params["renderer"]) + return get_offset + + +@_api.deprecated("3.7", alternative='patches.bbox_artist') +def bbox_artist(*args, **kwargs): + if DEBUG: + mbbox_artist(*args, **kwargs) + + +# for debugging use +def _bbox_artist(*args, **kwargs): + if DEBUG: + mbbox_artist(*args, **kwargs) + + +def _get_packed_offsets(widths, total, sep, mode="fixed"): + r""" + Pack boxes specified by their *widths*. + + For simplicity of the description, the terminology used here assumes a + horizontal layout, but the function works equally for a vertical layout. + + There are three packing *mode*\s: + + - 'fixed': The elements are packed tight to the left with a spacing of + *sep* in between. If *total* is *None* the returned total will be the + right edge of the last box. A non-*None* total will be passed unchecked + to the output. In particular this means that right edge of the last + box may be further to the right than the returned total. + + - 'expand': Distribute the boxes with equal spacing so that the left edge + of the first box is at 0, and the right edge of the last box is at + *total*. The parameter *sep* is ignored in this mode. A total of *None* + is accepted and considered equal to 1. The total is returned unchanged + (except for the conversion *None* to 1). If the total is smaller than + the sum of the widths, the laid out boxes will overlap. + + - 'equal': If *total* is given, the total space is divided in N equal + ranges and each box is left-aligned within its subspace. + Otherwise (*total* is *None*), *sep* must be provided and each box is + left-aligned in its subspace of width ``(max(widths) + sep)``. The + total width is then calculated to be ``N * (max(widths) + sep)``. + + Parameters + ---------- + widths : list of float + Widths of boxes to be packed. + total : float or None + Intended total length. *None* if not used. + sep : float or None + Spacing between boxes. + mode : {'fixed', 'expand', 'equal'} + The packing mode. + + Returns + ------- + total : float + The total width needed to accommodate the laid out boxes. + offsets : array of float + The left offsets of the boxes. + """ + _api.check_in_list(["fixed", "expand", "equal"], mode=mode) + + if mode == "fixed": + offsets_ = np.cumsum([0] + [w + sep for w in widths]) + offsets = offsets_[:-1] + if total is None: + total = offsets_[-1] - sep + return total, offsets + + elif mode == "expand": + # This is a bit of a hack to avoid a TypeError when *total* + # is None and used in conjugation with tight layout. + if total is None: + total = 1 + if len(widths) > 1: + sep = (total - sum(widths)) / (len(widths) - 1) + else: + sep = 0 + offsets_ = np.cumsum([0] + [w + sep for w in widths]) + offsets = offsets_[:-1] + return total, offsets + + elif mode == "equal": + maxh = max(widths) + if total is None: + if sep is None: + raise ValueError("total and sep cannot both be None when " + "using layout mode 'equal'") + total = (maxh + sep) * len(widths) + else: + sep = total / len(widths) - maxh + offsets = (maxh + sep) * np.arange(len(widths)) + return total, offsets + + +def _get_aligned_offsets(yspans, height, align="baseline"): + """ + Align boxes each specified by their ``(y0, y1)`` spans. + + For simplicity of the description, the terminology used here assumes a + horizontal layout (i.e., vertical alignment), but the function works + equally for a vertical layout. + + Parameters + ---------- + yspans + List of (y0, y1) spans of boxes to be aligned. + height : float or None + Intended total height. If None, the maximum of the heights + (``y1 - y0``) in *yspans* is used. + align : {'baseline', 'left', 'top', 'right', 'bottom', 'center'} + The alignment anchor of the boxes. + + Returns + ------- + (y0, y1) + y range spanned by the packing. If a *height* was originally passed + in, then for all alignments other than "baseline", a span of ``(0, + height)`` is used without checking that it is actually large enough). + descent + The descent of the packing. + offsets + The bottom offsets of the boxes. + """ + + _api.check_in_list( + ["baseline", "left", "top", "right", "bottom", "center"], align=align) + if height is None: + height = max(y1 - y0 for y0, y1 in yspans) + + if align == "baseline": + yspan = (min(y0 for y0, y1 in yspans), max(y1 for y0, y1 in yspans)) + offsets = [0] * len(yspans) + elif align in ["left", "bottom"]: + yspan = (0, height) + offsets = [-y0 for y0, y1 in yspans] + elif align in ["right", "top"]: + yspan = (0, height) + offsets = [height - y1 for y0, y1 in yspans] + elif align == "center": + yspan = (0, height) + offsets = [(height - (y1 - y0)) * .5 - y0 for y0, y1 in yspans] + + return yspan, offsets + + +class OffsetBox(martist.Artist): + """ + The OffsetBox is a simple container artist. + + The child artists are meant to be drawn at a relative position to its + parent. + + Being an artist itself, all parameters are passed on to `.Artist`. + """ + def __init__(self, *args, **kwargs): + super().__init__(*args) + self._internal_update(kwargs) + # Clipping has not been implemented in the OffsetBox family, so + # disable the clip flag for consistency. It can always be turned back + # on to zero effect. + self.set_clip_on(False) + self._children = [] + self._offset = (0, 0) + + def set_figure(self, fig): + """ + Set the `.Figure` for the `.OffsetBox` and all its children. + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + """ + super().set_figure(fig) + for c in self.get_children(): + c.set_figure(fig) + + @martist.Artist.axes.setter + def axes(self, ax): + # TODO deal with this better + martist.Artist.axes.fset(self, ax) + for c in self.get_children(): + if c is not None: + c.axes = ax + + def contains(self, mouseevent): + """ + Delegate the mouse event contains-check to the children. + + As a container, the `.OffsetBox` does not respond itself to + mouseevents. + + Parameters + ---------- + mouseevent : `~matplotlib.backend_bases.MouseEvent` + + Returns + ------- + contains : bool + Whether any values are within the radius. + details : dict + An artist-specific dictionary of details of the event context, + such as which points are contained in the pick radius. See the + individual Artist subclasses for details. + + See Also + -------- + .Artist.contains + """ + if self._different_canvas(mouseevent): + return False, {} + for c in self.get_children(): + a, b = c.contains(mouseevent) + if a: + return a, b + return False, {} + + def set_offset(self, xy): + """ + Set the offset. + + Parameters + ---------- + xy : (float, float) or callable + The (x, y) coordinates of the offset in display units. These can + either be given explicitly as a tuple (x, y), or by providing a + function that converts the extent into the offset. This function + must have the signature:: + + def offset(width, height, xdescent, ydescent, renderer) \ +-> (float, float) + """ + self._offset = xy + self.stale = True + + @_compat_get_offset + def get_offset(self, bbox, renderer): + """ + Return the offset as a tuple (x, y). + + The extent parameters have to be provided to handle the case where the + offset is dynamically determined by a callable (see + `~.OffsetBox.set_offset`). + + Parameters + ---------- + bbox : `.Bbox` + renderer : `.RendererBase` subclass + """ + return ( + self._offset(bbox.width, bbox.height, -bbox.x0, -bbox.y0, renderer) + if callable(self._offset) + else self._offset) + + def set_width(self, width): + """ + Set the width of the box. + + Parameters + ---------- + width : float + """ + self.width = width + self.stale = True + + def set_height(self, height): + """ + Set the height of the box. + + Parameters + ---------- + height : float + """ + self.height = height + self.stale = True + + def get_visible_children(self): + r"""Return a list of the visible child `.Artist`\s.""" + return [c for c in self._children if c.get_visible()] + + def get_children(self): + r"""Return a list of the child `.Artist`\s.""" + return self._children + + def _get_bbox_and_child_offsets(self, renderer): + """ + Return the bbox of the offsetbox and the child offsets. + + The bbox should satisfy ``x0 <= x1 and y0 <= y1``. + + Parameters + ---------- + renderer : `.RendererBase` subclass + + Returns + ------- + bbox + list of (xoffset, yoffset) pairs + """ + raise NotImplementedError( + "get_bbox_and_offsets must be overridden in derived classes") + + def get_bbox(self, renderer): + """Return the bbox of the offsetbox, ignoring parent offsets.""" + bbox, offsets = self._get_bbox_and_child_offsets(renderer) + return bbox + + @_api.deprecated("3.7", alternative="get_bbox and child.get_offset") + def get_extent_offsets(self, renderer): + """ + Update offset of the children and return the extent of the box. + + Parameters + ---------- + renderer : `.RendererBase` subclass + + Returns + ------- + width + height + xdescent + ydescent + list of (xoffset, yoffset) pairs + """ + bbox, offsets = self._get_bbox_and_child_offsets(renderer) + return bbox.width, bbox.height, -bbox.x0, -bbox.y0, offsets + + @_api.deprecated("3.7", alternative="get_bbox") + def get_extent(self, renderer): + """Return a tuple ``width, height, xdescent, ydescent`` of the box.""" + bbox = self.get_bbox(renderer) + return bbox.width, bbox.height, -bbox.x0, -bbox.y0 + + def get_window_extent(self, renderer=None): + # docstring inherited + if renderer is None: + renderer = self.figure._get_renderer() + bbox = self.get_bbox(renderer) + try: # Some subclasses redefine get_offset to take no args. + px, py = self.get_offset(bbox, renderer) + except TypeError: + px, py = self.get_offset() + return bbox.translated(px, py) + + def draw(self, renderer): + """ + Update the location of children if necessary and draw them + to the given *renderer*. + """ + bbox, offsets = self._get_bbox_and_child_offsets(renderer) + px, py = self.get_offset(bbox, renderer) + for c, (ox, oy) in zip(self.get_visible_children(), offsets): + c.set_offset((px + ox, py + oy)) + c.draw(renderer) + _bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) + self.stale = False + + +class PackerBase(OffsetBox): + def __init__(self, pad=0., sep=0., width=None, height=None, + align="baseline", mode="fixed", children=None): + """ + Parameters + ---------- + pad : float, default: 0.0 + The boundary padding in points. + + sep : float, default: 0.0 + The spacing between items in points. + + width, height : float, optional + Width and height of the container box in pixels, calculated if + *None*. + + align : {'top', 'bottom', 'left', 'right', 'center', 'baseline'}, \ +default: 'baseline' + Alignment of boxes. + + mode : {'fixed', 'expand', 'equal'}, default: 'fixed' + The packing mode. + + - 'fixed' packs the given `.Artist`\\s tight with *sep* spacing. + - 'expand' uses the maximal available space to distribute the + artists with equal spacing in between. + - 'equal': Each artist an equal fraction of the available space + and is left-aligned (or top-aligned) therein. + + children : list of `.Artist` + The artists to pack. + + Notes + ----- + *pad* and *sep* are in points and will be scaled with the renderer + dpi, while *width* and *height* are in pixels. + """ + super().__init__() + self.height = height + self.width = width + self.sep = sep + self.pad = pad + self.mode = mode + self.align = align + self._children = children + + +class VPacker(PackerBase): + """ + VPacker packs its children vertically, automatically adjusting their + relative positions at draw time. + """ + + def _get_bbox_and_child_offsets(self, renderer): + # docstring inherited + dpicor = renderer.points_to_pixels(1.) + pad = self.pad * dpicor + sep = self.sep * dpicor + + if self.width is not None: + for c in self.get_visible_children(): + if isinstance(c, PackerBase) and c.mode == "expand": + c.set_width(self.width) + + bboxes = [c.get_bbox(renderer) for c in self.get_visible_children()] + (x0, x1), xoffsets = _get_aligned_offsets( + [bbox.intervalx for bbox in bboxes], self.width, self.align) + height, yoffsets = _get_packed_offsets( + [bbox.height for bbox in bboxes], self.height, sep, self.mode) + + yoffsets = height - (yoffsets + [bbox.y1 for bbox in bboxes]) + ydescent = yoffsets[0] + yoffsets = yoffsets - ydescent + + return ( + Bbox.from_bounds(x0, -ydescent, x1 - x0, height).padded(pad), + [*zip(xoffsets, yoffsets)]) + + +class HPacker(PackerBase): + """ + HPacker packs its children horizontally, automatically adjusting their + relative positions at draw time. + """ + + def _get_bbox_and_child_offsets(self, renderer): + # docstring inherited + dpicor = renderer.points_to_pixels(1.) + pad = self.pad * dpicor + sep = self.sep * dpicor + + bboxes = [c.get_bbox(renderer) for c in self.get_visible_children()] + if not bboxes: + return Bbox.from_bounds(0, 0, 0, 0).padded(pad), [] + + (y0, y1), yoffsets = _get_aligned_offsets( + [bbox.intervaly for bbox in bboxes], self.height, self.align) + width, xoffsets = _get_packed_offsets( + [bbox.width for bbox in bboxes], self.width, sep, self.mode) + + x0 = bboxes[0].x0 + xoffsets -= ([bbox.x0 for bbox in bboxes] - x0) + + return (Bbox.from_bounds(x0, y0, width, y1 - y0).padded(pad), + [*zip(xoffsets, yoffsets)]) + + +class PaddedBox(OffsetBox): + """ + A container to add a padding around an `.Artist`. + + The `.PaddedBox` contains a `.FancyBboxPatch` that is used to visualize + it when rendering. + """ + + def __init__(self, child, pad=0., *, draw_frame=False, patch_attrs=None): + """ + Parameters + ---------- + child : `~matplotlib.artist.Artist` + The contained `.Artist`. + pad : float, default: 0.0 + The padding in points. This will be scaled with the renderer dpi. + In contrast, *width* and *height* are in *pixels* and thus not + scaled. + draw_frame : bool + Whether to draw the contained `.FancyBboxPatch`. + patch_attrs : dict or None + Additional parameters passed to the contained `.FancyBboxPatch`. + """ + super().__init__() + self.pad = pad + self._children = [child] + self.patch = FancyBboxPatch( + xy=(0.0, 0.0), width=1., height=1., + facecolor='w', edgecolor='k', + mutation_scale=1, # self.prop.get_size_in_points(), + snap=True, + visible=draw_frame, + boxstyle="square,pad=0", + ) + if patch_attrs is not None: + self.patch.update(patch_attrs) + + def _get_bbox_and_child_offsets(self, renderer): + # docstring inherited. + pad = self.pad * renderer.points_to_pixels(1.) + return (self._children[0].get_bbox(renderer).padded(pad), [(0, 0)]) + + def draw(self, renderer): + # docstring inherited + bbox, offsets = self._get_bbox_and_child_offsets(renderer) + px, py = self.get_offset(bbox, renderer) + for c, (ox, oy) in zip(self.get_visible_children(), offsets): + c.set_offset((px + ox, py + oy)) + + self.draw_frame(renderer) + + for c in self.get_visible_children(): + c.draw(renderer) + + self.stale = False + + def update_frame(self, bbox, fontsize=None): + self.patch.set_bounds(bbox.bounds) + if fontsize: + self.patch.set_mutation_scale(fontsize) + self.stale = True + + def draw_frame(self, renderer): + # update the location and size of the legend + self.update_frame(self.get_window_extent(renderer)) + self.patch.draw(renderer) + + +class DrawingArea(OffsetBox): + """ + The DrawingArea can contain any Artist as a child. The DrawingArea + has a fixed width and height. The position of children relative to + the parent is fixed. The children can be clipped at the + boundaries of the parent. + """ + + def __init__(self, width, height, xdescent=0., ydescent=0., clip=False): + """ + Parameters + ---------- + width, height : float + Width and height of the container box. + xdescent, ydescent : float + Descent of the box in x- and y-direction. + clip : bool + Whether to clip the children to the box. + """ + super().__init__() + self.width = width + self.height = height + self.xdescent = xdescent + self.ydescent = ydescent + self._clip_children = clip + self.offset_transform = mtransforms.Affine2D() + self.dpi_transform = mtransforms.Affine2D() + + @property + def clip_children(self): + """ + If the children of this DrawingArea should be clipped + by DrawingArea bounding box. + """ + return self._clip_children + + @clip_children.setter + def clip_children(self, val): + self._clip_children = bool(val) + self.stale = True + + def get_transform(self): + """ + Return the `~matplotlib.transforms.Transform` applied to the children. + """ + return self.dpi_transform + self.offset_transform + + def set_transform(self, t): + """ + set_transform is ignored. + """ + + def set_offset(self, xy): + """ + Set the offset of the container. + + Parameters + ---------- + xy : (float, float) + The (x, y) coordinates of the offset in display units. + """ + self._offset = xy + self.offset_transform.clear() + self.offset_transform.translate(xy[0], xy[1]) + self.stale = True + + def get_offset(self): + """Return offset of the container.""" + return self._offset + + def get_bbox(self, renderer): + # docstring inherited + dpi_cor = renderer.points_to_pixels(1.) + return Bbox.from_bounds( + -self.xdescent * dpi_cor, -self.ydescent * dpi_cor, + self.width * dpi_cor, self.height * dpi_cor) + + def add_artist(self, a): + """Add an `.Artist` to the container box.""" + self._children.append(a) + if not a.is_transform_set(): + a.set_transform(self.get_transform()) + if self.axes is not None: + a.axes = self.axes + fig = self.figure + if fig is not None: + a.set_figure(fig) + + def draw(self, renderer): + # docstring inherited + + dpi_cor = renderer.points_to_pixels(1.) + self.dpi_transform.clear() + self.dpi_transform.scale(dpi_cor) + + # At this point the DrawingArea has a transform + # to the display space so the path created is + # good for clipping children + tpath = mtransforms.TransformedPath( + mpath.Path([[0, 0], [0, self.height], + [self.width, self.height], + [self.width, 0]]), + self.get_transform()) + for c in self._children: + if self._clip_children and not (c.clipbox or c._clippath): + c.set_clip_path(tpath) + c.draw(renderer) + + _bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) + self.stale = False + + +class TextArea(OffsetBox): + """ + The TextArea is a container artist for a single Text instance. + + The text is placed at (0, 0) with baseline+left alignment, by default. The + width and height of the TextArea instance is the width and height of its + child text. + """ + + def __init__(self, s, + *, + textprops=None, + multilinebaseline=False, + ): + """ + Parameters + ---------- + s : str + The text to be displayed. + textprops : dict, default: {} + Dictionary of keyword parameters to be passed to the `.Text` + instance in the TextArea. + multilinebaseline : bool, default: False + Whether the baseline for multiline text is adjusted so that it + is (approximately) center-aligned with single-line text. + """ + if textprops is None: + textprops = {} + self._text = mtext.Text(0, 0, s, **textprops) + super().__init__() + self._children = [self._text] + self.offset_transform = mtransforms.Affine2D() + self._baseline_transform = mtransforms.Affine2D() + self._text.set_transform(self.offset_transform + + self._baseline_transform) + self._multilinebaseline = multilinebaseline + + def set_text(self, s): + """Set the text of this area as a string.""" + self._text.set_text(s) + self.stale = True + + def get_text(self): + """Return the string representation of this area's text.""" + return self._text.get_text() + + def set_multilinebaseline(self, t): + """ + Set multilinebaseline. + + If True, the baseline for multiline text is adjusted so that it is + (approximately) center-aligned with single-line text. This is used + e.g. by the legend implementation so that single-line labels are + baseline-aligned, but multiline labels are "center"-aligned with them. + """ + self._multilinebaseline = t + self.stale = True + + def get_multilinebaseline(self): + """ + Get multilinebaseline. + """ + return self._multilinebaseline + + def set_transform(self, t): + """ + set_transform is ignored. + """ + + def set_offset(self, xy): + """ + Set the offset of the container. + + Parameters + ---------- + xy : (float, float) + The (x, y) coordinates of the offset in display units. + """ + self._offset = xy + self.offset_transform.clear() + self.offset_transform.translate(xy[0], xy[1]) + self.stale = True + + def get_offset(self): + """Return offset of the container.""" + return self._offset + + def get_bbox(self, renderer): + _, h_, d_ = renderer.get_text_width_height_descent( + "lp", self._text._fontproperties, + ismath="TeX" if self._text.get_usetex() else False) + + bbox, info, yd = self._text._get_layout(renderer) + w, h = bbox.size + + self._baseline_transform.clear() + + if len(info) > 1 and self._multilinebaseline: + yd_new = 0.5 * h - 0.5 * (h_ - d_) + self._baseline_transform.translate(0, yd - yd_new) + yd = yd_new + else: # single line + h_d = max(h_ - d_, h - yd) + h = h_d + yd + + ha = self._text.get_horizontalalignment() + x0 = {"left": 0, "center": -w / 2, "right": -w}[ha] + + return Bbox.from_bounds(x0, -yd, w, h) + + def draw(self, renderer): + # docstring inherited + self._text.draw(renderer) + _bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) + self.stale = False + + +class AuxTransformBox(OffsetBox): + """ + Offset Box with the aux_transform. Its children will be + transformed with the aux_transform first then will be + offsetted. The absolute coordinate of the aux_transform is meaning + as it will be automatically adjust so that the left-lower corner + of the bounding box of children will be set to (0, 0) before the + offset transform. + + It is similar to drawing area, except that the extent of the box + is not predetermined but calculated from the window extent of its + children. Furthermore, the extent of the children will be + calculated in the transformed coordinate. + """ + def __init__(self, aux_transform): + self.aux_transform = aux_transform + super().__init__() + self.offset_transform = mtransforms.Affine2D() + # ref_offset_transform makes offset_transform always relative to the + # lower-left corner of the bbox of its children. + self.ref_offset_transform = mtransforms.Affine2D() + + def add_artist(self, a): + """Add an `.Artist` to the container box.""" + self._children.append(a) + a.set_transform(self.get_transform()) + self.stale = True + + def get_transform(self): + """ + Return the :class:`~matplotlib.transforms.Transform` applied + to the children + """ + return (self.aux_transform + + self.ref_offset_transform + + self.offset_transform) + + def set_transform(self, t): + """ + set_transform is ignored. + """ + + def set_offset(self, xy): + """ + Set the offset of the container. + + Parameters + ---------- + xy : (float, float) + The (x, y) coordinates of the offset in display units. + """ + self._offset = xy + self.offset_transform.clear() + self.offset_transform.translate(xy[0], xy[1]) + self.stale = True + + def get_offset(self): + """Return offset of the container.""" + return self._offset + + def get_bbox(self, renderer): + # clear the offset transforms + _off = self.offset_transform.get_matrix() # to be restored later + self.ref_offset_transform.clear() + self.offset_transform.clear() + # calculate the extent + bboxes = [c.get_window_extent(renderer) for c in self._children] + ub = Bbox.union(bboxes) + # adjust ref_offset_transform + self.ref_offset_transform.translate(-ub.x0, -ub.y0) + # restore offset transform + self.offset_transform.set_matrix(_off) + return Bbox.from_bounds(0, 0, ub.width, ub.height) + + def draw(self, renderer): + # docstring inherited + for c in self._children: + c.draw(renderer) + _bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) + self.stale = False + + +class AnchoredOffsetbox(OffsetBox): + """ + An offset box placed according to location *loc*. + + AnchoredOffsetbox has a single child. When multiple children are needed, + use an extra OffsetBox to enclose them. By default, the offset box is + anchored against its parent axes. You may explicitly specify the + *bbox_to_anchor*. + """ + zorder = 5 # zorder of the legend + + # Location codes + codes = {'upper right': 1, + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'right': 5, + 'center left': 6, + 'center right': 7, + 'lower center': 8, + 'upper center': 9, + 'center': 10, + } + + def __init__(self, loc, *, + pad=0.4, borderpad=0.5, + child=None, prop=None, frameon=True, + bbox_to_anchor=None, + bbox_transform=None, + **kwargs): + """ + Parameters + ---------- + loc : str + The box location. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + pad : float, default: 0.4 + Padding around the child as fraction of the fontsize. + borderpad : float, default: 0.5 + Padding between the offsetbox frame and the *bbox_to_anchor*. + child : `.OffsetBox` + The box that will be anchored. + prop : `.FontProperties` + This is only used as a reference for paddings. If not given, + :rc:`legend.fontsize` is used. + frameon : bool + Whether to draw a frame around the box. + bbox_to_anchor : `.BboxBase`, 2-tuple, or 4-tuple of floats + Box that is used to position the legend in conjunction with *loc*. + bbox_transform : None or :class:`matplotlib.transforms.Transform` + The transform for the bounding box (*bbox_to_anchor*). + **kwargs + All other parameters are passed on to `.OffsetBox`. + + Notes + ----- + See `.Legend` for a detailed description of the anchoring mechanism. + """ + super().__init__(**kwargs) + + self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform) + self.set_child(child) + + if isinstance(loc, str): + loc = _api.check_getitem(self.codes, loc=loc) + + self.loc = loc + self.borderpad = borderpad + self.pad = pad + + if prop is None: + self.prop = FontProperties(size=mpl.rcParams["legend.fontsize"]) + else: + self.prop = FontProperties._from_any(prop) + if isinstance(prop, dict) and "size" not in prop: + self.prop.set_size(mpl.rcParams["legend.fontsize"]) + + self.patch = FancyBboxPatch( + xy=(0.0, 0.0), width=1., height=1., + facecolor='w', edgecolor='k', + mutation_scale=self.prop.get_size_in_points(), + snap=True, + visible=frameon, + boxstyle="square,pad=0", + ) + + def set_child(self, child): + """Set the child to be anchored.""" + self._child = child + if child is not None: + child.axes = self.axes + self.stale = True + + def get_child(self): + """Return the child.""" + return self._child + + def get_children(self): + """Return the list of children.""" + return [self._child] + + def get_bbox(self, renderer): + # docstring inherited + fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) + pad = self.pad * fontsize + return self.get_child().get_bbox(renderer).padded(pad) + + def get_bbox_to_anchor(self): + """Return the bbox that the box is anchored to.""" + if self._bbox_to_anchor is None: + return self.axes.bbox + else: + transform = self._bbox_to_anchor_transform + if transform is None: + return self._bbox_to_anchor + else: + return TransformedBbox(self._bbox_to_anchor, transform) + + def set_bbox_to_anchor(self, bbox, transform=None): + """ + Set the bbox that the box is anchored to. + + *bbox* can be a Bbox instance, a list of [left, bottom, width, + height], or a list of [left, bottom] where the width and + height will be assumed to be zero. The bbox will be + transformed to display coordinate by the given transform. + """ + if bbox is None or isinstance(bbox, BboxBase): + self._bbox_to_anchor = bbox + else: + try: + l = len(bbox) + except TypeError as err: + raise ValueError(f"Invalid bbox: {bbox}") from err + + if l == 2: + bbox = [bbox[0], bbox[1], 0, 0] + + self._bbox_to_anchor = Bbox.from_bounds(*bbox) + + self._bbox_to_anchor_transform = transform + self.stale = True + + @_compat_get_offset + def get_offset(self, bbox, renderer): + # docstring inherited + pad = (self.borderpad + * renderer.points_to_pixels(self.prop.get_size_in_points())) + bbox_to_anchor = self.get_bbox_to_anchor() + x0, y0 = _get_anchored_bbox( + self.loc, Bbox.from_bounds(0, 0, bbox.width, bbox.height), + bbox_to_anchor, pad) + return x0 - bbox.x0, y0 - bbox.y0 + + def update_frame(self, bbox, fontsize=None): + self.patch.set_bounds(bbox.bounds) + if fontsize: + self.patch.set_mutation_scale(fontsize) + + def draw(self, renderer): + # docstring inherited + if not self.get_visible(): + return + + # update the location and size of the legend + bbox = self.get_window_extent(renderer) + fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) + self.update_frame(bbox, fontsize) + self.patch.draw(renderer) + + px, py = self.get_offset(self.get_bbox(renderer), renderer) + self.get_child().set_offset((px, py)) + self.get_child().draw(renderer) + self.stale = False + + +def _get_anchored_bbox(loc, bbox, parentbbox, borderpad): + """ + Return the (x, y) position of the *bbox* anchored at the *parentbbox* with + the *loc* code with the *borderpad*. + """ + # This is only called internally and *loc* should already have been + # validated. If 0 (None), we just let ``bbox.anchored`` raise. + c = [None, "NE", "NW", "SW", "SE", "E", "W", "E", "S", "N", "C"][loc] + container = parentbbox.padded(-borderpad) + return bbox.anchored(c, container=container).p0 + + +class AnchoredText(AnchoredOffsetbox): + """ + AnchoredOffsetbox with Text. + """ + + def __init__(self, s, loc, *, pad=0.4, borderpad=0.5, prop=None, **kwargs): + """ + Parameters + ---------- + s : str + Text. + + loc : str + Location code. See `AnchoredOffsetbox`. + + pad : float, default: 0.4 + Padding around the text as fraction of the fontsize. + + borderpad : float, default: 0.5 + Spacing between the offsetbox frame and the *bbox_to_anchor*. + + prop : dict, optional + Dictionary of keyword parameters to be passed to the + `~matplotlib.text.Text` instance contained inside AnchoredText. + + **kwargs + All other parameters are passed to `AnchoredOffsetbox`. + """ + + if prop is None: + prop = {} + badkwargs = {'va', 'verticalalignment'} + if badkwargs & set(prop): + raise ValueError( + 'Mixing verticalalignment with AnchoredText is not supported.') + + self.txt = TextArea(s, textprops=prop) + fp = self.txt._text.get_fontproperties() + super().__init__( + loc, pad=pad, borderpad=borderpad, child=self.txt, prop=fp, + **kwargs) + + +class OffsetImage(OffsetBox): + + def __init__(self, arr, *, + zoom=1, + cmap=None, + norm=None, + interpolation=None, + origin=None, + filternorm=True, + filterrad=4.0, + resample=False, + dpi_cor=True, + **kwargs + ): + + super().__init__() + self._dpi_cor = dpi_cor + + self.image = BboxImage(bbox=self.get_window_extent, + cmap=cmap, + norm=norm, + interpolation=interpolation, + origin=origin, + filternorm=filternorm, + filterrad=filterrad, + resample=resample, + **kwargs + ) + + self._children = [self.image] + + self.set_zoom(zoom) + self.set_data(arr) + + def set_data(self, arr): + self._data = np.asarray(arr) + self.image.set_data(self._data) + self.stale = True + + def get_data(self): + return self._data + + def set_zoom(self, zoom): + self._zoom = zoom + self.stale = True + + def get_zoom(self): + return self._zoom + + def get_offset(self): + """Return offset of the container.""" + return self._offset + + def get_children(self): + return [self.image] + + def get_bbox(self, renderer): + dpi_cor = renderer.points_to_pixels(1.) if self._dpi_cor else 1. + zoom = self.get_zoom() + data = self.get_data() + ny, nx = data.shape[:2] + w, h = dpi_cor * nx * zoom, dpi_cor * ny * zoom + return Bbox.from_bounds(0, 0, w, h) + + def draw(self, renderer): + # docstring inherited + self.image.draw(renderer) + # bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) + self.stale = False + + +class AnnotationBbox(martist.Artist, mtext._AnnotationBase): + """ + Container for an `OffsetBox` referring to a specific position *xy*. + + Optionally an arrow pointing from the offsetbox to *xy* can be drawn. + + This is like `.Annotation`, but with `OffsetBox` instead of `.Text`. + """ + + zorder = 3 + + def __str__(self): + return f"AnnotationBbox({self.xy[0]:g},{self.xy[1]:g})" + + @_docstring.dedent_interpd + def __init__(self, offsetbox, xy, xybox=None, xycoords='data', boxcoords=None, *, + frameon=True, pad=0.4, # FancyBboxPatch boxstyle. + annotation_clip=None, + box_alignment=(0.5, 0.5), + bboxprops=None, + arrowprops=None, + fontsize=None, + **kwargs): + """ + Parameters + ---------- + offsetbox : `OffsetBox` + + xy : (float, float) + The point *(x, y)* to annotate. The coordinate system is determined + by *xycoords*. + + xybox : (float, float), default: *xy* + The position *(x, y)* to place the text at. The coordinate system + is determined by *boxcoords*. + + xycoords : single or two-tuple of str or `.Artist` or `.Transform` or \ +callable, default: 'data' + The coordinate system that *xy* is given in. See the parameter + *xycoords* in `.Annotation` for a detailed description. + + boxcoords : single or two-tuple of str or `.Artist` or `.Transform` \ +or callable, default: value of *xycoords* + The coordinate system that *xybox* is given in. See the parameter + *textcoords* in `.Annotation` for a detailed description. + + frameon : bool, default: True + By default, the text is surrounded by a white `.FancyBboxPatch` + (accessible as the ``patch`` attribute of the `.AnnotationBbox`). + If *frameon* is set to False, this patch is made invisible. + + annotation_clip: bool or None, default: None + Whether to clip (i.e. not draw) the annotation when the annotation + point *xy* is outside the axes area. + + - If *True*, the annotation will be clipped when *xy* is outside + the axes. + - If *False*, the annotation will always be drawn. + - If *None*, the annotation will be clipped when *xy* is outside + the axes and *xycoords* is 'data'. + + pad : float, default: 0.4 + Padding around the offsetbox. + + box_alignment : (float, float) + A tuple of two floats for a vertical and horizontal alignment of + the offset box w.r.t. the *boxcoords*. + The lower-left corner is (0, 0) and upper-right corner is (1, 1). + + bboxprops : dict, optional + A dictionary of properties to set for the annotation bounding box, + for example *boxstyle* and *alpha*. See `.FancyBboxPatch` for + details. + + arrowprops: dict, optional + Arrow properties, see `.Annotation` for description. + + fontsize: float or str, optional + Translated to points and passed as *mutation_scale* into + `.FancyBboxPatch` to scale attributes of the box style (e.g. pad + or rounding_size). The name is chosen in analogy to `.Text` where + *fontsize* defines the mutation scale as well. If not given, + :rc:`legend.fontsize` is used. See `.Text.set_fontsize` for valid + values. + + **kwargs + Other `AnnotationBbox` properties. See `.AnnotationBbox.set` for + a list. + """ + + martist.Artist.__init__(self) + mtext._AnnotationBase.__init__( + self, xy, xycoords=xycoords, annotation_clip=annotation_clip) + + self.offsetbox = offsetbox + self.arrowprops = arrowprops.copy() if arrowprops is not None else None + self.set_fontsize(fontsize) + self.xybox = xybox if xybox is not None else xy + self.boxcoords = boxcoords if boxcoords is not None else xycoords + self._box_alignment = box_alignment + + if arrowprops is not None: + self._arrow_relpos = self.arrowprops.pop("relpos", (0.5, 0.5)) + self.arrow_patch = FancyArrowPatch((0, 0), (1, 1), + **self.arrowprops) + else: + self._arrow_relpos = None + self.arrow_patch = None + + self.patch = FancyBboxPatch( # frame + xy=(0.0, 0.0), width=1., height=1., + facecolor='w', edgecolor='k', + mutation_scale=self.prop.get_size_in_points(), + snap=True, + visible=frameon, + ) + self.patch.set_boxstyle("square", pad=pad) + if bboxprops: + self.patch.set(**bboxprops) + + self._internal_update(kwargs) + + @property + def xyann(self): + return self.xybox + + @xyann.setter + def xyann(self, xyann): + self.xybox = xyann + self.stale = True + + @property + def anncoords(self): + return self.boxcoords + + @anncoords.setter + def anncoords(self, coords): + self.boxcoords = coords + self.stale = True + + def contains(self, mouseevent): + if self._different_canvas(mouseevent): + return False, {} + if not self._check_xy(None): + return False, {} + return self.offsetbox.contains(mouseevent) + # self.arrow_patch is currently not checked as this can be a line - JJ + + def get_children(self): + children = [self.offsetbox, self.patch] + if self.arrow_patch: + children.append(self.arrow_patch) + return children + + def set_figure(self, fig): + if self.arrow_patch is not None: + self.arrow_patch.set_figure(fig) + self.offsetbox.set_figure(fig) + martist.Artist.set_figure(self, fig) + + def set_fontsize(self, s=None): + """ + Set the fontsize in points. + + If *s* is not given, reset to :rc:`legend.fontsize`. + """ + if s is None: + s = mpl.rcParams["legend.fontsize"] + + self.prop = FontProperties(size=s) + self.stale = True + + def get_fontsize(self): + """Return the fontsize in points.""" + return self.prop.get_size_in_points() + + def get_window_extent(self, renderer=None): + # docstring inherited + if renderer is None: + renderer = self.figure._get_renderer() + self.update_positions(renderer) + return Bbox.union([child.get_window_extent(renderer) + for child in self.get_children()]) + + def get_tightbbox(self, renderer=None): + # docstring inherited + if renderer is None: + renderer = self.figure._get_renderer() + self.update_positions(renderer) + return Bbox.union([child.get_tightbbox(renderer) + for child in self.get_children()]) + + def update_positions(self, renderer): + """Update pixel positions for the annotated point, the text, and the arrow.""" + + ox0, oy0 = self._get_xy(renderer, self.xybox, self.boxcoords) + bbox = self.offsetbox.get_bbox(renderer) + fw, fh = self._box_alignment + self.offsetbox.set_offset( + (ox0 - fw*bbox.width - bbox.x0, oy0 - fh*bbox.height - bbox.y0)) + + bbox = self.offsetbox.get_window_extent(renderer) + self.patch.set_bounds(bbox.bounds) + + mutation_scale = renderer.points_to_pixels(self.get_fontsize()) + self.patch.set_mutation_scale(mutation_scale) + + if self.arrowprops: + # Use FancyArrowPatch if self.arrowprops has "arrowstyle" key. + + # Adjust the starting point of the arrow relative to the textbox. + # TODO: Rotation needs to be accounted. + arrow_begin = bbox.p0 + bbox.size * self._arrow_relpos + arrow_end = self._get_position_xy(renderer) + # The arrow (from arrow_begin to arrow_end) will be first clipped + # by patchA and patchB, then shrunk by shrinkA and shrinkB (in + # points). If patch A is not set, self.bbox_patch is used. + self.arrow_patch.set_positions(arrow_begin, arrow_end) + + if "mutation_scale" in self.arrowprops: + mutation_scale = renderer.points_to_pixels( + self.arrowprops["mutation_scale"]) + # Else, use fontsize-based mutation_scale defined above. + self.arrow_patch.set_mutation_scale(mutation_scale) + + patchA = self.arrowprops.get("patchA", self.patch) + self.arrow_patch.set_patchA(patchA) + + def draw(self, renderer): + # docstring inherited + if renderer is not None: + self._renderer = renderer + if not self.get_visible() or not self._check_xy(renderer): + return + renderer.open_group(self.__class__.__name__, gid=self.get_gid()) + self.update_positions(renderer) + if self.arrow_patch is not None: + if self.arrow_patch.figure is None and self.figure is not None: + self.arrow_patch.figure = self.figure + self.arrow_patch.draw(renderer) + self.patch.draw(renderer) + self.offsetbox.draw(renderer) + renderer.close_group(self.__class__.__name__) + self.stale = False + + +class DraggableBase: + """ + Helper base class for a draggable artist (legend, offsetbox). + + Derived classes must override the following methods:: + + def save_offset(self): + ''' + Called when the object is picked for dragging; should save the + reference position of the artist. + ''' + + def update_offset(self, dx, dy): + ''' + Called during the dragging; (*dx*, *dy*) is the pixel offset from + the point where the mouse drag started. + ''' + + Optionally, you may override the following method:: + + def finalize_offset(self): + '''Called when the mouse is released.''' + + In the current implementation of `.DraggableLegend` and + `DraggableAnnotation`, `update_offset` places the artists in display + coordinates, and `finalize_offset` recalculates their position in axes + coordinate and set a relevant attribute. + """ + + def __init__(self, ref_artist, use_blit=False): + self.ref_artist = ref_artist + if not ref_artist.pickable(): + ref_artist.set_picker(True) + self.got_artist = False + self._use_blit = use_blit and self.canvas.supports_blit + callbacks = ref_artist.figure._canvas_callbacks + self._disconnectors = [ + functools.partial( + callbacks.disconnect, callbacks._connect_picklable(name, func)) + for name, func in [ + ("pick_event", self.on_pick), + ("button_release_event", self.on_release), + ("motion_notify_event", self.on_motion), + ] + ] + + # A property, not an attribute, to maintain picklability. + canvas = property(lambda self: self.ref_artist.figure.canvas) + + cids = property(lambda self: [ + disconnect.args[0] for disconnect in self._disconnectors[:2]]) + + def on_motion(self, evt): + if self._check_still_parented() and self.got_artist: + dx = evt.x - self.mouse_x + dy = evt.y - self.mouse_y + self.update_offset(dx, dy) + if self._use_blit: + self.canvas.restore_region(self.background) + self.ref_artist.draw( + self.ref_artist.figure._get_renderer()) + self.canvas.blit() + else: + self.canvas.draw() + + def on_pick(self, evt): + if self._check_still_parented() and evt.artist == self.ref_artist: + self.mouse_x = evt.mouseevent.x + self.mouse_y = evt.mouseevent.y + self.got_artist = True + if self._use_blit: + self.ref_artist.set_animated(True) + self.canvas.draw() + self.background = \ + self.canvas.copy_from_bbox(self.ref_artist.figure.bbox) + self.ref_artist.draw( + self.ref_artist.figure._get_renderer()) + self.canvas.blit() + self.save_offset() + + def on_release(self, event): + if self._check_still_parented() and self.got_artist: + self.finalize_offset() + self.got_artist = False + if self._use_blit: + self.ref_artist.set_animated(False) + + def _check_still_parented(self): + if self.ref_artist.figure is None: + self.disconnect() + return False + else: + return True + + def disconnect(self): + """Disconnect the callbacks.""" + for disconnector in self._disconnectors: + disconnector() + + def save_offset(self): + pass + + def update_offset(self, dx, dy): + pass + + def finalize_offset(self): + pass + + +class DraggableOffsetBox(DraggableBase): + def __init__(self, ref_artist, offsetbox, use_blit=False): + super().__init__(ref_artist, use_blit=use_blit) + self.offsetbox = offsetbox + + def save_offset(self): + offsetbox = self.offsetbox + renderer = offsetbox.figure._get_renderer() + offset = offsetbox.get_offset(offsetbox.get_bbox(renderer), renderer) + self.offsetbox_x, self.offsetbox_y = offset + self.offsetbox.set_offset(offset) + + def update_offset(self, dx, dy): + loc_in_canvas = self.offsetbox_x + dx, self.offsetbox_y + dy + self.offsetbox.set_offset(loc_in_canvas) + + def get_loc_in_canvas(self): + offsetbox = self.offsetbox + renderer = offsetbox.figure._get_renderer() + bbox = offsetbox.get_bbox(renderer) + ox, oy = offsetbox._offset + loc_in_canvas = (ox + bbox.x0, oy + bbox.y0) + return loc_in_canvas + + +class DraggableAnnotation(DraggableBase): + def __init__(self, annotation, use_blit=False): + super().__init__(annotation, use_blit=use_blit) + self.annotation = annotation + + def save_offset(self): + ann = self.annotation + self.ox, self.oy = ann.get_transform().transform(ann.xyann) + + def update_offset(self, dx, dy): + ann = self.annotation + ann.xyann = ann.get_transform().inverted().transform( + (self.ox + dx, self.oy + dy)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.pyi new file mode 100644 index 00000000..fdd6ce28 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/offsetbox.pyi @@ -0,0 +1,321 @@ +import matplotlib.artist as martist +from matplotlib.backend_bases import RendererBase, Event, FigureCanvasBase +from matplotlib.colors import Colormap, Normalize +import matplotlib.text as mtext +from matplotlib.figure import Figure +from matplotlib.font_manager import FontProperties +from matplotlib.image import BboxImage +from matplotlib.patches import FancyArrowPatch, FancyBboxPatch +from matplotlib.transforms import Bbox, BboxBase, Transform + +import numpy as np +from numpy.typing import ArrayLike +from collections.abc import Callable, Sequence +from typing import Any, Literal, overload + +DEBUG: bool + +def bbox_artist(*args, **kwargs) -> None: ... +def _get_packed_offsets( + widths: Sequence[float], + total: float | None, + sep: float | None, + mode: Literal["fixed", "expand", "equal"] = ..., +) -> tuple[float, np.ndarray]: ... + +class OffsetBox(martist.Artist): + width: float | None + height: float | None + def __init__(self, *args, **kwargs) -> None: ... + def set_figure(self, fig: Figure) -> None: ... + def set_offset( + self, + xy: tuple[float, float] + | Callable[[float, float, float, float, RendererBase], tuple[float, float]], + ) -> None: ... + + @overload + def get_offset(self, bbox: Bbox, renderer: RendererBase) -> tuple[float, float]: ... + @overload + def get_offset( + self, + width: float, + height: float, + xdescent: float, + ydescent: float, + renderer: RendererBase + ) -> tuple[float, float]: ... + + def set_width(self, width: float) -> None: ... + def set_height(self, height: float) -> None: ... + def get_visible_children(self) -> list[martist.Artist]: ... + def get_children(self) -> list[martist.Artist]: ... + def get_bbox(self, renderer: RendererBase) -> Bbox: ... + def get_extent_offsets( + self, renderer: RendererBase + ) -> tuple[float, float, float, float, list[tuple[float, float]]]: ... + def get_extent( + self, renderer: RendererBase + ) -> tuple[float, float, float, float]: ... + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... + +class PackerBase(OffsetBox): + height: float | None + width: float | None + sep: float | None + pad: float | None + mode: Literal["fixed", "expand", "equal"] + align: Literal["top", "bottom", "left", "right", "center", "baseline"] + def __init__( + self, + pad: float | None = ..., + sep: float | None = ..., + width: float | None = ..., + height: float | None = ..., + align: Literal["top", "bottom", "left", "right", "center", "baseline"] = ..., + mode: Literal["fixed", "expand", "equal"] = ..., + children: list[martist.Artist] | None = ..., + ) -> None: ... + +class VPacker(PackerBase): ... +class HPacker(PackerBase): ... + +class PaddedBox(OffsetBox): + pad: float | None + patch: FancyBboxPatch + def __init__( + self, + child: martist.Artist, + pad: float | None = ..., + *, + draw_frame: bool = ..., + patch_attrs: dict[str, Any] | None = ..., + ) -> None: ... + def update_frame(self, bbox: Bbox, fontsize: float | None = ...) -> None: ... + def draw_frame(self, renderer: RendererBase) -> None: ... + +class DrawingArea(OffsetBox): + width: float + height: float + xdescent: float + ydescent: float + offset_transform: Transform + dpi_transform: Transform + def __init__( + self, + width: float, + height: float, + xdescent: float = ..., + ydescent: float = ..., + clip: bool = ..., + ) -> None: ... + @property + def clip_children(self) -> bool: ... + @clip_children.setter + def clip_children(self, val: bool) -> None: ... + def get_transform(self) -> Transform: ... + + # does not accept all options of superclass + def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override] + def get_offset(self) -> tuple[float, float]: ... # type: ignore[override] + def add_artist(self, a: martist.Artist) -> None: ... + +class TextArea(OffsetBox): + offset_transform: Transform + def __init__( + self, + s: str, + *, + textprops: dict[str, Any] | None = ..., + multilinebaseline: bool = ..., + ) -> None: ... + def set_text(self, s: str) -> None: ... + def get_text(self) -> str: ... + def set_multilinebaseline(self, t: bool) -> None: ... + def get_multilinebaseline(self) -> bool: ... + + # does not accept all options of superclass + def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override] + def get_offset(self) -> tuple[float, float]: ... # type: ignore[override] + +class AuxTransformBox(OffsetBox): + aux_transform: Transform + offset_transform: Transform + ref_offset_transform: Transform + def __init__(self, aux_transform: Transform) -> None: ... + def add_artist(self, a: martist.Artist) -> None: ... + def get_transform(self) -> Transform: ... + + # does not accept all options of superclass + def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override] + def get_offset(self) -> tuple[float, float]: ... # type: ignore[override] + +class AnchoredOffsetbox(OffsetBox): + zorder: float + codes: dict[str, int] + loc: int + borderpad: float + pad: float + prop: FontProperties + patch: FancyBboxPatch + def __init__( + self, + loc: str, + *, + pad: float = ..., + borderpad: float = ..., + child: OffsetBox | None = ..., + prop: FontProperties | None = ..., + frameon: bool = ..., + bbox_to_anchor: BboxBase + | tuple[float, float] + | tuple[float, float, float, float] + | None = ..., + bbox_transform: Transform | None = ..., + **kwargs + ) -> None: ... + def set_child(self, child: OffsetBox | None) -> None: ... + def get_child(self) -> OffsetBox | None: ... + def get_children(self) -> list[martist.Artist]: ... + def get_bbox_to_anchor(self) -> Bbox: ... + def set_bbox_to_anchor( + self, bbox: BboxBase, transform: Transform | None = ... + ) -> None: ... + def update_frame(self, bbox: Bbox, fontsize: float | None = ...) -> None: ... + +class AnchoredText(AnchoredOffsetbox): + txt: TextArea + def __init__( + self, + s: str, + loc: str, + *, + pad: float = ..., + borderpad: float = ..., + prop: dict[str, Any] | None = ..., + **kwargs + ) -> None: ... + +class OffsetImage(OffsetBox): + image: BboxImage + def __init__( + self, + arr: ArrayLike, + *, + zoom: float = ..., + cmap: Colormap | str | None = ..., + norm: Normalize | str | None = ..., + interpolation: str | None = ..., + origin: Literal["upper", "lower"] | None = ..., + filternorm: bool = ..., + filterrad: float = ..., + resample: bool = ..., + dpi_cor: bool = ..., + **kwargs + ) -> None: ... + stale: bool + def set_data(self, arr: ArrayLike | None) -> None: ... + def get_data(self) -> ArrayLike | None: ... + def set_zoom(self, zoom: float) -> None: ... + def get_zoom(self) -> float: ... + def get_children(self) -> list[martist.Artist]: ... + def get_offset(self) -> tuple[float, float]: ... # type: ignore[override] + +class AnnotationBbox(martist.Artist, mtext._AnnotationBase): + zorder: float + offsetbox: OffsetBox + arrowprops: dict[str, Any] | None + xybox: tuple[float, float] + boxcoords: str | tuple[str, str] | martist.Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ] + arrow_patch: FancyArrowPatch | None + patch: FancyBboxPatch + prop: FontProperties + def __init__( + self, + offsetbox: OffsetBox, + xy: tuple[float, float], + xybox: tuple[float, float] | None = ..., + xycoords: str + | tuple[str, str] + | martist.Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] = ..., + boxcoords: str + | tuple[str, str] + | martist.Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] + | None = ..., + *, + frameon: bool = ..., + pad: float = ..., + annotation_clip: bool | None = ..., + box_alignment: tuple[float, float] = ..., + bboxprops: dict[str, Any] | None = ..., + arrowprops: dict[str, Any] | None = ..., + fontsize: float | str | None = ..., + **kwargs + ) -> None: ... + @property + def xyann(self) -> tuple[float, float]: ... + @xyann.setter + def xyann(self, xyann: tuple[float, float]) -> None: ... + @property + def anncoords( + self, + ) -> str | tuple[str, str] | martist.Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ]: ... + @anncoords.setter + def anncoords( + self, + coords: str + | tuple[str, str] + | martist.Artist + | Transform + | Callable[[RendererBase], Bbox | Transform], + ) -> None: ... + def get_children(self) -> list[martist.Artist]: ... + def set_figure(self, fig: Figure) -> None: ... + def set_fontsize(self, s: str | float | None = ...) -> None: ... + def get_fontsize(self) -> float: ... + def get_tightbbox(self, renderer: RendererBase | None = ...) -> Bbox: ... + def update_positions(self, renderer: RendererBase) -> None: ... + +class DraggableBase: + ref_artist: martist.Artist + got_artist: bool + mouse_x: int + mouse_y: int + background: Any + + @property + def canvas(self) -> FigureCanvasBase: ... + @property + def cids(self) -> list[int]: ... + + def __init__(self, ref_artist: martist.Artist, use_blit: bool = ...) -> None: ... + def on_motion(self, evt: Event) -> None: ... + def on_pick(self, evt: Event) -> None: ... + def on_release(self, event: Event) -> None: ... + def disconnect(self) -> None: ... + def save_offset(self) -> None: ... + def update_offset(self, dx: float, dy: float) -> None: ... + def finalize_offset(self) -> None: ... + +class DraggableOffsetBox(DraggableBase): + offsetbox: OffsetBox + def __init__( + self, ref_artist: martist.Artist, offsetbox: OffsetBox, use_blit: bool = ... + ) -> None: ... + def save_offset(self) -> None: ... + def update_offset(self, dx: float, dy: float) -> None: ... + def get_loc_in_canvas(self) -> tuple[float, float]: ... + +class DraggableAnnotation(DraggableBase): + annotation: mtext.Annotation + def __init__(self, annotation: mtext.Annotation, use_blit: bool = ...) -> None: ... + def save_offset(self) -> None: ... + def update_offset(self, dx: float, dy: float) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.py new file mode 100644 index 00000000..f80df92c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.py @@ -0,0 +1,4634 @@ +r""" +Patches are `.Artist`\s with a face color and an edge color. +""" + +import functools +import inspect +import math +from numbers import Number, Real +import textwrap +from types import SimpleNamespace +from collections import namedtuple +from matplotlib.transforms import Affine2D + +import numpy as np + +import matplotlib as mpl +from . import (_api, artist, cbook, colors, _docstring, hatch as mhatch, + lines as mlines, transforms) +from .bezier import ( + NonIntersectingPathException, get_cos_sin, get_intersection, + get_parallels, inside_circle, make_wedged_bezier2, + split_bezier_intersecting_with_closedpath, split_path_inout) +from .path import Path +from ._enums import JoinStyle, CapStyle + + +@_docstring.interpd +@_api.define_aliases({ + "antialiased": ["aa"], + "edgecolor": ["ec"], + "facecolor": ["fc"], + "linestyle": ["ls"], + "linewidth": ["lw"], +}) +class Patch(artist.Artist): + """ + A patch is a 2D artist with a face color and an edge color. + + If any of *edgecolor*, *facecolor*, *linewidth*, or *antialiased* + are *None*, they default to their rc params setting. + """ + zorder = 1 + + # Whether to draw an edge by default. Set on a + # subclass-by-subclass basis. + _edge_default = False + + def __init__(self, *, + edgecolor=None, + facecolor=None, + color=None, + linewidth=None, + linestyle=None, + antialiased=None, + hatch=None, + fill=True, + capstyle=None, + joinstyle=None, + **kwargs): + """ + The following kwarg properties are supported + + %(Patch:kwdoc)s + """ + super().__init__() + + if linestyle is None: + linestyle = "solid" + if capstyle is None: + capstyle = CapStyle.butt + if joinstyle is None: + joinstyle = JoinStyle.miter + + self._hatch_color = colors.to_rgba(mpl.rcParams['hatch.color']) + self._fill = bool(fill) # needed for set_facecolor call + if color is not None: + if edgecolor is not None or facecolor is not None: + _api.warn_external( + "Setting the 'color' property will override " + "the edgecolor or facecolor properties.") + self.set_color(color) + else: + self.set_edgecolor(edgecolor) + self.set_facecolor(facecolor) + + self._linewidth = 0 + self._unscaled_dash_pattern = (0, None) # offset, dash + self._dash_pattern = (0, None) # offset, dash (scaled by linewidth) + + self.set_linestyle(linestyle) + self.set_linewidth(linewidth) + self.set_antialiased(antialiased) + self.set_hatch(hatch) + self.set_capstyle(capstyle) + self.set_joinstyle(joinstyle) + + if len(kwargs): + self._internal_update(kwargs) + + def get_verts(self): + """ + Return a copy of the vertices used in this patch. + + If the patch contains Bézier curves, the curves will be interpolated by + line segments. To access the curves as curves, use `get_path`. + """ + trans = self.get_transform() + path = self.get_path() + polygons = path.to_polygons(trans) + if len(polygons): + return polygons[0] + return [] + + def _process_radius(self, radius): + if radius is not None: + return radius + if isinstance(self._picker, Number): + _radius = self._picker + else: + if self.get_edgecolor()[3] == 0: + _radius = 0 + else: + _radius = self.get_linewidth() + return _radius + + def contains(self, mouseevent, radius=None): + """ + Test whether the mouse event occurred in the patch. + + Returns + ------- + (bool, empty dict) + """ + if self._different_canvas(mouseevent): + return False, {} + radius = self._process_radius(radius) + codes = self.get_path().codes + if codes is not None: + vertices = self.get_path().vertices + # if the current path is concatenated by multiple sub paths. + # get the indexes of the starting code(MOVETO) of all sub paths + idxs, = np.where(codes == Path.MOVETO) + # Don't split before the first MOVETO. + idxs = idxs[1:] + subpaths = map( + Path, np.split(vertices, idxs), np.split(codes, idxs)) + else: + subpaths = [self.get_path()] + inside = any( + subpath.contains_point( + (mouseevent.x, mouseevent.y), self.get_transform(), radius) + for subpath in subpaths) + return inside, {} + + def contains_point(self, point, radius=None): + """ + Return whether the given point is inside the patch. + + Parameters + ---------- + point : (float, float) + The point (x, y) to check, in target coordinates of + ``self.get_transform()``. These are display coordinates for patches + that are added to a figure or axes. + radius : float, optional + Additional margin on the patch in target coordinates of + ``self.get_transform()``. See `.Path.contains_point` for further + details. + + Returns + ------- + bool + + Notes + ----- + The proper use of this method depends on the transform of the patch. + Isolated patches do not have a transform. In this case, the patch + creation coordinates and the point coordinates match. The following + example checks that the center of a circle is within the circle + + >>> center = 0, 0 + >>> c = Circle(center, radius=1) + >>> c.contains_point(center) + True + + The convention of checking against the transformed patch stems from + the fact that this method is predominantly used to check if display + coordinates (e.g. from mouse events) are within the patch. If you want + to do the above check with data coordinates, you have to properly + transform them first: + + >>> center = 0, 0 + >>> c = Circle(center, radius=1) + >>> plt.gca().add_patch(c) + >>> transformed_center = c.get_transform().transform(center) + >>> c.contains_point(transformed_center) + True + + """ + radius = self._process_radius(radius) + return self.get_path().contains_point(point, + self.get_transform(), + radius) + + def contains_points(self, points, radius=None): + """ + Return whether the given points are inside the patch. + + Parameters + ---------- + points : (N, 2) array + The points to check, in target coordinates of + ``self.get_transform()``. These are display coordinates for patches + that are added to a figure or axes. Columns contain x and y values. + radius : float, optional + Additional margin on the patch in target coordinates of + ``self.get_transform()``. See `.Path.contains_point` for further + details. + + Returns + ------- + length-N bool array + + Notes + ----- + The proper use of this method depends on the transform of the patch. + See the notes on `.Patch.contains_point`. + """ + radius = self._process_radius(radius) + return self.get_path().contains_points(points, + self.get_transform(), + radius) + + def update_from(self, other): + # docstring inherited. + super().update_from(other) + # For some properties we don't need or don't want to go through the + # getters/setters, so we just copy them directly. + self._edgecolor = other._edgecolor + self._facecolor = other._facecolor + self._original_edgecolor = other._original_edgecolor + self._original_facecolor = other._original_facecolor + self._fill = other._fill + self._hatch = other._hatch + self._hatch_color = other._hatch_color + self._unscaled_dash_pattern = other._unscaled_dash_pattern + self.set_linewidth(other._linewidth) # also sets scaled dashes + self.set_transform(other.get_data_transform()) + # If the transform of other needs further initialization, then it will + # be the case for this artist too. + self._transformSet = other.is_transform_set() + + def get_extents(self): + """ + Return the `Patch`'s axis-aligned extents as a `~.transforms.Bbox`. + """ + return self.get_path().get_extents(self.get_transform()) + + def get_transform(self): + """Return the `~.transforms.Transform` applied to the `Patch`.""" + return self.get_patch_transform() + artist.Artist.get_transform(self) + + def get_data_transform(self): + """ + Return the `~.transforms.Transform` mapping data coordinates to + physical coordinates. + """ + return artist.Artist.get_transform(self) + + def get_patch_transform(self): + """ + Return the `~.transforms.Transform` instance mapping patch coordinates + to data coordinates. + + For example, one may define a patch of a circle which represents a + radius of 5 by providing coordinates for a unit circle, and a + transform which scales the coordinates (the patch coordinate) by 5. + """ + return transforms.IdentityTransform() + + def get_antialiased(self): + """Return whether antialiasing is used for drawing.""" + return self._antialiased + + def get_edgecolor(self): + """Return the edge color.""" + return self._edgecolor + + def get_facecolor(self): + """Return the face color.""" + return self._facecolor + + def get_linewidth(self): + """Return the line width in points.""" + return self._linewidth + + def get_linestyle(self): + """Return the linestyle.""" + return self._linestyle + + def set_antialiased(self, aa): + """ + Set whether to use antialiased rendering. + + Parameters + ---------- + aa : bool or None + """ + if aa is None: + aa = mpl.rcParams['patch.antialiased'] + self._antialiased = aa + self.stale = True + + def _set_edgecolor(self, color): + set_hatch_color = True + if color is None: + if (mpl.rcParams['patch.force_edgecolor'] or + not self._fill or self._edge_default): + color = mpl.rcParams['patch.edgecolor'] + else: + color = 'none' + set_hatch_color = False + + self._edgecolor = colors.to_rgba(color, self._alpha) + if set_hatch_color: + self._hatch_color = self._edgecolor + self.stale = True + + def set_edgecolor(self, color): + """ + Set the patch edge color. + + Parameters + ---------- + color : color or None + """ + self._original_edgecolor = color + self._set_edgecolor(color) + + def _set_facecolor(self, color): + if color is None: + color = mpl.rcParams['patch.facecolor'] + alpha = self._alpha if self._fill else 0 + self._facecolor = colors.to_rgba(color, alpha) + self.stale = True + + def set_facecolor(self, color): + """ + Set the patch face color. + + Parameters + ---------- + color : color or None + """ + self._original_facecolor = color + self._set_facecolor(color) + + def set_color(self, c): + """ + Set both the edgecolor and the facecolor. + + Parameters + ---------- + c : color + + See Also + -------- + Patch.set_facecolor, Patch.set_edgecolor + For setting the edge or face color individually. + """ + self.set_facecolor(c) + self.set_edgecolor(c) + + def set_alpha(self, alpha): + # docstring inherited + super().set_alpha(alpha) + self._set_facecolor(self._original_facecolor) + self._set_edgecolor(self._original_edgecolor) + # stale is already True + + def set_linewidth(self, w): + """ + Set the patch linewidth in points. + + Parameters + ---------- + w : float or None + """ + if w is None: + w = mpl.rcParams['patch.linewidth'] + self._linewidth = float(w) + self._dash_pattern = mlines._scale_dashes( + *self._unscaled_dash_pattern, w) + self.stale = True + + def set_linestyle(self, ls): + """ + Set the patch linestyle. + + ========================================== ================= + linestyle description + ========================================== ================= + ``'-'`` or ``'solid'`` solid line + ``'--'`` or ``'dashed'`` dashed line + ``'-.'`` or ``'dashdot'`` dash-dotted line + ``':'`` or ``'dotted'`` dotted line + ``'none'``, ``'None'``, ``' '``, or ``''`` draw nothing + ========================================== ================= + + Alternatively a dash tuple of the following form can be provided:: + + (offset, onoffseq) + + where ``onoffseq`` is an even length tuple of on and off ink in points. + + Parameters + ---------- + ls : {'-', '--', '-.', ':', '', (offset, on-off-seq), ...} + The line style. + """ + if ls is None: + ls = "solid" + if ls in [' ', '', 'none']: + ls = 'None' + self._linestyle = ls + self._unscaled_dash_pattern = mlines._get_dash_pattern(ls) + self._dash_pattern = mlines._scale_dashes( + *self._unscaled_dash_pattern, self._linewidth) + self.stale = True + + def set_fill(self, b): + """ + Set whether to fill the patch. + + Parameters + ---------- + b : bool + """ + self._fill = bool(b) + self._set_facecolor(self._original_facecolor) + self._set_edgecolor(self._original_edgecolor) + self.stale = True + + def get_fill(self): + """Return whether the patch is filled.""" + return self._fill + + # Make fill a property so as to preserve the long-standing + # but somewhat inconsistent behavior in which fill was an + # attribute. + fill = property(get_fill, set_fill) + + @_docstring.interpd + def set_capstyle(self, s): + """ + Set the `.CapStyle`. + + The default capstyle is 'round' for `.FancyArrowPatch` and 'butt' for + all other patches. + + Parameters + ---------- + s : `.CapStyle` or %(CapStyle)s + """ + cs = CapStyle(s) + self._capstyle = cs + self.stale = True + + def get_capstyle(self): + """Return the capstyle.""" + return self._capstyle.name + + @_docstring.interpd + def set_joinstyle(self, s): + """ + Set the `.JoinStyle`. + + The default joinstyle is 'round' for `.FancyArrowPatch` and 'miter' for + all other patches. + + Parameters + ---------- + s : `.JoinStyle` or %(JoinStyle)s + """ + js = JoinStyle(s) + self._joinstyle = js + self.stale = True + + def get_joinstyle(self): + """Return the joinstyle.""" + return self._joinstyle.name + + def set_hatch(self, hatch): + r""" + Set the hatching pattern. + + *hatch* can be one of:: + + / - diagonal hatching + \ - back diagonal + | - vertical + - - horizontal + + - crossed + x - crossed diagonal + o - small circle + O - large circle + . - dots + * - stars + + Letters can be combined, in which case all the specified + hatchings are done. If same letter repeats, it increases the + density of hatching of that pattern. + + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + + Parameters + ---------- + hatch : {'/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*'} + """ + # Use validate_hatch(list) after deprecation. + mhatch._validate_hatch_pattern(hatch) + self._hatch = hatch + self.stale = True + + def get_hatch(self): + """Return the hatching pattern.""" + return self._hatch + + def _draw_paths_with_artist_properties( + self, renderer, draw_path_args_list): + """ + ``draw()`` helper factored out for sharing with `FancyArrowPatch`. + + Configure *renderer* and the associated graphics context *gc* + from the artist properties, then repeatedly call + ``renderer.draw_path(gc, *draw_path_args)`` for each tuple + *draw_path_args* in *draw_path_args_list*. + """ + + renderer.open_group('patch', self.get_gid()) + gc = renderer.new_gc() + + gc.set_foreground(self._edgecolor, isRGBA=True) + + lw = self._linewidth + if self._edgecolor[3] == 0 or self._linestyle == 'None': + lw = 0 + gc.set_linewidth(lw) + gc.set_dashes(*self._dash_pattern) + gc.set_capstyle(self._capstyle) + gc.set_joinstyle(self._joinstyle) + + gc.set_antialiased(self._antialiased) + self._set_gc_clip(gc) + gc.set_url(self._url) + gc.set_snap(self.get_snap()) + + gc.set_alpha(self._alpha) + + if self._hatch: + gc.set_hatch(self._hatch) + gc.set_hatch_color(self._hatch_color) + + if self.get_sketch_params() is not None: + gc.set_sketch_params(*self.get_sketch_params()) + + if self.get_path_effects(): + from matplotlib.patheffects import PathEffectRenderer + renderer = PathEffectRenderer(self.get_path_effects(), renderer) + + for draw_path_args in draw_path_args_list: + renderer.draw_path(gc, *draw_path_args) + + gc.restore() + renderer.close_group('patch') + self.stale = False + + @artist.allow_rasterization + def draw(self, renderer): + # docstring inherited + if not self.get_visible(): + return + path = self.get_path() + transform = self.get_transform() + tpath = transform.transform_path_non_affine(path) + affine = transform.get_affine() + self._draw_paths_with_artist_properties( + renderer, + [(tpath, affine, + # Work around a bug in the PDF and SVG renderers, which + # do not draw the hatches if the facecolor is fully + # transparent, but do if it is None. + self._facecolor if self._facecolor[3] else None)]) + + def get_path(self): + """Return the path of this patch.""" + raise NotImplementedError('Derived must override') + + def get_window_extent(self, renderer=None): + return self.get_path().get_extents(self.get_transform()) + + def _convert_xy_units(self, xy): + """Convert x and y units for a tuple (x, y).""" + x = self.convert_xunits(xy[0]) + y = self.convert_yunits(xy[1]) + return x, y + + +class Shadow(Patch): + def __str__(self): + return f"Shadow({self.patch})" + + @_docstring.dedent_interpd + def __init__(self, patch, ox, oy, *, shade=0.7, **kwargs): + """ + Create a shadow of the given *patch*. + + By default, the shadow will have the same face color as the *patch*, + but darkened. The darkness can be controlled by *shade*. + + Parameters + ---------- + patch : `~matplotlib.patches.Patch` + The patch to create the shadow for. + ox, oy : float + The shift of the shadow in data coordinates, scaled by a factor + of dpi/72. + shade : float, default: 0.7 + How the darkness of the shadow relates to the original color. If 1, the + shadow is black, if 0, the shadow has the same color as the *patch*. + + .. versionadded:: 3.8 + + **kwargs + Properties of the shadow patch. Supported keys are: + + %(Patch:kwdoc)s + """ + super().__init__() + self.patch = patch + self._ox, self._oy = ox, oy + self._shadow_transform = transforms.Affine2D() + + self.update_from(self.patch) + if not 0 <= shade <= 1: + raise ValueError("shade must be between 0 and 1.") + color = (1 - shade) * np.asarray(colors.to_rgb(self.patch.get_facecolor())) + self.update({'facecolor': color, 'edgecolor': color, 'alpha': 0.5, + # Place shadow patch directly behind the inherited patch. + 'zorder': np.nextafter(self.patch.zorder, -np.inf), + **kwargs}) + + def _update_transform(self, renderer): + ox = renderer.points_to_pixels(self._ox) + oy = renderer.points_to_pixels(self._oy) + self._shadow_transform.clear().translate(ox, oy) + + def get_path(self): + return self.patch.get_path() + + def get_patch_transform(self): + return self.patch.get_patch_transform() + self._shadow_transform + + def draw(self, renderer): + self._update_transform(renderer) + super().draw(renderer) + + +class Rectangle(Patch): + """ + A rectangle defined via an anchor point *xy* and its *width* and *height*. + + The rectangle extends from ``xy[0]`` to ``xy[0] + width`` in x-direction + and from ``xy[1]`` to ``xy[1] + height`` in y-direction. :: + + : +------------------+ + : | | + : height | + : | | + : (xy)---- width -----+ + + One may picture *xy* as the bottom left corner, but which corner *xy* is + actually depends on the direction of the axis and the sign of *width* + and *height*; e.g. *xy* would be the bottom right corner if the x-axis + was inverted or if *width* was negative. + """ + + def __str__(self): + pars = self._x0, self._y0, self._width, self._height, self.angle + fmt = "Rectangle(xy=(%g, %g), width=%g, height=%g, angle=%g)" + return fmt % pars + + @_docstring.dedent_interpd + def __init__(self, xy, width, height, *, + angle=0.0, rotation_point='xy', **kwargs): + """ + Parameters + ---------- + xy : (float, float) + The anchor point. + width : float + Rectangle width. + height : float + Rectangle height. + angle : float, default: 0 + Rotation in degrees anti-clockwise about the rotation point. + rotation_point : {'xy', 'center', (number, number)}, default: 'xy' + If ``'xy'``, rotate around the anchor point. If ``'center'`` rotate + around the center. If 2-tuple of number, rotate around this + coordinate. + + Other Parameters + ---------------- + **kwargs : `~matplotlib.patches.Patch` properties + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + self._x0 = xy[0] + self._y0 = xy[1] + self._width = width + self._height = height + self.angle = float(angle) + self.rotation_point = rotation_point + # Required for RectangleSelector with axes aspect ratio != 1 + # The patch is defined in data coordinates and when changing the + # selector with square modifier and not in data coordinates, we need + # to correct for the aspect ratio difference between the data and + # display coordinate systems. Its value is typically provide by + # Axes._get_aspect_ratio() + self._aspect_ratio_correction = 1.0 + self._convert_units() # Validate the inputs. + + def get_path(self): + """Return the vertices of the rectangle.""" + return Path.unit_rectangle() + + def _convert_units(self): + """Convert bounds of the rectangle.""" + x0 = self.convert_xunits(self._x0) + y0 = self.convert_yunits(self._y0) + x1 = self.convert_xunits(self._x0 + self._width) + y1 = self.convert_yunits(self._y0 + self._height) + return x0, y0, x1, y1 + + def get_patch_transform(self): + # Note: This cannot be called until after this has been added to + # an Axes, otherwise unit conversion will fail. This makes it very + # important to call the accessor method and not directly access the + # transformation member variable. + bbox = self.get_bbox() + if self.rotation_point == 'center': + width, height = bbox.x1 - bbox.x0, bbox.y1 - bbox.y0 + rotation_point = bbox.x0 + width / 2., bbox.y0 + height / 2. + elif self.rotation_point == 'xy': + rotation_point = bbox.x0, bbox.y0 + else: + rotation_point = self.rotation_point + return transforms.BboxTransformTo(bbox) \ + + transforms.Affine2D() \ + .translate(-rotation_point[0], -rotation_point[1]) \ + .scale(1, self._aspect_ratio_correction) \ + .rotate_deg(self.angle) \ + .scale(1, 1 / self._aspect_ratio_correction) \ + .translate(*rotation_point) + + @property + def rotation_point(self): + """The rotation point of the patch.""" + return self._rotation_point + + @rotation_point.setter + def rotation_point(self, value): + if value in ['center', 'xy'] or ( + isinstance(value, tuple) and len(value) == 2 and + isinstance(value[0], Real) and isinstance(value[1], Real) + ): + self._rotation_point = value + else: + raise ValueError("`rotation_point` must be one of " + "{'xy', 'center', (number, number)}.") + + def get_x(self): + """Return the left coordinate of the rectangle.""" + return self._x0 + + def get_y(self): + """Return the bottom coordinate of the rectangle.""" + return self._y0 + + def get_xy(self): + """Return the left and bottom coords of the rectangle as a tuple.""" + return self._x0, self._y0 + + def get_corners(self): + """ + Return the corners of the rectangle, moving anti-clockwise from + (x0, y0). + """ + return self.get_patch_transform().transform( + [(0, 0), (1, 0), (1, 1), (0, 1)]) + + def get_center(self): + """Return the centre of the rectangle.""" + return self.get_patch_transform().transform((0.5, 0.5)) + + def get_width(self): + """Return the width of the rectangle.""" + return self._width + + def get_height(self): + """Return the height of the rectangle.""" + return self._height + + def get_angle(self): + """Get the rotation angle in degrees.""" + return self.angle + + def set_x(self, x): + """Set the left coordinate of the rectangle.""" + self._x0 = x + self.stale = True + + def set_y(self, y): + """Set the bottom coordinate of the rectangle.""" + self._y0 = y + self.stale = True + + def set_angle(self, angle): + """ + Set the rotation angle in degrees. + + The rotation is performed anti-clockwise around *xy*. + """ + self.angle = angle + self.stale = True + + def set_xy(self, xy): + """ + Set the left and bottom coordinates of the rectangle. + + Parameters + ---------- + xy : (float, float) + """ + self._x0, self._y0 = xy + self.stale = True + + def set_width(self, w): + """Set the width of the rectangle.""" + self._width = w + self.stale = True + + def set_height(self, h): + """Set the height of the rectangle.""" + self._height = h + self.stale = True + + def set_bounds(self, *args): + """ + Set the bounds of the rectangle as *left*, *bottom*, *width*, *height*. + + The values may be passed as separate parameters or as a tuple:: + + set_bounds(left, bottom, width, height) + set_bounds((left, bottom, width, height)) + + .. ACCEPTS: (left, bottom, width, height) + """ + if len(args) == 1: + l, b, w, h = args[0] + else: + l, b, w, h = args + self._x0 = l + self._y0 = b + self._width = w + self._height = h + self.stale = True + + def get_bbox(self): + """Return the `.Bbox`.""" + return transforms.Bbox.from_extents(*self._convert_units()) + + xy = property(get_xy, set_xy) + + +class RegularPolygon(Patch): + """A regular polygon patch.""" + + def __str__(self): + s = "RegularPolygon((%g, %g), %d, radius=%g, orientation=%g)" + return s % (self.xy[0], self.xy[1], self.numvertices, self.radius, + self.orientation) + + @_docstring.dedent_interpd + def __init__(self, xy, numVertices, *, + radius=5, orientation=0, **kwargs): + """ + Parameters + ---------- + xy : (float, float) + The center position. + + numVertices : int + The number of vertices. + + radius : float + The distance from the center to each of the vertices. + + orientation : float + The polygon rotation angle (in radians). + + **kwargs + `Patch` properties: + + %(Patch:kwdoc)s + """ + self.xy = xy + self.numvertices = numVertices + self.orientation = orientation + self.radius = radius + self._path = Path.unit_regular_polygon(numVertices) + self._patch_transform = transforms.Affine2D() + super().__init__(**kwargs) + + def get_path(self): + return self._path + + def get_patch_transform(self): + return self._patch_transform.clear() \ + .scale(self.radius) \ + .rotate(self.orientation) \ + .translate(*self.xy) + + +class PathPatch(Patch): + """A general polycurve path patch.""" + + _edge_default = True + + def __str__(self): + s = "PathPatch%d((%g, %g) ...)" + return s % (len(self._path.vertices), *tuple(self._path.vertices[0])) + + @_docstring.dedent_interpd + def __init__(self, path, **kwargs): + """ + *path* is a `.Path` object. + + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + self._path = path + + def get_path(self): + return self._path + + def set_path(self, path): + self._path = path + + +class StepPatch(PathPatch): + """ + A path patch describing a stepwise constant function. + + By default, the path is not closed and starts and stops at + baseline value. + """ + + _edge_default = False + + @_docstring.dedent_interpd + def __init__(self, values, edges, *, + orientation='vertical', baseline=0, **kwargs): + """ + Parameters + ---------- + values : array-like + The step heights. + + edges : array-like + The edge positions, with ``len(edges) == len(vals) + 1``, + between which the curve takes on vals values. + + orientation : {'vertical', 'horizontal'}, default: 'vertical' + The direction of the steps. Vertical means that *values* are + along the y-axis, and edges are along the x-axis. + + baseline : float, array-like or None, default: 0 + The bottom value of the bounding edges or when + ``fill=True``, position of lower edge. If *fill* is + True or an array is passed to *baseline*, a closed + path is drawn. + + **kwargs + `Patch` properties: + + %(Patch:kwdoc)s + """ + self.orientation = orientation + self._edges = np.asarray(edges) + self._values = np.asarray(values) + self._baseline = np.asarray(baseline) if baseline is not None else None + self._update_path() + super().__init__(self._path, **kwargs) + + def _update_path(self): + if np.isnan(np.sum(self._edges)): + raise ValueError('Nan values in "edges" are disallowed') + if self._edges.size - 1 != self._values.size: + raise ValueError('Size mismatch between "values" and "edges". ' + "Expected `len(values) + 1 == len(edges)`, but " + f"`len(values) = {self._values.size}` and " + f"`len(edges) = {self._edges.size}`.") + # Initializing with empty arrays allows supporting empty stairs. + verts, codes = [np.empty((0, 2))], [np.empty(0, dtype=Path.code_type)] + + _nan_mask = np.isnan(self._values) + if self._baseline is not None: + _nan_mask |= np.isnan(self._baseline) + for idx0, idx1 in cbook.contiguous_regions(~_nan_mask): + x = np.repeat(self._edges[idx0:idx1+1], 2) + y = np.repeat(self._values[idx0:idx1], 2) + if self._baseline is None: + y = np.concatenate([y[:1], y, y[-1:]]) + elif self._baseline.ndim == 0: # single baseline value + y = np.concatenate([[self._baseline], y, [self._baseline]]) + elif self._baseline.ndim == 1: # baseline array + base = np.repeat(self._baseline[idx0:idx1], 2)[::-1] + x = np.concatenate([x, x[::-1]]) + y = np.concatenate([base[-1:], y, base[:1], + base[:1], base, base[-1:]]) + else: # no baseline + raise ValueError('Invalid `baseline` specified') + if self.orientation == 'vertical': + xy = np.column_stack([x, y]) + else: + xy = np.column_stack([y, x]) + verts.append(xy) + codes.append([Path.MOVETO] + [Path.LINETO]*(len(xy)-1)) + self._path = Path(np.concatenate(verts), np.concatenate(codes)) + + def get_data(self): + """Get `.StepPatch` values, edges and baseline as namedtuple.""" + StairData = namedtuple('StairData', 'values edges baseline') + return StairData(self._values, self._edges, self._baseline) + + def set_data(self, values=None, edges=None, baseline=None): + """ + Set `.StepPatch` values, edges and baseline. + + Parameters + ---------- + values : 1D array-like or None + Will not update values, if passing None + edges : 1D array-like, optional + baseline : float, 1D array-like or None + """ + if values is None and edges is None and baseline is None: + raise ValueError("Must set *values*, *edges* or *baseline*.") + if values is not None: + self._values = np.asarray(values) + if edges is not None: + self._edges = np.asarray(edges) + if baseline is not None: + self._baseline = np.asarray(baseline) + self._update_path() + self.stale = True + + +class Polygon(Patch): + """A general polygon patch.""" + + def __str__(self): + if len(self._path.vertices): + s = "Polygon%d((%g, %g) ...)" + return s % (len(self._path.vertices), *self._path.vertices[0]) + else: + return "Polygon0()" + + @_docstring.dedent_interpd + def __init__(self, xy, *, closed=True, **kwargs): + """ + Parameters + ---------- + xy : (N, 2) array + + closed : bool, default: True + Whether the polygon is closed (i.e., has identical start and end + points). + + **kwargs + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + self._closed = closed + self.set_xy(xy) + + def get_path(self): + """Get the `.Path` of the polygon.""" + return self._path + + def get_closed(self): + """Return whether the polygon is closed.""" + return self._closed + + def set_closed(self, closed): + """ + Set whether the polygon is closed. + + Parameters + ---------- + closed : bool + True if the polygon is closed + """ + if self._closed == bool(closed): + return + self._closed = bool(closed) + self.set_xy(self.get_xy()) + self.stale = True + + def get_xy(self): + """ + Get the vertices of the path. + + Returns + ------- + (N, 2) array + The coordinates of the vertices. + """ + return self._path.vertices + + def set_xy(self, xy): + """ + Set the vertices of the polygon. + + Parameters + ---------- + xy : (N, 2) array-like + The coordinates of the vertices. + + Notes + ----- + Unlike `.Path`, we do not ignore the last input vertex. If the + polygon is meant to be closed, and the last point of the polygon is not + equal to the first, we assume that the user has not explicitly passed a + ``CLOSEPOLY`` vertex, and add it ourselves. + """ + xy = np.asarray(xy) + nverts, _ = xy.shape + if self._closed: + # if the first and last vertex are the "same", then we assume that + # the user explicitly passed the CLOSEPOLY vertex. Otherwise, we + # have to append one since the last vertex will be "ignored" by + # Path + if nverts == 1 or nverts > 1 and (xy[0] != xy[-1]).any(): + xy = np.concatenate([xy, [xy[0]]]) + else: + # if we aren't closed, and the last vertex matches the first, then + # we assume we have an unnecessary CLOSEPOLY vertex and remove it + if nverts > 2 and (xy[0] == xy[-1]).all(): + xy = xy[:-1] + self._path = Path(xy, closed=self._closed) + self.stale = True + + xy = property(get_xy, set_xy, + doc='The vertices of the path as a (N, 2) array.') + + +class Wedge(Patch): + """Wedge shaped patch.""" + + def __str__(self): + pars = (self.center[0], self.center[1], self.r, + self.theta1, self.theta2, self.width) + fmt = "Wedge(center=(%g, %g), r=%g, theta1=%g, theta2=%g, width=%s)" + return fmt % pars + + @_docstring.dedent_interpd + def __init__(self, center, r, theta1, theta2, *, width=None, **kwargs): + """ + A wedge centered at *x*, *y* center with radius *r* that + sweeps *theta1* to *theta2* (in degrees). If *width* is given, + then a partial wedge is drawn from inner radius *r* - *width* + to outer radius *r*. + + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + self.center = center + self.r, self.width = r, width + self.theta1, self.theta2 = theta1, theta2 + self._patch_transform = transforms.IdentityTransform() + self._recompute_path() + + def _recompute_path(self): + # Inner and outer rings are connected unless the annulus is complete + if abs((self.theta2 - self.theta1) - 360) <= 1e-12: + theta1, theta2 = 0, 360 + connector = Path.MOVETO + else: + theta1, theta2 = self.theta1, self.theta2 + connector = Path.LINETO + + # Form the outer ring + arc = Path.arc(theta1, theta2) + + if self.width is not None: + # Partial annulus needs to draw the outer ring + # followed by a reversed and scaled inner ring + v1 = arc.vertices + v2 = arc.vertices[::-1] * (self.r - self.width) / self.r + v = np.concatenate([v1, v2, [(0, 0)]]) + c = [*arc.codes, connector, *arc.codes[1:], Path.CLOSEPOLY] + else: + # Wedge doesn't need an inner ring + v = np.concatenate([arc.vertices, [(0, 0), (0, 0)]]) + c = [*arc.codes, connector, Path.CLOSEPOLY] + + # Shift and scale the wedge to the final location. + self._path = Path(v * self.r + self.center, c) + + def set_center(self, center): + self._path = None + self.center = center + self.stale = True + + def set_radius(self, radius): + self._path = None + self.r = radius + self.stale = True + + def set_theta1(self, theta1): + self._path = None + self.theta1 = theta1 + self.stale = True + + def set_theta2(self, theta2): + self._path = None + self.theta2 = theta2 + self.stale = True + + def set_width(self, width): + self._path = None + self.width = width + self.stale = True + + def get_path(self): + if self._path is None: + self._recompute_path() + return self._path + + +# COVERAGE NOTE: Not used internally or from examples +class Arrow(Patch): + """An arrow patch.""" + + def __str__(self): + return "Arrow()" + + _path = Path._create_closed([ + [0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], + [0.8, 0.3], [0.8, 0.1]]) + + @_docstring.dedent_interpd + def __init__(self, x, y, dx, dy, *, width=1.0, **kwargs): + """ + Draws an arrow from (*x*, *y*) to (*x* + *dx*, *y* + *dy*). + The width of the arrow is scaled by *width*. + + Parameters + ---------- + x : float + x coordinate of the arrow tail. + y : float + y coordinate of the arrow tail. + dx : float + Arrow length in the x direction. + dy : float + Arrow length in the y direction. + width : float, default: 1 + Scale factor for the width of the arrow. With a default value of 1, + the tail width is 0.2 and head width is 0.6. + **kwargs + Keyword arguments control the `Patch` properties: + + %(Patch:kwdoc)s + + See Also + -------- + FancyArrow + Patch that allows independent control of the head and tail + properties. + """ + super().__init__(**kwargs) + self._patch_transform = ( + transforms.Affine2D() + .scale(np.hypot(dx, dy), width) + .rotate(np.arctan2(dy, dx)) + .translate(x, y) + .frozen()) + + def get_path(self): + return self._path + + def get_patch_transform(self): + return self._patch_transform + + +class FancyArrow(Polygon): + """ + Like Arrow, but lets you set head width and head height independently. + """ + + _edge_default = True + + def __str__(self): + return "FancyArrow()" + + @_docstring.dedent_interpd + def __init__(self, x, y, dx, dy, *, + width=0.001, length_includes_head=False, head_width=None, + head_length=None, shape='full', overhang=0, + head_starts_at_zero=False, **kwargs): + """ + Parameters + ---------- + x, y : float + The x and y coordinates of the arrow base. + + dx, dy : float + The length of the arrow along x and y direction. + + width : float, default: 0.001 + Width of full arrow tail. + + length_includes_head : bool, default: False + True if head is to be counted in calculating the length. + + head_width : float or None, default: 3*width + Total width of the full arrow head. + + head_length : float or None, default: 1.5*head_width + Length of arrow head. + + shape : {'full', 'left', 'right'}, default: 'full' + Draw the left-half, right-half, or full arrow. + + overhang : float, default: 0 + Fraction that the arrow is swept back (0 overhang means + triangular shape). Can be negative or greater than one. + + head_starts_at_zero : bool, default: False + If True, the head starts being drawn at coordinate 0 + instead of ending at coordinate 0. + + **kwargs + `.Patch` properties: + + %(Patch:kwdoc)s + """ + self._x = x + self._y = y + self._dx = dx + self._dy = dy + self._width = width + self._length_includes_head = length_includes_head + self._head_width = head_width + self._head_length = head_length + self._shape = shape + self._overhang = overhang + self._head_starts_at_zero = head_starts_at_zero + self._make_verts() + super().__init__(self.verts, closed=True, **kwargs) + + def set_data(self, *, x=None, y=None, dx=None, dy=None, width=None, + head_width=None, head_length=None): + """ + Set `.FancyArrow` x, y, dx, dy, width, head_with, and head_length. + Values left as None will not be updated. + + Parameters + ---------- + x, y : float or None, default: None + The x and y coordinates of the arrow base. + + dx, dy : float or None, default: None + The length of the arrow along x and y direction. + + width : float or None, default: None + Width of full arrow tail. + + head_width : float or None, default: None + Total width of the full arrow head. + + head_length : float or None, default: None + Length of arrow head. + """ + if x is not None: + self._x = x + if y is not None: + self._y = y + if dx is not None: + self._dx = dx + if dy is not None: + self._dy = dy + if width is not None: + self._width = width + if head_width is not None: + self._head_width = head_width + if head_length is not None: + self._head_length = head_length + self._make_verts() + self.set_xy(self.verts) + + def _make_verts(self): + if self._head_width is None: + head_width = 3 * self._width + else: + head_width = self._head_width + if self._head_length is None: + head_length = 1.5 * head_width + else: + head_length = self._head_length + + distance = np.hypot(self._dx, self._dy) + + if self._length_includes_head: + length = distance + else: + length = distance + head_length + if not length: + self.verts = np.empty([0, 2]) # display nothing if empty + else: + # start by drawing horizontal arrow, point at (0, 0) + hw, hl = head_width, head_length + hs, lw = self._overhang, self._width + left_half_arrow = np.array([ + [0.0, 0.0], # tip + [-hl, -hw / 2], # leftmost + [-hl * (1 - hs), -lw / 2], # meets stem + [-length, -lw / 2], # bottom left + [-length, 0], + ]) + # if we're not including the head, shift up by head length + if not self._length_includes_head: + left_half_arrow += [head_length, 0] + # if the head starts at 0, shift up by another head length + if self._head_starts_at_zero: + left_half_arrow += [head_length / 2, 0] + # figure out the shape, and complete accordingly + if self._shape == 'left': + coords = left_half_arrow + else: + right_half_arrow = left_half_arrow * [1, -1] + if self._shape == 'right': + coords = right_half_arrow + elif self._shape == 'full': + # The half-arrows contain the midpoint of the stem, + # which we can omit from the full arrow. Including it + # twice caused a problem with xpdf. + coords = np.concatenate([left_half_arrow[:-1], + right_half_arrow[-2::-1]]) + else: + raise ValueError(f"Got unknown shape: {self._shape!r}") + if distance != 0: + cx = self._dx / distance + sx = self._dy / distance + else: + # Account for division by zero + cx, sx = 0, 1 + M = [[cx, sx], [-sx, cx]] + self.verts = np.dot(coords, M) + [ + self._x + self._dx, + self._y + self._dy, + ] + + +_docstring.interpd.update( + FancyArrow="\n".join( + (inspect.getdoc(FancyArrow.__init__) or "").splitlines()[2:])) + + +class CirclePolygon(RegularPolygon): + """A polygon-approximation of a circle patch.""" + + def __str__(self): + s = "CirclePolygon((%g, %g), radius=%g, resolution=%d)" + return s % (self.xy[0], self.xy[1], self.radius, self.numvertices) + + @_docstring.dedent_interpd + def __init__(self, xy, radius=5, *, + resolution=20, # the number of vertices + ** kwargs): + """ + Create a circle at *xy* = (*x*, *y*) with given *radius*. + + This circle is approximated by a regular polygon with *resolution* + sides. For a smoother circle drawn with splines, see `Circle`. + + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__( + xy, resolution, radius=radius, orientation=0, **kwargs) + + +class Ellipse(Patch): + """A scale-free ellipse.""" + + def __str__(self): + pars = (self._center[0], self._center[1], + self.width, self.height, self.angle) + fmt = "Ellipse(xy=(%s, %s), width=%s, height=%s, angle=%s)" + return fmt % pars + + @_docstring.dedent_interpd + def __init__(self, xy, width, height, *, angle=0, **kwargs): + """ + Parameters + ---------- + xy : (float, float) + xy coordinates of ellipse centre. + width : float + Total length (diameter) of horizontal axis. + height : float + Total length (diameter) of vertical axis. + angle : float, default: 0 + Rotation in degrees anti-clockwise. + + Notes + ----- + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + + self._center = xy + self._width, self._height = width, height + self._angle = angle + self._path = Path.unit_circle() + # Required for EllipseSelector with axes aspect ratio != 1 + # The patch is defined in data coordinates and when changing the + # selector with square modifier and not in data coordinates, we need + # to correct for the aspect ratio difference between the data and + # display coordinate systems. + self._aspect_ratio_correction = 1.0 + # Note: This cannot be calculated until this is added to an Axes + self._patch_transform = transforms.IdentityTransform() + + def _recompute_transform(self): + """ + Notes + ----- + This cannot be called until after this has been added to an Axes, + otherwise unit conversion will fail. This makes it very important to + call the accessor method and not directly access the transformation + member variable. + """ + center = (self.convert_xunits(self._center[0]), + self.convert_yunits(self._center[1])) + width = self.convert_xunits(self._width) + height = self.convert_yunits(self._height) + self._patch_transform = transforms.Affine2D() \ + .scale(width * 0.5, height * 0.5 * self._aspect_ratio_correction) \ + .rotate_deg(self.angle) \ + .scale(1, 1 / self._aspect_ratio_correction) \ + .translate(*center) + + def get_path(self): + """Return the path of the ellipse.""" + return self._path + + def get_patch_transform(self): + self._recompute_transform() + return self._patch_transform + + def set_center(self, xy): + """ + Set the center of the ellipse. + + Parameters + ---------- + xy : (float, float) + """ + self._center = xy + self.stale = True + + def get_center(self): + """Return the center of the ellipse.""" + return self._center + + center = property(get_center, set_center) + + def set_width(self, width): + """ + Set the width of the ellipse. + + Parameters + ---------- + width : float + """ + self._width = width + self.stale = True + + def get_width(self): + """ + Return the width of the ellipse. + """ + return self._width + + width = property(get_width, set_width) + + def set_height(self, height): + """ + Set the height of the ellipse. + + Parameters + ---------- + height : float + """ + self._height = height + self.stale = True + + def get_height(self): + """Return the height of the ellipse.""" + return self._height + + height = property(get_height, set_height) + + def set_angle(self, angle): + """ + Set the angle of the ellipse. + + Parameters + ---------- + angle : float + """ + self._angle = angle + self.stale = True + + def get_angle(self): + """Return the angle of the ellipse.""" + return self._angle + + angle = property(get_angle, set_angle) + + def get_corners(self): + """ + Return the corners of the ellipse bounding box. + + The bounding box orientation is moving anti-clockwise from the + lower left corner defined before rotation. + """ + return self.get_patch_transform().transform( + [(-1, -1), (1, -1), (1, 1), (-1, 1)]) + + def get_vertices(self): + """ + Return the vertices coordinates of the ellipse. + + The definition can be found `here <https://en.wikipedia.org/wiki/Ellipse>`_ + + .. versionadded:: 3.8 + """ + if self.width < self.height: + ret = self.get_patch_transform().transform([(0, 1), (0, -1)]) + else: + ret = self.get_patch_transform().transform([(1, 0), (-1, 0)]) + return [tuple(x) for x in ret] + + def get_co_vertices(self): + """ + Return the co-vertices coordinates of the ellipse. + + The definition can be found `here <https://en.wikipedia.org/wiki/Ellipse>`_ + + .. versionadded:: 3.8 + """ + if self.width < self.height: + ret = self.get_patch_transform().transform([(1, 0), (-1, 0)]) + else: + ret = self.get_patch_transform().transform([(0, 1), (0, -1)]) + return [tuple(x) for x in ret] + + +class Annulus(Patch): + """ + An elliptical annulus. + """ + + @_docstring.dedent_interpd + def __init__(self, xy, r, width, angle=0.0, **kwargs): + """ + Parameters + ---------- + xy : (float, float) + xy coordinates of annulus centre. + r : float or (float, float) + The radius, or semi-axes: + + - If float: radius of the outer circle. + - If two floats: semi-major and -minor axes of outer ellipse. + width : float + Width (thickness) of the annular ring. The width is measured inward + from the outer ellipse so that for the inner ellipse the semi-axes + are given by ``r - width``. *width* must be less than or equal to + the semi-minor axis. + angle : float, default: 0 + Rotation angle in degrees (anti-clockwise from the positive + x-axis). Ignored for circular annuli (i.e., if *r* is a scalar). + **kwargs + Keyword arguments control the `Patch` properties: + + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + + self.set_radii(r) + self.center = xy + self.width = width + self.angle = angle + self._path = None + + def __str__(self): + if self.a == self.b: + r = self.a + else: + r = (self.a, self.b) + + return "Annulus(xy=(%s, %s), r=%s, width=%s, angle=%s)" % \ + (*self.center, r, self.width, self.angle) + + def set_center(self, xy): + """ + Set the center of the annulus. + + Parameters + ---------- + xy : (float, float) + """ + self._center = xy + self._path = None + self.stale = True + + def get_center(self): + """Return the center of the annulus.""" + return self._center + + center = property(get_center, set_center) + + def set_width(self, width): + """ + Set the width (thickness) of the annulus ring. + + The width is measured inwards from the outer ellipse. + + Parameters + ---------- + width : float + """ + if min(self.a, self.b) <= width: + raise ValueError( + 'Width of annulus must be less than or equal semi-minor axis') + + self._width = width + self._path = None + self.stale = True + + def get_width(self): + """Return the width (thickness) of the annulus ring.""" + return self._width + + width = property(get_width, set_width) + + def set_angle(self, angle): + """ + Set the tilt angle of the annulus. + + Parameters + ---------- + angle : float + """ + self._angle = angle + self._path = None + self.stale = True + + def get_angle(self): + """Return the angle of the annulus.""" + return self._angle + + angle = property(get_angle, set_angle) + + def set_semimajor(self, a): + """ + Set the semi-major axis *a* of the annulus. + + Parameters + ---------- + a : float + """ + self.a = float(a) + self._path = None + self.stale = True + + def set_semiminor(self, b): + """ + Set the semi-minor axis *b* of the annulus. + + Parameters + ---------- + b : float + """ + self.b = float(b) + self._path = None + self.stale = True + + def set_radii(self, r): + """ + Set the semi-major (*a*) and semi-minor radii (*b*) of the annulus. + + Parameters + ---------- + r : float or (float, float) + The radius, or semi-axes: + + - If float: radius of the outer circle. + - If two floats: semi-major and -minor axes of outer ellipse. + """ + if np.shape(r) == (2,): + self.a, self.b = r + elif np.shape(r) == (): + self.a = self.b = float(r) + else: + raise ValueError("Parameter 'r' must be one or two floats.") + + self._path = None + self.stale = True + + def get_radii(self): + """Return the semi-major and semi-minor radii of the annulus.""" + return self.a, self.b + + radii = property(get_radii, set_radii) + + def _transform_verts(self, verts, a, b): + return transforms.Affine2D() \ + .scale(*self._convert_xy_units((a, b))) \ + .rotate_deg(self.angle) \ + .translate(*self._convert_xy_units(self.center)) \ + .transform(verts) + + def _recompute_path(self): + # circular arc + arc = Path.arc(0, 360) + + # annulus needs to draw an outer ring + # followed by a reversed and scaled inner ring + a, b, w = self.a, self.b, self.width + v1 = self._transform_verts(arc.vertices, a, b) + v2 = self._transform_verts(arc.vertices[::-1], a - w, b - w) + v = np.vstack([v1, v2, v1[0, :], (0, 0)]) + c = np.hstack([arc.codes, Path.MOVETO, + arc.codes[1:], Path.MOVETO, + Path.CLOSEPOLY]) + self._path = Path(v, c) + + def get_path(self): + if self._path is None: + self._recompute_path() + return self._path + + +class Circle(Ellipse): + """ + A circle patch. + """ + def __str__(self): + pars = self.center[0], self.center[1], self.radius + fmt = "Circle(xy=(%g, %g), radius=%g)" + return fmt % pars + + @_docstring.dedent_interpd + def __init__(self, xy, radius=5, **kwargs): + """ + Create a true circle at center *xy* = (*x*, *y*) with given *radius*. + + Unlike `CirclePolygon` which is a polygonal approximation, this uses + Bezier splines and is much closer to a scale-free circle. + + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__(xy, radius * 2, radius * 2, **kwargs) + self.radius = radius + + def set_radius(self, radius): + """ + Set the radius of the circle. + + Parameters + ---------- + radius : float + """ + self.width = self.height = 2 * radius + self.stale = True + + def get_radius(self): + """Return the radius of the circle.""" + return self.width / 2. + + radius = property(get_radius, set_radius) + + +class Arc(Ellipse): + """ + An elliptical arc, i.e. a segment of an ellipse. + + Due to internal optimizations, the arc cannot be filled. + """ + + def __str__(self): + pars = (self.center[0], self.center[1], self.width, + self.height, self.angle, self.theta1, self.theta2) + fmt = ("Arc(xy=(%g, %g), width=%g, " + "height=%g, angle=%g, theta1=%g, theta2=%g)") + return fmt % pars + + @_docstring.dedent_interpd + def __init__(self, xy, width, height, *, + angle=0.0, theta1=0.0, theta2=360.0, **kwargs): + """ + Parameters + ---------- + xy : (float, float) + The center of the ellipse. + + width : float + The length of the horizontal axis. + + height : float + The length of the vertical axis. + + angle : float + Rotation of the ellipse in degrees (counterclockwise). + + theta1, theta2 : float, default: 0, 360 + Starting and ending angles of the arc in degrees. These values + are relative to *angle*, e.g. if *angle* = 45 and *theta1* = 90 + the absolute starting angle is 135. + Default *theta1* = 0, *theta2* = 360, i.e. a complete ellipse. + The arc is drawn in the counterclockwise direction. + Angles greater than or equal to 360, or smaller than 0, are + represented by an equivalent angle in the range [0, 360), by + taking the input value mod 360. + + Other Parameters + ---------------- + **kwargs : `~matplotlib.patches.Patch` properties + Most `.Patch` properties are supported as keyword arguments, + except *fill* and *facecolor* because filling is not supported. + + %(Patch:kwdoc)s + """ + fill = kwargs.setdefault('fill', False) + if fill: + raise ValueError("Arc objects cannot be filled") + + super().__init__(xy, width, height, angle=angle, **kwargs) + + self.theta1 = theta1 + self.theta2 = theta2 + (self._theta1, self._theta2, self._stretched_width, + self._stretched_height) = self._theta_stretch() + self._path = Path.arc(self._theta1, self._theta2) + + @artist.allow_rasterization + def draw(self, renderer): + """ + Draw the arc to the given *renderer*. + + Notes + ----- + Ellipses are normally drawn using an approximation that uses + eight cubic Bezier splines. The error of this approximation + is 1.89818e-6, according to this unverified source: + + Lancaster, Don. *Approximating a Circle or an Ellipse Using + Four Bezier Cubic Splines.* + + https://www.tinaja.com/glib/ellipse4.pdf + + There is a use case where very large ellipses must be drawn + with very high accuracy, and it is too expensive to render the + entire ellipse with enough segments (either splines or line + segments). Therefore, in the case where either radius of the + ellipse is large enough that the error of the spline + approximation will be visible (greater than one pixel offset + from the ideal), a different technique is used. + + In that case, only the visible parts of the ellipse are drawn, + with each visible arc using a fixed number of spline segments + (8). The algorithm proceeds as follows: + + 1. The points where the ellipse intersects the axes (or figure) + bounding box are located. (This is done by performing an inverse + transformation on the bbox such that it is relative to the unit + circle -- this makes the intersection calculation much easier than + doing rotated ellipse intersection directly.) + + This uses the "line intersecting a circle" algorithm from: + + Vince, John. *Geometry for Computer Graphics: Formulae, + Examples & Proofs.* London: Springer-Verlag, 2005. + + 2. The angles of each of the intersection points are calculated. + + 3. Proceeding counterclockwise starting in the positive + x-direction, each of the visible arc-segments between the + pairs of vertices are drawn using the Bezier arc + approximation technique implemented in `.Path.arc`. + """ + if not self.get_visible(): + return + + self._recompute_transform() + + self._update_path() + # Get width and height in pixels we need to use + # `self.get_data_transform` rather than `self.get_transform` + # because we want the transform from dataspace to the + # screen space to estimate how big the arc will be in physical + # units when rendered (the transform that we get via + # `self.get_transform()` goes from an idealized unit-radius + # space to screen space). + data_to_screen_trans = self.get_data_transform() + pwidth, pheight = ( + data_to_screen_trans.transform((self._stretched_width, + self._stretched_height)) - + data_to_screen_trans.transform((0, 0))) + inv_error = (1.0 / 1.89818e-6) * 0.5 + + if pwidth < inv_error and pheight < inv_error: + return Patch.draw(self, renderer) + + def line_circle_intersect(x0, y0, x1, y1): + dx = x1 - x0 + dy = y1 - y0 + dr2 = dx * dx + dy * dy + D = x0 * y1 - x1 * y0 + D2 = D * D + discrim = dr2 - D2 + if discrim >= 0.0: + sign_dy = np.copysign(1, dy) # +/-1, never 0. + sqrt_discrim = np.sqrt(discrim) + return np.array( + [[(D * dy + sign_dy * dx * sqrt_discrim) / dr2, + (-D * dx + abs(dy) * sqrt_discrim) / dr2], + [(D * dy - sign_dy * dx * sqrt_discrim) / dr2, + (-D * dx - abs(dy) * sqrt_discrim) / dr2]]) + else: + return np.empty((0, 2)) + + def segment_circle_intersect(x0, y0, x1, y1): + epsilon = 1e-9 + if x1 < x0: + x0e, x1e = x1, x0 + else: + x0e, x1e = x0, x1 + if y1 < y0: + y0e, y1e = y1, y0 + else: + y0e, y1e = y0, y1 + xys = line_circle_intersect(x0, y0, x1, y1) + xs, ys = xys.T + return xys[ + (x0e - epsilon < xs) & (xs < x1e + epsilon) + & (y0e - epsilon < ys) & (ys < y1e + epsilon) + ] + + # Transform the axes (or figure) box_path so that it is relative to + # the unit circle in the same way that it is relative to the desired + # ellipse. + box_path_transform = ( + transforms.BboxTransformTo((self.axes or self.figure).bbox) + - self.get_transform()) + box_path = Path.unit_rectangle().transformed(box_path_transform) + + thetas = set() + # For each of the point pairs, there is a line segment + for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]): + xy = segment_circle_intersect(*p0, *p1) + x, y = xy.T + # arctan2 return [-pi, pi), the rest of our angles are in + # [0, 360], adjust as needed. + theta = (np.rad2deg(np.arctan2(y, x)) + 360) % 360 + thetas.update( + theta[(self._theta1 < theta) & (theta < self._theta2)]) + thetas = sorted(thetas) + [self._theta2] + last_theta = self._theta1 + theta1_rad = np.deg2rad(self._theta1) + inside = box_path.contains_point( + (np.cos(theta1_rad), np.sin(theta1_rad)) + ) + + # save original path + path_original = self._path + for theta in thetas: + if inside: + self._path = Path.arc(last_theta, theta, 8) + Patch.draw(self, renderer) + inside = False + else: + inside = True + last_theta = theta + + # restore original path + self._path = path_original + + def _update_path(self): + # Compute new values and update and set new _path if any value changed + stretched = self._theta_stretch() + if any(a != b for a, b in zip( + stretched, (self._theta1, self._theta2, self._stretched_width, + self._stretched_height))): + (self._theta1, self._theta2, self._stretched_width, + self._stretched_height) = stretched + self._path = Path.arc(self._theta1, self._theta2) + + def _theta_stretch(self): + # If the width and height of ellipse are not equal, take into account + # stretching when calculating angles to draw between + def theta_stretch(theta, scale): + theta = np.deg2rad(theta) + x = np.cos(theta) + y = np.sin(theta) + stheta = np.rad2deg(np.arctan2(scale * y, x)) + # arctan2 has the range [-pi, pi], we expect [0, 2*pi] + return (stheta + 360) % 360 + + width = self.convert_xunits(self.width) + height = self.convert_yunits(self.height) + if ( + # if we need to stretch the angles because we are distorted + width != height + # and we are not doing a full circle. + # + # 0 and 360 do not exactly round-trip through the angle + # stretching (due to both float precision limitations and + # the difference between the range of arctan2 [-pi, pi] and + # this method [0, 360]) so avoid doing it if we don't have to. + and not (self.theta1 != self.theta2 and + self.theta1 % 360 == self.theta2 % 360) + ): + theta1 = theta_stretch(self.theta1, width / height) + theta2 = theta_stretch(self.theta2, width / height) + return theta1, theta2, width, height + return self.theta1, self.theta2, width, height + + +def bbox_artist(artist, renderer, props=None, fill=True): + """ + A debug function to draw a rectangle around the bounding + box returned by an artist's `.Artist.get_window_extent` + to test whether the artist is returning the correct bbox. + + *props* is a dict of rectangle props with the additional property + 'pad' that sets the padding around the bbox in points. + """ + if props is None: + props = {} + props = props.copy() # don't want to alter the pad externally + pad = props.pop('pad', 4) + pad = renderer.points_to_pixels(pad) + bbox = artist.get_window_extent(renderer) + r = Rectangle( + xy=(bbox.x0 - pad / 2, bbox.y0 - pad / 2), + width=bbox.width + pad, height=bbox.height + pad, + fill=fill, transform=transforms.IdentityTransform(), clip_on=False) + r.update(props) + r.draw(renderer) + + +def draw_bbox(bbox, renderer, color='k', trans=None): + """ + A debug function to draw a rectangle around the bounding + box returned by an artist's `.Artist.get_window_extent` + to test whether the artist is returning the correct bbox. + """ + r = Rectangle(xy=bbox.p0, width=bbox.width, height=bbox.height, + edgecolor=color, fill=False, clip_on=False) + if trans is not None: + r.set_transform(trans) + r.draw(renderer) + + +class _Style: + """ + A base class for the Styles. It is meant to be a container class, + where actual styles are declared as subclass of it, and it + provides some helper functions. + """ + + def __init_subclass__(cls): + # Automatically perform docstring interpolation on the subclasses: + # This allows listing the supported styles via + # - %(BoxStyle:table)s + # - %(ConnectionStyle:table)s + # - %(ArrowStyle:table)s + # and additionally adding .. ACCEPTS: blocks via + # - %(BoxStyle:table_and_accepts)s + # - %(ConnectionStyle:table_and_accepts)s + # - %(ArrowStyle:table_and_accepts)s + _docstring.interpd.update({ + f"{cls.__name__}:table": cls.pprint_styles(), + f"{cls.__name__}:table_and_accepts": ( + cls.pprint_styles() + + "\n\n .. ACCEPTS: [" + + "|".join(map(" '{}' ".format, cls._style_list)) + + "]") + }) + + def __new__(cls, stylename, **kwargs): + """Return the instance of the subclass with the given style name.""" + # The "class" should have the _style_list attribute, which is a mapping + # of style names to style classes. + _list = stylename.replace(" ", "").split(",") + _name = _list[0].lower() + try: + _cls = cls._style_list[_name] + except KeyError as err: + raise ValueError(f"Unknown style: {stylename!r}") from err + try: + _args_pair = [cs.split("=") for cs in _list[1:]] + _args = {k: float(v) for k, v in _args_pair} + except ValueError as err: + raise ValueError( + f"Incorrect style argument: {stylename!r}") from err + return _cls(**{**_args, **kwargs}) + + @classmethod + def get_styles(cls): + """Return a dictionary of available styles.""" + return cls._style_list + + @classmethod + def pprint_styles(cls): + """Return the available styles as pretty-printed string.""" + table = [('Class', 'Name', 'Attrs'), + *[(cls.__name__, + # Add backquotes, as - and | have special meaning in reST. + f'``{name}``', + # [1:-1] drops the surrounding parentheses. + str(inspect.signature(cls))[1:-1] or 'None') + for name, cls in cls._style_list.items()]] + # Convert to rst table. + col_len = [max(len(cell) for cell in column) for column in zip(*table)] + table_formatstr = ' '.join('=' * cl for cl in col_len) + rst_table = '\n'.join([ + '', + table_formatstr, + ' '.join(cell.ljust(cl) for cell, cl in zip(table[0], col_len)), + table_formatstr, + *[' '.join(cell.ljust(cl) for cell, cl in zip(row, col_len)) + for row in table[1:]], + table_formatstr, + ]) + return textwrap.indent(rst_table, prefix=' ' * 4) + + @classmethod + def register(cls, name, style): + """Register a new style.""" + if not issubclass(style, cls._Base): + raise ValueError(f"{style} must be a subclass of {cls._Base}") + cls._style_list[name] = style + + +def _register_style(style_list, cls=None, *, name=None): + """Class decorator that stashes a class in a (style) dictionary.""" + if cls is None: + return functools.partial(_register_style, style_list, name=name) + style_list[name or cls.__name__.lower()] = cls + return cls + + +@_docstring.dedent_interpd +class BoxStyle(_Style): + """ + `BoxStyle` is a container class which defines several + boxstyle classes, which are used for `FancyBboxPatch`. + + A style object can be created as:: + + BoxStyle.Round(pad=0.2) + + or:: + + BoxStyle("Round", pad=0.2) + + or:: + + BoxStyle("Round, pad=0.2") + + The following boxstyle classes are defined. + + %(BoxStyle:table)s + + An instance of a boxstyle class is a callable object, with the signature :: + + __call__(self, x0, y0, width, height, mutation_size) -> Path + + *x0*, *y0*, *width* and *height* specify the location and size of the box + to be drawn; *mutation_size* scales the outline properties such as padding. + """ + + _style_list = {} + + @_register_style(_style_list) + class Square: + """A square box.""" + + def __init__(self, pad=0.3): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + """ + self.pad = pad + + def __call__(self, x0, y0, width, height, mutation_size): + pad = mutation_size * self.pad + # width and height with padding added. + width, height = width + 2 * pad, height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad + x1, y1 = x0 + width, y0 + height + return Path._create_closed( + [(x0, y0), (x1, y0), (x1, y1), (x0, y1)]) + + @_register_style(_style_list) + class Circle: + """A circular box.""" + + def __init__(self, pad=0.3): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + """ + self.pad = pad + + def __call__(self, x0, y0, width, height, mutation_size): + pad = mutation_size * self.pad + width, height = width + 2 * pad, height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad + return Path.circle((x0 + width / 2, y0 + height / 2), + max(width, height) / 2) + + @_register_style(_style_list) + class Ellipse: + """ + An elliptical box. + + .. versionadded:: 3.7 + """ + + def __init__(self, pad=0.3): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + """ + self.pad = pad + + def __call__(self, x0, y0, width, height, mutation_size): + pad = mutation_size * self.pad + width, height = width + 2 * pad, height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad + a = width / math.sqrt(2) + b = height / math.sqrt(2) + trans = Affine2D().scale(a, b).translate(x0 + width / 2, + y0 + height / 2) + return trans.transform_path(Path.unit_circle()) + + @_register_style(_style_list) + class LArrow: + """A box in the shape of a left-pointing arrow.""" + + def __init__(self, pad=0.3): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + """ + self.pad = pad + + def __call__(self, x0, y0, width, height, mutation_size): + # padding + pad = mutation_size * self.pad + # width and height with padding added. + width, height = width + 2 * pad, height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad, + x1, y1 = x0 + width, y0 + height + + dx = (y1 - y0) / 2 + dxx = dx / 2 + x0 = x0 + pad / 1.4 # adjust by ~sqrt(2) + + return Path._create_closed( + [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1), + (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx), + (x0 + dxx, y0 - dxx), # arrow + (x0 + dxx, y0)]) + + @_register_style(_style_list) + class RArrow(LArrow): + """A box in the shape of a right-pointing arrow.""" + + def __call__(self, x0, y0, width, height, mutation_size): + p = BoxStyle.LArrow.__call__( + self, x0, y0, width, height, mutation_size) + p.vertices[:, 0] = 2 * x0 + width - p.vertices[:, 0] + return p + + @_register_style(_style_list) + class DArrow: + """A box in the shape of a two-way arrow.""" + # Modified from LArrow to add a right arrow to the bbox. + + def __init__(self, pad=0.3): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + """ + self.pad = pad + + def __call__(self, x0, y0, width, height, mutation_size): + # padding + pad = mutation_size * self.pad + # width and height with padding added. + # The width is padded by the arrows, so we don't need to pad it. + height = height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad + x1, y1 = x0 + width, y0 + height + + dx = (y1 - y0) / 2 + dxx = dx / 2 + x0 = x0 + pad / 1.4 # adjust by ~sqrt(2) + + return Path._create_closed([ + (x0 + dxx, y0), (x1, y0), # bot-segment + (x1, y0 - dxx), (x1 + dx + dxx, y0 + dx), + (x1, y1 + dxx), # right-arrow + (x1, y1), (x0 + dxx, y1), # top-segment + (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx), + (x0 + dxx, y0 - dxx), # left-arrow + (x0 + dxx, y0)]) + + @_register_style(_style_list) + class Round: + """A box with round corners.""" + + def __init__(self, pad=0.3, rounding_size=None): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + rounding_size : float, default: *pad* + Radius of the corners. + """ + self.pad = pad + self.rounding_size = rounding_size + + def __call__(self, x0, y0, width, height, mutation_size): + + # padding + pad = mutation_size * self.pad + + # size of the rounding corner + if self.rounding_size: + dr = mutation_size * self.rounding_size + else: + dr = pad + + width, height = width + 2 * pad, height + 2 * pad + + x0, y0 = x0 - pad, y0 - pad, + x1, y1 = x0 + width, y0 + height + + # Round corners are implemented as quadratic Bezier, e.g., + # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner. + cp = [(x0 + dr, y0), + (x1 - dr, y0), + (x1, y0), (x1, y0 + dr), + (x1, y1 - dr), + (x1, y1), (x1 - dr, y1), + (x0 + dr, y1), + (x0, y1), (x0, y1 - dr), + (x0, y0 + dr), + (x0, y0), (x0 + dr, y0), + (x0 + dr, y0)] + + com = [Path.MOVETO, + Path.LINETO, + Path.CURVE3, Path.CURVE3, + Path.LINETO, + Path.CURVE3, Path.CURVE3, + Path.LINETO, + Path.CURVE3, Path.CURVE3, + Path.LINETO, + Path.CURVE3, Path.CURVE3, + Path.CLOSEPOLY] + + return Path(cp, com) + + @_register_style(_style_list) + class Round4: + """A box with rounded edges.""" + + def __init__(self, pad=0.3, rounding_size=None): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + rounding_size : float, default: *pad*/2 + Rounding of edges. + """ + self.pad = pad + self.rounding_size = rounding_size + + def __call__(self, x0, y0, width, height, mutation_size): + + # padding + pad = mutation_size * self.pad + + # Rounding size; defaults to half of the padding. + if self.rounding_size: + dr = mutation_size * self.rounding_size + else: + dr = pad / 2. + + width = width + 2 * pad - 2 * dr + height = height + 2 * pad - 2 * dr + + x0, y0 = x0 - pad + dr, y0 - pad + dr, + x1, y1 = x0 + width, y0 + height + + cp = [(x0, y0), + (x0 + dr, y0 - dr), (x1 - dr, y0 - dr), (x1, y0), + (x1 + dr, y0 + dr), (x1 + dr, y1 - dr), (x1, y1), + (x1 - dr, y1 + dr), (x0 + dr, y1 + dr), (x0, y1), + (x0 - dr, y1 - dr), (x0 - dr, y0 + dr), (x0, y0), + (x0, y0)] + + com = [Path.MOVETO, + Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.CLOSEPOLY] + + return Path(cp, com) + + @_register_style(_style_list) + class Sawtooth: + """A box with a sawtooth outline.""" + + def __init__(self, pad=0.3, tooth_size=None): + """ + Parameters + ---------- + pad : float, default: 0.3 + The amount of padding around the original box. + tooth_size : float, default: *pad*/2 + Size of the sawtooth. + """ + self.pad = pad + self.tooth_size = tooth_size + + def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size): + + # padding + pad = mutation_size * self.pad + + # size of sawtooth + if self.tooth_size is None: + tooth_size = self.pad * .5 * mutation_size + else: + tooth_size = self.tooth_size * mutation_size + + hsz = tooth_size / 2 + width = width + 2 * pad - tooth_size + height = height + 2 * pad - tooth_size + + # the sizes of the vertical and horizontal sawtooth are + # separately adjusted to fit the given box size. + dsx_n = round((width - tooth_size) / (tooth_size * 2)) * 2 + dsy_n = round((height - tooth_size) / (tooth_size * 2)) * 2 + + x0, y0 = x0 - pad + hsz, y0 - pad + hsz + x1, y1 = x0 + width, y0 + height + + xs = [ + x0, *np.linspace(x0 + hsz, x1 - hsz, 2 * dsx_n + 1), # bottom + *([x1, x1 + hsz, x1, x1 - hsz] * dsy_n)[:2*dsy_n+2], # right + x1, *np.linspace(x1 - hsz, x0 + hsz, 2 * dsx_n + 1), # top + *([x0, x0 - hsz, x0, x0 + hsz] * dsy_n)[:2*dsy_n+2], # left + ] + ys = [ + *([y0, y0 - hsz, y0, y0 + hsz] * dsx_n)[:2*dsx_n+2], # bottom + y0, *np.linspace(y0 + hsz, y1 - hsz, 2 * dsy_n + 1), # right + *([y1, y1 + hsz, y1, y1 - hsz] * dsx_n)[:2*dsx_n+2], # top + y1, *np.linspace(y1 - hsz, y0 + hsz, 2 * dsy_n + 1), # left + ] + + return [*zip(xs, ys), (xs[0], ys[0])] + + def __call__(self, x0, y0, width, height, mutation_size): + saw_vertices = self._get_sawtooth_vertices(x0, y0, width, + height, mutation_size) + return Path(saw_vertices, closed=True) + + @_register_style(_style_list) + class Roundtooth(Sawtooth): + """A box with a rounded sawtooth outline.""" + + def __call__(self, x0, y0, width, height, mutation_size): + saw_vertices = self._get_sawtooth_vertices(x0, y0, + width, height, + mutation_size) + # Add a trailing vertex to allow us to close the polygon correctly + saw_vertices = np.concatenate([saw_vertices, [saw_vertices[0]]]) + codes = ([Path.MOVETO] + + [Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1)//2) + + [Path.CLOSEPOLY]) + return Path(saw_vertices, codes) + + +@_docstring.dedent_interpd +class ConnectionStyle(_Style): + """ + `ConnectionStyle` is a container class which defines + several connectionstyle classes, which is used to create a path + between two points. These are mainly used with `FancyArrowPatch`. + + A connectionstyle object can be either created as:: + + ConnectionStyle.Arc3(rad=0.2) + + or:: + + ConnectionStyle("Arc3", rad=0.2) + + or:: + + ConnectionStyle("Arc3, rad=0.2") + + The following classes are defined + + %(ConnectionStyle:table)s + + An instance of any connection style class is a callable object, + whose call signature is:: + + __call__(self, posA, posB, + patchA=None, patchB=None, + shrinkA=2., shrinkB=2.) + + and it returns a `.Path` instance. *posA* and *posB* are + tuples of (x, y) coordinates of the two points to be + connected. *patchA* (or *patchB*) is given, the returned path is + clipped so that it start (or end) from the boundary of the + patch. The path is further shrunk by *shrinkA* (or *shrinkB*) + which is given in points. + """ + + _style_list = {} + + class _Base: + """ + A base class for connectionstyle classes. The subclass needs + to implement a *connect* method whose call signature is:: + + connect(posA, posB) + + where posA and posB are tuples of x, y coordinates to be + connected. The method needs to return a path connecting two + points. This base class defines a __call__ method, and a few + helper methods. + """ + + @_api.deprecated("3.7") + class SimpleEvent: + def __init__(self, xy): + self.x, self.y = xy + + def _in_patch(self, patch): + """ + Return a predicate function testing whether a point *xy* is + contained in *patch*. + """ + return lambda xy: patch.contains( + SimpleNamespace(x=xy[0], y=xy[1]))[0] + + def _clip(self, path, in_start, in_stop): + """ + Clip *path* at its start by the region where *in_start* returns + True, and at its stop by the region where *in_stop* returns True. + + The original path is assumed to start in the *in_start* region and + to stop in the *in_stop* region. + """ + if in_start: + try: + _, path = split_path_inout(path, in_start) + except ValueError: + pass + if in_stop: + try: + path, _ = split_path_inout(path, in_stop) + except ValueError: + pass + return path + + def __call__(self, posA, posB, + shrinkA=2., shrinkB=2., patchA=None, patchB=None): + """ + Call the *connect* method to create a path between *posA* and + *posB*; then clip and shrink the path. + """ + path = self.connect(posA, posB) + path = self._clip( + path, + self._in_patch(patchA) if patchA else None, + self._in_patch(patchB) if patchB else None, + ) + path = self._clip( + path, + inside_circle(*path.vertices[0], shrinkA) if shrinkA else None, + inside_circle(*path.vertices[-1], shrinkB) if shrinkB else None + ) + return path + + @_register_style(_style_list) + class Arc3(_Base): + """ + Creates a simple quadratic Bézier curve between two + points. The curve is created so that the middle control point + (C1) is located at the same distance from the start (C0) and + end points(C2) and the distance of the C1 to the line + connecting C0-C2 is *rad* times the distance of C0-C2. + """ + + def __init__(self, rad=0.): + """ + Parameters + ---------- + rad : float + Curvature of the curve. + """ + self.rad = rad + + def connect(self, posA, posB): + x1, y1 = posA + x2, y2 = posB + x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2. + dx, dy = x2 - x1, y2 - y1 + + f = self.rad + + cx, cy = x12 + f * dy, y12 - f * dx + + vertices = [(x1, y1), + (cx, cy), + (x2, y2)] + codes = [Path.MOVETO, + Path.CURVE3, + Path.CURVE3] + + return Path(vertices, codes) + + @_register_style(_style_list) + class Angle3(_Base): + """ + Creates a simple quadratic Bézier curve between two points. The middle + control point is placed at the intersecting point of two lines which + cross the start and end point, and have a slope of *angleA* and + *angleB*, respectively. + """ + + def __init__(self, angleA=90, angleB=0): + """ + Parameters + ---------- + angleA : float + Starting angle of the path. + + angleB : float + Ending angle of the path. + """ + + self.angleA = angleA + self.angleB = angleB + + def connect(self, posA, posB): + x1, y1 = posA + x2, y2 = posB + + cosA = math.cos(math.radians(self.angleA)) + sinA = math.sin(math.radians(self.angleA)) + cosB = math.cos(math.radians(self.angleB)) + sinB = math.sin(math.radians(self.angleB)) + + cx, cy = get_intersection(x1, y1, cosA, sinA, + x2, y2, cosB, sinB) + + vertices = [(x1, y1), (cx, cy), (x2, y2)] + codes = [Path.MOVETO, Path.CURVE3, Path.CURVE3] + + return Path(vertices, codes) + + @_register_style(_style_list) + class Angle(_Base): + """ + Creates a piecewise continuous quadratic Bézier path between two + points. The path has a one passing-through point placed at the + intersecting point of two lines which cross the start and end point, + and have a slope of *angleA* and *angleB*, respectively. + The connecting edges are rounded with *rad*. + """ + + def __init__(self, angleA=90, angleB=0, rad=0.): + """ + Parameters + ---------- + angleA : float + Starting angle of the path. + + angleB : float + Ending angle of the path. + + rad : float + Rounding radius of the edge. + """ + + self.angleA = angleA + self.angleB = angleB + + self.rad = rad + + def connect(self, posA, posB): + x1, y1 = posA + x2, y2 = posB + + cosA = math.cos(math.radians(self.angleA)) + sinA = math.sin(math.radians(self.angleA)) + cosB = math.cos(math.radians(self.angleB)) + sinB = math.sin(math.radians(self.angleB)) + + cx, cy = get_intersection(x1, y1, cosA, sinA, + x2, y2, cosB, sinB) + + vertices = [(x1, y1)] + codes = [Path.MOVETO] + + if self.rad == 0.: + vertices.append((cx, cy)) + codes.append(Path.LINETO) + else: + dx1, dy1 = x1 - cx, y1 - cy + d1 = np.hypot(dx1, dy1) + f1 = self.rad / d1 + dx2, dy2 = x2 - cx, y2 - cy + d2 = np.hypot(dx2, dy2) + f2 = self.rad / d2 + vertices.extend([(cx + dx1 * f1, cy + dy1 * f1), + (cx, cy), + (cx + dx2 * f2, cy + dy2 * f2)]) + codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3]) + + vertices.append((x2, y2)) + codes.append(Path.LINETO) + + return Path(vertices, codes) + + @_register_style(_style_list) + class Arc(_Base): + """ + Creates a piecewise continuous quadratic Bézier path between two + points. The path can have two passing-through points, a + point placed at the distance of *armA* and angle of *angleA* from + point A, another point with respect to point B. The edges are + rounded with *rad*. + """ + + def __init__(self, angleA=0, angleB=0, armA=None, armB=None, rad=0.): + """ + Parameters + ---------- + angleA : float + Starting angle of the path. + + angleB : float + Ending angle of the path. + + armA : float or None + Length of the starting arm. + + armB : float or None + Length of the ending arm. + + rad : float + Rounding radius of the edges. + """ + + self.angleA = angleA + self.angleB = angleB + self.armA = armA + self.armB = armB + + self.rad = rad + + def connect(self, posA, posB): + x1, y1 = posA + x2, y2 = posB + + vertices = [(x1, y1)] + rounded = [] + codes = [Path.MOVETO] + + if self.armA: + cosA = math.cos(math.radians(self.angleA)) + sinA = math.sin(math.radians(self.angleA)) + # x_armA, y_armB + d = self.armA - self.rad + rounded.append((x1 + d * cosA, y1 + d * sinA)) + d = self.armA + rounded.append((x1 + d * cosA, y1 + d * sinA)) + + if self.armB: + cosB = math.cos(math.radians(self.angleB)) + sinB = math.sin(math.radians(self.angleB)) + x_armB, y_armB = x2 + self.armB * cosB, y2 + self.armB * sinB + + if rounded: + xp, yp = rounded[-1] + dx, dy = x_armB - xp, y_armB - yp + dd = (dx * dx + dy * dy) ** .5 + + rounded.append((xp + self.rad * dx / dd, + yp + self.rad * dy / dd)) + vertices.extend(rounded) + codes.extend([Path.LINETO, + Path.CURVE3, + Path.CURVE3]) + else: + xp, yp = vertices[-1] + dx, dy = x_armB - xp, y_armB - yp + dd = (dx * dx + dy * dy) ** .5 + + d = dd - self.rad + rounded = [(xp + d * dx / dd, yp + d * dy / dd), + (x_armB, y_armB)] + + if rounded: + xp, yp = rounded[-1] + dx, dy = x2 - xp, y2 - yp + dd = (dx * dx + dy * dy) ** .5 + + rounded.append((xp + self.rad * dx / dd, + yp + self.rad * dy / dd)) + vertices.extend(rounded) + codes.extend([Path.LINETO, + Path.CURVE3, + Path.CURVE3]) + + vertices.append((x2, y2)) + codes.append(Path.LINETO) + + return Path(vertices, codes) + + @_register_style(_style_list) + class Bar(_Base): + """ + A line with *angle* between A and B with *armA* and *armB*. One of the + arms is extended so that they are connected in a right angle. The + length of *armA* is determined by (*armA* + *fraction* x AB distance). + Same for *armB*. + """ + + def __init__(self, armA=0., armB=0., fraction=0.3, angle=None): + """ + Parameters + ---------- + armA : float + Minimum length of armA. + + armB : float + Minimum length of armB. + + fraction : float + A fraction of the distance between two points that will be + added to armA and armB. + + angle : float or None + Angle of the connecting line (if None, parallel to A and B). + """ + self.armA = armA + self.armB = armB + self.fraction = fraction + self.angle = angle + + def connect(self, posA, posB): + x1, y1 = posA + x20, y20 = x2, y2 = posB + + theta1 = math.atan2(y2 - y1, x2 - x1) + dx, dy = x2 - x1, y2 - y1 + dd = (dx * dx + dy * dy) ** .5 + ddx, ddy = dx / dd, dy / dd + + armA, armB = self.armA, self.armB + + if self.angle is not None: + theta0 = np.deg2rad(self.angle) + dtheta = theta1 - theta0 + dl = dd * math.sin(dtheta) + dL = dd * math.cos(dtheta) + x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0) + armB = armB - dl + + # update + dx, dy = x2 - x1, y2 - y1 + dd2 = (dx * dx + dy * dy) ** .5 + ddx, ddy = dx / dd2, dy / dd2 + + arm = max(armA, armB) + f = self.fraction * dd + arm + + cx1, cy1 = x1 + f * ddy, y1 - f * ddx + cx2, cy2 = x2 + f * ddy, y2 - f * ddx + + vertices = [(x1, y1), + (cx1, cy1), + (cx2, cy2), + (x20, y20)] + codes = [Path.MOVETO, + Path.LINETO, + Path.LINETO, + Path.LINETO] + + return Path(vertices, codes) + + +def _point_along_a_line(x0, y0, x1, y1, d): + """ + Return the point on the line connecting (*x0*, *y0*) -- (*x1*, *y1*) whose + distance from (*x0*, *y0*) is *d*. + """ + dx, dy = x0 - x1, y0 - y1 + ff = d / (dx * dx + dy * dy) ** .5 + x2, y2 = x0 - ff * dx, y0 - ff * dy + + return x2, y2 + + +@_docstring.dedent_interpd +class ArrowStyle(_Style): + """ + `ArrowStyle` is a container class which defines several + arrowstyle classes, which is used to create an arrow path along a + given path. These are mainly used with `FancyArrowPatch`. + + An arrowstyle object can be either created as:: + + ArrowStyle.Fancy(head_length=.4, head_width=.4, tail_width=.4) + + or:: + + ArrowStyle("Fancy", head_length=.4, head_width=.4, tail_width=.4) + + or:: + + ArrowStyle("Fancy, head_length=.4, head_width=.4, tail_width=.4") + + The following classes are defined + + %(ArrowStyle:table)s + + For an overview of the visual appearance, see + :doc:`/gallery/text_labels_and_annotations/fancyarrow_demo`. + + An instance of any arrow style class is a callable object, + whose call signature is:: + + __call__(self, path, mutation_size, linewidth, aspect_ratio=1.) + + and it returns a tuple of a `.Path` instance and a boolean + value. *path* is a `.Path` instance along which the arrow + will be drawn. *mutation_size* and *aspect_ratio* have the same + meaning as in `BoxStyle`. *linewidth* is a line width to be + stroked. This is meant to be used to correct the location of the + head so that it does not overshoot the destination point, but not all + classes support it. + + Notes + ----- + *angleA* and *angleB* specify the orientation of the bracket, as either a + clockwise or counterclockwise angle depending on the arrow type. 0 degrees + means perpendicular to the line connecting the arrow's head and tail. + + .. plot:: gallery/text_labels_and_annotations/angles_on_bracket_arrows.py + """ + + _style_list = {} + + class _Base: + """ + Arrow Transmuter Base class + + ArrowTransmuterBase and its derivatives are used to make a fancy + arrow around a given path. The __call__ method returns a path + (which will be used to create a PathPatch instance) and a boolean + value indicating the path is open therefore is not fillable. This + class is not an artist and actual drawing of the fancy arrow is + done by the FancyArrowPatch class. + """ + + # The derived classes are required to be able to be initialized + # w/o arguments, i.e., all its argument (except self) must have + # the default values. + + @staticmethod + def ensure_quadratic_bezier(path): + """ + Some ArrowStyle classes only works with a simple quadratic + Bézier curve (created with `.ConnectionStyle.Arc3` or + `.ConnectionStyle.Angle3`). This static method checks if the + provided path is a simple quadratic Bézier curve and returns its + control points if true. + """ + segments = list(path.iter_segments()) + if (len(segments) != 2 or segments[0][1] != Path.MOVETO or + segments[1][1] != Path.CURVE3): + raise ValueError( + "'path' is not a valid quadratic Bezier curve") + return [*segments[0][0], *segments[1][0]] + + def transmute(self, path, mutation_size, linewidth): + """ + The transmute method is the very core of the ArrowStyle class and + must be overridden in the subclasses. It receives the *path* + object along which the arrow will be drawn, and the + *mutation_size*, with which the arrow head etc. will be scaled. + The *linewidth* may be used to adjust the path so that it does not + pass beyond the given points. It returns a tuple of a `.Path` + instance and a boolean. The boolean value indicate whether the + path can be filled or not. The return value can also be a list of + paths and list of booleans of the same length. + """ + raise NotImplementedError('Derived must override') + + def __call__(self, path, mutation_size, linewidth, + aspect_ratio=1.): + """ + The __call__ method is a thin wrapper around the transmute method + and takes care of the aspect ratio. + """ + + if aspect_ratio is not None: + # Squeeze the given height by the aspect_ratio + vertices = path.vertices / [1, aspect_ratio] + path_shrunk = Path(vertices, path.codes) + # call transmute method with squeezed height. + path_mutated, fillable = self.transmute(path_shrunk, + mutation_size, + linewidth) + if np.iterable(fillable): + # Restore the height + path_list = [Path(p.vertices * [1, aspect_ratio], p.codes) + for p in path_mutated] + return path_list, fillable + else: + return path_mutated, fillable + else: + return self.transmute(path, mutation_size, linewidth) + + class _Curve(_Base): + """ + A simple arrow which will work with any path instance. The + returned path is the concatenation of the original path, and at + most two paths representing the arrow head or bracket at the start + point and at the end point. The arrow heads can be either open + or closed. + """ + + arrow = "-" + fillbegin = fillend = False # Whether arrows are filled. + + def __init__(self, head_length=.4, head_width=.2, widthA=1., widthB=1., + lengthA=0.2, lengthB=0.2, angleA=0, angleB=0, scaleA=None, + scaleB=None): + """ + Parameters + ---------- + head_length : float, default: 0.4 + Length of the arrow head, relative to *mutation_size*. + head_width : float, default: 0.2 + Width of the arrow head, relative to *mutation_size*. + widthA, widthB : float, default: 1.0 + Width of the bracket. + lengthA, lengthB : float, default: 0.2 + Length of the bracket. + angleA, angleB : float, default: 0 + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + scaleA, scaleB : float, default: *mutation_size* + The scale of the brackets. + """ + + self.head_length, self.head_width = head_length, head_width + self.widthA, self.widthB = widthA, widthB + self.lengthA, self.lengthB = lengthA, lengthB + self.angleA, self.angleB = angleA, angleB + self.scaleA, self.scaleB = scaleA, scaleB + + self._beginarrow_head = False + self._beginarrow_bracket = False + self._endarrow_head = False + self._endarrow_bracket = False + + if "-" not in self.arrow: + raise ValueError("arrow must have the '-' between " + "the two heads") + + beginarrow, endarrow = self.arrow.split("-", 1) + + if beginarrow == "<": + self._beginarrow_head = True + self._beginarrow_bracket = False + elif beginarrow == "<|": + self._beginarrow_head = True + self._beginarrow_bracket = False + self.fillbegin = True + elif beginarrow in ("]", "|"): + self._beginarrow_head = False + self._beginarrow_bracket = True + + if endarrow == ">": + self._endarrow_head = True + self._endarrow_bracket = False + elif endarrow == "|>": + self._endarrow_head = True + self._endarrow_bracket = False + self.fillend = True + elif endarrow in ("[", "|"): + self._endarrow_head = False + self._endarrow_bracket = True + + super().__init__() + + def _get_arrow_wedge(self, x0, y0, x1, y1, + head_dist, cos_t, sin_t, linewidth): + """ + Return the paths for arrow heads. Since arrow lines are + drawn with capstyle=projected, The arrow goes beyond the + desired point. This method also returns the amount of the path + to be shrunken so that it does not overshoot. + """ + + # arrow from x0, y0 to x1, y1 + dx, dy = x0 - x1, y0 - y1 + + cp_distance = np.hypot(dx, dy) + + # pad_projected : amount of pad to account the + # overshooting of the projection of the wedge + pad_projected = (.5 * linewidth / sin_t) + + # Account for division by zero + if cp_distance == 0: + cp_distance = 1 + + # apply pad for projected edge + ddx = pad_projected * dx / cp_distance + ddy = pad_projected * dy / cp_distance + + # offset for arrow wedge + dx = dx / cp_distance * head_dist + dy = dy / cp_distance * head_dist + + dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy + dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy + + vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1), + (x1 + ddx, y1 + ddy), + (x1 + ddx + dx2, y1 + ddy + dy2)] + codes_arrow = [Path.MOVETO, + Path.LINETO, + Path.LINETO] + + return vertices_arrow, codes_arrow, ddx, ddy + + def _get_bracket(self, x0, y0, + x1, y1, width, length, angle): + + cos_t, sin_t = get_cos_sin(x1, y1, x0, y0) + + # arrow from x0, y0 to x1, y1 + from matplotlib.bezier import get_normal_points + x1, y1, x2, y2 = get_normal_points(x0, y0, cos_t, sin_t, width) + + dx, dy = length * cos_t, length * sin_t + + vertices_arrow = [(x1 + dx, y1 + dy), + (x1, y1), + (x2, y2), + (x2 + dx, y2 + dy)] + codes_arrow = [Path.MOVETO, + Path.LINETO, + Path.LINETO, + Path.LINETO] + + if angle: + trans = transforms.Affine2D().rotate_deg_around(x0, y0, angle) + vertices_arrow = trans.transform(vertices_arrow) + + return vertices_arrow, codes_arrow + + def transmute(self, path, mutation_size, linewidth): + # docstring inherited + if self._beginarrow_head or self._endarrow_head: + head_length = self.head_length * mutation_size + head_width = self.head_width * mutation_size + head_dist = np.hypot(head_length, head_width) + cos_t, sin_t = head_length / head_dist, head_width / head_dist + + scaleA = mutation_size if self.scaleA is None else self.scaleA + scaleB = mutation_size if self.scaleB is None else self.scaleB + + # begin arrow + x0, y0 = path.vertices[0] + x1, y1 = path.vertices[1] + + # If there is no room for an arrow and a line, then skip the arrow + has_begin_arrow = self._beginarrow_head and (x0, y0) != (x1, y1) + verticesA, codesA, ddxA, ddyA = ( + self._get_arrow_wedge(x1, y1, x0, y0, + head_dist, cos_t, sin_t, linewidth) + if has_begin_arrow + else ([], [], 0, 0) + ) + + # end arrow + x2, y2 = path.vertices[-2] + x3, y3 = path.vertices[-1] + + # If there is no room for an arrow and a line, then skip the arrow + has_end_arrow = self._endarrow_head and (x2, y2) != (x3, y3) + verticesB, codesB, ddxB, ddyB = ( + self._get_arrow_wedge(x2, y2, x3, y3, + head_dist, cos_t, sin_t, linewidth) + if has_end_arrow + else ([], [], 0, 0) + ) + + # This simple code will not work if ddx, ddy is greater than the + # separation between vertices. + paths = [Path(np.concatenate([[(x0 + ddxA, y0 + ddyA)], + path.vertices[1:-1], + [(x3 + ddxB, y3 + ddyB)]]), + path.codes)] + fills = [False] + + if has_begin_arrow: + if self.fillbegin: + paths.append( + Path([*verticesA, (0, 0)], [*codesA, Path.CLOSEPOLY])) + fills.append(True) + else: + paths.append(Path(verticesA, codesA)) + fills.append(False) + elif self._beginarrow_bracket: + x0, y0 = path.vertices[0] + x1, y1 = path.vertices[1] + verticesA, codesA = self._get_bracket(x0, y0, x1, y1, + self.widthA * scaleA, + self.lengthA * scaleA, + self.angleA) + + paths.append(Path(verticesA, codesA)) + fills.append(False) + + if has_end_arrow: + if self.fillend: + fills.append(True) + paths.append( + Path([*verticesB, (0, 0)], [*codesB, Path.CLOSEPOLY])) + else: + fills.append(False) + paths.append(Path(verticesB, codesB)) + elif self._endarrow_bracket: + x0, y0 = path.vertices[-1] + x1, y1 = path.vertices[-2] + verticesB, codesB = self._get_bracket(x0, y0, x1, y1, + self.widthB * scaleB, + self.lengthB * scaleB, + self.angleB) + + paths.append(Path(verticesB, codesB)) + fills.append(False) + + return paths, fills + + @_register_style(_style_list, name="-") + class Curve(_Curve): + """A simple curve without any arrow head.""" + + def __init__(self): # hide head_length, head_width + # These attributes (whose values come from backcompat) only matter + # if someone modifies beginarrow/etc. on an ArrowStyle instance. + super().__init__(head_length=.2, head_width=.1) + + @_register_style(_style_list, name="<-") + class CurveA(_Curve): + """An arrow with a head at its start point.""" + arrow = "<-" + + @_register_style(_style_list, name="->") + class CurveB(_Curve): + """An arrow with a head at its end point.""" + arrow = "->" + + @_register_style(_style_list, name="<->") + class CurveAB(_Curve): + """An arrow with heads both at the start and the end point.""" + arrow = "<->" + + @_register_style(_style_list, name="<|-") + class CurveFilledA(_Curve): + """An arrow with filled triangle head at the start.""" + arrow = "<|-" + + @_register_style(_style_list, name="-|>") + class CurveFilledB(_Curve): + """An arrow with filled triangle head at the end.""" + arrow = "-|>" + + @_register_style(_style_list, name="<|-|>") + class CurveFilledAB(_Curve): + """An arrow with filled triangle heads at both ends.""" + arrow = "<|-|>" + + @_register_style(_style_list, name="]-") + class BracketA(_Curve): + """An arrow with an outward square bracket at its start.""" + arrow = "]-" + + def __init__(self, widthA=1., lengthA=0.2, angleA=0): + """ + Parameters + ---------- + widthA : float, default: 1.0 + Width of the bracket. + lengthA : float, default: 0.2 + Length of the bracket. + angleA : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA) + + @_register_style(_style_list, name="-[") + class BracketB(_Curve): + """An arrow with an outward square bracket at its end.""" + arrow = "-[" + + def __init__(self, widthB=1., lengthB=0.2, angleB=0): + """ + Parameters + ---------- + widthB : float, default: 1.0 + Width of the bracket. + lengthB : float, default: 0.2 + Length of the bracket. + angleB : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthB=widthB, lengthB=lengthB, angleB=angleB) + + @_register_style(_style_list, name="]-[") + class BracketAB(_Curve): + """An arrow with outward square brackets at both ends.""" + arrow = "]-[" + + def __init__(self, + widthA=1., lengthA=0.2, angleA=0, + widthB=1., lengthB=0.2, angleB=0): + """ + Parameters + ---------- + widthA, widthB : float, default: 1.0 + Width of the bracket. + lengthA, lengthB : float, default: 0.2 + Length of the bracket. + angleA, angleB : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA, + widthB=widthB, lengthB=lengthB, angleB=angleB) + + @_register_style(_style_list, name="|-|") + class BarAB(_Curve): + """An arrow with vertical bars ``|`` at both ends.""" + arrow = "|-|" + + def __init__(self, widthA=1., angleA=0, widthB=1., angleB=0): + """ + Parameters + ---------- + widthA, widthB : float, default: 1.0 + Width of the bracket. + angleA, angleB : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthA=widthA, lengthA=0, angleA=angleA, + widthB=widthB, lengthB=0, angleB=angleB) + + @_register_style(_style_list, name=']->') + class BracketCurve(_Curve): + """ + An arrow with an outward square bracket at its start and a head at + the end. + """ + arrow = "]->" + + def __init__(self, widthA=1., lengthA=0.2, angleA=None): + """ + Parameters + ---------- + widthA : float, default: 1.0 + Width of the bracket. + lengthA : float, default: 0.2 + Length of the bracket. + angleA : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA) + + @_register_style(_style_list, name='<-[') + class CurveBracket(_Curve): + """ + An arrow with an outward square bracket at its end and a head at + the start. + """ + arrow = "<-[" + + def __init__(self, widthB=1., lengthB=0.2, angleB=None): + """ + Parameters + ---------- + widthB : float, default: 1.0 + Width of the bracket. + lengthB : float, default: 0.2 + Length of the bracket. + angleB : float, default: 0 degrees + Orientation of the bracket, as a counterclockwise angle. + 0 degrees means perpendicular to the line. + """ + super().__init__(widthB=widthB, lengthB=lengthB, angleB=angleB) + + @_register_style(_style_list) + class Simple(_Base): + """A simple arrow. Only works with a quadratic Bézier curve.""" + + def __init__(self, head_length=.5, head_width=.5, tail_width=.2): + """ + Parameters + ---------- + head_length : float, default: 0.5 + Length of the arrow head. + + head_width : float, default: 0.5 + Width of the arrow head. + + tail_width : float, default: 0.2 + Width of the arrow tail. + """ + self.head_length, self.head_width, self.tail_width = \ + head_length, head_width, tail_width + super().__init__() + + def transmute(self, path, mutation_size, linewidth): + # docstring inherited + x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) + + # divide the path into a head and a tail + head_length = self.head_length * mutation_size + in_f = inside_circle(x2, y2, head_length) + arrow_path = [(x0, y0), (x1, y1), (x2, y2)] + + try: + arrow_out, arrow_in = \ + split_bezier_intersecting_with_closedpath(arrow_path, in_f) + except NonIntersectingPathException: + # if this happens, make a straight line of the head_length + # long. + x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length) + x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2) + arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)] + arrow_out = None + + # head + head_width = self.head_width * mutation_size + head_left, head_right = make_wedged_bezier2(arrow_in, + head_width / 2., wm=.5) + + # tail + if arrow_out is not None: + tail_width = self.tail_width * mutation_size + tail_left, tail_right = get_parallels(arrow_out, + tail_width / 2.) + + patch_path = [(Path.MOVETO, tail_right[0]), + (Path.CURVE3, tail_right[1]), + (Path.CURVE3, tail_right[2]), + (Path.LINETO, head_right[0]), + (Path.CURVE3, head_right[1]), + (Path.CURVE3, head_right[2]), + (Path.CURVE3, head_left[1]), + (Path.CURVE3, head_left[0]), + (Path.LINETO, tail_left[2]), + (Path.CURVE3, tail_left[1]), + (Path.CURVE3, tail_left[0]), + (Path.LINETO, tail_right[0]), + (Path.CLOSEPOLY, tail_right[0]), + ] + else: + patch_path = [(Path.MOVETO, head_right[0]), + (Path.CURVE3, head_right[1]), + (Path.CURVE3, head_right[2]), + (Path.CURVE3, head_left[1]), + (Path.CURVE3, head_left[0]), + (Path.CLOSEPOLY, head_left[0]), + ] + + path = Path([p for c, p in patch_path], [c for c, p in patch_path]) + + return path, True + + @_register_style(_style_list) + class Fancy(_Base): + """A fancy arrow. Only works with a quadratic Bézier curve.""" + + def __init__(self, head_length=.4, head_width=.4, tail_width=.4): + """ + Parameters + ---------- + head_length : float, default: 0.4 + Length of the arrow head. + + head_width : float, default: 0.4 + Width of the arrow head. + + tail_width : float, default: 0.4 + Width of the arrow tail. + """ + self.head_length, self.head_width, self.tail_width = \ + head_length, head_width, tail_width + super().__init__() + + def transmute(self, path, mutation_size, linewidth): + # docstring inherited + x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) + + # divide the path into a head and a tail + head_length = self.head_length * mutation_size + arrow_path = [(x0, y0), (x1, y1), (x2, y2)] + + # path for head + in_f = inside_circle(x2, y2, head_length) + try: + path_out, path_in = split_bezier_intersecting_with_closedpath( + arrow_path, in_f) + except NonIntersectingPathException: + # if this happens, make a straight line of the head_length + # long. + x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length) + x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2) + arrow_path = [(x0, y0), (x1n, y1n), (x2, y2)] + path_head = arrow_path + else: + path_head = path_in + + # path for head + in_f = inside_circle(x2, y2, head_length * .8) + path_out, path_in = split_bezier_intersecting_with_closedpath( + arrow_path, in_f) + path_tail = path_out + + # head + head_width = self.head_width * mutation_size + head_l, head_r = make_wedged_bezier2(path_head, + head_width / 2., + wm=.6) + + # tail + tail_width = self.tail_width * mutation_size + tail_left, tail_right = make_wedged_bezier2(path_tail, + tail_width * .5, + w1=1., wm=0.6, w2=0.3) + + # path for head + in_f = inside_circle(x0, y0, tail_width * .3) + path_in, path_out = split_bezier_intersecting_with_closedpath( + arrow_path, in_f) + tail_start = path_in[-1] + + head_right, head_left = head_r, head_l + patch_path = [(Path.MOVETO, tail_start), + (Path.LINETO, tail_right[0]), + (Path.CURVE3, tail_right[1]), + (Path.CURVE3, tail_right[2]), + (Path.LINETO, head_right[0]), + (Path.CURVE3, head_right[1]), + (Path.CURVE3, head_right[2]), + (Path.CURVE3, head_left[1]), + (Path.CURVE3, head_left[0]), + (Path.LINETO, tail_left[2]), + (Path.CURVE3, tail_left[1]), + (Path.CURVE3, tail_left[0]), + (Path.LINETO, tail_start), + (Path.CLOSEPOLY, tail_start), + ] + path = Path([p for c, p in patch_path], [c for c, p in patch_path]) + + return path, True + + @_register_style(_style_list) + class Wedge(_Base): + """ + Wedge(?) shape. Only works with a quadratic Bézier curve. The + start point has a width of the *tail_width* and the end point has a + width of 0. At the middle, the width is *shrink_factor*x*tail_width*. + """ + + def __init__(self, tail_width=.3, shrink_factor=0.5): + """ + Parameters + ---------- + tail_width : float, default: 0.3 + Width of the tail. + + shrink_factor : float, default: 0.5 + Fraction of the arrow width at the middle point. + """ + self.tail_width = tail_width + self.shrink_factor = shrink_factor + super().__init__() + + def transmute(self, path, mutation_size, linewidth): + # docstring inherited + x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) + + arrow_path = [(x0, y0), (x1, y1), (x2, y2)] + b_plus, b_minus = make_wedged_bezier2( + arrow_path, + self.tail_width * mutation_size / 2., + wm=self.shrink_factor) + + patch_path = [(Path.MOVETO, b_plus[0]), + (Path.CURVE3, b_plus[1]), + (Path.CURVE3, b_plus[2]), + (Path.LINETO, b_minus[2]), + (Path.CURVE3, b_minus[1]), + (Path.CURVE3, b_minus[0]), + (Path.CLOSEPOLY, b_minus[0]), + ] + path = Path([p for c, p in patch_path], [c for c, p in patch_path]) + + return path, True + + +class FancyBboxPatch(Patch): + """ + A fancy box around a rectangle with lower left at *xy* = (*x*, *y*) + with specified width and height. + + `.FancyBboxPatch` is similar to `.Rectangle`, but it draws a fancy box + around the rectangle. The transformation of the rectangle box to the + fancy box is delegated to the style classes defined in `.BoxStyle`. + """ + + _edge_default = True + + def __str__(self): + s = self.__class__.__name__ + "((%g, %g), width=%g, height=%g)" + return s % (self._x, self._y, self._width, self._height) + + @_docstring.dedent_interpd + def __init__(self, xy, width, height, boxstyle="round", *, + mutation_scale=1, mutation_aspect=1, **kwargs): + """ + Parameters + ---------- + xy : (float, float) + The lower left corner of the box. + + width : float + The width of the box. + + height : float + The height of the box. + + boxstyle : str or `~matplotlib.patches.BoxStyle` + The style of the fancy box. This can either be a `.BoxStyle` + instance or a string of the style name and optionally comma + separated attributes (e.g. "Round, pad=0.2"). This string is + passed to `.BoxStyle` to construct a `.BoxStyle` object. See + there for a full documentation. + + The following box styles are available: + + %(BoxStyle:table)s + + mutation_scale : float, default: 1 + Scaling factor applied to the attributes of the box style + (e.g. pad or rounding_size). + + mutation_aspect : float, default: 1 + The height of the rectangle will be squeezed by this value before + the mutation and the mutated box will be stretched by the inverse + of it. For example, this allows different horizontal and vertical + padding. + + Other Parameters + ---------------- + **kwargs : `~matplotlib.patches.Patch` properties + + %(Patch:kwdoc)s + """ + + super().__init__(**kwargs) + self._x, self._y = xy + self._width = width + self._height = height + self.set_boxstyle(boxstyle) + self._mutation_scale = mutation_scale + self._mutation_aspect = mutation_aspect + self.stale = True + + @_docstring.dedent_interpd + def set_boxstyle(self, boxstyle=None, **kwargs): + """ + Set the box style, possibly with further attributes. + + Attributes from the previous box style are not reused. + + Without argument (or with ``boxstyle=None``), the available box styles + are returned as a human-readable string. + + Parameters + ---------- + boxstyle : str or `~matplotlib.patches.BoxStyle` + The style of the box: either a `.BoxStyle` instance, or a string, + which is the style name and optionally comma separated attributes + (e.g. "Round,pad=0.2"). Such a string is used to construct a + `.BoxStyle` object, as documented in that class. + + The following box styles are available: + + %(BoxStyle:table_and_accepts)s + + **kwargs + Additional attributes for the box style. See the table above for + supported parameters. + + Examples + -------- + :: + + set_boxstyle("Round,pad=0.2") + set_boxstyle("round", pad=0.2) + """ + if boxstyle is None: + return BoxStyle.pprint_styles() + self._bbox_transmuter = ( + BoxStyle(boxstyle, **kwargs) + if isinstance(boxstyle, str) else boxstyle) + self.stale = True + + def get_boxstyle(self): + """Return the boxstyle object.""" + return self._bbox_transmuter + + def set_mutation_scale(self, scale): + """ + Set the mutation scale. + + Parameters + ---------- + scale : float + """ + self._mutation_scale = scale + self.stale = True + + def get_mutation_scale(self): + """Return the mutation scale.""" + return self._mutation_scale + + def set_mutation_aspect(self, aspect): + """ + Set the aspect ratio of the bbox mutation. + + Parameters + ---------- + aspect : float + """ + self._mutation_aspect = aspect + self.stale = True + + def get_mutation_aspect(self): + """Return the aspect ratio of the bbox mutation.""" + return (self._mutation_aspect if self._mutation_aspect is not None + else 1) # backcompat. + + def get_path(self): + """Return the mutated path of the rectangle.""" + boxstyle = self.get_boxstyle() + m_aspect = self.get_mutation_aspect() + # Call boxstyle with y, height squeezed by aspect_ratio. + path = boxstyle(self._x, self._y / m_aspect, + self._width, self._height / m_aspect, + self.get_mutation_scale()) + return Path(path.vertices * [1, m_aspect], path.codes) # Unsqueeze y. + + # Following methods are borrowed from the Rectangle class. + + def get_x(self): + """Return the left coord of the rectangle.""" + return self._x + + def get_y(self): + """Return the bottom coord of the rectangle.""" + return self._y + + def get_width(self): + """Return the width of the rectangle.""" + return self._width + + def get_height(self): + """Return the height of the rectangle.""" + return self._height + + def set_x(self, x): + """ + Set the left coord of the rectangle. + + Parameters + ---------- + x : float + """ + self._x = x + self.stale = True + + def set_y(self, y): + """ + Set the bottom coord of the rectangle. + + Parameters + ---------- + y : float + """ + self._y = y + self.stale = True + + def set_width(self, w): + """ + Set the rectangle width. + + Parameters + ---------- + w : float + """ + self._width = w + self.stale = True + + def set_height(self, h): + """ + Set the rectangle height. + + Parameters + ---------- + h : float + """ + self._height = h + self.stale = True + + def set_bounds(self, *args): + """ + Set the bounds of the rectangle. + + Call signatures:: + + set_bounds(left, bottom, width, height) + set_bounds((left, bottom, width, height)) + + Parameters + ---------- + left, bottom : float + The coordinates of the bottom left corner of the rectangle. + width, height : float + The width/height of the rectangle. + """ + if len(args) == 1: + l, b, w, h = args[0] + else: + l, b, w, h = args + self._x = l + self._y = b + self._width = w + self._height = h + self.stale = True + + def get_bbox(self): + """Return the `.Bbox`.""" + return transforms.Bbox.from_bounds(self._x, self._y, + self._width, self._height) + + +class FancyArrowPatch(Patch): + """ + A fancy arrow patch. + + It draws an arrow using the `ArrowStyle`. It is primarily used by the + `~.axes.Axes.annotate` method. For most purposes, use the annotate method for + drawing arrows. + + The head and tail positions are fixed at the specified start and end points + of the arrow, but the size and shape (in display coordinates) of the arrow + does not change when the axis is moved or zoomed. + """ + _edge_default = True + + def __str__(self): + if self._posA_posB is not None: + (x1, y1), (x2, y2) = self._posA_posB + return f"{type(self).__name__}(({x1:g}, {y1:g})->({x2:g}, {y2:g}))" + else: + return f"{type(self).__name__}({self._path_original})" + + @_docstring.dedent_interpd + def __init__(self, posA=None, posB=None, *, + path=None, arrowstyle="simple", connectionstyle="arc3", + patchA=None, patchB=None, shrinkA=2, shrinkB=2, + mutation_scale=1, mutation_aspect=1, **kwargs): + """ + There are two ways for defining an arrow: + + - If *posA* and *posB* are given, a path connecting two points is + created according to *connectionstyle*. The path will be + clipped with *patchA* and *patchB* and further shrunken by + *shrinkA* and *shrinkB*. An arrow is drawn along this + resulting path using the *arrowstyle* parameter. + + - Alternatively if *path* is provided, an arrow is drawn along this + path and *patchA*, *patchB*, *shrinkA*, and *shrinkB* are ignored. + + Parameters + ---------- + posA, posB : (float, float), default: None + (x, y) coordinates of arrow tail and arrow head respectively. + + path : `~matplotlib.path.Path`, default: None + If provided, an arrow is drawn along this path and *patchA*, + *patchB*, *shrinkA*, and *shrinkB* are ignored. + + arrowstyle : str or `.ArrowStyle`, default: 'simple' + The `.ArrowStyle` with which the fancy arrow is drawn. If a + string, it should be one of the available arrowstyle names, with + optional comma-separated attributes. The optional attributes are + meant to be scaled with the *mutation_scale*. The following arrow + styles are available: + + %(ArrowStyle:table)s + + connectionstyle : str or `.ConnectionStyle` or None, optional, \ +default: 'arc3' + The `.ConnectionStyle` with which *posA* and *posB* are connected. + If a string, it should be one of the available connectionstyle + names, with optional comma-separated attributes. The following + connection styles are available: + + %(ConnectionStyle:table)s + + patchA, patchB : `~matplotlib.patches.Patch`, default: None + Head and tail patches, respectively. + + shrinkA, shrinkB : float, default: 2 + Shrinking factor of the tail and head of the arrow respectively. + + mutation_scale : float, default: 1 + Value with which attributes of *arrowstyle* (e.g., *head_length*) + will be scaled. + + mutation_aspect : None or float, default: None + The height of the rectangle will be squeezed by this value before + the mutation and the mutated box will be stretched by the inverse + of it. + + Other Parameters + ---------------- + **kwargs : `~matplotlib.patches.Patch` properties, optional + Here is a list of available `.Patch` properties: + + %(Patch:kwdoc)s + + In contrast to other patches, the default ``capstyle`` and + ``joinstyle`` for `FancyArrowPatch` are set to ``"round"``. + """ + # Traditionally, the cap- and joinstyle for FancyArrowPatch are round + kwargs.setdefault("joinstyle", JoinStyle.round) + kwargs.setdefault("capstyle", CapStyle.round) + + super().__init__(**kwargs) + + if posA is not None and posB is not None and path is None: + self._posA_posB = [posA, posB] + + if connectionstyle is None: + connectionstyle = "arc3" + self.set_connectionstyle(connectionstyle) + + elif posA is None and posB is None and path is not None: + self._posA_posB = None + else: + raise ValueError("Either posA and posB, or path need to provided") + + self.patchA = patchA + self.patchB = patchB + self.shrinkA = shrinkA + self.shrinkB = shrinkB + + self._path_original = path + + self.set_arrowstyle(arrowstyle) + + self._mutation_scale = mutation_scale + self._mutation_aspect = mutation_aspect + + self._dpi_cor = 1.0 + + def set_positions(self, posA, posB): + """ + Set the start and end positions of the connecting path. + + Parameters + ---------- + posA, posB : None, tuple + (x, y) coordinates of arrow tail and arrow head respectively. If + `None` use current value. + """ + if posA is not None: + self._posA_posB[0] = posA + if posB is not None: + self._posA_posB[1] = posB + self.stale = True + + def set_patchA(self, patchA): + """ + Set the tail patch. + + Parameters + ---------- + patchA : `.patches.Patch` + """ + self.patchA = patchA + self.stale = True + + def set_patchB(self, patchB): + """ + Set the head patch. + + Parameters + ---------- + patchB : `.patches.Patch` + """ + self.patchB = patchB + self.stale = True + + @_docstring.dedent_interpd + def set_connectionstyle(self, connectionstyle=None, **kwargs): + """ + Set the connection style, possibly with further attributes. + + Attributes from the previous connection style are not reused. + + Without argument (or with ``connectionstyle=None``), the available box + styles are returned as a human-readable string. + + Parameters + ---------- + connectionstyle : str or `~matplotlib.patches.ConnectionStyle` + The style of the connection: either a `.ConnectionStyle` instance, + or a string, which is the style name and optionally comma separated + attributes (e.g. "Arc,armA=30,rad=10"). Such a string is used to + construct a `.ConnectionStyle` object, as documented in that class. + + The following connection styles are available: + + %(ConnectionStyle:table_and_accepts)s + + **kwargs + Additional attributes for the connection style. See the table above + for supported parameters. + + Examples + -------- + :: + + set_connectionstyle("Arc,armA=30,rad=10") + set_connectionstyle("arc", armA=30, rad=10) + """ + if connectionstyle is None: + return ConnectionStyle.pprint_styles() + self._connector = ( + ConnectionStyle(connectionstyle, **kwargs) + if isinstance(connectionstyle, str) else connectionstyle) + self.stale = True + + def get_connectionstyle(self): + """Return the `ConnectionStyle` used.""" + return self._connector + + def set_arrowstyle(self, arrowstyle=None, **kwargs): + """ + Set the arrow style, possibly with further attributes. + + Attributes from the previous arrow style are not reused. + + Without argument (or with ``arrowstyle=None``), the available box + styles are returned as a human-readable string. + + Parameters + ---------- + arrowstyle : str or `~matplotlib.patches.ArrowStyle` + The style of the arrow: either a `.ArrowStyle` instance, or a + string, which is the style name and optionally comma separated + attributes (e.g. "Fancy,head_length=0.2"). Such a string is used to + construct a `.ArrowStyle` object, as documented in that class. + + The following arrow styles are available: + + %(ArrowStyle:table_and_accepts)s + + **kwargs + Additional attributes for the arrow style. See the table above for + supported parameters. + + Examples + -------- + :: + + set_arrowstyle("Fancy,head_length=0.2") + set_arrowstyle("fancy", head_length=0.2) + """ + if arrowstyle is None: + return ArrowStyle.pprint_styles() + self._arrow_transmuter = ( + ArrowStyle(arrowstyle, **kwargs) + if isinstance(arrowstyle, str) else arrowstyle) + self.stale = True + + def get_arrowstyle(self): + """Return the arrowstyle object.""" + return self._arrow_transmuter + + def set_mutation_scale(self, scale): + """ + Set the mutation scale. + + Parameters + ---------- + scale : float + """ + self._mutation_scale = scale + self.stale = True + + def get_mutation_scale(self): + """ + Return the mutation scale. + + Returns + ------- + scalar + """ + return self._mutation_scale + + def set_mutation_aspect(self, aspect): + """ + Set the aspect ratio of the bbox mutation. + + Parameters + ---------- + aspect : float + """ + self._mutation_aspect = aspect + self.stale = True + + def get_mutation_aspect(self): + """Return the aspect ratio of the bbox mutation.""" + return (self._mutation_aspect if self._mutation_aspect is not None + else 1) # backcompat. + + def get_path(self): + """Return the path of the arrow in the data coordinates.""" + # The path is generated in display coordinates, then converted back to + # data coordinates. + _path, fillable = self._get_path_in_displaycoord() + if np.iterable(fillable): + _path = Path.make_compound_path(*_path) + return self.get_transform().inverted().transform_path(_path) + + def _get_path_in_displaycoord(self): + """Return the mutated path of the arrow in display coordinates.""" + dpi_cor = self._dpi_cor + + if self._posA_posB is not None: + posA = self._convert_xy_units(self._posA_posB[0]) + posB = self._convert_xy_units(self._posA_posB[1]) + (posA, posB) = self.get_transform().transform((posA, posB)) + _path = self.get_connectionstyle()(posA, posB, + patchA=self.patchA, + patchB=self.patchB, + shrinkA=self.shrinkA * dpi_cor, + shrinkB=self.shrinkB * dpi_cor + ) + else: + _path = self.get_transform().transform_path(self._path_original) + + _path, fillable = self.get_arrowstyle()( + _path, + self.get_mutation_scale() * dpi_cor, + self.get_linewidth() * dpi_cor, + self.get_mutation_aspect()) + + return _path, fillable + + def draw(self, renderer): + if not self.get_visible(): + return + + # FIXME: dpi_cor is for the dpi-dependency of the linewidth. There + # could be room for improvement. Maybe _get_path_in_displaycoord could + # take a renderer argument, but get_path should be adapted too. + self._dpi_cor = renderer.points_to_pixels(1.) + path, fillable = self._get_path_in_displaycoord() + + if not np.iterable(fillable): + path = [path] + fillable = [fillable] + + affine = transforms.IdentityTransform() + + self._draw_paths_with_artist_properties( + renderer, + [(p, affine, self._facecolor if f and self._facecolor[3] else None) + for p, f in zip(path, fillable)]) + + +class ConnectionPatch(FancyArrowPatch): + """A patch that connects two points (possibly in different axes).""" + + def __str__(self): + return "ConnectionPatch((%g, %g), (%g, %g))" % \ + (self.xy1[0], self.xy1[1], self.xy2[0], self.xy2[1]) + + @_docstring.dedent_interpd + def __init__(self, xyA, xyB, coordsA, coordsB=None, *, + axesA=None, axesB=None, + arrowstyle="-", + connectionstyle="arc3", + patchA=None, + patchB=None, + shrinkA=0., + shrinkB=0., + mutation_scale=10., + mutation_aspect=None, + clip_on=False, + **kwargs): + """ + Connect point *xyA* in *coordsA* with point *xyB* in *coordsB*. + + Valid keys are + + =============== ====================================================== + Key Description + =============== ====================================================== + arrowstyle the arrow style + connectionstyle the connection style + relpos default is (0.5, 0.5) + patchA default is bounding box of the text + patchB default is None + shrinkA default is 2 points + shrinkB default is 2 points + mutation_scale default is text size (in points) + mutation_aspect default is 1. + ? any key for `matplotlib.patches.PathPatch` + =============== ====================================================== + + *coordsA* and *coordsB* are strings that indicate the + coordinates of *xyA* and *xyB*. + + ==================== ================================================== + Property Description + ==================== ================================================== + 'figure points' points from the lower left corner of the figure + 'figure pixels' pixels from the lower left corner of the figure + 'figure fraction' 0, 0 is lower left of figure and 1, 1 is upper + right + 'subfigure points' points from the lower left corner of the subfigure + 'subfigure pixels' pixels from the lower left corner of the subfigure + 'subfigure fraction' fraction of the subfigure, 0, 0 is lower left. + 'axes points' points from lower left corner of axes + 'axes pixels' pixels from lower left corner of axes + 'axes fraction' 0, 0 is lower left of axes and 1, 1 is upper right + 'data' use the coordinate system of the object being + annotated (default) + 'offset points' offset (in points) from the *xy* value + 'polar' you can specify *theta*, *r* for the annotation, + even in cartesian plots. Note that if you are + using a polar axes, you do not need to specify + polar for the coordinate system since that is the + native "data" coordinate system. + ==================== ================================================== + + Alternatively they can be set to any valid + `~matplotlib.transforms.Transform`. + + Note that 'subfigure pixels' and 'figure pixels' are the same + for the parent figure, so users who want code that is usable in + a subfigure can use 'subfigure pixels'. + + .. note:: + + Using `ConnectionPatch` across two `~.axes.Axes` instances + is not directly compatible with :ref:`constrained layout + <constrainedlayout_guide>`. Add the artist + directly to the `.Figure` instead of adding it to a specific Axes, + or exclude it from the layout using ``con.set_in_layout(False)``. + + .. code-block:: default + + fig, ax = plt.subplots(1, 2, constrained_layout=True) + con = ConnectionPatch(..., axesA=ax[0], axesB=ax[1]) + fig.add_artist(con) + + """ + if coordsB is None: + coordsB = coordsA + # we'll draw ourself after the artist we annotate by default + self.xy1 = xyA + self.xy2 = xyB + self.coords1 = coordsA + self.coords2 = coordsB + + self.axesA = axesA + self.axesB = axesB + + super().__init__(posA=(0, 0), posB=(1, 1), + arrowstyle=arrowstyle, + connectionstyle=connectionstyle, + patchA=patchA, patchB=patchB, + shrinkA=shrinkA, shrinkB=shrinkB, + mutation_scale=mutation_scale, + mutation_aspect=mutation_aspect, + clip_on=clip_on, + **kwargs) + # if True, draw annotation only if self.xy is inside the axes + self._annotation_clip = None + + def _get_xy(self, xy, s, axes=None): + """Calculate the pixel position of given point.""" + s0 = s # For the error message, if needed. + if axes is None: + axes = self.axes + xy = np.array(xy) + if s in ["figure points", "axes points"]: + xy *= self.figure.dpi / 72 + s = s.replace("points", "pixels") + elif s == "figure fraction": + s = self.figure.transFigure + elif s == "subfigure fraction": + s = self.figure.transSubfigure + elif s == "axes fraction": + s = axes.transAxes + x, y = xy + + if s == 'data': + trans = axes.transData + x = float(self.convert_xunits(x)) + y = float(self.convert_yunits(y)) + return trans.transform((x, y)) + elif s == 'offset points': + if self.xycoords == 'offset points': # prevent recursion + return self._get_xy(self.xy, 'data') + return ( + self._get_xy(self.xy, self.xycoords) # converted data point + + xy * self.figure.dpi / 72) # converted offset + elif s == 'polar': + theta, r = x, y + x = r * np.cos(theta) + y = r * np.sin(theta) + trans = axes.transData + return trans.transform((x, y)) + elif s == 'figure pixels': + # pixels from the lower left corner of the figure + bb = self.figure.figbbox + x = bb.x0 + x if x >= 0 else bb.x1 + x + y = bb.y0 + y if y >= 0 else bb.y1 + y + return x, y + elif s == 'subfigure pixels': + # pixels from the lower left corner of the figure + bb = self.figure.bbox + x = bb.x0 + x if x >= 0 else bb.x1 + x + y = bb.y0 + y if y >= 0 else bb.y1 + y + return x, y + elif s == 'axes pixels': + # pixels from the lower left corner of the axes + bb = axes.bbox + x = bb.x0 + x if x >= 0 else bb.x1 + x + y = bb.y0 + y if y >= 0 else bb.y1 + y + return x, y + elif isinstance(s, transforms.Transform): + return s.transform(xy) + else: + raise ValueError(f"{s0} is not a valid coordinate transformation") + + def set_annotation_clip(self, b): + """ + Set the annotation's clipping behavior. + + Parameters + ---------- + b : bool or None + - True: The annotation will be clipped when ``self.xy`` is + outside the axes. + - False: The annotation will always be drawn. + - None: The annotation will be clipped when ``self.xy`` is + outside the axes and ``self.xycoords == "data"``. + """ + self._annotation_clip = b + self.stale = True + + def get_annotation_clip(self): + """ + Return the clipping behavior. + + See `.set_annotation_clip` for the meaning of the return value. + """ + return self._annotation_clip + + def _get_path_in_displaycoord(self): + """Return the mutated path of the arrow in display coordinates.""" + dpi_cor = self._dpi_cor + posA = self._get_xy(self.xy1, self.coords1, self.axesA) + posB = self._get_xy(self.xy2, self.coords2, self.axesB) + path = self.get_connectionstyle()( + posA, posB, + patchA=self.patchA, patchB=self.patchB, + shrinkA=self.shrinkA * dpi_cor, shrinkB=self.shrinkB * dpi_cor, + ) + path, fillable = self.get_arrowstyle()( + path, + self.get_mutation_scale() * dpi_cor, + self.get_linewidth() * dpi_cor, + self.get_mutation_aspect() + ) + return path, fillable + + def _check_xy(self, renderer): + """Check whether the annotation needs to be drawn.""" + + b = self.get_annotation_clip() + + if b or (b is None and self.coords1 == "data"): + xy_pixel = self._get_xy(self.xy1, self.coords1, self.axesA) + if self.axesA is None: + axes = self.axes + else: + axes = self.axesA + if not axes.contains_point(xy_pixel): + return False + + if b or (b is None and self.coords2 == "data"): + xy_pixel = self._get_xy(self.xy2, self.coords2, self.axesB) + if self.axesB is None: + axes = self.axes + else: + axes = self.axesB + if not axes.contains_point(xy_pixel): + return False + + return True + + def draw(self, renderer): + if renderer is not None: + self._renderer = renderer + if not self.get_visible() or not self._check_xy(renderer): + return + super().draw(renderer) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.pyi new file mode 100644 index 00000000..29fe36aa --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patches.pyi @@ -0,0 +1,751 @@ +from . import artist +from .axes import Axes +from .backend_bases import RendererBase, MouseEvent +from .path import Path +from .transforms import Transform, Bbox + +from typing import Any, Literal, overload + +import numpy as np +from numpy.typing import ArrayLike +from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType + +class Patch(artist.Artist): + zorder: float + def __init__( + self, + *, + edgecolor: ColorType | None = ..., + facecolor: ColorType | None = ..., + color: ColorType | None = ..., + linewidth: float | None = ..., + linestyle: LineStyleType | None = ..., + antialiased: bool | None = ..., + hatch: str | None = ..., + fill: bool = ..., + capstyle: CapStyleType | None = ..., + joinstyle: JoinStyleType | None = ..., + **kwargs, + ) -> None: ... + def get_verts(self) -> ArrayLike: ... + def contains(self, mouseevent: MouseEvent, radius: float | None = None) -> tuple[bool, dict[Any, Any]]: ... + def contains_point( + self, point: tuple[float, float], radius: float | None = ... + ) -> bool: ... + def contains_points( + self, points: ArrayLike, radius: float | None = ... + ) -> np.ndarray: ... + def get_extents(self) -> Bbox: ... + def get_transform(self) -> Transform: ... + def get_data_transform(self) -> Transform: ... + def get_patch_transform(self) -> Transform: ... + def get_antialiased(self) -> bool: ... + def get_edgecolor(self) -> ColorType: ... + def get_facecolor(self) -> ColorType: ... + def get_linewidth(self) -> float: ... + def get_linestyle(self) -> LineStyleType: ... + def set_antialiased(self, aa: bool | None) -> None: ... + def set_edgecolor(self, color: ColorType | None) -> None: ... + def set_facecolor(self, color: ColorType | None) -> None: ... + def set_color(self, c: ColorType | None) -> None: ... + def set_alpha(self, alpha: float | None) -> None: ... + def set_linewidth(self, w: float | None) -> None: ... + def set_linestyle(self, ls: LineStyleType | None) -> None: ... + def set_fill(self, b: bool) -> None: ... + def get_fill(self) -> bool: ... + fill = property(get_fill, set_fill) + def set_capstyle(self, s: CapStyleType) -> None: ... + def get_capstyle(self) -> Literal["butt", "projecting", "round"]: ... + def set_joinstyle(self, s: JoinStyleType) -> None: ... + def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ... + def set_hatch(self, hatch: str) -> None: ... + def get_hatch(self) -> str: ... + def get_path(self) -> Path: ... + +class Shadow(Patch): + patch: Patch + def __init__(self, patch: Patch, ox: float, oy: float, *, shade: float = ..., **kwargs) -> None: ... + +class Rectangle(Patch): + angle: float + def __init__( + self, + xy: tuple[float, float], + width: float, + height: float, + *, + angle: float = ..., + rotation_point: Literal["xy", "center"] | tuple[float, float] = ..., + **kwargs, + ) -> None: ... + @property + def rotation_point(self) -> Literal["xy", "center"] | tuple[float, float]: ... + @rotation_point.setter + def rotation_point( + self, value: Literal["xy", "center"] | tuple[float, float] + ) -> None: ... + def get_x(self) -> float: ... + def get_y(self) -> float: ... + def get_xy(self) -> tuple[float, float]: ... + def get_corners(self) -> np.ndarray: ... + def get_center(self) -> np.ndarray: ... + def get_width(self) -> float: ... + def get_height(self) -> float: ... + def get_angle(self) -> float: ... + def set_x(self, x: float) -> None: ... + def set_y(self, y: float) -> None: ... + def set_angle(self, angle: float) -> None: ... + def set_xy(self, xy: tuple[float, float]) -> None: ... + def set_width(self, w: float) -> None: ... + def set_height(self, h: float) -> None: ... + @overload + def set_bounds(self, args: tuple[float, float, float, float], /) -> None: ... + @overload + def set_bounds( + self, left: float, bottom: float, width: float, height: float, / + ) -> None: ... + def get_bbox(self) -> Bbox: ... + xy = property(get_xy, set_xy) + +class RegularPolygon(Patch): + xy: tuple[float, float] + numvertices: int + orientation: float + radius: float + def __init__( + self, + xy: tuple[float, float], + numVertices: int, + *, + radius: float = ..., + orientation: float = ..., + **kwargs, + ) -> None: ... + +class PathPatch(Patch): + def __init__(self, path: Path, **kwargs) -> None: ... + def set_path(self, path: Path) -> None: ... + +class StepPatch(PathPatch): + orientation: Literal["vertical", "horizontal"] + def __init__( + self, + values: ArrayLike, + edges: ArrayLike, + *, + orientation: Literal["vertical", "horizontal"] = ..., + baseline: float = ..., + **kwargs, + ) -> None: ... + + # NamedTuple StairData, defined in body of method + def get_data(self) -> tuple[np.ndarray, np.ndarray, float]: ... + def set_data( + self, + values: ArrayLike | None = ..., + edges: ArrayLike | None = ..., + baseline: float | None = ..., + ) -> None: ... + +class Polygon(Patch): + def __init__(self, xy: ArrayLike, *, closed: bool = ..., **kwargs) -> None: ... + def get_closed(self) -> bool: ... + def set_closed(self, closed: bool) -> None: ... + def get_xy(self) -> np.ndarray: ... + def set_xy(self, xy: ArrayLike) -> None: ... + xy = property(get_xy, set_xy) + +class Wedge(Patch): + center: tuple[float, float] + r: float + theta1: float + theta2: float + width: float | None + def __init__( + self, + center: tuple[float, float], + r: float, + theta1: float, + theta2: float, + *, + width: float | None = ..., + **kwargs, + ) -> None: ... + def set_center(self, center: tuple[float, float]) -> None: ... + def set_radius(self, radius: float) -> None: ... + def set_theta1(self, theta1: float) -> None: ... + def set_theta2(self, theta2: float) -> None: ... + def set_width(self, width: float | None) -> None: ... + +class Arrow(Patch): + def __init__( + self, x: float, y: float, dx: float, dy: float, *, width: float = ..., **kwargs + ) -> None: ... + +class FancyArrow(Polygon): + def __init__( + self, + x: float, + y: float, + dx: float, + dy: float, + *, + width: float = ..., + length_includes_head: bool = ..., + head_width: float | None = ..., + head_length: float | None = ..., + shape: Literal["full", "left", "right"] = ..., + overhang: float = ..., + head_starts_at_zero: bool = ..., + **kwargs, + ) -> None: ... + def set_data( + self, + *, + x: float | None = ..., + y: float | None = ..., + dx: float | None = ..., + dy: float | None = ..., + width: float | None = ..., + head_width: float | None = ..., + head_length: float | None = ..., + ) -> None: ... + +class CirclePolygon(RegularPolygon): + def __init__( + self, + xy: tuple[float, float], + radius: float = ..., + *, + resolution: int = ..., + **kwargs, + ) -> None: ... + +class Ellipse(Patch): + def __init__( + self, + xy: tuple[float, float], + width: float, + height: float, + *, + angle: float = ..., + **kwargs, + ) -> None: ... + def set_center(self, xy: tuple[float, float]) -> None: ... + def get_center(self) -> float: ... + center = property(get_center, set_center) + + def set_width(self, width: float) -> None: ... + def get_width(self) -> float: ... + width = property(get_width, set_width) + + def set_height(self, height: float) -> None: ... + def get_height(self) -> float: ... + height = property(get_height, set_height) + + def set_angle(self, angle: float) -> None: ... + def get_angle(self) -> float: ... + angle = property(get_angle, set_angle) + + def get_corners(self) -> np.ndarray: ... + + def get_vertices(self) -> list[tuple[float, float]]: ... + def get_co_vertices(self) -> list[tuple[float, float]]: ... + + +class Annulus(Patch): + a: float + b: float + def __init__( + self, + xy: tuple[float, float], + r: float | tuple[float, float], + width: float, + angle: float = ..., + **kwargs, + ) -> None: ... + def set_center(self, xy: tuple[float, float]) -> None: ... + def get_center(self) -> tuple[float, float]: ... + center = property(get_center, set_center) + + def set_width(self, width: float) -> None: ... + def get_width(self) -> float: ... + width = property(get_width, set_width) + + def set_angle(self, angle: float) -> None: ... + def get_angle(self) -> float: ... + angle = property(get_angle, set_angle) + + def set_semimajor(self, a: float) -> None: ... + def set_semiminor(self, b: float) -> None: ... + def set_radii(self, r: float | tuple[float, float]) -> None: ... + def get_radii(self) -> tuple[float, float]: ... + radii = property(get_radii, set_radii) + +class Circle(Ellipse): + def __init__( + self, xy: tuple[float, float], radius: float = ..., **kwargs + ) -> None: ... + def set_radius(self, radius: float) -> None: ... + def get_radius(self) -> float: ... + radius = property(get_radius, set_radius) + +class Arc(Ellipse): + theta1: float + theta2: float + def __init__( + self, + xy: tuple[float, float], + width: float, + height: float, + *, + angle: float = ..., + theta1: float = ..., + theta2: float = ..., + **kwargs, + ) -> None: ... + +def bbox_artist( + artist: artist.Artist, + renderer: RendererBase, + props: dict[str, Any] | None = ..., + fill: bool = ..., +) -> None: ... +def draw_bbox( + bbox: Bbox, + renderer: RendererBase, + color: ColorType = ..., + trans: Transform | None = ..., +) -> None: ... + +class _Style: + def __new__(cls, stylename, **kwargs): ... + @classmethod + def get_styles(cls) -> dict[str, type]: ... + @classmethod + def pprint_styles(cls) -> str: ... + @classmethod + def register(cls, name: str, style: type) -> None: ... + +class BoxStyle(_Style): + class Square(BoxStyle): + pad: float + def __init__(self, pad: float = ...) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Circle(BoxStyle): + pad: float + def __init__(self, pad: float = ...) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Ellipse(BoxStyle): + pad: float + def __init__(self, pad: float = ...) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class LArrow(BoxStyle): + pad: float + def __init__(self, pad: float = ...) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class RArrow(LArrow): + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class DArrow(BoxStyle): + pad: float + def __init__(self, pad: float = ...) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Round(BoxStyle): + pad: float + rounding_size: float | None + def __init__( + self, pad: float = ..., rounding_size: float | None = ... + ) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Round4(BoxStyle): + pad: float + rounding_size: float | None + def __init__( + self, pad: float = ..., rounding_size: float | None = ... + ) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Sawtooth(BoxStyle): + pad: float + tooth_size: float | None + def __init__( + self, pad: float = ..., tooth_size: float | None = ... + ) -> None: ... + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + + class Roundtooth(Sawtooth): + def __call__( + self, + x0: float, + y0: float, + width: float, + height: float, + mutation_size: float, + ) -> Path: ... + +class ConnectionStyle(_Style): + class _Base(ConnectionStyle): + class SimpleEvent: + def __init__(self, xy: tuple[float, float]) -> None: ... + + def __call__( + self, + posA: tuple[float, float], + posB: tuple[float, float], + shrinkA: float = ..., + shrinkB: float = ..., + patchA: Patch | None = ..., + patchB: Patch | None = ..., + ) -> Path: ... + + class Arc3(_Base): + rad: float + def __init__(self, rad: float = ...) -> None: ... + def connect( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> Path: ... + + class Angle3(_Base): + angleA: float + angleB: float + def __init__(self, angleA: float = ..., angleB: float = ...) -> None: ... + def connect( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> Path: ... + + class Angle(_Base): + angleA: float + angleB: float + rad: float + def __init__( + self, angleA: float = ..., angleB: float = ..., rad: float = ... + ) -> None: ... + def connect( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> Path: ... + + class Arc(_Base): + angleA: float + angleB: float + armA: float | None + armB: float | None + rad: float + def __init__( + self, + angleA: float = ..., + angleB: float = ..., + armA: float | None = ..., + armB: float | None = ..., + rad: float = ..., + ) -> None: ... + def connect( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> Path: ... + + class Bar(_Base): + armA: float + armB: float + fraction: float + angle: float | None + def __init__( + self, + armA: float = ..., + armB: float = ..., + fraction: float = ..., + angle: float | None = ..., + ) -> None: ... + def connect( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> Path: ... + +class ArrowStyle(_Style): + class _Base(ArrowStyle): + @staticmethod + def ensure_quadratic_bezier(path: Path) -> list[float]: ... + def transmute( + self, path: Path, mutation_size: float, linewidth: float + ) -> tuple[Path, bool]: ... + def __call__( + self, + path: Path, + mutation_size: float, + linewidth: float, + aspect_ratio: float = ..., + ) -> tuple[Path, bool]: ... + + class _Curve(_Base): + arrow: str + fillbegin: bool + fillend: bool + def __init__( + self, + head_length: float = ..., + head_width: float = ..., + widthA: float = ..., + widthB: float = ..., + lengthA: float = ..., + lengthB: float = ..., + angleA: float | None = ..., + angleB: float | None = ..., + scaleA: float | None = ..., + scaleB: float | None = ..., + ) -> None: ... + + class Curve(_Curve): + def __init__(self) -> None: ... + + class CurveA(_Curve): + arrow: str + + class CurveB(_Curve): + arrow: str + + class CurveAB(_Curve): + arrow: str + + class CurveFilledA(_Curve): + arrow: str + + class CurveFilledB(_Curve): + arrow: str + + class CurveFilledAB(_Curve): + arrow: str + + class BracketA(_Curve): + arrow: str + def __init__( + self, widthA: float = ..., lengthA: float = ..., angleA: float = ... + ) -> None: ... + + class BracketB(_Curve): + arrow: str + def __init__( + self, widthB: float = ..., lengthB: float = ..., angleB: float = ... + ) -> None: ... + + class BracketAB(_Curve): + arrow: str + def __init__( + self, + widthA: float = ..., + lengthA: float = ..., + angleA: float = ..., + widthB: float = ..., + lengthB: float = ..., + angleB: float = ..., + ) -> None: ... + + class BarAB(_Curve): + arrow: str + def __init__( + self, + widthA: float = ..., + angleA: float = ..., + widthB: float = ..., + angleB: float = ..., + ) -> None: ... + + class BracketCurve(_Curve): + arrow: str + def __init__( + self, widthA: float = ..., lengthA: float = ..., angleA: float | None = ... + ) -> None: ... + + class CurveBracket(_Curve): + arrow: str + def __init__( + self, widthB: float = ..., lengthB: float = ..., angleB: float | None = ... + ) -> None: ... + + class Simple(_Base): + def __init__( + self, + head_length: float = ..., + head_width: float = ..., + tail_width: float = ..., + ) -> None: ... + + class Fancy(_Base): + def __init__( + self, + head_length: float = ..., + head_width: float = ..., + tail_width: float = ..., + ) -> None: ... + + class Wedge(_Base): + tail_width: float + shrink_factor: float + def __init__( + self, tail_width: float = ..., shrink_factor: float = ... + ) -> None: ... + +class FancyBboxPatch(Patch): + def __init__( + self, + xy: tuple[float, float], + width: float, + height: float, + boxstyle: str | BoxStyle = ..., + *, + mutation_scale: float = ..., + mutation_aspect: float = ..., + **kwargs, + ) -> None: ... + def set_boxstyle(self, boxstyle: str | BoxStyle | None = ..., **kwargs) -> None: ... + def get_boxstyle(self) -> BoxStyle: ... + def set_mutation_scale(self, scale: float) -> None: ... + def get_mutation_scale(self) -> float: ... + def set_mutation_aspect(self, aspect: float) -> None: ... + def get_mutation_aspect(self) -> float: ... + def get_x(self) -> float: ... + def get_y(self) -> float: ... + def get_width(self) -> float: ... + def get_height(self) -> float: ... + def set_x(self, x: float) -> None: ... + def set_y(self, y: float) -> None: ... + def set_width(self, w: float) -> None: ... + def set_height(self, h: float) -> None: ... + @overload + def set_bounds(self, args: tuple[float, float, float, float], /) -> None: ... + @overload + def set_bounds( + self, left: float, bottom: float, width: float, height: float, / + ) -> None: ... + def get_bbox(self) -> Bbox: ... + +class FancyArrowPatch(Patch): + patchA: Patch + patchB: Patch + shrinkA: float + shrinkB: float + def __init__( + self, + posA: tuple[float, float] | None = ..., + posB: tuple[float, float] | None = ..., + *, + path: Path | None = ..., + arrowstyle: str | ArrowStyle = ..., + connectionstyle: str | ConnectionStyle = ..., + patchA: Patch | None = ..., + patchB: Patch | None = ..., + shrinkA: float = ..., + shrinkB: float = ..., + mutation_scale: float = ..., + mutation_aspect: float | None = ..., + **kwargs, + ) -> None: ... + def set_positions( + self, posA: tuple[float, float], posB: tuple[float, float] + ) -> None: ... + def set_patchA(self, patchA: Patch) -> None: ... + def set_patchB(self, patchB: Patch) -> None: ... + def set_connectionstyle(self, connectionstyle: str | ConnectionStyle | None = ..., **kwargs) -> None: ... + def get_connectionstyle(self) -> ConnectionStyle: ... + def set_arrowstyle(self, arrowstyle: str | ArrowStyle | None = ..., **kwargs) -> None: ... + def get_arrowstyle(self) -> ArrowStyle: ... + def set_mutation_scale(self, scale: float) -> None: ... + def get_mutation_scale(self) -> float: ... + def set_mutation_aspect(self, aspect: float | None) -> None: ... + def get_mutation_aspect(self) -> float: ... + +class ConnectionPatch(FancyArrowPatch): + xy1: tuple[float, float] + xy2: tuple[float, float] + coords1: str | Transform + coords2: str | Transform | None + axesA: Axes | None + axesB: Axes | None + def __init__( + self, + xyA: tuple[float, float], + xyB: tuple[float, float], + coordsA: str | Transform, + coordsB: str | Transform | None = ..., + *, + axesA: Axes | None = ..., + axesB: Axes | None = ..., + arrowstyle: str | ArrowStyle = ..., + connectionstyle: str | ConnectionStyle = ..., + patchA: Patch | None = ..., + patchB: Patch | None = ..., + shrinkA: float = ..., + shrinkB: float = ..., + mutation_scale: float = ..., + mutation_aspect: float | None = ..., + clip_on: bool = ..., + **kwargs, + ) -> None: ... + def set_annotation_clip(self, b: bool | None) -> None: ... + def get_annotation_clip(self) -> bool | None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.py new file mode 100644 index 00000000..e72eb1a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.py @@ -0,0 +1,1093 @@ +r""" +A module for dealing with the polylines used throughout Matplotlib. + +The primary class for polyline handling in Matplotlib is `Path`. Almost all +vector drawing makes use of `Path`\s somewhere in the drawing pipeline. + +Whilst a `Path` instance itself cannot be drawn, some `.Artist` subclasses, +such as `.PathPatch` and `.PathCollection`, can be used for convenient `Path` +visualisation. +""" + +import copy +from functools import lru_cache +from weakref import WeakValueDictionary + +import numpy as np + +import matplotlib as mpl +from . import _api, _path +from .cbook import _to_unmasked_float_array, simple_linear_interpolation +from .bezier import BezierSegment + + +class Path: + """ + A series of possibly disconnected, possibly closed, line and curve + segments. + + The underlying storage is made up of two parallel numpy arrays: + + - *vertices*: an (N, 2) float array of vertices + - *codes*: an N-length `numpy.uint8` array of path codes, or None + + These two arrays always have the same length in the first + dimension. For example, to represent a cubic curve, you must + provide three vertices and three `CURVE4` codes. + + The code types are: + + - `STOP` : 1 vertex (ignored) + A marker for the end of the entire path (currently not required and + ignored) + + - `MOVETO` : 1 vertex + Pick up the pen and move to the given vertex. + + - `LINETO` : 1 vertex + Draw a line from the current position to the given vertex. + + - `CURVE3` : 1 control point, 1 endpoint + Draw a quadratic Bézier curve from the current position, with the given + control point, to the given end point. + + - `CURVE4` : 2 control points, 1 endpoint + Draw a cubic Bézier curve from the current position, with the given + control points, to the given end point. + + - `CLOSEPOLY` : 1 vertex (ignored) + Draw a line segment to the start point of the current polyline. + + If *codes* is None, it is interpreted as a `MOVETO` followed by a series + of `LINETO`. + + Users of Path objects should not access the vertices and codes arrays + directly. Instead, they should use `iter_segments` or `cleaned` to get the + vertex/code pairs. This helps, in particular, to consistently handle the + case of *codes* being None. + + Some behavior of Path objects can be controlled by rcParams. See the + rcParams whose keys start with 'path.'. + + .. note:: + + The vertices and codes arrays should be treated as + immutable -- there are a number of optimizations and assumptions + made up front in the constructor that will not change when the + data changes. + """ + + code_type = np.uint8 + + # Path codes + STOP = code_type(0) # 1 vertex + MOVETO = code_type(1) # 1 vertex + LINETO = code_type(2) # 1 vertex + CURVE3 = code_type(3) # 2 vertices + CURVE4 = code_type(4) # 3 vertices + CLOSEPOLY = code_type(79) # 1 vertex + + #: A dictionary mapping Path codes to the number of vertices that the + #: code expects. + NUM_VERTICES_FOR_CODE = {STOP: 1, + MOVETO: 1, + LINETO: 1, + CURVE3: 2, + CURVE4: 3, + CLOSEPOLY: 1} + + def __init__(self, vertices, codes=None, _interpolation_steps=1, + closed=False, readonly=False): + """ + Create a new path with the given vertices and codes. + + Parameters + ---------- + vertices : (N, 2) array-like + The path vertices, as an array, masked array or sequence of pairs. + Masked values, if any, will be converted to NaNs, which are then + handled correctly by the Agg PathIterator and other consumers of + path data, such as :meth:`iter_segments`. + codes : array-like or None, optional + N-length array of integers representing the codes of the path. + If not None, codes must be the same length as vertices. + If None, *vertices* will be treated as a series of line segments. + _interpolation_steps : int, optional + Used as a hint to certain projections, such as Polar, that this + path should be linearly interpolated immediately before drawing. + This attribute is primarily an implementation detail and is not + intended for public use. + closed : bool, optional + If *codes* is None and closed is True, vertices will be treated as + line segments of a closed polygon. Note that the last vertex will + then be ignored (as the corresponding code will be set to + `CLOSEPOLY`). + readonly : bool, optional + Makes the path behave in an immutable way and sets the vertices + and codes as read-only arrays. + """ + vertices = _to_unmasked_float_array(vertices) + _api.check_shape((None, 2), vertices=vertices) + + if codes is not None: + codes = np.asarray(codes, self.code_type) + if codes.ndim != 1 or len(codes) != len(vertices): + raise ValueError("'codes' must be a 1D list or array with the " + "same length of 'vertices'. " + f"Your vertices have shape {vertices.shape} " + f"but your codes have shape {codes.shape}") + if len(codes) and codes[0] != self.MOVETO: + raise ValueError("The first element of 'code' must be equal " + f"to 'MOVETO' ({self.MOVETO}). " + f"Your first code is {codes[0]}") + elif closed and len(vertices): + codes = np.empty(len(vertices), dtype=self.code_type) + codes[0] = self.MOVETO + codes[1:-1] = self.LINETO + codes[-1] = self.CLOSEPOLY + + self._vertices = vertices + self._codes = codes + self._interpolation_steps = _interpolation_steps + self._update_values() + + if readonly: + self._vertices.flags.writeable = False + if self._codes is not None: + self._codes.flags.writeable = False + self._readonly = True + else: + self._readonly = False + + @classmethod + def _fast_from_codes_and_verts(cls, verts, codes, internals_from=None): + """ + Create a Path instance without the expense of calling the constructor. + + Parameters + ---------- + verts : array-like + codes : array + internals_from : Path or None + If not None, another `Path` from which the attributes + ``should_simplify``, ``simplify_threshold``, and + ``interpolation_steps`` will be copied. Note that ``readonly`` is + never copied, and always set to ``False`` by this constructor. + """ + pth = cls.__new__(cls) + pth._vertices = _to_unmasked_float_array(verts) + pth._codes = codes + pth._readonly = False + if internals_from is not None: + pth._should_simplify = internals_from._should_simplify + pth._simplify_threshold = internals_from._simplify_threshold + pth._interpolation_steps = internals_from._interpolation_steps + else: + pth._should_simplify = True + pth._simplify_threshold = mpl.rcParams['path.simplify_threshold'] + pth._interpolation_steps = 1 + return pth + + @classmethod + def _create_closed(cls, vertices): + """ + Create a closed polygonal path going through *vertices*. + + Unlike ``Path(..., closed=True)``, *vertices* should **not** end with + an entry for the CLOSEPATH; this entry is added by `._create_closed`. + """ + v = _to_unmasked_float_array(vertices) + return cls(np.concatenate([v, v[:1]]), closed=True) + + def _update_values(self): + self._simplify_threshold = mpl.rcParams['path.simplify_threshold'] + self._should_simplify = ( + self._simplify_threshold > 0 and + mpl.rcParams['path.simplify'] and + len(self._vertices) >= 128 and + (self._codes is None or np.all(self._codes <= Path.LINETO)) + ) + + @property + def vertices(self): + """The vertices of the `Path` as an (N, 2) array.""" + return self._vertices + + @vertices.setter + def vertices(self, vertices): + if self._readonly: + raise AttributeError("Can't set vertices on a readonly Path") + self._vertices = vertices + self._update_values() + + @property + def codes(self): + """ + The list of codes in the `Path` as a 1D array. + + Each code is one of `STOP`, `MOVETO`, `LINETO`, `CURVE3`, `CURVE4` or + `CLOSEPOLY`. For codes that correspond to more than one vertex + (`CURVE3` and `CURVE4`), that code will be repeated so that the length + of `vertices` and `codes` is always the same. + """ + return self._codes + + @codes.setter + def codes(self, codes): + if self._readonly: + raise AttributeError("Can't set codes on a readonly Path") + self._codes = codes + self._update_values() + + @property + def simplify_threshold(self): + """ + The fraction of a pixel difference below which vertices will + be simplified out. + """ + return self._simplify_threshold + + @simplify_threshold.setter + def simplify_threshold(self, threshold): + self._simplify_threshold = threshold + + @property + def should_simplify(self): + """ + `True` if the vertices array should be simplified. + """ + return self._should_simplify + + @should_simplify.setter + def should_simplify(self, should_simplify): + self._should_simplify = should_simplify + + @property + def readonly(self): + """ + `True` if the `Path` is read-only. + """ + return self._readonly + + def copy(self): + """ + Return a shallow copy of the `Path`, which will share the + vertices and codes with the source `Path`. + """ + return copy.copy(self) + + def __deepcopy__(self, memo=None): + """ + Return a deepcopy of the `Path`. The `Path` will not be + readonly, even if the source `Path` is. + """ + # Deepcopying arrays (vertices, codes) strips the writeable=False flag. + p = copy.deepcopy(super(), memo) + p._readonly = False + return p + + deepcopy = __deepcopy__ + + @classmethod + def make_compound_path_from_polys(cls, XY): + """ + Make a compound `Path` object to draw a number of polygons with equal + numbers of sides. + + .. plot:: gallery/misc/histogram_path.py + + Parameters + ---------- + XY : (numpolys, numsides, 2) array + """ + # for each poly: 1 for the MOVETO, (numsides-1) for the LINETO, 1 for + # the CLOSEPOLY; the vert for the closepoly is ignored but we still + # need it to keep the codes aligned with the vertices + numpolys, numsides, two = XY.shape + if two != 2: + raise ValueError("The third dimension of 'XY' must be 2") + stride = numsides + 1 + nverts = numpolys * stride + verts = np.zeros((nverts, 2)) + codes = np.full(nverts, cls.LINETO, dtype=cls.code_type) + codes[0::stride] = cls.MOVETO + codes[numsides::stride] = cls.CLOSEPOLY + for i in range(numsides): + verts[i::stride] = XY[:, i] + return cls(verts, codes) + + @classmethod + def make_compound_path(cls, *args): + r""" + Concatenate a list of `Path`\s into a single `Path`, removing all `STOP`\s. + """ + if not args: + return Path(np.empty([0, 2], dtype=np.float32)) + vertices = np.concatenate([path.vertices for path in args]) + codes = np.empty(len(vertices), dtype=cls.code_type) + i = 0 + for path in args: + size = len(path.vertices) + if path.codes is None: + if size: + codes[i] = cls.MOVETO + codes[i+1:i+size] = cls.LINETO + else: + codes[i:i+size] = path.codes + i += size + not_stop_mask = codes != cls.STOP # Remove STOPs, as internal STOPs are a bug. + return cls(vertices[not_stop_mask], codes[not_stop_mask]) + + def __repr__(self): + return f"Path({self.vertices!r}, {self.codes!r})" + + def __len__(self): + return len(self.vertices) + + def iter_segments(self, transform=None, remove_nans=True, clip=None, + snap=False, stroke_width=1.0, simplify=None, + curves=True, sketch=None): + """ + Iterate over all curve segments in the path. + + Each iteration returns a pair ``(vertices, code)``, where ``vertices`` + is a sequence of 1-3 coordinate pairs, and ``code`` is a `Path` code. + + Additionally, this method can provide a number of standard cleanups and + conversions to the path. + + Parameters + ---------- + transform : None or :class:`~matplotlib.transforms.Transform` + If not None, the given affine transformation will be applied to the + path. + remove_nans : bool, optional + Whether to remove all NaNs from the path and skip over them using + MOVETO commands. + clip : None or (float, float, float, float), optional + If not None, must be a four-tuple (x1, y1, x2, y2) + defining a rectangle in which to clip the path. + snap : None or bool, optional + If True, snap all nodes to pixels; if False, don't snap them. + If None, snap if the path contains only segments + parallel to the x or y axes, and no more than 1024 of them. + stroke_width : float, optional + The width of the stroke being drawn (used for path snapping). + simplify : None or bool, optional + Whether to simplify the path by removing vertices + that do not affect its appearance. If None, use the + :attr:`should_simplify` attribute. See also :rc:`path.simplify` + and :rc:`path.simplify_threshold`. + curves : bool, optional + If True, curve segments will be returned as curve segments. + If False, all curves will be converted to line segments. + sketch : None or sequence, optional + If not None, must be a 3-tuple of the form + (scale, length, randomness), representing the sketch parameters. + """ + if not len(self): + return + + cleaned = self.cleaned(transform=transform, + remove_nans=remove_nans, clip=clip, + snap=snap, stroke_width=stroke_width, + simplify=simplify, curves=curves, + sketch=sketch) + + # Cache these object lookups for performance in the loop. + NUM_VERTICES_FOR_CODE = self.NUM_VERTICES_FOR_CODE + STOP = self.STOP + + vertices = iter(cleaned.vertices) + codes = iter(cleaned.codes) + for curr_vertices, code in zip(vertices, codes): + if code == STOP: + break + extra_vertices = NUM_VERTICES_FOR_CODE[code] - 1 + if extra_vertices: + for i in range(extra_vertices): + next(codes) + curr_vertices = np.append(curr_vertices, next(vertices)) + yield curr_vertices, code + + def iter_bezier(self, **kwargs): + """ + Iterate over each Bézier curve (lines included) in a `Path`. + + Parameters + ---------- + **kwargs + Forwarded to `.iter_segments`. + + Yields + ------ + B : `~matplotlib.bezier.BezierSegment` + The Bézier curves that make up the current path. Note in particular + that freestanding points are Bézier curves of order 0, and lines + are Bézier curves of order 1 (with two control points). + code : `~matplotlib.path.Path.code_type` + The code describing what kind of curve is being returned. + `MOVETO`, `LINETO`, `CURVE3`, and `CURVE4` correspond to + Bézier curves with 1, 2, 3, and 4 control points (respectively). + `CLOSEPOLY` is a `LINETO` with the control points correctly + chosen based on the start/end points of the current stroke. + """ + first_vert = None + prev_vert = None + for verts, code in self.iter_segments(**kwargs): + if first_vert is None: + if code != Path.MOVETO: + raise ValueError("Malformed path, must start with MOVETO.") + if code == Path.MOVETO: # a point is like "CURVE1" + first_vert = verts + yield BezierSegment(np.array([first_vert])), code + elif code == Path.LINETO: # "CURVE2" + yield BezierSegment(np.array([prev_vert, verts])), code + elif code == Path.CURVE3: + yield BezierSegment(np.array([prev_vert, verts[:2], + verts[2:]])), code + elif code == Path.CURVE4: + yield BezierSegment(np.array([prev_vert, verts[:2], + verts[2:4], verts[4:]])), code + elif code == Path.CLOSEPOLY: + yield BezierSegment(np.array([prev_vert, first_vert])), code + elif code == Path.STOP: + return + else: + raise ValueError(f"Invalid Path.code_type: {code}") + prev_vert = verts[-2:] + + def _iter_connected_components(self): + """Return subpaths split at MOVETOs.""" + if self.codes is None: + yield self + else: + idxs = np.append((self.codes == Path.MOVETO).nonzero()[0], len(self.codes)) + for sl in map(slice, idxs, idxs[1:]): + yield Path._fast_from_codes_and_verts( + self.vertices[sl], self.codes[sl], self) + + def cleaned(self, transform=None, remove_nans=False, clip=None, + *, simplify=False, curves=False, + stroke_width=1.0, snap=False, sketch=None): + """ + Return a new `Path` with vertices and codes cleaned according to the + parameters. + + See Also + -------- + Path.iter_segments : for details of the keyword arguments. + """ + vertices, codes = _path.cleanup_path( + self, transform, remove_nans, clip, snap, stroke_width, simplify, + curves, sketch) + pth = Path._fast_from_codes_and_verts(vertices, codes, self) + if not simplify: + pth._should_simplify = False + return pth + + def transformed(self, transform): + """ + Return a transformed copy of the path. + + See Also + -------- + matplotlib.transforms.TransformedPath + A specialized path class that will cache the transformed result and + automatically update when the transform changes. + """ + return Path(transform.transform(self.vertices), self.codes, + self._interpolation_steps) + + def contains_point(self, point, transform=None, radius=0.0): + """ + Return whether the area enclosed by the path contains the given point. + + The path is always treated as closed; i.e. if the last code is not + `CLOSEPOLY` an implicit segment connecting the last vertex to the first + vertex is assumed. + + Parameters + ---------- + point : (float, float) + The point (x, y) to check. + transform : `~matplotlib.transforms.Transform`, optional + If not ``None``, *point* will be compared to ``self`` transformed + by *transform*; i.e. for a correct check, *transform* should + transform the path into the coordinate system of *point*. + radius : float, default: 0 + Additional margin on the path in coordinates of *point*. + The path is extended tangentially by *radius/2*; i.e. if you would + draw the path with a linewidth of *radius*, all points on the line + would still be considered to be contained in the area. Conversely, + negative values shrink the area: Points on the imaginary line + will be considered outside the area. + + Returns + ------- + bool + + Notes + ----- + The current algorithm has some limitations: + + - The result is undefined for points exactly at the boundary + (i.e. at the path shifted by *radius/2*). + - The result is undefined if there is no enclosed area, i.e. all + vertices are on a straight line. + - If bounding lines start to cross each other due to *radius* shift, + the result is not guaranteed to be correct. + """ + if transform is not None: + transform = transform.frozen() + # `point_in_path` does not handle nonlinear transforms, so we + # transform the path ourselves. If *transform* is affine, letting + # `point_in_path` handle the transform avoids allocating an extra + # buffer. + if transform and not transform.is_affine: + self = transform.transform_path(self) + transform = None + return _path.point_in_path(point[0], point[1], radius, self, transform) + + def contains_points(self, points, transform=None, radius=0.0): + """ + Return whether the area enclosed by the path contains the given points. + + The path is always treated as closed; i.e. if the last code is not + `CLOSEPOLY` an implicit segment connecting the last vertex to the first + vertex is assumed. + + Parameters + ---------- + points : (N, 2) array + The points to check. Columns contain x and y values. + transform : `~matplotlib.transforms.Transform`, optional + If not ``None``, *points* will be compared to ``self`` transformed + by *transform*; i.e. for a correct check, *transform* should + transform the path into the coordinate system of *points*. + radius : float, default: 0 + Additional margin on the path in coordinates of *points*. + The path is extended tangentially by *radius/2*; i.e. if you would + draw the path with a linewidth of *radius*, all points on the line + would still be considered to be contained in the area. Conversely, + negative values shrink the area: Points on the imaginary line + will be considered outside the area. + + Returns + ------- + length-N bool array + + Notes + ----- + The current algorithm has some limitations: + + - The result is undefined for points exactly at the boundary + (i.e. at the path shifted by *radius/2*). + - The result is undefined if there is no enclosed area, i.e. all + vertices are on a straight line. + - If bounding lines start to cross each other due to *radius* shift, + the result is not guaranteed to be correct. + """ + if transform is not None: + transform = transform.frozen() + result = _path.points_in_path(points, radius, self, transform) + return result.astype('bool') + + def contains_path(self, path, transform=None): + """ + Return whether this (closed) path completely contains the given path. + + If *transform* is not ``None``, the path will be transformed before + checking for containment. + """ + if transform is not None: + transform = transform.frozen() + return _path.path_in_path(self, None, path, transform) + + def get_extents(self, transform=None, **kwargs): + """ + Get Bbox of the path. + + Parameters + ---------- + transform : `~matplotlib.transforms.Transform`, optional + Transform to apply to path before computing extents, if any. + **kwargs + Forwarded to `.iter_bezier`. + + Returns + ------- + matplotlib.transforms.Bbox + The extents of the path Bbox([[xmin, ymin], [xmax, ymax]]) + """ + from .transforms import Bbox + if transform is not None: + self = transform.transform_path(self) + if self.codes is None: + xys = self.vertices + elif len(np.intersect1d(self.codes, [Path.CURVE3, Path.CURVE4])) == 0: + # Optimization for the straight line case. + # Instead of iterating through each curve, consider + # each line segment's end-points + # (recall that STOP and CLOSEPOLY vertices are ignored) + xys = self.vertices[np.isin(self.codes, + [Path.MOVETO, Path.LINETO])] + else: + xys = [] + for curve, code in self.iter_bezier(**kwargs): + # places where the derivative is zero can be extrema + _, dzeros = curve.axis_aligned_extrema() + # as can the ends of the curve + xys.append(curve([0, *dzeros, 1])) + xys = np.concatenate(xys) + if len(xys): + return Bbox([xys.min(axis=0), xys.max(axis=0)]) + else: + return Bbox.null() + + def intersects_path(self, other, filled=True): + """ + Return whether if this path intersects another given path. + + If *filled* is True, then this also returns True if one path completely + encloses the other (i.e., the paths are treated as filled). + """ + return _path.path_intersects_path(self, other, filled) + + def intersects_bbox(self, bbox, filled=True): + """ + Return whether this path intersects a given `~.transforms.Bbox`. + + If *filled* is True, then this also returns True if the path completely + encloses the `.Bbox` (i.e., the path is treated as filled). + + The bounding box is always considered filled. + """ + return _path.path_intersects_rectangle( + self, bbox.x0, bbox.y0, bbox.x1, bbox.y1, filled) + + def interpolated(self, steps): + """ + Return a new path resampled to length N x *steps*. + + Codes other than `LINETO` are not handled correctly. + """ + if steps == 1: + return self + + vertices = simple_linear_interpolation(self.vertices, steps) + codes = self.codes + if codes is not None: + new_codes = np.full((len(codes) - 1) * steps + 1, Path.LINETO, + dtype=self.code_type) + new_codes[0::steps] = codes + else: + new_codes = None + return Path(vertices, new_codes) + + def to_polygons(self, transform=None, width=0, height=0, closed_only=True): + """ + Convert this path to a list of polygons or polylines. Each + polygon/polyline is an (N, 2) array of vertices. In other words, + each polygon has no `MOVETO` instructions or curves. This + is useful for displaying in backends that do not support + compound paths or Bézier curves. + + If *width* and *height* are both non-zero then the lines will + be simplified so that vertices outside of (0, 0), (width, + height) will be clipped. + + If *closed_only* is `True` (default), only closed polygons, + with the last point being the same as the first point, will be + returned. Any unclosed polylines in the path will be + explicitly closed. If *closed_only* is `False`, any unclosed + polygons in the path will be returned as unclosed polygons, + and the closed polygons will be returned explicitly closed by + setting the last point to the same as the first point. + """ + if len(self.vertices) == 0: + return [] + + if transform is not None: + transform = transform.frozen() + + if self.codes is None and (width == 0 or height == 0): + vertices = self.vertices + if closed_only: + if len(vertices) < 3: + return [] + elif np.any(vertices[0] != vertices[-1]): + vertices = [*vertices, vertices[0]] + + if transform is None: + return [vertices] + else: + return [transform.transform(vertices)] + + # Deal with the case where there are curves and/or multiple + # subpaths (using extension code) + return _path.convert_path_to_polygons( + self, transform, width, height, closed_only) + + _unit_rectangle = None + + @classmethod + def unit_rectangle(cls): + """ + Return a `Path` instance of the unit rectangle from (0, 0) to (1, 1). + """ + if cls._unit_rectangle is None: + cls._unit_rectangle = cls([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]], + closed=True, readonly=True) + return cls._unit_rectangle + + _unit_regular_polygons = WeakValueDictionary() + + @classmethod + def unit_regular_polygon(cls, numVertices): + """ + Return a :class:`Path` instance for a unit regular polygon with the + given *numVertices* such that the circumscribing circle has radius 1.0, + centered at (0, 0). + """ + if numVertices <= 16: + path = cls._unit_regular_polygons.get(numVertices) + else: + path = None + if path is None: + theta = ((2 * np.pi / numVertices) * np.arange(numVertices + 1) + # This initial rotation is to make sure the polygon always + # "points-up". + + np.pi / 2) + verts = np.column_stack((np.cos(theta), np.sin(theta))) + path = cls(verts, closed=True, readonly=True) + if numVertices <= 16: + cls._unit_regular_polygons[numVertices] = path + return path + + _unit_regular_stars = WeakValueDictionary() + + @classmethod + def unit_regular_star(cls, numVertices, innerCircle=0.5): + """ + Return a :class:`Path` for a unit regular star with the given + numVertices and radius of 1.0, centered at (0, 0). + """ + if numVertices <= 16: + path = cls._unit_regular_stars.get((numVertices, innerCircle)) + else: + path = None + if path is None: + ns2 = numVertices * 2 + theta = (2*np.pi/ns2 * np.arange(ns2 + 1)) + # This initial rotation is to make sure the polygon always + # "points-up" + theta += np.pi / 2.0 + r = np.ones(ns2 + 1) + r[1::2] = innerCircle + verts = (r * np.vstack((np.cos(theta), np.sin(theta)))).T + path = cls(verts, closed=True, readonly=True) + if numVertices <= 16: + cls._unit_regular_stars[(numVertices, innerCircle)] = path + return path + + @classmethod + def unit_regular_asterisk(cls, numVertices): + """ + Return a :class:`Path` for a unit regular asterisk with the given + numVertices and radius of 1.0, centered at (0, 0). + """ + return cls.unit_regular_star(numVertices, 0.0) + + _unit_circle = None + + @classmethod + def unit_circle(cls): + """ + Return the readonly :class:`Path` of the unit circle. + + For most cases, :func:`Path.circle` will be what you want. + """ + if cls._unit_circle is None: + cls._unit_circle = cls.circle(center=(0, 0), radius=1, + readonly=True) + return cls._unit_circle + + @classmethod + def circle(cls, center=(0., 0.), radius=1., readonly=False): + """ + Return a `Path` representing a circle of a given radius and center. + + Parameters + ---------- + center : (float, float), default: (0, 0) + The center of the circle. + radius : float, default: 1 + The radius of the circle. + readonly : bool + Whether the created path should have the "readonly" argument + set when creating the Path instance. + + Notes + ----- + The circle is approximated using 8 cubic Bézier curves, as described in + + Lancaster, Don. `Approximating a Circle or an Ellipse Using Four + Bezier Cubic Splines <https://www.tinaja.com/glib/ellipse4.pdf>`_. + """ + MAGIC = 0.2652031 + SQRTHALF = np.sqrt(0.5) + MAGIC45 = SQRTHALF * MAGIC + + vertices = np.array([[0.0, -1.0], + + [MAGIC, -1.0], + [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45], + [SQRTHALF, -SQRTHALF], + + [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45], + [1.0, -MAGIC], + [1.0, 0.0], + + [1.0, MAGIC], + [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45], + [SQRTHALF, SQRTHALF], + + [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45], + [MAGIC, 1.0], + [0.0, 1.0], + + [-MAGIC, 1.0], + [-SQRTHALF+MAGIC45, SQRTHALF+MAGIC45], + [-SQRTHALF, SQRTHALF], + + [-SQRTHALF-MAGIC45, SQRTHALF-MAGIC45], + [-1.0, MAGIC], + [-1.0, 0.0], + + [-1.0, -MAGIC], + [-SQRTHALF-MAGIC45, -SQRTHALF+MAGIC45], + [-SQRTHALF, -SQRTHALF], + + [-SQRTHALF+MAGIC45, -SQRTHALF-MAGIC45], + [-MAGIC, -1.0], + [0.0, -1.0], + + [0.0, -1.0]], + dtype=float) + + codes = [cls.CURVE4] * 26 + codes[0] = cls.MOVETO + codes[-1] = cls.CLOSEPOLY + return Path(vertices * radius + center, codes, readonly=readonly) + + _unit_circle_righthalf = None + + @classmethod + def unit_circle_righthalf(cls): + """ + Return a `Path` of the right half of a unit circle. + + See `Path.circle` for the reference on the approximation used. + """ + if cls._unit_circle_righthalf is None: + MAGIC = 0.2652031 + SQRTHALF = np.sqrt(0.5) + MAGIC45 = SQRTHALF * MAGIC + + vertices = np.array( + [[0.0, -1.0], + + [MAGIC, -1.0], + [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45], + [SQRTHALF, -SQRTHALF], + + [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45], + [1.0, -MAGIC], + [1.0, 0.0], + + [1.0, MAGIC], + [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45], + [SQRTHALF, SQRTHALF], + + [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45], + [MAGIC, 1.0], + [0.0, 1.0], + + [0.0, -1.0]], + + float) + + codes = np.full(14, cls.CURVE4, dtype=cls.code_type) + codes[0] = cls.MOVETO + codes[-1] = cls.CLOSEPOLY + + cls._unit_circle_righthalf = cls(vertices, codes, readonly=True) + return cls._unit_circle_righthalf + + @classmethod + def arc(cls, theta1, theta2, n=None, is_wedge=False): + """ + Return a `Path` for the unit circle arc from angles *theta1* to + *theta2* (in degrees). + + *theta2* is unwrapped to produce the shortest arc within 360 degrees. + That is, if *theta2* > *theta1* + 360, the arc will be from *theta1* to + *theta2* - 360 and not a full circle plus some extra overlap. + + If *n* is provided, it is the number of spline segments to make. + If *n* is not provided, the number of spline segments is + determined based on the delta between *theta1* and *theta2*. + + Masionobe, L. 2003. `Drawing an elliptical arc using + polylines, quadratic or cubic Bezier curves + <https://web.archive.org/web/20190318044212/http://www.spaceroots.org/documents/ellipse/index.html>`_. + """ + halfpi = np.pi * 0.5 + + eta1 = theta1 + eta2 = theta2 - 360 * np.floor((theta2 - theta1) / 360) + # Ensure 2pi range is not flattened to 0 due to floating-point errors, + # but don't try to expand existing 0 range. + if theta2 != theta1 and eta2 <= eta1: + eta2 += 360 + eta1, eta2 = np.deg2rad([eta1, eta2]) + + # number of curve segments to make + if n is None: + n = int(2 ** np.ceil((eta2 - eta1) / halfpi)) + if n < 1: + raise ValueError("n must be >= 1 or None") + + deta = (eta2 - eta1) / n + t = np.tan(0.5 * deta) + alpha = np.sin(deta) * (np.sqrt(4.0 + 3.0 * t * t) - 1) / 3.0 + + steps = np.linspace(eta1, eta2, n + 1, True) + cos_eta = np.cos(steps) + sin_eta = np.sin(steps) + + xA = cos_eta[:-1] + yA = sin_eta[:-1] + xA_dot = -yA + yA_dot = xA + + xB = cos_eta[1:] + yB = sin_eta[1:] + xB_dot = -yB + yB_dot = xB + + if is_wedge: + length = n * 3 + 4 + vertices = np.zeros((length, 2), float) + codes = np.full(length, cls.CURVE4, dtype=cls.code_type) + vertices[1] = [xA[0], yA[0]] + codes[0:2] = [cls.MOVETO, cls.LINETO] + codes[-2:] = [cls.LINETO, cls.CLOSEPOLY] + vertex_offset = 2 + end = length - 2 + else: + length = n * 3 + 1 + vertices = np.empty((length, 2), float) + codes = np.full(length, cls.CURVE4, dtype=cls.code_type) + vertices[0] = [xA[0], yA[0]] + codes[0] = cls.MOVETO + vertex_offset = 1 + end = length + + vertices[vertex_offset:end:3, 0] = xA + alpha * xA_dot + vertices[vertex_offset:end:3, 1] = yA + alpha * yA_dot + vertices[vertex_offset+1:end:3, 0] = xB - alpha * xB_dot + vertices[vertex_offset+1:end:3, 1] = yB - alpha * yB_dot + vertices[vertex_offset+2:end:3, 0] = xB + vertices[vertex_offset+2:end:3, 1] = yB + + return cls(vertices, codes, readonly=True) + + @classmethod + def wedge(cls, theta1, theta2, n=None): + """ + Return a `Path` for the unit circle wedge from angles *theta1* to + *theta2* (in degrees). + + *theta2* is unwrapped to produce the shortest wedge within 360 degrees. + That is, if *theta2* > *theta1* + 360, the wedge will be from *theta1* + to *theta2* - 360 and not a full circle plus some extra overlap. + + If *n* is provided, it is the number of spline segments to make. + If *n* is not provided, the number of spline segments is + determined based on the delta between *theta1* and *theta2*. + + See `Path.arc` for the reference on the approximation used. + """ + return cls.arc(theta1, theta2, n, True) + + @staticmethod + @lru_cache(8) + def hatch(hatchpattern, density=6): + """ + Given a hatch specifier, *hatchpattern*, generates a `Path` that + can be used in a repeated hatching pattern. *density* is the + number of lines per unit square. + """ + from matplotlib.hatch import get_path + return (get_path(hatchpattern, density) + if hatchpattern is not None else None) + + def clip_to_bbox(self, bbox, inside=True): + """ + Clip the path to the given bounding box. + + The path must be made up of one or more closed polygons. This + algorithm will not behave correctly for unclosed paths. + + If *inside* is `True`, clip to the inside of the box, otherwise + to the outside of the box. + """ + verts = _path.clip_path_to_rect(self, bbox, inside) + paths = [Path(poly) for poly in verts] + return self.make_compound_path(*paths) + + +def get_path_collection_extents( + master_transform, paths, transforms, offsets, offset_transform): + r""" + Get bounding box of a `.PathCollection`\s internal objects. + + That is, given a sequence of `Path`\s, `.Transform`\s objects, and offsets, as found + in a `.PathCollection`, return the bounding box that encapsulates all of them. + + Parameters + ---------- + master_transform : `~matplotlib.transforms.Transform` + Global transformation applied to all paths. + paths : list of `Path` + transforms : list of `~matplotlib.transforms.Affine2DBase` + If non-empty, this overrides *master_transform*. + offsets : (N, 2) array-like + offset_transform : `~matplotlib.transforms.Affine2DBase` + Transform applied to the offsets before offsetting the path. + + Notes + ----- + The way that *paths*, *transforms* and *offsets* are combined follows the same + method as for collections: each is iterated over independently, so if you have 3 + paths (A, B, C), 2 transforms (α, β) and 1 offset (O), their combinations are as + follows: + + - (A, α, O) + - (B, β, O) + - (C, α, O) + """ + from .transforms import Bbox + if len(paths) == 0: + raise ValueError("No paths provided") + if len(offsets) == 0: + _api.warn_deprecated( + "3.8", message="Calling get_path_collection_extents() with an" + " empty offsets list is deprecated since %(since)s. Support will" + " be removed %(removal)s.") + extents, minpos = _path.get_path_collection_extents( + master_transform, paths, np.atleast_3d(transforms), + offsets, offset_transform) + return Bbox.from_extents(*extents, minpos=minpos) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.pyi new file mode 100644 index 00000000..464fc6d9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/path.pyi @@ -0,0 +1,140 @@ +from .bezier import BezierSegment +from .transforms import Affine2D, Transform, Bbox +from collections.abc import Generator, Iterable, Sequence + +import numpy as np +from numpy.typing import ArrayLike + +from typing import Any, overload + +class Path: + code_type: type[np.uint8] + STOP: np.uint8 + MOVETO: np.uint8 + LINETO: np.uint8 + CURVE3: np.uint8 + CURVE4: np.uint8 + CLOSEPOLY: np.uint8 + NUM_VERTICES_FOR_CODE: dict[np.uint8, int] + + def __init__( + self, + vertices: ArrayLike, + codes: ArrayLike | None = ..., + _interpolation_steps: int = ..., + closed: bool = ..., + readonly: bool = ..., + ) -> None: ... + @property + def vertices(self) -> ArrayLike: ... + @vertices.setter + def vertices(self, vertices: ArrayLike) -> None: ... + @property + def codes(self) -> ArrayLike | None: ... + @codes.setter + def codes(self, codes: ArrayLike) -> None: ... + @property + def simplify_threshold(self) -> float: ... + @simplify_threshold.setter + def simplify_threshold(self, threshold: float) -> None: ... + @property + def should_simplify(self) -> bool: ... + @should_simplify.setter + def should_simplify(self, should_simplify: bool) -> None: ... + @property + def readonly(self) -> bool: ... + def copy(self) -> Path: ... + def __deepcopy__(self, memo: dict[int, Any] | None = ...) -> Path: ... + deepcopy = __deepcopy__ + + @classmethod + def make_compound_path_from_polys(cls, XY: ArrayLike) -> Path: ... + @classmethod + def make_compound_path(cls, *args: Path) -> Path: ... + def __len__(self) -> int: ... + def iter_segments( + self, + transform: Transform | None = ..., + remove_nans: bool = ..., + clip: tuple[float, float, float, float] | None = ..., + snap: bool | None = ..., + stroke_width: float = ..., + simplify: bool | None = ..., + curves: bool = ..., + sketch: tuple[float, float, float] | None = ..., + ) -> Generator[tuple[np.ndarray, np.uint8], None, None]: ... + def iter_bezier(self, **kwargs) -> Generator[BezierSegment, None, None]: ... + def cleaned( + self, + transform: Transform | None = ..., + remove_nans: bool = ..., + clip: tuple[float, float, float, float] | None = ..., + *, + simplify: bool | None = ..., + curves: bool = ..., + stroke_width: float = ..., + snap: bool | None = ..., + sketch: tuple[float, float, float] | None = ... + ) -> Path: ... + def transformed(self, transform: Transform) -> Path: ... + def contains_point( + self, + point: tuple[float, float], + transform: Transform | None = ..., + radius: float = ..., + ) -> bool: ... + def contains_points( + self, points: ArrayLike, transform: Transform | None = ..., radius: float = ... + ) -> np.ndarray: ... + def contains_path(self, path: Path, transform: Transform | None = ...) -> bool: ... + def get_extents(self, transform: Transform | None = ..., **kwargs) -> Bbox: ... + def intersects_path(self, other: Path, filled: bool = ...) -> bool: ... + def intersects_bbox(self, bbox: Bbox, filled: bool = ...) -> bool: ... + def interpolated(self, steps: int) -> Path: ... + def to_polygons( + self, + transform: Transform | None = ..., + width: float = ..., + height: float = ..., + closed_only: bool = ..., + ) -> list[ArrayLike]: ... + @classmethod + def unit_rectangle(cls) -> Path: ... + @classmethod + def unit_regular_polygon(cls, numVertices: int) -> Path: ... + @classmethod + def unit_regular_star(cls, numVertices: int, innerCircle: float = ...) -> Path: ... + @classmethod + def unit_regular_asterisk(cls, numVertices: int) -> Path: ... + @classmethod + def unit_circle(cls) -> Path: ... + @classmethod + def circle( + cls, + center: tuple[float, float] = ..., + radius: float = ..., + readonly: bool = ..., + ) -> Path: ... + @classmethod + def unit_circle_righthalf(cls) -> Path: ... + @classmethod + def arc( + cls, theta1: float, theta2: float, n: int | None = ..., is_wedge: bool = ... + ) -> Path: ... + @classmethod + def wedge(cls, theta1: float, theta2: float, n: int | None = ...) -> Path: ... + @overload + @staticmethod + def hatch(hatchpattern: str, density: float = ...) -> Path: ... + @overload + @staticmethod + def hatch(hatchpattern: None, density: float = ...) -> None: ... + def clip_to_bbox(self, bbox: Bbox, inside: bool = ...) -> Path: ... + +def get_path_collection_extents( + master_transform: Transform, + paths: Sequence[Path], + transforms: Iterable[Affine2D], + offsets: ArrayLike, + offset_transform: Affine2D, +) -> Bbox: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.py new file mode 100644 index 00000000..5bb4c8e2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.py @@ -0,0 +1,513 @@ +""" +Defines classes for path effects. The path effects are supported in `.Text`, +`.Line2D` and `.Patch`. + +.. seealso:: + :ref:`patheffects_guide` +""" + +from matplotlib.backend_bases import RendererBase +from matplotlib import colors as mcolors +from matplotlib import patches as mpatches +from matplotlib import transforms as mtransforms +from matplotlib.path import Path +import numpy as np + + +class AbstractPathEffect: + """ + A base class for path effects. + + Subclasses should override the ``draw_path`` method to add effect + functionality. + """ + + def __init__(self, offset=(0., 0.)): + """ + Parameters + ---------- + offset : (float, float), default: (0, 0) + The (x, y) offset to apply to the path, measured in points. + """ + self._offset = offset + + def _offset_transform(self, renderer): + """Apply the offset to the given transform.""" + return mtransforms.Affine2D().translate( + *map(renderer.points_to_pixels, self._offset)) + + def _update_gc(self, gc, new_gc_dict): + """ + Update the given GraphicsContext with the given dict of properties. + + The keys in the dictionary are used to identify the appropriate + ``set_`` method on the *gc*. + """ + new_gc_dict = new_gc_dict.copy() + + dashes = new_gc_dict.pop("dashes", None) + if dashes: + gc.set_dashes(**dashes) + + for k, v in new_gc_dict.items(): + set_method = getattr(gc, 'set_' + k, None) + if not callable(set_method): + raise AttributeError(f'Unknown property {k}') + set_method(v) + return gc + + def draw_path(self, renderer, gc, tpath, affine, rgbFace=None): + """ + Derived should override this method. The arguments are the same + as :meth:`matplotlib.backend_bases.RendererBase.draw_path` + except the first argument is a renderer. + """ + # Get the real renderer, not a PathEffectRenderer. + if isinstance(renderer, PathEffectRenderer): + renderer = renderer._renderer + return renderer.draw_path(gc, tpath, affine, rgbFace) + + +class PathEffectRenderer(RendererBase): + """ + Implements a Renderer which contains another renderer. + + This proxy then intercepts draw calls, calling the appropriate + :class:`AbstractPathEffect` draw method. + + .. note:: + Not all methods have been overridden on this RendererBase subclass. + It may be necessary to add further methods to extend the PathEffects + capabilities further. + """ + + def __init__(self, path_effects, renderer): + """ + Parameters + ---------- + path_effects : iterable of :class:`AbstractPathEffect` + The path effects which this renderer represents. + renderer : `~matplotlib.backend_bases.RendererBase` subclass + + """ + self._path_effects = path_effects + self._renderer = renderer + + def copy_with_path_effect(self, path_effects): + return self.__class__(path_effects, self._renderer) + + def draw_path(self, gc, tpath, affine, rgbFace=None): + for path_effect in self._path_effects: + path_effect.draw_path(self._renderer, gc, tpath, affine, + rgbFace) + + def draw_markers( + self, gc, marker_path, marker_trans, path, *args, **kwargs): + # We do a little shimmy so that all markers are drawn for each path + # effect in turn. Essentially, we induce recursion (depth 1) which is + # terminated once we have just a single path effect to work with. + if len(self._path_effects) == 1: + # Call the base path effect function - this uses the unoptimised + # approach of calling "draw_path" multiple times. + return super().draw_markers(gc, marker_path, marker_trans, path, + *args, **kwargs) + + for path_effect in self._path_effects: + renderer = self.copy_with_path_effect([path_effect]) + # Recursively call this method, only next time we will only have + # one path effect. + renderer.draw_markers(gc, marker_path, marker_trans, path, + *args, **kwargs) + + def draw_path_collection(self, gc, master_transform, paths, *args, + **kwargs): + # We do a little shimmy so that all paths are drawn for each path + # effect in turn. Essentially, we induce recursion (depth 1) which is + # terminated once we have just a single path effect to work with. + if len(self._path_effects) == 1: + # Call the base path effect function - this uses the unoptimised + # approach of calling "draw_path" multiple times. + return super().draw_path_collection(gc, master_transform, paths, + *args, **kwargs) + + for path_effect in self._path_effects: + renderer = self.copy_with_path_effect([path_effect]) + # Recursively call this method, only next time we will only have + # one path effect. + renderer.draw_path_collection(gc, master_transform, paths, + *args, **kwargs) + + def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath): + # Implements the naive text drawing as is found in RendererBase. + path, transform = self._get_text_path_transform(x, y, s, prop, + angle, ismath) + color = gc.get_rgb() + gc.set_linewidth(0.0) + self.draw_path(gc, path, transform, rgbFace=color) + + def __getattribute__(self, name): + if name in ['flipy', 'get_canvas_width_height', 'new_gc', + 'points_to_pixels', '_text2path', 'height', 'width']: + return getattr(self._renderer, name) + else: + return object.__getattribute__(self, name) + + +class Normal(AbstractPathEffect): + """ + The "identity" PathEffect. + + The Normal PathEffect's sole purpose is to draw the original artist with + no special path effect. + """ + + +def _subclass_with_normal(effect_class): + """ + Create a PathEffect class combining *effect_class* and a normal draw. + """ + + class withEffect(effect_class): + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + super().draw_path(renderer, gc, tpath, affine, rgbFace) + renderer.draw_path(gc, tpath, affine, rgbFace) + + withEffect.__name__ = f"with{effect_class.__name__}" + withEffect.__qualname__ = f"with{effect_class.__name__}" + withEffect.__doc__ = f""" + A shortcut PathEffect for applying `.{effect_class.__name__}` and then + drawing the original Artist. + + With this class you can use :: + + artist.set_path_effects([patheffects.with{effect_class.__name__}()]) + + as a shortcut for :: + + artist.set_path_effects([patheffects.{effect_class.__name__}(), + patheffects.Normal()]) + """ + # Docstring inheritance doesn't work for locally-defined subclasses. + withEffect.draw_path.__doc__ = effect_class.draw_path.__doc__ + return withEffect + + +class Stroke(AbstractPathEffect): + """A line based PathEffect which re-draws a stroke.""" + + def __init__(self, offset=(0, 0), **kwargs): + """ + The path will be stroked with its gc updated with the given + keyword arguments, i.e., the keyword arguments should be valid + gc parameter values. + """ + super().__init__(offset) + self._gc = kwargs + + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + """Draw the path with updated gc.""" + gc0 = renderer.new_gc() # Don't modify gc, but a copy! + gc0.copy_properties(gc) + gc0 = self._update_gc(gc0, self._gc) + renderer.draw_path( + gc0, tpath, affine + self._offset_transform(renderer), rgbFace) + gc0.restore() + + +withStroke = _subclass_with_normal(effect_class=Stroke) + + +class SimplePatchShadow(AbstractPathEffect): + """A simple shadow via a filled patch.""" + + def __init__(self, offset=(2, -2), + shadow_rgbFace=None, alpha=None, + rho=0.3, **kwargs): + """ + Parameters + ---------- + offset : (float, float), default: (2, -2) + The (x, y) offset of the shadow in points. + shadow_rgbFace : color + The shadow color. + alpha : float, default: 0.3 + The alpha transparency of the created shadow patch. + rho : float, default: 0.3 + A scale factor to apply to the rgbFace color if *shadow_rgbFace* + is not specified. + **kwargs + Extra keywords are stored and passed through to + :meth:`AbstractPathEffect._update_gc`. + + """ + super().__init__(offset) + + if shadow_rgbFace is None: + self._shadow_rgbFace = shadow_rgbFace + else: + self._shadow_rgbFace = mcolors.to_rgba(shadow_rgbFace) + + if alpha is None: + alpha = 0.3 + + self._alpha = alpha + self._rho = rho + + #: The dictionary of keywords to update the graphics collection with. + self._gc = kwargs + + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + """ + Overrides the standard draw_path to add the shadow offset and + necessary color changes for the shadow. + """ + gc0 = renderer.new_gc() # Don't modify gc, but a copy! + gc0.copy_properties(gc) + + if self._shadow_rgbFace is None: + r, g, b = (rgbFace or (1., 1., 1.))[:3] + # Scale the colors by a factor to improve the shadow effect. + shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho) + else: + shadow_rgbFace = self._shadow_rgbFace + + gc0.set_foreground("none") + gc0.set_alpha(self._alpha) + gc0.set_linewidth(0) + + gc0 = self._update_gc(gc0, self._gc) + renderer.draw_path( + gc0, tpath, affine + self._offset_transform(renderer), + shadow_rgbFace) + gc0.restore() + + +withSimplePatchShadow = _subclass_with_normal(effect_class=SimplePatchShadow) + + +class SimpleLineShadow(AbstractPathEffect): + """A simple shadow via a line.""" + + def __init__(self, offset=(2, -2), + shadow_color='k', alpha=0.3, rho=0.3, **kwargs): + """ + Parameters + ---------- + offset : (float, float), default: (2, -2) + The (x, y) offset to apply to the path, in points. + shadow_color : color, default: 'black' + The shadow color. + A value of ``None`` takes the original artist's color + with a scale factor of *rho*. + alpha : float, default: 0.3 + The alpha transparency of the created shadow patch. + rho : float, default: 0.3 + A scale factor to apply to the rgbFace color if *shadow_color* + is ``None``. + **kwargs + Extra keywords are stored and passed through to + :meth:`AbstractPathEffect._update_gc`. + """ + super().__init__(offset) + if shadow_color is None: + self._shadow_color = shadow_color + else: + self._shadow_color = mcolors.to_rgba(shadow_color) + self._alpha = alpha + self._rho = rho + #: The dictionary of keywords to update the graphics collection with. + self._gc = kwargs + + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + """ + Overrides the standard draw_path to add the shadow offset and + necessary color changes for the shadow. + """ + gc0 = renderer.new_gc() # Don't modify gc, but a copy! + gc0.copy_properties(gc) + + if self._shadow_color is None: + r, g, b = (gc0.get_foreground() or (1., 1., 1.))[:3] + # Scale the colors by a factor to improve the shadow effect. + shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho) + else: + shadow_rgbFace = self._shadow_color + + gc0.set_foreground(shadow_rgbFace) + gc0.set_alpha(self._alpha) + + gc0 = self._update_gc(gc0, self._gc) + renderer.draw_path( + gc0, tpath, affine + self._offset_transform(renderer)) + gc0.restore() + + +class PathPatchEffect(AbstractPathEffect): + """ + Draws a `.PathPatch` instance whose Path comes from the original + PathEffect artist. + """ + + def __init__(self, offset=(0, 0), **kwargs): + """ + Parameters + ---------- + offset : (float, float), default: (0, 0) + The (x, y) offset to apply to the path, in points. + **kwargs + All keyword arguments are passed through to the + :class:`~matplotlib.patches.PathPatch` constructor. The + properties which cannot be overridden are "path", "clip_box" + "transform" and "clip_path". + """ + super().__init__(offset=offset) + self.patch = mpatches.PathPatch([], **kwargs) + + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + self.patch._path = tpath + self.patch.set_transform(affine + self._offset_transform(renderer)) + self.patch.set_clip_box(gc.get_clip_rectangle()) + clip_path = gc.get_clip_path() + if clip_path and self.patch.get_clip_path() is None: + self.patch.set_clip_path(*clip_path) + self.patch.draw(renderer) + + +class TickedStroke(AbstractPathEffect): + """ + A line-based PathEffect which draws a path with a ticked style. + + This line style is frequently used to represent constraints in + optimization. The ticks may be used to indicate that one side + of the line is invalid or to represent a closed boundary of a + domain (i.e. a wall or the edge of a pipe). + + The spacing, length, and angle of ticks can be controlled. + + This line style is sometimes referred to as a hatched line. + + See also the :doc:`/gallery/misc/tickedstroke_demo` example. + """ + + def __init__(self, offset=(0, 0), + spacing=10.0, angle=45.0, length=np.sqrt(2), + **kwargs): + """ + Parameters + ---------- + offset : (float, float), default: (0, 0) + The (x, y) offset to apply to the path, in points. + spacing : float, default: 10.0 + The spacing between ticks in points. + angle : float, default: 45.0 + The angle between the path and the tick in degrees. The angle + is measured as if you were an ant walking along the curve, with + zero degrees pointing directly ahead, 90 to your left, -90 + to your right, and 180 behind you. To change side of the ticks, + change sign of the angle. + length : float, default: 1.414 + The length of the tick relative to spacing. + Recommended length = 1.414 (sqrt(2)) when angle=45, length=1.0 + when angle=90 and length=2.0 when angle=60. + **kwargs + Extra keywords are stored and passed through to + :meth:`AbstractPathEffect._update_gc`. + + Examples + -------- + See :doc:`/gallery/misc/tickedstroke_demo`. + """ + super().__init__(offset) + + self._spacing = spacing + self._angle = angle + self._length = length + self._gc = kwargs + + def draw_path(self, renderer, gc, tpath, affine, rgbFace): + """Draw the path with updated gc.""" + # Do not modify the input! Use copy instead. + gc0 = renderer.new_gc() + gc0.copy_properties(gc) + + gc0 = self._update_gc(gc0, self._gc) + trans = affine + self._offset_transform(renderer) + + theta = -np.radians(self._angle) + trans_matrix = np.array([[np.cos(theta), -np.sin(theta)], + [np.sin(theta), np.cos(theta)]]) + + # Convert spacing parameter to pixels. + spacing_px = renderer.points_to_pixels(self._spacing) + + # Transform before evaluation because to_polygons works at resolution + # of one -- assuming it is working in pixel space. + transpath = affine.transform_path(tpath) + + # Evaluate path to straight line segments that can be used to + # construct line ticks. + polys = transpath.to_polygons(closed_only=False) + + for p in polys: + x = p[:, 0] + y = p[:, 1] + + # Can not interpolate points or draw line if only one point in + # polyline. + if x.size < 2: + continue + + # Find distance between points on the line + ds = np.hypot(x[1:] - x[:-1], y[1:] - y[:-1]) + + # Build parametric coordinate along curve + s = np.concatenate(([0.0], np.cumsum(ds))) + s_total = s[-1] + + num = int(np.ceil(s_total / spacing_px)) - 1 + # Pick parameter values for ticks. + s_tick = np.linspace(spacing_px/2, s_total - spacing_px/2, num) + + # Find points along the parameterized curve + x_tick = np.interp(s_tick, s, x) + y_tick = np.interp(s_tick, s, y) + + # Find unit vectors in local direction of curve + delta_s = self._spacing * .001 + u = (np.interp(s_tick + delta_s, s, x) - x_tick) / delta_s + v = (np.interp(s_tick + delta_s, s, y) - y_tick) / delta_s + + # Normalize slope into unit slope vector. + n = np.hypot(u, v) + mask = n == 0 + n[mask] = 1.0 + + uv = np.array([u / n, v / n]).T + uv[mask] = np.array([0, 0]).T + + # Rotate and scale unit vector into tick vector + dxy = np.dot(uv, trans_matrix) * self._length * spacing_px + + # Build tick endpoints + x_end = x_tick + dxy[:, 0] + y_end = y_tick + dxy[:, 1] + + # Interleave ticks to form Path vertices + xyt = np.empty((2 * num, 2), dtype=x_tick.dtype) + xyt[0::2, 0] = x_tick + xyt[1::2, 0] = x_end + xyt[0::2, 1] = y_tick + xyt[1::2, 1] = y_end + + # Build up vector of Path codes + codes = np.tile([Path.MOVETO, Path.LINETO], num) + + # Construct and draw resulting path + h = Path(xyt, codes) + # Transform back to data space during render + renderer.draw_path(gc0, h, affine.inverted() + trans, rgbFace) + + gc0.restore() + + +withTickedStroke = _subclass_with_normal(effect_class=TickedStroke) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.pyi new file mode 100644 index 00000000..5d8dcfea --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/patheffects.pyi @@ -0,0 +1,106 @@ +from collections.abc import Iterable, Sequence +from typing import Any + +from matplotlib.backend_bases import RendererBase, GraphicsContextBase +from matplotlib.path import Path +from matplotlib.patches import Patch +from matplotlib.transforms import Transform + +from matplotlib.typing import ColorType + +class AbstractPathEffect: + def __init__(self, offset: tuple[float, float] = ...) -> None: ... + def draw_path( + self, + renderer: RendererBase, + gc: GraphicsContextBase, + tpath: Path, + affine: Transform, + rgbFace: ColorType | None = ..., + ) -> None: ... + +class PathEffectRenderer(RendererBase): + def __init__( + self, path_effects: Iterable[AbstractPathEffect], renderer: RendererBase + ) -> None: ... + def copy_with_path_effect(self, path_effects: Iterable[AbstractPathEffect]) -> PathEffectRenderer: ... + def draw_path( + self, + gc: GraphicsContextBase, + tpath: Path, + affine: Transform, + rgbFace: ColorType | None = ..., + ) -> None: ... + def draw_markers( + self, + gc: GraphicsContextBase, + marker_path: Path, + marker_trans: Transform, + path: Path, + *args, + **kwargs + ) -> None: ... + def draw_path_collection( + self, + gc: GraphicsContextBase, + master_transform: Transform, + paths: Sequence[Path], + *args, + **kwargs + ) -> None: ... + def __getattribute__(self, name: str) -> Any: ... + +class Normal(AbstractPathEffect): ... + +class Stroke(AbstractPathEffect): + def __init__(self, offset: tuple[float, float] = ..., **kwargs) -> None: ... + # rgbFace becomes non-optional + def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore + +class withStroke(Stroke): ... + +class SimplePatchShadow(AbstractPathEffect): + def __init__( + self, + offset: tuple[float, float] = ..., + shadow_rgbFace: ColorType | None = ..., + alpha: float | None = ..., + rho: float = ..., + **kwargs + ) -> None: ... + # rgbFace becomes non-optional + def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore + +class withSimplePatchShadow(SimplePatchShadow): ... + +class SimpleLineShadow(AbstractPathEffect): + def __init__( + self, + offset: tuple[float, float] = ..., + shadow_color: ColorType = ..., + alpha: float = ..., + rho: float = ..., + **kwargs + ) -> None: ... + # rgbFace becomes non-optional + def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore + +class PathPatchEffect(AbstractPathEffect): + patch: Patch + def __init__(self, offset: tuple[float, float] = ..., **kwargs) -> None: ... + # rgbFace becomes non-optional + def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore + +class TickedStroke(AbstractPathEffect): + def __init__( + self, + offset: tuple[float, float] = ..., + spacing: float = ..., + angle: float = ..., + length: float = ..., + **kwargs + ) -> None: ... + # rgbFace becomes non-optional + def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore + +class withTickedStroke(TickedStroke): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.py new file mode 100644 index 00000000..4c5ef8e2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.py @@ -0,0 +1,126 @@ +""" +Non-separable transforms that map from data space to screen space. + +Projections are defined as `~.axes.Axes` subclasses. They include the +following elements: + +- A transformation from data coordinates into display coordinates. + +- An inverse of that transformation. This is used, for example, to convert + mouse positions from screen space back into data space. + +- Transformations for the gridlines, ticks and ticklabels. Custom projections + will often need to place these elements in special locations, and Matplotlib + has a facility to help with doing so. + +- Setting up default values (overriding `~.axes.Axes.cla`), since the defaults + for a rectilinear axes may not be appropriate. + +- Defining the shape of the axes, for example, an elliptical axes, that will be + used to draw the background of the plot and for clipping any data elements. + +- Defining custom locators and formatters for the projection. For example, in + a geographic projection, it may be more convenient to display the grid in + degrees, even if the data is in radians. + +- Set up interactive panning and zooming. This is left as an "advanced" + feature left to the reader, but there is an example of this for polar plots + in `matplotlib.projections.polar`. + +- Any additional methods for additional convenience or features. + +Once the projection axes is defined, it can be used in one of two ways: + +- By defining the class attribute ``name``, the projection axes can be + registered with `matplotlib.projections.register_projection` and subsequently + simply invoked by name:: + + fig.add_subplot(projection="my_proj_name") + +- For more complex, parameterisable projections, a generic "projection" object + may be defined which includes the method ``_as_mpl_axes``. ``_as_mpl_axes`` + should take no arguments and return the projection's axes subclass and a + dictionary of additional arguments to pass to the subclass' ``__init__`` + method. Subsequently a parameterised projection can be initialised with:: + + fig.add_subplot(projection=MyProjection(param1=param1_value)) + + where MyProjection is an object which implements a ``_as_mpl_axes`` method. + +A full-fledged and heavily annotated example is in +:doc:`/gallery/misc/custom_projection`. The polar plot functionality in +`matplotlib.projections.polar` may also be of interest. +""" + +from .. import axes, _docstring +from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes +from .polar import PolarAxes + +try: + from mpl_toolkits.mplot3d import Axes3D +except Exception: + import warnings + warnings.warn("Unable to import Axes3D. This may be due to multiple versions of " + "Matplotlib being installed (e.g. as a system package and as a pip " + "package). As a result, the 3D projection is not available.") + Axes3D = None + + +class ProjectionRegistry: + """A mapping of registered projection names to projection classes.""" + + def __init__(self): + self._all_projection_types = {} + + def register(self, *projections): + """Register a new set of projections.""" + for projection in projections: + name = projection.name + self._all_projection_types[name] = projection + + def get_projection_class(self, name): + """Get a projection class from its *name*.""" + return self._all_projection_types[name] + + def get_projection_names(self): + """Return the names of all projections currently registered.""" + return sorted(self._all_projection_types) + + +projection_registry = ProjectionRegistry() +projection_registry.register( + axes.Axes, + PolarAxes, + AitoffAxes, + HammerAxes, + LambertAxes, + MollweideAxes, +) +if Axes3D is not None: + projection_registry.register(Axes3D) +else: + # remove from namespace if not importable + del Axes3D + + +def register_projection(cls): + projection_registry.register(cls) + + +def get_projection_class(projection=None): + """ + Get a projection class from its name. + + If *projection* is None, a standard rectilinear projection is returned. + """ + if projection is None: + projection = 'rectilinear' + + try: + return projection_registry.get_projection_class(projection) + except KeyError as err: + raise ValueError("Unknown projection %r" % projection) from err + + +get_projection_names = projection_registry.get_projection_names +_docstring.interpd.update(projection_names=get_projection_names()) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.pyi new file mode 100644 index 00000000..0f8b6c09 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/__init__.pyi @@ -0,0 +1,15 @@ +from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes +from .polar import PolarAxes +from ..axes import Axes + +class ProjectionRegistry: + def __init__(self) -> None: ... + def register(self, *projections: type[Axes]) -> None: ... + def get_projection_class(self, name: str) -> type[Axes]: ... + def get_projection_names(self) -> list[str]: ... + +projection_registry: ProjectionRegistry + +def register_projection(cls: type[Axes]) -> None: ... +def get_projection_class(projection: str | None = ...) -> type[Axes]: ... +def get_projection_names() -> list[str]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.py new file mode 100644 index 00000000..498b2f72 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.py @@ -0,0 +1,510 @@ +import numpy as np + +import matplotlib as mpl +from matplotlib import _api +from matplotlib.axes import Axes +import matplotlib.axis as maxis +from matplotlib.patches import Circle +from matplotlib.path import Path +import matplotlib.spines as mspines +from matplotlib.ticker import ( + Formatter, NullLocator, FixedLocator, NullFormatter) +from matplotlib.transforms import Affine2D, BboxTransformTo, Transform + + +class GeoAxes(Axes): + """An abstract base class for geographic projections.""" + + class ThetaFormatter(Formatter): + """ + Used to format the theta tick labels. Converts the native + unit of radians into degrees and adds a degree symbol. + """ + def __init__(self, round_to=1.0): + self._round_to = round_to + + def __call__(self, x, pos=None): + degrees = round(np.rad2deg(x) / self._round_to) * self._round_to + return f"{degrees:0.0f}\N{DEGREE SIGN}" + + RESOLUTION = 75 + + def _init_axis(self): + self.xaxis = maxis.XAxis(self, clear=False) + self.yaxis = maxis.YAxis(self, clear=False) + self.spines['geo'].register_axis(self.yaxis) + + def clear(self): + # docstring inherited + super().clear() + + self.set_longitude_grid(30) + self.set_latitude_grid(15) + self.set_longitude_grid_ends(75) + self.xaxis.set_minor_locator(NullLocator()) + self.yaxis.set_minor_locator(NullLocator()) + self.xaxis.set_ticks_position('none') + self.yaxis.set_ticks_position('none') + self.yaxis.set_tick_params(label1On=True) + # Why do we need to turn on yaxis tick labels, but + # xaxis tick labels are already on? + + self.grid(mpl.rcParams['axes.grid']) + + Axes.set_xlim(self, -np.pi, np.pi) + Axes.set_ylim(self, -np.pi / 2.0, np.pi / 2.0) + + def _set_lim_and_transforms(self): + # A (possibly non-linear) projection on the (already scaled) data + self.transProjection = self._get_core_transform(self.RESOLUTION) + + self.transAffine = self._get_affine_transform() + + self.transAxes = BboxTransformTo(self.bbox) + + # The complete data transformation stack -- from data all the + # way to display coordinates + self.transData = \ + self.transProjection + \ + self.transAffine + \ + self.transAxes + + # This is the transform for longitude ticks. + self._xaxis_pretransform = \ + Affine2D() \ + .scale(1, self._longitude_cap * 2) \ + .translate(0, -self._longitude_cap) + self._xaxis_transform = \ + self._xaxis_pretransform + \ + self.transData + self._xaxis_text1_transform = \ + Affine2D().scale(1, 0) + \ + self.transData + \ + Affine2D().translate(0, 4) + self._xaxis_text2_transform = \ + Affine2D().scale(1, 0) + \ + self.transData + \ + Affine2D().translate(0, -4) + + # This is the transform for latitude ticks. + yaxis_stretch = Affine2D().scale(np.pi * 2, 1).translate(-np.pi, 0) + yaxis_space = Affine2D().scale(1, 1.1) + self._yaxis_transform = \ + yaxis_stretch + \ + self.transData + yaxis_text_base = \ + yaxis_stretch + \ + self.transProjection + \ + (yaxis_space + + self.transAffine + + self.transAxes) + self._yaxis_text1_transform = \ + yaxis_text_base + \ + Affine2D().translate(-8, 0) + self._yaxis_text2_transform = \ + yaxis_text_base + \ + Affine2D().translate(8, 0) + + def _get_affine_transform(self): + transform = self._get_core_transform(1) + xscale, _ = transform.transform((np.pi, 0)) + _, yscale = transform.transform((0, np.pi/2)) + return Affine2D() \ + .scale(0.5 / xscale, 0.5 / yscale) \ + .translate(0.5, 0.5) + + def get_xaxis_transform(self, which='grid'): + _api.check_in_list(['tick1', 'tick2', 'grid'], which=which) + return self._xaxis_transform + + def get_xaxis_text1_transform(self, pad): + return self._xaxis_text1_transform, 'bottom', 'center' + + def get_xaxis_text2_transform(self, pad): + return self._xaxis_text2_transform, 'top', 'center' + + def get_yaxis_transform(self, which='grid'): + _api.check_in_list(['tick1', 'tick2', 'grid'], which=which) + return self._yaxis_transform + + def get_yaxis_text1_transform(self, pad): + return self._yaxis_text1_transform, 'center', 'right' + + def get_yaxis_text2_transform(self, pad): + return self._yaxis_text2_transform, 'center', 'left' + + def _gen_axes_patch(self): + return Circle((0.5, 0.5), 0.5) + + def _gen_axes_spines(self): + return {'geo': mspines.Spine.circular_spine(self, (0.5, 0.5), 0.5)} + + def set_yscale(self, *args, **kwargs): + if args[0] != 'linear': + raise NotImplementedError + + set_xscale = set_yscale + + def set_xlim(self, *args, **kwargs): + """Not supported. Please consider using Cartopy.""" + raise TypeError("Changing axes limits of a geographic projection is " + "not supported. Please consider using Cartopy.") + + set_ylim = set_xlim + + def format_coord(self, lon, lat): + """Return a format string formatting the coordinate.""" + lon, lat = np.rad2deg([lon, lat]) + ns = 'N' if lat >= 0.0 else 'S' + ew = 'E' if lon >= 0.0 else 'W' + return ('%f\N{DEGREE SIGN}%s, %f\N{DEGREE SIGN}%s' + % (abs(lat), ns, abs(lon), ew)) + + def set_longitude_grid(self, degrees): + """ + Set the number of degrees between each longitude grid. + """ + # Skip -180 and 180, which are the fixed limits. + grid = np.arange(-180 + degrees, 180, degrees) + self.xaxis.set_major_locator(FixedLocator(np.deg2rad(grid))) + self.xaxis.set_major_formatter(self.ThetaFormatter(degrees)) + + def set_latitude_grid(self, degrees): + """ + Set the number of degrees between each latitude grid. + """ + # Skip -90 and 90, which are the fixed limits. + grid = np.arange(-90 + degrees, 90, degrees) + self.yaxis.set_major_locator(FixedLocator(np.deg2rad(grid))) + self.yaxis.set_major_formatter(self.ThetaFormatter(degrees)) + + def set_longitude_grid_ends(self, degrees): + """ + Set the latitude(s) at which to stop drawing the longitude grids. + """ + self._longitude_cap = np.deg2rad(degrees) + self._xaxis_pretransform \ + .clear() \ + .scale(1.0, self._longitude_cap * 2.0) \ + .translate(0.0, -self._longitude_cap) + + def get_data_ratio(self): + """Return the aspect ratio of the data itself.""" + return 1.0 + + ### Interactive panning + + def can_zoom(self): + """ + Return whether this Axes supports the zoom box button functionality. + + This Axes object does not support interactive zoom box. + """ + return False + + def can_pan(self): + """ + Return whether this Axes supports the pan/zoom button functionality. + + This Axes object does not support interactive pan/zoom. + """ + return False + + def start_pan(self, x, y, button): + pass + + def end_pan(self): + pass + + def drag_pan(self, button, key, x, y): + pass + + +class _GeoTransform(Transform): + # Factoring out some common functionality. + input_dims = output_dims = 2 + + def __init__(self, resolution): + """ + Create a new geographical transform. + + Resolution is the number of steps to interpolate between each input + line segment to approximate its path in curved space. + """ + super().__init__() + self._resolution = resolution + + def __str__(self): + return f"{type(self).__name__}({self._resolution})" + + def transform_path_non_affine(self, path): + # docstring inherited + ipath = path.interpolated(self._resolution) + return Path(self.transform(ipath.vertices), ipath.codes) + + +class AitoffAxes(GeoAxes): + name = 'aitoff' + + class AitoffTransform(_GeoTransform): + """The base Aitoff transform.""" + + @_api.rename_parameter("3.8", "ll", "values") + def transform_non_affine(self, values): + # docstring inherited + longitude, latitude = values.T + + # Pre-compute some values + half_long = longitude / 2.0 + cos_latitude = np.cos(latitude) + + alpha = np.arccos(cos_latitude * np.cos(half_long)) + sinc_alpha = np.sinc(alpha / np.pi) # np.sinc is sin(pi*x)/(pi*x). + + x = (cos_latitude * np.sin(half_long)) / sinc_alpha + y = np.sin(latitude) / sinc_alpha + return np.column_stack([x, y]) + + def inverted(self): + # docstring inherited + return AitoffAxes.InvertedAitoffTransform(self._resolution) + + class InvertedAitoffTransform(_GeoTransform): + + @_api.rename_parameter("3.8", "xy", "values") + def transform_non_affine(self, values): + # docstring inherited + # MGDTODO: Math is hard ;( + return np.full_like(values, np.nan) + + def inverted(self): + # docstring inherited + return AitoffAxes.AitoffTransform(self._resolution) + + def __init__(self, *args, **kwargs): + self._longitude_cap = np.pi / 2.0 + super().__init__(*args, **kwargs) + self.set_aspect(0.5, adjustable='box', anchor='C') + self.clear() + + def _get_core_transform(self, resolution): + return self.AitoffTransform(resolution) + + +class HammerAxes(GeoAxes): + name = 'hammer' + + class HammerTransform(_GeoTransform): + """The base Hammer transform.""" + + @_api.rename_parameter("3.8", "ll", "values") + def transform_non_affine(self, values): + # docstring inherited + longitude, latitude = values.T + half_long = longitude / 2.0 + cos_latitude = np.cos(latitude) + sqrt2 = np.sqrt(2.0) + alpha = np.sqrt(1.0 + cos_latitude * np.cos(half_long)) + x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha + y = (sqrt2 * np.sin(latitude)) / alpha + return np.column_stack([x, y]) + + def inverted(self): + # docstring inherited + return HammerAxes.InvertedHammerTransform(self._resolution) + + class InvertedHammerTransform(_GeoTransform): + + @_api.rename_parameter("3.8", "xy", "values") + def transform_non_affine(self, values): + # docstring inherited + x, y = values.T + z = np.sqrt(1 - (x / 4) ** 2 - (y / 2) ** 2) + longitude = 2 * np.arctan((z * x) / (2 * (2 * z ** 2 - 1))) + latitude = np.arcsin(y*z) + return np.column_stack([longitude, latitude]) + + def inverted(self): + # docstring inherited + return HammerAxes.HammerTransform(self._resolution) + + def __init__(self, *args, **kwargs): + self._longitude_cap = np.pi / 2.0 + super().__init__(*args, **kwargs) + self.set_aspect(0.5, adjustable='box', anchor='C') + self.clear() + + def _get_core_transform(self, resolution): + return self.HammerTransform(resolution) + + +class MollweideAxes(GeoAxes): + name = 'mollweide' + + class MollweideTransform(_GeoTransform): + """The base Mollweide transform.""" + + @_api.rename_parameter("3.8", "ll", "values") + def transform_non_affine(self, values): + # docstring inherited + def d(theta): + delta = (-(theta + np.sin(theta) - pi_sin_l) + / (1 + np.cos(theta))) + return delta, np.abs(delta) > 0.001 + + longitude, latitude = values.T + + clat = np.pi/2 - np.abs(latitude) + ihigh = clat < 0.087 # within 5 degrees of the poles + ilow = ~ihigh + aux = np.empty(latitude.shape, dtype=float) + + if ilow.any(): # Newton-Raphson iteration + pi_sin_l = np.pi * np.sin(latitude[ilow]) + theta = 2.0 * latitude[ilow] + delta, large_delta = d(theta) + while np.any(large_delta): + theta[large_delta] += delta[large_delta] + delta, large_delta = d(theta) + aux[ilow] = theta / 2 + + if ihigh.any(): # Taylor series-based approx. solution + e = clat[ihigh] + d = 0.5 * (3 * np.pi * e**2) ** (1.0/3) + aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh]) + + xy = np.empty(values.shape, dtype=float) + xy[:, 0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux) + xy[:, 1] = np.sqrt(2.0) * np.sin(aux) + + return xy + + def inverted(self): + # docstring inherited + return MollweideAxes.InvertedMollweideTransform(self._resolution) + + class InvertedMollweideTransform(_GeoTransform): + + @_api.rename_parameter("3.8", "xy", "values") + def transform_non_affine(self, values): + # docstring inherited + x, y = values.T + # from Equations (7, 8) of + # https://mathworld.wolfram.com/MollweideProjection.html + theta = np.arcsin(y / np.sqrt(2)) + longitude = (np.pi / (2 * np.sqrt(2))) * x / np.cos(theta) + latitude = np.arcsin((2 * theta + np.sin(2 * theta)) / np.pi) + return np.column_stack([longitude, latitude]) + + def inverted(self): + # docstring inherited + return MollweideAxes.MollweideTransform(self._resolution) + + def __init__(self, *args, **kwargs): + self._longitude_cap = np.pi / 2.0 + super().__init__(*args, **kwargs) + self.set_aspect(0.5, adjustable='box', anchor='C') + self.clear() + + def _get_core_transform(self, resolution): + return self.MollweideTransform(resolution) + + +class LambertAxes(GeoAxes): + name = 'lambert' + + class LambertTransform(_GeoTransform): + """The base Lambert transform.""" + + def __init__(self, center_longitude, center_latitude, resolution): + """ + Create a new Lambert transform. Resolution is the number of steps + to interpolate between each input line segment to approximate its + path in curved Lambert space. + """ + _GeoTransform.__init__(self, resolution) + self._center_longitude = center_longitude + self._center_latitude = center_latitude + + @_api.rename_parameter("3.8", "ll", "values") + def transform_non_affine(self, values): + # docstring inherited + longitude, latitude = values.T + clong = self._center_longitude + clat = self._center_latitude + cos_lat = np.cos(latitude) + sin_lat = np.sin(latitude) + diff_long = longitude - clong + cos_diff_long = np.cos(diff_long) + + inner_k = np.maximum( # Prevent divide-by-zero problems + 1 + np.sin(clat)*sin_lat + np.cos(clat)*cos_lat*cos_diff_long, + 1e-15) + k = np.sqrt(2 / inner_k) + x = k * cos_lat*np.sin(diff_long) + y = k * (np.cos(clat)*sin_lat - np.sin(clat)*cos_lat*cos_diff_long) + + return np.column_stack([x, y]) + + def inverted(self): + # docstring inherited + return LambertAxes.InvertedLambertTransform( + self._center_longitude, + self._center_latitude, + self._resolution) + + class InvertedLambertTransform(_GeoTransform): + + def __init__(self, center_longitude, center_latitude, resolution): + _GeoTransform.__init__(self, resolution) + self._center_longitude = center_longitude + self._center_latitude = center_latitude + + @_api.rename_parameter("3.8", "xy", "values") + def transform_non_affine(self, values): + # docstring inherited + x, y = values.T + clong = self._center_longitude + clat = self._center_latitude + p = np.maximum(np.hypot(x, y), 1e-9) + c = 2 * np.arcsin(0.5 * p) + sin_c = np.sin(c) + cos_c = np.cos(c) + + latitude = np.arcsin(cos_c*np.sin(clat) + + ((y*sin_c*np.cos(clat)) / p)) + longitude = clong + np.arctan( + (x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c)) + + return np.column_stack([longitude, latitude]) + + def inverted(self): + # docstring inherited + return LambertAxes.LambertTransform( + self._center_longitude, + self._center_latitude, + self._resolution) + + def __init__(self, *args, center_longitude=0, center_latitude=0, **kwargs): + self._longitude_cap = np.pi / 2 + self._center_longitude = center_longitude + self._center_latitude = center_latitude + super().__init__(*args, **kwargs) + self.set_aspect('equal', adjustable='box', anchor='C') + self.clear() + + def clear(self): + # docstring inherited + super().clear() + self.yaxis.set_major_formatter(NullFormatter()) + + def _get_core_transform(self, resolution): + return self.LambertTransform( + self._center_longitude, + self._center_latitude, + resolution) + + def _get_affine_transform(self): + return Affine2D() \ + .scale(0.25) \ + .translate(0.5, 0.5) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.pyi new file mode 100644 index 00000000..93220f8c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/geo.pyi @@ -0,0 +1,112 @@ +from matplotlib.axes import Axes +from matplotlib.ticker import Formatter +from matplotlib.transforms import Transform + +from typing import Any, Literal + +class GeoAxes(Axes): + class ThetaFormatter(Formatter): + def __init__(self, round_to: float = ...) -> None: ... + def __call__(self, x: float, pos: Any | None = ...): ... + RESOLUTION: float + def get_xaxis_transform( + self, which: Literal["tick1", "tick2", "grid"] = ... + ) -> Transform: ... + def get_xaxis_text1_transform( + self, pad: float + ) -> tuple[ + Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_xaxis_text2_transform( + self, pad: float + ) -> tuple[ + Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_yaxis_transform( + self, which: Literal["tick1", "tick2", "grid"] = ... + ) -> Transform: ... + def get_yaxis_text1_transform( + self, pad: float + ) -> tuple[ + Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_yaxis_text2_transform( + self, pad: float + ) -> tuple[ + Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def set_xlim(self, *args, **kwargs) -> tuple[float, float]: ... + def set_ylim(self, *args, **kwargs) -> tuple[float, float]: ... + def format_coord(self, lon: float, lat: float) -> str: ... + def set_longitude_grid(self, degrees: float) -> None: ... + def set_latitude_grid(self, degrees: float) -> None: ... + def set_longitude_grid_ends(self, degrees: float) -> None: ... + def get_data_ratio(self) -> float: ... + def can_zoom(self) -> bool: ... + def can_pan(self) -> bool: ... + def start_pan(self, x, y, button) -> None: ... + def end_pan(self) -> None: ... + def drag_pan(self, button, key, x, y) -> None: ... + +class _GeoTransform(Transform): + input_dims: int + output_dims: int + def __init__(self, resolution: int) -> None: ... + +class AitoffAxes(GeoAxes): + name: str + + class AitoffTransform(_GeoTransform): + def inverted(self) -> AitoffAxes.InvertedAitoffTransform: ... + + class InvertedAitoffTransform(_GeoTransform): + def inverted(self) -> AitoffAxes.AitoffTransform: ... + +class HammerAxes(GeoAxes): + name: str + + class HammerTransform(_GeoTransform): + def inverted(self) -> HammerAxes.InvertedHammerTransform: ... + + class InvertedHammerTransform(_GeoTransform): + def inverted(self) -> HammerAxes.HammerTransform: ... + +class MollweideAxes(GeoAxes): + name: str + + class MollweideTransform(_GeoTransform): + def inverted(self) -> MollweideAxes.InvertedMollweideTransform: ... + + class InvertedMollweideTransform(_GeoTransform): + def inverted(self) -> MollweideAxes.MollweideTransform: ... + +class LambertAxes(GeoAxes): + name: str + + class LambertTransform(_GeoTransform): + def __init__( + self, center_longitude: float, center_latitude: float, resolution: int + ) -> None: ... + def inverted(self) -> LambertAxes.InvertedLambertTransform: ... + + class InvertedLambertTransform(_GeoTransform): + def __init__( + self, center_longitude: float, center_latitude: float, resolution: int + ) -> None: ... + def inverted(self) -> LambertAxes.LambertTransform: ... + + def __init__( + self, + *args, + center_longitude: float = ..., + center_latitude: float = ..., + **kwargs + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.py new file mode 100644 index 00000000..0bff320e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.py @@ -0,0 +1,1536 @@ +import math +import types + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook +from matplotlib.axes import Axes +import matplotlib.axis as maxis +import matplotlib.markers as mmarkers +import matplotlib.patches as mpatches +from matplotlib.path import Path +import matplotlib.ticker as mticker +import matplotlib.transforms as mtransforms +from matplotlib.spines import Spine + + +class PolarTransform(mtransforms.Transform): + r""" + The base polar transform. + + This transform maps polar coordinates :math:`\theta, r` into Cartesian + coordinates :math:`x, y = r \cos(\theta), r \sin(\theta)` + (but does not fully transform into Axes coordinates or + handle positioning in screen space). + + This transformation is designed to be applied to data after any scaling + along the radial axis (e.g. log-scaling) has been applied to the input + data. + + Path segments at a fixed radius are automatically transformed to circular + arcs as long as ``path._interpolation_steps > 1``. + """ + + input_dims = output_dims = 2 + + def __init__(self, axis=None, use_rmin=True, + _apply_theta_transforms=True, *, scale_transform=None): + """ + Parameters + ---------- + axis : `~matplotlib.axis.Axis`, optional + Axis associated with this transform. This is used to get the + minimum radial limit. + use_rmin : `bool`, optional + If ``True``, subtract the minimum radial axis limit before + transforming to Cartesian coordinates. *axis* must also be + specified for this to take effect. + """ + super().__init__() + self._axis = axis + self._use_rmin = use_rmin + self._apply_theta_transforms = _apply_theta_transforms + self._scale_transform = scale_transform + + __str__ = mtransforms._make_str_method( + "_axis", + use_rmin="_use_rmin", + _apply_theta_transforms="_apply_theta_transforms") + + def _get_rorigin(self): + # Get lower r limit after being scaled by the radial scale transform + return self._scale_transform.transform( + (0, self._axis.get_rorigin()))[1] + + @_api.rename_parameter("3.8", "tr", "values") + def transform_non_affine(self, values): + # docstring inherited + theta, r = np.transpose(values) + # PolarAxes does not use the theta transforms here, but apply them for + # backwards-compatibility if not being used by it. + if self._apply_theta_transforms and self._axis is not None: + theta *= self._axis.get_theta_direction() + theta += self._axis.get_theta_offset() + if self._use_rmin and self._axis is not None: + r = (r - self._get_rorigin()) * self._axis.get_rsign() + r = np.where(r >= 0, r, np.nan) + return np.column_stack([r * np.cos(theta), r * np.sin(theta)]) + + def transform_path_non_affine(self, path): + # docstring inherited + if not len(path) or path._interpolation_steps == 1: + return Path(self.transform_non_affine(path.vertices), path.codes) + xys = [] + codes = [] + last_t = last_r = None + for trs, c in path.iter_segments(): + trs = trs.reshape((-1, 2)) + if c == Path.LINETO: + (t, r), = trs + if t == last_t: # Same angle: draw a straight line. + xys.extend(self.transform_non_affine(trs)) + codes.append(Path.LINETO) + elif r == last_r: # Same radius: draw an arc. + # The following is complicated by Path.arc() being + # "helpful" and unwrapping the angles, but we don't want + # that behavior here. + last_td, td = np.rad2deg([last_t, t]) + if self._use_rmin and self._axis is not None: + r = ((r - self._get_rorigin()) + * self._axis.get_rsign()) + if last_td <= td: + while td - last_td > 360: + arc = Path.arc(last_td, last_td + 360) + xys.extend(arc.vertices[1:] * r) + codes.extend(arc.codes[1:]) + last_td += 360 + arc = Path.arc(last_td, td) + xys.extend(arc.vertices[1:] * r) + codes.extend(arc.codes[1:]) + else: + # The reverse version also relies on the fact that all + # codes but the first one are the same. + while last_td - td > 360: + arc = Path.arc(last_td - 360, last_td) + xys.extend(arc.vertices[::-1][1:] * r) + codes.extend(arc.codes[1:]) + last_td -= 360 + arc = Path.arc(td, last_td) + xys.extend(arc.vertices[::-1][1:] * r) + codes.extend(arc.codes[1:]) + else: # Interpolate. + trs = cbook.simple_linear_interpolation( + np.vstack([(last_t, last_r), trs]), + path._interpolation_steps)[1:] + xys.extend(self.transform_non_affine(trs)) + codes.extend([Path.LINETO] * len(trs)) + else: # Not a straight line. + xys.extend(self.transform_non_affine(trs)) + codes.extend([c] * len(trs)) + last_t, last_r = trs[-1] + return Path(xys, codes) + + def inverted(self): + # docstring inherited + return PolarAxes.InvertedPolarTransform(self._axis, self._use_rmin, + self._apply_theta_transforms) + + +class PolarAffine(mtransforms.Affine2DBase): + r""" + The affine part of the polar projection. + + Scales the output so that maximum radius rests on the edge of the axes + circle and the origin is mapped to (0.5, 0.5). The transform applied is + the same to x and y components and given by: + + .. math:: + + x_{1} = 0.5 \left [ \frac{x_{0}}{(r_{\max} - r_{\min})} + 1 \right ] + + :math:`r_{\min}, r_{\max}` are the minimum and maximum radial limits after + any scaling (e.g. log scaling) has been removed. + """ + def __init__(self, scale_transform, limits): + """ + Parameters + ---------- + scale_transform : `~matplotlib.transforms.Transform` + Scaling transform for the data. This is used to remove any scaling + from the radial view limits. + limits : `~matplotlib.transforms.BboxBase` + View limits of the data. The only part of its bounds that is used + is the y limits (for the radius limits). + """ + super().__init__() + self._scale_transform = scale_transform + self._limits = limits + self.set_children(scale_transform, limits) + self._mtx = None + + __str__ = mtransforms._make_str_method("_scale_transform", "_limits") + + def get_matrix(self): + # docstring inherited + if self._invalid: + limits_scaled = self._limits.transformed(self._scale_transform) + yscale = limits_scaled.ymax - limits_scaled.ymin + affine = mtransforms.Affine2D() \ + .scale(0.5 / yscale) \ + .translate(0.5, 0.5) + self._mtx = affine.get_matrix() + self._inverted = None + self._invalid = 0 + return self._mtx + + +class InvertedPolarTransform(mtransforms.Transform): + """ + The inverse of the polar transform, mapping Cartesian + coordinate space *x* and *y* back to *theta* and *r*. + """ + input_dims = output_dims = 2 + + def __init__(self, axis=None, use_rmin=True, + _apply_theta_transforms=True): + """ + Parameters + ---------- + axis : `~matplotlib.axis.Axis`, optional + Axis associated with this transform. This is used to get the + minimum radial limit. + use_rmin : `bool`, optional + If ``True`` add the minimum radial axis limit after + transforming from Cartesian coordinates. *axis* must also be + specified for this to take effect. + """ + super().__init__() + self._axis = axis + self._use_rmin = use_rmin + self._apply_theta_transforms = _apply_theta_transforms + + __str__ = mtransforms._make_str_method( + "_axis", + use_rmin="_use_rmin", + _apply_theta_transforms="_apply_theta_transforms") + + @_api.rename_parameter("3.8", "xy", "values") + def transform_non_affine(self, values): + # docstring inherited + x, y = values.T + r = np.hypot(x, y) + theta = (np.arctan2(y, x) + 2 * np.pi) % (2 * np.pi) + # PolarAxes does not use the theta transforms here, but apply them for + # backwards-compatibility if not being used by it. + if self._apply_theta_transforms and self._axis is not None: + theta -= self._axis.get_theta_offset() + theta *= self._axis.get_theta_direction() + theta %= 2 * np.pi + if self._use_rmin and self._axis is not None: + r += self._axis.get_rorigin() + r *= self._axis.get_rsign() + return np.column_stack([theta, r]) + + def inverted(self): + # docstring inherited + return PolarAxes.PolarTransform(self._axis, self._use_rmin, + self._apply_theta_transforms) + + +class ThetaFormatter(mticker.Formatter): + """ + Used to format the *theta* tick labels. Converts the native + unit of radians into degrees and adds a degree symbol. + """ + + def __call__(self, x, pos=None): + vmin, vmax = self.axis.get_view_interval() + d = np.rad2deg(abs(vmax - vmin)) + digits = max(-int(np.log10(d) - 1.5), 0) + # Use Unicode rather than mathtext with \circ, so that it will work + # correctly with any arbitrary font (assuming it has a degree sign), + # whereas $5\circ$ will only work correctly with one of the supported + # math fonts (Computer Modern and STIX). + return f"{np.rad2deg(x):0.{digits:d}f}\N{DEGREE SIGN}" + + +class _AxisWrapper: + def __init__(self, axis): + self._axis = axis + + def get_view_interval(self): + return np.rad2deg(self._axis.get_view_interval()) + + def set_view_interval(self, vmin, vmax): + self._axis.set_view_interval(*np.deg2rad((vmin, vmax))) + + def get_minpos(self): + return np.rad2deg(self._axis.get_minpos()) + + def get_data_interval(self): + return np.rad2deg(self._axis.get_data_interval()) + + def set_data_interval(self, vmin, vmax): + self._axis.set_data_interval(*np.deg2rad((vmin, vmax))) + + def get_tick_space(self): + return self._axis.get_tick_space() + + +class ThetaLocator(mticker.Locator): + """ + Used to locate theta ticks. + + This will work the same as the base locator except in the case that the + view spans the entire circle. In such cases, the previously used default + locations of every 45 degrees are returned. + """ + + def __init__(self, base): + self.base = base + self.axis = self.base.axis = _AxisWrapper(self.base.axis) + + def set_axis(self, axis): + self.axis = _AxisWrapper(axis) + self.base.set_axis(self.axis) + + def __call__(self): + lim = self.axis.get_view_interval() + if _is_full_circle_deg(lim[0], lim[1]): + return np.arange(8) * 2 * np.pi / 8 + else: + return np.deg2rad(self.base()) + + def view_limits(self, vmin, vmax): + vmin, vmax = np.rad2deg((vmin, vmax)) + return np.deg2rad(self.base.view_limits(vmin, vmax)) + + +class ThetaTick(maxis.XTick): + """ + A theta-axis tick. + + This subclass of `.XTick` provides angular ticks with some small + modification to their re-positioning such that ticks are rotated based on + tick location. This results in ticks that are correctly perpendicular to + the arc spine. + + When 'auto' rotation is enabled, labels are also rotated to be parallel to + the spine. The label padding is also applied here since it's not possible + to use a generic axes transform to produce tick-specific padding. + """ + + def __init__(self, axes, *args, **kwargs): + self._text1_translate = mtransforms.ScaledTranslation( + 0, 0, axes.figure.dpi_scale_trans) + self._text2_translate = mtransforms.ScaledTranslation( + 0, 0, axes.figure.dpi_scale_trans) + super().__init__(axes, *args, **kwargs) + self.label1.set( + rotation_mode='anchor', + transform=self.label1.get_transform() + self._text1_translate) + self.label2.set( + rotation_mode='anchor', + transform=self.label2.get_transform() + self._text2_translate) + + def _apply_params(self, **kwargs): + super()._apply_params(**kwargs) + # Ensure transform is correct; sometimes this gets reset. + trans = self.label1.get_transform() + if not trans.contains_branch(self._text1_translate): + self.label1.set_transform(trans + self._text1_translate) + trans = self.label2.get_transform() + if not trans.contains_branch(self._text2_translate): + self.label2.set_transform(trans + self._text2_translate) + + def _update_padding(self, pad, angle): + padx = pad * np.cos(angle) / 72 + pady = pad * np.sin(angle) / 72 + self._text1_translate._t = (padx, pady) + self._text1_translate.invalidate() + self._text2_translate._t = (-padx, -pady) + self._text2_translate.invalidate() + + def update_position(self, loc): + super().update_position(loc) + axes = self.axes + angle = loc * axes.get_theta_direction() + axes.get_theta_offset() + text_angle = np.rad2deg(angle) % 360 - 90 + angle -= np.pi / 2 + + marker = self.tick1line.get_marker() + if marker in (mmarkers.TICKUP, '|'): + trans = mtransforms.Affine2D().scale(1, 1).rotate(angle) + elif marker == mmarkers.TICKDOWN: + trans = mtransforms.Affine2D().scale(1, -1).rotate(angle) + else: + # Don't modify custom tick line markers. + trans = self.tick1line._marker._transform + self.tick1line._marker._transform = trans + + marker = self.tick2line.get_marker() + if marker in (mmarkers.TICKUP, '|'): + trans = mtransforms.Affine2D().scale(1, 1).rotate(angle) + elif marker == mmarkers.TICKDOWN: + trans = mtransforms.Affine2D().scale(1, -1).rotate(angle) + else: + # Don't modify custom tick line markers. + trans = self.tick2line._marker._transform + self.tick2line._marker._transform = trans + + mode, user_angle = self._labelrotation + if mode == 'default': + text_angle = user_angle + else: + if text_angle > 90: + text_angle -= 180 + elif text_angle < -90: + text_angle += 180 + text_angle += user_angle + self.label1.set_rotation(text_angle) + self.label2.set_rotation(text_angle) + + # This extra padding helps preserve the look from previous releases but + # is also needed because labels are anchored to their center. + pad = self._pad + 7 + self._update_padding(pad, + self._loc * axes.get_theta_direction() + + axes.get_theta_offset()) + + +class ThetaAxis(maxis.XAxis): + """ + A theta Axis. + + This overrides certain properties of an `.XAxis` to provide special-casing + for an angular axis. + """ + __name__ = 'thetaaxis' + axis_name = 'theta' #: Read-only name identifying the axis. + _tick_class = ThetaTick + + def _wrap_locator_formatter(self): + self.set_major_locator(ThetaLocator(self.get_major_locator())) + self.set_major_formatter(ThetaFormatter()) + self.isDefault_majloc = True + self.isDefault_majfmt = True + + def clear(self): + # docstring inherited + super().clear() + self.set_ticks_position('none') + self._wrap_locator_formatter() + + def _set_scale(self, value, **kwargs): + if value != 'linear': + raise NotImplementedError( + "The xscale cannot be set on a polar plot") + super()._set_scale(value, **kwargs) + # LinearScale.set_default_locators_and_formatters just set the major + # locator to be an AutoLocator, so we customize it here to have ticks + # at sensible degree multiples. + self.get_major_locator().set_params(steps=[1, 1.5, 3, 4.5, 9, 10]) + self._wrap_locator_formatter() + + def _copy_tick_props(self, src, dest): + """Copy the props from src tick to dest tick.""" + if src is None or dest is None: + return + super()._copy_tick_props(src, dest) + + # Ensure that tick transforms are independent so that padding works. + trans = dest._get_text1_transform()[0] + dest.label1.set_transform(trans + dest._text1_translate) + trans = dest._get_text2_transform()[0] + dest.label2.set_transform(trans + dest._text2_translate) + + +class RadialLocator(mticker.Locator): + """ + Used to locate radius ticks. + + Ensures that all ticks are strictly positive. For all other tasks, it + delegates to the base `.Locator` (which may be different depending on the + scale of the *r*-axis). + """ + + def __init__(self, base, axes=None): + self.base = base + self._axes = axes + + def set_axis(self, axis): + self.base.set_axis(axis) + + def __call__(self): + # Ensure previous behaviour with full circle non-annular views. + if self._axes: + if _is_full_circle_rad(*self._axes.viewLim.intervalx): + rorigin = self._axes.get_rorigin() * self._axes.get_rsign() + if self._axes.get_rmin() <= rorigin: + return [tick for tick in self.base() if tick > rorigin] + return self.base() + + def _zero_in_bounds(self): + """ + Return True if zero is within the valid values for the + scale of the radial axis. + """ + vmin, vmax = self._axes.yaxis._scale.limit_range_for_scale(0, 1, 1e-5) + return vmin == 0 + + def nonsingular(self, vmin, vmax): + # docstring inherited + if self._zero_in_bounds() and (vmin, vmax) == (-np.inf, np.inf): + # Initial view limits + return (0, 1) + else: + return self.base.nonsingular(vmin, vmax) + + def view_limits(self, vmin, vmax): + vmin, vmax = self.base.view_limits(vmin, vmax) + if self._zero_in_bounds() and vmax > vmin: + # this allows inverted r/y-lims + vmin = min(0, vmin) + return mtransforms.nonsingular(vmin, vmax) + + +class _ThetaShift(mtransforms.ScaledTranslation): + """ + Apply a padding shift based on axes theta limits. + + This is used to create padding for radial ticks. + + Parameters + ---------- + axes : `~matplotlib.axes.Axes` + The owning axes; used to determine limits. + pad : float + The padding to apply, in points. + mode : {'min', 'max', 'rlabel'} + Whether to shift away from the start (``'min'``) or the end (``'max'``) + of the axes, or using the rlabel position (``'rlabel'``). + """ + def __init__(self, axes, pad, mode): + super().__init__(pad, pad, axes.figure.dpi_scale_trans) + self.set_children(axes._realViewLim) + self.axes = axes + self.mode = mode + self.pad = pad + + __str__ = mtransforms._make_str_method("axes", "pad", "mode") + + def get_matrix(self): + if self._invalid: + if self.mode == 'rlabel': + angle = ( + np.deg2rad(self.axes.get_rlabel_position()) * + self.axes.get_theta_direction() + + self.axes.get_theta_offset() + ) + else: + if self.mode == 'min': + angle = self.axes._realViewLim.xmin + elif self.mode == 'max': + angle = self.axes._realViewLim.xmax + + if self.mode in ('rlabel', 'min'): + padx = np.cos(angle - np.pi / 2) + pady = np.sin(angle - np.pi / 2) + else: + padx = np.cos(angle + np.pi / 2) + pady = np.sin(angle + np.pi / 2) + + self._t = (self.pad * padx / 72, self.pad * pady / 72) + return super().get_matrix() + + +class RadialTick(maxis.YTick): + """ + A radial-axis tick. + + This subclass of `.YTick` provides radial ticks with some small + modification to their re-positioning such that ticks are rotated based on + axes limits. This results in ticks that are correctly perpendicular to + the spine. Labels are also rotated to be perpendicular to the spine, when + 'auto' rotation is enabled. + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.label1.set_rotation_mode('anchor') + self.label2.set_rotation_mode('anchor') + + def _determine_anchor(self, mode, angle, start): + # Note: angle is the (spine angle - 90) because it's used for the tick + # & text setup, so all numbers below are -90 from (normed) spine angle. + if mode == 'auto': + if start: + if -90 <= angle <= 90: + return 'left', 'center' + else: + return 'right', 'center' + else: + if -90 <= angle <= 90: + return 'right', 'center' + else: + return 'left', 'center' + else: + if start: + if angle < -68.5: + return 'center', 'top' + elif angle < -23.5: + return 'left', 'top' + elif angle < 22.5: + return 'left', 'center' + elif angle < 67.5: + return 'left', 'bottom' + elif angle < 112.5: + return 'center', 'bottom' + elif angle < 157.5: + return 'right', 'bottom' + elif angle < 202.5: + return 'right', 'center' + elif angle < 247.5: + return 'right', 'top' + else: + return 'center', 'top' + else: + if angle < -68.5: + return 'center', 'bottom' + elif angle < -23.5: + return 'right', 'bottom' + elif angle < 22.5: + return 'right', 'center' + elif angle < 67.5: + return 'right', 'top' + elif angle < 112.5: + return 'center', 'top' + elif angle < 157.5: + return 'left', 'top' + elif angle < 202.5: + return 'left', 'center' + elif angle < 247.5: + return 'left', 'bottom' + else: + return 'center', 'bottom' + + def update_position(self, loc): + super().update_position(loc) + axes = self.axes + thetamin = axes.get_thetamin() + thetamax = axes.get_thetamax() + direction = axes.get_theta_direction() + offset_rad = axes.get_theta_offset() + offset = np.rad2deg(offset_rad) + full = _is_full_circle_deg(thetamin, thetamax) + + if full: + angle = (axes.get_rlabel_position() * direction + + offset) % 360 - 90 + tick_angle = 0 + else: + angle = (thetamin * direction + offset) % 360 - 90 + if direction > 0: + tick_angle = np.deg2rad(angle) + else: + tick_angle = np.deg2rad(angle + 180) + text_angle = (angle + 90) % 180 - 90 # between -90 and +90. + mode, user_angle = self._labelrotation + if mode == 'auto': + text_angle += user_angle + else: + text_angle = user_angle + + if full: + ha = self.label1.get_horizontalalignment() + va = self.label1.get_verticalalignment() + else: + ha, va = self._determine_anchor(mode, angle, direction > 0) + self.label1.set_horizontalalignment(ha) + self.label1.set_verticalalignment(va) + self.label1.set_rotation(text_angle) + + marker = self.tick1line.get_marker() + if marker == mmarkers.TICKLEFT: + trans = mtransforms.Affine2D().rotate(tick_angle) + elif marker == '_': + trans = mtransforms.Affine2D().rotate(tick_angle + np.pi / 2) + elif marker == mmarkers.TICKRIGHT: + trans = mtransforms.Affine2D().scale(-1, 1).rotate(tick_angle) + else: + # Don't modify custom tick line markers. + trans = self.tick1line._marker._transform + self.tick1line._marker._transform = trans + + if full: + self.label2.set_visible(False) + self.tick2line.set_visible(False) + angle = (thetamax * direction + offset) % 360 - 90 + if direction > 0: + tick_angle = np.deg2rad(angle) + else: + tick_angle = np.deg2rad(angle + 180) + text_angle = (angle + 90) % 180 - 90 # between -90 and +90. + mode, user_angle = self._labelrotation + if mode == 'auto': + text_angle += user_angle + else: + text_angle = user_angle + + ha, va = self._determine_anchor(mode, angle, direction < 0) + self.label2.set_ha(ha) + self.label2.set_va(va) + self.label2.set_rotation(text_angle) + + marker = self.tick2line.get_marker() + if marker == mmarkers.TICKLEFT: + trans = mtransforms.Affine2D().rotate(tick_angle) + elif marker == '_': + trans = mtransforms.Affine2D().rotate(tick_angle + np.pi / 2) + elif marker == mmarkers.TICKRIGHT: + trans = mtransforms.Affine2D().scale(-1, 1).rotate(tick_angle) + else: + # Don't modify custom tick line markers. + trans = self.tick2line._marker._transform + self.tick2line._marker._transform = trans + + +class RadialAxis(maxis.YAxis): + """ + A radial Axis. + + This overrides certain properties of a `.YAxis` to provide special-casing + for a radial axis. + """ + __name__ = 'radialaxis' + axis_name = 'radius' #: Read-only name identifying the axis. + _tick_class = RadialTick + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.sticky_edges.y.append(0) + + def _wrap_locator_formatter(self): + self.set_major_locator(RadialLocator(self.get_major_locator(), + self.axes)) + self.isDefault_majloc = True + + def clear(self): + # docstring inherited + super().clear() + self.set_ticks_position('none') + self._wrap_locator_formatter() + + def _set_scale(self, value, **kwargs): + super()._set_scale(value, **kwargs) + self._wrap_locator_formatter() + + +def _is_full_circle_deg(thetamin, thetamax): + """ + Determine if a wedge (in degrees) spans the full circle. + + The condition is derived from :class:`~matplotlib.patches.Wedge`. + """ + return abs(abs(thetamax - thetamin) - 360.0) < 1e-12 + + +def _is_full_circle_rad(thetamin, thetamax): + """ + Determine if a wedge (in radians) spans the full circle. + + The condition is derived from :class:`~matplotlib.patches.Wedge`. + """ + return abs(abs(thetamax - thetamin) - 2 * np.pi) < 1.74e-14 + + +class _WedgeBbox(mtransforms.Bbox): + """ + Transform (theta, r) wedge Bbox into axes bounding box. + + Parameters + ---------- + center : (float, float) + Center of the wedge + viewLim : `~matplotlib.transforms.Bbox` + Bbox determining the boundaries of the wedge + originLim : `~matplotlib.transforms.Bbox` + Bbox determining the origin for the wedge, if different from *viewLim* + """ + def __init__(self, center, viewLim, originLim, **kwargs): + super().__init__([[0, 0], [1, 1]], **kwargs) + self._center = center + self._viewLim = viewLim + self._originLim = originLim + self.set_children(viewLim, originLim) + + __str__ = mtransforms._make_str_method("_center", "_viewLim", "_originLim") + + def get_points(self): + # docstring inherited + if self._invalid: + points = self._viewLim.get_points().copy() + # Scale angular limits to work with Wedge. + points[:, 0] *= 180 / np.pi + if points[0, 0] > points[1, 0]: + points[:, 0] = points[::-1, 0] + + # Scale radial limits based on origin radius. + points[:, 1] -= self._originLim.y0 + + # Scale radial limits to match axes limits. + rscale = 0.5 / points[1, 1] + points[:, 1] *= rscale + width = min(points[1, 1] - points[0, 1], 0.5) + + # Generate bounding box for wedge. + wedge = mpatches.Wedge(self._center, points[1, 1], + points[0, 0], points[1, 0], + width=width) + self.update_from_path(wedge.get_path()) + + # Ensure equal aspect ratio. + w, h = self._points[1] - self._points[0] + deltah = max(w - h, 0) / 2 + deltaw = max(h - w, 0) / 2 + self._points += np.array([[-deltaw, -deltah], [deltaw, deltah]]) + + self._invalid = 0 + + return self._points + + +class PolarAxes(Axes): + """ + A polar graph projection, where the input dimensions are *theta*, *r*. + + Theta starts pointing east and goes anti-clockwise. + """ + name = 'polar' + + def __init__(self, *args, + theta_offset=0, theta_direction=1, rlabel_position=22.5, + **kwargs): + # docstring inherited + self._default_theta_offset = theta_offset + self._default_theta_direction = theta_direction + self._default_rlabel_position = np.deg2rad(rlabel_position) + super().__init__(*args, **kwargs) + self.use_sticky_edges = True + self.set_aspect('equal', adjustable='box', anchor='C') + self.clear() + + def clear(self): + # docstring inherited + super().clear() + + self.title.set_y(1.05) + + start = self.spines.get('start', None) + if start: + start.set_visible(False) + end = self.spines.get('end', None) + if end: + end.set_visible(False) + self.set_xlim(0.0, 2 * np.pi) + + self.grid(mpl.rcParams['polaraxes.grid']) + inner = self.spines.get('inner', None) + if inner: + inner.set_visible(False) + + self.set_rorigin(None) + self.set_theta_offset(self._default_theta_offset) + self.set_theta_direction(self._default_theta_direction) + + def _init_axis(self): + # This is moved out of __init__ because non-separable axes don't use it + self.xaxis = ThetaAxis(self, clear=False) + self.yaxis = RadialAxis(self, clear=False) + self.spines['polar'].register_axis(self.yaxis) + + def _set_lim_and_transforms(self): + # A view limit where the minimum radius can be locked if the user + # specifies an alternate origin. + self._originViewLim = mtransforms.LockableBbox(self.viewLim) + + # Handle angular offset and direction. + self._direction = mtransforms.Affine2D() \ + .scale(self._default_theta_direction, 1.0) + self._theta_offset = mtransforms.Affine2D() \ + .translate(self._default_theta_offset, 0.0) + self.transShift = self._direction + self._theta_offset + # A view limit shifted to the correct location after accounting for + # orientation and offset. + self._realViewLim = mtransforms.TransformedBbox(self.viewLim, + self.transShift) + + # Transforms the x and y axis separately by a scale factor + # It is assumed that this part will have non-linear components + self.transScale = mtransforms.TransformWrapper( + mtransforms.IdentityTransform()) + + # Scale view limit into a bbox around the selected wedge. This may be + # smaller than the usual unit axes rectangle if not plotting the full + # circle. + self.axesLim = _WedgeBbox((0.5, 0.5), + self._realViewLim, self._originViewLim) + + # Scale the wedge to fill the axes. + self.transWedge = mtransforms.BboxTransformFrom(self.axesLim) + + # Scale the axes to fill the figure. + self.transAxes = mtransforms.BboxTransformTo(self.bbox) + + # A (possibly non-linear) projection on the (already scaled) + # data. This one is aware of rmin + self.transProjection = self.PolarTransform( + self, + _apply_theta_transforms=False, + scale_transform=self.transScale + ) + # Add dependency on rorigin. + self.transProjection.set_children(self._originViewLim) + + # An affine transformation on the data, generally to limit the + # range of the axes + self.transProjectionAffine = self.PolarAffine(self.transScale, + self._originViewLim) + + # The complete data transformation stack -- from data all the + # way to display coordinates + # + # 1. Remove any radial axis scaling (e.g. log scaling) + # 2. Shift data in the theta direction + # 3. Project the data from polar to cartesian values + # (with the origin in the same place) + # 4. Scale and translate the cartesian values to Axes coordinates + # (here the origin is moved to the lower left of the Axes) + # 5. Move and scale to fill the Axes + # 6. Convert from Axes coordinates to Figure coordinates + self.transData = ( + self.transScale + + self.transShift + + self.transProjection + + ( + self.transProjectionAffine + + self.transWedge + + self.transAxes + ) + ) + + # This is the transform for theta-axis ticks. It is + # equivalent to transData, except it always puts r == 0.0 and r == 1.0 + # at the edge of the axis circles. + self._xaxis_transform = ( + mtransforms.blended_transform_factory( + mtransforms.IdentityTransform(), + mtransforms.BboxTransformTo(self.viewLim)) + + self.transData) + # The theta labels are flipped along the radius, so that text 1 is on + # the outside by default. This should work the same as before. + flipr_transform = mtransforms.Affine2D() \ + .translate(0.0, -0.5) \ + .scale(1.0, -1.0) \ + .translate(0.0, 0.5) + self._xaxis_text_transform = flipr_transform + self._xaxis_transform + + # This is the transform for r-axis ticks. It scales the theta + # axis so the gridlines from 0.0 to 1.0, now go from thetamin to + # thetamax. + self._yaxis_transform = ( + mtransforms.blended_transform_factory( + mtransforms.BboxTransformTo(self.viewLim), + mtransforms.IdentityTransform()) + + self.transData) + # The r-axis labels are put at an angle and padded in the r-direction + self._r_label_position = mtransforms.Affine2D() \ + .translate(self._default_rlabel_position, 0.0) + self._yaxis_text_transform = mtransforms.TransformWrapper( + self._r_label_position + self.transData) + + def get_xaxis_transform(self, which='grid'): + _api.check_in_list(['tick1', 'tick2', 'grid'], which=which) + return self._xaxis_transform + + def get_xaxis_text1_transform(self, pad): + return self._xaxis_text_transform, 'center', 'center' + + def get_xaxis_text2_transform(self, pad): + return self._xaxis_text_transform, 'center', 'center' + + def get_yaxis_transform(self, which='grid'): + if which in ('tick1', 'tick2'): + return self._yaxis_text_transform + elif which == 'grid': + return self._yaxis_transform + else: + _api.check_in_list(['tick1', 'tick2', 'grid'], which=which) + + def get_yaxis_text1_transform(self, pad): + thetamin, thetamax = self._realViewLim.intervalx + if _is_full_circle_rad(thetamin, thetamax): + return self._yaxis_text_transform, 'bottom', 'left' + elif self.get_theta_direction() > 0: + halign = 'left' + pad_shift = _ThetaShift(self, pad, 'min') + else: + halign = 'right' + pad_shift = _ThetaShift(self, pad, 'max') + return self._yaxis_text_transform + pad_shift, 'center', halign + + def get_yaxis_text2_transform(self, pad): + if self.get_theta_direction() > 0: + halign = 'right' + pad_shift = _ThetaShift(self, pad, 'max') + else: + halign = 'left' + pad_shift = _ThetaShift(self, pad, 'min') + return self._yaxis_text_transform + pad_shift, 'center', halign + + def draw(self, renderer): + self._unstale_viewLim() + thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx) + if thetamin > thetamax: + thetamin, thetamax = thetamax, thetamin + rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) * + self.get_rsign()) + if isinstance(self.patch, mpatches.Wedge): + # Backwards-compatibility: Any subclassed Axes might override the + # patch to not be the Wedge that PolarAxes uses. + center = self.transWedge.transform((0.5, 0.5)) + self.patch.set_center(center) + self.patch.set_theta1(thetamin) + self.patch.set_theta2(thetamax) + + edge, _ = self.transWedge.transform((1, 0)) + radius = edge - center[0] + width = min(radius * (rmax - rmin) / rmax, radius) + self.patch.set_radius(radius) + self.patch.set_width(width) + + inner_width = radius - width + inner = self.spines.get('inner', None) + if inner: + inner.set_visible(inner_width != 0.0) + + visible = not _is_full_circle_deg(thetamin, thetamax) + # For backwards compatibility, any subclassed Axes might override the + # spines to not include start/end that PolarAxes uses. + start = self.spines.get('start', None) + end = self.spines.get('end', None) + if start: + start.set_visible(visible) + if end: + end.set_visible(visible) + if visible: + yaxis_text_transform = self._yaxis_transform + else: + yaxis_text_transform = self._r_label_position + self.transData + if self._yaxis_text_transform != yaxis_text_transform: + self._yaxis_text_transform.set(yaxis_text_transform) + self.yaxis.reset_ticks() + self.yaxis.set_clip_path(self.patch) + + super().draw(renderer) + + def _gen_axes_patch(self): + return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0) + + def _gen_axes_spines(self): + spines = { + 'polar': Spine.arc_spine(self, 'top', (0.5, 0.5), 0.5, 0, 360), + 'start': Spine.linear_spine(self, 'left'), + 'end': Spine.linear_spine(self, 'right'), + 'inner': Spine.arc_spine(self, 'bottom', (0.5, 0.5), 0.0, 0, 360), + } + spines['polar'].set_transform(self.transWedge + self.transAxes) + spines['inner'].set_transform(self.transWedge + self.transAxes) + spines['start'].set_transform(self._yaxis_transform) + spines['end'].set_transform(self._yaxis_transform) + return spines + + def set_thetamax(self, thetamax): + """Set the maximum theta limit in degrees.""" + self.viewLim.x1 = np.deg2rad(thetamax) + + def get_thetamax(self): + """Return the maximum theta limit in degrees.""" + return np.rad2deg(self.viewLim.xmax) + + def set_thetamin(self, thetamin): + """Set the minimum theta limit in degrees.""" + self.viewLim.x0 = np.deg2rad(thetamin) + + def get_thetamin(self): + """Get the minimum theta limit in degrees.""" + return np.rad2deg(self.viewLim.xmin) + + def set_thetalim(self, *args, **kwargs): + r""" + Set the minimum and maximum theta values. + + Can take the following signatures: + + - ``set_thetalim(minval, maxval)``: Set the limits in radians. + - ``set_thetalim(thetamin=minval, thetamax=maxval)``: Set the limits + in degrees. + + where minval and maxval are the minimum and maximum limits. Values are + wrapped in to the range :math:`[0, 2\pi]` (in radians), so for example + it is possible to do ``set_thetalim(-np.pi / 2, np.pi / 2)`` to have + an axis symmetric around 0. A ValueError is raised if the absolute + angle difference is larger than a full circle. + """ + orig_lim = self.get_xlim() # in radians + if 'thetamin' in kwargs: + kwargs['xmin'] = np.deg2rad(kwargs.pop('thetamin')) + if 'thetamax' in kwargs: + kwargs['xmax'] = np.deg2rad(kwargs.pop('thetamax')) + new_min, new_max = self.set_xlim(*args, **kwargs) + # Parsing all permutations of *args, **kwargs is tricky; it is simpler + # to let set_xlim() do it and then validate the limits. + if abs(new_max - new_min) > 2 * np.pi: + self.set_xlim(orig_lim) # un-accept the change + raise ValueError("The angle range must be less than a full circle") + return tuple(np.rad2deg((new_min, new_max))) + + def set_theta_offset(self, offset): + """ + Set the offset for the location of 0 in radians. + """ + mtx = self._theta_offset.get_matrix() + mtx[0, 2] = offset + self._theta_offset.invalidate() + + def get_theta_offset(self): + """ + Get the offset for the location of 0 in radians. + """ + return self._theta_offset.get_matrix()[0, 2] + + def set_theta_zero_location(self, loc, offset=0.0): + """ + Set the location of theta's zero. + + This simply calls `set_theta_offset` with the correct value in radians. + + Parameters + ---------- + loc : str + May be one of "N", "NW", "W", "SW", "S", "SE", "E", or "NE". + offset : float, default: 0 + An offset in degrees to apply from the specified *loc*. **Note:** + this offset is *always* applied counter-clockwise regardless of + the direction setting. + """ + mapping = { + 'N': np.pi * 0.5, + 'NW': np.pi * 0.75, + 'W': np.pi, + 'SW': np.pi * 1.25, + 'S': np.pi * 1.5, + 'SE': np.pi * 1.75, + 'E': 0, + 'NE': np.pi * 0.25} + return self.set_theta_offset(mapping[loc] + np.deg2rad(offset)) + + def set_theta_direction(self, direction): + """ + Set the direction in which theta increases. + + clockwise, -1: + Theta increases in the clockwise direction + + counterclockwise, anticlockwise, 1: + Theta increases in the counterclockwise direction + """ + mtx = self._direction.get_matrix() + if direction in ('clockwise', -1): + mtx[0, 0] = -1 + elif direction in ('counterclockwise', 'anticlockwise', 1): + mtx[0, 0] = 1 + else: + _api.check_in_list( + [-1, 1, 'clockwise', 'counterclockwise', 'anticlockwise'], + direction=direction) + self._direction.invalidate() + + def get_theta_direction(self): + """ + Get the direction in which theta increases. + + -1: + Theta increases in the clockwise direction + + 1: + Theta increases in the counterclockwise direction + """ + return self._direction.get_matrix()[0, 0] + + def set_rmax(self, rmax): + """ + Set the outer radial limit. + + Parameters + ---------- + rmax : float + """ + self.viewLim.y1 = rmax + + def get_rmax(self): + """ + Returns + ------- + float + Outer radial limit. + """ + return self.viewLim.ymax + + def set_rmin(self, rmin): + """ + Set the inner radial limit. + + Parameters + ---------- + rmin : float + """ + self.viewLim.y0 = rmin + + def get_rmin(self): + """ + Returns + ------- + float + The inner radial limit. + """ + return self.viewLim.ymin + + def set_rorigin(self, rorigin): + """ + Update the radial origin. + + Parameters + ---------- + rorigin : float + """ + self._originViewLim.locked_y0 = rorigin + + def get_rorigin(self): + """ + Returns + ------- + float + """ + return self._originViewLim.y0 + + def get_rsign(self): + return np.sign(self._originViewLim.y1 - self._originViewLim.y0) + + def set_rlim(self, bottom=None, top=None, *, + emit=True, auto=False, **kwargs): + """ + Set the radial axis view limits. + + This function behaves like `.Axes.set_ylim`, but additionally supports + *rmin* and *rmax* as aliases for *bottom* and *top*. + + See Also + -------- + .Axes.set_ylim + """ + if 'rmin' in kwargs: + if bottom is None: + bottom = kwargs.pop('rmin') + else: + raise ValueError('Cannot supply both positional "bottom"' + 'argument and kwarg "rmin"') + if 'rmax' in kwargs: + if top is None: + top = kwargs.pop('rmax') + else: + raise ValueError('Cannot supply both positional "top"' + 'argument and kwarg "rmax"') + return self.set_ylim(bottom=bottom, top=top, emit=emit, auto=auto, + **kwargs) + + def get_rlabel_position(self): + """ + Returns + ------- + float + The theta position of the radius labels in degrees. + """ + return np.rad2deg(self._r_label_position.get_matrix()[0, 2]) + + def set_rlabel_position(self, value): + """ + Update the theta position of the radius labels. + + Parameters + ---------- + value : number + The angular position of the radius labels in degrees. + """ + self._r_label_position.clear().translate(np.deg2rad(value), 0.0) + + def set_yscale(self, *args, **kwargs): + super().set_yscale(*args, **kwargs) + self.yaxis.set_major_locator( + self.RadialLocator(self.yaxis.get_major_locator(), self)) + + def set_rscale(self, *args, **kwargs): + return Axes.set_yscale(self, *args, **kwargs) + + def set_rticks(self, *args, **kwargs): + return Axes.set_yticks(self, *args, **kwargs) + + def set_thetagrids(self, angles, labels=None, fmt=None, **kwargs): + """ + Set the theta gridlines in a polar plot. + + Parameters + ---------- + angles : tuple with floats, degrees + The angles of the theta gridlines. + + labels : tuple with strings or None + The labels to use at each theta gridline. The + `.projections.polar.ThetaFormatter` will be used if None. + + fmt : str or None + Format string used in `matplotlib.ticker.FormatStrFormatter`. + For example '%f'. Note that the angle that is used is in + radians. + + Returns + ------- + lines : list of `.lines.Line2D` + The theta gridlines. + + labels : list of `.text.Text` + The tick labels. + + Other Parameters + ---------------- + **kwargs + *kwargs* are optional `.Text` properties for the labels. + + .. warning:: + + This only sets the properties of the current ticks. + Ticks are not guaranteed to be persistent. Various operations + can create, delete and modify the Tick instances. There is an + imminent risk that these settings can get lost if you work on + the figure further (including also panning/zooming on a + displayed figure). + + Use `.set_tick_params` instead if possible. + + See Also + -------- + .PolarAxes.set_rgrids + .Axis.get_gridlines + .Axis.get_ticklabels + """ + + # Make sure we take into account unitized data + angles = self.convert_yunits(angles) + angles = np.deg2rad(angles) + self.set_xticks(angles) + if labels is not None: + self.set_xticklabels(labels) + elif fmt is not None: + self.xaxis.set_major_formatter(mticker.FormatStrFormatter(fmt)) + for t in self.xaxis.get_ticklabels(): + t._internal_update(kwargs) + return self.xaxis.get_ticklines(), self.xaxis.get_ticklabels() + + def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs): + """ + Set the radial gridlines on a polar plot. + + Parameters + ---------- + radii : tuple with floats + The radii for the radial gridlines + + labels : tuple with strings or None + The labels to use at each radial gridline. The + `matplotlib.ticker.ScalarFormatter` will be used if None. + + angle : float + The angular position of the radius labels in degrees. + + fmt : str or None + Format string used in `matplotlib.ticker.FormatStrFormatter`. + For example '%f'. + + Returns + ------- + lines : list of `.lines.Line2D` + The radial gridlines. + + labels : list of `.text.Text` + The tick labels. + + Other Parameters + ---------------- + **kwargs + *kwargs* are optional `.Text` properties for the labels. + + .. warning:: + + This only sets the properties of the current ticks. + Ticks are not guaranteed to be persistent. Various operations + can create, delete and modify the Tick instances. There is an + imminent risk that these settings can get lost if you work on + the figure further (including also panning/zooming on a + displayed figure). + + Use `.set_tick_params` instead if possible. + + See Also + -------- + .PolarAxes.set_thetagrids + .Axis.get_gridlines + .Axis.get_ticklabels + """ + # Make sure we take into account unitized data + radii = self.convert_xunits(radii) + radii = np.asarray(radii) + + self.set_yticks(radii) + if labels is not None: + self.set_yticklabels(labels) + elif fmt is not None: + self.yaxis.set_major_formatter(mticker.FormatStrFormatter(fmt)) + if angle is None: + angle = self.get_rlabel_position() + self.set_rlabel_position(angle) + for t in self.yaxis.get_ticklabels(): + t._internal_update(kwargs) + return self.yaxis.get_gridlines(), self.yaxis.get_ticklabels() + + def format_coord(self, theta, r): + # docstring inherited + screen_xy = self.transData.transform((theta, r)) + screen_xys = screen_xy + np.stack( + np.meshgrid([-1, 0, 1], [-1, 0, 1])).reshape((2, -1)).T + ts, rs = self.transData.inverted().transform(screen_xys).T + delta_t = abs((ts - theta + np.pi) % (2 * np.pi) - np.pi).max() + delta_t_halfturns = delta_t / np.pi + delta_t_degrees = delta_t_halfturns * 180 + delta_r = abs(rs - r).max() + if theta < 0: + theta += 2 * np.pi + theta_halfturns = theta / np.pi + theta_degrees = theta_halfturns * 180 + + # See ScalarFormatter.format_data_short. For r, use #g-formatting + # (as for linear axes), but for theta, use f-formatting as scientific + # notation doesn't make sense and the trailing dot is ugly. + def format_sig(value, delta, opt, fmt): + # For "f", only count digits after decimal point. + prec = (max(0, -math.floor(math.log10(delta))) if fmt == "f" else + cbook._g_sig_digits(value, delta)) + return f"{value:-{opt}.{prec}{fmt}}" + + return ('\N{GREEK SMALL LETTER THETA}={}\N{GREEK SMALL LETTER PI} ' + '({}\N{DEGREE SIGN}), r={}').format( + format_sig(theta_halfturns, delta_t_halfturns, "", "f"), + format_sig(theta_degrees, delta_t_degrees, "", "f"), + format_sig(r, delta_r, "#", "g"), + ) + + def get_data_ratio(self): + """ + Return the aspect ratio of the data itself. For a polar plot, + this should always be 1.0 + """ + return 1.0 + + # # # Interactive panning + + def can_zoom(self): + """ + Return whether this Axes supports the zoom box button functionality. + + A polar Axes does not support zoom boxes. + """ + return False + + def can_pan(self): + """ + Return whether this Axes supports the pan/zoom button functionality. + + For a polar Axes, this is slightly misleading. Both panning and + zooming are performed by the same button. Panning is performed + in azimuth while zooming is done along the radial. + """ + return True + + def start_pan(self, x, y, button): + angle = np.deg2rad(self.get_rlabel_position()) + mode = '' + if button == 1: + epsilon = np.pi / 45.0 + t, r = self.transData.inverted().transform((x, y)) + if angle - epsilon <= t <= angle + epsilon: + mode = 'drag_r_labels' + elif button == 3: + mode = 'zoom' + + self._pan_start = types.SimpleNamespace( + rmax=self.get_rmax(), + trans=self.transData.frozen(), + trans_inverse=self.transData.inverted().frozen(), + r_label_angle=self.get_rlabel_position(), + x=x, + y=y, + mode=mode) + + def end_pan(self): + del self._pan_start + + def drag_pan(self, button, key, x, y): + p = self._pan_start + + if p.mode == 'drag_r_labels': + (startt, startr), (t, r) = p.trans_inverse.transform( + [(p.x, p.y), (x, y)]) + + # Deal with theta + dt = np.rad2deg(startt - t) + self.set_rlabel_position(p.r_label_angle - dt) + + trans, vert1, horiz1 = self.get_yaxis_text1_transform(0.0) + trans, vert2, horiz2 = self.get_yaxis_text2_transform(0.0) + for t in self.yaxis.majorTicks + self.yaxis.minorTicks: + t.label1.set_va(vert1) + t.label1.set_ha(horiz1) + t.label2.set_va(vert2) + t.label2.set_ha(horiz2) + + elif p.mode == 'zoom': + (startt, startr), (t, r) = p.trans_inverse.transform( + [(p.x, p.y), (x, y)]) + + # Deal with r + scale = r / startr + self.set_rmax(p.rmax / scale) + + +# To keep things all self-contained, we can put aliases to the Polar classes +# defined above. This isn't strictly necessary, but it makes some of the +# code more readable, and provides a backwards compatible Polar API. In +# particular, this is used by the :doc:`/gallery/specialty_plots/radar_chart` +# example to override PolarTransform on a PolarAxes subclass, so make sure that +# that example is unaffected before changing this. +PolarAxes.PolarTransform = PolarTransform +PolarAxes.PolarAffine = PolarAffine +PolarAxes.InvertedPolarTransform = InvertedPolarTransform +PolarAxes.ThetaFormatter = ThetaFormatter +PolarAxes.RadialLocator = RadialLocator +PolarAxes.ThetaLocator = ThetaLocator diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.pyi new file mode 100644 index 00000000..2592d494 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/projections/polar.pyi @@ -0,0 +1,196 @@ +import matplotlib.axis as maxis +import matplotlib.ticker as mticker +import matplotlib.transforms as mtransforms +from matplotlib.axes import Axes +from matplotlib.lines import Line2D +from matplotlib.text import Text + +import numpy as np +from numpy.typing import ArrayLike +from collections.abc import Sequence +from typing import Any, ClassVar, Literal, overload + +class PolarTransform(mtransforms.Transform): + input_dims: int + output_dims: int + def __init__( + self, + axis: PolarAxes | None = ..., + use_rmin: bool = ..., + _apply_theta_transforms: bool = ..., + *, + scale_transform: mtransforms.Transform | None = ..., + ) -> None: ... + def inverted(self) -> InvertedPolarTransform: ... + +class PolarAffine(mtransforms.Affine2DBase): + def __init__( + self, scale_transform: mtransforms.Transform, limits: mtransforms.BboxBase + ) -> None: ... + +class InvertedPolarTransform(mtransforms.Transform): + input_dims: int + output_dims: int + def __init__( + self, + axis: PolarAxes | None = ..., + use_rmin: bool = ..., + _apply_theta_transforms: bool = ..., + ) -> None: ... + def inverted(self) -> PolarTransform: ... + +class ThetaFormatter(mticker.Formatter): ... + +class _AxisWrapper: + def __init__(self, axis: maxis.Axis) -> None: ... + def get_view_interval(self) -> np.ndarray: ... + def set_view_interval(self, vmin: float, vmax: float) -> None: ... + def get_minpos(self) -> float: ... + def get_data_interval(self) -> np.ndarray: ... + def set_data_interval(self, vmin: float, vmax: float) -> None: ... + def get_tick_space(self) -> int: ... + +class ThetaLocator(mticker.Locator): + base: mticker.Locator + axis: _AxisWrapper | None + def __init__(self, base: mticker.Locator) -> None: ... + +class ThetaTick(maxis.XTick): + def __init__(self, axes: PolarAxes, *args, **kwargs) -> None: ... + +class ThetaAxis(maxis.XAxis): + axis_name: str + +class RadialLocator(mticker.Locator): + base: mticker.Locator + def __init__(self, base, axes: PolarAxes | None = ...) -> None: ... + +class RadialTick(maxis.YTick): ... + +class RadialAxis(maxis.YAxis): + axis_name: str + +class _WedgeBbox(mtransforms.Bbox): + def __init__( + self, + center: tuple[float, float], + viewLim: mtransforms.Bbox, + originLim: mtransforms.Bbox, + **kwargs, + ) -> None: ... + +class PolarAxes(Axes): + + PolarTransform: ClassVar[type] = PolarTransform + PolarAffine: ClassVar[type] = PolarAffine + InvertedPolarTransform: ClassVar[type] = InvertedPolarTransform + ThetaFormatter: ClassVar[type] = ThetaFormatter + RadialLocator: ClassVar[type] = RadialLocator + ThetaLocator: ClassVar[type] = ThetaLocator + + name: str + use_sticky_edges: bool + def __init__( + self, + *args, + theta_offset: float = ..., + theta_direction: float = ..., + rlabel_position: float = ..., + **kwargs, + ) -> None: ... + def get_xaxis_transform( + self, which: Literal["tick1", "tick2", "grid"] = ... + ) -> mtransforms.Transform: ... + def get_xaxis_text1_transform( + self, pad: float + ) -> tuple[ + mtransforms.Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_xaxis_text2_transform( + self, pad: float + ) -> tuple[ + mtransforms.Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_yaxis_transform( + self, which: Literal["tick1", "tick2", "grid"] = ... + ) -> mtransforms.Transform: ... + def get_yaxis_text1_transform( + self, pad: float + ) -> tuple[ + mtransforms.Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def get_yaxis_text2_transform( + self, pad: float + ) -> tuple[ + mtransforms.Transform, + Literal["center", "top", "bottom", "baseline", "center_baseline"], + Literal["center", "left", "right"], + ]: ... + def set_thetamax(self, thetamax: float) -> None: ... + def get_thetamax(self) -> float: ... + def set_thetamin(self, thetamin: float) -> None: ... + def get_thetamin(self) -> float: ... + @overload + def set_thetalim(self, minval: float, maxval: float, /) -> tuple[float, float]: ... + @overload + def set_thetalim(self, *, thetamin: float, thetamax: float) -> tuple[float, float]: ... + def set_theta_offset(self, offset: float) -> None: ... + def get_theta_offset(self) -> float: ... + def set_theta_zero_location( + self, + loc: Literal["N", "NW", "W", "SW", "S", "SE", "E", "NE"], + offset: float = ..., + ) -> None: ... + def set_theta_direction( + self, + direction: Literal[-1, 1, "clockwise", "counterclockwise", "anticlockwise"], + ) -> None: ... + def get_theta_direction(self) -> Literal[-1, 1]: ... + def set_rmax(self, rmax: float) -> None: ... + def get_rmax(self) -> float: ... + def set_rmin(self, rmin: float) -> None: ... + def get_rmin(self) -> float: ... + def set_rorigin(self, rorigin: float | None) -> None: ... + def get_rorigin(self) -> float: ... + def get_rsign(self) -> float: ... + def set_rlim( + self, + bottom: float | tuple[float, float] | None = ..., + top: float | None = ..., + *, + emit: bool = ..., + auto: bool = ..., + **kwargs, + ) -> tuple[float, float]: ... + def get_rlabel_position(self) -> float: ... + def set_rlabel_position(self, value: float) -> None: ... + def set_rscale(self, *args, **kwargs) -> None: ... + def set_rticks(self, *args, **kwargs) -> None: ... + def set_thetagrids( + self, + angles: ArrayLike, + labels: Sequence[str | Text] | None = ..., + fmt: str | None = ..., + **kwargs, + ) -> tuple[list[Line2D], list[Text]]: ... + def set_rgrids( + self, + radii: ArrayLike, + labels: Sequence[str | Text] | None = ..., + angle: float | None = ..., + fmt: str | None = ..., + **kwargs, + ) -> tuple[list[Line2D], list[Text]]: ... + def format_coord(self, theta: float, r: float) -> str: ... + def get_data_ratio(self) -> float: ... + def can_zoom(self) -> bool: ... + def can_pan(self) -> bool: ... + def start_pan(self, x: float, y: float, button: int) -> None: ... + def end_pan(self) -> None: ... + def drag_pan(self, button: Any, key: Any, x: float, y: float) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/py.typed b/dbdpy-env/lib/python3.9/site-packages/matplotlib/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/pylab.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/pylab.py new file mode 100644 index 00000000..77eb6506 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/pylab.py @@ -0,0 +1,65 @@ +""" +`pylab` is a historic interface and its use is strongly discouraged. The equivalent +replacement is `matplotlib.pyplot`. See :ref:`api_interfaces` for a full overview +of Matplotlib interfaces. + +`pylab` was designed to support a MATLAB-like way of working with all plotting related +functions directly available in the global namespace. This was achieved through a +wildcard import (``from pylab import *``). + +.. warning:: + The use of `pylab` is discouraged for the following reasons: + + ``from pylab import *`` imports all the functions from `matplotlib.pyplot`, `numpy`, + `numpy.fft`, `numpy.linalg`, and `numpy.random`, and some additional functions into + the global namespace. + + Such a pattern is considered bad practice in modern python, as it clutters the global + namespace. Even more severely, in the case of `pylab`, this will overwrite some + builtin functions (e.g. the builtin `sum` will be replaced by `numpy.sum`), which + can lead to unexpected behavior. + +""" + +from matplotlib.cbook import flatten, silent_list + +import matplotlib as mpl + +from matplotlib.dates import ( + date2num, num2date, datestr2num, drange, DateFormatter, DateLocator, + RRuleLocator, YearLocator, MonthLocator, WeekdayLocator, DayLocator, + HourLocator, MinuteLocator, SecondLocator, rrule, MO, TU, WE, TH, FR, + SA, SU, YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY, + relativedelta) + +# bring all the symbols in so folks can import them from +# pylab in one fell swoop + +## We are still importing too many things from mlab; more cleanup is needed. + +from matplotlib.mlab import ( + detrend, detrend_linear, detrend_mean, detrend_none, window_hanning, + window_none) + +from matplotlib import cbook, mlab, pyplot as plt +from matplotlib.pyplot import * + +from numpy import * +from numpy.fft import * +from numpy.random import * +from numpy.linalg import * + +import numpy as np +import numpy.ma as ma + +# don't let numpy's datetime hide stdlib +import datetime + +# This is needed, or bytes will be numpy.random.bytes from +# "from numpy.random import *" above +bytes = __import__("builtins").bytes +# We also don't want the numpy version of these functions +abs = __import__("builtins").abs +max = __import__("builtins").max +min = __import__("builtins").min +round = __import__("builtins").round diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/pyplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/pyplot.py new file mode 100644 index 00000000..62f7eba7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/pyplot.py @@ -0,0 +1,4373 @@ +# Note: The first part of this file can be modified in place, but the latter +# part is autogenerated by the boilerplate.py script. + +""" +`matplotlib.pyplot` is a state-based interface to matplotlib. It provides +an implicit, MATLAB-like, way of plotting. It also opens figures on your +screen, and acts as the figure GUI manager. + +pyplot is mainly intended for interactive plots and simple cases of +programmatic plot generation:: + + import numpy as np + import matplotlib.pyplot as plt + + x = np.arange(0, 5, 0.1) + y = np.sin(x) + plt.plot(x, y) + +The explicit object-oriented API is recommended for complex plots, though +pyplot is still usually used to create the figure and often the axes in the +figure. See `.pyplot.figure`, `.pyplot.subplots`, and +`.pyplot.subplot_mosaic` to create figures, and +:doc:`Axes API </api/axes_api>` for the plotting methods on an Axes:: + + import numpy as np + import matplotlib.pyplot as plt + + x = np.arange(0, 5, 0.1) + y = np.sin(x) + fig, ax = plt.subplots() + ax.plot(x, y) + + +See :ref:`api_interfaces` for an explanation of the tradeoffs between the +implicit and explicit interfaces. +""" + +# fmt: off + +from __future__ import annotations + +from contextlib import AbstractContextManager, ExitStack +from enum import Enum +import functools +import importlib +import inspect +import logging +import re +import sys +import threading +import time +from typing import cast, overload + +from cycler import cycler +import matplotlib +import matplotlib.colorbar +import matplotlib.image +from matplotlib import _api +from matplotlib import ( # Re-exported for typing. + cm as cm, get_backend as get_backend, rcParams as rcParams, style as style) +from matplotlib import _pylab_helpers, interactive +from matplotlib import cbook +from matplotlib import _docstring +from matplotlib.backend_bases import ( + FigureCanvasBase, FigureManagerBase, MouseButton) +from matplotlib.figure import Figure, FigureBase, figaspect +from matplotlib.gridspec import GridSpec, SubplotSpec +from matplotlib import rcsetup, rcParamsDefault, rcParamsOrig +from matplotlib.artist import Artist +from matplotlib.axes import Axes, Subplot # type: ignore +from matplotlib.projections import PolarAxes # type: ignore +from matplotlib import mlab # for detrend_none, window_hanning +from matplotlib.scale import get_scale_names + +from matplotlib.cm import _colormaps +from matplotlib.cm import register_cmap # type: ignore +from matplotlib.colors import _color_sequences + +import numpy as np + +from typing import TYPE_CHECKING, cast + +if TYPE_CHECKING: + from collections.abc import Callable, Hashable, Iterable, Sequence + import datetime + import pathlib + import os + from typing import Any, BinaryIO, Literal, TypeVar + from typing_extensions import ParamSpec + + import PIL.Image + from numpy.typing import ArrayLike + + from matplotlib.axis import Tick + from matplotlib.axes._base import _AxesBase + from matplotlib.backend_bases import RendererBase, Event + from matplotlib.cm import ScalarMappable + from matplotlib.contour import ContourSet, QuadContourSet + from matplotlib.collections import ( + Collection, + LineCollection, + BrokenBarHCollection, + PolyCollection, + PathCollection, + EventCollection, + QuadMesh, + ) + from matplotlib.colorbar import Colorbar + from matplotlib.colors import Colormap + from matplotlib.container import ( + BarContainer, + ErrorbarContainer, + StemContainer, + ) + from matplotlib.figure import SubFigure + from matplotlib.legend import Legend + from matplotlib.mlab import GaussianKDE + from matplotlib.image import AxesImage, FigureImage + from matplotlib.patches import FancyArrow, StepPatch, Wedge + from matplotlib.quiver import Barbs, Quiver, QuiverKey + from matplotlib.scale import ScaleBase + from matplotlib.transforms import Transform, Bbox + from matplotlib.typing import ColorType, LineStyleType, MarkerType, HashableList + from matplotlib.widgets import SubplotTool + + _P = ParamSpec('_P') + _R = TypeVar('_R') + _T = TypeVar('_T') + + +# We may not need the following imports here: +from matplotlib.colors import Normalize +from matplotlib.lines import Line2D +from matplotlib.text import Text, Annotation +from matplotlib.patches import Polygon, Rectangle, Circle, Arrow +from matplotlib.widgets import Button, Slider, Widget + +from .ticker import ( + TickHelper, Formatter, FixedFormatter, NullFormatter, FuncFormatter, + FormatStrFormatter, ScalarFormatter, LogFormatter, LogFormatterExponent, + LogFormatterMathtext, Locator, IndexLocator, FixedLocator, NullLocator, + LinearLocator, LogLocator, AutoLocator, MultipleLocator, MaxNLocator) + +_log = logging.getLogger(__name__) + + +# Explicit rename instead of import-as for typing's sake. +colormaps = _colormaps +color_sequences = _color_sequences + + +@overload +def _copy_docstring_and_deprecators( + method: Any, + func: Literal[None] = None +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... + + +@overload +def _copy_docstring_and_deprecators( + method: Any, func: Callable[_P, _R]) -> Callable[_P, _R]: ... + + +def _copy_docstring_and_deprecators( + method: Any, + func: Callable[_P, _R] | None = None +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]] | Callable[_P, _R]: + if func is None: + return cast('Callable[[Callable[_P, _R]], Callable[_P, _R]]', + functools.partial(_copy_docstring_and_deprecators, method)) + decorators: list[Callable[[Callable[_P, _R]], Callable[_P, _R]]] = [ + _docstring.copy(method) + ] + # Check whether the definition of *method* includes @_api.rename_parameter + # or @_api.make_keyword_only decorators; if so, propagate them to the + # pyplot wrapper as well. + while hasattr(method, "__wrapped__"): + potential_decorator = _api.deprecation.DECORATORS.get(method) + if potential_decorator: + decorators.append(potential_decorator) + method = method.__wrapped__ + for decorator in decorators[::-1]: + func = decorator(func) + return func + + +## Global ## + + +# The state controlled by {,un}install_repl_displayhook(). +_ReplDisplayHook = Enum("_ReplDisplayHook", ["NONE", "PLAIN", "IPYTHON"]) +_REPL_DISPLAYHOOK = _ReplDisplayHook.NONE + + +def _draw_all_if_interactive() -> None: + if matplotlib.is_interactive(): + draw_all() + + +def install_repl_displayhook() -> None: + """ + Connect to the display hook of the current shell. + + The display hook gets called when the read-evaluate-print-loop (REPL) of + the shell has finished the execution of a command. We use this callback + to be able to automatically update a figure in interactive mode. + + This works both with IPython and with vanilla python shells. + """ + global _REPL_DISPLAYHOOK + + if _REPL_DISPLAYHOOK is _ReplDisplayHook.IPYTHON: + return + + # See if we have IPython hooks around, if so use them. + # Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as + # entries can also have been explicitly set to None. + mod_ipython = sys.modules.get("IPython") + if not mod_ipython: + _REPL_DISPLAYHOOK = _ReplDisplayHook.PLAIN + return + ip = mod_ipython.get_ipython() + if not ip: + _REPL_DISPLAYHOOK = _ReplDisplayHook.PLAIN + return + + ip.events.register("post_execute", _draw_all_if_interactive) + _REPL_DISPLAYHOOK = _ReplDisplayHook.IPYTHON + + from IPython.core.pylabtools import backend2gui # type: ignore + # trigger IPython's eventloop integration, if available + ipython_gui_name = backend2gui.get(get_backend()) + if ipython_gui_name: + ip.enable_gui(ipython_gui_name) + + +def uninstall_repl_displayhook() -> None: + """Disconnect from the display hook of the current shell.""" + global _REPL_DISPLAYHOOK + if _REPL_DISPLAYHOOK is _ReplDisplayHook.IPYTHON: + from IPython import get_ipython # type: ignore + ip = get_ipython() + ip.events.unregister("post_execute", _draw_all_if_interactive) + _REPL_DISPLAYHOOK = _ReplDisplayHook.NONE + + +draw_all = _pylab_helpers.Gcf.draw_all + + +# Ensure this appears in the pyplot docs. +@_copy_docstring_and_deprecators(matplotlib.set_loglevel) +def set_loglevel(*args, **kwargs) -> None: + return matplotlib.set_loglevel(*args, **kwargs) + + +@_copy_docstring_and_deprecators(Artist.findobj) +def findobj( + o: Artist | None = None, + match: Callable[[Artist], bool] | type[Artist] | None = None, + include_self: bool = True +) -> list[Artist]: + if o is None: + o = gcf() + return o.findobj(match, include_self=include_self) + + +_backend_mod: type[matplotlib.backend_bases._Backend] | None = None + + +def _get_backend_mod() -> type[matplotlib.backend_bases._Backend]: + """ + Ensure that a backend is selected and return it. + + This is currently private, but may be made public in the future. + """ + if _backend_mod is None: + # Use rcParams._get("backend") to avoid going through the fallback + # logic (which will (re)import pyplot and then call switch_backend if + # we need to resolve the auto sentinel) + switch_backend(rcParams._get("backend")) # type: ignore[attr-defined] + return cast(type[matplotlib.backend_bases._Backend], _backend_mod) + + +def switch_backend(newbackend: str) -> None: + """ + Set the pyplot backend. + + Switching to an interactive backend is possible only if no event loop for + another interactive backend has started. Switching to and from + non-interactive backends is always possible. + + If the new backend is different than the current backend then all open + Figures will be closed via ``plt.close('all')``. + + Parameters + ---------- + newbackend : str + The case-insensitive name of the backend to use. + + """ + global _backend_mod + # make sure the init is pulled up so we can assign to it later + import matplotlib.backends + + if newbackend is rcsetup._auto_backend_sentinel: + current_framework = cbook._get_running_interactive_framework() + mapping = {'qt': 'qtagg', + 'gtk3': 'gtk3agg', + 'gtk4': 'gtk4agg', + 'wx': 'wxagg', + 'tk': 'tkagg', + 'macosx': 'macosx', + 'headless': 'agg'} + + if current_framework in mapping: + candidates = [mapping[current_framework]] + else: + candidates = [] + candidates += [ + "macosx", "qtagg", "gtk4agg", "gtk3agg", "tkagg", "wxagg"] + + # Don't try to fallback on the cairo-based backends as they each have + # an additional dependency (pycairo) over the agg-based backend, and + # are of worse quality. + for candidate in candidates: + try: + switch_backend(candidate) + except ImportError: + continue + else: + rcParamsOrig['backend'] = candidate + return + else: + # Switching to Agg should always succeed; if it doesn't, let the + # exception propagate out. + switch_backend("agg") + rcParamsOrig["backend"] = "agg" + return + # have to escape the switch on access logic + old_backend = dict.__getitem__(rcParams, 'backend') + + module = importlib.import_module(cbook._backend_module_name(newbackend)) + canvas_class = module.FigureCanvas + + required_framework = canvas_class.required_interactive_framework + if required_framework is not None: + current_framework = cbook._get_running_interactive_framework() + if (current_framework and required_framework + and current_framework != required_framework): + raise ImportError( + "Cannot load backend {!r} which requires the {!r} interactive " + "framework, as {!r} is currently running".format( + newbackend, required_framework, current_framework)) + + # Load the new_figure_manager() and show() functions from the backend. + + # Classically, backends can directly export these functions. This should + # keep working for backcompat. + new_figure_manager = getattr(module, "new_figure_manager", None) + show = getattr(module, "show", None) + + # In that classical approach, backends are implemented as modules, but + # "inherit" default method implementations from backend_bases._Backend. + # This is achieved by creating a "class" that inherits from + # backend_bases._Backend and whose body is filled with the module globals. + class backend_mod(matplotlib.backend_bases._Backend): + locals().update(vars(module)) + + # However, the newer approach for defining new_figure_manager and + # show is to derive them from canvas methods. In that case, also + # update backend_mod accordingly; also, per-backend customization of + # draw_if_interactive is disabled. + if new_figure_manager is None: + + def new_figure_manager_given_figure(num, figure): + return canvas_class.new_manager(figure, num) + + def new_figure_manager(num, *args, FigureClass=Figure, **kwargs): + fig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, fig) + + def draw_if_interactive() -> None: + if matplotlib.is_interactive(): + manager = _pylab_helpers.Gcf.get_active() + if manager: + manager.canvas.draw_idle() + + backend_mod.new_figure_manager_given_figure = ( # type: ignore[method-assign] + new_figure_manager_given_figure) + backend_mod.new_figure_manager = ( # type: ignore[method-assign] + new_figure_manager) + backend_mod.draw_if_interactive = ( # type: ignore[method-assign] + draw_if_interactive) + + # If the manager explicitly overrides pyplot_show, use it even if a global + # show is already present, as the latter may be here for backcompat. + manager_class = getattr(canvas_class, "manager_class", None) + # We can't compare directly manager_class.pyplot_show and FMB.pyplot_show because + # pyplot_show is a classmethod so the above constructs are bound classmethods, and + # thus always different (being bound to different classes). We also have to use + # getattr_static instead of vars as manager_class could have no __dict__. + manager_pyplot_show = inspect.getattr_static(manager_class, "pyplot_show", None) + base_pyplot_show = inspect.getattr_static(FigureManagerBase, "pyplot_show", None) + if (show is None + or (manager_pyplot_show is not None + and manager_pyplot_show != base_pyplot_show)): + if not manager_pyplot_show: + raise ValueError( + f"Backend {newbackend} defines neither FigureCanvas.manager_class nor " + f"a toplevel show function") + _pyplot_show = cast('Any', manager_class).pyplot_show + backend_mod.show = _pyplot_show # type: ignore[method-assign] + + _log.debug("Loaded backend %s version %s.", + newbackend, backend_mod.backend_version) + + rcParams['backend'] = rcParamsDefault['backend'] = newbackend + _backend_mod = backend_mod + for func_name in ["new_figure_manager", "draw_if_interactive", "show"]: + globals()[func_name].__signature__ = inspect.signature( + getattr(backend_mod, func_name)) + + # Need to keep a global reference to the backend for compatibility reasons. + # See https://github.com/matplotlib/matplotlib/issues/6092 + matplotlib.backends.backend = newbackend # type: ignore[attr-defined] + + if not cbook._str_equal(old_backend, newbackend): + if get_fignums(): + _api.warn_deprecated("3.8", message=( + "Auto-close()ing of figures upon backend switching is deprecated since " + "%(since)s and will be removed %(removal)s. To suppress this warning, " + "explicitly call plt.close('all') first.")) + close("all") + + # Make sure the repl display hook is installed in case we become interactive. + install_repl_displayhook() + + +def _warn_if_gui_out_of_main_thread() -> None: + warn = False + canvas_class = cast(type[FigureCanvasBase], _get_backend_mod().FigureCanvas) + if canvas_class.required_interactive_framework: + if hasattr(threading, 'get_native_id'): + # This compares native thread ids because even if Python-level + # Thread objects match, the underlying OS thread (which is what + # really matters) may be different on Python implementations with + # green threads. + if threading.get_native_id() != threading.main_thread().native_id: + warn = True + else: + # Fall back to Python-level Thread if native IDs are unavailable, + # mainly for PyPy. + if threading.current_thread() is not threading.main_thread(): + warn = True + if warn: + _api.warn_external( + "Starting a Matplotlib GUI outside of the main thread will likely " + "fail.") + + +# This function's signature is rewritten upon backend-load by switch_backend. +def new_figure_manager(*args, **kwargs): + """Create a new figure manager instance.""" + _warn_if_gui_out_of_main_thread() + return _get_backend_mod().new_figure_manager(*args, **kwargs) + + +# This function's signature is rewritten upon backend-load by switch_backend. +def draw_if_interactive(*args, **kwargs): + """ + Redraw the current figure if in interactive mode. + + .. warning:: + + End users will typically not have to call this function because the + the interactive mode takes care of this. + """ + return _get_backend_mod().draw_if_interactive(*args, **kwargs) + + +# This function's signature is rewritten upon backend-load by switch_backend. +def show(*args, **kwargs) -> None: + """ + Display all open figures. + + Parameters + ---------- + block : bool, optional + Whether to wait for all figures to be closed before returning. + + If `True` block and run the GUI main loop until all figure windows + are closed. + + If `False` ensure that all figure windows are displayed and return + immediately. In this case, you are responsible for ensuring + that the event loop is running to have responsive figures. + + Defaults to True in non-interactive mode and to False in interactive + mode (see `.pyplot.isinteractive`). + + See Also + -------- + ion : Enable interactive mode, which shows / updates the figure after + every plotting command, so that calling ``show()`` is not necessary. + ioff : Disable interactive mode. + savefig : Save the figure to an image file instead of showing it on screen. + + Notes + ----- + **Saving figures to file and showing a window at the same time** + + If you want an image file as well as a user interface window, use + `.pyplot.savefig` before `.pyplot.show`. At the end of (a blocking) + ``show()`` the figure is closed and thus unregistered from pyplot. Calling + `.pyplot.savefig` afterwards would save a new and thus empty figure. This + limitation of command order does not apply if the show is non-blocking or + if you keep a reference to the figure and use `.Figure.savefig`. + + **Auto-show in jupyter notebooks** + + The jupyter backends (activated via ``%matplotlib inline``, + ``%matplotlib notebook``, or ``%matplotlib widget``), call ``show()`` at + the end of every cell by default. Thus, you usually don't have to call it + explicitly there. + """ + _warn_if_gui_out_of_main_thread() + return _get_backend_mod().show(*args, **kwargs) + + +def isinteractive() -> bool: + """ + Return whether plots are updated after every plotting command. + + The interactive mode is mainly useful if you build plots from the command + line and want to see the effect of each command while you are building the + figure. + + In interactive mode: + + - newly created figures will be shown immediately; + - figures will automatically redraw on change; + - `.pyplot.show` will not block by default. + + In non-interactive mode: + + - newly created figures and changes to figures will not be reflected until + explicitly asked to be; + - `.pyplot.show` will block by default. + + See Also + -------- + ion : Enable interactive mode. + ioff : Disable interactive mode. + show : Show all figures (and maybe block). + pause : Show all figures, and block for a time. + """ + return matplotlib.is_interactive() + + +def ioff() -> ExitStack: + """ + Disable interactive mode. + + See `.pyplot.isinteractive` for more details. + + See Also + -------- + ion : Enable interactive mode. + isinteractive : Whether interactive mode is enabled. + show : Show all figures (and maybe block). + pause : Show all figures, and block for a time. + + Notes + ----- + For a temporary change, this can be used as a context manager:: + + # if interactive mode is on + # then figures will be shown on creation + plt.ion() + # This figure will be shown immediately + fig = plt.figure() + + with plt.ioff(): + # interactive mode will be off + # figures will not automatically be shown + fig2 = plt.figure() + # ... + + To enable optional usage as a context manager, this function returns a + `~contextlib.ExitStack` object, which is not intended to be stored or + accessed by the user. + """ + stack = ExitStack() + stack.callback(ion if isinteractive() else ioff) + matplotlib.interactive(False) + uninstall_repl_displayhook() + return stack + + +def ion() -> ExitStack: + """ + Enable interactive mode. + + See `.pyplot.isinteractive` for more details. + + See Also + -------- + ioff : Disable interactive mode. + isinteractive : Whether interactive mode is enabled. + show : Show all figures (and maybe block). + pause : Show all figures, and block for a time. + + Notes + ----- + For a temporary change, this can be used as a context manager:: + + # if interactive mode is off + # then figures will not be shown on creation + plt.ioff() + # This figure will not be shown immediately + fig = plt.figure() + + with plt.ion(): + # interactive mode will be on + # figures will automatically be shown + fig2 = plt.figure() + # ... + + To enable optional usage as a context manager, this function returns a + `~contextlib.ExitStack` object, which is not intended to be stored or + accessed by the user. + """ + stack = ExitStack() + stack.callback(ion if isinteractive() else ioff) + matplotlib.interactive(True) + install_repl_displayhook() + return stack + + +def pause(interval: float) -> None: + """ + Run the GUI event loop for *interval* seconds. + + If there is an active figure, it will be updated and displayed before the + pause, and the GUI event loop (if any) will run during the pause. + + This can be used for crude animation. For more complex animation use + :mod:`matplotlib.animation`. + + If there is no active figure, sleep for *interval* seconds instead. + + See Also + -------- + matplotlib.animation : Proper animations + show : Show all figures and optional block until all figures are closed. + """ + manager = _pylab_helpers.Gcf.get_active() + if manager is not None: + canvas = manager.canvas + if canvas.figure.stale: + canvas.draw_idle() + show(block=False) + canvas.start_event_loop(interval) + else: + time.sleep(interval) + + +@_copy_docstring_and_deprecators(matplotlib.rc) +def rc(group: str, **kwargs) -> None: + matplotlib.rc(group, **kwargs) + + +@_copy_docstring_and_deprecators(matplotlib.rc_context) +def rc_context( + rc: dict[str, Any] | None = None, + fname: str | pathlib.Path | os.PathLike | None = None, +) -> AbstractContextManager[None]: + return matplotlib.rc_context(rc, fname) + + +@_copy_docstring_and_deprecators(matplotlib.rcdefaults) +def rcdefaults() -> None: + matplotlib.rcdefaults() + if matplotlib.is_interactive(): + draw_all() + + +# getp/get/setp are explicitly reexported so that they show up in pyplot docs. + + +@_copy_docstring_and_deprecators(matplotlib.artist.getp) +def getp(obj, *args, **kwargs): + return matplotlib.artist.getp(obj, *args, **kwargs) + + +@_copy_docstring_and_deprecators(matplotlib.artist.get) +def get(obj, *args, **kwargs): + return matplotlib.artist.get(obj, *args, **kwargs) + + +@_copy_docstring_and_deprecators(matplotlib.artist.setp) +def setp(obj, *args, **kwargs): + return matplotlib.artist.setp(obj, *args, **kwargs) + + +def xkcd( + scale: float = 1, length: float = 100, randomness: float = 2 +) -> ExitStack: + """ + Turn on `xkcd <https://xkcd.com/>`_ sketch-style drawing mode. + + This will only have an effect on things drawn after this function is called. + + For best results, install the `xkcd script <https://github.com/ipython/xkcd-font/>`_ + font; xkcd fonts are not packaged with Matplotlib. + + Parameters + ---------- + scale : float, optional + The amplitude of the wiggle perpendicular to the source line. + length : float, optional + The length of the wiggle along the line. + randomness : float, optional + The scale factor by which the length is shrunken or expanded. + + Notes + ----- + This function works by a number of rcParams, so it will probably + override others you have set before. + + If you want the effects of this function to be temporary, it can + be used as a context manager, for example:: + + with plt.xkcd(): + # This figure will be in XKCD-style + fig1 = plt.figure() + # ... + + # This figure will be in regular style + fig2 = plt.figure() + """ + # This cannot be implemented in terms of contextmanager() or rc_context() + # because this needs to work as a non-contextmanager too. + + if rcParams['text.usetex']: + raise RuntimeError( + "xkcd mode is not compatible with text.usetex = True") + + stack = ExitStack() + stack.callback(dict.update, rcParams, rcParams.copy()) # type: ignore + + from matplotlib import patheffects + rcParams.update({ + 'font.family': ['xkcd', 'xkcd Script', 'Comic Neue', 'Comic Sans MS'], + 'font.size': 14.0, + 'path.sketch': (scale, length, randomness), + 'path.effects': [ + patheffects.withStroke(linewidth=4, foreground="w")], + 'axes.linewidth': 1.5, + 'lines.linewidth': 2.0, + 'figure.facecolor': 'white', + 'grid.linewidth': 0.0, + 'axes.grid': False, + 'axes.unicode_minus': False, + 'axes.edgecolor': 'black', + 'xtick.major.size': 8, + 'xtick.major.width': 3, + 'ytick.major.size': 8, + 'ytick.major.width': 3, + }) + + return stack + + +## Figures ## + +def figure( + # autoincrement if None, else integer from 1-N + num: int | str | Figure | SubFigure | None = None, + # defaults to rc figure.figsize + figsize: tuple[float, float] | None = None, + # defaults to rc figure.dpi + dpi: float | None = None, + *, + # defaults to rc figure.facecolor + facecolor: ColorType | None = None, + # defaults to rc figure.edgecolor + edgecolor: ColorType | None = None, + frameon: bool = True, + FigureClass: type[Figure] = Figure, + clear: bool = False, + **kwargs +) -> Figure: + """ + Create a new figure, or activate an existing figure. + + Parameters + ---------- + num : int or str or `.Figure` or `.SubFigure`, optional + A unique identifier for the figure. + + If a figure with that identifier already exists, this figure is made + active and returned. An integer refers to the ``Figure.number`` + attribute, a string refers to the figure label. + + If there is no figure with the identifier or *num* is not given, a new + figure is created, made active and returned. If *num* is an int, it + will be used for the ``Figure.number`` attribute, otherwise, an + auto-generated integer value is used (starting at 1 and incremented + for each new figure). If *num* is a string, the figure label and the + window title is set to this value. If num is a ``SubFigure``, its + parent ``Figure`` is activated. + + figsize : (float, float), default: :rc:`figure.figsize` + Width, height in inches. + + dpi : float, default: :rc:`figure.dpi` + The resolution of the figure in dots-per-inch. + + facecolor : color, default: :rc:`figure.facecolor` + The background color. + + edgecolor : color, default: :rc:`figure.edgecolor` + The border color. + + frameon : bool, default: True + If False, suppress drawing the figure frame. + + FigureClass : subclass of `~matplotlib.figure.Figure` + If set, an instance of this subclass will be created, rather than a + plain `.Figure`. + + clear : bool, default: False + If True and the figure already exists, then it is cleared. + + layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, None}, \ +default: None + The layout mechanism for positioning of plot elements to avoid + overlapping Axes decorations (labels, ticks, etc). Note that layout + managers can measurably slow down figure display. + + - 'constrained': The constrained layout solver adjusts axes sizes + to avoid overlapping axes decorations. Can handle complex plot + layouts and colorbars, and is thus recommended. + + See :ref:`constrainedlayout_guide` + for examples. + + - 'compressed': uses the same algorithm as 'constrained', but + removes extra space between fixed-aspect-ratio Axes. Best for + simple grids of axes. + + - 'tight': Use the tight layout mechanism. This is a relatively + simple algorithm that adjusts the subplot parameters so that + decorations do not overlap. See `.Figure.set_tight_layout` for + further details. + + - 'none': Do not use a layout engine. + + - A `.LayoutEngine` instance. Builtin layout classes are + `.ConstrainedLayoutEngine` and `.TightLayoutEngine`, more easily + accessible by 'constrained' and 'tight'. Passing an instance + allows third parties to provide their own layout engine. + + If not given, fall back to using the parameters *tight_layout* and + *constrained_layout*, including their config defaults + :rc:`figure.autolayout` and :rc:`figure.constrained_layout.use`. + + **kwargs + Additional keyword arguments are passed to the `.Figure` constructor. + + Returns + ------- + `~matplotlib.figure.Figure` + + Notes + ----- + A newly created figure is passed to the `~.FigureCanvasBase.new_manager` + method or the `new_figure_manager` function provided by the current + backend, which install a canvas and a manager on the figure. + + Once this is done, :rc:`figure.hooks` are called, one at a time, on the + figure; these hooks allow arbitrary customization of the figure (e.g., + attaching callbacks) or of associated elements (e.g., modifying the + toolbar). See :doc:`/gallery/user_interfaces/mplcvd` for an example of + toolbar customization. + + If you are creating many figures, make sure you explicitly call + `.pyplot.close` on the figures you are not using, because this will + enable pyplot to properly clean up the memory. + + `~matplotlib.rcParams` defines the default values, which can be modified + in the matplotlibrc file. + """ + if isinstance(num, FigureBase): + # type narrowed to `Figure | SubFigure` by combination of input and isinstance + if num.canvas.manager is None: + raise ValueError("The passed figure is not managed by pyplot") + _pylab_helpers.Gcf.set_active(num.canvas.manager) + return num.figure + + allnums = get_fignums() + next_num = max(allnums) + 1 if allnums else 1 + fig_label = '' + if num is None: + num = next_num + elif isinstance(num, str): + fig_label = num + all_labels = get_figlabels() + if fig_label not in all_labels: + if fig_label == 'all': + _api.warn_external("close('all') closes all existing figures.") + num = next_num + else: + inum = all_labels.index(fig_label) + num = allnums[inum] + else: + num = int(num) # crude validation of num argument + + # Type of "num" has narrowed to int, but mypy can't quite see it + manager = _pylab_helpers.Gcf.get_fig_manager(num) # type: ignore[arg-type] + if manager is None: + max_open_warning = rcParams['figure.max_open_warning'] + if len(allnums) == max_open_warning >= 1: + _api.warn_external( + f"More than {max_open_warning} figures have been opened. " + f"Figures created through the pyplot interface " + f"(`matplotlib.pyplot.figure`) are retained until explicitly " + f"closed and may consume too much memory. (To control this " + f"warning, see the rcParam `figure.max_open_warning`). " + f"Consider using `matplotlib.pyplot.close()`.", + RuntimeWarning) + + manager = new_figure_manager( + num, figsize=figsize, dpi=dpi, + facecolor=facecolor, edgecolor=edgecolor, frameon=frameon, + FigureClass=FigureClass, **kwargs) + fig = manager.canvas.figure + if fig_label: + fig.set_label(fig_label) + + for hookspecs in rcParams["figure.hooks"]: + module_name, dotted_name = hookspecs.split(":") + obj: Any = importlib.import_module(module_name) + for part in dotted_name.split("."): + obj = getattr(obj, part) + obj(fig) + + _pylab_helpers.Gcf._set_new_active_manager(manager) + + # make sure backends (inline) that we don't ship that expect this + # to be called in plotting commands to make the figure call show + # still work. There is probably a better way to do this in the + # FigureManager base class. + draw_if_interactive() + + if _REPL_DISPLAYHOOK is _ReplDisplayHook.PLAIN: + fig.stale_callback = _auto_draw_if_interactive + + if clear: + manager.canvas.figure.clear() + + return manager.canvas.figure + + +def _auto_draw_if_interactive(fig, val): + """ + An internal helper function for making sure that auto-redrawing + works as intended in the plain python repl. + + Parameters + ---------- + fig : Figure + A figure object which is assumed to be associated with a canvas + """ + if (val and matplotlib.is_interactive() + and not fig.canvas.is_saving() + and not fig.canvas._is_idle_drawing): + # Some artists can mark themselves as stale in the middle of drawing + # (e.g. axes position & tick labels being computed at draw time), but + # this shouldn't trigger a redraw because the current redraw will + # already take them into account. + with fig.canvas._idle_draw_cntx(): + fig.canvas.draw_idle() + + +def gcf() -> Figure: + """ + Get the current figure. + + If there is currently no figure on the pyplot figure stack, a new one is + created using `~.pyplot.figure()`. (To test whether there is currently a + figure on the pyplot figure stack, check whether `~.pyplot.get_fignums()` + is empty.) + """ + manager = _pylab_helpers.Gcf.get_active() + if manager is not None: + return manager.canvas.figure + else: + return figure() + + +def fignum_exists(num: int) -> bool: + """Return whether the figure with the given id exists.""" + return _pylab_helpers.Gcf.has_fignum(num) or num in get_figlabels() + + +def get_fignums() -> list[int]: + """Return a list of existing figure numbers.""" + return sorted(_pylab_helpers.Gcf.figs) + + +def get_figlabels() -> list[Any]: + """Return a list of existing figure labels.""" + managers = _pylab_helpers.Gcf.get_all_fig_managers() + managers.sort(key=lambda m: m.num) + return [m.canvas.figure.get_label() for m in managers] + + +def get_current_fig_manager() -> FigureManagerBase | None: + """ + Return the figure manager of the current figure. + + The figure manager is a container for the actual backend-depended window + that displays the figure on screen. + + If no current figure exists, a new one is created, and its figure + manager is returned. + + Returns + ------- + `.FigureManagerBase` or backend-dependent subclass thereof + """ + return gcf().canvas.manager + + +@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_connect) +def connect(s: str, func: Callable[[Event], Any]) -> int: + return gcf().canvas.mpl_connect(s, func) + + +@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_disconnect) +def disconnect(cid: int) -> None: + gcf().canvas.mpl_disconnect(cid) + + +def close(fig: None | int | str | Figure | Literal["all"] = None) -> None: + """ + Close a figure window. + + Parameters + ---------- + fig : None or int or str or `.Figure` + The figure to close. There are a number of ways to specify this: + + - *None*: the current figure + - `.Figure`: the given `.Figure` instance + - ``int``: a figure number + - ``str``: a figure name + - 'all': all figures + + """ + if fig is None: + manager = _pylab_helpers.Gcf.get_active() + if manager is None: + return + else: + _pylab_helpers.Gcf.destroy(manager) + elif fig == 'all': + _pylab_helpers.Gcf.destroy_all() + elif isinstance(fig, int): + _pylab_helpers.Gcf.destroy(fig) + elif hasattr(fig, 'int'): + # if we are dealing with a type UUID, we + # can use its integer representation + _pylab_helpers.Gcf.destroy(fig.int) + elif isinstance(fig, str): + all_labels = get_figlabels() + if fig in all_labels: + num = get_fignums()[all_labels.index(fig)] + _pylab_helpers.Gcf.destroy(num) + elif isinstance(fig, Figure): + _pylab_helpers.Gcf.destroy_fig(fig) + else: + raise TypeError("close() argument must be a Figure, an int, a string, " + "or None, not %s" % type(fig)) + + +def clf() -> None: + """Clear the current figure.""" + gcf().clear() + + +def draw() -> None: + """ + Redraw the current figure. + + This is used to update a figure that has been altered, but not + automatically re-drawn. If interactive mode is on (via `.ion()`), this + should be only rarely needed, but there may be ways to modify the state of + a figure without marking it as "stale". Please report these cases as bugs. + + This is equivalent to calling ``fig.canvas.draw_idle()``, where ``fig`` is + the current figure. + + See Also + -------- + .FigureCanvasBase.draw_idle + .FigureCanvasBase.draw + """ + gcf().canvas.draw_idle() + + +@_copy_docstring_and_deprecators(Figure.savefig) +def savefig(*args, **kwargs) -> None: + fig = gcf() + # savefig default implementation has no return, so mypy is unhappy + # presumably this is here because subclasses can return? + res = fig.savefig(*args, **kwargs) # type: ignore[func-returns-value] + fig.canvas.draw_idle() # Need this if 'transparent=True', to reset colors. + return res + + +## Putting things in figures ## + + +def figlegend(*args, **kwargs) -> Legend: + return gcf().legend(*args, **kwargs) +if Figure.legend.__doc__: + figlegend.__doc__ = Figure.legend.__doc__ \ + .replace(" legend(", " figlegend(") \ + .replace("fig.legend(", "plt.figlegend(") \ + .replace("ax.plot(", "plt.plot(") + + +## Axes ## + +@_docstring.dedent_interpd +def axes( + arg: None | tuple[float, float, float, float] = None, + **kwargs +) -> matplotlib.axes.Axes: + """ + Add an Axes to the current figure and make it the current Axes. + + Call signatures:: + + plt.axes() + plt.axes(rect, projection=None, polar=False, **kwargs) + plt.axes(ax) + + Parameters + ---------- + arg : None or 4-tuple + The exact behavior of this function depends on the type: + + - *None*: A new full window Axes is added using + ``subplot(**kwargs)``. + - 4-tuple of floats *rect* = ``(left, bottom, width, height)``. + A new Axes is added with dimensions *rect* in normalized + (0, 1) units using `~.Figure.add_axes` on the current figure. + + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', 'rectilinear', str}, optional + The projection type of the `~.axes.Axes`. *str* is the name of + a custom projection, see `~matplotlib.projections`. The default + None results in a 'rectilinear' projection. + + polar : bool, default: False + If True, equivalent to projection='polar'. + + sharex, sharey : `~matplotlib.axes.Axes`, optional + Share the x or y `~matplotlib.axis` with sharex and/or sharey. + The axis will have the same limits, ticks, and scale as the axis + of the shared Axes. + + label : str + A label for the returned Axes. + + Returns + ------- + `~.axes.Axes`, or a subclass of `~.axes.Axes` + The returned axes class depends on the projection used. It is + `~.axes.Axes` if rectilinear projection is used and + `.projections.polar.PolarAxes` if polar projection is used. + + Other Parameters + ---------------- + **kwargs + This method also takes the keyword arguments for + the returned Axes class. The keyword arguments for the + rectilinear Axes class `~.axes.Axes` can be found in + the following table but there might also be other keyword + arguments if another projection is used, see the actual Axes + class. + + %(Axes:kwdoc)s + + See Also + -------- + .Figure.add_axes + .pyplot.subplot + .Figure.add_subplot + .Figure.subplots + .pyplot.subplots + + Examples + -------- + :: + + # Creating a new full window Axes + plt.axes() + + # Creating a new Axes with specified dimensions and a grey background + plt.axes((left, bottom, width, height), facecolor='grey') + """ + fig = gcf() + pos = kwargs.pop('position', None) + if arg is None: + if pos is None: + return fig.add_subplot(**kwargs) + else: + return fig.add_axes(pos, **kwargs) + else: + return fig.add_axes(arg, **kwargs) + + +def delaxes(ax: matplotlib.axes.Axes | None = None) -> None: + """ + Remove an `~.axes.Axes` (defaulting to the current axes) from its figure. + """ + if ax is None: + ax = gca() + ax.remove() + + +def sca(ax: Axes) -> None: + """ + Set the current Axes to *ax* and the current Figure to the parent of *ax*. + """ + # Mypy sees ax.figure as potentially None, + # but if you are calling this, it won't be None + # Additionally the slight difference between `Figure` and `FigureBase` mypy catches + figure(ax.figure) # type: ignore[arg-type] + ax.figure.sca(ax) # type: ignore[union-attr] + + +def cla() -> None: + """Clear the current axes.""" + # Not generated via boilerplate.py to allow a different docstring. + return gca().cla() + + +## More ways of creating axes ## + +@_docstring.dedent_interpd +def subplot(*args, **kwargs) -> Axes: + """ + Add an Axes to the current figure or retrieve an existing Axes. + + This is a wrapper of `.Figure.add_subplot` which provides additional + behavior when working with the implicit API (see the notes section). + + Call signatures:: + + subplot(nrows, ncols, index, **kwargs) + subplot(pos, **kwargs) + subplot(**kwargs) + subplot(ax) + + Parameters + ---------- + *args : int, (int, int, *index*), or `.SubplotSpec`, default: (1, 1, 1) + The position of the subplot described by one of + + - Three integers (*nrows*, *ncols*, *index*). The subplot will take the + *index* position on a grid with *nrows* rows and *ncols* columns. + *index* starts at 1 in the upper left corner and increases to the + right. *index* can also be a two-tuple specifying the (*first*, + *last*) indices (1-based, and including *last*) of the subplot, e.g., + ``fig.add_subplot(3, 1, (1, 2))`` makes a subplot that spans the + upper 2/3 of the figure. + - A 3-digit integer. The digits are interpreted as if given separately + as three single-digit integers, i.e. ``fig.add_subplot(235)`` is the + same as ``fig.add_subplot(2, 3, 5)``. Note that this can only be used + if there are no more than 9 subplots. + - A `.SubplotSpec`. + + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', 'rectilinear', str}, optional + The projection type of the subplot (`~.axes.Axes`). *str* is the name + of a custom projection, see `~matplotlib.projections`. The default + None results in a 'rectilinear' projection. + + polar : bool, default: False + If True, equivalent to projection='polar'. + + sharex, sharey : `~matplotlib.axes.Axes`, optional + Share the x or y `~matplotlib.axis` with sharex and/or sharey. The + axis will have the same limits, ticks, and scale as the axis of the + shared axes. + + label : str + A label for the returned axes. + + Returns + ------- + `~.axes.Axes` + + The Axes of the subplot. The returned Axes can actually be an instance + of a subclass, such as `.projections.polar.PolarAxes` for polar + projections. + + Other Parameters + ---------------- + **kwargs + This method also takes the keyword arguments for the returned axes + base class; except for the *figure* argument. The keyword arguments + for the rectilinear base class `~.axes.Axes` can be found in + the following table but there might also be other keyword + arguments if another projection is used. + + %(Axes:kwdoc)s + + Notes + ----- + Creating a new Axes will delete any preexisting Axes that + overlaps with it beyond sharing a boundary:: + + import matplotlib.pyplot as plt + # plot a line, implicitly creating a subplot(111) + plt.plot([1, 2, 3]) + # now create a subplot which represents the top plot of a grid + # with 2 rows and 1 column. Since this subplot will overlap the + # first, the plot (and its axes) previously created, will be removed + plt.subplot(211) + + If you do not want this behavior, use the `.Figure.add_subplot` method + or the `.pyplot.axes` function instead. + + If no *kwargs* are passed and there exists an Axes in the location + specified by *args* then that Axes will be returned rather than a new + Axes being created. + + If *kwargs* are passed and there exists an Axes in the location + specified by *args*, the projection type is the same, and the + *kwargs* match with the existing Axes, then the existing Axes is + returned. Otherwise a new Axes is created with the specified + parameters. We save a reference to the *kwargs* which we use + for this comparison. If any of the values in *kwargs* are + mutable we will not detect the case where they are mutated. + In these cases we suggest using `.Figure.add_subplot` and the + explicit Axes API rather than the implicit pyplot API. + + See Also + -------- + .Figure.add_subplot + .pyplot.subplots + .pyplot.axes + .Figure.subplots + + Examples + -------- + :: + + plt.subplot(221) + + # equivalent but more general + ax1 = plt.subplot(2, 2, 1) + + # add a subplot with no frame + ax2 = plt.subplot(222, frameon=False) + + # add a polar subplot + plt.subplot(223, projection='polar') + + # add a red subplot that shares the x-axis with ax1 + plt.subplot(224, sharex=ax1, facecolor='red') + + # delete ax2 from the figure + plt.delaxes(ax2) + + # add ax2 to the figure again + plt.subplot(ax2) + + # make the first axes "current" again + plt.subplot(221) + + """ + # Here we will only normalize `polar=True` vs `projection='polar'` and let + # downstream code deal with the rest. + unset = object() + projection = kwargs.get('projection', unset) + polar = kwargs.pop('polar', unset) + if polar is not unset and polar: + # if we got mixed messages from the user, raise + if projection is not unset and projection != 'polar': + raise ValueError( + f"polar={polar}, yet projection={projection!r}. " + "Only one of these arguments should be supplied." + ) + kwargs['projection'] = projection = 'polar' + + # if subplot called without arguments, create subplot(1, 1, 1) + if len(args) == 0: + args = (1, 1, 1) + + # This check was added because it is very easy to type subplot(1, 2, False) + # when subplots(1, 2, False) was intended (sharex=False, that is). In most + # cases, no error will ever occur, but mysterious behavior can result + # because what was intended to be the sharex argument is instead treated as + # a subplot index for subplot() + if len(args) >= 3 and isinstance(args[2], bool): + _api.warn_external("The subplot index argument to subplot() appears " + "to be a boolean. Did you intend to use " + "subplots()?") + # Check for nrows and ncols, which are not valid subplot args: + if 'nrows' in kwargs or 'ncols' in kwargs: + raise TypeError("subplot() got an unexpected keyword argument 'ncols' " + "and/or 'nrows'. Did you intend to call subplots()?") + + fig = gcf() + + # First, search for an existing subplot with a matching spec. + key = SubplotSpec._from_subplot_args(fig, args) + + for ax in fig.axes: + # If we found an Axes at the position, we can re-use it if the user passed no + # kwargs or if the axes class and kwargs are identical. + if (ax.get_subplotspec() == key + and (kwargs == {} + or (ax._projection_init + == fig._process_projection_requirements(**kwargs)))): + break + else: + # we have exhausted the known Axes and none match, make a new one! + ax = fig.add_subplot(*args, **kwargs) + + fig.sca(ax) + + return ax + + +def subplots( + nrows: int = 1, ncols: int = 1, *, + sharex: bool | Literal["none", "all", "row", "col"] = False, + sharey: bool | Literal["none", "all", "row", "col"] = False, + squeeze: bool = True, + width_ratios: Sequence[float] | None = None, + height_ratios: Sequence[float] | None = None, + subplot_kw: dict[str, Any] | None = None, + gridspec_kw: dict[str, Any] | None = None, + **fig_kw +) -> tuple[Figure, Any]: + """ + Create a figure and a set of subplots. + + This utility wrapper makes it convenient to create common layouts of + subplots, including the enclosing figure object, in a single call. + + Parameters + ---------- + nrows, ncols : int, default: 1 + Number of rows/columns of the subplot grid. + + sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False + Controls sharing of properties among x (*sharex*) or y (*sharey*) + axes: + + - True or 'all': x- or y-axis will be shared among all subplots. + - False or 'none': each subplot x- or y-axis will be independent. + - 'row': each subplot row will share an x- or y-axis. + - 'col': each subplot column will share an x- or y-axis. + + When subplots have a shared x-axis along a column, only the x tick + labels of the bottom subplot are created. Similarly, when subplots + have a shared y-axis along a row, only the y tick labels of the first + column subplot are created. To later turn other subplots' ticklabels + on, use `~matplotlib.axes.Axes.tick_params`. + + When subplots have a shared axis that has units, calling + `~matplotlib.axis.Axis.set_units` will update each axis with the + new units. + + squeeze : bool, default: True + - If True, extra dimensions are squeezed out from the returned + array of `~matplotlib.axes.Axes`: + + - if only one subplot is constructed (nrows=ncols=1), the + resulting single Axes object is returned as a scalar. + - for Nx1 or 1xM subplots, the returned object is a 1D numpy + object array of Axes objects. + - for NxM, subplots with N>1 and M>1 are returned as a 2D array. + + - If False, no squeezing at all is done: the returned Axes object is + always a 2D array containing Axes instances, even if it ends up + being 1x1. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. Equivalent + to ``gridspec_kw={'width_ratios': [...]}``. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. Convenience + for ``gridspec_kw={'height_ratios': [...]}``. + + subplot_kw : dict, optional + Dict with keywords passed to the + `~matplotlib.figure.Figure.add_subplot` call used to create each + subplot. + + gridspec_kw : dict, optional + Dict with keywords passed to the `~matplotlib.gridspec.GridSpec` + constructor used to create the grid the subplots are placed on. + + **fig_kw + All additional keyword arguments are passed to the + `.pyplot.figure` call. + + Returns + ------- + fig : `.Figure` + + ax : `~matplotlib.axes.Axes` or array of Axes + *ax* can be either a single `~.axes.Axes` object, or an array of Axes + objects if more than one subplot was created. The dimensions of the + resulting array can be controlled with the squeeze keyword, see above. + + Typical idioms for handling the return value are:: + + # using the variable ax for single a Axes + fig, ax = plt.subplots() + + # using the variable axs for multiple Axes + fig, axs = plt.subplots(2, 2) + + # using tuple unpacking for multiple Axes + fig, (ax1, ax2) = plt.subplots(1, 2) + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) + + The names ``ax`` and pluralized ``axs`` are preferred over ``axes`` + because for the latter it's not clear if it refers to a single + `~.axes.Axes` instance or a collection of these. + + See Also + -------- + .pyplot.figure + .pyplot.subplot + .pyplot.axes + .Figure.subplots + .Figure.add_subplot + + Examples + -------- + :: + + # First create some toy data: + x = np.linspace(0, 2*np.pi, 400) + y = np.sin(x**2) + + # Create just a figure and only one subplot + fig, ax = plt.subplots() + ax.plot(x, y) + ax.set_title('Simple plot') + + # Create two subplots and unpack the output array immediately + f, (ax1, ax2) = plt.subplots(1, 2, sharey=True) + ax1.plot(x, y) + ax1.set_title('Sharing Y axis') + ax2.scatter(x, y) + + # Create four polar axes and access them through the returned array + fig, axs = plt.subplots(2, 2, subplot_kw=dict(projection="polar")) + axs[0, 0].plot(x, y) + axs[1, 1].scatter(x, y) + + # Share a X axis with each column of subplots + plt.subplots(2, 2, sharex='col') + + # Share a Y axis with each row of subplots + plt.subplots(2, 2, sharey='row') + + # Share both X and Y axes with all subplots + plt.subplots(2, 2, sharex='all', sharey='all') + + # Note that this is the same as + plt.subplots(2, 2, sharex=True, sharey=True) + + # Create figure number 10 with a single subplot + # and clears it if it already exists. + fig, ax = plt.subplots(num=10, clear=True) + + """ + fig = figure(**fig_kw) + axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey, + squeeze=squeeze, subplot_kw=subplot_kw, + gridspec_kw=gridspec_kw, height_ratios=height_ratios, + width_ratios=width_ratios) + return fig, axs + + +@overload +def subplot_mosaic( + mosaic: str, + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: str = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ..., + **fig_kw: Any +) -> tuple[Figure, dict[str, matplotlib.axes.Axes]]: ... + + +@overload +def subplot_mosaic( + mosaic: list[HashableList[_T]], + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: _T = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ..., + **fig_kw: Any +) -> tuple[Figure, dict[_T, matplotlib.axes.Axes]]: ... + + +@overload +def subplot_mosaic( + mosaic: list[HashableList[Hashable]], + *, + sharex: bool = ..., + sharey: bool = ..., + width_ratios: ArrayLike | None = ..., + height_ratios: ArrayLike | None = ..., + empty_sentinel: Any = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ..., + **fig_kw: Any +) -> tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]: ... + + +def subplot_mosaic( + mosaic: str | list[HashableList[_T]] | list[HashableList[Hashable]], + *, + sharex: bool = False, + sharey: bool = False, + width_ratios: ArrayLike | None = None, + height_ratios: ArrayLike | None = None, + empty_sentinel: Any = '.', + subplot_kw: dict[str, Any] | None = None, + gridspec_kw: dict[str, Any] | None = None, + per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | + dict[_T | tuple[_T, ...], dict[str, Any]] | + dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = None, + **fig_kw: Any +) -> tuple[Figure, dict[str, matplotlib.axes.Axes]] | \ + tuple[Figure, dict[_T, matplotlib.axes.Axes]] | \ + tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]: + """ + Build a layout of Axes based on ASCII art or nested lists. + + This is a helper function to build complex GridSpec layouts visually. + + See :ref:`mosaic` + for an example and full API documentation + + Parameters + ---------- + mosaic : list of list of {hashable or nested} or str + + A visual layout of how you want your Axes to be arranged + labeled as strings. For example :: + + x = [['A panel', 'A panel', 'edge'], + ['C panel', '.', 'edge']] + + produces 4 axes: + + - 'A panel' which is 1 row high and spans the first two columns + - 'edge' which is 2 rows high and is on the right edge + - 'C panel' which in 1 row and 1 column wide in the bottom left + - a blank space 1 row and 1 column wide in the bottom center + + Any of the entries in the layout can be a list of lists + of the same form to create nested layouts. + + If input is a str, then it must be of the form :: + + ''' + AAE + C.E + ''' + + where each character is a column and each line is a row. + This only allows only single character Axes labels and does + not allow nesting but is very terse. + + sharex, sharey : bool, default: False + If True, the x-axis (*sharex*) or y-axis (*sharey*) will be shared + among all subplots. In that case, tick label visibility and axis units + behave as for `subplots`. If False, each subplot's x- or y-axis will + be independent. + + width_ratios : array-like of length *ncols*, optional + Defines the relative widths of the columns. Each column gets a + relative width of ``width_ratios[i] / sum(width_ratios)``. + If not given, all columns will have the same width. Convenience + for ``gridspec_kw={'width_ratios': [...]}``. + + height_ratios : array-like of length *nrows*, optional + Defines the relative heights of the rows. Each row gets a + relative height of ``height_ratios[i] / sum(height_ratios)``. + If not given, all rows will have the same height. Convenience + for ``gridspec_kw={'height_ratios': [...]}``. + + empty_sentinel : object, optional + Entry in the layout to mean "leave this space empty". Defaults + to ``'.'``. Note, if *layout* is a string, it is processed via + `inspect.cleandoc` to remove leading white space, which may + interfere with using white-space as the empty sentinel. + + subplot_kw : dict, optional + Dictionary with keywords passed to the `.Figure.add_subplot` call + used to create each subplot. These values may be overridden by + values in *per_subplot_kw*. + + per_subplot_kw : dict, optional + A dictionary mapping the Axes identifiers or tuples of identifiers + to a dictionary of keyword arguments to be passed to the + `.Figure.add_subplot` call used to create each subplot. The values + in these dictionaries have precedence over the values in + *subplot_kw*. + + If *mosaic* is a string, and thus all keys are single characters, + it is possible to use a single string instead of a tuple as keys; + i.e. ``"AB"`` is equivalent to ``("A", "B")``. + + .. versionadded:: 3.7 + + gridspec_kw : dict, optional + Dictionary with keywords passed to the `.GridSpec` constructor used + to create the grid the subplots are placed on. + + **fig_kw + All additional keyword arguments are passed to the + `.pyplot.figure` call. + + Returns + ------- + fig : `.Figure` + The new figure + + dict[label, Axes] + A dictionary mapping the labels to the Axes objects. The order of + the axes is left-to-right and top-to-bottom of their position in the + total layout. + + """ + fig = figure(**fig_kw) + ax_dict = fig.subplot_mosaic( # type: ignore[misc] + mosaic, # type: ignore[arg-type] + sharex=sharex, sharey=sharey, + height_ratios=height_ratios, width_ratios=width_ratios, + subplot_kw=subplot_kw, gridspec_kw=gridspec_kw, + empty_sentinel=empty_sentinel, + per_subplot_kw=per_subplot_kw, # type: ignore[arg-type] + ) + return fig, ax_dict + + +def subplot2grid( + shape: tuple[int, int], loc: tuple[int, int], + rowspan: int = 1, colspan: int = 1, + fig: Figure | None = None, + **kwargs +) -> matplotlib.axes.Axes: + """ + Create a subplot at a specific location inside a regular grid. + + Parameters + ---------- + shape : (int, int) + Number of rows and of columns of the grid in which to place axis. + loc : (int, int) + Row number and column number of the axis location within the grid. + rowspan : int, default: 1 + Number of rows for the axis to span downwards. + colspan : int, default: 1 + Number of columns for the axis to span to the right. + fig : `.Figure`, optional + Figure to place the subplot in. Defaults to the current figure. + **kwargs + Additional keyword arguments are handed to `~.Figure.add_subplot`. + + Returns + ------- + `~.axes.Axes` + + The Axes of the subplot. The returned Axes can actually be an instance + of a subclass, such as `.projections.polar.PolarAxes` for polar + projections. + + Notes + ----- + The following call :: + + ax = subplot2grid((nrows, ncols), (row, col), rowspan, colspan) + + is identical to :: + + fig = gcf() + gs = fig.add_gridspec(nrows, ncols) + ax = fig.add_subplot(gs[row:row+rowspan, col:col+colspan]) + """ + if fig is None: + fig = gcf() + rows, cols = shape + gs = GridSpec._check_gridspec_exists(fig, rows, cols) + subplotspec = gs.new_subplotspec(loc, rowspan=rowspan, colspan=colspan) + return fig.add_subplot(subplotspec, **kwargs) + + +def twinx(ax: matplotlib.axes.Axes | None = None) -> _AxesBase: + """ + Make and return a second axes that shares the *x*-axis. The new axes will + overlay *ax* (or the current axes if *ax* is *None*), and its ticks will be + on the right. + + Examples + -------- + :doc:`/gallery/subplots_axes_and_figures/two_scales` + """ + if ax is None: + ax = gca() + ax1 = ax.twinx() + return ax1 + + +def twiny(ax: matplotlib.axes.Axes | None = None) -> _AxesBase: + """ + Make and return a second axes that shares the *y*-axis. The new axes will + overlay *ax* (or the current axes if *ax* is *None*), and its ticks will be + on the top. + + Examples + -------- + :doc:`/gallery/subplots_axes_and_figures/two_scales` + """ + if ax is None: + ax = gca() + ax1 = ax.twiny() + return ax1 + + +def subplot_tool(targetfig: Figure | None = None) -> SubplotTool | None: + """ + Launch a subplot tool window for a figure. + + Returns + ------- + `matplotlib.widgets.SubplotTool` + """ + if targetfig is None: + targetfig = gcf() + tb = targetfig.canvas.manager.toolbar # type: ignore[union-attr] + if hasattr(tb, "configure_subplots"): # toolbar2 + from matplotlib.backend_bases import NavigationToolbar2 + return cast(NavigationToolbar2, tb).configure_subplots() + elif hasattr(tb, "trigger_tool"): # toolmanager + from matplotlib.backend_bases import ToolContainerBase + cast(ToolContainerBase, tb).trigger_tool("subplots") + return None + else: + raise ValueError("subplot_tool can only be launched for figures with " + "an associated toolbar") + + +def box(on: bool | None = None) -> None: + """ + Turn the axes box on or off on the current axes. + + Parameters + ---------- + on : bool or None + The new `~matplotlib.axes.Axes` box state. If ``None``, toggle + the state. + + See Also + -------- + :meth:`matplotlib.axes.Axes.set_frame_on` + :meth:`matplotlib.axes.Axes.get_frame_on` + """ + ax = gca() + if on is None: + on = not ax.get_frame_on() + ax.set_frame_on(on) + +## Axis ## + + +def xlim(*args, **kwargs) -> tuple[float, float]: + """ + Get or set the x limits of the current axes. + + Call signatures:: + + left, right = xlim() # return the current xlim + xlim((left, right)) # set the xlim to left, right + xlim(left, right) # set the xlim to left, right + + If you do not specify args, you can pass *left* or *right* as kwargs, + i.e.:: + + xlim(right=3) # adjust the right leaving left unchanged + xlim(left=1) # adjust the left leaving right unchanged + + Setting limits turns autoscaling off for the x-axis. + + Returns + ------- + left, right + A tuple of the new x-axis limits. + + Notes + ----- + Calling this function with no arguments (e.g. ``xlim()``) is the pyplot + equivalent of calling `~.Axes.get_xlim` on the current axes. + Calling this function with arguments is the pyplot equivalent of calling + `~.Axes.set_xlim` on the current axes. All arguments are passed though. + """ + ax = gca() + if not args and not kwargs: + return ax.get_xlim() + ret = ax.set_xlim(*args, **kwargs) + return ret + + +def ylim(*args, **kwargs) -> tuple[float, float]: + """ + Get or set the y-limits of the current axes. + + Call signatures:: + + bottom, top = ylim() # return the current ylim + ylim((bottom, top)) # set the ylim to bottom, top + ylim(bottom, top) # set the ylim to bottom, top + + If you do not specify args, you can alternatively pass *bottom* or + *top* as kwargs, i.e.:: + + ylim(top=3) # adjust the top leaving bottom unchanged + ylim(bottom=1) # adjust the bottom leaving top unchanged + + Setting limits turns autoscaling off for the y-axis. + + Returns + ------- + bottom, top + A tuple of the new y-axis limits. + + Notes + ----- + Calling this function with no arguments (e.g. ``ylim()``) is the pyplot + equivalent of calling `~.Axes.get_ylim` on the current axes. + Calling this function with arguments is the pyplot equivalent of calling + `~.Axes.set_ylim` on the current axes. All arguments are passed though. + """ + ax = gca() + if not args and not kwargs: + return ax.get_ylim() + ret = ax.set_ylim(*args, **kwargs) + return ret + + +def xticks( + ticks: ArrayLike | None = None, + labels: Sequence[str] | None = None, + *, + minor: bool = False, + **kwargs +) -> tuple[list[Tick] | np.ndarray, list[Text]]: + """ + Get or set the current tick locations and labels of the x-axis. + + Pass no arguments to return the current values without modifying them. + + Parameters + ---------- + ticks : array-like, optional + The list of xtick locations. Passing an empty list removes all xticks. + labels : array-like, optional + The labels to place at the given *ticks* locations. This argument can + only be passed if *ticks* is passed as well. + minor : bool, default: False + If ``False``, get/set the major ticks/labels; if ``True``, the minor + ticks/labels. + **kwargs + `.Text` properties can be used to control the appearance of the labels. + + Returns + ------- + locs + The list of xtick locations. + labels + The list of xlabel `.Text` objects. + + Notes + ----- + Calling this function with no arguments (e.g. ``xticks()``) is the pyplot + equivalent of calling `~.Axes.get_xticks` and `~.Axes.get_xticklabels` on + the current axes. + Calling this function with arguments is the pyplot equivalent of calling + `~.Axes.set_xticks` and `~.Axes.set_xticklabels` on the current axes. + + Examples + -------- + >>> locs, labels = xticks() # Get the current locations and labels. + >>> xticks(np.arange(0, 1, step=0.2)) # Set label locations. + >>> xticks(np.arange(3), ['Tom', 'Dick', 'Sue']) # Set text labels. + >>> xticks([0, 1, 2], ['January', 'February', 'March'], + ... rotation=20) # Set text labels and properties. + >>> xticks([]) # Disable xticks. + """ + ax = gca() + + locs: list[Tick] | np.ndarray + if ticks is None: + locs = ax.get_xticks(minor=minor) + if labels is not None: + raise TypeError("xticks(): Parameter 'labels' can't be set " + "without setting 'ticks'") + else: + locs = ax.set_xticks(ticks, minor=minor) + + labels_out: list[Text] = [] + if labels is None: + labels_out = ax.get_xticklabels(minor=minor) + for l in labels_out: + l._internal_update(kwargs) + else: + labels_out = ax.set_xticklabels(labels, minor=minor, **kwargs) + + return locs, labels_out + + +def yticks( + ticks: ArrayLike | None = None, + labels: Sequence[str] | None = None, + *, + minor: bool = False, + **kwargs +) -> tuple[list[Tick] | np.ndarray, list[Text]]: + """ + Get or set the current tick locations and labels of the y-axis. + + Pass no arguments to return the current values without modifying them. + + Parameters + ---------- + ticks : array-like, optional + The list of ytick locations. Passing an empty list removes all yticks. + labels : array-like, optional + The labels to place at the given *ticks* locations. This argument can + only be passed if *ticks* is passed as well. + minor : bool, default: False + If ``False``, get/set the major ticks/labels; if ``True``, the minor + ticks/labels. + **kwargs + `.Text` properties can be used to control the appearance of the labels. + + Returns + ------- + locs + The list of ytick locations. + labels + The list of ylabel `.Text` objects. + + Notes + ----- + Calling this function with no arguments (e.g. ``yticks()``) is the pyplot + equivalent of calling `~.Axes.get_yticks` and `~.Axes.get_yticklabels` on + the current axes. + Calling this function with arguments is the pyplot equivalent of calling + `~.Axes.set_yticks` and `~.Axes.set_yticklabels` on the current axes. + + Examples + -------- + >>> locs, labels = yticks() # Get the current locations and labels. + >>> yticks(np.arange(0, 1, step=0.2)) # Set label locations. + >>> yticks(np.arange(3), ['Tom', 'Dick', 'Sue']) # Set text labels. + >>> yticks([0, 1, 2], ['January', 'February', 'March'], + ... rotation=45) # Set text labels and properties. + >>> yticks([]) # Disable yticks. + """ + ax = gca() + + locs: list[Tick] | np.ndarray + if ticks is None: + locs = ax.get_yticks(minor=minor) + if labels is not None: + raise TypeError("yticks(): Parameter 'labels' can't be set " + "without setting 'ticks'") + else: + locs = ax.set_yticks(ticks, minor=minor) + + labels_out: list[Text] = [] + if labels is None: + labels_out = ax.get_yticklabels(minor=minor) + for l in labels_out: + l._internal_update(kwargs) + else: + labels_out = ax.set_yticklabels(labels, minor=minor, **kwargs) + + return locs, labels_out + + +def rgrids( + radii: ArrayLike | None = None, + labels: Sequence[str | Text] | None = None, + angle: float | None = None, + fmt: str | None = None, + **kwargs +) -> tuple[list[Line2D], list[Text]]: + """ + Get or set the radial gridlines on the current polar plot. + + Call signatures:: + + lines, labels = rgrids() + lines, labels = rgrids(radii, labels=None, angle=22.5, fmt=None, **kwargs) + + When called with no arguments, `.rgrids` simply returns the tuple + (*lines*, *labels*). When called with arguments, the labels will + appear at the specified radial distances and angle. + + Parameters + ---------- + radii : tuple with floats + The radii for the radial gridlines + + labels : tuple with strings or None + The labels to use at each radial gridline. The + `matplotlib.ticker.ScalarFormatter` will be used if None. + + angle : float + The angular position of the radius labels in degrees. + + fmt : str or None + Format string used in `matplotlib.ticker.FormatStrFormatter`. + For example '%f'. + + Returns + ------- + lines : list of `.lines.Line2D` + The radial gridlines. + + labels : list of `.text.Text` + The tick labels. + + Other Parameters + ---------------- + **kwargs + *kwargs* are optional `.Text` properties for the labels. + + See Also + -------- + .pyplot.thetagrids + .projections.polar.PolarAxes.set_rgrids + .Axis.get_gridlines + .Axis.get_ticklabels + + Examples + -------- + :: + + # set the locations of the radial gridlines + lines, labels = rgrids( (0.25, 0.5, 1.0) ) + + # set the locations and labels of the radial gridlines + lines, labels = rgrids( (0.25, 0.5, 1.0), ('Tom', 'Dick', 'Harry' )) + """ + ax = gca() + if not isinstance(ax, PolarAxes): + raise RuntimeError('rgrids only defined for polar axes') + if all(p is None for p in [radii, labels, angle, fmt]) and not kwargs: + lines_out: list[Line2D] = ax.yaxis.get_gridlines() + labels_out: list[Text] = ax.yaxis.get_ticklabels() + elif radii is None: + raise TypeError("'radii' cannot be None when other parameters are passed") + else: + lines_out, labels_out = ax.set_rgrids( + radii, labels=labels, angle=angle, fmt=fmt, **kwargs) + return lines_out, labels_out + + +def thetagrids( + angles: ArrayLike | None = None, + labels: Sequence[str | Text] | None = None, + fmt: str | None = None, + **kwargs +) -> tuple[list[Line2D], list[Text]]: + """ + Get or set the theta gridlines on the current polar plot. + + Call signatures:: + + lines, labels = thetagrids() + lines, labels = thetagrids(angles, labels=None, fmt=None, **kwargs) + + When called with no arguments, `.thetagrids` simply returns the tuple + (*lines*, *labels*). When called with arguments, the labels will + appear at the specified angles. + + Parameters + ---------- + angles : tuple with floats, degrees + The angles of the theta gridlines. + + labels : tuple with strings or None + The labels to use at each radial gridline. The + `.projections.polar.ThetaFormatter` will be used if None. + + fmt : str or None + Format string used in `matplotlib.ticker.FormatStrFormatter`. + For example '%f'. Note that the angle in radians will be used. + + Returns + ------- + lines : list of `.lines.Line2D` + The theta gridlines. + + labels : list of `.text.Text` + The tick labels. + + Other Parameters + ---------------- + **kwargs + *kwargs* are optional `.Text` properties for the labels. + + See Also + -------- + .pyplot.rgrids + .projections.polar.PolarAxes.set_thetagrids + .Axis.get_gridlines + .Axis.get_ticklabels + + Examples + -------- + :: + + # set the locations of the angular gridlines + lines, labels = thetagrids(range(45, 360, 90)) + + # set the locations and labels of the angular gridlines + lines, labels = thetagrids(range(45, 360, 90), ('NE', 'NW', 'SW', 'SE')) + """ + ax = gca() + if not isinstance(ax, PolarAxes): + raise RuntimeError('thetagrids only defined for polar axes') + if all(param is None for param in [angles, labels, fmt]) and not kwargs: + lines_out: list[Line2D] = ax.xaxis.get_ticklines() + labels_out: list[Text] = ax.xaxis.get_ticklabels() + elif angles is None: + raise TypeError("'angles' cannot be None when other parameters are passed") + else: + lines_out, labels_out = ax.set_thetagrids(angles, + labels=labels, fmt=fmt, + **kwargs) + return lines_out, labels_out + + +@_api.deprecated("3.7", pending=True) +def get_plot_commands() -> list[str]: + """ + Get a sorted list of all of the plotting commands. + """ + NON_PLOT_COMMANDS = { + 'connect', 'disconnect', 'get_current_fig_manager', 'ginput', + 'new_figure_manager', 'waitforbuttonpress'} + return [name for name in _get_pyplot_commands() + if name not in NON_PLOT_COMMANDS] + + +def _get_pyplot_commands() -> list[str]: + # This works by searching for all functions in this module and removing + # a few hard-coded exclusions, as well as all of the colormap-setting + # functions, and anything marked as private with a preceding underscore. + exclude = {'colormaps', 'colors', 'get_plot_commands', *colormaps} + this_module = inspect.getmodule(get_plot_commands) + return sorted( + name for name, obj in globals().items() + if not name.startswith('_') and name not in exclude + and inspect.isfunction(obj) + and inspect.getmodule(obj) is this_module) + + +## Plotting part 1: manually generated functions and wrappers ## + + +@_copy_docstring_and_deprecators(Figure.colorbar) +def colorbar( + mappable: ScalarMappable | None = None, + cax: matplotlib.axes.Axes | None = None, + ax: matplotlib.axes.Axes | Iterable[matplotlib.axes.Axes] | None = None, + **kwargs +) -> Colorbar: + if mappable is None: + mappable = gci() + if mappable is None: + raise RuntimeError('No mappable was found to use for colorbar ' + 'creation. First define a mappable such as ' + 'an image (with imshow) or a contour set (' + 'with contourf).') + ret = gcf().colorbar(mappable, cax=cax, ax=ax, **kwargs) + return ret + + +def clim(vmin: float | None = None, vmax: float | None = None) -> None: + """ + Set the color limits of the current image. + + If either *vmin* or *vmax* is None, the image min/max respectively + will be used for color scaling. + + If you want to set the clim of multiple images, use + `~.ScalarMappable.set_clim` on every image, for example:: + + for im in gca().get_images(): + im.set_clim(0, 0.5) + + """ + im = gci() + if im is None: + raise RuntimeError('You must first define an image, e.g., with imshow') + + im.set_clim(vmin, vmax) + + +# eventually this implementation should move here, use indirection for now to +# avoid having two copies of the code floating around. +def get_cmap( + name: Colormap | str | None = None, + lut: int | None = None +) -> Colormap: + return cm._get_cmap(name=name, lut=lut) # type: ignore +get_cmap.__doc__ = cm._get_cmap.__doc__ # type: ignore + + +def set_cmap(cmap: Colormap | str) -> None: + """ + Set the default colormap, and applies it to the current image if any. + + Parameters + ---------- + cmap : `~matplotlib.colors.Colormap` or str + A colormap instance or the name of a registered colormap. + + See Also + -------- + colormaps + matplotlib.cm.register_cmap + matplotlib.cm.get_cmap + """ + cmap = get_cmap(cmap) + + rc('image', cmap=cmap.name) + im = gci() + + if im is not None: + im.set_cmap(cmap) + + +@_copy_docstring_and_deprecators(matplotlib.image.imread) +def imread( + fname: str | pathlib.Path | BinaryIO, format: str | None = None +) -> np.ndarray: + return matplotlib.image.imread(fname, format) + + +@_copy_docstring_and_deprecators(matplotlib.image.imsave) +def imsave( + fname: str | os.PathLike | BinaryIO, arr: ArrayLike, **kwargs +) -> None: + matplotlib.image.imsave(fname, arr, **kwargs) + + +def matshow(A: ArrayLike, fignum: None | int = None, **kwargs) -> AxesImage: + """ + Display an array as a matrix in a new figure window. + + The origin is set at the upper left hand corner and rows (first + dimension of the array) are displayed horizontally. The aspect + ratio of the figure window is that of the array, unless this would + make an excessively short or narrow figure. + + Tick labels for the xaxis are placed on top. + + Parameters + ---------- + A : 2D array-like + The matrix to be displayed. + + fignum : None or int + If *None*, create a new, appropriately sized figure window. + + If 0, use the current Axes (creating one if there is none, without ever + adjusting the figure size). + + Otherwise, create a new Axes on the figure with the given number + (creating it at the appropriate size if it does not exist, but not + adjusting the figure size otherwise). Note that this will be drawn on + top of any preexisting Axes on the figure. + + Returns + ------- + `~matplotlib.image.AxesImage` + + Other Parameters + ---------------- + **kwargs : `~matplotlib.axes.Axes.imshow` arguments + + """ + A = np.asanyarray(A) + if fignum == 0: + ax = gca() + else: + # Extract actual aspect ratio of array and make appropriately sized + # figure. + fig = figure(fignum, figsize=figaspect(A)) + ax = fig.add_axes((0.15, 0.09, 0.775, 0.775)) + im = ax.matshow(A, **kwargs) + sci(im) + return im + + +def polar(*args, **kwargs) -> list[Line2D]: + """ + Make a polar plot. + + call signature:: + + polar(theta, r, **kwargs) + + Multiple *theta*, *r* arguments are supported, with format strings, as in + `plot`. + """ + # If an axis already exists, check if it has a polar projection + if gcf().get_axes(): + ax = gca() + if not isinstance(ax, PolarAxes): + _api.warn_external('Trying to create polar plot on an Axes ' + 'that does not have a polar projection.') + else: + ax = axes(projection="polar") + return ax.plot(*args, **kwargs) + + +# If rcParams['backend_fallback'] is true, and an interactive backend is +# requested, ignore rcParams['backend'] and force selection of a backend that +# is compatible with the current running interactive framework. +if (rcParams["backend_fallback"] + and rcParams._get_backend_or_none() in ( # type: ignore + set(rcsetup.interactive_bk) - {'WebAgg', 'nbAgg'}) + and cbook._get_running_interactive_framework()): # type: ignore + rcParams._set("backend", rcsetup._auto_backend_sentinel) # type: ignore + +# fmt: on + +################# REMAINING CONTENT GENERATED BY boilerplate.py ############## + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.figimage) +def figimage( + X: ArrayLike, + xo: int = 0, + yo: int = 0, + alpha: float | None = None, + norm: str | Normalize | None = None, + cmap: str | Colormap | None = None, + vmin: float | None = None, + vmax: float | None = None, + origin: Literal["upper", "lower"] | None = None, + resize: bool = False, + **kwargs, +) -> FigureImage: + return gcf().figimage( + X, + xo=xo, + yo=yo, + alpha=alpha, + norm=norm, + cmap=cmap, + vmin=vmin, + vmax=vmax, + origin=origin, + resize=resize, + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.text) +def figtext( + x: float, y: float, s: str, fontdict: dict[str, Any] | None = None, **kwargs +) -> Text: + return gcf().text(x, y, s, fontdict=fontdict, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.gca) +def gca() -> Axes: + return gcf().gca() + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure._gci) +def gci() -> ScalarMappable | None: + return gcf()._gci() + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.ginput) +def ginput( + n: int = 1, + timeout: float = 30, + show_clicks: bool = True, + mouse_add: MouseButton = MouseButton.LEFT, + mouse_pop: MouseButton = MouseButton.RIGHT, + mouse_stop: MouseButton = MouseButton.MIDDLE, +) -> list[tuple[int, int]]: + return gcf().ginput( + n=n, + timeout=timeout, + show_clicks=show_clicks, + mouse_add=mouse_add, + mouse_pop=mouse_pop, + mouse_stop=mouse_stop, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.subplots_adjust) +def subplots_adjust( + left: float | None = None, + bottom: float | None = None, + right: float | None = None, + top: float | None = None, + wspace: float | None = None, + hspace: float | None = None, +) -> None: + gcf().subplots_adjust( + left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=hspace + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.suptitle) +def suptitle(t: str, **kwargs) -> Text: + return gcf().suptitle(t, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.tight_layout) +def tight_layout( + *, + pad: float = 1.08, + h_pad: float | None = None, + w_pad: float | None = None, + rect: tuple[float, float, float, float] | None = None, +) -> None: + gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Figure.waitforbuttonpress) +def waitforbuttonpress(timeout: float = -1) -> None | bool: + return gcf().waitforbuttonpress(timeout=timeout) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.acorr) +def acorr( + x: ArrayLike, *, data=None, **kwargs +) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]: + return gca().acorr(x, **({"data": data} if data is not None else {}), **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.angle_spectrum) +def angle_spectrum( + x: ArrayLike, + Fs: float | None = None, + Fc: int | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, Line2D]: + return gca().angle_spectrum( + x, + Fs=Fs, + Fc=Fc, + window=window, + pad_to=pad_to, + sides=sides, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.annotate) +def annotate( + text: str, + xy: tuple[float, float], + xytext: tuple[float, float] | None = None, + xycoords: str + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] + | tuple[float, float] = "data", + textcoords: str + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] + | tuple[float, float] + | None = None, + arrowprops: dict[str, Any] | None = None, + annotation_clip: bool | None = None, + **kwargs, +) -> Annotation: + return gca().annotate( + text, + xy, + xytext=xytext, + xycoords=xycoords, + textcoords=textcoords, + arrowprops=arrowprops, + annotation_clip=annotation_clip, + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.arrow) +def arrow(x: float, y: float, dx: float, dy: float, **kwargs) -> FancyArrow: + return gca().arrow(x, y, dx, dy, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.autoscale) +def autoscale( + enable: bool = True, + axis: Literal["both", "x", "y"] = "both", + tight: bool | None = None, +) -> None: + gca().autoscale(enable=enable, axis=axis, tight=tight) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axhline) +def axhline(y: float = 0, xmin: float = 0, xmax: float = 1, **kwargs) -> Line2D: + return gca().axhline(y=y, xmin=xmin, xmax=xmax, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axhspan) +def axhspan( + ymin: float, ymax: float, xmin: float = 0, xmax: float = 1, **kwargs +) -> Polygon: + return gca().axhspan(ymin, ymax, xmin=xmin, xmax=xmax, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axis) +def axis( + arg: tuple[float, float, float, float] | bool | str | None = None, + /, + *, + emit: bool = True, + **kwargs, +) -> tuple[float, float, float, float]: + return gca().axis(arg, emit=emit, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axline) +def axline( + xy1: tuple[float, float], + xy2: tuple[float, float] | None = None, + *, + slope: float | None = None, + **kwargs, +) -> Line2D: + return gca().axline(xy1, xy2=xy2, slope=slope, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axvline) +def axvline(x: float = 0, ymin: float = 0, ymax: float = 1, **kwargs) -> Line2D: + return gca().axvline(x=x, ymin=ymin, ymax=ymax, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.axvspan) +def axvspan( + xmin: float, xmax: float, ymin: float = 0, ymax: float = 1, **kwargs +) -> Polygon: + return gca().axvspan(xmin, xmax, ymin=ymin, ymax=ymax, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.bar) +def bar( + x: float | ArrayLike, + height: float | ArrayLike, + width: float | ArrayLike = 0.8, + bottom: float | ArrayLike | None = None, + *, + align: Literal["center", "edge"] = "center", + data=None, + **kwargs, +) -> BarContainer: + return gca().bar( + x, + height, + width=width, + bottom=bottom, + align=align, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.barbs) +def barbs(*args, data=None, **kwargs) -> Barbs: + return gca().barbs(*args, **({"data": data} if data is not None else {}), **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.barh) +def barh( + y: float | ArrayLike, + width: float | ArrayLike, + height: float | ArrayLike = 0.8, + left: float | ArrayLike | None = None, + *, + align: Literal["center", "edge"] = "center", + data=None, + **kwargs, +) -> BarContainer: + return gca().barh( + y, + width, + height=height, + left=left, + align=align, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.bar_label) +def bar_label( + container: BarContainer, + labels: ArrayLike | None = None, + *, + fmt: str | Callable[[float], str] = "%g", + label_type: Literal["center", "edge"] = "edge", + padding: float = 0, + **kwargs, +) -> list[Annotation]: + return gca().bar_label( + container, + labels=labels, + fmt=fmt, + label_type=label_type, + padding=padding, + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.boxplot) +def boxplot( + x: ArrayLike | Sequence[ArrayLike], + notch: bool | None = None, + sym: str | None = None, + vert: bool | None = None, + whis: float | tuple[float, float] | None = None, + positions: ArrayLike | None = None, + widths: float | ArrayLike | None = None, + patch_artist: bool | None = None, + bootstrap: int | None = None, + usermedians: ArrayLike | None = None, + conf_intervals: ArrayLike | None = None, + meanline: bool | None = None, + showmeans: bool | None = None, + showcaps: bool | None = None, + showbox: bool | None = None, + showfliers: bool | None = None, + boxprops: dict[str, Any] | None = None, + labels: Sequence[str] | None = None, + flierprops: dict[str, Any] | None = None, + medianprops: dict[str, Any] | None = None, + meanprops: dict[str, Any] | None = None, + capprops: dict[str, Any] | None = None, + whiskerprops: dict[str, Any] | None = None, + manage_ticks: bool = True, + autorange: bool = False, + zorder: float | None = None, + capwidths: float | ArrayLike | None = None, + *, + data=None, +) -> dict[str, Any]: + return gca().boxplot( + x, + notch=notch, + sym=sym, + vert=vert, + whis=whis, + positions=positions, + widths=widths, + patch_artist=patch_artist, + bootstrap=bootstrap, + usermedians=usermedians, + conf_intervals=conf_intervals, + meanline=meanline, + showmeans=showmeans, + showcaps=showcaps, + showbox=showbox, + showfliers=showfliers, + boxprops=boxprops, + labels=labels, + flierprops=flierprops, + medianprops=medianprops, + meanprops=meanprops, + capprops=capprops, + whiskerprops=whiskerprops, + manage_ticks=manage_ticks, + autorange=autorange, + zorder=zorder, + capwidths=capwidths, + **({"data": data} if data is not None else {}), + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.broken_barh) +def broken_barh( + xranges: Sequence[tuple[float, float]], + yrange: tuple[float, float], + *, + data=None, + **kwargs, +) -> BrokenBarHCollection: + return gca().broken_barh( + xranges, yrange, **({"data": data} if data is not None else {}), **kwargs + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.clabel) +def clabel(CS: ContourSet, levels: ArrayLike | None = None, **kwargs) -> list[Text]: + return gca().clabel(CS, levels=levels, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.cohere) +def cohere( + x: ArrayLike, + y: ArrayLike, + NFFT: int = 256, + Fs: float = 2, + Fc: int = 0, + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike], ArrayLike] = mlab.detrend_none, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike = mlab.window_hanning, + noverlap: int = 0, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] = "default", + scale_by_freq: bool | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray]: + return gca().cohere( + x, + y, + NFFT=NFFT, + Fs=Fs, + Fc=Fc, + detrend=detrend, + window=window, + noverlap=noverlap, + pad_to=pad_to, + sides=sides, + scale_by_freq=scale_by_freq, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.contour) +def contour(*args, data=None, **kwargs) -> QuadContourSet: + __ret = gca().contour( + *args, **({"data": data} if data is not None else {}), **kwargs + ) + if __ret._A is not None: # type: ignore[attr-defined] + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.contourf) +def contourf(*args, data=None, **kwargs) -> QuadContourSet: + __ret = gca().contourf( + *args, **({"data": data} if data is not None else {}), **kwargs + ) + if __ret._A is not None: # type: ignore[attr-defined] + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.csd) +def csd( + x: ArrayLike, + y: ArrayLike, + NFFT: int | None = None, + Fs: float | None = None, + Fc: int | None = None, + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike], ArrayLike] + | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + noverlap: int | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + scale_by_freq: bool | None = None, + return_line: bool | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]: + return gca().csd( + x, + y, + NFFT=NFFT, + Fs=Fs, + Fc=Fc, + detrend=detrend, + window=window, + noverlap=noverlap, + pad_to=pad_to, + sides=sides, + scale_by_freq=scale_by_freq, + return_line=return_line, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.ecdf) +def ecdf( + x: ArrayLike, + weights: ArrayLike | None = None, + *, + complementary: bool = False, + orientation: Literal["vertical", "horizonatal"] = "vertical", + compress: bool = False, + data=None, + **kwargs, +) -> Line2D: + return gca().ecdf( + x, + weights=weights, + complementary=complementary, + orientation=orientation, + compress=compress, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.errorbar) +def errorbar( + x: float | ArrayLike, + y: float | ArrayLike, + yerr: float | ArrayLike | None = None, + xerr: float | ArrayLike | None = None, + fmt: str = "", + ecolor: ColorType | None = None, + elinewidth: float | None = None, + capsize: float | None = None, + barsabove: bool = False, + lolims: bool | ArrayLike = False, + uplims: bool | ArrayLike = False, + xlolims: bool | ArrayLike = False, + xuplims: bool | ArrayLike = False, + errorevery: int | tuple[int, int] = 1, + capthick: float | None = None, + *, + data=None, + **kwargs, +) -> ErrorbarContainer: + return gca().errorbar( + x, + y, + yerr=yerr, + xerr=xerr, + fmt=fmt, + ecolor=ecolor, + elinewidth=elinewidth, + capsize=capsize, + barsabove=barsabove, + lolims=lolims, + uplims=uplims, + xlolims=xlolims, + xuplims=xuplims, + errorevery=errorevery, + capthick=capthick, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.eventplot) +def eventplot( + positions: ArrayLike | Sequence[ArrayLike], + orientation: Literal["horizontal", "vertical"] = "horizontal", + lineoffsets: float | Sequence[float] = 1, + linelengths: float | Sequence[float] = 1, + linewidths: float | Sequence[float] | None = None, + colors: ColorType | Sequence[ColorType] | None = None, + alpha: float | Sequence[float] | None = None, + linestyles: LineStyleType | Sequence[LineStyleType] = "solid", + *, + data=None, + **kwargs, +) -> EventCollection: + return gca().eventplot( + positions, + orientation=orientation, + lineoffsets=lineoffsets, + linelengths=linelengths, + linewidths=linewidths, + colors=colors, + alpha=alpha, + linestyles=linestyles, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.fill) +def fill(*args, data=None, **kwargs) -> list[Polygon]: + return gca().fill(*args, **({"data": data} if data is not None else {}), **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.fill_between) +def fill_between( + x: ArrayLike, + y1: ArrayLike | float, + y2: ArrayLike | float = 0, + where: Sequence[bool] | None = None, + interpolate: bool = False, + step: Literal["pre", "post", "mid"] | None = None, + *, + data=None, + **kwargs, +) -> PolyCollection: + return gca().fill_between( + x, + y1, + y2=y2, + where=where, + interpolate=interpolate, + step=step, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.fill_betweenx) +def fill_betweenx( + y: ArrayLike, + x1: ArrayLike | float, + x2: ArrayLike | float = 0, + where: Sequence[bool] | None = None, + step: Literal["pre", "post", "mid"] | None = None, + interpolate: bool = False, + *, + data=None, + **kwargs, +) -> PolyCollection: + return gca().fill_betweenx( + y, + x1, + x2=x2, + where=where, + step=step, + interpolate=interpolate, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.grid) +def grid( + visible: bool | None = None, + which: Literal["major", "minor", "both"] = "major", + axis: Literal["both", "x", "y"] = "both", + **kwargs, +) -> None: + gca().grid(visible=visible, which=which, axis=axis, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.hexbin) +def hexbin( + x: ArrayLike, + y: ArrayLike, + C: ArrayLike | None = None, + gridsize: int | tuple[int, int] = 100, + bins: Literal["log"] | int | Sequence[float] | None = None, + xscale: Literal["linear", "log"] = "linear", + yscale: Literal["linear", "log"] = "linear", + extent: tuple[float, float, float, float] | None = None, + cmap: str | Colormap | None = None, + norm: str | Normalize | None = None, + vmin: float | None = None, + vmax: float | None = None, + alpha: float | None = None, + linewidths: float | None = None, + edgecolors: Literal["face", "none"] | ColorType = "face", + reduce_C_function: Callable[[np.ndarray | list[float]], float] = np.mean, + mincnt: int | None = None, + marginals: bool = False, + *, + data=None, + **kwargs, +) -> PolyCollection: + __ret = gca().hexbin( + x, + y, + C=C, + gridsize=gridsize, + bins=bins, + xscale=xscale, + yscale=yscale, + extent=extent, + cmap=cmap, + norm=norm, + vmin=vmin, + vmax=vmax, + alpha=alpha, + linewidths=linewidths, + edgecolors=edgecolors, + reduce_C_function=reduce_C_function, + mincnt=mincnt, + marginals=marginals, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.hist) +def hist( + x: ArrayLike | Sequence[ArrayLike], + bins: int | Sequence[float] | str | None = None, + range: tuple[float, float] | None = None, + density: bool = False, + weights: ArrayLike | None = None, + cumulative: bool | float = False, + bottom: ArrayLike | float | None = None, + histtype: Literal["bar", "barstacked", "step", "stepfilled"] = "bar", + align: Literal["left", "mid", "right"] = "mid", + orientation: Literal["vertical", "horizontal"] = "vertical", + rwidth: float | None = None, + log: bool = False, + color: ColorType | Sequence[ColorType] | None = None, + label: str | Sequence[str] | None = None, + stacked: bool = False, + *, + data=None, + **kwargs, +) -> tuple[ + np.ndarray | list[np.ndarray], + np.ndarray, + BarContainer | Polygon | list[BarContainer | Polygon], +]: + return gca().hist( + x, + bins=bins, + range=range, + density=density, + weights=weights, + cumulative=cumulative, + bottom=bottom, + histtype=histtype, + align=align, + orientation=orientation, + rwidth=rwidth, + log=log, + color=color, + label=label, + stacked=stacked, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.stairs) +def stairs( + values: ArrayLike, + edges: ArrayLike | None = None, + *, + orientation: Literal["vertical", "horizontal"] = "vertical", + baseline: float | ArrayLike | None = 0, + fill: bool = False, + data=None, + **kwargs, +) -> StepPatch: + return gca().stairs( + values, + edges=edges, + orientation=orientation, + baseline=baseline, + fill=fill, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.hist2d) +def hist2d( + x: ArrayLike, + y: ArrayLike, + bins: None | int | tuple[int, int] | ArrayLike | tuple[ArrayLike, ArrayLike] = 10, + range: ArrayLike | None = None, + density: bool = False, + weights: ArrayLike | None = None, + cmin: float | None = None, + cmax: float | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, np.ndarray, QuadMesh]: + __ret = gca().hist2d( + x, + y, + bins=bins, + range=range, + density=density, + weights=weights, + cmin=cmin, + cmax=cmax, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret[-1]) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.hlines) +def hlines( + y: float | ArrayLike, + xmin: float | ArrayLike, + xmax: float | ArrayLike, + colors: ColorType | Sequence[ColorType] | None = None, + linestyles: LineStyleType = "solid", + label: str = "", + *, + data=None, + **kwargs, +) -> LineCollection: + return gca().hlines( + y, + xmin, + xmax, + colors=colors, + linestyles=linestyles, + label=label, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.imshow) +def imshow( + X: ArrayLike | PIL.Image.Image, + cmap: str | Colormap | None = None, + norm: str | Normalize | None = None, + *, + aspect: Literal["equal", "auto"] | float | None = None, + interpolation: str | None = None, + alpha: float | ArrayLike | None = None, + vmin: float | None = None, + vmax: float | None = None, + origin: Literal["upper", "lower"] | None = None, + extent: tuple[float, float, float, float] | None = None, + interpolation_stage: Literal["data", "rgba"] | None = None, + filternorm: bool = True, + filterrad: float = 4.0, + resample: bool | None = None, + url: str | None = None, + data=None, + **kwargs, +) -> AxesImage: + __ret = gca().imshow( + X, + cmap=cmap, + norm=norm, + aspect=aspect, + interpolation=interpolation, + alpha=alpha, + vmin=vmin, + vmax=vmax, + origin=origin, + extent=extent, + interpolation_stage=interpolation_stage, + filternorm=filternorm, + filterrad=filterrad, + resample=resample, + url=url, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.legend) +def legend(*args, **kwargs) -> Legend: + return gca().legend(*args, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.locator_params) +def locator_params( + axis: Literal["both", "x", "y"] = "both", tight: bool | None = None, **kwargs +) -> None: + gca().locator_params(axis=axis, tight=tight, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.loglog) +def loglog(*args, **kwargs) -> list[Line2D]: + return gca().loglog(*args, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.magnitude_spectrum) +def magnitude_spectrum( + x: ArrayLike, + Fs: float | None = None, + Fc: int | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + scale: Literal["default", "linear", "dB"] | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, Line2D]: + return gca().magnitude_spectrum( + x, + Fs=Fs, + Fc=Fc, + window=window, + pad_to=pad_to, + sides=sides, + scale=scale, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.margins) +def margins( + *margins: float, + x: float | None = None, + y: float | None = None, + tight: bool | None = True, +) -> tuple[float, float] | None: + return gca().margins(*margins, x=x, y=y, tight=tight) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.minorticks_off) +def minorticks_off() -> None: + gca().minorticks_off() + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.minorticks_on) +def minorticks_on() -> None: + gca().minorticks_on() + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.pcolor) +def pcolor( + *args: ArrayLike, + shading: Literal["flat", "nearest", "auto"] | None = None, + alpha: float | None = None, + norm: str | Normalize | None = None, + cmap: str | Colormap | None = None, + vmin: float | None = None, + vmax: float | None = None, + data=None, + **kwargs, +) -> Collection: + __ret = gca().pcolor( + *args, + shading=shading, + alpha=alpha, + norm=norm, + cmap=cmap, + vmin=vmin, + vmax=vmax, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.pcolormesh) +def pcolormesh( + *args: ArrayLike, + alpha: float | None = None, + norm: str | Normalize | None = None, + cmap: str | Colormap | None = None, + vmin: float | None = None, + vmax: float | None = None, + shading: Literal["flat", "nearest", "gouraud", "auto"] | None = None, + antialiased: bool = False, + data=None, + **kwargs, +) -> QuadMesh: + __ret = gca().pcolormesh( + *args, + alpha=alpha, + norm=norm, + cmap=cmap, + vmin=vmin, + vmax=vmax, + shading=shading, + antialiased=antialiased, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.phase_spectrum) +def phase_spectrum( + x: ArrayLike, + Fs: float | None = None, + Fc: int | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, Line2D]: + return gca().phase_spectrum( + x, + Fs=Fs, + Fc=Fc, + window=window, + pad_to=pad_to, + sides=sides, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.pie) +def pie( + x: ArrayLike, + explode: ArrayLike | None = None, + labels: Sequence[str] | None = None, + colors: ColorType | Sequence[ColorType] | None = None, + autopct: str | Callable[[float], str] | None = None, + pctdistance: float = 0.6, + shadow: bool = False, + labeldistance: float | None = 1.1, + startangle: float = 0, + radius: float = 1, + counterclock: bool = True, + wedgeprops: dict[str, Any] | None = None, + textprops: dict[str, Any] | None = None, + center: tuple[float, float] = (0, 0), + frame: bool = False, + rotatelabels: bool = False, + *, + normalize: bool = True, + hatch: str | Sequence[str] | None = None, + data=None, +) -> tuple[list[Wedge], list[Text]] | tuple[list[Wedge], list[Text], list[Text]]: + return gca().pie( + x, + explode=explode, + labels=labels, + colors=colors, + autopct=autopct, + pctdistance=pctdistance, + shadow=shadow, + labeldistance=labeldistance, + startangle=startangle, + radius=radius, + counterclock=counterclock, + wedgeprops=wedgeprops, + textprops=textprops, + center=center, + frame=frame, + rotatelabels=rotatelabels, + normalize=normalize, + hatch=hatch, + **({"data": data} if data is not None else {}), + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.plot) +def plot( + *args: float | ArrayLike | str, + scalex: bool = True, + scaley: bool = True, + data=None, + **kwargs, +) -> list[Line2D]: + return gca().plot( + *args, + scalex=scalex, + scaley=scaley, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.plot_date) +def plot_date( + x: ArrayLike, + y: ArrayLike, + fmt: str = "o", + tz: str | datetime.tzinfo | None = None, + xdate: bool = True, + ydate: bool = False, + *, + data=None, + **kwargs, +) -> list[Line2D]: + return gca().plot_date( + x, + y, + fmt=fmt, + tz=tz, + xdate=xdate, + ydate=ydate, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.psd) +def psd( + x: ArrayLike, + NFFT: int | None = None, + Fs: float | None = None, + Fc: int | None = None, + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike], ArrayLike] + | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + noverlap: int | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + scale_by_freq: bool | None = None, + return_line: bool | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]: + return gca().psd( + x, + NFFT=NFFT, + Fs=Fs, + Fc=Fc, + detrend=detrend, + window=window, + noverlap=noverlap, + pad_to=pad_to, + sides=sides, + scale_by_freq=scale_by_freq, + return_line=return_line, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.quiver) +def quiver(*args, data=None, **kwargs) -> Quiver: + __ret = gca().quiver( + *args, **({"data": data} if data is not None else {}), **kwargs + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.quiverkey) +def quiverkey( + Q: Quiver, X: float, Y: float, U: float, label: str, **kwargs +) -> QuiverKey: + return gca().quiverkey(Q, X, Y, U, label, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.scatter) +def scatter( + x: float | ArrayLike, + y: float | ArrayLike, + s: float | ArrayLike | None = None, + c: ArrayLike | Sequence[ColorType] | ColorType | None = None, + marker: MarkerType | None = None, + cmap: str | Colormap | None = None, + norm: str | Normalize | None = None, + vmin: float | None = None, + vmax: float | None = None, + alpha: float | None = None, + linewidths: float | Sequence[float] | None = None, + *, + edgecolors: Literal["face", "none"] | ColorType | Sequence[ColorType] | None = None, + plotnonfinite: bool = False, + data=None, + **kwargs, +) -> PathCollection: + __ret = gca().scatter( + x, + y, + s=s, + c=c, + marker=marker, + cmap=cmap, + norm=norm, + vmin=vmin, + vmax=vmax, + alpha=alpha, + linewidths=linewidths, + edgecolors=edgecolors, + plotnonfinite=plotnonfinite, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.semilogx) +def semilogx(*args, **kwargs) -> list[Line2D]: + return gca().semilogx(*args, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.semilogy) +def semilogy(*args, **kwargs) -> list[Line2D]: + return gca().semilogy(*args, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.specgram) +def specgram( + x: ArrayLike, + NFFT: int | None = None, + Fs: float | None = None, + Fc: int | None = None, + detrend: Literal["none", "mean", "linear"] + | Callable[[ArrayLike], ArrayLike] + | None = None, + window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None, + noverlap: int | None = None, + cmap: str | Colormap | None = None, + xextent: tuple[float, float] | None = None, + pad_to: int | None = None, + sides: Literal["default", "onesided", "twosided"] | None = None, + scale_by_freq: bool | None = None, + mode: Literal["default", "psd", "magnitude", "angle", "phase"] | None = None, + scale: Literal["default", "linear", "dB"] | None = None, + vmin: float | None = None, + vmax: float | None = None, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, np.ndarray, AxesImage]: + __ret = gca().specgram( + x, + NFFT=NFFT, + Fs=Fs, + Fc=Fc, + detrend=detrend, + window=window, + noverlap=noverlap, + cmap=cmap, + xextent=xextent, + pad_to=pad_to, + sides=sides, + scale_by_freq=scale_by_freq, + mode=mode, + scale=scale, + vmin=vmin, + vmax=vmax, + **({"data": data} if data is not None else {}), + **kwargs, + ) + sci(__ret[-1]) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.spy) +def spy( + Z: ArrayLike, + precision: float | Literal["present"] = 0, + marker: str | None = None, + markersize: float | None = None, + aspect: Literal["equal", "auto"] | float | None = "equal", + origin: Literal["upper", "lower"] = "upper", + **kwargs, +) -> AxesImage: + __ret = gca().spy( + Z, + precision=precision, + marker=marker, + markersize=markersize, + aspect=aspect, + origin=origin, + **kwargs, + ) + if isinstance(__ret, cm.ScalarMappable): + sci(__ret) # noqa + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.stackplot) +def stackplot(x, *args, labels=(), colors=None, baseline="zero", data=None, **kwargs): + return gca().stackplot( + x, + *args, + labels=labels, + colors=colors, + baseline=baseline, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.stem) +def stem( + *args: ArrayLike | str, + linefmt: str | None = None, + markerfmt: str | None = None, + basefmt: str | None = None, + bottom: float = 0, + label: str | None = None, + orientation: Literal["vertical", "horizontal"] = "vertical", + data=None, +) -> StemContainer: + return gca().stem( + *args, + linefmt=linefmt, + markerfmt=markerfmt, + basefmt=basefmt, + bottom=bottom, + label=label, + orientation=orientation, + **({"data": data} if data is not None else {}), + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.step) +def step( + x: ArrayLike, + y: ArrayLike, + *args, + where: Literal["pre", "post", "mid"] = "pre", + data=None, + **kwargs, +) -> list[Line2D]: + return gca().step( + x, + y, + *args, + where=where, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.streamplot) +def streamplot( + x, + y, + u, + v, + density=1, + linewidth=None, + color=None, + cmap=None, + norm=None, + arrowsize=1, + arrowstyle="-|>", + minlength=0.1, + transform=None, + zorder=None, + start_points=None, + maxlength=4.0, + integration_direction="both", + broken_streamlines=True, + *, + data=None, +): + __ret = gca().streamplot( + x, + y, + u, + v, + density=density, + linewidth=linewidth, + color=color, + cmap=cmap, + norm=norm, + arrowsize=arrowsize, + arrowstyle=arrowstyle, + minlength=minlength, + transform=transform, + zorder=zorder, + start_points=start_points, + maxlength=maxlength, + integration_direction=integration_direction, + broken_streamlines=broken_streamlines, + **({"data": data} if data is not None else {}), + ) + sci(__ret.lines) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.table) +def table( + cellText=None, + cellColours=None, + cellLoc="right", + colWidths=None, + rowLabels=None, + rowColours=None, + rowLoc="left", + colLabels=None, + colColours=None, + colLoc="center", + loc="bottom", + bbox=None, + edges="closed", + **kwargs, +): + return gca().table( + cellText=cellText, + cellColours=cellColours, + cellLoc=cellLoc, + colWidths=colWidths, + rowLabels=rowLabels, + rowColours=rowColours, + rowLoc=rowLoc, + colLabels=colLabels, + colColours=colColours, + colLoc=colLoc, + loc=loc, + bbox=bbox, + edges=edges, + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.text) +def text( + x: float, y: float, s: str, fontdict: dict[str, Any] | None = None, **kwargs +) -> Text: + return gca().text(x, y, s, fontdict=fontdict, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.tick_params) +def tick_params(axis: Literal["both", "x", "y"] = "both", **kwargs) -> None: + gca().tick_params(axis=axis, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.ticklabel_format) +def ticklabel_format( + *, + axis: Literal["both", "x", "y"] = "both", + style: Literal["", "sci", "scientific", "plain"] = "", + scilimits: tuple[int, int] | None = None, + useOffset: bool | float | None = None, + useLocale: bool | None = None, + useMathText: bool | None = None, +) -> None: + gca().ticklabel_format( + axis=axis, + style=style, + scilimits=scilimits, + useOffset=useOffset, + useLocale=useLocale, + useMathText=useMathText, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.tricontour) +def tricontour(*args, **kwargs): + __ret = gca().tricontour(*args, **kwargs) + if __ret._A is not None: # type: ignore[attr-defined] + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.tricontourf) +def tricontourf(*args, **kwargs): + __ret = gca().tricontourf(*args, **kwargs) + if __ret._A is not None: # type: ignore[attr-defined] + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.tripcolor) +def tripcolor( + *args, + alpha=1.0, + norm=None, + cmap=None, + vmin=None, + vmax=None, + shading="flat", + facecolors=None, + **kwargs, +): + __ret = gca().tripcolor( + *args, + alpha=alpha, + norm=norm, + cmap=cmap, + vmin=vmin, + vmax=vmax, + shading=shading, + facecolors=facecolors, + **kwargs, + ) + sci(__ret) + return __ret + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.triplot) +def triplot(*args, **kwargs): + return gca().triplot(*args, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.violinplot) +def violinplot( + dataset: ArrayLike | Sequence[ArrayLike], + positions: ArrayLike | None = None, + vert: bool = True, + widths: float | ArrayLike = 0.5, + showmeans: bool = False, + showextrema: bool = True, + showmedians: bool = False, + quantiles: Sequence[float | Sequence[float]] | None = None, + points: int = 100, + bw_method: Literal["scott", "silverman"] + | float + | Callable[[GaussianKDE], float] + | None = None, + *, + data=None, +) -> dict[str, Collection]: + return gca().violinplot( + dataset, + positions=positions, + vert=vert, + widths=widths, + showmeans=showmeans, + showextrema=showextrema, + showmedians=showmedians, + quantiles=quantiles, + points=points, + bw_method=bw_method, + **({"data": data} if data is not None else {}), + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.vlines) +def vlines( + x: float | ArrayLike, + ymin: float | ArrayLike, + ymax: float | ArrayLike, + colors: ColorType | Sequence[ColorType] | None = None, + linestyles: LineStyleType = "solid", + label: str = "", + *, + data=None, + **kwargs, +) -> LineCollection: + return gca().vlines( + x, + ymin, + ymax, + colors=colors, + linestyles=linestyles, + label=label, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.xcorr) +def xcorr( + x: ArrayLike, + y: ArrayLike, + normed: bool = True, + detrend: Callable[[ArrayLike], ArrayLike] = mlab.detrend_none, + usevlines: bool = True, + maxlags: int = 10, + *, + data=None, + **kwargs, +) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]: + return gca().xcorr( + x, + y, + normed=normed, + detrend=detrend, + usevlines=usevlines, + maxlags=maxlags, + **({"data": data} if data is not None else {}), + **kwargs, + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes._sci) +def sci(im: ScalarMappable) -> None: + gca()._sci(im) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.set_title) +def title( + label: str, + fontdict: dict[str, Any] | None = None, + loc: Literal["left", "center", "right"] | None = None, + pad: float | None = None, + *, + y: float | None = None, + **kwargs, +) -> Text: + return gca().set_title(label, fontdict=fontdict, loc=loc, pad=pad, y=y, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.set_xlabel) +def xlabel( + xlabel: str, + fontdict: dict[str, Any] | None = None, + labelpad: float | None = None, + *, + loc: Literal["left", "center", "right"] | None = None, + **kwargs, +) -> Text: + return gca().set_xlabel( + xlabel, fontdict=fontdict, labelpad=labelpad, loc=loc, **kwargs + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.set_ylabel) +def ylabel( + ylabel: str, + fontdict: dict[str, Any] | None = None, + labelpad: float | None = None, + *, + loc: Literal["bottom", "center", "top"] | None = None, + **kwargs, +) -> Text: + return gca().set_ylabel( + ylabel, fontdict=fontdict, labelpad=labelpad, loc=loc, **kwargs + ) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.set_xscale) +def xscale(value: str | ScaleBase, **kwargs) -> None: + gca().set_xscale(value, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +@_copy_docstring_and_deprecators(Axes.set_yscale) +def yscale(value: str | ScaleBase, **kwargs) -> None: + gca().set_yscale(value, **kwargs) + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def autumn() -> None: + """ + Set the colormap to 'autumn'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("autumn") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def bone() -> None: + """ + Set the colormap to 'bone'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("bone") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def cool() -> None: + """ + Set the colormap to 'cool'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("cool") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def copper() -> None: + """ + Set the colormap to 'copper'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("copper") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def flag() -> None: + """ + Set the colormap to 'flag'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("flag") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def gray() -> None: + """ + Set the colormap to 'gray'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("gray") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def hot() -> None: + """ + Set the colormap to 'hot'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("hot") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def hsv() -> None: + """ + Set the colormap to 'hsv'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("hsv") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def jet() -> None: + """ + Set the colormap to 'jet'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("jet") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def pink() -> None: + """ + Set the colormap to 'pink'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("pink") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def prism() -> None: + """ + Set the colormap to 'prism'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("prism") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def spring() -> None: + """ + Set the colormap to 'spring'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("spring") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def summer() -> None: + """ + Set the colormap to 'summer'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("summer") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def winter() -> None: + """ + Set the colormap to 'winter'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("winter") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def magma() -> None: + """ + Set the colormap to 'magma'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("magma") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def inferno() -> None: + """ + Set the colormap to 'inferno'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("inferno") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def plasma() -> None: + """ + Set the colormap to 'plasma'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("plasma") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def viridis() -> None: + """ + Set the colormap to 'viridis'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("viridis") + + +# Autogenerated by boilerplate.py. Do not edit as changes will be lost. +def nipy_spectral() -> None: + """ + Set the colormap to 'nipy_spectral'. + + This changes the default colormap as well as the colormap of the current + image if there is one. See ``help(colormaps)`` for more information. + """ + set_cmap("nipy_spectral") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.py new file mode 100644 index 00000000..c8f8ba56 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.py @@ -0,0 +1,1181 @@ +""" +Support for plotting vector fields. + +Presently this contains Quiver and Barb. Quiver plots an arrow in the +direction of the vector, with the size of the arrow related to the +magnitude of the vector. + +Barbs are like quiver in that they point along a vector, but +the magnitude of the vector is given schematically by the presence of barbs +or flags on the barb. + +This will also become a home for things such as standard +deviation ellipses, which can and will be derived very easily from +the Quiver code. +""" + +import math + +import numpy as np +from numpy import ma + +from matplotlib import _api, cbook, _docstring +import matplotlib.artist as martist +import matplotlib.collections as mcollections +from matplotlib.patches import CirclePolygon +import matplotlib.text as mtext +import matplotlib.transforms as transforms + + +_quiver_doc = """ +Plot a 2D field of arrows. + +Call signature:: + + quiver([X, Y], U, V, [C], **kwargs) + +*X*, *Y* define the arrow locations, *U*, *V* define the arrow directions, and +*C* optionally sets the color. + +**Arrow length** + +The default settings auto-scales the length of the arrows to a reasonable size. +To change this behavior see the *scale* and *scale_units* parameters. + +**Arrow shape** + +The arrow shape is determined by *width*, *headwidth*, *headlength* and +*headaxislength*. See the notes below. + +**Arrow styling** + +Each arrow is internally represented by a filled polygon with a default edge +linewidth of 0. As a result, an arrow is rather a filled area, not a line with +a head, and `.PolyCollection` properties like *linewidth*, *edgecolor*, +*facecolor*, etc. act accordingly. + + +Parameters +---------- +X, Y : 1D or 2D array-like, optional + The x and y coordinates of the arrow locations. + + If not given, they will be generated as a uniform integer meshgrid based + on the dimensions of *U* and *V*. + + If *X* and *Y* are 1D but *U*, *V* are 2D, *X*, *Y* are expanded to 2D + using ``X, Y = np.meshgrid(X, Y)``. In this case ``len(X)`` and ``len(Y)`` + must match the column and row dimensions of *U* and *V*. + +U, V : 1D or 2D array-like + The x and y direction components of the arrow vectors. The interpretation + of these components (in data or in screen space) depends on *angles*. + + *U* and *V* must have the same number of elements, matching the number of + arrow locations in *X*, *Y*. *U* and *V* may be masked. Locations masked + in any of *U*, *V*, and *C* will not be drawn. + +C : 1D or 2D array-like, optional + Numeric data that defines the arrow colors by colormapping via *norm* and + *cmap*. + + This does not support explicit colors. If you want to set colors directly, + use *color* instead. The size of *C* must match the number of arrow + locations. + +angles : {'uv', 'xy'} or array-like, default: 'uv' + Method for determining the angle of the arrows. + + - 'uv': Arrow direction in screen coordinates. Use this if the arrows + symbolize a quantity that is not based on *X*, *Y* data coordinates. + + If *U* == *V* the orientation of the arrow on the plot is 45 degrees + counter-clockwise from the horizontal axis (positive to the right). + + - 'xy': Arrow direction in data coordinates, i.e. the arrows point from + (x, y) to (x+u, y+v). Use this e.g. for plotting a gradient field. + + - Arbitrary angles may be specified explicitly as an array of values + in degrees, counter-clockwise from the horizontal axis. + + In this case *U*, *V* is only used to determine the length of the + arrows. + + Note: inverting a data axis will correspondingly invert the + arrows only with ``angles='xy'``. + +pivot : {'tail', 'mid', 'middle', 'tip'}, default: 'tail' + The part of the arrow that is anchored to the *X*, *Y* grid. The arrow + rotates about this point. + + 'mid' is a synonym for 'middle'. + +scale : float, optional + Scales the length of the arrow inversely. + + Number of data units per arrow length unit, e.g., m/s per plot width; a + smaller scale parameter makes the arrow longer. Default is *None*. + + If *None*, a simple autoscaling algorithm is used, based on the average + vector length and the number of vectors. The arrow length unit is given by + the *scale_units* parameter. + +scale_units : {'width', 'height', 'dots', 'inches', 'x', 'y', 'xy'}, optional + If the *scale* kwarg is *None*, the arrow length unit. Default is *None*. + + e.g. *scale_units* is 'inches', *scale* is 2.0, and ``(u, v) = (1, 0)``, + then the vector will be 0.5 inches long. + + If *scale_units* is 'width' or 'height', then the vector will be half the + width/height of the axes. + + If *scale_units* is 'x' then the vector will be 0.5 x-axis + units. To plot vectors in the x-y plane, with u and v having + the same units as x and y, use + ``angles='xy', scale_units='xy', scale=1``. + +units : {'width', 'height', 'dots', 'inches', 'x', 'y', 'xy'}, default: 'width' + Affects the arrow size (except for the length). In particular, the shaft + *width* is measured in multiples of this unit. + + Supported values are: + + - 'width', 'height': The width or height of the Axes. + - 'dots', 'inches': Pixels or inches based on the figure dpi. + - 'x', 'y', 'xy': *X*, *Y* or :math:`\\sqrt{X^2 + Y^2}` in data units. + + The following table summarizes how these values affect the visible arrow + size under zooming and figure size changes: + + ================= ================= ================== + units zoom figure size change + ================= ================= ================== + 'x', 'y', 'xy' arrow size scales — + 'width', 'height' — arrow size scales + 'dots', 'inches' — — + ================= ================= ================== + +width : float, optional + Shaft width in arrow units. All head parameters are relative to *width*. + + The default depends on choice of *units* above, and number of vectors; + a typical starting value is about 0.005 times the width of the plot. + +headwidth : float, default: 3 + Head width as multiple of shaft *width*. See the notes below. + +headlength : float, default: 5 + Head length as multiple of shaft *width*. See the notes below. + +headaxislength : float, default: 4.5 + Head length at shaft intersection as multiple of shaft *width*. + See the notes below. + +minshaft : float, default: 1 + Length below which arrow scales, in units of head length. Do not + set this to less than 1, or small arrows will look terrible! + +minlength : float, default: 1 + Minimum length as a multiple of shaft width; if an arrow length + is less than this, plot a dot (hexagon) of this diameter instead. + +color : color or color sequence, optional + Explicit color(s) for the arrows. If *C* has been set, *color* has no + effect. + + This is a synonym for the `.PolyCollection` *facecolor* parameter. + +Other Parameters +---------------- +data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + +**kwargs : `~matplotlib.collections.PolyCollection` properties, optional + All other keyword arguments are passed on to `.PolyCollection`: + + %(PolyCollection:kwdoc)s + +Returns +------- +`~matplotlib.quiver.Quiver` + +See Also +-------- +.Axes.quiverkey : Add a key to a quiver plot. + +Notes +----- + +**Arrow shape** + +The arrow is drawn as a polygon using the nodes as shown below. The values +*headwidth*, *headlength*, and *headaxislength* are in units of *width*. + +.. image:: /_static/quiver_sizes.svg + :width: 500px + +The defaults give a slightly swept-back arrow. Here are some guidelines how to +get other head shapes: + +- To make the head a triangle, make *headaxislength* the same as *headlength*. +- To make the arrow more pointed, reduce *headwidth* or increase *headlength* + and *headaxislength*. +- To make the head smaller relative to the shaft, scale down all the head + parameters proportionally. +- To remove the head completely, set all *head* parameters to 0. +- To get a diamond-shaped head, make *headaxislength* larger than *headlength*. +- Warning: For *headaxislength* < (*headlength* / *headwidth*), the "headaxis" + nodes (i.e. the ones connecting the head with the shaft) will protrude out + of the head in forward direction so that the arrow head looks broken. +""" % _docstring.interpd.params + +_docstring.interpd.update(quiver_doc=_quiver_doc) + + +class QuiverKey(martist.Artist): + """Labelled arrow for use as a quiver plot scale key.""" + halign = {'N': 'center', 'S': 'center', 'E': 'left', 'W': 'right'} + valign = {'N': 'bottom', 'S': 'top', 'E': 'center', 'W': 'center'} + pivot = {'N': 'middle', 'S': 'middle', 'E': 'tip', 'W': 'tail'} + + def __init__(self, Q, X, Y, U, label, + *, angle=0, coordinates='axes', color=None, labelsep=0.1, + labelpos='N', labelcolor=None, fontproperties=None, **kwargs): + """ + Add a key to a quiver plot. + + The positioning of the key depends on *X*, *Y*, *coordinates*, and + *labelpos*. If *labelpos* is 'N' or 'S', *X*, *Y* give the position of + the middle of the key arrow. If *labelpos* is 'E', *X*, *Y* positions + the head, and if *labelpos* is 'W', *X*, *Y* positions the tail; in + either of these two cases, *X*, *Y* is somewhere in the middle of the + arrow+label key object. + + Parameters + ---------- + Q : `~matplotlib.quiver.Quiver` + A `.Quiver` object as returned by a call to `~.Axes.quiver()`. + X, Y : float + The location of the key. + U : float + The length of the key. + label : str + The key label (e.g., length and units of the key). + angle : float, default: 0 + The angle of the key arrow, in degrees anti-clockwise from the + x-axis. + coordinates : {'axes', 'figure', 'data', 'inches'}, default: 'axes' + Coordinate system and units for *X*, *Y*: 'axes' and 'figure' are + normalized coordinate systems with (0, 0) in the lower left and + (1, 1) in the upper right; 'data' are the axes data coordinates + (used for the locations of the vectors in the quiver plot itself); + 'inches' is position in the figure in inches, with (0, 0) at the + lower left corner. + color : color + Overrides face and edge colors from *Q*. + labelpos : {'N', 'S', 'E', 'W'} + Position the label above, below, to the right, to the left of the + arrow, respectively. + labelsep : float, default: 0.1 + Distance in inches between the arrow and the label. + labelcolor : color, default: :rc:`text.color` + Label color. + fontproperties : dict, optional + A dictionary with keyword arguments accepted by the + `~matplotlib.font_manager.FontProperties` initializer: + *family*, *style*, *variant*, *size*, *weight*. + **kwargs + Any additional keyword arguments are used to override vector + properties taken from *Q*. + """ + super().__init__() + self.Q = Q + self.X = X + self.Y = Y + self.U = U + self.angle = angle + self.coord = coordinates + self.color = color + self.label = label + self._labelsep_inches = labelsep + + self.labelpos = labelpos + self.labelcolor = labelcolor + self.fontproperties = fontproperties or dict() + self.kw = kwargs + self.text = mtext.Text( + text=label, + horizontalalignment=self.halign[self.labelpos], + verticalalignment=self.valign[self.labelpos], + fontproperties=self.fontproperties) + if self.labelcolor is not None: + self.text.set_color(self.labelcolor) + self._dpi_at_last_init = None + self.zorder = Q.zorder + 0.1 + + @property + def labelsep(self): + return self._labelsep_inches * self.Q.axes.figure.dpi + + def _init(self): + if True: # self._dpi_at_last_init != self.axes.figure.dpi + if self.Q._dpi_at_last_init != self.Q.axes.figure.dpi: + self.Q._init() + self._set_transform() + with cbook._setattr_cm(self.Q, pivot=self.pivot[self.labelpos], + # Hack: save and restore the Umask + Umask=ma.nomask): + u = self.U * np.cos(np.radians(self.angle)) + v = self.U * np.sin(np.radians(self.angle)) + angle = (self.Q.angles if isinstance(self.Q.angles, str) + else 'uv') + self.verts = self.Q._make_verts( + np.array([u]), np.array([v]), angle) + kwargs = self.Q.polykw + kwargs.update(self.kw) + self.vector = mcollections.PolyCollection( + self.verts, + offsets=[(self.X, self.Y)], + offset_transform=self.get_transform(), + **kwargs) + if self.color is not None: + self.vector.set_color(self.color) + self.vector.set_transform(self.Q.get_transform()) + self.vector.set_figure(self.get_figure()) + self._dpi_at_last_init = self.Q.axes.figure.dpi + + def _text_shift(self): + return { + "N": (0, +self.labelsep), + "S": (0, -self.labelsep), + "E": (+self.labelsep, 0), + "W": (-self.labelsep, 0), + }[self.labelpos] + + @martist.allow_rasterization + def draw(self, renderer): + self._init() + self.vector.draw(renderer) + pos = self.get_transform().transform((self.X, self.Y)) + self.text.set_position(pos + self._text_shift()) + self.text.draw(renderer) + self.stale = False + + def _set_transform(self): + self.set_transform(_api.check_getitem({ + "data": self.Q.axes.transData, + "axes": self.Q.axes.transAxes, + "figure": self.Q.axes.figure.transFigure, + "inches": self.Q.axes.figure.dpi_scale_trans, + }, coordinates=self.coord)) + + def set_figure(self, fig): + super().set_figure(fig) + self.text.set_figure(fig) + + def contains(self, mouseevent): + if self._different_canvas(mouseevent): + return False, {} + # Maybe the dictionary should allow one to + # distinguish between a text hit and a vector hit. + if (self.text.contains(mouseevent)[0] or + self.vector.contains(mouseevent)[0]): + return True, {} + return False, {} + + +def _parse_args(*args, caller_name='function'): + """ + Helper function to parse positional parameters for colored vector plots. + + This is currently used for Quiver and Barbs. + + Parameters + ---------- + *args : list + list of 2-5 arguments. Depending on their number they are parsed to:: + + U, V + U, V, C + X, Y, U, V + X, Y, U, V, C + + caller_name : str + Name of the calling method (used in error messages). + """ + X = Y = C = None + + nargs = len(args) + if nargs == 2: + # The use of atleast_1d allows for handling scalar arguments while also + # keeping masked arrays + U, V = np.atleast_1d(*args) + elif nargs == 3: + U, V, C = np.atleast_1d(*args) + elif nargs == 4: + X, Y, U, V = np.atleast_1d(*args) + elif nargs == 5: + X, Y, U, V, C = np.atleast_1d(*args) + else: + raise _api.nargs_error(caller_name, takes="from 2 to 5", given=nargs) + + nr, nc = (1, U.shape[0]) if U.ndim == 1 else U.shape + + if X is not None: + X = X.ravel() + Y = Y.ravel() + if len(X) == nc and len(Y) == nr: + X, Y = [a.ravel() for a in np.meshgrid(X, Y)] + elif len(X) != len(Y): + raise ValueError('X and Y must be the same size, but ' + f'X.size is {X.size} and Y.size is {Y.size}.') + else: + indexgrid = np.meshgrid(np.arange(nc), np.arange(nr)) + X, Y = [np.ravel(a) for a in indexgrid] + # Size validation for U, V, C is left to the set_UVC method. + return X, Y, U, V, C + + +def _check_consistent_shapes(*arrays): + all_shapes = {a.shape for a in arrays} + if len(all_shapes) != 1: + raise ValueError('The shapes of the passed in arrays do not match') + + +class Quiver(mcollections.PolyCollection): + """ + Specialized PolyCollection for arrows. + + The only API method is set_UVC(), which can be used + to change the size, orientation, and color of the + arrows; their locations are fixed when the class is + instantiated. Possibly this method will be useful + in animations. + + Much of the work in this class is done in the draw() + method so that as much information as possible is available + about the plot. In subsequent draw() calls, recalculation + is limited to things that might have changed, so there + should be no performance penalty from putting the calculations + in the draw() method. + """ + + _PIVOT_VALS = ('tail', 'middle', 'tip') + + @_docstring.Substitution(_quiver_doc) + def __init__(self, ax, *args, + scale=None, headwidth=3, headlength=5, headaxislength=4.5, + minshaft=1, minlength=1, units='width', scale_units=None, + angles='uv', width=None, color='k', pivot='tail', **kwargs): + """ + The constructor takes one required argument, an Axes + instance, followed by the args and kwargs described + by the following pyplot interface documentation: + %s + """ + self._axes = ax # The attr actually set by the Artist.axes property. + X, Y, U, V, C = _parse_args(*args, caller_name='quiver') + self.X = X + self.Y = Y + self.XY = np.column_stack((X, Y)) + self.N = len(X) + self.scale = scale + self.headwidth = headwidth + self.headlength = float(headlength) + self.headaxislength = headaxislength + self.minshaft = minshaft + self.minlength = minlength + self.units = units + self.scale_units = scale_units + self.angles = angles + self.width = width + + if pivot.lower() == 'mid': + pivot = 'middle' + self.pivot = pivot.lower() + _api.check_in_list(self._PIVOT_VALS, pivot=self.pivot) + + self.transform = kwargs.pop('transform', ax.transData) + kwargs.setdefault('facecolors', color) + kwargs.setdefault('linewidths', (0,)) + super().__init__([], offsets=self.XY, offset_transform=self.transform, + closed=False, **kwargs) + self.polykw = kwargs + self.set_UVC(U, V, C) + self._dpi_at_last_init = None + + def _init(self): + """ + Initialization delayed until first draw; + allow time for axes setup. + """ + # It seems that there are not enough event notifications + # available to have this work on an as-needed basis at present. + if True: # self._dpi_at_last_init != self.axes.figure.dpi + trans = self._set_transform() + self.span = trans.inverted().transform_bbox(self.axes.bbox).width + if self.width is None: + sn = np.clip(math.sqrt(self.N), 8, 25) + self.width = 0.06 * self.span / sn + + # _make_verts sets self.scale if not already specified + if (self._dpi_at_last_init != self.axes.figure.dpi + and self.scale is None): + self._make_verts(self.U, self.V, self.angles) + + self._dpi_at_last_init = self.axes.figure.dpi + + def get_datalim(self, transData): + trans = self.get_transform() + offset_trf = self.get_offset_transform() + full_transform = (trans - transData) + (offset_trf - transData) + XY = full_transform.transform(self.XY) + bbox = transforms.Bbox.null() + bbox.update_from_data_xy(XY, ignore=True) + return bbox + + @martist.allow_rasterization + def draw(self, renderer): + self._init() + verts = self._make_verts(self.U, self.V, self.angles) + self.set_verts(verts, closed=False) + super().draw(renderer) + self.stale = False + + def set_UVC(self, U, V, C=None): + # We need to ensure we have a copy, not a reference + # to an array that might change before draw(). + U = ma.masked_invalid(U, copy=True).ravel() + V = ma.masked_invalid(V, copy=True).ravel() + if C is not None: + C = ma.masked_invalid(C, copy=True).ravel() + for name, var in zip(('U', 'V', 'C'), (U, V, C)): + if not (var is None or var.size == self.N or var.size == 1): + raise ValueError(f'Argument {name} has a size {var.size}' + f' which does not match {self.N},' + ' the number of arrow positions') + + mask = ma.mask_or(U.mask, V.mask, copy=False, shrink=True) + if C is not None: + mask = ma.mask_or(mask, C.mask, copy=False, shrink=True) + if mask is ma.nomask: + C = C.filled() + else: + C = ma.array(C, mask=mask, copy=False) + self.U = U.filled(1) + self.V = V.filled(1) + self.Umask = mask + if C is not None: + self.set_array(C) + self.stale = True + + def _dots_per_unit(self, units): + """Return a scale factor for converting from units to pixels.""" + bb = self.axes.bbox + vl = self.axes.viewLim + return _api.check_getitem({ + 'x': bb.width / vl.width, + 'y': bb.height / vl.height, + 'xy': np.hypot(*bb.size) / np.hypot(*vl.size), + 'width': bb.width, + 'height': bb.height, + 'dots': 1., + 'inches': self.axes.figure.dpi, + }, units=units) + + def _set_transform(self): + """ + Set the PolyCollection transform to go + from arrow width units to pixels. + """ + dx = self._dots_per_unit(self.units) + self._trans_scale = dx # pixels per arrow width unit + trans = transforms.Affine2D().scale(dx) + self.set_transform(trans) + return trans + + def _angles_lengths(self, U, V, eps=1): + xy = self.axes.transData.transform(self.XY) + uv = np.column_stack((U, V)) + xyp = self.axes.transData.transform(self.XY + eps * uv) + dxy = xyp - xy + angles = np.arctan2(dxy[:, 1], dxy[:, 0]) + lengths = np.hypot(*dxy.T) / eps + return angles, lengths + + def _make_verts(self, U, V, angles): + uv = (U + V * 1j) + str_angles = angles if isinstance(angles, str) else '' + if str_angles == 'xy' and self.scale_units == 'xy': + # Here eps is 1 so that if we get U, V by diffing + # the X, Y arrays, the vectors will connect the + # points, regardless of the axis scaling (including log). + angles, lengths = self._angles_lengths(U, V, eps=1) + elif str_angles == 'xy' or self.scale_units == 'xy': + # Calculate eps based on the extents of the plot + # so that we don't end up with roundoff error from + # adding a small number to a large. + eps = np.abs(self.axes.dataLim.extents).max() * 0.001 + angles, lengths = self._angles_lengths(U, V, eps=eps) + if str_angles and self.scale_units == 'xy': + a = lengths + else: + a = np.abs(uv) + if self.scale is None: + sn = max(10, math.sqrt(self.N)) + if self.Umask is not ma.nomask: + amean = a[~self.Umask].mean() + else: + amean = a.mean() + # crude auto-scaling + # scale is typical arrow length as a multiple of the arrow width + scale = 1.8 * amean * sn / self.span + if self.scale_units is None: + if self.scale is None: + self.scale = scale + widthu_per_lenu = 1.0 + else: + if self.scale_units == 'xy': + dx = 1 + else: + dx = self._dots_per_unit(self.scale_units) + widthu_per_lenu = dx / self._trans_scale + if self.scale is None: + self.scale = scale * widthu_per_lenu + length = a * (widthu_per_lenu / (self.scale * self.width)) + X, Y = self._h_arrows(length) + if str_angles == 'xy': + theta = angles + elif str_angles == 'uv': + theta = np.angle(uv) + else: + theta = ma.masked_invalid(np.deg2rad(angles)).filled(0) + theta = theta.reshape((-1, 1)) # for broadcasting + xy = (X + Y * 1j) * np.exp(1j * theta) * self.width + XY = np.stack((xy.real, xy.imag), axis=2) + if self.Umask is not ma.nomask: + XY = ma.array(XY) + XY[self.Umask] = ma.masked + # This might be handled more efficiently with nans, given + # that nans will end up in the paths anyway. + + return XY + + def _h_arrows(self, length): + """Length is in arrow width units.""" + # It might be possible to streamline the code + # and speed it up a bit by using complex (x, y) + # instead of separate arrays; but any gain would be slight. + minsh = self.minshaft * self.headlength + N = len(length) + length = length.reshape(N, 1) + # This number is chosen based on when pixel values overflow in Agg + # causing rendering errors + # length = np.minimum(length, 2 ** 16) + np.clip(length, 0, 2 ** 16, out=length) + # x, y: normal horizontal arrow + x = np.array([0, -self.headaxislength, + -self.headlength, 0], + np.float64) + x = x + np.array([0, 1, 1, 1]) * length + y = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) + y = np.repeat(y[np.newaxis, :], N, axis=0) + # x0, y0: arrow without shaft, for short vectors + x0 = np.array([0, minsh - self.headaxislength, + minsh - self.headlength, minsh], np.float64) + y0 = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64) + ii = [0, 1, 2, 3, 2, 1, 0, 0] + X = x[:, ii] + Y = y[:, ii] + Y[:, 3:-1] *= -1 + X0 = x0[ii] + Y0 = y0[ii] + Y0[3:-1] *= -1 + shrink = length / minsh if minsh != 0. else 0. + X0 = shrink * X0[np.newaxis, :] + Y0 = shrink * Y0[np.newaxis, :] + short = np.repeat(length < minsh, 8, axis=1) + # Now select X0, Y0 if short, otherwise X, Y + np.copyto(X, X0, where=short) + np.copyto(Y, Y0, where=short) + if self.pivot == 'middle': + X -= 0.5 * X[:, 3, np.newaxis] + elif self.pivot == 'tip': + # numpy bug? using -= does not work here unless we multiply by a + # float first, as with 'mid'. + X = X - X[:, 3, np.newaxis] + elif self.pivot != 'tail': + _api.check_in_list(["middle", "tip", "tail"], pivot=self.pivot) + + tooshort = length < self.minlength + if tooshort.any(): + # Use a heptagonal dot: + th = np.arange(0, 8, 1, np.float64) * (np.pi / 3.0) + x1 = np.cos(th) * self.minlength * 0.5 + y1 = np.sin(th) * self.minlength * 0.5 + X1 = np.repeat(x1[np.newaxis, :], N, axis=0) + Y1 = np.repeat(y1[np.newaxis, :], N, axis=0) + tooshort = np.repeat(tooshort, 8, 1) + np.copyto(X, X1, where=tooshort) + np.copyto(Y, Y1, where=tooshort) + # Mask handling is deferred to the caller, _make_verts. + return X, Y + + quiver_doc = _api.deprecated("3.7")(property(lambda self: _quiver_doc)) + + +_barbs_doc = r""" +Plot a 2D field of barbs. + +Call signature:: + + barbs([X, Y], U, V, [C], **kwargs) + +Where *X*, *Y* define the barb locations, *U*, *V* define the barb +directions, and *C* optionally sets the color. + +All arguments may be 1D or 2D. *U*, *V*, *C* may be masked arrays, but masked +*X*, *Y* are not supported at present. + +Barbs are traditionally used in meteorology as a way to plot the speed +and direction of wind observations, but can technically be used to +plot any two dimensional vector quantity. As opposed to arrows, which +give vector magnitude by the length of the arrow, the barbs give more +quantitative information about the vector magnitude by putting slanted +lines or a triangle for various increments in magnitude, as show +schematically below:: + + : /\ \ + : / \ \ + : / \ \ \ + : / \ \ \ + : ------------------------------ + +The largest increment is given by a triangle (or "flag"). After those +come full lines (barbs). The smallest increment is a half line. There +is only, of course, ever at most 1 half line. If the magnitude is +small and only needs a single half-line and no full lines or +triangles, the half-line is offset from the end of the barb so that it +can be easily distinguished from barbs with a single full line. The +magnitude for the barb shown above would nominally be 65, using the +standard increments of 50, 10, and 5. + +See also https://en.wikipedia.org/wiki/Wind_barb. + +Parameters +---------- +X, Y : 1D or 2D array-like, optional + The x and y coordinates of the barb locations. See *pivot* for how the + barbs are drawn to the x, y positions. + + If not given, they will be generated as a uniform integer meshgrid based + on the dimensions of *U* and *V*. + + If *X* and *Y* are 1D but *U*, *V* are 2D, *X*, *Y* are expanded to 2D + using ``X, Y = np.meshgrid(X, Y)``. In this case ``len(X)`` and ``len(Y)`` + must match the column and row dimensions of *U* and *V*. + +U, V : 1D or 2D array-like + The x and y components of the barb shaft. + +C : 1D or 2D array-like, optional + Numeric data that defines the barb colors by colormapping via *norm* and + *cmap*. + + This does not support explicit colors. If you want to set colors directly, + use *barbcolor* instead. + +length : float, default: 7 + Length of the barb in points; the other parts of the barb + are scaled against this. + +pivot : {'tip', 'middle'} or float, default: 'tip' + The part of the arrow that is anchored to the *X*, *Y* grid. The barb + rotates about this point. This can also be a number, which shifts the + start of the barb that many points away from grid point. + +barbcolor : color or color sequence + The color of all parts of the barb except for the flags. This parameter + is analogous to the *edgecolor* parameter for polygons, which can be used + instead. However this parameter will override facecolor. + +flagcolor : color or color sequence + The color of any flags on the barb. This parameter is analogous to the + *facecolor* parameter for polygons, which can be used instead. However, + this parameter will override facecolor. If this is not set (and *C* has + not either) then *flagcolor* will be set to match *barbcolor* so that the + barb has a uniform color. If *C* has been set, *flagcolor* has no effect. + +sizes : dict, optional + A dictionary of coefficients specifying the ratio of a given + feature to the length of the barb. Only those values one wishes to + override need to be included. These features include: + + - 'spacing' - space between features (flags, full/half barbs) + - 'height' - height (distance from shaft to top) of a flag or full barb + - 'width' - width of a flag, twice the width of a full barb + - 'emptybarb' - radius of the circle used for low magnitudes + +fill_empty : bool, default: False + Whether the empty barbs (circles) that are drawn should be filled with + the flag color. If they are not filled, the center is transparent. + +rounding : bool, default: True + Whether the vector magnitude should be rounded when allocating barb + components. If True, the magnitude is rounded to the nearest multiple + of the half-barb increment. If False, the magnitude is simply truncated + to the next lowest multiple. + +barb_increments : dict, optional + A dictionary of increments specifying values to associate with + different parts of the barb. Only those values one wishes to + override need to be included. + + - 'half' - half barbs (Default is 5) + - 'full' - full barbs (Default is 10) + - 'flag' - flags (default is 50) + +flip_barb : bool or array-like of bool, default: False + Whether the lines and flags should point opposite to normal. + Normal behavior is for the barbs and lines to point right (comes from wind + barbs having these features point towards low pressure in the Northern + Hemisphere). + + A single value is applied to all barbs. Individual barbs can be flipped by + passing a bool array of the same size as *U* and *V*. + +Returns +------- +barbs : `~matplotlib.quiver.Barbs` + +Other Parameters +---------------- +data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + +**kwargs + The barbs can further be customized using `.PolyCollection` keyword + arguments: + + %(PolyCollection:kwdoc)s +""" % _docstring.interpd.params + +_docstring.interpd.update(barbs_doc=_barbs_doc) + + +class Barbs(mcollections.PolyCollection): + """ + Specialized PolyCollection for barbs. + + The only API method is :meth:`set_UVC`, which can be used to + change the size, orientation, and color of the arrows. Locations + are changed using the :meth:`set_offsets` collection method. + Possibly this method will be useful in animations. + + There is one internal function :meth:`_find_tails` which finds + exactly what should be put on the barb given the vector magnitude. + From there :meth:`_make_barbs` is used to find the vertices of the + polygon to represent the barb based on this information. + """ + + # This may be an abuse of polygons here to render what is essentially maybe + # 1 triangle and a series of lines. It works fine as far as I can tell + # however. + + @_docstring.interpd + def __init__(self, ax, *args, + pivot='tip', length=7, barbcolor=None, flagcolor=None, + sizes=None, fill_empty=False, barb_increments=None, + rounding=True, flip_barb=False, **kwargs): + """ + The constructor takes one required argument, an Axes + instance, followed by the args and kwargs described + by the following pyplot interface documentation: + %(barbs_doc)s + """ + self.sizes = sizes or dict() + self.fill_empty = fill_empty + self.barb_increments = barb_increments or dict() + self.rounding = rounding + self.flip = np.atleast_1d(flip_barb) + transform = kwargs.pop('transform', ax.transData) + self._pivot = pivot + self._length = length + + # Flagcolor and barbcolor provide convenience parameters for + # setting the facecolor and edgecolor, respectively, of the barb + # polygon. We also work here to make the flag the same color as the + # rest of the barb by default + + if None in (barbcolor, flagcolor): + kwargs['edgecolors'] = 'face' + if flagcolor: + kwargs['facecolors'] = flagcolor + elif barbcolor: + kwargs['facecolors'] = barbcolor + else: + # Set to facecolor passed in or default to black + kwargs.setdefault('facecolors', 'k') + else: + kwargs['edgecolors'] = barbcolor + kwargs['facecolors'] = flagcolor + + # Explicitly set a line width if we're not given one, otherwise + # polygons are not outlined and we get no barbs + if 'linewidth' not in kwargs and 'lw' not in kwargs: + kwargs['linewidth'] = 1 + + # Parse out the data arrays from the various configurations supported + x, y, u, v, c = _parse_args(*args, caller_name='barbs') + self.x = x + self.y = y + xy = np.column_stack((x, y)) + + # Make a collection + barb_size = self._length ** 2 / 4 # Empirically determined + super().__init__( + [], (barb_size,), offsets=xy, offset_transform=transform, **kwargs) + self.set_transform(transforms.IdentityTransform()) + + self.set_UVC(u, v, c) + + def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50): + """ + Find how many of each of the tail pieces is necessary. + + Parameters + ---------- + mag : `~numpy.ndarray` + Vector magnitudes; must be non-negative (and an actual ndarray). + rounding : bool, default: True + Whether to round or to truncate to the nearest half-barb. + half, full, flag : float, defaults: 5, 10, 50 + Increments for a half-barb, a barb, and a flag. + + Returns + ------- + n_flags, n_barbs : int array + For each entry in *mag*, the number of flags and barbs. + half_flag : bool array + For each entry in *mag*, whether a half-barb is needed. + empty_flag : bool array + For each entry in *mag*, whether nothing is drawn. + """ + # If rounding, round to the nearest multiple of half, the smallest + # increment + if rounding: + mag = half * np.around(mag / half) + n_flags, mag = divmod(mag, flag) + n_barb, mag = divmod(mag, full) + half_flag = mag >= half + empty_flag = ~(half_flag | (n_flags > 0) | (n_barb > 0)) + return n_flags.astype(int), n_barb.astype(int), half_flag, empty_flag + + def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length, + pivot, sizes, fill_empty, flip): + """ + Create the wind barbs. + + Parameters + ---------- + u, v + Components of the vector in the x and y directions, respectively. + + nflags, nbarbs, half_barb, empty_flag + Respectively, the number of flags, number of barbs, flag for + half a barb, and flag for empty barb, ostensibly obtained from + :meth:`_find_tails`. + + length + The length of the barb staff in points. + + pivot : {"tip", "middle"} or number + The point on the barb around which the entire barb should be + rotated. If a number, the start of the barb is shifted by that + many points from the origin. + + sizes : dict + Coefficients specifying the ratio of a given feature to the length + of the barb. These features include: + + - *spacing*: space between features (flags, full/half barbs). + - *height*: distance from shaft of top of a flag or full barb. + - *width*: width of a flag, twice the width of a full barb. + - *emptybarb*: radius of the circle used for low magnitudes. + + fill_empty : bool + Whether the circle representing an empty barb should be filled or + not (this changes the drawing of the polygon). + + flip : list of bool + Whether the features should be flipped to the other side of the + barb (useful for winds in the southern hemisphere). + + Returns + ------- + list of arrays of vertices + Polygon vertices for each of the wind barbs. These polygons have + been rotated to properly align with the vector direction. + """ + + # These control the spacing and size of barb elements relative to the + # length of the shaft + spacing = length * sizes.get('spacing', 0.125) + full_height = length * sizes.get('height', 0.4) + full_width = length * sizes.get('width', 0.25) + empty_rad = length * sizes.get('emptybarb', 0.15) + + # Controls y point where to pivot the barb. + pivot_points = dict(tip=0.0, middle=-length / 2.) + + endx = 0.0 + try: + endy = float(pivot) + except ValueError: + endy = pivot_points[pivot.lower()] + + # Get the appropriate angle for the vector components. The offset is + # due to the way the barb is initially drawn, going down the y-axis. + # This makes sense in a meteorological mode of thinking since there 0 + # degrees corresponds to north (the y-axis traditionally) + angles = -(ma.arctan2(v, u) + np.pi / 2) + + # Used for low magnitude. We just get the vertices, so if we make it + # out here, it can be reused. The center set here should put the + # center of the circle at the location(offset), rather than at the + # same point as the barb pivot; this seems more sensible. + circ = CirclePolygon((0, 0), radius=empty_rad).get_verts() + if fill_empty: + empty_barb = circ + else: + # If we don't want the empty one filled, we make a degenerate + # polygon that wraps back over itself + empty_barb = np.concatenate((circ, circ[::-1])) + + barb_list = [] + for index, angle in np.ndenumerate(angles): + # If the vector magnitude is too weak to draw anything, plot an + # empty circle instead + if empty_flag[index]: + # We can skip the transform since the circle has no preferred + # orientation + barb_list.append(empty_barb) + continue + + poly_verts = [(endx, endy)] + offset = length + + # Handle if this barb should be flipped + barb_height = -full_height if flip[index] else full_height + + # Add vertices for each flag + for i in range(nflags[index]): + # The spacing that works for the barbs is a little to much for + # the flags, but this only occurs when we have more than 1 + # flag. + if offset != length: + offset += spacing / 2. + poly_verts.extend( + [[endx, endy + offset], + [endx + barb_height, endy - full_width / 2 + offset], + [endx, endy - full_width + offset]]) + + offset -= full_width + spacing + + # Add vertices for each barb. These really are lines, but works + # great adding 3 vertices that basically pull the polygon out and + # back down the line + for i in range(nbarbs[index]): + poly_verts.extend( + [(endx, endy + offset), + (endx + barb_height, endy + offset + full_width / 2), + (endx, endy + offset)]) + + offset -= spacing + + # Add the vertices for half a barb, if needed + if half_barb[index]: + # If the half barb is the first on the staff, traditionally it + # is offset from the end to make it easy to distinguish from a + # barb with a full one + if offset == length: + poly_verts.append((endx, endy + offset)) + offset -= 1.5 * spacing + poly_verts.extend( + [(endx, endy + offset), + (endx + barb_height / 2, endy + offset + full_width / 4), + (endx, endy + offset)]) + + # Rotate the barb according the angle. Making the barb first and + # then rotating it made the math for drawing the barb really easy. + # Also, the transform framework makes doing the rotation simple. + poly_verts = transforms.Affine2D().rotate(-angle).transform( + poly_verts) + barb_list.append(poly_verts) + + return barb_list + + def set_UVC(self, U, V, C=None): + # We need to ensure we have a copy, not a reference to an array that + # might change before draw(). + self.u = ma.masked_invalid(U, copy=True).ravel() + self.v = ma.masked_invalid(V, copy=True).ravel() + + # Flip needs to have the same number of entries as everything else. + # Use broadcast_to to avoid a bloated array of identical values. + # (can't rely on actual broadcasting) + if len(self.flip) == 1: + flip = np.broadcast_to(self.flip, self.u.shape) + else: + flip = self.flip + + if C is not None: + c = ma.masked_invalid(C, copy=True).ravel() + x, y, u, v, c, flip = cbook.delete_masked_points( + self.x.ravel(), self.y.ravel(), self.u, self.v, c, + flip.ravel()) + _check_consistent_shapes(x, y, u, v, c, flip) + else: + x, y, u, v, flip = cbook.delete_masked_points( + self.x.ravel(), self.y.ravel(), self.u, self.v, flip.ravel()) + _check_consistent_shapes(x, y, u, v, flip) + + magnitude = np.hypot(u, v) + flags, barbs, halves, empty = self._find_tails( + magnitude, self.rounding, **self.barb_increments) + + # Get the vertices for each of the barbs + + plot_barbs = self._make_barbs(u, v, flags, barbs, halves, empty, + self._length, self._pivot, self.sizes, + self.fill_empty, flip) + self.set_verts(plot_barbs) + + # Set the color array + if C is not None: + self.set_array(c) + + # Update the offsets in case the masked data changed + xy = np.column_stack((x, y)) + self._offsets = xy + self.stale = True + + def set_offsets(self, xy): + """ + Set the offsets for the barb polygons. This saves the offsets passed + in and masks them as appropriate for the existing U/V data. + + Parameters + ---------- + xy : sequence of pairs of floats + """ + self.x = xy[:, 0] + self.y = xy[:, 1] + x, y, u, v = cbook.delete_masked_points( + self.x.ravel(), self.y.ravel(), self.u, self.v) + _check_consistent_shapes(x, y, u, v) + xy = np.column_stack((x, y)) + super().set_offsets(xy) + self.stale = True + + barbs_doc = _api.deprecated("3.7")(property(lambda self: _barbs_doc)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.pyi new file mode 100644 index 00000000..c673c5dd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/quiver.pyi @@ -0,0 +1,187 @@ +import matplotlib.artist as martist +import matplotlib.collections as mcollections +from matplotlib.axes import Axes +from matplotlib.figure import Figure +from matplotlib.text import Text +from matplotlib.transforms import Transform, Bbox + + +import numpy as np +from numpy.typing import ArrayLike +from collections.abc import Sequence +from typing import Any, Literal, overload +from matplotlib.typing import ColorType + +class QuiverKey(martist.Artist): + halign: dict[Literal["N", "S", "E", "W"], Literal["left", "center", "right"]] + valign: dict[Literal["N", "S", "E", "W"], Literal["top", "center", "bottom"]] + pivot: dict[Literal["N", "S", "E", "W"], Literal["middle", "tip", "tail"]] + Q: Quiver + X: float + Y: float + U: float + angle: float + coord: Literal["axes", "figure", "data", "inches"] + color: ColorType | None + label: str + labelpos: Literal["N", "S", "E", "W"] + labelcolor: ColorType | None + fontproperties: dict[str, Any] + kw: dict[str, Any] + text: Text + zorder: float + def __init__( + self, + Q: Quiver, + X: float, + Y: float, + U: float, + label: str, + *, + angle: float = ..., + coordinates: Literal["axes", "figure", "data", "inches"] = ..., + color: ColorType | None = ..., + labelsep: float = ..., + labelpos: Literal["N", "S", "E", "W"] = ..., + labelcolor: ColorType | None = ..., + fontproperties: dict[str, Any] | None = ..., + **kwargs + ) -> None: ... + @property + def labelsep(self) -> float: ... + def set_figure(self, fig: Figure) -> None: ... + +class Quiver(mcollections.PolyCollection): + X: ArrayLike + Y: ArrayLike + XY: ArrayLike + U: ArrayLike + V: ArrayLike + Umask: ArrayLike + N: int + scale: float | None + headwidth: float + headlength: float + headaxislength: float + minshaft: float + minlength: float + units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] + scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] | None + angles: Literal["uv", "xy"] | ArrayLike + width: float | None + pivot: Literal["tail", "middle", "tip"] + transform: Transform + polykw: dict[str, Any] + + @overload + def __init__( + self, + ax: Axes, + U: ArrayLike, + V: ArrayLike, + C: ArrayLike = ..., + *, + scale: float | None = ..., + headwidth: float = ..., + headlength: float = ..., + headaxislength: float = ..., + minshaft: float = ..., + minlength: float = ..., + units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] = ..., + scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] + | None = ..., + angles: Literal["uv", "xy"] | ArrayLike = ..., + width: float | None = ..., + color: ColorType | Sequence[ColorType] = ..., + pivot: Literal["tail", "mid", "middle", "tip"] = ..., + **kwargs + ) -> None: ... + @overload + def __init__( + self, + ax: Axes, + X: ArrayLike, + Y: ArrayLike, + U: ArrayLike, + V: ArrayLike, + C: ArrayLike = ..., + *, + scale: float | None = ..., + headwidth: float = ..., + headlength: float = ..., + headaxislength: float = ..., + minshaft: float = ..., + minlength: float = ..., + units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] = ..., + scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] + | None = ..., + angles: Literal["uv", "xy"] | ArrayLike = ..., + width: float | None = ..., + color: ColorType | Sequence[ColorType] = ..., + pivot: Literal["tail", "mid", "middle", "tip"] = ..., + **kwargs + ) -> None: ... + def get_datalim(self, transData: Transform) -> Bbox: ... + def set_UVC( + self, U: ArrayLike, V: ArrayLike, C: ArrayLike | None = ... + ) -> None: ... + @property + def quiver_doc(self) -> str: ... + +class Barbs(mcollections.PolyCollection): + sizes: dict[str, float] + fill_empty: bool + barb_increments: dict[str, float] + rounding: bool + flip: np.ndarray + x: ArrayLike + y: ArrayLike + u: ArrayLike + v: ArrayLike + + @overload + def __init__( + self, + ax: Axes, + U: ArrayLike, + V: ArrayLike, + C: ArrayLike = ..., + *, + pivot: str = ..., + length: int = ..., + barbcolor: ColorType | Sequence[ColorType] | None = ..., + flagcolor: ColorType | Sequence[ColorType] | None = ..., + sizes: dict[str, float] | None = ..., + fill_empty: bool = ..., + barb_increments: dict[str, float] | None = ..., + rounding: bool = ..., + flip_barb: bool | ArrayLike = ..., + **kwargs + ) -> None: ... + @overload + def __init__( + self, + ax: Axes, + X: ArrayLike, + Y: ArrayLike, + U: ArrayLike, + V: ArrayLike, + C: ArrayLike = ..., + *, + pivot: str = ..., + length: int = ..., + barbcolor: ColorType | Sequence[ColorType] | None = ..., + flagcolor: ColorType | Sequence[ColorType] | None = ..., + sizes: dict[str, float] | None = ..., + fill_empty: bool = ..., + barb_increments: dict[str, float] | None = ..., + rounding: bool = ..., + flip_barb: bool | ArrayLike = ..., + **kwargs + ) -> None: ... + def set_UVC( + self, U: ArrayLike, V: ArrayLike, C: ArrayLike | None = ... + ) -> None: ... + def set_offsets(self, xy: ArrayLike) -> None: ... + @property + def barbs_doc(self) -> str: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.py new file mode 100644 index 00000000..276bb9f8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.py @@ -0,0 +1,1346 @@ +""" +The rcsetup module contains the validation code for customization using +Matplotlib's rc settings. + +Each rc setting is assigned a function used to validate any attempted changes +to that setting. The validation functions are defined in the rcsetup module, +and are used to construct the rcParams global object which stores the settings +and is referenced throughout Matplotlib. + +The default values of the rc settings are set in the default matplotlibrc file. +Any additions or deletions to the parameter set listed here should also be +propagated to the :file:`lib/matplotlib/mpl-data/matplotlibrc` in Matplotlib's +root source directory. +""" + +import ast +from functools import lru_cache, reduce +from numbers import Real +import operator +import os +import re + +import numpy as np + +from matplotlib import _api, cbook +from matplotlib.cbook import ls_mapper +from matplotlib.colors import Colormap, is_color_like +from matplotlib._fontconfig_pattern import parse_fontconfig_pattern +from matplotlib._enums import JoinStyle, CapStyle + +# Don't let the original cycler collide with our validating cycler +from cycler import Cycler, cycler as ccycler + + +# The capitalized forms are needed for ipython at present; this may +# change for later versions. +interactive_bk = [ + 'GTK3Agg', 'GTK3Cairo', 'GTK4Agg', 'GTK4Cairo', + 'MacOSX', + 'nbAgg', + 'QtAgg', 'QtCairo', 'Qt5Agg', 'Qt5Cairo', + 'TkAgg', 'TkCairo', + 'WebAgg', + 'WX', 'WXAgg', 'WXCairo', +] +non_interactive_bk = ['agg', 'cairo', + 'pdf', 'pgf', 'ps', 'svg', 'template'] +all_backends = interactive_bk + non_interactive_bk + + +class ValidateInStrings: + def __init__(self, key, valid, ignorecase=False, *, + _deprecated_since=None): + """*valid* is a list of legal strings.""" + self.key = key + self.ignorecase = ignorecase + self._deprecated_since = _deprecated_since + + def func(s): + if ignorecase: + return s.lower() + else: + return s + self.valid = {func(k): k for k in valid} + + def __call__(self, s): + if self._deprecated_since: + name, = (k for k, v in globals().items() if v is self) + _api.warn_deprecated( + self._deprecated_since, name=name, obj_type="function") + if self.ignorecase and isinstance(s, str): + s = s.lower() + if s in self.valid: + return self.valid[s] + msg = (f"{s!r} is not a valid value for {self.key}; supported values " + f"are {[*self.valid.values()]}") + if (isinstance(s, str) + and (s.startswith('"') and s.endswith('"') + or s.startswith("'") and s.endswith("'")) + and s[1:-1] in self.valid): + msg += "; remove quotes surrounding your string" + raise ValueError(msg) + + +@lru_cache +def _listify_validator(scalar_validator, allow_stringlist=False, *, + n=None, doc=None): + def f(s): + if isinstance(s, str): + try: + val = [scalar_validator(v.strip()) for v in s.split(',') + if v.strip()] + except Exception: + if allow_stringlist: + # Sometimes, a list of colors might be a single string + # of single-letter colornames. So give that a shot. + val = [scalar_validator(v.strip()) for v in s if v.strip()] + else: + raise + # Allow any ordered sequence type -- generators, np.ndarray, pd.Series + # -- but not sets, whose iteration order is non-deterministic. + elif np.iterable(s) and not isinstance(s, (set, frozenset)): + # The condition on this list comprehension will preserve the + # behavior of filtering out any empty strings (behavior was + # from the original validate_stringlist()), while allowing + # any non-string/text scalar values such as numbers and arrays. + val = [scalar_validator(v) for v in s + if not isinstance(v, str) or v] + else: + raise ValueError( + f"Expected str or other non-set iterable, but got {s}") + if n is not None and len(val) != n: + raise ValueError( + f"Expected {n} values, but there are {len(val)} values in {s}") + return val + + try: + f.__name__ = f"{scalar_validator.__name__}list" + except AttributeError: # class instance. + f.__name__ = f"{type(scalar_validator).__name__}List" + f.__qualname__ = f.__qualname__.rsplit(".", 1)[0] + "." + f.__name__ + f.__doc__ = doc if doc is not None else scalar_validator.__doc__ + return f + + +def validate_any(s): + return s +validate_anylist = _listify_validator(validate_any) + + +def _validate_date(s): + try: + np.datetime64(s) + return s + except ValueError: + raise ValueError( + f'{s!r} should be a string that can be parsed by numpy.datetime64') + + +def validate_bool(b): + """Convert b to ``bool`` or raise.""" + if isinstance(b, str): + b = b.lower() + if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True): + return True + elif b in ('f', 'n', 'no', 'off', 'false', '0', 0, False): + return False + else: + raise ValueError(f'Cannot convert {b!r} to bool') + + +def validate_axisbelow(s): + try: + return validate_bool(s) + except ValueError: + if isinstance(s, str): + if s == 'line': + return 'line' + raise ValueError(f'{s!r} cannot be interpreted as' + ' True, False, or "line"') + + +def validate_dpi(s): + """Confirm s is string 'figure' or convert s to float or raise.""" + if s == 'figure': + return s + try: + return float(s) + except ValueError as e: + raise ValueError(f'{s!r} is not string "figure" and ' + f'could not convert {s!r} to float') from e + + +def _make_type_validator(cls, *, allow_none=False): + """ + Return a validator that converts inputs to *cls* or raises (and possibly + allows ``None`` as well). + """ + + def validator(s): + if (allow_none and + (s is None or isinstance(s, str) and s.lower() == "none")): + return None + if cls is str and not isinstance(s, str): + raise ValueError(f'Could not convert {s!r} to str') + try: + return cls(s) + except (TypeError, ValueError) as e: + raise ValueError( + f'Could not convert {s!r} to {cls.__name__}') from e + + validator.__name__ = f"validate_{cls.__name__}" + if allow_none: + validator.__name__ += "_or_None" + validator.__qualname__ = ( + validator.__qualname__.rsplit(".", 1)[0] + "." + validator.__name__) + return validator + + +validate_string = _make_type_validator(str) +validate_string_or_None = _make_type_validator(str, allow_none=True) +validate_stringlist = _listify_validator( + validate_string, doc='return a list of strings') +validate_int = _make_type_validator(int) +validate_int_or_None = _make_type_validator(int, allow_none=True) +validate_float = _make_type_validator(float) +validate_float_or_None = _make_type_validator(float, allow_none=True) +validate_floatlist = _listify_validator( + validate_float, doc='return a list of floats') + + +def _validate_pathlike(s): + if isinstance(s, (str, os.PathLike)): + # Store value as str because savefig.directory needs to distinguish + # between "" (cwd) and "." (cwd, but gets updated by user selections). + return os.fsdecode(s) + else: + return validate_string(s) + + +def validate_fonttype(s): + """ + Confirm that this is a Postscript or PDF font type that we know how to + convert to. + """ + fonttypes = {'type3': 3, + 'truetype': 42} + try: + fonttype = validate_int(s) + except ValueError: + try: + return fonttypes[s.lower()] + except KeyError as e: + raise ValueError('Supported Postscript/PDF font types are %s' + % list(fonttypes)) from e + else: + if fonttype not in fonttypes.values(): + raise ValueError( + 'Supported Postscript/PDF font types are %s' % + list(fonttypes.values())) + return fonttype + + +_validate_standard_backends = ValidateInStrings( + 'backend', all_backends, ignorecase=True) +_auto_backend_sentinel = object() + + +def validate_backend(s): + backend = ( + s if s is _auto_backend_sentinel or s.startswith("module://") + else _validate_standard_backends(s)) + return backend + + +def _validate_toolbar(s): + s = ValidateInStrings( + 'toolbar', ['None', 'toolbar2', 'toolmanager'], ignorecase=True)(s) + if s == 'toolmanager': + _api.warn_external( + "Treat the new Tool classes introduced in v1.5 as experimental " + "for now; the API and rcParam may change in future versions.") + return s + + +def validate_color_or_inherit(s): + """Return a valid color arg.""" + if cbook._str_equal(s, 'inherit'): + return s + return validate_color(s) + + +def validate_color_or_auto(s): + if cbook._str_equal(s, 'auto'): + return s + return validate_color(s) + + +def validate_color_for_prop_cycle(s): + # N-th color cycle syntax can't go into the color cycle. + if isinstance(s, str) and re.match("^C[0-9]$", s): + raise ValueError(f"Cannot put cycle reference ({s!r}) in prop_cycler") + return validate_color(s) + + +def _validate_color_or_linecolor(s): + if cbook._str_equal(s, 'linecolor'): + return s + elif cbook._str_equal(s, 'mfc') or cbook._str_equal(s, 'markerfacecolor'): + return 'markerfacecolor' + elif cbook._str_equal(s, 'mec') or cbook._str_equal(s, 'markeredgecolor'): + return 'markeredgecolor' + elif s is None: + return None + elif isinstance(s, str) and len(s) == 6 or len(s) == 8: + stmp = '#' + s + if is_color_like(stmp): + return stmp + if s.lower() == 'none': + return None + elif is_color_like(s): + return s + + raise ValueError(f'{s!r} does not look like a color arg') + + +def validate_color(s): + """Return a valid color arg.""" + if isinstance(s, str): + if s.lower() == 'none': + return 'none' + if len(s) == 6 or len(s) == 8: + stmp = '#' + s + if is_color_like(stmp): + return stmp + + if is_color_like(s): + return s + + # If it is still valid, it must be a tuple (as a string from matplotlibrc). + try: + color = ast.literal_eval(s) + except (SyntaxError, ValueError): + pass + else: + if is_color_like(color): + return color + + raise ValueError(f'{s!r} does not look like a color arg') + + +validate_colorlist = _listify_validator( + validate_color, allow_stringlist=True, doc='return a list of colorspecs') + + +def _validate_cmap(s): + _api.check_isinstance((str, Colormap), cmap=s) + return s + + +def validate_aspect(s): + if s in ('auto', 'equal'): + return s + try: + return float(s) + except ValueError as e: + raise ValueError('not a valid aspect specification') from e + + +def validate_fontsize_None(s): + if s is None or s == 'None': + return None + else: + return validate_fontsize(s) + + +def validate_fontsize(s): + fontsizes = ['xx-small', 'x-small', 'small', 'medium', 'large', + 'x-large', 'xx-large', 'smaller', 'larger'] + if isinstance(s, str): + s = s.lower() + if s in fontsizes: + return s + try: + return float(s) + except ValueError as e: + raise ValueError("%s is not a valid font size. Valid font sizes " + "are %s." % (s, ", ".join(fontsizes))) from e + + +validate_fontsizelist = _listify_validator(validate_fontsize) + + +def validate_fontweight(s): + weights = [ + 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', + 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black'] + # Note: Historically, weights have been case-sensitive in Matplotlib + if s in weights: + return s + try: + return int(s) + except (ValueError, TypeError) as e: + raise ValueError(f'{s} is not a valid font weight.') from e + + +def validate_fontstretch(s): + stretchvalues = [ + 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', + 'normal', 'semi-expanded', 'expanded', 'extra-expanded', + 'ultra-expanded'] + # Note: Historically, stretchvalues have been case-sensitive in Matplotlib + if s in stretchvalues: + return s + try: + return int(s) + except (ValueError, TypeError) as e: + raise ValueError(f'{s} is not a valid font stretch.') from e + + +def validate_font_properties(s): + parse_fontconfig_pattern(s) + return s + + +def _validate_mathtext_fallback(s): + _fallback_fonts = ['cm', 'stix', 'stixsans'] + if isinstance(s, str): + s = s.lower() + if s is None or s == 'none': + return None + elif s.lower() in _fallback_fonts: + return s + else: + raise ValueError( + f"{s} is not a valid fallback font name. Valid fallback font " + f"names are {','.join(_fallback_fonts)}. Passing 'None' will turn " + "fallback off.") + + +def validate_whiskers(s): + try: + return _listify_validator(validate_float, n=2)(s) + except (TypeError, ValueError): + try: + return float(s) + except ValueError as e: + raise ValueError("Not a valid whisker value [float, " + "(float, float)]") from e + + +def validate_ps_distiller(s): + if isinstance(s, str): + s = s.lower() + if s in ('none', None, 'false', False): + return None + else: + return ValidateInStrings('ps.usedistiller', ['ghostscript', 'xpdf'])(s) + + +def _validate_papersize(s): + # Re-inline this validator when the 'auto' deprecation expires. + s = ValidateInStrings("ps.papersize", + ["figure", "auto", "letter", "legal", "ledger", + *[f"{ab}{i}" for ab in "ab" for i in range(11)]], + ignorecase=True)(s) + if s == "auto": + _api.warn_deprecated("3.8", name="ps.papersize='auto'", + addendum="Pass an explicit paper type, figure, or omit " + "the *ps.papersize* rcParam entirely.") + return s + + +# A validator dedicated to the named line styles, based on the items in +# ls_mapper, and a list of possible strings read from Line2D.set_linestyle +_validate_named_linestyle = ValidateInStrings( + 'linestyle', + [*ls_mapper.keys(), *ls_mapper.values(), 'None', 'none', ' ', ''], + ignorecase=True) + + +def _validate_linestyle(ls): + """ + A validator for all possible line styles, the named ones *and* + the on-off ink sequences. + """ + if isinstance(ls, str): + try: # Look first for a valid named line style, like '--' or 'solid'. + return _validate_named_linestyle(ls) + except ValueError: + pass + try: + ls = ast.literal_eval(ls) # Parsing matplotlibrc. + except (SyntaxError, ValueError): + pass # Will error with the ValueError at the end. + + def _is_iterable_not_string_like(x): + # Explicitly exclude bytes/bytearrays so that they are not + # nonsensically interpreted as sequences of numbers (codepoints). + return np.iterable(x) and not isinstance(x, (str, bytes, bytearray)) + + if _is_iterable_not_string_like(ls): + if len(ls) == 2 and _is_iterable_not_string_like(ls[1]): + # (offset, (on, off, on, off, ...)) + offset, onoff = ls + else: + # For backcompat: (on, off, on, off, ...); the offset is implicit. + offset = 0 + onoff = ls + + if (isinstance(offset, Real) + and len(onoff) % 2 == 0 + and all(isinstance(elem, Real) for elem in onoff)): + return (offset, onoff) + + raise ValueError(f"linestyle {ls!r} is not a valid on-off ink sequence.") + + +validate_fillstyle = ValidateInStrings( + 'markers.fillstyle', ['full', 'left', 'right', 'bottom', 'top', 'none']) + + +validate_fillstylelist = _listify_validator(validate_fillstyle) + + +def validate_markevery(s): + """ + Validate the markevery property of a Line2D object. + + Parameters + ---------- + s : None, int, (int, int), slice, float, (float, float), or list[int] + + Returns + ------- + None, int, (int, int), slice, float, (float, float), or list[int] + """ + # Validate s against type slice float int and None + if isinstance(s, (slice, float, int, type(None))): + return s + # Validate s against type tuple + if isinstance(s, tuple): + if (len(s) == 2 + and (all(isinstance(e, int) for e in s) + or all(isinstance(e, float) for e in s))): + return s + else: + raise TypeError( + "'markevery' tuple must be pair of ints or of floats") + # Validate s against type list + if isinstance(s, list): + if all(isinstance(e, int) for e in s): + return s + else: + raise TypeError( + "'markevery' list must have all elements of type int") + raise TypeError("'markevery' is of an invalid type") + + +validate_markeverylist = _listify_validator(validate_markevery) + + +def validate_bbox(s): + if isinstance(s, str): + s = s.lower() + if s == 'tight': + return s + if s == 'standard': + return None + raise ValueError("bbox should be 'tight' or 'standard'") + elif s is not None: + # Backwards compatibility. None is equivalent to 'standard'. + raise ValueError("bbox should be 'tight' or 'standard'") + return s + + +def validate_sketch(s): + if isinstance(s, str): + s = s.lower() + if s == 'none' or s is None: + return None + try: + return tuple(_listify_validator(validate_float, n=3)(s)) + except ValueError: + raise ValueError("Expected a (scale, length, randomness) triplet") + + +def _validate_greaterthan_minushalf(s): + s = validate_float(s) + if s > -0.5: + return s + else: + raise RuntimeError(f'Value must be >-0.5; got {s}') + + +def _validate_greaterequal0_lessequal1(s): + s = validate_float(s) + if 0 <= s <= 1: + return s + else: + raise RuntimeError(f'Value must be >=0 and <=1; got {s}') + + +def _validate_int_greaterequal0(s): + s = validate_int(s) + if s >= 0: + return s + else: + raise RuntimeError(f'Value must be >=0; got {s}') + + +def validate_hatch(s): + r""" + Validate a hatch pattern. + A hatch pattern string can have any sequence of the following + characters: ``\ / | - + * . x o O``. + """ + if not isinstance(s, str): + raise ValueError("Hatch pattern must be a string") + _api.check_isinstance(str, hatch_pattern=s) + unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'} + if unknown: + raise ValueError("Unknown hatch symbol(s): %s" % list(unknown)) + return s + + +validate_hatchlist = _listify_validator(validate_hatch) +validate_dashlist = _listify_validator(validate_floatlist) + + +def _validate_minor_tick_ndivs(n): + """ + Validate ndiv parameter related to the minor ticks. + It controls the number of minor ticks to be placed between + two major ticks. + """ + + if isinstance(n, str) and n.lower() == 'auto': + return n + try: + n = _validate_int_greaterequal0(n) + return n + except (RuntimeError, ValueError): + pass + + raise ValueError("'tick.minor.ndivs' must be 'auto' or non-negative int") + + +_prop_validators = { + 'color': _listify_validator(validate_color_for_prop_cycle, + allow_stringlist=True), + 'linewidth': validate_floatlist, + 'linestyle': _listify_validator(_validate_linestyle), + 'facecolor': validate_colorlist, + 'edgecolor': validate_colorlist, + 'joinstyle': _listify_validator(JoinStyle), + 'capstyle': _listify_validator(CapStyle), + 'fillstyle': validate_fillstylelist, + 'markerfacecolor': validate_colorlist, + 'markersize': validate_floatlist, + 'markeredgewidth': validate_floatlist, + 'markeredgecolor': validate_colorlist, + 'markevery': validate_markeverylist, + 'alpha': validate_floatlist, + 'marker': validate_stringlist, + 'hatch': validate_hatchlist, + 'dashes': validate_dashlist, + } +_prop_aliases = { + 'c': 'color', + 'lw': 'linewidth', + 'ls': 'linestyle', + 'fc': 'facecolor', + 'ec': 'edgecolor', + 'mfc': 'markerfacecolor', + 'mec': 'markeredgecolor', + 'mew': 'markeredgewidth', + 'ms': 'markersize', + } + + +def cycler(*args, **kwargs): + """ + Create a `~cycler.Cycler` object much like :func:`cycler.cycler`, + but includes input validation. + + Call signatures:: + + cycler(cycler) + cycler(label=values[, label2=values2[, ...]]) + cycler(label, values) + + Form 1 copies a given `~cycler.Cycler` object. + + Form 2 creates a `~cycler.Cycler` which cycles over one or more + properties simultaneously. If multiple properties are given, their + value lists must have the same length. + + Form 3 creates a `~cycler.Cycler` for a single property. This form + exists for compatibility with the original cycler. Its use is + discouraged in favor of the kwarg form, i.e. ``cycler(label=values)``. + + Parameters + ---------- + cycler : Cycler + Copy constructor for Cycler. + + label : str + The property key. Must be a valid `.Artist` property. + For example, 'color' or 'linestyle'. Aliases are allowed, + such as 'c' for 'color' and 'lw' for 'linewidth'. + + values : iterable + Finite-length iterable of the property values. These values + are validated and will raise a ValueError if invalid. + + Returns + ------- + Cycler + A new :class:`~cycler.Cycler` for the given properties. + + Examples + -------- + Creating a cycler for a single property: + + >>> c = cycler(color=['red', 'green', 'blue']) + + Creating a cycler for simultaneously cycling over multiple properties + (e.g. red circle, green plus, blue cross): + + >>> c = cycler(color=['red', 'green', 'blue'], + ... marker=['o', '+', 'x']) + + """ + if args and kwargs: + raise TypeError("cycler() can only accept positional OR keyword " + "arguments -- not both.") + elif not args and not kwargs: + raise TypeError("cycler() must have positional OR keyword arguments") + + if len(args) == 1: + if not isinstance(args[0], Cycler): + raise TypeError("If only one positional argument given, it must " + "be a Cycler instance.") + return validate_cycler(args[0]) + elif len(args) == 2: + pairs = [(args[0], args[1])] + elif len(args) > 2: + raise _api.nargs_error('cycler', '0-2', len(args)) + else: + pairs = kwargs.items() + + validated = [] + for prop, vals in pairs: + norm_prop = _prop_aliases.get(prop, prop) + validator = _prop_validators.get(norm_prop, None) + if validator is None: + raise TypeError("Unknown artist property: %s" % prop) + vals = validator(vals) + # We will normalize the property names as well to reduce + # the amount of alias handling code elsewhere. + validated.append((norm_prop, vals)) + + return reduce(operator.add, (ccycler(k, v) for k, v in validated)) + + +class _DunderChecker(ast.NodeVisitor): + def visit_Attribute(self, node): + if node.attr.startswith("__") and node.attr.endswith("__"): + raise ValueError("cycler strings with dunders are forbidden") + self.generic_visit(node) + + +# A validator dedicated to the named legend loc +_validate_named_legend_loc = ValidateInStrings( + 'legend.loc', + [ + "best", + "upper right", "upper left", "lower left", "lower right", "right", + "center left", "center right", "lower center", "upper center", + "center"], + ignorecase=True) + + +def _validate_legend_loc(loc): + """ + Confirm that loc is a type which rc.Params["legend.loc"] supports. + + .. versionadded:: 3.8 + + Parameters + ---------- + loc : str | int | (float, float) | str((float, float)) + The location of the legend. + + Returns + ------- + loc : str | int | (float, float) or raise ValueError exception + The location of the legend. + """ + if isinstance(loc, str): + try: + return _validate_named_legend_loc(loc) + except ValueError: + pass + try: + loc = ast.literal_eval(loc) + except (SyntaxError, ValueError): + pass + if isinstance(loc, int): + if 0 <= loc <= 10: + return loc + if isinstance(loc, tuple): + if len(loc) == 2 and all(isinstance(e, Real) for e in loc): + return loc + raise ValueError(f"{loc} is not a valid legend location.") + + +def validate_cycler(s): + """Return a Cycler object from a string repr or the object itself.""" + if isinstance(s, str): + # TODO: We might want to rethink this... + # While I think I have it quite locked down, it is execution of + # arbitrary code without sanitation. + # Combine this with the possibility that rcparams might come from the + # internet (future plans), this could be downright dangerous. + # I locked it down by only having the 'cycler()' function available. + # UPDATE: Partly plugging a security hole. + # I really should have read this: + # https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + # We should replace this eval with a combo of PyParsing and + # ast.literal_eval() + try: + _DunderChecker().visit(ast.parse(s)) + s = eval(s, {'cycler': cycler, '__builtins__': {}}) + except BaseException as e: + raise ValueError(f"{s!r} is not a valid cycler construction: {e}" + ) from e + # Should make sure what comes from the above eval() + # is a Cycler object. + if isinstance(s, Cycler): + cycler_inst = s + else: + raise ValueError(f"Object is not a string or Cycler instance: {s!r}") + + unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases)) + if unknowns: + raise ValueError("Unknown artist properties: %s" % unknowns) + + # Not a full validation, but it'll at least normalize property names + # A fuller validation would require v0.10 of cycler. + checker = set() + for prop in cycler_inst.keys: + norm_prop = _prop_aliases.get(prop, prop) + if norm_prop != prop and norm_prop in cycler_inst.keys: + raise ValueError(f"Cannot specify both {norm_prop!r} and alias " + f"{prop!r} in the same prop_cycle") + if norm_prop in checker: + raise ValueError(f"Another property was already aliased to " + f"{norm_prop!r}. Collision normalizing {prop!r}.") + checker.update([norm_prop]) + + # This is just an extra-careful check, just in case there is some + # edge-case I haven't thought of. + assert len(checker) == len(cycler_inst.keys) + + # Now, it should be safe to mutate this cycler + for prop in cycler_inst.keys: + norm_prop = _prop_aliases.get(prop, prop) + cycler_inst.change_key(prop, norm_prop) + + for key, vals in cycler_inst.by_key().items(): + _prop_validators[key](vals) + + return cycler_inst + + +def validate_hist_bins(s): + valid_strs = ["auto", "sturges", "fd", "doane", "scott", "rice", "sqrt"] + if isinstance(s, str) and s in valid_strs: + return s + try: + return int(s) + except (TypeError, ValueError): + pass + try: + return validate_floatlist(s) + except ValueError: + pass + raise ValueError(f"'hist.bins' must be one of {valid_strs}, an int or" + " a sequence of floats") + + +class _ignorecase(list): + """A marker class indicating that a list-of-str is case-insensitive.""" + + +def _convert_validator_spec(key, conv): + if isinstance(conv, list): + ignorecase = isinstance(conv, _ignorecase) + return ValidateInStrings(key, conv, ignorecase=ignorecase) + else: + return conv + + +# Mapping of rcParams to validators. +# Converters given as lists or _ignorecase are converted to ValidateInStrings +# immediately below. +# The rcParams defaults are defined in lib/matplotlib/mpl-data/matplotlibrc, which +# gets copied to matplotlib/mpl-data/matplotlibrc by the setup script. +_validators = { + "backend": validate_backend, + "backend_fallback": validate_bool, + "figure.hooks": validate_stringlist, + "toolbar": _validate_toolbar, + "interactive": validate_bool, + "timezone": validate_string, + + "webagg.port": validate_int, + "webagg.address": validate_string, + "webagg.open_in_browser": validate_bool, + "webagg.port_retries": validate_int, + + # line props + "lines.linewidth": validate_float, # line width in points + "lines.linestyle": _validate_linestyle, # solid line + "lines.color": validate_color, # first color in color cycle + "lines.marker": validate_string, # marker name + "lines.markerfacecolor": validate_color_or_auto, # default color + "lines.markeredgecolor": validate_color_or_auto, # default color + "lines.markeredgewidth": validate_float, + "lines.markersize": validate_float, # markersize, in points + "lines.antialiased": validate_bool, # antialiased (no jaggies) + "lines.dash_joinstyle": JoinStyle, + "lines.solid_joinstyle": JoinStyle, + "lines.dash_capstyle": CapStyle, + "lines.solid_capstyle": CapStyle, + "lines.dashed_pattern": validate_floatlist, + "lines.dashdot_pattern": validate_floatlist, + "lines.dotted_pattern": validate_floatlist, + "lines.scale_dashes": validate_bool, + + # marker props + "markers.fillstyle": validate_fillstyle, + + ## pcolor(mesh) props: + "pcolor.shading": ["auto", "flat", "nearest", "gouraud"], + "pcolormesh.snap": validate_bool, + + ## patch props + "patch.linewidth": validate_float, # line width in points + "patch.edgecolor": validate_color, + "patch.force_edgecolor": validate_bool, + "patch.facecolor": validate_color, # first color in cycle + "patch.antialiased": validate_bool, # antialiased (no jaggies) + + ## hatch props + "hatch.color": validate_color, + "hatch.linewidth": validate_float, + + ## Histogram properties + "hist.bins": validate_hist_bins, + + ## Boxplot properties + "boxplot.notch": validate_bool, + "boxplot.vertical": validate_bool, + "boxplot.whiskers": validate_whiskers, + "boxplot.bootstrap": validate_int_or_None, + "boxplot.patchartist": validate_bool, + "boxplot.showmeans": validate_bool, + "boxplot.showcaps": validate_bool, + "boxplot.showbox": validate_bool, + "boxplot.showfliers": validate_bool, + "boxplot.meanline": validate_bool, + + "boxplot.flierprops.color": validate_color, + "boxplot.flierprops.marker": validate_string, + "boxplot.flierprops.markerfacecolor": validate_color_or_auto, + "boxplot.flierprops.markeredgecolor": validate_color, + "boxplot.flierprops.markeredgewidth": validate_float, + "boxplot.flierprops.markersize": validate_float, + "boxplot.flierprops.linestyle": _validate_linestyle, + "boxplot.flierprops.linewidth": validate_float, + + "boxplot.boxprops.color": validate_color, + "boxplot.boxprops.linewidth": validate_float, + "boxplot.boxprops.linestyle": _validate_linestyle, + + "boxplot.whiskerprops.color": validate_color, + "boxplot.whiskerprops.linewidth": validate_float, + "boxplot.whiskerprops.linestyle": _validate_linestyle, + + "boxplot.capprops.color": validate_color, + "boxplot.capprops.linewidth": validate_float, + "boxplot.capprops.linestyle": _validate_linestyle, + + "boxplot.medianprops.color": validate_color, + "boxplot.medianprops.linewidth": validate_float, + "boxplot.medianprops.linestyle": _validate_linestyle, + + "boxplot.meanprops.color": validate_color, + "boxplot.meanprops.marker": validate_string, + "boxplot.meanprops.markerfacecolor": validate_color, + "boxplot.meanprops.markeredgecolor": validate_color, + "boxplot.meanprops.markersize": validate_float, + "boxplot.meanprops.linestyle": _validate_linestyle, + "boxplot.meanprops.linewidth": validate_float, + + ## font props + "font.family": validate_stringlist, # used by text object + "font.style": validate_string, + "font.variant": validate_string, + "font.stretch": validate_fontstretch, + "font.weight": validate_fontweight, + "font.size": validate_float, # Base font size in points + "font.serif": validate_stringlist, + "font.sans-serif": validate_stringlist, + "font.cursive": validate_stringlist, + "font.fantasy": validate_stringlist, + "font.monospace": validate_stringlist, + + # text props + "text.color": validate_color, + "text.usetex": validate_bool, + "text.latex.preamble": validate_string, + "text.hinting": ["default", "no_autohint", "force_autohint", + "no_hinting", "auto", "native", "either", "none"], + "text.hinting_factor": validate_int, + "text.kerning_factor": validate_int, + "text.antialiased": validate_bool, + "text.parse_math": validate_bool, + + "mathtext.cal": validate_font_properties, + "mathtext.rm": validate_font_properties, + "mathtext.tt": validate_font_properties, + "mathtext.it": validate_font_properties, + "mathtext.bf": validate_font_properties, + "mathtext.bfit": validate_font_properties, + "mathtext.sf": validate_font_properties, + "mathtext.fontset": ["dejavusans", "dejavuserif", "cm", "stix", + "stixsans", "custom"], + "mathtext.default": ["rm", "cal", "bfit", "it", "tt", "sf", "bf", "default", + "bb", "frak", "scr", "regular"], + "mathtext.fallback": _validate_mathtext_fallback, + + "image.aspect": validate_aspect, # equal, auto, a number + "image.interpolation": validate_string, + "image.cmap": _validate_cmap, # gray, jet, etc. + "image.lut": validate_int, # lookup table + "image.origin": ["upper", "lower"], + "image.resample": validate_bool, + # Specify whether vector graphics backends will combine all images on a + # set of axes into a single composite image + "image.composite_image": validate_bool, + + # contour props + "contour.negative_linestyle": _validate_linestyle, + "contour.corner_mask": validate_bool, + "contour.linewidth": validate_float_or_None, + "contour.algorithm": ["mpl2005", "mpl2014", "serial", "threaded"], + + # errorbar props + "errorbar.capsize": validate_float, + + # axis props + # alignment of x/y axis title + "xaxis.labellocation": ["left", "center", "right"], + "yaxis.labellocation": ["bottom", "center", "top"], + + # axes props + "axes.axisbelow": validate_axisbelow, + "axes.facecolor": validate_color, # background color + "axes.edgecolor": validate_color, # edge color + "axes.linewidth": validate_float, # edge linewidth + + "axes.spines.left": validate_bool, # Set visibility of axes spines, + "axes.spines.right": validate_bool, # i.e., the lines around the chart + "axes.spines.bottom": validate_bool, # denoting data boundary. + "axes.spines.top": validate_bool, + + "axes.titlesize": validate_fontsize, # axes title fontsize + "axes.titlelocation": ["left", "center", "right"], # axes title alignment + "axes.titleweight": validate_fontweight, # axes title font weight + "axes.titlecolor": validate_color_or_auto, # axes title font color + # title location, axes units, None means auto + "axes.titley": validate_float_or_None, + # pad from axes top decoration to title in points + "axes.titlepad": validate_float, + "axes.grid": validate_bool, # display grid or not + "axes.grid.which": ["minor", "both", "major"], # which grids are drawn + "axes.grid.axis": ["x", "y", "both"], # grid type + "axes.labelsize": validate_fontsize, # fontsize of x & y labels + "axes.labelpad": validate_float, # space between label and axis + "axes.labelweight": validate_fontweight, # fontsize of x & y labels + "axes.labelcolor": validate_color, # color of axis label + # use scientific notation if log10 of the axis range is smaller than the + # first or larger than the second + "axes.formatter.limits": _listify_validator(validate_int, n=2), + # use current locale to format ticks + "axes.formatter.use_locale": validate_bool, + "axes.formatter.use_mathtext": validate_bool, + # minimum exponent to format in scientific notation + "axes.formatter.min_exponent": validate_int, + "axes.formatter.useoffset": validate_bool, + "axes.formatter.offset_threshold": validate_int, + "axes.unicode_minus": validate_bool, + # This entry can be either a cycler object or a string repr of a + # cycler-object, which gets eval()'ed to create the object. + "axes.prop_cycle": validate_cycler, + # If "data", axes limits are set close to the data. + # If "round_numbers" axes limits are set to the nearest round numbers. + "axes.autolimit_mode": ["data", "round_numbers"], + "axes.xmargin": _validate_greaterthan_minushalf, # margin added to xaxis + "axes.ymargin": _validate_greaterthan_minushalf, # margin added to yaxis + "axes.zmargin": _validate_greaterthan_minushalf, # margin added to zaxis + + "polaraxes.grid": validate_bool, # display polar grid or not + "axes3d.grid": validate_bool, # display 3d grid + + "axes3d.xaxis.panecolor": validate_color, # 3d background pane + "axes3d.yaxis.panecolor": validate_color, # 3d background pane + "axes3d.zaxis.panecolor": validate_color, # 3d background pane + + # scatter props + "scatter.marker": validate_string, + "scatter.edgecolors": validate_string, + + "date.epoch": _validate_date, + "date.autoformatter.year": validate_string, + "date.autoformatter.month": validate_string, + "date.autoformatter.day": validate_string, + "date.autoformatter.hour": validate_string, + "date.autoformatter.minute": validate_string, + "date.autoformatter.second": validate_string, + "date.autoformatter.microsecond": validate_string, + + 'date.converter': ['auto', 'concise'], + # for auto date locator, choose interval_multiples + 'date.interval_multiples': validate_bool, + + # legend properties + "legend.fancybox": validate_bool, + "legend.loc": _validate_legend_loc, + + # the number of points in the legend line + "legend.numpoints": validate_int, + # the number of points in the legend line for scatter + "legend.scatterpoints": validate_int, + "legend.fontsize": validate_fontsize, + "legend.title_fontsize": validate_fontsize_None, + # color of the legend + "legend.labelcolor": _validate_color_or_linecolor, + # the relative size of legend markers vs. original + "legend.markerscale": validate_float, + # using dict in rcParams not yet supported, so make sure it is bool + "legend.shadow": validate_bool, + # whether or not to draw a frame around legend + "legend.frameon": validate_bool, + # alpha value of the legend frame + "legend.framealpha": validate_float_or_None, + + ## the following dimensions are in fraction of the font size + "legend.borderpad": validate_float, # units are fontsize + # the vertical space between the legend entries + "legend.labelspacing": validate_float, + # the length of the legend lines + "legend.handlelength": validate_float, + # the length of the legend lines + "legend.handleheight": validate_float, + # the space between the legend line and legend text + "legend.handletextpad": validate_float, + # the border between the axes and legend edge + "legend.borderaxespad": validate_float, + # the border between the axes and legend edge + "legend.columnspacing": validate_float, + "legend.facecolor": validate_color_or_inherit, + "legend.edgecolor": validate_color_or_inherit, + + # tick properties + "xtick.top": validate_bool, # draw ticks on top side + "xtick.bottom": validate_bool, # draw ticks on bottom side + "xtick.labeltop": validate_bool, # draw label on top + "xtick.labelbottom": validate_bool, # draw label on bottom + "xtick.major.size": validate_float, # major xtick size in points + "xtick.minor.size": validate_float, # minor xtick size in points + "xtick.major.width": validate_float, # major xtick width in points + "xtick.minor.width": validate_float, # minor xtick width in points + "xtick.major.pad": validate_float, # distance to label in points + "xtick.minor.pad": validate_float, # distance to label in points + "xtick.color": validate_color, # color of xticks + "xtick.labelcolor": validate_color_or_inherit, # color of xtick labels + "xtick.minor.visible": validate_bool, # visibility of minor xticks + "xtick.minor.top": validate_bool, # draw top minor xticks + "xtick.minor.bottom": validate_bool, # draw bottom minor xticks + "xtick.major.top": validate_bool, # draw top major xticks + "xtick.major.bottom": validate_bool, # draw bottom major xticks + # number of minor xticks + "xtick.minor.ndivs": _validate_minor_tick_ndivs, + "xtick.labelsize": validate_fontsize, # fontsize of xtick labels + "xtick.direction": ["out", "in", "inout"], # direction of xticks + "xtick.alignment": ["center", "right", "left"], + + "ytick.left": validate_bool, # draw ticks on left side + "ytick.right": validate_bool, # draw ticks on right side + "ytick.labelleft": validate_bool, # draw tick labels on left side + "ytick.labelright": validate_bool, # draw tick labels on right side + "ytick.major.size": validate_float, # major ytick size in points + "ytick.minor.size": validate_float, # minor ytick size in points + "ytick.major.width": validate_float, # major ytick width in points + "ytick.minor.width": validate_float, # minor ytick width in points + "ytick.major.pad": validate_float, # distance to label in points + "ytick.minor.pad": validate_float, # distance to label in points + "ytick.color": validate_color, # color of yticks + "ytick.labelcolor": validate_color_or_inherit, # color of ytick labels + "ytick.minor.visible": validate_bool, # visibility of minor yticks + "ytick.minor.left": validate_bool, # draw left minor yticks + "ytick.minor.right": validate_bool, # draw right minor yticks + "ytick.major.left": validate_bool, # draw left major yticks + "ytick.major.right": validate_bool, # draw right major yticks + # number of minor yticks + "ytick.minor.ndivs": _validate_minor_tick_ndivs, + "ytick.labelsize": validate_fontsize, # fontsize of ytick labels + "ytick.direction": ["out", "in", "inout"], # direction of yticks + "ytick.alignment": [ + "center", "top", "bottom", "baseline", "center_baseline"], + + "grid.color": validate_color, # grid color + "grid.linestyle": _validate_linestyle, # solid + "grid.linewidth": validate_float, # in points + "grid.alpha": validate_float, + + ## figure props + # figure title + "figure.titlesize": validate_fontsize, + "figure.titleweight": validate_fontweight, + + # figure labels + "figure.labelsize": validate_fontsize, + "figure.labelweight": validate_fontweight, + + # figure size in inches: width by height + "figure.figsize": _listify_validator(validate_float, n=2), + "figure.dpi": validate_float, + "figure.facecolor": validate_color, + "figure.edgecolor": validate_color, + "figure.frameon": validate_bool, + "figure.autolayout": validate_bool, + "figure.max_open_warning": validate_int, + "figure.raise_window": validate_bool, + "macosx.window_mode": ["system", "tab", "window"], + + "figure.subplot.left": validate_float, + "figure.subplot.right": validate_float, + "figure.subplot.bottom": validate_float, + "figure.subplot.top": validate_float, + "figure.subplot.wspace": validate_float, + "figure.subplot.hspace": validate_float, + + "figure.constrained_layout.use": validate_bool, # run constrained_layout? + # wspace and hspace are fraction of adjacent subplots to use for space. + # Much smaller than above because we don't need room for the text. + "figure.constrained_layout.hspace": validate_float, + "figure.constrained_layout.wspace": validate_float, + # buffer around the axes, in inches. + "figure.constrained_layout.h_pad": validate_float, + "figure.constrained_layout.w_pad": validate_float, + + ## Saving figure's properties + 'savefig.dpi': validate_dpi, + 'savefig.facecolor': validate_color_or_auto, + 'savefig.edgecolor': validate_color_or_auto, + 'savefig.orientation': ['landscape', 'portrait'], + "savefig.format": validate_string, + "savefig.bbox": validate_bbox, # "tight", or "standard" (= None) + "savefig.pad_inches": validate_float, + # default directory in savefig dialog box + "savefig.directory": _validate_pathlike, + "savefig.transparent": validate_bool, + + "tk.window_focus": validate_bool, # Maintain shell focus for TkAgg + + # Set the papersize/type + "ps.papersize": _validate_papersize, + "ps.useafm": validate_bool, + # use ghostscript or xpdf to distill ps output + "ps.usedistiller": validate_ps_distiller, + "ps.distiller.res": validate_int, # dpi + "ps.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype) + "pdf.compression": validate_int, # 0-9 compression level; 0 to disable + "pdf.inheritcolor": validate_bool, # skip color setting commands + # use only the 14 PDF core fonts embedded in every PDF viewing application + "pdf.use14corefonts": validate_bool, + "pdf.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype) + + "pgf.texsystem": ["xelatex", "lualatex", "pdflatex"], # latex variant used + "pgf.rcfonts": validate_bool, # use mpl's rc settings for font config + "pgf.preamble": validate_string, # custom LaTeX preamble + + # write raster image data into the svg file + "svg.image_inline": validate_bool, + "svg.fonttype": ["none", "path"], # save text as text ("none") or "paths" + "svg.hashsalt": validate_string_or_None, + + # set this when you want to generate hardcopy docstring + "docstring.hardcopy": validate_bool, + + "path.simplify": validate_bool, + "path.simplify_threshold": _validate_greaterequal0_lessequal1, + "path.snap": validate_bool, + "path.sketch": validate_sketch, + "path.effects": validate_anylist, + "agg.path.chunksize": validate_int, # 0 to disable chunking + + # key-mappings (multi-character mappings should be a list/tuple) + "keymap.fullscreen": validate_stringlist, + "keymap.home": validate_stringlist, + "keymap.back": validate_stringlist, + "keymap.forward": validate_stringlist, + "keymap.pan": validate_stringlist, + "keymap.zoom": validate_stringlist, + "keymap.save": validate_stringlist, + "keymap.quit": validate_stringlist, + "keymap.quit_all": validate_stringlist, # e.g.: "W", "cmd+W", "Q" + "keymap.grid": validate_stringlist, + "keymap.grid_minor": validate_stringlist, + "keymap.yscale": validate_stringlist, + "keymap.xscale": validate_stringlist, + "keymap.help": validate_stringlist, + "keymap.copy": validate_stringlist, + + # Animation settings + "animation.html": ["html5", "jshtml", "none"], + # Limit, in MB, of size of base64 encoded animation in HTML + # (i.e. IPython notebook) + "animation.embed_limit": validate_float, + "animation.writer": validate_string, + "animation.codec": validate_string, + "animation.bitrate": validate_int, + # Controls image format when frames are written to disk + "animation.frame_format": ["png", "jpeg", "tiff", "raw", "rgba", "ppm", + "sgi", "bmp", "pbm", "svg"], + # Path to ffmpeg binary. If just binary name, subprocess uses $PATH. + "animation.ffmpeg_path": _validate_pathlike, + # Additional arguments for ffmpeg movie writer (using pipes) + "animation.ffmpeg_args": validate_stringlist, + # Path to convert binary. If just binary name, subprocess uses $PATH. + "animation.convert_path": _validate_pathlike, + # Additional arguments for convert movie writer (using pipes) + "animation.convert_args": validate_stringlist, + + # Classic (pre 2.0) compatibility mode + # This is used for things that are hard to make backward compatible + # with a sane rcParam alone. This does *not* turn on classic mode + # altogether. For that use `matplotlib.style.use("classic")`. + "_internal.classic_mode": validate_bool +} +_hardcoded_defaults = { # Defaults not inferred from + # lib/matplotlib/mpl-data/matplotlibrc... + # ... because they are private: + "_internal.classic_mode": False, + # ... because they are deprecated: + # No current deprecations. + # backend is handled separately when constructing rcParamsDefault. +} +_validators = {k: _convert_validator_spec(k, conv) + for k, conv in _validators.items()} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.pyi new file mode 100644 index 00000000..70e94a76 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/rcsetup.pyi @@ -0,0 +1,157 @@ +from cycler import Cycler + +from collections.abc import Callable, Iterable +from typing import Any, Literal, TypeVar +from matplotlib.typing import ColorType, LineStyleType, MarkEveryType + +interactive_bk: list[str] +non_interactive_bk: list[str] +all_backends: list[str] + +_T = TypeVar("_T") + +def _listify_validator(s: Callable[[Any], _T]) -> Callable[[Any], list[_T]]: ... + +class ValidateInStrings: + key: str + ignorecase: bool + valid: dict[str, str] + def __init__( + self, + key: str, + valid: Iterable[str], + ignorecase: bool = ..., + *, + _deprecated_since: str | None = ... + ) -> None: ... + def __call__(self, s: Any) -> str: ... + +def validate_any(s: Any) -> Any: ... +def validate_anylist(s: Any) -> list[Any]: ... +def validate_bool(b: Any) -> bool: ... +def validate_axisbelow(s: Any) -> bool | Literal["line"]: ... +def validate_dpi(s: Any) -> Literal["figure"] | float: ... +def validate_string(s: Any) -> str: ... +def validate_string_or_None(s: Any) -> str | None: ... +def validate_stringlist(s: Any) -> list[str]: ... +def validate_int(s: Any) -> int: ... +def validate_int_or_None(s: Any) -> int | None: ... +def validate_float(s: Any) -> float: ... +def validate_float_or_None(s: Any) -> float | None: ... +def validate_floatlist(s: Any) -> list[float]: ... +def validate_fonttype(s: Any) -> int: ... + +_auto_backend_sentinel: object + +def validate_backend(s: Any) -> str: ... +def validate_color_or_inherit(s: Any) -> Literal["inherit"] | ColorType: ... +def validate_color_or_auto(s: Any) -> ColorType | Literal["auto"]: ... +def validate_color_for_prop_cycle(s: Any) -> ColorType: ... +def validate_color(s: Any) -> ColorType: ... +def validate_colorlist(s: Any) -> list[ColorType]: ... +def _validate_color_or_linecolor( + s: Any, +) -> ColorType | Literal["linecolor", "markerfacecolor", "markeredgecolor"] | None: ... +def validate_aspect(s: Any) -> Literal["auto", "equal"] | float: ... +def validate_fontsize_None( + s: Any, +) -> Literal[ + "xx-small", + "x-small", + "small", + "medium", + "large", + "x-large", + "xx-large", + "smaller", + "larger", +] | float | None: ... +def validate_fontsize( + s: Any, +) -> Literal[ + "xx-small", + "x-small", + "small", + "medium", + "large", + "x-large", + "xx-large", + "smaller", + "larger", +] | float: ... +def validate_fontsizelist( + s: Any, +) -> list[ + Literal[ + "xx-small", + "x-small", + "small", + "medium", + "large", + "x-large", + "xx-large", + "smaller", + "larger", + ] + | float +]: ... +def validate_fontweight( + s: Any, +) -> Literal[ + "ultralight", + "light", + "normal", + "regular", + "book", + "medium", + "roman", + "semibold", + "demibold", + "demi", + "bold", + "heavy", + "extra bold", + "black", +] | int: ... +def validate_fontstretch( + s: Any, +) -> Literal[ + "ultra-condensed", + "extra-condensed", + "condensed", + "semi-condensed", + "normal", + "semi-expanded", + "expanded", + "extra-expanded", + "ultra-expanded", +] | int: ... +def validate_font_properties(s: Any) -> dict[str, Any]: ... +def validate_whiskers(s: Any) -> list[float] | float: ... +def validate_ps_distiller(s: Any) -> None | Literal["ghostscript", "xpdf"]: ... + +validate_fillstyle: ValidateInStrings + +def validate_fillstylelist( + s: Any, +) -> list[Literal["full", "left", "right", "bottom", "top", "none"]]: ... +def validate_markevery(s: Any) -> MarkEveryType: ... +def _validate_linestyle(s: Any) -> LineStyleType: ... +def validate_markeverylist(s: Any) -> list[MarkEveryType]: ... +def validate_bbox(s: Any) -> Literal["tight", "standard"] | None: ... +def validate_sketch(s: Any) -> None | tuple[float, float, float]: ... +def validate_hatch(s: Any) -> str: ... +def validate_hatchlist(s: Any) -> list[str]: ... +def validate_dashlist(s: Any) -> list[list[float]]: ... + +# TODO: copy cycler overloads? +def cycler(*args, **kwargs) -> Cycler: ... +def validate_cycler(s: Any) -> Cycler: ... +def validate_hist_bins( + s: Any, +) -> Literal["auto", "sturges", "fd", "doane", "scott", "rice", "sqrt"] | int | list[ + float +]: ... + +# At runtime is added in __init__.py +defaultParams: dict[str, Any] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.py new file mode 100644 index 00000000..b626abe3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.py @@ -0,0 +1,814 @@ +""" +Module for creating Sankey diagrams using Matplotlib. +""" + +import logging +from types import SimpleNamespace + +import numpy as np + +import matplotlib as mpl +from matplotlib.path import Path +from matplotlib.patches import PathPatch +from matplotlib.transforms import Affine2D +from matplotlib import _docstring + +_log = logging.getLogger(__name__) + +__author__ = "Kevin L. Davies" +__credits__ = ["Yannick Copin"] +__license__ = "BSD" +__version__ = "2011/09/16" + +# Angles [deg/90] +RIGHT = 0 +UP = 1 +# LEFT = 2 +DOWN = 3 + + +class Sankey: + """ + Sankey diagram. + + Sankey diagrams are a specific type of flow diagram, in which + the width of the arrows is shown proportionally to the flow + quantity. They are typically used to visualize energy or + material or cost transfers between processes. + `Wikipedia (6/1/2011) <https://en.wikipedia.org/wiki/Sankey_diagram>`_ + + """ + + def __init__(self, ax=None, scale=1.0, unit='', format='%G', gap=0.25, + radius=0.1, shoulder=0.03, offset=0.15, head_angle=100, + margin=0.4, tolerance=1e-6, **kwargs): + """ + Create a new Sankey instance. + + The optional arguments listed below are applied to all subdiagrams so + that there is consistent alignment and formatting. + + In order to draw a complex Sankey diagram, create an instance of + `Sankey` by calling it without any kwargs:: + + sankey = Sankey() + + Then add simple Sankey sub-diagrams:: + + sankey.add() # 1 + sankey.add() # 2 + #... + sankey.add() # n + + Finally, create the full diagram:: + + sankey.finish() + + Or, instead, simply daisy-chain those calls:: + + Sankey().add().add... .add().finish() + + Other Parameters + ---------------- + ax : `~matplotlib.axes.Axes` + Axes onto which the data should be plotted. If *ax* isn't + provided, new Axes will be created. + scale : float + Scaling factor for the flows. *scale* sizes the width of the paths + in order to maintain proper layout. The same scale is applied to + all subdiagrams. The value should be chosen such that the product + of the scale and the sum of the inputs is approximately 1.0 (and + the product of the scale and the sum of the outputs is + approximately -1.0). + unit : str + The physical unit associated with the flow quantities. If *unit* + is None, then none of the quantities are labeled. + format : str or callable + A Python number formatting string or callable used to label the + flows with their quantities (i.e., a number times a unit, where the + unit is given). If a format string is given, the label will be + ``format % quantity``. If a callable is given, it will be called + with ``quantity`` as an argument. + gap : float + Space between paths that break in/break away to/from the top or + bottom. + radius : float + Inner radius of the vertical paths. + shoulder : float + Size of the shoulders of output arrows. + offset : float + Text offset (from the dip or tip of the arrow). + head_angle : float + Angle, in degrees, of the arrow heads (and negative of the angle of + the tails). + margin : float + Minimum space between Sankey outlines and the edge of the plot + area. + tolerance : float + Acceptable maximum of the magnitude of the sum of flows. The + magnitude of the sum of connected flows cannot be greater than + *tolerance*. + **kwargs + Any additional keyword arguments will be passed to `add`, which + will create the first subdiagram. + + See Also + -------- + Sankey.add + Sankey.finish + + Examples + -------- + .. plot:: gallery/specialty_plots/sankey_basics.py + """ + # Check the arguments. + if gap < 0: + raise ValueError( + "'gap' is negative, which is not allowed because it would " + "cause the paths to overlap") + if radius > gap: + raise ValueError( + "'radius' is greater than 'gap', which is not allowed because " + "it would cause the paths to overlap") + if head_angle < 0: + raise ValueError( + "'head_angle' is negative, which is not allowed because it " + "would cause inputs to look like outputs and vice versa") + if tolerance < 0: + raise ValueError( + "'tolerance' is negative, but it must be a magnitude") + + # Create axes if necessary. + if ax is None: + import matplotlib.pyplot as plt + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[]) + + self.diagrams = [] + + # Store the inputs. + self.ax = ax + self.unit = unit + self.format = format + self.scale = scale + self.gap = gap + self.radius = radius + self.shoulder = shoulder + self.offset = offset + self.margin = margin + self.pitch = np.tan(np.pi * (1 - head_angle / 180.0) / 2.0) + self.tolerance = tolerance + + # Initialize the vertices of tight box around the diagram(s). + self.extent = np.array((np.inf, -np.inf, np.inf, -np.inf)) + + # If there are any kwargs, create the first subdiagram. + if len(kwargs): + self.add(**kwargs) + + def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)): + """ + Return the codes and vertices for a rotated, scaled, and translated + 90 degree arc. + + Other Parameters + ---------------- + quadrant : {0, 1, 2, 3}, default: 0 + Uses 0-based indexing (0, 1, 2, or 3). + cw : bool, default: True + If True, the arc vertices are produced clockwise; counter-clockwise + otherwise. + radius : float, default: 1 + The radius of the arc. + center : (float, float), default: (0, 0) + (x, y) tuple of the arc's center. + """ + # Note: It would be possible to use matplotlib's transforms to rotate, + # scale, and translate the arc, but since the angles are discrete, + # it's just as easy and maybe more efficient to do it here. + ARC_CODES = [Path.LINETO, + Path.CURVE4, + Path.CURVE4, + Path.CURVE4, + Path.CURVE4, + Path.CURVE4, + Path.CURVE4] + # Vertices of a cubic Bezier curve approximating a 90 deg arc + # These can be determined by Path.arc(0, 90). + ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00], + [1.00000000e+00, 2.65114773e-01], + [8.94571235e-01, 5.19642327e-01], + [7.07106781e-01, 7.07106781e-01], + [5.19642327e-01, 8.94571235e-01], + [2.65114773e-01, 1.00000000e+00], + # Insignificant + # [6.12303177e-17, 1.00000000e+00]]) + [0.00000000e+00, 1.00000000e+00]]) + if quadrant in (0, 2): + if cw: + vertices = ARC_VERTICES + else: + vertices = ARC_VERTICES[:, ::-1] # Swap x and y. + else: # 1, 3 + # Negate x. + if cw: + # Swap x and y. + vertices = np.column_stack((-ARC_VERTICES[:, 1], + ARC_VERTICES[:, 0])) + else: + vertices = np.column_stack((-ARC_VERTICES[:, 0], + ARC_VERTICES[:, 1])) + if quadrant > 1: + radius = -radius # Rotate 180 deg. + return list(zip(ARC_CODES, radius * vertices + + np.tile(center, (ARC_VERTICES.shape[0], 1)))) + + def _add_input(self, path, angle, flow, length): + """ + Add an input to a path and return its tip and label locations. + """ + if angle is None: + return [0, 0], [0, 0] + else: + x, y = path[-1][1] # Use the last point as a reference. + dipdepth = (flow / 2) * self.pitch + if angle == RIGHT: + x -= length + dip = [x + dipdepth, y + flow / 2.0] + path.extend([(Path.LINETO, [x, y]), + (Path.LINETO, dip), + (Path.LINETO, [x, y + flow]), + (Path.LINETO, [x + self.gap, y + flow])]) + label_location = [dip[0] - self.offset, dip[1]] + else: # Vertical + x -= self.gap + if angle == UP: + sign = 1 + else: + sign = -1 + + dip = [x - flow / 2, y - sign * (length - dipdepth)] + if angle == DOWN: + quadrant = 2 + else: + quadrant = 1 + + # Inner arc isn't needed if inner radius is zero + if self.radius: + path.extend(self._arc(quadrant=quadrant, + cw=angle == UP, + radius=self.radius, + center=(x + self.radius, + y - sign * self.radius))) + else: + path.append((Path.LINETO, [x, y])) + path.extend([(Path.LINETO, [x, y - sign * length]), + (Path.LINETO, dip), + (Path.LINETO, [x - flow, y - sign * length])]) + path.extend(self._arc(quadrant=quadrant, + cw=angle == DOWN, + radius=flow + self.radius, + center=(x + self.radius, + y - sign * self.radius))) + path.append((Path.LINETO, [x - flow, y + sign * flow])) + label_location = [dip[0], dip[1] - sign * self.offset] + + return dip, label_location + + def _add_output(self, path, angle, flow, length): + """ + Append an output to a path and return its tip and label locations. + + .. note:: *flow* is negative for an output. + """ + if angle is None: + return [0, 0], [0, 0] + else: + x, y = path[-1][1] # Use the last point as a reference. + tipheight = (self.shoulder - flow / 2) * self.pitch + if angle == RIGHT: + x += length + tip = [x + tipheight, y + flow / 2.0] + path.extend([(Path.LINETO, [x, y]), + (Path.LINETO, [x, y + self.shoulder]), + (Path.LINETO, tip), + (Path.LINETO, [x, y - self.shoulder + flow]), + (Path.LINETO, [x, y + flow]), + (Path.LINETO, [x - self.gap, y + flow])]) + label_location = [tip[0] + self.offset, tip[1]] + else: # Vertical + x += self.gap + if angle == UP: + sign, quadrant = 1, 3 + else: + sign, quadrant = -1, 0 + + tip = [x - flow / 2.0, y + sign * (length + tipheight)] + # Inner arc isn't needed if inner radius is zero + if self.radius: + path.extend(self._arc(quadrant=quadrant, + cw=angle == UP, + radius=self.radius, + center=(x - self.radius, + y + sign * self.radius))) + else: + path.append((Path.LINETO, [x, y])) + path.extend([(Path.LINETO, [x, y + sign * length]), + (Path.LINETO, [x - self.shoulder, + y + sign * length]), + (Path.LINETO, tip), + (Path.LINETO, [x + self.shoulder - flow, + y + sign * length]), + (Path.LINETO, [x - flow, y + sign * length])]) + path.extend(self._arc(quadrant=quadrant, + cw=angle == DOWN, + radius=self.radius - flow, + center=(x - self.radius, + y + sign * self.radius))) + path.append((Path.LINETO, [x - flow, y + sign * flow])) + label_location = [tip[0], tip[1] + sign * self.offset] + return tip, label_location + + def _revert(self, path, first_action=Path.LINETO): + """ + A path is not simply reversible by path[::-1] since the code + specifies an action to take from the **previous** point. + """ + reverse_path = [] + next_code = first_action + for code, position in path[::-1]: + reverse_path.append((next_code, position)) + next_code = code + return reverse_path + # This might be more efficient, but it fails because 'tuple' object + # doesn't support item assignment: + # path[1] = path[1][-1:0:-1] + # path[1][0] = first_action + # path[2] = path[2][::-1] + # return path + + @_docstring.dedent_interpd + def add(self, patchlabel='', flows=None, orientations=None, labels='', + trunklength=1.0, pathlengths=0.25, prior=None, connect=(0, 0), + rotation=0, **kwargs): + """ + Add a simple Sankey diagram with flows at the same hierarchical level. + + Parameters + ---------- + patchlabel : str + Label to be placed at the center of the diagram. + Note that *label* (not *patchlabel*) can be passed as keyword + argument to create an entry in the legend. + + flows : list of float + Array of flow values. By convention, inputs are positive and + outputs are negative. + + Flows are placed along the top of the diagram from the inside out + in order of their index within *flows*. They are placed along the + sides of the diagram from the top down and along the bottom from + the outside in. + + If the sum of the inputs and outputs is + nonzero, the discrepancy will appear as a cubic Bézier curve along + the top and bottom edges of the trunk. + + orientations : list of {-1, 0, 1} + List of orientations of the flows (or a single orientation to be + used for all flows). Valid values are 0 (inputs from + the left, outputs to the right), 1 (from and to the top) or -1 + (from and to the bottom). + + labels : list of (str or None) + List of labels for the flows (or a single label to be used for all + flows). Each label may be *None* (no label), or a labeling string. + If an entry is a (possibly empty) string, then the quantity for the + corresponding flow will be shown below the string. However, if + the *unit* of the main diagram is None, then quantities are never + shown, regardless of the value of this argument. + + trunklength : float + Length between the bases of the input and output groups (in + data-space units). + + pathlengths : list of float + List of lengths of the vertical arrows before break-in or after + break-away. If a single value is given, then it will be applied to + the first (inside) paths on the top and bottom, and the length of + all other arrows will be justified accordingly. The *pathlengths* + are not applied to the horizontal inputs and outputs. + + prior : int + Index of the prior diagram to which this diagram should be + connected. + + connect : (int, int) + A (prior, this) tuple indexing the flow of the prior diagram and + the flow of this diagram which should be connected. If this is the + first diagram or *prior* is *None*, *connect* will be ignored. + + rotation : float + Angle of rotation of the diagram in degrees. The interpretation of + the *orientations* argument will be rotated accordingly (e.g., if + *rotation* == 90, an *orientations* entry of 1 means to/from the + left). *rotation* is ignored if this diagram is connected to an + existing one (using *prior* and *connect*). + + Returns + ------- + Sankey + The current `.Sankey` instance. + + Other Parameters + ---------------- + **kwargs + Additional keyword arguments set `matplotlib.patches.PathPatch` + properties, listed below. For example, one may want to use + ``fill=False`` or ``label="A legend entry"``. + + %(Patch:kwdoc)s + + See Also + -------- + Sankey.finish + """ + # Check and preprocess the arguments. + flows = np.array([1.0, -1.0]) if flows is None else np.array(flows) + n = flows.shape[0] # Number of flows + if rotation is None: + rotation = 0 + else: + # In the code below, angles are expressed in deg/90. + rotation /= 90.0 + if orientations is None: + orientations = 0 + try: + orientations = np.broadcast_to(orientations, n) + except ValueError: + raise ValueError( + f"The shapes of 'flows' {np.shape(flows)} and 'orientations' " + f"{np.shape(orientations)} are incompatible" + ) from None + try: + labels = np.broadcast_to(labels, n) + except ValueError: + raise ValueError( + f"The shapes of 'flows' {np.shape(flows)} and 'labels' " + f"{np.shape(labels)} are incompatible" + ) from None + if trunklength < 0: + raise ValueError( + "'trunklength' is negative, which is not allowed because it " + "would cause poor layout") + if abs(np.sum(flows)) > self.tolerance: + _log.info("The sum of the flows is nonzero (%f; patchlabel=%r); " + "is the system not at steady state?", + np.sum(flows), patchlabel) + scaled_flows = self.scale * flows + gain = sum(max(flow, 0) for flow in scaled_flows) + loss = sum(min(flow, 0) for flow in scaled_flows) + if prior is not None: + if prior < 0: + raise ValueError("The index of the prior diagram is negative") + if min(connect) < 0: + raise ValueError( + "At least one of the connection indices is negative") + if prior >= len(self.diagrams): + raise ValueError( + f"The index of the prior diagram is {prior}, but there " + f"are only {len(self.diagrams)} other diagrams") + if connect[0] >= len(self.diagrams[prior].flows): + raise ValueError( + "The connection index to the source diagram is {}, but " + "that diagram has only {} flows".format( + connect[0], len(self.diagrams[prior].flows))) + if connect[1] >= n: + raise ValueError( + f"The connection index to this diagram is {connect[1]}, " + f"but this diagram has only {n} flows") + if self.diagrams[prior].angles[connect[0]] is None: + raise ValueError( + f"The connection cannot be made, which may occur if the " + f"magnitude of flow {connect[0]} of diagram {prior} is " + f"less than the specified tolerance") + flow_error = (self.diagrams[prior].flows[connect[0]] + + flows[connect[1]]) + if abs(flow_error) >= self.tolerance: + raise ValueError( + f"The scaled sum of the connected flows is {flow_error}, " + f"which is not within the tolerance ({self.tolerance})") + + # Determine if the flows are inputs. + are_inputs = [None] * n + for i, flow in enumerate(flows): + if flow >= self.tolerance: + are_inputs[i] = True + elif flow <= -self.tolerance: + are_inputs[i] = False + else: + _log.info( + "The magnitude of flow %d (%f) is below the tolerance " + "(%f).\nIt will not be shown, and it cannot be used in a " + "connection.", i, flow, self.tolerance) + + # Determine the angles of the arrows (before rotation). + angles = [None] * n + for i, (orient, is_input) in enumerate(zip(orientations, are_inputs)): + if orient == 1: + if is_input: + angles[i] = DOWN + elif is_input is False: + # Be specific since is_input can be None. + angles[i] = UP + elif orient == 0: + if is_input is not None: + angles[i] = RIGHT + else: + if orient != -1: + raise ValueError( + f"The value of orientations[{i}] is {orient}, " + f"but it must be -1, 0, or 1") + if is_input: + angles[i] = UP + elif is_input is False: + angles[i] = DOWN + + # Justify the lengths of the paths. + if np.iterable(pathlengths): + if len(pathlengths) != n: + raise ValueError( + f"The lengths of 'flows' ({n}) and 'pathlengths' " + f"({len(pathlengths)}) are incompatible") + else: # Make pathlengths into a list. + urlength = pathlengths + ullength = pathlengths + lrlength = pathlengths + lllength = pathlengths + d = dict(RIGHT=pathlengths) + pathlengths = [d.get(angle, 0) for angle in angles] + # Determine the lengths of the top-side arrows + # from the middle outwards. + for i, (angle, is_input, flow) in enumerate(zip(angles, are_inputs, + scaled_flows)): + if angle == DOWN and is_input: + pathlengths[i] = ullength + ullength += flow + elif angle == UP and is_input is False: + pathlengths[i] = urlength + urlength -= flow # Flow is negative for outputs. + # Determine the lengths of the bottom-side arrows + # from the middle outwards. + for i, (angle, is_input, flow) in enumerate(reversed(list(zip( + angles, are_inputs, scaled_flows)))): + if angle == UP and is_input: + pathlengths[n - i - 1] = lllength + lllength += flow + elif angle == DOWN and is_input is False: + pathlengths[n - i - 1] = lrlength + lrlength -= flow + # Determine the lengths of the left-side arrows + # from the bottom upwards. + has_left_input = False + for i, (angle, is_input, spec) in enumerate(reversed(list(zip( + angles, are_inputs, zip(scaled_flows, pathlengths))))): + if angle == RIGHT: + if is_input: + if has_left_input: + pathlengths[n - i - 1] = 0 + else: + has_left_input = True + # Determine the lengths of the right-side arrows + # from the top downwards. + has_right_output = False + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, list(zip(scaled_flows, pathlengths)))): + if angle == RIGHT: + if is_input is False: + if has_right_output: + pathlengths[i] = 0 + else: + has_right_output = True + + # Begin the subpaths, and smooth the transition if the sum of the flows + # is nonzero. + urpath = [(Path.MOVETO, [(self.gap - trunklength / 2.0), # Upper right + gain / 2.0]), + (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, + gain / 2.0]), + (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, + gain / 2.0]), + (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, + -loss / 2.0]), + (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, + -loss / 2.0]), + (Path.LINETO, [(trunklength / 2.0 - self.gap), + -loss / 2.0])] + llpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower left + loss / 2.0]), + (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, + loss / 2.0]), + (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, + loss / 2.0]), + (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, + -gain / 2.0]), + (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, + -gain / 2.0]), + (Path.LINETO, [(self.gap - trunklength / 2.0), + -gain / 2.0])] + lrpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower right + loss / 2.0])] + ulpath = [(Path.LINETO, [self.gap - trunklength / 2.0, # Upper left + gain / 2.0])] + + # Add the subpaths and assign the locations of the tips and labels. + tips = np.zeros((n, 2)) + label_locations = np.zeros((n, 2)) + # Add the top-side inputs and outputs from the middle outwards. + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, list(zip(scaled_flows, pathlengths)))): + if angle == DOWN and is_input: + tips[i, :], label_locations[i, :] = self._add_input( + ulpath, angle, *spec) + elif angle == UP and is_input is False: + tips[i, :], label_locations[i, :] = self._add_output( + urpath, angle, *spec) + # Add the bottom-side inputs and outputs from the middle outwards. + for i, (angle, is_input, spec) in enumerate(reversed(list(zip( + angles, are_inputs, list(zip(scaled_flows, pathlengths)))))): + if angle == UP and is_input: + tip, label_location = self._add_input(llpath, angle, *spec) + tips[n - i - 1, :] = tip + label_locations[n - i - 1, :] = label_location + elif angle == DOWN and is_input is False: + tip, label_location = self._add_output(lrpath, angle, *spec) + tips[n - i - 1, :] = tip + label_locations[n - i - 1, :] = label_location + # Add the left-side inputs from the bottom upwards. + has_left_input = False + for i, (angle, is_input, spec) in enumerate(reversed(list(zip( + angles, are_inputs, list(zip(scaled_flows, pathlengths)))))): + if angle == RIGHT and is_input: + if not has_left_input: + # Make sure the lower path extends + # at least as far as the upper one. + if llpath[-1][1][0] > ulpath[-1][1][0]: + llpath.append((Path.LINETO, [ulpath[-1][1][0], + llpath[-1][1][1]])) + has_left_input = True + tip, label_location = self._add_input(llpath, angle, *spec) + tips[n - i - 1, :] = tip + label_locations[n - i - 1, :] = label_location + # Add the right-side outputs from the top downwards. + has_right_output = False + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, list(zip(scaled_flows, pathlengths)))): + if angle == RIGHT and is_input is False: + if not has_right_output: + # Make sure the upper path extends + # at least as far as the lower one. + if urpath[-1][1][0] < lrpath[-1][1][0]: + urpath.append((Path.LINETO, [lrpath[-1][1][0], + urpath[-1][1][1]])) + has_right_output = True + tips[i, :], label_locations[i, :] = self._add_output( + urpath, angle, *spec) + # Trim any hanging vertices. + if not has_left_input: + ulpath.pop() + llpath.pop() + if not has_right_output: + lrpath.pop() + urpath.pop() + + # Concatenate the subpaths in the correct order (clockwise from top). + path = (urpath + self._revert(lrpath) + llpath + self._revert(ulpath) + + [(Path.CLOSEPOLY, urpath[0][1])]) + + # Create a patch with the Sankey outline. + codes, vertices = zip(*path) + vertices = np.array(vertices) + + def _get_angle(a, r): + if a is None: + return None + else: + return a + r + + if prior is None: + if rotation != 0: # By default, none of this is needed. + angles = [_get_angle(angle, rotation) for angle in angles] + rotate = Affine2D().rotate_deg(rotation * 90).transform_affine + tips = rotate(tips) + label_locations = rotate(label_locations) + vertices = rotate(vertices) + text = self.ax.text(0, 0, s=patchlabel, ha='center', va='center') + else: + rotation = (self.diagrams[prior].angles[connect[0]] - + angles[connect[1]]) + angles = [_get_angle(angle, rotation) for angle in angles] + rotate = Affine2D().rotate_deg(rotation * 90).transform_affine + tips = rotate(tips) + offset = self.diagrams[prior].tips[connect[0]] - tips[connect[1]] + translate = Affine2D().translate(*offset).transform_affine + tips = translate(tips) + label_locations = translate(rotate(label_locations)) + vertices = translate(rotate(vertices)) + kwds = dict(s=patchlabel, ha='center', va='center') + text = self.ax.text(*offset, **kwds) + if mpl.rcParams['_internal.classic_mode']: + fc = kwargs.pop('fc', kwargs.pop('facecolor', '#bfd1d4')) + lw = kwargs.pop('lw', kwargs.pop('linewidth', 0.5)) + else: + fc = kwargs.pop('fc', kwargs.pop('facecolor', None)) + lw = kwargs.pop('lw', kwargs.pop('linewidth', None)) + if fc is None: + fc = self.ax._get_patches_for_fill.get_next_color() + patch = PathPatch(Path(vertices, codes), fc=fc, lw=lw, **kwargs) + self.ax.add_patch(patch) + + # Add the path labels. + texts = [] + for number, angle, label, location in zip(flows, angles, labels, + label_locations): + if label is None or angle is None: + label = '' + elif self.unit is not None: + if isinstance(self.format, str): + quantity = self.format % abs(number) + self.unit + elif callable(self.format): + quantity = self.format(number) + else: + raise TypeError( + 'format must be callable or a format string') + if label != '': + label += "\n" + label += quantity + texts.append(self.ax.text(x=location[0], y=location[1], + s=label, + ha='center', va='center')) + # Text objects are placed even they are empty (as long as the magnitude + # of the corresponding flow is larger than the tolerance) in case the + # user wants to provide labels later. + + # Expand the size of the diagram if necessary. + self.extent = (min(np.min(vertices[:, 0]), + np.min(label_locations[:, 0]), + self.extent[0]), + max(np.max(vertices[:, 0]), + np.max(label_locations[:, 0]), + self.extent[1]), + min(np.min(vertices[:, 1]), + np.min(label_locations[:, 1]), + self.extent[2]), + max(np.max(vertices[:, 1]), + np.max(label_locations[:, 1]), + self.extent[3])) + # Include both vertices _and_ label locations in the extents; there are + # where either could determine the margins (e.g., arrow shoulders). + + # Add this diagram as a subdiagram. + self.diagrams.append( + SimpleNamespace(patch=patch, flows=flows, angles=angles, tips=tips, + text=text, texts=texts)) + + # Allow a daisy-chained call structure (see docstring for the class). + return self + + def finish(self): + """ + Adjust the axes and return a list of information about the Sankey + subdiagram(s). + + Returns a list of subdiagrams with the following fields: + + ======== ============================================================= + Field Description + ======== ============================================================= + *patch* Sankey outline (a `~matplotlib.patches.PathPatch`). + *flows* Flow values (positive for input, negative for output). + *angles* List of angles of the arrows [deg/90]. + For example, if the diagram has not been rotated, + an input to the top side has an angle of 3 (DOWN), + and an output from the top side has an angle of 1 (UP). + If a flow has been skipped (because its magnitude is less + than *tolerance*), then its angle will be *None*. + *tips* (N, 2)-array of the (x, y) positions of the tips (or "dips") + of the flow paths. + If the magnitude of a flow is less the *tolerance* of this + `Sankey` instance, the flow is skipped and its tip will be at + the center of the diagram. + *text* `.Text` instance for the diagram label. + *texts* List of `.Text` instances for the flow labels. + ======== ============================================================= + + See Also + -------- + Sankey.add + """ + self.ax.axis([self.extent[0] - self.margin, + self.extent[1] + self.margin, + self.extent[2] - self.margin, + self.extent[3] + self.margin]) + self.ax.set_aspect('equal', adjustable='datalim') + return self.diagrams diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.pyi new file mode 100644 index 00000000..4a40c31e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sankey.pyi @@ -0,0 +1,61 @@ +from matplotlib.axes import Axes + +from collections.abc import Callable, Iterable +from typing import Any + +import numpy as np + +__license__: str +__credits__: list[str] +__author__: str +__version__: str + +RIGHT: int +UP: int +DOWN: int + +# TODO typing units +class Sankey: + diagrams: list[Any] + ax: Axes + unit: Any + format: str | Callable[[float], str] + scale: float + gap: float + radius: float + shoulder: float + offset: float + margin: float + pitch: float + tolerance: float + extent: np.ndarray + def __init__( + self, + ax: Axes | None = ..., + scale: float = ..., + unit: Any = ..., + format: str | Callable[[float], str] = ..., + gap: float = ..., + radius: float = ..., + shoulder: float = ..., + offset: float = ..., + head_angle: float = ..., + margin: float = ..., + tolerance: float = ..., + **kwargs + ) -> None: ... + def add( + self, + patchlabel: str = ..., + flows: Iterable[float] | None = ..., + orientations: Iterable[int] | None = ..., + labels: str | Iterable[str | None] = ..., + trunklength: float = ..., + pathlengths: float | Iterable[float] = ..., + prior: int | None = ..., + connect: tuple[int, int] = ..., + rotation: float = ..., + **kwargs + # Replace return with Self when py3.9 is dropped + ) -> Sankey: ... + def finish(self) -> list[Any]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.py new file mode 100644 index 00000000..d86de461 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.py @@ -0,0 +1,756 @@ +""" +Scales define the distribution of data values on an axis, e.g. a log scaling. +They are defined as subclasses of `ScaleBase`. + +See also `.axes.Axes.set_xscale` and the scales examples in the documentation. + +See :doc:`/gallery/scales/custom_scale` for a full example of defining a custom +scale. + +Matplotlib also supports non-separable transformations that operate on both +`~.axis.Axis` at the same time. They are known as projections, and defined in +`matplotlib.projections`. +""" + +import inspect +import textwrap + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, _docstring +from matplotlib.ticker import ( + NullFormatter, ScalarFormatter, LogFormatterSciNotation, LogitFormatter, + NullLocator, LogLocator, AutoLocator, AutoMinorLocator, + SymmetricalLogLocator, AsinhLocator, LogitLocator) +from matplotlib.transforms import Transform, IdentityTransform + + +class ScaleBase: + """ + The base class for all scales. + + Scales are separable transformations, working on a single dimension. + + Subclasses should override + + :attr:`name` + The scale's name. + :meth:`get_transform` + A method returning a `.Transform`, which converts data coordinates to + scaled coordinates. This transform should be invertible, so that e.g. + mouse positions can be converted back to data coordinates. + :meth:`set_default_locators_and_formatters` + A method that sets default locators and formatters for an `~.axis.Axis` + that uses this scale. + :meth:`limit_range_for_scale` + An optional method that "fixes" the axis range to acceptable values, + e.g. restricting log-scaled axes to positive values. + """ + + def __init__(self, axis): + r""" + Construct a new scale. + + Notes + ----- + The following note is for scale implementors. + + For back-compatibility reasons, scales take an `~matplotlib.axis.Axis` + object as first argument. However, this argument should not + be used: a single scale object should be usable by multiple + `~matplotlib.axis.Axis`\es at the same time. + """ + + def get_transform(self): + """ + Return the `.Transform` object associated with this scale. + """ + raise NotImplementedError() + + def set_default_locators_and_formatters(self, axis): + """ + Set the locators and formatters of *axis* to instances suitable for + this scale. + """ + raise NotImplementedError() + + def limit_range_for_scale(self, vmin, vmax, minpos): + """ + Return the range *vmin*, *vmax*, restricted to the + domain supported by this scale (if any). + + *minpos* should be the minimum positive value in the data. + This is used by log scales to determine a minimum value. + """ + return vmin, vmax + + +class LinearScale(ScaleBase): + """ + The default linear scale. + """ + + name = 'linear' + + def __init__(self, axis): + # This method is present only to prevent inheritance of the base class' + # constructor docstring, which would otherwise end up interpolated into + # the docstring of Axis.set_scale. + """ + """ # noqa: D419 + + def set_default_locators_and_formatters(self, axis): + # docstring inherited + axis.set_major_locator(AutoLocator()) + axis.set_major_formatter(ScalarFormatter()) + axis.set_minor_formatter(NullFormatter()) + # update the minor locator for x and y axis based on rcParams + if (axis.axis_name == 'x' and mpl.rcParams['xtick.minor.visible'] or + axis.axis_name == 'y' and mpl.rcParams['ytick.minor.visible']): + axis.set_minor_locator(AutoMinorLocator()) + else: + axis.set_minor_locator(NullLocator()) + + def get_transform(self): + """ + Return the transform for linear scaling, which is just the + `~matplotlib.transforms.IdentityTransform`. + """ + return IdentityTransform() + + +class FuncTransform(Transform): + """ + A simple transform that takes and arbitrary function for the + forward and inverse transform. + """ + + input_dims = output_dims = 1 + + def __init__(self, forward, inverse): + """ + Parameters + ---------- + forward : callable + The forward function for the transform. This function must have + an inverse and, for best behavior, be monotonic. + It must have the signature:: + + def forward(values: array-like) -> array-like + + inverse : callable + The inverse of the forward function. Signature as ``forward``. + """ + super().__init__() + if callable(forward) and callable(inverse): + self._forward = forward + self._inverse = inverse + else: + raise ValueError('arguments to FuncTransform must be functions') + + def transform_non_affine(self, values): + return self._forward(values) + + def inverted(self): + return FuncTransform(self._inverse, self._forward) + + +class FuncScale(ScaleBase): + """ + Provide an arbitrary scale with user-supplied function for the axis. + """ + + name = 'function' + + def __init__(self, axis, functions): + """ + Parameters + ---------- + axis : `~matplotlib.axis.Axis` + The axis for the scale. + functions : (callable, callable) + two-tuple of the forward and inverse functions for the scale. + The forward function must be monotonic. + + Both functions must have the signature:: + + def forward(values: array-like) -> array-like + """ + forward, inverse = functions + transform = FuncTransform(forward, inverse) + self._transform = transform + + def get_transform(self): + """Return the `.FuncTransform` associated with this scale.""" + return self._transform + + def set_default_locators_and_formatters(self, axis): + # docstring inherited + axis.set_major_locator(AutoLocator()) + axis.set_major_formatter(ScalarFormatter()) + axis.set_minor_formatter(NullFormatter()) + # update the minor locator for x and y axis based on rcParams + if (axis.axis_name == 'x' and mpl.rcParams['xtick.minor.visible'] or + axis.axis_name == 'y' and mpl.rcParams['ytick.minor.visible']): + axis.set_minor_locator(AutoMinorLocator()) + else: + axis.set_minor_locator(NullLocator()) + + +class LogTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, base, nonpositive='clip'): + super().__init__() + if base <= 0 or base == 1: + raise ValueError('The log base cannot be <= 0 or == 1') + self.base = base + self._clip = _api.check_getitem( + {"clip": True, "mask": False}, nonpositive=nonpositive) + + def __str__(self): + return "{}(base={}, nonpositive={!r})".format( + type(self).__name__, self.base, "clip" if self._clip else "mask") + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + # Ignore invalid values due to nans being passed to the transform. + with np.errstate(divide="ignore", invalid="ignore"): + log = {np.e: np.log, 2: np.log2, 10: np.log10}.get(self.base) + if log: # If possible, do everything in a single call to NumPy. + out = log(values) + else: + out = np.log(values) + out /= np.log(self.base) + if self._clip: + # SVG spec says that conforming viewers must support values up + # to 3.4e38 (C float); however experiments suggest that + # Inkscape (which uses cairo for rendering) runs into cairo's + # 24-bit limit (which is apparently shared by Agg). + # Ghostscript (used for pdf rendering appears to overflow even + # earlier, with the max value around 2 ** 15 for the tests to + # pass. On the other hand, in practice, we want to clip beyond + # np.log10(np.nextafter(0, 1)) ~ -323 + # so 1000 seems safe. + out[values <= 0] = -1000 + return out + + def inverted(self): + return InvertedLogTransform(self.base) + + +class InvertedLogTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, base): + super().__init__() + self.base = base + + def __str__(self): + return f"{type(self).__name__}(base={self.base})" + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + return np.power(self.base, values) + + def inverted(self): + return LogTransform(self.base) + + +class LogScale(ScaleBase): + """ + A standard logarithmic scale. Care is taken to only plot positive values. + """ + name = 'log' + + def __init__(self, axis, *, base=10, subs=None, nonpositive="clip"): + """ + Parameters + ---------- + axis : `~matplotlib.axis.Axis` + The axis for the scale. + base : float, default: 10 + The base of the logarithm. + nonpositive : {'clip', 'mask'}, default: 'clip' + Determines the behavior for non-positive values. They can either + be masked as invalid, or clipped to a very small positive number. + subs : sequence of int, default: None + Where to place the subticks between each major tick. For example, + in a log10 scale, ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place 8 + logarithmically spaced minor ticks between each major tick. + """ + self._transform = LogTransform(base, nonpositive) + self.subs = subs + + base = property(lambda self: self._transform.base) + + def set_default_locators_and_formatters(self, axis): + # docstring inherited + axis.set_major_locator(LogLocator(self.base)) + axis.set_major_formatter(LogFormatterSciNotation(self.base)) + axis.set_minor_locator(LogLocator(self.base, self.subs)) + axis.set_minor_formatter( + LogFormatterSciNotation(self.base, + labelOnlyBase=(self.subs is not None))) + + def get_transform(self): + """Return the `.LogTransform` associated with this scale.""" + return self._transform + + def limit_range_for_scale(self, vmin, vmax, minpos): + """Limit the domain to positive values.""" + if not np.isfinite(minpos): + minpos = 1e-300 # Should rarely (if ever) have a visible effect. + + return (minpos if vmin <= 0 else vmin, + minpos if vmax <= 0 else vmax) + + +class FuncScaleLog(LogScale): + """ + Provide an arbitrary scale with user-supplied function for the axis and + then put on a logarithmic axes. + """ + + name = 'functionlog' + + def __init__(self, axis, functions, base=10): + """ + Parameters + ---------- + axis : `~matplotlib.axis.Axis` + The axis for the scale. + functions : (callable, callable) + two-tuple of the forward and inverse functions for the scale. + The forward function must be monotonic. + + Both functions must have the signature:: + + def forward(values: array-like) -> array-like + + base : float, default: 10 + Logarithmic base of the scale. + """ + forward, inverse = functions + self.subs = None + self._transform = FuncTransform(forward, inverse) + LogTransform(base) + + @property + def base(self): + return self._transform._b.base # Base of the LogTransform. + + def get_transform(self): + """Return the `.Transform` associated with this scale.""" + return self._transform + + +class SymmetricalLogTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, base, linthresh, linscale): + super().__init__() + if base <= 1.0: + raise ValueError("'base' must be larger than 1") + if linthresh <= 0.0: + raise ValueError("'linthresh' must be positive") + if linscale <= 0.0: + raise ValueError("'linscale' must be positive") + self.base = base + self.linthresh = linthresh + self.linscale = linscale + self._linscale_adj = (linscale / (1.0 - self.base ** -1)) + self._log_base = np.log(base) + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + abs_a = np.abs(values) + with np.errstate(divide="ignore", invalid="ignore"): + out = np.sign(values) * self.linthresh * ( + self._linscale_adj + + np.log(abs_a / self.linthresh) / self._log_base) + inside = abs_a <= self.linthresh + out[inside] = values[inside] * self._linscale_adj + return out + + def inverted(self): + return InvertedSymmetricalLogTransform(self.base, self.linthresh, + self.linscale) + + +class InvertedSymmetricalLogTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, base, linthresh, linscale): + super().__init__() + symlog = SymmetricalLogTransform(base, linthresh, linscale) + self.base = base + self.linthresh = linthresh + self.invlinthresh = symlog.transform(linthresh) + self.linscale = linscale + self._linscale_adj = (linscale / (1.0 - self.base ** -1)) + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + abs_a = np.abs(values) + with np.errstate(divide="ignore", invalid="ignore"): + out = np.sign(values) * self.linthresh * ( + np.power(self.base, + abs_a / self.linthresh - self._linscale_adj)) + inside = abs_a <= self.invlinthresh + out[inside] = values[inside] / self._linscale_adj + return out + + def inverted(self): + return SymmetricalLogTransform(self.base, + self.linthresh, self.linscale) + + +class SymmetricalLogScale(ScaleBase): + """ + The symmetrical logarithmic scale is logarithmic in both the + positive and negative directions from the origin. + + Since the values close to zero tend toward infinity, there is a + need to have a range around zero that is linear. The parameter + *linthresh* allows the user to specify the size of this range + (-*linthresh*, *linthresh*). + + Parameters + ---------- + base : float, default: 10 + The base of the logarithm. + + linthresh : float, default: 2 + Defines the range ``(-x, x)``, within which the plot is linear. + This avoids having the plot go to infinity around zero. + + subs : sequence of int + Where to place the subticks between each major tick. + For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place + 8 logarithmically spaced minor ticks between each major tick. + + linscale : float, optional + This allows the linear range ``(-linthresh, linthresh)`` to be + stretched relative to the logarithmic range. Its value is the number of + decades to use for each half of the linear range. For example, when + *linscale* == 1.0 (the default), the space used for the positive and + negative halves of the linear range will be equal to one decade in + the logarithmic range. + """ + name = 'symlog' + + def __init__(self, axis, *, base=10, linthresh=2, subs=None, linscale=1): + self._transform = SymmetricalLogTransform(base, linthresh, linscale) + self.subs = subs + + base = property(lambda self: self._transform.base) + linthresh = property(lambda self: self._transform.linthresh) + linscale = property(lambda self: self._transform.linscale) + + def set_default_locators_and_formatters(self, axis): + # docstring inherited + axis.set_major_locator(SymmetricalLogLocator(self.get_transform())) + axis.set_major_formatter(LogFormatterSciNotation(self.base)) + axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(), + self.subs)) + axis.set_minor_formatter(NullFormatter()) + + def get_transform(self): + """Return the `.SymmetricalLogTransform` associated with this scale.""" + return self._transform + + +class AsinhTransform(Transform): + """Inverse hyperbolic-sine transformation used by `.AsinhScale`""" + input_dims = output_dims = 1 + + def __init__(self, linear_width): + super().__init__() + if linear_width <= 0.0: + raise ValueError("Scale parameter 'linear_width' " + + "must be strictly positive") + self.linear_width = linear_width + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + return self.linear_width * np.arcsinh(values / self.linear_width) + + def inverted(self): + return InvertedAsinhTransform(self.linear_width) + + +class InvertedAsinhTransform(Transform): + """Hyperbolic sine transformation used by `.AsinhScale`""" + input_dims = output_dims = 1 + + def __init__(self, linear_width): + super().__init__() + self.linear_width = linear_width + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + return self.linear_width * np.sinh(values / self.linear_width) + + def inverted(self): + return AsinhTransform(self.linear_width) + + +class AsinhScale(ScaleBase): + """ + A quasi-logarithmic scale based on the inverse hyperbolic sine (asinh) + + For values close to zero, this is essentially a linear scale, + but for large magnitude values (either positive or negative) + it is asymptotically logarithmic. The transition between these + linear and logarithmic regimes is smooth, and has no discontinuities + in the function gradient in contrast to + the `.SymmetricalLogScale` ("symlog") scale. + + Specifically, the transformation of an axis coordinate :math:`a` is + :math:`a \\rightarrow a_0 \\sinh^{-1} (a / a_0)` where :math:`a_0` + is the effective width of the linear region of the transformation. + In that region, the transformation is + :math:`a \\rightarrow a + \\mathcal{O}(a^3)`. + For large values of :math:`a` the transformation behaves as + :math:`a \\rightarrow a_0 \\, \\mathrm{sgn}(a) \\ln |a| + \\mathcal{O}(1)`. + + .. note:: + + This API is provisional and may be revised in the future + based on early user feedback. + """ + + name = 'asinh' + + auto_tick_multipliers = { + 3: (2, ), + 4: (2, ), + 5: (2, ), + 8: (2, 4), + 10: (2, 5), + 16: (2, 4, 8), + 64: (4, 16), + 1024: (256, 512) + } + + def __init__(self, axis, *, linear_width=1.0, + base=10, subs='auto', **kwargs): + """ + Parameters + ---------- + linear_width : float, default: 1 + The scale parameter (elsewhere referred to as :math:`a_0`) + defining the extent of the quasi-linear region, + and the coordinate values beyond which the transformation + becomes asymptotically logarithmic. + base : int, default: 10 + The number base used for rounding tick locations + on a logarithmic scale. If this is less than one, + then rounding is to the nearest integer multiple + of powers of ten. + subs : sequence of int + Multiples of the number base used for minor ticks. + If set to 'auto', this will use built-in defaults, + e.g. (2, 5) for base=10. + """ + super().__init__(axis) + self._transform = AsinhTransform(linear_width) + self._base = int(base) + if subs == 'auto': + self._subs = self.auto_tick_multipliers.get(self._base) + else: + self._subs = subs + + linear_width = property(lambda self: self._transform.linear_width) + + def get_transform(self): + return self._transform + + def set_default_locators_and_formatters(self, axis): + axis.set(major_locator=AsinhLocator(self.linear_width, + base=self._base), + minor_locator=AsinhLocator(self.linear_width, + base=self._base, + subs=self._subs), + minor_formatter=NullFormatter()) + if self._base > 1: + axis.set_major_formatter(LogFormatterSciNotation(self._base)) + else: + axis.set_major_formatter('{x:.3g}') + + +class LogitTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, nonpositive='mask'): + super().__init__() + _api.check_in_list(['mask', 'clip'], nonpositive=nonpositive) + self._nonpositive = nonpositive + self._clip = {"clip": True, "mask": False}[nonpositive] + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + """logit transform (base 10), masked or clipped""" + with np.errstate(divide="ignore", invalid="ignore"): + out = np.log10(values / (1 - values)) + if self._clip: # See LogTransform for choice of clip value. + out[values <= 0] = -1000 + out[1 <= values] = 1000 + return out + + def inverted(self): + return LogisticTransform(self._nonpositive) + + def __str__(self): + return f"{type(self).__name__}({self._nonpositive!r})" + + +class LogisticTransform(Transform): + input_dims = output_dims = 1 + + def __init__(self, nonpositive='mask'): + super().__init__() + self._nonpositive = nonpositive + + @_api.rename_parameter("3.8", "a", "values") + def transform_non_affine(self, values): + """logistic transform (base 10)""" + return 1.0 / (1 + 10**(-values)) + + def inverted(self): + return LogitTransform(self._nonpositive) + + def __str__(self): + return f"{type(self).__name__}({self._nonpositive!r})" + + +class LogitScale(ScaleBase): + """ + Logit scale for data between zero and one, both excluded. + + This scale is similar to a log scale close to zero and to one, and almost + linear around 0.5. It maps the interval ]0, 1[ onto ]-infty, +infty[. + """ + name = 'logit' + + def __init__(self, axis, nonpositive='mask', *, + one_half=r"\frac{1}{2}", use_overline=False): + r""" + Parameters + ---------- + axis : `~matplotlib.axis.Axis` + Currently unused. + nonpositive : {'mask', 'clip'} + Determines the behavior for values beyond the open interval ]0, 1[. + They can either be masked as invalid, or clipped to a number very + close to 0 or 1. + use_overline : bool, default: False + Indicate the usage of survival notation (\overline{x}) in place of + standard notation (1-x) for probability close to one. + one_half : str, default: r"\frac{1}{2}" + The string used for ticks formatter to represent 1/2. + """ + self._transform = LogitTransform(nonpositive) + self._use_overline = use_overline + self._one_half = one_half + + def get_transform(self): + """Return the `.LogitTransform` associated with this scale.""" + return self._transform + + def set_default_locators_and_formatters(self, axis): + # docstring inherited + # ..., 0.01, 0.1, 0.5, 0.9, 0.99, ... + axis.set_major_locator(LogitLocator()) + axis.set_major_formatter( + LogitFormatter( + one_half=self._one_half, + use_overline=self._use_overline + ) + ) + axis.set_minor_locator(LogitLocator(minor=True)) + axis.set_minor_formatter( + LogitFormatter( + minor=True, + one_half=self._one_half, + use_overline=self._use_overline + ) + ) + + def limit_range_for_scale(self, vmin, vmax, minpos): + """ + Limit the domain to values between 0 and 1 (excluded). + """ + if not np.isfinite(minpos): + minpos = 1e-7 # Should rarely (if ever) have a visible effect. + return (minpos if vmin <= 0 else vmin, + 1 - minpos if vmax >= 1 else vmax) + + +_scale_mapping = { + 'linear': LinearScale, + 'log': LogScale, + 'symlog': SymmetricalLogScale, + 'asinh': AsinhScale, + 'logit': LogitScale, + 'function': FuncScale, + 'functionlog': FuncScaleLog, + } + + +def get_scale_names(): + """Return the names of the available scales.""" + return sorted(_scale_mapping) + + +def scale_factory(scale, axis, **kwargs): + """ + Return a scale class by name. + + Parameters + ---------- + scale : {%(names)s} + axis : `~matplotlib.axis.Axis` + """ + scale_cls = _api.check_getitem(_scale_mapping, scale=scale) + return scale_cls(axis, **kwargs) + + +if scale_factory.__doc__: + scale_factory.__doc__ = scale_factory.__doc__ % { + "names": ", ".join(map(repr, get_scale_names()))} + + +def register_scale(scale_class): + """ + Register a new kind of scale. + + Parameters + ---------- + scale_class : subclass of `ScaleBase` + The scale to register. + """ + _scale_mapping[scale_class.name] = scale_class + + +def _get_scale_docs(): + """ + Helper function for generating docstrings related to scales. + """ + docs = [] + for name, scale_class in _scale_mapping.items(): + docstring = inspect.getdoc(scale_class.__init__) or "" + docs.extend([ + f" {name!r}", + "", + textwrap.indent(docstring, " " * 8), + "" + ]) + return "\n".join(docs) + + +_docstring.interpd.update( + scale_type='{%s}' % ', '.join([repr(x) for x in get_scale_names()]), + scale_docs=_get_scale_docs().rstrip(), + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.pyi new file mode 100644 index 00000000..7fec8e68 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/scale.pyi @@ -0,0 +1,178 @@ +from matplotlib.axis import Axis +from matplotlib.transforms import Transform + +from collections.abc import Callable, Iterable +from typing import Literal +from numpy.typing import ArrayLike + +class ScaleBase: + def __init__(self, axis: Axis | None) -> None: ... + def get_transform(self) -> Transform: ... + def set_default_locators_and_formatters(self, axis: Axis) -> None: ... + def limit_range_for_scale( + self, vmin: float, vmax: float, minpos: float + ) -> tuple[float, float]: ... + +class LinearScale(ScaleBase): + name: str + +class FuncTransform(Transform): + input_dims: int + output_dims: int + def __init__( + self, + forward: Callable[[ArrayLike], ArrayLike], + inverse: Callable[[ArrayLike], ArrayLike], + ) -> None: ... + def inverted(self) -> FuncTransform: ... + +class FuncScale(ScaleBase): + name: str + def __init__( + self, + axis: Axis | None, + functions: tuple[ + Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike] + ], + ) -> None: ... + +class LogTransform(Transform): + input_dims: int + output_dims: int + base: float + def __init__( + self, base: float, nonpositive: Literal["clip", "mask"] = ... + ) -> None: ... + def inverted(self) -> InvertedLogTransform: ... + +class InvertedLogTransform(Transform): + input_dims: int + output_dims: int + base: float + def __init__(self, base: float) -> None: ... + def inverted(self) -> LogTransform: ... + +class LogScale(ScaleBase): + name: str + subs: Iterable[int] | None + def __init__( + self, + axis: Axis | None, + *, + base: float = ..., + subs: Iterable[int] | None = ..., + nonpositive: Literal["clip", "mask"] = ... + ) -> None: ... + @property + def base(self) -> float: ... + def get_transform(self) -> Transform: ... + +class FuncScaleLog(LogScale): + def __init__( + self, + axis: Axis | None, + functions: tuple[ + Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike] + ], + base: float = ..., + ) -> None: ... + @property + def base(self) -> float: ... + def get_transform(self) -> Transform: ... + +class SymmetricalLogTransform(Transform): + input_dims: int + output_dims: int + base: float + linthresh: float + linscale: float + def __init__(self, base: float, linthresh: float, linscale: float) -> None: ... + def inverted(self) -> InvertedSymmetricalLogTransform: ... + +class InvertedSymmetricalLogTransform(Transform): + input_dims: int + output_dims: int + base: float + linthresh: float + invlinthresh: float + linscale: float + def __init__(self, base: float, linthresh: float, linscale: float) -> None: ... + def inverted(self) -> SymmetricalLogTransform: ... + +class SymmetricalLogScale(ScaleBase): + name: str + subs: Iterable[int] | None + def __init__( + self, + axis: Axis | None, + *, + base: float = ..., + linthresh: float = ..., + subs: Iterable[int] | None = ..., + linscale: float = ... + ) -> None: ... + @property + def base(self) -> float: ... + @property + def linthresh(self) -> float: ... + @property + def linscale(self) -> float: ... + def get_transform(self) -> SymmetricalLogTransform: ... + +class AsinhTransform(Transform): + input_dims: int + output_dims: int + linear_width: float + def __init__(self, linear_width: float) -> None: ... + def inverted(self) -> InvertedAsinhTransform: ... + +class InvertedAsinhTransform(Transform): + input_dims: int + output_dims: int + linear_width: float + def __init__(self, linear_width: float) -> None: ... + def inverted(self) -> AsinhTransform: ... + +class AsinhScale(ScaleBase): + name: str + auto_tick_multipliers: dict[int, tuple[int, ...]] + def __init__( + self, + axis: Axis | None, + *, + linear_width: float = ..., + base: float = ..., + subs: Iterable[int] | Literal["auto"] | None = ..., + **kwargs + ) -> None: ... + @property + def linear_width(self) -> float: ... + def get_transform(self) -> AsinhTransform: ... + +class LogitTransform(Transform): + input_dims: int + output_dims: int + def __init__(self, nonpositive: Literal["mask", "clip"] = ...) -> None: ... + def inverted(self) -> LogisticTransform: ... + +class LogisticTransform(Transform): + input_dims: int + output_dims: int + def __init__(self, nonpositive: Literal["mask", "clip"] = ...) -> None: ... + def inverted(self) -> LogitTransform: ... + +class LogitScale(ScaleBase): + name: str + def __init__( + self, + axis: Axis | None, + nonpositive: Literal["mask", "clip"] = ..., + *, + one_half: str = ..., + use_overline: bool = ... + ) -> None: ... + def get_transform(self) -> LogitTransform: ... + +def get_scale_names() -> list[str]: ... +def scale_factory(scale: str, axis: Axis, **kwargs) -> ScaleBase: ... +def register_scale(scale_class: type[ScaleBase]) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/figmpl_directive.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/figmpl_directive.py new file mode 100644 index 00000000..5ef34f4d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/figmpl_directive.py @@ -0,0 +1,288 @@ +""" +Add a ``figure-mpl`` directive that is a responsive version of ``figure``. + +This implementation is very similar to ``.. figure::``, except it also allows a +``srcset=`` argument to be passed to the image tag, hence allowing responsive +resolution images. + +There is no particular reason this could not be used standalone, but is meant +to be used with :doc:`/api/sphinxext_plot_directive_api`. + +Note that the directory organization is a bit different than ``.. figure::``. +See the *FigureMpl* documentation below. + +""" +from docutils import nodes + +from docutils.parsers.rst import directives +from docutils.parsers.rst.directives.images import Figure, Image + +import os +from os.path import relpath +from pathlib import PurePath, Path +import shutil + +from sphinx.errors import ExtensionError + +import matplotlib + + +class figmplnode(nodes.General, nodes.Element): + pass + + +class FigureMpl(Figure): + """ + Implements a directive to allow an optional hidpi image. + + Meant to be used with the *plot_srcset* configuration option in conf.py, + and gets set in the TEMPLATE of plot_directive.py + + e.g.:: + + .. figure-mpl:: plot_directive/some_plots-1.png + :alt: bar + :srcset: plot_directive/some_plots-1.png, + plot_directive/some_plots-1.2x.png 2.00x + :class: plot-directive + + The resulting html (at ``some_plots.html``) is:: + + <img src="sphx_glr_bar_001_hidpi.png" + srcset="_images/some_plot-1.png, + _images/some_plots-1.2x.png 2.00x", + alt="bar" + class="plot_directive" /> + + Note that the handling of subdirectories is different than that used by the sphinx + figure directive:: + + .. figure-mpl:: plot_directive/nestedpage/index-1.png + :alt: bar + :srcset: plot_directive/nestedpage/index-1.png + plot_directive/nestedpage/index-1.2x.png 2.00x + :class: plot_directive + + The resulting html (at ``nestedpage/index.html``):: + + <img src="../_images/nestedpage-index-1.png" + srcset="../_images/nestedpage-index-1.png, + ../_images/_images/nestedpage-index-1.2x.png 2.00x", + alt="bar" + class="sphx-glr-single-img" /> + + where the subdirectory is included in the image name for uniqueness. + """ + + has_content = False + required_arguments = 1 + optional_arguments = 2 + final_argument_whitespace = False + option_spec = { + 'alt': directives.unchanged, + 'height': directives.length_or_unitless, + 'width': directives.length_or_percentage_or_unitless, + 'scale': directives.nonnegative_int, + 'align': Image.align, + 'class': directives.class_option, + 'caption': directives.unchanged, + 'srcset': directives.unchanged, + } + + def run(self): + + image_node = figmplnode() + + imagenm = self.arguments[0] + image_node['alt'] = self.options.get('alt', '') + image_node['align'] = self.options.get('align', None) + image_node['class'] = self.options.get('class', None) + image_node['width'] = self.options.get('width', None) + image_node['height'] = self.options.get('height', None) + image_node['scale'] = self.options.get('scale', None) + image_node['caption'] = self.options.get('caption', None) + + # we would like uri to be the highest dpi version so that + # latex etc will use that. But for now, lets just make + # imagenm... maybe pdf one day? + + image_node['uri'] = imagenm + image_node['srcset'] = self.options.get('srcset', None) + + return [image_node] + + +def _parse_srcsetNodes(st): + """ + parse srcset... + """ + entries = st.split(',') + srcset = {} + for entry in entries: + spl = entry.strip().split(' ') + if len(spl) == 1: + srcset[0] = spl[0] + elif len(spl) == 2: + mult = spl[1][:-1] + srcset[float(mult)] = spl[0] + else: + raise ExtensionError(f'srcset argument "{entry}" is invalid.') + return srcset + + +def _copy_images_figmpl(self, node): + + # these will be the temporary place the plot-directive put the images eg: + # ../../../build/html/plot_directive/users/explain/artists/index-1.png + if node['srcset']: + srcset = _parse_srcsetNodes(node['srcset']) + else: + srcset = None + + # the rst file's location: eg /Users/username/matplotlib/doc/users/explain/artists + docsource = PurePath(self.document['source']).parent + + # get the relpath relative to root: + srctop = self.builder.srcdir + rel = relpath(docsource, srctop).replace('.', '').replace(os.sep, '-') + if len(rel): + rel += '-' + # eg: users/explain/artists + + imagedir = PurePath(self.builder.outdir, self.builder.imagedir) + # eg: /Users/username/matplotlib/doc/build/html/_images/users/explain/artists + + Path(imagedir).mkdir(parents=True, exist_ok=True) + + # copy all the sources to the imagedir: + if srcset: + for src in srcset.values(): + # the entries in srcset are relative to docsource's directory + abspath = PurePath(docsource, src) + name = rel + abspath.name + shutil.copyfile(abspath, imagedir / name) + else: + abspath = PurePath(docsource, node['uri']) + name = rel + abspath.name + shutil.copyfile(abspath, imagedir / name) + + return imagedir, srcset, rel + + +def visit_figmpl_html(self, node): + + imagedir, srcset, rel = _copy_images_figmpl(self, node) + + # /doc/examples/subd/plot_1.rst + docsource = PurePath(self.document['source']) + # /doc/ + # make sure to add the trailing slash: + srctop = PurePath(self.builder.srcdir, '') + # examples/subd/plot_1.rst + relsource = relpath(docsource, srctop) + # /doc/build/html + desttop = PurePath(self.builder.outdir, '') + # /doc/build/html/examples/subd + dest = desttop / relsource + + # ../../_images/ for dirhtml and ../_images/ for html + imagerel = PurePath(relpath(imagedir, dest.parent)).as_posix() + if self.builder.name == "dirhtml": + imagerel = f'..{imagerel}' + + # make uri also be relative... + nm = PurePath(node['uri'][1:]).name + uri = f'{imagerel}/{rel}{nm}' + + # make srcset str. Need to change all the prefixes! + maxsrc = uri + srcsetst = '' + if srcset: + maxmult = -1 + for mult, src in srcset.items(): + nm = PurePath(src[1:]).name + # ../../_images/plot_1_2_0x.png + path = f'{imagerel}/{rel}{nm}' + srcsetst += path + if mult == 0: + srcsetst += ', ' + else: + srcsetst += f' {mult:1.2f}x, ' + + if mult > maxmult: + maxmult = mult + maxsrc = path + + # trim trailing comma and space... + srcsetst = srcsetst[:-2] + + alt = node['alt'] + if node['class'] is not None: + classst = ' '.join(node['class']) + classst = f'class="{classst}"' + + else: + classst = '' + + stylers = ['width', 'height', 'scale'] + stylest = '' + for style in stylers: + if node[style]: + stylest += f'{style}: {node[style]};' + + figalign = node['align'] if node['align'] else 'center' + +# <figure class="align-default" id="id1"> +# <a class="reference internal image-reference" href="_images/index-1.2x.png"> +# <img alt="_images/index-1.2x.png" src="_images/index-1.2x.png" style="width: 53%;" /> +# </a> +# <figcaption> +# <p><span class="caption-text">Figure caption is here....</span> +# <a class="headerlink" href="#id1" title="Permalink to this image">#</a></p> +# </figcaption> +# </figure> + img_block = (f'<img src="{uri}" style="{stylest}" srcset="{srcsetst}" ' + f'alt="{alt}" {classst}/>') + html_block = f'<figure class="align-{figalign}">\n' + html_block += f' <a class="reference internal image-reference" href="{maxsrc}">\n' + html_block += f' {img_block}\n </a>\n' + if node['caption']: + html_block += ' <figcaption>\n' + html_block += f' <p><span class="caption-text">{node["caption"]}</span></p>\n' + html_block += ' </figcaption>\n' + html_block += '</figure>\n' + self.body.append(html_block) + + +def visit_figmpl_latex(self, node): + + if node['srcset'] is not None: + imagedir, srcset = _copy_images_figmpl(self, node) + maxmult = -1 + # choose the highest res version for latex: + maxmult = max(srcset, default=-1) + node['uri'] = PurePath(srcset[maxmult]).name + + self.visit_figure(node) + + +def depart_figmpl_html(self, node): + pass + + +def depart_figmpl_latex(self, node): + self.depart_figure(node) + + +def figurempl_addnode(app): + app.add_node(figmplnode, + html=(visit_figmpl_html, depart_figmpl_html), + latex=(visit_figmpl_latex, depart_figmpl_latex)) + + +def setup(app): + app.add_directive("figure-mpl", FigureMpl) + figurempl_addnode(app) + metadata = {'parallel_read_safe': True, 'parallel_write_safe': True, + 'version': matplotlib.__version__} + return metadata diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/mathmpl.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/mathmpl.py new file mode 100644 index 00000000..3e0d562e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/mathmpl.py @@ -0,0 +1,239 @@ +r""" +A role and directive to display mathtext in Sphinx +================================================== + +The ``mathmpl`` Sphinx extension creates a mathtext image in Matplotlib and +shows it in html output. Thus, it is a true and faithful representation of what +you will see if you pass a given LaTeX string to Matplotlib (see +:ref:`mathtext`). + +.. warning:: + In most cases, you will likely want to use one of `Sphinx's builtin Math + extensions + <https://www.sphinx-doc.org/en/master/usage/extensions/math.html>`__ + instead of this one. The builtin Sphinx math directive uses MathJax to + render mathematical expressions, and addresses accessibility concerns that + ``mathmpl`` doesn't address. + +Mathtext may be included in two ways: + +1. Inline, using the role:: + + This text uses inline math: :mathmpl:`\alpha > \beta`. + + which produces: + + This text uses inline math: :mathmpl:`\alpha > \beta`. + +2. Standalone, using the directive:: + + Here is some standalone math: + + .. mathmpl:: + + \alpha > \beta + + which produces: + + Here is some standalone math: + + .. mathmpl:: + + \alpha > \beta + +Options +------- + +The ``mathmpl`` role and directive both support the following options: + +fontset : str, default: 'cm' + The font set to use when displaying math. See :rc:`mathtext.fontset`. + +fontsize : float + The font size, in points. Defaults to the value from the extension + configuration option defined below. + +Configuration options +--------------------- + +The mathtext extension has the following configuration options: + +mathmpl_fontsize : float, default: 10.0 + Default font size, in points. + +mathmpl_srcset : list of str, default: [] + Additional image sizes to generate when embedding in HTML, to support + `responsive resolution images + <https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images>`__. + The list should contain additional x-descriptors (``'1.5x'``, ``'2x'``, + etc.) to generate (1x is the default and always included.) + +""" + +import hashlib +from pathlib import Path + +from docutils import nodes +from docutils.parsers.rst import Directive, directives +import sphinx +from sphinx.errors import ConfigError, ExtensionError + +import matplotlib as mpl +from matplotlib import _api, mathtext +from matplotlib.rcsetup import validate_float_or_None + + +# Define LaTeX math node: +class latex_math(nodes.General, nodes.Element): + pass + + +def fontset_choice(arg): + return directives.choice(arg, mathtext.MathTextParser._font_type_mapping) + + +def math_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + i = rawtext.find('`') + latex = rawtext[i+1:-1] + node = latex_math(rawtext) + node['latex'] = latex + node['fontset'] = options.get('fontset', 'cm') + node['fontsize'] = options.get('fontsize', + setup.app.config.mathmpl_fontsize) + return [node], [] +math_role.options = {'fontset': fontset_choice, + 'fontsize': validate_float_or_None} + + +class MathDirective(Directive): + """ + The ``.. mathmpl::`` directive, as documented in the module's docstring. + """ + has_content = True + required_arguments = 0 + optional_arguments = 0 + final_argument_whitespace = False + option_spec = {'fontset': fontset_choice, + 'fontsize': validate_float_or_None} + + def run(self): + latex = ''.join(self.content) + node = latex_math(self.block_text) + node['latex'] = latex + node['fontset'] = self.options.get('fontset', 'cm') + node['fontsize'] = self.options.get('fontsize', + setup.app.config.mathmpl_fontsize) + return [node] + + +# This uses mathtext to render the expression +def latex2png(latex, filename, fontset='cm', fontsize=10, dpi=100): + with mpl.rc_context({'mathtext.fontset': fontset, 'font.size': fontsize}): + try: + depth = mathtext.math_to_image( + f"${latex}$", filename, dpi=dpi, format="png") + except Exception: + _api.warn_external(f"Could not render math expression {latex}") + depth = 0 + return depth + + +# LaTeX to HTML translation stuff: +def latex2html(node, source): + inline = isinstance(node.parent, nodes.TextElement) + latex = node['latex'] + fontset = node['fontset'] + fontsize = node['fontsize'] + name = 'math-{}'.format( + hashlib.md5(f'{latex}{fontset}{fontsize}'.encode()).hexdigest()[-10:]) + + destdir = Path(setup.app.builder.outdir, '_images', 'mathmpl') + destdir.mkdir(parents=True, exist_ok=True) + + dest = destdir / f'{name}.png' + depth = latex2png(latex, dest, fontset, fontsize=fontsize) + + srcset = [] + for size in setup.app.config.mathmpl_srcset: + filename = f'{name}-{size.replace(".", "_")}.png' + latex2png(latex, destdir / filename, fontset, fontsize=fontsize, + dpi=100 * float(size[:-1])) + srcset.append( + f'{setup.app.builder.imgpath}/mathmpl/{filename} {size}') + if srcset: + srcset = (f'srcset="{setup.app.builder.imgpath}/mathmpl/{name}.png, ' + + ', '.join(srcset) + '" ') + + if inline: + cls = '' + else: + cls = 'class="center" ' + if inline and depth != 0: + style = 'style="position: relative; bottom: -%dpx"' % (depth + 1) + else: + style = '' + + return (f'<img src="{setup.app.builder.imgpath}/mathmpl/{name}.png"' + f' {srcset}{cls}{style}/>') + + +def _config_inited(app, config): + # Check for srcset hidpi images + for i, size in enumerate(app.config.mathmpl_srcset): + if size[-1] == 'x': # "2x" = "2.0" + try: + float(size[:-1]) + except ValueError: + raise ConfigError( + f'Invalid value for mathmpl_srcset parameter: {size!r}. ' + 'Must be a list of strings with the multiplicative ' + 'factor followed by an "x". e.g. ["2.0x", "1.5x"]') + else: + raise ConfigError( + f'Invalid value for mathmpl_srcset parameter: {size!r}. ' + 'Must be a list of strings with the multiplicative ' + 'factor followed by an "x". e.g. ["2.0x", "1.5x"]') + + +def setup(app): + setup.app = app + app.add_config_value('mathmpl_fontsize', 10.0, True) + app.add_config_value('mathmpl_srcset', [], True) + try: + app.connect('config-inited', _config_inited) # Sphinx 1.8+ + except ExtensionError: + app.connect('env-updated', lambda app, env: _config_inited(app, None)) + + # Add visit/depart methods to HTML-Translator: + def visit_latex_math_html(self, node): + source = self.document.attributes['source'] + self.body.append(latex2html(node, source)) + + def depart_latex_math_html(self, node): + pass + + # Add visit/depart methods to LaTeX-Translator: + def visit_latex_math_latex(self, node): + inline = isinstance(node.parent, nodes.TextElement) + if inline: + self.body.append('$%s$' % node['latex']) + else: + self.body.extend(['\\begin{equation}', + node['latex'], + '\\end{equation}']) + + def depart_latex_math_latex(self, node): + pass + + app.add_node(latex_math, + html=(visit_latex_math_html, depart_latex_math_html), + latex=(visit_latex_math_latex, depart_latex_math_latex)) + app.add_role('mathmpl', math_role) + app.add_directive('mathmpl', MathDirective) + if sphinx.version_info < (1, 8): + app.add_role('math', math_role) + app.add_directive('math', MathDirective) + + metadata = {'parallel_read_safe': True, 'parallel_write_safe': True} + return metadata diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/plot_directive.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/plot_directive.py new file mode 100644 index 00000000..65b25fb9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/sphinxext/plot_directive.py @@ -0,0 +1,933 @@ +""" +A directive for including a Matplotlib plot in a Sphinx document +================================================================ + +This is a Sphinx extension providing a reStructuredText directive +``.. plot::`` for including a plot in a Sphinx document. + +In HTML output, ``.. plot::`` will include a .png file with a link +to a high-res .png and .pdf. In LaTeX output, it will include a .pdf. + +The plot content may be defined in one of three ways: + +1. **A path to a source file** as the argument to the directive:: + + .. plot:: path/to/plot.py + + When a path to a source file is given, the content of the + directive may optionally contain a caption for the plot:: + + .. plot:: path/to/plot.py + + The plot caption. + + Additionally, one may specify the name of a function to call (with + no arguments) immediately after importing the module:: + + .. plot:: path/to/plot.py plot_function1 + +2. Included as **inline content** to the directive:: + + .. plot:: + + import matplotlib.pyplot as plt + plt.plot([1, 2, 3], [4, 5, 6]) + plt.title("A plotting exammple") + +3. Using **doctest** syntax:: + + .. plot:: + + A plotting example: + >>> import matplotlib.pyplot as plt + >>> plt.plot([1, 2, 3], [4, 5, 6]) + +Options +------- + +The ``.. plot::`` directive supports the following options: + +``:format:`` : {'python', 'doctest'} + The format of the input. If unset, the format is auto-detected. + +``:include-source:`` : bool + Whether to display the source code. The default can be changed using + the ``plot_include_source`` variable in :file:`conf.py` (which itself + defaults to False). + +``:show-source-link:`` : bool + Whether to show a link to the source in HTML. The default can be + changed using the ``plot_html_show_source_link`` variable in + :file:`conf.py` (which itself defaults to True). + +``:context:`` : bool or str + If provided, the code will be run in the context of all previous plot + directives for which the ``:context:`` option was specified. This only + applies to inline code plot directives, not those run from files. If + the ``:context: reset`` option is specified, the context is reset + for this and future plots, and previous figures are closed prior to + running the code. ``:context: close-figs`` keeps the context but closes + previous figures before running the code. + +``:nofigs:`` : bool + If specified, the code block will be run, but no figures will be + inserted. This is usually useful with the ``:context:`` option. + +``:caption:`` : str + If specified, the option's argument will be used as a caption for the + figure. This overwrites the caption given in the content, when the plot + is generated from a file. + +Additionally, this directive supports all the options of the `image directive +<https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_, +except for ``:target:`` (since plot will add its own target). These include +``:alt:``, ``:height:``, ``:width:``, ``:scale:``, ``:align:`` and ``:class:``. + +Configuration options +--------------------- + +The plot directive has the following configuration options: + +plot_include_source + Default value for the include-source option (default: False). + +plot_html_show_source_link + Whether to show a link to the source in HTML (default: True). + +plot_pre_code + Code that should be executed before each plot. If None (the default), + it will default to a string containing:: + + import numpy as np + from matplotlib import pyplot as plt + +plot_basedir + Base directory, to which ``plot::`` file names are relative to. + If None or empty (the default), file names are relative to the + directory where the file containing the directive is. + +plot_formats + File formats to generate (default: ['png', 'hires.png', 'pdf']). + List of tuples or strings:: + + [(suffix, dpi), suffix, ...] + + that determine the file format and the DPI. For entries whose + DPI was omitted, sensible defaults are chosen. When passing from + the command line through sphinx_build the list should be passed as + suffix:dpi,suffix:dpi, ... + +plot_html_show_formats + Whether to show links to the files in HTML (default: True). + +plot_rcparams + A dictionary containing any non-standard rcParams that should + be applied before each plot (default: {}). + +plot_apply_rcparams + By default, rcParams are applied when ``:context:`` option is not used + in a plot directive. If set, this configuration option overrides this + behavior and applies rcParams before each plot. + +plot_working_directory + By default, the working directory will be changed to the directory of + the example, so the code can get at its data files, if any. Also its + path will be added to `sys.path` so it can import any helper modules + sitting beside it. This configuration option can be used to specify + a central directory (also added to `sys.path`) where data files and + helper modules for all code are located. + +plot_template + Provide a customized template for preparing restructured text. + +plot_srcset + Allow the srcset image option for responsive image resolutions. List of + strings with the multiplicative factors followed by an "x". + e.g. ["2.0x", "1.5x"]. "2.0x" will create a png with the default "png" + resolution from plot_formats, multiplied by 2. If plot_srcset is + specified, the plot directive uses the + :doc:`/api/sphinxext_figmpl_directive_api` (instead of the usual figure + directive) in the intermediary rst file that is generated. + The plot_srcset option is incompatible with *singlehtml* builds, and an + error will be raised. + +Notes on how it works +--------------------- + +The plot directive runs the code it is given, either in the source file or the +code under the directive. The figure created (if any) is saved in the sphinx +build directory under a subdirectory named ``plot_directive``. It then creates +an intermediate rst file that calls a ``.. figure:`` directive (or +``.. figmpl::`` directive if ``plot_srcset`` is being used) and has links to +the ``*.png`` files in the ``plot_directive`` directory. These translations can +be customized by changing the *plot_template*. See the source of +:doc:`/api/sphinxext_plot_directive_api` for the templates defined in *TEMPLATE* +and *TEMPLATE_SRCSET*. +""" + +import contextlib +import doctest +from io import StringIO +import itertools +import os +from os.path import relpath +from pathlib import Path +import re +import shutil +import sys +import textwrap +import traceback + +from docutils.parsers.rst import directives, Directive +from docutils.parsers.rst.directives.images import Image +import jinja2 # Sphinx dependency. + +from sphinx.errors import ExtensionError + +import matplotlib +from matplotlib.backend_bases import FigureManagerBase +import matplotlib.pyplot as plt +from matplotlib import _pylab_helpers, cbook + +matplotlib.use("agg") + +__version__ = 2 + + +# ----------------------------------------------------------------------------- +# Registration hook +# ----------------------------------------------------------------------------- + + +def _option_boolean(arg): + if not arg or not arg.strip(): + # no argument given, assume used as a flag + return True + elif arg.strip().lower() in ('no', '0', 'false'): + return False + elif arg.strip().lower() in ('yes', '1', 'true'): + return True + else: + raise ValueError(f'{arg!r} unknown boolean') + + +def _option_context(arg): + if arg in [None, 'reset', 'close-figs']: + return arg + raise ValueError("Argument should be None or 'reset' or 'close-figs'") + + +def _option_format(arg): + return directives.choice(arg, ('python', 'doctest')) + + +def mark_plot_labels(app, document): + """ + To make plots referenceable, we need to move the reference from the + "htmlonly" (or "latexonly") node to the actual figure node itself. + """ + for name, explicit in document.nametypes.items(): + if not explicit: + continue + labelid = document.nameids[name] + if labelid is None: + continue + node = document.ids[labelid] + if node.tagname in ('html_only', 'latex_only'): + for n in node: + if n.tagname == 'figure': + sectname = name + for c in n: + if c.tagname == 'caption': + sectname = c.astext() + break + + node['ids'].remove(labelid) + node['names'].remove(name) + n['ids'].append(labelid) + n['names'].append(name) + document.settings.env.labels[name] = \ + document.settings.env.docname, labelid, sectname + break + + +class PlotDirective(Directive): + """The ``.. plot::`` directive, as documented in the module's docstring.""" + + has_content = True + required_arguments = 0 + optional_arguments = 2 + final_argument_whitespace = False + option_spec = { + 'alt': directives.unchanged, + 'height': directives.length_or_unitless, + 'width': directives.length_or_percentage_or_unitless, + 'scale': directives.nonnegative_int, + 'align': Image.align, + 'class': directives.class_option, + 'include-source': _option_boolean, + 'show-source-link': _option_boolean, + 'format': _option_format, + 'context': _option_context, + 'nofigs': directives.flag, + 'caption': directives.unchanged, + } + + def run(self): + """Run the plot directive.""" + try: + return run(self.arguments, self.content, self.options, + self.state_machine, self.state, self.lineno) + except Exception as e: + raise self.error(str(e)) + + +def _copy_css_file(app, exc): + if exc is None and app.builder.format == 'html': + src = cbook._get_data_path('plot_directive/plot_directive.css') + dst = app.outdir / Path('_static') + dst.mkdir(exist_ok=True) + # Use copyfile because we do not want to copy src's permissions. + shutil.copyfile(src, dst / Path('plot_directive.css')) + + +def setup(app): + setup.app = app + setup.config = app.config + setup.confdir = app.confdir + app.add_directive('plot', PlotDirective) + app.add_config_value('plot_pre_code', None, True) + app.add_config_value('plot_include_source', False, True) + app.add_config_value('plot_html_show_source_link', True, True) + app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True) + app.add_config_value('plot_basedir', None, True) + app.add_config_value('plot_html_show_formats', True, True) + app.add_config_value('plot_rcparams', {}, True) + app.add_config_value('plot_apply_rcparams', False, True) + app.add_config_value('plot_working_directory', None, True) + app.add_config_value('plot_template', None, True) + app.add_config_value('plot_srcset', [], True) + app.connect('doctree-read', mark_plot_labels) + app.add_css_file('plot_directive.css') + app.connect('build-finished', _copy_css_file) + metadata = {'parallel_read_safe': True, 'parallel_write_safe': True, + 'version': matplotlib.__version__} + return metadata + + +# ----------------------------------------------------------------------------- +# Doctest handling +# ----------------------------------------------------------------------------- + + +def contains_doctest(text): + try: + # check if it's valid Python as-is + compile(text, '<string>', 'exec') + return False + except SyntaxError: + pass + r = re.compile(r'^\s*>>>', re.M) + m = r.search(text) + return bool(m) + + +def _split_code_at_show(text, function_name): + """Split code at plt.show().""" + + is_doctest = contains_doctest(text) + if function_name is None: + parts = [] + part = [] + for line in text.split("\n"): + if ((not is_doctest and line.startswith('plt.show(')) or + (is_doctest and line.strip() == '>>> plt.show()')): + part.append(line) + parts.append("\n".join(part)) + part = [] + else: + part.append(line) + if "\n".join(part).strip(): + parts.append("\n".join(part)) + else: + parts = [text] + return is_doctest, parts + + +# ----------------------------------------------------------------------------- +# Template +# ----------------------------------------------------------------------------- + +_SOURCECODE = """ +{{ source_code }} + +.. only:: html + + {% if src_name or (html_show_formats and not multi_image) %} + ( + {%- if src_name -%} + :download:`Source code <{{ build_dir }}/{{ src_name }}>` + {%- endif -%} + {%- if html_show_formats and not multi_image -%} + {%- for img in images -%} + {%- for fmt in img.formats -%} + {%- if src_name or not loop.first -%}, {% endif -%} + :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>` + {%- endfor -%} + {%- endfor -%} + {%- endif -%} + ) + {% endif %} +""" + +TEMPLATE_SRCSET = _SOURCECODE + """ + {% for img in images %} + .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }} + {% for option in options -%} + {{ option }} + {% endfor %} + {%- if caption -%} + {{ caption }} {# appropriate leading whitespace added beforehand #} + {% endif -%} + {%- if srcset -%} + :srcset: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }} + {%- for sr in srcset -%} + , {{ build_dir }}/{{ img.basename }}.{{ sr }}.{{ default_fmt }} {{sr}} + {%- endfor -%} + {% endif %} + + {% if html_show_formats and multi_image %} + ( + {%- for fmt in img.formats -%} + {%- if not loop.first -%}, {% endif -%} + :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>` + {%- endfor -%} + ) + {% endif %} + + + {% endfor %} + +.. only:: not html + + {% for img in images %} + .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.* + {% for option in options -%} + {{ option }} + {% endfor -%} + + {{ caption }} {# appropriate leading whitespace added beforehand #} + {% endfor %} + +""" + +TEMPLATE = _SOURCECODE + """ + + {% for img in images %} + .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }} + {% for option in options -%} + {{ option }} + {% endfor %} + + {% if html_show_formats and multi_image -%} + ( + {%- for fmt in img.formats -%} + {%- if not loop.first -%}, {% endif -%} + :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>` + {%- endfor -%} + ) + {%- endif -%} + + {{ caption }} {# appropriate leading whitespace added beforehand #} + {% endfor %} + +.. only:: not html + + {% for img in images %} + .. figure:: {{ build_dir }}/{{ img.basename }}.* + {% for option in options -%} + {{ option }} + {% endfor -%} + + {{ caption }} {# appropriate leading whitespace added beforehand #} + {% endfor %} + +""" + +exception_template = """ +.. only:: html + + [`source code <%(linkdir)s/%(basename)s.py>`__] + +Exception occurred rendering plot. + +""" + +# the context of the plot for all directives specified with the +# :context: option +plot_context = dict() + + +class ImageFile: + def __init__(self, basename, dirname): + self.basename = basename + self.dirname = dirname + self.formats = [] + + def filename(self, format): + return os.path.join(self.dirname, f"{self.basename}.{format}") + + def filenames(self): + return [self.filename(fmt) for fmt in self.formats] + + +def out_of_date(original, derived, includes=None): + """ + Return whether *derived* is out-of-date relative to *original* or any of + the RST files included in it using the RST include directive (*includes*). + *derived* and *original* are full paths, and *includes* is optionally a + list of full paths which may have been included in the *original*. + """ + if not os.path.exists(derived): + return True + + if includes is None: + includes = [] + files_to_check = [original, *includes] + + def out_of_date_one(original, derived_mtime): + return (os.path.exists(original) and + derived_mtime < os.stat(original).st_mtime) + + derived_mtime = os.stat(derived).st_mtime + return any(out_of_date_one(f, derived_mtime) for f in files_to_check) + + +class PlotError(RuntimeError): + pass + + +def _run_code(code, code_path, ns=None, function_name=None): + """ + Import a Python module from a path, and run the function given by + name, if function_name is not None. + """ + + # Change the working directory to the directory of the example, so + # it can get at its data files, if any. Add its path to sys.path + # so it can import any helper modules sitting beside it. + pwd = os.getcwd() + if setup.config.plot_working_directory is not None: + try: + os.chdir(setup.config.plot_working_directory) + except OSError as err: + raise OSError(f'{err}\n`plot_working_directory` option in ' + f'Sphinx configuration file must be a valid ' + f'directory path') from err + except TypeError as err: + raise TypeError(f'{err}\n`plot_working_directory` option in ' + f'Sphinx configuration file must be a string or ' + f'None') from err + elif code_path is not None: + dirname = os.path.abspath(os.path.dirname(code_path)) + os.chdir(dirname) + + with cbook._setattr_cm( + sys, argv=[code_path], path=[os.getcwd(), *sys.path]), \ + contextlib.redirect_stdout(StringIO()): + try: + if ns is None: + ns = {} + if not ns: + if setup.config.plot_pre_code is None: + exec('import numpy as np\n' + 'from matplotlib import pyplot as plt\n', ns) + else: + exec(str(setup.config.plot_pre_code), ns) + if "__main__" in code: + ns['__name__'] = '__main__' + + # Patch out non-interactive show() to avoid triggering a warning. + with cbook._setattr_cm(FigureManagerBase, show=lambda self: None): + exec(code, ns) + if function_name is not None: + exec(function_name + "()", ns) + + except (Exception, SystemExit) as err: + raise PlotError(traceback.format_exc()) from err + finally: + os.chdir(pwd) + return ns + + +def clear_state(plot_rcparams, close=True): + if close: + plt.close('all') + matplotlib.rc_file_defaults() + matplotlib.rcParams.update(plot_rcparams) + + +def get_plot_formats(config): + default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200} + formats = [] + plot_formats = config.plot_formats + for fmt in plot_formats: + if isinstance(fmt, str): + if ':' in fmt: + suffix, dpi = fmt.split(':') + formats.append((str(suffix), int(dpi))) + else: + formats.append((fmt, default_dpi.get(fmt, 80))) + elif isinstance(fmt, (tuple, list)) and len(fmt) == 2: + formats.append((str(fmt[0]), int(fmt[1]))) + else: + raise PlotError('invalid image format "%r" in plot_formats' % fmt) + return formats + + +def _parse_srcset(entries): + """ + Parse srcset for multiples... + """ + srcset = {} + for entry in entries: + entry = entry.strip() + if len(entry) >= 2: + mult = entry[:-1] + srcset[float(mult)] = entry + else: + raise ExtensionError(f'srcset argument {entry!r} is invalid.') + return srcset + + +def render_figures(code, code_path, output_dir, output_base, context, + function_name, config, context_reset=False, + close_figs=False, + code_includes=None): + """ + Run a pyplot script and save the images in *output_dir*. + + Save the images under *output_dir* with file names derived from + *output_base* + """ + + if function_name is not None: + output_base = f'{output_base}_{function_name}' + formats = get_plot_formats(config) + + # Try to determine if all images already exist + + is_doctest, code_pieces = _split_code_at_show(code, function_name) + # Look for single-figure output files first + img = ImageFile(output_base, output_dir) + for format, dpi in formats: + if context or out_of_date(code_path, img.filename(format), + includes=code_includes): + all_exists = False + break + img.formats.append(format) + else: + all_exists = True + + if all_exists: + return [(code, [img])] + + # Then look for multi-figure output files + results = [] + for i, code_piece in enumerate(code_pieces): + images = [] + for j in itertools.count(): + if len(code_pieces) > 1: + img = ImageFile('%s_%02d_%02d' % (output_base, i, j), + output_dir) + else: + img = ImageFile('%s_%02d' % (output_base, j), output_dir) + for fmt, dpi in formats: + if context or out_of_date(code_path, img.filename(fmt), + includes=code_includes): + all_exists = False + break + img.formats.append(fmt) + + # assume that if we have one, we have them all + if not all_exists: + all_exists = (j > 0) + break + images.append(img) + if not all_exists: + break + results.append((code_piece, images)) + else: + all_exists = True + + if all_exists: + return results + + # We didn't find the files, so build them + + results = [] + ns = plot_context if context else {} + + if context_reset: + clear_state(config.plot_rcparams) + plot_context.clear() + + close_figs = not context or close_figs + + for i, code_piece in enumerate(code_pieces): + + if not context or config.plot_apply_rcparams: + clear_state(config.plot_rcparams, close_figs) + elif close_figs: + plt.close('all') + + _run_code(doctest.script_from_examples(code_piece) if is_doctest + else code_piece, + code_path, ns, function_name) + + images = [] + fig_managers = _pylab_helpers.Gcf.get_all_fig_managers() + for j, figman in enumerate(fig_managers): + if len(fig_managers) == 1 and len(code_pieces) == 1: + img = ImageFile(output_base, output_dir) + elif len(code_pieces) == 1: + img = ImageFile("%s_%02d" % (output_base, j), output_dir) + else: + img = ImageFile("%s_%02d_%02d" % (output_base, i, j), + output_dir) + images.append(img) + + for fmt, dpi in formats: + try: + figman.canvas.figure.savefig(img.filename(fmt), dpi=dpi) + if fmt == formats[0][0] and config.plot_srcset: + # save a 2x, 3x etc version of the default... + srcset = _parse_srcset(config.plot_srcset) + for mult, suffix in srcset.items(): + fm = f'{suffix}.{fmt}' + img.formats.append(fm) + figman.canvas.figure.savefig(img.filename(fm), + dpi=int(dpi * mult)) + except Exception as err: + raise PlotError(traceback.format_exc()) from err + img.formats.append(fmt) + + results.append((code_piece, images)) + + if not context or config.plot_apply_rcparams: + clear_state(config.plot_rcparams, close=not context) + + return results + + +def run(arguments, content, options, state_machine, state, lineno): + document = state_machine.document + config = document.settings.env.config + nofigs = 'nofigs' in options + + if config.plot_srcset and setup.app.builder.name == 'singlehtml': + raise ExtensionError( + 'plot_srcset option not compatible with single HTML writer') + + formats = get_plot_formats(config) + default_fmt = formats[0][0] + + options.setdefault('include-source', config.plot_include_source) + options.setdefault('show-source-link', config.plot_html_show_source_link) + + if 'class' in options: + # classes are parsed into a list of string, and output by simply + # printing the list, abusing the fact that RST guarantees to strip + # non-conforming characters + options['class'] = ['plot-directive'] + options['class'] + else: + options.setdefault('class', ['plot-directive']) + keep_context = 'context' in options + context_opt = None if not keep_context else options['context'] + + rst_file = document.attributes['source'] + rst_dir = os.path.dirname(rst_file) + + if len(arguments): + if not config.plot_basedir: + source_file_name = os.path.join(setup.app.builder.srcdir, + directives.uri(arguments[0])) + else: + source_file_name = os.path.join(setup.confdir, config.plot_basedir, + directives.uri(arguments[0])) + # If there is content, it will be passed as a caption. + caption = '\n'.join(content) + + # Enforce unambiguous use of captions. + if "caption" in options: + if caption: + raise ValueError( + 'Caption specified in both content and options.' + ' Please remove ambiguity.' + ) + # Use caption option + caption = options["caption"] + + # If the optional function name is provided, use it + if len(arguments) == 2: + function_name = arguments[1] + else: + function_name = None + + code = Path(source_file_name).read_text(encoding='utf-8') + output_base = os.path.basename(source_file_name) + else: + source_file_name = rst_file + code = textwrap.dedent("\n".join(map(str, content))) + counter = document.attributes.get('_plot_counter', 0) + 1 + document.attributes['_plot_counter'] = counter + base, ext = os.path.splitext(os.path.basename(source_file_name)) + output_base = '%s-%d.py' % (base, counter) + function_name = None + caption = options.get('caption', '') + + base, source_ext = os.path.splitext(output_base) + if source_ext in ('.py', '.rst', '.txt'): + output_base = base + else: + source_ext = '' + + # ensure that LaTeX includegraphics doesn't choke in foo.bar.pdf filenames + output_base = output_base.replace('.', '-') + + # is it in doctest format? + is_doctest = contains_doctest(code) + if 'format' in options: + if options['format'] == 'python': + is_doctest = False + else: + is_doctest = True + + # determine output directory name fragment + source_rel_name = relpath(source_file_name, setup.confdir) + source_rel_dir = os.path.dirname(source_rel_name).lstrip(os.path.sep) + + # build_dir: where to place output files (temporarily) + build_dir = os.path.join(os.path.dirname(setup.app.doctreedir), + 'plot_directive', + source_rel_dir) + # get rid of .. in paths, also changes pathsep + # see note in Python docs for warning about symbolic links on Windows. + # need to compare source and dest paths at end + build_dir = os.path.normpath(build_dir) + os.makedirs(build_dir, exist_ok=True) + + # how to link to files from the RST file + try: + build_dir_link = relpath(build_dir, rst_dir).replace(os.path.sep, '/') + except ValueError: + # on Windows, relpath raises ValueError when path and start are on + # different mounts/drives + build_dir_link = build_dir + + # get list of included rst files so that the output is updated when any + # plots in the included files change. These attributes are modified by the + # include directive (see the docutils.parsers.rst.directives.misc module). + try: + source_file_includes = [os.path.join(os.getcwd(), t[0]) + for t in state.document.include_log] + except AttributeError: + # the document.include_log attribute only exists in docutils >=0.17, + # before that we need to inspect the state machine + possible_sources = {os.path.join(setup.confdir, t[0]) + for t in state_machine.input_lines.items} + source_file_includes = [f for f in possible_sources + if os.path.isfile(f)] + # remove the source file itself from the includes + try: + source_file_includes.remove(source_file_name) + except ValueError: + pass + + # save script (if necessary) + if options['show-source-link']: + Path(build_dir, output_base + source_ext).write_text( + doctest.script_from_examples(code) + if source_file_name == rst_file and is_doctest + else code, + encoding='utf-8') + + # make figures + try: + results = render_figures(code=code, + code_path=source_file_name, + output_dir=build_dir, + output_base=output_base, + context=keep_context, + function_name=function_name, + config=config, + context_reset=context_opt == 'reset', + close_figs=context_opt == 'close-figs', + code_includes=source_file_includes) + errors = [] + except PlotError as err: + reporter = state.memo.reporter + sm = reporter.system_message( + 2, "Exception occurred in plotting {}\n from {}:\n{}".format( + output_base, source_file_name, err), + line=lineno) + results = [(code, [])] + errors = [sm] + + # Properly indent the caption + if caption and config.plot_srcset: + caption = f':caption: {caption}' + elif caption: + caption = '\n' + '\n'.join(' ' + line.strip() + for line in caption.split('\n')) + # generate output restructuredtext + total_lines = [] + for j, (code_piece, images) in enumerate(results): + if options['include-source']: + if is_doctest: + lines = ['', *code_piece.splitlines()] + else: + lines = ['.. code-block:: python', '', + *textwrap.indent(code_piece, ' ').splitlines()] + source_code = "\n".join(lines) + else: + source_code = "" + + if nofigs: + images = [] + + opts = [ + f':{key}: {val}' for key, val in options.items() + if key in ('alt', 'height', 'width', 'scale', 'align', 'class')] + + # Not-None src_name signals the need for a source download in the + # generated html + if j == 0 and options['show-source-link']: + src_name = output_base + source_ext + else: + src_name = None + if config.plot_srcset: + srcset = [*_parse_srcset(config.plot_srcset).values()] + template = TEMPLATE_SRCSET + else: + srcset = None + template = TEMPLATE + + result = jinja2.Template(config.plot_template or template).render( + default_fmt=default_fmt, + build_dir=build_dir_link, + src_name=src_name, + multi_image=len(images) > 1, + options=opts, + srcset=srcset, + images=images, + source_code=source_code, + html_show_formats=config.plot_html_show_formats and len(images), + caption=caption) + total_lines.extend(result.split("\n")) + total_lines.extend("\n") + + if total_lines: + state_machine.insert_input(total_lines, source=source_file_name) + + return errors diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.py new file mode 100644 index 00000000..9077ae47 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.py @@ -0,0 +1,595 @@ +from collections.abc import MutableMapping +import functools + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, _docstring +from matplotlib.artist import allow_rasterization +import matplotlib.transforms as mtransforms +import matplotlib.patches as mpatches +import matplotlib.path as mpath + + +class Spine(mpatches.Patch): + """ + An axis spine -- the line noting the data area boundaries. + + Spines are the lines connecting the axis tick marks and noting the + boundaries of the data area. They can be placed at arbitrary + positions. See `~.Spine.set_position` for more information. + + The default position is ``('outward', 0)``. + + Spines are subclasses of `.Patch`, and inherit much of their behavior. + + Spines draw a line, a circle, or an arc depending on if + `~.Spine.set_patch_line`, `~.Spine.set_patch_circle`, or + `~.Spine.set_patch_arc` has been called. Line-like is the default. + + For examples see :ref:`spines_examples`. + """ + def __str__(self): + return "Spine" + + @_docstring.dedent_interpd + def __init__(self, axes, spine_type, path, **kwargs): + """ + Parameters + ---------- + axes : `~matplotlib.axes.Axes` + The `~.axes.Axes` instance containing the spine. + spine_type : str + The spine type. + path : `~matplotlib.path.Path` + The `.Path` instance used to draw the spine. + + Other Parameters + ---------------- + **kwargs + Valid keyword arguments are: + + %(Patch:kwdoc)s + """ + super().__init__(**kwargs) + self.axes = axes + self.set_figure(self.axes.figure) + self.spine_type = spine_type + self.set_facecolor('none') + self.set_edgecolor(mpl.rcParams['axes.edgecolor']) + self.set_linewidth(mpl.rcParams['axes.linewidth']) + self.set_capstyle('projecting') + self.axis = None + + self.set_zorder(2.5) + self.set_transform(self.axes.transData) # default transform + + self._bounds = None # default bounds + + # Defer initial position determination. (Not much support for + # non-rectangular axes is currently implemented, and this lets + # them pass through the spines machinery without errors.) + self._position = None + _api.check_isinstance(mpath.Path, path=path) + self._path = path + + # To support drawing both linear and circular spines, this + # class implements Patch behavior three ways. If + # self._patch_type == 'line', behave like a mpatches.PathPatch + # instance. If self._patch_type == 'circle', behave like a + # mpatches.Ellipse instance. If self._patch_type == 'arc', behave like + # a mpatches.Arc instance. + self._patch_type = 'line' + + # Behavior copied from mpatches.Ellipse: + # Note: This cannot be calculated until this is added to an Axes + self._patch_transform = mtransforms.IdentityTransform() + + def set_patch_arc(self, center, radius, theta1, theta2): + """Set the spine to be arc-like.""" + self._patch_type = 'arc' + self._center = center + self._width = radius * 2 + self._height = radius * 2 + self._theta1 = theta1 + self._theta2 = theta2 + self._path = mpath.Path.arc(theta1, theta2) + # arc drawn on axes transform + self.set_transform(self.axes.transAxes) + self.stale = True + + def set_patch_circle(self, center, radius): + """Set the spine to be circular.""" + self._patch_type = 'circle' + self._center = center + self._width = radius * 2 + self._height = radius * 2 + # circle drawn on axes transform + self.set_transform(self.axes.transAxes) + self.stale = True + + def set_patch_line(self): + """Set the spine to be linear.""" + self._patch_type = 'line' + self.stale = True + + # Behavior copied from mpatches.Ellipse: + def _recompute_transform(self): + """ + Notes + ----- + This cannot be called until after this has been added to an Axes, + otherwise unit conversion will fail. This makes it very important to + call the accessor method and not directly access the transformation + member variable. + """ + assert self._patch_type in ('arc', 'circle') + center = (self.convert_xunits(self._center[0]), + self.convert_yunits(self._center[1])) + width = self.convert_xunits(self._width) + height = self.convert_yunits(self._height) + self._patch_transform = mtransforms.Affine2D() \ + .scale(width * 0.5, height * 0.5) \ + .translate(*center) + + def get_patch_transform(self): + if self._patch_type in ('arc', 'circle'): + self._recompute_transform() + return self._patch_transform + else: + return super().get_patch_transform() + + def get_window_extent(self, renderer=None): + """ + Return the window extent of the spines in display space, including + padding for ticks (but not their labels) + + See Also + -------- + matplotlib.axes.Axes.get_tightbbox + matplotlib.axes.Axes.get_window_extent + """ + # make sure the location is updated so that transforms etc are correct: + self._adjust_location() + bb = super().get_window_extent(renderer=renderer) + if self.axis is None or not self.axis.get_visible(): + return bb + bboxes = [bb] + drawn_ticks = self.axis._update_ticks() + + major_tick = next(iter({*drawn_ticks} & {*self.axis.majorTicks}), None) + minor_tick = next(iter({*drawn_ticks} & {*self.axis.minorTicks}), None) + for tick in [major_tick, minor_tick]: + if tick is None: + continue + bb0 = bb.frozen() + tickl = tick._size + tickdir = tick._tickdir + if tickdir == 'out': + padout = 1 + padin = 0 + elif tickdir == 'in': + padout = 0 + padin = 1 + else: + padout = 0.5 + padin = 0.5 + padout = padout * tickl / 72 * self.figure.dpi + padin = padin * tickl / 72 * self.figure.dpi + + if tick.tick1line.get_visible(): + if self.spine_type == 'left': + bb0.x0 = bb0.x0 - padout + bb0.x1 = bb0.x1 + padin + elif self.spine_type == 'bottom': + bb0.y0 = bb0.y0 - padout + bb0.y1 = bb0.y1 + padin + + if tick.tick2line.get_visible(): + if self.spine_type == 'right': + bb0.x1 = bb0.x1 + padout + bb0.x0 = bb0.x0 - padin + elif self.spine_type == 'top': + bb0.y1 = bb0.y1 + padout + bb0.y0 = bb0.y0 - padout + bboxes.append(bb0) + + return mtransforms.Bbox.union(bboxes) + + def get_path(self): + return self._path + + def _ensure_position_is_set(self): + if self._position is None: + # default position + self._position = ('outward', 0.0) # in points + self.set_position(self._position) + + def register_axis(self, axis): + """ + Register an axis. + + An axis should be registered with its corresponding spine from + the Axes instance. This allows the spine to clear any axis + properties when needed. + """ + self.axis = axis + self.stale = True + + def clear(self): + """Clear the current spine.""" + self._clear() + if self.axis is not None: + self.axis.clear() + + def _clear(self): + """ + Clear things directly related to the spine. + + In this way it is possible to avoid clearing the Axis as well when calling + from library code where it is known that the Axis is cleared separately. + """ + self._position = None # clear position + + def _adjust_location(self): + """Automatically set spine bounds to the view interval.""" + + if self.spine_type == 'circle': + return + + if self._bounds is not None: + low, high = self._bounds + elif self.spine_type in ('left', 'right'): + low, high = self.axes.viewLim.intervaly + elif self.spine_type in ('top', 'bottom'): + low, high = self.axes.viewLim.intervalx + else: + raise ValueError(f'unknown spine spine_type: {self.spine_type}') + + if self._patch_type == 'arc': + if self.spine_type in ('bottom', 'top'): + try: + direction = self.axes.get_theta_direction() + except AttributeError: + direction = 1 + try: + offset = self.axes.get_theta_offset() + except AttributeError: + offset = 0 + low = low * direction + offset + high = high * direction + offset + if low > high: + low, high = high, low + + self._path = mpath.Path.arc(np.rad2deg(low), np.rad2deg(high)) + + if self.spine_type == 'bottom': + rmin, rmax = self.axes.viewLim.intervaly + try: + rorigin = self.axes.get_rorigin() + except AttributeError: + rorigin = rmin + scaled_diameter = (rmin - rorigin) / (rmax - rorigin) + self._height = scaled_diameter + self._width = scaled_diameter + + else: + raise ValueError('unable to set bounds for spine "%s"' % + self.spine_type) + else: + v1 = self._path.vertices + assert v1.shape == (2, 2), 'unexpected vertices shape' + if self.spine_type in ['left', 'right']: + v1[0, 1] = low + v1[1, 1] = high + elif self.spine_type in ['bottom', 'top']: + v1[0, 0] = low + v1[1, 0] = high + else: + raise ValueError('unable to set bounds for spine "%s"' % + self.spine_type) + + @allow_rasterization + def draw(self, renderer): + self._adjust_location() + ret = super().draw(renderer) + self.stale = False + return ret + + def set_position(self, position): + """ + Set the position of the spine. + + Spine position is specified by a 2 tuple of (position type, + amount). The position types are: + + * 'outward': place the spine out from the data area by the specified + number of points. (Negative values place the spine inwards.) + * 'axes': place the spine at the specified Axes coordinate (0 to 1). + * 'data': place the spine at the specified data coordinate. + + Additionally, shorthand notations define a special positions: + + * 'center' -> ``('axes', 0.5)`` + * 'zero' -> ``('data', 0.0)`` + + Examples + -------- + :doc:`/gallery/spines/spine_placement_demo` + """ + if position in ('center', 'zero'): # special positions + pass + else: + if len(position) != 2: + raise ValueError("position should be 'center' or 2-tuple") + if position[0] not in ['outward', 'axes', 'data']: + raise ValueError("position[0] should be one of 'outward', " + "'axes', or 'data' ") + self._position = position + self.set_transform(self.get_spine_transform()) + if self.axis is not None: + self.axis.reset_ticks() + self.stale = True + + def get_position(self): + """Return the spine position.""" + self._ensure_position_is_set() + return self._position + + def get_spine_transform(self): + """Return the spine transform.""" + self._ensure_position_is_set() + + position = self._position + if isinstance(position, str): + if position == 'center': + position = ('axes', 0.5) + elif position == 'zero': + position = ('data', 0) + assert len(position) == 2, 'position should be 2-tuple' + position_type, amount = position + _api.check_in_list(['axes', 'outward', 'data'], + position_type=position_type) + if self.spine_type in ['left', 'right']: + base_transform = self.axes.get_yaxis_transform(which='grid') + elif self.spine_type in ['top', 'bottom']: + base_transform = self.axes.get_xaxis_transform(which='grid') + else: + raise ValueError(f'unknown spine spine_type: {self.spine_type!r}') + + if position_type == 'outward': + if amount == 0: # short circuit commonest case + return base_transform + else: + offset_vec = {'left': (-1, 0), 'right': (1, 0), + 'bottom': (0, -1), 'top': (0, 1), + }[self.spine_type] + # calculate x and y offset in dots + offset_dots = amount * np.array(offset_vec) / 72 + return (base_transform + + mtransforms.ScaledTranslation( + *offset_dots, self.figure.dpi_scale_trans)) + elif position_type == 'axes': + if self.spine_type in ['left', 'right']: + # keep y unchanged, fix x at amount + return (mtransforms.Affine2D.from_values(0, 0, 0, 1, amount, 0) + + base_transform) + elif self.spine_type in ['bottom', 'top']: + # keep x unchanged, fix y at amount + return (mtransforms.Affine2D.from_values(1, 0, 0, 0, 0, amount) + + base_transform) + elif position_type == 'data': + if self.spine_type in ('right', 'top'): + # The right and top spines have a default position of 1 in + # axes coordinates. When specifying the position in data + # coordinates, we need to calculate the position relative to 0. + amount -= 1 + if self.spine_type in ('left', 'right'): + return mtransforms.blended_transform_factory( + mtransforms.Affine2D().translate(amount, 0) + + self.axes.transData, + self.axes.transData) + elif self.spine_type in ('bottom', 'top'): + return mtransforms.blended_transform_factory( + self.axes.transData, + mtransforms.Affine2D().translate(0, amount) + + self.axes.transData) + + def set_bounds(self, low=None, high=None): + """ + Set the spine bounds. + + Parameters + ---------- + low : float or None, optional + The lower spine bound. Passing *None* leaves the limit unchanged. + + The bounds may also be passed as the tuple (*low*, *high*) as the + first positional argument. + + .. ACCEPTS: (low: float, high: float) + + high : float or None, optional + The higher spine bound. Passing *None* leaves the limit unchanged. + """ + if self.spine_type == 'circle': + raise ValueError( + 'set_bounds() method incompatible with circular spines') + if high is None and np.iterable(low): + low, high = low + old_low, old_high = self.get_bounds() or (None, None) + if low is None: + low = old_low + if high is None: + high = old_high + self._bounds = (low, high) + self.stale = True + + def get_bounds(self): + """Get the bounds of the spine.""" + return self._bounds + + @classmethod + def linear_spine(cls, axes, spine_type, **kwargs): + """Create and return a linear `Spine`.""" + # all values of 0.999 get replaced upon call to set_bounds() + if spine_type == 'left': + path = mpath.Path([(0.0, 0.999), (0.0, 0.999)]) + elif spine_type == 'right': + path = mpath.Path([(1.0, 0.999), (1.0, 0.999)]) + elif spine_type == 'bottom': + path = mpath.Path([(0.999, 0.0), (0.999, 0.0)]) + elif spine_type == 'top': + path = mpath.Path([(0.999, 1.0), (0.999, 1.0)]) + else: + raise ValueError('unable to make path for spine "%s"' % spine_type) + result = cls(axes, spine_type, path, **kwargs) + result.set_visible(mpl.rcParams[f'axes.spines.{spine_type}']) + + return result + + @classmethod + def arc_spine(cls, axes, spine_type, center, radius, theta1, theta2, + **kwargs): + """Create and return an arc `Spine`.""" + path = mpath.Path.arc(theta1, theta2) + result = cls(axes, spine_type, path, **kwargs) + result.set_patch_arc(center, radius, theta1, theta2) + return result + + @classmethod + def circular_spine(cls, axes, center, radius, **kwargs): + """Create and return a circular `Spine`.""" + path = mpath.Path.unit_circle() + spine_type = 'circle' + result = cls(axes, spine_type, path, **kwargs) + result.set_patch_circle(center, radius) + return result + + def set_color(self, c): + """ + Set the edgecolor. + + Parameters + ---------- + c : color + + Notes + ----- + This method does not modify the facecolor (which defaults to "none"), + unlike the `.Patch.set_color` method defined in the parent class. Use + `.Patch.set_facecolor` to set the facecolor. + """ + self.set_edgecolor(c) + self.stale = True + + +class SpinesProxy: + """ + A proxy to broadcast ``set_*()`` and ``set()`` method calls to contained `.Spines`. + + The proxy cannot be used for any other operations on its members. + + The supported methods are determined dynamically based on the contained + spines. If not all spines support a given method, it's executed only on + the subset of spines that support it. + """ + def __init__(self, spine_dict): + self._spine_dict = spine_dict + + def __getattr__(self, name): + broadcast_targets = [spine for spine in self._spine_dict.values() + if hasattr(spine, name)] + if (name != 'set' and not name.startswith('set_')) or not broadcast_targets: + raise AttributeError( + f"'SpinesProxy' object has no attribute '{name}'") + + def x(_targets, _funcname, *args, **kwargs): + for spine in _targets: + getattr(spine, _funcname)(*args, **kwargs) + x = functools.partial(x, broadcast_targets, name) + x.__doc__ = broadcast_targets[0].__doc__ + return x + + def __dir__(self): + names = [] + for spine in self._spine_dict.values(): + names.extend(name + for name in dir(spine) if name.startswith('set_')) + return list(sorted(set(names))) + + +class Spines(MutableMapping): + r""" + The container of all `.Spine`\s in an Axes. + + The interface is dict-like mapping names (e.g. 'left') to `.Spine` objects. + Additionally, it implements some pandas.Series-like features like accessing + elements by attribute:: + + spines['top'].set_visible(False) + spines.top.set_visible(False) + + Multiple spines can be addressed simultaneously by passing a list:: + + spines[['top', 'right']].set_visible(False) + + Use an open slice to address all spines:: + + spines[:].set_visible(False) + + The latter two indexing methods will return a `SpinesProxy` that broadcasts all + ``set_*()`` and ``set()`` calls to its members, but cannot be used for any other + operation. + """ + def __init__(self, **kwargs): + self._dict = kwargs + + @classmethod + def from_dict(cls, d): + return cls(**d) + + def __getstate__(self): + return self._dict + + def __setstate__(self, state): + self.__init__(**state) + + def __getattr__(self, name): + try: + return self._dict[name] + except KeyError: + raise AttributeError( + f"'Spines' object does not contain a '{name}' spine") + + def __getitem__(self, key): + if isinstance(key, list): + unknown_keys = [k for k in key if k not in self._dict] + if unknown_keys: + raise KeyError(', '.join(unknown_keys)) + return SpinesProxy({k: v for k, v in self._dict.items() + if k in key}) + if isinstance(key, tuple): + raise ValueError('Multiple spines must be passed as a single list') + if isinstance(key, slice): + if key.start is None and key.stop is None and key.step is None: + return SpinesProxy(self._dict) + else: + raise ValueError( + 'Spines does not support slicing except for the fully ' + 'open slice [:] to access all spines.') + return self._dict[key] + + def __setitem__(self, key, value): + # TODO: Do we want to deprecate adding spines? + self._dict[key] = value + + def __delitem__(self, key): + # TODO: Do we want to deprecate deleting spines? + del self._dict[key] + + def __iter__(self): + return iter(self._dict) + + def __len__(self): + return len(self._dict) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.pyi new file mode 100644 index 00000000..0f06a6d1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/spines.pyi @@ -0,0 +1,83 @@ +from collections.abc import Callable, Iterator, MutableMapping +from typing import Any, Literal, TypeVar, overload + +import matplotlib.patches as mpatches +from matplotlib.axes import Axes +from matplotlib.axis import Axis +from matplotlib.path import Path +from matplotlib.transforms import Transform +from matplotlib.typing import ColorType + +class Spine(mpatches.Patch): + axes: Axes + spine_type: str + axis: Axis | None + def __init__(self, axes: Axes, spine_type: str, path: Path, **kwargs) -> None: ... + def set_patch_arc( + self, center: tuple[float, float], radius: float, theta1: float, theta2: float + ) -> None: ... + def set_patch_circle(self, center: tuple[float, float], radius: float) -> None: ... + def set_patch_line(self) -> None: ... + def get_patch_transform(self) -> Transform: ... + def get_path(self) -> Path: ... + def register_axis(self, axis: Axis) -> None: ... + def clear(self) -> None: ... + def set_position( + self, + position: Literal["center", "zero"] + | tuple[Literal["outward", "axes", "data"], float], + ) -> None: ... + def get_position( + self, + ) -> Literal["center", "zero"] | tuple[ + Literal["outward", "axes", "data"], float + ]: ... + def get_spine_transform(self) -> Transform: ... + def set_bounds(self, low: float | None = ..., high: float | None = ...) -> None: ... + def get_bounds(self) -> tuple[float, float]: ... + + _T = TypeVar("_T", bound=Spine) + @classmethod + def linear_spine( + cls: type[_T], + axes: Axes, + spine_type: Literal["left", "right", "bottom", "top"], + **kwargs + ) -> _T: ... + @classmethod + def arc_spine( + cls: type[_T], + axes: Axes, + spine_type: Literal["left", "right", "bottom", "top"], + center: tuple[float, float], + radius: float, + theta1: float, + theta2: float, + **kwargs + ) -> _T: ... + @classmethod + def circular_spine( + cls: type[_T], axes: Axes, center: tuple[float, float], radius: float, **kwargs + ) -> _T: ... + def set_color(self, c: ColorType | None) -> None: ... + +class SpinesProxy: + def __init__(self, spine_dict: dict[str, Spine]) -> None: ... + def __getattr__(self, name: str) -> Callable[..., None]: ... + def __dir__(self) -> list[str]: ... + +class Spines(MutableMapping[str, Spine]): + def __init__(self, **kwargs: Spine) -> None: ... + @classmethod + def from_dict(cls, d: dict[str, Spine]) -> Spines: ... + def __getattr__(self, name: str) -> Spine: ... + @overload + def __getitem__(self, key: str) -> Spine: ... + @overload + def __getitem__(self, key: list[str]) -> SpinesProxy: ... + @overload + def __getitem__(self, key: slice) -> SpinesProxy: ... + def __setitem__(self, key: str, value: Spine) -> None: ... + def __delitem__(self, key: str) -> None: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.py new file mode 100644 index 00000000..26295936 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.py @@ -0,0 +1,127 @@ +""" +Stacked area plot for 1D arrays inspired by Douglas Y'barbo's stackoverflow +answer: +https://stackoverflow.com/q/2225995/ + +(https://stackoverflow.com/users/66549/doug) +""" + +import itertools + +import numpy as np + +from matplotlib import _api + +__all__ = ['stackplot'] + + +def stackplot(axes, x, *args, + labels=(), colors=None, baseline='zero', + **kwargs): + """ + Draw a stacked area plot. + + Parameters + ---------- + x : (N,) array-like + + y : (M, N) array-like + The data is assumed to be unstacked. Each of the following + calls is legal:: + + stackplot(x, y) # where y has shape (M, N) + stackplot(x, y1, y2, y3) # where y1, y2, y3, y4 have length N + + baseline : {'zero', 'sym', 'wiggle', 'weighted_wiggle'} + Method used to calculate the baseline: + + - ``'zero'``: Constant zero baseline, i.e. a simple stacked plot. + - ``'sym'``: Symmetric around zero and is sometimes called + 'ThemeRiver'. + - ``'wiggle'``: Minimizes the sum of the squared slopes. + - ``'weighted_wiggle'``: Does the same but weights to account for + size of each layer. It is also called 'Streamgraph'-layout. More + details can be found at http://leebyron.com/streamgraph/. + + labels : list of str, optional + A sequence of labels to assign to each data series. If unspecified, + then no labels will be applied to artists. + + colors : list of color, optional + A sequence of colors to be cycled through and used to color the stacked + areas. The sequence need not be exactly the same length as the number + of provided *y*, in which case the colors will repeat from the + beginning. + + If not specified, the colors from the Axes property cycle will be used. + + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + **kwargs + All other keyword arguments are passed to `.Axes.fill_between`. + + Returns + ------- + list of `.PolyCollection` + A list of `.PolyCollection` instances, one for each element in the + stacked area plot. + """ + + y = np.vstack(args) + + labels = iter(labels) + if colors is not None: + colors = itertools.cycle(colors) + else: + colors = (axes._get_lines.get_next_color() for _ in y) + + # Assume data passed has not been 'stacked', so stack it here. + # We'll need a float buffer for the upcoming calculations. + stack = np.cumsum(y, axis=0, dtype=np.promote_types(y.dtype, np.float32)) + + _api.check_in_list(['zero', 'sym', 'wiggle', 'weighted_wiggle'], + baseline=baseline) + if baseline == 'zero': + first_line = 0. + + elif baseline == 'sym': + first_line = -np.sum(y, 0) * 0.5 + stack += first_line[None, :] + + elif baseline == 'wiggle': + m = y.shape[0] + first_line = (y * (m - 0.5 - np.arange(m)[:, None])).sum(0) + first_line /= -m + stack += first_line + + elif baseline == 'weighted_wiggle': + total = np.sum(y, 0) + # multiply by 1/total (or zero) to avoid infinities in the division: + inv_total = np.zeros_like(total) + mask = total > 0 + inv_total[mask] = 1.0 / total[mask] + increase = np.hstack((y[:, 0:1], np.diff(y))) + below_size = total - stack + below_size += 0.5 * y + move_up = below_size * inv_total + move_up[:, 0] = 0.5 + center = (move_up - 0.5) * increase + center = np.cumsum(center.sum(0)) + first_line = center - 0.5 * total + stack += first_line + + # Color between x = 0 and the first array. + coll = axes.fill_between(x, first_line, stack[0, :], + facecolor=next(colors), label=next(labels, None), + **kwargs) + coll.sticky_edges.y[:] = [0] + r = [coll] + + # Color between array i-1 and array i + for i in range(len(y) - 1): + r.append(axes.fill_between(x, stack[i, :], stack[i + 1, :], + facecolor=next(colors), + label=next(labels, None), + **kwargs)) + return r diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.pyi new file mode 100644 index 00000000..503e2826 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/stackplot.pyi @@ -0,0 +1,17 @@ +from matplotlib.axes import Axes +from matplotlib.collections import PolyCollection + +from collections.abc import Iterable +from typing import Literal +from numpy.typing import ArrayLike +from matplotlib.typing import ColorType + +def stackplot( + axes: Axes, + x: ArrayLike, + *args: ArrayLike, + labels: Iterable[str] = ..., + colors: Iterable[ColorType] | None = ..., + baseline: Literal["zero", "sym", "wiggle", "weighted_wiggle"] = ..., + **kwargs +) -> list[PolyCollection]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.py new file mode 100644 index 00000000..daae8fc5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.py @@ -0,0 +1,712 @@ +""" +Streamline plotting for 2D vector fields. + +""" + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cm, patches +import matplotlib.colors as mcolors +import matplotlib.collections as mcollections +import matplotlib.lines as mlines + + +__all__ = ['streamplot'] + + +def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, + cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', + minlength=0.1, transform=None, zorder=None, start_points=None, + maxlength=4.0, integration_direction='both', + broken_streamlines=True): + """ + Draw streamlines of a vector flow. + + Parameters + ---------- + x, y : 1D/2D arrays + Evenly spaced strictly increasing arrays to make a grid. If 2D, all + rows of *x* must be equal and all columns of *y* must be equal; i.e., + they must be as if generated by ``np.meshgrid(x_1d, y_1d)``. + u, v : 2D arrays + *x* and *y*-velocities. The number of rows and columns must match + the length of *y* and *x*, respectively. + density : float or (float, float) + Controls the closeness of streamlines. When ``density = 1``, the domain + is divided into a 30x30 grid. *density* linearly scales this grid. + Each cell in the grid can have, at most, one traversing streamline. + For different densities in each direction, use a tuple + (density_x, density_y). + linewidth : float or 2D array + The width of the streamlines. With a 2D array the line width can be + varied across the grid. The array must have the same shape as *u* + and *v*. + color : color or 2D array + The streamline color. If given an array, its values are converted to + colors using *cmap* and *norm*. The array must have the same shape + as *u* and *v*. + cmap, norm + Data normalization and colormapping parameters for *color*; only used + if *color* is an array of floats. See `~.Axes.imshow` for a detailed + description. + arrowsize : float + Scaling factor for the arrow size. + arrowstyle : str + Arrow style specification. + See `~matplotlib.patches.FancyArrowPatch`. + minlength : float + Minimum length of streamline in axes coordinates. + start_points : (N, 2) array + Coordinates of starting points for the streamlines in data coordinates + (the same coordinates as the *x* and *y* arrays). + zorder : float + The zorder of the streamlines and arrows. + Artists with lower zorder values are drawn first. + maxlength : float + Maximum length of streamline in axes coordinates. + integration_direction : {'forward', 'backward', 'both'}, default: 'both' + Integrate the streamline in forward, backward or both directions. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + broken_streamlines : boolean, default: True + If False, forces streamlines to continue until they + leave the plot domain. If True, they may be terminated if they + come too close to another streamline. + + Returns + ------- + StreamplotSet + Container object with attributes + + - ``lines``: `.LineCollection` of streamlines + + - ``arrows``: `.PatchCollection` containing `.FancyArrowPatch` + objects representing the arrows half-way along streamlines. + + This container will probably change in the future to allow changes + to the colormap, alpha, etc. for both lines and arrows, but these + changes should be backward compatible. + """ + grid = Grid(x, y) + mask = StreamMask(density) + dmap = DomainMap(grid, mask) + + if zorder is None: + zorder = mlines.Line2D.zorder + + # default to data coordinates + if transform is None: + transform = axes.transData + + if color is None: + color = axes._get_lines.get_next_color() + + if linewidth is None: + linewidth = mpl.rcParams['lines.linewidth'] + + line_kw = {} + arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) + + _api.check_in_list(['both', 'forward', 'backward'], + integration_direction=integration_direction) + + if integration_direction == 'both': + maxlength /= 2. + + use_multicolor_lines = isinstance(color, np.ndarray) + if use_multicolor_lines: + if color.shape != grid.shape: + raise ValueError("If 'color' is given, it must match the shape of " + "the (x, y) grid") + line_colors = [[]] # Empty entry allows concatenation of zero arrays. + color = np.ma.masked_invalid(color) + else: + line_kw['color'] = color + arrow_kw['color'] = color + + if isinstance(linewidth, np.ndarray): + if linewidth.shape != grid.shape: + raise ValueError("If 'linewidth' is given, it must match the " + "shape of the (x, y) grid") + line_kw['linewidth'] = [] + else: + line_kw['linewidth'] = linewidth + arrow_kw['linewidth'] = linewidth + + line_kw['zorder'] = zorder + arrow_kw['zorder'] = zorder + + # Sanity checks. + if u.shape != grid.shape or v.shape != grid.shape: + raise ValueError("'u' and 'v' must match the shape of the (x, y) grid") + + u = np.ma.masked_invalid(u) + v = np.ma.masked_invalid(v) + + integrate = _get_integrator(u, v, dmap, minlength, maxlength, + integration_direction) + + trajectories = [] + if start_points is None: + for xm, ym in _gen_starting_points(mask.shape): + if mask[ym, xm] == 0: + xg, yg = dmap.mask2grid(xm, ym) + t = integrate(xg, yg, broken_streamlines) + if t is not None: + trajectories.append(t) + else: + sp2 = np.asanyarray(start_points, dtype=float).copy() + + # Check if start_points are outside the data boundaries + for xs, ys in sp2: + if not (grid.x_origin <= xs <= grid.x_origin + grid.width and + grid.y_origin <= ys <= grid.y_origin + grid.height): + raise ValueError(f"Starting point ({xs}, {ys}) outside of " + "data boundaries") + + # Convert start_points from data to array coords + # Shift the seed points from the bottom left of the data so that + # data2grid works properly. + sp2[:, 0] -= grid.x_origin + sp2[:, 1] -= grid.y_origin + + for xs, ys in sp2: + xg, yg = dmap.data2grid(xs, ys) + # Floating point issues can cause xg, yg to be slightly out of + # bounds for xs, ys on the upper boundaries. Because we have + # already checked that the starting points are within the original + # grid, clip the xg, yg to the grid to work around this issue + xg = np.clip(xg, 0, grid.nx - 1) + yg = np.clip(yg, 0, grid.ny - 1) + + t = integrate(xg, yg, broken_streamlines) + if t is not None: + trajectories.append(t) + + if use_multicolor_lines: + if norm is None: + norm = mcolors.Normalize(color.min(), color.max()) + cmap = cm._ensure_cmap(cmap) + + streamlines = [] + arrows = [] + for t in trajectories: + tgx, tgy = t.T + # Rescale from grid-coordinates to data-coordinates. + tx, ty = dmap.grid2data(tgx, tgy) + tx += grid.x_origin + ty += grid.y_origin + + # Create multiple tiny segments if varying width or color is given + if isinstance(linewidth, np.ndarray) or use_multicolor_lines: + points = np.transpose([tx, ty]).reshape(-1, 1, 2) + streamlines.extend(np.hstack([points[:-1], points[1:]])) + else: + points = np.transpose([tx, ty]) + streamlines.append(points) + + # Add arrows halfway along each trajectory. + s = np.cumsum(np.hypot(np.diff(tx), np.diff(ty))) + n = np.searchsorted(s, s[-1] / 2.) + arrow_tail = (tx[n], ty[n]) + arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2])) + + if isinstance(linewidth, np.ndarray): + line_widths = interpgrid(linewidth, tgx, tgy)[:-1] + line_kw['linewidth'].extend(line_widths) + arrow_kw['linewidth'] = line_widths[n] + + if use_multicolor_lines: + color_values = interpgrid(color, tgx, tgy)[:-1] + line_colors.append(color_values) + arrow_kw['color'] = cmap(norm(color_values[n])) + + p = patches.FancyArrowPatch( + arrow_tail, arrow_head, transform=transform, **arrow_kw) + arrows.append(p) + + lc = mcollections.LineCollection( + streamlines, transform=transform, **line_kw) + lc.sticky_edges.x[:] = [grid.x_origin, grid.x_origin + grid.width] + lc.sticky_edges.y[:] = [grid.y_origin, grid.y_origin + grid.height] + if use_multicolor_lines: + lc.set_array(np.ma.hstack(line_colors)) + lc.set_cmap(cmap) + lc.set_norm(norm) + axes.add_collection(lc) + + ac = mcollections.PatchCollection(arrows) + # Adding the collection itself is broken; see #2341. + for p in arrows: + axes.add_patch(p) + + axes.autoscale_view() + stream_container = StreamplotSet(lc, ac) + return stream_container + + +class StreamplotSet: + + def __init__(self, lines, arrows): + self.lines = lines + self.arrows = arrows + + +# Coordinate definitions +# ======================== + +class DomainMap: + """ + Map representing different coordinate systems. + + Coordinate definitions: + + * axes-coordinates goes from 0 to 1 in the domain. + * data-coordinates are specified by the input x-y coordinates. + * grid-coordinates goes from 0 to N and 0 to M for an N x M grid, + where N and M match the shape of the input data. + * mask-coordinates goes from 0 to N and 0 to M for an N x M mask, + where N and M are user-specified to control the density of streamlines. + + This class also has methods for adding trajectories to the StreamMask. + Before adding a trajectory, run `start_trajectory` to keep track of regions + crossed by a given trajectory. Later, if you decide the trajectory is bad + (e.g., if the trajectory is very short) just call `undo_trajectory`. + """ + + def __init__(self, grid, mask): + self.grid = grid + self.mask = mask + # Constants for conversion between grid- and mask-coordinates + self.x_grid2mask = (mask.nx - 1) / (grid.nx - 1) + self.y_grid2mask = (mask.ny - 1) / (grid.ny - 1) + + self.x_mask2grid = 1. / self.x_grid2mask + self.y_mask2grid = 1. / self.y_grid2mask + + self.x_data2grid = 1. / grid.dx + self.y_data2grid = 1. / grid.dy + + def grid2mask(self, xi, yi): + """Return nearest space in mask-coords from given grid-coords.""" + return round(xi * self.x_grid2mask), round(yi * self.y_grid2mask) + + def mask2grid(self, xm, ym): + return xm * self.x_mask2grid, ym * self.y_mask2grid + + def data2grid(self, xd, yd): + return xd * self.x_data2grid, yd * self.y_data2grid + + def grid2data(self, xg, yg): + return xg / self.x_data2grid, yg / self.y_data2grid + + def start_trajectory(self, xg, yg, broken_streamlines=True): + xm, ym = self.grid2mask(xg, yg) + self.mask._start_trajectory(xm, ym, broken_streamlines) + + def reset_start_point(self, xg, yg): + xm, ym = self.grid2mask(xg, yg) + self.mask._current_xy = (xm, ym) + + def update_trajectory(self, xg, yg, broken_streamlines=True): + if not self.grid.within_grid(xg, yg): + raise InvalidIndexError + xm, ym = self.grid2mask(xg, yg) + self.mask._update_trajectory(xm, ym, broken_streamlines) + + def undo_trajectory(self): + self.mask._undo_trajectory() + + +class Grid: + """Grid of data.""" + def __init__(self, x, y): + + if np.ndim(x) == 1: + pass + elif np.ndim(x) == 2: + x_row = x[0] + if not np.allclose(x_row, x): + raise ValueError("The rows of 'x' must be equal") + x = x_row + else: + raise ValueError("'x' can have at maximum 2 dimensions") + + if np.ndim(y) == 1: + pass + elif np.ndim(y) == 2: + yt = np.transpose(y) # Also works for nested lists. + y_col = yt[0] + if not np.allclose(y_col, yt): + raise ValueError("The columns of 'y' must be equal") + y = y_col + else: + raise ValueError("'y' can have at maximum 2 dimensions") + + if not (np.diff(x) > 0).all(): + raise ValueError("'x' must be strictly increasing") + if not (np.diff(y) > 0).all(): + raise ValueError("'y' must be strictly increasing") + + self.nx = len(x) + self.ny = len(y) + + self.dx = x[1] - x[0] + self.dy = y[1] - y[0] + + self.x_origin = x[0] + self.y_origin = y[0] + + self.width = x[-1] - x[0] + self.height = y[-1] - y[0] + + if not np.allclose(np.diff(x), self.width / (self.nx - 1)): + raise ValueError("'x' values must be equally spaced") + if not np.allclose(np.diff(y), self.height / (self.ny - 1)): + raise ValueError("'y' values must be equally spaced") + + @property + def shape(self): + return self.ny, self.nx + + def within_grid(self, xi, yi): + """Return whether (*xi*, *yi*) is a valid index of the grid.""" + # Note that xi/yi can be floats; so, for example, we can't simply check + # `xi < self.nx` since *xi* can be `self.nx - 1 < xi < self.nx` + return 0 <= xi <= self.nx - 1 and 0 <= yi <= self.ny - 1 + + +class StreamMask: + """ + Mask to keep track of discrete regions crossed by streamlines. + + The resolution of this grid determines the approximate spacing between + trajectories. Streamlines are only allowed to pass through zeroed cells: + When a streamline enters a cell, that cell is set to 1, and no new + streamlines are allowed to enter. + """ + + def __init__(self, density): + try: + self.nx, self.ny = (30 * np.broadcast_to(density, 2)).astype(int) + except ValueError as err: + raise ValueError("'density' must be a scalar or be of length " + "2") from err + if self.nx < 0 or self.ny < 0: + raise ValueError("'density' must be positive") + self._mask = np.zeros((self.ny, self.nx)) + self.shape = self._mask.shape + + self._current_xy = None + + def __getitem__(self, args): + return self._mask[args] + + def _start_trajectory(self, xm, ym, broken_streamlines=True): + """Start recording streamline trajectory""" + self._traj = [] + self._update_trajectory(xm, ym, broken_streamlines) + + def _undo_trajectory(self): + """Remove current trajectory from mask""" + for t in self._traj: + self._mask[t] = 0 + + def _update_trajectory(self, xm, ym, broken_streamlines=True): + """ + Update current trajectory position in mask. + + If the new position has already been filled, raise `InvalidIndexError`. + """ + if self._current_xy != (xm, ym): + if self[ym, xm] == 0: + self._traj.append((ym, xm)) + self._mask[ym, xm] = 1 + self._current_xy = (xm, ym) + else: + if broken_streamlines: + raise InvalidIndexError + else: + pass + + +class InvalidIndexError(Exception): + pass + + +class TerminateTrajectory(Exception): + pass + + +# Integrator definitions +# ======================= + +def _get_integrator(u, v, dmap, minlength, maxlength, integration_direction): + + # rescale velocity onto grid-coordinates for integrations. + u, v = dmap.data2grid(u, v) + + # speed (path length) will be in axes-coordinates + u_ax = u / (dmap.grid.nx - 1) + v_ax = v / (dmap.grid.ny - 1) + speed = np.ma.sqrt(u_ax ** 2 + v_ax ** 2) + + def forward_time(xi, yi): + if not dmap.grid.within_grid(xi, yi): + raise OutOfBounds + ds_dt = interpgrid(speed, xi, yi) + if ds_dt == 0: + raise TerminateTrajectory() + dt_ds = 1. / ds_dt + ui = interpgrid(u, xi, yi) + vi = interpgrid(v, xi, yi) + return ui * dt_ds, vi * dt_ds + + def backward_time(xi, yi): + dxi, dyi = forward_time(xi, yi) + return -dxi, -dyi + + def integrate(x0, y0, broken_streamlines=True): + """ + Return x, y grid-coordinates of trajectory based on starting point. + + Integrate both forward and backward in time from starting point in + grid coordinates. + + Integration is terminated when a trajectory reaches a domain boundary + or when it crosses into an already occupied cell in the StreamMask. The + resulting trajectory is None if it is shorter than `minlength`. + """ + + stotal, xy_traj = 0., [] + + try: + dmap.start_trajectory(x0, y0, broken_streamlines) + except InvalidIndexError: + return None + if integration_direction in ['both', 'backward']: + s, xyt = _integrate_rk12(x0, y0, dmap, backward_time, maxlength, + broken_streamlines) + stotal += s + xy_traj += xyt[::-1] + + if integration_direction in ['both', 'forward']: + dmap.reset_start_point(x0, y0) + s, xyt = _integrate_rk12(x0, y0, dmap, forward_time, maxlength, + broken_streamlines) + stotal += s + xy_traj += xyt[1:] + + if stotal > minlength: + return np.broadcast_arrays(xy_traj, np.empty((1, 2)))[0] + else: # reject short trajectories + dmap.undo_trajectory() + return None + + return integrate + + +class OutOfBounds(IndexError): + pass + + +def _integrate_rk12(x0, y0, dmap, f, maxlength, broken_streamlines=True): + """ + 2nd-order Runge-Kutta algorithm with adaptive step size. + + This method is also referred to as the improved Euler's method, or Heun's + method. This method is favored over higher-order methods because: + + 1. To get decent looking trajectories and to sample every mask cell + on the trajectory we need a small timestep, so a lower order + solver doesn't hurt us unless the data is *very* high resolution. + In fact, for cases where the user inputs + data smaller or of similar grid size to the mask grid, the higher + order corrections are negligible because of the very fast linear + interpolation used in `interpgrid`. + + 2. For high resolution input data (i.e. beyond the mask + resolution), we must reduce the timestep. Therefore, an adaptive + timestep is more suited to the problem as this would be very hard + to judge automatically otherwise. + + This integrator is about 1.5 - 2x as fast as RK4 and RK45 solvers (using + similar Python implementations) in most setups. + """ + # This error is below that needed to match the RK4 integrator. It + # is set for visual reasons -- too low and corners start + # appearing ugly and jagged. Can be tuned. + maxerror = 0.003 + + # This limit is important (for all integrators) to avoid the + # trajectory skipping some mask cells. We could relax this + # condition if we use the code which is commented out below to + # increment the location gradually. However, due to the efficient + # nature of the interpolation, this doesn't boost speed by much + # for quite a bit of complexity. + maxds = min(1. / dmap.mask.nx, 1. / dmap.mask.ny, 0.1) + + ds = maxds + stotal = 0 + xi = x0 + yi = y0 + xyf_traj = [] + + while True: + try: + if dmap.grid.within_grid(xi, yi): + xyf_traj.append((xi, yi)) + else: + raise OutOfBounds + + # Compute the two intermediate gradients. + # f should raise OutOfBounds if the locations given are + # outside the grid. + k1x, k1y = f(xi, yi) + k2x, k2y = f(xi + ds * k1x, yi + ds * k1y) + + except OutOfBounds: + # Out of the domain during this step. + # Take an Euler step to the boundary to improve neatness + # unless the trajectory is currently empty. + if xyf_traj: + ds, xyf_traj = _euler_step(xyf_traj, dmap, f) + stotal += ds + break + except TerminateTrajectory: + break + + dx1 = ds * k1x + dy1 = ds * k1y + dx2 = ds * 0.5 * (k1x + k2x) + dy2 = ds * 0.5 * (k1y + k2y) + + ny, nx = dmap.grid.shape + # Error is normalized to the axes coordinates + error = np.hypot((dx2 - dx1) / (nx - 1), (dy2 - dy1) / (ny - 1)) + + # Only save step if within error tolerance + if error < maxerror: + xi += dx2 + yi += dy2 + try: + dmap.update_trajectory(xi, yi, broken_streamlines) + except InvalidIndexError: + break + if stotal + ds > maxlength: + break + stotal += ds + + # recalculate stepsize based on step error + if error == 0: + ds = maxds + else: + ds = min(maxds, 0.85 * ds * (maxerror / error) ** 0.5) + + return stotal, xyf_traj + + +def _euler_step(xyf_traj, dmap, f): + """Simple Euler integration step that extends streamline to boundary.""" + ny, nx = dmap.grid.shape + xi, yi = xyf_traj[-1] + cx, cy = f(xi, yi) + if cx == 0: + dsx = np.inf + elif cx < 0: + dsx = xi / -cx + else: + dsx = (nx - 1 - xi) / cx + if cy == 0: + dsy = np.inf + elif cy < 0: + dsy = yi / -cy + else: + dsy = (ny - 1 - yi) / cy + ds = min(dsx, dsy) + xyf_traj.append((xi + cx * ds, yi + cy * ds)) + return ds, xyf_traj + + +# Utility functions +# ======================== + +def interpgrid(a, xi, yi): + """Fast 2D, linear interpolation on an integer grid""" + + Ny, Nx = np.shape(a) + if isinstance(xi, np.ndarray): + x = xi.astype(int) + y = yi.astype(int) + # Check that xn, yn don't exceed max index + xn = np.clip(x + 1, 0, Nx - 1) + yn = np.clip(y + 1, 0, Ny - 1) + else: + x = int(xi) + y = int(yi) + # conditional is faster than clipping for integers + if x == (Nx - 1): + xn = x + else: + xn = x + 1 + if y == (Ny - 1): + yn = y + else: + yn = y + 1 + + a00 = a[y, x] + a01 = a[y, xn] + a10 = a[yn, x] + a11 = a[yn, xn] + xt = xi - x + yt = yi - y + a0 = a00 * (1 - xt) + a01 * xt + a1 = a10 * (1 - xt) + a11 * xt + ai = a0 * (1 - yt) + a1 * yt + + if not isinstance(xi, np.ndarray): + if np.ma.is_masked(ai): + raise TerminateTrajectory + + return ai + + +def _gen_starting_points(shape): + """ + Yield starting points for streamlines. + + Trying points on the boundary first gives higher quality streamlines. + This algorithm starts with a point on the mask corner and spirals inward. + This algorithm is inefficient, but fast compared to rest of streamplot. + """ + ny, nx = shape + xfirst = 0 + yfirst = 1 + xlast = nx - 1 + ylast = ny - 1 + x, y = 0, 0 + direction = 'right' + for i in range(nx * ny): + yield x, y + + if direction == 'right': + x += 1 + if x >= xlast: + xlast -= 1 + direction = 'up' + elif direction == 'up': + y += 1 + if y >= ylast: + ylast -= 1 + direction = 'left' + elif direction == 'left': + x -= 1 + if x <= xfirst: + xfirst += 1 + direction = 'down' + elif direction == 'down': + y -= 1 + if y <= yfirst: + yfirst += 1 + direction = 'right' diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.pyi new file mode 100644 index 00000000..9da83096 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/streamplot.pyi @@ -0,0 +1,82 @@ +from matplotlib.axes import Axes +from matplotlib.colors import Normalize, Colormap +from matplotlib.collections import LineCollection, PatchCollection +from matplotlib.patches import ArrowStyle +from matplotlib.transforms import Transform + +from typing import Literal +from numpy.typing import ArrayLike +from .typing import ColorType + +def streamplot( + axes: Axes, + x: ArrayLike, + y: ArrayLike, + u: ArrayLike, + v: ArrayLike, + density: float | tuple[float, float] = ..., + linewidth: float | ArrayLike | None = ..., + color: ColorType | ArrayLike | None = ..., + cmap: str | Colormap | None = ..., + norm: str | Normalize | None = ..., + arrowsize: float = ..., + arrowstyle: str | ArrowStyle = ..., + minlength: float = ..., + transform: Transform | None = ..., + zorder: float | None = ..., + start_points: ArrayLike | None = ..., + maxlength: float = ..., + integration_direction: Literal["forward", "backward", "both"] = ..., + broken_streamlines: bool = ..., +) -> StreamplotSet: ... + +class StreamplotSet: + lines: LineCollection + arrows: PatchCollection + def __init__(self, lines: LineCollection, arrows: PatchCollection) -> None: ... + +class DomainMap: + grid: Grid + mask: StreamMask + x_grid2mask: float + y_grid2mask: float + x_mask2grid: float + y_mask2grid: float + x_data2grid: float + y_data2grid: float + def __init__(self, grid: Grid, mask: StreamMask) -> None: ... + def grid2mask(self, xi: float, yi: float) -> tuple[int, int]: ... + def mask2grid(self, xm: float, ym: float) -> tuple[float, float]: ... + def data2grid(self, xd: float, yd: float) -> tuple[float, float]: ... + def grid2data(self, xg: float, yg: float) -> tuple[float, float]: ... + def start_trajectory( + self, xg: float, yg: float, broken_streamlines: bool = ... + ) -> None: ... + def reset_start_point(self, xg: float, yg: float) -> None: ... + def update_trajectory(self, xg, yg, broken_streamlines: bool = ...) -> None: ... + def undo_trajectory(self) -> None: ... + +class Grid: + nx: int + ny: int + dx: float + dy: float + x_origin: float + y_origin: float + width: float + height: float + def __init__(self, x: ArrayLike, y: ArrayLike) -> None: ... + @property + def shape(self) -> tuple[int, int]: ... + def within_grid(self, xi: float, yi: float) -> bool: ... + +class StreamMask: + nx: int + ny: int + shape: tuple[int, int] + def __init__(self, density: float | tuple[float, float]) -> None: ... + def __getitem__(self, args): ... + +class InvalidIndexError(Exception): ... +class TerminateTrajectory(Exception): ... +class OutOfBounds(IndexError): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/__init__.py new file mode 100644 index 00000000..488c6d6a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/__init__.py @@ -0,0 +1,4 @@ +from .core import available, context, library, reload_library, use + + +__all__ = ["available", "context", "library", "reload_library", "use"] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.py new file mode 100644 index 00000000..7e9008c5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.py @@ -0,0 +1,245 @@ +""" +Core functions and attributes for the matplotlib style library: + +``use`` + Select style sheet to override the current matplotlib settings. +``context`` + Context manager to use a style sheet temporarily. +``available`` + List available style sheets. +``library`` + A dictionary of style names and matplotlib settings. +""" + +import contextlib +import logging +import os +from pathlib import Path +import sys +import warnings + +if sys.version_info >= (3, 10): + import importlib.resources as importlib_resources +else: + # Even though Py3.9 has importlib.resources, it doesn't properly handle + # modules added in sys.path. + import importlib_resources + +import matplotlib as mpl +from matplotlib import _api, _docstring, _rc_params_in_file, rcParamsDefault + +_log = logging.getLogger(__name__) + +__all__ = ['use', 'context', 'available', 'library', 'reload_library'] + + +BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib') +# Users may want multiple library paths, so store a list of paths. +USER_LIBRARY_PATHS = [os.path.join(mpl.get_configdir(), 'stylelib')] +STYLE_EXTENSION = 'mplstyle' +# A list of rcParams that should not be applied from styles +STYLE_BLACKLIST = { + 'interactive', 'backend', 'webagg.port', 'webagg.address', + 'webagg.port_retries', 'webagg.open_in_browser', 'backend_fallback', + 'toolbar', 'timezone', 'figure.max_open_warning', + 'figure.raise_window', 'savefig.directory', 'tk.window_focus', + 'docstring.hardcopy', 'date.epoch'} + + +@_docstring.Substitution( + "\n".join(map("- {}".format, sorted(STYLE_BLACKLIST, key=str.lower))) +) +def use(style): + """ + Use Matplotlib style settings from a style specification. + + The style name of 'default' is reserved for reverting back to + the default style settings. + + .. note:: + + This updates the `.rcParams` with the settings from the style. + `.rcParams` not defined in the style are kept. + + Parameters + ---------- + style : str, dict, Path or list + + A style specification. Valid options are: + + str + - One of the style names in `.style.available` (a builtin style or + a style installed in the user library path). + + - A dotted name of the form "package.style_name"; in that case, + "package" should be an importable Python package name, e.g. at + ``/path/to/package/__init__.py``; the loaded style file is + ``/path/to/package/style_name.mplstyle``. (Style files in + subpackages are likewise supported.) + + - The path or URL to a style file, which gets loaded by + `.rc_params_from_file`. + + dict + A mapping of key/value pairs for `matplotlib.rcParams`. + + Path + The path to a style file, which gets loaded by + `.rc_params_from_file`. + + list + A list of style specifiers (str, Path or dict), which are applied + from first to last in the list. + + Notes + ----- + The following `.rcParams` are not related to style and will be ignored if + found in a style specification: + + %s + """ + if isinstance(style, (str, Path)) or hasattr(style, 'keys'): + # If name is a single str, Path or dict, make it a single element list. + styles = [style] + else: + styles = style + + style_alias = {'mpl20': 'default', 'mpl15': 'classic'} + + for style in styles: + if isinstance(style, str): + style = style_alias.get(style, style) + if style == "default": + # Deprecation warnings were already handled when creating + # rcParamsDefault, no need to reemit them here. + with _api.suppress_matplotlib_deprecation_warning(): + # don't trigger RcParams.__getitem__('backend') + style = {k: rcParamsDefault[k] for k in rcParamsDefault + if k not in STYLE_BLACKLIST} + elif style in library: + style = library[style] + elif "." in style: + pkg, _, name = style.rpartition(".") + try: + path = (importlib_resources.files(pkg) + / f"{name}.{STYLE_EXTENSION}") + style = _rc_params_in_file(path) + except (ModuleNotFoundError, OSError, TypeError) as exc: + # There is an ambiguity whether a dotted name refers to a + # package.style_name or to a dotted file path. Currently, + # we silently try the first form and then the second one; + # in the future, we may consider forcing file paths to + # either use Path objects or be prepended with "./" and use + # the slash as marker for file paths. + pass + if isinstance(style, (str, Path)): + try: + style = _rc_params_in_file(style) + except OSError as err: + raise OSError( + f"{style!r} is not a valid package style, path of style " + f"file, URL of style file, or library style name (library " + f"styles are listed in `style.available`)") from err + filtered = {} + for k in style: # don't trigger RcParams.__getitem__('backend') + if k in STYLE_BLACKLIST: + _api.warn_external( + f"Style includes a parameter, {k!r}, that is not " + f"related to style. Ignoring this parameter.") + else: + filtered[k] = style[k] + mpl.rcParams.update(filtered) + + +@contextlib.contextmanager +def context(style, after_reset=False): + """ + Context manager for using style settings temporarily. + + Parameters + ---------- + style : str, dict, Path or list + A style specification. Valid options are: + + str + - One of the style names in `.style.available` (a builtin style or + a style installed in the user library path). + + - A dotted name of the form "package.style_name"; in that case, + "package" should be an importable Python package name, e.g. at + ``/path/to/package/__init__.py``; the loaded style file is + ``/path/to/package/style_name.mplstyle``. (Style files in + subpackages are likewise supported.) + + - The path or URL to a style file, which gets loaded by + `.rc_params_from_file`. + dict + A mapping of key/value pairs for `matplotlib.rcParams`. + + Path + The path to a style file, which gets loaded by + `.rc_params_from_file`. + + list + A list of style specifiers (str, Path or dict), which are applied + from first to last in the list. + + after_reset : bool + If True, apply style after resetting settings to their defaults; + otherwise, apply style on top of the current settings. + """ + with mpl.rc_context(): + if after_reset: + mpl.rcdefaults() + use(style) + yield + + +def update_user_library(library): + """Update style library with user-defined rc files.""" + for stylelib_path in map(os.path.expanduser, USER_LIBRARY_PATHS): + styles = read_style_directory(stylelib_path) + update_nested_dict(library, styles) + return library + + +def read_style_directory(style_dir): + """Return dictionary of styles defined in *style_dir*.""" + styles = dict() + for path in Path(style_dir).glob(f"*.{STYLE_EXTENSION}"): + with warnings.catch_warnings(record=True) as warns: + styles[path.stem] = _rc_params_in_file(path) + for w in warns: + _log.warning('In %s: %s', path, w.message) + return styles + + +def update_nested_dict(main_dict, new_dict): + """ + Update nested dict (only level of nesting) with new values. + + Unlike `dict.update`, this assumes that the values of the parent dict are + dicts (or dict-like), so you shouldn't replace the nested dict if it + already exists. Instead you should update the sub-dict. + """ + # update named styles specified by user + for name, rc_dict in new_dict.items(): + main_dict.setdefault(name, {}).update(rc_dict) + return main_dict + + +# Load style library +# ================== +_base_library = read_style_directory(BASE_LIBRARY_PATH) +library = {} +available = [] + + +def reload_library(): + """Reload the style library.""" + library.clear() + library.update(update_user_library(_base_library)) + available[:] = sorted(library.keys()) + + +reload_library() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.pyi new file mode 100644 index 00000000..73400492 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/style/core.pyi @@ -0,0 +1,19 @@ +from collections.abc import Generator +import contextlib + +from matplotlib import RcParams +from matplotlib.typing import RcStyleType + +USER_LIBRARY_PATHS: list[str] = ... +STYLE_EXTENSION: str = ... + +def use(style: RcStyleType) -> None: ... +@contextlib.contextmanager +def context( + style: RcStyleType, after_reset: bool = ... +) -> Generator[None, None, None]: ... + +library: dict[str, RcParams] +available: list[str] + +def reload_library() -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.py new file mode 100644 index 00000000..d42cdf87 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.py @@ -0,0 +1,831 @@ +# Original code by: +# John Gill <jng@europe.renre.com> +# Copyright 2004 John Gill and John Hunter +# +# Subsequent changes: +# The Matplotlib development team +# Copyright The Matplotlib development team + +""" +Tables drawing. + +.. note:: + The table implementation in Matplotlib is lightly maintained. For a more + featureful table implementation, you may wish to try `blume + <https://github.com/swfiua/blume>`_. + +Use the factory function `~matplotlib.table.table` to create a ready-made +table from texts. If you need more control, use the `.Table` class and its +methods. + +The table consists of a grid of cells, which are indexed by (row, column). +The cell (0, 0) is positioned at the top left. + +Thanks to John Gill for providing the class and table. +""" + +import numpy as np + +from . import _api, _docstring +from .artist import Artist, allow_rasterization +from .patches import Rectangle +from .text import Text +from .transforms import Bbox +from .path import Path + + +class Cell(Rectangle): + """ + A cell is a `.Rectangle` with some associated `.Text`. + + As a user, you'll most likely not creates cells yourself. Instead, you + should use either the `~matplotlib.table.table` factory function or + `.Table.add_cell`. + """ + + PAD = 0.1 + """Padding between text and rectangle.""" + + _edges = 'BRTL' + _edge_aliases = {'open': '', + 'closed': _edges, # default + 'horizontal': 'BT', + 'vertical': 'RL' + } + + def __init__(self, xy, width, height, *, + edgecolor='k', facecolor='w', + fill=True, + text='', + loc=None, + fontproperties=None, + visible_edges='closed', + ): + """ + Parameters + ---------- + xy : 2-tuple + The position of the bottom left corner of the cell. + width : float + The cell width. + height : float + The cell height. + edgecolor : color + The color of the cell border. + facecolor : color + The cell facecolor. + fill : bool + Whether the cell background is filled. + text : str + The cell text. + loc : {'left', 'center', 'right'}, default: 'right' + The alignment of the text within the cell. + fontproperties : dict + A dict defining the font properties of the text. Supported keys and + values are the keyword arguments accepted by `.FontProperties`. + visible_edges : str, default: 'closed' + The cell edges to be drawn with a line: a substring of 'BRTL' + (bottom, right, top, left), or one of 'open' (no edges drawn), + 'closed' (all edges drawn), 'horizontal' (bottom and top), + 'vertical' (right and left). + """ + + # Call base + super().__init__(xy, width=width, height=height, fill=fill, + edgecolor=edgecolor, facecolor=facecolor) + self.set_clip_on(False) + self.visible_edges = visible_edges + + # Create text object + if loc is None: + loc = 'right' + self._loc = loc + self._text = Text(x=xy[0], y=xy[1], clip_on=False, + text=text, fontproperties=fontproperties, + horizontalalignment=loc, verticalalignment='center') + + @_api.rename_parameter("3.8", "trans", "t") + def set_transform(self, t): + super().set_transform(t) + # the text does not get the transform! + self.stale = True + + def set_figure(self, fig): + super().set_figure(fig) + self._text.set_figure(fig) + + def get_text(self): + """Return the cell `.Text` instance.""" + return self._text + + def set_fontsize(self, size): + """Set the text fontsize.""" + self._text.set_fontsize(size) + self.stale = True + + def get_fontsize(self): + """Return the cell fontsize.""" + return self._text.get_fontsize() + + def auto_set_font_size(self, renderer): + """Shrink font size until the text fits into the cell width.""" + fontsize = self.get_fontsize() + required = self.get_required_width(renderer) + while fontsize > 1 and required > self.get_width(): + fontsize -= 1 + self.set_fontsize(fontsize) + required = self.get_required_width(renderer) + + return fontsize + + @allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + # draw the rectangle + super().draw(renderer) + # position the text + self._set_text_position(renderer) + self._text.draw(renderer) + self.stale = False + + def _set_text_position(self, renderer): + """Set text up so it is drawn in the right place.""" + bbox = self.get_window_extent(renderer) + # center vertically + y = bbox.y0 + bbox.height / 2 + # position horizontally + loc = self._text.get_horizontalalignment() + if loc == 'center': + x = bbox.x0 + bbox.width / 2 + elif loc == 'left': + x = bbox.x0 + bbox.width * self.PAD + else: # right. + x = bbox.x0 + bbox.width * (1 - self.PAD) + self._text.set_position((x, y)) + + def get_text_bounds(self, renderer): + """ + Return the text bounds as *(x, y, width, height)* in table coordinates. + """ + return (self._text.get_window_extent(renderer) + .transformed(self.get_data_transform().inverted()) + .bounds) + + def get_required_width(self, renderer): + """Return the minimal required width for the cell.""" + l, b, w, h = self.get_text_bounds(renderer) + return w * (1.0 + (2.0 * self.PAD)) + + @_docstring.dedent_interpd + def set_text_props(self, **kwargs): + """ + Update the text properties. + + Valid keyword arguments are: + + %(Text:kwdoc)s + """ + self._text._internal_update(kwargs) + self.stale = True + + @property + def visible_edges(self): + """ + The cell edges to be drawn with a line. + + Reading this property returns a substring of 'BRTL' (bottom, right, + top, left'). + + When setting this property, you can use a substring of 'BRTL' or one + of {'open', 'closed', 'horizontal', 'vertical'}. + """ + return self._visible_edges + + @visible_edges.setter + def visible_edges(self, value): + if value is None: + self._visible_edges = self._edges + elif value in self._edge_aliases: + self._visible_edges = self._edge_aliases[value] + else: + if any(edge not in self._edges for edge in value): + raise ValueError('Invalid edge param {}, must only be one of ' + '{} or string of {}'.format( + value, + ", ".join(self._edge_aliases), + ", ".join(self._edges))) + self._visible_edges = value + self.stale = True + + def get_path(self): + """Return a `.Path` for the `.visible_edges`.""" + codes = [Path.MOVETO] + codes.extend( + Path.LINETO if edge in self._visible_edges else Path.MOVETO + for edge in self._edges) + if Path.MOVETO not in codes[1:]: # All sides are visible + codes[-1] = Path.CLOSEPOLY + return Path( + [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]], + codes, + readonly=True + ) + + +CustomCell = Cell # Backcompat. alias. + + +class Table(Artist): + """ + A table of cells. + + The table consists of a grid of cells, which are indexed by (row, column). + + For a simple table, you'll have a full grid of cells with indices from + (0, 0) to (num_rows-1, num_cols-1), in which the cell (0, 0) is positioned + at the top left. However, you can also add cells with negative indices. + You don't have to add a cell to every grid position, so you can create + tables that have holes. + + *Note*: You'll usually not create an empty table from scratch. Instead use + `~matplotlib.table.table` to create a table from data. + """ + codes = {'best': 0, + 'upper right': 1, # default + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'center left': 5, + 'center right': 6, + 'lower center': 7, + 'upper center': 8, + 'center': 9, + 'top right': 10, + 'top left': 11, + 'bottom left': 12, + 'bottom right': 13, + 'right': 14, + 'left': 15, + 'top': 16, + 'bottom': 17, + } + """Possible values where to place the table relative to the Axes.""" + + FONTSIZE = 10 + + AXESPAD = 0.02 + """The border between the Axes and the table edge in Axes units.""" + + def __init__(self, ax, loc=None, bbox=None, **kwargs): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` to plot the table into. + loc : str + The position of the cell with respect to *ax*. This must be one of + the `~.Table.codes`. + bbox : `.Bbox` or [xmin, ymin, width, height], optional + A bounding box to draw the table into. If this is not *None*, this + overrides *loc*. + + Other Parameters + ---------------- + **kwargs + `.Artist` properties. + """ + + super().__init__() + + if isinstance(loc, str): + if loc not in self.codes: + raise ValueError( + "Unrecognized location {!r}. Valid locations are\n\t{}" + .format(loc, '\n\t'.join(self.codes))) + loc = self.codes[loc] + self.set_figure(ax.figure) + self._axes = ax + self._loc = loc + self._bbox = bbox + + # use axes coords + ax._unstale_viewLim() + self.set_transform(ax.transAxes) + + self._cells = {} + self._edges = None + self._autoColumns = [] + self._autoFontsize = True + self._internal_update(kwargs) + + self.set_clip_on(False) + + def add_cell(self, row, col, *args, **kwargs): + """ + Create a cell and add it to the table. + + Parameters + ---------- + row : int + Row index. + col : int + Column index. + *args, **kwargs + All other parameters are passed on to `Cell`. + + Returns + ------- + `.Cell` + The created cell. + + """ + xy = (0, 0) + cell = Cell(xy, visible_edges=self.edges, *args, **kwargs) + self[row, col] = cell + return cell + + def __setitem__(self, position, cell): + """ + Set a custom cell in a given position. + """ + _api.check_isinstance(Cell, cell=cell) + try: + row, col = position[0], position[1] + except Exception as err: + raise KeyError('Only tuples length 2 are accepted as ' + 'coordinates') from err + cell.set_figure(self.figure) + cell.set_transform(self.get_transform()) + cell.set_clip_on(False) + self._cells[row, col] = cell + self.stale = True + + def __getitem__(self, position): + """Retrieve a custom cell from a given position.""" + return self._cells[position] + + @property + def edges(self): + """ + The default value of `~.Cell.visible_edges` for newly added + cells using `.add_cell`. + + Notes + ----- + This setting does currently only affect newly created cells using + `.add_cell`. + + To change existing cells, you have to set their edges explicitly:: + + for c in tab.get_celld().values(): + c.visible_edges = 'horizontal' + + """ + return self._edges + + @edges.setter + def edges(self, value): + self._edges = value + self.stale = True + + def _approx_text_height(self): + return (self.FONTSIZE / 72.0 * self.figure.dpi / + self._axes.bbox.height * 1.2) + + @allow_rasterization + def draw(self, renderer): + # docstring inherited + + # Need a renderer to do hit tests on mouseevent; assume the last one + # will do + if renderer is None: + renderer = self.figure._get_renderer() + if renderer is None: + raise RuntimeError('No renderer defined') + + if not self.get_visible(): + return + renderer.open_group('table', gid=self.get_gid()) + self._update_positions(renderer) + + for key in sorted(self._cells): + self._cells[key].draw(renderer) + + renderer.close_group('table') + self.stale = False + + def _get_grid_bbox(self, renderer): + """ + Get a bbox, in axes coordinates for the cells. + + Only include those in the range (0, 0) to (maxRow, maxCol). + """ + boxes = [cell.get_window_extent(renderer) + for (row, col), cell in self._cells.items() + if row >= 0 and col >= 0] + bbox = Bbox.union(boxes) + return bbox.transformed(self.get_transform().inverted()) + + def contains(self, mouseevent): + # docstring inherited + if self._different_canvas(mouseevent): + return False, {} + # TODO: Return index of the cell containing the cursor so that the user + # doesn't have to bind to each one individually. + renderer = self.figure._get_renderer() + if renderer is not None: + boxes = [cell.get_window_extent(renderer) + for (row, col), cell in self._cells.items() + if row >= 0 and col >= 0] + bbox = Bbox.union(boxes) + return bbox.contains(mouseevent.x, mouseevent.y), {} + else: + return False, {} + + def get_children(self): + """Return the Artists contained by the table.""" + return list(self._cells.values()) + + def get_window_extent(self, renderer=None): + # docstring inherited + if renderer is None: + renderer = self.figure._get_renderer() + self._update_positions(renderer) + boxes = [cell.get_window_extent(renderer) + for cell in self._cells.values()] + return Bbox.union(boxes) + + def _do_cell_alignment(self): + """ + Calculate row heights and column widths; position cells accordingly. + """ + # Calculate row/column widths + widths = {} + heights = {} + for (row, col), cell in self._cells.items(): + height = heights.setdefault(row, 0.0) + heights[row] = max(height, cell.get_height()) + width = widths.setdefault(col, 0.0) + widths[col] = max(width, cell.get_width()) + + # work out left position for each column + xpos = 0 + lefts = {} + for col in sorted(widths): + lefts[col] = xpos + xpos += widths[col] + + ypos = 0 + bottoms = {} + for row in sorted(heights, reverse=True): + bottoms[row] = ypos + ypos += heights[row] + + # set cell positions + for (row, col), cell in self._cells.items(): + cell.set_x(lefts[col]) + cell.set_y(bottoms[row]) + + def auto_set_column_width(self, col): + """ + Automatically set the widths of given columns to optimal sizes. + + Parameters + ---------- + col : int or sequence of ints + The indices of the columns to auto-scale. + """ + col1d = np.atleast_1d(col) + if not np.issubdtype(col1d.dtype, np.integer): + _api.warn_deprecated("3.8", name="col", + message="%(name)r must be an int or sequence of ints. " + "Passing other types is deprecated since %(since)s " + "and will be removed %(removal)s.") + return + for cell in col1d: + self._autoColumns.append(cell) + + self.stale = True + + def _auto_set_column_width(self, col, renderer): + """Automatically set width for column.""" + cells = [cell for key, cell in self._cells.items() if key[1] == col] + max_width = max((cell.get_required_width(renderer) for cell in cells), + default=0) + for cell in cells: + cell.set_width(max_width) + + def auto_set_font_size(self, value=True): + """Automatically set font size.""" + self._autoFontsize = value + self.stale = True + + def _auto_set_font_size(self, renderer): + + if len(self._cells) == 0: + return + fontsize = next(iter(self._cells.values())).get_fontsize() + cells = [] + for key, cell in self._cells.items(): + # ignore auto-sized columns + if key[1] in self._autoColumns: + continue + size = cell.auto_set_font_size(renderer) + fontsize = min(fontsize, size) + cells.append(cell) + + # now set all fontsizes equal + for cell in self._cells.values(): + cell.set_fontsize(fontsize) + + def scale(self, xscale, yscale): + """Scale column widths by *xscale* and row heights by *yscale*.""" + for c in self._cells.values(): + c.set_width(c.get_width() * xscale) + c.set_height(c.get_height() * yscale) + + def set_fontsize(self, size): + """ + Set the font size, in points, of the cell text. + + Parameters + ---------- + size : float + + Notes + ----- + As long as auto font size has not been disabled, the value will be + clipped such that the text fits horizontally into the cell. + + You can disable this behavior using `.auto_set_font_size`. + + >>> the_table.auto_set_font_size(False) + >>> the_table.set_fontsize(20) + + However, there is no automatic scaling of the row height so that the + text may exceed the cell boundary. + """ + for cell in self._cells.values(): + cell.set_fontsize(size) + self.stale = True + + def _offset(self, ox, oy): + """Move all the artists by ox, oy (axes coords).""" + for c in self._cells.values(): + x, y = c.get_x(), c.get_y() + c.set_x(x + ox) + c.set_y(y + oy) + + def _update_positions(self, renderer): + # called from renderer to allow more precise estimates of + # widths and heights with get_window_extent + + # Do any auto width setting + for col in self._autoColumns: + self._auto_set_column_width(col, renderer) + + if self._autoFontsize: + self._auto_set_font_size(renderer) + + # Align all the cells + self._do_cell_alignment() + + bbox = self._get_grid_bbox(renderer) + l, b, w, h = bbox.bounds + + if self._bbox is not None: + # Position according to bbox + if isinstance(self._bbox, Bbox): + rl, rb, rw, rh = self._bbox.bounds + else: + rl, rb, rw, rh = self._bbox + self.scale(rw / w, rh / h) + ox = rl - l + oy = rb - b + self._do_cell_alignment() + else: + # Position using loc + (BEST, UR, UL, LL, LR, CL, CR, LC, UC, C, + TR, TL, BL, BR, R, L, T, B) = range(len(self.codes)) + # defaults for center + ox = (0.5 - w / 2) - l + oy = (0.5 - h / 2) - b + if self._loc in (UL, LL, CL): # left + ox = self.AXESPAD - l + if self._loc in (BEST, UR, LR, R, CR): # right + ox = 1 - (l + w + self.AXESPAD) + if self._loc in (BEST, UR, UL, UC): # upper + oy = 1 - (b + h + self.AXESPAD) + if self._loc in (LL, LR, LC): # lower + oy = self.AXESPAD - b + if self._loc in (LC, UC, C): # center x + ox = (0.5 - w / 2) - l + if self._loc in (CL, CR, C): # center y + oy = (0.5 - h / 2) - b + + if self._loc in (TL, BL, L): # out left + ox = - (l + w) + if self._loc in (TR, BR, R): # out right + ox = 1.0 - l + if self._loc in (TR, TL, T): # out top + oy = 1.0 - b + if self._loc in (BL, BR, B): # out bottom + oy = - (b + h) + + self._offset(ox, oy) + + def get_celld(self): + r""" + Return a dict of cells in the table mapping *(row, column)* to + `.Cell`\s. + + Notes + ----- + You can also directly index into the Table object to access individual + cells:: + + cell = table[row, col] + + """ + return self._cells + + +@_docstring.dedent_interpd +def table(ax, + cellText=None, cellColours=None, + cellLoc='right', colWidths=None, + rowLabels=None, rowColours=None, rowLoc='left', + colLabels=None, colColours=None, colLoc='center', + loc='bottom', bbox=None, edges='closed', + **kwargs): + """ + Add a table to an `~.axes.Axes`. + + At least one of *cellText* or *cellColours* must be specified. These + parameters must be 2D lists, in which the outer lists define the rows and + the inner list define the column values per row. Each row must have the + same number of elements. + + The table can optionally have row and column headers, which are configured + using *rowLabels*, *rowColours*, *rowLoc* and *colLabels*, *colColours*, + *colLoc* respectively. + + For finer grained control over tables, use the `.Table` class and add it to + the axes with `.Axes.add_table`. + + Parameters + ---------- + cellText : 2D list of str, optional + The texts to place into the table cells. + + *Note*: Line breaks in the strings are currently not accounted for and + will result in the text exceeding the cell boundaries. + + cellColours : 2D list of colors, optional + The background colors of the cells. + + cellLoc : {'left', 'center', 'right'}, default: 'right' + The alignment of the text within the cells. + + colWidths : list of float, optional + The column widths in units of the axes. If not given, all columns will + have a width of *1 / ncols*. + + rowLabels : list of str, optional + The text of the row header cells. + + rowColours : list of colors, optional + The colors of the row header cells. + + rowLoc : {'left', 'center', 'right'}, default: 'left' + The text alignment of the row header cells. + + colLabels : list of str, optional + The text of the column header cells. + + colColours : list of colors, optional + The colors of the column header cells. + + colLoc : {'left', 'center', 'right'}, default: 'left' + The text alignment of the column header cells. + + loc : str, optional + The position of the cell with respect to *ax*. This must be one of + the `~.Table.codes`. + + bbox : `.Bbox` or [xmin, ymin, width, height], optional + A bounding box to draw the table into. If this is not *None*, this + overrides *loc*. + + edges : substring of 'BRTL' or {'open', 'closed', 'horizontal', 'vertical'} + The cell edges to be drawn with a line. See also + `~.Cell.visible_edges`. + + Returns + ------- + `~matplotlib.table.Table` + The created table. + + Other Parameters + ---------------- + **kwargs + `.Table` properties. + + %(Table:kwdoc)s + """ + + if cellColours is None and cellText is None: + raise ValueError('At least one argument from "cellColours" or ' + '"cellText" must be provided to create a table.') + + # Check we have some cellText + if cellText is None: + # assume just colours are needed + rows = len(cellColours) + cols = len(cellColours[0]) + cellText = [[''] * cols] * rows + + rows = len(cellText) + cols = len(cellText[0]) + for row in cellText: + if len(row) != cols: + raise ValueError(f"Each row in 'cellText' must have {cols} " + "columns") + + if cellColours is not None: + if len(cellColours) != rows: + raise ValueError(f"'cellColours' must have {rows} rows") + for row in cellColours: + if len(row) != cols: + raise ValueError("Each row in 'cellColours' must have " + f"{cols} columns") + else: + cellColours = ['w' * cols] * rows + + # Set colwidths if not given + if colWidths is None: + colWidths = [1.0 / cols] * cols + + # Fill in missing information for column + # and row labels + rowLabelWidth = 0 + if rowLabels is None: + if rowColours is not None: + rowLabels = [''] * rows + rowLabelWidth = colWidths[0] + elif rowColours is None: + rowColours = 'w' * rows + + if rowLabels is not None: + if len(rowLabels) != rows: + raise ValueError(f"'rowLabels' must be of length {rows}") + + # If we have column labels, need to shift + # the text and colour arrays down 1 row + offset = 1 + if colLabels is None: + if colColours is not None: + colLabels = [''] * cols + else: + offset = 0 + elif colColours is None: + colColours = 'w' * cols + + # Set up cell colours if not given + if cellColours is None: + cellColours = ['w' * cols] * rows + + # Now create the table + table = Table(ax, loc, bbox, **kwargs) + table.edges = edges + height = table._approx_text_height() + + # Add the cells + for row in range(rows): + for col in range(cols): + table.add_cell(row + offset, col, + width=colWidths[col], height=height, + text=cellText[row][col], + facecolor=cellColours[row][col], + loc=cellLoc) + # Do column labels + if colLabels is not None: + for col in range(cols): + table.add_cell(0, col, + width=colWidths[col], height=height, + text=colLabels[col], facecolor=colColours[col], + loc=colLoc) + + # Do row labels + if rowLabels is not None: + for row in range(rows): + table.add_cell(row + offset, -1, + width=rowLabelWidth or 1e-15, height=height, + text=rowLabels[row], facecolor=rowColours[row], + loc=rowLoc) + if rowLabelWidth == 0: + table.auto_set_column_width(-1) + + ax.add_table(table) + return table diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.pyi new file mode 100644 index 00000000..842c55ed --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/table.pyi @@ -0,0 +1,85 @@ +from .artist import Artist +from .axes import Axes +from .backend_bases import RendererBase +from .patches import Rectangle +from .path import Path +from .text import Text +from .transforms import Bbox +from .typing import ColorType + +from collections.abc import Sequence +from typing import Any, Literal + +class Cell(Rectangle): + PAD: float + def __init__( + self, + xy: tuple[float, float], + width: float, + height: float, + *, + edgecolor: ColorType = ..., + facecolor: ColorType = ..., + fill: bool = ..., + text: str = ..., + loc: Literal["left", "center", "right"] | None = ..., + fontproperties: dict[str, Any] | None = ..., + visible_edges: str | None = ... + ) -> None: ... + def get_text(self) -> Text: ... + def set_fontsize(self, size: float) -> None: ... + def get_fontsize(self) -> float: ... + def auto_set_font_size(self, renderer: RendererBase) -> float: ... + def get_text_bounds( + self, renderer: RendererBase + ) -> tuple[float, float, float, float]: ... + def get_required_width(self, renderer: RendererBase) -> float: ... + def set_text_props(self, **kwargs) -> None: ... + @property + def visible_edges(self) -> str: ... + @visible_edges.setter + def visible_edges(self, value: str | None) -> None: ... + def get_path(self) -> Path: ... + +CustomCell = Cell + +class Table(Artist): + codes: dict[str, int] + FONTSIZE: float + AXESPAD: float + def __init__( + self, ax: Axes, loc: str | None = ..., bbox: Bbox | None = ..., **kwargs + ) -> None: ... + def add_cell(self, row: int, col: int, *args, **kwargs) -> Cell: ... + def __setitem__(self, position: tuple[int, int], cell: Cell) -> None: ... + def __getitem__(self, position: tuple[int, int]) -> Cell: ... + @property + def edges(self) -> str | None: ... + @edges.setter + def edges(self, value: str | None) -> None: ... + def draw(self, renderer) -> None: ... + def get_children(self) -> list[Artist]: ... + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... + def auto_set_column_width(self, col: int | Sequence[int]) -> None: ... + def auto_set_font_size(self, value: bool = ...) -> None: ... + def scale(self, xscale: float, yscale: float) -> None: ... + def set_fontsize(self, size: float) -> None: ... + def get_celld(self) -> dict[tuple[int, int], Cell]: ... + +def table( + ax: Axes, + cellText: Sequence[Sequence[str]] | None = ..., + cellColours: Sequence[Sequence[ColorType]] | None = ..., + cellLoc: Literal["left", "center", "right"] = ..., + colWidths: Sequence[float] | None = ..., + rowLabels: Sequence[str] | None = ..., + rowColours: Sequence[ColorType] | None = ..., + rowLoc: Literal["left", "center", "right"] = ..., + colLabels: Sequence[str] | None = ..., + colColours: Sequence[ColorType] | None = ..., + colLoc: Literal["left", "center", "right"] = ..., + loc: str = ..., + bbox: Bbox | None = ..., + edges: str = ..., + **kwargs +) -> Table: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.py new file mode 100644 index 00000000..da21eb42 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.py @@ -0,0 +1,174 @@ +""" +Helper functions for testing. +""" +from pathlib import Path +from tempfile import TemporaryDirectory +import locale +import logging +import os +import subprocess +import sys + +import matplotlib as mpl +from matplotlib import _api + +_log = logging.getLogger(__name__) + + +def set_font_settings_for_testing(): + mpl.rcParams['font.family'] = 'DejaVu Sans' + mpl.rcParams['text.hinting'] = 'none' + mpl.rcParams['text.hinting_factor'] = 8 + + +def set_reproducibility_for_testing(): + mpl.rcParams['svg.hashsalt'] = 'matplotlib' + + +def setup(): + # The baseline images are created in this locale, so we should use + # it during all of the tests. + + try: + locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') + except locale.Error: + try: + locale.setlocale(locale.LC_ALL, 'English_United States.1252') + except locale.Error: + _log.warning( + "Could not set locale to English/United States. " + "Some date-related tests may fail.") + + mpl.use('Agg') + + with _api.suppress_matplotlib_deprecation_warning(): + mpl.rcdefaults() # Start with all defaults + + # These settings *must* be hardcoded for running the comparison tests and + # are not necessarily the default values as specified in rcsetup.py. + set_font_settings_for_testing() + set_reproducibility_for_testing() + + +def subprocess_run_for_testing(command, env=None, timeout=None, stdout=None, + stderr=None, check=False, text=True, + capture_output=False): + """ + Create and run a subprocess. + + Thin wrapper around `subprocess.run`, intended for testing. Will + mark fork() failures on Cygwin as expected failures: not a + success, but not indicating a problem with the code either. + + Parameters + ---------- + args : list of str + env : dict[str, str] + timeout : float + stdout, stderr + check : bool + text : bool + Also called ``universal_newlines`` in subprocess. I chose this + name since the main effect is returning bytes (`False`) vs. str + (`True`), though it also tries to normalize newlines across + platforms. + capture_output : bool + Set stdout and stderr to subprocess.PIPE + + Returns + ------- + proc : subprocess.Popen + + See Also + -------- + subprocess.run + + Raises + ------ + pytest.xfail + If platform is Cygwin and subprocess reports a fork() failure. + """ + if capture_output: + stdout = stderr = subprocess.PIPE + try: + proc = subprocess.run( + command, env=env, + timeout=timeout, check=check, + stdout=stdout, stderr=stderr, + text=text + ) + except BlockingIOError: + if sys.platform == "cygwin": + # Might want to make this more specific + import pytest + pytest.xfail("Fork failure") + raise + return proc + + +def subprocess_run_helper(func, *args, timeout, extra_env=None): + """ + Run a function in a sub-process. + + Parameters + ---------- + func : function + The function to be run. It must be in a module that is importable. + *args : str + Any additional command line arguments to be passed in + the first argument to ``subprocess.run``. + extra_env : dict[str, str] + Any additional environment variables to be set for the subprocess. + """ + target = func.__name__ + module = func.__module__ + proc = subprocess_run_for_testing( + [ + sys.executable, + "-c", + f"from {module} import {target}; {target}()", + *args + ], + env={**os.environ, "SOURCE_DATE_EPOCH": "0", **(extra_env or {})}, + timeout=timeout, check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + return proc + + +def _check_for_pgf(texsystem): + """ + Check if a given TeX system + pgf is available + + Parameters + ---------- + texsystem : str + The executable name to check + """ + with TemporaryDirectory() as tmpdir: + tex_path = Path(tmpdir, "test.tex") + tex_path.write_text(r""" + \documentclass{article} + \usepackage{pgf} + \begin{document} + \typeout{pgfversion=\pgfversion} + \makeatletter + \@@end + """, encoding="utf-8") + try: + subprocess.check_call( + [texsystem, "-halt-on-error", str(tex_path)], cwd=tmpdir, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except (OSError, subprocess.CalledProcessError): + return False + return True + + +def _has_tex_package(package): + try: + mpl.dviread.find_tex_file(f"{package}.sty") + return True + except FileNotFoundError: + return False diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.pyi new file mode 100644 index 00000000..30cfd9a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/__init__.pyi @@ -0,0 +1,49 @@ +from collections.abc import Callable +import subprocess +from typing import Any, IO, Literal, overload + +def set_font_settings_for_testing() -> None: ... +def set_reproducibility_for_testing() -> None: ... +def setup() -> None: ... +@overload +def subprocess_run_for_testing( + command: list[str], + env: dict[str, str] | None = ..., + timeout: float | None = ..., + stdout: int | IO[Any] | None = ..., + stderr: int | IO[Any] | None = ..., + check: bool = ..., + *, + text: Literal[True], + capture_output: bool = ..., +) -> subprocess.CompletedProcess[str]: ... +@overload +def subprocess_run_for_testing( + command: list[str], + env: dict[str, str] | None = ..., + timeout: float | None = ..., + stdout: int | IO[Any] | None = ..., + stderr: int | IO[Any] | None = ..., + check: bool = ..., + text: Literal[False] = ..., + capture_output: bool = ..., +) -> subprocess.CompletedProcess[bytes]: ... +@overload +def subprocess_run_for_testing( + command: list[str], + env: dict[str, str] | None = ..., + timeout: float | None = ..., + stdout: int | IO[Any] | None = ..., + stderr: int | IO[Any] | None = ..., + check: bool = ..., + text: bool = ..., + capture_output: bool = ..., +) -> subprocess.CompletedProcess[bytes] | subprocess.CompletedProcess[str]: ... +def subprocess_run_helper( + func: Callable[[], None], + *args: Any, + timeout: float, + extra_env: dict[str, str] | None = ..., +) -> subprocess.CompletedProcess[str]: ... +def _check_for_pgf(texsystem: str) -> bool: ... +def _has_tex_package(package: str) -> bool: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/_markers.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/_markers.py new file mode 100644 index 00000000..c7ef8687 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/_markers.py @@ -0,0 +1,49 @@ +""" +pytest markers for the internal Matplotlib test suite. +""" + +import logging +import shutil + +import pytest + +import matplotlib.testing +import matplotlib.testing.compare +from matplotlib import _get_executable_info, ExecutableNotFoundError + + +_log = logging.getLogger(__name__) + + +def _checkdep_usetex() -> bool: + if not shutil.which("tex"): + _log.warning("usetex mode requires TeX.") + return False + try: + _get_executable_info("dvipng") + except ExecutableNotFoundError: + _log.warning("usetex mode requires dvipng.") + return False + try: + _get_executable_info("gs") + except ExecutableNotFoundError: + _log.warning("usetex mode requires ghostscript.") + return False + return True + + +needs_ghostscript = pytest.mark.skipif( + "eps" not in matplotlib.testing.compare.converter, + reason="This test needs a ghostscript installation") +needs_pgf_lualatex = pytest.mark.skipif( + not matplotlib.testing._check_for_pgf('lualatex'), + reason='lualatex + pgf is required') +needs_pgf_pdflatex = pytest.mark.skipif( + not matplotlib.testing._check_for_pgf('pdflatex'), + reason='pdflatex + pgf is required') +needs_pgf_xelatex = pytest.mark.skipif( + not matplotlib.testing._check_for_pgf('xelatex'), + reason='xelatex + pgf is required') +needs_usetex = pytest.mark.skipif( + not _checkdep_usetex(), + reason="This test needs a TeX installation") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.py new file mode 100644 index 00000000..655765b3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.py @@ -0,0 +1,515 @@ +""" +Utilities for comparing image results. +""" + +import atexit +import functools +import hashlib +import logging +import os +from pathlib import Path +import shutil +import subprocess +import sys +from tempfile import TemporaryDirectory, TemporaryFile +import weakref + +import numpy as np +from PIL import Image + +import matplotlib as mpl +from matplotlib import cbook +from matplotlib.testing.exceptions import ImageComparisonFailure + +_log = logging.getLogger(__name__) + +__all__ = ['calculate_rms', 'comparable_formats', 'compare_images'] + + +def make_test_filename(fname, purpose): + """ + Make a new filename by inserting *purpose* before the file's extension. + """ + base, ext = os.path.splitext(fname) + return f'{base}-{purpose}{ext}' + + +def _get_cache_path(): + cache_dir = Path(mpl.get_cachedir(), 'test_cache') + cache_dir.mkdir(parents=True, exist_ok=True) + return cache_dir + + +def get_cache_dir(): + return str(_get_cache_path()) + + +def get_file_hash(path, block_size=2 ** 20): + md5 = hashlib.md5() + with open(path, 'rb') as fd: + while True: + data = fd.read(block_size) + if not data: + break + md5.update(data) + + if Path(path).suffix == '.pdf': + md5.update(str(mpl._get_executable_info("gs").version) + .encode('utf-8')) + elif Path(path).suffix == '.svg': + md5.update(str(mpl._get_executable_info("inkscape").version) + .encode('utf-8')) + + return md5.hexdigest() + + +class _ConverterError(Exception): + pass + + +class _Converter: + def __init__(self): + self._proc = None + # Explicitly register deletion from an atexit handler because if we + # wait until the object is GC'd (which occurs later), then some module + # globals (e.g. signal.SIGKILL) has already been set to None, and + # kill() doesn't work anymore... + atexit.register(self.__del__) + + def __del__(self): + if self._proc: + self._proc.kill() + self._proc.wait() + for stream in filter(None, [self._proc.stdin, + self._proc.stdout, + self._proc.stderr]): + stream.close() + self._proc = None + + def _read_until(self, terminator): + """Read until the prompt is reached.""" + buf = bytearray() + while True: + c = self._proc.stdout.read(1) + if not c: + raise _ConverterError(os.fsdecode(bytes(buf))) + buf.extend(c) + if buf.endswith(terminator): + return bytes(buf) + + +class _GSConverter(_Converter): + def __call__(self, orig, dest): + if not self._proc: + self._proc = subprocess.Popen( + [mpl._get_executable_info("gs").executable, + "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop", "-sDEVICE=png16m"], + # As far as I can see, ghostscript never outputs to stderr. + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + try: + self._read_until(b"\nGS") + except _ConverterError as e: + raise OSError(f"Failed to start Ghostscript:\n\n{e.args[0]}") from None + + def encode_and_escape(name): + return (os.fsencode(name) + .replace(b"\\", b"\\\\") + .replace(b"(", br"\(") + .replace(b")", br"\)")) + + self._proc.stdin.write( + b"<< /OutputFile (" + + encode_and_escape(dest) + + b") >> setpagedevice (" + + encode_and_escape(orig) + + b") run flush\n") + self._proc.stdin.flush() + # GS> if nothing left on the stack; GS<n> if n items left on the stack. + err = self._read_until((b"GS<", b"GS>")) + stack = self._read_until(b">") if err.endswith(b"GS<") else b"" + if stack or not os.path.exists(dest): + stack_size = int(stack[:-1]) if stack else 0 + self._proc.stdin.write(b"pop\n" * stack_size) + # Using the systemencoding should at least get the filenames right. + raise ImageComparisonFailure( + (err + stack).decode(sys.getfilesystemencoding(), "replace")) + + +class _SVGConverter(_Converter): + def __call__(self, orig, dest): + old_inkscape = mpl._get_executable_info("inkscape").version.major < 1 + terminator = b"\n>" if old_inkscape else b"> " + if not hasattr(self, "_tmpdir"): + self._tmpdir = TemporaryDirectory() + # On Windows, we must make sure that self._proc has terminated + # (which __del__ does) before clearing _tmpdir. + weakref.finalize(self._tmpdir, self.__del__) + if (not self._proc # First run. + or self._proc.poll() is not None): # Inkscape terminated. + if self._proc is not None and self._proc.poll() is not None: + for stream in filter(None, [self._proc.stdin, + self._proc.stdout, + self._proc.stderr]): + stream.close() + env = { + **os.environ, + # If one passes e.g. a png file to Inkscape, it will try to + # query the user for conversion options via a GUI (even with + # `--without-gui`). Unsetting `DISPLAY` prevents this (and + # causes GTK to crash and Inkscape to terminate, but that'll + # just be reported as a regular exception below). + "DISPLAY": "", + # Do not load any user options. + "INKSCAPE_PROFILE_DIR": self._tmpdir.name, + } + # Old versions of Inkscape (e.g. 0.48.3.1) seem to sometimes + # deadlock when stderr is redirected to a pipe, so we redirect it + # to a temporary file instead. This is not necessary anymore as of + # Inkscape 0.92.1. + stderr = TemporaryFile() + self._proc = subprocess.Popen( + ["inkscape", "--without-gui", "--shell"] if old_inkscape else + ["inkscape", "--shell"], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=stderr, + env=env, cwd=self._tmpdir.name) + # Slight abuse, but makes shutdown handling easier. + self._proc.stderr = stderr + try: + self._read_until(terminator) + except _ConverterError as err: + raise OSError( + "Failed to start Inkscape in interactive mode:\n\n" + + err.args[0]) from err + + # Inkscape's shell mode does not support escaping metacharacters in the + # filename ("\n", and ":;" for inkscape>=1). Avoid any problems by + # running from a temporary directory and using fixed filenames. + inkscape_orig = Path(self._tmpdir.name, os.fsdecode(b"f.svg")) + inkscape_dest = Path(self._tmpdir.name, os.fsdecode(b"f.png")) + try: + inkscape_orig.symlink_to(Path(orig).resolve()) + except OSError: + shutil.copyfile(orig, inkscape_orig) + self._proc.stdin.write( + b"f.svg --export-png=f.png\n" if old_inkscape else + b"file-open:f.svg;export-filename:f.png;export-do;file-close\n") + self._proc.stdin.flush() + try: + self._read_until(terminator) + except _ConverterError as err: + # Inkscape's output is not localized but gtk's is, so the output + # stream probably has a mixed encoding. Using the filesystem + # encoding should at least get the filenames right... + self._proc.stderr.seek(0) + raise ImageComparisonFailure( + self._proc.stderr.read().decode( + sys.getfilesystemencoding(), "replace")) from err + os.remove(inkscape_orig) + shutil.move(inkscape_dest, dest) + + def __del__(self): + super().__del__() + if hasattr(self, "_tmpdir"): + self._tmpdir.cleanup() + + +class _SVGWithMatplotlibFontsConverter(_SVGConverter): + """ + A SVG converter which explicitly adds the fonts shipped by Matplotlib to + Inkspace's font search path, to better support `svg.fonttype = "none"` + (which is in particular used by certain mathtext tests). + """ + + def __call__(self, orig, dest): + if not hasattr(self, "_tmpdir"): + self._tmpdir = TemporaryDirectory() + shutil.copytree(cbook._get_data_path("fonts/ttf"), + Path(self._tmpdir.name, "fonts")) + return super().__call__(orig, dest) + + +def _update_converter(): + try: + mpl._get_executable_info("gs") + except mpl.ExecutableNotFoundError: + pass + else: + converter['pdf'] = converter['eps'] = _GSConverter() + try: + mpl._get_executable_info("inkscape") + except mpl.ExecutableNotFoundError: + pass + else: + converter['svg'] = _SVGConverter() + + +#: A dictionary that maps filename extensions to functions which themselves +#: convert between arguments `old` and `new` (filenames). +converter = {} +_update_converter() +_svg_with_matplotlib_fonts_converter = _SVGWithMatplotlibFontsConverter() + + +def comparable_formats(): + """ + Return the list of file formats that `.compare_images` can compare + on this system. + + Returns + ------- + list of str + E.g. ``['png', 'pdf', 'svg', 'eps']``. + + """ + return ['png', *converter] + + +def convert(filename, cache): + """ + Convert the named file to png; return the name of the created file. + + If *cache* is True, the result of the conversion is cached in + `matplotlib.get_cachedir() + '/test_cache/'`. The caching is based on a + hash of the exact contents of the input file. Old cache entries are + automatically deleted as needed to keep the size of the cache capped to + twice the size of all baseline images. + """ + path = Path(filename) + if not path.exists(): + raise OSError(f"{path} does not exist") + if path.suffix[1:] not in converter: + import pytest + pytest.skip(f"Don't know how to convert {path.suffix} files to png") + newpath = path.parent / f"{path.stem}_{path.suffix[1:]}.png" + + # Only convert the file if the destination doesn't already exist or + # is out of date. + if not newpath.exists() or newpath.stat().st_mtime < path.stat().st_mtime: + cache_dir = _get_cache_path() if cache else None + + if cache_dir is not None: + _register_conversion_cache_cleaner_once() + hash_value = get_file_hash(path) + cached_path = cache_dir / (hash_value + newpath.suffix) + if cached_path.exists(): + _log.debug("For %s: reusing cached conversion.", filename) + shutil.copyfile(cached_path, newpath) + return str(newpath) + + _log.debug("For %s: converting to png.", filename) + convert = converter[path.suffix[1:]] + if path.suffix == ".svg": + contents = path.read_text() + if 'style="font:' in contents: + # for svg.fonttype = none, we explicitly patch the font search + # path so that fonts shipped by Matplotlib are found. + convert = _svg_with_matplotlib_fonts_converter + convert(path, newpath) + + if cache_dir is not None: + _log.debug("For %s: caching conversion result.", filename) + shutil.copyfile(newpath, cached_path) + + return str(newpath) + + +def _clean_conversion_cache(): + # This will actually ignore mpl_toolkits baseline images, but they're + # relatively small. + baseline_images_size = sum( + path.stat().st_size + for path in Path(mpl.__file__).parent.glob("**/baseline_images/**/*")) + # 2x: one full copy of baselines, and one full copy of test results + # (actually an overestimate: we don't convert png baselines and results). + max_cache_size = 2 * baseline_images_size + # Reduce cache until it fits. + with cbook._lock_path(_get_cache_path()): + cache_stat = { + path: path.stat() for path in _get_cache_path().glob("*")} + cache_size = sum(stat.st_size for stat in cache_stat.values()) + paths_by_atime = sorted( # Oldest at the end. + cache_stat, key=lambda path: cache_stat[path].st_atime, + reverse=True) + while cache_size > max_cache_size: + path = paths_by_atime.pop() + cache_size -= cache_stat[path].st_size + path.unlink() + + +@functools.cache # Ensure this is only registered once. +def _register_conversion_cache_cleaner_once(): + atexit.register(_clean_conversion_cache) + + +def crop_to_same(actual_path, actual_image, expected_path, expected_image): + # clip the images to the same size -- this is useful only when + # comparing eps to pdf + if actual_path[-7:-4] == 'eps' and expected_path[-7:-4] == 'pdf': + aw, ah, ad = actual_image.shape + ew, eh, ed = expected_image.shape + actual_image = actual_image[int(aw / 2 - ew / 2):int( + aw / 2 + ew / 2), int(ah / 2 - eh / 2):int(ah / 2 + eh / 2)] + return actual_image, expected_image + + +def calculate_rms(expected_image, actual_image): + """ + Calculate the per-pixel errors, then compute the root mean square error. + """ + if expected_image.shape != actual_image.shape: + raise ImageComparisonFailure( + f"Image sizes do not match expected size: {expected_image.shape} " + f"actual size {actual_image.shape}") + # Convert to float to avoid overflowing finite integer types. + return np.sqrt(((expected_image - actual_image).astype(float) ** 2).mean()) + + +# NOTE: compare_image and save_diff_image assume that the image does not have +# 16-bit depth, as Pillow converts these to RGB incorrectly. + + +def _load_image(path): + img = Image.open(path) + # In an RGBA image, if the smallest value in the alpha channel is 255, all + # values in it must be 255, meaning that the image is opaque. If so, + # discard the alpha channel so that it may compare equal to an RGB image. + if img.mode != "RGBA" or img.getextrema()[3][0] == 255: + img = img.convert("RGB") + return np.asarray(img) + + +def compare_images(expected, actual, tol, in_decorator=False): + """ + Compare two "image" files checking differences within a tolerance. + + The two given filenames may point to files which are convertible to + PNG via the `.converter` dictionary. The underlying RMS is calculated + with the `.calculate_rms` function. + + Parameters + ---------- + expected : str + The filename of the expected image. + actual : str + The filename of the actual image. + tol : float + The tolerance (a color value difference, where 255 is the + maximal difference). The test fails if the average pixel + difference is greater than this value. + in_decorator : bool + Determines the output format. If called from image_comparison + decorator, this should be True. (default=False) + + Returns + ------- + None or dict or str + Return *None* if the images are equal within the given tolerance. + + If the images differ, the return value depends on *in_decorator*. + If *in_decorator* is true, a dict with the following entries is + returned: + + - *rms*: The RMS of the image difference. + - *expected*: The filename of the expected image. + - *actual*: The filename of the actual image. + - *diff_image*: The filename of the difference image. + - *tol*: The comparison tolerance. + + Otherwise, a human-readable multi-line string representation of this + information is returned. + + Examples + -------- + :: + + img1 = "./baseline/plot.png" + img2 = "./output/plot.png" + compare_images(img1, img2, 0.001) + + """ + actual = os.fspath(actual) + if not os.path.exists(actual): + raise Exception(f"Output image {actual} does not exist.") + if os.stat(actual).st_size == 0: + raise Exception(f"Output image file {actual} is empty.") + + # Convert the image to png + expected = os.fspath(expected) + if not os.path.exists(expected): + raise OSError(f'Baseline image {expected!r} does not exist.') + extension = expected.split('.')[-1] + if extension != 'png': + actual = convert(actual, cache=True) + expected = convert(expected, cache=True) + + # open the image files + expected_image = _load_image(expected) + actual_image = _load_image(actual) + + actual_image, expected_image = crop_to_same( + actual, actual_image, expected, expected_image) + + diff_image = make_test_filename(actual, 'failed-diff') + + if tol <= 0: + if np.array_equal(expected_image, actual_image): + return None + + # convert to signed integers, so that the images can be subtracted without + # overflow + expected_image = expected_image.astype(np.int16) + actual_image = actual_image.astype(np.int16) + + rms = calculate_rms(expected_image, actual_image) + + if rms <= tol: + return None + + save_diff_image(expected, actual, diff_image) + + results = dict(rms=rms, expected=str(expected), + actual=str(actual), diff=str(diff_image), tol=tol) + + if not in_decorator: + # Then the results should be a string suitable for stdout. + template = ['Error: Image files did not match.', + 'RMS Value: {rms}', + 'Expected: \n {expected}', + 'Actual: \n {actual}', + 'Difference:\n {diff}', + 'Tolerance: \n {tol}', ] + results = '\n '.join([line.format(**results) for line in template]) + return results + + +def save_diff_image(expected, actual, output): + """ + Parameters + ---------- + expected : str + File path of expected image. + actual : str + File path of actual image. + output : str + File path to save difference image to. + """ + expected_image = _load_image(expected) + actual_image = _load_image(actual) + actual_image, expected_image = crop_to_same( + actual, actual_image, expected, expected_image) + expected_image = np.array(expected_image, float) + actual_image = np.array(actual_image, float) + if expected_image.shape != actual_image.shape: + raise ImageComparisonFailure( + f"Image sizes do not match expected size: {expected_image.shape} " + f"actual size {actual_image.shape}") + abs_diff = np.abs(expected_image - actual_image) + + # expand differences in luminance domain + abs_diff *= 10 + abs_diff = np.clip(abs_diff, 0, 255).astype(np.uint8) + + if abs_diff.shape[2] == 4: # Hard-code the alpha channel to fully solid + abs_diff[:, :, 3] = 255 + + Image.fromarray(abs_diff).save(output, format="png") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.pyi new file mode 100644 index 00000000..8f11b3be --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/compare.pyi @@ -0,0 +1,32 @@ +from collections.abc import Callable +from typing import Literal, overload + +from numpy.typing import NDArray + +__all__ = ["calculate_rms", "comparable_formats", "compare_images"] + +def make_test_filename(fname: str, purpose: str) -> str: ... +def get_cache_dir() -> str: ... +def get_file_hash(path: str, block_size: int = ...) -> str: ... + +converter: dict[str, Callable[[str, str], None]] = {} + +def comparable_formats() -> list[str]: ... +def convert(filename: str, cache: bool) -> str: ... +def crop_to_same( + actual_path: str, actual_image: NDArray, expected_path: str, expected_image: NDArray +) -> tuple[NDArray, NDArray]: ... +def calculate_rms(expected_image: NDArray, actual_image: NDArray) -> float: ... +@overload +def compare_images( + expected: str, actual: str, tol: float, in_decorator: Literal[True] +) -> None | dict[str, float | str]: ... +@overload +def compare_images( + expected: str, actual: str, tol: float, in_decorator: Literal[False] +) -> None | str: ... +@overload +def compare_images( + expected: str, actual: str, tol: float, in_decorator: bool = ... +) -> None | str | dict[str, float | str]: ... +def save_diff_image(expected: str, actual: str, output: str) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.py new file mode 100644 index 00000000..c285c247 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.py @@ -0,0 +1,100 @@ +import pytest +import sys +import matplotlib +from matplotlib import _api + + +def pytest_configure(config): + # config is initialized here rather than in pytest.ini so that `pytest + # --pyargs matplotlib` (which would not find pytest.ini) works. The only + # entries in pytest.ini set minversion (which is checked earlier), + # testpaths/python_files, as they are required to properly find the tests + for key, value in [ + ("markers", "flaky: (Provided by pytest-rerunfailures.)"), + ("markers", "timeout: (Provided by pytest-timeout.)"), + ("markers", "backend: Set alternate Matplotlib backend temporarily."), + ("markers", "baseline_images: Compare output against references."), + ("markers", "pytz: Tests that require pytz to be installed."), + ("filterwarnings", "error"), + ("filterwarnings", + "ignore:.*The py23 module has been deprecated:DeprecationWarning"), + ("filterwarnings", + r"ignore:DynamicImporter.find_spec\(\) not found; " + r"falling back to find_module\(\):ImportWarning"), + ]: + config.addinivalue_line(key, value) + + matplotlib.use('agg', force=True) + matplotlib._called_from_pytest = True + matplotlib._init_tests() + + +def pytest_unconfigure(config): + matplotlib._called_from_pytest = False + + +@pytest.fixture(autouse=True) +def mpl_test_settings(request): + from matplotlib.testing.decorators import _cleanup_cm + + with _cleanup_cm(): + + backend = None + backend_marker = request.node.get_closest_marker('backend') + prev_backend = matplotlib.get_backend() + if backend_marker is not None: + assert len(backend_marker.args) == 1, \ + "Marker 'backend' must specify 1 backend." + backend, = backend_marker.args + skip_on_importerror = backend_marker.kwargs.get( + 'skip_on_importerror', False) + + # special case Qt backend importing to avoid conflicts + if backend.lower().startswith('qt5'): + if any(sys.modules.get(k) for k in ('PyQt4', 'PySide')): + pytest.skip('Qt4 binding already imported') + + matplotlib.testing.setup() + with _api.suppress_matplotlib_deprecation_warning(): + if backend is not None: + # This import must come after setup() so it doesn't load the + # default backend prematurely. + import matplotlib.pyplot as plt + try: + plt.switch_backend(backend) + except ImportError as exc: + # Should only occur for the cairo backend tests, if neither + # pycairo nor cairocffi are installed. + if 'cairo' in backend.lower() or skip_on_importerror: + pytest.skip("Failed to switch to backend " + f"{backend} ({exc}).") + else: + raise + # Default of cleanup and image_comparison too. + matplotlib.style.use(["classic", "_classic_test_patch"]) + try: + yield + finally: + if backend is not None: + plt.close("all") + matplotlib.use(prev_backend) + + +@pytest.fixture +def pd(): + """Fixture to import and configure pandas.""" + pd = pytest.importorskip('pandas') + try: + from pandas.plotting import ( + deregister_matplotlib_converters as deregister) + deregister() + except ImportError: + pass + return pd + + +@pytest.fixture +def xr(): + """Fixture to import xarray.""" + xr = pytest.importorskip('xarray') + return xr diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.pyi new file mode 100644 index 00000000..2af0eb93 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/conftest.pyi @@ -0,0 +1,12 @@ +from types import ModuleType + +import pytest + +def pytest_configure(config: pytest.Config) -> None: ... +def pytest_unconfigure(config: pytest.Config) -> None: ... +@pytest.fixture +def mpl_test_settings(request: pytest.FixtureRequest) -> None: ... +@pytest.fixture +def pd() -> ModuleType: ... +@pytest.fixture +def xr() -> ModuleType: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.py new file mode 100644 index 00000000..49ac4a15 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.py @@ -0,0 +1,464 @@ +import contextlib +import functools +import inspect +import os +from platform import uname +from pathlib import Path +import shutil +import string +import sys +import warnings + +from packaging.version import parse as parse_version + +import matplotlib.style +import matplotlib.units +import matplotlib.testing +from matplotlib import _pylab_helpers, cbook, ft2font, pyplot as plt, ticker +from .compare import comparable_formats, compare_images, make_test_filename +from .exceptions import ImageComparisonFailure + + +@contextlib.contextmanager +def _cleanup_cm(): + orig_units_registry = matplotlib.units.registry.copy() + try: + with warnings.catch_warnings(), matplotlib.rc_context(): + yield + finally: + matplotlib.units.registry.clear() + matplotlib.units.registry.update(orig_units_registry) + plt.close("all") + + +def _check_freetype_version(ver): + if ver is None: + return True + + if isinstance(ver, str): + ver = (ver, ver) + ver = [parse_version(x) for x in ver] + found = parse_version(ft2font.__freetype_version__) + + return ver[0] <= found <= ver[1] + + +def _checked_on_freetype_version(required_freetype_version): + import pytest + return pytest.mark.xfail( + not _check_freetype_version(required_freetype_version), + reason=f"Mismatched version of freetype. " + f"Test requires '{required_freetype_version}', " + f"you have '{ft2font.__freetype_version__}'", + raises=ImageComparisonFailure, strict=False) + + +def remove_ticks_and_titles(figure): + figure.suptitle("") + null_formatter = ticker.NullFormatter() + def remove_ticks(ax): + """Remove ticks in *ax* and all its child Axes.""" + ax.set_title("") + ax.xaxis.set_major_formatter(null_formatter) + ax.xaxis.set_minor_formatter(null_formatter) + ax.yaxis.set_major_formatter(null_formatter) + ax.yaxis.set_minor_formatter(null_formatter) + try: + ax.zaxis.set_major_formatter(null_formatter) + ax.zaxis.set_minor_formatter(null_formatter) + except AttributeError: + pass + for child in ax.child_axes: + remove_ticks(child) + for ax in figure.get_axes(): + remove_ticks(ax) + + +@contextlib.contextmanager +def _collect_new_figures(): + """ + After:: + + with _collect_new_figures() as figs: + some_code() + + the list *figs* contains the figures that have been created during the + execution of ``some_code``, sorted by figure number. + """ + managers = _pylab_helpers.Gcf.figs + preexisting = [manager for manager in managers.values()] + new_figs = [] + try: + yield new_figs + finally: + new_managers = sorted([manager for manager in managers.values() + if manager not in preexisting], + key=lambda manager: manager.num) + new_figs[:] = [manager.canvas.figure for manager in new_managers] + + +def _raise_on_image_difference(expected, actual, tol): + __tracebackhide__ = True + + err = compare_images(expected, actual, tol, in_decorator=True) + if err: + for key in ["actual", "expected", "diff"]: + err[key] = os.path.relpath(err[key]) + raise ImageComparisonFailure( + ('images not close (RMS %(rms).3f):' + '\n\t%(actual)s\n\t%(expected)s\n\t%(diff)s') % err) + + +class _ImageComparisonBase: + """ + Image comparison base class + + This class provides *just* the comparison-related functionality and avoids + any code that would be specific to any testing framework. + """ + + def __init__(self, func, tol, remove_text, savefig_kwargs): + self.func = func + self.baseline_dir, self.result_dir = _image_directories(func) + self.tol = tol + self.remove_text = remove_text + self.savefig_kwargs = savefig_kwargs + + def copy_baseline(self, baseline, extension): + baseline_path = self.baseline_dir / baseline + orig_expected_path = baseline_path.with_suffix(f'.{extension}') + if extension == 'eps' and not orig_expected_path.exists(): + orig_expected_path = orig_expected_path.with_suffix('.pdf') + expected_fname = make_test_filename( + self.result_dir / orig_expected_path.name, 'expected') + try: + # os.symlink errors if the target already exists. + with contextlib.suppress(OSError): + os.remove(expected_fname) + try: + if 'microsoft' in uname().release.lower(): + raise OSError # On WSL, symlink breaks silently + os.symlink(orig_expected_path, expected_fname) + except OSError: # On Windows, symlink *may* be unavailable. + shutil.copyfile(orig_expected_path, expected_fname) + except OSError as err: + raise ImageComparisonFailure( + f"Missing baseline image {expected_fname} because the " + f"following file cannot be accessed: " + f"{orig_expected_path}") from err + return expected_fname + + def compare(self, fig, baseline, extension, *, _lock=False): + __tracebackhide__ = True + + if self.remove_text: + remove_ticks_and_titles(fig) + + actual_path = (self.result_dir / baseline).with_suffix(f'.{extension}') + kwargs = self.savefig_kwargs.copy() + if extension == 'pdf': + kwargs.setdefault('metadata', + {'Creator': None, 'Producer': None, + 'CreationDate': None}) + + lock = (cbook._lock_path(actual_path) + if _lock else contextlib.nullcontext()) + with lock: + try: + fig.savefig(actual_path, **kwargs) + finally: + # Matplotlib has an autouse fixture to close figures, but this + # makes things more convenient for third-party users. + plt.close(fig) + expected_path = self.copy_baseline(baseline, extension) + _raise_on_image_difference(expected_path, actual_path, self.tol) + + +def _pytest_image_comparison(baseline_images, extensions, tol, + freetype_version, remove_text, savefig_kwargs, + style): + """ + Decorate function with image comparison for pytest. + + This function creates a decorator that wraps a figure-generating function + with image comparison code. + """ + import pytest + + KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY + + def decorator(func): + old_sig = inspect.signature(func) + + @functools.wraps(func) + @pytest.mark.parametrize('extension', extensions) + @matplotlib.style.context(style) + @_checked_on_freetype_version(freetype_version) + @functools.wraps(func) + def wrapper(*args, extension, request, **kwargs): + __tracebackhide__ = True + if 'extension' in old_sig.parameters: + kwargs['extension'] = extension + if 'request' in old_sig.parameters: + kwargs['request'] = request + + if extension not in comparable_formats(): + reason = { + 'pdf': 'because Ghostscript is not installed', + 'eps': 'because Ghostscript is not installed', + 'svg': 'because Inkscape is not installed', + }.get(extension, 'on this system') + pytest.skip(f"Cannot compare {extension} files {reason}") + + img = _ImageComparisonBase(func, tol=tol, remove_text=remove_text, + savefig_kwargs=savefig_kwargs) + matplotlib.testing.set_font_settings_for_testing() + + with _collect_new_figures() as figs: + func(*args, **kwargs) + + # If the test is parametrized in any way other than applied via + # this decorator, then we need to use a lock to prevent two + # processes from touching the same output file. + needs_lock = any( + marker.args[0] != 'extension' + for marker in request.node.iter_markers('parametrize')) + + if baseline_images is not None: + our_baseline_images = baseline_images + else: + # Allow baseline image list to be produced on the fly based on + # current parametrization. + our_baseline_images = request.getfixturevalue( + 'baseline_images') + + assert len(figs) == len(our_baseline_images), ( + f"Test generated {len(figs)} images but there are " + f"{len(our_baseline_images)} baseline images") + for fig, baseline in zip(figs, our_baseline_images): + img.compare(fig, baseline, extension, _lock=needs_lock) + + parameters = list(old_sig.parameters.values()) + if 'extension' not in old_sig.parameters: + parameters += [inspect.Parameter('extension', KEYWORD_ONLY)] + if 'request' not in old_sig.parameters: + parameters += [inspect.Parameter("request", KEYWORD_ONLY)] + new_sig = old_sig.replace(parameters=parameters) + wrapper.__signature__ = new_sig + + # Reach a bit into pytest internals to hoist the marks from our wrapped + # function. + new_marks = getattr(func, 'pytestmark', []) + wrapper.pytestmark + wrapper.pytestmark = new_marks + + return wrapper + + return decorator + + +def image_comparison(baseline_images, extensions=None, tol=0, + freetype_version=None, remove_text=False, + savefig_kwarg=None, + # Default of mpl_test_settings fixture and cleanup too. + style=("classic", "_classic_test_patch")): + """ + Compare images generated by the test with those specified in + *baseline_images*, which must correspond, else an `ImageComparisonFailure` + exception will be raised. + + Parameters + ---------- + baseline_images : list or None + A list of strings specifying the names of the images generated by + calls to `.Figure.savefig`. + + If *None*, the test function must use the ``baseline_images`` fixture, + either as a parameter or with `pytest.mark.usefixtures`. This value is + only allowed when using pytest. + + extensions : None or list of str + The list of extensions to test, e.g. ``['png', 'pdf']``. + + If *None*, defaults to all supported extensions: png, pdf, and svg. + + When testing a single extension, it can be directly included in the + names passed to *baseline_images*. In that case, *extensions* must not + be set. + + In order to keep the size of the test suite from ballooning, we only + include the ``svg`` or ``pdf`` outputs if the test is explicitly + exercising a feature dependent on that backend (see also the + `check_figures_equal` decorator for that purpose). + + tol : float, default: 0 + The RMS threshold above which the test is considered failed. + + Due to expected small differences in floating-point calculations, on + 32-bit systems an additional 0.06 is added to this threshold. + + freetype_version : str or tuple + The expected freetype version or range of versions for this test to + pass. + + remove_text : bool + Remove the title and tick text from the figure before comparison. This + is useful to make the baseline images independent of variations in text + rendering between different versions of FreeType. + + This does not remove other, more deliberate, text, such as legends and + annotations. + + savefig_kwarg : dict + Optional arguments that are passed to the savefig method. + + style : str, dict, or list + The optional style(s) to apply to the image test. The test itself + can also apply additional styles if desired. Defaults to ``["classic", + "_classic_test_patch"]``. + """ + + if baseline_images is not None: + # List of non-empty filename extensions. + baseline_exts = [*filter(None, {Path(baseline).suffix[1:] + for baseline in baseline_images})] + if baseline_exts: + if extensions is not None: + raise ValueError( + "When including extensions directly in 'baseline_images', " + "'extensions' cannot be set as well") + if len(baseline_exts) > 1: + raise ValueError( + "When including extensions directly in 'baseline_images', " + "all baselines must share the same suffix") + extensions = baseline_exts + baseline_images = [ # Chop suffix out from baseline_images. + Path(baseline).stem for baseline in baseline_images] + if extensions is None: + # Default extensions to test, if not set via baseline_images. + extensions = ['png', 'pdf', 'svg'] + if savefig_kwarg is None: + savefig_kwarg = dict() # default no kwargs to savefig + if sys.maxsize <= 2**32: + tol += 0.06 + return _pytest_image_comparison( + baseline_images=baseline_images, extensions=extensions, tol=tol, + freetype_version=freetype_version, remove_text=remove_text, + savefig_kwargs=savefig_kwarg, style=style) + + +def check_figures_equal(*, extensions=("png", "pdf", "svg"), tol=0): + """ + Decorator for test cases that generate and compare two figures. + + The decorated function must take two keyword arguments, *fig_test* + and *fig_ref*, and draw the test and reference images on them. + After the function returns, the figures are saved and compared. + + This decorator should be preferred over `image_comparison` when possible in + order to keep the size of the test suite from ballooning. + + Parameters + ---------- + extensions : list, default: ["png", "pdf", "svg"] + The extensions to test. + tol : float + The RMS threshold above which the test is considered failed. + + Raises + ------ + RuntimeError + If any new figures are created (and not subsequently closed) inside + the test function. + + Examples + -------- + Check that calling `.Axes.plot` with a single argument plots it against + ``[0, 1, 2, ...]``:: + + @check_figures_equal() + def test_plot(fig_test, fig_ref): + fig_test.subplots().plot([1, 3, 5]) + fig_ref.subplots().plot([0, 1, 2], [1, 3, 5]) + + """ + ALLOWED_CHARS = set(string.digits + string.ascii_letters + '_-[]()') + KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY + + def decorator(func): + import pytest + + _, result_dir = _image_directories(func) + old_sig = inspect.signature(func) + + if not {"fig_test", "fig_ref"}.issubset(old_sig.parameters): + raise ValueError("The decorated function must have at least the " + "parameters 'fig_test' and 'fig_ref', but your " + f"function has the signature {old_sig}") + + @pytest.mark.parametrize("ext", extensions) + def wrapper(*args, ext, request, **kwargs): + if 'ext' in old_sig.parameters: + kwargs['ext'] = ext + if 'request' in old_sig.parameters: + kwargs['request'] = request + + file_name = "".join(c for c in request.node.name + if c in ALLOWED_CHARS) + try: + fig_test = plt.figure("test") + fig_ref = plt.figure("reference") + with _collect_new_figures() as figs: + func(*args, fig_test=fig_test, fig_ref=fig_ref, **kwargs) + if figs: + raise RuntimeError('Number of open figures changed during ' + 'test. Make sure you are plotting to ' + 'fig_test or fig_ref, or if this is ' + 'deliberate explicitly close the ' + 'new figure(s) inside the test.') + test_image_path = result_dir / (file_name + "." + ext) + ref_image_path = result_dir / (file_name + "-expected." + ext) + fig_test.savefig(test_image_path) + fig_ref.savefig(ref_image_path) + _raise_on_image_difference( + ref_image_path, test_image_path, tol=tol + ) + finally: + plt.close(fig_test) + plt.close(fig_ref) + + parameters = [ + param + for param in old_sig.parameters.values() + if param.name not in {"fig_test", "fig_ref"} + ] + if 'ext' not in old_sig.parameters: + parameters += [inspect.Parameter("ext", KEYWORD_ONLY)] + if 'request' not in old_sig.parameters: + parameters += [inspect.Parameter("request", KEYWORD_ONLY)] + new_sig = old_sig.replace(parameters=parameters) + wrapper.__signature__ = new_sig + + # reach a bit into pytest internals to hoist the marks from + # our wrapped function + new_marks = getattr(func, "pytestmark", []) + wrapper.pytestmark + wrapper.pytestmark = new_marks + + return wrapper + + return decorator + + +def _image_directories(func): + """ + Compute the baseline and result image directories for testing *func*. + + For test module ``foo.bar.test_baz``, the baseline directory is at + ``foo/bar/baseline_images/test_baz`` and the result directory at + ``$(pwd)/result_images/test_baz``. The result directory is created if it + doesn't exist. + """ + module_path = Path(inspect.getfile(func)) + baseline_dir = module_path.parent / "baseline_images" / module_path.stem + result_dir = Path().resolve() / "result_images" / module_path.stem + result_dir.mkdir(parents=True, exist_ok=True) + return baseline_dir, result_dir diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.pyi new file mode 100644 index 00000000..f1b6c5e5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/decorators.pyi @@ -0,0 +1,25 @@ +from collections.abc import Callable, Sequence +from pathlib import Path +from typing import Any, TypeVar +from typing_extensions import ParamSpec + +from matplotlib.figure import Figure +from matplotlib.typing import RcStyleType + +_P = ParamSpec("_P") +_R = TypeVar("_R") + +def remove_ticks_and_titles(figure: Figure) -> None: ... +def image_comparison( + baseline_images: list[str] | None, + extensions: list[str] | None = ..., + tol: float = ..., + freetype_version: tuple[str, str] | str | None = ..., + remove_text: bool = ..., + savefig_kwarg: dict[str, Any] | None = ..., + style: RcStyleType = ..., +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... +def check_figures_equal( + *, extensions: Sequence[str] = ..., tol: float = ... +) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ... +def _image_directories(func: Callable) -> tuple[Path, Path]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/exceptions.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/exceptions.py new file mode 100644 index 00000000..c39a3920 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/exceptions.py @@ -0,0 +1,4 @@ +class ImageComparisonFailure(AssertionError): + """ + Raise this exception to mark a test as a comparison between two images. + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Duration.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Duration.py new file mode 100644 index 00000000..052c5a47 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Duration.py @@ -0,0 +1,138 @@ +"""Duration module.""" + +import functools +import operator + +from matplotlib import _api + + +class Duration: + """Class Duration in development.""" + + allowed = ["ET", "UTC"] + + def __init__(self, frame, seconds): + """ + Create a new Duration object. + + = ERROR CONDITIONS + - If the input frame is not in the allowed list, an error is thrown. + + = INPUT VARIABLES + - frame The frame of the duration. Must be 'ET' or 'UTC' + - seconds The number of seconds in the Duration. + """ + _api.check_in_list(self.allowed, frame=frame) + self._frame = frame + self._seconds = seconds + + def frame(self): + """Return the frame the duration is in.""" + return self._frame + + def __abs__(self): + """Return the absolute value of the duration.""" + return Duration(self._frame, abs(self._seconds)) + + def __neg__(self): + """Return the negative value of this Duration.""" + return Duration(self._frame, -self._seconds) + + def seconds(self): + """Return the number of seconds in the Duration.""" + return self._seconds + + def __bool__(self): + return self._seconds != 0 + + def _cmp(self, op, rhs): + """ + Check that *self* and *rhs* share frames; compare them using *op*. + """ + self.checkSameFrame(rhs, "compare") + return op(self._seconds, rhs._seconds) + + __eq__ = functools.partialmethod(_cmp, operator.eq) + __ne__ = functools.partialmethod(_cmp, operator.ne) + __lt__ = functools.partialmethod(_cmp, operator.lt) + __le__ = functools.partialmethod(_cmp, operator.le) + __gt__ = functools.partialmethod(_cmp, operator.gt) + __ge__ = functools.partialmethod(_cmp, operator.ge) + + def __add__(self, rhs): + """ + Add two Durations. + + = ERROR CONDITIONS + - If the input rhs is not in the same frame, an error is thrown. + + = INPUT VARIABLES + - rhs The Duration to add. + + = RETURN VALUE + - Returns the sum of ourselves and the input Duration. + """ + # Delay-load due to circular dependencies. + import matplotlib.testing.jpl_units as U + + if isinstance(rhs, U.Epoch): + return rhs + self + + self.checkSameFrame(rhs, "add") + return Duration(self._frame, self._seconds + rhs._seconds) + + def __sub__(self, rhs): + """ + Subtract two Durations. + + = ERROR CONDITIONS + - If the input rhs is not in the same frame, an error is thrown. + + = INPUT VARIABLES + - rhs The Duration to subtract. + + = RETURN VALUE + - Returns the difference of ourselves and the input Duration. + """ + self.checkSameFrame(rhs, "sub") + return Duration(self._frame, self._seconds - rhs._seconds) + + def __mul__(self, rhs): + """ + Scale a UnitDbl by a value. + + = INPUT VARIABLES + - rhs The scalar to multiply by. + + = RETURN VALUE + - Returns the scaled Duration. + """ + return Duration(self._frame, self._seconds * float(rhs)) + + __rmul__ = __mul__ + + def __str__(self): + """Print the Duration.""" + return f"{self._seconds:g} {self._frame}" + + def __repr__(self): + """Print the Duration.""" + return f"Duration('{self._frame}', {self._seconds:g})" + + def checkSameFrame(self, rhs, func): + """ + Check to see if frames are the same. + + = ERROR CONDITIONS + - If the frame of the rhs Duration is not the same as our frame, + an error is thrown. + + = INPUT VARIABLES + - rhs The Duration to check for the same frame + - func The name of the function doing the check. + """ + if self._frame != rhs._frame: + raise ValueError( + f"Cannot {func} Durations with different frames.\n" + f"LHS: {self._frame}\n" + f"RHS: {rhs._frame}") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Epoch.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Epoch.py new file mode 100644 index 00000000..501b7fa3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/Epoch.py @@ -0,0 +1,211 @@ +"""Epoch module.""" + +import functools +import operator +import math +import datetime as DT + +from matplotlib import _api +from matplotlib.dates import date2num + + +class Epoch: + # Frame conversion offsets in seconds + # t(TO) = t(FROM) + allowed[ FROM ][ TO ] + allowed = { + "ET": { + "UTC": +64.1839, + }, + "UTC": { + "ET": -64.1839, + }, + } + + def __init__(self, frame, sec=None, jd=None, daynum=None, dt=None): + """ + Create a new Epoch object. + + Build an epoch 1 of 2 ways: + + Using seconds past a Julian date: + # Epoch('ET', sec=1e8, jd=2451545) + + or using a matplotlib day number + # Epoch('ET', daynum=730119.5) + + = ERROR CONDITIONS + - If the input units are not in the allowed list, an error is thrown. + + = INPUT VARIABLES + - frame The frame of the epoch. Must be 'ET' or 'UTC' + - sec The number of seconds past the input JD. + - jd The Julian date of the epoch. + - daynum The matplotlib day number of the epoch. + - dt A python datetime instance. + """ + if ((sec is None and jd is not None) or + (sec is not None and jd is None) or + (daynum is not None and + (sec is not None or jd is not None)) or + (daynum is None and dt is None and + (sec is None or jd is None)) or + (daynum is not None and dt is not None) or + (dt is not None and (sec is not None or jd is not None)) or + ((dt is not None) and not isinstance(dt, DT.datetime))): + raise ValueError( + "Invalid inputs. Must enter sec and jd together, " + "daynum by itself, or dt (must be a python datetime).\n" + "Sec = %s\n" + "JD = %s\n" + "dnum= %s\n" + "dt = %s" % (sec, jd, daynum, dt)) + + _api.check_in_list(self.allowed, frame=frame) + self._frame = frame + + if dt is not None: + daynum = date2num(dt) + + if daynum is not None: + # 1-JAN-0001 in JD = 1721425.5 + jd = float(daynum) + 1721425.5 + self._jd = math.floor(jd) + self._seconds = (jd - self._jd) * 86400.0 + + else: + self._seconds = float(sec) + self._jd = float(jd) + + # Resolve seconds down to [ 0, 86400) + deltaDays = math.floor(self._seconds / 86400) + self._jd += deltaDays + self._seconds -= deltaDays * 86400.0 + + def convert(self, frame): + if self._frame == frame: + return self + + offset = self.allowed[self._frame][frame] + + return Epoch(frame, self._seconds + offset, self._jd) + + def frame(self): + return self._frame + + def julianDate(self, frame): + t = self + if frame != self._frame: + t = self.convert(frame) + + return t._jd + t._seconds / 86400.0 + + def secondsPast(self, frame, jd): + t = self + if frame != self._frame: + t = self.convert(frame) + + delta = t._jd - jd + return t._seconds + delta * 86400 + + def _cmp(self, op, rhs): + """Compare Epochs *self* and *rhs* using operator *op*.""" + t = self + if self._frame != rhs._frame: + t = self.convert(rhs._frame) + if t._jd != rhs._jd: + return op(t._jd, rhs._jd) + return op(t._seconds, rhs._seconds) + + __eq__ = functools.partialmethod(_cmp, operator.eq) + __ne__ = functools.partialmethod(_cmp, operator.ne) + __lt__ = functools.partialmethod(_cmp, operator.lt) + __le__ = functools.partialmethod(_cmp, operator.le) + __gt__ = functools.partialmethod(_cmp, operator.gt) + __ge__ = functools.partialmethod(_cmp, operator.ge) + + def __add__(self, rhs): + """ + Add a duration to an Epoch. + + = INPUT VARIABLES + - rhs The Epoch to subtract. + + = RETURN VALUE + - Returns the difference of ourselves and the input Epoch. + """ + t = self + if self._frame != rhs.frame(): + t = self.convert(rhs._frame) + + sec = t._seconds + rhs.seconds() + + return Epoch(t._frame, sec, t._jd) + + def __sub__(self, rhs): + """ + Subtract two Epoch's or a Duration from an Epoch. + + Valid: + Duration = Epoch - Epoch + Epoch = Epoch - Duration + + = INPUT VARIABLES + - rhs The Epoch to subtract. + + = RETURN VALUE + - Returns either the duration between to Epoch's or the a new + Epoch that is the result of subtracting a duration from an epoch. + """ + # Delay-load due to circular dependencies. + import matplotlib.testing.jpl_units as U + + # Handle Epoch - Duration + if isinstance(rhs, U.Duration): + return self + -rhs + + t = self + if self._frame != rhs._frame: + t = self.convert(rhs._frame) + + days = t._jd - rhs._jd + sec = t._seconds - rhs._seconds + + return U.Duration(rhs._frame, days*86400 + sec) + + def __str__(self): + """Print the Epoch.""" + return f"{self.julianDate(self._frame):22.15e} {self._frame}" + + def __repr__(self): + """Print the Epoch.""" + return str(self) + + @staticmethod + def range(start, stop, step): + """ + Generate a range of Epoch objects. + + Similar to the Python range() method. Returns the range [ + start, stop) at the requested step. Each element will be a + Epoch object. + + = INPUT VARIABLES + - start The starting value of the range. + - stop The stop value of the range. + - step Step to use. + + = RETURN VALUE + - Returns a list containing the requested Epoch values. + """ + elems = [] + + i = 0 + while True: + d = start + i * step + if d >= stop: + break + + elems.append(d) + i += 1 + + return elems diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/EpochConverter.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/EpochConverter.py new file mode 100644 index 00000000..f42d7b71 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/EpochConverter.py @@ -0,0 +1,96 @@ +"""EpochConverter module containing class EpochConverter.""" + +from matplotlib import cbook, units +import matplotlib.dates as date_ticker + +__all__ = ['EpochConverter'] + + +class EpochConverter(units.ConversionInterface): + """ + Provides Matplotlib conversion functionality for Monte Epoch and Duration + classes. + """ + + # julian date reference for "Jan 1, 0001" minus 1 day because + # Matplotlib really wants "Jan 0, 0001" + jdRef = 1721425.5 - 1 + + @staticmethod + def axisinfo(unit, axis): + # docstring inherited + majloc = date_ticker.AutoDateLocator() + majfmt = date_ticker.AutoDateFormatter(majloc) + return units.AxisInfo(majloc=majloc, majfmt=majfmt, label=unit) + + @staticmethod + def float2epoch(value, unit): + """ + Convert a Matplotlib floating-point date into an Epoch of the specified + units. + + = INPUT VARIABLES + - value The Matplotlib floating-point date. + - unit The unit system to use for the Epoch. + + = RETURN VALUE + - Returns the value converted to an Epoch in the specified time system. + """ + # Delay-load due to circular dependencies. + import matplotlib.testing.jpl_units as U + + secPastRef = value * 86400.0 * U.UnitDbl(1.0, 'sec') + return U.Epoch(unit, secPastRef, EpochConverter.jdRef) + + @staticmethod + def epoch2float(value, unit): + """ + Convert an Epoch value to a float suitable for plotting as a python + datetime object. + + = INPUT VARIABLES + - value An Epoch or list of Epochs that need to be converted. + - unit The units to use for an axis with Epoch data. + + = RETURN VALUE + - Returns the value parameter converted to floats. + """ + return value.julianDate(unit) - EpochConverter.jdRef + + @staticmethod + def duration2float(value): + """ + Convert a Duration value to a float suitable for plotting as a python + datetime object. + + = INPUT VARIABLES + - value A Duration or list of Durations that need to be converted. + + = RETURN VALUE + - Returns the value parameter converted to floats. + """ + return value.seconds() / 86400.0 + + @staticmethod + def convert(value, unit, axis): + # docstring inherited + + # Delay-load due to circular dependencies. + import matplotlib.testing.jpl_units as U + + if not cbook.is_scalar_or_string(value): + return [EpochConverter.convert(x, unit, axis) for x in value] + if unit is None: + unit = EpochConverter.default_units(value, axis) + if isinstance(value, U.Duration): + return EpochConverter.duration2float(value) + else: + return EpochConverter.epoch2float(value, unit) + + @staticmethod + def default_units(value, axis): + # docstring inherited + if cbook.is_scalar_or_string(value): + return value.frame() + else: + return EpochConverter.default_units(value[0], axis) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/StrConverter.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/StrConverter.py new file mode 100644 index 00000000..a62d4981 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/StrConverter.py @@ -0,0 +1,97 @@ +"""StrConverter module containing class StrConverter.""" + +import numpy as np + +import matplotlib.units as units + +__all__ = ['StrConverter'] + + +class StrConverter(units.ConversionInterface): + """ + A Matplotlib converter class for string data values. + + Valid units for string are: + - 'indexed' : Values are indexed as they are specified for plotting. + - 'sorted' : Values are sorted alphanumerically. + - 'inverted' : Values are inverted so that the first value is on top. + - 'sorted-inverted' : A combination of 'sorted' and 'inverted' + """ + + @staticmethod + def axisinfo(unit, axis): + # docstring inherited + return None + + @staticmethod + def convert(value, unit, axis): + # docstring inherited + + if value == []: + return [] + + # we delay loading to make matplotlib happy + ax = axis.axes + if axis is ax.xaxis: + isXAxis = True + else: + isXAxis = False + + axis.get_major_ticks() + ticks = axis.get_ticklocs() + labels = axis.get_ticklabels() + + labels = [l.get_text() for l in labels if l.get_text()] + + if not labels: + ticks = [] + labels = [] + + if not np.iterable(value): + value = [value] + + newValues = [] + for v in value: + if v not in labels and v not in newValues: + newValues.append(v) + + labels.extend(newValues) + + # DISABLED: This is disabled because matplotlib bar plots do not + # DISABLED: recalculate the unit conversion of the data values + # DISABLED: this is due to design and is not really a bug. + # DISABLED: If this gets changed, then we can activate the following + # DISABLED: block of code. Note that this works for line plots. + # DISABLED if unit: + # DISABLED if unit.find("sorted") > -1: + # DISABLED labels.sort() + # DISABLED if unit.find("inverted") > -1: + # DISABLED labels = labels[::-1] + + # add padding (so they do not appear on the axes themselves) + labels = [''] + labels + [''] + ticks = list(range(len(labels))) + ticks[0] = 0.5 + ticks[-1] = ticks[-1] - 0.5 + + axis.set_ticks(ticks) + axis.set_ticklabels(labels) + # we have to do the following lines to make ax.autoscale_view work + loc = axis.get_major_locator() + loc.set_bounds(ticks[0], ticks[-1]) + + if isXAxis: + ax.set_xlim(ticks[0], ticks[-1]) + else: + ax.set_ylim(ticks[0], ticks[-1]) + + result = [ticks[labels.index(v)] for v in value] + + ax.viewLim.ignore(-1) + return result + + @staticmethod + def default_units(value, axis): + # docstring inherited + # The default behavior for string indexing. + return "indexed" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDbl.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDbl.py new file mode 100644 index 00000000..5226c06a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDbl.py @@ -0,0 +1,180 @@ +"""UnitDbl module.""" + +import functools +import operator + +from matplotlib import _api + + +class UnitDbl: + """Class UnitDbl in development.""" + + # Unit conversion table. Small subset of the full one but enough + # to test the required functions. First field is a scale factor to + # convert the input units to the units of the second field. Only + # units in this table are allowed. + allowed = { + "m": (0.001, "km"), + "km": (1, "km"), + "mile": (1.609344, "km"), + + "rad": (1, "rad"), + "deg": (1.745329251994330e-02, "rad"), + + "sec": (1, "sec"), + "min": (60.0, "sec"), + "hour": (3600, "sec"), + } + + _types = { + "km": "distance", + "rad": "angle", + "sec": "time", + } + + def __init__(self, value, units): + """ + Create a new UnitDbl object. + + Units are internally converted to km, rad, and sec. The only + valid inputs for units are [m, km, mile, rad, deg, sec, min, hour]. + + The field UnitDbl.value will contain the converted value. Use + the convert() method to get a specific type of units back. + + = ERROR CONDITIONS + - If the input units are not in the allowed list, an error is thrown. + + = INPUT VARIABLES + - value The numeric value of the UnitDbl. + - units The string name of the units the value is in. + """ + data = _api.check_getitem(self.allowed, units=units) + self._value = float(value * data[0]) + self._units = data[1] + + def convert(self, units): + """ + Convert the UnitDbl to a specific set of units. + + = ERROR CONDITIONS + - If the input units are not in the allowed list, an error is thrown. + + = INPUT VARIABLES + - units The string name of the units to convert to. + + = RETURN VALUE + - Returns the value of the UnitDbl in the requested units as a floating + point number. + """ + if self._units == units: + return self._value + data = _api.check_getitem(self.allowed, units=units) + if self._units != data[1]: + raise ValueError(f"Error trying to convert to different units.\n" + f" Invalid conversion requested.\n" + f" UnitDbl: {self}\n" + f" Units: {units}\n") + return self._value / data[0] + + def __abs__(self): + """Return the absolute value of this UnitDbl.""" + return UnitDbl(abs(self._value), self._units) + + def __neg__(self): + """Return the negative value of this UnitDbl.""" + return UnitDbl(-self._value, self._units) + + def __bool__(self): + """Return the truth value of a UnitDbl.""" + return bool(self._value) + + def _cmp(self, op, rhs): + """Check that *self* and *rhs* share units; compare them using *op*.""" + self.checkSameUnits(rhs, "compare") + return op(self._value, rhs._value) + + __eq__ = functools.partialmethod(_cmp, operator.eq) + __ne__ = functools.partialmethod(_cmp, operator.ne) + __lt__ = functools.partialmethod(_cmp, operator.lt) + __le__ = functools.partialmethod(_cmp, operator.le) + __gt__ = functools.partialmethod(_cmp, operator.gt) + __ge__ = functools.partialmethod(_cmp, operator.ge) + + def _binop_unit_unit(self, op, rhs): + """Check that *self* and *rhs* share units; combine them using *op*.""" + self.checkSameUnits(rhs, op.__name__) + return UnitDbl(op(self._value, rhs._value), self._units) + + __add__ = functools.partialmethod(_binop_unit_unit, operator.add) + __sub__ = functools.partialmethod(_binop_unit_unit, operator.sub) + + def _binop_unit_scalar(self, op, scalar): + """Combine *self* and *scalar* using *op*.""" + return UnitDbl(op(self._value, scalar), self._units) + + __mul__ = functools.partialmethod(_binop_unit_scalar, operator.mul) + __rmul__ = functools.partialmethod(_binop_unit_scalar, operator.mul) + + def __str__(self): + """Print the UnitDbl.""" + return f"{self._value:g} *{self._units}" + + def __repr__(self): + """Print the UnitDbl.""" + return f"UnitDbl({self._value:g}, '{self._units}')" + + def type(self): + """Return the type of UnitDbl data.""" + return self._types[self._units] + + @staticmethod + def range(start, stop, step=None): + """ + Generate a range of UnitDbl objects. + + Similar to the Python range() method. Returns the range [ + start, stop) at the requested step. Each element will be a + UnitDbl object. + + = INPUT VARIABLES + - start The starting value of the range. + - stop The stop value of the range. + - step Optional step to use. If set to None, then a UnitDbl of + value 1 w/ the units of the start is used. + + = RETURN VALUE + - Returns a list containing the requested UnitDbl values. + """ + if step is None: + step = UnitDbl(1, start._units) + + elems = [] + + i = 0 + while True: + d = start + i * step + if d >= stop: + break + + elems.append(d) + i += 1 + + return elems + + def checkSameUnits(self, rhs, func): + """ + Check to see if units are the same. + + = ERROR CONDITIONS + - If the units of the rhs UnitDbl are not the same as our units, + an error is thrown. + + = INPUT VARIABLES + - rhs The UnitDbl to check for the same units + - func The name of the function doing the check. + """ + if self._units != rhs._units: + raise ValueError(f"Cannot {func} units of different types.\n" + f"LHS: {self._units}\n" + f"RHS: {rhs._units}") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblConverter.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblConverter.py new file mode 100644 index 00000000..23065379 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblConverter.py @@ -0,0 +1,85 @@ +"""UnitDblConverter module containing class UnitDblConverter.""" + +import numpy as np + +from matplotlib import cbook, units +import matplotlib.projections.polar as polar + +__all__ = ['UnitDblConverter'] + + +# A special function for use with the matplotlib FuncFormatter class +# for formatting axes with radian units. +# This was copied from matplotlib example code. +def rad_fn(x, pos=None): + """Radian function formatter.""" + n = int((x / np.pi) * 2.0 + 0.25) + if n == 0: + return str(x) + elif n == 1: + return r'$\pi/2$' + elif n == 2: + return r'$\pi$' + elif n % 2 == 0: + return fr'${n//2}\pi$' + else: + return fr'${n}\pi/2$' + + +class UnitDblConverter(units.ConversionInterface): + """ + Provides Matplotlib conversion functionality for the Monte UnitDbl class. + """ + # default for plotting + defaults = { + "distance": 'km', + "angle": 'deg', + "time": 'sec', + } + + @staticmethod + def axisinfo(unit, axis): + # docstring inherited + + # Delay-load due to circular dependencies. + import matplotlib.testing.jpl_units as U + + # Check to see if the value used for units is a string unit value + # or an actual instance of a UnitDbl so that we can use the unit + # value for the default axis label value. + if unit: + label = unit if isinstance(unit, str) else unit.label() + else: + label = None + + if label == "deg" and isinstance(axis.axes, polar.PolarAxes): + # If we want degrees for a polar plot, use the PolarPlotFormatter + majfmt = polar.PolarAxes.ThetaFormatter() + else: + majfmt = U.UnitDblFormatter(useOffset=False) + + return units.AxisInfo(majfmt=majfmt, label=label) + + @staticmethod + def convert(value, unit, axis): + # docstring inherited + if not cbook.is_scalar_or_string(value): + return [UnitDblConverter.convert(x, unit, axis) for x in value] + # If no units were specified, then get the default units to use. + if unit is None: + unit = UnitDblConverter.default_units(value, axis) + # Convert the incoming UnitDbl value/values to float/floats + if isinstance(axis.axes, polar.PolarAxes) and value.type() == "angle": + # Guarantee that units are radians for polar plots. + return value.convert("rad") + return value.convert(unit) + + @staticmethod + def default_units(value, axis): + # docstring inherited + # Determine the default units based on the user preferences set for + # default units when printing a UnitDbl. + if cbook.is_scalar_or_string(value): + return UnitDblConverter.defaults[value.type()] + else: + return UnitDblConverter.default_units(value[0], axis) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblFormatter.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblFormatter.py new file mode 100644 index 00000000..30a99140 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/UnitDblFormatter.py @@ -0,0 +1,28 @@ +"""UnitDblFormatter module containing class UnitDblFormatter.""" + +import matplotlib.ticker as ticker + +__all__ = ['UnitDblFormatter'] + + +class UnitDblFormatter(ticker.ScalarFormatter): + """ + The formatter for UnitDbl data types. + + This allows for formatting with the unit string. + """ + + def __call__(self, x, pos=None): + # docstring inherited + if len(self.locs) == 0: + return '' + else: + return f'{x:.12}' + + def format_data_short(self, value): + # docstring inherited + return f'{value:.12}' + + def format_data(self, value): + # docstring inherited + return f'{value:.12}' diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/__init__.py new file mode 100644 index 00000000..b8caa9a8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/jpl_units/__init__.py @@ -0,0 +1,76 @@ +""" +A sample set of units for use with testing unit conversion +of Matplotlib routines. These are used because they use very strict +enforcement of unitized data which will test the entire spectrum of how +unitized data might be used (it is not always meaningful to convert to +a float without specific units given). + +UnitDbl is essentially a unitized floating point number. It has a +minimal set of supported units (enough for testing purposes). All +of the mathematical operation are provided to fully test any behaviour +that might occur with unitized data. Remember that unitized data has +rules as to how it can be applied to one another (a value of distance +cannot be added to a value of time). Thus we need to guard against any +accidental "default" conversion that will strip away the meaning of the +data and render it neutered. + +Epoch is different than a UnitDbl of time. Time is something that can be +measured where an Epoch is a specific moment in time. Epochs are typically +referenced as an offset from some predetermined epoch. + +A difference of two epochs is a Duration. The distinction between a Duration +and a UnitDbl of time is made because an Epoch can have different frames (or +units). In the case of our test Epoch class the two allowed frames are 'UTC' +and 'ET' (Note that these are rough estimates provided for testing purposes +and should not be used in production code where accuracy of time frames is +desired). As such a Duration also has a frame of reference and therefore needs +to be called out as different that a simple measurement of time since a delta-t +in one frame may not be the same in another. +""" + +from .Duration import Duration +from .Epoch import Epoch +from .UnitDbl import UnitDbl + +from .StrConverter import StrConverter +from .EpochConverter import EpochConverter +from .UnitDblConverter import UnitDblConverter + +from .UnitDblFormatter import UnitDblFormatter + + +__version__ = "1.0" + +__all__ = [ + 'register', + 'Duration', + 'Epoch', + 'UnitDbl', + 'UnitDblFormatter', + ] + + +def register(): + """Register the unit conversion classes with matplotlib.""" + import matplotlib.units as mplU + + mplU.registry[str] = StrConverter() + mplU.registry[Epoch] = EpochConverter() + mplU.registry[Duration] = EpochConverter() + mplU.registry[UnitDbl] = UnitDblConverter() + + +# Some default unit instances +# Distances +m = UnitDbl(1.0, "m") +km = UnitDbl(1.0, "km") +mile = UnitDbl(1.0, "mile") +# Angles +deg = UnitDbl(1.0, "deg") +rad = UnitDbl(1.0, "rad") +# Time +sec = UnitDbl(1.0, "sec") +min = UnitDbl(1.0, "min") +hr = UnitDbl(1.0, "hour") +day = UnitDbl(24.0, "hour") +sec = UnitDbl(1.0, "sec") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.py new file mode 100644 index 00000000..eb755185 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.py @@ -0,0 +1,119 @@ +""" +======================== +Widget testing utilities +======================== + +See also :mod:`matplotlib.tests.test_widgets`. +""" + +from unittest import mock + +import matplotlib.pyplot as plt + + +def get_ax(): + """Create a plot and return its axes.""" + fig, ax = plt.subplots(1, 1) + ax.plot([0, 200], [0, 200]) + ax.set_aspect(1.0) + ax.figure.canvas.draw() + return ax + + +def noop(*args, **kwargs): + pass + + +def mock_event(ax, button=1, xdata=0, ydata=0, key=None, step=1): + r""" + Create a mock event that can stand in for `.Event` and its subclasses. + + This event is intended to be used in tests where it can be passed into + event handling functions. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The axes the event will be in. + xdata : float + x coord of mouse in data coords. + ydata : float + y coord of mouse in data coords. + button : None or `MouseButton` or {'up', 'down'} + The mouse button pressed in this event (see also `.MouseEvent`). + key : None or str + The key pressed when the mouse event triggered (see also `.KeyEvent`). + step : int + Number of scroll steps (positive for 'up', negative for 'down'). + + Returns + ------- + event + A `.Event`\-like Mock instance. + """ + event = mock.Mock() + event.button = button + event.x, event.y = ax.transData.transform([(xdata, ydata), + (xdata, ydata)])[0] + event.xdata, event.ydata = xdata, ydata + event.inaxes = ax + event.canvas = ax.figure.canvas + event.key = key + event.step = step + event.guiEvent = None + event.name = 'Custom' + return event + + +def do_event(tool, etype, button=1, xdata=0, ydata=0, key=None, step=1): + """ + Trigger an event on the given tool. + + Parameters + ---------- + tool : matplotlib.widgets.AxesWidget + etype : str + The event to trigger. + xdata : float + x coord of mouse in data coords. + ydata : float + y coord of mouse in data coords. + button : None or `MouseButton` or {'up', 'down'} + The mouse button pressed in this event (see also `.MouseEvent`). + key : None or str + The key pressed when the mouse event triggered (see also `.KeyEvent`). + step : int + Number of scroll steps (positive for 'up', negative for 'down'). + """ + event = mock_event(tool.ax, button, xdata, ydata, key, step) + func = getattr(tool, etype) + func(event) + + +def click_and_drag(tool, start, end, key=None): + """ + Helper to simulate a mouse drag operation. + + Parameters + ---------- + tool : `~matplotlib.widgets.Widget` + start : [float, float] + Starting point in data coordinates. + end : [float, float] + End point in data coordinates. + key : None or str + An optional key that is pressed during the whole operation + (see also `.KeyEvent`). + """ + if key is not None: + # Press key + do_event(tool, 'on_key_press', xdata=start[0], ydata=start[1], + button=1, key=key) + # Click, move, and release mouse + do_event(tool, 'press', xdata=start[0], ydata=start[1], button=1) + do_event(tool, 'onmove', xdata=end[0], ydata=end[1], button=1) + do_event(tool, 'release', xdata=end[0], ydata=end[1], button=1) + if key is not None: + # Release key + do_event(tool, 'on_key_release', xdata=end[0], ydata=end[1], + button=1, key=key) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.pyi new file mode 100644 index 00000000..858ff457 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/testing/widgets.pyi @@ -0,0 +1,31 @@ +from typing import Any, Literal + +from matplotlib.axes import Axes +from matplotlib.backend_bases import Event, MouseButton +from matplotlib.widgets import AxesWidget, Widget + +def get_ax() -> Axes: ... +def noop(*args: Any, **kwargs: Any) -> None: ... +def mock_event( + ax: Axes, + button: MouseButton | int | Literal["up", "down"] | None = ..., + xdata: float = ..., + ydata: float = ..., + key: str | None = ..., + step: int = ..., +) -> Event: ... +def do_event( + tool: AxesWidget, + etype: str, + button: MouseButton | int | Literal["up", "down"] | None = ..., + xdata: float = ..., + ydata: float = ..., + key: str | None = ..., + step: int = ..., +) -> None: ... +def click_and_drag( + tool: Widget, + start: tuple[float, float], + end: tuple[float, float], + key: str | None = ..., +) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/__init__.py new file mode 100644 index 00000000..8cce4fe4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/__init__.py @@ -0,0 +1,10 @@ +from pathlib import Path + + +# Check that the test directories exist. +if not (Path(__file__).parent / 'baseline_images').exists(): + raise OSError( + 'The baseline image directory does not exist. ' + 'This is most likely because the test data is not installed. ' + 'You may need to install matplotlib from source to get the ' + 'test data.') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/conftest.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/conftest.py new file mode 100644 index 00000000..54a1bc6c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/conftest.py @@ -0,0 +1,2 @@ +from matplotlib.testing.conftest import ( # noqa + mpl_test_settings, pytest_configure, pytest_unconfigure, pd, xr) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_afm.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_afm.py new file mode 100644 index 00000000..e5c6a839 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_afm.py @@ -0,0 +1,137 @@ +from io import BytesIO +import pytest +import logging + +from matplotlib import _afm +from matplotlib import font_manager as fm + + +# See note in afm.py re: use of comma as decimal separator in the +# UnderlineThickness field and re: use of non-ASCII characters in the Notice +# field. +AFM_TEST_DATA = b"""StartFontMetrics 2.0 +Comment Comments are ignored. +Comment Creation Date:Mon Nov 13 12:34:11 GMT 2017 +FontName MyFont-Bold +EncodingScheme FontSpecific +FullName My Font Bold +FamilyName Test Fonts +Weight Bold +ItalicAngle 0.0 +IsFixedPitch false +UnderlinePosition -100 +UnderlineThickness 56,789 +Version 001.000 +Notice Copyright \xa9 2017 No one. +FontBBox 0 -321 1234 369 +StartCharMetrics 3 +C 0 ; WX 250 ; N space ; B 0 0 0 0 ; +C 42 ; WX 1141 ; N foo ; B 40 60 800 360 ; +C 99 ; WX 583 ; N bar ; B 40 -10 543 210 ; +EndCharMetrics +EndFontMetrics +""" + + +def test_nonascii_str(): + # This tests that we also decode bytes as utf-8 properly. + # Else, font files with non ascii characters fail to load. + inp_str = "привет" + byte_str = inp_str.encode("utf8") + + ret = _afm._to_str(byte_str) + assert ret == inp_str + + +def test_parse_header(): + fh = BytesIO(AFM_TEST_DATA) + header = _afm._parse_header(fh) + assert header == { + b'StartFontMetrics': 2.0, + b'FontName': 'MyFont-Bold', + b'EncodingScheme': 'FontSpecific', + b'FullName': 'My Font Bold', + b'FamilyName': 'Test Fonts', + b'Weight': 'Bold', + b'ItalicAngle': 0.0, + b'IsFixedPitch': False, + b'UnderlinePosition': -100, + b'UnderlineThickness': 56.789, + b'Version': '001.000', + b'Notice': b'Copyright \xa9 2017 No one.', + b'FontBBox': [0, -321, 1234, 369], + b'StartCharMetrics': 3, + } + + +def test_parse_char_metrics(): + fh = BytesIO(AFM_TEST_DATA) + _afm._parse_header(fh) # position + metrics = _afm._parse_char_metrics(fh) + assert metrics == ( + {0: (250.0, 'space', [0, 0, 0, 0]), + 42: (1141.0, 'foo', [40, 60, 800, 360]), + 99: (583.0, 'bar', [40, -10, 543, 210]), + }, + {'space': (250.0, 'space', [0, 0, 0, 0]), + 'foo': (1141.0, 'foo', [40, 60, 800, 360]), + 'bar': (583.0, 'bar', [40, -10, 543, 210]), + }) + + +def test_get_familyname_guessed(): + fh = BytesIO(AFM_TEST_DATA) + font = _afm.AFM(fh) + del font._header[b'FamilyName'] # remove FamilyName, so we have to guess + assert font.get_familyname() == 'My Font' + + +def test_font_manager_weight_normalization(): + font = _afm.AFM(BytesIO( + AFM_TEST_DATA.replace(b"Weight Bold\n", b"Weight Custom\n"))) + assert fm.afmFontProperty("", font).weight == "normal" + + +@pytest.mark.parametrize( + "afm_data", + [ + b"""nope +really nope""", + b"""StartFontMetrics 2.0 +Comment Comments are ignored. +Comment Creation Date:Mon Nov 13 12:34:11 GMT 2017 +FontName MyFont-Bold +EncodingScheme FontSpecific""", + ], +) +def test_bad_afm(afm_data): + fh = BytesIO(afm_data) + with pytest.raises(RuntimeError): + _afm._parse_header(fh) + + +@pytest.mark.parametrize( + "afm_data", + [ + b"""StartFontMetrics 2.0 +Comment Comments are ignored. +Comment Creation Date:Mon Nov 13 12:34:11 GMT 2017 +Aardvark bob +FontName MyFont-Bold +EncodingScheme FontSpecific +StartCharMetrics 3""", + b"""StartFontMetrics 2.0 +Comment Comments are ignored. +Comment Creation Date:Mon Nov 13 12:34:11 GMT 2017 +ItalicAngle zero degrees +FontName MyFont-Bold +EncodingScheme FontSpecific +StartCharMetrics 3""", + ], +) +def test_malformed_header(afm_data, caplog): + fh = BytesIO(afm_data) + with caplog.at_level(logging.ERROR): + _afm._parse_header(fh) + + assert len(caplog.records) == 1 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg.py new file mode 100644 index 00000000..6ca74ed4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg.py @@ -0,0 +1,338 @@ +import io + +import numpy as np +from numpy.testing import assert_array_almost_equal +from PIL import Image, TiffTags +import pytest + + +from matplotlib import ( + collections, patheffects, pyplot as plt, transforms as mtransforms, + rcParams, rc_context) +from matplotlib.backends.backend_agg import RendererAgg +from matplotlib.figure import Figure +from matplotlib.image import imread +from matplotlib.path import Path +from matplotlib.testing.decorators import image_comparison +from matplotlib.transforms import IdentityTransform + + +def test_repeated_save_with_alpha(): + # We want an image which has a background color of bluish green, with an + # alpha of 0.25. + + fig = Figure([1, 0.4]) + fig.set_facecolor((0, 1, 0.4)) + fig.patch.set_alpha(0.25) + + # The target color is fig.patch.get_facecolor() + + buf = io.BytesIO() + + fig.savefig(buf, + facecolor=fig.get_facecolor(), + edgecolor='none') + + # Save the figure again to check that the + # colors don't bleed from the previous renderer. + buf.seek(0) + fig.savefig(buf, + facecolor=fig.get_facecolor(), + edgecolor='none') + + # Check the first pixel has the desired color & alpha + # (approx: 0, 1.0, 0.4, 0.25) + buf.seek(0) + assert_array_almost_equal(tuple(imread(buf)[0, 0]), + (0.0, 1.0, 0.4, 0.250), + decimal=3) + + +def test_large_single_path_collection(): + buff = io.BytesIO() + + # Generates a too-large single path in a path collection that + # would cause a segfault if the draw_markers optimization is + # applied. + f, ax = plt.subplots() + collection = collections.PathCollection( + [Path([[-10, 5], [10, 5], [10, -5], [-10, -5], [-10, 5]])]) + ax.add_artist(collection) + ax.set_xlim(10**-3, 1) + plt.savefig(buff) + + +def test_marker_with_nan(): + # This creates a marker with nans in it, which was segfaulting the + # Agg backend (see #3722) + fig, ax = plt.subplots(1) + steps = 1000 + data = np.arange(steps) + ax.semilogx(data) + ax.fill_between(data, data*0.8, data*1.2) + buf = io.BytesIO() + fig.savefig(buf, format='png') + + +def test_long_path(): + buff = io.BytesIO() + fig = Figure() + ax = fig.subplots() + points = np.ones(100_000) + points[::2] *= -1 + ax.plot(points) + fig.savefig(buff, format='png') + + +@image_comparison(['agg_filter.png'], remove_text=True) +def test_agg_filter(): + def smooth1d(x, window_len): + # copied from https://scipy-cookbook.readthedocs.io/ + s = np.r_[ + 2*x[0] - x[window_len:1:-1], x, 2*x[-1] - x[-1:-window_len:-1]] + w = np.hanning(window_len) + y = np.convolve(w/w.sum(), s, mode='same') + return y[window_len-1:-window_len+1] + + def smooth2d(A, sigma=3): + window_len = max(int(sigma), 3) * 2 + 1 + A = np.apply_along_axis(smooth1d, 0, A, window_len) + A = np.apply_along_axis(smooth1d, 1, A, window_len) + return A + + class BaseFilter: + + def get_pad(self, dpi): + return 0 + + def process_image(self, padded_src, dpi): + raise NotImplementedError("Should be overridden by subclasses") + + def __call__(self, im, dpi): + pad = self.get_pad(dpi) + padded_src = np.pad(im, [(pad, pad), (pad, pad), (0, 0)], + "constant") + tgt_image = self.process_image(padded_src, dpi) + return tgt_image, -pad, -pad + + class OffsetFilter(BaseFilter): + + def __init__(self, offsets=(0, 0)): + self.offsets = offsets + + def get_pad(self, dpi): + return int(max(self.offsets) / 72 * dpi) + + def process_image(self, padded_src, dpi): + ox, oy = self.offsets + a1 = np.roll(padded_src, int(ox / 72 * dpi), axis=1) + a2 = np.roll(a1, -int(oy / 72 * dpi), axis=0) + return a2 + + class GaussianFilter(BaseFilter): + """Simple Gaussian filter.""" + + def __init__(self, sigma, alpha=0.5, color=(0, 0, 0)): + self.sigma = sigma + self.alpha = alpha + self.color = color + + def get_pad(self, dpi): + return int(self.sigma*3 / 72 * dpi) + + def process_image(self, padded_src, dpi): + tgt_image = np.empty_like(padded_src) + tgt_image[:, :, :3] = self.color + tgt_image[:, :, 3] = smooth2d(padded_src[:, :, 3] * self.alpha, + self.sigma / 72 * dpi) + return tgt_image + + class DropShadowFilter(BaseFilter): + + def __init__(self, sigma, alpha=0.3, color=(0, 0, 0), offsets=(0, 0)): + self.gauss_filter = GaussianFilter(sigma, alpha, color) + self.offset_filter = OffsetFilter(offsets) + + def get_pad(self, dpi): + return max(self.gauss_filter.get_pad(dpi), + self.offset_filter.get_pad(dpi)) + + def process_image(self, padded_src, dpi): + t1 = self.gauss_filter.process_image(padded_src, dpi) + t2 = self.offset_filter.process_image(t1, dpi) + return t2 + + fig, ax = plt.subplots() + + # draw lines + line1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-", + mec="b", mfc="w", lw=5, mew=3, ms=10, label="Line 1") + line2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "ro-", + mec="r", mfc="w", lw=5, mew=3, ms=10, label="Line 1") + + gauss = DropShadowFilter(4) + + for line in [line1, line2]: + + # draw shadows with same lines with slight offset. + xx = line.get_xdata() + yy = line.get_ydata() + shadow, = ax.plot(xx, yy) + shadow.update_from(line) + + # offset transform + transform = mtransforms.offset_copy(line.get_transform(), ax.figure, + x=4.0, y=-6.0, units='points') + shadow.set_transform(transform) + + # adjust zorder of the shadow lines so that it is drawn below the + # original lines + shadow.set_zorder(line.get_zorder() - 0.5) + shadow.set_agg_filter(gauss) + shadow.set_rasterized(True) # to support mixed-mode renderers + + ax.set_xlim(0., 1.) + ax.set_ylim(0., 1.) + + ax.xaxis.set_visible(False) + ax.yaxis.set_visible(False) + + +def test_too_large_image(): + fig = plt.figure(figsize=(300, 1000)) + buff = io.BytesIO() + with pytest.raises(ValueError): + fig.savefig(buff) + + +def test_chunksize(): + x = range(200) + + # Test without chunksize + fig, ax = plt.subplots() + ax.plot(x, np.sin(x)) + fig.canvas.draw() + + # Test with chunksize + fig, ax = plt.subplots() + rcParams['agg.path.chunksize'] = 105 + ax.plot(x, np.sin(x)) + fig.canvas.draw() + + +@pytest.mark.backend('Agg') +def test_jpeg_dpi(): + # Check that dpi is set correctly in jpg files. + plt.plot([0, 1, 2], [0, 1, 0]) + buf = io.BytesIO() + plt.savefig(buf, format="jpg", dpi=200) + im = Image.open(buf) + assert im.info['dpi'] == (200, 200) + + +def test_pil_kwargs_png(): + from PIL.PngImagePlugin import PngInfo + buf = io.BytesIO() + pnginfo = PngInfo() + pnginfo.add_text("Software", "test") + plt.figure().savefig(buf, format="png", pil_kwargs={"pnginfo": pnginfo}) + im = Image.open(buf) + assert im.info["Software"] == "test" + + +def test_pil_kwargs_tiff(): + buf = io.BytesIO() + pil_kwargs = {"description": "test image"} + plt.figure().savefig(buf, format="tiff", pil_kwargs=pil_kwargs) + im = Image.open(buf) + tags = {TiffTags.TAGS_V2[k].name: v for k, v in im.tag_v2.items()} + assert tags["ImageDescription"] == "test image" + + +def test_pil_kwargs_webp(): + plt.plot([0, 1, 2], [0, 1, 0]) + buf_small = io.BytesIO() + pil_kwargs_low = {"quality": 1} + plt.savefig(buf_small, format="webp", pil_kwargs=pil_kwargs_low) + assert len(pil_kwargs_low) == 1 + buf_large = io.BytesIO() + pil_kwargs_high = {"quality": 100} + plt.savefig(buf_large, format="webp", pil_kwargs=pil_kwargs_high) + assert len(pil_kwargs_high) == 1 + assert buf_large.getbuffer().nbytes > buf_small.getbuffer().nbytes + + +def test_webp_alpha(): + plt.plot([0, 1, 2], [0, 1, 0]) + buf = io.BytesIO() + plt.savefig(buf, format="webp", transparent=True) + im = Image.open(buf) + assert im.mode == "RGBA" + + +def test_draw_path_collection_error_handling(): + fig, ax = plt.subplots() + ax.scatter([1], [1]).set_paths(Path([(0, 1), (2, 3)])) + with pytest.raises(TypeError): + fig.canvas.draw() + + +def test_chunksize_fails(): + # NOTE: This test covers multiple independent test scenarios in a single + # function, because each scenario uses ~2GB of memory and we don't + # want parallel test executors to accidentally run multiple of these + # at the same time. + + N = 100_000 + dpi = 500 + w = 5*dpi + h = 6*dpi + + # make a Path that spans the whole w-h rectangle + x = np.linspace(0, w, N) + y = np.ones(N) * h + y[::2] = 0 + path = Path(np.vstack((x, y)).T) + # effectively disable path simplification (but leaving it "on") + path.simplify_threshold = 0 + + # setup the minimal GraphicsContext to draw a Path + ra = RendererAgg(w, h, dpi) + gc = ra.new_gc() + gc.set_linewidth(1) + gc.set_foreground('r') + + gc.set_hatch('/') + with pytest.raises(OverflowError, match='cannot split hatched path'): + ra.draw_path(gc, path, IdentityTransform()) + gc.set_hatch(None) + + with pytest.raises(OverflowError, match='cannot split filled path'): + ra.draw_path(gc, path, IdentityTransform(), (1, 0, 0)) + + # Set to zero to disable, currently defaults to 0, but let's be sure. + with rc_context({'agg.path.chunksize': 0}): + with pytest.raises(OverflowError, match='Please set'): + ra.draw_path(gc, path, IdentityTransform()) + + # Set big enough that we do not try to chunk. + with rc_context({'agg.path.chunksize': 1_000_000}): + with pytest.raises(OverflowError, match='Please reduce'): + ra.draw_path(gc, path, IdentityTransform()) + + # Small enough we will try to chunk, but big enough we will fail to render. + with rc_context({'agg.path.chunksize': 90_000}): + with pytest.raises(OverflowError, match='Please reduce'): + ra.draw_path(gc, path, IdentityTransform()) + + path.should_simplify = False + with pytest.raises(OverflowError, match="should_simplify is False"): + ra.draw_path(gc, path, IdentityTransform()) + + +def test_non_tuple_rgbaface(): + # This passes rgbaFace as a ndarray to draw_path. + fig = plt.figure() + fig.add_subplot(projection="3d").scatter( + [0, 1, 2], [0, 1, 2], path_effects=[patheffects.Stroke(linewidth=4)]) + fig.canvas.draw() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg_filter.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg_filter.py new file mode 100644 index 00000000..dc8cff68 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_agg_filter.py @@ -0,0 +1,33 @@ +import numpy as np + +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison + + +@image_comparison(baseline_images=['agg_filter_alpha'], + extensions=['png', 'pdf']) +def test_agg_filter_alpha(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + ax = plt.axes() + x, y = np.mgrid[0:7, 0:8] + data = x**2 - y**2 + mesh = ax.pcolormesh(data, cmap='Reds', zorder=5) + + def manual_alpha(im, dpi): + im[:, :, 3] *= 0.6 + print('CALLED') + return im, 0, 0 + + # Note: Doing alpha like this is not the same as setting alpha on + # the mesh itself. Currently meshes are drawn as independent patches, + # and we see fine borders around the blocks of color. See the SO + # question for an example: https://stackoverflow.com/q/20678817/ + mesh.set_agg_filter(manual_alpha) + + # Currently we must enable rasterization for this to have an effect in + # the PDF backend. + mesh.set_rasterized(True) + + ax.plot([0, 4, 7], [1, 3, 8]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_animation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_animation.py new file mode 100644 index 00000000..a4de96d7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_animation.py @@ -0,0 +1,553 @@ +import os +from pathlib import Path +import platform +import re +import shutil +import subprocess +import sys +import weakref + +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import pyplot as plt +from matplotlib import animation +from matplotlib.testing.decorators import check_figures_equal + + +@pytest.fixture() +def anim(request): + """Create a simple animation (with options).""" + fig, ax = plt.subplots() + line, = ax.plot([], []) + + ax.set_xlim(0, 10) + ax.set_ylim(-1, 1) + + def init(): + line.set_data([], []) + return line, + + def animate(i): + x = np.linspace(0, 10, 100) + y = np.sin(x + i) + line.set_data(x, y) + return line, + + # "klass" can be passed to determine the class returned by the fixture + kwargs = dict(getattr(request, 'param', {})) # make a copy + klass = kwargs.pop('klass', animation.FuncAnimation) + if 'frames' not in kwargs: + kwargs['frames'] = 5 + return klass(fig=fig, func=animate, init_func=init, **kwargs) + + +class NullMovieWriter(animation.AbstractMovieWriter): + """ + A minimal MovieWriter. It doesn't actually write anything. + It just saves the arguments that were given to the setup() and + grab_frame() methods as attributes, and counts how many times + grab_frame() is called. + + This class doesn't have an __init__ method with the appropriate + signature, and it doesn't define an isAvailable() method, so + it cannot be added to the 'writers' registry. + """ + + def setup(self, fig, outfile, dpi, *args): + self.fig = fig + self.outfile = outfile + self.dpi = dpi + self.args = args + self._count = 0 + + def grab_frame(self, **savefig_kwargs): + from matplotlib.animation import _validate_grabframe_kwargs + _validate_grabframe_kwargs(savefig_kwargs) + self.savefig_kwargs = savefig_kwargs + self._count += 1 + + def finish(self): + pass + + +def test_null_movie_writer(anim): + # Test running an animation with NullMovieWriter. + plt.rcParams["savefig.facecolor"] = "auto" + filename = "unused.null" + dpi = 50 + savefig_kwargs = dict(foo=0) + writer = NullMovieWriter() + + anim.save(filename, dpi=dpi, writer=writer, + savefig_kwargs=savefig_kwargs) + + assert writer.fig == plt.figure(1) # The figure used by anim fixture + assert writer.outfile == filename + assert writer.dpi == dpi + assert writer.args == () + # we enrich the savefig kwargs to ensure we composite transparent + # output to an opaque background + for k, v in savefig_kwargs.items(): + assert writer.savefig_kwargs[k] == v + assert writer._count == anim._save_count + + +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_animation_delete(anim): + if platform.python_implementation() == 'PyPy': + # Something in the test setup fixture lingers around into the test and + # breaks pytest.warns on PyPy. This garbage collection fixes it. + # https://foss.heptapod.net/pypy/pypy/-/issues/3536 + np.testing.break_cycles() + anim = animation.FuncAnimation(**anim) + with pytest.warns(Warning, match='Animation was deleted'): + del anim + np.testing.break_cycles() + + +def test_movie_writer_dpi_default(): + class DummyMovieWriter(animation.MovieWriter): + def _run(self): + pass + + # Test setting up movie writer with figure.dpi default. + fig = plt.figure() + + filename = "unused.null" + fps = 5 + codec = "unused" + bitrate = 1 + extra_args = ["unused"] + + writer = DummyMovieWriter(fps, codec, bitrate, extra_args) + writer.setup(fig, filename) + assert writer.dpi == fig.dpi + + +@animation.writers.register('null') +class RegisteredNullMovieWriter(NullMovieWriter): + + # To be able to add NullMovieWriter to the 'writers' registry, + # we must define an __init__ method with a specific signature, + # and we must define the class method isAvailable(). + # (These methods are not actually required to use an instance + # of this class as the 'writer' argument of Animation.save().) + + def __init__(self, fps=None, codec=None, bitrate=None, + extra_args=None, metadata=None): + pass + + @classmethod + def isAvailable(cls): + return True + + +WRITER_OUTPUT = [ + ('ffmpeg', 'movie.mp4'), + ('ffmpeg_file', 'movie.mp4'), + ('imagemagick', 'movie.gif'), + ('imagemagick_file', 'movie.gif'), + ('pillow', 'movie.gif'), + ('html', 'movie.html'), + ('null', 'movie.null') +] + + +def gen_writers(): + for writer, output in WRITER_OUTPUT: + if not animation.writers.is_available(writer): + mark = pytest.mark.skip( + f"writer '{writer}' not available on this system") + yield pytest.param(writer, None, output, marks=[mark]) + yield pytest.param(writer, None, Path(output), marks=[mark]) + continue + + writer_class = animation.writers[writer] + for frame_format in getattr(writer_class, 'supported_formats', [None]): + yield writer, frame_format, output + yield writer, frame_format, Path(output) + + +# Smoke test for saving animations. In the future, we should probably +# design more sophisticated tests which compare resulting frames a-la +# matplotlib.testing.image_comparison +@pytest.mark.parametrize('writer, frame_format, output', gen_writers()) +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_save_animation_smoketest(tmpdir, writer, frame_format, output, anim): + if frame_format is not None: + plt.rcParams["animation.frame_format"] = frame_format + anim = animation.FuncAnimation(**anim) + dpi = None + codec = None + if writer == 'ffmpeg': + # Issue #8253 + anim._fig.set_size_inches((10.85, 9.21)) + dpi = 100. + codec = 'h264' + + # Use temporary directory for the file-based writers, which produce a file + # per frame with known names. + with tmpdir.as_cwd(): + anim.save(output, fps=30, writer=writer, bitrate=500, dpi=dpi, + codec=codec) + + del anim + + +@pytest.mark.parametrize('writer, frame_format, output', gen_writers()) +def test_grabframe(tmpdir, writer, frame_format, output): + WriterClass = animation.writers[writer] + + if frame_format is not None: + plt.rcParams["animation.frame_format"] = frame_format + + fig, ax = plt.subplots() + + dpi = None + codec = None + if writer == 'ffmpeg': + # Issue #8253 + fig.set_size_inches((10.85, 9.21)) + dpi = 100. + codec = 'h264' + + test_writer = WriterClass() + # Use temporary directory for the file-based writers, which produce a file + # per frame with known names. + with tmpdir.as_cwd(): + with test_writer.saving(fig, output, dpi): + # smoke test it works + test_writer.grab_frame() + for k in {'dpi', 'bbox_inches', 'format'}: + with pytest.raises( + TypeError, + match=f"grab_frame got an unexpected keyword argument {k!r}" + ): + test_writer.grab_frame(**{k: object()}) + + +@pytest.mark.parametrize('writer', [ + pytest.param( + 'ffmpeg', marks=pytest.mark.skipif( + not animation.FFMpegWriter.isAvailable(), + reason='Requires FFMpeg')), + pytest.param( + 'imagemagick', marks=pytest.mark.skipif( + not animation.ImageMagickWriter.isAvailable(), + reason='Requires ImageMagick')), +]) +@pytest.mark.parametrize('html, want', [ + ('none', None), + ('html5', '<video width'), + ('jshtml', '<script ') +]) +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_animation_repr_html(writer, html, want, anim): + if platform.python_implementation() == 'PyPy': + # Something in the test setup fixture lingers around into the test and + # breaks pytest.warns on PyPy. This garbage collection fixes it. + # https://foss.heptapod.net/pypy/pypy/-/issues/3536 + np.testing.break_cycles() + if (writer == 'imagemagick' and html == 'html5' + # ImageMagick delegates to ffmpeg for this format. + and not animation.FFMpegWriter.isAvailable()): + pytest.skip('Requires FFMpeg') + # create here rather than in the fixture otherwise we get __del__ warnings + # about producing no output + anim = animation.FuncAnimation(**anim) + with plt.rc_context({'animation.writer': writer, + 'animation.html': html}): + html = anim._repr_html_() + if want is None: + assert html is None + with pytest.warns(UserWarning): + del anim # Animation was never run, so will warn on cleanup. + np.testing.break_cycles() + else: + assert want in html + + +@pytest.mark.parametrize( + 'anim', + [{'save_count': 10, 'frames': iter(range(5))}], + indirect=['anim'] +) +def test_no_length_frames(anim): + anim.save('unused.null', writer=NullMovieWriter()) + + +def test_movie_writer_registry(): + assert len(animation.writers._registered) > 0 + mpl.rcParams['animation.ffmpeg_path'] = "not_available_ever_xxxx" + assert not animation.writers.is_available("ffmpeg") + # something guaranteed to be available in path and exits immediately + bin = "true" if sys.platform != 'win32' else "where" + mpl.rcParams['animation.ffmpeg_path'] = bin + assert animation.writers.is_available("ffmpeg") + + +@pytest.mark.parametrize( + "method_name", + [pytest.param("to_html5_video", marks=pytest.mark.skipif( + not animation.writers.is_available(mpl.rcParams["animation.writer"]), + reason="animation writer not installed")), + "to_jshtml"]) +@pytest.mark.parametrize('anim', [dict(frames=1)], indirect=['anim']) +def test_embed_limit(method_name, caplog, tmpdir, anim): + caplog.set_level("WARNING") + with tmpdir.as_cwd(): + with mpl.rc_context({"animation.embed_limit": 1e-6}): # ~1 byte. + getattr(anim, method_name)() + assert len(caplog.records) == 1 + record, = caplog.records + assert (record.name == "matplotlib.animation" + and record.levelname == "WARNING") + + +@pytest.mark.parametrize( + "method_name", + [pytest.param("to_html5_video", marks=pytest.mark.skipif( + not animation.writers.is_available(mpl.rcParams["animation.writer"]), + reason="animation writer not installed")), + "to_jshtml"]) +@pytest.mark.parametrize('anim', [dict(frames=1)], indirect=['anim']) +def test_cleanup_temporaries(method_name, tmpdir, anim): + with tmpdir.as_cwd(): + getattr(anim, method_name)() + assert list(Path(str(tmpdir)).iterdir()) == [] + + +@pytest.mark.skipif(shutil.which("/bin/sh") is None, reason="requires a POSIX OS") +def test_failing_ffmpeg(tmpdir, monkeypatch, anim): + """ + Test that we correctly raise a CalledProcessError when ffmpeg fails. + + To do so, mock ffmpeg using a simple executable shell script that + succeeds when called with no arguments (so that it gets registered by + `isAvailable`), but fails otherwise, and add it to the $PATH. + """ + with tmpdir.as_cwd(): + monkeypatch.setenv("PATH", ".:" + os.environ["PATH"]) + exe_path = Path(str(tmpdir), "ffmpeg") + exe_path.write_bytes(b"#!/bin/sh\n[[ $@ -eq 0 ]]\n") + os.chmod(exe_path, 0o755) + with pytest.raises(subprocess.CalledProcessError): + anim.save("test.mpeg") + + +@pytest.mark.parametrize("cache_frame_data", [False, True]) +def test_funcanimation_cache_frame_data(cache_frame_data): + fig, ax = plt.subplots() + line, = ax.plot([], []) + + class Frame(dict): + # this subclassing enables to use weakref.ref() + pass + + def init(): + line.set_data([], []) + return line, + + def animate(frame): + line.set_data(frame['x'], frame['y']) + return line, + + frames_generated = [] + + def frames_generator(): + for _ in range(5): + x = np.linspace(0, 10, 100) + y = np.random.rand(100) + + frame = Frame(x=x, y=y) + + # collect weak references to frames + # to validate their references later + frames_generated.append(weakref.ref(frame)) + + yield frame + + MAX_FRAMES = 100 + anim = animation.FuncAnimation(fig, animate, init_func=init, + frames=frames_generator, + cache_frame_data=cache_frame_data, + save_count=MAX_FRAMES) + + writer = NullMovieWriter() + anim.save('unused.null', writer=writer) + assert len(frames_generated) == 5 + np.testing.break_cycles() + for f in frames_generated: + # If cache_frame_data is True, then the weakref should be alive; + # if cache_frame_data is False, then the weakref should be dead (None). + assert (f() is None) != cache_frame_data + + +@pytest.mark.parametrize('return_value', [ + # User forgot to return (returns None). + None, + # User returned a string. + 'string', + # User returned an int. + 1, + # User returns a sequence of other objects, e.g., string instead of Artist. + ('string', ), + # User forgot to return a sequence (handled in `animate` below.) + 'artist', +]) +def test_draw_frame(return_value): + # test _draw_frame method + + fig, ax = plt.subplots() + line, = ax.plot([]) + + def animate(i): + # general update func + line.set_data([0, 1], [0, i]) + if return_value == 'artist': + # *not* a sequence + return line + else: + return return_value + + with pytest.raises(RuntimeError): + animation.FuncAnimation( + fig, animate, blit=True, cache_frame_data=False + ) + + +def test_exhausted_animation(tmpdir): + fig, ax = plt.subplots() + + def update(frame): + return [] + + anim = animation.FuncAnimation( + fig, update, frames=iter(range(10)), repeat=False, + cache_frame_data=False + ) + + with tmpdir.as_cwd(): + anim.save("test.gif", writer='pillow') + + with pytest.warns(UserWarning, match="exhausted"): + anim._start() + + +def test_no_frame_warning(tmpdir): + fig, ax = plt.subplots() + + def update(frame): + return [] + + anim = animation.FuncAnimation( + fig, update, frames=[], repeat=False, + cache_frame_data=False + ) + + with pytest.warns(UserWarning, match="exhausted"): + anim._start() + + +@check_figures_equal(extensions=["png"]) +def test_animation_frame(tmpdir, fig_test, fig_ref): + # Test the expected image after iterating through a few frames + # we save the animation to get the iteration because we are not + # in an interactive framework. + ax = fig_test.add_subplot() + ax.set_xlim(0, 2 * np.pi) + ax.set_ylim(-1, 1) + x = np.linspace(0, 2 * np.pi, 100) + line, = ax.plot([], []) + + def init(): + line.set_data([], []) + return line, + + def animate(i): + line.set_data(x, np.sin(x + i / 100)) + return line, + + anim = animation.FuncAnimation( + fig_test, animate, init_func=init, frames=5, + blit=True, repeat=False) + with tmpdir.as_cwd(): + anim.save("test.gif") + + # Reference figure without animation + ax = fig_ref.add_subplot() + ax.set_xlim(0, 2 * np.pi) + ax.set_ylim(-1, 1) + + # 5th frame's data + ax.plot(x, np.sin(x + 4 / 100)) + + +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_save_count_override_warnings_has_length(anim): + + save_count = 5 + frames = list(range(2)) + match_target = ( + f'You passed in an explicit {save_count=} ' + "which is being ignored in favor of " + f"{len(frames)=}." + ) + + with pytest.warns(UserWarning, match=re.escape(match_target)): + anim = animation.FuncAnimation( + **{**anim, 'frames': frames, 'save_count': save_count} + ) + assert anim._save_count == len(frames) + anim._init_draw() + + +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_save_count_override_warnings_scaler(anim): + save_count = 5 + frames = 7 + match_target = ( + f'You passed in an explicit {save_count=} ' + + "which is being ignored in favor of " + + f"{frames=}." + ) + + with pytest.warns(UserWarning, match=re.escape(match_target)): + anim = animation.FuncAnimation( + **{**anim, 'frames': frames, 'save_count': save_count} + ) + + assert anim._save_count == frames + anim._init_draw() + + +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_disable_cache_warning(anim): + cache_frame_data = True + frames = iter(range(5)) + match_target = ( + f"{frames=!r} which we can infer the length of, " + "did not pass an explicit *save_count* " + f"and passed {cache_frame_data=}. To avoid a possibly " + "unbounded cache, frame data caching has been disabled. " + "To suppress this warning either pass " + "`cache_frame_data=False` or `save_count=MAX_FRAMES`." + ) + with pytest.warns(UserWarning, match=re.escape(match_target)): + anim = animation.FuncAnimation( + **{**anim, 'cache_frame_data': cache_frame_data, 'frames': frames} + ) + assert anim._cache_frame_data is False + anim._init_draw() + + +def test_movie_writer_invalid_path(anim): + if sys.platform == "win32": + match_str = re.escape("[WinError 3] The system cannot find the path specified:") + else: + match_str = re.escape("[Errno 2] No such file or directory: '/foo") + with pytest.raises(FileNotFoundError, match=match_str): + anim.save("/foo/bar/aardvark/thiscannotreallyexist.mp4", + writer=animation.FFMpegFileWriter()) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_api.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_api.py new file mode 100644 index 00000000..8b0f1e70 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_api.py @@ -0,0 +1,116 @@ +from __future__ import annotations + +import re +import typing +from typing import Any, Callable, TypeVar + +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import _api + + +if typing.TYPE_CHECKING: + from typing_extensions import Self + +T = TypeVar('T') + + +@pytest.mark.parametrize('target,shape_repr,test_shape', + [((None, ), "(N,)", (1, 3)), + ((None, 3), "(N, 3)", (1,)), + ((None, 3), "(N, 3)", (1, 2)), + ((1, 5), "(1, 5)", (1, 9)), + ((None, 2, None), "(M, 2, N)", (1, 3, 1)) + ]) +def test_check_shape(target: tuple[int | None, ...], + shape_repr: str, + test_shape: tuple[int, ...]) -> None: + error_pattern = "^" + re.escape( + f"'aardvark' must be {len(target)}D with shape {shape_repr}, but your input " + f"has shape {test_shape}") + data = np.zeros(test_shape) + with pytest.raises(ValueError, match=error_pattern): + _api.check_shape(target, aardvark=data) + + +def test_classproperty_deprecation() -> None: + class A: + @_api.deprecated("0.0.0") + @_api.classproperty + def f(cls: Self) -> None: + pass + with pytest.warns(mpl.MatplotlibDeprecationWarning): + A.f + with pytest.warns(mpl.MatplotlibDeprecationWarning): + a = A() + a.f + + +def test_deprecate_privatize_attribute() -> None: + class C: + def __init__(self) -> None: self._attr = 1 + def _meth(self, arg: T) -> T: return arg + attr: int = _api.deprecate_privatize_attribute("0.0") + meth: Callable = _api.deprecate_privatize_attribute("0.0") + + c = C() + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert c.attr == 1 + with pytest.warns(mpl.MatplotlibDeprecationWarning): + c.attr = 2 + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert c.attr == 2 + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert c.meth(42) == 42 + + +def test_delete_parameter() -> None: + @_api.delete_parameter("3.0", "foo") + def func1(foo: Any = None) -> None: + pass + + @_api.delete_parameter("3.0", "foo") + def func2(**kwargs: Any) -> None: + pass + + for func in [func1, func2]: # type: ignore[list-item] + func() # No warning. + with pytest.warns(mpl.MatplotlibDeprecationWarning): + func(foo="bar") + + def pyplot_wrapper(foo: Any = _api.deprecation._deprecated_parameter) -> None: + func1(foo) + + pyplot_wrapper() # No warning. + with pytest.warns(mpl.MatplotlibDeprecationWarning): + func(foo="bar") + + +def test_make_keyword_only() -> None: + @_api.make_keyword_only("3.0", "arg") + def func(pre: Any, arg: Any, post: Any = None) -> None: + pass + + func(1, arg=2) # Check that no warning is emitted. + + with pytest.warns(mpl.MatplotlibDeprecationWarning): + func(1, 2) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + func(1, 2, 3) + + +def test_deprecation_alternative() -> None: + alternative = "`.f1`, `f2`, `f3(x) <.f3>` or `f4(x)<f4>`" + @_api.deprecated("1", alternative=alternative) + def f() -> None: + pass + if f.__doc__ is None: + pytest.skip('Documentation is disabled') + assert alternative in f.__doc__ + + +def test_empty_check_in_list() -> None: + with pytest.raises(TypeError, match="No argument to check!"): + _api.check_in_list(["a"]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_arrow_patches.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_arrow_patches.py new file mode 100644 index 00000000..8d573b4a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_arrow_patches.py @@ -0,0 +1,177 @@ +import pytest +import platform +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison +import matplotlib.patches as mpatches + + +def draw_arrow(ax, t, r): + ax.annotate('', xy=(0.5, 0.5 + r), xytext=(0.5, 0.5), size=30, + arrowprops=dict(arrowstyle=t, + fc="b", ec='k')) + + +@image_comparison(['fancyarrow_test_image']) +def test_fancyarrow(): + # Added 0 to test division by zero error described in issue 3930 + r = [0.4, 0.3, 0.2, 0.1, 0] + t = ["fancy", "simple", mpatches.ArrowStyle.Fancy()] + + fig, axs = plt.subplots(len(t), len(r), squeeze=False, + figsize=(8, 4.5), subplot_kw=dict(aspect=1)) + + for i_r, r1 in enumerate(r): + for i_t, t1 in enumerate(t): + ax = axs[i_t, i_r] + draw_arrow(ax, t1, r1) + ax.tick_params(labelleft=False, labelbottom=False) + + +@image_comparison(['boxarrow_test_image.png']) +def test_boxarrow(): + + styles = mpatches.BoxStyle.get_styles() + + n = len(styles) + spacing = 1.2 + + figheight = (n * spacing + .5) + fig = plt.figure(figsize=(4 / 1.5, figheight / 1.5)) + + fontsize = 0.3 * 72 + + for i, stylename in enumerate(sorted(styles)): + fig.text(0.5, ((n - i) * spacing - 0.5)/figheight, stylename, + ha="center", + size=fontsize, + transform=fig.transFigure, + bbox=dict(boxstyle=stylename, fc="w", ec="k")) + + +def __prepare_fancyarrow_dpi_cor_test(): + """ + Convenience function that prepares and returns a FancyArrowPatch. It aims + at being used to test that the size of the arrow head does not depend on + the DPI value of the exported picture. + + NB: this function *is not* a test in itself! + """ + fig2 = plt.figure("fancyarrow_dpi_cor_test", figsize=(4, 3), dpi=50) + ax = fig2.add_subplot() + ax.set_xlim([0, 1]) + ax.set_ylim([0, 1]) + ax.add_patch(mpatches.FancyArrowPatch(posA=(0.3, 0.4), posB=(0.8, 0.6), + lw=3, arrowstyle='->', + mutation_scale=100)) + return fig2 + + +@image_comparison(['fancyarrow_dpi_cor_100dpi.png'], remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.02, + savefig_kwarg=dict(dpi=100)) +def test_fancyarrow_dpi_cor_100dpi(): + """ + Check the export of a FancyArrowPatch @ 100 DPI. FancyArrowPatch is + instantiated through a dedicated function because another similar test + checks a similar export but with a different DPI value. + + Remark: test only a rasterized format. + """ + + __prepare_fancyarrow_dpi_cor_test() + + +@image_comparison(['fancyarrow_dpi_cor_200dpi.png'], remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.02, + savefig_kwarg=dict(dpi=200)) +def test_fancyarrow_dpi_cor_200dpi(): + """ + As test_fancyarrow_dpi_cor_100dpi, but exports @ 200 DPI. The relative size + of the arrow head should be the same. + """ + + __prepare_fancyarrow_dpi_cor_test() + + +@image_comparison(['fancyarrow_dash.png'], remove_text=True, style='default') +def test_fancyarrow_dash(): + fig, ax = plt.subplots() + e = mpatches.FancyArrowPatch((0, 0), (0.5, 0.5), + arrowstyle='-|>', + connectionstyle='angle3,angleA=0,angleB=90', + mutation_scale=10.0, + linewidth=2, + linestyle='dashed', + color='k') + e2 = mpatches.FancyArrowPatch((0, 0), (0.5, 0.5), + arrowstyle='-|>', + connectionstyle='angle3', + mutation_scale=10.0, + linewidth=2, + linestyle='dotted', + color='k') + ax.add_patch(e) + ax.add_patch(e2) + + +@image_comparison(['arrow_styles.png'], style='mpl20', remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.005) +def test_arrow_styles(): + styles = mpatches.ArrowStyle.get_styles() + + n = len(styles) + fig, ax = plt.subplots(figsize=(8, 8)) + ax.set_xlim(0, 1) + ax.set_ylim(-1, n) + fig.subplots_adjust(left=0, right=1, bottom=0, top=1) + + for i, stylename in enumerate(sorted(styles)): + patch = mpatches.FancyArrowPatch((0.1 + (i % 2)*0.05, i), + (0.45 + (i % 2)*0.05, i), + arrowstyle=stylename, + mutation_scale=25) + ax.add_patch(patch) + + for i, stylename in enumerate([']-[', ']-', '-[', '|-|']): + style = stylename + if stylename[0] != '-': + style += ',angleA=ANGLE' + if stylename[-1] != '-': + style += ',angleB=ANGLE' + + for j, angle in enumerate([-30, 60]): + arrowstyle = style.replace('ANGLE', str(angle)) + patch = mpatches.FancyArrowPatch((0.55, 2*i + j), (0.9, 2*i + j), + arrowstyle=arrowstyle, + mutation_scale=25) + ax.add_patch(patch) + + +@image_comparison(['connection_styles.png'], style='mpl20', remove_text=True) +def test_connection_styles(): + styles = mpatches.ConnectionStyle.get_styles() + + n = len(styles) + fig, ax = plt.subplots(figsize=(6, 10)) + ax.set_xlim(0, 1) + ax.set_ylim(-1, n) + + for i, stylename in enumerate(sorted(styles)): + patch = mpatches.FancyArrowPatch((0.1, i), (0.8, i + 0.5), + arrowstyle="->", + connectionstyle=stylename, + mutation_scale=25) + ax.add_patch(patch) + + +def test_invalid_intersection(): + conn_style_1 = mpatches.ConnectionStyle.Angle3(angleA=20, angleB=200) + p1 = mpatches.FancyArrowPatch((.2, .2), (.5, .5), + connectionstyle=conn_style_1) + with pytest.raises(ValueError): + plt.gca().add_patch(p1) + + conn_style_2 = mpatches.ConnectionStyle.Angle3(angleA=20, angleB=199.9) + p2 = mpatches.FancyArrowPatch((.2, .2), (.5, .5), + connectionstyle=conn_style_2) + plt.gca().add_patch(p2) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_artist.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_artist.py new file mode 100644 index 00000000..dbb5dd23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_artist.py @@ -0,0 +1,564 @@ +import io +from itertools import chain + +import numpy as np + +import pytest + +import matplotlib.colors as mcolors +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import matplotlib.lines as mlines +import matplotlib.path as mpath +import matplotlib.transforms as mtransforms +import matplotlib.collections as mcollections +import matplotlib.artist as martist +import matplotlib.backend_bases as mbackend_bases +import matplotlib as mpl +from matplotlib.testing.decorators import check_figures_equal, image_comparison + + +def test_patch_transform_of_none(): + # tests the behaviour of patches added to an Axes with various transform + # specifications + + ax = plt.axes() + ax.set_xlim(1, 3) + ax.set_ylim(1, 3) + + # Draw an ellipse over data coord (2, 2) by specifying device coords. + xy_data = (2, 2) + xy_pix = ax.transData.transform(xy_data) + + # Not providing a transform of None puts the ellipse in data coordinates . + e = mpatches.Ellipse(xy_data, width=1, height=1, fc='yellow', alpha=0.5) + ax.add_patch(e) + assert e._transform == ax.transData + + # Providing a transform of None puts the ellipse in device coordinates. + e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', + transform=None, alpha=0.5) + assert e.is_transform_set() + ax.add_patch(e) + assert isinstance(e._transform, mtransforms.IdentityTransform) + + # Providing an IdentityTransform puts the ellipse in device coordinates. + e = mpatches.Ellipse(xy_pix, width=100, height=100, + transform=mtransforms.IdentityTransform(), alpha=0.5) + ax.add_patch(e) + assert isinstance(e._transform, mtransforms.IdentityTransform) + + # Not providing a transform, and then subsequently "get_transform" should + # not mean that "is_transform_set". + e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', + alpha=0.5) + intermediate_transform = e.get_transform() + assert not e.is_transform_set() + ax.add_patch(e) + assert e.get_transform() != intermediate_transform + assert e.is_transform_set() + assert e._transform == ax.transData + + +def test_collection_transform_of_none(): + # tests the behaviour of collections added to an Axes with various + # transform specifications + + ax = plt.axes() + ax.set_xlim(1, 3) + ax.set_ylim(1, 3) + + # draw an ellipse over data coord (2, 2) by specifying device coords + xy_data = (2, 2) + xy_pix = ax.transData.transform(xy_data) + + # not providing a transform of None puts the ellipse in data coordinates + e = mpatches.Ellipse(xy_data, width=1, height=1) + c = mcollections.PatchCollection([e], facecolor='yellow', alpha=0.5) + ax.add_collection(c) + # the collection should be in data coordinates + assert c.get_offset_transform() + c.get_transform() == ax.transData + + # providing a transform of None puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=120, height=120) + c = mcollections.PatchCollection([e], facecolor='coral', + alpha=0.5) + c.set_transform(None) + ax.add_collection(c) + assert isinstance(c.get_transform(), mtransforms.IdentityTransform) + + # providing an IdentityTransform puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=100, height=100) + c = mcollections.PatchCollection([e], + transform=mtransforms.IdentityTransform(), + alpha=0.5) + ax.add_collection(c) + assert isinstance(c.get_offset_transform(), mtransforms.IdentityTransform) + + +@image_comparison(["clip_path_clipping"], remove_text=True) +def test_clipping(): + exterior = mpath.Path.unit_rectangle().deepcopy() + exterior.vertices *= 4 + exterior.vertices -= 2 + interior = mpath.Path.unit_circle().deepcopy() + interior.vertices = interior.vertices[::-1] + clip_path = mpath.Path.make_compound_path(exterior, interior) + + star = mpath.Path.unit_regular_star(6).deepcopy() + star.vertices *= 2.6 + + fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True) + + col = mcollections.PathCollection([star], lw=5, edgecolor='blue', + facecolor='red', alpha=0.7, hatch='*') + col.set_clip_path(clip_path, ax1.transData) + ax1.add_collection(col) + + patch = mpatches.PathPatch(star, lw=5, edgecolor='blue', facecolor='red', + alpha=0.7, hatch='*') + patch.set_clip_path(clip_path, ax2.transData) + ax2.add_patch(patch) + + ax1.set_xlim([-3, 3]) + ax1.set_ylim([-3, 3]) + + +@check_figures_equal(extensions=['png']) +def test_clipping_zoom(fig_test, fig_ref): + # This test places the Axes and sets its limits such that the clip path is + # outside the figure entirely. This should not break the clip path. + ax_test = fig_test.add_axes([0, 0, 1, 1]) + l, = ax_test.plot([-3, 3], [-3, 3]) + # Explicit Path instead of a Rectangle uses clip path processing, instead + # of a clip box optimization. + p = mpath.Path([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) + p = mpatches.PathPatch(p, transform=ax_test.transData) + l.set_clip_path(p) + + ax_ref = fig_ref.add_axes([0, 0, 1, 1]) + ax_ref.plot([-3, 3], [-3, 3]) + + ax_ref.set(xlim=(0.5, 0.75), ylim=(0.5, 0.75)) + ax_test.set(xlim=(0.5, 0.75), ylim=(0.5, 0.75)) + + +def test_cull_markers(): + x = np.random.random(20000) + y = np.random.random(20000) + + fig, ax = plt.subplots() + ax.plot(x, y, 'k.') + ax.set_xlim(2, 3) + + pdf = io.BytesIO() + fig.savefig(pdf, format="pdf") + assert len(pdf.getvalue()) < 8000 + + svg = io.BytesIO() + fig.savefig(svg, format="svg") + assert len(svg.getvalue()) < 20000 + + +@image_comparison(['hatching'], remove_text=True, style='default') +def test_hatching(): + fig, ax = plt.subplots(1, 1) + + # Default hatch color. + rect1 = mpatches.Rectangle((0, 0), 3, 4, hatch='/') + ax.add_patch(rect1) + + rect2 = mcollections.RegularPolyCollection( + 4, sizes=[16000], offsets=[(1.5, 6.5)], offset_transform=ax.transData, + hatch='/') + ax.add_collection(rect2) + + # Ensure edge color is not applied to hatching. + rect3 = mpatches.Rectangle((4, 0), 3, 4, hatch='/', edgecolor='C1') + ax.add_patch(rect3) + + rect4 = mcollections.RegularPolyCollection( + 4, sizes=[16000], offsets=[(5.5, 6.5)], offset_transform=ax.transData, + hatch='/', edgecolor='C1') + ax.add_collection(rect4) + + ax.set_xlim(0, 7) + ax.set_ylim(0, 9) + + +def test_remove(): + fig, ax = plt.subplots() + im = ax.imshow(np.arange(36).reshape(6, 6)) + ln, = ax.plot(range(5)) + + assert fig.stale + assert ax.stale + + fig.canvas.draw() + assert not fig.stale + assert not ax.stale + assert not ln.stale + + assert im in ax._mouseover_set + assert ln not in ax._mouseover_set + assert im.axes is ax + + im.remove() + ln.remove() + + for art in [im, ln]: + assert art.axes is None + assert art.figure is None + + assert im not in ax._mouseover_set + assert fig.stale + assert ax.stale + + +@image_comparison(["default_edges.png"], remove_text=True, style='default') +def test_default_edges(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2) + + ax1.plot(np.arange(10), np.arange(10), 'x', + np.arange(10) + 1, np.arange(10), 'o') + ax2.bar(np.arange(10), np.arange(10), align='edge') + ax3.text(0, 0, "BOX", size=24, bbox=dict(boxstyle='sawtooth')) + ax3.set_xlim((-1, 1)) + ax3.set_ylim((-1, 1)) + pp1 = mpatches.PathPatch( + mpath.Path([(0, 0), (1, 0), (1, 1), (0, 0)], + [mpath.Path.MOVETO, mpath.Path.CURVE3, + mpath.Path.CURVE3, mpath.Path.CLOSEPOLY]), + fc="none", transform=ax4.transData) + ax4.add_patch(pp1) + + +def test_properties(): + ln = mlines.Line2D([], []) + ln.properties() # Check that no warning is emitted. + + +def test_setp(): + # Check empty list + plt.setp([]) + plt.setp([[]]) + + # Check arbitrary iterables + fig, ax = plt.subplots() + lines1 = ax.plot(range(3)) + lines2 = ax.plot(range(3)) + martist.setp(chain(lines1, lines2), 'lw', 5) + plt.setp(ax.spines.values(), color='green') + + # Check *file* argument + sio = io.StringIO() + plt.setp(lines1, 'zorder', file=sio) + assert sio.getvalue() == ' zorder: float\n' + + +def test_None_zorder(): + fig, ax = plt.subplots() + ln, = ax.plot(range(5), zorder=None) + assert ln.get_zorder() == mlines.Line2D.zorder + ln.set_zorder(123456) + assert ln.get_zorder() == 123456 + ln.set_zorder(None) + assert ln.get_zorder() == mlines.Line2D.zorder + + +@pytest.mark.parametrize('accept_clause, expected', [ + ('', 'unknown'), + ("ACCEPTS: [ '-' | '--' | '-.' ]", "[ '-' | '--' | '-.' ]"), + ('ACCEPTS: Some description.', 'Some description.'), + ('.. ACCEPTS: Some description.', 'Some description.'), + ('arg : int', 'int'), + ('*arg : int', 'int'), + ('arg : int\nACCEPTS: Something else.', 'Something else. '), +]) +def test_artist_inspector_get_valid_values(accept_clause, expected): + class TestArtist(martist.Artist): + def set_f(self, arg): + pass + + TestArtist.set_f.__doc__ = """ + Some text. + + %s + """ % accept_clause + valid_values = martist.ArtistInspector(TestArtist).get_valid_values('f') + assert valid_values == expected + + +def test_artist_inspector_get_aliases(): + # test the correct format and type of get_aliases method + ai = martist.ArtistInspector(mlines.Line2D) + aliases = ai.get_aliases() + assert aliases["linewidth"] == {"lw"} + + +def test_set_alpha(): + art = martist.Artist() + with pytest.raises(TypeError, match='^alpha must be numeric or None'): + art.set_alpha('string') + with pytest.raises(TypeError, match='^alpha must be numeric or None'): + art.set_alpha([1, 2, 3]) + with pytest.raises(ValueError, match="outside 0-1 range"): + art.set_alpha(1.1) + with pytest.raises(ValueError, match="outside 0-1 range"): + art.set_alpha(np.nan) + + +def test_set_alpha_for_array(): + art = martist.Artist() + with pytest.raises(TypeError, match='^alpha must be numeric or None'): + art._set_alpha_for_array('string') + with pytest.raises(ValueError, match="outside 0-1 range"): + art._set_alpha_for_array(1.1) + with pytest.raises(ValueError, match="outside 0-1 range"): + art._set_alpha_for_array(np.nan) + with pytest.raises(ValueError, match="alpha must be between 0 and 1"): + art._set_alpha_for_array([0.5, 1.1]) + with pytest.raises(ValueError, match="alpha must be between 0 and 1"): + art._set_alpha_for_array([0.5, np.nan]) + + +def test_callbacks(): + def func(artist): + func.counter += 1 + + func.counter = 0 + + art = martist.Artist() + oid = art.add_callback(func) + assert func.counter == 0 + art.pchanged() # must call the callback + assert func.counter == 1 + art.set_zorder(10) # setting a property must also call the callback + assert func.counter == 2 + art.remove_callback(oid) + art.pchanged() # must not call the callback anymore + assert func.counter == 2 + + +def test_set_signature(): + """Test autogenerated ``set()`` for Artist subclasses.""" + class MyArtist1(martist.Artist): + def set_myparam1(self, val): + pass + + assert hasattr(MyArtist1.set, '_autogenerated_signature') + assert 'myparam1' in MyArtist1.set.__doc__ + + class MyArtist2(MyArtist1): + def set_myparam2(self, val): + pass + + assert hasattr(MyArtist2.set, '_autogenerated_signature') + assert 'myparam1' in MyArtist2.set.__doc__ + assert 'myparam2' in MyArtist2.set.__doc__ + + +def test_set_is_overwritten(): + """set() defined in Artist subclasses should not be overwritten.""" + class MyArtist3(martist.Artist): + + def set(self, **kwargs): + """Not overwritten.""" + + assert not hasattr(MyArtist3.set, '_autogenerated_signature') + assert MyArtist3.set.__doc__ == "Not overwritten." + + class MyArtist4(MyArtist3): + pass + + assert MyArtist4.set is MyArtist3.set + + +def test_format_cursor_data_BoundaryNorm(): + """Test if cursor data is correct when using BoundaryNorm.""" + X = np.empty((3, 3)) + X[0, 0] = 0.9 + X[0, 1] = 0.99 + X[0, 2] = 0.999 + X[1, 0] = -1 + X[1, 1] = 0 + X[1, 2] = 1 + X[2, 0] = 0.09 + X[2, 1] = 0.009 + X[2, 2] = 0.0009 + + # map range -1..1 to 0..256 in 0.1 steps + fig, ax = plt.subplots() + fig.suptitle("-1..1 to 0..256 in 0.1") + norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 20), 256) + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + + labels_list = [ + "[0.9]", + "[1.]", + "[1.]", + "[-1.0]", + "[0.0]", + "[1.0]", + "[0.09]", + "[0.009]", + "[0.0009]", + ] + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.1)) + assert img.format_cursor_data(v) == label + + plt.close() + + # map range -1..1 to 0..256 in 0.01 steps + fig, ax = plt.subplots() + fig.suptitle("-1..1 to 0..256 in 0.01") + cmap = mpl.colormaps['RdBu_r'].resampled(200) + norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 200), 200) + img = ax.imshow(X, cmap=cmap, norm=norm) + + labels_list = [ + "[0.90]", + "[0.99]", + "[1.0]", + "[-1.00]", + "[0.00]", + "[1.00]", + "[0.09]", + "[0.009]", + "[0.0009]", + ] + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.01)) + assert img.format_cursor_data(v) == label + + plt.close() + + # map range -1..1 to 0..256 in 0.01 steps + fig, ax = plt.subplots() + fig.suptitle("-1..1 to 0..256 in 0.001") + cmap = mpl.colormaps['RdBu_r'].resampled(2000) + norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 2000), 2000) + img = ax.imshow(X, cmap=cmap, norm=norm) + + labels_list = [ + "[0.900]", + "[0.990]", + "[0.999]", + "[-1.000]", + "[0.000]", + "[1.000]", + "[0.090]", + "[0.009]", + "[0.0009]", + ] + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.001)) + assert img.format_cursor_data(v) == label + + plt.close() + + # different testing data set with + # out of bounds values for 0..1 range + X = np.empty((7, 1)) + X[0] = -1.0 + X[1] = 0.0 + X[2] = 0.1 + X[3] = 0.5 + X[4] = 0.9 + X[5] = 1.0 + X[6] = 2.0 + + labels_list = [ + "[-1.0]", + "[0.0]", + "[0.1]", + "[0.5]", + "[0.9]", + "[1.0]", + "[2.0]", + ] + + fig, ax = plt.subplots() + fig.suptitle("noclip, neither") + norm = mcolors.BoundaryNorm( + np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='neither') + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33)) + assert img.format_cursor_data(v) == label + + plt.close() + + fig, ax = plt.subplots() + fig.suptitle("noclip, min") + norm = mcolors.BoundaryNorm( + np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='min') + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33)) + assert img.format_cursor_data(v) == label + + plt.close() + + fig, ax = plt.subplots() + fig.suptitle("noclip, max") + norm = mcolors.BoundaryNorm( + np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='max') + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33)) + assert img.format_cursor_data(v) == label + + plt.close() + + fig, ax = plt.subplots() + fig.suptitle("noclip, both") + norm = mcolors.BoundaryNorm( + np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='both') + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33)) + assert img.format_cursor_data(v) == label + + plt.close() + + fig, ax = plt.subplots() + fig.suptitle("clip, neither") + norm = mcolors.BoundaryNorm( + np.linspace(0, 1, 4, endpoint=True), 256, clip=True, extend='neither') + img = ax.imshow(X, cmap='RdBu_r', norm=norm) + for v, label in zip(X.flat, labels_list): + # label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33)) + assert img.format_cursor_data(v) == label + + plt.close() + + +def test_auto_no_rasterize(): + class Gen1(martist.Artist): + ... + + assert 'draw' in Gen1.__dict__ + assert Gen1.__dict__['draw'] is Gen1.draw + + class Gen2(Gen1): + ... + + assert 'draw' not in Gen2.__dict__ + assert Gen2.draw is Gen1.draw + + +def test_draw_wraper_forward_input(): + class TestKlass(martist.Artist): + def draw(self, renderer, extra): + return extra + + art = TestKlass() + renderer = mbackend_bases.RendererBase() + + assert 'aardvark' == art.draw(renderer, 'aardvark') + assert 'aardvark' == art.draw(renderer, extra='aardvark') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axes.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axes.py new file mode 100644 index 00000000..edc040ef --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axes.py @@ -0,0 +1,8839 @@ +import contextlib +from collections import namedtuple +import datetime +from decimal import Decimal +from functools import partial +import inspect +import io +from itertools import product +import platform +from types import SimpleNamespace + +import dateutil.tz + +import numpy as np +from numpy import ma +from cycler import cycler +import pytest + +import matplotlib +import matplotlib as mpl +from matplotlib import rc_context, patheffects +import matplotlib.colors as mcolors +import matplotlib.dates as mdates +from matplotlib.figure import Figure +from matplotlib.axes import Axes +import matplotlib.font_manager as mfont_manager +import matplotlib.markers as mmarkers +import matplotlib.patches as mpatches +import matplotlib.path as mpath +from matplotlib.projections.geo import HammerAxes +from matplotlib.projections.polar import PolarAxes +import matplotlib.pyplot as plt +import matplotlib.text as mtext +import matplotlib.ticker as mticker +import matplotlib.transforms as mtransforms +import mpl_toolkits.axisartist as AA # type: ignore +from numpy.testing import ( + assert_allclose, assert_array_equal, assert_array_almost_equal) +from matplotlib.testing.decorators import ( + image_comparison, check_figures_equal, remove_ticks_and_titles) + +# Note: Some test cases are run twice: once normally and once with labeled data +# These two must be defined in the same test function or need to have +# different baseline images to prevent race conditions when pytest runs +# the tests with multiple threads. + + +@check_figures_equal(extensions=["png"]) +def test_invisible_axes(fig_test, fig_ref): + ax = fig_test.subplots() + ax.set_visible(False) + + +def test_get_labels(): + fig, ax = plt.subplots() + ax.set_xlabel('x label') + ax.set_ylabel('y label') + assert ax.get_xlabel() == 'x label' + assert ax.get_ylabel() == 'y label' + + +def test_repr(): + fig, ax = plt.subplots() + ax.set_label('label') + ax.set_title('title') + ax.set_xlabel('x') + ax.set_ylabel('y') + assert repr(ax) == ( + "<Axes: " + "label='label', title={'center': 'title'}, xlabel='x', ylabel='y'>") + + +@check_figures_equal() +def test_label_loc_vertical(fig_test, fig_ref): + ax = fig_test.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label', loc='top') + ax.set_xlabel('X Label', loc='right') + cbar = fig_test.colorbar(sc) + cbar.set_label("Z Label", loc='top') + + ax = fig_ref.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label', y=1, ha='right') + ax.set_xlabel('X Label', x=1, ha='right') + cbar = fig_ref.colorbar(sc) + cbar.set_label("Z Label", y=1, ha='right') + + +@check_figures_equal() +def test_label_loc_horizontal(fig_test, fig_ref): + ax = fig_test.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label', loc='bottom') + ax.set_xlabel('X Label', loc='left') + cbar = fig_test.colorbar(sc, orientation='horizontal') + cbar.set_label("Z Label", loc='left') + + ax = fig_ref.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label', y=0, ha='left') + ax.set_xlabel('X Label', x=0, ha='left') + cbar = fig_ref.colorbar(sc, orientation='horizontal') + cbar.set_label("Z Label", x=0, ha='left') + + +@check_figures_equal() +def test_label_loc_rc(fig_test, fig_ref): + with matplotlib.rc_context({"xaxis.labellocation": "right", + "yaxis.labellocation": "top"}): + ax = fig_test.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label') + ax.set_xlabel('X Label') + cbar = fig_test.colorbar(sc, orientation='horizontal') + cbar.set_label("Z Label") + + ax = fig_ref.subplots() + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() + ax.set_ylabel('Y Label', y=1, ha='right') + ax.set_xlabel('X Label', x=1, ha='right') + cbar = fig_ref.colorbar(sc, orientation='horizontal') + cbar.set_label("Z Label", x=1, ha='right') + + +def test_label_shift(): + fig, ax = plt.subplots() + + # Test label re-centering on x-axis + ax.set_xlabel("Test label", loc="left") + ax.set_xlabel("Test label", loc="center") + assert ax.xaxis.get_label().get_horizontalalignment() == "center" + ax.set_xlabel("Test label", loc="right") + assert ax.xaxis.get_label().get_horizontalalignment() == "right" + ax.set_xlabel("Test label", loc="center") + assert ax.xaxis.get_label().get_horizontalalignment() == "center" + + # Test label re-centering on y-axis + ax.set_ylabel("Test label", loc="top") + ax.set_ylabel("Test label", loc="center") + assert ax.yaxis.get_label().get_horizontalalignment() == "center" + ax.set_ylabel("Test label", loc="bottom") + assert ax.yaxis.get_label().get_horizontalalignment() == "left" + ax.set_ylabel("Test label", loc="center") + assert ax.yaxis.get_label().get_horizontalalignment() == "center" + + +@check_figures_equal(extensions=["png"]) +def test_acorr(fig_test, fig_ref): + np.random.seed(19680801) + Nx = 512 + x = np.random.normal(0, 1, Nx).cumsum() + maxlags = Nx-1 + + ax_test = fig_test.subplots() + ax_test.acorr(x, maxlags=maxlags) + + ax_ref = fig_ref.subplots() + # Normalized autocorrelation + norm_auto_corr = np.correlate(x, x, mode="full")/np.dot(x, x) + lags = np.arange(-maxlags, maxlags+1) + norm_auto_corr = norm_auto_corr[Nx-1-maxlags:Nx+maxlags] + ax_ref.vlines(lags, [0], norm_auto_corr) + ax_ref.axhline(y=0, xmin=0, xmax=1) + + +@check_figures_equal(extensions=["png"]) +def test_acorr_integers(fig_test, fig_ref): + np.random.seed(19680801) + Nx = 51 + x = (np.random.rand(Nx) * 10).cumsum() + x = (np.ceil(x)).astype(np.int64) + maxlags = Nx-1 + + ax_test = fig_test.subplots() + ax_test.acorr(x, maxlags=maxlags) + + ax_ref = fig_ref.subplots() + + # Normalized autocorrelation + norm_auto_corr = np.correlate(x, x, mode="full")/np.dot(x, x) + lags = np.arange(-maxlags, maxlags+1) + norm_auto_corr = norm_auto_corr[Nx-1-maxlags:Nx+maxlags] + ax_ref.vlines(lags, [0], norm_auto_corr) + ax_ref.axhline(y=0, xmin=0, xmax=1) + + +@check_figures_equal(extensions=["png"]) +def test_spy(fig_test, fig_ref): + np.random.seed(19680801) + a = np.ones(32 * 32) + a[:16 * 32] = 0 + np.random.shuffle(a) + a = a.reshape((32, 32)) + + axs_test = fig_test.subplots(2) + axs_test[0].spy(a) + axs_test[1].spy(a, marker=".", origin="lower") + + axs_ref = fig_ref.subplots(2) + axs_ref[0].imshow(a, cmap="gray_r", interpolation="nearest") + axs_ref[0].xaxis.tick_top() + axs_ref[1].plot(*np.nonzero(a)[::-1], ".", markersize=10) + axs_ref[1].set( + aspect=1, xlim=axs_ref[0].get_xlim(), ylim=axs_ref[0].get_ylim()[::-1]) + for ax in axs_ref: + ax.xaxis.set_ticks_position("both") + + +def test_spy_invalid_kwargs(): + fig, ax = plt.subplots() + for unsupported_kw in [{'interpolation': 'nearest'}, + {'marker': 'o', 'linestyle': 'solid'}]: + with pytest.raises(TypeError): + ax.spy(np.eye(3, 3), **unsupported_kw) + + +@check_figures_equal(extensions=["png"]) +def test_matshow(fig_test, fig_ref): + mpl.style.use("mpl20") + a = np.random.rand(32, 32) + fig_test.add_subplot().matshow(a) + ax_ref = fig_ref.add_subplot() + ax_ref.imshow(a) + ax_ref.xaxis.tick_top() + ax_ref.xaxis.set_ticks_position('both') + + +@image_comparison(['formatter_ticker_001', + 'formatter_ticker_002', + 'formatter_ticker_003', + 'formatter_ticker_004', + 'formatter_ticker_005', + ]) +def test_formatter_ticker(): + import matplotlib.testing.jpl_units as units + units.register() + + # This should affect the tick size. (Tests issue #543) + matplotlib.rcParams['lines.markeredgewidth'] = 30 + + # This essentially test to see if user specified labels get overwritten + # by the auto labeler functionality of the axes. + xdata = [x*units.sec for x in range(10)] + ydata1 = [(1.5*y - 0.5)*units.km for y in range(10)] + ydata2 = [(1.75*y - 1.0)*units.km for y in range(10)] + + ax = plt.figure().subplots() + ax.set_xlabel("x-label 001") + + ax = plt.figure().subplots() + ax.set_xlabel("x-label 001") + ax.plot(xdata, ydata1, color='blue', xunits="sec") + + ax = plt.figure().subplots() + ax.set_xlabel("x-label 001") + ax.plot(xdata, ydata1, color='blue', xunits="sec") + ax.set_xlabel("x-label 003") + + ax = plt.figure().subplots() + ax.plot(xdata, ydata1, color='blue', xunits="sec") + ax.plot(xdata, ydata2, color='green', xunits="hour") + ax.set_xlabel("x-label 004") + + # See SF bug 2846058 + # https://sourceforge.net/tracker/?func=detail&aid=2846058&group_id=80706&atid=560720 + ax = plt.figure().subplots() + ax.plot(xdata, ydata1, color='blue', xunits="sec") + ax.plot(xdata, ydata2, color='green', xunits="hour") + ax.set_xlabel("x-label 005") + ax.autoscale_view() + + +def test_funcformatter_auto_formatter(): + def _formfunc(x, pos): + return '' + + ax = plt.figure().subplots() + + assert ax.xaxis.isDefault_majfmt + assert ax.xaxis.isDefault_minfmt + assert ax.yaxis.isDefault_majfmt + assert ax.yaxis.isDefault_minfmt + + ax.xaxis.set_major_formatter(_formfunc) + + assert not ax.xaxis.isDefault_majfmt + assert ax.xaxis.isDefault_minfmt + assert ax.yaxis.isDefault_majfmt + assert ax.yaxis.isDefault_minfmt + + targ_funcformatter = mticker.FuncFormatter(_formfunc) + + assert isinstance(ax.xaxis.get_major_formatter(), + mticker.FuncFormatter) + + assert ax.xaxis.get_major_formatter().func == targ_funcformatter.func + + +def test_strmethodformatter_auto_formatter(): + formstr = '{x}_{pos}' + + ax = plt.figure().subplots() + + assert ax.xaxis.isDefault_majfmt + assert ax.xaxis.isDefault_minfmt + assert ax.yaxis.isDefault_majfmt + assert ax.yaxis.isDefault_minfmt + + ax.yaxis.set_minor_formatter(formstr) + + assert ax.xaxis.isDefault_majfmt + assert ax.xaxis.isDefault_minfmt + assert ax.yaxis.isDefault_majfmt + assert not ax.yaxis.isDefault_minfmt + + targ_strformatter = mticker.StrMethodFormatter(formstr) + + assert isinstance(ax.yaxis.get_minor_formatter(), + mticker.StrMethodFormatter) + + assert ax.yaxis.get_minor_formatter().fmt == targ_strformatter.fmt + + +@image_comparison(["twin_axis_locators_formatters"]) +def test_twin_axis_locators_formatters(): + vals = np.linspace(0, 1, num=5, endpoint=True) + locs = np.sin(np.pi * vals / 2.0) + + majl = plt.FixedLocator(locs) + minl = plt.FixedLocator([0.1, 0.2, 0.3]) + + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + ax1.plot([0.1, 100], [0, 1]) + ax1.yaxis.set_major_locator(majl) + ax1.yaxis.set_minor_locator(minl) + ax1.yaxis.set_major_formatter(plt.FormatStrFormatter('%08.2lf')) + ax1.yaxis.set_minor_formatter(plt.FixedFormatter(['tricks', 'mind', + 'jedi'])) + + ax1.xaxis.set_major_locator(plt.LinearLocator()) + ax1.xaxis.set_minor_locator(plt.FixedLocator([15, 35, 55, 75])) + ax1.xaxis.set_major_formatter(plt.FormatStrFormatter('%05.2lf')) + ax1.xaxis.set_minor_formatter(plt.FixedFormatter(['c', '3', 'p', 'o'])) + ax1.twiny() + ax1.twinx() + + +def test_twinx_cla(): + fig, ax = plt.subplots() + ax2 = ax.twinx() + ax3 = ax2.twiny() + plt.draw() + assert not ax2.xaxis.get_visible() + assert not ax2.patch.get_visible() + ax2.cla() + ax3.cla() + + assert not ax2.xaxis.get_visible() + assert not ax2.patch.get_visible() + assert ax2.yaxis.get_visible() + + assert ax3.xaxis.get_visible() + assert not ax3.patch.get_visible() + assert not ax3.yaxis.get_visible() + + assert ax.xaxis.get_visible() + assert ax.patch.get_visible() + assert ax.yaxis.get_visible() + + +@pytest.mark.parametrize('twin', ('x', 'y')) +def test_twin_units(twin): + axis_name = f'{twin}axis' + twin_func = f'twin{twin}' + + a = ['0', '1'] + b = ['a', 'b'] + + fig = Figure() + ax1 = fig.subplots() + ax1.plot(a, b) + assert getattr(ax1, axis_name).units is not None + ax2 = getattr(ax1, twin_func)() + assert getattr(ax2, axis_name).units is not None + assert getattr(ax2, axis_name).units is getattr(ax1, axis_name).units + + +@pytest.mark.parametrize('twin', ('x', 'y')) +@check_figures_equal(extensions=['png'], tol=0.19) +def test_twin_logscale(fig_test, fig_ref, twin): + twin_func = f'twin{twin}' # test twinx or twiny + set_scale = f'set_{twin}scale' + x = np.arange(1, 100) + + # Change scale after twinning. + ax_test = fig_test.add_subplot(2, 1, 1) + ax_twin = getattr(ax_test, twin_func)() + getattr(ax_test, set_scale)('log') + ax_twin.plot(x, x) + + # Twin after changing scale. + ax_test = fig_test.add_subplot(2, 1, 2) + getattr(ax_test, set_scale)('log') + ax_twin = getattr(ax_test, twin_func)() + ax_twin.plot(x, x) + + for i in [1, 2]: + ax_ref = fig_ref.add_subplot(2, 1, i) + getattr(ax_ref, set_scale)('log') + ax_ref.plot(x, x) + + # This is a hack because twinned Axes double-draw the frame. + # Remove this when that is fixed. + Path = matplotlib.path.Path + fig_ref.add_artist( + matplotlib.patches.PathPatch( + Path([[0, 0], [0, 1], + [0, 1], [1, 1], + [1, 1], [1, 0], + [1, 0], [0, 0]], + [Path.MOVETO, Path.LINETO] * 4), + transform=ax_ref.transAxes, + facecolor='none', + edgecolor=mpl.rcParams['axes.edgecolor'], + linewidth=mpl.rcParams['axes.linewidth'], + capstyle='projecting')) + + remove_ticks_and_titles(fig_test) + remove_ticks_and_titles(fig_ref) + + +@image_comparison(['twin_autoscale.png']) +def test_twinx_axis_scales(): + x = np.array([0, 0.5, 1]) + y = 0.5 * x + x2 = np.array([0, 1, 2]) + y2 = 2 * x2 + + fig = plt.figure() + ax = fig.add_axes((0, 0, 1, 1), autoscalex_on=False, autoscaley_on=False) + ax.plot(x, y, color='blue', lw=10) + + ax2 = plt.twinx(ax) + ax2.plot(x2, y2, 'r--', lw=5) + + ax.margins(0, 0) + ax2.margins(0, 0) + + +def test_twin_inherit_autoscale_setting(): + fig, ax = plt.subplots() + ax_x_on = ax.twinx() + ax.set_autoscalex_on(False) + ax_x_off = ax.twinx() + + assert ax_x_on.get_autoscalex_on() + assert not ax_x_off.get_autoscalex_on() + + ax_y_on = ax.twiny() + ax.set_autoscaley_on(False) + ax_y_off = ax.twiny() + + assert ax_y_on.get_autoscaley_on() + assert not ax_y_off.get_autoscaley_on() + + +def test_inverted_cla(): + # GitHub PR #5450. Setting autoscale should reset + # axes to be non-inverted. + # plotting an image, then 1d graph, axis is now down + fig = plt.figure(0) + ax = fig.gca() + # 1. test that a new axis is not inverted per default + assert not ax.xaxis_inverted() + assert not ax.yaxis_inverted() + img = np.random.random((100, 100)) + ax.imshow(img) + # 2. test that a image axis is inverted + assert not ax.xaxis_inverted() + assert ax.yaxis_inverted() + # 3. test that clearing and plotting a line, axes are + # not inverted + ax.cla() + x = np.linspace(0, 2*np.pi, 100) + ax.plot(x, np.cos(x)) + assert not ax.xaxis_inverted() + assert not ax.yaxis_inverted() + + # 4. autoscaling should not bring back axes to normal + ax.cla() + ax.imshow(img) + plt.autoscale() + assert not ax.xaxis_inverted() + assert ax.yaxis_inverted() + + for ax in fig.axes: + ax.remove() + # 5. two shared axes. Inverting the leader axis should invert the shared + # axes; clearing the leader axis should bring axes in shared + # axes back to normal. + ax0 = plt.subplot(211) + ax1 = plt.subplot(212, sharey=ax0) + ax0.yaxis.set_inverted(True) + assert ax1.yaxis_inverted() + ax1.plot(x, np.cos(x)) + ax0.cla() + assert not ax1.yaxis_inverted() + ax1.cla() + # 6. clearing the follower should not touch limits + ax0.imshow(img) + ax1.plot(x, np.cos(x)) + ax1.cla() + assert ax.yaxis_inverted() + + # clean up + plt.close(fig) + + +def test_subclass_clear_cla(): + # Ensure that subclasses of Axes call cla/clear correctly. + # Note, we cannot use mocking here as we want to be sure that the + # superclass fallback does not recurse. + + with pytest.warns(PendingDeprecationWarning, + match='Overriding `Axes.cla`'): + class ClaAxes(Axes): + def cla(self): + nonlocal called + called = True + + with pytest.warns(PendingDeprecationWarning, + match='Overriding `Axes.cla`'): + class ClaSuperAxes(Axes): + def cla(self): + nonlocal called + called = True + super().cla() + + class SubClaAxes(ClaAxes): + pass + + class ClearAxes(Axes): + def clear(self): + nonlocal called + called = True + + class ClearSuperAxes(Axes): + def clear(self): + nonlocal called + called = True + super().clear() + + class SubClearAxes(ClearAxes): + pass + + fig = Figure() + for axes_class in [ClaAxes, ClaSuperAxes, SubClaAxes, + ClearAxes, ClearSuperAxes, SubClearAxes]: + called = False + ax = axes_class(fig, [0, 0, 1, 1]) + # Axes.__init__ has already called clear (which aliases to cla or is in + # the subclass). + assert called + + called = False + ax.cla() + assert called + + +def test_cla_not_redefined_internally(): + for klass in Axes.__subclasses__(): + # Check that cla does not get redefined in our Axes subclasses, except + # for in the above test function. + if 'test_subclass_clear_cla' not in klass.__qualname__: + assert 'cla' not in klass.__dict__ + + +@check_figures_equal(extensions=["png"]) +def test_minorticks_on_rcParams_both(fig_test, fig_ref): + with matplotlib.rc_context({"xtick.minor.visible": True, + "ytick.minor.visible": True}): + ax_test = fig_test.subplots() + ax_test.plot([0, 1], [0, 1]) + ax_ref = fig_ref.subplots() + ax_ref.plot([0, 1], [0, 1]) + ax_ref.minorticks_on() + + +@image_comparison(["autoscale_tiny_range"], remove_text=True) +def test_autoscale_tiny_range(): + # github pull #904 + fig, axs = plt.subplots(2, 2) + for i, ax in enumerate(axs.flat): + y1 = 10**(-11 - i) + ax.plot([0, 1], [1, 1 + y1]) + + +@mpl.style.context('default') +def test_autoscale_tight(): + fig, ax = plt.subplots(1, 1) + ax.plot([1, 2, 3, 4]) + ax.autoscale(enable=True, axis='x', tight=False) + ax.autoscale(enable=True, axis='y', tight=True) + assert_allclose(ax.get_xlim(), (-0.15, 3.15)) + assert_allclose(ax.get_ylim(), (1.0, 4.0)) + + # Check that autoscale is on + assert ax.get_autoscalex_on() + assert ax.get_autoscaley_on() + assert ax.get_autoscale_on() + # Set enable to None + ax.autoscale(enable=None) + # Same limits + assert_allclose(ax.get_xlim(), (-0.15, 3.15)) + assert_allclose(ax.get_ylim(), (1.0, 4.0)) + # autoscale still on + assert ax.get_autoscalex_on() + assert ax.get_autoscaley_on() + assert ax.get_autoscale_on() + + +@mpl.style.context('default') +def test_autoscale_log_shared(): + # related to github #7587 + # array starts at zero to trigger _minpos handling + x = np.arange(100, dtype=float) + fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) + ax1.loglog(x, x) + ax2.semilogx(x, x) + ax1.autoscale(tight=True) + ax2.autoscale(tight=True) + plt.draw() + lims = (x[1], x[-1]) + assert_allclose(ax1.get_xlim(), lims) + assert_allclose(ax1.get_ylim(), lims) + assert_allclose(ax2.get_xlim(), lims) + assert_allclose(ax2.get_ylim(), (x[0], x[-1])) + + +@mpl.style.context('default') +def test_use_sticky_edges(): + fig, ax = plt.subplots() + ax.imshow([[0, 1], [2, 3]], origin='lower') + assert_allclose(ax.get_xlim(), (-0.5, 1.5)) + assert_allclose(ax.get_ylim(), (-0.5, 1.5)) + ax.use_sticky_edges = False + ax.autoscale() + xlim = (-0.5 - 2 * ax._xmargin, 1.5 + 2 * ax._xmargin) + ylim = (-0.5 - 2 * ax._ymargin, 1.5 + 2 * ax._ymargin) + assert_allclose(ax.get_xlim(), xlim) + assert_allclose(ax.get_ylim(), ylim) + # Make sure it is reversible: + ax.use_sticky_edges = True + ax.autoscale() + assert_allclose(ax.get_xlim(), (-0.5, 1.5)) + assert_allclose(ax.get_ylim(), (-0.5, 1.5)) + + +@check_figures_equal(extensions=["png"]) +def test_sticky_shared_axes(fig_test, fig_ref): + # Check that sticky edges work whether they are set in an Axes that is a + # "leader" in a share, or an Axes that is a "follower". + Z = np.arange(15).reshape(3, 5) + + ax0 = fig_test.add_subplot(211) + ax1 = fig_test.add_subplot(212, sharex=ax0) + ax1.pcolormesh(Z) + + ax0 = fig_ref.add_subplot(212) + ax1 = fig_ref.add_subplot(211, sharex=ax0) + ax0.pcolormesh(Z) + + +def test_nargs_stem(): + with pytest.raises(TypeError, match='0 were given'): + # stem() takes 1-3 arguments. + plt.stem() + + +def test_nargs_legend(): + with pytest.raises(TypeError, match='3 were given'): + ax = plt.subplot() + # legend() takes 0-2 arguments. + ax.legend(['First'], ['Second'], 3) + + +def test_nargs_pcolorfast(): + with pytest.raises(TypeError, match='2 were given'): + ax = plt.subplot() + # pcolorfast() takes 1 or 3 arguments, + # not passing any arguments fails at C = args[-1] + # before nargs_err is raised. + ax.pcolorfast([(0, 1), (0, 2)], [[1, 2, 3], [1, 2, 3]]) + + +@image_comparison(['offset_points'], remove_text=True) +def test_basic_annotate(): + # Setup some data + t = np.arange(0.0, 5.0, 0.01) + s = np.cos(2.0*np.pi * t) + + # Offset Points + + fig = plt.figure() + ax = fig.add_subplot(autoscale_on=False, xlim=(-1, 5), ylim=(-3, 5)) + line, = ax.plot(t, s, lw=3, color='purple') + + ax.annotate('local max', xy=(3, 1), xycoords='data', + xytext=(3, 3), textcoords='offset points') + + +@image_comparison(['arrow_simple.png'], remove_text=True) +def test_arrow_simple(): + # Simple image test for ax.arrow + # kwargs that take discrete values + length_includes_head = (True, False) + shape = ('full', 'left', 'right') + head_starts_at_zero = (True, False) + # Create outer product of values + kwargs = product(length_includes_head, shape, head_starts_at_zero) + + fig, axs = plt.subplots(3, 4) + for i, (ax, kwarg) in enumerate(zip(axs.flat, kwargs)): + ax.set_xlim(-2, 2) + ax.set_ylim(-2, 2) + # Unpack kwargs + (length_includes_head, shape, head_starts_at_zero) = kwarg + theta = 2 * np.pi * i / 12 + # Draw arrow + ax.arrow(0, 0, np.sin(theta), np.cos(theta), + width=theta/100, + length_includes_head=length_includes_head, + shape=shape, + head_starts_at_zero=head_starts_at_zero, + head_width=theta / 10, + head_length=theta / 10) + + +def test_arrow_empty(): + _, ax = plt.subplots() + # Create an empty FancyArrow + ax.arrow(0, 0, 0, 0, head_length=0) + + +def test_arrow_in_view(): + _, ax = plt.subplots() + ax.arrow(1, 1, 1, 1) + assert ax.get_xlim() == (0.8, 2.2) + assert ax.get_ylim() == (0.8, 2.2) + + +def test_annotate_default_arrow(): + # Check that we can make an annotation arrow with only default properties. + fig, ax = plt.subplots() + ann = ax.annotate("foo", (0, 1), xytext=(2, 3)) + assert ann.arrow_patch is None + ann = ax.annotate("foo", (0, 1), xytext=(2, 3), arrowprops={}) + assert ann.arrow_patch is not None + + +def test_annotate_signature(): + """Check that the signature of Axes.annotate() matches Annotation.""" + fig, ax = plt.subplots() + annotate_params = inspect.signature(ax.annotate).parameters + annotation_params = inspect.signature(mtext.Annotation).parameters + assert list(annotate_params.keys()) == list(annotation_params.keys()) + for p1, p2 in zip(annotate_params.values(), annotation_params.values()): + assert p1 == p2 + + +@image_comparison(['fill_units.png'], savefig_kwarg={'dpi': 60}) +def test_fill_units(): + import matplotlib.testing.jpl_units as units + units.register() + + # generate some data + t = units.Epoch("ET", dt=datetime.datetime(2009, 4, 27)) + value = 10.0 * units.deg + day = units.Duration("ET", 24.0 * 60.0 * 60.0) + dt = np.arange('2009-04-27', '2009-04-29', dtype='datetime64[D]') + dtn = mdates.date2num(dt) + + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) + + ax1.plot([t], [value], yunits='deg', color='red') + ind = [0, 0, 1, 1] + ax1.fill(dtn[ind], [0.0, 0.0, 90.0, 0.0], 'b') + + ax2.plot([t], [value], yunits='deg', color='red') + ax2.fill([t, t, t + day, t + day], + [0.0, 0.0, 90.0, 0.0], 'b') + + ax3.plot([t], [value], yunits='deg', color='red') + ax3.fill(dtn[ind], + [0 * units.deg, 0 * units.deg, 90 * units.deg, 0 * units.deg], + 'b') + + ax4.plot([t], [value], yunits='deg', color='red') + ax4.fill([t, t, t + day, t + day], + [0 * units.deg, 0 * units.deg, 90 * units.deg, 0 * units.deg], + facecolor="blue") + fig.autofmt_xdate() + + +def test_plot_format_kwarg_redundant(): + with pytest.warns(UserWarning, match="marker .* redundantly defined"): + plt.plot([0], [0], 'o', marker='x') + with pytest.warns(UserWarning, match="linestyle .* redundantly defined"): + plt.plot([0], [0], '-', linestyle='--') + with pytest.warns(UserWarning, match="color .* redundantly defined"): + plt.plot([0], [0], 'r', color='blue') + # smoke-test: should not warn + plt.errorbar([0], [0], fmt='none', color='blue') + + +@check_figures_equal(extensions=["png"]) +def test_errorbar_dashes(fig_test, fig_ref): + x = [1, 2, 3, 4] + y = np.sin(x) + + ax_ref = fig_ref.gca() + ax_test = fig_test.gca() + + line, *_ = ax_ref.errorbar(x, y, xerr=np.abs(y), yerr=np.abs(y)) + line.set_dashes([2, 2]) + + ax_test.errorbar(x, y, xerr=np.abs(y), yerr=np.abs(y), dashes=[2, 2]) + + +@image_comparison(['single_point', 'single_point']) +def test_single_point(): + # Issue #1796: don't let lines.marker affect the grid + matplotlib.rcParams['lines.marker'] = 'o' + matplotlib.rcParams['axes.grid'] = True + + fig, (ax1, ax2) = plt.subplots(2) + ax1.plot([0], [0], 'o') + ax2.plot([1], [1], 'o') + + # Reuse testcase from above for a labeled data test + data = {'a': [0], 'b': [1]} + + fig, (ax1, ax2) = plt.subplots(2) + ax1.plot('a', 'a', 'o', data=data) + ax2.plot('b', 'b', 'o', data=data) + + +@image_comparison(['single_date.png'], style='mpl20') +def test_single_date(): + + # use former defaults to match existing baseline image + plt.rcParams['axes.formatter.limits'] = -7, 7 + dt = mdates.date2num(np.datetime64('0000-12-31')) + + time1 = [721964.0] + data1 = [-65.54] + + fig, ax = plt.subplots(2, 1) + ax[0].plot_date(time1 + dt, data1, 'o', color='r') + ax[1].plot(time1, data1, 'o', color='r') + + +@check_figures_equal(extensions=["png"]) +def test_shaped_data(fig_test, fig_ref): + row = np.arange(10).reshape((1, -1)) + col = np.arange(0, 100, 10).reshape((-1, 1)) + + axs = fig_test.subplots(2) + axs[0].plot(row) # Actually plots nothing (columns are single points). + axs[1].plot(col) # Same as plotting 1d. + + axs = fig_ref.subplots(2) + # xlim from the implicit "x=0", ylim from the row datalim. + axs[0].set(xlim=(-.06, .06), ylim=(0, 9)) + axs[1].plot(col.ravel()) + + +def test_structured_data(): + # support for structured data + pts = np.array([(1, 1), (2, 2)], dtype=[("ones", float), ("twos", float)]) + + # this should not read second name as a format and raise ValueError + axs = plt.figure().subplots(2) + axs[0].plot("ones", "twos", data=pts) + axs[1].plot("ones", "twos", "r", data=pts) + + +@image_comparison(['aitoff_proj'], extensions=["png"], + remove_text=True, style='mpl20') +def test_aitoff_proj(): + """ + Test aitoff projection ref.: + https://github.com/matplotlib/matplotlib/pull/14451 + """ + x = np.linspace(-np.pi, np.pi, 20) + y = np.linspace(-np.pi / 2, np.pi / 2, 20) + X, Y = np.meshgrid(x, y) + + fig, ax = plt.subplots(figsize=(8, 4.2), + subplot_kw=dict(projection="aitoff")) + ax.grid() + ax.plot(X.flat, Y.flat, 'o', markersize=4) + + +@image_comparison(['axvspan_epoch']) +def test_axvspan_epoch(): + import matplotlib.testing.jpl_units as units + units.register() + + # generate some data + t0 = units.Epoch("ET", dt=datetime.datetime(2009, 1, 20)) + tf = units.Epoch("ET", dt=datetime.datetime(2009, 1, 21)) + dt = units.Duration("ET", units.day.convert("sec")) + + ax = plt.gca() + ax.axvspan(t0, tf, facecolor="blue", alpha=0.25) + ax.set_xlim(t0 - 5.0*dt, tf + 5.0*dt) + + +@image_comparison(['axhspan_epoch'], tol=0.02) +def test_axhspan_epoch(): + import matplotlib.testing.jpl_units as units + units.register() + + # generate some data + t0 = units.Epoch("ET", dt=datetime.datetime(2009, 1, 20)) + tf = units.Epoch("ET", dt=datetime.datetime(2009, 1, 21)) + dt = units.Duration("ET", units.day.convert("sec")) + + ax = plt.gca() + ax.axhspan(t0, tf, facecolor="blue", alpha=0.25) + ax.set_ylim(t0 - 5.0*dt, tf + 5.0*dt) + + +@image_comparison(['hexbin_extent.png', 'hexbin_extent.png'], remove_text=True) +def test_hexbin_extent(): + # this test exposes sf bug 2856228 + fig, ax = plt.subplots() + data = (np.arange(2000) / 2000).reshape((2, 1000)) + x, y = data + + ax.hexbin(x, y, extent=[.1, .3, .6, .7]) + + # Reuse testcase from above for a labeled data test + data = {"x": x, "y": y} + + fig, ax = plt.subplots() + ax.hexbin("x", "y", extent=[.1, .3, .6, .7], data=data) + + +@image_comparison(['hexbin_empty.png', 'hexbin_empty.png'], remove_text=True) +def test_hexbin_empty(): + # From #3886: creating hexbin from empty dataset raises ValueError + fig, ax = plt.subplots() + ax.hexbin([], []) + fig, ax = plt.subplots() + # From #23922: creating hexbin with log scaling from empty + # dataset raises ValueError + ax.hexbin([], [], bins='log') + # From #27103: np.max errors when handed empty data + ax.hexbin([], [], C=[], reduce_C_function=np.max) + + +def test_hexbin_pickable(): + # From #1973: Test that picking a hexbin collection works + fig, ax = plt.subplots() + data = (np.arange(200) / 200).reshape((2, 100)) + x, y = data + hb = ax.hexbin(x, y, extent=[.1, .3, .6, .7], picker=-1) + mouse_event = SimpleNamespace(x=400, y=300) + assert hb.contains(mouse_event)[0] + + +@image_comparison(['hexbin_log.png'], style='mpl20') +def test_hexbin_log(): + # Issue #1636 (and also test log scaled colorbar) + + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + np.random.seed(19680801) + n = 100000 + x = np.random.standard_normal(n) + y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) + y = np.power(2, y * 0.5) + + fig, ax = plt.subplots() + h = ax.hexbin(x, y, yscale='log', bins='log', + marginals=True, reduce_C_function=np.sum) + plt.colorbar(h) + + +@image_comparison(["hexbin_linear.png"], style="mpl20", remove_text=True) +def test_hexbin_linear(): + # Issue #21165 + np.random.seed(19680801) + n = 100000 + x = np.random.standard_normal(n) + y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) + + fig, ax = plt.subplots() + ax.hexbin(x, y, gridsize=(10, 5), marginals=True, + reduce_C_function=np.sum) + + +def test_hexbin_log_clim(): + x, y = np.arange(200).reshape((2, 100)) + fig, ax = plt.subplots() + h = ax.hexbin(x, y, bins='log', vmin=2, vmax=100) + assert h.get_clim() == (2, 100) + + +@check_figures_equal(extensions=['png']) +def test_hexbin_mincnt_behavior_upon_C_parameter(fig_test, fig_ref): + # see: gh:12926 + datapoints = [ + # list of (x, y) + (0, 0), + (0, 0), + (6, 0), + (0, 6), + ] + X, Y = zip(*datapoints) + C = [1] * len(X) + extent = [-10., 10, -10., 10] + gridsize = (7, 7) + + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + + # without C parameter + ax_ref.hexbin( + X, Y, + extent=extent, + gridsize=gridsize, + mincnt=1, + ) + ax_ref.set_facecolor("green") # for contrast of background + + # with C parameter + ax_test.hexbin( + X, Y, + C=[1] * len(X), + reduce_C_function=lambda v: sum(v), + mincnt=1, + extent=extent, + gridsize=gridsize, + ) + ax_test.set_facecolor("green") + + +def test_inverted_limits(): + # Test gh:1553 + # Calling invert_xaxis prior to plotting should not disable autoscaling + # while still maintaining the inverted direction + fig, ax = plt.subplots() + ax.invert_xaxis() + ax.plot([-5, -3, 2, 4], [1, 2, -3, 5]) + + assert ax.get_xlim() == (4, -5) + assert ax.get_ylim() == (-3, 5) + plt.close() + + fig, ax = plt.subplots() + ax.invert_yaxis() + ax.plot([-5, -3, 2, 4], [1, 2, -3, 5]) + + assert ax.get_xlim() == (-5, 4) + assert ax.get_ylim() == (5, -3) + + # Test inverting nonlinear axes. + fig, ax = plt.subplots() + ax.set_yscale("log") + ax.set_ylim(10, 1) + assert ax.get_ylim() == (10, 1) + + +@image_comparison(['nonfinite_limits']) +def test_nonfinite_limits(): + x = np.arange(0., np.e, 0.01) + # silence divide by zero warning from log(0) + with np.errstate(divide='ignore'): + y = np.log(x) + x[len(x)//2] = np.nan + fig, ax = plt.subplots() + ax.plot(x, y) + + +@mpl.style.context('default') +@pytest.mark.parametrize('plot_fun', + ['scatter', 'plot', 'fill_between']) +@check_figures_equal(extensions=["png"]) +def test_limits_empty_data(plot_fun, fig_test, fig_ref): + # Check that plotting empty data doesn't change autoscaling of dates + x = np.arange("2010-01-01", "2011-01-01", dtype="datetime64[D]") + + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + + getattr(ax_test, plot_fun)([], []) + + for ax in [ax_test, ax_ref]: + getattr(ax, plot_fun)(x, range(len(x)), color='C0') + + +@image_comparison(['imshow', 'imshow'], remove_text=True, style='mpl20') +def test_imshow(): + # use former defaults to match existing baseline image + matplotlib.rcParams['image.interpolation'] = 'nearest' + # Create a NxN image + N = 100 + (x, y) = np.indices((N, N)) + x -= N//2 + y -= N//2 + r = np.sqrt(x**2+y**2-x*y) + + # Create a contour plot at N/4 and extract both the clip path and transform + fig, ax = plt.subplots() + ax.imshow(r) + + # Reuse testcase from above for a labeled data test + data = {"r": r} + fig, ax = plt.subplots() + ax.imshow("r", data=data) + + +@image_comparison( + ['imshow_clip'], style='mpl20', + tol=1.24 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_imshow_clip(): + # As originally reported by Gellule Xg <gellule.xg@free.fr> + # use former defaults to match existing baseline image + matplotlib.rcParams['image.interpolation'] = 'nearest' + + # Create a NxN image + N = 100 + (x, y) = np.indices((N, N)) + x -= N//2 + y -= N//2 + r = np.sqrt(x**2+y**2-x*y) + + # Create a contour plot at N/4 and extract both the clip path and transform + fig, ax = plt.subplots() + + c = ax.contour(r, [N/4]) + clip_path = mtransforms.TransformedPath(c.get_paths()[0], c.get_transform()) + + # Plot the image clipped by the contour + ax.imshow(r, clip_path=clip_path) + + +def test_imshow_norm_vminvmax(): + """Parameters vmin, vmax should error if norm is given.""" + a = [[1, 2], [3, 4]] + ax = plt.axes() + with pytest.raises(ValueError, + match="Passing a Normalize instance simultaneously " + "with vmin/vmax is not supported."): + ax.imshow(a, norm=mcolors.Normalize(-10, 10), vmin=0, vmax=5) + + +@image_comparison(['polycollection_joinstyle'], remove_text=True) +def test_polycollection_joinstyle(): + # Bug #2890979 reported by Matthew West + fig, ax = plt.subplots() + verts = np.array([[1, 1], [1, 2], [2, 2], [2, 1]]) + c = mpl.collections.PolyCollection([verts], linewidths=40) + ax.add_collection(c) + ax.set_xbound(0, 3) + ax.set_ybound(0, 3) + + +@pytest.mark.parametrize( + 'x, y1, y2', [ + (np.zeros((2, 2)), 3, 3), + (np.arange(0.0, 2, 0.02), np.zeros((2, 2)), 3), + (np.arange(0.0, 2, 0.02), 3, np.zeros((2, 2))) + ], ids=[ + '2d_x_input', + '2d_y1_input', + '2d_y2_input' + ] +) +def test_fill_between_input(x, y1, y2): + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.fill_between(x, y1, y2) + + +@pytest.mark.parametrize( + 'y, x1, x2', [ + (np.zeros((2, 2)), 3, 3), + (np.arange(0.0, 2, 0.02), np.zeros((2, 2)), 3), + (np.arange(0.0, 2, 0.02), 3, np.zeros((2, 2))) + ], ids=[ + '2d_y_input', + '2d_x1_input', + '2d_x2_input' + ] +) +def test_fill_betweenx_input(y, x1, x2): + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.fill_betweenx(y, x1, x2) + + +@image_comparison(['fill_between_interpolate'], remove_text=True) +def test_fill_between_interpolate(): + x = np.arange(0.0, 2, 0.02) + y1 = np.sin(2*np.pi*x) + y2 = 1.2*np.sin(4*np.pi*x) + + fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) + ax1.plot(x, y1, x, y2, color='black') + ax1.fill_between(x, y1, y2, where=y2 >= y1, facecolor='white', hatch='/', + interpolate=True) + ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', + interpolate=True) + + # Test support for masked arrays. + y2 = np.ma.masked_greater(y2, 1.0) + # Test that plotting works for masked arrays with the first element masked + y2[0] = np.ma.masked + ax2.plot(x, y1, x, y2, color='black') + ax2.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', + interpolate=True) + ax2.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', + interpolate=True) + + +@image_comparison(['fill_between_interpolate_decreasing'], + style='mpl20', remove_text=True) +def test_fill_between_interpolate_decreasing(): + p = np.array([724.3, 700, 655]) + t = np.array([9.4, 7, 2.2]) + prof = np.array([7.9, 6.6, 3.8]) + + fig, ax = plt.subplots(figsize=(9, 9)) + + ax.plot(t, p, 'tab:red') + ax.plot(prof, p, 'k') + + ax.fill_betweenx(p, t, prof, where=prof < t, + facecolor='blue', interpolate=True, alpha=0.4) + ax.fill_betweenx(p, t, prof, where=prof > t, + facecolor='red', interpolate=True, alpha=0.4) + + ax.set_xlim(0, 30) + ax.set_ylim(800, 600) + + +@image_comparison(['fill_between_interpolate_nan'], remove_text=True) +def test_fill_between_interpolate_nan(): + # Tests fix for issue #18986. + x = np.arange(10) + y1 = np.asarray([8, 18, np.nan, 18, 8, 18, 24, 18, 8, 18]) + y2 = np.asarray([18, 11, 8, 11, 18, 26, 32, 30, np.nan, np.nan]) + + fig, ax = plt.subplots() + + ax.plot(x, y1, c='k') + ax.plot(x, y2, c='b') + ax.fill_between(x, y1, y2, where=y2 >= y1, facecolor="green", + interpolate=True, alpha=0.5) + ax.fill_between(x, y1, y2, where=y1 >= y2, facecolor="red", + interpolate=True, alpha=0.5) + + +# test_symlog and test_symlog2 used to have baseline images in all three +# formats, but the png and svg baselines got invalidated by the removal of +# minor tick overstriking. +@image_comparison(['symlog.pdf']) +def test_symlog(): + x = np.array([0, 1, 2, 4, 6, 9, 12, 24]) + y = np.array([1000000, 500000, 100000, 100, 5, 0, 0, 0]) + + fig, ax = plt.subplots() + ax.plot(x, y) + ax.set_yscale('symlog') + ax.set_xscale('linear') + ax.set_ylim(-1, 10000000) + + +@image_comparison(['symlog2.pdf'], remove_text=True) +def test_symlog2(): + # Numbers from -50 to 50, with 0.1 as step + x = np.arange(-50, 50, 0.001) + + fig, axs = plt.subplots(5, 1) + for ax, linthresh in zip(axs, [20., 2., 1., 0.1, 0.01]): + ax.plot(x, x) + ax.set_xscale('symlog', linthresh=linthresh) + ax.grid(True) + axs[-1].set_ylim(-0.1, 0.1) + + +def test_pcolorargs_5205(): + # Smoketest to catch issue found in gh:5205 + x = [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5] + y = [-1.5, -1.25, -1.0, -0.75, -0.5, -0.25, 0, + 0.25, 0.5, 0.75, 1.0, 1.25, 1.5] + X, Y = np.meshgrid(x, y) + Z = np.hypot(X, Y) + + plt.pcolor(Z) + plt.pcolor(list(Z)) + plt.pcolor(x, y, Z[:-1, :-1]) + plt.pcolor(X, Y, list(Z[:-1, :-1])) + + +@image_comparison(['pcolormesh'], remove_text=True) +def test_pcolormesh(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + n = 12 + x = np.linspace(-1.5, 1.5, n) + y = np.linspace(-1.5, 1.5, n*2) + X, Y = np.meshgrid(x, y) + Qx = np.cos(Y) - np.cos(X) + Qz = np.sin(Y) + np.sin(X) + Qx = (Qx + 1.1) + Z = np.hypot(X, Y) / 5 + Z = (Z - Z.min()) / np.ptp(Z) + + # The color array can include masked values: + Zm = ma.masked_where(np.abs(Qz) < 0.5 * np.max(Qz), Z) + + _, (ax1, ax2, ax3) = plt.subplots(1, 3) + ax1.pcolormesh(Qx, Qz, Zm[:-1, :-1], lw=0.5, edgecolors='k') + ax2.pcolormesh(Qx, Qz, Zm[:-1, :-1], lw=2, edgecolors=['b', 'w']) + ax3.pcolormesh(Qx, Qz, Zm, shading="gouraud") + + +@image_comparison(['pcolormesh_small'], extensions=["eps"]) +def test_pcolormesh_small(): + n = 3 + x = np.linspace(-1.5, 1.5, n) + y = np.linspace(-1.5, 1.5, n*2) + X, Y = np.meshgrid(x, y) + Qx = np.cos(Y) - np.cos(X) + Qz = np.sin(Y) + np.sin(X) + Qx = (Qx + 1.1) + Z = np.hypot(X, Y) / 5 + Z = (Z - Z.min()) / np.ptp(Z) + Zm = ma.masked_where(np.abs(Qz) < 0.5 * np.max(Qz), Z) + Zm2 = ma.masked_where(Qz < -0.5 * np.max(Qz), Z) + + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) + ax1.pcolormesh(Qx, Qz, Zm[:-1, :-1], lw=0.5, edgecolors='k') + ax2.pcolormesh(Qx, Qz, Zm[:-1, :-1], lw=2, edgecolors=['b', 'w']) + # gouraud with Zm yields a blank plot; there are no unmasked triangles. + ax3.pcolormesh(Qx, Qz, Zm, shading="gouraud") + # Reduce the masking to get a plot. + ax4.pcolormesh(Qx, Qz, Zm2, shading="gouraud") + + for ax in fig.axes: + ax.set_axis_off() + + +@image_comparison(['pcolormesh_alpha'], extensions=["png", "pdf"], + remove_text=True) +def test_pcolormesh_alpha(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + n = 12 + X, Y = np.meshgrid( + np.linspace(-1.5, 1.5, n), + np.linspace(-1.5, 1.5, n*2) + ) + Qx = X + Qy = Y + np.sin(X) + Z = np.hypot(X, Y) / 5 + Z = (Z - Z.min()) / np.ptp(Z) + vir = mpl.colormaps["viridis"].resampled(16) + # make another colormap with varying alpha + colors = vir(np.arange(16)) + colors[:, 3] = 0.5 + 0.5*np.sin(np.arange(16)) + cmap = mcolors.ListedColormap(colors) + + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) + for ax in ax1, ax2, ax3, ax4: + ax.add_patch(mpatches.Rectangle( + (0, -1.5), 1.5, 3, facecolor=[.7, .1, .1, .5], zorder=0 + )) + # ax1, ax2: constant alpha + ax1.pcolormesh(Qx, Qy, Z[:-1, :-1], cmap=vir, alpha=0.4, + shading='flat', zorder=1) + ax2.pcolormesh(Qx, Qy, Z, cmap=vir, alpha=0.4, shading='gouraud', zorder=1) + # ax3, ax4: alpha from colormap + ax3.pcolormesh(Qx, Qy, Z[:-1, :-1], cmap=cmap, shading='flat', zorder=1) + ax4.pcolormesh(Qx, Qy, Z, cmap=cmap, shading='gouraud', zorder=1) + + +@pytest.mark.parametrize("dims,alpha", [(3, 1), (4, 0.5)]) +@check_figures_equal(extensions=["png"]) +def test_pcolormesh_rgba(fig_test, fig_ref, dims, alpha): + ax = fig_test.subplots() + c = np.ones((5, 6, dims), dtype=float) / 2 + ax.pcolormesh(c) + + ax = fig_ref.subplots() + ax.pcolormesh(c[..., 0], cmap="gray", vmin=0, vmax=1, alpha=alpha) + + +@image_comparison(['pcolormesh_datetime_axis.png'], style='mpl20') +def test_pcolormesh_datetime_axis(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig = plt.figure() + fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15) + base = datetime.datetime(2013, 1, 1) + x = np.array([base + datetime.timedelta(days=d) for d in range(21)]) + y = np.arange(21) + z1, z2 = np.meshgrid(np.arange(20), np.arange(20)) + z = z1 * z2 + plt.subplot(221) + plt.pcolormesh(x[:-1], y[:-1], z[:-1, :-1]) + plt.subplot(222) + plt.pcolormesh(x, y, z) + x = np.repeat(x[np.newaxis], 21, axis=0) + y = np.repeat(y[:, np.newaxis], 21, axis=1) + plt.subplot(223) + plt.pcolormesh(x[:-1, :-1], y[:-1, :-1], z[:-1, :-1]) + plt.subplot(224) + plt.pcolormesh(x, y, z) + for ax in fig.get_axes(): + for label in ax.get_xticklabels(): + label.set_ha('right') + label.set_rotation(30) + + +@image_comparison(['pcolor_datetime_axis.png'], style='mpl20') +def test_pcolor_datetime_axis(): + fig = plt.figure() + fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15) + base = datetime.datetime(2013, 1, 1) + x = np.array([base + datetime.timedelta(days=d) for d in range(21)]) + y = np.arange(21) + z1, z2 = np.meshgrid(np.arange(20), np.arange(20)) + z = z1 * z2 + plt.subplot(221) + plt.pcolor(x[:-1], y[:-1], z[:-1, :-1]) + plt.subplot(222) + plt.pcolor(x, y, z) + x = np.repeat(x[np.newaxis], 21, axis=0) + y = np.repeat(y[:, np.newaxis], 21, axis=1) + plt.subplot(223) + plt.pcolor(x[:-1, :-1], y[:-1, :-1], z[:-1, :-1]) + plt.subplot(224) + plt.pcolor(x, y, z) + for ax in fig.get_axes(): + for label in ax.get_xticklabels(): + label.set_ha('right') + label.set_rotation(30) + + +def test_pcolorargs(): + n = 12 + x = np.linspace(-1.5, 1.5, n) + y = np.linspace(-1.5, 1.5, n*2) + X, Y = np.meshgrid(x, y) + Z = np.hypot(X, Y) / 5 + + _, ax = plt.subplots() + with pytest.raises(TypeError): + ax.pcolormesh(y, x, Z) + with pytest.raises(TypeError): + ax.pcolormesh(X, Y, Z.T) + with pytest.raises(TypeError): + ax.pcolormesh(x, y, Z[:-1, :-1], shading="gouraud") + with pytest.raises(TypeError): + ax.pcolormesh(X, Y, Z[:-1, :-1], shading="gouraud") + x[0] = np.nan + with pytest.raises(ValueError): + ax.pcolormesh(x, y, Z[:-1, :-1]) + with np.errstate(invalid='ignore'): + x = np.ma.array(x, mask=(x < 0)) + with pytest.raises(ValueError): + ax.pcolormesh(x, y, Z[:-1, :-1]) + # Expect a warning with non-increasing coordinates + x = [359, 0, 1] + y = [-10, 10] + X, Y = np.meshgrid(x, y) + Z = np.zeros(X.shape) + with pytest.warns(UserWarning, + match='are not monotonically increasing or decreasing'): + ax.pcolormesh(X, Y, Z, shading='auto') + + +def test_pcolorargs_with_read_only(): + x = np.arange(6).reshape(2, 3) + xmask = np.broadcast_to([False, True, False], x.shape) # read-only array + assert xmask.flags.writeable is False + masked_x = np.ma.array(x, mask=xmask) + plt.pcolormesh(masked_x) + + x = np.linspace(0, 1, 10) + y = np.linspace(0, 1, 10) + X, Y = np.meshgrid(x, y) + Z = np.sin(2 * np.pi * X) * np.cos(2 * np.pi * Y) + mask = np.zeros(10, dtype=bool) + mask[-1] = True + mask = np.broadcast_to(mask, Z.shape) + assert mask.flags.writeable is False + masked_Z = np.ma.array(Z, mask=mask) + plt.pcolormesh(X, Y, masked_Z) + + masked_X = np.ma.array(X, mask=mask) + masked_Y = np.ma.array(Y, mask=mask) + plt.pcolor(masked_X, masked_Y, masked_Z) + + +@check_figures_equal(extensions=["png"]) +def test_pcolornearest(fig_test, fig_ref): + ax = fig_test.subplots() + x = np.arange(0, 10) + y = np.arange(0, 3) + np.random.seed(19680801) + Z = np.random.randn(2, 9) + ax.pcolormesh(x, y, Z, shading='flat') + + ax = fig_ref.subplots() + # specify the centers + x2 = x[:-1] + np.diff(x) / 2 + y2 = y[:-1] + np.diff(y) / 2 + ax.pcolormesh(x2, y2, Z, shading='nearest') + + +@check_figures_equal(extensions=["png"]) +def test_pcolornearestunits(fig_test, fig_ref): + ax = fig_test.subplots() + x = [datetime.datetime.fromtimestamp(x * 3600) for x in range(10)] + y = np.arange(0, 3) + np.random.seed(19680801) + Z = np.random.randn(2, 9) + ax.pcolormesh(x, y, Z, shading='flat') + + ax = fig_ref.subplots() + # specify the centers + x2 = [datetime.datetime.fromtimestamp((x + 0.5) * 3600) for x in range(9)] + y2 = y[:-1] + np.diff(y) / 2 + ax.pcolormesh(x2, y2, Z, shading='nearest') + + +def test_pcolorflaterror(): + fig, ax = plt.subplots() + x = np.arange(0, 9) + y = np.arange(0, 3) + np.random.seed(19680801) + Z = np.random.randn(3, 9) + with pytest.raises(TypeError, match='Dimensions of C'): + ax.pcolormesh(x, y, Z, shading='flat') + + +def test_samesizepcolorflaterror(): + fig, ax = plt.subplots() + x, y = np.meshgrid(np.arange(5), np.arange(3)) + Z = x + y + with pytest.raises(TypeError, match=r".*one smaller than X"): + ax.pcolormesh(x, y, Z, shading='flat') + + +@pytest.mark.parametrize('snap', [False, True]) +@check_figures_equal(extensions=["png"]) +def test_pcolorauto(fig_test, fig_ref, snap): + ax = fig_test.subplots() + x = np.arange(0, 10) + y = np.arange(0, 4) + np.random.seed(19680801) + Z = np.random.randn(3, 9) + # this is the same as flat; note that auto is default + ax.pcolormesh(x, y, Z, snap=snap) + + ax = fig_ref.subplots() + # specify the centers + x2 = x[:-1] + np.diff(x) / 2 + y2 = y[:-1] + np.diff(y) / 2 + # this is same as nearest: + ax.pcolormesh(x2, y2, Z, snap=snap) + + +@image_comparison(['canonical']) +def test_canonical(): + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + + +@image_comparison(['arc_angles.png'], remove_text=True, style='default') +def test_arc_angles(): + # Ellipse parameters + w = 2 + h = 1 + centre = (0.2, 0.5) + scale = 2 + + fig, axs = plt.subplots(3, 3) + for i, ax in enumerate(axs.flat): + theta2 = i * 360 / 9 + theta1 = theta2 - 45 + + ax.add_patch(mpatches.Ellipse(centre, w, h, alpha=0.3)) + ax.add_patch(mpatches.Arc(centre, w, h, theta1=theta1, theta2=theta2)) + # Straight lines intersecting start and end of arc + ax.plot([scale * np.cos(np.deg2rad(theta1)) + centre[0], + centre[0], + scale * np.cos(np.deg2rad(theta2)) + centre[0]], + [scale * np.sin(np.deg2rad(theta1)) + centre[1], + centre[1], + scale * np.sin(np.deg2rad(theta2)) + centre[1]]) + + ax.set_xlim(-scale, scale) + ax.set_ylim(-scale, scale) + + # This looks the same, but it triggers a different code path when it + # gets large enough. + w *= 10 + h *= 10 + centre = (centre[0] * 10, centre[1] * 10) + scale *= 10 + + +@image_comparison(['arc_ellipse'], remove_text=True) +def test_arc_ellipse(): + xcenter, ycenter = 0.38, 0.52 + width, height = 1e-1, 3e-1 + angle = -30 + + theta = np.deg2rad(np.arange(360)) + x = width / 2. * np.cos(theta) + y = height / 2. * np.sin(theta) + + rtheta = np.deg2rad(angle) + R = np.array([ + [np.cos(rtheta), -np.sin(rtheta)], + [np.sin(rtheta), np.cos(rtheta)]]) + + x, y = np.dot(R, [x, y]) + x += xcenter + y += ycenter + + fig = plt.figure() + ax = fig.add_subplot(211, aspect='auto') + ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', + linewidth=1, zorder=1) + + e1 = mpatches.Arc((xcenter, ycenter), width, height, + angle=angle, linewidth=2, fill=False, zorder=2) + + ax.add_patch(e1) + + ax = fig.add_subplot(212, aspect='equal') + ax.fill(x, y, alpha=0.2, facecolor='green', edgecolor='green', zorder=1) + e2 = mpatches.Arc((xcenter, ycenter), width, height, + angle=angle, linewidth=2, fill=False, zorder=2) + + ax.add_patch(e2) + + +def test_marker_as_markerstyle(): + fix, ax = plt.subplots() + m = mmarkers.MarkerStyle('o') + ax.plot([1, 2, 3], [3, 2, 1], marker=m) + ax.scatter([1, 2, 3], [4, 3, 2], marker=m) + ax.errorbar([1, 2, 3], [5, 4, 3], marker=m) + + +@image_comparison(['markevery'], remove_text=True) +def test_markevery(): + x = np.linspace(0, 10, 100) + y = np.sin(x) * np.sqrt(x/10 + 0.5) + + # check marker only plot + fig, ax = plt.subplots() + ax.plot(x, y, 'o', label='default') + ax.plot(x, y, 'd', markevery=None, label='mark all') + ax.plot(x, y, 's', markevery=10, label='mark every 10') + ax.plot(x, y, '+', markevery=(5, 20), label='mark every 5 starting at 10') + ax.legend() + + +@image_comparison(['markevery_line'], remove_text=True, tol=0.005) +def test_markevery_line(): + # TODO: a slight change in rendering between Inkscape versions may explain + # why one had to introduce a small non-zero tolerance for the SVG test + # to pass. One may try to remove this hack once Travis' Inkscape version + # is modern enough. FWIW, no failure with 0.92.3 on my computer (#11358). + x = np.linspace(0, 10, 100) + y = np.sin(x) * np.sqrt(x/10 + 0.5) + + # check line/marker combos + fig, ax = plt.subplots() + ax.plot(x, y, '-o', label='default') + ax.plot(x, y, '-d', markevery=None, label='mark all') + ax.plot(x, y, '-s', markevery=10, label='mark every 10') + ax.plot(x, y, '-+', markevery=(5, 20), label='mark every 5 starting at 10') + ax.legend() + + +@image_comparison(['markevery_linear_scales'], remove_text=True, tol=0.001) +def test_markevery_linear_scales(): + cases = [None, + 8, + (30, 8), + [16, 24, 30], [0, -1], + slice(100, 200, 3), + 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cols = 3 + gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols) + + delta = 0.11 + x = np.linspace(0, 10 - 2 * delta, 200) + delta + y = np.sin(x) + 1.0 + delta + + for i, case in enumerate(cases): + row = (i // cols) + col = i % cols + plt.subplot(gs[row, col]) + plt.title('markevery=%s' % str(case)) + plt.plot(x, y, 'o', ls='-', ms=4, markevery=case) + + +@image_comparison(['markevery_linear_scales_zoomed'], remove_text=True) +def test_markevery_linear_scales_zoomed(): + cases = [None, + 8, + (30, 8), + [16, 24, 30], [0, -1], + slice(100, 200, 3), + 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cols = 3 + gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols) + + delta = 0.11 + x = np.linspace(0, 10 - 2 * delta, 200) + delta + y = np.sin(x) + 1.0 + delta + + for i, case in enumerate(cases): + row = (i // cols) + col = i % cols + plt.subplot(gs[row, col]) + plt.title('markevery=%s' % str(case)) + plt.plot(x, y, 'o', ls='-', ms=4, markevery=case) + plt.xlim((6, 6.7)) + plt.ylim((1.1, 1.7)) + + +@image_comparison(['markevery_log_scales'], remove_text=True) +def test_markevery_log_scales(): + cases = [None, + 8, + (30, 8), + [16, 24, 30], [0, -1], + slice(100, 200, 3), + 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cols = 3 + gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols) + + delta = 0.11 + x = np.linspace(0, 10 - 2 * delta, 200) + delta + y = np.sin(x) + 1.0 + delta + + for i, case in enumerate(cases): + row = (i // cols) + col = i % cols + plt.subplot(gs[row, col]) + plt.title('markevery=%s' % str(case)) + plt.xscale('log') + plt.yscale('log') + plt.plot(x, y, 'o', ls='-', ms=4, markevery=case) + + +@image_comparison(['markevery_polar'], style='default', remove_text=True) +def test_markevery_polar(): + cases = [None, + 8, + (30, 8), + [16, 24, 30], [0, -1], + slice(100, 200, 3), + 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cols = 3 + gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols) + + r = np.linspace(0, 3.0, 200) + theta = 2 * np.pi * r + + for i, case in enumerate(cases): + row = (i // cols) + col = i % cols + plt.subplot(gs[row, col], polar=True) + plt.title('markevery=%s' % str(case)) + plt.plot(theta, r, 'o', ls='-', ms=4, markevery=case) + + +@image_comparison(['markevery_linear_scales_nans'], remove_text=True) +def test_markevery_linear_scales_nans(): + cases = [None, + 8, + (30, 8), + [16, 24, 30], [0, -1], + slice(100, 200, 3), + 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cols = 3 + gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols) + + delta = 0.11 + x = np.linspace(0, 10 - 2 * delta, 200) + delta + y = np.sin(x) + 1.0 + delta + y[:10] = y[-20:] = y[50:70] = np.nan + + for i, case in enumerate(cases): + row = (i // cols) + col = i % cols + plt.subplot(gs[row, col]) + plt.title('markevery=%s' % str(case)) + plt.plot(x, y, 'o', ls='-', ms=4, markevery=case) + + +@image_comparison(['marker_edges'], remove_text=True) +def test_marker_edges(): + x = np.linspace(0, 1, 10) + fig, ax = plt.subplots() + ax.plot(x, np.sin(x), 'y.', ms=30.0, mew=0, mec='r') + ax.plot(x+0.1, np.sin(x), 'y.', ms=30.0, mew=1, mec='r') + ax.plot(x+0.2, np.sin(x), 'y.', ms=30.0, mew=2, mec='b') + + +@image_comparison(['bar_tick_label_single.png', 'bar_tick_label_single.png']) +def test_bar_tick_label_single(): + # From 2516: plot bar with array of string labels for x axis + ax = plt.gca() + ax.bar(0, 1, align='edge', tick_label='0') + + # Reuse testcase from above for a labeled data test + data = {"a": 0, "b": 1} + fig, ax = plt.subplots() + ax = plt.gca() + ax.bar("a", "b", align='edge', tick_label='0', data=data) + + +def test_nan_bar_values(): + fig, ax = plt.subplots() + ax.bar([0, 1], [np.nan, 4]) + + +def test_bar_ticklabel_fail(): + fig, ax = plt.subplots() + ax.bar([], []) + + +@image_comparison(['bar_tick_label_multiple.png']) +def test_bar_tick_label_multiple(): + # From 2516: plot bar with array of string labels for x axis + ax = plt.gca() + ax.bar([1, 2.5], [1, 2], width=[0.2, 0.5], tick_label=['a', 'b'], + align='center') + + +@image_comparison(['bar_tick_label_multiple_old_label_alignment.png']) +def test_bar_tick_label_multiple_old_alignment(): + # Test that the alignment for class is backward compatible + matplotlib.rcParams["ytick.alignment"] = "center" + ax = plt.gca() + ax.bar([1, 2.5], [1, 2], width=[0.2, 0.5], tick_label=['a', 'b'], + align='center') + + +@check_figures_equal(extensions=["png"]) +def test_bar_decimal_center(fig_test, fig_ref): + ax = fig_test.subplots() + x0 = [1.5, 8.4, 5.3, 4.2] + y0 = [1.1, 2.2, 3.3, 4.4] + x = [Decimal(x) for x in x0] + y = [Decimal(y) for y in y0] + # Test image - vertical, align-center bar chart with Decimal() input + ax.bar(x, y, align='center') + # Reference image + ax = fig_ref.subplots() + ax.bar(x0, y0, align='center') + + +@check_figures_equal(extensions=["png"]) +def test_barh_decimal_center(fig_test, fig_ref): + ax = fig_test.subplots() + x0 = [1.5, 8.4, 5.3, 4.2] + y0 = [1.1, 2.2, 3.3, 4.4] + x = [Decimal(x) for x in x0] + y = [Decimal(y) for y in y0] + # Test image - horizontal, align-center bar chart with Decimal() input + ax.barh(x, y, height=[0.5, 0.5, 1, 1], align='center') + # Reference image + ax = fig_ref.subplots() + ax.barh(x0, y0, height=[0.5, 0.5, 1, 1], align='center') + + +@check_figures_equal(extensions=["png"]) +def test_bar_decimal_width(fig_test, fig_ref): + x = [1.5, 8.4, 5.3, 4.2] + y = [1.1, 2.2, 3.3, 4.4] + w0 = [0.7, 1.45, 1, 2] + w = [Decimal(i) for i in w0] + # Test image - vertical bar chart with Decimal() width + ax = fig_test.subplots() + ax.bar(x, y, width=w, align='center') + # Reference image + ax = fig_ref.subplots() + ax.bar(x, y, width=w0, align='center') + + +@check_figures_equal(extensions=["png"]) +def test_barh_decimal_height(fig_test, fig_ref): + x = [1.5, 8.4, 5.3, 4.2] + y = [1.1, 2.2, 3.3, 4.4] + h0 = [0.7, 1.45, 1, 2] + h = [Decimal(i) for i in h0] + # Test image - horizontal bar chart with Decimal() height + ax = fig_test.subplots() + ax.barh(x, y, height=h, align='center') + # Reference image + ax = fig_ref.subplots() + ax.barh(x, y, height=h0, align='center') + + +def test_bar_color_none_alpha(): + ax = plt.gca() + rects = ax.bar([1, 2], [2, 4], alpha=0.3, color='none', edgecolor='r') + for rect in rects: + assert rect.get_facecolor() == (0, 0, 0, 0) + assert rect.get_edgecolor() == (1, 0, 0, 0.3) + + +def test_bar_edgecolor_none_alpha(): + ax = plt.gca() + rects = ax.bar([1, 2], [2, 4], alpha=0.3, color='r', edgecolor='none') + for rect in rects: + assert rect.get_facecolor() == (1, 0, 0, 0.3) + assert rect.get_edgecolor() == (0, 0, 0, 0) + + +@image_comparison(['barh_tick_label.png']) +def test_barh_tick_label(): + # From 2516: plot barh with array of string labels for y axis + ax = plt.gca() + ax.barh([1, 2.5], [1, 2], height=[0.2, 0.5], tick_label=['a', 'b'], + align='center') + + +def test_bar_timedelta(): + """Smoketest that bar can handle width and height in delta units.""" + fig, ax = plt.subplots() + ax.bar(datetime.datetime(2018, 1, 1), 1., + width=datetime.timedelta(hours=3)) + ax.bar(datetime.datetime(2018, 1, 1), 1., + xerr=datetime.timedelta(hours=2), + width=datetime.timedelta(hours=3)) + fig, ax = plt.subplots() + ax.barh(datetime.datetime(2018, 1, 1), 1, + height=datetime.timedelta(hours=3)) + ax.barh(datetime.datetime(2018, 1, 1), 1, + height=datetime.timedelta(hours=3), + yerr=datetime.timedelta(hours=2)) + fig, ax = plt.subplots() + ax.barh([datetime.datetime(2018, 1, 1), datetime.datetime(2018, 1, 1)], + np.array([1, 1.5]), + height=datetime.timedelta(hours=3)) + ax.barh([datetime.datetime(2018, 1, 1), datetime.datetime(2018, 1, 1)], + np.array([1, 1.5]), + height=[datetime.timedelta(hours=t) for t in [1, 2]]) + ax.broken_barh([(datetime.datetime(2018, 1, 1), + datetime.timedelta(hours=1))], + (10, 20)) + + +def test_bar_datetime_start(): + """test that tickers are correct for datetimes""" + start = np.array([np.datetime64('2012-01-01'), np.datetime64('2012-02-01'), + np.datetime64('2012-01-15')]) + stop = np.array([np.datetime64('2012-02-07'), np.datetime64('2012-02-13'), + np.datetime64('2012-02-12')]) + + fig, ax = plt.subplots() + ax.bar([0, 1, 3], height=stop-start, bottom=start) + assert isinstance(ax.yaxis.get_major_formatter(), mdates.AutoDateFormatter) + + fig, ax = plt.subplots() + ax.barh([0, 1, 3], width=stop-start, left=start) + assert isinstance(ax.xaxis.get_major_formatter(), mdates.AutoDateFormatter) + + +def test_boxplot_dates_pandas(pd): + # smoke test for boxplot and dates in pandas + data = np.random.rand(5, 2) + years = pd.date_range('1/1/2000', + periods=2, freq=pd.DateOffset(years=1)).year + plt.figure() + plt.boxplot(data, positions=years) + + +def test_boxplot_capwidths(): + data = np.random.rand(5, 3) + fig, axs = plt.subplots(9) + + axs[0].boxplot(data, capwidths=[0.3, 0.2, 0.1], widths=[0.1, 0.2, 0.3]) + axs[1].boxplot(data, capwidths=[0.3, 0.2, 0.1], widths=0.2) + axs[2].boxplot(data, capwidths=[0.3, 0.2, 0.1]) + + axs[3].boxplot(data, capwidths=0.5, widths=[0.1, 0.2, 0.3]) + axs[4].boxplot(data, capwidths=0.5, widths=0.2) + axs[5].boxplot(data, capwidths=0.5) + + axs[6].boxplot(data, widths=[0.1, 0.2, 0.3]) + axs[7].boxplot(data, widths=0.2) + axs[8].boxplot(data) + + +def test_pcolor_regression(pd): + from pandas.plotting import ( + register_matplotlib_converters, + deregister_matplotlib_converters, + ) + + fig = plt.figure() + ax = fig.add_subplot(111) + + times = [datetime.datetime(2021, 1, 1)] + while len(times) < 7: + times.append(times[-1] + datetime.timedelta(seconds=120)) + + y_vals = np.arange(5) + + time_axis, y_axis = np.meshgrid(times, y_vals) + shape = (len(y_vals) - 1, len(times) - 1) + z_data = np.arange(shape[0] * shape[1]) + + z_data.shape = shape + try: + register_matplotlib_converters() + + im = ax.pcolormesh(time_axis, y_axis, z_data) + # make sure this does not raise! + fig.canvas.draw() + finally: + deregister_matplotlib_converters() + + +def test_bar_pandas(pd): + # Smoke test for pandas + df = pd.DataFrame( + {'year': [2018, 2018, 2018], + 'month': [1, 1, 1], + 'day': [1, 2, 3], + 'value': [1, 2, 3]}) + df['date'] = pd.to_datetime(df[['year', 'month', 'day']]) + + monthly = df[['date', 'value']].groupby(['date']).sum() + dates = monthly.index + forecast = monthly['value'] + baseline = monthly['value'] + + fig, ax = plt.subplots() + ax.bar(dates, forecast, width=10, align='center') + ax.plot(dates, baseline, color='orange', lw=4) + + +def test_bar_pandas_indexed(pd): + # Smoke test for indexed pandas + df = pd.DataFrame({"x": [1., 2., 3.], "width": [.2, .4, .6]}, + index=[1, 2, 3]) + fig, ax = plt.subplots() + ax.bar(df.x, 1., width=df.width) + + +@mpl.style.context('default') +@check_figures_equal() +def test_bar_hatches(fig_test, fig_ref): + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + + x = [1, 2] + y = [2, 3] + hatches = ['x', 'o'] + for i in range(2): + ax_ref.bar(x[i], y[i], color='C0', hatch=hatches[i]) + + ax_test.bar(x, y, hatch=hatches) + + +@pytest.mark.parametrize( + ("x", "width", "label", "expected_labels", "container_label"), + [ + ("x", 1, "x", ["_nolegend_"], "x"), + (["a", "b", "c"], [10, 20, 15], ["A", "B", "C"], + ["A", "B", "C"], "_nolegend_"), + (["a", "b", "c"], [10, 20, 15], ["R", "Y", "_nolegend_"], + ["R", "Y", "_nolegend_"], "_nolegend_"), + (["a", "b", "c"], [10, 20, 15], "bars", + ["_nolegend_", "_nolegend_", "_nolegend_"], "bars"), + ] +) +def test_bar_labels(x, width, label, expected_labels, container_label): + _, ax = plt.subplots() + bar_container = ax.bar(x, width, label=label) + bar_labels = [bar.get_label() for bar in bar_container] + assert expected_labels == bar_labels + assert bar_container.get_label() == container_label + + +def test_bar_labels_length(): + _, ax = plt.subplots() + with pytest.raises(ValueError): + ax.bar(["x", "y"], [1, 2], label=["X", "Y", "Z"]) + _, ax = plt.subplots() + with pytest.raises(ValueError): + ax.bar(["x", "y"], [1, 2], label=["X"]) + + +def test_pandas_minimal_plot(pd): + # smoke test that series and index objects do not warn + for x in [pd.Series([1, 2], dtype="float64"), + pd.Series([1, 2], dtype="Float64")]: + plt.plot(x, x) + plt.plot(x.index, x) + plt.plot(x) + plt.plot(x.index) + df = pd.DataFrame({'col': [1, 2, 3]}) + plt.plot(df) + plt.plot(df, df) + + +@image_comparison(['hist_log'], remove_text=True) +def test_hist_log(): + data0 = np.linspace(0, 1, 200)**3 + data = np.concatenate([1 - data0, 1 + data0]) + fig, ax = plt.subplots() + ax.hist(data, fill=False, log=True) + + +@check_figures_equal(extensions=["png"]) +def test_hist_log_2(fig_test, fig_ref): + axs_test = fig_test.subplots(2, 3) + axs_ref = fig_ref.subplots(2, 3) + for i, histtype in enumerate(["bar", "step", "stepfilled"]): + # Set log scale, then call hist(). + axs_test[0, i].set_yscale("log") + axs_test[0, i].hist(1, 1, histtype=histtype) + # Call hist(), then set log scale. + axs_test[1, i].hist(1, 1, histtype=histtype) + axs_test[1, i].set_yscale("log") + # Use hist(..., log=True). + for ax in axs_ref[:, i]: + ax.hist(1, 1, log=True, histtype=histtype) + + +def test_hist_log_barstacked(): + fig, axs = plt.subplots(2) + axs[0].hist([[0], [0, 1]], 2, histtype="barstacked") + axs[0].set_yscale("log") + axs[1].hist([0, 0, 1], 2, histtype="barstacked") + axs[1].set_yscale("log") + fig.canvas.draw() + assert axs[0].get_ylim() == axs[1].get_ylim() + + +@image_comparison(['hist_bar_empty.png'], remove_text=True) +def test_hist_bar_empty(): + # From #3886: creating hist from empty dataset raises ValueError + ax = plt.gca() + ax.hist([], histtype='bar') + + +def test_hist_float16(): + np.random.seed(19680801) + values = np.clip( + np.random.normal(0.5, 0.3, size=1000), 0, 1).astype(np.float16) + h = plt.hist(values, bins=3, alpha=0.5) + bc = h[2] + # Check that there are no overlapping rectangles + for r in range(1, len(bc)): + rleft = bc[r-1].get_corners() + rright = bc[r].get_corners() + # right hand position of left rectangle <= + # left hand position of right rectangle + assert rleft[1][0] <= rright[0][0] + + +@image_comparison(['hist_step_empty.png'], remove_text=True) +def test_hist_step_empty(): + # From #3886: creating hist from empty dataset raises ValueError + ax = plt.gca() + ax.hist([], histtype='step') + + +@image_comparison(['hist_step_filled.png'], remove_text=True) +def test_hist_step_filled(): + np.random.seed(0) + x = np.random.randn(1000, 3) + n_bins = 10 + + kwargs = [{'fill': True}, {'fill': False}, {'fill': None}, {}]*2 + types = ['step']*4+['stepfilled']*4 + fig, axs = plt.subplots(nrows=2, ncols=4) + + for kg, _type, ax in zip(kwargs, types, axs.flat): + ax.hist(x, n_bins, histtype=_type, stacked=True, **kg) + ax.set_title(f'{kg}/{_type}') + ax.set_ylim(bottom=-50) + + patches = axs[0, 0].patches + assert all(p.get_facecolor() == p.get_edgecolor() for p in patches) + + +@image_comparison(['hist_density.png']) +def test_hist_density(): + np.random.seed(19680801) + data = np.random.standard_normal(2000) + fig, ax = plt.subplots() + ax.hist(data, density=True) + + +def test_hist_unequal_bins_density(): + # Test correct behavior of normalized histogram with unequal bins + # https://github.com/matplotlib/matplotlib/issues/9557 + rng = np.random.RandomState(57483) + t = rng.randn(100) + bins = [-3, -1, -0.5, 0, 1, 5] + mpl_heights, _, _ = plt.hist(t, bins=bins, density=True) + np_heights, _ = np.histogram(t, bins=bins, density=True) + assert_allclose(mpl_heights, np_heights) + + +def test_hist_datetime_datasets(): + data = [[datetime.datetime(2017, 1, 1), datetime.datetime(2017, 1, 1)], + [datetime.datetime(2017, 1, 1), datetime.datetime(2017, 1, 2)]] + fig, ax = plt.subplots() + ax.hist(data, stacked=True) + ax.hist(data, stacked=False) + + +@pytest.mark.parametrize("bins_preprocess", + [mpl.dates.date2num, + lambda bins: bins, + lambda bins: np.asarray(bins, 'datetime64')], + ids=['date2num', 'datetime.datetime', + 'np.datetime64']) +def test_hist_datetime_datasets_bins(bins_preprocess): + data = [[datetime.datetime(2019, 1, 5), datetime.datetime(2019, 1, 11), + datetime.datetime(2019, 2, 1), datetime.datetime(2019, 3, 1)], + [datetime.datetime(2019, 1, 11), datetime.datetime(2019, 2, 5), + datetime.datetime(2019, 2, 18), datetime.datetime(2019, 3, 1)]] + + date_edges = [datetime.datetime(2019, 1, 1), datetime.datetime(2019, 2, 1), + datetime.datetime(2019, 3, 1)] + + fig, ax = plt.subplots() + _, bins, _ = ax.hist(data, bins=bins_preprocess(date_edges), stacked=True) + np.testing.assert_allclose(bins, mpl.dates.date2num(date_edges)) + + _, bins, _ = ax.hist(data, bins=bins_preprocess(date_edges), stacked=False) + np.testing.assert_allclose(bins, mpl.dates.date2num(date_edges)) + + +@pytest.mark.parametrize('data, expected_number_of_hists', + [([], 1), + ([[]], 1), + ([[], []], 2)]) +def test_hist_with_empty_input(data, expected_number_of_hists): + hists, _, _ = plt.hist(data) + hists = np.asarray(hists) + + if hists.ndim == 1: + assert 1 == expected_number_of_hists + else: + assert hists.shape[0] == expected_number_of_hists + + +@pytest.mark.parametrize("histtype, zorder", + [("bar", mpl.patches.Patch.zorder), + ("step", mpl.lines.Line2D.zorder), + ("stepfilled", mpl.patches.Patch.zorder)]) +def test_hist_zorder(histtype, zorder): + ax = plt.figure().add_subplot() + ax.hist([1, 2], histtype=histtype) + assert ax.patches + for patch in ax.patches: + assert patch.get_zorder() == zorder + + +@check_figures_equal(extensions=['png']) +def test_stairs(fig_test, fig_ref): + import matplotlib.lines as mlines + y = np.array([6, 14, 32, 37, 48, 32, 21, 4]) # hist + x = np.array([1., 2., 3., 4., 5., 6., 7., 8., 9.]) # bins + + test_axes = fig_test.subplots(3, 2).flatten() + test_axes[0].stairs(y, x, baseline=None) + test_axes[1].stairs(y, x, baseline=None, orientation='horizontal') + test_axes[2].stairs(y, x) + test_axes[3].stairs(y, x, orientation='horizontal') + test_axes[4].stairs(y, x) + test_axes[4].semilogy() + test_axes[5].stairs(y, x, orientation='horizontal') + test_axes[5].semilogx() + + # defaults of `PathPatch` to be used for all following Line2D + style = {'solid_joinstyle': 'miter', 'solid_capstyle': 'butt'} + + ref_axes = fig_ref.subplots(3, 2).flatten() + ref_axes[0].plot(x, np.append(y, y[-1]), drawstyle='steps-post', **style) + ref_axes[1].plot(np.append(y[0], y), x, drawstyle='steps-post', **style) + + ref_axes[2].plot(x, np.append(y, y[-1]), drawstyle='steps-post', **style) + ref_axes[2].add_line(mlines.Line2D([x[0], x[0]], [0, y[0]], **style)) + ref_axes[2].add_line(mlines.Line2D([x[-1], x[-1]], [0, y[-1]], **style)) + ref_axes[2].set_ylim(0, None) + + ref_axes[3].plot(np.append(y[0], y), x, drawstyle='steps-post', **style) + ref_axes[3].add_line(mlines.Line2D([0, y[0]], [x[0], x[0]], **style)) + ref_axes[3].add_line(mlines.Line2D([0, y[-1]], [x[-1], x[-1]], **style)) + ref_axes[3].set_xlim(0, None) + + ref_axes[4].plot(x, np.append(y, y[-1]), drawstyle='steps-post', **style) + ref_axes[4].add_line(mlines.Line2D([x[0], x[0]], [0, y[0]], **style)) + ref_axes[4].add_line(mlines.Line2D([x[-1], x[-1]], [0, y[-1]], **style)) + ref_axes[4].semilogy() + + ref_axes[5].plot(np.append(y[0], y), x, drawstyle='steps-post', **style) + ref_axes[5].add_line(mlines.Line2D([0, y[0]], [x[0], x[0]], **style)) + ref_axes[5].add_line(mlines.Line2D([0, y[-1]], [x[-1], x[-1]], **style)) + ref_axes[5].semilogx() + + +@check_figures_equal(extensions=['png']) +def test_stairs_fill(fig_test, fig_ref): + h, bins = [1, 2, 3, 4, 2], [0, 1, 2, 3, 4, 5] + bs = -2 + # Test + test_axes = fig_test.subplots(2, 2).flatten() + test_axes[0].stairs(h, bins, fill=True) + test_axes[1].stairs(h, bins, orientation='horizontal', fill=True) + test_axes[2].stairs(h, bins, baseline=bs, fill=True) + test_axes[3].stairs(h, bins, baseline=bs, orientation='horizontal', + fill=True) + + # # Ref + ref_axes = fig_ref.subplots(2, 2).flatten() + ref_axes[0].fill_between(bins, np.append(h, h[-1]), step='post', lw=0) + ref_axes[0].set_ylim(0, None) + ref_axes[1].fill_betweenx(bins, np.append(h, h[-1]), step='post', lw=0) + ref_axes[1].set_xlim(0, None) + ref_axes[2].fill_between(bins, np.append(h, h[-1]), + np.ones(len(h)+1)*bs, step='post', lw=0) + ref_axes[2].set_ylim(bs, None) + ref_axes[3].fill_betweenx(bins, np.append(h, h[-1]), + np.ones(len(h)+1)*bs, step='post', lw=0) + ref_axes[3].set_xlim(bs, None) + + +@check_figures_equal(extensions=['png']) +def test_stairs_update(fig_test, fig_ref): + # fixed ylim because stairs() does autoscale, but updating data does not + ylim = -3, 4 + # Test + test_ax = fig_test.add_subplot() + h = test_ax.stairs([1, 2, 3]) + test_ax.set_ylim(ylim) + h.set_data([3, 2, 1]) + h.set_data(edges=np.arange(4)+2) + h.set_data([1, 2, 1], np.arange(4)/2) + h.set_data([1, 2, 3]) + h.set_data(None, np.arange(4)) + assert np.allclose(h.get_data()[0], np.arange(1, 4)) + assert np.allclose(h.get_data()[1], np.arange(4)) + h.set_data(baseline=-2) + assert h.get_data().baseline == -2 + + # Ref + ref_ax = fig_ref.add_subplot() + h = ref_ax.stairs([1, 2, 3], baseline=-2) + ref_ax.set_ylim(ylim) + + +@check_figures_equal(extensions=['png']) +def test_stairs_baseline_0(fig_test, fig_ref): + # Test + test_ax = fig_test.add_subplot() + test_ax.stairs([5, 6, 7], baseline=None) + + # Ref + ref_ax = fig_ref.add_subplot() + style = {'solid_joinstyle': 'miter', 'solid_capstyle': 'butt'} + ref_ax.plot(range(4), [5, 6, 7, 7], drawstyle='steps-post', **style) + ref_ax.set_ylim(0, None) + + +def test_stairs_empty(): + ax = plt.figure().add_subplot() + ax.stairs([], [42]) + assert ax.get_xlim() == (39, 45) + assert ax.get_ylim() == (-0.06, 0.06) + + +def test_stairs_invalid_nan(): + with pytest.raises(ValueError, match='Nan values in "edges"'): + plt.stairs([1, 2], [0, np.nan, 1]) + + +def test_stairs_invalid_mismatch(): + with pytest.raises(ValueError, match='Size mismatch'): + plt.stairs([1, 2], [0, 1]) + + +def test_stairs_invalid_update(): + h = plt.stairs([1, 2], [0, 1, 2]) + with pytest.raises(ValueError, match='Nan values in "edges"'): + h.set_data(edges=[1, np.nan, 2]) + + +def test_stairs_invalid_update2(): + h = plt.stairs([1, 2], [0, 1, 2]) + with pytest.raises(ValueError, match='Size mismatch'): + h.set_data(edges=np.arange(5)) + + +@image_comparison(['test_stairs_options.png'], remove_text=True) +def test_stairs_options(): + x, y = np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4]).astype(float) + yn = y.copy() + yn[1] = np.nan + + fig, ax = plt.subplots() + ax.stairs(y*3, x, color='green', fill=True, label="A") + ax.stairs(y, x*3-3, color='red', fill=True, + orientation='horizontal', label="B") + ax.stairs(yn, x, color='orange', ls='--', lw=2, label="C") + ax.stairs(yn/3, x*3-2, ls='--', lw=2, baseline=0.5, + orientation='horizontal', label="D") + ax.stairs(y[::-1]*3+13, x-1, color='red', ls='--', lw=2, baseline=None, + label="E") + ax.stairs(y[::-1]*3+14, x, baseline=26, + color='purple', ls='--', lw=2, label="F") + ax.stairs(yn[::-1]*3+15, x+1, baseline=np.linspace(27, 25, len(y)), + color='blue', ls='--', label="G", fill=True) + ax.stairs(y[:-1][::-1]*2+11, x[:-1]+0.5, color='black', ls='--', lw=2, + baseline=12, hatch='//', label="H") + ax.legend(loc=0) + + +@image_comparison(['test_stairs_datetime.png']) +def test_stairs_datetime(): + f, ax = plt.subplots(constrained_layout=True) + ax.stairs(np.arange(36), + np.arange(np.datetime64('2001-12-27'), + np.datetime64('2002-02-02'))) + plt.xticks(rotation=30) + + +@check_figures_equal(extensions=['png']) +def test_stairs_edge_handling(fig_test, fig_ref): + # Test + test_ax = fig_test.add_subplot() + test_ax.stairs([1, 2, 3], color='red', fill=True) + + # Ref + ref_ax = fig_ref.add_subplot() + st = ref_ax.stairs([1, 2, 3], fill=True) + st.set_color('red') + + +def contour_dat(): + x = np.linspace(-3, 5, 150) + y = np.linspace(-3, 5, 120) + z = np.cos(x) + np.sin(y[:, np.newaxis]) + return x, y, z + + +@image_comparison(['contour_hatching'], remove_text=True, style='mpl20') +def test_contour_hatching(): + x, y, z = contour_dat() + fig, ax = plt.subplots() + ax.contourf(x, y, z, 7, hatches=['/', '\\', '//', '-'], + cmap=mpl.colormaps['gray'], + extend='both', alpha=0.5) + + +@image_comparison( + ['contour_colorbar'], style='mpl20', + tol=0.54 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_contour_colorbar(): + x, y, z = contour_dat() + + fig, ax = plt.subplots() + cs = ax.contourf(x, y, z, levels=np.arange(-1.8, 1.801, 0.2), + cmap=mpl.colormaps['RdBu'], + vmin=-0.6, + vmax=0.6, + extend='both') + cs1 = ax.contour(x, y, z, levels=np.arange(-2.2, -0.599, 0.2), + colors=['y'], + linestyles='solid', + linewidths=2) + cs2 = ax.contour(x, y, z, levels=np.arange(0.6, 2.2, 0.2), + colors=['c'], + linewidths=2) + cbar = fig.colorbar(cs, ax=ax) + cbar.add_lines(cs1) + cbar.add_lines(cs2, erase=False) + + +@image_comparison(['hist2d', 'hist2d'], remove_text=True, style='mpl20') +def test_hist2d(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + np.random.seed(0) + # make it not symmetric in case we switch x and y axis + x = np.random.randn(100)*2+5 + y = np.random.randn(100)-2 + fig, ax = plt.subplots() + ax.hist2d(x, y, bins=10, rasterized=True) + + # Reuse testcase from above for a labeled data test + data = {"x": x, "y": y} + fig, ax = plt.subplots() + ax.hist2d("x", "y", bins=10, data=data, rasterized=True) + + +@image_comparison(['hist2d_transpose'], remove_text=True, style='mpl20') +def test_hist2d_transpose(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + np.random.seed(0) + # make sure the output from np.histogram is transposed before + # passing to pcolorfast + x = np.array([5]*100) + y = np.random.randn(100)-2 + fig, ax = plt.subplots() + ax.hist2d(x, y, bins=10, rasterized=True) + + +def test_hist2d_density(): + x, y = np.random.random((2, 100)) + ax = plt.figure().subplots() + for obj in [ax, plt]: + obj.hist2d(x, y, density=True) + + +class TestScatter: + @image_comparison(['scatter'], style='mpl20', remove_text=True) + def test_scatter_plot(self): + data = {"x": np.array([3, 4, 2, 6]), "y": np.array([2, 5, 2, 3]), + "c": ['r', 'y', 'b', 'lime'], "s": [24, 15, 19, 29], + "c2": ['0.5', '0.6', '0.7', '0.8']} + + fig, ax = plt.subplots() + ax.scatter(data["x"] - 1., data["y"] - 1., c=data["c"], s=data["s"]) + ax.scatter(data["x"] + 1., data["y"] + 1., c=data["c2"], s=data["s"]) + ax.scatter("x", "y", c="c", s="s", data=data) + + @image_comparison(['scatter_marker.png'], remove_text=True) + def test_scatter_marker(self): + fig, (ax0, ax1, ax2) = plt.subplots(ncols=3) + ax0.scatter([3, 4, 2, 6], [2, 5, 2, 3], + c=[(1, 0, 0), 'y', 'b', 'lime'], + s=[60, 50, 40, 30], + edgecolors=['k', 'r', 'g', 'b'], + marker='s') + ax1.scatter([3, 4, 2, 6], [2, 5, 2, 3], + c=[(1, 0, 0), 'y', 'b', 'lime'], + s=[60, 50, 40, 30], + edgecolors=['k', 'r', 'g', 'b'], + marker=mmarkers.MarkerStyle('o', fillstyle='top')) + # unit area ellipse + rx, ry = 3, 1 + area = rx * ry * np.pi + theta = np.linspace(0, 2 * np.pi, 21) + verts = np.column_stack([np.cos(theta) * rx / area, + np.sin(theta) * ry / area]) + ax2.scatter([3, 4, 2, 6], [2, 5, 2, 3], + c=[(1, 0, 0), 'y', 'b', 'lime'], + s=[60, 50, 40, 30], + edgecolors=['k', 'r', 'g', 'b'], + marker=verts) + + @image_comparison(['scatter_2D'], remove_text=True, extensions=['png']) + def test_scatter_2D(self): + x = np.arange(3) + y = np.arange(2) + x, y = np.meshgrid(x, y) + z = x + y + fig, ax = plt.subplots() + ax.scatter(x, y, c=z, s=200, edgecolors='face') + + @check_figures_equal(extensions=["png"]) + def test_scatter_decimal(self, fig_test, fig_ref): + x0 = np.array([1.5, 8.4, 5.3, 4.2]) + y0 = np.array([1.1, 2.2, 3.3, 4.4]) + x = np.array([Decimal(i) for i in x0]) + y = np.array([Decimal(i) for i in y0]) + c = ['r', 'y', 'b', 'lime'] + s = [24, 15, 19, 29] + # Test image - scatter plot with Decimal() input + ax = fig_test.subplots() + ax.scatter(x, y, c=c, s=s) + # Reference image + ax = fig_ref.subplots() + ax.scatter(x0, y0, c=c, s=s) + + def test_scatter_color(self): + # Try to catch cases where 'c' kwarg should have been used. + with pytest.raises(ValueError): + plt.scatter([1, 2], [1, 2], color=[0.1, 0.2]) + with pytest.raises(ValueError): + plt.scatter([1, 2, 3], [1, 2, 3], color=[1, 2, 3]) + + @pytest.mark.parametrize('kwargs', + [ + {'cmap': 'gray'}, + {'norm': mcolors.Normalize()}, + {'vmin': 0}, + {'vmax': 0} + ]) + def test_scatter_color_warning(self, kwargs): + warn_match = "No data for colormapping provided " + # Warn for cases where 'cmap', 'norm', 'vmin', 'vmax' + # kwargs are being overridden + with pytest.warns(Warning, match=warn_match): + plt.scatter([], [], **kwargs) + with pytest.warns(Warning, match=warn_match): + plt.scatter([1, 2], [3, 4], c=[], **kwargs) + # Do not warn for cases where 'c' matches 'x' and 'y' + plt.scatter([], [], c=[], **kwargs) + plt.scatter([1, 2], [3, 4], c=[4, 5], **kwargs) + + def test_scatter_unfilled(self): + coll = plt.scatter([0, 1, 2], [1, 3, 2], c=['0.1', '0.3', '0.5'], + marker=mmarkers.MarkerStyle('o', fillstyle='none'), + linewidths=[1.1, 1.2, 1.3]) + assert coll.get_facecolors().shape == (0, 4) # no facecolors + assert_array_equal(coll.get_edgecolors(), [[0.1, 0.1, 0.1, 1], + [0.3, 0.3, 0.3, 1], + [0.5, 0.5, 0.5, 1]]) + assert_array_equal(coll.get_linewidths(), [1.1, 1.2, 1.3]) + + @mpl.style.context('default') + def test_scatter_unfillable(self): + coll = plt.scatter([0, 1, 2], [1, 3, 2], c=['0.1', '0.3', '0.5'], + marker='x', + linewidths=[1.1, 1.2, 1.3]) + assert_array_equal(coll.get_facecolors(), coll.get_edgecolors()) + assert_array_equal(coll.get_edgecolors(), [[0.1, 0.1, 0.1, 1], + [0.3, 0.3, 0.3, 1], + [0.5, 0.5, 0.5, 1]]) + assert_array_equal(coll.get_linewidths(), [1.1, 1.2, 1.3]) + + def test_scatter_size_arg_size(self): + x = np.arange(4) + with pytest.raises(ValueError, match='same size as x and y'): + plt.scatter(x, x, x[1:]) + with pytest.raises(ValueError, match='same size as x and y'): + plt.scatter(x[1:], x[1:], x) + with pytest.raises(ValueError, match='float array-like'): + plt.scatter(x, x, 'foo') + + def test_scatter_edgecolor_RGB(self): + # GitHub issue 19066 + coll = plt.scatter([1, 2, 3], [1, np.nan, np.nan], + edgecolor=(1, 0, 0)) + assert mcolors.same_color(coll.get_edgecolor(), (1, 0, 0)) + coll = plt.scatter([1, 2, 3, 4], [1, np.nan, np.nan, 1], + edgecolor=(1, 0, 0, 1)) + assert mcolors.same_color(coll.get_edgecolor(), (1, 0, 0, 1)) + + @check_figures_equal(extensions=["png"]) + def test_scatter_invalid_color(self, fig_test, fig_ref): + ax = fig_test.subplots() + cmap = mpl.colormaps["viridis"].resampled(16) + cmap.set_bad("k", 1) + # Set a nonuniform size to prevent the last call to `scatter` (plotting + # the invalid points separately in fig_ref) from using the marker + # stamping fast path, which would result in slightly offset markers. + ax.scatter(range(4), range(4), + c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4], + cmap=cmap, plotnonfinite=True) + ax = fig_ref.subplots() + cmap = mpl.colormaps["viridis"].resampled(16) + ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap) + ax.scatter([1, 3], [1, 3], s=[2, 4], color="k") + + @check_figures_equal(extensions=["png"]) + def test_scatter_no_invalid_color(self, fig_test, fig_ref): + # With plotnonfinite=False we plot only 2 points. + ax = fig_test.subplots() + cmap = mpl.colormaps["viridis"].resampled(16) + cmap.set_bad("k", 1) + ax.scatter(range(4), range(4), + c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4], + cmap=cmap, plotnonfinite=False) + ax = fig_ref.subplots() + ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap) + + def test_scatter_norm_vminvmax(self): + """Parameters vmin, vmax should error if norm is given.""" + x = [1, 2, 3] + ax = plt.axes() + with pytest.raises(ValueError, + match="Passing a Normalize instance simultaneously " + "with vmin/vmax is not supported."): + ax.scatter(x, x, c=x, norm=mcolors.Normalize(-10, 10), + vmin=0, vmax=5) + + @check_figures_equal(extensions=["png"]) + def test_scatter_single_point(self, fig_test, fig_ref): + ax = fig_test.subplots() + ax.scatter(1, 1, c=1) + ax = fig_ref.subplots() + ax.scatter([1], [1], c=[1]) + + @check_figures_equal(extensions=["png"]) + def test_scatter_different_shapes(self, fig_test, fig_ref): + x = np.arange(10) + ax = fig_test.subplots() + ax.scatter(x, x.reshape(2, 5), c=x.reshape(5, 2)) + ax = fig_ref.subplots() + ax.scatter(x.reshape(5, 2), x, c=x.reshape(2, 5)) + + # Parameters for *test_scatter_c*. NB: assuming that the + # scatter plot will have 4 elements. The tuple scheme is: + # (*c* parameter case, exception regexp key or None if no exception) + params_test_scatter_c = [ + # single string: + ('0.5', None), + # Single letter-sequences + (["rgby"], "conversion"), + # Special cases + ("red", None), + ("none", None), + (None, None), + (["r", "g", "b", "none"], None), + # Non-valid color spec (FWIW, 'jaune' means yellow in French) + ("jaune", "conversion"), + (["jaune"], "conversion"), # wrong type before wrong size + (["jaune"]*4, "conversion"), + # Value-mapping like + ([0.5]*3, None), # should emit a warning for user's eyes though + ([0.5]*4, None), # NB: no warning as matching size allows mapping + ([0.5]*5, "shape"), + # list of strings: + (['0.5', '0.4', '0.6', '0.7'], None), + (['0.5', 'red', '0.6', 'C5'], None), + (['0.5', 0.5, '0.6', 'C5'], "conversion"), + # RGB values + ([[1, 0, 0]], None), + ([[1, 0, 0]]*3, "shape"), + ([[1, 0, 0]]*4, None), + ([[1, 0, 0]]*5, "shape"), + # RGBA values + ([[1, 0, 0, 0.5]], None), + ([[1, 0, 0, 0.5]]*3, "shape"), + ([[1, 0, 0, 0.5]]*4, None), + ([[1, 0, 0, 0.5]]*5, "shape"), + # Mix of valid color specs + ([[1, 0, 0, 0.5]]*3 + [[1, 0, 0]], None), + ([[1, 0, 0, 0.5], "red", "0.0"], "shape"), + ([[1, 0, 0, 0.5], "red", "0.0", "C5"], None), + ([[1, 0, 0, 0.5], "red", "0.0", "C5", [0, 1, 0]], "shape"), + # Mix of valid and non valid color specs + ([[1, 0, 0, 0.5], "red", "jaune"], "conversion"), + ([[1, 0, 0, 0.5], "red", "0.0", "jaune"], "conversion"), + ([[1, 0, 0, 0.5], "red", "0.0", "C5", "jaune"], "conversion"), + ] + + @pytest.mark.parametrize('c_case, re_key', params_test_scatter_c) + def test_scatter_c(self, c_case, re_key): + def get_next_color(): + return 'blue' # currently unused + + xsize = 4 + # Additional checking of *c* (introduced in #11383). + REGEXP = { + "shape": "^'c' argument has [0-9]+ elements", # shape mismatch + "conversion": "^'c' argument must be a color", # bad vals + } + + assert_context = ( + pytest.raises(ValueError, match=REGEXP[re_key]) + if re_key is not None + else pytest.warns(match="argument looks like a single numeric RGB") + if isinstance(c_case, list) and len(c_case) == 3 + else contextlib.nullcontext() + ) + with assert_context: + mpl.axes.Axes._parse_scatter_color_args( + c=c_case, edgecolors="black", kwargs={}, xsize=xsize, + get_next_color_func=get_next_color) + + @mpl.style.context('default') + @check_figures_equal(extensions=["png"]) + def test_scatter_single_color_c(self, fig_test, fig_ref): + rgb = [[1, 0.5, 0.05]] + rgba = [[1, 0.5, 0.05, .5]] + + # set via color kwarg + ax_ref = fig_ref.subplots() + ax_ref.scatter(np.ones(3), range(3), color=rgb) + ax_ref.scatter(np.ones(4)*2, range(4), color=rgba) + + # set via broadcasting via c + ax_test = fig_test.subplots() + ax_test.scatter(np.ones(3), range(3), c=rgb) + ax_test.scatter(np.ones(4)*2, range(4), c=rgba) + + def test_scatter_linewidths(self): + x = np.arange(5) + + fig, ax = plt.subplots() + for i in range(3): + pc = ax.scatter(x, np.full(5, i), c=f'C{i}', marker='x', s=100, + linewidths=i + 1) + assert pc.get_linewidths() == i + 1 + + pc = ax.scatter(x, np.full(5, 3), c='C3', marker='x', s=100, + linewidths=[*range(1, 5), None]) + assert_array_equal(pc.get_linewidths(), + [*range(1, 5), mpl.rcParams['lines.linewidth']]) + + def test_scatter_singular_plural_arguments(self): + + with pytest.raises(TypeError, + match="Got both 'linewidth' and 'linewidths',\ + which are aliases of one another"): + plt.scatter([1, 2, 3], [1, 2, 3], linewidths=[0.5, 0.4, 0.3], linewidth=0.2) + + with pytest.raises(TypeError, + match="Got both 'edgecolor' and 'edgecolors',\ + which are aliases of one another"): + plt.scatter([1, 2, 3], [1, 2, 3], + edgecolors=["#ffffff", "#000000", "#f0f0f0"], + edgecolor="#ffffff") + + with pytest.raises(TypeError, + match="Got both 'facecolors' and 'facecolor',\ + which are aliases of one another"): + plt.scatter([1, 2, 3], [1, 2, 3], + facecolors=["#ffffff", "#000000", "#f0f0f0"], + facecolor="#ffffff") + + +def _params(c=None, xsize=2, *, edgecolors=None, **kwargs): + return (c, edgecolors, kwargs if kwargs is not None else {}, xsize) +_result = namedtuple('_result', 'c, colors') + + +@pytest.mark.parametrize( + 'params, expected_result', + [(_params(), + _result(c='b', colors=np.array([[0, 0, 1, 1]]))), + (_params(c='r'), + _result(c='r', colors=np.array([[1, 0, 0, 1]]))), + (_params(c='r', colors='b'), + _result(c='r', colors=np.array([[1, 0, 0, 1]]))), + # color + (_params(color='b'), + _result(c='b', colors=np.array([[0, 0, 1, 1]]))), + (_params(color=['b', 'g']), + _result(c=['b', 'g'], colors=np.array([[0, 0, 1, 1], [0, .5, 0, 1]]))), + ]) +def test_parse_scatter_color_args(params, expected_result): + def get_next_color(): + return 'blue' # currently unused + + c, colors, _edgecolors = mpl.axes.Axes._parse_scatter_color_args( + *params, get_next_color_func=get_next_color) + assert c == expected_result.c + assert_allclose(colors, expected_result.colors) + +del _params +del _result + + +@pytest.mark.parametrize( + 'kwargs, expected_edgecolors', + [(dict(), None), + (dict(c='b'), None), + (dict(edgecolors='r'), 'r'), + (dict(edgecolors=['r', 'g']), ['r', 'g']), + (dict(edgecolor='r'), 'r'), + (dict(edgecolors='face'), 'face'), + (dict(edgecolors='none'), 'none'), + (dict(edgecolor='r', edgecolors='g'), 'r'), + (dict(c='b', edgecolor='r', edgecolors='g'), 'r'), + (dict(color='r'), 'r'), + (dict(color='r', edgecolor='g'), 'g'), + ]) +def test_parse_scatter_color_args_edgecolors(kwargs, expected_edgecolors): + def get_next_color(): + return 'blue' # currently unused + + c = kwargs.pop('c', None) + edgecolors = kwargs.pop('edgecolors', None) + _, _, result_edgecolors = \ + mpl.axes.Axes._parse_scatter_color_args( + c, edgecolors, kwargs, xsize=2, get_next_color_func=get_next_color) + assert result_edgecolors == expected_edgecolors + + +def test_parse_scatter_color_args_error(): + def get_next_color(): + return 'blue' # currently unused + + with pytest.raises(ValueError, + match="RGBA values should be within 0-1 range"): + c = np.array([[0.1, 0.2, 0.7], [0.2, 0.4, 1.4]]) # value > 1 + mpl.axes.Axes._parse_scatter_color_args( + c, None, kwargs={}, xsize=2, get_next_color_func=get_next_color) + + +def test_as_mpl_axes_api(): + # tests the _as_mpl_axes api + class Polar: + def __init__(self): + self.theta_offset = 0 + + def _as_mpl_axes(self): + # implement the matplotlib axes interface + return PolarAxes, {'theta_offset': self.theta_offset} + + prj = Polar() + prj2 = Polar() + prj2.theta_offset = np.pi + + # testing axes creation with plt.axes + ax = plt.axes((0, 0, 1, 1), projection=prj) + assert type(ax) is PolarAxes + plt.close() + + # testing axes creation with subplot + ax = plt.subplot(121, projection=prj) + assert type(ax) is PolarAxes + plt.close() + + +def test_pyplot_axes(): + # test focusing of Axes in other Figure + fig1, ax1 = plt.subplots() + fig2, ax2 = plt.subplots() + plt.sca(ax1) + assert ax1 is plt.gca() + assert fig1 is plt.gcf() + plt.close(fig1) + plt.close(fig2) + + +def test_log_scales(): + fig, ax = plt.subplots() + ax.plot(np.log(np.linspace(0.1, 100))) + ax.set_yscale('log', base=5.5) + ax.invert_yaxis() + ax.set_xscale('log', base=9.0) + xticks, yticks = [ + [(t.get_loc(), t.label1.get_text()) for t in axis._update_ticks()] + for axis in [ax.xaxis, ax.yaxis] + ] + assert xticks == [ + (1.0, '$\\mathdefault{9^{0}}$'), + (9.0, '$\\mathdefault{9^{1}}$'), + (81.0, '$\\mathdefault{9^{2}}$'), + (2.0, ''), + (3.0, ''), + (4.0, ''), + (5.0, ''), + (6.0, ''), + (7.0, ''), + (8.0, ''), + (18.0, ''), + (27.0, ''), + (36.0, ''), + (45.0, ''), + (54.0, ''), + (63.0, ''), + (72.0, ''), + ] + assert yticks == [ + (0.18181818181818182, '$\\mathdefault{5.5^{-1}}$'), + (1.0, '$\\mathdefault{5.5^{0}}$'), + (5.5, '$\\mathdefault{5.5^{1}}$'), + (0.36363636363636365, ''), + (0.5454545454545454, ''), + (0.7272727272727273, ''), + (0.9090909090909092, ''), + (2.0, ''), + (3.0, ''), + (4.0, ''), + (5.0, ''), + ] + + +def test_log_scales_no_data(): + _, ax = plt.subplots() + ax.set(xscale="log", yscale="log") + ax.xaxis.set_major_locator(mticker.MultipleLocator(1)) + assert ax.get_xlim() == ax.get_ylim() == (1, 10) + + +def test_log_scales_invalid(): + fig, ax = plt.subplots() + ax.set_xscale('log') + with pytest.warns(UserWarning, match='Attempt to set non-positive'): + ax.set_xlim(-1, 10) + ax.set_yscale('log') + with pytest.warns(UserWarning, match='Attempt to set non-positive'): + ax.set_ylim(-1, 10) + + +@image_comparison(['stackplot_test_image', 'stackplot_test_image']) +def test_stackplot(): + fig = plt.figure() + x = np.linspace(0, 10, 10) + y1 = 1.0 * x + y2 = 2.0 * x + 1 + y3 = 3.0 * x + 2 + ax = fig.add_subplot(1, 1, 1) + ax.stackplot(x, y1, y2, y3) + ax.set_xlim((0, 10)) + ax.set_ylim((0, 70)) + + # Reuse testcase from above for a test with labeled data and with colours + # from the Axes property cycle. + data = {"x": x, "y1": y1, "y2": y2, "y3": y3} + fig, ax = plt.subplots() + ax.stackplot("x", "y1", "y2", "y3", data=data, colors=["C0", "C1", "C2"]) + ax.set_xlim((0, 10)) + ax.set_ylim((0, 70)) + + +@image_comparison(['stackplot_test_baseline'], remove_text=True) +def test_stackplot_baseline(): + np.random.seed(0) + + def layers(n, m): + a = np.zeros((m, n)) + for i in range(n): + for j in range(5): + x = 1 / (.1 + np.random.random()) + y = 2 * np.random.random() - .5 + z = 10 / (.1 + np.random.random()) + a[:, i] += x * np.exp(-((np.arange(m) / m - y) * z) ** 2) + return a + + d = layers(3, 100) + d[50, :] = 0 # test for fixed weighted wiggle (issue #6313) + + fig, axs = plt.subplots(2, 2) + + axs[0, 0].stackplot(range(100), d.T, baseline='zero') + axs[0, 1].stackplot(range(100), d.T, baseline='sym') + axs[1, 0].stackplot(range(100), d.T, baseline='wiggle') + axs[1, 1].stackplot(range(100), d.T, baseline='weighted_wiggle') + + +def _bxp_test_helper( + stats_kwargs={}, transform_stats=lambda s: s, bxp_kwargs={}): + np.random.seed(937) + logstats = mpl.cbook.boxplot_stats( + np.random.lognormal(mean=1.25, sigma=1., size=(37, 4)), **stats_kwargs) + fig, ax = plt.subplots() + if bxp_kwargs.get('vert', True): + ax.set_yscale('log') + else: + ax.set_xscale('log') + # Work around baseline images generate back when bxp did not respect the + # boxplot.boxprops.linewidth rcParam when patch_artist is False. + if not bxp_kwargs.get('patch_artist', False): + mpl.rcParams['boxplot.boxprops.linewidth'] = \ + mpl.rcParams['lines.linewidth'] + ax.bxp(transform_stats(logstats), **bxp_kwargs) + + +@image_comparison(['bxp_baseline.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_baseline(): + _bxp_test_helper() + + +@image_comparison(['bxp_rangewhis.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_rangewhis(): + _bxp_test_helper(stats_kwargs=dict(whis=[0, 100])) + + +@image_comparison(['bxp_percentilewhis.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_percentilewhis(): + _bxp_test_helper(stats_kwargs=dict(whis=[5, 95])) + + +@image_comparison(['bxp_with_xlabels.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_with_xlabels(): + def transform(stats): + for s, label in zip(stats, list('ABCD')): + s['label'] = label + return stats + + _bxp_test_helper(transform_stats=transform) + + +@image_comparison(['bxp_horizontal.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default', + tol=0.1) +def test_bxp_horizontal(): + _bxp_test_helper(bxp_kwargs=dict(vert=False)) + + +@image_comparison(['bxp_with_ylabels.png'], + savefig_kwarg={'dpi': 40}, + style='default', + tol=0.1) +def test_bxp_with_ylabels(): + def transform(stats): + for s, label in zip(stats, list('ABCD')): + s['label'] = label + return stats + + _bxp_test_helper(transform_stats=transform, bxp_kwargs=dict(vert=False)) + + +@image_comparison(['bxp_patchartist.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_patchartist(): + _bxp_test_helper(bxp_kwargs=dict(patch_artist=True)) + + +@image_comparison(['bxp_custompatchartist.png'], + remove_text=True, + savefig_kwarg={'dpi': 100}, + style='default') +def test_bxp_custompatchartist(): + _bxp_test_helper(bxp_kwargs=dict( + patch_artist=True, + boxprops=dict(facecolor='yellow', edgecolor='green', ls=':'))) + + +@image_comparison(['bxp_customoutlier.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_customoutlier(): + _bxp_test_helper(bxp_kwargs=dict( + flierprops=dict(linestyle='none', marker='d', mfc='g'))) + + +@image_comparison(['bxp_withmean_custompoint.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_showcustommean(): + _bxp_test_helper(bxp_kwargs=dict( + showmeans=True, + meanprops=dict(linestyle='none', marker='d', mfc='green'), + )) + + +@image_comparison(['bxp_custombox.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_custombox(): + _bxp_test_helper(bxp_kwargs=dict( + boxprops=dict(linestyle='--', color='b', lw=3))) + + +@image_comparison(['bxp_custommedian.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_custommedian(): + _bxp_test_helper(bxp_kwargs=dict( + medianprops=dict(linestyle='--', color='b', lw=3))) + + +@image_comparison(['bxp_customcap.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_customcap(): + _bxp_test_helper(bxp_kwargs=dict( + capprops=dict(linestyle='--', color='g', lw=3))) + + +@image_comparison(['bxp_customwhisker.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_customwhisker(): + _bxp_test_helper(bxp_kwargs=dict( + whiskerprops=dict(linestyle='-', color='m', lw=3))) + + +@check_figures_equal() +def test_boxplot_median_bound_by_box(fig_test, fig_ref): + data = np.arange(3) + medianprops_test = {"linewidth": 12} + medianprops_ref = {**medianprops_test, "solid_capstyle": "butt"} + fig_test.subplots().boxplot(data, medianprops=medianprops_test) + fig_ref.subplots().boxplot(data, medianprops=medianprops_ref) + + +@image_comparison(['bxp_withnotch.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_shownotches(): + _bxp_test_helper(bxp_kwargs=dict(shownotches=True)) + + +@image_comparison(['bxp_nocaps.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_nocaps(): + _bxp_test_helper(bxp_kwargs=dict(showcaps=False)) + + +@image_comparison(['bxp_nobox.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_nobox(): + _bxp_test_helper(bxp_kwargs=dict(showbox=False)) + + +@image_comparison(['bxp_no_flier_stats.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_no_flier_stats(): + def transform(stats): + for s in stats: + s.pop('fliers', None) + return stats + + _bxp_test_helper(transform_stats=transform, + bxp_kwargs=dict(showfliers=False)) + + +@image_comparison(['bxp_withmean_point.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_showmean(): + _bxp_test_helper(bxp_kwargs=dict(showmeans=True, meanline=False)) + + +@image_comparison(['bxp_withmean_line.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_showmeanasline(): + _bxp_test_helper(bxp_kwargs=dict(showmeans=True, meanline=True)) + + +@image_comparison(['bxp_scalarwidth.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_scalarwidth(): + _bxp_test_helper(bxp_kwargs=dict(widths=.25)) + + +@image_comparison(['bxp_customwidths.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_customwidths(): + _bxp_test_helper(bxp_kwargs=dict(widths=[0.10, 0.25, 0.65, 0.85])) + + +@image_comparison(['bxp_custompositions.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_custompositions(): + _bxp_test_helper(bxp_kwargs=dict(positions=[1, 5, 6, 7])) + + +def test_bxp_bad_widths(): + with pytest.raises(ValueError): + _bxp_test_helper(bxp_kwargs=dict(widths=[1])) + + +def test_bxp_bad_positions(): + with pytest.raises(ValueError): + _bxp_test_helper(bxp_kwargs=dict(positions=[2, 3])) + + +@image_comparison(['bxp_custom_capwidths.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_custom_capwidths(): + _bxp_test_helper(bxp_kwargs=dict(capwidths=[0.0, 0.1, 0.5, 1.0])) + + +@image_comparison(['bxp_custom_capwidth.png'], + savefig_kwarg={'dpi': 40}, + style='default') +def test_bxp_custom_capwidth(): + _bxp_test_helper(bxp_kwargs=dict(capwidths=0.6)) + + +def test_bxp_bad_capwidths(): + with pytest.raises(ValueError): + _bxp_test_helper(bxp_kwargs=dict(capwidths=[1])) + + +@image_comparison(['boxplot', 'boxplot'], tol=1.28, style='default') +def test_boxplot(): + # Randomness used for bootstrapping. + np.random.seed(937) + + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + + ax.boxplot([x, x], bootstrap=10000, notch=1) + ax.set_ylim((-30, 30)) + + # Reuse testcase from above for a labeled data test + data = {"x": [x, x]} + fig, ax = plt.subplots() + ax.boxplot("x", bootstrap=10000, notch=1, data=data) + ax.set_ylim((-30, 30)) + + +@image_comparison(['boxplot_custom_capwidths.png'], + savefig_kwarg={'dpi': 40}, style='default') +def test_boxplot_custom_capwidths(): + + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + + ax.boxplot([x, x], notch=1, capwidths=[0.01, 0.2]) + + +@image_comparison(['boxplot_sym2.png'], remove_text=True, style='default') +def test_boxplot_sym2(): + # Randomness used for bootstrapping. + np.random.seed(937) + + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, [ax1, ax2] = plt.subplots(1, 2) + + ax1.boxplot([x, x], bootstrap=10000, sym='^') + ax1.set_ylim((-30, 30)) + + ax2.boxplot([x, x], bootstrap=10000, sym='g') + ax2.set_ylim((-30, 30)) + + +@image_comparison(['boxplot_sym.png'], + remove_text=True, + savefig_kwarg={'dpi': 40}, + style='default') +def test_boxplot_sym(): + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + + ax.boxplot([x, x], sym='gs') + ax.set_ylim((-30, 30)) + + +@image_comparison(['boxplot_autorange_false_whiskers.png', + 'boxplot_autorange_true_whiskers.png'], + style='default') +def test_boxplot_autorange_whiskers(): + # Randomness used for bootstrapping. + np.random.seed(937) + + x = np.ones(140) + x = np.hstack([0, x, 2]) + + fig1, ax1 = plt.subplots() + ax1.boxplot([x, x], bootstrap=10000, notch=1) + ax1.set_ylim((-5, 5)) + + fig2, ax2 = plt.subplots() + ax2.boxplot([x, x], bootstrap=10000, notch=1, autorange=True) + ax2.set_ylim((-5, 5)) + + +def _rc_test_bxp_helper(ax, rc_dict): + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + with matplotlib.rc_context(rc_dict): + ax.boxplot([x, x]) + return ax + + +@image_comparison(['boxplot_rc_parameters'], + savefig_kwarg={'dpi': 100}, remove_text=True, + tol=1, style='default') +def test_boxplot_rc_parameters(): + # Randomness used for bootstrapping. + np.random.seed(937) + + fig, ax = plt.subplots(3) + + rc_axis0 = { + 'boxplot.notch': True, + 'boxplot.whiskers': [5, 95], + 'boxplot.bootstrap': 10000, + + 'boxplot.flierprops.color': 'b', + 'boxplot.flierprops.marker': 'o', + 'boxplot.flierprops.markerfacecolor': 'g', + 'boxplot.flierprops.markeredgecolor': 'b', + 'boxplot.flierprops.markersize': 5, + 'boxplot.flierprops.linestyle': '--', + 'boxplot.flierprops.linewidth': 2.0, + + 'boxplot.boxprops.color': 'r', + 'boxplot.boxprops.linewidth': 2.0, + 'boxplot.boxprops.linestyle': '--', + + 'boxplot.capprops.color': 'c', + 'boxplot.capprops.linewidth': 2.0, + 'boxplot.capprops.linestyle': '--', + + 'boxplot.medianprops.color': 'k', + 'boxplot.medianprops.linewidth': 2.0, + 'boxplot.medianprops.linestyle': '--', + } + + rc_axis1 = { + 'boxplot.vertical': False, + 'boxplot.whiskers': [0, 100], + 'boxplot.patchartist': True, + } + + rc_axis2 = { + 'boxplot.whiskers': 2.0, + 'boxplot.showcaps': False, + 'boxplot.showbox': False, + 'boxplot.showfliers': False, + 'boxplot.showmeans': True, + 'boxplot.meanline': True, + + 'boxplot.meanprops.color': 'c', + 'boxplot.meanprops.linewidth': 2.0, + 'boxplot.meanprops.linestyle': '--', + + 'boxplot.whiskerprops.color': 'r', + 'boxplot.whiskerprops.linewidth': 2.0, + 'boxplot.whiskerprops.linestyle': '-.', + } + dict_list = [rc_axis0, rc_axis1, rc_axis2] + for axis, rc_axis in zip(ax, dict_list): + _rc_test_bxp_helper(axis, rc_axis) + + assert (matplotlib.patches.PathPatch in + [type(t) for t in ax[1].get_children()]) + + +@image_comparison(['boxplot_with_CIarray.png'], + remove_text=True, savefig_kwarg={'dpi': 40}, style='default') +def test_boxplot_with_CIarray(): + # Randomness used for bootstrapping. + np.random.seed(937) + + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + CIs = np.array([[-1.5, 3.], [-1., 3.5]]) + + # show a boxplot with Matplotlib medians and confidence intervals, and + # another with manual values + ax.boxplot([x, x], bootstrap=10000, usermedians=[None, 1.0], + conf_intervals=CIs, notch=1) + ax.set_ylim((-30, 30)) + + +@image_comparison(['boxplot_no_inverted_whisker.png'], + remove_text=True, savefig_kwarg={'dpi': 40}, style='default') +def test_boxplot_no_weird_whisker(): + x = np.array([3, 9000, 150, 88, 350, 200000, 1400, 960], + dtype=np.float64) + ax1 = plt.axes() + ax1.boxplot(x) + ax1.set_yscale('log') + ax1.yaxis.grid(False, which='minor') + ax1.xaxis.grid(False) + + +def test_boxplot_bad_medians(): + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.boxplot(x, usermedians=[1, 2]) + with pytest.raises(ValueError): + ax.boxplot([x, x], usermedians=[[1, 2], [1, 2]]) + + +def test_boxplot_bad_ci(): + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.boxplot([x, x], conf_intervals=[[1, 2]]) + with pytest.raises(ValueError): + ax.boxplot([x, x], conf_intervals=[[1, 2], [1]]) + + +def test_boxplot_zorder(): + x = np.arange(10) + fix, ax = plt.subplots() + assert ax.boxplot(x)['boxes'][0].get_zorder() == 2 + assert ax.boxplot(x, zorder=10)['boxes'][0].get_zorder() == 10 + + +def test_boxplot_marker_behavior(): + plt.rcParams['lines.marker'] = 's' + plt.rcParams['boxplot.flierprops.marker'] = 'o' + plt.rcParams['boxplot.meanprops.marker'] = '^' + fig, ax = plt.subplots() + test_data = np.arange(100) + test_data[-1] = 150 # a flier point + bxp_handle = ax.boxplot(test_data, showmeans=True) + for bxp_lines in ['whiskers', 'caps', 'boxes', 'medians']: + for each_line in bxp_handle[bxp_lines]: + # Ensure that the rcParams['lines.marker'] is overridden by '' + assert each_line.get_marker() == '' + + # Ensure that markers for fliers and means aren't overridden with '' + assert bxp_handle['fliers'][0].get_marker() == 'o' + assert bxp_handle['means'][0].get_marker() == '^' + + +@image_comparison(['boxplot_mod_artists_after_plotting.png'], + remove_text=True, savefig_kwarg={'dpi': 40}, style='default') +def test_boxplot_mod_artist_after_plotting(): + x = [0.15, 0.11, 0.06, 0.06, 0.12, 0.56, -0.56] + fig, ax = plt.subplots() + bp = ax.boxplot(x, sym="o") + for key in bp: + for obj in bp[key]: + obj.set_color('green') + + +@image_comparison(['violinplot_vert_baseline.png', + 'violinplot_vert_baseline.png']) +def test_vert_violinplot_baseline(): + # First 9 digits of frac(sqrt(2)) + np.random.seed(414213562) + data = [np.random.normal(size=100) for _ in range(4)] + ax = plt.axes() + ax.violinplot(data, positions=range(4), showmeans=False, showextrema=False, + showmedians=False) + + # Reuse testcase from above for a labeled data test + data = {"d": data} + fig, ax = plt.subplots() + ax.violinplot("d", positions=range(4), showmeans=False, showextrema=False, + showmedians=False, data=data) + + +@image_comparison(['violinplot_vert_showmeans.png']) +def test_vert_violinplot_showmeans(): + ax = plt.axes() + # First 9 digits of frac(sqrt(3)) + np.random.seed(732050807) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=True, showextrema=False, + showmedians=False) + + +@image_comparison(['violinplot_vert_showextrema.png']) +def test_vert_violinplot_showextrema(): + ax = plt.axes() + # First 9 digits of frac(sqrt(5)) + np.random.seed(236067977) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=False, showextrema=True, + showmedians=False) + + +@image_comparison(['violinplot_vert_showmedians.png']) +def test_vert_violinplot_showmedians(): + ax = plt.axes() + # First 9 digits of frac(sqrt(7)) + np.random.seed(645751311) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=False, showextrema=False, + showmedians=True) + + +@image_comparison(['violinplot_vert_showall.png']) +def test_vert_violinplot_showall(): + ax = plt.axes() + # First 9 digits of frac(sqrt(11)) + np.random.seed(316624790) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=True, showextrema=True, + showmedians=True, + quantiles=[[0.1, 0.9], [0.2, 0.8], [0.3, 0.7], [0.4, 0.6]]) + + +@image_comparison(['violinplot_vert_custompoints_10.png']) +def test_vert_violinplot_custompoints_10(): + ax = plt.axes() + # First 9 digits of frac(sqrt(13)) + np.random.seed(605551275) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=False, showextrema=False, + showmedians=False, points=10) + + +@image_comparison(['violinplot_vert_custompoints_200.png']) +def test_vert_violinplot_custompoints_200(): + ax = plt.axes() + # First 9 digits of frac(sqrt(17)) + np.random.seed(123105625) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), showmeans=False, showextrema=False, + showmedians=False, points=200) + + +@image_comparison(['violinplot_horiz_baseline.png']) +def test_horiz_violinplot_baseline(): + ax = plt.axes() + # First 9 digits of frac(sqrt(19)) + np.random.seed(358898943) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=False, + showextrema=False, showmedians=False) + + +@image_comparison(['violinplot_horiz_showmedians.png']) +def test_horiz_violinplot_showmedians(): + ax = plt.axes() + # First 9 digits of frac(sqrt(23)) + np.random.seed(795831523) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=False, + showextrema=False, showmedians=True) + + +@image_comparison(['violinplot_horiz_showmeans.png']) +def test_horiz_violinplot_showmeans(): + ax = plt.axes() + # First 9 digits of frac(sqrt(29)) + np.random.seed(385164807) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=True, + showextrema=False, showmedians=False) + + +@image_comparison(['violinplot_horiz_showextrema.png']) +def test_horiz_violinplot_showextrema(): + ax = plt.axes() + # First 9 digits of frac(sqrt(31)) + np.random.seed(567764362) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=False, + showextrema=True, showmedians=False) + + +@image_comparison(['violinplot_horiz_showall.png']) +def test_horiz_violinplot_showall(): + ax = plt.axes() + # First 9 digits of frac(sqrt(37)) + np.random.seed(82762530) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=True, + showextrema=True, showmedians=True, + quantiles=[[0.1, 0.9], [0.2, 0.8], [0.3, 0.7], [0.4, 0.6]]) + + +@image_comparison(['violinplot_horiz_custompoints_10.png']) +def test_horiz_violinplot_custompoints_10(): + ax = plt.axes() + # First 9 digits of frac(sqrt(41)) + np.random.seed(403124237) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=False, + showextrema=False, showmedians=False, points=10) + + +@image_comparison(['violinplot_horiz_custompoints_200.png']) +def test_horiz_violinplot_custompoints_200(): + ax = plt.axes() + # First 9 digits of frac(sqrt(43)) + np.random.seed(557438524) + data = [np.random.normal(size=100) for _ in range(4)] + ax.violinplot(data, positions=range(4), vert=False, showmeans=False, + showextrema=False, showmedians=False, points=200) + + +def test_violinplot_bad_positions(): + ax = plt.axes() + # First 9 digits of frac(sqrt(47)) + np.random.seed(855654600) + data = [np.random.normal(size=100) for _ in range(4)] + with pytest.raises(ValueError): + ax.violinplot(data, positions=range(5)) + + +def test_violinplot_bad_widths(): + ax = plt.axes() + # First 9 digits of frac(sqrt(53)) + np.random.seed(280109889) + data = [np.random.normal(size=100) for _ in range(4)] + with pytest.raises(ValueError): + ax.violinplot(data, positions=range(4), widths=[1, 2, 3]) + + +def test_violinplot_bad_quantiles(): + ax = plt.axes() + # First 9 digits of frac(sqrt(73)) + np.random.seed(544003745) + data = [np.random.normal(size=100)] + + # Different size quantile list and plots + with pytest.raises(ValueError): + ax.violinplot(data, quantiles=[[0.1, 0.2], [0.5, 0.7]]) + + +def test_violinplot_outofrange_quantiles(): + ax = plt.axes() + # First 9 digits of frac(sqrt(79)) + np.random.seed(888194417) + data = [np.random.normal(size=100)] + + # Quantile value above 100 + with pytest.raises(ValueError): + ax.violinplot(data, quantiles=[[0.1, 0.2, 0.3, 1.05]]) + + # Quantile value below 0 + with pytest.raises(ValueError): + ax.violinplot(data, quantiles=[[-0.05, 0.2, 0.3, 0.75]]) + + +@check_figures_equal(extensions=["png"]) +def test_violinplot_single_list_quantiles(fig_test, fig_ref): + # Ensures quantile list for 1D can be passed in as single list + # First 9 digits of frac(sqrt(83)) + np.random.seed(110433579) + data = [np.random.normal(size=100)] + + # Test image + ax = fig_test.subplots() + ax.violinplot(data, quantiles=[0.1, 0.3, 0.9]) + + # Reference image + ax = fig_ref.subplots() + ax.violinplot(data, quantiles=[[0.1, 0.3, 0.9]]) + + +@check_figures_equal(extensions=["png"]) +def test_violinplot_pandas_series(fig_test, fig_ref, pd): + np.random.seed(110433579) + s1 = pd.Series(np.random.normal(size=7), index=[9, 8, 7, 6, 5, 4, 3]) + s2 = pd.Series(np.random.normal(size=9), index=list('ABCDEFGHI')) + s3 = pd.Series(np.random.normal(size=11)) + fig_test.subplots().violinplot([s1, s2, s3]) + fig_ref.subplots().violinplot([s1.values, s2.values, s3.values]) + + +def test_manage_xticks(): + _, ax = plt.subplots() + ax.set_xlim(0, 4) + old_xlim = ax.get_xlim() + np.random.seed(0) + y1 = np.random.normal(10, 3, 20) + y2 = np.random.normal(3, 1, 20) + ax.boxplot([y1, y2], positions=[1, 2], manage_ticks=False) + new_xlim = ax.get_xlim() + assert_array_equal(old_xlim, new_xlim) + + +def test_boxplot_not_single(): + fig, ax = plt.subplots() + ax.boxplot(np.random.rand(100), positions=[3]) + ax.boxplot(np.random.rand(100), positions=[5]) + fig.canvas.draw() + assert ax.get_xlim() == (2.5, 5.5) + assert list(ax.get_xticks()) == [3, 5] + assert [t.get_text() for t in ax.get_xticklabels()] == ["3", "5"] + + +def test_tick_space_size_0(): + # allow font size to be zero, which affects ticks when there is + # no other text in the figure. + plt.plot([0, 1], [0, 1]) + matplotlib.rcParams.update({'font.size': 0}) + b = io.BytesIO() + plt.savefig(b, dpi=80, format='raw') + + +@image_comparison(['errorbar_basic', 'errorbar_mixed', 'errorbar_basic']) +def test_errorbar(): + # longdouble due to floating point rounding issues with certain + # computer chipsets + x = np.arange(0.1, 4, 0.5, dtype=np.longdouble) + y = np.exp(-x) + + yerr = 0.1 + 0.2*np.sqrt(x) + xerr = 0.1 + yerr + + # First illustrate basic pyplot interface, using defaults where possible. + fig = plt.figure() + ax = fig.gca() + ax.errorbar(x, y, xerr=0.2, yerr=0.4) + ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y") + + # Now switch to a more OO interface to exercise more features. + fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True) + ax = axs[0, 0] + ax.errorbar(x, y, yerr=yerr, fmt='o') + ax.set_title('Vert. symmetric') + + # With 4 subplots, reduce the number of axis ticks to avoid crowding. + ax.locator_params(nbins=4) + + ax = axs[0, 1] + ax.errorbar(x, y, xerr=xerr, fmt='o', alpha=0.4) + ax.set_title('Hor. symmetric w/ alpha') + + ax = axs[1, 0] + ax.errorbar(x, y, yerr=[yerr, 2*yerr], xerr=[xerr, 2*xerr], fmt='--o') + ax.set_title('H, V asymmetric') + + ax = axs[1, 1] + ax.set_yscale('log') + # Here we have to be careful to keep all y values positive: + ylower = np.maximum(1e-2, y - yerr) + yerr_lower = y - ylower + + ax.errorbar(x, y, yerr=[yerr_lower, 2*yerr], xerr=xerr, + fmt='o', ecolor='g', capthick=2) + ax.set_title('Mixed sym., log y') + # Force limits due to floating point slop potentially expanding the range + ax.set_ylim(1e-2, 1e1) + + fig.suptitle('Variable errorbars') + + # Reuse the first testcase from above for a labeled data test + data = {"x": x, "y": y} + fig = plt.figure() + ax = fig.gca() + ax.errorbar("x", "y", xerr=0.2, yerr=0.4, data=data) + ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y") + + +@image_comparison(['mixed_errorbar_polar_caps'], extensions=['png'], + remove_text=True) +def test_mixed_errorbar_polar_caps(): + """ + Mix several polar errorbar use cases in a single test figure. + + It is advisable to position individual points off the grid. If there are + problems with reproducibility of this test, consider removing grid. + """ + fig = plt.figure() + ax = plt.subplot(111, projection='polar') + + # symmetric errorbars + th_sym = [1, 2, 3] + r_sym = [0.9]*3 + ax.errorbar(th_sym, r_sym, xerr=0.35, yerr=0.2, fmt="o") + + # long errorbars + th_long = [np.pi/2 + .1, np.pi + .1] + r_long = [1.8, 2.2] + ax.errorbar(th_long, r_long, xerr=0.8 * np.pi, yerr=0.15, fmt="o") + + # asymmetric errorbars + th_asym = [4*np.pi/3 + .1, 5*np.pi/3 + .1, 2*np.pi-0.1] + r_asym = [1.1]*3 + xerr = [[.3, .3, .2], [.2, .3, .3]] + yerr = [[.35, .5, .5], [.5, .35, .5]] + ax.errorbar(th_asym, r_asym, xerr=xerr, yerr=yerr, fmt="o") + + # overlapping errorbar + th_over = [2.1] + r_over = [3.1] + ax.errorbar(th_over, r_over, xerr=10, yerr=.2, fmt="o") + + +def test_errorbar_colorcycle(): + + f, ax = plt.subplots() + x = np.arange(10) + y = 2*x + + e1, _, _ = ax.errorbar(x, y, c=None) + e2, _, _ = ax.errorbar(x, 2*y, c=None) + ln1, = ax.plot(x, 4*y) + + assert mcolors.to_rgba(e1.get_color()) == mcolors.to_rgba('C0') + assert mcolors.to_rgba(e2.get_color()) == mcolors.to_rgba('C1') + assert mcolors.to_rgba(ln1.get_color()) == mcolors.to_rgba('C2') + + +@check_figures_equal() +def test_errorbar_cycle_ecolor(fig_test, fig_ref): + x = np.arange(0.1, 4, 0.5) + y = [np.exp(-x+n) for n in range(4)] + + axt = fig_test.subplots() + axr = fig_ref.subplots() + + for yi, color in zip(y, ['C0', 'C1', 'C2', 'C3']): + axt.errorbar(x, yi, yerr=(yi * 0.25), linestyle='-', + marker='o', ecolor='black') + axr.errorbar(x, yi, yerr=(yi * 0.25), linestyle='-', + marker='o', color=color, ecolor='black') + + +def test_errorbar_shape(): + fig = plt.figure() + ax = fig.gca() + + x = np.arange(0.1, 4, 0.5) + y = np.exp(-x) + yerr1 = 0.1 + 0.2*np.sqrt(x) + yerr = np.vstack((yerr1, 2*yerr1)).T + xerr = 0.1 + yerr + + with pytest.raises(ValueError): + ax.errorbar(x, y, yerr=yerr, fmt='o') + with pytest.raises(ValueError): + ax.errorbar(x, y, xerr=xerr, fmt='o') + with pytest.raises(ValueError): + ax.errorbar(x, y, yerr=yerr, xerr=xerr, fmt='o') + + +@image_comparison(['errorbar_limits']) +def test_errorbar_limits(): + x = np.arange(0.5, 5.5, 0.5) + y = np.exp(-x) + xerr = 0.1 + yerr = 0.2 + ls = 'dotted' + + fig, ax = plt.subplots() + + # standard error bars + ax.errorbar(x, y, xerr=xerr, yerr=yerr, ls=ls, color='blue') + + # including upper limits + uplims = np.zeros_like(x) + uplims[[1, 5, 9]] = True + ax.errorbar(x, y+0.5, xerr=xerr, yerr=yerr, uplims=uplims, ls=ls, + color='green') + + # including lower limits + lolims = np.zeros_like(x) + lolims[[2, 4, 8]] = True + ax.errorbar(x, y+1.0, xerr=xerr, yerr=yerr, lolims=lolims, ls=ls, + color='red') + + # including upper and lower limits + ax.errorbar(x, y+1.5, marker='o', ms=8, xerr=xerr, yerr=yerr, + lolims=lolims, uplims=uplims, ls=ls, color='magenta') + + # including xlower and xupper limits + xerr = 0.2 + yerr = np.full_like(x, 0.2) + yerr[[3, 6]] = 0.3 + xlolims = lolims + xuplims = uplims + lolims = np.zeros_like(x) + uplims = np.zeros_like(x) + lolims[[6]] = True + uplims[[3]] = True + ax.errorbar(x, y+2.1, marker='o', ms=8, xerr=xerr, yerr=yerr, + xlolims=xlolims, xuplims=xuplims, uplims=uplims, + lolims=lolims, ls='none', mec='blue', capsize=0, + color='cyan') + ax.set_xlim((0, 5.5)) + ax.set_title('Errorbar upper and lower limits') + + +def test_errorbar_nonefmt(): + # Check that passing 'none' as a format still plots errorbars + x = np.arange(5) + y = np.arange(5) + + plotline, _, barlines = plt.errorbar(x, y, xerr=1, yerr=1, fmt='none') + assert plotline is None + for errbar in barlines: + assert np.all(errbar.get_color() == mcolors.to_rgba('C0')) + + +def test_errorbar_line_specific_kwargs(): + # Check that passing line-specific keyword arguments will not result in + # errors. + x = np.arange(5) + y = np.arange(5) + + plotline, _, _ = plt.errorbar(x, y, xerr=1, yerr=1, ls='None', + marker='s', fillstyle='full', + drawstyle='steps-mid', + dash_capstyle='round', + dash_joinstyle='miter', + solid_capstyle='butt', + solid_joinstyle='bevel') + assert plotline.get_fillstyle() == 'full' + assert plotline.get_drawstyle() == 'steps-mid' + + +@check_figures_equal(extensions=['png']) +def test_errorbar_with_prop_cycle(fig_test, fig_ref): + ax = fig_ref.subplots() + ax.errorbar(x=[2, 4, 10], y=[0, 1, 2], yerr=0.5, + ls='--', marker='s', mfc='k') + ax.errorbar(x=[2, 4, 10], y=[2, 3, 4], yerr=0.5, color='tab:green', + ls=':', marker='s', mfc='y') + ax.errorbar(x=[2, 4, 10], y=[4, 5, 6], yerr=0.5, fmt='tab:blue', + ls='-.', marker='o', mfc='c') + ax.set_xlim(1, 11) + + _cycle = cycler(ls=['--', ':', '-.'], marker=['s', 's', 'o'], + mfc=['k', 'y', 'c'], color=['b', 'g', 'r']) + plt.rc("axes", prop_cycle=_cycle) + ax = fig_test.subplots() + ax.errorbar(x=[2, 4, 10], y=[0, 1, 2], yerr=0.5) + ax.errorbar(x=[2, 4, 10], y=[2, 3, 4], yerr=0.5, color='tab:green') + ax.errorbar(x=[2, 4, 10], y=[4, 5, 6], yerr=0.5, fmt='tab:blue') + ax.set_xlim(1, 11) + + +def test_errorbar_every_invalid(): + x = np.linspace(0, 1, 15) + y = x * (1-x) + yerr = y/6 + + ax = plt.figure().subplots() + + with pytest.raises(ValueError, match='not a tuple of two integers'): + ax.errorbar(x, y, yerr, errorevery=(1, 2, 3)) + with pytest.raises(ValueError, match='not a tuple of two integers'): + ax.errorbar(x, y, yerr, errorevery=(1.3, 3)) + with pytest.raises(ValueError, match='not a valid NumPy fancy index'): + ax.errorbar(x, y, yerr, errorevery=[False, True]) + with pytest.raises(ValueError, match='not a recognized value'): + ax.errorbar(x, y, yerr, errorevery='foobar') + + +def test_xerr_yerr_not_negative(): + ax = plt.figure().subplots() + + with pytest.raises(ValueError, + match="'xerr' must not contain negative values"): + ax.errorbar(x=[0], y=[0], xerr=[[-0.5], [1]], yerr=[[-0.5], [1]]) + with pytest.raises(ValueError, + match="'xerr' must not contain negative values"): + ax.errorbar(x=[0], y=[0], xerr=[[-0.5], [1]]) + with pytest.raises(ValueError, + match="'yerr' must not contain negative values"): + ax.errorbar(x=[0], y=[0], yerr=[[-0.5], [1]]) + with pytest.raises(ValueError, + match="'yerr' must not contain negative values"): + x = np.arange(5) + y = [datetime.datetime(2021, 9, i * 2 + 1) for i in x] + ax.errorbar(x=x, + y=y, + yerr=datetime.timedelta(days=-10)) + + +@check_figures_equal() +def test_errorbar_every(fig_test, fig_ref): + x = np.linspace(0, 1, 15) + y = x * (1-x) + yerr = y/6 + + ax_ref = fig_ref.subplots() + ax_test = fig_test.subplots() + + for color, shift in zip('rgbk', [0, 0, 2, 7]): + y += .02 + + # Check errorevery using an explicit offset and step. + ax_test.errorbar(x, y, yerr, errorevery=(shift, 4), + capsize=4, c=color) + + # Using manual errorbars + # n.b. errorbar draws the main plot at z=2.1 by default + ax_ref.plot(x, y, c=color, zorder=2.1) + ax_ref.errorbar(x[shift::4], y[shift::4], yerr[shift::4], + capsize=4, c=color, fmt='none') + + # Check that markevery is propagated to line, without affecting errorbars. + ax_test.errorbar(x, y + 0.1, yerr, markevery=(1, 4), capsize=4, fmt='o') + ax_ref.plot(x[1::4], y[1::4] + 0.1, 'o', zorder=2.1) + ax_ref.errorbar(x, y + 0.1, yerr, capsize=4, fmt='none') + + # Check that passing a slice to markevery/errorevery works. + ax_test.errorbar(x, y + 0.2, yerr, errorevery=slice(2, None, 3), + markevery=slice(2, None, 3), + capsize=4, c='C0', fmt='o') + ax_ref.plot(x[2::3], y[2::3] + 0.2, 'o', c='C0', zorder=2.1) + ax_ref.errorbar(x[2::3], y[2::3] + 0.2, yerr[2::3], + capsize=4, c='C0', fmt='none') + + # Check that passing an iterable to markevery/errorevery works. + ax_test.errorbar(x, y + 0.2, yerr, errorevery=[False, True, False] * 5, + markevery=[False, True, False] * 5, + capsize=4, c='C1', fmt='o') + ax_ref.plot(x[1::3], y[1::3] + 0.2, 'o', c='C1', zorder=2.1) + ax_ref.errorbar(x[1::3], y[1::3] + 0.2, yerr[1::3], + capsize=4, c='C1', fmt='none') + + +@pytest.mark.parametrize('elinewidth', [[1, 2, 3], + np.array([1, 2, 3]), + 1]) +def test_errorbar_linewidth_type(elinewidth): + plt.errorbar([1, 2, 3], [1, 2, 3], yerr=[1, 2, 3], elinewidth=elinewidth) + + +@check_figures_equal(extensions=["png"]) +def test_errorbar_nan(fig_test, fig_ref): + ax = fig_test.add_subplot() + xs = range(5) + ys = np.array([1, 2, np.nan, np.nan, 3]) + es = np.array([4, 5, np.nan, np.nan, 6]) + ax.errorbar(xs, ys, es) + ax = fig_ref.add_subplot() + ax.errorbar([0, 1], [1, 2], [4, 5]) + ax.errorbar([4], [3], [6], fmt="C0") + + +@image_comparison(['hist_stacked_stepfilled', 'hist_stacked_stepfilled']) +def test_hist_stacked_stepfilled(): + # make some data + d1 = np.linspace(1, 3, 20) + d2 = np.linspace(0, 10, 50) + fig, ax = plt.subplots() + ax.hist((d1, d2), histtype="stepfilled", stacked=True) + + # Reuse testcase from above for a labeled data test + data = {"x": (d1, d2)} + fig, ax = plt.subplots() + ax.hist("x", histtype="stepfilled", stacked=True, data=data) + + +@image_comparison(['hist_offset']) +def test_hist_offset(): + # make some data + d1 = np.linspace(0, 10, 50) + d2 = np.linspace(1, 3, 20) + fig, ax = plt.subplots() + ax.hist(d1, bottom=5) + ax.hist(d2, bottom=15) + + +@image_comparison(['hist_step.png'], remove_text=True) +def test_hist_step(): + # make some data + d1 = np.linspace(1, 3, 20) + fig, ax = plt.subplots() + ax.hist(d1, histtype="step") + ax.set_ylim(0, 10) + ax.set_xlim(-1, 5) + + +@image_comparison(['hist_step_horiz.png']) +def test_hist_step_horiz(): + # make some data + d1 = np.linspace(0, 10, 50) + d2 = np.linspace(1, 3, 20) + fig, ax = plt.subplots() + ax.hist((d1, d2), histtype="step", orientation="horizontal") + + +@image_comparison(['hist_stacked_weights']) +def test_hist_stacked_weighted(): + # make some data + d1 = np.linspace(0, 10, 50) + d2 = np.linspace(1, 3, 20) + w1 = np.linspace(0.01, 3.5, 50) + w2 = np.linspace(0.05, 2., 20) + fig, ax = plt.subplots() + ax.hist((d1, d2), weights=(w1, w2), histtype="stepfilled", stacked=True) + + +@image_comparison(['stem.png'], style='mpl20', remove_text=True) +def test_stem(): + x = np.linspace(0.1, 2 * np.pi, 100) + + fig, ax = plt.subplots() + # Label is a single space to force a legend to be drawn, but to avoid any + # text being drawn + ax.stem(x, np.cos(x), + linefmt='C2-.', markerfmt='k+', basefmt='C1-.', label=' ') + ax.legend() + + +def test_stem_args(): + """Test that stem() correctly identifies x and y values.""" + def _assert_equal(stem_container, expected): + x, y = map(list, stem_container.markerline.get_data()) + assert x == expected[0] + assert y == expected[1] + + fig, ax = plt.subplots() + + x = [1, 3, 5] + y = [9, 8, 7] + + # Test the call signatures + _assert_equal(ax.stem(y), expected=([0, 1, 2], y)) + _assert_equal(ax.stem(x, y), expected=(x, y)) + _assert_equal(ax.stem(x, y, linefmt='r--'), expected=(x, y)) + _assert_equal(ax.stem(x, y, 'r--'), expected=(x, y)) + _assert_equal(ax.stem(x, y, linefmt='r--', basefmt='b--'), expected=(x, y)) + _assert_equal(ax.stem(y, linefmt='r--'), expected=([0, 1, 2], y)) + _assert_equal(ax.stem(y, 'r--'), expected=([0, 1, 2], y)) + + +def test_stem_markerfmt(): + """Test that stem(..., markerfmt=...) produces the intended markers.""" + def _assert_equal(stem_container, linecolor=None, markercolor=None, + marker=None): + """ + Check that the given StemContainer has the properties listed as + keyword-arguments. + """ + if linecolor is not None: + assert mcolors.same_color( + stem_container.stemlines.get_color(), + linecolor) + if markercolor is not None: + assert mcolors.same_color( + stem_container.markerline.get_color(), + markercolor) + if marker is not None: + assert stem_container.markerline.get_marker() == marker + assert stem_container.markerline.get_linestyle() == 'None' + + fig, ax = plt.subplots() + + x = [1, 3, 5] + y = [9, 8, 7] + + # no linefmt + _assert_equal(ax.stem(x, y), markercolor='C0', marker='o') + _assert_equal(ax.stem(x, y, markerfmt='x'), markercolor='C0', marker='x') + _assert_equal(ax.stem(x, y, markerfmt='rx'), markercolor='r', marker='x') + + # positional linefmt + _assert_equal( + ax.stem(x, y, 'r'), # marker color follows linefmt if not given + linecolor='r', markercolor='r', marker='o') + _assert_equal( + ax.stem(x, y, 'rx'), # the marker is currently not taken from linefmt + linecolor='r', markercolor='r', marker='o') + _assert_equal( + ax.stem(x, y, 'r', markerfmt='x'), # only marker type specified + linecolor='r', markercolor='r', marker='x') + _assert_equal( + ax.stem(x, y, 'r', markerfmt='g'), # only marker color specified + linecolor='r', markercolor='g', marker='o') + _assert_equal( + ax.stem(x, y, 'r', markerfmt='gx'), # marker type and color specified + linecolor='r', markercolor='g', marker='x') + _assert_equal( + ax.stem(x, y, 'r', markerfmt=' '), # markerfmt=' ' for no marker + linecolor='r', markercolor='r', marker='None') + _assert_equal( + ax.stem(x, y, 'r', markerfmt=''), # markerfmt='' for no marker + linecolor='r', markercolor='r', marker='None') + + # with linefmt kwarg + _assert_equal( + ax.stem(x, y, linefmt='r'), + linecolor='r', markercolor='r', marker='o') + _assert_equal( + ax.stem(x, y, linefmt='r', markerfmt='x'), + linecolor='r', markercolor='r', marker='x') + _assert_equal( + ax.stem(x, y, linefmt='r', markerfmt='gx'), + linecolor='r', markercolor='g', marker='x') + + +def test_stem_dates(): + fig, ax = plt.subplots(1, 1) + xs = [dateutil.parser.parse("2013-9-28 11:00:00"), + dateutil.parser.parse("2013-9-28 12:00:00")] + ys = [100, 200] + ax.stem(xs, ys) + + +@image_comparison(['stem_orientation.png'], style='mpl20', remove_text=True) +def test_stem_orientation(): + x = np.linspace(0.1, 2*np.pi, 50) + + fig, ax = plt.subplots() + ax.stem(x, np.cos(x), + linefmt='C2-.', markerfmt='kx', basefmt='C1-.', + orientation='horizontal') + + +@image_comparison(['hist_stacked_stepfilled_alpha']) +def test_hist_stacked_stepfilled_alpha(): + # make some data + d1 = np.linspace(1, 3, 20) + d2 = np.linspace(0, 10, 50) + fig, ax = plt.subplots() + ax.hist((d1, d2), histtype="stepfilled", stacked=True, alpha=0.5) + + +@image_comparison(['hist_stacked_step']) +def test_hist_stacked_step(): + # make some data + d1 = np.linspace(1, 3, 20) + d2 = np.linspace(0, 10, 50) + fig, ax = plt.subplots() + ax.hist((d1, d2), histtype="step", stacked=True) + + +@image_comparison(['hist_stacked_normed']) +def test_hist_stacked_density(): + # make some data + d1 = np.linspace(1, 3, 20) + d2 = np.linspace(0, 10, 50) + fig, ax = plt.subplots() + ax.hist((d1, d2), stacked=True, density=True) + + +@image_comparison(['hist_step_bottom.png'], remove_text=True) +def test_hist_step_bottom(): + # make some data + d1 = np.linspace(1, 3, 20) + fig, ax = plt.subplots() + ax.hist(d1, bottom=np.arange(10), histtype="stepfilled") + + +def test_hist_stepfilled_geometry(): + bins = [0, 1, 2, 3] + data = [0, 0, 1, 1, 1, 2] + _, _, (polygon, ) = plt.hist(data, + bins=bins, + histtype='stepfilled') + xy = [[0, 0], [0, 2], [1, 2], [1, 3], [2, 3], [2, 1], [3, 1], + [3, 0], [2, 0], [2, 0], [1, 0], [1, 0], [0, 0]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_step_geometry(): + bins = [0, 1, 2, 3] + data = [0, 0, 1, 1, 1, 2] + _, _, (polygon, ) = plt.hist(data, + bins=bins, + histtype='step') + xy = [[0, 0], [0, 2], [1, 2], [1, 3], [2, 3], [2, 1], [3, 1], [3, 0]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_stepfilled_bottom_geometry(): + bins = [0, 1, 2, 3] + data = [0, 0, 1, 1, 1, 2] + _, _, (polygon, ) = plt.hist(data, + bins=bins, + bottom=[1, 2, 1.5], + histtype='stepfilled') + xy = [[0, 1], [0, 3], [1, 3], [1, 5], [2, 5], [2, 2.5], [3, 2.5], + [3, 1.5], [2, 1.5], [2, 2], [1, 2], [1, 1], [0, 1]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_step_bottom_geometry(): + bins = [0, 1, 2, 3] + data = [0, 0, 1, 1, 1, 2] + _, _, (polygon, ) = plt.hist(data, + bins=bins, + bottom=[1, 2, 1.5], + histtype='step') + xy = [[0, 1], [0, 3], [1, 3], [1, 5], [2, 5], [2, 2.5], [3, 2.5], [3, 1.5]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_stacked_stepfilled_geometry(): + bins = [0, 1, 2, 3] + data_1 = [0, 0, 1, 1, 1, 2] + data_2 = [0, 1, 2] + _, _, patches = plt.hist([data_1, data_2], + bins=bins, + stacked=True, + histtype='stepfilled') + + assert len(patches) == 2 + + polygon, = patches[0] + xy = [[0, 0], [0, 2], [1, 2], [1, 3], [2, 3], [2, 1], [3, 1], + [3, 0], [2, 0], [2, 0], [1, 0], [1, 0], [0, 0]] + assert_array_equal(polygon.get_xy(), xy) + + polygon, = patches[1] + xy = [[0, 2], [0, 3], [1, 3], [1, 4], [2, 4], [2, 2], [3, 2], + [3, 1], [2, 1], [2, 3], [1, 3], [1, 2], [0, 2]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_stacked_step_geometry(): + bins = [0, 1, 2, 3] + data_1 = [0, 0, 1, 1, 1, 2] + data_2 = [0, 1, 2] + _, _, patches = plt.hist([data_1, data_2], + bins=bins, + stacked=True, + histtype='step') + + assert len(patches) == 2 + + polygon, = patches[0] + xy = [[0, 0], [0, 2], [1, 2], [1, 3], [2, 3], [2, 1], [3, 1], [3, 0]] + assert_array_equal(polygon.get_xy(), xy) + + polygon, = patches[1] + xy = [[0, 2], [0, 3], [1, 3], [1, 4], [2, 4], [2, 2], [3, 2], [3, 1]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_stacked_stepfilled_bottom_geometry(): + bins = [0, 1, 2, 3] + data_1 = [0, 0, 1, 1, 1, 2] + data_2 = [0, 1, 2] + _, _, patches = plt.hist([data_1, data_2], + bins=bins, + stacked=True, + bottom=[1, 2, 1.5], + histtype='stepfilled') + + assert len(patches) == 2 + + polygon, = patches[0] + xy = [[0, 1], [0, 3], [1, 3], [1, 5], [2, 5], [2, 2.5], [3, 2.5], + [3, 1.5], [2, 1.5], [2, 2], [1, 2], [1, 1], [0, 1]] + assert_array_equal(polygon.get_xy(), xy) + + polygon, = patches[1] + xy = [[0, 3], [0, 4], [1, 4], [1, 6], [2, 6], [2, 3.5], [3, 3.5], + [3, 2.5], [2, 2.5], [2, 5], [1, 5], [1, 3], [0, 3]] + assert_array_equal(polygon.get_xy(), xy) + + +def test_hist_stacked_step_bottom_geometry(): + bins = [0, 1, 2, 3] + data_1 = [0, 0, 1, 1, 1, 2] + data_2 = [0, 1, 2] + _, _, patches = plt.hist([data_1, data_2], + bins=bins, + stacked=True, + bottom=[1, 2, 1.5], + histtype='step') + + assert len(patches) == 2 + + polygon, = patches[0] + xy = [[0, 1], [0, 3], [1, 3], [1, 5], [2, 5], [2, 2.5], [3, 2.5], [3, 1.5]] + assert_array_equal(polygon.get_xy(), xy) + + polygon, = patches[1] + xy = [[0, 3], [0, 4], [1, 4], [1, 6], [2, 6], [2, 3.5], [3, 3.5], [3, 2.5]] + assert_array_equal(polygon.get_xy(), xy) + + +@image_comparison(['hist_stacked_bar']) +def test_hist_stacked_bar(): + # make some data + d = [[100, 100, 100, 100, 200, 320, 450, 80, 20, 600, 310, 800], + [20, 23, 50, 11, 100, 420], [120, 120, 120, 140, 140, 150, 180], + [60, 60, 60, 60, 300, 300, 5, 5, 5, 5, 10, 300], + [555, 555, 555, 30, 30, 30, 30, 30, 100, 100, 100, 100, 30, 30], + [30, 30, 30, 30, 400, 400, 400, 400, 400, 400, 400, 400]] + colors = [(0.5759849696758961, 1.0, 0.0), (0.0, 1.0, 0.350624650815206), + (0.0, 1.0, 0.6549834156005998), (0.0, 0.6569064625276622, 1.0), + (0.28302699607823545, 0.0, 1.0), (0.6849123462299822, 0.0, 1.0)] + labels = ['green', 'orange', ' yellow', 'magenta', 'black'] + fig, ax = plt.subplots() + ax.hist(d, bins=10, histtype='barstacked', align='mid', color=colors, + label=labels) + ax.legend(loc='upper right', bbox_to_anchor=(1.0, 1.0), ncols=1) + + +def test_hist_barstacked_bottom_unchanged(): + b = np.array([10, 20]) + plt.hist([[0, 1], [0, 1]], 2, histtype="barstacked", bottom=b) + assert b.tolist() == [10, 20] + + +def test_hist_emptydata(): + fig, ax = plt.subplots() + ax.hist([[], range(10), range(10)], histtype="step") + + +def test_hist_labels(): + # test singleton labels OK + fig, ax = plt.subplots() + _, _, bars = ax.hist([0, 1], label=0) + assert bars[0].get_label() == '0' + _, _, bars = ax.hist([0, 1], label=[0]) + assert bars[0].get_label() == '0' + _, _, bars = ax.hist([0, 1], label=None) + assert bars[0].get_label() == '_nolegend_' + _, _, bars = ax.hist([0, 1], label='0') + assert bars[0].get_label() == '0' + _, _, bars = ax.hist([0, 1], label='00') + assert bars[0].get_label() == '00' + + +@image_comparison(['transparent_markers'], remove_text=True) +def test_transparent_markers(): + np.random.seed(0) + data = np.random.random(50) + + fig, ax = plt.subplots() + ax.plot(data, 'D', mfc='none', markersize=100) + + +@image_comparison(['rgba_markers'], remove_text=True) +def test_rgba_markers(): + fig, axs = plt.subplots(ncols=2) + rcolors = [(1, 0, 0, 1), (1, 0, 0, 0.5)] + bcolors = [(0, 0, 1, 1), (0, 0, 1, 0.5)] + alphas = [None, 0.2] + kw = dict(ms=100, mew=20) + for i, alpha in enumerate(alphas): + for j, rcolor in enumerate(rcolors): + for k, bcolor in enumerate(bcolors): + axs[i].plot(j+1, k+1, 'o', mfc=bcolor, mec=rcolor, + alpha=alpha, **kw) + axs[i].plot(j+1, k+3, 'x', mec=rcolor, alpha=alpha, **kw) + for ax in axs: + ax.axis([-1, 4, 0, 5]) + + +@image_comparison(['mollweide_grid'], remove_text=True) +def test_mollweide_grid(): + # test that both horizontal and vertical gridlines appear on the Mollweide + # projection + fig = plt.figure() + ax = fig.add_subplot(projection='mollweide') + ax.grid() + + +def test_mollweide_forward_inverse_closure(): + # test that the round-trip Mollweide forward->inverse transformation is an + # approximate identity + fig = plt.figure() + ax = fig.add_subplot(projection='mollweide') + + # set up 1-degree grid in longitude, latitude + lon = np.linspace(-np.pi, np.pi, 360) + # The poles are degenerate and thus sensitive to floating point precision errors + lat = np.linspace(-np.pi / 2.0, np.pi / 2.0, 180)[1:-1] + lon, lat = np.meshgrid(lon, lat) + ll = np.vstack((lon.flatten(), lat.flatten())).T + + # perform forward transform + xy = ax.transProjection.transform(ll) + + # perform inverse transform + ll2 = ax.transProjection.inverted().transform(xy) + + # compare + np.testing.assert_array_almost_equal(ll, ll2, 3) + + +def test_mollweide_inverse_forward_closure(): + # test that the round-trip Mollweide inverse->forward transformation is an + # approximate identity + fig = plt.figure() + ax = fig.add_subplot(projection='mollweide') + + # set up grid in x, y + x = np.linspace(0, 1, 500) + x, y = np.meshgrid(x, x) + xy = np.vstack((x.flatten(), y.flatten())).T + + # perform inverse transform + ll = ax.transProjection.inverted().transform(xy) + + # perform forward transform + xy2 = ax.transProjection.transform(ll) + + # compare + np.testing.assert_array_almost_equal(xy, xy2, 3) + + +@image_comparison(['test_alpha'], remove_text=True) +def test_alpha(): + np.random.seed(0) + data = np.random.random(50) + + fig, ax = plt.subplots() + + # alpha=.5 markers, solid line + ax.plot(data, '-D', color=[1, 0, 0], mfc=[1, 0, 0, .5], + markersize=20, lw=10) + + # everything solid by kwarg + ax.plot(data + 2, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0, .5], + markersize=20, lw=10, + alpha=1) + + # everything alpha=.5 by kwarg + ax.plot(data + 4, '-D', color=[1, 0, 0], mfc=[1, 0, 0], + markersize=20, lw=10, + alpha=.5) + + # everything alpha=.5 by colors + ax.plot(data + 6, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0, .5], + markersize=20, lw=10) + + # alpha=.5 line, solid markers + ax.plot(data + 8, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0], + markersize=20, lw=10) + + +@image_comparison(['eventplot', 'eventplot'], remove_text=True) +def test_eventplot(): + np.random.seed(0) + + data1 = np.random.random([32, 20]).tolist() + data2 = np.random.random([6, 20]).tolist() + data = data1 + data2 + num_datasets = len(data) + + colors1 = [[0, 1, .7]] * len(data1) + colors2 = [[1, 0, 0], + [0, 1, 0], + [0, 0, 1], + [1, .75, 0], + [1, 0, 1], + [0, 1, 1]] + colors = colors1 + colors2 + + lineoffsets1 = 12 + np.arange(0, len(data1)) * .33 + lineoffsets2 = [-15, -3, 1, 1.5, 6, 10] + lineoffsets = lineoffsets1.tolist() + lineoffsets2 + + linelengths1 = [.33] * len(data1) + linelengths2 = [5, 2, 1, 1, 3, 1.5] + linelengths = linelengths1 + linelengths2 + + fig = plt.figure() + axobj = fig.add_subplot() + colls = axobj.eventplot(data, colors=colors, lineoffsets=lineoffsets, + linelengths=linelengths) + + num_collections = len(colls) + assert num_collections == num_datasets + + # Reuse testcase from above for a labeled data test + data = {"pos": data, "c": colors, "lo": lineoffsets, "ll": linelengths} + fig = plt.figure() + axobj = fig.add_subplot() + colls = axobj.eventplot("pos", colors="c", lineoffsets="lo", + linelengths="ll", data=data) + num_collections = len(colls) + assert num_collections == num_datasets + + +@image_comparison(['test_eventplot_defaults.png'], remove_text=True) +def test_eventplot_defaults(): + """ + test that eventplot produces the correct output given the default params + (see bug #3728) + """ + np.random.seed(0) + + data1 = np.random.random([32, 20]).tolist() + data2 = np.random.random([6, 20]).tolist() + data = data1 + data2 + + fig = plt.figure() + axobj = fig.add_subplot() + axobj.eventplot(data) + + +@pytest.mark.parametrize(('colors'), [ + ('0.5',), # string color with multiple characters: not OK before #8193 fix + ('tab:orange', 'tab:pink', 'tab:cyan', 'bLacK'), # case-insensitive + ('red', (0, 1, 0), None, (1, 0, 1, 0.5)), # a tricky case mixing types +]) +def test_eventplot_colors(colors): + """Test the *colors* parameter of eventplot. Inspired by issue #8193.""" + data = [[0], [1], [2], [3]] # 4 successive events of different nature + + # Build the list of the expected colors + expected = [c if c is not None else 'C0' for c in colors] + # Convert the list into an array of RGBA values + # NB: ['rgbk'] is not a valid argument for to_rgba_array, while 'rgbk' is. + if len(expected) == 1: + expected = expected[0] + expected = np.broadcast_to(mcolors.to_rgba_array(expected), (len(data), 4)) + + fig, ax = plt.subplots() + if len(colors) == 1: # tuple with a single string (like '0.5' or 'rgbk') + colors = colors[0] + collections = ax.eventplot(data, colors=colors) + + for coll, color in zip(collections, expected): + assert_allclose(coll.get_color(), color) + + +def test_eventplot_alpha(): + fig, ax = plt.subplots() + + # one alpha for all + collections = ax.eventplot([[0, 2, 4], [1, 3, 5, 7]], alpha=0.7) + assert collections[0].get_alpha() == 0.7 + assert collections[1].get_alpha() == 0.7 + + # one alpha per collection + collections = ax.eventplot([[0, 2, 4], [1, 3, 5, 7]], alpha=[0.5, 0.7]) + assert collections[0].get_alpha() == 0.5 + assert collections[1].get_alpha() == 0.7 + + with pytest.raises(ValueError, match="alpha and positions are unequal"): + ax.eventplot([[0, 2, 4], [1, 3, 5, 7]], alpha=[0.5, 0.7, 0.9]) + + with pytest.raises(ValueError, match="alpha and positions are unequal"): + ax.eventplot([0, 2, 4], alpha=[0.5, 0.7]) + + +@image_comparison(['test_eventplot_problem_kwargs.png'], remove_text=True) +def test_eventplot_problem_kwargs(recwarn): + """ + test that 'singular' versions of LineCollection props raise an + MatplotlibDeprecationWarning rather than overriding the 'plural' versions + (e.g., to prevent 'color' from overriding 'colors', see issue #4297) + """ + np.random.seed(0) + + data1 = np.random.random([20]).tolist() + data2 = np.random.random([10]).tolist() + data = [data1, data2] + + fig = plt.figure() + axobj = fig.add_subplot() + + axobj.eventplot(data, + colors=['r', 'b'], + color=['c', 'm'], + linewidths=[2, 1], + linewidth=[1, 2], + linestyles=['solid', 'dashed'], + linestyle=['dashdot', 'dotted']) + + assert len(recwarn) == 3 + assert all(issubclass(wi.category, mpl.MatplotlibDeprecationWarning) + for wi in recwarn) + + +def test_empty_eventplot(): + fig, ax = plt.subplots(1, 1) + ax.eventplot([[]], colors=[(0.0, 0.0, 0.0, 0.0)]) + plt.draw() + + +@pytest.mark.parametrize('data', [[[]], [[], [0, 1]], [[0, 1], []]]) +@pytest.mark.parametrize('orientation', [None, 'vertical', 'horizontal']) +def test_eventplot_orientation(data, orientation): + """Introduced when fixing issue #6412.""" + opts = {} if orientation is None else {'orientation': orientation} + fig, ax = plt.subplots(1, 1) + ax.eventplot(data, **opts) + plt.draw() + + +@check_figures_equal(extensions=['png']) +def test_eventplot_units_list(fig_test, fig_ref): + # test that list of lists converted properly: + ts_1 = [datetime.datetime(2021, 1, 1), datetime.datetime(2021, 1, 2), + datetime.datetime(2021, 1, 3)] + ts_2 = [datetime.datetime(2021, 1, 15), datetime.datetime(2021, 1, 16)] + + ax = fig_ref.subplots() + ax.eventplot(ts_1, lineoffsets=0) + ax.eventplot(ts_2, lineoffsets=1) + + ax = fig_test.subplots() + ax.eventplot([ts_1, ts_2]) + + +@image_comparison(['marker_styles.png'], remove_text=True) +def test_marker_styles(): + fig, ax = plt.subplots() + # Since generation of the test image, None was removed but 'none' was + # added. By moving 'none' to the front (=former sorted place of None) + # we can avoid regenerating the test image. This can be removed if the + # test image has to be regenerated for other reasons. + markers = sorted(matplotlib.markers.MarkerStyle.markers, + key=lambda x: str(type(x))+str(x)) + markers.remove('none') + markers = ['none', *markers] + for y, marker in enumerate(markers): + ax.plot((y % 2)*5 + np.arange(10)*10, np.ones(10)*10*y, linestyle='', + marker=marker, markersize=10+y/5, label=marker) + + +@image_comparison(['rc_markerfill.png']) +def test_markers_fillstyle_rcparams(): + fig, ax = plt.subplots() + x = np.arange(7) + for idx, (style, marker) in enumerate( + [('top', 's'), ('bottom', 'o'), ('none', '^')]): + matplotlib.rcParams['markers.fillstyle'] = style + ax.plot(x+idx, marker=marker) + + +@image_comparison(['vertex_markers.png'], remove_text=True) +def test_vertex_markers(): + data = list(range(10)) + marker_as_tuple = ((-1, -1), (1, -1), (1, 1), (-1, 1)) + marker_as_list = [(-1, -1), (1, -1), (1, 1), (-1, 1)] + fig, ax = plt.subplots() + ax.plot(data, linestyle='', marker=marker_as_tuple, mfc='k') + ax.plot(data[::-1], linestyle='', marker=marker_as_list, mfc='b') + ax.set_xlim([-1, 10]) + ax.set_ylim([-1, 10]) + + +@image_comparison(['vline_hline_zorder', 'errorbar_zorder'], + tol=0 if platform.machine() == 'x86_64' else 0.02) +def test_eb_line_zorder(): + x = list(range(10)) + + # First illustrate basic pyplot interface, using defaults where possible. + fig = plt.figure() + ax = fig.gca() + ax.plot(x, lw=10, zorder=5) + ax.axhline(1, color='red', lw=10, zorder=1) + ax.axhline(5, color='green', lw=10, zorder=10) + ax.axvline(7, color='m', lw=10, zorder=7) + ax.axvline(2, color='k', lw=10, zorder=3) + + ax.set_title("axvline and axhline zorder test") + + # Now switch to a more OO interface to exercise more features. + fig = plt.figure() + ax = fig.gca() + x = list(range(10)) + y = np.zeros(10) + yerr = list(range(10)) + ax.errorbar(x, y, yerr=yerr, zorder=5, lw=5, color='r') + for j in range(10): + ax.axhline(j, lw=5, color='k', zorder=j) + ax.axhline(-j, lw=5, color='k', zorder=j) + + ax.set_title("errorbar zorder test") + + +@check_figures_equal() +def test_axline_loglog(fig_test, fig_ref): + ax = fig_test.subplots() + ax.set(xlim=(0.1, 10), ylim=(1e-3, 1)) + ax.loglog([.3, .6], [.3, .6], ".-") + ax.axline((1, 1e-3), (10, 1e-2), c="k") + + ax = fig_ref.subplots() + ax.set(xlim=(0.1, 10), ylim=(1e-3, 1)) + ax.loglog([.3, .6], [.3, .6], ".-") + ax.loglog([1, 10], [1e-3, 1e-2], c="k") + + +@check_figures_equal() +def test_axline(fig_test, fig_ref): + ax = fig_test.subplots() + ax.set(xlim=(-1, 1), ylim=(-1, 1)) + ax.axline((0, 0), (1, 1)) + ax.axline((0, 0), (1, 0), color='C1') + ax.axline((0, 0.5), (1, 0.5), color='C2') + # slopes + ax.axline((-0.7, -0.5), slope=0, color='C3') + ax.axline((1, -0.5), slope=-0.5, color='C4') + ax.axline((-0.5, 1), slope=float('inf'), color='C5') + + ax = fig_ref.subplots() + ax.set(xlim=(-1, 1), ylim=(-1, 1)) + ax.plot([-1, 1], [-1, 1]) + ax.axhline(0, color='C1') + ax.axhline(0.5, color='C2') + # slopes + ax.axhline(-0.5, color='C3') + ax.plot([-1, 1], [0.5, -0.5], color='C4') + ax.axvline(-0.5, color='C5') + + +@check_figures_equal() +def test_axline_transaxes(fig_test, fig_ref): + ax = fig_test.subplots() + ax.set(xlim=(-1, 1), ylim=(-1, 1)) + ax.axline((0, 0), slope=1, transform=ax.transAxes) + ax.axline((1, 0.5), slope=1, color='C1', transform=ax.transAxes) + ax.axline((0.5, 0.5), slope=0, color='C2', transform=ax.transAxes) + ax.axline((0.5, 0), (0.5, 1), color='C3', transform=ax.transAxes) + + ax = fig_ref.subplots() + ax.set(xlim=(-1, 1), ylim=(-1, 1)) + ax.plot([-1, 1], [-1, 1]) + ax.plot([0, 1], [-1, 0], color='C1') + ax.plot([-1, 1], [0, 0], color='C2') + ax.plot([0, 0], [-1, 1], color='C3') + + +@check_figures_equal() +def test_axline_transaxes_panzoom(fig_test, fig_ref): + # test that it is robust against pan/zoom and + # figure resize after plotting + ax = fig_test.subplots() + ax.set(xlim=(-1, 1), ylim=(-1, 1)) + ax.axline((0, 0), slope=1, transform=ax.transAxes) + ax.axline((0.5, 0.5), slope=2, color='C1', transform=ax.transAxes) + ax.axline((0.5, 0.5), slope=0, color='C2', transform=ax.transAxes) + ax.set(xlim=(0, 5), ylim=(0, 10)) + fig_test.set_size_inches(3, 3) + + ax = fig_ref.subplots() + ax.set(xlim=(0, 5), ylim=(0, 10)) + fig_ref.set_size_inches(3, 3) + ax.plot([0, 5], [0, 5]) + ax.plot([0, 5], [0, 10], color='C1') + ax.plot([0, 5], [5, 5], color='C2') + + +def test_axline_args(): + """Exactly one of *xy2* and *slope* must be specified.""" + fig, ax = plt.subplots() + with pytest.raises(TypeError): + ax.axline((0, 0)) # missing second parameter + with pytest.raises(TypeError): + ax.axline((0, 0), (1, 1), slope=1) # redundant parameters + ax.set_xscale('log') + with pytest.raises(TypeError): + ax.axline((0, 0), slope=1) + ax.set_xscale('linear') + ax.set_yscale('log') + with pytest.raises(TypeError): + ax.axline((0, 0), slope=1) + ax.set_yscale('linear') + with pytest.raises(ValueError): + ax.axline((0, 0), (0, 0)) # two identical points are not allowed + plt.draw() + + +@image_comparison(['vlines_basic', 'vlines_with_nan', 'vlines_masked'], + extensions=['png']) +def test_vlines(): + # normal + x1 = [2, 3, 4, 5, 7] + y1 = [2, -6, 3, 8, 2] + fig1, ax1 = plt.subplots() + ax1.vlines(x1, 0, y1, colors='g', linewidth=5) + + # GH #7406 + x2 = [2, 3, 4, 5, 6, 7] + y2 = [2, -6, 3, 8, np.nan, 2] + fig2, (ax2, ax3, ax4) = plt.subplots(nrows=3, figsize=(4, 8)) + ax2.vlines(x2, 0, y2, colors='g', linewidth=5) + + x3 = [2, 3, 4, 5, 6, 7] + y3 = [np.nan, 2, -6, 3, 8, 2] + ax3.vlines(x3, 0, y3, colors='r', linewidth=3, linestyle='--') + + x4 = [2, 3, 4, 5, 6, 7] + y4 = [np.nan, 2, -6, 3, 8, np.nan] + ax4.vlines(x4, 0, y4, colors='k', linewidth=2) + + # tweak the x-axis so we can see the lines better + for ax in [ax1, ax2, ax3, ax4]: + ax.set_xlim(0, 10) + + # check that the y-lims are all automatically the same + assert ax1.get_ylim() == ax2.get_ylim() + assert ax1.get_ylim() == ax3.get_ylim() + assert ax1.get_ylim() == ax4.get_ylim() + + fig3, ax5 = plt.subplots() + x5 = np.ma.masked_equal([2, 4, 6, 8, 10, 12], 8) + ymin5 = np.ma.masked_equal([0, 1, -1, 0, 2, 1], 2) + ymax5 = np.ma.masked_equal([13, 14, 15, 16, 17, 18], 18) + ax5.vlines(x5, ymin5, ymax5, colors='k', linewidth=2) + ax5.set_xlim(0, 15) + + +def test_vlines_default(): + fig, ax = plt.subplots() + with mpl.rc_context({'lines.color': 'red'}): + lines = ax.vlines(0.5, 0, 1) + assert mpl.colors.same_color(lines.get_color(), 'red') + + +@image_comparison(['hlines_basic', 'hlines_with_nan', 'hlines_masked'], + extensions=['png']) +def test_hlines(): + # normal + y1 = [2, 3, 4, 5, 7] + x1 = [2, -6, 3, 8, 2] + fig1, ax1 = plt.subplots() + ax1.hlines(y1, 0, x1, colors='g', linewidth=5) + + # GH #7406 + y2 = [2, 3, 4, 5, 6, 7] + x2 = [2, -6, 3, 8, np.nan, 2] + fig2, (ax2, ax3, ax4) = plt.subplots(nrows=3, figsize=(4, 8)) + ax2.hlines(y2, 0, x2, colors='g', linewidth=5) + + y3 = [2, 3, 4, 5, 6, 7] + x3 = [np.nan, 2, -6, 3, 8, 2] + ax3.hlines(y3, 0, x3, colors='r', linewidth=3, linestyle='--') + + y4 = [2, 3, 4, 5, 6, 7] + x4 = [np.nan, 2, -6, 3, 8, np.nan] + ax4.hlines(y4, 0, x4, colors='k', linewidth=2) + + # tweak the y-axis so we can see the lines better + for ax in [ax1, ax2, ax3, ax4]: + ax.set_ylim(0, 10) + + # check that the x-lims are all automatically the same + assert ax1.get_xlim() == ax2.get_xlim() + assert ax1.get_xlim() == ax3.get_xlim() + assert ax1.get_xlim() == ax4.get_xlim() + + fig3, ax5 = plt.subplots() + y5 = np.ma.masked_equal([2, 4, 6, 8, 10, 12], 8) + xmin5 = np.ma.masked_equal([0, 1, -1, 0, 2, 1], 2) + xmax5 = np.ma.masked_equal([13, 14, 15, 16, 17, 18], 18) + ax5.hlines(y5, xmin5, xmax5, colors='k', linewidth=2) + ax5.set_ylim(0, 15) + + +def test_hlines_default(): + fig, ax = plt.subplots() + with mpl.rc_context({'lines.color': 'red'}): + lines = ax.hlines(0.5, 0, 1) + assert mpl.colors.same_color(lines.get_color(), 'red') + + +@pytest.mark.parametrize('data', [[1, 2, 3, np.nan, 5], + np.ma.masked_equal([1, 2, 3, 4, 5], 4)]) +@check_figures_equal(extensions=["png"]) +def test_lines_with_colors(fig_test, fig_ref, data): + test_colors = ['red', 'green', 'blue', 'purple', 'orange'] + fig_test.add_subplot(2, 1, 1).vlines(data, 0, 1, + colors=test_colors, linewidth=5) + fig_test.add_subplot(2, 1, 2).hlines(data, 0, 1, + colors=test_colors, linewidth=5) + + expect_xy = [1, 2, 3, 5] + expect_color = ['red', 'green', 'blue', 'orange'] + fig_ref.add_subplot(2, 1, 1).vlines(expect_xy, 0, 1, + colors=expect_color, linewidth=5) + fig_ref.add_subplot(2, 1, 2).hlines(expect_xy, 0, 1, + colors=expect_color, linewidth=5) + + +@image_comparison(['vlines_hlines_blended_transform'], + extensions=['png'], style='mpl20') +def test_vlines_hlines_blended_transform(): + t = np.arange(5.0, 10.0, 0.1) + s = np.exp(-t) + np.sin(2 * np.pi * t) + 10 + fig, (hax, vax) = plt.subplots(2, 1, figsize=(6, 6)) + hax.plot(t, s, '^') + hax.hlines([10, 9], xmin=0, xmax=0.5, + transform=hax.get_yaxis_transform(), colors='r') + vax.plot(t, s, '^') + vax.vlines([6, 7], ymin=0, ymax=0.15, transform=vax.get_xaxis_transform(), + colors='r') + + +@image_comparison(['step_linestyle', 'step_linestyle'], remove_text=True, + tol=0.2) +def test_step_linestyle(): + # Tolerance caused by reordering of floating-point operations + # Remove when regenerating the images + x = y = np.arange(10) + + # First illustrate basic pyplot interface, using defaults where possible. + fig, ax_lst = plt.subplots(2, 2) + ax_lst = ax_lst.flatten() + + ln_styles = ['-', '--', '-.', ':'] + + for ax, ls in zip(ax_lst, ln_styles): + ax.step(x, y, lw=5, linestyle=ls, where='pre') + ax.step(x, y + 1, lw=5, linestyle=ls, where='mid') + ax.step(x, y + 2, lw=5, linestyle=ls, where='post') + ax.set_xlim([-1, 5]) + ax.set_ylim([-1, 7]) + + # Reuse testcase from above for a labeled data test + data = {"X": x, "Y0": y, "Y1": y+1, "Y2": y+2} + fig, ax_lst = plt.subplots(2, 2) + ax_lst = ax_lst.flatten() + ln_styles = ['-', '--', '-.', ':'] + for ax, ls in zip(ax_lst, ln_styles): + ax.step("X", "Y0", lw=5, linestyle=ls, where='pre', data=data) + ax.step("X", "Y1", lw=5, linestyle=ls, where='mid', data=data) + ax.step("X", "Y2", lw=5, linestyle=ls, where='post', data=data) + ax.set_xlim([-1, 5]) + ax.set_ylim([-1, 7]) + + +@image_comparison(['mixed_collection'], remove_text=True) +def test_mixed_collection(): + # First illustrate basic pyplot interface, using defaults where possible. + fig, ax = plt.subplots() + + c = mpatches.Circle((8, 8), radius=4, facecolor='none', edgecolor='green') + + # PDF can optimize this one + p1 = mpl.collections.PatchCollection([c], match_original=True) + p1.set_offsets([[0, 0], [24, 24]]) + p1.set_linewidths([1, 5]) + + # PDF can't optimize this one, because the alpha of the edge changes + p2 = mpl.collections.PatchCollection([c], match_original=True) + p2.set_offsets([[48, 0], [-32, -16]]) + p2.set_linewidths([1, 5]) + p2.set_edgecolors([[0, 0, 0.1, 1.0], [0, 0, 0.1, 0.5]]) + + ax.patch.set_color('0.5') + ax.add_collection(p1) + ax.add_collection(p2) + + ax.set_xlim(0, 16) + ax.set_ylim(0, 16) + + +def test_subplot_key_hash(): + ax = plt.subplot(np.int32(5), np.int64(1), 1) + ax.twinx() + assert ax.get_subplotspec().get_geometry() == (5, 1, 0, 0) + + +@image_comparison( + ["specgram_freqs.png", "specgram_freqs_linear.png", + "specgram_noise.png", "specgram_noise_linear.png"], + remove_text=True, tol=0.07, style="default") +def test_specgram(): + """Test axes.specgram in default (psd) mode.""" + + # use former defaults to match existing baseline image + matplotlib.rcParams['image.interpolation'] = 'nearest' + + n = 1000 + Fs = 10. + + fstims = [[Fs/4, Fs/5, Fs/11], [Fs/4.7, Fs/5.6, Fs/11.9]] + NFFT_freqs = int(10 * Fs / np.min(fstims)) + x = np.arange(0, n, 1/Fs) + y_freqs = np.concatenate( + np.sin(2 * np.pi * np.multiply.outer(fstims, x)).sum(axis=1)) + + NFFT_noise = int(10 * Fs / 11) + np.random.seed(0) + y_noise = np.concatenate([np.random.standard_normal(n), np.random.rand(n)]) + + all_sides = ["default", "onesided", "twosided"] + for y, NFFT in [(y_freqs, NFFT_freqs), (y_noise, NFFT_noise)]: + noverlap = NFFT // 2 + pad_to = int(2 ** np.ceil(np.log2(NFFT))) + for ax, sides in zip(plt.figure().subplots(3), all_sides): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides) + for ax, sides in zip(plt.figure().subplots(3), all_sides): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides, + scale="linear", norm=matplotlib.colors.LogNorm()) + + +@image_comparison( + ["specgram_magnitude_freqs.png", "specgram_magnitude_freqs_linear.png", + "specgram_magnitude_noise.png", "specgram_magnitude_noise_linear.png"], + remove_text=True, tol=0.07, style="default") +def test_specgram_magnitude(): + """Test axes.specgram in magnitude mode.""" + + # use former defaults to match existing baseline image + matplotlib.rcParams['image.interpolation'] = 'nearest' + + n = 1000 + Fs = 10. + + fstims = [[Fs/4, Fs/5, Fs/11], [Fs/4.7, Fs/5.6, Fs/11.9]] + NFFT_freqs = int(100 * Fs / np.min(fstims)) + x = np.arange(0, n, 1/Fs) + y = np.sin(2 * np.pi * np.multiply.outer(fstims, x)).sum(axis=1) + y[:, -1] = 1 + y_freqs = np.hstack(y) + + NFFT_noise = int(10 * Fs / 11) + np.random.seed(0) + y_noise = np.concatenate([np.random.standard_normal(n), np.random.rand(n)]) + + all_sides = ["default", "onesided", "twosided"] + for y, NFFT in [(y_freqs, NFFT_freqs), (y_noise, NFFT_noise)]: + noverlap = NFFT // 2 + pad_to = int(2 ** np.ceil(np.log2(NFFT))) + for ax, sides in zip(plt.figure().subplots(3), all_sides): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides, mode="magnitude") + for ax, sides in zip(plt.figure().subplots(3), all_sides): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides, mode="magnitude", + scale="linear", norm=matplotlib.colors.LogNorm()) + + +@image_comparison( + ["specgram_angle_freqs.png", "specgram_phase_freqs.png", + "specgram_angle_noise.png", "specgram_phase_noise.png"], + remove_text=True, tol=0.07, style="default") +def test_specgram_angle(): + """Test axes.specgram in angle and phase modes.""" + + # use former defaults to match existing baseline image + matplotlib.rcParams['image.interpolation'] = 'nearest' + + n = 1000 + Fs = 10. + + fstims = [[Fs/4, Fs/5, Fs/11], [Fs/4.7, Fs/5.6, Fs/11.9]] + NFFT_freqs = int(10 * Fs / np.min(fstims)) + x = np.arange(0, n, 1/Fs) + y = np.sin(2 * np.pi * np.multiply.outer(fstims, x)).sum(axis=1) + y[:, -1] = 1 + y_freqs = np.hstack(y) + + NFFT_noise = int(10 * Fs / 11) + np.random.seed(0) + y_noise = np.concatenate([np.random.standard_normal(n), np.random.rand(n)]) + + all_sides = ["default", "onesided", "twosided"] + for y, NFFT in [(y_freqs, NFFT_freqs), (y_noise, NFFT_noise)]: + noverlap = NFFT // 2 + pad_to = int(2 ** np.ceil(np.log2(NFFT))) + for mode in ["angle", "phase"]: + for ax, sides in zip(plt.figure().subplots(3), all_sides): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides, mode=mode) + with pytest.raises(ValueError): + ax.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap, + pad_to=pad_to, sides=sides, mode=mode, + scale="dB") + + +def test_specgram_fs_none(): + """Test axes.specgram when Fs is None, should not throw error.""" + spec, freqs, t, im = plt.specgram(np.ones(300), Fs=None, scale='linear') + xmin, xmax, freq0, freq1 = im.get_extent() + assert xmin == 32 and xmax == 96 + + +@check_figures_equal(extensions=["png"]) +def test_specgram_origin_rcparam(fig_test, fig_ref): + """Test specgram ignores image.origin rcParam and uses origin 'upper'.""" + t = np.arange(500) + signal = np.sin(t) + + plt.rcParams["image.origin"] = 'upper' + + # Reference: First graph using default origin in imshow (upper), + fig_ref.subplots().specgram(signal) + + # Try to overwrite the setting trying to flip the specgram + plt.rcParams["image.origin"] = 'lower' + + # Test: origin='lower' should be ignored + fig_test.subplots().specgram(signal) + + +def test_specgram_origin_kwarg(): + """Ensure passing origin as a kwarg raises a TypeError.""" + t = np.arange(500) + signal = np.sin(t) + + with pytest.raises(TypeError): + plt.specgram(signal, origin='lower') + + +@image_comparison( + ["psd_freqs.png", "csd_freqs.png", "psd_noise.png", "csd_noise.png"], + remove_text=True, tol=0.002) +def test_psd_csd(): + n = 10000 + Fs = 100. + + fstims = [[Fs/4, Fs/5, Fs/11], [Fs/4.7, Fs/5.6, Fs/11.9]] + NFFT_freqs = int(1000 * Fs / np.min(fstims)) + x = np.arange(0, n, 1/Fs) + ys_freqs = np.sin(2 * np.pi * np.multiply.outer(fstims, x)).sum(axis=1) + + NFFT_noise = int(1000 * Fs / 11) + np.random.seed(0) + ys_noise = [np.random.standard_normal(n), np.random.rand(n)] + + all_kwargs = [{"sides": "default"}, + {"sides": "onesided", "return_line": False}, + {"sides": "twosided", "return_line": True}] + for ys, NFFT in [(ys_freqs, NFFT_freqs), (ys_noise, NFFT_noise)]: + noverlap = NFFT // 2 + pad_to = int(2 ** np.ceil(np.log2(NFFT))) + for ax, kwargs in zip(plt.figure().subplots(3), all_kwargs): + ret = ax.psd(np.concatenate(ys), NFFT=NFFT, Fs=Fs, + noverlap=noverlap, pad_to=pad_to, **kwargs) + assert len(ret) == 2 + kwargs.get("return_line", False) + ax.set(xlabel="", ylabel="") + for ax, kwargs in zip(plt.figure().subplots(3), all_kwargs): + ret = ax.csd(*ys, NFFT=NFFT, Fs=Fs, + noverlap=noverlap, pad_to=pad_to, **kwargs) + assert len(ret) == 2 + kwargs.get("return_line", False) + ax.set(xlabel="", ylabel="") + + +@image_comparison( + ["magnitude_spectrum_freqs_linear.png", + "magnitude_spectrum_freqs_dB.png", + "angle_spectrum_freqs.png", + "phase_spectrum_freqs.png", + "magnitude_spectrum_noise_linear.png", + "magnitude_spectrum_noise_dB.png", + "angle_spectrum_noise.png", + "phase_spectrum_noise.png"], + remove_text=True) +def test_spectrum(): + n = 10000 + Fs = 100. + + fstims1 = [Fs/4, Fs/5, Fs/11] + NFFT = int(1000 * Fs / min(fstims1)) + pad_to = int(2 ** np.ceil(np.log2(NFFT))) + + x = np.arange(0, n, 1/Fs) + y_freqs = ((np.sin(2 * np.pi * np.outer(x, fstims1)) * 10**np.arange(3)) + .sum(axis=1)) + np.random.seed(0) + y_noise = np.hstack([np.random.standard_normal(n), np.random.rand(n)]) - .5 + + all_sides = ["default", "onesided", "twosided"] + kwargs = {"Fs": Fs, "pad_to": pad_to} + for y in [y_freqs, y_noise]: + for ax, sides in zip(plt.figure().subplots(3), all_sides): + spec, freqs, line = ax.magnitude_spectrum(y, sides=sides, **kwargs) + ax.set(xlabel="", ylabel="") + for ax, sides in zip(plt.figure().subplots(3), all_sides): + spec, freqs, line = ax.magnitude_spectrum(y, sides=sides, **kwargs, + scale="dB") + ax.set(xlabel="", ylabel="") + for ax, sides in zip(plt.figure().subplots(3), all_sides): + spec, freqs, line = ax.angle_spectrum(y, sides=sides, **kwargs) + ax.set(xlabel="", ylabel="") + for ax, sides in zip(plt.figure().subplots(3), all_sides): + spec, freqs, line = ax.phase_spectrum(y, sides=sides, **kwargs) + ax.set(xlabel="", ylabel="") + + +def test_psd_csd_edge_cases(): + # Inverted yaxis or fully zero inputs used to throw exceptions. + axs = plt.figure().subplots(2) + for ax in axs: + ax.yaxis.set(inverted=True) + with np.errstate(divide="ignore"): + axs[0].psd(np.zeros(5)) + axs[1].csd(np.zeros(5), np.zeros(5)) + + +@check_figures_equal(extensions=['png']) +def test_twin_remove(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_twinx = ax_test.twinx() + ax_twiny = ax_test.twiny() + ax_twinx.remove() + ax_twiny.remove() + + ax_ref = fig_ref.add_subplot() + # Ideally we also undo tick changes when calling ``remove()``, but for now + # manually set the ticks of the reference image to match the test image + ax_ref.xaxis.tick_bottom() + ax_ref.yaxis.tick_left() + + +@image_comparison(['twin_spines.png'], remove_text=True) +def test_twin_spines(): + + def make_patch_spines_invisible(ax): + ax.set_frame_on(True) + ax.patch.set_visible(False) + ax.spines[:].set_visible(False) + + fig = plt.figure(figsize=(4, 3)) + fig.subplots_adjust(right=0.75) + + host = fig.add_subplot() + par1 = host.twinx() + par2 = host.twinx() + + # Offset the right spine of par2. The ticks and label have already been + # placed on the right by twinx above. + par2.spines.right.set_position(("axes", 1.2)) + # Having been created by twinx, par2 has its frame off, so the line of + # its detached spine is invisible. First, activate the frame but make + # the patch and spines invisible. + make_patch_spines_invisible(par2) + # Second, show the right spine. + par2.spines.right.set_visible(True) + + p1, = host.plot([0, 1, 2], [0, 1, 2], "b-") + p2, = par1.plot([0, 1, 2], [0, 3, 2], "r-") + p3, = par2.plot([0, 1, 2], [50, 30, 15], "g-") + + host.set_xlim(0, 2) + host.set_ylim(0, 2) + par1.set_ylim(0, 4) + par2.set_ylim(1, 65) + + host.yaxis.label.set_color(p1.get_color()) + par1.yaxis.label.set_color(p2.get_color()) + par2.yaxis.label.set_color(p3.get_color()) + + tkw = dict(size=4, width=1.5) + host.tick_params(axis='y', colors=p1.get_color(), **tkw) + par1.tick_params(axis='y', colors=p2.get_color(), **tkw) + par2.tick_params(axis='y', colors=p3.get_color(), **tkw) + host.tick_params(axis='x', **tkw) + + +@image_comparison(['twin_spines_on_top.png', 'twin_spines_on_top.png'], + remove_text=True) +def test_twin_spines_on_top(): + matplotlib.rcParams['axes.linewidth'] = 48.0 + matplotlib.rcParams['lines.linewidth'] = 48.0 + + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + + data = np.array([[1000, 1100, 1200, 1250], + [310, 301, 360, 400]]) + + ax2 = ax1.twinx() + + ax1.plot(data[0], data[1]/1E3, color='#BEAED4') + ax1.fill_between(data[0], data[1]/1E3, color='#BEAED4', alpha=.8) + + ax2.plot(data[0], data[1]/1E3, color='#7FC97F') + ax2.fill_between(data[0], data[1]/1E3, color='#7FC97F', alpha=.5) + + # Reuse testcase from above for a labeled data test + data = {"i": data[0], "j": data[1]/1E3} + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + ax2 = ax1.twinx() + ax1.plot("i", "j", color='#BEAED4', data=data) + ax1.fill_between("i", "j", color='#BEAED4', alpha=.8, data=data) + ax2.plot("i", "j", color='#7FC97F', data=data) + ax2.fill_between("i", "j", color='#7FC97F', alpha=.5, data=data) + + +@pytest.mark.parametrize("grid_which, major_visible, minor_visible", [ + ("both", True, True), + ("major", True, False), + ("minor", False, True), +]) +def test_rcparam_grid_minor(grid_which, major_visible, minor_visible): + mpl.rcParams.update({"axes.grid": True, "axes.grid.which": grid_which}) + fig, ax = plt.subplots() + fig.canvas.draw() + assert all(tick.gridline.get_visible() == major_visible + for tick in ax.xaxis.majorTicks) + assert all(tick.gridline.get_visible() == minor_visible + for tick in ax.xaxis.minorTicks) + + +def test_grid(): + fig, ax = plt.subplots() + ax.grid() + fig.canvas.draw() + assert ax.xaxis.majorTicks[0].gridline.get_visible() + ax.grid(visible=False) + fig.canvas.draw() + assert not ax.xaxis.majorTicks[0].gridline.get_visible() + ax.grid(visible=True) + fig.canvas.draw() + assert ax.xaxis.majorTicks[0].gridline.get_visible() + ax.grid() + fig.canvas.draw() + assert not ax.xaxis.majorTicks[0].gridline.get_visible() + + +def test_reset_grid(): + fig, ax = plt.subplots() + ax.tick_params(reset=True, which='major', labelsize=10) + assert not ax.xaxis.majorTicks[0].gridline.get_visible() + ax.grid(color='red') # enables grid + assert ax.xaxis.majorTicks[0].gridline.get_visible() + + with plt.rc_context({'axes.grid': True}): + ax.clear() + ax.tick_params(reset=True, which='major', labelsize=10) + assert ax.xaxis.majorTicks[0].gridline.get_visible() + + +@check_figures_equal(extensions=['png']) +def test_reset_ticks(fig_test, fig_ref): + for fig in [fig_ref, fig_test]: + ax = fig.add_subplot() + ax.grid(True) + ax.tick_params( + direction='in', length=10, width=5, color='C0', pad=12, + labelsize=14, labelcolor='C1', labelrotation=45, + grid_color='C2', grid_alpha=0.8, grid_linewidth=3, + grid_linestyle='--') + fig.draw_without_rendering() + + # After we've changed any setting on ticks, reset_ticks will mean + # re-creating them from scratch. This *should* appear the same as not + # resetting them. + for ax in fig_test.axes: + ax.xaxis.reset_ticks() + ax.yaxis.reset_ticks() + + +def test_vline_limit(): + fig = plt.figure() + ax = fig.gca() + ax.axvline(0.5) + ax.plot([-0.1, 0, 0.2, 0.1]) + assert_allclose(ax.get_ylim(), (-.1, .2)) + + +@pytest.mark.parametrize('fv, fh, args', [[plt.axvline, plt.axhline, (1,)], + [plt.axvspan, plt.axhspan, (1, 1)]]) +def test_axline_minmax(fv, fh, args): + bad_lim = matplotlib.dates.num2date(1) + # Check vertical functions + with pytest.raises(ValueError, match='ymin must be a single scalar value'): + fv(*args, ymin=bad_lim, ymax=1) + with pytest.raises(ValueError, match='ymax must be a single scalar value'): + fv(*args, ymin=1, ymax=bad_lim) + # Check horizontal functions + with pytest.raises(ValueError, match='xmin must be a single scalar value'): + fh(*args, xmin=bad_lim, xmax=1) + with pytest.raises(ValueError, match='xmax must be a single scalar value'): + fh(*args, xmin=1, xmax=bad_lim) + + +def test_empty_shared_subplots(): + # empty plots with shared axes inherit limits from populated plots + fig, axs = plt.subplots(nrows=1, ncols=2, sharex=True, sharey=True) + axs[0].plot([1, 2, 3], [2, 4, 6]) + x0, x1 = axs[1].get_xlim() + y0, y1 = axs[1].get_ylim() + assert x0 <= 1 + assert x1 >= 3 + assert y0 <= 2 + assert y1 >= 6 + + +def test_shared_with_aspect_1(): + # allow sharing one axis + for adjustable in ['box', 'datalim']: + fig, axs = plt.subplots(nrows=2, sharex=True) + axs[0].set_aspect(2, adjustable=adjustable, share=True) + assert axs[1].get_aspect() == 2 + assert axs[1].get_adjustable() == adjustable + + fig, axs = plt.subplots(nrows=2, sharex=True) + axs[0].set_aspect(2, adjustable=adjustable) + assert axs[1].get_aspect() == 'auto' + + +def test_shared_with_aspect_2(): + # Share 2 axes only with 'box': + fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True) + axs[0].set_aspect(2, share=True) + axs[0].plot([1, 2], [3, 4]) + axs[1].plot([3, 4], [1, 2]) + plt.draw() # Trigger apply_aspect(). + assert axs[0].get_xlim() == axs[1].get_xlim() + assert axs[0].get_ylim() == axs[1].get_ylim() + + +def test_shared_with_aspect_3(): + # Different aspect ratios: + for adjustable in ['box', 'datalim']: + fig, axs = plt.subplots(nrows=2, sharey=True) + axs[0].set_aspect(2, adjustable=adjustable) + axs[1].set_aspect(0.5, adjustable=adjustable) + axs[0].plot([1, 2], [3, 4]) + axs[1].plot([3, 4], [1, 2]) + plt.draw() # Trigger apply_aspect(). + assert axs[0].get_xlim() != axs[1].get_xlim() + assert axs[0].get_ylim() == axs[1].get_ylim() + fig_aspect = fig.bbox_inches.height / fig.bbox_inches.width + for ax in axs: + p = ax.get_position() + box_aspect = p.height / p.width + lim_aspect = ax.viewLim.height / ax.viewLim.width + expected = fig_aspect * box_aspect / lim_aspect + assert round(expected, 4) == round(ax.get_aspect(), 4) + + +def test_shared_aspect_error(): + fig, axes = plt.subplots(1, 2, sharex=True, sharey=True) + axes[0].axis("equal") + with pytest.raises(RuntimeError, match=r"set_aspect\(..., adjustable="): + fig.draw_without_rendering() + + +@pytest.mark.parametrize('err, args, kwargs, match', + ((TypeError, (1, 2), {}, + r"axis\(\) takes from 0 to 1 positional arguments " + "but 2 were given"), + (ValueError, ('foo', ), {}, + "Unrecognized string 'foo' to axis; try 'on' or " + "'off'"), + (TypeError, ([1, 2], ), {}, + "The first argument to axis*"), + (TypeError, tuple(), {'foo': None}, + r"axis\(\) got an unexpected keyword argument " + "'foo'"), + )) +def test_axis_errors(err, args, kwargs, match): + with pytest.raises(err, match=match): + plt.axis(*args, **kwargs) + + +def test_axis_method_errors(): + ax = plt.gca() + with pytest.raises(ValueError, match="unknown value for which: 'foo'"): + ax.get_xaxis_transform('foo') + with pytest.raises(ValueError, match="unknown value for which: 'foo'"): + ax.get_yaxis_transform('foo') + with pytest.raises(TypeError, match="Cannot supply both positional and"): + ax.set_prop_cycle('foo', label='bar') + with pytest.raises(ValueError, match="argument must be among"): + ax.set_anchor('foo') + with pytest.raises(ValueError, match="scilimits must be a sequence"): + ax.ticklabel_format(scilimits=1) + with pytest.raises(TypeError, match="Specifying 'loc' is disallowed"): + ax.set_xlabel('foo', loc='left', x=1) + with pytest.raises(TypeError, match="Specifying 'loc' is disallowed"): + ax.set_ylabel('foo', loc='top', y=1) + with pytest.raises(TypeError, match="Cannot pass both 'left'"): + ax.set_xlim(left=0, xmin=1) + with pytest.raises(TypeError, match="Cannot pass both 'right'"): + ax.set_xlim(right=0, xmax=1) + with pytest.raises(TypeError, match="Cannot pass both 'bottom'"): + ax.set_ylim(bottom=0, ymin=1) + with pytest.raises(TypeError, match="Cannot pass both 'top'"): + ax.set_ylim(top=0, ymax=1) + + +@pytest.mark.parametrize('twin', ('x', 'y')) +def test_twin_with_aspect(twin): + fig, ax = plt.subplots() + # test twinx or twiny + ax_twin = getattr(ax, f'twin{twin}')() + ax.set_aspect(5) + ax_twin.set_aspect(2) + assert_array_equal(ax.bbox.extents, + ax_twin.bbox.extents) + + +def test_relim_visible_only(): + x1 = (0., 10.) + y1 = (0., 10.) + x2 = (-10., 20.) + y2 = (-10., 30.) + + fig = matplotlib.figure.Figure() + ax = fig.add_subplot() + ax.plot(x1, y1) + assert ax.get_xlim() == x1 + assert ax.get_ylim() == y1 + line, = ax.plot(x2, y2) + assert ax.get_xlim() == x2 + assert ax.get_ylim() == y2 + line.set_visible(False) + assert ax.get_xlim() == x2 + assert ax.get_ylim() == y2 + + ax.relim(visible_only=True) + ax.autoscale_view() + + assert ax.get_xlim() == x1 + assert ax.get_ylim() == y1 + + +def test_text_labelsize(): + """ + tests for issue #1172 + """ + fig = plt.figure() + ax = fig.gca() + ax.tick_params(labelsize='large') + ax.tick_params(direction='out') + + +@image_comparison(['pie_default.png']) +def test_pie_default(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + fig1, ax1 = plt.subplots(figsize=(8, 6)) + ax1.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90) + + +@image_comparison(['pie_linewidth_0', 'pie_linewidth_0', 'pie_linewidth_0'], + extensions=['png'], style='mpl20') +def test_pie_linewidth_0(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + # Reuse testcase from above for a labeled data test + data = {"l": labels, "s": sizes, "c": colors, "ex": explode} + fig = plt.figure() + ax = fig.gca() + ax.pie("s", explode="ex", labels="l", colors="c", + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, data=data) + ax.axis('equal') + + # And again to test the pyplot functions which should also be able to be + # called with a data kwarg + plt.figure() + plt.pie("s", explode="ex", labels="l", colors="c", + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, data=data) + plt.axis('equal') + + +@image_comparison(['pie_center_radius.png'], style='mpl20') +def test_pie_center_radius(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, center=(1, 2), radius=1.5) + + plt.annotate("Center point", xy=(1, 2), xytext=(1, 1.3), + arrowprops=dict(arrowstyle="->", + connectionstyle="arc3"), + bbox=dict(boxstyle="square", facecolor="lightgrey")) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + +@image_comparison(['pie_linewidth_2.png'], style='mpl20') +def test_pie_linewidth_2(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 2}) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + +@image_comparison(['pie_ccw_true.png'], style='mpl20') +def test_pie_ccw_true(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + counterclock=True) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + +@image_comparison(['pie_frame_grid.png'], style='mpl20') +def test_pie_frame_grid(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + # only "explode" the 2nd slice (i.e. 'Hogs') + explode = (0, 0.1, 0, 0) + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, + frame=True, center=(2, 2)) + + plt.pie(sizes[::-1], explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, + frame=True, center=(5, 2)) + + plt.pie(sizes, explode=explode[::-1], labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + wedgeprops={'linewidth': 0}, + frame=True, center=(3, 5)) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + +@image_comparison(['pie_rotatelabels_true.png'], style='mpl20') +def test_pie_rotatelabels_true(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Hogwarts', 'Frogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + rotatelabels=True) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + +@image_comparison(['pie_no_label.png']) +def test_pie_nolabel_but_legend(): + labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, labeldistance=None, + rotatelabels=True) + plt.axis('equal') + plt.ylim(-1.2, 1.2) + plt.legend() + + +@image_comparison(['pie_shadow.png'], style='mpl20') +def test_pie_shadow(): + # Also acts as a test for the shade argument of Shadow + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice + _, axes = plt.subplots(2, 2) + axes[0][0].pie(sizes, explode=explode, colors=colors, + shadow=True, startangle=90, + wedgeprops={'linewidth': 0}) + + axes[0][1].pie(sizes, explode=explode, colors=colors, + shadow=False, startangle=90, + wedgeprops={'linewidth': 0}) + + axes[1][0].pie(sizes, explode=explode, colors=colors, + shadow={'ox': -0.05, 'oy': -0.05, 'shade': 0.9, 'edgecolor': 'none'}, + startangle=90, wedgeprops={'linewidth': 0}) + + axes[1][1].pie(sizes, explode=explode, colors=colors, + shadow={'ox': 0.05, 'linewidth': 2, 'shade': 0.2}, + startangle=90, wedgeprops={'linewidth': 0}) + + +def test_pie_textprops(): + data = [23, 34, 45] + labels = ["Long name 1", "Long name 2", "Long name 3"] + + textprops = dict(horizontalalignment="center", + verticalalignment="top", + rotation=90, + rotation_mode="anchor", + size=12, color="red") + + _, texts, autopct = plt.gca().pie(data, labels=labels, autopct='%.2f', + textprops=textprops) + for labels in [texts, autopct]: + for tx in labels: + assert tx.get_ha() == textprops["horizontalalignment"] + assert tx.get_va() == textprops["verticalalignment"] + assert tx.get_rotation() == textprops["rotation"] + assert tx.get_rotation_mode() == textprops["rotation_mode"] + assert tx.get_size() == textprops["size"] + assert tx.get_color() == textprops["color"] + + +def test_pie_get_negative_values(): + # Test the ValueError raised when feeding negative values into axes.pie + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.pie([5, 5, -3], explode=[0, .1, .2]) + + +def test_normalize_kwarg_pie(): + fig, ax = plt.subplots() + x = [0.3, 0.3, 0.1] + t1 = ax.pie(x=x, normalize=True) + assert abs(t1[0][-1].theta2 - 360.) < 1e-3 + t2 = ax.pie(x=x, normalize=False) + assert abs(t2[0][-1].theta2 - 360.) > 1e-3 + + +@check_figures_equal() +def test_pie_hatch_single(fig_test, fig_ref): + x = [0.3, 0.3, 0.1] + hatch = '+' + fig_test.subplots().pie(x, hatch=hatch) + wedges, _ = fig_ref.subplots().pie(x) + [w.set_hatch(hatch) for w in wedges] + + +@check_figures_equal() +def test_pie_hatch_multi(fig_test, fig_ref): + x = [0.3, 0.3, 0.1] + hatch = ['/', '+', '.'] + fig_test.subplots().pie(x, hatch=hatch) + wedges, _ = fig_ref.subplots().pie(x) + [w.set_hatch(hp) for w, hp in zip(wedges, hatch)] + + +@image_comparison(['set_get_ticklabels.png']) +def test_set_get_ticklabels(): + # test issue 2246 + fig, ax = plt.subplots(2) + ha = ['normal', 'set_x/yticklabels'] + + ax[0].plot(np.arange(10)) + ax[0].set_title(ha[0]) + + ax[1].plot(np.arange(10)) + ax[1].set_title(ha[1]) + + # set ticklabel to 1 plot in normal way + ax[0].set_xticks(range(10)) + ax[0].set_yticks(range(10)) + ax[0].set_xticklabels(['a', 'b', 'c', 'd'] + 6 * ['']) + ax[0].set_yticklabels(['11', '12', '13', '14'] + 6 * ['']) + + # set ticklabel to the other plot, expect the 2 plots have same label + # setting pass get_ticklabels return value as ticklabels argument + ax[1].set_xticks(ax[0].get_xticks()) + ax[1].set_yticks(ax[0].get_yticks()) + ax[1].set_xticklabels(ax[0].get_xticklabels()) + ax[1].set_yticklabels(ax[0].get_yticklabels()) + + +def test_set_ticks_kwargs_raise_error_without_labels(): + """ + When labels=None and any kwarg is passed, axis.set_ticks() raises a + ValueError. + """ + fig, ax = plt.subplots() + ticks = [1, 2, 3] + with pytest.raises(ValueError, match="Incorrect use of keyword argument 'alpha'"): + ax.xaxis.set_ticks(ticks, alpha=0.5) + + +@check_figures_equal(extensions=["png"]) +def test_set_ticks_with_labels(fig_test, fig_ref): + """ + Test that these two are identical:: + + set_xticks(ticks); set_xticklabels(labels, **kwargs) + set_xticks(ticks, labels, **kwargs) + + """ + ax = fig_ref.subplots() + ax.set_xticks([1, 2, 4, 6]) + ax.set_xticklabels(['a', 'b', 'c', 'd'], fontweight='bold') + ax.set_yticks([1, 3, 5]) + ax.set_yticks([2, 4], minor=True) + ax.set_yticklabels(['A', 'B'], minor=True) + + ax = fig_test.subplots() + ax.set_xticks([1, 2, 4, 6], ['a', 'b', 'c', 'd'], fontweight='bold') + ax.set_yticks([1, 3, 5]) + ax.set_yticks([2, 4], ['A', 'B'], minor=True) + + +def test_xticks_bad_args(): + ax = plt.figure().add_subplot() + with pytest.raises(TypeError, match='must be a sequence'): + ax.set_xticks([2, 9], 3.1) + with pytest.raises(ValueError, match='must be 1D'): + plt.xticks(np.arange(4).reshape((-1, 1))) + with pytest.raises(ValueError, match='must be 1D'): + plt.xticks(np.arange(4).reshape((1, -1))) + with pytest.raises(ValueError, match='must be 1D'): + plt.xticks(np.arange(4).reshape((-1, 1)), labels=range(4)) + with pytest.raises(ValueError, match='must be 1D'): + plt.xticks(np.arange(4).reshape((1, -1)), labels=range(4)) + + +def test_subsampled_ticklabels(): + # test issue 11937 + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + ax.xaxis.set_ticks(np.arange(10) + 0.1) + ax.locator_params(nbins=5) + ax.xaxis.set_ticklabels([c for c in "bcdefghijk"]) + plt.draw() + labels = [t.get_text() for t in ax.xaxis.get_ticklabels()] + assert labels == ['b', 'd', 'f', 'h', 'j'] + + +def test_mismatched_ticklabels(): + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + ax.xaxis.set_ticks([1.5, 2.5]) + with pytest.raises(ValueError): + ax.xaxis.set_ticklabels(['a', 'b', 'c']) + + +def test_empty_ticks_fixed_loc(): + # Smoke test that [] can be used to unset all tick labels + fig, ax = plt.subplots() + ax.bar([1, 2], [1, 2]) + ax.set_xticks([1, 2]) + ax.set_xticklabels([]) + + +@image_comparison(['retain_tick_visibility.png']) +def test_retain_tick_visibility(): + fig, ax = plt.subplots() + plt.plot([0, 1, 2], [0, -1, 4]) + plt.setp(ax.get_yticklabels(), visible=False) + ax.tick_params(axis="y", which="both", length=0) + + +def test_warn_too_few_labels(): + # note that the axis is still using an AutoLocator: + fig, ax = plt.subplots() + with pytest.warns( + UserWarning, + match=r'set_ticklabels\(\) should only be used with a fixed number'): + ax.set_xticklabels(['0', '0.1']) + # note that the axis is still using a FixedLocator: + fig, ax = plt.subplots() + ax.set_xticks([0, 0.5, 1]) + with pytest.raises(ValueError, + match='The number of FixedLocator locations'): + ax.set_xticklabels(['0', '0.1']) + + +def test_tick_label_update(): + # test issue 9397 + + fig, ax = plt.subplots() + + # Set up a dummy formatter + def formatter_func(x, pos): + return "unit value" if x == 1 else "" + ax.xaxis.set_major_formatter(plt.FuncFormatter(formatter_func)) + + # Force some of the x-axis ticks to be outside of the drawn range + ax.set_xticks([-1, 0, 1, 2, 3]) + ax.set_xlim(-0.5, 2.5) + + ax.figure.canvas.draw() + tick_texts = [tick.get_text() for tick in ax.xaxis.get_ticklabels()] + assert tick_texts == ["", "", "unit value", "", ""] + + +@image_comparison(['o_marker_path_snap.png'], savefig_kwarg={'dpi': 72}) +def test_o_marker_path_snap(): + fig, ax = plt.subplots() + ax.margins(.1) + for ms in range(1, 15): + ax.plot([1, 2, ], np.ones(2) + ms, 'o', ms=ms) + + for ms in np.linspace(1, 10, 25): + ax.plot([3, 4, ], np.ones(2) + ms, 'o', ms=ms) + + +def test_margins(): + # test all ways margins can be called + data = [1, 10] + xmin = 0.0 + xmax = len(data) - 1.0 + ymin = min(data) + ymax = max(data) + + fig1, ax1 = plt.subplots(1, 1) + ax1.plot(data) + ax1.margins(1) + assert ax1.margins() == (1, 1) + assert ax1.get_xlim() == (xmin - (xmax - xmin) * 1, + xmax + (xmax - xmin) * 1) + assert ax1.get_ylim() == (ymin - (ymax - ymin) * 1, + ymax + (ymax - ymin) * 1) + + fig2, ax2 = plt.subplots(1, 1) + ax2.plot(data) + ax2.margins(0.5, 2) + assert ax2.margins() == (0.5, 2) + assert ax2.get_xlim() == (xmin - (xmax - xmin) * 0.5, + xmax + (xmax - xmin) * 0.5) + assert ax2.get_ylim() == (ymin - (ymax - ymin) * 2, + ymax + (ymax - ymin) * 2) + + fig3, ax3 = plt.subplots(1, 1) + ax3.plot(data) + ax3.margins(x=-0.2, y=0.5) + assert ax3.margins() == (-0.2, 0.5) + assert ax3.get_xlim() == (xmin - (xmax - xmin) * -0.2, + xmax + (xmax - xmin) * -0.2) + assert ax3.get_ylim() == (ymin - (ymax - ymin) * 0.5, + ymax + (ymax - ymin) * 0.5) + + +def test_set_margin_updates_limits(): + mpl.style.use("default") + fig, ax = plt.subplots() + ax.plot([1, 2], [1, 2]) + ax.set(xscale="log", xmargin=0) + assert ax.get_xlim() == (1, 2) + + +@pytest.mark.parametrize('err, args, kwargs, match', ( + (ValueError, (-1,), {}, r'margin must be greater than -0\.5'), + (ValueError, (1, -1), {}, r'margin must be greater than -0\.5'), + (ValueError, tuple(), {'x': -1}, r'margin must be greater than -0\.5'), + (ValueError, tuple(), {'y': -1}, r'margin must be greater than -0\.5'), + (TypeError, (1, ), {'x': 1, 'y': 1}, + 'Cannot pass both positional and keyword arguments for x and/or y'), + (TypeError, (1, ), {'x': 1}, + 'Cannot pass both positional and keyword arguments for x and/or y'), + (TypeError, (1, 1, 1), {}, 'Must pass a single positional argument'), +)) +def test_margins_errors(err, args, kwargs, match): + with pytest.raises(err, match=match): + fig = plt.figure() + ax = fig.add_subplot() + ax.margins(*args, **kwargs) + + +def test_length_one_hist(): + fig, ax = plt.subplots() + ax.hist(1) + ax.hist([1]) + + +def test_set_xy_bound(): + fig = plt.figure() + ax = fig.add_subplot() + ax.set_xbound(2.0, 3.0) + assert ax.get_xbound() == (2.0, 3.0) + assert ax.get_xlim() == (2.0, 3.0) + ax.set_xbound(upper=4.0) + assert ax.get_xbound() == (2.0, 4.0) + assert ax.get_xlim() == (2.0, 4.0) + ax.set_xbound(lower=3.0) + assert ax.get_xbound() == (3.0, 4.0) + assert ax.get_xlim() == (3.0, 4.0) + + ax.set_ybound(2.0, 3.0) + assert ax.get_ybound() == (2.0, 3.0) + assert ax.get_ylim() == (2.0, 3.0) + ax.set_ybound(upper=4.0) + assert ax.get_ybound() == (2.0, 4.0) + assert ax.get_ylim() == (2.0, 4.0) + ax.set_ybound(lower=3.0) + assert ax.get_ybound() == (3.0, 4.0) + assert ax.get_ylim() == (3.0, 4.0) + + +def test_pathological_hexbin(): + # issue #2863 + mylist = [10] * 100 + fig, ax = plt.subplots(1, 1) + ax.hexbin(mylist, mylist) + fig.savefig(io.BytesIO()) # Check that no warning is emitted. + + +def test_color_None(): + # issue 3855 + fig, ax = plt.subplots() + ax.plot([1, 2], [1, 2], color=None) + + +def test_color_alias(): + # issues 4157 and 4162 + fig, ax = plt.subplots() + line = ax.plot([0, 1], c='lime')[0] + assert 'lime' == line.get_color() + + +def test_numerical_hist_label(): + fig, ax = plt.subplots() + ax.hist([range(15)] * 5, label=range(5)) + ax.legend() + + +def test_unicode_hist_label(): + fig, ax = plt.subplots() + a = (b'\xe5\xbe\x88\xe6\xbc\x82\xe4\xba\xae, ' + + b'r\xc3\xb6m\xc3\xa4n ch\xc3\xa4r\xc3\xa1ct\xc3\xa8rs') + b = b'\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d' + labels = [a.decode('utf-8'), + 'hi aardvark', + b.decode('utf-8'), + ] + + ax.hist([range(15)] * 3, label=labels) + ax.legend() + + +def test_move_offsetlabel(): + data = np.random.random(10) * 1e-22 + + fig, ax = plt.subplots() + ax.plot(data) + fig.canvas.draw() + before = ax.yaxis.offsetText.get_position() + assert ax.yaxis.offsetText.get_horizontalalignment() == 'left' + ax.yaxis.tick_right() + fig.canvas.draw() + after = ax.yaxis.offsetText.get_position() + assert after[0] > before[0] and after[1] == before[1] + assert ax.yaxis.offsetText.get_horizontalalignment() == 'right' + + fig, ax = plt.subplots() + ax.plot(data) + fig.canvas.draw() + before = ax.xaxis.offsetText.get_position() + assert ax.xaxis.offsetText.get_verticalalignment() == 'top' + ax.xaxis.tick_top() + fig.canvas.draw() + after = ax.xaxis.offsetText.get_position() + assert after[0] == before[0] and after[1] > before[1] + assert ax.xaxis.offsetText.get_verticalalignment() == 'bottom' + + +@image_comparison(['rc_spines.png'], savefig_kwarg={'dpi': 40}) +def test_rc_spines(): + rc_dict = { + 'axes.spines.left': False, + 'axes.spines.right': False, + 'axes.spines.top': False, + 'axes.spines.bottom': False} + with matplotlib.rc_context(rc_dict): + plt.subplots() # create a figure and axes with the spine properties + + +@image_comparison(['rc_grid.png'], savefig_kwarg={'dpi': 40}) +def test_rc_grid(): + fig = plt.figure() + rc_dict0 = { + 'axes.grid': True, + 'axes.grid.axis': 'both' + } + rc_dict1 = { + 'axes.grid': True, + 'axes.grid.axis': 'x' + } + rc_dict2 = { + 'axes.grid': True, + 'axes.grid.axis': 'y' + } + dict_list = [rc_dict0, rc_dict1, rc_dict2] + + for i, rc_dict in enumerate(dict_list, 1): + with matplotlib.rc_context(rc_dict): + fig.add_subplot(3, 1, i) + + +def test_rc_tick(): + d = {'xtick.bottom': False, 'xtick.top': True, + 'ytick.left': True, 'ytick.right': False} + with plt.rc_context(rc=d): + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + xax = ax1.xaxis + yax = ax1.yaxis + # tick1On bottom/left + assert not xax._major_tick_kw['tick1On'] + assert xax._major_tick_kw['tick2On'] + assert not xax._minor_tick_kw['tick1On'] + assert xax._minor_tick_kw['tick2On'] + + assert yax._major_tick_kw['tick1On'] + assert not yax._major_tick_kw['tick2On'] + assert yax._minor_tick_kw['tick1On'] + assert not yax._minor_tick_kw['tick2On'] + + +def test_rc_major_minor_tick(): + d = {'xtick.top': True, 'ytick.right': True, # Enable all ticks + 'xtick.bottom': True, 'ytick.left': True, + # Selectively disable + 'xtick.minor.bottom': False, 'xtick.major.bottom': False, + 'ytick.major.left': False, 'ytick.minor.left': False} + with plt.rc_context(rc=d): + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + xax = ax1.xaxis + yax = ax1.yaxis + # tick1On bottom/left + assert not xax._major_tick_kw['tick1On'] + assert xax._major_tick_kw['tick2On'] + assert not xax._minor_tick_kw['tick1On'] + assert xax._minor_tick_kw['tick2On'] + + assert not yax._major_tick_kw['tick1On'] + assert yax._major_tick_kw['tick2On'] + assert not yax._minor_tick_kw['tick1On'] + assert yax._minor_tick_kw['tick2On'] + + +def test_square_plot(): + x = np.arange(4) + y = np.array([1., 3., 5., 7.]) + fig, ax = plt.subplots() + ax.plot(x, y, 'mo') + ax.axis('square') + xlim, ylim = ax.get_xlim(), ax.get_ylim() + assert np.diff(xlim) == np.diff(ylim) + assert ax.get_aspect() == 1 + assert_array_almost_equal( + ax.get_position(original=True).extents, (0.125, 0.1, 0.9, 0.9)) + assert_array_almost_equal( + ax.get_position(original=False).extents, (0.2125, 0.1, 0.8125, 0.9)) + + +def test_bad_plot_args(): + with pytest.raises(ValueError): + plt.plot(None) + with pytest.raises(ValueError): + plt.plot(None, None) + with pytest.raises(ValueError): + plt.plot(np.zeros((2, 2)), np.zeros((2, 3))) + with pytest.raises(ValueError): + plt.plot((np.arange(5).reshape((1, -1)), np.arange(5).reshape(-1, 1))) + + +@pytest.mark.parametrize( + "xy, cls", [ + ((), mpl.image.AxesImage), # (0, N) + (((3, 7), (2, 6)), mpl.image.AxesImage), # (xmin, xmax) + ((range(5), range(4)), mpl.image.AxesImage), # regular grid + (([1, 2, 4, 8, 16], [0, 1, 2, 3]), # irregular grid + mpl.image.PcolorImage), + ((np.random.random((4, 5)), np.random.random((4, 5))), # 2D coords + mpl.collections.QuadMesh), + ] +) +@pytest.mark.parametrize( + "data", [np.arange(12).reshape((3, 4)), np.random.rand(3, 4, 3)] +) +def test_pcolorfast(xy, data, cls): + fig, ax = plt.subplots() + assert type(ax.pcolorfast(*xy, data)) == cls + + +def test_shared_scale(): + fig, axs = plt.subplots(2, 2, sharex=True, sharey=True) + + axs[0, 0].set_xscale("log") + axs[0, 0].set_yscale("log") + + for ax in axs.flat: + assert ax.get_yscale() == 'log' + assert ax.get_xscale() == 'log' + + axs[1, 1].set_xscale("linear") + axs[1, 1].set_yscale("linear") + + for ax in axs.flat: + assert ax.get_yscale() == 'linear' + assert ax.get_xscale() == 'linear' + + +def test_shared_bool(): + with pytest.raises(TypeError): + plt.subplot(sharex=True) + with pytest.raises(TypeError): + plt.subplot(sharey=True) + + +def test_violin_point_mass(): + """Violin plot should handle point mass pdf gracefully.""" + plt.violinplot(np.array([0, 0])) + + +def generate_errorbar_inputs(): + base_xy = cycler('x', [np.arange(5)]) + cycler('y', [np.ones(5)]) + err_cycler = cycler('err', [1, + [1, 1, 1, 1, 1], + [[1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]], + np.ones(5), + np.ones((2, 5)), + None + ]) + xerr_cy = cycler('xerr', err_cycler) + yerr_cy = cycler('yerr', err_cycler) + + empty = ((cycler('x', [[]]) + cycler('y', [[]])) * + cycler('xerr', [[], None]) * cycler('yerr', [[], None])) + xerr_only = base_xy * xerr_cy + yerr_only = base_xy * yerr_cy + both_err = base_xy * yerr_cy * xerr_cy + + return [*xerr_only, *yerr_only, *both_err, *empty] + + +@pytest.mark.parametrize('kwargs', generate_errorbar_inputs()) +def test_errorbar_inputs_shotgun(kwargs): + ax = plt.gca() + eb = ax.errorbar(**kwargs) + eb.remove() + + +@image_comparison(["dash_offset"], remove_text=True) +def test_dash_offset(): + fig, ax = plt.subplots() + x = np.linspace(0, 10) + y = np.ones_like(x) + for j in range(0, 100, 2): + ax.plot(x, j*y, ls=(j, (10, 10)), lw=5, color='k') + + +def test_title_pad(): + # check that title padding puts the title in the right + # place... + fig, ax = plt.subplots() + ax.set_title('aardvark', pad=30.) + m = ax.titleOffsetTrans.get_matrix() + assert m[1, -1] == (30. / 72. * fig.dpi) + ax.set_title('aardvark', pad=0.) + m = ax.titleOffsetTrans.get_matrix() + assert m[1, -1] == 0. + # check that it is reverted... + ax.set_title('aardvark', pad=None) + m = ax.titleOffsetTrans.get_matrix() + assert m[1, -1] == (matplotlib.rcParams['axes.titlepad'] / 72. * fig.dpi) + + +def test_title_location_roundtrip(): + fig, ax = plt.subplots() + # set default title location + plt.rcParams['axes.titlelocation'] = 'center' + ax.set_title('aardvark') + ax.set_title('left', loc='left') + ax.set_title('right', loc='right') + + assert 'left' == ax.get_title(loc='left') + assert 'right' == ax.get_title(loc='right') + assert 'aardvark' == ax.get_title(loc='center') + + with pytest.raises(ValueError): + ax.get_title(loc='foo') + with pytest.raises(ValueError): + ax.set_title('fail', loc='foo') + + +@pytest.mark.parametrize('sharex', [True, False]) +def test_title_location_shared(sharex): + fig, axs = plt.subplots(2, 1, sharex=sharex) + axs[0].set_title('A', pad=-40) + axs[1].set_title('B', pad=-40) + fig.draw_without_rendering() + x, y1 = axs[0].title.get_position() + x, y2 = axs[1].title.get_position() + assert y1 == y2 == 1.0 + + +@image_comparison(["loglog.png"], remove_text=True, tol=0.02) +def test_loglog(): + fig, ax = plt.subplots() + x = np.arange(1, 11) + ax.loglog(x, x**3, lw=5) + ax.tick_params(length=25, width=2) + ax.tick_params(length=15, width=2, which='minor') + + +@image_comparison(["test_loglog_nonpos.png"], remove_text=True, style='mpl20') +def test_loglog_nonpos(): + fig, axs = plt.subplots(3, 3) + x = np.arange(1, 11) + y = x**3 + y[7] = -3. + x[4] = -10 + for (mcy, mcx), ax in zip(product(['mask', 'clip', ''], repeat=2), + axs.flat): + if mcx == mcy: + if mcx: + ax.loglog(x, y**3, lw=2, nonpositive=mcx) + else: + ax.loglog(x, y**3, lw=2) + else: + ax.loglog(x, y**3, lw=2) + if mcx: + ax.set_xscale("log", nonpositive=mcx) + if mcy: + ax.set_yscale("log", nonpositive=mcy) + + +@mpl.style.context('default') +def test_axes_margins(): + fig, ax = plt.subplots() + ax.plot([0, 1, 2, 3]) + assert ax.get_ybound()[0] != 0 + + fig, ax = plt.subplots() + ax.bar([0, 1, 2, 3], [1, 1, 1, 1]) + assert ax.get_ybound()[0] == 0 + + fig, ax = plt.subplots() + ax.barh([0, 1, 2, 3], [1, 1, 1, 1]) + assert ax.get_xbound()[0] == 0 + + fig, ax = plt.subplots() + ax.pcolor(np.zeros((10, 10))) + assert ax.get_xbound() == (0, 10) + assert ax.get_ybound() == (0, 10) + + fig, ax = plt.subplots() + ax.pcolorfast(np.zeros((10, 10))) + assert ax.get_xbound() == (0, 10) + assert ax.get_ybound() == (0, 10) + + fig, ax = plt.subplots() + ax.hist(np.arange(10)) + assert ax.get_ybound()[0] == 0 + + fig, ax = plt.subplots() + ax.imshow(np.zeros((10, 10))) + assert ax.get_xbound() == (-0.5, 9.5) + assert ax.get_ybound() == (-0.5, 9.5) + + +@pytest.fixture(params=['x', 'y']) +def shared_axis_remover(request): + def _helper_x(ax): + ax2 = ax.twinx() + ax2.remove() + ax.set_xlim(0, 15) + r = ax.xaxis.get_major_locator()() + assert r[-1] > 14 + + def _helper_y(ax): + ax2 = ax.twiny() + ax2.remove() + ax.set_ylim(0, 15) + r = ax.yaxis.get_major_locator()() + assert r[-1] > 14 + + return {"x": _helper_x, "y": _helper_y}[request.param] + + +@pytest.fixture(params=['gca', 'subplots', 'subplots_shared', 'add_axes']) +def shared_axes_generator(request): + # test all of the ways to get fig/ax sets + if request.param == 'gca': + fig = plt.figure() + ax = fig.gca() + elif request.param == 'subplots': + fig, ax = plt.subplots() + elif request.param == 'subplots_shared': + fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all') + ax = ax_lst[0][0] + elif request.param == 'add_axes': + fig = plt.figure() + ax = fig.add_axes([.1, .1, .8, .8]) + return fig, ax + + +def test_remove_shared_axes(shared_axes_generator, shared_axis_remover): + # test all of the ways to get fig/ax sets + fig, ax = shared_axes_generator + shared_axis_remover(ax) + + +def test_remove_shared_axes_relim(): + fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all') + ax = ax_lst[0][0] + orig_xlim = ax_lst[0][1].get_xlim() + ax.remove() + ax.set_xlim(0, 5) + assert_array_equal(ax_lst[0][1].get_xlim(), orig_xlim) + + +def test_shared_axes_autoscale(): + l = np.arange(-80, 90, 40) + t = np.random.random_sample((l.size, l.size)) + + fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, sharey=True) + + ax1.set_xlim(-1000, 1000) + ax1.set_ylim(-1000, 1000) + ax1.contour(l, l, t) + + ax2.contour(l, l, t) + assert not ax1.get_autoscalex_on() and not ax2.get_autoscalex_on() + assert not ax1.get_autoscaley_on() and not ax2.get_autoscaley_on() + assert ax1.get_xlim() == ax2.get_xlim() == (-1000, 1000) + assert ax1.get_ylim() == ax2.get_ylim() == (-1000, 1000) + + +def test_adjust_numtick_aspect(): + fig, ax = plt.subplots() + ax.yaxis.get_major_locator().set_params(nbins='auto') + ax.set_xlim(0, 1000) + ax.set_aspect('equal') + fig.canvas.draw() + assert len(ax.yaxis.get_major_locator()()) == 2 + ax.set_ylim(0, 1000) + fig.canvas.draw() + assert len(ax.yaxis.get_major_locator()()) > 2 + + +@mpl.style.context("default") +def test_auto_numticks(): + axs = plt.figure().subplots(4, 4) + for ax in axs.flat: # Tiny, empty subplots have only 3 ticks. + assert [*ax.get_xticks()] == [*ax.get_yticks()] == [0, 0.5, 1] + + +@mpl.style.context("default") +def test_auto_numticks_log(): + # Verify that there are not too many ticks with a large log range. + fig, ax = plt.subplots() + mpl.rcParams['axes.autolimit_mode'] = 'round_numbers' + ax.loglog([1e-20, 1e5], [1e-16, 10]) + assert (np.log10(ax.get_xticks()) == np.arange(-26, 18, 4)).all() + assert (np.log10(ax.get_yticks()) == np.arange(-20, 10, 3)).all() + + +def test_broken_barh_empty(): + fig, ax = plt.subplots() + ax.broken_barh([], (.1, .5)) + + +def test_broken_barh_timedelta(): + """Check that timedelta works as x, dx pair for this method.""" + fig, ax = plt.subplots() + d0 = datetime.datetime(2018, 11, 9, 0, 0, 0) + pp = ax.broken_barh([(d0, datetime.timedelta(hours=1))], [1, 2]) + assert pp.get_paths()[0].vertices[0, 0] == mdates.date2num(d0) + assert pp.get_paths()[0].vertices[2, 0] == mdates.date2num(d0) + 1 / 24 + + +def test_pandas_pcolormesh(pd): + time = pd.date_range('2000-01-01', periods=10) + depth = np.arange(20) + data = np.random.rand(19, 9) + + fig, ax = plt.subplots() + ax.pcolormesh(time, depth, data) + + +def test_pandas_indexing_dates(pd): + dates = np.arange('2005-02', '2005-03', dtype='datetime64[D]') + values = np.sin(range(len(dates))) + df = pd.DataFrame({'dates': dates, 'values': values}) + + ax = plt.gca() + + without_zero_index = df[np.array(df.index) % 2 == 1].copy() + ax.plot('dates', 'values', data=without_zero_index) + + +def test_pandas_errorbar_indexing(pd): + df = pd.DataFrame(np.random.uniform(size=(5, 4)), + columns=['x', 'y', 'xe', 'ye'], + index=[1, 2, 3, 4, 5]) + fig, ax = plt.subplots() + ax.errorbar('x', 'y', xerr='xe', yerr='ye', data=df) + + +def test_pandas_index_shape(pd): + df = pd.DataFrame({"XX": [4, 5, 6], "YY": [7, 1, 2]}) + fig, ax = plt.subplots() + ax.plot(df.index, df['YY']) + + +def test_pandas_indexing_hist(pd): + ser_1 = pd.Series(data=[1, 2, 2, 3, 3, 4, 4, 4, 4, 5]) + ser_2 = ser_1.iloc[1:] + fig, ax = plt.subplots() + ax.hist(ser_2) + + +def test_pandas_bar_align_center(pd): + # Tests fix for issue 8767 + df = pd.DataFrame({'a': range(2), 'b': range(2)}) + + fig, ax = plt.subplots(1) + + ax.bar(df.loc[df['a'] == 1, 'b'], + df.loc[df['a'] == 1, 'b'], + align='center') + + fig.canvas.draw() + + +def test_axis_get_tick_params(): + axis = plt.subplot().yaxis + initial_major_style_translated = {**axis.get_tick_params(which='major')} + initial_minor_style_translated = {**axis.get_tick_params(which='minor')} + + translated_major_kw = axis._translate_tick_params( + axis._major_tick_kw, reverse=True + ) + translated_minor_kw = axis._translate_tick_params( + axis._minor_tick_kw, reverse=True + ) + + assert translated_major_kw == initial_major_style_translated + assert translated_minor_kw == initial_minor_style_translated + axis.set_tick_params(labelsize=30, labelcolor='red', + direction='out', which='both') + + new_major_style_translated = {**axis.get_tick_params(which='major')} + new_minor_style_translated = {**axis.get_tick_params(which='minor')} + new_major_style = axis._translate_tick_params(new_major_style_translated) + new_minor_style = axis._translate_tick_params(new_minor_style_translated) + assert initial_major_style_translated != new_major_style_translated + assert axis._major_tick_kw == new_major_style + assert initial_minor_style_translated != new_minor_style_translated + assert axis._minor_tick_kw == new_minor_style + + +def test_axis_set_tick_params_labelsize_labelcolor(): + # Tests fix for issue 4346 + axis_1 = plt.subplot() + axis_1.yaxis.set_tick_params(labelsize=30, labelcolor='red', + direction='out') + + # Expected values after setting the ticks + assert axis_1.yaxis.majorTicks[0]._size == 4.0 + assert axis_1.yaxis.majorTicks[0].tick1line.get_color() == 'k' + assert axis_1.yaxis.majorTicks[0].label1.get_size() == 30.0 + assert axis_1.yaxis.majorTicks[0].label1.get_color() == 'red' + + +def test_axes_tick_params_gridlines(): + # Now treating grid params like other Tick params + ax = plt.subplot() + ax.tick_params(grid_color='b', grid_linewidth=5, grid_alpha=0.5, + grid_linestyle='dashdot') + for axis in ax.xaxis, ax.yaxis: + assert axis.majorTicks[0].gridline.get_color() == 'b' + assert axis.majorTicks[0].gridline.get_linewidth() == 5 + assert axis.majorTicks[0].gridline.get_alpha() == 0.5 + assert axis.majorTicks[0].gridline.get_linestyle() == '-.' + + +def test_axes_tick_params_ylabelside(): + # Tests fix for issue 10267 + ax = plt.subplot() + ax.tick_params(labelleft=False, labelright=True, + which='major') + ax.tick_params(labelleft=False, labelright=True, + which='minor') + # expects left false, right true + assert ax.yaxis.majorTicks[0].label1.get_visible() is False + assert ax.yaxis.majorTicks[0].label2.get_visible() is True + assert ax.yaxis.minorTicks[0].label1.get_visible() is False + assert ax.yaxis.minorTicks[0].label2.get_visible() is True + + +def test_axes_tick_params_xlabelside(): + # Tests fix for issue 10267 + ax = plt.subplot() + ax.tick_params(labeltop=True, labelbottom=False, + which='major') + ax.tick_params(labeltop=True, labelbottom=False, + which='minor') + # expects top True, bottom False + # label1.get_visible() mapped to labelbottom + # label2.get_visible() mapped to labeltop + assert ax.xaxis.majorTicks[0].label1.get_visible() is False + assert ax.xaxis.majorTicks[0].label2.get_visible() is True + assert ax.xaxis.minorTicks[0].label1.get_visible() is False + assert ax.xaxis.minorTicks[0].label2.get_visible() is True + + +def test_none_kwargs(): + ax = plt.figure().subplots() + ln, = ax.plot(range(32), linestyle=None) + assert ln.get_linestyle() == '-' + + +def test_bar_uint8(): + xs = [0, 1, 2, 3] + b = plt.bar(np.array(xs, dtype=np.uint8), [2, 3, 4, 5], align="edge") + for (patch, x) in zip(b.patches, xs): + assert patch.xy[0] == x + + +@image_comparison(['date_timezone_x.png'], tol=1.0) +def test_date_timezone_x(): + # Tests issue 5575 + time_index = [datetime.datetime(2016, 2, 22, hour=x, + tzinfo=dateutil.tz.gettz('Canada/Eastern')) + for x in range(3)] + + # Same Timezone + plt.figure(figsize=(20, 12)) + plt.subplot(2, 1, 1) + plt.plot_date(time_index, [3] * 3, tz='Canada/Eastern') + + # Different Timezone + plt.subplot(2, 1, 2) + plt.plot_date(time_index, [3] * 3, tz='UTC') + + +@image_comparison(['date_timezone_y.png']) +def test_date_timezone_y(): + # Tests issue 5575 + time_index = [datetime.datetime(2016, 2, 22, hour=x, + tzinfo=dateutil.tz.gettz('Canada/Eastern')) + for x in range(3)] + + # Same Timezone + plt.figure(figsize=(20, 12)) + plt.subplot(2, 1, 1) + plt.plot_date([3] * 3, + time_index, tz='Canada/Eastern', xdate=False, ydate=True) + + # Different Timezone + plt.subplot(2, 1, 2) + plt.plot_date([3] * 3, time_index, tz='UTC', xdate=False, ydate=True) + + +@image_comparison(['date_timezone_x_and_y.png'], tol=1.0) +def test_date_timezone_x_and_y(): + # Tests issue 5575 + UTC = datetime.timezone.utc + time_index = [datetime.datetime(2016, 2, 22, hour=x, tzinfo=UTC) + for x in range(3)] + + # Same Timezone + plt.figure(figsize=(20, 12)) + plt.subplot(2, 1, 1) + plt.plot_date(time_index, time_index, tz='UTC', ydate=True) + + # Different Timezone + plt.subplot(2, 1, 2) + plt.plot_date(time_index, time_index, tz='US/Eastern', ydate=True) + + +@image_comparison(['axisbelow.png'], remove_text=True) +def test_axisbelow(): + # Test 'line' setting added in 6287. + # Show only grids, not frame or ticks, to make this test + # independent of future change to drawing order of those elements. + axs = plt.figure().subplots(ncols=3, sharex=True, sharey=True) + settings = (False, 'line', True) + + for ax, setting in zip(axs, settings): + ax.plot((0, 10), (0, 10), lw=10, color='m') + circ = mpatches.Circle((3, 3), color='r') + ax.add_patch(circ) + ax.grid(color='c', linestyle='-', linewidth=3) + ax.tick_params(top=False, bottom=False, + left=False, right=False) + ax.spines[:].set_visible(False) + ax.set_axisbelow(setting) + assert ax.get_axisbelow() == setting + + +def test_titletwiny(): + plt.style.use('mpl20') + fig, ax = plt.subplots(dpi=72) + ax2 = ax.twiny() + xlabel2 = ax2.set_xlabel('Xlabel2') + title = ax.set_title('Title') + fig.canvas.draw() + renderer = fig.canvas.get_renderer() + # ------- Test that title is put above Xlabel2 (Xlabel2 at top) ---------- + bbox_y0_title = title.get_window_extent(renderer).y0 # bottom of title + bbox_y1_xlabel2 = xlabel2.get_window_extent(renderer).y1 # top of xlabel2 + y_diff = bbox_y0_title - bbox_y1_xlabel2 + assert np.isclose(y_diff, 3) + + +def test_titlesetpos(): + # Test that title stays put if we set it manually + fig, ax = plt.subplots() + fig.subplots_adjust(top=0.8) + ax2 = ax.twiny() + ax.set_xlabel('Xlabel') + ax2.set_xlabel('Xlabel2') + ax.set_title('Title') + pos = (0.5, 1.11) + ax.title.set_position(pos) + renderer = fig.canvas.get_renderer() + ax._update_title_position(renderer) + assert ax.title.get_position() == pos + + +def test_title_xticks_top(): + # Test that title moves if xticks on top of axes. + mpl.rcParams['axes.titley'] = None + fig, ax = plt.subplots() + ax.xaxis.set_ticks_position('top') + ax.set_title('xlabel top') + fig.canvas.draw() + assert ax.title.get_position()[1] > 1.04 + + +def test_title_xticks_top_both(): + # Test that title moves if xticks on top of axes. + mpl.rcParams['axes.titley'] = None + fig, ax = plt.subplots() + ax.tick_params(axis="x", + bottom=True, top=True, labelbottom=True, labeltop=True) + ax.set_title('xlabel top') + fig.canvas.draw() + assert ax.title.get_position()[1] > 1.04 + + +@pytest.mark.parametrize( + 'left, center', [ + ('left', ''), + ('', 'center'), + ('left', 'center') + ], ids=[ + 'left title moved', + 'center title kept', + 'both titles aligned' + ] +) +def test_title_above_offset(left, center): + # Test that title moves if overlaps with yaxis offset text. + mpl.rcParams['axes.titley'] = None + fig, ax = plt.subplots() + ax.set_ylim(1e11) + ax.set_title(left, loc='left') + ax.set_title(center) + fig.draw_without_rendering() + if left and not center: + assert ax._left_title.get_position()[1] > 1.0 + elif not left and center: + assert ax.title.get_position()[1] == 1.0 + else: + yleft = ax._left_title.get_position()[1] + ycenter = ax.title.get_position()[1] + assert yleft > 1.0 + assert ycenter == yleft + + +def test_title_no_move_off_page(): + # If an Axes is off the figure (ie. if it is cropped during a save) + # make sure that the automatic title repositioning does not get done. + mpl.rcParams['axes.titley'] = None + fig = plt.figure() + ax = fig.add_axes([0.1, -0.5, 0.8, 0.2]) + ax.tick_params(axis="x", + bottom=True, top=True, labelbottom=True, labeltop=True) + tt = ax.set_title('Boo') + fig.canvas.draw() + assert tt.get_position()[1] == 1.0 + + +def test_offset_label_color(): + # Tests issue 6440 + fig, ax = plt.subplots() + ax.plot([1.01e9, 1.02e9, 1.03e9]) + ax.yaxis.set_tick_params(labelcolor='red') + assert ax.yaxis.get_offset_text().get_color() == 'red' + + +def test_offset_text_visible(): + fig, ax = plt.subplots() + ax.plot([1.01e9, 1.02e9, 1.03e9]) + ax.yaxis.set_tick_params(label1On=False, label2On=True) + assert ax.yaxis.get_offset_text().get_visible() + ax.yaxis.set_tick_params(label2On=False) + assert not ax.yaxis.get_offset_text().get_visible() + + +def test_large_offset(): + fig, ax = plt.subplots() + ax.plot((1 + np.array([0, 1.e-12])) * 1.e27) + fig.canvas.draw() + + +def test_barb_units(): + fig, ax = plt.subplots() + dates = [datetime.datetime(2017, 7, 15, 18, i) for i in range(0, 60, 10)] + y = np.linspace(0, 5, len(dates)) + u = v = np.linspace(0, 50, len(dates)) + ax.barbs(dates, y, u, v) + + +def test_quiver_units(): + fig, ax = plt.subplots() + dates = [datetime.datetime(2017, 7, 15, 18, i) for i in range(0, 60, 10)] + y = np.linspace(0, 5, len(dates)) + u = v = np.linspace(0, 50, len(dates)) + ax.quiver(dates, y, u, v) + + +def test_bar_color_cycle(): + to_rgb = mcolors.to_rgb + fig, ax = plt.subplots() + for j in range(5): + ln, = ax.plot(range(3)) + brs = ax.bar(range(3), range(3)) + for br in brs: + assert to_rgb(ln.get_color()) == to_rgb(br.get_facecolor()) + + +def test_tick_param_label_rotation(): + fix, (ax, ax2) = plt.subplots(1, 2) + ax.plot([0, 1], [0, 1]) + ax2.plot([0, 1], [0, 1]) + ax.xaxis.set_tick_params(which='both', rotation=75) + ax.yaxis.set_tick_params(which='both', rotation=90) + for text in ax.get_xticklabels(which='both'): + assert text.get_rotation() == 75 + for text in ax.get_yticklabels(which='both'): + assert text.get_rotation() == 90 + + ax2.tick_params(axis='x', labelrotation=53) + ax2.tick_params(axis='y', rotation=35) + for text in ax2.get_xticklabels(which='major'): + assert text.get_rotation() == 53 + for text in ax2.get_yticklabels(which='major'): + assert text.get_rotation() == 35 + + +@mpl.style.context('default') +def test_fillbetween_cycle(): + fig, ax = plt.subplots() + + for j in range(3): + cc = ax.fill_between(range(3), range(3)) + target = mcolors.to_rgba(f'C{j}') + assert tuple(cc.get_facecolors().squeeze()) == tuple(target) + + for j in range(3, 6): + cc = ax.fill_betweenx(range(3), range(3)) + target = mcolors.to_rgba(f'C{j}') + assert tuple(cc.get_facecolors().squeeze()) == tuple(target) + + target = mcolors.to_rgba('k') + + for al in ['facecolor', 'facecolors', 'color']: + cc = ax.fill_between(range(3), range(3), **{al: 'k'}) + assert tuple(cc.get_facecolors().squeeze()) == tuple(target) + + edge_target = mcolors.to_rgba('k') + for j, el in enumerate(['edgecolor', 'edgecolors'], start=6): + cc = ax.fill_between(range(3), range(3), **{el: 'k'}) + face_target = mcolors.to_rgba(f'C{j}') + assert tuple(cc.get_facecolors().squeeze()) == tuple(face_target) + assert tuple(cc.get_edgecolors().squeeze()) == tuple(edge_target) + + +def test_log_margins(): + plt.rcParams['axes.autolimit_mode'] = 'data' + fig, ax = plt.subplots() + margin = 0.05 + ax.set_xmargin(margin) + ax.semilogx([10, 100], [10, 100]) + xlim0, xlim1 = ax.get_xlim() + transform = ax.xaxis.get_transform() + xlim0t, xlim1t = transform.transform([xlim0, xlim1]) + x0t, x1t = transform.transform([10, 100]) + delta = (x1t - x0t) * margin + assert_allclose([xlim0t + delta, xlim1t - delta], [x0t, x1t]) + + +def test_color_length_mismatch(): + N = 5 + x, y = np.arange(N), np.arange(N) + colors = np.arange(N+1) + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.scatter(x, y, c=colors) + with pytest.warns(match="argument looks like a single numeric RGB"): + ax.scatter(x, y, c=(0.5, 0.5, 0.5)) + ax.scatter(x, y, c=[(0.5, 0.5, 0.5)] * N) + + +def test_eventplot_legend(): + plt.eventplot([1.0], label='Label') + plt.legend() + + +@pytest.mark.parametrize('err, args, kwargs, match', ( + (ValueError, [[1]], {'lineoffsets': []}, 'lineoffsets cannot be empty'), + (ValueError, [[1]], {'linelengths': []}, 'linelengths cannot be empty'), + (ValueError, [[1]], {'linewidths': []}, 'linewidths cannot be empty'), + (ValueError, [[1]], {'linestyles': []}, 'linestyles cannot be empty'), + (ValueError, [[1]], {'alpha': []}, 'alpha cannot be empty'), + (ValueError, [1], {}, 'positions must be one-dimensional'), + (ValueError, [[1]], {'lineoffsets': [1, 2]}, + 'lineoffsets and positions are unequal sized sequences'), + (ValueError, [[1]], {'linelengths': [1, 2]}, + 'linelengths and positions are unequal sized sequences'), + (ValueError, [[1]], {'linewidths': [1, 2]}, + 'linewidths and positions are unequal sized sequences'), + (ValueError, [[1]], {'linestyles': [1, 2]}, + 'linestyles and positions are unequal sized sequences'), + (ValueError, [[1]], {'alpha': [1, 2]}, + 'alpha and positions are unequal sized sequences'), + (ValueError, [[1]], {'colors': [1, 2]}, + 'colors and positions are unequal sized sequences'), +)) +def test_eventplot_errors(err, args, kwargs, match): + with pytest.raises(err, match=match): + plt.eventplot(*args, **kwargs) + + +def test_bar_broadcast_args(): + fig, ax = plt.subplots() + # Check that a bar chart with a single height for all bars works. + ax.bar(range(4), 1) + # Check that a horizontal chart with one width works. + ax.barh(0, 1, left=range(4), height=1) + # Check that edgecolor gets broadcast. + rect1, rect2 = ax.bar([0, 1], [0, 1], edgecolor=(.1, .2, .3, .4)) + assert rect1.get_edgecolor() == rect2.get_edgecolor() == (.1, .2, .3, .4) + + +def test_invalid_axis_limits(): + plt.plot([0, 1], [0, 1]) + with pytest.raises(ValueError): + plt.xlim(np.nan) + with pytest.raises(ValueError): + plt.xlim(np.inf) + with pytest.raises(ValueError): + plt.ylim(np.nan) + with pytest.raises(ValueError): + plt.ylim(np.inf) + + +# Test all 4 combinations of logs/symlogs for minorticks_on() +@pytest.mark.parametrize('xscale', ['symlog', 'log']) +@pytest.mark.parametrize('yscale', ['symlog', 'log']) +def test_minorticks_on(xscale, yscale): + ax = plt.subplot() + ax.plot([1, 2, 3, 4]) + ax.set_xscale(xscale) + ax.set_yscale(yscale) + ax.minorticks_on() + + +def test_twinx_knows_limits(): + fig, ax = plt.subplots() + + ax.axvspan(1, 2) + xtwin = ax.twinx() + xtwin.plot([0, 0.5], [1, 2]) + # control axis + fig2, ax2 = plt.subplots() + + ax2.axvspan(1, 2) + ax2.plot([0, 0.5], [1, 2]) + + assert_array_equal(xtwin.viewLim.intervalx, ax2.viewLim.intervalx) + + +def test_zero_linewidth(): + # Check that setting a zero linewidth doesn't error + plt.plot([0, 1], [0, 1], ls='--', lw=0) + + +def test_empty_errorbar_legend(): + fig, ax = plt.subplots() + ax.errorbar([], [], xerr=[], label='empty y') + ax.errorbar([], [], yerr=[], label='empty x') + ax.legend() + + +@check_figures_equal(extensions=["png"]) +def test_plot_decimal(fig_test, fig_ref): + x0 = np.arange(-10, 10, 0.3) + y0 = [5.2 * x ** 3 - 2.1 * x ** 2 + 7.34 * x + 4.5 for x in x0] + x = [Decimal(i) for i in x0] + y = [Decimal(i) for i in y0] + # Test image - line plot with Decimal input + fig_test.subplots().plot(x, y) + # Reference image + fig_ref.subplots().plot(x0, y0) + + +# pdf and svg tests fail using travis' old versions of gs and inkscape. +@check_figures_equal(extensions=["png"]) +def test_markerfacecolor_none_alpha(fig_test, fig_ref): + fig_test.subplots().plot(0, "o", mfc="none", alpha=.5) + fig_ref.subplots().plot(0, "o", mfc="w", alpha=.5) + + +def test_tick_padding_tightbbox(): + """Test that tick padding gets turned off if axis is off""" + plt.rcParams["xtick.direction"] = "out" + plt.rcParams["ytick.direction"] = "out" + fig, ax = plt.subplots() + bb = ax.get_tightbbox(fig.canvas.get_renderer()) + ax.axis('off') + bb2 = ax.get_tightbbox(fig.canvas.get_renderer()) + assert bb.x0 < bb2.x0 + assert bb.y0 < bb2.y0 + + +def test_inset(): + """ + Ensure that inset_ax argument is indeed optional + """ + dx, dy = 0.05, 0.05 + # generate 2 2d grids for the x & y bounds + y, x = np.mgrid[slice(1, 5 + dy, dy), + slice(1, 5 + dx, dx)] + z = np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x) + + fig, ax = plt.subplots() + ax.pcolormesh(x, y, z[:-1, :-1]) + ax.set_aspect(1.) + ax.apply_aspect() + # we need to apply_aspect to make the drawing below work. + + xlim = [1.5, 2.15] + ylim = [2, 2.5] + + rect = [xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0]] + + rec, connectors = ax.indicate_inset(bounds=rect) + assert connectors is None + fig.canvas.draw() + xx = np.array([[1.5, 2.], + [2.15, 2.5]]) + assert np.all(rec.get_bbox().get_points() == xx) + + +def test_zoom_inset(): + dx, dy = 0.05, 0.05 + # generate 2 2d grids for the x & y bounds + y, x = np.mgrid[slice(1, 5 + dy, dy), + slice(1, 5 + dx, dx)] + z = np.sin(x)**10 + np.cos(10 + y*x) * np.cos(x) + + fig, ax = plt.subplots() + ax.pcolormesh(x, y, z[:-1, :-1]) + ax.set_aspect(1.) + ax.apply_aspect() + # we need to apply_aspect to make the drawing below work. + + # Make the inset_axes... Position axes coordinates... + axin1 = ax.inset_axes([0.7, 0.7, 0.35, 0.35]) + # redraw the data in the inset axes... + axin1.pcolormesh(x, y, z[:-1, :-1]) + axin1.set_xlim([1.5, 2.15]) + axin1.set_ylim([2, 2.5]) + axin1.set_aspect(ax.get_aspect()) + + rec, connectors = ax.indicate_inset_zoom(axin1) + assert len(connectors) == 4 + fig.canvas.draw() + xx = np.array([[1.5, 2.], + [2.15, 2.5]]) + assert np.all(rec.get_bbox().get_points() == xx) + xx = np.array([[0.6325, 0.692308], + [0.8425, 0.907692]]) + np.testing.assert_allclose( + axin1.get_position().get_points(), xx, rtol=1e-4) + + +@image_comparison(['inset_polar.png'], remove_text=True, style='mpl20') +def test_inset_polar(): + _, ax = plt.subplots() + axins = ax.inset_axes([0.5, 0.1, 0.45, 0.45], polar=True) + assert isinstance(axins, PolarAxes) + + r = np.arange(0, 2, 0.01) + theta = 2 * np.pi * r + + ax.plot(theta, r) + axins.plot(theta, r) + + +def test_inset_projection(): + _, ax = plt.subplots() + axins = ax.inset_axes([0.2, 0.2, 0.3, 0.3], projection="hammer") + assert isinstance(axins, HammerAxes) + + +def test_inset_subclass(): + _, ax = plt.subplots() + axins = ax.inset_axes([0.2, 0.2, 0.3, 0.3], axes_class=AA.Axes) + assert isinstance(axins, AA.Axes) + + +@pytest.mark.parametrize('x_inverted', [False, True]) +@pytest.mark.parametrize('y_inverted', [False, True]) +def test_indicate_inset_inverted(x_inverted, y_inverted): + """ + Test that the inset lines are correctly located with inverted data axes. + """ + fig, (ax1, ax2) = plt.subplots(1, 2) + + x = np.arange(10) + ax1.plot(x, x, 'o') + if x_inverted: + ax1.invert_xaxis() + if y_inverted: + ax1.invert_yaxis() + + rect, bounds = ax1.indicate_inset([2, 2, 5, 4], ax2) + lower_left, upper_left, lower_right, upper_right = bounds + + sign_x = -1 if x_inverted else 1 + sign_y = -1 if y_inverted else 1 + assert sign_x * (lower_right.xy2[0] - lower_left.xy2[0]) > 0 + assert sign_x * (upper_right.xy2[0] - upper_left.xy2[0]) > 0 + assert sign_y * (upper_left.xy2[1] - lower_left.xy2[1]) > 0 + assert sign_y * (upper_right.xy2[1] - lower_right.xy2[1]) > 0 + + +def test_set_position(): + fig, ax = plt.subplots() + ax.set_aspect(3.) + ax.set_position([0.1, 0.1, 0.4, 0.4], which='both') + assert np.allclose(ax.get_position().width, 0.1) + ax.set_aspect(2.) + ax.set_position([0.1, 0.1, 0.4, 0.4], which='original') + assert np.allclose(ax.get_position().width, 0.15) + ax.set_aspect(3.) + ax.set_position([0.1, 0.1, 0.4, 0.4], which='active') + assert np.allclose(ax.get_position().width, 0.1) + + +def test_spines_properbbox_after_zoom(): + fig, ax = plt.subplots() + bb = ax.spines.bottom.get_window_extent(fig.canvas.get_renderer()) + # this is what zoom calls: + ax._set_view_from_bbox((320, 320, 500, 500), 'in', + None, False, False) + bb2 = ax.spines.bottom.get_window_extent(fig.canvas.get_renderer()) + np.testing.assert_allclose(bb.get_points(), bb2.get_points(), rtol=1e-6) + + +def test_limits_after_scroll_zoom(): + fig, ax = plt.subplots() + # + xlim = (-0.5, 0.5) + ylim = (-1, 2) + ax.set_xlim(xlim) + ax.set_ylim(ymin=ylim[0], ymax=ylim[1]) + # This is what scroll zoom calls: + # Zoom with factor 1, small numerical change + ax._set_view_from_bbox((200, 200, 1.)) + np.testing.assert_allclose(xlim, ax.get_xlim(), atol=1e-16) + np.testing.assert_allclose(ylim, ax.get_ylim(), atol=1e-16) + + # Zoom in + ax._set_view_from_bbox((200, 200, 2.)) + # Hard-coded values + new_xlim = (-0.3790322580645161, 0.12096774193548387) + new_ylim = (-0.40625, 1.09375) + + res_xlim = ax.get_xlim() + res_ylim = ax.get_ylim() + np.testing.assert_allclose(res_xlim[1] - res_xlim[0], 0.5) + np.testing.assert_allclose(res_ylim[1] - res_ylim[0], 1.5) + np.testing.assert_allclose(new_xlim, res_xlim, atol=1e-16) + np.testing.assert_allclose(new_ylim, res_ylim) + + # Zoom out, should be same as before, except for numerical issues + ax._set_view_from_bbox((200, 200, 0.5)) + res_xlim = ax.get_xlim() + res_ylim = ax.get_ylim() + np.testing.assert_allclose(res_xlim[1] - res_xlim[0], 1) + np.testing.assert_allclose(res_ylim[1] - res_ylim[0], 3) + np.testing.assert_allclose(xlim, res_xlim, atol=1e-16) + np.testing.assert_allclose(ylim, res_ylim, atol=1e-16) + + +def test_gettightbbox_ignore_nan(): + fig, ax = plt.subplots() + remove_ticks_and_titles(fig) + ax.text(np.nan, 1, 'Boo') + renderer = fig.canvas.get_renderer() + np.testing.assert_allclose(ax.get_tightbbox(renderer).width, 496) + + +def test_scatter_series_non_zero_index(pd): + # create non-zero index + ids = range(10, 18) + x = pd.Series(np.random.uniform(size=8), index=ids) + y = pd.Series(np.random.uniform(size=8), index=ids) + c = pd.Series([1, 1, 1, 1, 1, 0, 0, 0], index=ids) + plt.scatter(x, y, c) + + +def test_scatter_empty_data(): + # making sure this does not raise an exception + plt.scatter([], []) + plt.scatter([], [], s=[], c=[]) + + +@image_comparison(['annotate_across_transforms.png'], + style='mpl20', remove_text=True) +def test_annotate_across_transforms(): + x = np.linspace(0, 10, 200) + y = np.exp(-x) * np.sin(x) + + fig, ax = plt.subplots(figsize=(3.39, 3)) + ax.plot(x, y) + axins = ax.inset_axes([0.4, 0.5, 0.3, 0.3]) + axins.set_aspect(0.2) + axins.xaxis.set_visible(False) + axins.yaxis.set_visible(False) + ax.annotate("", xy=(x[150], y[150]), xycoords=ax.transData, + xytext=(1, 0), textcoords=axins.transAxes, + arrowprops=dict(arrowstyle="->")) + + +@image_comparison(['secondary_xy.png'], style='mpl20') +def test_secondary_xy(): + fig, axs = plt.subplots(1, 2, figsize=(10, 5), constrained_layout=True) + + def invert(x): + with np.errstate(divide='ignore'): + return 1 / x + + for nn, ax in enumerate(axs): + ax.plot(np.arange(2, 11), np.arange(2, 11)) + if nn == 0: + secax = ax.secondary_xaxis + else: + secax = ax.secondary_yaxis + + secax(0.2, functions=(invert, invert)) + secax(0.4, functions=(lambda x: 2 * x, lambda x: x / 2)) + secax(0.6, functions=(lambda x: x**2, lambda x: x**(1/2))) + secax(0.8) + + +def test_secondary_fail(): + fig, ax = plt.subplots() + ax.plot(np.arange(2, 11), np.arange(2, 11)) + with pytest.raises(ValueError): + ax.secondary_xaxis(0.2, functions=(lambda x: 1 / x)) + with pytest.raises(ValueError): + ax.secondary_xaxis('right') + with pytest.raises(ValueError): + ax.secondary_yaxis('bottom') + + +def test_secondary_resize(): + fig, ax = plt.subplots(figsize=(10, 5)) + ax.plot(np.arange(2, 11), np.arange(2, 11)) + + def invert(x): + with np.errstate(divide='ignore'): + return 1 / x + + ax.secondary_xaxis('top', functions=(invert, invert)) + fig.canvas.draw() + fig.set_size_inches((7, 4)) + assert_allclose(ax.get_position().extents, [0.125, 0.1, 0.9, 0.9]) + + +def test_secondary_minorloc(): + fig, ax = plt.subplots(figsize=(10, 5)) + ax.plot(np.arange(2, 11), np.arange(2, 11)) + + def invert(x): + with np.errstate(divide='ignore'): + return 1 / x + + secax = ax.secondary_xaxis('top', functions=(invert, invert)) + assert isinstance(secax._axis.get_minor_locator(), + mticker.NullLocator) + secax.minorticks_on() + assert isinstance(secax._axis.get_minor_locator(), + mticker.AutoMinorLocator) + ax.set_xscale('log') + plt.draw() + assert isinstance(secax._axis.get_minor_locator(), + mticker.LogLocator) + ax.set_xscale('linear') + plt.draw() + assert isinstance(secax._axis.get_minor_locator(), + mticker.NullLocator) + + +def test_secondary_formatter(): + fig, ax = plt.subplots() + ax.set_xscale("log") + secax = ax.secondary_xaxis("top") + secax.xaxis.set_major_formatter(mticker.ScalarFormatter()) + fig.canvas.draw() + assert isinstance( + secax.xaxis.get_major_formatter(), mticker.ScalarFormatter) + + +def test_secondary_repr(): + fig, ax = plt.subplots() + secax = ax.secondary_xaxis("top") + assert repr(secax) == '<SecondaryAxis: >' + + +@image_comparison(['axis_options.png'], remove_text=True, style='mpl20') +def test_axis_options(): + fig, axes = plt.subplots(2, 3) + for i, option in enumerate(('scaled', 'tight', 'image')): + # Draw a line and a circle fitting within the boundaries of the line + # The circle should look like a circle for 'scaled' and 'image' + # High/narrow aspect ratio + axes[0, i].plot((1, 2), (1, 3.2)) + axes[0, i].axis(option) + axes[0, i].add_artist(mpatches.Circle((1.5, 1.5), radius=0.5, + facecolor='none', edgecolor='k')) + # Low/wide aspect ratio + axes[1, i].plot((1, 2.25), (1, 1.75)) + axes[1, i].axis(option) + axes[1, i].add_artist(mpatches.Circle((1.5, 1.25), radius=0.25, + facecolor='none', edgecolor='k')) + + +def color_boxes(fig, ax): + """ + Helper for the tests below that test the extents of various axes elements + """ + fig.canvas.draw() + + renderer = fig.canvas.get_renderer() + bbaxis = [] + for nn, axx in enumerate([ax.xaxis, ax.yaxis]): + bb = axx.get_tightbbox(renderer) + if bb: + axisr = mpatches.Rectangle( + (bb.x0, bb.y0), width=bb.width, height=bb.height, + linewidth=0.7, edgecolor='y', facecolor="none", transform=None, + zorder=3) + fig.add_artist(axisr) + bbaxis += [bb] + + bbspines = [] + for nn, a in enumerate(['bottom', 'top', 'left', 'right']): + bb = ax.spines[a].get_window_extent(renderer) + spiner = mpatches.Rectangle( + (bb.x0, bb.y0), width=bb.width, height=bb.height, + linewidth=0.7, edgecolor="green", facecolor="none", transform=None, + zorder=3) + fig.add_artist(spiner) + bbspines += [bb] + + bb = ax.get_window_extent() + rect2 = mpatches.Rectangle( + (bb.x0, bb.y0), width=bb.width, height=bb.height, + linewidth=1.5, edgecolor="magenta", facecolor="none", transform=None, + zorder=2) + fig.add_artist(rect2) + bbax = bb + + bb2 = ax.get_tightbbox(renderer) + rect2 = mpatches.Rectangle( + (bb2.x0, bb2.y0), width=bb2.width, height=bb2.height, + linewidth=3, edgecolor="red", facecolor="none", transform=None, + zorder=1) + fig.add_artist(rect2) + bbtb = bb2 + return bbaxis, bbspines, bbax, bbtb + + +def test_normal_axes(): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + fig.canvas.draw() + plt.close(fig) + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + + # test the axis bboxes + target = [ + [123.375, 75.88888888888886, 983.25, 33.0], + [85.51388888888889, 99.99999999999997, 53.375, 993.0] + ] + for nn, b in enumerate(bbaxis): + targetbb = mtransforms.Bbox.from_bounds(*target[nn]) + assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2) + + target = [ + [150.0, 119.999, 930.0, 11.111], + [150.0, 1080.0, 930.0, 0.0], + [150.0, 119.9999, 11.111, 960.0], + [1068.8888, 119.9999, 11.111, 960.0] + ] + for nn, b in enumerate(bbspines): + targetbb = mtransforms.Bbox.from_bounds(*target[nn]) + assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2) + + target = [150.0, 119.99999999999997, 930.0, 960.0] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_array_almost_equal(bbax.bounds, targetbb.bounds, decimal=2) + + target = [85.5138, 75.88888, 1021.11, 1017.11] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_array_almost_equal(bbtb.bounds, targetbb.bounds, decimal=2) + + # test that get_position roundtrips to get_window_extent + axbb = ax.get_position().transformed(fig.transFigure).bounds + assert_array_almost_equal(axbb, ax.get_window_extent().bounds, decimal=2) + + +def test_nodecorator(): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + fig.canvas.draw() + ax.set(xticklabels=[], yticklabels=[]) + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + + # test the axis bboxes + for nn, b in enumerate(bbaxis): + assert b is None + + target = [ + [150.0, 119.999, 930.0, 11.111], + [150.0, 1080.0, 930.0, 0.0], + [150.0, 119.9999, 11.111, 960.0], + [1068.8888, 119.9999, 11.111, 960.0] + ] + for nn, b in enumerate(bbspines): + targetbb = mtransforms.Bbox.from_bounds(*target[nn]) + assert_allclose(b.bounds, targetbb.bounds, atol=1e-2) + + target = [150.0, 119.99999999999997, 930.0, 960.0] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_allclose(bbax.bounds, targetbb.bounds, atol=1e-2) + + target = [150., 120., 930., 960.] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_allclose(bbtb.bounds, targetbb.bounds, atol=1e-2) + + +def test_displaced_spine(): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + ax.set(xticklabels=[], yticklabels=[]) + ax.spines.bottom.set_position(('axes', -0.1)) + fig.canvas.draw() + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + + targets = [ + [150., 24., 930., 11.111111], + [150.0, 1080.0, 930.0, 0.0], + [150.0, 119.9999, 11.111, 960.0], + [1068.8888, 119.9999, 11.111, 960.0] + ] + for target, bbspine in zip(targets, bbspines): + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_allclose(bbspine.bounds, targetbb.bounds, atol=1e-2) + + target = [150.0, 119.99999999999997, 930.0, 960.0] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_allclose(bbax.bounds, targetbb.bounds, atol=1e-2) + + target = [150., 24., 930., 1056.] + targetbb = mtransforms.Bbox.from_bounds(*target) + assert_allclose(bbtb.bounds, targetbb.bounds, atol=1e-2) + + +def test_tickdirs(): + """ + Switch the tickdirs and make sure the bboxes switch with them + """ + targets = [[[150.0, 120.0, 930.0, 11.1111], + [150.0, 120.0, 11.111, 960.0]], + [[150.0, 108.8889, 930.0, 11.111111111111114], + [138.889, 120, 11.111, 960.0]], + [[150.0, 114.44444444444441, 930.0, 11.111111111111114], + [144.44444444444446, 119.999, 11.111, 960.0]]] + for dnum, dirs in enumerate(['in', 'out', 'inout']): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + ax.tick_params(direction=dirs) + fig.canvas.draw() + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + for nn, num in enumerate([0, 2]): + targetbb = mtransforms.Bbox.from_bounds(*targets[dnum][nn]) + assert_allclose( + bbspines[num].bounds, targetbb.bounds, atol=1e-2) + + +def test_minor_accountedfor(): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + fig.canvas.draw() + ax.tick_params(which='both', direction='out') + + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + targets = [[150.0, 108.88888888888886, 930.0, 11.111111111111114], + [138.8889, 119.9999, 11.1111, 960.0]] + for n in range(2): + targetbb = mtransforms.Bbox.from_bounds(*targets[n]) + assert_allclose( + bbspines[n * 2].bounds, targetbb.bounds, atol=1e-2) + + fig, ax = plt.subplots(dpi=200, figsize=(6, 6)) + fig.canvas.draw() + ax.tick_params(which='both', direction='out') + ax.minorticks_on() + ax.tick_params(axis='both', which='minor', length=30) + fig.canvas.draw() + bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax) + targets = [[150.0, 36.66666666666663, 930.0, 83.33333333333334], + [66.6667, 120.0, 83.3333, 960.0]] + + for n in range(2): + targetbb = mtransforms.Bbox.from_bounds(*targets[n]) + assert_allclose( + bbspines[n * 2].bounds, targetbb.bounds, atol=1e-2) + + +@check_figures_equal(extensions=["png"]) +def test_axis_bool_arguments(fig_test, fig_ref): + # Test if False and "off" give the same + fig_test.add_subplot(211).axis(False) + fig_ref.add_subplot(211).axis("off") + # Test if True after False gives the same as "on" + ax = fig_test.add_subplot(212) + ax.axis(False) + ax.axis(True) + fig_ref.add_subplot(212).axis("on") + + +def test_axis_extent_arg(): + fig, ax = plt.subplots() + xmin = 5 + xmax = 10 + ymin = 15 + ymax = 20 + extent = ax.axis([xmin, xmax, ymin, ymax]) + + # test that the docstring is correct + assert tuple(extent) == (xmin, xmax, ymin, ymax) + + # test that limits were set per the docstring + assert (xmin, xmax) == ax.get_xlim() + assert (ymin, ymax) == ax.get_ylim() + + +def test_axis_extent_arg2(): + # Same as test_axis_extent_arg, but with keyword arguments + fig, ax = plt.subplots() + xmin = 5 + xmax = 10 + ymin = 15 + ymax = 20 + extent = ax.axis(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) + + # test that the docstring is correct + assert tuple(extent) == (xmin, xmax, ymin, ymax) + + # test that limits were set per the docstring + assert (xmin, xmax) == ax.get_xlim() + assert (ymin, ymax) == ax.get_ylim() + + +def test_hist_auto_bins(): + _, bins, _ = plt.hist([[1, 2, 3], [3, 4, 5, 6]], bins='auto') + assert bins[0] <= 1 + assert bins[-1] >= 6 + + +def test_hist_nan_data(): + fig, (ax1, ax2) = plt.subplots(2) + + data = [1, 2, 3] + nan_data = data + [np.nan] + + bins, edges, _ = ax1.hist(data) + with np.errstate(invalid='ignore'): + nanbins, nanedges, _ = ax2.hist(nan_data) + + np.testing.assert_allclose(bins, nanbins) + np.testing.assert_allclose(edges, nanedges) + + +def test_hist_range_and_density(): + _, bins, _ = plt.hist(np.random.rand(10), "auto", + range=(0, 1), density=True) + assert bins[0] == 0 + assert bins[-1] == 1 + + +def test_bar_errbar_zorder(): + # Check that the zorder of errorbars is always greater than the bar they + # are plotted on + fig, ax = plt.subplots() + x = [1, 2, 3] + barcont = ax.bar(x=x, height=x, yerr=x, capsize=5, zorder=3) + + data_line, caplines, barlinecols = barcont.errorbar.lines + for bar in barcont.patches: + for capline in caplines: + assert capline.zorder > bar.zorder + for barlinecol in barlinecols: + assert barlinecol.zorder > bar.zorder + + +def test_set_ticks_inverted(): + fig, ax = plt.subplots() + ax.invert_xaxis() + ax.set_xticks([.3, .7]) + assert ax.get_xlim() == (1, 0) + ax.set_xticks([-1]) + assert ax.get_xlim() == (1, -1) + + +def test_aspect_nonlinear_adjustable_box(): + fig = plt.figure(figsize=(10, 10)) # Square. + + ax = fig.add_subplot() + ax.plot([.4, .6], [.4, .6]) # Set minpos to keep logit happy. + ax.set(xscale="log", xlim=(1, 10), + yscale="logit", ylim=(1/11, 1/1001), + aspect=1, adjustable="box") + ax.margins(0) + pos = fig.transFigure.transform_bbox(ax.get_position()) + assert pos.height / pos.width == pytest.approx(2) + + +def test_aspect_nonlinear_adjustable_datalim(): + fig = plt.figure(figsize=(10, 10)) # Square. + + ax = fig.add_axes([.1, .1, .8, .8]) # Square. + ax.plot([.4, .6], [.4, .6]) # Set minpos to keep logit happy. + ax.set(xscale="log", xlim=(1, 100), + yscale="logit", ylim=(1 / 101, 1 / 11), + aspect=1, adjustable="datalim") + ax.margins(0) + ax.apply_aspect() + + assert ax.get_xlim() == pytest.approx([1*10**(1/2), 100/10**(1/2)]) + assert ax.get_ylim() == (1 / 101, 1 / 11) + + +def test_box_aspect(): + # Test if axes with box_aspect=1 has same dimensions + # as axes with aspect equal and adjustable="box" + + fig1, ax1 = plt.subplots() + axtwin = ax1.twinx() + axtwin.plot([12, 344]) + + ax1.set_box_aspect(1) + assert ax1.get_box_aspect() == 1.0 + + fig2, ax2 = plt.subplots() + ax2.margins(0) + ax2.plot([0, 2], [6, 8]) + ax2.set_aspect("equal", adjustable="box") + + fig1.canvas.draw() + fig2.canvas.draw() + + bb1 = ax1.get_position() + bbt = axtwin.get_position() + bb2 = ax2.get_position() + + assert_array_equal(bb1.extents, bb2.extents) + assert_array_equal(bbt.extents, bb2.extents) + + +def test_box_aspect_custom_position(): + # Test if axes with custom position and box_aspect + # behaves the same independent of the order of setting those. + + fig1, ax1 = plt.subplots() + ax1.set_position([0.1, 0.1, 0.9, 0.2]) + fig1.canvas.draw() + ax1.set_box_aspect(1.) + + fig2, ax2 = plt.subplots() + ax2.set_box_aspect(1.) + fig2.canvas.draw() + ax2.set_position([0.1, 0.1, 0.9, 0.2]) + + fig1.canvas.draw() + fig2.canvas.draw() + + bb1 = ax1.get_position() + bb2 = ax2.get_position() + + assert_array_equal(bb1.extents, bb2.extents) + + +def test_bbox_aspect_axes_init(): + # Test that box_aspect can be given to axes init and produces + # all equal square axes. + fig, axs = plt.subplots(2, 3, subplot_kw=dict(box_aspect=1), + constrained_layout=True) + fig.canvas.draw() + renderer = fig.canvas.get_renderer() + sizes = [] + for ax in axs.flat: + bb = ax.get_window_extent(renderer) + sizes.extend([bb.width, bb.height]) + + assert_allclose(sizes, sizes[0]) + + +def test_set_aspect_negative(): + fig, ax = plt.subplots() + with pytest.raises(ValueError, match="must be finite and positive"): + ax.set_aspect(-1) + with pytest.raises(ValueError, match="must be finite and positive"): + ax.set_aspect(0) + with pytest.raises(ValueError, match="must be finite and positive"): + ax.set_aspect(np.inf) + with pytest.raises(ValueError, match="must be finite and positive"): + ax.set_aspect(-np.inf) + + +def test_redraw_in_frame(): + fig, ax = plt.subplots(1, 1) + ax.plot([1, 2, 3]) + fig.canvas.draw() + ax.redraw_in_frame() + + +def test_invisible_axes_events(): + # invisible axes should not respond to events... + fig, ax = plt.subplots() + assert fig.canvas.inaxes((200, 200)) is not None + ax.set_visible(False) + assert fig.canvas.inaxes((200, 200)) is None + + +def test_xtickcolor_is_not_markercolor(): + plt.rcParams['lines.markeredgecolor'] = 'white' + ax = plt.axes() + ticks = ax.xaxis.get_major_ticks() + for tick in ticks: + assert tick.tick1line.get_markeredgecolor() != 'white' + + +def test_ytickcolor_is_not_markercolor(): + plt.rcParams['lines.markeredgecolor'] = 'white' + ax = plt.axes() + ticks = ax.yaxis.get_major_ticks() + for tick in ticks: + assert tick.tick1line.get_markeredgecolor() != 'white' + + +@pytest.mark.parametrize('axis', ('x', 'y')) +@pytest.mark.parametrize('auto', (True, False, None)) +def test_unautoscale(axis, auto): + fig, ax = plt.subplots() + x = np.arange(100) + y = np.linspace(-.1, .1, 100) + ax.scatter(y, x) + + get_autoscale_on = getattr(ax, f'get_autoscale{axis}_on') + set_lim = getattr(ax, f'set_{axis}lim') + get_lim = getattr(ax, f'get_{axis}lim') + + post_auto = get_autoscale_on() if auto is None else auto + + set_lim((-0.5, 0.5), auto=auto) + assert post_auto == get_autoscale_on() + fig.canvas.draw() + assert_array_equal(get_lim(), (-0.5, 0.5)) + + +@check_figures_equal(extensions=["png"]) +def test_polar_interpolation_steps_variable_r(fig_test, fig_ref): + l, = fig_test.add_subplot(projection="polar").plot([0, np.pi/2], [1, 2]) + l.get_path()._interpolation_steps = 100 + fig_ref.add_subplot(projection="polar").plot( + np.linspace(0, np.pi/2, 101), np.linspace(1, 2, 101)) + + +@mpl.style.context('default') +def test_autoscale_tiny_sticky(): + fig, ax = plt.subplots() + ax.bar(0, 1e-9) + fig.canvas.draw() + assert ax.get_ylim() == (0, 1.05e-9) + + +def test_xtickcolor_is_not_xticklabelcolor(): + plt.rcParams['xtick.color'] = 'yellow' + plt.rcParams['xtick.labelcolor'] = 'blue' + ax = plt.axes() + ticks = ax.xaxis.get_major_ticks() + for tick in ticks: + assert tick.tick1line.get_color() == 'yellow' + assert tick.label1.get_color() == 'blue' + + +def test_ytickcolor_is_not_yticklabelcolor(): + plt.rcParams['ytick.color'] = 'yellow' + plt.rcParams['ytick.labelcolor'] = 'blue' + ax = plt.axes() + ticks = ax.yaxis.get_major_ticks() + for tick in ticks: + assert tick.tick1line.get_color() == 'yellow' + assert tick.label1.get_color() == 'blue' + + +def test_xaxis_offsetText_color(): + plt.rcParams['xtick.labelcolor'] = 'blue' + ax = plt.axes() + assert ax.xaxis.offsetText.get_color() == 'blue' + + plt.rcParams['xtick.color'] = 'yellow' + plt.rcParams['xtick.labelcolor'] = 'inherit' + ax = plt.axes() + assert ax.xaxis.offsetText.get_color() == 'yellow' + + +def test_yaxis_offsetText_color(): + plt.rcParams['ytick.labelcolor'] = 'green' + ax = plt.axes() + assert ax.yaxis.offsetText.get_color() == 'green' + + plt.rcParams['ytick.color'] = 'red' + plt.rcParams['ytick.labelcolor'] = 'inherit' + ax = plt.axes() + assert ax.yaxis.offsetText.get_color() == 'red' + + +@pytest.mark.parametrize('size', [size for size in mfont_manager.font_scalings + if size is not None] + [8, 10, 12]) +@mpl.style.context('default') +def test_relative_ticklabel_sizes(size): + mpl.rcParams['xtick.labelsize'] = size + mpl.rcParams['ytick.labelsize'] = size + fig, ax = plt.subplots() + fig.canvas.draw() + + for name, axis in zip(['x', 'y'], [ax.xaxis, ax.yaxis]): + for tick in axis.get_major_ticks(): + assert tick.label1.get_size() == axis._get_tick_label_size(name) + + +def test_multiplot_autoscale(): + fig = plt.figure() + ax1, ax2 = fig.subplots(2, 1, sharex='all') + ax1.scatter([1, 2, 3, 4], [2, 3, 2, 3]) + ax2.axhspan(-5, 5) + xlim = ax1.get_xlim() + assert np.allclose(xlim, [0.5, 4.5]) + + +def test_sharing_does_not_link_positions(): + fig = plt.figure() + ax0 = fig.add_subplot(221) + ax1 = fig.add_axes([.6, .6, .3, .3], sharex=ax0) + init_pos = ax1.get_position() + fig.subplots_adjust(left=0) + assert (ax1.get_position().get_points() == init_pos.get_points()).all() + + +@check_figures_equal(extensions=["pdf"]) +def test_2dcolor_plot(fig_test, fig_ref): + color = np.array([0.1, 0.2, 0.3]) + # plot with 1D-color: + axs = fig_test.subplots(5) + axs[0].plot([1, 2], [1, 2], c=color.reshape(-1)) + with pytest.warns(match="argument looks like a single numeric RGB"): + axs[1].scatter([1, 2], [1, 2], c=color.reshape(-1)) + axs[2].step([1, 2], [1, 2], c=color.reshape(-1)) + axs[3].hist(np.arange(10), color=color.reshape(-1)) + axs[4].bar(np.arange(10), np.arange(10), color=color.reshape(-1)) + # plot with 2D-color: + axs = fig_ref.subplots(5) + axs[0].plot([1, 2], [1, 2], c=color.reshape((1, -1))) + axs[1].scatter([1, 2], [1, 2], c=color.reshape((1, -1))) + axs[2].step([1, 2], [1, 2], c=color.reshape((1, -1))) + axs[3].hist(np.arange(10), color=color.reshape((1, -1))) + axs[4].bar(np.arange(10), np.arange(10), color=color.reshape((1, -1))) + + +@check_figures_equal(extensions=['png']) +def test_shared_axes_clear(fig_test, fig_ref): + x = np.arange(0.0, 2*np.pi, 0.01) + y = np.sin(x) + + axs = fig_ref.subplots(2, 2, sharex=True, sharey=True) + for ax in axs.flat: + ax.plot(x, y) + + axs = fig_test.subplots(2, 2, sharex=True, sharey=True) + for ax in axs.flat: + ax.clear() + ax.plot(x, y) + + +def test_shared_axes_retick(): + fig, axs = plt.subplots(2, 2, sharex='all', sharey='all') + + for ax in axs.flat: + ax.plot([0, 2], 'o-') + + axs[0, 0].set_xticks([-0.5, 0, 1, 1.5]) # should affect all axes xlims + for ax in axs.flat: + assert ax.get_xlim() == axs[0, 0].get_xlim() + + axs[0, 0].set_yticks([-0.5, 0, 2, 2.5]) # should affect all axes ylims + for ax in axs.flat: + assert ax.get_ylim() == axs[0, 0].get_ylim() + + +@pytest.mark.parametrize('ha', ['left', 'center', 'right']) +def test_ylabel_ha_with_position(ha): + fig = Figure() + ax = fig.subplots() + ax.set_ylabel("test", y=1, ha=ha) + ax.yaxis.set_label_position("right") + assert ax.yaxis.get_label().get_ha() == ha + + +def test_bar_label_location_vertical(): + ax = plt.gca() + xs, heights = [1, 2], [3, -4] + rects = ax.bar(xs, heights) + labels = ax.bar_label(rects) + assert labels[0].xy == (xs[0], heights[0]) + assert labels[0].get_horizontalalignment() == 'center' + assert labels[0].get_verticalalignment() == 'bottom' + assert labels[1].xy == (xs[1], heights[1]) + assert labels[1].get_horizontalalignment() == 'center' + assert labels[1].get_verticalalignment() == 'top' + + +def test_bar_label_location_vertical_yinverted(): + ax = plt.gca() + ax.invert_yaxis() + xs, heights = [1, 2], [3, -4] + rects = ax.bar(xs, heights) + labels = ax.bar_label(rects) + assert labels[0].xy == (xs[0], heights[0]) + assert labels[0].get_horizontalalignment() == 'center' + assert labels[0].get_verticalalignment() == 'top' + assert labels[1].xy == (xs[1], heights[1]) + assert labels[1].get_horizontalalignment() == 'center' + assert labels[1].get_verticalalignment() == 'bottom' + + +def test_bar_label_location_horizontal(): + ax = plt.gca() + ys, widths = [1, 2], [3, -4] + rects = ax.barh(ys, widths) + labels = ax.bar_label(rects) + assert labels[0].xy == (widths[0], ys[0]) + assert labels[0].get_horizontalalignment() == 'left' + assert labels[0].get_verticalalignment() == 'center' + assert labels[1].xy == (widths[1], ys[1]) + assert labels[1].get_horizontalalignment() == 'right' + assert labels[1].get_verticalalignment() == 'center' + + +def test_bar_label_location_horizontal_yinverted(): + ax = plt.gca() + ax.invert_yaxis() + ys, widths = [1, 2], [3, -4] + rects = ax.barh(ys, widths) + labels = ax.bar_label(rects) + assert labels[0].xy == (widths[0], ys[0]) + assert labels[0].get_horizontalalignment() == 'left' + assert labels[0].get_verticalalignment() == 'center' + assert labels[1].xy == (widths[1], ys[1]) + assert labels[1].get_horizontalalignment() == 'right' + assert labels[1].get_verticalalignment() == 'center' + + +def test_bar_label_location_horizontal_xinverted(): + ax = plt.gca() + ax.invert_xaxis() + ys, widths = [1, 2], [3, -4] + rects = ax.barh(ys, widths) + labels = ax.bar_label(rects) + assert labels[0].xy == (widths[0], ys[0]) + assert labels[0].get_horizontalalignment() == 'right' + assert labels[0].get_verticalalignment() == 'center' + assert labels[1].xy == (widths[1], ys[1]) + assert labels[1].get_horizontalalignment() == 'left' + assert labels[1].get_verticalalignment() == 'center' + + +def test_bar_label_location_horizontal_xyinverted(): + ax = plt.gca() + ax.invert_xaxis() + ax.invert_yaxis() + ys, widths = [1, 2], [3, -4] + rects = ax.barh(ys, widths) + labels = ax.bar_label(rects) + assert labels[0].xy == (widths[0], ys[0]) + assert labels[0].get_horizontalalignment() == 'right' + assert labels[0].get_verticalalignment() == 'center' + assert labels[1].xy == (widths[1], ys[1]) + assert labels[1].get_horizontalalignment() == 'left' + assert labels[1].get_verticalalignment() == 'center' + + +def test_bar_label_location_center(): + ax = plt.gca() + ys, widths = [1, 2], [3, -4] + rects = ax.barh(ys, widths) + labels = ax.bar_label(rects, label_type='center') + assert labels[0].xy == (0.5, 0.5) + assert labels[0].get_horizontalalignment() == 'center' + assert labels[0].get_verticalalignment() == 'center' + assert labels[1].xy == (0.5, 0.5) + assert labels[1].get_horizontalalignment() == 'center' + assert labels[1].get_verticalalignment() == 'center' + + +@image_comparison(['test_centered_bar_label_nonlinear.svg']) +def test_centered_bar_label_nonlinear(): + _, ax = plt.subplots() + bar_container = ax.barh(['c', 'b', 'a'], [1_000, 5_000, 7_000]) + ax.set_xscale('log') + ax.set_xlim(1, None) + ax.bar_label(bar_container, label_type='center') + ax.set_axis_off() + + +def test_centered_bar_label_label_beyond_limits(): + fig, ax = plt.subplots() + + last = 0 + for label, value in zip(['a', 'b', 'c'], [10, 20, 50]): + bar_container = ax.barh('col', value, label=label, left=last) + ax.bar_label(bar_container, label_type='center') + last += value + ax.set_xlim(None, 20) + + fig.draw_without_rendering() + + +def test_bar_label_location_errorbars(): + ax = plt.gca() + xs, heights = [1, 2], [3, -4] + rects = ax.bar(xs, heights, yerr=1) + labels = ax.bar_label(rects) + assert labels[0].xy == (xs[0], heights[0] + 1) + assert labels[0].get_horizontalalignment() == 'center' + assert labels[0].get_verticalalignment() == 'bottom' + assert labels[1].xy == (xs[1], heights[1] - 1) + assert labels[1].get_horizontalalignment() == 'center' + assert labels[1].get_verticalalignment() == 'top' + + +@pytest.mark.parametrize('fmt', [ + '%.2f', '{:.2f}', '{:.2f}'.format +]) +def test_bar_label_fmt(fmt): + ax = plt.gca() + rects = ax.bar([1, 2], [3, -4]) + labels = ax.bar_label(rects, fmt=fmt) + assert labels[0].get_text() == '3.00' + assert labels[1].get_text() == '-4.00' + + +def test_bar_label_fmt_error(): + ax = plt.gca() + rects = ax.bar([1, 2], [3, -4]) + with pytest.raises(TypeError, match='str or callable'): + _ = ax.bar_label(rects, fmt=10) + + +def test_bar_label_labels(): + ax = plt.gca() + rects = ax.bar([1, 2], [3, -4]) + labels = ax.bar_label(rects, labels=['A', 'B']) + assert labels[0].get_text() == 'A' + assert labels[1].get_text() == 'B' + + +def test_bar_label_nan_ydata(): + ax = plt.gca() + bars = ax.bar([2, 3], [np.nan, 1]) + labels = ax.bar_label(bars) + assert [l.get_text() for l in labels] == ['', '1'] + assert labels[0].xy == (2, 0) + assert labels[0].get_verticalalignment() == 'bottom' + + +def test_bar_label_nan_ydata_inverted(): + ax = plt.gca() + ax.yaxis_inverted() + bars = ax.bar([2, 3], [np.nan, 1]) + labels = ax.bar_label(bars) + assert [l.get_text() for l in labels] == ['', '1'] + assert labels[0].xy == (2, 0) + assert labels[0].get_verticalalignment() == 'bottom' + + +def test_nan_barlabels(): + fig, ax = plt.subplots() + bars = ax.bar([1, 2, 3], [np.nan, 1, 2], yerr=[0.2, 0.4, 0.6]) + labels = ax.bar_label(bars) + assert [l.get_text() for l in labels] == ['', '1', '2'] + assert np.allclose(ax.get_ylim(), (0.0, 3.0)) + + fig, ax = plt.subplots() + bars = ax.bar([1, 2, 3], [0, 1, 2], yerr=[0.2, np.nan, 0.6]) + labels = ax.bar_label(bars) + assert [l.get_text() for l in labels] == ['0', '1', '2'] + assert np.allclose(ax.get_ylim(), (-0.5, 3.0)) + + fig, ax = plt.subplots() + bars = ax.bar([1, 2, 3], [np.nan, 1, 2], yerr=[np.nan, np.nan, 0.6]) + labels = ax.bar_label(bars) + assert [l.get_text() for l in labels] == ['', '1', '2'] + assert np.allclose(ax.get_ylim(), (0.0, 3.0)) + + +def test_patch_bounds(): # PR 19078 + fig, ax = plt.subplots() + ax.add_patch(mpatches.Wedge((0, -1), 1.05, 60, 120, width=0.1)) + bot = 1.9*np.sin(15*np.pi/180)**2 + np.testing.assert_array_almost_equal_nulp( + np.array((-0.525, -(bot+0.05), 1.05, bot+0.1)), ax.dataLim.bounds, 16) + + +@mpl.style.context('default') +def test_warn_ignored_scatter_kwargs(): + with pytest.warns(UserWarning, + match=r"You passed a edgecolor/edgecolors"): + plt.scatter([0], [0], marker="+", s=500, facecolor="r", edgecolor="b") + + +def test_artist_sublists(): + fig, ax = plt.subplots() + lines = [ax.plot(np.arange(i, i + 5))[0] for i in range(6)] + col = ax.scatter(np.arange(5), np.arange(5)) + im = ax.imshow(np.zeros((5, 5))) + patch = ax.add_patch(mpatches.Rectangle((0, 0), 5, 5)) + text = ax.text(0, 0, 'foo') + + # Get items, which should not be mixed. + assert list(ax.collections) == [col] + assert list(ax.images) == [im] + assert list(ax.lines) == lines + assert list(ax.patches) == [patch] + assert not ax.tables + assert list(ax.texts) == [text] + + # Get items should work like lists/tuple. + assert ax.lines[0] is lines[0] + assert ax.lines[-1] is lines[-1] + with pytest.raises(IndexError, match='out of range'): + ax.lines[len(lines) + 1] + + # Adding to other lists should produce a regular list. + assert ax.lines + [1, 2, 3] == [*lines, 1, 2, 3] + assert [1, 2, 3] + ax.lines == [1, 2, 3, *lines] + + # Adding to other tuples should produce a regular tuples. + assert ax.lines + (1, 2, 3) == (*lines, 1, 2, 3) + assert (1, 2, 3) + ax.lines == (1, 2, 3, *lines) + + # Lists should be empty after removing items. + col.remove() + assert not ax.collections + im.remove() + assert not ax.images + patch.remove() + assert not ax.patches + assert not ax.tables + text.remove() + assert not ax.texts + + for ln in ax.lines: + ln.remove() + assert len(ax.lines) == 0 + + +def test_empty_line_plots(): + # Incompatible nr columns, plot "nothing" + x = np.ones(10) + y = np.ones((10, 0)) + _, ax = plt.subplots() + line = ax.plot(x, y) + assert len(line) == 0 + + # Ensure plot([],[]) creates line + _, ax = plt.subplots() + line = ax.plot([], []) + assert len(line) == 1 + + +@pytest.mark.parametrize('fmt, match', ( + ("f", r"'f' is not a valid format string \(unrecognized character 'f'\)"), + ("o+", r"'o\+' is not a valid format string \(two marker symbols\)"), + (":-", r"':-' is not a valid format string \(two linestyle symbols\)"), + ("rk", r"'rk' is not a valid format string \(two color symbols\)"), + (":o-r", r"':o-r' is not a valid format string \(two linestyle symbols\)"), +)) +@pytest.mark.parametrize("data", [None, {"string": range(3)}]) +def test_plot_format_errors(fmt, match, data): + fig, ax = plt.subplots() + if data is not None: + match = match.replace("not", "neither a data key nor") + with pytest.raises(ValueError, match=r"\A" + match + r"\Z"): + ax.plot("string", fmt, data=data) + + +def test_plot_format(): + fig, ax = plt.subplots() + line = ax.plot([1, 2, 3], '1.0') + assert line[0].get_color() == (1.0, 1.0, 1.0, 1.0) + assert line[0].get_marker() == 'None' + fig, ax = plt.subplots() + line = ax.plot([1, 2, 3], '1') + assert line[0].get_marker() == '1' + fig, ax = plt.subplots() + line = ax.plot([1, 2], [1, 2], '1.0', "1") + fig.canvas.draw() + assert line[0].get_color() == (1.0, 1.0, 1.0, 1.0) + assert ax.get_yticklabels()[0].get_text() == '1' + fig, ax = plt.subplots() + line = ax.plot([1, 2], [1, 2], '1', "1.0") + fig.canvas.draw() + assert line[0].get_marker() == '1' + assert ax.get_yticklabels()[0].get_text() == '1.0' + fig, ax = plt.subplots() + line = ax.plot([1, 2, 3], 'k3') + assert line[0].get_marker() == '3' + assert line[0].get_color() == 'k' + + +def test_automatic_legend(): + fig, ax = plt.subplots() + ax.plot("a", "b", data={"d": 2}) + leg = ax.legend() + fig.canvas.draw() + assert leg.get_texts()[0].get_text() == 'a' + assert ax.get_yticklabels()[0].get_text() == 'a' + + fig, ax = plt.subplots() + ax.plot("a", "b", "c", data={"d": 2}) + leg = ax.legend() + fig.canvas.draw() + assert leg.get_texts()[0].get_text() == 'b' + assert ax.get_xticklabels()[0].get_text() == 'a' + assert ax.get_yticklabels()[0].get_text() == 'b' + + +def test_plot_errors(): + with pytest.raises(TypeError, match=r"plot\(\) got an unexpected keyword"): + plt.plot([1, 2, 3], x=1) + with pytest.raises(ValueError, match=r"plot\(\) with multiple groups"): + plt.plot([1, 2, 3], [1, 2, 3], [2, 3, 4], [2, 3, 4], label=['1', '2']) + with pytest.raises(ValueError, match="x and y must have same first"): + plt.plot([1, 2, 3], [1]) + with pytest.raises(ValueError, match="x and y can be no greater than"): + plt.plot(np.ones((2, 2, 2))) + with pytest.raises(ValueError, match="Using arbitrary long args with"): + plt.plot("a", "b", "c", "d", data={"a": 2}) + + +def test_clim(): + ax = plt.figure().add_subplot() + for plot_method in [ + partial(ax.scatter, range(3), range(3), c=range(3)), + partial(ax.imshow, [[0, 1], [2, 3]]), + partial(ax.pcolor, [[0, 1], [2, 3]]), + partial(ax.pcolormesh, [[0, 1], [2, 3]]), + partial(ax.pcolorfast, [[0, 1], [2, 3]]), + ]: + clim = (7, 8) + norm = plot_method(clim=clim).norm + assert (norm.vmin, norm.vmax) == clim + + +def test_bezier_autoscale(): + # Check that bezier curves autoscale to their curves, and not their + # control points + verts = [[-1, 0], + [0, -1], + [1, 0], + [1, 0]] + codes = [mpath.Path.MOVETO, + mpath.Path.CURVE3, + mpath.Path.CURVE3, + mpath.Path.CLOSEPOLY] + p = mpath.Path(verts, codes) + + fig, ax = plt.subplots() + ax.add_patch(mpatches.PathPatch(p)) + ax.autoscale() + # Bottom ylim should be at the edge of the curve (-0.5), and not include + # the control point (at -1) + assert ax.get_ylim()[0] == -0.5 + + +def test_small_autoscale(): + # Check that paths with small values autoscale correctly #24097. + verts = np.array([ + [-5.45, 0.00], [-5.45, 0.00], [-5.29, 0.00], [-5.29, 0.00], + [-5.13, 0.00], [-5.13, 0.00], [-4.97, 0.00], [-4.97, 0.00], + [-4.81, 0.00], [-4.81, 0.00], [-4.65, 0.00], [-4.65, 0.00], + [-4.49, 0.00], [-4.49, 0.00], [-4.33, 0.00], [-4.33, 0.00], + [-4.17, 0.00], [-4.17, 0.00], [-4.01, 0.00], [-4.01, 0.00], + [-3.85, 0.00], [-3.85, 0.00], [-3.69, 0.00], [-3.69, 0.00], + [-3.53, 0.00], [-3.53, 0.00], [-3.37, 0.00], [-3.37, 0.00], + [-3.21, 0.00], [-3.21, 0.01], [-3.05, 0.01], [-3.05, 0.01], + [-2.89, 0.01], [-2.89, 0.01], [-2.73, 0.01], [-2.73, 0.02], + [-2.57, 0.02], [-2.57, 0.04], [-2.41, 0.04], [-2.41, 0.04], + [-2.25, 0.04], [-2.25, 0.06], [-2.09, 0.06], [-2.09, 0.08], + [-1.93, 0.08], [-1.93, 0.10], [-1.77, 0.10], [-1.77, 0.12], + [-1.61, 0.12], [-1.61, 0.14], [-1.45, 0.14], [-1.45, 0.17], + [-1.30, 0.17], [-1.30, 0.19], [-1.14, 0.19], [-1.14, 0.22], + [-0.98, 0.22], [-0.98, 0.25], [-0.82, 0.25], [-0.82, 0.27], + [-0.66, 0.27], [-0.66, 0.29], [-0.50, 0.29], [-0.50, 0.30], + [-0.34, 0.30], [-0.34, 0.32], [-0.18, 0.32], [-0.18, 0.33], + [-0.02, 0.33], [-0.02, 0.32], [0.13, 0.32], [0.13, 0.33], [0.29, 0.33], + [0.29, 0.31], [0.45, 0.31], [0.45, 0.30], [0.61, 0.30], [0.61, 0.28], + [0.77, 0.28], [0.77, 0.25], [0.93, 0.25], [0.93, 0.22], [1.09, 0.22], + [1.09, 0.19], [1.25, 0.19], [1.25, 0.17], [1.41, 0.17], [1.41, 0.15], + [1.57, 0.15], [1.57, 0.12], [1.73, 0.12], [1.73, 0.10], [1.89, 0.10], + [1.89, 0.08], [2.05, 0.08], [2.05, 0.07], [2.21, 0.07], [2.21, 0.05], + [2.37, 0.05], [2.37, 0.04], [2.53, 0.04], [2.53, 0.02], [2.69, 0.02], + [2.69, 0.02], [2.85, 0.02], [2.85, 0.01], [3.01, 0.01], [3.01, 0.01], + [3.17, 0.01], [3.17, 0.00], [3.33, 0.00], [3.33, 0.00], [3.49, 0.00], + [3.49, 0.00], [3.65, 0.00], [3.65, 0.00], [3.81, 0.00], [3.81, 0.00], + [3.97, 0.00], [3.97, 0.00], [4.13, 0.00], [4.13, 0.00], [4.29, 0.00], + [4.29, 0.00], [4.45, 0.00], [4.45, 0.00], [4.61, 0.00], [4.61, 0.00], + [4.77, 0.00], [4.77, 0.00], [4.93, 0.00], [4.93, 0.00], + ]) + + minx = np.min(verts[:, 0]) + miny = np.min(verts[:, 1]) + maxx = np.max(verts[:, 0]) + maxy = np.max(verts[:, 1]) + + p = mpath.Path(verts) + + fig, ax = plt.subplots() + ax.add_patch(mpatches.PathPatch(p)) + ax.autoscale() + + assert ax.get_xlim()[0] <= minx + assert ax.get_xlim()[1] >= maxx + assert ax.get_ylim()[0] <= miny + assert ax.get_ylim()[1] >= maxy + + +def test_get_xticklabel(): + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + for ind in range(10): + assert ax.get_xticklabels()[ind].get_text() == f'{ind}' + assert ax.get_yticklabels()[ind].get_text() == f'{ind}' + + +def test_bar_leading_nan(): + + barx = np.arange(3, dtype=float) + barheights = np.array([0.5, 1.5, 2.0]) + barstarts = np.array([0.77]*3) + + barx[0] = np.nan + + fig, ax = plt.subplots() + + bars = ax.bar(barx, barheights, bottom=barstarts) + + hbars = ax.barh(barx, barheights, left=barstarts) + + for bar_set in (bars, hbars): + # the first bar should have a nan in the location + nanful, *rest = bar_set + assert (~np.isfinite(nanful.xy)).any() + assert np.isfinite(nanful.get_width()) + for b in rest: + assert np.isfinite(b.xy).all() + assert np.isfinite(b.get_width()) + + +@check_figures_equal(extensions=["png"]) +def test_bar_all_nan(fig_test, fig_ref): + mpl.style.use("mpl20") + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + + ax_test.bar([np.nan], [np.nan]) + ax_test.bar([1], [1]) + + ax_ref.bar([1], [1]).remove() + ax_ref.bar([1], [1]) + + +@image_comparison(["extent_units.png"], style="mpl20") +def test_extent_units(): + _, axs = plt.subplots(2, 2) + date_first = np.datetime64('2020-01-01', 'D') + date_last = np.datetime64('2020-01-11', 'D') + arr = [[i+j for i in range(10)] for j in range(10)] + + axs[0, 0].set_title('Date extents on y axis') + im = axs[0, 0].imshow(arr, origin='lower', + extent=[1, 11, date_first, date_last], + cmap=mpl.colormaps["plasma"]) + + axs[0, 1].set_title('Date extents on x axis (Day of Jan 2020)') + im = axs[0, 1].imshow(arr, origin='lower', + extent=[date_first, date_last, 1, 11], + cmap=mpl.colormaps["plasma"]) + axs[0, 1].xaxis.set_major_formatter(mdates.DateFormatter('%d')) + + im = axs[1, 0].imshow(arr, origin='lower', + extent=[date_first, date_last, + date_first, date_last], + cmap=mpl.colormaps["plasma"]) + axs[1, 0].xaxis.set_major_formatter(mdates.DateFormatter('%d')) + axs[1, 0].set(xlabel='Day of Jan 2020') + + im = axs[1, 1].imshow(arr, origin='lower', + cmap=mpl.colormaps["plasma"]) + im.set_extent([date_last, date_first, date_last, date_first]) + axs[1, 1].xaxis.set_major_formatter(mdates.DateFormatter('%d')) + axs[1, 1].set(xlabel='Day of Jan 2020') + + with pytest.raises(TypeError, match=r"set_extent\(\) got an unexpected"): + im.set_extent([2, 12, date_first, date_last], clip=False) + + +def test_cla_clears_children_axes_and_fig(): + fig, ax = plt.subplots() + lines = ax.plot([], [], [], []) + img = ax.imshow([[1]]) + for art in lines + [img]: + assert art.axes is ax + assert art.figure is fig + ax.clear() + for art in lines + [img]: + assert art.axes is None + assert art.figure is None + + +def test_child_axes_removal(): + fig, ax = plt.subplots() + marginal = ax.inset_axes([1, 0, .1, 1], sharey=ax) + marginal_twin = marginal.twinx() + marginal.remove() + ax.set(xlim=(-1, 1), ylim=(10, 20)) + + +def test_scatter_color_repr_error(): + + def get_next_color(): + return 'blue' # pragma: no cover + msg = ( + r"'c' argument must be a color, a sequence of colors" + r", or a sequence of numbers, not 'red\\n'" + ) + with pytest.raises(ValueError, match=msg): + c = 'red\n' + mpl.axes.Axes._parse_scatter_color_args( + c, None, kwargs={}, xsize=2, get_next_color_func=get_next_color) + + +def test_zorder_and_explicit_rasterization(): + fig, ax = plt.subplots() + ax.set_rasterization_zorder(5) + ln, = ax.plot(range(5), rasterized=True, zorder=1) + with io.BytesIO() as b: + fig.savefig(b, format='pdf') + + +@image_comparison(["preset_clip_paths.png"], remove_text=True, style="mpl20") +def test_preset_clip_paths(): + fig, ax = plt.subplots() + + poly = mpl.patches.Polygon( + [[1, 0], [0, 1], [-1, 0], [0, -1]], facecolor="#ddffdd", + edgecolor="#00ff00", linewidth=2, alpha=0.5) + + ax.add_patch(poly) + + line = mpl.lines.Line2D((-1, 1), (0.5, 0.5), clip_on=True, clip_path=poly) + line.set_path_effects([patheffects.withTickedStroke()]) + ax.add_artist(line) + + line = mpl.lines.Line2D((-1, 1), (-0.5, -0.5), color='r', clip_on=True, + clip_path=poly) + ax.add_artist(line) + + poly2 = mpl.patches.Polygon( + [[-1, 1], [0, 1], [0, -0.25]], facecolor="#beefc0", alpha=0.3, + edgecolor="#faded0", linewidth=2, clip_on=True, clip_path=poly) + ax.add_artist(poly2) + + # When text clipping works, the "Annotation" text should be clipped + ax.annotate('Annotation', (-0.75, -0.75), xytext=(0.1, 0.75), + arrowprops={'color': 'k'}, clip_on=True, clip_path=poly) + + poly3 = mpl.patches.Polygon( + [[0, 0], [0, 0.5], [0.5, 0.5], [0.5, 0]], facecolor="g", edgecolor="y", + linewidth=2, alpha=0.3, clip_on=True, clip_path=poly) + + fig.add_artist(poly3, clip=True) + + ax.set_xlim(-1, 1) + ax.set_ylim(-1, 1) + + +@mpl.style.context('default') +def test_rc_axes_label_formatting(): + mpl.rcParams['axes.labelcolor'] = 'red' + mpl.rcParams['axes.labelsize'] = 20 + mpl.rcParams['axes.labelweight'] = 'bold' + + ax = plt.axes() + assert ax.xaxis.label.get_color() == 'red' + assert ax.xaxis.label.get_fontsize() == 20 + assert ax.xaxis.label.get_fontweight() == 'bold' + + +@check_figures_equal(extensions=["png"]) +def test_ecdf(fig_test, fig_ref): + data = np.array([0, -np.inf, -np.inf, np.inf, 1, 1, 2]) + weights = range(len(data)) + axs_test = fig_test.subplots(1, 2) + for ax, orientation in zip(axs_test, ["vertical", "horizontal"]): + l0 = ax.ecdf(data, orientation=orientation) + l1 = ax.ecdf("d", "w", data={"d": np.ma.array(data), "w": weights}, + orientation=orientation, + complementary=True, compress=True, ls=":") + assert len(l0.get_xdata()) == (~np.isnan(data)).sum() + 1 + assert len(l1.get_xdata()) == len({*data[~np.isnan(data)]}) + 1 + axs_ref = fig_ref.subplots(1, 2) + axs_ref[0].plot([-np.inf, -np.inf, -np.inf, 0, 1, 1, 2, np.inf], + np.arange(8) / 7, ds="steps-post") + axs_ref[0].plot([-np.inf, 0, 1, 2, np.inf, np.inf], + np.array([21, 20, 18, 14, 3, 0]) / 21, + ds="steps-pre", ls=":") + axs_ref[1].plot(np.arange(8) / 7, + [-np.inf, -np.inf, -np.inf, 0, 1, 1, 2, np.inf], + ds="steps-pre") + axs_ref[1].plot(np.array([21, 20, 18, 14, 3, 0]) / 21, + [-np.inf, 0, 1, 2, np.inf, np.inf], + ds="steps-post", ls=":") + + +def test_ecdf_invalid(): + with pytest.raises(ValueError): + plt.ecdf([1, np.nan]) + with pytest.raises(ValueError): + plt.ecdf(np.ma.array([1, 2], mask=[True, False])) + + +def test_fill_between_axes_limits(): + fig, ax = plt.subplots() + x = np.arange(0, 4 * np.pi, 0.01) + y = 0.1*np.sin(x) + threshold = 0.075 + ax.plot(x, y, color='black') + + original_lims = (ax.get_xlim(), ax.get_ylim()) + + ax.axhline(threshold, color='green', lw=2, alpha=0.7) + ax.fill_between(x, 0, 1, where=y > threshold, + color='green', alpha=0.5, transform=ax.get_xaxis_transform()) + + assert (ax.get_xlim(), ax.get_ylim()) == original_lims + + +def test_tick_param_labelfont(): + fig, ax = plt.subplots() + ax.plot([1, 2, 3, 4], [1, 2, 3, 4]) + ax.set_xlabel('X label in Impact font', fontname='Impact') + ax.set_ylabel('Y label in xkcd script', fontname='xkcd script') + ax.tick_params(color='r', labelfontfamily='monospace') + plt.title('Title in sans-serif') + for text in ax.get_xticklabels(): + assert text.get_fontfamily()[0] == 'monospace' + + +def test_set_secondary_axis_color(): + fig, ax = plt.subplots() + sax = ax.secondary_xaxis("top", color="red") + assert mcolors.same_color(sax.spines["bottom"].get_edgecolor(), "red") + assert mcolors.same_color(sax.spines["top"].get_edgecolor(), "red") + assert mcolors.same_color(sax.xaxis.get_tick_params()["color"], "red") + assert mcolors.same_color(sax.xaxis.get_tick_params()["labelcolor"], "red") + assert mcolors.same_color(sax.xaxis.label.get_color(), "red") + + +def test_xylim_changed_shared(): + fig, axs = plt.subplots(2, sharex=True, sharey=True) + events = [] + axs[1].callbacks.connect("xlim_changed", events.append) + axs[1].callbacks.connect("ylim_changed", events.append) + axs[0].set(xlim=[1, 3], ylim=[2, 4]) + assert events == [axs[1], axs[1]] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axis.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axis.py new file mode 100644 index 00000000..97b5f88d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_axis.py @@ -0,0 +1,10 @@ +import numpy as np + +import matplotlib.pyplot as plt +from matplotlib.axis import XTick + + +def test_tick_labelcolor_array(): + # Smoke test that we can instantiate a Tick with labelcolor as array. + ax = plt.axes() + XTick(ax, 0, labelcolor=np.array([1, 0, 0, 1])) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_bases.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_bases.py new file mode 100644 index 00000000..471f46f0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_bases.py @@ -0,0 +1,441 @@ +import re + +from matplotlib import path, transforms +from matplotlib.backend_bases import ( + FigureCanvasBase, KeyEvent, LocationEvent, MouseButton, MouseEvent, + NavigationToolbar2, RendererBase) +from matplotlib.backend_tools import RubberbandBase +from matplotlib.figure import Figure +from matplotlib.testing._markers import needs_pgf_xelatex +import matplotlib.pyplot as plt + +import numpy as np +import pytest + + +_EXPECTED_WARNING_TOOLMANAGER = ( + r"Treat the new Tool classes introduced in " + r"v[0-9]*.[0-9]* as experimental for now; " + "the API and rcParam may change in future versions.") + + +def test_uses_per_path(): + id = transforms.Affine2D() + paths = [path.Path.unit_regular_polygon(i) for i in range(3, 7)] + tforms_matrices = [id.rotate(i).get_matrix().copy() for i in range(1, 5)] + offsets = np.arange(20).reshape((10, 2)) + facecolors = ['red', 'green'] + edgecolors = ['red', 'green'] + + def check(master_transform, paths, all_transforms, + offsets, facecolors, edgecolors): + rb = RendererBase() + raw_paths = list(rb._iter_collection_raw_paths( + master_transform, paths, all_transforms)) + gc = rb.new_gc() + ids = [path_id for xo, yo, path_id, gc0, rgbFace in + rb._iter_collection( + gc, range(len(raw_paths)), offsets, + transforms.AffineDeltaTransform(master_transform), + facecolors, edgecolors, [], [], [False], + [], 'screen')] + uses = rb._iter_collection_uses_per_path( + paths, all_transforms, offsets, facecolors, edgecolors) + if raw_paths: + seen = np.bincount(ids, minlength=len(raw_paths)) + assert set(seen).issubset([uses - 1, uses]) + + check(id, paths, tforms_matrices, offsets, facecolors, edgecolors) + check(id, paths[0:1], tforms_matrices, offsets, facecolors, edgecolors) + check(id, [], tforms_matrices, offsets, facecolors, edgecolors) + check(id, paths, tforms_matrices[0:1], offsets, facecolors, edgecolors) + check(id, paths, [], offsets, facecolors, edgecolors) + for n in range(0, offsets.shape[0]): + check(id, paths, tforms_matrices, offsets[0:n, :], + facecolors, edgecolors) + check(id, paths, tforms_matrices, offsets, [], edgecolors) + check(id, paths, tforms_matrices, offsets, facecolors, []) + check(id, paths, tforms_matrices, offsets, [], []) + check(id, paths, tforms_matrices, offsets, facecolors[0:1], edgecolors) + + +def test_canvas_ctor(): + assert isinstance(FigureCanvasBase().figure, Figure) + + +def test_get_default_filename(): + assert plt.figure().canvas.get_default_filename() == 'image.png' + + +def test_canvas_change(): + fig = plt.figure() + # Replaces fig.canvas + canvas = FigureCanvasBase(fig) + # Should still work. + plt.close(fig) + assert not plt.fignum_exists(fig.number) + + +@pytest.mark.backend('pdf') +def test_non_gui_warning(monkeypatch): + plt.subplots() + + monkeypatch.setenv("DISPLAY", ":999") + + with pytest.warns(UserWarning) as rec: + plt.show() + assert len(rec) == 1 + assert ('FigureCanvasPdf is non-interactive, and thus cannot be shown' + in str(rec[0].message)) + + with pytest.warns(UserWarning) as rec: + plt.gcf().show() + assert len(rec) == 1 + assert ('FigureCanvasPdf is non-interactive, and thus cannot be shown' + in str(rec[0].message)) + + +def test_grab_clear(): + fig, ax = plt.subplots() + + fig.canvas.grab_mouse(ax) + assert fig.canvas.mouse_grabber == ax + + fig.clear() + assert fig.canvas.mouse_grabber is None + + +@pytest.mark.parametrize( + "x, y", [(42, 24), (None, 42), (None, None), (200, 100.01), (205.75, 2.0)]) +def test_location_event_position(x, y): + # LocationEvent should cast its x and y arguments to int unless it is None. + fig, ax = plt.subplots() + canvas = FigureCanvasBase(fig) + event = LocationEvent("test_event", canvas, x, y) + if x is None: + assert event.x is None + else: + assert event.x == int(x) + assert isinstance(event.x, int) + if y is None: + assert event.y is None + else: + assert event.y == int(y) + assert isinstance(event.y, int) + if x is not None and y is not None: + assert re.match( + f"x={ax.format_xdata(x)} +y={ax.format_ydata(y)}", + ax.format_coord(x, y)) + ax.fmt_xdata = ax.fmt_ydata = lambda x: "foo" + assert re.match("x=foo +y=foo", ax.format_coord(x, y)) + + +def test_pick(): + fig = plt.figure() + fig.text(.5, .5, "hello", ha="center", va="center", picker=True) + fig.canvas.draw() + + picks = [] + def handle_pick(event): + assert event.mouseevent.key == "a" + picks.append(event) + fig.canvas.mpl_connect("pick_event", handle_pick) + + KeyEvent("key_press_event", fig.canvas, "a")._process() + MouseEvent("button_press_event", fig.canvas, + *fig.transFigure.transform((.5, .5)), + MouseButton.LEFT)._process() + KeyEvent("key_release_event", fig.canvas, "a")._process() + assert len(picks) == 1 + + +def test_interactive_zoom(): + fig, ax = plt.subplots() + ax.set(xscale="logit") + assert ax.get_navigate_mode() is None + + tb = NavigationToolbar2(fig.canvas) + tb.zoom() + assert ax.get_navigate_mode() == 'ZOOM' + + xlim0 = ax.get_xlim() + ylim0 = ax.get_ylim() + + # Zoom from x=1e-6, y=0.1 to x=1-1e-5, 0.8 (data coordinates, "d"). + d0 = (1e-6, 0.1) + d1 = (1-1e-5, 0.8) + # Convert to screen coordinates ("s"). Events are defined only with pixel + # precision, so round the pixel values, and below, check against the + # corresponding xdata/ydata, which are close but not equal to d0/d1. + s0 = ax.transData.transform(d0).astype(int) + s1 = ax.transData.transform(d1).astype(int) + + # Zoom in. + start_event = MouseEvent( + "button_press_event", fig.canvas, *s0, MouseButton.LEFT) + fig.canvas.callbacks.process(start_event.name, start_event) + stop_event = MouseEvent( + "button_release_event", fig.canvas, *s1, MouseButton.LEFT) + fig.canvas.callbacks.process(stop_event.name, stop_event) + assert ax.get_xlim() == (start_event.xdata, stop_event.xdata) + assert ax.get_ylim() == (start_event.ydata, stop_event.ydata) + + # Zoom out. + start_event = MouseEvent( + "button_press_event", fig.canvas, *s1, MouseButton.RIGHT) + fig.canvas.callbacks.process(start_event.name, start_event) + stop_event = MouseEvent( + "button_release_event", fig.canvas, *s0, MouseButton.RIGHT) + fig.canvas.callbacks.process(stop_event.name, stop_event) + # Absolute tolerance much less than original xmin (1e-7). + assert ax.get_xlim() == pytest.approx(xlim0, rel=0, abs=1e-10) + assert ax.get_ylim() == pytest.approx(ylim0, rel=0, abs=1e-10) + + tb.zoom() + assert ax.get_navigate_mode() is None + + assert not ax.get_autoscalex_on() and not ax.get_autoscaley_on() + + +def test_widgetlock_zoompan(): + fig, ax = plt.subplots() + ax.plot([0, 1], [0, 1]) + fig.canvas.widgetlock(ax) + tb = NavigationToolbar2(fig.canvas) + tb.zoom() + assert ax.get_navigate_mode() is None + tb.pan() + assert ax.get_navigate_mode() is None + + +@pytest.mark.parametrize("plot_func", ["imshow", "contourf"]) +@pytest.mark.parametrize("orientation", ["vertical", "horizontal"]) +@pytest.mark.parametrize("tool,button,expected", + [("zoom", MouseButton.LEFT, (4, 6)), # zoom in + ("zoom", MouseButton.RIGHT, (-20, 30)), # zoom out + ("pan", MouseButton.LEFT, (-2, 8)), + ("pan", MouseButton.RIGHT, (1.47, 7.78))]) # zoom +def test_interactive_colorbar(plot_func, orientation, tool, button, expected): + fig, ax = plt.subplots() + data = np.arange(12).reshape((4, 3)) + vmin0, vmax0 = 0, 10 + coll = getattr(ax, plot_func)(data, vmin=vmin0, vmax=vmax0) + + cb = fig.colorbar(coll, ax=ax, orientation=orientation) + if plot_func == "contourf": + # Just determine we can't navigate and exit out of the test + assert not cb.ax.get_navigate() + return + + assert cb.ax.get_navigate() + + # Mouse from 4 to 6 (data coordinates, "d"). + vmin, vmax = 4, 6 + # The y coordinate doesn't matter, it just needs to be between 0 and 1 + # However, we will set d0/d1 to the same y coordinate to test that small + # pixel changes in that coordinate doesn't cancel the zoom like a normal + # axes would. + d0 = (vmin, 0.5) + d1 = (vmax, 0.5) + # Swap them if the orientation is vertical + if orientation == "vertical": + d0 = d0[::-1] + d1 = d1[::-1] + # Convert to screen coordinates ("s"). Events are defined only with pixel + # precision, so round the pixel values, and below, check against the + # corresponding xdata/ydata, which are close but not equal to d0/d1. + s0 = cb.ax.transData.transform(d0).astype(int) + s1 = cb.ax.transData.transform(d1).astype(int) + + # Set up the mouse movements + start_event = MouseEvent( + "button_press_event", fig.canvas, *s0, button) + stop_event = MouseEvent( + "button_release_event", fig.canvas, *s1, button) + + tb = NavigationToolbar2(fig.canvas) + if tool == "zoom": + tb.zoom() + tb.press_zoom(start_event) + tb.drag_zoom(stop_event) + tb.release_zoom(stop_event) + else: + tb.pan() + tb.press_pan(start_event) + tb.drag_pan(stop_event) + tb.release_pan(stop_event) + + # Should be close, but won't be exact due to screen integer resolution + assert (cb.vmin, cb.vmax) == pytest.approx(expected, abs=0.15) + + +def test_toolbar_zoompan(): + with pytest.warns(UserWarning, match=_EXPECTED_WARNING_TOOLMANAGER): + plt.rcParams['toolbar'] = 'toolmanager' + ax = plt.gca() + assert ax.get_navigate_mode() is None + ax.figure.canvas.manager.toolmanager.trigger_tool('zoom') + assert ax.get_navigate_mode() == "ZOOM" + ax.figure.canvas.manager.toolmanager.trigger_tool('pan') + assert ax.get_navigate_mode() == "PAN" + + +def test_toolbar_home_restores_autoscale(): + fig, ax = plt.subplots() + ax.plot(range(11), range(11)) + + tb = NavigationToolbar2(fig.canvas) + tb.zoom() + + # Switch to log. + KeyEvent("key_press_event", fig.canvas, "k", 100, 100)._process() + KeyEvent("key_press_event", fig.canvas, "l", 100, 100)._process() + assert ax.get_xlim() == ax.get_ylim() == (1, 10) # Autolimits excluding 0. + # Switch back to linear. + KeyEvent("key_press_event", fig.canvas, "k", 100, 100)._process() + KeyEvent("key_press_event", fig.canvas, "l", 100, 100)._process() + assert ax.get_xlim() == ax.get_ylim() == (0, 10) # Autolimits. + + # Zoom in from (x, y) = (2, 2) to (5, 5). + start, stop = ax.transData.transform([(2, 2), (5, 5)]) + MouseEvent("button_press_event", fig.canvas, *start, MouseButton.LEFT)._process() + MouseEvent("button_release_event", fig.canvas, *stop, MouseButton.LEFT)._process() + # Go back to home. + KeyEvent("key_press_event", fig.canvas, "h")._process() + + assert ax.get_xlim() == ax.get_ylim() == (0, 10) + # Switch to log. + KeyEvent("key_press_event", fig.canvas, "k", 100, 100)._process() + KeyEvent("key_press_event", fig.canvas, "l", 100, 100)._process() + assert ax.get_xlim() == ax.get_ylim() == (1, 10) # Autolimits excluding 0. + + +@pytest.mark.parametrize( + "backend", ['svg', 'ps', 'pdf', + pytest.param('pgf', marks=needs_pgf_xelatex)] +) +def test_draw(backend): + from matplotlib.figure import Figure + from matplotlib.backends.backend_agg import FigureCanvas + test_backend = pytest.importorskip( + f'matplotlib.backends.backend_{backend}' + ) + TestCanvas = test_backend.FigureCanvas + fig_test = Figure(constrained_layout=True) + TestCanvas(fig_test) + axes_test = fig_test.subplots(2, 2) + + # defaults to FigureCanvasBase + fig_agg = Figure(constrained_layout=True) + # put a backends.backend_agg.FigureCanvas on it + FigureCanvas(fig_agg) + axes_agg = fig_agg.subplots(2, 2) + + init_pos = [ax.get_position() for ax in axes_test.ravel()] + + fig_test.canvas.draw() + fig_agg.canvas.draw() + + layed_out_pos_test = [ax.get_position() for ax in axes_test.ravel()] + layed_out_pos_agg = [ax.get_position() for ax in axes_agg.ravel()] + + for init, placed in zip(init_pos, layed_out_pos_test): + assert not np.allclose(init, placed, atol=0.005) + + for ref, test in zip(layed_out_pos_agg, layed_out_pos_test): + np.testing.assert_allclose(ref, test, atol=0.005) + + +@pytest.mark.parametrize( + "key,mouseend,expectedxlim,expectedylim", + [(None, (0.2, 0.2), (3.49, 12.49), (2.7, 11.7)), + (None, (0.2, 0.5), (3.49, 12.49), (0, 9)), + (None, (0.5, 0.2), (0, 9), (2.7, 11.7)), + (None, (0.5, 0.5), (0, 9), (0, 9)), # No move + (None, (0.8, 0.25), (-3.47, 5.53), (2.25, 11.25)), + (None, (0.2, 0.25), (3.49, 12.49), (2.25, 11.25)), + (None, (0.8, 0.85), (-3.47, 5.53), (-3.14, 5.86)), + (None, (0.2, 0.85), (3.49, 12.49), (-3.14, 5.86)), + ("shift", (0.2, 0.4), (3.49, 12.49), (0, 9)), # snap to x + ("shift", (0.4, 0.2), (0, 9), (2.7, 11.7)), # snap to y + ("shift", (0.2, 0.25), (3.49, 12.49), (3.49, 12.49)), # snap to diagonal + ("shift", (0.8, 0.25), (-3.47, 5.53), (3.47, 12.47)), # snap to diagonal + ("shift", (0.8, 0.9), (-3.58, 5.41), (-3.58, 5.41)), # snap to diagonal + ("shift", (0.2, 0.85), (3.49, 12.49), (-3.49, 5.51)), # snap to diagonal + ("x", (0.2, 0.1), (3.49, 12.49), (0, 9)), # only x + ("y", (0.1, 0.2), (0, 9), (2.7, 11.7)), # only y + ("control", (0.2, 0.2), (3.49, 12.49), (3.49, 12.49)), # diagonal + ("control", (0.4, 0.2), (2.72, 11.72), (2.72, 11.72)), # diagonal + ]) +def test_interactive_pan(key, mouseend, expectedxlim, expectedylim): + fig, ax = plt.subplots() + ax.plot(np.arange(10)) + assert ax.get_navigate() + # Set equal aspect ratio to easier see diagonal snap + ax.set_aspect('equal') + + # Mouse move starts from 0.5, 0.5 + mousestart = (0.5, 0.5) + # Convert to screen coordinates ("s"). Events are defined only with pixel + # precision, so round the pixel values, and below, check against the + # corresponding xdata/ydata, which are close but not equal to d0/d1. + sstart = ax.transData.transform(mousestart).astype(int) + send = ax.transData.transform(mouseend).astype(int) + + # Set up the mouse movements + start_event = MouseEvent( + "button_press_event", fig.canvas, *sstart, button=MouseButton.LEFT, + key=key) + stop_event = MouseEvent( + "button_release_event", fig.canvas, *send, button=MouseButton.LEFT, + key=key) + + tb = NavigationToolbar2(fig.canvas) + tb.pan() + tb.press_pan(start_event) + tb.drag_pan(stop_event) + tb.release_pan(stop_event) + # Should be close, but won't be exact due to screen integer resolution + assert tuple(ax.get_xlim()) == pytest.approx(expectedxlim, abs=0.02) + assert tuple(ax.get_ylim()) == pytest.approx(expectedylim, abs=0.02) + + +def test_toolmanager_remove(): + with pytest.warns(UserWarning, match=_EXPECTED_WARNING_TOOLMANAGER): + plt.rcParams['toolbar'] = 'toolmanager' + fig = plt.gcf() + initial_len = len(fig.canvas.manager.toolmanager.tools) + assert 'forward' in fig.canvas.manager.toolmanager.tools + fig.canvas.manager.toolmanager.remove_tool('forward') + assert len(fig.canvas.manager.toolmanager.tools) == initial_len - 1 + assert 'forward' not in fig.canvas.manager.toolmanager.tools + + +def test_toolmanager_get_tool(): + with pytest.warns(UserWarning, match=_EXPECTED_WARNING_TOOLMANAGER): + plt.rcParams['toolbar'] = 'toolmanager' + fig = plt.gcf() + rubberband = fig.canvas.manager.toolmanager.get_tool('rubberband') + assert isinstance(rubberband, RubberbandBase) + assert fig.canvas.manager.toolmanager.get_tool(rubberband) is rubberband + with pytest.warns(UserWarning, + match="ToolManager does not control tool 'foo'"): + assert fig.canvas.manager.toolmanager.get_tool('foo') is None + assert fig.canvas.manager.toolmanager.get_tool('foo', warn=False) is None + + with pytest.warns(UserWarning, + match="ToolManager does not control tool 'foo'"): + assert fig.canvas.manager.toolmanager.trigger_tool('foo') is None + + +def test_toolmanager_update_keymap(): + with pytest.warns(UserWarning, match=_EXPECTED_WARNING_TOOLMANAGER): + plt.rcParams['toolbar'] = 'toolmanager' + fig = plt.gcf() + assert 'v' in fig.canvas.manager.toolmanager.get_tool_keymap('forward') + with pytest.warns(UserWarning, + match="Key c changed from back to forward"): + fig.canvas.manager.toolmanager.update_keymap('forward', 'c') + assert fig.canvas.manager.toolmanager.get_tool_keymap('forward') == ['c'] + with pytest.raises(KeyError, match="'foo' not in Tools"): + fig.canvas.manager.toolmanager.update_keymap('foo', 'c') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_cairo.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_cairo.py new file mode 100644 index 00000000..8cc0b319 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_cairo.py @@ -0,0 +1,48 @@ +import numpy as np + +import pytest + +from matplotlib.testing.decorators import check_figures_equal +from matplotlib import ( + collections as mcollections, patches as mpatches, path as mpath) + + +@pytest.mark.backend('cairo') +@check_figures_equal(extensions=["png"]) +def test_patch_alpha_coloring(fig_test, fig_ref): + """ + Test checks that the patch and collection are rendered with the specified + alpha values in their facecolor and edgecolor. + """ + star = mpath.Path.unit_regular_star(6) + circle = mpath.Path.unit_circle() + # concatenate the star with an internal cutout of the circle + verts = np.concatenate([circle.vertices, star.vertices[::-1]]) + codes = np.concatenate([circle.codes, star.codes]) + cut_star1 = mpath.Path(verts, codes) + cut_star2 = mpath.Path(verts + 1, codes) + + # Reference: two separate patches + ax = fig_ref.subplots() + ax.set_xlim([-1, 2]) + ax.set_ylim([-1, 2]) + patch = mpatches.PathPatch(cut_star1, + linewidth=5, linestyle='dashdot', + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_patch(patch) + patch = mpatches.PathPatch(cut_star2, + linewidth=5, linestyle='dashdot', + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_patch(patch) + + # Test: path collection + ax = fig_test.subplots() + ax.set_xlim([-1, 2]) + ax.set_ylim([-1, 2]) + col = mcollections.PathCollection([cut_star1, cut_star2], + linewidth=5, linestyles='dashdot', + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_collection(col) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_gtk3.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_gtk3.py new file mode 100644 index 00000000..6a95f47e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_gtk3.py @@ -0,0 +1,51 @@ +from matplotlib import pyplot as plt + +import pytest + + +pytest.importorskip("matplotlib.backends.backend_gtk3agg") + + +@pytest.mark.backend("gtk3agg", skip_on_importerror=True) +def test_correct_key(): + pytest.xfail("test_widget_send_event is not triggering key_press_event") + + from gi.repository import Gdk, Gtk # type: ignore + fig = plt.figure() + buf = [] + + def send(event): + for key, mod in [ + (Gdk.KEY_a, Gdk.ModifierType.SHIFT_MASK), + (Gdk.KEY_a, 0), + (Gdk.KEY_a, Gdk.ModifierType.CONTROL_MASK), + (Gdk.KEY_agrave, 0), + (Gdk.KEY_Control_L, Gdk.ModifierType.MOD1_MASK), + (Gdk.KEY_Alt_L, Gdk.ModifierType.CONTROL_MASK), + (Gdk.KEY_agrave, + Gdk.ModifierType.CONTROL_MASK + | Gdk.ModifierType.MOD1_MASK + | Gdk.ModifierType.MOD4_MASK), + (0xfd16, 0), # KEY_3270_Play. + (Gdk.KEY_BackSpace, 0), + (Gdk.KEY_BackSpace, Gdk.ModifierType.CONTROL_MASK), + ]: + # This is not actually really the right API: it depends on the + # actual keymap (e.g. on Azerty, shift+agrave -> 0). + Gtk.test_widget_send_key(fig.canvas, key, mod) + + def receive(event): + buf.append(event.key) + if buf == [ + "A", "a", "ctrl+a", + "\N{LATIN SMALL LETTER A WITH GRAVE}", + "alt+control", "ctrl+alt", + "ctrl+alt+super+\N{LATIN SMALL LETTER A WITH GRAVE}", + # (No entry for KEY_3270_Play.) + "backspace", "ctrl+backspace", + ]: + plt.close(fig) + + fig.canvas.mpl_connect("draw_event", send) + fig.canvas.mpl_connect("key_press_event", receive) + plt.show() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_macosx.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_macosx.py new file mode 100644 index 00000000..c460da37 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_macosx.py @@ -0,0 +1,46 @@ +import os + +import pytest + +import matplotlib as mpl +import matplotlib.pyplot as plt +try: + from matplotlib.backends import _macosx +except ImportError: + pytest.skip("These are mac only tests", allow_module_level=True) + + +@pytest.mark.backend('macosx') +def test_cached_renderer(): + # Make sure that figures have an associated renderer after + # a fig.canvas.draw() call + fig = plt.figure(1) + fig.canvas.draw() + assert fig.canvas.get_renderer()._renderer is not None + + fig = plt.figure(2) + fig.draw_without_rendering() + assert fig.canvas.get_renderer()._renderer is not None + + +@pytest.mark.backend('macosx') +def test_savefig_rcparam(monkeypatch, tmp_path): + + def new_choose_save_file(title, directory, filename): + # Replacement function instead of opening a GUI window + # Make a new directory for testing the update of the rcParams + assert directory == str(tmp_path) + os.makedirs(f"{directory}/test") + return f"{directory}/test/{filename}" + + monkeypatch.setattr(_macosx, "choose_save_file", new_choose_save_file) + fig = plt.figure() + with mpl.rc_context({"savefig.directory": tmp_path}): + fig.canvas.toolbar.save_figure() + # Check the saved location got created + save_file = f"{tmp_path}/test/{fig.canvas.get_default_filename()}" + assert os.path.exists(save_file) + + # Check the savefig.directory rcParam got updated because + # we added a subdirectory "test" + assert mpl.rcParams["savefig.directory"] == f"{tmp_path}/test" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_nbagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_nbagg.py new file mode 100644 index 00000000..4ebf3e1f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_nbagg.py @@ -0,0 +1,30 @@ +import os +from pathlib import Path +import subprocess +from tempfile import TemporaryDirectory + +import pytest + +nbformat = pytest.importorskip('nbformat') +pytest.importorskip('nbconvert') +pytest.importorskip('ipykernel') + +# From https://blog.thedataincubator.com/2016/06/testing-jupyter-notebooks/ + + +def test_ipynb(): + nb_path = Path(__file__).parent / 'test_nbagg_01.ipynb' + + with TemporaryDirectory() as tmpdir: + out_path = Path(tmpdir, "out.ipynb") + subprocess.check_call( + ["jupyter", "nbconvert", "--to", "notebook", + "--execute", "--ExecutePreprocessor.timeout=500", + "--output", str(out_path), str(nb_path)], + env={**os.environ, "IPYTHONDIR": tmpdir}) + with out_path.open() as out: + nb = nbformat.read(out, nbformat.current_nbformat) + + errors = [output for cell in nb.cells for output in cell.get("outputs", []) + if output.output_type == "error"] + assert not errors diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pdf.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pdf.py new file mode 100644 index 00000000..68ce02cc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pdf.py @@ -0,0 +1,445 @@ +import datetime +import decimal +import io +import os +from pathlib import Path + +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import ( + pyplot as plt, rcParams, font_manager as fm +) +from matplotlib.cbook import _get_data_path +from matplotlib.ft2font import FT2Font +from matplotlib.font_manager import findfont, FontProperties +from matplotlib.backends._backend_pdf_ps import get_glyphs_subset +from matplotlib.backends.backend_pdf import PdfPages +from matplotlib.patches import Rectangle +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing._markers import needs_usetex + + +@image_comparison(['pdf_use14corefonts.pdf']) +def test_use14corefonts(): + rcParams['pdf.use14corefonts'] = True + rcParams['font.family'] = 'sans-serif' + rcParams['font.size'] = 8 + rcParams['font.sans-serif'] = ['Helvetica'] + rcParams['pdf.compression'] = 0 + + text = '''A three-line text positioned just above a blue line +and containing some French characters and the euro symbol: +"Merci pépé pour les 10 €"''' + + fig, ax = plt.subplots() + ax.set_title('Test PDF backend with option use14corefonts=True') + ax.text(0.5, 0.5, text, horizontalalignment='center', + verticalalignment='bottom', + fontsize=14) + ax.axhline(0.5, linewidth=0.5) + + +@pytest.mark.parametrize('fontname, fontfile', [ + ('DejaVu Sans', 'DejaVuSans.ttf'), + ('WenQuanYi Zen Hei', 'wqy-zenhei.ttc'), +]) +@pytest.mark.parametrize('fonttype', [3, 42]) +def test_embed_fonts(fontname, fontfile, fonttype): + if Path(findfont(FontProperties(family=[fontname]))).name != fontfile: + pytest.skip(f'Font {fontname!r} may be missing') + + rcParams['pdf.fonttype'] = fonttype + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + ax.set_title('Axes Title', font=fontname) + fig.savefig(io.BytesIO(), format='pdf') + + +def test_multipage_pagecount(): + with PdfPages(io.BytesIO()) as pdf: + assert pdf.get_pagecount() == 0 + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + fig.savefig(pdf, format="pdf") + assert pdf.get_pagecount() == 1 + pdf.savefig() + assert pdf.get_pagecount() == 2 + + +def test_multipage_properfinalize(): + pdfio = io.BytesIO() + with PdfPages(pdfio) as pdf: + for i in range(10): + fig, ax = plt.subplots() + ax.set_title('This is a long title') + fig.savefig(pdf, format="pdf") + s = pdfio.getvalue() + assert s.count(b'startxref') == 1 + assert len(s) < 40000 + + +def test_multipage_keep_empty(tmp_path): + os.chdir(tmp_path) + + # test empty pdf files + + # an empty pdf is left behind with keep_empty unset + with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: + pass + assert os.path.exists("a.pdf") + + # an empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("b.pdf", keep_empty=True) as pdf: + pass + assert os.path.exists("b.pdf") + + # an empty pdf deletes itself afterwards with keep_empty=False + with PdfPages("c.pdf", keep_empty=False) as pdf: + pass + assert not os.path.exists("c.pdf") + + # test pdf files with content, they should never be deleted + + # a non-empty pdf is left behind with keep_empty unset + with PdfPages("d.pdf") as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("d.pdf") + + # a non-empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("e.pdf", keep_empty=True) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("e.pdf") + + # a non-empty pdf is left behind with keep_empty=False + with PdfPages("f.pdf", keep_empty=False) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("f.pdf") + + +def test_composite_image(): + # Test that figures can be saved with and without combining multiple images + # (on a single set of axes) into a single composite image. + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + fig, ax = plt.subplots() + ax.set_xlim(0, 3) + ax.imshow(Z, extent=[0, 1, 0, 1]) + ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) + plt.rcParams['image.composite_image'] = True + with PdfPages(io.BytesIO()) as pdf: + fig.savefig(pdf, format="pdf") + assert len(pdf._file._images) == 1 + plt.rcParams['image.composite_image'] = False + with PdfPages(io.BytesIO()) as pdf: + fig.savefig(pdf, format="pdf") + assert len(pdf._file._images) == 2 + + +def test_indexed_image(): + # An image with low color count should compress to a palette-indexed format. + pikepdf = pytest.importorskip('pikepdf') + + data = np.zeros((256, 1, 3), dtype=np.uint8) + data[:, 0, 0] = np.arange(256) # Maximum unique colours for an indexed image. + + rcParams['pdf.compression'] = True + fig = plt.figure() + fig.figimage(data, resize=True) + buf = io.BytesIO() + fig.savefig(buf, format='pdf', dpi='figure') + + with pikepdf.Pdf.open(buf) as pdf: + page, = pdf.pages + image, = page.images.values() + pdf_image = pikepdf.PdfImage(image) + assert pdf_image.indexed + pil_image = pdf_image.as_pil_image() + rgb = np.asarray(pil_image.convert('RGB')) + + np.testing.assert_array_equal(data, rgb) + + +def test_savefig_metadata(monkeypatch): + pikepdf = pytest.importorskip('pikepdf') + monkeypatch.setenv('SOURCE_DATE_EPOCH', '0') + + fig, ax = plt.subplots() + ax.plot(range(5)) + + md = { + 'Author': 'me', + 'Title': 'Multipage PDF', + 'Subject': 'Test page', + 'Keywords': 'test,pdf,multipage', + 'ModDate': datetime.datetime( + 1968, 8, 1, tzinfo=datetime.timezone(datetime.timedelta(0))), + 'Trapped': 'True' + } + buf = io.BytesIO() + fig.savefig(buf, metadata=md, format='pdf') + + with pikepdf.Pdf.open(buf) as pdf: + info = {k: str(v) for k, v in pdf.docinfo.items()} + + assert info == { + '/Author': 'me', + '/CreationDate': 'D:19700101000000Z', + '/Creator': f'Matplotlib v{mpl.__version__}, https://matplotlib.org', + '/Keywords': 'test,pdf,multipage', + '/ModDate': 'D:19680801000000Z', + '/Producer': f'Matplotlib pdf backend v{mpl.__version__}', + '/Subject': 'Test page', + '/Title': 'Multipage PDF', + '/Trapped': '/True', + } + + +def test_invalid_metadata(): + fig, ax = plt.subplots() + + with pytest.warns(UserWarning, + match="Unknown infodict keyword: 'foobar'."): + fig.savefig(io.BytesIO(), format='pdf', metadata={'foobar': 'invalid'}) + + with pytest.warns(UserWarning, + match='not an instance of datetime.datetime.'): + fig.savefig(io.BytesIO(), format='pdf', + metadata={'ModDate': '1968-08-01'}) + + with pytest.warns(UserWarning, + match='not one of {"True", "False", "Unknown"}'): + fig.savefig(io.BytesIO(), format='pdf', metadata={'Trapped': 'foo'}) + + with pytest.warns(UserWarning, match='not an instance of str.'): + fig.savefig(io.BytesIO(), format='pdf', metadata={'Title': 1234}) + + +def test_multipage_metadata(monkeypatch): + pikepdf = pytest.importorskip('pikepdf') + monkeypatch.setenv('SOURCE_DATE_EPOCH', '0') + + fig, ax = plt.subplots() + ax.plot(range(5)) + + md = { + 'Author': 'me', + 'Title': 'Multipage PDF', + 'Subject': 'Test page', + 'Keywords': 'test,pdf,multipage', + 'ModDate': datetime.datetime( + 1968, 8, 1, tzinfo=datetime.timezone(datetime.timedelta(0))), + 'Trapped': 'True' + } + buf = io.BytesIO() + with PdfPages(buf, metadata=md) as pdf: + pdf.savefig(fig) + pdf.savefig(fig) + + with pikepdf.Pdf.open(buf) as pdf: + info = {k: str(v) for k, v in pdf.docinfo.items()} + + assert info == { + '/Author': 'me', + '/CreationDate': 'D:19700101000000Z', + '/Creator': f'Matplotlib v{mpl.__version__}, https://matplotlib.org', + '/Keywords': 'test,pdf,multipage', + '/ModDate': 'D:19680801000000Z', + '/Producer': f'Matplotlib pdf backend v{mpl.__version__}', + '/Subject': 'Test page', + '/Title': 'Multipage PDF', + '/Trapped': '/True', + } + + +def test_text_urls(): + pikepdf = pytest.importorskip('pikepdf') + + test_url = 'https://test_text_urls.matplotlib.org/' + + fig = plt.figure(figsize=(2, 1)) + fig.text(0.1, 0.1, 'test plain 123', url=f'{test_url}plain') + fig.text(0.1, 0.4, 'test mathtext $123$', url=f'{test_url}mathtext') + + with io.BytesIO() as fd: + fig.savefig(fd, format='pdf') + + with pikepdf.Pdf.open(fd) as pdf: + annots = pdf.pages[0].Annots + + # Iteration over Annots must occur within the context manager, + # otherwise it may fail depending on the pdf structure. + for y, fragment in [('0.1', 'plain'), ('0.4', 'mathtext')]: + annot = next( + (a for a in annots if a.A.URI == f'{test_url}{fragment}'), + None) + assert annot is not None + assert getattr(annot, 'QuadPoints', None) is None + # Positions in points (72 per inch.) + assert annot.Rect[1] == decimal.Decimal(y) * 72 + + +def test_text_rotated_urls(): + pikepdf = pytest.importorskip('pikepdf') + + test_url = 'https://test_text_urls.matplotlib.org/' + + fig = plt.figure(figsize=(1, 1)) + fig.text(0.1, 0.1, 'N', rotation=45, url=f'{test_url}') + + with io.BytesIO() as fd: + fig.savefig(fd, format='pdf') + + with pikepdf.Pdf.open(fd) as pdf: + annots = pdf.pages[0].Annots + + # Iteration over Annots must occur within the context manager, + # otherwise it may fail depending on the pdf structure. + annot = next( + (a for a in annots if a.A.URI == f'{test_url}'), + None) + assert annot is not None + assert getattr(annot, 'QuadPoints', None) is not None + # Positions in points (72 per inch) + assert annot.Rect[0] == \ + annot.QuadPoints[6] - decimal.Decimal('0.00001') + + +@needs_usetex +def test_text_urls_tex(): + pikepdf = pytest.importorskip('pikepdf') + + test_url = 'https://test_text_urls.matplotlib.org/' + + fig = plt.figure(figsize=(2, 1)) + fig.text(0.1, 0.7, 'test tex $123$', usetex=True, url=f'{test_url}tex') + + with io.BytesIO() as fd: + fig.savefig(fd, format='pdf') + + with pikepdf.Pdf.open(fd) as pdf: + annots = pdf.pages[0].Annots + + # Iteration over Annots must occur within the context manager, + # otherwise it may fail depending on the pdf structure. + annot = next( + (a for a in annots if a.A.URI == f'{test_url}tex'), + None) + assert annot is not None + # Positions in points (72 per inch.) + assert annot.Rect[1] == decimal.Decimal('0.7') * 72 + + +def test_pdfpages_fspath(): + with PdfPages(Path(os.devnull)) as pdf: + pdf.savefig(plt.figure()) + + +@image_comparison(['hatching_legend.pdf']) +def test_hatching_legend(): + """Test for correct hatching on patches in legend""" + fig = plt.figure(figsize=(1, 2)) + + a = Rectangle([0, 0], 0, 0, facecolor="green", hatch="XXXX") + b = Rectangle([0, 0], 0, 0, facecolor="blue", hatch="XXXX") + + fig.legend([a, b, a, b], ["", "", "", ""]) + + +@image_comparison(['grayscale_alpha.pdf']) +def test_grayscale_alpha(): + """Masking images with NaN did not work for grayscale images""" + x, y = np.ogrid[-2:2:.1, -2:2:.1] + dd = np.exp(-(x**2 + y**2)) + dd[dd < .1] = np.nan + fig, ax = plt.subplots() + ax.imshow(dd, interpolation='none', cmap='gray_r') + ax.set_xticks([]) + ax.set_yticks([]) + + +@mpl.style.context('default') +@check_figures_equal(extensions=["pdf", "eps"]) +def test_pdf_eps_savefig_when_color_is_none(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_test.set_axis_off() + ax_test.plot(np.sin(np.linspace(-5, 5, 100)), "v", c="none") + ax_ref = fig_ref.add_subplot() + ax_ref.set_axis_off() + + +@needs_usetex +def test_failing_latex(): + """Test failing latex subprocess call""" + plt.xlabel("$22_2_2$", usetex=True) # This fails with "Double subscript" + with pytest.raises(RuntimeError): + plt.savefig(io.BytesIO(), format="pdf") + + +def test_empty_rasterized(): + # Check that empty figures that are rasterised save to pdf files fine + fig, ax = plt.subplots() + ax.plot([], [], rasterized=True) + fig.savefig(io.BytesIO(), format="pdf") + + +@image_comparison(['kerning.pdf']) +def test_kerning(): + fig = plt.figure() + s = "AVAVAVAVAVAVAVAV€AAVV" + fig.text(0, .25, s, size=5) + fig.text(0, .75, s, size=20) + + +def test_glyphs_subset(): + fpath = str(_get_data_path("fonts/ttf/DejaVuSerif.ttf")) + chars = "these should be subsetted! 1234567890" + + # non-subsetted FT2Font + nosubfont = FT2Font(fpath) + nosubfont.set_text(chars) + + # subsetted FT2Font + subfont = FT2Font(get_glyphs_subset(fpath, chars)) + subfont.set_text(chars) + + nosubcmap = nosubfont.get_charmap() + subcmap = subfont.get_charmap() + + # all unique chars must be available in subsetted font + assert {*chars} == {chr(key) for key in subcmap} + + # subsetted font's charmap should have less entries + assert len(subcmap) < len(nosubcmap) + + # since both objects are assigned same characters + assert subfont.get_num_glyphs() == nosubfont.get_num_glyphs() + + +@image_comparison(["multi_font_type3.pdf"], tol=4.6) +def test_multi_font_type3(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + plt.rc('pdf', fonttype=3) + + fig = plt.figure() + fig.text(0.15, 0.475, "There are 几个汉字 in between!") + + +@image_comparison(["multi_font_type42.pdf"], tol=2.2) +def test_multi_font_type42(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + plt.rc('pdf', fonttype=42) + + fig = plt.figure() + fig.text(0.15, 0.475, "There are 几个汉字 in between!") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pgf.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pgf.py new file mode 100644 index 00000000..a866916c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_pgf.py @@ -0,0 +1,404 @@ +import datetime +from io import BytesIO +import os +import shutil + +import numpy as np +from packaging.version import parse as parse_version +import pytest + +import matplotlib as mpl +import matplotlib.pyplot as plt +from matplotlib.testing import _has_tex_package, _check_for_pgf +from matplotlib.testing.exceptions import ImageComparisonFailure +from matplotlib.testing.compare import compare_images +from matplotlib.backends.backend_pgf import PdfPages +from matplotlib.testing.decorators import ( + _image_directories, check_figures_equal, image_comparison) +from matplotlib.testing._markers import ( + needs_ghostscript, needs_pgf_lualatex, needs_pgf_pdflatex, + needs_pgf_xelatex) + + +baseline_dir, result_dir = _image_directories(lambda: 'dummy func') + + +def compare_figure(fname, savefig_kwargs={}, tol=0): + actual = os.path.join(result_dir, fname) + plt.savefig(actual, **savefig_kwargs) + + expected = os.path.join(result_dir, "expected_%s" % fname) + shutil.copyfile(os.path.join(baseline_dir, fname), expected) + err = compare_images(expected, actual, tol=tol) + if err: + raise ImageComparisonFailure(err) + + +@needs_pgf_xelatex +@needs_ghostscript +@pytest.mark.backend('pgf') +def test_tex_special_chars(tmp_path): + fig = plt.figure() + fig.text(.5, .5, "%_^ $a_b^c$") + buf = BytesIO() + fig.savefig(buf, format="png", backend="pgf") + buf.seek(0) + t = plt.imread(buf) + assert not (t == 1).all() # The leading "%" didn't eat up everything. + + +def create_figure(): + plt.figure() + x = np.linspace(0, 1, 15) + + # line plot + plt.plot(x, x ** 2, "b-") + + # marker + plt.plot(x, 1 - x**2, "g>") + + # filled paths and patterns + plt.fill_between([0., .4], [.4, 0.], hatch='//', facecolor="lightgray", + edgecolor="red") + plt.fill([3, 3, .8, .8, 3], [2, -2, -2, 0, 2], "b") + + # text and typesetting + plt.plot([0.9], [0.5], "ro", markersize=3) + plt.text(0.9, 0.5, 'unicode (ü, °, \N{Section Sign}) and math ($\\mu_i = x_i^2$)', + ha='right', fontsize=20) + plt.ylabel('sans-serif, blue, $\\frac{\\sqrt{x}}{y^2}$..', + family='sans-serif', color='blue') + plt.text(1, 1, 'should be clipped as default clip_box is Axes bbox', + fontsize=20, clip_on=True) + + plt.xlim(0, 1) + plt.ylim(0, 1) + + +# test compiling a figure to pdf with xelatex +@needs_pgf_xelatex +@pytest.mark.backend('pgf') +@image_comparison(['pgf_xelatex.pdf'], style='default') +def test_xelatex(): + rc_xelatex = {'font.family': 'serif', + 'pgf.rcfonts': False} + mpl.rcParams.update(rc_xelatex) + create_figure() + + +try: + _old_gs_version = \ + mpl._get_executable_info('gs').version < parse_version('9.50') +except mpl.ExecutableNotFoundError: + _old_gs_version = True + + +# test compiling a figure to pdf with pdflatex +@needs_pgf_pdflatex +@pytest.mark.skipif(not _has_tex_package('type1ec'), reason='needs type1ec.sty') +@pytest.mark.skipif(not _has_tex_package('ucs'), reason='needs ucs.sty') +@pytest.mark.backend('pgf') +@image_comparison(['pgf_pdflatex.pdf'], style='default', + tol=11.71 if _old_gs_version else 0) +def test_pdflatex(): + rc_pdflatex = {'font.family': 'serif', + 'pgf.rcfonts': False, + 'pgf.texsystem': 'pdflatex', + 'pgf.preamble': ('\\usepackage[utf8x]{inputenc}' + '\\usepackage[T1]{fontenc}')} + mpl.rcParams.update(rc_pdflatex) + create_figure() + + +# test updating the rc parameters for each figure +@needs_pgf_xelatex +@needs_pgf_pdflatex +@mpl.style.context('default') +@pytest.mark.backend('pgf') +def test_rcupdate(): + rc_sets = [{'font.family': 'sans-serif', + 'font.size': 30, + 'figure.subplot.left': .2, + 'lines.markersize': 10, + 'pgf.rcfonts': False, + 'pgf.texsystem': 'xelatex'}, + {'font.family': 'monospace', + 'font.size': 10, + 'figure.subplot.left': .1, + 'lines.markersize': 20, + 'pgf.rcfonts': False, + 'pgf.texsystem': 'pdflatex', + 'pgf.preamble': ('\\usepackage[utf8x]{inputenc}' + '\\usepackage[T1]{fontenc}' + '\\usepackage{sfmath}')}] + tol = [0, 13.2] if _old_gs_version else [0, 0] + for i, rc_set in enumerate(rc_sets): + with mpl.rc_context(rc_set): + for substring, pkg in [('sfmath', 'sfmath'), ('utf8x', 'ucs')]: + if (substring in mpl.rcParams['pgf.preamble'] + and not _has_tex_package(pkg)): + pytest.skip(f'needs {pkg}.sty') + create_figure() + compare_figure(f'pgf_rcupdate{i + 1}.pdf', tol=tol[i]) + + +# test backend-side clipping, since large numbers are not supported by TeX +@needs_pgf_xelatex +@mpl.style.context('default') +@pytest.mark.backend('pgf') +def test_pathclip(): + np.random.seed(19680801) + mpl.rcParams.update({'font.family': 'serif', 'pgf.rcfonts': False}) + fig, axs = plt.subplots(1, 2) + + axs[0].plot([0., 1e100], [0., 1e100]) + axs[0].set_xlim(0, 1) + axs[0].set_ylim(0, 1) + + axs[1].scatter([0, 1], [1, 1]) + axs[1].hist(np.random.normal(size=1000), bins=20, range=[-10, 10]) + axs[1].set_xscale('log') + + fig.savefig(BytesIO(), format="pdf") # No image comparison. + + +# test mixed mode rendering +@needs_pgf_xelatex +@pytest.mark.backend('pgf') +@image_comparison(['pgf_mixedmode.pdf'], style='default') +def test_mixedmode(): + mpl.rcParams.update({'font.family': 'serif', 'pgf.rcfonts': False}) + Y, X = np.ogrid[-1:1:40j, -1:1:40j] + plt.pcolor(X**2 + Y**2).set_rasterized(True) + + +# test bbox_inches clipping +@needs_pgf_xelatex +@mpl.style.context('default') +@pytest.mark.backend('pgf') +def test_bbox_inches(): + mpl.rcParams.update({'font.family': 'serif', 'pgf.rcfonts': False}) + fig, (ax1, ax2) = plt.subplots(1, 2) + ax1.plot(range(5)) + ax2.plot(range(5)) + plt.tight_layout() + bbox = ax1.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) + compare_figure('pgf_bbox_inches.pdf', savefig_kwargs={'bbox_inches': bbox}, + tol=0) + + +@mpl.style.context('default') +@pytest.mark.backend('pgf') +@pytest.mark.parametrize('system', [ + pytest.param('lualatex', marks=[needs_pgf_lualatex]), + pytest.param('pdflatex', marks=[needs_pgf_pdflatex]), + pytest.param('xelatex', marks=[needs_pgf_xelatex]), +]) +def test_pdf_pages(system): + rc_pdflatex = { + 'font.family': 'serif', + 'pgf.rcfonts': False, + 'pgf.texsystem': system, + } + mpl.rcParams.update(rc_pdflatex) + + fig1, ax1 = plt.subplots() + ax1.plot(range(5)) + fig1.tight_layout() + + fig2, ax2 = plt.subplots(figsize=(3, 2)) + ax2.plot(range(5)) + fig2.tight_layout() + + path = os.path.join(result_dir, f'pdfpages_{system}.pdf') + md = { + 'Author': 'me', + 'Title': 'Multipage PDF with pgf', + 'Subject': 'Test page', + 'Keywords': 'test,pdf,multipage', + 'ModDate': datetime.datetime( + 1968, 8, 1, tzinfo=datetime.timezone(datetime.timedelta(0))), + 'Trapped': 'Unknown' + } + + with PdfPages(path, metadata=md) as pdf: + pdf.savefig(fig1) + pdf.savefig(fig2) + pdf.savefig(fig1) + + assert pdf.get_pagecount() == 3 + + +@mpl.style.context('default') +@pytest.mark.backend('pgf') +@pytest.mark.parametrize('system', [ + pytest.param('lualatex', marks=[needs_pgf_lualatex]), + pytest.param('pdflatex', marks=[needs_pgf_pdflatex]), + pytest.param('xelatex', marks=[needs_pgf_xelatex]), +]) +def test_pdf_pages_metadata_check(monkeypatch, system): + # Basically the same as test_pdf_pages, but we keep it separate to leave + # pikepdf as an optional dependency. + pikepdf = pytest.importorskip('pikepdf') + monkeypatch.setenv('SOURCE_DATE_EPOCH', '0') + + mpl.rcParams.update({'pgf.texsystem': system}) + + fig, ax = plt.subplots() + ax.plot(range(5)) + + md = { + 'Author': 'me', + 'Title': 'Multipage PDF with pgf', + 'Subject': 'Test page', + 'Keywords': 'test,pdf,multipage', + 'ModDate': datetime.datetime( + 1968, 8, 1, tzinfo=datetime.timezone(datetime.timedelta(0))), + 'Trapped': 'True' + } + path = os.path.join(result_dir, f'pdfpages_meta_check_{system}.pdf') + with PdfPages(path, metadata=md) as pdf: + pdf.savefig(fig) + + with pikepdf.Pdf.open(path) as pdf: + info = {k: str(v) for k, v in pdf.docinfo.items()} + + # Not set by us, so don't bother checking. + if '/PTEX.FullBanner' in info: + del info['/PTEX.FullBanner'] + if '/PTEX.Fullbanner' in info: + del info['/PTEX.Fullbanner'] + + # Some LaTeX engines ignore this setting, and state themselves as producer. + producer = info.pop('/Producer') + assert producer == f'Matplotlib pgf backend v{mpl.__version__}' or ( + system == 'lualatex' and 'LuaTeX' in producer) + + assert info == { + '/Author': 'me', + '/CreationDate': 'D:19700101000000Z', + '/Creator': f'Matplotlib v{mpl.__version__}, https://matplotlib.org', + '/Keywords': 'test,pdf,multipage', + '/ModDate': 'D:19680801000000Z', + '/Subject': 'Test page', + '/Title': 'Multipage PDF with pgf', + '/Trapped': '/True', + } + + +@needs_pgf_xelatex +def test_multipage_keep_empty(tmp_path): + os.chdir(tmp_path) + + # test empty pdf files + + # an empty pdf is left behind with keep_empty unset + with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: + pass + assert os.path.exists("a.pdf") + + # an empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("b.pdf", keep_empty=True) as pdf: + pass + assert os.path.exists("b.pdf") + + # an empty pdf deletes itself afterwards with keep_empty=False + with PdfPages("c.pdf", keep_empty=False) as pdf: + pass + assert not os.path.exists("c.pdf") + + # test pdf files with content, they should never be deleted + + # a non-empty pdf is left behind with keep_empty unset + with PdfPages("d.pdf") as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("d.pdf") + + # a non-empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("e.pdf", keep_empty=True) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("e.pdf") + + # a non-empty pdf is left behind with keep_empty=False + with PdfPages("f.pdf", keep_empty=False) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("f.pdf") + + +@needs_pgf_xelatex +def test_tex_restart_after_error(): + fig = plt.figure() + fig.suptitle(r"\oops") + with pytest.raises(ValueError): + fig.savefig(BytesIO(), format="pgf") + + fig = plt.figure() # start from scratch + fig.suptitle(r"this is ok") + fig.savefig(BytesIO(), format="pgf") + + +@needs_pgf_xelatex +def test_bbox_inches_tight(): + fig, ax = plt.subplots() + ax.imshow([[0, 1], [2, 3]]) + fig.savefig(BytesIO(), format="pdf", backend="pgf", bbox_inches="tight") + + +@needs_pgf_xelatex +@needs_ghostscript +def test_png_transparency(): # Actually, also just testing that png works. + buf = BytesIO() + plt.figure().savefig(buf, format="png", backend="pgf", transparent=True) + buf.seek(0) + t = plt.imread(buf) + assert (t[..., 3] == 0).all() # fully transparent. + + +@needs_pgf_xelatex +def test_unknown_font(caplog): + with caplog.at_level("WARNING"): + mpl.rcParams["font.family"] = "this-font-does-not-exist" + plt.figtext(.5, .5, "hello, world") + plt.savefig(BytesIO(), format="pgf") + assert "Ignoring unknown font: this-font-does-not-exist" in [ + r.getMessage() for r in caplog.records] + + +@check_figures_equal(extensions=["pdf"]) +@pytest.mark.parametrize("texsystem", ("pdflatex", "xelatex", "lualatex")) +@pytest.mark.backend("pgf") +def test_minus_signs_with_tex(fig_test, fig_ref, texsystem): + if not _check_for_pgf(texsystem): + pytest.skip(texsystem + ' + pgf is required') + mpl.rcParams["pgf.texsystem"] = texsystem + fig_test.text(.5, .5, "$-1$") + fig_ref.text(.5, .5, "$\N{MINUS SIGN}1$") + + +@pytest.mark.backend("pgf") +def test_sketch_params(): + fig, ax = plt.subplots(figsize=(3, 3)) + ax.set_xticks([]) + ax.set_yticks([]) + ax.set_frame_on(False) + handle, = ax.plot([0, 1]) + handle.set_sketch_params(scale=5, length=30, randomness=42) + + with BytesIO() as fd: + fig.savefig(fd, format='pgf') + buf = fd.getvalue().decode() + + baseline = r"""\pgfpathmoveto{\pgfqpoint{0.375000in}{0.300000in}}% +\pgfpathlineto{\pgfqpoint{2.700000in}{2.700000in}}% +\usepgfmodule{decorations}% +\usepgflibrary{decorations.pathmorphing}% +\pgfkeys{/pgf/decoration/.cd, """ \ + r"""segment length = 0.150000in, amplitude = 0.100000in}% +\pgfmathsetseed{42}% +\pgfdecoratecurrentpath{random steps}% +\pgfusepath{stroke}%""" + # \pgfdecoratecurrentpath must be after the path definition and before the + # path is used (\pgfusepath) + assert baseline in buf diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_ps.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_ps.py new file mode 100644 index 00000000..cbf33ccc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_ps.py @@ -0,0 +1,380 @@ +from collections import Counter +from pathlib import Path +import io +import re +import tempfile + +import numpy as np +import pytest + +from matplotlib import cbook, path, patheffects, font_manager as fm +from matplotlib.figure import Figure +from matplotlib.patches import Ellipse +from matplotlib.testing._markers import needs_ghostscript, needs_usetex +from matplotlib.testing.decorators import check_figures_equal, image_comparison +import matplotlib as mpl +import matplotlib.collections as mcollections +import matplotlib.colors as mcolors +import matplotlib.pyplot as plt + + +# This tests tends to hit a TeX cache lock on AppVeyor. +@pytest.mark.flaky(reruns=3) +@pytest.mark.parametrize('papersize', ['letter', 'figure']) +@pytest.mark.parametrize('orientation', ['portrait', 'landscape']) +@pytest.mark.parametrize('format, use_log, rcParams', [ + ('ps', False, {}), + ('ps', False, {'ps.usedistiller': 'ghostscript'}), + ('ps', False, {'ps.usedistiller': 'xpdf'}), + ('ps', False, {'text.usetex': True}), + ('eps', False, {}), + ('eps', True, {'ps.useafm': True}), + ('eps', False, {'text.usetex': True}), +], ids=[ + 'ps', + 'ps with distiller=ghostscript', + 'ps with distiller=xpdf', + 'ps with usetex', + 'eps', + 'eps afm', + 'eps with usetex' +]) +def test_savefig_to_stringio(format, use_log, rcParams, orientation, papersize): + mpl.rcParams.update(rcParams) + if mpl.rcParams["ps.usedistiller"] == "ghostscript": + try: + mpl._get_executable_info("gs") + except mpl.ExecutableNotFoundError as exc: + pytest.skip(str(exc)) + elif mpl.rcParams["ps.usedistiller"] == "xpdf": + try: + mpl._get_executable_info("gs") # Effectively checks for ps2pdf. + mpl._get_executable_info("pdftops") + except mpl.ExecutableNotFoundError as exc: + pytest.skip(str(exc)) + + fig, ax = plt.subplots() + + with io.StringIO() as s_buf, io.BytesIO() as b_buf: + + if use_log: + ax.set_yscale('log') + + ax.plot([1, 2], [1, 2]) + title = "Déjà vu" + if not mpl.rcParams["text.usetex"]: + title += " \N{MINUS SIGN}\N{EURO SIGN}" + ax.set_title(title) + allowable_exceptions = [] + if mpl.rcParams["text.usetex"]: + allowable_exceptions.append(RuntimeError) + if mpl.rcParams["ps.useafm"]: + allowable_exceptions.append(mpl.MatplotlibDeprecationWarning) + try: + fig.savefig(s_buf, format=format, orientation=orientation, + papertype=papersize) + fig.savefig(b_buf, format=format, orientation=orientation, + papertype=papersize) + except tuple(allowable_exceptions) as exc: + pytest.skip(str(exc)) + + assert not s_buf.closed + assert not b_buf.closed + s_val = s_buf.getvalue().encode('ascii') + b_val = b_buf.getvalue() + + if format == 'ps': + # Default figsize = (8, 6) inches = (576, 432) points = (203.2, 152.4) mm. + # Landscape orientation will swap dimensions. + if mpl.rcParams["ps.usedistiller"] == "xpdf": + # Some versions specifically show letter/203x152, but not all, + # so we can only use this simpler test. + if papersize == 'figure': + assert b'letter' not in s_val.lower() + else: + assert b'letter' in s_val.lower() + elif mpl.rcParams["ps.usedistiller"] or mpl.rcParams["text.usetex"]: + width = b'432.0' if orientation == 'landscape' else b'576.0' + wanted = (b'-dDEVICEWIDTHPOINTS=' + width if papersize == 'figure' + else b'-sPAPERSIZE') + assert wanted in s_val + else: + if papersize == 'figure': + assert b'%%DocumentPaperSizes' not in s_val + else: + assert b'%%DocumentPaperSizes' in s_val + + # Strip out CreationDate: ghostscript and cairo don't obey + # SOURCE_DATE_EPOCH, and that environment variable is already tested in + # test_determinism. + s_val = re.sub(b"(?<=\n%%CreationDate: ).*", b"", s_val) + b_val = re.sub(b"(?<=\n%%CreationDate: ).*", b"", b_val) + + assert s_val == b_val.replace(b'\r\n', b'\n') + + +def test_patheffects(): + mpl.rcParams['path.effects'] = [ + patheffects.withStroke(linewidth=4, foreground='w')] + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + with io.BytesIO() as ps: + fig.savefig(ps, format='ps') + + +@needs_usetex +@needs_ghostscript +def test_tilde_in_tempfilename(tmpdir): + # Tilde ~ in the tempdir path (e.g. TMPDIR, TMP or TEMP on windows + # when the username is very long and windows uses a short name) breaks + # latex before https://github.com/matplotlib/matplotlib/pull/5928 + base_tempdir = Path(tmpdir, "short-1") + base_tempdir.mkdir() + # Change the path for new tempdirs, which is used internally by the ps + # backend to write a file. + with cbook._setattr_cm(tempfile, tempdir=str(base_tempdir)): + # usetex results in the latex call, which does not like the ~ + mpl.rcParams['text.usetex'] = True + plt.plot([1, 2, 3, 4]) + plt.xlabel(r'\textbf{time} (s)') + # use the PS backend to write the file... + plt.savefig(base_tempdir / 'tex_demo.eps', format="ps") + + +@image_comparison(["empty.eps"]) +def test_transparency(): + fig, ax = plt.subplots() + ax.set_axis_off() + ax.plot([0, 1], color="r", alpha=0) + ax.text(.5, .5, "foo", color="r", alpha=0) + + +@needs_usetex +@image_comparison(["empty.eps"]) +def test_transparency_tex(): + mpl.rcParams['text.usetex'] = True + fig, ax = plt.subplots() + ax.set_axis_off() + ax.plot([0, 1], color="r", alpha=0) + ax.text(.5, .5, "foo", color="r", alpha=0) + + +def test_bbox(): + fig, ax = plt.subplots() + with io.BytesIO() as buf: + fig.savefig(buf, format='eps') + buf = buf.getvalue() + + bb = re.search(b'^%%BoundingBox: (.+) (.+) (.+) (.+)$', buf, re.MULTILINE) + assert bb + hibb = re.search(b'^%%HiResBoundingBox: (.+) (.+) (.+) (.+)$', buf, + re.MULTILINE) + assert hibb + + for i in range(1, 5): + # BoundingBox must use integers, and be ceil/floor of the hi res. + assert b'.' not in bb.group(i) + assert int(bb.group(i)) == pytest.approx(float(hibb.group(i)), 1) + + +@needs_usetex +def test_failing_latex(): + """Test failing latex subprocess call""" + mpl.rcParams['text.usetex'] = True + # This fails with "Double subscript" + plt.xlabel("$22_2_2$") + with pytest.raises(RuntimeError): + plt.savefig(io.BytesIO(), format="ps") + + +@needs_usetex +def test_partial_usetex(caplog): + caplog.set_level("WARNING") + plt.figtext(.1, .1, "foo", usetex=True) + plt.figtext(.2, .2, "bar", usetex=True) + plt.savefig(io.BytesIO(), format="ps") + record, = caplog.records # asserts there's a single record. + assert "as if usetex=False" in record.getMessage() + + +@needs_usetex +def test_usetex_preamble(caplog): + mpl.rcParams.update({ + "text.usetex": True, + # Check that these don't conflict with the packages loaded by default. + "text.latex.preamble": r"\usepackage{color,graphicx,textcomp}", + }) + plt.figtext(.5, .5, "foo") + plt.savefig(io.BytesIO(), format="ps") + + +@image_comparison(["useafm.eps"]) +def test_useafm(): + mpl.rcParams["ps.useafm"] = True + fig, ax = plt.subplots() + ax.set_axis_off() + ax.axhline(.5) + ax.text(.5, .5, "qk") + + +@image_comparison(["type3.eps"]) +def test_type3_font(): + plt.figtext(.5, .5, "I/J") + + +@image_comparison(["coloredhatcheszerolw.eps"]) +def test_colored_hatch_zero_linewidth(): + ax = plt.gca() + ax.add_patch(Ellipse((0, 0), 1, 1, hatch='/', facecolor='none', + edgecolor='r', linewidth=0)) + ax.add_patch(Ellipse((0.5, 0.5), 0.5, 0.5, hatch='+', facecolor='none', + edgecolor='g', linewidth=0.2)) + ax.add_patch(Ellipse((1, 1), 0.3, 0.8, hatch='\\', facecolor='none', + edgecolor='b', linewidth=0)) + ax.set_axis_off() + + +@check_figures_equal(extensions=["eps"]) +def test_text_clip(fig_test, fig_ref): + ax = fig_test.add_subplot() + # Fully clipped-out text should not appear. + ax.text(0, 0, "hello", transform=fig_test.transFigure, clip_on=True) + fig_ref.add_subplot() + + +@needs_ghostscript +def test_d_glyph(tmp_path): + # Ensure that we don't have a procedure defined as /d, which would be + # overwritten by the glyph definition for "d". + fig = plt.figure() + fig.text(.5, .5, "def") + out = tmp_path / "test.eps" + fig.savefig(out) + mpl.testing.compare.convert(out, cache=False) # Should not raise. + + +@image_comparison(["type42_without_prep.eps"], style='mpl20') +def test_type42_font_without_prep(): + # Test whether Type 42 fonts without prep table are properly embedded + mpl.rcParams["ps.fonttype"] = 42 + mpl.rcParams["mathtext.fontset"] = "stix" + + plt.figtext(0.5, 0.5, "Mass $m$") + + +@pytest.mark.parametrize('fonttype', ["3", "42"]) +def test_fonttype(fonttype): + mpl.rcParams["ps.fonttype"] = fonttype + fig, ax = plt.subplots() + + ax.text(0.25, 0.5, "Forty-two is the answer to everything!") + + buf = io.BytesIO() + fig.savefig(buf, format="ps") + + test = b'/FontType ' + bytes(f"{fonttype}", encoding='utf-8') + b' def' + + assert re.search(test, buf.getvalue(), re.MULTILINE) + + +def test_linedash(): + """Test that dashed lines do not break PS output""" + fig, ax = plt.subplots() + + ax.plot([0, 1], linestyle="--") + + buf = io.BytesIO() + fig.savefig(buf, format="ps") + + assert buf.tell() > 0 + + +def test_empty_line(): + # Smoke-test for gh#23954 + figure = Figure() + figure.text(0.5, 0.5, "\nfoo\n\n") + buf = io.BytesIO() + figure.savefig(buf, format='eps') + figure.savefig(buf, format='ps') + + +def test_no_duplicate_definition(): + + fig = Figure() + axs = fig.subplots(4, 4, subplot_kw=dict(projection="polar")) + for ax in axs.flat: + ax.set(xticks=[], yticks=[]) + ax.plot([1, 2]) + fig.suptitle("hello, world") + + buf = io.StringIO() + fig.savefig(buf, format='eps') + buf.seek(0) + + wds = [ln.partition(' ')[0] for + ln in buf.readlines() + if ln.startswith('/')] + + assert max(Counter(wds).values()) == 1 + + +@image_comparison(["multi_font_type3.eps"], tol=0.51) +def test_multi_font_type3(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + plt.rc('ps', fonttype=3) + + fig = plt.figure() + fig.text(0.15, 0.475, "There are 几个汉字 in between!") + + +@image_comparison(["multi_font_type42.eps"], tol=1.6) +def test_multi_font_type42(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + plt.rc('ps', fonttype=42) + + fig = plt.figure() + fig.text(0.15, 0.475, "There are 几个汉字 in between!") + + +@image_comparison(["scatter.eps"]) +def test_path_collection(): + rng = np.random.default_rng(19680801) + xvals = rng.uniform(0, 1, 10) + yvals = rng.uniform(0, 1, 10) + sizes = rng.uniform(30, 100, 10) + fig, ax = plt.subplots() + ax.scatter(xvals, yvals, sizes, edgecolor=[0.9, 0.2, 0.1], marker='<') + ax.set_axis_off() + paths = [path.Path.unit_regular_polygon(i) for i in range(3, 7)] + offsets = rng.uniform(0, 200, 20).reshape(10, 2) + sizes = [0.02, 0.04] + pc = mcollections.PathCollection(paths, sizes, zorder=-1, + facecolors='yellow', offsets=offsets) + ax.add_collection(pc) + ax.set_xlim(0, 1) + + +@image_comparison(["colorbar_shift.eps"], savefig_kwarg={"bbox_inches": "tight"}, + style="mpl20") +def test_colorbar_shift(tmp_path): + cmap = mcolors.ListedColormap(["r", "g", "b"]) + norm = mcolors.BoundaryNorm([-1, -0.5, 0.5, 1], cmap.N) + plt.scatter([0, 1], [1, 1], c=[0, 1], cmap=cmap, norm=norm) + plt.colorbar() + + +def test_auto_papersize_deprecation(): + fig = plt.figure() + with pytest.warns(mpl.MatplotlibDeprecationWarning): + fig.savefig(io.BytesIO(), format='eps', papertype='auto') + + with pytest.warns(mpl.MatplotlibDeprecationWarning): + mpl.rcParams['ps.papersize'] = 'auto' diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_qt.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_qt.py new file mode 100644 index 00000000..f4a7ef67 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_qt.py @@ -0,0 +1,377 @@ +import copy +import importlib +import os +import signal +import sys + +from datetime import date, datetime +from unittest import mock + +import pytest + +import matplotlib +from matplotlib import pyplot as plt +from matplotlib._pylab_helpers import Gcf +from matplotlib import _c_internal_utils + + +try: + from matplotlib.backends.qt_compat import QtGui, QtWidgets # type: ignore # noqa + from matplotlib.backends.qt_editor import _formlayout +except ImportError: + pytestmark = pytest.mark.skip('No usable Qt bindings') + + +_test_timeout = 60 # A reasonably safe value for slower architectures. + + +@pytest.fixture +def qt_core(request): + qt_compat = pytest.importorskip('matplotlib.backends.qt_compat') + QtCore = qt_compat.QtCore + + return QtCore + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_fig_close(): + + # save the state of Gcf.figs + init_figs = copy.copy(Gcf.figs) + + # make a figure using pyplot interface + fig = plt.figure() + + # simulate user clicking the close button by reaching in + # and calling close on the underlying Qt object + fig.canvas.manager.window.close() + + # assert that we have removed the reference to the FigureManager + # that got added by plt.figure() + assert init_figs == Gcf.figs + + +@pytest.mark.parametrize( + "qt_key, qt_mods, answer", + [ + ("Key_A", ["ShiftModifier"], "A"), + ("Key_A", [], "a"), + ("Key_A", ["ControlModifier"], ("ctrl+a")), + ( + "Key_Aacute", + ["ShiftModifier"], + "\N{LATIN CAPITAL LETTER A WITH ACUTE}", + ), + ("Key_Aacute", [], "\N{LATIN SMALL LETTER A WITH ACUTE}"), + ("Key_Control", ["AltModifier"], ("alt+control")), + ("Key_Alt", ["ControlModifier"], "ctrl+alt"), + ( + "Key_Aacute", + ["ControlModifier", "AltModifier", "MetaModifier"], + ("ctrl+alt+meta+\N{LATIN SMALL LETTER A WITH ACUTE}"), + ), + # We do not currently map the media keys, this may change in the + # future. This means the callback will never fire + ("Key_Play", [], None), + ("Key_Backspace", [], "backspace"), + ( + "Key_Backspace", + ["ControlModifier"], + "ctrl+backspace", + ), + ], + ids=[ + 'shift', + 'lower', + 'control', + 'unicode_upper', + 'unicode_lower', + 'alt_control', + 'control_alt', + 'modifier_order', + 'non_unicode_key', + 'backspace', + 'backspace_mod', + ] +) +@pytest.mark.parametrize('backend', [ + # Note: the value is irrelevant; the important part is the marker. + pytest.param( + 'Qt5Agg', + marks=pytest.mark.backend('Qt5Agg', skip_on_importerror=True)), + pytest.param( + 'QtAgg', + marks=pytest.mark.backend('QtAgg', skip_on_importerror=True)), +]) +def test_correct_key(backend, qt_core, qt_key, qt_mods, answer, monkeypatch): + """ + Make a figure. + Send a key_press_event event (using non-public, qtX backend specific api). + Catch the event. + Assert sent and caught keys are the same. + """ + from matplotlib.backends.qt_compat import _to_int, QtCore + + if sys.platform == "darwin" and answer is not None: + answer = answer.replace("ctrl", "cmd") + answer = answer.replace("control", "cmd") + answer = answer.replace("meta", "ctrl") + result = None + qt_mod = QtCore.Qt.KeyboardModifier.NoModifier + for mod in qt_mods: + qt_mod |= getattr(QtCore.Qt.KeyboardModifier, mod) + + class _Event: + def isAutoRepeat(self): return False + def key(self): return _to_int(getattr(QtCore.Qt.Key, qt_key)) + + monkeypatch.setattr(QtWidgets.QApplication, "keyboardModifiers", + lambda self: qt_mod) + + def on_key_press(event): + nonlocal result + result = event.key + + qt_canvas = plt.figure().canvas + qt_canvas.mpl_connect('key_press_event', on_key_press) + qt_canvas.keyPressEvent(_Event()) + assert result == answer + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_device_pixel_ratio_change(): + """ + Make sure that if the pixel ratio changes, the figure dpi changes but the + widget remains the same logical size. + """ + + prop = 'matplotlib.backends.backend_qt.FigureCanvasQT.devicePixelRatioF' + with mock.patch(prop) as p: + p.return_value = 3 + + fig = plt.figure(figsize=(5, 2), dpi=120) + qt_canvas = fig.canvas + qt_canvas.show() + + def set_device_pixel_ratio(ratio): + p.return_value = ratio + + # The value here doesn't matter, as we can't mock the C++ QScreen + # object, but can override the functional wrapper around it. + # Emitting this event is simply to trigger the DPI change handler + # in Matplotlib in the same manner that it would occur normally. + screen.logicalDotsPerInchChanged.emit(96) + + qt_canvas.draw() + qt_canvas.flush_events() + + # Make sure the mocking worked + assert qt_canvas.device_pixel_ratio == ratio + + qt_canvas.manager.show() + size = qt_canvas.size() + screen = qt_canvas.window().windowHandle().screen() + set_device_pixel_ratio(3) + + # The DPI and the renderer width/height change + assert fig.dpi == 360 + assert qt_canvas.renderer.width == 1800 + assert qt_canvas.renderer.height == 720 + + # The actual widget size and figure logical size don't change. + assert size.width() == 600 + assert size.height() == 240 + assert qt_canvas.get_width_height() == (600, 240) + assert (fig.get_size_inches() == (5, 2)).all() + + set_device_pixel_ratio(2) + + # The DPI and the renderer width/height change + assert fig.dpi == 240 + assert qt_canvas.renderer.width == 1200 + assert qt_canvas.renderer.height == 480 + + # The actual widget size and figure logical size don't change. + assert size.width() == 600 + assert size.height() == 240 + assert qt_canvas.get_width_height() == (600, 240) + assert (fig.get_size_inches() == (5, 2)).all() + + set_device_pixel_ratio(1.5) + + # The DPI and the renderer width/height change + assert fig.dpi == 180 + assert qt_canvas.renderer.width == 900 + assert qt_canvas.renderer.height == 360 + + # The actual widget size and figure logical size don't change. + assert size.width() == 600 + assert size.height() == 240 + assert qt_canvas.get_width_height() == (600, 240) + assert (fig.get_size_inches() == (5, 2)).all() + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_subplottool(): + fig, ax = plt.subplots() + with mock.patch("matplotlib.backends.qt_compat._exec", lambda obj: None): + fig.canvas.manager.toolbar.configure_subplots() + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_figureoptions(): + fig, ax = plt.subplots() + ax.plot([1, 2]) + ax.imshow([[1]]) + ax.scatter(range(3), range(3), c=range(3)) + with mock.patch("matplotlib.backends.qt_compat._exec", lambda obj: None): + fig.canvas.manager.toolbar.edit_parameters() + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_figureoptions_with_datetime_axes(): + fig, ax = plt.subplots() + xydata = [ + datetime(year=2021, month=1, day=1), + datetime(year=2021, month=2, day=1) + ] + ax.plot(xydata, xydata) + with mock.patch("matplotlib.backends.qt_compat._exec", lambda obj: None): + fig.canvas.manager.toolbar.edit_parameters() + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_double_resize(): + # Check that resizing a figure twice keeps the same window size + fig, ax = plt.subplots() + fig.canvas.draw() + window = fig.canvas.manager.window + + w, h = 3, 2 + fig.set_size_inches(w, h) + assert fig.canvas.width() == w * matplotlib.rcParams['figure.dpi'] + assert fig.canvas.height() == h * matplotlib.rcParams['figure.dpi'] + + old_width = window.width() + old_height = window.height() + + fig.set_size_inches(w, h) + assert window.width() == old_width + assert window.height() == old_height + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_canvas_reinit(): + from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg + + called = False + + def crashing_callback(fig, stale): + nonlocal called + fig.canvas.draw_idle() + called = True + + fig, ax = plt.subplots() + fig.stale_callback = crashing_callback + # this should not raise + canvas = FigureCanvasQTAgg(fig) + fig.stale = True + assert called + + +@pytest.mark.backend('Qt5Agg', skip_on_importerror=True) +def test_form_widget_get_with_datetime_and_date_fields(): + from matplotlib.backends.backend_qt import _create_qApp + _create_qApp() + + form = [ + ("Datetime field", datetime(year=2021, month=3, day=11)), + ("Date field", date(year=2021, month=3, day=11)) + ] + widget = _formlayout.FormWidget(form) + widget.setup() + values = widget.get() + assert values == [ + datetime(year=2021, month=3, day=11), + date(year=2021, month=3, day=11) + ] + + +def _get_testable_qt_backends(): + envs = [] + for deps, env in [ + ([qt_api], {"MPLBACKEND": "qtagg", "QT_API": qt_api}) + for qt_api in ["PyQt6", "PySide6", "PyQt5", "PySide2"] + ]: + reason = None + missing = [dep for dep in deps if not importlib.util.find_spec(dep)] + if (sys.platform == "linux" and + not _c_internal_utils.display_is_valid()): + reason = "$DISPLAY and $WAYLAND_DISPLAY are unset" + elif missing: + reason = "{} cannot be imported".format(", ".join(missing)) + elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'): + reason = "macosx backend fails on Azure" + marks = [] + if reason: + marks.append(pytest.mark.skip( + reason=f"Skipping {env} because {reason}")) + envs.append(pytest.param(env, marks=marks, id=str(env))) + return envs + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_fig_sigint_override(qt_core): + from matplotlib.backends.backend_qt5 import _BackendQT5 + # Create a figure + plt.figure() + + # Variable to access the handler from the inside of the event loop + event_loop_handler = None + + # Callback to fire during event loop: save SIGINT handler, then exit + def fire_signal_and_quit(): + # Save event loop signal + nonlocal event_loop_handler + event_loop_handler = signal.getsignal(signal.SIGINT) + + # Request event loop exit + qt_core.QCoreApplication.exit() + + # Timer to exit event loop + qt_core.QTimer.singleShot(0, fire_signal_and_quit) + + # Save original SIGINT handler + original_handler = signal.getsignal(signal.SIGINT) + + # Use our own SIGINT handler to be 100% sure this is working + def custom_handler(signum, frame): + pass + + signal.signal(signal.SIGINT, custom_handler) + + try: + # mainloop() sets SIGINT, starts Qt event loop (which triggers timer + # and exits) and then mainloop() resets SIGINT + matplotlib.backends.backend_qt._BackendQT.mainloop() + + # Assert: signal handler during loop execution is changed + # (can't test equality with func) + assert event_loop_handler != custom_handler + + # Assert: current signal handler is the same as the one we set before + assert signal.getsignal(signal.SIGINT) == custom_handler + + # Repeat again to test that SIG_DFL and SIG_IGN will not be overridden + for custom_handler in (signal.SIG_DFL, signal.SIG_IGN): + qt_core.QTimer.singleShot(0, fire_signal_and_quit) + signal.signal(signal.SIGINT, custom_handler) + + _BackendQT5.mainloop() + + assert event_loop_handler == custom_handler + assert signal.getsignal(signal.SIGINT) == custom_handler + + finally: + # Reset SIGINT handler to what it was before the test + signal.signal(signal.SIGINT, original_handler) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_svg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_svg.py new file mode 100644 index 00000000..01edbf87 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_svg.py @@ -0,0 +1,643 @@ +import datetime +from io import BytesIO +from pathlib import Path +import xml.etree.ElementTree +import xml.parsers.expat + +import pytest + +import numpy as np + +import matplotlib as mpl +from matplotlib.figure import Figure +from matplotlib.text import Text +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing._markers import needs_usetex +from matplotlib import font_manager as fm +from matplotlib.offsetbox import (OffsetImage, AnnotationBbox) + + +def test_visibility(): + fig, ax = plt.subplots() + + x = np.linspace(0, 4 * np.pi, 50) + y = np.sin(x) + yerr = np.ones_like(y) + + a, b, c = ax.errorbar(x, y, yerr=yerr, fmt='ko') + for artist in b: + artist.set_visible(False) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue() + + parser = xml.parsers.expat.ParserCreate() + parser.Parse(buf) # this will raise ExpatError if the svg is invalid + + +@image_comparison(['fill_black_with_alpha.svg'], remove_text=True) +def test_fill_black_with_alpha(): + fig, ax = plt.subplots() + ax.scatter(x=[0, 0.1, 1], y=[0, 0, 0], c='k', alpha=0.1, s=10000) + + +@image_comparison(['noscale'], remove_text=True) +def test_noscale(): + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + + fig, ax = plt.subplots() + ax.imshow(Z, cmap='gray', interpolation='none') + + +def test_text_urls(): + fig = plt.figure() + + test_url = "http://test_text_urls.matplotlib.org" + fig.suptitle("test_text_urls", url=test_url) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + + expected = f'<a xlink:href="{test_url}">' + assert expected in buf + + +@image_comparison(['bold_font_output.svg']) +def test_bold_font_output(): + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)) + ax.set_xlabel('nonbold-xlabel') + ax.set_ylabel('bold-ylabel', fontweight='bold') + ax.set_title('bold-title', fontweight='bold') + + +@image_comparison(['bold_font_output_with_none_fonttype.svg']) +def test_bold_font_output_with_none_fonttype(): + plt.rcParams['svg.fonttype'] = 'none' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)) + ax.set_xlabel('nonbold-xlabel') + ax.set_ylabel('bold-ylabel', fontweight='bold') + ax.set_title('bold-title', fontweight='bold') + + +@check_figures_equal(tol=20) +def test_rasterized(fig_test, fig_ref): + t = np.arange(0, 100) * (2.3) + x = np.cos(t) + y = np.sin(t) + + ax_ref = fig_ref.subplots() + ax_ref.plot(x, y, "-", c="r", lw=10) + ax_ref.plot(x+1, y, "-", c="b", lw=10) + + ax_test = fig_test.subplots() + ax_test.plot(x, y, "-", c="r", lw=10, rasterized=True) + ax_test.plot(x+1, y, "-", c="b", lw=10, rasterized=True) + + +@check_figures_equal() +def test_rasterized_ordering(fig_test, fig_ref): + t = np.arange(0, 100) * (2.3) + x = np.cos(t) + y = np.sin(t) + + ax_ref = fig_ref.subplots() + ax_ref.set_xlim(0, 3) + ax_ref.set_ylim(-1.1, 1.1) + ax_ref.plot(x, y, "-", c="r", lw=10, rasterized=True) + ax_ref.plot(x+1, y, "-", c="b", lw=10, rasterized=False) + ax_ref.plot(x+2, y, "-", c="g", lw=10, rasterized=True) + ax_ref.plot(x+3, y, "-", c="m", lw=10, rasterized=True) + + ax_test = fig_test.subplots() + ax_test.set_xlim(0, 3) + ax_test.set_ylim(-1.1, 1.1) + ax_test.plot(x, y, "-", c="r", lw=10, rasterized=True, zorder=1.1) + ax_test.plot(x+2, y, "-", c="g", lw=10, rasterized=True, zorder=1.3) + ax_test.plot(x+3, y, "-", c="m", lw=10, rasterized=True, zorder=1.4) + ax_test.plot(x+1, y, "-", c="b", lw=10, rasterized=False, zorder=1.2) + + +@check_figures_equal(tol=5, extensions=['svg', 'pdf']) +def test_prevent_rasterization(fig_test, fig_ref): + loc = [0.05, 0.05] + + ax_ref = fig_ref.subplots() + + ax_ref.plot([loc[0]], [loc[1]], marker="x", c="black", zorder=2) + + b = mpl.offsetbox.TextArea("X") + abox = mpl.offsetbox.AnnotationBbox(b, loc, zorder=2.1) + ax_ref.add_artist(abox) + + ax_test = fig_test.subplots() + ax_test.plot([loc[0]], [loc[1]], marker="x", c="black", zorder=2, + rasterized=True) + + b = mpl.offsetbox.TextArea("X") + abox = mpl.offsetbox.AnnotationBbox(b, loc, zorder=2.1) + ax_test.add_artist(abox) + + +def test_count_bitmaps(): + def count_tag(fig, tag): + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + return buf.count(f"<{tag}") + + # No rasterized elements + fig1 = plt.figure() + ax1 = fig1.add_subplot(1, 1, 1) + ax1.set_axis_off() + for n in range(5): + ax1.plot([0, 20], [0, n], "b-", rasterized=False) + assert count_tag(fig1, "image") == 0 + assert count_tag(fig1, "path") == 6 # axis patch plus lines + + # rasterized can be merged + fig2 = plt.figure() + ax2 = fig2.add_subplot(1, 1, 1) + ax2.set_axis_off() + for n in range(5): + ax2.plot([0, 20], [0, n], "b-", rasterized=True) + assert count_tag(fig2, "image") == 1 + assert count_tag(fig2, "path") == 1 # axis patch + + # rasterized can't be merged without affecting draw order + fig3 = plt.figure() + ax3 = fig3.add_subplot(1, 1, 1) + ax3.set_axis_off() + for n in range(5): + ax3.plot([0, 20], [n, 0], "b-", rasterized=False) + ax3.plot([0, 20], [0, n], "b-", rasterized=True) + assert count_tag(fig3, "image") == 5 + assert count_tag(fig3, "path") == 6 + + # rasterized whole axes + fig4 = plt.figure() + ax4 = fig4.add_subplot(1, 1, 1) + ax4.set_axis_off() + ax4.set_rasterized(True) + for n in range(5): + ax4.plot([0, 20], [n, 0], "b-", rasterized=False) + ax4.plot([0, 20], [0, n], "b-", rasterized=True) + assert count_tag(fig4, "image") == 1 + assert count_tag(fig4, "path") == 1 + + # rasterized can be merged, but inhibited by suppressComposite + fig5 = plt.figure() + fig5.suppressComposite = True + ax5 = fig5.add_subplot(1, 1, 1) + ax5.set_axis_off() + for n in range(5): + ax5.plot([0, 20], [0, n], "b-", rasterized=True) + assert count_tag(fig5, "image") == 5 + assert count_tag(fig5, "path") == 1 # axis patch + + +# Use Computer Modern Sans Serif, not Helvetica (which has no \textwon). +@mpl.style.context('default') +@needs_usetex +def test_unicode_won(): + fig = Figure() + fig.text(.5, .5, r'\textwon', usetex=True) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue() + + tree = xml.etree.ElementTree.fromstring(buf) + ns = 'http://www.w3.org/2000/svg' + won_id = 'SFSS3583-8e' + assert len(tree.findall(f'.//{{{ns}}}path[@d][@id="{won_id}"]')) == 1 + assert f'#{won_id}' in tree.find(f'.//{{{ns}}}use').attrib.values() + + +def test_svgnone_with_data_coordinates(): + plt.rcParams.update({'svg.fonttype': 'none', 'font.stretch': 'condensed'}) + expected = 'Unlikely to appear by chance' + + fig, ax = plt.subplots() + ax.text(np.datetime64('2019-06-30'), 1, expected) + ax.set_xlim(np.datetime64('2019-01-01'), np.datetime64('2019-12-31')) + ax.set_ylim(0, 2) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + fd.seek(0) + buf = fd.read().decode() + + assert expected in buf and "condensed" in buf + + +def test_gid(): + """Test that object gid appears in output svg.""" + from matplotlib.offsetbox import OffsetBox + from matplotlib.axis import Tick + + fig = plt.figure() + + ax1 = fig.add_subplot(131) + ax1.imshow([[1., 2.], [2., 3.]], aspect="auto") + ax1.scatter([1, 2, 3], [1, 2, 3], label="myscatter") + ax1.plot([2, 3, 1], label="myplot") + ax1.legend() + ax1a = ax1.twinx() + ax1a.bar([1, 2, 3], [1, 2, 3]) + + ax2 = fig.add_subplot(132, projection="polar") + ax2.plot([0, 1.5, 3], [1, 2, 3]) + + ax3 = fig.add_subplot(133, projection="3d") + ax3.plot([1, 2], [1, 2], [1, 2]) + + fig.canvas.draw() + + gdic = {} + for idx, obj in enumerate(fig.findobj(include_self=True)): + if obj.get_visible(): + gid = f"test123{obj.__class__.__name__}_{idx}" + gdic[gid] = obj + obj.set_gid(gid) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + + def include(gid, obj): + # we need to exclude certain objects which will not appear in the svg + if isinstance(obj, OffsetBox): + return False + if isinstance(obj, Text): + if obj.get_text() == "": + return False + elif obj.axes is None: + return False + if isinstance(obj, plt.Line2D): + xdata, ydata = obj.get_data() + if len(xdata) == len(ydata) == 1: + return False + elif not hasattr(obj, "axes") or obj.axes is None: + return False + if isinstance(obj, Tick): + loc = obj.get_loc() + if loc == 0: + return False + vi = obj.get_view_interval() + if loc < min(vi) or loc > max(vi): + return False + return True + + for gid, obj in gdic.items(): + if include(gid, obj): + assert gid in buf + + +def test_savefig_tight(): + # Check that the draw-disabled renderer correctly disables open/close_group + # as well. + plt.savefig(BytesIO(), format="svgz", bbox_inches="tight") + + +def test_url(): + # Test that object url appears in output svg. + + fig, ax = plt.subplots() + + # collections + s = ax.scatter([1, 2, 3], [4, 5, 6]) + s.set_urls(['https://example.com/foo', 'https://example.com/bar', None]) + + # Line2D + p, = plt.plot([1, 3], [6, 5]) + p.set_url('https://example.com/baz') + + b = BytesIO() + fig.savefig(b, format='svg') + b = b.getvalue() + for v in [b'foo', b'bar', b'baz']: + assert b'https://example.com/' + v in b + + +def test_url_tick(monkeypatch): + monkeypatch.setenv('SOURCE_DATE_EPOCH', '19680801') + + fig1, ax = plt.subplots() + ax.scatter([1, 2, 3], [4, 5, 6]) + for i, tick in enumerate(ax.yaxis.get_major_ticks()): + tick.set_url(f'https://example.com/{i}') + + fig2, ax = plt.subplots() + ax.scatter([1, 2, 3], [4, 5, 6]) + for i, tick in enumerate(ax.yaxis.get_major_ticks()): + tick.label1.set_url(f'https://example.com/{i}') + tick.label2.set_url(f'https://example.com/{i}') + + b1 = BytesIO() + fig1.savefig(b1, format='svg') + b1 = b1.getvalue() + + b2 = BytesIO() + fig2.savefig(b2, format='svg') + b2 = b2.getvalue() + + for i in range(len(ax.yaxis.get_major_ticks())): + assert f'https://example.com/{i}'.encode('ascii') in b1 + assert b1 == b2 + + +def test_svg_default_metadata(monkeypatch): + # Values have been predefined for 'Creator', 'Date', 'Format', and 'Type'. + monkeypatch.setenv('SOURCE_DATE_EPOCH', '19680801') + + fig, ax = plt.subplots() + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + + # Creator + assert mpl.__version__ in buf + # Date + assert '1970-08-16' in buf + # Format + assert 'image/svg+xml' in buf + # Type + assert 'StillImage' in buf + + # Now make sure all the default metadata can be cleared. + with BytesIO() as fd: + fig.savefig(fd, format='svg', metadata={'Date': None, 'Creator': None, + 'Format': None, 'Type': None}) + buf = fd.getvalue().decode() + + # Creator + assert mpl.__version__ not in buf + # Date + assert '1970-08-16' not in buf + # Format + assert 'image/svg+xml' not in buf + # Type + assert 'StillImage' not in buf + + +def test_svg_clear_default_metadata(monkeypatch): + # Makes sure that setting a default metadata to `None` + # removes the corresponding tag from the metadata. + monkeypatch.setenv('SOURCE_DATE_EPOCH', '19680801') + + metadata_contains = {'creator': mpl.__version__, 'date': '1970-08-16', + 'format': 'image/svg+xml', 'type': 'StillImage'} + + SVGNS = '{http://www.w3.org/2000/svg}' + RDFNS = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}' + CCNS = '{http://creativecommons.org/ns#}' + DCNS = '{http://purl.org/dc/elements/1.1/}' + + fig, ax = plt.subplots() + for name in metadata_contains: + with BytesIO() as fd: + fig.savefig(fd, format='svg', metadata={name.title(): None}) + buf = fd.getvalue().decode() + + root = xml.etree.ElementTree.fromstring(buf) + work, = root.findall(f'./{SVGNS}metadata/{RDFNS}RDF/{CCNS}Work') + for key in metadata_contains: + data = work.findall(f'./{DCNS}{key}') + if key == name: + # The one we cleared is not there + assert not data + continue + # Everything else should be there + data, = data + xmlstr = xml.etree.ElementTree.tostring(data, encoding="unicode") + assert metadata_contains[key] in xmlstr + + +def test_svg_clear_all_metadata(): + # Makes sure that setting all default metadata to `None` + # removes the metadata tag from the output. + + fig, ax = plt.subplots() + with BytesIO() as fd: + fig.savefig(fd, format='svg', metadata={'Date': None, 'Creator': None, + 'Format': None, 'Type': None}) + buf = fd.getvalue().decode() + + SVGNS = '{http://www.w3.org/2000/svg}' + + root = xml.etree.ElementTree.fromstring(buf) + assert not root.findall(f'./{SVGNS}metadata') + + +def test_svg_metadata(): + single_value = ['Coverage', 'Identifier', 'Language', 'Relation', 'Source', + 'Title', 'Type'] + multi_value = ['Contributor', 'Creator', 'Keywords', 'Publisher', 'Rights'] + metadata = { + 'Date': [datetime.date(1968, 8, 1), + datetime.datetime(1968, 8, 2, 1, 2, 3)], + 'Description': 'description\ntext', + **{k: f'{k} foo' for k in single_value}, + **{k: [f'{k} bar', f'{k} baz'] for k in multi_value}, + } + + fig = plt.figure() + with BytesIO() as fd: + fig.savefig(fd, format='svg', metadata=metadata) + buf = fd.getvalue().decode() + + SVGNS = '{http://www.w3.org/2000/svg}' + RDFNS = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}' + CCNS = '{http://creativecommons.org/ns#}' + DCNS = '{http://purl.org/dc/elements/1.1/}' + + root = xml.etree.ElementTree.fromstring(buf) + rdf, = root.findall(f'./{SVGNS}metadata/{RDFNS}RDF') + + # Check things that are single entries. + titles = [node.text for node in root.findall(f'./{SVGNS}title')] + assert titles == [metadata['Title']] + types = [node.attrib[f'{RDFNS}resource'] + for node in rdf.findall(f'./{CCNS}Work/{DCNS}type')] + assert types == [metadata['Type']] + for k in ['Description', *single_value]: + if k == 'Type': + continue + values = [node.text + for node in rdf.findall(f'./{CCNS}Work/{DCNS}{k.lower()}')] + assert values == [metadata[k]] + + # Check things that are multi-value entries. + for k in multi_value: + if k == 'Keywords': + continue + values = [ + node.text + for node in rdf.findall( + f'./{CCNS}Work/{DCNS}{k.lower()}/{CCNS}Agent/{DCNS}title')] + assert values == metadata[k] + + # Check special things. + dates = [node.text for node in rdf.findall(f'./{CCNS}Work/{DCNS}date')] + assert dates == ['1968-08-01/1968-08-02T01:02:03'] + + values = [node.text for node in + rdf.findall(f'./{CCNS}Work/{DCNS}subject/{RDFNS}Bag/{RDFNS}li')] + assert values == metadata['Keywords'] + + +@image_comparison(["multi_font_aspath.svg"], tol=1.8) +def test_multi_font_type3(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + plt.rc('svg', fonttype='path') + + fig = plt.figure() + fig.text(0.15, 0.475, "There are 几个汉字 in between!") + + +@image_comparison(["multi_font_astext.svg"]) +def test_multi_font_type42(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + fig = plt.figure() + plt.rc('svg', fonttype='none') + + plt.rc('font', family=['DejaVu Sans', 'WenQuanYi Zen Hei'], size=27) + fig.text(0.15, 0.475, "There are 几个汉字 in between!") + + +@pytest.mark.parametrize('metadata,error,message', [ + ({'Date': 1}, TypeError, "Invalid type for Date metadata. Expected str"), + ({'Date': [1]}, TypeError, + "Invalid type for Date metadata. Expected iterable"), + ({'Keywords': 1}, TypeError, + "Invalid type for Keywords metadata. Expected str"), + ({'Keywords': [1]}, TypeError, + "Invalid type for Keywords metadata. Expected iterable"), + ({'Creator': 1}, TypeError, + "Invalid type for Creator metadata. Expected str"), + ({'Creator': [1]}, TypeError, + "Invalid type for Creator metadata. Expected iterable"), + ({'Title': 1}, TypeError, + "Invalid type for Title metadata. Expected str"), + ({'Format': 1}, TypeError, + "Invalid type for Format metadata. Expected str"), + ({'Foo': 'Bar'}, ValueError, "Unknown metadata key"), + ]) +def test_svg_incorrect_metadata(metadata, error, message): + with pytest.raises(error, match=message), BytesIO() as fd: + fig = plt.figure() + fig.savefig(fd, format='svg', metadata=metadata) + + +def test_svg_escape(): + fig = plt.figure() + fig.text(0.5, 0.5, "<\'\"&>", gid="<\'\"&>") + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + assert '&lt;&apos;&quot;&amp;&gt;"' in buf + + +@pytest.mark.parametrize("font_str", [ + "'DejaVu Sans', 'WenQuanYi Zen Hei', 'Arial', sans-serif", + "'DejaVu Serif', 'WenQuanYi Zen Hei', 'Times New Roman', serif", + "'Arial', 'WenQuanYi Zen Hei', cursive", + "'Impact', 'WenQuanYi Zen Hei', fantasy", + "'DejaVu Sans Mono', 'WenQuanYi Zen Hei', 'Courier New', monospace", + # These do not work because the logic to get the font metrics will not find + # WenQuanYi as the fallback logic stops with the first fallback font: + # "'DejaVu Sans Mono', 'Courier New', 'WenQuanYi Zen Hei', monospace", + # "'DejaVu Sans', 'Arial', 'WenQuanYi Zen Hei', sans-serif", + # "'DejaVu Serif', 'Times New Roman', 'WenQuanYi Zen Hei', serif", +]) +@pytest.mark.parametrize("include_generic", [True, False]) +def test_svg_font_string(font_str, include_generic): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font may be missing") + + explicit, *rest, generic = map( + lambda x: x.strip("'"), font_str.split(", ") + ) + size = len(generic) + if include_generic: + rest = rest + [generic] + plt.rcParams[f"font.{generic}"] = rest + plt.rcParams["font.size"] = size + plt.rcParams["svg.fonttype"] = "none" + + fig, ax = plt.subplots() + if generic == "sans-serif": + generic_options = ["sans", "sans-serif", "sans serif"] + else: + generic_options = [generic] + + for generic_name in generic_options: + # test that fallback works + ax.text(0.5, 0.5, "There are 几个汉字 in between!", + family=[explicit, generic_name], ha="center") + # test deduplication works + ax.text(0.5, 0.1, "There are 几个汉字 in between!", + family=[explicit, *rest, generic_name], ha="center") + ax.axis("off") + + with BytesIO() as fd: + fig.savefig(fd, format="svg") + buf = fd.getvalue() + + tree = xml.etree.ElementTree.fromstring(buf) + ns = "http://www.w3.org/2000/svg" + text_count = 0 + for text_element in tree.findall(f".//{{{ns}}}text"): + text_count += 1 + font_info = dict( + map(lambda x: x.strip(), _.strip().split(":")) + for _ in dict(text_element.items())["style"].split(";") + )["font"] + + assert font_info == f"{size}px {font_str}" + assert text_count == len(ax.texts) + + +def test_annotationbbox_gid(): + # Test that object gid appears in the AnnotationBbox + # in output svg. + fig = plt.figure() + ax = fig.add_subplot() + arr_img = np.ones((32, 32)) + xy = (0.3, 0.55) + + imagebox = OffsetImage(arr_img, zoom=0.1) + imagebox.image.axes = ax + + ab = AnnotationBbox(imagebox, xy, + xybox=(120., -80.), + xycoords='data', + boxcoords="offset points", + pad=0.5, + arrowprops=dict( + arrowstyle="->", + connectionstyle="angle,angleA=0,angleB=90,rad=3") + ) + ab.set_gid("a test for issue 20044") + ax.add_artist(ab) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode('utf-8') + + expected = '<g id="a test for issue 20044">' + assert expected in buf diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_template.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_template.py new file mode 100644 index 00000000..d7e2a5cd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_template.py @@ -0,0 +1,51 @@ +""" +Backend-loading machinery tests, using variations on the template backend. +""" + +import sys +from types import SimpleNamespace +from unittest.mock import MagicMock + +import matplotlib as mpl +from matplotlib import pyplot as plt +from matplotlib.backends import backend_template +from matplotlib.backends.backend_template import ( + FigureCanvasTemplate, FigureManagerTemplate) + + +def test_load_template(): + mpl.use("template") + assert type(plt.figure().canvas) == FigureCanvasTemplate + + +def test_load_old_api(monkeypatch): + mpl_test_backend = SimpleNamespace(**vars(backend_template)) + mpl_test_backend.new_figure_manager = ( + lambda num, *args, FigureClass=mpl.figure.Figure, **kwargs: + FigureManagerTemplate( + FigureCanvasTemplate(FigureClass(*args, **kwargs)), num)) + monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) + mpl.use("module://mpl_test_backend") + assert type(plt.figure().canvas) == FigureCanvasTemplate + plt.draw_if_interactive() + + +def test_show(monkeypatch): + mpl_test_backend = SimpleNamespace(**vars(backend_template)) + mock_show = MagicMock() + monkeypatch.setattr( + mpl_test_backend.FigureManagerTemplate, "pyplot_show", mock_show) + monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) + mpl.use("module://mpl_test_backend") + plt.show() + mock_show.assert_called_with() + + +def test_show_old_global_api(monkeypatch): + mpl_test_backend = SimpleNamespace(**vars(backend_template)) + mock_show = MagicMock() + monkeypatch.setattr(mpl_test_backend, "show", mock_show, raising=False) + monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) + mpl.use("module://mpl_test_backend") + plt.show() + mock_show.assert_called_with() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tk.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tk.py new file mode 100644 index 00000000..e44e5589 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tk.py @@ -0,0 +1,265 @@ +import functools +import importlib +import os +import platform +import subprocess +import sys + +import pytest + +from matplotlib import _c_internal_utils +from matplotlib.testing import subprocess_run_helper + + +_test_timeout = 60 # A reasonably safe value for slower architectures. + + +def _isolated_tk_test(success_count, func=None): + """ + A decorator to run *func* in a subprocess and assert that it prints + "success" *success_count* times and nothing on stderr. + + TkAgg tests seem to have interactions between tests, so isolate each test + in a subprocess. See GH#18261 + """ + + if func is None: + return functools.partial(_isolated_tk_test, success_count) + + if "MPL_TEST_ESCAPE_HATCH" in os.environ: + # set in subprocess_run_helper() below + return func + + @pytest.mark.skipif( + not importlib.util.find_spec('tkinter'), + reason="missing tkinter" + ) + @pytest.mark.skipif( + sys.platform == "linux" and not _c_internal_utils.display_is_valid(), + reason="$DISPLAY and $WAYLAND_DISPLAY are unset" + ) + @pytest.mark.xfail( # https://github.com/actions/setup-python/issues/649 + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and sys.version_info[:2] < (3, 11), + reason='Tk version mismatch on Azure macOS CI' + ) + @functools.wraps(func) + def test_func(): + # even if the package exists, may not actually be importable this can + # be the case on some CI systems. + pytest.importorskip('tkinter') + try: + proc = subprocess_run_helper( + func, timeout=_test_timeout, extra_env=dict( + MPLBACKEND="TkAgg", MPL_TEST_ESCAPE_HATCH="1")) + except subprocess.TimeoutExpired: + pytest.fail("Subprocess timed out") + except subprocess.CalledProcessError as e: + pytest.fail("Subprocess failed to test intended behavior\n" + + str(e.stderr)) + else: + # macOS may actually emit irrelevant errors about Accelerated + # OpenGL vs. software OpenGL, or some permission error on Azure, so + # suppress them. + # Asserting stderr first (and printing it on failure) should be + # more helpful for debugging that printing a failed success count. + ignored_lines = ["OpenGL", "CFMessagePort: bootstrap_register", + "/usr/include/servers/bootstrap_defs.h"] + assert not [line for line in proc.stderr.splitlines() + if all(msg not in line for msg in ignored_lines)] + assert proc.stdout.count("success") == success_count + + return test_func + + +@_isolated_tk_test(success_count=6) # len(bad_boxes) +def test_blit(): + import matplotlib.pyplot as plt + import numpy as np + import matplotlib.backends.backend_tkagg # noqa + from matplotlib.backends import _backend_tk, _tkagg + + fig, ax = plt.subplots() + photoimage = fig.canvas._tkphoto + data = np.ones((4, 4, 4)) + height, width = data.shape[:2] + dataptr = (height, width, data.ctypes.data) + # Test out of bounds blitting. + bad_boxes = ((-1, 2, 0, 2), + (2, 0, 0, 2), + (1, 6, 0, 2), + (0, 2, -1, 2), + (0, 2, 2, 0), + (0, 2, 1, 6)) + for bad_box in bad_boxes: + try: + _tkagg.blit( + photoimage.tk.interpaddr(), str(photoimage), dataptr, 0, + (0, 1, 2, 3), bad_box) + except ValueError: + print("success") + + # Test blitting to a destroyed canvas. + plt.close(fig) + _backend_tk.blit(photoimage, data, (0, 1, 2, 3)) + + +@_isolated_tk_test(success_count=1) +def test_figuremanager_preserves_host_mainloop(): + import tkinter + import matplotlib.pyplot as plt + success = [] + + def do_plot(): + plt.figure() + plt.plot([1, 2], [3, 5]) + plt.close() + root.after(0, legitimate_quit) + + def legitimate_quit(): + root.quit() + success.append(True) + + root = tkinter.Tk() + root.after(0, do_plot) + root.mainloop() + + if success: + print("success") + + +@pytest.mark.skipif(platform.python_implementation() != 'CPython', + reason='PyPy does not support Tkinter threading: ' + 'https://foss.heptapod.net/pypy/pypy/-/issues/1929') +@pytest.mark.flaky(reruns=3) +@_isolated_tk_test(success_count=1) +def test_figuremanager_cleans_own_mainloop(): + import tkinter + import time + import matplotlib.pyplot as plt + import threading + from matplotlib.cbook import _get_running_interactive_framework + + root = tkinter.Tk() + plt.plot([1, 2, 3], [1, 2, 5]) + + def target(): + while not 'tk' == _get_running_interactive_framework(): + time.sleep(.01) + plt.close() + if show_finished_event.wait(): + print('success') + + show_finished_event = threading.Event() + thread = threading.Thread(target=target, daemon=True) + thread.start() + plt.show(block=True) # Testing if this function hangs. + show_finished_event.set() + thread.join() + + +@pytest.mark.flaky(reruns=3) +@_isolated_tk_test(success_count=0) +def test_never_update(): + import tkinter + del tkinter.Misc.update + del tkinter.Misc.update_idletasks + + import matplotlib.pyplot as plt + fig = plt.figure() + plt.show(block=False) + + plt.draw() # Test FigureCanvasTkAgg. + fig.canvas.toolbar.configure_subplots() # Test NavigationToolbar2Tk. + # Test FigureCanvasTk filter_destroy callback + fig.canvas.get_tk_widget().after(100, plt.close, fig) + + # Check for update() or update_idletasks() in the event queue, functionally + # equivalent to tkinter.Misc.update. + plt.show(block=True) + + # Note that exceptions would be printed to stderr; _isolated_tk_test + # checks them. + + +@_isolated_tk_test(success_count=2) +def test_missing_back_button(): + import matplotlib.pyplot as plt + from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk + + class Toolbar(NavigationToolbar2Tk): + # Only display the buttons we need. + toolitems = [t for t in NavigationToolbar2Tk.toolitems if + t[0] in ('Home', 'Pan', 'Zoom')] + + fig = plt.figure() + print("success") + Toolbar(fig.canvas, fig.canvas.manager.window) # This should not raise. + print("success") + + +@_isolated_tk_test(success_count=1) +def test_canvas_focus(): + import tkinter as tk + import matplotlib.pyplot as plt + success = [] + + def check_focus(): + tkcanvas = fig.canvas.get_tk_widget() + # Give the plot window time to appear + if not tkcanvas.winfo_viewable(): + tkcanvas.wait_visibility() + # Make sure the canvas has the focus, so that it's able to receive + # keyboard events. + if tkcanvas.focus_lastfor() == tkcanvas: + success.append(True) + plt.close() + root.destroy() + + root = tk.Tk() + fig = plt.figure() + plt.plot([1, 2, 3]) + root.after(0, plt.show) + root.after(100, check_focus) + root.mainloop() + + if success: + print("success") + + +@_isolated_tk_test(success_count=2) +def test_embedding(): + import tkinter as tk + from matplotlib.backends.backend_tkagg import ( + FigureCanvasTkAgg, NavigationToolbar2Tk) + from matplotlib.backend_bases import key_press_handler + from matplotlib.figure import Figure + + root = tk.Tk() + + def test_figure(master): + fig = Figure() + ax = fig.add_subplot() + ax.plot([1, 2, 3]) + + canvas = FigureCanvasTkAgg(fig, master=master) + canvas.draw() + canvas.mpl_connect("key_press_event", key_press_handler) + canvas.get_tk_widget().pack(expand=True, fill="both") + + toolbar = NavigationToolbar2Tk(canvas, master, pack_toolbar=False) + toolbar.pack(expand=True, fill="x") + + canvas.get_tk_widget().forget() + toolbar.forget() + + test_figure(root) + print("success") + + # Test with a dark button color. Doesn't actually check whether the icon + # color becomes lighter, just that the code doesn't break. + + root.tk_setPalette(background="sky blue", selectColor="midnight blue", + foreground="white") + test_figure(root) + print("success") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tools.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tools.py new file mode 100644 index 00000000..cc05a1a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_tools.py @@ -0,0 +1,20 @@ +import pytest + +from matplotlib.backend_tools import ToolHelpBase + + +@pytest.mark.parametrize('rc_shortcut,expected', [ + ('home', 'Home'), + ('backspace', 'Backspace'), + ('f1', 'F1'), + ('ctrl+a', 'Ctrl+A'), + ('ctrl+A', 'Ctrl+Shift+A'), + ('a', 'a'), + ('A', 'A'), + ('ctrl+shift+f1', 'Ctrl+Shift+F1'), + ('1', '1'), + ('cmd+p', 'Cmd+P'), + ('cmd+1', 'Cmd+1'), +]) +def test_format_shortcut(rc_shortcut, expected): + assert ToolHelpBase.format_shortcut(rc_shortcut) == expected diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_webagg.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_webagg.py new file mode 100644 index 00000000..237a279c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backend_webagg.py @@ -0,0 +1,33 @@ +import subprocess +import os +import sys +import pytest +import matplotlib.backends.backend_webagg_core + + +@pytest.mark.parametrize("backend", ["webagg", "nbagg"]) +def test_webagg_fallback(backend): + pytest.importorskip("tornado") + if backend == "nbagg": + pytest.importorskip("IPython") + env = dict(os.environ) + if sys.platform != "win32": + env["DISPLAY"] = "" + + env["MPLBACKEND"] = backend + + test_code = ( + "import os;" + + f"assert os.environ['MPLBACKEND'] == '{backend}';" + + "import matplotlib.pyplot as plt; " + + "print(plt.get_backend());" + f"assert '{backend}' == plt.get_backend().lower();" + ) + ret = subprocess.call([sys.executable, "-c", test_code], env=env) + + assert ret == 0 + + +def test_webagg_core_no_toolbar(): + fm = matplotlib.backends.backend_webagg_core.FigureManagerWebAgg + assert fm._toolbar2_class is None diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backends_interactive.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backends_interactive.py new file mode 100644 index 00000000..6048b264 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_backends_interactive.py @@ -0,0 +1,841 @@ +import importlib +import importlib.util +import inspect +import json +import os +import platform +import signal +import subprocess +import sys +import tempfile +import time +import urllib.request + +from PIL import Image + +import pytest + +import matplotlib as mpl +from matplotlib import _c_internal_utils +from matplotlib.backend_tools import ToolToggleBase +from matplotlib.testing import subprocess_run_helper as _run_helper + + +class _WaitForStringPopen(subprocess.Popen): + """ + A Popen that passes flags that allow triggering KeyboardInterrupt. + """ + + def __init__(self, *args, **kwargs): + if sys.platform == 'win32': + kwargs['creationflags'] = subprocess.CREATE_NEW_CONSOLE + super().__init__( + *args, **kwargs, + # Force Agg so that each test can switch to its desired backend. + env={**os.environ, "MPLBACKEND": "Agg", "SOURCE_DATE_EPOCH": "0"}, + stdout=subprocess.PIPE, universal_newlines=True) + + def wait_for(self, terminator): + """Read until the terminator is reached.""" + buf = '' + while True: + c = self.stdout.read(1) + if not c: + raise RuntimeError( + f'Subprocess died before emitting expected {terminator!r}') + buf += c + if buf.endswith(terminator): + return + + +# Minimal smoke-testing of the backends for which the dependencies are +# PyPI-installable on CI. They are not available for all tested Python +# versions so we don't fail on missing backends. + +def _get_testable_interactive_backends(): + envs = [] + for deps, env in [ + *[([qt_api], + {"MPLBACKEND": "qtagg", "QT_API": qt_api}) + for qt_api in ["PyQt6", "PySide6", "PyQt5", "PySide2"]], + *[([qt_api, "cairocffi"], + {"MPLBACKEND": "qtcairo", "QT_API": qt_api}) + for qt_api in ["PyQt6", "PySide6", "PyQt5", "PySide2"]], + *[(["cairo", "gi"], {"MPLBACKEND": f"gtk{version}{renderer}"}) + for version in [3, 4] for renderer in ["agg", "cairo"]], + (["tkinter"], {"MPLBACKEND": "tkagg"}), + (["wx"], {"MPLBACKEND": "wx"}), + (["wx"], {"MPLBACKEND": "wxagg"}), + (["matplotlib.backends._macosx"], {"MPLBACKEND": "macosx"}), + ]: + reason = None + missing = [dep for dep in deps if not importlib.util.find_spec(dep)] + if (sys.platform == "linux" and + not _c_internal_utils.display_is_valid()): + reason = "$DISPLAY and $WAYLAND_DISPLAY are unset" + elif missing: + reason = "{} cannot be imported".format(", ".join(missing)) + elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'): + reason = "macosx backend fails on Azure" + elif env["MPLBACKEND"].startswith('gtk'): + import gi # type: ignore + version = env["MPLBACKEND"][3] + repo = gi.Repository.get_default() + if f'{version}.0' not in repo.enumerate_versions('Gtk'): + reason = "no usable GTK bindings" + marks = [] + if reason: + marks.append(pytest.mark.skip( + reason=f"Skipping {env} because {reason}")) + elif env["MPLBACKEND"].startswith('wx') and sys.platform == 'darwin': + # ignore on OSX because that's currently broken (github #16849) + marks.append(pytest.mark.xfail(reason='github #16849')) + elif (env['MPLBACKEND'] == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and + sys.version_info[:2] < (3, 11) + ): + marks.append( # https://github.com/actions/setup-python/issues/649 + pytest.mark.xfail(reason='Tk version mismatch on Azure macOS CI')) + envs.append( + pytest.param( + {**env, 'BACKEND_DEPS': ','.join(deps)}, + marks=marks, id=str(env) + ) + ) + return envs + + +def is_ci_environment(): + # Common CI variables + ci_environment_variables = [ + 'CI', # Generic CI environment variable + 'CONTINUOUS_INTEGRATION', # Generic CI environment variable + 'TRAVIS', # Travis CI + 'CIRCLECI', # CircleCI + 'JENKINS', # Jenkins + 'GITLAB_CI', # GitLab CI + 'GITHUB_ACTIONS', # GitHub Actions + 'TEAMCITY_VERSION' # TeamCity + # Add other CI environment variables as needed + ] + + for env_var in ci_environment_variables: + if os.getenv(env_var): + return True + + return False + + +# Reasonable safe values for slower CI/Remote and local architectures. +_test_timeout = 120 if is_ci_environment() else 20 + + +def _test_toolbar_button_la_mode_icon(fig): + # test a toolbar button icon using an image in LA mode (GH issue 25174) + # create an icon in LA mode + with tempfile.TemporaryDirectory() as tempdir: + img = Image.new("LA", (26, 26)) + tmp_img_path = os.path.join(tempdir, "test_la_icon.png") + img.save(tmp_img_path) + + class CustomTool(ToolToggleBase): + image = tmp_img_path + description = "" # gtk3 backend does not allow None + + toolmanager = fig.canvas.manager.toolmanager + toolbar = fig.canvas.manager.toolbar + toolmanager.add_tool("test", CustomTool) + toolbar.add_tool("test", "group") + + +# The source of this function gets extracted and run in another process, so it +# must be fully self-contained. +# Using a timer not only allows testing of timers (on other backends), but is +# also necessary on gtk3 and wx, where directly processing a KeyEvent() for "q" +# from draw_event causes breakage as the canvas widget gets deleted too early. +def _test_interactive_impl(): + import importlib.util + import io + import json + import sys + + import pytest + + import matplotlib as mpl + from matplotlib import pyplot as plt + from matplotlib.backend_bases import KeyEvent + mpl.rcParams.update({ + "webagg.open_in_browser": False, + "webagg.port_retries": 1, + }) + + mpl.rcParams.update(json.loads(sys.argv[1])) + backend = plt.rcParams["backend"].lower() + + if backend.endswith("agg") and not backend.startswith(("gtk", "web")): + # Force interactive framework setup. + plt.figure() + + # Check that we cannot switch to a backend using another interactive + # framework, but can switch to a backend using cairo instead of agg, + # or a non-interactive backend. In the first case, we use tkagg as + # the "other" interactive backend as it is (essentially) guaranteed + # to be present. Moreover, don't test switching away from gtk3 (as + # Gtk.main_level() is not set up at this point yet) and webagg (which + # uses no interactive framework). + + if backend != "tkagg": + with pytest.raises(ImportError): + mpl.use("tkagg", force=True) + + def check_alt_backend(alt_backend): + mpl.use(alt_backend, force=True) + fig = plt.figure() + assert (type(fig.canvas).__module__ == + f"matplotlib.backends.backend_{alt_backend}") + plt.close("all") + + if importlib.util.find_spec("cairocffi"): + check_alt_backend(backend[:-3] + "cairo") + check_alt_backend("svg") + mpl.use(backend, force=True) + + fig, ax = plt.subplots() + assert type(fig.canvas).__module__ == f"matplotlib.backends.backend_{backend}" + + assert fig.canvas.manager.get_window_title() == "Figure 1" + + if mpl.rcParams["toolbar"] == "toolmanager": + # test toolbar button icon LA mode see GH issue 25174 + _test_toolbar_button_la_mode_icon(fig) + + ax.plot([0, 1], [2, 3]) + if fig.canvas.toolbar: # i.e toolbar2. + fig.canvas.toolbar.draw_rubberband(None, 1., 1, 2., 2) + + timer = fig.canvas.new_timer(1.) # Test that floats are cast to int. + timer.add_callback(KeyEvent("key_press_event", fig.canvas, "q")._process) + # Trigger quitting upon draw. + fig.canvas.mpl_connect("draw_event", lambda event: timer.start()) + fig.canvas.mpl_connect("close_event", print) + + result = io.BytesIO() + fig.savefig(result, format='png') + + plt.show() + + # Ensure that the window is really closed. + plt.pause(0.5) + + # Test that saving works after interactive window is closed, but the figure + # is not deleted. + result_after = io.BytesIO() + fig.savefig(result_after, format='png') + + if not backend.startswith('qt5') and sys.platform == 'darwin': + # FIXME: This should be enabled everywhere once Qt5 is fixed on macOS + # to not resize incorrectly. + assert result.getvalue() == result_after.getvalue() + + +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +@pytest.mark.parametrize("toolbar", ["toolbar2", "toolmanager"]) +@pytest.mark.flaky(reruns=3) +def test_interactive_backend(env, toolbar): + if env["MPLBACKEND"] == "macosx": + if toolbar == "toolmanager": + pytest.skip("toolmanager is not implemented for macosx.") + if env["MPLBACKEND"] == "wx": + pytest.skip("wx backend is deprecated; tests failed on appveyor") + try: + proc = _run_helper( + _test_interactive_impl, + json.dumps({"toolbar": toolbar}), + timeout=_test_timeout, + extra_env=env, + ) + except subprocess.CalledProcessError as err: + pytest.fail( + "Subprocess failed to test intended behavior\n" + + str(err.stderr)) + assert proc.stdout.count("CloseEvent") == 1 + + +def _test_thread_impl(): + from concurrent.futures import ThreadPoolExecutor + + import matplotlib as mpl + from matplotlib import pyplot as plt + + mpl.rcParams.update({ + "webagg.open_in_browser": False, + "webagg.port_retries": 1, + }) + + # Test artist creation and drawing does not crash from thread + # No other guarantees! + fig, ax = plt.subplots() + # plt.pause needed vs plt.show(block=False) at least on toolbar2-tkagg + plt.pause(0.5) + + future = ThreadPoolExecutor().submit(ax.plot, [1, 3, 6]) + future.result() # Joins the thread; rethrows any exception. + + fig.canvas.mpl_connect("close_event", print) + future = ThreadPoolExecutor().submit(fig.canvas.draw) + plt.pause(0.5) # flush_events fails here on at least Tkagg (bpo-41176) + future.result() # Joins the thread; rethrows any exception. + plt.close() # backend is responsible for flushing any events here + if plt.rcParams["backend"].startswith("WX"): + # TODO: debug why WX needs this only on py >= 3.8 + fig.canvas.flush_events() + + +_thread_safe_backends = _get_testable_interactive_backends() +# Known unsafe backends. Remove the xfails if they start to pass! +for param in _thread_safe_backends: + backend = param.values[0]["MPLBACKEND"] + if "cairo" in backend: + # Cairo backends save a cairo_t on the graphics context, and sharing + # these is not threadsafe. + param.marks.append( + pytest.mark.xfail(raises=subprocess.CalledProcessError)) + elif backend == "wx": + param.marks.append( + pytest.mark.xfail(raises=subprocess.CalledProcessError)) + elif backend == "macosx": + from packaging.version import parse + mac_ver = platform.mac_ver()[0] + # Note, macOS Big Sur is both 11 and 10.16, depending on SDK that + # Python was compiled against. + if mac_ver and parse(mac_ver) < parse('10.16'): + param.marks.append( + pytest.mark.xfail(raises=subprocess.TimeoutExpired, + strict=True)) + elif param.values[0].get("QT_API") == "PySide2": + param.marks.append( + pytest.mark.xfail(raises=subprocess.CalledProcessError)) + elif backend == "tkagg" and platform.python_implementation() != 'CPython': + param.marks.append( + pytest.mark.xfail( + reason='PyPy does not support Tkinter threading: ' + 'https://foss.heptapod.net/pypy/pypy/-/issues/1929', + strict=True)) + elif (backend == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and sys.version_info[:2] < (3, 11)): + param.marks.append( # https://github.com/actions/setup-python/issues/649 + pytest.mark.xfail('Tk version mismatch on Azure macOS CI')) + + +@pytest.mark.parametrize("env", _thread_safe_backends) +@pytest.mark.flaky(reruns=3) +def test_interactive_thread_safety(env): + proc = _run_helper(_test_thread_impl, timeout=_test_timeout, extra_env=env) + assert proc.stdout.count("CloseEvent") == 1 + + +def _impl_test_lazy_auto_backend_selection(): + import matplotlib + import matplotlib.pyplot as plt + # just importing pyplot should not be enough to trigger resolution + bk = matplotlib.rcParams._get('backend') + assert not isinstance(bk, str) + assert plt._backend_mod is None + # but actually plotting should + plt.plot(5) + assert plt._backend_mod is not None + bk = matplotlib.rcParams._get('backend') + assert isinstance(bk, str) + + +def test_lazy_auto_backend_selection(): + _run_helper(_impl_test_lazy_auto_backend_selection, + timeout=_test_timeout) + + +def _implqt5agg(): + import matplotlib.backends.backend_qt5agg # noqa + import sys + + assert 'PyQt6' not in sys.modules + assert 'pyside6' not in sys.modules + assert 'PyQt5' in sys.modules or 'pyside2' in sys.modules + + +def _implcairo(): + import matplotlib.backends.backend_qt5cairo # noqa + import sys + + assert 'PyQt6' not in sys.modules + assert 'pyside6' not in sys.modules + assert 'PyQt5' in sys.modules or 'pyside2' in sys.modules + + +def _implcore(): + import matplotlib.backends.backend_qt5 # noqa + import sys + + assert 'PyQt6' not in sys.modules + assert 'pyside6' not in sys.modules + assert 'PyQt5' in sys.modules or 'pyside2' in sys.modules + + +def test_qt5backends_uses_qt5(): + qt5_bindings = [ + dep for dep in ['PyQt5', 'pyside2'] + if importlib.util.find_spec(dep) is not None + ] + qt6_bindings = [ + dep for dep in ['PyQt6', 'pyside6'] + if importlib.util.find_spec(dep) is not None + ] + if len(qt5_bindings) == 0 or len(qt6_bindings) == 0: + pytest.skip('need both QT6 and QT5 bindings') + _run_helper(_implqt5agg, timeout=_test_timeout) + if importlib.util.find_spec('pycairo') is not None: + _run_helper(_implcairo, timeout=_test_timeout) + _run_helper(_implcore, timeout=_test_timeout) + + +def _impl_missing(): + import sys + # Simulate uninstalled + sys.modules["PyQt6"] = None + sys.modules["PyQt5"] = None + sys.modules["PySide2"] = None + sys.modules["PySide6"] = None + + import matplotlib.pyplot as plt + with pytest.raises(ImportError, match="Failed to import any of the following Qt"): + plt.switch_backend("qtagg") + # Specifically ensure that Pyside6/Pyqt6 are not in the error message for qt5agg + with pytest.raises(ImportError, match="^(?:(?!(PySide6|PyQt6)).)*$"): + plt.switch_backend("qt5agg") + + +def test_qt_missing(): + _run_helper(_impl_missing, timeout=_test_timeout) + + +def _impl_test_cross_Qt_imports(): + import sys + import importlib + import pytest + + _, host_binding, mpl_binding = sys.argv + # import the mpl binding. This will force us to use that binding + importlib.import_module(f'{mpl_binding}.QtCore') + mpl_binding_qwidgets = importlib.import_module(f'{mpl_binding}.QtWidgets') + import matplotlib.backends.backend_qt + host_qwidgets = importlib.import_module(f'{host_binding}.QtWidgets') + + host_app = host_qwidgets.QApplication(["mpl testing"]) + with pytest.warns(UserWarning, match="Mixing Qt major"): + matplotlib.backends.backend_qt._create_qApp() + + +def test_cross_Qt_imports(): + qt5_bindings = [ + dep for dep in ['PyQt5', 'PySide2'] + if importlib.util.find_spec(dep) is not None + ] + qt6_bindings = [ + dep for dep in ['PyQt6', 'PySide6'] + if importlib.util.find_spec(dep) is not None + ] + if len(qt5_bindings) == 0 or len(qt6_bindings) == 0: + pytest.skip('need both QT6 and QT5 bindings') + + for qt5 in qt5_bindings: + for qt6 in qt6_bindings: + for pair in ([qt5, qt6], [qt6, qt5]): + try: + _run_helper(_impl_test_cross_Qt_imports, + *pair, + timeout=_test_timeout) + except subprocess.CalledProcessError as ex: + # if segfault, carry on. We do try to warn the user they + # are doing something that we do not expect to work + if ex.returncode == -signal.SIGSEGV: + continue + # We got the abort signal which is likely because the Qt5 / + # Qt6 cross import is unhappy, carry on. + elif ex.returncode == -signal.SIGABRT: + continue + raise + + +@pytest.mark.skipif('TF_BUILD' in os.environ, + reason="this test fails an azure for unknown reasons") +@pytest.mark.skipif(sys.platform == "win32", reason="Cannot send SIGINT on Windows.") +def test_webagg(): + pytest.importorskip("tornado") + proc = subprocess.Popen( + [sys.executable, "-c", + inspect.getsource(_test_interactive_impl) + + "\n_test_interactive_impl()", "{}"], + env={**os.environ, "MPLBACKEND": "webagg", "SOURCE_DATE_EPOCH": "0"}) + url = f'http://{mpl.rcParams["webagg.address"]}:{mpl.rcParams["webagg.port"]}' + timeout = time.perf_counter() + _test_timeout + try: + while True: + try: + retcode = proc.poll() + # check that the subprocess for the server is not dead + assert retcode is None + conn = urllib.request.urlopen(url) + break + except urllib.error.URLError: + if time.perf_counter() > timeout: + pytest.fail("Failed to connect to the webagg server.") + else: + continue + conn.close() + proc.send_signal(signal.SIGINT) + assert proc.wait(timeout=_test_timeout) == 0 + finally: + if proc.poll() is None: + proc.kill() + + +def _lazy_headless(): + import os + import sys + + backend, deps = sys.argv[1:] + deps = deps.split(',') + + # make it look headless + os.environ.pop('DISPLAY', None) + os.environ.pop('WAYLAND_DISPLAY', None) + for dep in deps: + assert dep not in sys.modules + + # we should fast-track to Agg + import matplotlib.pyplot as plt + assert plt.get_backend() == 'agg' + for dep in deps: + assert dep not in sys.modules + + # make sure we really have dependencies installed + for dep in deps: + importlib.import_module(dep) + assert dep in sys.modules + + # try to switch and make sure we fail with ImportError + try: + plt.switch_backend(backend) + except ImportError: + pass + else: + sys.exit(1) + + +@pytest.mark.skipif(sys.platform != "linux", reason="this a linux-only test") +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +def test_lazy_linux_headless(env): + proc = _run_helper( + _lazy_headless, + env.pop('MPLBACKEND'), env.pop("BACKEND_DEPS"), + timeout=_test_timeout, + extra_env={**env, 'DISPLAY': '', 'WAYLAND_DISPLAY': ''} + ) + + +def _test_number_of_draws_script(): + import matplotlib.pyplot as plt + + fig, ax = plt.subplots() + + # animated=True tells matplotlib to only draw the artist when we + # explicitly request it + ln, = ax.plot([0, 1], [1, 2], animated=True) + + # make sure the window is raised, but the script keeps going + plt.show(block=False) + plt.pause(0.3) + # Connect to draw_event to count the occurrences + fig.canvas.mpl_connect('draw_event', print) + + # get copy of entire figure (everything inside fig.bbox) + # sans animated artist + bg = fig.canvas.copy_from_bbox(fig.bbox) + # draw the animated artist, this uses a cached renderer + ax.draw_artist(ln) + # show the result to the screen + fig.canvas.blit(fig.bbox) + + for j in range(10): + # reset the background back in the canvas state, screen unchanged + fig.canvas.restore_region(bg) + # Create a **new** artist here, this is poor usage of blitting + # but good for testing to make sure that this doesn't create + # excessive draws + ln, = ax.plot([0, 1], [1, 2]) + # render the artist, updating the canvas state, but not the screen + ax.draw_artist(ln) + # copy the image to the GUI state, but screen might not changed yet + fig.canvas.blit(fig.bbox) + # flush any pending GUI events, re-painting the screen if needed + fig.canvas.flush_events() + + # Let the event loop process everything before leaving + plt.pause(0.1) + + +_blit_backends = _get_testable_interactive_backends() +for param in _blit_backends: + backend = param.values[0]["MPLBACKEND"] + if backend == "gtk3cairo": + # copy_from_bbox only works when rendering to an ImageSurface + param.marks.append( + pytest.mark.skip("gtk3cairo does not support blitting")) + elif backend == "gtk4cairo": + # copy_from_bbox only works when rendering to an ImageSurface + param.marks.append( + pytest.mark.skip("gtk4cairo does not support blitting")) + elif backend == "wx": + param.marks.append( + pytest.mark.skip("wx does not support blitting")) + elif (backend == 'tkagg' and + ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and + sys.platform == 'darwin' and + sys.version_info[:2] < (3, 11) + ): + param.marks.append( # https://github.com/actions/setup-python/issues/649 + pytest.mark.xfail('Tk version mismatch on Azure macOS CI') + ) + + +@pytest.mark.parametrize("env", _blit_backends) +# subprocesses can struggle to get the display, so rerun a few times +@pytest.mark.flaky(reruns=4) +def test_blitting_events(env): + proc = _run_helper( + _test_number_of_draws_script, timeout=_test_timeout, extra_env=env) + # Count the number of draw_events we got. We could count some initial + # canvas draws (which vary in number by backend), but the critical + # check here is that it isn't 10 draws, which would be called if + # blitting is not properly implemented + ndraws = proc.stdout.count("DrawEvent") + assert 0 < ndraws < 5 + + +# The source of this function gets extracted and run in another process, so it +# must be fully self-contained. +def _test_figure_leak(): + import gc + import sys + + import psutil + from matplotlib import pyplot as plt + # Second argument is pause length, but if zero we should skip pausing + t = float(sys.argv[1]) + p = psutil.Process() + + # Warmup cycle, this reasonably allocates a lot + for _ in range(2): + fig = plt.figure() + if t: + plt.pause(t) + plt.close(fig) + mem = p.memory_info().rss + gc.collect() + + for _ in range(5): + fig = plt.figure() + if t: + plt.pause(t) + plt.close(fig) + gc.collect() + growth = p.memory_info().rss - mem + + print(growth) + + +# TODO: "0.1" memory threshold could be reduced 10x by fixing tkagg +@pytest.mark.skipif(sys.platform == "win32", + reason="appveyor tests fail; gh-22988 suggests reworking") +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +@pytest.mark.parametrize("time_mem", [(0.0, 2_000_000), (0.1, 30_000_000)]) +def test_figure_leak_20490(env, time_mem, request): + pytest.importorskip("psutil", reason="psutil needed to run this test") + + # We haven't yet directly identified the leaks so test with a memory growth + # threshold. + pause_time, acceptable_memory_leakage = time_mem + if env["MPLBACKEND"] == "wx": + pytest.skip("wx backend is deprecated; tests failed on appveyor") + + if env["MPLBACKEND"] == "macosx": + request.node.add_marker(pytest.mark.xfail(reason="macosx backend is leaky")) + + if env["MPLBACKEND"] == "tkagg" and sys.platform == "darwin": + acceptable_memory_leakage += 11_000_000 + + result = _run_helper( + _test_figure_leak, str(pause_time), + timeout=_test_timeout, extra_env=env) + + growth = int(result.stdout) + assert growth <= acceptable_memory_leakage + + +def _impl_test_interactive_timers(): + # A timer with <1 millisecond gets converted to int and therefore 0 + # milliseconds, which the mac framework interprets as singleshot. + # We only want singleshot if we specify that ourselves, otherwise we want + # a repeating timer + import os + from unittest.mock import Mock + import matplotlib.pyplot as plt + # increase pause duration on CI to let things spin up + # particularly relevant for gtk3cairo + pause_time = 2 if os.getenv("CI") else 0.5 + fig = plt.figure() + plt.pause(pause_time) + timer = fig.canvas.new_timer(0.1) + mock = Mock() + timer.add_callback(mock) + timer.start() + plt.pause(pause_time) + timer.stop() + assert mock.call_count > 1 + + # Now turn it into a single shot timer and verify only one gets triggered + mock.call_count = 0 + timer.single_shot = True + timer.start() + plt.pause(pause_time) + assert mock.call_count == 1 + + # Make sure we can start the timer a second time + timer.start() + plt.pause(pause_time) + assert mock.call_count == 2 + plt.close("all") + + +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +def test_interactive_timers(env): + if env["MPLBACKEND"] == "gtk3cairo" and os.getenv("CI"): + pytest.skip("gtk3cairo timers do not work in remote CI") + if env["MPLBACKEND"] == "wx": + pytest.skip("wx backend is deprecated; tests failed on appveyor") + _run_helper(_impl_test_interactive_timers, + timeout=_test_timeout, extra_env=env) + + +def _test_sigint_impl(backend, target_name, kwargs): + import sys + import matplotlib.pyplot as plt + import os + import threading + + plt.switch_backend(backend) + + def interrupter(): + if sys.platform == 'win32': + import win32api + win32api.GenerateConsoleCtrlEvent(0, 0) + else: + import signal + os.kill(os.getpid(), signal.SIGINT) + + target = getattr(plt, target_name) + timer = threading.Timer(1, interrupter) + fig = plt.figure() + fig.canvas.mpl_connect( + 'draw_event', + lambda *args: print('DRAW', flush=True) + ) + fig.canvas.mpl_connect( + 'draw_event', + lambda *args: timer.start() + ) + try: + target(**kwargs) + except KeyboardInterrupt: + print('SUCCESS', flush=True) + + +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +@pytest.mark.parametrize("target, kwargs", [ + ('show', {'block': True}), + ('pause', {'interval': 10}) +]) +def test_sigint(env, target, kwargs): + backend = env.get("MPLBACKEND") + if not backend.startswith(("qt", "macosx")): + pytest.skip("SIGINT currently only tested on qt and macosx") + proc = _WaitForStringPopen( + [sys.executable, "-c", + inspect.getsource(_test_sigint_impl) + + f"\n_test_sigint_impl({backend!r}, {target!r}, {kwargs!r})"]) + try: + proc.wait_for('DRAW') + stdout, _ = proc.communicate(timeout=_test_timeout) + except Exception: + proc.kill() + stdout, _ = proc.communicate() + raise + assert 'SUCCESS' in stdout + + +def _test_other_signal_before_sigint_impl(backend, target_name, kwargs): + import signal + import matplotlib.pyplot as plt + + plt.switch_backend(backend) + + target = getattr(plt, target_name) + + fig = plt.figure() + fig.canvas.mpl_connect('draw_event', lambda *args: print('DRAW', flush=True)) + + timer = fig.canvas.new_timer(interval=1) + timer.single_shot = True + timer.add_callback(print, 'SIGUSR1', flush=True) + + def custom_signal_handler(signum, frame): + timer.start() + signal.signal(signal.SIGUSR1, custom_signal_handler) + + try: + target(**kwargs) + except KeyboardInterrupt: + print('SUCCESS', flush=True) + + +@pytest.mark.skipif(sys.platform == 'win32', + reason='No other signal available to send on Windows') +@pytest.mark.parametrize("env", _get_testable_interactive_backends()) +@pytest.mark.parametrize("target, kwargs", [ + ('show', {'block': True}), + ('pause', {'interval': 10}) +]) +def test_other_signal_before_sigint(env, target, kwargs, request): + backend = env.get("MPLBACKEND") + if not backend.startswith(("qt", "macosx")): + pytest.skip("SIGINT currently only tested on qt and macosx") + if backend == "macosx": + request.node.add_marker(pytest.mark.xfail(reason="macosx backend is buggy")) + proc = _WaitForStringPopen( + [sys.executable, "-c", + inspect.getsource(_test_other_signal_before_sigint_impl) + + "\n_test_other_signal_before_sigint_impl(" + f"{backend!r}, {target!r}, {kwargs!r})"]) + try: + proc.wait_for('DRAW') + os.kill(proc.pid, signal.SIGUSR1) + proc.wait_for('SIGUSR1') + os.kill(proc.pid, signal.SIGINT) + stdout, _ = proc.communicate(timeout=_test_timeout) + except Exception: + proc.kill() + stdout, _ = proc.communicate() + raise + print(stdout) + assert 'SUCCESS' in stdout diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_basic.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_basic.py new file mode 100644 index 00000000..6fad2bac --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_basic.py @@ -0,0 +1,46 @@ +import builtins +import os +import subprocess +import sys +import textwrap + + +def test_simple(): + assert 1 + 1 == 2 + + +def test_override_builtins(): + import pylab # type: ignore + ok_to_override = { + '__name__', + '__doc__', + '__package__', + '__loader__', + '__spec__', + 'any', + 'all', + 'sum', + 'divmod' + } + overridden = {key for key in {*dir(pylab)} & {*dir(builtins)} + if getattr(pylab, key) != getattr(builtins, key)} + assert overridden <= ok_to_override + + +def test_lazy_imports(): + source = textwrap.dedent(""" + import sys + + import matplotlib.figure + import matplotlib.backend_bases + import matplotlib.pyplot + + assert 'matplotlib._tri' not in sys.modules + assert 'matplotlib._qhull' not in sys.modules + assert 'matplotlib._contour' not in sys.modules + assert 'urllib.request' not in sys.modules + """) + + subprocess.check_call( + [sys.executable, '-c', source], + env={**os.environ, "MPLBACKEND": "", "MATPLOTLIBRC": os.devnull}) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_bbox_tight.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_bbox_tight.py new file mode 100644 index 00000000..4d4624e1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_bbox_tight.py @@ -0,0 +1,174 @@ +from io import BytesIO + +import numpy as np + +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +import matplotlib.path as mpath +import matplotlib.patches as mpatches +from matplotlib.ticker import FuncFormatter + + +@image_comparison(['bbox_inches_tight'], remove_text=True, + savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight(): + #: Test that a figure saved using bbox_inches='tight' is clipped correctly + data = [[66386, 174296, 75131, 577908, 32015], + [58230, 381139, 78045, 99308, 160454], + [89135, 80552, 152558, 497981, 603535], + [78415, 81858, 150656, 193263, 69638], + [139361, 331509, 343164, 781380, 52269]] + + col_labels = row_labels = [''] * 5 + + rows = len(data) + ind = np.arange(len(col_labels)) + 0.3 # the x locations for the groups + cell_text = [] + width = 0.4 # the width of the bars + yoff = np.zeros(len(col_labels)) + # the bottom values for stacked bar chart + fig, ax = plt.subplots(1, 1) + for row in range(rows): + ax.bar(ind, data[row], width, bottom=yoff, align='edge', color='b') + yoff = yoff + data[row] + cell_text.append(['']) + plt.xticks([]) + plt.xlim(0, 5) + plt.legend([''] * 5, loc=(1.2, 0.2)) + fig.legend([''] * 5, bbox_to_anchor=(0, 0.2), loc='lower left') + # Add a table at the bottom of the axes + cell_text.reverse() + plt.table(cellText=cell_text, rowLabels=row_labels, colLabels=col_labels, + loc='bottom') + + +@image_comparison(['bbox_inches_tight_suptile_legend'], + savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight_suptile_legend(): + plt.plot(np.arange(10), label='a straight line') + plt.legend(bbox_to_anchor=(0.9, 1), loc='upper left') + plt.title('Axis title') + plt.suptitle('Figure title') + + # put an extra long y tick on to see that the bbox is accounted for + def y_formatter(y, pos): + if int(y) == 4: + return 'The number 4' + else: + return str(y) + plt.gca().yaxis.set_major_formatter(FuncFormatter(y_formatter)) + + plt.xlabel('X axis') + + +@image_comparison(['bbox_inches_tight_suptile_non_default.png'], + savefig_kwarg={'bbox_inches': 'tight'}, + tol=0.1) # large tolerance because only testing clipping. +def test_bbox_inches_tight_suptitle_non_default(): + fig, ax = plt.subplots() + fig.suptitle('Booo', x=0.5, y=1.1) + + +@image_comparison(['bbox_inches_tight_layout.png'], remove_text=True, + style='mpl20', + savefig_kwarg=dict(bbox_inches='tight', pad_inches='layout')) +def test_bbox_inches_tight_layout_constrained(): + fig, ax = plt.subplots(layout='constrained') + fig.get_layout_engine().set(h_pad=0.5) + ax.set_aspect('equal') + + +def test_bbox_inches_tight_layout_notconstrained(tmp_path): + # pad_inches='layout' should be ignored when not using constrained/ + # compressed layout. Smoke test that savefig doesn't error in this case. + fig, ax = plt.subplots() + fig.savefig(tmp_path / 'foo.png', bbox_inches='tight', pad_inches='layout') + + +@image_comparison(['bbox_inches_tight_clipping'], + remove_text=True, savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight_clipping(): + # tests bbox clipping on scatter points, and path clipping on a patch + # to generate an appropriately tight bbox + plt.scatter(np.arange(10), np.arange(10)) + ax = plt.gca() + ax.set_xlim(0, 5) + ax.set_ylim(0, 5) + + # make a massive rectangle and clip it with a path + patch = mpatches.Rectangle([-50, -50], 100, 100, + transform=ax.transData, + facecolor='blue', alpha=0.5) + + path = mpath.Path.unit_regular_star(5).deepcopy() + path.vertices *= 0.25 + patch.set_clip_path(path, transform=ax.transAxes) + plt.gcf().artists.append(patch) + + +@image_comparison(['bbox_inches_tight_raster'], + remove_text=True, savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight_raster(): + """Test rasterization with tight_layout""" + fig, ax = plt.subplots() + ax.plot([1.0, 2.0], rasterized=True) + + +def test_only_on_non_finite_bbox(): + fig, ax = plt.subplots() + ax.annotate("", xy=(0, float('nan'))) + ax.set_axis_off() + # we only need to test that it does not error out on save + fig.savefig(BytesIO(), bbox_inches='tight', format='png') + + +def test_tight_pcolorfast(): + fig, ax = plt.subplots() + ax.pcolorfast(np.arange(4).reshape((2, 2))) + ax.set(ylim=(0, .1)) + buf = BytesIO() + fig.savefig(buf, bbox_inches="tight") + buf.seek(0) + height, width, _ = plt.imread(buf).shape + # Previously, the bbox would include the area of the image clipped out by + # the axes, resulting in a very tall image given the y limits of (0, 0.1). + assert width > height + + +def test_noop_tight_bbox(): + from PIL import Image + x_size, y_size = (10, 7) + dpi = 100 + # make the figure just the right size up front + fig = plt.figure(frameon=False, dpi=dpi, figsize=(x_size/dpi, y_size/dpi)) + ax = plt.Axes(fig, [0., 0., 1., 1.]) + fig.add_axes(ax) + ax.set_axis_off() + ax.xaxis.set_visible(False) + ax.yaxis.set_visible(False) + + data = np.arange(x_size * y_size).reshape(y_size, x_size) + ax.imshow(data, rasterized=True) + + # When a rasterized Artist is included, a mixed-mode renderer does + # additional bbox adjustment. It should also be a no-op, and not affect the + # next save. + fig.savefig(BytesIO(), bbox_inches='tight', pad_inches=0, format='pdf') + + out = BytesIO() + fig.savefig(out, bbox_inches='tight', pad_inches=0) + out.seek(0) + im = np.asarray(Image.open(out)) + assert (im[:, :, 3] == 255).all() + assert not (im[:, :, :3] == 255).all() + assert im.shape == (7, 10, 4) + + +@image_comparison(['bbox_inches_fixed_aspect'], extensions=['png'], + remove_text=True, savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_fixed_aspect(): + with plt.rc_context({'figure.constrained_layout.use': True}): + fig, ax = plt.subplots() + ax.plot([0, 1]) + ax.set_xlim(0, 1) + ax.set_aspect('equal') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_category.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_category.py new file mode 100644 index 00000000..fd4aec88 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_category.py @@ -0,0 +1,323 @@ +"""Catch all for categorical functions""" +import warnings + +import pytest +import numpy as np + +import matplotlib as mpl +from matplotlib.axes import Axes +import matplotlib.pyplot as plt +import matplotlib.category as cat +from matplotlib.testing.decorators import check_figures_equal + + +class TestUnitData: + test_cases = [('single', (["hello world"], [0])), + ('unicode', (["Здравствуйте мир"], [0])), + ('mixed', (['A', "np.nan", 'B', "3.14", "мир"], + [0, 1, 2, 3, 4]))] + ids, data = zip(*test_cases) + + @pytest.mark.parametrize("data, locs", data, ids=ids) + def test_unit(self, data, locs): + unit = cat.UnitData(data) + assert list(unit._mapping.keys()) == data + assert list(unit._mapping.values()) == locs + + def test_update(self): + data = ['a', 'd'] + locs = [0, 1] + + data_update = ['b', 'd', 'e'] + unique_data = ['a', 'd', 'b', 'e'] + updated_locs = [0, 1, 2, 3] + + unit = cat.UnitData(data) + assert list(unit._mapping.keys()) == data + assert list(unit._mapping.values()) == locs + + unit.update(data_update) + assert list(unit._mapping.keys()) == unique_data + assert list(unit._mapping.values()) == updated_locs + + failing_test_cases = [("number", 3.14), ("nan", np.nan), + ("list", [3.14, 12]), ("mixed type", ["A", 2])] + + fids, fdata = zip(*test_cases) + + @pytest.mark.parametrize("fdata", fdata, ids=fids) + def test_non_string_fails(self, fdata): + with pytest.raises(TypeError): + cat.UnitData(fdata) + + @pytest.mark.parametrize("fdata", fdata, ids=fids) + def test_non_string_update_fails(self, fdata): + unitdata = cat.UnitData() + with pytest.raises(TypeError): + unitdata.update(fdata) + + +class FakeAxis: + def __init__(self, units): + self.units = units + + +class TestStrCategoryConverter: + """ + Based on the pandas conversion and factorization tests: + + ref: /pandas/tseries/tests/test_converter.py + /pandas/tests/test_algos.py:TestFactorize + """ + test_cases = [("unicode", ["Здравствуйте мир"]), + ("ascii", ["hello world"]), + ("single", ['a', 'b', 'c']), + ("integer string", ["1", "2"]), + ("single + values>10", ["A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", + "O", "P", "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z"])] + + ids, values = zip(*test_cases) + + failing_test_cases = [("mixed", [3.14, 'A', np.inf]), + ("string integer", ['42', 42])] + + fids, fvalues = zip(*failing_test_cases) + + @pytest.fixture(autouse=True) + def mock_axis(self, request): + self.cc = cat.StrCategoryConverter() + # self.unit should be probably be replaced with real mock unit + self.unit = cat.UnitData() + self.ax = FakeAxis(self.unit) + + @pytest.mark.parametrize("vals", values, ids=ids) + def test_convert(self, vals): + np.testing.assert_allclose(self.cc.convert(vals, self.ax.units, + self.ax), + range(len(vals))) + + @pytest.mark.parametrize("value", ["hi", "мир"], ids=["ascii", "unicode"]) + def test_convert_one_string(self, value): + assert self.cc.convert(value, self.unit, self.ax) == 0 + + @pytest.mark.parametrize("fvals", fvalues, ids=fids) + def test_convert_fail(self, fvals): + with pytest.raises(TypeError): + self.cc.convert(fvals, self.unit, self.ax) + + def test_axisinfo(self): + axis = self.cc.axisinfo(self.unit, self.ax) + assert isinstance(axis.majloc, cat.StrCategoryLocator) + assert isinstance(axis.majfmt, cat.StrCategoryFormatter) + + def test_default_units(self): + assert isinstance(self.cc.default_units(["a"], self.ax), cat.UnitData) + + +PLOT_LIST = [Axes.scatter, Axes.plot, Axes.bar] +PLOT_IDS = ["scatter", "plot", "bar"] + + +class TestStrCategoryLocator: + def test_StrCategoryLocator(self): + locs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + unit = cat.UnitData([str(j) for j in locs]) + ticks = cat.StrCategoryLocator(unit._mapping) + np.testing.assert_array_equal(ticks.tick_values(None, None), locs) + + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_StrCategoryLocatorPlot(self, plotter): + ax = plt.figure().subplots() + plotter(ax, [1, 2, 3], ["a", "b", "c"]) + np.testing.assert_array_equal(ax.yaxis.major.locator(), range(3)) + + +class TestStrCategoryFormatter: + test_cases = [("ascii", ["hello", "world", "hi"]), + ("unicode", ["Здравствуйте", "привет"])] + + ids, cases = zip(*test_cases) + + @pytest.mark.parametrize("ydata", cases, ids=ids) + def test_StrCategoryFormatter(self, ydata): + unit = cat.UnitData(ydata) + labels = cat.StrCategoryFormatter(unit._mapping) + for i, d in enumerate(ydata): + assert labels(i, i) == d + assert labels(i, None) == d + + @pytest.mark.parametrize("ydata", cases, ids=ids) + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_StrCategoryFormatterPlot(self, ydata, plotter): + ax = plt.figure().subplots() + plotter(ax, range(len(ydata)), ydata) + for i, d in enumerate(ydata): + assert ax.yaxis.major.formatter(i) == d + assert ax.yaxis.major.formatter(i+1) == "" + + +def axis_test(axis, labels): + ticks = list(range(len(labels))) + np.testing.assert_array_equal(axis.get_majorticklocs(), ticks) + graph_labels = [axis.major.formatter(i, i) for i in ticks] + # _text also decodes bytes as utf-8. + assert graph_labels == [cat.StrCategoryFormatter._text(l) for l in labels] + assert list(axis.units._mapping.keys()) == [l for l in labels] + assert list(axis.units._mapping.values()) == ticks + + +class TestPlotBytes: + bytes_cases = [('string list', ['a', 'b', 'c']), + ('bytes list', [b'a', b'b', b'c']), + ('bytes ndarray', np.array([b'a', b'b', b'c']))] + + bytes_ids, bytes_data = zip(*bytes_cases) + + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + @pytest.mark.parametrize("bdata", bytes_data, ids=bytes_ids) + def test_plot_bytes(self, plotter, bdata): + ax = plt.figure().subplots() + counts = np.array([4, 6, 5]) + plotter(ax, bdata, counts) + axis_test(ax.xaxis, bdata) + + +class TestPlotNumlike: + numlike_cases = [('string list', ['1', '11', '3']), + ('string ndarray', np.array(['1', '11', '3'])), + ('bytes list', [b'1', b'11', b'3']), + ('bytes ndarray', np.array([b'1', b'11', b'3']))] + numlike_ids, numlike_data = zip(*numlike_cases) + + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + @pytest.mark.parametrize("ndata", numlike_data, ids=numlike_ids) + def test_plot_numlike(self, plotter, ndata): + ax = plt.figure().subplots() + counts = np.array([4, 6, 5]) + plotter(ax, ndata, counts) + axis_test(ax.xaxis, ndata) + + +class TestPlotTypes: + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_plot_unicode(self, plotter): + ax = plt.figure().subplots() + words = ['Здравствуйте', 'привет'] + plotter(ax, words, [0, 1]) + axis_test(ax.xaxis, words) + + @pytest.fixture + def test_data(self): + self.x = ["hello", "happy", "world"] + self.xy = [2, 6, 3] + self.y = ["Python", "is", "fun"] + self.yx = [3, 4, 5] + + @pytest.mark.usefixtures("test_data") + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_plot_xaxis(self, test_data, plotter): + ax = plt.figure().subplots() + plotter(ax, self.x, self.xy) + axis_test(ax.xaxis, self.x) + + @pytest.mark.usefixtures("test_data") + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_plot_yaxis(self, test_data, plotter): + ax = plt.figure().subplots() + plotter(ax, self.yx, self.y) + axis_test(ax.yaxis, self.y) + + @pytest.mark.usefixtures("test_data") + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_plot_xyaxis(self, test_data, plotter): + ax = plt.figure().subplots() + plotter(ax, self.x, self.y) + axis_test(ax.xaxis, self.x) + axis_test(ax.yaxis, self.y) + + @pytest.mark.parametrize("plotter", PLOT_LIST, ids=PLOT_IDS) + def test_update_plot(self, plotter): + ax = plt.figure().subplots() + plotter(ax, ['a', 'b'], ['e', 'g']) + plotter(ax, ['a', 'b', 'd'], ['f', 'a', 'b']) + plotter(ax, ['b', 'c', 'd'], ['g', 'e', 'd']) + axis_test(ax.xaxis, ['a', 'b', 'd', 'c']) + axis_test(ax.yaxis, ['e', 'g', 'f', 'a', 'b', 'd']) + + failing_test_cases = [("mixed", ['A', 3.14]), + ("number integer", ['1', 1]), + ("string integer", ['42', 42]), + ("missing", ['12', np.nan])] + + fids, fvalues = zip(*failing_test_cases) + + plotters = [Axes.scatter, Axes.bar, + pytest.param(Axes.plot, marks=pytest.mark.xfail)] + + @pytest.mark.parametrize("plotter", plotters) + @pytest.mark.parametrize("xdata", fvalues, ids=fids) + def test_mixed_type_exception(self, plotter, xdata): + ax = plt.figure().subplots() + with pytest.raises(TypeError): + plotter(ax, xdata, [1, 2]) + + @pytest.mark.parametrize("plotter", plotters) + @pytest.mark.parametrize("xdata", fvalues, ids=fids) + def test_mixed_type_update_exception(self, plotter, xdata): + ax = plt.figure().subplots() + with pytest.raises(TypeError): + plotter(ax, [0, 3], [1, 3]) + plotter(ax, xdata, [1, 2]) + + +@mpl.style.context('default') +@check_figures_equal(extensions=["png"]) +def test_overriding_units_in_plot(fig_test, fig_ref): + from datetime import datetime + + t0 = datetime(2018, 3, 1) + t1 = datetime(2018, 3, 2) + t2 = datetime(2018, 3, 3) + t3 = datetime(2018, 3, 4) + + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + for ax, kwargs in zip([ax_test, ax_ref], + ({}, dict(xunits=None, yunits=None))): + # First call works + ax.plot([t0, t1], ["V1", "V2"], **kwargs) + x_units = ax.xaxis.units + y_units = ax.yaxis.units + # this should not raise + ax.plot([t2, t3], ["V1", "V2"], **kwargs) + # assert that we have not re-set the units attribute at all + assert x_units is ax.xaxis.units + assert y_units is ax.yaxis.units + + +def test_no_deprecation_on_empty_data(): + """ + Smoke test to check that no deprecation warning is emitted. See #22640. + """ + f, ax = plt.subplots() + ax.xaxis.update_units(["a", "b"]) + ax.plot([], []) + + +def test_hist(): + fig, ax = plt.subplots() + n, bins, patches = ax.hist(['a', 'b', 'a', 'c', 'ff']) + assert n.shape == (10,) + np.testing.assert_allclose(n, [2., 0., 0., 1., 0., 0., 1., 0., 0., 1.]) + + +def test_set_lim(): + # Numpy 1.25 deprecated casting [2.] to float, catch_warnings added to error + # with numpy 1.25 and prior to the change from gh-26597 + # can be removed once the minimum numpy version has expired the warning + f, ax = plt.subplots() + ax.plot(["a", "b", "c", "d"], [1, 2, 3, 4]) + with warnings.catch_warnings(): + ax.set_xlim("b", "c") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cbook.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cbook.py new file mode 100644 index 00000000..1f4f9632 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cbook.py @@ -0,0 +1,940 @@ +from __future__ import annotations + +import itertools +import pickle + +from typing import Any +from unittest.mock import patch, Mock + +from datetime import datetime, date, timedelta + +import numpy as np +from numpy.testing import (assert_array_equal, assert_approx_equal, + assert_array_almost_equal) +import pytest + +from matplotlib import _api, cbook +import matplotlib.colors as mcolors +from matplotlib.cbook import delete_masked_points, strip_math + + +class Test_delete_masked_points: + def test_bad_first_arg(self): + with pytest.raises(ValueError): + delete_masked_points('a string', np.arange(1.0, 7.0)) + + def test_string_seq(self): + a1 = ['a', 'b', 'c', 'd', 'e', 'f'] + a2 = [1, 2, 3, np.nan, np.nan, 6] + result1, result2 = delete_masked_points(a1, a2) + ind = [0, 1, 2, 5] + assert_array_equal(result1, np.array(a1)[ind]) + assert_array_equal(result2, np.array(a2)[ind]) + + def test_datetime(self): + dates = [datetime(2008, 1, 1), datetime(2008, 1, 2), + datetime(2008, 1, 3), datetime(2008, 1, 4), + datetime(2008, 1, 5), datetime(2008, 1, 6)] + a_masked = np.ma.array([1, 2, 3, np.nan, np.nan, 6], + mask=[False, False, True, True, False, False]) + actual = delete_masked_points(dates, a_masked) + ind = [0, 1, 5] + assert_array_equal(actual[0], np.array(dates)[ind]) + assert_array_equal(actual[1], a_masked[ind].compressed()) + + def test_rgba(self): + a_masked = np.ma.array([1, 2, 3, np.nan, np.nan, 6], + mask=[False, False, True, True, False, False]) + a_rgba = mcolors.to_rgba_array(['r', 'g', 'b', 'c', 'm', 'y']) + actual = delete_masked_points(a_masked, a_rgba) + ind = [0, 1, 5] + assert_array_equal(actual[0], a_masked[ind].compressed()) + assert_array_equal(actual[1], a_rgba[ind]) + + +class Test_boxplot_stats: + def setup_method(self): + np.random.seed(937) + self.nrows = 37 + self.ncols = 4 + self.data = np.random.lognormal(size=(self.nrows, self.ncols), + mean=1.5, sigma=1.75) + self.known_keys = sorted([ + 'mean', 'med', 'q1', 'q3', 'iqr', + 'cilo', 'cihi', 'whislo', 'whishi', + 'fliers', 'label' + ]) + self.std_results = cbook.boxplot_stats(self.data) + + self.known_nonbootstrapped_res = { + 'cihi': 6.8161283264444847, + 'cilo': -0.1489815330368689, + 'iqr': 13.492709959447094, + 'mean': 13.00447442387868, + 'med': 3.3335733967038079, + 'fliers': np.array([ + 92.55467075, 87.03819018, 42.23204914, 39.29390996 + ]), + 'q1': 1.3597529879465153, + 'q3': 14.85246294739361, + 'whishi': 27.899688243699629, + 'whislo': 0.042143774965502923 + } + + self.known_bootstrapped_ci = { + 'cihi': 8.939577523357828, + 'cilo': 1.8692703958676578, + } + + self.known_whis3_res = { + 'whishi': 42.232049135969874, + 'whislo': 0.042143774965502923, + 'fliers': np.array([92.55467075, 87.03819018]), + } + + self.known_res_percentiles = { + 'whislo': 0.1933685896907924, + 'whishi': 42.232049135969874 + } + + self.known_res_range = { + 'whislo': 0.042143774965502923, + 'whishi': 92.554670752188699 + + } + + def test_form_main_list(self): + assert isinstance(self.std_results, list) + + def test_form_each_dict(self): + for res in self.std_results: + assert isinstance(res, dict) + + def test_form_dict_keys(self): + for res in self.std_results: + assert set(res) <= set(self.known_keys) + + def test_results_baseline(self): + res = self.std_results[0] + for key, value in self.known_nonbootstrapped_res.items(): + assert_array_almost_equal(res[key], value) + + def test_results_bootstrapped(self): + results = cbook.boxplot_stats(self.data, bootstrap=10000) + res = results[0] + for key, value in self.known_bootstrapped_ci.items(): + assert_approx_equal(res[key], value) + + def test_results_whiskers_float(self): + results = cbook.boxplot_stats(self.data, whis=3) + res = results[0] + for key, value in self.known_whis3_res.items(): + assert_array_almost_equal(res[key], value) + + def test_results_whiskers_range(self): + results = cbook.boxplot_stats(self.data, whis=[0, 100]) + res = results[0] + for key, value in self.known_res_range.items(): + assert_array_almost_equal(res[key], value) + + def test_results_whiskers_percentiles(self): + results = cbook.boxplot_stats(self.data, whis=[5, 95]) + res = results[0] + for key, value in self.known_res_percentiles.items(): + assert_array_almost_equal(res[key], value) + + def test_results_withlabels(self): + labels = ['Test1', 2, 'Aardvark', 4] + results = cbook.boxplot_stats(self.data, labels=labels) + for lab, res in zip(labels, results): + assert res['label'] == lab + + results = cbook.boxplot_stats(self.data) + for res in results: + assert 'label' not in res + + def test_label_error(self): + labels = [1, 2] + with pytest.raises(ValueError): + cbook.boxplot_stats(self.data, labels=labels) + + def test_bad_dims(self): + data = np.random.normal(size=(34, 34, 34)) + with pytest.raises(ValueError): + cbook.boxplot_stats(data) + + def test_boxplot_stats_autorange_false(self): + x = np.zeros(shape=140) + x = np.hstack([-25, x, 25]) + bstats_false = cbook.boxplot_stats(x, autorange=False) + bstats_true = cbook.boxplot_stats(x, autorange=True) + + assert bstats_false[0]['whislo'] == 0 + assert bstats_false[0]['whishi'] == 0 + assert_array_almost_equal(bstats_false[0]['fliers'], [-25, 25]) + + assert bstats_true[0]['whislo'] == -25 + assert bstats_true[0]['whishi'] == 25 + assert_array_almost_equal(bstats_true[0]['fliers'], []) + + +class Test_callback_registry: + def setup_method(self): + self.signal = 'test' + self.callbacks = cbook.CallbackRegistry() + + def connect(self, s, func, pickle): + if pickle: + return self.callbacks.connect(s, func) + else: + return self.callbacks._connect_picklable(s, func) + + def disconnect(self, cid): + return self.callbacks.disconnect(cid) + + def count(self): + count1 = len(self.callbacks._func_cid_map.get(self.signal, [])) + count2 = len(self.callbacks.callbacks.get(self.signal)) + assert count1 == count2 + return count1 + + def is_empty(self): + np.testing.break_cycles() + assert self.callbacks._func_cid_map == {} + assert self.callbacks.callbacks == {} + assert self.callbacks._pickled_cids == set() + + def is_not_empty(self): + np.testing.break_cycles() + assert self.callbacks._func_cid_map != {} + assert self.callbacks.callbacks != {} + + def test_cid_restore(self): + cb = cbook.CallbackRegistry() + cb.connect('a', lambda: None) + cb2 = pickle.loads(pickle.dumps(cb)) + cid = cb2.connect('c', lambda: None) + assert cid == 1 + + @pytest.mark.parametrize('pickle', [True, False]) + def test_callback_complete(self, pickle): + # ensure we start with an empty registry + self.is_empty() + + # create a class for testing + mini_me = Test_callback_registry() + + # test that we can add a callback + cid1 = self.connect(self.signal, mini_me.dummy, pickle) + assert type(cid1) is int + self.is_not_empty() + + # test that we don't add a second callback + cid2 = self.connect(self.signal, mini_me.dummy, pickle) + assert cid1 == cid2 + self.is_not_empty() + assert len(self.callbacks._func_cid_map) == 1 + assert len(self.callbacks.callbacks) == 1 + + del mini_me + + # check we now have no callbacks registered + self.is_empty() + + @pytest.mark.parametrize('pickle', [True, False]) + def test_callback_disconnect(self, pickle): + # ensure we start with an empty registry + self.is_empty() + + # create a class for testing + mini_me = Test_callback_registry() + + # test that we can add a callback + cid1 = self.connect(self.signal, mini_me.dummy, pickle) + assert type(cid1) is int + self.is_not_empty() + + self.disconnect(cid1) + + # check we now have no callbacks registered + self.is_empty() + + @pytest.mark.parametrize('pickle', [True, False]) + def test_callback_wrong_disconnect(self, pickle): + # ensure we start with an empty registry + self.is_empty() + + # create a class for testing + mini_me = Test_callback_registry() + + # test that we can add a callback + cid1 = self.connect(self.signal, mini_me.dummy, pickle) + assert type(cid1) is int + self.is_not_empty() + + self.disconnect("foo") + + # check we still have callbacks registered + self.is_not_empty() + + @pytest.mark.parametrize('pickle', [True, False]) + def test_registration_on_non_empty_registry(self, pickle): + # ensure we start with an empty registry + self.is_empty() + + # setup the registry with a callback + mini_me = Test_callback_registry() + self.connect(self.signal, mini_me.dummy, pickle) + + # Add another callback + mini_me2 = Test_callback_registry() + self.connect(self.signal, mini_me2.dummy, pickle) + + # Remove and add the second callback + mini_me2 = Test_callback_registry() + self.connect(self.signal, mini_me2.dummy, pickle) + + # We still have 2 references + self.is_not_empty() + assert self.count() == 2 + + # Removing the last 2 references + mini_me = None + mini_me2 = None + self.is_empty() + + def dummy(self): + pass + + def test_pickling(self): + assert hasattr(pickle.loads(pickle.dumps(cbook.CallbackRegistry())), + "callbacks") + + +def test_callbackregistry_default_exception_handler(capsys, monkeypatch): + cb = cbook.CallbackRegistry() + cb.connect("foo", lambda: None) + + monkeypatch.setattr( + cbook, "_get_running_interactive_framework", lambda: None) + with pytest.raises(TypeError): + cb.process("foo", "argument mismatch") + outerr = capsys.readouterr() + assert outerr.out == outerr.err == "" + + monkeypatch.setattr( + cbook, "_get_running_interactive_framework", lambda: "not-none") + cb.process("foo", "argument mismatch") # No error in that case. + outerr = capsys.readouterr() + assert outerr.out == "" + assert "takes 0 positional arguments but 1 was given" in outerr.err + + +def raising_cb_reg(func): + class TestException(Exception): + pass + + def raise_runtime_error(): + raise RuntimeError + + def raise_value_error(): + raise ValueError + + def transformer(excp): + if isinstance(excp, RuntimeError): + raise TestException + raise excp + + # old default + cb_old = cbook.CallbackRegistry(exception_handler=None) + cb_old.connect('foo', raise_runtime_error) + + # filter + cb_filt = cbook.CallbackRegistry(exception_handler=transformer) + cb_filt.connect('foo', raise_runtime_error) + + # filter + cb_filt_pass = cbook.CallbackRegistry(exception_handler=transformer) + cb_filt_pass.connect('foo', raise_value_error) + + return pytest.mark.parametrize('cb, excp', + [[cb_old, RuntimeError], + [cb_filt, TestException], + [cb_filt_pass, ValueError]])(func) + + +@raising_cb_reg +def test_callbackregistry_custom_exception_handler(monkeypatch, cb, excp): + monkeypatch.setattr( + cbook, "_get_running_interactive_framework", lambda: None) + with pytest.raises(excp): + cb.process('foo') + + +def test_callbackregistry_signals(): + cr = cbook.CallbackRegistry(signals=["foo"]) + results = [] + def cb(x): results.append(x) + cr.connect("foo", cb) + with pytest.raises(ValueError): + cr.connect("bar", cb) + cr.process("foo", 1) + with pytest.raises(ValueError): + cr.process("bar", 1) + assert results == [1] + + +def test_callbackregistry_blocking(): + # Needs an exception handler for interactive testing environments + # that would only print this out instead of raising the exception + def raise_handler(excp): + raise excp + cb = cbook.CallbackRegistry(exception_handler=raise_handler) + def test_func1(): + raise ValueError("1 should be blocked") + def test_func2(): + raise ValueError("2 should be blocked") + cb.connect("test1", test_func1) + cb.connect("test2", test_func2) + + # block all of the callbacks to make sure they aren't processed + with cb.blocked(): + cb.process("test1") + cb.process("test2") + + # block individual callbacks to make sure the other is still processed + with cb.blocked(signal="test1"): + # Blocked + cb.process("test1") + # Should raise + with pytest.raises(ValueError, match="2 should be blocked"): + cb.process("test2") + + # Make sure the original callback functions are there after blocking + with pytest.raises(ValueError, match="1 should be blocked"): + cb.process("test1") + with pytest.raises(ValueError, match="2 should be blocked"): + cb.process("test2") + + +@pytest.mark.parametrize('line, result', [ + ('a : no_comment', 'a : no_comment'), + ('a : "quoted str"', 'a : "quoted str"'), + ('a : "quoted str" # comment', 'a : "quoted str"'), + ('a : "#000000"', 'a : "#000000"'), + ('a : "#000000" # comment', 'a : "#000000"'), + ('a : ["#000000", "#FFFFFF"]', 'a : ["#000000", "#FFFFFF"]'), + ('a : ["#000000", "#FFFFFF"] # comment', 'a : ["#000000", "#FFFFFF"]'), + ('a : val # a comment "with quotes"', 'a : val'), + ('# only comment "with quotes" xx', ''), +]) +def test_strip_comment(line, result): + """Strip everything from the first unquoted #.""" + assert cbook._strip_comment(line) == result + + +def test_strip_comment_invalid(): + with pytest.raises(ValueError, match="Missing closing quote"): + cbook._strip_comment('grid.color: "aa') + + +def test_sanitize_sequence(): + d = {'a': 1, 'b': 2, 'c': 3} + k = ['a', 'b', 'c'] + v = [1, 2, 3] + i = [('a', 1), ('b', 2), ('c', 3)] + assert k == sorted(cbook.sanitize_sequence(d.keys())) + assert v == sorted(cbook.sanitize_sequence(d.values())) + assert i == sorted(cbook.sanitize_sequence(d.items())) + assert i == cbook.sanitize_sequence(i) + assert k == cbook.sanitize_sequence(k) + + +fail_mapping: tuple[tuple[dict, dict], ...] = ( + ({'a': 1, 'b': 2}, {'alias_mapping': {'a': ['b']}}), + ({'a': 1, 'b': 2}, {'alias_mapping': {'a': ['a', 'b']}}), +) + +pass_mapping: tuple[tuple[Any, dict, dict], ...] = ( + (None, {}, {}), + ({'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {}), + ({'b': 2}, {'a': 2}, {'alias_mapping': {'a': ['a', 'b']}}), +) + + +@pytest.mark.parametrize('inp, kwargs_to_norm', fail_mapping) +def test_normalize_kwargs_fail(inp, kwargs_to_norm): + with pytest.raises(TypeError), \ + _api.suppress_matplotlib_deprecation_warning(): + cbook.normalize_kwargs(inp, **kwargs_to_norm) + + +@pytest.mark.parametrize('inp, expected, kwargs_to_norm', + pass_mapping) +def test_normalize_kwargs_pass(inp, expected, kwargs_to_norm): + with _api.suppress_matplotlib_deprecation_warning(): + # No other warning should be emitted. + assert expected == cbook.normalize_kwargs(inp, **kwargs_to_norm) + + +def test_warn_external_frame_embedded_python(): + with patch.object(cbook, "sys") as mock_sys: + mock_sys._getframe = Mock(return_value=None) + with pytest.warns(UserWarning, match=r"\Adummy\Z"): + _api.warn_external("dummy") + + +def test_to_prestep(): + x = np.arange(4) + y1 = np.arange(4) + y2 = np.arange(4)[::-1] + + xs, y1s, y2s = cbook.pts_to_prestep(x, y1, y2) + + x_target = np.asarray([0, 0, 1, 1, 2, 2, 3], dtype=float) + y1_target = np.asarray([0, 1, 1, 2, 2, 3, 3], dtype=float) + y2_target = np.asarray([3, 2, 2, 1, 1, 0, 0], dtype=float) + + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + assert_array_equal(y2_target, y2s) + + xs, y1s = cbook.pts_to_prestep(x, y1) + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + + +def test_to_prestep_empty(): + steps = cbook.pts_to_prestep([], []) + assert steps.shape == (2, 0) + + +def test_to_poststep(): + x = np.arange(4) + y1 = np.arange(4) + y2 = np.arange(4)[::-1] + + xs, y1s, y2s = cbook.pts_to_poststep(x, y1, y2) + + x_target = np.asarray([0, 1, 1, 2, 2, 3, 3], dtype=float) + y1_target = np.asarray([0, 0, 1, 1, 2, 2, 3], dtype=float) + y2_target = np.asarray([3, 3, 2, 2, 1, 1, 0], dtype=float) + + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + assert_array_equal(y2_target, y2s) + + xs, y1s = cbook.pts_to_poststep(x, y1) + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + + +def test_to_poststep_empty(): + steps = cbook.pts_to_poststep([], []) + assert steps.shape == (2, 0) + + +def test_to_midstep(): + x = np.arange(4) + y1 = np.arange(4) + y2 = np.arange(4)[::-1] + + xs, y1s, y2s = cbook.pts_to_midstep(x, y1, y2) + + x_target = np.asarray([0, .5, .5, 1.5, 1.5, 2.5, 2.5, 3], dtype=float) + y1_target = np.asarray([0, 0, 1, 1, 2, 2, 3, 3], dtype=float) + y2_target = np.asarray([3, 3, 2, 2, 1, 1, 0, 0], dtype=float) + + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + assert_array_equal(y2_target, y2s) + + xs, y1s = cbook.pts_to_midstep(x, y1) + assert_array_equal(x_target, xs) + assert_array_equal(y1_target, y1s) + + +def test_to_midstep_empty(): + steps = cbook.pts_to_midstep([], []) + assert steps.shape == (2, 0) + + +@pytest.mark.parametrize( + "args", + [(np.arange(12).reshape(3, 4), 'a'), + (np.arange(12), 'a'), + (np.arange(12), np.arange(3))]) +def test_step_fails(args): + with pytest.raises(ValueError): + cbook.pts_to_prestep(*args) + + +def test_grouper(): + class Dummy: + pass + a, b, c, d, e = objs = [Dummy() for _ in range(5)] + g = cbook.Grouper() + g.join(*objs) + assert set(list(g)[0]) == set(objs) + assert set(g.get_siblings(a)) == set(objs) + + for other in objs[1:]: + assert g.joined(a, other) + + g.remove(a) + for other in objs[1:]: + assert not g.joined(a, other) + + for A, B in itertools.product(objs[1:], objs[1:]): + assert g.joined(A, B) + + +def test_grouper_private(): + class Dummy: + pass + objs = [Dummy() for _ in range(5)] + g = cbook.Grouper() + g.join(*objs) + # reach in and touch the internals ! + mapping = g._mapping + + for o in objs: + assert o in mapping + + base_set = mapping[objs[0]] + for o in objs[1:]: + assert mapping[o] is base_set + + +def test_flatiter(): + x = np.arange(5) + it = x.flat + assert 0 == next(it) + assert 1 == next(it) + ret = cbook._safe_first_finite(it) + assert ret == 0 + + assert 0 == next(it) + assert 1 == next(it) + + +def test__safe_first_finite_all_nan(): + arr = np.full(2, np.nan) + ret = cbook._safe_first_finite(arr) + assert np.isnan(ret) + + +def test__safe_first_finite_all_inf(): + arr = np.full(2, np.inf) + ret = cbook._safe_first_finite(arr) + assert np.isinf(ret) + + +def test_reshape2d(): + + class Dummy: + pass + + xnew = cbook._reshape_2D([], 'x') + assert np.shape(xnew) == (1, 0) + + x = [Dummy() for _ in range(5)] + + xnew = cbook._reshape_2D(x, 'x') + assert np.shape(xnew) == (1, 5) + + x = np.arange(5) + xnew = cbook._reshape_2D(x, 'x') + assert np.shape(xnew) == (1, 5) + + x = [[Dummy() for _ in range(5)] for _ in range(3)] + xnew = cbook._reshape_2D(x, 'x') + assert np.shape(xnew) == (3, 5) + + # this is strange behaviour, but... + x = np.random.rand(3, 5) + xnew = cbook._reshape_2D(x, 'x') + assert np.shape(xnew) == (5, 3) + + # Test a list of lists which are all of length 1 + x = [[1], [2], [3]] + xnew = cbook._reshape_2D(x, 'x') + assert isinstance(xnew, list) + assert isinstance(xnew[0], np.ndarray) and xnew[0].shape == (1,) + assert isinstance(xnew[1], np.ndarray) and xnew[1].shape == (1,) + assert isinstance(xnew[2], np.ndarray) and xnew[2].shape == (1,) + + # Test a list of zero-dimensional arrays + x = [np.array(0), np.array(1), np.array(2)] + xnew = cbook._reshape_2D(x, 'x') + assert isinstance(xnew, list) + assert len(xnew) == 1 + assert isinstance(xnew[0], np.ndarray) and xnew[0].shape == (3,) + + # Now test with a list of lists with different lengths, which means the + # array will internally be converted to a 1D object array of lists + x = [[1, 2, 3], [3, 4], [2]] + xnew = cbook._reshape_2D(x, 'x') + assert isinstance(xnew, list) + assert isinstance(xnew[0], np.ndarray) and xnew[0].shape == (3,) + assert isinstance(xnew[1], np.ndarray) and xnew[1].shape == (2,) + assert isinstance(xnew[2], np.ndarray) and xnew[2].shape == (1,) + + # We now need to make sure that this works correctly for Numpy subclasses + # where iterating over items can return subclasses too, which may be + # iterable even if they are scalars. To emulate this, we make a Numpy + # array subclass that returns Numpy 'scalars' when iterating or accessing + # values, and these are technically iterable if checking for example + # isinstance(x, collections.abc.Iterable). + + class ArraySubclass(np.ndarray): + + def __iter__(self): + for value in super().__iter__(): + yield np.array(value) + + def __getitem__(self, item): + return np.array(super().__getitem__(item)) + + v = np.arange(10, dtype=float) + x = ArraySubclass((10,), dtype=float, buffer=v.data) + + xnew = cbook._reshape_2D(x, 'x') + + # We check here that the array wasn't split up into many individual + # ArraySubclass, which is what used to happen due to a bug in _reshape_2D + assert len(xnew) == 1 + assert isinstance(xnew[0], ArraySubclass) + + # check list of strings: + x = ['a', 'b', 'c', 'c', 'dd', 'e', 'f', 'ff', 'f'] + xnew = cbook._reshape_2D(x, 'x') + assert len(xnew[0]) == len(x) + assert isinstance(xnew[0], np.ndarray) + + +def test_reshape2d_pandas(pd): + # separate to allow the rest of the tests to run if no pandas... + X = np.arange(30).reshape(10, 3) + x = pd.DataFrame(X, columns=["a", "b", "c"]) + Xnew = cbook._reshape_2D(x, 'x') + # Need to check each row because _reshape_2D returns a list of arrays: + for x, xnew in zip(X.T, Xnew): + np.testing.assert_array_equal(x, xnew) + + +def test_reshape2d_xarray(xr): + # separate to allow the rest of the tests to run if no xarray... + X = np.arange(30).reshape(10, 3) + x = xr.DataArray(X, dims=["x", "y"]) + Xnew = cbook._reshape_2D(x, 'x') + # Need to check each row because _reshape_2D returns a list of arrays: + for x, xnew in zip(X.T, Xnew): + np.testing.assert_array_equal(x, xnew) + + +def test_index_of_pandas(pd): + # separate to allow the rest of the tests to run if no pandas... + X = np.arange(30).reshape(10, 3) + x = pd.DataFrame(X, columns=["a", "b", "c"]) + Idx, Xnew = cbook.index_of(x) + np.testing.assert_array_equal(X, Xnew) + IdxRef = np.arange(10) + np.testing.assert_array_equal(Idx, IdxRef) + + +def test_index_of_xarray(xr): + # separate to allow the rest of the tests to run if no xarray... + X = np.arange(30).reshape(10, 3) + x = xr.DataArray(X, dims=["x", "y"]) + Idx, Xnew = cbook.index_of(x) + np.testing.assert_array_equal(X, Xnew) + IdxRef = np.arange(10) + np.testing.assert_array_equal(Idx, IdxRef) + + +def test_contiguous_regions(): + a, b, c = 3, 4, 5 + # Starts and ends with True + mask = [True]*a + [False]*b + [True]*c + expected = [(0, a), (a+b, a+b+c)] + assert cbook.contiguous_regions(mask) == expected + d, e = 6, 7 + # Starts with True ends with False + mask = mask + [False]*e + assert cbook.contiguous_regions(mask) == expected + # Starts with False ends with True + mask = [False]*d + mask[:-e] + expected = [(d, d+a), (d+a+b, d+a+b+c)] + assert cbook.contiguous_regions(mask) == expected + # Starts and ends with False + mask = mask + [False]*e + assert cbook.contiguous_regions(mask) == expected + # No True in mask + assert cbook.contiguous_regions([False]*5) == [] + # Empty mask + assert cbook.contiguous_regions([]) == [] + + +def test_safe_first_element_pandas_series(pd): + # deliberately create a pandas series with index not starting from 0 + s = pd.Series(range(5), index=range(10, 15)) + actual = cbook._safe_first_finite(s) + assert actual == 0 + + +def test_warn_external(recwarn): + _api.warn_external("oops") + assert len(recwarn) == 1 + assert recwarn[0].filename == __file__ + + +def test_array_patch_perimeters(): + # This compares the old implementation as a reference for the + # vectorized one. + def check(x, rstride, cstride): + rows, cols = x.shape + row_inds = [*range(0, rows-1, rstride), rows-1] + col_inds = [*range(0, cols-1, cstride), cols-1] + polys = [] + for rs, rs_next in zip(row_inds[:-1], row_inds[1:]): + for cs, cs_next in zip(col_inds[:-1], col_inds[1:]): + # +1 ensures we share edges between polygons + ps = cbook._array_perimeter(x[rs:rs_next+1, cs:cs_next+1]).T + polys.append(ps) + polys = np.asarray(polys) + assert np.array_equal(polys, + cbook._array_patch_perimeters( + x, rstride=rstride, cstride=cstride)) + + def divisors(n): + return [i for i in range(1, n + 1) if n % i == 0] + + for rows, cols in [(5, 5), (7, 14), (13, 9)]: + x = np.arange(rows * cols).reshape(rows, cols) + for rstride, cstride in itertools.product(divisors(rows - 1), + divisors(cols - 1)): + check(x, rstride=rstride, cstride=cstride) + + +def test_setattr_cm(): + class A: + cls_level = object() + override = object() + + def __init__(self): + self.aardvark = 'aardvark' + self.override = 'override' + self._p = 'p' + + def meth(self): + ... + + @classmethod + def classy(cls): + ... + + @staticmethod + def static(): + ... + + @property + def prop(self): + return self._p + + @prop.setter + def prop(self, val): + self._p = val + + class B(A): + ... + + other = A() + + def verify_pre_post_state(obj): + # When you access a Python method the function is bound + # to the object at access time so you get a new instance + # of MethodType every time. + # + # https://docs.python.org/3/howto/descriptor.html#functions-and-methods + assert obj.meth is not obj.meth + # normal attribute should give you back the same instance every time + assert obj.aardvark is obj.aardvark + assert a.aardvark == 'aardvark' + # and our property happens to give the same instance every time + assert obj.prop is obj.prop + assert obj.cls_level is A.cls_level + assert obj.override == 'override' + assert not hasattr(obj, 'extra') + assert obj.prop == 'p' + assert obj.monkey == other.meth + assert obj.cls_level is A.cls_level + assert 'cls_level' not in obj.__dict__ + assert 'classy' not in obj.__dict__ + assert 'static' not in obj.__dict__ + + a = B() + + a.monkey = other.meth + verify_pre_post_state(a) + with cbook._setattr_cm( + a, prop='squirrel', + aardvark='moose', meth=lambda: None, + override='boo', extra='extra', + monkey=lambda: None, cls_level='bob', + classy='classy', static='static'): + # because we have set a lambda, it is normal attribute access + # and the same every time + assert a.meth is a.meth + assert a.aardvark is a.aardvark + assert a.aardvark == 'moose' + assert a.override == 'boo' + assert a.extra == 'extra' + assert a.prop == 'squirrel' + assert a.monkey != other.meth + assert a.cls_level == 'bob' + assert a.classy == 'classy' + assert a.static == 'static' + + verify_pre_post_state(a) + + +def test_format_approx(): + f = cbook._format_approx + assert f(0, 1) == '0' + assert f(0, 2) == '0' + assert f(0, 3) == '0' + assert f(-0.0123, 1) == '-0' + assert f(1e-7, 5) == '0' + assert f(0.0012345600001, 5) == '0.00123' + assert f(-0.0012345600001, 5) == '-0.00123' + assert f(0.0012345600001, 8) == f(0.0012345600001, 10) == '0.00123456' + + +def test_safe_first_element_with_none(): + datetime_lst = [date.today() + timedelta(days=i) for i in range(10)] + datetime_lst[0] = None + actual = cbook._safe_first_finite(datetime_lst) + assert actual is not None and actual == datetime_lst[1] + + +def test_strip_math(): + assert strip_math(r'1 \times 2') == r'1 \times 2' + assert strip_math(r'$1 \times 2$') == '1 x 2' + assert strip_math(r'$\rm{hi}$') == 'hi' + + +@pytest.mark.parametrize('fmt, value, result', [ + ('%.2f m', 0.2, '0.20 m'), + ('{:.2f} m', 0.2, '0.20 m'), + ('{} m', 0.2, '0.2 m'), + ('const', 0.2, 'const'), + ('%d or {}', 0.2, '0 or {}'), + ('{{{:,.0f}}}', 2e5, '{200,000}'), + ('{:.2%}', 2/3, '66.67%'), + ('$%g', 2.54, '$2.54'), +]) +def test_auto_format_str(fmt, value, result): + """Apply *value* to the format string *fmt*.""" + assert cbook._auto_format_str(fmt, value) == result + assert cbook._auto_format_str(fmt, np.float64(value)) == result diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_collections.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_collections.py new file mode 100644 index 00000000..43bbea34 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_collections.py @@ -0,0 +1,1282 @@ +from datetime import datetime +import io +import itertools +import re +from types import SimpleNamespace + +import numpy as np +from numpy.testing import assert_array_equal, assert_array_almost_equal +import pytest + +import matplotlib as mpl +import matplotlib.pyplot as plt +import matplotlib.collections as mcollections +import matplotlib.colors as mcolors +import matplotlib.path as mpath +import matplotlib.transforms as mtransforms +from matplotlib.collections import (Collection, LineCollection, + EventCollection, PolyCollection) +from matplotlib.testing.decorators import check_figures_equal, image_comparison + + +@pytest.fixture(params=["pcolormesh", "pcolor"]) +def pcfunc(request): + return request.param + + +def generate_EventCollection_plot(): + """Generate the initial collection and plot it.""" + positions = np.array([0., 1., 2., 3., 5., 8., 13., 21.]) + extra_positions = np.array([34., 55., 89.]) + orientation = 'horizontal' + lineoffset = 1 + linelength = .5 + linewidth = 2 + color = [1, 0, 0, 1] + linestyle = 'solid' + antialiased = True + + coll = EventCollection(positions, + orientation=orientation, + lineoffset=lineoffset, + linelength=linelength, + linewidth=linewidth, + color=color, + linestyle=linestyle, + antialiased=antialiased + ) + + fig, ax = plt.subplots() + ax.add_collection(coll) + ax.set_title('EventCollection: default') + props = {'positions': positions, + 'extra_positions': extra_positions, + 'orientation': orientation, + 'lineoffset': lineoffset, + 'linelength': linelength, + 'linewidth': linewidth, + 'color': color, + 'linestyle': linestyle, + 'antialiased': antialiased + } + ax.set_xlim(-1, 22) + ax.set_ylim(0, 2) + return ax, coll, props + + +@image_comparison(['EventCollection_plot__default']) +def test__EventCollection__get_props(): + _, coll, props = generate_EventCollection_plot() + # check that the default segments have the correct coordinates + check_segments(coll, + props['positions'], + props['linelength'], + props['lineoffset'], + props['orientation']) + # check that the default positions match the input positions + np.testing.assert_array_equal(props['positions'], coll.get_positions()) + # check that the default orientation matches the input orientation + assert props['orientation'] == coll.get_orientation() + # check that the default orientation matches the input orientation + assert coll.is_horizontal() + # check that the default linelength matches the input linelength + assert props['linelength'] == coll.get_linelength() + # check that the default lineoffset matches the input lineoffset + assert props['lineoffset'] == coll.get_lineoffset() + # check that the default linestyle matches the input linestyle + assert coll.get_linestyle() == [(0, None)] + # check that the default color matches the input color + for color in [coll.get_color(), *coll.get_colors()]: + np.testing.assert_array_equal(color, props['color']) + + +@image_comparison(['EventCollection_plot__set_positions']) +def test__EventCollection__set_positions(): + splt, coll, props = generate_EventCollection_plot() + new_positions = np.hstack([props['positions'], props['extra_positions']]) + coll.set_positions(new_positions) + np.testing.assert_array_equal(new_positions, coll.get_positions()) + check_segments(coll, new_positions, + props['linelength'], + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: set_positions') + splt.set_xlim(-1, 90) + + +@image_comparison(['EventCollection_plot__add_positions']) +def test__EventCollection__add_positions(): + splt, coll, props = generate_EventCollection_plot() + new_positions = np.hstack([props['positions'], + props['extra_positions'][0]]) + coll.switch_orientation() # Test adding in the vertical orientation, too. + coll.add_positions(props['extra_positions'][0]) + coll.switch_orientation() + np.testing.assert_array_equal(new_positions, coll.get_positions()) + check_segments(coll, + new_positions, + props['linelength'], + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: add_positions') + splt.set_xlim(-1, 35) + + +@image_comparison(['EventCollection_plot__append_positions']) +def test__EventCollection__append_positions(): + splt, coll, props = generate_EventCollection_plot() + new_positions = np.hstack([props['positions'], + props['extra_positions'][2]]) + coll.append_positions(props['extra_positions'][2]) + np.testing.assert_array_equal(new_positions, coll.get_positions()) + check_segments(coll, + new_positions, + props['linelength'], + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: append_positions') + splt.set_xlim(-1, 90) + + +@image_comparison(['EventCollection_plot__extend_positions']) +def test__EventCollection__extend_positions(): + splt, coll, props = generate_EventCollection_plot() + new_positions = np.hstack([props['positions'], + props['extra_positions'][1:]]) + coll.extend_positions(props['extra_positions'][1:]) + np.testing.assert_array_equal(new_positions, coll.get_positions()) + check_segments(coll, + new_positions, + props['linelength'], + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: extend_positions') + splt.set_xlim(-1, 90) + + +@image_comparison(['EventCollection_plot__switch_orientation']) +def test__EventCollection__switch_orientation(): + splt, coll, props = generate_EventCollection_plot() + new_orientation = 'vertical' + coll.switch_orientation() + assert new_orientation == coll.get_orientation() + assert not coll.is_horizontal() + new_positions = coll.get_positions() + check_segments(coll, + new_positions, + props['linelength'], + props['lineoffset'], new_orientation) + splt.set_title('EventCollection: switch_orientation') + splt.set_ylim(-1, 22) + splt.set_xlim(0, 2) + + +@image_comparison(['EventCollection_plot__switch_orientation__2x']) +def test__EventCollection__switch_orientation_2x(): + """ + Check that calling switch_orientation twice sets the orientation back to + the default. + """ + splt, coll, props = generate_EventCollection_plot() + coll.switch_orientation() + coll.switch_orientation() + new_positions = coll.get_positions() + assert props['orientation'] == coll.get_orientation() + assert coll.is_horizontal() + np.testing.assert_array_equal(props['positions'], new_positions) + check_segments(coll, + new_positions, + props['linelength'], + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: switch_orientation 2x') + + +@image_comparison(['EventCollection_plot__set_orientation']) +def test__EventCollection__set_orientation(): + splt, coll, props = generate_EventCollection_plot() + new_orientation = 'vertical' + coll.set_orientation(new_orientation) + assert new_orientation == coll.get_orientation() + assert not coll.is_horizontal() + check_segments(coll, + props['positions'], + props['linelength'], + props['lineoffset'], + new_orientation) + splt.set_title('EventCollection: set_orientation') + splt.set_ylim(-1, 22) + splt.set_xlim(0, 2) + + +@image_comparison(['EventCollection_plot__set_linelength']) +def test__EventCollection__set_linelength(): + splt, coll, props = generate_EventCollection_plot() + new_linelength = 15 + coll.set_linelength(new_linelength) + assert new_linelength == coll.get_linelength() + check_segments(coll, + props['positions'], + new_linelength, + props['lineoffset'], + props['orientation']) + splt.set_title('EventCollection: set_linelength') + splt.set_ylim(-20, 20) + + +@image_comparison(['EventCollection_plot__set_lineoffset']) +def test__EventCollection__set_lineoffset(): + splt, coll, props = generate_EventCollection_plot() + new_lineoffset = -5. + coll.set_lineoffset(new_lineoffset) + assert new_lineoffset == coll.get_lineoffset() + check_segments(coll, + props['positions'], + props['linelength'], + new_lineoffset, + props['orientation']) + splt.set_title('EventCollection: set_lineoffset') + splt.set_ylim(-6, -4) + + +@image_comparison([ + 'EventCollection_plot__set_linestyle', + 'EventCollection_plot__set_linestyle', + 'EventCollection_plot__set_linewidth', +]) +def test__EventCollection__set_prop(): + for prop, value, expected in [ + ('linestyle', 'dashed', [(0, (6.0, 6.0))]), + ('linestyle', (0, (6., 6.)), [(0, (6.0, 6.0))]), + ('linewidth', 5, 5), + ]: + splt, coll, _ = generate_EventCollection_plot() + coll.set(**{prop: value}) + assert plt.getp(coll, prop) == expected + splt.set_title(f'EventCollection: set_{prop}') + + +@image_comparison(['EventCollection_plot__set_color']) +def test__EventCollection__set_color(): + splt, coll, _ = generate_EventCollection_plot() + new_color = np.array([0, 1, 1, 1]) + coll.set_color(new_color) + for color in [coll.get_color(), *coll.get_colors()]: + np.testing.assert_array_equal(color, new_color) + splt.set_title('EventCollection: set_color') + + +def check_segments(coll, positions, linelength, lineoffset, orientation): + """ + Test helper checking that all values in the segment are correct, given a + particular set of inputs. + """ + segments = coll.get_segments() + if (orientation.lower() == 'horizontal' + or orientation.lower() == 'none' or orientation is None): + # if horizontal, the position in is in the y-axis + pos1 = 1 + pos2 = 0 + elif orientation.lower() == 'vertical': + # if vertical, the position in is in the x-axis + pos1 = 0 + pos2 = 1 + else: + raise ValueError("orientation must be 'horizontal' or 'vertical'") + + # test to make sure each segment is correct + for i, segment in enumerate(segments): + assert segment[0, pos1] == lineoffset + linelength / 2 + assert segment[1, pos1] == lineoffset - linelength / 2 + assert segment[0, pos2] == positions[i] + assert segment[1, pos2] == positions[i] + + +def test_null_collection_datalim(): + col = mcollections.PathCollection([]) + col_data_lim = col.get_datalim(mtransforms.IdentityTransform()) + assert_array_equal(col_data_lim.get_points(), + mtransforms.Bbox.null().get_points()) + + +def test_no_offsets_datalim(): + # A collection with no offsets and a non transData + # transform should return a null bbox + ax = plt.axes() + coll = mcollections.PathCollection([mpath.Path([(0, 0), (1, 0)])]) + ax.add_collection(coll) + coll_data_lim = coll.get_datalim(mtransforms.IdentityTransform()) + assert_array_equal(coll_data_lim.get_points(), + mtransforms.Bbox.null().get_points()) + + +def test_add_collection(): + # Test if data limits are unchanged by adding an empty collection. + # GitHub issue #1490, pull #1497. + plt.figure() + ax = plt.axes() + ax.scatter([0, 1], [0, 1]) + bounds = ax.dataLim.bounds + ax.scatter([], []) + assert ax.dataLim.bounds == bounds + + +@mpl.style.context('mpl20') +@check_figures_equal(extensions=['png']) +def test_collection_log_datalim(fig_test, fig_ref): + # Data limits should respect the minimum x/y when using log scale. + x_vals = [4.38462e-6, 5.54929e-6, 7.02332e-6, 8.88889e-6, 1.12500e-5, + 1.42383e-5, 1.80203e-5, 2.28070e-5, 2.88651e-5, 3.65324e-5, + 4.62363e-5, 5.85178e-5, 7.40616e-5, 9.37342e-5, 1.18632e-4] + y_vals = [0.0, 0.1, 0.182, 0.332, 0.604, 1.1, 2.0, 3.64, 6.64, 12.1, 22.0, + 39.6, 71.3] + + x, y = np.meshgrid(x_vals, y_vals) + x = x.flatten() + y = y.flatten() + + ax_test = fig_test.subplots() + ax_test.set_xscale('log') + ax_test.set_yscale('log') + ax_test.margins = 0 + ax_test.scatter(x, y) + + ax_ref = fig_ref.subplots() + ax_ref.set_xscale('log') + ax_ref.set_yscale('log') + ax_ref.plot(x, y, marker="o", ls="") + + +def test_quiver_limits(): + ax = plt.axes() + x, y = np.arange(8), np.arange(10) + u = v = np.linspace(0, 10, 80).reshape(10, 8) + q = plt.quiver(x, y, u, v) + assert q.get_datalim(ax.transData).bounds == (0., 0., 7., 9.) + + plt.figure() + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.quiver(x, y, np.sin(x), np.cos(y), transform=trans) + assert ax.dataLim.bounds == (20.0, 30.0, 15.0, 6.0) + + +def test_barb_limits(): + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans) + # The calculated bounds are approximately the bounds of the original data, + # this is because the entire path is taken into account when updating the + # datalim. + assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6), + decimal=1) + + +@image_comparison(['EllipseCollection_test_image.png'], remove_text=True) +def test_EllipseCollection(): + # Test basic functionality + fig, ax = plt.subplots() + x = np.arange(4) + y = np.arange(3) + X, Y = np.meshgrid(x, y) + XY = np.vstack((X.ravel(), Y.ravel())).T + + ww = X / x[-1] + hh = Y / y[-1] + aa = np.ones_like(ww) * 20 # first axis is 20 degrees CCW from x axis + + ec = mcollections.EllipseCollection( + ww, hh, aa, units='x', offsets=XY, offset_transform=ax.transData, + facecolors='none') + ax.add_collection(ec) + ax.autoscale_view() + + +@image_comparison(['polycollection_close.png'], remove_text=True, style='mpl20') +def test_polycollection_close(): + from mpl_toolkits.mplot3d import Axes3D # type: ignore + + vertsQuad = [ + [[0., 0.], [0., 1.], [1., 1.], [1., 0.]], + [[0., 1.], [2., 3.], [2., 2.], [1., 1.]], + [[2., 2.], [2., 3.], [4., 1.], [3., 1.]], + [[3., 0.], [3., 1.], [4., 1.], [4., 0.]]] + + fig = plt.figure() + ax = fig.add_axes(Axes3D(fig)) + + colors = ['r', 'g', 'b', 'y', 'k'] + zpos = list(range(5)) + + poly = mcollections.PolyCollection( + vertsQuad * len(zpos), linewidth=0.25) + poly.set_alpha(0.7) + + # need to have a z-value for *each* polygon = element! + zs = [] + cs = [] + for z, c in zip(zpos, colors): + zs.extend([z] * len(vertsQuad)) + cs.extend([c] * len(vertsQuad)) + + poly.set_color(cs) + + ax.add_collection3d(poly, zs=zs, zdir='y') + + # axis limit settings: + ax.set_xlim3d(0, 4) + ax.set_zlim3d(0, 3) + ax.set_ylim3d(0, 4) + + +@image_comparison(['regularpolycollection_rotate.png'], remove_text=True) +def test_regularpolycollection_rotate(): + xx, yy = np.mgrid[:10, :10] + xy_points = np.transpose([xx.flatten(), yy.flatten()]) + rotations = np.linspace(0, 2*np.pi, len(xy_points)) + + fig, ax = plt.subplots() + for xy, alpha in zip(xy_points, rotations): + col = mcollections.RegularPolyCollection( + 4, sizes=(100,), rotation=alpha, + offsets=[xy], offset_transform=ax.transData) + ax.add_collection(col, autolim=True) + ax.autoscale_view() + + +@image_comparison(['regularpolycollection_scale.png'], remove_text=True) +def test_regularpolycollection_scale(): + # See issue #3860 + + class SquareCollection(mcollections.RegularPolyCollection): + def __init__(self, **kwargs): + super().__init__(4, rotation=np.pi/4., **kwargs) + + def get_transform(self): + """Return transform scaling circle areas to data space.""" + ax = self.axes + + pts2pixels = 72.0 / ax.figure.dpi + + scale_x = pts2pixels * ax.bbox.width / ax.viewLim.width + scale_y = pts2pixels * ax.bbox.height / ax.viewLim.height + return mtransforms.Affine2D().scale(scale_x, scale_y) + + fig, ax = plt.subplots() + + xy = [(0, 0)] + # Unit square has a half-diagonal of `1/sqrt(2)`, so `pi * r**2` equals... + circle_areas = [np.pi / 2] + squares = SquareCollection( + sizes=circle_areas, offsets=xy, offset_transform=ax.transData) + ax.add_collection(squares, autolim=True) + ax.axis([-1, 1, -1, 1]) + + +def test_picking(): + fig, ax = plt.subplots() + col = ax.scatter([0], [0], [1000], picker=True) + fig.savefig(io.BytesIO(), dpi=fig.dpi) + mouse_event = SimpleNamespace(x=325, y=240) + found, indices = col.contains(mouse_event) + assert found + assert_array_equal(indices['ind'], [0]) + + +def test_quadmesh_contains(): + x = np.arange(4) + X = x[:, None] * x[None, :] + + fig, ax = plt.subplots() + mesh = ax.pcolormesh(X) + fig.draw_without_rendering() + xdata, ydata = 0.5, 0.5 + x, y = mesh.get_transform().transform((xdata, ydata)) + mouse_event = SimpleNamespace(xdata=xdata, ydata=ydata, x=x, y=y) + found, indices = mesh.contains(mouse_event) + assert found + assert_array_equal(indices['ind'], [0]) + + xdata, ydata = 1.5, 1.5 + x, y = mesh.get_transform().transform((xdata, ydata)) + mouse_event = SimpleNamespace(xdata=xdata, ydata=ydata, x=x, y=y) + found, indices = mesh.contains(mouse_event) + assert found + assert_array_equal(indices['ind'], [5]) + + +def test_quadmesh_contains_concave(): + # Test a concave polygon, V-like shape + x = [[0, -1], [1, 0]] + y = [[0, 1], [1, -1]] + fig, ax = plt.subplots() + mesh = ax.pcolormesh(x, y, [[0]]) + fig.draw_without_rendering() + # xdata, ydata, expected + points = [(-0.5, 0.25, True), # left wing + (0, 0.25, False), # between the two wings + (0.5, 0.25, True), # right wing + (0, -0.25, True), # main body + ] + for point in points: + xdata, ydata, expected = point + x, y = mesh.get_transform().transform((xdata, ydata)) + mouse_event = SimpleNamespace(xdata=xdata, ydata=ydata, x=x, y=y) + found, indices = mesh.contains(mouse_event) + assert found is expected + + +def test_quadmesh_cursor_data(): + x = np.arange(4) + X = x[:, None] * x[None, :] + + fig, ax = plt.subplots() + mesh = ax.pcolormesh(X) + # Empty array data + mesh._A = None + fig.draw_without_rendering() + xdata, ydata = 0.5, 0.5 + x, y = mesh.get_transform().transform((xdata, ydata)) + mouse_event = SimpleNamespace(xdata=xdata, ydata=ydata, x=x, y=y) + # Empty collection should return None + assert mesh.get_cursor_data(mouse_event) is None + + # Now test adding the array data, to make sure we do get a value + mesh.set_array(np.ones(X.shape)) + assert_array_equal(mesh.get_cursor_data(mouse_event), [1]) + + +def test_quadmesh_cursor_data_multiple_points(): + x = [1, 2, 1, 2] + fig, ax = plt.subplots() + mesh = ax.pcolormesh(x, x, np.ones((3, 3))) + fig.draw_without_rendering() + xdata, ydata = 1.5, 1.5 + x, y = mesh.get_transform().transform((xdata, ydata)) + mouse_event = SimpleNamespace(xdata=xdata, ydata=ydata, x=x, y=y) + # All quads are covering the same square + assert_array_equal(mesh.get_cursor_data(mouse_event), np.ones(9)) + + +def test_linestyle_single_dashes(): + plt.scatter([0, 1, 2], [0, 1, 2], linestyle=(0., [2., 2.])) + plt.draw() + + +@image_comparison(['size_in_xy.png'], remove_text=True) +def test_size_in_xy(): + fig, ax = plt.subplots() + + widths, heights, angles = (10, 10), 10, 0 + widths = 10, 10 + coords = [(10, 10), (15, 15)] + e = mcollections.EllipseCollection( + widths, heights, angles, units='xy', + offsets=coords, offset_transform=ax.transData) + + ax.add_collection(e) + + ax.set_xlim(0, 30) + ax.set_ylim(0, 30) + + +def test_pandas_indexing(pd): + + # Should not fail break when faced with a + # non-zero indexed series + index = [11, 12, 13] + ec = fc = pd.Series(['red', 'blue', 'green'], index=index) + lw = pd.Series([1, 2, 3], index=index) + ls = pd.Series(['solid', 'dashed', 'dashdot'], index=index) + aa = pd.Series([True, False, True], index=index) + + Collection(edgecolors=ec) + Collection(facecolors=fc) + Collection(linewidths=lw) + Collection(linestyles=ls) + Collection(antialiaseds=aa) + + +@mpl.style.context('default') +def test_lslw_bcast(): + col = mcollections.PathCollection([]) + col.set_linestyles(['-', '-']) + col.set_linewidths([1, 2, 3]) + + assert col.get_linestyles() == [(0, None)] * 6 + assert col.get_linewidths() == [1, 2, 3] * 2 + + col.set_linestyles(['-', '-', '-']) + assert col.get_linestyles() == [(0, None)] * 3 + assert (col.get_linewidths() == [1, 2, 3]).all() + + +def test_set_wrong_linestyle(): + c = Collection() + with pytest.raises(ValueError, match="Do not know how to convert 'fuzzy'"): + c.set_linestyle('fuzzy') + + +@mpl.style.context('default') +def test_capstyle(): + col = mcollections.PathCollection([]) + assert col.get_capstyle() is None + col = mcollections.PathCollection([], capstyle='round') + assert col.get_capstyle() == 'round' + col.set_capstyle('butt') + assert col.get_capstyle() == 'butt' + + +@mpl.style.context('default') +def test_joinstyle(): + col = mcollections.PathCollection([]) + assert col.get_joinstyle() is None + col = mcollections.PathCollection([], joinstyle='round') + assert col.get_joinstyle() == 'round' + col.set_joinstyle('miter') + assert col.get_joinstyle() == 'miter' + + +@image_comparison(['cap_and_joinstyle.png']) +def test_cap_and_joinstyle_image(): + fig, ax = plt.subplots() + ax.set_xlim([-0.5, 1.5]) + ax.set_ylim([-0.5, 2.5]) + + x = np.array([0.0, 1.0, 0.5]) + ys = np.array([[0.0], [0.5], [1.0]]) + np.array([[0.0, 0.0, 1.0]]) + + segs = np.zeros((3, 3, 2)) + segs[:, :, 0] = x + segs[:, :, 1] = ys + line_segments = LineCollection(segs, linewidth=[10, 15, 20]) + line_segments.set_capstyle("round") + line_segments.set_joinstyle("miter") + + ax.add_collection(line_segments) + ax.set_title('Line collection with customized caps and joinstyle') + + +@image_comparison(['scatter_post_alpha.png'], + remove_text=True, style='default') +def test_scatter_post_alpha(): + fig, ax = plt.subplots() + sc = ax.scatter(range(5), range(5), c=range(5)) + sc.set_alpha(.1) + + +def test_scatter_alpha_array(): + x = np.arange(5) + alpha = x / 5 + # With colormapping. + fig, (ax0, ax1) = plt.subplots(2) + sc0 = ax0.scatter(x, x, c=x, alpha=alpha) + sc1 = ax1.scatter(x, x, c=x) + sc1.set_alpha(alpha) + plt.draw() + assert_array_equal(sc0.get_facecolors()[:, -1], alpha) + assert_array_equal(sc1.get_facecolors()[:, -1], alpha) + # Without colormapping. + fig, (ax0, ax1) = plt.subplots(2) + sc0 = ax0.scatter(x, x, color=['r', 'g', 'b', 'c', 'm'], alpha=alpha) + sc1 = ax1.scatter(x, x, color='r', alpha=alpha) + plt.draw() + assert_array_equal(sc0.get_facecolors()[:, -1], alpha) + assert_array_equal(sc1.get_facecolors()[:, -1], alpha) + # Without colormapping, and set alpha afterward. + fig, (ax0, ax1) = plt.subplots(2) + sc0 = ax0.scatter(x, x, color=['r', 'g', 'b', 'c', 'm']) + sc0.set_alpha(alpha) + sc1 = ax1.scatter(x, x, color='r') + sc1.set_alpha(alpha) + plt.draw() + assert_array_equal(sc0.get_facecolors()[:, -1], alpha) + assert_array_equal(sc1.get_facecolors()[:, -1], alpha) + + +def test_pathcollection_legend_elements(): + np.random.seed(19680801) + x, y = np.random.rand(2, 10) + y = np.random.rand(10) + c = np.random.randint(0, 5, size=10) + s = np.random.randint(10, 300, size=10) + + fig, ax = plt.subplots() + sc = ax.scatter(x, y, c=c, s=s, cmap="jet", marker="o", linewidths=0) + + h, l = sc.legend_elements(fmt="{x:g}") + assert len(h) == 5 + assert l == ["0", "1", "2", "3", "4"] + colors = np.array([line.get_color() for line in h]) + colors2 = sc.cmap(np.arange(5)/4) + assert_array_equal(colors, colors2) + l1 = ax.legend(h, l, loc=1) + + h2, lab2 = sc.legend_elements(num=9) + assert len(h2) == 9 + l2 = ax.legend(h2, lab2, loc=2) + + h, l = sc.legend_elements(prop="sizes", alpha=0.5, color="red") + assert all(line.get_alpha() == 0.5 for line in h) + assert all(line.get_markerfacecolor() == "red" for line in h) + l3 = ax.legend(h, l, loc=4) + + h, l = sc.legend_elements(prop="sizes", num=4, fmt="{x:.2f}", + func=lambda x: 2*x) + actsizes = [line.get_markersize() for line in h] + labeledsizes = np.sqrt(np.array(l, float) / 2) + assert_array_almost_equal(actsizes, labeledsizes) + l4 = ax.legend(h, l, loc=3) + + loc = mpl.ticker.MaxNLocator(nbins=9, min_n_ticks=9-1, + steps=[1, 2, 2.5, 3, 5, 6, 8, 10]) + h5, lab5 = sc.legend_elements(num=loc) + assert len(h2) == len(h5) + + levels = [-1, 0, 55.4, 260] + h6, lab6 = sc.legend_elements(num=levels, prop="sizes", fmt="{x:g}") + assert [float(l) for l in lab6] == levels[2:] + + for l in [l1, l2, l3, l4]: + ax.add_artist(l) + + fig.canvas.draw() + + +def test_EventCollection_nosort(): + # Check that EventCollection doesn't modify input in place + arr = np.array([3, 2, 1, 10]) + coll = EventCollection(arr) + np.testing.assert_array_equal(arr, np.array([3, 2, 1, 10])) + + +def test_collection_set_verts_array(): + verts = np.arange(80, dtype=np.double).reshape(10, 4, 2) + col_arr = PolyCollection(verts) + col_list = PolyCollection(list(verts)) + assert len(col_arr._paths) == len(col_list._paths) + for ap, lp in zip(col_arr._paths, col_list._paths): + assert np.array_equal(ap._vertices, lp._vertices) + assert np.array_equal(ap._codes, lp._codes) + + verts_tuple = np.empty(10, dtype=object) + verts_tuple[:] = [tuple(tuple(y) for y in x) for x in verts] + col_arr_tuple = PolyCollection(verts_tuple) + assert len(col_arr._paths) == len(col_arr_tuple._paths) + for ap, atp in zip(col_arr._paths, col_arr_tuple._paths): + assert np.array_equal(ap._vertices, atp._vertices) + assert np.array_equal(ap._codes, atp._codes) + + +def test_collection_set_array(): + vals = [*range(10)] + + # Test set_array with list + c = Collection() + c.set_array(vals) + + # Test set_array with wrong dtype + with pytest.raises(TypeError, match="^Image data of dtype"): + c.set_array("wrong_input") + + # Test if array kwarg is copied + vals[5] = 45 + assert np.not_equal(vals, c.get_array()).any() + + +def test_blended_collection_autolim(): + a = [1, 2, 4] + height = .2 + + xy_pairs = np.column_stack([np.repeat(a, 2), np.tile([0, height], len(a))]) + line_segs = xy_pairs.reshape([len(a), 2, 2]) + + f, ax = plt.subplots() + trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes) + ax.add_collection(LineCollection(line_segs, transform=trans)) + ax.autoscale_view(scalex=True, scaley=False) + np.testing.assert_allclose(ax.get_xlim(), [1., 4.]) + + +def test_singleton_autolim(): + fig, ax = plt.subplots() + ax.scatter(0, 0) + np.testing.assert_allclose(ax.get_ylim(), [-0.06, 0.06]) + np.testing.assert_allclose(ax.get_xlim(), [-0.06, 0.06]) + + +@pytest.mark.parametrize("transform, expected", [ + ("transData", (-0.5, 3.5)), + ("transAxes", (2.8, 3.2)), +]) +def test_autolim_with_zeros(transform, expected): + # 1) Test that a scatter at (0, 0) data coordinates contributes to + # autoscaling even though any(offsets) would be False in that situation. + # 2) Test that specifying transAxes for the transform does not contribute + # to the autoscaling. + fig, ax = plt.subplots() + ax.scatter(0, 0, transform=getattr(ax, transform)) + ax.scatter(3, 3) + np.testing.assert_allclose(ax.get_ylim(), expected) + np.testing.assert_allclose(ax.get_xlim(), expected) + + +def test_quadmesh_set_array_validation(pcfunc): + x = np.arange(11) + y = np.arange(8) + z = np.random.random((7, 10)) + fig, ax = plt.subplots() + coll = getattr(ax, pcfunc)(x, y, z) + + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (10, 7)")): + coll.set_array(z.reshape(10, 7)) + + z = np.arange(54).reshape((6, 9)) + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (6, 9)")): + coll.set_array(z) + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (54,)")): + coll.set_array(z.ravel()) + + # RGB(A) tests + z = np.ones((9, 6, 3)) # RGB with wrong X/Y dims + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (9, 6, 3)")): + coll.set_array(z) + + z = np.ones((9, 6, 4)) # RGBA with wrong X/Y dims + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (9, 6, 4)")): + coll.set_array(z) + + z = np.ones((7, 10, 2)) # Right X/Y dims, bad 3rd dim + with pytest.raises(ValueError, match=re.escape( + "For X (11) and Y (8) with flat shading, A should have shape " + "(7, 10, 3) or (7, 10, 4) or (7, 10) or (70,), not (7, 10, 2)")): + coll.set_array(z) + + x = np.arange(10) + y = np.arange(7) + z = np.random.random((7, 10)) + fig, ax = plt.subplots() + coll = ax.pcolormesh(x, y, z, shading='gouraud') + + +def test_polyquadmesh_masked_vertices_array(): + xx, yy = np.meshgrid([0, 1, 2], [0, 1, 2, 3]) + # 2 x 3 mesh data + zz = (xx*yy)[:-1, :-1] + quadmesh = plt.pcolormesh(xx, yy, zz) + quadmesh.update_scalarmappable() + quadmesh_fc = quadmesh.get_facecolor()[1:, :] + # Mask the origin vertex in x + xx = np.ma.masked_where((xx == 0) & (yy == 0), xx) + polymesh = plt.pcolor(xx, yy, zz) + polymesh.update_scalarmappable() + # One cell should be left out + assert len(polymesh.get_paths()) == 5 + # Poly version should have the same facecolors as the end of the quadmesh + assert_array_equal(quadmesh_fc, polymesh.get_facecolor()) + + # Mask the origin vertex in y + yy = np.ma.masked_where((xx == 0) & (yy == 0), yy) + polymesh = plt.pcolor(xx, yy, zz) + polymesh.update_scalarmappable() + # One cell should be left out + assert len(polymesh.get_paths()) == 5 + # Poly version should have the same facecolors as the end of the quadmesh + assert_array_equal(quadmesh_fc, polymesh.get_facecolor()) + + # Mask the origin cell data + zz = np.ma.masked_where((xx[:-1, :-1] == 0) & (yy[:-1, :-1] == 0), zz) + polymesh = plt.pcolor(zz) + polymesh.update_scalarmappable() + # One cell should be left out + assert len(polymesh.get_paths()) == 5 + # Poly version should have the same facecolors as the end of the quadmesh + assert_array_equal(quadmesh_fc, polymesh.get_facecolor()) + + # Setting array with 1D compressed values is deprecated + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="Setting a PolyQuadMesh"): + polymesh.set_array(np.ones(5)) + + # We should also be able to call set_array with a new mask and get + # updated polys + # Remove mask, should add all polys back + zz = np.arange(6).reshape((3, 2)) + polymesh.set_array(zz) + polymesh.update_scalarmappable() + assert len(polymesh.get_paths()) == 6 + # Add mask should remove polys + zz = np.ma.masked_less(zz, 2) + polymesh.set_array(zz) + polymesh.update_scalarmappable() + assert len(polymesh.get_paths()) == 4 + + +def test_quadmesh_get_coordinates(pcfunc): + x = [0, 1, 2] + y = [2, 4, 6] + z = np.ones(shape=(2, 2)) + xx, yy = np.meshgrid(x, y) + coll = getattr(plt, pcfunc)(xx, yy, z) + + # shape (3, 3, 2) + coords = np.stack([xx.T, yy.T]).T + assert_array_equal(coll.get_coordinates(), coords) + + +def test_quadmesh_set_array(): + x = np.arange(4) + y = np.arange(4) + z = np.arange(9).reshape((3, 3)) + fig, ax = plt.subplots() + coll = ax.pcolormesh(x, y, np.ones(z.shape)) + # Test that the collection is able to update with a 2d array + coll.set_array(z) + fig.canvas.draw() + assert np.array_equal(coll.get_array(), z) + + # Check that pre-flattened arrays work too + coll.set_array(np.ones(9)) + fig.canvas.draw() + assert np.array_equal(coll.get_array(), np.ones(9)) + + z = np.arange(16).reshape((4, 4)) + fig, ax = plt.subplots() + coll = ax.pcolormesh(x, y, np.ones(z.shape), shading='gouraud') + # Test that the collection is able to update with a 2d array + coll.set_array(z) + fig.canvas.draw() + assert np.array_equal(coll.get_array(), z) + + # Check that pre-flattened arrays work too + coll.set_array(np.ones(16)) + fig.canvas.draw() + assert np.array_equal(coll.get_array(), np.ones(16)) + + +def test_quadmesh_vmin_vmax(pcfunc): + # test when vmin/vmax on the norm changes, the quadmesh gets updated + fig, ax = plt.subplots() + cmap = mpl.colormaps['plasma'] + norm = mpl.colors.Normalize(vmin=0, vmax=1) + coll = getattr(ax, pcfunc)([[1]], cmap=cmap, norm=norm) + fig.canvas.draw() + assert np.array_equal(coll.get_facecolors()[0, :], cmap(norm(1))) + + # Change the vmin/vmax of the norm so that the color is from + # the bottom of the colormap now + norm.vmin, norm.vmax = 1, 2 + fig.canvas.draw() + assert np.array_equal(coll.get_facecolors()[0, :], cmap(norm(1))) + + +def test_quadmesh_alpha_array(pcfunc): + x = np.arange(4) + y = np.arange(4) + z = np.arange(9).reshape((3, 3)) + alpha = z / z.max() + alpha_flat = alpha.ravel() + # Provide 2-D alpha: + fig, (ax0, ax1) = plt.subplots(2) + coll1 = getattr(ax0, pcfunc)(x, y, z, alpha=alpha) + coll2 = getattr(ax0, pcfunc)(x, y, z) + coll2.set_alpha(alpha) + plt.draw() + assert_array_equal(coll1.get_facecolors()[:, -1], alpha_flat) + assert_array_equal(coll2.get_facecolors()[:, -1], alpha_flat) + # Or provide 1-D alpha: + fig, (ax0, ax1) = plt.subplots(2) + coll1 = getattr(ax0, pcfunc)(x, y, z, alpha=alpha) + coll2 = getattr(ax1, pcfunc)(x, y, z) + coll2.set_alpha(alpha) + plt.draw() + assert_array_equal(coll1.get_facecolors()[:, -1], alpha_flat) + assert_array_equal(coll2.get_facecolors()[:, -1], alpha_flat) + + +def test_alpha_validation(pcfunc): + # Most of the relevant testing is in test_artist and test_colors. + fig, ax = plt.subplots() + pc = getattr(ax, pcfunc)(np.arange(12).reshape((3, 4))) + with pytest.raises(ValueError, match="^Data array shape"): + pc.set_alpha([0.5, 0.6]) + pc.update_scalarmappable() + + +def test_legend_inverse_size_label_relationship(): + """ + Ensure legend markers scale appropriately when label and size are + inversely related. + Here label = 5 / size + """ + + np.random.seed(19680801) + X = np.random.random(50) + Y = np.random.random(50) + C = 1 - np.random.random(50) + S = 5 / C + + legend_sizes = [0.2, 0.4, 0.6, 0.8] + fig, ax = plt.subplots() + sc = ax.scatter(X, Y, s=S) + handles, labels = sc.legend_elements( + prop='sizes', num=legend_sizes, func=lambda s: 5 / s + ) + + # Convert markersize scale to 's' scale + handle_sizes = [x.get_markersize() for x in handles] + handle_sizes = [5 / x**2 for x in handle_sizes] + + assert_array_almost_equal(handle_sizes, legend_sizes, decimal=1) + + +@mpl.style.context('default') +def test_color_logic(pcfunc): + pcfunc = getattr(plt, pcfunc) + z = np.arange(12).reshape(3, 4) + # Explicitly set an edgecolor. + pc = pcfunc(z, edgecolors='red', facecolors='none') + pc.update_scalarmappable() # This is called in draw(). + # Define 2 reference "colors" here for multiple use. + face_default = mcolors.to_rgba_array(pc._get_default_facecolor()) + mapped = pc.get_cmap()(pc.norm(z.ravel())) + # GitHub issue #1302: + assert mcolors.same_color(pc.get_edgecolor(), 'red') + # Check setting attributes after initialization: + pc = pcfunc(z) + pc.set_facecolor('none') + pc.set_edgecolor('red') + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_facecolor(), 'none') + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + pc.set_alpha(0.5) + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 0.5]]) + pc.set_alpha(None) # restore default alpha + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + # Reset edgecolor to default. + pc.set_edgecolor(None) + pc.update_scalarmappable() + assert np.array_equal(pc.get_edgecolor(), mapped) + pc.set_facecolor(None) # restore default for facecolor + pc.update_scalarmappable() + assert np.array_equal(pc.get_facecolor(), mapped) + assert mcolors.same_color(pc.get_edgecolor(), 'none') + # Turn off colormapping entirely: + pc.set_array(None) + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_edgecolor(), 'none') + assert mcolors.same_color(pc.get_facecolor(), face_default) # not mapped + # Turn it back on by restoring the array (must be 1D!): + pc.set_array(z) + pc.update_scalarmappable() + assert np.array_equal(pc.get_facecolor(), mapped) + assert mcolors.same_color(pc.get_edgecolor(), 'none') + # Give color via tuple rather than string. + pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=(0, 1, 0)) + pc.update_scalarmappable() + assert np.array_equal(pc.get_facecolor(), mapped) + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + # Provide an RGB array; mapping overrides it. + pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=np.ones((12, 3))) + pc.update_scalarmappable() + assert np.array_equal(pc.get_facecolor(), mapped) + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + # Turn off the mapping. + pc.set_array(None) + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_facecolor(), np.ones((12, 3))) + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + # And an RGBA array. + pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=np.ones((12, 4))) + pc.update_scalarmappable() + assert np.array_equal(pc.get_facecolor(), mapped) + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + # Turn off the mapping. + pc.set_array(None) + pc.update_scalarmappable() + assert mcolors.same_color(pc.get_facecolor(), np.ones((12, 4))) + assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]]) + + +def test_LineCollection_args(): + lc = LineCollection(None, linewidth=2.2, edgecolor='r', + zorder=3, facecolors=[0, 1, 0, 1]) + assert lc.get_linewidth()[0] == 2.2 + assert mcolors.same_color(lc.get_edgecolor(), 'r') + assert lc.get_zorder() == 3 + assert mcolors.same_color(lc.get_facecolor(), [[0, 1, 0, 1]]) + # To avoid breaking mplot3d, LineCollection internally sets the facecolor + # kwarg if it has not been specified. Hence we need the following test + # for LineCollection._set_default(). + lc = LineCollection(None, facecolor=None) + assert mcolors.same_color(lc.get_facecolor(), 'none') + + +def test_array_dimensions(pcfunc): + # Make sure we can set the 1D, 2D, and 3D array shapes + z = np.arange(12).reshape(3, 4) + pc = getattr(plt, pcfunc)(z) + # 1D + pc.set_array(z.ravel()) + pc.update_scalarmappable() + # 2D + pc.set_array(z) + pc.update_scalarmappable() + # 3D RGB is OK as well + z = np.arange(36, dtype=np.uint8).reshape(3, 4, 3) + pc.set_array(z) + pc.update_scalarmappable() + + +def test_get_segments(): + segments = np.tile(np.linspace(0, 1, 256), (2, 1)).T + lc = LineCollection([segments]) + + readback, = lc.get_segments() + # these should comeback un-changed! + assert np.all(segments == readback) + + +def test_set_offsets_late(): + identity = mtransforms.IdentityTransform() + sizes = [2] + + null = mcollections.CircleCollection(sizes=sizes) + + init = mcollections.CircleCollection(sizes=sizes, offsets=(10, 10)) + + late = mcollections.CircleCollection(sizes=sizes) + late.set_offsets((10, 10)) + + # Bbox.__eq__ doesn't compare bounds + null_bounds = null.get_datalim(identity).bounds + init_bounds = init.get_datalim(identity).bounds + late_bounds = late.get_datalim(identity).bounds + + # offsets and transform are applied when set after initialization + assert null_bounds != init_bounds + assert init_bounds == late_bounds + + +def test_set_offset_transform(): + skew = mtransforms.Affine2D().skew(2, 2) + init = mcollections.Collection(offset_transform=skew) + + late = mcollections.Collection() + late.set_offset_transform(skew) + + assert skew == init.get_offset_transform() == late.get_offset_transform() + + +def test_set_offset_units(): + # passing the offsets in initially (i.e. via scatter) + # should yield the same results as `set_offsets` + x = np.linspace(0, 10, 5) + y = np.sin(x) + d = x * np.timedelta64(24, 'h') + np.datetime64('2021-11-29') + + sc = plt.scatter(d, y) + off0 = sc.get_offsets() + sc.set_offsets(list(zip(d, y))) + np.testing.assert_allclose(off0, sc.get_offsets()) + + # try the other way around + fig, ax = plt.subplots() + sc = ax.scatter(y, d) + off0 = sc.get_offsets() + sc.set_offsets(list(zip(y, d))) + np.testing.assert_allclose(off0, sc.get_offsets()) + + +@image_comparison(baseline_images=["test_check_masked_offsets"], + extensions=["png"], remove_text=True, style="mpl20") +def test_check_masked_offsets(): + # Check if masked data is respected by scatter + # Ref: Issue #24545 + unmasked_x = [ + datetime(2022, 12, 15, 4, 49, 52), + datetime(2022, 12, 15, 4, 49, 53), + datetime(2022, 12, 15, 4, 49, 54), + datetime(2022, 12, 15, 4, 49, 55), + datetime(2022, 12, 15, 4, 49, 56), + ] + + masked_y = np.ma.array([1, 2, 3, 4, 5], mask=[0, 1, 1, 0, 0]) + + fig, ax = plt.subplots() + ax.scatter(unmasked_x, masked_y) + + +@check_figures_equal(extensions=["png"]) +def test_masked_set_offsets(fig_ref, fig_test): + x = np.ma.array([1, 2, 3, 4, 5], mask=[0, 0, 1, 1, 0]) + y = np.arange(1, 6) + + ax_test = fig_test.add_subplot() + scat = ax_test.scatter(x, y) + scat.set_offsets(np.ma.column_stack([x, y])) + ax_test.set_xticks([]) + ax_test.set_yticks([]) + + ax_ref = fig_ref.add_subplot() + ax_ref.scatter([1, 2, 5], [1, 2, 5]) + ax_ref.set_xticks([]) + ax_ref.set_yticks([]) + + +def test_check_offsets_dtype(): + # Check that setting offsets doesn't change dtype + x = np.ma.array([1, 2, 3, 4, 5], mask=[0, 0, 1, 1, 0]) + y = np.arange(1, 6) + + fig, ax = plt.subplots() + scat = ax.scatter(x, y) + masked_offsets = np.ma.column_stack([x, y]) + scat.set_offsets(masked_offsets) + assert isinstance(scat.get_offsets(), type(masked_offsets)) + + unmasked_offsets = np.column_stack([x, y]) + scat.set_offsets(unmasked_offsets) + assert isinstance(scat.get_offsets(), type(unmasked_offsets)) + + +@pytest.mark.parametrize('gapcolor', ['orange', ['r', 'k']]) +@check_figures_equal(extensions=['png']) +@mpl.rc_context({'lines.linewidth': 20}) +def test_striped_lines(fig_test, fig_ref, gapcolor): + ax_test = fig_test.add_subplot(111) + ax_ref = fig_ref.add_subplot(111) + + for ax in [ax_test, ax_ref]: + ax.set_xlim(0, 6) + ax.set_ylim(0, 1) + + x = range(1, 6) + linestyles = [':', '-', '--'] + + ax_test.vlines(x, 0, 1, linestyle=linestyles, gapcolor=gapcolor, alpha=0.5) + + if isinstance(gapcolor, str): + gapcolor = [gapcolor] + + for x, gcol, ls in zip(x, itertools.cycle(gapcolor), + itertools.cycle(linestyles)): + ax_ref.axvline(x, 0, 1, linestyle=ls, gapcolor=gcol, alpha=0.5) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colorbar.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colorbar.py new file mode 100644 index 00000000..0cf098e7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colorbar.py @@ -0,0 +1,1238 @@ +import platform + +import numpy as np +import pytest + +from matplotlib import cm +import matplotlib.colors as mcolors +import matplotlib as mpl + + +from matplotlib import rc_context +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +from matplotlib.colors import ( + BoundaryNorm, LogNorm, PowerNorm, Normalize, NoNorm +) +from matplotlib.colorbar import Colorbar +from matplotlib.ticker import FixedLocator, LogFormatter, StrMethodFormatter +from matplotlib.testing.decorators import check_figures_equal + + +def _get_cmap_norms(): + """ + Define a colormap and appropriate norms for each of the four + possible settings of the extend keyword. + + Helper function for _colorbar_extension_shape and + colorbar_extension_length. + """ + # Create a colormap and specify the levels it represents. + cmap = mpl.colormaps["RdBu"].resampled(5) + clevs = [-5., -2.5, -.5, .5, 1.5, 3.5] + # Define norms for the colormaps. + norms = dict() + norms['neither'] = BoundaryNorm(clevs, len(clevs) - 1) + norms['min'] = BoundaryNorm([-10] + clevs[1:], len(clevs) - 1) + norms['max'] = BoundaryNorm(clevs[:-1] + [10], len(clevs) - 1) + norms['both'] = BoundaryNorm([-10] + clevs[1:-1] + [10], len(clevs) - 1) + return cmap, norms + + +def _colorbar_extension_shape(spacing): + """ + Produce 4 colorbars with rectangular extensions for either uniform + or proportional spacing. + + Helper function for test_colorbar_extension_shape. + """ + # Get a colormap and appropriate norms for each extension type. + cmap, norms = _get_cmap_norms() + # Create a figure and adjust whitespace for subplots. + fig = plt.figure() + fig.subplots_adjust(hspace=4) + for i, extension_type in enumerate(('neither', 'min', 'max', 'both')): + # Get the appropriate norm and use it to get colorbar boundaries. + norm = norms[extension_type] + boundaries = values = norm.boundaries + # note that the last value was silently dropped pre 3.3: + values = values[:-1] + # Create a subplot. + cax = fig.add_subplot(4, 1, i + 1) + # Generate the colorbar. + Colorbar(cax, cmap=cmap, norm=norm, + boundaries=boundaries, values=values, + extend=extension_type, extendrect=True, + orientation='horizontal', spacing=spacing) + # Turn off text and ticks. + cax.tick_params(left=False, labelleft=False, + bottom=False, labelbottom=False) + # Return the figure to the caller. + return fig + + +def _colorbar_extension_length(spacing): + """ + Produce 12 colorbars with variable length extensions for either + uniform or proportional spacing. + + Helper function for test_colorbar_extension_length. + """ + # Get a colormap and appropriate norms for each extension type. + cmap, norms = _get_cmap_norms() + # Create a figure and adjust whitespace for subplots. + fig = plt.figure() + fig.subplots_adjust(hspace=.6) + for i, extension_type in enumerate(('neither', 'min', 'max', 'both')): + # Get the appropriate norm and use it to get colorbar boundaries. + norm = norms[extension_type] + boundaries = values = norm.boundaries + values = values[:-1] + for j, extendfrac in enumerate((None, 'auto', 0.1)): + # Create a subplot. + cax = fig.add_subplot(12, 1, i*3 + j + 1) + # Generate the colorbar. + Colorbar(cax, cmap=cmap, norm=norm, + boundaries=boundaries, values=values, + extend=extension_type, extendfrac=extendfrac, + orientation='horizontal', spacing=spacing) + # Turn off text and ticks. + cax.tick_params(left=False, labelleft=False, + bottom=False, labelbottom=False) + # Return the figure to the caller. + return fig + + +@image_comparison(['colorbar_extensions_shape_uniform.png', + 'colorbar_extensions_shape_proportional.png']) +def test_colorbar_extension_shape(): + """Test rectangular colorbar extensions.""" + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + # Create figures for uniform and proportionally spaced colorbars. + _colorbar_extension_shape('uniform') + _colorbar_extension_shape('proportional') + + +@image_comparison(['colorbar_extensions_uniform.png', + 'colorbar_extensions_proportional.png'], + tol=1.0) +def test_colorbar_extension_length(): + """Test variable length colorbar extensions.""" + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + # Create figures for uniform and proportionally spaced colorbars. + _colorbar_extension_length('uniform') + _colorbar_extension_length('proportional') + + +@pytest.mark.parametrize("orientation", ["horizontal", "vertical"]) +@pytest.mark.parametrize("extend,expected", [("min", (0, 0, 0, 1)), + ("max", (1, 1, 1, 1)), + ("both", (1, 1, 1, 1))]) +def test_colorbar_extension_inverted_axis(orientation, extend, expected): + """Test extension color with an inverted axis""" + data = np.arange(12).reshape(3, 4) + fig, ax = plt.subplots() + cmap = mpl.colormaps["viridis"].with_extremes(under=(0, 0, 0, 1), + over=(1, 1, 1, 1)) + im = ax.imshow(data, cmap=cmap) + cbar = fig.colorbar(im, orientation=orientation, extend=extend) + if orientation == "horizontal": + cbar.ax.invert_xaxis() + else: + cbar.ax.invert_yaxis() + assert cbar._extend_patches[0].get_facecolor() == expected + if extend == "both": + assert len(cbar._extend_patches) == 2 + assert cbar._extend_patches[1].get_facecolor() == (0, 0, 0, 1) + else: + assert len(cbar._extend_patches) == 1 + + +@pytest.mark.parametrize('use_gridspec', [True, False]) +@image_comparison(['cbar_with_orientation', + 'cbar_locationing', + 'double_cbar', + 'cbar_sharing', + ], + extensions=['png'], remove_text=True, + savefig_kwarg={'dpi': 40}) +def test_colorbar_positioning(use_gridspec): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + data = np.arange(1200).reshape(30, 40) + levels = [0, 200, 400, 600, 800, 1000, 1200] + + # ------------------- + plt.figure() + plt.contourf(data, levels=levels) + plt.colorbar(orientation='horizontal', use_gridspec=use_gridspec) + + locations = ['left', 'right', 'top', 'bottom'] + plt.figure() + for i, location in enumerate(locations): + plt.subplot(2, 2, i + 1) + plt.contourf(data, levels=levels) + plt.colorbar(location=location, use_gridspec=use_gridspec) + + # ------------------- + plt.figure() + # make some other data (random integers) + data_2nd = np.array([[2, 3, 2, 3], [1.5, 2, 2, 3], [2, 3, 3, 4]]) + # make the random data expand to the shape of the main data + data_2nd = np.repeat(np.repeat(data_2nd, 10, axis=1), 10, axis=0) + + color_mappable = plt.contourf(data, levels=levels, extend='both') + # test extend frac here + hatch_mappable = plt.contourf(data_2nd, levels=[1, 2, 3], colors='none', + hatches=['/', 'o', '+'], extend='max') + plt.contour(hatch_mappable, colors='black') + + plt.colorbar(color_mappable, location='left', label='variable 1', + use_gridspec=use_gridspec) + plt.colorbar(hatch_mappable, location='right', label='variable 2', + use_gridspec=use_gridspec) + + # ------------------- + plt.figure() + ax1 = plt.subplot(211, anchor='NE', aspect='equal') + plt.contourf(data, levels=levels) + ax2 = plt.subplot(223) + plt.contourf(data, levels=levels) + ax3 = plt.subplot(224) + plt.contourf(data, levels=levels) + + plt.colorbar(ax=[ax2, ax3, ax1], location='right', pad=0.0, shrink=0.5, + panchor=False, use_gridspec=use_gridspec) + plt.colorbar(ax=[ax2, ax3, ax1], location='left', shrink=0.5, + panchor=False, use_gridspec=use_gridspec) + plt.colorbar(ax=[ax1], location='bottom', panchor=False, + anchor=(0.8, 0.5), shrink=0.6, use_gridspec=use_gridspec) + + +def test_colorbar_single_ax_panchor_false(): + # Note that this differs from the tests above with panchor=False because + # there use_gridspec is actually ineffective: passing *ax* as lists always + # disables use_gridspec. + ax = plt.subplot(111, anchor='N') + plt.imshow([[0, 1]]) + plt.colorbar(panchor=False) + assert ax.get_anchor() == 'N' + + +@pytest.mark.parametrize('constrained', [False, True], + ids=['standard', 'constrained']) +def test_colorbar_single_ax_panchor_east(constrained): + fig = plt.figure(constrained_layout=constrained) + ax = fig.add_subplot(111, anchor='N') + plt.imshow([[0, 1]]) + plt.colorbar(panchor='E') + assert ax.get_anchor() == 'E' + + +@image_comparison( + ['contour_colorbar.png'], remove_text=True, + tol=0.01 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_contour_colorbar(): + fig, ax = plt.subplots(figsize=(4, 2)) + data = np.arange(1200).reshape(30, 40) - 500 + levels = np.array([0, 200, 400, 600, 800, 1000, 1200]) - 500 + + CS = ax.contour(data, levels=levels, extend='both') + fig.colorbar(CS, orientation='horizontal', extend='both') + fig.colorbar(CS, orientation='vertical') + + +@image_comparison(['cbar_with_subplots_adjust.png'], remove_text=True, + savefig_kwarg={'dpi': 40}) +def test_gridspec_make_colorbar(): + plt.figure() + data = np.arange(1200).reshape(30, 40) + levels = [0, 200, 400, 600, 800, 1000, 1200] + + plt.subplot(121) + plt.contourf(data, levels=levels) + plt.colorbar(use_gridspec=True, orientation='vertical') + + plt.subplot(122) + plt.contourf(data, levels=levels) + plt.colorbar(use_gridspec=True, orientation='horizontal') + + plt.subplots_adjust(top=0.95, right=0.95, bottom=0.2, hspace=0.25) + + +@image_comparison(['colorbar_single_scatter.png'], remove_text=True, + savefig_kwarg={'dpi': 40}) +def test_colorbar_single_scatter(): + # Issue #2642: if a path collection has only one entry, + # the norm scaling within the colorbar must ensure a + # finite range, otherwise a zero denominator will occur in _locate. + plt.figure() + x = y = [0] + z = [50] + cmap = mpl.colormaps['jet'].resampled(16) + cs = plt.scatter(x, y, z, c=z, cmap=cmap) + plt.colorbar(cs) + + +@pytest.mark.parametrize('use_gridspec', [False, True], + ids=['no gridspec', 'with gridspec']) +def test_remove_from_figure(use_gridspec): + """ + Test `remove` with the specified ``use_gridspec`` setting + """ + fig, ax = plt.subplots() + sc = ax.scatter([1, 2], [3, 4]) + sc.set_array(np.array([5, 6])) + pre_position = ax.get_position() + cb = fig.colorbar(sc, use_gridspec=use_gridspec) + fig.subplots_adjust() + cb.remove() + fig.subplots_adjust() + post_position = ax.get_position() + assert (pre_position.get_points() == post_position.get_points()).all() + + +def test_remove_from_figure_cl(): + """ + Test `remove` with constrained_layout + """ + fig, ax = plt.subplots(constrained_layout=True) + sc = ax.scatter([1, 2], [3, 4]) + sc.set_array(np.array([5, 6])) + fig.draw_without_rendering() + pre_position = ax.get_position() + cb = fig.colorbar(sc) + cb.remove() + fig.draw_without_rendering() + post_position = ax.get_position() + np.testing.assert_allclose(pre_position.get_points(), + post_position.get_points()) + + +def test_colorbarbase(): + # smoke test from #3805 + ax = plt.gca() + Colorbar(ax, cmap=plt.cm.bone) + + +def test_parentless_mappable(): + pc = mpl.collections.PatchCollection([], cmap=plt.get_cmap('viridis'), array=[]) + with pytest.raises(ValueError, match='Unable to determine Axes to steal'): + plt.colorbar(pc) + + +@image_comparison(['colorbar_closed_patch.png'], remove_text=True) +def test_colorbar_closed_patch(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig = plt.figure(figsize=(8, 6)) + ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1]) + ax2 = fig.add_axes([0.1, 0.65, 0.75, 0.1]) + ax3 = fig.add_axes([0.05, 0.45, 0.9, 0.1]) + ax4 = fig.add_axes([0.05, 0.25, 0.9, 0.1]) + ax5 = fig.add_axes([0.05, 0.05, 0.9, 0.1]) + + cmap = mpl.colormaps["RdBu"].resampled(5) + + im = ax1.pcolormesh(np.linspace(0, 10, 16).reshape((4, 4)), cmap=cmap) + + # The use of a "values" kwarg here is unusual. It works only + # because it is matched to the data range in the image and to + # the number of colors in the LUT. + values = np.linspace(0, 10, 5) + cbar_kw = dict(orientation='horizontal', values=values, ticks=[]) + + # The wide line is to show that the closed path is being handled + # correctly. See PR #4186. + with rc_context({'axes.linewidth': 16}): + plt.colorbar(im, cax=ax2, extend='both', extendfrac=0.5, **cbar_kw) + plt.colorbar(im, cax=ax3, extend='both', **cbar_kw) + plt.colorbar(im, cax=ax4, extend='both', extendrect=True, **cbar_kw) + plt.colorbar(im, cax=ax5, extend='neither', **cbar_kw) + + +def test_colorbar_ticks(): + # test fix for #5673 + fig, ax = plt.subplots() + x = np.arange(-3.0, 4.001) + y = np.arange(-4.0, 3.001) + X, Y = np.meshgrid(x, y) + Z = X * Y + clevs = np.array([-12, -5, 0, 5, 12], dtype=float) + colors = ['r', 'g', 'b', 'c'] + cs = ax.contourf(X, Y, Z, clevs, colors=colors, extend='neither') + cbar = fig.colorbar(cs, ax=ax, orientation='horizontal', ticks=clevs) + assert len(cbar.ax.xaxis.get_ticklocs()) == len(clevs) + + +def test_colorbar_minorticks_on_off(): + # test for github issue #11510 and PR #11584 + np.random.seed(seed=12345) + data = np.random.randn(20, 20) + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots() + # purposefully setting vmin and vmax to odd fractions + # so as to check for the correct locations of the minor ticks + im = ax.pcolormesh(data, vmin=-2.3, vmax=3.3) + + cbar = fig.colorbar(im, extend='both') + # testing after minorticks_on() + cbar.minorticks_on() + np.testing.assert_almost_equal( + cbar.ax.yaxis.get_minorticklocs(), + [-2.2, -1.8, -1.6, -1.4, -1.2, -0.8, -0.6, -0.4, -0.2, + 0.2, 0.4, 0.6, 0.8, 1.2, 1.4, 1.6, 1.8, 2.2, 2.4, 2.6, 2.8, 3.2]) + # testing after minorticks_off() + cbar.minorticks_off() + np.testing.assert_almost_equal(cbar.ax.yaxis.get_minorticklocs(), []) + + im.set_clim(vmin=-1.2, vmax=1.2) + cbar.minorticks_on() + np.testing.assert_almost_equal( + cbar.ax.yaxis.get_minorticklocs(), + [-1.2, -1.1, -0.9, -0.8, -0.7, -0.6, -0.4, -0.3, -0.2, -0.1, + 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2]) + + # tests for github issue #13257 and PR #13265 + data = np.random.uniform(low=1, high=10, size=(20, 20)) + + fig, ax = plt.subplots() + im = ax.pcolormesh(data, norm=LogNorm()) + cbar = fig.colorbar(im) + fig.canvas.draw() + default_minorticklocks = cbar.ax.yaxis.get_minorticklocs() + # test that minorticks turn off for LogNorm + cbar.minorticks_off() + np.testing.assert_equal(cbar.ax.yaxis.get_minorticklocs(), []) + + # test that minorticks turn back on for LogNorm + cbar.minorticks_on() + np.testing.assert_equal(cbar.ax.yaxis.get_minorticklocs(), + default_minorticklocks) + + # test issue #13339: minorticks for LogNorm should stay off + cbar.minorticks_off() + cbar.set_ticks([3, 5, 7, 9]) + np.testing.assert_equal(cbar.ax.yaxis.get_minorticklocs(), []) + + +def test_cbar_minorticks_for_rc_xyminortickvisible(): + """ + issue gh-16468. + + Making sure that minor ticks on the colorbar are turned on + (internally) using the cbar.minorticks_on() method when + rcParams['xtick.minor.visible'] = True (for horizontal cbar) + rcParams['ytick.minor.visible'] = True (for vertical cbar). + Using cbar.minorticks_on() ensures that the minor ticks + don't overflow into the extend regions of the colorbar. + """ + + plt.rcParams['ytick.minor.visible'] = True + plt.rcParams['xtick.minor.visible'] = True + + vmin, vmax = 0.4, 2.6 + fig, ax = plt.subplots() + im = ax.pcolormesh([[1, 2]], vmin=vmin, vmax=vmax) + + cbar = fig.colorbar(im, extend='both', orientation='vertical') + assert cbar.ax.yaxis.get_minorticklocs()[0] >= vmin + assert cbar.ax.yaxis.get_minorticklocs()[-1] <= vmax + + cbar = fig.colorbar(im, extend='both', orientation='horizontal') + assert cbar.ax.xaxis.get_minorticklocs()[0] >= vmin + assert cbar.ax.xaxis.get_minorticklocs()[-1] <= vmax + + +def test_colorbar_autoticks(): + # Test new autotick modes. Needs to be classic because + # non-classic doesn't go this route. + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(2, 1) + x = np.arange(-3.0, 4.001) + y = np.arange(-4.0, 3.001) + X, Y = np.meshgrid(x, y) + Z = X * Y + Z = Z[:-1, :-1] + pcm = ax[0].pcolormesh(X, Y, Z) + cbar = fig.colorbar(pcm, ax=ax[0], extend='both', + orientation='vertical') + + pcm = ax[1].pcolormesh(X, Y, Z) + cbar2 = fig.colorbar(pcm, ax=ax[1], extend='both', + orientation='vertical', shrink=0.4) + # note only -10 to 10 are visible, + np.testing.assert_almost_equal(cbar.ax.yaxis.get_ticklocs(), + np.arange(-15, 16, 5)) + # note only -10 to 10 are visible + np.testing.assert_almost_equal(cbar2.ax.yaxis.get_ticklocs(), + np.arange(-20, 21, 10)) + + +def test_colorbar_autotickslog(): + # Test new autotick modes... + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots(2, 1) + x = np.arange(-3.0, 4.001) + y = np.arange(-4.0, 3.001) + X, Y = np.meshgrid(x, y) + Z = X * Y + Z = Z[:-1, :-1] + pcm = ax[0].pcolormesh(X, Y, 10**Z, norm=LogNorm()) + cbar = fig.colorbar(pcm, ax=ax[0], extend='both', + orientation='vertical') + + pcm = ax[1].pcolormesh(X, Y, 10**Z, norm=LogNorm()) + cbar2 = fig.colorbar(pcm, ax=ax[1], extend='both', + orientation='vertical', shrink=0.4) + # note only -12 to +12 are visible + np.testing.assert_almost_equal(cbar.ax.yaxis.get_ticklocs(), + 10**np.arange(-16., 16.2, 4.)) + # note only -24 to +24 are visible + np.testing.assert_almost_equal(cbar2.ax.yaxis.get_ticklocs(), + 10**np.arange(-24., 25., 12.)) + + +def test_colorbar_get_ticks(): + # test feature for #5792 + plt.figure() + data = np.arange(1200).reshape(30, 40) + levels = [0, 200, 400, 600, 800, 1000, 1200] + + plt.contourf(data, levels=levels) + + # testing getter for user set ticks + userTicks = plt.colorbar(ticks=[0, 600, 1200]) + assert userTicks.get_ticks().tolist() == [0, 600, 1200] + + # testing for getter after calling set_ticks + userTicks.set_ticks([600, 700, 800]) + assert userTicks.get_ticks().tolist() == [600, 700, 800] + + # testing for getter after calling set_ticks with some ticks out of bounds + # removed #20054: other axes don't trim fixed lists, so colorbars + # should not either: + # userTicks.set_ticks([600, 1300, 1400, 1500]) + # assert userTicks.get_ticks().tolist() == [600] + + # testing getter when no ticks are assigned + defTicks = plt.colorbar(orientation='horizontal') + np.testing.assert_allclose(defTicks.get_ticks().tolist(), levels) + + # test normal ticks and minor ticks + fig, ax = plt.subplots() + x = np.arange(-3.0, 4.001) + y = np.arange(-4.0, 3.001) + X, Y = np.meshgrid(x, y) + Z = X * Y + Z = Z[:-1, :-1] + pcm = ax.pcolormesh(X, Y, Z) + cbar = fig.colorbar(pcm, ax=ax, extend='both', + orientation='vertical') + ticks = cbar.get_ticks() + np.testing.assert_allclose(ticks, np.arange(-15, 16, 5)) + assert len(cbar.get_ticks(minor=True)) == 0 + + +@pytest.mark.parametrize("extend", ['both', 'min', 'max']) +def test_colorbar_lognorm_extension(extend): + # Test that colorbar with lognorm is extended correctly + f, ax = plt.subplots() + cb = Colorbar(ax, norm=LogNorm(vmin=0.1, vmax=1000.0), + orientation='vertical', extend=extend) + assert cb._values[0] >= 0.0 + + +def test_colorbar_powernorm_extension(): + # Test that colorbar with powernorm is extended correctly + f, ax = plt.subplots() + cb = Colorbar(ax, norm=PowerNorm(gamma=0.5, vmin=0.0, vmax=1.0), + orientation='vertical', extend='both') + assert cb._values[0] >= 0.0 + + +def test_colorbar_axes_kw(): + # test fix for #8493: This does only test, that axes-related keywords pass + # and do not raise an exception. + plt.figure() + plt.imshow([[1, 2], [3, 4]]) + plt.colorbar(orientation='horizontal', fraction=0.2, pad=0.2, shrink=0.5, + aspect=10, anchor=(0., 0.), panchor=(0., 1.)) + + +def test_colorbar_log_minortick_labels(): + with rc_context({'_internal.classic_mode': False}): + fig, ax = plt.subplots() + pcm = ax.imshow([[10000, 50000]], norm=LogNorm()) + cb = fig.colorbar(pcm) + fig.canvas.draw() + lb = [l.get_text() for l in cb.ax.yaxis.get_ticklabels(which='both')] + expected = [r'$\mathdefault{10^{4}}$', + r'$\mathdefault{2\times10^{4}}$', + r'$\mathdefault{3\times10^{4}}$', + r'$\mathdefault{4\times10^{4}}$'] + for exp in expected: + assert exp in lb + + +def test_colorbar_renorm(): + x, y = np.ogrid[-4:4:31j, -4:4:31j] + z = 120000*np.exp(-x**2 - y**2) + + fig, ax = plt.subplots() + im = ax.imshow(z) + cbar = fig.colorbar(im) + np.testing.assert_allclose(cbar.ax.yaxis.get_majorticklocs(), + np.arange(0, 120000.1, 20000)) + + cbar.set_ticks([1, 2, 3]) + assert isinstance(cbar.locator, FixedLocator) + + norm = LogNorm(z.min(), z.max()) + im.set_norm(norm) + np.testing.assert_allclose(cbar.ax.yaxis.get_majorticklocs(), + np.logspace(-10, 7, 18)) + # note that set_norm removes the FixedLocator... + assert np.isclose(cbar.vmin, z.min()) + cbar.set_ticks([1, 2, 3]) + assert isinstance(cbar.locator, FixedLocator) + np.testing.assert_allclose(cbar.ax.yaxis.get_majorticklocs(), + [1.0, 2.0, 3.0]) + + norm = LogNorm(z.min() * 1000, z.max() * 1000) + im.set_norm(norm) + assert np.isclose(cbar.vmin, z.min() * 1000) + assert np.isclose(cbar.vmax, z.max() * 1000) + + +@pytest.mark.parametrize('fmt', ['%4.2e', '{x:.2e}']) +def test_colorbar_format(fmt): + # make sure that format is passed properly + x, y = np.ogrid[-4:4:31j, -4:4:31j] + z = 120000*np.exp(-x**2 - y**2) + + fig, ax = plt.subplots() + im = ax.imshow(z) + cbar = fig.colorbar(im, format=fmt) + fig.canvas.draw() + assert cbar.ax.yaxis.get_ticklabels()[4].get_text() == '8.00e+04' + + # make sure that if we change the clim of the mappable that the + # formatting is *not* lost: + im.set_clim([4, 200]) + fig.canvas.draw() + assert cbar.ax.yaxis.get_ticklabels()[4].get_text() == '2.00e+02' + + # but if we change the norm: + im.set_norm(LogNorm(vmin=0.1, vmax=10)) + fig.canvas.draw() + assert (cbar.ax.yaxis.get_ticklabels()[0].get_text() == + '$\\mathdefault{10^{-2}}$') + + +def test_colorbar_scale_reset(): + x, y = np.ogrid[-4:4:31j, -4:4:31j] + z = 120000*np.exp(-x**2 - y**2) + + fig, ax = plt.subplots() + pcm = ax.pcolormesh(z, cmap='RdBu_r', rasterized=True) + cbar = fig.colorbar(pcm, ax=ax) + cbar.outline.set_edgecolor('red') + assert cbar.ax.yaxis.get_scale() == 'linear' + + pcm.set_norm(LogNorm(vmin=1, vmax=100)) + assert cbar.ax.yaxis.get_scale() == 'log' + pcm.set_norm(Normalize(vmin=-20, vmax=20)) + assert cbar.ax.yaxis.get_scale() == 'linear' + + assert cbar.outline.get_edgecolor() == mcolors.to_rgba('red') + + # log scale with no vmin/vmax set should scale to the data if there + # is a mappable already associated with the colorbar, not (0, 1) + pcm.norm = LogNorm() + assert pcm.norm.vmin == z.min() + assert pcm.norm.vmax == z.max() + + +def test_colorbar_get_ticks_2(): + plt.rcParams['_internal.classic_mode'] = False + fig, ax = plt.subplots() + pc = ax.pcolormesh([[.05, .95]]) + cb = fig.colorbar(pc) + np.testing.assert_allclose(cb.get_ticks(), [0., 0.2, 0.4, 0.6, 0.8, 1.0]) + + +def test_colorbar_inverted_ticks(): + fig, axs = plt.subplots(2) + ax = axs[0] + pc = ax.pcolormesh(10**np.arange(1, 5).reshape(2, 2), norm=LogNorm()) + cbar = fig.colorbar(pc, ax=ax, extend='both') + ticks = cbar.get_ticks() + cbar.ax.invert_yaxis() + np.testing.assert_allclose(ticks, cbar.get_ticks()) + + ax = axs[1] + pc = ax.pcolormesh(np.arange(1, 5).reshape(2, 2)) + cbar = fig.colorbar(pc, ax=ax, extend='both') + cbar.minorticks_on() + ticks = cbar.get_ticks() + minorticks = cbar.get_ticks(minor=True) + assert isinstance(minorticks, np.ndarray) + cbar.ax.invert_yaxis() + np.testing.assert_allclose(ticks, cbar.get_ticks()) + np.testing.assert_allclose(minorticks, cbar.get_ticks(minor=True)) + + +def test_mappable_no_alpha(): + fig, ax = plt.subplots() + sm = cm.ScalarMappable(norm=mcolors.Normalize(), cmap='viridis') + fig.colorbar(sm, ax=ax) + sm.set_cmap('plasma') + plt.draw() + + +def test_mappable_2d_alpha(): + fig, ax = plt.subplots() + x = np.arange(1, 5).reshape(2, 2)/4 + pc = ax.pcolormesh(x, alpha=x) + cb = fig.colorbar(pc, ax=ax) + # The colorbar's alpha should be None and the mappable should still have + # the original alpha array + assert cb.alpha is None + assert pc.get_alpha() is x + fig.draw_without_rendering() + + +def test_colorbar_label(): + """ + Test the label parameter. It should just be mapped to the xlabel/ylabel of + the axes, depending on the orientation. + """ + fig, ax = plt.subplots() + im = ax.imshow([[1, 2], [3, 4]]) + cbar = fig.colorbar(im, label='cbar') + assert cbar.ax.get_ylabel() == 'cbar' + cbar.set_label(None) + assert cbar.ax.get_ylabel() == '' + cbar.set_label('cbar 2') + assert cbar.ax.get_ylabel() == 'cbar 2' + + cbar2 = fig.colorbar(im, label=None) + assert cbar2.ax.get_ylabel() == '' + + cbar3 = fig.colorbar(im, orientation='horizontal', label='horizontal cbar') + assert cbar3.ax.get_xlabel() == 'horizontal cbar' + + +@image_comparison(['colorbar_keeping_xlabel.png'], style='mpl20') +def test_keeping_xlabel(): + # github issue #23398 - xlabels being ignored in colorbar axis + arr = np.arange(25).reshape((5, 5)) + fig, ax = plt.subplots() + im = ax.imshow(arr) + cbar = plt.colorbar(im) + cbar.ax.set_xlabel('Visible Xlabel') + cbar.set_label('YLabel') + + +@pytest.mark.parametrize("clim", [(-20000, 20000), (-32768, 0)]) +def test_colorbar_int(clim): + # Check that we cast to float early enough to not + # overflow ``int16(20000) - int16(-20000)`` or + # run into ``abs(int16(-32768)) == -32768``. + fig, ax = plt.subplots() + im = ax.imshow([[*map(np.int16, clim)]]) + fig.colorbar(im) + assert (im.norm.vmin, im.norm.vmax) == clim + + +def test_anchored_cbar_position_using_specgrid(): + data = np.arange(1200).reshape(30, 40) + levels = [0, 200, 400, 600, 800, 1000, 1200] + shrink = 0.5 + anchor_y = 0.3 + # right + fig, ax = plt.subplots() + cs = ax.contourf(data, levels=levels) + cbar = plt.colorbar( + cs, ax=ax, use_gridspec=True, + location='right', anchor=(1, anchor_y), shrink=shrink) + + # the bottom left corner of one ax is (x0, y0) + # the top right corner of one ax is (x1, y1) + # p0: the vertical / horizontal position of anchor + x0, y0, x1, y1 = ax.get_position().extents + cx0, cy0, cx1, cy1 = cbar.ax.get_position().extents + p0 = (y1 - y0) * anchor_y + y0 + + np.testing.assert_allclose( + [cy1, cy0], + [y1 * shrink + (1 - shrink) * p0, p0 * (1 - shrink) + y0 * shrink]) + + # left + fig, ax = plt.subplots() + cs = ax.contourf(data, levels=levels) + cbar = plt.colorbar( + cs, ax=ax, use_gridspec=True, + location='left', anchor=(1, anchor_y), shrink=shrink) + + # the bottom left corner of one ax is (x0, y0) + # the top right corner of one ax is (x1, y1) + # p0: the vertical / horizontal position of anchor + x0, y0, x1, y1 = ax.get_position().extents + cx0, cy0, cx1, cy1 = cbar.ax.get_position().extents + p0 = (y1 - y0) * anchor_y + y0 + + np.testing.assert_allclose( + [cy1, cy0], + [y1 * shrink + (1 - shrink) * p0, p0 * (1 - shrink) + y0 * shrink]) + + # top + shrink = 0.5 + anchor_x = 0.3 + fig, ax = plt.subplots() + cs = ax.contourf(data, levels=levels) + cbar = plt.colorbar( + cs, ax=ax, use_gridspec=True, + location='top', anchor=(anchor_x, 1), shrink=shrink) + + # the bottom left corner of one ax is (x0, y0) + # the top right corner of one ax is (x1, y1) + # p0: the vertical / horizontal position of anchor + x0, y0, x1, y1 = ax.get_position().extents + cx0, cy0, cx1, cy1 = cbar.ax.get_position().extents + p0 = (x1 - x0) * anchor_x + x0 + + np.testing.assert_allclose( + [cx1, cx0], + [x1 * shrink + (1 - shrink) * p0, p0 * (1 - shrink) + x0 * shrink]) + + # bottom + shrink = 0.5 + anchor_x = 0.3 + fig, ax = plt.subplots() + cs = ax.contourf(data, levels=levels) + cbar = plt.colorbar( + cs, ax=ax, use_gridspec=True, + location='bottom', anchor=(anchor_x, 1), shrink=shrink) + + # the bottom left corner of one ax is (x0, y0) + # the top right corner of one ax is (x1, y1) + # p0: the vertical / horizontal position of anchor + x0, y0, x1, y1 = ax.get_position().extents + cx0, cy0, cx1, cy1 = cbar.ax.get_position().extents + p0 = (x1 - x0) * anchor_x + x0 + + np.testing.assert_allclose( + [cx1, cx0], + [x1 * shrink + (1 - shrink) * p0, p0 * (1 - shrink) + x0 * shrink]) + + +@image_comparison(['colorbar_change_lim_scale.png'], remove_text=True, + style='mpl20') +def test_colorbar_change_lim_scale(): + fig, ax = plt.subplots(1, 2, constrained_layout=True) + pc = ax[0].pcolormesh(np.arange(100).reshape(10, 10)+1) + cb = fig.colorbar(pc, ax=ax[0], extend='both') + cb.ax.set_yscale('log') + + pc = ax[1].pcolormesh(np.arange(100).reshape(10, 10)+1) + cb = fig.colorbar(pc, ax=ax[1], extend='both') + cb.ax.set_ylim([20, 90]) + + +@check_figures_equal(extensions=["png"]) +def test_axes_handles_same_functions(fig_ref, fig_test): + # prove that cax and cb.ax are functionally the same + for nn, fig in enumerate([fig_ref, fig_test]): + ax = fig.add_subplot() + pc = ax.pcolormesh(np.ones(300).reshape(10, 30)) + cax = fig.add_axes([0.9, 0.1, 0.03, 0.8]) + cb = fig.colorbar(pc, cax=cax) + if nn == 0: + caxx = cax + else: + caxx = cb.ax + caxx.set_yticks(np.arange(0, 20)) + caxx.set_yscale('log') + caxx.set_position([0.92, 0.1, 0.02, 0.7]) + + +def test_inset_colorbar_layout(): + fig, ax = plt.subplots(constrained_layout=True, figsize=(3, 6)) + pc = ax.imshow(np.arange(100).reshape(10, 10)) + cax = ax.inset_axes([1.02, 0.1, 0.03, 0.8]) + cb = fig.colorbar(pc, cax=cax) + + fig.draw_without_rendering() + # make sure this is in the figure. In the colorbar swapping + # it was being dropped from the list of children... + np.testing.assert_allclose(cb.ax.get_position().bounds, + [0.87, 0.342, 0.0237, 0.315], atol=0.01) + assert cb.ax in ax.child_axes + + +@image_comparison(['colorbar_twoslope.png'], remove_text=True, + style='mpl20') +def test_twoslope_colorbar(): + # Note that the second tick = 20, and should be in the middle + # of the colorbar (white) + # There should be no tick right at the bottom, nor at the top. + fig, ax = plt.subplots() + + norm = mcolors.TwoSlopeNorm(20, 5, 95) + pc = ax.pcolormesh(np.arange(1, 11), np.arange(1, 11), + np.arange(100).reshape(10, 10), + norm=norm, cmap='RdBu_r') + fig.colorbar(pc) + + +@check_figures_equal(extensions=["png"]) +def test_remove_cb_whose_mappable_has_no_figure(fig_ref, fig_test): + ax = fig_test.add_subplot() + cb = fig_test.colorbar(cm.ScalarMappable(), cax=ax) + cb.remove() + + +def test_aspects(): + fig, ax = plt.subplots(3, 2, figsize=(8, 8)) + aspects = [20, 20, 10] + extends = ['neither', 'both', 'both'] + cb = [[None, None, None], [None, None, None]] + for nn, orient in enumerate(['vertical', 'horizontal']): + for mm, (aspect, extend) in enumerate(zip(aspects, extends)): + pc = ax[mm, nn].pcolormesh(np.arange(100).reshape(10, 10)) + cb[nn][mm] = fig.colorbar(pc, ax=ax[mm, nn], orientation=orient, + aspect=aspect, extend=extend) + fig.draw_without_rendering() + # check the extends are right ratio: + np.testing.assert_almost_equal(cb[0][1].ax.get_position().height, + cb[0][0].ax.get_position().height * 0.9, + decimal=2) + # horizontal + np.testing.assert_almost_equal(cb[1][1].ax.get_position().width, + cb[1][0].ax.get_position().width * 0.9, + decimal=2) + # check correct aspect: + pos = cb[0][0].ax.get_position(original=False) + np.testing.assert_almost_equal(pos.height, pos.width * 20, decimal=2) + pos = cb[1][0].ax.get_position(original=False) + np.testing.assert_almost_equal(pos.height * 20, pos.width, decimal=2) + # check twice as wide if aspect is 10 instead of 20 + np.testing.assert_almost_equal( + cb[0][0].ax.get_position(original=False).width * 2, + cb[0][2].ax.get_position(original=False).width, decimal=2) + np.testing.assert_almost_equal( + cb[1][0].ax.get_position(original=False).height * 2, + cb[1][2].ax.get_position(original=False).height, decimal=2) + + +@image_comparison(['proportional_colorbars.png'], remove_text=True, + style='mpl20') +def test_proportional_colorbars(): + + x = y = np.arange(-3.0, 3.01, 0.025) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-X**2 - Y**2) + Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) + Z = (Z1 - Z2) * 2 + + levels = [-1.25, -0.5, -0.125, 0.125, 0.5, 1.25] + cmap = mcolors.ListedColormap( + ['0.3', '0.5', 'white', 'lightblue', 'steelblue']) + cmap.set_under('darkred') + cmap.set_over('crimson') + norm = mcolors.BoundaryNorm(levels, cmap.N) + + extends = ['neither', 'both'] + spacings = ['uniform', 'proportional'] + fig, axs = plt.subplots(2, 2) + for i in range(2): + for j in range(2): + CS3 = axs[i, j].contourf(X, Y, Z, levels, cmap=cmap, norm=norm, + extend=extends[i]) + fig.colorbar(CS3, spacing=spacings[j], ax=axs[i, j]) + + +@image_comparison(['extend_drawedges.png'], remove_text=True, style='mpl20') +def test_colorbar_extend_drawedges(): + params = [ + ('both', 1, [[[1.1, 0], [1.1, 1]], + [[2, 0], [2, 1]], + [[2.9, 0], [2.9, 1]]]), + ('min', 0, [[[1.1, 0], [1.1, 1]], + [[2, 0], [2, 1]]]), + ('max', 0, [[[2, 0], [2, 1]], + [[2.9, 0], [2.9, 1]]]), + ('neither', -1, [[[2, 0], [2, 1]]]), + ] + + plt.rcParams['axes.linewidth'] = 2 + + fig = plt.figure(figsize=(10, 4)) + subfigs = fig.subfigures(1, 2) + + for orientation, subfig in zip(['horizontal', 'vertical'], subfigs): + if orientation == 'horizontal': + axs = subfig.subplots(4, 1) + else: + axs = subfig.subplots(1, 4) + fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95) + + for ax, (extend, coloroffset, res) in zip(axs, params): + cmap = mpl.colormaps["viridis"] + bounds = np.arange(5) + nb_colors = len(bounds) + coloroffset + colors = cmap(np.linspace(100, 255, nb_colors).astype(int)) + cmap, norm = mcolors.from_levels_and_colors(bounds, colors, + extend=extend) + + cbar = Colorbar(ax, cmap=cmap, norm=norm, orientation=orientation, + drawedges=True) + # Set limits such that only two colours are visible, and the + # dividers would be outside the Axes, to ensure that a) they are + # not drawn outside, and b) a divider still appears between the + # main colour and the extension. + if orientation == 'horizontal': + ax.set_xlim(1.1, 2.9) + else: + ax.set_ylim(1.1, 2.9) + res = np.array(res)[:, :, [1, 0]] + np.testing.assert_array_equal(cbar.dividers.get_segments(), res) + + +@image_comparison(['contourf_extend_patches.png'], remove_text=True, + style='mpl20') +def test_colorbar_contourf_extend_patches(): + params = [ + ('both', 5, ['\\', '//']), + ('min', 7, ['+']), + ('max', 2, ['|', '-', '/', '\\', '//']), + ('neither', 10, ['//', '\\', '||']), + ] + + plt.rcParams['axes.linewidth'] = 2 + + fig = plt.figure(figsize=(10, 4)) + subfigs = fig.subfigures(1, 2) + fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95) + + x = np.linspace(-2, 3, 50) + y = np.linspace(-2, 3, 30) + z = np.cos(x[np.newaxis, :]) + np.sin(y[:, np.newaxis]) + + cmap = mpl.colormaps["viridis"] + for orientation, subfig in zip(['horizontal', 'vertical'], subfigs): + axs = subfig.subplots(2, 2).ravel() + for ax, (extend, levels, hatches) in zip(axs, params): + cs = ax.contourf(x, y, z, levels, hatches=hatches, + cmap=cmap, extend=extend) + subfig.colorbar(cs, ax=ax, orientation=orientation, fraction=0.4, + extendfrac=0.2, aspect=5) + + +def test_negative_boundarynorm(): + fig, ax = plt.subplots(figsize=(1, 3)) + cmap = mpl.colormaps["viridis"] + + clevs = np.arange(-94, -85) + norm = BoundaryNorm(clevs, cmap.N) + cb = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm), cax=ax) + np.testing.assert_allclose(cb.ax.get_ylim(), [clevs[0], clevs[-1]]) + np.testing.assert_allclose(cb.ax.get_yticks(), clevs) + + clevs = np.arange(85, 94) + norm = BoundaryNorm(clevs, cmap.N) + cb = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm), cax=ax) + np.testing.assert_allclose(cb.ax.get_ylim(), [clevs[0], clevs[-1]]) + np.testing.assert_allclose(cb.ax.get_yticks(), clevs) + + clevs = np.arange(-3, 3) + norm = BoundaryNorm(clevs, cmap.N) + cb = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm), cax=ax) + np.testing.assert_allclose(cb.ax.get_ylim(), [clevs[0], clevs[-1]]) + np.testing.assert_allclose(cb.ax.get_yticks(), clevs) + + clevs = np.arange(-8, 1) + norm = BoundaryNorm(clevs, cmap.N) + cb = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm), cax=ax) + np.testing.assert_allclose(cb.ax.get_ylim(), [clevs[0], clevs[-1]]) + np.testing.assert_allclose(cb.ax.get_yticks(), clevs) + + +def test_centerednorm(): + # Test default centered norm gets expanded with non-singular limits + # when plot data is all equal (autoscale halfrange == 0) + fig, ax = plt.subplots(figsize=(1, 3)) + + norm = mcolors.CenteredNorm() + mappable = ax.pcolormesh(np.zeros((3, 3)), norm=norm) + fig.colorbar(mappable) + assert (norm.vmin, norm.vmax) == (-0.1, 0.1) + + +@image_comparison(['nonorm_colorbars.svg'], style='mpl20') +def test_nonorm(): + plt.rcParams['svg.fonttype'] = 'none' + data = [1, 2, 3, 4, 5] + + fig, ax = plt.subplots(figsize=(6, 1)) + fig.subplots_adjust(bottom=0.5) + + norm = NoNorm(vmin=min(data), vmax=max(data)) + cmap = mpl.colormaps["viridis"].resampled(len(data)) + mappable = cm.ScalarMappable(norm=norm, cmap=cmap) + cbar = fig.colorbar(mappable, cax=ax, orientation="horizontal") + + +@image_comparison(['test_boundaries.png'], remove_text=True, + style='mpl20') +def test_boundaries(): + np.random.seed(seed=19680808) + fig, ax = plt.subplots(figsize=(2, 2)) + pc = ax.pcolormesh(np.random.randn(10, 10), cmap='RdBu_r') + cb = fig.colorbar(pc, ax=ax, boundaries=np.linspace(-3, 3, 7)) + + +def test_colorbar_no_warning_rcparams_grid_true(): + # github issue #21723 - If mpl style has 'axes.grid' = True, + # fig.colorbar raises a warning about Auto-removal of grids + # by pcolor() and pcolormesh(). This is fixed by PR #22216. + plt.rcParams['axes.grid'] = True + fig, ax = plt.subplots() + ax.grid(False) + im = ax.pcolormesh([0, 1], [0, 1], [[1]]) + # make sure that no warning is raised by fig.colorbar + fig.colorbar(im) + + +def test_colorbar_set_formatter_locator(): + # check that the locator properties echo what is on the axis: + fig, ax = plt.subplots() + pc = ax.pcolormesh(np.random.randn(10, 10)) + cb = fig.colorbar(pc) + cb.ax.yaxis.set_major_locator(FixedLocator(np.arange(10))) + cb.ax.yaxis.set_minor_locator(FixedLocator(np.arange(0, 10, 0.2))) + assert cb.locator is cb.ax.yaxis.get_major_locator() + assert cb.minorlocator is cb.ax.yaxis.get_minor_locator() + cb.ax.yaxis.set_major_formatter(LogFormatter()) + cb.ax.yaxis.set_minor_formatter(LogFormatter()) + assert cb.formatter is cb.ax.yaxis.get_major_formatter() + assert cb.minorformatter is cb.ax.yaxis.get_minor_formatter() + + # check that the setter works as expected: + loc = FixedLocator(np.arange(7)) + cb.locator = loc + assert cb.ax.yaxis.get_major_locator() is loc + loc = FixedLocator(np.arange(0, 7, 0.1)) + cb.minorlocator = loc + assert cb.ax.yaxis.get_minor_locator() is loc + fmt = LogFormatter() + cb.formatter = fmt + assert cb.ax.yaxis.get_major_formatter() is fmt + fmt = LogFormatter() + cb.minorformatter = fmt + assert cb.ax.yaxis.get_minor_formatter() is fmt + + +@image_comparison(['colorbar_extend_alpha.png'], remove_text=True, + savefig_kwarg={'dpi': 40}) +def test_colorbar_extend_alpha(): + fig, ax = plt.subplots() + im = ax.imshow([[0, 1], [2, 3]], alpha=0.3, interpolation="none") + fig.colorbar(im, extend='both', boundaries=[0.5, 1.5, 2.5]) + + +def test_offset_text_loc(): + plt.style.use('mpl20') + fig, ax = plt.subplots() + np.random.seed(seed=19680808) + pc = ax.pcolormesh(np.random.randn(10, 10)*1e6) + cb = fig.colorbar(pc, location='right', extend='max') + fig.draw_without_rendering() + # check that the offsetText is in the proper place above the + # colorbar axes. In this case the colorbar axes is the same + # height as the parent, so use the parents bbox. + assert cb.ax.yaxis.offsetText.get_position()[1] > ax.bbox.y1 + + +def test_title_text_loc(): + plt.style.use('mpl20') + fig, ax = plt.subplots() + np.random.seed(seed=19680808) + pc = ax.pcolormesh(np.random.randn(10, 10)) + cb = fig.colorbar(pc, location='right', extend='max') + cb.ax.set_title('Aardvark') + fig.draw_without_rendering() + # check that the title is in the proper place above the + # colorbar axes, including its extend triangles.... + assert (cb.ax.title.get_window_extent(fig.canvas.get_renderer()).ymax > + cb.ax.spines['outline'].get_window_extent().ymax) + + +@check_figures_equal(extensions=["png"]) +def test_passing_location(fig_ref, fig_test): + ax_ref = fig_ref.add_subplot() + im = ax_ref.imshow([[0, 1], [2, 3]]) + ax_ref.figure.colorbar(im, cax=ax_ref.inset_axes([0, 1.05, 1, 0.05]), + orientation="horizontal", ticklocation="top") + ax_test = fig_test.add_subplot() + im = ax_test.imshow([[0, 1], [2, 3]]) + ax_test.figure.colorbar(im, cax=ax_test.inset_axes([0, 1.05, 1, 0.05]), + location="top") + + +@pytest.mark.parametrize("kwargs,error,message", [ + ({'location': 'top', 'orientation': 'vertical'}, TypeError, + "location and orientation are mutually exclusive"), + ({'location': 'top', 'orientation': 'vertical', 'cax': True}, TypeError, + "location and orientation are mutually exclusive"), # Different to above + ({'ticklocation': 'top', 'orientation': 'vertical', 'cax': True}, + ValueError, "'top' is not a valid value for position"), + ({'location': 'top', 'extendfrac': (0, None)}, ValueError, + "invalid value for extendfrac"), + ]) +def test_colorbar_errors(kwargs, error, message): + fig, ax = plt.subplots() + im = ax.imshow([[0, 1], [2, 3]]) + if kwargs.get('cax', None) is True: + kwargs['cax'] = ax.inset_axes([0, 1.05, 1, 0.05]) + with pytest.raises(error, match=message): + fig.colorbar(im, **kwargs) + + +def test_colorbar_axes_parmeters(): + fig, ax = plt.subplots(2) + im = ax[0].imshow([[0, 1], [2, 3]]) + # colorbar should accept any form of axes sequence: + fig.colorbar(im, ax=ax) + fig.colorbar(im, ax=ax[0]) + fig.colorbar(im, ax=[_ax for _ax in ax]) + fig.colorbar(im, ax=(ax[0], ax[1])) + fig.colorbar(im, ax={i: _ax for i, _ax in enumerate(ax)}.values()) + fig.draw_without_rendering() + + +def test_colorbar_wrong_figure(): + # If we decide in the future to disallow calling colorbar() on the "wrong" figure, + # just delete this test. + fig_tl = plt.figure(layout="tight") + fig_cl = plt.figure(layout="constrained") + im = fig_cl.add_subplot().imshow([[0, 1]]) + # Make sure this doesn't try to setup a gridspec-controlled colorbar on fig_cl, + # which would crash CL. + fig_tl.colorbar(im) + fig_tl.draw_without_rendering() + fig_cl.draw_without_rendering() + + +def test_colorbar_format_string_and_old(): + plt.imshow([[0, 1]]) + cb = plt.colorbar(format="{x}%") + assert isinstance(cb._formatter, StrMethodFormatter) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colors.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colors.py new file mode 100644 index 00000000..139efbe1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_colors.py @@ -0,0 +1,1710 @@ +import copy +import itertools +import unittest.mock + +from io import BytesIO +import numpy as np +from PIL import Image +import pytest +import base64 + +from numpy.testing import assert_array_equal, assert_array_almost_equal + +from matplotlib import cbook, cm +import matplotlib +import matplotlib as mpl +import matplotlib.colors as mcolors +import matplotlib.colorbar as mcolorbar +import matplotlib.pyplot as plt +import matplotlib.scale as mscale +from matplotlib.rcsetup import cycler +from matplotlib.testing.decorators import image_comparison, check_figures_equal + + +@pytest.mark.parametrize('N, result', [ + (5, [1, .6, .2, .1, 0]), + (2, [1, 0]), + (1, [0]), +]) +def test_create_lookup_table(N, result): + data = [(0.0, 1.0, 1.0), (0.5, 0.2, 0.2), (1.0, 0.0, 0.0)] + assert_array_almost_equal(mcolors._create_lookup_table(N, data), result) + + +@pytest.mark.parametrize("dtype", [np.uint8, int, np.float16, float]) +def test_index_dtype(dtype): + # We use subtraction in the indexing, so need to verify that uint8 works + cm = mpl.colormaps["viridis"] + assert_array_equal(cm(dtype(0)), cm(0)) + + +def test_resampled(): + """ + GitHub issue #6025 pointed to incorrect ListedColormap.resampled; + here we test the method for LinearSegmentedColormap as well. + """ + n = 101 + colorlist = np.empty((n, 4), float) + colorlist[:, 0] = np.linspace(0, 1, n) + colorlist[:, 1] = 0.2 + colorlist[:, 2] = np.linspace(1, 0, n) + colorlist[:, 3] = 0.7 + lsc = mcolors.LinearSegmentedColormap.from_list('lsc', colorlist) + lc = mcolors.ListedColormap(colorlist) + # Set some bad values for testing too + for cmap in [lsc, lc]: + cmap.set_under('r') + cmap.set_over('g') + cmap.set_bad('b') + lsc3 = lsc.resampled(3) + lc3 = lc.resampled(3) + expected = np.array([[0.0, 0.2, 1.0, 0.7], + [0.5, 0.2, 0.5, 0.7], + [1.0, 0.2, 0.0, 0.7]], float) + assert_array_almost_equal(lsc3([0, 0.5, 1]), expected) + assert_array_almost_equal(lc3([0, 0.5, 1]), expected) + # Test over/under was copied properly + assert_array_almost_equal(lsc(np.inf), lsc3(np.inf)) + assert_array_almost_equal(lsc(-np.inf), lsc3(-np.inf)) + assert_array_almost_equal(lsc(np.nan), lsc3(np.nan)) + assert_array_almost_equal(lc(np.inf), lc3(np.inf)) + assert_array_almost_equal(lc(-np.inf), lc3(-np.inf)) + assert_array_almost_equal(lc(np.nan), lc3(np.nan)) + + +def test_register_cmap(): + new_cm = mpl.colormaps["viridis"] + target = "viridis2" + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\.register\(name\)" + ): + cm.register_cmap(target, new_cm) + assert mpl.colormaps[target] == new_cm + + with pytest.raises(ValueError, + match="Arguments must include a name or a Colormap"): + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\.register\(name\)" + ): + cm.register_cmap() + + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\.unregister\(name\)" + ): + cm.unregister_cmap(target) + with pytest.raises(ValueError, + match=f'{target!r} is not a valid value for name;'): + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\[name\]" + ): + cm.get_cmap(target) + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\.unregister\(name\)" + ): + # test that second time is error free + cm.unregister_cmap(target) + + with pytest.raises(TypeError, match="'cmap' must be"): + with pytest.warns( + mpl.MatplotlibDeprecationWarning, + match=r"matplotlib\.colormaps\.register\(name\)" + ): + cm.register_cmap('nome', cmap='not a cmap') + + +def test_colormaps_get_cmap(): + cr = mpl.colormaps + + # check str, and Colormap pass + assert cr.get_cmap('plasma') == cr["plasma"] + assert cr.get_cmap(cr["magma"]) == cr["magma"] + + # check default + assert cr.get_cmap(None) == cr[mpl.rcParams['image.cmap']] + + # check ValueError on bad name + bad_cmap = 'AardvarksAreAwkward' + with pytest.raises(ValueError, match=bad_cmap): + cr.get_cmap(bad_cmap) + + # check TypeError on bad type + with pytest.raises(TypeError, match='object'): + cr.get_cmap(object()) + + +def test_double_register_builtin_cmap(): + name = "viridis" + match = f"Re-registering the builtin cmap {name!r}." + with pytest.raises(ValueError, match=match): + matplotlib.colormaps.register( + mpl.colormaps[name], name=name, force=True + ) + with pytest.raises(ValueError, match='A colormap named "viridis"'): + with pytest.warns(mpl.MatplotlibDeprecationWarning): + cm.register_cmap(name, mpl.colormaps[name]) + with pytest.warns(UserWarning): + # TODO is warning more than once! + cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) + + +def test_unregister_builtin_cmap(): + name = "viridis" + match = f'cannot unregister {name!r} which is a builtin colormap.' + with pytest.raises(ValueError, match=match): + with pytest.warns(mpl.MatplotlibDeprecationWarning): + cm.unregister_cmap(name) + + +def test_colormap_copy(): + cmap = plt.cm.Reds + copied_cmap = copy.copy(cmap) + with np.errstate(invalid='ignore'): + ret1 = copied_cmap([-1, 0, .5, 1, np.nan, np.inf]) + cmap2 = copy.copy(copied_cmap) + cmap2.set_bad('g') + with np.errstate(invalid='ignore'): + ret2 = copied_cmap([-1, 0, .5, 1, np.nan, np.inf]) + assert_array_equal(ret1, ret2) + # again with the .copy method: + cmap = plt.cm.Reds + copied_cmap = cmap.copy() + with np.errstate(invalid='ignore'): + ret1 = copied_cmap([-1, 0, .5, 1, np.nan, np.inf]) + cmap2 = copy.copy(copied_cmap) + cmap2.set_bad('g') + with np.errstate(invalid='ignore'): + ret2 = copied_cmap([-1, 0, .5, 1, np.nan, np.inf]) + assert_array_equal(ret1, ret2) + + +def test_colormap_equals(): + cmap = mpl.colormaps["plasma"] + cm_copy = cmap.copy() + # different object id's + assert cm_copy is not cmap + # But the same data should be equal + assert cm_copy == cmap + # Change the copy + cm_copy.set_bad('y') + assert cm_copy != cmap + # Make sure we can compare different sizes without failure + cm_copy._lut = cm_copy._lut[:10, :] + assert cm_copy != cmap + # Test different names are equal if the lookup table is the same + cm_copy = cmap.copy() + cm_copy.name = "Test" + assert cm_copy == cmap + # Test colorbar extends + cm_copy = cmap.copy() + cm_copy.colorbar_extend = not cmap.colorbar_extend + assert cm_copy != cmap + + +def test_colormap_endian(): + """ + GitHub issue #1005: a bug in putmask caused erroneous + mapping of 1.0 when input from a non-native-byteorder + array. + """ + cmap = mpl.colormaps["jet"] + # Test under, over, and invalid along with values 0 and 1. + a = [-0.5, 0, 0.5, 1, 1.5, np.nan] + for dt in ["f2", "f4", "f8"]: + anative = np.ma.masked_invalid(np.array(a, dtype=dt)) + aforeign = anative.byteswap().view(anative.dtype.newbyteorder()) + assert_array_equal(cmap(anative), cmap(aforeign)) + + +def test_colormap_invalid(): + """ + GitHub issue #9892: Handling of nan's were getting mapped to under + rather than bad. This tests to make sure all invalid values + (-inf, nan, inf) are mapped respectively to (under, bad, over). + """ + cmap = mpl.colormaps["plasma"] + x = np.array([-np.inf, -1, 0, np.nan, .7, 2, np.inf]) + + expected = np.array([[0.050383, 0.029803, 0.527975, 1.], + [0.050383, 0.029803, 0.527975, 1.], + [0.050383, 0.029803, 0.527975, 1.], + [0., 0., 0., 0.], + [0.949217, 0.517763, 0.295662, 1.], + [0.940015, 0.975158, 0.131326, 1.], + [0.940015, 0.975158, 0.131326, 1.]]) + assert_array_equal(cmap(x), expected) + + # Test masked representation (-inf, inf) are now masked + expected = np.array([[0., 0., 0., 0.], + [0.050383, 0.029803, 0.527975, 1.], + [0.050383, 0.029803, 0.527975, 1.], + [0., 0., 0., 0.], + [0.949217, 0.517763, 0.295662, 1.], + [0.940015, 0.975158, 0.131326, 1.], + [0., 0., 0., 0.]]) + assert_array_equal(cmap(np.ma.masked_invalid(x)), expected) + + # Test scalar representations + assert_array_equal(cmap(-np.inf), cmap(0)) + assert_array_equal(cmap(np.inf), cmap(1.0)) + assert_array_equal(cmap(np.nan), [0., 0., 0., 0.]) + + +def test_colormap_return_types(): + """ + Make sure that tuples are returned for scalar input and + that the proper shapes are returned for ndarrays. + """ + cmap = mpl.colormaps["plasma"] + # Test return types and shapes + # scalar input needs to return a tuple of length 4 + assert isinstance(cmap(0.5), tuple) + assert len(cmap(0.5)) == 4 + + # input array returns an ndarray of shape x.shape + (4,) + x = np.ones(4) + assert cmap(x).shape == x.shape + (4,) + + # multi-dimensional array input + x2d = np.zeros((2, 2)) + assert cmap(x2d).shape == x2d.shape + (4,) + + +def test_BoundaryNorm(): + """ + GitHub issue #1258: interpolation was failing with numpy + 1.7 pre-release. + """ + + boundaries = [0, 1.1, 2.2] + vals = [-1, 0, 1, 2, 2.2, 4] + + # Without interpolation + expected = [-1, 0, 0, 1, 2, 2] + ncolors = len(boundaries) - 1 + bn = mcolors.BoundaryNorm(boundaries, ncolors) + assert_array_equal(bn(vals), expected) + + # ncolors != len(boundaries) - 1 triggers interpolation + expected = [-1, 0, 0, 2, 3, 3] + ncolors = len(boundaries) + bn = mcolors.BoundaryNorm(boundaries, ncolors) + assert_array_equal(bn(vals), expected) + + # with a single region and interpolation + expected = [-1, 1, 1, 1, 3, 3] + bn = mcolors.BoundaryNorm([0, 2.2], ncolors) + assert_array_equal(bn(vals), expected) + + # more boundaries for a third color + boundaries = [0, 1, 2, 3] + vals = [-1, 0.1, 1.1, 2.2, 4] + ncolors = 5 + expected = [-1, 0, 2, 4, 5] + bn = mcolors.BoundaryNorm(boundaries, ncolors) + assert_array_equal(bn(vals), expected) + + # a scalar as input should not trigger an error and should return a scalar + boundaries = [0, 1, 2] + vals = [-1, 0.1, 1.1, 2.2] + bn = mcolors.BoundaryNorm(boundaries, 2) + expected = [-1, 0, 1, 2] + for v, ex in zip(vals, expected): + ret = bn(v) + assert isinstance(ret, int) + assert_array_equal(ret, ex) + assert_array_equal(bn([v]), ex) + + # same with interp + bn = mcolors.BoundaryNorm(boundaries, 3) + expected = [-1, 0, 2, 3] + for v, ex in zip(vals, expected): + ret = bn(v) + assert isinstance(ret, int) + assert_array_equal(ret, ex) + assert_array_equal(bn([v]), ex) + + # Clipping + bn = mcolors.BoundaryNorm(boundaries, 3, clip=True) + expected = [0, 0, 2, 2] + for v, ex in zip(vals, expected): + ret = bn(v) + assert isinstance(ret, int) + assert_array_equal(ret, ex) + assert_array_equal(bn([v]), ex) + + # Masked arrays + boundaries = [0, 1.1, 2.2] + vals = np.ma.masked_invalid([-1., np.nan, 0, 1.4, 9]) + + # Without interpolation + ncolors = len(boundaries) - 1 + bn = mcolors.BoundaryNorm(boundaries, ncolors) + expected = np.ma.masked_array([-1, -99, 0, 1, 2], mask=[0, 1, 0, 0, 0]) + assert_array_equal(bn(vals), expected) + + # With interpolation + bn = mcolors.BoundaryNorm(boundaries, len(boundaries)) + expected = np.ma.masked_array([-1, -99, 0, 2, 3], mask=[0, 1, 0, 0, 0]) + assert_array_equal(bn(vals), expected) + + # Non-trivial masked arrays + vals = np.ma.masked_invalid([np.inf, np.nan]) + assert np.all(bn(vals).mask) + vals = np.ma.masked_invalid([np.inf]) + assert np.all(bn(vals).mask) + + # Incompatible extend and clip + with pytest.raises(ValueError, match="not compatible"): + mcolors.BoundaryNorm(np.arange(4), 5, extend='both', clip=True) + + # Too small ncolors argument + with pytest.raises(ValueError, match="ncolors must equal or exceed"): + mcolors.BoundaryNorm(np.arange(4), 2) + + with pytest.raises(ValueError, match="ncolors must equal or exceed"): + mcolors.BoundaryNorm(np.arange(4), 3, extend='min') + + with pytest.raises(ValueError, match="ncolors must equal or exceed"): + mcolors.BoundaryNorm(np.arange(4), 4, extend='both') + + # Testing extend keyword, with interpolation (large cmap) + bounds = [1, 2, 3] + cmap = mpl.colormaps['viridis'] + mynorm = mcolors.BoundaryNorm(bounds, cmap.N, extend='both') + refnorm = mcolors.BoundaryNorm([0] + bounds + [4], cmap.N) + x = np.random.randn(100) * 10 + 2 + ref = refnorm(x) + ref[ref == 0] = -1 + ref[ref == cmap.N - 1] = cmap.N + assert_array_equal(mynorm(x), ref) + + # Without interpolation + cmref = mcolors.ListedColormap(['blue', 'red']) + cmref.set_over('black') + cmref.set_under('white') + cmshould = mcolors.ListedColormap(['white', 'blue', 'red', 'black']) + + assert mcolors.same_color(cmref.get_over(), 'black') + assert mcolors.same_color(cmref.get_under(), 'white') + + refnorm = mcolors.BoundaryNorm(bounds, cmref.N) + mynorm = mcolors.BoundaryNorm(bounds, cmshould.N, extend='both') + assert mynorm.vmin == refnorm.vmin + assert mynorm.vmax == refnorm.vmax + + assert mynorm(bounds[0] - 0.1) == -1 # under + assert mynorm(bounds[0] + 0.1) == 1 # first bin -> second color + assert mynorm(bounds[-1] - 0.1) == cmshould.N - 2 # next-to-last color + assert mynorm(bounds[-1] + 0.1) == cmshould.N # over + + x = [-1, 1.2, 2.3, 9.6] + assert_array_equal(cmshould(mynorm(x)), cmshould([0, 1, 2, 3])) + x = np.random.randn(100) * 10 + 2 + assert_array_equal(cmshould(mynorm(x)), cmref(refnorm(x))) + + # Just min + cmref = mcolors.ListedColormap(['blue', 'red']) + cmref.set_under('white') + cmshould = mcolors.ListedColormap(['white', 'blue', 'red']) + + assert mcolors.same_color(cmref.get_under(), 'white') + + assert cmref.N == 2 + assert cmshould.N == 3 + refnorm = mcolors.BoundaryNorm(bounds, cmref.N) + mynorm = mcolors.BoundaryNorm(bounds, cmshould.N, extend='min') + assert mynorm.vmin == refnorm.vmin + assert mynorm.vmax == refnorm.vmax + x = [-1, 1.2, 2.3] + assert_array_equal(cmshould(mynorm(x)), cmshould([0, 1, 2])) + x = np.random.randn(100) * 10 + 2 + assert_array_equal(cmshould(mynorm(x)), cmref(refnorm(x))) + + # Just max + cmref = mcolors.ListedColormap(['blue', 'red']) + cmref.set_over('black') + cmshould = mcolors.ListedColormap(['blue', 'red', 'black']) + + assert mcolors.same_color(cmref.get_over(), 'black') + + assert cmref.N == 2 + assert cmshould.N == 3 + refnorm = mcolors.BoundaryNorm(bounds, cmref.N) + mynorm = mcolors.BoundaryNorm(bounds, cmshould.N, extend='max') + assert mynorm.vmin == refnorm.vmin + assert mynorm.vmax == refnorm.vmax + x = [1.2, 2.3, 4] + assert_array_equal(cmshould(mynorm(x)), cmshould([0, 1, 2])) + x = np.random.randn(100) * 10 + 2 + assert_array_equal(cmshould(mynorm(x)), cmref(refnorm(x))) + + +def test_CenteredNorm(): + np.random.seed(0) + + # Assert equivalence to symmetrical Normalize. + x = np.random.normal(size=100) + x_maxabs = np.max(np.abs(x)) + norm_ref = mcolors.Normalize(vmin=-x_maxabs, vmax=x_maxabs) + norm = mcolors.CenteredNorm() + assert_array_almost_equal(norm_ref(x), norm(x)) + + # Check that vcenter is in the center of vmin and vmax + # when vcenter is set. + vcenter = int(np.random.normal(scale=50)) + norm = mcolors.CenteredNorm(vcenter=vcenter) + norm.autoscale_None([1, 2]) + assert norm.vmax + norm.vmin == 2 * vcenter + + # Check that halfrange can be set without setting vcenter and that it is + # not reset through autoscale_None. + norm = mcolors.CenteredNorm(halfrange=1.0) + norm.autoscale_None([1, 3000]) + assert norm.halfrange == 1.0 + + # Check that halfrange input works correctly. + x = np.random.normal(size=10) + norm = mcolors.CenteredNorm(vcenter=0.5, halfrange=0.5) + assert_array_almost_equal(x, norm(x)) + norm = mcolors.CenteredNorm(vcenter=1, halfrange=1) + assert_array_almost_equal(x, 2 * norm(x)) + + # Check that halfrange input works correctly and use setters. + norm = mcolors.CenteredNorm() + norm.vcenter = 2 + norm.halfrange = 2 + assert_array_almost_equal(x, 4 * norm(x)) + + # Check that prior to adding data, setting halfrange first has same effect. + norm = mcolors.CenteredNorm() + norm.halfrange = 2 + norm.vcenter = 2 + assert_array_almost_equal(x, 4 * norm(x)) + + # Check that manual change of vcenter adjusts halfrange accordingly. + norm = mcolors.CenteredNorm() + assert norm.vcenter == 0 + # add data + norm(np.linspace(-1.0, 0.0, 10)) + assert norm.vmax == 1.0 + assert norm.halfrange == 1.0 + # set vcenter to 1, which should move the center but leave the + # halfrange unchanged + norm.vcenter = 1 + assert norm.vmin == 0 + assert norm.vmax == 2 + assert norm.halfrange == 1 + + # Check setting vmin directly updates the halfrange and vmax, but + # leaves vcenter alone + norm.vmin = -1 + assert norm.halfrange == 2 + assert norm.vmax == 3 + assert norm.vcenter == 1 + + # also check vmax updates + norm.vmax = 2 + assert norm.halfrange == 1 + assert norm.vmin == 0 + assert norm.vcenter == 1 + + +@pytest.mark.parametrize("vmin,vmax", [[-1, 2], [3, 1]]) +def test_lognorm_invalid(vmin, vmax): + # Check that invalid limits in LogNorm error + norm = mcolors.LogNorm(vmin=vmin, vmax=vmax) + with pytest.raises(ValueError): + norm(1) + with pytest.raises(ValueError): + norm.inverse(1) + + +def test_LogNorm(): + """ + LogNorm ignored clip, now it has the same + behavior as Normalize, e.g., values > vmax are bigger than 1 + without clip, with clip they are 1. + """ + ln = mcolors.LogNorm(clip=True, vmax=5) + assert_array_equal(ln([1, 6]), [0, 1.0]) + + +def test_LogNorm_inverse(): + """ + Test that lists work, and that the inverse works + """ + norm = mcolors.LogNorm(vmin=0.1, vmax=10) + assert_array_almost_equal(norm([0.5, 0.4]), [0.349485, 0.30103]) + assert_array_almost_equal([0.5, 0.4], norm.inverse([0.349485, 0.30103])) + assert_array_almost_equal(norm(0.4), [0.30103]) + assert_array_almost_equal([0.4], norm.inverse([0.30103])) + + +def test_PowerNorm(): + # Check an exponent of 1 gives same results as a normal linear + # normalization. Also implicitly checks that vmin/vmax are + # automatically initialized from first array input. + a = np.array([0, 0.5, 1, 1.5], dtype=float) + pnorm = mcolors.PowerNorm(1) + norm = mcolors.Normalize() + assert_array_almost_equal(norm(a), pnorm(a)) + + a = np.array([-0.5, 0, 2, 4, 8], dtype=float) + expected = [0, 0, 1/16, 1/4, 1] + pnorm = mcolors.PowerNorm(2, vmin=0, vmax=8) + assert_array_almost_equal(pnorm(a), expected) + assert pnorm(a[0]) == expected[0] + assert pnorm(a[2]) == expected[2] + assert_array_almost_equal(a[1:], pnorm.inverse(pnorm(a))[1:]) + + # Clip = True + a = np.array([-0.5, 0, 1, 8, 16], dtype=float) + expected = [0, 0, 0, 1, 1] + # Clip = True when creating the norm + pnorm = mcolors.PowerNorm(2, vmin=2, vmax=8, clip=True) + assert_array_almost_equal(pnorm(a), expected) + assert pnorm(a[0]) == expected[0] + assert pnorm(a[-1]) == expected[-1] + # Clip = True at call time + pnorm = mcolors.PowerNorm(2, vmin=2, vmax=8, clip=False) + assert_array_almost_equal(pnorm(a, clip=True), expected) + assert pnorm(a[0], clip=True) == expected[0] + assert pnorm(a[-1], clip=True) == expected[-1] + + # Check clip=True preserves masked values + a = np.ma.array([5, 2], mask=[True, False]) + out = pnorm(a, clip=True) + assert_array_equal(out.mask, [True, False]) + + +def test_PowerNorm_translation_invariance(): + a = np.array([0, 1/2, 1], dtype=float) + expected = [0, 1/8, 1] + pnorm = mcolors.PowerNorm(vmin=0, vmax=1, gamma=3) + assert_array_almost_equal(pnorm(a), expected) + pnorm = mcolors.PowerNorm(vmin=-2, vmax=-1, gamma=3) + assert_array_almost_equal(pnorm(a - 2), expected) + + +def test_Normalize(): + norm = mcolors.Normalize() + vals = np.arange(-10, 10, 1, dtype=float) + _inverse_tester(norm, vals) + _scalar_tester(norm, vals) + _mask_tester(norm, vals) + + # Handle integer input correctly (don't overflow when computing max-min, + # i.e. 127-(-128) here). + vals = np.array([-128, 127], dtype=np.int8) + norm = mcolors.Normalize(vals.min(), vals.max()) + assert_array_equal(norm(vals), [0, 1]) + + # Don't lose precision on longdoubles (float128 on Linux): + # for array inputs... + vals = np.array([1.2345678901, 9.8765432109], dtype=np.longdouble) + norm = mcolors.Normalize(vals[0], vals[1]) + assert norm(vals).dtype == np.longdouble + assert_array_equal(norm(vals), [0, 1]) + # and for scalar ones. + eps = np.finfo(np.longdouble).resolution + norm = plt.Normalize(1, 1 + 100 * eps) + # This returns exactly 0.5 when longdouble is extended precision (80-bit), + # but only a value close to it when it is quadruple precision (128-bit). + assert_array_almost_equal(norm(1 + 50 * eps), 0.5, decimal=3) + + +def test_FuncNorm(): + def forward(x): + return (x**2) + def inverse(x): + return np.sqrt(x) + + norm = mcolors.FuncNorm((forward, inverse), vmin=0, vmax=10) + expected = np.array([0, 0.25, 1]) + input = np.array([0, 5, 10]) + assert_array_almost_equal(norm(input), expected) + assert_array_almost_equal(norm.inverse(expected), input) + + def forward(x): + return np.log10(x) + def inverse(x): + return 10**x + norm = mcolors.FuncNorm((forward, inverse), vmin=0.1, vmax=10) + lognorm = mcolors.LogNorm(vmin=0.1, vmax=10) + assert_array_almost_equal(norm([0.2, 5, 10]), lognorm([0.2, 5, 10])) + assert_array_almost_equal(norm.inverse([0.2, 5, 10]), + lognorm.inverse([0.2, 5, 10])) + + +def test_TwoSlopeNorm_autoscale(): + norm = mcolors.TwoSlopeNorm(vcenter=20) + norm.autoscale([10, 20, 30, 40]) + assert norm.vmin == 10. + assert norm.vmax == 40. + + +def test_TwoSlopeNorm_autoscale_None_vmin(): + norm = mcolors.TwoSlopeNorm(2, vmin=0, vmax=None) + norm.autoscale_None([1, 2, 3, 4, 5]) + assert norm(5) == 1 + assert norm.vmax == 5 + + +def test_TwoSlopeNorm_autoscale_None_vmax(): + norm = mcolors.TwoSlopeNorm(2, vmin=None, vmax=10) + norm.autoscale_None([1, 2, 3, 4, 5]) + assert norm(1) == 0 + assert norm.vmin == 1 + + +def test_TwoSlopeNorm_scale(): + norm = mcolors.TwoSlopeNorm(2) + assert norm.scaled() is False + norm([1, 2, 3, 4]) + assert norm.scaled() is True + + +def test_TwoSlopeNorm_scaleout_center(): + # test the vmin never goes above vcenter + norm = mcolors.TwoSlopeNorm(vcenter=0) + norm([0, 1, 2, 3, 5]) + assert norm.vmin == -5 + assert norm.vmax == 5 + + +def test_TwoSlopeNorm_scaleout_center_max(): + # test the vmax never goes below vcenter + norm = mcolors.TwoSlopeNorm(vcenter=0) + norm([0, -1, -2, -3, -5]) + assert norm.vmax == 5 + assert norm.vmin == -5 + + +def test_TwoSlopeNorm_Even(): + norm = mcolors.TwoSlopeNorm(vmin=-1, vcenter=0, vmax=4) + vals = np.array([-1.0, -0.5, 0.0, 1.0, 2.0, 3.0, 4.0]) + expected = np.array([0.0, 0.25, 0.5, 0.625, 0.75, 0.875, 1.0]) + assert_array_equal(norm(vals), expected) + + +def test_TwoSlopeNorm_Odd(): + norm = mcolors.TwoSlopeNorm(vmin=-2, vcenter=0, vmax=5) + vals = np.array([-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) + expected = np.array([0.0, 0.25, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]) + assert_array_equal(norm(vals), expected) + + +def test_TwoSlopeNorm_VminEqualsVcenter(): + with pytest.raises(ValueError): + mcolors.TwoSlopeNorm(vmin=-2, vcenter=-2, vmax=2) + + +def test_TwoSlopeNorm_VmaxEqualsVcenter(): + with pytest.raises(ValueError): + mcolors.TwoSlopeNorm(vmin=-2, vcenter=2, vmax=2) + + +def test_TwoSlopeNorm_VminGTVcenter(): + with pytest.raises(ValueError): + mcolors.TwoSlopeNorm(vmin=10, vcenter=0, vmax=20) + + +def test_TwoSlopeNorm_TwoSlopeNorm_VminGTVmax(): + with pytest.raises(ValueError): + mcolors.TwoSlopeNorm(vmin=10, vcenter=0, vmax=5) + + +def test_TwoSlopeNorm_VcenterGTVmax(): + with pytest.raises(ValueError): + mcolors.TwoSlopeNorm(vmin=10, vcenter=25, vmax=20) + + +def test_TwoSlopeNorm_premature_scaling(): + norm = mcolors.TwoSlopeNorm(vcenter=2) + with pytest.raises(ValueError): + norm.inverse(np.array([0.1, 0.5, 0.9])) + + +def test_SymLogNorm(): + """ + Test SymLogNorm behavior + """ + norm = mcolors.SymLogNorm(3, vmax=5, linscale=1.2, base=np.e) + vals = np.array([-30, -1, 2, 6], dtype=float) + normed_vals = norm(vals) + expected = [0., 0.53980074, 0.826991, 1.02758204] + assert_array_almost_equal(normed_vals, expected) + _inverse_tester(norm, vals) + _scalar_tester(norm, vals) + _mask_tester(norm, vals) + + # Ensure that specifying vmin returns the same result as above + norm = mcolors.SymLogNorm(3, vmin=-30, vmax=5, linscale=1.2, base=np.e) + normed_vals = norm(vals) + assert_array_almost_equal(normed_vals, expected) + + # test something more easily checked. + norm = mcolors.SymLogNorm(1, vmin=-np.e**3, vmax=np.e**3, base=np.e) + nn = norm([-np.e**3, -np.e**2, -np.e**1, -1, + 0, 1, np.e**1, np.e**2, np.e**3]) + xx = np.array([0., 0.109123, 0.218246, 0.32737, 0.5, 0.67263, + 0.781754, 0.890877, 1.]) + assert_array_almost_equal(nn, xx) + norm = mcolors.SymLogNorm(1, vmin=-10**3, vmax=10**3, base=10) + nn = norm([-10**3, -10**2, -10**1, -1, + 0, 1, 10**1, 10**2, 10**3]) + xx = np.array([0., 0.121622, 0.243243, 0.364865, 0.5, 0.635135, + 0.756757, 0.878378, 1.]) + assert_array_almost_equal(nn, xx) + + +def test_SymLogNorm_colorbar(): + """ + Test un-called SymLogNorm in a colorbar. + """ + norm = mcolors.SymLogNorm(0.1, vmin=-1, vmax=1, linscale=1, base=np.e) + fig = plt.figure() + mcolorbar.ColorbarBase(fig.add_subplot(), norm=norm) + plt.close(fig) + + +def test_SymLogNorm_single_zero(): + """ + Test SymLogNorm to ensure it is not adding sub-ticks to zero label + """ + fig = plt.figure() + norm = mcolors.SymLogNorm(1e-5, vmin=-1, vmax=1, base=np.e) + cbar = mcolorbar.ColorbarBase(fig.add_subplot(), norm=norm) + ticks = cbar.get_ticks() + assert np.count_nonzero(ticks == 0) <= 1 + plt.close(fig) + + +class TestAsinhNorm: + """ + Tests for `~.colors.AsinhNorm` + """ + + def test_init(self): + norm0 = mcolors.AsinhNorm() + assert norm0.linear_width == 1 + + norm5 = mcolors.AsinhNorm(linear_width=5) + assert norm5.linear_width == 5 + + def test_norm(self): + norm = mcolors.AsinhNorm(2, vmin=-4, vmax=4) + vals = np.arange(-3.5, 3.5, 10) + normed_vals = norm(vals) + asinh2 = np.arcsinh(2) + + expected = (2 * np.arcsinh(vals / 2) + 2 * asinh2) / (4 * asinh2) + assert_array_almost_equal(normed_vals, expected) + + +def _inverse_tester(norm_instance, vals): + """ + Checks if the inverse of the given normalization is working. + """ + assert_array_almost_equal(norm_instance.inverse(norm_instance(vals)), vals) + + +def _scalar_tester(norm_instance, vals): + """ + Checks if scalars and arrays are handled the same way. + Tests only for float. + """ + scalar_result = [norm_instance(float(v)) for v in vals] + assert_array_almost_equal(scalar_result, norm_instance(vals)) + + +def _mask_tester(norm_instance, vals): + """ + Checks mask handling + """ + masked_array = np.ma.array(vals) + masked_array[0] = np.ma.masked + assert_array_equal(masked_array.mask, norm_instance(masked_array).mask) + + +@image_comparison(['levels_and_colors.png']) +def test_cmap_and_norm_from_levels_and_colors(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + data = np.linspace(-2, 4, 49).reshape(7, 7) + levels = [-1, 2, 2.5, 3] + colors = ['red', 'green', 'blue', 'yellow', 'black'] + extend = 'both' + cmap, norm = mcolors.from_levels_and_colors(levels, colors, extend=extend) + + ax = plt.axes() + m = plt.pcolormesh(data, cmap=cmap, norm=norm) + plt.colorbar(m) + + # Hide the axes labels (but not the colorbar ones, as they are useful) + ax.tick_params(labelleft=False, labelbottom=False) + + +@image_comparison(baseline_images=['boundarynorm_and_colorbar'], + extensions=['png'], tol=1.0) +def test_boundarynorm_and_colorbarbase(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + # Make a figure and axes with dimensions as desired. + fig = plt.figure() + ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) + ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) + ax3 = fig.add_axes([0.05, 0.15, 0.9, 0.15]) + + # Set the colormap and bounds + bounds = [-1, 2, 5, 7, 12, 15] + cmap = mpl.colormaps['viridis'] + + # Default behavior + norm = mcolors.BoundaryNorm(bounds, cmap.N) + cb1 = mcolorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, extend='both', + orientation='horizontal', spacing='uniform') + # New behavior + norm = mcolors.BoundaryNorm(bounds, cmap.N, extend='both') + cb2 = mcolorbar.ColorbarBase(ax2, cmap=cmap, norm=norm, + orientation='horizontal') + + # User can still force to any extend='' if really needed + norm = mcolors.BoundaryNorm(bounds, cmap.N, extend='both') + cb3 = mcolorbar.ColorbarBase(ax3, cmap=cmap, norm=norm, + extend='neither', orientation='horizontal') + + +def test_cmap_and_norm_from_levels_and_colors2(): + levels = [-1, 2, 2.5, 3] + colors = ['red', (0, 1, 0), 'blue', (0.5, 0.5, 0.5), (0.0, 0.0, 0.0, 1.0)] + clr = mcolors.to_rgba_array(colors) + bad = (0.1, 0.1, 0.1, 0.1) + no_color = (0.0, 0.0, 0.0, 0.0) + masked_value = 'masked_value' + + # Define the test values which are of interest. + # Note: levels are lev[i] <= v < lev[i+1] + tests = [('both', None, {-2: clr[0], + -1: clr[1], + 2: clr[2], + 2.25: clr[2], + 3: clr[4], + 3.5: clr[4], + masked_value: bad}), + + ('min', -1, {-2: clr[0], + -1: clr[1], + 2: clr[2], + 2.25: clr[2], + 3: no_color, + 3.5: no_color, + masked_value: bad}), + + ('max', -1, {-2: no_color, + -1: clr[0], + 2: clr[1], + 2.25: clr[1], + 3: clr[3], + 3.5: clr[3], + masked_value: bad}), + + ('neither', -2, {-2: no_color, + -1: clr[0], + 2: clr[1], + 2.25: clr[1], + 3: no_color, + 3.5: no_color, + masked_value: bad}), + ] + + for extend, i1, cases in tests: + cmap, norm = mcolors.from_levels_and_colors(levels, colors[0:i1], + extend=extend) + cmap.set_bad(bad) + for d_val, expected_color in cases.items(): + if d_val == masked_value: + d_val = np.ma.array([1], mask=True) + else: + d_val = [d_val] + assert_array_equal(expected_color, cmap(norm(d_val))[0], + f'With extend={extend!r} and data ' + f'value={d_val!r}') + + with pytest.raises(ValueError): + mcolors.from_levels_and_colors(levels, colors) + + +def test_rgb_hsv_round_trip(): + for a_shape in [(500, 500, 3), (500, 3), (1, 3), (3,)]: + np.random.seed(0) + tt = np.random.random(a_shape) + assert_array_almost_equal( + tt, mcolors.hsv_to_rgb(mcolors.rgb_to_hsv(tt))) + assert_array_almost_equal( + tt, mcolors.rgb_to_hsv(mcolors.hsv_to_rgb(tt))) + + +def test_autoscale_masked(): + # Test for #2336. Previously fully masked data would trigger a ValueError. + data = np.ma.masked_all((12, 20)) + plt.pcolor(data) + plt.draw() + + +@image_comparison(['light_source_shading_topo.png']) +def test_light_source_topo_surface(): + """Shades a DEM using different v.e.'s and blend modes.""" + dem = cbook.get_sample_data('jacksboro_fault_dem.npz') + elev = dem['elevation'] + dx, dy = dem['dx'], dem['dy'] + # Get the true cellsize in meters for accurate vertical exaggeration + # Convert from decimal degrees to meters + dx = 111320.0 * dx * np.cos(dem['ymin']) + dy = 111320.0 * dy + + ls = mcolors.LightSource(315, 45) + cmap = cm.gist_earth + + fig, axs = plt.subplots(nrows=3, ncols=3) + for row, mode in zip(axs, ['hsv', 'overlay', 'soft']): + for ax, ve in zip(row, [0.1, 1, 10]): + rgb = ls.shade(elev, cmap, vert_exag=ve, dx=dx, dy=dy, + blend_mode=mode) + ax.imshow(rgb) + ax.set(xticks=[], yticks=[]) + + +def test_light_source_shading_default(): + """ + Array comparison test for the default "hsv" blend mode. Ensure the + default result doesn't change without warning. + """ + y, x = np.mgrid[-1.2:1.2:8j, -1.2:1.2:8j] + z = 10 * np.cos(x**2 + y**2) + + cmap = plt.cm.copper + ls = mcolors.LightSource(315, 45) + rgb = ls.shade(z, cmap) + + # Result stored transposed and rounded for more compact display... + expect = np.array( + [[[0.00, 0.45, 0.90, 0.90, 0.82, 0.62, 0.28, 0.00], + [0.45, 0.94, 0.99, 1.00, 1.00, 0.96, 0.65, 0.17], + [0.90, 0.99, 1.00, 1.00, 1.00, 1.00, 0.94, 0.35], + [0.90, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.49], + [0.82, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 0.41], + [0.62, 0.96, 1.00, 1.00, 1.00, 1.00, 0.90, 0.07], + [0.28, 0.65, 0.94, 1.00, 1.00, 0.90, 0.35, 0.01], + [0.00, 0.17, 0.35, 0.49, 0.41, 0.07, 0.01, 0.00]], + + [[0.00, 0.28, 0.59, 0.72, 0.62, 0.40, 0.18, 0.00], + [0.28, 0.78, 0.93, 0.92, 0.83, 0.66, 0.39, 0.11], + [0.59, 0.93, 0.99, 1.00, 0.92, 0.75, 0.50, 0.21], + [0.72, 0.92, 1.00, 0.99, 0.93, 0.76, 0.51, 0.18], + [0.62, 0.83, 0.92, 0.93, 0.87, 0.68, 0.42, 0.08], + [0.40, 0.66, 0.75, 0.76, 0.68, 0.52, 0.23, 0.02], + [0.18, 0.39, 0.50, 0.51, 0.42, 0.23, 0.00, 0.00], + [0.00, 0.11, 0.21, 0.18, 0.08, 0.02, 0.00, 0.00]], + + [[0.00, 0.18, 0.38, 0.46, 0.39, 0.26, 0.11, 0.00], + [0.18, 0.50, 0.70, 0.75, 0.64, 0.44, 0.25, 0.07], + [0.38, 0.70, 0.91, 0.98, 0.81, 0.51, 0.29, 0.13], + [0.46, 0.75, 0.98, 0.96, 0.84, 0.48, 0.22, 0.12], + [0.39, 0.64, 0.81, 0.84, 0.71, 0.31, 0.11, 0.05], + [0.26, 0.44, 0.51, 0.48, 0.31, 0.10, 0.03, 0.01], + [0.11, 0.25, 0.29, 0.22, 0.11, 0.03, 0.00, 0.00], + [0.00, 0.07, 0.13, 0.12, 0.05, 0.01, 0.00, 0.00]], + + [[1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00]] + ]).T + + assert_array_almost_equal(rgb, expect, decimal=2) + + +def test_light_source_shading_empty_mask(): + y, x = np.mgrid[-1.2:1.2:8j, -1.2:1.2:8j] + z0 = 10 * np.cos(x**2 + y**2) + z1 = np.ma.array(z0) + + cmap = plt.cm.copper + ls = mcolors.LightSource(315, 45) + rgb0 = ls.shade(z0, cmap) + rgb1 = ls.shade(z1, cmap) + + assert_array_almost_equal(rgb0, rgb1) + + +# Numpy 1.9.1 fixed a bug in masked arrays which resulted in +# additional elements being masked when calculating the gradient thus +# the output is different with earlier numpy versions. +def test_light_source_masked_shading(): + """ + Array comparison test for a surface with a masked portion. Ensures that + we don't wind up with "fringes" of odd colors around masked regions. + """ + y, x = np.mgrid[-1.2:1.2:8j, -1.2:1.2:8j] + z = 10 * np.cos(x**2 + y**2) + + z = np.ma.masked_greater(z, 9.9) + + cmap = plt.cm.copper + ls = mcolors.LightSource(315, 45) + rgb = ls.shade(z, cmap) + + # Result stored transposed and rounded for more compact display... + expect = np.array( + [[[0.00, 0.46, 0.91, 0.91, 0.84, 0.64, 0.29, 0.00], + [0.46, 0.96, 1.00, 1.00, 1.00, 0.97, 0.67, 0.18], + [0.91, 1.00, 1.00, 1.00, 1.00, 1.00, 0.96, 0.36], + [0.91, 1.00, 1.00, 0.00, 0.00, 1.00, 1.00, 0.51], + [0.84, 1.00, 1.00, 0.00, 0.00, 1.00, 1.00, 0.44], + [0.64, 0.97, 1.00, 1.00, 1.00, 1.00, 0.94, 0.09], + [0.29, 0.67, 0.96, 1.00, 1.00, 0.94, 0.38, 0.01], + [0.00, 0.18, 0.36, 0.51, 0.44, 0.09, 0.01, 0.00]], + + [[0.00, 0.29, 0.61, 0.75, 0.64, 0.41, 0.18, 0.00], + [0.29, 0.81, 0.95, 0.93, 0.85, 0.68, 0.40, 0.11], + [0.61, 0.95, 1.00, 0.78, 0.78, 0.77, 0.52, 0.22], + [0.75, 0.93, 0.78, 0.00, 0.00, 0.78, 0.54, 0.19], + [0.64, 0.85, 0.78, 0.00, 0.00, 0.78, 0.45, 0.08], + [0.41, 0.68, 0.77, 0.78, 0.78, 0.55, 0.25, 0.02], + [0.18, 0.40, 0.52, 0.54, 0.45, 0.25, 0.00, 0.00], + [0.00, 0.11, 0.22, 0.19, 0.08, 0.02, 0.00, 0.00]], + + [[0.00, 0.19, 0.39, 0.48, 0.41, 0.26, 0.12, 0.00], + [0.19, 0.52, 0.73, 0.78, 0.66, 0.46, 0.26, 0.07], + [0.39, 0.73, 0.95, 0.50, 0.50, 0.53, 0.30, 0.14], + [0.48, 0.78, 0.50, 0.00, 0.00, 0.50, 0.23, 0.12], + [0.41, 0.66, 0.50, 0.00, 0.00, 0.50, 0.11, 0.05], + [0.26, 0.46, 0.53, 0.50, 0.50, 0.11, 0.03, 0.01], + [0.12, 0.26, 0.30, 0.23, 0.11, 0.03, 0.00, 0.00], + [0.00, 0.07, 0.14, 0.12, 0.05, 0.01, 0.00, 0.00]], + + [[1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 0.00, 0.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 0.00, 0.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], + [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00]], + ]).T + + assert_array_almost_equal(rgb, expect, decimal=2) + + +def test_light_source_hillshading(): + """ + Compare the current hillshading method against one that should be + mathematically equivalent. Illuminates a cone from a range of angles. + """ + + def alternative_hillshade(azimuth, elev, z): + illum = _sph2cart(*_azimuth2math(azimuth, elev)) + illum = np.array(illum) + + dy, dx = np.gradient(-z) + dy = -dy + dz = np.ones_like(dy) + normals = np.dstack([dx, dy, dz]) + normals /= np.linalg.norm(normals, axis=2)[..., None] + + intensity = np.tensordot(normals, illum, axes=(2, 0)) + intensity -= intensity.min() + intensity /= np.ptp(intensity) + return intensity + + y, x = np.mgrid[5:0:-1, :5] + z = -np.hypot(x - x.mean(), y - y.mean()) + + for az, elev in itertools.product(range(0, 390, 30), range(0, 105, 15)): + ls = mcolors.LightSource(az, elev) + h1 = ls.hillshade(z) + h2 = alternative_hillshade(az, elev, z) + assert_array_almost_equal(h1, h2) + + +def test_light_source_planar_hillshading(): + """ + Ensure that the illumination intensity is correct for planar surfaces. + """ + + def plane(azimuth, elevation, x, y): + """ + Create a plane whose normal vector is at the given azimuth and + elevation. + """ + theta, phi = _azimuth2math(azimuth, elevation) + a, b, c = _sph2cart(theta, phi) + z = -(a*x + b*y) / c + return z + + def angled_plane(azimuth, elevation, angle, x, y): + """ + Create a plane whose normal vector is at an angle from the given + azimuth and elevation. + """ + elevation = elevation + angle + if elevation > 90: + azimuth = (azimuth + 180) % 360 + elevation = (90 - elevation) % 90 + return plane(azimuth, elevation, x, y) + + y, x = np.mgrid[5:0:-1, :5] + for az, elev in itertools.product(range(0, 390, 30), range(0, 105, 15)): + ls = mcolors.LightSource(az, elev) + + # Make a plane at a range of angles to the illumination + for angle in range(0, 105, 15): + z = angled_plane(az, elev, angle, x, y) + h = ls.hillshade(z) + assert_array_almost_equal(h, np.cos(np.radians(angle))) + + +def test_color_names(): + assert mcolors.to_hex("blue") == "#0000ff" + assert mcolors.to_hex("xkcd:blue") == "#0343df" + assert mcolors.to_hex("tab:blue") == "#1f77b4" + + +def _sph2cart(theta, phi): + x = np.cos(theta) * np.sin(phi) + y = np.sin(theta) * np.sin(phi) + z = np.cos(phi) + return x, y, z + + +def _azimuth2math(azimuth, elevation): + """ + Convert from clockwise-from-north and up-from-horizontal to mathematical + conventions. + """ + theta = np.radians((90 - azimuth) % 360) + phi = np.radians(90 - elevation) + return theta, phi + + +def test_pandas_iterable(pd): + # Using a list or series yields equivalent + # colormaps, i.e the series isn't seen as + # a single color + lst = ['red', 'blue', 'green'] + s = pd.Series(lst) + cm1 = mcolors.ListedColormap(lst, N=5) + cm2 = mcolors.ListedColormap(s, N=5) + assert_array_equal(cm1.colors, cm2.colors) + + +@pytest.mark.parametrize('name', sorted(mpl.colormaps())) +def test_colormap_reversing(name): + """ + Check the generated _lut data of a colormap and corresponding reversed + colormap if they are almost the same. + """ + cmap = mpl.colormaps[name] + cmap_r = cmap.reversed() + if not cmap_r._isinit: + cmap._init() + cmap_r._init() + assert_array_almost_equal(cmap._lut[:-3], cmap_r._lut[-4::-1]) + # Test the bad, over, under values too + assert_array_almost_equal(cmap(-np.inf), cmap_r(np.inf)) + assert_array_almost_equal(cmap(np.inf), cmap_r(-np.inf)) + assert_array_almost_equal(cmap(np.nan), cmap_r(np.nan)) + + +def test_has_alpha_channel(): + assert mcolors._has_alpha_channel((0, 0, 0, 0)) + assert mcolors._has_alpha_channel([1, 1, 1, 1]) + assert not mcolors._has_alpha_channel('blue') # 4-char string! + assert not mcolors._has_alpha_channel('0.25') + assert not mcolors._has_alpha_channel('r') + assert not mcolors._has_alpha_channel((1, 0, 0)) + + +def test_cn(): + matplotlib.rcParams['axes.prop_cycle'] = cycler('color', + ['blue', 'r']) + assert mcolors.to_hex("C0") == '#0000ff' + assert mcolors.to_hex("C1") == '#ff0000' + + matplotlib.rcParams['axes.prop_cycle'] = cycler('color', + ['xkcd:blue', 'r']) + assert mcolors.to_hex("C0") == '#0343df' + assert mcolors.to_hex("C1") == '#ff0000' + assert mcolors.to_hex("C10") == '#0343df' + assert mcolors.to_hex("C11") == '#ff0000' + + matplotlib.rcParams['axes.prop_cycle'] = cycler('color', ['8e4585', 'r']) + + assert mcolors.to_hex("C0") == '#8e4585' + # if '8e4585' gets parsed as a float before it gets detected as a hex + # colour it will be interpreted as a very large number. + # this mustn't happen. + assert mcolors.to_rgb("C0")[0] != np.inf + + +def test_conversions(): + # to_rgba_array("none") returns a (0, 4) array. + assert_array_equal(mcolors.to_rgba_array("none"), np.zeros((0, 4))) + assert_array_equal(mcolors.to_rgba_array([]), np.zeros((0, 4))) + # a list of grayscale levels, not a single color. + assert_array_equal( + mcolors.to_rgba_array([".2", ".5", ".8"]), + np.vstack([mcolors.to_rgba(c) for c in [".2", ".5", ".8"]])) + # alpha is properly set. + assert mcolors.to_rgba((1, 1, 1), .5) == (1, 1, 1, .5) + assert mcolors.to_rgba(".1", .5) == (.1, .1, .1, .5) + # builtin round differs between py2 and py3. + assert mcolors.to_hex((.7, .7, .7)) == "#b2b2b2" + # hex roundtrip. + hex_color = "#1234abcd" + assert mcolors.to_hex(mcolors.to_rgba(hex_color), keep_alpha=True) == \ + hex_color + + +def test_conversions_masked(): + x1 = np.ma.array(['k', 'b'], mask=[True, False]) + x2 = np.ma.array([[0, 0, 0, 1], [0, 0, 1, 1]]) + x2[0] = np.ma.masked + assert mcolors.to_rgba(x1[0]) == (0, 0, 0, 0) + assert_array_equal(mcolors.to_rgba_array(x1), + [[0, 0, 0, 0], [0, 0, 1, 1]]) + assert_array_equal(mcolors.to_rgba_array(x2), mcolors.to_rgba_array(x1)) + + +def test_to_rgba_array_single_str(): + # single color name is valid + assert_array_equal(mcolors.to_rgba_array("red"), [(1, 0, 0, 1)]) + + # single char color sequence is invalid + with pytest.raises(ValueError, + match="'rgb' is not a valid color value."): + array = mcolors.to_rgba_array("rgb") + + +def test_to_rgba_array_2tuple_str(): + expected = np.array([[0, 0, 0, 1], [1, 1, 1, 1]]) + assert_array_equal(mcolors.to_rgba_array(("k", "w")), expected) + + +def test_to_rgba_array_alpha_array(): + with pytest.raises(ValueError, match="The number of colors must match"): + mcolors.to_rgba_array(np.ones((5, 3), float), alpha=np.ones((2,))) + alpha = [0.5, 0.6] + c = mcolors.to_rgba_array(np.ones((2, 3), float), alpha=alpha) + assert_array_equal(c[:, 3], alpha) + c = mcolors.to_rgba_array(['r', 'g'], alpha=alpha) + assert_array_equal(c[:, 3], alpha) + + +def test_to_rgba_array_accepts_color_alpha_tuple(): + assert_array_equal( + mcolors.to_rgba_array(('black', 0.9)), + [[0, 0, 0, 0.9]]) + + +def test_to_rgba_array_explicit_alpha_overrides_tuple_alpha(): + assert_array_equal( + mcolors.to_rgba_array(('black', 0.9), alpha=0.5), + [[0, 0, 0, 0.5]]) + + +def test_to_rgba_array_accepts_color_alpha_tuple_with_multiple_colors(): + color_array = np.array([[1., 1., 1., 1.], [0., 0., 1., 0.]]) + assert_array_equal( + mcolors.to_rgba_array((color_array, 0.2)), + [[1., 1., 1., 0.2], [0., 0., 1., 0.2]]) + + color_sequence = [[1., 1., 1., 1.], [0., 0., 1., 0.]] + assert_array_equal( + mcolors.to_rgba_array((color_sequence, 0.4)), + [[1., 1., 1., 0.4], [0., 0., 1., 0.4]]) + + +def test_to_rgba_array_error_with_color_invalid_alpha_tuple(): + with pytest.raises(ValueError, match="'alpha' must be between 0 and 1,"): + mcolors.to_rgba_array(('black', 2.0)) + + +@pytest.mark.parametrize('rgba_alpha', + [('white', 0.5), ('#ffffff', 0.5), ('#ffffff00', 0.5), + ((1.0, 1.0, 1.0, 1.0), 0.5)]) +def test_to_rgba_accepts_color_alpha_tuple(rgba_alpha): + assert mcolors.to_rgba(rgba_alpha) == (1, 1, 1, 0.5) + + +def test_to_rgba_explicit_alpha_overrides_tuple_alpha(): + assert mcolors.to_rgba(('red', 0.1), alpha=0.9) == (1, 0, 0, 0.9) + + +def test_to_rgba_error_with_color_invalid_alpha_tuple(): + with pytest.raises(ValueError, match="'alpha' must be between 0 and 1"): + mcolors.to_rgba(('blue', 2.0)) + + +@pytest.mark.parametrize("bytes", (True, False)) +def test_scalarmappable_to_rgba(bytes): + sm = cm.ScalarMappable() + alpha_1 = 255 if bytes else 1 + + # uint8 RGBA + x = np.ones((2, 3, 4), dtype=np.uint8) + expected = x.copy() if bytes else x.astype(np.float32)/255 + np.testing.assert_array_equal(sm.to_rgba(x, bytes=bytes), expected) + # uint8 RGB + expected[..., 3] = alpha_1 + np.testing.assert_array_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected) + # uint8 masked RGBA + xm = np.ma.masked_array(x, mask=np.zeros_like(x)) + xm.mask[0, 0, 0] = True + expected = x.copy() if bytes else x.astype(np.float32)/255 + expected[0, 0, 3] = 0 + np.testing.assert_array_equal(sm.to_rgba(xm, bytes=bytes), expected) + # uint8 masked RGB + expected[..., 3] = alpha_1 + expected[0, 0, 3] = 0 + np.testing.assert_array_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected) + + # float RGBA + x = np.ones((2, 3, 4), dtype=float) * 0.5 + expected = (x * 255).astype(np.uint8) if bytes else x.copy() + np.testing.assert_array_equal(sm.to_rgba(x, bytes=bytes), expected) + # float RGB + expected[..., 3] = alpha_1 + np.testing.assert_array_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected) + # float masked RGBA + xm = np.ma.masked_array(x, mask=np.zeros_like(x)) + xm.mask[0, 0, 0] = True + expected = (x * 255).astype(np.uint8) if bytes else x.copy() + expected[0, 0, 3] = 0 + np.testing.assert_array_equal(sm.to_rgba(xm, bytes=bytes), expected) + # float masked RGB + expected[..., 3] = alpha_1 + expected[0, 0, 3] = 0 + np.testing.assert_array_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected) + + +def test_failed_conversions(): + with pytest.raises(ValueError): + mcolors.to_rgba('5') + with pytest.raises(ValueError): + mcolors.to_rgba('-1') + with pytest.raises(ValueError): + mcolors.to_rgba('nan') + with pytest.raises(ValueError): + mcolors.to_rgba('unknown_color') + with pytest.raises(ValueError): + # Gray must be a string to distinguish 3-4 grays from RGB or RGBA. + mcolors.to_rgba(0.4) + + +def test_grey_gray(): + color_mapping = mcolors._colors_full_map + for k in color_mapping.keys(): + if 'grey' in k: + assert color_mapping[k] == color_mapping[k.replace('grey', 'gray')] + if 'gray' in k: + assert color_mapping[k] == color_mapping[k.replace('gray', 'grey')] + + +def test_tableau_order(): + dflt_cycle = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', + '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', + '#bcbd22', '#17becf'] + + assert list(mcolors.TABLEAU_COLORS.values()) == dflt_cycle + + +def test_ndarray_subclass_norm(): + # Emulate an ndarray subclass that handles units + # which objects when adding or subtracting with other + # arrays. See #6622 and #8696 + class MyArray(np.ndarray): + def __isub__(self, other): # type: ignore + raise RuntimeError + + def __add__(self, other): + raise RuntimeError + + data = np.arange(-10, 10, 1, dtype=float).reshape((10, 2)) + mydata = data.view(MyArray) + + for norm in [mcolors.Normalize(), mcolors.LogNorm(), + mcolors.SymLogNorm(3, vmax=5, linscale=1, base=np.e), + mcolors.Normalize(vmin=mydata.min(), vmax=mydata.max()), + mcolors.SymLogNorm(3, vmin=mydata.min(), vmax=mydata.max(), + base=np.e), + mcolors.PowerNorm(1)]: + assert_array_equal(norm(mydata), norm(data)) + fig, ax = plt.subplots() + ax.imshow(mydata, norm=norm) + fig.canvas.draw() # Check that no warning is emitted. + + +def test_same_color(): + assert mcolors.same_color('k', (0, 0, 0)) + assert not mcolors.same_color('w', (1, 1, 0)) + assert mcolors.same_color(['red', 'blue'], ['r', 'b']) + assert mcolors.same_color('none', 'none') + assert not mcolors.same_color('none', 'red') + with pytest.raises(ValueError): + mcolors.same_color(['r', 'g', 'b'], ['r']) + with pytest.raises(ValueError): + mcolors.same_color(['red', 'green'], 'none') + + +def test_hex_shorthand_notation(): + assert mcolors.same_color("#123", "#112233") + assert mcolors.same_color("#123a", "#112233aa") + + +def test_repr_png(): + cmap = mpl.colormaps['viridis'] + png = cmap._repr_png_() + assert len(png) > 0 + img = Image.open(BytesIO(png)) + assert img.width > 0 + assert img.height > 0 + assert 'Title' in img.text + assert 'Description' in img.text + assert 'Author' in img.text + assert 'Software' in img.text + + +def test_repr_html(): + cmap = mpl.colormaps['viridis'] + html = cmap._repr_html_() + assert len(html) > 0 + png = cmap._repr_png_() + assert base64.b64encode(png).decode('ascii') in html + assert cmap.name in html + assert html.startswith('<div') + assert html.endswith('</div>') + + +def test_get_under_over_bad(): + cmap = mpl.colormaps['viridis'] + assert_array_equal(cmap.get_under(), cmap(-np.inf)) + assert_array_equal(cmap.get_over(), cmap(np.inf)) + assert_array_equal(cmap.get_bad(), cmap(np.nan)) + + +@pytest.mark.parametrize('kind', ('over', 'under', 'bad')) +def test_non_mutable_get_values(kind): + cmap = copy.copy(mpl.colormaps['viridis']) + init_value = getattr(cmap, f'get_{kind}')() + getattr(cmap, f'set_{kind}')('k') + black_value = getattr(cmap, f'get_{kind}')() + assert np.all(black_value == [0, 0, 0, 1]) + assert not np.all(init_value == black_value) + + +def test_colormap_alpha_array(): + cmap = mpl.colormaps['viridis'] + vals = [-1, 0.5, 2] # under, valid, over + with pytest.raises(ValueError, match="alpha is array-like but"): + cmap(vals, alpha=[1, 1, 1, 1]) + alpha = np.array([0.1, 0.2, 0.3]) + c = cmap(vals, alpha=alpha) + assert_array_equal(c[:, -1], alpha) + c = cmap(vals, alpha=alpha, bytes=True) + assert_array_equal(c[:, -1], (alpha * 255).astype(np.uint8)) + + +def test_colormap_bad_data_with_alpha(): + cmap = mpl.colormaps['viridis'] + c = cmap(np.nan, alpha=0.5) + assert c == (0, 0, 0, 0) + c = cmap([0.5, np.nan], alpha=0.5) + assert_array_equal(c[1], (0, 0, 0, 0)) + c = cmap([0.5, np.nan], alpha=[0.1, 0.2]) + assert_array_equal(c[1], (0, 0, 0, 0)) + c = cmap([[np.nan, 0.5], [0, 0]], alpha=0.5) + assert_array_equal(c[0, 0], (0, 0, 0, 0)) + c = cmap([[np.nan, 0.5], [0, 0]], alpha=np.full((2, 2), 0.5)) + assert_array_equal(c[0, 0], (0, 0, 0, 0)) + + +def test_2d_to_rgba(): + color = np.array([0.1, 0.2, 0.3]) + rgba_1d = mcolors.to_rgba(color.reshape(-1)) + rgba_2d = mcolors.to_rgba(color.reshape((1, -1))) + assert rgba_1d == rgba_2d + + +def test_set_dict_to_rgba(): + # downstream libraries do this... + # note we can't test this because it is not well-ordered + # so just smoketest: + colors = {(0, .5, 1), (1, .2, .5), (.4, 1, .2)} + res = mcolors.to_rgba_array(colors) + palette = {"red": (1, 0, 0), "green": (0, 1, 0), "blue": (0, 0, 1)} + res = mcolors.to_rgba_array(palette.values()) + exp = np.eye(3) + np.testing.assert_array_almost_equal(res[:, :-1], exp) + + +def test_norm_deepcopy(): + norm = mcolors.LogNorm() + norm.vmin = 0.0002 + norm2 = copy.deepcopy(norm) + assert norm2.vmin == norm.vmin + assert isinstance(norm2._scale, mscale.LogScale) + norm = mcolors.Normalize() + norm.vmin = 0.0002 + norm2 = copy.deepcopy(norm) + assert norm2._scale is None + assert norm2.vmin == norm.vmin + + +def test_norm_callback(): + increment = unittest.mock.Mock(return_value=None) + + norm = mcolors.Normalize() + norm.callbacks.connect('changed', increment) + # Haven't updated anything, so call count should be 0 + assert increment.call_count == 0 + + # Now change vmin and vmax to test callbacks + norm.vmin = 1 + assert increment.call_count == 1 + norm.vmax = 5 + assert increment.call_count == 2 + # callback shouldn't be called if setting to the same value + norm.vmin = 1 + assert increment.call_count == 2 + norm.vmax = 5 + assert increment.call_count == 2 + + # We only want autoscale() calls to send out one update signal + increment.call_count = 0 + norm.autoscale([0, 1, 2]) + assert increment.call_count == 1 + + +def test_scalarmappable_norm_update(): + norm = mcolors.Normalize() + sm = matplotlib.cm.ScalarMappable(norm=norm, cmap='plasma') + # sm doesn't have a stale attribute at first, set it to False + sm.stale = False + # The mappable should be stale after updating vmin/vmax + norm.vmin = 5 + assert sm.stale + sm.stale = False + norm.vmax = 5 + assert sm.stale + sm.stale = False + norm.clip = True + assert sm.stale + # change to the CenteredNorm and TwoSlopeNorm to test those + # Also make sure that updating the norm directly and with + # set_norm both update the Norm callback + norm = mcolors.CenteredNorm() + sm.norm = norm + sm.stale = False + norm.vcenter = 1 + assert sm.stale + norm = mcolors.TwoSlopeNorm(vcenter=0, vmin=-1, vmax=1) + sm.set_norm(norm) + sm.stale = False + norm.vcenter = 1 + assert sm.stale + + +@check_figures_equal() +def test_norm_update_figs(fig_test, fig_ref): + ax_ref = fig_ref.add_subplot() + ax_test = fig_test.add_subplot() + + z = np.arange(100).reshape((10, 10)) + ax_ref.imshow(z, norm=mcolors.Normalize(10, 90)) + + # Create the norm beforehand with different limits and then update + # after adding to the plot + norm = mcolors.Normalize(0, 1) + ax_test.imshow(z, norm=norm) + # Force initial draw to make sure it isn't already stale + fig_test.canvas.draw() + norm.vmin, norm.vmax = 10, 90 + + +def test_make_norm_from_scale_name(): + logitnorm = mcolors.make_norm_from_scale( + mscale.LogitScale, mcolors.Normalize) + assert logitnorm.__name__ == logitnorm.__qualname__ == "LogitScaleNorm" + + +def test_color_sequences(): + # basic access + assert plt.color_sequences is matplotlib.color_sequences # same registry + assert list(plt.color_sequences) == [ + 'tab10', 'tab20', 'tab20b', 'tab20c', 'Pastel1', 'Pastel2', 'Paired', + 'Accent', 'Dark2', 'Set1', 'Set2', 'Set3'] + assert len(plt.color_sequences['tab10']) == 10 + assert len(plt.color_sequences['tab20']) == 20 + + tab_colors = [ + 'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', + 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'] + for seq_color, tab_color in zip(plt.color_sequences['tab10'], tab_colors): + assert mcolors.same_color(seq_color, tab_color) + + # registering + with pytest.raises(ValueError, match="reserved name"): + plt.color_sequences.register('tab10', ['r', 'g', 'b']) + with pytest.raises(ValueError, match="not a valid color specification"): + plt.color_sequences.register('invalid', ['not a color']) + + rgb_colors = ['r', 'g', 'b'] + plt.color_sequences.register('rgb', rgb_colors) + assert plt.color_sequences['rgb'] == ['r', 'g', 'b'] + # should not affect the registered sequence because input is copied + rgb_colors.append('c') + assert plt.color_sequences['rgb'] == ['r', 'g', 'b'] + # should not affect the registered sequence because returned list is a copy + plt.color_sequences['rgb'].append('c') + assert plt.color_sequences['rgb'] == ['r', 'g', 'b'] + + # unregister + plt.color_sequences.unregister('rgb') + with pytest.raises(KeyError): + plt.color_sequences['rgb'] # rgb is gone + plt.color_sequences.unregister('rgb') # multiple unregisters are ok + with pytest.raises(ValueError, match="Cannot unregister builtin"): + plt.color_sequences.unregister('tab10') + + +def test_cm_set_cmap_error(): + sm = cm.ScalarMappable() + # Pick a name we are pretty sure will never be a colormap name + bad_cmap = 'AardvarksAreAwkward' + with pytest.raises(ValueError, match=bad_cmap): + sm.set_cmap(bad_cmap) + + +def test_set_cmap_mismatched_name(): + cmap = matplotlib.colormaps["viridis"].with_extremes(over='r') + # register it with different names + cmap.name = "test-cmap" + matplotlib.colormaps.register(name='wrong-cmap', cmap=cmap) + + plt.set_cmap("wrong-cmap") + cmap_returned = plt.get_cmap("wrong-cmap") + assert cmap_returned == cmap + assert cmap_returned.name == "wrong-cmap" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_compare_images.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_compare_images.py new file mode 100644 index 00000000..6023f3d0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_compare_images.py @@ -0,0 +1,73 @@ +from pathlib import Path +import shutil + +import pytest +from pytest import approx + +from matplotlib.testing.compare import compare_images +from matplotlib.testing.decorators import _image_directories + + +# Tests of the image comparison algorithm. +@pytest.mark.parametrize( + 'im1, im2, tol, expect_rms', + [ + # Comparison of an image and the same image with minor differences. + # This expects the images to compare equal under normal tolerance, and + # have a small RMS. + ('basn3p02.png', 'basn3p02-minorchange.png', 10, None), + # Now test with no tolerance. + ('basn3p02.png', 'basn3p02-minorchange.png', 0, 6.50646), + # Comparison with an image that is shifted by 1px in the X axis. + ('basn3p02.png', 'basn3p02-1px-offset.png', 0, 90.15611), + # Comparison with an image with half the pixels shifted by 1px in the X + # axis. + ('basn3p02.png', 'basn3p02-half-1px-offset.png', 0, 63.75), + # Comparison of an image and the same image scrambled. + # This expects the images to compare completely different, with a very + # large RMS. + # Note: The image has been scrambled in a specific way, by having + # each color component of each pixel randomly placed somewhere in the + # image. It contains exactly the same number of pixels of each color + # value of R, G and B, but in a totally different position. + # Test with no tolerance to make sure that we pick up even a very small + # RMS error. + ('basn3p02.png', 'basn3p02-scrambled.png', 0, 172.63582), + # Comparison of an image and a slightly brighter image. + # The two images are solid color, with the second image being exactly 1 + # color value brighter. + # This expects the images to compare equal under normal tolerance, and + # have an RMS of exactly 1. + ('all127.png', 'all128.png', 0, 1), + # Now test the reverse comparison. + ('all128.png', 'all127.png', 0, 1), + ]) +def test_image_comparison_expect_rms(im1, im2, tol, expect_rms, tmp_path, + monkeypatch): + """ + Compare two images, expecting a particular RMS error. + + im1 and im2 are filenames relative to the baseline_dir directory. + + tol is the tolerance to pass to compare_images. + + expect_rms is the expected RMS value, or None. If None, the test will + succeed if compare_images succeeds. Otherwise, the test will succeed if + compare_images fails and returns an RMS error almost equal to this value. + """ + # Change the working directory using monkeypatch to use a temporary + # test specific directory + monkeypatch.chdir(tmp_path) + baseline_dir, result_dir = map(Path, _image_directories(lambda: "dummy")) + # Copy "test" image to result_dir, so that compare_images writes + # the diff to result_dir, rather than to the source tree + result_im2 = result_dir / im1 + shutil.copyfile(baseline_dir / im2, result_im2) + results = compare_images( + baseline_dir / im1, result_im2, tol=tol, in_decorator=True) + + if expect_rms is None: + assert results is None + else: + assert results is not None + assert results['rms'] == approx(expect_rms, abs=1e-4) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_constrainedlayout.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_constrainedlayout.py new file mode 100644 index 00000000..6703dfe3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_constrainedlayout.py @@ -0,0 +1,694 @@ +import gc +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms +from matplotlib import gridspec, ticker + + +def example_plot(ax, fontsize=12, nodec=False): + ax.plot([1, 2]) + ax.locator_params(nbins=3) + if not nodec: + ax.set_xlabel('x-label', fontsize=fontsize) + ax.set_ylabel('y-label', fontsize=fontsize) + ax.set_title('Title', fontsize=fontsize) + else: + ax.set_xticklabels([]) + ax.set_yticklabels([]) + + +def example_pcolor(ax, fontsize=12): + dx, dy = 0.6, 0.6 + y, x = np.mgrid[slice(-3, 3 + dy, dy), + slice(-3, 3 + dx, dx)] + z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2) + pcm = ax.pcolormesh(x, y, z[:-1, :-1], cmap='RdBu_r', vmin=-1., vmax=1., + rasterized=True) + ax.set_xlabel('x-label', fontsize=fontsize) + ax.set_ylabel('y-label', fontsize=fontsize) + ax.set_title('Title', fontsize=fontsize) + return pcm + + +@image_comparison(['constrained_layout1.png']) +def test_constrained_layout1(): + """Test constrained_layout for a single subplot""" + fig = plt.figure(layout="constrained") + ax = fig.add_subplot() + example_plot(ax, fontsize=24) + + +@image_comparison(['constrained_layout2.png']) +def test_constrained_layout2(): + """Test constrained_layout for 2x2 subplots""" + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + example_plot(ax, fontsize=24) + + +@image_comparison(['constrained_layout3.png']) +def test_constrained_layout3(): + """Test constrained_layout for colorbars with subplots""" + + fig, axs = plt.subplots(2, 2, layout="constrained") + for nn, ax in enumerate(axs.flat): + pcm = example_pcolor(ax, fontsize=24) + if nn == 3: + pad = 0.08 + else: + pad = 0.02 # default + fig.colorbar(pcm, ax=ax, pad=pad) + + +@image_comparison(['constrained_layout4.png']) +def test_constrained_layout4(): + """Test constrained_layout for a single colorbar with subplots""" + + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + pcm = example_pcolor(ax, fontsize=24) + fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) + + +@image_comparison(['constrained_layout5.png'], tol=0.002) +def test_constrained_layout5(): + """ + Test constrained_layout for a single colorbar with subplots, + colorbar bottom + """ + + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + pcm = example_pcolor(ax, fontsize=24) + fig.colorbar(pcm, ax=axs, + use_gridspec=False, pad=0.01, shrink=0.6, + location='bottom') + + +@image_comparison(['constrained_layout6.png'], tol=0.002) +def test_constrained_layout6(): + """Test constrained_layout for nested gridspecs""" + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig = plt.figure(layout="constrained") + gs = fig.add_gridspec(1, 2, figure=fig) + gsl = gs[0].subgridspec(2, 2) + gsr = gs[1].subgridspec(1, 2) + axsl = [] + for gs in gsl: + ax = fig.add_subplot(gs) + axsl += [ax] + example_plot(ax, fontsize=12) + ax.set_xlabel('x-label\nMultiLine') + axsr = [] + for gs in gsr: + ax = fig.add_subplot(gs) + axsr += [ax] + pcm = example_pcolor(ax, fontsize=12) + + fig.colorbar(pcm, ax=axsr, + pad=0.01, shrink=0.99, location='bottom', + ticks=ticker.MaxNLocator(nbins=5)) + + +def test_identical_subgridspec(): + + fig = plt.figure(constrained_layout=True) + + GS = fig.add_gridspec(2, 1) + + GSA = GS[0].subgridspec(1, 3) + GSB = GS[1].subgridspec(1, 3) + + axa = [] + axb = [] + for i in range(3): + axa += [fig.add_subplot(GSA[i])] + axb += [fig.add_subplot(GSB[i])] + + fig.draw_without_rendering() + # check first row above second + assert axa[0].get_position().y0 > axb[0].get_position().y1 + + +def test_constrained_layout7(): + """Test for proper warning if fig not set in GridSpec""" + with pytest.warns( + UserWarning, match=('There are no gridspecs with layoutgrids. ' + 'Possibly did not call parent GridSpec with ' + 'the "figure" keyword')): + fig = plt.figure(layout="constrained") + gs = gridspec.GridSpec(1, 2) + gsl = gridspec.GridSpecFromSubplotSpec(2, 2, gs[0]) + gsr = gridspec.GridSpecFromSubplotSpec(1, 2, gs[1]) + for gs in gsl: + fig.add_subplot(gs) + # need to trigger a draw to get warning + fig.draw_without_rendering() + + +@image_comparison(['constrained_layout8.png']) +def test_constrained_layout8(): + """Test for gridspecs that are not completely full""" + + fig = plt.figure(figsize=(10, 5), layout="constrained") + gs = gridspec.GridSpec(3, 5, figure=fig) + axs = [] + for j in [0, 1]: + if j == 0: + ilist = [1] + else: + ilist = [0, 4] + for i in ilist: + ax = fig.add_subplot(gs[j, i]) + axs += [ax] + example_pcolor(ax, fontsize=9) + if i > 0: + ax.set_ylabel('') + if j < 1: + ax.set_xlabel('') + ax.set_title('') + ax = fig.add_subplot(gs[2, :]) + axs += [ax] + pcm = example_pcolor(ax, fontsize=9) + + fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) + + +@image_comparison(['constrained_layout9.png']) +def test_constrained_layout9(): + """Test for handling suptitle and for sharex and sharey""" + + fig, axs = plt.subplots(2, 2, layout="constrained", + sharex=False, sharey=False) + for ax in axs.flat: + pcm = example_pcolor(ax, fontsize=24) + ax.set_xlabel('') + ax.set_ylabel('') + ax.set_aspect(2.) + fig.colorbar(pcm, ax=axs, pad=0.01, shrink=0.6) + fig.suptitle('Test Suptitle', fontsize=28) + + +@image_comparison(['constrained_layout10.png']) +def test_constrained_layout10(): + """Test for handling legend outside axis""" + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + ax.plot(np.arange(12), label='This is a label') + ax.legend(loc='center left', bbox_to_anchor=(0.8, 0.5)) + + +@image_comparison(['constrained_layout11.png']) +def test_constrained_layout11(): + """Test for multiple nested gridspecs""" + + fig = plt.figure(layout="constrained", figsize=(13, 3)) + gs0 = gridspec.GridSpec(1, 2, figure=fig) + gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0]) + gsl0 = gridspec.GridSpecFromSubplotSpec(2, 2, gsl[1]) + ax = fig.add_subplot(gs0[1]) + example_plot(ax, fontsize=9) + axs = [] + for gs in gsl0: + ax = fig.add_subplot(gs) + axs += [ax] + pcm = example_pcolor(ax, fontsize=9) + fig.colorbar(pcm, ax=axs, shrink=0.6, aspect=70.) + ax = fig.add_subplot(gsl[0]) + example_plot(ax, fontsize=9) + + +@image_comparison(['constrained_layout11rat.png']) +def test_constrained_layout11rat(): + """Test for multiple nested gridspecs with width_ratios""" + + fig = plt.figure(layout="constrained", figsize=(10, 3)) + gs0 = gridspec.GridSpec(1, 2, figure=fig, width_ratios=[6, 1]) + gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0]) + gsl0 = gridspec.GridSpecFromSubplotSpec(2, 2, gsl[1], height_ratios=[2, 1]) + ax = fig.add_subplot(gs0[1]) + example_plot(ax, fontsize=9) + axs = [] + for gs in gsl0: + ax = fig.add_subplot(gs) + axs += [ax] + pcm = example_pcolor(ax, fontsize=9) + fig.colorbar(pcm, ax=axs, shrink=0.6, aspect=70.) + ax = fig.add_subplot(gsl[0]) + example_plot(ax, fontsize=9) + + +@image_comparison(['constrained_layout12.png']) +def test_constrained_layout12(): + """Test that very unbalanced labeling still works.""" + fig = plt.figure(layout="constrained", figsize=(6, 8)) + + gs0 = gridspec.GridSpec(6, 2, figure=fig) + + ax1 = fig.add_subplot(gs0[:3, 1]) + ax2 = fig.add_subplot(gs0[3:, 1]) + + example_plot(ax1, fontsize=18) + example_plot(ax2, fontsize=18) + + ax = fig.add_subplot(gs0[0:2, 0]) + example_plot(ax, nodec=True) + ax = fig.add_subplot(gs0[2:4, 0]) + example_plot(ax, nodec=True) + ax = fig.add_subplot(gs0[4:, 0]) + example_plot(ax, nodec=True) + ax.set_xlabel('x-label') + + +@image_comparison(['constrained_layout13.png'], tol=2.e-2) +def test_constrained_layout13(): + """Test that padding works.""" + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + pcm = example_pcolor(ax, fontsize=12) + fig.colorbar(pcm, ax=ax, shrink=0.6, aspect=20., pad=0.02) + with pytest.raises(TypeError): + fig.get_layout_engine().set(wpad=1, hpad=2) + fig.get_layout_engine().set(w_pad=24./72., h_pad=24./72.) + + +@image_comparison(['constrained_layout14.png']) +def test_constrained_layout14(): + """Test that padding works.""" + fig, axs = plt.subplots(2, 2, layout="constrained") + for ax in axs.flat: + pcm = example_pcolor(ax, fontsize=12) + fig.colorbar(pcm, ax=ax, shrink=0.6, aspect=20., pad=0.02) + fig.get_layout_engine().set( + w_pad=3./72., h_pad=3./72., + hspace=0.2, wspace=0.2) + + +@image_comparison(['constrained_layout15.png']) +def test_constrained_layout15(): + """Test that rcparams work.""" + mpl.rcParams['figure.constrained_layout.use'] = True + fig, axs = plt.subplots(2, 2) + for ax in axs.flat: + example_plot(ax, fontsize=12) + + +@image_comparison(['constrained_layout16.png']) +def test_constrained_layout16(): + """Test ax.set_position.""" + fig, ax = plt.subplots(layout="constrained") + example_plot(ax, fontsize=12) + ax2 = fig.add_axes([0.2, 0.2, 0.4, 0.4]) + + +@image_comparison(['constrained_layout17.png']) +def test_constrained_layout17(): + """Test uneven gridspecs""" + fig = plt.figure(layout="constrained") + gs = gridspec.GridSpec(3, 3, figure=fig) + + ax1 = fig.add_subplot(gs[0, 0]) + ax2 = fig.add_subplot(gs[0, 1:]) + ax3 = fig.add_subplot(gs[1:, 0:2]) + ax4 = fig.add_subplot(gs[1:, -1]) + + example_plot(ax1) + example_plot(ax2) + example_plot(ax3) + example_plot(ax4) + + +def test_constrained_layout18(): + """Test twinx""" + fig, ax = plt.subplots(layout="constrained") + ax2 = ax.twinx() + example_plot(ax) + example_plot(ax2, fontsize=24) + fig.draw_without_rendering() + assert all(ax.get_position().extents == ax2.get_position().extents) + + +def test_constrained_layout19(): + """Test twiny""" + fig, ax = plt.subplots(layout="constrained") + ax2 = ax.twiny() + example_plot(ax) + example_plot(ax2, fontsize=24) + ax2.set_title('') + ax.set_title('') + fig.draw_without_rendering() + assert all(ax.get_position().extents == ax2.get_position().extents) + + +def test_constrained_layout20(): + """Smoke test cl does not mess up added axes""" + gx = np.linspace(-5, 5, 4) + img = np.hypot(gx, gx[:, None]) + + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1]) + mesh = ax.pcolormesh(gx, gx, img[:-1, :-1]) + fig.colorbar(mesh) + + +def test_constrained_layout21(): + """#11035: repeated calls to suptitle should not alter the layout""" + fig, ax = plt.subplots(layout="constrained") + + fig.suptitle("Suptitle0") + fig.draw_without_rendering() + extents0 = np.copy(ax.get_position().extents) + + fig.suptitle("Suptitle1") + fig.draw_without_rendering() + extents1 = np.copy(ax.get_position().extents) + + np.testing.assert_allclose(extents0, extents1) + + +def test_constrained_layout22(): + """#11035: suptitle should not be include in CL if manually positioned""" + fig, ax = plt.subplots(layout="constrained") + + fig.draw_without_rendering() + extents0 = np.copy(ax.get_position().extents) + + fig.suptitle("Suptitle", y=0.5) + fig.draw_without_rendering() + extents1 = np.copy(ax.get_position().extents) + + np.testing.assert_allclose(extents0, extents1) + + +def test_constrained_layout23(): + """ + Comment in #11035: suptitle used to cause an exception when + reusing a figure w/ CL with ``clear=True``. + """ + + for i in range(2): + fig = plt.figure(layout="constrained", clear=True, num="123") + gs = fig.add_gridspec(1, 2) + sub = gs[0].subgridspec(2, 2) + fig.suptitle(f"Suptitle{i}") + + +@image_comparison(['test_colorbar_location.png'], + remove_text=True, style='mpl20') +def test_colorbar_location(): + """ + Test that colorbar handling is as expected for various complicated + cases... + """ + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig, axs = plt.subplots(4, 5, layout="constrained") + for ax in axs.flat: + pcm = example_pcolor(ax) + ax.set_xlabel('') + ax.set_ylabel('') + fig.colorbar(pcm, ax=axs[:, 1], shrink=0.4) + fig.colorbar(pcm, ax=axs[-1, :2], shrink=0.5, location='bottom') + fig.colorbar(pcm, ax=axs[0, 2:], shrink=0.5, location='bottom', pad=0.05) + fig.colorbar(pcm, ax=axs[-2, 3:], shrink=0.5, location='top') + fig.colorbar(pcm, ax=axs[0, 0], shrink=0.5, location='left') + fig.colorbar(pcm, ax=axs[1:3, 2], shrink=0.5, location='right') + + +def test_hidden_axes(): + # test that if we make an Axes not visible that constrained_layout + # still works. Note the axes still takes space in the layout + # (as does a gridspec slot that is empty) + fig, axs = plt.subplots(2, 2, layout="constrained") + axs[0, 1].set_visible(False) + fig.draw_without_rendering() + extents1 = np.copy(axs[0, 0].get_position().extents) + + np.testing.assert_allclose( + extents1, [0.045552, 0.543288, 0.47819, 0.982638], rtol=1e-5) + + +def test_colorbar_align(): + for location in ['right', 'left', 'top', 'bottom']: + fig, axs = plt.subplots(2, 2, layout="constrained") + cbs = [] + for nn, ax in enumerate(axs.flat): + ax.tick_params(direction='in') + pc = example_pcolor(ax) + cb = fig.colorbar(pc, ax=ax, location=location, shrink=0.6, + pad=0.04) + cbs += [cb] + cb.ax.tick_params(direction='in') + if nn != 1: + cb.ax.xaxis.set_ticks([]) + cb.ax.yaxis.set_ticks([]) + ax.set_xticklabels([]) + ax.set_yticklabels([]) + fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, + hspace=0.1, wspace=0.1) + + fig.draw_without_rendering() + if location in ['left', 'right']: + np.testing.assert_allclose(cbs[0].ax.get_position().x0, + cbs[2].ax.get_position().x0) + np.testing.assert_allclose(cbs[1].ax.get_position().x0, + cbs[3].ax.get_position().x0) + else: + np.testing.assert_allclose(cbs[0].ax.get_position().y0, + cbs[1].ax.get_position().y0) + np.testing.assert_allclose(cbs[2].ax.get_position().y0, + cbs[3].ax.get_position().y0) + + +@image_comparison(['test_colorbars_no_overlapV.png'], style='mpl20') +def test_colorbars_no_overlapV(): + fig = plt.figure(figsize=(2, 4), layout="constrained") + axs = fig.subplots(2, 1, sharex=True, sharey=True) + for ax in axs: + ax.yaxis.set_major_formatter(ticker.NullFormatter()) + ax.tick_params(axis='both', direction='in') + im = ax.imshow([[1, 2], [3, 4]]) + fig.colorbar(im, ax=ax, orientation="vertical") + fig.suptitle("foo") + + +@image_comparison(['test_colorbars_no_overlapH.png'], style='mpl20') +def test_colorbars_no_overlapH(): + fig = plt.figure(figsize=(4, 2), layout="constrained") + fig.suptitle("foo") + axs = fig.subplots(1, 2, sharex=True, sharey=True) + for ax in axs: + ax.yaxis.set_major_formatter(ticker.NullFormatter()) + ax.tick_params(axis='both', direction='in') + im = ax.imshow([[1, 2], [3, 4]]) + fig.colorbar(im, ax=ax, orientation="horizontal") + + +def test_manually_set_position(): + fig, axs = plt.subplots(1, 2, layout="constrained") + axs[0].set_position([0.2, 0.2, 0.3, 0.3]) + fig.draw_without_rendering() + pp = axs[0].get_position() + np.testing.assert_allclose(pp, [[0.2, 0.2], [0.5, 0.5]]) + + fig, axs = plt.subplots(1, 2, layout="constrained") + axs[0].set_position([0.2, 0.2, 0.3, 0.3]) + pc = axs[0].pcolormesh(np.random.rand(20, 20)) + fig.colorbar(pc, ax=axs[0]) + fig.draw_without_rendering() + pp = axs[0].get_position() + np.testing.assert_allclose(pp, [[0.2, 0.2], [0.44, 0.5]]) + + +@image_comparison(['test_bboxtight.png'], + remove_text=True, style='mpl20', + savefig_kwarg={'bbox_inches': 'tight'}) +def test_bboxtight(): + fig, ax = plt.subplots(layout="constrained") + ax.set_aspect(1.) + + +@image_comparison(['test_bbox.png'], + remove_text=True, style='mpl20', + savefig_kwarg={'bbox_inches': + mtransforms.Bbox([[0.5, 0], [2.5, 2]])}) +def test_bbox(): + fig, ax = plt.subplots(layout="constrained") + ax.set_aspect(1.) + + +def test_align_labels(): + """ + Tests for a bug in which constrained layout and align_ylabels on + three unevenly sized subplots, one of whose y tick labels include + negative numbers, drives the non-negative subplots' y labels off + the edge of the plot + """ + fig, (ax3, ax1, ax2) = plt.subplots(3, 1, layout="constrained", + figsize=(6.4, 8), + gridspec_kw={"height_ratios": (1, 1, + 0.7)}) + + ax1.set_ylim(0, 1) + ax1.set_ylabel("Label") + + ax2.set_ylim(-1.5, 1.5) + ax2.set_ylabel("Label") + + ax3.set_ylim(0, 1) + ax3.set_ylabel("Label") + + fig.align_ylabels(axs=(ax3, ax1, ax2)) + + fig.draw_without_rendering() + after_align = [ax1.yaxis.label.get_window_extent(), + ax2.yaxis.label.get_window_extent(), + ax3.yaxis.label.get_window_extent()] + # ensure labels are approximately aligned + np.testing.assert_allclose([after_align[0].x0, after_align[2].x0], + after_align[1].x0, rtol=0, atol=1e-05) + # ensure labels do not go off the edge + assert after_align[0].x0 >= 1 + + +def test_suplabels(): + fig, ax = plt.subplots(layout="constrained") + fig.draw_without_rendering() + pos0 = ax.get_tightbbox(fig.canvas.get_renderer()) + fig.supxlabel('Boo') + fig.supylabel('Booy') + fig.draw_without_rendering() + pos = ax.get_tightbbox(fig.canvas.get_renderer()) + assert pos.y0 > pos0.y0 + 10.0 + assert pos.x0 > pos0.x0 + 10.0 + + fig, ax = plt.subplots(layout="constrained") + fig.draw_without_rendering() + pos0 = ax.get_tightbbox(fig.canvas.get_renderer()) + # check that specifying x (y) doesn't ruin the layout + fig.supxlabel('Boo', x=0.5) + fig.supylabel('Boo', y=0.5) + fig.draw_without_rendering() + pos = ax.get_tightbbox(fig.canvas.get_renderer()) + assert pos.y0 > pos0.y0 + 10.0 + assert pos.x0 > pos0.x0 + 10.0 + + +def test_gridspec_addressing(): + fig = plt.figure() + gs = fig.add_gridspec(3, 3) + sp = fig.add_subplot(gs[0:, 1:]) + fig.draw_without_rendering() + + +def test_discouraged_api(): + fig, ax = plt.subplots(constrained_layout=True) + fig.draw_without_rendering() + + with pytest.warns(PendingDeprecationWarning, + match="will be deprecated"): + fig, ax = plt.subplots() + fig.set_constrained_layout(True) + fig.draw_without_rendering() + + with pytest.warns(PendingDeprecationWarning, + match="will be deprecated"): + fig, ax = plt.subplots() + fig.set_constrained_layout({'w_pad': 0.02, 'h_pad': 0.02}) + fig.draw_without_rendering() + + +def test_kwargs(): + fig, ax = plt.subplots(constrained_layout={'h_pad': 0.02}) + fig.draw_without_rendering() + + +def test_rect(): + fig, ax = plt.subplots(layout='constrained') + fig.get_layout_engine().set(rect=[0, 0, 0.5, 0.5]) + fig.draw_without_rendering() + ppos = ax.get_position() + assert ppos.x1 < 0.5 + assert ppos.y1 < 0.5 + + fig, ax = plt.subplots(layout='constrained') + fig.get_layout_engine().set(rect=[0.2, 0.2, 0.3, 0.3]) + fig.draw_without_rendering() + ppos = ax.get_position() + assert ppos.x1 < 0.5 + assert ppos.y1 < 0.5 + assert ppos.x0 > 0.2 + assert ppos.y0 > 0.2 + + +def test_compressed1(): + fig, axs = plt.subplots(3, 2, layout='compressed', + sharex=True, sharey=True) + for ax in axs.flat: + pc = ax.imshow(np.random.randn(20, 20)) + + fig.colorbar(pc, ax=axs) + fig.draw_without_rendering() + + pos = axs[0, 0].get_position() + np.testing.assert_allclose(pos.x0, 0.2344, atol=1e-3) + pos = axs[0, 1].get_position() + np.testing.assert_allclose(pos.x1, 0.7024, atol=1e-3) + + # wider than tall + fig, axs = plt.subplots(2, 3, layout='compressed', + sharex=True, sharey=True, figsize=(5, 4)) + for ax in axs.flat: + pc = ax.imshow(np.random.randn(20, 20)) + + fig.colorbar(pc, ax=axs) + fig.draw_without_rendering() + + pos = axs[0, 0].get_position() + np.testing.assert_allclose(pos.x0, 0.06195, atol=1e-3) + np.testing.assert_allclose(pos.y1, 0.8537, atol=1e-3) + pos = axs[1, 2].get_position() + np.testing.assert_allclose(pos.x1, 0.8618, atol=1e-3) + np.testing.assert_allclose(pos.y0, 0.1934, atol=1e-3) + + +@pytest.mark.parametrize('arg, state', [ + (True, True), + (False, False), + ({}, True), + ({'rect': None}, True) +]) +def test_set_constrained_layout(arg, state): + fig, ax = plt.subplots(constrained_layout=arg) + assert fig.get_constrained_layout() is state + + +def test_constrained_toggle(): + fig, ax = plt.subplots() + with pytest.warns(PendingDeprecationWarning): + fig.set_constrained_layout(True) + assert fig.get_constrained_layout() + fig.set_constrained_layout(False) + assert not fig.get_constrained_layout() + fig.set_constrained_layout(True) + assert fig.get_constrained_layout() + + +def test_layout_leak(): + # Make sure there aren't any cyclic references when using LayoutGrid + # GH #25853 + fig = plt.figure(constrained_layout=True, figsize=(10, 10)) + fig.add_subplot() + fig.draw_without_rendering() + plt.close("all") + del fig + gc.collect() + assert not any(isinstance(obj, mpl._layoutgrid.LayoutGrid) + for obj in gc.get_objects()) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_container.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_container.py new file mode 100644 index 00000000..1e4577c5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_container.py @@ -0,0 +1,37 @@ +import numpy as np +import matplotlib.pyplot as plt + + +def test_stem_remove(): + ax = plt.gca() + st = ax.stem([1, 2], [1, 2]) + st.remove() + + +def test_errorbar_remove(): + + # Regression test for a bug that caused remove to fail when using + # fmt='none' + + ax = plt.gca() + + eb = ax.errorbar([1], [1]) + eb.remove() + + eb = ax.errorbar([1], [1], xerr=1) + eb.remove() + + eb = ax.errorbar([1], [1], yerr=2) + eb.remove() + + eb = ax.errorbar([1], [1], xerr=[2], yerr=2) + eb.remove() + + eb = ax.errorbar([1], [1], fmt='none') + eb.remove() + + +def test_nonstring_label(): + # Test for #26824 + plt.bar(np.arange(10), np.random.rand(10), label=1) + plt.legend() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_contour.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_contour.py new file mode 100644 index 00000000..f79584be --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_contour.py @@ -0,0 +1,899 @@ +import datetime +import platform +import re +from unittest import mock + +import contourpy +import numpy as np +from numpy.testing import ( + assert_array_almost_equal, assert_array_almost_equal_nulp, assert_array_equal) +import matplotlib as mpl +from matplotlib import pyplot as plt, rc_context, ticker +from matplotlib.colors import LogNorm, same_color +import matplotlib.patches as mpatches +from matplotlib.testing.decorators import check_figures_equal, image_comparison +import pytest + + +# Helper to test the transition from ContourSets holding multiple Collections to being a +# single Collection; remove once the deprecated old layout expires. +def _maybe_split_collections(do_split): + if not do_split: + return + for fig in map(plt.figure, plt.get_fignums()): + for ax in fig.axes: + for coll in ax.collections: + if isinstance(coll, mpl.contour.ContourSet): + with pytest.warns(mpl._api.MatplotlibDeprecationWarning): + coll.collections + + +def test_contour_shape_1d_valid(): + + x = np.arange(10) + y = np.arange(9) + z = np.random.random((9, 10)) + + fig, ax = plt.subplots() + ax.contour(x, y, z) + + +def test_contour_shape_2d_valid(): + + x = np.arange(10) + y = np.arange(9) + xg, yg = np.meshgrid(x, y) + z = np.random.random((9, 10)) + + fig, ax = plt.subplots() + ax.contour(xg, yg, z) + + +@pytest.mark.parametrize("args, message", [ + ((np.arange(9), np.arange(9), np.empty((9, 10))), + 'Length of x (9) must match number of columns in z (10)'), + ((np.arange(10), np.arange(10), np.empty((9, 10))), + 'Length of y (10) must match number of rows in z (9)'), + ((np.empty((10, 10)), np.arange(10), np.empty((9, 10))), + 'Number of dimensions of x (2) and y (1) do not match'), + ((np.arange(10), np.empty((10, 10)), np.empty((9, 10))), + 'Number of dimensions of x (1) and y (2) do not match'), + ((np.empty((9, 9)), np.empty((9, 10)), np.empty((9, 10))), + 'Shapes of x (9, 9) and z (9, 10) do not match'), + ((np.empty((9, 10)), np.empty((9, 9)), np.empty((9, 10))), + 'Shapes of y (9, 9) and z (9, 10) do not match'), + ((np.empty((3, 3, 3)), np.empty((3, 3, 3)), np.empty((9, 10))), + 'Inputs x and y must be 1D or 2D, not 3D'), + ((np.empty((3, 3, 3)), np.empty((3, 3, 3)), np.empty((3, 3, 3))), + 'Input z must be 2D, not 3D'), + (([[0]],), # github issue 8197 + 'Input z must be at least a (2, 2) shaped array, but has shape (1, 1)'), + (([0], [0], [[0]]), + 'Input z must be at least a (2, 2) shaped array, but has shape (1, 1)'), +]) +def test_contour_shape_error(args, message): + fig, ax = plt.subplots() + with pytest.raises(TypeError, match=re.escape(message)): + ax.contour(*args) + + +def test_contour_no_valid_levels(): + fig, ax = plt.subplots() + # no warning for empty levels. + ax.contour(np.random.rand(9, 9), levels=[]) + # no warning if levels is given and is not within the range of z. + cs = ax.contour(np.arange(81).reshape((9, 9)), levels=[100]) + # ... and if fmt is given. + ax.clabel(cs, fmt={100: '%1.2f'}) + # no warning if z is uniform. + ax.contour(np.ones((9, 9))) + + +def test_contour_Nlevels(): + # A scalar levels arg or kwarg should trigger auto level generation. + # https://github.com/matplotlib/matplotlib/issues/11913 + z = np.arange(12).reshape((3, 4)) + fig, ax = plt.subplots() + cs1 = ax.contour(z, 5) + assert len(cs1.levels) > 1 + cs2 = ax.contour(z, levels=5) + assert (cs1.levels == cs2.levels).all() + + +@check_figures_equal(extensions=['png']) +def test_contour_set_paths(fig_test, fig_ref): + cs_test = fig_test.subplots().contour([[0, 1], [1, 2]]) + cs_ref = fig_ref.subplots().contour([[1, 0], [2, 1]]) + + cs_test.set_paths(cs_ref.get_paths()) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_manual_labels'], remove_text=True, style='mpl20', tol=0.26) +def test_contour_manual_labels(split_collections): + x, y = np.meshgrid(np.arange(0, 10), np.arange(0, 10)) + z = np.max(np.dstack([abs(x), abs(y)]), 2) + + plt.figure(figsize=(6, 2), dpi=200) + cs = plt.contour(x, y, z) + + _maybe_split_collections(split_collections) + + pts = np.array([(1.0, 3.0), (1.0, 4.4), (1.0, 6.0)]) + plt.clabel(cs, manual=pts) + pts = np.array([(2.0, 3.0), (2.0, 4.4), (2.0, 6.0)]) + plt.clabel(cs, manual=pts, fontsize='small', colors=('r', 'g')) + + +def test_contour_manual_moveto(): + x = np.linspace(-10, 10) + y = np.linspace(-10, 10) + + X, Y = np.meshgrid(x, y) + + Z = X**2 * 1 / Y**2 - 1 + + contours = plt.contour(X, Y, Z, levels=[0, 100]) + + # This point lies on the `MOVETO` line for the 100 contour + # but is actually closest to the 0 contour + point = (1.3, 1) + clabels = plt.clabel(contours, manual=[point]) + + # Ensure that the 0 contour was chosen, not the 100 contour + assert clabels[0].get_text() == "0" + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_disconnected_segments'], + remove_text=True, style='mpl20', extensions=['png']) +def test_contour_label_with_disconnected_segments(split_collections): + x, y = np.mgrid[-1:1:21j, -1:1:21j] + z = 1 / np.sqrt(0.01 + (x + 0.3) ** 2 + y ** 2) + z += 1 / np.sqrt(0.01 + (x - 0.3) ** 2 + y ** 2) + + plt.figure() + cs = plt.contour(x, y, z, levels=[7]) + + # Adding labels should invalidate the old style + _maybe_split_collections(split_collections) + + cs.clabel(manual=[(0.2, 0.1)]) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_manual_colors_and_levels.png'], remove_text=True) +def test_given_colors_levels_and_extends(split_collections): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + _, axs = plt.subplots(2, 4) + + data = np.arange(12).reshape(3, 4) + + colors = ['red', 'yellow', 'pink', 'blue', 'black'] + levels = [2, 4, 8, 10] + + for i, ax in enumerate(axs.flat): + filled = i % 2 == 0. + extend = ['neither', 'min', 'max', 'both'][i // 2] + + if filled: + # If filled, we have 3 colors with no extension, + # 4 colors with one extension, and 5 colors with both extensions + first_color = 1 if extend in ['max', 'neither'] else None + last_color = -1 if extend in ['min', 'neither'] else None + c = ax.contourf(data, colors=colors[first_color:last_color], + levels=levels, extend=extend) + else: + # If not filled, we have 4 levels and 4 colors + c = ax.contour(data, colors=colors[:-1], + levels=levels, extend=extend) + + plt.colorbar(c, ax=ax) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_log_locator.svg'], style='mpl20', remove_text=False) +def test_log_locator_levels(split_collections): + + fig, ax = plt.subplots() + + N = 100 + x = np.linspace(-3.0, 3.0, N) + y = np.linspace(-2.0, 2.0, N) + + X, Y = np.meshgrid(x, y) + + Z1 = np.exp(-X**2 - Y**2) + Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2) + data = Z1 + 50 * Z2 + + c = ax.contourf(data, locator=ticker.LogLocator()) + assert_array_almost_equal(c.levels, np.power(10.0, np.arange(-6, 3))) + cb = fig.colorbar(c, ax=ax) + assert_array_almost_equal(cb.ax.get_yticks(), c.levels) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_datetime_axis.png'], style='mpl20') +def test_contour_datetime_axis(split_collections): + fig = plt.figure() + fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15) + base = datetime.datetime(2013, 1, 1) + x = np.array([base + datetime.timedelta(days=d) for d in range(20)]) + y = np.arange(20) + z1, z2 = np.meshgrid(np.arange(20), np.arange(20)) + z = z1 * z2 + plt.subplot(221) + plt.contour(x, y, z) + plt.subplot(222) + plt.contourf(x, y, z) + x = np.repeat(x[np.newaxis], 20, axis=0) + y = np.repeat(y[:, np.newaxis], 20, axis=1) + plt.subplot(223) + plt.contour(x, y, z) + plt.subplot(224) + plt.contourf(x, y, z) + for ax in fig.get_axes(): + for label in ax.get_xticklabels(): + label.set_ha('right') + label.set_rotation(30) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_test_label_transforms.png'], + remove_text=True, style='mpl20', tol=1.1) +def test_labels(split_collections): + # Adapted from pylab_examples example code: contour_demo.py + # see issues #2475, #2843, and #2818 for explanation + delta = 0.025 + x = np.arange(-3.0, 3.0, delta) + y = np.arange(-2.0, 2.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi) + Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) / + (2 * np.pi * 0.5 * 1.5)) + + # difference of Gaussians + Z = 10.0 * (Z2 - Z1) + + fig, ax = plt.subplots(1, 1) + CS = ax.contour(X, Y, Z) + disp_units = [(216, 177), (359, 290), (521, 406)] + data_units = [(-2, .5), (0, -1.5), (2.8, 1)] + + # Adding labels should invalidate the old style + _maybe_split_collections(split_collections) + + CS.clabel() + + for x, y in data_units: + CS.add_label_near(x, y, inline=True, transform=None) + + for x, y in disp_units: + CS.add_label_near(x, y, inline=True, transform=False) + + _maybe_split_collections(split_collections) + + +def test_label_contour_start(): + # Set up data and figure/axes that result in automatic labelling adding the + # label to the start of a contour + + _, ax = plt.subplots(dpi=100) + lats = lons = np.linspace(-np.pi / 2, np.pi / 2, 50) + lons, lats = np.meshgrid(lons, lats) + wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons) + mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2) + data = wave + mean + + cs = ax.contour(lons, lats, data) + + with mock.patch.object( + cs, '_split_path_and_get_label_rotation', + wraps=cs._split_path_and_get_label_rotation) as mocked_splitter: + # Smoke test that we can add the labels + cs.clabel(fontsize=9) + + # Verify at least one label was added to the start of a contour. I.e. the + # splitting method was called with idx=0 at least once. + idxs = [cargs[0][1] for cargs in mocked_splitter.call_args_list] + assert 0 in idxs + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_corner_mask_False.png', 'contour_corner_mask_True.png'], + remove_text=True, tol=1.88) +def test_corner_mask(split_collections): + n = 60 + mask_level = 0.95 + noise_amp = 1.0 + np.random.seed([1]) + x, y = np.meshgrid(np.linspace(0, 2.0, n), np.linspace(0, 2.0, n)) + z = np.cos(7*x)*np.sin(8*y) + noise_amp*np.random.rand(n, n) + mask = np.random.rand(n, n) >= mask_level + z = np.ma.array(z, mask=mask) + + for corner_mask in [False, True]: + plt.figure() + plt.contourf(z, corner_mask=corner_mask) + + _maybe_split_collections(split_collections) + + +def test_contourf_decreasing_levels(): + # github issue 5477. + z = [[0.1, 0.3], [0.5, 0.7]] + plt.figure() + with pytest.raises(ValueError): + plt.contourf(z, [1.0, 0.0]) + + +def test_contourf_symmetric_locator(): + # github issue 7271 + z = np.arange(12).reshape((3, 4)) + locator = plt.MaxNLocator(nbins=4, symmetric=True) + cs = plt.contourf(z, locator=locator) + assert_array_almost_equal(cs.levels, np.linspace(-12, 12, 5)) + + +def test_circular_contour_warning(): + # Check that almost circular contours don't throw a warning + x, y = np.meshgrid(np.linspace(-2, 2, 4), np.linspace(-2, 2, 4)) + r = np.hypot(x, y) + plt.figure() + cs = plt.contour(x, y, r) + plt.clabel(cs) + + +@pytest.mark.parametrize("use_clabeltext, contour_zorder, clabel_zorder", + [(True, 123, 1234), (False, 123, 1234), + (True, 123, None), (False, 123, None)]) +def test_clabel_zorder(use_clabeltext, contour_zorder, clabel_zorder): + x, y = np.meshgrid(np.arange(0, 10), np.arange(0, 10)) + z = np.max(np.dstack([abs(x), abs(y)]), 2) + + fig, (ax1, ax2) = plt.subplots(ncols=2) + cs = ax1.contour(x, y, z, zorder=contour_zorder) + cs_filled = ax2.contourf(x, y, z, zorder=contour_zorder) + clabels1 = cs.clabel(zorder=clabel_zorder, use_clabeltext=use_clabeltext) + clabels2 = cs_filled.clabel(zorder=clabel_zorder, + use_clabeltext=use_clabeltext) + + if clabel_zorder is None: + expected_clabel_zorder = 2+contour_zorder + else: + expected_clabel_zorder = clabel_zorder + + for clabel in clabels1: + assert clabel.get_zorder() == expected_clabel_zorder + for clabel in clabels2: + assert clabel.get_zorder() == expected_clabel_zorder + + +def test_clabel_with_large_spacing(): + # When the inline spacing is large relative to the contour, it may cause the + # entire contour to be removed. In current implementation, one line segment is + # retained between the identified points. + # This behavior may be worth reconsidering, but check to be sure we do not produce + # an invalid path, which results in an error at clabel call time. + # see gh-27045 for more information + x = y = np.arange(-3.0, 3.01, 0.05) + X, Y = np.meshgrid(x, y) + Z = np.exp(-X**2 - Y**2) + + fig, ax = plt.subplots() + contourset = ax.contour(X, Y, Z, levels=[0.01, 0.2, .5, .8]) + ax.clabel(contourset, inline_spacing=100) + + +# tol because ticks happen to fall on pixel boundaries so small +# floating point changes in tick location flip which pixel gets +# the tick. +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(['contour_log_extension.png'], + remove_text=True, style='mpl20', + tol=1.444) +def test_contourf_log_extension(split_collections): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + # Test that contourf with lognorm is extended correctly + fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(10, 5)) + fig.subplots_adjust(left=0.05, right=0.95) + + # make data set with large range e.g. between 1e-8 and 1e10 + data_exp = np.linspace(-7.5, 9.5, 1200) + data = np.power(10, data_exp).reshape(30, 40) + # make manual levels e.g. between 1e-4 and 1e-6 + levels_exp = np.arange(-4., 7.) + levels = np.power(10., levels_exp) + + # original data + c1 = ax1.contourf(data, + norm=LogNorm(vmin=data.min(), vmax=data.max())) + # just show data in levels + c2 = ax2.contourf(data, levels=levels, + norm=LogNorm(vmin=levels.min(), vmax=levels.max()), + extend='neither') + # extend data from levels + c3 = ax3.contourf(data, levels=levels, + norm=LogNorm(vmin=levels.min(), vmax=levels.max()), + extend='both') + cb = plt.colorbar(c1, ax=ax1) + assert cb.ax.get_ylim() == (1e-8, 1e10) + cb = plt.colorbar(c2, ax=ax2) + assert_array_almost_equal_nulp(cb.ax.get_ylim(), np.array((1e-4, 1e6))) + cb = plt.colorbar(c3, ax=ax3) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison( + ['contour_addlines.png'], remove_text=True, style='mpl20', + tol=0.15 if platform.machine() in ('aarch64', 'ppc64le', 's390x') + else 0.03) +# tolerance is because image changed minutely when tick finding on +# colorbars was cleaned up... +def test_contour_addlines(split_collections): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig, ax = plt.subplots() + np.random.seed(19680812) + X = np.random.rand(10, 10)*10000 + pcm = ax.pcolormesh(X) + # add 1000 to make colors visible... + cont = ax.contour(X+1000) + cb = fig.colorbar(pcm) + cb.add_lines(cont) + assert_array_almost_equal(cb.ax.get_ylim(), [114.3091, 9972.30735], 3) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(baseline_images=['contour_uneven'], + extensions=['png'], remove_text=True, style='mpl20') +def test_contour_uneven(split_collections): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + z = np.arange(24).reshape(4, 6) + fig, axs = plt.subplots(1, 2) + ax = axs[0] + cs = ax.contourf(z, levels=[2, 4, 6, 10, 20]) + fig.colorbar(cs, ax=ax, spacing='proportional') + ax = axs[1] + cs = ax.contourf(z, levels=[2, 4, 6, 10, 20]) + fig.colorbar(cs, ax=ax, spacing='uniform') + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize( + "rc_lines_linewidth, rc_contour_linewidth, call_linewidths, expected", [ + (1.23, None, None, 1.23), + (1.23, 4.24, None, 4.24), + (1.23, 4.24, 5.02, 5.02) + ]) +def test_contour_linewidth( + rc_lines_linewidth, rc_contour_linewidth, call_linewidths, expected): + + with rc_context(rc={"lines.linewidth": rc_lines_linewidth, + "contour.linewidth": rc_contour_linewidth}): + fig, ax = plt.subplots() + X = np.arange(4*3).reshape(4, 3) + cs = ax.contour(X, linewidths=call_linewidths) + assert cs.get_linewidths()[0] == expected + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="tlinewidths"): + assert cs.tlinewidths[0][0] == expected + + +@pytest.mark.backend("pdf") +def test_label_nonagg(): + # This should not crash even if the canvas doesn't have a get_renderer(). + plt.clabel(plt.contour([[1, 2], [3, 4]])) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(baseline_images=['contour_closed_line_loop'], + extensions=['png'], remove_text=True) +def test_contour_closed_line_loop(split_collections): + # github issue 19568. + z = [[0, 0, 0], [0, 2, 0], [0, 0, 0], [2, 1, 2]] + + fig, ax = plt.subplots(figsize=(2, 2)) + ax.contour(z, [0.5], linewidths=[20], alpha=0.7) + ax.set_xlim(-0.1, 2.1) + ax.set_ylim(-0.1, 3.1) + + _maybe_split_collections(split_collections) + + +def test_quadcontourset_reuse(): + # If QuadContourSet returned from one contour(f) call is passed as first + # argument to another the underlying C++ contour generator will be reused. + x, y = np.meshgrid([0.0, 1.0], [0.0, 1.0]) + z = x + y + fig, ax = plt.subplots() + qcs1 = ax.contourf(x, y, z) + qcs2 = ax.contour(x, y, z) + assert qcs2._contour_generator != qcs1._contour_generator + qcs3 = ax.contour(qcs1, z) + assert qcs3._contour_generator == qcs1._contour_generator + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(baseline_images=['contour_manual'], + extensions=['png'], remove_text=True, tol=0.89) +def test_contour_manual(split_collections): + # Manually specifying contour lines/polygons to plot. + from matplotlib.contour import ContourSet + + fig, ax = plt.subplots(figsize=(4, 4)) + cmap = 'viridis' + + # Segments only (no 'kind' codes). + lines0 = [[[2, 0], [1, 2], [1, 3]]] # Single line. + lines1 = [[[3, 0], [3, 2]], [[3, 3], [3, 4]]] # Two lines. + filled01 = [[[0, 0], [0, 4], [1, 3], [1, 2], [2, 0]]] + filled12 = [[[2, 0], [3, 0], [3, 2], [1, 3], [1, 2]], # Two polygons. + [[1, 4], [3, 4], [3, 3]]] + ContourSet(ax, [0, 1, 2], [filled01, filled12], filled=True, cmap=cmap) + ContourSet(ax, [1, 2], [lines0, lines1], linewidths=3, colors=['r', 'k']) + + # Segments and kind codes (1 = MOVETO, 2 = LINETO, 79 = CLOSEPOLY). + segs = [[[4, 0], [7, 0], [7, 3], [4, 3], [4, 0], + [5, 1], [5, 2], [6, 2], [6, 1], [5, 1]]] + kinds = [[1, 2, 2, 2, 79, 1, 2, 2, 2, 79]] # Polygon containing hole. + ContourSet(ax, [2, 3], [segs], [kinds], filled=True, cmap=cmap) + ContourSet(ax, [2], [segs], [kinds], colors='k', linewidths=3) + + _maybe_split_collections(split_collections) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(baseline_images=['contour_line_start_on_corner_edge'], + extensions=['png'], remove_text=True) +def test_contour_line_start_on_corner_edge(split_collections): + fig, ax = plt.subplots(figsize=(6, 5)) + + x, y = np.meshgrid([0, 1, 2, 3, 4], [0, 1, 2]) + z = 1.2 - (x - 2)**2 + (y - 1)**2 + mask = np.zeros_like(z, dtype=bool) + mask[1, 1] = mask[1, 3] = True + z = np.ma.array(z, mask=mask) + + filled = ax.contourf(x, y, z, corner_mask=True) + cbar = fig.colorbar(filled) + lines = ax.contour(x, y, z, corner_mask=True, colors='k') + cbar.add_lines(lines) + + _maybe_split_collections(split_collections) + + +def test_find_nearest_contour(): + xy = np.indices((15, 15)) + img = np.exp(-np.pi * (np.sum((xy - 5)**2, 0)/5.**2)) + cs = plt.contour(img, 10) + + nearest_contour = cs.find_nearest_contour(1, 1, pixel=False) + expected_nearest = (1, 0, 33, 1.965966, 1.965966, 1.866183) + assert_array_almost_equal(nearest_contour, expected_nearest) + + nearest_contour = cs.find_nearest_contour(8, 1, pixel=False) + expected_nearest = (1, 0, 5, 7.550173, 1.587542, 0.547550) + assert_array_almost_equal(nearest_contour, expected_nearest) + + nearest_contour = cs.find_nearest_contour(2, 5, pixel=False) + expected_nearest = (3, 0, 21, 1.884384, 5.023335, 0.013911) + assert_array_almost_equal(nearest_contour, expected_nearest) + + nearest_contour = cs.find_nearest_contour(2, 5, indices=(5, 7), pixel=False) + expected_nearest = (5, 0, 16, 2.628202, 5.0, 0.394638) + assert_array_almost_equal(nearest_contour, expected_nearest) + + +def test_find_nearest_contour_no_filled(): + xy = np.indices((15, 15)) + img = np.exp(-np.pi * (np.sum((xy - 5)**2, 0)/5.**2)) + cs = plt.contourf(img, 10) + + with pytest.raises(ValueError, match="Method does not support filled contours"): + cs.find_nearest_contour(1, 1, pixel=False) + + with pytest.raises(ValueError, match="Method does not support filled contours"): + cs.find_nearest_contour(1, 10, indices=(5, 7), pixel=False) + + with pytest.raises(ValueError, match="Method does not support filled contours"): + cs.find_nearest_contour(2, 5, indices=(2, 7), pixel=True) + + +@mpl.style.context("default") +def test_contour_autolabel_beyond_powerlimits(): + ax = plt.figure().add_subplot() + cs = plt.contour(np.geomspace(1e-6, 1e-4, 100).reshape(10, 10), + levels=[.25e-5, 1e-5, 4e-5]) + ax.clabel(cs) + # Currently, the exponent is missing, but that may be fixed in the future. + assert {text.get_text() for text in ax.texts} == {"0.25", "1.00", "4.00"} + + +def test_contourf_legend_elements(): + from matplotlib.patches import Rectangle + x = np.arange(1, 10) + y = x.reshape(-1, 1) + h = x * y + + cs = plt.contourf(h, levels=[10, 30, 50], + colors=['#FFFF00', '#FF00FF', '#00FFFF'], + extend='both') + cs.cmap.set_over('red') + cs.cmap.set_under('blue') + cs.changed() + artists, labels = cs.legend_elements() + assert labels == ['$x \\leq -1e+250s$', + '$10.0 < x \\leq 30.0$', + '$30.0 < x \\leq 50.0$', + '$x > 1e+250s$'] + expected_colors = ('blue', '#FFFF00', '#FF00FF', 'red') + assert all(isinstance(a, Rectangle) for a in artists) + assert all(same_color(a.get_facecolor(), c) + for a, c in zip(artists, expected_colors)) + + +def test_contour_legend_elements(): + x = np.arange(1, 10) + y = x.reshape(-1, 1) + h = x * y + + colors = ['blue', '#00FF00', 'red'] + cs = plt.contour(h, levels=[10, 30, 50], + colors=colors, + extend='both') + artists, labels = cs.legend_elements() + assert labels == ['$x = 10.0$', '$x = 30.0$', '$x = 50.0$'] + assert all(isinstance(a, mpl.lines.Line2D) for a in artists) + assert all(same_color(a.get_color(), c) + for a, c in zip(artists, colors)) + + +@pytest.mark.parametrize( + "algorithm, klass", + [('mpl2005', contourpy.Mpl2005ContourGenerator), + ('mpl2014', contourpy.Mpl2014ContourGenerator), + ('serial', contourpy.SerialContourGenerator), + ('threaded', contourpy.ThreadedContourGenerator), + ('invalid', None)]) +def test_algorithm_name(algorithm, klass): + z = np.array([[1.0, 2.0], [3.0, 4.0]]) + if klass is not None: + cs = plt.contourf(z, algorithm=algorithm) + assert isinstance(cs._contour_generator, klass) + else: + with pytest.raises(ValueError): + plt.contourf(z, algorithm=algorithm) + + +@pytest.mark.parametrize( + "algorithm", ['mpl2005', 'mpl2014', 'serial', 'threaded']) +def test_algorithm_supports_corner_mask(algorithm): + z = np.array([[1.0, 2.0], [3.0, 4.0]]) + + # All algorithms support corner_mask=False + plt.contourf(z, algorithm=algorithm, corner_mask=False) + + # Only some algorithms support corner_mask=True + if algorithm != 'mpl2005': + plt.contourf(z, algorithm=algorithm, corner_mask=True) + else: + with pytest.raises(ValueError): + plt.contourf(z, algorithm=algorithm, corner_mask=True) + + +@pytest.mark.parametrize("split_collections", [False, True]) +@image_comparison(baseline_images=['contour_all_algorithms'], + extensions=['png'], remove_text=True, tol=0.06) +def test_all_algorithms(split_collections): + algorithms = ['mpl2005', 'mpl2014', 'serial', 'threaded'] + + rng = np.random.default_rng(2981) + x, y = np.meshgrid(np.linspace(0.0, 1.0, 10), np.linspace(0.0, 1.0, 6)) + z = np.sin(15*x)*np.cos(10*y) + rng.normal(scale=0.5, size=(6, 10)) + mask = np.zeros_like(z, dtype=bool) + mask[3, 7] = True + z = np.ma.array(z, mask=mask) + + _, axs = plt.subplots(2, 2) + for ax, algorithm in zip(axs.ravel(), algorithms): + ax.contourf(x, y, z, algorithm=algorithm) + ax.contour(x, y, z, algorithm=algorithm, colors='k') + ax.set_title(algorithm) + + _maybe_split_collections(split_collections) + + +def test_subfigure_clabel(): + # Smoke test for gh#23173 + delta = 0.025 + x = np.arange(-3.0, 3.0, delta) + y = np.arange(-2.0, 2.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-(X**2) - Y**2) + Z2 = np.exp(-((X - 1) ** 2) - (Y - 1) ** 2) + Z = (Z1 - Z2) * 2 + + fig = plt.figure() + figs = fig.subfigures(nrows=1, ncols=2) + + for f in figs: + ax = f.subplots() + CS = ax.contour(X, Y, Z) + ax.clabel(CS, inline=True, fontsize=10) + ax.set_title("Simplest default with labels") + + +@pytest.mark.parametrize( + "style", ['solid', 'dashed', 'dashdot', 'dotted']) +def test_linestyles(style): + delta = 0.025 + x = np.arange(-3.0, 3.0, delta) + y = np.arange(-2.0, 2.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-X**2 - Y**2) + Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) + Z = (Z1 - Z2) * 2 + + # Positive contour defaults to solid + fig1, ax1 = plt.subplots() + CS1 = ax1.contour(X, Y, Z, 6, colors='k') + ax1.clabel(CS1, fontsize=9, inline=True) + ax1.set_title('Single color - positive contours solid (default)') + assert CS1.linestyles is None # default + + # Change linestyles using linestyles kwarg + fig2, ax2 = plt.subplots() + CS2 = ax2.contour(X, Y, Z, 6, colors='k', linestyles=style) + ax2.clabel(CS2, fontsize=9, inline=True) + ax2.set_title(f'Single color - positive contours {style}') + assert CS2.linestyles == style + + # Ensure linestyles do not change when negative_linestyles is defined + fig3, ax3 = plt.subplots() + CS3 = ax3.contour(X, Y, Z, 6, colors='k', linestyles=style, + negative_linestyles='dashdot') + ax3.clabel(CS3, fontsize=9, inline=True) + ax3.set_title(f'Single color - positive contours {style}') + assert CS3.linestyles == style + + +@pytest.mark.parametrize( + "style", ['solid', 'dashed', 'dashdot', 'dotted']) +def test_negative_linestyles(style): + delta = 0.025 + x = np.arange(-3.0, 3.0, delta) + y = np.arange(-2.0, 2.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-X**2 - Y**2) + Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) + Z = (Z1 - Z2) * 2 + + # Negative contour defaults to dashed + fig1, ax1 = plt.subplots() + CS1 = ax1.contour(X, Y, Z, 6, colors='k') + ax1.clabel(CS1, fontsize=9, inline=True) + ax1.set_title('Single color - negative contours dashed (default)') + assert CS1.negative_linestyles == 'dashed' # default + + # Change negative_linestyles using rcParams + plt.rcParams['contour.negative_linestyle'] = style + fig2, ax2 = plt.subplots() + CS2 = ax2.contour(X, Y, Z, 6, colors='k') + ax2.clabel(CS2, fontsize=9, inline=True) + ax2.set_title(f'Single color - negative contours {style}' + '(using rcParams)') + assert CS2.negative_linestyles == style + + # Change negative_linestyles using negative_linestyles kwarg + fig3, ax3 = plt.subplots() + CS3 = ax3.contour(X, Y, Z, 6, colors='k', negative_linestyles=style) + ax3.clabel(CS3, fontsize=9, inline=True) + ax3.set_title(f'Single color - negative contours {style}') + assert CS3.negative_linestyles == style + + # Ensure negative_linestyles do not change when linestyles is defined + fig4, ax4 = plt.subplots() + CS4 = ax4.contour(X, Y, Z, 6, colors='k', linestyles='dashdot', + negative_linestyles=style) + ax4.clabel(CS4, fontsize=9, inline=True) + ax4.set_title(f'Single color - negative contours {style}') + assert CS4.negative_linestyles == style + + +def test_contour_remove(): + ax = plt.figure().add_subplot() + orig_children = ax.get_children() + cs = ax.contour(np.arange(16).reshape((4, 4))) + cs.clabel() + assert ax.get_children() != orig_children + cs.remove() + assert ax.get_children() == orig_children + + +def test_contour_no_args(): + fig, ax = plt.subplots() + data = [[0, 1], [1, 0]] + with pytest.raises(TypeError, match=r"contour\(\) takes from 1 to 4"): + ax.contour(Z=data) + + +def test_contour_clip_path(): + fig, ax = plt.subplots() + data = [[0, 1], [1, 0]] + circle = mpatches.Circle([0.5, 0.5], 0.5, transform=ax.transAxes) + cs = ax.contour(data, clip_path=circle) + assert cs.get_clip_path() is not None + + +def test_bool_autolevel(): + x, y = np.random.rand(2, 9) + z = (np.arange(9) % 2).reshape((3, 3)).astype(bool) + m = [[False, False, False], [False, True, False], [False, False, False]] + assert plt.contour(z.tolist()).levels.tolist() == [.5] + assert plt.contour(z).levels.tolist() == [.5] + assert plt.contour(np.ma.array(z, mask=m)).levels.tolist() == [.5] + assert plt.contourf(z.tolist()).levels.tolist() == [0, .5, 1] + assert plt.contourf(z).levels.tolist() == [0, .5, 1] + assert plt.contourf(np.ma.array(z, mask=m)).levels.tolist() == [0, .5, 1] + z = z.ravel() + assert plt.tricontour(x, y, z.tolist()).levels.tolist() == [.5] + assert plt.tricontour(x, y, z).levels.tolist() == [.5] + assert plt.tricontourf(x, y, z.tolist()).levels.tolist() == [0, .5, 1] + assert plt.tricontourf(x, y, z).levels.tolist() == [0, .5, 1] + + +def test_all_nan(): + x = np.array([[np.nan, np.nan], [np.nan, np.nan]]) + assert_array_almost_equal(plt.contour(x).levels, + [-1e-13, -7.5e-14, -5e-14, -2.4e-14, 0.0, + 2.4e-14, 5e-14, 7.5e-14, 1e-13]) + + +def test_allsegs_allkinds(): + x, y = np.meshgrid(np.arange(0, 10, 2), np.arange(0, 10, 2)) + z = np.sin(x) * np.cos(y) + + cs = plt.contour(x, y, z, levels=[0, 0.5]) + + # Expect two levels, the first with 5 segments and the second with 4. + for result in [cs.allsegs, cs.allkinds]: + assert len(result) == 2 + assert len(result[0]) == 5 + assert len(result[1]) == 4 + + +def test_deprecated_apis(): + cs = plt.contour(np.arange(16).reshape((4, 4))) + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="collections"): + colls = cs.collections + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="tcolors"): + assert_array_equal(cs.tcolors, [c.get_edgecolor() for c in colls]) + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="tlinewidths"): + assert cs.tlinewidths == [c.get_linewidth() for c in colls] + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="antialiased"): + assert cs.antialiased + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="antialiased"): + cs.antialiased = False + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="antialiased"): + assert not cs.antialiased diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cycles.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cycles.py new file mode 100644 index 00000000..9bbb9bc9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_cycles.py @@ -0,0 +1,170 @@ +import contextlib +from io import StringIO + +import matplotlib as mpl +import matplotlib.pyplot as plt +import numpy as np +import pytest + +from cycler import cycler + + +def test_colorcycle_basic(): + fig, ax = plt.subplots() + ax.set_prop_cycle(cycler('color', ['r', 'g', 'y'])) + for _ in range(4): + ax.plot(range(10), range(10)) + assert [l.get_color() for l in ax.lines] == ['r', 'g', 'y', 'r'] + + +def test_marker_cycle(): + fig, ax = plt.subplots() + ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) + + cycler('marker', ['.', '*', 'x'])) + for _ in range(4): + ax.plot(range(10), range(10)) + assert [l.get_color() for l in ax.lines] == ['r', 'g', 'y', 'r'] + assert [l.get_marker() for l in ax.lines] == ['.', '*', 'x', '.'] + + +def test_marker_cycle_kwargs_arrays_iterators(): + fig, ax = plt.subplots() + ax.set_prop_cycle(c=np.array(['r', 'g', 'y']), + marker=iter(['.', '*', 'x'])) + for _ in range(4): + ax.plot(range(10), range(10)) + assert [l.get_color() for l in ax.lines] == ['r', 'g', 'y', 'r'] + assert [l.get_marker() for l in ax.lines] == ['.', '*', 'x', '.'] + + +def test_linestylecycle_basic(): + fig, ax = plt.subplots() + ax.set_prop_cycle(cycler('ls', ['-', '--', ':'])) + for _ in range(4): + ax.plot(range(10), range(10)) + assert [l.get_linestyle() for l in ax.lines] == ['-', '--', ':', '-'] + + +def test_fillcycle_basic(): + fig, ax = plt.subplots() + ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) + + cycler('hatch', ['xx', 'O', '|-']) + + cycler('linestyle', ['-', '--', ':'])) + for _ in range(4): + ax.fill(range(10), range(10)) + assert ([p.get_facecolor() for p in ax.patches] + == [mpl.colors.to_rgba(c) for c in ['r', 'g', 'y', 'r']]) + assert [p.get_hatch() for p in ax.patches] == ['xx', 'O', '|-', 'xx'] + assert [p.get_linestyle() for p in ax.patches] == ['-', '--', ':', '-'] + + +def test_fillcycle_ignore(): + fig, ax = plt.subplots() + ax.set_prop_cycle(cycler('color', ['r', 'g', 'y']) + + cycler('hatch', ['xx', 'O', '|-']) + + cycler('marker', ['.', '*', 'D'])) + t = range(10) + # Should not advance the cycler, even though there is an + # unspecified property in the cycler "marker". + # "marker" is not a Polygon property, and should be ignored. + ax.fill(t, t, 'r', hatch='xx') + # Allow the cycler to advance, but specify some properties + ax.fill(t, t, hatch='O') + ax.fill(t, t) + ax.fill(t, t) + assert ([p.get_facecolor() for p in ax.patches] + == [mpl.colors.to_rgba(c) for c in ['r', 'r', 'g', 'y']]) + assert [p.get_hatch() for p in ax.patches] == ['xx', 'O', 'O', '|-'] + + +def test_property_collision_plot(): + fig, ax = plt.subplots() + ax.set_prop_cycle('linewidth', [2, 4]) + t = range(10) + for c in range(1, 4): + ax.plot(t, t, lw=0.1) + ax.plot(t, t) + ax.plot(t, t) + assert [l.get_linewidth() for l in ax.lines] == [0.1, 0.1, 0.1, 2, 4] + + +def test_property_collision_fill(): + fig, ax = plt.subplots() + ax.set_prop_cycle(linewidth=[2, 3, 4, 5, 6], facecolor='bgcmy') + t = range(10) + for c in range(1, 4): + ax.fill(t, t, lw=0.1) + ax.fill(t, t) + ax.fill(t, t) + assert ([p.get_facecolor() for p in ax.patches] + == [mpl.colors.to_rgba(c) for c in 'bgcmy']) + assert [p.get_linewidth() for p in ax.patches] == [0.1, 0.1, 0.1, 5, 6] + + +def test_valid_input_forms(): + fig, ax = plt.subplots() + # These should not raise an error. + ax.set_prop_cycle(None) + ax.set_prop_cycle(cycler('linewidth', [1, 2])) + ax.set_prop_cycle('color', 'rgywkbcm') + ax.set_prop_cycle('lw', (1, 2)) + ax.set_prop_cycle('linewidth', [1, 2]) + ax.set_prop_cycle('linewidth', iter([1, 2])) + ax.set_prop_cycle('linewidth', np.array([1, 2])) + ax.set_prop_cycle('color', np.array([[1, 0, 0], + [0, 1, 0], + [0, 0, 1]])) + ax.set_prop_cycle('dashes', [[], [13, 2], [8, 3, 1, 3]]) + ax.set_prop_cycle(lw=[1, 2], color=['k', 'w'], ls=['-', '--']) + ax.set_prop_cycle(lw=np.array([1, 2]), + color=np.array(['k', 'w']), + ls=np.array(['-', '--'])) + + +def test_cycle_reset(): + fig, ax = plt.subplots() + prop0 = StringIO() + prop1 = StringIO() + prop2 = StringIO() + + with contextlib.redirect_stdout(prop0): + plt.getp(ax.plot([1, 2], label="label")[0]) + + ax.set_prop_cycle(linewidth=[10, 9, 4]) + with contextlib.redirect_stdout(prop1): + plt.getp(ax.plot([1, 2], label="label")[0]) + assert prop1.getvalue() != prop0.getvalue() + + ax.set_prop_cycle(None) + with contextlib.redirect_stdout(prop2): + plt.getp(ax.plot([1, 2], label="label")[0]) + assert prop2.getvalue() == prop0.getvalue() + + +def test_invalid_input_forms(): + fig, ax = plt.subplots() + + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle(1) + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle([1, 2]) + + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle('color', 'fish') + + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle('linewidth', 1) + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle('linewidth', {1, 2}) + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle(linewidth=1, color='r') + + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle('foobar', [1, 2]) + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle(foobar=[1, 2]) + + with pytest.raises((TypeError, ValueError)): + ax.set_prop_cycle(cycler(foobar=[1, 2])) + with pytest.raises(ValueError): + ax.set_prop_cycle(cycler(color='rgb', c='cmy')) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dates.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dates.py new file mode 100644 index 00000000..8995b9b3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dates.py @@ -0,0 +1,1411 @@ +import datetime + +import dateutil.tz +import dateutil.rrule +import functools +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import rc_context, style +import matplotlib.dates as mdates +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison +import matplotlib.ticker as mticker + + +def test_date_numpyx(): + # test that numpy dates work properly... + base = datetime.datetime(2017, 1, 1) + time = [base + datetime.timedelta(days=x) for x in range(0, 3)] + timenp = np.array(time, dtype='datetime64[ns]') + data = np.array([0., 2., 1.]) + fig = plt.figure(figsize=(10, 2)) + ax = fig.add_subplot(1, 1, 1) + h, = ax.plot(time, data) + hnp, = ax.plot(timenp, data) + np.testing.assert_equal(h.get_xdata(orig=False), hnp.get_xdata(orig=False)) + fig = plt.figure(figsize=(10, 2)) + ax = fig.add_subplot(1, 1, 1) + h, = ax.plot(data, time) + hnp, = ax.plot(data, timenp) + np.testing.assert_equal(h.get_ydata(orig=False), hnp.get_ydata(orig=False)) + + +@pytest.mark.parametrize('t0', [datetime.datetime(2017, 1, 1, 0, 1, 1), + + [datetime.datetime(2017, 1, 1, 0, 1, 1), + datetime.datetime(2017, 1, 1, 1, 1, 1)], + + [[datetime.datetime(2017, 1, 1, 0, 1, 1), + datetime.datetime(2017, 1, 1, 1, 1, 1)], + [datetime.datetime(2017, 1, 1, 2, 1, 1), + datetime.datetime(2017, 1, 1, 3, 1, 1)]]]) +@pytest.mark.parametrize('dtype', ['datetime64[s]', + 'datetime64[us]', + 'datetime64[ms]', + 'datetime64[ns]']) +def test_date_date2num_numpy(t0, dtype): + time = mdates.date2num(t0) + tnp = np.array(t0, dtype=dtype) + nptime = mdates.date2num(tnp) + np.testing.assert_equal(time, nptime) + + +@pytest.mark.parametrize('dtype', ['datetime64[s]', + 'datetime64[us]', + 'datetime64[ms]', + 'datetime64[ns]']) +def test_date2num_NaT(dtype): + t0 = datetime.datetime(2017, 1, 1, 0, 1, 1) + tmpl = [mdates.date2num(t0), np.nan] + tnp = np.array([t0, 'NaT'], dtype=dtype) + nptime = mdates.date2num(tnp) + np.testing.assert_array_equal(tmpl, nptime) + + +@pytest.mark.parametrize('units', ['s', 'ms', 'us', 'ns']) +def test_date2num_NaT_scalar(units): + tmpl = mdates.date2num(np.datetime64('NaT', units)) + assert np.isnan(tmpl) + + +def test_date2num_masked(): + # Without tzinfo + base = datetime.datetime(2022, 12, 15) + dates = np.ma.array([base + datetime.timedelta(days=(2 * i)) + for i in range(7)], mask=[0, 1, 1, 0, 0, 0, 1]) + npdates = mdates.date2num(dates) + np.testing.assert_array_equal(np.ma.getmask(npdates), + (False, True, True, False, False, False, + True)) + + # With tzinfo + base = datetime.datetime(2022, 12, 15, tzinfo=mdates.UTC) + dates = np.ma.array([base + datetime.timedelta(days=(2 * i)) + for i in range(7)], mask=[0, 1, 1, 0, 0, 0, 1]) + npdates = mdates.date2num(dates) + np.testing.assert_array_equal(np.ma.getmask(npdates), + (False, True, True, False, False, False, + True)) + + +def test_date_empty(): + # make sure we do the right thing when told to plot dates even + # if no date data has been presented, cf + # http://sourceforge.net/tracker/?func=detail&aid=2850075&group_id=80706&atid=560720 + fig, ax = plt.subplots() + ax.xaxis_date() + fig.draw_without_rendering() + np.testing.assert_allclose(ax.get_xlim(), + [mdates.date2num(np.datetime64('1970-01-01')), + mdates.date2num(np.datetime64('1970-01-02'))]) + + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + fig, ax = plt.subplots() + ax.xaxis_date() + fig.draw_without_rendering() + np.testing.assert_allclose(ax.get_xlim(), + [mdates.date2num(np.datetime64('1970-01-01')), + mdates.date2num(np.datetime64('1970-01-02'))]) + mdates._reset_epoch_test_example() + + +def test_date_not_empty(): + fig = plt.figure() + ax = fig.add_subplot() + + ax.plot([50, 70], [1, 2]) + ax.xaxis.axis_date() + np.testing.assert_allclose(ax.get_xlim(), [50, 70]) + + +def test_axhline(): + # make sure that axhline doesn't set the xlimits... + fig, ax = plt.subplots() + ax.axhline(1.5) + ax.plot([np.datetime64('2016-01-01'), np.datetime64('2016-01-02')], [1, 2]) + np.testing.assert_allclose(ax.get_xlim(), + [mdates.date2num(np.datetime64('2016-01-01')), + mdates.date2num(np.datetime64('2016-01-02'))]) + + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + fig, ax = plt.subplots() + ax.axhline(1.5) + ax.plot([np.datetime64('2016-01-01'), np.datetime64('2016-01-02')], [1, 2]) + np.testing.assert_allclose(ax.get_xlim(), + [mdates.date2num(np.datetime64('2016-01-01')), + mdates.date2num(np.datetime64('2016-01-02'))]) + mdates._reset_epoch_test_example() + + +@image_comparison(['date_axhspan.png']) +def test_date_axhspan(): + # test axhspan with date inputs + t0 = datetime.datetime(2009, 1, 20) + tf = datetime.datetime(2009, 1, 21) + fig, ax = plt.subplots() + ax.axhspan(t0, tf, facecolor="blue", alpha=0.25) + ax.set_ylim(t0 - datetime.timedelta(days=5), + tf + datetime.timedelta(days=5)) + fig.subplots_adjust(left=0.25) + + +@image_comparison(['date_axvspan.png']) +def test_date_axvspan(): + # test axvspan with date inputs + t0 = datetime.datetime(2000, 1, 20) + tf = datetime.datetime(2010, 1, 21) + fig, ax = plt.subplots() + ax.axvspan(t0, tf, facecolor="blue", alpha=0.25) + ax.set_xlim(t0 - datetime.timedelta(days=720), + tf + datetime.timedelta(days=720)) + fig.autofmt_xdate() + + +@image_comparison(['date_axhline.png']) +def test_date_axhline(): + # test axhline with date inputs + t0 = datetime.datetime(2009, 1, 20) + tf = datetime.datetime(2009, 1, 31) + fig, ax = plt.subplots() + ax.axhline(t0, color="blue", lw=3) + ax.set_ylim(t0 - datetime.timedelta(days=5), + tf + datetime.timedelta(days=5)) + fig.subplots_adjust(left=0.25) + + +@image_comparison(['date_axvline.png']) +def test_date_axvline(): + # test axvline with date inputs + t0 = datetime.datetime(2000, 1, 20) + tf = datetime.datetime(2000, 1, 21) + fig, ax = plt.subplots() + ax.axvline(t0, color="red", lw=3) + ax.set_xlim(t0 - datetime.timedelta(days=5), + tf + datetime.timedelta(days=5)) + fig.autofmt_xdate() + + +def test_too_many_date_ticks(caplog): + # Attempt to test SF 2715172, see + # https://sourceforge.net/tracker/?func=detail&aid=2715172&group_id=80706&atid=560720 + # setting equal datetimes triggers and expander call in + # transforms.nonsingular which results in too many ticks in the + # DayLocator. This should emit a log at WARNING level. + caplog.set_level("WARNING") + t0 = datetime.datetime(2000, 1, 20) + tf = datetime.datetime(2000, 1, 20) + fig, ax = plt.subplots() + with pytest.warns(UserWarning) as rec: + ax.set_xlim((t0, tf), auto=True) + assert len(rec) == 1 + assert ('Attempting to set identical low and high xlims' + in str(rec[0].message)) + ax.plot([], []) + ax.xaxis.set_major_locator(mdates.DayLocator()) + v = ax.xaxis.get_major_locator()() + assert len(v) > 1000 + # The warning is emitted multiple times because the major locator is also + # called both when placing the minor ticks (for overstriking detection) and + # during tick label positioning. + assert caplog.records and all( + record.name == "matplotlib.ticker" and record.levelname == "WARNING" + for record in caplog.records) + assert len(caplog.records) > 0 + + +def _new_epoch_decorator(thefunc): + @functools.wraps(thefunc) + def wrapper(): + mdates._reset_epoch_test_example() + mdates.set_epoch('2000-01-01') + thefunc() + mdates._reset_epoch_test_example() + return wrapper + + +@image_comparison(['RRuleLocator_bounds.png']) +def test_RRuleLocator(): + import matplotlib.testing.jpl_units as units + units.register() + # This will cause the RRuleLocator to go out of bounds when it tries + # to add padding to the limits, so we make sure it caps at the correct + # boundary values. + t0 = datetime.datetime(1000, 1, 1) + tf = datetime.datetime(6000, 1, 1) + + fig = plt.figure() + ax = plt.subplot() + ax.set_autoscale_on(True) + ax.plot([t0, tf], [0.0, 1.0], marker='o') + + rrule = mdates.rrulewrapper(dateutil.rrule.YEARLY, interval=500) + locator = mdates.RRuleLocator(rrule) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator)) + + ax.autoscale_view() + fig.autofmt_xdate() + + +def test_RRuleLocator_dayrange(): + loc = mdates.DayLocator() + x1 = datetime.datetime(year=1, month=1, day=1, tzinfo=mdates.UTC) + y1 = datetime.datetime(year=1, month=1, day=16, tzinfo=mdates.UTC) + loc.tick_values(x1, y1) + # On success, no overflow error shall be thrown + + +def test_RRuleLocator_close_minmax(): + # if d1 and d2 are very close together, rrule cannot create + # reasonable tick intervals; ensure that this is handled properly + rrule = mdates.rrulewrapper(dateutil.rrule.SECONDLY, interval=5) + loc = mdates.RRuleLocator(rrule) + d1 = datetime.datetime(year=2020, month=1, day=1) + d2 = datetime.datetime(year=2020, month=1, day=1, microsecond=1) + expected = ['2020-01-01 00:00:00+00:00', + '2020-01-01 00:00:00.000001+00:00'] + assert list(map(str, mdates.num2date(loc.tick_values(d1, d2)))) == expected + + +@image_comparison(['DateFormatter_fractionalSeconds.png']) +def test_DateFormatter(): + import matplotlib.testing.jpl_units as units + units.register() + + # Lets make sure that DateFormatter will allow us to have tick marks + # at intervals of fractional seconds. + + t0 = datetime.datetime(2001, 1, 1, 0, 0, 0) + tf = datetime.datetime(2001, 1, 1, 0, 0, 1) + + fig = plt.figure() + ax = plt.subplot() + ax.set_autoscale_on(True) + ax.plot([t0, tf], [0.0, 1.0], marker='o') + + # rrule = mpldates.rrulewrapper( dateutil.rrule.YEARLY, interval=500 ) + # locator = mpldates.RRuleLocator( rrule ) + # ax.xaxis.set_major_locator( locator ) + # ax.xaxis.set_major_formatter( mpldates.AutoDateFormatter(locator) ) + + ax.autoscale_view() + fig.autofmt_xdate() + + +def test_locator_set_formatter(): + """ + Test if setting the locator only will update the AutoDateFormatter to use + the new locator. + """ + plt.rcParams["date.autoformatter.minute"] = "%d %H:%M" + t = [datetime.datetime(2018, 9, 30, 8, 0), + datetime.datetime(2018, 9, 30, 8, 59), + datetime.datetime(2018, 9, 30, 10, 30)] + x = [2, 3, 1] + + fig, ax = plt.subplots() + ax.plot(t, x) + ax.xaxis.set_major_locator(mdates.MinuteLocator((0, 30))) + fig.canvas.draw() + ticklabels = [tl.get_text() for tl in ax.get_xticklabels()] + expected = ['30 08:00', '30 08:30', '30 09:00', + '30 09:30', '30 10:00', '30 10:30'] + assert ticklabels == expected + + ax.xaxis.set_major_locator(mticker.NullLocator()) + ax.xaxis.set_minor_locator(mdates.MinuteLocator((5, 55))) + decoy_loc = mdates.MinuteLocator((12, 27)) + ax.xaxis.set_minor_formatter(mdates.AutoDateFormatter(decoy_loc)) + + ax.xaxis.set_minor_locator(mdates.MinuteLocator((15, 45))) + fig.canvas.draw() + ticklabels = [tl.get_text() for tl in ax.get_xticklabels(which="minor")] + expected = ['30 08:15', '30 08:45', '30 09:15', '30 09:45', '30 10:15'] + assert ticklabels == expected + + +def test_date_formatter_callable(): + + class _Locator: + def _get_unit(self): return -11 + + def callable_formatting_function(dates, _): + return [dt.strftime('%d-%m//%Y') for dt in dates] + + formatter = mdates.AutoDateFormatter(_Locator()) + formatter.scaled[-10] = callable_formatting_function + assert formatter([datetime.datetime(2014, 12, 25)]) == ['25-12//2014'] + + +@pytest.mark.parametrize('delta, expected', [ + (datetime.timedelta(weeks=52 * 200), + [r'$\mathdefault{%d}$' % year for year in range(1990, 2171, 20)]), + (datetime.timedelta(days=30), + [r'$\mathdefault{1990{-}01{-}%02d}$' % day for day in range(1, 32, 3)]), + (datetime.timedelta(hours=20), + [r'$\mathdefault{01{-}01\;%02d}$' % hour for hour in range(0, 21, 2)]), + (datetime.timedelta(minutes=10), + [r'$\mathdefault{01\;00{:}%02d}$' % minu for minu in range(0, 11)]), +]) +def test_date_formatter_usetex(delta, expected): + style.use("default") + + d1 = datetime.datetime(1990, 1, 1) + d2 = d1 + delta + + locator = mdates.AutoDateLocator(interval_multiples=False) + locator.create_dummy_axis() + locator.axis.set_view_interval(mdates.date2num(d1), mdates.date2num(d2)) + + formatter = mdates.AutoDateFormatter(locator, usetex=True) + assert [formatter(loc) for loc in locator()] == expected + + +def test_drange(): + """ + This test should check if drange works as expected, and if all the + rounding errors are fixed + """ + start = datetime.datetime(2011, 1, 1, tzinfo=mdates.UTC) + end = datetime.datetime(2011, 1, 2, tzinfo=mdates.UTC) + delta = datetime.timedelta(hours=1) + # We expect 24 values in drange(start, end, delta), because drange returns + # dates from an half open interval [start, end) + assert len(mdates.drange(start, end, delta)) == 24 + + # Same if interval ends slightly earlier + end = end - datetime.timedelta(microseconds=1) + assert len(mdates.drange(start, end, delta)) == 24 + + # if end is a little bit later, we expect the range to contain one element + # more + end = end + datetime.timedelta(microseconds=2) + assert len(mdates.drange(start, end, delta)) == 25 + + # reset end + end = datetime.datetime(2011, 1, 2, tzinfo=mdates.UTC) + + # and tst drange with "complicated" floats: + # 4 hours = 1/6 day, this is an "dangerous" float + delta = datetime.timedelta(hours=4) + daterange = mdates.drange(start, end, delta) + assert len(daterange) == 6 + assert mdates.num2date(daterange[-1]) == (end - delta) + + +@_new_epoch_decorator +def test_auto_date_locator(): + def _create_auto_date_locator(date1, date2): + locator = mdates.AutoDateLocator(interval_multiples=False) + locator.create_dummy_axis() + locator.axis.set_view_interval(*mdates.date2num([date1, date2])) + return locator + + d1 = datetime.datetime(1990, 1, 1) + results = ([datetime.timedelta(weeks=52 * 200), + ['1990-01-01 00:00:00+00:00', '2010-01-01 00:00:00+00:00', + '2030-01-01 00:00:00+00:00', '2050-01-01 00:00:00+00:00', + '2070-01-01 00:00:00+00:00', '2090-01-01 00:00:00+00:00', + '2110-01-01 00:00:00+00:00', '2130-01-01 00:00:00+00:00', + '2150-01-01 00:00:00+00:00', '2170-01-01 00:00:00+00:00'] + ], + [datetime.timedelta(weeks=52), + ['1990-01-01 00:00:00+00:00', '1990-02-01 00:00:00+00:00', + '1990-03-01 00:00:00+00:00', '1990-04-01 00:00:00+00:00', + '1990-05-01 00:00:00+00:00', '1990-06-01 00:00:00+00:00', + '1990-07-01 00:00:00+00:00', '1990-08-01 00:00:00+00:00', + '1990-09-01 00:00:00+00:00', '1990-10-01 00:00:00+00:00', + '1990-11-01 00:00:00+00:00', '1990-12-01 00:00:00+00:00'] + ], + [datetime.timedelta(days=141), + ['1990-01-05 00:00:00+00:00', '1990-01-26 00:00:00+00:00', + '1990-02-16 00:00:00+00:00', '1990-03-09 00:00:00+00:00', + '1990-03-30 00:00:00+00:00', '1990-04-20 00:00:00+00:00', + '1990-05-11 00:00:00+00:00'] + ], + [datetime.timedelta(days=40), + ['1990-01-03 00:00:00+00:00', '1990-01-10 00:00:00+00:00', + '1990-01-17 00:00:00+00:00', '1990-01-24 00:00:00+00:00', + '1990-01-31 00:00:00+00:00', '1990-02-07 00:00:00+00:00'] + ], + [datetime.timedelta(hours=40), + ['1990-01-01 00:00:00+00:00', '1990-01-01 04:00:00+00:00', + '1990-01-01 08:00:00+00:00', '1990-01-01 12:00:00+00:00', + '1990-01-01 16:00:00+00:00', '1990-01-01 20:00:00+00:00', + '1990-01-02 00:00:00+00:00', '1990-01-02 04:00:00+00:00', + '1990-01-02 08:00:00+00:00', '1990-01-02 12:00:00+00:00', + '1990-01-02 16:00:00+00:00'] + ], + [datetime.timedelta(minutes=20), + ['1990-01-01 00:00:00+00:00', '1990-01-01 00:05:00+00:00', + '1990-01-01 00:10:00+00:00', '1990-01-01 00:15:00+00:00', + '1990-01-01 00:20:00+00:00'] + ], + [datetime.timedelta(seconds=40), + ['1990-01-01 00:00:00+00:00', '1990-01-01 00:00:05+00:00', + '1990-01-01 00:00:10+00:00', '1990-01-01 00:00:15+00:00', + '1990-01-01 00:00:20+00:00', '1990-01-01 00:00:25+00:00', + '1990-01-01 00:00:30+00:00', '1990-01-01 00:00:35+00:00', + '1990-01-01 00:00:40+00:00'] + ], + [datetime.timedelta(microseconds=1500), + ['1989-12-31 23:59:59.999500+00:00', + '1990-01-01 00:00:00+00:00', + '1990-01-01 00:00:00.000500+00:00', + '1990-01-01 00:00:00.001000+00:00', + '1990-01-01 00:00:00.001500+00:00', + '1990-01-01 00:00:00.002000+00:00'] + ], + ) + + for t_delta, expected in results: + d2 = d1 + t_delta + locator = _create_auto_date_locator(d1, d2) + assert list(map(str, mdates.num2date(locator()))) == expected + + locator = mdates.AutoDateLocator(interval_multiples=False) + assert locator.maxticks == {0: 11, 1: 12, 3: 11, 4: 12, 5: 11, 6: 11, 7: 8} + + locator = mdates.AutoDateLocator(maxticks={dateutil.rrule.MONTHLY: 5}) + assert locator.maxticks == {0: 11, 1: 5, 3: 11, 4: 12, 5: 11, 6: 11, 7: 8} + + locator = mdates.AutoDateLocator(maxticks=5) + assert locator.maxticks == {0: 5, 1: 5, 3: 5, 4: 5, 5: 5, 6: 5, 7: 5} + + +@_new_epoch_decorator +def test_auto_date_locator_intmult(): + def _create_auto_date_locator(date1, date2): + locator = mdates.AutoDateLocator(interval_multiples=True) + locator.create_dummy_axis() + locator.axis.set_view_interval(*mdates.date2num([date1, date2])) + return locator + + results = ([datetime.timedelta(weeks=52 * 200), + ['1980-01-01 00:00:00+00:00', '2000-01-01 00:00:00+00:00', + '2020-01-01 00:00:00+00:00', '2040-01-01 00:00:00+00:00', + '2060-01-01 00:00:00+00:00', '2080-01-01 00:00:00+00:00', + '2100-01-01 00:00:00+00:00', '2120-01-01 00:00:00+00:00', + '2140-01-01 00:00:00+00:00', '2160-01-01 00:00:00+00:00', + '2180-01-01 00:00:00+00:00', '2200-01-01 00:00:00+00:00'] + ], + [datetime.timedelta(weeks=52), + ['1997-01-01 00:00:00+00:00', '1997-02-01 00:00:00+00:00', + '1997-03-01 00:00:00+00:00', '1997-04-01 00:00:00+00:00', + '1997-05-01 00:00:00+00:00', '1997-06-01 00:00:00+00:00', + '1997-07-01 00:00:00+00:00', '1997-08-01 00:00:00+00:00', + '1997-09-01 00:00:00+00:00', '1997-10-01 00:00:00+00:00', + '1997-11-01 00:00:00+00:00', '1997-12-01 00:00:00+00:00'] + ], + [datetime.timedelta(days=141), + ['1997-01-01 00:00:00+00:00', '1997-01-15 00:00:00+00:00', + '1997-02-01 00:00:00+00:00', '1997-02-15 00:00:00+00:00', + '1997-03-01 00:00:00+00:00', '1997-03-15 00:00:00+00:00', + '1997-04-01 00:00:00+00:00', '1997-04-15 00:00:00+00:00', + '1997-05-01 00:00:00+00:00', '1997-05-15 00:00:00+00:00'] + ], + [datetime.timedelta(days=40), + ['1997-01-01 00:00:00+00:00', '1997-01-05 00:00:00+00:00', + '1997-01-09 00:00:00+00:00', '1997-01-13 00:00:00+00:00', + '1997-01-17 00:00:00+00:00', '1997-01-21 00:00:00+00:00', + '1997-01-25 00:00:00+00:00', '1997-01-29 00:00:00+00:00', + '1997-02-01 00:00:00+00:00', '1997-02-05 00:00:00+00:00', + '1997-02-09 00:00:00+00:00'] + ], + [datetime.timedelta(hours=40), + ['1997-01-01 00:00:00+00:00', '1997-01-01 04:00:00+00:00', + '1997-01-01 08:00:00+00:00', '1997-01-01 12:00:00+00:00', + '1997-01-01 16:00:00+00:00', '1997-01-01 20:00:00+00:00', + '1997-01-02 00:00:00+00:00', '1997-01-02 04:00:00+00:00', + '1997-01-02 08:00:00+00:00', '1997-01-02 12:00:00+00:00', + '1997-01-02 16:00:00+00:00'] + ], + [datetime.timedelta(minutes=20), + ['1997-01-01 00:00:00+00:00', '1997-01-01 00:05:00+00:00', + '1997-01-01 00:10:00+00:00', '1997-01-01 00:15:00+00:00', + '1997-01-01 00:20:00+00:00'] + ], + [datetime.timedelta(seconds=40), + ['1997-01-01 00:00:00+00:00', '1997-01-01 00:00:05+00:00', + '1997-01-01 00:00:10+00:00', '1997-01-01 00:00:15+00:00', + '1997-01-01 00:00:20+00:00', '1997-01-01 00:00:25+00:00', + '1997-01-01 00:00:30+00:00', '1997-01-01 00:00:35+00:00', + '1997-01-01 00:00:40+00:00'] + ], + [datetime.timedelta(microseconds=1500), + ['1996-12-31 23:59:59.999500+00:00', + '1997-01-01 00:00:00+00:00', + '1997-01-01 00:00:00.000500+00:00', + '1997-01-01 00:00:00.001000+00:00', + '1997-01-01 00:00:00.001500+00:00', + '1997-01-01 00:00:00.002000+00:00'] + ], + ) + + d1 = datetime.datetime(1997, 1, 1) + for t_delta, expected in results: + d2 = d1 + t_delta + locator = _create_auto_date_locator(d1, d2) + assert list(map(str, mdates.num2date(locator()))) == expected + + +def test_concise_formatter_subsecond(): + locator = mdates.AutoDateLocator(interval_multiples=True) + formatter = mdates.ConciseDateFormatter(locator) + year_1996 = 9861.0 + strings = formatter.format_ticks([ + year_1996, + year_1996 + 500 / mdates.MUSECONDS_PER_DAY, + year_1996 + 900 / mdates.MUSECONDS_PER_DAY]) + assert strings == ['00:00', '00.0005', '00.0009'] + + +def test_concise_formatter(): + def _create_auto_date_locator(date1, date2): + fig, ax = plt.subplots() + + locator = mdates.AutoDateLocator(interval_multiples=True) + formatter = mdates.ConciseDateFormatter(locator) + ax.yaxis.set_major_locator(locator) + ax.yaxis.set_major_formatter(formatter) + ax.set_ylim(date1, date2) + fig.canvas.draw() + sts = [st.get_text() for st in ax.get_yticklabels()] + return sts + + d1 = datetime.datetime(1997, 1, 1) + results = ([datetime.timedelta(weeks=52 * 200), + [str(t) for t in range(1980, 2201, 20)] + ], + [datetime.timedelta(weeks=52), + ['1997', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', + 'Sep', 'Oct', 'Nov', 'Dec'] + ], + [datetime.timedelta(days=141), + ['Jan', '15', 'Feb', '15', 'Mar', '15', 'Apr', '15', + 'May', '15'] + ], + [datetime.timedelta(days=40), + ['Jan', '05', '09', '13', '17', '21', '25', '29', 'Feb', + '05', '09'] + ], + [datetime.timedelta(hours=40), + ['Jan-01', '04:00', '08:00', '12:00', '16:00', '20:00', + 'Jan-02', '04:00', '08:00', '12:00', '16:00'] + ], + [datetime.timedelta(minutes=20), + ['00:00', '00:05', '00:10', '00:15', '00:20'] + ], + [datetime.timedelta(seconds=40), + ['00:00', '05', '10', '15', '20', '25', '30', '35', '40'] + ], + [datetime.timedelta(seconds=2), + ['59.5', '00:00', '00.5', '01.0', '01.5', '02.0', '02.5'] + ], + ) + for t_delta, expected in results: + d2 = d1 + t_delta + strings = _create_auto_date_locator(d1, d2) + assert strings == expected + + +@pytest.mark.parametrize('t_delta, expected', [ + (datetime.timedelta(seconds=0.01), '1997-Jan-01 00:00'), + (datetime.timedelta(minutes=1), '1997-Jan-01 00:01'), + (datetime.timedelta(hours=1), '1997-Jan-01'), + (datetime.timedelta(days=1), '1997-Jan-02'), + (datetime.timedelta(weeks=1), '1997-Jan'), + (datetime.timedelta(weeks=26), ''), + (datetime.timedelta(weeks=520), '') +]) +def test_concise_formatter_show_offset(t_delta, expected): + d1 = datetime.datetime(1997, 1, 1) + d2 = d1 + t_delta + + fig, ax = plt.subplots() + locator = mdates.AutoDateLocator() + formatter = mdates.ConciseDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + + ax.plot([d1, d2], [0, 0]) + fig.canvas.draw() + assert formatter.get_offset() == expected + + +def test_concise_converter_stays(): + # This test demonstrates problems introduced by gh-23417 (reverted in gh-25278) + # In particular, downstream libraries like Pandas had their designated converters + # overridden by actions like setting xlim (or plotting additional points using + # stdlib/numpy dates and string date representation, which otherwise work fine with + # their date converters) + # While this is a bit of a toy example that would be unusual to see it demonstrates + # the same ideas (namely having a valid converter already applied that is desired) + # without introducing additional subclasses. + # See also discussion at gh-25219 for how Pandas was affected + x = [datetime.datetime(2000, 1, 1), datetime.datetime(2020, 2, 20)] + y = [0, 1] + fig, ax = plt.subplots() + ax.plot(x, y) + # Bypass Switchable date converter + ax.xaxis.converter = conv = mdates.ConciseDateConverter() + assert ax.xaxis.units is None + ax.set_xlim(*x) + assert ax.xaxis.converter == conv + + +def test_offset_changes(): + fig, ax = plt.subplots() + + d1 = datetime.datetime(1997, 1, 1) + d2 = d1 + datetime.timedelta(weeks=520) + + locator = mdates.AutoDateLocator() + formatter = mdates.ConciseDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + + ax.plot([d1, d2], [0, 0]) + fig.draw_without_rendering() + assert formatter.get_offset() == '' + ax.set_xlim(d1, d1 + datetime.timedelta(weeks=3)) + fig.draw_without_rendering() + assert formatter.get_offset() == '1997-Jan' + ax.set_xlim(d1 + datetime.timedelta(weeks=7), + d1 + datetime.timedelta(weeks=30)) + fig.draw_without_rendering() + assert formatter.get_offset() == '1997' + ax.set_xlim(d1, d1 + datetime.timedelta(weeks=520)) + fig.draw_without_rendering() + assert formatter.get_offset() == '' + + +@pytest.mark.parametrize('t_delta, expected', [ + (datetime.timedelta(weeks=52 * 200), + ['$\\mathdefault{%d}$' % (t, ) for t in range(1980, 2201, 20)]), + (datetime.timedelta(days=40), + ['Jan', '$\\mathdefault{05}$', '$\\mathdefault{09}$', + '$\\mathdefault{13}$', '$\\mathdefault{17}$', '$\\mathdefault{21}$', + '$\\mathdefault{25}$', '$\\mathdefault{29}$', 'Feb', + '$\\mathdefault{05}$', '$\\mathdefault{09}$']), + (datetime.timedelta(hours=40), + ['Jan$\\mathdefault{{-}01}$', '$\\mathdefault{04{:}00}$', + '$\\mathdefault{08{:}00}$', '$\\mathdefault{12{:}00}$', + '$\\mathdefault{16{:}00}$', '$\\mathdefault{20{:}00}$', + 'Jan$\\mathdefault{{-}02}$', '$\\mathdefault{04{:}00}$', + '$\\mathdefault{08{:}00}$', '$\\mathdefault{12{:}00}$', + '$\\mathdefault{16{:}00}$']), + (datetime.timedelta(seconds=2), + ['$\\mathdefault{59.5}$', '$\\mathdefault{00{:}00}$', + '$\\mathdefault{00.5}$', '$\\mathdefault{01.0}$', + '$\\mathdefault{01.5}$', '$\\mathdefault{02.0}$', + '$\\mathdefault{02.5}$']), +]) +def test_concise_formatter_usetex(t_delta, expected): + d1 = datetime.datetime(1997, 1, 1) + d2 = d1 + t_delta + + locator = mdates.AutoDateLocator(interval_multiples=True) + locator.create_dummy_axis() + locator.axis.set_view_interval(mdates.date2num(d1), mdates.date2num(d2)) + + formatter = mdates.ConciseDateFormatter(locator, usetex=True) + assert formatter.format_ticks(locator()) == expected + + +def test_concise_formatter_formats(): + formats = ['%Y', '%m/%Y', 'day: %d', + '%H hr %M min', '%H hr %M min', '%S.%f sec'] + + def _create_auto_date_locator(date1, date2): + fig, ax = plt.subplots() + + locator = mdates.AutoDateLocator(interval_multiples=True) + formatter = mdates.ConciseDateFormatter(locator, formats=formats) + ax.yaxis.set_major_locator(locator) + ax.yaxis.set_major_formatter(formatter) + ax.set_ylim(date1, date2) + fig.canvas.draw() + sts = [st.get_text() for st in ax.get_yticklabels()] + return sts + + d1 = datetime.datetime(1997, 1, 1) + results = ( + [datetime.timedelta(weeks=52 * 200), [str(t) for t in range(1980, + 2201, 20)]], + [datetime.timedelta(weeks=52), [ + '1997', '02/1997', '03/1997', '04/1997', '05/1997', '06/1997', + '07/1997', '08/1997', '09/1997', '10/1997', '11/1997', '12/1997', + ]], + [datetime.timedelta(days=141), [ + '01/1997', 'day: 15', '02/1997', 'day: 15', '03/1997', 'day: 15', + '04/1997', 'day: 15', '05/1997', 'day: 15', + ]], + [datetime.timedelta(days=40), [ + '01/1997', 'day: 05', 'day: 09', 'day: 13', 'day: 17', 'day: 21', + 'day: 25', 'day: 29', '02/1997', 'day: 05', 'day: 09', + ]], + [datetime.timedelta(hours=40), [ + 'day: 01', '04 hr 00 min', '08 hr 00 min', '12 hr 00 min', + '16 hr 00 min', '20 hr 00 min', 'day: 02', '04 hr 00 min', + '08 hr 00 min', '12 hr 00 min', '16 hr 00 min', + ]], + [datetime.timedelta(minutes=20), ['00 hr 00 min', '00 hr 05 min', + '00 hr 10 min', '00 hr 15 min', '00 hr 20 min']], + [datetime.timedelta(seconds=40), [ + '00 hr 00 min', '05.000000 sec', '10.000000 sec', + '15.000000 sec', '20.000000 sec', '25.000000 sec', + '30.000000 sec', '35.000000 sec', '40.000000 sec', + ]], + [datetime.timedelta(seconds=2), [ + '59.500000 sec', '00 hr 00 min', '00.500000 sec', '01.000000 sec', + '01.500000 sec', '02.000000 sec', '02.500000 sec', + ]], + ) + for t_delta, expected in results: + d2 = d1 + t_delta + strings = _create_auto_date_locator(d1, d2) + assert strings == expected + + +def test_concise_formatter_zformats(): + zero_formats = ['', "'%y", '%B', '%m-%d', '%S', '%S.%f'] + + def _create_auto_date_locator(date1, date2): + fig, ax = plt.subplots() + + locator = mdates.AutoDateLocator(interval_multiples=True) + formatter = mdates.ConciseDateFormatter( + locator, zero_formats=zero_formats) + ax.yaxis.set_major_locator(locator) + ax.yaxis.set_major_formatter(formatter) + ax.set_ylim(date1, date2) + fig.canvas.draw() + sts = [st.get_text() for st in ax.get_yticklabels()] + return sts + + d1 = datetime.datetime(1997, 1, 1) + results = ([datetime.timedelta(weeks=52 * 200), + [str(t) for t in range(1980, 2201, 20)] + ], + [datetime.timedelta(weeks=52), + ["'97", 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + ], + [datetime.timedelta(days=141), + ['January', '15', 'February', '15', 'March', + '15', 'April', '15', 'May', '15'] + ], + [datetime.timedelta(days=40), + ['January', '05', '09', '13', '17', '21', + '25', '29', 'February', '05', '09'] + ], + [datetime.timedelta(hours=40), + ['01-01', '04:00', '08:00', '12:00', '16:00', '20:00', + '01-02', '04:00', '08:00', '12:00', '16:00'] + ], + [datetime.timedelta(minutes=20), + ['00', '00:05', '00:10', '00:15', '00:20'] + ], + [datetime.timedelta(seconds=40), + ['00', '05', '10', '15', '20', '25', '30', '35', '40'] + ], + [datetime.timedelta(seconds=2), + ['59.5', '00.0', '00.5', '01.0', '01.5', '02.0', '02.5'] + ], + ) + for t_delta, expected in results: + d2 = d1 + t_delta + strings = _create_auto_date_locator(d1, d2) + assert strings == expected + + +def test_concise_formatter_tz(): + def _create_auto_date_locator(date1, date2, tz): + fig, ax = plt.subplots() + + locator = mdates.AutoDateLocator(interval_multiples=True) + formatter = mdates.ConciseDateFormatter(locator, tz=tz) + ax.yaxis.set_major_locator(locator) + ax.yaxis.set_major_formatter(formatter) + ax.set_ylim(date1, date2) + fig.canvas.draw() + sts = [st.get_text() for st in ax.get_yticklabels()] + return sts, ax.yaxis.get_offset_text().get_text() + + d1 = datetime.datetime(1997, 1, 1).replace(tzinfo=datetime.timezone.utc) + results = ([datetime.timedelta(hours=40), + ['03:00', '07:00', '11:00', '15:00', '19:00', '23:00', + '03:00', '07:00', '11:00', '15:00', '19:00'], + "1997-Jan-02" + ], + [datetime.timedelta(minutes=20), + ['03:00', '03:05', '03:10', '03:15', '03:20'], + "1997-Jan-01" + ], + [datetime.timedelta(seconds=40), + ['03:00', '05', '10', '15', '20', '25', '30', '35', '40'], + "1997-Jan-01 03:00" + ], + [datetime.timedelta(seconds=2), + ['59.5', '03:00', '00.5', '01.0', '01.5', '02.0', '02.5'], + "1997-Jan-01 03:00" + ], + ) + + new_tz = datetime.timezone(datetime.timedelta(hours=3)) + for t_delta, expected_strings, expected_offset in results: + d2 = d1 + t_delta + strings, offset = _create_auto_date_locator(d1, d2, new_tz) + assert strings == expected_strings + assert offset == expected_offset + + +def test_auto_date_locator_intmult_tz(): + def _create_auto_date_locator(date1, date2, tz): + locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz) + locator.create_dummy_axis() + locator.axis.set_view_interval(*mdates.date2num([date1, date2])) + return locator + + results = ([datetime.timedelta(weeks=52*200), + ['1980-01-01 00:00:00-08:00', '2000-01-01 00:00:00-08:00', + '2020-01-01 00:00:00-08:00', '2040-01-01 00:00:00-08:00', + '2060-01-01 00:00:00-08:00', '2080-01-01 00:00:00-08:00', + '2100-01-01 00:00:00-08:00', '2120-01-01 00:00:00-08:00', + '2140-01-01 00:00:00-08:00', '2160-01-01 00:00:00-08:00', + '2180-01-01 00:00:00-08:00', '2200-01-01 00:00:00-08:00'] + ], + [datetime.timedelta(weeks=52), + ['1997-01-01 00:00:00-08:00', '1997-02-01 00:00:00-08:00', + '1997-03-01 00:00:00-08:00', '1997-04-01 00:00:00-08:00', + '1997-05-01 00:00:00-07:00', '1997-06-01 00:00:00-07:00', + '1997-07-01 00:00:00-07:00', '1997-08-01 00:00:00-07:00', + '1997-09-01 00:00:00-07:00', '1997-10-01 00:00:00-07:00', + '1997-11-01 00:00:00-08:00', '1997-12-01 00:00:00-08:00'] + ], + [datetime.timedelta(days=141), + ['1997-01-01 00:00:00-08:00', '1997-01-15 00:00:00-08:00', + '1997-02-01 00:00:00-08:00', '1997-02-15 00:00:00-08:00', + '1997-03-01 00:00:00-08:00', '1997-03-15 00:00:00-08:00', + '1997-04-01 00:00:00-08:00', '1997-04-15 00:00:00-07:00', + '1997-05-01 00:00:00-07:00', '1997-05-15 00:00:00-07:00'] + ], + [datetime.timedelta(days=40), + ['1997-01-01 00:00:00-08:00', '1997-01-05 00:00:00-08:00', + '1997-01-09 00:00:00-08:00', '1997-01-13 00:00:00-08:00', + '1997-01-17 00:00:00-08:00', '1997-01-21 00:00:00-08:00', + '1997-01-25 00:00:00-08:00', '1997-01-29 00:00:00-08:00', + '1997-02-01 00:00:00-08:00', '1997-02-05 00:00:00-08:00', + '1997-02-09 00:00:00-08:00'] + ], + [datetime.timedelta(hours=40), + ['1997-01-01 00:00:00-08:00', '1997-01-01 04:00:00-08:00', + '1997-01-01 08:00:00-08:00', '1997-01-01 12:00:00-08:00', + '1997-01-01 16:00:00-08:00', '1997-01-01 20:00:00-08:00', + '1997-01-02 00:00:00-08:00', '1997-01-02 04:00:00-08:00', + '1997-01-02 08:00:00-08:00', '1997-01-02 12:00:00-08:00', + '1997-01-02 16:00:00-08:00'] + ], + [datetime.timedelta(minutes=20), + ['1997-01-01 00:00:00-08:00', '1997-01-01 00:05:00-08:00', + '1997-01-01 00:10:00-08:00', '1997-01-01 00:15:00-08:00', + '1997-01-01 00:20:00-08:00'] + ], + [datetime.timedelta(seconds=40), + ['1997-01-01 00:00:00-08:00', '1997-01-01 00:00:05-08:00', + '1997-01-01 00:00:10-08:00', '1997-01-01 00:00:15-08:00', + '1997-01-01 00:00:20-08:00', '1997-01-01 00:00:25-08:00', + '1997-01-01 00:00:30-08:00', '1997-01-01 00:00:35-08:00', + '1997-01-01 00:00:40-08:00'] + ] + ) + + tz = dateutil.tz.gettz('Canada/Pacific') + d1 = datetime.datetime(1997, 1, 1, tzinfo=tz) + for t_delta, expected in results: + with rc_context({'_internal.classic_mode': False}): + d2 = d1 + t_delta + locator = _create_auto_date_locator(d1, d2, tz) + st = list(map(str, mdates.num2date(locator(), tz=tz))) + assert st == expected + + +@image_comparison(['date_inverted_limit.png']) +def test_date_inverted_limit(): + # test ax hline with date inputs + t0 = datetime.datetime(2009, 1, 20) + tf = datetime.datetime(2009, 1, 31) + fig, ax = plt.subplots() + ax.axhline(t0, color="blue", lw=3) + ax.set_ylim(t0 - datetime.timedelta(days=5), + tf + datetime.timedelta(days=5)) + ax.invert_yaxis() + fig.subplots_adjust(left=0.25) + + +def _test_date2num_dst(date_range, tz_convert): + # Timezones + + BRUSSELS = dateutil.tz.gettz('Europe/Brussels') + UTC = mdates.UTC + + # Create a list of timezone-aware datetime objects in UTC + # Interval is 0b0.0000011 days, to prevent float rounding issues + dtstart = datetime.datetime(2014, 3, 30, 0, 0, tzinfo=UTC) + interval = datetime.timedelta(minutes=33, seconds=45) + interval_days = interval.seconds / 86400 + N = 8 + + dt_utc = date_range(start=dtstart, freq=interval, periods=N) + dt_bxl = tz_convert(dt_utc, BRUSSELS) + t0 = 735322.0 + mdates.date2num(np.datetime64('0000-12-31')) + expected_ordinalf = [t0 + (i * interval_days) for i in range(N)] + actual_ordinalf = list(mdates.date2num(dt_bxl)) + + assert actual_ordinalf == expected_ordinalf + + +def test_date2num_dst(): + # Test for github issue #3896, but in date2num around DST transitions + # with a timezone-aware pandas date_range object. + + class dt_tzaware(datetime.datetime): + """ + This bug specifically occurs because of the normalization behavior of + pandas Timestamp objects, so in order to replicate it, we need a + datetime-like object that applies timezone normalization after + subtraction. + """ + + def __sub__(self, other): + r = super().__sub__(other) + tzinfo = getattr(r, 'tzinfo', None) + + if tzinfo is not None: + localizer = getattr(tzinfo, 'normalize', None) + if localizer is not None: + r = tzinfo.normalize(r) + + if isinstance(r, datetime.datetime): + r = self.mk_tzaware(r) + + return r + + def __add__(self, other): + return self.mk_tzaware(super().__add__(other)) + + def astimezone(self, tzinfo): + dt = super().astimezone(tzinfo) + return self.mk_tzaware(dt) + + @classmethod + def mk_tzaware(cls, datetime_obj): + kwargs = {} + attrs = ('year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'microsecond', + 'tzinfo') + + for attr in attrs: + val = getattr(datetime_obj, attr, None) + if val is not None: + kwargs[attr] = val + + return cls(**kwargs) + + # Define a date_range function similar to pandas.date_range + def date_range(start, freq, periods): + dtstart = dt_tzaware.mk_tzaware(start) + + return [dtstart + (i * freq) for i in range(periods)] + + # Define a tz_convert function that converts a list to a new timezone. + def tz_convert(dt_list, tzinfo): + return [d.astimezone(tzinfo) for d in dt_list] + + _test_date2num_dst(date_range, tz_convert) + + +def test_date2num_dst_pandas(pd): + # Test for github issue #3896, but in date2num around DST transitions + # with a timezone-aware pandas date_range object. + + def tz_convert(*args): + return pd.DatetimeIndex.tz_convert(*args).astype(object) + + _test_date2num_dst(pd.date_range, tz_convert) + + +def _test_rrulewrapper(attach_tz, get_tz): + SYD = get_tz('Australia/Sydney') + + dtstart = attach_tz(datetime.datetime(2017, 4, 1, 0), SYD) + dtend = attach_tz(datetime.datetime(2017, 4, 4, 0), SYD) + + rule = mdates.rrulewrapper(freq=dateutil.rrule.DAILY, dtstart=dtstart) + + act = rule.between(dtstart, dtend) + exp = [datetime.datetime(2017, 4, 1, 13, tzinfo=dateutil.tz.tzutc()), + datetime.datetime(2017, 4, 2, 14, tzinfo=dateutil.tz.tzutc())] + + assert act == exp + + +def test_rrulewrapper(): + def attach_tz(dt, zi): + return dt.replace(tzinfo=zi) + + _test_rrulewrapper(attach_tz, dateutil.tz.gettz) + + SYD = dateutil.tz.gettz('Australia/Sydney') + dtstart = datetime.datetime(2017, 4, 1, 0) + dtend = datetime.datetime(2017, 4, 4, 0) + rule = mdates.rrulewrapper(freq=dateutil.rrule.DAILY, dtstart=dtstart, + tzinfo=SYD, until=dtend) + assert rule.after(dtstart) == datetime.datetime(2017, 4, 2, 0, 0, + tzinfo=SYD) + assert rule.before(dtend) == datetime.datetime(2017, 4, 3, 0, 0, + tzinfo=SYD) + + # Test parts of __getattr__ + assert rule._base_tzinfo == SYD + assert rule._interval == 1 + + +@pytest.mark.pytz +def test_rrulewrapper_pytz(): + # Test to make sure pytz zones are supported in rrules + pytz = pytest.importorskip("pytz") + + def attach_tz(dt, zi): + return zi.localize(dt) + + _test_rrulewrapper(attach_tz, pytz.timezone) + + +@pytest.mark.pytz +def test_yearlocator_pytz(): + pytz = pytest.importorskip("pytz") + + tz = pytz.timezone('America/New_York') + x = [tz.localize(datetime.datetime(2010, 1, 1)) + + datetime.timedelta(i) for i in range(2000)] + locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz) + locator.create_dummy_axis() + locator.axis.set_view_interval(mdates.date2num(x[0])-1.0, + mdates.date2num(x[-1])+1.0) + t = np.array([733408.208333, 733773.208333, 734138.208333, + 734503.208333, 734869.208333, 735234.208333, 735599.208333]) + # convert to new epoch from old... + t = t + mdates.date2num(np.datetime64('0000-12-31')) + np.testing.assert_allclose(t, locator()) + expected = ['2009-01-01 00:00:00-05:00', + '2010-01-01 00:00:00-05:00', '2011-01-01 00:00:00-05:00', + '2012-01-01 00:00:00-05:00', '2013-01-01 00:00:00-05:00', + '2014-01-01 00:00:00-05:00', '2015-01-01 00:00:00-05:00'] + st = list(map(str, mdates.num2date(locator(), tz=tz))) + assert st == expected + assert np.allclose(locator.tick_values(x[0], x[1]), np.array( + [14610.20833333, 14610.33333333, 14610.45833333, 14610.58333333, + 14610.70833333, 14610.83333333, 14610.95833333, 14611.08333333, + 14611.20833333])) + assert np.allclose(locator.get_locator(x[1], x[0]).tick_values(x[0], x[1]), + np.array( + [14610.20833333, 14610.33333333, 14610.45833333, 14610.58333333, + 14610.70833333, 14610.83333333, 14610.95833333, 14611.08333333, + 14611.20833333])) + + +def test_YearLocator(): + def _create_year_locator(date1, date2, **kwargs): + locator = mdates.YearLocator(**kwargs) + locator.create_dummy_axis() + locator.axis.set_view_interval(mdates.date2num(date1), + mdates.date2num(date2)) + return locator + + d1 = datetime.datetime(1990, 1, 1) + results = ([datetime.timedelta(weeks=52 * 200), + {'base': 20, 'month': 1, 'day': 1}, + ['1980-01-01 00:00:00+00:00', '2000-01-01 00:00:00+00:00', + '2020-01-01 00:00:00+00:00', '2040-01-01 00:00:00+00:00', + '2060-01-01 00:00:00+00:00', '2080-01-01 00:00:00+00:00', + '2100-01-01 00:00:00+00:00', '2120-01-01 00:00:00+00:00', + '2140-01-01 00:00:00+00:00', '2160-01-01 00:00:00+00:00', + '2180-01-01 00:00:00+00:00', '2200-01-01 00:00:00+00:00'] + ], + [datetime.timedelta(weeks=52 * 200), + {'base': 20, 'month': 5, 'day': 16}, + ['1980-05-16 00:00:00+00:00', '2000-05-16 00:00:00+00:00', + '2020-05-16 00:00:00+00:00', '2040-05-16 00:00:00+00:00', + '2060-05-16 00:00:00+00:00', '2080-05-16 00:00:00+00:00', + '2100-05-16 00:00:00+00:00', '2120-05-16 00:00:00+00:00', + '2140-05-16 00:00:00+00:00', '2160-05-16 00:00:00+00:00', + '2180-05-16 00:00:00+00:00', '2200-05-16 00:00:00+00:00'] + ], + [datetime.timedelta(weeks=52 * 5), + {'base': 20, 'month': 9, 'day': 25}, + ['1980-09-25 00:00:00+00:00', '2000-09-25 00:00:00+00:00'] + ], + ) + + for delta, arguments, expected in results: + d2 = d1 + delta + locator = _create_year_locator(d1, d2, **arguments) + assert list(map(str, mdates.num2date(locator()))) == expected + + +def test_DayLocator(): + with pytest.raises(ValueError): + mdates.DayLocator(interval=-1) + with pytest.raises(ValueError): + mdates.DayLocator(interval=-1.5) + with pytest.raises(ValueError): + mdates.DayLocator(interval=0) + with pytest.raises(ValueError): + mdates.DayLocator(interval=1.3) + mdates.DayLocator(interval=1.0) + + +def test_tz_utc(): + dt = datetime.datetime(1970, 1, 1, tzinfo=mdates.UTC) + assert dt.tzname() == 'UTC' + + +@pytest.mark.parametrize("x, tdelta", + [(1, datetime.timedelta(days=1)), + ([1, 1.5], [datetime.timedelta(days=1), + datetime.timedelta(days=1.5)])]) +def test_num2timedelta(x, tdelta): + dt = mdates.num2timedelta(x) + assert dt == tdelta + + +def test_datetime64_in_list(): + dt = [np.datetime64('2000-01-01'), np.datetime64('2001-01-01')] + dn = mdates.date2num(dt) + # convert fixed values from old to new epoch + t = (np.array([730120., 730486.]) + + mdates.date2num(np.datetime64('0000-12-31'))) + np.testing.assert_equal(dn, t) + + +def test_change_epoch(): + date = np.datetime64('2000-01-01') + + # use private method to clear the epoch and allow it to be set... + mdates._reset_epoch_test_example() + mdates.get_epoch() # Set default. + + with pytest.raises(RuntimeError): + # this should fail here because there is a sentinel on the epoch + # if the epoch has been used then it cannot be set. + mdates.set_epoch('0000-01-01') + + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01') + dt = (date - np.datetime64('1970-01-01')).astype('datetime64[D]') + dt = dt.astype('int') + np.testing.assert_equal(mdates.date2num(date), float(dt)) + + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + np.testing.assert_equal(mdates.date2num(date), 730120.0) + + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01T01:00:00') + np.testing.assert_allclose(mdates.date2num(date), dt - 1./24.) + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01T00:00:00') + np.testing.assert_allclose( + mdates.date2num(np.datetime64('1970-01-01T12:00:00')), + 0.5) + + +def test_warn_notintervals(): + dates = np.arange('2001-01-10', '2001-03-04', dtype='datetime64[D]') + locator = mdates.AutoDateLocator(interval_multiples=False) + locator.intervald[3] = [2] + locator.create_dummy_axis() + locator.axis.set_view_interval(mdates.date2num(dates[0]), + mdates.date2num(dates[-1])) + with pytest.warns(UserWarning, match="AutoDateLocator was unable"): + locs = locator() + + +def test_change_converter(): + plt.rcParams['date.converter'] = 'concise' + dates = np.arange('2020-01-01', '2020-05-01', dtype='datetime64[D]') + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan' + assert ax.get_xticklabels()[1].get_text() == '15' + + plt.rcParams['date.converter'] = 'auto' + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 01 2020' + assert ax.get_xticklabels()[1].get_text() == 'Jan 15 2020' + with pytest.raises(ValueError): + plt.rcParams['date.converter'] = 'boo' + + +def test_change_interval_multiples(): + plt.rcParams['date.interval_multiples'] = False + dates = np.arange('2020-01-10', '2020-05-01', dtype='datetime64[D]') + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 10 2020' + assert ax.get_xticklabels()[1].get_text() == 'Jan 24 2020' + + plt.rcParams['date.interval_multiples'] = 'True' + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 15 2020' + assert ax.get_xticklabels()[1].get_text() == 'Feb 01 2020' + + +def test_julian2num(): + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + with pytest.warns(mpl.MatplotlibDeprecationWarning): + # 2440587.5 is julian date for 1970-01-01T00:00:00 + # https://en.wikipedia.org/wiki/Julian_day + assert mdates.julian2num(2440588.5) == 719164.0 + assert mdates.num2julian(719165.0) == 2440589.5 + # set back to the default + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01T00:00:00') + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert mdates.julian2num(2440588.5) == 1.0 + assert mdates.num2julian(2.0) == 2440589.5 + + +def test_DateLocator(): + locator = mdates.DateLocator() + # Test nonsingular + assert locator.nonsingular(0, np.inf) == (0, 1) + assert locator.nonsingular(0, 1) == (0, 1) + assert locator.nonsingular(1, 0) == (0, 1) + assert locator.nonsingular(0, 0) == (-2, 2) + locator.create_dummy_axis() + # default values + assert locator.datalim_to_dt() == ( + datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + datetime.datetime(1970, 1, 2, 0, 0, tzinfo=datetime.timezone.utc)) + + # Check default is UTC + assert locator.tz == mdates.UTC + tz_str = 'Iceland' + iceland_tz = dateutil.tz.gettz(tz_str) + # Check not Iceland + assert locator.tz != iceland_tz + # Set it to Iceland + locator.set_tzinfo('Iceland') + # Check now it is Iceland + assert locator.tz == iceland_tz + locator.create_dummy_axis() + locator.axis.set_data_interval(*mdates.date2num(["2022-01-10", + "2022-01-08"])) + assert locator.datalim_to_dt() == ( + datetime.datetime(2022, 1, 8, 0, 0, tzinfo=iceland_tz), + datetime.datetime(2022, 1, 10, 0, 0, tzinfo=iceland_tz)) + + # Set rcParam + plt.rcParams['timezone'] = tz_str + + # Create a new one in a similar way + locator = mdates.DateLocator() + # Check now it is Iceland + assert locator.tz == iceland_tz + + # Test invalid tz values + with pytest.raises(ValueError, match="Aiceland is not a valid timezone"): + mdates.DateLocator(tz="Aiceland") + with pytest.raises(TypeError, + match="tz must be string or tzinfo subclass."): + mdates.DateLocator(tz=1) + + +def test_datestr2num(): + assert mdates.datestr2num('2022-01-10') == 19002.0 + dt = datetime.date(year=2022, month=1, day=10) + assert mdates.datestr2num('2022-01', default=dt) == 19002.0 + assert np.all(mdates.datestr2num( + ['2022-01', '2022-02'], default=dt + ) == np.array([19002., 19033.])) + assert mdates.datestr2num([]).size == 0 + assert mdates.datestr2num([], datetime.date(year=2022, + month=1, day=10)).size == 0 + + +@pytest.mark.parametrize('kwarg', + ('formats', 'zero_formats', 'offset_formats')) +def test_concise_formatter_exceptions(kwarg): + locator = mdates.AutoDateLocator() + kwargs = {kwarg: ['', '%Y']} + match = f"{kwarg} argument must be a list" + with pytest.raises(ValueError, match=match): + mdates.ConciseDateFormatter(locator, **kwargs) + + +def test_concise_formatter_call(): + locator = mdates.AutoDateLocator() + formatter = mdates.ConciseDateFormatter(locator) + assert formatter(19002.0) == '2022' + assert formatter.format_data_short(19002.0) == '2022-01-10 00:00:00' + + +def test_datetime_masked(): + # make sure that all-masked data falls back to the viewlim + # set in convert.axisinfo.... + x = np.array([datetime.datetime(2017, 1, n) for n in range(1, 6)]) + y = np.array([1, 2, 3, 4, 5]) + m = np.ma.masked_greater(y, 0) + + fig, ax = plt.subplots() + ax.plot(x, m) + assert ax.get_xlim() == (0, 1) + + +@pytest.mark.parametrize('val', (-1000000, 10000000)) +def test_num2date_error(val): + with pytest.raises(ValueError, match=f"Date ordinal {val} converts"): + mdates.num2date(val) + + +def test_num2date_roundoff(): + assert mdates.num2date(100000.0000578702) == datetime.datetime( + 2243, 10, 17, 0, 0, 4, 999980, tzinfo=datetime.timezone.utc) + # Slightly larger, steps of 20 microseconds + assert mdates.num2date(100000.0000578703) == datetime.datetime( + 2243, 10, 17, 0, 0, 5, tzinfo=datetime.timezone.utc) + + +def test_DateFormatter_settz(): + time = mdates.date2num(datetime.datetime(2011, 1, 1, 0, 0, + tzinfo=mdates.UTC)) + formatter = mdates.DateFormatter('%Y-%b-%d %H:%M') + # Default UTC + assert formatter(time) == '2011-Jan-01 00:00' + + # Set tzinfo + formatter.set_tzinfo('Pacific/Kiritimati') + assert formatter(time) == '2011-Jan-01 14:00' diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_determinism.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_determinism.py new file mode 100644 index 00000000..fe0fb34e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_determinism.py @@ -0,0 +1,138 @@ +""" +Test output reproducibility. +""" + +import os +import subprocess +import sys + +import pytest + +import matplotlib as mpl +import matplotlib.testing.compare +from matplotlib import pyplot as plt +from matplotlib.testing._markers import needs_ghostscript, needs_usetex + + +def _save_figure(objects='mhi', fmt="pdf", usetex=False): + mpl.use(fmt) + mpl.rcParams.update({'svg.hashsalt': 'asdf', 'text.usetex': usetex}) + + fig = plt.figure() + + if 'm' in objects: + # use different markers... + ax1 = fig.add_subplot(1, 6, 1) + x = range(10) + ax1.plot(x, [1] * 10, marker='D') + ax1.plot(x, [2] * 10, marker='x') + ax1.plot(x, [3] * 10, marker='^') + ax1.plot(x, [4] * 10, marker='H') + ax1.plot(x, [5] * 10, marker='v') + + if 'h' in objects: + # also use different hatch patterns + ax2 = fig.add_subplot(1, 6, 2) + bars = (ax2.bar(range(1, 5), range(1, 5)) + + ax2.bar(range(1, 5), [6] * 4, bottom=range(1, 5))) + ax2.set_xticks([1.5, 2.5, 3.5, 4.5]) + + patterns = ('-', '+', 'x', '\\', '*', 'o', 'O', '.') + for bar, pattern in zip(bars, patterns): + bar.set_hatch(pattern) + + if 'i' in objects: + # also use different images + A = [[1, 2, 3], [2, 3, 1], [3, 1, 2]] + fig.add_subplot(1, 6, 3).imshow(A, interpolation='nearest') + A = [[1, 3, 2], [1, 2, 3], [3, 1, 2]] + fig.add_subplot(1, 6, 4).imshow(A, interpolation='bilinear') + A = [[2, 3, 1], [1, 2, 3], [2, 1, 3]] + fig.add_subplot(1, 6, 5).imshow(A, interpolation='bicubic') + + x = range(5) + ax = fig.add_subplot(1, 6, 6) + ax.plot(x, x) + ax.set_title('A string $1+2+\\sigma$') + ax.set_xlabel('A string $1+2+\\sigma$') + ax.set_ylabel('A string $1+2+\\sigma$') + + stdout = getattr(sys.stdout, 'buffer', sys.stdout) + fig.savefig(stdout, format=fmt) + + +@pytest.mark.parametrize( + "objects, fmt, usetex", [ + ("", "pdf", False), + ("m", "pdf", False), + ("h", "pdf", False), + ("i", "pdf", False), + ("mhi", "pdf", False), + ("mhi", "ps", False), + pytest.param( + "mhi", "ps", True, marks=[needs_usetex, needs_ghostscript]), + ("mhi", "svg", False), + pytest.param("mhi", "svg", True, marks=needs_usetex), + ] +) +def test_determinism_check(objects, fmt, usetex): + """ + Output three times the same graphs and checks that the outputs are exactly + the same. + + Parameters + ---------- + objects : str + Objects to be included in the test document: 'm' for markers, 'h' for + hatch patterns, 'i' for images. + fmt : {"pdf", "ps", "svg"} + Output format. + """ + plots = [ + subprocess.check_output( + [sys.executable, "-R", "-c", + f"from matplotlib.tests.test_determinism import _save_figure;" + f"_save_figure({objects!r}, {fmt!r}, {usetex})"], + env={**os.environ, "SOURCE_DATE_EPOCH": "946684800", + "MPLBACKEND": "Agg"}) + for _ in range(3) + ] + for p in plots[1:]: + if fmt == "ps" and usetex: + if p != plots[0]: + pytest.skip("failed, maybe due to ghostscript timestamps") + else: + assert p == plots[0] + + +@pytest.mark.parametrize( + "fmt, string", [ + ("pdf", b"/CreationDate (D:20000101000000Z)"), + # SOURCE_DATE_EPOCH support is not tested with text.usetex, + # because the produced timestamp comes from ghostscript: + # %%CreationDate: D:20000101000000Z00\'00\', and this could change + # with another ghostscript version. + ("ps", b"%%CreationDate: Sat Jan 01 00:00:00 2000"), + ] +) +def test_determinism_source_date_epoch(fmt, string): + """ + Test SOURCE_DATE_EPOCH support. Output a document with the environment + variable SOURCE_DATE_EPOCH set to 2000-01-01 00:00 UTC and check that the + document contains the timestamp that corresponds to this date (given as an + argument). + + Parameters + ---------- + fmt : {"pdf", "ps", "svg"} + Output format. + string : bytes + Timestamp string for 2000-01-01 00:00 UTC. + """ + buf = subprocess.check_output( + [sys.executable, "-R", "-c", + f"from matplotlib.tests.test_determinism import _save_figure; " + f"_save_figure('', {fmt!r})"], + env={**os.environ, "SOURCE_DATE_EPOCH": "946684800", + "MPLBACKEND": "Agg"}) + assert string in buf diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_doc.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_doc.py new file mode 100644 index 00000000..592a2419 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_doc.py @@ -0,0 +1,34 @@ +import pytest + + +def test_sphinx_gallery_example_header(): + """ + We have copied EXAMPLE_HEADER and modified it to include meta keywords. + This test monitors that the version we have copied is still the same as + the EXAMPLE_HEADER in sphinx-gallery. If sphinx-gallery changes its + EXAMPLE_HEADER, this test will start to fail. In that case, please update + the monkey-patching of EXAMPLE_HEADER in conf.py. + """ + gen_rst = pytest.importorskip('sphinx_gallery.gen_rst') + + EXAMPLE_HEADER = """ +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "{0}" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end <sphx_glr_download_{1}>` + to download the full example code{2} + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_{1}: + +""" + assert gen_rst.EXAMPLE_HEADER == EXAMPLE_HEADER diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dviread.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dviread.py new file mode 100644 index 00000000..7b7ff151 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_dviread.py @@ -0,0 +1,77 @@ +import json +from pathlib import Path +import shutil + +import matplotlib.dviread as dr +import pytest + + +def test_PsfontsMap(monkeypatch): + monkeypatch.setattr(dr, 'find_tex_file', lambda x: x.decode()) + + filename = str(Path(__file__).parent / 'baseline_images/dviread/test.map') + fontmap = dr.PsfontsMap(filename) + # Check all properties of a few fonts + for n in [1, 2, 3, 4, 5]: + key = b'TeXfont%d' % n + entry = fontmap[key] + assert entry.texname == key + assert entry.psname == b'PSfont%d' % n + if n not in [3, 5]: + assert entry.encoding == 'font%d.enc' % n + elif n == 3: + assert entry.encoding == 'enc3.foo' + # We don't care about the encoding of TeXfont5, which specifies + # multiple encodings. + if n not in [1, 5]: + assert entry.filename == 'font%d.pfa' % n + else: + assert entry.filename == 'font%d.pfb' % n + if n == 4: + assert entry.effects == {'slant': -0.1, 'extend': 1.2} + else: + assert entry.effects == {} + # Some special cases + entry = fontmap[b'TeXfont6'] + assert entry.filename is None + assert entry.encoding is None + entry = fontmap[b'TeXfont7'] + assert entry.filename is None + assert entry.encoding == 'font7.enc' + entry = fontmap[b'TeXfont8'] + assert entry.filename == 'font8.pfb' + assert entry.encoding is None + entry = fontmap[b'TeXfont9'] + assert entry.psname == b'TeXfont9' + assert entry.filename == '/absolute/font9.pfb' + # First of duplicates only. + entry = fontmap[b'TeXfontA'] + assert entry.psname == b'PSfontA1' + # Slant/Extend only works for T1 fonts. + entry = fontmap[b'TeXfontB'] + assert entry.psname == b'PSfontB6' + # Subsetted TrueType must have encoding. + entry = fontmap[b'TeXfontC'] + assert entry.psname == b'PSfontC3' + # Missing font + with pytest.raises(LookupError, match='no-such-font'): + fontmap[b'no-such-font'] + with pytest.raises(LookupError, match='%'): + fontmap[b'%'] + + +@pytest.mark.skipif(shutil.which("kpsewhich") is None, + reason="kpsewhich is not available") +def test_dviread(): + dirpath = Path(__file__).parent / 'baseline_images/dviread' + with (dirpath / 'test.json').open() as f: + correct = json.load(f) + with dr.Dvi(str(dirpath / 'test.dvi'), None) as dvi: + data = [{'text': [[t.x, t.y, + chr(t.glyph), + t.font.texname.decode('ascii'), + round(t.font.size, 2)] + for t in page.text], + 'boxes': [[b.x, b.y, b.height, b.width] for b in page.boxes]} + for page in dvi] + assert data == correct diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_figure.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_figure.py new file mode 100644 index 00000000..6d6a3d77 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_figure.py @@ -0,0 +1,1661 @@ +import copy +from datetime import datetime +import io +from pathlib import Path +import pickle +import platform +from threading import Timer +from types import SimpleNamespace +import warnings + +import numpy as np +import pytest +from PIL import Image + +import matplotlib as mpl +from matplotlib import gridspec +from matplotlib.testing.decorators import image_comparison, check_figures_equal +from matplotlib.axes import Axes +from matplotlib.backend_bases import KeyEvent, MouseEvent +from matplotlib.figure import Figure, FigureBase +from matplotlib.layout_engine import (ConstrainedLayoutEngine, + TightLayoutEngine, + PlaceHolderLayoutEngine) +from matplotlib.ticker import AutoMinorLocator, FixedFormatter, ScalarFormatter +import matplotlib.pyplot as plt +import matplotlib.dates as mdates + + +@image_comparison(['figure_align_labels'], extensions=['png', 'svg'], + tol=0 if platform.machine() == 'x86_64' else 0.01) +def test_align_labels(): + fig = plt.figure(layout='tight') + gs = gridspec.GridSpec(3, 3) + + ax = fig.add_subplot(gs[0, :2]) + ax.plot(np.arange(0, 1e6, 1000)) + ax.set_ylabel('Ylabel0 0') + ax = fig.add_subplot(gs[0, -1]) + ax.plot(np.arange(0, 1e4, 100)) + + for i in range(3): + ax = fig.add_subplot(gs[1, i]) + ax.set_ylabel('YLabel1 %d' % i) + ax.set_xlabel('XLabel1 %d' % i) + if i in [0, 2]: + ax.xaxis.set_label_position("top") + ax.xaxis.tick_top() + if i == 0: + for tick in ax.get_xticklabels(): + tick.set_rotation(90) + if i == 2: + ax.yaxis.set_label_position("right") + ax.yaxis.tick_right() + + for i in range(3): + ax = fig.add_subplot(gs[2, i]) + ax.set_xlabel(f'XLabel2 {i}') + ax.set_ylabel(f'YLabel2 {i}') + + if i == 2: + ax.plot(np.arange(0, 1e4, 10)) + ax.yaxis.set_label_position("right") + ax.yaxis.tick_right() + for tick in ax.get_xticklabels(): + tick.set_rotation(90) + + fig.align_labels() + + +def test_align_labels_stray_axes(): + fig, axs = plt.subplots(2, 2) + for nn, ax in enumerate(axs.flat): + ax.set_xlabel('Boo') + ax.set_xlabel('Who') + ax.plot(np.arange(4)**nn, np.arange(4)**nn) + fig.align_ylabels() + fig.align_xlabels() + fig.draw_without_rendering() + xn = np.zeros(4) + yn = np.zeros(4) + for nn, ax in enumerate(axs.flat): + yn[nn] = ax.xaxis.label.get_position()[1] + xn[nn] = ax.yaxis.label.get_position()[0] + np.testing.assert_allclose(xn[:2], xn[2:]) + np.testing.assert_allclose(yn[::2], yn[1::2]) + + fig, axs = plt.subplots(2, 2, constrained_layout=True) + for nn, ax in enumerate(axs.flat): + ax.set_xlabel('Boo') + ax.set_xlabel('Who') + pc = ax.pcolormesh(np.random.randn(10, 10)) + fig.colorbar(pc, ax=ax) + fig.align_ylabels() + fig.align_xlabels() + fig.draw_without_rendering() + xn = np.zeros(4) + yn = np.zeros(4) + for nn, ax in enumerate(axs.flat): + yn[nn] = ax.xaxis.label.get_position()[1] + xn[nn] = ax.yaxis.label.get_position()[0] + np.testing.assert_allclose(xn[:2], xn[2:]) + np.testing.assert_allclose(yn[::2], yn[1::2]) + + +def test_figure_label(): + # pyplot figure creation, selection, and closing with label/number/instance + plt.close('all') + fig_today = plt.figure('today') + plt.figure(3) + plt.figure('tomorrow') + plt.figure() + plt.figure(0) + plt.figure(1) + plt.figure(3) + assert plt.get_fignums() == [0, 1, 3, 4, 5] + assert plt.get_figlabels() == ['', 'today', '', 'tomorrow', ''] + plt.close(10) + plt.close() + plt.close(5) + plt.close('tomorrow') + assert plt.get_fignums() == [0, 1] + assert plt.get_figlabels() == ['', 'today'] + plt.figure(fig_today) + assert plt.gcf() == fig_today + with pytest.raises(ValueError): + plt.figure(Figure()) + + +def test_fignum_exists(): + # pyplot figure creation, selection and closing with fignum_exists + plt.figure('one') + plt.figure(2) + plt.figure('three') + plt.figure() + assert plt.fignum_exists('one') + assert plt.fignum_exists(2) + assert plt.fignum_exists('three') + assert plt.fignum_exists(4) + plt.close('one') + plt.close(4) + assert not plt.fignum_exists('one') + assert not plt.fignum_exists(4) + + +def test_clf_keyword(): + # test if existing figure is cleared with figure() and subplots() + text1 = 'A fancy plot' + text2 = 'Really fancy!' + + fig0 = plt.figure(num=1) + fig0.suptitle(text1) + assert [t.get_text() for t in fig0.texts] == [text1] + + fig1 = plt.figure(num=1, clear=False) + fig1.text(0.5, 0.5, text2) + assert fig0 is fig1 + assert [t.get_text() for t in fig1.texts] == [text1, text2] + + fig2, ax2 = plt.subplots(2, 1, num=1, clear=True) + assert fig0 is fig2 + assert [t.get_text() for t in fig2.texts] == [] + + +@image_comparison(['figure_today']) +def test_figure(): + # named figure support + fig = plt.figure('today') + ax = fig.add_subplot() + ax.set_title(fig.get_label()) + ax.plot(np.arange(5)) + # plot red line in a different figure. + plt.figure('tomorrow') + plt.plot([0, 1], [1, 0], 'r') + # Return to the original; make sure the red line is not there. + plt.figure('today') + plt.close('tomorrow') + + +@image_comparison(['figure_legend']) +def test_figure_legend(): + fig, axs = plt.subplots(2) + axs[0].plot([0, 1], [1, 0], label='x', color='g') + axs[0].plot([0, 1], [0, 1], label='y', color='r') + axs[0].plot([0, 1], [0.5, 0.5], label='y', color='k') + + axs[1].plot([0, 1], [1, 0], label='_y', color='r') + axs[1].plot([0, 1], [0, 1], label='z', color='b') + fig.legend() + + +def test_gca(): + fig = plt.figure() + + # test that gca() picks up Axes created via add_axes() + ax0 = fig.add_axes([0, 0, 1, 1]) + assert fig.gca() is ax0 + + # test that gca() picks up Axes created via add_subplot() + ax1 = fig.add_subplot(111) + assert fig.gca() is ax1 + + # add_axes on an existing Axes should not change stored order, but will + # make it current. + fig.add_axes(ax0) + assert fig.axes == [ax0, ax1] + assert fig.gca() is ax0 + + # sca() should not change stored order of Axes, which is order added. + fig.sca(ax0) + assert fig.axes == [ax0, ax1] + + # add_subplot on an existing Axes should not change stored order, but will + # make it current. + fig.add_subplot(ax1) + assert fig.axes == [ax0, ax1] + assert fig.gca() is ax1 + + +def test_add_subplot_subclass(): + fig = plt.figure() + fig.add_subplot(axes_class=Axes) + with pytest.raises(ValueError): + fig.add_subplot(axes_class=Axes, projection="3d") + with pytest.raises(ValueError): + fig.add_subplot(axes_class=Axes, polar=True) + with pytest.raises(ValueError): + fig.add_subplot(projection="3d", polar=True) + with pytest.raises(TypeError): + fig.add_subplot(projection=42) + + +def test_add_subplot_invalid(): + fig = plt.figure() + with pytest.raises(ValueError, + match='Number of columns must be a positive integer'): + fig.add_subplot(2, 0, 1) + with pytest.raises(ValueError, + match='Number of rows must be a positive integer'): + fig.add_subplot(0, 2, 1) + with pytest.raises(ValueError, match='num must be an integer with ' + '1 <= num <= 4'): + fig.add_subplot(2, 2, 0) + with pytest.raises(ValueError, match='num must be an integer with ' + '1 <= num <= 4'): + fig.add_subplot(2, 2, 5) + with pytest.raises(ValueError, match='num must be an integer with ' + '1 <= num <= 4'): + fig.add_subplot(2, 2, 0.5) + + with pytest.raises(ValueError, match='must be a three-digit integer'): + fig.add_subplot(42) + with pytest.raises(ValueError, match='must be a three-digit integer'): + fig.add_subplot(1000) + + with pytest.raises(TypeError, match='takes 1 or 3 positional arguments ' + 'but 2 were given'): + fig.add_subplot(2, 2) + with pytest.raises(TypeError, match='takes 1 or 3 positional arguments ' + 'but 4 were given'): + fig.add_subplot(1, 2, 3, 4) + with pytest.raises(ValueError, + match="Number of rows must be a positive integer, " + "not '2'"): + fig.add_subplot('2', 2, 1) + with pytest.raises(ValueError, + match='Number of columns must be a positive integer, ' + 'not 2.0'): + fig.add_subplot(2, 2.0, 1) + _, ax = plt.subplots() + with pytest.raises(ValueError, + match='The Axes must have been created in the ' + 'present figure'): + fig.add_subplot(ax) + + +@image_comparison(['figure_suptitle']) +def test_suptitle(): + fig, _ = plt.subplots() + fig.suptitle('hello', color='r') + fig.suptitle('title', color='g', rotation=30) + + +def test_suptitle_fontproperties(): + fig, ax = plt.subplots() + fps = mpl.font_manager.FontProperties(size='large', weight='bold') + txt = fig.suptitle('fontprops title', fontproperties=fps) + assert txt.get_fontsize() == fps.get_size_in_points() + assert txt.get_weight() == fps.get_weight() + + +def test_suptitle_subfigures(): + fig = plt.figure(figsize=(4, 3)) + sf1, sf2 = fig.subfigures(1, 2) + sf2.set_facecolor('white') + sf1.subplots() + sf2.subplots() + fig.suptitle("This is a visible suptitle.") + + # verify the first subfigure facecolor is the default transparent + assert sf1.get_facecolor() == (0.0, 0.0, 0.0, 0.0) + # verify the second subfigure facecolor is white + assert sf2.get_facecolor() == (1.0, 1.0, 1.0, 1.0) + + +def test_get_suptitle_supxlabel_supylabel(): + fig, ax = plt.subplots() + assert fig.get_suptitle() == "" + assert fig.get_supxlabel() == "" + assert fig.get_supylabel() == "" + fig.suptitle('suptitle') + assert fig.get_suptitle() == 'suptitle' + fig.supxlabel('supxlabel') + assert fig.get_supxlabel() == 'supxlabel' + fig.supylabel('supylabel') + assert fig.get_supylabel() == 'supylabel' + + +@image_comparison(['alpha_background'], + # only test png and svg. The PDF output appears correct, + # but Ghostscript does not preserve the background color. + extensions=['png', 'svg'], + savefig_kwarg={'facecolor': (0, 1, 0.4), + 'edgecolor': 'none'}) +def test_alpha(): + # We want an image which has a background color and an alpha of 0.4. + fig = plt.figure(figsize=[2, 1]) + fig.set_facecolor((0, 1, 0.4)) + fig.patch.set_alpha(0.4) + fig.patches.append(mpl.patches.CirclePolygon( + [20, 20], radius=15, alpha=0.6, facecolor='red')) + + +def test_too_many_figures(): + with pytest.warns(RuntimeWarning): + for i in range(mpl.rcParams['figure.max_open_warning'] + 1): + plt.figure() + + +def test_iterability_axes_argument(): + + # This is a regression test for matplotlib/matplotlib#3196. If one of the + # arguments returned by _as_mpl_axes defines __getitem__ but is not + # iterable, this would raise an exception. This is because we check + # whether the arguments are iterable, and if so we try and convert them + # to a tuple. However, the ``iterable`` function returns True if + # __getitem__ is present, but some classes can define __getitem__ without + # being iterable. The tuple conversion is now done in a try...except in + # case it fails. + + class MyAxes(Axes): + def __init__(self, *args, myclass=None, **kwargs): + Axes.__init__(self, *args, **kwargs) + + class MyClass: + + def __getitem__(self, item): + if item != 'a': + raise ValueError("item should be a") + + def _as_mpl_axes(self): + return MyAxes, {'myclass': self} + + fig = plt.figure() + fig.add_subplot(1, 1, 1, projection=MyClass()) + plt.close(fig) + + +def test_set_fig_size(): + fig = plt.figure() + + # check figwidth + fig.set_figwidth(5) + assert fig.get_figwidth() == 5 + + # check figheight + fig.set_figheight(1) + assert fig.get_figheight() == 1 + + # check using set_size_inches + fig.set_size_inches(2, 4) + assert fig.get_figwidth() == 2 + assert fig.get_figheight() == 4 + + # check using tuple to first argument + fig.set_size_inches((1, 3)) + assert fig.get_figwidth() == 1 + assert fig.get_figheight() == 3 + + +def test_axes_remove(): + fig, axs = plt.subplots(2, 2) + axs[-1, -1].remove() + for ax in axs.ravel()[:-1]: + assert ax in fig.axes + assert axs[-1, -1] not in fig.axes + assert len(fig.axes) == 3 + + +def test_figaspect(): + w, h = plt.figaspect(np.float64(2) / np.float64(1)) + assert h / w == 2 + w, h = plt.figaspect(2) + assert h / w == 2 + w, h = plt.figaspect(np.zeros((1, 2))) + assert h / w == 0.5 + w, h = plt.figaspect(np.zeros((2, 2))) + assert h / w == 1 + + +@pytest.mark.parametrize('which', ['both', 'major', 'minor']) +def test_autofmt_xdate(which): + date = ['3 Jan 2013', '4 Jan 2013', '5 Jan 2013', '6 Jan 2013', + '7 Jan 2013', '8 Jan 2013', '9 Jan 2013', '10 Jan 2013', + '11 Jan 2013', '12 Jan 2013', '13 Jan 2013', '14 Jan 2013'] + + time = ['16:44:00', '16:45:00', '16:46:00', '16:47:00', '16:48:00', + '16:49:00', '16:51:00', '16:52:00', '16:53:00', '16:55:00', + '16:56:00', '16:57:00'] + + angle = 60 + minors = [1, 2, 3, 4, 5, 6, 7] + + x = mdates.datestr2num(date) + y = mdates.datestr2num(time) + + fig, ax = plt.subplots() + + ax.plot(x, y) + ax.yaxis_date() + ax.xaxis_date() + + ax.xaxis.set_minor_locator(AutoMinorLocator(2)) + with warnings.catch_warnings(): + warnings.filterwarnings( + 'ignore', + 'FixedFormatter should only be used together with FixedLocator') + ax.xaxis.set_minor_formatter(FixedFormatter(minors)) + + fig.autofmt_xdate(0.2, angle, 'right', which) + + if which in ('both', 'major'): + for label in fig.axes[0].get_xticklabels(False, 'major'): + assert int(label.get_rotation()) == angle + + if which in ('both', 'minor'): + for label in fig.axes[0].get_xticklabels(True, 'minor'): + assert int(label.get_rotation()) == angle + + +@mpl.style.context('default') +def test_change_dpi(): + fig = plt.figure(figsize=(4, 4)) + fig.draw_without_rendering() + assert fig.canvas.renderer.height == 400 + assert fig.canvas.renderer.width == 400 + fig.dpi = 50 + fig.draw_without_rendering() + assert fig.canvas.renderer.height == 200 + assert fig.canvas.renderer.width == 200 + + +@pytest.mark.parametrize('width, height', [ + (1, np.nan), + (-1, 1), + (np.inf, 1) +]) +def test_invalid_figure_size(width, height): + with pytest.raises(ValueError): + plt.figure(figsize=(width, height)) + + fig = plt.figure() + with pytest.raises(ValueError): + fig.set_size_inches(width, height) + + +def test_invalid_figure_add_axes(): + fig = plt.figure() + with pytest.raises(TypeError, + match="missing 1 required positional argument: 'rect'"): + fig.add_axes() + + with pytest.raises(ValueError): + fig.add_axes((.1, .1, .5, np.nan)) + + with pytest.raises(TypeError, match="multiple values for argument 'rect'"): + fig.add_axes([0, 0, 1, 1], rect=[0, 0, 1, 1]) + + fig2, ax = plt.subplots() + with pytest.raises(ValueError, + match="The Axes must have been created in the present " + "figure"): + fig.add_axes(ax) + + fig2.delaxes(ax) + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="Passing more than one positional argument"): + fig2.add_axes(ax, "extra positional argument") + + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="Passing more than one positional argument"): + fig.add_axes([0, 0, 1, 1], "extra positional argument") + + +def test_subplots_shareax_loglabels(): + fig, axs = plt.subplots(2, 2, sharex=True, sharey=True, squeeze=False) + for ax in axs.flat: + ax.plot([10, 20, 30], [10, 20, 30]) + + ax.set_yscale("log") + ax.set_xscale("log") + + for ax in axs[0, :]: + assert 0 == len(ax.xaxis.get_ticklabels(which='both')) + + for ax in axs[1, :]: + assert 0 < len(ax.xaxis.get_ticklabels(which='both')) + + for ax in axs[:, 1]: + assert 0 == len(ax.yaxis.get_ticklabels(which='both')) + + for ax in axs[:, 0]: + assert 0 < len(ax.yaxis.get_ticklabels(which='both')) + + +def test_savefig(): + fig = plt.figure() + msg = r"savefig\(\) takes 2 positional arguments but 3 were given" + with pytest.raises(TypeError, match=msg): + fig.savefig("fname1.png", "fname2.png") + + +def test_savefig_warns(): + fig = plt.figure() + for format in ['png', 'pdf', 'svg', 'tif', 'jpg']: + with pytest.raises(TypeError): + fig.savefig(io.BytesIO(), format=format, non_existent_kwarg=True) + + +def test_savefig_backend(): + fig = plt.figure() + # Intentionally use an invalid module name. + with pytest.raises(ModuleNotFoundError, match="No module named '@absent'"): + fig.savefig("test", backend="module://@absent") + with pytest.raises(ValueError, + match="The 'pdf' backend does not support png output"): + fig.savefig("test.png", backend="pdf") + + +@pytest.mark.parametrize('backend', [ + pytest.param('Agg', marks=[pytest.mark.backend('Agg')]), + pytest.param('Cairo', marks=[pytest.mark.backend('Cairo')]), +]) +def test_savefig_pixel_ratio(backend): + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + with io.BytesIO() as buf: + fig.savefig(buf, format='png') + ratio1 = Image.open(buf) + ratio1.load() + + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + fig.canvas._set_device_pixel_ratio(2) + with io.BytesIO() as buf: + fig.savefig(buf, format='png') + ratio2 = Image.open(buf) + ratio2.load() + + assert ratio1 == ratio2 + + +def test_savefig_preserve_layout_engine(): + fig = plt.figure(layout='compressed') + fig.savefig(io.BytesIO(), bbox_inches='tight') + + assert fig.get_layout_engine()._compress + + +def test_savefig_locate_colorbar(): + fig, ax = plt.subplots() + pc = ax.pcolormesh(np.random.randn(2, 2)) + cbar = fig.colorbar(pc, aspect=40) + fig.savefig(io.BytesIO(), bbox_inches=mpl.transforms.Bbox([[0, 0], [4, 4]])) + + # Check that an aspect ratio has been applied. + assert (cbar.ax.get_position(original=True).bounds != + cbar.ax.get_position(original=False).bounds) + + +@mpl.rc_context({"savefig.transparent": True}) +@check_figures_equal(extensions=["png"]) +def test_savefig_transparent(fig_test, fig_ref): + # create two transparent subfigures with corresponding transparent inset + # axes. the entire background of the image should be transparent. + gs1 = fig_test.add_gridspec(3, 3, left=0.05, wspace=0.05) + f1 = fig_test.add_subfigure(gs1[:, :]) + f2 = f1.add_subfigure(gs1[0, 0]) + + ax12 = f2.add_subplot(gs1[:, :]) + + ax1 = f1.add_subplot(gs1[:-1, :]) + iax1 = ax1.inset_axes([.1, .2, .3, .4]) + iax2 = iax1.inset_axes([.1, .2, .3, .4]) + + ax2 = fig_test.add_subplot(gs1[-1, :-1]) + ax3 = fig_test.add_subplot(gs1[-1, -1]) + + for ax in [ax12, ax1, iax1, iax2, ax2, ax3]: + ax.set(xticks=[], yticks=[]) + ax.spines[:].set_visible(False) + + +def test_figure_repr(): + fig = plt.figure(figsize=(10, 20), dpi=10) + assert repr(fig) == "<Figure size 100x200 with 0 Axes>" + + +def test_valid_layouts(): + fig = Figure(layout=None) + assert not fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(layout='tight') + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(layout='constrained') + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + + +def test_invalid_layouts(): + fig, ax = plt.subplots(layout="constrained") + with pytest.warns(UserWarning): + # this should warn, + fig.subplots_adjust(top=0.8) + assert isinstance(fig.get_layout_engine(), ConstrainedLayoutEngine) + + # Using layout + (tight|constrained)_layout warns, but the former takes + # precedence. + wst = "The Figure parameters 'layout' and 'tight_layout'" + with pytest.warns(UserWarning, match=wst): + fig = Figure(layout='tight', tight_layout=False) + assert isinstance(fig.get_layout_engine(), TightLayoutEngine) + wst = "The Figure parameters 'layout' and 'constrained_layout'" + with pytest.warns(UserWarning, match=wst): + fig = Figure(layout='constrained', constrained_layout=False) + assert not isinstance(fig.get_layout_engine(), TightLayoutEngine) + assert isinstance(fig.get_layout_engine(), ConstrainedLayoutEngine) + + with pytest.raises(ValueError, + match="Invalid value for 'layout'"): + Figure(layout='foobar') + + # test that layouts can be swapped if no colorbar: + fig, ax = plt.subplots(layout="constrained") + fig.set_layout_engine("tight") + assert isinstance(fig.get_layout_engine(), TightLayoutEngine) + fig.set_layout_engine("constrained") + assert isinstance(fig.get_layout_engine(), ConstrainedLayoutEngine) + + # test that layouts cannot be swapped if there is a colorbar: + fig, ax = plt.subplots(layout="constrained") + pc = ax.pcolormesh(np.random.randn(2, 2)) + fig.colorbar(pc) + with pytest.raises(RuntimeError, match='Colorbar layout of new layout'): + fig.set_layout_engine("tight") + fig.set_layout_engine("none") + with pytest.raises(RuntimeError, match='Colorbar layout of new layout'): + fig.set_layout_engine("tight") + + fig, ax = plt.subplots(layout="tight") + pc = ax.pcolormesh(np.random.randn(2, 2)) + fig.colorbar(pc) + with pytest.raises(RuntimeError, match='Colorbar layout of new layout'): + fig.set_layout_engine("constrained") + fig.set_layout_engine("none") + assert isinstance(fig.get_layout_engine(), PlaceHolderLayoutEngine) + + with pytest.raises(RuntimeError, match='Colorbar layout of new layout'): + fig.set_layout_engine("constrained") + + +@check_figures_equal(extensions=["png"]) +def test_tightlayout_autolayout_deconflict(fig_test, fig_ref): + for fig, autolayout in zip([fig_ref, fig_test], [False, True]): + with mpl.rc_context({'figure.autolayout': autolayout}): + axes = fig.subplots(ncols=2) + fig.tight_layout(w_pad=10) + assert isinstance(fig.get_layout_engine(), PlaceHolderLayoutEngine) + + +@pytest.mark.parametrize('layout', ['constrained', 'compressed']) +def test_layout_change_warning(layout): + """ + Raise a warning when a previously assigned layout changes to tight using + plt.tight_layout(). + """ + fig, ax = plt.subplots(layout=layout) + with pytest.warns(UserWarning, match='The figure layout has changed to'): + plt.tight_layout() + + +def test_repeated_tightlayout(): + fig = Figure() + fig.tight_layout() + # subsequent calls should not warn + fig.tight_layout() + fig.tight_layout() + + +@check_figures_equal(extensions=["png", "pdf"]) +def test_add_artist(fig_test, fig_ref): + fig_test.dpi = 100 + fig_ref.dpi = 100 + + fig_test.subplots() + l1 = plt.Line2D([.2, .7], [.7, .7], gid='l1') + l2 = plt.Line2D([.2, .7], [.8, .8], gid='l2') + r1 = plt.Circle((20, 20), 100, transform=None, gid='C1') + r2 = plt.Circle((.7, .5), .05, gid='C2') + r3 = plt.Circle((4.5, .8), .55, transform=fig_test.dpi_scale_trans, + facecolor='crimson', gid='C3') + for a in [l1, l2, r1, r2, r3]: + fig_test.add_artist(a) + l2.remove() + + ax2 = fig_ref.subplots() + l1 = plt.Line2D([.2, .7], [.7, .7], transform=fig_ref.transFigure, + gid='l1', zorder=21) + r1 = plt.Circle((20, 20), 100, transform=None, clip_on=False, zorder=20, + gid='C1') + r2 = plt.Circle((.7, .5), .05, transform=fig_ref.transFigure, gid='C2', + zorder=20) + r3 = plt.Circle((4.5, .8), .55, transform=fig_ref.dpi_scale_trans, + facecolor='crimson', clip_on=False, zorder=20, gid='C3') + for a in [l1, r1, r2, r3]: + ax2.add_artist(a) + + +@pytest.mark.parametrize("fmt", ["png", "pdf", "ps", "eps", "svg"]) +def test_fspath(fmt, tmpdir): + out = Path(tmpdir, f"test.{fmt}") + plt.savefig(out) + with out.open("rb") as file: + # All the supported formats include the format name (case-insensitive) + # in the first 100 bytes. + assert fmt.encode("ascii") in file.read(100).lower() + + +def test_tightbbox(): + fig, ax = plt.subplots() + ax.set_xlim(0, 1) + t = ax.text(1., 0.5, 'This dangles over end') + renderer = fig.canvas.get_renderer() + x1Nom0 = 9.035 # inches + assert abs(t.get_tightbbox(renderer).x1 - x1Nom0 * fig.dpi) < 2 + assert abs(ax.get_tightbbox(renderer).x1 - x1Nom0 * fig.dpi) < 2 + assert abs(fig.get_tightbbox(renderer).x1 - x1Nom0) < 0.05 + assert abs(fig.get_tightbbox(renderer).x0 - 0.679) < 0.05 + # now exclude t from the tight bbox so now the bbox is quite a bit + # smaller + t.set_in_layout(False) + x1Nom = 7.333 + assert abs(ax.get_tightbbox(renderer).x1 - x1Nom * fig.dpi) < 2 + assert abs(fig.get_tightbbox(renderer).x1 - x1Nom) < 0.05 + + t.set_in_layout(True) + x1Nom = 7.333 + assert abs(ax.get_tightbbox(renderer).x1 - x1Nom0 * fig.dpi) < 2 + # test bbox_extra_artists method... + assert abs(ax.get_tightbbox(renderer, bbox_extra_artists=[]).x1 + - x1Nom * fig.dpi) < 2 + + +def test_axes_removal(): + # Check that units can set the formatter after an Axes removal + fig, axs = plt.subplots(1, 2, sharex=True) + axs[1].remove() + axs[0].plot([datetime(2000, 1, 1), datetime(2000, 2, 1)], [0, 1]) + assert isinstance(axs[0].xaxis.get_major_formatter(), + mdates.AutoDateFormatter) + + # Check that manually setting the formatter, then removing Axes keeps + # the set formatter. + fig, axs = plt.subplots(1, 2, sharex=True) + axs[1].xaxis.set_major_formatter(ScalarFormatter()) + axs[1].remove() + axs[0].plot([datetime(2000, 1, 1), datetime(2000, 2, 1)], [0, 1]) + assert isinstance(axs[0].xaxis.get_major_formatter(), + ScalarFormatter) + + +def test_removed_axis(): + # Simple smoke test to make sure removing a shared axis works + fig, axs = plt.subplots(2, sharex=True) + axs[0].remove() + fig.canvas.draw() + + +@pytest.mark.parametrize('clear_meth', ['clear', 'clf']) +def test_figure_clear(clear_meth): + # we test the following figure clearing scenarios: + fig = plt.figure() + + # a) an empty figure + fig.clear() + assert fig.axes == [] + + # b) a figure with a single unnested axes + ax = fig.add_subplot(111) + getattr(fig, clear_meth)() + assert fig.axes == [] + + # c) a figure multiple unnested axes + axes = [fig.add_subplot(2, 1, i+1) for i in range(2)] + getattr(fig, clear_meth)() + assert fig.axes == [] + + # d) a figure with a subfigure + gs = fig.add_gridspec(ncols=2, nrows=1) + subfig = fig.add_subfigure(gs[0]) + subaxes = subfig.add_subplot(111) + getattr(fig, clear_meth)() + assert subfig not in fig.subfigs + assert fig.axes == [] + + # e) a figure with a subfigure and a subplot + subfig = fig.add_subfigure(gs[0]) + subaxes = subfig.add_subplot(111) + mainaxes = fig.add_subplot(gs[1]) + + # e.1) removing just the axes leaves the subplot + mainaxes.remove() + assert fig.axes == [subaxes] + + # e.2) removing just the subaxes leaves the subplot + # and subfigure + mainaxes = fig.add_subplot(gs[1]) + subaxes.remove() + assert fig.axes == [mainaxes] + assert subfig in fig.subfigs + + # e.3) clearing the subfigure leaves the subplot + subaxes = subfig.add_subplot(111) + assert mainaxes in fig.axes + assert subaxes in fig.axes + getattr(subfig, clear_meth)() + assert subfig in fig.subfigs + assert subaxes not in subfig.axes + assert subaxes not in fig.axes + assert mainaxes in fig.axes + + # e.4) clearing the whole thing + subaxes = subfig.add_subplot(111) + getattr(fig, clear_meth)() + assert fig.axes == [] + assert fig.subfigs == [] + + # f) multiple subfigures + subfigs = [fig.add_subfigure(gs[i]) for i in [0, 1]] + subaxes = [sfig.add_subplot(111) for sfig in subfigs] + assert all(ax in fig.axes for ax in subaxes) + assert all(sfig in fig.subfigs for sfig in subfigs) + + # f.1) clearing only one subfigure + getattr(subfigs[0], clear_meth)() + assert subaxes[0] not in fig.axes + assert subaxes[1] in fig.axes + assert subfigs[1] in fig.subfigs + + # f.2) clearing the whole thing + getattr(subfigs[1], clear_meth)() + subfigs = [fig.add_subfigure(gs[i]) for i in [0, 1]] + subaxes = [sfig.add_subplot(111) for sfig in subfigs] + assert all(ax in fig.axes for ax in subaxes) + assert all(sfig in fig.subfigs for sfig in subfigs) + getattr(fig, clear_meth)() + assert fig.subfigs == [] + assert fig.axes == [] + + +def test_clf_not_redefined(): + for klass in FigureBase.__subclasses__(): + # check that subclasses do not get redefined in our Figure subclasses + assert 'clf' not in klass.__dict__ + + +@mpl.style.context('mpl20') +def test_picking_does_not_stale(): + fig, ax = plt.subplots() + ax.scatter([0], [0], [1000], picker=True) + fig.canvas.draw() + assert not fig.stale + + mouse_event = SimpleNamespace(x=ax.bbox.x0 + ax.bbox.width / 2, + y=ax.bbox.y0 + ax.bbox.height / 2, + inaxes=ax, guiEvent=None) + fig.pick(mouse_event) + assert not fig.stale + + +def test_add_subplot_twotuple(): + fig = plt.figure() + ax1 = fig.add_subplot(3, 2, (3, 5)) + assert ax1.get_subplotspec().rowspan == range(1, 3) + assert ax1.get_subplotspec().colspan == range(0, 1) + ax2 = fig.add_subplot(3, 2, (4, 6)) + assert ax2.get_subplotspec().rowspan == range(1, 3) + assert ax2.get_subplotspec().colspan == range(1, 2) + ax3 = fig.add_subplot(3, 2, (3, 6)) + assert ax3.get_subplotspec().rowspan == range(1, 3) + assert ax3.get_subplotspec().colspan == range(0, 2) + ax4 = fig.add_subplot(3, 2, (4, 5)) + assert ax4.get_subplotspec().rowspan == range(1, 3) + assert ax4.get_subplotspec().colspan == range(0, 2) + with pytest.raises(IndexError): + fig.add_subplot(3, 2, (6, 3)) + + +@image_comparison(['tightbbox_box_aspect.svg'], style='mpl20', + savefig_kwarg={'bbox_inches': 'tight', + 'facecolor': 'teal'}, + remove_text=True) +def test_tightbbox_box_aspect(): + fig = plt.figure() + gs = fig.add_gridspec(1, 2) + ax1 = fig.add_subplot(gs[0, 0]) + ax2 = fig.add_subplot(gs[0, 1], projection='3d') + ax1.set_box_aspect(.5) + ax2.set_box_aspect((2, 1, 1)) + + +@check_figures_equal(extensions=["svg", "pdf", "eps", "png"]) +def test_animated_with_canvas_change(fig_test, fig_ref): + ax_ref = fig_ref.subplots() + ax_ref.plot(range(5)) + + ax_test = fig_test.subplots() + ax_test.plot(range(5), animated=True) + + +class TestSubplotMosaic: + @check_figures_equal(extensions=["png"]) + @pytest.mark.parametrize( + "x", [ + [["A", "A", "B"], ["C", "D", "B"]], + [[1, 1, 2], [3, 4, 2]], + (("A", "A", "B"), ("C", "D", "B")), + ((1, 1, 2), (3, 4, 2)) + ] + ) + def test_basic(self, fig_test, fig_ref, x): + grid_axes = fig_test.subplot_mosaic(x) + + for k, ax in grid_axes.items(): + ax.set_title(k) + + labels = sorted(np.unique(x)) + + assert len(labels) == len(grid_axes) + + gs = fig_ref.add_gridspec(2, 3) + axA = fig_ref.add_subplot(gs[:1, :2]) + axA.set_title(labels[0]) + + axB = fig_ref.add_subplot(gs[:, 2]) + axB.set_title(labels[1]) + + axC = fig_ref.add_subplot(gs[1, 0]) + axC.set_title(labels[2]) + + axD = fig_ref.add_subplot(gs[1, 1]) + axD.set_title(labels[3]) + + @check_figures_equal(extensions=["png"]) + def test_all_nested(self, fig_test, fig_ref): + x = [["A", "B"], ["C", "D"]] + y = [["E", "F"], ["G", "H"]] + + fig_ref.set_layout_engine("constrained") + fig_test.set_layout_engine("constrained") + + grid_axes = fig_test.subplot_mosaic([[x, y]]) + for ax in grid_axes.values(): + ax.set_title(ax.get_label()) + + gs = fig_ref.add_gridspec(1, 2) + gs_left = gs[0, 0].subgridspec(2, 2) + for j, r in enumerate(x): + for k, label in enumerate(r): + fig_ref.add_subplot(gs_left[j, k]).set_title(label) + + gs_right = gs[0, 1].subgridspec(2, 2) + for j, r in enumerate(y): + for k, label in enumerate(r): + fig_ref.add_subplot(gs_right[j, k]).set_title(label) + + @check_figures_equal(extensions=["png"]) + def test_nested(self, fig_test, fig_ref): + + fig_ref.set_layout_engine("constrained") + fig_test.set_layout_engine("constrained") + + x = [["A", "B"], ["C", "D"]] + + y = [["F"], [x]] + + grid_axes = fig_test.subplot_mosaic(y) + + for k, ax in grid_axes.items(): + ax.set_title(k) + + gs = fig_ref.add_gridspec(2, 1) + + gs_n = gs[1, 0].subgridspec(2, 2) + + axA = fig_ref.add_subplot(gs_n[0, 0]) + axA.set_title("A") + + axB = fig_ref.add_subplot(gs_n[0, 1]) + axB.set_title("B") + + axC = fig_ref.add_subplot(gs_n[1, 0]) + axC.set_title("C") + + axD = fig_ref.add_subplot(gs_n[1, 1]) + axD.set_title("D") + + axF = fig_ref.add_subplot(gs[0, 0]) + axF.set_title("F") + + @check_figures_equal(extensions=["png"]) + def test_nested_tuple(self, fig_test, fig_ref): + x = [["A", "B", "B"], ["C", "C", "D"]] + xt = (("A", "B", "B"), ("C", "C", "D")) + + fig_ref.subplot_mosaic([["F"], [x]]) + fig_test.subplot_mosaic([["F"], [xt]]) + + def test_nested_width_ratios(self): + x = [["A", [["B"], + ["C"]]]] + width_ratios = [2, 1] + + fig, axd = plt.subplot_mosaic(x, width_ratios=width_ratios) + + assert axd["A"].get_gridspec().get_width_ratios() == width_ratios + assert axd["B"].get_gridspec().get_width_ratios() != width_ratios + + def test_nested_height_ratios(self): + x = [["A", [["B"], + ["C"]]], ["D", "D"]] + height_ratios = [1, 2] + + fig, axd = plt.subplot_mosaic(x, height_ratios=height_ratios) + + assert axd["D"].get_gridspec().get_height_ratios() == height_ratios + assert axd["B"].get_gridspec().get_height_ratios() != height_ratios + + @check_figures_equal(extensions=["png"]) + @pytest.mark.parametrize( + "x, empty_sentinel", + [ + ([["A", None], [None, "B"]], None), + ([["A", "."], [".", "B"]], "SKIP"), + ([["A", 0], [0, "B"]], 0), + ([[1, None], [None, 2]], None), + ([[1, "."], [".", 2]], "SKIP"), + ([[1, 0], [0, 2]], 0), + ], + ) + def test_empty(self, fig_test, fig_ref, x, empty_sentinel): + if empty_sentinel != "SKIP": + kwargs = {"empty_sentinel": empty_sentinel} + else: + kwargs = {} + grid_axes = fig_test.subplot_mosaic(x, **kwargs) + + for k, ax in grid_axes.items(): + ax.set_title(k) + + labels = sorted( + {name for row in x for name in row} - {empty_sentinel, "."} + ) + + assert len(labels) == len(grid_axes) + + gs = fig_ref.add_gridspec(2, 2) + axA = fig_ref.add_subplot(gs[0, 0]) + axA.set_title(labels[0]) + + axB = fig_ref.add_subplot(gs[1, 1]) + axB.set_title(labels[1]) + + def test_fail_list_of_str(self): + with pytest.raises(ValueError, match='must be 2D'): + plt.subplot_mosaic(['foo', 'bar']) + with pytest.raises(ValueError, match='must be 2D'): + plt.subplot_mosaic(['foo']) + with pytest.raises(ValueError, match='must be 2D'): + plt.subplot_mosaic([['foo', ('bar',)]]) + with pytest.raises(ValueError, match='must be 2D'): + plt.subplot_mosaic([['a', 'b'], [('a', 'b'), 'c']]) + + @check_figures_equal(extensions=["png"]) + @pytest.mark.parametrize("subplot_kw", [{}, {"projection": "polar"}, None]) + def test_subplot_kw(self, fig_test, fig_ref, subplot_kw): + x = [[1, 2]] + grid_axes = fig_test.subplot_mosaic(x, subplot_kw=subplot_kw) + subplot_kw = subplot_kw or {} + + gs = fig_ref.add_gridspec(1, 2) + axA = fig_ref.add_subplot(gs[0, 0], **subplot_kw) + + axB = fig_ref.add_subplot(gs[0, 1], **subplot_kw) + + @check_figures_equal(extensions=["png"]) + @pytest.mark.parametrize("multi_value", ['BC', tuple('BC')]) + def test_per_subplot_kw(self, fig_test, fig_ref, multi_value): + x = 'AB;CD' + grid_axes = fig_test.subplot_mosaic( + x, + subplot_kw={'facecolor': 'red'}, + per_subplot_kw={ + 'D': {'facecolor': 'blue'}, + multi_value: {'facecolor': 'green'}, + } + ) + + gs = fig_ref.add_gridspec(2, 2) + for color, spec in zip(['red', 'green', 'green', 'blue'], gs): + fig_ref.add_subplot(spec, facecolor=color) + + def test_string_parser(self): + normalize = Figure._normalize_grid_string + + assert normalize('ABC') == [['A', 'B', 'C']] + assert normalize('AB;CC') == [['A', 'B'], ['C', 'C']] + assert normalize('AB;CC;DE') == [['A', 'B'], ['C', 'C'], ['D', 'E']] + assert normalize(""" + ABC + """) == [['A', 'B', 'C']] + assert normalize(""" + AB + CC + """) == [['A', 'B'], ['C', 'C']] + assert normalize(""" + AB + CC + DE + """) == [['A', 'B'], ['C', 'C'], ['D', 'E']] + + def test_per_subplot_kw_expander(self): + normalize = Figure._norm_per_subplot_kw + assert normalize({"A": {}, "B": {}}) == {"A": {}, "B": {}} + assert normalize({("A", "B"): {}}) == {"A": {}, "B": {}} + with pytest.raises( + ValueError, match=f'The key {"B"!r} appears multiple times' + ): + normalize({("A", "B"): {}, "B": {}}) + with pytest.raises( + ValueError, match=f'The key {"B"!r} appears multiple times' + ): + normalize({"B": {}, ("A", "B"): {}}) + + def test_extra_per_subplot_kw(self): + with pytest.raises( + ValueError, match=f'The keys {set("B")!r} are in' + ): + Figure().subplot_mosaic("A", per_subplot_kw={"B": {}}) + + @check_figures_equal(extensions=["png"]) + @pytest.mark.parametrize("str_pattern", + ["AAA\nBBB", "\nAAA\nBBB\n", "ABC\nDEF"] + ) + def test_single_str_input(self, fig_test, fig_ref, str_pattern): + grid_axes = fig_test.subplot_mosaic(str_pattern) + + grid_axes = fig_ref.subplot_mosaic( + [list(ln) for ln in str_pattern.strip().split("\n")] + ) + + @pytest.mark.parametrize( + "x,match", + [ + ( + [["A", "."], [".", "A"]], + ( + "(?m)we found that the label .A. specifies a " + + "non-rectangular or non-contiguous area." + ), + ), + ( + [["A", "B"], [None, [["A", "B"], ["C", "D"]]]], + "There are duplicate keys .* between the outer layout", + ), + ("AAA\nc\nBBB", "All of the rows must be the same length"), + ( + [["A", [["B", "C"], ["D"]]], ["E", "E"]], + "All of the rows must be the same length", + ), + ], + ) + def test_fail(self, x, match): + fig = plt.figure() + with pytest.raises(ValueError, match=match): + fig.subplot_mosaic(x) + + @check_figures_equal(extensions=["png"]) + def test_hashable_keys(self, fig_test, fig_ref): + fig_test.subplot_mosaic([[object(), object()]]) + fig_ref.subplot_mosaic([["A", "B"]]) + + @pytest.mark.parametrize('str_pattern', + ['abc', 'cab', 'bca', 'cba', 'acb', 'bac']) + def test_user_order(self, str_pattern): + fig = plt.figure() + ax_dict = fig.subplot_mosaic(str_pattern) + assert list(str_pattern) == list(ax_dict) + assert list(fig.axes) == list(ax_dict.values()) + + def test_nested_user_order(self): + layout = [ + ["A", [["B", "C"], + ["D", "E"]]], + ["F", "G"], + [".", [["H", [["I"], + ["."]]]]] + ] + + fig = plt.figure() + ax_dict = fig.subplot_mosaic(layout) + assert list(ax_dict) == list("ABCDEFGHI") + assert list(fig.axes) == list(ax_dict.values()) + + def test_share_all(self): + layout = [ + ["A", [["B", "C"], + ["D", "E"]]], + ["F", "G"], + [".", [["H", [["I"], + ["."]]]]] + ] + fig = plt.figure() + ax_dict = fig.subplot_mosaic(layout, sharex=True, sharey=True) + ax_dict["A"].set(xscale="log", yscale="logit") + assert all(ax.get_xscale() == "log" and ax.get_yscale() == "logit" + for ax in ax_dict.values()) + + +def test_reused_gridspec(): + """Test that these all use the same gridspec""" + fig = plt.figure() + ax1 = fig.add_subplot(3, 2, (3, 5)) + ax2 = fig.add_subplot(3, 2, 4) + ax3 = plt.subplot2grid((3, 2), (2, 1), colspan=2, fig=fig) + + gs1 = ax1.get_subplotspec().get_gridspec() + gs2 = ax2.get_subplotspec().get_gridspec() + gs3 = ax3.get_subplotspec().get_gridspec() + + assert gs1 == gs2 + assert gs1 == gs3 + + +@image_comparison(['test_subfigure.png'], style='mpl20', + savefig_kwarg={'facecolor': 'teal'}) +def test_subfigure(): + np.random.seed(19680801) + fig = plt.figure(layout='constrained') + sub = fig.subfigures(1, 2) + + axs = sub[0].subplots(2, 2) + for ax in axs.flat: + pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2, vmax=2) + sub[0].colorbar(pc, ax=axs) + sub[0].suptitle('Left Side') + sub[0].set_facecolor('white') + + axs = sub[1].subplots(1, 3) + for ax in axs.flat: + pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2, vmax=2) + sub[1].colorbar(pc, ax=axs, location='bottom') + sub[1].suptitle('Right Side') + sub[1].set_facecolor('white') + + fig.suptitle('Figure suptitle', fontsize='xx-large') + + +def test_subfigure_tightbbox(): + # test that we can get the tightbbox with a subfigure... + fig = plt.figure(layout='constrained') + sub = fig.subfigures(1, 2) + + np.testing.assert_allclose( + fig.get_tightbbox(fig.canvas.get_renderer()).width, + 8.0) + + +def test_subfigure_dpi(): + fig = plt.figure(dpi=100) + sub_fig = fig.subfigures() + assert sub_fig.get_dpi() == fig.get_dpi() + + sub_fig.set_dpi(200) + assert sub_fig.get_dpi() == 200 + assert fig.get_dpi() == 200 + + +@image_comparison(['test_subfigure_ss.png'], style='mpl20', + savefig_kwarg={'facecolor': 'teal'}, tol=0.02) +def test_subfigure_ss(): + # test assigning the subfigure via subplotspec + np.random.seed(19680801) + fig = plt.figure(layout='constrained') + gs = fig.add_gridspec(1, 2) + + sub = fig.add_subfigure(gs[0], facecolor='pink') + + axs = sub.subplots(2, 2) + for ax in axs.flat: + pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2, vmax=2) + sub.colorbar(pc, ax=axs) + sub.suptitle('Left Side') + + ax = fig.add_subplot(gs[1]) + ax.plot(np.arange(20)) + ax.set_title('Axes') + + fig.suptitle('Figure suptitle', fontsize='xx-large') + + +@image_comparison(['test_subfigure_double.png'], style='mpl20', + savefig_kwarg={'facecolor': 'teal'}) +def test_subfigure_double(): + # test assigning the subfigure via subplotspec + np.random.seed(19680801) + + fig = plt.figure(layout='constrained', figsize=(10, 8)) + + fig.suptitle('fig') + + subfigs = fig.subfigures(1, 2, wspace=0.07) + + subfigs[0].set_facecolor('coral') + subfigs[0].suptitle('subfigs[0]') + + subfigs[1].set_facecolor('coral') + subfigs[1].suptitle('subfigs[1]') + + subfigsnest = subfigs[0].subfigures(2, 1, height_ratios=[1, 1.4]) + subfigsnest[0].suptitle('subfigsnest[0]') + subfigsnest[0].set_facecolor('r') + axsnest0 = subfigsnest[0].subplots(1, 2, sharey=True) + for ax in axsnest0: + fontsize = 12 + pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2.5, vmax=2.5) + ax.set_xlabel('x-label', fontsize=fontsize) + ax.set_ylabel('y-label', fontsize=fontsize) + ax.set_title('Title', fontsize=fontsize) + + subfigsnest[0].colorbar(pc, ax=axsnest0) + + subfigsnest[1].suptitle('subfigsnest[1]') + subfigsnest[1].set_facecolor('g') + axsnest1 = subfigsnest[1].subplots(3, 1, sharex=True) + for nn, ax in enumerate(axsnest1): + ax.set_ylabel(f'ylabel{nn}') + subfigsnest[1].supxlabel('supxlabel') + subfigsnest[1].supylabel('supylabel') + + axsRight = subfigs[1].subplots(2, 2) + + +def test_subfigure_spanning(): + # test that subfigures get laid out properly... + fig = plt.figure(constrained_layout=True) + gs = fig.add_gridspec(3, 3) + sub_figs = [ + fig.add_subfigure(gs[0, 0]), + fig.add_subfigure(gs[0:2, 1]), + fig.add_subfigure(gs[2, 1:3]), + fig.add_subfigure(gs[0:, 1:]) + ] + + w = 640 + h = 480 + np.testing.assert_allclose(sub_figs[0].bbox.min, [0., h * 2/3]) + np.testing.assert_allclose(sub_figs[0].bbox.max, [w / 3, h]) + + np.testing.assert_allclose(sub_figs[1].bbox.min, [w / 3, h / 3]) + np.testing.assert_allclose(sub_figs[1].bbox.max, [w * 2/3, h]) + + np.testing.assert_allclose(sub_figs[2].bbox.min, [w / 3, 0]) + np.testing.assert_allclose(sub_figs[2].bbox.max, [w, h / 3]) + + # check here that slicing actually works. Last sub_fig + # with open slices failed, but only on draw... + for i in range(4): + sub_figs[i].add_subplot() + fig.draw_without_rendering() + + +@mpl.style.context('mpl20') +def test_subfigure_ticks(): + # This tests a tick-spacing error that only seems applicable + # when the subfigures are saved to file. It is very hard to replicate + fig = plt.figure(constrained_layout=True, figsize=(10, 3)) + # create left/right subfigs nested in bottom subfig + (subfig_bl, subfig_br) = fig.subfigures(1, 2, wspace=0.01, + width_ratios=[7, 2]) + + # put ax1-ax3 in gridspec of bottom-left subfig + gs = subfig_bl.add_gridspec(nrows=1, ncols=14) + + ax1 = subfig_bl.add_subplot(gs[0, :1]) + ax1.scatter(x=[-56.46881504821776, 24.179891162109396], y=[1500, 3600]) + + ax2 = subfig_bl.add_subplot(gs[0, 1:3], sharey=ax1) + ax2.scatter(x=[-126.5357270050049, 94.68456736755368], y=[1500, 3600]) + ax3 = subfig_bl.add_subplot(gs[0, 3:14], sharey=ax1) + + fig.dpi = 120 + fig.draw_without_rendering() + ticks120 = ax2.get_xticks() + fig.dpi = 300 + fig.draw_without_rendering() + ticks300 = ax2.get_xticks() + np.testing.assert_allclose(ticks120, ticks300) + + +@image_comparison(['test_subfigure_scatter_size.png'], style='mpl20', + remove_text=True) +def test_subfigure_scatter_size(): + # markers in the left- and right-most subplots should be the same + fig = plt.figure() + gs = fig.add_gridspec(1, 2) + ax0 = fig.add_subplot(gs[1]) + ax0.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s') + ax0.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s') + + sfig = fig.add_subfigure(gs[0]) + axs = sfig.subplots(1, 2) + for ax in [ax0, axs[0]]: + ax.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s', color='r') + ax.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s', color='g') + + +def test_subfigure_pdf(): + fig = plt.figure(layout='constrained') + sub_fig = fig.subfigures() + ax = sub_fig.add_subplot(111) + b = ax.bar(1, 1) + ax.bar_label(b) + buffer = io.BytesIO() + fig.savefig(buffer, format='pdf') + + +def test_subfigures_wspace_hspace(): + sub_figs = plt.figure().subfigures(2, 3, hspace=0.5, wspace=1/6.) + + w = 640 + h = 480 + + np.testing.assert_allclose(sub_figs[0, 0].bbox.min, [0., h * 0.6]) + np.testing.assert_allclose(sub_figs[0, 0].bbox.max, [w * 0.3, h]) + + np.testing.assert_allclose(sub_figs[0, 1].bbox.min, [w * 0.35, h * 0.6]) + np.testing.assert_allclose(sub_figs[0, 1].bbox.max, [w * 0.65, h]) + + np.testing.assert_allclose(sub_figs[0, 2].bbox.min, [w * 0.7, h * 0.6]) + np.testing.assert_allclose(sub_figs[0, 2].bbox.max, [w, h]) + + np.testing.assert_allclose(sub_figs[1, 0].bbox.min, [0, 0]) + np.testing.assert_allclose(sub_figs[1, 0].bbox.max, [w * 0.3, h * 0.4]) + + np.testing.assert_allclose(sub_figs[1, 1].bbox.min, [w * 0.35, 0]) + np.testing.assert_allclose(sub_figs[1, 1].bbox.max, [w * 0.65, h * 0.4]) + + np.testing.assert_allclose(sub_figs[1, 2].bbox.min, [w * 0.7, 0]) + np.testing.assert_allclose(sub_figs[1, 2].bbox.max, [w, h * 0.4]) + + +def test_add_subplot_kwargs(): + # fig.add_subplot() always creates new axes, even if axes kwargs differ. + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + ax1 = fig.add_subplot(1, 1, 1) + assert ax is not None + assert ax1 is not ax + plt.close() + + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='polar') + ax1 = fig.add_subplot(1, 1, 1, projection='polar') + assert ax is not None + assert ax1 is not ax + plt.close() + + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='polar') + ax1 = fig.add_subplot(1, 1, 1) + assert ax is not None + assert ax1.name == 'rectilinear' + assert ax1 is not ax + plt.close() + + +def test_add_axes_kwargs(): + # fig.add_axes() always creates new axes, even if axes kwargs differ. + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1]) + ax1 = fig.add_axes([0, 0, 1, 1]) + assert ax is not None + assert ax1 is not ax + plt.close() + + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1], projection='polar') + ax1 = fig.add_axes([0, 0, 1, 1], projection='polar') + assert ax is not None + assert ax1 is not ax + plt.close() + + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1], projection='polar') + ax1 = fig.add_axes([0, 0, 1, 1]) + assert ax is not None + assert ax1.name == 'rectilinear' + assert ax1 is not ax + plt.close() + + +def test_ginput(recwarn): # recwarn undoes warn filters at exit. + warnings.filterwarnings("ignore", "cannot show the figure") + fig, ax = plt.subplots() + trans = ax.transData.transform + + def single_press(): + MouseEvent("button_press_event", fig.canvas, *trans((.1, .2)), 1)._process() + + Timer(.1, single_press).start() + assert fig.ginput() == [(.1, .2)] + + def multi_presses(): + MouseEvent("button_press_event", fig.canvas, *trans((.1, .2)), 1)._process() + KeyEvent("key_press_event", fig.canvas, "backspace")._process() + MouseEvent("button_press_event", fig.canvas, *trans((.3, .4)), 1)._process() + MouseEvent("button_press_event", fig.canvas, *trans((.5, .6)), 1)._process() + MouseEvent("button_press_event", fig.canvas, *trans((0, 0)), 2)._process() + + Timer(.1, multi_presses).start() + np.testing.assert_allclose(fig.ginput(3), [(.3, .4), (.5, .6)]) + + +def test_waitforbuttonpress(recwarn): # recwarn undoes warn filters at exit. + warnings.filterwarnings("ignore", "cannot show the figure") + fig = plt.figure() + assert fig.waitforbuttonpress(timeout=.1) is None + Timer(.1, KeyEvent("key_press_event", fig.canvas, "z")._process).start() + assert fig.waitforbuttonpress() is True + Timer(.1, MouseEvent("button_press_event", fig.canvas, 0, 0, 1)._process).start() + assert fig.waitforbuttonpress() is False + + +def test_kwargs_pass(): + fig = Figure(label='whole Figure') + sub_fig = fig.subfigures(1, 1, label='sub figure') + + assert fig.get_label() == 'whole Figure' + assert sub_fig.get_label() == 'sub figure' + + +@check_figures_equal(extensions=["png"]) +def test_rcparams(fig_test, fig_ref): + fig_ref.supxlabel("xlabel", weight='bold', size=15) + fig_ref.supylabel("ylabel", weight='bold', size=15) + fig_ref.suptitle("Title", weight='light', size=20) + with mpl.rc_context({'figure.labelweight': 'bold', + 'figure.labelsize': 15, + 'figure.titleweight': 'light', + 'figure.titlesize': 20}): + fig_test.supxlabel("xlabel") + fig_test.supylabel("ylabel") + fig_test.suptitle("Title") + + +def test_deepcopy(): + fig1, ax = plt.subplots() + ax.plot([0, 1], [2, 3]) + ax.set_yscale('log') + + fig2 = copy.deepcopy(fig1) + + # Make sure it is a new object + assert fig2.axes[0] is not ax + # And that the axis scale got propagated + assert fig2.axes[0].get_yscale() == 'log' + # Update the deepcopy and check the original isn't modified + fig2.axes[0].set_yscale('linear') + assert ax.get_yscale() == 'log' + + # And test the limits of the axes don't get propagated + ax.set_xlim(1e-1, 1e2) + # Draw these to make sure limits are updated + fig1.draw_without_rendering() + fig2.draw_without_rendering() + + assert ax.get_xlim() == (1e-1, 1e2) + assert fig2.axes[0].get_xlim() == (0, 1) + + +def test_unpickle_with_device_pixel_ratio(): + fig = Figure(dpi=42) + fig.canvas._set_device_pixel_ratio(7) + assert fig.dpi == 42*7 + fig2 = pickle.loads(pickle.dumps(fig)) + assert fig2.dpi == 42 + + +def test_gridspec_no_mutate_input(): + gs = {'left': .1} + gs_orig = dict(gs) + plt.subplots(1, 2, width_ratios=[1, 2], gridspec_kw=gs) + assert gs == gs_orig + plt.subplot_mosaic('AB', width_ratios=[1, 2], gridspec_kw=gs) + + +@pytest.mark.parametrize('fmt', ['eps', 'pdf', 'png', 'ps', 'svg', 'svgz']) +def test_savefig_metadata(fmt): + Figure().savefig(io.BytesIO(), format=fmt, metadata={}) + + +@pytest.mark.parametrize('fmt', ['jpeg', 'jpg', 'tif', 'tiff', 'webp', "raw", "rgba"]) +def test_savefig_metadata_error(fmt): + with pytest.raises(ValueError, match="metadata not supported"): + Figure().savefig(io.BytesIO(), format=fmt, metadata={}) + + +def test_get_constrained_layout_pads(): + params = {'w_pad': 0.01, 'h_pad': 0.02, 'wspace': 0.03, 'hspace': 0.04} + expected = tuple([*params.values()]) + fig = plt.figure(layout=mpl.layout_engine.ConstrainedLayoutEngine(**params)) + with pytest.warns(PendingDeprecationWarning, match="will be deprecated"): + assert fig.get_constrained_layout_pads() == expected + + +def test_not_visible_figure(): + fig = Figure() + + buf = io.StringIO() + fig.savefig(buf, format='svg') + buf.seek(0) + assert '<g ' in buf.read() + + fig.set_visible(False) + buf = io.StringIO() + fig.savefig(buf, format='svg') + buf.seek(0) + assert '<g ' not in buf.read() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_font_manager.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_font_manager.py new file mode 100644 index 00000000..ec901452 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_font_manager.py @@ -0,0 +1,348 @@ +from io import BytesIO, StringIO +import gc +import multiprocessing +import os +from pathlib import Path +from PIL import Image +import shutil +import subprocess +import sys +import warnings + +import numpy as np +import pytest + +from matplotlib.font_manager import ( + findfont, findSystemFonts, FontEntry, FontProperties, fontManager, + json_dump, json_load, get_font, is_opentype_cff_font, + MSUserFontDirectories, _get_fontconfig_fonts, ttfFontProperty) +from matplotlib import cbook, ft2font, pyplot as plt, rc_context, figure as mfigure + +has_fclist = shutil.which('fc-list') is not None + + +def test_font_priority(): + with rc_context(rc={ + 'font.sans-serif': + ['cmmi10', 'Bitstream Vera Sans']}): + fontfile = findfont(FontProperties(family=["sans-serif"])) + assert Path(fontfile).name == 'cmmi10.ttf' + + # Smoketest get_charmap, which isn't used internally anymore + font = get_font(fontfile) + cmap = font.get_charmap() + assert len(cmap) == 131 + assert cmap[8729] == 30 + + +def test_score_weight(): + assert 0 == fontManager.score_weight("regular", "regular") + assert 0 == fontManager.score_weight("bold", "bold") + assert (0 < fontManager.score_weight(400, 400) < + fontManager.score_weight("normal", "bold")) + assert (0 < fontManager.score_weight("normal", "regular") < + fontManager.score_weight("normal", "bold")) + assert (fontManager.score_weight("normal", "regular") == + fontManager.score_weight(400, 400)) + + +def test_json_serialization(tmpdir): + # Can't open a NamedTemporaryFile twice on Windows, so use a temporary + # directory instead. + path = Path(tmpdir, "fontlist.json") + json_dump(fontManager, path) + copy = json_load(path) + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', 'findfont: Font family.*not found') + for prop in ({'family': 'STIXGeneral'}, + {'family': 'Bitstream Vera Sans', 'weight': 700}, + {'family': 'no such font family'}): + fp = FontProperties(**prop) + assert (fontManager.findfont(fp, rebuild_if_missing=False) == + copy.findfont(fp, rebuild_if_missing=False)) + + +def test_otf(): + fname = '/usr/share/fonts/opentype/freefont/FreeMono.otf' + if Path(fname).exists(): + assert is_opentype_cff_font(fname) + for f in fontManager.ttflist: + if 'otf' in f.fname: + with open(f.fname, 'rb') as fd: + res = fd.read(4) == b'OTTO' + assert res == is_opentype_cff_font(f.fname) + + +@pytest.mark.skipif(sys.platform == "win32" or not has_fclist, + reason='no fontconfig installed') +def test_get_fontconfig_fonts(): + assert len(_get_fontconfig_fonts()) > 1 + + +@pytest.mark.parametrize('factor', [2, 4, 6, 8]) +def test_hinting_factor(factor): + font = findfont(FontProperties(family=["sans-serif"])) + + font1 = get_font(font, hinting_factor=1) + font1.clear() + font1.set_size(12, 100) + font1.set_text('abc') + expected = font1.get_width_height() + + hinted_font = get_font(font, hinting_factor=factor) + hinted_font.clear() + hinted_font.set_size(12, 100) + hinted_font.set_text('abc') + # Check that hinting only changes text layout by a small (10%) amount. + np.testing.assert_allclose(hinted_font.get_width_height(), expected, + rtol=0.1) + + +def test_utf16m_sfnt(): + try: + # seguisbi = Microsoft Segoe UI Semibold + entry = next(entry for entry in fontManager.ttflist + if Path(entry.fname).name == "seguisbi.ttf") + except StopIteration: + pytest.skip("Couldn't find seguisbi.ttf font to test against.") + else: + # Check that we successfully read "semibold" from the font's sfnt table + # and set its weight accordingly. + assert entry.weight == 600 + + +def test_find_ttc(): + fp = FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font wqy-zenhei.ttc may be missing") + fig, ax = plt.subplots() + ax.text(.5, .5, "\N{KANGXI RADICAL DRAGON}", fontproperties=fp) + for fmt in ["raw", "svg", "pdf", "ps"]: + fig.savefig(BytesIO(), format=fmt) + + +def test_find_noto(): + fp = FontProperties(family=["Noto Sans CJK SC", "Noto Sans CJK JP"]) + name = Path(findfont(fp)).name + if name not in ("NotoSansCJKsc-Regular.otf", "NotoSansCJK-Regular.ttc"): + pytest.skip(f"Noto Sans CJK SC font may be missing (found {name})") + + fig, ax = plt.subplots() + ax.text(0.5, 0.5, 'Hello, 你好', fontproperties=fp) + for fmt in ["raw", "svg", "pdf", "ps"]: + fig.savefig(BytesIO(), format=fmt) + + +def test_find_invalid(tmpdir): + tmp_path = Path(tmpdir) + + with pytest.raises(FileNotFoundError): + get_font(tmp_path / 'non-existent-font-name.ttf') + + with pytest.raises(FileNotFoundError): + get_font(str(tmp_path / 'non-existent-font-name.ttf')) + + with pytest.raises(FileNotFoundError): + get_font(bytes(tmp_path / 'non-existent-font-name.ttf')) + + # Not really public, but get_font doesn't expose non-filename constructor. + from matplotlib.ft2font import FT2Font + with pytest.raises(TypeError, match='font file or a binary-mode file'): + FT2Font(StringIO()) # type: ignore[arg-type] + + +@pytest.mark.skipif(sys.platform != 'linux' or not has_fclist, + reason='only Linux with fontconfig installed') +def test_user_fonts_linux(tmpdir, monkeypatch): + font_test_file = 'mpltest.ttf' + + # Precondition: the test font should not be available + fonts = findSystemFonts() + if any(font_test_file in font for font in fonts): + pytest.skip(f'{font_test_file} already exists in system fonts') + + # Prepare a temporary user font directory + user_fonts_dir = tmpdir.join('fonts') + user_fonts_dir.ensure(dir=True) + shutil.copyfile(Path(__file__).parent / font_test_file, + user_fonts_dir.join(font_test_file)) + + with monkeypatch.context() as m: + m.setenv('XDG_DATA_HOME', str(tmpdir)) + _get_fontconfig_fonts.cache_clear() + # Now, the font should be available + fonts = findSystemFonts() + assert any(font_test_file in font for font in fonts) + + # Make sure the temporary directory is no longer cached. + _get_fontconfig_fonts.cache_clear() + + +def test_addfont_as_path(): + """Smoke test that addfont() accepts pathlib.Path.""" + font_test_file = 'mpltest.ttf' + path = Path(__file__).parent / font_test_file + try: + fontManager.addfont(path) + added, = [font for font in fontManager.ttflist + if font.fname.endswith(font_test_file)] + fontManager.ttflist.remove(added) + finally: + to_remove = [font for font in fontManager.ttflist + if font.fname.endswith(font_test_file)] + for font in to_remove: + fontManager.ttflist.remove(font) + + +@pytest.mark.skipif(sys.platform != 'win32', reason='Windows only') +def test_user_fonts_win32(): + if not (os.environ.get('APPVEYOR') or os.environ.get('TF_BUILD')): + pytest.xfail("This test should only run on CI (appveyor or azure) " + "as the developer's font directory should remain " + "unchanged.") + pytest.xfail("We need to update the registry for this test to work") + font_test_file = 'mpltest.ttf' + + # Precondition: the test font should not be available + fonts = findSystemFonts() + if any(font_test_file in font for font in fonts): + pytest.skip(f'{font_test_file} already exists in system fonts') + + user_fonts_dir = MSUserFontDirectories[0] + + # Make sure that the user font directory exists (this is probably not the + # case on Windows versions < 1809) + os.makedirs(user_fonts_dir) + + # Copy the test font to the user font directory + shutil.copy(Path(__file__).parent / font_test_file, user_fonts_dir) + + # Now, the font should be available + fonts = findSystemFonts() + assert any(font_test_file in font for font in fonts) + + +def _model_handler(_): + fig, ax = plt.subplots() + fig.savefig(BytesIO(), format="pdf") + plt.close() + + +@pytest.mark.skipif(not hasattr(os, "register_at_fork"), + reason="Cannot register at_fork handlers") +def test_fork(): + _model_handler(0) # Make sure the font cache is filled. + ctx = multiprocessing.get_context("fork") + with ctx.Pool(processes=2) as pool: + pool.map(_model_handler, range(2)) + + +def test_missing_family(caplog): + plt.rcParams["font.sans-serif"] = ["this-font-does-not-exist"] + with caplog.at_level("WARNING"): + findfont("sans") + assert [rec.getMessage() for rec in caplog.records] == [ + "findfont: Font family ['sans'] not found. " + "Falling back to DejaVu Sans.", + "findfont: Generic family 'sans' not found because none of the " + "following families were found: this-font-does-not-exist", + ] + + +def _test_threading(): + import threading + from matplotlib.ft2font import LOAD_NO_HINTING + import matplotlib.font_manager as fm + + N = 10 + b = threading.Barrier(N) + + def bad_idea(n): + b.wait() + for j in range(100): + font = fm.get_font(fm.findfont("DejaVu Sans")) + font.set_text(str(n), 0.0, flags=LOAD_NO_HINTING) + + threads = [ + threading.Thread(target=bad_idea, name=f"bad_thread_{j}", args=(j,)) + for j in range(N) + ] + + for t in threads: + t.start() + + for t in threads: + t.join() + + +def test_fontcache_thread_safe(): + pytest.importorskip('threading') + import inspect + + proc = subprocess.run( + [sys.executable, "-c", + inspect.getsource(_test_threading) + '\n_test_threading()'] + ) + if proc.returncode: + pytest.fail("The subprocess returned with non-zero exit status " + f"{proc.returncode}.") + + +def test_fontentry_dataclass(): + fontent = FontEntry(name='font-name') + + png = fontent._repr_png_() + img = Image.open(BytesIO(png)) + assert img.width > 0 + assert img.height > 0 + + html = fontent._repr_html_() + assert html.startswith("<img src=\"data:image/png;base64") + + +def test_fontentry_dataclass_invalid_path(): + with pytest.raises(FileNotFoundError): + fontent = FontEntry(fname='/random', name='font-name') + fontent._repr_html_() + + +@pytest.mark.skipif(sys.platform == 'win32', reason='Linux or OS only') +def test_get_font_names(): + paths_mpl = [cbook._get_data_path('fonts', subdir) for subdir in ['ttf']] + fonts_mpl = findSystemFonts(paths_mpl, fontext='ttf') + fonts_system = findSystemFonts(fontext='ttf') + ttf_fonts = [] + for path in fonts_mpl + fonts_system: + try: + font = ft2font.FT2Font(path) + prop = ttfFontProperty(font) + ttf_fonts.append(prop.name) + except Exception: + pass + available_fonts = sorted(list(set(ttf_fonts))) + mpl_font_names = sorted(fontManager.get_font_names()) + assert set(available_fonts) == set(mpl_font_names) + assert len(available_fonts) == len(mpl_font_names) + assert available_fonts == mpl_font_names + + +def test_donot_cache_tracebacks(): + + class SomeObject: + pass + + def inner(): + x = SomeObject() + fig = mfigure.Figure() + ax = fig.subplots() + fig.text(.5, .5, 'aardvark', family='doesnotexist') + with BytesIO() as out: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + fig.savefig(out, format='raw') + + inner() + + for obj in gc.get_objects(): + if isinstance(obj, SomeObject): + pytest.fail("object from inner stack still alive") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_fontconfig_pattern.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_fontconfig_pattern.py new file mode 100644 index 00000000..792a8ed5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_fontconfig_pattern.py @@ -0,0 +1,77 @@ +import pytest + +from matplotlib.font_manager import FontProperties + + +# Attributes on FontProperties object to check for consistency +keys = [ + "get_family", + "get_style", + "get_variant", + "get_weight", + "get_size", + ] + + +def test_fontconfig_pattern(): + """Test converting a FontProperties to string then back.""" + + # Defaults + test = "defaults " + f1 = FontProperties() + s = str(f1) + + f2 = FontProperties(s) + for k in keys: + assert getattr(f1, k)() == getattr(f2, k)(), test + k + + # Basic inputs + test = "basic " + f1 = FontProperties(family="serif", size=20, style="italic") + s = str(f1) + + f2 = FontProperties(s) + for k in keys: + assert getattr(f1, k)() == getattr(f2, k)(), test + k + + # Full set of inputs. + test = "full " + f1 = FontProperties(family="sans-serif", size=24, weight="bold", + style="oblique", variant="small-caps", + stretch="expanded") + s = str(f1) + + f2 = FontProperties(s) + for k in keys: + assert getattr(f1, k)() == getattr(f2, k)(), test + k + + +def test_fontconfig_str(): + """Test FontProperties string conversions for correctness.""" + + # Known good strings taken from actual font config specs on a linux box + # and modified for MPL defaults. + + # Default values found by inspection. + test = "defaults " + s = ("sans\\-serif:style=normal:variant=normal:weight=normal" + ":stretch=normal:size=12.0") + font = FontProperties(s) + right = FontProperties() + for k in keys: + assert getattr(font, k)() == getattr(right, k)(), test + k + + test = "full " + s = ("serif-24:style=oblique:variant=small-caps:weight=bold" + ":stretch=expanded") + font = FontProperties(s) + right = FontProperties(family="serif", size=24, weight="bold", + style="oblique", variant="small-caps", + stretch="expanded") + for k in keys: + assert getattr(font, k)() == getattr(right, k)(), test + k + + +def test_fontconfig_unknown_constant(): + with pytest.warns(DeprecationWarning): + FontProperties(":unknown") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ft2font.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ft2font.py new file mode 100644 index 00000000..0139bdf4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ft2font.py @@ -0,0 +1,106 @@ +from pathlib import Path +import io + +import pytest + +from matplotlib import ft2font +from matplotlib.testing.decorators import check_figures_equal +import matplotlib.font_manager as fm +import matplotlib.pyplot as plt + + +def test_fallback_errors(): + file_name = fm.findfont('DejaVu Sans') + + with pytest.raises(TypeError, match="Fallback list must be a list"): + # failing to be a list will fail before the 0 + ft2font.FT2Font(file_name, _fallback_list=(0,)) # type: ignore[arg-type] + + with pytest.raises( + TypeError, match="Fallback fonts must be FT2Font objects." + ): + ft2font.FT2Font(file_name, _fallback_list=[0]) # type: ignore[list-item] + + +def test_ft2font_positive_hinting_factor(): + file_name = fm.findfont('DejaVu Sans') + with pytest.raises( + ValueError, match="hinting_factor must be greater than 0" + ): + ft2font.FT2Font(file_name, 0) + + +def test_fallback_smoke(): + fp = fm.FontProperties(family=["WenQuanYi Zen Hei"]) + if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc": + pytest.skip("Font wqy-zenhei.ttc may be missing") + + fp = fm.FontProperties(family=["Noto Sans CJK JP"]) + if Path(fm.findfont(fp)).name != "NotoSansCJK-Regular.ttc": + pytest.skip("Noto Sans CJK JP font may be missing.") + + plt.rcParams['font.size'] = 20 + fig = plt.figure(figsize=(4.75, 1.85)) + fig.text(0.05, 0.45, "There are 几个汉字 in between!", + family=['DejaVu Sans', "Noto Sans CJK JP"]) + fig.text(0.05, 0.25, "There are 几个汉字 in between!", + family=['DejaVu Sans', "WenQuanYi Zen Hei"]) + fig.text(0.05, 0.65, "There are 几个汉字 in between!", + family=["Noto Sans CJK JP"]) + fig.text(0.05, 0.85, "There are 几个汉字 in between!", + family=["WenQuanYi Zen Hei"]) + + # TODO enable fallback for other backends! + for fmt in ['png', 'raw']: # ["svg", "pdf", "ps"]: + fig.savefig(io.BytesIO(), format=fmt) + + +@pytest.mark.parametrize('family_name, file_name', + [("WenQuanYi Zen Hei", "wqy-zenhei"), + ("Noto Sans CJK JP", "NotoSansCJK")] + ) +@check_figures_equal(extensions=["png", "pdf", "eps", "svg"]) +def test_font_fallback_chinese(fig_test, fig_ref, family_name, file_name): + fp = fm.FontProperties(family=[family_name]) + if file_name not in Path(fm.findfont(fp)).name: + pytest.skip(f"Font {family_name} ({file_name}) is missing") + + text = ["There are", "几个汉字", "in between!"] + + plt.rcParams["font.size"] = 20 + test_fonts = [["DejaVu Sans", family_name]] * 3 + ref_fonts = [["DejaVu Sans"], [family_name], ["DejaVu Sans"]] + + for j, (txt, test_font, ref_font) in enumerate( + zip(text, test_fonts, ref_fonts) + ): + fig_ref.text(0.05, .85 - 0.15*j, txt, family=ref_font) + fig_test.text(0.05, .85 - 0.15*j, txt, family=test_font) + + +@pytest.mark.parametrize( + "family_name, file_name", + [ + ("WenQuanYi Zen Hei", "wqy-zenhei"), + ("Noto Sans CJK JP", "NotoSansCJK"), + ], +) +def test__get_fontmap(family_name, file_name): + fp = fm.FontProperties(family=[family_name]) + found_file_name = Path(fm.findfont(fp)).name + if file_name not in found_file_name: + pytest.skip(f"Font {family_name} ({file_name}) is missing") + + text = "There are 几个汉字 in between!" + ft = fm.get_font( + fm.fontManager._find_fonts_by_props( + fm.FontProperties(family=["DejaVu Sans", family_name]) + ) + ) + + fontmap = ft._get_fontmap(text) + for char, font in fontmap.items(): + if ord(char) > 127: + assert Path(font.fname).name == found_file_name + else: + assert Path(font.fname).name == "DejaVuSans.ttf" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_getattr.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_getattr.py new file mode 100644 index 00000000..a34e82ed --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_getattr.py @@ -0,0 +1,35 @@ +from importlib import import_module +from pkgutil import walk_packages + +import matplotlib +import pytest + +# Get the names of all matplotlib submodules, +# except for the unit tests and private modules. +module_names = [ + m.name + for m in walk_packages( + path=matplotlib.__path__, prefix=f'{matplotlib.__name__}.' + ) + if not m.name.startswith(__package__) + and not any(x.startswith('_') for x in m.name.split('.')) +] + + +@pytest.mark.parametrize('module_name', module_names) +@pytest.mark.filterwarnings('ignore::DeprecationWarning') +@pytest.mark.filterwarnings('ignore::ImportWarning') +def test_getattr(module_name): + """ + Test that __getattr__ methods raise AttributeError for unknown keys. + See #20822, #20855. + """ + try: + module = import_module(module_name) + except (ImportError, RuntimeError) as e: + # Skip modules that cannot be imported due to missing dependencies + pytest.skip(f'Cannot import {module_name} due to {e}') + + key = 'THIS_SYMBOL_SHOULD_NOT_EXIST' + if hasattr(module, key): + delattr(module, key) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_gridspec.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_gridspec.py new file mode 100644 index 00000000..5d5d7523 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_gridspec.py @@ -0,0 +1,37 @@ +import matplotlib.gridspec as gridspec +import pytest + + +def test_equal(): + gs = gridspec.GridSpec(2, 1) + assert gs[0, 0] == gs[0, 0] + assert gs[:, 0] == gs[:, 0] + + +def test_width_ratios(): + """ + Addresses issue #5835. + See at https://github.com/matplotlib/matplotlib/issues/5835. + """ + with pytest.raises(ValueError): + gridspec.GridSpec(1, 1, width_ratios=[2, 1, 3]) + + +def test_height_ratios(): + """ + Addresses issue #5835. + See at https://github.com/matplotlib/matplotlib/issues/5835. + """ + with pytest.raises(ValueError): + gridspec.GridSpec(1, 1, height_ratios=[2, 1, 3]) + + +def test_repr(): + ss = gridspec.GridSpec(3, 3)[2, 1:3] + assert repr(ss) == "GridSpec(3, 3)[2:3, 1:3]" + + ss = gridspec.GridSpec(2, 2, + height_ratios=(3, 1), + width_ratios=(1, 3)) + assert repr(ss) == \ + "GridSpec(2, 2, height_ratios=(3, 1), width_ratios=(1, 3))" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_image.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_image.py new file mode 100644 index 00000000..aeeebd13 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_image.py @@ -0,0 +1,1505 @@ +from contextlib import ExitStack +from copy import copy +import functools +import io +import os +from pathlib import Path +import platform +import sys +import urllib.request + +import numpy as np +from numpy.testing import assert_array_equal +from PIL import Image + +import matplotlib as mpl +from matplotlib import ( + colors, image as mimage, patches, pyplot as plt, style, rcParams) +from matplotlib.image import (AxesImage, BboxImage, FigureImage, + NonUniformImage, PcolorImage) +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.transforms import Bbox, Affine2D, TransformedBbox +import matplotlib.ticker as mticker + +import pytest + + +@image_comparison(['image_interps'], style='mpl20') +def test_image_interps(): + """Make the basic nearest, bilinear and bicubic interps.""" + # Remove texts when this image is regenerated. + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + X = np.arange(100).reshape(5, 20) + + fig, (ax1, ax2, ax3) = plt.subplots(3) + ax1.imshow(X, interpolation='nearest') + ax1.set_title('three interpolations') + ax1.set_ylabel('nearest') + + ax2.imshow(X, interpolation='bilinear') + ax2.set_ylabel('bilinear') + + ax3.imshow(X, interpolation='bicubic') + ax3.set_ylabel('bicubic') + + +@image_comparison(['interp_alpha.png'], remove_text=True) +def test_alpha_interp(): + """Test the interpolation of the alpha channel on RGBA images""" + fig, (axl, axr) = plt.subplots(1, 2) + # full green image + img = np.zeros((5, 5, 4)) + img[..., 1] = np.ones((5, 5)) + # transparent under main diagonal + img[..., 3] = np.tril(np.ones((5, 5), dtype=np.uint8)) + axl.imshow(img, interpolation="none") + axr.imshow(img, interpolation="bilinear") + + +@image_comparison(['interp_nearest_vs_none'], + extensions=['pdf', 'svg'], remove_text=True) +def test_interp_nearest_vs_none(): + """Test the effect of "nearest" and "none" interpolation""" + # Setting dpi to something really small makes the difference very + # visible. This works fine with pdf, since the dpi setting doesn't + # affect anything but images, but the agg output becomes unusably + # small. + rcParams['savefig.dpi'] = 3 + X = np.array([[[218, 165, 32], [122, 103, 238]], + [[127, 255, 0], [255, 99, 71]]], dtype=np.uint8) + fig, (ax1, ax2) = plt.subplots(1, 2) + ax1.imshow(X, interpolation='none') + ax1.set_title('interpolation none') + ax2.imshow(X, interpolation='nearest') + ax2.set_title('interpolation nearest') + + +@pytest.mark.parametrize('suppressComposite', [False, True]) +@image_comparison(['figimage'], extensions=['png', 'pdf']) +def test_figimage(suppressComposite): + fig = plt.figure(figsize=(2, 2), dpi=100) + fig.suppressComposite = suppressComposite + x, y = np.ix_(np.arange(100) / 100.0, np.arange(100) / 100) + z = np.sin(x**2 + y**2 - x*y) + c = np.sin(20*x**2 + 50*y**2) + img = z + c/5 + + fig.figimage(img, xo=0, yo=0, origin='lower') + fig.figimage(img[::-1, :], xo=0, yo=100, origin='lower') + fig.figimage(img[:, ::-1], xo=100, yo=0, origin='lower') + fig.figimage(img[::-1, ::-1], xo=100, yo=100, origin='lower') + + +def test_image_python_io(): + fig, ax = plt.subplots() + ax.plot([1, 2, 3]) + buffer = io.BytesIO() + fig.savefig(buffer) + buffer.seek(0) + plt.imread(buffer) + + +@pytest.mark.parametrize( + "img_size, fig_size, interpolation", + [(5, 2, "hanning"), # data larger than figure. + (5, 5, "nearest"), # exact resample. + (5, 10, "nearest"), # double sample. + (3, 2.9, "hanning"), # <3 upsample. + (3, 9.1, "nearest"), # >3 upsample. + ]) +@check_figures_equal(extensions=['png']) +def test_imshow_antialiased(fig_test, fig_ref, + img_size, fig_size, interpolation): + np.random.seed(19680801) + dpi = plt.rcParams["savefig.dpi"] + A = np.random.rand(int(dpi * img_size), int(dpi * img_size)) + for fig in [fig_test, fig_ref]: + fig.set_size_inches(fig_size, fig_size) + ax = fig_test.subplots() + ax.set_position([0, 0, 1, 1]) + ax.imshow(A, interpolation='antialiased') + ax = fig_ref.subplots() + ax.set_position([0, 0, 1, 1]) + ax.imshow(A, interpolation=interpolation) + + +@check_figures_equal(extensions=['png']) +def test_imshow_zoom(fig_test, fig_ref): + # should be less than 3 upsample, so should be nearest... + np.random.seed(19680801) + dpi = plt.rcParams["savefig.dpi"] + A = np.random.rand(int(dpi * 3), int(dpi * 3)) + for fig in [fig_test, fig_ref]: + fig.set_size_inches(2.9, 2.9) + ax = fig_test.subplots() + ax.imshow(A, interpolation='antialiased') + ax.set_xlim([10, 20]) + ax.set_ylim([10, 20]) + ax = fig_ref.subplots() + ax.imshow(A, interpolation='nearest') + ax.set_xlim([10, 20]) + ax.set_ylim([10, 20]) + + +@check_figures_equal() +def test_imshow_pil(fig_test, fig_ref): + style.use("default") + png_path = Path(__file__).parent / "baseline_images/pngsuite/basn3p04.png" + tiff_path = Path(__file__).parent / "baseline_images/test_image/uint16.tif" + axs = fig_test.subplots(2) + axs[0].imshow(Image.open(png_path)) + axs[1].imshow(Image.open(tiff_path)) + axs = fig_ref.subplots(2) + axs[0].imshow(plt.imread(png_path)) + axs[1].imshow(plt.imread(tiff_path)) + + +def test_imread_pil_uint16(): + img = plt.imread(os.path.join(os.path.dirname(__file__), + 'baseline_images', 'test_image', 'uint16.tif')) + assert img.dtype == np.uint16 + assert np.sum(img) == 134184960 + + +def test_imread_fspath(): + img = plt.imread( + Path(__file__).parent / 'baseline_images/test_image/uint16.tif') + assert img.dtype == np.uint16 + assert np.sum(img) == 134184960 + + +@pytest.mark.parametrize("fmt", ["png", "jpg", "jpeg", "tiff"]) +def test_imsave(fmt): + has_alpha = fmt not in ["jpg", "jpeg"] + + # The goal here is that the user can specify an output logical DPI + # for the image, but this will not actually add any extra pixels + # to the image, it will merely be used for metadata purposes. + + # So we do the traditional case (dpi == 1), and the new case (dpi + # == 100) and read the resulting PNG files back in and make sure + # the data is 100% identical. + np.random.seed(1) + # The height of 1856 pixels was selected because going through creating an + # actual dpi=100 figure to save the image to a Pillow-provided format would + # cause a rounding error resulting in a final image of shape 1855. + data = np.random.rand(1856, 2) + + buff_dpi1 = io.BytesIO() + plt.imsave(buff_dpi1, data, format=fmt, dpi=1) + + buff_dpi100 = io.BytesIO() + plt.imsave(buff_dpi100, data, format=fmt, dpi=100) + + buff_dpi1.seek(0) + arr_dpi1 = plt.imread(buff_dpi1, format=fmt) + + buff_dpi100.seek(0) + arr_dpi100 = plt.imread(buff_dpi100, format=fmt) + + assert arr_dpi1.shape == (1856, 2, 3 + has_alpha) + assert arr_dpi100.shape == (1856, 2, 3 + has_alpha) + + assert_array_equal(arr_dpi1, arr_dpi100) + + +@pytest.mark.parametrize("fmt", ["png", "pdf", "ps", "eps", "svg"]) +def test_imsave_fspath(fmt): + plt.imsave(Path(os.devnull), np.array([[0, 1]]), format=fmt) + + +def test_imsave_color_alpha(): + # Test that imsave accept arrays with ndim=3 where the third dimension is + # color and alpha without raising any exceptions, and that the data is + # acceptably preserved through a save/read roundtrip. + np.random.seed(1) + + for origin in ['lower', 'upper']: + data = np.random.rand(16, 16, 4) + buff = io.BytesIO() + plt.imsave(buff, data, origin=origin, format="png") + + buff.seek(0) + arr_buf = plt.imread(buff) + + # Recreate the float -> uint8 conversion of the data + # We can only expect to be the same with 8 bits of precision, + # since that's what the PNG file used. + data = (255*data).astype('uint8') + if origin == 'lower': + data = data[::-1] + arr_buf = (255*arr_buf).astype('uint8') + + assert_array_equal(data, arr_buf) + + +def test_imsave_pil_kwargs_png(): + from PIL.PngImagePlugin import PngInfo + buf = io.BytesIO() + pnginfo = PngInfo() + pnginfo.add_text("Software", "test") + plt.imsave(buf, [[0, 1], [2, 3]], + format="png", pil_kwargs={"pnginfo": pnginfo}) + im = Image.open(buf) + assert im.info["Software"] == "test" + + +def test_imsave_pil_kwargs_tiff(): + from PIL.TiffTags import TAGS_V2 as TAGS + buf = io.BytesIO() + pil_kwargs = {"description": "test image"} + plt.imsave(buf, [[0, 1], [2, 3]], format="tiff", pil_kwargs=pil_kwargs) + assert len(pil_kwargs) == 1 + im = Image.open(buf) + tags = {TAGS[k].name: v for k, v in im.tag_v2.items()} + assert tags["ImageDescription"] == "test image" + + +@image_comparison(['image_alpha'], remove_text=True) +def test_image_alpha(): + np.random.seed(0) + Z = np.random.rand(6, 6) + + fig, (ax1, ax2, ax3) = plt.subplots(1, 3) + ax1.imshow(Z, alpha=1.0, interpolation='none') + ax2.imshow(Z, alpha=0.5, interpolation='none') + ax3.imshow(Z, alpha=0.5, interpolation='nearest') + + +def test_cursor_data(): + from matplotlib.backend_bases import MouseEvent + + fig, ax = plt.subplots() + im = ax.imshow(np.arange(100).reshape(10, 10), origin='upper') + + x, y = 4, 4 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == 44 + + # Now try for a point outside the image + # Tests issue #4957 + x, y = 10.1, 4 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) is None + + # Hmm, something is wrong here... I get 0, not None... + # But, this works further down in the tests with extents flipped + # x, y = 0.1, -0.1 + # xdisp, ydisp = ax.transData.transform([x, y]) + # event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + # z = im.get_cursor_data(event) + # assert z is None, "Did not get None, got %d" % z + + ax.clear() + # Now try with the extents flipped. + im = ax.imshow(np.arange(100).reshape(10, 10), origin='lower') + + x, y = 4, 4 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == 44 + + fig, ax = plt.subplots() + im = ax.imshow(np.arange(100).reshape(10, 10), extent=[0, 0.5, 0, 0.5]) + + x, y = 0.25, 0.25 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == 55 + + # Now try for a point outside the image + # Tests issue #4957 + x, y = 0.75, 0.25 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) is None + + x, y = 0.01, -0.01 + xdisp, ydisp = ax.transData.transform([x, y]) + + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) is None + + # Now try with additional transform applied to the image artist + trans = Affine2D().scale(2).rotate(0.5) + im = ax.imshow(np.arange(100).reshape(10, 10), + transform=trans + ax.transData) + x, y = 3, 10 + xdisp, ydisp = ax.transData.transform([x, y]) + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.get_cursor_data(event) == 44 + + +@pytest.mark.parametrize( + "data, text", [ + ([[10001, 10000]], "[10001.000]"), + ([[.123, .987]], "[0.123]"), + ([[np.nan, 1, 2]], "[]"), + ([[1, 1+1e-15]], "[1.0000000000000000]"), + ([[-1, -1]], "[-1.0000000000000000]"), + ]) +def test_format_cursor_data(data, text): + from matplotlib.backend_bases import MouseEvent + + fig, ax = plt.subplots() + im = ax.imshow(data) + + xdisp, ydisp = ax.transData.transform([0, 0]) + event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp) + assert im.format_cursor_data(im.get_cursor_data(event)) == text + + +@image_comparison(['image_clip'], style='mpl20') +def test_image_clip(): + d = [[1, 2], [3, 4]] + + fig, ax = plt.subplots() + im = ax.imshow(d) + patch = patches.Circle((0, 0), radius=1, transform=ax.transData) + im.set_clip_path(patch) + + +@image_comparison(['image_cliprect'], style='mpl20') +def test_image_cliprect(): + fig, ax = plt.subplots() + d = [[1, 2], [3, 4]] + + im = ax.imshow(d, extent=(0, 5, 0, 5)) + + rect = patches.Rectangle( + xy=(1, 1), width=2, height=2, transform=im.axes.transData) + im.set_clip_path(rect) + + +@image_comparison(['imshow'], remove_text=True, style='mpl20') +def test_imshow(): + fig, ax = plt.subplots() + arr = np.arange(100).reshape((10, 10)) + ax.imshow(arr, interpolation="bilinear", extent=(1, 2, 1, 2)) + ax.set_xlim(0, 3) + ax.set_ylim(0, 3) + + +@check_figures_equal(extensions=['png']) +def test_imshow_10_10_1(fig_test, fig_ref): + # 10x10x1 should be the same as 10x10 + arr = np.arange(100).reshape((10, 10, 1)) + ax = fig_ref.subplots() + ax.imshow(arr[:, :, 0], interpolation="bilinear", extent=(1, 2, 1, 2)) + ax.set_xlim(0, 3) + ax.set_ylim(0, 3) + + ax = fig_test.subplots() + ax.imshow(arr, interpolation="bilinear", extent=(1, 2, 1, 2)) + ax.set_xlim(0, 3) + ax.set_ylim(0, 3) + + +def test_imshow_10_10_2(): + fig, ax = plt.subplots() + arr = np.arange(200).reshape((10, 10, 2)) + with pytest.raises(TypeError): + ax.imshow(arr) + + +def test_imshow_10_10_5(): + fig, ax = plt.subplots() + arr = np.arange(500).reshape((10, 10, 5)) + with pytest.raises(TypeError): + ax.imshow(arr) + + +@image_comparison(['no_interpolation_origin'], remove_text=True) +def test_no_interpolation_origin(): + fig, axs = plt.subplots(2) + axs[0].imshow(np.arange(100).reshape((2, 50)), origin="lower", + interpolation='none') + axs[1].imshow(np.arange(100).reshape((2, 50)), interpolation='none') + + +@image_comparison(['image_shift'], remove_text=True, extensions=['pdf', 'svg']) +def test_image_shift(): + imgData = [[1 / x + 1 / y for x in range(1, 100)] for y in range(1, 100)] + tMin = 734717.945208 + tMax = 734717.946366 + + fig, ax = plt.subplots() + ax.imshow(imgData, norm=colors.LogNorm(), interpolation='none', + extent=(tMin, tMax, 1, 100)) + ax.set_aspect('auto') + + +def test_image_edges(): + fig = plt.figure(figsize=[1, 1]) + ax = fig.add_axes([0, 0, 1, 1], frameon=False) + + data = np.tile(np.arange(12), 15).reshape(20, 9) + + im = ax.imshow(data, origin='upper', extent=[-10, 10, -10, 10], + interpolation='none', cmap='gray') + + x = y = 2 + ax.set_xlim([-x, x]) + ax.set_ylim([-y, y]) + + ax.set_xticks([]) + ax.set_yticks([]) + + buf = io.BytesIO() + fig.savefig(buf, facecolor=(0, 1, 0)) + + buf.seek(0) + + im = plt.imread(buf) + r, g, b, a = sum(im[:, 0]) + r, g, b, a = sum(im[:, -1]) + + assert g != 100, 'Expected a non-green edge - but sadly, it was.' + + +@image_comparison(['image_composite_background'], + remove_text=True, style='mpl20') +def test_image_composite_background(): + fig, ax = plt.subplots() + arr = np.arange(12).reshape(4, 3) + ax.imshow(arr, extent=[0, 2, 15, 0]) + ax.imshow(arr, extent=[4, 6, 15, 0]) + ax.set_facecolor((1, 0, 0, 0.5)) + ax.set_xlim([0, 12]) + + +@image_comparison(['image_composite_alpha'], remove_text=True) +def test_image_composite_alpha(): + """ + Tests that the alpha value is recognized and correctly applied in the + process of compositing images together. + """ + fig, ax = plt.subplots() + arr = np.zeros((11, 21, 4)) + arr[:, :, 0] = 1 + arr[:, :, 3] = np.concatenate( + (np.arange(0, 1.1, 0.1), np.arange(0, 1, 0.1)[::-1])) + arr2 = np.zeros((21, 11, 4)) + arr2[:, :, 0] = 1 + arr2[:, :, 1] = 1 + arr2[:, :, 3] = np.concatenate( + (np.arange(0, 1.1, 0.1), np.arange(0, 1, 0.1)[::-1]))[:, np.newaxis] + ax.imshow(arr, extent=[1, 2, 5, 0], alpha=0.3) + ax.imshow(arr, extent=[2, 3, 5, 0], alpha=0.6) + ax.imshow(arr, extent=[3, 4, 5, 0]) + ax.imshow(arr2, extent=[0, 5, 1, 2]) + ax.imshow(arr2, extent=[0, 5, 2, 3], alpha=0.6) + ax.imshow(arr2, extent=[0, 5, 3, 4], alpha=0.3) + ax.set_facecolor((0, 0.5, 0, 1)) + ax.set_xlim([0, 5]) + ax.set_ylim([5, 0]) + + +@check_figures_equal(extensions=["pdf"]) +def test_clip_path_disables_compositing(fig_test, fig_ref): + t = np.arange(9).reshape((3, 3)) + for fig in [fig_test, fig_ref]: + ax = fig.add_subplot() + ax.imshow(t, clip_path=(mpl.path.Path([(0, 0), (0, 1), (1, 0)]), + ax.transData)) + ax.imshow(t, clip_path=(mpl.path.Path([(1, 1), (1, 2), (2, 1)]), + ax.transData)) + fig_ref.suppressComposite = True + + +@image_comparison(['rasterize_10dpi'], + extensions=['pdf', 'svg'], remove_text=True, style='mpl20') +def test_rasterize_dpi(): + # This test should check rasterized rendering with high output resolution. + # It plots a rasterized line and a normal image with imshow. So it will + # catch when images end up in the wrong place in case of non-standard dpi + # setting. Instead of high-res rasterization I use low-res. Therefore + # the fact that the resolution is non-standard is easily checked by + # image_comparison. + img = np.asarray([[1, 2], [3, 4]]) + + fig, axs = plt.subplots(1, 3, figsize=(3, 1)) + + axs[0].imshow(img) + + axs[1].plot([0, 1], [0, 1], linewidth=20., rasterized=True) + axs[1].set(xlim=(0, 1), ylim=(-1, 2)) + + axs[2].plot([0, 1], [0, 1], linewidth=20.) + axs[2].set(xlim=(0, 1), ylim=(-1, 2)) + + # Low-dpi PDF rasterization errors prevent proper image comparison tests. + # Hide detailed structures like the axes spines. + for ax in axs: + ax.set_xticks([]) + ax.set_yticks([]) + ax.spines[:].set_visible(False) + + rcParams['savefig.dpi'] = 10 + + +@image_comparison(['bbox_image_inverted'], remove_text=True, style='mpl20') +def test_bbox_image_inverted(): + # This is just used to produce an image to feed to BboxImage + image = np.arange(100).reshape((10, 10)) + + fig, ax = plt.subplots() + bbox_im = BboxImage( + TransformedBbox(Bbox([[100, 100], [0, 0]]), ax.transData), + interpolation='nearest') + bbox_im.set_data(image) + bbox_im.set_clip_on(False) + ax.set_xlim(0, 100) + ax.set_ylim(0, 100) + ax.add_artist(bbox_im) + + image = np.identity(10) + + bbox_im = BboxImage(TransformedBbox(Bbox([[0.1, 0.2], [0.3, 0.25]]), + ax.figure.transFigure), + interpolation='nearest') + bbox_im.set_data(image) + bbox_im.set_clip_on(False) + ax.add_artist(bbox_im) + + +def test_get_window_extent_for_AxisImage(): + # Create a figure of known size (1000x1000 pixels), place an image + # object at a given location and check that get_window_extent() + # returns the correct bounding box values (in pixels). + + im = np.array([[0.25, 0.75, 1.0, 0.75], [0.1, 0.65, 0.5, 0.4], + [0.6, 0.3, 0.0, 0.2], [0.7, 0.9, 0.4, 0.6]]) + fig, ax = plt.subplots(figsize=(10, 10), dpi=100) + ax.set_position([0, 0, 1, 1]) + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + im_obj = ax.imshow( + im, extent=[0.4, 0.7, 0.2, 0.9], interpolation='nearest') + + fig.canvas.draw() + renderer = fig.canvas.renderer + im_bbox = im_obj.get_window_extent(renderer) + + assert_array_equal(im_bbox.get_points(), [[400, 200], [700, 900]]) + + fig, ax = plt.subplots(figsize=(10, 10), dpi=100) + ax.set_position([0, 0, 1, 1]) + ax.set_xlim(1, 2) + ax.set_ylim(0, 1) + im_obj = ax.imshow( + im, extent=[0.4, 0.7, 0.2, 0.9], interpolation='nearest', + transform=ax.transAxes) + + fig.canvas.draw() + renderer = fig.canvas.renderer + im_bbox = im_obj.get_window_extent(renderer) + + assert_array_equal(im_bbox.get_points(), [[400, 200], [700, 900]]) + + +@image_comparison(['zoom_and_clip_upper_origin.png'], + remove_text=True, style='mpl20') +def test_zoom_and_clip_upper_origin(): + image = np.arange(100) + image = image.reshape((10, 10)) + + fig, ax = plt.subplots() + ax.imshow(image) + ax.set_ylim(2.0, -0.5) + ax.set_xlim(-0.5, 2.0) + + +def test_nonuniformimage_setcmap(): + ax = plt.gca() + im = NonUniformImage(ax) + im.set_cmap('Blues') + + +def test_nonuniformimage_setnorm(): + ax = plt.gca() + im = NonUniformImage(ax) + im.set_norm(plt.Normalize()) + + +def test_jpeg_2d(): + # smoke test that mode-L pillow images work. + imd = np.ones((10, 10), dtype='uint8') + for i in range(10): + imd[i, :] = np.linspace(0.0, 1.0, 10) * 255 + im = Image.new('L', (10, 10)) + im.putdata(imd.flatten()) + fig, ax = plt.subplots() + ax.imshow(im) + + +def test_jpeg_alpha(): + plt.figure(figsize=(1, 1), dpi=300) + # Create an image that is all black, with a gradient from 0-1 in + # the alpha channel from left to right. + im = np.zeros((300, 300, 4), dtype=float) + im[..., 3] = np.linspace(0.0, 1.0, 300) + + plt.figimage(im) + + buff = io.BytesIO() + plt.savefig(buff, facecolor="red", format='jpg', dpi=300) + + buff.seek(0) + image = Image.open(buff) + + # If this fails, there will be only one color (all black). If this + # is working, we should have all 256 shades of grey represented. + num_colors = len(image.getcolors(256)) + assert 175 <= num_colors <= 210 + # The fully transparent part should be red. + corner_pixel = image.getpixel((0, 0)) + assert corner_pixel == (254, 0, 0) + + +def test_axesimage_setdata(): + ax = plt.gca() + im = AxesImage(ax) + z = np.arange(12, dtype=float).reshape((4, 3)) + im.set_data(z) + z[0, 0] = 9.9 + assert im._A[0, 0] == 0, 'value changed' + + +def test_figureimage_setdata(): + fig = plt.gcf() + im = FigureImage(fig) + z = np.arange(12, dtype=float).reshape((4, 3)) + im.set_data(z) + z[0, 0] = 9.9 + assert im._A[0, 0] == 0, 'value changed' + + +@pytest.mark.parametrize( + "image_cls,x,y,a", [ + (NonUniformImage, + np.arange(3.), np.arange(4.), np.arange(12.).reshape((4, 3))), + (PcolorImage, + np.arange(3.), np.arange(4.), np.arange(6.).reshape((3, 2))), + ]) +def test_setdata_xya(image_cls, x, y, a): + ax = plt.gca() + im = image_cls(ax) + im.set_data(x, y, a) + x[0] = y[0] = a[0, 0] = 9.9 + assert im._A[0, 0] == im._Ax[0] == im._Ay[0] == 0, 'value changed' + im.set_data(x, y, a.reshape((*a.shape, -1))) # Just a smoketest. + + +def test_minimized_rasterized(): + # This ensures that the rasterized content in the colorbars is + # only as thick as the colorbar, and doesn't extend to other parts + # of the image. See #5814. While the original bug exists only + # in Postscript, the best way to detect it is to generate SVG + # and then parse the output to make sure the two colorbar images + # are the same size. + from xml.etree import ElementTree + + np.random.seed(0) + data = np.random.rand(10, 10) + + fig, ax = plt.subplots(1, 2) + p1 = ax[0].pcolormesh(data) + p2 = ax[1].pcolormesh(data) + + plt.colorbar(p1, ax=ax[0]) + plt.colorbar(p2, ax=ax[1]) + + buff = io.BytesIO() + plt.savefig(buff, format='svg') + + buff = io.BytesIO(buff.getvalue()) + tree = ElementTree.parse(buff) + width = None + for image in tree.iter('image'): + if width is None: + width = image['width'] + else: + if image['width'] != width: + assert False + + +def test_load_from_url(): + path = Path(__file__).parent / "baseline_images/pngsuite/basn3p04.png" + url = ('file:' + + ('///' if sys.platform == 'win32' else '') + + path.resolve().as_posix()) + with pytest.raises(ValueError, match="Please open the URL"): + plt.imread(url) + with urllib.request.urlopen(url) as file: + plt.imread(file) + + +@image_comparison(['log_scale_image'], remove_text=True) +def test_log_scale_image(): + Z = np.zeros((10, 10)) + Z[::2] = 1 + + fig, ax = plt.subplots() + ax.imshow(Z, extent=[1, 100, 1, 100], cmap='viridis', vmax=1, vmin=-1, + aspect='auto') + ax.set(yscale='log') + + +@image_comparison(['rotate_image'], remove_text=True) +def test_rotate_image(): + delta = 0.25 + x = y = np.arange(-3.0, 3.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi) + Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) / + (2 * np.pi * 0.5 * 1.5)) + Z = Z2 - Z1 # difference of Gaussians + + fig, ax1 = plt.subplots(1, 1) + im1 = ax1.imshow(Z, interpolation='none', cmap='viridis', + origin='lower', + extent=[-2, 4, -3, 2], clip_on=True) + + trans_data2 = Affine2D().rotate_deg(30) + ax1.transData + im1.set_transform(trans_data2) + + # display intended extent of the image + x1, x2, y1, y2 = im1.get_extent() + + ax1.plot([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], "r--", lw=3, + transform=trans_data2) + + ax1.set_xlim(2, 5) + ax1.set_ylim(0, 4) + + +def test_image_preserve_size(): + buff = io.BytesIO() + + im = np.zeros((481, 321)) + plt.imsave(buff, im, format="png") + + buff.seek(0) + img = plt.imread(buff) + + assert img.shape[:2] == im.shape + + +def test_image_preserve_size2(): + n = 7 + data = np.identity(n, float) + + fig = plt.figure(figsize=(n, n), frameon=False) + + ax = plt.Axes(fig, [0.0, 0.0, 1.0, 1.0]) + ax.set_axis_off() + fig.add_axes(ax) + ax.imshow(data, interpolation='nearest', origin='lower', aspect='auto') + buff = io.BytesIO() + fig.savefig(buff, dpi=1) + + buff.seek(0) + img = plt.imread(buff) + + assert img.shape == (7, 7, 4) + + assert_array_equal(np.asarray(img[:, :, 0], bool), + np.identity(n, bool)[::-1]) + + +@image_comparison(['mask_image_over_under.png'], remove_text=True, tol=1.0) +def test_mask_image_over_under(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + delta = 0.025 + x = y = np.arange(-3.0, 3.0, delta) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi) + Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) / + (2 * np.pi * 0.5 * 1.5)) + Z = 10*(Z2 - Z1) # difference of Gaussians + + palette = plt.cm.gray.with_extremes(over='r', under='g', bad='b') + Zm = np.ma.masked_where(Z > 1.2, Z) + fig, (ax1, ax2) = plt.subplots(1, 2) + im = ax1.imshow(Zm, interpolation='bilinear', + cmap=palette, + norm=colors.Normalize(vmin=-1.0, vmax=1.0, clip=False), + origin='lower', extent=[-3, 3, -3, 3]) + ax1.set_title('Green=low, Red=high, Blue=bad') + fig.colorbar(im, extend='both', orientation='horizontal', + ax=ax1, aspect=10) + + im = ax2.imshow(Zm, interpolation='nearest', + cmap=palette, + norm=colors.BoundaryNorm([-1, -0.5, -0.2, 0, 0.2, 0.5, 1], + ncolors=256, clip=False), + origin='lower', extent=[-3, 3, -3, 3]) + ax2.set_title('With BoundaryNorm') + fig.colorbar(im, extend='both', spacing='proportional', + orientation='horizontal', ax=ax2, aspect=10) + + +@image_comparison(['mask_image'], remove_text=True) +def test_mask_image(): + # Test mask image two ways: Using nans and using a masked array. + + fig, (ax1, ax2) = plt.subplots(1, 2) + + A = np.ones((5, 5)) + A[1:2, 1:2] = np.nan + + ax1.imshow(A, interpolation='nearest') + + A = np.zeros((5, 5), dtype=bool) + A[1:2, 1:2] = True + A = np.ma.masked_array(np.ones((5, 5), dtype=np.uint16), A) + + ax2.imshow(A, interpolation='nearest') + + +def test_mask_image_all(): + # Test behavior with an image that is entirely masked does not warn + data = np.full((2, 2), np.nan) + fig, ax = plt.subplots() + ax.imshow(data) + fig.canvas.draw_idle() # would emit a warning + + +@image_comparison(['imshow_endianess.png'], remove_text=True) +def test_imshow_endianess(): + x = np.arange(10) + X, Y = np.meshgrid(x, x) + Z = np.hypot(X - 5, Y - 5) + + fig, (ax1, ax2) = plt.subplots(1, 2) + + kwargs = dict(origin="lower", interpolation='nearest', cmap='viridis') + + ax1.imshow(Z.astype('<f8'), **kwargs) + ax2.imshow(Z.astype('>f8'), **kwargs) + + +@image_comparison(['imshow_masked_interpolation'], + tol=0 if platform.machine() == 'x86_64' else 0.01, + remove_text=True, style='mpl20') +def test_imshow_masked_interpolation(): + + cmap = mpl.colormaps['viridis'].with_extremes(over='r', under='b', bad='k') + + N = 20 + n = colors.Normalize(vmin=0, vmax=N*N-1) + + data = np.arange(N*N, dtype=float).reshape(N, N) + + data[5, 5] = -1 + # This will cause crazy ringing for the higher-order + # interpolations + data[15, 5] = 1e5 + + # data[3, 3] = np.nan + + data[15, 15] = np.inf + + mask = np.zeros_like(data).astype('bool') + mask[5, 15] = True + + data = np.ma.masked_array(data, mask) + + fig, ax_grid = plt.subplots(3, 6) + interps = sorted(mimage._interpd_) + interps.remove('antialiased') + + for interp, ax in zip(interps, ax_grid.ravel()): + ax.set_title(interp) + ax.imshow(data, norm=n, cmap=cmap, interpolation=interp) + ax.axis('off') + + +def test_imshow_no_warn_invalid(): + plt.imshow([[1, 2], [3, np.nan]]) # Check that no warning is emitted. + + +@pytest.mark.parametrize( + 'dtype', [np.dtype(s) for s in 'u2 u4 i2 i4 i8 f4 f8'.split()]) +def test_imshow_clips_rgb_to_valid_range(dtype): + arr = np.arange(300, dtype=dtype).reshape((10, 10, 3)) + if dtype.kind != 'u': + arr -= 10 + too_low = arr < 0 + too_high = arr > 255 + if dtype.kind == 'f': + arr = arr / 255 + _, ax = plt.subplots() + out = ax.imshow(arr).get_array() + assert (out[too_low] == 0).all() + if dtype.kind == 'f': + assert (out[too_high] == 1).all() + assert out.dtype.kind == 'f' + else: + assert (out[too_high] == 255).all() + assert out.dtype == np.uint8 + + +@image_comparison(['imshow_flatfield.png'], remove_text=True, style='mpl20') +def test_imshow_flatfield(): + fig, ax = plt.subplots() + im = ax.imshow(np.ones((5, 5)), interpolation='nearest') + im.set_clim(.5, 1.5) + + +@image_comparison(['imshow_bignumbers.png'], remove_text=True, style='mpl20') +def test_imshow_bignumbers(): + rcParams['image.interpolation'] = 'nearest' + # putting a big number in an array of integers shouldn't + # ruin the dynamic range of the resolved bits. + fig, ax = plt.subplots() + img = np.array([[1, 2, 1e12], [3, 1, 4]], dtype=np.uint64) + pc = ax.imshow(img) + pc.set_clim(0, 5) + + +@image_comparison(['imshow_bignumbers_real.png'], + remove_text=True, style='mpl20') +def test_imshow_bignumbers_real(): + rcParams['image.interpolation'] = 'nearest' + # putting a big number in an array of integers shouldn't + # ruin the dynamic range of the resolved bits. + fig, ax = plt.subplots() + img = np.array([[2., 1., 1.e22], [4., 1., 3.]]) + pc = ax.imshow(img) + pc.set_clim(0, 5) + + +@pytest.mark.parametrize( + "make_norm", + [colors.Normalize, + colors.LogNorm, + lambda: colors.SymLogNorm(1), + lambda: colors.PowerNorm(1)]) +def test_empty_imshow(make_norm): + fig, ax = plt.subplots() + with pytest.warns(UserWarning, + match="Attempting to set identical low and high xlims"): + im = ax.imshow([[]], norm=make_norm()) + im.set_extent([-5, 5, -5, 5]) + fig.canvas.draw() + + with pytest.raises(RuntimeError): + im.make_image(fig.canvas.get_renderer()) + + +def test_imshow_float16(): + fig, ax = plt.subplots() + ax.imshow(np.zeros((3, 3), dtype=np.float16)) + # Ensure that drawing doesn't cause crash. + fig.canvas.draw() + + +def test_imshow_float128(): + fig, ax = plt.subplots() + ax.imshow(np.zeros((3, 3), dtype=np.longdouble)) + with (ExitStack() if np.can_cast(np.longdouble, np.float64, "equiv") + else pytest.warns(UserWarning)): + # Ensure that drawing doesn't cause crash. + fig.canvas.draw() + + +def test_imshow_bool(): + fig, ax = plt.subplots() + ax.imshow(np.array([[True, False], [False, True]], dtype=bool)) + + +def test_full_invalid(): + fig, ax = plt.subplots() + ax.imshow(np.full((10, 10), np.nan)) + + fig.canvas.draw() + + +@pytest.mark.parametrize("fmt,counted", + [("ps", b" colorimage"), ("svg", b"<image")]) +@pytest.mark.parametrize("composite_image,count", [(True, 1), (False, 2)]) +def test_composite(fmt, counted, composite_image, count): + # Test that figures can be saved with and without combining multiple images + # (on a single set of axes) into a single composite image. + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + + fig, ax = plt.subplots() + ax.set_xlim(0, 3) + ax.imshow(Z, extent=[0, 1, 0, 1]) + ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) + plt.rcParams['image.composite_image'] = composite_image + buf = io.BytesIO() + fig.savefig(buf, format=fmt) + assert buf.getvalue().count(counted) == count + + +def test_relim(): + fig, ax = plt.subplots() + ax.imshow([[0]], extent=(0, 1, 0, 1)) + ax.relim() + ax.autoscale() + assert ax.get_xlim() == ax.get_ylim() == (0, 1) + + +def test_unclipped(): + fig, ax = plt.subplots() + ax.set_axis_off() + im = ax.imshow([[0, 0], [0, 0]], aspect="auto", extent=(-10, 10, -10, 10), + cmap='gray', clip_on=False) + ax.set(xlim=(0, 1), ylim=(0, 1)) + fig.canvas.draw() + # The unclipped image should fill the *entire* figure and be black. + # Ignore alpha for this comparison. + assert (np.array(fig.canvas.buffer_rgba())[..., :3] == 0).all() + + +def test_respects_bbox(): + fig, axs = plt.subplots(2) + for ax in axs: + ax.set_axis_off() + im = axs[1].imshow([[0, 1], [2, 3]], aspect="auto", extent=(0, 1, 0, 1)) + im.set_clip_path(None) + # Make the image invisible in axs[1], but visible in axs[0] if we pan + # axs[1] up. + im.set_clip_box(axs[0].bbox) + buf_before = io.BytesIO() + fig.savefig(buf_before, format="rgba") + assert {*buf_before.getvalue()} == {0xff} # All white. + axs[1].set(ylim=(-1, 0)) + buf_after = io.BytesIO() + fig.savefig(buf_after, format="rgba") + assert buf_before.getvalue() != buf_after.getvalue() # Not all white. + + +def test_image_cursor_formatting(): + fig, ax = plt.subplots() + # Create a dummy image to be able to call format_cursor_data + im = ax.imshow(np.zeros((4, 4))) + + data = np.ma.masked_array([0], mask=[True]) + assert im.format_cursor_data(data) == '[]' + + data = np.ma.masked_array([0], mask=[False]) + assert im.format_cursor_data(data) == '[0]' + + data = np.nan + assert im.format_cursor_data(data) == '[nan]' + + +@check_figures_equal() +def test_image_array_alpha(fig_test, fig_ref): + """Per-pixel alpha channel test.""" + x = np.linspace(0, 1) + xx, yy = np.meshgrid(x, x) + + zz = np.exp(- 3 * ((xx - 0.5) ** 2) + (yy - 0.7 ** 2)) + alpha = zz / zz.max() + + cmap = mpl.colormaps['viridis'] + ax = fig_test.add_subplot() + ax.imshow(zz, alpha=alpha, cmap=cmap, interpolation='nearest') + + ax = fig_ref.add_subplot() + rgba = cmap(colors.Normalize()(zz)) + rgba[..., -1] = alpha + ax.imshow(rgba, interpolation='nearest') + + +def test_image_array_alpha_validation(): + with pytest.raises(TypeError, match="alpha must be a float, two-d"): + plt.imshow(np.zeros((2, 2)), alpha=[1, 1]) + + +@mpl.style.context('mpl20') +def test_exact_vmin(): + cmap = copy(mpl.colormaps["autumn_r"]) + cmap.set_under(color="lightgrey") + + # make the image exactly 190 pixels wide + fig = plt.figure(figsize=(1.9, 0.1), dpi=100) + ax = fig.add_axes([0, 0, 1, 1]) + + data = np.array( + [[-1, -1, -1, 0, 0, 0, 0, 43, 79, 95, 66, 1, -1, -1, -1, 0, 0, 0, 34]], + dtype=float, + ) + + im = ax.imshow(data, aspect="auto", cmap=cmap, vmin=0, vmax=100) + ax.axis("off") + fig.canvas.draw() + + # get the RGBA slice from the image + from_image = im.make_image(fig.canvas.renderer)[0][0] + # expand the input to be 190 long and run through norm / cmap + direct_computation = ( + im.cmap(im.norm((data * ([[1]] * 10)).T.ravel())) * 255 + ).astype(int) + + # check than the RBGA values are the same + assert np.all(from_image == direct_computation) + + +@image_comparison(['image_placement'], extensions=['svg', 'pdf'], + remove_text=True, style='mpl20') +def test_image_placement(): + """ + The red box should line up exactly with the outside of the image. + """ + fig, ax = plt.subplots() + ax.plot([0, 0, 1, 1, 0], [0, 1, 1, 0, 0], color='r', lw=0.1) + np.random.seed(19680801) + ax.imshow(np.random.randn(16, 16), cmap='Blues', extent=(0, 1, 0, 1), + interpolation='none', vmin=-1, vmax=1) + ax.set_xlim(-0.1, 1+0.1) + ax.set_ylim(-0.1, 1+0.1) + + +# A basic ndarray subclass that implements a quantity +# It does not implement an entire unit system or all quantity math. +# There is just enough implemented to test handling of ndarray +# subclasses. +class QuantityND(np.ndarray): + def __new__(cls, input_array, units): + obj = np.asarray(input_array).view(cls) + obj.units = units + return obj + + def __array_finalize__(self, obj): + self.units = getattr(obj, "units", None) + + def __getitem__(self, item): + units = getattr(self, "units", None) + ret = super().__getitem__(item) + if isinstance(ret, QuantityND) or units is not None: + ret = QuantityND(ret, units) + return ret + + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + func = getattr(ufunc, method) + if "out" in kwargs: + return NotImplemented + if len(inputs) == 1: + i0 = inputs[0] + unit = getattr(i0, "units", "dimensionless") + out_arr = func(np.asarray(i0), **kwargs) + elif len(inputs) == 2: + i0 = inputs[0] + i1 = inputs[1] + u0 = getattr(i0, "units", "dimensionless") + u1 = getattr(i1, "units", "dimensionless") + u0 = u1 if u0 is None else u0 + u1 = u0 if u1 is None else u1 + if ufunc in [np.add, np.subtract]: + if u0 != u1: + raise ValueError + unit = u0 + elif ufunc == np.multiply: + unit = f"{u0}*{u1}" + elif ufunc == np.divide: + unit = f"{u0}/({u1})" + elif ufunc in (np.greater, np.greater_equal, + np.equal, np.not_equal, + np.less, np.less_equal): + # Comparisons produce unitless booleans for output + unit = None + else: + return NotImplemented + out_arr = func(i0.view(np.ndarray), i1.view(np.ndarray), **kwargs) + else: + return NotImplemented + if unit is None: + out_arr = np.array(out_arr) + else: + out_arr = QuantityND(out_arr, unit) + return out_arr + + @property + def v(self): + return self.view(np.ndarray) + + +def test_quantitynd(): + q = QuantityND([1, 2], "m") + q0, q1 = q[:] + assert np.all(q.v == np.asarray([1, 2])) + assert q.units == "m" + assert np.all((q0 + q1).v == np.asarray([3])) + assert (q0 * q1).units == "m*m" + assert (q1 / q0).units == "m/(m)" + with pytest.raises(ValueError): + q0 + QuantityND(1, "s") + + +def test_imshow_quantitynd(): + # generate a dummy ndarray subclass + arr = QuantityND(np.ones((2, 2)), "m") + fig, ax = plt.subplots() + ax.imshow(arr) + # executing the draw should not raise an exception + fig.canvas.draw() + + +@check_figures_equal(extensions=['png']) +def test_norm_change(fig_test, fig_ref): + # LogNorm should not mask anything invalid permanently. + data = np.full((5, 5), 1, dtype=np.float64) + data[0:2, :] = -1 + + masked_data = np.ma.array(data, mask=False) + masked_data.mask[0:2, 0:2] = True + + cmap = mpl.colormaps['viridis'].with_extremes(under='w') + + ax = fig_test.subplots() + im = ax.imshow(data, norm=colors.LogNorm(vmin=0.5, vmax=1), + extent=(0, 5, 0, 5), interpolation='nearest', cmap=cmap) + im.set_norm(colors.Normalize(vmin=-2, vmax=2)) + im = ax.imshow(masked_data, norm=colors.LogNorm(vmin=0.5, vmax=1), + extent=(5, 10, 5, 10), interpolation='nearest', cmap=cmap) + im.set_norm(colors.Normalize(vmin=-2, vmax=2)) + ax.set(xlim=(0, 10), ylim=(0, 10)) + + ax = fig_ref.subplots() + ax.imshow(data, norm=colors.Normalize(vmin=-2, vmax=2), + extent=(0, 5, 0, 5), interpolation='nearest', cmap=cmap) + ax.imshow(masked_data, norm=colors.Normalize(vmin=-2, vmax=2), + extent=(5, 10, 5, 10), interpolation='nearest', cmap=cmap) + ax.set(xlim=(0, 10), ylim=(0, 10)) + + +@pytest.mark.parametrize('x', [-1, 1]) +@check_figures_equal(extensions=['png']) +def test_huge_range_log(fig_test, fig_ref, x): + # parametrize over bad lognorm -1 values and large range 1 -> 1e20 + data = np.full((5, 5), x, dtype=np.float64) + data[0:2, :] = 1E20 + + ax = fig_test.subplots() + ax.imshow(data, norm=colors.LogNorm(vmin=1, vmax=data.max()), + interpolation='nearest', cmap='viridis') + + data = np.full((5, 5), x, dtype=np.float64) + data[0:2, :] = 1000 + + ax = fig_ref.subplots() + cmap = mpl.colormaps['viridis'].with_extremes(under='w') + ax.imshow(data, norm=colors.Normalize(vmin=1, vmax=data.max()), + interpolation='nearest', cmap=cmap) + + +@check_figures_equal() +def test_spy_box(fig_test, fig_ref): + # setting up reference and test + ax_test = fig_test.subplots(1, 3) + ax_ref = fig_ref.subplots(1, 3) + + plot_data = ( + [[1, 1], [1, 1]], + [[0, 0], [0, 0]], + [[0, 1], [1, 0]], + ) + plot_titles = ["ones", "zeros", "mixed"] + + for i, (z, title) in enumerate(zip(plot_data, plot_titles)): + ax_test[i].set_title(title) + ax_test[i].spy(z) + ax_ref[i].set_title(title) + ax_ref[i].imshow(z, interpolation='nearest', + aspect='equal', origin='upper', cmap='Greys', + vmin=0, vmax=1) + ax_ref[i].set_xlim(-0.5, 1.5) + ax_ref[i].set_ylim(1.5, -0.5) + ax_ref[i].xaxis.tick_top() + ax_ref[i].title.set_y(1.05) + ax_ref[i].xaxis.set_ticks_position('both') + ax_ref[i].xaxis.set_major_locator( + mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True) + ) + ax_ref[i].yaxis.set_major_locator( + mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True) + ) + + +@image_comparison(["nonuniform_and_pcolor.png"], style="mpl20") +def test_nonuniform_and_pcolor(): + axs = plt.figure(figsize=(3, 3)).subplots(3, sharex=True, sharey=True) + for ax, interpolation in zip(axs, ["nearest", "bilinear"]): + im = NonUniformImage(ax, interpolation=interpolation) + im.set_data(np.arange(3) ** 2, np.arange(3) ** 2, + np.arange(9).reshape((3, 3))) + ax.add_image(im) + axs[2].pcolorfast( # PcolorImage + np.arange(4) ** 2, np.arange(4) ** 2, np.arange(9).reshape((3, 3))) + for ax in axs: + ax.set_axis_off() + # NonUniformImage "leaks" out of extents, not PColorImage. + ax.set(xlim=(0, 10)) + + +@image_comparison( + ['rgba_antialias.png'], style='mpl20', remove_text=True, + tol=0.007 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_rgba_antialias(): + fig, axs = plt.subplots(2, 2, figsize=(3.5, 3.5), sharex=False, + sharey=False, constrained_layout=True) + N = 250 + aa = np.ones((N, N)) + aa[::2, :] = -1 + + x = np.arange(N) / N - 0.5 + y = np.arange(N) / N - 0.5 + + X, Y = np.meshgrid(x, y) + R = np.sqrt(X**2 + Y**2) + f0 = 10 + k = 75 + # aliased concentric circles + a = np.sin(np.pi * 2 * (f0 * R + k * R**2 / 2)) + + # stripes on lhs + a[:int(N/2), :][R[:int(N/2), :] < 0.4] = -1 + a[:int(N/2), :][R[:int(N/2), :] < 0.3] = 1 + aa[:, int(N/2):] = a[:, int(N/2):] + + # set some over/unders and NaNs + aa[20:50, 20:50] = np.nan + aa[70:90, 70:90] = 1e6 + aa[70:90, 20:30] = -1e6 + aa[70:90, 195:215] = 1e6 + aa[20:30, 195:215] = -1e6 + + cmap = copy(plt.cm.RdBu_r) + cmap.set_over('yellow') + cmap.set_under('cyan') + + axs = axs.flatten() + # zoom in + axs[0].imshow(aa, interpolation='nearest', cmap=cmap, vmin=-1.2, vmax=1.2) + axs[0].set_xlim([N/2-25, N/2+25]) + axs[0].set_ylim([N/2+50, N/2-10]) + + # no anti-alias + axs[1].imshow(aa, interpolation='nearest', cmap=cmap, vmin=-1.2, vmax=1.2) + + # data antialias: Note no purples, and white in circle. Note + # that alternating red and blue stripes become white. + axs[2].imshow(aa, interpolation='antialiased', interpolation_stage='data', + cmap=cmap, vmin=-1.2, vmax=1.2) + + # rgba antialias: Note purples at boundary with circle. Note that + # alternating red and blue stripes become purple + axs[3].imshow(aa, interpolation='antialiased', interpolation_stage='rgba', + cmap=cmap, vmin=-1.2, vmax=1.2) + + +# We check for the warning with a draw() in the test, but we also need to +# filter the warning as it is emitted by the figure test decorator +@pytest.mark.filterwarnings(r'ignore:Data with more than .* ' + 'cannot be accurately displayed') +@pytest.mark.parametrize('origin', ['upper', 'lower']) +@pytest.mark.parametrize( + 'dim, size, msg', [['row', 2**23, r'2\*\*23 columns'], + ['col', 2**24, r'2\*\*24 rows']]) +@check_figures_equal(extensions=('png', )) +def test_large_image(fig_test, fig_ref, dim, size, msg, origin): + # Check that Matplotlib downsamples images that are too big for AGG + # See issue #19276. Currently the fix only works for png output but not + # pdf or svg output. + ax_test = fig_test.subplots() + ax_ref = fig_ref.subplots() + + array = np.zeros((1, size + 2)) + array[:, array.size // 2:] = 1 + if dim == 'col': + array = array.T + im = ax_test.imshow(array, vmin=0, vmax=1, + aspect='auto', extent=(0, 1, 0, 1), + interpolation='none', + origin=origin) + + with pytest.warns(UserWarning, + match=f'Data with more than {msg} cannot be ' + 'accurately displayed.'): + fig_test.canvas.draw() + + array = np.zeros((1, 2)) + array[:, 1] = 1 + if dim == 'col': + array = array.T + im = ax_ref.imshow(array, vmin=0, vmax=1, aspect='auto', + extent=(0, 1, 0, 1), + interpolation='none', + origin=origin) + + +@check_figures_equal(extensions=["png"]) +def test_str_norms(fig_test, fig_ref): + t = np.random.rand(10, 10) * .8 + .1 # between 0 and 1 + axts = fig_test.subplots(1, 5) + axts[0].imshow(t, norm="log") + axts[1].imshow(t, norm="log", vmin=.2) + axts[2].imshow(t, norm="symlog") + axts[3].imshow(t, norm="symlog", vmin=.3, vmax=.7) + axts[4].imshow(t, norm="logit", vmin=.3, vmax=.7) + axrs = fig_ref.subplots(1, 5) + axrs[0].imshow(t, norm=colors.LogNorm()) + axrs[1].imshow(t, norm=colors.LogNorm(vmin=.2)) + # same linthresh as SymmetricalLogScale's default. + axrs[2].imshow(t, norm=colors.SymLogNorm(linthresh=2)) + axrs[3].imshow(t, norm=colors.SymLogNorm(linthresh=2, vmin=.3, vmax=.7)) + axrs[4].imshow(t, norm="logit", clim=(.3, .7)) + + assert type(axts[0].images[0].norm) is colors.LogNorm # Exactly that class + with pytest.raises(ValueError): + axts[0].imshow(t, norm="foobar") + + +def test__resample_valid_output(): + resample = functools.partial(mpl._image.resample, transform=Affine2D()) + with pytest.raises(ValueError, match="must be a NumPy array"): + resample(np.zeros((9, 9)), None) + with pytest.raises(ValueError, match="different dimensionalities"): + resample(np.zeros((9, 9)), np.zeros((9, 9, 4))) + with pytest.raises(ValueError, match="must be RGBA"): + resample(np.zeros((9, 9, 4)), np.zeros((9, 9, 3))) + with pytest.raises(ValueError, match="Mismatched types"): + resample(np.zeros((9, 9), np.uint8), np.zeros((9, 9))) + with pytest.raises(ValueError, match="must be C-contiguous"): + resample(np.zeros((9, 9)), np.zeros((9, 9)).T) + + +def test_axesimage_get_shape(): + # generate dummy image to test get_shape method + ax = plt.gca() + im = AxesImage(ax) + with pytest.raises(RuntimeError, match="You must first set the image array"): + im.get_shape() + z = np.arange(12, dtype=float).reshape((4, 3)) + im.set_data(z) + assert im.get_shape() == (4, 3) + assert im.get_size() == im.get_shape() + + +def test_non_transdata_image_does_not_touch_aspect(): + ax = plt.figure().add_subplot() + im = np.arange(4).reshape((2, 2)) + ax.imshow(im, transform=ax.transAxes) + assert ax.get_aspect() == "auto" + ax.imshow(im, transform=Affine2D().scale(2) + ax.transData) + assert ax.get_aspect() == 1 + ax.imshow(im, transform=ax.transAxes, aspect=2) + assert ax.get_aspect() == 2 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_legend.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_legend.py new file mode 100644 index 00000000..759ac6aa --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_legend.py @@ -0,0 +1,1343 @@ +import collections +import platform +from unittest import mock +import warnings + +import numpy as np +from numpy.testing import assert_allclose +import pytest + +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing._markers import needs_usetex +import matplotlib.pyplot as plt +import matplotlib as mpl +import matplotlib.patches as mpatches +import matplotlib.transforms as mtransforms +import matplotlib.collections as mcollections +import matplotlib.lines as mlines +from matplotlib.legend_handler import HandlerTuple +import matplotlib.legend as mlegend +from matplotlib import _api, rc_context +from matplotlib.font_manager import FontProperties + + +def test_legend_ordereddict(): + # smoketest that ordereddict inputs work... + + X = np.random.randn(10) + Y = np.random.randn(10) + labels = ['a'] * 5 + ['b'] * 5 + colors = ['r'] * 5 + ['g'] * 5 + + fig, ax = plt.subplots() + for x, y, label, color in zip(X, Y, labels, colors): + ax.scatter(x, y, label=label, c=color) + + handles, labels = ax.get_legend_handles_labels() + legend = collections.OrderedDict(zip(labels, handles)) + ax.legend(legend.values(), legend.keys(), + loc='center left', bbox_to_anchor=(1, .5)) + + +@image_comparison(['legend_auto1'], remove_text=True) +def test_legend_auto1(): + """Test automatic legend placement""" + fig, ax = plt.subplots() + x = np.arange(100) + ax.plot(x, 50 - x, 'o', label='y=1') + ax.plot(x, x - 50, 'o', label='y=-1') + ax.legend(loc='best') + + +@image_comparison(['legend_auto2'], remove_text=True) +def test_legend_auto2(): + """Test automatic legend placement""" + fig, ax = plt.subplots() + x = np.arange(100) + b1 = ax.bar(x, x, align='edge', color='m') + b2 = ax.bar(x, x[::-1], align='edge', color='g') + ax.legend([b1[0], b2[0]], ['up', 'down'], loc='best') + + +@image_comparison(['legend_auto3']) +def test_legend_auto3(): + """Test automatic legend placement""" + fig, ax = plt.subplots() + x = [0.9, 0.1, 0.1, 0.9, 0.9, 0.5] + y = [0.95, 0.95, 0.05, 0.05, 0.5, 0.5] + ax.plot(x, y, 'o-', label='line') + ax.set_xlim(0.0, 1.0) + ax.set_ylim(0.0, 1.0) + ax.legend(loc='best') + + +def test_legend_auto4(): + """ + Check that the legend location with automatic placement is the same, + whatever the histogram type is. Related to issue #9580. + """ + # NB: barstacked is pointless with a single dataset. + fig, axs = plt.subplots(ncols=3, figsize=(6.4, 2.4)) + leg_bboxes = [] + for ax, ht in zip(axs.flat, ('bar', 'step', 'stepfilled')): + ax.set_title(ht) + # A high bar on the left but an even higher one on the right. + ax.hist([0] + 5*[9], bins=range(10), label="Legend", histtype=ht) + leg = ax.legend(loc="best") + fig.canvas.draw() + leg_bboxes.append( + leg.get_window_extent().transformed(ax.transAxes.inverted())) + + # The histogram type "bar" is assumed to be the correct reference. + assert_allclose(leg_bboxes[1].bounds, leg_bboxes[0].bounds) + assert_allclose(leg_bboxes[2].bounds, leg_bboxes[0].bounds) + + +def test_legend_auto5(): + """ + Check that the automatic placement handle a rather complex + case with non rectangular patch. Related to issue #9580. + """ + fig, axs = plt.subplots(ncols=2, figsize=(9.6, 4.8)) + + leg_bboxes = [] + for ax, loc in zip(axs.flat, ("center", "best")): + # An Ellipse patch at the top, a U-shaped Polygon patch at the + # bottom and a ring-like Wedge patch: the correct placement of + # the legend should be in the center. + for _patch in [ + mpatches.Ellipse( + xy=(0.5, 0.9), width=0.8, height=0.2, fc="C1"), + mpatches.Polygon(np.array([ + [0, 1], [0, 0], [1, 0], [1, 1], [0.9, 1.0], [0.9, 0.1], + [0.1, 0.1], [0.1, 1.0], [0.1, 1.0]]), fc="C1"), + mpatches.Wedge((0.5, 0.5), 0.5, 0, 360, width=0.05, fc="C0") + ]: + ax.add_patch(_patch) + + ax.plot([0.1, 0.9], [0.9, 0.9], label="A segment") # sthg to label + + leg = ax.legend(loc=loc) + fig.canvas.draw() + leg_bboxes.append( + leg.get_window_extent().transformed(ax.transAxes.inverted())) + + assert_allclose(leg_bboxes[1].bounds, leg_bboxes[0].bounds) + + +@image_comparison(['legend_various_labels'], remove_text=True) +def test_various_labels(): + # tests all sorts of label types + fig = plt.figure() + ax = fig.add_subplot(121) + ax.plot(np.arange(4), 'o', label=1) + ax.plot(np.linspace(4, 4.1), 'o', label='Développés') + ax.plot(np.arange(4, 1, -1), 'o', label='__nolegend__') + ax.legend(numpoints=1, loc='best') + + +def test_legend_label_with_leading_underscore(): + """ + Test that artists with labels starting with an underscore are not added to + the legend, and that a warning is issued if one tries to add them + explicitly. + """ + fig, ax = plt.subplots() + line, = ax.plot([0, 1], label='_foo') + with pytest.warns(_api.MatplotlibDeprecationWarning, match="with an underscore"): + legend = ax.legend(handles=[line]) + assert len(legend.legend_handles) == 0 + + +@image_comparison(['legend_labels_first.png'], remove_text=True) +def test_labels_first(): + # test labels to left of markers + fig, ax = plt.subplots() + ax.plot(np.arange(10), '-o', label=1) + ax.plot(np.ones(10)*5, ':x', label="x") + ax.plot(np.arange(20, 10, -1), 'd', label="diamond") + ax.legend(loc='best', markerfirst=False) + + +@image_comparison(['legend_multiple_keys.png'], remove_text=True) +def test_multiple_keys(): + # test legend entries with multiple keys + fig, ax = plt.subplots() + p1, = ax.plot([1, 2, 3], '-o') + p2, = ax.plot([2, 3, 4], '-x') + p3, = ax.plot([3, 4, 5], '-d') + ax.legend([(p1, p2), (p2, p1), p3], ['two keys', 'pad=0', 'one key'], + numpoints=1, + handler_map={(p1, p2): HandlerTuple(ndivide=None), + (p2, p1): HandlerTuple(ndivide=None, pad=0)}) + + +@image_comparison(['rgba_alpha.png'], remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.01) +def test_alpha_rgba(): + fig, ax = plt.subplots() + ax.plot(range(10), lw=5) + leg = plt.legend(['Longlabel that will go away'], loc='center') + leg.legendPatch.set_facecolor([1, 0, 0, 0.5]) + + +@image_comparison(['rcparam_alpha.png'], remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.01) +def test_alpha_rcparam(): + fig, ax = plt.subplots() + ax.plot(range(10), lw=5) + with mpl.rc_context(rc={'legend.framealpha': .75}): + leg = plt.legend(['Longlabel that will go away'], loc='center') + # this alpha is going to be over-ridden by the rcparam with + # sets the alpha of the patch to be non-None which causes the alpha + # value of the face color to be discarded. This behavior may not be + # ideal, but it is what it is and we should keep track of it changing + leg.legendPatch.set_facecolor([1, 0, 0, 0.5]) + + +@image_comparison(['fancy'], remove_text=True, tol=0.05) +def test_fancy(): + # Tolerance caused by changing default shadow "shade" from 0.3 to 1 - 0.7 = + # 0.30000000000000004 + # using subplot triggers some offsetbox functionality untested elsewhere + plt.subplot(121) + plt.plot([5] * 10, 'o--', label='XX') + plt.scatter(np.arange(10), np.arange(10, 0, -1), label='XX\nXX') + plt.errorbar(np.arange(10), np.arange(10), xerr=0.5, + yerr=0.5, label='XX') + plt.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], + ncols=2, shadow=True, title="My legend", numpoints=1) + + +@image_comparison(['framealpha'], remove_text=True, + tol=0 if platform.machine() == 'x86_64' else 0.02) +def test_framealpha(): + x = np.linspace(1, 100, 100) + y = x + plt.plot(x, y, label='mylabel', lw=10) + plt.legend(framealpha=0.5) + + +@image_comparison(['scatter_rc3', 'scatter_rc1'], remove_text=True) +def test_rc(): + # using subplot triggers some offsetbox functionality untested elsewhere + plt.figure() + ax = plt.subplot(121) + ax.scatter(np.arange(10), np.arange(10, 0, -1), label='three') + ax.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], + title="My legend") + + mpl.rcParams['legend.scatterpoints'] = 1 + plt.figure() + ax = plt.subplot(121) + ax.scatter(np.arange(10), np.arange(10, 0, -1), label='one') + ax.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], + title="My legend") + + +@image_comparison(['legend_expand'], remove_text=True) +def test_legend_expand(): + """Test expand mode""" + legend_modes = [None, "expand"] + fig, axs = plt.subplots(len(legend_modes), 1) + x = np.arange(100) + for ax, mode in zip(axs, legend_modes): + ax.plot(x, 50 - x, 'o', label='y=1') + l1 = ax.legend(loc='upper left', mode=mode) + ax.add_artist(l1) + ax.plot(x, x - 50, 'o', label='y=-1') + l2 = ax.legend(loc='right', mode=mode) + ax.add_artist(l2) + ax.legend(loc='lower left', mode=mode, ncols=2) + + +@image_comparison(['hatching'], remove_text=True, style='default') +def test_hatching(): + # Remove legend texts when this image is regenerated. + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, ax = plt.subplots() + + # Patches + patch = plt.Rectangle((0, 0), 0.3, 0.3, hatch='xx', + label='Patch\ndefault color\nfilled') + ax.add_patch(patch) + patch = plt.Rectangle((0.33, 0), 0.3, 0.3, hatch='||', edgecolor='C1', + label='Patch\nexplicit color\nfilled') + ax.add_patch(patch) + patch = plt.Rectangle((0, 0.4), 0.3, 0.3, hatch='xx', fill=False, + label='Patch\ndefault color\nunfilled') + ax.add_patch(patch) + patch = plt.Rectangle((0.33, 0.4), 0.3, 0.3, hatch='||', fill=False, + edgecolor='C1', + label='Patch\nexplicit color\nunfilled') + ax.add_patch(patch) + + # Paths + ax.fill_between([0, .15, .3], [.8, .8, .8], [.9, 1.0, .9], + hatch='+', label='Path\ndefault color') + ax.fill_between([.33, .48, .63], [.8, .8, .8], [.9, 1.0, .9], + hatch='+', edgecolor='C2', label='Path\nexplicit color') + + ax.set_xlim(-0.01, 1.1) + ax.set_ylim(-0.01, 1.1) + ax.legend(handlelength=4, handleheight=4) + + +def test_legend_remove(): + fig, ax = plt.subplots() + lines = ax.plot(range(10)) + leg = fig.legend(lines, "test") + leg.remove() + assert fig.legends == [] + leg = ax.legend("test") + leg.remove() + assert ax.get_legend() is None + + +def test_reverse_legend_handles_and_labels(): + """Check that the legend handles and labels are reversed.""" + fig, ax = plt.subplots() + x = 1 + y = 1 + labels = ["First label", "Second label", "Third label"] + markers = ['.', ',', 'o'] + + ax.plot(x, y, markers[0], label=labels[0]) + ax.plot(x, y, markers[1], label=labels[1]) + ax.plot(x, y, markers[2], label=labels[2]) + leg = ax.legend(reverse=True) + actual_labels = [t.get_text() for t in leg.get_texts()] + actual_markers = [h.get_marker() for h in leg.legend_handles] + assert actual_labels == list(reversed(labels)) + assert actual_markers == list(reversed(markers)) + + +@check_figures_equal(extensions=["png"]) +def test_reverse_legend_display(fig_test, fig_ref): + """Check that the rendered legend entries are reversed""" + ax = fig_test.subplots() + ax.plot([1], 'ro', label="first") + ax.plot([2], 'bx', label="second") + ax.legend(reverse=True) + + ax = fig_ref.subplots() + ax.plot([2], 'bx', label="second") + ax.plot([1], 'ro', label="first") + ax.legend() + + +class TestLegendFunction: + # Tests the legend function on the Axes and pyplot. + def test_legend_no_args(self): + lines = plt.plot(range(10), label='hello world') + with mock.patch('matplotlib.legend.Legend') as Legend: + plt.legend() + Legend.assert_called_with(plt.gca(), lines, ['hello world']) + + def test_legend_positional_handles_labels(self): + lines = plt.plot(range(10)) + with mock.patch('matplotlib.legend.Legend') as Legend: + plt.legend(lines, ['hello world']) + Legend.assert_called_with(plt.gca(), lines, ['hello world']) + + def test_legend_positional_handles_only(self): + lines = plt.plot(range(10)) + with pytest.raises(TypeError, match='but found an Artist'): + # a single arg is interpreted as labels + # it's a common error to just pass handles + plt.legend(lines) + + def test_legend_positional_labels_only(self): + lines = plt.plot(range(10), label='hello world') + with mock.patch('matplotlib.legend.Legend') as Legend: + plt.legend(['foobar']) + Legend.assert_called_with(plt.gca(), lines, ['foobar']) + + def test_legend_three_args(self): + lines = plt.plot(range(10), label='hello world') + with mock.patch('matplotlib.legend.Legend') as Legend: + plt.legend(lines, ['foobar'], loc='right') + Legend.assert_called_with(plt.gca(), lines, ['foobar'], loc='right') + + def test_legend_handler_map(self): + lines = plt.plot(range(10), label='hello world') + with mock.patch('matplotlib.legend.' + '_get_legend_handles_labels') as handles_labels: + handles_labels.return_value = lines, ['hello world'] + plt.legend(handler_map={'1': 2}) + handles_labels.assert_called_with([plt.gca()], {'1': 2}) + + def test_legend_kwargs_handles_only(self): + fig, ax = plt.subplots() + x = np.linspace(0, 1, 11) + ln1, = ax.plot(x, x, label='x') + ln2, = ax.plot(x, 2*x, label='2x') + ln3, = ax.plot(x, 3*x, label='3x') + with mock.patch('matplotlib.legend.Legend') as Legend: + ax.legend(handles=[ln3, ln2]) # reversed and not ln1 + Legend.assert_called_with(ax, [ln3, ln2], ['3x', '2x']) + + def test_legend_kwargs_labels_only(self): + fig, ax = plt.subplots() + x = np.linspace(0, 1, 11) + ln1, = ax.plot(x, x) + ln2, = ax.plot(x, 2*x) + with mock.patch('matplotlib.legend.Legend') as Legend: + ax.legend(labels=['x', '2x']) + Legend.assert_called_with(ax, [ln1, ln2], ['x', '2x']) + + def test_legend_kwargs_handles_labels(self): + fig, ax = plt.subplots() + th = np.linspace(0, 2*np.pi, 1024) + lns, = ax.plot(th, np.sin(th), label='sin') + lnc, = ax.plot(th, np.cos(th), label='cos') + with mock.patch('matplotlib.legend.Legend') as Legend: + # labels of lns, lnc are overwritten with explicit ('a', 'b') + ax.legend(labels=('a', 'b'), handles=(lnc, lns)) + Legend.assert_called_with(ax, (lnc, lns), ('a', 'b')) + + def test_warn_mixed_args_and_kwargs(self): + fig, ax = plt.subplots() + th = np.linspace(0, 2*np.pi, 1024) + lns, = ax.plot(th, np.sin(th), label='sin') + lnc, = ax.plot(th, np.cos(th), label='cos') + with pytest.warns(UserWarning) as record: + ax.legend((lnc, lns), labels=('a', 'b')) + assert len(record) == 1 + assert str(record[0].message) == ( + "You have mixed positional and keyword arguments, some input may " + "be discarded.") + + def test_parasite(self): + from mpl_toolkits.axes_grid1 import host_subplot # type: ignore + + host = host_subplot(111) + par = host.twinx() + + p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") + p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature") + + with mock.patch('matplotlib.legend.Legend') as Legend: + plt.legend() + Legend.assert_called_with(host, [p1, p2], ['Density', 'Temperature']) + + +class TestLegendFigureFunction: + # Tests the legend function for figure + def test_legend_handle_label(self): + fig, ax = plt.subplots() + lines = ax.plot(range(10)) + with mock.patch('matplotlib.legend.Legend') as Legend: + fig.legend(lines, ['hello world']) + Legend.assert_called_with(fig, lines, ['hello world'], + bbox_transform=fig.transFigure) + + def test_legend_no_args(self): + fig, ax = plt.subplots() + lines = ax.plot(range(10), label='hello world') + with mock.patch('matplotlib.legend.Legend') as Legend: + fig.legend() + Legend.assert_called_with(fig, lines, ['hello world'], + bbox_transform=fig.transFigure) + + def test_legend_label_arg(self): + fig, ax = plt.subplots() + lines = ax.plot(range(10)) + with mock.patch('matplotlib.legend.Legend') as Legend: + fig.legend(['foobar']) + Legend.assert_called_with(fig, lines, ['foobar'], + bbox_transform=fig.transFigure) + + def test_legend_label_three_args(self): + fig, ax = plt.subplots() + lines = ax.plot(range(10)) + with pytest.raises(TypeError, match="0-2"): + fig.legend(lines, ['foobar'], 'right') + with pytest.raises(TypeError, match="0-2"): + fig.legend(lines, ['foobar'], 'right', loc='left') + + def test_legend_kw_args(self): + fig, axs = plt.subplots(1, 2) + lines = axs[0].plot(range(10)) + lines2 = axs[1].plot(np.arange(10) * 2.) + with mock.patch('matplotlib.legend.Legend') as Legend: + fig.legend(loc='right', labels=('a', 'b'), handles=(lines, lines2)) + Legend.assert_called_with( + fig, (lines, lines2), ('a', 'b'), loc='right', + bbox_transform=fig.transFigure) + + def test_warn_args_kwargs(self): + fig, axs = plt.subplots(1, 2) + lines = axs[0].plot(range(10)) + lines2 = axs[1].plot(np.arange(10) * 2.) + with pytest.warns(UserWarning) as record: + fig.legend((lines, lines2), labels=('a', 'b')) + assert len(record) == 1 + assert str(record[0].message) == ( + "You have mixed positional and keyword arguments, some input may " + "be discarded.") + + +def test_figure_legend_outside(): + todos = ['upper ' + pos for pos in ['left', 'center', 'right']] + todos += ['lower ' + pos for pos in ['left', 'center', 'right']] + todos += ['left ' + pos for pos in ['lower', 'center', 'upper']] + todos += ['right ' + pos for pos in ['lower', 'center', 'upper']] + + upperext = [20.347556, 27.722556, 790.583, 545.499] + lowerext = [20.347556, 71.056556, 790.583, 588.833] + leftext = [151.681556, 27.722556, 790.583, 588.833] + rightext = [20.347556, 27.722556, 659.249, 588.833] + axbb = [upperext, upperext, upperext, + lowerext, lowerext, lowerext, + leftext, leftext, leftext, + rightext, rightext, rightext] + + legbb = [[10., 555., 133., 590.], # upper left + [338.5, 555., 461.5, 590.], # upper center + [667, 555., 790., 590.], # upper right + [10., 10., 133., 45.], # lower left + [338.5, 10., 461.5, 45.], # lower center + [667., 10., 790., 45.], # lower right + [10., 10., 133., 45.], # left lower + [10., 282.5, 133., 317.5], # left center + [10., 555., 133., 590.], # left upper + [667, 10., 790., 45.], # right lower + [667., 282.5, 790., 317.5], # right center + [667., 555., 790., 590.]] # right upper + + for nn, todo in enumerate(todos): + print(todo) + fig, axs = plt.subplots(constrained_layout=True, dpi=100) + axs.plot(range(10), label='Boo1') + leg = fig.legend(loc='outside ' + todo) + fig.draw_without_rendering() + + assert_allclose(axs.get_window_extent().extents, + axbb[nn]) + assert_allclose(leg.get_window_extent().extents, + legbb[nn]) + + +@image_comparison(['legend_stackplot.png']) +def test_legend_stackplot(): + """Test legend for PolyCollection using stackplot.""" + # related to #1341, #1943, and PR #3303 + fig, ax = plt.subplots() + x = np.linspace(0, 10, 10) + y1 = 1.0 * x + y2 = 2.0 * x + 1 + y3 = 3.0 * x + 2 + ax.stackplot(x, y1, y2, y3, labels=['y1', 'y2', 'y3']) + ax.set_xlim((0, 10)) + ax.set_ylim((0, 70)) + ax.legend(loc='best') + + +def test_cross_figure_patch_legend(): + fig, ax = plt.subplots() + fig2, ax2 = plt.subplots() + + brs = ax.bar(range(3), range(3)) + fig2.legend(brs, 'foo') + + +def test_nanscatter(): + fig, ax = plt.subplots() + + h = ax.scatter([np.nan], [np.nan], marker="o", + facecolor="r", edgecolor="r", s=3) + + ax.legend([h], ["scatter"]) + + fig, ax = plt.subplots() + for color in ['red', 'green', 'blue']: + n = 750 + x, y = np.random.rand(2, n) + scale = 200.0 * np.random.rand(n) + ax.scatter(x, y, c=color, s=scale, label=color, + alpha=0.3, edgecolors='none') + + ax.legend() + ax.grid(True) + + +def test_legend_repeatcheckok(): + fig, ax = plt.subplots() + ax.scatter(0.0, 1.0, color='k', marker='o', label='test') + ax.scatter(0.5, 0.0, color='r', marker='v', label='test') + ax.legend() + hand, lab = mlegend._get_legend_handles_labels([ax]) + assert len(lab) == 2 + fig, ax = plt.subplots() + ax.scatter(0.0, 1.0, color='k', marker='o', label='test') + ax.scatter(0.5, 0.0, color='k', marker='v', label='test') + ax.legend() + hand, lab = mlegend._get_legend_handles_labels([ax]) + assert len(lab) == 2 + + +@image_comparison(['not_covering_scatter.png']) +def test_not_covering_scatter(): + colors = ['b', 'g', 'r'] + + for n in range(3): + plt.scatter([n], [n], color=colors[n]) + + plt.legend(['foo', 'foo', 'foo'], loc='best') + plt.gca().set_xlim(-0.5, 2.2) + plt.gca().set_ylim(-0.5, 2.2) + + +@image_comparison(['not_covering_scatter_transform.png']) +def test_not_covering_scatter_transform(): + # Offsets point to top left, the default auto position + offset = mtransforms.Affine2D().translate(-20, 20) + x = np.linspace(0, 30, 1000) + plt.plot(x, x) + + plt.scatter([20], [10], transform=offset + plt.gca().transData) + + plt.legend(['foo', 'bar'], loc='best') + + +def test_linecollection_scaled_dashes(): + lines1 = [[(0, .5), (.5, 1)], [(.3, .6), (.2, .2)]] + lines2 = [[[0.7, .2], [.8, .4]], [[.5, .7], [.6, .1]]] + lines3 = [[[0.6, .2], [.8, .4]], [[.5, .7], [.1, .1]]] + lc1 = mcollections.LineCollection(lines1, linestyles="--", lw=3) + lc2 = mcollections.LineCollection(lines2, linestyles="-.") + lc3 = mcollections.LineCollection(lines3, linestyles=":", lw=.5) + + fig, ax = plt.subplots() + ax.add_collection(lc1) + ax.add_collection(lc2) + ax.add_collection(lc3) + + leg = ax.legend([lc1, lc2, lc3], ["line1", "line2", 'line 3']) + h1, h2, h3 = leg.legend_handles + + for oh, lh in zip((lc1, lc2, lc3), (h1, h2, h3)): + assert oh.get_linestyles()[0] == lh._dash_pattern + + +def test_handler_numpoints(): + """Test legend handler with numpoints <= 1.""" + # related to #6921 and PR #8478 + fig, ax = plt.subplots() + ax.plot(range(5), label='test') + ax.legend(numpoints=0.5) + + +def test_text_nohandler_warning(): + """Test that Text artists with labels raise a warning""" + fig, ax = plt.subplots() + ax.text(x=0, y=0, s="text", label="label") + with pytest.warns(UserWarning) as record: + ax.legend() + assert len(record) == 1 + + # this should _not_ warn: + f, ax = plt.subplots() + ax.pcolormesh(np.random.uniform(0, 1, (10, 10))) + with warnings.catch_warnings(): + warnings.simplefilter("error") + ax.get_legend_handles_labels() + + +def test_empty_bar_chart_with_legend(): + """Test legend when bar chart is empty with a label.""" + # related to issue #13003. Calling plt.legend() should not + # raise an IndexError. + plt.bar([], [], label='test') + plt.legend() + + +@image_comparison(['shadow_argument_types.png'], remove_text=True, + style='mpl20') +def test_shadow_argument_types(): + # Test that different arguments for shadow work as expected + fig, ax = plt.subplots() + ax.plot([1, 2, 3], label='test') + + # Test various shadow configurations + # as well as different ways of specifying colors + legs = (ax.legend(loc='upper left', shadow=True), # True + ax.legend(loc='upper right', shadow=False), # False + ax.legend(loc='center left', # string + shadow={'color': 'red', 'alpha': 0.1}), + ax.legend(loc='center right', # tuple + shadow={'color': (0.1, 0.2, 0.5), 'oy': -5}), + ax.legend(loc='lower left', # tab + shadow={'color': 'tab:cyan', 'ox': 10}) + ) + for l in legs: + ax.add_artist(l) + ax.legend(loc='lower right') # default + + +def test_shadow_invalid_argument(): + # Test if invalid argument to legend shadow + # (i.e. not [color|bool]) raises ValueError + fig, ax = plt.subplots() + ax.plot([1, 2, 3], label='test') + with pytest.raises(ValueError, match="dict or bool"): + ax.legend(loc="upper left", shadow="aardvark") # Bad argument + + +def test_shadow_framealpha(): + # Test if framealpha is activated when shadow is True + # and framealpha is not explicitly passed''' + fig, ax = plt.subplots() + ax.plot(range(100), label="test") + leg = ax.legend(shadow=True, facecolor='w') + assert leg.get_frame().get_alpha() == 1 + + +def test_legend_title_empty(): + # test that if we don't set the legend title, that + # it comes back as an empty string, and that it is not + # visible: + fig, ax = plt.subplots() + ax.plot(range(10)) + leg = ax.legend() + assert leg.get_title().get_text() == "" + assert not leg.get_title().get_visible() + + +def test_legend_proper_window_extent(): + # test that legend returns the expected extent under various dpi... + fig, ax = plt.subplots(dpi=100) + ax.plot(range(10), label='Aardvark') + leg = ax.legend() + x01 = leg.get_window_extent(fig.canvas.get_renderer()).x0 + + fig, ax = plt.subplots(dpi=200) + ax.plot(range(10), label='Aardvark') + leg = ax.legend() + x02 = leg.get_window_extent(fig.canvas.get_renderer()).x0 + assert pytest.approx(x01*2, 0.1) == x02 + + +def test_window_extent_cached_renderer(): + fig, ax = plt.subplots(dpi=100) + ax.plot(range(10), label='Aardvark') + leg = ax.legend() + leg2 = fig.legend() + fig.canvas.draw() + # check that get_window_extent will use the cached renderer + leg.get_window_extent() + leg2.get_window_extent() + + +def test_legend_title_fontprop_fontsize(): + # test the title_fontsize kwarg + plt.plot(range(10)) + with pytest.raises(ValueError): + plt.legend(title='Aardvark', title_fontsize=22, + title_fontproperties={'family': 'serif', 'size': 22}) + + leg = plt.legend(title='Aardvark', title_fontproperties=FontProperties( + family='serif', size=22)) + assert leg.get_title().get_size() == 22 + + fig, axes = plt.subplots(2, 3, figsize=(10, 6)) + axes = axes.flat + axes[0].plot(range(10)) + leg0 = axes[0].legend(title='Aardvark', title_fontsize=22) + assert leg0.get_title().get_fontsize() == 22 + axes[1].plot(range(10)) + leg1 = axes[1].legend(title='Aardvark', + title_fontproperties={'family': 'serif', 'size': 22}) + assert leg1.get_title().get_fontsize() == 22 + axes[2].plot(range(10)) + mpl.rcParams['legend.title_fontsize'] = None + leg2 = axes[2].legend(title='Aardvark', + title_fontproperties={'family': 'serif'}) + assert leg2.get_title().get_fontsize() == mpl.rcParams['font.size'] + axes[3].plot(range(10)) + leg3 = axes[3].legend(title='Aardvark') + assert leg3.get_title().get_fontsize() == mpl.rcParams['font.size'] + axes[4].plot(range(10)) + mpl.rcParams['legend.title_fontsize'] = 20 + leg4 = axes[4].legend(title='Aardvark', + title_fontproperties={'family': 'serif'}) + assert leg4.get_title().get_fontsize() == 20 + axes[5].plot(range(10)) + leg5 = axes[5].legend(title='Aardvark') + assert leg5.get_title().get_fontsize() == 20 + + +@pytest.mark.parametrize('alignment', ('center', 'left', 'right')) +def test_legend_alignment(alignment): + fig, ax = plt.subplots() + ax.plot(range(10), label='test') + leg = ax.legend(title="Aardvark", alignment=alignment) + assert leg.get_children()[0].align == alignment + assert leg.get_alignment() == alignment + + +@pytest.mark.parametrize('loc', ('center', 'best',)) +def test_ax_legend_set_loc(loc): + fig, ax = plt.subplots() + ax.plot(range(10), label='test') + leg = ax.legend() + leg.set_loc(loc) + assert leg._get_loc() == mlegend.Legend.codes[loc] + + +@pytest.mark.parametrize('loc', ('outside right', 'right',)) +def test_fig_legend_set_loc(loc): + fig, ax = plt.subplots() + ax.plot(range(10), label='test') + leg = fig.legend() + leg.set_loc(loc) + + loc = loc.split()[1] if loc.startswith("outside") else loc + assert leg._get_loc() == mlegend.Legend.codes[loc] + + +@pytest.mark.parametrize('alignment', ('center', 'left', 'right')) +def test_legend_set_alignment(alignment): + fig, ax = plt.subplots() + ax.plot(range(10), label='test') + leg = ax.legend() + leg.set_alignment(alignment) + assert leg.get_children()[0].align == alignment + assert leg.get_alignment() == alignment + + +@pytest.mark.parametrize('color', ('red', 'none', (.5, .5, .5))) +def test_legend_labelcolor_single(color): + # test labelcolor for a single color + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1') + ax.plot(np.arange(10), np.arange(10)*2, label='#2') + ax.plot(np.arange(10), np.arange(10)*3, label='#3') + + leg = ax.legend(labelcolor=color) + for text in leg.get_texts(): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_list(): + # test labelcolor for a list of colors + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1') + ax.plot(np.arange(10), np.arange(10)*2, label='#2') + ax.plot(np.arange(10), np.arange(10)*3, label='#3') + + leg = ax.legend(labelcolor=['r', 'g', 'b']) + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_linecolor(): + # test the labelcolor for labelcolor='linecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', color='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', color='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', color='b') + + leg = ax.legend(labelcolor='linecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_linecolor(): + # test the labelcolor for labelcolor='linecolor' on PathCollection + fig, ax = plt.subplots() + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', c='r') + ax.scatter(np.arange(10), np.arange(10)*2, label='#2', c='g') + ax.scatter(np.arange(10), np.arange(10)*3, label='#3', c='b') + + leg = ax.legend(labelcolor='linecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_linecolor_iterable(): + # test the labelcolor for labelcolor='linecolor' on PathCollection + # with iterable colors + fig, ax = plt.subplots() + colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', c=colors) + + leg = ax.legend(labelcolor='linecolor') + text, = leg.get_texts() + assert mpl.colors.same_color(text.get_color(), 'black') + + +def test_legend_pathcollection_labelcolor_linecolor_cmap(): + # test the labelcolor for labelcolor='linecolor' on PathCollection + # with a colormap + fig, ax = plt.subplots() + ax.scatter(np.arange(10), np.arange(10), c=np.arange(10), label='#1') + + leg = ax.legend(labelcolor='linecolor') + text, = leg.get_texts() + assert mpl.colors.same_color(text.get_color(), 'black') + + +def test_legend_labelcolor_markeredgecolor(): + # test the labelcolor for labelcolor='markeredgecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markeredgecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markeredgecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markeredgecolor='b') + + leg = ax.legend(labelcolor='markeredgecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markeredgecolor(): + # test the labelcolor for labelcolor='markeredgecolor' on PathCollection + fig, ax = plt.subplots() + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', edgecolor='r') + ax.scatter(np.arange(10), np.arange(10)*2, label='#2', edgecolor='g') + ax.scatter(np.arange(10), np.arange(10)*3, label='#3', edgecolor='b') + + leg = ax.legend(labelcolor='markeredgecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markeredgecolor_iterable(): + # test the labelcolor for labelcolor='markeredgecolor' on PathCollection + # with iterable colors + fig, ax = plt.subplots() + colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', edgecolor=colors) + + leg = ax.legend(labelcolor='markeredgecolor') + for text, color in zip(leg.get_texts(), ['k']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markeredgecolor_cmap(): + # test the labelcolor for labelcolor='markeredgecolor' on PathCollection + # with a colormap + fig, ax = plt.subplots() + edgecolors = mpl.cm.viridis(np.random.rand(10)) + ax.scatter( + np.arange(10), + np.arange(10), + label='#1', + c=np.arange(10), + edgecolor=edgecolors, + cmap="Reds" + ) + + leg = ax.legend(labelcolor='markeredgecolor') + for text, color in zip(leg.get_texts(), ['k']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_markerfacecolor(): + # test the labelcolor for labelcolor='markerfacecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markerfacecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markerfacecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markerfacecolor='b') + + leg = ax.legend(labelcolor='markerfacecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markerfacecolor(): + # test the labelcolor for labelcolor='markerfacecolor' on PathCollection + fig, ax = plt.subplots() + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', facecolor='r') + ax.scatter(np.arange(10), np.arange(10)*2, label='#2', facecolor='g') + ax.scatter(np.arange(10), np.arange(10)*3, label='#3', facecolor='b') + + leg = ax.legend(labelcolor='markerfacecolor') + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markerfacecolor_iterable(): + # test the labelcolor for labelcolor='markerfacecolor' on PathCollection + # with iterable colors + fig, ax = plt.subplots() + colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) + ax.scatter(np.arange(10), np.arange(10)*1, label='#1', facecolor=colors) + + leg = ax.legend(labelcolor='markerfacecolor') + for text, color in zip(leg.get_texts(), ['k']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_pathcollection_labelcolor_markfacecolor_cmap(): + # test the labelcolor for labelcolor='markerfacecolor' on PathCollection + # with colormaps + fig, ax = plt.subplots() + facecolors = mpl.cm.viridis(np.random.rand(10)) + ax.scatter( + np.arange(10), + np.arange(10), + label='#1', + c=np.arange(10), + facecolor=facecolors + ) + + leg = ax.legend(labelcolor='markerfacecolor') + for text, color in zip(leg.get_texts(), ['k']): + assert mpl.colors.same_color(text.get_color(), color) + + +@pytest.mark.parametrize('color', ('red', 'none', (.5, .5, .5))) +def test_legend_labelcolor_rcparam_single(color): + # test the rcParams legend.labelcolor for a single color + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1') + ax.plot(np.arange(10), np.arange(10)*2, label='#2') + ax.plot(np.arange(10), np.arange(10)*3, label='#3') + + mpl.rcParams['legend.labelcolor'] = color + leg = ax.legend() + for text in leg.get_texts(): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_rcparam_linecolor(): + # test the rcParams legend.labelcolor for a linecolor + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', color='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', color='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', color='b') + + mpl.rcParams['legend.labelcolor'] = 'linecolor' + leg = ax.legend() + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_rcparam_markeredgecolor(): + # test the labelcolor for labelcolor='markeredgecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markeredgecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markeredgecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markeredgecolor='b') + + mpl.rcParams['legend.labelcolor'] = 'markeredgecolor' + leg = ax.legend() + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_rcparam_markeredgecolor_short(): + # test the labelcolor for labelcolor='markeredgecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markeredgecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markeredgecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markeredgecolor='b') + + mpl.rcParams['legend.labelcolor'] = 'mec' + leg = ax.legend() + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_rcparam_markerfacecolor(): + # test the labelcolor for labelcolor='markeredgecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markerfacecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markerfacecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markerfacecolor='b') + + mpl.rcParams['legend.labelcolor'] = 'markerfacecolor' + leg = ax.legend() + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_legend_labelcolor_rcparam_markerfacecolor_short(): + # test the labelcolor for labelcolor='markeredgecolor' + fig, ax = plt.subplots() + ax.plot(np.arange(10), np.arange(10)*1, label='#1', markerfacecolor='r') + ax.plot(np.arange(10), np.arange(10)*2, label='#2', markerfacecolor='g') + ax.plot(np.arange(10), np.arange(10)*3, label='#3', markerfacecolor='b') + + mpl.rcParams['legend.labelcolor'] = 'mfc' + leg = ax.legend() + for text, color in zip(leg.get_texts(), ['r', 'g', 'b']): + assert mpl.colors.same_color(text.get_color(), color) + + +def test_get_set_draggable(): + legend = plt.legend() + assert not legend.get_draggable() + legend.set_draggable(True) + assert legend.get_draggable() + legend.set_draggable(False) + assert not legend.get_draggable() + + +@pytest.mark.parametrize('draggable', (True, False)) +def test_legend_draggable(draggable): + fig, ax = plt.subplots() + ax.plot(range(10), label='shabnams') + leg = ax.legend(draggable=draggable) + assert leg.get_draggable() is draggable + + +def test_alpha_handles(): + x, n, hh = plt.hist([1, 2, 3], alpha=0.25, label='data', color='red') + legend = plt.legend() + for lh in legend.legend_handles: + lh.set_alpha(1.0) + assert lh.get_facecolor()[:-1] == hh[1].get_facecolor()[:-1] + assert lh.get_edgecolor()[:-1] == hh[1].get_edgecolor()[:-1] + + +@needs_usetex +def test_usetex_no_warn(caplog): + mpl.rcParams['font.family'] = 'serif' + mpl.rcParams['font.serif'] = 'Computer Modern' + mpl.rcParams['text.usetex'] = True + + fig, ax = plt.subplots() + ax.plot(0, 0, label='input') + ax.legend(title="My legend") + + fig.canvas.draw() + assert "Font family ['serif'] not found." not in caplog.text + + +def test_warn_big_data_best_loc(): + fig, ax = plt.subplots() + fig.canvas.draw() # So that we can call draw_artist later. + for idx in range(1000): + ax.plot(np.arange(5000), label=idx) + with rc_context({'legend.loc': 'best'}): + legend = ax.legend() + with pytest.warns(UserWarning) as records: + fig.draw_artist(legend) # Don't bother drawing the lines -- it's slow. + # The _find_best_position method of Legend is called twice, duplicating + # the warning message. + assert len(records) == 2 + for record in records: + assert str(record.message) == ( + 'Creating legend with loc="best" can be slow with large ' + 'amounts of data.') + + +def test_no_warn_big_data_when_loc_specified(): + fig, ax = plt.subplots() + fig.canvas.draw() + for idx in range(1000): + ax.plot(np.arange(5000), label=idx) + legend = ax.legend('best') + fig.draw_artist(legend) # Check that no warning is emitted. + + +@pytest.mark.parametrize('label_array', [['low', 'high'], + ('low', 'high'), + np.array(['low', 'high'])]) +def test_plot_multiple_input_multiple_label(label_array): + # test ax.plot() with multidimensional input + # and multiple labels + x = [1, 2, 3] + y = [[1, 2], + [2, 5], + [4, 9]] + + fig, ax = plt.subplots() + ax.plot(x, y, label=label_array) + leg = ax.legend() + legend_texts = [entry.get_text() for entry in leg.get_texts()] + assert legend_texts == ['low', 'high'] + + +@pytest.mark.parametrize('label', ['one', 1, int]) +def test_plot_multiple_input_single_label(label): + # test ax.plot() with multidimensional input + # and single label + x = [1, 2, 3] + y = [[1, 2], + [2, 5], + [4, 9]] + + fig, ax = plt.subplots() + ax.plot(x, y, label=label) + leg = ax.legend() + legend_texts = [entry.get_text() for entry in leg.get_texts()] + assert legend_texts == [str(label)] * 2 + + +@pytest.mark.parametrize('label_array', [['low', 'high'], + ('low', 'high'), + np.array(['low', 'high'])]) +def test_plot_single_input_multiple_label(label_array): + # test ax.plot() with 1D array like input + # and iterable label + x = [1, 2, 3] + y = [2, 5, 6] + fig, ax = plt.subplots() + ax.plot(x, y, label=label_array) + leg = ax.legend() + assert len(leg.get_texts()) == 1 + assert leg.get_texts()[0].get_text() == str(label_array) + + +def test_plot_multiple_label_incorrect_length_exception(): + # check that exception is raised if multiple labels + # are given, but number of on labels != number of lines + with pytest.raises(ValueError): + x = [1, 2, 3] + y = [[1, 2], + [2, 5], + [4, 9]] + label = ['high', 'low', 'medium'] + fig, ax = plt.subplots() + ax.plot(x, y, label=label) + + +def test_legend_face_edgecolor(): + # Smoke test for PolyCollection legend handler with 'face' edgecolor. + fig, ax = plt.subplots() + ax.fill_between([0, 1, 2], [1, 2, 3], [2, 3, 4], + facecolor='r', edgecolor='face', label='Fill') + ax.legend() + + +def test_legend_text_axes(): + fig, ax = plt.subplots() + ax.plot([1, 2], [3, 4], label='line') + leg = ax.legend() + + assert leg.axes is ax + assert leg.get_texts()[0].axes is ax + + +def test_handlerline2d(): + # Test marker consistency for monolithic Line2D legend handler (#11357). + fig, ax = plt.subplots() + ax.scatter([0, 1], [0, 1], marker="v") + handles = [mlines.Line2D([0], [0], marker="v")] + leg = ax.legend(handles, ["Aardvark"], numpoints=1) + assert handles[0].get_marker() == leg.legend_handles[0].get_marker() + + +def test_subfigure_legend(): + # Test that legend can be added to subfigure (#20723) + subfig = plt.figure().subfigures() + ax = subfig.subplots() + ax.plot([0, 1], [0, 1], label="line") + leg = subfig.legend() + assert leg.figure is subfig + + +def test_setting_alpha_keeps_polycollection_color(): + pc = plt.fill_between([0, 1], [2, 3], color='#123456', label='label') + patch = plt.legend().get_patches()[0] + patch.set_alpha(0.5) + assert patch.get_facecolor()[:3] == tuple(pc.get_facecolor()[0][:3]) + assert patch.get_edgecolor()[:3] == tuple(pc.get_edgecolor()[0][:3]) + + +def test_legend_markers_from_line2d(): + # Test that markers can be copied for legend lines (#17960) + _markers = ['.', '*', 'v'] + fig, ax = plt.subplots() + lines = [mlines.Line2D([0], [0], ls='None', marker=mark) + for mark in _markers] + labels = ["foo", "bar", "xyzzy"] + markers = [line.get_marker() for line in lines] + legend = ax.legend(lines, labels) + + new_markers = [line.get_marker() for line in legend.get_lines()] + new_labels = [text.get_text() for text in legend.get_texts()] + + assert markers == new_markers == _markers + assert labels == new_labels + + +@check_figures_equal() +def test_ncol_ncols(fig_test, fig_ref): + # Test that both ncol and ncols work + strings = ["a", "b", "c", "d", "e", "f"] + ncols = 3 + fig_test.legend(strings, ncol=ncols) + fig_ref.legend(strings, ncols=ncols) + + +def test_loc_invalid_tuple_exception(): + # check that exception is raised if the loc arg + # of legend is not a 2-tuple of numbers + fig, ax = plt.subplots() + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not \\(1.1,\\)')): + ax.legend(loc=(1.1, )) + + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not \\(0.481, 0.4227, 0.4523\\)')): + ax.legend(loc=(0.481, 0.4227, 0.4523)) + + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not \\(0.481, \'go blue\'\\)')): + ax.legend(loc=(0.481, "go blue")) + + +def test_loc_valid_tuple(): + fig, ax = plt.subplots() + ax.legend(loc=(0.481, 0.442)) + ax.legend(loc=(1, 2)) + + +def test_loc_valid_list(): + fig, ax = plt.subplots() + ax.legend(loc=[0.481, 0.442]) + ax.legend(loc=[1, 2]) + + +def test_loc_invalid_list_exception(): + fig, ax = plt.subplots() + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not \\[1.1, 2.2, 3.3\\]')): + ax.legend(loc=[1.1, 2.2, 3.3]) + + +def test_loc_invalid_type(): + fig, ax = plt.subplots() + with pytest.raises(ValueError, match=("loc must be string, coordinate " + "tuple, or an integer 0-10, not {'not': True}")): + ax.legend(loc={'not': True}) + + +def test_loc_validation_numeric_value(): + fig, ax = plt.subplots() + ax.legend(loc=0) + ax.legend(loc=1) + ax.legend(loc=5) + ax.legend(loc=10) + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not 11')): + ax.legend(loc=11) + + with pytest.raises(ValueError, match=('loc must be string, coordinate ' + 'tuple, or an integer 0-10, not -1')): + ax.legend(loc=-1) + + +def test_loc_validation_string_value(): + fig, ax = plt.subplots() + ax.legend(loc='best') + ax.legend(loc='upper right') + ax.legend(loc='best') + ax.legend(loc='upper right') + ax.legend(loc='upper left') + ax.legend(loc='lower left') + ax.legend(loc='lower right') + ax.legend(loc='right') + ax.legend(loc='center left') + ax.legend(loc='center right') + ax.legend(loc='lower center') + ax.legend(loc='upper center') + with pytest.raises(ValueError, match="'wrong' is not a valid value for"): + ax.legend(loc='wrong') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_lines.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_lines.py new file mode 100644 index 00000000..4f23e696 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_lines.py @@ -0,0 +1,438 @@ +""" +Tests specific to the lines module. +""" + +import itertools +import platform +import timeit +from types import SimpleNamespace + +from cycler import cycler +import numpy as np +from numpy.testing import assert_array_equal +import pytest + +import matplotlib +import matplotlib as mpl +from matplotlib import _path +import matplotlib.lines as mlines +from matplotlib.markers import MarkerStyle +from matplotlib.path import Path +import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms +from matplotlib.testing.decorators import image_comparison, check_figures_equal + + +def test_segment_hits(): + """Test a problematic case.""" + cx, cy = 553, 902 + x, y = np.array([553., 553.]), np.array([95., 947.]) + radius = 6.94 + assert_array_equal(mlines.segment_hits(cx, cy, x, y, radius), [0]) + + +# Runtimes on a loaded system are inherently flaky. Not so much that a rerun +# won't help, hopefully. +@pytest.mark.flaky(reruns=3) +def test_invisible_Line_rendering(): + """ + GitHub issue #1256 identified a bug in Line.draw method + + Despite visibility attribute set to False, the draw method was not + returning early enough and some pre-rendering code was executed + though not necessary. + + Consequence was an excessive draw time for invisible Line instances + holding a large number of points (Npts> 10**6) + """ + # Creates big x and y data: + N = 10**7 + x = np.linspace(0, 1, N) + y = np.random.normal(size=N) + + # Create a plot figure: + fig = plt.figure() + ax = plt.subplot() + + # Create a "big" Line instance: + l = mlines.Line2D(x, y) + l.set_visible(False) + # but don't add it to the Axis instance `ax` + + # [here Interactive panning and zooming is pretty responsive] + # Time the canvas drawing: + t_no_line = min(timeit.repeat(fig.canvas.draw, number=1, repeat=3)) + # (gives about 25 ms) + + # Add the big invisible Line: + ax.add_line(l) + + # [Now interactive panning and zooming is very slow] + # Time the canvas drawing: + t_invisible_line = min(timeit.repeat(fig.canvas.draw, number=1, repeat=3)) + # gives about 290 ms for N = 10**7 pts + + slowdown_factor = t_invisible_line / t_no_line + slowdown_threshold = 2 # trying to avoid false positive failures + assert slowdown_factor < slowdown_threshold + + +def test_set_line_coll_dash(): + fig, ax = plt.subplots() + np.random.seed(0) + # Testing setting linestyles for line collections. + # This should not produce an error. + ax.contour(np.random.randn(20, 30), linestyles=[(0, (3, 3))]) + + +def test_invalid_line_data(): + with pytest.raises(RuntimeError, match='xdata must be'): + mlines.Line2D(0, []) + with pytest.raises(RuntimeError, match='ydata must be'): + mlines.Line2D([], 1) + + line = mlines.Line2D([], []) + # when deprecation cycle is completed + # with pytest.raises(RuntimeError, match='x must be'): + with pytest.warns(mpl.MatplotlibDeprecationWarning): + line.set_xdata(0) + # with pytest.raises(RuntimeError, match='y must be'): + with pytest.warns(mpl.MatplotlibDeprecationWarning): + line.set_ydata(0) + + +@image_comparison(['line_dashes'], remove_text=True, tol=0.002) +def test_line_dashes(): + # Tolerance introduced after reordering of floating-point operations + # Remove when regenerating the images + fig, ax = plt.subplots() + + ax.plot(range(10), linestyle=(0, (3, 3)), lw=5) + + +def test_line_colors(): + fig, ax = plt.subplots() + ax.plot(range(10), color='none') + ax.plot(range(10), color='r') + ax.plot(range(10), color='.3') + ax.plot(range(10), color=(1, 0, 0, 1)) + ax.plot(range(10), color=(1, 0, 0)) + fig.canvas.draw() + + +def test_valid_colors(): + line = mlines.Line2D([], []) + with pytest.raises(ValueError): + line.set_color("foobar") + + +def test_linestyle_variants(): + fig, ax = plt.subplots() + for ls in ["-", "solid", "--", "dashed", + "-.", "dashdot", ":", "dotted", + (0, None), (0, ()), (0, []), # gh-22930 + ]: + ax.plot(range(10), linestyle=ls) + fig.canvas.draw() + + +def test_valid_linestyles(): + line = mlines.Line2D([], []) + with pytest.raises(ValueError): + line.set_linestyle('aardvark') + + +@image_comparison(['drawstyle_variants.png'], remove_text=True) +def test_drawstyle_variants(): + fig, axs = plt.subplots(6) + dss = ["default", "steps-mid", "steps-pre", "steps-post", "steps", None] + # We want to check that drawstyles are properly handled even for very long + # lines (for which the subslice optimization is on); however, we need + # to zoom in so that the difference between the drawstyles is actually + # visible. + for ax, ds in zip(axs.flat, dss): + ax.plot(range(2000), drawstyle=ds) + ax.set(xlim=(0, 2), ylim=(0, 2)) + + +@check_figures_equal(extensions=('png',)) +def test_no_subslice_with_transform(fig_ref, fig_test): + ax = fig_ref.add_subplot() + x = np.arange(2000) + ax.plot(x + 2000, x) + + ax = fig_test.add_subplot() + t = mtransforms.Affine2D().translate(2000.0, 0.0) + ax.plot(x, x, transform=t+ax.transData) + + +def test_valid_drawstyles(): + line = mlines.Line2D([], []) + with pytest.raises(ValueError): + line.set_drawstyle('foobar') + + +def test_set_drawstyle(): + x = np.linspace(0, 2*np.pi, 10) + y = np.sin(x) + + fig, ax = plt.subplots() + line, = ax.plot(x, y) + line.set_drawstyle("steps-pre") + assert len(line.get_path().vertices) == 2*len(x)-1 + + line.set_drawstyle("default") + assert len(line.get_path().vertices) == len(x) + + +@image_comparison( + ['line_collection_dashes'], remove_text=True, style='mpl20', + tol=0.65 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_set_line_coll_dash_image(): + fig, ax = plt.subplots() + np.random.seed(0) + ax.contour(np.random.randn(20, 30), linestyles=[(0, (3, 3))]) + + +@image_comparison(['marker_fill_styles.png'], remove_text=True) +def test_marker_fill_styles(): + colors = itertools.cycle([[0, 0, 1], 'g', '#ff0000', 'c', 'm', 'y', + np.array([0, 0, 0])]) + altcolor = 'lightgreen' + + y = np.array([1, 1]) + x = np.array([0, 9]) + fig, ax = plt.subplots() + + # This hard-coded list of markers correspond to an earlier iteration of + # MarkerStyle.filled_markers; the value of that attribute has changed but + # we kept the old value here to not regenerate the baseline image. + # Replace with mlines.Line2D.filled_markers when the image is regenerated. + for j, marker in enumerate("ov^<>8sp*hHDdPX"): + for i, fs in enumerate(mlines.Line2D.fillStyles): + color = next(colors) + ax.plot(j * 10 + x, y + i + .5 * (j % 2), + marker=marker, + markersize=20, + markerfacecoloralt=altcolor, + fillstyle=fs, + label=fs, + linewidth=5, + color=color, + markeredgecolor=color, + markeredgewidth=2) + + ax.set_ylim([0, 7.5]) + ax.set_xlim([-5, 155]) + + +def test_markerfacecolor_fillstyle(): + """Test that markerfacecolor does not override fillstyle='none'.""" + l, = plt.plot([1, 3, 2], marker=MarkerStyle('o', fillstyle='none'), + markerfacecolor='red') + assert l.get_fillstyle() == 'none' + assert l.get_markerfacecolor() == 'none' + + +@image_comparison(['scaled_lines'], style='default') +def test_lw_scaling(): + th = np.linspace(0, 32) + fig, ax = plt.subplots() + lins_styles = ['dashed', 'dotted', 'dashdot'] + cy = cycler(matplotlib.rcParams['axes.prop_cycle']) + for j, (ls, sty) in enumerate(zip(lins_styles, cy)): + for lw in np.linspace(.5, 10, 10): + ax.plot(th, j*np.ones(50) + .1 * lw, linestyle=ls, lw=lw, **sty) + + +def test_is_sorted_and_has_non_nan(): + assert _path.is_sorted_and_has_non_nan(np.array([1, 2, 3])) + assert _path.is_sorted_and_has_non_nan(np.array([1, np.nan, 3])) + assert not _path.is_sorted_and_has_non_nan([3, 5] + [np.nan] * 100 + [0, 2]) + n = 2 * mlines.Line2D._subslice_optim_min_size + plt.plot([np.nan] * n, range(n)) + + +@check_figures_equal() +def test_step_markers(fig_test, fig_ref): + fig_test.subplots().step([0, 1], "-o") + fig_ref.subplots().plot([0, 0, 1], [0, 1, 1], "-o", markevery=[0, 2]) + + +@pytest.mark.parametrize("parent", ["figure", "axes"]) +@check_figures_equal(extensions=('png',)) +def test_markevery(fig_test, fig_ref, parent): + np.random.seed(42) + x = np.linspace(0, 1, 14) + y = np.random.rand(len(x)) + + cases_test = [None, 4, (2, 5), [1, 5, 11], + [0, -1], slice(5, 10, 2), + np.arange(len(x))[y > 0.5], + 0.3, (0.3, 0.4)] + cases_ref = ["11111111111111", "10001000100010", "00100001000010", + "01000100000100", "10000000000001", "00000101010000", + "01110001110110", "11011011011110", "01010011011101"] + + if parent == "figure": + # float markevery ("relative to axes size") is not supported. + cases_test = cases_test[:-2] + cases_ref = cases_ref[:-2] + + def add_test(x, y, *, markevery): + fig_test.add_artist( + mlines.Line2D(x, y, marker="o", markevery=markevery)) + + def add_ref(x, y, *, markevery): + fig_ref.add_artist( + mlines.Line2D(x, y, marker="o", markevery=markevery)) + + elif parent == "axes": + axs_test = iter(fig_test.subplots(3, 3).flat) + axs_ref = iter(fig_ref.subplots(3, 3).flat) + + def add_test(x, y, *, markevery): + next(axs_test).plot(x, y, "-gD", markevery=markevery) + + def add_ref(x, y, *, markevery): + next(axs_ref).plot(x, y, "-gD", markevery=markevery) + + for case in cases_test: + add_test(x, y, markevery=case) + + for case in cases_ref: + me = np.array(list(case)).astype(int).astype(bool) + add_ref(x, y, markevery=me) + + +def test_markevery_figure_line_unsupported_relsize(): + fig = plt.figure() + fig.add_artist(mlines.Line2D([0, 1], [0, 1], marker="o", markevery=.5)) + with pytest.raises(ValueError): + fig.canvas.draw() + + +def test_marker_as_markerstyle(): + fig, ax = plt.subplots() + line, = ax.plot([2, 4, 3], marker=MarkerStyle("D")) + fig.canvas.draw() + assert line.get_marker() == "D" + + # continue with smoke tests: + line.set_marker("s") + fig.canvas.draw() + line.set_marker(MarkerStyle("o")) + fig.canvas.draw() + # test Path roundtrip + triangle1 = Path._create_closed([[-1, -1], [1, -1], [0, 2]]) + line2, = ax.plot([1, 3, 2], marker=MarkerStyle(triangle1), ms=22) + line3, = ax.plot([0, 2, 1], marker=triangle1, ms=22) + + assert_array_equal(line2.get_marker().vertices, triangle1.vertices) + assert_array_equal(line3.get_marker().vertices, triangle1.vertices) + + +@image_comparison(['striped_line.png'], remove_text=True, style='mpl20') +def test_striped_lines(): + rng = np.random.default_rng(19680801) + _, ax = plt.subplots() + ax.plot(rng.uniform(size=12), color='orange', gapcolor='blue', + linestyle='--', lw=5, label=' ') + ax.plot(rng.uniform(size=12), color='red', gapcolor='black', + linestyle=(0, (2, 5, 4, 2)), lw=5, label=' ', alpha=0.5) + ax.legend(handlelength=5) + + +@check_figures_equal() +def test_odd_dashes(fig_test, fig_ref): + fig_test.add_subplot().plot([1, 2], dashes=[1, 2, 3]) + fig_ref.add_subplot().plot([1, 2], dashes=[1, 2, 3, 1, 2, 3]) + + +def test_picking(): + fig, ax = plt.subplots() + mouse_event = SimpleNamespace(x=fig.bbox.width // 2, + y=fig.bbox.height // 2 + 15) + + # Default pickradius is 5, so event should not pick this line. + l0, = ax.plot([0, 1], [0, 1], picker=True) + found, indices = l0.contains(mouse_event) + assert not found + + # But with a larger pickradius, this should be picked. + l1, = ax.plot([0, 1], [0, 1], picker=True, pickradius=20) + found, indices = l1.contains(mouse_event) + assert found + assert_array_equal(indices['ind'], [0]) + + # And if we modify the pickradius after creation, it should work as well. + l2, = ax.plot([0, 1], [0, 1], picker=True) + found, indices = l2.contains(mouse_event) + assert not found + l2.set_pickradius(20) + found, indices = l2.contains(mouse_event) + assert found + assert_array_equal(indices['ind'], [0]) + + +@check_figures_equal() +def test_input_copy(fig_test, fig_ref): + + t = np.arange(0, 6, 2) + l, = fig_test.add_subplot().plot(t, t, ".-") + t[:] = range(3) + # Trigger cache invalidation + l.set_drawstyle("steps") + fig_ref.add_subplot().plot([0, 2, 4], [0, 2, 4], ".-", drawstyle="steps") + + +@check_figures_equal(extensions=["png"]) +def test_markevery_prop_cycle(fig_test, fig_ref): + """Test that we can set markevery prop_cycle.""" + cases = [None, 8, (30, 8), [16, 24, 30], [0, -1], + slice(100, 200, 3), 0.1, 0.3, 1.5, + (0.0, 0.1), (0.45, 0.1)] + + cmap = mpl.colormaps['jet'] + colors = cmap(np.linspace(0.2, 0.8, len(cases))) + + x = np.linspace(-1, 1) + y = 5 * x**2 + + axs = fig_ref.add_subplot() + for i, markevery in enumerate(cases): + axs.plot(y - i, 'o-', markevery=markevery, color=colors[i]) + + matplotlib.rcParams['axes.prop_cycle'] = cycler(markevery=cases, + color=colors) + + ax = fig_test.add_subplot() + for i, _ in enumerate(cases): + ax.plot(y - i, 'o-') + + +def test_axline_setters(): + fig, ax = plt.subplots() + line1 = ax.axline((.1, .1), slope=0.6) + line2 = ax.axline((.1, .1), (.8, .4)) + # Testing xy1, xy2 and slope setters. + # This should not produce an error. + line1.set_xy1(.2, .3) + line1.set_slope(2.4) + line2.set_xy1(.3, .2) + line2.set_xy2(.6, .8) + # Testing xy1, xy2 and slope getters. + # Should return the modified values. + assert line1.get_xy1() == (.2, .3) + assert line1.get_slope() == 2.4 + assert line2.get_xy1() == (.3, .2) + assert line2.get_xy2() == (.6, .8) + # Testing setting xy2 and slope together. + # These test should raise a ValueError + with pytest.raises(ValueError, + match="Cannot set an 'xy2' value while 'slope' is set"): + line1.set_xy2(.2, .3) + + with pytest.raises(ValueError, + match="Cannot set a 'slope' value while 'xy2' is set"): + line2.set_slope(3) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_marker.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_marker.py new file mode 100644 index 00000000..463ff1d0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_marker.py @@ -0,0 +1,303 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import markers +from matplotlib.path import Path +from matplotlib.testing.decorators import check_figures_equal +from matplotlib.transforms import Affine2D + +import pytest + + +def test_marker_fillstyle(): + marker_style = markers.MarkerStyle(marker='o', fillstyle='none') + assert marker_style.get_fillstyle() == 'none' + assert not marker_style.is_filled() + + +@pytest.mark.parametrize('marker', [ + 'o', + 'x', + '', + 'None', + r'$\frac{1}{2}$', + "$\u266B$", + 1, + markers.TICKLEFT, + [[-1, 0], [1, 0]], + np.array([[-1, 0], [1, 0]]), + Path([[0, 0], [1, 0]], [Path.MOVETO, Path.LINETO]), + (5, 0), # a pentagon + (7, 1), # a 7-pointed star + (5, 2), # asterisk + (5, 0, 10), # a pentagon, rotated by 10 degrees + (7, 1, 10), # a 7-pointed star, rotated by 10 degrees + (5, 2, 10), # asterisk, rotated by 10 degrees + markers.MarkerStyle('o'), +]) +def test_markers_valid(marker): + # Checking this doesn't fail. + markers.MarkerStyle(marker) + + +@pytest.mark.parametrize('marker', [ + 'square', # arbitrary string + np.array([[-0.5, 0, 1, 2, 3]]), # 1D array + (1,), + (5, 3), # second parameter of tuple must be 0, 1, or 2 + (1, 2, 3, 4), +]) +def test_markers_invalid(marker): + with pytest.raises(ValueError): + markers.MarkerStyle(marker) + + +class UnsnappedMarkerStyle(markers.MarkerStyle): + """ + A MarkerStyle where the snap threshold is force-disabled. + + This is used to compare to polygon/star/asterisk markers which do not have + any snap threshold set. + """ + def _recache(self): + super()._recache() + self._snap_threshold = None + + +@check_figures_equal() +def test_poly_marker(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + # Note, some reference sizes must be different because they have unit + # *length*, while polygon markers are inscribed in a circle of unit + # *radius*. This introduces a factor of np.sqrt(2), but since size is + # squared, that becomes 2. + size = 20**2 + + # Squares + ax_test.scatter([0], [0], marker=(4, 0, 45), s=size) + ax_ref.scatter([0], [0], marker='s', s=size/2) + + # Diamonds, with and without rotation argument + ax_test.scatter([1], [1], marker=(4, 0), s=size) + ax_ref.scatter([1], [1], marker=UnsnappedMarkerStyle('D'), s=size/2) + ax_test.scatter([1], [1.5], marker=(4, 0, 0), s=size) + ax_ref.scatter([1], [1.5], marker=UnsnappedMarkerStyle('D'), s=size/2) + + # Pentagon, with and without rotation argument + ax_test.scatter([2], [2], marker=(5, 0), s=size) + ax_ref.scatter([2], [2], marker=UnsnappedMarkerStyle('p'), s=size) + ax_test.scatter([2], [2.5], marker=(5, 0, 0), s=size) + ax_ref.scatter([2], [2.5], marker=UnsnappedMarkerStyle('p'), s=size) + + # Hexagon, with and without rotation argument + ax_test.scatter([3], [3], marker=(6, 0), s=size) + ax_ref.scatter([3], [3], marker='h', s=size) + ax_test.scatter([3], [3.5], marker=(6, 0, 0), s=size) + ax_ref.scatter([3], [3.5], marker='h', s=size) + + # Rotated hexagon + ax_test.scatter([4], [4], marker=(6, 0, 30), s=size) + ax_ref.scatter([4], [4], marker='H', s=size) + + # Octagons + ax_test.scatter([5], [5], marker=(8, 0, 22.5), s=size) + ax_ref.scatter([5], [5], marker=UnsnappedMarkerStyle('8'), s=size) + + ax_test.set(xlim=(-0.5, 5.5), ylim=(-0.5, 5.5)) + ax_ref.set(xlim=(-0.5, 5.5), ylim=(-0.5, 5.5)) + + +def test_star_marker(): + # We don't really have a strict equivalent to this marker, so we'll just do + # a smoke test. + size = 20**2 + + fig, ax = plt.subplots() + ax.scatter([0], [0], marker=(5, 1), s=size) + ax.scatter([1], [1], marker=(5, 1, 0), s=size) + ax.set(xlim=(-0.5, 0.5), ylim=(-0.5, 1.5)) + + +# The asterisk marker is really a star with 0-size inner circle, so the ends +# are corners and get a slight bevel. The reference markers are just singular +# lines without corners, so they have no bevel, and we need to add a slight +# tolerance. +@check_figures_equal(tol=1.45) +def test_asterisk_marker(fig_test, fig_ref, request): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + # Note, some reference sizes must be different because they have unit + # *length*, while asterisk markers are inscribed in a circle of unit + # *radius*. This introduces a factor of np.sqrt(2), but since size is + # squared, that becomes 2. + size = 20**2 + + def draw_ref_marker(y, style, size): + # As noted above, every line is doubled. Due to antialiasing, these + # doubled lines make a slight difference in the .png results. + ax_ref.scatter([y], [y], marker=UnsnappedMarkerStyle(style), s=size) + if request.getfixturevalue('ext') == 'png': + ax_ref.scatter([y], [y], marker=UnsnappedMarkerStyle(style), + s=size) + + # Plus + ax_test.scatter([0], [0], marker=(4, 2), s=size) + draw_ref_marker(0, '+', size) + ax_test.scatter([0.5], [0.5], marker=(4, 2, 0), s=size) + draw_ref_marker(0.5, '+', size) + + # Cross + ax_test.scatter([1], [1], marker=(4, 2, 45), s=size) + draw_ref_marker(1, 'x', size/2) + + ax_test.set(xlim=(-0.5, 1.5), ylim=(-0.5, 1.5)) + ax_ref.set(xlim=(-0.5, 1.5), ylim=(-0.5, 1.5)) + + +# The bullet mathtext marker is not quite a circle, so this is not a perfect match, but +# it is close enough to confirm that the text-based marker is centred correctly. But we +# still need a small tolerance to work around that difference. +@check_figures_equal(extensions=['png'], tol=1.86) +def test_text_marker(fig_ref, fig_test): + ax_ref = fig_ref.add_subplot() + ax_test = fig_test.add_subplot() + + ax_ref.plot(0, 0, marker=r'o', markersize=100, markeredgewidth=0) + ax_test.plot(0, 0, marker=r'$\bullet$', markersize=100, markeredgewidth=0) + + +@check_figures_equal() +def test_marker_clipping(fig_ref, fig_test): + # Plotting multiple markers can trigger different optimized paths in + # backends, so compare single markers vs multiple to ensure they are + # clipped correctly. + marker_count = len(markers.MarkerStyle.markers) + marker_size = 50 + ncol = 7 + nrow = marker_count // ncol + 1 + + width = 2 * marker_size * ncol + height = 2 * marker_size * nrow * 2 + fig_ref.set_size_inches((width / fig_ref.dpi, height / fig_ref.dpi)) + ax_ref = fig_ref.add_axes([0, 0, 1, 1]) + fig_test.set_size_inches((width / fig_test.dpi, height / fig_ref.dpi)) + ax_test = fig_test.add_axes([0, 0, 1, 1]) + + for i, marker in enumerate(markers.MarkerStyle.markers): + x = i % ncol + y = i // ncol * 2 + + # Singular markers per call. + ax_ref.plot([x, x], [y, y + 1], c='k', linestyle='-', lw=3) + ax_ref.plot(x, y, c='k', + marker=marker, markersize=marker_size, markeredgewidth=10, + fillstyle='full', markerfacecolor='white') + ax_ref.plot(x, y + 1, c='k', + marker=marker, markersize=marker_size, markeredgewidth=10, + fillstyle='full', markerfacecolor='white') + + # Multiple markers in a single call. + ax_test.plot([x, x], [y, y + 1], c='k', linestyle='-', lw=3, + marker=marker, markersize=marker_size, markeredgewidth=10, + fillstyle='full', markerfacecolor='white') + + ax_ref.set(xlim=(-0.5, ncol), ylim=(-0.5, 2 * nrow)) + ax_test.set(xlim=(-0.5, ncol), ylim=(-0.5, 2 * nrow)) + ax_ref.axis('off') + ax_test.axis('off') + + +def test_marker_init_transforms(): + """Test that initializing marker with transform is a simple addition.""" + marker = markers.MarkerStyle("o") + t = Affine2D().translate(1, 1) + t_marker = markers.MarkerStyle("o", transform=t) + assert marker.get_transform() + t == t_marker.get_transform() + + +def test_marker_init_joinstyle(): + marker = markers.MarkerStyle("*") + styled_marker = markers.MarkerStyle("*", joinstyle="round") + assert styled_marker.get_joinstyle() == "round" + assert marker.get_joinstyle() != "round" + + +def test_marker_init_captyle(): + marker = markers.MarkerStyle("*") + styled_marker = markers.MarkerStyle("*", capstyle="round") + assert styled_marker.get_capstyle() == "round" + assert marker.get_capstyle() != "round" + + +@pytest.mark.parametrize("marker,transform,expected", [ + (markers.MarkerStyle("o"), Affine2D().translate(1, 1), + Affine2D().translate(1, 1)), + (markers.MarkerStyle("o", transform=Affine2D().translate(1, 1)), + Affine2D().translate(1, 1), Affine2D().translate(2, 2)), + (markers.MarkerStyle("$|||$", transform=Affine2D().translate(1, 1)), + Affine2D().translate(1, 1), Affine2D().translate(2, 2)), + (markers.MarkerStyle( + markers.TICKLEFT, transform=Affine2D().translate(1, 1)), + Affine2D().translate(1, 1), Affine2D().translate(2, 2)), +]) +def test_marker_transformed(marker, transform, expected): + new_marker = marker.transformed(transform) + assert new_marker is not marker + assert new_marker.get_user_transform() == expected + assert marker._user_transform is not new_marker._user_transform + + +def test_marker_rotated_invalid(): + marker = markers.MarkerStyle("o") + with pytest.raises(ValueError): + new_marker = marker.rotated() + with pytest.raises(ValueError): + new_marker = marker.rotated(deg=10, rad=10) + + +@pytest.mark.parametrize("marker,deg,rad,expected", [ + (markers.MarkerStyle("o"), 10, None, Affine2D().rotate_deg(10)), + (markers.MarkerStyle("o"), None, 0.01, Affine2D().rotate(0.01)), + (markers.MarkerStyle("o", transform=Affine2D().translate(1, 1)), + 10, None, Affine2D().translate(1, 1).rotate_deg(10)), + (markers.MarkerStyle("o", transform=Affine2D().translate(1, 1)), + None, 0.01, Affine2D().translate(1, 1).rotate(0.01)), + (markers.MarkerStyle("$|||$", transform=Affine2D().translate(1, 1)), + 10, None, Affine2D().translate(1, 1).rotate_deg(10)), + (markers.MarkerStyle( + markers.TICKLEFT, transform=Affine2D().translate(1, 1)), + 10, None, Affine2D().translate(1, 1).rotate_deg(10)), +]) +def test_marker_rotated(marker, deg, rad, expected): + new_marker = marker.rotated(deg=deg, rad=rad) + assert new_marker is not marker + assert new_marker.get_user_transform() == expected + assert marker._user_transform is not new_marker._user_transform + + +def test_marker_scaled(): + marker = markers.MarkerStyle("1") + new_marker = marker.scaled(2) + assert new_marker is not marker + assert new_marker.get_user_transform() == Affine2D().scale(2) + assert marker._user_transform is not new_marker._user_transform + + new_marker = marker.scaled(2, 3) + assert new_marker is not marker + assert new_marker.get_user_transform() == Affine2D().scale(2, 3) + assert marker._user_transform is not new_marker._user_transform + + marker = markers.MarkerStyle("1", transform=Affine2D().translate(1, 1)) + new_marker = marker.scaled(2) + assert new_marker is not marker + expected = Affine2D().translate(1, 1).scale(2) + assert new_marker.get_user_transform() == expected + assert marker._user_transform is not new_marker._user_transform + + +def test_alt_transform(): + m1 = markers.MarkerStyle("o", "left") + m2 = markers.MarkerStyle("o", "left", Affine2D().rotate_deg(90)) + assert m1.get_alt_transform().rotate_deg(90) == m2.get_alt_transform() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mathtext.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mathtext.py new file mode 100644 index 00000000..7ebc76da --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mathtext.py @@ -0,0 +1,560 @@ +from __future__ import annotations + +import io +from pathlib import Path +import platform +import re +import shlex +from xml.etree import ElementTree as ET +from typing import Any + +import numpy as np +from packaging.version import parse as parse_version +import pyparsing +import pytest + + +import matplotlib as mpl +from matplotlib.testing.decorators import check_figures_equal, image_comparison +import matplotlib.pyplot as plt +from matplotlib import mathtext, _mathtext + +pyparsing_version = parse_version(pyparsing.__version__) + + +# If test is removed, use None as placeholder +math_tests = [ + r'$a+b+\dot s+\dot{s}+\ldots$', + r'$x\hspace{-0.2}\doteq\hspace{-0.2}y$', + r'\$100.00 $\alpha \_$', + r'$\frac{\$100.00}{y}$', + r'$x y$', + r'$x+y\ x=y\ x<y\ x:y\ x,y\ x@y$', + r'$100\%y\ x*y\ x/y x\$y$', + r'$x\leftarrow y\ x\forall y\ x-y$', + r'$x \sf x \bf x {\cal X} \rm x$', + r'$x\ x\,x\;x\quad x\qquad x\!x\hspace{ 0.5 }y$', + r'$\{ \rm braces \}$', + r'$\left[\left\lfloor\frac{5}{\frac{\left(3\right)}{4}} y\right)\right]$', + r'$\left(x\right)$', + r'$\sin(x)$', + r'$x_2$', + r'$x^2$', + r'$x^2_y$', + r'$x_y^2$', + (r'$\sum _{\genfrac{}{}{0}{}{0\leq i\leq m}{0<j<n}}f\left(i,j\right)' + r'\mathcal{R}\prod_{i=\alpha_{i+1}}^\infty a_i \sin(2 \pi f x_i)' + r"\sqrt[2]{\prod^\frac{x}{2\pi^2}_\infty}$"), + r'$x = \frac{x+\frac{5}{2}}{\frac{y+3}{8}}$', + r'$dz/dt = \gamma x^2 + {\rm sin}(2\pi y+\phi)$', + r'Foo: $\alpha_{i+1}^j = {\rm sin}(2\pi f_j t_i) e^{-5 t_i/\tau}$', + None, + r'Variable $i$ is good', + r'$\Delta_i^j$', + r'$\Delta^j_{i+1}$', + r'$\ddot{o}\acute{e}\grave{e}\hat{O}\breve{\imath}\tilde{n}\vec{q}$', + r"$\arccos((x^i))$", + r"$\gamma = \frac{x=\frac{6}{8}}{y} \delta$", + r'$\limsup_{x\to\infty}$', + None, + r"$f'\quad f'''(x)\quad ''/\mathrm{yr}$", + r'$\frac{x_2888}{y}$', + r"$\sqrt[3]{\frac{X_2}{Y}}=5$", + None, + r"$\sqrt[3]{x}=5$", + r'$\frac{X}{\frac{X}{Y}}$', + r"$W^{3\beta}_{\delta_1 \rho_1 \sigma_2} = U^{3\beta}_{\delta_1 \rho_1} + \frac{1}{8 \pi 2} \int^{\alpha_2}_{\alpha_2} d \alpha^\prime_2 \left[\frac{ U^{2\beta}_{\delta_1 \rho_1} - \alpha^\prime_2U^{1\beta}_{\rho_1 \sigma_2} }{U^{0\beta}_{\rho_1 \sigma_2}}\right]$", + r'$\mathcal{H} = \int d \tau \left(\epsilon E^2 + \mu H^2\right)$', + r'$\widehat{abc}\widetilde{def}$', + '$\\Gamma \\Delta \\Theta \\Lambda \\Xi \\Pi \\Sigma \\Upsilon \\Phi \\Psi \\Omega$', + '$\\alpha \\beta \\gamma \\delta \\epsilon \\zeta \\eta \\theta \\iota \\lambda \\mu \\nu \\xi \\pi \\kappa \\rho \\sigma \\tau \\upsilon \\phi \\chi \\psi$', + + # The following examples are from the MathML torture test here: + # https://www-archive.mozilla.org/projects/mathml/demo/texvsmml.xhtml + r'${x}^{2}{y}^{2}$', + r'${}_{2}F_{3}$', + r'$\frac{x+{y}^{2}}{k+1}$', + r'$x+{y}^{\frac{2}{k+1}}$', + r'$\frac{a}{b/2}$', + r'${a}_{0}+\frac{1}{{a}_{1}+\frac{1}{{a}_{2}+\frac{1}{{a}_{3}+\frac{1}{{a}_{4}}}}}$', + r'${a}_{0}+\frac{1}{{a}_{1}+\frac{1}{{a}_{2}+\frac{1}{{a}_{3}+\frac{1}{{a}_{4}}}}}$', + r'$\binom{n}{k/2}$', + r'$\binom{p}{2}{x}^{2}{y}^{p-2}-\frac{1}{1-x}\frac{1}{1-{x}^{2}}$', + r'${x}^{2y}$', + r'$\sum _{i=1}^{p}\sum _{j=1}^{q}\sum _{k=1}^{r}{a}_{ij}{b}_{jk}{c}_{ki}$', + r'$\sqrt{1+\sqrt{1+\sqrt{1+\sqrt{1+\sqrt{1+\sqrt{1+\sqrt{1+x}}}}}}}$', + r'$\left(\frac{{\partial }^{2}}{\partial {x}^{2}}+\frac{{\partial }^{2}}{\partial {y}^{2}}\right){|\varphi \left(x+iy\right)|}^{2}=0$', + r'${2}^{{2}^{{2}^{x}}}$', + r'${\int }_{1}^{x}\frac{\mathrm{dt}}{t}$', + r'$\int {\int }_{D}\mathrm{dx} \mathrm{dy}$', + # mathtex doesn't support array + # 'mmltt18' : r'$f\left(x\right)=\left\{\begin{array}{cc}\hfill 1/3\hfill & \text{if_}0\le x\le 1;\hfill \\ \hfill 2/3\hfill & \hfill \text{if_}3\le x\le 4;\hfill \\ \hfill 0\hfill & \text{elsewhere.}\hfill \end{array}$', + # mathtex doesn't support stackrel + # 'mmltt19' : r'$\stackrel{\stackrel{k\text{times}}{\ufe37}}{x+...+x}$', + r'${y}_{{x}^{2}}$', + # mathtex doesn't support the "\text" command + # 'mmltt21' : r'$\sum _{p\text{\prime}}f\left(p\right)={\int }_{t>1}f\left(t\right) d\pi \left(t\right)$', + # mathtex doesn't support array + # 'mmltt23' : r'$\left(\begin{array}{cc}\hfill \left(\begin{array}{cc}\hfill a\hfill & \hfill b\hfill \\ \hfill c\hfill & \hfill d\hfill \end{array}\right)\hfill & \hfill \left(\begin{array}{cc}\hfill e\hfill & \hfill f\hfill \\ \hfill g\hfill & \hfill h\hfill \end{array}\right)\hfill \\ \hfill 0\hfill & \hfill \left(\begin{array}{cc}\hfill i\hfill & \hfill j\hfill \\ \hfill k\hfill & \hfill l\hfill \end{array}\right)\hfill \end{array}\right)$', + # mathtex doesn't support array + # 'mmltt24' : r'$det|\begin{array}{ccccc}\hfill {c}_{0}\hfill & \hfill {c}_{1}\hfill & \hfill {c}_{2}\hfill & \hfill \dots \hfill & \hfill {c}_{n}\hfill \\ \hfill {c}_{1}\hfill & \hfill {c}_{2}\hfill & \hfill {c}_{3}\hfill & \hfill \dots \hfill & \hfill {c}_{n+1}\hfill \\ \hfill {c}_{2}\hfill & \hfill {c}_{3}\hfill & \hfill {c}_{4}\hfill & \hfill \dots \hfill & \hfill {c}_{n+2}\hfill \\ \hfill \u22ee\hfill & \hfill \u22ee\hfill & \hfill \u22ee\hfill & \hfill \hfill & \hfill \u22ee\hfill \\ \hfill {c}_{n}\hfill & \hfill {c}_{n+1}\hfill & \hfill {c}_{n+2}\hfill & \hfill \dots \hfill & \hfill {c}_{2n}\hfill \end{array}|>0$', + r'${y}_{{x}_{2}}$', + r'${x}_{92}^{31415}+\pi $', + r'${x}_{{y}_{b}^{a}}^{{z}_{c}^{d}}$', + r'${y}_{3}^{\prime \prime \prime }$', + # End of the MathML torture tests. + + r"$\left( \xi \left( 1 - \xi \right) \right)$", # Bug 2969451 + r"$\left(2 \, a=b\right)$", # Sage bug #8125 + r"$? ! &$", # github issue #466 + None, + None, + r"$\left\Vert \frac{a}{b} \right\Vert \left\vert \frac{a}{b} \right\vert \left\| \frac{a}{b}\right\| \left| \frac{a}{b} \right| \Vert a \Vert \vert b \vert \| a \| | b |$", + r'$\mathring{A} \AA$', + r'$M \, M \thinspace M \/ M \> M \: M \; M \ M \enspace M \quad M \qquad M \! M$', + r'$\Cap$ $\Cup$ $\leftharpoonup$ $\barwedge$ $\rightharpoonup$', + r'$\hspace{-0.2}\dotplus\hspace{-0.2}$ $\hspace{-0.2}\doteq\hspace{-0.2}$ $\hspace{-0.2}\doteqdot\hspace{-0.2}$ $\ddots$', + r'$xyz^kx_kx^py^{p-2} d_i^jb_jc_kd x^j_i E^0 E^0_u$', # github issue #4873 + r'${xyz}^k{x}_{k}{x}^{p}{y}^{p-2} {d}_{i}^{j}{b}_{j}{c}_{k}{d} {x}^{j}_{i}{E}^{0}{E}^0_u$', + r'${\int}_x^x x\oint_x^x x\int_{X}^{X}x\int_x x \int^x x \int_{x} x\int^{x}{\int}_{x} x{\int}^{x}_{x}x$', + r'testing$^{123}$', + None, + r'$6-2$; $-2$; $ -2$; ${-2}$; ${ -2}$; $20^{+3}_{-2}$', + r'$\overline{\omega}^x \frac{1}{2}_0^x$', # github issue #5444 + r'$,$ $.$ $1{,}234{, }567{ , }890$ and $1,234,567,890$', # github issue 5799 + r'$\left(X\right)_{a}^{b}$', # github issue 7615 + r'$\dfrac{\$100.00}{y}$', # github issue #1888 +] +# 'svgastext' tests switch svg output to embed text as text (rather than as +# paths). +svgastext_math_tests = [ + r'$-$-', +] +# 'lightweight' tests test only a single fontset (dejavusans, which is the +# default) and only png outputs, in order to minimize the size of baseline +# images. +lightweight_math_tests = [ + r'$\sqrt[ab]{123}$', # github issue #8665 + r'$x \overset{f}{\rightarrow} \overset{f}{x} \underset{xx}{ff} \overset{xx}{ff} \underset{f}{x} \underset{f}{\leftarrow} x$', # github issue #18241 + r'$\sum x\quad\sum^nx\quad\sum_nx\quad\sum_n^nx\quad\prod x\quad\prod^nx\quad\prod_nx\quad\prod_n^nx$', # GitHub issue 18085 + r'$1.$ $2.$ $19680801.$ $a.$ $b.$ $mpl.$', + r'$\text{text}_{\text{sub}}^{\text{sup}} + \text{\$foo\$} + \frac{\text{num}}{\mathbf{\text{den}}}\text{with space, curly brackets \{\}, and dash -}$', + r'$\boldsymbol{abcde} \boldsymbol{+} \boldsymbol{\Gamma + \Omega} \boldsymbol{01234} \boldsymbol{\alpha * \beta}$', + r'$\left\lbrace\frac{\left\lbrack A^b_c\right\rbrace}{\left\leftbrace D^e_f \right\rbrack}\right\rightbrace\ \left\leftparen\max_{x} \left\lgroup \frac{A}{B}\right\rgroup \right\rightparen$', + r'$\left( a\middle. b \right)$ $\left( \frac{a}{b} \middle\vert x_i \in P^S \right)$ $\left[ 1 - \middle| a\middle| + \left( x - \left\lfloor \dfrac{a}{b}\right\rfloor \right) \right]$', + r'$\sum_{\substack{k = 1\\ k \neq \lfloor n/2\rfloor}}^{n}P(i,j) \sum_{\substack{i \neq 0\\ -1 \leq i \leq 3\\ 1 \leq j \leq 5}} F^i(x,y) \sum_{\substack{\left \lfloor \frac{n}{2} \right\rfloor}} F(n)$', +] + +digits = "0123456789" +uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +lowercase = "abcdefghijklmnopqrstuvwxyz" +uppergreek = ("\\Gamma \\Delta \\Theta \\Lambda \\Xi \\Pi \\Sigma \\Upsilon \\Phi \\Psi " + "\\Omega") +lowergreek = ("\\alpha \\beta \\gamma \\delta \\epsilon \\zeta \\eta \\theta \\iota " + "\\lambda \\mu \\nu \\xi \\pi \\kappa \\rho \\sigma \\tau \\upsilon " + "\\phi \\chi \\psi") +all = [digits, uppercase, lowercase, uppergreek, lowergreek] + +# Use stubs to reserve space if tests are removed +# stub should be of the form (None, N) where N is the number of strings that +# used to be tested +# Add new tests at the end. +font_test_specs: list[tuple[None | list[str], Any]] = [ + ([], all), + (['mathrm'], all), + (['mathbf'], all), + (['mathit'], all), + (['mathtt'], [digits, uppercase, lowercase]), + (None, 3), + (None, 3), + (None, 3), + (['mathbb'], [digits, uppercase, lowercase, + r'\Gamma \Pi \Sigma \gamma \pi']), + (['mathrm', 'mathbb'], [digits, uppercase, lowercase, + r'\Gamma \Pi \Sigma \gamma \pi']), + (['mathbf', 'mathbb'], [digits, uppercase, lowercase, + r'\Gamma \Pi \Sigma \gamma \pi']), + (['mathcal'], [uppercase]), + (['mathfrak'], [uppercase, lowercase]), + (['mathbf', 'mathfrak'], [uppercase, lowercase]), + (['mathscr'], [uppercase, lowercase]), + (['mathsf'], [digits, uppercase, lowercase]), + (['mathrm', 'mathsf'], [digits, uppercase, lowercase]), + (['mathbf', 'mathsf'], [digits, uppercase, lowercase]), + (['mathbfit'], all), + ] + +font_tests: list[None | str] = [] +for fonts, chars in font_test_specs: + if fonts is None: + font_tests.extend([None] * chars) + else: + wrapper = ''.join([ + ' '.join(fonts), + ' $', + *(r'\%s{' % font for font in fonts), + '%s', + *('}' for font in fonts), + '$', + ]) + for set in chars: + font_tests.append(wrapper % set) + + +@pytest.fixture +def baseline_images(request, fontset, index, text): + if text is None: + pytest.skip("test has been removed") + return ['%s_%s_%02d' % (request.param, fontset, index)] + + +@pytest.mark.parametrize( + 'index, text', enumerate(math_tests), ids=range(len(math_tests))) +@pytest.mark.parametrize( + 'fontset', ['cm', 'stix', 'stixsans', 'dejavusans', 'dejavuserif']) +@pytest.mark.parametrize('baseline_images', ['mathtext'], indirect=True) +@image_comparison(baseline_images=None, + tol=0.011 if platform.machine() in ('ppc64le', 's390x') else 0) +def test_mathtext_rendering(baseline_images, fontset, index, text): + mpl.rcParams['mathtext.fontset'] = fontset + fig = plt.figure(figsize=(5.25, 0.75)) + fig.text(0.5, 0.5, text, + horizontalalignment='center', verticalalignment='center') + + +@pytest.mark.parametrize('index, text', enumerate(svgastext_math_tests), + ids=range(len(svgastext_math_tests))) +@pytest.mark.parametrize('fontset', ['cm', 'dejavusans']) +@pytest.mark.parametrize('baseline_images', ['mathtext0'], indirect=True) +@image_comparison( + baseline_images=None, extensions=['svg'], + savefig_kwarg={'metadata': { # Minimize image size. + 'Creator': None, 'Date': None, 'Format': None, 'Type': None}}) +def test_mathtext_rendering_svgastext(baseline_images, fontset, index, text): + mpl.rcParams['mathtext.fontset'] = fontset + mpl.rcParams['svg.fonttype'] = 'none' # Minimize image size. + fig = plt.figure(figsize=(5.25, 0.75)) + fig.patch.set(visible=False) # Minimize image size. + fig.text(0.5, 0.5, text, + horizontalalignment='center', verticalalignment='center') + + +@pytest.mark.parametrize('index, text', enumerate(lightweight_math_tests), + ids=range(len(lightweight_math_tests))) +@pytest.mark.parametrize('fontset', ['dejavusans']) +@pytest.mark.parametrize('baseline_images', ['mathtext1'], indirect=True) +@image_comparison(baseline_images=None, extensions=['png']) +def test_mathtext_rendering_lightweight(baseline_images, fontset, index, text): + fig = plt.figure(figsize=(5.25, 0.75)) + fig.text(0.5, 0.5, text, math_fontfamily=fontset, + horizontalalignment='center', verticalalignment='center') + + +@pytest.mark.parametrize( + 'index, text', enumerate(font_tests), ids=range(len(font_tests))) +@pytest.mark.parametrize( + 'fontset', ['cm', 'stix', 'stixsans', 'dejavusans', 'dejavuserif']) +@pytest.mark.parametrize('baseline_images', ['mathfont'], indirect=True) +@image_comparison(baseline_images=None, extensions=['png'], + tol=0.011 if platform.machine() in ('ppc64le', 's390x') else 0) +def test_mathfont_rendering(baseline_images, fontset, index, text): + mpl.rcParams['mathtext.fontset'] = fontset + fig = plt.figure(figsize=(5.25, 0.75)) + fig.text(0.5, 0.5, text, + horizontalalignment='center', verticalalignment='center') + + +@check_figures_equal(extensions=["png"]) +def test_short_long_accents(fig_test, fig_ref): + acc_map = _mathtext.Parser._accent_map + short_accs = [s for s in acc_map if len(s) == 1] + corresponding_long_accs = [] + for s in short_accs: + l, = [l for l in acc_map if len(l) > 1 and acc_map[l] == acc_map[s]] + corresponding_long_accs.append(l) + fig_test.text(0, .5, "$" + "".join(rf"\{s}a" for s in short_accs) + "$") + fig_ref.text( + 0, .5, "$" + "".join(fr"\{l} a" for l in corresponding_long_accs) + "$") + + +def test_fontinfo(): + fontpath = mpl.font_manager.findfont("DejaVu Sans") + font = mpl.ft2font.FT2Font(fontpath) + table = font.get_sfnt_table("head") + assert table is not None + assert table['version'] == (1, 0) + + +# See gh-26152 for more context on this xfail +@pytest.mark.xfail(pyparsing_version.release == (3, 1, 0), + reason="Error messages are incorrect for this version") +@pytest.mark.parametrize( + 'math, msg', + [ + (r'$\hspace{}$', r'Expected \hspace{space}'), + (r'$\hspace{foo}$', r'Expected \hspace{space}'), + (r'$\sinx$', r'Unknown symbol: \sinx'), + (r'$\dotx$', r'Unknown symbol: \dotx'), + (r'$\frac$', r'Expected \frac{num}{den}'), + (r'$\frac{}{}$', r'Expected \frac{num}{den}'), + (r'$\binom$', r'Expected \binom{num}{den}'), + (r'$\binom{}{}$', r'Expected \binom{num}{den}'), + (r'$\genfrac$', + r'Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}'), + (r'$\genfrac{}{}{}{}{}{}$', + r'Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}'), + (r'$\sqrt$', r'Expected \sqrt{value}'), + (r'$\sqrt f$', r'Expected \sqrt{value}'), + (r'$\overline$', r'Expected \overline{body}'), + (r'$\overline{}$', r'Expected \overline{body}'), + (r'$\leftF$', r'Expected a delimiter'), + (r'$\rightF$', r'Unknown symbol: \rightF'), + (r'$\left(\right$', r'Expected a delimiter'), + # PyParsing 2 uses double quotes, PyParsing 3 uses single quotes and an + # extra backslash. + (r'$\left($', re.compile(r'Expected ("|\'\\)\\right["\']')), + (r'$\dfrac$', r'Expected \dfrac{num}{den}'), + (r'$\dfrac{}{}$', r'Expected \dfrac{num}{den}'), + (r'$\overset$', r'Expected \overset{annotation}{body}'), + (r'$\underset$', r'Expected \underset{annotation}{body}'), + (r'$\foo$', r'Unknown symbol: \foo'), + (r'$a^2^2$', r'Double superscript'), + (r'$a_2_2$', r'Double subscript'), + (r'$a^2_a^2$', r'Double superscript'), + (r'$a = {b$', r"Expected '}'"), + ], + ids=[ + 'hspace without value', + 'hspace with invalid value', + 'function without space', + 'accent without space', + 'frac without parameters', + 'frac with empty parameters', + 'binom without parameters', + 'binom with empty parameters', + 'genfrac without parameters', + 'genfrac with empty parameters', + 'sqrt without parameters', + 'sqrt with invalid value', + 'overline without parameters', + 'overline with empty parameter', + 'left with invalid delimiter', + 'right with invalid delimiter', + 'unclosed parentheses with sizing', + 'unclosed parentheses without sizing', + 'dfrac without parameters', + 'dfrac with empty parameters', + 'overset without parameters', + 'underset without parameters', + 'unknown symbol', + 'double superscript', + 'double subscript', + 'super on sub without braces', + 'unclosed group', + ] +) +def test_mathtext_exceptions(math, msg): + parser = mathtext.MathTextParser('agg') + match = re.escape(msg) if isinstance(msg, str) else msg + with pytest.raises(ValueError, match=match): + parser.parse(math) + + +def test_get_unicode_index_exception(): + with pytest.raises(ValueError): + _mathtext.get_unicode_index(r'\foo') + + +def test_single_minus_sign(): + fig = plt.figure() + fig.text(0.5, 0.5, '$-$') + fig.canvas.draw() + t = np.asarray(fig.canvas.renderer.buffer_rgba()) + assert (t != 0xff).any() # assert that canvas is not all white. + + +@check_figures_equal(extensions=["png"]) +def test_spaces(fig_test, fig_ref): + fig_test.text(.5, .5, r"$1\,2\>3\ 4$") + fig_ref.text(.5, .5, r"$1\/2\:3~4$") + + +@check_figures_equal(extensions=["png"]) +def test_operator_space(fig_test, fig_ref): + fig_test.text(0.1, 0.1, r"$\log 6$") + fig_test.text(0.1, 0.2, r"$\log(6)$") + fig_test.text(0.1, 0.3, r"$\arcsin 6$") + fig_test.text(0.1, 0.4, r"$\arcsin|6|$") + fig_test.text(0.1, 0.5, r"$\operatorname{op} 6$") # GitHub issue #553 + fig_test.text(0.1, 0.6, r"$\operatorname{op}[6]$") + fig_test.text(0.1, 0.7, r"$\cos^2$") + fig_test.text(0.1, 0.8, r"$\log_2$") + fig_test.text(0.1, 0.9, r"$\sin^2 \cos$") # GitHub issue #17852 + + fig_ref.text(0.1, 0.1, r"$\mathrm{log\,}6$") + fig_ref.text(0.1, 0.2, r"$\mathrm{log}(6)$") + fig_ref.text(0.1, 0.3, r"$\mathrm{arcsin\,}6$") + fig_ref.text(0.1, 0.4, r"$\mathrm{arcsin}|6|$") + fig_ref.text(0.1, 0.5, r"$\mathrm{op\,}6$") + fig_ref.text(0.1, 0.6, r"$\mathrm{op}[6]$") + fig_ref.text(0.1, 0.7, r"$\mathrm{cos}^2$") + fig_ref.text(0.1, 0.8, r"$\mathrm{log}_2$") + fig_ref.text(0.1, 0.9, r"$\mathrm{sin}^2 \mathrm{\,cos}$") + + +@check_figures_equal(extensions=["png"]) +def test_inverted_delimiters(fig_test, fig_ref): + fig_test.text(.5, .5, r"$\left)\right($", math_fontfamily="dejavusans") + fig_ref.text(.5, .5, r"$)($", math_fontfamily="dejavusans") + + +@check_figures_equal(extensions=["png"]) +def test_genfrac_displaystyle(fig_test, fig_ref): + fig_test.text(0.1, 0.1, r"$\dfrac{2x}{3y}$") + + thickness = _mathtext.TruetypeFonts.get_underline_thickness( + None, None, fontsize=mpl.rcParams["font.size"], + dpi=mpl.rcParams["savefig.dpi"]) + fig_ref.text(0.1, 0.1, r"$\genfrac{}{}{%f}{0}{2x}{3y}$" % thickness) + + +def test_mathtext_fallback_valid(): + for fallback in ['cm', 'stix', 'stixsans', 'None']: + mpl.rcParams['mathtext.fallback'] = fallback + + +def test_mathtext_fallback_invalid(): + for fallback in ['abc', '']: + with pytest.raises(ValueError, match="not a valid fallback font name"): + mpl.rcParams['mathtext.fallback'] = fallback + + +@pytest.mark.parametrize( + "fallback,fontlist", + [("cm", ['DejaVu Sans', 'mpltest', 'STIXGeneral', 'cmr10', 'STIXGeneral']), + ("stix", ['DejaVu Sans', 'mpltest', 'STIXGeneral'])]) +def test_mathtext_fallback(fallback, fontlist): + mpl.font_manager.fontManager.addfont( + str(Path(__file__).resolve().parent / 'mpltest.ttf')) + mpl.rcParams["svg.fonttype"] = 'none' + mpl.rcParams['mathtext.fontset'] = 'custom' + mpl.rcParams['mathtext.rm'] = 'mpltest' + mpl.rcParams['mathtext.it'] = 'mpltest:italic' + mpl.rcParams['mathtext.bf'] = 'mpltest:bold' + mpl.rcParams['mathtext.bfit'] = 'mpltest:italic:bold' + mpl.rcParams['mathtext.fallback'] = fallback + + test_str = r'a$A\AA\breve\gimel$' + + buff = io.BytesIO() + fig, ax = plt.subplots() + fig.text(.5, .5, test_str, fontsize=40, ha='center') + fig.savefig(buff, format="svg") + tspans = (ET.fromstring(buff.getvalue()) + .findall(".//{http://www.w3.org/2000/svg}tspan[@style]")) + # Getting the last element of the style attrib is a close enough + # approximation for parsing the font property. + char_fonts = [shlex.split(tspan.attrib["style"])[-1] for tspan in tspans] + assert char_fonts == fontlist + mpl.font_manager.fontManager.ttflist.pop() + + +def test_math_to_image(tmpdir): + mathtext.math_to_image('$x^2$', str(tmpdir.join('example.png'))) + mathtext.math_to_image('$x^2$', io.BytesIO()) + mathtext.math_to_image('$x^2$', io.BytesIO(), color='Maroon') + + +@image_comparison(baseline_images=['math_fontfamily_image.png'], + savefig_kwarg={'dpi': 40}) +def test_math_fontfamily(): + fig = plt.figure(figsize=(10, 3)) + fig.text(0.2, 0.7, r"$This\ text\ should\ have\ one\ font$", + size=24, math_fontfamily='dejavusans') + fig.text(0.2, 0.3, r"$This\ text\ should\ have\ another$", + size=24, math_fontfamily='stix') + + +def test_default_math_fontfamily(): + mpl.rcParams['mathtext.fontset'] = 'cm' + test_str = r'abc$abc\alpha$' + fig, ax = plt.subplots() + + text1 = fig.text(0.1, 0.1, test_str, font='Arial') + prop1 = text1.get_fontproperties() + assert prop1.get_math_fontfamily() == 'cm' + text2 = fig.text(0.2, 0.2, test_str, fontproperties='Arial') + prop2 = text2.get_fontproperties() + assert prop2.get_math_fontfamily() == 'cm' + + fig.draw_without_rendering() + + +def test_argument_order(): + mpl.rcParams['mathtext.fontset'] = 'cm' + test_str = r'abc$abc\alpha$' + fig, ax = plt.subplots() + + text1 = fig.text(0.1, 0.1, test_str, + math_fontfamily='dejavusans', font='Arial') + prop1 = text1.get_fontproperties() + assert prop1.get_math_fontfamily() == 'dejavusans' + text2 = fig.text(0.2, 0.2, test_str, + math_fontfamily='dejavusans', fontproperties='Arial') + prop2 = text2.get_fontproperties() + assert prop2.get_math_fontfamily() == 'dejavusans' + text3 = fig.text(0.3, 0.3, test_str, + font='Arial', math_fontfamily='dejavusans') + prop3 = text3.get_fontproperties() + assert prop3.get_math_fontfamily() == 'dejavusans' + text4 = fig.text(0.4, 0.4, test_str, + fontproperties='Arial', math_fontfamily='dejavusans') + prop4 = text4.get_fontproperties() + assert prop4.get_math_fontfamily() == 'dejavusans' + + fig.draw_without_rendering() + + +def test_mathtext_cmr10_minus_sign(): + # cmr10 does not contain a minus sign and used to issue a warning + # RuntimeWarning: Glyph 8722 missing from current font. + mpl.rcParams['font.family'] = 'cmr10' + mpl.rcParams['axes.formatter.use_mathtext'] = True + fig, ax = plt.subplots() + ax.plot(range(-1, 1), range(-1, 1)) + # draw to make sure we have no warnings + fig.canvas.draw() + + +def test_mathtext_operators(): + test_str = r''' + \increment \smallin \notsmallowns + \smallowns \QED \rightangle + \smallintclockwise \smallvarointclockwise + \smallointctrcclockwise + \ratio \minuscolon \dotsminusdots + \sinewave \simneqq \nlesssim + \ngtrsim \nlessgtr \ngtrless + \cupleftarrow \oequal \rightassert + \rightModels \hermitmatrix \barvee + \measuredrightangle \varlrtriangle + \equalparallel \npreccurlyeq \nsucccurlyeq + \nsqsubseteq \nsqsupseteq \sqsubsetneq + \sqsupsetneq \disin \varisins + \isins \isindot \varisinobar + \isinobar \isinvb \isinE + \nisd \varnis \nis + \varniobar \niobar \bagmember + \triangle'''.split() + + fig = plt.figure() + for x, i in enumerate(test_str): + fig.text(0.5, (x + 0.5)/len(test_str), r'${%s}$' % i) + + fig.draw_without_rendering() + + +@check_figures_equal(extensions=["png"]) +def test_boldsymbol(fig_test, fig_ref): + fig_test.text(0.1, 0.2, r"$\boldsymbol{\mathrm{abc0123\alpha}}$") + fig_ref.text(0.1, 0.2, r"$\mathrm{abc0123\alpha}$") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_matplotlib.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_matplotlib.py new file mode 100644 index 00000000..ac1c3455 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_matplotlib.py @@ -0,0 +1,77 @@ +import os +import subprocess +import sys + +import pytest + +import matplotlib + + +@pytest.mark.parametrize('version_str, version_tuple', [ + ('3.5.0', (3, 5, 0, 'final', 0)), + ('3.5.0rc2', (3, 5, 0, 'candidate', 2)), + ('3.5.0.dev820+g6768ef8c4c', (3, 5, 0, 'alpha', 820)), + ('3.5.0.post820+g6768ef8c4c', (3, 5, 1, 'alpha', 820)), +]) +def test_parse_to_version_info(version_str, version_tuple): + assert matplotlib._parse_to_version_info(version_str) == version_tuple + + +@pytest.mark.skipif(sys.platform == "win32", + reason="chmod() doesn't work as is on Windows") +@pytest.mark.skipif(sys.platform != "win32" and os.geteuid() == 0, + reason="chmod() doesn't work as root") +def test_tmpconfigdir_warning(tmpdir): + """Test that a warning is emitted if a temporary configdir must be used.""" + mode = os.stat(tmpdir).st_mode + try: + os.chmod(tmpdir, 0) + proc = subprocess.run( + [sys.executable, "-c", "import matplotlib"], + env={**os.environ, "MPLCONFIGDIR": str(tmpdir)}, + stderr=subprocess.PIPE, text=True, check=True) + assert "set the MPLCONFIGDIR" in proc.stderr + finally: + os.chmod(tmpdir, mode) + + +def test_importable_with_no_home(tmpdir): + subprocess.run( + [sys.executable, "-c", + "import pathlib; pathlib.Path.home = lambda *args: 1/0; " + "import matplotlib.pyplot"], + env={**os.environ, "MPLCONFIGDIR": str(tmpdir)}, check=True) + + +def test_use_doc_standard_backends(): + """ + Test that the standard backends mentioned in the docstring of + matplotlib.use() are the same as in matplotlib.rcsetup. + """ + def parse(key): + backends = [] + for line in matplotlib.use.__doc__.split(key)[1].split('\n'): + if not line.strip(): + break + backends += [e.strip() for e in line.split(',') if e] + return backends + + assert (set(parse('- interactive backends:\n')) == + set(matplotlib.rcsetup.interactive_bk)) + assert (set(parse('- non-interactive backends:\n')) == + set(matplotlib.rcsetup.non_interactive_bk)) + + +def test_importable_with__OO(): + """ + When using -OO or export PYTHONOPTIMIZE=2, docstrings are discarded, + this simple test may prevent something like issue #17970. + """ + program = ( + "import matplotlib as mpl; " + "import matplotlib.pyplot as plt; " + "import matplotlib.cbook as cbook; " + "import matplotlib.patches as mpatches" + ) + cmd = [sys.executable, "-OO", "-c", program] + assert subprocess.call(cmd, env={**os.environ, "MPLBACKEND": ""}) == 0 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mlab.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mlab.py new file mode 100644 index 00000000..3b0d2529 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_mlab.py @@ -0,0 +1,1022 @@ +from numpy.testing import (assert_allclose, assert_almost_equal, + assert_array_equal, assert_array_almost_equal_nulp) +import numpy as np +import pytest + +from matplotlib import mlab + + +def test_window(): + np.random.seed(0) + n = 1000 + rand = np.random.standard_normal(n) + 100 + ones = np.ones(n) + assert_array_equal(mlab.window_none(ones), ones) + assert_array_equal(mlab.window_none(rand), rand) + assert_array_equal(np.hanning(len(rand)) * rand, mlab.window_hanning(rand)) + assert_array_equal(np.hanning(len(ones)), mlab.window_hanning(ones)) + + +class TestDetrend: + def setup_method(self): + np.random.seed(0) + n = 1000 + x = np.linspace(0., 100, n) + + self.sig_zeros = np.zeros(n) + + self.sig_off = self.sig_zeros + 100. + self.sig_slope = np.linspace(-10., 90., n) + self.sig_slope_mean = x - x.mean() + + self.sig_base = ( + np.random.standard_normal(n) + np.sin(x*2*np.pi/(n/100))) + self.sig_base -= self.sig_base.mean() + + def allclose(self, *args): + assert_allclose(*args, atol=1e-8) + + def test_detrend_none(self): + assert mlab.detrend_none(0.) == 0. + assert mlab.detrend_none(0., axis=1) == 0. + assert mlab.detrend(0., key="none") == 0. + assert mlab.detrend(0., key=mlab.detrend_none) == 0. + for sig in [ + 5.5, self.sig_off, self.sig_slope, self.sig_base, + (self.sig_base + self.sig_slope + self.sig_off).tolist(), + np.vstack([self.sig_base, # 2D case. + self.sig_base + self.sig_off, + self.sig_base + self.sig_slope, + self.sig_base + self.sig_off + self.sig_slope]), + np.vstack([self.sig_base, # 2D transposed case. + self.sig_base + self.sig_off, + self.sig_base + self.sig_slope, + self.sig_base + self.sig_off + self.sig_slope]).T, + ]: + if isinstance(sig, np.ndarray): + assert_array_equal(mlab.detrend_none(sig), sig) + else: + assert mlab.detrend_none(sig) == sig + + def test_detrend_mean(self): + for sig in [0., 5.5]: # 0D. + assert mlab.detrend_mean(sig) == 0. + assert mlab.detrend(sig, key="mean") == 0. + assert mlab.detrend(sig, key=mlab.detrend_mean) == 0. + # 1D. + self.allclose(mlab.detrend_mean(self.sig_zeros), self.sig_zeros) + self.allclose(mlab.detrend_mean(self.sig_base), self.sig_base) + self.allclose(mlab.detrend_mean(self.sig_base + self.sig_off), + self.sig_base) + self.allclose(mlab.detrend_mean(self.sig_base + self.sig_slope), + self.sig_base + self.sig_slope_mean) + self.allclose( + mlab.detrend_mean(self.sig_base + self.sig_slope + self.sig_off), + self.sig_base + self.sig_slope_mean) + + def test_detrend_mean_1d_base_slope_off_list_andor_axis0(self): + input = self.sig_base + self.sig_slope + self.sig_off + target = self.sig_base + self.sig_slope_mean + self.allclose(mlab.detrend_mean(input, axis=0), target) + self.allclose(mlab.detrend_mean(input.tolist()), target) + self.allclose(mlab.detrend_mean(input.tolist(), axis=0), target) + + def test_detrend_mean_2d(self): + input = np.vstack([self.sig_off, + self.sig_base + self.sig_off]) + target = np.vstack([self.sig_zeros, + self.sig_base]) + self.allclose(mlab.detrend_mean(input), target) + self.allclose(mlab.detrend_mean(input, axis=None), target) + self.allclose(mlab.detrend_mean(input.T, axis=None).T, target) + self.allclose(mlab.detrend(input), target) + self.allclose(mlab.detrend(input, axis=None), target) + self.allclose( + mlab.detrend(input.T, key="constant", axis=None), target.T) + + input = np.vstack([self.sig_base, + self.sig_base + self.sig_off, + self.sig_base + self.sig_slope, + self.sig_base + self.sig_off + self.sig_slope]) + target = np.vstack([self.sig_base, + self.sig_base, + self.sig_base + self.sig_slope_mean, + self.sig_base + self.sig_slope_mean]) + self.allclose(mlab.detrend_mean(input.T, axis=0), target.T) + self.allclose(mlab.detrend_mean(input, axis=1), target) + self.allclose(mlab.detrend_mean(input, axis=-1), target) + self.allclose(mlab.detrend(input, key="default", axis=1), target) + self.allclose(mlab.detrend(input.T, key="mean", axis=0), target.T) + self.allclose( + mlab.detrend(input.T, key=mlab.detrend_mean, axis=0), target.T) + + def test_detrend_ValueError(self): + for signal, kwargs in [ + (self.sig_slope[np.newaxis], {"key": "spam"}), + (self.sig_slope[np.newaxis], {"key": 5}), + (5.5, {"axis": 0}), + (self.sig_slope, {"axis": 1}), + (self.sig_slope[np.newaxis], {"axis": 2}), + ]: + with pytest.raises(ValueError): + mlab.detrend(signal, **kwargs) + + def test_detrend_mean_ValueError(self): + for signal, kwargs in [ + (5.5, {"axis": 0}), + (self.sig_slope, {"axis": 1}), + (self.sig_slope[np.newaxis], {"axis": 2}), + ]: + with pytest.raises(ValueError): + mlab.detrend_mean(signal, **kwargs) + + def test_detrend_linear(self): + # 0D. + assert mlab.detrend_linear(0.) == 0. + assert mlab.detrend_linear(5.5) == 0. + assert mlab.detrend(5.5, key="linear") == 0. + assert mlab.detrend(5.5, key=mlab.detrend_linear) == 0. + for sig in [ # 1D. + self.sig_off, + self.sig_slope, + self.sig_slope + self.sig_off, + ]: + self.allclose(mlab.detrend_linear(sig), self.sig_zeros) + + def test_detrend_str_linear_1d(self): + input = self.sig_slope + self.sig_off + target = self.sig_zeros + self.allclose(mlab.detrend(input, key="linear"), target) + self.allclose(mlab.detrend(input, key=mlab.detrend_linear), target) + self.allclose(mlab.detrend_linear(input.tolist()), target) + + def test_detrend_linear_2d(self): + input = np.vstack([self.sig_off, + self.sig_slope, + self.sig_slope + self.sig_off]) + target = np.vstack([self.sig_zeros, + self.sig_zeros, + self.sig_zeros]) + self.allclose( + mlab.detrend(input.T, key="linear", axis=0), target.T) + self.allclose( + mlab.detrend(input.T, key=mlab.detrend_linear, axis=0), target.T) + self.allclose( + mlab.detrend(input, key="linear", axis=1), target) + self.allclose( + mlab.detrend(input, key=mlab.detrend_linear, axis=1), target) + + with pytest.raises(ValueError): + mlab.detrend_linear(self.sig_slope[np.newaxis]) + + +@pytest.mark.parametrize('iscomplex', [False, True], + ids=['real', 'complex'], scope='class') +@pytest.mark.parametrize('sides', ['onesided', 'twosided', 'default'], + scope='class') +@pytest.mark.parametrize( + 'fstims,len_x,NFFT_density,nover_density,pad_to_density,pad_to_spectrum', + [ + ([], None, -1, -1, -1, -1), + ([4], None, -1, -1, -1, -1), + ([4, 5, 10], None, -1, -1, -1, -1), + ([], None, None, -1, -1, None), + ([], None, -1, -1, None, None), + ([], None, None, -1, None, None), + ([], 1024, 512, -1, -1, 128), + ([], 256, -1, -1, 33, 257), + ([], 255, 33, -1, -1, None), + ([], 256, 128, -1, 256, 256), + ([], None, -1, 32, -1, -1), + ], + ids=[ + 'nosig', + 'Fs4', + 'FsAll', + 'nosig_noNFFT', + 'nosig_nopad_to', + 'nosig_noNFFT_no_pad_to', + 'nosig_trim', + 'nosig_odd', + 'nosig_oddlen', + 'nosig_stretch', + 'nosig_overlap', + ], + scope='class') +class TestSpectral: + @pytest.fixture(scope='class', autouse=True) + def stim(self, request, fstims, iscomplex, sides, len_x, NFFT_density, + nover_density, pad_to_density, pad_to_spectrum): + Fs = 100. + + x = np.arange(0, 10, 1 / Fs) + if len_x is not None: + x = x[:len_x] + + # get the stimulus frequencies, defaulting to None + fstims = [Fs / fstim for fstim in fstims] + + # get the constants, default to calculated values + if NFFT_density is None: + NFFT_density_real = 256 + elif NFFT_density < 0: + NFFT_density_real = NFFT_density = 100 + else: + NFFT_density_real = NFFT_density + + if nover_density is None: + nover_density_real = 0 + elif nover_density < 0: + nover_density_real = nover_density = NFFT_density_real // 2 + else: + nover_density_real = nover_density + + if pad_to_density is None: + pad_to_density_real = NFFT_density_real + elif pad_to_density < 0: + pad_to_density = int(2**np.ceil(np.log2(NFFT_density_real))) + pad_to_density_real = pad_to_density + else: + pad_to_density_real = pad_to_density + + if pad_to_spectrum is None: + pad_to_spectrum_real = len(x) + elif pad_to_spectrum < 0: + pad_to_spectrum_real = pad_to_spectrum = len(x) + else: + pad_to_spectrum_real = pad_to_spectrum + + if pad_to_spectrum is None: + NFFT_spectrum_real = NFFT_spectrum = pad_to_spectrum_real + else: + NFFT_spectrum_real = NFFT_spectrum = len(x) + nover_spectrum = 0 + + NFFT_specgram = NFFT_density + nover_specgram = nover_density + pad_to_specgram = pad_to_density + NFFT_specgram_real = NFFT_density_real + nover_specgram_real = nover_density_real + + if sides == 'onesided' or (sides == 'default' and not iscomplex): + # frequencies for specgram, psd, and csd + # need to handle even and odd differently + if pad_to_density_real % 2: + freqs_density = np.linspace(0, Fs / 2, + num=pad_to_density_real, + endpoint=False)[::2] + else: + freqs_density = np.linspace(0, Fs / 2, + num=pad_to_density_real // 2 + 1) + + # frequencies for complex, magnitude, angle, and phase spectrums + # need to handle even and odd differently + if pad_to_spectrum_real % 2: + freqs_spectrum = np.linspace(0, Fs / 2, + num=pad_to_spectrum_real, + endpoint=False)[::2] + else: + freqs_spectrum = np.linspace(0, Fs / 2, + num=pad_to_spectrum_real // 2 + 1) + else: + # frequencies for specgram, psd, and csd + # need to handle even and odd differently + if pad_to_density_real % 2: + freqs_density = np.linspace(-Fs / 2, Fs / 2, + num=2 * pad_to_density_real, + endpoint=False)[1::2] + else: + freqs_density = np.linspace(-Fs / 2, Fs / 2, + num=pad_to_density_real, + endpoint=False) + + # frequencies for complex, magnitude, angle, and phase spectrums + # need to handle even and odd differently + if pad_to_spectrum_real % 2: + freqs_spectrum = np.linspace(-Fs / 2, Fs / 2, + num=2 * pad_to_spectrum_real, + endpoint=False)[1::2] + else: + freqs_spectrum = np.linspace(-Fs / 2, Fs / 2, + num=pad_to_spectrum_real, + endpoint=False) + + freqs_specgram = freqs_density + # time points for specgram + t_start = NFFT_specgram_real // 2 + t_stop = len(x) - NFFT_specgram_real // 2 + 1 + t_step = NFFT_specgram_real - nover_specgram_real + t_specgram = x[t_start:t_stop:t_step] + if NFFT_specgram_real % 2: + t_specgram += 1 / Fs / 2 + if len(t_specgram) == 0: + t_specgram = np.array([NFFT_specgram_real / (2 * Fs)]) + t_spectrum = np.array([NFFT_spectrum_real / (2 * Fs)]) + t_density = t_specgram + + y = np.zeros_like(x) + for i, fstim in enumerate(fstims): + y += np.sin(fstim * x * np.pi * 2) * 10**i + + if iscomplex: + y = y.astype('complex') + + # Interestingly, the instance on which this fixture is called is not + # the same as the one on which a test is run. So we need to modify the + # class itself when using a class-scoped fixture. + cls = request.cls + + cls.Fs = Fs + cls.sides = sides + cls.fstims = fstims + + cls.NFFT_density = NFFT_density + cls.nover_density = nover_density + cls.pad_to_density = pad_to_density + + cls.NFFT_spectrum = NFFT_spectrum + cls.nover_spectrum = nover_spectrum + cls.pad_to_spectrum = pad_to_spectrum + + cls.NFFT_specgram = NFFT_specgram + cls.nover_specgram = nover_specgram + cls.pad_to_specgram = pad_to_specgram + + cls.t_specgram = t_specgram + cls.t_density = t_density + cls.t_spectrum = t_spectrum + cls.y = y + + cls.freqs_density = freqs_density + cls.freqs_spectrum = freqs_spectrum + cls.freqs_specgram = freqs_specgram + + cls.NFFT_density_real = NFFT_density_real + + def check_freqs(self, vals, targfreqs, resfreqs, fstims): + assert resfreqs.argmin() == 0 + assert resfreqs.argmax() == len(resfreqs)-1 + assert_allclose(resfreqs, targfreqs, atol=1e-06) + for fstim in fstims: + i = np.abs(resfreqs - fstim).argmin() + assert vals[i] > vals[i+2] + assert vals[i] > vals[i-2] + + def check_maxfreq(self, spec, fsp, fstims): + # skip the test if there are no frequencies + if len(fstims) == 0: + return + + # if twosided, do the test for each side + if fsp.min() < 0: + fspa = np.abs(fsp) + zeroind = fspa.argmin() + self.check_maxfreq(spec[:zeroind], fspa[:zeroind], fstims) + self.check_maxfreq(spec[zeroind:], fspa[zeroind:], fstims) + return + + fstimst = fstims[:] + spect = spec.copy() + + # go through each peak and make sure it is correctly the maximum peak + while fstimst: + maxind = spect.argmax() + maxfreq = fsp[maxind] + assert_almost_equal(maxfreq, fstimst[-1]) + del fstimst[-1] + spect[maxind-5:maxind+5] = 0 + + def test_spectral_helper_raises(self): + # We don't use parametrize here to handle ``y = self.y``. + for kwargs in [ # Various error conditions: + {"y": self.y+1, "mode": "complex"}, # Modes requiring ``x is y``. + {"y": self.y+1, "mode": "magnitude"}, + {"y": self.y+1, "mode": "angle"}, + {"y": self.y+1, "mode": "phase"}, + {"mode": "spam"}, # Bad mode. + {"y": self.y, "sides": "eggs"}, # Bad sides. + {"y": self.y, "NFFT": 10, "noverlap": 20}, # noverlap > NFFT. + {"NFFT": 10, "noverlap": 10}, # noverlap == NFFT. + {"y": self.y, "NFFT": 10, + "window": np.ones(9)}, # len(win) != NFFT. + ]: + with pytest.raises(ValueError): + mlab._spectral_helper(x=self.y, **kwargs) + + @pytest.mark.parametrize('mode', ['default', 'psd']) + def test_single_spectrum_helper_unsupported_modes(self, mode): + with pytest.raises(ValueError): + mlab._single_spectrum_helper(x=self.y, mode=mode) + + @pytest.mark.parametrize("mode, case", [ + ("psd", "density"), + ("magnitude", "specgram"), + ("magnitude", "spectrum"), + ]) + def test_spectral_helper_psd(self, mode, case): + freqs = getattr(self, f"freqs_{case}") + spec, fsp, t = mlab._spectral_helper( + x=self.y, y=self.y, + NFFT=getattr(self, f"NFFT_{case}"), + Fs=self.Fs, + noverlap=getattr(self, f"nover_{case}"), + pad_to=getattr(self, f"pad_to_{case}"), + sides=self.sides, + mode=mode) + + assert_allclose(fsp, freqs, atol=1e-06) + assert_allclose(t, getattr(self, f"t_{case}"), atol=1e-06) + assert spec.shape[0] == freqs.shape[0] + assert spec.shape[1] == getattr(self, f"t_{case}").shape[0] + + def test_csd(self): + freqs = self.freqs_density + spec, fsp = mlab.csd(x=self.y, y=self.y+1, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides) + assert_allclose(fsp, freqs, atol=1e-06) + assert spec.shape == freqs.shape + + def test_csd_padding(self): + """Test zero padding of csd().""" + if self.NFFT_density is None: # for derived classes + return + sargs = dict(x=self.y, y=self.y+1, Fs=self.Fs, window=mlab.window_none, + sides=self.sides) + + spec0, _ = mlab.csd(NFFT=self.NFFT_density, **sargs) + spec1, _ = mlab.csd(NFFT=self.NFFT_density*2, **sargs) + assert_almost_equal(np.sum(np.conjugate(spec0)*spec0).real, + np.sum(np.conjugate(spec1/2)*spec1/2).real) + + def test_psd(self): + freqs = self.freqs_density + spec, fsp = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides) + assert spec.shape == freqs.shape + self.check_freqs(spec, freqs, fsp, self.fstims) + + @pytest.mark.parametrize( + 'make_data, detrend', + [(np.zeros, mlab.detrend_mean), (np.zeros, 'mean'), + (np.arange, mlab.detrend_linear), (np.arange, 'linear')]) + def test_psd_detrend(self, make_data, detrend): + if self.NFFT_density is None: + return + ydata = make_data(self.NFFT_density) + ydata1 = ydata+5 + ydata2 = ydata+3.3 + ydata = np.vstack([ydata1, ydata2]) + ydata = np.tile(ydata, (20, 1)) + ydatab = ydata.T.flatten() + ydata = ydata.flatten() + ycontrol = np.zeros_like(ydata) + spec_g, fsp_g = mlab.psd(x=ydata, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + detrend=detrend) + spec_b, fsp_b = mlab.psd(x=ydatab, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + detrend=detrend) + spec_c, fsp_c = mlab.psd(x=ycontrol, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides) + assert_array_equal(fsp_g, fsp_c) + assert_array_equal(fsp_b, fsp_c) + assert_allclose(spec_g, spec_c, atol=1e-08) + # these should not be almost equal + with pytest.raises(AssertionError): + assert_allclose(spec_b, spec_c, atol=1e-08) + + def test_psd_window_hanning(self): + if self.NFFT_density is None: + return + ydata = np.arange(self.NFFT_density) + ydata1 = ydata+5 + ydata2 = ydata+3.3 + windowVals = mlab.window_hanning(np.ones_like(ydata1)) + ycontrol1 = ydata1 * windowVals + ycontrol2 = mlab.window_hanning(ydata2) + ydata = np.vstack([ydata1, ydata2]) + ycontrol = np.vstack([ycontrol1, ycontrol2]) + ydata = np.tile(ydata, (20, 1)) + ycontrol = np.tile(ycontrol, (20, 1)) + ydatab = ydata.T.flatten() + ydataf = ydata.flatten() + ycontrol = ycontrol.flatten() + spec_g, fsp_g = mlab.psd(x=ydataf, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=mlab.window_hanning) + spec_b, fsp_b = mlab.psd(x=ydatab, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=mlab.window_hanning) + spec_c, fsp_c = mlab.psd(x=ycontrol, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=mlab.window_none) + spec_c *= len(ycontrol1)/(windowVals**2).sum() + assert_array_equal(fsp_g, fsp_c) + assert_array_equal(fsp_b, fsp_c) + assert_allclose(spec_g, spec_c, atol=1e-08) + # these should not be almost equal + with pytest.raises(AssertionError): + assert_allclose(spec_b, spec_c, atol=1e-08) + + def test_psd_window_hanning_detrend_linear(self): + if self.NFFT_density is None: + return + ydata = np.arange(self.NFFT_density) + ycontrol = np.zeros(self.NFFT_density) + ydata1 = ydata+5 + ydata2 = ydata+3.3 + ycontrol1 = ycontrol + ycontrol2 = ycontrol + windowVals = mlab.window_hanning(np.ones_like(ycontrol1)) + ycontrol1 = ycontrol1 * windowVals + ycontrol2 = mlab.window_hanning(ycontrol2) + ydata = np.vstack([ydata1, ydata2]) + ycontrol = np.vstack([ycontrol1, ycontrol2]) + ydata = np.tile(ydata, (20, 1)) + ycontrol = np.tile(ycontrol, (20, 1)) + ydatab = ydata.T.flatten() + ydataf = ydata.flatten() + ycontrol = ycontrol.flatten() + spec_g, fsp_g = mlab.psd(x=ydataf, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + detrend=mlab.detrend_linear, + window=mlab.window_hanning) + spec_b, fsp_b = mlab.psd(x=ydatab, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + detrend=mlab.detrend_linear, + window=mlab.window_hanning) + spec_c, fsp_c = mlab.psd(x=ycontrol, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=mlab.window_none) + spec_c *= len(ycontrol1)/(windowVals**2).sum() + assert_array_equal(fsp_g, fsp_c) + assert_array_equal(fsp_b, fsp_c) + assert_allclose(spec_g, spec_c, atol=1e-08) + # these should not be almost equal + with pytest.raises(AssertionError): + assert_allclose(spec_b, spec_c, atol=1e-08) + + def test_psd_window_flattop(self): + # flattop window + # adaption from https://github.com/scipy/scipy/blob\ + # /v1.10.0/scipy/signal/windows/_windows.py#L562-L622 + a = [0.21557895, 0.41663158, 0.277263158, 0.083578947, 0.006947368] + fac = np.linspace(-np.pi, np.pi, self.NFFT_density_real) + win = np.zeros(self.NFFT_density_real) + for k in range(len(a)): + win += a[k] * np.cos(k * fac) + + spec, fsp = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=win, + scale_by_freq=False) + spec_a, fsp_a = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=0, + sides=self.sides, + window=win) + assert_allclose(spec*win.sum()**2, + spec_a*self.Fs*(win**2).sum(), + atol=1e-08) + + def test_psd_windowarray(self): + freqs = self.freqs_density + spec, fsp = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides, + window=np.ones(self.NFFT_density_real)) + assert_allclose(fsp, freqs, atol=1e-06) + assert spec.shape == freqs.shape + + def test_psd_windowarray_scale_by_freq(self): + win = mlab.window_hanning(np.ones(self.NFFT_density_real)) + + spec, fsp = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides, + window=mlab.window_hanning) + spec_s, fsp_s = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides, + window=mlab.window_hanning, + scale_by_freq=True) + spec_n, fsp_n = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides, + window=mlab.window_hanning, + scale_by_freq=False) + assert_array_equal(fsp, fsp_s) + assert_array_equal(fsp, fsp_n) + assert_array_equal(spec, spec_s) + assert_allclose(spec_s*(win**2).sum(), + spec_n/self.Fs*win.sum()**2, + atol=1e-08) + + @pytest.mark.parametrize( + "kind", ["complex", "magnitude", "angle", "phase"]) + def test_spectrum(self, kind): + freqs = self.freqs_spectrum + spec, fsp = getattr(mlab, f"{kind}_spectrum")( + x=self.y, + Fs=self.Fs, sides=self.sides, pad_to=self.pad_to_spectrum) + assert_allclose(fsp, freqs, atol=1e-06) + assert spec.shape == freqs.shape + if kind == "magnitude": + self.check_maxfreq(spec, fsp, self.fstims) + self.check_freqs(spec, freqs, fsp, self.fstims) + + @pytest.mark.parametrize( + 'kwargs', + [{}, {'mode': 'default'}, {'mode': 'psd'}, {'mode': 'magnitude'}, + {'mode': 'complex'}, {'mode': 'angle'}, {'mode': 'phase'}]) + def test_specgram(self, kwargs): + freqs = self.freqs_specgram + spec, fsp, t = mlab.specgram(x=self.y, + NFFT=self.NFFT_specgram, + Fs=self.Fs, + noverlap=self.nover_specgram, + pad_to=self.pad_to_specgram, + sides=self.sides, + **kwargs) + if kwargs.get('mode') == 'complex': + spec = np.abs(spec) + specm = np.mean(spec, axis=1) + + assert_allclose(fsp, freqs, atol=1e-06) + assert_allclose(t, self.t_specgram, atol=1e-06) + + assert spec.shape[0] == freqs.shape[0] + assert spec.shape[1] == self.t_specgram.shape[0] + + if kwargs.get('mode') not in ['complex', 'angle', 'phase']: + # using a single freq, so all time slices should be about the same + if np.abs(spec.max()) != 0: + assert_allclose( + np.diff(spec, axis=1).max() / np.abs(spec.max()), 0, + atol=1e-02) + if kwargs.get('mode') not in ['angle', 'phase']: + self.check_freqs(specm, freqs, fsp, self.fstims) + + def test_specgram_warn_only1seg(self): + """Warning should be raised if len(x) <= NFFT.""" + with pytest.warns(UserWarning, match="Only one segment is calculated"): + mlab.specgram(x=self.y, NFFT=len(self.y), Fs=self.Fs) + + def test_psd_csd_equal(self): + Pxx, freqsxx = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides) + Pxy, freqsxy = mlab.csd(x=self.y, y=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides) + assert_array_almost_equal_nulp(Pxx, Pxy) + assert_array_equal(freqsxx, freqsxy) + + @pytest.mark.parametrize("mode", ["default", "psd"]) + def test_specgram_auto_default_psd_equal(self, mode): + """ + Test that mlab.specgram without mode and with mode 'default' and 'psd' + are all the same. + """ + speca, freqspeca, ta = mlab.specgram(x=self.y, + NFFT=self.NFFT_specgram, + Fs=self.Fs, + noverlap=self.nover_specgram, + pad_to=self.pad_to_specgram, + sides=self.sides) + specb, freqspecb, tb = mlab.specgram(x=self.y, + NFFT=self.NFFT_specgram, + Fs=self.Fs, + noverlap=self.nover_specgram, + pad_to=self.pad_to_specgram, + sides=self.sides, + mode=mode) + assert_array_equal(speca, specb) + assert_array_equal(freqspeca, freqspecb) + assert_array_equal(ta, tb) + + @pytest.mark.parametrize( + "mode, conv", [ + ("magnitude", np.abs), + ("angle", np.angle), + ("phase", lambda x: np.unwrap(np.angle(x), axis=0)) + ]) + def test_specgram_complex_equivalent(self, mode, conv): + specc, freqspecc, tc = mlab.specgram(x=self.y, + NFFT=self.NFFT_specgram, + Fs=self.Fs, + noverlap=self.nover_specgram, + pad_to=self.pad_to_specgram, + sides=self.sides, + mode='complex') + specm, freqspecm, tm = mlab.specgram(x=self.y, + NFFT=self.NFFT_specgram, + Fs=self.Fs, + noverlap=self.nover_specgram, + pad_to=self.pad_to_specgram, + sides=self.sides, + mode=mode) + + assert_array_equal(freqspecc, freqspecm) + assert_array_equal(tc, tm) + assert_allclose(conv(specc), specm, atol=1e-06) + + def test_psd_windowarray_equal(self): + win = mlab.window_hanning(np.ones(self.NFFT_density_real)) + speca, fspa = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides, + window=win) + specb, fspb = mlab.psd(x=self.y, + NFFT=self.NFFT_density, + Fs=self.Fs, + noverlap=self.nover_density, + pad_to=self.pad_to_density, + sides=self.sides) + assert_array_equal(fspa, fspb) + assert_allclose(speca, specb, atol=1e-08) + + +# extra test for cohere... +def test_cohere(): + N = 1024 + np.random.seed(19680801) + x = np.random.randn(N) + # phase offset + y = np.roll(x, 20) + # high-freq roll-off + y = np.convolve(y, np.ones(20) / 20., mode='same') + cohsq, f = mlab.cohere(x, y, NFFT=256, Fs=2, noverlap=128) + assert_allclose(np.mean(cohsq), 0.837, atol=1.e-3) + assert np.isreal(np.mean(cohsq)) + + +# ***************************************************************** +# These Tests were taken from SCIPY with some minor modifications +# this can be retrieved from: +# https://github.com/scipy/scipy/blob/master/scipy/stats/tests/test_kdeoth.py +# ***************************************************************** + +class TestGaussianKDE: + + def test_kde_integer_input(self): + """Regression test for #1181.""" + x1 = np.arange(5) + kde = mlab.GaussianKDE(x1) + y_expected = [0.13480721, 0.18222869, 0.19514935, 0.18222869, + 0.13480721] + np.testing.assert_array_almost_equal(kde(x1), y_expected, decimal=6) + + def test_gaussian_kde_covariance_caching(self): + x1 = np.array([-7, -5, 1, 4, 5], dtype=float) + xs = np.linspace(-10, 10, num=5) + # These expected values are from scipy 0.10, before some changes to + # gaussian_kde. They were not compared with any external reference. + y_expected = [0.02463386, 0.04689208, 0.05395444, 0.05337754, + 0.01664475] + + # set it to the default bandwidth. + kde2 = mlab.GaussianKDE(x1, 'scott') + y2 = kde2(xs) + + np.testing.assert_array_almost_equal(y_expected, y2, decimal=7) + + def test_kde_bandwidth_method(self): + + np.random.seed(8765678) + n_basesample = 50 + xn = np.random.randn(n_basesample) + + # Default + gkde = mlab.GaussianKDE(xn) + # Supply a callable + gkde2 = mlab.GaussianKDE(xn, 'scott') + # Supply a scalar + gkde3 = mlab.GaussianKDE(xn, bw_method=gkde.factor) + + xs = np.linspace(-7, 7, 51) + kdepdf = gkde.evaluate(xs) + kdepdf2 = gkde2.evaluate(xs) + assert kdepdf.all() == kdepdf2.all() + kdepdf3 = gkde3.evaluate(xs) + assert kdepdf.all() == kdepdf3.all() + + +class TestGaussianKDECustom: + def test_no_data(self): + """Pass no data into the GaussianKDE class.""" + with pytest.raises(ValueError): + mlab.GaussianKDE([]) + + def test_single_dataset_element(self): + """Pass a single dataset element into the GaussianKDE class.""" + with pytest.raises(ValueError): + mlab.GaussianKDE([42]) + + def test_silverman_multidim_dataset(self): + """Test silverman's for a multi-dimensional array.""" + x1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + with pytest.raises(np.linalg.LinAlgError): + mlab.GaussianKDE(x1, "silverman") + + def test_silverman_singledim_dataset(self): + """Test silverman's output for a single dimension list.""" + x1 = np.array([-7, -5, 1, 4, 5]) + mygauss = mlab.GaussianKDE(x1, "silverman") + y_expected = 0.76770389927475502 + assert_almost_equal(mygauss.covariance_factor(), y_expected, 7) + + def test_scott_multidim_dataset(self): + """Test scott's output for a multi-dimensional array.""" + x1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + with pytest.raises(np.linalg.LinAlgError): + mlab.GaussianKDE(x1, "scott") + + def test_scott_singledim_dataset(self): + """Test scott's output a single-dimensional array.""" + x1 = np.array([-7, -5, 1, 4, 5]) + mygauss = mlab.GaussianKDE(x1, "scott") + y_expected = 0.72477966367769553 + assert_almost_equal(mygauss.covariance_factor(), y_expected, 7) + + def test_scalar_empty_dataset(self): + """Test the scalar's cov factor for an empty array.""" + with pytest.raises(ValueError): + mlab.GaussianKDE([], bw_method=5) + + def test_scalar_covariance_dataset(self): + """Test a scalar's cov factor.""" + np.random.seed(8765678) + n_basesample = 50 + multidim_data = [np.random.randn(n_basesample) for i in range(5)] + + kde = mlab.GaussianKDE(multidim_data, bw_method=0.5) + assert kde.covariance_factor() == 0.5 + + def test_callable_covariance_dataset(self): + """Test the callable's cov factor for a multi-dimensional array.""" + np.random.seed(8765678) + n_basesample = 50 + multidim_data = [np.random.randn(n_basesample) for i in range(5)] + + def callable_fun(x): + return 0.55 + kde = mlab.GaussianKDE(multidim_data, bw_method=callable_fun) + assert kde.covariance_factor() == 0.55 + + def test_callable_singledim_dataset(self): + """Test the callable's cov factor for a single-dimensional array.""" + np.random.seed(8765678) + n_basesample = 50 + multidim_data = np.random.randn(n_basesample) + + kde = mlab.GaussianKDE(multidim_data, bw_method='silverman') + y_expected = 0.48438841363348911 + assert_almost_equal(kde.covariance_factor(), y_expected, 7) + + def test_wrong_bw_method(self): + """Test the error message that should be called when bw is invalid.""" + np.random.seed(8765678) + n_basesample = 50 + data = np.random.randn(n_basesample) + with pytest.raises(ValueError): + mlab.GaussianKDE(data, bw_method="invalid") + + +class TestGaussianKDEEvaluate: + + def test_evaluate_diff_dim(self): + """ + Test the evaluate method when the dim's of dataset and points have + different dimensions. + """ + x1 = np.arange(3, 10, 2) + kde = mlab.GaussianKDE(x1) + x2 = np.arange(3, 12, 2) + y_expected = [ + 0.08797252, 0.11774109, 0.11774109, 0.08797252, 0.0370153 + ] + y = kde.evaluate(x2) + np.testing.assert_array_almost_equal(y, y_expected, 7) + + def test_evaluate_inv_dim(self): + """ + Invert the dimensions; i.e., for a dataset of dimension 1 [3, 2, 4], + the points should have a dimension of 3 [[3], [2], [4]]. + """ + np.random.seed(8765678) + n_basesample = 50 + multidim_data = np.random.randn(n_basesample) + kde = mlab.GaussianKDE(multidim_data) + x2 = [[1], [2], [3]] + with pytest.raises(ValueError): + kde.evaluate(x2) + + def test_evaluate_dim_and_num(self): + """Tests if evaluated against a one by one array""" + x1 = np.arange(3, 10, 2) + x2 = np.array([3]) + kde = mlab.GaussianKDE(x1) + y_expected = [0.08797252] + y = kde.evaluate(x2) + np.testing.assert_array_almost_equal(y, y_expected, 7) + + def test_evaluate_point_dim_not_one(self): + x1 = np.arange(3, 10, 2) + x2 = [np.arange(3, 10, 2), np.arange(3, 10, 2)] + kde = mlab.GaussianKDE(x1) + with pytest.raises(ValueError): + kde.evaluate(x2) + + def test_evaluate_equal_dim_and_num_lt(self): + x1 = np.arange(3, 10, 2) + x2 = np.arange(3, 8, 2) + kde = mlab.GaussianKDE(x1) + y_expected = [0.08797252, 0.11774109, 0.11774109] + y = kde.evaluate(x2) + np.testing.assert_array_almost_equal(y, y_expected, 7) + + +def test_psd_onesided_norm(): + u = np.array([0, 1, 2, 3, 1, 2, 1]) + dt = 1.0 + Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size) + P, f = mlab.psd(u, NFFT=u.size, Fs=1/dt, window=mlab.window_none, + detrend=mlab.detrend_none, noverlap=0, pad_to=None, + scale_by_freq=None, + sides='onesided') + Su_1side = np.append([Su[0]], Su[1:4] + Su[4:][::-1]) + assert_allclose(P, Su_1side, atol=1e-06) + + +def test_psd_oversampling(): + """Test the case len(x) < NFFT for psd().""" + u = np.array([0, 1, 2, 3, 1, 2, 1]) + dt = 1.0 + Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size) + P, f = mlab.psd(u, NFFT=u.size*2, Fs=1/dt, window=mlab.window_none, + detrend=mlab.detrend_none, noverlap=0, pad_to=None, + scale_by_freq=None, + sides='onesided') + Su_1side = np.append([Su[0]], Su[1:4] + Su[4:][::-1]) + assert_almost_equal(np.sum(P), np.sum(Su_1side)) # same energy diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_offsetbox.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_offsetbox.py new file mode 100644 index 00000000..49b55e4c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_offsetbox.py @@ -0,0 +1,452 @@ +from collections import namedtuple +import io + +import numpy as np +from numpy.testing import assert_allclose +import pytest + +from matplotlib.testing.decorators import check_figures_equal, image_comparison +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import matplotlib.lines as mlines +from matplotlib.backend_bases import MouseButton, MouseEvent + +from matplotlib.offsetbox import ( + AnchoredOffsetbox, AnnotationBbox, AnchoredText, DrawingArea, HPacker, + OffsetBox, OffsetImage, PaddedBox, TextArea, VPacker, _get_packed_offsets) + + +@image_comparison(['offsetbox_clipping'], remove_text=True) +def test_offsetbox_clipping(): + # - create a plot + # - put an AnchoredOffsetbox with a child DrawingArea + # at the center of the axes + # - give the DrawingArea a gray background + # - put a black line across the bounds of the DrawingArea + # - see that the black line is clipped to the edges of + # the DrawingArea. + fig, ax = plt.subplots() + size = 100 + da = DrawingArea(size, size, clip=True) + assert da.clip_children + bg = mpatches.Rectangle((0, 0), size, size, + facecolor='#CCCCCC', + edgecolor='None', + linewidth=0) + line = mlines.Line2D([-size*.5, size*1.5], [size/2, size/2], + color='black', + linewidth=10) + anchored_box = AnchoredOffsetbox( + loc='center', + child=da, + pad=0., + frameon=False, + bbox_to_anchor=(.5, .5), + bbox_transform=ax.transAxes, + borderpad=0.) + + da.add_artist(bg) + da.add_artist(line) + ax.add_artist(anchored_box) + ax.set_xlim((0, 1)) + ax.set_ylim((0, 1)) + + +def test_offsetbox_clip_children(): + # - create a plot + # - put an AnchoredOffsetbox with a child DrawingArea + # at the center of the axes + # - give the DrawingArea a gray background + # - put a black line across the bounds of the DrawingArea + # - see that the black line is clipped to the edges of + # the DrawingArea. + fig, ax = plt.subplots() + size = 100 + da = DrawingArea(size, size, clip=True) + bg = mpatches.Rectangle((0, 0), size, size, + facecolor='#CCCCCC', + edgecolor='None', + linewidth=0) + line = mlines.Line2D([-size*.5, size*1.5], [size/2, size/2], + color='black', + linewidth=10) + anchored_box = AnchoredOffsetbox( + loc='center', + child=da, + pad=0., + frameon=False, + bbox_to_anchor=(.5, .5), + bbox_transform=ax.transAxes, + borderpad=0.) + + da.add_artist(bg) + da.add_artist(line) + ax.add_artist(anchored_box) + + fig.canvas.draw() + assert not fig.stale + da.clip_children = True + assert fig.stale + + +def test_offsetbox_loc_codes(): + # Check that valid string location codes all work with an AnchoredOffsetbox + codes = {'upper right': 1, + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'right': 5, + 'center left': 6, + 'center right': 7, + 'lower center': 8, + 'upper center': 9, + 'center': 10, + } + fig, ax = plt.subplots() + da = DrawingArea(100, 100) + for code in codes: + anchored_box = AnchoredOffsetbox(loc=code, child=da) + ax.add_artist(anchored_box) + fig.canvas.draw() + + +def test_expand_with_tight_layout(): + # Check issue reported in #10476, and updated due to #10784 + fig, ax = plt.subplots() + + d1 = [1, 2] + d2 = [2, 1] + ax.plot(d1, label='series 1') + ax.plot(d2, label='series 2') + ax.legend(ncols=2, mode='expand') + + fig.tight_layout() # where the crash used to happen + + +@pytest.mark.parametrize('widths', + ([150], [150, 150, 150], [0.1], [0.1, 0.1])) +@pytest.mark.parametrize('total', (250, 100, 0, -1, None)) +@pytest.mark.parametrize('sep', (250, 1, 0, -1)) +@pytest.mark.parametrize('mode', ("expand", "fixed", "equal")) +def test_get_packed_offsets(widths, total, sep, mode): + # Check a (rather arbitrary) set of parameters due to successive similar + # issue tickets (at least #10476 and #10784) related to corner cases + # triggered inside this function when calling higher-level functions + # (e.g. `Axes.legend`). + # These are just some additional smoke tests. The output is untested. + _get_packed_offsets(widths, total, sep, mode=mode) + + +_Params = namedtuple('_Params', 'wd_list, total, sep, expected') + + +@pytest.mark.parametrize('widths, total, sep, expected', [ + _Params( # total=None + [3, 1, 2], total=None, sep=1, expected=(8, [0, 4, 6])), + _Params( # total larger than required + [3, 1, 2], total=10, sep=1, expected=(10, [0, 4, 6])), + _Params( # total smaller than required + [3, 1, 2], total=5, sep=1, expected=(5, [0, 4, 6])), +]) +def test_get_packed_offsets_fixed(widths, total, sep, expected): + result = _get_packed_offsets(widths, total, sep, mode='fixed') + assert result[0] == expected[0] + assert_allclose(result[1], expected[1]) + + +@pytest.mark.parametrize('widths, total, sep, expected', [ + _Params( # total=None (implicit 1) + [.1, .1, .1], total=None, sep=None, expected=(1, [0, .45, .9])), + _Params( # total larger than sum of widths + [3, 1, 2], total=10, sep=1, expected=(10, [0, 5, 8])), + _Params( # total smaller sum of widths: overlapping boxes + [3, 1, 2], total=5, sep=1, expected=(5, [0, 2.5, 3])), +]) +def test_get_packed_offsets_expand(widths, total, sep, expected): + result = _get_packed_offsets(widths, total, sep, mode='expand') + assert result[0] == expected[0] + assert_allclose(result[1], expected[1]) + + +@pytest.mark.parametrize('widths, total, sep, expected', [ + _Params( # total larger than required + [3, 2, 1], total=6, sep=None, expected=(6, [0, 2, 4])), + _Params( # total smaller sum of widths: overlapping boxes + [3, 2, 1, .5], total=2, sep=None, expected=(2, [0, 0.5, 1, 1.5])), + _Params( # total larger than required + [.5, 1, .2], total=None, sep=1, expected=(6, [0, 2, 4])), + # the case total=None, sep=None is tested separately below +]) +def test_get_packed_offsets_equal(widths, total, sep, expected): + result = _get_packed_offsets(widths, total, sep, mode='equal') + assert result[0] == expected[0] + assert_allclose(result[1], expected[1]) + + +def test_get_packed_offsets_equal_total_none_sep_none(): + with pytest.raises(ValueError): + _get_packed_offsets([1, 1, 1], total=None, sep=None, mode='equal') + + +@pytest.mark.parametrize('child_type', ['draw', 'image', 'text']) +@pytest.mark.parametrize('boxcoords', + ['axes fraction', 'axes pixels', 'axes points', + 'data']) +def test_picking(child_type, boxcoords): + # These all take up approximately the same area. + if child_type == 'draw': + picking_child = DrawingArea(5, 5) + picking_child.add_artist(mpatches.Rectangle((0, 0), 5, 5, linewidth=0)) + elif child_type == 'image': + im = np.ones((5, 5)) + im[2, 2] = 0 + picking_child = OffsetImage(im) + elif child_type == 'text': + picking_child = TextArea('\N{Black Square}', textprops={'fontsize': 5}) + else: + assert False, f'Unknown picking child type {child_type}' + + fig, ax = plt.subplots() + ab = AnnotationBbox(picking_child, (0.5, 0.5), boxcoords=boxcoords) + ab.set_picker(True) + ax.add_artist(ab) + + calls = [] + fig.canvas.mpl_connect('pick_event', lambda event: calls.append(event)) + + # Annotation should be picked by an event occurring at its center. + if boxcoords == 'axes points': + x, y = ax.transAxes.transform_point((0, 0)) + x += 0.5 * fig.dpi / 72 + y += 0.5 * fig.dpi / 72 + elif boxcoords == 'axes pixels': + x, y = ax.transAxes.transform_point((0, 0)) + x += 0.5 + y += 0.5 + else: + x, y = ax.transAxes.transform_point((0.5, 0.5)) + fig.canvas.draw() + calls.clear() + MouseEvent( + "button_press_event", fig.canvas, x, y, MouseButton.LEFT)._process() + assert len(calls) == 1 and calls[0].artist == ab + + # Annotation should *not* be picked by an event at its original center + # point when the limits have changed enough to hide the *xy* point. + ax.set_xlim(-1, 0) + ax.set_ylim(-1, 0) + fig.canvas.draw() + calls.clear() + MouseEvent( + "button_press_event", fig.canvas, x, y, MouseButton.LEFT)._process() + assert len(calls) == 0 + + +@image_comparison(['anchoredtext_align.png'], remove_text=True, style='mpl20') +def test_anchoredtext_horizontal_alignment(): + fig, ax = plt.subplots() + + text0 = AnchoredText("test\ntest long text", loc="center left", + pad=0.2, prop={"ha": "left"}) + ax.add_artist(text0) + text1 = AnchoredText("test\ntest long text", loc="center", + pad=0.2, prop={"ha": "center"}) + ax.add_artist(text1) + text2 = AnchoredText("test\ntest long text", loc="center right", + pad=0.2, prop={"ha": "right"}) + ax.add_artist(text2) + + +@pytest.mark.parametrize("extent_kind", ["window_extent", "tightbbox"]) +def test_annotationbbox_extents(extent_kind): + plt.rcParams.update(plt.rcParamsDefault) + fig, ax = plt.subplots(figsize=(4, 3), dpi=100) + + ax.axis([0, 1, 0, 1]) + + an1 = ax.annotate("Annotation", xy=(.9, .9), xytext=(1.1, 1.1), + arrowprops=dict(arrowstyle="->"), clip_on=False, + va="baseline", ha="left") + + da = DrawingArea(20, 20, 0, 0, clip=True) + p = mpatches.Circle((-10, 30), 32) + da.add_artist(p) + + ab3 = AnnotationBbox(da, [.5, .5], xybox=(-0.2, 0.5), xycoords='data', + boxcoords="axes fraction", box_alignment=(0., .5), + arrowprops=dict(arrowstyle="->")) + ax.add_artist(ab3) + + im = OffsetImage(np.random.rand(10, 10), zoom=3) + im.image.axes = ax + ab6 = AnnotationBbox(im, (0.5, -.3), xybox=(0, 75), + xycoords='axes fraction', + boxcoords="offset points", pad=0.3, + arrowprops=dict(arrowstyle="->")) + ax.add_artist(ab6) + + # Test Annotation + bb1 = getattr(an1, f"get_{extent_kind}")() + + target1 = [332.9, 242.8, 467.0, 298.9] + assert_allclose(bb1.extents, target1, atol=2) + + # Test AnnotationBbox + bb3 = getattr(ab3, f"get_{extent_kind}")() + + target3 = [-17.6, 129.0, 200.7, 167.9] + assert_allclose(bb3.extents, target3, atol=2) + + bb6 = getattr(ab6, f"get_{extent_kind}")() + + target6 = [180.0, -32.0, 230.0, 92.9] + assert_allclose(bb6.extents, target6, atol=2) + + # Test bbox_inches='tight' + buf = io.BytesIO() + fig.savefig(buf, bbox_inches='tight') + buf.seek(0) + shape = plt.imread(buf).shape + targetshape = (350, 504, 4) + assert_allclose(shape, targetshape, atol=2) + + # Simple smoke test for tight_layout, to make sure it does not error out. + fig.canvas.draw() + fig.tight_layout() + fig.canvas.draw() + + +def test_zorder(): + assert OffsetBox(zorder=42).zorder == 42 + + +def test_arrowprops_copied(): + da = DrawingArea(20, 20, 0, 0, clip=True) + arrowprops = {"arrowstyle": "->", "relpos": (.3, .7)} + ab = AnnotationBbox(da, [.5, .5], xybox=(-0.2, 0.5), xycoords='data', + boxcoords="axes fraction", box_alignment=(0., .5), + arrowprops=arrowprops) + assert ab.arrowprops is not ab + assert arrowprops["relpos"] == (.3, .7) + + +@pytest.mark.parametrize("align", ["baseline", "bottom", "top", + "left", "right", "center"]) +def test_packers(align): + # set the DPI to match points to make the math easier below + fig = plt.figure(dpi=72) + renderer = fig.canvas.get_renderer() + + x1, y1 = 10, 30 + x2, y2 = 20, 60 + r1 = DrawingArea(x1, y1) + r2 = DrawingArea(x2, y2) + + # HPacker + hpacker = HPacker(children=[r1, r2], align=align) + hpacker.draw(renderer) + bbox = hpacker.get_bbox(renderer) + px, py = hpacker.get_offset(bbox, renderer) + # width, height, xdescent, ydescent + assert_allclose(bbox.bounds, (0, 0, x1 + x2, max(y1, y2))) + # internal element placement + if align in ("baseline", "left", "bottom"): + y_height = 0 + elif align in ("right", "top"): + y_height = y2 - y1 + elif align == "center": + y_height = (y2 - y1) / 2 + # x-offsets, y-offsets + assert_allclose([child.get_offset() for child in hpacker.get_children()], + [(px, py + y_height), (px + x1, py)]) + + # VPacker + vpacker = VPacker(children=[r1, r2], align=align) + vpacker.draw(renderer) + bbox = vpacker.get_bbox(renderer) + px, py = vpacker.get_offset(bbox, renderer) + # width, height, xdescent, ydescent + assert_allclose(bbox.bounds, (0, -max(y1, y2), max(x1, x2), y1 + y2)) + # internal element placement + if align in ("baseline", "left", "bottom"): + x_height = 0 + elif align in ("right", "top"): + x_height = x2 - x1 + elif align == "center": + x_height = (x2 - x1) / 2 + # x-offsets, y-offsets + assert_allclose([child.get_offset() for child in vpacker.get_children()], + [(px + x_height, py), (px, py - y2)]) + + +def test_paddedbox_default_values(): + # smoke test paddedbox for correct default value + fig, ax = plt.subplots() + at = AnchoredText("foo", 'upper left') + pb = PaddedBox(at, patch_attrs={'facecolor': 'r'}, draw_frame=True) + ax.add_artist(pb) + fig.draw_without_rendering() + + +def test_annotationbbox_properties(): + ab = AnnotationBbox(DrawingArea(20, 20, 0, 0, clip=True), (0.5, 0.5), + xycoords='data') + assert ab.xyann == (0.5, 0.5) # xy if xybox not given + assert ab.anncoords == 'data' # xycoords if boxcoords not given + + ab = AnnotationBbox(DrawingArea(20, 20, 0, 0, clip=True), (0.5, 0.5), + xybox=(-0.2, 0.4), xycoords='data', + boxcoords='axes fraction') + assert ab.xyann == (-0.2, 0.4) # xybox if given + assert ab.anncoords == 'axes fraction' # boxcoords if given + + +def test_textarea_properties(): + ta = TextArea('Foo') + assert ta.get_text() == 'Foo' + assert not ta.get_multilinebaseline() + + ta.set_text('Bar') + ta.set_multilinebaseline(True) + assert ta.get_text() == 'Bar' + assert ta.get_multilinebaseline() + + +@check_figures_equal() +def test_textarea_set_text(fig_test, fig_ref): + ax_ref = fig_ref.add_subplot() + text0 = AnchoredText("Foo", "upper left") + ax_ref.add_artist(text0) + + ax_test = fig_test.add_subplot() + text1 = AnchoredText("Bar", "upper left") + ax_test.add_artist(text1) + text1.txt.set_text("Foo") + + +@image_comparison(['paddedbox.png'], remove_text=True, style='mpl20') +def test_paddedbox(): + fig, ax = plt.subplots() + + ta = TextArea("foo") + pb = PaddedBox(ta, pad=5, patch_attrs={'facecolor': 'r'}, draw_frame=True) + ab = AnchoredOffsetbox('upper left', child=pb) + ax.add_artist(ab) + + ta = TextArea("bar") + pb = PaddedBox(ta, pad=10, patch_attrs={'facecolor': 'b'}) + ab = AnchoredOffsetbox('upper right', child=pb) + ax.add_artist(ab) + + ta = TextArea("foobar") + pb = PaddedBox(ta, pad=15, draw_frame=True) + ab = AnchoredOffsetbox('lower right', child=pb) + ax.add_artist(ab) + + +def test_remove_draggable(): + fig, ax = plt.subplots() + an = ax.annotate("foo", (.5, .5)) + an.draggable(True) + an.remove() + MouseEvent("button_release_event", fig.canvas, 1, 1)._process() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patches.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patches.py new file mode 100644 index 00000000..b1af0abb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patches.py @@ -0,0 +1,933 @@ +""" +Tests specific to the patches module. +""" +import numpy as np +from numpy.testing import assert_almost_equal, assert_array_equal +import pytest + +import matplotlib as mpl +from matplotlib.patches import (Annulus, Ellipse, Patch, Polygon, Rectangle, + FancyArrowPatch, FancyArrow, BoxStyle, Arc) +from matplotlib.testing.decorators import image_comparison, check_figures_equal +from matplotlib.transforms import Bbox +import matplotlib.pyplot as plt +from matplotlib import ( + collections as mcollections, colors as mcolors, patches as mpatches, + path as mpath, transforms as mtransforms, rcParams) + +import sys +on_win = (sys.platform == 'win32') + + +def test_Polygon_close(): + #: GitHub issue #1018 identified a bug in the Polygon handling + #: of the closed attribute; the path was not getting closed + #: when set_xy was used to set the vertices. + + # open set of vertices: + xy = [[0, 0], [0, 1], [1, 1]] + # closed set: + xyclosed = xy + [[0, 0]] + + # start with open path and close it: + p = Polygon(xy, closed=True) + assert p.get_closed() + assert_array_equal(p.get_xy(), xyclosed) + p.set_xy(xy) + assert_array_equal(p.get_xy(), xyclosed) + + # start with closed path and open it: + p = Polygon(xyclosed, closed=False) + assert_array_equal(p.get_xy(), xy) + p.set_xy(xyclosed) + assert_array_equal(p.get_xy(), xy) + + # start with open path and leave it open: + p = Polygon(xy, closed=False) + assert not p.get_closed() + assert_array_equal(p.get_xy(), xy) + p.set_xy(xy) + assert_array_equal(p.get_xy(), xy) + + # start with closed path and leave it closed: + p = Polygon(xyclosed, closed=True) + assert_array_equal(p.get_xy(), xyclosed) + p.set_xy(xyclosed) + assert_array_equal(p.get_xy(), xyclosed) + + +def test_corner_center(): + loc = [10, 20] + width = 1 + height = 2 + + # Rectangle + # No rotation + corners = ((10, 20), (11, 20), (11, 22), (10, 22)) + rect = Rectangle(loc, width, height) + assert_array_equal(rect.get_corners(), corners) + assert_array_equal(rect.get_center(), (10.5, 21)) + + # 90 deg rotation + corners_rot = ((10, 20), (10, 21), (8, 21), (8, 20)) + rect.set_angle(90) + assert_array_equal(rect.get_corners(), corners_rot) + assert_array_equal(rect.get_center(), (9, 20.5)) + + # Rotation not a multiple of 90 deg + theta = 33 + t = mtransforms.Affine2D().rotate_around(*loc, np.deg2rad(theta)) + corners_rot = t.transform(corners) + rect.set_angle(theta) + assert_almost_equal(rect.get_corners(), corners_rot) + + # Ellipse + loc = [loc[0] + width / 2, + loc[1] + height / 2] + ellipse = Ellipse(loc, width, height) + + # No rotation + assert_array_equal(ellipse.get_corners(), corners) + + # 90 deg rotation + corners_rot = ((11.5, 20.5), (11.5, 21.5), (9.5, 21.5), (9.5, 20.5)) + ellipse.set_angle(90) + assert_array_equal(ellipse.get_corners(), corners_rot) + # Rotation shouldn't change ellipse center + assert_array_equal(ellipse.get_center(), loc) + + # Rotation not a multiple of 90 deg + theta = 33 + t = mtransforms.Affine2D().rotate_around(*loc, np.deg2rad(theta)) + corners_rot = t.transform(corners) + ellipse.set_angle(theta) + assert_almost_equal(ellipse.get_corners(), corners_rot) + + +def test_ellipse_vertices(): + # expect 0 for 0 ellipse width, height + ellipse = Ellipse(xy=(0, 0), width=0, height=0, angle=0) + assert_almost_equal( + ellipse.get_vertices(), + [(0.0, 0.0), (0.0, 0.0)], + ) + assert_almost_equal( + ellipse.get_co_vertices(), + [(0.0, 0.0), (0.0, 0.0)], + ) + + ellipse = Ellipse(xy=(0, 0), width=2, height=1, angle=30) + assert_almost_equal( + ellipse.get_vertices(), + [ + ( + ellipse.center[0] + ellipse.width / 4 * np.sqrt(3), + ellipse.center[1] + ellipse.width / 4, + ), + ( + ellipse.center[0] - ellipse.width / 4 * np.sqrt(3), + ellipse.center[1] - ellipse.width / 4, + ), + ], + ) + assert_almost_equal( + ellipse.get_co_vertices(), + [ + ( + ellipse.center[0] - ellipse.height / 4, + ellipse.center[1] + ellipse.height / 4 * np.sqrt(3), + ), + ( + ellipse.center[0] + ellipse.height / 4, + ellipse.center[1] - ellipse.height / 4 * np.sqrt(3), + ), + ], + ) + v1, v2 = np.array(ellipse.get_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + v1, v2 = np.array(ellipse.get_co_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + + ellipse = Ellipse(xy=(2.252, -10.859), width=2.265, height=1.98, angle=68.78) + v1, v2 = np.array(ellipse.get_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + v1, v2 = np.array(ellipse.get_co_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + + +def test_rotate_rect(): + loc = np.asarray([1.0, 2.0]) + width = 2 + height = 3 + angle = 30.0 + + # A rotated rectangle + rect1 = Rectangle(loc, width, height, angle=angle) + + # A non-rotated rectangle + rect2 = Rectangle(loc, width, height) + + # Set up an explicit rotation matrix (in radians) + angle_rad = np.pi * angle / 180.0 + rotation_matrix = np.array([[np.cos(angle_rad), -np.sin(angle_rad)], + [np.sin(angle_rad), np.cos(angle_rad)]]) + + # Translate to origin, rotate each vertex, and then translate back + new_verts = np.inner(rotation_matrix, rect2.get_verts() - loc).T + loc + + # They should be the same + assert_almost_equal(rect1.get_verts(), new_verts) + + +@check_figures_equal(extensions=['png']) +def test_rotate_rect_draw(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + loc = (0, 0) + width, height = (1, 1) + angle = 30 + rect_ref = Rectangle(loc, width, height, angle=angle) + ax_ref.add_patch(rect_ref) + assert rect_ref.get_angle() == angle + + # Check that when the angle is updated after adding to an Axes, that the + # patch is marked stale and redrawn in the correct location + rect_test = Rectangle(loc, width, height) + assert rect_test.get_angle() == 0 + ax_test.add_patch(rect_test) + rect_test.set_angle(angle) + assert rect_test.get_angle() == angle + + +@check_figures_equal(extensions=['png']) +def test_dash_offset_patch_draw(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + loc = (0.1, 0.1) + width, height = (0.8, 0.8) + rect_ref = Rectangle(loc, width, height, linewidth=3, edgecolor='b', + linestyle=(0, [6, 6])) + # fill the line gaps using a linestyle (0, [0, 6, 6, 0]), which is + # equivalent to (6, [6, 6]) but has 0 dash offset + rect_ref2 = Rectangle(loc, width, height, linewidth=3, edgecolor='r', + linestyle=(0, [0, 6, 6, 0])) + assert rect_ref.get_linestyle() == (0, [6, 6]) + assert rect_ref2.get_linestyle() == (0, [0, 6, 6, 0]) + + ax_ref.add_patch(rect_ref) + ax_ref.add_patch(rect_ref2) + + # Check that the dash offset of the rect is the same if we pass it in the + # init method and if we create two rects with appropriate onoff sequence + # of linestyle. + + rect_test = Rectangle(loc, width, height, linewidth=3, edgecolor='b', + linestyle=(0, [6, 6])) + rect_test2 = Rectangle(loc, width, height, linewidth=3, edgecolor='r', + linestyle=(6, [6, 6])) + assert rect_test.get_linestyle() == (0, [6, 6]) + assert rect_test2.get_linestyle() == (6, [6, 6]) + + ax_test.add_patch(rect_test) + ax_test.add_patch(rect_test2) + + +def test_negative_rect(): + # These two rectangles have the same vertices, but starting from a + # different point. (We also drop the last vertex, which is a duplicate.) + pos_vertices = Rectangle((-3, -2), 3, 2).get_verts()[:-1] + neg_vertices = Rectangle((0, 0), -3, -2).get_verts()[:-1] + assert_array_equal(np.roll(neg_vertices, 2, 0), pos_vertices) + + +@image_comparison(['clip_to_bbox']) +def test_clip_to_bbox(): + fig, ax = plt.subplots() + ax.set_xlim([-18, 20]) + ax.set_ylim([-150, 100]) + + path = mpath.Path.unit_regular_star(8).deepcopy() + path.vertices *= [10, 100] + path.vertices -= [5, 25] + + path2 = mpath.Path.unit_circle().deepcopy() + path2.vertices *= [10, 100] + path2.vertices += [10, -25] + + combined = mpath.Path.make_compound_path(path, path2) + + patch = mpatches.PathPatch( + combined, alpha=0.5, facecolor='coral', edgecolor='none') + ax.add_patch(patch) + + bbox = mtransforms.Bbox([[-12, -77.5], [50, -110]]) + result_path = combined.clip_to_bbox(bbox) + result_patch = mpatches.PathPatch( + result_path, alpha=0.5, facecolor='green', lw=4, edgecolor='black') + + ax.add_patch(result_patch) + + +@image_comparison(['patch_alpha_coloring'], remove_text=True) +def test_patch_alpha_coloring(): + """ + Test checks that the patch and collection are rendered with the specified + alpha values in their facecolor and edgecolor. + """ + star = mpath.Path.unit_regular_star(6) + circle = mpath.Path.unit_circle() + # concatenate the star with an internal cutout of the circle + verts = np.concatenate([circle.vertices, star.vertices[::-1]]) + codes = np.concatenate([circle.codes, star.codes]) + cut_star1 = mpath.Path(verts, codes) + cut_star2 = mpath.Path(verts + 1, codes) + + ax = plt.axes() + col = mcollections.PathCollection([cut_star2], + linewidth=5, linestyles='dashdot', + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_collection(col) + + patch = mpatches.PathPatch(cut_star1, + linewidth=5, linestyle='dashdot', + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_patch(patch) + + ax.set_xlim(-1, 2) + ax.set_ylim(-1, 2) + + +@image_comparison(['patch_alpha_override'], remove_text=True) +def test_patch_alpha_override(): + #: Test checks that specifying an alpha attribute for a patch or + #: collection will override any alpha component of the facecolor + #: or edgecolor. + star = mpath.Path.unit_regular_star(6) + circle = mpath.Path.unit_circle() + # concatenate the star with an internal cutout of the circle + verts = np.concatenate([circle.vertices, star.vertices[::-1]]) + codes = np.concatenate([circle.codes, star.codes]) + cut_star1 = mpath.Path(verts, codes) + cut_star2 = mpath.Path(verts + 1, codes) + + ax = plt.axes() + col = mcollections.PathCollection([cut_star2], + linewidth=5, linestyles='dashdot', + alpha=0.25, + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_collection(col) + + patch = mpatches.PathPatch(cut_star1, + linewidth=5, linestyle='dashdot', + alpha=0.25, + facecolor=(1, 0, 0, 0.5), + edgecolor=(0, 0, 1, 0.75)) + ax.add_patch(patch) + + ax.set_xlim(-1, 2) + ax.set_ylim(-1, 2) + + +@mpl.style.context('default') +def test_patch_color_none(): + # Make sure the alpha kwarg does not override 'none' facecolor. + # Addresses issue #7478. + c = plt.Circle((0, 0), 1, facecolor='none', alpha=1) + assert c.get_facecolor()[0] == 0 + + +@image_comparison(['patch_custom_linestyle'], remove_text=True) +def test_patch_custom_linestyle(): + #: A test to check that patches and collections accept custom dash + #: patterns as linestyle and that they display correctly. + star = mpath.Path.unit_regular_star(6) + circle = mpath.Path.unit_circle() + # concatenate the star with an internal cutout of the circle + verts = np.concatenate([circle.vertices, star.vertices[::-1]]) + codes = np.concatenate([circle.codes, star.codes]) + cut_star1 = mpath.Path(verts, codes) + cut_star2 = mpath.Path(verts + 1, codes) + + ax = plt.axes() + col = mcollections.PathCollection( + [cut_star2], + linewidth=5, linestyles=[(0, (5, 7, 10, 7))], + facecolor=(1, 0, 0), edgecolor=(0, 0, 1)) + ax.add_collection(col) + + patch = mpatches.PathPatch( + cut_star1, + linewidth=5, linestyle=(0, (5, 7, 10, 7)), + facecolor=(1, 0, 0), edgecolor=(0, 0, 1)) + ax.add_patch(patch) + + ax.set_xlim(-1, 2) + ax.set_ylim(-1, 2) + + +def test_patch_linestyle_accents(): + #: Test if linestyle can also be specified with short mnemonics like "--" + #: c.f. GitHub issue #2136 + star = mpath.Path.unit_regular_star(6) + circle = mpath.Path.unit_circle() + # concatenate the star with an internal cutout of the circle + verts = np.concatenate([circle.vertices, star.vertices[::-1]]) + codes = np.concatenate([circle.codes, star.codes]) + + linestyles = ["-", "--", "-.", ":", + "solid", "dashed", "dashdot", "dotted"] + + fig, ax = plt.subplots() + for i, ls in enumerate(linestyles): + star = mpath.Path(verts + i, codes) + patch = mpatches.PathPatch(star, + linewidth=3, linestyle=ls, + facecolor=(1, 0, 0), + edgecolor=(0, 0, 1)) + ax.add_patch(patch) + + ax.set_xlim([-1, i + 1]) + ax.set_ylim([-1, i + 1]) + fig.canvas.draw() + + +@check_figures_equal(extensions=['png']) +def test_patch_linestyle_none(fig_test, fig_ref): + circle = mpath.Path.unit_circle() + + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + for i, ls in enumerate(['none', 'None', ' ', '']): + path = mpath.Path(circle.vertices + i, circle.codes) + patch = mpatches.PathPatch(path, + linewidth=3, linestyle=ls, + facecolor=(1, 0, 0), + edgecolor=(0, 0, 1)) + ax_test.add_patch(patch) + + patch = mpatches.PathPatch(path, + linewidth=3, linestyle='-', + facecolor=(1, 0, 0), + edgecolor='none') + ax_ref.add_patch(patch) + + ax_test.set_xlim([-1, i + 1]) + ax_test.set_ylim([-1, i + 1]) + ax_ref.set_xlim([-1, i + 1]) + ax_ref.set_ylim([-1, i + 1]) + + +def test_wedge_movement(): + param_dict = {'center': ((0, 0), (1, 1), 'set_center'), + 'r': (5, 8, 'set_radius'), + 'width': (2, 3, 'set_width'), + 'theta1': (0, 30, 'set_theta1'), + 'theta2': (45, 50, 'set_theta2')} + + init_args = {k: v[0] for k, v in param_dict.items()} + + w = mpatches.Wedge(**init_args) + for attr, (old_v, new_v, func) in param_dict.items(): + assert getattr(w, attr) == old_v + getattr(w, func)(new_v) + assert getattr(w, attr) == new_v + + +# png needs tol>=0.06, pdf tol>=1.617 +@image_comparison(['wedge_range'], remove_text=True, tol=1.65 if on_win else 0) +def test_wedge_range(): + ax = plt.axes() + + t1 = 2.313869244286224 + + args = [[52.31386924, 232.31386924], + [52.313869244286224, 232.31386924428622], + [t1, t1 + 180.0], + [0, 360], + [90, 90 + 360], + [-180, 180], + [0, 380], + [45, 46], + [46, 45]] + + for i, (theta1, theta2) in enumerate(args): + x = i % 3 + y = i // 3 + + wedge = mpatches.Wedge((x * 3, y * 3), 1, theta1, theta2, + facecolor='none', edgecolor='k', lw=3) + + ax.add_artist(wedge) + + ax.set_xlim(-2, 8) + ax.set_ylim(-2, 9) + + +def test_patch_str(): + """ + Check that patches have nice and working `str` representation. + + Note that the logic is that `__str__` is defined such that: + str(eval(str(p))) == str(p) + """ + p = mpatches.Circle(xy=(1, 2), radius=3) + assert str(p) == 'Circle(xy=(1, 2), radius=3)' + + p = mpatches.Ellipse(xy=(1, 2), width=3, height=4, angle=5) + assert str(p) == 'Ellipse(xy=(1, 2), width=3, height=4, angle=5)' + + p = mpatches.Rectangle(xy=(1, 2), width=3, height=4, angle=5) + assert str(p) == 'Rectangle(xy=(1, 2), width=3, height=4, angle=5)' + + p = mpatches.Wedge(center=(1, 2), r=3, theta1=4, theta2=5, width=6) + assert str(p) == 'Wedge(center=(1, 2), r=3, theta1=4, theta2=5, width=6)' + + p = mpatches.Arc(xy=(1, 2), width=3, height=4, angle=5, theta1=6, theta2=7) + expected = 'Arc(xy=(1, 2), width=3, height=4, angle=5, theta1=6, theta2=7)' + assert str(p) == expected + + p = mpatches.Annulus(xy=(1, 2), r=(3, 4), width=1, angle=2) + expected = "Annulus(xy=(1, 2), r=(3, 4), width=1, angle=2)" + assert str(p) == expected + + p = mpatches.RegularPolygon((1, 2), 20, radius=5) + assert str(p) == "RegularPolygon((1, 2), 20, radius=5, orientation=0)" + + p = mpatches.CirclePolygon(xy=(1, 2), radius=5, resolution=20) + assert str(p) == "CirclePolygon((1, 2), radius=5, resolution=20)" + + p = mpatches.FancyBboxPatch((1, 2), width=3, height=4) + assert str(p) == "FancyBboxPatch((1, 2), width=3, height=4)" + + # Further nice __str__ which cannot be `eval`uated: + path = mpath.Path([(1, 2), (2, 2), (1, 2)], closed=True) + p = mpatches.PathPatch(path) + assert str(p) == "PathPatch3((1, 2) ...)" + + p = mpatches.Polygon(np.empty((0, 2))) + assert str(p) == "Polygon0()" + + data = [[1, 2], [2, 2], [1, 2]] + p = mpatches.Polygon(data) + assert str(p) == "Polygon3((1, 2) ...)" + + p = mpatches.FancyArrowPatch(path=path) + assert str(p)[:27] == "FancyArrowPatch(Path(array(" + + p = mpatches.FancyArrowPatch((1, 2), (3, 4)) + assert str(p) == "FancyArrowPatch((1, 2)->(3, 4))" + + p = mpatches.ConnectionPatch((1, 2), (3, 4), 'data') + assert str(p) == "ConnectionPatch((1, 2), (3, 4))" + + s = mpatches.Shadow(p, 1, 1) + assert str(s) == "Shadow(ConnectionPatch((1, 2), (3, 4)))" + + # Not testing Arrow, FancyArrow here + # because they seem to exist only for historical reasons. + + +@image_comparison(['multi_color_hatch'], remove_text=True, style='default') +def test_multi_color_hatch(): + fig, ax = plt.subplots() + + rects = ax.bar(range(5), range(1, 6)) + for i, rect in enumerate(rects): + rect.set_facecolor('none') + rect.set_edgecolor(f'C{i}') + rect.set_hatch('/') + + ax.autoscale_view() + ax.autoscale(False) + + for i in range(5): + with mpl.style.context({'hatch.color': f'C{i}'}): + r = Rectangle((i - .8 / 2, 5), .8, 1, hatch='//', fc='none') + ax.add_patch(r) + + +@image_comparison(['units_rectangle.png']) +def test_units_rectangle(): + import matplotlib.testing.jpl_units as U + U.register() + + p = mpatches.Rectangle((5*U.km, 6*U.km), 1*U.km, 2*U.km) + + fig, ax = plt.subplots() + ax.add_patch(p) + ax.set_xlim([4*U.km, 7*U.km]) + ax.set_ylim([5*U.km, 9*U.km]) + + +@image_comparison(['connection_patch.png'], style='mpl20', remove_text=True) +def test_connection_patch(): + fig, (ax1, ax2) = plt.subplots(1, 2) + + con = mpatches.ConnectionPatch(xyA=(0.1, 0.1), xyB=(0.9, 0.9), + coordsA='data', coordsB='data', + axesA=ax2, axesB=ax1, + arrowstyle="->") + ax2.add_artist(con) + + xyA = (0.6, 1.0) # in axes coordinates + xyB = (0.0, 0.2) # x in axes coordinates, y in data coordinates + coordsA = "axes fraction" + coordsB = ax2.get_yaxis_transform() + con = mpatches.ConnectionPatch(xyA=xyA, xyB=xyB, coordsA=coordsA, + coordsB=coordsB, arrowstyle="-") + ax2.add_artist(con) + + +@check_figures_equal(extensions=["png"]) +def test_connection_patch_fig(fig_test, fig_ref): + # Test that connection patch can be added as figure artist, and that figure + # pixels count negative values from the top right corner (this API may be + # changed in the future). + ax1, ax2 = fig_test.subplots(1, 2) + con = mpatches.ConnectionPatch( + xyA=(.3, .2), coordsA="data", axesA=ax1, + xyB=(-30, -20), coordsB="figure pixels", + arrowstyle="->", shrinkB=5) + fig_test.add_artist(con) + + ax1, ax2 = fig_ref.subplots(1, 2) + bb = fig_ref.bbox + # Necessary so that pixel counts match on both sides. + plt.rcParams["savefig.dpi"] = plt.rcParams["figure.dpi"] + con = mpatches.ConnectionPatch( + xyA=(.3, .2), coordsA="data", axesA=ax1, + xyB=(bb.width - 30, bb.height - 20), coordsB="figure pixels", + arrowstyle="->", shrinkB=5) + fig_ref.add_artist(con) + + +def test_datetime_rectangle(): + # Check that creating a rectangle with timedeltas doesn't fail + from datetime import datetime, timedelta + + start = datetime(2017, 1, 1, 0, 0, 0) + delta = timedelta(seconds=16) + patch = mpatches.Rectangle((start, 0), delta, 1) + + fig, ax = plt.subplots() + ax.add_patch(patch) + + +def test_datetime_datetime_fails(): + from datetime import datetime + + start = datetime(2017, 1, 1, 0, 0, 0) + dt_delta = datetime(1970, 1, 5) # Will be 5 days if units are done wrong. + + with pytest.raises(TypeError): + mpatches.Rectangle((start, 0), dt_delta, 1) + + with pytest.raises(TypeError): + mpatches.Rectangle((0, start), 1, dt_delta) + + +def test_contains_point(): + ell = mpatches.Ellipse((0.5, 0.5), 0.5, 1.0) + points = [(0.0, 0.5), (0.2, 0.5), (0.25, 0.5), (0.5, 0.5)] + path = ell.get_path() + transform = ell.get_transform() + radius = ell._process_radius(None) + expected = np.array([path.contains_point(point, + transform, + radius) for point in points]) + result = np.array([ell.contains_point(point) for point in points]) + assert np.all(result == expected) + + +def test_contains_points(): + ell = mpatches.Ellipse((0.5, 0.5), 0.5, 1.0) + points = [(0.0, 0.5), (0.2, 0.5), (0.25, 0.5), (0.5, 0.5)] + path = ell.get_path() + transform = ell.get_transform() + radius = ell._process_radius(None) + expected = path.contains_points(points, transform, radius) + result = ell.contains_points(points) + assert np.all(result == expected) + + +# Currently fails with pdf/svg, probably because some parts assume a dpi of 72. +@check_figures_equal(extensions=["png"]) +def test_shadow(fig_test, fig_ref): + xy = np.array([.2, .3]) + dxy = np.array([.1, .2]) + # We need to work around the nonsensical (dpi-dependent) interpretation of + # offsets by the Shadow class... + plt.rcParams["savefig.dpi"] = "figure" + # Test image. + a1 = fig_test.subplots() + rect = mpatches.Rectangle(xy=xy, width=.5, height=.5) + shadow = mpatches.Shadow(rect, ox=dxy[0], oy=dxy[1]) + a1.add_patch(rect) + a1.add_patch(shadow) + # Reference image. + a2 = fig_ref.subplots() + rect = mpatches.Rectangle(xy=xy, width=.5, height=.5) + shadow = mpatches.Rectangle( + xy=xy + fig_ref.dpi / 72 * dxy, width=.5, height=.5, + fc=np.asarray(mcolors.to_rgb(rect.get_facecolor())) * .3, + ec=np.asarray(mcolors.to_rgb(rect.get_facecolor())) * .3, + alpha=.5) + a2.add_patch(shadow) + a2.add_patch(rect) + + +def test_fancyarrow_units(): + from datetime import datetime + # Smoke test to check that FancyArrowPatch works with units + dtime = datetime(2000, 1, 1) + fig, ax = plt.subplots() + arrow = FancyArrowPatch((0, dtime), (0.01, dtime)) + + +def test_fancyarrow_setdata(): + fig, ax = plt.subplots() + arrow = ax.arrow(0, 0, 10, 10, head_length=5, head_width=1, width=.5) + expected1 = np.array( + [[13.54, 13.54], + [10.35, 9.65], + [10.18, 9.82], + [0.18, -0.18], + [-0.18, 0.18], + [9.82, 10.18], + [9.65, 10.35], + [13.54, 13.54]] + ) + assert np.allclose(expected1, np.round(arrow.verts, 2)) + + expected2 = np.array( + [[16.71, 16.71], + [16.71, 15.29], + [16.71, 15.29], + [1.71, 0.29], + [0.29, 1.71], + [15.29, 16.71], + [15.29, 16.71], + [16.71, 16.71]] + ) + arrow.set_data( + x=1, y=1, dx=15, dy=15, width=2, head_width=2, head_length=1 + ) + assert np.allclose(expected2, np.round(arrow.verts, 2)) + + +@image_comparison(["large_arc.svg"], style="mpl20") +def test_large_arc(): + fig, (ax1, ax2) = plt.subplots(1, 2) + x = 210 + y = -2115 + diameter = 4261 + for ax in [ax1, ax2]: + a = Arc((x, y), diameter, diameter, lw=2, color='k') + ax.add_patch(a) + ax.set_axis_off() + ax.set_aspect('equal') + # force the high accuracy case + ax1.set_xlim(7, 8) + ax1.set_ylim(5, 6) + + # force the low accuracy case + ax2.set_xlim(-25000, 18000) + ax2.set_ylim(-20000, 6600) + + +@image_comparison(["all_quadrants_arcs.svg"], style="mpl20") +def test_rotated_arcs(): + fig, ax_arr = plt.subplots(2, 2, squeeze=False, figsize=(10, 10)) + + scale = 10_000_000 + diag_centers = ((-1, -1), (-1, 1), (1, 1), (1, -1)) + on_axis_centers = ((0, 1), (1, 0), (0, -1), (-1, 0)) + skews = ((2, 2), (2, 1/10), (2, 1/100), (2, 1/1000)) + + for ax, (sx, sy) in zip(ax_arr.ravel(), skews): + k = 0 + for prescale, centers in zip((1 - .0001, (1 - .0001) / np.sqrt(2)), + (on_axis_centers, diag_centers)): + for j, (x_sign, y_sign) in enumerate(centers, start=k): + a = Arc( + (x_sign * scale * prescale, + y_sign * scale * prescale), + scale * sx, + scale * sy, + lw=4, + color=f"C{j}", + zorder=1 + j, + angle=np.rad2deg(np.arctan2(y_sign, x_sign)) % 360, + label=f'big {j}', + gid=f'big {j}' + ) + ax.add_patch(a) + + k = j+1 + ax.set_xlim(-scale / 4000, scale / 4000) + ax.set_ylim(-scale / 4000, scale / 4000) + ax.axhline(0, color="k") + ax.axvline(0, color="k") + ax.set_axis_off() + ax.set_aspect("equal") + + +def test_fancyarrow_shape_error(): + with pytest.raises(ValueError, match="Got unknown shape: 'foo'"): + FancyArrow(0, 0, 0.2, 0.2, shape='foo') + + +@pytest.mark.parametrize('fmt, match', ( + ("foo", "Unknown style: 'foo'"), + ("Round,foo", "Incorrect style argument: 'Round,foo'"), +)) +def test_boxstyle_errors(fmt, match): + with pytest.raises(ValueError, match=match): + BoxStyle(fmt) + + +@image_comparison(baseline_images=['annulus'], extensions=['png']) +def test_annulus(): + + fig, ax = plt.subplots() + cir = Annulus((0.5, 0.5), 0.2, 0.05, fc='g') # circular annulus + ell = Annulus((0.5, 0.5), (0.5, 0.3), 0.1, 45, # elliptical + fc='m', ec='b', alpha=0.5, hatch='xxx') + ax.add_patch(cir) + ax.add_patch(ell) + ax.set_aspect('equal') + + +@image_comparison(baseline_images=['annulus'], extensions=['png']) +def test_annulus_setters(): + + fig, ax = plt.subplots() + cir = Annulus((0., 0.), 0.2, 0.01, fc='g') # circular annulus + ell = Annulus((0., 0.), (1, 2), 0.1, 0, # elliptical + fc='m', ec='b', alpha=0.5, hatch='xxx') + ax.add_patch(cir) + ax.add_patch(ell) + ax.set_aspect('equal') + + cir.center = (0.5, 0.5) + cir.radii = 0.2 + cir.width = 0.05 + + ell.center = (0.5, 0.5) + ell.radii = (0.5, 0.3) + ell.width = 0.1 + ell.angle = 45 + + +@image_comparison(baseline_images=['annulus'], extensions=['png']) +def test_annulus_setters2(): + + fig, ax = plt.subplots() + cir = Annulus((0., 0.), 0.2, 0.01, fc='g') # circular annulus + ell = Annulus((0., 0.), (1, 2), 0.1, 0, # elliptical + fc='m', ec='b', alpha=0.5, hatch='xxx') + ax.add_patch(cir) + ax.add_patch(ell) + ax.set_aspect('equal') + + cir.center = (0.5, 0.5) + cir.set_semimajor(0.2) + cir.set_semiminor(0.2) + assert cir.radii == (0.2, 0.2) + cir.width = 0.05 + + ell.center = (0.5, 0.5) + ell.set_semimajor(0.5) + ell.set_semiminor(0.3) + assert ell.radii == (0.5, 0.3) + ell.width = 0.1 + ell.angle = 45 + + +def test_degenerate_polygon(): + point = [0, 0] + correct_extents = Bbox([point, point]).extents + assert np.all(Polygon([point]).get_extents().extents == correct_extents) + + +@pytest.mark.parametrize('kwarg', ('edgecolor', 'facecolor')) +def test_color_override_warning(kwarg): + with pytest.warns(UserWarning, + match="Setting the 'color' property will override " + "the edgecolor or facecolor properties."): + Patch(color='black', **{kwarg: 'black'}) + + +def test_empty_verts(): + poly = Polygon(np.zeros((0, 2))) + assert poly.get_verts() == [] + + +def test_default_antialiased(): + patch = Patch() + + patch.set_antialiased(not rcParams['patch.antialiased']) + assert patch.get_antialiased() == (not rcParams['patch.antialiased']) + # Check that None resets the state + patch.set_antialiased(None) + assert patch.get_antialiased() == rcParams['patch.antialiased'] + + +def test_default_linestyle(): + patch = Patch() + patch.set_linestyle('--') + patch.set_linestyle(None) + assert patch.get_linestyle() == 'solid' + + +def test_default_capstyle(): + patch = Patch() + assert patch.get_capstyle() == 'butt' + + +def test_default_joinstyle(): + patch = Patch() + assert patch.get_joinstyle() == 'miter' + + +@image_comparison(["autoscale_arc"], extensions=['png', 'svg'], + style="mpl20", remove_text=True) +def test_autoscale_arc(): + fig, axs = plt.subplots(1, 3, figsize=(4, 1)) + arc_lists = ( + [Arc((0, 0), 1, 1, theta1=0, theta2=90)], + [Arc((0.5, 0.5), 1.5, 0.5, theta1=10, theta2=20)], + [Arc((0.5, 0.5), 1.5, 0.5, theta1=10, theta2=20), + Arc((0.5, 0.5), 2.5, 0.5, theta1=110, theta2=120), + Arc((0.5, 0.5), 3.5, 0.5, theta1=210, theta2=220), + Arc((0.5, 0.5), 4.5, 0.5, theta1=310, theta2=320)]) + + for ax, arcs in zip(axs, arc_lists): + for arc in arcs: + ax.add_patch(arc) + ax.autoscale() + + +@check_figures_equal(extensions=["png", 'svg', 'pdf', 'eps']) +def test_arc_in_collection(fig_test, fig_ref): + arc1 = Arc([.5, .5], .5, 1, theta1=0, theta2=60, angle=20) + arc2 = Arc([.5, .5], .5, 1, theta1=0, theta2=60, angle=20) + col = mcollections.PatchCollection(patches=[arc2], facecolors='none', + edgecolors='k') + fig_ref.subplots().add_patch(arc1) + fig_test.subplots().add_collection(col) + + +@check_figures_equal(extensions=["png", 'svg', 'pdf', 'eps']) +def test_modifying_arc(fig_test, fig_ref): + arc1 = Arc([.5, .5], .5, 1, theta1=0, theta2=60, angle=20) + arc2 = Arc([.5, .5], 1.5, 1, theta1=0, theta2=60, angle=10) + fig_ref.subplots().add_patch(arc1) + fig_test.subplots().add_patch(arc2) + arc2.set_width(.5) + arc2.set_angle(20) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_path.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_path.py new file mode 100644 index 00000000..0a1d6c6b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_path.py @@ -0,0 +1,541 @@ +import re + +import numpy as np + +from numpy.testing import assert_array_equal +import pytest + +from matplotlib import patches +from matplotlib.path import Path +from matplotlib.patches import Polygon +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +from matplotlib import transforms +from matplotlib.backend_bases import MouseEvent + + +def test_empty_closed_path(): + path = Path(np.zeros((0, 2)), closed=True) + assert path.vertices.shape == (0, 2) + assert path.codes is None + assert_array_equal(path.get_extents().extents, + transforms.Bbox.null().extents) + + +def test_readonly_path(): + path = Path.unit_circle() + + def modify_vertices(): + path.vertices = path.vertices * 2.0 + + with pytest.raises(AttributeError): + modify_vertices() + + +def test_path_exceptions(): + bad_verts1 = np.arange(12).reshape(4, 3) + with pytest.raises(ValueError, + match=re.escape(f'has shape {bad_verts1.shape}')): + Path(bad_verts1) + + bad_verts2 = np.arange(12).reshape(2, 3, 2) + with pytest.raises(ValueError, + match=re.escape(f'has shape {bad_verts2.shape}')): + Path(bad_verts2) + + good_verts = np.arange(12).reshape(6, 2) + bad_codes = np.arange(2) + msg = re.escape(f"Your vertices have shape {good_verts.shape} " + f"but your codes have shape {bad_codes.shape}") + with pytest.raises(ValueError, match=msg): + Path(good_verts, bad_codes) + + +def test_point_in_path(): + # Test #1787 + path = Path._create_closed([(0, 0), (0, 1), (1, 1), (1, 0)]) + points = [(0.5, 0.5), (1.5, 0.5)] + ret = path.contains_points(points) + assert ret.dtype == 'bool' + np.testing.assert_equal(ret, [True, False]) + + +@pytest.mark.parametrize( + "other_path, inside, inverted_inside", + [(Path([(0.25, 0.25), (0.25, 0.75), (0.75, 0.75), (0.75, 0.25), (0.25, 0.25)], + closed=True), True, False), + (Path([(-0.25, -0.25), (-0.25, 1.75), (1.75, 1.75), (1.75, -0.25), (-0.25, -0.25)], + closed=True), False, True), + (Path([(-0.25, -0.25), (-0.25, 1.75), (0.5, 0.5), + (1.75, 1.75), (1.75, -0.25), (-0.25, -0.25)], + closed=True), False, False), + (Path([(0.25, 0.25), (0.25, 1.25), (1.25, 1.25), (1.25, 0.25), (0.25, 0.25)], + closed=True), False, False), + (Path([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)], closed=True), False, False), + (Path([(2, 2), (2, 3), (3, 3), (3, 2), (2, 2)], closed=True), False, False)]) +def test_contains_path(other_path, inside, inverted_inside): + path = Path([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)], closed=True) + assert path.contains_path(other_path) is inside + assert other_path.contains_path(path) is inverted_inside + + +def test_contains_points_negative_radius(): + path = Path.unit_circle() + + points = [(0.0, 0.0), (1.25, 0.0), (0.9, 0.9)] + result = path.contains_points(points, radius=-0.5) + np.testing.assert_equal(result, [True, False, False]) + + +_test_paths = [ + # interior extrema determine extents and degenerate derivative + Path([[0, 0], [1, 0], [1, 1], [0, 1]], + [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]), + # a quadratic curve + Path([[0, 0], [0, 1], [1, 0]], [Path.MOVETO, Path.CURVE3, Path.CURVE3]), + # a linear curve, degenerate vertically + Path([[0, 1], [1, 1]], [Path.MOVETO, Path.LINETO]), + # a point + Path([[1, 2]], [Path.MOVETO]), +] + + +_test_path_extents = [(0., 0., 0.75, 1.), (0., 0., 1., 0.5), (0., 1., 1., 1.), + (1., 2., 1., 2.)] + + +@pytest.mark.parametrize('path, extents', zip(_test_paths, _test_path_extents)) +def test_exact_extents(path, extents): + # notice that if we just looked at the control points to get the bounding + # box of each curve, we would get the wrong answers. For example, for + # hard_curve = Path([[0, 0], [1, 0], [1, 1], [0, 1]], + # [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]) + # we would get that the extents area (0, 0, 1, 1). This code takes into + # account the curved part of the path, which does not typically extend all + # the way out to the control points. + # Note that counterintuitively, path.get_extents() returns a Bbox, so we + # have to get that Bbox's `.extents`. + assert np.all(path.get_extents().extents == extents) + + +@pytest.mark.parametrize('ignored_code', [Path.CLOSEPOLY, Path.STOP]) +def test_extents_with_ignored_codes(ignored_code): + # Check that STOP and CLOSEPOLY points are ignored when calculating extents + # of a path with only straight lines + path = Path([[0, 0], + [1, 1], + [2, 2]], [Path.MOVETO, Path.MOVETO, ignored_code]) + assert np.all(path.get_extents().extents == (0., 0., 1., 1.)) + + +def test_point_in_path_nan(): + box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) + p = Path(box) + test = np.array([[np.nan, 0.5]]) + contains = p.contains_points(test) + assert len(contains) == 1 + assert not contains[0] + + +def test_nonlinear_containment(): + fig, ax = plt.subplots() + ax.set(xscale="log", ylim=(0, 1)) + polygon = ax.axvspan(1, 10) + assert polygon.get_path().contains_point( + ax.transData.transform((5, .5)), ax.transData) + assert not polygon.get_path().contains_point( + ax.transData.transform((.5, .5)), ax.transData) + assert not polygon.get_path().contains_point( + ax.transData.transform((50, .5)), ax.transData) + + +@image_comparison(['arrow_contains_point.png'], + remove_text=True, style='mpl20') +def test_arrow_contains_point(): + # fix bug (#8384) + fig, ax = plt.subplots() + ax.set_xlim((0, 2)) + ax.set_ylim((0, 2)) + + # create an arrow with Curve style + arrow = patches.FancyArrowPatch((0.5, 0.25), (1.5, 0.75), + arrowstyle='->', + mutation_scale=40) + ax.add_patch(arrow) + # create an arrow with Bracket style + arrow1 = patches.FancyArrowPatch((0.5, 1), (1.5, 1.25), + arrowstyle=']-[', + mutation_scale=40) + ax.add_patch(arrow1) + # create an arrow with other arrow style + arrow2 = patches.FancyArrowPatch((0.5, 1.5), (1.5, 1.75), + arrowstyle='fancy', + fill=False, + mutation_scale=40) + ax.add_patch(arrow2) + patches_list = [arrow, arrow1, arrow2] + + # generate some points + X, Y = np.meshgrid(np.arange(0, 2, 0.1), + np.arange(0, 2, 0.1)) + for k, (x, y) in enumerate(zip(X.ravel(), Y.ravel())): + xdisp, ydisp = ax.transData.transform([x, y]) + event = MouseEvent('button_press_event', fig.canvas, xdisp, ydisp) + for m, patch in enumerate(patches_list): + # set the points to red only if the arrow contains the point + inside, res = patch.contains(event) + if inside: + ax.scatter(x, y, s=5, c="r") + + +@image_comparison(['path_clipping.svg'], remove_text=True) +def test_path_clipping(): + fig = plt.figure(figsize=(6.0, 6.2)) + + for i, xy in enumerate([ + [(200, 200), (200, 350), (400, 350), (400, 200)], + [(200, 200), (200, 350), (400, 350), (400, 100)], + [(200, 100), (200, 350), (400, 350), (400, 100)], + [(200, 100), (200, 415), (400, 350), (400, 100)], + [(200, 100), (200, 415), (400, 415), (400, 100)], + [(200, 415), (400, 415), (400, 100), (200, 100)], + [(400, 415), (400, 100), (200, 100), (200, 415)]]): + ax = fig.add_subplot(4, 2, i+1) + bbox = [0, 140, 640, 260] + ax.set_xlim(bbox[0], bbox[0] + bbox[2]) + ax.set_ylim(bbox[1], bbox[1] + bbox[3]) + ax.add_patch(Polygon( + xy, facecolor='none', edgecolor='red', closed=True)) + + +@image_comparison(['semi_log_with_zero.png'], style='mpl20') +def test_log_transform_with_zero(): + x = np.arange(-10, 10) + y = (1.0 - 1.0/(x**2+1))**20 + + fig, ax = plt.subplots() + ax.semilogy(x, y, "-o", lw=15, markeredgecolor='k') + ax.set_ylim(1e-7, 1) + ax.grid(True) + + +def test_make_compound_path_empty(): + # We should be able to make a compound path with no arguments. + # This makes it easier to write generic path based code. + empty = Path.make_compound_path() + assert empty.vertices.shape == (0, 2) + r2 = Path.make_compound_path(empty, empty) + assert r2.vertices.shape == (0, 2) + assert r2.codes.shape == (0,) + r3 = Path.make_compound_path(Path([(0, 0)]), empty) + assert r3.vertices.shape == (1, 2) + assert r3.codes.shape == (1,) + + +def test_make_compound_path_stops(): + zero = [0, 0] + paths = 3*[Path([zero, zero], [Path.MOVETO, Path.STOP])] + compound_path = Path.make_compound_path(*paths) + # the choice to not preserve the terminal STOP is arbitrary, but + # documented, so we test that it is in fact respected here + assert np.sum(compound_path.codes == Path.STOP) == 0 + + +@image_comparison(['xkcd.png'], remove_text=True) +def test_xkcd(): + np.random.seed(0) + + x = np.linspace(0, 2 * np.pi, 100) + y = np.sin(x) + + with plt.xkcd(): + fig, ax = plt.subplots() + ax.plot(x, y) + + +@image_comparison(['xkcd_marker.png'], remove_text=True) +def test_xkcd_marker(): + np.random.seed(0) + + x = np.linspace(0, 5, 8) + y1 = x + y2 = 5 - x + y3 = 2.5 * np.ones(8) + + with plt.xkcd(): + fig, ax = plt.subplots() + ax.plot(x, y1, '+', ms=10) + ax.plot(x, y2, 'o', ms=10) + ax.plot(x, y3, '^', ms=10) + + +@image_comparison(['marker_paths.pdf'], remove_text=True) +def test_marker_paths_pdf(): + N = 7 + + plt.errorbar(np.arange(N), + np.ones(N) + 4, + np.ones(N)) + plt.xlim(-1, N) + plt.ylim(-1, 7) + + +@image_comparison(['nan_path'], style='default', remove_text=True, + extensions=['pdf', 'svg', 'eps', 'png']) +def test_nan_isolated_points(): + + y0 = [0, np.nan, 2, np.nan, 4, 5, 6] + y1 = [np.nan, 7, np.nan, 9, 10, np.nan, 12] + + fig, ax = plt.subplots() + + ax.plot(y0, '-o') + ax.plot(y1, '-o') + + +def test_path_no_doubled_point_in_to_polygon(): + hand = np.array( + [[1.64516129, 1.16145833], + [1.64516129, 1.59375], + [1.35080645, 1.921875], + [1.375, 2.18229167], + [1.68548387, 1.9375], + [1.60887097, 2.55208333], + [1.68548387, 2.69791667], + [1.76209677, 2.56770833], + [1.83064516, 1.97395833], + [1.89516129, 2.75], + [1.9516129, 2.84895833], + [2.01209677, 2.76041667], + [1.99193548, 1.99479167], + [2.11290323, 2.63020833], + [2.2016129, 2.734375], + [2.25403226, 2.60416667], + [2.14919355, 1.953125], + [2.30645161, 2.36979167], + [2.39112903, 2.36979167], + [2.41532258, 2.1875], + [2.1733871, 1.703125], + [2.07782258, 1.16666667]]) + + (r0, c0, r1, c1) = (1.0, 1.5, 2.1, 2.5) + + poly = Path(np.vstack((hand[:, 1], hand[:, 0])).T, closed=True) + clip_rect = transforms.Bbox([[r0, c0], [r1, c1]]) + poly_clipped = poly.clip_to_bbox(clip_rect).to_polygons()[0] + + assert np.all(poly_clipped[-2] != poly_clipped[-1]) + assert np.all(poly_clipped[-1] == poly_clipped[0]) + + +def test_path_to_polygons(): + data = [[10, 10], [20, 20]] + p = Path(data) + + assert_array_equal(p.to_polygons(width=40, height=40), []) + assert_array_equal(p.to_polygons(width=40, height=40, closed_only=False), + [data]) + assert_array_equal(p.to_polygons(), []) + assert_array_equal(p.to_polygons(closed_only=False), [data]) + + data = [[10, 10], [20, 20], [30, 30]] + closed_data = [[10, 10], [20, 20], [30, 30], [10, 10]] + p = Path(data) + + assert_array_equal(p.to_polygons(width=40, height=40), [closed_data]) + assert_array_equal(p.to_polygons(width=40, height=40, closed_only=False), + [data]) + assert_array_equal(p.to_polygons(), [closed_data]) + assert_array_equal(p.to_polygons(closed_only=False), [data]) + + +def test_path_deepcopy(): + # Should not raise any error + verts = [[0, 0], [1, 1]] + codes = [Path.MOVETO, Path.LINETO] + path1 = Path(verts) + path2 = Path(verts, codes) + path1_copy = path1.deepcopy() + path2_copy = path2.deepcopy() + assert path1 is not path1_copy + assert path1.vertices is not path1_copy.vertices + assert path2 is not path2_copy + assert path2.vertices is not path2_copy.vertices + assert path2.codes is not path2_copy.codes + + +def test_path_shallowcopy(): + # Should not raise any error + verts = [[0, 0], [1, 1]] + codes = [Path.MOVETO, Path.LINETO] + path1 = Path(verts) + path2 = Path(verts, codes) + path1_copy = path1.copy() + path2_copy = path2.copy() + assert path1 is not path1_copy + assert path1.vertices is path1_copy.vertices + assert path2 is not path2_copy + assert path2.vertices is path2_copy.vertices + assert path2.codes is path2_copy.codes + + +@pytest.mark.parametrize('phi', np.concatenate([ + np.array([0, 15, 30, 45, 60, 75, 90, 105, 120, 135]) + delta + for delta in [-1, 0, 1]])) +def test_path_intersect_path(phi): + # test for the range of intersection angles + eps_array = [1e-5, 1e-8, 1e-10, 1e-12] + + transform = transforms.Affine2D().rotate(np.deg2rad(phi)) + + # a and b intersect at angle phi + a = Path([(-2, 0), (2, 0)]) + b = transform.transform_path(a) + assert a.intersects_path(b) and b.intersects_path(a) + + # a and b touch at angle phi at (0, 0) + a = Path([(0, 0), (2, 0)]) + b = transform.transform_path(a) + assert a.intersects_path(b) and b.intersects_path(a) + + # a and b are orthogonal and intersect at (0, 3) + a = transform.transform_path(Path([(0, 1), (0, 3)])) + b = transform.transform_path(Path([(1, 3), (0, 3)])) + assert a.intersects_path(b) and b.intersects_path(a) + + # a and b are collinear and intersect at (0, 3) + a = transform.transform_path(Path([(0, 1), (0, 3)])) + b = transform.transform_path(Path([(0, 5), (0, 3)])) + assert a.intersects_path(b) and b.intersects_path(a) + + # self-intersect + assert a.intersects_path(a) + + # a contains b + a = transform.transform_path(Path([(0, 0), (5, 5)])) + b = transform.transform_path(Path([(1, 1), (3, 3)])) + assert a.intersects_path(b) and b.intersects_path(a) + + # a and b are collinear but do not intersect + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(3, 0), (3, 3)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + # a and b are on the same line but do not intersect + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(0, 6), (0, 7)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + # Note: 1e-13 is the absolute tolerance error used for + # `isclose` function from src/_path.h + + # a and b are parallel but do not touch + for eps in eps_array: + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(0 + eps, 1), (0 + eps, 5)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + # a and b are on the same line but do not intersect (really close) + for eps in eps_array: + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(0, 5 + eps), (0, 7)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + # a and b are on the same line and intersect (really close) + for eps in eps_array: + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(0, 5 - eps), (0, 7)])) + assert a.intersects_path(b) and b.intersects_path(a) + + # b is the same as a but with an extra point + a = transform.transform_path(Path([(0, 1), (0, 5)])) + b = transform.transform_path(Path([(0, 1), (0, 2), (0, 5)])) + assert a.intersects_path(b) and b.intersects_path(a) + + # a and b are collinear but do not intersect + a = transform.transform_path(Path([(1, -1), (0, -1)])) + b = transform.transform_path(Path([(0, 1), (0.9, 1)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + # a and b are collinear but do not intersect + a = transform.transform_path(Path([(0., -5.), (1., -5.)])) + b = transform.transform_path(Path([(1., 5.), (0., 5.)])) + assert not a.intersects_path(b) and not b.intersects_path(a) + + +@pytest.mark.parametrize('offset', range(-720, 361, 45)) +def test_full_arc(offset): + low = offset + high = 360 + offset + + path = Path.arc(low, high) + mins = np.min(path.vertices, axis=0) + maxs = np.max(path.vertices, axis=0) + np.testing.assert_allclose(mins, -1) + np.testing.assert_allclose(maxs, 1) + + +def test_disjoint_zero_length_segment(): + this_path = Path( + np.array([ + [824.85064295, 2056.26489203], + [861.69033931, 2041.00539016], + [868.57864109, 2057.63522175], + [831.73894473, 2072.89472361], + [824.85064295, 2056.26489203]]), + np.array([1, 2, 2, 2, 79], dtype=Path.code_type)) + + outline_path = Path( + np.array([ + [859.91051028, 2165.38461538], + [859.06772495, 2149.30331334], + [859.06772495, 2181.46591743], + [859.91051028, 2165.38461538], + [859.91051028, 2165.38461538]]), + np.array([1, 2, 2, 2, 2], + dtype=Path.code_type)) + + assert not outline_path.intersects_path(this_path) + assert not this_path.intersects_path(outline_path) + + +def test_intersect_zero_length_segment(): + this_path = Path( + np.array([ + [0, 0], + [1, 1], + ])) + + outline_path = Path( + np.array([ + [1, 0], + [.5, .5], + [.5, .5], + [0, 1], + ])) + + assert outline_path.intersects_path(this_path) + assert this_path.intersects_path(outline_path) + + +def test_cleanup_closepoly(): + # if the first connected component of a Path ends in a CLOSEPOLY, but that + # component contains a NaN, then Path.cleaned should ignore not just the + # control points but also the CLOSEPOLY, since it has nowhere valid to + # point. + paths = [ + Path([[np.nan, np.nan], [np.nan, np.nan]], + [Path.MOVETO, Path.CLOSEPOLY]), + # we trigger a different path in the C++ code if we don't pass any + # codes explicitly, so we must also make sure that this works + Path([[np.nan, np.nan], [np.nan, np.nan]]), + # we should also make sure that this cleanup works if there's some + # multi-vertex curves + Path([[np.nan, np.nan], [np.nan, np.nan], [np.nan, np.nan], + [np.nan, np.nan]], + [Path.MOVETO, Path.CURVE3, Path.CURVE3, Path.CLOSEPOLY]) + ] + for p in paths: + cleaned = p.cleaned(remove_nans=True) + assert len(cleaned) == 1 + assert cleaned.codes[0] == Path.STOP diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patheffects.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patheffects.py new file mode 100644 index 00000000..32cce141 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_patheffects.py @@ -0,0 +1,194 @@ +import numpy as np + +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +import matplotlib.patheffects as path_effects +from matplotlib.path import Path +import matplotlib.patches as patches + + +@image_comparison(['patheffect1'], remove_text=True) +def test_patheffect1(): + ax1 = plt.subplot() + ax1.imshow([[1, 2], [2, 3]]) + txt = ax1.annotate("test", (1., 1.), (0., 0), + arrowprops=dict(arrowstyle="->", + connectionstyle="angle3", lw=2), + size=20, ha="center", + path_effects=[path_effects.withStroke(linewidth=3, + foreground="w")]) + txt.arrow_patch.set_path_effects([path_effects.Stroke(linewidth=5, + foreground="w"), + path_effects.Normal()]) + + pe = [path_effects.withStroke(linewidth=3, foreground="w")] + ax1.grid(True, linestyle="-", path_effects=pe) + + +@image_comparison(['patheffect2'], remove_text=True, style='mpl20') +def test_patheffect2(): + + ax2 = plt.subplot() + arr = np.arange(25).reshape((5, 5)) + ax2.imshow(arr, interpolation='nearest') + cntr = ax2.contour(arr, colors="k") + cntr.set(path_effects=[path_effects.withStroke(linewidth=3, foreground="w")]) + + clbls = ax2.clabel(cntr, fmt="%2.0f", use_clabeltext=True) + plt.setp(clbls, + path_effects=[path_effects.withStroke(linewidth=3, + foreground="w")]) + + +@image_comparison(['patheffect3']) +def test_patheffect3(): + p1, = plt.plot([1, 3, 5, 4, 3], 'o-b', lw=4) + p1.set_path_effects([path_effects.SimpleLineShadow(), + path_effects.Normal()]) + plt.title( + r'testing$^{123}$', + path_effects=[path_effects.withStroke(linewidth=1, foreground="r")]) + leg = plt.legend([p1], [r'Line 1$^2$'], fancybox=True, loc='upper left') + leg.legendPatch.set_path_effects([path_effects.withSimplePatchShadow()]) + + text = plt.text(2, 3, 'Drop test', color='white', + bbox={'boxstyle': 'circle,pad=0.1', 'color': 'red'}) + pe = [path_effects.Stroke(linewidth=3.75, foreground='k'), + path_effects.withSimplePatchShadow((6, -3), shadow_rgbFace='blue')] + text.set_path_effects(pe) + text.get_bbox_patch().set_path_effects(pe) + + pe = [path_effects.PathPatchEffect(offset=(4, -4), hatch='xxxx', + facecolor='gray'), + path_effects.PathPatchEffect(edgecolor='white', facecolor='black', + lw=1.1)] + + t = plt.gcf().text(0.02, 0.1, 'Hatch shadow', fontsize=75, weight=1000, + va='center') + t.set_path_effects(pe) + + +@image_comparison(['stroked_text.png']) +def test_patheffects_stroked_text(): + text_chunks = [ + 'A B C D E F G H I J K L', + 'M N O P Q R S T U V W', + 'X Y Z a b c d e f g h i j', + 'k l m n o p q r s t u v', + 'w x y z 0123456789', + r"!@#$%^&*()-=_+[]\;'", + ',./{}|:"<>?' + ] + font_size = 50 + + ax = plt.axes((0, 0, 1, 1)) + for i, chunk in enumerate(text_chunks): + text = ax.text(x=0.01, y=(0.9 - i * 0.13), s=chunk, + fontdict={'ha': 'left', 'va': 'center', + 'size': font_size, 'color': 'white'}) + + text.set_path_effects([path_effects.Stroke(linewidth=font_size / 10, + foreground='black'), + path_effects.Normal()]) + + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.axis('off') + + +def test_PathEffect_points_to_pixels(): + fig = plt.figure(dpi=150) + p1, = plt.plot(range(10)) + p1.set_path_effects([path_effects.SimpleLineShadow(), + path_effects.Normal()]) + renderer = fig.canvas.get_renderer() + pe_renderer = path_effects.PathEffectRenderer( + p1.get_path_effects(), renderer) + # Confirm that using a path effects renderer maintains point sizes + # appropriately. Otherwise rendered font would be the wrong size. + assert renderer.points_to_pixels(15) == pe_renderer.points_to_pixels(15) + + +def test_SimplePatchShadow_offset(): + pe = path_effects.SimplePatchShadow(offset=(4, 5)) + assert pe._offset == (4, 5) + + +@image_comparison(['collection'], tol=0.03, style='mpl20') +def test_collection(): + x, y = np.meshgrid(np.linspace(0, 10, 150), np.linspace(-5, 5, 100)) + data = np.sin(x) + np.cos(y) + cs = plt.contour(data) + cs.set(path_effects=[ + path_effects.PathPatchEffect(edgecolor='black', facecolor='none', linewidth=12), + path_effects.Stroke(linewidth=5)]) + for text in plt.clabel(cs, colors='white'): + text.set_path_effects([path_effects.withStroke(foreground='k', + linewidth=3)]) + text.set_bbox({'boxstyle': 'sawtooth', 'facecolor': 'none', + 'edgecolor': 'blue'}) + + +@image_comparison(['tickedstroke'], remove_text=True, extensions=['png'], + tol=0.22) # Increased tolerance due to fixed clipping. +def test_tickedstroke(): + fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(12, 4)) + path = Path.unit_circle() + patch = patches.PathPatch(path, facecolor='none', lw=2, path_effects=[ + path_effects.withTickedStroke(angle=-90, spacing=10, + length=1)]) + + ax1.add_patch(patch) + ax1.axis('equal') + ax1.set_xlim(-2, 2) + ax1.set_ylim(-2, 2) + + ax2.plot([0, 1], [0, 1], label=' ', + path_effects=[path_effects.withTickedStroke(spacing=7, + angle=135)]) + nx = 101 + x = np.linspace(0.0, 1.0, nx) + y = 0.3 * np.sin(x * 8) + 0.4 + ax2.plot(x, y, label=' ', path_effects=[path_effects.withTickedStroke()]) + + ax2.legend() + + nx = 101 + ny = 105 + + # Set up survey vectors + xvec = np.linspace(0.001, 4.0, nx) + yvec = np.linspace(0.001, 4.0, ny) + + # Set up survey matrices. Design disk loading and gear ratio. + x1, x2 = np.meshgrid(xvec, yvec) + + # Evaluate some stuff to plot + g1 = -(3 * x1 + x2 - 5.5) + g2 = -(x1 + 2 * x2 - 4) + g3 = .8 + x1 ** -3 - x2 + + cg1 = ax3.contour(x1, x2, g1, [0], colors=('k',)) + cg1.set(path_effects=[path_effects.withTickedStroke(angle=135)]) + + cg2 = ax3.contour(x1, x2, g2, [0], colors=('r',)) + cg2.set(path_effects=[path_effects.withTickedStroke(angle=60, length=2)]) + + cg3 = ax3.contour(x1, x2, g3, [0], colors=('b',)) + cg3.set(path_effects=[path_effects.withTickedStroke(spacing=7)]) + + ax3.set_xlim(0, 4) + ax3.set_ylim(0, 4) + + +@image_comparison(['spaces_and_newlines.png'], remove_text=True) +def test_patheffects_spaces_and_newlines(): + ax = plt.subplot() + s1 = " " + s2 = "\nNewline also causes problems" + text1 = ax.text(0.5, 0.75, s1, ha='center', va='center', size=20, + bbox={'color': 'salmon'}) + text2 = ax.text(0.5, 0.25, s2, ha='center', va='center', size=20, + bbox={'color': 'thistle'}) + text1.set_path_effects([path_effects.Normal()]) + text2.set_path_effects([path_effects.Normal()]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pickle.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pickle.py new file mode 100644 index 00000000..e222a495 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pickle.py @@ -0,0 +1,303 @@ +from io import BytesIO +import ast +import pickle +import pickletools + +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import cm +from matplotlib.testing import subprocess_run_helper +from matplotlib.testing.decorators import check_figures_equal +from matplotlib.dates import rrulewrapper +from matplotlib.lines import VertexSelector +import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms +import matplotlib.figure as mfigure +from mpl_toolkits.axes_grid1 import parasite_axes # type: ignore + + +def test_simple(): + fig = plt.figure() + pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) + + ax = plt.subplot(121) + pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + + ax = plt.axes(projection='polar') + plt.plot(np.arange(10), label='foobar') + plt.legend() + + pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + +# ax = plt.subplot(121, projection='hammer') +# pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + + plt.figure() + plt.bar(x=np.arange(10), height=np.arange(10)) + pickle.dump(plt.gca(), BytesIO(), pickle.HIGHEST_PROTOCOL) + + fig = plt.figure() + ax = plt.axes() + plt.plot(np.arange(10)) + ax.set_yscale('log') + pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) + + +def _generate_complete_test_figure(fig_ref): + fig_ref.set_size_inches((10, 6)) + plt.figure(fig_ref) + + plt.suptitle('Can you fit any more in a figure?') + + # make some arbitrary data + x, y = np.arange(8), np.arange(10) + data = u = v = np.linspace(0, 10, 80).reshape(10, 8) + v = np.sin(v * -0.6) + + # Ensure lists also pickle correctly. + plt.subplot(3, 3, 1) + plt.plot(list(range(10))) + plt.ylabel("hello") + + plt.subplot(3, 3, 2) + plt.contourf(data, hatches=['//', 'ooo']) + plt.colorbar() + + plt.subplot(3, 3, 3) + plt.pcolormesh(data) + + plt.subplot(3, 3, 4) + plt.imshow(data) + plt.ylabel("hello\nworld!") + + plt.subplot(3, 3, 5) + plt.pcolor(data) + + ax = plt.subplot(3, 3, 6) + ax.set_xlim(0, 7) + ax.set_ylim(0, 9) + plt.streamplot(x, y, u, v) + + ax = plt.subplot(3, 3, 7) + ax.set_xlim(0, 7) + ax.set_ylim(0, 9) + plt.quiver(x, y, u, v) + + plt.subplot(3, 3, 8) + plt.scatter(x, x ** 2, label='$x^2$') + plt.legend(loc='upper left') + + plt.subplot(3, 3, 9) + plt.errorbar(x, x * -0.5, xerr=0.2, yerr=0.4) + plt.legend(draggable=True) + + fig_ref.align_ylabels() # Test handling of _align_label_groups Groupers. + + +@mpl.style.context("default") +@check_figures_equal(extensions=["png"]) +def test_complete(fig_test, fig_ref): + _generate_complete_test_figure(fig_ref) + # plotting is done, now test its pickle-ability + pkl = pickle.dumps(fig_ref, pickle.HIGHEST_PROTOCOL) + # FigureCanvasAgg is picklable and GUI canvases are generally not, but there should + # be no reference to the canvas in the pickle stream in either case. In order to + # keep the test independent of GUI toolkits, run it with Agg and check that there's + # no reference to FigureCanvasAgg in the pickle stream. + assert "FigureCanvasAgg" not in [arg for op, arg, pos in pickletools.genops(pkl)] + loaded = pickle.loads(pkl) + loaded.canvas.draw() + + fig_test.set_size_inches(loaded.get_size_inches()) + fig_test.figimage(loaded.canvas.renderer.buffer_rgba()) + + plt.close(loaded) + + +def _pickle_load_subprocess(): + import os + import pickle + + path = os.environ['PICKLE_FILE_PATH'] + + with open(path, 'rb') as blob: + fig = pickle.load(blob) + + print(str(pickle.dumps(fig))) + + +@mpl.style.context("default") +@check_figures_equal(extensions=['png']) +def test_pickle_load_from_subprocess(fig_test, fig_ref, tmp_path): + _generate_complete_test_figure(fig_ref) + + fp = tmp_path / 'sinus.pickle' + assert not fp.exists() + + with fp.open('wb') as file: + pickle.dump(fig_ref, file, pickle.HIGHEST_PROTOCOL) + assert fp.exists() + + proc = subprocess_run_helper( + _pickle_load_subprocess, + timeout=60, + extra_env={'PICKLE_FILE_PATH': str(fp), 'MPLBACKEND': 'Agg'} + ) + + loaded_fig = pickle.loads(ast.literal_eval(proc.stdout)) + + loaded_fig.canvas.draw() + + fig_test.set_size_inches(loaded_fig.get_size_inches()) + fig_test.figimage(loaded_fig.canvas.renderer.buffer_rgba()) + + plt.close(loaded_fig) + + +def test_gcf(): + fig = plt.figure("a label") + buf = BytesIO() + pickle.dump(fig, buf, pickle.HIGHEST_PROTOCOL) + plt.close("all") + assert plt._pylab_helpers.Gcf.figs == {} # No figures must be left. + fig = pickle.loads(buf.getbuffer()) + assert plt._pylab_helpers.Gcf.figs != {} # A manager is there again. + assert fig.get_label() == "a label" + + +def test_no_pyplot(): + # tests pickle-ability of a figure not created with pyplot + from matplotlib.backends.backend_pdf import FigureCanvasPdf + fig = mfigure.Figure() + _ = FigureCanvasPdf(fig) + ax = fig.add_subplot(1, 1, 1) + ax.plot([1, 2, 3], [1, 2, 3]) + pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) + + +def test_renderer(): + from matplotlib.backends.backend_agg import RendererAgg + renderer = RendererAgg(10, 20, 30) + pickle.dump(renderer, BytesIO()) + + +def test_image(): + # Prior to v1.4.0 the Image would cache data which was not picklable + # once it had been drawn. + from matplotlib.backends.backend_agg import new_figure_manager + manager = new_figure_manager(1000) + fig = manager.canvas.figure + ax = fig.add_subplot(1, 1, 1) + ax.imshow(np.arange(12).reshape(3, 4)) + manager.canvas.draw() + pickle.dump(fig, BytesIO()) + + +def test_polar(): + plt.subplot(polar=True) + fig = plt.gcf() + pf = pickle.dumps(fig) + pickle.loads(pf) + plt.draw() + + +class TransformBlob: + def __init__(self): + self.identity = mtransforms.IdentityTransform() + self.identity2 = mtransforms.IdentityTransform() + # Force use of the more complex composition. + self.composite = mtransforms.CompositeGenericTransform( + self.identity, + self.identity2) + # Check parent -> child links of TransformWrapper. + self.wrapper = mtransforms.TransformWrapper(self.composite) + # Check child -> parent links of TransformWrapper. + self.composite2 = mtransforms.CompositeGenericTransform( + self.wrapper, + self.identity) + + +def test_transform(): + obj = TransformBlob() + pf = pickle.dumps(obj) + del obj + + obj = pickle.loads(pf) + # Check parent -> child links of TransformWrapper. + assert obj.wrapper._child == obj.composite + # Check child -> parent links of TransformWrapper. + assert [v() for v in obj.wrapper._parents.values()] == [obj.composite2] + # Check input and output dimensions are set as expected. + assert obj.wrapper.input_dims == obj.composite.input_dims + assert obj.wrapper.output_dims == obj.composite.output_dims + + +def test_rrulewrapper(): + r = rrulewrapper(2) + try: + pickle.loads(pickle.dumps(r)) + except RecursionError: + print('rrulewrapper pickling test failed') + raise + + +def test_shared(): + fig, axs = plt.subplots(2, sharex=True) + fig = pickle.loads(pickle.dumps(fig)) + fig.axes[0].set_xlim(10, 20) + assert fig.axes[1].get_xlim() == (10, 20) + + +def test_inset_and_secondary(): + fig, ax = plt.subplots() + ax.inset_axes([.1, .1, .3, .3]) + ax.secondary_xaxis("top", functions=(np.square, np.sqrt)) + pickle.loads(pickle.dumps(fig)) + + +@pytest.mark.parametrize("cmap", cm._colormaps.values()) +def test_cmap(cmap): + pickle.dumps(cmap) + + +def test_unpickle_canvas(): + fig = mfigure.Figure() + assert fig.canvas is not None + out = BytesIO() + pickle.dump(fig, out) + out.seek(0) + fig2 = pickle.load(out) + assert fig2.canvas is not None + + +def test_mpl_toolkits(): + ax = parasite_axes.host_axes([0, 0, 1, 1]) + assert type(pickle.loads(pickle.dumps(ax))) == parasite_axes.HostAxes + + +def test_standard_norm(): + assert type(pickle.loads(pickle.dumps(mpl.colors.LogNorm()))) \ + == mpl.colors.LogNorm + + +def test_dynamic_norm(): + logit_norm_instance = mpl.colors.make_norm_from_scale( + mpl.scale.LogitScale, mpl.colors.Normalize)() + assert type(pickle.loads(pickle.dumps(logit_norm_instance))) \ + == type(logit_norm_instance) + + +def test_vertexselector(): + line, = plt.plot([0, 1], picker=True) + pickle.loads(pickle.dumps(VertexSelector(line))) + + +def test_cycler(): + ax = plt.figure().add_subplot() + ax.set_prop_cycle(c=["c", "m", "y", "k"]) + ax.plot([1, 2]) + ax = pickle.loads(pickle.dumps(ax)) + l, = ax.plot([3, 4]) + assert l.get_color() == "m" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_png.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_png.py new file mode 100644 index 00000000..066eb01c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_png.py @@ -0,0 +1,50 @@ +from io import BytesIO +from pathlib import Path + +import pytest + +from matplotlib.testing.decorators import image_comparison +from matplotlib import cm, pyplot as plt + + +@image_comparison(['pngsuite.png'], tol=0.03) +def test_pngsuite(): + files = sorted( + (Path(__file__).parent / "baseline_images/pngsuite").glob("basn*.png")) + + plt.figure(figsize=(len(files), 2)) + + for i, fname in enumerate(files): + data = plt.imread(fname) + cmap = None # use default colormap + if data.ndim == 2: + # keep grayscale images gray + cmap = cm.gray + plt.imshow(data, extent=(i, i + 1, 0, 1), cmap=cmap) + + plt.gca().patch.set_facecolor("#ddffff") + plt.gca().set_xlim(0, len(files)) + + +def test_truncated_file(tmp_path): + path = tmp_path / 'test.png' + path_t = tmp_path / 'test_truncated.png' + plt.savefig(path) + with open(path, 'rb') as fin: + buf = fin.read() + with open(path_t, 'wb') as fout: + fout.write(buf[:20]) + + with pytest.raises(Exception): + plt.imread(path_t) + + +def test_truncated_buffer(): + b = BytesIO() + plt.savefig(b) + b.seek(0) + b2 = BytesIO(b.read(20)) + b2.seek(0) + + with pytest.raises(Exception): + plt.imread(b2) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_polar.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_polar.py new file mode 100644 index 00000000..9d6e78da --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_polar.py @@ -0,0 +1,448 @@ +import numpy as np +from numpy.testing import assert_allclose +import pytest + +import matplotlib as mpl +from matplotlib import pyplot as plt +from matplotlib.testing.decorators import image_comparison, check_figures_equal + + +@image_comparison(['polar_axes'], style='default', tol=0.012) +def test_polar_annotations(): + # You can specify the xypoint and the xytext in different positions and + # coordinate systems, and optionally turn on a connecting line and mark the + # point with a marker. Annotations work on polar axes too. In the example + # below, the xy point is in native coordinates (xycoords defaults to + # 'data'). For a polar axes, this is in (theta, radius) space. The text + # in this example is placed in the fractional figure coordinate system. + # Text keyword args like horizontal and vertical alignment are respected. + + # Setup some data + r = np.arange(0.0, 1.0, 0.001) + theta = 2.0 * 2.0 * np.pi * r + + fig = plt.figure() + ax = fig.add_subplot(polar=True) + line, = ax.plot(theta, r, color='#ee8d18', lw=3) + line, = ax.plot((0, 0), (0, 1), color="#0000ff", lw=1) + + ind = 800 + thisr, thistheta = r[ind], theta[ind] + ax.plot([thistheta], [thisr], 'o') + ax.annotate('a polar annotation', + xy=(thistheta, thisr), # theta, radius + xytext=(0.05, 0.05), # fraction, fraction + textcoords='figure fraction', + arrowprops=dict(facecolor='black', shrink=0.05), + horizontalalignment='left', + verticalalignment='baseline', + ) + + ax.tick_params(axis='x', tick1On=True, tick2On=True, direction='out') + + +@image_comparison(['polar_coords'], style='default', remove_text=True, + tol=0.012) +def test_polar_coord_annotations(): + # You can also use polar notation on a cartesian axes. Here the native + # coordinate system ('data') is cartesian, so you need to specify the + # xycoords and textcoords as 'polar' if you want to use (theta, radius). + el = mpl.patches.Ellipse((0, 0), 10, 20, facecolor='r', alpha=0.5) + + fig = plt.figure() + ax = fig.add_subplot(aspect='equal') + + ax.add_artist(el) + el.set_clip_box(ax.bbox) + + ax.annotate('the top', + xy=(np.pi/2., 10.), # theta, radius + xytext=(np.pi/3, 20.), # theta, radius + xycoords='polar', + textcoords='polar', + arrowprops=dict(facecolor='black', shrink=0.05), + horizontalalignment='left', + verticalalignment='baseline', + clip_on=True, # clip to the axes bounding box + ) + + ax.set_xlim(-20, 20) + ax.set_ylim(-20, 20) + + +@image_comparison(['polar_alignment.png']) +def test_polar_alignment(): + # Test changing the vertical/horizontal alignment of a polar graph. + angles = np.arange(0, 360, 90) + grid_values = [0, 0.2, 0.4, 0.6, 0.8, 1] + + fig = plt.figure() + rect = [0.1, 0.1, 0.8, 0.8] + + horizontal = fig.add_axes(rect, polar=True, label='horizontal') + horizontal.set_thetagrids(angles) + + vertical = fig.add_axes(rect, polar=True, label='vertical') + vertical.patch.set_visible(False) + + for i in range(2): + fig.axes[i].set_rgrids( + grid_values, angle=angles[i], + horizontalalignment='left', verticalalignment='top') + + +def test_polar_twice(): + fig = plt.figure() + plt.polar([1, 2], [.1, .2]) + plt.polar([3, 4], [.3, .4]) + assert len(fig.axes) == 1, 'More than one polar axes created.' + + +@check_figures_equal() +def test_polar_wrap(fig_test, fig_ref): + ax = fig_test.add_subplot(projection="polar") + ax.plot(np.deg2rad([179, -179]), [0.2, 0.1]) + ax.plot(np.deg2rad([2, -2]), [0.2, 0.1]) + ax = fig_ref.add_subplot(projection="polar") + ax.plot(np.deg2rad([179, 181]), [0.2, 0.1]) + ax.plot(np.deg2rad([2, 358]), [0.2, 0.1]) + + +@check_figures_equal() +def test_polar_units_1(fig_test, fig_ref): + import matplotlib.testing.jpl_units as units + units.register() + xs = [30.0, 45.0, 60.0, 90.0] + ys = [1.0, 2.0, 3.0, 4.0] + + plt.figure(fig_test.number) + plt.polar([x * units.deg for x in xs], ys) + + ax = fig_ref.add_subplot(projection="polar") + ax.plot(np.deg2rad(xs), ys) + ax.set(xlabel="deg") + + +@check_figures_equal() +def test_polar_units_2(fig_test, fig_ref): + import matplotlib.testing.jpl_units as units + units.register() + xs = [30.0, 45.0, 60.0, 90.0] + xs_deg = [x * units.deg for x in xs] + ys = [1.0, 2.0, 3.0, 4.0] + ys_km = [y * units.km for y in ys] + + plt.figure(fig_test.number) + # test {theta,r}units. + plt.polar(xs_deg, ys_km, thetaunits="rad", runits="km") + assert isinstance(plt.gca().xaxis.get_major_formatter(), + units.UnitDblFormatter) + + ax = fig_ref.add_subplot(projection="polar") + ax.plot(np.deg2rad(xs), ys) + ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter("{:.12}".format)) + ax.set(xlabel="rad", ylabel="km") + + +@image_comparison(['polar_rmin'], style='default') +def test_polar_rmin(): + r = np.arange(0, 3.0, 0.01) + theta = 2*np.pi*r + + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.plot(theta, r) + ax.set_rmax(2.0) + ax.set_rmin(0.5) + + +@image_comparison(['polar_negative_rmin'], style='default') +def test_polar_negative_rmin(): + r = np.arange(-3.0, 0.0, 0.01) + theta = 2*np.pi*r + + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.plot(theta, r) + ax.set_rmax(0.0) + ax.set_rmin(-3.0) + + +@image_comparison(['polar_rorigin'], style='default') +def test_polar_rorigin(): + r = np.arange(0, 3.0, 0.01) + theta = 2*np.pi*r + + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.plot(theta, r) + ax.set_rmax(2.0) + ax.set_rmin(0.5) + ax.set_rorigin(0.0) + + +@image_comparison(['polar_invertedylim.png'], style='default') +def test_polar_invertedylim(): + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.set_ylim(2, 0) + + +@image_comparison(['polar_invertedylim_rorigin.png'], style='default') +def test_polar_invertedylim_rorigin(): + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.yaxis.set_inverted(True) + # Set the rlims to inverted (2, 0) without calling set_rlim, to check that + # viewlims are correctly unstaled before draw()ing. + ax.plot([0, 0], [0, 2], c="none") + ax.margins(0) + ax.set_rorigin(3) + + +@image_comparison(['polar_theta_position'], style='default') +def test_polar_theta_position(): + r = np.arange(0, 3.0, 0.01) + theta = 2*np.pi*r + + fig = plt.figure() + ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) + ax.plot(theta, r) + ax.set_theta_zero_location("NW", 30) + ax.set_theta_direction('clockwise') + + +@image_comparison(['polar_rlabel_position'], style='default') +def test_polar_rlabel_position(): + fig = plt.figure() + ax = fig.add_subplot(projection='polar') + ax.set_rlabel_position(315) + ax.tick_params(rotation='auto') + + +@image_comparison(['polar_theta_wedge'], style='default') +def test_polar_theta_limits(): + r = np.arange(0, 3.0, 0.01) + theta = 2*np.pi*r + + theta_mins = np.arange(15.0, 361.0, 90.0) + theta_maxs = np.arange(50.0, 361.0, 90.0) + DIRECTIONS = ('out', 'in', 'inout') + + fig, axs = plt.subplots(len(theta_mins), len(theta_maxs), + subplot_kw={'polar': True}, + figsize=(8, 6)) + + for i, start in enumerate(theta_mins): + for j, end in enumerate(theta_maxs): + ax = axs[i, j] + ax.plot(theta, r) + if start < end: + ax.set_thetamin(start) + ax.set_thetamax(end) + else: + # Plot with clockwise orientation instead. + ax.set_thetamin(end) + ax.set_thetamax(start) + ax.set_theta_direction('clockwise') + ax.tick_params(tick1On=True, tick2On=True, + direction=DIRECTIONS[i % len(DIRECTIONS)], + rotation='auto') + ax.yaxis.set_tick_params(label2On=True, rotation='auto') + ax.xaxis.get_major_locator().base.set_params( # backcompat + steps=[1, 2, 2.5, 5, 10]) + + +@check_figures_equal(extensions=["png"]) +def test_polar_rlim(fig_test, fig_ref): + ax = fig_test.subplots(subplot_kw={'polar': True}) + ax.set_rlim(top=10) + ax.set_rlim(bottom=.5) + + ax = fig_ref.subplots(subplot_kw={'polar': True}) + ax.set_rmax(10.) + ax.set_rmin(.5) + + +@check_figures_equal(extensions=["png"]) +def test_polar_rlim_bottom(fig_test, fig_ref): + ax = fig_test.subplots(subplot_kw={'polar': True}) + ax.set_rlim(bottom=[.5, 10]) + + ax = fig_ref.subplots(subplot_kw={'polar': True}) + ax.set_rmax(10.) + ax.set_rmin(.5) + + +def test_polar_rlim_zero(): + ax = plt.figure().add_subplot(projection='polar') + ax.plot(np.arange(10), np.arange(10) + .01) + assert ax.get_ylim()[0] == 0 + + +def test_polar_no_data(): + plt.subplot(projection="polar") + ax = plt.gca() + assert ax.get_rmin() == 0 and ax.get_rmax() == 1 + plt.close("all") + # Used to behave differently (by triggering an autoscale with no data). + plt.polar() + ax = plt.gca() + assert ax.get_rmin() == 0 and ax.get_rmax() == 1 + + +def test_polar_default_log_lims(): + plt.subplot(projection='polar') + ax = plt.gca() + ax.set_rscale('log') + assert ax.get_rmin() > 0 + + +def test_polar_not_datalim_adjustable(): + ax = plt.figure().add_subplot(projection="polar") + with pytest.raises(ValueError): + ax.set_adjustable("datalim") + + +def test_polar_gridlines(): + fig = plt.figure() + ax = fig.add_subplot(polar=True) + # make all major grid lines lighter, only x grid lines set in 2.1.0 + ax.grid(alpha=0.2) + # hide y tick labels, no effect in 2.1.0 + plt.setp(ax.yaxis.get_ticklabels(), visible=False) + fig.canvas.draw() + assert ax.xaxis.majorTicks[0].gridline.get_alpha() == .2 + assert ax.yaxis.majorTicks[0].gridline.get_alpha() == .2 + + +def test_get_tightbbox_polar(): + fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) + fig.canvas.draw() + bb = ax.get_tightbbox(fig.canvas.get_renderer()) + assert_allclose( + bb.extents, [107.7778, 29.2778, 539.7847, 450.7222], rtol=1e-03) + + +@check_figures_equal(extensions=["png"]) +def test_polar_interpolation_steps_constant_r(fig_test, fig_ref): + # Check that an extra half-turn doesn't make any difference -- modulo + # antialiasing, which we disable here. + p1 = (fig_test.add_subplot(121, projection="polar") + .bar([0], [1], 3*np.pi, edgecolor="none", antialiased=False)) + p2 = (fig_test.add_subplot(122, projection="polar") + .bar([0], [1], -3*np.pi, edgecolor="none", antialiased=False)) + p3 = (fig_ref.add_subplot(121, projection="polar") + .bar([0], [1], 2*np.pi, edgecolor="none", antialiased=False)) + p4 = (fig_ref.add_subplot(122, projection="polar") + .bar([0], [1], -2*np.pi, edgecolor="none", antialiased=False)) + + +@check_figures_equal(extensions=["png"]) +def test_polar_interpolation_steps_variable_r(fig_test, fig_ref): + l, = fig_test.add_subplot(projection="polar").plot([0, np.pi/2], [1, 2]) + l.get_path()._interpolation_steps = 100 + fig_ref.add_subplot(projection="polar").plot( + np.linspace(0, np.pi/2, 101), np.linspace(1, 2, 101)) + + +def test_thetalim_valid_invalid(): + ax = plt.subplot(projection='polar') + ax.set_thetalim(0, 2 * np.pi) # doesn't raise. + ax.set_thetalim(thetamin=800, thetamax=440) # doesn't raise. + with pytest.raises(ValueError, + match='angle range must be less than a full circle'): + ax.set_thetalim(0, 3 * np.pi) + with pytest.raises(ValueError, + match='angle range must be less than a full circle'): + ax.set_thetalim(thetamin=800, thetamax=400) + + +def test_thetalim_args(): + ax = plt.subplot(projection='polar') + ax.set_thetalim(0, 1) + assert tuple(np.radians((ax.get_thetamin(), ax.get_thetamax()))) == (0, 1) + ax.set_thetalim((2, 3)) + assert tuple(np.radians((ax.get_thetamin(), ax.get_thetamax()))) == (2, 3) + + +def test_default_thetalocator(): + # Ideally we would check AAAABBC, but the smallest axes currently puts a + # single tick at 150° because MaxNLocator doesn't have a way to accept 15° + # while rejecting 150°. + fig, axs = plt.subplot_mosaic( + "AAAABB.", subplot_kw={"projection": "polar"}) + for ax in axs.values(): + ax.set_thetalim(0, np.pi) + for ax in axs.values(): + ticklocs = np.degrees(ax.xaxis.get_majorticklocs()).tolist() + assert pytest.approx(90) in ticklocs + assert pytest.approx(100) not in ticklocs + + +def test_axvspan(): + ax = plt.subplot(projection="polar") + span = ax.axvspan(0, np.pi/4) + assert span.get_path()._interpolation_steps > 1 + + +@check_figures_equal(extensions=["png"]) +def test_remove_shared_polar(fig_ref, fig_test): + # Removing shared polar axes used to crash. Test removing them, keeping in + # both cases just the lower left axes of a grid to avoid running into a + # separate issue (now being fixed) of ticklabel visibility for shared axes. + axs = fig_ref.subplots( + 2, 2, sharex=True, subplot_kw={"projection": "polar"}) + for i in [0, 1, 3]: + axs.flat[i].remove() + axs = fig_test.subplots( + 2, 2, sharey=True, subplot_kw={"projection": "polar"}) + for i in [0, 1, 3]: + axs.flat[i].remove() + + +def test_shared_polar_keeps_ticklabels(): + fig, axs = plt.subplots( + 2, 2, subplot_kw={"projection": "polar"}, sharex=True, sharey=True) + fig.canvas.draw() + assert axs[0, 1].xaxis.majorTicks[0].get_visible() + assert axs[0, 1].yaxis.majorTicks[0].get_visible() + fig, axs = plt.subplot_mosaic( + "ab\ncd", subplot_kw={"projection": "polar"}, sharex=True, sharey=True) + fig.canvas.draw() + assert axs["b"].xaxis.majorTicks[0].get_visible() + assert axs["b"].yaxis.majorTicks[0].get_visible() + + +def test_axvline_axvspan_do_not_modify_rlims(): + ax = plt.subplot(projection="polar") + ax.axvspan(0, 1) + ax.axvline(.5) + ax.plot([.1, .2]) + assert ax.get_ylim() == (0, .2) + + +def test_cursor_precision(): + ax = plt.subplot(projection="polar") + # Higher radii correspond to higher theta-precisions. + assert ax.format_coord(0, 0.005) == "θ=0.0π (0°), r=0.005" + assert ax.format_coord(0, .1) == "θ=0.00π (0°), r=0.100" + assert ax.format_coord(0, 1) == "θ=0.000π (0.0°), r=1.000" + assert ax.format_coord(1, 0.005) == "θ=0.3π (57°), r=0.005" + assert ax.format_coord(1, .1) == "θ=0.32π (57°), r=0.100" + assert ax.format_coord(1, 1) == "θ=0.318π (57.3°), r=1.000" + assert ax.format_coord(2, 0.005) == "θ=0.6π (115°), r=0.005" + assert ax.format_coord(2, .1) == "θ=0.64π (115°), r=0.100" + assert ax.format_coord(2, 1) == "θ=0.637π (114.6°), r=1.000" + + +@image_comparison(['polar_log.png'], style='default') +def test_polar_log(): + fig = plt.figure() + ax = fig.add_subplot(polar=True) + + ax.set_rscale('log') + ax.set_rlim(1, 1000) + + n = 100 + ax.plot(np.linspace(0, 2 * np.pi, n), np.logspace(0, 2, n)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_preprocess_data.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_preprocess_data.py new file mode 100644 index 00000000..0684f0db --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_preprocess_data.py @@ -0,0 +1,288 @@ +import re +import sys + +import numpy as np +import pytest + +from matplotlib import _preprocess_data +from matplotlib.axes import Axes +from matplotlib.testing import subprocess_run_for_testing +from matplotlib.testing.decorators import check_figures_equal + +# Notes on testing the plotting functions itself +# * the individual decorated plotting functions are tested in 'test_axes.py' +# * that pyplot functions accept a data kwarg is only tested in +# test_axes.test_pie_linewidth_0 + + +# this gets used in multiple tests, so define it here +@_preprocess_data(replace_names=["x", "y"], label_namer="y") +def plot_func(ax, x, y, ls="x", label=None, w="xyz"): + return f"x: {list(x)}, y: {list(y)}, ls: {ls}, w: {w}, label: {label}" + + +all_funcs = [plot_func] +all_func_ids = ['plot_func'] + + +def test_compiletime_checks(): + """Test decorator invocations -> no replacements.""" + + def func(ax, x, y): pass + def func_args(ax, x, y, *args): pass + def func_kwargs(ax, x, y, **kwargs): pass + def func_no_ax_args(*args, **kwargs): pass + + # this is ok + _preprocess_data(replace_names=["x", "y"])(func) + _preprocess_data(replace_names=["x", "y"])(func_kwargs) + # this has "enough" information to do all the replaces + _preprocess_data(replace_names=["x", "y"])(func_args) + + # no positional_parameter_names but needed due to replaces + with pytest.raises(AssertionError): + # z is unknown + _preprocess_data(replace_names=["x", "y", "z"])(func_args) + + # no replacements at all -> all ok... + _preprocess_data(replace_names=[], label_namer=None)(func) + _preprocess_data(replace_names=[], label_namer=None)(func_args) + _preprocess_data(replace_names=[], label_namer=None)(func_kwargs) + _preprocess_data(replace_names=[], label_namer=None)(func_no_ax_args) + + # label namer is unknown + with pytest.raises(AssertionError): + _preprocess_data(label_namer="z")(func) + + with pytest.raises(AssertionError): + _preprocess_data(label_namer="z")(func_args) + + +@pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) +def test_function_call_without_data(func): + """Test without data -> no replacements.""" + assert (func(None, "x", "y") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: None") + assert (func(None, x="x", y="y") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: None") + assert (func(None, "x", "y", label="") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: ") + assert (func(None, "x", "y", label="text") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: text") + assert (func(None, x="x", y="y", label="") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: ") + assert (func(None, x="x", y="y", label="text") == + "x: ['x'], y: ['y'], ls: x, w: xyz, label: text") + + +@pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) +def test_function_call_with_dict_input(func): + """Tests with dict input, unpacking via preprocess_pipeline""" + data = {'a': 1, 'b': 2} + assert (func(None, data.keys(), data.values()) == + "x: ['a', 'b'], y: [1, 2], ls: x, w: xyz, label: None") + + +@pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) +def test_function_call_with_dict_data(func): + """Test with dict data -> label comes from the value of 'x' parameter.""" + data = {"a": [1, 2], "b": [8, 9], "w": "NOT"} + assert (func(None, "a", "b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func(None, x="a", y="b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func(None, "a", "b", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert (func(None, "a", "b", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + assert (func(None, x="a", y="b", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert (func(None, x="a", y="b", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + + +@pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) +def test_function_call_with_dict_data_not_in_data(func): + """Test the case that one var is not in data -> half replaces, half kept""" + data = {"a": [1, 2], "w": "NOT"} + assert (func(None, "a", "b", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: b") + assert (func(None, x="a", y="b", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: b") + assert (func(None, "a", "b", label="", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: ") + assert (func(None, "a", "b", label="text", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: text") + assert (func(None, x="a", y="b", label="", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: ") + assert (func(None, x="a", y="b", label="text", data=data) == + "x: [1, 2], y: ['b'], ls: x, w: xyz, label: text") + + +@pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) +def test_function_call_with_pandas_data(func, pd): + """Test with pandas dataframe -> label comes from ``data["col"].name``.""" + data = pd.DataFrame({"a": np.array([1, 2], dtype=np.int32), + "b": np.array([8, 9], dtype=np.int32), + "w": ["NOT", "NOT"]}) + + assert (func(None, "a", "b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func(None, x="a", y="b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func(None, "a", "b", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert (func(None, "a", "b", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + assert (func(None, x="a", y="b", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert (func(None, x="a", y="b", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + + +def test_function_call_replace_all(): + """Test without a "replace_names" argument, all vars should be replaced.""" + data = {"a": [1, 2], "b": [8, 9], "x": "xyz"} + + @_preprocess_data(label_namer="y") + def func_replace_all(ax, x, y, ls="x", label=None, w="NOT"): + return f"x: {list(x)}, y: {list(y)}, ls: {ls}, w: {w}, label: {label}" + + assert (func_replace_all(None, "a", "b", w="x", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func_replace_all(None, x="a", y="b", w="x", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: b") + assert (func_replace_all(None, "a", "b", w="x", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert ( + func_replace_all(None, "a", "b", w="x", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + assert ( + func_replace_all(None, x="a", y="b", w="x", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert ( + func_replace_all(None, x="a", y="b", w="x", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + + +def test_no_label_replacements(): + """Test with "label_namer=None" -> no label replacement at all.""" + + @_preprocess_data(replace_names=["x", "y"], label_namer=None) + def func_no_label(ax, x, y, ls="x", label=None, w="xyz"): + return f"x: {list(x)}, y: {list(y)}, ls: {ls}, w: {w}, label: {label}" + + data = {"a": [1, 2], "b": [8, 9], "w": "NOT"} + assert (func_no_label(None, "a", "b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: None") + assert (func_no_label(None, x="a", y="b", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: None") + assert (func_no_label(None, "a", "b", label="", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: ") + assert (func_no_label(None, "a", "b", label="text", data=data) == + "x: [1, 2], y: [8, 9], ls: x, w: xyz, label: text") + + +def test_more_args_than_pos_parameter(): + @_preprocess_data(replace_names=["x", "y"], label_namer="y") + def func(ax, x, y, z=1): + pass + + data = {"a": [1, 2], "b": [8, 9], "w": "NOT"} + with pytest.raises(TypeError): + func(None, "a", "b", "z", "z", data=data) + + +def test_docstring_addition(): + @_preprocess_data() + def funcy(ax, *args, **kwargs): + """ + Parameters + ---------- + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + """ + + assert re.search(r"all parameters also accept a string", funcy.__doc__) + assert not re.search(r"the following parameters", funcy.__doc__) + + @_preprocess_data(replace_names=[]) + def funcy(ax, x, y, z, bar=None): + """ + Parameters + ---------- + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + """ + + assert not re.search(r"all parameters also accept a string", funcy.__doc__) + assert not re.search(r"the following parameters", funcy.__doc__) + + @_preprocess_data(replace_names=["bar"]) + def funcy(ax, x, y, z, bar=None): + """ + Parameters + ---------- + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + """ + + assert not re.search(r"all parameters also accept a string", funcy.__doc__) + assert not re.search(r"the following parameters .*: \*bar\*\.", + funcy.__doc__) + + @_preprocess_data(replace_names=["x", "t"]) + def funcy(ax, x, y, z, t=None): + """ + Parameters + ---------- + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + """ + + assert not re.search(r"all parameters also accept a string", funcy.__doc__) + assert not re.search(r"the following parameters .*: \*x\*, \*t\*\.", + funcy.__doc__) + + +def test_data_parameter_replacement(): + """ + Test that the docstring contains the correct *data* parameter stub + for all methods that we run _preprocess_data() on. + """ + program = ( + "import logging; " + "logging.basicConfig(level=logging.DEBUG); " + "import matplotlib.pyplot as plt" + ) + cmd = [sys.executable, "-c", program] + completed_proc = subprocess_run_for_testing( + cmd, text=True, capture_output=True + ) + assert 'data parameter docstring error' not in completed_proc.stderr + + +class TestPlotTypes: + + plotters = [Axes.scatter, Axes.bar, Axes.plot] + + @pytest.mark.parametrize('plotter', plotters) + @check_figures_equal(extensions=['png']) + def test_dict_unpack(self, plotter, fig_test, fig_ref): + x = [1, 2, 3] + y = [4, 5, 6] + ddict = dict(zip(x, y)) + + plotter(fig_test.subplots(), + ddict.keys(), ddict.values()) + plotter(fig_ref.subplots(), x, y) + + @pytest.mark.parametrize('plotter', plotters) + @check_figures_equal(extensions=['png']) + def test_data_kwarg(self, plotter, fig_test, fig_ref): + x = [1, 2, 3] + y = [4, 5, 6] + + plotter(fig_test.subplots(), 'xval', 'yval', + data={'xval': x, 'yval': y}) + plotter(fig_ref.subplots(), x, y) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pyplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pyplot.py new file mode 100644 index 00000000..68a1de24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_pyplot.py @@ -0,0 +1,459 @@ +import difflib + +import numpy as np +import sys +from pathlib import Path + +import pytest + +import matplotlib as mpl +from matplotlib.testing import subprocess_run_for_testing +from matplotlib import pyplot as plt + + +def test_pyplot_up_to_date(tmpdir): + pytest.importorskip("black") + + gen_script = Path(mpl.__file__).parents[2] / "tools/boilerplate.py" + if not gen_script.exists(): + pytest.skip("boilerplate.py not found") + orig_contents = Path(plt.__file__).read_text() + plt_file = tmpdir.join('pyplot.py') + plt_file.write_text(orig_contents, 'utf-8') + + subprocess_run_for_testing( + [sys.executable, str(gen_script), str(plt_file)], + check=True) + new_contents = plt_file.read_text('utf-8') + + if orig_contents != new_contents: + diff_msg = '\n'.join( + difflib.unified_diff( + orig_contents.split('\n'), new_contents.split('\n'), + fromfile='found pyplot.py', + tofile='expected pyplot.py', + n=0, lineterm='')) + pytest.fail( + "pyplot.py is not up-to-date. Please run " + "'python tools/boilerplate.py' to update pyplot.py. " + "This needs to be done from an environment where your " + "current working copy is installed (e.g. 'pip install -e'd). " + "Here is a diff of unexpected differences:\n%s" % diff_msg + ) + + +def test_copy_docstring_and_deprecators(recwarn): + @mpl._api.rename_parameter("(version)", "old", "new") + @mpl._api.make_keyword_only("(version)", "kwo") + def func(new, kwo=None): + pass + + @plt._copy_docstring_and_deprecators(func) + def wrapper_func(new, kwo=None): + pass + + wrapper_func(None) + wrapper_func(new=None) + wrapper_func(None, kwo=None) + wrapper_func(new=None, kwo=None) + assert not recwarn + with pytest.warns(mpl.MatplotlibDeprecationWarning): + wrapper_func(old=None) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + wrapper_func(None, None) + + +def test_pyplot_box(): + fig, ax = plt.subplots() + plt.box(False) + assert not ax.get_frame_on() + plt.box(True) + assert ax.get_frame_on() + plt.box() + assert not ax.get_frame_on() + plt.box() + assert ax.get_frame_on() + + +def test_stackplot_smoke(): + # Small smoke test for stackplot (see #12405) + plt.stackplot([1, 2, 3], [1, 2, 3]) + + +def test_nrows_error(): + with pytest.raises(TypeError): + plt.subplot(nrows=1) + with pytest.raises(TypeError): + plt.subplot(ncols=1) + + +def test_ioff(): + plt.ion() + assert mpl.is_interactive() + with plt.ioff(): + assert not mpl.is_interactive() + assert mpl.is_interactive() + + plt.ioff() + assert not mpl.is_interactive() + with plt.ioff(): + assert not mpl.is_interactive() + assert not mpl.is_interactive() + + +def test_ion(): + plt.ioff() + assert not mpl.is_interactive() + with plt.ion(): + assert mpl.is_interactive() + assert not mpl.is_interactive() + + plt.ion() + assert mpl.is_interactive() + with plt.ion(): + assert mpl.is_interactive() + assert mpl.is_interactive() + + +def test_nested_ion_ioff(): + # initial state is interactive + plt.ion() + + # mixed ioff/ion + with plt.ioff(): + assert not mpl.is_interactive() + with plt.ion(): + assert mpl.is_interactive() + assert not mpl.is_interactive() + assert mpl.is_interactive() + + # redundant contexts + with plt.ioff(): + with plt.ioff(): + assert not mpl.is_interactive() + assert mpl.is_interactive() + + with plt.ion(): + plt.ioff() + assert mpl.is_interactive() + + # initial state is not interactive + plt.ioff() + + # mixed ioff/ion + with plt.ion(): + assert mpl.is_interactive() + with plt.ioff(): + assert not mpl.is_interactive() + assert mpl.is_interactive() + assert not mpl.is_interactive() + + # redundant contexts + with plt.ion(): + with plt.ion(): + assert mpl.is_interactive() + assert not mpl.is_interactive() + + with plt.ioff(): + plt.ion() + assert not mpl.is_interactive() + + +def test_close(): + try: + plt.close(1.1) + except TypeError as e: + assert str(e) == "close() argument must be a Figure, an int, " \ + "a string, or None, not <class 'float'>" + + +def test_subplot_reuse(): + ax1 = plt.subplot(121) + assert ax1 is plt.gca() + ax2 = plt.subplot(122) + assert ax2 is plt.gca() + ax3 = plt.subplot(121) + assert ax1 is plt.gca() + assert ax1 is ax3 + + +def test_axes_kwargs(): + # plt.axes() always creates new axes, even if axes kwargs differ. + plt.figure() + ax = plt.axes() + ax1 = plt.axes() + assert ax is not None + assert ax1 is not ax + plt.close() + + plt.figure() + ax = plt.axes(projection='polar') + ax1 = plt.axes(projection='polar') + assert ax is not None + assert ax1 is not ax + plt.close() + + plt.figure() + ax = plt.axes(projection='polar') + ax1 = plt.axes() + assert ax is not None + assert ax1.name == 'rectilinear' + assert ax1 is not ax + plt.close() + + +def test_subplot_replace_projection(): + # plt.subplot() searches for axes with the same subplot spec, and if one + # exists, and the kwargs match returns it, create a new one if they do not + fig = plt.figure() + ax = plt.subplot(1, 2, 1) + ax1 = plt.subplot(1, 2, 1) + ax2 = plt.subplot(1, 2, 2) + ax3 = plt.subplot(1, 2, 1, projection='polar') + ax4 = plt.subplot(1, 2, 1, projection='polar') + assert ax is not None + assert ax1 is ax + assert ax2 is not ax + assert ax3 is not ax + assert ax3 is ax4 + + assert ax in fig.axes + assert ax2 in fig.axes + assert ax3 in fig.axes + + assert ax.name == 'rectilinear' + assert ax2.name == 'rectilinear' + assert ax3.name == 'polar' + + +def test_subplot_kwarg_collision(): + ax1 = plt.subplot(projection='polar', theta_offset=0) + ax2 = plt.subplot(projection='polar', theta_offset=0) + assert ax1 is ax2 + ax1.remove() + ax3 = plt.subplot(projection='polar', theta_offset=1) + assert ax1 is not ax3 + assert ax1 not in plt.gcf().axes + + +def test_gca(): + # plt.gca() returns an existing axes, unless there were no axes. + plt.figure() + ax = plt.gca() + ax1 = plt.gca() + assert ax is not None + assert ax1 is ax + plt.close() + + +def test_subplot_projection_reuse(): + # create an Axes + ax1 = plt.subplot(111) + # check that it is current + assert ax1 is plt.gca() + # make sure we get it back if we ask again + assert ax1 is plt.subplot(111) + # remove it + ax1.remove() + # create a polar plot + ax2 = plt.subplot(111, projection='polar') + assert ax2 is plt.gca() + # this should have deleted the first axes + assert ax1 not in plt.gcf().axes + # assert we get it back if no extra parameters passed + assert ax2 is plt.subplot(111) + ax2.remove() + # now check explicitly setting the projection to rectilinear + # makes a new axes + ax3 = plt.subplot(111, projection='rectilinear') + assert ax3 is plt.gca() + assert ax3 is not ax2 + assert ax2 not in plt.gcf().axes + + +def test_subplot_polar_normalization(): + ax1 = plt.subplot(111, projection='polar') + ax2 = plt.subplot(111, polar=True) + ax3 = plt.subplot(111, polar=True, projection='polar') + assert ax1 is ax2 + assert ax1 is ax3 + + with pytest.raises(ValueError, + match="polar=True, yet projection='3d'"): + ax2 = plt.subplot(111, polar=True, projection='3d') + + +def test_subplot_change_projection(): + created_axes = set() + ax = plt.subplot() + created_axes.add(ax) + projections = ('aitoff', 'hammer', 'lambert', 'mollweide', + 'polar', 'rectilinear', '3d') + for proj in projections: + ax.remove() + ax = plt.subplot(projection=proj) + assert ax is plt.subplot() + assert ax.name == proj + created_axes.add(ax) + # Check that each call created a new Axes. + assert len(created_axes) == 1 + len(projections) + + +def test_polar_second_call(): + # the first call creates the axes with polar projection + ln1, = plt.polar(0., 1., 'ro') + assert isinstance(ln1, mpl.lines.Line2D) + # the second call should reuse the existing axes + ln2, = plt.polar(1.57, .5, 'bo') + assert isinstance(ln2, mpl.lines.Line2D) + assert ln1.axes is ln2.axes + + +def test_fallback_position(): + # check that position kwarg works if rect not supplied + axref = plt.axes([0.2, 0.2, 0.5, 0.5]) + axtest = plt.axes(position=[0.2, 0.2, 0.5, 0.5]) + np.testing.assert_allclose(axtest.bbox.get_points(), + axref.bbox.get_points()) + + # check that position kwarg ignored if rect is supplied + axref = plt.axes([0.2, 0.2, 0.5, 0.5]) + axtest = plt.axes([0.2, 0.2, 0.5, 0.5], position=[0.1, 0.1, 0.8, 0.8]) + np.testing.assert_allclose(axtest.bbox.get_points(), + axref.bbox.get_points()) + + +def test_set_current_figure_via_subfigure(): + fig1 = plt.figure() + subfigs = fig1.subfigures(2) + + plt.figure() + assert plt.gcf() != fig1 + + current = plt.figure(subfigs[1]) + assert plt.gcf() == fig1 + assert current == fig1 + + +def test_set_current_axes_on_subfigure(): + fig = plt.figure() + subfigs = fig.subfigures(2) + + ax = subfigs[0].subplots(1, squeeze=True) + subfigs[1].subplots(1, squeeze=True) + + assert plt.gca() != ax + plt.sca(ax) + assert plt.gca() == ax + + +def test_pylab_integration(): + IPython = pytest.importorskip("IPython") + mpl.testing.subprocess_run_helper( + IPython.start_ipython, + "--pylab", + "-c", + ";".join(( + "import matplotlib.pyplot as plt", + "assert plt._REPL_DISPLAYHOOK == plt._ReplDisplayHook.IPYTHON", + )), + timeout=60, + ) + + +def test_doc_pyplot_summary(): + """Test that pyplot_summary lists all the plot functions.""" + pyplot_docs = Path(__file__).parent / '../../../doc/api/pyplot_summary.rst' + if not pyplot_docs.exists(): + pytest.skip("Documentation sources not available") + + def extract_documented_functions(lines): + """ + Return a list of all the functions that are mentioned in the + autosummary blocks contained in *lines*. + + An autosummary block looks like this:: + + .. autosummary:: + :toctree: _as_gen + :template: autosummary.rst + :nosignatures: + + plot + plot_date + + """ + functions = [] + in_autosummary = False + for line in lines: + if not in_autosummary: + if line.startswith(".. autosummary::"): + in_autosummary = True + else: + if not line or line.startswith(" :"): + # empty line or autosummary parameter + continue + if not line[0].isspace(): + # no more indentation: end of autosummary block + in_autosummary = False + continue + functions.append(line.strip()) + return functions + + lines = pyplot_docs.read_text().split("\n") + doc_functions = set(extract_documented_functions(lines)) + plot_commands = set(plt._get_pyplot_commands()) + missing = plot_commands.difference(doc_functions) + if missing: + raise AssertionError( + f"The following pyplot functions are not listed in the " + f"documentation. Please add them to doc/api/pyplot_summary.rst: " + f"{missing!r}") + extra = doc_functions.difference(plot_commands) + if extra: + raise AssertionError( + f"The following functions are listed in the pyplot documentation, " + f"but they do not exist in pyplot. " + f"Please remove them from doc/api/pyplot_summary.rst: {extra!r}") + + +def test_minor_ticks(): + plt.figure() + plt.plot(np.arange(1, 10)) + tick_pos, tick_labels = plt.xticks(minor=True) + assert np.all(tick_labels == np.array([], dtype=np.float64)) + assert tick_labels == [] + + plt.yticks(ticks=[3.5, 6.5], labels=["a", "b"], minor=True) + ax = plt.gca() + tick_pos = ax.get_yticks(minor=True) + tick_labels = ax.get_yticklabels(minor=True) + assert np.all(tick_pos == np.array([3.5, 6.5])) + assert [l.get_text() for l in tick_labels] == ['a', 'b'] + + +def test_switch_backend_no_close(): + plt.switch_backend('agg') + fig = plt.figure() + fig = plt.figure() + assert len(plt.get_fignums()) == 2 + plt.switch_backend('agg') + assert len(plt.get_fignums()) == 2 + with pytest.warns(mpl.MatplotlibDeprecationWarning): + plt.switch_backend('svg') + assert len(plt.get_fignums()) == 0 + + +def figure_hook_example(figure): + figure._test_was_here = True + + +def test_figure_hook(): + + test_rc = { + 'figure.hooks': ['matplotlib.tests.test_pyplot:figure_hook_example'] + } + with mpl.rc_context(test_rc): + fig = plt.figure() + + assert fig._test_was_here diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_quiver.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_quiver.py new file mode 100644 index 00000000..6e032a54 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_quiver.py @@ -0,0 +1,279 @@ +import platform +import sys + +import numpy as np +import pytest + +from matplotlib import pyplot as plt +from matplotlib.testing.decorators import image_comparison + + +def draw_quiver(ax, **kwargs): + X, Y = np.meshgrid(np.arange(0, 2 * np.pi, 1), + np.arange(0, 2 * np.pi, 1)) + U = np.cos(X) + V = np.sin(Y) + + Q = ax.quiver(U, V, **kwargs) + return Q + + +@pytest.mark.skipif(platform.python_implementation() != 'CPython', + reason='Requires CPython') +def test_quiver_memory_leak(): + fig, ax = plt.subplots() + + Q = draw_quiver(ax) + ttX = Q.X + Q.remove() + + del Q + + assert sys.getrefcount(ttX) == 2 + + +@pytest.mark.skipif(platform.python_implementation() != 'CPython', + reason='Requires CPython') +def test_quiver_key_memory_leak(): + fig, ax = plt.subplots() + + Q = draw_quiver(ax) + + qk = ax.quiverkey(Q, 0.5, 0.92, 2, r'$2 \frac{m}{s}$', + labelpos='W', + fontproperties={'weight': 'bold'}) + assert sys.getrefcount(qk) == 3 + qk.remove() + assert sys.getrefcount(qk) == 2 + + +def test_quiver_number_of_args(): + X = [1, 2] + with pytest.raises( + TypeError, + match='takes from 2 to 5 positional arguments but 1 were given'): + plt.quiver(X) + with pytest.raises( + TypeError, + match='takes from 2 to 5 positional arguments but 6 were given'): + plt.quiver(X, X, X, X, X, X) + + +def test_quiver_arg_sizes(): + X2 = [1, 2] + X3 = [1, 2, 3] + with pytest.raises( + ValueError, match=('X and Y must be the same size, but ' + 'X.size is 2 and Y.size is 3.')): + plt.quiver(X2, X3, X2, X2) + with pytest.raises( + ValueError, match=('Argument U has a size 3 which does not match ' + '2, the number of arrow positions')): + plt.quiver(X2, X2, X3, X2) + with pytest.raises( + ValueError, match=('Argument V has a size 3 which does not match ' + '2, the number of arrow positions')): + plt.quiver(X2, X2, X2, X3) + with pytest.raises( + ValueError, match=('Argument C has a size 3 which does not match ' + '2, the number of arrow positions')): + plt.quiver(X2, X2, X2, X2, X3) + + +def test_no_warnings(): + fig, ax = plt.subplots() + X, Y = np.meshgrid(np.arange(15), np.arange(10)) + U = V = np.ones_like(X) + phi = (np.random.rand(15, 10) - .5) * 150 + ax.quiver(X, Y, U, V, angles=phi) + fig.canvas.draw() # Check that no warning is emitted. + + +def test_zero_headlength(): + # Based on report by Doug McNeil: + # https://discourse.matplotlib.org/t/quiver-warnings/16722 + fig, ax = plt.subplots() + X, Y = np.meshgrid(np.arange(10), np.arange(10)) + U, V = np.cos(X), np.sin(Y) + ax.quiver(U, V, headlength=0, headaxislength=0) + fig.canvas.draw() # Check that no warning is emitted. + + +@image_comparison(['quiver_animated_test_image.png']) +def test_quiver_animate(): + # Tests fix for #2616 + fig, ax = plt.subplots() + Q = draw_quiver(ax, animated=True) + ax.quiverkey(Q, 0.5, 0.92, 2, r'$2 \frac{m}{s}$', + labelpos='W', fontproperties={'weight': 'bold'}) + + +@image_comparison(['quiver_with_key_test_image.png']) +def test_quiver_with_key(): + fig, ax = plt.subplots() + ax.margins(0.1) + Q = draw_quiver(ax) + ax.quiverkey(Q, 0.5, 0.95, 2, + r'$2\, \mathrm{m}\, \mathrm{s}^{-1}$', + angle=-10, + coordinates='figure', + labelpos='W', + fontproperties={'weight': 'bold', 'size': 'large'}) + + +@image_comparison(['quiver_single_test_image.png'], remove_text=True) +def test_quiver_single(): + fig, ax = plt.subplots() + ax.margins(0.1) + ax.quiver([1], [1], [2], [2]) + + +def test_quiver_copy(): + fig, ax = plt.subplots() + uv = dict(u=np.array([1.1]), v=np.array([2.0])) + q0 = ax.quiver([1], [1], uv['u'], uv['v']) + uv['v'][0] = 0 + assert q0.V[0] == 2.0 + + +@image_comparison(['quiver_key_pivot.png'], remove_text=True) +def test_quiver_key_pivot(): + fig, ax = plt.subplots() + + u, v = np.mgrid[0:2*np.pi:10j, 0:2*np.pi:10j] + + q = ax.quiver(np.sin(u), np.cos(v)) + ax.set_xlim(-2, 11) + ax.set_ylim(-2, 11) + ax.quiverkey(q, 0.5, 1, 1, 'N', labelpos='N') + ax.quiverkey(q, 1, 0.5, 1, 'E', labelpos='E') + ax.quiverkey(q, 0.5, 0, 1, 'S', labelpos='S') + ax.quiverkey(q, 0, 0.5, 1, 'W', labelpos='W') + + +@image_comparison(['quiver_key_xy.png'], remove_text=True) +def test_quiver_key_xy(): + # With scale_units='xy', ensure quiverkey still matches its quiver. + # Note that the quiver and quiverkey lengths depend on the axes aspect + # ratio, and that with angles='xy' their angles also depend on the axes + # aspect ratio. + X = np.arange(8) + Y = np.zeros(8) + angles = X * (np.pi / 4) + uv = np.exp(1j * angles) + U = uv.real + V = uv.imag + fig, axs = plt.subplots(2) + for ax, angle_str in zip(axs, ('uv', 'xy')): + ax.set_xlim(-1, 8) + ax.set_ylim(-0.2, 0.2) + q = ax.quiver(X, Y, U, V, pivot='middle', + units='xy', width=0.05, + scale=2, scale_units='xy', + angles=angle_str) + for x, angle in zip((0.2, 0.5, 0.8), (0, 45, 90)): + ax.quiverkey(q, X=x, Y=0.8, U=1, angle=angle, label='', color='b') + + +@image_comparison(['barbs_test_image.png'], remove_text=True) +def test_barbs(): + x = np.linspace(-5, 5, 5) + X, Y = np.meshgrid(x, x) + U, V = 12*X, 12*Y + fig, ax = plt.subplots() + ax.barbs(X, Y, U, V, np.hypot(U, V), fill_empty=True, rounding=False, + sizes=dict(emptybarb=0.25, spacing=0.2, height=0.3), + cmap='viridis') + + +@image_comparison(['barbs_pivot_test_image.png'], remove_text=True) +def test_barbs_pivot(): + x = np.linspace(-5, 5, 5) + X, Y = np.meshgrid(x, x) + U, V = 12*X, 12*Y + fig, ax = plt.subplots() + ax.barbs(X, Y, U, V, fill_empty=True, rounding=False, pivot=1.7, + sizes=dict(emptybarb=0.25, spacing=0.2, height=0.3)) + ax.scatter(X, Y, s=49, c='black') + + +@image_comparison(['barbs_test_flip.png'], remove_text=True) +def test_barbs_flip(): + """Test barbs with an array for flip_barb.""" + x = np.linspace(-5, 5, 5) + X, Y = np.meshgrid(x, x) + U, V = 12*X, 12*Y + fig, ax = plt.subplots() + ax.barbs(X, Y, U, V, fill_empty=True, rounding=False, pivot=1.7, + sizes=dict(emptybarb=0.25, spacing=0.2, height=0.3), + flip_barb=Y < 0) + + +def test_barb_copy(): + fig, ax = plt.subplots() + u = np.array([1.1]) + v = np.array([2.2]) + b0 = ax.barbs([1], [1], u, v) + u[0] = 0 + assert b0.u[0] == 1.1 + v[0] = 0 + assert b0.v[0] == 2.2 + + +def test_bad_masked_sizes(): + """Test error handling when given differing sized masked arrays.""" + x = np.arange(3) + y = np.arange(3) + u = np.ma.array(15. * np.ones((4,))) + v = np.ma.array(15. * np.ones_like(u)) + u[1] = np.ma.masked + v[1] = np.ma.masked + fig, ax = plt.subplots() + with pytest.raises(ValueError): + ax.barbs(x, y, u, v) + + +def test_angles_and_scale(): + # angles array + scale_units kwarg + fig, ax = plt.subplots() + X, Y = np.meshgrid(np.arange(15), np.arange(10)) + U = V = np.ones_like(X) + phi = (np.random.rand(15, 10) - .5) * 150 + ax.quiver(X, Y, U, V, angles=phi, scale_units='xy') + + +@image_comparison(['quiver_xy.png'], remove_text=True) +def test_quiver_xy(): + # simple arrow pointing from SW to NE + fig, ax = plt.subplots(subplot_kw=dict(aspect='equal')) + ax.quiver(0, 0, 1, 1, angles='xy', scale_units='xy', scale=1) + ax.set_xlim(0, 1.1) + ax.set_ylim(0, 1.1) + ax.grid() + + +def test_quiverkey_angles(): + # Check that only a single arrow is plotted for a quiverkey when an array + # of angles is given to the original quiver plot + fig, ax = plt.subplots() + + X, Y = np.meshgrid(np.arange(2), np.arange(2)) + U = V = angles = np.ones_like(X) + + q = ax.quiver(X, Y, U, V, angles=angles) + qk = ax.quiverkey(q, 1, 1, 2, 'Label') + # The arrows are only created when the key is drawn + fig.canvas.draw() + assert len(qk.verts) == 1 + + +def test_quiver_setuvc_numbers(): + """Check that it is possible to set all arrow UVC to the same numbers""" + + fig, ax = plt.subplots() + + X, Y = np.meshgrid(np.arange(2), np.arange(2)) + U = V = np.ones_like(X) + + q = ax.quiver(X, Y, U, V) + q.set_UVC(0, 1) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_rcparams.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_rcparams.py new file mode 100644 index 00000000..515068c4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_rcparams.py @@ -0,0 +1,630 @@ +import copy +import os +from pathlib import Path +import subprocess +import sys +from unittest import mock + +from cycler import cycler, Cycler +import pytest + +import matplotlib as mpl +from matplotlib import _api, _c_internal_utils +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import numpy as np +from matplotlib.rcsetup import ( + validate_bool, + validate_color, + validate_colorlist, + _validate_color_or_linecolor, + validate_cycler, + validate_float, + validate_fontstretch, + validate_fontweight, + validate_hatch, + validate_hist_bins, + validate_int, + validate_markevery, + validate_stringlist, + _validate_linestyle, + _listify_validator) + + +def test_rcparams(tmpdir): + mpl.rc('text', usetex=False) + mpl.rc('lines', linewidth=22) + + usetex = mpl.rcParams['text.usetex'] + linewidth = mpl.rcParams['lines.linewidth'] + + rcpath = Path(tmpdir) / 'test_rcparams.rc' + rcpath.write_text('lines.linewidth: 33', encoding='utf-8') + + # test context given dictionary + with mpl.rc_context(rc={'text.usetex': not usetex}): + assert mpl.rcParams['text.usetex'] == (not usetex) + assert mpl.rcParams['text.usetex'] == usetex + + # test context given filename (mpl.rc sets linewidth to 33) + with mpl.rc_context(fname=rcpath): + assert mpl.rcParams['lines.linewidth'] == 33 + assert mpl.rcParams['lines.linewidth'] == linewidth + + # test context given filename and dictionary + with mpl.rc_context(fname=rcpath, rc={'lines.linewidth': 44}): + assert mpl.rcParams['lines.linewidth'] == 44 + assert mpl.rcParams['lines.linewidth'] == linewidth + + # test context as decorator (and test reusability, by calling func twice) + @mpl.rc_context({'lines.linewidth': 44}) + def func(): + assert mpl.rcParams['lines.linewidth'] == 44 + + func() + func() + + # test rc_file + mpl.rc_file(rcpath) + assert mpl.rcParams['lines.linewidth'] == 33 + + +def test_RcParams_class(): + rc = mpl.RcParams({'font.cursive': ['Apple Chancery', + 'Textile', + 'Zapf Chancery', + 'cursive'], + 'font.family': 'sans-serif', + 'font.weight': 'normal', + 'font.size': 12}) + + expected_repr = """ +RcParams({'font.cursive': ['Apple Chancery', + 'Textile', + 'Zapf Chancery', + 'cursive'], + 'font.family': ['sans-serif'], + 'font.size': 12.0, + 'font.weight': 'normal'})""".lstrip() + + assert expected_repr == repr(rc) + + expected_str = """ +font.cursive: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'] +font.family: ['sans-serif'] +font.size: 12.0 +font.weight: normal""".lstrip() + + assert expected_str == str(rc) + + # test the find_all functionality + assert ['font.cursive', 'font.size'] == sorted(rc.find_all('i[vz]')) + assert ['font.family'] == list(rc.find_all('family')) + + +def test_rcparams_update(): + rc = mpl.RcParams({'figure.figsize': (3.5, 42)}) + bad_dict = {'figure.figsize': (3.5, 42, 1)} + # make sure validation happens on input + with pytest.raises(ValueError), \ + pytest.warns(UserWarning, match="validate"): + rc.update(bad_dict) + + +def test_rcparams_init(): + with pytest.raises(ValueError), \ + pytest.warns(UserWarning, match="validate"): + mpl.RcParams({'figure.figsize': (3.5, 42, 1)}) + + +def test_nargs_cycler(): + from matplotlib.rcsetup import cycler as ccl + with pytest.raises(TypeError, match='3 were given'): + # cycler() takes 0-2 arguments. + ccl(ccl(color=list('rgb')), 2, 3) + + +def test_Bug_2543(): + # Test that it possible to add all values to itself / deepcopy + # https://github.com/matplotlib/matplotlib/issues/2543 + # We filter warnings at this stage since a number of them are raised + # for deprecated rcparams as they should. We don't want these in the + # printed in the test suite. + with _api.suppress_matplotlib_deprecation_warning(): + with mpl.rc_context(): + _copy = mpl.rcParams.copy() + for key in _copy: + mpl.rcParams[key] = _copy[key] + with mpl.rc_context(): + copy.deepcopy(mpl.rcParams) + with pytest.raises(ValueError): + validate_bool(None) + with pytest.raises(ValueError): + with mpl.rc_context(): + mpl.rcParams['svg.fonttype'] = True + + +legend_color_tests = [ + ('face', {'color': 'r'}, mcolors.to_rgba('r')), + ('face', {'color': 'inherit', 'axes.facecolor': 'r'}, + mcolors.to_rgba('r')), + ('face', {'color': 'g', 'axes.facecolor': 'r'}, mcolors.to_rgba('g')), + ('edge', {'color': 'r'}, mcolors.to_rgba('r')), + ('edge', {'color': 'inherit', 'axes.edgecolor': 'r'}, + mcolors.to_rgba('r')), + ('edge', {'color': 'g', 'axes.facecolor': 'r'}, mcolors.to_rgba('g')) +] +legend_color_test_ids = [ + 'same facecolor', + 'inherited facecolor', + 'different facecolor', + 'same edgecolor', + 'inherited edgecolor', + 'different facecolor', +] + + +@pytest.mark.parametrize('color_type, param_dict, target', legend_color_tests, + ids=legend_color_test_ids) +def test_legend_colors(color_type, param_dict, target): + param_dict[f'legend.{color_type}color'] = param_dict.pop('color') + get_func = f'get_{color_type}color' + + with mpl.rc_context(param_dict): + _, ax = plt.subplots() + ax.plot(range(3), label='test') + leg = ax.legend() + assert getattr(leg.legendPatch, get_func)() == target + + +def test_mfc_rcparams(): + mpl.rcParams['lines.markerfacecolor'] = 'r' + ln = mpl.lines.Line2D([1, 2], [1, 2]) + assert ln.get_markerfacecolor() == 'r' + + +def test_mec_rcparams(): + mpl.rcParams['lines.markeredgecolor'] = 'r' + ln = mpl.lines.Line2D([1, 2], [1, 2]) + assert ln.get_markeredgecolor() == 'r' + + +def test_axes_titlecolor_rcparams(): + mpl.rcParams['axes.titlecolor'] = 'r' + _, ax = plt.subplots() + title = ax.set_title("Title") + assert title.get_color() == 'r' + + +def test_Issue_1713(tmpdir): + rcpath = Path(tmpdir) / 'test_rcparams.rc' + rcpath.write_text('timezone: UTC', encoding='utf-8') + with mock.patch('locale.getpreferredencoding', return_value='UTF-32-BE'): + rc = mpl.rc_params_from_file(rcpath, True, False) + assert rc.get('timezone') == 'UTC' + + +def test_animation_frame_formats(): + # Animation frame_format should allow any of the following + # if any of these are not allowed, an exception will be raised + # test for gh issue #17908 + for fmt in ['png', 'jpeg', 'tiff', 'raw', 'rgba', 'ppm', + 'sgi', 'bmp', 'pbm', 'svg']: + mpl.rcParams['animation.frame_format'] = fmt + + +def generate_validator_testcases(valid): + validation_tests = ( + {'validator': validate_bool, + 'success': (*((_, True) for _ in + ('t', 'y', 'yes', 'on', 'true', '1', 1, True)), + *((_, False) for _ in + ('f', 'n', 'no', 'off', 'false', '0', 0, False))), + 'fail': ((_, ValueError) + for _ in ('aardvark', 2, -1, [], )) + }, + {'validator': validate_stringlist, + 'success': (('', []), + ('a,b', ['a', 'b']), + ('aardvark', ['aardvark']), + ('aardvark, ', ['aardvark']), + ('aardvark, ,', ['aardvark']), + (['a', 'b'], ['a', 'b']), + (('a', 'b'), ['a', 'b']), + (iter(['a', 'b']), ['a', 'b']), + (np.array(['a', 'b']), ['a', 'b']), + ), + 'fail': ((set(), ValueError), + (1, ValueError), + ) + }, + {'validator': _listify_validator(validate_int, n=2), + 'success': ((_, [1, 2]) + for _ in ('1, 2', [1.5, 2.5], [1, 2], + (1, 2), np.array((1, 2)))), + 'fail': ((_, ValueError) + for _ in ('aardvark', ('a', 1), + (1, 2, 3) + )) + }, + {'validator': _listify_validator(validate_float, n=2), + 'success': ((_, [1.5, 2.5]) + for _ in ('1.5, 2.5', [1.5, 2.5], [1.5, 2.5], + (1.5, 2.5), np.array((1.5, 2.5)))), + 'fail': ((_, ValueError) + for _ in ('aardvark', ('a', 1), (1, 2, 3), (None, ), None)) + }, + {'validator': validate_cycler, + 'success': (('cycler("color", "rgb")', + cycler("color", 'rgb')), + (cycler('linestyle', ['-', '--']), + cycler('linestyle', ['-', '--'])), + ("""(cycler("color", ["r", "g", "b"]) + + cycler("mew", [2, 3, 5]))""", + (cycler("color", 'rgb') + + cycler("markeredgewidth", [2, 3, 5]))), + ("cycler(c='rgb', lw=[1, 2, 3])", + cycler('color', 'rgb') + cycler('linewidth', [1, 2, 3])), + ("cycler('c', 'rgb') * cycler('linestyle', ['-', '--'])", + (cycler('color', 'rgb') * + cycler('linestyle', ['-', '--']))), + (cycler('ls', ['-', '--']), + cycler('linestyle', ['-', '--'])), + (cycler(mew=[2, 5]), + cycler('markeredgewidth', [2, 5])), + ), + # This is *so* incredibly important: validate_cycler() eval's + # an arbitrary string! I think I have it locked down enough, + # and that is what this is testing. + # TODO: Note that these tests are actually insufficient, as it may + # be that they raised errors, but still did an action prior to + # raising the exception. We should devise some additional tests + # for that... + 'fail': ((4, ValueError), # Gotta be a string or Cycler object + ('cycler("bleh, [])', ValueError), # syntax error + ('Cycler("linewidth", [1, 2, 3])', + ValueError), # only 'cycler()' function is allowed + # do not allow dunder in string literals + ("cycler('c', [j.__class__(j) for j in ['r', 'b']])", + ValueError), + ("cycler('c', [j. __class__(j) for j in ['r', 'b']])", + ValueError), + ("cycler('c', [j.\t__class__(j) for j in ['r', 'b']])", + ValueError), + ("cycler('c', [j.\u000c__class__(j) for j in ['r', 'b']])", + ValueError), + ("cycler('c', [j.__class__(j).lower() for j in ['r', 'b']])", + ValueError), + ('1 + 2', ValueError), # doesn't produce a Cycler object + ('os.system("echo Gotcha")', ValueError), # os not available + ('import os', ValueError), # should not be able to import + ('def badjuju(a): return a; badjuju(cycler("color", "rgb"))', + ValueError), # Should not be able to define anything + # even if it does return a cycler + ('cycler("waka", [1, 2, 3])', ValueError), # not a property + ('cycler(c=[1, 2, 3])', ValueError), # invalid values + ("cycler(lw=['a', 'b', 'c'])", ValueError), # invalid values + (cycler('waka', [1, 3, 5]), ValueError), # not a property + (cycler('color', ['C1', 'r', 'g']), ValueError) # no CN + ) + }, + {'validator': validate_hatch, + 'success': (('--|', '--|'), ('\\oO', '\\oO'), + ('/+*/.x', '/+*/.x'), ('', '')), + 'fail': (('--_', ValueError), + (8, ValueError), + ('X', ValueError)), + }, + {'validator': validate_colorlist, + 'success': (('r,g,b', ['r', 'g', 'b']), + (['r', 'g', 'b'], ['r', 'g', 'b']), + ('r, ,', ['r']), + (['', 'g', 'blue'], ['g', 'blue']), + ([np.array([1, 0, 0]), np.array([0, 1, 0])], + np.array([[1, 0, 0], [0, 1, 0]])), + (np.array([[1, 0, 0], [0, 1, 0]]), + np.array([[1, 0, 0], [0, 1, 0]])), + ), + 'fail': (('fish', ValueError), + ), + }, + {'validator': validate_color, + 'success': (('None', 'none'), + ('none', 'none'), + ('AABBCC', '#AABBCC'), # RGB hex code + ('AABBCC00', '#AABBCC00'), # RGBA hex code + ('tab:blue', 'tab:blue'), # named color + ('C12', 'C12'), # color from cycle + ('(0, 1, 0)', (0.0, 1.0, 0.0)), # RGB tuple + ((0, 1, 0), (0, 1, 0)), # non-string version + ('(0, 1, 0, 1)', (0.0, 1.0, 0.0, 1.0)), # RGBA tuple + ((0, 1, 0, 1), (0, 1, 0, 1)), # non-string version + ), + 'fail': (('tab:veryblue', ValueError), # invalid name + ('(0, 1)', ValueError), # tuple with length < 3 + ('(0, 1, 0, 1, 0)', ValueError), # tuple with length > 4 + ('(0, 1, none)', ValueError), # cannot cast none to float + ('(0, 1, "0.5")', ValueError), # last one not a float + ), + }, + {'validator': _validate_color_or_linecolor, + 'success': (('linecolor', 'linecolor'), + ('markerfacecolor', 'markerfacecolor'), + ('mfc', 'markerfacecolor'), + ('markeredgecolor', 'markeredgecolor'), + ('mec', 'markeredgecolor') + ), + 'fail': (('line', ValueError), + ('marker', ValueError) + ) + }, + {'validator': validate_hist_bins, + 'success': (('auto', 'auto'), + ('fd', 'fd'), + ('10', 10), + ('1, 2, 3', [1, 2, 3]), + ([1, 2, 3], [1, 2, 3]), + (np.arange(15), np.arange(15)) + ), + 'fail': (('aardvark', ValueError), + ) + }, + {'validator': validate_markevery, + 'success': ((None, None), + (1, 1), + (0.1, 0.1), + ((1, 1), (1, 1)), + ((0.1, 0.1), (0.1, 0.1)), + ([1, 2, 3], [1, 2, 3]), + (slice(2), slice(None, 2, None)), + (slice(1, 2, 3), slice(1, 2, 3)) + ), + 'fail': (((1, 2, 3), TypeError), + ([1, 2, 0.3], TypeError), + (['a', 2, 3], TypeError), + ([1, 2, 'a'], TypeError), + ((0.1, 0.2, 0.3), TypeError), + ((0.1, 2, 3), TypeError), + ((1, 0.2, 0.3), TypeError), + ((1, 0.1), TypeError), + ((0.1, 1), TypeError), + (('abc'), TypeError), + ((1, 'a'), TypeError), + ((0.1, 'b'), TypeError), + (('a', 1), TypeError), + (('a', 0.1), TypeError), + ('abc', TypeError), + ('a', TypeError), + (object(), TypeError) + ) + }, + {'validator': _validate_linestyle, + 'success': (('-', '-'), ('solid', 'solid'), + ('--', '--'), ('dashed', 'dashed'), + ('-.', '-.'), ('dashdot', 'dashdot'), + (':', ':'), ('dotted', 'dotted'), + ('', ''), (' ', ' '), + ('None', 'none'), ('none', 'none'), + ('DoTtEd', 'dotted'), # case-insensitive + ('1, 3', (0, (1, 3))), + ([1.23, 456], (0, [1.23, 456.0])), + ([1, 2, 3, 4], (0, [1.0, 2.0, 3.0, 4.0])), + ((0, [1, 2]), (0, [1, 2])), + ((-1, [1, 2]), (-1, [1, 2])), + ), + 'fail': (('aardvark', ValueError), # not a valid string + (b'dotted', ValueError), + ('dotted'.encode('utf-16'), ValueError), + ([1, 2, 3], ValueError), # sequence with odd length + (1.23, ValueError), # not a sequence + (("a", [1, 2]), ValueError), # wrong explicit offset + ((None, [1, 2]), ValueError), # wrong explicit offset + ((1, [1, 2, 3]), ValueError), # odd length sequence + (([1, 2], 1), ValueError), # inverted offset/onoff + ) + }, + ) + + for validator_dict in validation_tests: + validator = validator_dict['validator'] + if valid: + for arg, target in validator_dict['success']: + yield validator, arg, target + else: + for arg, error_type in validator_dict['fail']: + yield validator, arg, error_type + + +@pytest.mark.parametrize('validator, arg, target', + generate_validator_testcases(True)) +def test_validator_valid(validator, arg, target): + res = validator(arg) + if isinstance(target, np.ndarray): + np.testing.assert_equal(res, target) + elif not isinstance(target, Cycler): + assert res == target + else: + # Cyclers can't simply be asserted equal. They don't implement __eq__ + assert list(res) == list(target) + + +@pytest.mark.parametrize('validator, arg, exception_type', + generate_validator_testcases(False)) +def test_validator_invalid(validator, arg, exception_type): + with pytest.raises(exception_type): + validator(arg) + + +@pytest.mark.parametrize('weight, parsed_weight', [ + ('bold', 'bold'), + ('BOLD', ValueError), # weight is case-sensitive + (100, 100), + ('100', 100), + (np.array(100), 100), + # fractional fontweights are not defined. This should actually raise a + # ValueError, but historically did not. + (20.6, 20), + ('20.6', ValueError), + ([100], ValueError), +]) +def test_validate_fontweight(weight, parsed_weight): + if parsed_weight is ValueError: + with pytest.raises(ValueError): + validate_fontweight(weight) + else: + assert validate_fontweight(weight) == parsed_weight + + +@pytest.mark.parametrize('stretch, parsed_stretch', [ + ('expanded', 'expanded'), + ('EXPANDED', ValueError), # stretch is case-sensitive + (100, 100), + ('100', 100), + (np.array(100), 100), + # fractional fontweights are not defined. This should actually raise a + # ValueError, but historically did not. + (20.6, 20), + ('20.6', ValueError), + ([100], ValueError), +]) +def test_validate_fontstretch(stretch, parsed_stretch): + if parsed_stretch is ValueError: + with pytest.raises(ValueError): + validate_fontstretch(stretch) + else: + assert validate_fontstretch(stretch) == parsed_stretch + + +def test_keymaps(): + key_list = [k for k in mpl.rcParams if 'keymap' in k] + for k in key_list: + assert isinstance(mpl.rcParams[k], list) + + +def test_no_backend_reset_rccontext(): + assert mpl.rcParams['backend'] != 'module://aardvark' + with mpl.rc_context(): + mpl.rcParams['backend'] = 'module://aardvark' + assert mpl.rcParams['backend'] == 'module://aardvark' + + +def test_rcparams_reset_after_fail(): + # There was previously a bug that meant that if rc_context failed and + # raised an exception due to issues in the supplied rc parameters, the + # global rc parameters were left in a modified state. + with mpl.rc_context(rc={'text.usetex': False}): + assert mpl.rcParams['text.usetex'] is False + with pytest.raises(KeyError): + with mpl.rc_context(rc={'text.usetex': True, 'test.blah': True}): + pass + assert mpl.rcParams['text.usetex'] is False + + +@pytest.mark.skipif(sys.platform != "linux", reason="Linux only") +def test_backend_fallback_headless(tmpdir): + env = {**os.environ, + "DISPLAY": "", "WAYLAND_DISPLAY": "", + "MPLBACKEND": "", "MPLCONFIGDIR": str(tmpdir)} + with pytest.raises(subprocess.CalledProcessError): + subprocess.run( + [sys.executable, "-c", + "import matplotlib;" + "matplotlib.use('tkagg');" + "import matplotlib.pyplot;" + "matplotlib.pyplot.plot(42);" + ], + env=env, check=True, stderr=subprocess.DEVNULL) + + +@pytest.mark.skipif( + sys.platform == "linux" and not _c_internal_utils.display_is_valid(), + reason="headless") +def test_backend_fallback_headful(tmpdir): + pytest.importorskip("tkinter") + env = {**os.environ, "MPLBACKEND": "", "MPLCONFIGDIR": str(tmpdir)} + backend = subprocess.check_output( + [sys.executable, "-c", + "import matplotlib as mpl; " + "sentinel = mpl.rcsetup._auto_backend_sentinel; " + # Check that access on another instance does not resolve the sentinel. + "assert mpl.RcParams({'backend': sentinel})['backend'] == sentinel; " + "assert mpl.rcParams._get('backend') == sentinel; " + "import matplotlib.pyplot; " + "print(matplotlib.get_backend())"], + env=env, text=True) + # The actual backend will depend on what's installed, but at least tkagg is + # present. + assert backend.strip().lower() != "agg" + + +def test_deprecation(monkeypatch): + monkeypatch.setitem( + mpl._deprecated_map, "patch.linewidth", + ("0.0", "axes.linewidth", lambda old: 2 * old, lambda new: new / 2)) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert mpl.rcParams["patch.linewidth"] \ + == mpl.rcParams["axes.linewidth"] / 2 + with pytest.warns(mpl.MatplotlibDeprecationWarning): + mpl.rcParams["patch.linewidth"] = 1 + assert mpl.rcParams["axes.linewidth"] == 2 + + monkeypatch.setitem( + mpl._deprecated_ignore_map, "patch.edgecolor", + ("0.0", "axes.edgecolor")) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert mpl.rcParams["patch.edgecolor"] \ + == mpl.rcParams["axes.edgecolor"] + with pytest.warns(mpl.MatplotlibDeprecationWarning): + mpl.rcParams["patch.edgecolor"] = "#abcd" + assert mpl.rcParams["axes.edgecolor"] != "#abcd" + + monkeypatch.setitem( + mpl._deprecated_ignore_map, "patch.force_edgecolor", + ("0.0", None)) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert mpl.rcParams["patch.force_edgecolor"] is None + + monkeypatch.setitem( + mpl._deprecated_remain_as_none, "svg.hashsalt", + ("0.0",)) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + mpl.rcParams["svg.hashsalt"] = "foobar" + assert mpl.rcParams["svg.hashsalt"] == "foobar" # Doesn't warn. + mpl.rcParams["svg.hashsalt"] = None # Doesn't warn. + + mpl.rcParams.update(mpl.rcParams.copy()) # Doesn't warn. + # Note that the warning suppression actually arises from the + # iteration over the updater rcParams being protected by + # suppress_matplotlib_deprecation_warning, rather than any explicit check. + + +@pytest.mark.parametrize("value", [ + "best", + 1, + "1", + (0.9, .7), + (-0.9, .7), + "(0.9, .7)" +]) +def test_rcparams_legend_loc(value): + # rcParams['legend.loc'] should allow any of the following formats. + # if any of these are not allowed, an exception will be raised + # test for gh issue #22338 + mpl.rcParams["legend.loc"] = value + + +@pytest.mark.parametrize("value", [ + "best", + 1, + (0.9, .7), + (-0.9, .7), +]) +def test_rcparams_legend_loc_from_file(tmpdir, value): + # rcParams['legend.loc'] should be settable from matplotlibrc. + # if any of these are not allowed, an exception will be raised. + # test for gh issue #22338 + rc_path = tmpdir.join("matplotlibrc") + rc_path.write(f"legend.loc: {value}") + + with mpl.rc_context(fname=rc_path): + assert mpl.rcParams["legend.loc"] == value diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sankey.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sankey.py new file mode 100644 index 00000000..cbb7f516 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sankey.py @@ -0,0 +1,105 @@ +import pytest +from numpy.testing import assert_allclose, assert_array_equal + +from matplotlib.sankey import Sankey +from matplotlib.testing.decorators import check_figures_equal + + +def test_sankey(): + # lets just create a sankey instance and check the code runs + sankey = Sankey() + sankey.add() + + +def test_label(): + s = Sankey(flows=[0.25], labels=['First'], orientations=[-1]) + assert s.diagrams[0].texts[0].get_text() == 'First\n0.25' + + +def test_format_using_callable(): + # test using callable by slightly incrementing above label example + + def show_three_decimal_places(value): + return f'{value:.3f}' + + s = Sankey(flows=[0.25], labels=['First'], orientations=[-1], + format=show_three_decimal_places) + + assert s.diagrams[0].texts[0].get_text() == 'First\n0.250' + + +@pytest.mark.parametrize('kwargs, msg', ( + ({'gap': -1}, "'gap' is negative"), + ({'gap': 1, 'radius': 2}, "'radius' is greater than 'gap'"), + ({'head_angle': -1}, "'head_angle' is negative"), + ({'tolerance': -1}, "'tolerance' is negative"), + ({'flows': [1, -1], 'orientations': [-1, 0, 1]}, + r"The shapes of 'flows' \(2,\) and 'orientations'"), + ({'flows': [1, -1], 'labels': ['a', 'b', 'c']}, + r"The shapes of 'flows' \(2,\) and 'labels'"), + )) +def test_sankey_errors(kwargs, msg): + with pytest.raises(ValueError, match=msg): + Sankey(**kwargs) + + +@pytest.mark.parametrize('kwargs, msg', ( + ({'trunklength': -1}, "'trunklength' is negative"), + ({'flows': [0.2, 0.3], 'prior': 0}, "The scaled sum of the connected"), + ({'prior': -1}, "The index of the prior diagram is negative"), + ({'prior': 1}, "The index of the prior diagram is 1"), + ({'connect': (-1, 1), 'prior': 0}, "At least one of the connection"), + ({'connect': (2, 1), 'prior': 0}, "The connection index to the source"), + ({'connect': (1, 3), 'prior': 0}, "The connection index to this dia"), + ({'connect': (1, 1), 'prior': 0, 'flows': [-0.2, 0.2], + 'orientations': [2]}, "The value of orientations"), + ({'connect': (1, 1), 'prior': 0, 'flows': [-0.2, 0.2], + 'pathlengths': [2]}, "The lengths of 'flows'"), + )) +def test_sankey_add_errors(kwargs, msg): + sankey = Sankey() + with pytest.raises(ValueError, match=msg): + sankey.add(flows=[0.2, -0.2]) + sankey.add(**kwargs) + + +def test_sankey2(): + s = Sankey(flows=[0.25, -0.25, 0.5, -0.5], labels=['Foo'], + orientations=[-1], unit='Bar') + sf = s.finish() + assert_array_equal(sf[0].flows, [0.25, -0.25, 0.5, -0.5]) + assert sf[0].angles == [1, 3, 1, 3] + assert all([text.get_text()[0:3] == 'Foo' for text in sf[0].texts]) + assert all([text.get_text()[-3:] == 'Bar' for text in sf[0].texts]) + assert sf[0].text.get_text() == '' + assert_allclose(sf[0].tips, + [(-1.375, -0.52011255), + (1.375, -0.75506044), + (-0.75, -0.41522509), + (0.75, -0.8599479)]) + + s = Sankey(flows=[0.25, -0.25, 0, 0.5, -0.5], labels=['Foo'], + orientations=[-1], unit='Bar') + sf = s.finish() + assert_array_equal(sf[0].flows, [0.25, -0.25, 0, 0.5, -0.5]) + assert sf[0].angles == [1, 3, None, 1, 3] + assert_allclose(sf[0].tips, + [(-1.375, -0.52011255), + (1.375, -0.75506044), + (0, 0), + (-0.75, -0.41522509), + (0.75, -0.8599479)]) + + +@check_figures_equal(extensions=['png']) +def test_sankey3(fig_test, fig_ref): + ax_test = fig_test.gca() + s_test = Sankey(ax=ax_test, flows=[0.25, -0.25, -0.25, 0.25, 0.5, -0.5], + orientations=[1, -1, 1, -1, 0, 0]) + s_test.finish() + + ax_ref = fig_ref.gca() + s_ref = Sankey(ax=ax_ref) + s_ref.add(flows=[0.25, -0.25, -0.25, 0.25, 0.5, -0.5], + orientations=[1, -1, 1, -1, 0, 0]) + s_ref.finish() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_scale.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_scale.py new file mode 100644 index 00000000..72739736 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_scale.py @@ -0,0 +1,295 @@ +import copy + +import matplotlib.pyplot as plt +from matplotlib.scale import ( + AsinhScale, AsinhTransform, + LogTransform, InvertedLogTransform, + SymmetricalLogTransform) +import matplotlib.scale as mscale +from matplotlib.ticker import AsinhLocator, LogFormatterSciNotation +from matplotlib.testing.decorators import check_figures_equal, image_comparison + +import numpy as np +from numpy.testing import assert_allclose +import io +import pytest + + +@check_figures_equal() +def test_log_scales(fig_test, fig_ref): + ax_test = fig_test.add_subplot(122, yscale='log', xscale='symlog') + ax_test.axvline(24.1) + ax_test.axhline(24.1) + xlim = ax_test.get_xlim() + ylim = ax_test.get_ylim() + ax_ref = fig_ref.add_subplot(122, yscale='log', xscale='symlog') + ax_ref.set(xlim=xlim, ylim=ylim) + ax_ref.plot([24.1, 24.1], ylim, 'b') + ax_ref.plot(xlim, [24.1, 24.1], 'b') + + +def test_symlog_mask_nan(): + # Use a transform round-trip to verify that the forward and inverse + # transforms work, and that they respect nans and/or masking. + slt = SymmetricalLogTransform(10, 2, 1) + slti = slt.inverted() + + x = np.arange(-1.5, 5, 0.5) + out = slti.transform_non_affine(slt.transform_non_affine(x)) + assert_allclose(out, x) + assert type(out) is type(x) + + x[4] = np.nan + out = slti.transform_non_affine(slt.transform_non_affine(x)) + assert_allclose(out, x) + assert type(out) is type(x) + + x = np.ma.array(x) + out = slti.transform_non_affine(slt.transform_non_affine(x)) + assert_allclose(out, x) + assert type(out) is type(x) + + x[3] = np.ma.masked + out = slti.transform_non_affine(slt.transform_non_affine(x)) + assert_allclose(out, x) + assert type(out) is type(x) + + +@image_comparison(['logit_scales.png'], remove_text=True) +def test_logit_scales(): + fig, ax = plt.subplots() + + # Typical extinction curve for logit + x = np.array([0.001, 0.003, 0.01, 0.03, 0.1, 0.2, 0.3, 0.4, 0.5, + 0.6, 0.7, 0.8, 0.9, 0.97, 0.99, 0.997, 0.999]) + y = 1.0 / x + + ax.plot(x, y) + ax.set_xscale('logit') + ax.grid(True) + bbox = ax.get_tightbbox(fig.canvas.get_renderer()) + assert np.isfinite(bbox.x0) + assert np.isfinite(bbox.y0) + + +def test_log_scatter(): + """Issue #1799""" + fig, ax = plt.subplots(1) + + x = np.arange(10) + y = np.arange(10) - 1 + + ax.scatter(x, y) + + buf = io.BytesIO() + fig.savefig(buf, format='pdf') + + buf = io.BytesIO() + fig.savefig(buf, format='eps') + + buf = io.BytesIO() + fig.savefig(buf, format='svg') + + +def test_logscale_subs(): + fig, ax = plt.subplots() + ax.set_yscale('log', subs=np.array([2, 3, 4])) + # force draw + fig.canvas.draw() + + +@image_comparison(['logscale_mask.png'], remove_text=True) +def test_logscale_mask(): + # Check that zero values are masked correctly on log scales. + # See github issue 8045 + xs = np.linspace(0, 50, 1001) + + fig, ax = plt.subplots() + ax.plot(np.exp(-xs**2)) + fig.canvas.draw() + ax.set(yscale="log") + + +def test_extra_kwargs_raise(): + fig, ax = plt.subplots() + + for scale in ['linear', 'log', 'symlog']: + with pytest.raises(TypeError): + ax.set_yscale(scale, foo='mask') + + +def test_logscale_invert_transform(): + fig, ax = plt.subplots() + ax.set_yscale('log') + # get transformation from data to axes + tform = (ax.transAxes + ax.transData.inverted()).inverted() + + # direct test of log transform inversion + inverted_transform = LogTransform(base=2).inverted() + assert isinstance(inverted_transform, InvertedLogTransform) + assert inverted_transform.base == 2 + + +def test_logscale_transform_repr(): + fig, ax = plt.subplots() + ax.set_yscale('log') + repr(ax.transData) + repr(LogTransform(10, nonpositive='clip')) + + +@image_comparison(['logscale_nonpos_values.png'], + remove_text=True, tol=0.02, style='mpl20') +def test_logscale_nonpos_values(): + np.random.seed(19680801) + xs = np.random.normal(size=int(1e3)) + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) + ax1.hist(xs, range=(-5, 5), bins=10) + ax1.set_yscale('log') + ax2.hist(xs, range=(-5, 5), bins=10) + ax2.set_yscale('log', nonpositive='mask') + + xdata = np.arange(0, 10, 0.01) + ydata = np.exp(-xdata) + edata = 0.2*(10-xdata)*np.cos(5*xdata)*np.exp(-xdata) + + ax3.fill_between(xdata, ydata - edata, ydata + edata) + ax3.set_yscale('log') + + x = np.logspace(-1, 1) + y = x ** 3 + yerr = x**2 + ax4.errorbar(x, y, yerr=yerr) + + ax4.set_yscale('log') + ax4.set_xscale('log') + + +def test_invalid_log_lims(): + # Check that invalid log scale limits are ignored + fig, ax = plt.subplots() + ax.scatter(range(0, 4), range(0, 4)) + + ax.set_xscale('log') + original_xlim = ax.get_xlim() + with pytest.warns(UserWarning): + ax.set_xlim(left=0) + assert ax.get_xlim() == original_xlim + with pytest.warns(UserWarning): + ax.set_xlim(right=-1) + assert ax.get_xlim() == original_xlim + + ax.set_yscale('log') + original_ylim = ax.get_ylim() + with pytest.warns(UserWarning): + ax.set_ylim(bottom=0) + assert ax.get_ylim() == original_ylim + with pytest.warns(UserWarning): + ax.set_ylim(top=-1) + assert ax.get_ylim() == original_ylim + + +@image_comparison(['function_scales.png'], remove_text=True, style='mpl20') +def test_function_scale(): + def inverse(x): + return x**2 + + def forward(x): + return x**(1/2) + + fig, ax = plt.subplots() + + x = np.arange(1, 1000) + + ax.plot(x, x) + ax.set_xscale('function', functions=(forward, inverse)) + ax.set_xlim(1, 1000) + + +def test_pass_scale(): + # test passing a scale object works... + fig, ax = plt.subplots() + scale = mscale.LogScale(axis=None) + ax.set_xscale(scale) + scale = mscale.LogScale(axis=None) + ax.set_yscale(scale) + assert ax.xaxis.get_scale() == 'log' + assert ax.yaxis.get_scale() == 'log' + + +def test_scale_deepcopy(): + sc = mscale.LogScale(axis='x', base=10) + sc2 = copy.deepcopy(sc) + assert str(sc.get_transform()) == str(sc2.get_transform()) + assert sc._transform is not sc2._transform + + +class TestAsinhScale: + def test_transforms(self): + a0 = 17.0 + a = np.linspace(-50, 50, 100) + + forward = AsinhTransform(a0) + inverse = forward.inverted() + invinv = inverse.inverted() + + a_forward = forward.transform_non_affine(a) + a_inverted = inverse.transform_non_affine(a_forward) + assert_allclose(a_inverted, a) + + a_invinv = invinv.transform_non_affine(a) + assert_allclose(a_invinv, a0 * np.arcsinh(a / a0)) + + def test_init(self): + fig, ax = plt.subplots() + + s = AsinhScale(axis=None, linear_width=23.0) + assert s.linear_width == 23 + assert s._base == 10 + assert s._subs == (2, 5) + + tx = s.get_transform() + assert isinstance(tx, AsinhTransform) + assert tx.linear_width == s.linear_width + + def test_base_init(self): + fig, ax = plt.subplots() + + s3 = AsinhScale(axis=None, base=3) + assert s3._base == 3 + assert s3._subs == (2,) + + s7 = AsinhScale(axis=None, base=7, subs=(2, 4)) + assert s7._base == 7 + assert s7._subs == (2, 4) + + def test_fmtloc(self): + class DummyAxis: + def __init__(self): + self.fields = {} + def set(self, **kwargs): + self.fields.update(**kwargs) + def set_major_formatter(self, f): + self.fields['major_formatter'] = f + + ax0 = DummyAxis() + s0 = AsinhScale(axis=ax0, base=0) + s0.set_default_locators_and_formatters(ax0) + assert isinstance(ax0.fields['major_locator'], AsinhLocator) + assert isinstance(ax0.fields['major_formatter'], str) + + ax5 = DummyAxis() + s7 = AsinhScale(axis=ax5, base=5) + s7.set_default_locators_and_formatters(ax5) + assert isinstance(ax5.fields['major_locator'], AsinhLocator) + assert isinstance(ax5.fields['major_formatter'], + LogFormatterSciNotation) + + def test_bad_scale(self): + fig, ax = plt.subplots() + + with pytest.raises(ValueError): + AsinhScale(axis=None, linear_width=0) + with pytest.raises(ValueError): + AsinhScale(axis=None, linear_width=-1) + s0 = AsinhScale(axis=None, ) + s1 = AsinhScale(axis=None, linear_width=3.0) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_simplification.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_simplification.py new file mode 100644 index 00000000..446fc929 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_simplification.py @@ -0,0 +1,518 @@ +import base64 +import io + +import numpy as np +from numpy.testing import assert_array_almost_equal, assert_array_equal + +import pytest + +from matplotlib.testing.decorators import ( + check_figures_equal, image_comparison, remove_ticks_and_titles) +import matplotlib.pyplot as plt + +from matplotlib import patches, transforms +from matplotlib.path import Path + + +# NOTE: All of these tests assume that path.simplify is set to True +# (the default) + +@image_comparison(['clipping'], remove_text=True) +def test_clipping(): + t = np.arange(0.0, 2.0, 0.01) + s = np.sin(2*np.pi*t) + + fig, ax = plt.subplots() + ax.plot(t, s, linewidth=1.0) + ax.set_ylim((-0.20, -0.28)) + + +@image_comparison(['overflow'], remove_text=True) +def test_overflow(): + x = np.array([1.0, 2.0, 3.0, 2.0e5]) + y = np.arange(len(x)) + + fig, ax = plt.subplots() + ax.plot(x, y) + ax.set_xlim(2, 6) + + +@image_comparison(['clipping_diamond'], remove_text=True) +def test_diamond(): + x = np.array([0.0, 1.0, 0.0, -1.0, 0.0]) + y = np.array([1.0, 0.0, -1.0, 0.0, 1.0]) + + fig, ax = plt.subplots() + ax.plot(x, y) + ax.set_xlim(-0.6, 0.6) + ax.set_ylim(-0.6, 0.6) + + +def test_clipping_out_of_bounds(): + # Should work on a Path *without* codes. + path = Path([(0, 0), (1, 2), (2, 1)]) + simplified = path.cleaned(clip=(10, 10, 20, 20)) + assert_array_equal(simplified.vertices, [(0, 0)]) + assert simplified.codes == [Path.STOP] + + # Should work on a Path *with* codes, and no curves. + path = Path([(0, 0), (1, 2), (2, 1)], + [Path.MOVETO, Path.LINETO, Path.LINETO]) + simplified = path.cleaned(clip=(10, 10, 20, 20)) + assert_array_equal(simplified.vertices, [(0, 0)]) + assert simplified.codes == [Path.STOP] + + # A Path with curves does not do any clipping yet. + path = Path([(0, 0), (1, 2), (2, 3)], + [Path.MOVETO, Path.CURVE3, Path.CURVE3]) + simplified = path.cleaned() + simplified_clipped = path.cleaned(clip=(10, 10, 20, 20)) + assert_array_equal(simplified.vertices, simplified_clipped.vertices) + assert_array_equal(simplified.codes, simplified_clipped.codes) + + +def test_noise(): + np.random.seed(0) + x = np.random.uniform(size=50000) * 50 + + fig, ax = plt.subplots() + p1 = ax.plot(x, solid_joinstyle='round', linewidth=2.0) + + # Ensure that the path's transform takes the new axes limits into account. + fig.canvas.draw() + path = p1[0].get_path() + transform = p1[0].get_transform() + path = transform.transform_path(path) + simplified = path.cleaned(simplify=True) + + assert simplified.vertices.size == 25512 + + +def test_antiparallel_simplification(): + def _get_simplified(x, y): + fig, ax = plt.subplots() + p1 = ax.plot(x, y) + + path = p1[0].get_path() + transform = p1[0].get_transform() + path = transform.transform_path(path) + simplified = path.cleaned(simplify=True) + simplified = transform.inverted().transform_path(simplified) + + return simplified + + # test ending on a maximum + x = [0, 0, 0, 0, 0, 1] + y = [.5, 1, -1, 1, 2, .5] + + simplified = _get_simplified(x, y) + + assert_array_almost_equal([[0., 0.5], + [0., -1.], + [0., 2.], + [1., 0.5]], + simplified.vertices[:-2, :]) + + # test ending on a minimum + x = [0, 0, 0, 0, 0, 1] + y = [.5, 1, -1, 1, -2, .5] + + simplified = _get_simplified(x, y) + + assert_array_almost_equal([[0., 0.5], + [0., 1.], + [0., -2.], + [1., 0.5]], + simplified.vertices[:-2, :]) + + # test ending in between + x = [0, 0, 0, 0, 0, 1] + y = [.5, 1, -1, 1, 0, .5] + + simplified = _get_simplified(x, y) + + assert_array_almost_equal([[0., 0.5], + [0., 1.], + [0., -1.], + [0., 0.], + [1., 0.5]], + simplified.vertices[:-2, :]) + + # test no anti-parallel ending at max + x = [0, 0, 0, 0, 0, 1] + y = [.5, 1, 2, 1, 3, .5] + + simplified = _get_simplified(x, y) + + assert_array_almost_equal([[0., 0.5], + [0., 3.], + [1., 0.5]], + simplified.vertices[:-2, :]) + + # test no anti-parallel ending in middle + x = [0, 0, 0, 0, 0, 1] + y = [.5, 1, 2, 1, 1, .5] + + simplified = _get_simplified(x, y) + + assert_array_almost_equal([[0., 0.5], + [0., 2.], + [0., 1.], + [1., 0.5]], + simplified.vertices[:-2, :]) + + +# Only consider angles in 0 <= angle <= pi/2, otherwise +# using min/max will get the expected results out of order: +# min/max for simplification code depends on original vector, +# and if angle is outside above range then simplification +# min/max will be opposite from actual min/max. +@pytest.mark.parametrize('angle', [0, np.pi/4, np.pi/3, np.pi/2]) +@pytest.mark.parametrize('offset', [0, .5]) +def test_angled_antiparallel(angle, offset): + scale = 5 + np.random.seed(19680801) + # get 15 random offsets + # TODO: guarantee offset > 0 results in some offsets < 0 + vert_offsets = (np.random.rand(15) - offset) * scale + # always start at 0 so rotation makes sense + vert_offsets[0] = 0 + # always take the first step the same direction + vert_offsets[1] = 1 + # compute points along a diagonal line + x = np.sin(angle) * vert_offsets + y = np.cos(angle) * vert_offsets + + # will check these later + x_max = x[1:].max() + x_min = x[1:].min() + + y_max = y[1:].max() + y_min = y[1:].min() + + if offset > 0: + p_expected = Path([[0, 0], + [x_max, y_max], + [x_min, y_min], + [x[-1], y[-1]], + [0, 0]], + codes=[1, 2, 2, 2, 0]) + + else: + p_expected = Path([[0, 0], + [x_max, y_max], + [x[-1], y[-1]], + [0, 0]], + codes=[1, 2, 2, 0]) + + p = Path(np.vstack([x, y]).T) + p2 = p.cleaned(simplify=True) + + assert_array_almost_equal(p_expected.vertices, + p2.vertices) + assert_array_equal(p_expected.codes, p2.codes) + + +def test_sine_plus_noise(): + np.random.seed(0) + x = (np.sin(np.linspace(0, np.pi * 2.0, 50000)) + + np.random.uniform(size=50000) * 0.01) + + fig, ax = plt.subplots() + p1 = ax.plot(x, solid_joinstyle='round', linewidth=2.0) + + # Ensure that the path's transform takes the new axes limits into account. + fig.canvas.draw() + path = p1[0].get_path() + transform = p1[0].get_transform() + path = transform.transform_path(path) + simplified = path.cleaned(simplify=True) + + assert simplified.vertices.size == 25240 + + +@image_comparison(['simplify_curve'], remove_text=True, tol=0.017) +def test_simplify_curve(): + pp1 = patches.PathPatch( + Path([(0, 0), (1, 0), (1, 1), (np.nan, 1), (0, 0), (2, 0), (2, 2), + (0, 0)], + [Path.MOVETO, Path.CURVE3, Path.CURVE3, Path.CURVE3, Path.CURVE3, + Path.CURVE3, Path.CURVE3, Path.CLOSEPOLY]), + fc="none") + + fig, ax = plt.subplots() + ax.add_patch(pp1) + ax.set_xlim((0, 2)) + ax.set_ylim((0, 2)) + + +@check_figures_equal() +def test_closed_path_nan_removal(fig_test, fig_ref): + ax_test = fig_test.subplots(2, 2).flatten() + ax_ref = fig_ref.subplots(2, 2).flatten() + + # NaN on the first point also removes the last point, because it's closed. + path = Path( + [[-3, np.nan], [3, -3], [3, 3], [-3, 3], [-3, -3]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) + ax_test[0].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-3, np.nan], [3, -3], [3, 3], [-3, 3], [-3, np.nan]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO]) + ax_ref[0].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN on second-last point should not re-close. + path = Path( + [[-2, -2], [2, -2], [2, 2], [-2, np.nan], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) + ax_test[0].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-2, -2], [2, -2], [2, 2], [-2, np.nan], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO]) + ax_ref[0].add_patch(patches.PathPatch(path, facecolor='none')) + + # Test multiple loops in a single path (with same paths as above). + path = Path( + [[-3, np.nan], [3, -3], [3, 3], [-3, 3], [-3, -3], + [-2, -2], [2, -2], [2, 2], [-2, np.nan], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY, + Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]) + ax_test[1].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-3, np.nan], [3, -3], [3, 3], [-3, 3], [-3, np.nan], + [-2, -2], [2, -2], [2, 2], [-2, np.nan], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, + Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO]) + ax_ref[1].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN in first point of CURVE3 should not re-close, and hide entire curve. + path = Path( + [[-1, -1], [1, -1], [1, np.nan], [0, 1], [-1, 1], [-1, -1]], + [Path.MOVETO, Path.LINETO, Path.CURVE3, Path.CURVE3, Path.LINETO, + Path.CLOSEPOLY]) + ax_test[2].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-1, -1], [1, -1], [1, np.nan], [0, 1], [-1, 1], [-1, -1]], + [Path.MOVETO, Path.LINETO, Path.CURVE3, Path.CURVE3, Path.LINETO, + Path.CLOSEPOLY]) + ax_ref[2].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN in second point of CURVE3 should not re-close, and hide entire curve + # plus next line segment. + path = Path( + [[-3, -3], [3, -3], [3, 0], [0, np.nan], [-3, 3], [-3, -3]], + [Path.MOVETO, Path.LINETO, Path.CURVE3, Path.CURVE3, Path.LINETO, + Path.LINETO]) + ax_test[2].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-3, -3], [3, -3], [3, 0], [0, np.nan], [-3, 3], [-3, -3]], + [Path.MOVETO, Path.LINETO, Path.CURVE3, Path.CURVE3, Path.LINETO, + Path.LINETO]) + ax_ref[2].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN in first point of CURVE4 should not re-close, and hide entire curve. + path = Path( + [[-1, -1], [1, -1], [1, np.nan], [0, 0], [0, 1], [-1, 1], [-1, -1]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.CLOSEPOLY]) + ax_test[3].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-1, -1], [1, -1], [1, np.nan], [0, 0], [0, 1], [-1, 1], [-1, -1]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.CLOSEPOLY]) + ax_ref[3].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN in second point of CURVE4 should not re-close, and hide entire curve. + path = Path( + [[-2, -2], [2, -2], [2, 0], [0, np.nan], [0, 2], [-2, 2], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.LINETO]) + ax_test[3].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-2, -2], [2, -2], [2, 0], [0, np.nan], [0, 2], [-2, 2], [-2, -2]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.LINETO]) + ax_ref[3].add_patch(patches.PathPatch(path, facecolor='none')) + + # NaN in third point of CURVE4 should not re-close, and hide entire curve + # plus next line segment. + path = Path( + [[-3, -3], [3, -3], [3, 0], [0, 0], [0, np.nan], [-3, 3], [-3, -3]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.LINETO]) + ax_test[3].add_patch(patches.PathPatch(path, facecolor='none')) + path = Path( + [[-3, -3], [3, -3], [3, 0], [0, 0], [0, np.nan], [-3, 3], [-3, -3]], + [Path.MOVETO, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, + Path.LINETO, Path.LINETO]) + ax_ref[3].add_patch(patches.PathPatch(path, facecolor='none')) + + # Keep everything clean. + for ax in [*ax_test.flat, *ax_ref.flat]: + ax.set(xlim=(-3.5, 3.5), ylim=(-3.5, 3.5)) + remove_ticks_and_titles(fig_test) + remove_ticks_and_titles(fig_ref) + + +@check_figures_equal() +def test_closed_path_clipping(fig_test, fig_ref): + vertices = [] + for roll in range(8): + offset = 0.1 * roll + 0.1 + + # A U-like pattern. + pattern = [ + [-0.5, 1.5], [-0.5, -0.5], [1.5, -0.5], [1.5, 1.5], # Outer square + # With a notch in the top. + [1 - offset / 2, 1.5], [1 - offset / 2, offset], + [offset / 2, offset], [offset / 2, 1.5], + ] + + # Place the initial/final point anywhere in/out of the clipping area. + pattern = np.roll(pattern, roll, axis=0) + pattern = np.concatenate((pattern, pattern[:1, :])) + + vertices.append(pattern) + + # Multiple subpaths are used here to ensure they aren't broken by closed + # loop clipping. + codes = np.full(len(vertices[0]), Path.LINETO) + codes[0] = Path.MOVETO + codes[-1] = Path.CLOSEPOLY + codes = np.tile(codes, len(vertices)) + vertices = np.concatenate(vertices) + + fig_test.set_size_inches((5, 5)) + path = Path(vertices, codes) + fig_test.add_artist(patches.PathPatch(path, facecolor='none')) + + # For reference, we draw the same thing, but unclosed by using a line to + # the last point only. + fig_ref.set_size_inches((5, 5)) + codes = codes.copy() + codes[codes == Path.CLOSEPOLY] = Path.LINETO + path = Path(vertices, codes) + fig_ref.add_artist(patches.PathPatch(path, facecolor='none')) + + +@image_comparison(['hatch_simplify'], remove_text=True) +def test_hatch(): + fig, ax = plt.subplots() + ax.add_patch(plt.Rectangle((0, 0), 1, 1, fill=False, hatch="/")) + ax.set_xlim((0.45, 0.55)) + ax.set_ylim((0.45, 0.55)) + + +@image_comparison(['fft_peaks'], remove_text=True) +def test_fft_peaks(): + fig, ax = plt.subplots() + t = np.arange(65536) + p1 = ax.plot(abs(np.fft.fft(np.sin(2*np.pi*.01*t)*np.blackman(len(t))))) + + # Ensure that the path's transform takes the new axes limits into account. + fig.canvas.draw() + path = p1[0].get_path() + transform = p1[0].get_transform() + path = transform.transform_path(path) + simplified = path.cleaned(simplify=True) + + assert simplified.vertices.size == 36 + + +def test_start_with_moveto(): + # Should be entirely clipped away to a single MOVETO + data = b""" +ZwAAAAku+v9UAQAA+Tj6/z8CAADpQ/r/KAMAANlO+v8QBAAAyVn6//UEAAC6ZPr/2gUAAKpv+v+8 +BgAAm3r6/50HAACLhfr/ewgAAHyQ+v9ZCQAAbZv6/zQKAABepvr/DgsAAE+x+v/lCwAAQLz6/7wM +AAAxx/r/kA0AACPS+v9jDgAAFN36/zQPAAAF6Pr/AxAAAPfy+v/QEAAA6f36/5wRAADbCPv/ZhIA +AMwT+/8uEwAAvh77//UTAACwKfv/uRQAAKM0+/98FQAAlT/7/z0WAACHSvv//RYAAHlV+/+7FwAA +bGD7/3cYAABea/v/MRkAAFF2+//pGQAARIH7/6AaAAA3jPv/VRsAACmX+/8JHAAAHKL7/7ocAAAP +rfv/ah0AAAO4+/8YHgAA9sL7/8QeAADpzfv/bx8AANzY+/8YIAAA0OP7/78gAADD7vv/ZCEAALf5 ++/8IIgAAqwT8/6kiAACeD/z/SiMAAJIa/P/oIwAAhiX8/4QkAAB6MPz/HyUAAG47/P+4JQAAYkb8 +/1AmAABWUfz/5SYAAEpc/P95JwAAPmf8/wsoAAAzcvz/nCgAACd9/P8qKQAAHIj8/7cpAAAQk/z/ +QyoAAAWe/P/MKgAA+aj8/1QrAADus/z/2isAAOO+/P9eLAAA2Mn8/+AsAADM1Pz/YS0AAMHf/P/g +LQAAtur8/10uAACr9fz/2C4AAKEA/f9SLwAAlgv9/8ovAACLFv3/QDAAAIAh/f+1MAAAdSz9/ycx +AABrN/3/mDEAAGBC/f8IMgAAVk39/3UyAABLWP3/4TIAAEFj/f9LMwAANm79/7MzAAAsef3/GjQA +ACKE/f9+NAAAF4/9/+E0AAANmv3/QzUAAAOl/f+iNQAA+a/9/wA2AADvuv3/XDYAAOXF/f+2NgAA +29D9/w83AADR2/3/ZjcAAMfm/f+7NwAAvfH9/w44AACz/P3/XzgAAKkH/v+vOAAAnxL+//04AACW +Hf7/SjkAAIwo/v+UOQAAgjP+/905AAB5Pv7/JDoAAG9J/v9pOgAAZVT+/606AABcX/7/7zoAAFJq +/v8vOwAASXX+/207AAA/gP7/qjsAADaL/v/lOwAALZb+/x48AAAjof7/VTwAABqs/v+LPAAAELf+ +/788AAAHwv7/8TwAAP7M/v8hPQAA9df+/1A9AADr4v7/fT0AAOLt/v+oPQAA2fj+/9E9AADQA/// ++T0AAMYO//8fPgAAvRn//0M+AAC0JP//ZT4AAKsv//+GPgAAojr//6U+AACZRf//wj4AAJBQ///d +PgAAh1v///c+AAB+Zv//Dz8AAHRx//8lPwAAa3z//zk/AABih///TD8AAFmS//9dPwAAUJ3//2w/ +AABHqP//ej8AAD6z//+FPwAANb7//48/AAAsyf//lz8AACPU//+ePwAAGt///6M/AAAR6v//pj8A +AAj1//+nPwAA/////w==""" + + verts = np.frombuffer(base64.decodebytes(data), dtype='<i4') + verts = verts.reshape((len(verts) // 2, 2)) + path = Path(verts) + segs = path.iter_segments(transforms.IdentityTransform(), + clip=(0.0, 0.0, 100.0, 100.0)) + segs = list(segs) + assert len(segs) == 1 + assert segs[0][1] == Path.MOVETO + + +def test_throw_rendering_complexity_exceeded(): + plt.rcParams['path.simplify'] = False + xx = np.arange(2_000_000) + yy = np.random.rand(2_000_000) + yy[1000] = np.nan + + fig, ax = plt.subplots() + ax.plot(xx, yy) + with pytest.raises(OverflowError): + fig.savefig(io.BytesIO()) + + +@image_comparison(['clipper_edge'], remove_text=True) +def test_clipper(): + dat = (0, 1, 0, 2, 0, 3, 0, 4, 0, 5) + fig = plt.figure(figsize=(2, 1)) + fig.subplots_adjust(left=0, bottom=0, wspace=0, hspace=0) + + ax = fig.add_axes((0, 0, 1.0, 1.0), ylim=(0, 5), autoscale_on=False) + ax.plot(dat) + ax.xaxis.set_major_locator(plt.MultipleLocator(1)) + ax.yaxis.set_major_locator(plt.MultipleLocator(1)) + ax.xaxis.set_ticks_position('bottom') + ax.yaxis.set_ticks_position('left') + + ax.set_xlim(5, 9) + + +@image_comparison(['para_equal_perp'], remove_text=True) +def test_para_equal_perp(): + x = np.array([0, 1, 2, 1, 0, -1, 0, 1] + [1] * 128) + y = np.array([1, 1, 2, 1, 0, -1, 0, 0] + [0] * 128) + + fig, ax = plt.subplots() + ax.plot(x + 1, y + 1) + ax.plot(x + 1, y + 1, 'ro') + + +@image_comparison(['clipping_with_nans']) +def test_clipping_with_nans(): + x = np.linspace(0, 3.14 * 2, 3000) + y = np.sin(x) + x[::100] = np.nan + + fig, ax = plt.subplots() + ax.plot(x, y) + ax.set_ylim(-0.25, 0.25) + + +def test_clipping_full(): + p = Path([[1e30, 1e30]] * 5) + simplified = list(p.iter_segments(clip=[0, 0, 100, 100])) + assert simplified == [] + + p = Path([[50, 40], [75, 65]], [1, 2]) + simplified = list(p.iter_segments(clip=[0, 0, 100, 100])) + assert ([(list(x), y) for x, y in simplified] == + [([50, 40], 1), ([75, 65], 2)]) + + p = Path([[50, 40]], [1]) + simplified = list(p.iter_segments(clip=[0, 0, 100, 100])) + assert ([(list(x), y) for x, y in simplified] == + [([50, 40], 1)]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_skew.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_skew.py new file mode 100644 index 00000000..df17b2f7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_skew.py @@ -0,0 +1,168 @@ +""" +Testing that skewed axes properly work. +""" + +from contextlib import ExitStack +import itertools + +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison + +from matplotlib.axes import Axes +import matplotlib.transforms as transforms +import matplotlib.axis as maxis +import matplotlib.spines as mspines +import matplotlib.patches as mpatch +from matplotlib.projections import register_projection + + +# The sole purpose of this class is to look at the upper, lower, or total +# interval as appropriate and see what parts of the tick to draw, if any. +class SkewXTick(maxis.XTick): + def draw(self, renderer): + with ExitStack() as stack: + for artist in [self.gridline, self.tick1line, self.tick2line, + self.label1, self.label2]: + stack.callback(artist.set_visible, artist.get_visible()) + needs_lower = transforms.interval_contains( + self.axes.lower_xlim, self.get_loc()) + needs_upper = transforms.interval_contains( + self.axes.upper_xlim, self.get_loc()) + self.tick1line.set_visible( + self.tick1line.get_visible() and needs_lower) + self.label1.set_visible( + self.label1.get_visible() and needs_lower) + self.tick2line.set_visible( + self.tick2line.get_visible() and needs_upper) + self.label2.set_visible( + self.label2.get_visible() and needs_upper) + super().draw(renderer) + + def get_view_interval(self): + return self.axes.xaxis.get_view_interval() + + +# This class exists to provide two separate sets of intervals to the tick, +# as well as create instances of the custom tick +class SkewXAxis(maxis.XAxis): + def _get_tick(self, major): + return SkewXTick(self.axes, None, major=major) + + def get_view_interval(self): + return self.axes.upper_xlim[0], self.axes.lower_xlim[1] + + +# This class exists to calculate the separate data range of the +# upper X-axis and draw the spine there. It also provides this range +# to the X-axis artist for ticking and gridlines +class SkewSpine(mspines.Spine): + def _adjust_location(self): + pts = self._path.vertices + if self.spine_type == 'top': + pts[:, 0] = self.axes.upper_xlim + else: + pts[:, 0] = self.axes.lower_xlim + + +# This class handles registration of the skew-xaxes as a projection as well +# as setting up the appropriate transformations. It also overrides standard +# spines and axes instances as appropriate. +class SkewXAxes(Axes): + # The projection must specify a name. This will be used be the + # user to select the projection, i.e. ``subplot(projection='skewx')``. + name = 'skewx' + + def _init_axis(self): + # Taken from Axes and modified to use our modified X-axis + self.xaxis = SkewXAxis(self) + self.spines.top.register_axis(self.xaxis) + self.spines.bottom.register_axis(self.xaxis) + self.yaxis = maxis.YAxis(self) + self.spines.left.register_axis(self.yaxis) + self.spines.right.register_axis(self.yaxis) + + def _gen_axes_spines(self): + spines = {'top': SkewSpine.linear_spine(self, 'top'), + 'bottom': mspines.Spine.linear_spine(self, 'bottom'), + 'left': mspines.Spine.linear_spine(self, 'left'), + 'right': mspines.Spine.linear_spine(self, 'right')} + return spines + + def _set_lim_and_transforms(self): + """ + This is called once when the plot is created to set up all the + transforms for the data, text and grids. + """ + rot = 30 + + # Get the standard transform setup from the Axes base class + super()._set_lim_and_transforms() + + # Need to put the skew in the middle, after the scale and limits, + # but before the transAxes. This way, the skew is done in Axes + # coordinates thus performing the transform around the proper origin + # We keep the pre-transAxes transform around for other users, like the + # spines for finding bounds + self.transDataToAxes = (self.transScale + + (self.transLimits + + transforms.Affine2D().skew_deg(rot, 0))) + + # Create the full transform from Data to Pixels + self.transData = self.transDataToAxes + self.transAxes + + # Blended transforms like this need to have the skewing applied using + # both axes, in axes coords like before. + self._xaxis_transform = (transforms.blended_transform_factory( + self.transScale + self.transLimits, + transforms.IdentityTransform()) + + transforms.Affine2D().skew_deg(rot, 0)) + self.transAxes + + @property + def lower_xlim(self): + return self.axes.viewLim.intervalx + + @property + def upper_xlim(self): + pts = [[0., 1.], [1., 1.]] + return self.transDataToAxes.inverted().transform(pts)[:, 0] + + +# Now register the projection with matplotlib so the user can select +# it. +register_projection(SkewXAxes) + + +@image_comparison(['skew_axes'], remove_text=True) +def test_set_line_coll_dash_image(): + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='skewx') + ax.set_xlim(-50, 50) + ax.set_ylim(50, -50) + ax.grid(True) + + # An example of a slanted line at constant X + ax.axvline(0, color='b') + + +@image_comparison(['skew_rects'], remove_text=True) +def test_skew_rectangle(): + + fix, axes = plt.subplots(5, 5, sharex=True, sharey=True, figsize=(8, 8)) + axes = axes.flat + + rotations = list(itertools.product([-3, -1, 0, 1, 3], repeat=2)) + + axes[0].set_xlim([-3, 3]) + axes[0].set_ylim([-3, 3]) + axes[0].set_aspect('equal', share=True) + + for ax, (xrots, yrots) in zip(axes, rotations): + xdeg, ydeg = 45 * xrots, 45 * yrots + t = transforms.Affine2D().skew_deg(xdeg, ydeg) + + ax.set_title(f'Skew of {xdeg} in X and {ydeg} in Y') + ax.add_patch(mpatch.Rectangle([-1, -1], 2, 2, + transform=t + ax.transData, + alpha=0.5, facecolor='coral')) + + plt.subplots_adjust(wspace=0, left=0.01, right=0.99, bottom=0.01, top=0.99) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sphinxext.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sphinxext.py new file mode 100644 index 00000000..6624e3b1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_sphinxext.py @@ -0,0 +1,225 @@ +"""Tests for tinypages build using sphinx extensions.""" + +import filecmp +import os +from pathlib import Path +import shutil +import sys + +from matplotlib.testing import subprocess_run_for_testing +import pytest + + +pytest.importorskip('sphinx', + minversion=None if sys.version_info < (3, 10) else '4.1.3') + + +def build_sphinx_html(source_dir, doctree_dir, html_dir, extra_args=None): + # Build the pages with warnings turned into errors + extra_args = [] if extra_args is None else extra_args + cmd = [sys.executable, '-msphinx', '-W', '-b', 'html', + '-d', str(doctree_dir), str(source_dir), str(html_dir), *extra_args] + proc = subprocess_run_for_testing( + cmd, capture_output=True, text=True, + env={**os.environ, "MPLBACKEND": ""}) + out = proc.stdout + err = proc.stderr + + assert proc.returncode == 0, \ + f"sphinx build failed with stdout:\n{out}\nstderr:\n{err}\n" + if err: + pytest.fail(f"sphinx build emitted the following warnings:\n{err}") + + assert html_dir.is_dir() + + +def test_tinypages(tmp_path): + shutil.copytree(Path(__file__).parent / 'tinypages', tmp_path, + dirs_exist_ok=True) + html_dir = tmp_path / '_build' / 'html' + img_dir = html_dir / '_images' + doctree_dir = tmp_path / 'doctrees' + # Build the pages with warnings turned into errors + cmd = [sys.executable, '-msphinx', '-W', '-b', 'html', + '-d', str(doctree_dir), + str(Path(__file__).parent / 'tinypages'), str(html_dir)] + # On CI, gcov emits warnings (due to agg headers being included with the + # same name in multiple extension modules -- but we don't care about their + # coverage anyways); hide them using GCOV_ERROR_FILE. + proc = subprocess_run_for_testing( + cmd, capture_output=True, text=True, + env={**os.environ, "MPLBACKEND": "", "GCOV_ERROR_FILE": os.devnull} + ) + out = proc.stdout + err = proc.stderr + + # Build the pages with warnings turned into errors + build_sphinx_html(tmp_path, doctree_dir, html_dir) + + def plot_file(num): + return img_dir / f'some_plots-{num}.png' + + def plot_directive_file(num): + # This is always next to the doctree dir. + return doctree_dir.parent / 'plot_directive' / f'some_plots-{num}.png' + + range_10, range_6, range_4 = [plot_file(i) for i in range(1, 4)] + # Plot 5 is range(6) plot + assert filecmp.cmp(range_6, plot_file(5)) + # Plot 7 is range(4) plot + assert filecmp.cmp(range_4, plot_file(7)) + # Plot 11 is range(10) plot + assert filecmp.cmp(range_10, plot_file(11)) + # Plot 12 uses the old range(10) figure and the new range(6) figure + assert filecmp.cmp(range_10, plot_file('12_00')) + assert filecmp.cmp(range_6, plot_file('12_01')) + # Plot 13 shows close-figs in action + assert filecmp.cmp(range_4, plot_file(13)) + # Plot 14 has included source + html_contents = (html_dir / 'some_plots.html').read_bytes() + + assert b'# Only a comment' in html_contents + # check plot defined in external file. + assert filecmp.cmp(range_4, img_dir / 'range4.png') + assert filecmp.cmp(range_6, img_dir / 'range6_range6.png') + # check if figure caption made it into html file + assert b'This is the caption for plot 15.' in html_contents + # check if figure caption using :caption: made it into html file + assert b'Plot 17 uses the caption option.' in html_contents + # check if figure caption made it into html file + assert b'This is the caption for plot 18.' in html_contents + # check if the custom classes made it into the html file + assert b'plot-directive my-class my-other-class' in html_contents + # check that the multi-image caption is applied twice + assert html_contents.count(b'This caption applies to both plots.') == 2 + # Plot 21 is range(6) plot via an include directive. But because some of + # the previous plots are repeated, the argument to plot_file() is only 17. + assert filecmp.cmp(range_6, plot_file(17)) + # plot 22 is from the range6.py file again, but a different function + assert filecmp.cmp(range_10, img_dir / 'range6_range10.png') + + # Modify the included plot + contents = (tmp_path / 'included_plot_21.rst').read_bytes() + contents = contents.replace(b'plt.plot(range(6))', b'plt.plot(range(4))') + (tmp_path / 'included_plot_21.rst').write_bytes(contents) + # Build the pages again and check that the modified file was updated + modification_times = [plot_directive_file(i).stat().st_mtime + for i in (1, 2, 3, 5)] + build_sphinx_html(tmp_path, doctree_dir, html_dir) + assert filecmp.cmp(range_4, plot_file(17)) + # Check that the plots in the plot_directive folder weren't changed. + # (plot_directive_file(1) won't be modified, but it will be copied to html/ + # upon compilation, so plot_file(1) will be modified) + assert plot_directive_file(1).stat().st_mtime == modification_times[0] + assert plot_directive_file(2).stat().st_mtime == modification_times[1] + assert plot_directive_file(3).stat().st_mtime == modification_times[2] + assert filecmp.cmp(range_10, plot_file(1)) + assert filecmp.cmp(range_6, plot_file(2)) + assert filecmp.cmp(range_4, plot_file(3)) + # Make sure that figures marked with context are re-created (but that the + # contents are the same) + assert plot_directive_file(5).stat().st_mtime > modification_times[3] + assert filecmp.cmp(range_6, plot_file(5)) + + +def test_plot_html_show_source_link(tmp_path): + parent = Path(__file__).parent + shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py') + shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static') + doctree_dir = tmp_path / 'doctrees' + (tmp_path / 'index.rst').write_text(""" +.. plot:: + + plt.plot(range(2)) +""") + # Make sure source scripts are created by default + html_dir1 = tmp_path / '_build' / 'html1' + build_sphinx_html(tmp_path, doctree_dir, html_dir1) + assert len(list(html_dir1.glob("**/index-1.py"))) == 1 + # Make sure source scripts are NOT created when + # plot_html_show_source_link` is False + html_dir2 = tmp_path / '_build' / 'html2' + build_sphinx_html(tmp_path, doctree_dir, html_dir2, + extra_args=['-D', 'plot_html_show_source_link=0']) + assert len(list(html_dir2.glob("**/index-1.py"))) == 0 + + +@pytest.mark.parametrize('plot_html_show_source_link', [0, 1]) +def test_show_source_link_true(tmp_path, plot_html_show_source_link): + # Test that a source link is generated if :show-source-link: is true, + # whether or not plot_html_show_source_link is true. + parent = Path(__file__).parent + shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py') + shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static') + doctree_dir = tmp_path / 'doctrees' + (tmp_path / 'index.rst').write_text(""" +.. plot:: + :show-source-link: true + + plt.plot(range(2)) +""") + html_dir = tmp_path / '_build' / 'html' + build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=[ + '-D', f'plot_html_show_source_link={plot_html_show_source_link}']) + assert len(list(html_dir.glob("**/index-1.py"))) == 1 + + +@pytest.mark.parametrize('plot_html_show_source_link', [0, 1]) +def test_show_source_link_false(tmp_path, plot_html_show_source_link): + # Test that a source link is NOT generated if :show-source-link: is false, + # whether or not plot_html_show_source_link is true. + parent = Path(__file__).parent + shutil.copyfile(parent / 'tinypages/conf.py', tmp_path / 'conf.py') + shutil.copytree(parent / 'tinypages/_static', tmp_path / '_static') + doctree_dir = tmp_path / 'doctrees' + (tmp_path / 'index.rst').write_text(""" +.. plot:: + :show-source-link: false + + plt.plot(range(2)) +""") + html_dir = tmp_path / '_build' / 'html' + build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=[ + '-D', f'plot_html_show_source_link={plot_html_show_source_link}']) + assert len(list(html_dir.glob("**/index-1.py"))) == 0 + + +def test_srcset_version(tmp_path): + shutil.copytree(Path(__file__).parent / 'tinypages', tmp_path, + dirs_exist_ok=True) + html_dir = tmp_path / '_build' / 'html' + img_dir = html_dir / '_images' + doctree_dir = tmp_path / 'doctrees' + + build_sphinx_html(tmp_path, doctree_dir, html_dir, extra_args=[ + '-D', 'plot_srcset=2x']) + + def plot_file(num, suff=''): + return img_dir / f'some_plots-{num}{suff}.png' + + # check some-plots + for ind in [1, 2, 3, 5, 7, 11, 13, 15, 17]: + assert plot_file(ind).exists() + assert plot_file(ind, suff='.2x').exists() + + assert (img_dir / 'nestedpage-index-1.png').exists() + assert (img_dir / 'nestedpage-index-1.2x.png').exists() + assert (img_dir / 'nestedpage-index-2.png').exists() + assert (img_dir / 'nestedpage-index-2.2x.png').exists() + assert (img_dir / 'nestedpage2-index-1.png').exists() + assert (img_dir / 'nestedpage2-index-1.2x.png').exists() + assert (img_dir / 'nestedpage2-index-2.png').exists() + assert (img_dir / 'nestedpage2-index-2.2x.png').exists() + + # Check html for srcset + + assert ('srcset="_images/some_plots-1.png, _images/some_plots-1.2x.png 2.00x"' + in (html_dir / 'some_plots.html').read_text(encoding='utf-8')) + + st = ('srcset="../_images/nestedpage-index-1.png, ' + '../_images/nestedpage-index-1.2x.png 2.00x"') + assert st in (html_dir / 'nestedpage/index.html').read_text(encoding='utf-8') + + st = ('srcset="../_images/nestedpage2-index-2.png, ' + '../_images/nestedpage2-index-2.2x.png 2.00x"') + assert st in (html_dir / 'nestedpage2/index.html').read_text(encoding='utf-8') diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_spines.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_spines.py new file mode 100644 index 00000000..9ce16fb3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_spines.py @@ -0,0 +1,156 @@ +import numpy as np +import pytest + +import matplotlib.pyplot as plt +from matplotlib.spines import Spines +from matplotlib.testing.decorators import check_figures_equal, image_comparison + + +def test_spine_class(): + """Test Spines and SpinesProxy in isolation.""" + class SpineMock: + def __init__(self): + self.val = None + + def set(self, **kwargs): + vars(self).update(kwargs) + + def set_val(self, val): + self.val = val + + spines_dict = { + 'left': SpineMock(), + 'right': SpineMock(), + 'top': SpineMock(), + 'bottom': SpineMock(), + } + spines = Spines(**spines_dict) + + assert spines['left'] is spines_dict['left'] + assert spines.left is spines_dict['left'] + + spines[['left', 'right']].set_val('x') + assert spines.left.val == 'x' + assert spines.right.val == 'x' + assert spines.top.val is None + assert spines.bottom.val is None + + spines[:].set_val('y') + assert all(spine.val == 'y' for spine in spines.values()) + + spines[:].set(foo='bar') + assert all(spine.foo == 'bar' for spine in spines.values()) + + with pytest.raises(AttributeError, match='foo'): + spines.foo + with pytest.raises(KeyError, match='foo'): + spines['foo'] + with pytest.raises(KeyError, match='foo, bar'): + spines[['left', 'foo', 'right', 'bar']] + with pytest.raises(ValueError, match='single list'): + spines['left', 'right'] + with pytest.raises(ValueError, match='Spines does not support slicing'): + spines['left':'right'] + with pytest.raises(ValueError, match='Spines does not support slicing'): + spines['top':] + + +@image_comparison(['spines_axes_positions']) +def test_spines_axes_positions(): + # SF bug 2852168 + fig = plt.figure() + x = np.linspace(0, 2*np.pi, 100) + y = 2*np.sin(x) + ax = fig.add_subplot(1, 1, 1) + ax.set_title('centered spines') + ax.plot(x, y) + ax.spines.right.set_position(('axes', 0.1)) + ax.yaxis.set_ticks_position('right') + ax.spines.top.set_position(('axes', 0.25)) + ax.xaxis.set_ticks_position('top') + ax.spines.left.set_color('none') + ax.spines.bottom.set_color('none') + + +@image_comparison(['spines_data_positions']) +def test_spines_data_positions(): + fig, ax = plt.subplots() + ax.spines.left.set_position(('data', -1.5)) + ax.spines.top.set_position(('data', 0.5)) + ax.spines.right.set_position(('data', -0.5)) + ax.spines.bottom.set_position('zero') + ax.set_xlim([-2, 2]) + ax.set_ylim([-2, 2]) + + +@check_figures_equal(extensions=["png"]) +def test_spine_nonlinear_data_positions(fig_test, fig_ref): + plt.style.use("default") + + ax = fig_test.add_subplot() + ax.set(xscale="log", xlim=(.1, 1)) + # Use position="data" to visually swap the left and right spines, using + # linewidth to distinguish them. The calls to tick_params removes labels + # (for image comparison purposes) and harmonizes tick positions with the + # reference). + ax.spines.left.set_position(("data", 1)) + ax.spines.left.set_linewidth(2) + ax.spines.right.set_position(("data", .1)) + ax.tick_params(axis="y", labelleft=False, direction="in") + + ax = fig_ref.add_subplot() + ax.set(xscale="log", xlim=(.1, 1)) + ax.spines.right.set_linewidth(2) + ax.tick_params(axis="y", labelleft=False, left=False, right=True) + + +@image_comparison(['spines_capstyle']) +def test_spines_capstyle(): + # issue 2542 + plt.rc('axes', linewidth=20) + fig, ax = plt.subplots() + ax.set_xticks([]) + ax.set_yticks([]) + + +def test_label_without_ticks(): + fig, ax = plt.subplots() + plt.subplots_adjust(left=0.3, bottom=0.3) + ax.plot(np.arange(10)) + ax.yaxis.set_ticks_position('left') + ax.spines.left.set_position(('outward', 30)) + ax.spines.right.set_visible(False) + ax.set_ylabel('y label') + ax.xaxis.set_ticks_position('bottom') + ax.spines.bottom.set_position(('outward', 30)) + ax.spines.top.set_visible(False) + ax.set_xlabel('x label') + ax.xaxis.set_ticks([]) + ax.yaxis.set_ticks([]) + plt.draw() + + spine = ax.spines.left + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + assert ax.yaxis.label.get_position()[0] < spinebbox.xmin, \ + "Y-Axis label not left of the spine" + + spine = ax.spines.bottom + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + assert ax.xaxis.label.get_position()[1] < spinebbox.ymin, \ + "X-Axis label not below the spine" + + +@image_comparison(['black_axes']) +def test_spines_black_axes(): + # GitHub #18804 + plt.rcParams["savefig.pad_inches"] = 0 + plt.rcParams["savefig.bbox"] = 'tight' + fig = plt.figure(0, figsize=(4, 4)) + ax = fig.add_axes((0, 0, 1, 1)) + ax.set_xticklabels([]) + ax.set_yticklabels([]) + ax.set_xticks([]) + ax.set_yticks([]) + ax.set_facecolor((0, 0, 0)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_streamplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_streamplot.py new file mode 100644 index 00000000..10a64f1d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_streamplot.py @@ -0,0 +1,169 @@ +import numpy as np +from numpy.testing import assert_array_almost_equal +import pytest +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison +import matplotlib.transforms as mtransforms + + +def velocity_field(): + Y, X = np.mgrid[-3:3:100j, -3:3:200j] + U = -1 - X**2 + Y + V = 1 + X - Y**2 + return X, Y, U, V + + +def swirl_velocity_field(): + x = np.linspace(-3., 3., 200) + y = np.linspace(-3., 3., 100) + X, Y = np.meshgrid(x, y) + a = 0.1 + U = np.cos(a) * (-Y) - np.sin(a) * X + V = np.sin(a) * (-Y) + np.cos(a) * X + return x, y, U, V + + +@image_comparison(['streamplot_startpoints'], remove_text=True, style='mpl20', + extensions=['png']) +def test_startpoints(): + X, Y, U, V = velocity_field() + start_x, start_y = np.meshgrid(np.linspace(X.min(), X.max(), 5), + np.linspace(Y.min(), Y.max(), 5)) + start_points = np.column_stack([start_x.ravel(), start_y.ravel()]) + plt.streamplot(X, Y, U, V, start_points=start_points) + plt.plot(start_x, start_y, 'ok') + + +@image_comparison(['streamplot_colormap'], remove_text=True, style='mpl20', + tol=0.022) +def test_colormap(): + X, Y, U, V = velocity_field() + plt.streamplot(X, Y, U, V, color=U, density=0.6, linewidth=2, + cmap=plt.cm.autumn) + plt.colorbar() + + +@image_comparison(['streamplot_linewidth'], remove_text=True, style='mpl20', + tol=0.002) +def test_linewidth(): + X, Y, U, V = velocity_field() + speed = np.hypot(U, V) + lw = 5 * speed / speed.max() + ax = plt.figure().subplots() + ax.streamplot(X, Y, U, V, density=[0.5, 1], color='k', linewidth=lw) + + +@image_comparison(['streamplot_masks_and_nans'], + remove_text=True, style='mpl20') +def test_masks_and_nans(): + X, Y, U, V = velocity_field() + mask = np.zeros(U.shape, dtype=bool) + mask[40:60, 80:120] = 1 + U[:20, :40] = np.nan + U = np.ma.array(U, mask=mask) + ax = plt.figure().subplots() + with np.errstate(invalid='ignore'): + ax.streamplot(X, Y, U, V, color=U, cmap=plt.cm.Blues) + + +@image_comparison(['streamplot_maxlength.png'], + remove_text=True, style='mpl20', tol=0.302) +def test_maxlength(): + x, y, U, V = swirl_velocity_field() + ax = plt.figure().subplots() + ax.streamplot(x, y, U, V, maxlength=10., start_points=[[0., 1.5]], + linewidth=2, density=2) + assert ax.get_xlim()[-1] == ax.get_ylim()[-1] == 3 + # Compatibility for old test image + ax.set(xlim=(None, 3.2555988021882305), ylim=(None, 3.078326760195413)) + + +@image_comparison(['streamplot_maxlength_no_broken.png'], + remove_text=True, style='mpl20', tol=0.302) +def test_maxlength_no_broken(): + x, y, U, V = swirl_velocity_field() + ax = plt.figure().subplots() + ax.streamplot(x, y, U, V, maxlength=10., start_points=[[0., 1.5]], + linewidth=2, density=2, broken_streamlines=False) + assert ax.get_xlim()[-1] == ax.get_ylim()[-1] == 3 + # Compatibility for old test image + ax.set(xlim=(None, 3.2555988021882305), ylim=(None, 3.078326760195413)) + + +@image_comparison(['streamplot_direction.png'], + remove_text=True, style='mpl20', tol=0.073) +def test_direction(): + x, y, U, V = swirl_velocity_field() + plt.streamplot(x, y, U, V, integration_direction='backward', + maxlength=1.5, start_points=[[1.5, 0.]], + linewidth=2, density=2) + + +def test_streamplot_limits(): + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans) + # The calculated bounds are approximately the bounds of the original data, + # this is because the entire path is taken into account when updating the + # datalim. + assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6), + decimal=1) + + +def test_streamplot_grid(): + u = np.ones((2, 2)) + v = np.zeros((2, 2)) + + # Test for same rows and columns + x = np.array([[10, 20], [10, 30]]) + y = np.array([[10, 10], [20, 20]]) + + with pytest.raises(ValueError, match="The rows of 'x' must be equal"): + plt.streamplot(x, y, u, v) + + x = np.array([[10, 20], [10, 20]]) + y = np.array([[10, 10], [20, 30]]) + + with pytest.raises(ValueError, match="The columns of 'y' must be equal"): + plt.streamplot(x, y, u, v) + + x = np.array([[10, 20], [10, 20]]) + y = np.array([[10, 10], [20, 20]]) + plt.streamplot(x, y, u, v) + + # Test for maximum dimensions + x = np.array([0, 10]) + y = np.array([[[0, 10]]]) + + with pytest.raises(ValueError, match="'y' can have at maximum " + "2 dimensions"): + plt.streamplot(x, y, u, v) + + # Test for equal spacing + u = np.ones((3, 3)) + v = np.zeros((3, 3)) + x = np.array([0, 10, 20]) + y = np.array([0, 10, 30]) + + with pytest.raises(ValueError, match="'y' values must be equally spaced"): + plt.streamplot(x, y, u, v) + + # Test for strictly increasing + x = np.array([0, 20, 40]) + y = np.array([0, 20, 10]) + + with pytest.raises(ValueError, match="'y' must be strictly increasing"): + plt.streamplot(x, y, u, v) + + +def test_streamplot_inputs(): # test no exception occurs. + # fully-masked + plt.streamplot(np.arange(3), np.arange(3), + np.full((3, 3), np.nan), np.full((3, 3), np.nan), + color=np.random.rand(3, 3)) + # array-likes + plt.streamplot(range(3), range(3), + np.random.rand(3, 3), np.random.rand(3, 3)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_style.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_style.py new file mode 100644 index 00000000..96715ac0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_style.py @@ -0,0 +1,198 @@ +from contextlib import contextmanager +from pathlib import Path +from tempfile import TemporaryDirectory +import sys + +import numpy as np +import pytest + +import matplotlib as mpl +from matplotlib import pyplot as plt, style +from matplotlib.style.core import USER_LIBRARY_PATHS, STYLE_EXTENSION + + +PARAM = 'image.cmap' +VALUE = 'pink' +DUMMY_SETTINGS = {PARAM: VALUE} + + +@contextmanager +def temp_style(style_name, settings=None): + """Context manager to create a style sheet in a temporary directory.""" + if not settings: + settings = DUMMY_SETTINGS + temp_file = f'{style_name}.{STYLE_EXTENSION}' + try: + with TemporaryDirectory() as tmpdir: + # Write style settings to file in the tmpdir. + Path(tmpdir, temp_file).write_text( + "\n".join(f"{k}: {v}" for k, v in settings.items()), + encoding="utf-8") + # Add tmpdir to style path and reload so we can access this style. + USER_LIBRARY_PATHS.append(tmpdir) + style.reload_library() + yield + finally: + style.reload_library() + + +def test_invalid_rc_warning_includes_filename(caplog): + SETTINGS = {'foo': 'bar'} + basename = 'basename' + with temp_style(basename, SETTINGS): + # style.reload_library() in temp_style() triggers the warning + pass + assert (len(caplog.records) == 1 + and basename in caplog.records[0].getMessage()) + + +def test_available(): + with temp_style('_test_', DUMMY_SETTINGS): + assert '_test_' in style.available + + +def test_use(): + mpl.rcParams[PARAM] = 'gray' + with temp_style('test', DUMMY_SETTINGS): + with style.context('test'): + assert mpl.rcParams[PARAM] == VALUE + + +def test_use_url(tmpdir): + path = Path(tmpdir, 'file') + path.write_text('axes.facecolor: adeade', encoding='utf-8') + with temp_style('test', DUMMY_SETTINGS): + url = ('file:' + + ('///' if sys.platform == 'win32' else '') + + path.resolve().as_posix()) + with style.context(url): + assert mpl.rcParams['axes.facecolor'] == "#adeade" + + +def test_single_path(tmpdir): + mpl.rcParams[PARAM] = 'gray' + temp_file = f'text.{STYLE_EXTENSION}' + path = Path(tmpdir, temp_file) + path.write_text(f'{PARAM} : {VALUE}', encoding='utf-8') + with style.context(path): + assert mpl.rcParams[PARAM] == VALUE + assert mpl.rcParams[PARAM] == 'gray' + + +def test_context(): + mpl.rcParams[PARAM] = 'gray' + with temp_style('test', DUMMY_SETTINGS): + with style.context('test'): + assert mpl.rcParams[PARAM] == VALUE + # Check that this value is reset after the exiting the context. + assert mpl.rcParams[PARAM] == 'gray' + + +def test_context_with_dict(): + original_value = 'gray' + other_value = 'blue' + mpl.rcParams[PARAM] = original_value + with style.context({PARAM: other_value}): + assert mpl.rcParams[PARAM] == other_value + assert mpl.rcParams[PARAM] == original_value + + +def test_context_with_dict_after_namedstyle(): + # Test dict after style name where dict modifies the same parameter. + original_value = 'gray' + other_value = 'blue' + mpl.rcParams[PARAM] = original_value + with temp_style('test', DUMMY_SETTINGS): + with style.context(['test', {PARAM: other_value}]): + assert mpl.rcParams[PARAM] == other_value + assert mpl.rcParams[PARAM] == original_value + + +def test_context_with_dict_before_namedstyle(): + # Test dict before style name where dict modifies the same parameter. + original_value = 'gray' + other_value = 'blue' + mpl.rcParams[PARAM] = original_value + with temp_style('test', DUMMY_SETTINGS): + with style.context([{PARAM: other_value}, 'test']): + assert mpl.rcParams[PARAM] == VALUE + assert mpl.rcParams[PARAM] == original_value + + +def test_context_with_union_of_dict_and_namedstyle(): + # Test dict after style name where dict modifies the a different parameter. + original_value = 'gray' + other_param = 'text.usetex' + other_value = True + d = {other_param: other_value} + mpl.rcParams[PARAM] = original_value + mpl.rcParams[other_param] = (not other_value) + with temp_style('test', DUMMY_SETTINGS): + with style.context(['test', d]): + assert mpl.rcParams[PARAM] == VALUE + assert mpl.rcParams[other_param] == other_value + assert mpl.rcParams[PARAM] == original_value + assert mpl.rcParams[other_param] == (not other_value) + + +def test_context_with_badparam(): + original_value = 'gray' + other_value = 'blue' + with style.context({PARAM: other_value}): + assert mpl.rcParams[PARAM] == other_value + x = style.context({PARAM: original_value, 'badparam': None}) + with pytest.raises(KeyError): + with x: + pass + assert mpl.rcParams[PARAM] == other_value + + +@pytest.mark.parametrize('equiv_styles', + [('mpl20', 'default'), + ('mpl15', 'classic')], + ids=['mpl20', 'mpl15']) +def test_alias(equiv_styles): + rc_dicts = [] + for sty in equiv_styles: + with style.context(sty): + rc_dicts.append(mpl.rcParams.copy()) + + rc_base = rc_dicts[0] + for nm, rc in zip(equiv_styles[1:], rc_dicts[1:]): + assert rc_base == rc + + +def test_xkcd_no_cm(): + assert mpl.rcParams["path.sketch"] is None + plt.xkcd() + assert mpl.rcParams["path.sketch"] == (1, 100, 2) + np.testing.break_cycles() + assert mpl.rcParams["path.sketch"] == (1, 100, 2) + + +def test_xkcd_cm(): + assert mpl.rcParams["path.sketch"] is None + with plt.xkcd(): + assert mpl.rcParams["path.sketch"] == (1, 100, 2) + assert mpl.rcParams["path.sketch"] is None + + +def test_up_to_date_blacklist(): + assert mpl.style.core.STYLE_BLACKLIST <= {*mpl.rcsetup._validators} + + +def test_style_from_module(tmp_path, monkeypatch): + monkeypatch.syspath_prepend(tmp_path) + monkeypatch.chdir(tmp_path) + pkg_path = tmp_path / "mpl_test_style_pkg" + pkg_path.mkdir() + (pkg_path / "test_style.mplstyle").write_text( + "lines.linewidth: 42", encoding="utf-8") + pkg_path.with_suffix(".mplstyle").write_text( + "lines.linewidth: 84", encoding="utf-8") + mpl.style.use("mpl_test_style_pkg.test_style") + assert mpl.rcParams["lines.linewidth"] == 42 + mpl.style.use("mpl_test_style_pkg.mplstyle") + assert mpl.rcParams["lines.linewidth"] == 84 + mpl.style.use("./mpl_test_style_pkg.mplstyle") + assert mpl.rcParams["lines.linewidth"] == 84 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_subplots.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_subplots.py new file mode 100644 index 00000000..cf5f4b90 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_subplots.py @@ -0,0 +1,285 @@ +import itertools + +import numpy as np +import pytest + +from matplotlib.axes import Axes, SubplotBase +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import check_figures_equal, image_comparison + + +def check_shared(axs, x_shared, y_shared): + """ + x_shared and y_shared are n x n boolean matrices; entry (i, j) indicates + whether the x (or y) axes of subplots i and j should be shared. + """ + for (i1, ax1), (i2, ax2), (i3, (name, shared)) in itertools.product( + enumerate(axs), + enumerate(axs), + enumerate(zip("xy", [x_shared, y_shared]))): + if i2 <= i1: + continue + assert axs[0]._shared_axes[name].joined(ax1, ax2) == shared[i1, i2], \ + "axes %i and %i incorrectly %ssharing %s axis" % ( + i1, i2, "not " if shared[i1, i2] else "", name) + + +def check_ticklabel_visible(axs, x_visible, y_visible): + """Check that the x and y ticklabel visibility is as specified.""" + for i, (ax, vx, vy) in enumerate(zip(axs, x_visible, y_visible)): + for l in ax.get_xticklabels() + [ax.xaxis.offsetText]: + assert l.get_visible() == vx, \ + f"Visibility of x axis #{i} is incorrectly {vx}" + for l in ax.get_yticklabels() + [ax.yaxis.offsetText]: + assert l.get_visible() == vy, \ + f"Visibility of y axis #{i} is incorrectly {vy}" + # axis label "visibility" is toggled by label_outer by resetting the + # label to empty, but it can also be empty to start with. + if not vx: + assert ax.get_xlabel() == "" + if not vy: + assert ax.get_ylabel() == "" + + +def check_tick1_visible(axs, x_visible, y_visible): + """ + Check that the x and y tick visibility is as specified. + + Note: This only checks the tick1line, i.e. bottom / left ticks. + """ + for ax, visible, in zip(axs, x_visible): + for tick in ax.xaxis.get_major_ticks(): + assert tick.tick1line.get_visible() == visible + for ax, y_visible, in zip(axs, y_visible): + for tick in ax.yaxis.get_major_ticks(): + assert tick.tick1line.get_visible() == visible + + +def test_shared(): + rdim = (4, 4, 2) + share = { + 'all': np.ones(rdim[:2], dtype=bool), + 'none': np.zeros(rdim[:2], dtype=bool), + 'row': np.array([ + [False, True, False, False], + [True, False, False, False], + [False, False, False, True], + [False, False, True, False]]), + 'col': np.array([ + [False, False, True, False], + [False, False, False, True], + [True, False, False, False], + [False, True, False, False]]), + } + visible = { + 'x': { + 'all': [False, False, True, True], + 'col': [False, False, True, True], + 'row': [True] * 4, + 'none': [True] * 4, + False: [True] * 4, + True: [False, False, True, True], + }, + 'y': { + 'all': [True, False, True, False], + 'col': [True] * 4, + 'row': [True, False, True, False], + 'none': [True] * 4, + False: [True] * 4, + True: [True, False, True, False], + }, + } + share[False] = share['none'] + share[True] = share['all'] + + # test default + f, ((a1, a2), (a3, a4)) = plt.subplots(2, 2) + axs = [a1, a2, a3, a4] + check_shared(axs, share['none'], share['none']) + plt.close(f) + + # test all option combinations + ops = [False, True, 'all', 'none', 'row', 'col', 0, 1] + for xo in ops: + for yo in ops: + f, ((a1, a2), (a3, a4)) = plt.subplots(2, 2, sharex=xo, sharey=yo) + axs = [a1, a2, a3, a4] + check_shared(axs, share[xo], share[yo]) + check_ticklabel_visible(axs, visible['x'][xo], visible['y'][yo]) + plt.close(f) + + +@pytest.mark.parametrize('remove_ticks', [True, False]) +def test_label_outer(remove_ticks): + f, axs = plt.subplots(2, 2, sharex=True, sharey=True) + for ax in axs.flat: + ax.set(xlabel="foo", ylabel="bar") + ax.label_outer(remove_inner_ticks=remove_ticks) + check_ticklabel_visible( + axs.flat, [False, False, True, True], [True, False, True, False]) + if remove_ticks: + check_tick1_visible( + axs.flat, [False, False, True, True], [True, False, True, False]) + else: + check_tick1_visible( + axs.flat, [True, True, True, True], [True, True, True, True]) + + +def test_label_outer_span(): + fig = plt.figure() + gs = fig.add_gridspec(3, 3) + # +---+---+---+ + # | 1 | | + # +---+---+---+ + # | | | 3 | + # + 2 +---+---+ + # | | 4 | | + # +---+---+---+ + a1 = fig.add_subplot(gs[0, 0:2]) + a2 = fig.add_subplot(gs[1:3, 0]) + a3 = fig.add_subplot(gs[1, 2]) + a4 = fig.add_subplot(gs[2, 1]) + for ax in fig.axes: + ax.label_outer() + check_ticklabel_visible( + fig.axes, [False, True, False, True], [True, True, False, False]) + + +def test_label_outer_non_gridspec(): + ax = plt.axes((0, 0, 1, 1)) + ax.label_outer() # Does nothing. + check_ticklabel_visible([ax], [True], [True]) + + +def test_shared_and_moved(): + # test if sharey is on, but then tick_left is called that labels don't + # re-appear. Seaborn does this just to be sure yaxis is on left... + f, (a1, a2) = plt.subplots(1, 2, sharey=True) + check_ticklabel_visible([a2], [True], [False]) + a2.yaxis.tick_left() + check_ticklabel_visible([a2], [True], [False]) + + f, (a1, a2) = plt.subplots(2, 1, sharex=True) + check_ticklabel_visible([a1], [False], [True]) + a2.xaxis.tick_bottom() + check_ticklabel_visible([a1], [False], [True]) + + +def test_exceptions(): + # TODO should this test more options? + with pytest.raises(ValueError): + plt.subplots(2, 2, sharex='blah') + with pytest.raises(ValueError): + plt.subplots(2, 2, sharey='blah') + + +@image_comparison(['subplots_offset_text']) +def test_subplots_offsettext(): + x = np.arange(0, 1e10, 1e9) + y = np.arange(0, 100, 10)+1e4 + fig, axs = plt.subplots(2, 2, sharex='col', sharey='all') + axs[0, 0].plot(x, x) + axs[1, 0].plot(x, x) + axs[0, 1].plot(y, x) + axs[1, 1].plot(y, x) + + +@pytest.mark.parametrize("top", [True, False]) +@pytest.mark.parametrize("bottom", [True, False]) +@pytest.mark.parametrize("left", [True, False]) +@pytest.mark.parametrize("right", [True, False]) +def test_subplots_hide_ticklabels(top, bottom, left, right): + # Ideally, we would also test offset-text visibility (and remove + # test_subplots_offsettext), but currently, setting rcParams fails to move + # the offset texts as well. + with plt.rc_context({"xtick.labeltop": top, "xtick.labelbottom": bottom, + "ytick.labelleft": left, "ytick.labelright": right}): + axs = plt.figure().subplots(3, 3, sharex=True, sharey=True) + for (i, j), ax in np.ndenumerate(axs): + xtop = ax.xaxis._major_tick_kw["label2On"] + xbottom = ax.xaxis._major_tick_kw["label1On"] + yleft = ax.yaxis._major_tick_kw["label1On"] + yright = ax.yaxis._major_tick_kw["label2On"] + assert xtop == (top and i == 0) + assert xbottom == (bottom and i == 2) + assert yleft == (left and j == 0) + assert yright == (right and j == 2) + + +@pytest.mark.parametrize("xlabel_position", ["bottom", "top"]) +@pytest.mark.parametrize("ylabel_position", ["left", "right"]) +def test_subplots_hide_axislabels(xlabel_position, ylabel_position): + axs = plt.figure().subplots(3, 3, sharex=True, sharey=True) + for (i, j), ax in np.ndenumerate(axs): + ax.set(xlabel="foo", ylabel="bar") + ax.xaxis.set_label_position(xlabel_position) + ax.yaxis.set_label_position(ylabel_position) + ax.label_outer() + assert bool(ax.get_xlabel()) == ( + xlabel_position == "bottom" and i == 2 + or xlabel_position == "top" and i == 0) + assert bool(ax.get_ylabel()) == ( + ylabel_position == "left" and j == 0 + or ylabel_position == "right" and j == 2) + + +def test_get_gridspec(): + # ahem, pretty trivial, but... + fig, ax = plt.subplots() + assert ax.get_subplotspec().get_gridspec() == ax.get_gridspec() + + +def test_dont_mutate_kwargs(): + subplot_kw = {'sharex': 'all'} + gridspec_kw = {'width_ratios': [1, 2]} + fig, ax = plt.subplots(1, 2, subplot_kw=subplot_kw, + gridspec_kw=gridspec_kw) + assert subplot_kw == {'sharex': 'all'} + assert gridspec_kw == {'width_ratios': [1, 2]} + + +@pytest.mark.parametrize("width_ratios", [None, [1, 3, 2]]) +@pytest.mark.parametrize("height_ratios", [None, [1, 2]]) +@check_figures_equal(extensions=['png']) +def test_width_and_height_ratios(fig_test, fig_ref, + height_ratios, width_ratios): + fig_test.subplots(2, 3, height_ratios=height_ratios, + width_ratios=width_ratios) + fig_ref.subplots(2, 3, gridspec_kw={ + 'height_ratios': height_ratios, + 'width_ratios': width_ratios}) + + +@pytest.mark.parametrize("width_ratios", [None, [1, 3, 2]]) +@pytest.mark.parametrize("height_ratios", [None, [1, 2]]) +@check_figures_equal(extensions=['png']) +def test_width_and_height_ratios_mosaic(fig_test, fig_ref, + height_ratios, width_ratios): + mosaic_spec = [['A', 'B', 'B'], ['A', 'C', 'D']] + fig_test.subplot_mosaic(mosaic_spec, height_ratios=height_ratios, + width_ratios=width_ratios) + fig_ref.subplot_mosaic(mosaic_spec, gridspec_kw={ + 'height_ratios': height_ratios, + 'width_ratios': width_ratios}) + + +@pytest.mark.parametrize('method,args', [ + ('subplots', (2, 3)), + ('subplot_mosaic', ('abc;def', )) + ] +) +def test_ratio_overlapping_kws(method, args): + with pytest.raises(ValueError, match='height_ratios'): + getattr(plt, method)(*args, height_ratios=[1, 2], + gridspec_kw={'height_ratios': [1, 2]}) + with pytest.raises(ValueError, match='width_ratios'): + getattr(plt, method)(*args, width_ratios=[1, 2, 3], + gridspec_kw={'width_ratios': [1, 2, 3]}) + + +def test_old_subplot_compat(): + fig = plt.figure() + assert isinstance(fig.add_subplot(), SubplotBase) + assert not isinstance(fig.add_axes(rect=[0, 0, 1, 1]), SubplotBase) + with pytest.raises(TypeError): + Axes(fig, [0, 0, 1, 1], rect=[0, 0, 1, 1]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_table.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_table.py new file mode 100644 index 00000000..328fd020 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_table.py @@ -0,0 +1,231 @@ +import numpy as np +import pytest + +import matplotlib.pyplot as plt +import matplotlib as mpl +from matplotlib.path import Path +from matplotlib.table import CustomCell, Table +from matplotlib.testing.decorators import image_comparison, check_figures_equal +from matplotlib.transforms import Bbox + + +def test_non_square(): + # Check that creating a non-square table works + cellcolors = ['b', 'r'] + plt.table(cellColours=cellcolors) + + +@image_comparison(['table_zorder.png'], remove_text=True) +def test_zorder(): + data = [[66386, 174296], + [58230, 381139]] + + colLabels = ('Freeze', 'Wind') + rowLabels = ['%d year' % x for x in (100, 50)] + + cellText = [] + yoff = np.zeros(len(colLabels)) + for row in reversed(data): + yoff += row + cellText.append(['%1.1f' % (x/1000.0) for x in yoff]) + + t = np.linspace(0, 2*np.pi, 100) + plt.plot(t, np.cos(t), lw=4, zorder=2) + + plt.table(cellText=cellText, + rowLabels=rowLabels, + colLabels=colLabels, + loc='center', + zorder=-2, + ) + + plt.table(cellText=cellText, + rowLabels=rowLabels, + colLabels=colLabels, + loc='upper center', + zorder=4, + ) + plt.yticks([]) + + +@image_comparison(['table_labels.png']) +def test_label_colours(): + dim = 3 + + c = np.linspace(0, 1, dim) + colours = plt.cm.RdYlGn(c) + cellText = [['1'] * dim] * dim + + fig = plt.figure() + + ax1 = fig.add_subplot(4, 1, 1) + ax1.axis('off') + ax1.table(cellText=cellText, + rowColours=colours, + loc='best') + + ax2 = fig.add_subplot(4, 1, 2) + ax2.axis('off') + ax2.table(cellText=cellText, + rowColours=colours, + rowLabels=['Header'] * dim, + loc='best') + + ax3 = fig.add_subplot(4, 1, 3) + ax3.axis('off') + ax3.table(cellText=cellText, + colColours=colours, + loc='best') + + ax4 = fig.add_subplot(4, 1, 4) + ax4.axis('off') + ax4.table(cellText=cellText, + colColours=colours, + colLabels=['Header'] * dim, + loc='best') + + +@image_comparison(['table_cell_manipulation.png'], remove_text=True) +def test_diff_cell_table(): + cells = ('horizontal', 'vertical', 'open', 'closed', 'T', 'R', 'B', 'L') + cellText = [['1'] * len(cells)] * 2 + colWidths = [0.1] * len(cells) + + _, axs = plt.subplots(nrows=len(cells), figsize=(4, len(cells)+1)) + for ax, cell in zip(axs, cells): + ax.table( + colWidths=colWidths, + cellText=cellText, + loc='center', + edges=cell, + ) + ax.axis('off') + plt.tight_layout() + + +def test_customcell(): + types = ('horizontal', 'vertical', 'open', 'closed', 'T', 'R', 'B', 'L') + codes = ( + (Path.MOVETO, Path.LINETO, Path.MOVETO, Path.LINETO, Path.MOVETO), + (Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO, Path.LINETO), + (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO), + (Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY), + (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO), + (Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO, Path.MOVETO), + (Path.MOVETO, Path.LINETO, Path.MOVETO, Path.MOVETO, Path.MOVETO), + (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.LINETO), + ) + + for t, c in zip(types, codes): + cell = CustomCell((0, 0), visible_edges=t, width=1, height=1) + code = tuple(s for _, s in cell.get_path().iter_segments()) + assert c == code + + +@image_comparison(['table_auto_column.png']) +def test_auto_column(): + fig = plt.figure() + + # iterable list input + ax1 = fig.add_subplot(4, 1, 1) + ax1.axis('off') + tb1 = ax1.table( + cellText=[['Fit Text', 2], + ['very long long text, Longer text than default', 1]], + rowLabels=["A", "B"], + colLabels=["Col1", "Col2"], + loc="center") + tb1.auto_set_font_size(False) + tb1.set_fontsize(12) + tb1.auto_set_column_width([-1, 0, 1]) + + # iterable tuple input + ax2 = fig.add_subplot(4, 1, 2) + ax2.axis('off') + tb2 = ax2.table( + cellText=[['Fit Text', 2], + ['very long long text, Longer text than default', 1]], + rowLabels=["A", "B"], + colLabels=["Col1", "Col2"], + loc="center") + tb2.auto_set_font_size(False) + tb2.set_fontsize(12) + tb2.auto_set_column_width((-1, 0, 1)) + + # 3 single inputs + ax3 = fig.add_subplot(4, 1, 3) + ax3.axis('off') + tb3 = ax3.table( + cellText=[['Fit Text', 2], + ['very long long text, Longer text than default', 1]], + rowLabels=["A", "B"], + colLabels=["Col1", "Col2"], + loc="center") + tb3.auto_set_font_size(False) + tb3.set_fontsize(12) + tb3.auto_set_column_width(-1) + tb3.auto_set_column_width(0) + tb3.auto_set_column_width(1) + + # 4 non integer iterable input + ax4 = fig.add_subplot(4, 1, 4) + ax4.axis('off') + tb4 = ax4.table( + cellText=[['Fit Text', 2], + ['very long long text, Longer text than default', 1]], + rowLabels=["A", "B"], + colLabels=["Col1", "Col2"], + loc="center") + tb4.auto_set_font_size(False) + tb4.set_fontsize(12) + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="'col' must be an int or sequence of ints"): + tb4.auto_set_column_width("-101") # type: ignore [arg-type] + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="'col' must be an int or sequence of ints"): + tb4.auto_set_column_width(["-101"]) # type: ignore [list-item] + + +def test_table_cells(): + fig, ax = plt.subplots() + table = Table(ax) + + cell = table.add_cell(1, 2, 1, 1) + assert isinstance(cell, CustomCell) + assert cell is table[1, 2] + + cell2 = CustomCell((0, 0), 1, 2, visible_edges=None) + table[2, 1] = cell2 + assert table[2, 1] is cell2 + + # make sure getitem support has not broken + # properties and setp + table.properties() + plt.setp(table) + + +@check_figures_equal(extensions=["png"]) +def test_table_bbox(fig_test, fig_ref): + data = [[2, 3], + [4, 5]] + + col_labels = ('Foo', 'Bar') + row_labels = ('Ada', 'Bob') + + cell_text = [[f"{x}" for x in row] for row in data] + + ax_list = fig_test.subplots() + ax_list.table(cellText=cell_text, + rowLabels=row_labels, + colLabels=col_labels, + loc='center', + bbox=[0.1, 0.2, 0.8, 0.6] + ) + + ax_bbox = fig_ref.subplots() + ax_bbox.table(cellText=cell_text, + rowLabels=row_labels, + colLabels=col_labels, + loc='center', + bbox=Bbox.from_extents(0.1, 0.2, 0.9, 0.8) + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_testing.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_testing.py new file mode 100644 index 00000000..f13839d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_testing.py @@ -0,0 +1,41 @@ +import warnings + +import pytest + +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import check_figures_equal + + +@pytest.mark.xfail( + strict=True, reason="testing that warnings fail tests" +) +def test_warn_to_fail(): + warnings.warn("This should fail the test") + + +@pytest.mark.parametrize("a", [1]) +@check_figures_equal(extensions=["png"]) +@pytest.mark.parametrize("b", [1]) +def test_parametrize_with_check_figure_equal(a, fig_ref, b, fig_test): + assert a == b + + +def test_wrap_failure(): + with pytest.raises(ValueError, match="^The decorated function"): + @check_figures_equal() + def should_fail(test, ref): + pass + + +@pytest.mark.xfail(raises=RuntimeError, strict=True, + reason='Test for check_figures_equal test creating ' + 'new figures') +@check_figures_equal() +def test_check_figures_equal_extra_fig(fig_test, fig_ref): + plt.figure() + + +@check_figures_equal() +def test_check_figures_equal_closed_fig(fig_test, fig_ref): + fig = plt.figure() + plt.close(fig) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_texmanager.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_texmanager.py new file mode 100644 index 00000000..fbff2114 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_texmanager.py @@ -0,0 +1,74 @@ +import os +from pathlib import Path +import re +import subprocess +import sys + +import matplotlib.pyplot as plt +from matplotlib.texmanager import TexManager +from matplotlib.testing._markers import needs_usetex +import pytest + + +def test_fontconfig_preamble(): + """Test that the preamble is included in the source.""" + plt.rcParams['text.usetex'] = True + + src1 = TexManager()._get_tex_source("", fontsize=12) + plt.rcParams['text.latex.preamble'] = '\\usepackage{txfonts}' + src2 = TexManager()._get_tex_source("", fontsize=12) + + assert src1 != src2 + + +@pytest.mark.parametrize( + "rc, preamble, family", [ + ({"font.family": "sans-serif", "font.sans-serif": "helvetica"}, + r"\usepackage{helvet}", r"\sffamily"), + ({"font.family": "serif", "font.serif": "palatino"}, + r"\usepackage{mathpazo}", r"\rmfamily"), + ({"font.family": "cursive", "font.cursive": "zapf chancery"}, + r"\usepackage{chancery}", r"\rmfamily"), + ({"font.family": "monospace", "font.monospace": "courier"}, + r"\usepackage{courier}", r"\ttfamily"), + ({"font.family": "helvetica"}, r"\usepackage{helvet}", r"\sffamily"), + ({"font.family": "palatino"}, r"\usepackage{mathpazo}", r"\rmfamily"), + ({"font.family": "zapf chancery"}, + r"\usepackage{chancery}", r"\rmfamily"), + ({"font.family": "courier"}, r"\usepackage{courier}", r"\ttfamily") + ]) +def test_font_selection(rc, preamble, family): + plt.rcParams.update(rc) + tm = TexManager() + src = Path(tm.make_tex("hello, world", fontsize=12)).read_text() + assert preamble in src + assert [*re.findall(r"\\\w+family", src)] == [family] + + +@needs_usetex +def test_unicode_characters(): + # Smoke test to see that Unicode characters does not cause issues + # See #23019 + plt.rcParams['text.usetex'] = True + fig, ax = plt.subplots() + ax.set_ylabel('\\textit{Velocity (\N{DEGREE SIGN}/sec)}') + ax.set_xlabel('\N{VULGAR FRACTION ONE QUARTER}Öøæ') + fig.canvas.draw() + + # But not all characters. + # Should raise RuntimeError, not UnicodeDecodeError + with pytest.raises(RuntimeError): + ax.set_title('\N{SNOWMAN}') + fig.canvas.draw() + + +@needs_usetex +def test_openin_any_paranoid(): + completed = subprocess.run( + [sys.executable, "-c", + 'import matplotlib.pyplot as plt;' + 'plt.rcParams.update({"text.usetex": True});' + 'plt.title("paranoid");' + 'plt.show(block=False);'], + env={**os.environ, 'openin_any': 'p'}, check=True, capture_output=True) + assert completed.stderr == b"" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_text.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_text.py new file mode 100644 index 00000000..7222d5b0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_text.py @@ -0,0 +1,966 @@ +from datetime import datetime +import io +import warnings + +import numpy as np +from numpy.testing import assert_almost_equal +from packaging.version import parse as parse_version +import pyparsing +import pytest + +import matplotlib as mpl +from matplotlib.backend_bases import MouseEvent +from matplotlib.font_manager import FontProperties +import matplotlib.patches as mpatches +import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing._markers import needs_usetex +from matplotlib.text import Text, Annotation, OffsetFrom + +pyparsing_version = parse_version(pyparsing.__version__) + + +@image_comparison(['font_styles']) +def test_font_styles(): + + def find_matplotlib_font(**kw): + prop = FontProperties(**kw) + path = findfont(prop, directory=mpl.get_data_path()) + return FontProperties(fname=path) + + from matplotlib.font_manager import FontProperties, findfont + warnings.filterwarnings( + 'ignore', + r"findfont: Font family \[u?'Foo'\] not found. Falling back to .", + UserWarning, + module='matplotlib.font_manager') + + fig, ax = plt.subplots() + + normal_font = find_matplotlib_font( + family="sans-serif", + style="normal", + variant="normal", + size=14) + a = ax.annotate( + "Normal Font", + (0.1, 0.1), + xycoords='axes fraction', + fontproperties=normal_font) + assert a.get_fontname() == 'DejaVu Sans' + assert a.get_fontstyle() == 'normal' + assert a.get_fontvariant() == 'normal' + assert a.get_weight() == 'normal' + assert a.get_stretch() == 'normal' + + bold_font = find_matplotlib_font( + family="Foo", + style="normal", + variant="normal", + weight="bold", + stretch=500, + size=14) + ax.annotate( + "Bold Font", + (0.1, 0.2), + xycoords='axes fraction', + fontproperties=bold_font) + + bold_italic_font = find_matplotlib_font( + family="sans serif", + style="italic", + variant="normal", + weight=750, + stretch=500, + size=14) + ax.annotate( + "Bold Italic Font", + (0.1, 0.3), + xycoords='axes fraction', + fontproperties=bold_italic_font) + + light_font = find_matplotlib_font( + family="sans-serif", + style="normal", + variant="normal", + weight=200, + stretch=500, + size=14) + ax.annotate( + "Light Font", + (0.1, 0.4), + xycoords='axes fraction', + fontproperties=light_font) + + condensed_font = find_matplotlib_font( + family="sans-serif", + style="normal", + variant="normal", + weight=500, + stretch=100, + size=14) + ax.annotate( + "Condensed Font", + (0.1, 0.5), + xycoords='axes fraction', + fontproperties=condensed_font) + + ax.set_xticks([]) + ax.set_yticks([]) + + +@image_comparison(['multiline']) +def test_multiline(): + plt.figure() + ax = plt.subplot(1, 1, 1) + ax.set_title("multiline\ntext alignment") + + plt.text( + 0.2, 0.5, "TpTpTp\n$M$\nTpTpTp", size=20, ha="center", va="top") + + plt.text( + 0.5, 0.5, "TpTpTp\n$M^{M^{M^{M}}}$\nTpTpTp", size=20, + ha="center", va="top") + + plt.text( + 0.8, 0.5, "TpTpTp\n$M_{q_{q_{q}}}$\nTpTpTp", size=20, + ha="center", va="top") + + plt.xlim(0, 1) + plt.ylim(0, 0.8) + + ax.set_xticks([]) + ax.set_yticks([]) + + +@image_comparison(['multiline2'], style='mpl20') +def test_multiline2(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, ax = plt.subplots() + + ax.set_xlim([0, 1.4]) + ax.set_ylim([0, 2]) + ax.axhline(0.5, color='C2', linewidth=0.3) + sts = ['Line', '2 Lineg\n 2 Lg', '$\\sum_i x $', 'hi $\\sum_i x $\ntest', + 'test\n $\\sum_i x $', '$\\sum_i x $\n $\\sum_i x $'] + renderer = fig.canvas.get_renderer() + + def draw_box(ax, tt): + r = mpatches.Rectangle((0, 0), 1, 1, clip_on=False, + transform=ax.transAxes) + r.set_bounds( + tt.get_window_extent(renderer) + .transformed(ax.transAxes.inverted()) + .bounds) + ax.add_patch(r) + + horal = 'left' + for nn, st in enumerate(sts): + tt = ax.text(0.2 * nn + 0.1, 0.5, st, horizontalalignment=horal, + verticalalignment='bottom') + draw_box(ax, tt) + ax.text(1.2, 0.5, 'Bottom align', color='C2') + + ax.axhline(1.3, color='C2', linewidth=0.3) + for nn, st in enumerate(sts): + tt = ax.text(0.2 * nn + 0.1, 1.3, st, horizontalalignment=horal, + verticalalignment='top') + draw_box(ax, tt) + ax.text(1.2, 1.3, 'Top align', color='C2') + + ax.axhline(1.8, color='C2', linewidth=0.3) + for nn, st in enumerate(sts): + tt = ax.text(0.2 * nn + 0.1, 1.8, st, horizontalalignment=horal, + verticalalignment='baseline') + draw_box(ax, tt) + ax.text(1.2, 1.8, 'Baseline align', color='C2') + + ax.axhline(0.1, color='C2', linewidth=0.3) + for nn, st in enumerate(sts): + tt = ax.text(0.2 * nn + 0.1, 0.1, st, horizontalalignment=horal, + verticalalignment='bottom', rotation=20) + draw_box(ax, tt) + ax.text(1.2, 0.1, 'Bot align, rot20', color='C2') + + +@image_comparison(['antialiased.png'], style='mpl20') +def test_antialiasing(): + mpl.rcParams['text.antialiased'] = False # Passed arguments should override. + + fig = plt.figure(figsize=(5.25, 0.75)) + fig.text(0.3, 0.75, "antialiased", horizontalalignment='center', + verticalalignment='center', antialiased=True) + fig.text(0.3, 0.25, r"$\sqrt{x}$", horizontalalignment='center', + verticalalignment='center', antialiased=True) + + mpl.rcParams['text.antialiased'] = True # Passed arguments should override. + fig.text(0.7, 0.75, "not antialiased", horizontalalignment='center', + verticalalignment='center', antialiased=False) + fig.text(0.7, 0.25, r"$\sqrt{x}$", horizontalalignment='center', + verticalalignment='center', antialiased=False) + + mpl.rcParams['text.antialiased'] = False # Should not affect existing text. + + +def test_afm_kerning(): + fn = mpl.font_manager.findfont("Helvetica", fontext="afm") + with open(fn, 'rb') as fh: + afm = mpl._afm.AFM(fh) + assert afm.string_width_height('VAVAVAVAVAVA') == (7174.0, 718) + + +@image_comparison(['text_contains.png']) +def test_contains(): + fig = plt.figure() + ax = plt.axes() + + mevent = MouseEvent('button_press_event', fig.canvas, 0.5, 0.5, 1, None) + + xs = np.linspace(0.25, 0.75, 30) + ys = np.linspace(0.25, 0.75, 30) + xs, ys = np.meshgrid(xs, ys) + + txt = plt.text( + 0.5, 0.4, 'hello world', ha='center', fontsize=30, rotation=30) + # uncomment to draw the text's bounding box + # txt.set_bbox(dict(edgecolor='black', facecolor='none')) + + # draw the text. This is important, as the contains method can only work + # when a renderer exists. + fig.canvas.draw() + + for x, y in zip(xs.flat, ys.flat): + mevent.x, mevent.y = plt.gca().transAxes.transform([x, y]) + contains, _ = txt.contains(mevent) + color = 'yellow' if contains else 'red' + + # capture the viewLim, plot a point, and reset the viewLim + vl = ax.viewLim.frozen() + ax.plot(x, y, 'o', color=color) + ax.viewLim.set(vl) + + +def test_annotation_contains(): + # Check that Annotation.contains looks at the bboxes of the text and the + # arrow separately, not at the joint bbox. + fig, ax = plt.subplots() + ann = ax.annotate( + "hello", xy=(.4, .4), xytext=(.6, .6), arrowprops={"arrowstyle": "->"}) + fig.canvas.draw() # Needed for the same reason as in test_contains. + event = MouseEvent( + "button_press_event", fig.canvas, *ax.transData.transform((.5, .6))) + assert ann.contains(event) == (False, {}) + + +@pytest.mark.parametrize('err, xycoords, match', ( + (TypeError, print, "xycoords callable must return a BboxBase or Transform, not a"), + (TypeError, [0, 0], r"'xycoords' must be an instance of str, tuple"), + (ValueError, "foo", "'foo' is not a valid coordinate"), + (ValueError, "foo bar", "'foo bar' is not a valid coordinate"), + (ValueError, "offset foo", "xycoords cannot be an offset coordinate"), + (ValueError, "axes foo", "'foo' is not a recognized unit"), +)) +def test_annotate_errors(err, xycoords, match): + fig, ax = plt.subplots() + with pytest.raises(err, match=match): + ax.annotate('xy', (0, 0), xytext=(0.5, 0.5), xycoords=xycoords) + fig.canvas.draw() + + +@image_comparison(['titles']) +def test_titles(): + # left and right side titles + plt.figure() + ax = plt.subplot(1, 1, 1) + ax.set_title("left title", loc="left") + ax.set_title("right title", loc="right") + ax.set_xticks([]) + ax.set_yticks([]) + + +@image_comparison(['text_alignment'], style='mpl20') +def test_alignment(): + plt.figure() + ax = plt.subplot(1, 1, 1) + + x = 0.1 + for rotation in (0, 30): + for alignment in ('top', 'bottom', 'baseline', 'center'): + ax.text( + x, 0.5, alignment + " Tj", va=alignment, rotation=rotation, + bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5)) + ax.text( + x, 1.0, r'$\sum_{i=0}^{j}$', va=alignment, rotation=rotation) + x += 0.1 + + ax.plot([0, 1], [0.5, 0.5]) + ax.plot([0, 1], [1.0, 1.0]) + + ax.set_xlim(0, 1) + ax.set_ylim(0, 1.5) + ax.set_xticks([]) + ax.set_yticks([]) + + +@image_comparison(['axes_titles.png']) +def test_axes_titles(): + # Related to issue #3327 + plt.figure() + ax = plt.subplot(1, 1, 1) + ax.set_title('center', loc='center', fontsize=20, fontweight=700) + ax.set_title('left', loc='left', fontsize=12, fontweight=400) + ax.set_title('right', loc='right', fontsize=12, fontweight=400) + + +def test_set_position(): + fig, ax = plt.subplots() + + # test set_position + ann = ax.annotate( + 'test', (0, 0), xytext=(0, 0), textcoords='figure pixels') + fig.canvas.draw() + + init_pos = ann.get_window_extent(fig.canvas.renderer) + shift_val = 15 + ann.set_position((shift_val, shift_val)) + fig.canvas.draw() + post_pos = ann.get_window_extent(fig.canvas.renderer) + + for a, b in zip(init_pos.min, post_pos.min): + assert a + shift_val == b + + # test xyann + ann = ax.annotate( + 'test', (0, 0), xytext=(0, 0), textcoords='figure pixels') + fig.canvas.draw() + + init_pos = ann.get_window_extent(fig.canvas.renderer) + shift_val = 15 + ann.xyann = (shift_val, shift_val) + fig.canvas.draw() + post_pos = ann.get_window_extent(fig.canvas.renderer) + + for a, b in zip(init_pos.min, post_pos.min): + assert a + shift_val == b + + +def test_char_index_at(): + fig = plt.figure() + text = fig.text(0.1, 0.9, "") + + text.set_text("i") + bbox = text.get_window_extent() + size_i = bbox.x1 - bbox.x0 + + text.set_text("m") + bbox = text.get_window_extent() + size_m = bbox.x1 - bbox.x0 + + text.set_text("iiiimmmm") + bbox = text.get_window_extent() + origin = bbox.x0 + + assert text._char_index_at(origin - size_i) == 0 # left of first char + assert text._char_index_at(origin) == 0 + assert text._char_index_at(origin + 0.499*size_i) == 0 + assert text._char_index_at(origin + 0.501*size_i) == 1 + assert text._char_index_at(origin + size_i*3) == 3 + assert text._char_index_at(origin + size_i*4 + size_m*3) == 7 + assert text._char_index_at(origin + size_i*4 + size_m*4) == 8 + assert text._char_index_at(origin + size_i*4 + size_m*10) == 8 + + +@pytest.mark.parametrize('text', ['', 'O'], ids=['empty', 'non-empty']) +def test_non_default_dpi(text): + fig, ax = plt.subplots() + + t1 = ax.text(0.5, 0.5, text, ha='left', va='bottom') + fig.canvas.draw() + dpi = fig.dpi + + bbox1 = t1.get_window_extent() + bbox2 = t1.get_window_extent(dpi=dpi * 10) + np.testing.assert_allclose(bbox2.get_points(), bbox1.get_points() * 10, + rtol=5e-2) + # Text.get_window_extent should not permanently change dpi. + assert fig.dpi == dpi + + +def test_get_rotation_string(): + assert Text(rotation='horizontal').get_rotation() == 0. + assert Text(rotation='vertical').get_rotation() == 90. + + +def test_get_rotation_float(): + for i in [15., 16.70, 77.4]: + assert Text(rotation=i).get_rotation() == i + + +def test_get_rotation_int(): + for i in [67, 16, 41]: + assert Text(rotation=i).get_rotation() == float(i) + + +def test_get_rotation_raises(): + with pytest.raises(ValueError): + Text(rotation='hozirontal') + + +def test_get_rotation_none(): + assert Text(rotation=None).get_rotation() == 0.0 + + +def test_get_rotation_mod360(): + for i, j in zip([360., 377., 720+177.2], [0., 17., 177.2]): + assert_almost_equal(Text(rotation=i).get_rotation(), j) + + +@pytest.mark.parametrize("ha", ["center", "right", "left"]) +@pytest.mark.parametrize("va", ["center", "top", "bottom", + "baseline", "center_baseline"]) +def test_null_rotation_with_rotation_mode(ha, va): + fig, ax = plt.subplots() + kw = dict(rotation=0, va=va, ha=ha) + t0 = ax.text(.5, .5, 'test', rotation_mode='anchor', **kw) + t1 = ax.text(.5, .5, 'test', rotation_mode='default', **kw) + fig.canvas.draw() + assert_almost_equal(t0.get_window_extent(fig.canvas.renderer).get_points(), + t1.get_window_extent(fig.canvas.renderer).get_points()) + + +@image_comparison(['text_bboxclip']) +def test_bbox_clipping(): + plt.text(0.9, 0.2, 'Is bbox clipped?', backgroundcolor='r', clip_on=True) + t = plt.text(0.9, 0.5, 'Is fancy bbox clipped?', clip_on=True) + t.set_bbox({"boxstyle": "round, pad=0.1"}) + + +@image_comparison(['annotation_negative_ax_coords.png']) +def test_annotation_negative_ax_coords(): + fig, ax = plt.subplots() + + ax.annotate('+ pts', + xytext=[30, 20], textcoords='axes points', + xy=[30, 20], xycoords='axes points', fontsize=32) + ax.annotate('- pts', + xytext=[30, -20], textcoords='axes points', + xy=[30, -20], xycoords='axes points', fontsize=32, + va='top') + ax.annotate('+ frac', + xytext=[0.75, 0.05], textcoords='axes fraction', + xy=[0.75, 0.05], xycoords='axes fraction', fontsize=32) + ax.annotate('- frac', + xytext=[0.75, -0.05], textcoords='axes fraction', + xy=[0.75, -0.05], xycoords='axes fraction', fontsize=32, + va='top') + + ax.annotate('+ pixels', + xytext=[160, 25], textcoords='axes pixels', + xy=[160, 25], xycoords='axes pixels', fontsize=32) + ax.annotate('- pixels', + xytext=[160, -25], textcoords='axes pixels', + xy=[160, -25], xycoords='axes pixels', fontsize=32, + va='top') + + +@image_comparison(['annotation_negative_fig_coords.png']) +def test_annotation_negative_fig_coords(): + fig, ax = plt.subplots() + + ax.annotate('+ pts', + xytext=[10, 120], textcoords='figure points', + xy=[10, 120], xycoords='figure points', fontsize=32) + ax.annotate('- pts', + xytext=[-10, 180], textcoords='figure points', + xy=[-10, 180], xycoords='figure points', fontsize=32, + va='top') + ax.annotate('+ frac', + xytext=[0.05, 0.55], textcoords='figure fraction', + xy=[0.05, 0.55], xycoords='figure fraction', fontsize=32) + ax.annotate('- frac', + xytext=[-0.05, 0.5], textcoords='figure fraction', + xy=[-0.05, 0.5], xycoords='figure fraction', fontsize=32, + va='top') + + ax.annotate('+ pixels', + xytext=[50, 50], textcoords='figure pixels', + xy=[50, 50], xycoords='figure pixels', fontsize=32) + ax.annotate('- pixels', + xytext=[-50, 100], textcoords='figure pixels', + xy=[-50, 100], xycoords='figure pixels', fontsize=32, + va='top') + + +def test_text_stale(): + fig, (ax1, ax2) = plt.subplots(1, 2) + plt.draw_all() + assert not ax1.stale + assert not ax2.stale + assert not fig.stale + + txt1 = ax1.text(.5, .5, 'aardvark') + assert ax1.stale + assert txt1.stale + assert fig.stale + + ann1 = ax2.annotate('aardvark', xy=[.5, .5]) + assert ax2.stale + assert ann1.stale + assert fig.stale + + plt.draw_all() + assert not ax1.stale + assert not ax2.stale + assert not fig.stale + + +@image_comparison(['agg_text_clip.png']) +def test_agg_text_clip(): + np.random.seed(1) + fig, (ax1, ax2) = plt.subplots(2) + for x, y in np.random.rand(10, 2): + ax1.text(x, y, "foo", clip_on=True) + ax2.text(x, y, "foo") + + +def test_text_size_binding(): + mpl.rcParams['font.size'] = 10 + fp = mpl.font_manager.FontProperties(size='large') + sz1 = fp.get_size_in_points() + mpl.rcParams['font.size'] = 100 + + assert sz1 == fp.get_size_in_points() + + +@image_comparison(['font_scaling.pdf']) +def test_font_scaling(): + mpl.rcParams['pdf.fonttype'] = 42 + fig, ax = plt.subplots(figsize=(6.4, 12.4)) + ax.xaxis.set_major_locator(plt.NullLocator()) + ax.yaxis.set_major_locator(plt.NullLocator()) + ax.set_ylim(-10, 600) + + for i, fs in enumerate(range(4, 43, 2)): + ax.text(0.1, i*30, f"{fs} pt font size", fontsize=fs) + + +@pytest.mark.parametrize('spacing1, spacing2', [(0.4, 2), (2, 0.4), (2, 2)]) +def test_two_2line_texts(spacing1, spacing2): + text_string = 'line1\nline2' + fig = plt.figure() + renderer = fig.canvas.get_renderer() + + text1 = fig.text(0.25, 0.5, text_string, linespacing=spacing1) + text2 = fig.text(0.25, 0.5, text_string, linespacing=spacing2) + fig.canvas.draw() + + box1 = text1.get_window_extent(renderer=renderer) + box2 = text2.get_window_extent(renderer=renderer) + + # line spacing only affects height + assert box1.width == box2.width + if spacing1 == spacing2: + assert box1.height == box2.height + else: + assert box1.height != box2.height + + +def test_validate_linespacing(): + with pytest.raises(TypeError): + plt.text(.25, .5, "foo", linespacing="abc") + + +def test_nonfinite_pos(): + fig, ax = plt.subplots() + ax.text(0, np.nan, 'nan') + ax.text(np.inf, 0, 'inf') + fig.canvas.draw() + + +def test_hinting_factor_backends(): + plt.rcParams['text.hinting_factor'] = 1 + fig = plt.figure() + t = fig.text(0.5, 0.5, 'some text') + + fig.savefig(io.BytesIO(), format='svg') + expected = t.get_window_extent().intervalx + + fig.savefig(io.BytesIO(), format='png') + # Backends should apply hinting_factor consistently (within 10%). + np.testing.assert_allclose(t.get_window_extent().intervalx, expected, + rtol=0.1) + + +@needs_usetex +def test_usetex_is_copied(): + # Indirectly tests that update_from (which is used to copy tick label + # properties) copies usetex state. + fig = plt.figure() + plt.rcParams["text.usetex"] = False + ax1 = fig.add_subplot(121) + plt.rcParams["text.usetex"] = True + ax2 = fig.add_subplot(122) + fig.canvas.draw() + for ax, usetex in [(ax1, False), (ax2, True)]: + for t in ax.xaxis.majorTicks: + assert t.label1.get_usetex() == usetex + + +@needs_usetex +def test_single_artist_usetex(): + # Check that a single artist marked with usetex does not get passed through + # the mathtext parser at all (for the Agg backend) (the mathtext parser + # currently fails to parse \frac12, requiring \frac{1}{2} instead). + fig = plt.figure() + fig.text(.5, .5, r"$\frac12$", usetex=True) + fig.canvas.draw() + + +@pytest.mark.parametrize("fmt", ["png", "pdf", "svg"]) +def test_single_artist_usenotex(fmt): + # Check that a single artist can be marked as not-usetex even though the + # rcParam is on ("2_2_2" fails if passed to TeX). This currently skips + # postscript output as the ps renderer doesn't support mixing usetex and + # non-usetex. + plt.rcParams["text.usetex"] = True + fig = plt.figure() + fig.text(.5, .5, "2_2_2", usetex=False) + fig.savefig(io.BytesIO(), format=fmt) + + +@image_comparison(['text_as_path_opacity.svg']) +def test_text_as_path_opacity(): + plt.figure() + plt.gca().set_axis_off() + plt.text(0.25, 0.25, 'c', color=(0, 0, 0, 0.5)) + plt.text(0.25, 0.5, 'a', alpha=0.5) + plt.text(0.25, 0.75, 'x', alpha=0.5, color=(0, 0, 0, 1)) + + +@image_comparison(['text_as_text_opacity.svg']) +def test_text_as_text_opacity(): + mpl.rcParams['svg.fonttype'] = 'none' + plt.figure() + plt.gca().set_axis_off() + plt.text(0.25, 0.25, '50% using `color`', color=(0, 0, 0, 0.5)) + plt.text(0.25, 0.5, '50% using `alpha`', alpha=0.5) + plt.text(0.25, 0.75, '50% using `alpha` and 100% `color`', alpha=0.5, + color=(0, 0, 0, 1)) + + +def test_text_repr(): + # smoketest to make sure text repr doesn't error for category + plt.plot(['A', 'B'], [1, 2]) + repr(plt.text(['A'], 0.5, 'Boo')) + + +def test_annotation_update(): + fig, ax = plt.subplots(1, 1) + an = ax.annotate('annotation', xy=(0.5, 0.5)) + extent1 = an.get_window_extent(fig.canvas.get_renderer()) + fig.tight_layout() + extent2 = an.get_window_extent(fig.canvas.get_renderer()) + + assert not np.allclose(extent1.get_points(), extent2.get_points(), + rtol=1e-6) + + +@check_figures_equal(extensions=["png"]) +def test_annotation_units(fig_test, fig_ref): + ax = fig_test.add_subplot() + ax.plot(datetime.now(), 1, "o") # Implicitly set axes extents. + ax.annotate("x", (datetime.now(), 0.5), xycoords=("data", "axes fraction"), + # This used to crash before. + xytext=(0, 0), textcoords="offset points") + ax = fig_ref.add_subplot() + ax.plot(datetime.now(), 1, "o") + ax.annotate("x", (datetime.now(), 0.5), xycoords=("data", "axes fraction")) + + +@image_comparison(['large_subscript_title.png'], style='mpl20') +def test_large_subscript_title(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + plt.rcParams['axes.titley'] = None + + fig, axs = plt.subplots(1, 2, figsize=(9, 2.5), constrained_layout=True) + ax = axs[0] + ax.set_title(r'$\sum_{i} x_i$') + ax.set_title('New way', loc='left') + ax.set_xticklabels([]) + + ax = axs[1] + ax.set_title(r'$\sum_{i} x_i$', y=1.01) + ax.set_title('Old Way', loc='left') + ax.set_xticklabels([]) + + +@pytest.mark.parametrize( + "x, rotation, halign", + [(0.7, 0, 'left'), + (0.5, 95, 'left'), + (0.3, 0, 'right'), + (0.3, 185, 'left')]) +def test_wrap(x, rotation, halign): + fig = plt.figure(figsize=(6, 6)) + s = 'This is a very long text that should be wrapped multiple times.' + text = fig.text(x, 0.7, s, wrap=True, rotation=rotation, ha=halign) + fig.canvas.draw() + assert text._get_wrapped_text() == ('This is a very long\n' + 'text that should be\n' + 'wrapped multiple\n' + 'times.') + + +def test_mathwrap(): + fig = plt.figure(figsize=(6, 4)) + s = r'This is a very $\overline{\mathrm{long}}$ line of Mathtext.' + text = fig.text(0, 0.5, s, size=40, wrap=True) + fig.canvas.draw() + assert text._get_wrapped_text() == ('This is a very $\\overline{\\mathrm{long}}$\n' + 'line of Mathtext.') + + +def test_get_window_extent_wrapped(): + # Test that a long title that wraps to two lines has the same vertical + # extent as an explicit two line title. + + fig1 = plt.figure(figsize=(3, 3)) + fig1.suptitle("suptitle that is clearly too long in this case", wrap=True) + window_extent_test = fig1._suptitle.get_window_extent() + + fig2 = plt.figure(figsize=(3, 3)) + fig2.suptitle("suptitle that is clearly\ntoo long in this case") + window_extent_ref = fig2._suptitle.get_window_extent() + + assert window_extent_test.y0 == window_extent_ref.y0 + assert window_extent_test.y1 == window_extent_ref.y1 + + +def test_long_word_wrap(): + fig = plt.figure(figsize=(6, 4)) + text = fig.text(9.5, 8, 'Alonglineoftexttowrap', wrap=True) + fig.canvas.draw() + assert text._get_wrapped_text() == 'Alonglineoftexttowrap' + + +def test_wrap_no_wrap(): + fig = plt.figure(figsize=(6, 4)) + text = fig.text(0, 0, 'non wrapped text', wrap=True) + fig.canvas.draw() + assert text._get_wrapped_text() == 'non wrapped text' + + +@check_figures_equal(extensions=["png"]) +def test_buffer_size(fig_test, fig_ref): + # On old versions of the Agg renderer, large non-ascii single-character + # strings (here, "€") would be rendered clipped because the rendering + # buffer would be set by the physical size of the smaller "a" character. + ax = fig_test.add_subplot() + ax.set_yticks([0, 1]) + ax.set_yticklabels(["€", "a"]) + ax.yaxis.majorTicks[1].label1.set_color("w") + ax = fig_ref.add_subplot() + ax.set_yticks([0, 1]) + ax.set_yticklabels(["€", ""]) + + +def test_fontproperties_kwarg_precedence(): + """Test that kwargs take precedence over fontproperties defaults.""" + plt.figure() + text1 = plt.xlabel("value", fontproperties='Times New Roman', size=40.0) + text2 = plt.ylabel("counts", size=40.0, fontproperties='Times New Roman') + assert text1.get_size() == 40.0 + assert text2.get_size() == 40.0 + + +def test_transform_rotates_text(): + ax = plt.gca() + transform = mtransforms.Affine2D().rotate_deg(30) + text = ax.text(0, 0, 'test', transform=transform, + transform_rotates_text=True) + result = text.get_rotation() + assert_almost_equal(result, 30) + + +def test_update_mutate_input(): + inp = dict(fontproperties=FontProperties(weight="bold"), + bbox=None) + cache = dict(inp) + t = Text() + t.update(inp) + assert inp['fontproperties'] == cache['fontproperties'] + assert inp['bbox'] == cache['bbox'] + + +@pytest.mark.parametrize('rotation', ['invalid string', [90]]) +def test_invalid_rotation_values(rotation): + with pytest.raises( + ValueError, + match=("rotation must be 'vertical', 'horizontal' or a number")): + Text(0, 0, 'foo', rotation=rotation) + + +def test_invalid_color(): + with pytest.raises(ValueError): + plt.figtext(.5, .5, "foo", c="foobar") + + +@image_comparison(['text_pdf_kerning.pdf'], style='mpl20') +def test_pdf_kerning(): + plt.figure() + plt.figtext(0.1, 0.5, "ATATATATATATATATATA", size=30) + + +def test_unsupported_script(recwarn): + fig = plt.figure() + fig.text(.5, .5, "\N{BENGALI DIGIT ZERO}") + fig.canvas.draw() + assert all(isinstance(warn.message, UserWarning) for warn in recwarn) + assert ( + [warn.message.args for warn in recwarn] == + [(r"Glyph 2534 (\N{BENGALI DIGIT ZERO}) missing from current font.",), + (r"Matplotlib currently does not support Bengali natively.",)]) + + +# See gh-26152 for more information on this xfail +@pytest.mark.xfail(pyparsing_version.release == (3, 1, 0), + reason="Error messages are incorrect with pyparsing 3.1.0") +def test_parse_math(): + fig, ax = plt.subplots() + ax.text(0, 0, r"$ \wrong{math} $", parse_math=False) + fig.canvas.draw() + + ax.text(0, 0, r"$ \wrong{math} $", parse_math=True) + with pytest.raises(ValueError, match='Unknown symbol'): + fig.canvas.draw() + + +# See gh-26152 for more information on this xfail +@pytest.mark.xfail(pyparsing_version.release == (3, 1, 0), + reason="Error messages are incorrect with pyparsing 3.1.0") +def test_parse_math_rcparams(): + # Default is True + fig, ax = plt.subplots() + ax.text(0, 0, r"$ \wrong{math} $") + with pytest.raises(ValueError, match='Unknown symbol'): + fig.canvas.draw() + + # Setting rcParams to False + with mpl.rc_context({'text.parse_math': False}): + fig, ax = plt.subplots() + ax.text(0, 0, r"$ \wrong{math} $") + fig.canvas.draw() + + +@image_comparison(['text_pdf_font42_kerning.pdf'], style='mpl20') +def test_pdf_font42_kerning(): + plt.rcParams['pdf.fonttype'] = 42 + plt.figure() + plt.figtext(0.1, 0.5, "ATAVATAVATAVATAVATA", size=30) + + +@image_comparison(['text_pdf_chars_beyond_bmp.pdf'], style='mpl20') +def test_pdf_chars_beyond_bmp(): + plt.rcParams['pdf.fonttype'] = 42 + plt.rcParams['mathtext.fontset'] = 'stixsans' + plt.figure() + plt.figtext(0.1, 0.5, "Mass $m$ \U00010308", size=30) + + +@needs_usetex +def test_metrics_cache(): + mpl.text._get_text_metrics_with_cache_impl.cache_clear() + + fig = plt.figure() + fig.text(.3, .5, "foo\nbar") + fig.text(.3, .5, "foo\nbar", usetex=True) + fig.text(.5, .5, "foo\nbar", usetex=True) + fig.canvas.draw() + renderer = fig._get_renderer() + ys = {} # mapping of strings to where they were drawn in y with draw_tex. + + def call(*args, **kwargs): + renderer, x, y, s, *_ = args + ys.setdefault(s, set()).add(y) + + renderer.draw_tex = call + fig.canvas.draw() + assert [*ys] == ["foo", "bar"] + # Check that both TeX strings were drawn with the same y-position for both + # single-line substrings. Previously, there used to be an incorrect cache + # collision with the non-TeX string (drawn first here) whose metrics would + # get incorrectly reused by the first TeX string. + assert len(ys["foo"]) == len(ys["bar"]) == 1 + + info = mpl.text._get_text_metrics_with_cache_impl.cache_info() + # Every string gets a miss for the first layouting (extents), then a hit + # when drawing, but "foo\nbar" gets two hits as it's drawn twice. + assert info.hits > info.misses + + +def test_annotate_offset_fontsize(): + # Test that offset_fontsize parameter works and uses accurate values + fig, ax = plt.subplots() + text_coords = ['offset points', 'offset fontsize'] + # 10 points should be equal to 1 fontsize unit at fontsize=10 + xy_text = [(10, 10), (1, 1)] + anns = [ax.annotate('test', xy=(0.5, 0.5), + xytext=xy_text[i], + fontsize='10', + xycoords='data', + textcoords=text_coords[i]) for i in range(2)] + points_coords, fontsize_coords = [ann.get_window_extent() for ann in anns] + fig.canvas.draw() + assert str(points_coords) == str(fontsize_coords) + + +def test_get_set_antialiased(): + txt = Text(.5, .5, "foo\nbar") + assert txt._antialiased == mpl.rcParams['text.antialiased'] + assert txt.get_antialiased() == mpl.rcParams['text.antialiased'] + + txt.set_antialiased(True) + assert txt._antialiased is True + assert txt.get_antialiased() == txt._antialiased + + txt.set_antialiased(False) + assert txt._antialiased is False + assert txt.get_antialiased() == txt._antialiased + + +def test_annotation_antialiased(): + annot = Annotation("foo\nbar", (.5, .5), antialiased=True) + assert annot._antialiased is True + assert annot.get_antialiased() == annot._antialiased + + annot2 = Annotation("foo\nbar", (.5, .5), antialiased=False) + assert annot2._antialiased is False + assert annot2.get_antialiased() == annot2._antialiased + + annot3 = Annotation("foo\nbar", (.5, .5), antialiased=False) + annot3.set_antialiased(True) + assert annot3.get_antialiased() is True + assert annot3._antialiased is True + + annot4 = Annotation("foo\nbar", (.5, .5)) + assert annot4._antialiased == mpl.rcParams['text.antialiased'] + + +@check_figures_equal(extensions=["png"]) +def test_annotate_and_offsetfrom_copy_input(fig_test, fig_ref): + # Both approaches place the text (10, 0) pixels away from the center of the line. + ax = fig_test.add_subplot() + l, = ax.plot([0, 2], [0, 2]) + of_xy = np.array([.5, .5]) + ax.annotate("foo", textcoords=OffsetFrom(l, of_xy), xytext=(10, 0), + xy=(0, 0)) # xy is unused. + of_xy[:] = 1 + ax = fig_ref.add_subplot() + l, = ax.plot([0, 2], [0, 2]) + an_xy = np.array([.5, .5]) + ax.annotate("foo", xy=an_xy, xycoords=l, xytext=(10, 0), textcoords="offset points") + an_xy[:] = 2 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_textpath.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_textpath.py new file mode 100644 index 00000000..e421d262 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_textpath.py @@ -0,0 +1,10 @@ +import copy + +from matplotlib.textpath import TextPath + + +def test_copy(): + tp = TextPath((0, 0), ".") + assert copy.deepcopy(tp).vertices is not tp.vertices + assert (copy.deepcopy(tp).vertices == tp.vertices).all() + assert copy.copy(tp).vertices is tp.vertices diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ticker.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ticker.py new file mode 100644 index 00000000..961daaa1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ticker.py @@ -0,0 +1,1791 @@ +from contextlib import nullcontext +import itertools +import locale +import logging +import re + +import numpy as np +from numpy.testing import assert_almost_equal, assert_array_equal +import pytest + +import matplotlib as mpl +import matplotlib.pyplot as plt +import matplotlib.ticker as mticker + + +class TestMaxNLocator: + basic_data = [ + (20, 100, np.array([20., 40., 60., 80., 100.])), + (0.001, 0.0001, np.array([0., 0.0002, 0.0004, 0.0006, 0.0008, 0.001])), + (-1e15, 1e15, np.array([-1.0e+15, -5.0e+14, 0e+00, 5e+14, 1.0e+15])), + (0, 0.85e-50, np.arange(6) * 2e-51), + (-0.85e-50, 0, np.arange(-5, 1) * 2e-51), + ] + + integer_data = [ + (-0.1, 1.1, None, np.array([-1, 0, 1, 2])), + (-0.1, 0.95, None, np.array([-0.25, 0, 0.25, 0.5, 0.75, 1.0])), + (1, 55, [1, 1.5, 5, 6, 10], np.array([0, 15, 30, 45, 60])), + ] + + @pytest.mark.parametrize('vmin, vmax, expected', basic_data) + def test_basic(self, vmin, vmax, expected): + loc = mticker.MaxNLocator(nbins=5) + assert_almost_equal(loc.tick_values(vmin, vmax), expected) + + @pytest.mark.parametrize('vmin, vmax, steps, expected', integer_data) + def test_integer(self, vmin, vmax, steps, expected): + loc = mticker.MaxNLocator(nbins=5, integer=True, steps=steps) + assert_almost_equal(loc.tick_values(vmin, vmax), expected) + + @pytest.mark.parametrize('kwargs, errortype, match', [ + ({'foo': 0}, TypeError, + re.escape("set_params() got an unexpected keyword argument 'foo'")), + ({'steps': [2, 1]}, ValueError, "steps argument must be an increasing"), + ({'steps': 2}, ValueError, "steps argument must be an increasing"), + ({'steps': [2, 11]}, ValueError, "steps argument must be an increasing"), + ]) + def test_errors(self, kwargs, errortype, match): + with pytest.raises(errortype, match=match): + mticker.MaxNLocator(**kwargs) + + @pytest.mark.parametrize('steps, result', [ + ([1, 2, 10], [1, 2, 10]), + ([2, 10], [1, 2, 10]), + ([1, 2], [1, 2, 10]), + ([2], [1, 2, 10]), + ]) + def test_padding(self, steps, result): + loc = mticker.MaxNLocator(steps=steps) + assert (loc._steps == result).all() + + +class TestLinearLocator: + def test_basic(self): + loc = mticker.LinearLocator(numticks=3) + test_value = np.array([-0.8, -0.3, 0.2]) + assert_almost_equal(loc.tick_values(-0.8, 0.2), test_value) + + def test_zero_numticks(self): + loc = mticker.LinearLocator(numticks=0) + loc.tick_values(-0.8, 0.2) == [] + + def test_set_params(self): + """ + Create linear locator with presets={}, numticks=2 and change it to + something else. See if change was successful. Should not exception. + """ + loc = mticker.LinearLocator(numticks=2) + loc.set_params(numticks=8, presets={(0, 1): []}) + assert loc.numticks == 8 + assert loc.presets == {(0, 1): []} + + def test_presets(self): + loc = mticker.LinearLocator(presets={(1, 2): [1, 1.25, 1.75], + (0, 2): [0.5, 1.5]}) + assert loc.tick_values(1, 2) == [1, 1.25, 1.75] + assert loc.tick_values(2, 1) == [1, 1.25, 1.75] + assert loc.tick_values(0, 2) == [0.5, 1.5] + assert loc.tick_values(0.0, 2.0) == [0.5, 1.5] + assert (loc.tick_values(0, 1) == np.linspace(0, 1, 11)).all() + + +class TestMultipleLocator: + def test_basic(self): + loc = mticker.MultipleLocator(base=3.147) + test_value = np.array([-9.441, -6.294, -3.147, 0., 3.147, 6.294, + 9.441, 12.588]) + assert_almost_equal(loc.tick_values(-7, 10), test_value) + + def test_basic_with_offset(self): + loc = mticker.MultipleLocator(base=3.147, offset=1.2) + test_value = np.array([-8.241, -5.094, -1.947, 1.2, 4.347, 7.494, + 10.641]) + assert_almost_equal(loc.tick_values(-7, 10), test_value) + + def test_view_limits(self): + """ + Test basic behavior of view limits. + """ + with mpl.rc_context({'axes.autolimit_mode': 'data'}): + loc = mticker.MultipleLocator(base=3.147) + assert_almost_equal(loc.view_limits(-5, 5), (-5, 5)) + + def test_view_limits_round_numbers(self): + """ + Test that everything works properly with 'round_numbers' for auto + limit. + """ + with mpl.rc_context({'axes.autolimit_mode': 'round_numbers'}): + loc = mticker.MultipleLocator(base=3.147) + assert_almost_equal(loc.view_limits(-4, 4), (-6.294, 6.294)) + + def test_view_limits_round_numbers_with_offset(self): + """ + Test that everything works properly with 'round_numbers' for auto + limit. + """ + with mpl.rc_context({'axes.autolimit_mode': 'round_numbers'}): + loc = mticker.MultipleLocator(base=3.147, offset=1.3) + assert_almost_equal(loc.view_limits(-4, 4), (-4.994, 4.447)) + + def test_set_params(self): + """ + Create multiple locator with 0.7 base, and change it to something else. + See if change was successful. + """ + mult = mticker.MultipleLocator(base=0.7) + mult.set_params(base=1.7) + assert mult._edge.step == 1.7 + mult.set_params(offset=3) + assert mult._offset == 3 + + +class TestAutoMinorLocator: + def test_basic(self): + fig, ax = plt.subplots() + ax.set_xlim(0, 1.39) + ax.minorticks_on() + test_value = np.array([0.05, 0.1, 0.15, 0.25, 0.3, 0.35, 0.45, + 0.5, 0.55, 0.65, 0.7, 0.75, 0.85, 0.9, + 0.95, 1.05, 1.1, 1.15, 1.25, 1.3, 1.35]) + assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), test_value) + + # NB: the following values are assuming that *xlim* is [0, 5] + params = [ + (0, 0), # no major tick => no minor tick either + (1, 0) # a single major tick => no minor tick + ] + + def test_first_and_last_minorticks(self): + """ + Test that first and last minor tick appear as expected. + """ + # This test is related to issue #22331 + fig, ax = plt.subplots() + ax.set_xlim(-1.9, 1.9) + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator()) + test_value = np.array([-1.9, -1.8, -1.7, -1.6, -1.4, -1.3, -1.2, -1.1, + -0.9, -0.8, -0.7, -0.6, -0.4, -0.3, -0.2, -0.1, + 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9, 1.1, + 1.2, 1.3, 1.4, 1.6, 1.7, 1.8, 1.9]) + assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), test_value) + + ax.set_xlim(-5, 5) + test_value = np.array([-5.0, -4.5, -3.5, -3.0, -2.5, -1.5, -1.0, -0.5, + 0.5, 1.0, 1.5, 2.5, 3.0, 3.5, 4.5, 5.0]) + assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), test_value) + + @pytest.mark.parametrize('nb_majorticks, expected_nb_minorticks', params) + def test_low_number_of_majorticks( + self, nb_majorticks, expected_nb_minorticks): + # This test is related to issue #8804 + fig, ax = plt.subplots() + xlims = (0, 5) # easier to test the different code paths + ax.set_xlim(*xlims) + ax.set_xticks(np.linspace(xlims[0], xlims[1], nb_majorticks)) + ax.minorticks_on() + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator()) + assert len(ax.xaxis.get_minorticklocs()) == expected_nb_minorticks + + majorstep_minordivisions = [(1, 5), + (2, 4), + (2.5, 5), + (5, 5), + (10, 5)] + + # This test is meant to verify the parameterization for + # test_number_of_minor_ticks + def test_using_all_default_major_steps(self): + with mpl.rc_context({'_internal.classic_mode': False}): + majorsteps = [x[0] for x in self.majorstep_minordivisions] + np.testing.assert_allclose(majorsteps, + mticker.AutoLocator()._steps) + + @pytest.mark.parametrize('major_step, expected_nb_minordivisions', + majorstep_minordivisions) + def test_number_of_minor_ticks( + self, major_step, expected_nb_minordivisions): + fig, ax = plt.subplots() + xlims = (0, major_step) + ax.set_xlim(*xlims) + ax.set_xticks(xlims) + ax.minorticks_on() + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator()) + nb_minor_divisions = len(ax.xaxis.get_minorticklocs()) + 1 + assert nb_minor_divisions == expected_nb_minordivisions + + limits = [(0, 1.39), (0, 0.139), + (0, 0.11e-19), (0, 0.112e-12), + (-2.0e-07, -3.3e-08), (1.20e-06, 1.42e-06), + (-1.34e-06, -1.44e-06), (-8.76e-07, -1.51e-06)] + + reference = [ + [0.05, 0.1, 0.15, 0.25, 0.3, 0.35, 0.45, 0.5, 0.55, 0.65, 0.7, + 0.75, 0.85, 0.9, 0.95, 1.05, 1.1, 1.15, 1.25, 1.3, 1.35], + [0.005, 0.01, 0.015, 0.025, 0.03, 0.035, 0.045, 0.05, 0.055, 0.065, + 0.07, 0.075, 0.085, 0.09, 0.095, 0.105, 0.11, 0.115, 0.125, 0.13, + 0.135], + [5.00e-22, 1.00e-21, 1.50e-21, 2.50e-21, 3.00e-21, 3.50e-21, 4.50e-21, + 5.00e-21, 5.50e-21, 6.50e-21, 7.00e-21, 7.50e-21, 8.50e-21, 9.00e-21, + 9.50e-21, 1.05e-20, 1.10e-20], + [5.00e-15, 1.00e-14, 1.50e-14, 2.50e-14, 3.00e-14, 3.50e-14, 4.50e-14, + 5.00e-14, 5.50e-14, 6.50e-14, 7.00e-14, 7.50e-14, 8.50e-14, 9.00e-14, + 9.50e-14, 1.05e-13, 1.10e-13], + [-1.95e-07, -1.90e-07, -1.85e-07, -1.75e-07, -1.70e-07, -1.65e-07, + -1.55e-07, -1.50e-07, -1.45e-07, -1.35e-07, -1.30e-07, -1.25e-07, + -1.15e-07, -1.10e-07, -1.05e-07, -9.50e-08, -9.00e-08, -8.50e-08, + -7.50e-08, -7.00e-08, -6.50e-08, -5.50e-08, -5.00e-08, -4.50e-08, + -3.50e-08], + [1.21e-06, 1.22e-06, 1.23e-06, 1.24e-06, 1.26e-06, 1.27e-06, 1.28e-06, + 1.29e-06, 1.31e-06, 1.32e-06, 1.33e-06, 1.34e-06, 1.36e-06, 1.37e-06, + 1.38e-06, 1.39e-06, 1.41e-06, 1.42e-06], + [-1.435e-06, -1.430e-06, -1.425e-06, -1.415e-06, -1.410e-06, + -1.405e-06, -1.395e-06, -1.390e-06, -1.385e-06, -1.375e-06, + -1.370e-06, -1.365e-06, -1.355e-06, -1.350e-06, -1.345e-06], + [-1.48e-06, -1.46e-06, -1.44e-06, -1.42e-06, -1.38e-06, -1.36e-06, + -1.34e-06, -1.32e-06, -1.28e-06, -1.26e-06, -1.24e-06, -1.22e-06, + -1.18e-06, -1.16e-06, -1.14e-06, -1.12e-06, -1.08e-06, -1.06e-06, + -1.04e-06, -1.02e-06, -9.80e-07, -9.60e-07, -9.40e-07, -9.20e-07, + -8.80e-07]] + + additional_data = list(zip(limits, reference)) + + @pytest.mark.parametrize('lim, ref', additional_data) + def test_additional(self, lim, ref): + fig, ax = plt.subplots() + + ax.minorticks_on() + ax.grid(True, 'minor', 'y', linewidth=1) + ax.grid(True, 'major', color='k', linewidth=1) + ax.set_ylim(lim) + + assert_almost_equal(ax.yaxis.get_ticklocs(minor=True), ref) + + @pytest.mark.parametrize('use_rcparam', [False, True]) + @pytest.mark.parametrize( + 'lim, ref', [ + ((0, 1.39), + [0.05, 0.1, 0.15, 0.25, 0.3, 0.35, 0.45, 0.5, 0.55, 0.65, 0.7, + 0.75, 0.85, 0.9, 0.95, 1.05, 1.1, 1.15, 1.25, 1.3, 1.35]), + ((0, 0.139), + [0.005, 0.01, 0.015, 0.025, 0.03, 0.035, 0.045, 0.05, 0.055, + 0.065, 0.07, 0.075, 0.085, 0.09, 0.095, 0.105, 0.11, 0.115, + 0.125, 0.13, 0.135]), + ]) + def test_number_of_minor_ticks_auto(self, lim, ref, use_rcparam): + if use_rcparam: + context = {'xtick.minor.ndivs': 'auto', 'ytick.minor.ndivs': 'auto'} + kwargs = {} + else: + context = {} + kwargs = {'n': 'auto'} + + with mpl.rc_context(context): + fig, ax = plt.subplots() + ax.set_xlim(*lim) + ax.set_ylim(*lim) + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator(**kwargs)) + ax.yaxis.set_minor_locator(mticker.AutoMinorLocator(**kwargs)) + assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), ref) + assert_almost_equal(ax.yaxis.get_ticklocs(minor=True), ref) + + @pytest.mark.parametrize('use_rcparam', [False, True]) + @pytest.mark.parametrize( + 'n, lim, ref', [ + (2, (0, 4), [0.5, 1.5, 2.5, 3.5]), + (4, (0, 2), [0.25, 0.5, 0.75, 1.25, 1.5, 1.75]), + (10, (0, 1), [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]), + ]) + def test_number_of_minor_ticks_int(self, n, lim, ref, use_rcparam): + if use_rcparam: + context = {'xtick.minor.ndivs': n, 'ytick.minor.ndivs': n} + kwargs = {} + else: + context = {} + kwargs = {'n': n} + + with mpl.rc_context(context): + fig, ax = plt.subplots() + ax.set_xlim(*lim) + ax.set_ylim(*lim) + ax.xaxis.set_major_locator(mticker.MultipleLocator(1)) + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator(**kwargs)) + ax.yaxis.set_major_locator(mticker.MultipleLocator(1)) + ax.yaxis.set_minor_locator(mticker.AutoMinorLocator(**kwargs)) + assert_almost_equal(ax.xaxis.get_ticklocs(minor=True), ref) + assert_almost_equal(ax.yaxis.get_ticklocs(minor=True), ref) + + +class TestLogLocator: + def test_basic(self): + loc = mticker.LogLocator(numticks=5) + with pytest.raises(ValueError): + loc.tick_values(0, 1000) + + test_value = np.array([1.00000000e-05, 1.00000000e-03, 1.00000000e-01, + 1.00000000e+01, 1.00000000e+03, 1.00000000e+05, + 1.00000000e+07, 1.000000000e+09]) + assert_almost_equal(loc.tick_values(0.001, 1.1e5), test_value) + + loc = mticker.LogLocator(base=2) + test_value = np.array([0.5, 1., 2., 4., 8., 16., 32., 64., 128., 256.]) + assert_almost_equal(loc.tick_values(1, 100), test_value) + + def test_polar_axes(self): + """ + Polar axes have a different ticking logic. + """ + fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) + ax.set_yscale('log') + ax.set_ylim(1, 100) + assert_array_equal(ax.get_yticks(), [10, 100, 1000]) + + def test_switch_to_autolocator(self): + loc = mticker.LogLocator(subs="all") + assert_array_equal(loc.tick_values(0.45, 0.55), + [0.44, 0.46, 0.48, 0.5, 0.52, 0.54, 0.56]) + # check that we *skip* 1.0, and 10, because this is a minor locator + loc = mticker.LogLocator(subs=np.arange(2, 10)) + assert 1.0 not in loc.tick_values(0.9, 20.) + assert 10.0 not in loc.tick_values(0.9, 20.) + + def test_set_params(self): + """ + Create log locator with default value, base=10.0, subs=[1.0], + numdecs=4, numticks=15 and change it to something else. + See if change was successful. Should not raise exception. + """ + loc = mticker.LogLocator() + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="numdecs"): + loc.set_params(numticks=7, numdecs=8, subs=[2.0], base=4) + assert loc.numticks == 7 + with pytest.warns(mpl.MatplotlibDeprecationWarning, match="numdecs"): + assert loc.numdecs == 8 + assert loc._base == 4 + assert list(loc._subs) == [2.0] + + def test_tick_values_correct(self): + ll = mticker.LogLocator(subs=(1, 2, 5)) + test_value = np.array([1.e-01, 2.e-01, 5.e-01, 1.e+00, 2.e+00, 5.e+00, + 1.e+01, 2.e+01, 5.e+01, 1.e+02, 2.e+02, 5.e+02, + 1.e+03, 2.e+03, 5.e+03, 1.e+04, 2.e+04, 5.e+04, + 1.e+05, 2.e+05, 5.e+05, 1.e+06, 2.e+06, 5.e+06, + 1.e+07, 2.e+07, 5.e+07, 1.e+08, 2.e+08, 5.e+08]) + assert_almost_equal(ll.tick_values(1, 1e7), test_value) + + def test_tick_values_not_empty(self): + mpl.rcParams['_internal.classic_mode'] = False + ll = mticker.LogLocator(subs=(1, 2, 5)) + test_value = np.array([1.e-01, 2.e-01, 5.e-01, 1.e+00, 2.e+00, 5.e+00, + 1.e+01, 2.e+01, 5.e+01, 1.e+02, 2.e+02, 5.e+02, + 1.e+03, 2.e+03, 5.e+03, 1.e+04, 2.e+04, 5.e+04, + 1.e+05, 2.e+05, 5.e+05, 1.e+06, 2.e+06, 5.e+06, + 1.e+07, 2.e+07, 5.e+07, 1.e+08, 2.e+08, 5.e+08, + 1.e+09, 2.e+09, 5.e+09]) + assert_almost_equal(ll.tick_values(1, 1e8), test_value) + + def test_multiple_shared_axes(self): + rng = np.random.default_rng(19680801) + dummy_data = [rng.normal(size=100), [], []] + fig, axes = plt.subplots(len(dummy_data), sharex=True, sharey=True) + + for ax, data in zip(axes.flatten(), dummy_data): + ax.hist(data, bins=10) + ax.set_yscale('log', nonpositive='clip') + + for ax in axes.flatten(): + assert all(ax.get_yticks() == axes[0].get_yticks()) + assert ax.get_ylim() == axes[0].get_ylim() + + +class TestNullLocator: + def test_set_params(self): + """ + Create null locator, and attempt to call set_params() on it. + Should not exception, and should raise a warning. + """ + loc = mticker.NullLocator() + with pytest.warns(UserWarning): + loc.set_params() + + +class _LogitHelper: + @staticmethod + def isclose(x, y): + return (np.isclose(-np.log(1/x-1), -np.log(1/y-1)) + if 0 < x < 1 and 0 < y < 1 else False) + + @staticmethod + def assert_almost_equal(x, y): + ax = np.array(x) + ay = np.array(y) + assert np.all(ax > 0) and np.all(ax < 1) + assert np.all(ay > 0) and np.all(ay < 1) + lx = -np.log(1/ax-1) + ly = -np.log(1/ay-1) + assert_almost_equal(lx, ly) + + +class TestLogitLocator: + ref_basic_limits = [ + (5e-2, 1 - 5e-2), + (5e-3, 1 - 5e-3), + (5e-4, 1 - 5e-4), + (5e-5, 1 - 5e-5), + (5e-6, 1 - 5e-6), + (5e-7, 1 - 5e-7), + (5e-8, 1 - 5e-8), + (5e-9, 1 - 5e-9), + ] + + ref_basic_major_ticks = [ + 1 / (10 ** np.arange(1, 3)), + 1 / (10 ** np.arange(1, 4)), + 1 / (10 ** np.arange(1, 5)), + 1 / (10 ** np.arange(1, 6)), + 1 / (10 ** np.arange(1, 7)), + 1 / (10 ** np.arange(1, 8)), + 1 / (10 ** np.arange(1, 9)), + 1 / (10 ** np.arange(1, 10)), + ] + + ref_maxn_limits = [(0.4, 0.6), (5e-2, 2e-1), (1 - 2e-1, 1 - 5e-2)] + + @pytest.mark.parametrize( + "lims, expected_low_ticks", + zip(ref_basic_limits, ref_basic_major_ticks), + ) + def test_basic_major(self, lims, expected_low_ticks): + """ + Create logit locator with huge number of major, and tests ticks. + """ + expected_ticks = sorted( + [*expected_low_ticks, 0.5, *(1 - expected_low_ticks)] + ) + loc = mticker.LogitLocator(nbins=100) + _LogitHelper.assert_almost_equal( + loc.tick_values(*lims), + expected_ticks + ) + + @pytest.mark.parametrize("lims", ref_maxn_limits) + def test_maxn_major(self, lims): + """ + When the axis is zoomed, the locator must have the same behavior as + MaxNLocator. + """ + loc = mticker.LogitLocator(nbins=100) + maxn_loc = mticker.MaxNLocator(nbins=100, steps=[1, 2, 5, 10]) + for nbins in (4, 8, 16): + loc.set_params(nbins=nbins) + maxn_loc.set_params(nbins=nbins) + ticks = loc.tick_values(*lims) + maxn_ticks = maxn_loc.tick_values(*lims) + assert ticks.shape == maxn_ticks.shape + assert (ticks == maxn_ticks).all() + + @pytest.mark.parametrize("lims", ref_basic_limits + ref_maxn_limits) + def test_nbins_major(self, lims): + """ + Assert logit locator for respecting nbins param. + """ + + basic_needed = int(-np.floor(np.log10(lims[0]))) * 2 + 1 + loc = mticker.LogitLocator(nbins=100) + for nbins in range(basic_needed, 2, -1): + loc.set_params(nbins=nbins) + assert len(loc.tick_values(*lims)) <= nbins + 2 + + @pytest.mark.parametrize( + "lims, expected_low_ticks", + zip(ref_basic_limits, ref_basic_major_ticks), + ) + def test_minor(self, lims, expected_low_ticks): + """ + In large scale, test the presence of minor, + and assert no minor when major are subsampled. + """ + + expected_ticks = sorted( + [*expected_low_ticks, 0.5, *(1 - expected_low_ticks)] + ) + basic_needed = len(expected_ticks) + loc = mticker.LogitLocator(nbins=100) + minor_loc = mticker.LogitLocator(nbins=100, minor=True) + for nbins in range(basic_needed, 2, -1): + loc.set_params(nbins=nbins) + minor_loc.set_params(nbins=nbins) + major_ticks = loc.tick_values(*lims) + minor_ticks = minor_loc.tick_values(*lims) + if len(major_ticks) >= len(expected_ticks): + # no subsample, we must have a lot of minors ticks + assert (len(major_ticks) - 1) * 5 < len(minor_ticks) + else: + # subsample + _LogitHelper.assert_almost_equal( + sorted([*major_ticks, *minor_ticks]), expected_ticks) + + def test_minor_attr(self): + loc = mticker.LogitLocator(nbins=100) + assert not loc.minor + loc.minor = True + assert loc.minor + loc.set_params(minor=False) + assert not loc.minor + + acceptable_vmin_vmax = [ + *(2.5 ** np.arange(-3, 0)), + *(1 - 2.5 ** np.arange(-3, 0)), + ] + + @pytest.mark.parametrize( + "lims", + [ + (a, b) + for (a, b) in itertools.product(acceptable_vmin_vmax, repeat=2) + if a != b + ], + ) + def test_nonsingular_ok(self, lims): + """ + Create logit locator, and test the nonsingular method for acceptable + value + """ + loc = mticker.LogitLocator() + lims2 = loc.nonsingular(*lims) + assert sorted(lims) == sorted(lims2) + + @pytest.mark.parametrize("okval", acceptable_vmin_vmax) + def test_nonsingular_nok(self, okval): + """ + Create logit locator, and test the nonsingular method for non + acceptable value + """ + loc = mticker.LogitLocator() + vmin, vmax = (-1, okval) + vmin2, vmax2 = loc.nonsingular(vmin, vmax) + assert vmax2 == vmax + assert 0 < vmin2 < vmax2 + vmin, vmax = (okval, 2) + vmin2, vmax2 = loc.nonsingular(vmin, vmax) + assert vmin2 == vmin + assert vmin2 < vmax2 < 1 + + +class TestFixedLocator: + def test_set_params(self): + """ + Create fixed locator with 5 nbins, and change it to something else. + See if change was successful. + Should not exception. + """ + fixed = mticker.FixedLocator(range(0, 24), nbins=5) + fixed.set_params(nbins=7) + assert fixed.nbins == 7 + + +class TestIndexLocator: + def test_set_params(self): + """ + Create index locator with 3 base, 4 offset. and change it to something + else. See if change was successful. + Should not exception. + """ + index = mticker.IndexLocator(base=3, offset=4) + index.set_params(base=7, offset=7) + assert index._base == 7 + assert index.offset == 7 + + +class TestSymmetricalLogLocator: + def test_set_params(self): + """ + Create symmetrical log locator with default subs =[1.0] numticks = 15, + and change it to something else. + See if change was successful. + Should not exception. + """ + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1) + sym.set_params(subs=[2.0], numticks=8) + assert sym._subs == [2.0] + assert sym.numticks == 8 + + @pytest.mark.parametrize( + 'vmin, vmax, expected', + [ + (0, 1, [0, 1]), + (-1, 1, [-1, 0, 1]), + ], + ) + def test_values(self, vmin, vmax, expected): + # https://github.com/matplotlib/matplotlib/issues/25945 + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1) + ticks = sym.tick_values(vmin=vmin, vmax=vmax) + assert_array_equal(ticks, expected) + + def test_subs(self): + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1, subs=[2.0, 4.0]) + sym.create_dummy_axis() + sym.axis.set_view_interval(-10, 10) + assert (sym() == [-20., -40., -2., -4., 0., 2., 4., 20., 40.]).all() + + def test_extending(self): + sym = mticker.SymmetricalLogLocator(base=10, linthresh=1) + sym.create_dummy_axis() + sym.axis.set_view_interval(8, 9) + assert (sym() == [1.0]).all() + sym.axis.set_view_interval(8, 12) + assert (sym() == [1.0, 10.0]).all() + assert sym.view_limits(10, 10) == (1, 100) + assert sym.view_limits(-10, -10) == (-100, -1) + assert sym.view_limits(0, 0) == (-0.001, 0.001) + + +class TestAsinhLocator: + def test_init(self): + lctr = mticker.AsinhLocator(linear_width=2.718, numticks=19) + assert lctr.linear_width == 2.718 + assert lctr.numticks == 19 + assert lctr.base == 10 + + def test_set_params(self): + lctr = mticker.AsinhLocator(linear_width=5, + numticks=17, symthresh=0.125, + base=4, subs=(2.5, 3.25)) + assert lctr.numticks == 17 + assert lctr.symthresh == 0.125 + assert lctr.base == 4 + assert lctr.subs == (2.5, 3.25) + + lctr.set_params(numticks=23) + assert lctr.numticks == 23 + lctr.set_params(None) + assert lctr.numticks == 23 + + lctr.set_params(symthresh=0.5) + assert lctr.symthresh == 0.5 + lctr.set_params(symthresh=None) + assert lctr.symthresh == 0.5 + + lctr.set_params(base=7) + assert lctr.base == 7 + lctr.set_params(base=None) + assert lctr.base == 7 + + lctr.set_params(subs=(2, 4.125)) + assert lctr.subs == (2, 4.125) + lctr.set_params(subs=None) + assert lctr.subs == (2, 4.125) + lctr.set_params(subs=[]) + assert lctr.subs is None + + def test_linear_values(self): + lctr = mticker.AsinhLocator(linear_width=100, numticks=11, base=0) + + assert_almost_equal(lctr.tick_values(-1, 1), + np.arange(-1, 1.01, 0.2)) + assert_almost_equal(lctr.tick_values(-0.1, 0.1), + np.arange(-0.1, 0.101, 0.02)) + assert_almost_equal(lctr.tick_values(-0.01, 0.01), + np.arange(-0.01, 0.0101, 0.002)) + + def test_wide_values(self): + lctr = mticker.AsinhLocator(linear_width=0.1, numticks=11, base=0) + + assert_almost_equal(lctr.tick_values(-100, 100), + [-100, -20, -5, -1, -0.2, + 0, 0.2, 1, 5, 20, 100]) + assert_almost_equal(lctr.tick_values(-1000, 1000), + [-1000, -100, -20, -3, -0.4, + 0, 0.4, 3, 20, 100, 1000]) + + def test_near_zero(self): + """Check that manually injected zero will supersede nearby tick""" + lctr = mticker.AsinhLocator(linear_width=100, numticks=3, base=0) + + assert_almost_equal(lctr.tick_values(-1.1, 0.9), [-1.0, 0.0, 0.9]) + + def test_fallback(self): + lctr = mticker.AsinhLocator(1.0, numticks=11) + + assert_almost_equal(lctr.tick_values(101, 102), + np.arange(101, 102.01, 0.1)) + + def test_symmetrizing(self): + lctr = mticker.AsinhLocator(linear_width=1, numticks=3, + symthresh=0.25, base=0) + lctr.create_dummy_axis() + + lctr.axis.set_view_interval(-1, 2) + assert_almost_equal(lctr(), [-1, 0, 2]) + + lctr.axis.set_view_interval(-1, 0.9) + assert_almost_equal(lctr(), [-1, 0, 1]) + + lctr.axis.set_view_interval(-0.85, 1.05) + assert_almost_equal(lctr(), [-1, 0, 1]) + + lctr.axis.set_view_interval(1, 1.1) + assert_almost_equal(lctr(), [1, 1.05, 1.1]) + + def test_base_rounding(self): + lctr10 = mticker.AsinhLocator(linear_width=1, numticks=8, + base=10, subs=(1, 3, 5)) + assert_almost_equal(lctr10.tick_values(-110, 110), + [-500, -300, -100, -50, -30, -10, -5, -3, -1, + -0.5, -0.3, -0.1, 0, 0.1, 0.3, 0.5, + 1, 3, 5, 10, 30, 50, 100, 300, 500]) + + lctr5 = mticker.AsinhLocator(linear_width=1, numticks=20, base=5) + assert_almost_equal(lctr5.tick_values(-1050, 1050), + [-625, -125, -25, -5, -1, -0.2, 0, + 0.2, 1, 5, 25, 125, 625]) + + +class TestScalarFormatter: + offset_data = [ + (123, 189, 0), + (-189, -123, 0), + (12341, 12349, 12340), + (-12349, -12341, -12340), + (99999.5, 100010.5, 100000), + (-100010.5, -99999.5, -100000), + (99990.5, 100000.5, 100000), + (-100000.5, -99990.5, -100000), + (1233999, 1234001, 1234000), + (-1234001, -1233999, -1234000), + (1, 1, 1), + (123, 123, 0), + # Test cases courtesy of @WeatherGod + (.4538, .4578, .45), + (3789.12, 3783.1, 3780), + (45124.3, 45831.75, 45000), + (0.000721, 0.0007243, 0.00072), + (12592.82, 12591.43, 12590), + (9., 12., 0), + (900., 1200., 0), + (1900., 1200., 0), + (0.99, 1.01, 1), + (9.99, 10.01, 10), + (99.99, 100.01, 100), + (5.99, 6.01, 6), + (15.99, 16.01, 16), + (-0.452, 0.492, 0), + (-0.492, 0.492, 0), + (12331.4, 12350.5, 12300), + (-12335.3, 12335.3, 0), + ] + + use_offset_data = [True, False] + + useMathText_data = [True, False] + + # (sci_type, scilimits, lim, orderOfMag, fewticks) + scilimits_data = [ + (False, (0, 0), (10.0, 20.0), 0, False), + (True, (-2, 2), (-10, 20), 0, False), + (True, (-2, 2), (-20, 10), 0, False), + (True, (-2, 2), (-110, 120), 2, False), + (True, (-2, 2), (-120, 110), 2, False), + (True, (-2, 2), (-.001, 0.002), -3, False), + (True, (-7, 7), (0.18e10, 0.83e10), 9, True), + (True, (0, 0), (-1e5, 1e5), 5, False), + (True, (6, 6), (-1e5, 1e5), 6, False), + ] + + cursor_data = [ + [0., "0.000"], + [0.0123, "0.012"], + [0.123, "0.123"], + [1.23, "1.230"], + [12.3, "12.300"], + ] + + format_data = [ + (.1, "1e-1"), + (.11, "1.1e-1"), + (1e8, "1e8"), + (1.1e8, "1.1e8"), + ] + + @pytest.mark.parametrize('unicode_minus, result', + [(True, "\N{MINUS SIGN}1"), (False, "-1")]) + def test_unicode_minus(self, unicode_minus, result): + mpl.rcParams['axes.unicode_minus'] = unicode_minus + assert ( + plt.gca().xaxis.get_major_formatter().format_data_short(-1).strip() + == result) + + @pytest.mark.parametrize('left, right, offset', offset_data) + def test_offset_value(self, left, right, offset): + fig, ax = plt.subplots() + formatter = ax.xaxis.get_major_formatter() + + with (pytest.warns(UserWarning, match='Attempting to set identical') + if left == right else nullcontext()): + ax.set_xlim(left, right) + ax.xaxis._update_ticks() + assert formatter.offset == offset + + with (pytest.warns(UserWarning, match='Attempting to set identical') + if left == right else nullcontext()): + ax.set_xlim(right, left) + ax.xaxis._update_ticks() + assert formatter.offset == offset + + @pytest.mark.parametrize('use_offset', use_offset_data) + def test_use_offset(self, use_offset): + with mpl.rc_context({'axes.formatter.useoffset': use_offset}): + tmp_form = mticker.ScalarFormatter() + assert use_offset == tmp_form.get_useOffset() + assert tmp_form.offset == 0 + + @pytest.mark.parametrize('use_math_text', useMathText_data) + def test_useMathText(self, use_math_text): + with mpl.rc_context({'axes.formatter.use_mathtext': use_math_text}): + tmp_form = mticker.ScalarFormatter() + assert use_math_text == tmp_form.get_useMathText() + + def test_set_use_offset_float(self): + tmp_form = mticker.ScalarFormatter() + tmp_form.set_useOffset(0.5) + assert not tmp_form.get_useOffset() + assert tmp_form.offset == 0.5 + + def test_use_locale(self): + conv = locale.localeconv() + sep = conv['thousands_sep'] + if not sep or conv['grouping'][-1:] in ([], [locale.CHAR_MAX]): + pytest.skip('Locale does not apply grouping') # pragma: no cover + + with mpl.rc_context({'axes.formatter.use_locale': True}): + tmp_form = mticker.ScalarFormatter() + assert tmp_form.get_useLocale() + + tmp_form.create_dummy_axis() + tmp_form.axis.set_data_interval(0, 10) + tmp_form.set_locs([1, 2, 3]) + assert sep in tmp_form(1e9) + + @pytest.mark.parametrize( + 'sci_type, scilimits, lim, orderOfMag, fewticks', scilimits_data) + def test_scilimits(self, sci_type, scilimits, lim, orderOfMag, fewticks): + tmp_form = mticker.ScalarFormatter() + tmp_form.set_scientific(sci_type) + tmp_form.set_powerlimits(scilimits) + fig, ax = plt.subplots() + ax.yaxis.set_major_formatter(tmp_form) + ax.set_ylim(*lim) + if fewticks: + ax.yaxis.set_major_locator(mticker.MaxNLocator(4)) + + tmp_form.set_locs(ax.yaxis.get_majorticklocs()) + assert orderOfMag == tmp_form.orderOfMagnitude + + @pytest.mark.parametrize('value, expected', format_data) + def test_format_data(self, value, expected): + mpl.rcParams['axes.unicode_minus'] = False + sf = mticker.ScalarFormatter() + assert sf.format_data(value) == expected + + @pytest.mark.parametrize('data, expected', cursor_data) + def test_cursor_precision(self, data, expected): + fig, ax = plt.subplots() + ax.set_xlim(-1, 1) # Pointing precision of 0.001. + fmt = ax.xaxis.get_major_formatter().format_data_short + assert fmt(data) == expected + + @pytest.mark.parametrize('data, expected', cursor_data) + def test_cursor_dummy_axis(self, data, expected): + # Issue #17624 + sf = mticker.ScalarFormatter() + sf.create_dummy_axis() + sf.axis.set_view_interval(0, 10) + fmt = sf.format_data_short + assert fmt(data) == expected + assert sf.axis.get_tick_space() == 9 + assert sf.axis.get_minpos() == 0 + + def test_mathtext_ticks(self): + mpl.rcParams.update({ + 'font.family': 'serif', + 'font.serif': 'cmr10', + 'axes.formatter.use_mathtext': False + }) + + with pytest.warns(UserWarning, match='cmr10 font should ideally'): + fig, ax = plt.subplots() + ax.set_xticks([-1, 0, 1]) + fig.canvas.draw() + + def test_cmr10_substitutions(self, caplog): + mpl.rcParams.update({ + 'font.family': 'cmr10', + 'mathtext.fontset': 'cm', + 'axes.formatter.use_mathtext': True, + }) + + # Test that it does not log a warning about missing glyphs. + with caplog.at_level(logging.WARNING, logger='matplotlib.mathtext'): + fig, ax = plt.subplots() + ax.plot([-0.03, 0.05], [40, 0.05]) + ax.set_yscale('log') + yticks = [0.02, 0.3, 4, 50] + formatter = mticker.LogFormatterSciNotation() + ax.set_yticks(yticks, map(formatter, yticks)) + fig.canvas.draw() + assert not caplog.text + + def test_empty_locs(self): + sf = mticker.ScalarFormatter() + sf.set_locs([]) + assert sf(0.5) == '' + + +class TestLogFormatterExponent: + param_data = [ + (True, 4, np.arange(-3, 4.0), np.arange(-3, 4.0), + ['-3', '-2', '-1', '0', '1', '2', '3']), + # With labelOnlyBase=False, non-integer powers should be nicely + # formatted. + (False, 10, np.array([0.1, 0.00001, np.pi, 0.2, -0.2, -0.00001]), + range(6), ['0.1', '1e-05', '3.14', '0.2', '-0.2', '-1e-05']), + (False, 50, np.array([3, 5, 12, 42], dtype=float), range(6), + ['3', '5', '12', '42']), + ] + + base_data = [2.0, 5.0, 10.0, np.pi, np.e] + + @pytest.mark.parametrize( + 'labelOnlyBase, exponent, locs, positions, expected', param_data) + @pytest.mark.parametrize('base', base_data) + def test_basic(self, labelOnlyBase, base, exponent, locs, positions, + expected): + formatter = mticker.LogFormatterExponent(base=base, + labelOnlyBase=labelOnlyBase) + formatter.create_dummy_axis() + formatter.axis.set_view_interval(1, base**exponent) + vals = base**locs + labels = [formatter(x, pos) for (x, pos) in zip(vals, positions)] + expected = [label.replace('-', '\N{Minus Sign}') for label in expected] + assert labels == expected + + def test_blank(self): + # Should be a blank string for non-integer powers if labelOnlyBase=True + formatter = mticker.LogFormatterExponent(base=10, labelOnlyBase=True) + formatter.create_dummy_axis() + formatter.axis.set_view_interval(1, 10) + assert formatter(10**0.1) == '' + + +class TestLogFormatterMathtext: + fmt = mticker.LogFormatterMathtext() + test_data = [ + (0, 1, '$\\mathdefault{10^{0}}$'), + (0, 1e-2, '$\\mathdefault{10^{-2}}$'), + (0, 1e2, '$\\mathdefault{10^{2}}$'), + (3, 1, '$\\mathdefault{1}$'), + (3, 1e-2, '$\\mathdefault{0.01}$'), + (3, 1e2, '$\\mathdefault{100}$'), + (3, 1e-3, '$\\mathdefault{10^{-3}}$'), + (3, 1e3, '$\\mathdefault{10^{3}}$'), + ] + + @pytest.mark.parametrize('min_exponent, value, expected', test_data) + def test_min_exponent(self, min_exponent, value, expected): + with mpl.rc_context({'axes.formatter.min_exponent': min_exponent}): + assert self.fmt(value) == expected + + +class TestLogFormatterSciNotation: + test_data = [ + (2, 0.03125, '$\\mathdefault{2^{-5}}$'), + (2, 1, '$\\mathdefault{2^{0}}$'), + (2, 32, '$\\mathdefault{2^{5}}$'), + (2, 0.0375, '$\\mathdefault{1.2\\times2^{-5}}$'), + (2, 1.2, '$\\mathdefault{1.2\\times2^{0}}$'), + (2, 38.4, '$\\mathdefault{1.2\\times2^{5}}$'), + (10, -1, '$\\mathdefault{-10^{0}}$'), + (10, 1e-05, '$\\mathdefault{10^{-5}}$'), + (10, 1, '$\\mathdefault{10^{0}}$'), + (10, 100000, '$\\mathdefault{10^{5}}$'), + (10, 2e-05, '$\\mathdefault{2\\times10^{-5}}$'), + (10, 2, '$\\mathdefault{2\\times10^{0}}$'), + (10, 200000, '$\\mathdefault{2\\times10^{5}}$'), + (10, 5e-05, '$\\mathdefault{5\\times10^{-5}}$'), + (10, 5, '$\\mathdefault{5\\times10^{0}}$'), + (10, 500000, '$\\mathdefault{5\\times10^{5}}$'), + ] + + @mpl.style.context('default') + @pytest.mark.parametrize('base, value, expected', test_data) + def test_basic(self, base, value, expected): + formatter = mticker.LogFormatterSciNotation(base=base) + with mpl.rc_context({'text.usetex': False}): + assert formatter(value) == expected + + +class TestLogFormatter: + pprint_data = [ + (3.141592654e-05, 0.001, '3.142e-5'), + (0.0003141592654, 0.001, '3.142e-4'), + (0.003141592654, 0.001, '3.142e-3'), + (0.03141592654, 0.001, '3.142e-2'), + (0.3141592654, 0.001, '3.142e-1'), + (3.141592654, 0.001, '3.142'), + (31.41592654, 0.001, '3.142e1'), + (314.1592654, 0.001, '3.142e2'), + (3141.592654, 0.001, '3.142e3'), + (31415.92654, 0.001, '3.142e4'), + (314159.2654, 0.001, '3.142e5'), + (1e-05, 0.001, '1e-5'), + (0.0001, 0.001, '1e-4'), + (0.001, 0.001, '1e-3'), + (0.01, 0.001, '1e-2'), + (0.1, 0.001, '1e-1'), + (1, 0.001, '1'), + (10, 0.001, '10'), + (100, 0.001, '100'), + (1000, 0.001, '1000'), + (10000, 0.001, '1e4'), + (100000, 0.001, '1e5'), + (3.141592654e-05, 0.015, '0'), + (0.0003141592654, 0.015, '0'), + (0.003141592654, 0.015, '0.003'), + (0.03141592654, 0.015, '0.031'), + (0.3141592654, 0.015, '0.314'), + (3.141592654, 0.015, '3.142'), + (31.41592654, 0.015, '31.416'), + (314.1592654, 0.015, '314.159'), + (3141.592654, 0.015, '3141.593'), + (31415.92654, 0.015, '31415.927'), + (314159.2654, 0.015, '314159.265'), + (1e-05, 0.015, '0'), + (0.0001, 0.015, '0'), + (0.001, 0.015, '0.001'), + (0.01, 0.015, '0.01'), + (0.1, 0.015, '0.1'), + (1, 0.015, '1'), + (10, 0.015, '10'), + (100, 0.015, '100'), + (1000, 0.015, '1000'), + (10000, 0.015, '10000'), + (100000, 0.015, '100000'), + (3.141592654e-05, 0.5, '0'), + (0.0003141592654, 0.5, '0'), + (0.003141592654, 0.5, '0.003'), + (0.03141592654, 0.5, '0.031'), + (0.3141592654, 0.5, '0.314'), + (3.141592654, 0.5, '3.142'), + (31.41592654, 0.5, '31.416'), + (314.1592654, 0.5, '314.159'), + (3141.592654, 0.5, '3141.593'), + (31415.92654, 0.5, '31415.927'), + (314159.2654, 0.5, '314159.265'), + (1e-05, 0.5, '0'), + (0.0001, 0.5, '0'), + (0.001, 0.5, '0.001'), + (0.01, 0.5, '0.01'), + (0.1, 0.5, '0.1'), + (1, 0.5, '1'), + (10, 0.5, '10'), + (100, 0.5, '100'), + (1000, 0.5, '1000'), + (10000, 0.5, '10000'), + (100000, 0.5, '100000'), + (3.141592654e-05, 5, '0'), + (0.0003141592654, 5, '0'), + (0.003141592654, 5, '0'), + (0.03141592654, 5, '0.03'), + (0.3141592654, 5, '0.31'), + (3.141592654, 5, '3.14'), + (31.41592654, 5, '31.42'), + (314.1592654, 5, '314.16'), + (3141.592654, 5, '3141.59'), + (31415.92654, 5, '31415.93'), + (314159.2654, 5, '314159.27'), + (1e-05, 5, '0'), + (0.0001, 5, '0'), + (0.001, 5, '0'), + (0.01, 5, '0.01'), + (0.1, 5, '0.1'), + (1, 5, '1'), + (10, 5, '10'), + (100, 5, '100'), + (1000, 5, '1000'), + (10000, 5, '10000'), + (100000, 5, '100000'), + (3.141592654e-05, 100, '0'), + (0.0003141592654, 100, '0'), + (0.003141592654, 100, '0'), + (0.03141592654, 100, '0'), + (0.3141592654, 100, '0.3'), + (3.141592654, 100, '3.1'), + (31.41592654, 100, '31.4'), + (314.1592654, 100, '314.2'), + (3141.592654, 100, '3141.6'), + (31415.92654, 100, '31415.9'), + (314159.2654, 100, '314159.3'), + (1e-05, 100, '0'), + (0.0001, 100, '0'), + (0.001, 100, '0'), + (0.01, 100, '0'), + (0.1, 100, '0.1'), + (1, 100, '1'), + (10, 100, '10'), + (100, 100, '100'), + (1000, 100, '1000'), + (10000, 100, '10000'), + (100000, 100, '100000'), + (3.141592654e-05, 1000000.0, '3.1e-5'), + (0.0003141592654, 1000000.0, '3.1e-4'), + (0.003141592654, 1000000.0, '3.1e-3'), + (0.03141592654, 1000000.0, '3.1e-2'), + (0.3141592654, 1000000.0, '3.1e-1'), + (3.141592654, 1000000.0, '3.1'), + (31.41592654, 1000000.0, '3.1e1'), + (314.1592654, 1000000.0, '3.1e2'), + (3141.592654, 1000000.0, '3.1e3'), + (31415.92654, 1000000.0, '3.1e4'), + (314159.2654, 1000000.0, '3.1e5'), + (1e-05, 1000000.0, '1e-5'), + (0.0001, 1000000.0, '1e-4'), + (0.001, 1000000.0, '1e-3'), + (0.01, 1000000.0, '1e-2'), + (0.1, 1000000.0, '1e-1'), + (1, 1000000.0, '1'), + (10, 1000000.0, '10'), + (100, 1000000.0, '100'), + (1000, 1000000.0, '1000'), + (10000, 1000000.0, '1e4'), + (100000, 1000000.0, '1e5'), + ] + + @pytest.mark.parametrize('value, domain, expected', pprint_data) + def test_pprint(self, value, domain, expected): + fmt = mticker.LogFormatter() + label = fmt._pprint_val(value, domain) + assert label == expected + + @pytest.mark.parametrize('value, long, short', [ + (0.0, "0", "0 "), + (0, "0", "0 "), + (-1.0, "-10^0", "-1 "), + (2e-10, "2x10^-10", "2e-10 "), + (1e10, "10^10", "1e+10 "), + ]) + def test_format_data(self, value, long, short): + fig, ax = plt.subplots() + ax.set_xscale('log') + fmt = ax.xaxis.get_major_formatter() + assert fmt.format_data(value) == long + assert fmt.format_data_short(value) == short + + def _sub_labels(self, axis, subs=()): + """Test whether locator marks subs to be labeled.""" + fmt = axis.get_minor_formatter() + minor_tlocs = axis.get_minorticklocs() + fmt.set_locs(minor_tlocs) + coefs = minor_tlocs / 10**(np.floor(np.log10(minor_tlocs))) + label_expected = [round(c) in subs for c in coefs] + label_test = [fmt(x) != '' for x in minor_tlocs] + assert label_test == label_expected + + @mpl.style.context('default') + def test_sublabel(self): + # test label locator + fig, ax = plt.subplots() + ax.set_xscale('log') + ax.xaxis.set_major_locator(mticker.LogLocator(base=10, subs=[])) + ax.xaxis.set_minor_locator(mticker.LogLocator(base=10, + subs=np.arange(2, 10))) + ax.xaxis.set_major_formatter(mticker.LogFormatter(labelOnlyBase=True)) + ax.xaxis.set_minor_formatter(mticker.LogFormatter(labelOnlyBase=False)) + # axis range above 3 decades, only bases are labeled + ax.set_xlim(1, 1e4) + fmt = ax.xaxis.get_major_formatter() + fmt.set_locs(ax.xaxis.get_majorticklocs()) + show_major_labels = [fmt(x) != '' + for x in ax.xaxis.get_majorticklocs()] + assert np.all(show_major_labels) + self._sub_labels(ax.xaxis, subs=[]) + + # For the next two, if the numdec threshold in LogFormatter.set_locs + # were 3, then the label sub would be 3 for 2-3 decades and (2, 5) + # for 1-2 decades. With a threshold of 1, subs are not labeled. + # axis range at 2 to 3 decades + ax.set_xlim(1, 800) + self._sub_labels(ax.xaxis, subs=[]) + + # axis range at 1 to 2 decades + ax.set_xlim(1, 80) + self._sub_labels(ax.xaxis, subs=[]) + + # axis range at 0.4 to 1 decades, label subs 2, 3, 4, 6 + ax.set_xlim(1, 8) + self._sub_labels(ax.xaxis, subs=[2, 3, 4, 6]) + + # axis range at 0 to 0.4 decades, label all + ax.set_xlim(0.5, 0.9) + self._sub_labels(ax.xaxis, subs=np.arange(2, 10, dtype=int)) + + @pytest.mark.parametrize('val', [1, 10, 100, 1000]) + def test_LogFormatter_call(self, val): + # test _num_to_string method used in __call__ + temp_lf = mticker.LogFormatter() + temp_lf.create_dummy_axis() + temp_lf.axis.set_view_interval(1, 10) + assert temp_lf(val) == str(val) + + @pytest.mark.parametrize('val', [1e-323, 2e-323, 10e-323, 11e-323]) + def test_LogFormatter_call_tiny(self, val): + # test coeff computation in __call__ + temp_lf = mticker.LogFormatter() + temp_lf.create_dummy_axis() + temp_lf.axis.set_view_interval(1, 10) + temp_lf(val) + + +class TestLogitFormatter: + @staticmethod + def logit_deformatter(string): + r""" + Parser to convert string as r'$\mathdefault{1.41\cdot10^{-4}}$' in + float 1.41e-4, as '0.5' or as r'$\mathdefault{\frac{1}{2}}$' in float + 0.5, + """ + match = re.match( + r"[^\d]*" + r"(?P<comp>1-)?" + r"(?P<mant>\d*\.?\d*)?" + r"(?:\\cdot)?" + r"(?:10\^\{(?P<expo>-?\d*)})?" + r"[^\d]*$", + string, + ) + if match: + comp = match["comp"] is not None + mantissa = float(match["mant"]) if match["mant"] else 1 + expo = int(match["expo"]) if match["expo"] is not None else 0 + value = mantissa * 10 ** expo + if match["mant"] or match["expo"] is not None: + if comp: + return 1 - value + return value + match = re.match( + r"[^\d]*\\frac\{(?P<num>\d+)\}\{(?P<deno>\d+)\}[^\d]*$", string + ) + if match: + num, deno = float(match["num"]), float(match["deno"]) + return num / deno + raise ValueError("Not formatted by LogitFormatter") + + @pytest.mark.parametrize( + "fx, x", + [ + (r"STUFF0.41OTHERSTUFF", 0.41), + (r"STUFF1.41\cdot10^{-2}OTHERSTUFF", 1.41e-2), + (r"STUFF1-0.41OTHERSTUFF", 1 - 0.41), + (r"STUFF1-1.41\cdot10^{-2}OTHERSTUFF", 1 - 1.41e-2), + (r"STUFF", None), + (r"STUFF12.4e-3OTHERSTUFF", None), + ], + ) + def test_logit_deformater(self, fx, x): + if x is None: + with pytest.raises(ValueError): + TestLogitFormatter.logit_deformatter(fx) + else: + y = TestLogitFormatter.logit_deformatter(fx) + assert _LogitHelper.isclose(x, y) + + decade_test = sorted( + [10 ** (-i) for i in range(1, 10)] + + [1 - 10 ** (-i) for i in range(1, 10)] + + [1 / 2] + ) + + @pytest.mark.parametrize("x", decade_test) + def test_basic(self, x): + """ + Test the formatted value correspond to the value for ideal ticks in + logit space. + """ + formatter = mticker.LogitFormatter(use_overline=False) + formatter.set_locs(self.decade_test) + s = formatter(x) + x2 = TestLogitFormatter.logit_deformatter(s) + assert _LogitHelper.isclose(x, x2) + + @pytest.mark.parametrize("x", (-1, -0.5, -0.1, 1.1, 1.5, 2)) + def test_invalid(self, x): + """ + Test that invalid value are formatted with empty string without + raising exception. + """ + formatter = mticker.LogitFormatter(use_overline=False) + formatter.set_locs(self.decade_test) + s = formatter(x) + assert s == "" + + @pytest.mark.parametrize("x", 1 / (1 + np.exp(-np.linspace(-7, 7, 10)))) + def test_variablelength(self, x): + """ + The format length should change depending on the neighbor labels. + """ + formatter = mticker.LogitFormatter(use_overline=False) + for N in (10, 20, 50, 100, 200, 1000, 2000, 5000, 10000): + if x + 1 / N < 1: + formatter.set_locs([x - 1 / N, x, x + 1 / N]) + sx = formatter(x) + sx1 = formatter(x + 1 / N) + d = ( + TestLogitFormatter.logit_deformatter(sx1) + - TestLogitFormatter.logit_deformatter(sx) + ) + assert 0 < d < 2 / N + + lims_minor_major = [ + (True, (5e-8, 1 - 5e-8), ((25, False), (75, False))), + (True, (5e-5, 1 - 5e-5), ((25, False), (75, True))), + (True, (5e-2, 1 - 5e-2), ((25, True), (75, True))), + (False, (0.75, 0.76, 0.77), ((7, True), (25, True), (75, True))), + ] + + @pytest.mark.parametrize("method, lims, cases", lims_minor_major) + def test_minor_vs_major(self, method, lims, cases): + """ + Test minor/major displays. + """ + + if method: + min_loc = mticker.LogitLocator(minor=True) + ticks = min_loc.tick_values(*lims) + else: + ticks = np.array(lims) + min_form = mticker.LogitFormatter(minor=True) + for threshold, has_minor in cases: + min_form.set_minor_threshold(threshold) + formatted = min_form.format_ticks(ticks) + labelled = [f for f in formatted if len(f) > 0] + if has_minor: + assert len(labelled) > 0, (threshold, has_minor) + else: + assert len(labelled) == 0, (threshold, has_minor) + + def test_minor_number(self): + """ + Test the parameter minor_number + """ + min_loc = mticker.LogitLocator(minor=True) + min_form = mticker.LogitFormatter(minor=True) + ticks = min_loc.tick_values(5e-2, 1 - 5e-2) + for minor_number in (2, 4, 8, 16): + min_form.set_minor_number(minor_number) + formatted = min_form.format_ticks(ticks) + labelled = [f for f in formatted if len(f) > 0] + assert len(labelled) == minor_number + + def test_use_overline(self): + """ + Test the parameter use_overline + """ + x = 1 - 1e-2 + fx1 = r"$\mathdefault{1-10^{-2}}$" + fx2 = r"$\mathdefault{\overline{10^{-2}}}$" + form = mticker.LogitFormatter(use_overline=False) + assert form(x) == fx1 + form.use_overline(True) + assert form(x) == fx2 + form.use_overline(False) + assert form(x) == fx1 + + def test_one_half(self): + """ + Test the parameter one_half + """ + form = mticker.LogitFormatter() + assert r"\frac{1}{2}" in form(1/2) + form.set_one_half("1/2") + assert "1/2" in form(1/2) + form.set_one_half("one half") + assert "one half" in form(1/2) + + @pytest.mark.parametrize("N", (100, 253, 754)) + def test_format_data_short(self, N): + locs = np.linspace(0, 1, N)[1:-1] + form = mticker.LogitFormatter() + for x in locs: + fx = form.format_data_short(x) + if fx.startswith("1-"): + x2 = 1 - float(fx[2:]) + else: + x2 = float(fx) + assert abs(x - x2) < 1 / N + + +class TestFormatStrFormatter: + def test_basic(self): + # test % style formatter + tmp_form = mticker.FormatStrFormatter('%05d') + assert '00002' == tmp_form(2) + + +class TestStrMethodFormatter: + test_data = [ + ('{x:05d}', (2,), '00002'), + ('{x:03d}-{pos:02d}', (2, 1), '002-01'), + ] + + @pytest.mark.parametrize('format, input, expected', test_data) + def test_basic(self, format, input, expected): + fmt = mticker.StrMethodFormatter(format) + assert fmt(*input) == expected + + +class TestEngFormatter: + # (unicode_minus, input, expected) where ''expected'' corresponds to the + # outputs respectively returned when (places=None, places=0, places=2) + # unicode_minus is a boolean value for the rcParam['axes.unicode_minus'] + raw_format_data = [ + (False, -1234.56789, ('-1.23457 k', '-1 k', '-1.23 k')), + (True, -1234.56789, ('\N{MINUS SIGN}1.23457 k', '\N{MINUS SIGN}1 k', + '\N{MINUS SIGN}1.23 k')), + (False, -1.23456789, ('-1.23457', '-1', '-1.23')), + (True, -1.23456789, ('\N{MINUS SIGN}1.23457', '\N{MINUS SIGN}1', + '\N{MINUS SIGN}1.23')), + (False, -0.123456789, ('-123.457 m', '-123 m', '-123.46 m')), + (True, -0.123456789, ('\N{MINUS SIGN}123.457 m', '\N{MINUS SIGN}123 m', + '\N{MINUS SIGN}123.46 m')), + (False, -0.00123456789, ('-1.23457 m', '-1 m', '-1.23 m')), + (True, -0.00123456789, ('\N{MINUS SIGN}1.23457 m', '\N{MINUS SIGN}1 m', + '\N{MINUS SIGN}1.23 m')), + (True, -0.0, ('0', '0', '0.00')), + (True, -0, ('0', '0', '0.00')), + (True, 0, ('0', '0', '0.00')), + (True, 1.23456789e-6, ('1.23457 µ', '1 µ', '1.23 µ')), + (True, 0.123456789, ('123.457 m', '123 m', '123.46 m')), + (True, 0.1, ('100 m', '100 m', '100.00 m')), + (True, 1, ('1', '1', '1.00')), + (True, 1.23456789, ('1.23457', '1', '1.23')), + # places=0: corner-case rounding + (True, 999.9, ('999.9', '1 k', '999.90')), + # corner-case rounding for all + (True, 999.9999, ('1 k', '1 k', '1.00 k')), + # negative corner-case + (False, -999.9999, ('-1 k', '-1 k', '-1.00 k')), + (True, -999.9999, ('\N{MINUS SIGN}1 k', '\N{MINUS SIGN}1 k', + '\N{MINUS SIGN}1.00 k')), + (True, 1000, ('1 k', '1 k', '1.00 k')), + (True, 1001, ('1.001 k', '1 k', '1.00 k')), + (True, 100001, ('100.001 k', '100 k', '100.00 k')), + (True, 987654.321, ('987.654 k', '988 k', '987.65 k')), + # OoR value (> 1000 Q) + (True, 1.23e33, ('1230 Q', '1230 Q', '1230.00 Q')) + ] + + @pytest.mark.parametrize('unicode_minus, input, expected', raw_format_data) + def test_params(self, unicode_minus, input, expected): + """ + Test the formatting of EngFormatter for various values of the 'places' + argument, in several cases: + + 0. without a unit symbol but with a (default) space separator; + 1. with both a unit symbol and a (default) space separator; + 2. with both a unit symbol and some non default separators; + 3. without a unit symbol but with some non default separators. + + Note that cases 2. and 3. are looped over several separator strings. + """ + + plt.rcParams['axes.unicode_minus'] = unicode_minus + UNIT = 's' # seconds + DIGITS = '0123456789' # %timeit showed 10-20% faster search than set + + # Case 0: unit='' (default) and sep=' ' (default). + # 'expected' already corresponds to this reference case. + exp_outputs = expected + formatters = ( + mticker.EngFormatter(), # places=None (default) + mticker.EngFormatter(places=0), + mticker.EngFormatter(places=2) + ) + for _formatter, _exp_output in zip(formatters, exp_outputs): + assert _formatter(input) == _exp_output + + # Case 1: unit=UNIT and sep=' ' (default). + # Append a unit symbol to the reference case. + # Beware of the values in [1, 1000), where there is no prefix! + exp_outputs = (_s + " " + UNIT if _s[-1] in DIGITS # case w/o prefix + else _s + UNIT for _s in expected) + formatters = ( + mticker.EngFormatter(unit=UNIT), # places=None (default) + mticker.EngFormatter(unit=UNIT, places=0), + mticker.EngFormatter(unit=UNIT, places=2) + ) + for _formatter, _exp_output in zip(formatters, exp_outputs): + assert _formatter(input) == _exp_output + + # Test several non default separators: no separator, a narrow + # no-break space (Unicode character) and an extravagant string. + for _sep in ("", "\N{NARROW NO-BREAK SPACE}", "@_@"): + # Case 2: unit=UNIT and sep=_sep. + # Replace the default space separator from the reference case + # with the tested one `_sep` and append a unit symbol to it. + exp_outputs = (_s + _sep + UNIT if _s[-1] in DIGITS # no prefix + else _s.replace(" ", _sep) + UNIT + for _s in expected) + formatters = ( + mticker.EngFormatter(unit=UNIT, sep=_sep), # places=None + mticker.EngFormatter(unit=UNIT, places=0, sep=_sep), + mticker.EngFormatter(unit=UNIT, places=2, sep=_sep) + ) + for _formatter, _exp_output in zip(formatters, exp_outputs): + assert _formatter(input) == _exp_output + + # Case 3: unit='' (default) and sep=_sep. + # Replace the default space separator from the reference case + # with the tested one `_sep`. Reference case is already unitless. + exp_outputs = (_s.replace(" ", _sep) for _s in expected) + formatters = ( + mticker.EngFormatter(sep=_sep), # places=None (default) + mticker.EngFormatter(places=0, sep=_sep), + mticker.EngFormatter(places=2, sep=_sep) + ) + for _formatter, _exp_output in zip(formatters, exp_outputs): + assert _formatter(input) == _exp_output + + +def test_engformatter_usetex_useMathText(): + fig, ax = plt.subplots() + ax.plot([0, 500, 1000], [0, 500, 1000]) + ax.set_xticks([0, 500, 1000]) + for formatter in (mticker.EngFormatter(usetex=True), + mticker.EngFormatter(useMathText=True)): + ax.xaxis.set_major_formatter(formatter) + fig.canvas.draw() + x_tick_label_text = [labl.get_text() for labl in ax.get_xticklabels()] + # Checking if the dollar `$` signs have been inserted around numbers + # in tick labels. + assert x_tick_label_text == ['$0$', '$500$', '$1$ k'] + + +class TestPercentFormatter: + percent_data = [ + # Check explicitly set decimals over different intervals and values + (100, 0, '%', 120, 100, '120%'), + (100, 0, '%', 100, 90, '100%'), + (100, 0, '%', 90, 50, '90%'), + (100, 0, '%', -1.7, 40, '-2%'), + (100, 1, '%', 90.0, 100, '90.0%'), + (100, 1, '%', 80.1, 90, '80.1%'), + (100, 1, '%', 70.23, 50, '70.2%'), + # 60.554 instead of 60.55: see https://bugs.python.org/issue5118 + (100, 1, '%', -60.554, 40, '-60.6%'), + # Check auto decimals over different intervals and values + (100, None, '%', 95, 1, '95.00%'), + (1.0, None, '%', 3, 6, '300%'), + (17.0, None, '%', 1, 8.5, '6%'), + (17.0, None, '%', 1, 8.4, '5.9%'), + (5, None, '%', -100, 0.000001, '-2000.00000%'), + # Check percent symbol + (1.0, 2, None, 1.2, 100, '120.00'), + (75, 3, '', 50, 100, '66.667'), + (42, None, '^^Foobar$$', 21, 12, '50.0^^Foobar$$'), + ] + + percent_ids = [ + # Check explicitly set decimals over different intervals and values + 'decimals=0, x>100%', + 'decimals=0, x=100%', + 'decimals=0, x<100%', + 'decimals=0, x<0%', + 'decimals=1, x>100%', + 'decimals=1, x=100%', + 'decimals=1, x<100%', + 'decimals=1, x<0%', + # Check auto decimals over different intervals and values + 'autodecimal, x<100%, display_range=1', + 'autodecimal, x>100%, display_range=6 (custom xmax test)', + 'autodecimal, x<100%, display_range=8.5 (autodecimal test 1)', + 'autodecimal, x<100%, display_range=8.4 (autodecimal test 2)', + 'autodecimal, x<-100%, display_range=1e-6 (tiny display range)', + # Check percent symbol + 'None as percent symbol', + 'Empty percent symbol', + 'Custom percent symbol', + ] + + latex_data = [ + (False, False, r'50\{t}%'), + (False, True, r'50\\\{t\}\%'), + (True, False, r'50\{t}%'), + (True, True, r'50\{t}%'), + ] + + @pytest.mark.parametrize( + 'xmax, decimals, symbol, x, display_range, expected', + percent_data, ids=percent_ids) + def test_basic(self, xmax, decimals, symbol, + x, display_range, expected): + formatter = mticker.PercentFormatter(xmax, decimals, symbol) + with mpl.rc_context(rc={'text.usetex': False}): + assert formatter.format_pct(x, display_range) == expected + + @pytest.mark.parametrize('is_latex, usetex, expected', latex_data) + def test_latex(self, is_latex, usetex, expected): + fmt = mticker.PercentFormatter(symbol='\\{t}%', is_latex=is_latex) + with mpl.rc_context(rc={'text.usetex': usetex}): + assert fmt.format_pct(50, 100) == expected + + +def _impl_locale_comma(): + try: + locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') + except locale.Error: + print('SKIP: Locale de_DE.UTF-8 is not supported on this machine') + return + ticks = mticker.ScalarFormatter(useMathText=True, useLocale=True) + fmt = '$\\mathdefault{%1.1f}$' + x = ticks._format_maybe_minus_and_locale(fmt, 0.5) + assert x == '$\\mathdefault{0{,}5}$' + # Do not change , in the format string + fmt = ',$\\mathdefault{,%1.1f},$' + x = ticks._format_maybe_minus_and_locale(fmt, 0.5) + assert x == ',$\\mathdefault{,0{,}5},$' + # Make sure no brackets are added if not using math text + ticks = mticker.ScalarFormatter(useMathText=False, useLocale=True) + fmt = '%1.1f' + x = ticks._format_maybe_minus_and_locale(fmt, 0.5) + assert x == '0,5' + + +def test_locale_comma(): + # On some systems/pytest versions, `pytest.skip` in an exception handler + # does not skip, but is treated as an exception, so directly running this + # test can incorrectly fail instead of skip. + # Instead, run this test in a subprocess, which avoids the problem, and the + # need to fix the locale after. + proc = mpl.testing.subprocess_run_helper(_impl_locale_comma, timeout=60, + extra_env={'MPLBACKEND': 'Agg'}) + skip_msg = next((line[len('SKIP:'):].strip() + for line in proc.stdout.splitlines() + if line.startswith('SKIP:')), + '') + if skip_msg: + pytest.skip(skip_msg) + + +def test_majformatter_type(): + fig, ax = plt.subplots() + with pytest.raises(TypeError): + ax.xaxis.set_major_formatter(mticker.LogLocator()) + + +def test_minformatter_type(): + fig, ax = plt.subplots() + with pytest.raises(TypeError): + ax.xaxis.set_minor_formatter(mticker.LogLocator()) + + +def test_majlocator_type(): + fig, ax = plt.subplots() + with pytest.raises(TypeError): + ax.xaxis.set_major_locator(mticker.LogFormatter()) + + +def test_minlocator_type(): + fig, ax = plt.subplots() + with pytest.raises(TypeError): + ax.xaxis.set_minor_locator(mticker.LogFormatter()) + + +def test_minorticks_rc(): + fig = plt.figure() + + def minorticksubplot(xminor, yminor, i): + rc = {'xtick.minor.visible': xminor, + 'ytick.minor.visible': yminor} + with plt.rc_context(rc=rc): + ax = fig.add_subplot(2, 2, i) + + assert (len(ax.xaxis.get_minor_ticks()) > 0) == xminor + assert (len(ax.yaxis.get_minor_ticks()) > 0) == yminor + + minorticksubplot(False, False, 1) + minorticksubplot(True, False, 2) + minorticksubplot(False, True, 3) + minorticksubplot(True, True, 4) + + +@pytest.mark.parametrize('remove_overlapping_locs, expected_num', + ((True, 6), + (None, 6), # this tests the default + (False, 9))) +def test_remove_overlap(remove_overlapping_locs, expected_num): + t = np.arange("2018-11-03", "2018-11-06", dtype="datetime64") + x = np.ones(len(t)) + + fig, ax = plt.subplots() + ax.plot(t, x) + + ax.xaxis.set_major_locator(mpl.dates.DayLocator()) + ax.xaxis.set_major_formatter(mpl.dates.DateFormatter('\n%a')) + + ax.xaxis.set_minor_locator(mpl.dates.HourLocator((0, 6, 12, 18))) + ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%H:%M')) + # force there to be extra ticks + ax.xaxis.get_minor_ticks(15) + if remove_overlapping_locs is not None: + ax.xaxis.remove_overlapping_locs = remove_overlapping_locs + + # check that getter/setter exists + current = ax.xaxis.remove_overlapping_locs + assert (current == ax.xaxis.get_remove_overlapping_locs()) + plt.setp(ax.xaxis, remove_overlapping_locs=current) + new = ax.xaxis.remove_overlapping_locs + assert (new == ax.xaxis.remove_overlapping_locs) + + # check that the accessors filter correctly + # this is the method that does the actual filtering + assert len(ax.xaxis.get_minorticklocs()) == expected_num + # these three are derivative + assert len(ax.xaxis.get_minor_ticks()) == expected_num + assert len(ax.xaxis.get_minorticklabels()) == expected_num + assert len(ax.xaxis.get_minorticklines()) == expected_num*2 + + +@pytest.mark.parametrize('sub', [ + ['hi', 'aardvark'], + np.zeros((2, 2))]) +def test_bad_locator_subs(sub): + ll = mticker.LogLocator() + with pytest.raises(ValueError): + ll.set_params(subs=sub) + + +@pytest.mark.parametrize('numticks', [1, 2, 3, 9]) +@mpl.style.context('default') +def test_small_range_loglocator(numticks): + ll = mticker.LogLocator() + ll.set_params(numticks=numticks) + for top in [5, 7, 9, 11, 15, 50, 100, 1000]: + ticks = ll.tick_values(.5, top) + assert (np.diff(np.log10(ll.tick_values(6, 150))) == 1).all() + + +def test_NullFormatter(): + formatter = mticker.NullFormatter() + assert formatter(1.0) == '' + assert formatter.format_data(1.0) == '' + assert formatter.format_data_short(1.0) == '' + + +@pytest.mark.parametrize('formatter', ( + mticker.FuncFormatter(lambda a: f'val: {a}'), + mticker.FixedFormatter(('foo', 'bar')))) +def test_set_offset_string(formatter): + assert formatter.get_offset() == '' + formatter.set_offset_string('mpl') + assert formatter.get_offset() == 'mpl' diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_tightlayout.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_tightlayout.py new file mode 100644 index 00000000..968f0da7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_tightlayout.py @@ -0,0 +1,393 @@ +import warnings + +import numpy as np +from numpy.testing import assert_array_equal +import pytest + +import matplotlib as mpl +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +from matplotlib.offsetbox import AnchoredOffsetbox, DrawingArea +from matplotlib.patches import Rectangle + + +def example_plot(ax, fontsize=12): + ax.plot([1, 2]) + ax.locator_params(nbins=3) + ax.set_xlabel('x-label', fontsize=fontsize) + ax.set_ylabel('y-label', fontsize=fontsize) + ax.set_title('Title', fontsize=fontsize) + + +@image_comparison(['tight_layout1'], tol=1.9) +def test_tight_layout1(): + """Test tight_layout for a single subplot.""" + fig, ax = plt.subplots() + example_plot(ax, fontsize=24) + plt.tight_layout() + + +@image_comparison(['tight_layout2']) +def test_tight_layout2(): + """Test tight_layout for multiple subplots.""" + fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2) + example_plot(ax1) + example_plot(ax2) + example_plot(ax3) + example_plot(ax4) + plt.tight_layout() + + +@image_comparison(['tight_layout3']) +def test_tight_layout3(): + """Test tight_layout for multiple subplots.""" + ax1 = plt.subplot(221) + ax2 = plt.subplot(223) + ax3 = plt.subplot(122) + example_plot(ax1) + example_plot(ax2) + example_plot(ax3) + plt.tight_layout() + + +@image_comparison(['tight_layout4'], freetype_version=('2.5.5', '2.6.1'), + tol=0.015) +def test_tight_layout4(): + """Test tight_layout for subplot2grid.""" + ax1 = plt.subplot2grid((3, 3), (0, 0)) + ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2) + ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=2, rowspan=2) + ax4 = plt.subplot2grid((3, 3), (1, 2), rowspan=2) + example_plot(ax1) + example_plot(ax2) + example_plot(ax3) + example_plot(ax4) + plt.tight_layout() + + +@image_comparison(['tight_layout5']) +def test_tight_layout5(): + """Test tight_layout for image.""" + ax = plt.subplot() + arr = np.arange(100).reshape((10, 10)) + ax.imshow(arr, interpolation="none") + plt.tight_layout() + + +@image_comparison(['tight_layout6']) +def test_tight_layout6(): + """Test tight_layout for gridspec.""" + + # This raises warnings since tight layout cannot + # do this fully automatically. But the test is + # correct since the layout is manually edited + with warnings.catch_warnings(): + warnings.simplefilter("ignore", UserWarning) + fig = plt.figure() + + gs1 = mpl.gridspec.GridSpec(2, 1) + ax1 = fig.add_subplot(gs1[0]) + ax2 = fig.add_subplot(gs1[1]) + + example_plot(ax1) + example_plot(ax2) + + gs1.tight_layout(fig, rect=[0, 0, 0.5, 1]) + + gs2 = mpl.gridspec.GridSpec(3, 1) + + for ss in gs2: + ax = fig.add_subplot(ss) + example_plot(ax) + ax.set_title("") + ax.set_xlabel("") + + ax.set_xlabel("x-label", fontsize=12) + + gs2.tight_layout(fig, rect=[0.5, 0, 1, 1], h_pad=0.45) + + top = min(gs1.top, gs2.top) + bottom = max(gs1.bottom, gs2.bottom) + + gs1.tight_layout(fig, rect=[None, 0 + (bottom-gs1.bottom), + 0.5, 1 - (gs1.top-top)]) + gs2.tight_layout(fig, rect=[0.5, 0 + (bottom-gs2.bottom), + None, 1 - (gs2.top-top)], + h_pad=0.45) + + +@image_comparison(['tight_layout7'], tol=1.9) +def test_tight_layout7(): + # tight layout with left and right titles + fontsize = 24 + fig, ax = plt.subplots() + ax.plot([1, 2]) + ax.locator_params(nbins=3) + ax.set_xlabel('x-label', fontsize=fontsize) + ax.set_ylabel('y-label', fontsize=fontsize) + ax.set_title('Left Title', loc='left', fontsize=fontsize) + ax.set_title('Right Title', loc='right', fontsize=fontsize) + plt.tight_layout() + + +@image_comparison(['tight_layout8']) +def test_tight_layout8(): + """Test automatic use of tight_layout.""" + fig = plt.figure() + fig.set_layout_engine(layout='tight', pad=0.1) + ax = fig.add_subplot() + example_plot(ax, fontsize=24) + fig.draw_without_rendering() + + +@image_comparison(['tight_layout9']) +def test_tight_layout9(): + # Test tight_layout for non-visible subplots + # GH 8244 + f, axarr = plt.subplots(2, 2) + axarr[1][1].set_visible(False) + plt.tight_layout() + + +def test_outward_ticks(): + """Test automatic use of tight_layout.""" + fig = plt.figure() + ax = fig.add_subplot(221) + ax.xaxis.set_tick_params(tickdir='out', length=16, width=3) + ax.yaxis.set_tick_params(tickdir='out', length=16, width=3) + ax.xaxis.set_tick_params( + tickdir='out', length=32, width=3, tick1On=True, which='minor') + ax.yaxis.set_tick_params( + tickdir='out', length=32, width=3, tick1On=True, which='minor') + ax.xaxis.set_ticks([0], minor=True) + ax.yaxis.set_ticks([0], minor=True) + ax = fig.add_subplot(222) + ax.xaxis.set_tick_params(tickdir='in', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='in', length=32, width=3) + ax = fig.add_subplot(223) + ax.xaxis.set_tick_params(tickdir='inout', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='inout', length=32, width=3) + ax = fig.add_subplot(224) + ax.xaxis.set_tick_params(tickdir='out', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='out', length=32, width=3) + plt.tight_layout() + # These values were obtained after visual checking that they correspond + # to a tight layouting that did take the ticks into account. + ans = [[[0.091, 0.607], [0.433, 0.933]], + [[0.579, 0.607], [0.922, 0.933]], + [[0.091, 0.140], [0.433, 0.466]], + [[0.579, 0.140], [0.922, 0.466]]] + for nn, ax in enumerate(fig.axes): + assert_array_equal(np.round(ax.get_position().get_points(), 3), + ans[nn]) + + +def add_offsetboxes(ax, size=10, margin=.1, color='black'): + """ + Surround ax with OffsetBoxes + """ + m, mp = margin, 1+margin + anchor_points = [(-m, -m), (-m, .5), (-m, mp), + (mp, .5), (.5, mp), (mp, mp), + (.5, -m), (mp, -m), (.5, -m)] + for point in anchor_points: + da = DrawingArea(size, size) + background = Rectangle((0, 0), width=size, + height=size, + facecolor=color, + edgecolor='None', + linewidth=0, + antialiased=False) + da.add_artist(background) + + anchored_box = AnchoredOffsetbox( + loc='center', + child=da, + pad=0., + frameon=False, + bbox_to_anchor=point, + bbox_transform=ax.transAxes, + borderpad=0.) + ax.add_artist(anchored_box) + return anchored_box + + +@image_comparison(['tight_layout_offsetboxes1', 'tight_layout_offsetboxes2']) +def test_tight_layout_offsetboxes(): + # 1. + # - Create 4 subplots + # - Plot a diagonal line on them + # - Surround each plot with 7 boxes + # - Use tight_layout + # - See that the squares are included in the tight_layout + # and that the squares in the middle do not overlap + # + # 2. + # - Make the squares around the right side axes invisible + # - See that the invisible squares do not affect the + # tight_layout + rows = cols = 2 + colors = ['red', 'blue', 'green', 'yellow'] + x = y = [0, 1] + + def _subplots(): + _, axs = plt.subplots(rows, cols) + axs = axs.flat + for ax, color in zip(axs, colors): + ax.plot(x, y, color=color) + add_offsetboxes(ax, 20, color=color) + return axs + + # 1. + axs = _subplots() + plt.tight_layout() + + # 2. + axs = _subplots() + for ax in (axs[cols-1::rows]): + for child in ax.get_children(): + if isinstance(child, AnchoredOffsetbox): + child.set_visible(False) + + plt.tight_layout() + + +def test_empty_layout(): + """Test that tight layout doesn't cause an error when there are no axes.""" + fig = plt.gcf() + fig.tight_layout() + + +@pytest.mark.parametrize("label", ["xlabel", "ylabel"]) +def test_verybig_decorators(label): + """Test that no warning emitted when xlabel/ylabel too big.""" + fig, ax = plt.subplots(figsize=(3, 2)) + ax.set(**{label: 'a' * 100}) + + +def test_big_decorators_horizontal(): + """Test that doesn't warn when xlabel too big.""" + fig, axs = plt.subplots(1, 2, figsize=(3, 2)) + axs[0].set_xlabel('a' * 30) + axs[1].set_xlabel('b' * 30) + + +def test_big_decorators_vertical(): + """Test that doesn't warn when ylabel too big.""" + fig, axs = plt.subplots(2, 1, figsize=(3, 2)) + axs[0].set_ylabel('a' * 20) + axs[1].set_ylabel('b' * 20) + + +def test_badsubplotgrid(): + # test that we get warning for mismatched subplot grids, not than an error + plt.subplot2grid((4, 5), (0, 0)) + # this is the bad entry: + plt.subplot2grid((5, 5), (0, 3), colspan=3, rowspan=5) + with pytest.warns(UserWarning): + plt.tight_layout() + + +def test_collapsed(): + # test that if the amount of space required to make all the axes + # decorations fit would mean that the actual Axes would end up with size + # zero (i.e. margins add up to more than the available width) that a call + # to tight_layout will not get applied: + fig, ax = plt.subplots(tight_layout=True) + ax.set_xlim([0, 1]) + ax.set_ylim([0, 1]) + + ax.annotate('BIG LONG STRING', xy=(1.25, 2), xytext=(10.5, 1.75), + annotation_clip=False) + p1 = ax.get_position() + with pytest.warns(UserWarning): + plt.tight_layout() + p2 = ax.get_position() + assert p1.width == p2.width + # test that passing a rect doesn't crash... + with pytest.warns(UserWarning): + plt.tight_layout(rect=[0, 0, 0.8, 0.8]) + + +def test_suptitle(): + fig, ax = plt.subplots(tight_layout=True) + st = fig.suptitle("foo") + t = ax.set_title("bar") + fig.canvas.draw() + assert st.get_window_extent().y0 > t.get_window_extent().y1 + + +@pytest.mark.backend("pdf") +def test_non_agg_renderer(monkeypatch, recwarn): + unpatched_init = mpl.backend_bases.RendererBase.__init__ + + def __init__(self, *args, **kwargs): + # Check that we don't instantiate any other renderer than a pdf + # renderer to perform pdf tight layout. + assert isinstance(self, mpl.backends.backend_pdf.RendererPdf) + unpatched_init(self, *args, **kwargs) + + monkeypatch.setattr(mpl.backend_bases.RendererBase, "__init__", __init__) + fig, ax = plt.subplots() + fig.tight_layout() + + +def test_manual_colorbar(): + # This should warn, but not raise + fig, axes = plt.subplots(1, 2) + pts = axes[1].scatter([0, 1], [0, 1], c=[1, 5]) + ax_rect = axes[1].get_position() + cax = fig.add_axes( + [ax_rect.x1 + 0.005, ax_rect.y0, 0.015, ax_rect.height] + ) + fig.colorbar(pts, cax=cax) + with pytest.warns(UserWarning, match="This figure includes Axes"): + fig.tight_layout() + + +def test_clipped_to_axes(): + # Ensure that _fully_clipped_to_axes() returns True under default + # conditions for all projection types. Axes.get_tightbbox() + # uses this to skip artists in layout calculations. + arr = np.arange(100).reshape((10, 10)) + fig = plt.figure(figsize=(6, 2)) + ax1 = fig.add_subplot(131, projection='rectilinear') + ax2 = fig.add_subplot(132, projection='mollweide') + ax3 = fig.add_subplot(133, projection='polar') + for ax in (ax1, ax2, ax3): + # Default conditions (clipped by ax.bbox or ax.patch) + ax.grid(False) + h, = ax.plot(arr[:, 0]) + m = ax.pcolor(arr) + assert h._fully_clipped_to_axes() + assert m._fully_clipped_to_axes() + # Non-default conditions (not clipped by ax.patch) + rect = Rectangle((0, 0), 0.5, 0.5, transform=ax.transAxes) + h.set_clip_path(rect) + m.set_clip_path(rect.get_path(), rect.get_transform()) + assert not h._fully_clipped_to_axes() + assert not m._fully_clipped_to_axes() + + +def test_tight_pads(): + fig, ax = plt.subplots() + with pytest.warns(PendingDeprecationWarning, + match='will be deprecated'): + fig.set_tight_layout({'pad': 0.15}) + fig.draw_without_rendering() + + +def test_tight_kwargs(): + fig, ax = plt.subplots(tight_layout={'pad': 0.15}) + fig.draw_without_rendering() + + +def test_tight_toggle(): + fig, ax = plt.subplots() + with pytest.warns(PendingDeprecationWarning): + fig.set_tight_layout(True) + assert fig.get_tight_layout() + fig.set_tight_layout(False) + assert not fig.get_tight_layout() + fig.set_tight_layout(True) + assert fig.get_tight_layout() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_transforms.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_transforms.py new file mode 100644 index 00000000..a9a92d33 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_transforms.py @@ -0,0 +1,788 @@ +import copy + +import numpy as np +from numpy.testing import (assert_allclose, assert_almost_equal, + assert_array_equal, assert_array_almost_equal) +import pytest + +from matplotlib import scale +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import matplotlib.transforms as mtransforms +from matplotlib.transforms import Affine2D, Bbox, TransformedBbox +from matplotlib.path import Path +from matplotlib.testing.decorators import image_comparison, check_figures_equal + + +def test_non_affine_caching(): + class AssertingNonAffineTransform(mtransforms.Transform): + """ + This transform raises an assertion error when called when it + shouldn't be and ``self.raise_on_transform`` is True. + + """ + input_dims = output_dims = 2 + is_affine = False + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.raise_on_transform = False + self.underlying_transform = mtransforms.Affine2D().scale(10, 10) + + def transform_path_non_affine(self, path): + assert not self.raise_on_transform, \ + 'Invalidated affine part of transform unnecessarily.' + return self.underlying_transform.transform_path(path) + transform_path = transform_path_non_affine + + def transform_non_affine(self, path): + assert not self.raise_on_transform, \ + 'Invalidated affine part of transform unnecessarily.' + return self.underlying_transform.transform(path) + transform = transform_non_affine + + my_trans = AssertingNonAffineTransform() + ax = plt.axes() + plt.plot(np.arange(10), transform=my_trans + ax.transData) + plt.draw() + # enable the transform to raise an exception if it's non-affine transform + # method is triggered again. + my_trans.raise_on_transform = True + ax.transAxes.invalidate() + plt.draw() + + +def test_external_transform_api(): + class ScaledBy: + def __init__(self, scale_factor): + self._scale_factor = scale_factor + + def _as_mpl_transform(self, axes): + return (mtransforms.Affine2D().scale(self._scale_factor) + + axes.transData) + + ax = plt.axes() + line, = plt.plot(np.arange(10), transform=ScaledBy(10)) + ax.set_xlim(0, 100) + ax.set_ylim(0, 100) + # assert that the top transform of the line is the scale transform. + assert_allclose(line.get_transform()._a.get_matrix(), + mtransforms.Affine2D().scale(10).get_matrix()) + + +@image_comparison(['pre_transform_data'], remove_text=True, style='mpl20', + tol=0.05) +def test_pre_transform_plotting(): + # a catch-all for as many as possible plot layouts which handle + # pre-transforming the data NOTE: The axis range is important in this + # plot. It should be x10 what the data suggests it should be + + ax = plt.axes() + times10 = mtransforms.Affine2D().scale(10) + + ax.contourf(np.arange(48).reshape(6, 8), transform=times10 + ax.transData) + + ax.pcolormesh(np.linspace(0, 4, 7), + np.linspace(5.5, 8, 9), + np.arange(48).reshape(8, 6), + transform=times10 + ax.transData) + + ax.scatter(np.linspace(0, 10), np.linspace(10, 0), + transform=times10 + ax.transData) + + x = np.linspace(8, 10, 20) + y = np.linspace(1, 5, 20) + u = 2*np.sin(x) + np.cos(y[:, np.newaxis]) + v = np.sin(x) - np.cos(y[:, np.newaxis]) + + ax.streamplot(x, y, u, v, transform=times10 + ax.transData, + linewidth=np.hypot(u, v)) + + # reduce the vector data down a bit for barb and quiver plotting + x, y = x[::3], y[::3] + u, v = u[::3, ::3], v[::3, ::3] + + ax.quiver(x, y + 5, u, v, transform=times10 + ax.transData) + + ax.barbs(x - 3, y + 5, u**2, v**2, transform=times10 + ax.transData) + + +def test_contour_pre_transform_limits(): + ax = plt.axes() + xs, ys = np.meshgrid(np.linspace(15, 20, 15), np.linspace(12.4, 12.5, 20)) + ax.contourf(xs, ys, np.log(xs * ys), + transform=mtransforms.Affine2D().scale(0.1) + ax.transData) + + expected = np.array([[1.5, 1.24], + [2., 1.25]]) + assert_almost_equal(expected, ax.dataLim.get_points()) + + +def test_pcolor_pre_transform_limits(): + # Based on test_contour_pre_transform_limits() + ax = plt.axes() + xs, ys = np.meshgrid(np.linspace(15, 20, 15), np.linspace(12.4, 12.5, 20)) + ax.pcolor(xs, ys, np.log(xs * ys)[:-1, :-1], + transform=mtransforms.Affine2D().scale(0.1) + ax.transData) + + expected = np.array([[1.5, 1.24], + [2., 1.25]]) + assert_almost_equal(expected, ax.dataLim.get_points()) + + +def test_pcolormesh_pre_transform_limits(): + # Based on test_contour_pre_transform_limits() + ax = plt.axes() + xs, ys = np.meshgrid(np.linspace(15, 20, 15), np.linspace(12.4, 12.5, 20)) + ax.pcolormesh(xs, ys, np.log(xs * ys)[:-1, :-1], + transform=mtransforms.Affine2D().scale(0.1) + ax.transData) + + expected = np.array([[1.5, 1.24], + [2., 1.25]]) + assert_almost_equal(expected, ax.dataLim.get_points()) + + +def test_pcolormesh_gouraud_nans(): + np.random.seed(19680801) + + values = np.linspace(0, 180, 3) + radii = np.linspace(100, 1000, 10) + z, y = np.meshgrid(values, radii) + x = np.radians(np.random.rand(*z.shape) * 100) + + fig = plt.figure() + ax = fig.add_subplot(111, projection="polar") + # Setting the limit to cause clipping of the r values causes NaN to be + # introduced; these should not crash but be ignored as in other path + # operations. + ax.set_rlim(101, 1000) + ax.pcolormesh(x, y, z, shading="gouraud") + + fig.canvas.draw() + + +def test_Affine2D_from_values(): + points = np.array([[0, 0], + [10, 20], + [-1, 0], + ]) + + t = mtransforms.Affine2D.from_values(1, 0, 0, 0, 0, 0) + actual = t.transform(points) + expected = np.array([[0, 0], [10, 0], [-1, 0]]) + assert_almost_equal(actual, expected) + + t = mtransforms.Affine2D.from_values(0, 2, 0, 0, 0, 0) + actual = t.transform(points) + expected = np.array([[0, 0], [0, 20], [0, -2]]) + assert_almost_equal(actual, expected) + + t = mtransforms.Affine2D.from_values(0, 0, 3, 0, 0, 0) + actual = t.transform(points) + expected = np.array([[0, 0], [60, 0], [0, 0]]) + assert_almost_equal(actual, expected) + + t = mtransforms.Affine2D.from_values(0, 0, 0, 4, 0, 0) + actual = t.transform(points) + expected = np.array([[0, 0], [0, 80], [0, 0]]) + assert_almost_equal(actual, expected) + + t = mtransforms.Affine2D.from_values(0, 0, 0, 0, 5, 0) + actual = t.transform(points) + expected = np.array([[5, 0], [5, 0], [5, 0]]) + assert_almost_equal(actual, expected) + + t = mtransforms.Affine2D.from_values(0, 0, 0, 0, 0, 6) + actual = t.transform(points) + expected = np.array([[0, 6], [0, 6], [0, 6]]) + assert_almost_equal(actual, expected) + + +def test_affine_inverted_invalidated(): + # Ensure that the an affine transform is not declared valid on access + point = [1.0, 1.0] + t = mtransforms.Affine2D() + + assert_almost_equal(point, t.transform(t.inverted().transform(point))) + # Change and access the transform + t.translate(1.0, 1.0).get_matrix() + assert_almost_equal(point, t.transform(t.inverted().transform(point))) + + +def test_clipping_of_log(): + # issue 804 + path = Path._create_closed([(0.2, -99), (0.4, -99), (0.4, 20), (0.2, 20)]) + # something like this happens in plotting logarithmic histograms + trans = mtransforms.BlendedGenericTransform( + mtransforms.Affine2D(), scale.LogTransform(10, 'clip')) + tpath = trans.transform_path_non_affine(path) + result = tpath.iter_segments(trans.get_affine(), + clip=(0, 0, 100, 100), + simplify=False) + tpoints, tcodes = zip(*result) + assert_allclose(tcodes, path.codes[:-1]) # No longer closed. + + +class NonAffineForTest(mtransforms.Transform): + """ + A class which looks like a non affine transform, but does whatever + the given transform does (even if it is affine). This is very useful + for testing NonAffine behaviour with a simple Affine transform. + + """ + is_affine = False + output_dims = 2 + input_dims = 2 + + def __init__(self, real_trans, *args, **kwargs): + self.real_trans = real_trans + super().__init__(*args, **kwargs) + + def transform_non_affine(self, values): + return self.real_trans.transform(values) + + def transform_path_non_affine(self, path): + return self.real_trans.transform_path(path) + + +class TestBasicTransform: + def setup_method(self): + + self.ta1 = mtransforms.Affine2D(shorthand_name='ta1').rotate(np.pi / 2) + self.ta2 = mtransforms.Affine2D(shorthand_name='ta2').translate(10, 0) + self.ta3 = mtransforms.Affine2D(shorthand_name='ta3').scale(1, 2) + + self.tn1 = NonAffineForTest(mtransforms.Affine2D().translate(1, 2), + shorthand_name='tn1') + self.tn2 = NonAffineForTest(mtransforms.Affine2D().translate(1, 2), + shorthand_name='tn2') + self.tn3 = NonAffineForTest(mtransforms.Affine2D().translate(1, 2), + shorthand_name='tn3') + + # creates a transform stack which looks like ((A, (N, A)), A) + self.stack1 = (self.ta1 + (self.tn1 + self.ta2)) + self.ta3 + # creates a transform stack which looks like (((A, N), A), A) + self.stack2 = self.ta1 + self.tn1 + self.ta2 + self.ta3 + # creates a transform stack which is a subset of stack2 + self.stack2_subset = self.tn1 + self.ta2 + self.ta3 + + # when in debug, the transform stacks can produce dot images: +# self.stack1.write_graphviz(file('stack1.dot', 'w')) +# self.stack2.write_graphviz(file('stack2.dot', 'w')) +# self.stack2_subset.write_graphviz(file('stack2_subset.dot', 'w')) + + def test_transform_depth(self): + assert self.stack1.depth == 4 + assert self.stack2.depth == 4 + assert self.stack2_subset.depth == 3 + + def test_left_to_right_iteration(self): + stack3 = (self.ta1 + (self.tn1 + (self.ta2 + self.tn2))) + self.ta3 +# stack3.write_graphviz(file('stack3.dot', 'w')) + + target_transforms = [stack3, + (self.tn1 + (self.ta2 + self.tn2)) + self.ta3, + (self.ta2 + self.tn2) + self.ta3, + self.tn2 + self.ta3, + self.ta3, + ] + r = [rh for _, rh in stack3._iter_break_from_left_to_right()] + assert len(r) == len(target_transforms) + + for target_stack, stack in zip(target_transforms, r): + assert target_stack == stack + + def test_transform_shortcuts(self): + assert self.stack1 - self.stack2_subset == self.ta1 + assert self.stack2 - self.stack2_subset == self.ta1 + + assert self.stack2_subset - self.stack2 == self.ta1.inverted() + assert (self.stack2_subset - self.stack2).depth == 1 + + with pytest.raises(ValueError): + self.stack1 - self.stack2 + + aff1 = self.ta1 + (self.ta2 + self.ta3) + aff2 = self.ta2 + self.ta3 + + assert aff1 - aff2 == self.ta1 + assert aff1 - self.ta2 == aff1 + self.ta2.inverted() + + assert self.stack1 - self.ta3 == self.ta1 + (self.tn1 + self.ta2) + assert self.stack2 - self.ta3 == self.ta1 + self.tn1 + self.ta2 + + assert ((self.ta2 + self.ta3) - self.ta3 + self.ta3 == + self.ta2 + self.ta3) + + def test_contains_branch(self): + r1 = (self.ta2 + self.ta1) + r2 = (self.ta2 + self.ta1) + assert r1 == r2 + assert r1 != self.ta1 + assert r1.contains_branch(r2) + assert r1.contains_branch(self.ta1) + assert not r1.contains_branch(self.ta2) + assert not r1.contains_branch(self.ta2 + self.ta2) + + assert r1 == r2 + + assert self.stack1.contains_branch(self.ta3) + assert self.stack2.contains_branch(self.ta3) + + assert self.stack1.contains_branch(self.stack2_subset) + assert self.stack2.contains_branch(self.stack2_subset) + + assert not self.stack2_subset.contains_branch(self.stack1) + assert not self.stack2_subset.contains_branch(self.stack2) + + assert self.stack1.contains_branch(self.ta2 + self.ta3) + assert self.stack2.contains_branch(self.ta2 + self.ta3) + + assert not self.stack1.contains_branch(self.tn1 + self.ta2) + + def test_affine_simplification(self): + # tests that a transform stack only calls as much is absolutely + # necessary "non-affine" allowing the best possible optimization with + # complex transformation stacks. + points = np.array([[0, 0], [10, 20], [np.nan, 1], [-1, 0]], + dtype=np.float64) + na_pts = self.stack1.transform_non_affine(points) + all_pts = self.stack1.transform(points) + + na_expected = np.array([[1., 2.], [-19., 12.], + [np.nan, np.nan], [1., 1.]], dtype=np.float64) + all_expected = np.array([[11., 4.], [-9., 24.], + [np.nan, np.nan], [11., 2.]], + dtype=np.float64) + + # check we have the expected results from doing the affine part only + assert_array_almost_equal(na_pts, na_expected) + # check we have the expected results from a full transformation + assert_array_almost_equal(all_pts, all_expected) + # check we have the expected results from doing the transformation in + # two steps + assert_array_almost_equal(self.stack1.transform_affine(na_pts), + all_expected) + # check that getting the affine transformation first, then fully + # transforming using that yields the same result as before. + assert_array_almost_equal(self.stack1.get_affine().transform(na_pts), + all_expected) + + # check that the affine part of stack1 & stack2 are equivalent + # (i.e. the optimization is working) + expected_result = (self.ta2 + self.ta3).get_matrix() + result = self.stack1.get_affine().get_matrix() + assert_array_equal(expected_result, result) + + result = self.stack2.get_affine().get_matrix() + assert_array_equal(expected_result, result) + + +class TestTransformPlotInterface: + def test_line_extent_axes_coords(self): + # a simple line in axes coordinates + ax = plt.axes() + ax.plot([0.1, 1.2, 0.8], [0.9, 0.5, 0.8], transform=ax.transAxes) + assert_array_equal(ax.dataLim.get_points(), + np.array([[np.inf, np.inf], + [-np.inf, -np.inf]])) + + def test_line_extent_data_coords(self): + # a simple line in data coordinates + ax = plt.axes() + ax.plot([0.1, 1.2, 0.8], [0.9, 0.5, 0.8], transform=ax.transData) + assert_array_equal(ax.dataLim.get_points(), + np.array([[0.1, 0.5], [1.2, 0.9]])) + + def test_line_extent_compound_coords1(self): + # a simple line in data coordinates in the y component, and in axes + # coordinates in the x + ax = plt.axes() + trans = mtransforms.blended_transform_factory(ax.transAxes, + ax.transData) + ax.plot([0.1, 1.2, 0.8], [35, -5, 18], transform=trans) + assert_array_equal(ax.dataLim.get_points(), + np.array([[np.inf, -5.], + [-np.inf, 35.]])) + + def test_line_extent_predata_transform_coords(self): + # a simple line in (offset + data) coordinates + ax = plt.axes() + trans = mtransforms.Affine2D().scale(10) + ax.transData + ax.plot([0.1, 1.2, 0.8], [35, -5, 18], transform=trans) + assert_array_equal(ax.dataLim.get_points(), + np.array([[1., -50.], [12., 350.]])) + + def test_line_extent_compound_coords2(self): + # a simple line in (offset + data) coordinates in the y component, and + # in axes coordinates in the x + ax = plt.axes() + trans = mtransforms.blended_transform_factory( + ax.transAxes, mtransforms.Affine2D().scale(10) + ax.transData) + ax.plot([0.1, 1.2, 0.8], [35, -5, 18], transform=trans) + assert_array_equal(ax.dataLim.get_points(), + np.array([[np.inf, -50.], [-np.inf, 350.]])) + + def test_line_extents_affine(self): + ax = plt.axes() + offset = mtransforms.Affine2D().translate(10, 10) + plt.plot(np.arange(10), transform=offset + ax.transData) + expected_data_lim = np.array([[0., 0.], [9., 9.]]) + 10 + assert_array_almost_equal(ax.dataLim.get_points(), expected_data_lim) + + def test_line_extents_non_affine(self): + ax = plt.axes() + offset = mtransforms.Affine2D().translate(10, 10) + na_offset = NonAffineForTest(mtransforms.Affine2D().translate(10, 10)) + plt.plot(np.arange(10), transform=offset + na_offset + ax.transData) + expected_data_lim = np.array([[0., 0.], [9., 9.]]) + 20 + assert_array_almost_equal(ax.dataLim.get_points(), expected_data_lim) + + def test_pathc_extents_non_affine(self): + ax = plt.axes() + offset = mtransforms.Affine2D().translate(10, 10) + na_offset = NonAffineForTest(mtransforms.Affine2D().translate(10, 10)) + pth = Path([[0, 0], [0, 10], [10, 10], [10, 0]]) + patch = mpatches.PathPatch(pth, + transform=offset + na_offset + ax.transData) + ax.add_patch(patch) + expected_data_lim = np.array([[0., 0.], [10., 10.]]) + 20 + assert_array_almost_equal(ax.dataLim.get_points(), expected_data_lim) + + def test_pathc_extents_affine(self): + ax = plt.axes() + offset = mtransforms.Affine2D().translate(10, 10) + pth = Path([[0, 0], [0, 10], [10, 10], [10, 0]]) + patch = mpatches.PathPatch(pth, transform=offset + ax.transData) + ax.add_patch(patch) + expected_data_lim = np.array([[0., 0.], [10., 10.]]) + 10 + assert_array_almost_equal(ax.dataLim.get_points(), expected_data_lim) + + def test_line_extents_for_non_affine_transData(self): + ax = plt.axes(projection='polar') + # add 10 to the radius of the data + offset = mtransforms.Affine2D().translate(0, 10) + + plt.plot(np.arange(10), transform=offset + ax.transData) + # the data lim of a polar plot is stored in coordinates + # before a transData transformation, hence the data limits + # are not what is being shown on the actual plot. + expected_data_lim = np.array([[0., 0.], [9., 9.]]) + [0, 10] + assert_array_almost_equal(ax.dataLim.get_points(), expected_data_lim) + + +def assert_bbox_eq(bbox1, bbox2): + assert_array_equal(bbox1.bounds, bbox2.bounds) + + +def test_bbox_frozen_copies_minpos(): + bbox = mtransforms.Bbox.from_extents(0.0, 0.0, 1.0, 1.0, minpos=1.0) + frozen = bbox.frozen() + assert_array_equal(frozen.minpos, bbox.minpos) + + +def test_bbox_intersection(): + bbox_from_ext = mtransforms.Bbox.from_extents + inter = mtransforms.Bbox.intersection + + r1 = bbox_from_ext(0, 0, 1, 1) + r2 = bbox_from_ext(0.5, 0.5, 1.5, 1.5) + r3 = bbox_from_ext(0.5, 0, 0.75, 0.75) + r4 = bbox_from_ext(0.5, 1.5, 1, 2.5) + r5 = bbox_from_ext(1, 1, 2, 2) + + # self intersection -> no change + assert_bbox_eq(inter(r1, r1), r1) + # simple intersection + assert_bbox_eq(inter(r1, r2), bbox_from_ext(0.5, 0.5, 1, 1)) + # r3 contains r2 + assert_bbox_eq(inter(r1, r3), r3) + # no intersection + assert inter(r1, r4) is None + # single point + assert_bbox_eq(inter(r1, r5), bbox_from_ext(1, 1, 1, 1)) + + +def test_bbox_as_strings(): + b = mtransforms.Bbox([[.5, 0], [.75, .75]]) + assert_bbox_eq(b, eval(repr(b), {'Bbox': mtransforms.Bbox})) + asdict = eval(str(b), {'Bbox': dict}) + for k, v in asdict.items(): + assert getattr(b, k) == v + fmt = '.1f' + asdict = eval(format(b, fmt), {'Bbox': dict}) + for k, v in asdict.items(): + assert eval(format(getattr(b, k), fmt)) == v + + +def test_str_transform(): + # The str here should not be considered as "absolutely stable", and may be + # reformatted later; this is just a smoketest for __str__. + assert str(plt.subplot(projection="polar").transData) == """\ +CompositeGenericTransform( + CompositeGenericTransform( + CompositeGenericTransform( + TransformWrapper( + BlendedAffine2D( + IdentityTransform(), + IdentityTransform())), + CompositeAffine2D( + Affine2D().scale(1.0), + Affine2D().scale(1.0))), + PolarTransform( + PolarAxes(0.125,0.1;0.775x0.8), + use_rmin=True, + _apply_theta_transforms=False)), + CompositeGenericTransform( + CompositeGenericTransform( + PolarAffine( + TransformWrapper( + BlendedAffine2D( + IdentityTransform(), + IdentityTransform())), + LockableBbox( + Bbox(x0=0.0, y0=0.0, x1=6.283185307179586, y1=1.0), + [[-- --] + [-- --]])), + BboxTransformFrom( + _WedgeBbox( + (0.5, 0.5), + TransformedBbox( + Bbox(x0=0.0, y0=0.0, x1=6.283185307179586, y1=1.0), + CompositeAffine2D( + Affine2D().scale(1.0), + Affine2D().scale(1.0))), + LockableBbox( + Bbox(x0=0.0, y0=0.0, x1=6.283185307179586, y1=1.0), + [[-- --] + [-- --]])))), + BboxTransformTo( + TransformedBbox( + Bbox(x0=0.125, y0=0.09999999999999998, x1=0.9, y1=0.9), + BboxTransformTo( + TransformedBbox( + Bbox(x0=0.0, y0=0.0, x1=8.0, y1=6.0), + Affine2D().scale(80.0)))))))""" + + +def test_transform_single_point(): + t = mtransforms.Affine2D() + r = t.transform_affine((1, 1)) + assert r.shape == (2,) + + +def test_log_transform(): + # Tests that the last line runs without exception (previously the + # transform would fail if one of the axes was logarithmic). + fig, ax = plt.subplots() + ax.set_yscale('log') + ax.transData.transform((1, 1)) + + +def test_nan_overlap(): + a = mtransforms.Bbox([[0, 0], [1, 1]]) + b = mtransforms.Bbox([[0, 0], [1, np.nan]]) + assert not a.overlaps(b) + + +def test_transform_angles(): + t = mtransforms.Affine2D() # Identity transform + angles = np.array([20, 45, 60]) + points = np.array([[0, 0], [1, 1], [2, 2]]) + + # Identity transform does not change angles + new_angles = t.transform_angles(angles, points) + assert_array_almost_equal(angles, new_angles) + + # points missing a 2nd dimension + with pytest.raises(ValueError): + t.transform_angles(angles, points[0:2, 0:1]) + + # Number of angles != Number of points + with pytest.raises(ValueError): + t.transform_angles(angles, points[0:2, :]) + + +def test_nonsingular(): + # test for zero-expansion type cases; other cases may be added later + zero_expansion = np.array([-0.001, 0.001]) + cases = [(0, np.nan), (0, 0), (0, 7.9e-317)] + for args in cases: + out = np.array(mtransforms.nonsingular(*args)) + assert_array_equal(out, zero_expansion) + + +def test_invalid_arguments(): + t = mtransforms.Affine2D() + # There are two different exceptions, since the wrong number of + # dimensions is caught when constructing an array_view, and that + # raises a ValueError, and a wrong shape with a possible number + # of dimensions is caught by our CALL_CPP macro, which always + # raises the less precise RuntimeError. + with pytest.raises(ValueError): + t.transform(1) + with pytest.raises(ValueError): + t.transform([[[1]]]) + with pytest.raises(RuntimeError): + t.transform([]) + with pytest.raises(RuntimeError): + t.transform([1]) + with pytest.raises(RuntimeError): + t.transform([[1]]) + with pytest.raises(RuntimeError): + t.transform([[1, 2, 3]]) + + +def test_transformed_path(): + points = [(0, 0), (1, 0), (1, 1), (0, 1)] + path = Path(points, closed=True) + + trans = mtransforms.Affine2D() + trans_path = mtransforms.TransformedPath(path, trans) + assert_allclose(trans_path.get_fully_transformed_path().vertices, points) + + # Changing the transform should change the result. + r2 = 1 / np.sqrt(2) + trans.rotate(np.pi / 4) + assert_allclose(trans_path.get_fully_transformed_path().vertices, + [(0, 0), (r2, r2), (0, 2 * r2), (-r2, r2)], + atol=1e-15) + + # Changing the path does not change the result (it's cached). + path.points = [(0, 0)] * 4 + assert_allclose(trans_path.get_fully_transformed_path().vertices, + [(0, 0), (r2, r2), (0, 2 * r2), (-r2, r2)], + atol=1e-15) + + +def test_transformed_patch_path(): + trans = mtransforms.Affine2D() + patch = mpatches.Wedge((0, 0), 1, 45, 135, transform=trans) + + tpatch = mtransforms.TransformedPatchPath(patch) + points = tpatch.get_fully_transformed_path().vertices + + # Changing the transform should change the result. + trans.scale(2) + assert_allclose(tpatch.get_fully_transformed_path().vertices, points * 2) + + # Changing the path should change the result (and cancel out the scaling + # from the transform). + patch.set_radius(0.5) + assert_allclose(tpatch.get_fully_transformed_path().vertices, points) + + +@pytest.mark.parametrize('locked_element', ['x0', 'y0', 'x1', 'y1']) +def test_lockable_bbox(locked_element): + other_elements = ['x0', 'y0', 'x1', 'y1'] + other_elements.remove(locked_element) + + orig = mtransforms.Bbox.unit() + locked = mtransforms.LockableBbox(orig, **{locked_element: 2}) + + # LockableBbox should keep its locked element as specified in __init__. + assert getattr(locked, locked_element) == 2 + assert getattr(locked, 'locked_' + locked_element) == 2 + for elem in other_elements: + assert getattr(locked, elem) == getattr(orig, elem) + + # Changing underlying Bbox should update everything but locked element. + orig.set_points(orig.get_points() + 10) + assert getattr(locked, locked_element) == 2 + assert getattr(locked, 'locked_' + locked_element) == 2 + for elem in other_elements: + assert getattr(locked, elem) == getattr(orig, elem) + + # Unlocking element should revert values back to the underlying Bbox. + setattr(locked, 'locked_' + locked_element, None) + assert getattr(locked, 'locked_' + locked_element) is None + assert np.all(orig.get_points() == locked.get_points()) + + # Relocking an element should change its value, but not others. + setattr(locked, 'locked_' + locked_element, 3) + assert getattr(locked, locked_element) == 3 + assert getattr(locked, 'locked_' + locked_element) == 3 + for elem in other_elements: + assert getattr(locked, elem) == getattr(orig, elem) + + +def test_copy(): + a = mtransforms.Affine2D() + b = mtransforms.Affine2D() + s = a + b + # Updating a dependee should invalidate a copy of the dependent. + s.get_matrix() # resolve it. + s1 = copy.copy(s) + assert not s._invalid and not s1._invalid + a.translate(1, 2) + assert s._invalid and s1._invalid + assert (s1.get_matrix() == a.get_matrix()).all() + # Updating a copy of a dependee shouldn't invalidate a dependent. + s.get_matrix() # resolve it. + b1 = copy.copy(b) + b1.translate(3, 4) + assert not s._invalid + assert (s.get_matrix() == a.get_matrix()).all() + + +def test_deepcopy(): + a = mtransforms.Affine2D() + b = mtransforms.Affine2D() + s = a + b + # Updating a dependee shouldn't invalidate a deepcopy of the dependent. + s.get_matrix() # resolve it. + s1 = copy.deepcopy(s) + assert not s._invalid and not s1._invalid + a.translate(1, 2) + assert s._invalid and not s1._invalid + assert (s1.get_matrix() == mtransforms.Affine2D().get_matrix()).all() + # Updating a deepcopy of a dependee shouldn't invalidate a dependent. + s.get_matrix() # resolve it. + b1 = copy.deepcopy(b) + b1.translate(3, 4) + assert not s._invalid + assert (s.get_matrix() == a.get_matrix()).all() + + +def test_transformwrapper(): + t = mtransforms.TransformWrapper(mtransforms.Affine2D()) + with pytest.raises(ValueError, match=( + r"The input and output dims of the new child \(1, 1\) " + r"do not match those of current child \(2, 2\)")): + t.set(scale.LogTransform(10)) + + +@check_figures_equal(extensions=["png"]) +def test_scale_swapping(fig_test, fig_ref): + np.random.seed(19680801) + samples = np.random.normal(size=10) + x = np.linspace(-5, 5, 10) + + for fig, log_state in zip([fig_test, fig_ref], [True, False]): + ax = fig.subplots() + ax.hist(samples, log=log_state, density=True) + ax.plot(x, np.exp(-(x**2) / 2) / np.sqrt(2 * np.pi)) + fig.canvas.draw() + ax.set_yscale('linear') + + +def test_offset_copy_errors(): + with pytest.raises(ValueError, + match="'fontsize' is not a valid value for units;" + " supported values are 'dots', 'points', 'inches'"): + mtransforms.offset_copy(None, units='fontsize') + + with pytest.raises(ValueError, + match='For units of inches or points a fig kwarg is needed'): + mtransforms.offset_copy(None, units='inches') + + +def test_transformedbbox_contains(): + bb = TransformedBbox(Bbox.unit(), Affine2D().rotate_deg(30)) + assert bb.contains(.8, .5) + assert bb.contains(-.4, .85) + assert not bb.contains(.9, .5) + bb = TransformedBbox(Bbox.unit(), Affine2D().translate(.25, .5)) + assert bb.contains(1.25, 1.5) + assert not bb.fully_contains(1.25, 1.5) + assert not bb.fully_contains(.1, .1) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_triangulation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_triangulation.py new file mode 100644 index 00000000..14c591ab --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_triangulation.py @@ -0,0 +1,1403 @@ +import numpy as np +from numpy.testing import ( + assert_array_equal, assert_array_almost_equal, assert_array_less) +import numpy.ma.testutils as matest +import pytest + +import matplotlib as mpl +import matplotlib.pyplot as plt +import matplotlib.tri as mtri +from matplotlib.path import Path +from matplotlib.testing.decorators import image_comparison, check_figures_equal + + +class TestTriangulationParams: + x = [-1, 0, 1, 0] + y = [0, -1, 0, 1] + triangles = [[0, 1, 2], [0, 2, 3]] + mask = [False, True] + + @pytest.mark.parametrize('args, kwargs, expected', [ + ([x, y], {}, [x, y, None, None]), + ([x, y, triangles], {}, [x, y, triangles, None]), + ([x, y], dict(triangles=triangles), [x, y, triangles, None]), + ([x, y], dict(mask=mask), [x, y, None, mask]), + ([x, y, triangles], dict(mask=mask), [x, y, triangles, mask]), + ([x, y], dict(triangles=triangles, mask=mask), [x, y, triangles, mask]) + ]) + def test_extract_triangulation_params(self, args, kwargs, expected): + other_args = [1, 2] + other_kwargs = {'a': 3, 'b': '4'} + x_, y_, triangles_, mask_, args_, kwargs_ = \ + mtri.Triangulation._extract_triangulation_params( + args + other_args, {**kwargs, **other_kwargs}) + x, y, triangles, mask = expected + assert x_ is x + assert y_ is y + assert_array_equal(triangles_, triangles) + assert mask_ is mask + assert args_ == other_args + assert kwargs_ == other_kwargs + + +def test_extract_triangulation_positional_mask(): + # mask cannot be passed positionally + mask = [True] + args = [[0, 2, 1], [0, 0, 1], [[0, 1, 2]], mask] + x_, y_, triangles_, mask_, args_, kwargs_ = \ + mtri.Triangulation._extract_triangulation_params(args, {}) + assert mask_ is None + assert args_ == [mask] + # the positional mask must be caught downstream because this must pass + # unknown args through + + +def test_triangulation_init(): + x = [-1, 0, 1, 0] + y = [0, -1, 0, 1] + with pytest.raises(ValueError, match="x and y must be equal-length"): + mtri.Triangulation(x, [1, 2]) + with pytest.raises( + ValueError, + match=r"triangles must be a \(N, 3\) int array, but found shape " + r"\(3,\)"): + mtri.Triangulation(x, y, [0, 1, 2]) + with pytest.raises( + ValueError, + match=r"triangles must be a \(N, 3\) int array, not 'other'"): + mtri.Triangulation(x, y, 'other') + with pytest.raises(ValueError, match="found value 99"): + mtri.Triangulation(x, y, [[0, 1, 99]]) + with pytest.raises(ValueError, match="found value -1"): + mtri.Triangulation(x, y, [[0, 1, -1]]) + + +def test_triangulation_set_mask(): + x = [-1, 0, 1, 0] + y = [0, -1, 0, 1] + triangles = [[0, 1, 2], [2, 3, 0]] + triang = mtri.Triangulation(x, y, triangles) + + # Check neighbors, which forces creation of C++ triangulation + assert_array_equal(triang.neighbors, [[-1, -1, 1], [-1, -1, 0]]) + + # Set mask + triang.set_mask([False, True]) + assert_array_equal(triang.mask, [False, True]) + + # Reset mask + triang.set_mask(None) + assert triang.mask is None + + msg = r"mask array must have same length as triangles array" + for mask in ([False, True, False], [False], [True], False, True): + with pytest.raises(ValueError, match=msg): + triang.set_mask(mask) + + +def test_delaunay(): + # No duplicate points, regular grid. + nx = 5 + ny = 4 + x, y = np.meshgrid(np.linspace(0.0, 1.0, nx), np.linspace(0.0, 1.0, ny)) + x = x.ravel() + y = y.ravel() + npoints = nx*ny + ntriangles = 2 * (nx-1) * (ny-1) + nedges = 3*nx*ny - 2*nx - 2*ny + 1 + + # Create delaunay triangulation. + triang = mtri.Triangulation(x, y) + + # The tests in the remainder of this function should be passed by any + # triangulation that does not contain duplicate points. + + # Points - floating point. + assert_array_almost_equal(triang.x, x) + assert_array_almost_equal(triang.y, y) + + # Triangles - integers. + assert len(triang.triangles) == ntriangles + assert np.min(triang.triangles) == 0 + assert np.max(triang.triangles) == npoints-1 + + # Edges - integers. + assert len(triang.edges) == nedges + assert np.min(triang.edges) == 0 + assert np.max(triang.edges) == npoints-1 + + # Neighbors - integers. + # Check that neighbors calculated by C++ triangulation class are the same + # as those returned from delaunay routine. + neighbors = triang.neighbors + triang._neighbors = None + assert_array_equal(triang.neighbors, neighbors) + + # Is each point used in at least one triangle? + assert_array_equal(np.unique(triang.triangles), np.arange(npoints)) + + +def test_delaunay_duplicate_points(): + npoints = 10 + duplicate = 7 + duplicate_of = 3 + + np.random.seed(23) + x = np.random.random(npoints) + y = np.random.random(npoints) + x[duplicate] = x[duplicate_of] + y[duplicate] = y[duplicate_of] + + # Create delaunay triangulation. + triang = mtri.Triangulation(x, y) + + # Duplicate points should be ignored, so the index of the duplicate points + # should not appear in any triangle. + assert_array_equal(np.unique(triang.triangles), + np.delete(np.arange(npoints), duplicate)) + + +def test_delaunay_points_in_line(): + # Cannot triangulate points that are all in a straight line, but check + # that delaunay code fails gracefully. + x = np.linspace(0.0, 10.0, 11) + y = np.linspace(0.0, 10.0, 11) + with pytest.raises(RuntimeError): + mtri.Triangulation(x, y) + + # Add an extra point not on the line and the triangulation is OK. + x = np.append(x, 2.0) + y = np.append(y, 8.0) + mtri.Triangulation(x, y) + + +@pytest.mark.parametrize('x, y', [ + # Triangulation should raise a ValueError if passed less than 3 points. + ([], []), + ([1], [5]), + ([1, 2], [5, 6]), + # Triangulation should also raise a ValueError if passed duplicate points + # such that there are less than 3 unique points. + ([1, 2, 1], [5, 6, 5]), + ([1, 2, 2], [5, 6, 6]), + ([1, 1, 1, 2, 1, 2], [5, 5, 5, 6, 5, 6]), +]) +def test_delaunay_insufficient_points(x, y): + with pytest.raises(ValueError): + mtri.Triangulation(x, y) + + +def test_delaunay_robust(): + # Fails when mtri.Triangulation uses matplotlib.delaunay, works when using + # qhull. + tri_points = np.array([ + [0.8660254037844384, -0.5000000000000004], + [0.7577722283113836, -0.5000000000000004], + [0.6495190528383288, -0.5000000000000003], + [0.5412658773652739, -0.5000000000000003], + [0.811898816047911, -0.40625000000000044], + [0.7036456405748561, -0.4062500000000004], + [0.5953924651018013, -0.40625000000000033]]) + test_points = np.asarray([ + [0.58, -0.46], + [0.65, -0.46], + [0.65, -0.42], + [0.7, -0.48], + [0.7, -0.44], + [0.75, -0.44], + [0.8, -0.48]]) + + # Utility function that indicates if a triangle defined by 3 points + # (xtri, ytri) contains the test point xy. Avoid calling with a point that + # lies on or very near to an edge of the triangle. + def tri_contains_point(xtri, ytri, xy): + tri_points = np.vstack((xtri, ytri)).T + return Path(tri_points).contains_point(xy) + + # Utility function that returns how many triangles of the specified + # triangulation contain the test point xy. Avoid calling with a point that + # lies on or very near to an edge of any triangle in the triangulation. + def tris_contain_point(triang, xy): + return sum(tri_contains_point(triang.x[tri], triang.y[tri], xy) + for tri in triang.triangles) + + # Using matplotlib.delaunay, an invalid triangulation is created with + # overlapping triangles; qhull is OK. + triang = mtri.Triangulation(tri_points[:, 0], tri_points[:, 1]) + for test_point in test_points: + assert tris_contain_point(triang, test_point) == 1 + + # If ignore the first point of tri_points, matplotlib.delaunay throws a + # KeyError when calculating the convex hull; qhull is OK. + triang = mtri.Triangulation(tri_points[1:, 0], tri_points[1:, 1]) + + +@image_comparison(['tripcolor1.png']) +def test_tripcolor(): + x = np.asarray([0, 0.5, 1, 0, 0.5, 1, 0, 0.5, 1, 0.75]) + y = np.asarray([0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1, 0.75]) + triangles = np.asarray([ + [0, 1, 3], [1, 4, 3], + [1, 2, 4], [2, 5, 4], + [3, 4, 6], [4, 7, 6], + [4, 5, 9], [7, 4, 9], [8, 7, 9], [5, 8, 9]]) + + # Triangulation with same number of points and triangles. + triang = mtri.Triangulation(x, y, triangles) + + Cpoints = x + 0.5*y + + xmid = x[triang.triangles].mean(axis=1) + ymid = y[triang.triangles].mean(axis=1) + Cfaces = 0.5*xmid + ymid + + plt.subplot(121) + plt.tripcolor(triang, Cpoints, edgecolors='k') + plt.title('point colors') + + plt.subplot(122) + plt.tripcolor(triang, facecolors=Cfaces, edgecolors='k') + plt.title('facecolors') + + +def test_tripcolor_color(): + x = [-1, 0, 1, 0] + y = [0, -1, 0, 1] + fig, ax = plt.subplots() + with pytest.raises(TypeError, match=r"tripcolor\(\) missing 1 required "): + ax.tripcolor(x, y) + with pytest.raises(ValueError, match="The length of c must match either"): + ax.tripcolor(x, y, [1, 2, 3]) + with pytest.raises(ValueError, + match="length of facecolors must match .* triangles"): + ax.tripcolor(x, y, facecolors=[1, 2, 3, 4]) + with pytest.raises(ValueError, + match="'gouraud' .* at the points.* not at the faces"): + ax.tripcolor(x, y, facecolors=[1, 2], shading='gouraud') + with pytest.raises(ValueError, + match="'gouraud' .* at the points.* not at the faces"): + ax.tripcolor(x, y, [1, 2], shading='gouraud') # faces + with pytest.raises(TypeError, + match="positional.*'c'.*keyword-only.*'facecolors'"): + ax.tripcolor(x, y, C=[1, 2, 3, 4]) + with pytest.raises(TypeError, match="Unexpected positional parameter"): + ax.tripcolor(x, y, [1, 2], 'unused_positional') + + # smoke test for valid color specifications (via C or facecolors) + ax.tripcolor(x, y, [1, 2, 3, 4]) # edges + ax.tripcolor(x, y, [1, 2, 3, 4], shading='gouraud') # edges + ax.tripcolor(x, y, [1, 2]) # faces + ax.tripcolor(x, y, facecolors=[1, 2]) # faces + + +def test_tripcolor_clim(): + np.random.seed(19680801) + a, b, c = np.random.rand(10), np.random.rand(10), np.random.rand(10) + + ax = plt.figure().add_subplot() + clim = (0.25, 0.75) + norm = ax.tripcolor(a, b, c, clim=clim).norm + assert (norm.vmin, norm.vmax) == clim + + +def test_tripcolor_warnings(): + x = [-1, 0, 1, 0] + y = [0, -1, 0, 1] + c = [0.4, 0.5] + fig, ax = plt.subplots() + # facecolors takes precedence over c + with pytest.warns(UserWarning, match="Positional parameter c .*no effect"): + ax.tripcolor(x, y, c, facecolors=c) + with pytest.warns(UserWarning, match="Positional parameter c .*no effect"): + ax.tripcolor(x, y, 'interpreted as c', facecolors=c) + + +def test_no_modify(): + # Test that Triangulation does not modify triangles array passed to it. + triangles = np.array([[3, 2, 0], [3, 1, 0]], dtype=np.int32) + points = np.array([(0, 0), (0, 1.1), (1, 0), (1, 1)]) + + old_triangles = triangles.copy() + mtri.Triangulation(points[:, 0], points[:, 1], triangles).edges + assert_array_equal(old_triangles, triangles) + + +def test_trifinder(): + # Test points within triangles of masked triangulation. + x, y = np.meshgrid(np.arange(4), np.arange(4)) + x = x.ravel() + y = y.ravel() + triangles = [[0, 1, 4], [1, 5, 4], [1, 2, 5], [2, 6, 5], [2, 3, 6], + [3, 7, 6], [4, 5, 8], [5, 9, 8], [5, 6, 9], [6, 10, 9], + [6, 7, 10], [7, 11, 10], [8, 9, 12], [9, 13, 12], [9, 10, 13], + [10, 14, 13], [10, 11, 14], [11, 15, 14]] + mask = np.zeros(len(triangles)) + mask[8:10] = 1 + triang = mtri.Triangulation(x, y, triangles, mask) + trifinder = triang.get_trifinder() + + xs = [0.25, 1.25, 2.25, 3.25] + ys = [0.25, 1.25, 2.25, 3.25] + xs, ys = np.meshgrid(xs, ys) + xs = xs.ravel() + ys = ys.ravel() + tris = trifinder(xs, ys) + assert_array_equal(tris, [0, 2, 4, -1, 6, -1, 10, -1, + 12, 14, 16, -1, -1, -1, -1, -1]) + tris = trifinder(xs-0.5, ys-0.5) + assert_array_equal(tris, [-1, -1, -1, -1, -1, 1, 3, 5, + -1, 7, -1, 11, -1, 13, 15, 17]) + + # Test points exactly on boundary edges of masked triangulation. + xs = [0.5, 1.5, 2.5, 0.5, 1.5, 2.5, 1.5, 1.5, 0.0, 1.0, 2.0, 3.0] + ys = [0.0, 0.0, 0.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5, 1.5, 1.5, 1.5] + tris = trifinder(xs, ys) + assert_array_equal(tris, [0, 2, 4, 13, 15, 17, 3, 14, 6, 7, 10, 11]) + + # Test points exactly on boundary corners of masked triangulation. + xs = [0.0, 3.0] + ys = [0.0, 3.0] + tris = trifinder(xs, ys) + assert_array_equal(tris, [0, 17]) + + # + # Test triangles with horizontal colinear points. These are not valid + # triangulations, but we try to deal with the simplest violations. + # + + # If +ve, triangulation is OK, if -ve triangulation invalid, + # if zero have colinear points but should pass tests anyway. + delta = 0.0 + + x = [1.5, 0, 1, 2, 3, 1.5, 1.5] + y = [-1, 0, 0, 0, 0, delta, 1] + triangles = [[0, 2, 1], [0, 3, 2], [0, 4, 3], [1, 2, 5], [2, 3, 5], + [3, 4, 5], [1, 5, 6], [4, 6, 5]] + triang = mtri.Triangulation(x, y, triangles) + trifinder = triang.get_trifinder() + + xs = [-0.1, 0.4, 0.9, 1.4, 1.9, 2.4, 2.9] + ys = [-0.1, 0.1] + xs, ys = np.meshgrid(xs, ys) + tris = trifinder(xs, ys) + assert_array_equal(tris, [[-1, 0, 0, 1, 1, 2, -1], + [-1, 6, 6, 6, 7, 7, -1]]) + + # + # Test triangles with vertical colinear points. These are not valid + # triangulations, but we try to deal with the simplest violations. + # + + # If +ve, triangulation is OK, if -ve triangulation invalid, + # if zero have colinear points but should pass tests anyway. + delta = 0.0 + + x = [-1, -delta, 0, 0, 0, 0, 1] + y = [1.5, 1.5, 0, 1, 2, 3, 1.5] + triangles = [[0, 1, 2], [0, 1, 5], [1, 2, 3], [1, 3, 4], [1, 4, 5], + [2, 6, 3], [3, 6, 4], [4, 6, 5]] + triang = mtri.Triangulation(x, y, triangles) + trifinder = triang.get_trifinder() + + xs = [-0.1, 0.1] + ys = [-0.1, 0.4, 0.9, 1.4, 1.9, 2.4, 2.9] + xs, ys = np.meshgrid(xs, ys) + tris = trifinder(xs, ys) + assert_array_equal(tris, [[-1, -1], [0, 5], [0, 5], [0, 6], [1, 6], [1, 7], + [-1, -1]]) + + # Test that changing triangulation by setting a mask causes the trifinder + # to be reinitialised. + x = [0, 1, 0, 1] + y = [0, 0, 1, 1] + triangles = [[0, 1, 2], [1, 3, 2]] + triang = mtri.Triangulation(x, y, triangles) + trifinder = triang.get_trifinder() + + xs = [-0.2, 0.2, 0.8, 1.2] + ys = [0.5, 0.5, 0.5, 0.5] + tris = trifinder(xs, ys) + assert_array_equal(tris, [-1, 0, 1, -1]) + + triang.set_mask([1, 0]) + assert trifinder == triang.get_trifinder() + tris = trifinder(xs, ys) + assert_array_equal(tris, [-1, -1, 1, -1]) + + +def test_triinterp(): + # Test points within triangles of masked triangulation. + x, y = np.meshgrid(np.arange(4), np.arange(4)) + x = x.ravel() + y = y.ravel() + z = 1.23*x - 4.79*y + triangles = [[0, 1, 4], [1, 5, 4], [1, 2, 5], [2, 6, 5], [2, 3, 6], + [3, 7, 6], [4, 5, 8], [5, 9, 8], [5, 6, 9], [6, 10, 9], + [6, 7, 10], [7, 11, 10], [8, 9, 12], [9, 13, 12], [9, 10, 13], + [10, 14, 13], [10, 11, 14], [11, 15, 14]] + mask = np.zeros(len(triangles)) + mask[8:10] = 1 + triang = mtri.Triangulation(x, y, triangles, mask) + linear_interp = mtri.LinearTriInterpolator(triang, z) + cubic_min_E = mtri.CubicTriInterpolator(triang, z) + cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') + + xs = np.linspace(0.25, 2.75, 6) + ys = [0.25, 0.75, 2.25, 2.75] + xs, ys = np.meshgrid(xs, ys) # Testing arrays with array.ndim = 2 + for interp in (linear_interp, cubic_min_E, cubic_geom): + zs = interp(xs, ys) + assert_array_almost_equal(zs, (1.23*xs - 4.79*ys)) + + # Test points outside triangulation. + xs = [-0.25, 1.25, 1.75, 3.25] + ys = xs + xs, ys = np.meshgrid(xs, ys) + for interp in (linear_interp, cubic_min_E, cubic_geom): + zs = linear_interp(xs, ys) + assert_array_equal(zs.mask, [[True]*4]*4) + + # Test mixed configuration (outside / inside). + xs = np.linspace(0.25, 1.75, 6) + ys = [0.25, 0.75, 1.25, 1.75] + xs, ys = np.meshgrid(xs, ys) + for interp in (linear_interp, cubic_min_E, cubic_geom): + zs = interp(xs, ys) + matest.assert_array_almost_equal(zs, (1.23*xs - 4.79*ys)) + mask = (xs >= 1) * (xs <= 2) * (ys >= 1) * (ys <= 2) + assert_array_equal(zs.mask, mask) + + # 2nd order patch test: on a grid with an 'arbitrary shaped' triangle, + # patch test shall be exact for quadratic functions and cubic + # interpolator if *kind* = user + (a, b, c) = (1.23, -4.79, 0.6) + + def quad(x, y): + return a*(x-0.5)**2 + b*(y-0.5)**2 + c*x*y + + def gradient_quad(x, y): + return (2*a*(x-0.5) + c*y, 2*b*(y-0.5) + c*x) + + x = np.array([0.2, 0.33367, 0.669, 0., 1., 1., 0.]) + y = np.array([0.3, 0.80755, 0.4335, 0., 0., 1., 1.]) + triangles = np.array([[0, 1, 2], [3, 0, 4], [4, 0, 2], [4, 2, 5], + [1, 5, 2], [6, 5, 1], [6, 1, 0], [6, 0, 3]]) + triang = mtri.Triangulation(x, y, triangles) + z = quad(x, y) + dz = gradient_quad(x, y) + # test points for 2nd order patch test + xs = np.linspace(0., 1., 5) + ys = np.linspace(0., 1., 5) + xs, ys = np.meshgrid(xs, ys) + cubic_user = mtri.CubicTriInterpolator(triang, z, kind='user', dz=dz) + interp_zs = cubic_user(xs, ys) + assert_array_almost_equal(interp_zs, quad(xs, ys)) + (interp_dzsdx, interp_dzsdy) = cubic_user.gradient(x, y) + (dzsdx, dzsdy) = gradient_quad(x, y) + assert_array_almost_equal(interp_dzsdx, dzsdx) + assert_array_almost_equal(interp_dzsdy, dzsdy) + + # Cubic improvement: cubic interpolation shall perform better than linear + # on a sufficiently dense mesh for a quadratic function. + n = 11 + x, y = np.meshgrid(np.linspace(0., 1., n+1), np.linspace(0., 1., n+1)) + x = x.ravel() + y = y.ravel() + z = quad(x, y) + triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n+1)) + xs, ys = np.meshgrid(np.linspace(0.1, 0.9, 5), np.linspace(0.1, 0.9, 5)) + xs = xs.ravel() + ys = ys.ravel() + linear_interp = mtri.LinearTriInterpolator(triang, z) + cubic_min_E = mtri.CubicTriInterpolator(triang, z) + cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') + zs = quad(xs, ys) + diff_lin = np.abs(linear_interp(xs, ys) - zs) + for interp in (cubic_min_E, cubic_geom): + diff_cubic = np.abs(interp(xs, ys) - zs) + assert np.max(diff_lin) >= 10 * np.max(diff_cubic) + assert (np.dot(diff_lin, diff_lin) >= + 100 * np.dot(diff_cubic, diff_cubic)) + + +def test_triinterpcubic_C1_continuity(): + # Below the 4 tests which demonstrate C1 continuity of the + # TriCubicInterpolator (testing the cubic shape functions on arbitrary + # triangle): + # + # 1) Testing continuity of function & derivatives at corner for all 9 + # shape functions. Testing also function values at same location. + # 2) Testing C1 continuity along each edge (as gradient is polynomial of + # 2nd order, it is sufficient to test at the middle). + # 3) Testing C1 continuity at triangle barycenter (where the 3 subtriangles + # meet) + # 4) Testing C1 continuity at median 1/3 points (midside between 2 + # subtriangles) + + # Utility test function check_continuity + def check_continuity(interpolator, loc, values=None): + """ + Checks the continuity of interpolator (and its derivatives) near + location loc. Can check the value at loc itself if *values* is + provided. + + *interpolator* TriInterpolator + *loc* location to test (x0, y0) + *values* (optional) array [z0, dzx0, dzy0] to check the value at *loc* + """ + n_star = 24 # Number of continuity points in a boundary of loc + epsilon = 1.e-10 # Distance for loc boundary + k = 100. # Continuity coefficient + (loc_x, loc_y) = loc + star_x = loc_x + epsilon*np.cos(np.linspace(0., 2*np.pi, n_star)) + star_y = loc_y + epsilon*np.sin(np.linspace(0., 2*np.pi, n_star)) + z = interpolator([loc_x], [loc_y])[0] + (dzx, dzy) = interpolator.gradient([loc_x], [loc_y]) + if values is not None: + assert_array_almost_equal(z, values[0]) + assert_array_almost_equal(dzx[0], values[1]) + assert_array_almost_equal(dzy[0], values[2]) + diff_z = interpolator(star_x, star_y) - z + (tab_dzx, tab_dzy) = interpolator.gradient(star_x, star_y) + diff_dzx = tab_dzx - dzx + diff_dzy = tab_dzy - dzy + assert_array_less(diff_z, epsilon*k) + assert_array_less(diff_dzx, epsilon*k) + assert_array_less(diff_dzy, epsilon*k) + + # Drawing arbitrary triangle (a, b, c) inside a unit square. + (ax, ay) = (0.2, 0.3) + (bx, by) = (0.33367, 0.80755) + (cx, cy) = (0.669, 0.4335) + x = np.array([ax, bx, cx, 0., 1., 1., 0.]) + y = np.array([ay, by, cy, 0., 0., 1., 1.]) + triangles = np.array([[0, 1, 2], [3, 0, 4], [4, 0, 2], [4, 2, 5], + [1, 5, 2], [6, 5, 1], [6, 1, 0], [6, 0, 3]]) + triang = mtri.Triangulation(x, y, triangles) + + for idof in range(9): + z = np.zeros(7, dtype=np.float64) + dzx = np.zeros(7, dtype=np.float64) + dzy = np.zeros(7, dtype=np.float64) + values = np.zeros([3, 3], dtype=np.float64) + case = idof//3 + values[case, idof % 3] = 1.0 + if case == 0: + z[idof] = 1.0 + elif case == 1: + dzx[idof % 3] = 1.0 + elif case == 2: + dzy[idof % 3] = 1.0 + interp = mtri.CubicTriInterpolator(triang, z, kind='user', + dz=(dzx, dzy)) + # Test 1) Checking values and continuity at nodes + check_continuity(interp, (ax, ay), values[:, 0]) + check_continuity(interp, (bx, by), values[:, 1]) + check_continuity(interp, (cx, cy), values[:, 2]) + # Test 2) Checking continuity at midside nodes + check_continuity(interp, ((ax+bx)*0.5, (ay+by)*0.5)) + check_continuity(interp, ((ax+cx)*0.5, (ay+cy)*0.5)) + check_continuity(interp, ((cx+bx)*0.5, (cy+by)*0.5)) + # Test 3) Checking continuity at barycenter + check_continuity(interp, ((ax+bx+cx)/3., (ay+by+cy)/3.)) + # Test 4) Checking continuity at median 1/3-point + check_continuity(interp, ((4.*ax+bx+cx)/6., (4.*ay+by+cy)/6.)) + check_continuity(interp, ((ax+4.*bx+cx)/6., (ay+4.*by+cy)/6.)) + check_continuity(interp, ((ax+bx+4.*cx)/6., (ay+by+4.*cy)/6.)) + + +def test_triinterpcubic_cg_solver(): + # Now 3 basic tests of the Sparse CG solver, used for + # TriCubicInterpolator with *kind* = 'min_E' + # 1) A commonly used test involves a 2d Poisson matrix. + def poisson_sparse_matrix(n, m): + """ + Return the sparse, (n*m, n*m) matrix in coo format resulting from the + discretisation of the 2-dimensional Poisson equation according to a + finite difference numerical scheme on a uniform (n, m) grid. + """ + l = m*n + rows = np.concatenate([ + np.arange(l, dtype=np.int32), + np.arange(l-1, dtype=np.int32), np.arange(1, l, dtype=np.int32), + np.arange(l-n, dtype=np.int32), np.arange(n, l, dtype=np.int32)]) + cols = np.concatenate([ + np.arange(l, dtype=np.int32), + np.arange(1, l, dtype=np.int32), np.arange(l-1, dtype=np.int32), + np.arange(n, l, dtype=np.int32), np.arange(l-n, dtype=np.int32)]) + vals = np.concatenate([ + 4*np.ones(l, dtype=np.float64), + -np.ones(l-1, dtype=np.float64), -np.ones(l-1, dtype=np.float64), + -np.ones(l-n, dtype=np.float64), -np.ones(l-n, dtype=np.float64)]) + # In fact +1 and -1 diags have some zeros + vals[l:2*l-1][m-1::m] = 0. + vals[2*l-1:3*l-2][m-1::m] = 0. + return vals, rows, cols, (n*m, n*m) + + # Instantiating a sparse Poisson matrix of size 48 x 48: + (n, m) = (12, 4) + mat = mtri._triinterpolate._Sparse_Matrix_coo(*poisson_sparse_matrix(n, m)) + mat.compress_csc() + mat_dense = mat.to_dense() + # Testing a sparse solve for all 48 basis vector + for itest in range(n*m): + b = np.zeros(n*m, dtype=np.float64) + b[itest] = 1. + x, _ = mtri._triinterpolate._cg(A=mat, b=b, x0=np.zeros(n*m), + tol=1.e-10) + assert_array_almost_equal(np.dot(mat_dense, x), b) + + # 2) Same matrix with inserting 2 rows - cols with null diag terms + # (but still linked with the rest of the matrix by extra-diag terms) + (i_zero, j_zero) = (12, 49) + vals, rows, cols, _ = poisson_sparse_matrix(n, m) + rows = rows + 1*(rows >= i_zero) + 1*(rows >= j_zero) + cols = cols + 1*(cols >= i_zero) + 1*(cols >= j_zero) + # adding extra-diag terms + rows = np.concatenate([rows, [i_zero, i_zero-1, j_zero, j_zero-1]]) + cols = np.concatenate([cols, [i_zero-1, i_zero, j_zero-1, j_zero]]) + vals = np.concatenate([vals, [1., 1., 1., 1.]]) + mat = mtri._triinterpolate._Sparse_Matrix_coo(vals, rows, cols, + (n*m + 2, n*m + 2)) + mat.compress_csc() + mat_dense = mat.to_dense() + # Testing a sparse solve for all 50 basis vec + for itest in range(n*m + 2): + b = np.zeros(n*m + 2, dtype=np.float64) + b[itest] = 1. + x, _ = mtri._triinterpolate._cg(A=mat, b=b, x0=np.ones(n * m + 2), + tol=1.e-10) + assert_array_almost_equal(np.dot(mat_dense, x), b) + + # 3) Now a simple test that summation of duplicate (i.e. with same rows, + # same cols) entries occurs when compressed. + vals = np.ones(17, dtype=np.float64) + rows = np.array([0, 1, 2, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1], + dtype=np.int32) + cols = np.array([0, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], + dtype=np.int32) + dim = (3, 3) + mat = mtri._triinterpolate._Sparse_Matrix_coo(vals, rows, cols, dim) + mat.compress_csc() + mat_dense = mat.to_dense() + assert_array_almost_equal(mat_dense, np.array([ + [1., 2., 0.], [2., 1., 5.], [0., 5., 1.]], dtype=np.float64)) + + +def test_triinterpcubic_geom_weights(): + # Tests to check computation of weights for _DOF_estimator_geom: + # The weight sum per triangle can be 1. (in case all angles < 90 degrees) + # or (2*w_i) where w_i = 1-alpha_i/np.pi is the weight of apex i; alpha_i + # is the apex angle > 90 degrees. + (ax, ay) = (0., 1.687) + x = np.array([ax, 0.5*ax, 0., 1.]) + y = np.array([ay, -ay, 0., 0.]) + z = np.zeros(4, dtype=np.float64) + triangles = [[0, 2, 3], [1, 3, 2]] + sum_w = np.zeros([4, 2]) # 4 possibilities; 2 triangles + for theta in np.linspace(0., 2*np.pi, 14): # rotating the figure... + x_rot = np.cos(theta)*x + np.sin(theta)*y + y_rot = -np.sin(theta)*x + np.cos(theta)*y + triang = mtri.Triangulation(x_rot, y_rot, triangles) + cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') + dof_estimator = mtri._triinterpolate._DOF_estimator_geom(cubic_geom) + weights = dof_estimator.compute_geom_weights() + # Testing for the 4 possibilities... + sum_w[0, :] = np.sum(weights, 1) - 1 + for itri in range(3): + sum_w[itri+1, :] = np.sum(weights, 1) - 2*weights[:, itri] + assert_array_almost_equal(np.min(np.abs(sum_w), axis=0), + np.array([0., 0.], dtype=np.float64)) + + +def test_triinterp_colinear(): + # Tests interpolating inside a triangulation with horizontal colinear + # points (refer also to the tests :func:`test_trifinder` ). + # + # These are not valid triangulations, but we try to deal with the + # simplest violations (i. e. those handled by default TriFinder). + # + # Note that the LinearTriInterpolator and the CubicTriInterpolator with + # kind='min_E' or 'geom' still pass a linear patch test. + # We also test interpolation inside a flat triangle, by forcing + # *tri_index* in a call to :meth:`_interpolate_multikeys`. + + # If +ve, triangulation is OK, if -ve triangulation invalid, + # if zero have colinear points but should pass tests anyway. + delta = 0. + + x0 = np.array([1.5, 0, 1, 2, 3, 1.5, 1.5]) + y0 = np.array([-1, 0, 0, 0, 0, delta, 1]) + + # We test different affine transformations of the initial figure; to + # avoid issues related to round-off errors we only use integer + # coefficients (otherwise the Triangulation might become invalid even with + # delta == 0). + transformations = [[1, 0], [0, 1], [1, 1], [1, 2], [-2, -1], [-2, 1]] + for transformation in transformations: + x_rot = transformation[0]*x0 + transformation[1]*y0 + y_rot = -transformation[1]*x0 + transformation[0]*y0 + (x, y) = (x_rot, y_rot) + z = 1.23*x - 4.79*y + triangles = [[0, 2, 1], [0, 3, 2], [0, 4, 3], [1, 2, 5], [2, 3, 5], + [3, 4, 5], [1, 5, 6], [4, 6, 5]] + triang = mtri.Triangulation(x, y, triangles) + xs = np.linspace(np.min(triang.x), np.max(triang.x), 20) + ys = np.linspace(np.min(triang.y), np.max(triang.y), 20) + xs, ys = np.meshgrid(xs, ys) + xs = xs.ravel() + ys = ys.ravel() + mask_out = (triang.get_trifinder()(xs, ys) == -1) + zs_target = np.ma.array(1.23*xs - 4.79*ys, mask=mask_out) + + linear_interp = mtri.LinearTriInterpolator(triang, z) + cubic_min_E = mtri.CubicTriInterpolator(triang, z) + cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') + + for interp in (linear_interp, cubic_min_E, cubic_geom): + zs = interp(xs, ys) + assert_array_almost_equal(zs_target, zs) + + # Testing interpolation inside the flat triangle number 4: [2, 3, 5] + # by imposing *tri_index* in a call to :meth:`_interpolate_multikeys` + itri = 4 + pt1 = triang.triangles[itri, 0] + pt2 = triang.triangles[itri, 1] + xs = np.linspace(triang.x[pt1], triang.x[pt2], 10) + ys = np.linspace(triang.y[pt1], triang.y[pt2], 10) + zs_target = 1.23*xs - 4.79*ys + for interp in (linear_interp, cubic_min_E, cubic_geom): + zs, = interp._interpolate_multikeys( + xs, ys, tri_index=itri*np.ones(10, dtype=np.int32)) + assert_array_almost_equal(zs_target, zs) + + +def test_triinterp_transformations(): + # 1) Testing that the interpolation scheme is invariant by rotation of the + # whole figure. + # Note: This test is non-trivial for a CubicTriInterpolator with + # kind='min_E'. It does fail for a non-isotropic stiffness matrix E of + # :class:`_ReducedHCT_Element` (tested with E=np.diag([1., 1., 1.])), and + # provides a good test for :meth:`get_Kff_and_Ff`of the same class. + # + # 2) Also testing that the interpolation scheme is invariant by expansion + # of the whole figure along one axis. + n_angles = 20 + n_radii = 10 + min_radius = 0.15 + + def z(x, y): + r1 = np.hypot(0.5 - x, 0.5 - y) + theta1 = np.arctan2(0.5 - x, 0.5 - y) + r2 = np.hypot(-x - 0.2, -y - 0.2) + theta2 = np.arctan2(-x - 0.2, -y - 0.2) + z = -(2*(np.exp((r1/10)**2)-1)*30. * np.cos(7.*theta1) + + (np.exp((r2/10)**2)-1)*30. * np.cos(11.*theta2) + + 0.7*(x**2 + y**2)) + return (np.max(z)-z)/(np.max(z)-np.min(z)) + + # First create the x and y coordinates of the points. + radii = np.linspace(min_radius, 0.95, n_radii) + angles = np.linspace(0 + n_angles, 2*np.pi + n_angles, + n_angles, endpoint=False) + angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) + angles[:, 1::2] += np.pi/n_angles + x0 = (radii*np.cos(angles)).flatten() + y0 = (radii*np.sin(angles)).flatten() + triang0 = mtri.Triangulation(x0, y0) # Delaunay triangulation + z0 = z(x0, y0) + + # Then create the test points + xs0 = np.linspace(-1., 1., 23) + ys0 = np.linspace(-1., 1., 23) + xs0, ys0 = np.meshgrid(xs0, ys0) + xs0 = xs0.ravel() + ys0 = ys0.ravel() + + interp_z0 = {} + for i_angle in range(2): + # Rotating everything + theta = 2*np.pi / n_angles * i_angle + x = np.cos(theta)*x0 + np.sin(theta)*y0 + y = -np.sin(theta)*x0 + np.cos(theta)*y0 + xs = np.cos(theta)*xs0 + np.sin(theta)*ys0 + ys = -np.sin(theta)*xs0 + np.cos(theta)*ys0 + triang = mtri.Triangulation(x, y, triang0.triangles) + linear_interp = mtri.LinearTriInterpolator(triang, z0) + cubic_min_E = mtri.CubicTriInterpolator(triang, z0) + cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom') + dic_interp = {'lin': linear_interp, + 'min_E': cubic_min_E, + 'geom': cubic_geom} + # Testing that the interpolation is invariant by rotation... + for interp_key in ['lin', 'min_E', 'geom']: + interp = dic_interp[interp_key] + if i_angle == 0: + interp_z0[interp_key] = interp(xs0, ys0) # storage + else: + interpz = interp(xs, ys) + matest.assert_array_almost_equal(interpz, + interp_z0[interp_key]) + + scale_factor = 987654.3210 + for scaled_axis in ('x', 'y'): + # Scaling everything (expansion along scaled_axis) + if scaled_axis == 'x': + x = scale_factor * x0 + y = y0 + xs = scale_factor * xs0 + ys = ys0 + else: + x = x0 + y = scale_factor * y0 + xs = xs0 + ys = scale_factor * ys0 + triang = mtri.Triangulation(x, y, triang0.triangles) + linear_interp = mtri.LinearTriInterpolator(triang, z0) + cubic_min_E = mtri.CubicTriInterpolator(triang, z0) + cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom') + dic_interp = {'lin': linear_interp, + 'min_E': cubic_min_E, + 'geom': cubic_geom} + # Test that the interpolation is invariant by expansion along 1 axis... + for interp_key in ['lin', 'min_E', 'geom']: + interpz = dic_interp[interp_key](xs, ys) + matest.assert_array_almost_equal(interpz, interp_z0[interp_key]) + + +@image_comparison(['tri_smooth_contouring.png'], remove_text=True, tol=0.072) +def test_tri_smooth_contouring(): + # Image comparison based on example tricontour_smooth_user. + n_angles = 20 + n_radii = 10 + min_radius = 0.15 + + def z(x, y): + r1 = np.hypot(0.5 - x, 0.5 - y) + theta1 = np.arctan2(0.5 - x, 0.5 - y) + r2 = np.hypot(-x - 0.2, -y - 0.2) + theta2 = np.arctan2(-x - 0.2, -y - 0.2) + z = -(2*(np.exp((r1/10)**2)-1)*30. * np.cos(7.*theta1) + + (np.exp((r2/10)**2)-1)*30. * np.cos(11.*theta2) + + 0.7*(x**2 + y**2)) + return (np.max(z)-z)/(np.max(z)-np.min(z)) + + # First create the x and y coordinates of the points. + radii = np.linspace(min_radius, 0.95, n_radii) + angles = np.linspace(0 + n_angles, 2*np.pi + n_angles, + n_angles, endpoint=False) + angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) + angles[:, 1::2] += np.pi/n_angles + x0 = (radii*np.cos(angles)).flatten() + y0 = (radii*np.sin(angles)).flatten() + triang0 = mtri.Triangulation(x0, y0) # Delaunay triangulation + z0 = z(x0, y0) + triang0.set_mask(np.hypot(x0[triang0.triangles].mean(axis=1), + y0[triang0.triangles].mean(axis=1)) + < min_radius) + + # Then the plot + refiner = mtri.UniformTriRefiner(triang0) + tri_refi, z_test_refi = refiner.refine_field(z0, subdiv=4) + levels = np.arange(0., 1., 0.025) + plt.triplot(triang0, lw=0.5, color='0.5') + plt.tricontour(tri_refi, z_test_refi, levels=levels, colors="black") + + +@image_comparison(['tri_smooth_gradient.png'], remove_text=True, tol=0.092) +def test_tri_smooth_gradient(): + # Image comparison based on example trigradient_demo. + + def dipole_potential(x, y): + """An electric dipole potential V.""" + r_sq = x**2 + y**2 + theta = np.arctan2(y, x) + z = np.cos(theta)/r_sq + return (np.max(z)-z) / (np.max(z)-np.min(z)) + + # Creating a Triangulation + n_angles = 30 + n_radii = 10 + min_radius = 0.2 + radii = np.linspace(min_radius, 0.95, n_radii) + angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) + angles[:, 1::2] += np.pi/n_angles + x = (radii*np.cos(angles)).flatten() + y = (radii*np.sin(angles)).flatten() + V = dipole_potential(x, y) + triang = mtri.Triangulation(x, y) + triang.set_mask(np.hypot(x[triang.triangles].mean(axis=1), + y[triang.triangles].mean(axis=1)) + < min_radius) + + # Refine data - interpolates the electrical potential V + refiner = mtri.UniformTriRefiner(triang) + tri_refi, z_test_refi = refiner.refine_field(V, subdiv=3) + + # Computes the electrical field (Ex, Ey) as gradient of -V + tci = mtri.CubicTriInterpolator(triang, -V) + Ex, Ey = tci.gradient(triang.x, triang.y) + E_norm = np.hypot(Ex, Ey) + + # Plot the triangulation, the potential iso-contours and the vector field + plt.figure() + plt.gca().set_aspect('equal') + plt.triplot(triang, color='0.8') + + levels = np.arange(0., 1., 0.01) + cmap = mpl.colormaps['hot'] + plt.tricontour(tri_refi, z_test_refi, levels=levels, cmap=cmap, + linewidths=[2.0, 1.0, 1.0, 1.0]) + # Plots direction of the electrical vector field + plt.quiver(triang.x, triang.y, Ex/E_norm, Ey/E_norm, + units='xy', scale=10., zorder=3, color='blue', + width=0.007, headwidth=3., headlength=4.) + # We are leaving ax.use_sticky_margins as True, so the + # view limits are the contour data limits. + + +def test_tritools(): + # Tests TriAnalyzer.scale_factors on masked triangulation + # Tests circle_ratios on equilateral and right-angled triangle. + x = np.array([0., 1., 0.5, 0., 2.]) + y = np.array([0., 0., 0.5*np.sqrt(3.), -1., 1.]) + triangles = np.array([[0, 1, 2], [0, 1, 3], [1, 2, 4]], dtype=np.int32) + mask = np.array([False, False, True], dtype=bool) + triang = mtri.Triangulation(x, y, triangles, mask=mask) + analyser = mtri.TriAnalyzer(triang) + assert_array_almost_equal(analyser.scale_factors, [1, 1/(1+3**.5/2)]) + assert_array_almost_equal( + analyser.circle_ratios(rescale=False), + np.ma.masked_array([0.5, 1./(1.+np.sqrt(2.)), np.nan], mask)) + + # Tests circle ratio of a flat triangle + x = np.array([0., 1., 2.]) + y = np.array([1., 1.+3., 1.+6.]) + triangles = np.array([[0, 1, 2]], dtype=np.int32) + triang = mtri.Triangulation(x, y, triangles) + analyser = mtri.TriAnalyzer(triang) + assert_array_almost_equal(analyser.circle_ratios(), np.array([0.])) + + # Tests TriAnalyzer.get_flat_tri_mask + # Creates a triangulation of [-1, 1] x [-1, 1] with contiguous groups of + # 'flat' triangles at the 4 corners and at the center. Checks that only + # those at the borders are eliminated by TriAnalyzer.get_flat_tri_mask + n = 9 + + def power(x, a): + return np.abs(x)**a*np.sign(x) + + x = np.linspace(-1., 1., n+1) + x, y = np.meshgrid(power(x, 2.), power(x, 0.25)) + x = x.ravel() + y = y.ravel() + + triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n+1)) + analyser = mtri.TriAnalyzer(triang) + mask_flat = analyser.get_flat_tri_mask(0.2) + verif_mask = np.zeros(162, dtype=bool) + corners_index = [0, 1, 2, 3, 14, 15, 16, 17, 18, 19, 34, 35, 126, 127, + 142, 143, 144, 145, 146, 147, 158, 159, 160, 161] + verif_mask[corners_index] = True + assert_array_equal(mask_flat, verif_mask) + + # Now including a hole (masked triangle) at the center. The center also + # shall be eliminated by get_flat_tri_mask. + mask = np.zeros(162, dtype=bool) + mask[80] = True + triang.set_mask(mask) + mask_flat = analyser.get_flat_tri_mask(0.2) + center_index = [44, 45, 62, 63, 78, 79, 80, 81, 82, 83, 98, 99, 116, 117] + verif_mask[center_index] = True + assert_array_equal(mask_flat, verif_mask) + + +def test_trirefine(): + # Testing subdiv=2 refinement + n = 3 + subdiv = 2 + x = np.linspace(-1., 1., n+1) + x, y = np.meshgrid(x, x) + x = x.ravel() + y = y.ravel() + mask = np.zeros(2*n**2, dtype=bool) + mask[n**2:] = True + triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n+1), + mask=mask) + refiner = mtri.UniformTriRefiner(triang) + refi_triang = refiner.refine_triangulation(subdiv=subdiv) + x_refi = refi_triang.x + y_refi = refi_triang.y + + n_refi = n * subdiv**2 + x_verif = np.linspace(-1., 1., n_refi+1) + x_verif, y_verif = np.meshgrid(x_verif, x_verif) + x_verif = x_verif.ravel() + y_verif = y_verif.ravel() + ind1d = np.isin(np.around(x_verif*(2.5+y_verif), 8), + np.around(x_refi*(2.5+y_refi), 8)) + assert_array_equal(ind1d, True) + + # Testing the mask of the refined triangulation + refi_mask = refi_triang.mask + refi_tri_barycenter_x = np.sum(refi_triang.x[refi_triang.triangles], + axis=1) / 3. + refi_tri_barycenter_y = np.sum(refi_triang.y[refi_triang.triangles], + axis=1) / 3. + tri_finder = triang.get_trifinder() + refi_tri_indices = tri_finder(refi_tri_barycenter_x, + refi_tri_barycenter_y) + refi_tri_mask = triang.mask[refi_tri_indices] + assert_array_equal(refi_mask, refi_tri_mask) + + # Testing that the numbering of triangles does not change the + # interpolation result. + x = np.asarray([0.0, 1.0, 0.0, 1.0]) + y = np.asarray([0.0, 0.0, 1.0, 1.0]) + triang = [mtri.Triangulation(x, y, [[0, 1, 3], [3, 2, 0]]), + mtri.Triangulation(x, y, [[0, 1, 3], [2, 0, 3]])] + z = np.hypot(x - 0.3, y - 0.4) + # Refining the 2 triangulations and reordering the points + xyz_data = [] + for i in range(2): + refiner = mtri.UniformTriRefiner(triang[i]) + refined_triang, refined_z = refiner.refine_field(z, subdiv=1) + xyz = np.dstack((refined_triang.x, refined_triang.y, refined_z))[0] + xyz = xyz[np.lexsort((xyz[:, 1], xyz[:, 0]))] + xyz_data += [xyz] + assert_array_almost_equal(xyz_data[0], xyz_data[1]) + + +@pytest.mark.parametrize('interpolator', + [mtri.LinearTriInterpolator, + mtri.CubicTriInterpolator], + ids=['linear', 'cubic']) +def test_trirefine_masked(interpolator): + # Repeated points means we will have fewer triangles than points, and thus + # get masking. + x, y = np.mgrid[:2, :2] + x = np.repeat(x.flatten(), 2) + y = np.repeat(y.flatten(), 2) + + z = np.zeros_like(x) + tri = mtri.Triangulation(x, y) + refiner = mtri.UniformTriRefiner(tri) + interp = interpolator(tri, z) + refiner.refine_field(z, triinterpolator=interp, subdiv=2) + + +def meshgrid_triangles(n): + """ + Return (2*(N-1)**2, 3) array of triangles to mesh (N, N)-point np.meshgrid. + """ + tri = [] + for i in range(n-1): + for j in range(n-1): + a = i + j*n + b = (i+1) + j*n + c = i + (j+1)*n + d = (i+1) + (j+1)*n + tri += [[a, b, d], [a, d, c]] + return np.array(tri, dtype=np.int32) + + +def test_triplot_return(): + # Check that triplot returns the artists it adds + ax = plt.figure().add_subplot() + triang = mtri.Triangulation( + [0.0, 1.0, 0.0, 1.0], [0.0, 0.0, 1.0, 1.0], + triangles=[[0, 1, 3], [3, 2, 0]]) + assert ax.triplot(triang, "b-") is not None, \ + 'triplot should return the artist it adds' + + +def test_trirefiner_fortran_contiguous_triangles(): + # github issue 4180. Test requires two arrays of triangles that are + # identical except that one is C-contiguous and one is fortran-contiguous. + triangles1 = np.array([[2, 0, 3], [2, 1, 0]]) + assert not np.isfortran(triangles1) + + triangles2 = np.array(triangles1, copy=True, order='F') + assert np.isfortran(triangles2) + + x = np.array([0.39, 0.59, 0.43, 0.32]) + y = np.array([33.99, 34.01, 34.19, 34.18]) + triang1 = mtri.Triangulation(x, y, triangles1) + triang2 = mtri.Triangulation(x, y, triangles2) + + refiner1 = mtri.UniformTriRefiner(triang1) + refiner2 = mtri.UniformTriRefiner(triang2) + + fine_triang1 = refiner1.refine_triangulation(subdiv=1) + fine_triang2 = refiner2.refine_triangulation(subdiv=1) + + assert_array_equal(fine_triang1.triangles, fine_triang2.triangles) + + +def test_qhull_triangle_orientation(): + # github issue 4437. + xi = np.linspace(-2, 2, 100) + x, y = map(np.ravel, np.meshgrid(xi, xi)) + w = (x > y - 1) & (x < -1.95) & (y > -1.2) + x, y = x[w], y[w] + theta = np.radians(25) + x1 = x*np.cos(theta) - y*np.sin(theta) + y1 = x*np.sin(theta) + y*np.cos(theta) + + # Calculate Delaunay triangulation using Qhull. + triang = mtri.Triangulation(x1, y1) + + # Neighbors returned by Qhull. + qhull_neighbors = triang.neighbors + + # Obtain neighbors using own C++ calculation. + triang._neighbors = None + own_neighbors = triang.neighbors + + assert_array_equal(qhull_neighbors, own_neighbors) + + +def test_trianalyzer_mismatched_indices(): + # github issue 4999. + x = np.array([0., 1., 0.5, 0., 2.]) + y = np.array([0., 0., 0.5*np.sqrt(3.), -1., 1.]) + triangles = np.array([[0, 1, 2], [0, 1, 3], [1, 2, 4]], dtype=np.int32) + mask = np.array([False, False, True], dtype=bool) + triang = mtri.Triangulation(x, y, triangles, mask=mask) + analyser = mtri.TriAnalyzer(triang) + # numpy >= 1.10 raises a VisibleDeprecationWarning in the following line + # prior to the fix. + analyser._get_compressed_triangulation() + + +def test_tricontourf_decreasing_levels(): + # github issue 5477. + x = [0.0, 1.0, 1.0] + y = [0.0, 0.0, 1.0] + z = [0.2, 0.4, 0.6] + plt.figure() + with pytest.raises(ValueError): + plt.tricontourf(x, y, z, [1.0, 0.0]) + + +def test_internal_cpp_api(): + # Following github issue 8197. + from matplotlib import _tri # noqa: ensure lazy-loaded module *is* loaded. + + # C++ Triangulation. + with pytest.raises( + TypeError, + match=r'__init__\(\): incompatible constructor arguments.'): + mpl._tri.Triangulation() + + with pytest.raises( + ValueError, match=r'x and y must be 1D arrays of the same length'): + mpl._tri.Triangulation([], [1], [[]], (), (), (), False) + + x = [0, 1, 1] + y = [0, 0, 1] + with pytest.raises( + ValueError, + match=r'triangles must be a 2D array of shape \(\?,3\)'): + mpl._tri.Triangulation(x, y, [[0, 1]], (), (), (), False) + + tris = [[0, 1, 2]] + with pytest.raises( + ValueError, + match=r'mask must be a 1D array with the same length as the ' + r'triangles array'): + mpl._tri.Triangulation(x, y, tris, [0, 1], (), (), False) + + with pytest.raises( + ValueError, match=r'edges must be a 2D array with shape \(\?,2\)'): + mpl._tri.Triangulation(x, y, tris, (), [[1]], (), False) + + with pytest.raises( + ValueError, + match=r'neighbors must be a 2D array with the same shape as the ' + r'triangles array'): + mpl._tri.Triangulation(x, y, tris, (), (), [[-1]], False) + + triang = mpl._tri.Triangulation(x, y, tris, (), (), (), False) + + with pytest.raises( + ValueError, + match=r'z must be a 1D array with the same length as the ' + r'triangulation x and y arrays'): + triang.calculate_plane_coefficients([]) + + for mask in ([0, 1], None): + with pytest.raises( + ValueError, + match=r'mask must be a 1D array with the same length as the ' + r'triangles array'): + triang.set_mask(mask) + + triang.set_mask([True]) + assert_array_equal(triang.get_edges(), np.empty((0, 2))) + + triang.set_mask(()) # Equivalent to Python Triangulation mask=None + assert_array_equal(triang.get_edges(), [[1, 0], [2, 0], [2, 1]]) + + # C++ TriContourGenerator. + with pytest.raises( + TypeError, + match=r'__init__\(\): incompatible constructor arguments.'): + mpl._tri.TriContourGenerator() + + with pytest.raises( + ValueError, + match=r'z must be a 1D array with the same length as the x and y ' + r'arrays'): + mpl._tri.TriContourGenerator(triang, [1]) + + z = [0, 1, 2] + tcg = mpl._tri.TriContourGenerator(triang, z) + + with pytest.raises( + ValueError, match=r'filled contour levels must be increasing'): + tcg.create_filled_contour(1, 0) + + # C++ TrapezoidMapTriFinder. + with pytest.raises( + TypeError, + match=r'__init__\(\): incompatible constructor arguments.'): + mpl._tri.TrapezoidMapTriFinder() + + trifinder = mpl._tri.TrapezoidMapTriFinder(triang) + + with pytest.raises( + ValueError, match=r'x and y must be array-like with same shape'): + trifinder.find_many([0], [0, 1]) + + +def test_qhull_large_offset(): + # github issue 8682. + x = np.asarray([0, 1, 0, 1, 0.5]) + y = np.asarray([0, 0, 1, 1, 0.5]) + + offset = 1e10 + triang = mtri.Triangulation(x, y) + triang_offset = mtri.Triangulation(x + offset, y + offset) + assert len(triang.triangles) == len(triang_offset.triangles) + + +def test_tricontour_non_finite_z(): + # github issue 10167. + x = [0, 1, 0, 1] + y = [0, 0, 1, 1] + triang = mtri.Triangulation(x, y) + plt.figure() + + with pytest.raises(ValueError, match='z array must not contain non-finite ' + 'values within the triangulation'): + plt.tricontourf(triang, [0, 1, 2, np.inf]) + + with pytest.raises(ValueError, match='z array must not contain non-finite ' + 'values within the triangulation'): + plt.tricontourf(triang, [0, 1, 2, -np.inf]) + + with pytest.raises(ValueError, match='z array must not contain non-finite ' + 'values within the triangulation'): + plt.tricontourf(triang, [0, 1, 2, np.nan]) + + with pytest.raises(ValueError, match='z must not contain masked points ' + 'within the triangulation'): + plt.tricontourf(triang, np.ma.array([0, 1, 2, 3], mask=[1, 0, 0, 0])) + + +def test_tricontourset_reuse(): + # If TriContourSet returned from one tricontour(f) call is passed as first + # argument to another the underlying C++ contour generator will be reused. + x = [0.0, 0.5, 1.0] + y = [0.0, 1.0, 0.0] + z = [1.0, 2.0, 3.0] + fig, ax = plt.subplots() + tcs1 = ax.tricontourf(x, y, z) + tcs2 = ax.tricontour(x, y, z) + assert tcs2._contour_generator != tcs1._contour_generator + tcs3 = ax.tricontour(tcs1, z) + assert tcs3._contour_generator == tcs1._contour_generator + + +@check_figures_equal() +def test_triplot_with_ls(fig_test, fig_ref): + x = [0, 2, 1] + y = [0, 0, 1] + data = [[0, 1, 2]] + fig_test.subplots().triplot(x, y, data, ls='--') + fig_ref.subplots().triplot(x, y, data, linestyle='--') + + +def test_triplot_label(): + x = [0, 2, 1] + y = [0, 0, 1] + data = [[0, 1, 2]] + fig, ax = plt.subplots() + lines, markers = ax.triplot(x, y, data, label='label') + handles, labels = ax.get_legend_handles_labels() + assert labels == ['label'] + assert len(handles) == 1 + assert handles[0] is lines + + +def test_tricontour_path(): + x = [0, 4, 4, 0, 2] + y = [0, 0, 4, 4, 2] + triang = mtri.Triangulation(x, y) + _, ax = plt.subplots() + + # Line strip from boundary to boundary + cs = ax.tricontour(triang, [1, 0, 0, 0, 0], levels=[0.5]) + paths = cs.get_paths() + assert len(paths) == 1 + expected_vertices = [[2, 0], [1, 1], [0, 2]] + assert_array_almost_equal(paths[0].vertices, expected_vertices) + assert_array_equal(paths[0].codes, [1, 2, 2]) + assert_array_almost_equal( + paths[0].to_polygons(closed_only=False), [expected_vertices]) + + # Closed line loop inside domain + cs = ax.tricontour(triang, [0, 0, 0, 0, 1], levels=[0.5]) + paths = cs.get_paths() + assert len(paths) == 1 + expected_vertices = [[3, 1], [3, 3], [1, 3], [1, 1], [3, 1]] + assert_array_almost_equal(paths[0].vertices, expected_vertices) + assert_array_equal(paths[0].codes, [1, 2, 2, 2, 79]) + assert_array_almost_equal(paths[0].to_polygons(), [expected_vertices]) + + +def test_tricontourf_path(): + x = [0, 4, 4, 0, 2] + y = [0, 0, 4, 4, 2] + triang = mtri.Triangulation(x, y) + _, ax = plt.subplots() + + # Polygon inside domain + cs = ax.tricontourf(triang, [0, 0, 0, 0, 1], levels=[0.5, 1.5]) + paths = cs.get_paths() + assert len(paths) == 1 + expected_vertices = [[3, 1], [3, 3], [1, 3], [1, 1], [3, 1]] + assert_array_almost_equal(paths[0].vertices, expected_vertices) + assert_array_equal(paths[0].codes, [1, 2, 2, 2, 79]) + assert_array_almost_equal(paths[0].to_polygons(), [expected_vertices]) + + # Polygon following boundary and inside domain + cs = ax.tricontourf(triang, [1, 0, 0, 0, 0], levels=[0.5, 1.5]) + paths = cs.get_paths() + assert len(paths) == 1 + expected_vertices = [[2, 0], [1, 1], [0, 2], [0, 0], [2, 0]] + assert_array_almost_equal(paths[0].vertices, expected_vertices) + assert_array_equal(paths[0].codes, [1, 2, 2, 2, 79]) + assert_array_almost_equal(paths[0].to_polygons(), [expected_vertices]) + + # Polygon is outer boundary with hole + cs = ax.tricontourf(triang, [0, 0, 0, 0, 1], levels=[-0.5, 0.5]) + paths = cs.get_paths() + assert len(paths) == 1 + expected_vertices = [[0, 0], [4, 0], [4, 4], [0, 4], [0, 0], + [1, 1], [1, 3], [3, 3], [3, 1], [1, 1]] + assert_array_almost_equal(paths[0].vertices, expected_vertices) + assert_array_equal(paths[0].codes, [1, 2, 2, 2, 79, 1, 2, 2, 2, 79]) + assert_array_almost_equal(paths[0].to_polygons(), np.split(expected_vertices, [5])) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ttconv.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ttconv.py new file mode 100644 index 00000000..1d839e70 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_ttconv.py @@ -0,0 +1,17 @@ +from pathlib import Path + +import matplotlib +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt + + +@image_comparison(["truetype-conversion.pdf"]) +# mpltest.ttf does not have "l"/"p" glyphs so we get a warning when trying to +# get the font extents. +def test_truetype_conversion(recwarn): + matplotlib.rcParams['pdf.fonttype'] = 3 + fig, ax = plt.subplots() + ax.text(0, 0, "ABCDE", + font=Path(__file__).with_name("mpltest.ttf"), fontsize=80) + ax.set_xticks([]) + ax.set_yticks([]) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_type1font.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_type1font.py new file mode 100644 index 00000000..1e173d5e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_type1font.py @@ -0,0 +1,160 @@ +import matplotlib._type1font as t1f +import os.path +import difflib +import pytest + + +def test_Type1Font(): + filename = os.path.join(os.path.dirname(__file__), 'cmr10.pfb') + font = t1f.Type1Font(filename) + slanted = font.transform({'slant': 1}) + condensed = font.transform({'extend': 0.5}) + with open(filename, 'rb') as fd: + rawdata = fd.read() + assert font.parts[0] == rawdata[0x0006:0x10c5] + assert font.parts[1] == rawdata[0x10cb:0x897f] + assert font.parts[2] == rawdata[0x8985:0x8ba6] + assert font.decrypted.startswith(b'dup\n/Private 18 dict dup begin') + assert font.decrypted.endswith(b'mark currentfile closefile\n') + assert slanted.decrypted.startswith(b'dup\n/Private 18 dict dup begin') + assert slanted.decrypted.endswith(b'mark currentfile closefile\n') + assert b'UniqueID 5000793' in font.parts[0] + assert b'UniqueID 5000793' in font.decrypted + assert font._pos['UniqueID'] == [(797, 818), (4483, 4504)] + + len0 = len(font.parts[0]) + for key in font._pos.keys(): + for pos0, pos1 in font._pos[key]: + if pos0 < len0: + data = font.parts[0][pos0:pos1] + else: + data = font.decrypted[pos0-len0:pos1-len0] + assert data.startswith(f'/{key}'.encode('ascii')) + assert {'FontType', 'FontMatrix', 'PaintType', 'ItalicAngle', 'RD' + } < set(font._pos.keys()) + + assert b'UniqueID 5000793' not in slanted.parts[0] + assert b'UniqueID 5000793' not in slanted.decrypted + assert 'UniqueID' not in slanted._pos + assert font.prop['Weight'] == 'Medium' + assert not font.prop['isFixedPitch'] + assert font.prop['ItalicAngle'] == 0 + assert slanted.prop['ItalicAngle'] == -45 + assert font.prop['Encoding'][5] == 'Pi' + assert isinstance(font.prop['CharStrings']['Pi'], bytes) + assert font._abbr['ND'] == 'ND' + + differ = difflib.Differ() + diff = list(differ.compare( + font.parts[0].decode('latin-1').splitlines(), + slanted.parts[0].decode('latin-1').splitlines())) + for line in ( + # Removes UniqueID + '- /UniqueID 5000793 def', + # Changes the font name + '- /FontName /CMR10 def', + '+ /FontName/CMR10_Slant_1000 def', + # Alters FontMatrix + '- /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def', + '+ /FontMatrix [0.001 0 0.001 0.001 0 0] readonly def', + # Alters ItalicAngle + '- /ItalicAngle 0 def', + '+ /ItalicAngle -45.0 def'): + assert line in diff, 'diff to slanted font must contain %s' % line + + diff = list(differ.compare( + font.parts[0].decode('latin-1').splitlines(), + condensed.parts[0].decode('latin-1').splitlines())) + for line in ( + # Removes UniqueID + '- /UniqueID 5000793 def', + # Changes the font name + '- /FontName /CMR10 def', + '+ /FontName/CMR10_Extend_500 def', + # Alters FontMatrix + '- /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def', + '+ /FontMatrix [0.0005 0 0 0.001 0 0] readonly def'): + assert line in diff, 'diff to condensed font must contain %s' % line + + +def test_Type1Font_2(): + filename = os.path.join(os.path.dirname(__file__), + 'Courier10PitchBT-Bold.pfb') + font = t1f.Type1Font(filename) + assert font.prop['Weight'] == 'Bold' + assert font.prop['isFixedPitch'] + assert font.prop['Encoding'][65] == 'A' # the font uses StandardEncoding + (pos0, pos1), = font._pos['Encoding'] + assert font.parts[0][pos0:pos1] == b'/Encoding StandardEncoding' + assert font._abbr['ND'] == '|-' + + +def test_tokenize(): + data = (b'1234/abc false -9.81 Foo <<[0 1 2]<0 1ef a\t>>>\n' + b'(string with(nested\t\\) par)ens\\\\)') + # 1 2 x 2 xx1 + # 1 and 2 are matching parens, x means escaped character + n, w, num, kw, d = 'name', 'whitespace', 'number', 'keyword', 'delimiter' + b, s = 'boolean', 'string' + correct = [ + (num, 1234), (n, 'abc'), (w, ' '), (b, False), (w, ' '), (num, -9.81), + (w, ' '), (kw, 'Foo'), (w, ' '), (d, '<<'), (d, '['), (num, 0), + (w, ' '), (num, 1), (w, ' '), (num, 2), (d, ']'), (s, b'\x01\xef\xa0'), + (d, '>>'), (w, '\n'), (s, 'string with(nested\t) par)ens\\') + ] + correct_no_ws = [x for x in correct if x[0] != w] + + def convert(tokens): + return [(t.kind, t.value()) for t in tokens] + + assert convert(t1f._tokenize(data, False)) == correct + assert convert(t1f._tokenize(data, True)) == correct_no_ws + + def bin_after(n): + tokens = t1f._tokenize(data, True) + result = [] + for _ in range(n): + result.append(next(tokens)) + result.append(tokens.send(10)) + return convert(result) + + for n in range(1, len(correct_no_ws)): + result = bin_after(n) + assert result[:-1] == correct_no_ws[:n] + assert result[-1][0] == 'binary' + assert isinstance(result[-1][1], bytes) + + +def test_tokenize_errors(): + with pytest.raises(ValueError): + list(t1f._tokenize(b'1234 (this (string) is unterminated\\)', True)) + with pytest.raises(ValueError): + list(t1f._tokenize(b'/Foo<01234', True)) + with pytest.raises(ValueError): + list(t1f._tokenize(b'/Foo<01234abcg>/Bar', True)) + + +def test_overprecision(): + # We used to output too many digits in FontMatrix entries and + # ItalicAngle, which could make Type-1 parsers unhappy. + filename = os.path.join(os.path.dirname(__file__), 'cmr10.pfb') + font = t1f.Type1Font(filename) + slanted = font.transform({'slant': .167}) + lines = slanted.parts[0].decode('ascii').splitlines() + matrix, = [line[line.index('[')+1:line.index(']')] + for line in lines if '/FontMatrix' in line] + angle, = [word + for line in lines if '/ItalicAngle' in line + for word in line.split() if word[0] in '-0123456789'] + # the following used to include 0.00016700000000000002 + assert matrix == '0.001 0 0.000167 0.001 0 0' + # and here we had -9.48090361795083 + assert angle == '-9.4809' + + +def test_encrypt_decrypt_roundtrip(): + data = b'this is my plaintext \0\1\2\3' + encrypted = t1f.Type1Font._encrypt(data, 'eexec') + decrypted = t1f.Type1Font._decrypt(encrypted, 'eexec') + assert encrypted != decrypted + assert data == decrypted diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_units.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_units.py new file mode 100644 index 00000000..d3b8c5a7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_units.py @@ -0,0 +1,285 @@ +from datetime import datetime, timezone, timedelta +import platform +from unittest.mock import MagicMock + +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import check_figures_equal, image_comparison +import matplotlib.units as munits +from matplotlib.category import UnitData +import numpy as np +import pytest + + +# Basic class that wraps numpy array and has units +class Quantity: + def __init__(self, data, units): + self.magnitude = data + self.units = units + + def to(self, new_units): + factors = {('hours', 'seconds'): 3600, ('minutes', 'hours'): 1 / 60, + ('minutes', 'seconds'): 60, ('feet', 'miles'): 1 / 5280., + ('feet', 'inches'): 12, ('miles', 'inches'): 12 * 5280} + if self.units != new_units: + mult = factors[self.units, new_units] + return Quantity(mult * self.magnitude, new_units) + else: + return Quantity(self.magnitude, self.units) + + def __copy__(self): + return Quantity(self.magnitude, self.units) + + def __getattr__(self, attr): + return getattr(self.magnitude, attr) + + def __getitem__(self, item): + if np.iterable(self.magnitude): + return Quantity(self.magnitude[item], self.units) + else: + return Quantity(self.magnitude, self.units) + + def __array__(self): + return np.asarray(self.magnitude) + + +@pytest.fixture +def quantity_converter(): + # Create an instance of the conversion interface and + # mock so we can check methods called + qc = munits.ConversionInterface() + + def convert(value, unit, axis): + if hasattr(value, 'units'): + return value.to(unit).magnitude + elif np.iterable(value): + try: + return [v.to(unit).magnitude for v in value] + except AttributeError: + return [Quantity(v, axis.get_units()).to(unit).magnitude + for v in value] + else: + return Quantity(value, axis.get_units()).to(unit).magnitude + + def default_units(value, axis): + if hasattr(value, 'units'): + return value.units + elif np.iterable(value): + for v in value: + if hasattr(v, 'units'): + return v.units + return None + + qc.convert = MagicMock(side_effect=convert) + qc.axisinfo = MagicMock(side_effect=lambda u, a: + munits.AxisInfo(label=u, default_limits=(0, 100))) + qc.default_units = MagicMock(side_effect=default_units) + return qc + + +# Tests that the conversion machinery works properly for classes that +# work as a facade over numpy arrays (like pint) +@image_comparison(['plot_pint.png'], style='mpl20', + tol=0 if platform.machine() == 'x86_64' else 0.01) +def test_numpy_facade(quantity_converter): + # use former defaults to match existing baseline image + plt.rcParams['axes.formatter.limits'] = -7, 7 + + # Register the class + munits.registry[Quantity] = quantity_converter + + # Simple test + y = Quantity(np.linspace(0, 30), 'miles') + x = Quantity(np.linspace(0, 5), 'hours') + + fig, ax = plt.subplots() + fig.subplots_adjust(left=0.15) # Make space for label + ax.plot(x, y, 'tab:blue') + ax.axhline(Quantity(26400, 'feet'), color='tab:red') + ax.axvline(Quantity(120, 'minutes'), color='tab:green') + ax.yaxis.set_units('inches') + ax.xaxis.set_units('seconds') + + assert quantity_converter.convert.called + assert quantity_converter.axisinfo.called + assert quantity_converter.default_units.called + + +# Tests gh-8908 +@image_comparison(['plot_masked_units.png'], remove_text=True, style='mpl20', + tol=0 if platform.machine() == 'x86_64' else 0.01) +def test_plot_masked_units(): + data = np.linspace(-5, 5) + data_masked = np.ma.array(data, mask=(data > -2) & (data < 2)) + data_masked_units = Quantity(data_masked, 'meters') + + fig, ax = plt.subplots() + ax.plot(data_masked_units) + + +def test_empty_set_limits_with_units(quantity_converter): + # Register the class + munits.registry[Quantity] = quantity_converter + + fig, ax = plt.subplots() + ax.set_xlim(Quantity(-1, 'meters'), Quantity(6, 'meters')) + ax.set_ylim(Quantity(-1, 'hours'), Quantity(16, 'hours')) + + +@image_comparison(['jpl_bar_units.png'], + savefig_kwarg={'dpi': 120}, style='mpl20') +def test_jpl_bar_units(): + import matplotlib.testing.jpl_units as units + units.register() + + day = units.Duration("ET", 24.0 * 60.0 * 60.0) + x = [0 * units.km, 1 * units.km, 2 * units.km] + w = [1 * day, 2 * day, 3 * day] + b = units.Epoch("ET", dt=datetime(2009, 4, 25)) + fig, ax = plt.subplots() + ax.bar(x, w, bottom=b) + ax.set_ylim([b - 1 * day, b + w[-1] + (1.001) * day]) + + +@image_comparison(['jpl_barh_units.png'], + savefig_kwarg={'dpi': 120}, style='mpl20') +def test_jpl_barh_units(): + import matplotlib.testing.jpl_units as units + units.register() + + day = units.Duration("ET", 24.0 * 60.0 * 60.0) + x = [0 * units.km, 1 * units.km, 2 * units.km] + w = [1 * day, 2 * day, 3 * day] + b = units.Epoch("ET", dt=datetime(2009, 4, 25)) + + fig, ax = plt.subplots() + ax.barh(x, w, left=b) + ax.set_xlim([b - 1 * day, b + w[-1] + (1.001) * day]) + + +def test_empty_arrays(): + # Check that plotting an empty array with a dtype works + plt.scatter(np.array([], dtype='datetime64[ns]'), np.array([])) + + +def test_scatter_element0_masked(): + times = np.arange('2005-02', '2005-03', dtype='datetime64[D]') + y = np.arange(len(times), dtype=float) + y[0] = np.nan + fig, ax = plt.subplots() + ax.scatter(times, y) + fig.canvas.draw() + + +def test_errorbar_mixed_units(): + x = np.arange(10) + y = [datetime(2020, 5, i * 2 + 1) for i in x] + fig, ax = plt.subplots() + ax.errorbar(x, y, timedelta(days=0.5)) + fig.canvas.draw() + + +@check_figures_equal(extensions=["png"]) +def test_subclass(fig_test, fig_ref): + class subdate(datetime): + pass + + fig_test.subplots().plot(subdate(2000, 1, 1), 0, "o") + fig_ref.subplots().plot(datetime(2000, 1, 1), 0, "o") + + +def test_shared_axis_quantity(quantity_converter): + munits.registry[Quantity] = quantity_converter + x = Quantity(np.linspace(0, 1, 10), "hours") + y1 = Quantity(np.linspace(1, 2, 10), "feet") + y2 = Quantity(np.linspace(3, 4, 10), "feet") + fig, (ax1, ax2) = plt.subplots(2, 1, sharex='all', sharey='all') + ax1.plot(x, y1) + ax2.plot(x, y2) + assert ax1.xaxis.get_units() == ax2.xaxis.get_units() == "hours" + assert ax2.yaxis.get_units() == ax2.yaxis.get_units() == "feet" + ax1.xaxis.set_units("seconds") + ax2.yaxis.set_units("inches") + assert ax1.xaxis.get_units() == ax2.xaxis.get_units() == "seconds" + assert ax1.yaxis.get_units() == ax2.yaxis.get_units() == "inches" + + +def test_shared_axis_datetime(): + # datetime uses dates.DateConverter + y1 = [datetime(2020, i, 1, tzinfo=timezone.utc) for i in range(1, 13)] + y2 = [datetime(2021, i, 1, tzinfo=timezone.utc) for i in range(1, 13)] + fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True) + ax1.plot(y1) + ax2.plot(y2) + ax1.yaxis.set_units(timezone(timedelta(hours=5))) + assert ax2.yaxis.units == timezone(timedelta(hours=5)) + + +def test_shared_axis_categorical(): + # str uses category.StrCategoryConverter + d1 = {"a": 1, "b": 2} + d2 = {"a": 3, "b": 4} + fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True) + ax1.plot(d1.keys(), d1.values()) + ax2.plot(d2.keys(), d2.values()) + ax1.xaxis.set_units(UnitData(["c", "d"])) + assert "c" in ax2.xaxis.get_units()._mapping.keys() + + +def test_empty_default_limits(quantity_converter): + munits.registry[Quantity] = quantity_converter + fig, ax1 = plt.subplots() + ax1.xaxis.update_units(Quantity([10], "miles")) + fig.draw_without_rendering() + assert ax1.get_xlim() == (0, 100) + ax1.yaxis.update_units(Quantity([10], "miles")) + fig.draw_without_rendering() + assert ax1.get_ylim() == (0, 100) + + fig, ax = plt.subplots() + ax.axhline(30) + ax.plot(Quantity(np.arange(0, 3), "miles"), + Quantity(np.arange(0, 6, 2), "feet")) + fig.draw_without_rendering() + assert ax.get_xlim() == (0, 2) + assert ax.get_ylim() == (0, 30) + + fig, ax = plt.subplots() + ax.axvline(30) + ax.plot(Quantity(np.arange(0, 3), "miles"), + Quantity(np.arange(0, 6, 2), "feet")) + fig.draw_without_rendering() + assert ax.get_xlim() == (0, 30) + assert ax.get_ylim() == (0, 4) + + fig, ax = plt.subplots() + ax.xaxis.update_units(Quantity([10], "miles")) + ax.axhline(30) + fig.draw_without_rendering() + assert ax.get_xlim() == (0, 100) + assert ax.get_ylim() == (28.5, 31.5) + + fig, ax = plt.subplots() + ax.yaxis.update_units(Quantity([10], "miles")) + ax.axvline(30) + fig.draw_without_rendering() + assert ax.get_ylim() == (0, 100) + assert ax.get_xlim() == (28.5, 31.5) + + +# test array-like objects... +class Kernel: + def __init__(self, array): + self._array = np.asanyarray(array) + + def __array__(self): + return self._array + + @property + def shape(self): + return self._array.shape + + +def test_plot_kernel(): + # just a smoketest that fail + kernel = Kernel([1, 2, 3, 4, 5]) + plt.plot(kernel) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_usetex.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_usetex.py new file mode 100644 index 00000000..342face4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_usetex.py @@ -0,0 +1,187 @@ +from tempfile import TemporaryFile + +import numpy as np +from packaging.version import parse as parse_version +import pytest + +import matplotlib as mpl +from matplotlib import dviread +from matplotlib.testing import _has_tex_package +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing._markers import needs_usetex +import matplotlib.pyplot as plt + + +pytestmark = needs_usetex + + +@image_comparison( + baseline_images=['test_usetex'], + extensions=['pdf', 'png'], + style="mpl20") +def test_usetex(): + mpl.rcParams['text.usetex'] = True + fig, ax = plt.subplots() + kwargs = {"verticalalignment": "baseline", "size": 24, + "bbox": dict(pad=0, edgecolor="k", facecolor="none")} + ax.text(0.2, 0.7, + # the \LaTeX macro exercises character sizing and placement, + # \left[ ... \right\} draw some variable-height characters, + # \sqrt and \frac draw horizontal rules, \mathrm changes the font + r'\LaTeX\ $\left[\int\limits_e^{2e}' + r'\sqrt\frac{\log^3 x}{x}\,\mathrm{d}x \right\}$', + **kwargs) + ax.text(0.2, 0.3, "lg", **kwargs) + ax.text(0.4, 0.3, r"$\frac{1}{2}\pi$", **kwargs) + ax.text(0.6, 0.3, "$p^{3^A}$", **kwargs) + ax.text(0.8, 0.3, "$p_{3_2}$", **kwargs) + for x in {t.get_position()[0] for t in ax.texts}: + ax.axvline(x) + for y in {t.get_position()[1] for t in ax.texts}: + ax.axhline(y) + ax.set_axis_off() + + +@check_figures_equal() +def test_empty(fig_test, fig_ref): + mpl.rcParams['text.usetex'] = True + fig_test.text(.5, .5, "% a comment") + + +@check_figures_equal() +def test_unicode_minus(fig_test, fig_ref): + mpl.rcParams['text.usetex'] = True + fig_test.text(.5, .5, "$-$") + fig_ref.text(.5, .5, "\N{MINUS SIGN}") + + +def test_mathdefault(): + plt.rcParams["axes.formatter.use_mathtext"] = True + fig = plt.figure() + fig.add_subplot().set_xlim(-1, 1) + # Check that \mathdefault commands generated by tickers don't cause + # problems when later switching usetex on. + mpl.rcParams['text.usetex'] = True + fig.canvas.draw() + + +@image_comparison(['eqnarray.png']) +def test_multiline_eqnarray(): + text = ( + r'\begin{eqnarray*}' + r'foo\\' + r'bar\\' + r'baz\\' + r'\end{eqnarray*}' + ) + + fig = plt.figure(figsize=(1, 1)) + fig.text(0.5, 0.5, text, usetex=True, + horizontalalignment='center', verticalalignment='center') + + +@pytest.mark.parametrize("fontsize", [8, 10, 12]) +def test_minus_no_descent(fontsize): + # Test special-casing of minus descent in DviFont._height_depth_of, by + # checking that overdrawing a 1 and a -1 results in an overall height + # equivalent to drawing either of them separately. + mpl.style.use("mpl20") + mpl.rcParams['font.size'] = fontsize + heights = {} + fig = plt.figure() + for vals in [(1,), (-1,), (-1, 1)]: + fig.clear() + for x in vals: + fig.text(.5, .5, f"${x}$", usetex=True) + fig.canvas.draw() + # The following counts the number of non-fully-blank pixel rows. + heights[vals] = ((np.array(fig.canvas.buffer_rgba())[..., 0] != 255) + .any(axis=1).sum()) + assert len({*heights.values()}) == 1 + + +@pytest.mark.parametrize('pkg', ['xcolor', 'chemformula']) +def test_usetex_packages(pkg): + if not _has_tex_package(pkg): + pytest.skip(f'{pkg} is not available') + mpl.rcParams['text.usetex'] = True + + fig = plt.figure() + text = fig.text(0.5, 0.5, "Some text 0123456789") + fig.canvas.draw() + + mpl.rcParams['text.latex.preamble'] = ( + r'\PassOptionsToPackage{dvipsnames}{xcolor}\usepackage{%s}' % pkg) + fig = plt.figure() + text2 = fig.text(0.5, 0.5, "Some text 0123456789") + fig.canvas.draw() + np.testing.assert_array_equal(text2.get_window_extent(), + text.get_window_extent()) + + +@pytest.mark.parametrize( + "preamble", + [r"\usepackage[full]{textcomp}", r"\usepackage{underscore}"], +) +def test_latex_pkg_already_loaded(preamble): + plt.rcParams["text.latex.preamble"] = preamble + fig = plt.figure() + fig.text(.5, .5, "hello, world", usetex=True) + fig.canvas.draw() + + +def test_usetex_with_underscore(): + plt.rcParams["text.usetex"] = True + df = {"a_b": range(5)[::-1], "c": range(5)} + fig, ax = plt.subplots() + ax.plot("c", "a_b", data=df) + ax.legend() + ax.text(0, 0, "foo_bar", usetex=True) + plt.draw() + + +@pytest.mark.flaky(reruns=3) # Tends to hit a TeX cache lock on AppVeyor. +@pytest.mark.parametrize("fmt", ["pdf", "svg"]) +def test_missing_psfont(fmt, monkeypatch): + """An error is raised if a TeX font lacks a Type-1 equivalent""" + monkeypatch.setattr( + dviread.PsfontsMap, '__getitem__', + lambda self, k: dviread.PsFont( + texname=b'texfont', psname=b'Some Font', + effects=None, encoding=None, filename=None)) + mpl.rcParams['text.usetex'] = True + fig, ax = plt.subplots() + ax.text(0.5, 0.5, 'hello') + with TemporaryFile() as tmpfile, pytest.raises(ValueError): + fig.savefig(tmpfile, format=fmt) + + +try: + _old_gs_version = mpl._get_executable_info('gs').version < parse_version('9.55') +except mpl.ExecutableNotFoundError: + _old_gs_version = True + + +@image_comparison(baseline_images=['rotation'], extensions=['eps', 'pdf', 'png', 'svg'], + style='mpl20', tol=3.91 if _old_gs_version else 0) +def test_rotation(): + mpl.rcParams['text.usetex'] = True + + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1]) + ax.set(xlim=[-0.5, 5], xticks=[], ylim=[-0.5, 3], yticks=[], frame_on=False) + + text = {val: val[0] for val in ['top', 'center', 'bottom', 'left', 'right']} + text['baseline'] = 'B' + text['center_baseline'] = 'C' + + for i, va in enumerate(['top', 'center', 'bottom', 'baseline', 'center_baseline']): + for j, ha in enumerate(['left', 'center', 'right']): + for k, angle in enumerate([0, 90, 180, 270]): + k //= 2 + x = i + k / 2 + y = j + k / 2 + ax.plot(x, y, '+', c=f'C{k}', markersize=20, markeredgewidth=0.5) + # 'My' checks full height letters plus descenders. + ax.text(x, y, f"$\\mathrm{{My {text[ha]}{text[va]} {angle}}}$", + rotation=angle, horizontalalignment=ha, verticalalignment=va) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_widgets.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_widgets.py new file mode 100644 index 00000000..1ecb4b9a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tests/test_widgets.py @@ -0,0 +1,1771 @@ +import functools +import io +from unittest import mock + +import matplotlib as mpl +from matplotlib.backend_bases import MouseEvent +import matplotlib.colors as mcolors +import matplotlib.widgets as widgets +import matplotlib.pyplot as plt +from matplotlib.patches import Rectangle +from matplotlib.lines import Line2D +from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.testing.widgets import (click_and_drag, do_event, get_ax, + mock_event, noop) + +import numpy as np +from numpy.testing import assert_allclose + +import pytest + + +@pytest.fixture +def ax(): + return get_ax() + + +def test_save_blitted_widget_as_pdf(): + from matplotlib.widgets import CheckButtons, RadioButtons + from matplotlib.cbook import _get_running_interactive_framework + if _get_running_interactive_framework() not in ['headless', None]: + pytest.xfail("Callback exceptions are not raised otherwise.") + + fig, ax = plt.subplots( + nrows=2, ncols=2, figsize=(5, 2), width_ratios=[1, 2] + ) + default_rb = RadioButtons(ax[0, 0], ['Apples', 'Oranges']) + styled_rb = RadioButtons( + ax[0, 1], ['Apples', 'Oranges'], + label_props={'color': ['red', 'orange'], + 'fontsize': [16, 20]}, + radio_props={'edgecolor': ['red', 'orange'], + 'facecolor': ['mistyrose', 'peachpuff']} + ) + + default_cb = CheckButtons(ax[1, 0], ['Apples', 'Oranges'], + actives=[True, True]) + styled_cb = CheckButtons( + ax[1, 1], ['Apples', 'Oranges'], + actives=[True, True], + label_props={'color': ['red', 'orange'], + 'fontsize': [16, 20]}, + frame_props={'edgecolor': ['red', 'orange'], + 'facecolor': ['mistyrose', 'peachpuff']}, + check_props={'color': ['darkred', 'darkorange']} + ) + + ax[0, 0].set_title('Default') + ax[0, 1].set_title('Stylized') + # force an Agg render + fig.canvas.draw() + # force a pdf save + with io.BytesIO() as result_after: + fig.savefig(result_after, format='pdf') + + +@pytest.mark.parametrize('kwargs', [ + dict(), + dict(useblit=True, button=1), + dict(minspanx=10, minspany=10, spancoords='pixels'), + dict(props=dict(fill=True)), +]) +def test_rectangle_selector(ax, kwargs): + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.RectangleSelector(ax, onselect, **kwargs) + do_event(tool, 'press', xdata=100, ydata=100, button=1) + do_event(tool, 'onmove', xdata=199, ydata=199, button=1) + + # purposely drag outside of axis for release + do_event(tool, 'release', xdata=250, ydata=250, button=1) + + if kwargs.get('drawtype', None) not in ['line', 'none']: + assert_allclose(tool.geometry, + [[100., 100, 199, 199, 100], + [100, 199, 199, 100, 100]], + err_msg=tool.geometry) + + onselect.assert_called_once() + (epress, erelease), kwargs = onselect.call_args + assert epress.xdata == 100 + assert epress.ydata == 100 + assert erelease.xdata == 199 + assert erelease.ydata == 199 + assert kwargs == {} + + +@pytest.mark.parametrize('spancoords', ['data', 'pixels']) +@pytest.mark.parametrize('minspanx, x1', [[0, 10], [1, 10.5], [1, 11]]) +@pytest.mark.parametrize('minspany, y1', [[0, 10], [1, 10.5], [1, 11]]) +def test_rectangle_minspan(ax, spancoords, minspanx, x1, minspany, y1): + + onselect = mock.Mock(spec=noop, return_value=None) + + x0, y0 = (10, 10) + if spancoords == 'pixels': + minspanx, minspany = (ax.transData.transform((x1, y1)) - + ax.transData.transform((x0, y0))) + + tool = widgets.RectangleSelector(ax, onselect, interactive=True, + spancoords=spancoords, + minspanx=minspanx, minspany=minspany) + # Too small to create a selector + click_and_drag(tool, start=(x0, x1), end=(y0, y1)) + assert not tool._selection_completed + onselect.assert_not_called() + + click_and_drag(tool, start=(20, 20), end=(30, 30)) + assert tool._selection_completed + onselect.assert_called_once() + + # Too small to create a selector. Should clear existing selector, and + # trigger onselect because there was a preexisting selector + onselect.reset_mock() + click_and_drag(tool, start=(x0, y0), end=(x1, y1)) + assert not tool._selection_completed + onselect.assert_called_once() + (epress, erelease), kwargs = onselect.call_args + assert epress.xdata == x0 + assert epress.ydata == y0 + assert erelease.xdata == x1 + assert erelease.ydata == y1 + assert kwargs == {} + + +def test_deprecation_selector_visible_attribute(ax): + tool = widgets.RectangleSelector(ax, lambda *args: None) + + assert tool.get_visible() + + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="was deprecated in Matplotlib 3.8"): + tool.visible + + +@pytest.mark.parametrize('drag_from_anywhere, new_center', + [[True, (60, 75)], + [False, (30, 20)]]) +def test_rectangle_drag(ax, drag_from_anywhere, new_center): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True, + drag_from_anywhere=drag_from_anywhere) + # Create rectangle + click_and_drag(tool, start=(0, 10), end=(100, 120)) + assert tool.center == (50, 65) + # Drag inside rectangle, but away from centre handle + # + # If drag_from_anywhere == True, this will move the rectangle by (10, 10), + # giving it a new center of (60, 75) + # + # If drag_from_anywhere == False, this will create a new rectangle with + # center (30, 20) + click_and_drag(tool, start=(25, 15), end=(35, 25)) + assert tool.center == new_center + # Check that in both cases, dragging outside the rectangle draws a new + # rectangle + click_and_drag(tool, start=(175, 185), end=(185, 195)) + assert tool.center == (180, 190) + + +def test_rectangle_selector_set_props_handle_props(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True, + props=dict(facecolor='b', alpha=0.2), + handle_props=dict(alpha=0.5)) + # Create rectangle + click_and_drag(tool, start=(0, 10), end=(100, 120)) + + artist = tool._selection_artist + assert artist.get_facecolor() == mcolors.to_rgba('b', alpha=0.2) + tool.set_props(facecolor='r', alpha=0.3) + assert artist.get_facecolor() == mcolors.to_rgba('r', alpha=0.3) + + for artist in tool._handles_artists: + assert artist.get_markeredgecolor() == 'black' + assert artist.get_alpha() == 0.5 + tool.set_handle_props(markeredgecolor='r', alpha=0.3) + for artist in tool._handles_artists: + assert artist.get_markeredgecolor() == 'r' + assert artist.get_alpha() == 0.3 + + +def test_rectangle_resize(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Create rectangle + click_and_drag(tool, start=(0, 10), end=(100, 120)) + assert tool.extents == (0.0, 100.0, 10.0, 120.0) + + # resize NE handle + extents = tool.extents + xdata, ydata = extents[1], extents[3] + xdata_new, ydata_new = xdata + 10, ydata + 5 + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert tool.extents == (extents[0], xdata_new, extents[2], ydata_new) + + # resize E handle + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdata_new, ydata_new = xdata + 10, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert tool.extents == (extents[0], xdata_new, extents[2], extents[3]) + + # resize W handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdata_new, ydata_new = xdata + 15, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert tool.extents == (xdata_new, extents[1], extents[2], extents[3]) + + # resize SW handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + xdata_new, ydata_new = xdata + 20, ydata + 25 + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert tool.extents == (xdata_new, extents[1], ydata_new, extents[3]) + + +def test_rectangle_add_state(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Create rectangle + click_and_drag(tool, start=(70, 65), end=(125, 130)) + + with pytest.raises(ValueError): + tool.add_state('unsupported_state') + + with pytest.raises(ValueError): + tool.add_state('clear') + tool.add_state('move') + tool.add_state('square') + tool.add_state('center') + + +@pytest.mark.parametrize('add_state', [True, False]) +def test_rectangle_resize_center(ax, add_state): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Create rectangle + click_and_drag(tool, start=(70, 65), end=(125, 130)) + assert tool.extents == (70.0, 125.0, 65.0, 130.0) + + if add_state: + tool.add_state('center') + use_key = None + else: + use_key = 'control' + + # resize NE handle + extents = tool.extents + xdata, ydata = extents[1], extents[3] + xdiff, ydiff = 10, 5 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0] - xdiff, xdata_new, + extents[2] - ydiff, ydata_new) + + # resize E handle + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 10 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0] - xdiff, xdata_new, + extents[2], extents[3]) + + # resize E handle negative diff + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -20 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0] - xdiff, xdata_new, + extents[2], extents[3]) + + # resize W handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 15 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (xdata_new, extents[1] - xdiff, + extents[2], extents[3]) + + # resize W handle negative diff + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -25 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (xdata_new, extents[1] - xdiff, + extents[2], extents[3]) + + # resize SW handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + xdiff, ydiff = 20, 25 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (xdata_new, extents[1] - xdiff, + ydata_new, extents[3] - ydiff) + + +@pytest.mark.parametrize('add_state', [True, False]) +def test_rectangle_resize_square(ax, add_state): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Create rectangle + click_and_drag(tool, start=(70, 65), end=(120, 115)) + assert tool.extents == (70.0, 120.0, 65.0, 115.0) + + if add_state: + tool.add_state('square') + use_key = None + else: + use_key = 'shift' + + # resize NE handle + extents = tool.extents + xdata, ydata = extents[1], extents[3] + xdiff, ydiff = 10, 5 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0], xdata_new, + extents[2], extents[3] + xdiff) + + # resize E handle + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 10 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0], xdata_new, + extents[2], extents[3] + xdiff) + + # resize E handle negative diff + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -20 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0], xdata_new, + extents[2], extents[3] + xdiff) + + # resize W handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 15 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (xdata_new, extents[1], + extents[2], extents[3] - xdiff) + + # resize W handle negative diff + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -25 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (xdata_new, extents[1], + extents[2], extents[3] - xdiff) + + # resize SW handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + xdiff, ydiff = 20, 25 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new), + key=use_key) + assert tool.extents == (extents[0] + ydiff, extents[1], + ydata_new, extents[3]) + + +def test_rectangle_resize_square_center(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Create rectangle + click_and_drag(tool, start=(70, 65), end=(120, 115)) + tool.add_state('square') + tool.add_state('center') + assert_allclose(tool.extents, (70.0, 120.0, 65.0, 115.0)) + + # resize NE handle + extents = tool.extents + xdata, ydata = extents[1], extents[3] + xdiff, ydiff = 10, 5 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (extents[0] - xdiff, xdata_new, + extents[2] - xdiff, extents[3] + xdiff)) + + # resize E handle + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 10 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (extents[0] - xdiff, xdata_new, + extents[2] - xdiff, extents[3] + xdiff)) + + # resize E handle negative diff + extents = tool.extents + xdata, ydata = extents[1], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -20 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (extents[0] - xdiff, xdata_new, + extents[2] - xdiff, extents[3] + xdiff)) + + # resize W handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = 5 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (xdata_new, extents[1] - xdiff, + extents[2] + xdiff, extents[3] - xdiff)) + + # resize W handle negative diff + extents = tool.extents + xdata, ydata = extents[0], extents[2] + (extents[3] - extents[2]) / 2 + xdiff = -25 + xdata_new, ydata_new = xdata + xdiff, ydata + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (xdata_new, extents[1] - xdiff, + extents[2] + xdiff, extents[3] - xdiff)) + + # resize SW handle + extents = tool.extents + xdata, ydata = extents[0], extents[2] + xdiff, ydiff = 20, 25 + xdata_new, ydata_new = xdata + xdiff, ydata + ydiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, (extents[0] + ydiff, extents[1] - ydiff, + ydata_new, extents[3] - ydiff)) + + +@pytest.mark.parametrize('selector_class', + [widgets.RectangleSelector, widgets.EllipseSelector]) +def test_rectangle_rotate(ax, selector_class): + tool = selector_class(ax, onselect=noop, interactive=True) + # Draw rectangle + click_and_drag(tool, start=(100, 100), end=(130, 140)) + assert tool.extents == (100, 130, 100, 140) + assert len(tool._state) == 0 + + # Rotate anticlockwise using top-right corner + do_event(tool, 'on_key_press', key='r') + assert tool._state == {'rotate'} + assert len(tool._state) == 1 + click_and_drag(tool, start=(130, 140), end=(120, 145)) + do_event(tool, 'on_key_press', key='r') + assert len(tool._state) == 0 + # Extents shouldn't change (as shape of rectangle hasn't changed) + assert tool.extents == (100, 130, 100, 140) + assert_allclose(tool.rotation, 25.56, atol=0.01) + tool.rotation = 45 + assert tool.rotation == 45 + # Corners should move + assert_allclose(tool.corners, + np.array([[118.53, 139.75, 111.46, 90.25], + [95.25, 116.46, 144.75, 123.54]]), atol=0.01) + + # Scale using top-right corner + click_and_drag(tool, start=(110, 145), end=(110, 160)) + assert_allclose(tool.extents, (100, 139.75, 100, 151.82), atol=0.01) + + if selector_class == widgets.RectangleSelector: + with pytest.raises(ValueError): + tool._selection_artist.rotation_point = 'unvalid_value' + + +def test_rectangle_add_remove_set(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + # Draw rectangle + click_and_drag(tool, start=(100, 100), end=(130, 140)) + assert tool.extents == (100, 130, 100, 140) + assert len(tool._state) == 0 + for state in ['rotate', 'square', 'center']: + tool.add_state(state) + assert len(tool._state) == 1 + tool.remove_state(state) + assert len(tool._state) == 0 + + +@pytest.mark.parametrize('use_data_coordinates', [False, True]) +def test_rectangle_resize_square_center_aspect(ax, use_data_coordinates): + ax.set_aspect(0.8) + + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True, + use_data_coordinates=use_data_coordinates) + # Create rectangle + click_and_drag(tool, start=(70, 65), end=(120, 115)) + assert tool.extents == (70.0, 120.0, 65.0, 115.0) + tool.add_state('square') + tool.add_state('center') + + if use_data_coordinates: + # resize E handle + extents = tool.extents + xdata, ydata, width = extents[1], extents[3], extents[1] - extents[0] + xdiff, ycenter = 10, extents[2] + (extents[3] - extents[2]) / 2 + xdata_new, ydata_new = xdata + xdiff, ydata + ychange = width / 2 + xdiff + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new, + ycenter - ychange, ycenter + ychange]) + else: + # resize E handle + extents = tool.extents + xdata, ydata = extents[1], extents[3] + xdiff = 10 + xdata_new, ydata_new = xdata + xdiff, ydata + ychange = xdiff * 1 / tool._aspect_ratio_correction + click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new)) + assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new, + 46.25, 133.75]) + + +def test_ellipse(ax): + """For ellipse, test out the key modifiers""" + tool = widgets.EllipseSelector(ax, onselect=noop, + grab_range=10, interactive=True) + tool.extents = (100, 150, 100, 150) + + # drag the rectangle + click_and_drag(tool, start=(125, 125), end=(145, 145)) + assert tool.extents == (120, 170, 120, 170) + + # create from center + click_and_drag(tool, start=(100, 100), end=(125, 125), key='control') + assert tool.extents == (75, 125, 75, 125) + + # create a square + click_and_drag(tool, start=(10, 10), end=(35, 30), key='shift') + extents = [int(e) for e in tool.extents] + assert extents == [10, 35, 10, 35] + + # create a square from center + click_and_drag(tool, start=(100, 100), end=(125, 130), key='ctrl+shift') + extents = [int(e) for e in tool.extents] + assert extents == [70, 130, 70, 130] + + assert tool.geometry.shape == (2, 73) + assert_allclose(tool.geometry[:, 0], [70., 100]) + + +def test_rectangle_handles(ax): + tool = widgets.RectangleSelector(ax, onselect=noop, + grab_range=10, + interactive=True, + handle_props={'markerfacecolor': 'r', + 'markeredgecolor': 'b'}) + tool.extents = (100, 150, 100, 150) + + assert_allclose(tool.corners, ((100, 150, 150, 100), (100, 100, 150, 150))) + assert tool.extents == (100, 150, 100, 150) + assert_allclose(tool.edge_centers, + ((100, 125.0, 150, 125.0), (125.0, 100, 125.0, 150))) + assert tool.extents == (100, 150, 100, 150) + + # grab a corner and move it + click_and_drag(tool, start=(100, 100), end=(120, 120)) + assert tool.extents == (120, 150, 120, 150) + + # grab the center and move it + click_and_drag(tool, start=(132, 132), end=(120, 120)) + assert tool.extents == (108, 138, 108, 138) + + # create a new rectangle + click_and_drag(tool, start=(10, 10), end=(100, 100)) + assert tool.extents == (10, 100, 10, 100) + + # Check that marker_props worked. + assert mcolors.same_color( + tool._corner_handles.artists[0].get_markerfacecolor(), 'r') + assert mcolors.same_color( + tool._corner_handles.artists[0].get_markeredgecolor(), 'b') + + +@pytest.mark.parametrize('interactive', [True, False]) +def test_rectangle_selector_onselect(ax, interactive): + # check when press and release events take place at the same position + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.RectangleSelector(ax, onselect, interactive=interactive) + # move outside of axis + click_and_drag(tool, start=(100, 110), end=(150, 120)) + + onselect.assert_called_once() + assert tool.extents == (100.0, 150.0, 110.0, 120.0) + + onselect.reset_mock() + click_and_drag(tool, start=(10, 100), end=(10, 100)) + onselect.assert_called_once() + + +@pytest.mark.parametrize('ignore_event_outside', [True, False]) +def test_rectangle_selector_ignore_outside(ax, ignore_event_outside): + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.RectangleSelector(ax, onselect, + ignore_event_outside=ignore_event_outside) + click_and_drag(tool, start=(100, 110), end=(150, 120)) + onselect.assert_called_once() + assert tool.extents == (100.0, 150.0, 110.0, 120.0) + + onselect.reset_mock() + # Trigger event outside of span + click_and_drag(tool, start=(150, 150), end=(160, 160)) + if ignore_event_outside: + # event have been ignored and span haven't changed. + onselect.assert_not_called() + assert tool.extents == (100.0, 150.0, 110.0, 120.0) + else: + # A new shape is created + onselect.assert_called_once() + assert tool.extents == (150.0, 160.0, 150.0, 160.0) + + +@pytest.mark.parametrize('orientation, onmove_callback, kwargs', [ + ('horizontal', False, dict(minspan=10, useblit=True)), + ('vertical', True, dict(button=1)), + ('horizontal', False, dict(props=dict(fill=True))), + ('horizontal', False, dict(interactive=True)), +]) +def test_span_selector(ax, orientation, onmove_callback, kwargs): + onselect = mock.Mock(spec=noop, return_value=None) + onmove = mock.Mock(spec=noop, return_value=None) + if onmove_callback: + kwargs['onmove_callback'] = onmove + + # While at it, also test that span selectors work in the presence of twin axes on + # top of the axes that contain the selector. Note that we need to unforce the axes + # aspect here, otherwise the twin axes forces the original axes' limits (to respect + # aspect=1) which makes some of the values below go out of bounds. + ax.set_aspect("auto") + tax = ax.twinx() + + tool = widgets.SpanSelector(ax, onselect, orientation, **kwargs) + do_event(tool, 'press', xdata=100, ydata=100, button=1) + # move outside of axis + do_event(tool, 'onmove', xdata=199, ydata=199, button=1) + do_event(tool, 'release', xdata=250, ydata=250, button=1) + + onselect.assert_called_once_with(100, 199) + if onmove_callback: + onmove.assert_called_once_with(100, 199) + + +@pytest.mark.parametrize('interactive', [True, False]) +def test_span_selector_onselect(ax, interactive): + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.SpanSelector(ax, onselect, 'horizontal', + interactive=interactive) + # move outside of axis + click_and_drag(tool, start=(100, 100), end=(150, 100)) + onselect.assert_called_once() + assert tool.extents == (100, 150) + + onselect.reset_mock() + click_and_drag(tool, start=(10, 100), end=(10, 100)) + onselect.assert_called_once() + + +@pytest.mark.parametrize('ignore_event_outside', [True, False]) +def test_span_selector_ignore_outside(ax, ignore_event_outside): + onselect = mock.Mock(spec=noop, return_value=None) + onmove = mock.Mock(spec=noop, return_value=None) + + tool = widgets.SpanSelector(ax, onselect, 'horizontal', + onmove_callback=onmove, + ignore_event_outside=ignore_event_outside) + click_and_drag(tool, start=(100, 100), end=(125, 125)) + onselect.assert_called_once() + onmove.assert_called_once() + assert tool.extents == (100, 125) + + onselect.reset_mock() + onmove.reset_mock() + # Trigger event outside of span + click_and_drag(tool, start=(150, 150), end=(160, 160)) + if ignore_event_outside: + # event have been ignored and span haven't changed. + onselect.assert_not_called() + onmove.assert_not_called() + assert tool.extents == (100, 125) + else: + # A new shape is created + onselect.assert_called_once() + onmove.assert_called_once() + assert tool.extents == (150, 160) + + +@pytest.mark.parametrize('drag_from_anywhere', [True, False]) +def test_span_selector_drag(ax, drag_from_anywhere): + # Create span + tool = widgets.SpanSelector(ax, onselect=noop, direction='horizontal', + interactive=True, + drag_from_anywhere=drag_from_anywhere) + click_and_drag(tool, start=(10, 10), end=(100, 120)) + assert tool.extents == (10, 100) + # Drag inside span + # + # If drag_from_anywhere == True, this will move the span by 10, + # giving new value extents = 20, 110 + # + # If drag_from_anywhere == False, this will create a new span with + # value extents = 25, 35 + click_and_drag(tool, start=(25, 15), end=(35, 25)) + if drag_from_anywhere: + assert tool.extents == (20, 110) + else: + assert tool.extents == (25, 35) + + # Check that in both cases, dragging outside the span draws a new span + click_and_drag(tool, start=(175, 185), end=(185, 195)) + assert tool.extents == (175, 185) + + +def test_span_selector_direction(ax): + tool = widgets.SpanSelector(ax, onselect=noop, direction='horizontal', + interactive=True) + assert tool.direction == 'horizontal' + assert tool._edge_handles.direction == 'horizontal' + + with pytest.raises(ValueError): + tool = widgets.SpanSelector(ax, onselect=noop, + direction='invalid_direction') + + tool.direction = 'vertical' + assert tool.direction == 'vertical' + assert tool._edge_handles.direction == 'vertical' + + with pytest.raises(ValueError): + tool.direction = 'invalid_string' + + +def test_span_selector_set_props_handle_props(ax): + tool = widgets.SpanSelector(ax, onselect=noop, direction='horizontal', + interactive=True, + props=dict(facecolor='b', alpha=0.2), + handle_props=dict(alpha=0.5)) + # Create rectangle + click_and_drag(tool, start=(0, 10), end=(100, 120)) + + artist = tool._selection_artist + assert artist.get_facecolor() == mcolors.to_rgba('b', alpha=0.2) + tool.set_props(facecolor='r', alpha=0.3) + assert artist.get_facecolor() == mcolors.to_rgba('r', alpha=0.3) + + for artist in tool._handles_artists: + assert artist.get_color() == 'b' + assert artist.get_alpha() == 0.5 + tool.set_handle_props(color='r', alpha=0.3) + for artist in tool._handles_artists: + assert artist.get_color() == 'r' + assert artist.get_alpha() == 0.3 + + +@pytest.mark.parametrize('selector', ['span', 'rectangle']) +def test_selector_clear(ax, selector): + kwargs = dict(ax=ax, onselect=noop, interactive=True) + if selector == 'span': + Selector = widgets.SpanSelector + kwargs['direction'] = 'horizontal' + else: + Selector = widgets.RectangleSelector + + tool = Selector(**kwargs) + click_and_drag(tool, start=(10, 10), end=(100, 120)) + + # press-release event outside the selector to clear the selector + click_and_drag(tool, start=(130, 130), end=(130, 130)) + assert not tool._selection_completed + + kwargs['ignore_event_outside'] = True + tool = Selector(**kwargs) + assert tool.ignore_event_outside + click_and_drag(tool, start=(10, 10), end=(100, 120)) + + # press-release event outside the selector ignored + click_and_drag(tool, start=(130, 130), end=(130, 130)) + assert tool._selection_completed + + do_event(tool, 'on_key_press', key='escape') + assert not tool._selection_completed + + +@pytest.mark.parametrize('selector', ['span', 'rectangle']) +def test_selector_clear_method(ax, selector): + if selector == 'span': + tool = widgets.SpanSelector(ax, onselect=noop, direction='horizontal', + interactive=True, + ignore_event_outside=True) + else: + tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True) + click_and_drag(tool, start=(10, 10), end=(100, 120)) + assert tool._selection_completed + assert tool.get_visible() + if selector == 'span': + assert tool.extents == (10, 100) + + tool.clear() + assert not tool._selection_completed + assert not tool.get_visible() + + # Do another cycle of events to make sure we can + click_and_drag(tool, start=(10, 10), end=(50, 120)) + assert tool._selection_completed + assert tool.get_visible() + if selector == 'span': + assert tool.extents == (10, 50) + + +def test_span_selector_add_state(ax): + tool = widgets.SpanSelector(ax, noop, 'horizontal', + interactive=True) + + with pytest.raises(ValueError): + tool.add_state('unsupported_state') + with pytest.raises(ValueError): + tool.add_state('center') + with pytest.raises(ValueError): + tool.add_state('square') + + tool.add_state('move') + + +def test_tool_line_handle(ax): + positions = [20, 30, 50] + tool_line_handle = widgets.ToolLineHandles(ax, positions, 'horizontal', + useblit=False) + + for artist in tool_line_handle.artists: + assert not artist.get_animated() + assert not artist.get_visible() + + tool_line_handle.set_visible(True) + tool_line_handle.set_animated(True) + + for artist in tool_line_handle.artists: + assert artist.get_animated() + assert artist.get_visible() + + assert tool_line_handle.positions == positions + + +@pytest.mark.parametrize('direction', ("horizontal", "vertical")) +def test_span_selector_bound(direction): + fig, ax = plt.subplots(1, 1) + ax.plot([10, 20], [10, 30]) + ax.figure.canvas.draw() + x_bound = ax.get_xbound() + y_bound = ax.get_ybound() + + tool = widgets.SpanSelector(ax, print, direction, interactive=True) + assert ax.get_xbound() == x_bound + assert ax.get_ybound() == y_bound + + bound = x_bound if direction == 'horizontal' else y_bound + assert tool._edge_handles.positions == list(bound) + + press_data = (10.5, 11.5) + move_data = (11, 13) # Updating selector is done in onmove + release_data = move_data + click_and_drag(tool, start=press_data, end=move_data) + + assert ax.get_xbound() == x_bound + assert ax.get_ybound() == y_bound + + index = 0 if direction == 'horizontal' else 1 + handle_positions = [press_data[index], release_data[index]] + assert tool._edge_handles.positions == handle_positions + + +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +def test_span_selector_animated_artists_callback(): + """Check that the animated artists changed in callbacks are updated.""" + x = np.linspace(0, 2 * np.pi, 100) + values = np.sin(x) + + fig, ax = plt.subplots() + ln, = ax.plot(x, values, animated=True) + ln2, = ax.plot([], animated=True) + + # spin the event loop to let the backend process any pending operations + # before drawing artists + # See blitting tutorial + plt.pause(0.1) + ax.draw_artist(ln) + fig.canvas.blit(fig.bbox) + + def mean(vmin, vmax): + # Return mean of values in x between *vmin* and *vmax* + indmin, indmax = np.searchsorted(x, (vmin, vmax)) + v = values[indmin:indmax].mean() + ln2.set_data(x, np.full_like(x, v)) + + span = widgets.SpanSelector(ax, mean, direction='horizontal', + onmove_callback=mean, + interactive=True, + drag_from_anywhere=True, + useblit=True) + + # Add span selector and check that the line is draw after it was updated + # by the callback + press_data = [1, 2] + move_data = [2, 2] + do_event(span, 'press', xdata=press_data[0], ydata=press_data[1], button=1) + do_event(span, 'onmove', xdata=move_data[0], ydata=move_data[1], button=1) + assert span._get_animated_artists() == (ln, ln2) + assert ln.stale is False + assert ln2.stale + assert_allclose(ln2.get_ydata(), 0.9547335049088455) + span.update() + assert ln2.stale is False + + # Change span selector and check that the line is drawn/updated after its + # value was updated by the callback + press_data = [4, 0] + move_data = [5, 2] + release_data = [5, 2] + do_event(span, 'press', xdata=press_data[0], ydata=press_data[1], button=1) + do_event(span, 'onmove', xdata=move_data[0], ydata=move_data[1], button=1) + assert ln.stale is False + assert ln2.stale + assert_allclose(ln2.get_ydata(), -0.9424150707548072) + do_event(span, 'release', xdata=release_data[0], + ydata=release_data[1], button=1) + assert ln2.stale is False + + +def test_snapping_values_span_selector(ax): + def onselect(*args): + pass + + tool = widgets.SpanSelector(ax, onselect, direction='horizontal',) + snap_function = tool._snap + + snap_values = np.linspace(0, 5, 11) + values = np.array([-0.1, 0.1, 0.2, 0.5, 0.6, 0.7, 0.9, 4.76, 5.0, 5.5]) + expect = np.array([00.0, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 5.00, 5.0, 5.0]) + values = snap_function(values, snap_values) + assert_allclose(values, expect) + + +def test_span_selector_snap(ax): + def onselect(vmin, vmax): + ax._got_onselect = True + + snap_values = np.arange(50) * 4 + + tool = widgets.SpanSelector(ax, onselect, direction='horizontal', + snap_values=snap_values) + tool.extents = (17, 35) + assert tool.extents == (16, 36) + + tool.snap_values = None + assert tool.snap_values is None + tool.extents = (17, 35) + assert tool.extents == (17, 35) + + +@pytest.mark.parametrize('kwargs', [ + dict(), + dict(useblit=False, props=dict(color='red')), + dict(useblit=True, button=1), +]) +def test_lasso_selector(ax, kwargs): + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.LassoSelector(ax, onselect, **kwargs) + do_event(tool, 'press', xdata=100, ydata=100, button=1) + do_event(tool, 'onmove', xdata=125, ydata=125, button=1) + do_event(tool, 'release', xdata=150, ydata=150, button=1) + + onselect.assert_called_once_with([(100, 100), (125, 125), (150, 150)]) + + +def test_lasso_selector_set_props(ax): + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.LassoSelector(ax, onselect, props=dict(color='b', alpha=0.2)) + + artist = tool._selection_artist + assert mcolors.same_color(artist.get_color(), 'b') + assert artist.get_alpha() == 0.2 + tool.set_props(color='r', alpha=0.3) + assert mcolors.same_color(artist.get_color(), 'r') + assert artist.get_alpha() == 0.3 + + +def test_CheckButtons(ax): + check = widgets.CheckButtons(ax, ('a', 'b', 'c'), (True, False, True)) + assert check.get_status() == [True, False, True] + check.set_active(0) + assert check.get_status() == [False, False, True] + + cid = check.on_clicked(lambda: None) + check.disconnect(cid) + + +@pytest.mark.parametrize("toolbar", ["none", "toolbar2", "toolmanager"]) +def test_TextBox(ax, toolbar): + # Avoid "toolmanager is provisional" warning. + plt.rcParams._set("toolbar", toolbar) + + submit_event = mock.Mock(spec=noop, return_value=None) + text_change_event = mock.Mock(spec=noop, return_value=None) + tool = widgets.TextBox(ax, '') + tool.on_submit(submit_event) + tool.on_text_change(text_change_event) + + assert tool.text == '' + + do_event(tool, '_click') + + tool.set_val('x**2') + + assert tool.text == 'x**2' + assert text_change_event.call_count == 1 + + tool.begin_typing() + tool.stop_typing() + + assert submit_event.call_count == 2 + + do_event(tool, '_click', xdata=.5, ydata=.5) # Ensure the click is in the axes. + do_event(tool, '_keypress', key='+') + do_event(tool, '_keypress', key='5') + + assert text_change_event.call_count == 3 + + +@image_comparison(['check_radio_buttons.png'], style='mpl20', remove_text=True) +def test_check_radio_buttons_image(): + ax = get_ax() + fig = ax.figure + fig.subplots_adjust(left=0.3) + + rax1 = fig.add_axes((0.05, 0.7, 0.2, 0.15)) + rb1 = widgets.RadioButtons(rax1, ('Radio 1', 'Radio 2', 'Radio 3')) + with pytest.warns(DeprecationWarning, + match='The circles attribute was deprecated'): + rb1.circles # Trigger the old-style elliptic radiobuttons. + + rax2 = fig.add_axes((0.05, 0.5, 0.2, 0.15)) + cb1 = widgets.CheckButtons(rax2, ('Check 1', 'Check 2', 'Check 3'), + (False, True, True)) + with pytest.warns(DeprecationWarning, + match='The rectangles attribute was deprecated'): + cb1.rectangles # Trigger old-style Rectangle check boxes + + rax3 = fig.add_axes((0.05, 0.3, 0.2, 0.15)) + rb3 = widgets.RadioButtons( + rax3, ('Radio 1', 'Radio 2', 'Radio 3'), + label_props={'fontsize': [8, 12, 16], + 'color': ['red', 'green', 'blue']}, + radio_props={'edgecolor': ['red', 'green', 'blue'], + 'facecolor': ['mistyrose', 'palegreen', 'lightblue']}) + + rax4 = fig.add_axes((0.05, 0.1, 0.2, 0.15)) + cb4 = widgets.CheckButtons( + rax4, ('Check 1', 'Check 2', 'Check 3'), (False, True, True), + label_props={'fontsize': [8, 12, 16], + 'color': ['red', 'green', 'blue']}, + frame_props={'edgecolor': ['red', 'green', 'blue'], + 'facecolor': ['mistyrose', 'palegreen', 'lightblue']}, + check_props={'color': ['red', 'green', 'blue']}) + + +@check_figures_equal(extensions=["png"]) +def test_radio_buttons(fig_test, fig_ref): + widgets.RadioButtons(fig_test.subplots(), ["tea", "coffee"]) + ax = fig_ref.add_subplot(xticks=[], yticks=[]) + ax.scatter([.15, .15], [2/3, 1/3], transform=ax.transAxes, + s=(plt.rcParams["font.size"] / 2) ** 2, c=["C0", "none"]) + ax.text(.25, 2/3, "tea", transform=ax.transAxes, va="center") + ax.text(.25, 1/3, "coffee", transform=ax.transAxes, va="center") + + +@check_figures_equal(extensions=['png']) +def test_radio_buttons_props(fig_test, fig_ref): + label_props = {'color': ['red'], 'fontsize': [24]} + radio_props = {'facecolor': 'green', 'edgecolor': 'blue', 'linewidth': 2} + + widgets.RadioButtons(fig_ref.subplots(), ['tea', 'coffee'], + label_props=label_props, radio_props=radio_props) + + cb = widgets.RadioButtons(fig_test.subplots(), ['tea', 'coffee']) + cb.set_label_props(label_props) + # Setting the label size automatically increases default marker size, so we + # need to do that here as well. + cb.set_radio_props({**radio_props, 's': (24 / 2)**2}) + + +def test_radio_button_active_conflict(ax): + with pytest.warns(UserWarning, + match=r'Both the \*activecolor\* parameter'): + rb = widgets.RadioButtons(ax, ['tea', 'coffee'], activecolor='red', + radio_props={'facecolor': 'green'}) + # *radio_props*' facecolor wins over *activecolor* + assert mcolors.same_color(rb._buttons.get_facecolor(), ['green', 'none']) + + +@check_figures_equal(extensions=['png']) +def test_radio_buttons_activecolor_change(fig_test, fig_ref): + widgets.RadioButtons(fig_ref.subplots(), ['tea', 'coffee'], + activecolor='green') + + # Test property setter. + cb = widgets.RadioButtons(fig_test.subplots(), ['tea', 'coffee'], + activecolor='red') + cb.activecolor = 'green' + + +@check_figures_equal(extensions=["png"]) +def test_check_buttons(fig_test, fig_ref): + widgets.CheckButtons(fig_test.subplots(), ["tea", "coffee"], [True, True]) + ax = fig_ref.add_subplot(xticks=[], yticks=[]) + ax.scatter([.15, .15], [2/3, 1/3], marker='s', transform=ax.transAxes, + s=(plt.rcParams["font.size"] / 2) ** 2, c=["none", "none"]) + ax.scatter([.15, .15], [2/3, 1/3], marker='x', transform=ax.transAxes, + s=(plt.rcParams["font.size"] / 2) ** 2, c=["k", "k"]) + ax.text(.25, 2/3, "tea", transform=ax.transAxes, va="center") + ax.text(.25, 1/3, "coffee", transform=ax.transAxes, va="center") + + +@check_figures_equal(extensions=['png']) +def test_check_button_props(fig_test, fig_ref): + label_props = {'color': ['red'], 'fontsize': [24]} + frame_props = {'facecolor': 'green', 'edgecolor': 'blue', 'linewidth': 2} + check_props = {'facecolor': 'red', 'linewidth': 2} + + widgets.CheckButtons(fig_ref.subplots(), ['tea', 'coffee'], [True, True], + label_props=label_props, frame_props=frame_props, + check_props=check_props) + + cb = widgets.CheckButtons(fig_test.subplots(), ['tea', 'coffee'], + [True, True]) + cb.set_label_props(label_props) + # Setting the label size automatically increases default marker size, so we + # need to do that here as well. + cb.set_frame_props({**frame_props, 's': (24 / 2)**2}) + # FIXME: Axes.scatter promotes facecolor to edgecolor on unfilled markers, + # but Collection.update doesn't do that (it forgot the marker already). + # This means we cannot pass facecolor to both setters directly. + check_props['edgecolor'] = check_props.pop('facecolor') + cb.set_check_props({**check_props, 's': (24 / 2)**2}) + + +@check_figures_equal(extensions=["png"]) +def test_check_buttons_rectangles(fig_test, fig_ref): + # Test should be removed once .rectangles is removed + cb = widgets.CheckButtons(fig_test.subplots(), ["", ""], + [False, False]) + with pytest.warns(DeprecationWarning, + match='The rectangles attribute was deprecated'): + cb.rectangles + ax = fig_ref.add_subplot(xticks=[], yticks=[]) + ys = [2/3, 1/3] + dy = 1/3 + w, h = dy / 2, dy / 2 + rectangles = [ + Rectangle(xy=(0.05, ys[i] - h / 2), width=w, height=h, + edgecolor="black", + facecolor="none", + transform=ax.transAxes + ) + for i, y in enumerate(ys) + ] + for rectangle in rectangles: + ax.add_patch(rectangle) + + +@check_figures_equal(extensions=["png"]) +def test_check_buttons_lines(fig_test, fig_ref): + # Test should be removed once .lines is removed + cb = widgets.CheckButtons(fig_test.subplots(), ["", ""], [True, True]) + with pytest.warns(DeprecationWarning, + match='The lines attribute was deprecated'): + cb.lines + for rectangle in cb._rectangles: + rectangle.set_visible(False) + ax = fig_ref.add_subplot(xticks=[], yticks=[]) + ys = [2/3, 1/3] + dy = 1/3 + w, h = dy / 2, dy / 2 + lineparams = {'color': 'k', 'linewidth': 1.25, + 'transform': ax.transAxes, + 'solid_capstyle': 'butt'} + for i, y in enumerate(ys): + x, y = 0.05, y - h / 2 + l1 = Line2D([x, x + w], [y + h, y], **lineparams) + l2 = Line2D([x, x + w], [y, y + h], **lineparams) + + l1.set_visible(True) + l2.set_visible(True) + ax.add_line(l1) + ax.add_line(l2) + + +def test_slider_slidermin_slidermax_invalid(): + fig, ax = plt.subplots() + # test min/max with floats + with pytest.raises(ValueError): + widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + slidermin=10.0) + with pytest.raises(ValueError): + widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + slidermax=10.0) + + +def test_slider_slidermin_slidermax(): + fig, ax = plt.subplots() + slider_ = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=5.0) + + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=1.0, slidermin=slider_) + assert slider.val == slider_.val + + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=10.0, slidermax=slider_) + assert slider.val == slider_.val + + +def test_slider_valmin_valmax(): + fig, ax = plt.subplots() + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=-10.0) + assert slider.val == slider.valmin + + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=25.0) + assert slider.val == slider.valmax + + +def test_slider_valstep_snapping(): + fig, ax = plt.subplots() + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=11.4, valstep=1) + assert slider.val == 11 + + slider = widgets.Slider(ax=ax, label='', valmin=0.0, valmax=24.0, + valinit=11.4, valstep=[0, 1, 5.5, 19.7]) + assert slider.val == 5.5 + + +def test_slider_horizontal_vertical(): + fig, ax = plt.subplots() + slider = widgets.Slider(ax=ax, label='', valmin=0, valmax=24, + valinit=12, orientation='horizontal') + slider.set_val(10) + assert slider.val == 10 + # check the dimension of the slider patch in axes units + box = slider.poly.get_extents().transformed(ax.transAxes.inverted()) + assert_allclose(box.bounds, [0, .25, 10/24, .5]) + + fig, ax = plt.subplots() + slider = widgets.Slider(ax=ax, label='', valmin=0, valmax=24, + valinit=12, orientation='vertical') + slider.set_val(10) + assert slider.val == 10 + # check the dimension of the slider patch in axes units + box = slider.poly.get_extents().transformed(ax.transAxes.inverted()) + assert_allclose(box.bounds, [.25, 0, .5, 10/24]) + + +def test_slider_reset(): + fig, ax = plt.subplots() + slider = widgets.Slider(ax=ax, label='', valmin=0, valmax=1, valinit=.5) + slider.set_val(0.75) + slider.reset() + assert slider.val == 0.5 + + +@pytest.mark.parametrize("orientation", ["horizontal", "vertical"]) +def test_range_slider(orientation): + if orientation == "vertical": + idx = [1, 0, 3, 2] + else: + idx = [0, 1, 2, 3] + + fig, ax = plt.subplots() + + slider = widgets.RangeSlider( + ax=ax, label="", valmin=0.0, valmax=1.0, orientation=orientation, + valinit=[0.1, 0.34] + ) + box = slider.poly.get_extents().transformed(ax.transAxes.inverted()) + assert_allclose(box.get_points().flatten()[idx], [0.1, 0.25, 0.34, 0.75]) + + # Check initial value is set correctly + assert_allclose(slider.val, (0.1, 0.34)) + + def handle_positions(slider): + if orientation == "vertical": + return [h.get_ydata()[0] for h in slider._handles] + else: + return [h.get_xdata()[0] for h in slider._handles] + + slider.set_val((0.4, 0.6)) + assert_allclose(slider.val, (0.4, 0.6)) + assert_allclose(handle_positions(slider), (0.4, 0.6)) + + box = slider.poly.get_extents().transformed(ax.transAxes.inverted()) + assert_allclose(box.get_points().flatten()[idx], [0.4, .25, 0.6, .75]) + + slider.set_val((0.2, 0.1)) + assert_allclose(slider.val, (0.1, 0.2)) + assert_allclose(handle_positions(slider), (0.1, 0.2)) + + slider.set_val((-1, 10)) + assert_allclose(slider.val, (0, 1)) + assert_allclose(handle_positions(slider), (0, 1)) + + slider.reset() + assert_allclose(slider.val, (0.1, 0.34)) + assert_allclose(handle_positions(slider), (0.1, 0.34)) + + +@pytest.mark.parametrize("orientation", ["horizontal", "vertical"]) +def test_range_slider_same_init_values(orientation): + if orientation == "vertical": + idx = [1, 0, 3, 2] + else: + idx = [0, 1, 2, 3] + + fig, ax = plt.subplots() + + slider = widgets.RangeSlider( + ax=ax, label="", valmin=0.0, valmax=1.0, orientation=orientation, + valinit=[0, 0] + ) + box = slider.poly.get_extents().transformed(ax.transAxes.inverted()) + assert_allclose(box.get_points().flatten()[idx], [0, 0.25, 0, 0.75]) + + +def check_polygon_selector(event_sequence, expected_result, selections_count, + **kwargs): + """ + Helper function to test Polygon Selector. + + Parameters + ---------- + event_sequence : list of tuples (etype, dict()) + A sequence of events to perform. The sequence is a list of tuples + where the first element of the tuple is an etype (e.g., 'onmove', + 'press', etc.), and the second element of the tuple is a dictionary of + the arguments for the event (e.g., xdata=5, key='shift', etc.). + expected_result : list of vertices (xdata, ydata) + The list of vertices that are expected to result from the event + sequence. + selections_count : int + Wait for the tool to call its `onselect` function `selections_count` + times, before comparing the result to the `expected_result` + **kwargs + Keyword arguments are passed to PolygonSelector. + """ + ax = get_ax() + + onselect = mock.Mock(spec=noop, return_value=None) + + tool = widgets.PolygonSelector(ax, onselect, **kwargs) + + for (etype, event_args) in event_sequence: + do_event(tool, etype, **event_args) + + assert onselect.call_count == selections_count + assert onselect.call_args == ((expected_result, ), {}) + + +def polygon_place_vertex(xdata, ydata): + return [('onmove', dict(xdata=xdata, ydata=ydata)), + ('press', dict(xdata=xdata, ydata=ydata)), + ('release', dict(xdata=xdata, ydata=ydata))] + + +def polygon_remove_vertex(xdata, ydata): + return [('onmove', dict(xdata=xdata, ydata=ydata)), + ('press', dict(xdata=xdata, ydata=ydata, button=3)), + ('release', dict(xdata=xdata, ydata=ydata, button=3))] + + +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +def test_polygon_selector(draw_bounding_box): + check_selector = functools.partial( + check_polygon_selector, draw_bounding_box=draw_bounding_box) + + # Simple polygon + expected_result = [(50, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ] + check_selector(event_sequence, expected_result, 1) + + # Move first vertex before completing the polygon. + expected_result = [(75, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + ('on_key_press', dict(key='control')), + ('onmove', dict(xdata=50, ydata=50)), + ('press', dict(xdata=50, ydata=50)), + ('onmove', dict(xdata=75, ydata=50)), + ('release', dict(xdata=75, ydata=50)), + ('on_key_release', dict(key='control')), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(75, 50), + ] + check_selector(event_sequence, expected_result, 1) + + # Move first two vertices at once before completing the polygon. + expected_result = [(50, 75), (150, 75), (50, 150)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + ('on_key_press', dict(key='shift')), + ('onmove', dict(xdata=100, ydata=100)), + ('press', dict(xdata=100, ydata=100)), + ('onmove', dict(xdata=100, ydata=125)), + ('release', dict(xdata=100, ydata=125)), + ('on_key_release', dict(key='shift')), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 75), + ] + check_selector(event_sequence, expected_result, 1) + + # Move first vertex after completing the polygon. + expected_result = [(75, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ('onmove', dict(xdata=50, ydata=50)), + ('press', dict(xdata=50, ydata=50)), + ('onmove', dict(xdata=75, ydata=50)), + ('release', dict(xdata=75, ydata=50)), + ] + check_selector(event_sequence, expected_result, 2) + + # Move all vertices after completing the polygon. + expected_result = [(75, 75), (175, 75), (75, 175)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ('on_key_press', dict(key='shift')), + ('onmove', dict(xdata=100, ydata=100)), + ('press', dict(xdata=100, ydata=100)), + ('onmove', dict(xdata=125, ydata=125)), + ('release', dict(xdata=125, ydata=125)), + ('on_key_release', dict(key='shift')), + ] + check_selector(event_sequence, expected_result, 2) + + # Try to move a vertex and move all before placing any vertices. + expected_result = [(50, 50), (150, 50), (50, 150)] + event_sequence = [ + ('on_key_press', dict(key='control')), + ('onmove', dict(xdata=100, ydata=100)), + ('press', dict(xdata=100, ydata=100)), + ('onmove', dict(xdata=125, ydata=125)), + ('release', dict(xdata=125, ydata=125)), + ('on_key_release', dict(key='control')), + ('on_key_press', dict(key='shift')), + ('onmove', dict(xdata=100, ydata=100)), + ('press', dict(xdata=100, ydata=100)), + ('onmove', dict(xdata=125, ydata=125)), + ('release', dict(xdata=125, ydata=125)), + ('on_key_release', dict(key='shift')), + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ] + check_selector(event_sequence, expected_result, 1) + + # Try to place vertex out-of-bounds, then reset, and start a new polygon. + expected_result = [(50, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(250, 50), + ('on_key_press', dict(key='escape')), + ('on_key_release', dict(key='escape')), + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ] + check_selector(event_sequence, expected_result, 1) + + +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +def test_polygon_selector_set_props_handle_props(ax, draw_bounding_box): + tool = widgets.PolygonSelector(ax, onselect=noop, + props=dict(color='b', alpha=0.2), + handle_props=dict(alpha=0.5), + draw_bounding_box=draw_bounding_box) + + event_sequence = [ + *polygon_place_vertex(50, 50), + *polygon_place_vertex(150, 50), + *polygon_place_vertex(50, 150), + *polygon_place_vertex(50, 50), + ] + + for (etype, event_args) in event_sequence: + do_event(tool, etype, **event_args) + + artist = tool._selection_artist + assert artist.get_color() == 'b' + assert artist.get_alpha() == 0.2 + tool.set_props(color='r', alpha=0.3) + assert artist.get_color() == 'r' + assert artist.get_alpha() == 0.3 + + for artist in tool._handles_artists: + assert artist.get_color() == 'b' + assert artist.get_alpha() == 0.5 + tool.set_handle_props(color='r', alpha=0.3) + for artist in tool._handles_artists: + assert artist.get_color() == 'r' + assert artist.get_alpha() == 0.3 + + +@check_figures_equal() +def test_rect_visibility(fig_test, fig_ref): + # Check that requesting an invisible selector makes it invisible + ax_test = fig_test.subplots() + _ = fig_ref.subplots() + + tool = widgets.RectangleSelector(ax_test, onselect=noop, + props={'visible': False}) + tool.extents = (0.2, 0.8, 0.3, 0.7) + + +# Change the order that the extra point is inserted in +@pytest.mark.parametrize('idx', [1, 2, 3]) +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +def test_polygon_selector_remove(idx, draw_bounding_box): + verts = [(50, 50), (150, 50), (50, 150)] + event_sequence = [polygon_place_vertex(*verts[0]), + polygon_place_vertex(*verts[1]), + polygon_place_vertex(*verts[2]), + # Finish the polygon + polygon_place_vertex(*verts[0])] + # Add an extra point + event_sequence.insert(idx, polygon_place_vertex(200, 200)) + # Remove the extra point + event_sequence.append(polygon_remove_vertex(200, 200)) + # Flatten list of lists + event_sequence = sum(event_sequence, []) + check_polygon_selector(event_sequence, verts, 2, + draw_bounding_box=draw_bounding_box) + + +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +def test_polygon_selector_remove_first_point(draw_bounding_box): + verts = [(50, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(*verts[0]), + *polygon_place_vertex(*verts[1]), + *polygon_place_vertex(*verts[2]), + *polygon_place_vertex(*verts[0]), + *polygon_remove_vertex(*verts[0]), + ] + check_polygon_selector(event_sequence, verts[1:], 2, + draw_bounding_box=draw_bounding_box) + + +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +def test_polygon_selector_redraw(ax, draw_bounding_box): + verts = [(50, 50), (150, 50), (50, 150)] + event_sequence = [ + *polygon_place_vertex(*verts[0]), + *polygon_place_vertex(*verts[1]), + *polygon_place_vertex(*verts[2]), + *polygon_place_vertex(*verts[0]), + # Polygon completed, now remove first two verts. + *polygon_remove_vertex(*verts[1]), + *polygon_remove_vertex(*verts[2]), + # At this point the tool should be reset so we can add more vertices. + *polygon_place_vertex(*verts[1]), + ] + + tool = widgets.PolygonSelector(ax, onselect=noop, + draw_bounding_box=draw_bounding_box) + for (etype, event_args) in event_sequence: + do_event(tool, etype, **event_args) + # After removing two verts, only one remains, and the + # selector should be automatically resete + assert tool.verts == verts[0:2] + + +@pytest.mark.parametrize('draw_bounding_box', [False, True]) +@check_figures_equal(extensions=['png']) +def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box): + verts = [(0.1, 0.4), (0.5, 0.9), (0.3, 0.2)] + ax_test = fig_test.add_subplot() + + tool_test = widgets.PolygonSelector( + ax_test, onselect=noop, draw_bounding_box=draw_bounding_box) + tool_test.verts = verts + assert tool_test.verts == verts + + ax_ref = fig_ref.add_subplot() + tool_ref = widgets.PolygonSelector( + ax_ref, onselect=noop, draw_bounding_box=draw_bounding_box) + event_sequence = [ + *polygon_place_vertex(*verts[0]), + *polygon_place_vertex(*verts[1]), + *polygon_place_vertex(*verts[2]), + *polygon_place_vertex(*verts[0]), + ] + for (etype, event_args) in event_sequence: + do_event(tool_ref, etype, **event_args) + + +def test_polygon_selector_box(ax): + # Create a diamond (adjusting axes lims s.t. the diamond lies within axes limits). + ax.set(xlim=(-10, 50), ylim=(-10, 50)) + verts = [(20, 0), (0, 20), (20, 40), (40, 20)] + event_sequence = [ + *polygon_place_vertex(*verts[0]), + *polygon_place_vertex(*verts[1]), + *polygon_place_vertex(*verts[2]), + *polygon_place_vertex(*verts[3]), + *polygon_place_vertex(*verts[0]), + ] + + # Create selector + tool = widgets.PolygonSelector(ax, onselect=noop, draw_bounding_box=True) + for (etype, event_args) in event_sequence: + do_event(tool, etype, **event_args) + + # In order to trigger the correct callbacks, trigger events on the canvas + # instead of the individual tools + t = ax.transData + canvas = ax.figure.canvas + + # Scale to half size using the top right corner of the bounding box + MouseEvent( + "button_press_event", canvas, *t.transform((40, 40)), 1)._process() + MouseEvent( + "motion_notify_event", canvas, *t.transform((20, 20)))._process() + MouseEvent( + "button_release_event", canvas, *t.transform((20, 20)), 1)._process() + np.testing.assert_allclose( + tool.verts, [(10, 0), (0, 10), (10, 20), (20, 10)]) + + # Move using the center of the bounding box + MouseEvent( + "button_press_event", canvas, *t.transform((10, 10)), 1)._process() + MouseEvent( + "motion_notify_event", canvas, *t.transform((30, 30)))._process() + MouseEvent( + "button_release_event", canvas, *t.transform((30, 30)), 1)._process() + np.testing.assert_allclose( + tool.verts, [(30, 20), (20, 30), (30, 40), (40, 30)]) + + # Remove a point from the polygon and check that the box extents update + np.testing.assert_allclose( + tool._box.extents, (20.0, 40.0, 20.0, 40.0)) + + MouseEvent( + "button_press_event", canvas, *t.transform((30, 20)), 3)._process() + MouseEvent( + "button_release_event", canvas, *t.transform((30, 20)), 3)._process() + np.testing.assert_allclose( + tool.verts, [(20, 30), (30, 40), (40, 30)]) + np.testing.assert_allclose( + tool._box.extents, (20.0, 40.0, 30.0, 40.0)) + + +def test_polygon_selector_clear_method(ax): + onselect = mock.Mock(spec=noop, return_value=None) + tool = widgets.PolygonSelector(ax, onselect) + + for result in ([(50, 50), (150, 50), (50, 150), (50, 50)], + [(50, 50), (100, 50), (50, 150), (50, 50)]): + for x, y in result: + for etype, event_args in polygon_place_vertex(x, y): + do_event(tool, etype, **event_args) + + artist = tool._selection_artist + + assert tool._selection_completed + assert tool.get_visible() + assert artist.get_visible() + np.testing.assert_equal(artist.get_xydata(), result) + assert onselect.call_args == ((result[:-1],), {}) + + tool.clear() + assert not tool._selection_completed + np.testing.assert_equal(artist.get_xydata(), [(0, 0)]) + + +@pytest.mark.parametrize("horizOn", [False, True]) +@pytest.mark.parametrize("vertOn", [False, True]) +def test_MultiCursor(horizOn, vertOn): + (ax1, ax3) = plt.figure().subplots(2, sharex=True) + ax2 = plt.figure().subplots() + + # useblit=false to avoid having to draw the figure to cache the renderer + multi = widgets.MultiCursor( + None, (ax1, ax2), useblit=False, horizOn=horizOn, vertOn=vertOn + ) + + # Only two of the axes should have a line drawn on them. + assert len(multi.vlines) == 2 + assert len(multi.hlines) == 2 + + # mock a motion_notify_event + # Can't use `do_event` as that helper requires the widget + # to have a single .ax attribute. + event = mock_event(ax1, xdata=.5, ydata=.25) + multi.onmove(event) + # force a draw + draw event to exercise clear + ax1.figure.canvas.draw() + + # the lines in the first two ax should both move + for l in multi.vlines: + assert l.get_xdata() == (.5, .5) + for l in multi.hlines: + assert l.get_ydata() == (.25, .25) + # The relevant lines get turned on after move. + assert len([line for line in multi.vlines if line.get_visible()]) == ( + 2 if vertOn else 0) + assert len([line for line in multi.hlines if line.get_visible()]) == ( + 2 if horizOn else 0) + + # After toggling settings, the opposite lines should be visible after move. + multi.horizOn = not multi.horizOn + multi.vertOn = not multi.vertOn + event = mock_event(ax1, xdata=.5, ydata=.25) + multi.onmove(event) + assert len([line for line in multi.vlines if line.get_visible()]) == ( + 0 if vertOn else 2) + assert len([line for line in multi.hlines if line.get_visible()]) == ( + 0 if horizOn else 2) + + # test a move event in an Axes not part of the MultiCursor + # the lines in ax1 and ax2 should not have moved. + event = mock_event(ax3, xdata=.75, ydata=.75) + multi.onmove(event) + for l in multi.vlines: + assert l.get_xdata() == (.5, .5) + for l in multi.hlines: + assert l.get_ydata() == (.25, .25) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.py new file mode 100644 index 00000000..812eab58 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.py @@ -0,0 +1,368 @@ +r""" +Support for embedded TeX expressions in Matplotlib. + +Requirements: + +* LaTeX. +* \*Agg backends: dvipng>=1.6. +* PS backend: PSfrag, dvips, and Ghostscript>=9.0. +* PDF and SVG backends: if LuaTeX is present, it will be used to speed up some + post-processing steps, but note that it is not used to parse the TeX string + itself (only LaTeX is supported). + +To enable TeX rendering of all text in your Matplotlib figure, set +:rc:`text.usetex` to True. + +TeX and dvipng/dvips processing results are cached +in ~/.matplotlib/tex.cache for reuse between sessions. + +`TexManager.get_rgba` can also be used to directly obtain raster output as RGBA +NumPy arrays. +""" + +import functools +import hashlib +import logging +import os +from pathlib import Path +import subprocess +from tempfile import TemporaryDirectory + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook, dviread + +_log = logging.getLogger(__name__) + + +def _usepackage_if_not_loaded(package, *, option=None): + """ + Output LaTeX code that loads a package (possibly with an option) if it + hasn't been loaded yet. + + LaTeX cannot load twice a package with different options, so this helper + can be used to protect against users loading arbitrary packages/options in + their custom preamble. + """ + option = f"[{option}]" if option is not None else "" + return ( + r"\makeatletter" + r"\@ifpackageloaded{%(package)s}{}{\usepackage%(option)s{%(package)s}}" + r"\makeatother" + ) % {"package": package, "option": option} + + +class TexManager: + """ + Convert strings to dvi files using TeX, caching the results to a directory. + + The cache directory is called ``tex.cache`` and is located in the directory + returned by `.get_cachedir`. + + Repeated calls to this constructor always return the same instance. + """ + + texcache = _api.deprecate_privatize_attribute("3.8") + _texcache = os.path.join(mpl.get_cachedir(), 'tex.cache') + _grey_arrayd = {} + + _font_families = ('serif', 'sans-serif', 'cursive', 'monospace') + _font_preambles = { + 'new century schoolbook': r'\renewcommand{\rmdefault}{pnc}', + 'bookman': r'\renewcommand{\rmdefault}{pbk}', + 'times': r'\usepackage{mathptmx}', + 'palatino': r'\usepackage{mathpazo}', + 'zapf chancery': r'\usepackage{chancery}', + 'cursive': r'\usepackage{chancery}', + 'charter': r'\usepackage{charter}', + 'serif': '', + 'sans-serif': '', + 'helvetica': r'\usepackage{helvet}', + 'avant garde': r'\usepackage{avant}', + 'courier': r'\usepackage{courier}', + # Loading the type1ec package ensures that cm-super is installed, which + # is necessary for Unicode computer modern. (It also allows the use of + # computer modern at arbitrary sizes, but that's just a side effect.) + 'monospace': r'\usepackage{type1ec}', + 'computer modern roman': r'\usepackage{type1ec}', + 'computer modern sans serif': r'\usepackage{type1ec}', + 'computer modern typewriter': r'\usepackage{type1ec}', + } + _font_types = { + 'new century schoolbook': 'serif', + 'bookman': 'serif', + 'times': 'serif', + 'palatino': 'serif', + 'zapf chancery': 'cursive', + 'charter': 'serif', + 'helvetica': 'sans-serif', + 'avant garde': 'sans-serif', + 'courier': 'monospace', + 'computer modern roman': 'serif', + 'computer modern sans serif': 'sans-serif', + 'computer modern typewriter': 'monospace', + } + + @functools.lru_cache # Always return the same instance. + def __new__(cls): + Path(cls._texcache).mkdir(parents=True, exist_ok=True) + return object.__new__(cls) + + @classmethod + def _get_font_family_and_reduced(cls): + """Return the font family name and whether the font is reduced.""" + ff = mpl.rcParams['font.family'] + ff_val = ff[0].lower() if len(ff) == 1 else None + if len(ff) == 1 and ff_val in cls._font_families: + return ff_val, False + elif len(ff) == 1 and ff_val in cls._font_preambles: + return cls._font_types[ff_val], True + else: + _log.info('font.family must be one of (%s) when text.usetex is ' + 'True. serif will be used by default.', + ', '.join(cls._font_families)) + return 'serif', False + + @classmethod + def _get_font_preamble_and_command(cls): + requested_family, is_reduced_font = cls._get_font_family_and_reduced() + + preambles = {} + for font_family in cls._font_families: + if is_reduced_font and font_family == requested_family: + preambles[font_family] = cls._font_preambles[ + mpl.rcParams['font.family'][0].lower()] + else: + for font in mpl.rcParams['font.' + font_family]: + if font.lower() in cls._font_preambles: + preambles[font_family] = \ + cls._font_preambles[font.lower()] + _log.debug( + 'family: %s, font: %s, info: %s', + font_family, font, + cls._font_preambles[font.lower()]) + break + else: + _log.debug('%s font is not compatible with usetex.', + font) + else: + _log.info('No LaTeX-compatible font found for the %s font' + 'family in rcParams. Using default.', + font_family) + preambles[font_family] = cls._font_preambles[font_family] + + # The following packages and commands need to be included in the latex + # file's preamble: + cmd = {preambles[family] + for family in ['serif', 'sans-serif', 'monospace']} + if requested_family == 'cursive': + cmd.add(preambles['cursive']) + cmd.add(r'\usepackage{type1cm}') + preamble = '\n'.join(sorted(cmd)) + fontcmd = (r'\sffamily' if requested_family == 'sans-serif' else + r'\ttfamily' if requested_family == 'monospace' else + r'\rmfamily') + return preamble, fontcmd + + @classmethod + def get_basefile(cls, tex, fontsize, dpi=None): + """ + Return a filename based on a hash of the string, fontsize, and dpi. + """ + src = cls._get_tex_source(tex, fontsize) + str(dpi) + filehash = hashlib.md5(src.encode('utf-8')).hexdigest() + filepath = Path(cls._texcache) + + num_letters, num_levels = 2, 2 + for i in range(0, num_letters*num_levels, num_letters): + filepath = filepath / Path(filehash[i:i+2]) + + filepath.mkdir(parents=True, exist_ok=True) + return os.path.join(filepath, filehash) + + @classmethod + def get_font_preamble(cls): + """ + Return a string containing font configuration for the tex preamble. + """ + font_preamble, command = cls._get_font_preamble_and_command() + return font_preamble + + @classmethod + def get_custom_preamble(cls): + """Return a string containing user additions to the tex preamble.""" + return mpl.rcParams['text.latex.preamble'] + + @classmethod + def _get_tex_source(cls, tex, fontsize): + """Return the complete TeX source for processing a TeX string.""" + font_preamble, fontcmd = cls._get_font_preamble_and_command() + baselineskip = 1.25 * fontsize + return "\n".join([ + r"\documentclass{article}", + r"% Pass-through \mathdefault, which is used in non-usetex mode", + r"% to use the default text font but was historically suppressed", + r"% in usetex mode.", + r"\newcommand{\mathdefault}[1]{#1}", + font_preamble, + r"\usepackage[utf8]{inputenc}", + r"\DeclareUnicodeCharacter{2212}{\ensuremath{-}}", + r"% geometry is loaded before the custom preamble as ", + r"% convert_psfrags relies on a custom preamble to change the ", + r"% geometry.", + r"\usepackage[papersize=72in, margin=1in]{geometry}", + cls.get_custom_preamble(), + r"% Use `underscore` package to take care of underscores in text.", + r"% The [strings] option allows to use underscores in file names.", + _usepackage_if_not_loaded("underscore", option="strings"), + r"% Custom packages (e.g. newtxtext) may already have loaded ", + r"% textcomp with different options.", + _usepackage_if_not_loaded("textcomp"), + r"\pagestyle{empty}", + r"\begin{document}", + r"% The empty hbox ensures that a page is printed even for empty", + r"% inputs, except when using psfrag which gets confused by it.", + r"% matplotlibbaselinemarker is used by dviread to detect the", + r"% last line's baseline.", + rf"\fontsize{{{fontsize}}}{{{baselineskip}}}%", + r"\ifdefined\psfrag\else\hbox{}\fi%", + rf"{{{fontcmd} {tex}}}%", + r"\end{document}", + ]) + + @classmethod + def make_tex(cls, tex, fontsize): + """ + Generate a tex file to render the tex string at a specific font size. + + Return the file name. + """ + texfile = cls.get_basefile(tex, fontsize) + ".tex" + Path(texfile).write_text(cls._get_tex_source(tex, fontsize), + encoding='utf-8') + return texfile + + @classmethod + def _run_checked_subprocess(cls, command, tex, *, cwd=None): + _log.debug(cbook._pformat_subprocess(command)) + try: + report = subprocess.check_output( + command, cwd=cwd if cwd is not None else cls._texcache, + stderr=subprocess.STDOUT) + except FileNotFoundError as exc: + raise RuntimeError( + f'Failed to process string with tex because {command[0]} ' + 'could not be found') from exc + except subprocess.CalledProcessError as exc: + raise RuntimeError( + '{prog} was not able to process the following string:\n' + '{tex!r}\n\n' + 'Here is the full command invocation and its output:\n\n' + '{format_command}\n\n' + '{exc}\n\n'.format( + prog=command[0], + format_command=cbook._pformat_subprocess(command), + tex=tex.encode('unicode_escape'), + exc=exc.output.decode('utf-8', 'backslashreplace')) + ) from None + _log.debug(report) + return report + + @classmethod + def make_dvi(cls, tex, fontsize): + """ + Generate a dvi file containing latex's layout of tex string. + + Return the file name. + """ + basefile = cls.get_basefile(tex, fontsize) + dvifile = '%s.dvi' % basefile + if not os.path.exists(dvifile): + texfile = Path(cls.make_tex(tex, fontsize)) + # Generate the dvi in a temporary directory to avoid race + # conditions e.g. if multiple processes try to process the same tex + # string at the same time. Having tmpdir be a subdirectory of the + # final output dir ensures that they are on the same filesystem, + # and thus replace() works atomically. It also allows referring to + # the texfile with a relative path (for pathological MPLCONFIGDIRs, + # the absolute path may contain characters (e.g. ~) that TeX does + # not support; n.b. relative paths cannot traverse parents, or it + # will be blocked when `openin_any = p` in texmf.cnf). + cwd = Path(dvifile).parent + with TemporaryDirectory(dir=cwd) as tmpdir: + tmppath = Path(tmpdir) + cls._run_checked_subprocess( + ["latex", "-interaction=nonstopmode", "--halt-on-error", + f"--output-directory={tmppath.name}", + f"{texfile.name}"], tex, cwd=cwd) + (tmppath / Path(dvifile).name).replace(dvifile) + return dvifile + + @classmethod + def make_png(cls, tex, fontsize, dpi): + """ + Generate a png file containing latex's rendering of tex string. + + Return the file name. + """ + basefile = cls.get_basefile(tex, fontsize, dpi) + pngfile = '%s.png' % basefile + # see get_rgba for a discussion of the background + if not os.path.exists(pngfile): + dvifile = cls.make_dvi(tex, fontsize) + cmd = ["dvipng", "-bg", "Transparent", "-D", str(dpi), + "-T", "tight", "-o", pngfile, dvifile] + # When testing, disable FreeType rendering for reproducibility; but + # dvipng 1.16 has a bug (fixed in f3ff241) that breaks --freetype0 + # mode, so for it we keep FreeType enabled; the image will be + # slightly off. + if (getattr(mpl, "_called_from_pytest", False) and + mpl._get_executable_info("dvipng").raw_version != "1.16"): + cmd.insert(1, "--freetype0") + cls._run_checked_subprocess(cmd, tex) + return pngfile + + @classmethod + def get_grey(cls, tex, fontsize=None, dpi=None): + """Return the alpha channel.""" + if not fontsize: + fontsize = mpl.rcParams['font.size'] + if not dpi: + dpi = mpl.rcParams['savefig.dpi'] + key = cls._get_tex_source(tex, fontsize), dpi + alpha = cls._grey_arrayd.get(key) + if alpha is None: + pngfile = cls.make_png(tex, fontsize, dpi) + rgba = mpl.image.imread(os.path.join(cls._texcache, pngfile)) + cls._grey_arrayd[key] = alpha = rgba[:, :, -1] + return alpha + + @classmethod + def get_rgba(cls, tex, fontsize=None, dpi=None, rgb=(0, 0, 0)): + r""" + Return latex's rendering of the tex string as an RGBA array. + + Examples + -------- + >>> texmanager = TexManager() + >>> s = r"\TeX\ is $\displaystyle\sum_n\frac{-e^{i\pi}}{2^n}$!" + >>> Z = texmanager.get_rgba(s, fontsize=12, dpi=80, rgb=(1, 0, 0)) + """ + alpha = cls.get_grey(tex, fontsize, dpi) + rgba = np.empty((*alpha.shape, 4)) + rgba[..., :3] = mpl.colors.to_rgb(rgb) + rgba[..., -1] = alpha + return rgba + + @classmethod + def get_text_width_height_descent(cls, tex, fontsize, renderer=None): + """Return width, height and descent of the text.""" + if tex.strip() == '': + return 0, 0, 0 + dvifile = cls.make_dvi(tex, fontsize) + dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1 + with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi: + page, = dvi + # A total height (including the descent) needs to be returned. + return page.width, page.height + page.descent, page.descent diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.pyi new file mode 100644 index 00000000..94f0d76f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/texmanager.pyi @@ -0,0 +1,38 @@ +from .backend_bases import RendererBase + +from matplotlib.typing import ColorType + +import numpy as np + +class TexManager: + texcache: str + @classmethod + def get_basefile( + cls, tex: str, fontsize: float, dpi: float | None = ... + ) -> str: ... + @classmethod + def get_font_preamble(cls) -> str: ... + @classmethod + def get_custom_preamble(cls) -> str: ... + @classmethod + def make_tex(cls, tex: str, fontsize: float) -> str: ... + @classmethod + def make_dvi(cls, tex: str, fontsize: float) -> str: ... + @classmethod + def make_png(cls, tex: str, fontsize: float, dpi: float) -> str: ... + @classmethod + def get_grey( + cls, tex: str, fontsize: float | None = ..., dpi: float | None = ... + ) -> np.ndarray: ... + @classmethod + def get_rgba( + cls, + tex: str, + fontsize: float | None = ..., + dpi: float | None = ..., + rgb: ColorType = ..., + ) -> np.ndarray: ... + @classmethod + def get_text_width_height_descent( + cls, tex: str, fontsize, renderer: RendererBase | None = ... + ) -> tuple[int, int, int]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.py new file mode 100644 index 00000000..7a58ce71 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.py @@ -0,0 +1,2023 @@ +""" +Classes for including text in a figure. +""" + +import functools +import logging +import math +from numbers import Real +import weakref + +import numpy as np + +import matplotlib as mpl +from . import _api, artist, cbook, _docstring +from .artist import Artist +from .font_manager import FontProperties +from .patches import FancyArrowPatch, FancyBboxPatch, Rectangle +from .textpath import TextPath, TextToPath # noqa # Logically located here +from .transforms import ( + Affine2D, Bbox, BboxBase, BboxTransformTo, IdentityTransform, Transform) + + +_log = logging.getLogger(__name__) + + +def _get_textbox(text, renderer): + """ + Calculate the bounding box of the text. + + The bbox position takes text rotation into account, but the width and + height are those of the unrotated box (unlike `.Text.get_window_extent`). + """ + # TODO : This function may move into the Text class as a method. As a + # matter of fact, the information from the _get_textbox function + # should be available during the Text._get_layout() call, which is + # called within the _get_textbox. So, it would better to move this + # function as a method with some refactoring of _get_layout method. + + projected_xs = [] + projected_ys = [] + + theta = np.deg2rad(text.get_rotation()) + tr = Affine2D().rotate(-theta) + + _, parts, d = text._get_layout(renderer) + + for t, wh, x, y in parts: + w, h = wh + + xt1, yt1 = tr.transform((x, y)) + yt1 -= d + xt2, yt2 = xt1 + w, yt1 + h + + projected_xs.extend([xt1, xt2]) + projected_ys.extend([yt1, yt2]) + + xt_box, yt_box = min(projected_xs), min(projected_ys) + w_box, h_box = max(projected_xs) - xt_box, max(projected_ys) - yt_box + + x_box, y_box = Affine2D().rotate(theta).transform((xt_box, yt_box)) + + return x_box, y_box, w_box, h_box + + +def _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi): + """Call ``renderer.get_text_width_height_descent``, caching the results.""" + # Cached based on a copy of fontprop so that later in-place mutations of + # the passed-in argument do not mess up the cache. + return _get_text_metrics_with_cache_impl( + weakref.ref(renderer), text, fontprop.copy(), ismath, dpi) + + +@functools.lru_cache(4096) +def _get_text_metrics_with_cache_impl( + renderer_ref, text, fontprop, ismath, dpi): + # dpi is unused, but participates in cache invalidation (via the renderer). + return renderer_ref().get_text_width_height_descent(text, fontprop, ismath) + + +@_docstring.interpd +@_api.define_aliases({ + "color": ["c"], + "fontfamily": ["family"], + "fontproperties": ["font", "font_properties"], + "horizontalalignment": ["ha"], + "multialignment": ["ma"], + "fontname": ["name"], + "fontsize": ["size"], + "fontstretch": ["stretch"], + "fontstyle": ["style"], + "fontvariant": ["variant"], + "verticalalignment": ["va"], + "fontweight": ["weight"], +}) +class Text(Artist): + """Handle storing and drawing of text in window or data coordinates.""" + + zorder = 3 + _charsize_cache = dict() + + def __repr__(self): + return f"Text({self._x}, {self._y}, {self._text!r})" + + def __init__(self, + x=0, y=0, text='', *, + color=None, # defaults to rc params + verticalalignment='baseline', + horizontalalignment='left', + multialignment=None, + fontproperties=None, # defaults to FontProperties() + rotation=None, + linespacing=None, + rotation_mode=None, + usetex=None, # defaults to rcParams['text.usetex'] + wrap=False, + transform_rotates_text=False, + parse_math=None, # defaults to rcParams['text.parse_math'] + antialiased=None, # defaults to rcParams['text.antialiased'] + **kwargs + ): + """ + Create a `.Text` instance at *x*, *y* with string *text*. + + The text is aligned relative to the anchor point (*x*, *y*) according + to ``horizontalalignment`` (default: 'left') and ``verticalalignment`` + (default: 'bottom'). See also + :doc:`/gallery/text_labels_and_annotations/text_alignment`. + + While Text accepts the 'label' keyword argument, by default it is not + added to the handles of a legend. + + Valid keyword arguments are: + + %(Text:kwdoc)s + """ + super().__init__() + self._x, self._y = x, y + self._text = '' + self._reset_visual_defaults( + text=text, + color=color, + fontproperties=fontproperties, + usetex=usetex, + parse_math=parse_math, + wrap=wrap, + verticalalignment=verticalalignment, + horizontalalignment=horizontalalignment, + multialignment=multialignment, + rotation=rotation, + transform_rotates_text=transform_rotates_text, + linespacing=linespacing, + rotation_mode=rotation_mode, + antialiased=antialiased + ) + self.update(kwargs) + + def _reset_visual_defaults( + self, + text='', + color=None, + fontproperties=None, + usetex=None, + parse_math=None, + wrap=False, + verticalalignment='baseline', + horizontalalignment='left', + multialignment=None, + rotation=None, + transform_rotates_text=False, + linespacing=None, + rotation_mode=None, + antialiased=None + ): + self.set_text(text) + self.set_color(mpl._val_or_rc(color, "text.color")) + self.set_fontproperties(fontproperties) + self.set_usetex(usetex) + self.set_parse_math(mpl._val_or_rc(parse_math, 'text.parse_math')) + self.set_wrap(wrap) + self.set_verticalalignment(verticalalignment) + self.set_horizontalalignment(horizontalalignment) + self._multialignment = multialignment + self.set_rotation(rotation) + self._transform_rotates_text = transform_rotates_text + self._bbox_patch = None # a FancyBboxPatch instance + self._renderer = None + if linespacing is None: + linespacing = 1.2 # Maybe use rcParam later. + self.set_linespacing(linespacing) + self.set_rotation_mode(rotation_mode) + self.set_antialiased(antialiased if antialiased is not None else + mpl.rcParams['text.antialiased']) + + def update(self, kwargs): + # docstring inherited + ret = [] + kwargs = cbook.normalize_kwargs(kwargs, Text) + sentinel = object() # bbox can be None, so use another sentinel. + # Update fontproperties first, as it has lowest priority. + fontproperties = kwargs.pop("fontproperties", sentinel) + if fontproperties is not sentinel: + ret.append(self.set_fontproperties(fontproperties)) + # Update bbox last, as it depends on font properties. + bbox = kwargs.pop("bbox", sentinel) + ret.extend(super().update(kwargs)) + if bbox is not sentinel: + ret.append(self.set_bbox(bbox)) + return ret + + def __getstate__(self): + d = super().__getstate__() + # remove the cached _renderer (if it exists) + d['_renderer'] = None + return d + + def contains(self, mouseevent): + """ + Return whether the mouse event occurred inside the axis-aligned + bounding-box of the text. + """ + if (self._different_canvas(mouseevent) or not self.get_visible() + or self._renderer is None): + return False, {} + # Explicitly use Text.get_window_extent(self) and not + # self.get_window_extent() so that Annotation.contains does not + # accidentally cover the entire annotation bounding box. + bbox = Text.get_window_extent(self) + inside = (bbox.x0 <= mouseevent.x <= bbox.x1 + and bbox.y0 <= mouseevent.y <= bbox.y1) + cattr = {} + # if the text has a surrounding patch, also check containment for it, + # and merge the results with the results for the text. + if self._bbox_patch: + patch_inside, patch_cattr = self._bbox_patch.contains(mouseevent) + inside = inside or patch_inside + cattr["bbox_patch"] = patch_cattr + return inside, cattr + + def _get_xy_display(self): + """ + Get the (possibly unit converted) transformed x, y in display coords. + """ + x, y = self.get_unitless_position() + return self.get_transform().transform((x, y)) + + def _get_multialignment(self): + if self._multialignment is not None: + return self._multialignment + else: + return self._horizontalalignment + + def _char_index_at(self, x): + """ + Calculate the index closest to the coordinate x in display space. + + The position of text[index] is assumed to be the sum of the widths + of all preceding characters text[:index]. + + This works only on single line texts. + """ + if not self._text: + return 0 + + text = self._text + + fontproperties = str(self._fontproperties) + if fontproperties not in Text._charsize_cache: + Text._charsize_cache[fontproperties] = dict() + + charsize_cache = Text._charsize_cache[fontproperties] + for char in set(text): + if char not in charsize_cache: + self.set_text(char) + bb = self.get_window_extent() + charsize_cache[char] = bb.x1 - bb.x0 + + self.set_text(text) + bb = self.get_window_extent() + + size_accum = np.cumsum([0] + [charsize_cache[x] for x in text]) + std_x = x - bb.x0 + return (np.abs(size_accum - std_x)).argmin() + + def get_rotation(self): + """Return the text angle in degrees between 0 and 360.""" + if self.get_transform_rotates_text(): + return self.get_transform().transform_angles( + [self._rotation], [self.get_unitless_position()]).item(0) + else: + return self._rotation + + def get_transform_rotates_text(self): + """ + Return whether rotations of the transform affect the text direction. + """ + return self._transform_rotates_text + + def set_rotation_mode(self, m): + """ + Set text rotation mode. + + Parameters + ---------- + m : {None, 'default', 'anchor'} + If ``"default"``, the text will be first rotated, then aligned according + to their horizontal and vertical alignments. If ``"anchor"``, then + alignment occurs before rotation. Passing ``None`` will set the rotation + mode to ``"default"``. + """ + if m is None: + m = "default" + else: + _api.check_in_list(("anchor", "default"), rotation_mode=m) + self._rotation_mode = m + self.stale = True + + def get_rotation_mode(self): + """Return the text rotation mode.""" + return self._rotation_mode + + def set_antialiased(self, antialiased): + """ + Set whether to use antialiased rendering. + + Parameters + ---------- + antialiased : bool + + Notes + ----- + Antialiasing will be determined by :rc:`text.antialiased` + and the parameter *antialiased* will have no effect if the text contains + math expressions. + """ + self._antialiased = antialiased + self.stale = True + + def get_antialiased(self): + """Return whether antialiased rendering is used.""" + return self._antialiased + + def update_from(self, other): + # docstring inherited + super().update_from(other) + self._color = other._color + self._multialignment = other._multialignment + self._verticalalignment = other._verticalalignment + self._horizontalalignment = other._horizontalalignment + self._fontproperties = other._fontproperties.copy() + self._usetex = other._usetex + self._rotation = other._rotation + self._transform_rotates_text = other._transform_rotates_text + self._picker = other._picker + self._linespacing = other._linespacing + self._antialiased = other._antialiased + self.stale = True + + def _get_layout(self, renderer): + """ + Return the extent (bbox) of the text together with + multiple-alignment information. Note that it returns an extent + of a rotated text when necessary. + """ + thisx, thisy = 0.0, 0.0 + lines = self._get_wrapped_text().split("\n") # Ensures lines is not empty. + + ws = [] + hs = [] + xs = [] + ys = [] + + # Full vertical extent of font, including ascenders and descenders: + _, lp_h, lp_d = _get_text_metrics_with_cache( + renderer, "lp", self._fontproperties, + ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi) + min_dy = (lp_h - lp_d) * self._linespacing + + for i, line in enumerate(lines): + clean_line, ismath = self._preprocess_math(line) + if clean_line: + w, h, d = _get_text_metrics_with_cache( + renderer, clean_line, self._fontproperties, + ismath=ismath, dpi=self.figure.dpi) + else: + w = h = d = 0 + + # For multiline text, increase the line spacing when the text + # net-height (excluding baseline) is larger than that of a "l" + # (e.g., use of superscripts), which seems what TeX does. + h = max(h, lp_h) + d = max(d, lp_d) + + ws.append(w) + hs.append(h) + + # Metrics of the last line that are needed later: + baseline = (h - d) - thisy + + if i == 0: + # position at baseline + thisy = -(h - d) + else: + # put baseline a good distance from bottom of previous line + thisy -= max(min_dy, (h - d) * self._linespacing) + + xs.append(thisx) # == 0. + ys.append(thisy) + + thisy -= d + + # Metrics of the last line that are needed later: + descent = d + + # Bounding box definition: + width = max(ws) + xmin = 0 + xmax = width + ymax = 0 + ymin = ys[-1] - descent # baseline of last line minus its descent + + # get the rotation matrix + M = Affine2D().rotate_deg(self.get_rotation()) + + # now offset the individual text lines within the box + malign = self._get_multialignment() + if malign == 'left': + offset_layout = [(x, y) for x, y in zip(xs, ys)] + elif malign == 'center': + offset_layout = [(x + width / 2 - w / 2, y) + for x, y, w in zip(xs, ys, ws)] + elif malign == 'right': + offset_layout = [(x + width - w, y) + for x, y, w in zip(xs, ys, ws)] + + # the corners of the unrotated bounding box + corners_horiz = np.array( + [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]) + + # now rotate the bbox + corners_rotated = M.transform(corners_horiz) + # compute the bounds of the rotated box + xmin = corners_rotated[:, 0].min() + xmax = corners_rotated[:, 0].max() + ymin = corners_rotated[:, 1].min() + ymax = corners_rotated[:, 1].max() + width = xmax - xmin + height = ymax - ymin + + # Now move the box to the target position offset the display + # bbox by alignment + halign = self._horizontalalignment + valign = self._verticalalignment + + rotation_mode = self.get_rotation_mode() + if rotation_mode != "anchor": + # compute the text location in display coords and the offsets + # necessary to align the bbox with that location + if halign == 'center': + offsetx = (xmin + xmax) / 2 + elif halign == 'right': + offsetx = xmax + else: + offsetx = xmin + + if valign == 'center': + offsety = (ymin + ymax) / 2 + elif valign == 'top': + offsety = ymax + elif valign == 'baseline': + offsety = ymin + descent + elif valign == 'center_baseline': + offsety = ymin + height - baseline / 2.0 + else: + offsety = ymin + else: + xmin1, ymin1 = corners_horiz[0] + xmax1, ymax1 = corners_horiz[2] + + if halign == 'center': + offsetx = (xmin1 + xmax1) / 2.0 + elif halign == 'right': + offsetx = xmax1 + else: + offsetx = xmin1 + + if valign == 'center': + offsety = (ymin1 + ymax1) / 2.0 + elif valign == 'top': + offsety = ymax1 + elif valign == 'baseline': + offsety = ymax1 - baseline + elif valign == 'center_baseline': + offsety = ymax1 - baseline / 2.0 + else: + offsety = ymin1 + + offsetx, offsety = M.transform((offsetx, offsety)) + + xmin -= offsetx + ymin -= offsety + + bbox = Bbox.from_bounds(xmin, ymin, width, height) + + # now rotate the positions around the first (x, y) position + xys = M.transform(offset_layout) - (offsetx, offsety) + + return bbox, list(zip(lines, zip(ws, hs), *xys.T)), descent + + def set_bbox(self, rectprops): + """ + Draw a bounding box around self. + + Parameters + ---------- + rectprops : dict with properties for `.patches.FancyBboxPatch` + The default boxstyle is 'square'. The mutation + scale of the `.patches.FancyBboxPatch` is set to the fontsize. + + Examples + -------- + :: + + t.set_bbox(dict(facecolor='red', alpha=0.5)) + """ + + if rectprops is not None: + props = rectprops.copy() + boxstyle = props.pop("boxstyle", None) + pad = props.pop("pad", None) + if boxstyle is None: + boxstyle = "square" + if pad is None: + pad = 4 # points + pad /= self.get_size() # to fraction of font size + else: + if pad is None: + pad = 0.3 + # boxstyle could be a callable or a string + if isinstance(boxstyle, str) and "pad" not in boxstyle: + boxstyle += ",pad=%0.2f" % pad + self._bbox_patch = FancyBboxPatch( + (0, 0), 1, 1, + boxstyle=boxstyle, transform=IdentityTransform(), **props) + else: + self._bbox_patch = None + + self._update_clip_properties() + + def get_bbox_patch(self): + """ + Return the bbox Patch, or None if the `.patches.FancyBboxPatch` + is not made. + """ + return self._bbox_patch + + def update_bbox_position_size(self, renderer): + """ + Update the location and the size of the bbox. + + This method should be used when the position and size of the bbox needs + to be updated before actually drawing the bbox. + """ + if self._bbox_patch: + # don't use self.get_unitless_position here, which refers to text + # position in Text: + posx = float(self.convert_xunits(self._x)) + posy = float(self.convert_yunits(self._y)) + posx, posy = self.get_transform().transform((posx, posy)) + + x_box, y_box, w_box, h_box = _get_textbox(self, renderer) + self._bbox_patch.set_bounds(0., 0., w_box, h_box) + self._bbox_patch.set_transform( + Affine2D() + .rotate_deg(self.get_rotation()) + .translate(posx + x_box, posy + y_box)) + fontsize_in_pixel = renderer.points_to_pixels(self.get_size()) + self._bbox_patch.set_mutation_scale(fontsize_in_pixel) + + def _update_clip_properties(self): + if self._bbox_patch: + clipprops = dict(clip_box=self.clipbox, + clip_path=self._clippath, + clip_on=self._clipon) + self._bbox_patch.update(clipprops) + + def set_clip_box(self, clipbox): + # docstring inherited. + super().set_clip_box(clipbox) + self._update_clip_properties() + + def set_clip_path(self, path, transform=None): + # docstring inherited. + super().set_clip_path(path, transform) + self._update_clip_properties() + + def set_clip_on(self, b): + # docstring inherited. + super().set_clip_on(b) + self._update_clip_properties() + + def get_wrap(self): + """Return whether the text can be wrapped.""" + return self._wrap + + def set_wrap(self, wrap): + """ + Set whether the text can be wrapped. + + Parameters + ---------- + wrap : bool + + Notes + ----- + Wrapping does not work together with + ``savefig(..., bbox_inches='tight')`` (which is also used internally + by ``%matplotlib inline`` in IPython/Jupyter). The 'tight' setting + rescales the canvas to accommodate all content and happens before + wrapping. + """ + self._wrap = wrap + + def _get_wrap_line_width(self): + """ + Return the maximum line width for wrapping text based on the current + orientation. + """ + x0, y0 = self.get_transform().transform(self.get_position()) + figure_box = self.get_figure().get_window_extent() + + # Calculate available width based on text alignment + alignment = self.get_horizontalalignment() + self.set_rotation_mode('anchor') + rotation = self.get_rotation() + + left = self._get_dist_to_box(rotation, x0, y0, figure_box) + right = self._get_dist_to_box( + (180 + rotation) % 360, x0, y0, figure_box) + + if alignment == 'left': + line_width = left + elif alignment == 'right': + line_width = right + else: + line_width = 2 * min(left, right) + + return line_width + + def _get_dist_to_box(self, rotation, x0, y0, figure_box): + """ + Return the distance from the given points to the boundaries of a + rotated box, in pixels. + """ + if rotation > 270: + quad = rotation - 270 + h1 = y0 / math.cos(math.radians(quad)) + h2 = (figure_box.x1 - x0) / math.cos(math.radians(90 - quad)) + elif rotation > 180: + quad = rotation - 180 + h1 = x0 / math.cos(math.radians(quad)) + h2 = y0 / math.cos(math.radians(90 - quad)) + elif rotation > 90: + quad = rotation - 90 + h1 = (figure_box.y1 - y0) / math.cos(math.radians(quad)) + h2 = x0 / math.cos(math.radians(90 - quad)) + else: + h1 = (figure_box.x1 - x0) / math.cos(math.radians(rotation)) + h2 = (figure_box.y1 - y0) / math.cos(math.radians(90 - rotation)) + + return min(h1, h2) + + def _get_rendered_text_width(self, text): + """ + Return the width of a given text string, in pixels. + """ + + w, h, d = self._renderer.get_text_width_height_descent( + text, + self.get_fontproperties(), + cbook.is_math_text(text)) + return math.ceil(w) + + def _get_wrapped_text(self): + """ + Return a copy of the text string with new lines added so that the text + is wrapped relative to the parent figure (if `get_wrap` is True). + """ + if not self.get_wrap(): + return self.get_text() + + # Not fit to handle breaking up latex syntax correctly, so + # ignore latex for now. + if self.get_usetex(): + return self.get_text() + + # Build the line incrementally, for a more accurate measure of length + line_width = self._get_wrap_line_width() + wrapped_lines = [] + + # New lines in the user's text force a split + unwrapped_lines = self.get_text().split('\n') + + # Now wrap each individual unwrapped line + for unwrapped_line in unwrapped_lines: + + sub_words = unwrapped_line.split(' ') + # Remove items from sub_words as we go, so stop when empty + while len(sub_words) > 0: + if len(sub_words) == 1: + # Only one word, so just add it to the end + wrapped_lines.append(sub_words.pop(0)) + continue + + for i in range(2, len(sub_words) + 1): + # Get width of all words up to and including here + line = ' '.join(sub_words[:i]) + current_width = self._get_rendered_text_width(line) + + # If all these words are too wide, append all not including + # last word + if current_width > line_width: + wrapped_lines.append(' '.join(sub_words[:i - 1])) + sub_words = sub_words[i - 1:] + break + + # Otherwise if all words fit in the width, append them all + elif i == len(sub_words): + wrapped_lines.append(' '.join(sub_words[:i])) + sub_words = [] + break + + return '\n'.join(wrapped_lines) + + @artist.allow_rasterization + def draw(self, renderer): + # docstring inherited + + if renderer is not None: + self._renderer = renderer + if not self.get_visible(): + return + if self.get_text() == '': + return + + renderer.open_group('text', self.get_gid()) + + with self._cm_set(text=self._get_wrapped_text()): + bbox, info, descent = self._get_layout(renderer) + trans = self.get_transform() + + # don't use self.get_position here, which refers to text + # position in Text: + posx = float(self.convert_xunits(self._x)) + posy = float(self.convert_yunits(self._y)) + posx, posy = trans.transform((posx, posy)) + if not np.isfinite(posx) or not np.isfinite(posy): + _log.warning("posx and posy should be finite values") + return + canvasw, canvash = renderer.get_canvas_width_height() + + # Update the location and size of the bbox + # (`.patches.FancyBboxPatch`), and draw it. + if self._bbox_patch: + self.update_bbox_position_size(renderer) + self._bbox_patch.draw(renderer) + + gc = renderer.new_gc() + gc.set_foreground(self.get_color()) + gc.set_alpha(self.get_alpha()) + gc.set_url(self._url) + gc.set_antialiased(self._antialiased) + self._set_gc_clip(gc) + + angle = self.get_rotation() + + for line, wh, x, y in info: + + mtext = self if len(info) == 1 else None + x = x + posx + y = y + posy + if renderer.flipy(): + y = canvash - y + clean_line, ismath = self._preprocess_math(line) + + if self.get_path_effects(): + from matplotlib.patheffects import PathEffectRenderer + textrenderer = PathEffectRenderer( + self.get_path_effects(), renderer) + else: + textrenderer = renderer + + if self.get_usetex(): + textrenderer.draw_tex(gc, x, y, clean_line, + self._fontproperties, angle, + mtext=mtext) + else: + textrenderer.draw_text(gc, x, y, clean_line, + self._fontproperties, angle, + ismath=ismath, mtext=mtext) + + gc.restore() + renderer.close_group('text') + self.stale = False + + def get_color(self): + """Return the color of the text.""" + return self._color + + def get_fontproperties(self): + """Return the `.font_manager.FontProperties`.""" + return self._fontproperties + + def get_fontfamily(self): + """ + Return the list of font families used for font lookup. + + See Also + -------- + .font_manager.FontProperties.get_family + """ + return self._fontproperties.get_family() + + def get_fontname(self): + """ + Return the font name as a string. + + See Also + -------- + .font_manager.FontProperties.get_name + """ + return self._fontproperties.get_name() + + def get_fontstyle(self): + """ + Return the font style as a string. + + See Also + -------- + .font_manager.FontProperties.get_style + """ + return self._fontproperties.get_style() + + def get_fontsize(self): + """ + Return the font size as an integer. + + See Also + -------- + .font_manager.FontProperties.get_size_in_points + """ + return self._fontproperties.get_size_in_points() + + def get_fontvariant(self): + """ + Return the font variant as a string. + + See Also + -------- + .font_manager.FontProperties.get_variant + """ + return self._fontproperties.get_variant() + + def get_fontweight(self): + """ + Return the font weight as a string or a number. + + See Also + -------- + .font_manager.FontProperties.get_weight + """ + return self._fontproperties.get_weight() + + def get_stretch(self): + """ + Return the font stretch as a string or a number. + + See Also + -------- + .font_manager.FontProperties.get_stretch + """ + return self._fontproperties.get_stretch() + + def get_horizontalalignment(self): + """ + Return the horizontal alignment as a string. Will be one of + 'left', 'center' or 'right'. + """ + return self._horizontalalignment + + def get_unitless_position(self): + """Return the (x, y) unitless position of the text.""" + # This will get the position with all unit information stripped away. + # This is here for convenience since it is done in several locations. + x = float(self.convert_xunits(self._x)) + y = float(self.convert_yunits(self._y)) + return x, y + + def get_position(self): + """Return the (x, y) position of the text.""" + # This should return the same data (possible unitized) as was + # specified with 'set_x' and 'set_y'. + return self._x, self._y + + def get_text(self): + """Return the text string.""" + return self._text + + def get_verticalalignment(self): + """ + Return the vertical alignment as a string. Will be one of + 'top', 'center', 'bottom', 'baseline' or 'center_baseline'. + """ + return self._verticalalignment + + def get_window_extent(self, renderer=None, dpi=None): + """ + Return the `.Bbox` bounding the text, in display units. + + In addition to being used internally, this is useful for specifying + clickable regions in a png file on a web page. + + Parameters + ---------- + renderer : Renderer, optional + A renderer is needed to compute the bounding box. If the artist + has already been drawn, the renderer is cached; thus, it is only + necessary to pass this argument when calling `get_window_extent` + before the first draw. In practice, it is usually easier to + trigger a draw first, e.g. by calling + `~.Figure.draw_without_rendering` or ``plt.show()``. + + dpi : float, optional + The dpi value for computing the bbox, defaults to + ``self.figure.dpi`` (*not* the renderer dpi); should be set e.g. if + to match regions with a figure saved with a custom dpi value. + """ + if not self.get_visible(): + return Bbox.unit() + if dpi is None: + dpi = self.figure.dpi + if self.get_text() == '': + with cbook._setattr_cm(self.figure, dpi=dpi): + tx, ty = self._get_xy_display() + return Bbox.from_bounds(tx, ty, 0, 0) + + if renderer is not None: + self._renderer = renderer + if self._renderer is None: + self._renderer = self.figure._get_renderer() + if self._renderer is None: + raise RuntimeError( + "Cannot get window extent of text w/o renderer. You likely " + "want to call 'figure.draw_without_rendering()' first.") + + with cbook._setattr_cm(self.figure, dpi=dpi): + bbox, info, descent = self._get_layout(self._renderer) + x, y = self.get_unitless_position() + x, y = self.get_transform().transform((x, y)) + bbox = bbox.translated(x, y) + return bbox + + def set_backgroundcolor(self, color): + """ + Set the background color of the text by updating the bbox. + + Parameters + ---------- + color : color + + See Also + -------- + .set_bbox : To change the position of the bounding box + """ + if self._bbox_patch is None: + self.set_bbox(dict(facecolor=color, edgecolor=color)) + else: + self._bbox_patch.update(dict(facecolor=color)) + + self._update_clip_properties() + self.stale = True + + def set_color(self, color): + """ + Set the foreground color of the text + + Parameters + ---------- + color : color + """ + # "auto" is only supported by axisartist, but we can just let it error + # out at draw time for simplicity. + if not cbook._str_equal(color, "auto"): + mpl.colors._check_color_like(color=color) + self._color = color + self.stale = True + + def set_horizontalalignment(self, align): + """ + Set the horizontal alignment relative to the anchor point. + + See also :doc:`/gallery/text_labels_and_annotations/text_alignment`. + + Parameters + ---------- + align : {'left', 'center', 'right'} + """ + _api.check_in_list(['center', 'right', 'left'], align=align) + self._horizontalalignment = align + self.stale = True + + def set_multialignment(self, align): + """ + Set the text alignment for multiline texts. + + The layout of the bounding box of all the lines is determined by the + horizontalalignment and verticalalignment properties. This property + controls the alignment of the text lines within that box. + + Parameters + ---------- + align : {'left', 'right', 'center'} + """ + _api.check_in_list(['center', 'right', 'left'], align=align) + self._multialignment = align + self.stale = True + + def set_linespacing(self, spacing): + """ + Set the line spacing as a multiple of the font size. + + The default line spacing is 1.2. + + Parameters + ---------- + spacing : float (multiple of font size) + """ + _api.check_isinstance(Real, spacing=spacing) + self._linespacing = spacing + self.stale = True + + def set_fontfamily(self, fontname): + """ + Set the font family. Can be either a single string, or a list of + strings in decreasing priority. Each string may be either a real font + name or a generic font class name. If the latter, the specific font + names will be looked up in the corresponding rcParams. + + If a `Text` instance is constructed with ``fontfamily=None``, then the + font is set to :rc:`font.family`, and the + same is done when `set_fontfamily()` is called on an existing + `Text` instance. + + Parameters + ---------- + fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', \ +'monospace'} + + See Also + -------- + .font_manager.FontProperties.set_family + """ + self._fontproperties.set_family(fontname) + self.stale = True + + def set_fontvariant(self, variant): + """ + Set the font variant. + + Parameters + ---------- + variant : {'normal', 'small-caps'} + + See Also + -------- + .font_manager.FontProperties.set_variant + """ + self._fontproperties.set_variant(variant) + self.stale = True + + def set_fontstyle(self, fontstyle): + """ + Set the font style. + + Parameters + ---------- + fontstyle : {'normal', 'italic', 'oblique'} + + See Also + -------- + .font_manager.FontProperties.set_style + """ + self._fontproperties.set_style(fontstyle) + self.stale = True + + def set_fontsize(self, fontsize): + """ + Set the font size. + + Parameters + ---------- + fontsize : float or {'xx-small', 'x-small', 'small', 'medium', \ +'large', 'x-large', 'xx-large'} + If a float, the fontsize in points. The string values denote sizes + relative to the default font size. + + See Also + -------- + .font_manager.FontProperties.set_size + """ + self._fontproperties.set_size(fontsize) + self.stale = True + + def get_math_fontfamily(self): + """ + Return the font family name for math text rendered by Matplotlib. + + The default value is :rc:`mathtext.fontset`. + + See Also + -------- + set_math_fontfamily + """ + return self._fontproperties.get_math_fontfamily() + + def set_math_fontfamily(self, fontfamily): + """ + Set the font family for math text rendered by Matplotlib. + + This does only affect Matplotlib's own math renderer. It has no effect + when rendering with TeX (``usetex=True``). + + Parameters + ---------- + fontfamily : str + The name of the font family. + + Available font families are defined in the + :ref:`default matplotlibrc file + <customizing-with-matplotlibrc-files>`. + + See Also + -------- + get_math_fontfamily + """ + self._fontproperties.set_math_fontfamily(fontfamily) + + def set_fontweight(self, weight): + """ + Set the font weight. + + Parameters + ---------- + weight : {a numeric value in range 0-1000, 'ultralight', 'light', \ +'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', \ +'demi', 'bold', 'heavy', 'extra bold', 'black'} + + See Also + -------- + .font_manager.FontProperties.set_weight + """ + self._fontproperties.set_weight(weight) + self.stale = True + + def set_fontstretch(self, stretch): + """ + Set the font stretch (horizontal condensation or expansion). + + Parameters + ---------- + stretch : {a numeric value in range 0-1000, 'ultra-condensed', \ +'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', \ +'expanded', 'extra-expanded', 'ultra-expanded'} + + See Also + -------- + .font_manager.FontProperties.set_stretch + """ + self._fontproperties.set_stretch(stretch) + self.stale = True + + def set_position(self, xy): + """ + Set the (*x*, *y*) position of the text. + + Parameters + ---------- + xy : (float, float) + """ + self.set_x(xy[0]) + self.set_y(xy[1]) + + def set_x(self, x): + """ + Set the *x* position of the text. + + Parameters + ---------- + x : float + """ + self._x = x + self.stale = True + + def set_y(self, y): + """ + Set the *y* position of the text. + + Parameters + ---------- + y : float + """ + self._y = y + self.stale = True + + def set_rotation(self, s): + """ + Set the rotation of the text. + + Parameters + ---------- + s : float or {'vertical', 'horizontal'} + The rotation angle in degrees in mathematically positive direction + (counterclockwise). 'horizontal' equals 0, 'vertical' equals 90. + """ + if isinstance(s, Real): + self._rotation = float(s) % 360 + elif cbook._str_equal(s, 'horizontal') or s is None: + self._rotation = 0. + elif cbook._str_equal(s, 'vertical'): + self._rotation = 90. + else: + raise ValueError("rotation must be 'vertical', 'horizontal' or " + f"a number, not {s}") + self.stale = True + + def set_transform_rotates_text(self, t): + """ + Whether rotations of the transform affect the text direction. + + Parameters + ---------- + t : bool + """ + self._transform_rotates_text = t + self.stale = True + + def set_verticalalignment(self, align): + """ + Set the vertical alignment relative to the anchor point. + + See also :doc:`/gallery/text_labels_and_annotations/text_alignment`. + + Parameters + ---------- + align : {'bottom', 'baseline', 'center', 'center_baseline', 'top'} + """ + _api.check_in_list( + ['top', 'bottom', 'center', 'baseline', 'center_baseline'], + align=align) + self._verticalalignment = align + self.stale = True + + def set_text(self, s): + r""" + Set the text string *s*. + + It may contain newlines (``\n``) or math in LaTeX syntax. + + Parameters + ---------- + s : object + Any object gets converted to its `str` representation, except for + ``None`` which is converted to an empty string. + """ + s = '' if s is None else str(s) + if s != self._text: + self._text = s + self.stale = True + + def _preprocess_math(self, s): + """ + Return the string *s* after mathtext preprocessing, and the kind of + mathtext support needed. + + - If *self* is configured to use TeX, return *s* unchanged except that + a single space gets escaped, and the flag "TeX". + - Otherwise, if *s* is mathtext (has an even number of unescaped dollar + signs) and ``parse_math`` is not set to False, return *s* and the + flag True. + - Otherwise, return *s* with dollar signs unescaped, and the flag + False. + """ + if self.get_usetex(): + if s == " ": + s = r"\ " + return s, "TeX" + elif not self.get_parse_math(): + return s, False + elif cbook.is_math_text(s): + return s, True + else: + return s.replace(r"\$", "$"), False + + def set_fontproperties(self, fp): + """ + Set the font properties that control the text. + + Parameters + ---------- + fp : `.font_manager.FontProperties` or `str` or `pathlib.Path` + If a `str`, it is interpreted as a fontconfig pattern parsed by + `.FontProperties`. If a `pathlib.Path`, it is interpreted as the + absolute path to a font file. + """ + self._fontproperties = FontProperties._from_any(fp).copy() + self.stale = True + + def set_usetex(self, usetex): + """ + Parameters + ---------- + usetex : bool or None + Whether to render using TeX, ``None`` means to use + :rc:`text.usetex`. + """ + if usetex is None: + self._usetex = mpl.rcParams['text.usetex'] + else: + self._usetex = bool(usetex) + self.stale = True + + def get_usetex(self): + """Return whether this `Text` object uses TeX for rendering.""" + return self._usetex + + def set_parse_math(self, parse_math): + """ + Override switch to disable any mathtext parsing for this `Text`. + + Parameters + ---------- + parse_math : bool + If False, this `Text` will never use mathtext. If True, mathtext + will be used if there is an even number of unescaped dollar signs. + """ + self._parse_math = bool(parse_math) + + def get_parse_math(self): + """Return whether mathtext parsing is considered for this `Text`.""" + return self._parse_math + + def set_fontname(self, fontname): + """ + Alias for `set_fontfamily`. + + One-way alias only: the getter differs. + + Parameters + ---------- + fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', \ +'monospace'} + + See Also + -------- + .font_manager.FontProperties.set_family + + """ + self.set_fontfamily(fontname) + + +class OffsetFrom: + """Callable helper class for working with `Annotation`.""" + + def __init__(self, artist, ref_coord, unit="points"): + """ + Parameters + ---------- + artist : `~matplotlib.artist.Artist` or `.BboxBase` or `.Transform` + The object to compute the offset from. + + ref_coord : (float, float) + If *artist* is an `.Artist` or `.BboxBase`, this values is + the location to of the offset origin in fractions of the + *artist* bounding box. + + If *artist* is a transform, the offset origin is the + transform applied to this value. + + unit : {'points, 'pixels'}, default: 'points' + The screen units to use (pixels or points) for the offset input. + """ + self._artist = artist + x, y = ref_coord # Make copy when ref_coord is an array (and check the shape). + self._ref_coord = x, y + self.set_unit(unit) + + def set_unit(self, unit): + """ + Set the unit for input to the transform used by ``__call__``. + + Parameters + ---------- + unit : {'points', 'pixels'} + """ + _api.check_in_list(["points", "pixels"], unit=unit) + self._unit = unit + + def get_unit(self): + """Return the unit for input to the transform used by ``__call__``.""" + return self._unit + + def __call__(self, renderer): + """ + Return the offset transform. + + Parameters + ---------- + renderer : `RendererBase` + The renderer to use to compute the offset + + Returns + ------- + `Transform` + Maps (x, y) in pixel or point units to screen units + relative to the given artist. + """ + if isinstance(self._artist, Artist): + bbox = self._artist.get_window_extent(renderer) + xf, yf = self._ref_coord + x = bbox.x0 + bbox.width * xf + y = bbox.y0 + bbox.height * yf + elif isinstance(self._artist, BboxBase): + bbox = self._artist + xf, yf = self._ref_coord + x = bbox.x0 + bbox.width * xf + y = bbox.y0 + bbox.height * yf + elif isinstance(self._artist, Transform): + x, y = self._artist.transform(self._ref_coord) + else: + _api.check_isinstance((Artist, BboxBase, Transform), artist=self._artist) + scale = 1 if self._unit == "pixels" else renderer.points_to_pixels(1) + return Affine2D().scale(scale).translate(x, y) + + +class _AnnotationBase: + def __init__(self, + xy, + xycoords='data', + annotation_clip=None): + + x, y = xy # Make copy when xy is an array (and check the shape). + self.xy = x, y + self.xycoords = xycoords + self.set_annotation_clip(annotation_clip) + + self._draggable = None + + def _get_xy(self, renderer, xy, coords): + x, y = xy + xcoord, ycoord = coords if isinstance(coords, tuple) else (coords, coords) + if xcoord == 'data': + x = float(self.convert_xunits(x)) + if ycoord == 'data': + y = float(self.convert_yunits(y)) + return self._get_xy_transform(renderer, coords).transform((x, y)) + + def _get_xy_transform(self, renderer, coords): + + if isinstance(coords, tuple): + xcoord, ycoord = coords + from matplotlib.transforms import blended_transform_factory + tr1 = self._get_xy_transform(renderer, xcoord) + tr2 = self._get_xy_transform(renderer, ycoord) + return blended_transform_factory(tr1, tr2) + elif callable(coords): + tr = coords(renderer) + if isinstance(tr, BboxBase): + return BboxTransformTo(tr) + elif isinstance(tr, Transform): + return tr + else: + raise TypeError( + f"xycoords callable must return a BboxBase or Transform, not a " + f"{type(tr).__name__}") + elif isinstance(coords, Artist): + bbox = coords.get_window_extent(renderer) + return BboxTransformTo(bbox) + elif isinstance(coords, BboxBase): + return BboxTransformTo(coords) + elif isinstance(coords, Transform): + return coords + elif not isinstance(coords, str): + raise TypeError( + f"'xycoords' must be an instance of str, tuple[str, str], Artist, " + f"Transform, or Callable, not a {type(coords).__name__}") + + if coords == 'data': + return self.axes.transData + elif coords == 'polar': + from matplotlib.projections import PolarAxes + tr = PolarAxes.PolarTransform() + trans = tr + self.axes.transData + return trans + + try: + bbox_name, unit = coords.split() + except ValueError: # i.e. len(coords.split()) != 2. + raise ValueError(f"{coords!r} is not a valid coordinate") from None + + bbox0, xy0 = None, None + + # if unit is offset-like + if bbox_name == "figure": + bbox0 = self.figure.figbbox + elif bbox_name == "subfigure": + bbox0 = self.figure.bbox + elif bbox_name == "axes": + bbox0 = self.axes.bbox + + # reference x, y in display coordinate + if bbox0 is not None: + xy0 = bbox0.p0 + elif bbox_name == "offset": + xy0 = self._get_position_xy(renderer) + else: + raise ValueError(f"{coords!r} is not a valid coordinate") + + if unit == "points": + tr = Affine2D().scale(self.figure.dpi / 72) # dpi/72 dots per point + elif unit == "pixels": + tr = Affine2D() + elif unit == "fontsize": + tr = Affine2D().scale(self.get_size() * self.figure.dpi / 72) + elif unit == "fraction": + tr = Affine2D().scale(*bbox0.size) + else: + raise ValueError(f"{unit!r} is not a recognized unit") + + return tr.translate(*xy0) + + def set_annotation_clip(self, b): + """ + Set the annotation's clipping behavior. + + Parameters + ---------- + b : bool or None + - True: The annotation will be clipped when ``self.xy`` is + outside the axes. + - False: The annotation will always be drawn. + - None: The annotation will be clipped when ``self.xy`` is + outside the axes and ``self.xycoords == "data"``. + """ + self._annotation_clip = b + + def get_annotation_clip(self): + """ + Return the annotation's clipping behavior. + + See `set_annotation_clip` for the meaning of return values. + """ + return self._annotation_clip + + def _get_position_xy(self, renderer): + """Return the pixel position of the annotated point.""" + return self._get_xy(renderer, self.xy, self.xycoords) + + def _check_xy(self, renderer=None): + """Check whether the annotation at *xy_pixel* should be drawn.""" + if renderer is None: + renderer = self.figure._get_renderer() + b = self.get_annotation_clip() + if b or (b is None and self.xycoords == "data"): + # check if self.xy is inside the axes. + xy_pixel = self._get_position_xy(renderer) + return self.axes.contains_point(xy_pixel) + return True + + def draggable(self, state=None, use_blit=False): + """ + Set whether the annotation is draggable with the mouse. + + Parameters + ---------- + state : bool or None + - True or False: set the draggability. + - None: toggle the draggability. + use_blit : bool, default: False + Use blitting for faster image composition. For details see + :ref:`func-animation`. + + Returns + ------- + DraggableAnnotation or None + If the annotation is draggable, the corresponding + `.DraggableAnnotation` helper is returned. + """ + from matplotlib.offsetbox import DraggableAnnotation + is_draggable = self._draggable is not None + + # if state is None we'll toggle + if state is None: + state = not is_draggable + + if state: + if self._draggable is None: + self._draggable = DraggableAnnotation(self, use_blit) + else: + if self._draggable is not None: + self._draggable.disconnect() + self._draggable = None + + return self._draggable + + +class Annotation(Text, _AnnotationBase): + """ + An `.Annotation` is a `.Text` that can refer to a specific position *xy*. + Optionally an arrow pointing from the text to *xy* can be drawn. + + Attributes + ---------- + xy + The annotated position. + xycoords + The coordinate system for *xy*. + arrow_patch + A `.FancyArrowPatch` to point from *xytext* to *xy*. + """ + + def __str__(self): + return f"Annotation({self.xy[0]:g}, {self.xy[1]:g}, {self._text!r})" + + def __init__(self, text, xy, + xytext=None, + xycoords='data', + textcoords=None, + arrowprops=None, + annotation_clip=None, + **kwargs): + """ + Annotate the point *xy* with text *text*. + + In the simplest form, the text is placed at *xy*. + + Optionally, the text can be displayed in another position *xytext*. + An arrow pointing from the text to the annotated point *xy* can then + be added by defining *arrowprops*. + + Parameters + ---------- + text : str + The text of the annotation. + + xy : (float, float) + The point *(x, y)* to annotate. The coordinate system is determined + by *xycoords*. + + xytext : (float, float), default: *xy* + The position *(x, y)* to place the text at. The coordinate system + is determined by *textcoords*. + + xycoords : single or two-tuple of str or `.Artist` or `.Transform` or \ +callable, default: 'data' + + The coordinate system that *xy* is given in. The following types + of values are supported: + + - One of the following strings: + + ==================== ============================================ + Value Description + ==================== ============================================ + 'figure points' Points from the lower left of the figure + 'figure pixels' Pixels from the lower left of the figure + 'figure fraction' Fraction of figure from lower left + 'subfigure points' Points from the lower left of the subfigure + 'subfigure pixels' Pixels from the lower left of the subfigure + 'subfigure fraction' Fraction of subfigure from lower left + 'axes points' Points from lower left corner of axes + 'axes pixels' Pixels from lower left corner of axes + 'axes fraction' Fraction of axes from lower left + 'data' Use the coordinate system of the object + being annotated (default) + 'polar' *(theta, r)* if not native 'data' + coordinates + ==================== ============================================ + + Note that 'subfigure pixels' and 'figure pixels' are the same + for the parent figure, so users who want code that is usable in + a subfigure can use 'subfigure pixels'. + + - An `.Artist`: *xy* is interpreted as a fraction of the artist's + `~matplotlib.transforms.Bbox`. E.g. *(0, 0)* would be the lower + left corner of the bounding box and *(0.5, 1)* would be the + center top of the bounding box. + + - A `.Transform` to transform *xy* to screen coordinates. + + - A function with one of the following signatures:: + + def transform(renderer) -> Bbox + def transform(renderer) -> Transform + + where *renderer* is a `.RendererBase` subclass. + + The result of the function is interpreted like the `.Artist` and + `.Transform` cases above. + + - A tuple *(xcoords, ycoords)* specifying separate coordinate + systems for *x* and *y*. *xcoords* and *ycoords* must each be + of one of the above described types. + + See :ref:`plotting-guide-annotation` for more details. + + textcoords : single or two-tuple of str or `.Artist` or `.Transform` \ +or callable, default: value of *xycoords* + The coordinate system that *xytext* is given in. + + All *xycoords* values are valid as well as the following strings: + + ================= ================================================= + Value Description + ================= ================================================= + 'offset points' Offset, in points, from the *xy* value + 'offset pixels' Offset, in pixels, from the *xy* value + 'offset fontsize' Offset, relative to fontsize, from the *xy* value + ================= ================================================= + + arrowprops : dict, optional + The properties used to draw a `.FancyArrowPatch` arrow between the + positions *xy* and *xytext*. Defaults to None, i.e. no arrow is + drawn. + + For historical reasons there are two different ways to specify + arrows, "simple" and "fancy": + + **Simple arrow:** + + If *arrowprops* does not contain the key 'arrowstyle' the + allowed keys are: + + ========== ================================================= + Key Description + ========== ================================================= + width The width of the arrow in points + headwidth The width of the base of the arrow head in points + headlength The length of the arrow head in points + shrink Fraction of total length to shrink from both ends + ? Any `.FancyArrowPatch` property + ========== ================================================= + + The arrow is attached to the edge of the text box, the exact + position (corners or centers) depending on where it's pointing to. + + **Fancy arrow:** + + This is used if 'arrowstyle' is provided in the *arrowprops*. + + Valid keys are the following `.FancyArrowPatch` parameters: + + =============== =================================== + Key Description + =============== =================================== + arrowstyle The arrow style + connectionstyle The connection style + relpos See below; default is (0.5, 0.5) + patchA Default is bounding box of the text + patchB Default is None + shrinkA Default is 2 points + shrinkB Default is 2 points + mutation_scale Default is text size (in points) + mutation_aspect Default is 1 + ? Any `.FancyArrowPatch` property + =============== =================================== + + The exact starting point position of the arrow is defined by + *relpos*. It's a tuple of relative coordinates of the text box, + where (0, 0) is the lower left corner and (1, 1) is the upper + right corner. Values <0 and >1 are supported and specify points + outside the text box. By default (0.5, 0.5), so the starting point + is centered in the text box. + + annotation_clip : bool or None, default: None + Whether to clip (i.e. not draw) the annotation when the annotation + point *xy* is outside the axes area. + + - If *True*, the annotation will be clipped when *xy* is outside + the axes. + - If *False*, the annotation will always be drawn. + - If *None*, the annotation will be clipped when *xy* is outside + the axes and *xycoords* is 'data'. + + **kwargs + Additional kwargs are passed to `.Text`. + + Returns + ------- + `.Annotation` + + See Also + -------- + :ref:`plotting-guide-annotation` + + """ + _AnnotationBase.__init__(self, + xy, + xycoords=xycoords, + annotation_clip=annotation_clip) + # warn about wonky input data + if (xytext is None and + textcoords is not None and + textcoords != xycoords): + _api.warn_external("You have used the `textcoords` kwarg, but " + "not the `xytext` kwarg. This can lead to " + "surprising results.") + + # clean up textcoords and assign default + if textcoords is None: + textcoords = self.xycoords + self._textcoords = textcoords + + # cleanup xytext defaults + if xytext is None: + xytext = self.xy + x, y = xytext + + self.arrowprops = arrowprops + if arrowprops is not None: + arrowprops = arrowprops.copy() + if "arrowstyle" in arrowprops: + self._arrow_relpos = arrowprops.pop("relpos", (0.5, 0.5)) + else: + # modified YAArrow API to be used with FancyArrowPatch + for key in ['width', 'headwidth', 'headlength', 'shrink']: + arrowprops.pop(key, None) + if 'frac' in arrowprops: + _api.warn_deprecated( + "3.8", name="the (unused) 'frac' key in 'arrowprops'") + arrowprops.pop("frac") + self.arrow_patch = FancyArrowPatch((0, 0), (1, 1), **arrowprops) + else: + self.arrow_patch = None + + # Must come last, as some kwargs may be propagated to arrow_patch. + Text.__init__(self, x, y, text, **kwargs) + + @_api.rename_parameter("3.8", "event", "mouseevent") + def contains(self, mouseevent): + if self._different_canvas(mouseevent): + return False, {} + contains, tinfo = Text.contains(self, mouseevent) + if self.arrow_patch is not None: + in_patch, _ = self.arrow_patch.contains(mouseevent) + contains = contains or in_patch + return contains, tinfo + + @property + def xycoords(self): + return self._xycoords + + @xycoords.setter + def xycoords(self, xycoords): + def is_offset(s): + return isinstance(s, str) and s.startswith("offset") + + if (isinstance(xycoords, tuple) and any(map(is_offset, xycoords)) + or is_offset(xycoords)): + raise ValueError("xycoords cannot be an offset coordinate") + self._xycoords = xycoords + + @property + def xyann(self): + """ + The text position. + + See also *xytext* in `.Annotation`. + """ + return self.get_position() + + @xyann.setter + def xyann(self, xytext): + self.set_position(xytext) + + def get_anncoords(self): + """ + Return the coordinate system to use for `.Annotation.xyann`. + + See also *xycoords* in `.Annotation`. + """ + return self._textcoords + + def set_anncoords(self, coords): + """ + Set the coordinate system to use for `.Annotation.xyann`. + + See also *xycoords* in `.Annotation`. + """ + self._textcoords = coords + + anncoords = property(get_anncoords, set_anncoords, doc=""" + The coordinate system to use for `.Annotation.xyann`.""") + + def set_figure(self, fig): + # docstring inherited + if self.arrow_patch is not None: + self.arrow_patch.set_figure(fig) + Artist.set_figure(self, fig) + + def update_positions(self, renderer): + """ + Update the pixel positions of the annotation text and the arrow patch. + """ + # generate transformation + self.set_transform(self._get_xy_transform(renderer, self.anncoords)) + + arrowprops = self.arrowprops + if arrowprops is None: + return + + bbox = Text.get_window_extent(self, renderer) + + arrow_end = x1, y1 = self._get_position_xy(renderer) # Annotated pos. + + ms = arrowprops.get("mutation_scale", self.get_size()) + self.arrow_patch.set_mutation_scale(ms) + + if "arrowstyle" not in arrowprops: + # Approximately simulate the YAArrow. + shrink = arrowprops.get('shrink', 0.0) + width = arrowprops.get('width', 4) + headwidth = arrowprops.get('headwidth', 12) + headlength = arrowprops.get('headlength', 12) + + # NB: ms is in pts + stylekw = dict(head_length=headlength / ms, + head_width=headwidth / ms, + tail_width=width / ms) + + self.arrow_patch.set_arrowstyle('simple', **stylekw) + + # using YAArrow style: + # pick the corner of the text bbox closest to annotated point. + xpos = [(bbox.x0, 0), ((bbox.x0 + bbox.x1) / 2, 0.5), (bbox.x1, 1)] + ypos = [(bbox.y0, 0), ((bbox.y0 + bbox.y1) / 2, 0.5), (bbox.y1, 1)] + x, relposx = min(xpos, key=lambda v: abs(v[0] - x1)) + y, relposy = min(ypos, key=lambda v: abs(v[0] - y1)) + self._arrow_relpos = (relposx, relposy) + r = np.hypot(y - y1, x - x1) + shrink_pts = shrink * r / renderer.points_to_pixels(1) + self.arrow_patch.shrinkA = self.arrow_patch.shrinkB = shrink_pts + + # adjust the starting point of the arrow relative to the textbox. + # TODO : Rotation needs to be accounted. + arrow_begin = bbox.p0 + bbox.size * self._arrow_relpos + # The arrow is drawn from arrow_begin to arrow_end. It will be first + # clipped by patchA and patchB. Then it will be shrunk by shrinkA and + # shrinkB (in points). If patchA is not set, self.bbox_patch is used. + self.arrow_patch.set_positions(arrow_begin, arrow_end) + + if "patchA" in arrowprops: + patchA = arrowprops["patchA"] + elif self._bbox_patch: + patchA = self._bbox_patch + elif self.get_text() == "": + patchA = None + else: + pad = renderer.points_to_pixels(4) + patchA = Rectangle( + xy=(bbox.x0 - pad / 2, bbox.y0 - pad / 2), + width=bbox.width + pad, height=bbox.height + pad, + transform=IdentityTransform(), clip_on=False) + self.arrow_patch.set_patchA(patchA) + + @artist.allow_rasterization + def draw(self, renderer): + # docstring inherited + if renderer is not None: + self._renderer = renderer + if not self.get_visible() or not self._check_xy(renderer): + return + # Update text positions before `Text.draw` would, so that the + # FancyArrowPatch is correctly positioned. + self.update_positions(renderer) + self.update_bbox_position_size(renderer) + if self.arrow_patch is not None: # FancyArrowPatch + if self.arrow_patch.figure is None and self.figure is not None: + self.arrow_patch.figure = self.figure + self.arrow_patch.draw(renderer) + # Draw text, including FancyBboxPatch, after FancyArrowPatch. + # Otherwise, a wedge arrowstyle can land partly on top of the Bbox. + Text.draw(self, renderer) + + def get_window_extent(self, renderer=None): + # docstring inherited + # This block is the same as in Text.get_window_extent, but we need to + # set the renderer before calling update_positions(). + if not self.get_visible() or not self._check_xy(renderer): + return Bbox.unit() + if renderer is not None: + self._renderer = renderer + if self._renderer is None: + self._renderer = self.figure._get_renderer() + if self._renderer is None: + raise RuntimeError('Cannot get window extent without renderer') + + self.update_positions(self._renderer) + + text_bbox = Text.get_window_extent(self) + bboxes = [text_bbox] + + if self.arrow_patch is not None: + bboxes.append(self.arrow_patch.get_window_extent()) + + return Bbox.union(bboxes) + + def get_tightbbox(self, renderer=None): + # docstring inherited + if not self._check_xy(renderer): + return Bbox.null() + return super().get_tightbbox(renderer) + + +_docstring.interpd.update(Annotation=Annotation.__init__.__doc__) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.pyi new file mode 100644 index 00000000..6a83b1bb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/text.pyi @@ -0,0 +1,214 @@ +from .artist import Artist +from .backend_bases import RendererBase +from .font_manager import FontProperties +from .offsetbox import DraggableAnnotation +from .path import Path +from .patches import FancyArrowPatch, FancyBboxPatch +from .textpath import ( # noqa: reexported API + TextPath as TextPath, + TextToPath as TextToPath, +) +from .transforms import ( + Bbox, + BboxBase, + Transform, +) + +from collections.abc import Callable, Iterable +from typing import Any, Literal +from .typing import ColorType + +class Text(Artist): + zorder: float + def __init__( + self, + x: float = ..., + y: float = ..., + text: Any = ..., + *, + color: ColorType | None = ..., + verticalalignment: Literal[ + "bottom", "baseline", "center", "center_baseline", "top" + ] = ..., + horizontalalignment: Literal["left", "center", "right"] = ..., + multialignment: Literal["left", "center", "right"] | None = ..., + fontproperties: str | Path | FontProperties | None = ..., + rotation: float | Literal["vertical", "horizontal"] | None = ..., + linespacing: float | None = ..., + rotation_mode: Literal["default", "anchor"] | None = ..., + usetex: bool | None = ..., + wrap: bool = ..., + transform_rotates_text: bool = ..., + parse_math: bool | None = ..., + antialiased: bool | None = ..., + **kwargs + ) -> None: ... + def update(self, kwargs: dict[str, Any]) -> list[Any]: ... + def get_rotation(self) -> float: ... + def get_transform_rotates_text(self) -> bool: ... + def set_rotation_mode(self, m: None | Literal["default", "anchor"]) -> None: ... + def get_rotation_mode(self) -> Literal["default", "anchor"]: ... + def set_bbox(self, rectprops: dict[str, Any]) -> None: ... + def get_bbox_patch(self) -> None | FancyBboxPatch: ... + def update_bbox_position_size(self, renderer: RendererBase) -> None: ... + def get_wrap(self) -> bool: ... + def set_wrap(self, wrap: bool) -> None: ... + def get_color(self) -> ColorType: ... + def get_fontproperties(self) -> FontProperties: ... + def get_fontfamily(self) -> list[str]: ... + def get_fontname(self) -> str: ... + def get_fontstyle(self) -> Literal["normal", "italic", "oblique"]: ... + def get_fontsize(self) -> float | str: ... + def get_fontvariant(self) -> Literal["normal", "small-caps"]: ... + def get_fontweight(self) -> int | str: ... + def get_stretch(self) -> int | str: ... + def get_horizontalalignment(self) -> Literal["left", "center", "right"]: ... + def get_unitless_position(self) -> tuple[float, float]: ... + def get_position(self) -> tuple[float, float]: ... + def get_text(self) -> str: ... + def get_verticalalignment( + self, + ) -> Literal["bottom", "baseline", "center", "center_baseline", "top"]: ... + def get_window_extent( + self, renderer: RendererBase | None = ..., dpi: float | None = ... + ) -> Bbox: ... + def set_backgroundcolor(self, color: ColorType) -> None: ... + def set_color(self, color: ColorType) -> None: ... + def set_horizontalalignment( + self, align: Literal["left", "center", "right"] + ) -> None: ... + def set_multialignment(self, align: Literal["left", "center", "right"]) -> None: ... + def set_linespacing(self, spacing: float) -> None: ... + def set_fontfamily(self, fontname: str | Iterable[str]) -> None: ... + def set_fontvariant(self, variant: Literal["normal", "small-caps"]) -> None: ... + def set_fontstyle( + self, fontstyle: Literal["normal", "italic", "oblique"] + ) -> None: ... + def set_fontsize(self, fontsize: float | str) -> None: ... + def get_math_fontfamily(self) -> str: ... + def set_math_fontfamily(self, fontfamily: str) -> None: ... + def set_fontweight(self, weight: int | str) -> None: ... + def set_fontstretch(self, stretch: int | str) -> None: ... + def set_position(self, xy: tuple[float, float]) -> None: ... + def set_x(self, x: float) -> None: ... + def set_y(self, y: float) -> None: ... + def set_rotation(self, s: float) -> None: ... + def set_transform_rotates_text(self, t: bool) -> None: ... + def set_verticalalignment( + self, align: Literal["bottom", "baseline", "center", "center_baseline", "top"] + ) -> None: ... + def set_text(self, s: Any) -> None: ... + def set_fontproperties(self, fp: FontProperties | str | Path | None) -> None: ... + def set_usetex(self, usetex: bool | None) -> None: ... + def get_usetex(self) -> bool: ... + def set_parse_math(self, parse_math: bool) -> None: ... + def get_parse_math(self) -> bool: ... + def set_fontname(self, fontname: str | Iterable[str]) -> None: ... + def get_antialiased(self) -> bool: ... + def set_antialiased(self, antialiased: bool) -> None: ... + +class OffsetFrom: + def __init__( + self, + artist: Artist | BboxBase | Transform, + ref_coord: tuple[float, float], + unit: Literal["points", "pixels"] = ..., + ) -> None: ... + def set_unit(self, unit: Literal["points", "pixels"]) -> None: ... + def get_unit(self) -> Literal["points", "pixels"]: ... + def __call__(self, renderer: RendererBase) -> Transform: ... + +class _AnnotationBase: + xy: tuple[float, float] + xycoords: str | tuple[str, str] | Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ] + def __init__( + self, + xy, + xycoords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] = ..., + annotation_clip: bool | None = ..., + ) -> None: ... + def set_annotation_clip(self, b: bool | None) -> None: ... + def get_annotation_clip(self) -> bool | None: ... + def draggable( + self, state: bool | None = ..., use_blit: bool = ... + ) -> DraggableAnnotation | None: ... + +class Annotation(Text, _AnnotationBase): + arrowprops: dict[str, Any] | None + arrow_patch: FancyArrowPatch | None + def __init__( + self, + text: str, + xy: tuple[float, float], + xytext: tuple[float, float] | None = ..., + xycoords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] = ..., + textcoords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform] + | None = ..., + arrowprops: dict[str, Any] | None = ..., + annotation_clip: bool | None = ..., + **kwargs + ) -> None: ... + @property + def xycoords( + self, + ) -> str | tuple[str, str] | Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ]: ... + @xycoords.setter + def xycoords( + self, + xycoords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform], + ) -> None: ... + @property + def xyann(self) -> tuple[float, float]: ... + @xyann.setter + def xyann(self, xytext: tuple[float, float]) -> None: ... + def get_anncoords( + self, + ) -> str | tuple[str, str] | Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ]: ... + def set_anncoords( + self, + coords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform], + ) -> None: ... + @property + def anncoords( + self, + ) -> str | tuple[str, str] | Artist | Transform | Callable[ + [RendererBase], Bbox | Transform + ]: ... + @anncoords.setter + def anncoords( + self, + coords: str + | tuple[str, str] + | Artist + | Transform + | Callable[[RendererBase], Bbox | Transform], + ) -> None: ... + def update_positions(self, renderer: RendererBase) -> None: ... + # Drops `dpi` parameter from superclass + def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... # type: ignore[override] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.py new file mode 100644 index 00000000..c00966d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.py @@ -0,0 +1,397 @@ +from collections import OrderedDict +import logging +import urllib.parse + +import numpy as np + +from matplotlib import _text_helpers, dviread +from matplotlib.font_manager import ( + FontProperties, get_font, fontManager as _fontManager +) +from matplotlib.ft2font import LOAD_NO_HINTING, LOAD_TARGET_LIGHT +from matplotlib.mathtext import MathTextParser +from matplotlib.path import Path +from matplotlib.texmanager import TexManager +from matplotlib.transforms import Affine2D + +_log = logging.getLogger(__name__) + + +class TextToPath: + """A class that converts strings to paths.""" + + FONT_SCALE = 100. + DPI = 72 + + def __init__(self): + self.mathtext_parser = MathTextParser('path') + self._texmanager = None + + def _get_font(self, prop): + """ + Find the `FT2Font` matching font properties *prop*, with its size set. + """ + filenames = _fontManager._find_fonts_by_props(prop) + font = get_font(filenames) + font.set_size(self.FONT_SCALE, self.DPI) + return font + + def _get_hinting_flag(self): + return LOAD_NO_HINTING + + def _get_char_id(self, font, ccode): + """ + Return a unique id for the given font and character-code set. + """ + return urllib.parse.quote(f"{font.postscript_name}-{ccode:x}") + + def get_text_width_height_descent(self, s, prop, ismath): + fontsize = prop.get_size_in_points() + + if ismath == "TeX": + return TexManager().get_text_width_height_descent(s, fontsize) + + scale = fontsize / self.FONT_SCALE + + if ismath: + prop = prop.copy() + prop.set_size(self.FONT_SCALE) + width, height, descent, *_ = \ + self.mathtext_parser.parse(s, 72, prop) + return width * scale, height * scale, descent * scale + + font = self._get_font(prop) + font.set_text(s, 0.0, flags=LOAD_NO_HINTING) + w, h = font.get_width_height() + w /= 64.0 # convert from subpixels + h /= 64.0 + d = font.get_descent() + d /= 64.0 + return w * scale, h * scale, d * scale + + def get_text_path(self, prop, s, ismath=False): + """ + Convert text *s* to path (a tuple of vertices and codes for + matplotlib.path.Path). + + Parameters + ---------- + prop : `~matplotlib.font_manager.FontProperties` + The font properties for the text. + s : str + The text to be converted. + ismath : {False, True, "TeX"} + If True, use mathtext parser. If "TeX", use tex for rendering. + + Returns + ------- + verts : list + A list of arrays containing the (x, y) coordinates of the vertices. + codes : list + A list of path codes. + + Examples + -------- + Create a list of vertices and codes from a text, and create a `.Path` + from those:: + + from matplotlib.path import Path + from matplotlib.text import TextToPath + from matplotlib.font_manager import FontProperties + + fp = FontProperties(family="Comic Neue", style="italic") + verts, codes = TextToPath().get_text_path(fp, "ABC") + path = Path(verts, codes, closed=False) + + Also see `TextPath` for a more direct way to create a path from a text. + """ + if ismath == "TeX": + glyph_info, glyph_map, rects = self.get_glyphs_tex(prop, s) + elif not ismath: + font = self._get_font(prop) + glyph_info, glyph_map, rects = self.get_glyphs_with_font(font, s) + else: + glyph_info, glyph_map, rects = self.get_glyphs_mathtext(prop, s) + + verts, codes = [], [] + for glyph_id, xposition, yposition, scale in glyph_info: + verts1, codes1 = glyph_map[glyph_id] + verts.extend(verts1 * scale + [xposition, yposition]) + codes.extend(codes1) + for verts1, codes1 in rects: + verts.extend(verts1) + codes.extend(codes1) + + # Make sure an empty string or one with nothing to print + # (e.g. only spaces & newlines) will be valid/empty path + if not verts: + verts = np.empty((0, 2)) + + return verts, codes + + def get_glyphs_with_font(self, font, s, glyph_map=None, + return_new_glyphs_only=False): + """ + Convert string *s* to vertices and codes using the provided ttf font. + """ + + if glyph_map is None: + glyph_map = OrderedDict() + + if return_new_glyphs_only: + glyph_map_new = OrderedDict() + else: + glyph_map_new = glyph_map + + xpositions = [] + glyph_ids = [] + for item in _text_helpers.layout(s, font): + char_id = self._get_char_id(item.ft_object, ord(item.char)) + glyph_ids.append(char_id) + xpositions.append(item.x) + if char_id not in glyph_map: + glyph_map_new[char_id] = item.ft_object.get_path() + + ypositions = [0] * len(xpositions) + sizes = [1.] * len(xpositions) + + rects = [] + + return (list(zip(glyph_ids, xpositions, ypositions, sizes)), + glyph_map_new, rects) + + def get_glyphs_mathtext(self, prop, s, glyph_map=None, + return_new_glyphs_only=False): + """ + Parse mathtext string *s* and convert it to a (vertices, codes) pair. + """ + + prop = prop.copy() + prop.set_size(self.FONT_SCALE) + + width, height, descent, glyphs, rects = self.mathtext_parser.parse( + s, self.DPI, prop) + + if not glyph_map: + glyph_map = OrderedDict() + + if return_new_glyphs_only: + glyph_map_new = OrderedDict() + else: + glyph_map_new = glyph_map + + xpositions = [] + ypositions = [] + glyph_ids = [] + sizes = [] + + for font, fontsize, ccode, ox, oy in glyphs: + char_id = self._get_char_id(font, ccode) + if char_id not in glyph_map: + font.clear() + font.set_size(self.FONT_SCALE, self.DPI) + font.load_char(ccode, flags=LOAD_NO_HINTING) + glyph_map_new[char_id] = font.get_path() + + xpositions.append(ox) + ypositions.append(oy) + glyph_ids.append(char_id) + size = fontsize / self.FONT_SCALE + sizes.append(size) + + myrects = [] + for ox, oy, w, h in rects: + vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h), + (ox + w, oy), (ox, oy), (0, 0)] + code1 = [Path.MOVETO, + Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, + Path.CLOSEPOLY] + myrects.append((vert1, code1)) + + return (list(zip(glyph_ids, xpositions, ypositions, sizes)), + glyph_map_new, myrects) + + def get_glyphs_tex(self, prop, s, glyph_map=None, + return_new_glyphs_only=False): + """Convert the string *s* to vertices and codes using usetex mode.""" + # Mostly borrowed from pdf backend. + + dvifile = TexManager().make_dvi(s, self.FONT_SCALE) + with dviread.Dvi(dvifile, self.DPI) as dvi: + page, = dvi + + if glyph_map is None: + glyph_map = OrderedDict() + + if return_new_glyphs_only: + glyph_map_new = OrderedDict() + else: + glyph_map_new = glyph_map + + glyph_ids, xpositions, ypositions, sizes = [], [], [], [] + + # Gather font information and do some setup for combining + # characters into strings. + for text in page.text: + font = get_font(text.font_path) + char_id = self._get_char_id(font, text.glyph) + if char_id not in glyph_map: + font.clear() + font.set_size(self.FONT_SCALE, self.DPI) + glyph_name_or_index = text.glyph_name_or_index + if isinstance(glyph_name_or_index, str): + index = font.get_name_index(glyph_name_or_index) + font.load_glyph(index, flags=LOAD_TARGET_LIGHT) + elif isinstance(glyph_name_or_index, int): + self._select_native_charmap(font) + font.load_char( + glyph_name_or_index, flags=LOAD_TARGET_LIGHT) + else: # Should not occur. + raise TypeError(f"Glyph spec of unexpected type: " + f"{glyph_name_or_index!r}") + glyph_map_new[char_id] = font.get_path() + + glyph_ids.append(char_id) + xpositions.append(text.x) + ypositions.append(text.y) + sizes.append(text.font_size / self.FONT_SCALE) + + myrects = [] + + for ox, oy, h, w in page.boxes: + vert1 = [(ox, oy), (ox + w, oy), (ox + w, oy + h), + (ox, oy + h), (ox, oy), (0, 0)] + code1 = [Path.MOVETO, + Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, + Path.CLOSEPOLY] + myrects.append((vert1, code1)) + + return (list(zip(glyph_ids, xpositions, ypositions, sizes)), + glyph_map_new, myrects) + + @staticmethod + def _select_native_charmap(font): + # Select the native charmap. (we can't directly identify it but it's + # typically an Adobe charmap). + for charmap_code in [ + 1094992451, # ADOBE_CUSTOM. + 1094995778, # ADOBE_STANDARD. + ]: + try: + font.select_charmap(charmap_code) + except (ValueError, RuntimeError): + pass + else: + break + else: + _log.warning("No supported encoding in font (%s).", font.fname) + + +text_to_path = TextToPath() + + +class TextPath(Path): + """ + Create a path from the text. + """ + + def __init__(self, xy, s, size=None, prop=None, + _interpolation_steps=1, usetex=False): + r""" + Create a path from the text. Note that it simply is a path, + not an artist. You need to use the `.PathPatch` (or other artists) + to draw this path onto the canvas. + + Parameters + ---------- + xy : tuple or array of two float values + Position of the text. For no offset, use ``xy=(0, 0)``. + + s : str + The text to convert to a path. + + size : float, optional + Font size in points. Defaults to the size specified via the font + properties *prop*. + + prop : `~matplotlib.font_manager.FontProperties`, optional + Font property. If not provided, will use a default + `.FontProperties` with parameters from the + :ref:`rcParams<customizing-with-dynamic-rc-settings>`. + + _interpolation_steps : int, optional + (Currently ignored) + + usetex : bool, default: False + Whether to use tex rendering. + + Examples + -------- + The following creates a path from the string "ABC" with Helvetica + font face; and another path from the latex fraction 1/2:: + + from matplotlib.text import TextPath + from matplotlib.font_manager import FontProperties + + fp = FontProperties(family="Helvetica", style="italic") + path1 = TextPath((12, 12), "ABC", size=12, prop=fp) + path2 = TextPath((0, 0), r"$\frac{1}{2}$", size=12, usetex=True) + + Also see :doc:`/gallery/text_labels_and_annotations/demo_text_path`. + """ + # Circular import. + from matplotlib.text import Text + + prop = FontProperties._from_any(prop) + if size is None: + size = prop.get_size_in_points() + + self._xy = xy + self.set_size(size) + + self._cached_vertices = None + s, ismath = Text(usetex=usetex)._preprocess_math(s) + super().__init__( + *text_to_path.get_text_path(prop, s, ismath=ismath), + _interpolation_steps=_interpolation_steps, + readonly=True) + self._should_simplify = False + + def set_size(self, size): + """Set the text size.""" + self._size = size + self._invalid = True + + def get_size(self): + """Get the text size.""" + return self._size + + @property + def vertices(self): + """ + Return the cached path after updating it if necessary. + """ + self._revalidate_path() + return self._cached_vertices + + @property + def codes(self): + """ + Return the codes + """ + return self._codes + + def _revalidate_path(self): + """ + Update the path if necessary. + + The path for the text is initially create with the font size of + `.FONT_SCALE`, and this path is rescaled to other size when necessary. + """ + if self._invalid or self._cached_vertices is None: + tr = (Affine2D() + .scale(self._size / text_to_path.FONT_SCALE) + .translate(*self._xy)) + self._cached_vertices = tr.transform(self._vertices) + self._cached_vertices.flags.writeable = False + self._invalid = False diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.pyi new file mode 100644 index 00000000..34d4e92a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/textpath.pyi @@ -0,0 +1,74 @@ +from matplotlib.font_manager import FontProperties +from matplotlib.ft2font import FT2Font +from matplotlib.mathtext import MathTextParser, VectorParse +from matplotlib.path import Path + +import numpy as np + +from typing import Literal + +class TextToPath: + FONT_SCALE: float + DPI: float + mathtext_parser: MathTextParser[VectorParse] + def __init__(self) -> None: ... + def get_text_width_height_descent( + self, s: str, prop: FontProperties, ismath: bool | Literal["TeX"] + ) -> tuple[float, float, float]: ... + def get_text_path( + self, prop: FontProperties, s: str, ismath: bool | Literal["TeX"] = ... + ) -> list[np.ndarray]: ... + def get_glyphs_with_font( + self, + font: FT2Font, + s: str, + glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ..., + return_new_glyphs_only: bool = ..., + ) -> tuple[ + list[tuple[str, float, float, float]], + dict[str, tuple[np.ndarray, np.ndarray]], + list[tuple[list[tuple[float, float]], list[int]]], + ]: ... + def get_glyphs_mathtext( + self, + prop: FontProperties, + s: str, + glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ..., + return_new_glyphs_only: bool = ..., + ) -> tuple[ + list[tuple[str, float, float, float]], + dict[str, tuple[np.ndarray, np.ndarray]], + list[tuple[list[tuple[float, float]], list[int]]], + ]: ... + def get_glyphs_tex( + self, + prop: FontProperties, + s: str, + glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ..., + return_new_glyphs_only: bool = ..., + ) -> tuple[ + list[tuple[str, float, float, float]], + dict[str, tuple[np.ndarray, np.ndarray]], + list[tuple[list[tuple[float, float]], list[int]]], + ]: ... + +text_to_path: TextToPath + +class TextPath(Path): + def __init__( + self, + xy: tuple[float, float], + s: str, + size: float | None = ..., + prop: FontProperties | None = ..., + _interpolation_steps: int = ..., + usetex: bool = ..., + ) -> None: ... + def set_size(self, size: float | None) -> None: ... + def get_size(self) -> float | None: ... + + # These are read only... there actually are protections in the base class, so probably can be deleted... + @property # type: ignore[misc] + def vertices(self) -> np.ndarray: ... # type: ignore[override] + @property # type: ignore[misc] + def codes(self) -> np.ndarray: ... # type: ignore[override] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.py new file mode 100644 index 00000000..5b1b7e11 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.py @@ -0,0 +1,2942 @@ +""" +Tick locating and formatting +============================ + +This module contains classes for configuring tick locating and formatting. +Generic tick locators and formatters are provided, as well as domain specific +custom ones. + +Although the locators know nothing about major or minor ticks, they are used +by the Axis class to support major and minor tick locating and formatting. + +.. _tick_locating: +.. _locators: + +Tick locating +------------- + +The Locator class is the base class for all tick locators. The locators +handle autoscaling of the view limits based on the data limits, and the +choosing of tick locations. A useful semi-automatic tick locator is +`MultipleLocator`. It is initialized with a base, e.g., 10, and it picks +axis limits and ticks that are multiples of that base. + +The Locator subclasses defined here are: + +======================= ======================================================= +`AutoLocator` `MaxNLocator` with simple defaults. This is the default + tick locator for most plotting. +`MaxNLocator` Finds up to a max number of intervals with ticks at + nice locations. +`LinearLocator` Space ticks evenly from min to max. +`LogLocator` Space ticks logarithmically from min to max. +`MultipleLocator` Ticks and range are a multiple of base; either integer + or float. +`FixedLocator` Tick locations are fixed. +`IndexLocator` Locator for index plots (e.g., where + ``x = range(len(y))``). +`NullLocator` No ticks. +`SymmetricalLogLocator` Locator for use with the symlog norm; works like + `LogLocator` for the part outside of the threshold and + adds 0 if inside the limits. +`AsinhLocator` Locator for use with the asinh norm, attempting to + space ticks approximately uniformly. +`LogitLocator` Locator for logit scaling. +`AutoMinorLocator` Locator for minor ticks when the axis is linear and the + major ticks are uniformly spaced. Subdivides the major + tick interval into a specified number of minor + intervals, defaulting to 4 or 5 depending on the major + interval. +======================= ======================================================= + +There are a number of locators specialized for date locations - see +the :mod:`.dates` module. + +You can define your own locator by deriving from Locator. You must +override the ``__call__`` method, which returns a sequence of locations, +and you will probably want to override the autoscale method to set the +view limits from the data limits. + +If you want to override the default locator, use one of the above or a custom +locator and pass it to the x- or y-axis instance. The relevant methods are:: + + ax.xaxis.set_major_locator(xmajor_locator) + ax.xaxis.set_minor_locator(xminor_locator) + ax.yaxis.set_major_locator(ymajor_locator) + ax.yaxis.set_minor_locator(yminor_locator) + +The default minor locator is `NullLocator`, i.e., no minor ticks on by default. + +.. note:: + `Locator` instances should not be used with more than one + `~matplotlib.axis.Axis` or `~matplotlib.axes.Axes`. So instead of:: + + locator = MultipleLocator(5) + ax.xaxis.set_major_locator(locator) + ax2.xaxis.set_major_locator(locator) + + do the following instead:: + + ax.xaxis.set_major_locator(MultipleLocator(5)) + ax2.xaxis.set_major_locator(MultipleLocator(5)) + +.. _formatters: + +Tick formatting +--------------- + +Tick formatting is controlled by classes derived from Formatter. The formatter +operates on a single tick value and returns a string to the axis. + +========================= ===================================================== +`NullFormatter` No labels on the ticks. +`FixedFormatter` Set the strings manually for the labels. +`FuncFormatter` User defined function sets the labels. +`StrMethodFormatter` Use string `format` method. +`FormatStrFormatter` Use an old-style sprintf format string. +`ScalarFormatter` Default formatter for scalars: autopick the format + string. +`LogFormatter` Formatter for log axes. +`LogFormatterExponent` Format values for log axis using + ``exponent = log_base(value)``. +`LogFormatterMathtext` Format values for log axis using + ``exponent = log_base(value)`` using Math text. +`LogFormatterSciNotation` Format values for log axis using scientific notation. +`LogitFormatter` Probability formatter. +`EngFormatter` Format labels in engineering notation. +`PercentFormatter` Format labels as a percentage. +========================= ===================================================== + +You can derive your own formatter from the Formatter base class by +simply overriding the ``__call__`` method. The formatter class has +access to the axis view and data limits. + +To control the major and minor tick label formats, use one of the +following methods:: + + ax.xaxis.set_major_formatter(xmajor_formatter) + ax.xaxis.set_minor_formatter(xminor_formatter) + ax.yaxis.set_major_formatter(ymajor_formatter) + ax.yaxis.set_minor_formatter(yminor_formatter) + +In addition to a `.Formatter` instance, `~.Axis.set_major_formatter` and +`~.Axis.set_minor_formatter` also accept a ``str`` or function. ``str`` input +will be internally replaced with an autogenerated `.StrMethodFormatter` with +the input ``str``. For function input, a `.FuncFormatter` with the input +function will be generated and used. + +See :doc:`/gallery/ticks/major_minor_demo` for an example of setting major +and minor ticks. See the :mod:`matplotlib.dates` module for more information +and examples of using date locators and formatters. +""" + +import itertools +import logging +import locale +import math +from numbers import Integral + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook +from matplotlib import transforms as mtransforms + +_log = logging.getLogger(__name__) + +__all__ = ('TickHelper', 'Formatter', 'FixedFormatter', + 'NullFormatter', 'FuncFormatter', 'FormatStrFormatter', + 'StrMethodFormatter', 'ScalarFormatter', 'LogFormatter', + 'LogFormatterExponent', 'LogFormatterMathtext', + 'LogFormatterSciNotation', + 'LogitFormatter', 'EngFormatter', 'PercentFormatter', + 'Locator', 'IndexLocator', 'FixedLocator', 'NullLocator', + 'LinearLocator', 'LogLocator', 'AutoLocator', + 'MultipleLocator', 'MaxNLocator', 'AutoMinorLocator', + 'SymmetricalLogLocator', 'AsinhLocator', 'LogitLocator') + + +class _DummyAxis: + __name__ = "dummy" + + def __init__(self, minpos=0): + self._data_interval = (0, 1) + self._view_interval = (0, 1) + self._minpos = minpos + + def get_view_interval(self): + return self._view_interval + + def set_view_interval(self, vmin, vmax): + self._view_interval = (vmin, vmax) + + def get_minpos(self): + return self._minpos + + def get_data_interval(self): + return self._data_interval + + def set_data_interval(self, vmin, vmax): + self._data_interval = (vmin, vmax) + + def get_tick_space(self): + # Just use the long-standing default of nbins==9 + return 9 + + +class TickHelper: + axis = None + + def set_axis(self, axis): + self.axis = axis + + def create_dummy_axis(self, **kwargs): + if self.axis is None: + self.axis = _DummyAxis(**kwargs) + + +class Formatter(TickHelper): + """ + Create a string based on a tick value and location. + """ + # some classes want to see all the locs to help format + # individual ones + locs = [] + + def __call__(self, x, pos=None): + """ + Return the format for tick value *x* at position pos. + ``pos=None`` indicates an unspecified location. + """ + raise NotImplementedError('Derived must override') + + def format_ticks(self, values): + """Return the tick labels for all the ticks at once.""" + self.set_locs(values) + return [self(value, i) for i, value in enumerate(values)] + + def format_data(self, value): + """ + Return the full string representation of the value with the + position unspecified. + """ + return self.__call__(value) + + def format_data_short(self, value): + """ + Return a short string version of the tick value. + + Defaults to the position-independent long value. + """ + return self.format_data(value) + + def get_offset(self): + return '' + + def set_locs(self, locs): + """ + Set the locations of the ticks. + + This method is called before computing the tick labels because some + formatters need to know all tick locations to do so. + """ + self.locs = locs + + @staticmethod + def fix_minus(s): + """ + Some classes may want to replace a hyphen for minus with the proper + Unicode symbol (U+2212) for typographical correctness. This is a + helper method to perform such a replacement when it is enabled via + :rc:`axes.unicode_minus`. + """ + return (s.replace('-', '\N{MINUS SIGN}') + if mpl.rcParams['axes.unicode_minus'] + else s) + + def _set_locator(self, locator): + """Subclasses may want to override this to set a locator.""" + pass + + +class NullFormatter(Formatter): + """Always return the empty string.""" + + def __call__(self, x, pos=None): + # docstring inherited + return '' + + +class FixedFormatter(Formatter): + """ + Return fixed strings for tick labels based only on position, not value. + + .. note:: + `.FixedFormatter` should only be used together with `.FixedLocator`. + Otherwise, the labels may end up in unexpected positions. + """ + + def __init__(self, seq): + """Set the sequence *seq* of strings that will be used for labels.""" + self.seq = seq + self.offset_string = '' + + def __call__(self, x, pos=None): + """ + Return the label that matches the position, regardless of the value. + + For positions ``pos < len(seq)``, return ``seq[i]`` regardless of + *x*. Otherwise return empty string. ``seq`` is the sequence of + strings that this object was initialized with. + """ + if pos is None or pos >= len(self.seq): + return '' + else: + return self.seq[pos] + + def get_offset(self): + return self.offset_string + + def set_offset_string(self, ofs): + self.offset_string = ofs + + +class FuncFormatter(Formatter): + """ + Use a user-defined function for formatting. + + The function should take in two inputs (a tick value ``x`` and a + position ``pos``), and return a string containing the corresponding + tick label. + """ + + def __init__(self, func): + self.func = func + self.offset_string = "" + + def __call__(self, x, pos=None): + """ + Return the value of the user defined function. + + *x* and *pos* are passed through as-is. + """ + return self.func(x, pos) + + def get_offset(self): + return self.offset_string + + def set_offset_string(self, ofs): + self.offset_string = ofs + + +class FormatStrFormatter(Formatter): + """ + Use an old-style ('%' operator) format string to format the tick. + + The format string should have a single variable format (%) in it. + It will be applied to the value (not the position) of the tick. + + Negative numeric values will use a dash, not a Unicode minus; use mathtext + to get a Unicode minus by wrapping the format specifier with $ (e.g. + "$%g$"). + """ + def __init__(self, fmt): + self.fmt = fmt + + def __call__(self, x, pos=None): + """ + Return the formatted label string. + + Only the value *x* is formatted. The position is ignored. + """ + return self.fmt % x + + +class StrMethodFormatter(Formatter): + """ + Use a new-style format string (as used by `str.format`) to format the tick. + + The field used for the tick value must be labeled *x* and the field used + for the tick position must be labeled *pos*. + """ + def __init__(self, fmt): + self.fmt = fmt + + def __call__(self, x, pos=None): + """ + Return the formatted label string. + + *x* and *pos* are passed to `str.format` as keyword arguments + with those exact names. + """ + return self.fmt.format(x=x, pos=pos) + + +class ScalarFormatter(Formatter): + """ + Format tick values as a number. + + Parameters + ---------- + useOffset : bool or float, default: :rc:`axes.formatter.useoffset` + Whether to use offset notation. See `.set_useOffset`. + useMathText : bool, default: :rc:`axes.formatter.use_mathtext` + Whether to use fancy math formatting. See `.set_useMathText`. + useLocale : bool, default: :rc:`axes.formatter.use_locale`. + Whether to use locale settings for decimal sign and positive sign. + See `.set_useLocale`. + + Notes + ----- + In addition to the parameters above, the formatting of scientific vs. + floating point representation can be configured via `.set_scientific` + and `.set_powerlimits`). + + **Offset notation and scientific notation** + + Offset notation and scientific notation look quite similar at first sight. + Both split some information from the formatted tick values and display it + at the end of the axis. + + - The scientific notation splits up the order of magnitude, i.e. a + multiplicative scaling factor, e.g. ``1e6``. + + - The offset notation separates an additive constant, e.g. ``+1e6``. The + offset notation label is always prefixed with a ``+`` or ``-`` sign + and is thus distinguishable from the order of magnitude label. + + The following plot with x limits ``1_000_000`` to ``1_000_010`` illustrates + the different formatting. Note the labels at the right edge of the x axis. + + .. plot:: + + lim = (1_000_000, 1_000_010) + + fig, (ax1, ax2, ax3) = plt.subplots(3, 1, gridspec_kw={'hspace': 2}) + ax1.set(title='offset_notation', xlim=lim) + ax2.set(title='scientific notation', xlim=lim) + ax2.xaxis.get_major_formatter().set_useOffset(False) + ax3.set(title='floating point notation', xlim=lim) + ax3.xaxis.get_major_formatter().set_useOffset(False) + ax3.xaxis.get_major_formatter().set_scientific(False) + + """ + + def __init__(self, useOffset=None, useMathText=None, useLocale=None): + if useOffset is None: + useOffset = mpl.rcParams['axes.formatter.useoffset'] + self._offset_threshold = \ + mpl.rcParams['axes.formatter.offset_threshold'] + self.set_useOffset(useOffset) + self._usetex = mpl.rcParams['text.usetex'] + self.set_useMathText(useMathText) + self.orderOfMagnitude = 0 + self.format = '' + self._scientific = True + self._powerlimits = mpl.rcParams['axes.formatter.limits'] + self.set_useLocale(useLocale) + + def get_useOffset(self): + """ + Return whether automatic mode for offset notation is active. + + This returns True if ``set_useOffset(True)``; it returns False if an + explicit offset was set, e.g. ``set_useOffset(1000)``. + + See Also + -------- + ScalarFormatter.set_useOffset + """ + return self._useOffset + + def set_useOffset(self, val): + """ + Set whether to use offset notation. + + When formatting a set numbers whose value is large compared to their + range, the formatter can separate an additive constant. This can + shorten the formatted numbers so that they are less likely to overlap + when drawn on an axis. + + Parameters + ---------- + val : bool or float + - If False, do not use offset notation. + - If True (=automatic mode), use offset notation if it can make + the residual numbers significantly shorter. The exact behavior + is controlled by :rc:`axes.formatter.offset_threshold`. + - If a number, force an offset of the given value. + + Examples + -------- + With active offset notation, the values + + ``100_000, 100_002, 100_004, 100_006, 100_008`` + + will be formatted as ``0, 2, 4, 6, 8`` plus an offset ``+1e5``, which + is written to the edge of the axis. + """ + if val in [True, False]: + self.offset = 0 + self._useOffset = val + else: + self._useOffset = False + self.offset = val + + useOffset = property(fget=get_useOffset, fset=set_useOffset) + + def get_useLocale(self): + """ + Return whether locale settings are used for formatting. + + See Also + -------- + ScalarFormatter.set_useLocale + """ + return self._useLocale + + def set_useLocale(self, val): + """ + Set whether to use locale settings for decimal sign and positive sign. + + Parameters + ---------- + val : bool or None + *None* resets to :rc:`axes.formatter.use_locale`. + """ + if val is None: + self._useLocale = mpl.rcParams['axes.formatter.use_locale'] + else: + self._useLocale = val + + useLocale = property(fget=get_useLocale, fset=set_useLocale) + + def _format_maybe_minus_and_locale(self, fmt, arg): + """ + Format *arg* with *fmt*, applying Unicode minus and locale if desired. + """ + return self.fix_minus( + # Escape commas introduced by locale.format_string if using math text, + # but not those present from the beginning in fmt. + (",".join(locale.format_string(part, (arg,), True).replace(",", "{,}") + for part in fmt.split(",")) if self._useMathText + else locale.format_string(fmt, (arg,), True)) + if self._useLocale + else fmt % arg) + + def get_useMathText(self): + """ + Return whether to use fancy math formatting. + + See Also + -------- + ScalarFormatter.set_useMathText + """ + return self._useMathText + + def set_useMathText(self, val): + r""" + Set whether to use fancy math formatting. + + If active, scientific notation is formatted as :math:`1.2 \times 10^3`. + + Parameters + ---------- + val : bool or None + *None* resets to :rc:`axes.formatter.use_mathtext`. + """ + if val is None: + self._useMathText = mpl.rcParams['axes.formatter.use_mathtext'] + if self._useMathText is False: + try: + from matplotlib import font_manager + ufont = font_manager.findfont( + font_manager.FontProperties( + mpl.rcParams["font.family"] + ), + fallback_to_default=False, + ) + except ValueError: + ufont = None + + if ufont == str(cbook._get_data_path("fonts/ttf/cmr10.ttf")): + _api.warn_external( + "cmr10 font should ideally be used with " + "mathtext, set axes.formatter.use_mathtext to True" + ) + else: + self._useMathText = val + + useMathText = property(fget=get_useMathText, fset=set_useMathText) + + def __call__(self, x, pos=None): + """ + Return the format for tick value *x* at position *pos*. + """ + if len(self.locs) == 0: + return '' + else: + xp = (x - self.offset) / (10. ** self.orderOfMagnitude) + if abs(xp) < 1e-8: + xp = 0 + return self._format_maybe_minus_and_locale(self.format, xp) + + def set_scientific(self, b): + """ + Turn scientific notation on or off. + + See Also + -------- + ScalarFormatter.set_powerlimits + """ + self._scientific = bool(b) + + def set_powerlimits(self, lims): + r""" + Set size thresholds for scientific notation. + + Parameters + ---------- + lims : (int, int) + A tuple *(min_exp, max_exp)* containing the powers of 10 that + determine the switchover threshold. For a number representable as + :math:`a \times 10^\mathrm{exp}` with :math:`1 <= |a| < 10`, + scientific notation will be used if ``exp <= min_exp`` or + ``exp >= max_exp``. + + The default limits are controlled by :rc:`axes.formatter.limits`. + + In particular numbers with *exp* equal to the thresholds are + written in scientific notation. + + Typically, *min_exp* will be negative and *max_exp* will be + positive. + + For example, ``formatter.set_powerlimits((-3, 4))`` will provide + the following formatting: + :math:`1 \times 10^{-3}, 9.9 \times 10^{-3}, 0.01,` + :math:`9999, 1 \times 10^4`. + + See Also + -------- + ScalarFormatter.set_scientific + """ + if len(lims) != 2: + raise ValueError("'lims' must be a sequence of length 2") + self._powerlimits = lims + + def format_data_short(self, value): + # docstring inherited + if value is np.ma.masked: + return "" + if isinstance(value, Integral): + fmt = "%d" + else: + if getattr(self.axis, "__name__", "") in ["xaxis", "yaxis"]: + if self.axis.__name__ == "xaxis": + axis_trf = self.axis.axes.get_xaxis_transform() + axis_inv_trf = axis_trf.inverted() + screen_xy = axis_trf.transform((value, 0)) + neighbor_values = axis_inv_trf.transform( + screen_xy + [[-1, 0], [+1, 0]])[:, 0] + else: # yaxis: + axis_trf = self.axis.axes.get_yaxis_transform() + axis_inv_trf = axis_trf.inverted() + screen_xy = axis_trf.transform((0, value)) + neighbor_values = axis_inv_trf.transform( + screen_xy + [[0, -1], [0, +1]])[:, 1] + delta = abs(neighbor_values - value).max() + else: + # Rough approximation: no more than 1e4 divisions. + a, b = self.axis.get_view_interval() + delta = (b - a) / 1e4 + fmt = f"%-#.{cbook._g_sig_digits(value, delta)}g" + return self._format_maybe_minus_and_locale(fmt, value) + + def format_data(self, value): + # docstring inherited + e = math.floor(math.log10(abs(value))) + s = round(value / 10**e, 10) + significand = self._format_maybe_minus_and_locale( + "%d" if s % 1 == 0 else "%1.10g", s) + if e == 0: + return significand + exponent = self._format_maybe_minus_and_locale("%d", e) + if self._useMathText or self._usetex: + exponent = "10^{%s}" % exponent + return (exponent if s == 1 # reformat 1x10^y as 10^y + else rf"{significand} \times {exponent}") + else: + return f"{significand}e{exponent}" + + def get_offset(self): + """ + Return scientific notation, plus offset. + """ + if len(self.locs) == 0: + return '' + if self.orderOfMagnitude or self.offset: + offsetStr = '' + sciNotStr = '' + if self.offset: + offsetStr = self.format_data(self.offset) + if self.offset > 0: + offsetStr = '+' + offsetStr + if self.orderOfMagnitude: + if self._usetex or self._useMathText: + sciNotStr = self.format_data(10 ** self.orderOfMagnitude) + else: + sciNotStr = '1e%d' % self.orderOfMagnitude + if self._useMathText or self._usetex: + if sciNotStr != '': + sciNotStr = r'\times\mathdefault{%s}' % sciNotStr + s = fr'${sciNotStr}\mathdefault{{{offsetStr}}}$' + else: + s = ''.join((sciNotStr, offsetStr)) + return self.fix_minus(s) + return '' + + def set_locs(self, locs): + # docstring inherited + self.locs = locs + if len(self.locs) > 0: + if self._useOffset: + self._compute_offset() + self._set_order_of_magnitude() + self._set_format() + + def _compute_offset(self): + locs = self.locs + # Restrict to visible ticks. + vmin, vmax = sorted(self.axis.get_view_interval()) + locs = np.asarray(locs) + locs = locs[(vmin <= locs) & (locs <= vmax)] + if not len(locs): + self.offset = 0 + return + lmin, lmax = locs.min(), locs.max() + # Only use offset if there are at least two ticks and every tick has + # the same sign. + if lmin == lmax or lmin <= 0 <= lmax: + self.offset = 0 + return + # min, max comparing absolute values (we want division to round towards + # zero so we work on absolute values). + abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))]) + sign = math.copysign(1, lmin) + # What is the smallest power of ten such that abs_min and abs_max are + # equal up to that precision? + # Note: Internally using oom instead of 10 ** oom avoids some numerical + # accuracy issues. + oom_max = np.ceil(math.log10(abs_max)) + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) + if abs_min // 10 ** oom != abs_max // 10 ** oom) + if (abs_max - abs_min) / 10 ** oom <= 1e-2: + # Handle the case of straddling a multiple of a large power of ten + # (relative to the span). + # What is the smallest power of ten such that abs_min and abs_max + # are no more than 1 apart at that precision? + oom = 1 + next(oom for oom in itertools.count(oom_max, -1) + if abs_max // 10 ** oom - abs_min // 10 ** oom > 1) + # Only use offset if it saves at least _offset_threshold digits. + n = self._offset_threshold - 1 + self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom + if abs_max // 10 ** oom >= 10**n + else 0) + + def _set_order_of_magnitude(self): + # if scientific notation is to be used, find the appropriate exponent + # if using a numerical offset, find the exponent after applying the + # offset. When lower power limit = upper <> 0, use provided exponent. + if not self._scientific: + self.orderOfMagnitude = 0 + return + if self._powerlimits[0] == self._powerlimits[1] != 0: + # fixed scaling when lower power limit = upper <> 0. + self.orderOfMagnitude = self._powerlimits[0] + return + # restrict to visible ticks + vmin, vmax = sorted(self.axis.get_view_interval()) + locs = np.asarray(self.locs) + locs = locs[(vmin <= locs) & (locs <= vmax)] + locs = np.abs(locs) + if not len(locs): + self.orderOfMagnitude = 0 + return + if self.offset: + oom = math.floor(math.log10(vmax - vmin)) + else: + val = locs.max() + if val == 0: + oom = 0 + else: + oom = math.floor(math.log10(val)) + if oom <= self._powerlimits[0]: + self.orderOfMagnitude = oom + elif oom >= self._powerlimits[1]: + self.orderOfMagnitude = oom + else: + self.orderOfMagnitude = 0 + + def _set_format(self): + # set the format string to format all the ticklabels + if len(self.locs) < 2: + # Temporarily augment the locations with the axis end points. + _locs = [*self.locs, *self.axis.get_view_interval()] + else: + _locs = self.locs + locs = (np.asarray(_locs) - self.offset) / 10. ** self.orderOfMagnitude + loc_range = np.ptp(locs) + # Curvilinear coordinates can yield two identical points. + if loc_range == 0: + loc_range = np.max(np.abs(locs)) + # Both points might be zero. + if loc_range == 0: + loc_range = 1 + if len(self.locs) < 2: + # We needed the end points only for the loc_range calculation. + locs = locs[:-2] + loc_range_oom = int(math.floor(math.log10(loc_range))) + # first estimate: + sigfigs = max(0, 3 - loc_range_oom) + # refined estimate: + thresh = 1e-3 * 10 ** loc_range_oom + while sigfigs >= 0: + if np.abs(locs - np.round(locs, decimals=sigfigs)).max() < thresh: + sigfigs -= 1 + else: + break + sigfigs += 1 + self.format = f'%1.{sigfigs}f' + if self._usetex or self._useMathText: + self.format = r'$\mathdefault{%s}$' % self.format + + +class LogFormatter(Formatter): + """ + Base class for formatting ticks on a log or symlog scale. + + It may be instantiated directly, or subclassed. + + Parameters + ---------- + base : float, default: 10. + Base of the logarithm used in all calculations. + + labelOnlyBase : bool, default: False + If True, label ticks only at integer powers of base. + This is normally True for major ticks and False for + minor ticks. + + minor_thresholds : (subset, all), default: (1, 0.4) + If labelOnlyBase is False, these two numbers control + the labeling of ticks that are not at integer powers of + base; normally these are the minor ticks. The controlling + parameter is the log of the axis data range. In the typical + case where base is 10 it is the number of decades spanned + by the axis, so we can call it 'numdec'. If ``numdec <= all``, + all minor ticks will be labeled. If ``all < numdec <= subset``, + then only a subset of minor ticks will be labeled, so as to + avoid crowding. If ``numdec > subset`` then no minor ticks will + be labeled. + + linthresh : None or float, default: None + If a symmetric log scale is in use, its ``linthresh`` + parameter must be supplied here. + + Notes + ----- + The `set_locs` method must be called to enable the subsetting + logic controlled by the ``minor_thresholds`` parameter. + + In some cases such as the colorbar, there is no distinction between + major and minor ticks; the tick locations might be set manually, + or by a locator that puts ticks at integer powers of base and + at intermediate locations. For this situation, disable the + minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``, + so that all ticks will be labeled. + + To disable labeling of minor ticks when 'labelOnlyBase' is False, + use ``minor_thresholds=(0, 0)``. This is the default for the + "classic" style. + + Examples + -------- + To label a subset of minor ticks when the view limits span up + to 2 decades, and all of the ticks when zoomed in to 0.5 decades + or less, use ``minor_thresholds=(2, 0.5)``. + + To label all minor ticks when the view limits span up to 1.5 + decades, use ``minor_thresholds=(1.5, 1.5)``. + """ + + def __init__(self, base=10.0, labelOnlyBase=False, + minor_thresholds=None, + linthresh=None): + + self.set_base(base) + self.set_label_minor(labelOnlyBase) + if minor_thresholds is None: + if mpl.rcParams['_internal.classic_mode']: + minor_thresholds = (0, 0) + else: + minor_thresholds = (1, 0.4) + self.minor_thresholds = minor_thresholds + self._sublabels = None + self._linthresh = linthresh + + def set_base(self, base): + """ + Change the *base* for labeling. + + .. warning:: + Should always match the base used for :class:`LogLocator` + """ + self._base = float(base) + + def set_label_minor(self, labelOnlyBase): + """ + Switch minor tick labeling on or off. + + Parameters + ---------- + labelOnlyBase : bool + If True, label ticks only at integer powers of base. + """ + self.labelOnlyBase = labelOnlyBase + + def set_locs(self, locs=None): + """ + Use axis view limits to control which ticks are labeled. + + The *locs* parameter is ignored in the present algorithm. + """ + if np.isinf(self.minor_thresholds[0]): + self._sublabels = None + return + + # Handle symlog case: + linthresh = self._linthresh + if linthresh is None: + try: + linthresh = self.axis.get_transform().linthresh + except AttributeError: + pass + + vmin, vmax = self.axis.get_view_interval() + if vmin > vmax: + vmin, vmax = vmax, vmin + + if linthresh is None and vmin <= 0: + # It's probably a colorbar with + # a format kwarg setting a LogFormatter in the manner + # that worked with 1.5.x, but that doesn't work now. + self._sublabels = {1} # label powers of base + return + + b = self._base + if linthresh is not None: # symlog + # Only compute the number of decades in the logarithmic part of the + # axis + numdec = 0 + if vmin < -linthresh: + rhs = min(vmax, -linthresh) + numdec += math.log(vmin / rhs) / math.log(b) + if vmax > linthresh: + lhs = max(vmin, linthresh) + numdec += math.log(vmax / lhs) / math.log(b) + else: + vmin = math.log(vmin) / math.log(b) + vmax = math.log(vmax) / math.log(b) + numdec = abs(vmax - vmin) + + if numdec > self.minor_thresholds[0]: + # Label only bases + self._sublabels = {1} + elif numdec > self.minor_thresholds[1]: + # Add labels between bases at log-spaced coefficients; + # include base powers in case the locations include + # "major" and "minor" points, as in colorbar. + c = np.geomspace(1, b, int(b)//2 + 1) + self._sublabels = set(np.round(c)) + # For base 10, this yields (1, 2, 3, 4, 6, 10). + else: + # Label all integer multiples of base**n. + self._sublabels = set(np.arange(1, b + 1)) + + def _num_to_string(self, x, vmin, vmax): + if x > 10000: + s = '%1.0e' % x + elif x < 1: + s = '%1.0e' % x + else: + s = self._pprint_val(x, vmax - vmin) + return s + + def __call__(self, x, pos=None): + # docstring inherited + if x == 0.0: # Symlog + return '0' + + x = abs(x) + b = self._base + # only label the decades + fx = math.log(x) / math.log(b) + is_x_decade = _is_close_to_int(fx) + exponent = round(fx) if is_x_decade else np.floor(fx) + coeff = round(b ** (fx - exponent)) + + if self.labelOnlyBase and not is_x_decade: + return '' + if self._sublabels is not None and coeff not in self._sublabels: + return '' + + vmin, vmax = self.axis.get_view_interval() + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + s = self._num_to_string(x, vmin, vmax) + return self.fix_minus(s) + + def format_data(self, value): + with cbook._setattr_cm(self, labelOnlyBase=False): + return cbook.strip_math(self.__call__(value)) + + def format_data_short(self, value): + # docstring inherited + return '%-12g' % value + + def _pprint_val(self, x, d): + # If the number is not too big and it's an int, format it as an int. + if abs(x) < 1e4 and x == int(x): + return '%d' % x + fmt = ('%1.3e' if d < 1e-2 else + '%1.3f' if d <= 1 else + '%1.2f' if d <= 10 else + '%1.1f' if d <= 1e5 else + '%1.1e') + s = fmt % x + tup = s.split('e') + if len(tup) == 2: + mantissa = tup[0].rstrip('0').rstrip('.') + exponent = int(tup[1]) + if exponent: + s = '%se%d' % (mantissa, exponent) + else: + s = mantissa + else: + s = s.rstrip('0').rstrip('.') + return s + + +class LogFormatterExponent(LogFormatter): + """ + Format values for log axis using ``exponent = log_base(value)``. + """ + def _num_to_string(self, x, vmin, vmax): + fx = math.log(x) / math.log(self._base) + if abs(fx) > 10000: + s = '%1.0g' % fx + elif abs(fx) < 1: + s = '%1.0g' % fx + else: + fd = math.log(vmax - vmin) / math.log(self._base) + s = self._pprint_val(fx, fd) + return s + + +class LogFormatterMathtext(LogFormatter): + """ + Format values for log axis using ``exponent = log_base(value)``. + """ + + def _non_decade_format(self, sign_string, base, fx, usetex): + """Return string for non-decade locations.""" + return r'$\mathdefault{%s%s^{%.2f}}$' % (sign_string, base, fx) + + def __call__(self, x, pos=None): + # docstring inherited + if x == 0: # Symlog + return r'$\mathdefault{0}$' + + sign_string = '-' if x < 0 else '' + x = abs(x) + b = self._base + + # only label the decades + fx = math.log(x) / math.log(b) + is_x_decade = _is_close_to_int(fx) + exponent = round(fx) if is_x_decade else np.floor(fx) + coeff = round(b ** (fx - exponent)) + + if self.labelOnlyBase and not is_x_decade: + return '' + if self._sublabels is not None and coeff not in self._sublabels: + return '' + + if is_x_decade: + fx = round(fx) + + # use string formatting of the base if it is not an integer + if b % 1 == 0.0: + base = '%d' % b + else: + base = '%s' % b + + if abs(fx) < mpl.rcParams['axes.formatter.min_exponent']: + return r'$\mathdefault{%s%g}$' % (sign_string, x) + elif not is_x_decade: + usetex = mpl.rcParams['text.usetex'] + return self._non_decade_format(sign_string, base, fx, usetex) + else: + return r'$\mathdefault{%s%s^{%d}}$' % (sign_string, base, fx) + + +class LogFormatterSciNotation(LogFormatterMathtext): + """ + Format values following scientific notation in a logarithmic axis. + """ + + def _non_decade_format(self, sign_string, base, fx, usetex): + """Return string for non-decade locations.""" + b = float(base) + exponent = math.floor(fx) + coeff = b ** (fx - exponent) + if _is_close_to_int(coeff): + coeff = round(coeff) + return r'$\mathdefault{%s%g\times%s^{%d}}$' \ + % (sign_string, coeff, base, exponent) + + +class LogitFormatter(Formatter): + """ + Probability formatter (using Math text). + """ + + def __init__( + self, + *, + use_overline=False, + one_half=r"\frac{1}{2}", + minor=False, + minor_threshold=25, + minor_number=6, + ): + r""" + Parameters + ---------- + use_overline : bool, default: False + If x > 1/2, with x = 1-v, indicate if x should be displayed as + $\overline{v}$. The default is to display $1-v$. + + one_half : str, default: r"\frac{1}{2}" + The string used to represent 1/2. + + minor : bool, default: False + Indicate if the formatter is formatting minor ticks or not. + Basically minor ticks are not labelled, except when only few ticks + are provided, ticks with most space with neighbor ticks are + labelled. See other parameters to change the default behavior. + + minor_threshold : int, default: 25 + Maximum number of locs for labelling some minor ticks. This + parameter have no effect if minor is False. + + minor_number : int, default: 6 + Number of ticks which are labelled when the number of ticks is + below the threshold. + """ + self._use_overline = use_overline + self._one_half = one_half + self._minor = minor + self._labelled = set() + self._minor_threshold = minor_threshold + self._minor_number = minor_number + + def use_overline(self, use_overline): + r""" + Switch display mode with overline for labelling p>1/2. + + Parameters + ---------- + use_overline : bool, default: False + If x > 1/2, with x = 1-v, indicate if x should be displayed as + $\overline{v}$. The default is to display $1-v$. + """ + self._use_overline = use_overline + + def set_one_half(self, one_half): + r""" + Set the way one half is displayed. + + one_half : str, default: r"\frac{1}{2}" + The string used to represent 1/2. + """ + self._one_half = one_half + + def set_minor_threshold(self, minor_threshold): + """ + Set the threshold for labelling minors ticks. + + Parameters + ---------- + minor_threshold : int + Maximum number of locations for labelling some minor ticks. This + parameter have no effect if minor is False. + """ + self._minor_threshold = minor_threshold + + def set_minor_number(self, minor_number): + """ + Set the number of minor ticks to label when some minor ticks are + labelled. + + Parameters + ---------- + minor_number : int + Number of ticks which are labelled when the number of ticks is + below the threshold. + """ + self._minor_number = minor_number + + def set_locs(self, locs): + self.locs = np.array(locs) + self._labelled.clear() + + if not self._minor: + return None + if all( + _is_decade(x, rtol=1e-7) + or _is_decade(1 - x, rtol=1e-7) + or (_is_close_to_int(2 * x) and + int(np.round(2 * x)) == 1) + for x in locs + ): + # minor ticks are subsample from ideal, so no label + return None + if len(locs) < self._minor_threshold: + if len(locs) < self._minor_number: + self._labelled.update(locs) + else: + # we do not have a lot of minor ticks, so only few decades are + # displayed, then we choose some (spaced) minor ticks to label. + # Only minor ticks are known, we assume it is sufficient to + # choice which ticks are displayed. + # For each ticks we compute the distance between the ticks and + # the previous, and between the ticks and the next one. Ticks + # with smallest minimum are chosen. As tiebreak, the ticks + # with smallest sum is chosen. + diff = np.diff(-np.log(1 / self.locs - 1)) + space_pessimistic = np.minimum( + np.concatenate(((np.inf,), diff)), + np.concatenate((diff, (np.inf,))), + ) + space_sum = ( + np.concatenate(((0,), diff)) + + np.concatenate((diff, (0,))) + ) + good_minor = sorted( + range(len(self.locs)), + key=lambda i: (space_pessimistic[i], space_sum[i]), + )[-self._minor_number:] + self._labelled.update(locs[i] for i in good_minor) + + def _format_value(self, x, locs, sci_notation=True): + if sci_notation: + exponent = math.floor(np.log10(x)) + min_precision = 0 + else: + exponent = 0 + min_precision = 1 + value = x * 10 ** (-exponent) + if len(locs) < 2: + precision = min_precision + else: + diff = np.sort(np.abs(locs - x))[1] + precision = -np.log10(diff) + exponent + precision = ( + int(np.round(precision)) + if _is_close_to_int(precision) + else math.ceil(precision) + ) + if precision < min_precision: + precision = min_precision + mantissa = r"%.*f" % (precision, value) + if not sci_notation: + return mantissa + s = r"%s\cdot10^{%d}" % (mantissa, exponent) + return s + + def _one_minus(self, s): + if self._use_overline: + return r"\overline{%s}" % s + else: + return f"1-{s}" + + def __call__(self, x, pos=None): + if self._minor and x not in self._labelled: + return "" + if x <= 0 or x >= 1: + return "" + if _is_close_to_int(2 * x) and round(2 * x) == 1: + s = self._one_half + elif x < 0.5 and _is_decade(x, rtol=1e-7): + exponent = round(math.log10(x)) + s = "10^{%d}" % exponent + elif x > 0.5 and _is_decade(1 - x, rtol=1e-7): + exponent = round(math.log10(1 - x)) + s = self._one_minus("10^{%d}" % exponent) + elif x < 0.1: + s = self._format_value(x, self.locs) + elif x > 0.9: + s = self._one_minus(self._format_value(1-x, 1-self.locs)) + else: + s = self._format_value(x, self.locs, sci_notation=False) + return r"$\mathdefault{%s}$" % s + + def format_data_short(self, value): + # docstring inherited + # Thresholds chosen to use scientific notation iff exponent <= -2. + if value < 0.1: + return f"{value:e}" + if value < 0.9: + return f"{value:f}" + return f"1-{1 - value:e}" + + +class EngFormatter(Formatter): + """ + Format axis values using engineering prefixes to represent powers + of 1000, plus a specified unit, e.g., 10 MHz instead of 1e7. + """ + + # The SI engineering prefixes + ENG_PREFIXES = { + -30: "q", + -27: "r", + -24: "y", + -21: "z", + -18: "a", + -15: "f", + -12: "p", + -9: "n", + -6: "\N{MICRO SIGN}", + -3: "m", + 0: "", + 3: "k", + 6: "M", + 9: "G", + 12: "T", + 15: "P", + 18: "E", + 21: "Z", + 24: "Y", + 27: "R", + 30: "Q" + } + + def __init__(self, unit="", places=None, sep=" ", *, usetex=None, + useMathText=None): + r""" + Parameters + ---------- + unit : str, default: "" + Unit symbol to use, suitable for use with single-letter + representations of powers of 1000. For example, 'Hz' or 'm'. + + places : int, default: None + Precision with which to display the number, specified in + digits after the decimal point (there will be between one + and three digits before the decimal point). If it is None, + the formatting falls back to the floating point format '%g', + which displays up to 6 *significant* digits, i.e. the equivalent + value for *places* varies between 0 and 5 (inclusive). + + sep : str, default: " " + Separator used between the value and the prefix/unit. For + example, one get '3.14 mV' if ``sep`` is " " (default) and + '3.14mV' if ``sep`` is "". Besides the default behavior, some + other useful options may be: + + * ``sep=""`` to append directly the prefix/unit to the value; + * ``sep="\N{THIN SPACE}"`` (``U+2009``); + * ``sep="\N{NARROW NO-BREAK SPACE}"`` (``U+202F``); + * ``sep="\N{NO-BREAK SPACE}"`` (``U+00A0``). + + usetex : bool, default: :rc:`text.usetex` + To enable/disable the use of TeX's math mode for rendering the + numbers in the formatter. + + useMathText : bool, default: :rc:`axes.formatter.use_mathtext` + To enable/disable the use mathtext for rendering the numbers in + the formatter. + """ + self.unit = unit + self.places = places + self.sep = sep + self.set_usetex(usetex) + self.set_useMathText(useMathText) + + def get_usetex(self): + return self._usetex + + def set_usetex(self, val): + if val is None: + self._usetex = mpl.rcParams['text.usetex'] + else: + self._usetex = val + + usetex = property(fget=get_usetex, fset=set_usetex) + + def get_useMathText(self): + return self._useMathText + + def set_useMathText(self, val): + if val is None: + self._useMathText = mpl.rcParams['axes.formatter.use_mathtext'] + else: + self._useMathText = val + + useMathText = property(fget=get_useMathText, fset=set_useMathText) + + def __call__(self, x, pos=None): + s = f"{self.format_eng(x)}{self.unit}" + # Remove the trailing separator when there is neither prefix nor unit + if self.sep and s.endswith(self.sep): + s = s[:-len(self.sep)] + return self.fix_minus(s) + + def format_eng(self, num): + """ + Format a number in engineering notation, appending a letter + representing the power of 1000 of the original number. + Some examples: + + >>> format_eng(0) # for self.places = 0 + '0' + + >>> format_eng(1000000) # for self.places = 1 + '1.0 M' + + >>> format_eng(-1e-6) # for self.places = 2 + '-1.00 \N{MICRO SIGN}' + """ + sign = 1 + fmt = "g" if self.places is None else f".{self.places:d}f" + + if num < 0: + sign = -1 + num = -num + + if num != 0: + pow10 = int(math.floor(math.log10(num) / 3) * 3) + else: + pow10 = 0 + # Force num to zero, to avoid inconsistencies like + # format_eng(-0) = "0" and format_eng(0.0) = "0" + # but format_eng(-0.0) = "-0.0" + num = 0.0 + + pow10 = np.clip(pow10, min(self.ENG_PREFIXES), max(self.ENG_PREFIXES)) + + mant = sign * num / (10.0 ** pow10) + # Taking care of the cases like 999.9..., which may be rounded to 1000 + # instead of 1 k. Beware of the corner case of values that are beyond + # the range of SI prefixes (i.e. > 'Y'). + if (abs(float(format(mant, fmt))) >= 1000 + and pow10 < max(self.ENG_PREFIXES)): + mant /= 1000 + pow10 += 3 + + prefix = self.ENG_PREFIXES[int(pow10)] + if self._usetex or self._useMathText: + formatted = f"${mant:{fmt}}${self.sep}{prefix}" + else: + formatted = f"{mant:{fmt}}{self.sep}{prefix}" + + return formatted + + +class PercentFormatter(Formatter): + """ + Format numbers as a percentage. + + Parameters + ---------- + xmax : float + Determines how the number is converted into a percentage. + *xmax* is the data value that corresponds to 100%. + Percentages are computed as ``x / xmax * 100``. So if the data is + already scaled to be percentages, *xmax* will be 100. Another common + situation is where *xmax* is 1.0. + + decimals : None or int + The number of decimal places to place after the point. + If *None* (the default), the number will be computed automatically. + + symbol : str or None + A string that will be appended to the label. It may be + *None* or empty to indicate that no symbol should be used. LaTeX + special characters are escaped in *symbol* whenever latex mode is + enabled, unless *is_latex* is *True*. + + is_latex : bool + If *False*, reserved LaTeX characters in *symbol* will be escaped. + """ + def __init__(self, xmax=100, decimals=None, symbol='%', is_latex=False): + self.xmax = xmax + 0.0 + self.decimals = decimals + self._symbol = symbol + self._is_latex = is_latex + + def __call__(self, x, pos=None): + """Format the tick as a percentage with the appropriate scaling.""" + ax_min, ax_max = self.axis.get_view_interval() + display_range = abs(ax_max - ax_min) + return self.fix_minus(self.format_pct(x, display_range)) + + def format_pct(self, x, display_range): + """ + Format the number as a percentage number with the correct + number of decimals and adds the percent symbol, if any. + + If ``self.decimals`` is `None`, the number of digits after the + decimal point is set based on the *display_range* of the axis + as follows: + + ============= ======== ======================= + display_range decimals sample + ============= ======== ======================= + >50 0 ``x = 34.5`` => 35% + >5 1 ``x = 34.5`` => 34.5% + >0.5 2 ``x = 34.5`` => 34.50% + ... ... ... + ============= ======== ======================= + + This method will not be very good for tiny axis ranges or + extremely large ones. It assumes that the values on the chart + are percentages displayed on a reasonable scale. + """ + x = self.convert_to_pct(x) + if self.decimals is None: + # conversion works because display_range is a difference + scaled_range = self.convert_to_pct(display_range) + if scaled_range <= 0: + decimals = 0 + else: + # Luckily Python's built-in ceil rounds to +inf, not away from + # zero. This is very important since the equation for decimals + # starts out as `scaled_range > 0.5 * 10**(2 - decimals)` + # and ends up with `decimals > 2 - log10(2 * scaled_range)`. + decimals = math.ceil(2.0 - math.log10(2.0 * scaled_range)) + if decimals > 5: + decimals = 5 + elif decimals < 0: + decimals = 0 + else: + decimals = self.decimals + s = f'{x:0.{int(decimals)}f}' + + return s + self.symbol + + def convert_to_pct(self, x): + return 100.0 * (x / self.xmax) + + @property + def symbol(self): + r""" + The configured percent symbol as a string. + + If LaTeX is enabled via :rc:`text.usetex`, the special characters + ``{'#', '$', '%', '&', '~', '_', '^', '\', '{', '}'}`` are + automatically escaped in the string. + """ + symbol = self._symbol + if not symbol: + symbol = '' + elif not self._is_latex and mpl.rcParams['text.usetex']: + # Source: http://www.personal.ceu.hu/tex/specchar.htm + # Backslash must be first for this to work correctly since + # it keeps getting added in + for spec in r'\#$%&~_^{}': + symbol = symbol.replace(spec, '\\' + spec) + return symbol + + @symbol.setter + def symbol(self, symbol): + self._symbol = symbol + + +class Locator(TickHelper): + """ + Determine the tick locations; + + Note that the same locator should not be used across multiple + `~matplotlib.axis.Axis` because the locator stores references to the Axis + data and view limits. + """ + + # Some automatic tick locators can generate so many ticks they + # kill the machine when you try and render them. + # This parameter is set to cause locators to raise an error if too + # many ticks are generated. + MAXTICKS = 1000 + + def tick_values(self, vmin, vmax): + """ + Return the values of the located ticks given **vmin** and **vmax**. + + .. note:: + To get tick locations with the vmin and vmax values defined + automatically for the associated ``axis`` simply call + the Locator instance:: + + >>> print(type(loc)) + <type 'Locator'> + >>> print(loc()) + [1, 2, 3, 4] + + """ + raise NotImplementedError('Derived must override') + + def set_params(self, **kwargs): + """ + Do nothing, and raise a warning. Any locator class not supporting the + set_params() function will call this. + """ + _api.warn_external( + "'set_params()' not defined for locator of type " + + str(type(self))) + + def __call__(self): + """Return the locations of the ticks.""" + # note: some locators return data limits, other return view limits, + # hence there is no *one* interface to call self.tick_values. + raise NotImplementedError('Derived must override') + + def raise_if_exceeds(self, locs): + """ + Log at WARNING level if *locs* is longer than `Locator.MAXTICKS`. + + This is intended to be called immediately before returning *locs* from + ``__call__`` to inform users in case their Locator returns a huge + number of ticks, causing Matplotlib to run out of memory. + + The "strange" name of this method dates back to when it would raise an + exception instead of emitting a log. + """ + if len(locs) >= self.MAXTICKS: + _log.warning( + "Locator attempting to generate %s ticks ([%s, ..., %s]), " + "which exceeds Locator.MAXTICKS (%s).", + len(locs), locs[0], locs[-1], self.MAXTICKS) + return locs + + def nonsingular(self, v0, v1): + """ + Adjust a range as needed to avoid singularities. + + This method gets called during autoscaling, with ``(v0, v1)`` set to + the data limits on the axes if the axes contains any data, or + ``(-inf, +inf)`` if not. + + - If ``v0 == v1`` (possibly up to some floating point slop), this + method returns an expanded interval around this value. + - If ``(v0, v1) == (-inf, +inf)``, this method returns appropriate + default view limits. + - Otherwise, ``(v0, v1)`` is returned without modification. + """ + return mtransforms.nonsingular(v0, v1, expander=.05) + + def view_limits(self, vmin, vmax): + """ + Select a scale for the range from vmin to vmax. + + Subclasses should override this method to change locator behaviour. + """ + return mtransforms.nonsingular(vmin, vmax) + + +class IndexLocator(Locator): + """ + Place a tick on every multiple of some base number of points + plotted, e.g., on every 5th point. It is assumed that you are doing + index plotting; i.e., the axis is 0, len(data). This is mainly + useful for x ticks. + """ + def __init__(self, base, offset): + """Place ticks every *base* data point, starting at *offset*.""" + self._base = base + self.offset = offset + + def set_params(self, base=None, offset=None): + """Set parameters within this locator""" + if base is not None: + self._base = base + if offset is not None: + self.offset = offset + + def __call__(self): + """Return the locations of the ticks""" + dmin, dmax = self.axis.get_data_interval() + return self.tick_values(dmin, dmax) + + def tick_values(self, vmin, vmax): + return self.raise_if_exceeds( + np.arange(vmin + self.offset, vmax + 1, self._base)) + + +class FixedLocator(Locator): + """ + Tick locations are fixed at *locs*. If *nbins* is not None, + the *locs* array of possible positions will be subsampled to + keep the number of ticks <= *nbins* +1. + The subsampling will be done to include the smallest + absolute value; for example, if zero is included in the + array of possibilities, then it is guaranteed to be one of + the chosen ticks. + """ + + def __init__(self, locs, nbins=None): + self.locs = np.asarray(locs) + _api.check_shape((None,), locs=self.locs) + self.nbins = max(nbins, 2) if nbins is not None else None + + def set_params(self, nbins=None): + """Set parameters within this locator.""" + if nbins is not None: + self.nbins = nbins + + def __call__(self): + return self.tick_values(None, None) + + def tick_values(self, vmin, vmax): + """ + Return the locations of the ticks. + + .. note:: + + Because the values are fixed, vmin and vmax are not used in this + method. + + """ + if self.nbins is None: + return self.locs + step = max(int(np.ceil(len(self.locs) / self.nbins)), 1) + ticks = self.locs[::step] + for i in range(1, step): + ticks1 = self.locs[i::step] + if np.abs(ticks1).min() < np.abs(ticks).min(): + ticks = ticks1 + return self.raise_if_exceeds(ticks) + + +class NullLocator(Locator): + """ + No ticks + """ + + def __call__(self): + return self.tick_values(None, None) + + def tick_values(self, vmin, vmax): + """ + Return the locations of the ticks. + + .. note:: + + Because the values are Null, vmin and vmax are not used in this + method. + """ + return [] + + +class LinearLocator(Locator): + """ + Determine the tick locations + + The first time this function is called it will try to set the + number of ticks to make a nice tick partitioning. Thereafter, the + number of ticks will be fixed so that interactive navigation will + be nice + + """ + def __init__(self, numticks=None, presets=None): + """ + Parameters + ---------- + numticks : int or None, default None + Number of ticks. If None, *numticks* = 11. + presets : dict or None, default: None + Dictionary mapping ``(vmin, vmax)`` to an array of locations. + Overrides *numticks* if there is an entry for the current + ``(vmin, vmax)``. + """ + self.numticks = numticks + if presets is None: + self.presets = {} + else: + self.presets = presets + + @property + def numticks(self): + # Old hard-coded default. + return self._numticks if self._numticks is not None else 11 + + @numticks.setter + def numticks(self, numticks): + self._numticks = numticks + + def set_params(self, numticks=None, presets=None): + """Set parameters within this locator.""" + if presets is not None: + self.presets = presets + if numticks is not None: + self.numticks = numticks + + def __call__(self): + """Return the locations of the ticks.""" + vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + + if (vmin, vmax) in self.presets: + return self.presets[(vmin, vmax)] + + if self.numticks == 0: + return [] + ticklocs = np.linspace(vmin, vmax, self.numticks) + + return self.raise_if_exceeds(ticklocs) + + def view_limits(self, vmin, vmax): + """Try to choose the view limits intelligently.""" + + if vmax < vmin: + vmin, vmax = vmax, vmin + + if vmin == vmax: + vmin -= 1 + vmax += 1 + + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + exponent, remainder = divmod( + math.log10(vmax - vmin), math.log10(max(self.numticks - 1, 1))) + exponent -= (remainder < .5) + scale = max(self.numticks - 1, 1) ** (-exponent) + vmin = math.floor(scale * vmin) / scale + vmax = math.ceil(scale * vmax) / scale + + return mtransforms.nonsingular(vmin, vmax) + + +class MultipleLocator(Locator): + """ + Set a tick on each integer multiple of the *base* plus an *offset* within + the view interval. + """ + + def __init__(self, base=1.0, offset=0.0): + """ + Parameters + ---------- + base : float > 0 + Interval between ticks. + offset : float + Value added to each multiple of *base*. + + .. versionadded:: 3.8 + """ + self._edge = _Edge_integer(base, 0) + self._offset = offset + + def set_params(self, base=None, offset=None): + """ + Set parameters within this locator. + + Parameters + ---------- + base : float > 0 + Interval between ticks. + offset : float + Value added to each multiple of *base*. + + .. versionadded:: 3.8 + """ + if base is not None: + self._edge = _Edge_integer(base, 0) + if offset is not None: + self._offset = offset + + def __call__(self): + """Return the locations of the ticks.""" + vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + if vmax < vmin: + vmin, vmax = vmax, vmin + step = self._edge.step + vmin -= self._offset + vmax -= self._offset + vmin = self._edge.ge(vmin) * step + n = (vmax - vmin + 0.001 * step) // step + locs = vmin - step + np.arange(n + 3) * step + self._offset + return self.raise_if_exceeds(locs) + + def view_limits(self, dmin, dmax): + """ + Set the view limits to the nearest tick values that contain the data. + """ + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + vmin = self._edge.le(dmin - self._offset) * self._edge.step + self._offset + vmax = self._edge.ge(dmax - self._offset) * self._edge.step + self._offset + if vmin == vmax: + vmin -= 1 + vmax += 1 + else: + vmin = dmin + vmax = dmax + + return mtransforms.nonsingular(vmin, vmax) + + +def scale_range(vmin, vmax, n=1, threshold=100): + dv = abs(vmax - vmin) # > 0 as nonsingular is called before. + meanv = (vmax + vmin) / 2 + if abs(meanv) / dv < threshold: + offset = 0 + else: + offset = math.copysign(10 ** (math.log10(abs(meanv)) // 1), meanv) + scale = 10 ** (math.log10(dv / n) // 1) + return scale, offset + + +class _Edge_integer: + """ + Helper for `.MaxNLocator`, `.MultipleLocator`, etc. + + Take floating-point precision limitations into account when calculating + tick locations as integer multiples of a step. + """ + def __init__(self, step, offset): + """ + Parameters + ---------- + step : float > 0 + Interval between ticks. + offset : float + Offset subtracted from the data limits prior to calculating tick + locations. + """ + if step <= 0: + raise ValueError("'step' must be positive") + self.step = step + self._offset = abs(offset) + + def closeto(self, ms, edge): + # Allow more slop when the offset is large compared to the step. + if self._offset > 0: + digits = np.log10(self._offset / self.step) + tol = max(1e-10, 10 ** (digits - 12)) + tol = min(0.4999, tol) + else: + tol = 1e-10 + return abs(ms - edge) < tol + + def le(self, x): + """Return the largest n: n*step <= x.""" + d, m = divmod(x, self.step) + if self.closeto(m / self.step, 1): + return d + 1 + return d + + def ge(self, x): + """Return the smallest n: n*step >= x.""" + d, m = divmod(x, self.step) + if self.closeto(m / self.step, 0): + return d + return d + 1 + + +class MaxNLocator(Locator): + """ + Find nice tick locations with no more than *nbins* + 1 being within the + view limits. Locations beyond the limits are added to support autoscaling. + """ + default_params = dict(nbins=10, + steps=None, + integer=False, + symmetric=False, + prune=None, + min_n_ticks=2) + + def __init__(self, nbins=None, **kwargs): + """ + Parameters + ---------- + nbins : int or 'auto', default: 10 + Maximum number of intervals; one less than max number of + ticks. If the string 'auto', the number of bins will be + automatically determined based on the length of the axis. + + steps : array-like, optional + Sequence of acceptable tick multiples, starting with 1 and + ending with 10. For example, if ``steps=[1, 2, 4, 5, 10]``, + ``20, 40, 60`` or ``0.4, 0.6, 0.8`` would be possible + sets of ticks because they are multiples of 2. + ``30, 60, 90`` would not be generated because 3 does not + appear in this example list of steps. + + integer : bool, default: False + If True, ticks will take only integer values, provided at least + *min_n_ticks* integers are found within the view limits. + + symmetric : bool, default: False + If True, autoscaling will result in a range symmetric about zero. + + prune : {'lower', 'upper', 'both', None}, default: None + Remove the 'lower' tick, the 'upper' tick, or ticks on 'both' sides + *if they fall exactly on an axis' edge* (this typically occurs when + :rc:`axes.autolimit_mode` is 'round_numbers'). Removing such ticks + is mostly useful for stacked or ganged plots, where the upper tick + of an axes overlaps with the lower tick of the axes above it. + + min_n_ticks : int, default: 2 + Relax *nbins* and *integer* constraints if necessary to obtain + this minimum number of ticks. + """ + if nbins is not None: + kwargs['nbins'] = nbins + self.set_params(**{**self.default_params, **kwargs}) + + @staticmethod + def _validate_steps(steps): + if not np.iterable(steps): + raise ValueError('steps argument must be an increasing sequence ' + 'of numbers between 1 and 10 inclusive') + steps = np.asarray(steps) + if np.any(np.diff(steps) <= 0) or steps[-1] > 10 or steps[0] < 1: + raise ValueError('steps argument must be an increasing sequence ' + 'of numbers between 1 and 10 inclusive') + if steps[0] != 1: + steps = np.concatenate([[1], steps]) + if steps[-1] != 10: + steps = np.concatenate([steps, [10]]) + return steps + + @staticmethod + def _staircase(steps): + # Make an extended staircase within which the needed step will be + # found. This is probably much larger than necessary. + return np.concatenate([0.1 * steps[:-1], steps, [10 * steps[1]]]) + + def set_params(self, **kwargs): + """ + Set parameters for this locator. + + Parameters + ---------- + nbins : int or 'auto', optional + see `.MaxNLocator` + steps : array-like, optional + see `.MaxNLocator` + integer : bool, optional + see `.MaxNLocator` + symmetric : bool, optional + see `.MaxNLocator` + prune : {'lower', 'upper', 'both', None}, optional + see `.MaxNLocator` + min_n_ticks : int, optional + see `.MaxNLocator` + """ + if 'nbins' in kwargs: + self._nbins = kwargs.pop('nbins') + if self._nbins != 'auto': + self._nbins = int(self._nbins) + if 'symmetric' in kwargs: + self._symmetric = kwargs.pop('symmetric') + if 'prune' in kwargs: + prune = kwargs.pop('prune') + _api.check_in_list(['upper', 'lower', 'both', None], prune=prune) + self._prune = prune + if 'min_n_ticks' in kwargs: + self._min_n_ticks = max(1, kwargs.pop('min_n_ticks')) + if 'steps' in kwargs: + steps = kwargs.pop('steps') + if steps is None: + self._steps = np.array([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]) + else: + self._steps = self._validate_steps(steps) + self._extended_steps = self._staircase(self._steps) + if 'integer' in kwargs: + self._integer = kwargs.pop('integer') + if kwargs: + raise _api.kwarg_error("set_params", kwargs) + + def _raw_ticks(self, vmin, vmax): + """ + Generate a list of tick locations including the range *vmin* to + *vmax*. In some applications, one or both of the end locations + will not be needed, in which case they are trimmed off + elsewhere. + """ + if self._nbins == 'auto': + if self.axis is not None: + nbins = np.clip(self.axis.get_tick_space(), + max(1, self._min_n_ticks - 1), 9) + else: + nbins = 9 + else: + nbins = self._nbins + + scale, offset = scale_range(vmin, vmax, nbins) + _vmin = vmin - offset + _vmax = vmax - offset + steps = self._extended_steps * scale + if self._integer: + # For steps > 1, keep only integer values. + igood = (steps < 1) | (np.abs(steps - np.round(steps)) < 0.001) + steps = steps[igood] + + raw_step = ((_vmax - _vmin) / nbins) + large_steps = steps >= raw_step + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + # Classic round_numbers mode may require a larger step. + # Get first multiple of steps that are <= _vmin + floored_vmins = (_vmin // steps) * steps + floored_vmaxs = floored_vmins + steps * nbins + large_steps = large_steps & (floored_vmaxs >= _vmax) + + # Find index of smallest large step + istep = np.nonzero(large_steps)[0][0] + + # Start at smallest of the steps greater than the raw step, and check + # if it provides enough ticks. If not, work backwards through + # smaller steps until one is found that provides enough ticks. + for step in steps[:istep+1][::-1]: + + if (self._integer and + np.floor(_vmax) - np.ceil(_vmin) >= self._min_n_ticks - 1): + step = max(1, step) + best_vmin = (_vmin // step) * step + + # Find tick locations spanning the vmin-vmax range, taking into + # account degradation of precision when there is a large offset. + # The edge ticks beyond vmin and/or vmax are needed for the + # "round_numbers" autolimit mode. + edge = _Edge_integer(step, offset) + low = edge.le(_vmin - best_vmin) + high = edge.ge(_vmax - best_vmin) + ticks = np.arange(low, high + 1) * step + best_vmin + # Count only the ticks that will be displayed. + nticks = ((ticks <= _vmax) & (ticks >= _vmin)).sum() + if nticks >= self._min_n_ticks: + break + return ticks + offset + + def __call__(self): + vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + if self._symmetric: + vmax = max(abs(vmin), abs(vmax)) + vmin = -vmax + vmin, vmax = mtransforms.nonsingular( + vmin, vmax, expander=1e-13, tiny=1e-14) + locs = self._raw_ticks(vmin, vmax) + + prune = self._prune + if prune == 'lower': + locs = locs[1:] + elif prune == 'upper': + locs = locs[:-1] + elif prune == 'both': + locs = locs[1:-1] + return self.raise_if_exceeds(locs) + + def view_limits(self, dmin, dmax): + if self._symmetric: + dmax = max(abs(dmin), abs(dmax)) + dmin = -dmax + + dmin, dmax = mtransforms.nonsingular( + dmin, dmax, expander=1e-12, tiny=1e-13) + + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + return self._raw_ticks(dmin, dmax)[[0, -1]] + else: + return dmin, dmax + + +def _is_decade(x, *, base=10, rtol=None): + """Return True if *x* is an integer power of *base*.""" + if not np.isfinite(x): + return False + if x == 0.0: + return True + lx = np.log(abs(x)) / np.log(base) + if rtol is None: + return np.isclose(lx, np.round(lx)) + else: + return np.isclose(lx, np.round(lx), rtol=rtol) + + +def _decade_less_equal(x, base): + """ + Return the largest integer power of *base* that's less or equal to *x*. + + If *x* is negative, the exponent will be *greater*. + """ + return (x if x == 0 else + -_decade_greater_equal(-x, base) if x < 0 else + base ** np.floor(np.log(x) / np.log(base))) + + +def _decade_greater_equal(x, base): + """ + Return the smallest integer power of *base* that's greater or equal to *x*. + + If *x* is negative, the exponent will be *smaller*. + """ + return (x if x == 0 else + -_decade_less_equal(-x, base) if x < 0 else + base ** np.ceil(np.log(x) / np.log(base))) + + +def _decade_less(x, base): + """ + Return the largest integer power of *base* that's less than *x*. + + If *x* is negative, the exponent will be *greater*. + """ + if x < 0: + return -_decade_greater(-x, base) + less = _decade_less_equal(x, base) + if less == x: + less /= base + return less + + +def _decade_greater(x, base): + """ + Return the smallest integer power of *base* that's greater than *x*. + + If *x* is negative, the exponent will be *smaller*. + """ + if x < 0: + return -_decade_less(-x, base) + greater = _decade_greater_equal(x, base) + if greater == x: + greater *= base + return greater + + +def _is_close_to_int(x): + return math.isclose(x, round(x)) + + +class LogLocator(Locator): + """ + + Determine the tick locations for log axes. + + Place ticks on the locations : ``subs[j] * base**i`` + + Parameters + ---------- + base : float, default: 10.0 + The base of the log used, so major ticks are placed at + ``base**n``, where ``n`` is an integer. + subs : None or {'auto', 'all'} or sequence of float, default: (1.0,) + Gives the multiples of integer powers of the base at which + to place ticks. The default of ``(1.0, )`` places ticks only at + integer powers of the base. + Permitted string values are ``'auto'`` and ``'all'``. + Both of these use an algorithm based on the axis view + limits to determine whether and how to put ticks between + integer powers of the base. With ``'auto'``, ticks are + placed only between integer powers; with ``'all'``, the + integer powers are included. A value of None is + equivalent to ``'auto'``. + numticks : None or int, default: None + The maximum number of ticks to allow on a given axis. The default + of ``None`` will try to choose intelligently as long as this + Locator has already been assigned to an axis using + `~.axis.Axis.get_tick_space`, but otherwise falls back to 9. + + """ + + @_api.delete_parameter("3.8", "numdecs") + def __init__(self, base=10.0, subs=(1.0,), numdecs=4, numticks=None): + """Place ticks on the locations : subs[j] * base**i.""" + if numticks is None: + if mpl.rcParams['_internal.classic_mode']: + numticks = 15 + else: + numticks = 'auto' + self._base = float(base) + self._set_subs(subs) + self._numdecs = numdecs + self.numticks = numticks + + @_api.delete_parameter("3.8", "numdecs") + def set_params(self, base=None, subs=None, numdecs=None, numticks=None): + """Set parameters within this locator.""" + if base is not None: + self._base = float(base) + if subs is not None: + self._set_subs(subs) + if numdecs is not None: + self._numdecs = numdecs + if numticks is not None: + self.numticks = numticks + + numdecs = _api.deprecate_privatize_attribute( + "3.8", addendum="This attribute has no effect.") + + def _set_subs(self, subs): + """ + Set the minor ticks for the log scaling every ``base**i*subs[j]``. + """ + if subs is None: # consistency with previous bad API + self._subs = 'auto' + elif isinstance(subs, str): + _api.check_in_list(('all', 'auto'), subs=subs) + self._subs = subs + else: + try: + self._subs = np.asarray(subs, dtype=float) + except ValueError as e: + raise ValueError("subs must be None, 'all', 'auto' or " + "a sequence of floats, not " + f"{subs}.") from e + if self._subs.ndim != 1: + raise ValueError("A sequence passed to subs must be " + "1-dimensional, not " + f"{self._subs.ndim}-dimensional.") + + def __call__(self): + """Return the locations of the ticks.""" + vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + if self.numticks == 'auto': + if self.axis is not None: + numticks = np.clip(self.axis.get_tick_space(), 2, 9) + else: + numticks = 9 + else: + numticks = self.numticks + + b = self._base + if vmin <= 0.0: + if self.axis is not None: + vmin = self.axis.get_minpos() + + if vmin <= 0.0 or not np.isfinite(vmin): + raise ValueError( + "Data has no positive values, and therefore cannot be log-scaled.") + + _log.debug('vmin %s vmax %s', vmin, vmax) + + if vmax < vmin: + vmin, vmax = vmax, vmin + log_vmin = math.log(vmin) / math.log(b) + log_vmax = math.log(vmax) / math.log(b) + + numdec = math.floor(log_vmax) - math.ceil(log_vmin) + + if isinstance(self._subs, str): + if numdec > 10 or b < 3: + if self._subs == 'auto': + return np.array([]) # no minor or major ticks + else: + subs = np.array([1.0]) # major ticks + else: + _first = 2.0 if self._subs == 'auto' else 1.0 + subs = np.arange(_first, b) + else: + subs = self._subs + + # Get decades between major ticks. + stride = (max(math.ceil(numdec / (numticks - 1)), 1) + if mpl.rcParams['_internal.classic_mode'] else + numdec // numticks + 1) + + # if we have decided that the stride is as big or bigger than + # the range, clip the stride back to the available range - 1 + # with a floor of 1. This prevents getting axis with only 1 tick + # visible. + if stride >= numdec: + stride = max(1, numdec - 1) + + # Does subs include anything other than 1? Essentially a hack to know + # whether we're a major or a minor locator. + have_subs = len(subs) > 1 or (len(subs) == 1 and subs[0] != 1.0) + + decades = np.arange(math.floor(log_vmin) - stride, + math.ceil(log_vmax) + 2 * stride, stride) + + if have_subs: + if stride == 1: + ticklocs = np.concatenate( + [subs * decade_start for decade_start in b ** decades]) + else: + ticklocs = np.array([]) + else: + ticklocs = b ** decades + + _log.debug('ticklocs %r', ticklocs) + if (len(subs) > 1 + and stride == 1 + and ((vmin <= ticklocs) & (ticklocs <= vmax)).sum() <= 1): + # If we're a minor locator *that expects at least two ticks per + # decade* and the major locator stride is 1 and there's no more + # than one minor tick, switch to AutoLocator. + return AutoLocator().tick_values(vmin, vmax) + else: + return self.raise_if_exceeds(ticklocs) + + def view_limits(self, vmin, vmax): + """Try to choose the view limits intelligently.""" + b = self._base + + vmin, vmax = self.nonsingular(vmin, vmax) + + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + vmin = _decade_less_equal(vmin, b) + vmax = _decade_greater_equal(vmax, b) + + return vmin, vmax + + def nonsingular(self, vmin, vmax): + if vmin > vmax: + vmin, vmax = vmax, vmin + if not np.isfinite(vmin) or not np.isfinite(vmax): + vmin, vmax = 1, 10 # Initial range, no data plotted yet. + elif vmax <= 0: + _api.warn_external( + "Data has no positive values, and therefore cannot be " + "log-scaled.") + vmin, vmax = 1, 10 + else: + # Consider shared axises + minpos = min(axis.get_minpos() for axis in self.axis._get_shared_axis()) + if not np.isfinite(minpos): + minpos = 1e-300 # This should never take effect. + if vmin <= 0: + vmin = minpos + if vmin == vmax: + vmin = _decade_less(vmin, self._base) + vmax = _decade_greater(vmax, self._base) + return vmin, vmax + + +class SymmetricalLogLocator(Locator): + """ + Determine the tick locations for symmetric log axes. + """ + + def __init__(self, transform=None, subs=None, linthresh=None, base=None): + """ + Parameters + ---------- + transform : `~.scale.SymmetricalLogTransform`, optional + If set, defines the *base* and *linthresh* of the symlog transform. + base, linthresh : float, optional + The *base* and *linthresh* of the symlog transform, as documented + for `.SymmetricalLogScale`. These parameters are only used if + *transform* is not set. + subs : sequence of float, default: [1] + The multiples of integer powers of the base where ticks are placed, + i.e., ticks are placed at + ``[sub * base**i for i in ... for sub in subs]``. + + Notes + ----- + Either *transform*, or both *base* and *linthresh*, must be given. + """ + if transform is not None: + self._base = transform.base + self._linthresh = transform.linthresh + elif linthresh is not None and base is not None: + self._base = base + self._linthresh = linthresh + else: + raise ValueError("Either transform, or both linthresh " + "and base, must be provided.") + if subs is None: + self._subs = [1.0] + else: + self._subs = subs + self.numticks = 15 + + def set_params(self, subs=None, numticks=None): + """Set parameters within this locator.""" + if numticks is not None: + self.numticks = numticks + if subs is not None: + self._subs = subs + + def __call__(self): + """Return the locations of the ticks.""" + # Note, these are untransformed coordinates + vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + linthresh = self._linthresh + + if vmax < vmin: + vmin, vmax = vmax, vmin + + # The domain is divided into three sections, only some of + # which may actually be present. + # + # <======== -t ==0== t ========> + # aaaaaaaaa bbbbb ccccccccc + # + # a) and c) will have ticks at integral log positions. The + # number of ticks needs to be reduced if there are more + # than self.numticks of them. + # + # b) has a tick at 0 and only 0 (we assume t is a small + # number, and the linear segment is just an implementation + # detail and not interesting.) + # + # We could also add ticks at t, but that seems to usually be + # uninteresting. + # + # "simple" mode is when the range falls entirely within [-t, t] + # -- it should just display (vmin, 0, vmax) + if -linthresh <= vmin < vmax <= linthresh: + # only the linear range is present + return sorted({vmin, 0, vmax}) + + # Lower log range is present + has_a = (vmin < -linthresh) + # Upper log range is present + has_c = (vmax > linthresh) + + # Check if linear range is present + has_b = (has_a and vmax > -linthresh) or (has_c and vmin < linthresh) + + base = self._base + + def get_log_range(lo, hi): + lo = np.floor(np.log(lo) / np.log(base)) + hi = np.ceil(np.log(hi) / np.log(base)) + return lo, hi + + # Calculate all the ranges, so we can determine striding + a_lo, a_hi = (0, 0) + if has_a: + a_upper_lim = min(-linthresh, vmax) + a_lo, a_hi = get_log_range(abs(a_upper_lim), abs(vmin) + 1) + + c_lo, c_hi = (0, 0) + if has_c: + c_lower_lim = max(linthresh, vmin) + c_lo, c_hi = get_log_range(c_lower_lim, vmax + 1) + + # Calculate the total number of integer exponents in a and c ranges + total_ticks = (a_hi - a_lo) + (c_hi - c_lo) + if has_b: + total_ticks += 1 + stride = max(total_ticks // (self.numticks - 1), 1) + + decades = [] + if has_a: + decades.extend(-1 * (base ** (np.arange(a_lo, a_hi, + stride)[::-1]))) + + if has_b: + decades.append(0.0) + + if has_c: + decades.extend(base ** (np.arange(c_lo, c_hi, stride))) + + subs = np.asarray(self._subs) + + if len(subs) > 1 or subs[0] != 1.0: + ticklocs = [] + for decade in decades: + if decade == 0: + ticklocs.append(decade) + else: + ticklocs.extend(subs * decade) + else: + ticklocs = decades + + return self.raise_if_exceeds(np.array(ticklocs)) + + def view_limits(self, vmin, vmax): + """Try to choose the view limits intelligently.""" + b = self._base + if vmax < vmin: + vmin, vmax = vmax, vmin + + if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': + vmin = _decade_less_equal(vmin, b) + vmax = _decade_greater_equal(vmax, b) + if vmin == vmax: + vmin = _decade_less(vmin, b) + vmax = _decade_greater(vmax, b) + + return mtransforms.nonsingular(vmin, vmax) + + +class AsinhLocator(Locator): + """ + An axis tick locator specialized for the inverse-sinh scale + + This is very unlikely to have any use beyond + the `~.scale.AsinhScale` class. + + .. note:: + + This API is provisional and may be revised in the future + based on early user feedback. + """ + def __init__(self, linear_width, numticks=11, symthresh=0.2, + base=10, subs=None): + """ + Parameters + ---------- + linear_width : float + The scale parameter defining the extent + of the quasi-linear region. + numticks : int, default: 11 + The approximate number of major ticks that will fit + along the entire axis + symthresh : float, default: 0.2 + The fractional threshold beneath which data which covers + a range that is approximately symmetric about zero + will have ticks that are exactly symmetric. + base : int, default: 10 + The number base used for rounding tick locations + on a logarithmic scale. If this is less than one, + then rounding is to the nearest integer multiple + of powers of ten. + subs : tuple, default: None + Multiples of the number base, typically used + for the minor ticks, e.g. (2, 5) when base=10. + """ + super().__init__() + self.linear_width = linear_width + self.numticks = numticks + self.symthresh = symthresh + self.base = base + self.subs = subs + + def set_params(self, numticks=None, symthresh=None, + base=None, subs=None): + """Set parameters within this locator.""" + if numticks is not None: + self.numticks = numticks + if symthresh is not None: + self.symthresh = symthresh + if base is not None: + self.base = base + if subs is not None: + self.subs = subs if len(subs) > 0 else None + + def __call__(self): + vmin, vmax = self.axis.get_view_interval() + if (vmin * vmax) < 0 and abs(1 + vmax / vmin) < self.symthresh: + # Data-range appears to be almost symmetric, so round up: + bound = max(abs(vmin), abs(vmax)) + return self.tick_values(-bound, bound) + else: + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + # Construct a set of "on-screen" locations + # that are uniformly spaced: + ymin, ymax = self.linear_width * np.arcsinh(np.array([vmin, vmax]) + / self.linear_width) + ys = np.linspace(ymin, ymax, self.numticks) + zero_dev = np.abs(ys / (ymax - ymin)) + if (ymin * ymax) < 0: + # Ensure that the zero tick-mark is included, + # if the axis straddles zero + ys = np.hstack([ys[(zero_dev > 0.5 / self.numticks)], 0.0]) + + # Transform the "on-screen" grid to the data space: + xs = self.linear_width * np.sinh(ys / self.linear_width) + zero_xs = (ys == 0) + + # Round the data-space values to be intuitive base-n numbers, + # keeping track of positive and negative values separately, + # but giving careful treatment to the zero value: + if self.base > 1: + log_base = math.log(self.base) + powers = ( + np.where(zero_xs, 0, np.sign(xs)) * + np.power(self.base, + np.where(zero_xs, 0.0, + np.floor(np.log(np.abs(xs) + zero_xs*1e-6) + / log_base))) + ) + if self.subs: + qs = np.outer(powers, self.subs).flatten() + else: + qs = powers + else: + powers = ( + np.where(xs >= 0, 1, -1) * + np.power(10, np.where(zero_xs, 0.0, + np.floor(np.log10(np.abs(xs) + + zero_xs*1e-6)))) + ) + qs = powers * np.round(xs / powers) + ticks = np.array(sorted(set(qs))) + + if len(ticks) >= 2: + return ticks + else: + return np.linspace(vmin, vmax, self.numticks) + + +class LogitLocator(MaxNLocator): + """ + Determine the tick locations for logit axes + """ + + def __init__(self, minor=False, *, nbins="auto"): + """ + Place ticks on the logit locations + + Parameters + ---------- + nbins : int or 'auto', optional + Number of ticks. Only used if minor is False. + minor : bool, default: False + Indicate if this locator is for minor ticks or not. + """ + + self._minor = minor + super().__init__(nbins=nbins, steps=[1, 2, 5, 10]) + + def set_params(self, minor=None, **kwargs): + """Set parameters within this locator.""" + if minor is not None: + self._minor = minor + super().set_params(**kwargs) + + @property + def minor(self): + return self._minor + + @minor.setter + def minor(self, value): + self.set_params(minor=value) + + def tick_values(self, vmin, vmax): + # dummy axis has no axes attribute + if hasattr(self.axis, "axes") and self.axis.axes.name == "polar": + raise NotImplementedError("Polar axis cannot be logit scaled yet") + + if self._nbins == "auto": + if self.axis is not None: + nbins = self.axis.get_tick_space() + if nbins < 2: + nbins = 2 + else: + nbins = 9 + else: + nbins = self._nbins + + # We define ideal ticks with their index: + # linscale: ... 1e-3 1e-2 1e-1 1/2 1-1e-1 1-1e-2 1-1e-3 ... + # b-scale : ... -3 -2 -1 0 1 2 3 ... + def ideal_ticks(x): + return 10 ** x if x < 0 else 1 - (10 ** (-x)) if x > 0 else 0.5 + + vmin, vmax = self.nonsingular(vmin, vmax) + binf = int( + np.floor(np.log10(vmin)) + if vmin < 0.5 + else 0 + if vmin < 0.9 + else -np.ceil(np.log10(1 - vmin)) + ) + bsup = int( + np.ceil(np.log10(vmax)) + if vmax <= 0.5 + else 1 + if vmax <= 0.9 + else -np.floor(np.log10(1 - vmax)) + ) + numideal = bsup - binf - 1 + if numideal >= 2: + # have 2 or more wanted ideal ticks, so use them as major ticks + if numideal > nbins: + # to many ideal ticks, subsampling ideals for major ticks, and + # take others for minor ticks + subsampling_factor = math.ceil(numideal / nbins) + if self._minor: + ticklocs = [ + ideal_ticks(b) + for b in range(binf, bsup + 1) + if (b % subsampling_factor) != 0 + ] + else: + ticklocs = [ + ideal_ticks(b) + for b in range(binf, bsup + 1) + if (b % subsampling_factor) == 0 + ] + return self.raise_if_exceeds(np.array(ticklocs)) + if self._minor: + ticklocs = [] + for b in range(binf, bsup): + if b < -1: + ticklocs.extend(np.arange(2, 10) * 10 ** b) + elif b == -1: + ticklocs.extend(np.arange(2, 5) / 10) + elif b == 0: + ticklocs.extend(np.arange(6, 9) / 10) + else: + ticklocs.extend( + 1 - np.arange(2, 10)[::-1] * 10 ** (-b - 1) + ) + return self.raise_if_exceeds(np.array(ticklocs)) + ticklocs = [ideal_ticks(b) for b in range(binf, bsup + 1)] + return self.raise_if_exceeds(np.array(ticklocs)) + # the scale is zoomed so same ticks as linear scale can be used + if self._minor: + return [] + return super().tick_values(vmin, vmax) + + def nonsingular(self, vmin, vmax): + standard_minpos = 1e-7 + initial_range = (standard_minpos, 1 - standard_minpos) + if vmin > vmax: + vmin, vmax = vmax, vmin + if not np.isfinite(vmin) or not np.isfinite(vmax): + vmin, vmax = initial_range # Initial range, no data plotted yet. + elif vmax <= 0 or vmin >= 1: + # vmax <= 0 occurs when all values are negative + # vmin >= 1 occurs when all values are greater than one + _api.warn_external( + "Data has no values between 0 and 1, and therefore cannot be " + "logit-scaled." + ) + vmin, vmax = initial_range + else: + minpos = ( + self.axis.get_minpos() + if self.axis is not None + else standard_minpos + ) + if not np.isfinite(minpos): + minpos = standard_minpos # This should never take effect. + if vmin <= 0: + vmin = minpos + # NOTE: for vmax, we should query a property similar to get_minpos, + # but related to the maximal, less-than-one data point. + # Unfortunately, Bbox._minpos is defined very deep in the BBox and + # updated with data, so for now we use 1 - minpos as a substitute. + if vmax >= 1: + vmax = 1 - minpos + if vmin == vmax: + vmin, vmax = 0.1 * vmin, 1 - 0.1 * vmin + + return vmin, vmax + + +class AutoLocator(MaxNLocator): + """ + Dynamically find major tick positions. This is actually a subclass + of `~matplotlib.ticker.MaxNLocator`, with parameters *nbins = 'auto'* + and *steps = [1, 2, 2.5, 5, 10]*. + """ + def __init__(self): + """ + To know the values of the non-public parameters, please have a + look to the defaults of `~matplotlib.ticker.MaxNLocator`. + """ + if mpl.rcParams['_internal.classic_mode']: + nbins = 9 + steps = [1, 2, 5, 10] + else: + nbins = 'auto' + steps = [1, 2, 2.5, 5, 10] + super().__init__(nbins=nbins, steps=steps) + + +class AutoMinorLocator(Locator): + """ + Dynamically find minor tick positions based on the positions of + major ticks. The scale must be linear with major ticks evenly spaced. + """ + def __init__(self, n=None): + """ + *n* is the number of subdivisions of the interval between + major ticks; e.g., n=2 will place a single minor tick midway + between major ticks. + + If *n* is omitted or None, the value stored in rcParams will be used. + In case *n* is set to 'auto', it will be set to 4 or 5. If the distance + between the major ticks equals 1, 2.5, 5 or 10 it can be perfectly + divided in 5 equidistant sub-intervals with a length multiple of + 0.05. Otherwise it is divided in 4 sub-intervals. + """ + self.ndivs = n + + def __call__(self): + """Return the locations of the ticks.""" + if self.axis.get_scale() == 'log': + _api.warn_external('AutoMinorLocator does not work with ' + 'logarithmic scale') + return [] + + majorlocs = self.axis.get_majorticklocs() + try: + majorstep = majorlocs[1] - majorlocs[0] + except IndexError: + # Need at least two major ticks to find minor tick locations + # TODO: Figure out a way to still be able to display minor + # ticks without two major ticks visible. For now, just display + # no ticks at all. + return [] + + if self.ndivs is None: + + if self.axis.axis_name == 'y': + self.ndivs = mpl.rcParams['ytick.minor.ndivs'] + else: + # for x and z axis + self.ndivs = mpl.rcParams['xtick.minor.ndivs'] + + if self.ndivs == 'auto': + + majorstep_no_exponent = 10 ** (np.log10(majorstep) % 1) + + if np.isclose(majorstep_no_exponent, [1.0, 2.5, 5.0, 10.0]).any(): + ndivs = 5 + else: + ndivs = 4 + else: + ndivs = self.ndivs + + minorstep = majorstep / ndivs + + vmin, vmax = self.axis.get_view_interval() + if vmin > vmax: + vmin, vmax = vmax, vmin + + t0 = majorlocs[0] + tmin = round((vmin - t0) / minorstep) + tmax = round((vmax - t0) / minorstep) + 1 + locs = (np.arange(tmin, tmax) * minorstep) + t0 + + return self.raise_if_exceeds(locs) + + def tick_values(self, vmin, vmax): + raise NotImplementedError('Cannot get tick locations for a ' + '%s type.' % type(self)) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.pyi new file mode 100644 index 00000000..f026b494 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/ticker.pyi @@ -0,0 +1,301 @@ +from collections.abc import Callable, Sequence +from typing import Any, Literal + +from matplotlib.axis import Axis +from matplotlib.transforms import Transform +from matplotlib.projections.polar import _AxisWrapper + +import numpy as np + +class _DummyAxis: + __name__: str + def __init__(self, minpos: float = ...) -> None: ... + def get_view_interval(self) -> tuple[float, float]: ... + def set_view_interval(self, vmin: float, vmax: float) -> None: ... + def get_minpos(self) -> float: ... + def get_data_interval(self) -> tuple[float, float]: ... + def set_data_interval(self, vmin: float, vmax: float) -> None: ... + def get_tick_space(self) -> int: ... + +class TickHelper: + axis: None | Axis | _DummyAxis | _AxisWrapper + def set_axis(self, axis: Axis | _DummyAxis | _AxisWrapper | None) -> None: ... + def create_dummy_axis(self, **kwargs) -> None: ... + +class Formatter(TickHelper): + locs: list[float] + def __call__(self, x: float, pos: int | None = ...) -> str: ... + def format_ticks(self, values: list[float]) -> list[str]: ... + def format_data(self, value: float) -> str: ... + def format_data_short(self, value: float) -> str: ... + def get_offset(self) -> str: ... + def set_locs(self, locs: list[float]) -> None: ... + @staticmethod + def fix_minus(s: str) -> str: ... + +class NullFormatter(Formatter): ... + +class FixedFormatter(Formatter): + seq: Sequence[str] + offset_string: str + def __init__(self, seq: Sequence[str]) -> None: ... + def set_offset_string(self, ofs: str) -> None: ... + +class FuncFormatter(Formatter): + func: Callable[[float, int | None], str] + offset_string: str + # Callable[[float, int | None], str] | Callable[[float], str] + def __init__(self, func: Callable[..., str]) -> None: ... + def set_offset_string(self, ofs: str) -> None: ... + +class FormatStrFormatter(Formatter): + fmt: str + def __init__(self, fmt: str) -> None: ... + +class StrMethodFormatter(Formatter): + fmt: str + def __init__(self, fmt: str) -> None: ... + +class ScalarFormatter(Formatter): + orderOfMagnitude: int + format: str + def __init__( + self, + useOffset: bool | float | None = ..., + useMathText: bool | None = ..., + useLocale: bool | None = ..., + ) -> None: ... + offset: float + def get_useOffset(self) -> bool: ... + def set_useOffset(self, val: bool | float) -> None: ... + @property + def useOffset(self) -> bool: ... + @useOffset.setter + def useOffset(self, val: bool | float) -> None: ... + def get_useLocale(self) -> bool: ... + def set_useLocale(self, val: bool | None) -> None: ... + @property + def useLocale(self) -> bool: ... + @useLocale.setter + def useLocale(self, val: bool | None) -> None: ... + def get_useMathText(self) -> bool: ... + def set_useMathText(self, val: bool | None) -> None: ... + @property + def useMathText(self) -> bool: ... + @useMathText.setter + def useMathText(self, val: bool | None) -> None: ... + def set_scientific(self, b: bool) -> None: ... + def set_powerlimits(self, lims: tuple[int, int]) -> None: ... + def format_data_short(self, value: float | np.ma.MaskedArray) -> str: ... + def format_data(self, value: float) -> str: ... + +class LogFormatter(Formatter): + minor_thresholds: tuple[float, float] + def __init__( + self, + base: float = ..., + labelOnlyBase: bool = ..., + minor_thresholds: tuple[float, float] | None = ..., + linthresh: float | None = ..., + ) -> None: ... + def set_base(self, base: float) -> None: ... + labelOnlyBase: bool + def set_label_minor(self, labelOnlyBase: bool) -> None: ... + def set_locs(self, locs: Any | None = ...) -> None: ... + def format_data(self, value: float) -> str: ... + def format_data_short(self, value: float) -> str: ... + +class LogFormatterExponent(LogFormatter): ... +class LogFormatterMathtext(LogFormatter): ... +class LogFormatterSciNotation(LogFormatterMathtext): ... + +class LogitFormatter(Formatter): + def __init__( + self, + *, + use_overline: bool = ..., + one_half: str = ..., + minor: bool = ..., + minor_threshold: int = ..., + minor_number: int = ... + ) -> None: ... + def use_overline(self, use_overline: bool) -> None: ... + def set_one_half(self, one_half: str) -> None: ... + def set_minor_threshold(self, minor_threshold: int) -> None: ... + def set_minor_number(self, minor_number: int) -> None: ... + def format_data_short(self, value: float) -> str: ... + +class EngFormatter(Formatter): + ENG_PREFIXES: dict[int, str] + unit: str + places: int | None + sep: str + def __init__( + self, + unit: str = ..., + places: int | None = ..., + sep: str = ..., + *, + usetex: bool | None = ..., + useMathText: bool | None = ... + ) -> None: ... + def get_usetex(self) -> bool: ... + def set_usetex(self, val: bool | None) -> None: ... + @property + def usetex(self) -> bool: ... + @usetex.setter + def usetex(self, val: bool | None) -> None: ... + def get_useMathText(self) -> bool: ... + def set_useMathText(self, val: bool | None) -> None: ... + @property + def useMathText(self) -> bool: ... + @useMathText.setter + def useMathText(self, val: bool | None) -> None: ... + def format_eng(self, num: float) -> str: ... + +class PercentFormatter(Formatter): + xmax: float + decimals: int | None + def __init__( + self, + xmax: float = ..., + decimals: int | None = ..., + symbol: str | None = ..., + is_latex: bool = ..., + ) -> None: ... + def format_pct(self, x: float, display_range: float) -> str: ... + def convert_to_pct(self, x: float) -> float: ... + @property + def symbol(self) -> str: ... + @symbol.setter + def symbol(self, symbol: str) -> None: ... + +class Locator(TickHelper): + MAXTICKS: int + def tick_values(self, vmin: float, vmax: float) -> Sequence[float]: ... + # Implementation accepts **kwargs, but is a no-op other than a warning + # Typing as **kwargs would require each subclass to accept **kwargs for mypy + def set_params(self) -> None: ... + def __call__(self) -> Sequence[float]: ... + def raise_if_exceeds(self, locs: Sequence[float]) -> Sequence[float]: ... + def nonsingular(self, v0: float, v1: float) -> tuple[float, float]: ... + def view_limits(self, vmin: float, vmax: float) -> tuple[float, float]: ... + +class IndexLocator(Locator): + offset: float + def __init__(self, base: float, offset: float) -> None: ... + def set_params( + self, base: float | None = ..., offset: float | None = ... + ) -> None: ... + +class FixedLocator(Locator): + nbins: int | None + def __init__(self, locs: Sequence[float], nbins: int | None = ...) -> None: ... + def set_params(self, nbins: int | None = ...) -> None: ... + +class NullLocator(Locator): ... + +class LinearLocator(Locator): + presets: dict[tuple[float, float], Sequence[float]] + def __init__( + self, + numticks: int | None = ..., + presets: dict[tuple[float, float], Sequence[float]] | None = ..., + ) -> None: ... + @property + def numticks(self) -> int: ... + @numticks.setter + def numticks(self, numticks: int | None) -> None: ... + def set_params( + self, + numticks: int | None = ..., + presets: dict[tuple[float, float], Sequence[float]] | None = ..., + ) -> None: ... + +class MultipleLocator(Locator): + def __init__(self, base: float = ..., offset: float = ...) -> None: ... + def set_params(self, base: float | None = ..., offset: float | None = ...) -> None: ... + def view_limits(self, dmin: float, dmax: float) -> tuple[float, float]: ... + +class _Edge_integer: + step: float + def __init__(self, step: float, offset: float) -> None: ... + def closeto(self, ms: float, edge: float) -> bool: ... + def le(self, x: float) -> float: ... + def ge(self, x: float) -> float: ... + +class MaxNLocator(Locator): + default_params: dict[str, Any] + def __init__(self, nbins: int | Literal["auto"] | None = ..., **kwargs) -> None: ... + def set_params(self, **kwargs) -> None: ... + def view_limits(self, dmin: float, dmax: float) -> tuple[float, float]: ... + +class LogLocator(Locator): + numdecs: float + numticks: int | None + def __init__( + self, + base: float = ..., + subs: None | Literal["auto", "all"] | Sequence[float] = ..., + numdecs: float = ..., + numticks: int | None = ..., + ) -> None: ... + def set_params( + self, + base: float | None = ..., + subs: Literal["auto", "all"] | Sequence[float] | None = ..., + numdecs: float | None = ..., + numticks: int | None = ..., + ) -> None: ... + +class SymmetricalLogLocator(Locator): + numticks: int + def __init__( + self, + transform: Transform | None = ..., + subs: Sequence[float] | None = ..., + linthresh: float | None = ..., + base: float | None = ..., + ) -> None: ... + def set_params( + self, subs: Sequence[float] | None = ..., numticks: int | None = ... + ) -> None: ... + +class AsinhLocator(Locator): + linear_width: float + numticks: int + symthresh: float + base: int + subs: Sequence[float] | None + def __init__( + self, + linear_width: float, + numticks: int = ..., + symthresh: float = ..., + base: int = ..., + subs: Sequence[float] | None = ..., + ) -> None: ... + def set_params( + self, + numticks: int | None = ..., + symthresh: float | None = ..., + base: int | None = ..., + subs: Sequence[float] | None = ..., + ) -> None: ... + +class LogitLocator(MaxNLocator): + def __init__( + self, minor: bool = ..., *, nbins: Literal["auto"] | int = ... + ) -> None: ... + def set_params(self, minor: bool | None = ..., **kwargs) -> None: ... + @property + def minor(self) -> bool: ... + @minor.setter + def minor(self, value: bool) -> None: ... + +class AutoLocator(MaxNLocator): + def __init__(self) -> None: ... + +class AutoMinorLocator(Locator): + ndivs: int + def __init__(self, n: int | None = ...) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.py new file mode 100644 index 00000000..d04b59af --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.py @@ -0,0 +1,2975 @@ +""" +Matplotlib includes a framework for arbitrary geometric +transformations that is used determine the final position of all +elements drawn on the canvas. + +Transforms are composed into trees of `TransformNode` objects +whose actual value depends on their children. When the contents of +children change, their parents are automatically invalidated. The +next time an invalidated transform is accessed, it is recomputed to +reflect those changes. This invalidation/caching approach prevents +unnecessary recomputations of transforms, and contributes to better +interactive performance. + +For example, here is a graph of the transform tree used to plot data +to the graph: + +.. image:: ../_static/transforms.png + +The framework can be used for both affine and non-affine +transformations. However, for speed, we want to use the backend +renderers to perform affine transformations whenever possible. +Therefore, it is possible to perform just the affine or non-affine +part of a transformation on a set of data. The affine is always +assumed to occur after the non-affine. For any transform:: + + full transform == non-affine part + affine part + +The backends are not expected to handle non-affine transformations +themselves. + +See the tutorial :ref:`transforms_tutorial` for examples +of how to use transforms. +""" + +# Note: There are a number of places in the code where we use `np.min` or +# `np.minimum` instead of the builtin `min`, and likewise for `max`. This is +# done so that `nan`s are propagated, instead of being silently dropped. + +import copy +import functools +import textwrap +import weakref +import math + +import numpy as np +from numpy.linalg import inv + +from matplotlib import _api +from matplotlib._path import ( + affine_transform, count_bboxes_overlapping_bbox, update_path_extents) +from .path import Path + +DEBUG = False + + +def _make_str_method(*args, **kwargs): + """ + Generate a ``__str__`` method for a `.Transform` subclass. + + After :: + + class T: + __str__ = _make_str_method("attr", key="other") + + ``str(T(...))`` will be + + .. code-block:: text + + {type(T).__name__}( + {self.attr}, + key={self.other}) + """ + indent = functools.partial(textwrap.indent, prefix=" " * 4) + def strrepr(x): return repr(x) if isinstance(x, str) else str(x) + return lambda self: ( + type(self).__name__ + "(" + + ",".join([*(indent("\n" + strrepr(getattr(self, arg))) + for arg in args), + *(indent("\n" + k + "=" + strrepr(getattr(self, arg))) + for k, arg in kwargs.items())]) + + ")") + + +class TransformNode: + """ + The base class for anything that participates in the transform tree + and needs to invalidate its parents or be invalidated. This includes + classes that are not really transforms, such as bounding boxes, since some + transforms depend on bounding boxes to compute their values. + """ + + # Invalidation may affect only the affine part. If the + # invalidation was "affine-only", the _invalid member is set to + # INVALID_AFFINE_ONLY + INVALID_NON_AFFINE = _api.deprecated("3.8")(_api.classproperty(lambda cls: 1)) + INVALID_AFFINE = _api.deprecated("3.8")(_api.classproperty(lambda cls: 2)) + INVALID = _api.deprecated("3.8")(_api.classproperty(lambda cls: 3)) + + # Possible values for the _invalid attribute. + _VALID, _INVALID_AFFINE_ONLY, _INVALID_FULL = range(3) + + # Some metadata about the transform, used to determine whether an + # invalidation is affine-only + is_affine = False + is_bbox = False + + pass_through = False + """ + If pass_through is True, all ancestors will always be + invalidated, even if 'self' is already invalid. + """ + + def __init__(self, shorthand_name=None): + """ + Parameters + ---------- + shorthand_name : str + A string representing the "name" of the transform. The name carries + no significance other than to improve the readability of + ``str(transform)`` when DEBUG=True. + """ + self._parents = {} + # Initially invalid, until first computation. + self._invalid = self._INVALID_FULL + self._shorthand_name = shorthand_name or '' + + if DEBUG: + def __str__(self): + # either just return the name of this TransformNode, or its repr + return self._shorthand_name or repr(self) + + def __getstate__(self): + # turn the dictionary with weak values into a normal dictionary + return {**self.__dict__, + '_parents': {k: v() for k, v in self._parents.items()}} + + def __setstate__(self, data_dict): + self.__dict__ = data_dict + # turn the normal dictionary back into a dictionary with weak values + # The extra lambda is to provide a callback to remove dead + # weakrefs from the dictionary when garbage collection is done. + self._parents = { + k: weakref.ref(v, lambda _, pop=self._parents.pop, k=k: pop(k)) + for k, v in self._parents.items() if v is not None} + + def __copy__(self): + other = copy.copy(super()) + # If `c = a + b; a1 = copy(a)`, then modifications to `a1` do not + # propagate back to `c`, i.e. we need to clear the parents of `a1`. + other._parents = {} + # If `c = a + b; c1 = copy(c)`, then modifications to `a` also need to + # be propagated to `c1`. + for key, val in vars(self).items(): + if isinstance(val, TransformNode) and id(self) in val._parents: + other.set_children(val) # val == getattr(other, key) + return other + + def invalidate(self): + """ + Invalidate this `TransformNode` and triggers an invalidation of its + ancestors. Should be called any time the transform changes. + """ + return self._invalidate_internal( + level=self._INVALID_AFFINE_ONLY if self.is_affine else self._INVALID_FULL, + invalidating_node=self) + + def _invalidate_internal(self, level, invalidating_node): + """ + Called by :meth:`invalidate` and subsequently ascends the transform + stack calling each TransformNode's _invalidate_internal method. + """ + # If we are already more invalid than the currently propagated invalidation, + # then we don't need to do anything. + if level <= self._invalid and not self.pass_through: + return + self._invalid = level + for parent in list(self._parents.values()): + parent = parent() # Dereference the weak reference. + if parent is not None: + parent._invalidate_internal(level=level, invalidating_node=self) + + def set_children(self, *children): + """ + Set the children of the transform, to let the invalidation + system know which transforms can invalidate this transform. + Should be called from the constructor of any transforms that + depend on other transforms. + """ + # Parents are stored as weak references, so that if the + # parents are destroyed, references from the children won't + # keep them alive. + id_self = id(self) + for child in children: + # Use weak references so this dictionary won't keep obsolete nodes + # alive; the callback deletes the dictionary entry. This is a + # performance improvement over using WeakValueDictionary. + ref = weakref.ref( + self, lambda _, pop=child._parents.pop, k=id_self: pop(k)) + child._parents[id_self] = ref + + def frozen(self): + """ + Return a frozen copy of this transform node. The frozen copy will not + be updated when its children change. Useful for storing a previously + known state of a transform where ``copy.deepcopy()`` might normally be + used. + """ + return self + + +class BboxBase(TransformNode): + """ + The base class of all bounding boxes. + + This class is immutable; `Bbox` is a mutable subclass. + + The canonical representation is as two points, with no + restrictions on their ordering. Convenience properties are + provided to get the left, bottom, right and top edges and width + and height, but these are not stored explicitly. + """ + + is_bbox = True + is_affine = True + + if DEBUG: + @staticmethod + def _check(points): + if isinstance(points, np.ma.MaskedArray): + _api.warn_external("Bbox bounds are a masked array.") + points = np.asarray(points) + if any((points[1, :] - points[0, :]) == 0): + _api.warn_external("Singular Bbox.") + + def frozen(self): + return Bbox(self.get_points().copy()) + frozen.__doc__ = TransformNode.__doc__ + + def __array__(self, *args, **kwargs): + return self.get_points() + + @property + def x0(self): + """ + The first of the pair of *x* coordinates that define the bounding box. + + This is not guaranteed to be less than :attr:`x1` (for that, use + :attr:`xmin`). + """ + return self.get_points()[0, 0] + + @property + def y0(self): + """ + The first of the pair of *y* coordinates that define the bounding box. + + This is not guaranteed to be less than :attr:`y1` (for that, use + :attr:`ymin`). + """ + return self.get_points()[0, 1] + + @property + def x1(self): + """ + The second of the pair of *x* coordinates that define the bounding box. + + This is not guaranteed to be greater than :attr:`x0` (for that, use + :attr:`xmax`). + """ + return self.get_points()[1, 0] + + @property + def y1(self): + """ + The second of the pair of *y* coordinates that define the bounding box. + + This is not guaranteed to be greater than :attr:`y0` (for that, use + :attr:`ymax`). + """ + return self.get_points()[1, 1] + + @property + def p0(self): + """ + The first pair of (*x*, *y*) coordinates that define the bounding box. + + This is not guaranteed to be the bottom-left corner (for that, use + :attr:`min`). + """ + return self.get_points()[0] + + @property + def p1(self): + """ + The second pair of (*x*, *y*) coordinates that define the bounding box. + + This is not guaranteed to be the top-right corner (for that, use + :attr:`max`). + """ + return self.get_points()[1] + + @property + def xmin(self): + """The left edge of the bounding box.""" + return np.min(self.get_points()[:, 0]) + + @property + def ymin(self): + """The bottom edge of the bounding box.""" + return np.min(self.get_points()[:, 1]) + + @property + def xmax(self): + """The right edge of the bounding box.""" + return np.max(self.get_points()[:, 0]) + + @property + def ymax(self): + """The top edge of the bounding box.""" + return np.max(self.get_points()[:, 1]) + + @property + def min(self): + """The bottom-left corner of the bounding box.""" + return np.min(self.get_points(), axis=0) + + @property + def max(self): + """The top-right corner of the bounding box.""" + return np.max(self.get_points(), axis=0) + + @property + def intervalx(self): + """ + The pair of *x* coordinates that define the bounding box. + + This is not guaranteed to be sorted from left to right. + """ + return self.get_points()[:, 0] + + @property + def intervaly(self): + """ + The pair of *y* coordinates that define the bounding box. + + This is not guaranteed to be sorted from bottom to top. + """ + return self.get_points()[:, 1] + + @property + def width(self): + """The (signed) width of the bounding box.""" + points = self.get_points() + return points[1, 0] - points[0, 0] + + @property + def height(self): + """The (signed) height of the bounding box.""" + points = self.get_points() + return points[1, 1] - points[0, 1] + + @property + def size(self): + """The (signed) width and height of the bounding box.""" + points = self.get_points() + return points[1] - points[0] + + @property + def bounds(self): + """Return (:attr:`x0`, :attr:`y0`, :attr:`width`, :attr:`height`).""" + (x0, y0), (x1, y1) = self.get_points() + return (x0, y0, x1 - x0, y1 - y0) + + @property + def extents(self): + """Return (:attr:`x0`, :attr:`y0`, :attr:`x1`, :attr:`y1`).""" + return self.get_points().flatten() # flatten returns a copy. + + def get_points(self): + raise NotImplementedError + + def containsx(self, x): + """ + Return whether *x* is in the closed (:attr:`x0`, :attr:`x1`) interval. + """ + x0, x1 = self.intervalx + return x0 <= x <= x1 or x0 >= x >= x1 + + def containsy(self, y): + """ + Return whether *y* is in the closed (:attr:`y0`, :attr:`y1`) interval. + """ + y0, y1 = self.intervaly + return y0 <= y <= y1 or y0 >= y >= y1 + + def contains(self, x, y): + """ + Return whether ``(x, y)`` is in the bounding box or on its edge. + """ + return self.containsx(x) and self.containsy(y) + + def overlaps(self, other): + """ + Return whether this bounding box overlaps with the other bounding box. + + Parameters + ---------- + other : `.BboxBase` + """ + ax1, ay1, ax2, ay2 = self.extents + bx1, by1, bx2, by2 = other.extents + if ax2 < ax1: + ax2, ax1 = ax1, ax2 + if ay2 < ay1: + ay2, ay1 = ay1, ay2 + if bx2 < bx1: + bx2, bx1 = bx1, bx2 + if by2 < by1: + by2, by1 = by1, by2 + return ax1 <= bx2 and bx1 <= ax2 and ay1 <= by2 and by1 <= ay2 + + def fully_containsx(self, x): + """ + Return whether *x* is in the open (:attr:`x0`, :attr:`x1`) interval. + """ + x0, x1 = self.intervalx + return x0 < x < x1 or x0 > x > x1 + + def fully_containsy(self, y): + """ + Return whether *y* is in the open (:attr:`y0`, :attr:`y1`) interval. + """ + y0, y1 = self.intervaly + return y0 < y < y1 or y0 > y > y1 + + def fully_contains(self, x, y): + """ + Return whether ``x, y`` is in the bounding box, but not on its edge. + """ + return self.fully_containsx(x) and self.fully_containsy(y) + + def fully_overlaps(self, other): + """ + Return whether this bounding box overlaps with the other bounding box, + not including the edges. + + Parameters + ---------- + other : `.BboxBase` + """ + ax1, ay1, ax2, ay2 = self.extents + bx1, by1, bx2, by2 = other.extents + if ax2 < ax1: + ax2, ax1 = ax1, ax2 + if ay2 < ay1: + ay2, ay1 = ay1, ay2 + if bx2 < bx1: + bx2, bx1 = bx1, bx2 + if by2 < by1: + by2, by1 = by1, by2 + return ax1 < bx2 and bx1 < ax2 and ay1 < by2 and by1 < ay2 + + def transformed(self, transform): + """ + Construct a `Bbox` by statically transforming this one by *transform*. + """ + pts = self.get_points() + ll, ul, lr = transform.transform(np.array( + [pts[0], [pts[0, 0], pts[1, 1]], [pts[1, 0], pts[0, 1]]])) + return Bbox([ll, [lr[0], ul[1]]]) + + coefs = {'C': (0.5, 0.5), + 'SW': (0, 0), + 'S': (0.5, 0), + 'SE': (1.0, 0), + 'E': (1.0, 0.5), + 'NE': (1.0, 1.0), + 'N': (0.5, 1.0), + 'NW': (0, 1.0), + 'W': (0, 0.5)} + + def anchored(self, c, container=None): + """ + Return a copy of the `Bbox` anchored to *c* within *container*. + + Parameters + ---------- + c : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', ...} + Either an (*x*, *y*) pair of relative coordinates (0 is left or + bottom, 1 is right or top), 'C' (center), or a cardinal direction + ('SW', southwest, is bottom left, etc.). + container : `Bbox`, optional + The box within which the `Bbox` is positioned. + + See Also + -------- + .Axes.set_anchor + """ + if container is None: + _api.warn_deprecated( + "3.8", message="Calling anchored() with no container bbox " + "returns a frozen copy of the original bbox and is deprecated " + "since %(since)s.") + container = self + l, b, w, h = container.bounds + L, B, W, H = self.bounds + cx, cy = self.coefs[c] if isinstance(c, str) else c + return Bbox(self._points + + [(l + cx * (w - W)) - L, + (b + cy * (h - H)) - B]) + + def shrunk(self, mx, my): + """ + Return a copy of the `Bbox`, shrunk by the factor *mx* + in the *x* direction and the factor *my* in the *y* direction. + The lower left corner of the box remains unchanged. Normally + *mx* and *my* will be less than 1, but this is not enforced. + """ + w, h = self.size + return Bbox([self._points[0], + self._points[0] + [mx * w, my * h]]) + + def shrunk_to_aspect(self, box_aspect, container=None, fig_aspect=1.0): + """ + Return a copy of the `Bbox`, shrunk so that it is as + large as it can be while having the desired aspect ratio, + *box_aspect*. If the box coordinates are relative (i.e. + fractions of a larger box such as a figure) then the + physical aspect ratio of that figure is specified with + *fig_aspect*, so that *box_aspect* can also be given as a + ratio of the absolute dimensions, not the relative dimensions. + """ + if box_aspect <= 0 or fig_aspect <= 0: + raise ValueError("'box_aspect' and 'fig_aspect' must be positive") + if container is None: + container = self + w, h = container.size + H = w * box_aspect / fig_aspect + if H <= h: + W = w + else: + W = h * fig_aspect / box_aspect + H = h + return Bbox([self._points[0], + self._points[0] + (W, H)]) + + def splitx(self, *args): + """ + Return a list of new `Bbox` objects formed by splitting the original + one with vertical lines at fractional positions given by *args*. + """ + xf = [0, *args, 1] + x0, y0, x1, y1 = self.extents + w = x1 - x0 + return [Bbox([[x0 + xf0 * w, y0], [x0 + xf1 * w, y1]]) + for xf0, xf1 in zip(xf[:-1], xf[1:])] + + def splity(self, *args): + """ + Return a list of new `Bbox` objects formed by splitting the original + one with horizontal lines at fractional positions given by *args*. + """ + yf = [0, *args, 1] + x0, y0, x1, y1 = self.extents + h = y1 - y0 + return [Bbox([[x0, y0 + yf0 * h], [x1, y0 + yf1 * h]]) + for yf0, yf1 in zip(yf[:-1], yf[1:])] + + def count_contains(self, vertices): + """ + Count the number of vertices contained in the `Bbox`. + Any vertices with a non-finite x or y value are ignored. + + Parameters + ---------- + vertices : (N, 2) array + """ + if len(vertices) == 0: + return 0 + vertices = np.asarray(vertices) + with np.errstate(invalid='ignore'): + return (((self.min < vertices) & + (vertices < self.max)).all(axis=1).sum()) + + def count_overlaps(self, bboxes): + """ + Count the number of bounding boxes that overlap this one. + + Parameters + ---------- + bboxes : sequence of `.BboxBase` + """ + return count_bboxes_overlapping_bbox( + self, np.atleast_3d([np.array(x) for x in bboxes])) + + def expanded(self, sw, sh): + """ + Construct a `Bbox` by expanding this one around its center by the + factors *sw* and *sh*. + """ + width = self.width + height = self.height + deltaw = (sw * width - width) / 2.0 + deltah = (sh * height - height) / 2.0 + a = np.array([[-deltaw, -deltah], [deltaw, deltah]]) + return Bbox(self._points + a) + + @_api.rename_parameter("3.8", "p", "w_pad") + def padded(self, w_pad, h_pad=None): + """ + Construct a `Bbox` by padding this one on all four sides. + + Parameters + ---------- + w_pad : float + Width pad + h_pad : float, optional + Height pad. Defaults to *w_pad*. + + """ + points = self.get_points() + if h_pad is None: + h_pad = w_pad + return Bbox(points + [[-w_pad, -h_pad], [w_pad, h_pad]]) + + def translated(self, tx, ty): + """Construct a `Bbox` by translating this one by *tx* and *ty*.""" + return Bbox(self._points + (tx, ty)) + + def corners(self): + """ + Return the corners of this rectangle as an array of points. + + Specifically, this returns the array + ``[[x0, y0], [x0, y1], [x1, y0], [x1, y1]]``. + """ + (x0, y0), (x1, y1) = self.get_points() + return np.array([[x0, y0], [x0, y1], [x1, y0], [x1, y1]]) + + def rotated(self, radians): + """ + Return the axes-aligned bounding box that bounds the result of rotating + this `Bbox` by an angle of *radians*. + """ + corners = self.corners() + corners_rotated = Affine2D().rotate(radians).transform(corners) + bbox = Bbox.unit() + bbox.update_from_data_xy(corners_rotated, ignore=True) + return bbox + + @staticmethod + def union(bboxes): + """Return a `Bbox` that contains all of the given *bboxes*.""" + if not len(bboxes): + raise ValueError("'bboxes' cannot be empty") + x0 = np.min([bbox.xmin for bbox in bboxes]) + x1 = np.max([bbox.xmax for bbox in bboxes]) + y0 = np.min([bbox.ymin for bbox in bboxes]) + y1 = np.max([bbox.ymax for bbox in bboxes]) + return Bbox([[x0, y0], [x1, y1]]) + + @staticmethod + def intersection(bbox1, bbox2): + """ + Return the intersection of *bbox1* and *bbox2* if they intersect, or + None if they don't. + """ + x0 = np.maximum(bbox1.xmin, bbox2.xmin) + x1 = np.minimum(bbox1.xmax, bbox2.xmax) + y0 = np.maximum(bbox1.ymin, bbox2.ymin) + y1 = np.minimum(bbox1.ymax, bbox2.ymax) + return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None + +_default_minpos = np.array([np.inf, np.inf]) + + +class Bbox(BboxBase): + """ + A mutable bounding box. + + Examples + -------- + **Create from known bounds** + + The default constructor takes the boundary "points" ``[[xmin, ymin], + [xmax, ymax]]``. + + >>> Bbox([[1, 1], [3, 7]]) + Bbox([[1.0, 1.0], [3.0, 7.0]]) + + Alternatively, a Bbox can be created from the flattened points array, the + so-called "extents" ``(xmin, ymin, xmax, ymax)`` + + >>> Bbox.from_extents(1, 1, 3, 7) + Bbox([[1.0, 1.0], [3.0, 7.0]]) + + or from the "bounds" ``(xmin, ymin, width, height)``. + + >>> Bbox.from_bounds(1, 1, 2, 6) + Bbox([[1.0, 1.0], [3.0, 7.0]]) + + **Create from collections of points** + + The "empty" object for accumulating Bboxs is the null bbox, which is a + stand-in for the empty set. + + >>> Bbox.null() + Bbox([[inf, inf], [-inf, -inf]]) + + Adding points to the null bbox will give you the bbox of those points. + + >>> box = Bbox.null() + >>> box.update_from_data_xy([[1, 1]]) + >>> box + Bbox([[1.0, 1.0], [1.0, 1.0]]) + >>> box.update_from_data_xy([[2, 3], [3, 2]], ignore=False) + >>> box + Bbox([[1.0, 1.0], [3.0, 3.0]]) + + Setting ``ignore=True`` is equivalent to starting over from a null bbox. + + >>> box.update_from_data_xy([[1, 1]], ignore=True) + >>> box + Bbox([[1.0, 1.0], [1.0, 1.0]]) + + .. warning:: + + It is recommended to always specify ``ignore`` explicitly. If not, the + default value of ``ignore`` can be changed at any time by code with + access to your Bbox, for example using the method `~.Bbox.ignore`. + + **Properties of the ``null`` bbox** + + .. note:: + + The current behavior of `Bbox.null()` may be surprising as it does + not have all of the properties of the "empty set", and as such does + not behave like a "zero" object in the mathematical sense. We may + change that in the future (with a deprecation period). + + The null bbox is the identity for intersections + + >>> Bbox.intersection(Bbox([[1, 1], [3, 7]]), Bbox.null()) + Bbox([[1.0, 1.0], [3.0, 7.0]]) + + except with itself, where it returns the full space. + + >>> Bbox.intersection(Bbox.null(), Bbox.null()) + Bbox([[-inf, -inf], [inf, inf]]) + + A union containing null will always return the full space (not the other + set!) + + >>> Bbox.union([Bbox([[0, 0], [0, 0]]), Bbox.null()]) + Bbox([[-inf, -inf], [inf, inf]]) + """ + + def __init__(self, points, **kwargs): + """ + Parameters + ---------- + points : `~numpy.ndarray` + A (2, 2) array of the form ``[[x0, y0], [x1, y1]]``. + """ + super().__init__(**kwargs) + points = np.asarray(points, float) + if points.shape != (2, 2): + raise ValueError('Bbox points must be of the form ' + '"[[x0, y0], [x1, y1]]".') + self._points = points + self._minpos = _default_minpos.copy() + self._ignore = True + # it is helpful in some contexts to know if the bbox is a + # default or has been mutated; we store the orig points to + # support the mutated methods + self._points_orig = self._points.copy() + if DEBUG: + ___init__ = __init__ + + def __init__(self, points, **kwargs): + self._check(points) + self.___init__(points, **kwargs) + + def invalidate(self): + self._check(self._points) + super().invalidate() + + def frozen(self): + # docstring inherited + frozen_bbox = super().frozen() + frozen_bbox._minpos = self.minpos.copy() + return frozen_bbox + + @staticmethod + def unit(): + """Create a new unit `Bbox` from (0, 0) to (1, 1).""" + return Bbox([[0, 0], [1, 1]]) + + @staticmethod + def null(): + """Create a new null `Bbox` from (inf, inf) to (-inf, -inf).""" + return Bbox([[np.inf, np.inf], [-np.inf, -np.inf]]) + + @staticmethod + def from_bounds(x0, y0, width, height): + """ + Create a new `Bbox` from *x0*, *y0*, *width* and *height*. + + *width* and *height* may be negative. + """ + return Bbox.from_extents(x0, y0, x0 + width, y0 + height) + + @staticmethod + def from_extents(*args, minpos=None): + """ + Create a new Bbox from *left*, *bottom*, *right* and *top*. + + The *y*-axis increases upwards. + + Parameters + ---------- + left, bottom, right, top : float + The four extents of the bounding box. + minpos : float or None + If this is supplied, the Bbox will have a minimum positive value + set. This is useful when dealing with logarithmic scales and other + scales where negative bounds result in floating point errors. + """ + bbox = Bbox(np.reshape(args, (2, 2))) + if minpos is not None: + bbox._minpos[:] = minpos + return bbox + + def __format__(self, fmt): + return ( + 'Bbox(x0={0.x0:{1}}, y0={0.y0:{1}}, x1={0.x1:{1}}, y1={0.y1:{1}})'. + format(self, fmt)) + + def __str__(self): + return format(self, '') + + def __repr__(self): + return 'Bbox([[{0.x0}, {0.y0}], [{0.x1}, {0.y1}]])'.format(self) + + def ignore(self, value): + """ + Set whether the existing bounds of the box should be ignored + by subsequent calls to :meth:`update_from_data_xy`. + + value : bool + - When ``True``, subsequent calls to `update_from_data_xy` will + ignore the existing bounds of the `Bbox`. + - When ``False``, subsequent calls to `update_from_data_xy` will + include the existing bounds of the `Bbox`. + """ + self._ignore = value + + def update_from_path(self, path, ignore=None, updatex=True, updatey=True): + """ + Update the bounds of the `Bbox` to contain the vertices of the + provided path. After updating, the bounds will have positive *width* + and *height*; *x0* and *y0* will be the minimal values. + + Parameters + ---------- + path : `~matplotlib.path.Path` + ignore : bool, optional + - When ``True``, ignore the existing bounds of the `Bbox`. + - When ``False``, include the existing bounds of the `Bbox`. + - When ``None``, use the last value passed to :meth:`ignore`. + updatex, updatey : bool, default: True + When ``True``, update the x/y values. + """ + if ignore is None: + ignore = self._ignore + + if path.vertices.size == 0: + return + + points, minpos, changed = update_path_extents( + path, None, self._points, self._minpos, ignore) + + if changed: + self.invalidate() + if updatex: + self._points[:, 0] = points[:, 0] + self._minpos[0] = minpos[0] + if updatey: + self._points[:, 1] = points[:, 1] + self._minpos[1] = minpos[1] + + def update_from_data_x(self, x, ignore=None): + """ + Update the x-bounds of the `Bbox` based on the passed in data. After + updating, the bounds will have positive *width*, and *x0* will be the + minimal value. + + Parameters + ---------- + x : `~numpy.ndarray` + Array of x-values. + ignore : bool, optional + - When ``True``, ignore the existing bounds of the `Bbox`. + - When ``False``, include the existing bounds of the `Bbox`. + - When ``None``, use the last value passed to :meth:`ignore`. + """ + x = np.ravel(x) + self.update_from_data_xy(np.column_stack([x, np.ones(x.size)]), + ignore=ignore, updatey=False) + + def update_from_data_y(self, y, ignore=None): + """ + Update the y-bounds of the `Bbox` based on the passed in data. After + updating, the bounds will have positive *height*, and *y0* will be the + minimal value. + + Parameters + ---------- + y : `~numpy.ndarray` + Array of y-values. + ignore : bool, optional + - When ``True``, ignore the existing bounds of the `Bbox`. + - When ``False``, include the existing bounds of the `Bbox`. + - When ``None``, use the last value passed to :meth:`ignore`. + """ + y = np.ravel(y) + self.update_from_data_xy(np.column_stack([np.ones(y.size), y]), + ignore=ignore, updatex=False) + + def update_from_data_xy(self, xy, ignore=None, updatex=True, updatey=True): + """ + Update the `Bbox` bounds based on the passed in *xy* coordinates. + + After updating, the bounds will have positive *width* and *height*; + *x0* and *y0* will be the minimal values. + + Parameters + ---------- + xy : (N, 2) array-like + The (x, y) coordinates. + ignore : bool, optional + - When ``True``, ignore the existing bounds of the `Bbox`. + - When ``False``, include the existing bounds of the `Bbox`. + - When ``None``, use the last value passed to :meth:`ignore`. + updatex, updatey : bool, default: True + When ``True``, update the x/y values. + """ + if len(xy) == 0: + return + + path = Path(xy) + self.update_from_path(path, ignore=ignore, + updatex=updatex, updatey=updatey) + + @BboxBase.x0.setter + def x0(self, val): + self._points[0, 0] = val + self.invalidate() + + @BboxBase.y0.setter + def y0(self, val): + self._points[0, 1] = val + self.invalidate() + + @BboxBase.x1.setter + def x1(self, val): + self._points[1, 0] = val + self.invalidate() + + @BboxBase.y1.setter + def y1(self, val): + self._points[1, 1] = val + self.invalidate() + + @BboxBase.p0.setter + def p0(self, val): + self._points[0] = val + self.invalidate() + + @BboxBase.p1.setter + def p1(self, val): + self._points[1] = val + self.invalidate() + + @BboxBase.intervalx.setter + def intervalx(self, interval): + self._points[:, 0] = interval + self.invalidate() + + @BboxBase.intervaly.setter + def intervaly(self, interval): + self._points[:, 1] = interval + self.invalidate() + + @BboxBase.bounds.setter + def bounds(self, bounds): + l, b, w, h = bounds + points = np.array([[l, b], [l + w, b + h]], float) + if np.any(self._points != points): + self._points = points + self.invalidate() + + @property + def minpos(self): + """ + The minimum positive value in both directions within the Bbox. + + This is useful when dealing with logarithmic scales and other scales + where negative bounds result in floating point errors, and will be used + as the minimum extent instead of *p0*. + """ + return self._minpos + + @property + def minposx(self): + """ + The minimum positive value in the *x*-direction within the Bbox. + + This is useful when dealing with logarithmic scales and other scales + where negative bounds result in floating point errors, and will be used + as the minimum *x*-extent instead of *x0*. + """ + return self._minpos[0] + + @property + def minposy(self): + """ + The minimum positive value in the *y*-direction within the Bbox. + + This is useful when dealing with logarithmic scales and other scales + where negative bounds result in floating point errors, and will be used + as the minimum *y*-extent instead of *y0*. + """ + return self._minpos[1] + + def get_points(self): + """ + Get the points of the bounding box as an array of the form + ``[[x0, y0], [x1, y1]]``. + """ + self._invalid = 0 + return self._points + + def set_points(self, points): + """ + Set the points of the bounding box directly from an array of the form + ``[[x0, y0], [x1, y1]]``. No error checking is performed, as this + method is mainly for internal use. + """ + if np.any(self._points != points): + self._points = points + self.invalidate() + + def set(self, other): + """ + Set this bounding box from the "frozen" bounds of another `Bbox`. + """ + if np.any(self._points != other.get_points()): + self._points = other.get_points() + self.invalidate() + + def mutated(self): + """Return whether the bbox has changed since init.""" + return self.mutatedx() or self.mutatedy() + + def mutatedx(self): + """Return whether the x-limits have changed since init.""" + return (self._points[0, 0] != self._points_orig[0, 0] or + self._points[1, 0] != self._points_orig[1, 0]) + + def mutatedy(self): + """Return whether the y-limits have changed since init.""" + return (self._points[0, 1] != self._points_orig[0, 1] or + self._points[1, 1] != self._points_orig[1, 1]) + + +class TransformedBbox(BboxBase): + """ + A `Bbox` that is automatically transformed by a given + transform. When either the child bounding box or transform + changes, the bounds of this bbox will update accordingly. + """ + + def __init__(self, bbox, transform, **kwargs): + """ + Parameters + ---------- + bbox : `Bbox` + transform : `Transform` + """ + if not bbox.is_bbox: + raise ValueError("'bbox' is not a bbox") + _api.check_isinstance(Transform, transform=transform) + if transform.input_dims != 2 or transform.output_dims != 2: + raise ValueError( + "The input and output dimensions of 'transform' must be 2") + + super().__init__(**kwargs) + self._bbox = bbox + self._transform = transform + self.set_children(bbox, transform) + self._points = None + + __str__ = _make_str_method("_bbox", "_transform") + + def get_points(self): + # docstring inherited + if self._invalid: + p = self._bbox.get_points() + # Transform all four points, then make a new bounding box + # from the result, taking care to make the orientation the + # same. + points = self._transform.transform( + [[p[0, 0], p[0, 1]], + [p[1, 0], p[0, 1]], + [p[0, 0], p[1, 1]], + [p[1, 0], p[1, 1]]]) + points = np.ma.filled(points, 0.0) + + xs = min(points[:, 0]), max(points[:, 0]) + if p[0, 0] > p[1, 0]: + xs = xs[::-1] + + ys = min(points[:, 1]), max(points[:, 1]) + if p[0, 1] > p[1, 1]: + ys = ys[::-1] + + self._points = np.array([ + [xs[0], ys[0]], + [xs[1], ys[1]] + ]) + + self._invalid = 0 + return self._points + + if DEBUG: + _get_points = get_points + + def get_points(self): + points = self._get_points() + self._check(points) + return points + + def contains(self, x, y): + # Docstring inherited. + return self._bbox.contains(*self._transform.inverted().transform((x, y))) + + def fully_contains(self, x, y): + # Docstring inherited. + return self._bbox.fully_contains(*self._transform.inverted().transform((x, y))) + + +class LockableBbox(BboxBase): + """ + A `Bbox` where some elements may be locked at certain values. + + When the child bounding box changes, the bounds of this bbox will update + accordingly with the exception of the locked elements. + """ + def __init__(self, bbox, x0=None, y0=None, x1=None, y1=None, **kwargs): + """ + Parameters + ---------- + bbox : `Bbox` + The child bounding box to wrap. + + x0 : float or None + The locked value for x0, or None to leave unlocked. + + y0 : float or None + The locked value for y0, or None to leave unlocked. + + x1 : float or None + The locked value for x1, or None to leave unlocked. + + y1 : float or None + The locked value for y1, or None to leave unlocked. + + """ + if not bbox.is_bbox: + raise ValueError("'bbox' is not a bbox") + + super().__init__(**kwargs) + self._bbox = bbox + self.set_children(bbox) + self._points = None + fp = [x0, y0, x1, y1] + mask = [val is None for val in fp] + self._locked_points = np.ma.array(fp, float, mask=mask).reshape((2, 2)) + + __str__ = _make_str_method("_bbox", "_locked_points") + + def get_points(self): + # docstring inherited + if self._invalid: + points = self._bbox.get_points() + self._points = np.where(self._locked_points.mask, + points, + self._locked_points) + self._invalid = 0 + return self._points + + if DEBUG: + _get_points = get_points + + def get_points(self): + points = self._get_points() + self._check(points) + return points + + @property + def locked_x0(self): + """ + float or None: The value used for the locked x0. + """ + if self._locked_points.mask[0, 0]: + return None + else: + return self._locked_points[0, 0] + + @locked_x0.setter + def locked_x0(self, x0): + self._locked_points.mask[0, 0] = x0 is None + self._locked_points.data[0, 0] = x0 + self.invalidate() + + @property + def locked_y0(self): + """ + float or None: The value used for the locked y0. + """ + if self._locked_points.mask[0, 1]: + return None + else: + return self._locked_points[0, 1] + + @locked_y0.setter + def locked_y0(self, y0): + self._locked_points.mask[0, 1] = y0 is None + self._locked_points.data[0, 1] = y0 + self.invalidate() + + @property + def locked_x1(self): + """ + float or None: The value used for the locked x1. + """ + if self._locked_points.mask[1, 0]: + return None + else: + return self._locked_points[1, 0] + + @locked_x1.setter + def locked_x1(self, x1): + self._locked_points.mask[1, 0] = x1 is None + self._locked_points.data[1, 0] = x1 + self.invalidate() + + @property + def locked_y1(self): + """ + float or None: The value used for the locked y1. + """ + if self._locked_points.mask[1, 1]: + return None + else: + return self._locked_points[1, 1] + + @locked_y1.setter + def locked_y1(self, y1): + self._locked_points.mask[1, 1] = y1 is None + self._locked_points.data[1, 1] = y1 + self.invalidate() + + +class Transform(TransformNode): + """ + The base class of all `TransformNode` instances that + actually perform a transformation. + + All non-affine transformations should be subclasses of this class. + New affine transformations should be subclasses of `Affine2D`. + + Subclasses of this class should override the following members (at + minimum): + + - :attr:`input_dims` + - :attr:`output_dims` + - :meth:`transform` + - :meth:`inverted` (if an inverse exists) + + The following attributes may be overridden if the default is unsuitable: + + - :attr:`is_separable` (defaults to True for 1D -> 1D transforms, False + otherwise) + - :attr:`has_inverse` (defaults to True if :meth:`inverted` is overridden, + False otherwise) + + If the transform needs to do something non-standard with + `matplotlib.path.Path` objects, such as adding curves + where there were once line segments, it should override: + + - :meth:`transform_path` + """ + + input_dims = None + """ + The number of input dimensions of this transform. + Must be overridden (with integers) in the subclass. + """ + + output_dims = None + """ + The number of output dimensions of this transform. + Must be overridden (with integers) in the subclass. + """ + + is_separable = False + """True if this transform is separable in the x- and y- dimensions.""" + + has_inverse = False + """True if this transform has a corresponding inverse transform.""" + + def __init_subclass__(cls): + # 1d transforms are always separable; we assume higher-dimensional ones + # are not but subclasses can also directly set is_separable -- this is + # verified by checking whether "is_separable" appears more than once in + # the class's MRO (it appears once in Transform). + if (sum("is_separable" in vars(parent) for parent in cls.__mro__) == 1 + and cls.input_dims == cls.output_dims == 1): + cls.is_separable = True + # Transform.inverted raises NotImplementedError; we assume that if this + # is overridden then the transform is invertible but subclass can also + # directly set has_inverse. + if (sum("has_inverse" in vars(parent) for parent in cls.__mro__) == 1 + and hasattr(cls, "inverted") + and cls.inverted is not Transform.inverted): + cls.has_inverse = True + + def __add__(self, other): + """ + Compose two transforms together so that *self* is followed by *other*. + + ``A + B`` returns a transform ``C`` so that + ``C.transform(x) == B.transform(A.transform(x))``. + """ + return (composite_transform_factory(self, other) + if isinstance(other, Transform) else + NotImplemented) + + # Equality is based on object identity for `Transform`s (so we don't + # override `__eq__`), but some subclasses, such as TransformWrapper & + # AffineBase, override this behavior. + + def _iter_break_from_left_to_right(self): + """ + Return an iterator breaking down this transform stack from left to + right recursively. If self == ((A, N), A) then the result will be an + iterator which yields I : ((A, N), A), followed by A : (N, A), + followed by (A, N) : (A), but not ((A, N), A) : I. + + This is equivalent to flattening the stack then yielding + ``flat_stack[:i], flat_stack[i:]`` where i=0..(n-1). + """ + yield IdentityTransform(), self + + @property + def depth(self): + """ + Return the number of transforms which have been chained + together to form this Transform instance. + + .. note:: + + For the special case of a Composite transform, the maximum depth + of the two is returned. + + """ + return 1 + + def contains_branch(self, other): + """ + Return whether the given transform is a sub-tree of this transform. + + This routine uses transform equality to identify sub-trees, therefore + in many situations it is object id which will be used. + + For the case where the given transform represents the whole + of this transform, returns True. + """ + if self.depth < other.depth: + return False + + # check that a subtree is equal to other (starting from self) + for _, sub_tree in self._iter_break_from_left_to_right(): + if sub_tree == other: + return True + return False + + def contains_branch_seperately(self, other_transform): + """ + Return whether the given branch is a sub-tree of this transform on + each separate dimension. + + A common use for this method is to identify if a transform is a blended + transform containing an Axes' data transform. e.g.:: + + x_isdata, y_isdata = trans.contains_branch_seperately(ax.transData) + + """ + if self.output_dims != 2: + raise ValueError('contains_branch_seperately only supports ' + 'transforms with 2 output dimensions') + # for a non-blended transform each separate dimension is the same, so + # just return the appropriate shape. + return [self.contains_branch(other_transform)] * 2 + + def __sub__(self, other): + """ + Compose *self* with the inverse of *other*, cancelling identical terms + if any:: + + # In general: + A - B == A + B.inverted() + # (but see note regarding frozen transforms below). + + # If A "ends with" B (i.e. A == A' + B for some A') we can cancel + # out B: + (A' + B) - B == A' + + # Likewise, if B "starts with" A (B = A + B'), we can cancel out A: + A - (A + B') == B'.inverted() == B'^-1 + + Cancellation (rather than naively returning ``A + B.inverted()``) is + important for multiple reasons: + + - It avoids floating-point inaccuracies when computing the inverse of + B: ``B - B`` is guaranteed to cancel out exactly (resulting in the + identity transform), whereas ``B + B.inverted()`` may differ by a + small epsilon. + - ``B.inverted()`` always returns a frozen transform: if one computes + ``A + B + B.inverted()`` and later mutates ``B``, then + ``B.inverted()`` won't be updated and the last two terms won't cancel + out anymore; on the other hand, ``A + B - B`` will always be equal to + ``A`` even if ``B`` is mutated. + """ + # we only know how to do this operation if other is a Transform. + if not isinstance(other, Transform): + return NotImplemented + for remainder, sub_tree in self._iter_break_from_left_to_right(): + if sub_tree == other: + return remainder + for remainder, sub_tree in other._iter_break_from_left_to_right(): + if sub_tree == self: + if not remainder.has_inverse: + raise ValueError( + "The shortcut cannot be computed since 'other' " + "includes a non-invertible component") + return remainder.inverted() + # if we have got this far, then there was no shortcut possible + if other.has_inverse: + return self + other.inverted() + else: + raise ValueError('It is not possible to compute transA - transB ' + 'since transB cannot be inverted and there is no ' + 'shortcut possible.') + + def __array__(self, *args, **kwargs): + """Array interface to get at this Transform's affine matrix.""" + return self.get_affine().get_matrix() + + def transform(self, values): + """ + Apply this transformation on the given array of *values*. + + Parameters + ---------- + values : array-like + The input values as an array of length :attr:`input_dims` or + shape (N, :attr:`input_dims`). + + Returns + ------- + array + The output values as an array of length :attr:`output_dims` or + shape (N, :attr:`output_dims`), depending on the input. + """ + # Ensure that values is a 2d array (but remember whether + # we started with a 1d or 2d array). + values = np.asanyarray(values) + ndim = values.ndim + values = values.reshape((-1, self.input_dims)) + + # Transform the values + res = self.transform_affine(self.transform_non_affine(values)) + + # Convert the result back to the shape of the input values. + if ndim == 0: + assert not np.ma.is_masked(res) # just to be on the safe side + return res[0, 0] + if ndim == 1: + return res.reshape(-1) + elif ndim == 2: + return res + raise ValueError( + "Input values must have shape (N, {dims}) or ({dims},)" + .format(dims=self.input_dims)) + + def transform_affine(self, values): + """ + Apply only the affine part of this transformation on the + given array of values. + + ``transform(values)`` is always equivalent to + ``transform_affine(transform_non_affine(values))``. + + In non-affine transformations, this is generally a no-op. In + affine transformations, this is equivalent to + ``transform(values)``. + + Parameters + ---------- + values : array + The input values as an array of length :attr:`input_dims` or + shape (N, :attr:`input_dims`). + + Returns + ------- + array + The output values as an array of length :attr:`output_dims` or + shape (N, :attr:`output_dims`), depending on the input. + """ + return self.get_affine().transform(values) + + def transform_non_affine(self, values): + """ + Apply only the non-affine part of this transformation. + + ``transform(values)`` is always equivalent to + ``transform_affine(transform_non_affine(values))``. + + In non-affine transformations, this is generally equivalent to + ``transform(values)``. In affine transformations, this is + always a no-op. + + Parameters + ---------- + values : array + The input values as an array of length :attr:`input_dims` or + shape (N, :attr:`input_dims`). + + Returns + ------- + array + The output values as an array of length :attr:`output_dims` or + shape (N, :attr:`output_dims`), depending on the input. + """ + return values + + def transform_bbox(self, bbox): + """ + Transform the given bounding box. + + For smarter transforms including caching (a common requirement in + Matplotlib), see `TransformedBbox`. + """ + return Bbox(self.transform(bbox.get_points())) + + def get_affine(self): + """Get the affine part of this transform.""" + return IdentityTransform() + + def get_matrix(self): + """Get the matrix for the affine part of this transform.""" + return self.get_affine().get_matrix() + + def transform_point(self, point): + """ + Return a transformed point. + + This function is only kept for backcompatibility; the more general + `.transform` method is capable of transforming both a list of points + and a single point. + + The point is given as a sequence of length :attr:`input_dims`. + The transformed point is returned as a sequence of length + :attr:`output_dims`. + """ + if len(point) != self.input_dims: + raise ValueError("The length of 'point' must be 'self.input_dims'") + return self.transform(point) + + def transform_path(self, path): + """ + Apply the transform to `.Path` *path*, returning a new `.Path`. + + In some cases, this transform may insert curves into the path + that began as line segments. + """ + return self.transform_path_affine(self.transform_path_non_affine(path)) + + def transform_path_affine(self, path): + """ + Apply the affine part of this transform to `.Path` *path*, returning a + new `.Path`. + + ``transform_path(path)`` is equivalent to + ``transform_path_affine(transform_path_non_affine(values))``. + """ + return self.get_affine().transform_path_affine(path) + + def transform_path_non_affine(self, path): + """ + Apply the non-affine part of this transform to `.Path` *path*, + returning a new `.Path`. + + ``transform_path(path)`` is equivalent to + ``transform_path_affine(transform_path_non_affine(values))``. + """ + x = self.transform_non_affine(path.vertices) + return Path._fast_from_codes_and_verts(x, path.codes, path) + + def transform_angles(self, angles, pts, radians=False, pushoff=1e-5): + """ + Transform a set of angles anchored at specific locations. + + Parameters + ---------- + angles : (N,) array-like + The angles to transform. + pts : (N, 2) array-like + The points where the angles are anchored. + radians : bool, default: False + Whether *angles* are radians or degrees. + pushoff : float + For each point in *pts* and angle in *angles*, the transformed + angle is computed by transforming a segment of length *pushoff* + starting at that point and making that angle relative to the + horizontal axis, and measuring the angle between the horizontal + axis and the transformed segment. + + Returns + ------- + (N,) array + """ + # Must be 2D + if self.input_dims != 2 or self.output_dims != 2: + raise NotImplementedError('Only defined in 2D') + angles = np.asarray(angles) + pts = np.asarray(pts) + _api.check_shape((None, 2), pts=pts) + _api.check_shape((None,), angles=angles) + if len(angles) != len(pts): + raise ValueError("There must be as many 'angles' as 'pts'") + # Convert to radians if desired + if not radians: + angles = np.deg2rad(angles) + # Move a short distance away + pts2 = pts + pushoff * np.column_stack([np.cos(angles), + np.sin(angles)]) + # Transform both sets of points + tpts = self.transform(pts) + tpts2 = self.transform(pts2) + # Calculate transformed angles + d = tpts2 - tpts + a = np.arctan2(d[:, 1], d[:, 0]) + # Convert back to degrees if desired + if not radians: + a = np.rad2deg(a) + return a + + def inverted(self): + """ + Return the corresponding inverse transformation. + + It holds ``x == self.inverted().transform(self.transform(x))``. + + The return value of this method should be treated as + temporary. An update to *self* does not cause a corresponding + update to its inverted copy. + """ + raise NotImplementedError() + + +class TransformWrapper(Transform): + """ + A helper class that holds a single child transform and acts + equivalently to it. + + This is useful if a node of the transform tree must be replaced at + run time with a transform of a different type. This class allows + that replacement to correctly trigger invalidation. + + `TransformWrapper` instances must have the same input and output dimensions + during their entire lifetime, so the child transform may only be replaced + with another child transform of the same dimensions. + """ + + pass_through = True + + def __init__(self, child): + """ + *child*: A `Transform` instance. This child may later + be replaced with :meth:`set`. + """ + _api.check_isinstance(Transform, child=child) + super().__init__() + self.set(child) + + def __eq__(self, other): + return self._child.__eq__(other) + + __str__ = _make_str_method("_child") + + def frozen(self): + # docstring inherited + return self._child.frozen() + + def set(self, child): + """ + Replace the current child of this transform with another one. + + The new child must have the same number of input and output + dimensions as the current child. + """ + if hasattr(self, "_child"): # Absent during init. + self.invalidate() + new_dims = (child.input_dims, child.output_dims) + old_dims = (self._child.input_dims, self._child.output_dims) + if new_dims != old_dims: + raise ValueError( + f"The input and output dims of the new child {new_dims} " + f"do not match those of current child {old_dims}") + self._child._parents.pop(id(self), None) + + self._child = child + self.set_children(child) + + self.transform = child.transform + self.transform_affine = child.transform_affine + self.transform_non_affine = child.transform_non_affine + self.transform_path = child.transform_path + self.transform_path_affine = child.transform_path_affine + self.transform_path_non_affine = child.transform_path_non_affine + self.get_affine = child.get_affine + self.inverted = child.inverted + self.get_matrix = child.get_matrix + # note we do not wrap other properties here since the transform's + # child can be changed with WrappedTransform.set and so checking + # is_affine and other such properties may be dangerous. + + self._invalid = 0 + self.invalidate() + self._invalid = 0 + + input_dims = property(lambda self: self._child.input_dims) + output_dims = property(lambda self: self._child.output_dims) + is_affine = property(lambda self: self._child.is_affine) + is_separable = property(lambda self: self._child.is_separable) + has_inverse = property(lambda self: self._child.has_inverse) + + +class AffineBase(Transform): + """ + The base class of all affine transformations of any number of dimensions. + """ + is_affine = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._inverted = None + + def __array__(self, *args, **kwargs): + # optimises the access of the transform matrix vs. the superclass + return self.get_matrix() + + def __eq__(self, other): + if getattr(other, "is_affine", False) and hasattr(other, "get_matrix"): + return (self.get_matrix() == other.get_matrix()).all() + return NotImplemented + + def transform(self, values): + # docstring inherited + return self.transform_affine(values) + + def transform_affine(self, values): + # docstring inherited + raise NotImplementedError('Affine subclasses should override this ' + 'method.') + + @_api.rename_parameter("3.8", "points", "values") + def transform_non_affine(self, values): + # docstring inherited + return values + + def transform_path(self, path): + # docstring inherited + return self.transform_path_affine(path) + + def transform_path_affine(self, path): + # docstring inherited + return Path(self.transform_affine(path.vertices), + path.codes, path._interpolation_steps) + + def transform_path_non_affine(self, path): + # docstring inherited + return path + + def get_affine(self): + # docstring inherited + return self + + +class Affine2DBase(AffineBase): + """ + The base class of all 2D affine transformations. + + 2D affine transformations are performed using a 3x3 numpy array:: + + a c e + b d f + 0 0 1 + + This class provides the read-only interface. For a mutable 2D + affine transformation, use `Affine2D`. + + Subclasses of this class will generally only need to override a + constructor and `~.Transform.get_matrix` that generates a custom 3x3 matrix. + """ + input_dims = 2 + output_dims = 2 + + def frozen(self): + # docstring inherited + return Affine2D(self.get_matrix().copy()) + + @property + def is_separable(self): + mtx = self.get_matrix() + return mtx[0, 1] == mtx[1, 0] == 0.0 + + def to_values(self): + """ + Return the values of the matrix as an ``(a, b, c, d, e, f)`` tuple. + """ + mtx = self.get_matrix() + return tuple(mtx[:2].swapaxes(0, 1).flat) + + @_api.rename_parameter("3.8", "points", "values") + def transform_affine(self, values): + mtx = self.get_matrix() + if isinstance(values, np.ma.MaskedArray): + tpoints = affine_transform(values.data, mtx) + return np.ma.MaskedArray(tpoints, mask=np.ma.getmask(values)) + return affine_transform(values, mtx) + + if DEBUG: + _transform_affine = transform_affine + + @_api.rename_parameter("3.8", "points", "values") + def transform_affine(self, values): + # docstring inherited + # The major speed trap here is just converting to the + # points to an array in the first place. If we can use + # more arrays upstream, that should help here. + if not isinstance(values, np.ndarray): + _api.warn_external( + f'A non-numpy array of type {type(values)} was passed in ' + f'for transformation, which results in poor performance.') + return self._transform_affine(values) + + def inverted(self): + # docstring inherited + if self._inverted is None or self._invalid: + mtx = self.get_matrix() + shorthand_name = None + if self._shorthand_name: + shorthand_name = '(%s)-1' % self._shorthand_name + self._inverted = Affine2D(inv(mtx), shorthand_name=shorthand_name) + self._invalid = 0 + return self._inverted + + +class Affine2D(Affine2DBase): + """ + A mutable 2D affine transformation. + """ + + def __init__(self, matrix=None, **kwargs): + """ + Initialize an Affine transform from a 3x3 numpy float array:: + + a c e + b d f + 0 0 1 + + If *matrix* is None, initialize with the identity transform. + """ + super().__init__(**kwargs) + if matrix is None: + # A bit faster than np.identity(3). + matrix = IdentityTransform._mtx + self._mtx = matrix.copy() + self._invalid = 0 + + _base_str = _make_str_method("_mtx") + + def __str__(self): + return (self._base_str() + if (self._mtx != np.diag(np.diag(self._mtx))).any() + else f"Affine2D().scale({self._mtx[0, 0]}, {self._mtx[1, 1]})" + if self._mtx[0, 0] != self._mtx[1, 1] + else f"Affine2D().scale({self._mtx[0, 0]})") + + @staticmethod + def from_values(a, b, c, d, e, f): + """ + Create a new Affine2D instance from the given values:: + + a c e + b d f + 0 0 1 + + . + """ + return Affine2D( + np.array([a, c, e, b, d, f, 0.0, 0.0, 1.0], float).reshape((3, 3))) + + def get_matrix(self): + """ + Get the underlying transformation matrix as a 3x3 array:: + + a c e + b d f + 0 0 1 + + . + """ + if self._invalid: + self._inverted = None + self._invalid = 0 + return self._mtx + + def set_matrix(self, mtx): + """ + Set the underlying transformation matrix from a 3x3 array:: + + a c e + b d f + 0 0 1 + + . + """ + self._mtx = mtx + self.invalidate() + + def set(self, other): + """ + Set this transformation from the frozen copy of another + `Affine2DBase` object. + """ + _api.check_isinstance(Affine2DBase, other=other) + self._mtx = other.get_matrix() + self.invalidate() + + def clear(self): + """ + Reset the underlying matrix to the identity transform. + """ + # A bit faster than np.identity(3). + self._mtx = IdentityTransform._mtx.copy() + self.invalidate() + return self + + def rotate(self, theta): + """ + Add a rotation (in radians) to this transform in place. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + a = math.cos(theta) + b = math.sin(theta) + mtx = self._mtx + # Operating and assigning one scalar at a time is much faster. + (xx, xy, x0), (yx, yy, y0), _ = mtx.tolist() + # mtx = [[a -b 0], [b a 0], [0 0 1]] * mtx + mtx[0, 0] = a * xx - b * yx + mtx[0, 1] = a * xy - b * yy + mtx[0, 2] = a * x0 - b * y0 + mtx[1, 0] = b * xx + a * yx + mtx[1, 1] = b * xy + a * yy + mtx[1, 2] = b * x0 + a * y0 + self.invalidate() + return self + + def rotate_deg(self, degrees): + """ + Add a rotation (in degrees) to this transform in place. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + return self.rotate(math.radians(degrees)) + + def rotate_around(self, x, y, theta): + """ + Add a rotation (in radians) around the point (x, y) in place. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + return self.translate(-x, -y).rotate(theta).translate(x, y) + + def rotate_deg_around(self, x, y, degrees): + """ + Add a rotation (in degrees) around the point (x, y) in place. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + # Cast to float to avoid wraparound issues with uint8's + x, y = float(x), float(y) + return self.translate(-x, -y).rotate_deg(degrees).translate(x, y) + + def translate(self, tx, ty): + """ + Add a translation in place. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + self._mtx[0, 2] += tx + self._mtx[1, 2] += ty + self.invalidate() + return self + + def scale(self, sx, sy=None): + """ + Add a scale in place. + + If *sy* is None, the same scale is applied in both the *x*- and + *y*-directions. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + if sy is None: + sy = sx + # explicit element-wise scaling is fastest + self._mtx[0, 0] *= sx + self._mtx[0, 1] *= sx + self._mtx[0, 2] *= sx + self._mtx[1, 0] *= sy + self._mtx[1, 1] *= sy + self._mtx[1, 2] *= sy + self.invalidate() + return self + + def skew(self, xShear, yShear): + """ + Add a skew in place. + + *xShear* and *yShear* are the shear angles along the *x*- and + *y*-axes, respectively, in radians. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + rx = math.tan(xShear) + ry = math.tan(yShear) + mtx = self._mtx + # Operating and assigning one scalar at a time is much faster. + (xx, xy, x0), (yx, yy, y0), _ = mtx.tolist() + # mtx = [[1 rx 0], [ry 1 0], [0 0 1]] * mtx + mtx[0, 0] += rx * yx + mtx[0, 1] += rx * yy + mtx[0, 2] += rx * y0 + mtx[1, 0] += ry * xx + mtx[1, 1] += ry * xy + mtx[1, 2] += ry * x0 + self.invalidate() + return self + + def skew_deg(self, xShear, yShear): + """ + Add a skew in place. + + *xShear* and *yShear* are the shear angles along the *x*- and + *y*-axes, respectively, in degrees. + + Returns *self*, so this method can easily be chained with more + calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` + and :meth:`scale`. + """ + return self.skew(math.radians(xShear), math.radians(yShear)) + + +class IdentityTransform(Affine2DBase): + """ + A special class that does one thing, the identity transform, in a + fast way. + """ + _mtx = np.identity(3) + + def frozen(self): + # docstring inherited + return self + + __str__ = _make_str_method() + + def get_matrix(self): + # docstring inherited + return self._mtx + + @_api.rename_parameter("3.8", "points", "values") + def transform(self, values): + # docstring inherited + return np.asanyarray(values) + + @_api.rename_parameter("3.8", "points", "values") + def transform_affine(self, values): + # docstring inherited + return np.asanyarray(values) + + @_api.rename_parameter("3.8", "points", "values") + def transform_non_affine(self, values): + # docstring inherited + return np.asanyarray(values) + + def transform_path(self, path): + # docstring inherited + return path + + def transform_path_affine(self, path): + # docstring inherited + return path + + def transform_path_non_affine(self, path): + # docstring inherited + return path + + def get_affine(self): + # docstring inherited + return self + + def inverted(self): + # docstring inherited + return self + + +class _BlendedMixin: + """Common methods for `BlendedGenericTransform` and `BlendedAffine2D`.""" + + def __eq__(self, other): + if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)): + return (self._x == other._x) and (self._y == other._y) + elif self._x == self._y: + return self._x == other + else: + return NotImplemented + + def contains_branch_seperately(self, transform): + return (self._x.contains_branch(transform), + self._y.contains_branch(transform)) + + __str__ = _make_str_method("_x", "_y") + + +class BlendedGenericTransform(_BlendedMixin, Transform): + """ + A "blended" transform uses one transform for the *x*-direction, and + another transform for the *y*-direction. + + This "generic" version can handle any given child transform in the + *x*- and *y*-directions. + """ + input_dims = 2 + output_dims = 2 + is_separable = True + pass_through = True + + def __init__(self, x_transform, y_transform, **kwargs): + """ + Create a new "blended" transform using *x_transform* to transform the + *x*-axis and *y_transform* to transform the *y*-axis. + + You will generally not call this constructor directly but use the + `blended_transform_factory` function instead, which can determine + automatically which kind of blended transform to create. + """ + Transform.__init__(self, **kwargs) + self._x = x_transform + self._y = y_transform + self.set_children(x_transform, y_transform) + self._affine = None + + @property + def depth(self): + return max(self._x.depth, self._y.depth) + + def contains_branch(self, other): + # A blended transform cannot possibly contain a branch from two + # different transforms. + return False + + is_affine = property(lambda self: self._x.is_affine and self._y.is_affine) + has_inverse = property( + lambda self: self._x.has_inverse and self._y.has_inverse) + + def frozen(self): + # docstring inherited + return blended_transform_factory(self._x.frozen(), self._y.frozen()) + + @_api.rename_parameter("3.8", "points", "values") + def transform_non_affine(self, values): + # docstring inherited + if self._x.is_affine and self._y.is_affine: + return values + x = self._x + y = self._y + + if x == y and x.input_dims == 2: + return x.transform_non_affine(values) + + if x.input_dims == 2: + x_points = x.transform_non_affine(values)[:, 0:1] + else: + x_points = x.transform_non_affine(values[:, 0]) + x_points = x_points.reshape((len(x_points), 1)) + + if y.input_dims == 2: + y_points = y.transform_non_affine(values)[:, 1:] + else: + y_points = y.transform_non_affine(values[:, 1]) + y_points = y_points.reshape((len(y_points), 1)) + + if (isinstance(x_points, np.ma.MaskedArray) or + isinstance(y_points, np.ma.MaskedArray)): + return np.ma.concatenate((x_points, y_points), 1) + else: + return np.concatenate((x_points, y_points), 1) + + def inverted(self): + # docstring inherited + return BlendedGenericTransform(self._x.inverted(), self._y.inverted()) + + def get_affine(self): + # docstring inherited + if self._invalid or self._affine is None: + if self._x == self._y: + self._affine = self._x.get_affine() + else: + x_mtx = self._x.get_affine().get_matrix() + y_mtx = self._y.get_affine().get_matrix() + # We already know the transforms are separable, so we can skip + # setting b and c to zero. + mtx = np.array([x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]]) + self._affine = Affine2D(mtx) + self._invalid = 0 + return self._affine + + +class BlendedAffine2D(_BlendedMixin, Affine2DBase): + """ + A "blended" transform uses one transform for the *x*-direction, and + another transform for the *y*-direction. + + This version is an optimization for the case where both child + transforms are of type `Affine2DBase`. + """ + + is_separable = True + + def __init__(self, x_transform, y_transform, **kwargs): + """ + Create a new "blended" transform using *x_transform* to transform the + *x*-axis and *y_transform* to transform the *y*-axis. + + Both *x_transform* and *y_transform* must be 2D affine transforms. + + You will generally not call this constructor directly but use the + `blended_transform_factory` function instead, which can determine + automatically which kind of blended transform to create. + """ + is_affine = x_transform.is_affine and y_transform.is_affine + is_separable = x_transform.is_separable and y_transform.is_separable + is_correct = is_affine and is_separable + if not is_correct: + raise ValueError("Both *x_transform* and *y_transform* must be 2D " + "affine transforms") + + Transform.__init__(self, **kwargs) + self._x = x_transform + self._y = y_transform + self.set_children(x_transform, y_transform) + + Affine2DBase.__init__(self) + self._mtx = None + + def get_matrix(self): + # docstring inherited + if self._invalid: + if self._x == self._y: + self._mtx = self._x.get_matrix() + else: + x_mtx = self._x.get_matrix() + y_mtx = self._y.get_matrix() + # We already know the transforms are separable, so we can skip + # setting b and c to zero. + self._mtx = np.array([x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]]) + self._inverted = None + self._invalid = 0 + return self._mtx + + +def blended_transform_factory(x_transform, y_transform): + """ + Create a new "blended" transform using *x_transform* to transform + the *x*-axis and *y_transform* to transform the *y*-axis. + + A faster version of the blended transform is returned for the case + where both child transforms are affine. + """ + if (isinstance(x_transform, Affine2DBase) and + isinstance(y_transform, Affine2DBase)): + return BlendedAffine2D(x_transform, y_transform) + return BlendedGenericTransform(x_transform, y_transform) + + +class CompositeGenericTransform(Transform): + """ + A composite transform formed by applying transform *a* then + transform *b*. + + This "generic" version can handle any two arbitrary + transformations. + """ + pass_through = True + + def __init__(self, a, b, **kwargs): + """ + Create a new composite transform that is the result of + applying transform *a* then transform *b*. + + You will generally not call this constructor directly but write ``a + + b`` instead, which will automatically choose the best kind of composite + transform instance to create. + """ + if a.output_dims != b.input_dims: + raise ValueError("The output dimension of 'a' must be equal to " + "the input dimensions of 'b'") + self.input_dims = a.input_dims + self.output_dims = b.output_dims + + super().__init__(**kwargs) + self._a = a + self._b = b + self.set_children(a, b) + + def frozen(self): + # docstring inherited + self._invalid = 0 + frozen = composite_transform_factory( + self._a.frozen(), self._b.frozen()) + if not isinstance(frozen, CompositeGenericTransform): + return frozen.frozen() + return frozen + + def _invalidate_internal(self, level, invalidating_node): + # When the left child is invalidated at AFFINE_ONLY level and the right child is + # non-affine, the composite transform is FULLY invalidated. + if invalidating_node is self._a and not self._b.is_affine: + level = Transform._INVALID_FULL + super()._invalidate_internal(level, invalidating_node) + + def __eq__(self, other): + if isinstance(other, (CompositeGenericTransform, CompositeAffine2D)): + return self is other or (self._a == other._a + and self._b == other._b) + else: + return False + + def _iter_break_from_left_to_right(self): + for left, right in self._a._iter_break_from_left_to_right(): + yield left, right + self._b + for left, right in self._b._iter_break_from_left_to_right(): + yield self._a + left, right + + depth = property(lambda self: self._a.depth + self._b.depth) + is_affine = property(lambda self: self._a.is_affine and self._b.is_affine) + is_separable = property( + lambda self: self._a.is_separable and self._b.is_separable) + has_inverse = property( + lambda self: self._a.has_inverse and self._b.has_inverse) + + __str__ = _make_str_method("_a", "_b") + + @_api.rename_parameter("3.8", "points", "values") + def transform_affine(self, values): + # docstring inherited + return self.get_affine().transform(values) + + @_api.rename_parameter("3.8", "points", "values") + def transform_non_affine(self, values): + # docstring inherited + if self._a.is_affine and self._b.is_affine: + return values + elif not self._a.is_affine and self._b.is_affine: + return self._a.transform_non_affine(values) + else: + return self._b.transform_non_affine(self._a.transform(values)) + + def transform_path_non_affine(self, path): + # docstring inherited + if self._a.is_affine and self._b.is_affine: + return path + elif not self._a.is_affine and self._b.is_affine: + return self._a.transform_path_non_affine(path) + else: + return self._b.transform_path_non_affine( + self._a.transform_path(path)) + + def get_affine(self): + # docstring inherited + if not self._b.is_affine: + return self._b.get_affine() + else: + return Affine2D(np.dot(self._b.get_affine().get_matrix(), + self._a.get_affine().get_matrix())) + + def inverted(self): + # docstring inherited + return CompositeGenericTransform( + self._b.inverted(), self._a.inverted()) + + +class CompositeAffine2D(Affine2DBase): + """ + A composite transform formed by applying transform *a* then transform *b*. + + This version is an optimization that handles the case where both *a* + and *b* are 2D affines. + """ + def __init__(self, a, b, **kwargs): + """ + Create a new composite transform that is the result of + applying `Affine2DBase` *a* then `Affine2DBase` *b*. + + You will generally not call this constructor directly but write ``a + + b`` instead, which will automatically choose the best kind of composite + transform instance to create. + """ + if not a.is_affine or not b.is_affine: + raise ValueError("'a' and 'b' must be affine transforms") + if a.output_dims != b.input_dims: + raise ValueError("The output dimension of 'a' must be equal to " + "the input dimensions of 'b'") + self.input_dims = a.input_dims + self.output_dims = b.output_dims + + super().__init__(**kwargs) + self._a = a + self._b = b + self.set_children(a, b) + self._mtx = None + + @property + def depth(self): + return self._a.depth + self._b.depth + + def _iter_break_from_left_to_right(self): + for left, right in self._a._iter_break_from_left_to_right(): + yield left, right + self._b + for left, right in self._b._iter_break_from_left_to_right(): + yield self._a + left, right + + __str__ = _make_str_method("_a", "_b") + + def get_matrix(self): + # docstring inherited + if self._invalid: + self._mtx = np.dot( + self._b.get_matrix(), + self._a.get_matrix()) + self._inverted = None + self._invalid = 0 + return self._mtx + + +def composite_transform_factory(a, b): + """ + Create a new composite transform that is the result of applying + transform a then transform b. + + Shortcut versions of the blended transform are provided for the + case where both child transforms are affine, or one or the other + is the identity transform. + + Composite transforms may also be created using the '+' operator, + e.g.:: + + c = a + b + """ + # check to see if any of a or b are IdentityTransforms. We use + # isinstance here to guarantee that the transforms will *always* + # be IdentityTransforms. Since TransformWrappers are mutable, + # use of equality here would be wrong. + if isinstance(a, IdentityTransform): + return b + elif isinstance(b, IdentityTransform): + return a + elif isinstance(a, Affine2D) and isinstance(b, Affine2D): + return CompositeAffine2D(a, b) + return CompositeGenericTransform(a, b) + + +class BboxTransform(Affine2DBase): + """ + `BboxTransform` linearly transforms points from one `Bbox` to another. + """ + + is_separable = True + + def __init__(self, boxin, boxout, **kwargs): + """ + Create a new `BboxTransform` that linearly transforms + points from *boxin* to *boxout*. + """ + if not boxin.is_bbox or not boxout.is_bbox: + raise ValueError("'boxin' and 'boxout' must be bbox") + + super().__init__(**kwargs) + self._boxin = boxin + self._boxout = boxout + self.set_children(boxin, boxout) + self._mtx = None + self._inverted = None + + __str__ = _make_str_method("_boxin", "_boxout") + + def get_matrix(self): + # docstring inherited + if self._invalid: + inl, inb, inw, inh = self._boxin.bounds + outl, outb, outw, outh = self._boxout.bounds + x_scale = outw / inw + y_scale = outh / inh + if DEBUG and (x_scale == 0 or y_scale == 0): + raise ValueError( + "Transforming from or to a singular bounding box") + self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale+outl)], + [0.0 , y_scale, (-inb*y_scale+outb)], + [0.0 , 0.0 , 1.0 ]], + float) + self._inverted = None + self._invalid = 0 + return self._mtx + + +class BboxTransformTo(Affine2DBase): + """ + `BboxTransformTo` is a transformation that linearly transforms points from + the unit bounding box to a given `Bbox`. + """ + + is_separable = True + + def __init__(self, boxout, **kwargs): + """ + Create a new `BboxTransformTo` that linearly transforms + points from the unit bounding box to *boxout*. + """ + if not boxout.is_bbox: + raise ValueError("'boxout' must be bbox") + + super().__init__(**kwargs) + self._boxout = boxout + self.set_children(boxout) + self._mtx = None + self._inverted = None + + __str__ = _make_str_method("_boxout") + + def get_matrix(self): + # docstring inherited + if self._invalid: + outl, outb, outw, outh = self._boxout.bounds + if DEBUG and (outw == 0 or outh == 0): + raise ValueError("Transforming to a singular bounding box.") + self._mtx = np.array([[outw, 0.0, outl], + [ 0.0, outh, outb], + [ 0.0, 0.0, 1.0]], + float) + self._inverted = None + self._invalid = 0 + return self._mtx + + +class BboxTransformToMaxOnly(BboxTransformTo): + """ + `BboxTransformTo` is a transformation that linearly transforms points from + the unit bounding box to a given `Bbox` with a fixed upper left of (0, 0). + """ + def get_matrix(self): + # docstring inherited + if self._invalid: + xmax, ymax = self._boxout.max + if DEBUG and (xmax == 0 or ymax == 0): + raise ValueError("Transforming to a singular bounding box.") + self._mtx = np.array([[xmax, 0.0, 0.0], + [ 0.0, ymax, 0.0], + [ 0.0, 0.0, 1.0]], + float) + self._inverted = None + self._invalid = 0 + return self._mtx + + +class BboxTransformFrom(Affine2DBase): + """ + `BboxTransformFrom` linearly transforms points from a given `Bbox` to the + unit bounding box. + """ + is_separable = True + + def __init__(self, boxin, **kwargs): + if not boxin.is_bbox: + raise ValueError("'boxin' must be bbox") + + super().__init__(**kwargs) + self._boxin = boxin + self.set_children(boxin) + self._mtx = None + self._inverted = None + + __str__ = _make_str_method("_boxin") + + def get_matrix(self): + # docstring inherited + if self._invalid: + inl, inb, inw, inh = self._boxin.bounds + if DEBUG and (inw == 0 or inh == 0): + raise ValueError("Transforming from a singular bounding box.") + x_scale = 1.0 / inw + y_scale = 1.0 / inh + self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale)], + [0.0 , y_scale, (-inb*y_scale)], + [0.0 , 0.0 , 1.0 ]], + float) + self._inverted = None + self._invalid = 0 + return self._mtx + + +class ScaledTranslation(Affine2DBase): + """ + A transformation that translates by *xt* and *yt*, after *xt* and *yt* + have been transformed by *scale_trans*. + """ + def __init__(self, xt, yt, scale_trans, **kwargs): + super().__init__(**kwargs) + self._t = (xt, yt) + self._scale_trans = scale_trans + self.set_children(scale_trans) + self._mtx = None + self._inverted = None + + __str__ = _make_str_method("_t") + + def get_matrix(self): + # docstring inherited + if self._invalid: + # A bit faster than np.identity(3). + self._mtx = IdentityTransform._mtx.copy() + self._mtx[:2, 2] = self._scale_trans.transform(self._t) + self._invalid = 0 + self._inverted = None + return self._mtx + + +class AffineDeltaTransform(Affine2DBase): + r""" + A transform wrapper for transforming displacements between pairs of points. + + This class is intended to be used to transform displacements ("position + deltas") between pairs of points (e.g., as the ``offset_transform`` + of `.Collection`\s): given a transform ``t`` such that ``t = + AffineDeltaTransform(t) + offset``, ``AffineDeltaTransform`` + satisfies ``AffineDeltaTransform(a - b) == AffineDeltaTransform(a) - + AffineDeltaTransform(b)``. + + This is implemented by forcing the offset components of the transform + matrix to zero. + + This class is experimental as of 3.3, and the API may change. + """ + + def __init__(self, transform, **kwargs): + super().__init__(**kwargs) + self._base_transform = transform + + __str__ = _make_str_method("_base_transform") + + def get_matrix(self): + if self._invalid: + self._mtx = self._base_transform.get_matrix().copy() + self._mtx[:2, -1] = 0 + return self._mtx + + +class TransformedPath(TransformNode): + """ + A `TransformedPath` caches a non-affine transformed copy of the + `~.path.Path`. This cached copy is automatically updated when the + non-affine part of the transform changes. + + .. note:: + + Paths are considered immutable by this class. Any update to the + path's vertices/codes will not trigger a transform recomputation. + + """ + def __init__(self, path, transform): + """ + Parameters + ---------- + path : `~.path.Path` + transform : `Transform` + """ + _api.check_isinstance(Transform, transform=transform) + super().__init__() + self._path = path + self._transform = transform + self.set_children(transform) + self._transformed_path = None + self._transformed_points = None + + def _revalidate(self): + # only recompute if the invalidation includes the non_affine part of + # the transform + if (self._invalid == self._INVALID_FULL + or self._transformed_path is None): + self._transformed_path = \ + self._transform.transform_path_non_affine(self._path) + self._transformed_points = \ + Path._fast_from_codes_and_verts( + self._transform.transform_non_affine(self._path.vertices), + None, self._path) + self._invalid = 0 + + def get_transformed_points_and_affine(self): + """ + Return a copy of the child path, with the non-affine part of + the transform already applied, along with the affine part of + the path necessary to complete the transformation. Unlike + :meth:`get_transformed_path_and_affine`, no interpolation will + be performed. + """ + self._revalidate() + return self._transformed_points, self.get_affine() + + def get_transformed_path_and_affine(self): + """ + Return a copy of the child path, with the non-affine part of + the transform already applied, along with the affine part of + the path necessary to complete the transformation. + """ + self._revalidate() + return self._transformed_path, self.get_affine() + + def get_fully_transformed_path(self): + """ + Return a fully-transformed copy of the child path. + """ + self._revalidate() + return self._transform.transform_path_affine(self._transformed_path) + + def get_affine(self): + return self._transform.get_affine() + + +class TransformedPatchPath(TransformedPath): + """ + A `TransformedPatchPath` caches a non-affine transformed copy of the + `~.patches.Patch`. This cached copy is automatically updated when the + non-affine part of the transform or the patch changes. + """ + + def __init__(self, patch): + """ + Parameters + ---------- + patch : `~.patches.Patch` + """ + # Defer to TransformedPath.__init__. + super().__init__(patch.get_path(), patch.get_transform()) + self._patch = patch + + def _revalidate(self): + patch_path = self._patch.get_path() + # Force invalidation if the patch path changed; otherwise, let base + # class check invalidation. + if patch_path != self._path: + self._path = patch_path + self._transformed_path = None + super()._revalidate() + + +def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True): + """ + Modify the endpoints of a range as needed to avoid singularities. + + Parameters + ---------- + vmin, vmax : float + The initial endpoints. + expander : float, default: 0.001 + Fractional amount by which *vmin* and *vmax* are expanded if + the original interval is too small, based on *tiny*. + tiny : float, default: 1e-15 + Threshold for the ratio of the interval to the maximum absolute + value of its endpoints. If the interval is smaller than + this, it will be expanded. This value should be around + 1e-15 or larger; otherwise the interval will be approaching + the double precision resolution limit. + increasing : bool, default: True + If True, swap *vmin*, *vmax* if *vmin* > *vmax*. + + Returns + ------- + vmin, vmax : float + Endpoints, expanded and/or swapped if necessary. + If either input is inf or NaN, or if both inputs are 0 or very + close to zero, it returns -*expander*, *expander*. + """ + + if (not np.isfinite(vmin)) or (not np.isfinite(vmax)): + return -expander, expander + + swapped = False + if vmax < vmin: + vmin, vmax = vmax, vmin + swapped = True + + # Expand vmin, vmax to float: if they were integer types, they can wrap + # around in abs (abs(np.int8(-128)) == -128) and vmax - vmin can overflow. + vmin, vmax = map(float, [vmin, vmax]) + + maxabsvalue = max(abs(vmin), abs(vmax)) + if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny: + vmin = -expander + vmax = expander + + elif vmax - vmin <= maxabsvalue * tiny: + if vmax == 0 and vmin == 0: + vmin = -expander + vmax = expander + else: + vmin -= expander*abs(vmin) + vmax += expander*abs(vmax) + + if swapped and not increasing: + vmin, vmax = vmax, vmin + return vmin, vmax + + +def interval_contains(interval, val): + """ + Check, inclusively, whether an interval includes a given value. + + Parameters + ---------- + interval : (float, float) + The endpoints of the interval. + val : float + Value to check is within interval. + + Returns + ------- + bool + Whether *val* is within the *interval*. + """ + a, b = interval + if a > b: + a, b = b, a + return a <= val <= b + + +def _interval_contains_close(interval, val, rtol=1e-10): + """ + Check, inclusively, whether an interval includes a given value, with the + interval expanded by a small tolerance to admit floating point errors. + + Parameters + ---------- + interval : (float, float) + The endpoints of the interval. + val : float + Value to check is within interval. + rtol : float, default: 1e-10 + Relative tolerance slippage allowed outside of the interval. + For an interval ``[a, b]``, values + ``a - rtol * (b - a) <= val <= b + rtol * (b - a)`` are considered + inside the interval. + + Returns + ------- + bool + Whether *val* is within the *interval* (with tolerance). + """ + a, b = interval + if a > b: + a, b = b, a + rtol = (b - a) * rtol + return a - rtol <= val <= b + rtol + + +def interval_contains_open(interval, val): + """ + Check, excluding endpoints, whether an interval includes a given value. + + Parameters + ---------- + interval : (float, float) + The endpoints of the interval. + val : float + Value to check is within interval. + + Returns + ------- + bool + Whether *val* is within the *interval*. + """ + a, b = interval + return a < val < b or a > val > b + + +def offset_copy(trans, fig=None, x=0.0, y=0.0, units='inches'): + """ + Return a new transform with an added offset. + + Parameters + ---------- + trans : `Transform` subclass + Any transform, to which offset will be applied. + fig : `~matplotlib.figure.Figure`, default: None + Current figure. It can be None if *units* are 'dots'. + x, y : float, default: 0.0 + The offset to apply. + units : {'inches', 'points', 'dots'}, default: 'inches' + Units of the offset. + + Returns + ------- + `Transform` subclass + Transform with applied offset. + """ + _api.check_in_list(['dots', 'points', 'inches'], units=units) + if units == 'dots': + return trans + Affine2D().translate(x, y) + if fig is None: + raise ValueError('For units of inches or points a fig kwarg is needed') + if units == 'points': + x /= 72.0 + y /= 72.0 + # Default units are 'inches' + return trans + ScaledTranslation(x, y, fig.dpi_scale_trans) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.pyi new file mode 100644 index 00000000..90a527e5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/transforms.pyi @@ -0,0 +1,335 @@ +from .path import Path +from .patches import Patch +from .figure import Figure +import numpy as np +from numpy.typing import ArrayLike +from collections.abc import Iterable, Sequence +from typing import Literal + +DEBUG: bool + +class TransformNode: + INVALID_NON_AFFINE: int + INVALID_AFFINE: int + INVALID: int + is_bbox: bool + # Implemented as a standard attr in base class, but functionally readonly and some subclasses implement as such + @property + def is_affine(self) -> bool: ... + pass_through: bool + def __init__(self, shorthand_name: str | None = ...) -> None: ... + def __copy__(self) -> TransformNode: ... + def invalidate(self) -> None: ... + def set_children(self, *children: TransformNode) -> None: ... + def frozen(self) -> TransformNode: ... + +class BboxBase(TransformNode): + is_bbox: bool + is_affine: bool + def frozen(self) -> Bbox: ... + def __array__(self, *args, **kwargs): ... + @property + def x0(self) -> float: ... + @property + def y0(self) -> float: ... + @property + def x1(self) -> float: ... + @property + def y1(self) -> float: ... + @property + def p0(self) -> tuple[float, float]: ... + @property + def p1(self) -> tuple[float, float]: ... + @property + def xmin(self) -> float: ... + @property + def ymin(self) -> float: ... + @property + def xmax(self) -> float: ... + @property + def ymax(self) -> float: ... + @property + def min(self) -> tuple[float, float]: ... + @property + def max(self) -> tuple[float, float]: ... + @property + def intervalx(self) -> tuple[float, float]: ... + @property + def intervaly(self) -> tuple[float, float]: ... + @property + def width(self) -> float: ... + @property + def height(self) -> float: ... + @property + def size(self) -> tuple[float, float]: ... + @property + def bounds(self) -> tuple[float, float, float, float]: ... + @property + def extents(self) -> tuple[float, float, float, float]: ... + def get_points(self) -> np.ndarray: ... + def containsx(self, x: float) -> bool: ... + def containsy(self, y: float) -> bool: ... + def contains(self, x: float, y: float) -> bool: ... + def overlaps(self, other: BboxBase) -> bool: ... + def fully_containsx(self, x: float) -> bool: ... + def fully_containsy(self, y: float) -> bool: ... + def fully_contains(self, x: float, y: float) -> bool: ... + def fully_overlaps(self, other: BboxBase) -> bool: ... + def transformed(self, transform: Transform) -> Bbox: ... + coefs: dict[str, tuple[float, float]] + # anchored type can be s/str/Literal["C", "SW", "S", "SE", "E", "NE", "N", "NW", "W"] + def anchored( + self, c: tuple[float, float] | str, container: BboxBase | None = ... + ) -> Bbox: ... + def shrunk(self, mx: float, my: float) -> Bbox: ... + def shrunk_to_aspect( + self, + box_aspect: float, + container: BboxBase | None = ..., + fig_aspect: float = ..., + ) -> Bbox: ... + def splitx(self, *args: float) -> list[Bbox]: ... + def splity(self, *args: float) -> list[Bbox]: ... + def count_contains(self, vertices: ArrayLike) -> int: ... + def count_overlaps(self, bboxes: Iterable[BboxBase]) -> int: ... + def expanded(self, sw: float, sh: float) -> Bbox: ... + def padded(self, w_pad: float, h_pad: float | None = ...) -> Bbox: ... + def translated(self, tx: float, ty: float) -> Bbox: ... + def corners(self) -> np.ndarray: ... + def rotated(self, radians: float) -> Bbox: ... + @staticmethod + def union(bboxes: Sequence[BboxBase]) -> Bbox: ... + @staticmethod + def intersection(bbox1: BboxBase, bbox2: BboxBase) -> Bbox | None: ... + +class Bbox(BboxBase): + def __init__(self, points: ArrayLike, **kwargs) -> None: ... + @staticmethod + def unit() -> Bbox: ... + @staticmethod + def null() -> Bbox: ... + @staticmethod + def from_bounds(x0: float, y0: float, width: float, height: float) -> Bbox: ... + @staticmethod + def from_extents(*args: float, minpos: float | None = ...) -> Bbox: ... + def __format__(self, fmt: str) -> str: ... + def ignore(self, value: bool) -> None: ... + def update_from_path( + self, + path: Path, + ignore: bool | None = ..., + updatex: bool = ..., + updatey: bool = ..., + ) -> None: ... + def update_from_data_x(self, x: ArrayLike, ignore: bool | None = ...) -> None: ... + def update_from_data_y(self, y: ArrayLike, ignore: bool | None = ...) -> None: ... + def update_from_data_xy( + self, + xy: ArrayLike, + ignore: bool | None = ..., + updatex: bool = ..., + updatey: bool = ..., + ) -> None: ... + @property + def minpos(self) -> float: ... + @property + def minposx(self) -> float: ... + @property + def minposy(self) -> float: ... + def get_points(self) -> np.ndarray: ... + def set_points(self, points: ArrayLike) -> None: ... + def set(self, other: Bbox) -> None: ... + def mutated(self) -> bool: ... + def mutatedx(self) -> bool: ... + def mutatedy(self) -> bool: ... + +class TransformedBbox(BboxBase): + def __init__(self, bbox: Bbox, transform: Transform, **kwargs) -> None: ... + def get_points(self) -> np.ndarray: ... + +class LockableBbox(BboxBase): + def __init__( + self, + bbox: BboxBase, + x0: float | None = ..., + y0: float | None = ..., + x1: float | None = ..., + y1: float | None = ..., + **kwargs + ) -> None: ... + @property + def locked_x0(self) -> float | None: ... + @locked_x0.setter + def locked_x0(self, x0: float | None) -> None: ... + @property + def locked_y0(self) -> float | None: ... + @locked_y0.setter + def locked_y0(self, y0: float | None) -> None: ... + @property + def locked_x1(self) -> float | None: ... + @locked_x1.setter + def locked_x1(self, x1: float | None) -> None: ... + @property + def locked_y1(self) -> float | None: ... + @locked_y1.setter + def locked_y1(self, y1: float | None) -> None: ... + +class Transform(TransformNode): + + # Implemented as a standard attrs in base class, but functionally readonly and some subclasses implement as such + @property + def input_dims(self) -> int | None: ... + @property + def output_dims(self) -> int | None: ... + @property + def is_separable(self) -> bool: ... + @property + def has_inverse(self) -> bool: ... + + def __add__(self, other: Transform) -> Transform: ... + @property + def depth(self) -> int: ... + def contains_branch(self, other: Transform) -> bool: ... + def contains_branch_seperately( + self, other_transform: Transform + ) -> Sequence[bool]: ... + def __sub__(self, other: Transform) -> Transform: ... + def __array__(self, *args, **kwargs) -> np.ndarray: ... + def transform(self, values: ArrayLike) -> np.ndarray: ... + def transform_affine(self, values: ArrayLike) -> np.ndarray: ... + def transform_non_affine(self, values: ArrayLike) -> ArrayLike: ... + def transform_bbox(self, bbox: BboxBase) -> Bbox: ... + def get_affine(self) -> Transform: ... + def get_matrix(self) -> np.ndarray: ... + def transform_point(self, point: ArrayLike) -> np.ndarray: ... + def transform_path(self, path: Path) -> Path: ... + def transform_path_affine(self, path: Path) -> Path: ... + def transform_path_non_affine(self, path: Path) -> Path: ... + def transform_angles( + self, + angles: ArrayLike, + pts: ArrayLike, + radians: bool = ..., + pushoff: float = ..., + ) -> np.ndarray: ... + def inverted(self) -> Transform: ... + +class TransformWrapper(Transform): + pass_through: bool + def __init__(self, child: Transform) -> None: ... + def __eq__(self, other: object) -> bool: ... + def frozen(self) -> Transform: ... + def set(self, child: Transform) -> None: ... + +class AffineBase(Transform): + is_affine: Literal[True] + def __init__(self, *args, **kwargs) -> None: ... + def __eq__(self, other: object) -> bool: ... + +class Affine2DBase(AffineBase): + input_dims: Literal[2] + output_dims: Literal[2] + def frozen(self) -> Affine2D: ... + def to_values(self) -> tuple[float, float, float, float, float, float]: ... + +class Affine2D(Affine2DBase): + def __init__(self, matrix: ArrayLike | None = ..., **kwargs) -> None: ... + @staticmethod + def from_values( + a: float, b: float, c: float, d: float, e: float, f: float + ) -> Affine2D: ... + def set_matrix(self, mtx: ArrayLike) -> None: ... + def clear(self) -> Affine2D: ... + def rotate(self, theta: float) -> Affine2D: ... + def rotate_deg(self, degrees: float) -> Affine2D: ... + def rotate_around(self, x: float, y: float, theta: float) -> Affine2D: ... + def rotate_deg_around(self, x: float, y: float, degrees: float) -> Affine2D: ... + def translate(self, tx: float, ty: float) -> Affine2D: ... + def scale(self, sx: float, sy: float | None = ...) -> Affine2D: ... + def skew(self, xShear: float, yShear: float) -> Affine2D: ... + def skew_deg(self, xShear: float, yShear: float) -> Affine2D: ... + +class IdentityTransform(Affine2DBase): ... + +class _BlendedMixin: + def __eq__(self, other: object) -> bool: ... + def contains_branch_seperately(self, transform: Transform) -> Sequence[bool]: ... + +class BlendedGenericTransform(_BlendedMixin, Transform): + input_dims: Literal[2] + output_dims: Literal[2] + pass_through: bool + def __init__( + self, x_transform: Transform, y_transform: Transform, **kwargs + ) -> None: ... + @property + def depth(self) -> int: ... + def contains_branch(self, other: Transform) -> Literal[False]: ... + @property + def is_affine(self) -> bool: ... + +class BlendedAffine2D(_BlendedMixin, Affine2DBase): + def __init__( + self, x_transform: Transform, y_transform: Transform, **kwargs + ) -> None: ... + +def blended_transform_factory( + x_transform: Transform, y_transform: Transform +) -> BlendedGenericTransform | BlendedAffine2D: ... + +class CompositeGenericTransform(Transform): + pass_through: bool + def __init__(self, a: Transform, b: Transform, **kwargs) -> None: ... + +class CompositeAffine2D(Affine2DBase): + def __init__(self, a: Affine2DBase, b: Affine2DBase, **kwargs) -> None: ... + @property + def depth(self) -> int: ... + +def composite_transform_factory(a: Transform, b: Transform) -> Transform: ... + +class BboxTransform(Affine2DBase): + def __init__(self, boxin: BboxBase, boxout: BboxBase, **kwargs) -> None: ... + +class BboxTransformTo(Affine2DBase): + def __init__(self, boxout: BboxBase, **kwargs) -> None: ... + +class BboxTransformToMaxOnly(BboxTransformTo): ... + +class BboxTransformFrom(Affine2DBase): + def __init__(self, boxin: BboxBase, **kwargs) -> None: ... + +class ScaledTranslation(Affine2DBase): + def __init__( + self, xt: float, yt: float, scale_trans: Affine2DBase, **kwargs + ) -> None: ... + +class AffineDeltaTransform(Affine2DBase): + def __init__(self, transform: Affine2DBase, **kwargs) -> None: ... + +class TransformedPath(TransformNode): + def __init__(self, path: Path, transform: Transform) -> None: ... + def get_transformed_points_and_affine(self) -> tuple[Path, Transform]: ... + def get_transformed_path_and_affine(self) -> tuple[Path, Transform]: ... + def get_fully_transformed_path(self) -> Path: ... + def get_affine(self) -> Transform: ... + +class TransformedPatchPath(TransformedPath): + def __init__(self, patch: Patch) -> None: ... + +def nonsingular( + vmin: float, + vmax: float, + expander: float = ..., + tiny: float = ..., + increasing: bool = ..., +) -> tuple[float, float]: ... +def interval_contains(interval: tuple[float, float], val: float) -> bool: ... +def interval_contains_open(interval: tuple[float, float], val: float) -> bool: ... +def offset_copy( + trans: Transform, + fig: Figure | None = ..., + x: float = ..., + y: float = ..., + units: Literal["inches", "points", "dots"] = ..., +) -> Transform: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/__init__.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/__init__.py new file mode 100644 index 00000000..e000831d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/__init__.py @@ -0,0 +1,23 @@ +""" +Unstructured triangular grid functions. +""" + +from ._triangulation import Triangulation +from ._tricontour import TriContourSet, tricontour, tricontourf +from ._trifinder import TriFinder, TrapezoidMapTriFinder +from ._triinterpolate import (TriInterpolator, LinearTriInterpolator, + CubicTriInterpolator) +from ._tripcolor import tripcolor +from ._triplot import triplot +from ._trirefine import TriRefiner, UniformTriRefiner +from ._tritools import TriAnalyzer + + +__all__ = ["Triangulation", + "TriContourSet", "tricontour", "tricontourf", + "TriFinder", "TrapezoidMapTriFinder", + "TriInterpolator", "LinearTriInterpolator", "CubicTriInterpolator", + "tripcolor", + "triplot", + "TriRefiner", "UniformTriRefiner", + "TriAnalyzer"] diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.py new file mode 100644 index 00000000..a07192df --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.py @@ -0,0 +1,247 @@ +import sys + +import numpy as np + +from matplotlib import _api + + +class Triangulation: + """ + An unstructured triangular grid consisting of npoints points and + ntri triangles. The triangles can either be specified by the user + or automatically generated using a Delaunay triangulation. + + Parameters + ---------- + x, y : (npoints,) array-like + Coordinates of grid points. + triangles : (ntri, 3) array-like of int, optional + For each triangle, the indices of the three points that make + up the triangle, ordered in an anticlockwise manner. If not + specified, the Delaunay triangulation is calculated. + mask : (ntri,) array-like of bool, optional + Which triangles are masked out. + + Attributes + ---------- + triangles : (ntri, 3) array of int + For each triangle, the indices of the three points that make + up the triangle, ordered in an anticlockwise manner. If you want to + take the *mask* into account, use `get_masked_triangles` instead. + mask : (ntri, 3) array of bool or None + Masked out triangles. + is_delaunay : bool + Whether the Triangulation is a calculated Delaunay + triangulation (where *triangles* was not specified) or not. + + Notes + ----- + For a Triangulation to be valid it must not have duplicate points, + triangles formed from colinear points, or overlapping triangles. + """ + def __init__(self, x, y, triangles=None, mask=None): + from matplotlib import _qhull + + self.x = np.asarray(x, dtype=np.float64) + self.y = np.asarray(y, dtype=np.float64) + if self.x.shape != self.y.shape or self.x.ndim != 1: + raise ValueError("x and y must be equal-length 1D arrays, but " + f"found shapes {self.x.shape!r} and " + f"{self.y.shape!r}") + + self.mask = None + self._edges = None + self._neighbors = None + self.is_delaunay = False + + if triangles is None: + # No triangulation specified, so use matplotlib._qhull to obtain + # Delaunay triangulation. + self.triangles, self._neighbors = _qhull.delaunay(x, y, sys.flags.verbose) + self.is_delaunay = True + else: + # Triangulation specified. Copy, since we may correct triangle + # orientation. + try: + self.triangles = np.array(triangles, dtype=np.int32, order='C') + except ValueError as e: + raise ValueError('triangles must be a (N, 3) int array, not ' + f'{triangles!r}') from e + if self.triangles.ndim != 2 or self.triangles.shape[1] != 3: + raise ValueError( + 'triangles must be a (N, 3) int array, but found shape ' + f'{self.triangles.shape!r}') + if self.triangles.max() >= len(self.x): + raise ValueError( + 'triangles are indices into the points and must be in the ' + f'range 0 <= i < {len(self.x)} but found value ' + f'{self.triangles.max()}') + if self.triangles.min() < 0: + raise ValueError( + 'triangles are indices into the points and must be in the ' + f'range 0 <= i < {len(self.x)} but found value ' + f'{self.triangles.min()}') + + # Underlying C++ object is not created until first needed. + self._cpp_triangulation = None + + # Default TriFinder not created until needed. + self._trifinder = None + + self.set_mask(mask) + + def calculate_plane_coefficients(self, z): + """ + Calculate plane equation coefficients for all unmasked triangles from + the point (x, y) coordinates and specified z-array of shape (npoints). + The returned array has shape (npoints, 3) and allows z-value at (x, y) + position in triangle tri to be calculated using + ``z = array[tri, 0] * x + array[tri, 1] * y + array[tri, 2]``. + """ + return self.get_cpp_triangulation().calculate_plane_coefficients(z) + + @property + def edges(self): + """ + Return integer array of shape (nedges, 2) containing all edges of + non-masked triangles. + + Each row defines an edge by its start point index and end point + index. Each edge appears only once, i.e. for an edge between points + *i* and *j*, there will only be either *(i, j)* or *(j, i)*. + """ + if self._edges is None: + self._edges = self.get_cpp_triangulation().get_edges() + return self._edges + + def get_cpp_triangulation(self): + """ + Return the underlying C++ Triangulation object, creating it + if necessary. + """ + from matplotlib import _tri + if self._cpp_triangulation is None: + self._cpp_triangulation = _tri.Triangulation( + # For unset arrays use empty tuple which has size of zero. + self.x, self.y, self.triangles, + self.mask if self.mask is not None else (), + self._edges if self._edges is not None else (), + self._neighbors if self._neighbors is not None else (), + not self.is_delaunay) + return self._cpp_triangulation + + def get_masked_triangles(self): + """ + Return an array of triangles taking the mask into account. + """ + if self.mask is not None: + return self.triangles[~self.mask] + else: + return self.triangles + + @staticmethod + def get_from_args_and_kwargs(*args, **kwargs): + """ + Return a Triangulation object from the args and kwargs, and + the remaining args and kwargs with the consumed values removed. + + There are two alternatives: either the first argument is a + Triangulation object, in which case it is returned, or the args + and kwargs are sufficient to create a new Triangulation to + return. In the latter case, see Triangulation.__init__ for + the possible args and kwargs. + """ + if isinstance(args[0], Triangulation): + triangulation, *args = args + if 'triangles' in kwargs: + _api.warn_external( + "Passing the keyword 'triangles' has no effect when also " + "passing a Triangulation") + if 'mask' in kwargs: + _api.warn_external( + "Passing the keyword 'mask' has no effect when also " + "passing a Triangulation") + else: + x, y, triangles, mask, args, kwargs = \ + Triangulation._extract_triangulation_params(args, kwargs) + triangulation = Triangulation(x, y, triangles, mask) + return triangulation, args, kwargs + + @staticmethod + def _extract_triangulation_params(args, kwargs): + x, y, *args = args + # Check triangles in kwargs then args. + triangles = kwargs.pop('triangles', None) + from_args = False + if triangles is None and args: + triangles = args[0] + from_args = True + if triangles is not None: + try: + triangles = np.asarray(triangles, dtype=np.int32) + except ValueError: + triangles = None + if triangles is not None and (triangles.ndim != 2 or + triangles.shape[1] != 3): + triangles = None + if triangles is not None and from_args: + args = args[1:] # Consumed first item in args. + # Check for mask in kwargs. + mask = kwargs.pop('mask', None) + return x, y, triangles, mask, args, kwargs + + def get_trifinder(self): + """ + Return the default `matplotlib.tri.TriFinder` of this + triangulation, creating it if necessary. This allows the same + TriFinder object to be easily shared. + """ + if self._trifinder is None: + # Default TriFinder class. + from matplotlib.tri._trifinder import TrapezoidMapTriFinder + self._trifinder = TrapezoidMapTriFinder(self) + return self._trifinder + + @property + def neighbors(self): + """ + Return integer array of shape (ntri, 3) containing neighbor triangles. + + For each triangle, the indices of the three triangles that + share the same edges, or -1 if there is no such neighboring + triangle. ``neighbors[i, j]`` is the triangle that is the neighbor + to the edge from point index ``triangles[i, j]`` to point index + ``triangles[i, (j+1)%3]``. + """ + if self._neighbors is None: + self._neighbors = self.get_cpp_triangulation().get_neighbors() + return self._neighbors + + def set_mask(self, mask): + """ + Set or clear the mask array. + + Parameters + ---------- + mask : None or bool array of length ntri + """ + if mask is None: + self.mask = None + else: + self.mask = np.asarray(mask, dtype=bool) + if self.mask.shape != (self.triangles.shape[0],): + raise ValueError('mask array must have same length as ' + 'triangles array') + + # Set mask in C++ Triangulation. + if self._cpp_triangulation is not None: + self._cpp_triangulation.set_mask( + self.mask if self.mask is not None else ()) + + # Clear derived fields so they are recalculated when needed. + self._edges = None + self._neighbors = None + + # Recalculate TriFinder if it exists. + if self._trifinder is not None: + self._trifinder._initialize() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.pyi new file mode 100644 index 00000000..6e00b272 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triangulation.pyi @@ -0,0 +1,33 @@ +from matplotlib import _tri +from matplotlib.tri._trifinder import TriFinder + +import numpy as np +from numpy.typing import ArrayLike +from typing import Any + +class Triangulation: + x: np.ndarray + y: np.ndarray + mask: np.ndarray | None + is_delaunay: bool + triangles: np.ndarray + def __init__( + self, + x: ArrayLike, + y: ArrayLike, + triangles: ArrayLike | None = ..., + mask: ArrayLike | None = ..., + ) -> None: ... + def calculate_plane_coefficients(self, z: ArrayLike) -> np.ndarray: ... + @property + def edges(self) -> np.ndarray: ... + def get_cpp_triangulation(self) -> _tri.Triangulation: ... + def get_masked_triangles(self) -> np.ndarray: ... + @staticmethod + def get_from_args_and_kwargs( + *args, **kwargs + ) -> tuple[Triangulation, tuple[Any, ...], dict[str, Any]]: ... + def get_trifinder(self) -> TriFinder: ... + @property + def neighbors(self) -> np.ndarray: ... + def set_mask(self, mask: None | ArrayLike) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.py new file mode 100644 index 00000000..5b6d7453 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.py @@ -0,0 +1,272 @@ +import numpy as np + +from matplotlib import _docstring +from matplotlib.contour import ContourSet +from matplotlib.tri._triangulation import Triangulation + + +@_docstring.dedent_interpd +class TriContourSet(ContourSet): + """ + Create and store a set of contour lines or filled regions for + a triangular grid. + + This class is typically not instantiated directly by the user but by + `~.Axes.tricontour` and `~.Axes.tricontourf`. + + %(contour_set_attributes)s + """ + def __init__(self, ax, *args, **kwargs): + """ + Draw triangular grid contour lines or filled regions, + depending on whether keyword arg *filled* is False + (default) or True. + + The first argument of the initializer must be an `~.axes.Axes` + object. The remaining arguments and keyword arguments + are described in the docstring of `~.Axes.tricontour`. + """ + super().__init__(ax, *args, **kwargs) + + def _process_args(self, *args, **kwargs): + """ + Process args and kwargs. + """ + if isinstance(args[0], TriContourSet): + C = args[0]._contour_generator + if self.levels is None: + self.levels = args[0].levels + self.zmin = args[0].zmin + self.zmax = args[0].zmax + self._mins = args[0]._mins + self._maxs = args[0]._maxs + else: + from matplotlib import _tri + tri, z = self._contour_args(args, kwargs) + C = _tri.TriContourGenerator(tri.get_cpp_triangulation(), z) + self._mins = [tri.x.min(), tri.y.min()] + self._maxs = [tri.x.max(), tri.y.max()] + + self._contour_generator = C + return kwargs + + def _contour_args(self, args, kwargs): + tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, + **kwargs) + z, *args = args + z = np.ma.asarray(z) + if z.shape != tri.x.shape: + raise ValueError('z array must have same length as triangulation x' + ' and y arrays') + + # z values must be finite, only need to check points that are included + # in the triangulation. + z_check = z[np.unique(tri.get_masked_triangles())] + if np.ma.is_masked(z_check): + raise ValueError('z must not contain masked points within the ' + 'triangulation') + if not np.isfinite(z_check).all(): + raise ValueError('z array must not contain non-finite values ' + 'within the triangulation') + + z = np.ma.masked_invalid(z, copy=False) + self.zmax = float(z_check.max()) + self.zmin = float(z_check.min()) + if self.logscale and self.zmin <= 0: + func = 'contourf' if self.filled else 'contour' + raise ValueError(f'Cannot {func} log of negative values.') + self._process_contour_level_args(args, z.dtype) + return (tri, z) + + +_docstring.interpd.update(_tricontour_doc=""" +Draw contour %%(type)s on an unstructured triangular grid. + +Call signatures:: + + %%(func)s(triangulation, z, [levels], ...) + %%(func)s(x, y, z, [levels], *, [triangles=triangles], [mask=mask], ...) + +The triangular grid can be specified either by passing a `.Triangulation` +object as the first parameter, or by passing the points *x*, *y* and +optionally the *triangles* and a *mask*. See `.Triangulation` for an +explanation of these parameters. If neither of *triangulation* or +*triangles* are given, the triangulation is calculated on the fly. + +It is possible to pass *triangles* positionally, i.e. +``%%(func)s(x, y, triangles, z, ...)``. However, this is discouraged. For more +clarity, pass *triangles* via keyword argument. + +Parameters +---------- +triangulation : `.Triangulation`, optional + An already created triangular grid. + +x, y, triangles, mask + Parameters defining the triangular grid. See `.Triangulation`. + This is mutually exclusive with specifying *triangulation*. + +z : array-like + The height values over which the contour is drawn. Color-mapping is + controlled by *cmap*, *norm*, *vmin*, and *vmax*. + + .. note:: + All values in *z* must be finite. Hence, nan and inf values must + either be removed or `~.Triangulation.set_mask` be used. + +levels : int or array-like, optional + Determines the number and positions of the contour lines / regions. + + If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries to + automatically choose no more than *n+1* "nice" contour levels between + between minimum and maximum numeric values of *Z*. + + If array-like, draw contour lines at the specified levels. The values must + be in increasing order. + +Returns +------- +`~matplotlib.tri.TriContourSet` + +Other Parameters +---------------- +colors : color string or sequence of colors, optional + The colors of the levels, i.e., the contour %%(type)s. + + The sequence is cycled for the levels in ascending order. If the sequence + is shorter than the number of levels, it is repeated. + + As a shortcut, single color strings may be used in place of one-element + lists, i.e. ``'red'`` instead of ``['red']`` to color all levels with the + same color. This shortcut does only work for color strings, not for other + ways of specifying colors. + + By default (value *None*), the colormap specified by *cmap* will be used. + +alpha : float, default: 1 + The alpha blending value, between 0 (transparent) and 1 (opaque). + +%(cmap_doc)s + + This parameter is ignored if *colors* is set. + +%(norm_doc)s + + This parameter is ignored if *colors* is set. + +%(vmin_vmax_doc)s + + If *vmin* or *vmax* are not given, the default color scaling is based on + *levels*. + + This parameter is ignored if *colors* is set. + +origin : {*None*, 'upper', 'lower', 'image'}, default: None + Determines the orientation and exact position of *z* by specifying the + position of ``z[0, 0]``. This is only relevant, if *X*, *Y* are not given. + + - *None*: ``z[0, 0]`` is at X=0, Y=0 in the lower left corner. + - 'lower': ``z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner. + - 'upper': ``z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left corner. + - 'image': Use the value from :rc:`image.origin`. + +extent : (x0, x1, y0, y1), optional + If *origin* is not *None*, then *extent* is interpreted as in `.imshow`: it + gives the outer pixel boundaries. In this case, the position of z[0, 0] is + the center of the pixel, not a corner. If *origin* is *None*, then + (*x0*, *y0*) is the position of z[0, 0], and (*x1*, *y1*) is the position + of z[-1, -1]. + + This argument is ignored if *X* and *Y* are specified in the call to + contour. + +locator : ticker.Locator subclass, optional + The locator is used to determine the contour levels if they are not given + explicitly via *levels*. + Defaults to `~.ticker.MaxNLocator`. + +extend : {'neither', 'both', 'min', 'max'}, default: 'neither' + Determines the ``%%(func)s``-coloring of values that are outside the + *levels* range. + + If 'neither', values outside the *levels* range are not colored. If 'min', + 'max' or 'both', color the values below, above or below and above the + *levels* range. + + Values below ``min(levels)`` and above ``max(levels)`` are mapped to the + under/over values of the `.Colormap`. Note that most colormaps do not have + dedicated colors for these by default, so that the over and under values + are the edge values of the colormap. You may want to set these values + explicitly using `.Colormap.set_under` and `.Colormap.set_over`. + + .. note:: + + An existing `.TriContourSet` does not get notified if properties of its + colormap are changed. Therefore, an explicit call to + `.ContourSet.changed()` is needed after modifying the colormap. The + explicit call can be left out, if a colorbar is assigned to the + `.TriContourSet` because it internally calls `.ContourSet.changed()`. + +xunits, yunits : registered units, optional + Override axis units by specifying an instance of a + :class:`matplotlib.units.ConversionInterface`. + +antialiased : bool, optional + Enable antialiasing, overriding the defaults. For + filled contours, the default is *True*. For line contours, + it is taken from :rc:`lines.antialiased`.""" % _docstring.interpd.params) + + +@_docstring.Substitution(func='tricontour', type='lines') +@_docstring.dedent_interpd +def tricontour(ax, *args, **kwargs): + """ + %(_tricontour_doc)s + + linewidths : float or array-like, default: :rc:`contour.linewidth` + The line width of the contour lines. + + If a number, all levels will be plotted with this linewidth. + + If a sequence, the levels in ascending order will be plotted with + the linewidths in the order specified. + + If None, this falls back to :rc:`lines.linewidth`. + + linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional + If *linestyles* is *None*, the default is 'solid' unless the lines are + monochrome. In that case, negative contours will take their linestyle + from :rc:`contour.negative_linestyle` setting. + + *linestyles* can also be an iterable of the above strings specifying a + set of linestyles to be used. If this iterable is shorter than the + number of contour levels it will be repeated as necessary. + """ + kwargs['filled'] = False + return TriContourSet(ax, *args, **kwargs) + + +@_docstring.Substitution(func='tricontourf', type='regions') +@_docstring.dedent_interpd +def tricontourf(ax, *args, **kwargs): + """ + %(_tricontour_doc)s + + hatches : list[str], optional + A list of crosshatch patterns to use on the filled areas. + If None, no hatching will be added to the contour. + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + + Notes + ----- + `.tricontourf` fills intervals that are closed at the top; that is, for + boundaries *z1* and *z2*, the filled region is:: + + z1 < Z <= z2 + + except for the lowest interval, which is closed on both sides (i.e. it + includes the lowest value). + """ + kwargs['filled'] = True + return TriContourSet(ax, *args, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.pyi new file mode 100644 index 00000000..31929d86 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tricontour.pyi @@ -0,0 +1,52 @@ +from matplotlib.axes import Axes +from matplotlib.contour import ContourSet +from matplotlib.tri._triangulation import Triangulation + +from numpy.typing import ArrayLike +from typing import overload + +# TODO: more explicit args/kwargs (for all things in this module)? + +class TriContourSet(ContourSet): + def __init__(self, ax: Axes, *args, **kwargs) -> None: ... + +@overload +def tricontour( + ax: Axes, + triangulation: Triangulation, + z: ArrayLike, + levels: int | ArrayLike = ..., + **kwargs +) -> TriContourSet: ... +@overload +def tricontour( + ax: Axes, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + levels: int | ArrayLike = ..., + *, + triangles: ArrayLike = ..., + mask: ArrayLike = ..., + **kwargs +) -> TriContourSet: ... +@overload +def tricontourf( + ax: Axes, + triangulation: Triangulation, + z: ArrayLike, + levels: int | ArrayLike = ..., + **kwargs +) -> TriContourSet: ... +@overload +def tricontourf( + ax: Axes, + x: ArrayLike, + y: ArrayLike, + z: ArrayLike, + levels: int | ArrayLike = ..., + *, + triangles: ArrayLike = ..., + mask: ArrayLike = ..., + **kwargs +) -> TriContourSet: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.py new file mode 100644 index 00000000..852f3d9e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.py @@ -0,0 +1,96 @@ +import numpy as np + +from matplotlib import _api +from matplotlib.tri import Triangulation + + +class TriFinder: + """ + Abstract base class for classes used to find the triangles of a + Triangulation in which (x, y) points lie. + + Rather than instantiate an object of a class derived from TriFinder, it is + usually better to use the function `.Triangulation.get_trifinder`. + + Derived classes implement __call__(x, y) where x and y are array-like point + coordinates of the same shape. + """ + + def __init__(self, triangulation): + _api.check_isinstance(Triangulation, triangulation=triangulation) + self._triangulation = triangulation + + def __call__(self, x, y): + raise NotImplementedError + + +class TrapezoidMapTriFinder(TriFinder): + """ + `~matplotlib.tri.TriFinder` class implemented using the trapezoid + map algorithm from the book "Computational Geometry, Algorithms and + Applications", second edition, by M. de Berg, M. van Kreveld, M. Overmars + and O. Schwarzkopf. + + The triangulation must be valid, i.e. it must not have duplicate points, + triangles formed from colinear points, or overlapping triangles. The + algorithm has some tolerance to triangles formed from colinear points, but + this should not be relied upon. + """ + + def __init__(self, triangulation): + from matplotlib import _tri + super().__init__(triangulation) + self._cpp_trifinder = _tri.TrapezoidMapTriFinder( + triangulation.get_cpp_triangulation()) + self._initialize() + + def __call__(self, x, y): + """ + Return an array containing the indices of the triangles in which the + specified *x*, *y* points lie, or -1 for points that do not lie within + a triangle. + + *x*, *y* are array-like x and y coordinates of the same shape and any + number of dimensions. + + Returns integer array with the same shape and *x* and *y*. + """ + x = np.asarray(x, dtype=np.float64) + y = np.asarray(y, dtype=np.float64) + if x.shape != y.shape: + raise ValueError("x and y must be array-like with the same shape") + + # C++ does the heavy lifting, and expects 1D arrays. + indices = (self._cpp_trifinder.find_many(x.ravel(), y.ravel()) + .reshape(x.shape)) + return indices + + def _get_tree_stats(self): + """ + Return a python list containing the statistics about the node tree: + 0: number of nodes (tree size) + 1: number of unique nodes + 2: number of trapezoids (tree leaf nodes) + 3: number of unique trapezoids + 4: maximum parent count (max number of times a node is repeated in + tree) + 5: maximum depth of tree (one more than the maximum number of + comparisons needed to search through the tree) + 6: mean of all trapezoid depths (one more than the average number + of comparisons needed to search through the tree) + """ + return self._cpp_trifinder.get_tree_stats() + + def _initialize(self): + """ + Initialize the underlying C++ object. Can be called multiple times if, + for example, the triangulation is modified. + """ + self._cpp_trifinder.initialize() + + def _print_tree(self): + """ + Print a text representation of the node tree, which is useful for + debugging purposes. + """ + self._cpp_trifinder.print_tree() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.pyi new file mode 100644 index 00000000..41a9990b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trifinder.pyi @@ -0,0 +1,10 @@ +from matplotlib.tri import Triangulation +from numpy.typing import ArrayLike + +class TriFinder: + def __init__(self, triangulation: Triangulation) -> None: ... + def __call__(self, x: ArrayLike, y: ArrayLike) -> ArrayLike: ... + +class TrapezoidMapTriFinder(TriFinder): + def __init__(self, triangulation: Triangulation) -> None: ... + def __call__(self, x: ArrayLike, y: ArrayLike) -> ArrayLike: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.py new file mode 100644 index 00000000..90ad6cf3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.py @@ -0,0 +1,1574 @@ +""" +Interpolation inside triangular grids. +""" + +import numpy as np + +from matplotlib import _api +from matplotlib.tri import Triangulation +from matplotlib.tri._trifinder import TriFinder +from matplotlib.tri._tritools import TriAnalyzer + +__all__ = ('TriInterpolator', 'LinearTriInterpolator', 'CubicTriInterpolator') + + +class TriInterpolator: + """ + Abstract base class for classes used to interpolate on a triangular grid. + + Derived classes implement the following methods: + + - ``__call__(x, y)``, + where x, y are array-like point coordinates of the same shape, and + that returns a masked array of the same shape containing the + interpolated z-values. + + - ``gradient(x, y)``, + where x, y are array-like point coordinates of the same + shape, and that returns a list of 2 masked arrays of the same shape + containing the 2 derivatives of the interpolator (derivatives of + interpolated z values with respect to x and y). + """ + + def __init__(self, triangulation, z, trifinder=None): + _api.check_isinstance(Triangulation, triangulation=triangulation) + self._triangulation = triangulation + + self._z = np.asarray(z) + if self._z.shape != self._triangulation.x.shape: + raise ValueError("z array must have same length as triangulation x" + " and y arrays") + + _api.check_isinstance((TriFinder, None), trifinder=trifinder) + self._trifinder = trifinder or self._triangulation.get_trifinder() + + # Default scaling factors : 1.0 (= no scaling) + # Scaling may be used for interpolations for which the order of + # magnitude of x, y has an impact on the interpolant definition. + # Please refer to :meth:`_interpolate_multikeys` for details. + self._unit_x = 1.0 + self._unit_y = 1.0 + + # Default triangle renumbering: None (= no renumbering) + # Renumbering may be used to avoid unnecessary computations + # if complex calculations are done inside the Interpolator. + # Please refer to :meth:`_interpolate_multikeys` for details. + self._tri_renum = None + + # __call__ and gradient docstrings are shared by all subclasses + # (except, if needed, relevant additions). + # However these methods are only implemented in subclasses to avoid + # confusion in the documentation. + _docstring__call__ = """ + Returns a masked array containing interpolated values at the specified + (x, y) points. + + Parameters + ---------- + x, y : array-like + x and y coordinates of the same shape and any number of + dimensions. + + Returns + ------- + np.ma.array + Masked array of the same shape as *x* and *y*; values corresponding + to (*x*, *y*) points outside of the triangulation are masked out. + + """ + + _docstringgradient = r""" + Returns a list of 2 masked arrays containing interpolated derivatives + at the specified (x, y) points. + + Parameters + ---------- + x, y : array-like + x and y coordinates of the same shape and any number of + dimensions. + + Returns + ------- + dzdx, dzdy : np.ma.array + 2 masked arrays of the same shape as *x* and *y*; values + corresponding to (x, y) points outside of the triangulation + are masked out. + The first returned array contains the values of + :math:`\frac{\partial z}{\partial x}` and the second those of + :math:`\frac{\partial z}{\partial y}`. + + """ + + def _interpolate_multikeys(self, x, y, tri_index=None, + return_keys=('z',)): + """ + Versatile (private) method defined for all TriInterpolators. + + :meth:`_interpolate_multikeys` is a wrapper around method + :meth:`_interpolate_single_key` (to be defined in the child + subclasses). + :meth:`_interpolate_single_key actually performs the interpolation, + but only for 1-dimensional inputs and at valid locations (inside + unmasked triangles of the triangulation). + + The purpose of :meth:`_interpolate_multikeys` is to implement the + following common tasks needed in all subclasses implementations: + + - calculation of containing triangles + - dealing with more than one interpolation request at the same + location (e.g., if the 2 derivatives are requested, it is + unnecessary to compute the containing triangles twice) + - scaling according to self._unit_x, self._unit_y + - dealing with points outside of the grid (with fill value np.nan) + - dealing with multi-dimensional *x*, *y* arrays: flattening for + :meth:`_interpolate_params` call and final reshaping. + + (Note that np.vectorize could do most of those things very well for + you, but it does it by function evaluations over successive tuples of + the input arrays. Therefore, this tends to be more time-consuming than + using optimized numpy functions - e.g., np.dot - which can be used + easily on the flattened inputs, in the child-subclass methods + :meth:`_interpolate_single_key`.) + + It is guaranteed that the calls to :meth:`_interpolate_single_key` + will be done with flattened (1-d) array-like input parameters *x*, *y* + and with flattened, valid `tri_index` arrays (no -1 index allowed). + + Parameters + ---------- + x, y : array-like + x and y coordinates where interpolated values are requested. + tri_index : array-like of int, optional + Array of the containing triangle indices, same shape as + *x* and *y*. Defaults to None. If None, these indices + will be computed by a TriFinder instance. + (Note: For point outside the grid, tri_index[ipt] shall be -1). + return_keys : tuple of keys from {'z', 'dzdx', 'dzdy'} + Defines the interpolation arrays to return, and in which order. + + Returns + ------- + list of arrays + Each array-like contains the expected interpolated values in the + order defined by *return_keys* parameter. + """ + # Flattening and rescaling inputs arrays x, y + # (initial shape is stored for output) + x = np.asarray(x, dtype=np.float64) + y = np.asarray(y, dtype=np.float64) + sh_ret = x.shape + if x.shape != y.shape: + raise ValueError("x and y shall have same shapes." + f" Given: {x.shape} and {y.shape}") + x = np.ravel(x) + y = np.ravel(y) + x_scaled = x/self._unit_x + y_scaled = y/self._unit_y + size_ret = np.size(x_scaled) + + # Computes & ravels the element indexes, extract the valid ones. + if tri_index is None: + tri_index = self._trifinder(x, y) + else: + if tri_index.shape != sh_ret: + raise ValueError( + "tri_index array is provided and shall" + " have same shape as x and y. Given: " + f"{tri_index.shape} and {sh_ret}") + tri_index = np.ravel(tri_index) + + mask_in = (tri_index != -1) + if self._tri_renum is None: + valid_tri_index = tri_index[mask_in] + else: + valid_tri_index = self._tri_renum[tri_index[mask_in]] + valid_x = x_scaled[mask_in] + valid_y = y_scaled[mask_in] + + ret = [] + for return_key in return_keys: + # Find the return index associated with the key. + try: + return_index = {'z': 0, 'dzdx': 1, 'dzdy': 2}[return_key] + except KeyError as err: + raise ValueError("return_keys items shall take values in" + " {'z', 'dzdx', 'dzdy'}") from err + + # Sets the scale factor for f & df components + scale = [1., 1./self._unit_x, 1./self._unit_y][return_index] + + # Computes the interpolation + ret_loc = np.empty(size_ret, dtype=np.float64) + ret_loc[~mask_in] = np.nan + ret_loc[mask_in] = self._interpolate_single_key( + return_key, valid_tri_index, valid_x, valid_y) * scale + ret += [np.ma.masked_invalid(ret_loc.reshape(sh_ret), copy=False)] + + return ret + + def _interpolate_single_key(self, return_key, tri_index, x, y): + """ + Interpolate at points belonging to the triangulation + (inside an unmasked triangles). + + Parameters + ---------- + return_key : {'z', 'dzdx', 'dzdy'} + The requested values (z or its derivatives). + tri_index : 1D int array + Valid triangle index (cannot be -1). + x, y : 1D arrays, same shape as `tri_index` + Valid locations where interpolation is requested. + + Returns + ------- + 1-d array + Returned array of the same size as *tri_index* + """ + raise NotImplementedError("TriInterpolator subclasses" + + "should implement _interpolate_single_key!") + + +class LinearTriInterpolator(TriInterpolator): + """ + Linear interpolator on a triangular grid. + + Each triangle is represented by a plane so that an interpolated value at + point (x, y) lies on the plane of the triangle containing (x, y). + Interpolated values are therefore continuous across the triangulation, but + their first derivatives are discontinuous at edges between triangles. + + Parameters + ---------- + triangulation : `~matplotlib.tri.Triangulation` + The triangulation to interpolate over. + z : (npoints,) array-like + Array of values, defined at grid points, to interpolate between. + trifinder : `~matplotlib.tri.TriFinder`, optional + If this is not specified, the Triangulation's default TriFinder will + be used by calling `.Triangulation.get_trifinder`. + + Methods + ------- + `__call__` (x, y) : Returns interpolated values at (x, y) points. + `gradient` (x, y) : Returns interpolated derivatives at (x, y) points. + + """ + def __init__(self, triangulation, z, trifinder=None): + super().__init__(triangulation, z, trifinder) + + # Store plane coefficients for fast interpolation calculations. + self._plane_coefficients = \ + self._triangulation.calculate_plane_coefficients(self._z) + + def __call__(self, x, y): + return self._interpolate_multikeys(x, y, tri_index=None, + return_keys=('z',))[0] + __call__.__doc__ = TriInterpolator._docstring__call__ + + def gradient(self, x, y): + return self._interpolate_multikeys(x, y, tri_index=None, + return_keys=('dzdx', 'dzdy')) + gradient.__doc__ = TriInterpolator._docstringgradient + + def _interpolate_single_key(self, return_key, tri_index, x, y): + _api.check_in_list(['z', 'dzdx', 'dzdy'], return_key=return_key) + if return_key == 'z': + return (self._plane_coefficients[tri_index, 0]*x + + self._plane_coefficients[tri_index, 1]*y + + self._plane_coefficients[tri_index, 2]) + elif return_key == 'dzdx': + return self._plane_coefficients[tri_index, 0] + else: # 'dzdy' + return self._plane_coefficients[tri_index, 1] + + +class CubicTriInterpolator(TriInterpolator): + r""" + Cubic interpolator on a triangular grid. + + In one-dimension - on a segment - a cubic interpolating function is + defined by the values of the function and its derivative at both ends. + This is almost the same in 2D inside a triangle, except that the values + of the function and its 2 derivatives have to be defined at each triangle + node. + + The CubicTriInterpolator takes the value of the function at each node - + provided by the user - and internally computes the value of the + derivatives, resulting in a smooth interpolation. + (As a special feature, the user can also impose the value of the + derivatives at each node, but this is not supposed to be the common + usage.) + + Parameters + ---------- + triangulation : `~matplotlib.tri.Triangulation` + The triangulation to interpolate over. + z : (npoints,) array-like + Array of values, defined at grid points, to interpolate between. + kind : {'min_E', 'geom', 'user'}, optional + Choice of the smoothing algorithm, in order to compute + the interpolant derivatives (defaults to 'min_E'): + + - if 'min_E': (default) The derivatives at each node is computed + to minimize a bending energy. + - if 'geom': The derivatives at each node is computed as a + weighted average of relevant triangle normals. To be used for + speed optimization (large grids). + - if 'user': The user provides the argument *dz*, no computation + is hence needed. + + trifinder : `~matplotlib.tri.TriFinder`, optional + If not specified, the Triangulation's default TriFinder will + be used by calling `.Triangulation.get_trifinder`. + dz : tuple of array-likes (dzdx, dzdy), optional + Used only if *kind* ='user'. In this case *dz* must be provided as + (dzdx, dzdy) where dzdx, dzdy are arrays of the same shape as *z* and + are the interpolant first derivatives at the *triangulation* points. + + Methods + ------- + `__call__` (x, y) : Returns interpolated values at (x, y) points. + `gradient` (x, y) : Returns interpolated derivatives at (x, y) points. + + Notes + ----- + This note is a bit technical and details how the cubic interpolation is + computed. + + The interpolation is based on a Clough-Tocher subdivision scheme of + the *triangulation* mesh (to make it clearer, each triangle of the + grid will be divided in 3 child-triangles, and on each child triangle + the interpolated function is a cubic polynomial of the 2 coordinates). + This technique originates from FEM (Finite Element Method) analysis; + the element used is a reduced Hsieh-Clough-Tocher (HCT) + element. Its shape functions are described in [1]_. + The assembled function is guaranteed to be C1-smooth, i.e. it is + continuous and its first derivatives are also continuous (this + is easy to show inside the triangles but is also true when crossing the + edges). + + In the default case (*kind* ='min_E'), the interpolant minimizes a + curvature energy on the functional space generated by the HCT element + shape functions - with imposed values but arbitrary derivatives at each + node. The minimized functional is the integral of the so-called total + curvature (implementation based on an algorithm from [2]_ - PCG sparse + solver): + + .. math:: + + E(z) = \frac{1}{2} \int_{\Omega} \left( + \left( \frac{\partial^2{z}}{\partial{x}^2} \right)^2 + + \left( \frac{\partial^2{z}}{\partial{y}^2} \right)^2 + + 2\left( \frac{\partial^2{z}}{\partial{y}\partial{x}} \right)^2 + \right) dx\,dy + + If the case *kind* ='geom' is chosen by the user, a simple geometric + approximation is used (weighted average of the triangle normal + vectors), which could improve speed on very large grids. + + References + ---------- + .. [1] Michel Bernadou, Kamal Hassan, "Basis functions for general + Hsieh-Clough-Tocher triangles, complete or reduced.", + International Journal for Numerical Methods in Engineering, + 17(5):784 - 789. 2.01. + .. [2] C.T. Kelley, "Iterative Methods for Optimization". + + """ + def __init__(self, triangulation, z, kind='min_E', trifinder=None, + dz=None): + super().__init__(triangulation, z, trifinder) + + # Loads the underlying c++ _triangulation. + # (During loading, reordering of triangulation._triangles may occur so + # that all final triangles are now anti-clockwise) + self._triangulation.get_cpp_triangulation() + + # To build the stiffness matrix and avoid zero-energy spurious modes + # we will only store internally the valid (unmasked) triangles and + # the necessary (used) points coordinates. + # 2 renumbering tables need to be computed and stored: + # - a triangle renum table in order to translate the result from a + # TriFinder instance into the internal stored triangle number. + # - a node renum table to overwrite the self._z values into the new + # (used) node numbering. + tri_analyzer = TriAnalyzer(self._triangulation) + (compressed_triangles, compressed_x, compressed_y, tri_renum, + node_renum) = tri_analyzer._get_compressed_triangulation() + self._triangles = compressed_triangles + self._tri_renum = tri_renum + # Taking into account the node renumbering in self._z: + valid_node = (node_renum != -1) + self._z[node_renum[valid_node]] = self._z[valid_node] + + # Computing scale factors + self._unit_x = np.ptp(compressed_x) + self._unit_y = np.ptp(compressed_y) + self._pts = np.column_stack([compressed_x / self._unit_x, + compressed_y / self._unit_y]) + # Computing triangle points + self._tris_pts = self._pts[self._triangles] + # Computing eccentricities + self._eccs = self._compute_tri_eccentricities(self._tris_pts) + # Computing dof estimations for HCT triangle shape function + _api.check_in_list(['user', 'geom', 'min_E'], kind=kind) + self._dof = self._compute_dof(kind, dz=dz) + # Loading HCT element + self._ReferenceElement = _ReducedHCT_Element() + + def __call__(self, x, y): + return self._interpolate_multikeys(x, y, tri_index=None, + return_keys=('z',))[0] + __call__.__doc__ = TriInterpolator._docstring__call__ + + def gradient(self, x, y): + return self._interpolate_multikeys(x, y, tri_index=None, + return_keys=('dzdx', 'dzdy')) + gradient.__doc__ = TriInterpolator._docstringgradient + + def _interpolate_single_key(self, return_key, tri_index, x, y): + _api.check_in_list(['z', 'dzdx', 'dzdy'], return_key=return_key) + tris_pts = self._tris_pts[tri_index] + alpha = self._get_alpha_vec(x, y, tris_pts) + ecc = self._eccs[tri_index] + dof = np.expand_dims(self._dof[tri_index], axis=1) + if return_key == 'z': + return self._ReferenceElement.get_function_values( + alpha, ecc, dof) + else: # 'dzdx', 'dzdy' + J = self._get_jacobian(tris_pts) + dzdx = self._ReferenceElement.get_function_derivatives( + alpha, J, ecc, dof) + if return_key == 'dzdx': + return dzdx[:, 0, 0] + else: + return dzdx[:, 1, 0] + + def _compute_dof(self, kind, dz=None): + """ + Compute and return nodal dofs according to kind. + + Parameters + ---------- + kind : {'min_E', 'geom', 'user'} + Choice of the _DOF_estimator subclass to estimate the gradient. + dz : tuple of array-likes (dzdx, dzdy), optional + Used only if *kind*=user; in this case passed to the + :class:`_DOF_estimator_user`. + + Returns + ------- + array-like, shape (npts, 2) + Estimation of the gradient at triangulation nodes (stored as + degree of freedoms of reduced-HCT triangle elements). + """ + if kind == 'user': + if dz is None: + raise ValueError("For a CubicTriInterpolator with " + "*kind*='user', a valid *dz* " + "argument is expected.") + TE = _DOF_estimator_user(self, dz=dz) + elif kind == 'geom': + TE = _DOF_estimator_geom(self) + else: # 'min_E', checked in __init__ + TE = _DOF_estimator_min_E(self) + return TE.compute_dof_from_df() + + @staticmethod + def _get_alpha_vec(x, y, tris_pts): + """ + Fast (vectorized) function to compute barycentric coordinates alpha. + + Parameters + ---------- + x, y : array-like of dim 1 (shape (nx,)) + Coordinates of the points whose points barycentric coordinates are + requested. + tris_pts : array like of dim 3 (shape: (nx, 3, 2)) + Coordinates of the containing triangles apexes. + + Returns + ------- + array of dim 2 (shape (nx, 3)) + Barycentric coordinates of the points inside the containing + triangles. + """ + ndim = tris_pts.ndim-2 + + a = tris_pts[:, 1, :] - tris_pts[:, 0, :] + b = tris_pts[:, 2, :] - tris_pts[:, 0, :] + abT = np.stack([a, b], axis=-1) + ab = _transpose_vectorized(abT) + OM = np.stack([x, y], axis=1) - tris_pts[:, 0, :] + + metric = ab @ abT + # Here we try to deal with the colinear cases. + # metric_inv is in this case set to the Moore-Penrose pseudo-inverse + # meaning that we will still return a set of valid barycentric + # coordinates. + metric_inv = _pseudo_inv22sym_vectorized(metric) + Covar = ab @ _transpose_vectorized(np.expand_dims(OM, ndim)) + ksi = metric_inv @ Covar + alpha = _to_matrix_vectorized([ + [1-ksi[:, 0, 0]-ksi[:, 1, 0]], [ksi[:, 0, 0]], [ksi[:, 1, 0]]]) + return alpha + + @staticmethod + def _get_jacobian(tris_pts): + """ + Fast (vectorized) function to compute triangle jacobian matrix. + + Parameters + ---------- + tris_pts : array like of dim 3 (shape: (nx, 3, 2)) + Coordinates of the containing triangles apexes. + + Returns + ------- + array of dim 3 (shape (nx, 2, 2)) + Barycentric coordinates of the points inside the containing + triangles. + J[itri, :, :] is the jacobian matrix at apex 0 of the triangle + itri, so that the following (matrix) relationship holds: + [dz/dksi] = [J] x [dz/dx] + with x: global coordinates + ksi: element parametric coordinates in triangle first apex + local basis. + """ + a = np.array(tris_pts[:, 1, :] - tris_pts[:, 0, :]) + b = np.array(tris_pts[:, 2, :] - tris_pts[:, 0, :]) + J = _to_matrix_vectorized([[a[:, 0], a[:, 1]], + [b[:, 0], b[:, 1]]]) + return J + + @staticmethod + def _compute_tri_eccentricities(tris_pts): + """ + Compute triangle eccentricities. + + Parameters + ---------- + tris_pts : array like of dim 3 (shape: (nx, 3, 2)) + Coordinates of the triangles apexes. + + Returns + ------- + array like of dim 2 (shape: (nx, 3)) + The so-called eccentricity parameters [1] needed for HCT triangular + element. + """ + a = np.expand_dims(tris_pts[:, 2, :] - tris_pts[:, 1, :], axis=2) + b = np.expand_dims(tris_pts[:, 0, :] - tris_pts[:, 2, :], axis=2) + c = np.expand_dims(tris_pts[:, 1, :] - tris_pts[:, 0, :], axis=2) + # Do not use np.squeeze, this is dangerous if only one triangle + # in the triangulation... + dot_a = (_transpose_vectorized(a) @ a)[:, 0, 0] + dot_b = (_transpose_vectorized(b) @ b)[:, 0, 0] + dot_c = (_transpose_vectorized(c) @ c)[:, 0, 0] + # Note that this line will raise a warning for dot_a, dot_b or dot_c + # zeros, but we choose not to support triangles with duplicate points. + return _to_matrix_vectorized([[(dot_c-dot_b) / dot_a], + [(dot_a-dot_c) / dot_b], + [(dot_b-dot_a) / dot_c]]) + + +# FEM element used for interpolation and for solving minimisation +# problem (Reduced HCT element) +class _ReducedHCT_Element: + """ + Implementation of reduced HCT triangular element with explicit shape + functions. + + Computes z, dz, d2z and the element stiffness matrix for bending energy: + E(f) = integral( (d2z/dx2 + d2z/dy2)**2 dA) + + *** Reference for the shape functions: *** + [1] Basis functions for general Hsieh-Clough-Tocher _triangles, complete or + reduced. + Michel Bernadou, Kamal Hassan + International Journal for Numerical Methods in Engineering. + 17(5):784 - 789. 2.01 + + *** Element description: *** + 9 dofs: z and dz given at 3 apex + C1 (conform) + + """ + # 1) Loads matrices to generate shape functions as a function of + # triangle eccentricities - based on [1] p.11 ''' + M = np.array([ + [ 0.00, 0.00, 0.00, 4.50, 4.50, 0.00, 0.00, 0.00, 0.00, 0.00], + [-0.25, 0.00, 0.00, 0.50, 1.25, 0.00, 0.00, 0.00, 0.00, 0.00], + [-0.25, 0.00, 0.00, 1.25, 0.50, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.50, 1.00, 0.00, -1.50, 0.00, 3.00, 3.00, 0.00, 0.00, 3.00], + [ 0.00, 0.00, 0.00, -0.25, 0.25, 0.00, 1.00, 0.00, 0.00, 0.50], + [ 0.25, 0.00, 0.00, -0.50, -0.25, 1.00, 0.00, 0.00, 0.00, 1.00], + [ 0.50, 0.00, 1.00, 0.00, -1.50, 0.00, 0.00, 3.00, 3.00, 3.00], + [ 0.25, 0.00, 0.00, -0.25, -0.50, 0.00, 0.00, 0.00, 1.00, 1.00], + [ 0.00, 0.00, 0.00, 0.25, -0.25, 0.00, 0.00, 1.00, 0.00, 0.50]]) + M0 = np.array([ + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [-1.00, 0.00, 0.00, 1.50, 1.50, 0.00, 0.00, 0.00, 0.00, -3.00], + [-0.50, 0.00, 0.00, 0.75, 0.75, 0.00, 0.00, 0.00, 0.00, -1.50], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 1.00, 0.00, 0.00, -1.50, -1.50, 0.00, 0.00, 0.00, 0.00, 3.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.50, 0.00, 0.00, -0.75, -0.75, 0.00, 0.00, 0.00, 0.00, 1.50]]) + M1 = np.array([ + [-0.50, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [-0.25, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.50, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.25, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]]) + M2 = np.array([ + [ 0.50, 0.00, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.25, 0.00, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [-0.50, 0.00, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [-0.25, 0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00], + [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]]) + + # 2) Loads matrices to rotate components of gradient & Hessian + # vectors in the reference basis of triangle first apex (a0) + rotate_dV = np.array([[ 1., 0.], [ 0., 1.], + [ 0., 1.], [-1., -1.], + [-1., -1.], [ 1., 0.]]) + + rotate_d2V = np.array([[1., 0., 0.], [0., 1., 0.], [ 0., 0., 1.], + [0., 1., 0.], [1., 1., 1.], [ 0., -2., -1.], + [1., 1., 1.], [1., 0., 0.], [-2., 0., -1.]]) + + # 3) Loads Gauss points & weights on the 3 sub-_triangles for P2 + # exact integral - 3 points on each subtriangles. + # NOTE: as the 2nd derivative is discontinuous , we really need those 9 + # points! + n_gauss = 9 + gauss_pts = np.array([[13./18., 4./18., 1./18.], + [ 4./18., 13./18., 1./18.], + [ 7./18., 7./18., 4./18.], + [ 1./18., 13./18., 4./18.], + [ 1./18., 4./18., 13./18.], + [ 4./18., 7./18., 7./18.], + [ 4./18., 1./18., 13./18.], + [13./18., 1./18., 4./18.], + [ 7./18., 4./18., 7./18.]], dtype=np.float64) + gauss_w = np.ones([9], dtype=np.float64) / 9. + + # 4) Stiffness matrix for curvature energy + E = np.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 2.]]) + + # 5) Loads the matrix to compute DOF_rot from tri_J at apex 0 + J0_to_J1 = np.array([[-1., 1.], [-1., 0.]]) + J0_to_J2 = np.array([[ 0., -1.], [ 1., -1.]]) + + def get_function_values(self, alpha, ecc, dofs): + """ + Parameters + ---------- + alpha : is a (N x 3 x 1) array (array of column-matrices) of + barycentric coordinates, + ecc : is a (N x 3 x 1) array (array of column-matrices) of triangle + eccentricities, + dofs : is a (N x 1 x 9) arrays (arrays of row-matrices) of computed + degrees of freedom. + + Returns + ------- + Returns the N-array of interpolated function values. + """ + subtri = np.argmin(alpha, axis=1)[:, 0] + ksi = _roll_vectorized(alpha, -subtri, axis=0) + E = _roll_vectorized(ecc, -subtri, axis=0) + x = ksi[:, 0, 0] + y = ksi[:, 1, 0] + z = ksi[:, 2, 0] + x_sq = x*x + y_sq = y*y + z_sq = z*z + V = _to_matrix_vectorized([ + [x_sq*x], [y_sq*y], [z_sq*z], [x_sq*z], [x_sq*y], [y_sq*x], + [y_sq*z], [z_sq*y], [z_sq*x], [x*y*z]]) + prod = self.M @ V + prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ V) + prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ V) + prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ V) + s = _roll_vectorized(prod, 3*subtri, axis=0) + return (dofs @ s)[:, 0, 0] + + def get_function_derivatives(self, alpha, J, ecc, dofs): + """ + Parameters + ---------- + *alpha* is a (N x 3 x 1) array (array of column-matrices of + barycentric coordinates) + *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at + triangle first apex) + *ecc* is a (N x 3 x 1) array (array of column-matrices of triangle + eccentricities) + *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed + degrees of freedom. + + Returns + ------- + Returns the values of interpolated function derivatives [dz/dx, dz/dy] + in global coordinates at locations alpha, as a column-matrices of + shape (N x 2 x 1). + """ + subtri = np.argmin(alpha, axis=1)[:, 0] + ksi = _roll_vectorized(alpha, -subtri, axis=0) + E = _roll_vectorized(ecc, -subtri, axis=0) + x = ksi[:, 0, 0] + y = ksi[:, 1, 0] + z = ksi[:, 2, 0] + x_sq = x*x + y_sq = y*y + z_sq = z*z + dV = _to_matrix_vectorized([ + [ -3.*x_sq, -3.*x_sq], + [ 3.*y_sq, 0.], + [ 0., 3.*z_sq], + [ -2.*x*z, -2.*x*z+x_sq], + [-2.*x*y+x_sq, -2.*x*y], + [ 2.*x*y-y_sq, -y_sq], + [ 2.*y*z, y_sq], + [ z_sq, 2.*y*z], + [ -z_sq, 2.*x*z-z_sq], + [ x*z-y*z, x*y-y*z]]) + # Puts back dV in first apex basis + dV = dV @ _extract_submatrices( + self.rotate_dV, subtri, block_size=2, axis=0) + + prod = self.M @ dV + prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ dV) + prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ dV) + prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ dV) + dsdksi = _roll_vectorized(prod, 3*subtri, axis=0) + dfdksi = dofs @ dsdksi + # In global coordinates: + # Here we try to deal with the simplest colinear cases, returning a + # null matrix. + J_inv = _safe_inv22_vectorized(J) + dfdx = J_inv @ _transpose_vectorized(dfdksi) + return dfdx + + def get_function_hessians(self, alpha, J, ecc, dofs): + """ + Parameters + ---------- + *alpha* is a (N x 3 x 1) array (array of column-matrices) of + barycentric coordinates + *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at + triangle first apex) + *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle + eccentricities + *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed + degrees of freedom. + + Returns + ------- + Returns the values of interpolated function 2nd-derivatives + [d2z/dx2, d2z/dy2, d2z/dxdy] in global coordinates at locations alpha, + as a column-matrices of shape (N x 3 x 1). + """ + d2sdksi2 = self.get_d2Sidksij2(alpha, ecc) + d2fdksi2 = dofs @ d2sdksi2 + H_rot = self.get_Hrot_from_J(J) + d2fdx2 = d2fdksi2 @ H_rot + return _transpose_vectorized(d2fdx2) + + def get_d2Sidksij2(self, alpha, ecc): + """ + Parameters + ---------- + *alpha* is a (N x 3 x 1) array (array of column-matrices) of + barycentric coordinates + *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle + eccentricities + + Returns + ------- + Returns the arrays d2sdksi2 (N x 3 x 1) Hessian of shape functions + expressed in covariant coordinates in first apex basis. + """ + subtri = np.argmin(alpha, axis=1)[:, 0] + ksi = _roll_vectorized(alpha, -subtri, axis=0) + E = _roll_vectorized(ecc, -subtri, axis=0) + x = ksi[:, 0, 0] + y = ksi[:, 1, 0] + z = ksi[:, 2, 0] + d2V = _to_matrix_vectorized([ + [ 6.*x, 6.*x, 6.*x], + [ 6.*y, 0., 0.], + [ 0., 6.*z, 0.], + [ 2.*z, 2.*z-4.*x, 2.*z-2.*x], + [2.*y-4.*x, 2.*y, 2.*y-2.*x], + [2.*x-4.*y, 0., -2.*y], + [ 2.*z, 0., 2.*y], + [ 0., 2.*y, 2.*z], + [ 0., 2.*x-4.*z, -2.*z], + [ -2.*z, -2.*y, x-y-z]]) + # Puts back d2V in first apex basis + d2V = d2V @ _extract_submatrices( + self.rotate_d2V, subtri, block_size=3, axis=0) + prod = self.M @ d2V + prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ d2V) + prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ d2V) + prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ d2V) + d2sdksi2 = _roll_vectorized(prod, 3*subtri, axis=0) + return d2sdksi2 + + def get_bending_matrices(self, J, ecc): + """ + Parameters + ---------- + *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at + triangle first apex) + *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle + eccentricities + + Returns + ------- + Returns the element K matrices for bending energy expressed in + GLOBAL nodal coordinates. + K_ij = integral [ (d2zi/dx2 + d2zi/dy2) * (d2zj/dx2 + d2zj/dy2) dA] + tri_J is needed to rotate dofs from local basis to global basis + """ + n = np.size(ecc, 0) + + # 1) matrix to rotate dofs in global coordinates + J1 = self.J0_to_J1 @ J + J2 = self.J0_to_J2 @ J + DOF_rot = np.zeros([n, 9, 9], dtype=np.float64) + DOF_rot[:, 0, 0] = 1 + DOF_rot[:, 3, 3] = 1 + DOF_rot[:, 6, 6] = 1 + DOF_rot[:, 1:3, 1:3] = J + DOF_rot[:, 4:6, 4:6] = J1 + DOF_rot[:, 7:9, 7:9] = J2 + + # 2) matrix to rotate Hessian in global coordinates. + H_rot, area = self.get_Hrot_from_J(J, return_area=True) + + # 3) Computes stiffness matrix + # Gauss quadrature. + K = np.zeros([n, 9, 9], dtype=np.float64) + weights = self.gauss_w + pts = self.gauss_pts + for igauss in range(self.n_gauss): + alpha = np.tile(pts[igauss, :], n).reshape(n, 3) + alpha = np.expand_dims(alpha, 2) + weight = weights[igauss] + d2Skdksi2 = self.get_d2Sidksij2(alpha, ecc) + d2Skdx2 = d2Skdksi2 @ H_rot + K += weight * (d2Skdx2 @ self.E @ _transpose_vectorized(d2Skdx2)) + + # 4) With nodal (not elem) dofs + K = _transpose_vectorized(DOF_rot) @ K @ DOF_rot + + # 5) Need the area to compute total element energy + return _scalar_vectorized(area, K) + + def get_Hrot_from_J(self, J, return_area=False): + """ + Parameters + ---------- + *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at + triangle first apex) + + Returns + ------- + Returns H_rot used to rotate Hessian from local basis of first apex, + to global coordinates. + if *return_area* is True, returns also the triangle area (0.5*det(J)) + """ + # Here we try to deal with the simplest colinear cases; a null + # energy and area is imposed. + J_inv = _safe_inv22_vectorized(J) + Ji00 = J_inv[:, 0, 0] + Ji11 = J_inv[:, 1, 1] + Ji10 = J_inv[:, 1, 0] + Ji01 = J_inv[:, 0, 1] + H_rot = _to_matrix_vectorized([ + [Ji00*Ji00, Ji10*Ji10, Ji00*Ji10], + [Ji01*Ji01, Ji11*Ji11, Ji01*Ji11], + [2*Ji00*Ji01, 2*Ji11*Ji10, Ji00*Ji11+Ji10*Ji01]]) + if not return_area: + return H_rot + else: + area = 0.5 * (J[:, 0, 0]*J[:, 1, 1] - J[:, 0, 1]*J[:, 1, 0]) + return H_rot, area + + def get_Kff_and_Ff(self, J, ecc, triangles, Uc): + """ + Build K and F for the following elliptic formulation: + minimization of curvature energy with value of function at node + imposed and derivatives 'free'. + + Build the global Kff matrix in cco format. + Build the full Ff vec Ff = - Kfc x Uc. + + Parameters + ---------- + *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at + triangle first apex) + *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle + eccentricities + *triangles* is a (N x 3) array of nodes indexes. + *Uc* is (N x 3) array of imposed displacements at nodes + + Returns + ------- + (Kff_rows, Kff_cols, Kff_vals) Kff matrix in coo format - Duplicate + (row, col) entries must be summed. + Ff: force vector - dim npts * 3 + """ + ntri = np.size(ecc, 0) + vec_range = np.arange(ntri, dtype=np.int32) + c_indices = np.full(ntri, -1, dtype=np.int32) # for unused dofs, -1 + f_dof = [1, 2, 4, 5, 7, 8] + c_dof = [0, 3, 6] + + # vals, rows and cols indices in global dof numbering + f_dof_indices = _to_matrix_vectorized([[ + c_indices, triangles[:, 0]*2, triangles[:, 0]*2+1, + c_indices, triangles[:, 1]*2, triangles[:, 1]*2+1, + c_indices, triangles[:, 2]*2, triangles[:, 2]*2+1]]) + + expand_indices = np.ones([ntri, 9, 1], dtype=np.int32) + f_row_indices = _transpose_vectorized(expand_indices @ f_dof_indices) + f_col_indices = expand_indices @ f_dof_indices + K_elem = self.get_bending_matrices(J, ecc) + + # Extracting sub-matrices + # Explanation & notations: + # * Subscript f denotes 'free' degrees of freedom (i.e. dz/dx, dz/dx) + # * Subscript c denotes 'condensated' (imposed) degrees of freedom + # (i.e. z at all nodes) + # * F = [Ff, Fc] is the force vector + # * U = [Uf, Uc] is the imposed dof vector + # [ Kff Kfc ] + # * K = [ ] is the laplacian stiffness matrix + # [ Kcf Kff ] + # * As F = K x U one gets straightforwardly: Ff = - Kfc x Uc + + # Computing Kff stiffness matrix in sparse coo format + Kff_vals = np.ravel(K_elem[np.ix_(vec_range, f_dof, f_dof)]) + Kff_rows = np.ravel(f_row_indices[np.ix_(vec_range, f_dof, f_dof)]) + Kff_cols = np.ravel(f_col_indices[np.ix_(vec_range, f_dof, f_dof)]) + + # Computing Ff force vector in sparse coo format + Kfc_elem = K_elem[np.ix_(vec_range, f_dof, c_dof)] + Uc_elem = np.expand_dims(Uc, axis=2) + Ff_elem = -(Kfc_elem @ Uc_elem)[:, :, 0] + Ff_indices = f_dof_indices[np.ix_(vec_range, [0], f_dof)][:, 0, :] + + # Extracting Ff force vector in dense format + # We have to sum duplicate indices - using bincount + Ff = np.bincount(np.ravel(Ff_indices), weights=np.ravel(Ff_elem)) + return Kff_rows, Kff_cols, Kff_vals, Ff + + +# :class:_DOF_estimator, _DOF_estimator_user, _DOF_estimator_geom, +# _DOF_estimator_min_E +# Private classes used to compute the degree of freedom of each triangular +# element for the TriCubicInterpolator. +class _DOF_estimator: + """ + Abstract base class for classes used to estimate a function's first + derivatives, and deduce the dofs for a CubicTriInterpolator using a + reduced HCT element formulation. + + Derived classes implement ``compute_df(self, **kwargs)``, returning + ``np.vstack([dfx, dfy]).T`` where ``dfx, dfy`` are the estimation of the 2 + gradient coordinates. + """ + def __init__(self, interpolator, **kwargs): + _api.check_isinstance(CubicTriInterpolator, interpolator=interpolator) + self._pts = interpolator._pts + self._tris_pts = interpolator._tris_pts + self.z = interpolator._z + self._triangles = interpolator._triangles + (self._unit_x, self._unit_y) = (interpolator._unit_x, + interpolator._unit_y) + self.dz = self.compute_dz(**kwargs) + self.compute_dof_from_df() + + def compute_dz(self, **kwargs): + raise NotImplementedError + + def compute_dof_from_df(self): + """ + Compute reduced-HCT elements degrees of freedom, from the gradient. + """ + J = CubicTriInterpolator._get_jacobian(self._tris_pts) + tri_z = self.z[self._triangles] + tri_dz = self.dz[self._triangles] + tri_dof = self.get_dof_vec(tri_z, tri_dz, J) + return tri_dof + + @staticmethod + def get_dof_vec(tri_z, tri_dz, J): + """ + Compute the dof vector of a triangle, from the value of f, df and + of the local Jacobian at each node. + + Parameters + ---------- + tri_z : shape (3,) array + f nodal values. + tri_dz : shape (3, 2) array + df/dx, df/dy nodal values. + J + Jacobian matrix in local basis of apex 0. + + Returns + ------- + dof : shape (9,) array + For each apex ``iapex``:: + + dof[iapex*3+0] = f(Ai) + dof[iapex*3+1] = df(Ai).(AiAi+) + dof[iapex*3+2] = df(Ai).(AiAi-) + """ + npt = tri_z.shape[0] + dof = np.zeros([npt, 9], dtype=np.float64) + J1 = _ReducedHCT_Element.J0_to_J1 @ J + J2 = _ReducedHCT_Element.J0_to_J2 @ J + + col0 = J @ np.expand_dims(tri_dz[:, 0, :], axis=2) + col1 = J1 @ np.expand_dims(tri_dz[:, 1, :], axis=2) + col2 = J2 @ np.expand_dims(tri_dz[:, 2, :], axis=2) + + dfdksi = _to_matrix_vectorized([ + [col0[:, 0, 0], col1[:, 0, 0], col2[:, 0, 0]], + [col0[:, 1, 0], col1[:, 1, 0], col2[:, 1, 0]]]) + dof[:, 0:7:3] = tri_z + dof[:, 1:8:3] = dfdksi[:, 0] + dof[:, 2:9:3] = dfdksi[:, 1] + return dof + + +class _DOF_estimator_user(_DOF_estimator): + """dz is imposed by user; accounts for scaling if any.""" + + def compute_dz(self, dz): + (dzdx, dzdy) = dz + dzdx = dzdx * self._unit_x + dzdy = dzdy * self._unit_y + return np.vstack([dzdx, dzdy]).T + + +class _DOF_estimator_geom(_DOF_estimator): + """Fast 'geometric' approximation, recommended for large arrays.""" + + def compute_dz(self): + """ + self.df is computed as weighted average of _triangles sharing a common + node. On each triangle itri f is first assumed linear (= ~f), which + allows to compute d~f[itri] + Then the following approximation of df nodal values is then proposed: + f[ipt] = SUM ( w[itri] x d~f[itri] , for itri sharing apex ipt) + The weighted coeff. w[itri] are proportional to the angle of the + triangle itri at apex ipt + """ + el_geom_w = self.compute_geom_weights() + el_geom_grad = self.compute_geom_grads() + + # Sum of weights coeffs + w_node_sum = np.bincount(np.ravel(self._triangles), + weights=np.ravel(el_geom_w)) + + # Sum of weighted df = (dfx, dfy) + dfx_el_w = np.empty_like(el_geom_w) + dfy_el_w = np.empty_like(el_geom_w) + for iapex in range(3): + dfx_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 0] + dfy_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 1] + dfx_node_sum = np.bincount(np.ravel(self._triangles), + weights=np.ravel(dfx_el_w)) + dfy_node_sum = np.bincount(np.ravel(self._triangles), + weights=np.ravel(dfy_el_w)) + + # Estimation of df + dfx_estim = dfx_node_sum/w_node_sum + dfy_estim = dfy_node_sum/w_node_sum + return np.vstack([dfx_estim, dfy_estim]).T + + def compute_geom_weights(self): + """ + Build the (nelems, 3) weights coeffs of _triangles angles, + renormalized so that np.sum(weights, axis=1) == np.ones(nelems) + """ + weights = np.zeros([np.size(self._triangles, 0), 3]) + tris_pts = self._tris_pts + for ipt in range(3): + p0 = tris_pts[:, ipt % 3, :] + p1 = tris_pts[:, (ipt+1) % 3, :] + p2 = tris_pts[:, (ipt-1) % 3, :] + alpha1 = np.arctan2(p1[:, 1]-p0[:, 1], p1[:, 0]-p0[:, 0]) + alpha2 = np.arctan2(p2[:, 1]-p0[:, 1], p2[:, 0]-p0[:, 0]) + # In the below formula we could take modulo 2. but + # modulo 1. is safer regarding round-off errors (flat triangles). + angle = np.abs(((alpha2-alpha1) / np.pi) % 1) + # Weight proportional to angle up np.pi/2; null weight for + # degenerated cases 0 and np.pi (note that *angle* is normalized + # by np.pi). + weights[:, ipt] = 0.5 - np.abs(angle-0.5) + return weights + + def compute_geom_grads(self): + """ + Compute the (global) gradient component of f assumed linear (~f). + returns array df of shape (nelems, 2) + df[ielem].dM[ielem] = dz[ielem] i.e. df = dz x dM = dM.T^-1 x dz + """ + tris_pts = self._tris_pts + tris_f = self.z[self._triangles] + + dM1 = tris_pts[:, 1, :] - tris_pts[:, 0, :] + dM2 = tris_pts[:, 2, :] - tris_pts[:, 0, :] + dM = np.dstack([dM1, dM2]) + # Here we try to deal with the simplest colinear cases: a null + # gradient is assumed in this case. + dM_inv = _safe_inv22_vectorized(dM) + + dZ1 = tris_f[:, 1] - tris_f[:, 0] + dZ2 = tris_f[:, 2] - tris_f[:, 0] + dZ = np.vstack([dZ1, dZ2]).T + df = np.empty_like(dZ) + + # With np.einsum: could be ej,eji -> ej + df[:, 0] = dZ[:, 0]*dM_inv[:, 0, 0] + dZ[:, 1]*dM_inv[:, 1, 0] + df[:, 1] = dZ[:, 0]*dM_inv[:, 0, 1] + dZ[:, 1]*dM_inv[:, 1, 1] + return df + + +class _DOF_estimator_min_E(_DOF_estimator_geom): + """ + The 'smoothest' approximation, df is computed through global minimization + of the bending energy: + E(f) = integral[(d2z/dx2 + d2z/dy2 + 2 d2z/dxdy)**2 dA] + """ + def __init__(self, Interpolator): + self._eccs = Interpolator._eccs + super().__init__(Interpolator) + + def compute_dz(self): + """ + Elliptic solver for bending energy minimization. + Uses a dedicated 'toy' sparse Jacobi PCG solver. + """ + # Initial guess for iterative PCG solver. + dz_init = super().compute_dz() + Uf0 = np.ravel(dz_init) + + reference_element = _ReducedHCT_Element() + J = CubicTriInterpolator._get_jacobian(self._tris_pts) + eccs = self._eccs + triangles = self._triangles + Uc = self.z[self._triangles] + + # Building stiffness matrix and force vector in coo format + Kff_rows, Kff_cols, Kff_vals, Ff = reference_element.get_Kff_and_Ff( + J, eccs, triangles, Uc) + + # Building sparse matrix and solving minimization problem + # We could use scipy.sparse direct solver; however to avoid this + # external dependency an implementation of a simple PCG solver with + # a simple diagonal Jacobi preconditioner is implemented. + tol = 1.e-10 + n_dof = Ff.shape[0] + Kff_coo = _Sparse_Matrix_coo(Kff_vals, Kff_rows, Kff_cols, + shape=(n_dof, n_dof)) + Kff_coo.compress_csc() + Uf, err = _cg(A=Kff_coo, b=Ff, x0=Uf0, tol=tol) + # If the PCG did not converge, we return the best guess between Uf0 + # and Uf. + err0 = np.linalg.norm(Kff_coo.dot(Uf0) - Ff) + if err0 < err: + # Maybe a good occasion to raise a warning here ? + _api.warn_external("In TriCubicInterpolator initialization, " + "PCG sparse solver did not converge after " + "1000 iterations. `geom` approximation is " + "used instead of `min_E`") + Uf = Uf0 + + # Building dz from Uf + dz = np.empty([self._pts.shape[0], 2], dtype=np.float64) + dz[:, 0] = Uf[::2] + dz[:, 1] = Uf[1::2] + return dz + + +# The following private :class:_Sparse_Matrix_coo and :func:_cg provide +# a PCG sparse solver for (symmetric) elliptic problems. +class _Sparse_Matrix_coo: + def __init__(self, vals, rows, cols, shape): + """ + Create a sparse matrix in coo format. + *vals*: arrays of values of non-null entries of the matrix + *rows*: int arrays of rows of non-null entries of the matrix + *cols*: int arrays of cols of non-null entries of the matrix + *shape*: 2-tuple (n, m) of matrix shape + """ + self.n, self.m = shape + self.vals = np.asarray(vals, dtype=np.float64) + self.rows = np.asarray(rows, dtype=np.int32) + self.cols = np.asarray(cols, dtype=np.int32) + + def dot(self, V): + """ + Dot product of self by a vector *V* in sparse-dense to dense format + *V* dense vector of shape (self.m,). + """ + assert V.shape == (self.m,) + return np.bincount(self.rows, + weights=self.vals*V[self.cols], + minlength=self.m) + + def compress_csc(self): + """ + Compress rows, cols, vals / summing duplicates. Sort for csc format. + """ + _, unique, indices = np.unique( + self.rows + self.n*self.cols, + return_index=True, return_inverse=True) + self.rows = self.rows[unique] + self.cols = self.cols[unique] + self.vals = np.bincount(indices, weights=self.vals) + + def compress_csr(self): + """ + Compress rows, cols, vals / summing duplicates. Sort for csr format. + """ + _, unique, indices = np.unique( + self.m*self.rows + self.cols, + return_index=True, return_inverse=True) + self.rows = self.rows[unique] + self.cols = self.cols[unique] + self.vals = np.bincount(indices, weights=self.vals) + + def to_dense(self): + """ + Return a dense matrix representing self, mainly for debugging purposes. + """ + ret = np.zeros([self.n, self.m], dtype=np.float64) + nvals = self.vals.size + for i in range(nvals): + ret[self.rows[i], self.cols[i]] += self.vals[i] + return ret + + def __str__(self): + return self.to_dense().__str__() + + @property + def diag(self): + """Return the (dense) vector of the diagonal elements.""" + in_diag = (self.rows == self.cols) + diag = np.zeros(min(self.n, self.n), dtype=np.float64) # default 0. + diag[self.rows[in_diag]] = self.vals[in_diag] + return diag + + +def _cg(A, b, x0=None, tol=1.e-10, maxiter=1000): + """ + Use Preconditioned Conjugate Gradient iteration to solve A x = b + A simple Jacobi (diagonal) preconditioner is used. + + Parameters + ---------- + A : _Sparse_Matrix_coo + *A* must have been compressed before by compress_csc or + compress_csr method. + b : array + Right hand side of the linear system. + x0 : array, optional + Starting guess for the solution. Defaults to the zero vector. + tol : float, optional + Tolerance to achieve. The algorithm terminates when the relative + residual is below tol. Default is 1e-10. + maxiter : int, optional + Maximum number of iterations. Iteration will stop after *maxiter* + steps even if the specified tolerance has not been achieved. Defaults + to 1000. + + Returns + ------- + x : array + The converged solution. + err : float + The absolute error np.linalg.norm(A.dot(x) - b) + """ + n = b.size + assert A.n == n + assert A.m == n + b_norm = np.linalg.norm(b) + + # Jacobi pre-conditioner + kvec = A.diag + # For diag elem < 1e-6 we keep 1e-6. + kvec = np.maximum(kvec, 1e-6) + + # Initial guess + if x0 is None: + x = np.zeros(n) + else: + x = x0 + + r = b - A.dot(x) + w = r/kvec + + p = np.zeros(n) + beta = 0.0 + rho = np.dot(r, w) + k = 0 + + # Following C. T. Kelley + while (np.sqrt(abs(rho)) > tol*b_norm) and (k < maxiter): + p = w + beta*p + z = A.dot(p) + alpha = rho/np.dot(p, z) + r = r - alpha*z + w = r/kvec + rhoold = rho + rho = np.dot(r, w) + x = x + alpha*p + beta = rho/rhoold + # err = np.linalg.norm(A.dot(x) - b) # absolute accuracy - not used + k += 1 + err = np.linalg.norm(A.dot(x) - b) + return x, err + + +# The following private functions: +# :func:`_safe_inv22_vectorized` +# :func:`_pseudo_inv22sym_vectorized` +# :func:`_scalar_vectorized` +# :func:`_transpose_vectorized` +# :func:`_roll_vectorized` +# :func:`_to_matrix_vectorized` +# :func:`_extract_submatrices` +# provide fast numpy implementation of some standard operations on arrays of +# matrices - stored as (:, n_rows, n_cols)-shaped np.arrays. + +# Development note: Dealing with pathologic 'flat' triangles in the +# CubicTriInterpolator code and impact on (2, 2)-matrix inversion functions +# :func:`_safe_inv22_vectorized` and :func:`_pseudo_inv22sym_vectorized`. +# +# Goals: +# 1) The CubicTriInterpolator should be able to handle flat or almost flat +# triangles without raising an error, +# 2) These degenerated triangles should have no impact on the automatic dof +# calculation (associated with null weight for the _DOF_estimator_geom and +# with null energy for the _DOF_estimator_min_E), +# 3) Linear patch test should be passed exactly on degenerated meshes, +# 4) Interpolation (with :meth:`_interpolate_single_key` or +# :meth:`_interpolate_multi_key`) shall be correctly handled even *inside* +# the pathologic triangles, to interact correctly with a TriRefiner class. +# +# Difficulties: +# Flat triangles have rank-deficient *J* (so-called jacobian matrix) and +# *metric* (the metric tensor = J x J.T). Computation of the local +# tangent plane is also problematic. +# +# Implementation: +# Most of the time, when computing the inverse of a rank-deficient matrix it +# is safe to simply return the null matrix (which is the implementation in +# :func:`_safe_inv22_vectorized`). This is because of point 2), itself +# enforced by: +# - null area hence null energy in :class:`_DOF_estimator_min_E` +# - angles close or equal to 0 or np.pi hence null weight in +# :class:`_DOF_estimator_geom`. +# Note that the function angle -> weight is continuous and maximum for an +# angle np.pi/2 (refer to :meth:`compute_geom_weights`) +# The exception is the computation of barycentric coordinates, which is done +# by inversion of the *metric* matrix. In this case, we need to compute a set +# of valid coordinates (1 among numerous possibilities), to ensure point 4). +# We benefit here from the symmetry of metric = J x J.T, which makes it easier +# to compute a pseudo-inverse in :func:`_pseudo_inv22sym_vectorized` +def _safe_inv22_vectorized(M): + """ + Inversion of arrays of (2, 2) matrices, returns 0 for rank-deficient + matrices. + + *M* : array of (2, 2) matrices to inverse, shape (n, 2, 2) + """ + _api.check_shape((None, 2, 2), M=M) + M_inv = np.empty_like(M) + prod1 = M[:, 0, 0]*M[:, 1, 1] + delta = prod1 - M[:, 0, 1]*M[:, 1, 0] + + # We set delta_inv to 0. in case of a rank deficient matrix; a + # rank-deficient input matrix *M* will lead to a null matrix in output + rank2 = (np.abs(delta) > 1e-8*np.abs(prod1)) + if np.all(rank2): + # Normal 'optimized' flow. + delta_inv = 1./delta + else: + # 'Pathologic' flow. + delta_inv = np.zeros(M.shape[0]) + delta_inv[rank2] = 1./delta[rank2] + + M_inv[:, 0, 0] = M[:, 1, 1]*delta_inv + M_inv[:, 0, 1] = -M[:, 0, 1]*delta_inv + M_inv[:, 1, 0] = -M[:, 1, 0]*delta_inv + M_inv[:, 1, 1] = M[:, 0, 0]*delta_inv + return M_inv + + +def _pseudo_inv22sym_vectorized(M): + """ + Inversion of arrays of (2, 2) SYMMETRIC matrices; returns the + (Moore-Penrose) pseudo-inverse for rank-deficient matrices. + + In case M is of rank 1, we have M = trace(M) x P where P is the orthogonal + projection on Im(M), and we return trace(M)^-1 x P == M / trace(M)**2 + In case M is of rank 0, we return the null matrix. + + *M* : array of (2, 2) matrices to inverse, shape (n, 2, 2) + """ + _api.check_shape((None, 2, 2), M=M) + M_inv = np.empty_like(M) + prod1 = M[:, 0, 0]*M[:, 1, 1] + delta = prod1 - M[:, 0, 1]*M[:, 1, 0] + rank2 = (np.abs(delta) > 1e-8*np.abs(prod1)) + + if np.all(rank2): + # Normal 'optimized' flow. + M_inv[:, 0, 0] = M[:, 1, 1] / delta + M_inv[:, 0, 1] = -M[:, 0, 1] / delta + M_inv[:, 1, 0] = -M[:, 1, 0] / delta + M_inv[:, 1, 1] = M[:, 0, 0] / delta + else: + # 'Pathologic' flow. + # Here we have to deal with 2 sub-cases + # 1) First sub-case: matrices of rank 2: + delta = delta[rank2] + M_inv[rank2, 0, 0] = M[rank2, 1, 1] / delta + M_inv[rank2, 0, 1] = -M[rank2, 0, 1] / delta + M_inv[rank2, 1, 0] = -M[rank2, 1, 0] / delta + M_inv[rank2, 1, 1] = M[rank2, 0, 0] / delta + # 2) Second sub-case: rank-deficient matrices of rank 0 and 1: + rank01 = ~rank2 + tr = M[rank01, 0, 0] + M[rank01, 1, 1] + tr_zeros = (np.abs(tr) < 1.e-8) + sq_tr_inv = (1.-tr_zeros) / (tr**2+tr_zeros) + # sq_tr_inv = 1. / tr**2 + M_inv[rank01, 0, 0] = M[rank01, 0, 0] * sq_tr_inv + M_inv[rank01, 0, 1] = M[rank01, 0, 1] * sq_tr_inv + M_inv[rank01, 1, 0] = M[rank01, 1, 0] * sq_tr_inv + M_inv[rank01, 1, 1] = M[rank01, 1, 1] * sq_tr_inv + + return M_inv + + +def _scalar_vectorized(scalar, M): + """ + Scalar product between scalars and matrices. + """ + return scalar[:, np.newaxis, np.newaxis]*M + + +def _transpose_vectorized(M): + """ + Transposition of an array of matrices *M*. + """ + return np.transpose(M, [0, 2, 1]) + + +def _roll_vectorized(M, roll_indices, axis): + """ + Roll an array of matrices along *axis* (0: rows, 1: columns) according to + an array of indices *roll_indices*. + """ + assert axis in [0, 1] + ndim = M.ndim + assert ndim == 3 + ndim_roll = roll_indices.ndim + assert ndim_roll == 1 + sh = M.shape + r, c = sh[-2:] + assert sh[0] == roll_indices.shape[0] + vec_indices = np.arange(sh[0], dtype=np.int32) + + # Builds the rolled matrix + M_roll = np.empty_like(M) + if axis == 0: + for ir in range(r): + for ic in range(c): + M_roll[:, ir, ic] = M[vec_indices, (-roll_indices+ir) % r, ic] + else: # 1 + for ir in range(r): + for ic in range(c): + M_roll[:, ir, ic] = M[vec_indices, ir, (-roll_indices+ic) % c] + return M_roll + + +def _to_matrix_vectorized(M): + """ + Build an array of matrices from individuals np.arrays of identical shapes. + + Parameters + ---------- + M + ncols-list of nrows-lists of shape sh. + + Returns + ------- + M_res : np.array of shape (sh, nrow, ncols) + *M_res* satisfies ``M_res[..., i, j] = M[i][j]``. + """ + assert isinstance(M, (tuple, list)) + assert all(isinstance(item, (tuple, list)) for item in M) + c_vec = np.asarray([len(item) for item in M]) + assert np.all(c_vec-c_vec[0] == 0) + r = len(M) + c = c_vec[0] + M00 = np.asarray(M[0][0]) + dt = M00.dtype + sh = [M00.shape[0], r, c] + M_ret = np.empty(sh, dtype=dt) + for irow in range(r): + for icol in range(c): + M_ret[:, irow, icol] = np.asarray(M[irow][icol]) + return M_ret + + +def _extract_submatrices(M, block_indices, block_size, axis): + """ + Extract selected blocks of a matrices *M* depending on parameters + *block_indices* and *block_size*. + + Returns the array of extracted matrices *Mres* so that :: + + M_res[..., ir, :] = M[(block_indices*block_size+ir), :] + """ + assert block_indices.ndim == 1 + assert axis in [0, 1] + + r, c = M.shape + if axis == 0: + sh = [block_indices.shape[0], block_size, c] + else: # 1 + sh = [block_indices.shape[0], r, block_size] + + dt = M.dtype + M_res = np.empty(sh, dtype=dt) + if axis == 0: + for ir in range(block_size): + M_res[:, ir, :] = M[(block_indices*block_size+ir), :] + else: # 1 + for ic in range(block_size): + M_res[:, :, ic] = M[:, (block_indices*block_size+ic)] + + return M_res diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.pyi new file mode 100644 index 00000000..8a56b22a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triinterpolate.pyi @@ -0,0 +1,30 @@ +from matplotlib.tri import Triangulation, TriFinder + +from typing import Literal +import numpy as np +from numpy.typing import ArrayLike + +class TriInterpolator: + def __init__( + self, + triangulation: Triangulation, + z: ArrayLike, + trifinder: TriFinder | None = ..., + ) -> None: ... + # __call__ and gradient are not actually implemented by the ABC, but are specified as required + def __call__(self, x: ArrayLike, y: ArrayLike) -> np.ma.MaskedArray: ... + def gradient( + self, x: ArrayLike, y: ArrayLike + ) -> tuple[np.ma.MaskedArray, np.ma.MaskedArray]: ... + +class LinearTriInterpolator(TriInterpolator): ... + +class CubicTriInterpolator(TriInterpolator): + def __init__( + self, + triangulation: Triangulation, + z: ArrayLike, + kind: Literal["min_E", "geom", "user"] = ..., + trifinder: TriFinder | None = ..., + dz: tuple[ArrayLike, ArrayLike] | None = ..., + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.py new file mode 100644 index 00000000..1ac6c48a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.py @@ -0,0 +1,149 @@ +import numpy as np + +from matplotlib import _api +from matplotlib.collections import PolyCollection, TriMesh +from matplotlib.tri._triangulation import Triangulation + + +def tripcolor(ax, *args, alpha=1.0, norm=None, cmap=None, vmin=None, + vmax=None, shading='flat', facecolors=None, **kwargs): + """ + Create a pseudocolor plot of an unstructured triangular grid. + + Call signatures:: + + tripcolor(triangulation, c, *, ...) + tripcolor(x, y, c, *, [triangles=triangles], [mask=mask], ...) + + The triangular grid can be specified either by passing a `.Triangulation` + object as the first parameter, or by passing the points *x*, *y* and + optionally the *triangles* and a *mask*. See `.Triangulation` for an + explanation of these parameters. + + It is possible to pass the triangles positionally, i.e. + ``tripcolor(x, y, triangles, c, ...)``. However, this is discouraged. + For more clarity, pass *triangles* via keyword argument. + + If neither of *triangulation* or *triangles* are given, the triangulation + is calculated on the fly. In this case, it does not make sense to provide + colors at the triangle faces via *c* or *facecolors* because there are + multiple possible triangulations for a group of points and you don't know + which triangles will be constructed. + + Parameters + ---------- + triangulation : `.Triangulation` + An already created triangular grid. + x, y, triangles, mask + Parameters defining the triangular grid. See `.Triangulation`. + This is mutually exclusive with specifying *triangulation*. + c : array-like + The color values, either for the points or for the triangles. Which one + is automatically inferred from the length of *c*, i.e. does it match + the number of points or the number of triangles. If there are the same + number of points and triangles in the triangulation it is assumed that + color values are defined at points; to force the use of color values at + triangles use the keyword argument ``facecolors=c`` instead of just + ``c``. + This parameter is position-only. + facecolors : array-like, optional + Can be used alternatively to *c* to specify colors at the triangle + faces. This parameter takes precedence over *c*. + shading : {'flat', 'gouraud'}, default: 'flat' + If 'flat' and the color values *c* are defined at points, the color + values used for each triangle are from the mean c of the triangle's + three points. If *shading* is 'gouraud' then color values must be + defined at points. + other_parameters + All other parameters are the same as for `~.Axes.pcolor`. + """ + _api.check_in_list(['flat', 'gouraud'], shading=shading) + + tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs) + + # Parse the color to be in one of (the other variable will be None): + # - facecolors: if specified at the triangle faces + # - point_colors: if specified at the points + if facecolors is not None: + if args: + _api.warn_external( + "Positional parameter c has no effect when the keyword " + "facecolors is given") + point_colors = None + if len(facecolors) != len(tri.triangles): + raise ValueError("The length of facecolors must match the number " + "of triangles") + else: + # Color from positional parameter c + if not args: + raise TypeError( + "tripcolor() missing 1 required positional argument: 'c'; or " + "1 required keyword-only argument: 'facecolors'") + elif len(args) > 1: + raise TypeError(f"Unexpected positional parameters: {args[1:]!r}") + c = np.asarray(args[0]) + if len(c) == len(tri.x): + # having this before the len(tri.triangles) comparison gives + # precedence to nodes if there are as many nodes as triangles + point_colors = c + facecolors = None + elif len(c) == len(tri.triangles): + point_colors = None + facecolors = c + else: + raise ValueError('The length of c must match either the number ' + 'of points or the number of triangles') + + # Handling of linewidths, shading, edgecolors and antialiased as + # in Axes.pcolor + linewidths = (0.25,) + if 'linewidth' in kwargs: + kwargs['linewidths'] = kwargs.pop('linewidth') + kwargs.setdefault('linewidths', linewidths) + + edgecolors = 'none' + if 'edgecolor' in kwargs: + kwargs['edgecolors'] = kwargs.pop('edgecolor') + ec = kwargs.setdefault('edgecolors', edgecolors) + + if 'antialiased' in kwargs: + kwargs['antialiaseds'] = kwargs.pop('antialiased') + if 'antialiaseds' not in kwargs and ec.lower() == "none": + kwargs['antialiaseds'] = False + + if shading == 'gouraud': + if facecolors is not None: + raise ValueError( + "shading='gouraud' can only be used when the colors " + "are specified at the points, not at the faces.") + collection = TriMesh(tri, alpha=alpha, array=point_colors, + cmap=cmap, norm=norm, **kwargs) + else: # 'flat' + # Vertices of triangles. + maskedTris = tri.get_masked_triangles() + verts = np.stack((tri.x[maskedTris], tri.y[maskedTris]), axis=-1) + + # Color values. + if facecolors is None: + # One color per triangle, the mean of the 3 vertex color values. + colors = point_colors[maskedTris].mean(axis=1) + elif tri.mask is not None: + # Remove color values of masked triangles. + colors = facecolors[~tri.mask] + else: + colors = facecolors + collection = PolyCollection(verts, alpha=alpha, array=colors, + cmap=cmap, norm=norm, **kwargs) + + collection._scale_norm(norm, vmin, vmax) + ax.grid(False) + + minx = tri.x.min() + maxx = tri.x.max() + miny = tri.y.min() + maxy = tri.y.max() + corners = (minx, miny), (maxx, maxy) + ax.update_datalim(corners) + ax.autoscale_view() + ax.add_collection(collection) + return collection diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.pyi new file mode 100644 index 00000000..42acffcd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tripcolor.pyi @@ -0,0 +1,71 @@ +from matplotlib.axes import Axes +from matplotlib.collections import PolyCollection, TriMesh +from matplotlib.colors import Normalize, Colormap +from matplotlib.tri._triangulation import Triangulation + +from numpy.typing import ArrayLike + +from typing import overload, Literal + +@overload +def tripcolor( + ax: Axes, + triangulation: Triangulation, + c: ArrayLike = ..., + *, + alpha: float = ..., + norm: str | Normalize | None = ..., + cmap: str | Colormap | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + shading: Literal["flat"] = ..., + facecolors: ArrayLike | None = ..., + **kwargs +) -> PolyCollection: ... +@overload +def tripcolor( + ax: Axes, + x: ArrayLike, + y: ArrayLike, + c: ArrayLike = ..., + *, + alpha: float = ..., + norm: str | Normalize | None = ..., + cmap: str | Colormap | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + shading: Literal["flat"] = ..., + facecolors: ArrayLike | None = ..., + **kwargs +) -> PolyCollection: ... +@overload +def tripcolor( + ax: Axes, + triangulation: Triangulation, + c: ArrayLike = ..., + *, + alpha: float = ..., + norm: str | Normalize | None = ..., + cmap: str | Colormap | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + shading: Literal["gouraud"], + facecolors: ArrayLike | None = ..., + **kwargs +) -> TriMesh: ... +@overload +def tripcolor( + ax: Axes, + x: ArrayLike, + y: ArrayLike, + c: ArrayLike = ..., + *, + alpha: float = ..., + norm: str | Normalize | None = ..., + cmap: str | Colormap | None = ..., + vmin: float | None = ..., + vmax: float | None = ..., + shading: Literal["gouraud"], + facecolors: ArrayLike | None = ..., + **kwargs +) -> TriMesh: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.py new file mode 100644 index 00000000..6168946b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.py @@ -0,0 +1,86 @@ +import numpy as np +from matplotlib.tri._triangulation import Triangulation +import matplotlib.cbook as cbook +import matplotlib.lines as mlines + + +def triplot(ax, *args, **kwargs): + """ + Draw an unstructured triangular grid as lines and/or markers. + + Call signatures:: + + triplot(triangulation, ...) + triplot(x, y, [triangles], *, [mask=mask], ...) + + The triangular grid can be specified either by passing a `.Triangulation` + object as the first parameter, or by passing the points *x*, *y* and + optionally the *triangles* and a *mask*. If neither of *triangulation* or + *triangles* are given, the triangulation is calculated on the fly. + + Parameters + ---------- + triangulation : `.Triangulation` + An already created triangular grid. + x, y, triangles, mask + Parameters defining the triangular grid. See `.Triangulation`. + This is mutually exclusive with specifying *triangulation*. + other_parameters + All other args and kwargs are forwarded to `~.Axes.plot`. + + Returns + ------- + lines : `~matplotlib.lines.Line2D` + The drawn triangles edges. + markers : `~matplotlib.lines.Line2D` + The drawn marker nodes. + """ + import matplotlib.axes + + tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs) + x, y, edges = (tri.x, tri.y, tri.edges) + + # Decode plot format string, e.g., 'ro-' + fmt = args[0] if args else "" + linestyle, marker, color = matplotlib.axes._base._process_plot_format(fmt) + + # Insert plot format string into a copy of kwargs (kwargs values prevail). + kw = cbook.normalize_kwargs(kwargs, mlines.Line2D) + for key, val in zip(('linestyle', 'marker', 'color'), + (linestyle, marker, color)): + if val is not None: + kw.setdefault(key, val) + + # Draw lines without markers. + # Note 1: If we drew markers here, most markers would be drawn more than + # once as they belong to several edges. + # Note 2: We insert nan values in the flattened edges arrays rather than + # plotting directly (triang.x[edges].T, triang.y[edges].T) + # as it considerably speeds-up code execution. + linestyle = kw['linestyle'] + kw_lines = { + **kw, + 'marker': 'None', # No marker to draw. + 'zorder': kw.get('zorder', 1), # Path default zorder is used. + } + if linestyle not in [None, 'None', '', ' ']: + tri_lines_x = np.insert(x[edges], 2, np.nan, axis=1) + tri_lines_y = np.insert(y[edges], 2, np.nan, axis=1) + tri_lines = ax.plot(tri_lines_x.ravel(), tri_lines_y.ravel(), + **kw_lines) + else: + tri_lines = ax.plot([], [], **kw_lines) + + # Draw markers separately. + marker = kw['marker'] + kw_markers = { + **kw, + 'linestyle': 'None', # No line to draw. + } + kw_markers.pop('label', None) + if marker not in [None, 'None', '', ' ']: + tri_markers = ax.plot(x, y, **kw_markers) + else: + tri_markers = ax.plot([], [], **kw_markers) + + return tri_lines + tri_markers diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.pyi new file mode 100644 index 00000000..6224276a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_triplot.pyi @@ -0,0 +1,15 @@ +from matplotlib.tri._triangulation import Triangulation +from matplotlib.axes import Axes +from matplotlib.lines import Line2D + +from typing import overload +from numpy.typing import ArrayLike + +@overload +def triplot( + ax: Axes, triangulation: Triangulation, *args, **kwargs +) -> tuple[Line2D, Line2D]: ... +@overload +def triplot( + ax: Axes, x: ArrayLike, y: ArrayLike, triangles: ArrayLike = ..., *args, **kwargs +) -> tuple[Line2D, Line2D]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.py new file mode 100644 index 00000000..7f5110ab --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.py @@ -0,0 +1,307 @@ +""" +Mesh refinement for triangular grids. +""" + +import numpy as np + +from matplotlib import _api +from matplotlib.tri._triangulation import Triangulation +import matplotlib.tri._triinterpolate + + +class TriRefiner: + """ + Abstract base class for classes implementing mesh refinement. + + A TriRefiner encapsulates a Triangulation object and provides tools for + mesh refinement and interpolation. + + Derived classes must implement: + + - ``refine_triangulation(return_tri_index=False, **kwargs)`` , where + the optional keyword arguments *kwargs* are defined in each + TriRefiner concrete implementation, and which returns: + + - a refined triangulation, + - optionally (depending on *return_tri_index*), for each + point of the refined triangulation: the index of + the initial triangulation triangle to which it belongs. + + - ``refine_field(z, triinterpolator=None, **kwargs)``, where: + + - *z* array of field values (to refine) defined at the base + triangulation nodes, + - *triinterpolator* is an optional `~matplotlib.tri.TriInterpolator`, + - the other optional keyword arguments *kwargs* are defined in + each TriRefiner concrete implementation; + + and which returns (as a tuple) a refined triangular mesh and the + interpolated values of the field at the refined triangulation nodes. + """ + + def __init__(self, triangulation): + _api.check_isinstance(Triangulation, triangulation=triangulation) + self._triangulation = triangulation + + +class UniformTriRefiner(TriRefiner): + """ + Uniform mesh refinement by recursive subdivisions. + + Parameters + ---------- + triangulation : `~matplotlib.tri.Triangulation` + The encapsulated triangulation (to be refined) + """ +# See Also +# -------- +# :class:`~matplotlib.tri.CubicTriInterpolator` and +# :class:`~matplotlib.tri.TriAnalyzer`. +# """ + def __init__(self, triangulation): + super().__init__(triangulation) + + def refine_triangulation(self, return_tri_index=False, subdiv=3): + """ + Compute a uniformly refined triangulation *refi_triangulation* of + the encapsulated :attr:`triangulation`. + + This function refines the encapsulated triangulation by splitting each + father triangle into 4 child sub-triangles built on the edges midside + nodes, recursing *subdiv* times. In the end, each triangle is hence + divided into ``4**subdiv`` child triangles. + + Parameters + ---------- + return_tri_index : bool, default: False + Whether an index table indicating the father triangle index of each + point is returned. + subdiv : int, default: 3 + Recursion level for the subdivision. + Each triangle is divided into ``4**subdiv`` child triangles; + hence, the default results in 64 refined subtriangles for each + triangle of the initial triangulation. + + Returns + ------- + refi_triangulation : `~matplotlib.tri.Triangulation` + The refined triangulation. + found_index : int array + Index of the initial triangulation containing triangle, for each + point of *refi_triangulation*. + Returned only if *return_tri_index* is set to True. + """ + refi_triangulation = self._triangulation + ntri = refi_triangulation.triangles.shape[0] + + # Computes the triangulation ancestors numbers in the reference + # triangulation. + ancestors = np.arange(ntri, dtype=np.int32) + for _ in range(subdiv): + refi_triangulation, ancestors = self._refine_triangulation_once( + refi_triangulation, ancestors) + refi_npts = refi_triangulation.x.shape[0] + refi_triangles = refi_triangulation.triangles + + # Now we compute found_index table if needed + if return_tri_index: + # We have to initialize found_index with -1 because some nodes + # may very well belong to no triangle at all, e.g., in case of + # Delaunay Triangulation with DuplicatePointWarning. + found_index = np.full(refi_npts, -1, dtype=np.int32) + tri_mask = self._triangulation.mask + if tri_mask is None: + found_index[refi_triangles] = np.repeat(ancestors, + 3).reshape(-1, 3) + else: + # There is a subtlety here: we want to avoid whenever possible + # that refined points container is a masked triangle (which + # would result in artifacts in plots). + # So we impose the numbering from masked ancestors first, + # then overwrite it with unmasked ancestor numbers. + ancestor_mask = tri_mask[ancestors] + found_index[refi_triangles[ancestor_mask, :] + ] = np.repeat(ancestors[ancestor_mask], + 3).reshape(-1, 3) + found_index[refi_triangles[~ancestor_mask, :] + ] = np.repeat(ancestors[~ancestor_mask], + 3).reshape(-1, 3) + return refi_triangulation, found_index + else: + return refi_triangulation + + def refine_field(self, z, triinterpolator=None, subdiv=3): + """ + Refine a field defined on the encapsulated triangulation. + + Parameters + ---------- + z : (npoints,) array-like + Values of the field to refine, defined at the nodes of the + encapsulated triangulation. (``n_points`` is the number of points + in the initial triangulation) + triinterpolator : `~matplotlib.tri.TriInterpolator`, optional + Interpolator used for field interpolation. If not specified, + a `~matplotlib.tri.CubicTriInterpolator` will be used. + subdiv : int, default: 3 + Recursion level for the subdivision. + Each triangle is divided into ``4**subdiv`` child triangles. + + Returns + ------- + refi_tri : `~matplotlib.tri.Triangulation` + The returned refined triangulation. + refi_z : 1D array of length: *refi_tri* node count. + The returned interpolated field (at *refi_tri* nodes). + """ + if triinterpolator is None: + interp = matplotlib.tri.CubicTriInterpolator( + self._triangulation, z) + else: + _api.check_isinstance(matplotlib.tri.TriInterpolator, + triinterpolator=triinterpolator) + interp = triinterpolator + + refi_tri, found_index = self.refine_triangulation( + subdiv=subdiv, return_tri_index=True) + refi_z = interp._interpolate_multikeys( + refi_tri.x, refi_tri.y, tri_index=found_index)[0] + return refi_tri, refi_z + + @staticmethod + def _refine_triangulation_once(triangulation, ancestors=None): + """ + Refine a `.Triangulation` by splitting each triangle into 4 + child-masked_triangles built on the edges midside nodes. + + Masked triangles, if present, are also split, but their children + returned masked. + + If *ancestors* is not provided, returns only a new triangulation: + child_triangulation. + + If the array-like key table *ancestor* is given, it shall be of shape + (ntri,) where ntri is the number of *triangulation* masked_triangles. + In this case, the function returns + (child_triangulation, child_ancestors) + child_ancestors is defined so that the 4 child masked_triangles share + the same index as their father: child_ancestors.shape = (4 * ntri,). + """ + + x = triangulation.x + y = triangulation.y + + # According to tri.triangulation doc: + # neighbors[i, j] is the triangle that is the neighbor + # to the edge from point index masked_triangles[i, j] to point + # index masked_triangles[i, (j+1)%3]. + neighbors = triangulation.neighbors + triangles = triangulation.triangles + npts = np.shape(x)[0] + ntri = np.shape(triangles)[0] + if ancestors is not None: + ancestors = np.asarray(ancestors) + if np.shape(ancestors) != (ntri,): + raise ValueError( + "Incompatible shapes provide for " + "triangulation.masked_triangles and ancestors: " + f"{np.shape(triangles)} and {np.shape(ancestors)}") + + # Initiating tables refi_x and refi_y of the refined triangulation + # points + # hint: each apex is shared by 2 masked_triangles except the borders. + borders = np.sum(neighbors == -1) + added_pts = (3*ntri + borders) // 2 + refi_npts = npts + added_pts + refi_x = np.zeros(refi_npts) + refi_y = np.zeros(refi_npts) + + # First part of refi_x, refi_y is just the initial points + refi_x[:npts] = x + refi_y[:npts] = y + + # Second part contains the edge midside nodes. + # Each edge belongs to 1 triangle (if border edge) or is shared by 2 + # masked_triangles (interior edge). + # We first build 2 * ntri arrays of edge starting nodes (edge_elems, + # edge_apexes); we then extract only the masters to avoid overlaps. + # The so-called 'master' is the triangle with biggest index + # The 'slave' is the triangle with lower index + # (can be -1 if border edge) + # For slave and master we will identify the apex pointing to the edge + # start + edge_elems = np.tile(np.arange(ntri, dtype=np.int32), 3) + edge_apexes = np.repeat(np.arange(3, dtype=np.int32), ntri) + edge_neighbors = neighbors[edge_elems, edge_apexes] + mask_masters = (edge_elems > edge_neighbors) + + # Identifying the "masters" and adding to refi_x, refi_y vec + masters = edge_elems[mask_masters] + apex_masters = edge_apexes[mask_masters] + x_add = (x[triangles[masters, apex_masters]] + + x[triangles[masters, (apex_masters+1) % 3]]) * 0.5 + y_add = (y[triangles[masters, apex_masters]] + + y[triangles[masters, (apex_masters+1) % 3]]) * 0.5 + refi_x[npts:] = x_add + refi_y[npts:] = y_add + + # Building the new masked_triangles; each old masked_triangles hosts + # 4 new masked_triangles + # there are 6 pts to identify per 'old' triangle, 3 new_pt_corner and + # 3 new_pt_midside + new_pt_corner = triangles + + # What is the index in refi_x, refi_y of point at middle of apex iapex + # of elem ielem ? + # If ielem is the apex master: simple count, given the way refi_x was + # built. + # If ielem is the apex slave: yet we do not know; but we will soon + # using the neighbors table. + new_pt_midside = np.empty([ntri, 3], dtype=np.int32) + cum_sum = npts + for imid in range(3): + mask_st_loc = (imid == apex_masters) + n_masters_loc = np.sum(mask_st_loc) + elem_masters_loc = masters[mask_st_loc] + new_pt_midside[:, imid][elem_masters_loc] = np.arange( + n_masters_loc, dtype=np.int32) + cum_sum + cum_sum += n_masters_loc + + # Now dealing with slave elems. + # for each slave element we identify the master and then the inode + # once slave_masters is identified, slave_masters_apex is such that: + # neighbors[slaves_masters, slave_masters_apex] == slaves + mask_slaves = np.logical_not(mask_masters) + slaves = edge_elems[mask_slaves] + slaves_masters = edge_neighbors[mask_slaves] + diff_table = np.abs(neighbors[slaves_masters, :] - + np.outer(slaves, np.ones(3, dtype=np.int32))) + slave_masters_apex = np.argmin(diff_table, axis=1) + slaves_apex = edge_apexes[mask_slaves] + new_pt_midside[slaves, slaves_apex] = new_pt_midside[ + slaves_masters, slave_masters_apex] + + # Builds the 4 child masked_triangles + child_triangles = np.empty([ntri*4, 3], dtype=np.int32) + child_triangles[0::4, :] = np.vstack([ + new_pt_corner[:, 0], new_pt_midside[:, 0], + new_pt_midside[:, 2]]).T + child_triangles[1::4, :] = np.vstack([ + new_pt_corner[:, 1], new_pt_midside[:, 1], + new_pt_midside[:, 0]]).T + child_triangles[2::4, :] = np.vstack([ + new_pt_corner[:, 2], new_pt_midside[:, 2], + new_pt_midside[:, 1]]).T + child_triangles[3::4, :] = np.vstack([ + new_pt_midside[:, 0], new_pt_midside[:, 1], + new_pt_midside[:, 2]]).T + child_triangulation = Triangulation(refi_x, refi_y, child_triangles) + + # Builds the child mask + if triangulation.mask is not None: + child_triangulation.set_mask(np.repeat(triangulation.mask, 4)) + + if ancestors is None: + return child_triangulation + else: + return child_triangulation, np.repeat(ancestors, 4) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.pyi new file mode 100644 index 00000000..7c60dc76 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_trirefine.pyi @@ -0,0 +1,31 @@ +from typing import Literal, overload + +import numpy as np +from numpy.typing import ArrayLike + +from matplotlib.tri._triangulation import Triangulation +from matplotlib.tri._triinterpolate import TriInterpolator + +class TriRefiner: + def __init__(self, triangulation: Triangulation) -> None: ... + +class UniformTriRefiner(TriRefiner): + def __init__(self, triangulation: Triangulation) -> None: ... + @overload + def refine_triangulation( + self, *, return_tri_index: Literal[True], subdiv: int = ... + ) -> tuple[Triangulation, np.ndarray]: ... + @overload + def refine_triangulation( + self, return_tri_index: Literal[False] = ..., subdiv: int = ... + ) -> Triangulation: ... + @overload + def refine_triangulation( + self, return_tri_index: bool = ..., subdiv: int = ... + ) -> tuple[Triangulation, np.ndarray] | Triangulation: ... + def refine_field( + self, + z: ArrayLike, + triinterpolator: TriInterpolator | None = ..., + subdiv: int = ..., + ) -> tuple[Triangulation, np.ndarray]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.py new file mode 100644 index 00000000..9837309f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.py @@ -0,0 +1,263 @@ +""" +Tools for triangular grids. +""" + +import numpy as np + +from matplotlib import _api +from matplotlib.tri import Triangulation + + +class TriAnalyzer: + """ + Define basic tools for triangular mesh analysis and improvement. + + A TriAnalyzer encapsulates a `.Triangulation` object and provides basic + tools for mesh analysis and mesh improvement. + + Attributes + ---------- + scale_factors + + Parameters + ---------- + triangulation : `~matplotlib.tri.Triangulation` + The encapsulated triangulation to analyze. + """ + + def __init__(self, triangulation): + _api.check_isinstance(Triangulation, triangulation=triangulation) + self._triangulation = triangulation + + @property + def scale_factors(self): + """ + Factors to rescale the triangulation into a unit square. + + Returns + ------- + (float, float) + Scaling factors (kx, ky) so that the triangulation + ``[triangulation.x * kx, triangulation.y * ky]`` + fits exactly inside a unit square. + """ + compressed_triangles = self._triangulation.get_masked_triangles() + node_used = (np.bincount(np.ravel(compressed_triangles), + minlength=self._triangulation.x.size) != 0) + return (1 / np.ptp(self._triangulation.x[node_used]), + 1 / np.ptp(self._triangulation.y[node_used])) + + def circle_ratios(self, rescale=True): + """ + Return a measure of the triangulation triangles flatness. + + The ratio of the incircle radius over the circumcircle radius is a + widely used indicator of a triangle flatness. + It is always ``<= 0.5`` and ``== 0.5`` only for equilateral + triangles. Circle ratios below 0.01 denote very flat triangles. + + To avoid unduly low values due to a difference of scale between the 2 + axis, the triangular mesh can first be rescaled to fit inside a unit + square with `scale_factors` (Only if *rescale* is True, which is + its default value). + + Parameters + ---------- + rescale : bool, default: True + If True, internally rescale (based on `scale_factors`), so that the + (unmasked) triangles fit exactly inside a unit square mesh. + + Returns + ------- + masked array + Ratio of the incircle radius over the circumcircle radius, for + each 'rescaled' triangle of the encapsulated triangulation. + Values corresponding to masked triangles are masked out. + + """ + # Coords rescaling + if rescale: + (kx, ky) = self.scale_factors + else: + (kx, ky) = (1.0, 1.0) + pts = np.vstack([self._triangulation.x*kx, + self._triangulation.y*ky]).T + tri_pts = pts[self._triangulation.triangles] + # Computes the 3 side lengths + a = tri_pts[:, 1, :] - tri_pts[:, 0, :] + b = tri_pts[:, 2, :] - tri_pts[:, 1, :] + c = tri_pts[:, 0, :] - tri_pts[:, 2, :] + a = np.hypot(a[:, 0], a[:, 1]) + b = np.hypot(b[:, 0], b[:, 1]) + c = np.hypot(c[:, 0], c[:, 1]) + # circumcircle and incircle radii + s = (a+b+c)*0.5 + prod = s*(a+b-s)*(a+c-s)*(b+c-s) + # We have to deal with flat triangles with infinite circum_radius + bool_flat = (prod == 0.) + if np.any(bool_flat): + # Pathologic flow + ntri = tri_pts.shape[0] + circum_radius = np.empty(ntri, dtype=np.float64) + circum_radius[bool_flat] = np.inf + abc = a*b*c + circum_radius[~bool_flat] = abc[~bool_flat] / ( + 4.0*np.sqrt(prod[~bool_flat])) + else: + # Normal optimized flow + circum_radius = (a*b*c) / (4.0*np.sqrt(prod)) + in_radius = (a*b*c) / (4.0*circum_radius*s) + circle_ratio = in_radius/circum_radius + mask = self._triangulation.mask + if mask is None: + return circle_ratio + else: + return np.ma.array(circle_ratio, mask=mask) + + def get_flat_tri_mask(self, min_circle_ratio=0.01, rescale=True): + """ + Eliminate excessively flat border triangles from the triangulation. + + Returns a mask *new_mask* which allows to clean the encapsulated + triangulation from its border-located flat triangles + (according to their :meth:`circle_ratios`). + This mask is meant to be subsequently applied to the triangulation + using `.Triangulation.set_mask`. + *new_mask* is an extension of the initial triangulation mask + in the sense that an initially masked triangle will remain masked. + + The *new_mask* array is computed recursively; at each step flat + triangles are removed only if they share a side with the current mesh + border. Thus, no new holes in the triangulated domain will be created. + + Parameters + ---------- + min_circle_ratio : float, default: 0.01 + Border triangles with incircle/circumcircle radii ratio r/R will + be removed if r/R < *min_circle_ratio*. + rescale : bool, default: True + If True, first, internally rescale (based on `scale_factors`) so + that the (unmasked) triangles fit exactly inside a unit square + mesh. This rescaling accounts for the difference of scale which + might exist between the 2 axis. + + Returns + ------- + array of bool + Mask to apply to encapsulated triangulation. + All the initially masked triangles remain masked in the + *new_mask*. + + Notes + ----- + The rationale behind this function is that a Delaunay + triangulation - of an unstructured set of points - sometimes contains + almost flat triangles at its border, leading to artifacts in plots + (especially for high-resolution contouring). + Masked with computed *new_mask*, the encapsulated + triangulation would contain no more unmasked border triangles + with a circle ratio below *min_circle_ratio*, thus improving the + mesh quality for subsequent plots or interpolation. + """ + # Recursively computes the mask_current_borders, true if a triangle is + # at the border of the mesh OR touching the border through a chain of + # invalid aspect ratio masked_triangles. + ntri = self._triangulation.triangles.shape[0] + mask_bad_ratio = self.circle_ratios(rescale) < min_circle_ratio + + current_mask = self._triangulation.mask + if current_mask is None: + current_mask = np.zeros(ntri, dtype=bool) + valid_neighbors = np.copy(self._triangulation.neighbors) + renum_neighbors = np.arange(ntri, dtype=np.int32) + nadd = -1 + while nadd != 0: + # The active wavefront is the triangles from the border (unmasked + # but with a least 1 neighbor equal to -1 + wavefront = (np.min(valid_neighbors, axis=1) == -1) & ~current_mask + # The element from the active wavefront will be masked if their + # circle ratio is bad. + added_mask = wavefront & mask_bad_ratio + current_mask = added_mask | current_mask + nadd = np.sum(added_mask) + + # now we have to update the tables valid_neighbors + valid_neighbors[added_mask, :] = -1 + renum_neighbors[added_mask] = -1 + valid_neighbors = np.where(valid_neighbors == -1, -1, + renum_neighbors[valid_neighbors]) + + return np.ma.filled(current_mask, True) + + def _get_compressed_triangulation(self): + """ + Compress (if masked) the encapsulated triangulation. + + Returns minimal-length triangles array (*compressed_triangles*) and + coordinates arrays (*compressed_x*, *compressed_y*) that can still + describe the unmasked triangles of the encapsulated triangulation. + + Returns + ------- + compressed_triangles : array-like + the returned compressed triangulation triangles + compressed_x : array-like + the returned compressed triangulation 1st coordinate + compressed_y : array-like + the returned compressed triangulation 2nd coordinate + tri_renum : int array + renumbering table to translate the triangle numbers from the + encapsulated triangulation into the new (compressed) renumbering. + -1 for masked triangles (deleted from *compressed_triangles*). + node_renum : int array + renumbering table to translate the point numbers from the + encapsulated triangulation into the new (compressed) renumbering. + -1 for unused points (i.e. those deleted from *compressed_x* and + *compressed_y*). + + """ + # Valid triangles and renumbering + tri_mask = self._triangulation.mask + compressed_triangles = self._triangulation.get_masked_triangles() + ntri = self._triangulation.triangles.shape[0] + if tri_mask is not None: + tri_renum = self._total_to_compress_renum(~tri_mask) + else: + tri_renum = np.arange(ntri, dtype=np.int32) + + # Valid nodes and renumbering + valid_node = (np.bincount(np.ravel(compressed_triangles), + minlength=self._triangulation.x.size) != 0) + compressed_x = self._triangulation.x[valid_node] + compressed_y = self._triangulation.y[valid_node] + node_renum = self._total_to_compress_renum(valid_node) + + # Now renumbering the valid triangles nodes + compressed_triangles = node_renum[compressed_triangles] + + return (compressed_triangles, compressed_x, compressed_y, tri_renum, + node_renum) + + @staticmethod + def _total_to_compress_renum(valid): + """ + Parameters + ---------- + valid : 1D bool array + Validity mask. + + Returns + ------- + int array + Array so that (`valid_array` being a compressed array + based on a `masked_array` with mask ~*valid*): + + - For all i with valid[i] = True: + valid_array[renum[i]] = masked_array[i] + - For all i with valid[i] = False: + renum[i] = -1 (invalid value) + """ + renum = np.full(np.size(valid), -1, dtype=np.int32) + n_valid = np.sum(valid) + renum[valid] = np.arange(n_valid, dtype=np.int32) + return renum diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.pyi new file mode 100644 index 00000000..9b5e1bec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/_tritools.pyi @@ -0,0 +1,12 @@ +from matplotlib.tri import Triangulation + +import numpy as np + +class TriAnalyzer: + def __init__(self, triangulation: Triangulation) -> None: ... + @property + def scale_factors(self) -> tuple[float, float]: ... + def circle_ratios(self, rescale: bool = ...) -> np.ndarray: ... + def get_flat_tri_mask( + self, min_circle_ratio: float = ..., rescale: bool = ... + ) -> np.ndarray: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triangulation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triangulation.py new file mode 100644 index 00000000..c48b09b2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triangulation.py @@ -0,0 +1,9 @@ +from ._triangulation import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tricontour.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tricontour.py new file mode 100644 index 00000000..37406451 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tricontour.py @@ -0,0 +1,9 @@ +from ._tricontour import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trifinder.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trifinder.py new file mode 100644 index 00000000..1aff5c9d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trifinder.py @@ -0,0 +1,9 @@ +from ._trifinder import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triinterpolate.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triinterpolate.py new file mode 100644 index 00000000..3112bd38 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triinterpolate.py @@ -0,0 +1,9 @@ +from ._triinterpolate import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tripcolor.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tripcolor.py new file mode 100644 index 00000000..0da87891 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tripcolor.py @@ -0,0 +1,9 @@ +from ._tripcolor import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triplot.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triplot.py new file mode 100644 index 00000000..7c012b1a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/triplot.py @@ -0,0 +1,9 @@ +from ._triplot import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trirefine.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trirefine.py new file mode 100644 index 00000000..6f22f9e8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/trirefine.py @@ -0,0 +1,9 @@ +from ._trirefine import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tritools.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tritools.py new file mode 100644 index 00000000..9c6839ca --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/tri/tritools.py @@ -0,0 +1,9 @@ +from ._tritools import * # noqa: F401, F403 +from matplotlib import _api + + +_api.warn_deprecated( + "3.7", + message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will " + f"be removed two minor releases later. All functionality is " + f"available via the top-level module matplotlib.tri") diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/typing.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/typing.py new file mode 100644 index 00000000..02059be9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/typing.py @@ -0,0 +1,60 @@ +""" +Typing support for Matplotlib + +This module contains Type aliases which are useful for Matplotlib and potentially +downstream libraries. + +.. admonition:: Provisional status of typing + + The ``typing`` module and type stub files are considered provisional and may change + at any time without a deprecation period. +""" +from collections.abc import Hashable, Sequence +import pathlib +from typing import Any, Literal, TypeVar, Union + +from . import path +from ._enums import JoinStyle, CapStyle +from .markers import MarkerStyle + +# The following are type aliases. Once python 3.9 is dropped, they should be annotated +# using ``typing.TypeAlias`` and Unions should be converted to using ``|`` syntax. + +RGBColorType = Union[tuple[float, float, float], str] +RGBAColorType = Union[ + str, # "none" or "#RRGGBBAA"/"#RGBA" hex strings + tuple[float, float, float, float], + # 2 tuple (color, alpha) representations, not infinitely recursive + # RGBColorType includes the (str, float) tuple, even for RGBA strings + tuple[RGBColorType, float], + # (4-tuple, float) is odd, but accepted as the outer float overriding A of 4-tuple + tuple[tuple[float, float, float, float], float], +] + +ColorType = Union[RGBColorType, RGBAColorType] + +RGBColourType = RGBColorType +RGBAColourType = RGBAColorType +ColourType = ColorType + +LineStyleType = Union[str, tuple[float, Sequence[float]]] +DrawStyleType = Literal["default", "steps", "steps-pre", "steps-mid", "steps-post"] +MarkEveryType = Union[ + None, int, tuple[int, int], slice, list[int], float, tuple[float, float], list[bool] +] + +MarkerType = Union[str, path.Path, MarkerStyle] +FillStyleType = Literal["full", "left", "right", "bottom", "top", "none"] +JoinStyleType = Union[JoinStyle, Literal["miter", "round", "bevel"]] +CapStyleType = Union[CapStyle, Literal["butt", "projecting", "round"]] + +RcStyleType = Union[ + str, + dict[str, Any], + pathlib.Path, + Sequence[Union[str, pathlib.Path, dict[str, Any]]], +] + +_HT = TypeVar("_HT", bound=Hashable) +HashableList = list[Union[_HT, "HashableList[_HT]"]] +"""A nested list of Hashable values.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/units.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/units.py new file mode 100644 index 00000000..e3480f22 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/units.py @@ -0,0 +1,195 @@ +""" +The classes here provide support for using custom classes with +Matplotlib, e.g., those that do not expose the array interface but know +how to convert themselves to arrays. It also supports classes with +units and units conversion. Use cases include converters for custom +objects, e.g., a list of datetime objects, as well as for objects that +are unit aware. We don't assume any particular units implementation; +rather a units implementation must register with the Registry converter +dictionary and provide a `ConversionInterface`. For example, +here is a complete implementation which supports plotting with native +datetime objects:: + + import matplotlib.units as units + import matplotlib.dates as dates + import matplotlib.ticker as ticker + import datetime + + class DateConverter(units.ConversionInterface): + + @staticmethod + def convert(value, unit, axis): + "Convert a datetime value to a scalar or array." + return dates.date2num(value) + + @staticmethod + def axisinfo(unit, axis): + "Return major and minor tick locators and formatters." + if unit != 'date': + return None + majloc = dates.AutoDateLocator() + majfmt = dates.AutoDateFormatter(majloc) + return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='date') + + @staticmethod + def default_units(x, axis): + "Return the default unit for x or None." + return 'date' + + # Finally we register our object type with the Matplotlib units registry. + units.registry[datetime.date] = DateConverter() +""" + +from decimal import Decimal +from numbers import Number + +import numpy as np +from numpy import ma + +from matplotlib import cbook + + +class ConversionError(TypeError): + pass + + +def _is_natively_supported(x): + """ + Return whether *x* is of a type that Matplotlib natively supports or an + array of objects of such types. + """ + # Matplotlib natively supports all number types except Decimal. + if np.iterable(x): + # Assume lists are homogeneous as other functions in unit system. + for thisx in x: + if thisx is ma.masked: + continue + return isinstance(thisx, Number) and not isinstance(thisx, Decimal) + else: + return isinstance(x, Number) and not isinstance(x, Decimal) + + +class AxisInfo: + """ + Information to support default axis labeling, tick labeling, and limits. + + An instance of this class must be returned by + `ConversionInterface.axisinfo`. + """ + def __init__(self, majloc=None, minloc=None, + majfmt=None, minfmt=None, label=None, + default_limits=None): + """ + Parameters + ---------- + majloc, minloc : Locator, optional + Tick locators for the major and minor ticks. + majfmt, minfmt : Formatter, optional + Tick formatters for the major and minor ticks. + label : str, optional + The default axis label. + default_limits : optional + The default min and max limits of the axis if no data has + been plotted. + + Notes + ----- + If any of the above are ``None``, the axis will simply use the + default value. + """ + self.majloc = majloc + self.minloc = minloc + self.majfmt = majfmt + self.minfmt = minfmt + self.label = label + self.default_limits = default_limits + + +class ConversionInterface: + """ + The minimal interface for a converter to take custom data types (or + sequences) and convert them to values Matplotlib can use. + """ + + @staticmethod + def axisinfo(unit, axis): + """Return an `.AxisInfo` for the axis with the specified units.""" + return None + + @staticmethod + def default_units(x, axis): + """Return the default unit for *x* or ``None`` for the given axis.""" + return None + + @staticmethod + def convert(obj, unit, axis): + """ + Convert *obj* using *unit* for the specified *axis*. + + If *obj* is a sequence, return the converted sequence. The output must + be a sequence of scalars that can be used by the numpy array layer. + """ + return obj + + +class DecimalConverter(ConversionInterface): + """Converter for decimal.Decimal data to float.""" + + @staticmethod + def convert(value, unit, axis): + """ + Convert Decimals to floats. + + The *unit* and *axis* arguments are not used. + + Parameters + ---------- + value : decimal.Decimal or iterable + Decimal or list of Decimal need to be converted + """ + if isinstance(value, Decimal): + return float(value) + # value is Iterable[Decimal] + elif isinstance(value, ma.MaskedArray): + return ma.asarray(value, dtype=float) + else: + return np.asarray(value, dtype=float) + + # axisinfo and default_units can be inherited as Decimals are Numbers. + + +class Registry(dict): + """Register types with conversion interface.""" + + def get_converter(self, x): + """Get the converter interface instance for *x*, or None.""" + # Unpack in case of e.g. Pandas or xarray object + x = cbook._unpack_to_numpy(x) + + if isinstance(x, np.ndarray): + # In case x in a masked array, access the underlying data (only its + # type matters). If x is a regular ndarray, getdata() just returns + # the array itself. + x = np.ma.getdata(x).ravel() + # If there are no elements in x, infer the units from its dtype + if not x.size: + return self.get_converter(np.array([0], dtype=x.dtype)) + for cls in type(x).__mro__: # Look up in the cache. + try: + return self[cls] + except KeyError: + pass + try: # If cache lookup fails, look up based on first element... + first = cbook._safe_first_finite(x) + except (TypeError, StopIteration): + pass + else: + # ... and avoid infinite recursion for pathological iterables for + # which indexing returns instances of the same iterable class. + if type(first) is not type(x): + return self.get_converter(first) + return None + + +registry = Registry() +registry[Decimal] = DecimalConverter() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.py new file mode 100644 index 00000000..0a31a9dd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.py @@ -0,0 +1,4243 @@ +""" +GUI neutral widgets +=================== + +Widgets that are designed to work for any of the GUI backends. +All of these widgets require you to predefine an `~.axes.Axes` +instance and pass that as the first parameter. Matplotlib doesn't try to +be too smart with respect to layout -- you will have to figure out how +wide and tall you want your Axes to be to accommodate your widget. +""" + +from contextlib import ExitStack +import copy +import itertools +from numbers import Integral, Number + +from cycler import cycler +import numpy as np + +import matplotlib as mpl +from . import (_api, _docstring, backend_tools, cbook, collections, colors, + text as mtext, ticker, transforms) +from .lines import Line2D +from .patches import Circle, Rectangle, Ellipse, Polygon +from .transforms import TransformedPatchPath, Affine2D + + +class LockDraw: + """ + Some widgets, like the cursor, draw onto the canvas, and this is not + desirable under all circumstances, like when the toolbar is in zoom-to-rect + mode and drawing a rectangle. To avoid this, a widget can acquire a + canvas' lock with ``canvas.widgetlock(widget)`` before drawing on the + canvas; this will prevent other widgets from doing so at the same time (if + they also try to acquire the lock first). + """ + + def __init__(self): + self._owner = None + + def __call__(self, o): + """Reserve the lock for *o*.""" + if not self.available(o): + raise ValueError('already locked') + self._owner = o + + def release(self, o): + """Release the lock from *o*.""" + if not self.available(o): + raise ValueError('you do not own this lock') + self._owner = None + + def available(self, o): + """Return whether drawing is available to *o*.""" + return not self.locked() or self.isowner(o) + + def isowner(self, o): + """Return whether *o* owns this lock.""" + return self._owner is o + + def locked(self): + """Return whether the lock is currently held by an owner.""" + return self._owner is not None + + +class Widget: + """ + Abstract base class for GUI neutral widgets. + """ + drawon = True + eventson = True + _active = True + + def set_active(self, active): + """Set whether the widget is active.""" + self._active = active + + def get_active(self): + """Get whether the widget is active.""" + return self._active + + # set_active is overridden by SelectorWidgets. + active = property(get_active, set_active, doc="Is the widget active?") + + def ignore(self, event): + """ + Return whether *event* should be ignored. + + This method should be called at the beginning of any event callback. + """ + return not self.active + + def _changed_canvas(self): + """ + Someone has switched the canvas on us! + + This happens if `savefig` needs to save to a format the previous + backend did not support (e.g. saving a figure using an Agg based + backend saved to a vector format). + + Returns + ------- + bool + True if the canvas has been changed. + + """ + return self.canvas is not self.ax.figure.canvas + + +class AxesWidget(Widget): + """ + Widget connected to a single `~matplotlib.axes.Axes`. + + To guarantee that the widget remains responsive and not garbage-collected, + a reference to the object should be maintained by the user. + + This is necessary because the callback registry + maintains only weak-refs to the functions, which are member + functions of the widget. If there are no references to the widget + object it may be garbage collected which will disconnect the callbacks. + + Attributes + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + canvas : `~matplotlib.backend_bases.FigureCanvasBase` + The parent figure canvas for the widget. + active : bool + If False, the widget does not respond to events. + """ + + def __init__(self, ax): + self.ax = ax + self.canvas = ax.figure.canvas + self._cids = [] + + def connect_event(self, event, callback): + """ + Connect a callback function with an event. + + This should be used in lieu of ``figure.canvas.mpl_connect`` since this + function stores callback ids for later clean up. + """ + cid = self.canvas.mpl_connect(event, callback) + self._cids.append(cid) + + def disconnect_events(self): + """Disconnect all events created by this widget.""" + for c in self._cids: + self.canvas.mpl_disconnect(c) + + def _get_data_coords(self, event): + """Return *event*'s data coordinates in this widget's Axes.""" + # This method handles the possibility that event.inaxes != self.ax (which may + # occur if multiple axes are overlaid), in which case event.xdata/.ydata will + # be wrong. Note that we still special-case the common case where + # event.inaxes == self.ax and avoid re-running the inverse data transform, + # because that can introduce floating point errors for synthetic events. + return ((event.xdata, event.ydata) if event.inaxes is self.ax + else self.ax.transData.inverted().transform((event.x, event.y))) + + +class Button(AxesWidget): + """ + A GUI neutral button. + + For the button to remain responsive you must keep a reference to it. + Call `.on_clicked` to connect to the button. + + Attributes + ---------- + ax + The `~.axes.Axes` the button renders into. + label + A `.Text` instance. + color + The color of the button when not hovering. + hovercolor + The color of the button when hovering. + """ + + def __init__(self, ax, label, image=None, + color='0.85', hovercolor='0.95', *, useblit=True): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` instance the button will be placed into. + label : str + The button text. + image : array-like or PIL Image + The image to place in the button, if not *None*. The parameter is + directly forwarded to `~.axes.Axes.imshow`. + color : color + The color of the button when not activated. + hovercolor : color + The color of the button when the mouse is over it. + useblit : bool, default: True + Use blitting for faster drawing if supported by the backend. + See the tutorial :ref:`blitting` for details. + + .. versionadded:: 3.7 + """ + super().__init__(ax) + + if image is not None: + ax.imshow(image) + self.label = ax.text(0.5, 0.5, label, + verticalalignment='center', + horizontalalignment='center', + transform=ax.transAxes) + + self._useblit = useblit and self.canvas.supports_blit + + self._observers = cbook.CallbackRegistry(signals=["clicked"]) + + self.connect_event('button_press_event', self._click) + self.connect_event('button_release_event', self._release) + self.connect_event('motion_notify_event', self._motion) + ax.set_navigate(False) + ax.set_facecolor(color) + ax.set_xticks([]) + ax.set_yticks([]) + self.color = color + self.hovercolor = hovercolor + + def _click(self, event): + if not self.eventson or self.ignore(event) or not self.ax.contains(event)[0]: + return + if event.canvas.mouse_grabber != self.ax: + event.canvas.grab_mouse(self.ax) + + def _release(self, event): + if self.ignore(event) or event.canvas.mouse_grabber != self.ax: + return + event.canvas.release_mouse(self.ax) + if self.eventson and self.ax.contains(event)[0]: + self._observers.process('clicked', event) + + def _motion(self, event): + if self.ignore(event): + return + c = self.hovercolor if self.ax.contains(event)[0] else self.color + if not colors.same_color(c, self.ax.get_facecolor()): + self.ax.set_facecolor(c) + if self.drawon: + if self._useblit: + self.ax.draw_artist(self.ax) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw() + + def on_clicked(self, func): + """ + Connect the callback function *func* to button click events. + + Returns a connection id, which can be used to disconnect the callback. + """ + return self._observers.connect('clicked', lambda event: func(event)) + + def disconnect(self, cid): + """Remove the callback function with connection id *cid*.""" + self._observers.disconnect(cid) + + +class SliderBase(AxesWidget): + """ + The base class for constructing Slider widgets. Not intended for direct + usage. + + For the slider to remain responsive you must maintain a reference to it. + """ + def __init__(self, ax, orientation, closedmin, closedmax, + valmin, valmax, valfmt, dragging, valstep): + if ax.name == '3d': + raise ValueError('Sliders cannot be added to 3D Axes') + + super().__init__(ax) + _api.check_in_list(['horizontal', 'vertical'], orientation=orientation) + + self.orientation = orientation + self.closedmin = closedmin + self.closedmax = closedmax + self.valmin = valmin + self.valmax = valmax + self.valstep = valstep + self.drag_active = False + self.valfmt = valfmt + + if orientation == "vertical": + ax.set_ylim((valmin, valmax)) + axis = ax.yaxis + else: + ax.set_xlim((valmin, valmax)) + axis = ax.xaxis + + self._fmt = axis.get_major_formatter() + if not isinstance(self._fmt, ticker.ScalarFormatter): + self._fmt = ticker.ScalarFormatter() + self._fmt.set_axis(axis) + self._fmt.set_useOffset(False) # No additive offset. + self._fmt.set_useMathText(True) # x sign before multiplicative offset. + + ax.set_axis_off() + ax.set_navigate(False) + + self.connect_event("button_press_event", self._update) + self.connect_event("button_release_event", self._update) + if dragging: + self.connect_event("motion_notify_event", self._update) + self._observers = cbook.CallbackRegistry(signals=["changed"]) + + def _stepped_value(self, val): + """Return *val* coerced to closest number in the ``valstep`` grid.""" + if isinstance(self.valstep, Number): + val = (self.valmin + + round((val - self.valmin) / self.valstep) * self.valstep) + elif self.valstep is not None: + valstep = np.asanyarray(self.valstep) + if valstep.ndim != 1: + raise ValueError( + f"valstep must have 1 dimension but has {valstep.ndim}" + ) + val = valstep[np.argmin(np.abs(valstep - val))] + return val + + def disconnect(self, cid): + """ + Remove the observer with connection id *cid*. + + Parameters + ---------- + cid : int + Connection id of the observer to be removed. + """ + self._observers.disconnect(cid) + + def reset(self): + """Reset the slider to the initial value.""" + if np.any(self.val != self.valinit): + self.set_val(self.valinit) + + +class Slider(SliderBase): + """ + A slider representing a floating point range. + + Create a slider from *valmin* to *valmax* in Axes *ax*. For the slider to + remain responsive you must maintain a reference to it. Call + :meth:`on_changed` to connect to the slider event. + + Attributes + ---------- + val : float + Slider value. + """ + + @_api.make_keyword_only("3.7", name="valinit") + def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None, + closedmin=True, closedmax=True, slidermin=None, + slidermax=None, dragging=True, valstep=None, + orientation='horizontal', *, initcolor='r', + track_color='lightgrey', handle_style=None, **kwargs): + """ + Parameters + ---------- + ax : Axes + The Axes to put the slider in. + + label : str + Slider label. + + valmin : float + The minimum value of the slider. + + valmax : float + The maximum value of the slider. + + valinit : float, default: 0.5 + The slider initial position. + + valfmt : str, default: None + %-format string used to format the slider value. If None, a + `.ScalarFormatter` is used instead. + + closedmin : bool, default: True + Whether the slider interval is closed on the bottom. + + closedmax : bool, default: True + Whether the slider interval is closed on the top. + + slidermin : Slider, default: None + Do not allow the current slider to have a value less than + the value of the Slider *slidermin*. + + slidermax : Slider, default: None + Do not allow the current slider to have a value greater than + the value of the Slider *slidermax*. + + dragging : bool, default: True + If True the slider can be dragged by the mouse. + + valstep : float or array-like, default: None + If a float, the slider will snap to multiples of *valstep*. + If an array the slider will snap to the values in the array. + + orientation : {'horizontal', 'vertical'}, default: 'horizontal' + The orientation of the slider. + + initcolor : color, default: 'r' + The color of the line at the *valinit* position. Set to ``'none'`` + for no line. + + track_color : color, default: 'lightgrey' + The color of the background track. The track is accessible for + further styling via the *track* attribute. + + handle_style : dict + Properties of the slider handle. Default values are + + ========= ===== ======= ======================================== + Key Value Default Description + ========= ===== ======= ======================================== + facecolor color 'white' The facecolor of the slider handle. + edgecolor color '.75' The edgecolor of the slider handle. + size int 10 The size of the slider handle in points. + ========= ===== ======= ======================================== + + Other values will be transformed as marker{foo} and passed to the + `~.Line2D` constructor. e.g. ``handle_style = {'style'='x'}`` will + result in ``markerstyle = 'x'``. + + Notes + ----- + Additional kwargs are passed on to ``self.poly`` which is the + `~matplotlib.patches.Polygon` that draws the slider knob. See the + `.Polygon` documentation for valid property names (``facecolor``, + ``edgecolor``, ``alpha``, etc.). + """ + super().__init__(ax, orientation, closedmin, closedmax, + valmin, valmax, valfmt, dragging, valstep) + + if slidermin is not None and not hasattr(slidermin, 'val'): + raise ValueError( + f"Argument slidermin ({type(slidermin)}) has no 'val'") + if slidermax is not None and not hasattr(slidermax, 'val'): + raise ValueError( + f"Argument slidermax ({type(slidermax)}) has no 'val'") + self.slidermin = slidermin + self.slidermax = slidermax + valinit = self._value_in_bounds(valinit) + if valinit is None: + valinit = valmin + self.val = valinit + self.valinit = valinit + + defaults = {'facecolor': 'white', 'edgecolor': '.75', 'size': 10} + handle_style = {} if handle_style is None else handle_style + marker_props = { + f'marker{k}': v for k, v in {**defaults, **handle_style}.items() + } + + if orientation == 'vertical': + self.track = Rectangle( + (.25, 0), .5, 1, + transform=ax.transAxes, + facecolor=track_color + ) + ax.add_patch(self.track) + self.poly = ax.axhspan(valmin, valinit, .25, .75, **kwargs) + # Drawing a longer line and clipping it to the track avoids + # pixelation-related asymmetries. + self.hline = ax.axhline(valinit, 0, 1, color=initcolor, lw=1, + clip_path=TransformedPatchPath(self.track)) + handleXY = [[0.5], [valinit]] + else: + self.track = Rectangle( + (0, .25), 1, .5, + transform=ax.transAxes, + facecolor=track_color + ) + ax.add_patch(self.track) + self.poly = ax.axvspan(valmin, valinit, .25, .75, **kwargs) + self.vline = ax.axvline(valinit, 0, 1, color=initcolor, lw=1, + clip_path=TransformedPatchPath(self.track)) + handleXY = [[valinit], [0.5]] + self._handle, = ax.plot( + *handleXY, + "o", + **marker_props, + clip_on=False + ) + + if orientation == 'vertical': + self.label = ax.text(0.5, 1.02, label, transform=ax.transAxes, + verticalalignment='bottom', + horizontalalignment='center') + + self.valtext = ax.text(0.5, -0.02, self._format(valinit), + transform=ax.transAxes, + verticalalignment='top', + horizontalalignment='center') + else: + self.label = ax.text(-0.02, 0.5, label, transform=ax.transAxes, + verticalalignment='center', + horizontalalignment='right') + + self.valtext = ax.text(1.02, 0.5, self._format(valinit), + transform=ax.transAxes, + verticalalignment='center', + horizontalalignment='left') + + self.set_val(valinit) + + def _value_in_bounds(self, val): + """Makes sure *val* is with given bounds.""" + val = self._stepped_value(val) + + if val <= self.valmin: + if not self.closedmin: + return + val = self.valmin + elif val >= self.valmax: + if not self.closedmax: + return + val = self.valmax + + if self.slidermin is not None and val <= self.slidermin.val: + if not self.closedmin: + return + val = self.slidermin.val + + if self.slidermax is not None and val >= self.slidermax.val: + if not self.closedmax: + return + val = self.slidermax.val + return val + + def _update(self, event): + """Update the slider position.""" + if self.ignore(event) or event.button != 1: + return + + if event.name == 'button_press_event' and self.ax.contains(event)[0]: + self.drag_active = True + event.canvas.grab_mouse(self.ax) + + if not self.drag_active: + return + + if (event.name == 'button_release_event' + or event.name == 'button_press_event' and not self.ax.contains(event)[0]): + self.drag_active = False + event.canvas.release_mouse(self.ax) + return + + xdata, ydata = self._get_data_coords(event) + val = self._value_in_bounds( + xdata if self.orientation == 'horizontal' else ydata) + if val not in [None, self.val]: + self.set_val(val) + + def _format(self, val): + """Pretty-print *val*.""" + if self.valfmt is not None: + return self.valfmt % val + else: + _, s, _ = self._fmt.format_ticks([self.valmin, val, self.valmax]) + # fmt.get_offset is actually the multiplicative factor, if any. + return s + self._fmt.get_offset() + + def set_val(self, val): + """ + Set slider value to *val*. + + Parameters + ---------- + val : float + """ + xy = self.poly.xy + if self.orientation == 'vertical': + xy[1] = .25, val + xy[2] = .75, val + self._handle.set_ydata([val]) + else: + xy[2] = val, .75 + xy[3] = val, .25 + self._handle.set_xdata([val]) + self.poly.xy = xy + self.valtext.set_text(self._format(val)) + if self.drawon: + self.ax.figure.canvas.draw_idle() + self.val = val + if self.eventson: + self._observers.process('changed', val) + + def on_changed(self, func): + """ + Connect *func* as callback function to changes of the slider value. + + Parameters + ---------- + func : callable + Function to call when slider is changed. + The function must accept a single float as its arguments. + + Returns + ------- + int + Connection id (which can be used to disconnect *func*). + """ + return self._observers.connect('changed', lambda val: func(val)) + + +class RangeSlider(SliderBase): + """ + A slider representing a range of floating point values. Defines the min and + max of the range via the *val* attribute as a tuple of (min, max). + + Create a slider that defines a range contained within [*valmin*, *valmax*] + in Axes *ax*. For the slider to remain responsive you must maintain a + reference to it. Call :meth:`on_changed` to connect to the slider event. + + Attributes + ---------- + val : tuple of float + Slider value. + """ + + @_api.make_keyword_only("3.7", name="valinit") + def __init__( + self, + ax, + label, + valmin, + valmax, + valinit=None, + valfmt=None, + closedmin=True, + closedmax=True, + dragging=True, + valstep=None, + orientation="horizontal", + track_color='lightgrey', + handle_style=None, + **kwargs, + ): + """ + Parameters + ---------- + ax : Axes + The Axes to put the slider in. + + label : str + Slider label. + + valmin : float + The minimum value of the slider. + + valmax : float + The maximum value of the slider. + + valinit : tuple of float or None, default: None + The initial positions of the slider. If None the initial positions + will be at the 25th and 75th percentiles of the range. + + valfmt : str, default: None + %-format string used to format the slider values. If None, a + `.ScalarFormatter` is used instead. + + closedmin : bool, default: True + Whether the slider interval is closed on the bottom. + + closedmax : bool, default: True + Whether the slider interval is closed on the top. + + dragging : bool, default: True + If True the slider can be dragged by the mouse. + + valstep : float, default: None + If given, the slider will snap to multiples of *valstep*. + + orientation : {'horizontal', 'vertical'}, default: 'horizontal' + The orientation of the slider. + + track_color : color, default: 'lightgrey' + The color of the background track. The track is accessible for + further styling via the *track* attribute. + + handle_style : dict + Properties of the slider handles. Default values are + + ========= ===== ======= ========================================= + Key Value Default Description + ========= ===== ======= ========================================= + facecolor color 'white' The facecolor of the slider handles. + edgecolor color '.75' The edgecolor of the slider handles. + size int 10 The size of the slider handles in points. + ========= ===== ======= ========================================= + + Other values will be transformed as marker{foo} and passed to the + `~.Line2D` constructor. e.g. ``handle_style = {'style'='x'}`` will + result in ``markerstyle = 'x'``. + + Notes + ----- + Additional kwargs are passed on to ``self.poly`` which is the + `~matplotlib.patches.Polygon` that draws the slider knob. See the + `.Polygon` documentation for valid property names (``facecolor``, + ``edgecolor``, ``alpha``, etc.). + """ + super().__init__(ax, orientation, closedmin, closedmax, + valmin, valmax, valfmt, dragging, valstep) + + # Set a value to allow _value_in_bounds() to work. + self.val = (valmin, valmax) + if valinit is None: + # Place at the 25th and 75th percentiles + extent = valmax - valmin + valinit = np.array([valmin + extent * 0.25, + valmin + extent * 0.75]) + else: + valinit = self._value_in_bounds(valinit) + self.val = valinit + self.valinit = valinit + + defaults = {'facecolor': 'white', 'edgecolor': '.75', 'size': 10} + handle_style = {} if handle_style is None else handle_style + marker_props = { + f'marker{k}': v for k, v in {**defaults, **handle_style}.items() + } + + if orientation == "vertical": + self.track = Rectangle( + (.25, 0), .5, 2, + transform=ax.transAxes, + facecolor=track_color + ) + ax.add_patch(self.track) + poly_transform = self.ax.get_yaxis_transform(which="grid") + handleXY_1 = [.5, valinit[0]] + handleXY_2 = [.5, valinit[1]] + else: + self.track = Rectangle( + (0, .25), 1, .5, + transform=ax.transAxes, + facecolor=track_color + ) + ax.add_patch(self.track) + poly_transform = self.ax.get_xaxis_transform(which="grid") + handleXY_1 = [valinit[0], .5] + handleXY_2 = [valinit[1], .5] + self.poly = Polygon(np.zeros([5, 2]), **kwargs) + self._update_selection_poly(*valinit) + self.poly.set_transform(poly_transform) + self.poly.get_path()._interpolation_steps = 100 + self.ax.add_patch(self.poly) + self.ax._request_autoscale_view() + self._handles = [ + ax.plot( + *handleXY_1, + "o", + **marker_props, + clip_on=False + )[0], + ax.plot( + *handleXY_2, + "o", + **marker_props, + clip_on=False + )[0] + ] + + if orientation == "vertical": + self.label = ax.text( + 0.5, + 1.02, + label, + transform=ax.transAxes, + verticalalignment="bottom", + horizontalalignment="center", + ) + + self.valtext = ax.text( + 0.5, + -0.02, + self._format(valinit), + transform=ax.transAxes, + verticalalignment="top", + horizontalalignment="center", + ) + else: + self.label = ax.text( + -0.02, + 0.5, + label, + transform=ax.transAxes, + verticalalignment="center", + horizontalalignment="right", + ) + + self.valtext = ax.text( + 1.02, + 0.5, + self._format(valinit), + transform=ax.transAxes, + verticalalignment="center", + horizontalalignment="left", + ) + + self._active_handle = None + self.set_val(valinit) + + def _update_selection_poly(self, vmin, vmax): + """ + Update the vertices of the *self.poly* slider in-place + to cover the data range *vmin*, *vmax*. + """ + # The vertices are positioned + # 1 ------ 2 + # | | + # 0, 4 ---- 3 + verts = self.poly.xy + if self.orientation == "vertical": + verts[0] = verts[4] = .25, vmin + verts[1] = .25, vmax + verts[2] = .75, vmax + verts[3] = .75, vmin + else: + verts[0] = verts[4] = vmin, .25 + verts[1] = vmin, .75 + verts[2] = vmax, .75 + verts[3] = vmax, .25 + + def _min_in_bounds(self, min): + """Ensure the new min value is between valmin and self.val[1].""" + if min <= self.valmin: + if not self.closedmin: + return self.val[0] + min = self.valmin + + if min > self.val[1]: + min = self.val[1] + return self._stepped_value(min) + + def _max_in_bounds(self, max): + """Ensure the new max value is between valmax and self.val[0].""" + if max >= self.valmax: + if not self.closedmax: + return self.val[1] + max = self.valmax + + if max <= self.val[0]: + max = self.val[0] + return self._stepped_value(max) + + def _value_in_bounds(self, vals): + """Clip min, max values to the bounds.""" + return (self._min_in_bounds(vals[0]), self._max_in_bounds(vals[1])) + + def _update_val_from_pos(self, pos): + """Update the slider value based on a given position.""" + idx = np.argmin(np.abs(self.val - pos)) + if idx == 0: + val = self._min_in_bounds(pos) + self.set_min(val) + else: + val = self._max_in_bounds(pos) + self.set_max(val) + if self._active_handle: + if self.orientation == "vertical": + self._active_handle.set_ydata([val]) + else: + self._active_handle.set_xdata([val]) + + def _update(self, event): + """Update the slider position.""" + if self.ignore(event) or event.button != 1: + return + + if event.name == "button_press_event" and self.ax.contains(event)[0]: + self.drag_active = True + event.canvas.grab_mouse(self.ax) + + if not self.drag_active: + return + + if (event.name == "button_release_event" + or event.name == "button_press_event" and not self.ax.contains(event)[0]): + self.drag_active = False + event.canvas.release_mouse(self.ax) + self._active_handle = None + return + + # determine which handle was grabbed + xdata, ydata = self._get_data_coords(event) + handle_index = np.argmin(np.abs( + [h.get_xdata()[0] - xdata for h in self._handles] + if self.orientation == "horizontal" else + [h.get_ydata()[0] - ydata for h in self._handles])) + handle = self._handles[handle_index] + + # these checks ensure smooth behavior if the handles swap which one + # has a higher value. i.e. if one is dragged over and past the other. + if handle is not self._active_handle: + self._active_handle = handle + + self._update_val_from_pos(xdata if self.orientation == "horizontal" else ydata) + + def _format(self, val): + """Pretty-print *val*.""" + if self.valfmt is not None: + return f"({self.valfmt % val[0]}, {self.valfmt % val[1]})" + else: + _, s1, s2, _ = self._fmt.format_ticks( + [self.valmin, *val, self.valmax] + ) + # fmt.get_offset is actually the multiplicative factor, if any. + s1 += self._fmt.get_offset() + s2 += self._fmt.get_offset() + # Use f string to avoid issues with backslashes when cast to a str + return f"({s1}, {s2})" + + def set_min(self, min): + """ + Set the lower value of the slider to *min*. + + Parameters + ---------- + min : float + """ + self.set_val((min, self.val[1])) + + def set_max(self, max): + """ + Set the lower value of the slider to *max*. + + Parameters + ---------- + max : float + """ + self.set_val((self.val[0], max)) + + def set_val(self, val): + """ + Set slider value to *val*. + + Parameters + ---------- + val : tuple or array-like of float + """ + val = np.sort(val) + _api.check_shape((2,), val=val) + # Reset value to allow _value_in_bounds() to work. + self.val = (self.valmin, self.valmax) + vmin, vmax = self._value_in_bounds(val) + self._update_selection_poly(vmin, vmax) + if self.orientation == "vertical": + self._handles[0].set_ydata([vmin]) + self._handles[1].set_ydata([vmax]) + else: + self._handles[0].set_xdata([vmin]) + self._handles[1].set_xdata([vmax]) + + self.valtext.set_text(self._format((vmin, vmax))) + + if self.drawon: + self.ax.figure.canvas.draw_idle() + self.val = (vmin, vmax) + if self.eventson: + self._observers.process("changed", (vmin, vmax)) + + def on_changed(self, func): + """ + Connect *func* as callback function to changes of the slider value. + + Parameters + ---------- + func : callable + Function to call when slider is changed. The function + must accept a 2-tuple of floats as its argument. + + Returns + ------- + int + Connection id (which can be used to disconnect *func*). + """ + return self._observers.connect('changed', lambda val: func(val)) + + +def _expand_text_props(props): + props = cbook.normalize_kwargs(props, mtext.Text) + return cycler(**props)() if props else itertools.repeat({}) + + +class CheckButtons(AxesWidget): + r""" + A GUI neutral set of check buttons. + + For the check buttons to remain responsive you must keep a + reference to this object. + + Connect to the CheckButtons with the `.on_clicked` method. + + Attributes + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + + labels : list of `~matplotlib.text.Text` + + rectangles : list of `~matplotlib.patches.Rectangle` + + lines : list of (`.Line2D`, `.Line2D`) pairs + List of lines for the x's in the checkboxes. These lines exist for + each box, but have ``set_visible(False)`` when its box is not checked. + """ + + def __init__(self, ax, labels, actives=None, *, useblit=True, + label_props=None, frame_props=None, check_props=None): + """ + Add check buttons to `~.axes.Axes` instance *ax*. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + labels : list of str + The labels of the check buttons. + actives : list of bool, optional + The initial check states of the buttons. The list must have the + same length as *labels*. If not given, all buttons are unchecked. + useblit : bool, default: True + Use blitting for faster drawing if supported by the backend. + See the tutorial :ref:`blitting` for details. + + .. versionadded:: 3.7 + + label_props : dict, optional + Dictionary of `.Text` properties to be used for the labels. + + .. versionadded:: 3.7 + frame_props : dict, optional + Dictionary of scatter `.Collection` properties to be used for the + check button frame. Defaults (label font size / 2)**2 size, black + edgecolor, no facecolor, and 1.0 linewidth. + + .. versionadded:: 3.7 + check_props : dict, optional + Dictionary of scatter `.Collection` properties to be used for the + check button check. Defaults to (label font size / 2)**2 size, + black color, and 1.0 linewidth. + + .. versionadded:: 3.7 + """ + super().__init__(ax) + + _api.check_isinstance((dict, None), label_props=label_props, + frame_props=frame_props, check_props=check_props) + + ax.set_xticks([]) + ax.set_yticks([]) + ax.set_navigate(False) + + if actives is None: + actives = [False] * len(labels) + + self._useblit = useblit and self.canvas.supports_blit + self._background = None + + ys = np.linspace(1, 0, len(labels)+2)[1:-1] + + label_props = _expand_text_props(label_props) + self.labels = [ + ax.text(0.25, y, label, transform=ax.transAxes, + horizontalalignment="left", verticalalignment="center", + **props) + for y, label, props in zip(ys, labels, label_props)] + text_size = np.array([text.get_fontsize() for text in self.labels]) / 2 + + frame_props = { + 's': text_size**2, + 'linewidth': 1, + **cbook.normalize_kwargs(frame_props, collections.PathCollection), + 'marker': 's', + 'transform': ax.transAxes, + } + frame_props.setdefault('facecolor', frame_props.get('color', 'none')) + frame_props.setdefault('edgecolor', frame_props.pop('color', 'black')) + self._frames = ax.scatter([0.15] * len(ys), ys, **frame_props) + check_props = { + 'linewidth': 1, + 's': text_size**2, + **cbook.normalize_kwargs(check_props, collections.PathCollection), + 'marker': 'x', + 'transform': ax.transAxes, + 'animated': self._useblit, + } + check_props.setdefault('facecolor', check_props.pop('color', 'black')) + self._checks = ax.scatter([0.15] * len(ys), ys, **check_props) + # The user may have passed custom colours in check_props, so we need to + # create the checks (above), and modify the visibility after getting + # whatever the user set. + self._init_status(actives) + + self.connect_event('button_press_event', self._clicked) + if self._useblit: + self.connect_event('draw_event', self._clear) + + self._observers = cbook.CallbackRegistry(signals=["clicked"]) + + def _clear(self, event): + """Internal event handler to clear the buttons.""" + if self.ignore(event) or self._changed_canvas(): + return + self._background = self.canvas.copy_from_bbox(self.ax.bbox) + self.ax.draw_artist(self._checks) + if hasattr(self, '_lines'): + for l1, l2 in self._lines: + self.ax.draw_artist(l1) + self.ax.draw_artist(l2) + + def _clicked(self, event): + if self.ignore(event) or event.button != 1 or not self.ax.contains(event)[0]: + return + pclicked = self.ax.transAxes.inverted().transform((event.x, event.y)) + distances = {} + if hasattr(self, "_rectangles"): + for i, (p, t) in enumerate(zip(self._rectangles, self.labels)): + x0, y0 = p.get_xy() + if (t.get_window_extent().contains(event.x, event.y) + or (x0 <= pclicked[0] <= x0 + p.get_width() + and y0 <= pclicked[1] <= y0 + p.get_height())): + distances[i] = np.linalg.norm(pclicked - p.get_center()) + else: + _, frame_inds = self._frames.contains(event) + coords = self._frames.get_offset_transform().transform( + self._frames.get_offsets() + ) + for i, t in enumerate(self.labels): + if (i in frame_inds["ind"] + or t.get_window_extent().contains(event.x, event.y)): + distances[i] = np.linalg.norm(pclicked - coords[i]) + if len(distances) > 0: + closest = min(distances, key=distances.get) + self.set_active(closest) + + def set_label_props(self, props): + """ + Set properties of the `.Text` labels. + + .. versionadded:: 3.7 + + Parameters + ---------- + props : dict + Dictionary of `.Text` properties to be used for the labels. + """ + _api.check_isinstance(dict, props=props) + props = _expand_text_props(props) + for text, prop in zip(self.labels, props): + text.update(prop) + + def set_frame_props(self, props): + """ + Set properties of the check button frames. + + .. versionadded:: 3.7 + + Parameters + ---------- + props : dict + Dictionary of `.Collection` properties to be used for the check + button frames. + """ + _api.check_isinstance(dict, props=props) + if 's' in props: # Keep API consistent with constructor. + props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels)) + self._frames.update(props) + + def set_check_props(self, props): + """ + Set properties of the check button checks. + + .. versionadded:: 3.7 + + Parameters + ---------- + props : dict + Dictionary of `.Collection` properties to be used for the check + button check. + """ + _api.check_isinstance(dict, props=props) + if 's' in props: # Keep API consistent with constructor. + props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels)) + actives = self.get_status() + self._checks.update(props) + # If new colours are supplied, then we must re-apply the status. + self._init_status(actives) + + def set_active(self, index): + """ + Toggle (activate or deactivate) a check button by index. + + Callbacks will be triggered if :attr:`eventson` is True. + + Parameters + ---------- + index : int + Index of the check button to toggle. + + Raises + ------ + ValueError + If *index* is invalid. + """ + if index not in range(len(self.labels)): + raise ValueError(f'Invalid CheckButton index: {index}') + + invisible = colors.to_rgba('none') + + facecolors = self._checks.get_facecolor() + facecolors[index] = ( + self._active_check_colors[index] + if colors.same_color(facecolors[index], invisible) + else invisible + ) + self._checks.set_facecolor(facecolors) + + if hasattr(self, "_lines"): + l1, l2 = self._lines[index] + l1.set_visible(not l1.get_visible()) + l2.set_visible(not l2.get_visible()) + + if self.drawon: + if self._useblit: + if self._background is not None: + self.canvas.restore_region(self._background) + self.ax.draw_artist(self._checks) + if hasattr(self, "_lines"): + for l1, l2 in self._lines: + self.ax.draw_artist(l1) + self.ax.draw_artist(l2) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw() + + if self.eventson: + self._observers.process('clicked', self.labels[index].get_text()) + + def _init_status(self, actives): + """ + Initialize properties to match active status. + + The user may have passed custom colours in *check_props* to the + constructor, or to `.set_check_props`, so we need to modify the + visibility after getting whatever the user set. + """ + self._active_check_colors = self._checks.get_facecolor() + if len(self._active_check_colors) == 1: + self._active_check_colors = np.repeat(self._active_check_colors, + len(actives), axis=0) + self._checks.set_facecolor( + [ec if active else "none" + for ec, active in zip(self._active_check_colors, actives)]) + + def get_status(self): + """ + Return a list of the status (True/False) of all of the check buttons. + """ + return [not colors.same_color(color, colors.to_rgba("none")) + for color in self._checks.get_facecolors()] + + def on_clicked(self, func): + """ + Connect the callback function *func* to button click events. + + Returns a connection id, which can be used to disconnect the callback. + """ + return self._observers.connect('clicked', lambda text: func(text)) + + def disconnect(self, cid): + """Remove the observer with connection id *cid*.""" + self._observers.disconnect(cid) + + @_api.deprecated("3.7", + addendum="Any custom property styling may be lost.") + @property + def rectangles(self): + if not hasattr(self, "_rectangles"): + ys = np.linspace(1, 0, len(self.labels)+2)[1:-1] + dy = 1. / (len(self.labels) + 1) + w, h = dy / 2, dy / 2 + rectangles = self._rectangles = [ + Rectangle(xy=(0.05, ys[i] - h / 2), width=w, height=h, + edgecolor="black", + facecolor="none", + transform=self.ax.transAxes + ) + for i, y in enumerate(ys) + ] + self._frames.set_visible(False) + for rectangle in rectangles: + self.ax.add_patch(rectangle) + if not hasattr(self, "_lines"): + with _api.suppress_matplotlib_deprecation_warning(): + _ = self.lines + return self._rectangles + + @_api.deprecated("3.7", + addendum="Any custom property styling may be lost.") + @property + def lines(self): + if not hasattr(self, "_lines"): + ys = np.linspace(1, 0, len(self.labels)+2)[1:-1] + self._checks.set_visible(False) + dy = 1. / (len(self.labels) + 1) + w, h = dy / 2, dy / 2 + self._lines = [] + current_status = self.get_status() + lineparams = {'color': 'k', 'linewidth': 1.25, + 'transform': self.ax.transAxes, + 'solid_capstyle': 'butt', + 'animated': self._useblit} + for i, y in enumerate(ys): + x, y = 0.05, y - h / 2 + l1 = Line2D([x, x + w], [y + h, y], **lineparams) + l2 = Line2D([x, x + w], [y, y + h], **lineparams) + + l1.set_visible(current_status[i]) + l2.set_visible(current_status[i]) + self._lines.append((l1, l2)) + self.ax.add_line(l1) + self.ax.add_line(l2) + if not hasattr(self, "_rectangles"): + with _api.suppress_matplotlib_deprecation_warning(): + _ = self.rectangles + return self._lines + + +class TextBox(AxesWidget): + """ + A GUI neutral text input box. + + For the text box to remain responsive you must keep a reference to it. + + Call `.on_text_change` to be updated whenever the text changes. + + Call `.on_submit` to be updated whenever the user hits enter or + leaves the text entry field. + + Attributes + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + label : `~matplotlib.text.Text` + + color : color + The color of the text box when not hovering. + hovercolor : color + The color of the text box when hovering. + """ + + @_api.make_keyword_only("3.7", name="color") + def __init__(self, ax, label, initial='', + color='.95', hovercolor='1', label_pad=.01, + textalignment="left"): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` instance the button will be placed into. + label : str + Label for this text box. + initial : str + Initial value in the text box. + color : color + The color of the box. + hovercolor : color + The color of the box when the mouse is over it. + label_pad : float + The distance between the label and the right side of the textbox. + textalignment : {'left', 'center', 'right'} + The horizontal location of the text. + """ + super().__init__(ax) + + self._text_position = _api.check_getitem( + {"left": 0.05, "center": 0.5, "right": 0.95}, + textalignment=textalignment) + + self.label = ax.text( + -label_pad, 0.5, label, transform=ax.transAxes, + verticalalignment='center', horizontalalignment='right') + + # TextBox's text object should not parse mathtext at all. + self.text_disp = self.ax.text( + self._text_position, 0.5, initial, transform=self.ax.transAxes, + verticalalignment='center', horizontalalignment=textalignment, + parse_math=False) + + self._observers = cbook.CallbackRegistry(signals=["change", "submit"]) + + ax.set( + xlim=(0, 1), ylim=(0, 1), # s.t. cursor appears from first click. + navigate=False, facecolor=color, + xticks=[], yticks=[]) + + self.cursor_index = 0 + + self.cursor = ax.vlines(0, 0, 0, visible=False, color="k", lw=1, + transform=mpl.transforms.IdentityTransform()) + + self.connect_event('button_press_event', self._click) + self.connect_event('button_release_event', self._release) + self.connect_event('motion_notify_event', self._motion) + self.connect_event('key_press_event', self._keypress) + self.connect_event('resize_event', self._resize) + + self.color = color + self.hovercolor = hovercolor + + self.capturekeystrokes = False + + @property + def text(self): + return self.text_disp.get_text() + + def _rendercursor(self): + # this is a hack to figure out where the cursor should go. + # we draw the text up to where the cursor should go, measure + # and save its dimensions, draw the real text, then put the cursor + # at the saved dimensions + + # This causes a single extra draw if the figure has never been rendered + # yet, which should be fine as we're going to repeatedly re-render the + # figure later anyways. + if self.ax.figure._get_renderer() is None: + self.ax.figure.canvas.draw() + + text = self.text_disp.get_text() # Save value before overwriting it. + widthtext = text[:self.cursor_index] + + bb_text = self.text_disp.get_window_extent() + self.text_disp.set_text(widthtext or ",") + bb_widthtext = self.text_disp.get_window_extent() + + if bb_text.y0 == bb_text.y1: # Restoring the height if no text. + bb_text.y0 -= bb_widthtext.height / 2 + bb_text.y1 += bb_widthtext.height / 2 + elif not widthtext: # Keep width to 0. + bb_text.x1 = bb_text.x0 + else: # Move the cursor using width of bb_widthtext. + bb_text.x1 = bb_text.x0 + bb_widthtext.width + + self.cursor.set( + segments=[[(bb_text.x1, bb_text.y0), (bb_text.x1, bb_text.y1)]], + visible=True) + self.text_disp.set_text(text) + + self.ax.figure.canvas.draw() + + def _release(self, event): + if self.ignore(event): + return + if event.canvas.mouse_grabber != self.ax: + return + event.canvas.release_mouse(self.ax) + + def _keypress(self, event): + if self.ignore(event): + return + if self.capturekeystrokes: + key = event.key + text = self.text + if len(key) == 1: + text = (text[:self.cursor_index] + key + + text[self.cursor_index:]) + self.cursor_index += 1 + elif key == "right": + if self.cursor_index != len(text): + self.cursor_index += 1 + elif key == "left": + if self.cursor_index != 0: + self.cursor_index -= 1 + elif key == "home": + self.cursor_index = 0 + elif key == "end": + self.cursor_index = len(text) + elif key == "backspace": + if self.cursor_index != 0: + text = (text[:self.cursor_index - 1] + + text[self.cursor_index:]) + self.cursor_index -= 1 + elif key == "delete": + if self.cursor_index != len(self.text): + text = (text[:self.cursor_index] + + text[self.cursor_index + 1:]) + self.text_disp.set_text(text) + self._rendercursor() + if self.eventson: + self._observers.process('change', self.text) + if key in ["enter", "return"]: + self._observers.process('submit', self.text) + + def set_val(self, val): + newval = str(val) + if self.text == newval: + return + self.text_disp.set_text(newval) + self._rendercursor() + if self.eventson: + self._observers.process('change', self.text) + self._observers.process('submit', self.text) + + @_api.delete_parameter("3.7", "x") + def begin_typing(self, x=None): + self.capturekeystrokes = True + # Disable keypress shortcuts, which may otherwise cause the figure to + # be saved, closed, etc., until the user stops typing. The way to + # achieve this depends on whether toolmanager is in use. + stack = ExitStack() # Register cleanup actions when user stops typing. + self._on_stop_typing = stack.close + toolmanager = getattr( + self.ax.figure.canvas.manager, "toolmanager", None) + if toolmanager is not None: + # If using toolmanager, lock keypresses, and plan to release the + # lock when typing stops. + toolmanager.keypresslock(self) + stack.callback(toolmanager.keypresslock.release, self) + else: + # If not using toolmanager, disable all keypress-related rcParams. + # Avoid spurious warnings if keymaps are getting deprecated. + with _api.suppress_matplotlib_deprecation_warning(): + stack.enter_context(mpl.rc_context( + {k: [] for k in mpl.rcParams if k.startswith("keymap.")})) + + def stop_typing(self): + if self.capturekeystrokes: + self._on_stop_typing() + self._on_stop_typing = None + notifysubmit = True + else: + notifysubmit = False + self.capturekeystrokes = False + self.cursor.set_visible(False) + self.ax.figure.canvas.draw() + if notifysubmit and self.eventson: + # Because process() might throw an error in the user's code, only + # call it once we've already done our cleanup. + self._observers.process('submit', self.text) + + def _click(self, event): + if self.ignore(event): + return + if not self.ax.contains(event)[0]: + self.stop_typing() + return + if not self.eventson: + return + if event.canvas.mouse_grabber != self.ax: + event.canvas.grab_mouse(self.ax) + if not self.capturekeystrokes: + self.begin_typing() + self.cursor_index = self.text_disp._char_index_at(event.x) + self._rendercursor() + + def _resize(self, event): + self.stop_typing() + + def _motion(self, event): + if self.ignore(event): + return + c = self.hovercolor if self.ax.contains(event)[0] else self.color + if not colors.same_color(c, self.ax.get_facecolor()): + self.ax.set_facecolor(c) + if self.drawon: + self.ax.figure.canvas.draw() + + def on_text_change(self, func): + """ + When the text changes, call this *func* with event. + + A connection id is returned which can be used to disconnect. + """ + return self._observers.connect('change', lambda text: func(text)) + + def on_submit(self, func): + """ + When the user hits enter or leaves the submission box, call this + *func* with event. + + A connection id is returned which can be used to disconnect. + """ + return self._observers.connect('submit', lambda text: func(text)) + + def disconnect(self, cid): + """Remove the observer with connection id *cid*.""" + self._observers.disconnect(cid) + + +class RadioButtons(AxesWidget): + """ + A GUI neutral radio button. + + For the buttons to remain responsive you must keep a reference to this + object. + + Connect to the RadioButtons with the `.on_clicked` method. + + Attributes + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + activecolor : color + The color of the selected button. + labels : list of `.Text` + The button labels. + circles : list of `~.patches.Circle` + The buttons. + value_selected : str + The label text of the currently selected button. + """ + + def __init__(self, ax, labels, active=0, activecolor=None, *, + useblit=True, label_props=None, radio_props=None): + """ + Add radio buttons to an `~.axes.Axes`. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The Axes to add the buttons to. + labels : list of str + The button labels. + active : int + The index of the initially selected button. + activecolor : color + The color of the selected button. The default is ``'blue'`` if not + specified here or in *radio_props*. + useblit : bool, default: True + Use blitting for faster drawing if supported by the backend. + See the tutorial :ref:`blitting` for details. + + .. versionadded:: 3.7 + + label_props : dict or list of dict, optional + Dictionary of `.Text` properties to be used for the labels. + + .. versionadded:: 3.7 + radio_props : dict, optional + Dictionary of scatter `.Collection` properties to be used for the + radio buttons. Defaults to (label font size / 2)**2 size, black + edgecolor, and *activecolor* facecolor (when active). + + .. note:: + If a facecolor is supplied in *radio_props*, it will override + *activecolor*. This may be used to provide an active color per + button. + + .. versionadded:: 3.7 + """ + super().__init__(ax) + + _api.check_isinstance((dict, None), label_props=label_props, + radio_props=radio_props) + + radio_props = cbook.normalize_kwargs(radio_props, + collections.PathCollection) + if activecolor is not None: + if 'facecolor' in radio_props: + _api.warn_external( + 'Both the *activecolor* parameter and the *facecolor* ' + 'key in the *radio_props* parameter has been specified. ' + '*activecolor* will be ignored.') + else: + activecolor = 'blue' # Default. + + self._activecolor = activecolor + self.value_selected = labels[active] + + ax.set_xticks([]) + ax.set_yticks([]) + ax.set_navigate(False) + + ys = np.linspace(1, 0, len(labels) + 2)[1:-1] + + self._useblit = useblit and self.canvas.supports_blit + self._background = None + + label_props = _expand_text_props(label_props) + self.labels = [ + ax.text(0.25, y, label, transform=ax.transAxes, + horizontalalignment="left", verticalalignment="center", + **props) + for y, label, props in zip(ys, labels, label_props)] + text_size = np.array([text.get_fontsize() for text in self.labels]) / 2 + + radio_props = { + 's': text_size**2, + **radio_props, + 'marker': 'o', + 'transform': ax.transAxes, + 'animated': self._useblit, + } + radio_props.setdefault('edgecolor', radio_props.get('color', 'black')) + radio_props.setdefault('facecolor', + radio_props.pop('color', activecolor)) + self._buttons = ax.scatter([.15] * len(ys), ys, **radio_props) + # The user may have passed custom colours in radio_props, so we need to + # create the radios, and modify the visibility after getting whatever + # the user set. + self._active_colors = self._buttons.get_facecolor() + if len(self._active_colors) == 1: + self._active_colors = np.repeat(self._active_colors, len(labels), + axis=0) + self._buttons.set_facecolor( + [activecolor if i == active else "none" + for i, activecolor in enumerate(self._active_colors)]) + + self.connect_event('button_press_event', self._clicked) + if self._useblit: + self.connect_event('draw_event', self._clear) + + self._observers = cbook.CallbackRegistry(signals=["clicked"]) + + def _clear(self, event): + """Internal event handler to clear the buttons.""" + if self.ignore(event) or self._changed_canvas(): + return + self._background = self.canvas.copy_from_bbox(self.ax.bbox) + self.ax.draw_artist(self._buttons) + if hasattr(self, "_circles"): + for circle in self._circles: + self.ax.draw_artist(circle) + + def _clicked(self, event): + if self.ignore(event) or event.button != 1 or not self.ax.contains(event)[0]: + return + pclicked = self.ax.transAxes.inverted().transform((event.x, event.y)) + _, inds = self._buttons.contains(event) + coords = self._buttons.get_offset_transform().transform( + self._buttons.get_offsets()) + distances = {} + if hasattr(self, "_circles"): # Remove once circles is removed. + for i, (p, t) in enumerate(zip(self._circles, self.labels)): + if (t.get_window_extent().contains(event.x, event.y) + or np.linalg.norm(pclicked - p.center) < p.radius): + distances[i] = np.linalg.norm(pclicked - p.center) + else: + for i, t in enumerate(self.labels): + if (i in inds["ind"] + or t.get_window_extent().contains(event.x, event.y)): + distances[i] = np.linalg.norm(pclicked - coords[i]) + if len(distances) > 0: + closest = min(distances, key=distances.get) + self.set_active(closest) + + def set_label_props(self, props): + """ + Set properties of the `.Text` labels. + + .. versionadded:: 3.7 + + Parameters + ---------- + props : dict + Dictionary of `.Text` properties to be used for the labels. + """ + _api.check_isinstance(dict, props=props) + props = _expand_text_props(props) + for text, prop in zip(self.labels, props): + text.update(prop) + + def set_radio_props(self, props): + """ + Set properties of the `.Text` labels. + + .. versionadded:: 3.7 + + Parameters + ---------- + props : dict + Dictionary of `.Collection` properties to be used for the radio + buttons. + """ + _api.check_isinstance(dict, props=props) + if 's' in props: # Keep API consistent with constructor. + props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels)) + self._buttons.update(props) + self._active_colors = self._buttons.get_facecolor() + if len(self._active_colors) == 1: + self._active_colors = np.repeat(self._active_colors, + len(self.labels), axis=0) + self._buttons.set_facecolor( + [activecolor if text.get_text() == self.value_selected else "none" + for text, activecolor in zip(self.labels, self._active_colors)]) + + @property + def activecolor(self): + return self._activecolor + + @activecolor.setter + def activecolor(self, activecolor): + colors._check_color_like(activecolor=activecolor) + self._activecolor = activecolor + self.set_radio_props({'facecolor': activecolor}) + # Make sure the deprecated version is updated. + # Remove once circles is removed. + labels = [label.get_text() for label in self.labels] + with cbook._setattr_cm(self, eventson=False): + self.set_active(labels.index(self.value_selected)) + + def set_active(self, index): + """ + Select button with number *index*. + + Callbacks will be triggered if :attr:`eventson` is True. + """ + if index not in range(len(self.labels)): + raise ValueError(f'Invalid RadioButton index: {index}') + self.value_selected = self.labels[index].get_text() + button_facecolors = self._buttons.get_facecolor() + button_facecolors[:] = colors.to_rgba("none") + button_facecolors[index] = colors.to_rgba(self._active_colors[index]) + self._buttons.set_facecolor(button_facecolors) + if hasattr(self, "_circles"): # Remove once circles is removed. + for i, p in enumerate(self._circles): + p.set_facecolor(self.activecolor if i == index else "none") + if self.drawon and self._useblit: + self.ax.draw_artist(p) + if self.drawon: + if self._useblit: + if self._background is not None: + self.canvas.restore_region(self._background) + self.ax.draw_artist(self._buttons) + if hasattr(self, "_circles"): + for p in self._circles: + self.ax.draw_artist(p) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw() + + if self.eventson: + self._observers.process('clicked', self.labels[index].get_text()) + + def on_clicked(self, func): + """ + Connect the callback function *func* to button click events. + + Returns a connection id, which can be used to disconnect the callback. + """ + return self._observers.connect('clicked', func) + + def disconnect(self, cid): + """Remove the observer with connection id *cid*.""" + self._observers.disconnect(cid) + + @_api.deprecated("3.7", + addendum="Any custom property styling may be lost.") + @property + def circles(self): + if not hasattr(self, "_circles"): + radius = min(.5 / (len(self.labels) + 1) - .01, .05) + circles = self._circles = [ + Circle(xy=self._buttons.get_offsets()[i], edgecolor="black", + facecolor=self._buttons.get_facecolor()[i], + radius=radius, transform=self.ax.transAxes, + animated=self._useblit) + for i in range(len(self.labels))] + self._buttons.set_visible(False) + for circle in circles: + self.ax.add_patch(circle) + return self._circles + + +class SubplotTool(Widget): + """ + A tool to adjust the subplot params of a `.Figure`. + """ + + def __init__(self, targetfig, toolfig): + """ + Parameters + ---------- + targetfig : `~matplotlib.figure.Figure` + The figure instance to adjust. + toolfig : `~matplotlib.figure.Figure` + The figure instance to embed the subplot tool into. + """ + + self.figure = toolfig + self.targetfig = targetfig + toolfig.subplots_adjust(left=0.2, right=0.9) + toolfig.suptitle("Click on slider to adjust subplot param") + + self._sliders = [] + names = ["left", "bottom", "right", "top", "wspace", "hspace"] + # The last subplot, removed below, keeps space for the "Reset" button. + for name, ax in zip(names, toolfig.subplots(len(names) + 1)): + ax.set_navigate(False) + slider = Slider(ax, name, 0, 1, + valinit=getattr(targetfig.subplotpars, name)) + slider.on_changed(self._on_slider_changed) + self._sliders.append(slider) + toolfig.axes[-1].remove() + (self.sliderleft, self.sliderbottom, self.sliderright, self.slidertop, + self.sliderwspace, self.sliderhspace) = self._sliders + for slider in [self.sliderleft, self.sliderbottom, + self.sliderwspace, self.sliderhspace]: + slider.closedmax = False + for slider in [self.sliderright, self.slidertop]: + slider.closedmin = False + + # constraints + self.sliderleft.slidermax = self.sliderright + self.sliderright.slidermin = self.sliderleft + self.sliderbottom.slidermax = self.slidertop + self.slidertop.slidermin = self.sliderbottom + + bax = toolfig.add_axes([0.8, 0.05, 0.15, 0.075]) + self.buttonreset = Button(bax, 'Reset') + self.buttonreset.on_clicked(self._on_reset) + + def _on_slider_changed(self, _): + self.targetfig.subplots_adjust( + **{slider.label.get_text(): slider.val + for slider in self._sliders}) + if self.drawon: + self.targetfig.canvas.draw() + + def _on_reset(self, event): + with ExitStack() as stack: + # Temporarily disable drawing on self and self's sliders, and + # disconnect slider events (as the subplotparams can be temporarily + # invalid, depending on the order in which they are restored). + stack.enter_context(cbook._setattr_cm(self, drawon=False)) + for slider in self._sliders: + stack.enter_context( + cbook._setattr_cm(slider, drawon=False, eventson=False)) + # Reset the slider to the initial position. + for slider in self._sliders: + slider.reset() + if self.drawon: + event.canvas.draw() # Redraw the subplottool canvas. + self._on_slider_changed(None) # Apply changes to the target window. + + +class Cursor(AxesWidget): + """ + A crosshair cursor that spans the Axes and moves with mouse cursor. + + For the cursor to remain responsive you must keep a reference to it. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The `~.axes.Axes` to attach the cursor to. + horizOn : bool, default: True + Whether to draw the horizontal line. + vertOn : bool, default: True + Whether to draw the vertical line. + useblit : bool, default: False + Use blitting for faster drawing if supported by the backend. + See the tutorial :ref:`blitting` for details. + + Other Parameters + ---------------- + **lineprops + `.Line2D` properties that control the appearance of the lines. + See also `~.Axes.axhline`. + + Examples + -------- + See :doc:`/gallery/widgets/cursor`. + """ + @_api.make_keyword_only("3.7", "horizOn") + def __init__(self, ax, horizOn=True, vertOn=True, useblit=False, + **lineprops): + super().__init__(ax) + + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('draw_event', self.clear) + + self.visible = True + self.horizOn = horizOn + self.vertOn = vertOn + self.useblit = useblit and self.canvas.supports_blit + + if self.useblit: + lineprops['animated'] = True + self.lineh = ax.axhline(ax.get_ybound()[0], visible=False, **lineprops) + self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops) + + self.background = None + self.needclear = False + + def clear(self, event): + """Internal event handler to clear the cursor.""" + if self.ignore(event) or self._changed_canvas(): + return + if self.useblit: + self.background = self.canvas.copy_from_bbox(self.ax.bbox) + + def onmove(self, event): + """Internal event handler to draw the cursor when the mouse moves.""" + if self.ignore(event): + return + if not self.canvas.widgetlock.available(self): + return + if not self.ax.contains(event)[0]: + self.linev.set_visible(False) + self.lineh.set_visible(False) + + if self.needclear: + self.canvas.draw() + self.needclear = False + return + self.needclear = True + + xdata, ydata = self._get_data_coords(event) + self.linev.set_xdata((xdata, xdata)) + self.linev.set_visible(self.visible and self.vertOn) + self.lineh.set_ydata((ydata, ydata)) + self.lineh.set_visible(self.visible and self.horizOn) + + if self.visible and (self.vertOn or self.horizOn): + self._update() + + def _update(self): + if self.useblit: + if self.background is not None: + self.canvas.restore_region(self.background) + self.ax.draw_artist(self.linev) + self.ax.draw_artist(self.lineh) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw_idle() + return False + + +class MultiCursor(Widget): + """ + Provide a vertical (default) and/or horizontal line cursor shared between + multiple Axes. + + For the cursor to remain responsive you must keep a reference to it. + + Parameters + ---------- + canvas : object + This parameter is entirely unused and only kept for back-compatibility. + + axes : list of `~matplotlib.axes.Axes` + The `~.axes.Axes` to attach the cursor to. + + useblit : bool, default: True + Use blitting for faster drawing if supported by the backend. + See the tutorial :ref:`blitting` + for details. + + horizOn : bool, default: False + Whether to draw the horizontal line. + + vertOn : bool, default: True + Whether to draw the vertical line. + + Other Parameters + ---------------- + **lineprops + `.Line2D` properties that control the appearance of the lines. + See also `~.Axes.axhline`. + + Examples + -------- + See :doc:`/gallery/widgets/multicursor`. + """ + + def __init__(self, canvas, axes, *, useblit=True, horizOn=False, vertOn=True, + **lineprops): + # canvas is stored only to provide the deprecated .canvas attribute; + # once it goes away the unused argument won't need to be stored at all. + self._canvas = canvas + + self.axes = axes + self.horizOn = horizOn + self.vertOn = vertOn + + self._canvas_infos = { + ax.figure.canvas: {"cids": [], "background": None} for ax in axes} + + xmin, xmax = axes[-1].get_xlim() + ymin, ymax = axes[-1].get_ylim() + xmid = 0.5 * (xmin + xmax) + ymid = 0.5 * (ymin + ymax) + + self.visible = True + self.useblit = ( + useblit + and all(canvas.supports_blit for canvas in self._canvas_infos)) + + if self.useblit: + lineprops['animated'] = True + + self.vlines = [ax.axvline(xmid, visible=False, **lineprops) + for ax in axes] + self.hlines = [ax.axhline(ymid, visible=False, **lineprops) + for ax in axes] + + self.connect() + + needclear = _api.deprecated("3.7")(lambda self: False) + + def connect(self): + """Connect events.""" + for canvas, info in self._canvas_infos.items(): + info["cids"] = [ + canvas.mpl_connect('motion_notify_event', self.onmove), + canvas.mpl_connect('draw_event', self.clear), + ] + + def disconnect(self): + """Disconnect events.""" + for canvas, info in self._canvas_infos.items(): + for cid in info["cids"]: + canvas.mpl_disconnect(cid) + info["cids"].clear() + + def clear(self, event): + """Clear the cursor.""" + if self.ignore(event): + return + if self.useblit: + for canvas, info in self._canvas_infos.items(): + # someone has switched the canvas on us! This happens if + # `savefig` needs to save to a format the previous backend did + # not support (e.g. saving a figure using an Agg based backend + # saved to a vector format). + if canvas is not canvas.figure.canvas: + continue + info["background"] = canvas.copy_from_bbox(canvas.figure.bbox) + + def onmove(self, event): + axs = [ax for ax in self.axes if ax.contains(event)[0]] + if self.ignore(event) or not axs or not event.canvas.widgetlock.available(self): + return + ax = cbook._topmost_artist(axs) + xdata, ydata = ((event.xdata, event.ydata) if event.inaxes is ax + else ax.transData.inverted().transform((event.x, event.y))) + for line in self.vlines: + line.set_xdata((xdata, xdata)) + line.set_visible(self.visible and self.vertOn) + for line in self.hlines: + line.set_ydata((ydata, ydata)) + line.set_visible(self.visible and self.horizOn) + if self.visible and (self.vertOn or self.horizOn): + self._update() + + def _update(self): + if self.useblit: + for canvas, info in self._canvas_infos.items(): + if info["background"]: + canvas.restore_region(info["background"]) + if self.vertOn: + for ax, line in zip(self.axes, self.vlines): + ax.draw_artist(line) + if self.horizOn: + for ax, line in zip(self.axes, self.hlines): + ax.draw_artist(line) + for canvas in self._canvas_infos: + canvas.blit() + else: + for canvas in self._canvas_infos: + canvas.draw_idle() + + +class _SelectorWidget(AxesWidget): + + def __init__(self, ax, onselect, useblit=False, button=None, + state_modifier_keys=None, use_data_coordinates=False): + super().__init__(ax) + + self._visible = True + self.onselect = onselect + self.useblit = useblit and self.canvas.supports_blit + self.connect_default_events() + + self._state_modifier_keys = dict(move=' ', clear='escape', + square='shift', center='control', + rotate='r') + self._state_modifier_keys.update(state_modifier_keys or {}) + self._use_data_coordinates = use_data_coordinates + + self.background = None + + if isinstance(button, Integral): + self.validButtons = [button] + else: + self.validButtons = button + + # Set to True when a selection is completed, otherwise is False + self._selection_completed = False + + # will save the data (position at mouseclick) + self._eventpress = None + # will save the data (pos. at mouserelease) + self._eventrelease = None + self._prev_event = None + self._state = set() + + def set_active(self, active): + super().set_active(active) + if active: + self.update_background(None) + + def _get_animated_artists(self): + """ + Convenience method to get all animated artists of the figure containing + this widget, excluding those already present in self.artists. + The returned tuple is not sorted by 'z_order': z_order sorting is + valid only when considering all artists and not only a subset of all + artists. + """ + return tuple(a for ax_ in self.ax.get_figure().get_axes() + for a in ax_.get_children() + if a.get_animated() and a not in self.artists) + + def update_background(self, event): + """Force an update of the background.""" + # If you add a call to `ignore` here, you'll want to check edge case: + # `release` can call a draw event even when `ignore` is True. + if not self.useblit: + return + # Make sure that widget artists don't get accidentally included in the + # background, by re-rendering the background if needed (and then + # re-re-rendering the canvas with the visible widget artists). + # We need to remove all artists which will be drawn when updating + # the selector: if we have animated artists in the figure, it is safer + # to redrawn by default, in case they have updated by the callback + # zorder needs to be respected when redrawing + artists = sorted(self.artists + self._get_animated_artists(), + key=lambda a: a.get_zorder()) + needs_redraw = any(artist.get_visible() for artist in artists) + with ExitStack() as stack: + if needs_redraw: + for artist in artists: + stack.enter_context(artist._cm_set(visible=False)) + self.canvas.draw() + self.background = self.canvas.copy_from_bbox(self.ax.bbox) + if needs_redraw: + for artist in artists: + self.ax.draw_artist(artist) + + def connect_default_events(self): + """Connect the major canvas events to methods.""" + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('button_press_event', self.press) + self.connect_event('button_release_event', self.release) + self.connect_event('draw_event', self.update_background) + self.connect_event('key_press_event', self.on_key_press) + self.connect_event('key_release_event', self.on_key_release) + self.connect_event('scroll_event', self.on_scroll) + + def ignore(self, event): + # docstring inherited + if not self.active or not self.ax.get_visible(): + return True + # If canvas was locked + if not self.canvas.widgetlock.available(self): + return True + if not hasattr(event, 'button'): + event.button = None + # Only do rectangle selection if event was triggered + # with a desired button + if (self.validButtons is not None + and event.button not in self.validButtons): + return True + # If no button was pressed yet ignore the event if it was out of the Axes. + if self._eventpress is None: + return not self.ax.contains(event)[0] + # If a button was pressed, check if the release-button is the same. + if event.button == self._eventpress.button: + return False + # If a button was pressed, check if the release-button is the same. + return (not self.ax.contains(event)[0] or + event.button != self._eventpress.button) + + def update(self): + """Draw using blit() or draw_idle(), depending on ``self.useblit``.""" + if (not self.ax.get_visible() or + self.ax.figure._get_renderer() is None): + return + if self.useblit: + if self.background is not None: + self.canvas.restore_region(self.background) + else: + self.update_background(None) + # We need to draw all artists, which are not included in the + # background, therefore we also draw self._get_animated_artists() + # and we make sure that we respect z_order + artists = sorted(self.artists + self._get_animated_artists(), + key=lambda a: a.get_zorder()) + for artist in artists: + self.ax.draw_artist(artist) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw_idle() + + def _get_data(self, event): + """Get the xdata and ydata for event, with limits.""" + if event.xdata is None: + return None, None + xdata, ydata = self._get_data_coords(event) + xdata = np.clip(xdata, *self.ax.get_xbound()) + ydata = np.clip(ydata, *self.ax.get_ybound()) + return xdata, ydata + + def _clean_event(self, event): + """ + Preprocess an event: + + - Replace *event* by the previous event if *event* has no ``xdata``. + - Get ``xdata`` and ``ydata`` from this widget's axes, and clip them to the axes + limits. + - Update the previous event. + """ + if event.xdata is None: + event = self._prev_event + else: + event = copy.copy(event) + event.xdata, event.ydata = self._get_data(event) + self._prev_event = event + return event + + def press(self, event): + """Button press handler and validator.""" + if not self.ignore(event): + event = self._clean_event(event) + self._eventpress = event + self._prev_event = event + key = event.key or '' + key = key.replace('ctrl', 'control') + # move state is locked in on a button press + if key == self._state_modifier_keys['move']: + self._state.add('move') + self._press(event) + return True + return False + + def _press(self, event): + """Button press event handler.""" + + def release(self, event): + """Button release event handler and validator.""" + if not self.ignore(event) and self._eventpress: + event = self._clean_event(event) + self._eventrelease = event + self._release(event) + self._eventpress = None + self._eventrelease = None + self._state.discard('move') + return True + return False + + def _release(self, event): + """Button release event handler.""" + + def onmove(self, event): + """Cursor move event handler and validator.""" + if not self.ignore(event) and self._eventpress: + event = self._clean_event(event) + self._onmove(event) + return True + return False + + def _onmove(self, event): + """Cursor move event handler.""" + + def on_scroll(self, event): + """Mouse scroll event handler and validator.""" + if not self.ignore(event): + self._on_scroll(event) + + def _on_scroll(self, event): + """Mouse scroll event handler.""" + + def on_key_press(self, event): + """Key press event handler and validator for all selection widgets.""" + if self.active: + key = event.key or '' + key = key.replace('ctrl', 'control') + if key == self._state_modifier_keys['clear']: + self.clear() + return + for (state, modifier) in self._state_modifier_keys.items(): + if modifier in key.split('+'): + # 'rotate' is changing _state on press and is not removed + # from _state when releasing + if state == 'rotate': + if state in self._state: + self._state.discard(state) + else: + self._state.add(state) + else: + self._state.add(state) + self._on_key_press(event) + + def _on_key_press(self, event): + """Key press event handler - for widget-specific key press actions.""" + + def on_key_release(self, event): + """Key release event handler and validator.""" + if self.active: + key = event.key or '' + for (state, modifier) in self._state_modifier_keys.items(): + # 'rotate' is changing _state on press and is not removed + # from _state when releasing + if modifier in key.split('+') and state != 'rotate': + self._state.discard(state) + self._on_key_release(event) + + def _on_key_release(self, event): + """Key release event handler.""" + + def set_visible(self, visible): + """Set the visibility of the selector artists.""" + self._visible = visible + for artist in self.artists: + artist.set_visible(visible) + + def get_visible(self): + """Get the visibility of the selector artists.""" + return self._visible + + @property + def visible(self): + _api.warn_deprecated("3.8", alternative="get_visible") + return self.get_visible() + + def clear(self): + """Clear the selection and set the selector ready to make a new one.""" + self._clear_without_update() + self.update() + + def _clear_without_update(self): + self._selection_completed = False + self.set_visible(False) + + @property + def artists(self): + """Tuple of the artists of the selector.""" + handles_artists = getattr(self, '_handles_artists', ()) + return (self._selection_artist,) + handles_artists + + def set_props(self, **props): + """ + Set the properties of the selector artist. + + See the *props* argument in the selector docstring to know which properties are + supported. + """ + artist = self._selection_artist + props = cbook.normalize_kwargs(props, artist) + artist.set(**props) + if self.useblit: + self.update() + + def set_handle_props(self, **handle_props): + """ + Set the properties of the handles selector artist. See the + `handle_props` argument in the selector docstring to know which + properties are supported. + """ + if not hasattr(self, '_handles_artists'): + raise NotImplementedError("This selector doesn't have handles.") + + artist = self._handles_artists[0] + handle_props = cbook.normalize_kwargs(handle_props, artist) + for handle in self._handles_artists: + handle.set(**handle_props) + if self.useblit: + self.update() + self._handle_props.update(handle_props) + + def _validate_state(self, state): + supported_state = [ + key for key, value in self._state_modifier_keys.items() + if key != 'clear' and value != 'not-applicable' + ] + _api.check_in_list(supported_state, state=state) + + def add_state(self, state): + """ + Add a state to define the widget's behavior. See the + `state_modifier_keys` parameters for details. + + Parameters + ---------- + state : str + Must be a supported state of the selector. See the + `state_modifier_keys` parameters for details. + + Raises + ------ + ValueError + When the state is not supported by the selector. + + """ + self._validate_state(state) + self._state.add(state) + + def remove_state(self, state): + """ + Remove a state to define the widget's behavior. See the + `state_modifier_keys` parameters for details. + + Parameters + ---------- + state : str + Must be a supported state of the selector. See the + `state_modifier_keys` parameters for details. + + Raises + ------ + ValueError + When the state is not supported by the selector. + + """ + self._validate_state(state) + self._state.remove(state) + + +class SpanSelector(_SelectorWidget): + """ + Visually select a min/max range on a single axis and call a function with + those values. + + To guarantee that the selector remains responsive, keep a reference to it. + + In order to turn off the SpanSelector, set ``span_selector.active`` to + False. To turn it back on, set it to True. + + Press and release events triggered at the same coordinates outside the + selection will clear the selector, except when + ``ignore_event_outside=True``. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + + onselect : callable with signature ``func(min: float, max: float)`` + A callback function that is called after a release event and the + selection is created, changed or removed. + + direction : {"horizontal", "vertical"} + The direction along which to draw the span selector. + + minspan : float, default: 0 + If selection is less than or equal to *minspan*, the selection is + removed (when already existing) or cancelled. + + useblit : bool, default: False + If True, use the backend-dependent blitting features for faster + canvas updates. See the tutorial :ref:`blitting` for details. + + props : dict, default: {'facecolor': 'red', 'alpha': 0.5} + Dictionary of `.Patch` properties. + + onmove_callback : callable with signature ``func(min: float, max: float)``, optional + Called on mouse move while the span is being selected. + + interactive : bool, default: False + Whether to draw a set of handles that allow interaction with the + widget after it is drawn. + + button : `.MouseButton` or list of `.MouseButton`, default: all buttons + The mouse buttons which activate the span selector. + + handle_props : dict, default: None + Properties of the handle lines at the edges of the span. Only used + when *interactive* is True. See `.Line2D` for valid properties. + + grab_range : float, default: 10 + Distance in pixels within which the interactive tool handles can be activated. + + state_modifier_keys : dict, optional + Keyboard modifiers which affect the widget's behavior. Values + amend the defaults, which are: + + - "clear": Clear the current shape, default: "escape". + + drag_from_anywhere : bool, default: False + If `True`, the widget can be moved by clicking anywhere within its bounds. + + ignore_event_outside : bool, default: False + If `True`, the event triggered outside the span selector will be ignored. + + snap_values : 1D array-like, optional + Snap the selector edges to the given values. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> import matplotlib.widgets as mwidgets + >>> fig, ax = plt.subplots() + >>> ax.plot([1, 2, 3], [10, 50, 100]) + >>> def onselect(vmin, vmax): + ... print(vmin, vmax) + >>> span = mwidgets.SpanSelector(ax, onselect, 'horizontal', + ... props=dict(facecolor='blue', alpha=0.5)) + >>> fig.show() + + See also: :doc:`/gallery/widgets/span_selector` + """ + + @_api.make_keyword_only("3.7", name="minspan") + def __init__(self, ax, onselect, direction, minspan=0, useblit=False, + props=None, onmove_callback=None, interactive=False, + button=None, handle_props=None, grab_range=10, + state_modifier_keys=None, drag_from_anywhere=False, + ignore_event_outside=False, snap_values=None): + + if state_modifier_keys is None: + state_modifier_keys = dict(clear='escape', + square='not-applicable', + center='not-applicable', + rotate='not-applicable') + super().__init__(ax, onselect, useblit=useblit, button=button, + state_modifier_keys=state_modifier_keys) + + if props is None: + props = dict(facecolor='red', alpha=0.5) + + props['animated'] = self.useblit + + self.direction = direction + self._extents_on_press = None + self.snap_values = snap_values + + self.onmove_callback = onmove_callback + self.minspan = minspan + + self.grab_range = grab_range + self._interactive = interactive + self._edge_handles = None + self.drag_from_anywhere = drag_from_anywhere + self.ignore_event_outside = ignore_event_outside + + # Reset canvas so that `new_axes` connects events. + self.canvas = None + self.new_axes(ax, _props=props) + + # Setup handles + self._handle_props = { + 'color': props.get('facecolor', 'r'), + **cbook.normalize_kwargs(handle_props, Line2D)} + + if self._interactive: + self._edge_order = ['min', 'max'] + self._setup_edge_handles(self._handle_props) + + self._active_handle = None + + def new_axes(self, ax, *, _props=None): + """Set SpanSelector to operate on a new Axes.""" + self.ax = ax + if self.canvas is not ax.figure.canvas: + if self.canvas is not None: + self.disconnect_events() + + self.canvas = ax.figure.canvas + self.connect_default_events() + + # Reset + self._selection_completed = False + + if self.direction == 'horizontal': + trans = ax.get_xaxis_transform() + w, h = 0, 1 + else: + trans = ax.get_yaxis_transform() + w, h = 1, 0 + rect_artist = Rectangle((0, 0), w, h, transform=trans, visible=False) + if _props is not None: + rect_artist.update(_props) + elif self._selection_artist is not None: + rect_artist.update_from(self._selection_artist) + + self.ax.add_patch(rect_artist) + self._selection_artist = rect_artist + + def _setup_edge_handles(self, props): + # Define initial position using the axis bounds to keep the same bounds + if self.direction == 'horizontal': + positions = self.ax.get_xbound() + else: + positions = self.ax.get_ybound() + self._edge_handles = ToolLineHandles(self.ax, positions, + direction=self.direction, + line_props=props, + useblit=self.useblit) + + @property + def _handles_artists(self): + if self._edge_handles is not None: + return self._edge_handles.artists + else: + return () + + def _set_cursor(self, enabled): + """Update the canvas cursor based on direction of the selector.""" + if enabled: + cursor = (backend_tools.Cursors.RESIZE_HORIZONTAL + if self.direction == 'horizontal' else + backend_tools.Cursors.RESIZE_VERTICAL) + else: + cursor = backend_tools.Cursors.POINTER + + self.ax.figure.canvas.set_cursor(cursor) + + def connect_default_events(self): + # docstring inherited + super().connect_default_events() + if getattr(self, '_interactive', False): + self.connect_event('motion_notify_event', self._hover) + + def _press(self, event): + """Button press event handler.""" + self._set_cursor(True) + if self._interactive and self._selection_artist.get_visible(): + self._set_active_handle(event) + else: + self._active_handle = None + + if self._active_handle is None or not self._interactive: + # Clear previous rectangle before drawing new rectangle. + self.update() + + xdata, ydata = self._get_data_coords(event) + v = xdata if self.direction == 'horizontal' else ydata + + if self._active_handle is None and not self.ignore_event_outside: + # when the press event outside the span, we initially set the + # visibility to False and extents to (v, v) + # update will be called when setting the extents + self._visible = False + self.extents = v, v + # We need to set the visibility back, so the span selector will be + # drawn when necessary (span width > 0) + self._visible = True + else: + self.set_visible(True) + + return False + + @property + def direction(self): + """Direction of the span selector: 'vertical' or 'horizontal'.""" + return self._direction + + @direction.setter + def direction(self, direction): + """Set the direction of the span selector.""" + _api.check_in_list(['horizontal', 'vertical'], direction=direction) + if hasattr(self, '_direction') and direction != self._direction: + # remove previous artists + self._selection_artist.remove() + if self._interactive: + self._edge_handles.remove() + self._direction = direction + self.new_axes(self.ax) + if self._interactive: + self._setup_edge_handles(self._handle_props) + else: + self._direction = direction + + def _release(self, event): + """Button release event handler.""" + self._set_cursor(False) + + if not self._interactive: + self._selection_artist.set_visible(False) + + if (self._active_handle is None and self._selection_completed and + self.ignore_event_outside): + return + + vmin, vmax = self.extents + span = vmax - vmin + + if span <= self.minspan: + # Remove span and set self._selection_completed = False + self.set_visible(False) + if self._selection_completed: + # Call onselect, only when the span is already existing + self.onselect(vmin, vmax) + self._selection_completed = False + else: + self.onselect(vmin, vmax) + self._selection_completed = True + + self.update() + + self._active_handle = None + + return False + + def _hover(self, event): + """Update the canvas cursor if it's over a handle.""" + if self.ignore(event): + return + + if self._active_handle is not None or not self._selection_completed: + # Do nothing if button is pressed and a handle is active, which may + # occur with drag_from_anywhere=True. + # Do nothing if selection is not completed, which occurs when + # a selector has been cleared + return + + _, e_dist = self._edge_handles.closest(event.x, event.y) + self._set_cursor(e_dist <= self.grab_range) + + def _onmove(self, event): + """Motion notify event handler.""" + + xdata, ydata = self._get_data_coords(event) + if self.direction == 'horizontal': + v = xdata + vpress = self._eventpress.xdata + else: + v = ydata + vpress = self._eventpress.ydata + + # move existing span + # When "dragging from anywhere", `self._active_handle` is set to 'C' + # (match notation used in the RectangleSelector) + if self._active_handle == 'C' and self._extents_on_press is not None: + vmin, vmax = self._extents_on_press + dv = v - vpress + vmin += dv + vmax += dv + + # resize an existing shape + elif self._active_handle and self._active_handle != 'C': + vmin, vmax = self._extents_on_press + if self._active_handle == 'min': + vmin = v + else: + vmax = v + # new shape + else: + # Don't create a new span if there is already one when + # ignore_event_outside=True + if self.ignore_event_outside and self._selection_completed: + return + vmin, vmax = vpress, v + if vmin > vmax: + vmin, vmax = vmax, vmin + + self.extents = vmin, vmax + + if self.onmove_callback is not None: + self.onmove_callback(vmin, vmax) + + return False + + def _draw_shape(self, vmin, vmax): + if vmin > vmax: + vmin, vmax = vmax, vmin + if self.direction == 'horizontal': + self._selection_artist.set_x(vmin) + self._selection_artist.set_width(vmax - vmin) + else: + self._selection_artist.set_y(vmin) + self._selection_artist.set_height(vmax - vmin) + + def _set_active_handle(self, event): + """Set active handle based on the location of the mouse event.""" + # Note: event.xdata/ydata in data coordinates, event.x/y in pixels + e_idx, e_dist = self._edge_handles.closest(event.x, event.y) + + # Prioritise center handle over other handles + # Use 'C' to match the notation used in the RectangleSelector + if 'move' in self._state: + self._active_handle = 'C' + elif e_dist > self.grab_range: + # Not close to any handles + self._active_handle = None + if self.drag_from_anywhere and self._contains(event): + # Check if we've clicked inside the region + self._active_handle = 'C' + self._extents_on_press = self.extents + else: + self._active_handle = None + return + else: + # Closest to an edge handle + self._active_handle = self._edge_order[e_idx] + + # Save coordinates of rectangle at the start of handle movement. + self._extents_on_press = self.extents + + def _contains(self, event): + """Return True if event is within the patch.""" + return self._selection_artist.contains(event, radius=0)[0] + + @staticmethod + def _snap(values, snap_values): + """Snap values to a given array values (snap_values).""" + # take into account machine precision + eps = np.min(np.abs(np.diff(snap_values))) * 1e-12 + return tuple( + snap_values[np.abs(snap_values - v + np.sign(v) * eps).argmin()] + for v in values) + + @property + def extents(self): + """Return extents of the span selector.""" + if self.direction == 'horizontal': + vmin = self._selection_artist.get_x() + vmax = vmin + self._selection_artist.get_width() + else: + vmin = self._selection_artist.get_y() + vmax = vmin + self._selection_artist.get_height() + return vmin, vmax + + @extents.setter + def extents(self, extents): + # Update displayed shape + if self.snap_values is not None: + extents = tuple(self._snap(extents, self.snap_values)) + self._draw_shape(*extents) + if self._interactive: + # Update displayed handles + self._edge_handles.set_data(self.extents) + self.set_visible(self._visible) + self.update() + + +class ToolLineHandles: + """ + Control handles for canvas tools. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + Matplotlib Axes where tool handles are displayed. + positions : 1D array + Positions of handles in data coordinates. + direction : {"horizontal", "vertical"} + Direction of handles, either 'vertical' or 'horizontal' + line_props : dict, optional + Additional line properties. See `.Line2D`. + useblit : bool, default: True + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + """ + + @_api.make_keyword_only("3.7", "line_props") + def __init__(self, ax, positions, direction, line_props=None, + useblit=True): + self.ax = ax + + _api.check_in_list(['horizontal', 'vertical'], direction=direction) + self._direction = direction + + line_props = { + **(line_props if line_props is not None else {}), + 'visible': False, + 'animated': useblit, + } + + line_fun = ax.axvline if self.direction == 'horizontal' else ax.axhline + + self._artists = [line_fun(p, **line_props) for p in positions] + + @property + def artists(self): + return tuple(self._artists) + + @property + def positions(self): + """Positions of the handle in data coordinates.""" + method = 'get_xdata' if self.direction == 'horizontal' else 'get_ydata' + return [getattr(line, method)()[0] for line in self.artists] + + @property + def direction(self): + """Direction of the handle: 'vertical' or 'horizontal'.""" + return self._direction + + def set_data(self, positions): + """ + Set x- or y-positions of handles, depending on if the lines are + vertical or horizontal. + + Parameters + ---------- + positions : tuple of length 2 + Set the positions of the handle in data coordinates + """ + method = 'set_xdata' if self.direction == 'horizontal' else 'set_ydata' + for line, p in zip(self.artists, positions): + getattr(line, method)([p, p]) + + def set_visible(self, value): + """Set the visibility state of the handles artist.""" + for artist in self.artists: + artist.set_visible(value) + + def set_animated(self, value): + """Set the animated state of the handles artist.""" + for artist in self.artists: + artist.set_animated(value) + + def remove(self): + """Remove the handles artist from the figure.""" + for artist in self._artists: + artist.remove() + + def closest(self, x, y): + """ + Return index and pixel distance to closest handle. + + Parameters + ---------- + x, y : float + x, y position from which the distance will be calculated to + determinate the closest handle + + Returns + ------- + index, distance : index of the handle and its distance from + position x, y + """ + if self.direction == 'horizontal': + p_pts = np.array([ + self.ax.transData.transform((p, 0))[0] for p in self.positions + ]) + dist = abs(p_pts - x) + else: + p_pts = np.array([ + self.ax.transData.transform((0, p))[1] for p in self.positions + ]) + dist = abs(p_pts - y) + index = np.argmin(dist) + return index, dist[index] + + +class ToolHandles: + """ + Control handles for canvas tools. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + Matplotlib Axes where tool handles are displayed. + x, y : 1D arrays + Coordinates of control handles. + marker : str, default: 'o' + Shape of marker used to display handle. See `~.pyplot.plot`. + marker_props : dict, optional + Additional marker properties. See `.Line2D`. + useblit : bool, default: True + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + """ + + @_api.make_keyword_only("3.7", "marker") + def __init__(self, ax, x, y, marker='o', marker_props=None, useblit=True): + self.ax = ax + props = {'marker': marker, 'markersize': 7, 'markerfacecolor': 'w', + 'linestyle': 'none', 'alpha': 0.5, 'visible': False, + 'label': '_nolegend_', + **cbook.normalize_kwargs(marker_props, Line2D._alias_map)} + self._markers = Line2D(x, y, animated=useblit, **props) + self.ax.add_line(self._markers) + + @property + def x(self): + return self._markers.get_xdata() + + @property + def y(self): + return self._markers.get_ydata() + + @property + def artists(self): + return (self._markers, ) + + def set_data(self, pts, y=None): + """Set x and y positions of handles.""" + if y is not None: + x = pts + pts = np.array([x, y]) + self._markers.set_data(pts) + + def set_visible(self, val): + self._markers.set_visible(val) + + def set_animated(self, val): + self._markers.set_animated(val) + + def closest(self, x, y): + """Return index and pixel distance to closest index.""" + pts = np.column_stack([self.x, self.y]) + # Transform data coordinates to pixel coordinates. + pts = self.ax.transData.transform(pts) + diff = pts - [x, y] + dist = np.hypot(*diff.T) + min_index = np.argmin(dist) + return min_index, dist[min_index] + + +_RECTANGLESELECTOR_PARAMETERS_DOCSTRING = \ + r""" + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The parent axes for the widget. + + onselect : function + A callback function that is called after a release event and the + selection is created, changed or removed. + It must have the signature:: + + def onselect(eclick: MouseEvent, erelease: MouseEvent) + + where *eclick* and *erelease* are the mouse click and release + `.MouseEvent`\s that start and complete the selection. + + minspanx : float, default: 0 + Selections with an x-span less than or equal to *minspanx* are removed + (when already existing) or cancelled. + + minspany : float, default: 0 + Selections with an y-span less than or equal to *minspanx* are removed + (when already existing) or cancelled. + + useblit : bool, default: False + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + + props : dict, optional + Properties with which the __ARTIST_NAME__ is drawn. See + `.Patch` for valid properties. + Default: + + ``dict(facecolor='red', edgecolor='black', alpha=0.2, fill=True)`` + + spancoords : {"data", "pixels"}, default: "data" + Whether to interpret *minspanx* and *minspany* in data or in pixel + coordinates. + + button : `.MouseButton`, list of `.MouseButton`, default: all buttons + Button(s) that trigger rectangle selection. + + grab_range : float, default: 10 + Distance in pixels within which the interactive tool handles can be + activated. + + handle_props : dict, optional + Properties with which the interactive handles (marker artists) are + drawn. See the marker arguments in `.Line2D` for valid + properties. Default values are defined in ``mpl.rcParams`` except for + the default value of ``markeredgecolor`` which will be the same as the + ``edgecolor`` property in *props*. + + interactive : bool, default: False + Whether to draw a set of handles that allow interaction with the + widget after it is drawn. + + state_modifier_keys : dict, optional + Keyboard modifiers which affect the widget's behavior. Values + amend the defaults, which are: + + - "move": Move the existing shape, default: no modifier. + - "clear": Clear the current shape, default: "escape". + - "square": Make the shape square, default: "shift". + - "center": change the shape around its center, default: "ctrl". + - "rotate": Rotate the shape around its center between -45° and 45°, + default: "r". + + "square" and "center" can be combined. The square shape can be defined + in data or display coordinates as determined by the + ``use_data_coordinates`` argument specified when creating the selector. + + drag_from_anywhere : bool, default: False + If `True`, the widget can be moved by clicking anywhere within + its bounds. + + ignore_event_outside : bool, default: False + If `True`, the event triggered outside the span selector will be + ignored. + + use_data_coordinates : bool, default: False + If `True`, the "square" shape of the selector is defined in + data coordinates instead of display coordinates. + """ + + +@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace( + '__ARTIST_NAME__', 'rectangle')) +class RectangleSelector(_SelectorWidget): + """ + Select a rectangular region of an Axes. + + For the cursor to remain responsive you must keep a reference to it. + + Press and release events triggered at the same coordinates outside the + selection will clear the selector, except when + ``ignore_event_outside=True``. + + %s + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> import matplotlib.widgets as mwidgets + >>> fig, ax = plt.subplots() + >>> ax.plot([1, 2, 3], [10, 50, 100]) + >>> def onselect(eclick, erelease): + ... print(eclick.xdata, eclick.ydata) + ... print(erelease.xdata, erelease.ydata) + >>> props = dict(facecolor='blue', alpha=0.5) + >>> rect = mwidgets.RectangleSelector(ax, onselect, interactive=True, + ... props=props) + >>> fig.show() + >>> rect.add_state('square') + + See also: :doc:`/gallery/widgets/rectangle_selector` + """ + + def __init__(self, ax, onselect, *, minspanx=0, minspany=0, useblit=False, + props=None, spancoords='data', button=None, grab_range=10, + handle_props=None, interactive=False, + state_modifier_keys=None, drag_from_anywhere=False, + ignore_event_outside=False, use_data_coordinates=False): + super().__init__(ax, onselect, useblit=useblit, button=button, + state_modifier_keys=state_modifier_keys, + use_data_coordinates=use_data_coordinates) + + self._interactive = interactive + self.drag_from_anywhere = drag_from_anywhere + self.ignore_event_outside = ignore_event_outside + self._rotation = 0.0 + self._aspect_ratio_correction = 1.0 + + # State to allow the option of an interactive selector that can't be + # interactively drawn. This is used in PolygonSelector as an + # interactive bounding box to allow the polygon to be easily resized + self._allow_creation = True + + if props is None: + props = dict(facecolor='red', edgecolor='black', + alpha=0.2, fill=True) + props = {**props, 'animated': self.useblit} + self._visible = props.pop('visible', self._visible) + to_draw = self._init_shape(**props) + self.ax.add_patch(to_draw) + + self._selection_artist = to_draw + self._set_aspect_ratio_correction() + + self.minspanx = minspanx + self.minspany = minspany + + _api.check_in_list(['data', 'pixels'], spancoords=spancoords) + self.spancoords = spancoords + + self.grab_range = grab_range + + if self._interactive: + self._handle_props = { + 'markeredgecolor': (props or {}).get('edgecolor', 'black'), + **cbook.normalize_kwargs(handle_props, Line2D)} + + self._corner_order = ['SW', 'SE', 'NE', 'NW'] + xc, yc = self.corners + self._corner_handles = ToolHandles(self.ax, xc, yc, + marker_props=self._handle_props, + useblit=self.useblit) + + self._edge_order = ['W', 'S', 'E', 'N'] + xe, ye = self.edge_centers + self._edge_handles = ToolHandles(self.ax, xe, ye, marker='s', + marker_props=self._handle_props, + useblit=self.useblit) + + xc, yc = self.center + self._center_handle = ToolHandles(self.ax, [xc], [yc], marker='s', + marker_props=self._handle_props, + useblit=self.useblit) + + self._active_handle = None + + self._extents_on_press = None + + @property + def _handles_artists(self): + return (*self._center_handle.artists, *self._corner_handles.artists, + *self._edge_handles.artists) + + def _init_shape(self, **props): + return Rectangle((0, 0), 0, 1, visible=False, + rotation_point='center', **props) + + def _press(self, event): + """Button press event handler.""" + # make the drawn box/line visible get the click-coordinates, button, ... + if self._interactive and self._selection_artist.get_visible(): + self._set_active_handle(event) + else: + self._active_handle = None + + if ((self._active_handle is None or not self._interactive) and + self._allow_creation): + # Clear previous rectangle before drawing new rectangle. + self.update() + + if (self._active_handle is None and not self.ignore_event_outside and + self._allow_creation): + x, y = self._get_data_coords(event) + self._visible = False + self.extents = x, x, y, y + self._visible = True + else: + self.set_visible(True) + + self._extents_on_press = self.extents + self._rotation_on_press = self._rotation + self._set_aspect_ratio_correction() + + return False + + def _release(self, event): + """Button release event handler.""" + if not self._interactive: + self._selection_artist.set_visible(False) + + if (self._active_handle is None and self._selection_completed and + self.ignore_event_outside): + return + + # update the eventpress and eventrelease with the resulting extents + x0, x1, y0, y1 = self.extents + self._eventpress.xdata = x0 + self._eventpress.ydata = y0 + xy0 = self.ax.transData.transform([x0, y0]) + self._eventpress.x, self._eventpress.y = xy0 + + self._eventrelease.xdata = x1 + self._eventrelease.ydata = y1 + xy1 = self.ax.transData.transform([x1, y1]) + self._eventrelease.x, self._eventrelease.y = xy1 + + # calculate dimensions of box or line + if self.spancoords == 'data': + spanx = abs(self._eventpress.xdata - self._eventrelease.xdata) + spany = abs(self._eventpress.ydata - self._eventrelease.ydata) + elif self.spancoords == 'pixels': + spanx = abs(self._eventpress.x - self._eventrelease.x) + spany = abs(self._eventpress.y - self._eventrelease.y) + else: + _api.check_in_list(['data', 'pixels'], + spancoords=self.spancoords) + # check if drawn distance (if it exists) is not too small in + # either x or y-direction + if spanx <= self.minspanx or spany <= self.minspany: + if self._selection_completed: + # Call onselect, only when the selection is already existing + self.onselect(self._eventpress, self._eventrelease) + self._clear_without_update() + else: + self.onselect(self._eventpress, self._eventrelease) + self._selection_completed = True + + self.update() + self._active_handle = None + self._extents_on_press = None + + return False + + def _onmove(self, event): + """ + Motion notify event handler. + + This can do one of four things: + - Translate + - Rotate + - Re-size + - Continue the creation of a new shape + """ + eventpress = self._eventpress + # The calculations are done for rotation at zero: we apply inverse + # transformation to events except when we rotate and move + state = self._state + rotate = 'rotate' in state and self._active_handle in self._corner_order + move = self._active_handle == 'C' + resize = self._active_handle and not move + + xdata, ydata = self._get_data_coords(event) + if resize: + inv_tr = self._get_rotation_transform().inverted() + xdata, ydata = inv_tr.transform([xdata, ydata]) + eventpress.xdata, eventpress.ydata = inv_tr.transform( + (eventpress.xdata, eventpress.ydata)) + + dx = xdata - eventpress.xdata + dy = ydata - eventpress.ydata + # refmax is used when moving the corner handle with the square state + # and is the maximum between refx and refy + refmax = None + if self._use_data_coordinates: + refx, refy = dx, dy + else: + # Get dx/dy in display coordinates + refx = event.x - eventpress.x + refy = event.y - eventpress.y + + x0, x1, y0, y1 = self._extents_on_press + # rotate an existing shape + if rotate: + # calculate angle abc + a = (eventpress.xdata, eventpress.ydata) + b = self.center + c = (xdata, ydata) + angle = (np.arctan2(c[1]-b[1], c[0]-b[0]) - + np.arctan2(a[1]-b[1], a[0]-b[0])) + self.rotation = np.rad2deg(self._rotation_on_press + angle) + + elif resize: + size_on_press = [x1 - x0, y1 - y0] + center = (x0 + size_on_press[0] / 2, y0 + size_on_press[1] / 2) + + # Keeping the center fixed + if 'center' in state: + # hh, hw are half-height and half-width + if 'square' in state: + # when using a corner, find which reference to use + if self._active_handle in self._corner_order: + refmax = max(refx, refy, key=abs) + if self._active_handle in ['E', 'W'] or refmax == refx: + hw = xdata - center[0] + hh = hw / self._aspect_ratio_correction + else: + hh = ydata - center[1] + hw = hh * self._aspect_ratio_correction + else: + hw = size_on_press[0] / 2 + hh = size_on_press[1] / 2 + # cancel changes in perpendicular direction + if self._active_handle in ['E', 'W'] + self._corner_order: + hw = abs(xdata - center[0]) + if self._active_handle in ['N', 'S'] + self._corner_order: + hh = abs(ydata - center[1]) + + x0, x1, y0, y1 = (center[0] - hw, center[0] + hw, + center[1] - hh, center[1] + hh) + + else: + # change sign of relative changes to simplify calculation + # Switch variables so that x1 and/or y1 are updated on move + if 'W' in self._active_handle: + x0 = x1 + if 'S' in self._active_handle: + y0 = y1 + if self._active_handle in ['E', 'W'] + self._corner_order: + x1 = xdata + if self._active_handle in ['N', 'S'] + self._corner_order: + y1 = ydata + if 'square' in state: + # when using a corner, find which reference to use + if self._active_handle in self._corner_order: + refmax = max(refx, refy, key=abs) + if self._active_handle in ['E', 'W'] or refmax == refx: + sign = np.sign(ydata - y0) + y1 = y0 + sign * abs(x1 - x0) / self._aspect_ratio_correction + else: + sign = np.sign(xdata - x0) + x1 = x0 + sign * abs(y1 - y0) * self._aspect_ratio_correction + + elif move: + x0, x1, y0, y1 = self._extents_on_press + dx = xdata - eventpress.xdata + dy = ydata - eventpress.ydata + x0 += dx + x1 += dx + y0 += dy + y1 += dy + + else: + # Create a new shape + self._rotation = 0 + # Don't create a new rectangle if there is already one when + # ignore_event_outside=True + if ((self.ignore_event_outside and self._selection_completed) or + not self._allow_creation): + return + center = [eventpress.xdata, eventpress.ydata] + dx = (xdata - center[0]) / 2 + dy = (ydata - center[1]) / 2 + + # square shape + if 'square' in state: + refmax = max(refx, refy, key=abs) + if refmax == refx: + dy = np.sign(dy) * abs(dx) / self._aspect_ratio_correction + else: + dx = np.sign(dx) * abs(dy) * self._aspect_ratio_correction + + # from center + if 'center' in state: + dx *= 2 + dy *= 2 + + # from corner + else: + center[0] += dx + center[1] += dy + + x0, x1, y0, y1 = (center[0] - dx, center[0] + dx, + center[1] - dy, center[1] + dy) + + self.extents = x0, x1, y0, y1 + + @property + def _rect_bbox(self): + return self._selection_artist.get_bbox().bounds + + def _set_aspect_ratio_correction(self): + aspect_ratio = self.ax._get_aspect_ratio() + self._selection_artist._aspect_ratio_correction = aspect_ratio + if self._use_data_coordinates: + self._aspect_ratio_correction = 1 + else: + self._aspect_ratio_correction = aspect_ratio + + def _get_rotation_transform(self): + aspect_ratio = self.ax._get_aspect_ratio() + return Affine2D().translate(-self.center[0], -self.center[1]) \ + .scale(1, aspect_ratio) \ + .rotate(self._rotation) \ + .scale(1, 1 / aspect_ratio) \ + .translate(*self.center) + + @property + def corners(self): + """ + Corners of rectangle in data coordinates from lower left, + moving clockwise. + """ + x0, y0, width, height = self._rect_bbox + xc = x0, x0 + width, x0 + width, x0 + yc = y0, y0, y0 + height, y0 + height + transform = self._get_rotation_transform() + coords = transform.transform(np.array([xc, yc]).T).T + return coords[0], coords[1] + + @property + def edge_centers(self): + """ + Midpoint of rectangle edges in data coordinates from left, + moving anti-clockwise. + """ + x0, y0, width, height = self._rect_bbox + w = width / 2. + h = height / 2. + xe = x0, x0 + w, x0 + width, x0 + w + ye = y0 + h, y0, y0 + h, y0 + height + transform = self._get_rotation_transform() + coords = transform.transform(np.array([xe, ye]).T).T + return coords[0], coords[1] + + @property + def center(self): + """Center of rectangle in data coordinates.""" + x0, y0, width, height = self._rect_bbox + return x0 + width / 2., y0 + height / 2. + + @property + def extents(self): + """ + Return (xmin, xmax, ymin, ymax) in data coordinates as defined by the + bounding box before rotation. + """ + x0, y0, width, height = self._rect_bbox + xmin, xmax = sorted([x0, x0 + width]) + ymin, ymax = sorted([y0, y0 + height]) + return xmin, xmax, ymin, ymax + + @extents.setter + def extents(self, extents): + # Update displayed shape + self._draw_shape(extents) + if self._interactive: + # Update displayed handles + self._corner_handles.set_data(*self.corners) + self._edge_handles.set_data(*self.edge_centers) + x, y = self.center + self._center_handle.set_data([x], [y]) + self.set_visible(self._visible) + self.update() + + @property + def rotation(self): + """ + Rotation in degree in interval [-45°, 45°]. The rotation is limited in + range to keep the implementation simple. + """ + return np.rad2deg(self._rotation) + + @rotation.setter + def rotation(self, value): + # Restrict to a limited range of rotation [-45°, 45°] to avoid changing + # order of handles + if -45 <= value and value <= 45: + self._rotation = np.deg2rad(value) + # call extents setter to draw shape and update handles positions + self.extents = self.extents + + def _draw_shape(self, extents): + x0, x1, y0, y1 = extents + xmin, xmax = sorted([x0, x1]) + ymin, ymax = sorted([y0, y1]) + xlim = sorted(self.ax.get_xlim()) + ylim = sorted(self.ax.get_ylim()) + + xmin = max(xlim[0], xmin) + ymin = max(ylim[0], ymin) + xmax = min(xmax, xlim[1]) + ymax = min(ymax, ylim[1]) + + self._selection_artist.set_x(xmin) + self._selection_artist.set_y(ymin) + self._selection_artist.set_width(xmax - xmin) + self._selection_artist.set_height(ymax - ymin) + self._selection_artist.set_angle(self.rotation) + + def _set_active_handle(self, event): + """Set active handle based on the location of the mouse event.""" + # Note: event.xdata/ydata in data coordinates, event.x/y in pixels + c_idx, c_dist = self._corner_handles.closest(event.x, event.y) + e_idx, e_dist = self._edge_handles.closest(event.x, event.y) + m_idx, m_dist = self._center_handle.closest(event.x, event.y) + + if 'move' in self._state: + self._active_handle = 'C' + # Set active handle as closest handle, if mouse click is close enough. + elif m_dist < self.grab_range * 2: + # Prioritise center handle over other handles + self._active_handle = 'C' + elif c_dist > self.grab_range and e_dist > self.grab_range: + # Not close to any handles + if self.drag_from_anywhere and self._contains(event): + # Check if we've clicked inside the region + self._active_handle = 'C' + else: + self._active_handle = None + return + elif c_dist < e_dist: + # Closest to a corner handle + self._active_handle = self._corner_order[c_idx] + else: + # Closest to an edge handle + self._active_handle = self._edge_order[e_idx] + + def _contains(self, event): + """Return True if event is within the patch.""" + return self._selection_artist.contains(event, radius=0)[0] + + @property + def geometry(self): + """ + Return an array of shape (2, 5) containing the + x (``RectangleSelector.geometry[1, :]``) and + y (``RectangleSelector.geometry[0, :]``) data coordinates of the four + corners of the rectangle starting and ending in the top left corner. + """ + if hasattr(self._selection_artist, 'get_verts'): + xfm = self.ax.transData.inverted() + y, x = xfm.transform(self._selection_artist.get_verts()).T + return np.array([x, y]) + else: + return np.array(self._selection_artist.get_data()) + + +@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace( + '__ARTIST_NAME__', 'ellipse')) +class EllipseSelector(RectangleSelector): + """ + Select an elliptical region of an Axes. + + For the cursor to remain responsive you must keep a reference to it. + + Press and release events triggered at the same coordinates outside the + selection will clear the selector, except when + ``ignore_event_outside=True``. + + %s + + Examples + -------- + :doc:`/gallery/widgets/rectangle_selector` + """ + def _init_shape(self, **props): + return Ellipse((0, 0), 0, 1, visible=False, **props) + + def _draw_shape(self, extents): + x0, x1, y0, y1 = extents + xmin, xmax = sorted([x0, x1]) + ymin, ymax = sorted([y0, y1]) + center = [x0 + (x1 - x0) / 2., y0 + (y1 - y0) / 2.] + a = (xmax - xmin) / 2. + b = (ymax - ymin) / 2. + + self._selection_artist.center = center + self._selection_artist.width = 2 * a + self._selection_artist.height = 2 * b + self._selection_artist.angle = self.rotation + + @property + def _rect_bbox(self): + x, y = self._selection_artist.center + width = self._selection_artist.width + height = self._selection_artist.height + return x - width / 2., y - height / 2., width, height + + +class LassoSelector(_SelectorWidget): + """ + Selection curve of an arbitrary shape. + + For the selector to remain responsive you must keep a reference to it. + + The selected path can be used in conjunction with `~.Path.contains_point` + to select data points from an image. + + In contrast to `Lasso`, `LassoSelector` is written with an interface + similar to `RectangleSelector` and `SpanSelector`, and will continue to + interact with the Axes until disconnected. + + Example usage:: + + ax = plt.subplot() + ax.plot(x, y) + + def onselect(verts): + print(verts) + lasso = LassoSelector(ax, onselect) + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + onselect : function + Whenever the lasso is released, the *onselect* function is called and + passed the vertices of the selected path. + useblit : bool, default: True + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + props : dict, optional + Properties with which the line is drawn, see `.Line2D` + for valid properties. Default values are defined in ``mpl.rcParams``. + button : `.MouseButton` or list of `.MouseButton`, optional + The mouse buttons used for rectangle selection. Default is ``None``, + which corresponds to all buttons. + """ + + @_api.make_keyword_only("3.7", name="useblit") + def __init__(self, ax, onselect, useblit=True, props=None, button=None): + super().__init__(ax, onselect, useblit=useblit, button=button) + self.verts = None + props = { + **(props if props is not None else {}), + # Note that self.useblit may be != useblit, if the canvas doesn't + # support blitting. + 'animated': self.useblit, 'visible': False, + } + line = Line2D([], [], **props) + self.ax.add_line(line) + self._selection_artist = line + + def _press(self, event): + self.verts = [self._get_data(event)] + self._selection_artist.set_visible(True) + + def _release(self, event): + if self.verts is not None: + self.verts.append(self._get_data(event)) + self.onselect(self.verts) + self._selection_artist.set_data([[], []]) + self._selection_artist.set_visible(False) + self.verts = None + + def _onmove(self, event): + if self.verts is None: + return + self.verts.append(self._get_data(event)) + self._selection_artist.set_data(list(zip(*self.verts))) + + self.update() + + +class PolygonSelector(_SelectorWidget): + """ + Select a polygon region of an Axes. + + Place vertices with each mouse click, and make the selection by completing + the polygon (clicking on the first vertex). Once drawn individual vertices + can be moved by clicking and dragging with the left mouse button, or + removed by clicking the right mouse button. + + In addition, the following modifier keys can be used: + + - Hold *ctrl* and click and drag a vertex to reposition it before the + polygon has been completed. + - Hold the *shift* key and click and drag anywhere in the Axes to move + all vertices. + - Press the *esc* key to start a new polygon. + + For the selector to remain responsive you must keep a reference to it. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + + onselect : function + When a polygon is completed or modified after completion, + the *onselect* function is called and passed a list of the vertices as + ``(xdata, ydata)`` tuples. + + useblit : bool, default: False + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + + props : dict, optional + Properties with which the line is drawn, see `.Line2D` for valid properties. + Default:: + + dict(color='k', linestyle='-', linewidth=2, alpha=0.5) + + handle_props : dict, optional + Artist properties for the markers drawn at the vertices of the polygon. + See the marker arguments in `.Line2D` for valid + properties. Default values are defined in ``mpl.rcParams`` except for + the default value of ``markeredgecolor`` which will be the same as the + ``color`` property in *props*. + + grab_range : float, default: 10 + A vertex is selected (to complete the polygon or to move a vertex) if + the mouse click is within *grab_range* pixels of the vertex. + + draw_bounding_box : bool, optional + If `True`, a bounding box will be drawn around the polygon selector + once it is complete. This box can be used to move and resize the + selector. + + box_handle_props : dict, optional + Properties to set for the box handles. See the documentation for the + *handle_props* argument to `RectangleSelector` for more info. + + box_props : dict, optional + Properties to set for the box. See the documentation for the *props* + argument to `RectangleSelector` for more info. + + Examples + -------- + :doc:`/gallery/widgets/polygon_selector_simple` + :doc:`/gallery/widgets/polygon_selector_demo` + + Notes + ----- + If only one point remains after removing points, the selector reverts to an + incomplete state and you can start drawing a new polygon from the existing + point. + """ + + @_api.make_keyword_only("3.7", name="useblit") + def __init__(self, ax, onselect, useblit=False, + props=None, handle_props=None, grab_range=10, *, + draw_bounding_box=False, box_handle_props=None, + box_props=None): + # The state modifiers 'move', 'square', and 'center' are expected by + # _SelectorWidget but are not supported by PolygonSelector + # Note: could not use the existing 'move' state modifier in-place of + # 'move_all' because _SelectorWidget automatically discards 'move' + # from the state on button release. + state_modifier_keys = dict(clear='escape', move_vertex='control', + move_all='shift', move='not-applicable', + square='not-applicable', + center='not-applicable', + rotate='not-applicable') + super().__init__(ax, onselect, useblit=useblit, + state_modifier_keys=state_modifier_keys) + + self._xys = [(0, 0)] + + if props is None: + props = dict(color='k', linestyle='-', linewidth=2, alpha=0.5) + props = {**props, 'animated': self.useblit} + self._selection_artist = line = Line2D([], [], **props) + self.ax.add_line(line) + + if handle_props is None: + handle_props = dict(markeredgecolor='k', + markerfacecolor=props.get('color', 'k')) + self._handle_props = handle_props + self._polygon_handles = ToolHandles(self.ax, [], [], + useblit=self.useblit, + marker_props=self._handle_props) + + self._active_handle_idx = -1 + self.grab_range = grab_range + + self.set_visible(True) + self._draw_box = draw_bounding_box + self._box = None + + if box_handle_props is None: + box_handle_props = {} + self._box_handle_props = self._handle_props.update(box_handle_props) + self._box_props = box_props + + def _get_bbox(self): + return self._selection_artist.get_bbox() + + def _add_box(self): + self._box = RectangleSelector(self.ax, + onselect=lambda *args, **kwargs: None, + useblit=self.useblit, + grab_range=self.grab_range, + handle_props=self._box_handle_props, + props=self._box_props, + interactive=True) + self._box._state_modifier_keys.pop('rotate') + self._box.connect_event('motion_notify_event', self._scale_polygon) + self._update_box() + # Set state that prevents the RectangleSelector from being created + # by the user + self._box._allow_creation = False + self._box._selection_completed = True + self._draw_polygon() + + def _remove_box(self): + if self._box is not None: + self._box.set_visible(False) + self._box = None + + def _update_box(self): + # Update selection box extents to the extents of the polygon + if self._box is not None: + bbox = self._get_bbox() + self._box.extents = [bbox.x0, bbox.x1, bbox.y0, bbox.y1] + # Save a copy + self._old_box_extents = self._box.extents + + def _scale_polygon(self, event): + """ + Scale the polygon selector points when the bounding box is moved or + scaled. + + This is set as a callback on the bounding box RectangleSelector. + """ + if not self._selection_completed: + return + + if self._old_box_extents == self._box.extents: + return + + # Create transform from old box to new box + x1, y1, w1, h1 = self._box._rect_bbox + old_bbox = self._get_bbox() + t = (transforms.Affine2D() + .translate(-old_bbox.x0, -old_bbox.y0) + .scale(1 / old_bbox.width, 1 / old_bbox.height) + .scale(w1, h1) + .translate(x1, y1)) + + # Update polygon verts. Must be a list of tuples for consistency. + new_verts = [(x, y) for x, y in t.transform(np.array(self.verts))] + self._xys = [*new_verts, new_verts[0]] + self._draw_polygon() + self._old_box_extents = self._box.extents + + @property + def _handles_artists(self): + return self._polygon_handles.artists + + def _remove_vertex(self, i): + """Remove vertex with index i.""" + if (len(self._xys) > 2 and + self._selection_completed and + i in (0, len(self._xys) - 1)): + # If selecting the first or final vertex, remove both first and + # last vertex as they are the same for a closed polygon + self._xys.pop(0) + self._xys.pop(-1) + # Close the polygon again by appending the new first vertex to the + # end + self._xys.append(self._xys[0]) + else: + self._xys.pop(i) + if len(self._xys) <= 2: + # If only one point left, return to incomplete state to let user + # start drawing again + self._selection_completed = False + self._remove_box() + + def _press(self, event): + """Button press event handler.""" + # Check for selection of a tool handle. + if ((self._selection_completed or 'move_vertex' in self._state) + and len(self._xys) > 0): + h_idx, h_dist = self._polygon_handles.closest(event.x, event.y) + if h_dist < self.grab_range: + self._active_handle_idx = h_idx + # Save the vertex positions at the time of the press event (needed to + # support the 'move_all' state modifier). + self._xys_at_press = self._xys.copy() + + def _release(self, event): + """Button release event handler.""" + # Release active tool handle. + if self._active_handle_idx >= 0: + if event.button == 3: + self._remove_vertex(self._active_handle_idx) + self._draw_polygon() + self._active_handle_idx = -1 + + # Complete the polygon. + elif len(self._xys) > 3 and self._xys[-1] == self._xys[0]: + self._selection_completed = True + if self._draw_box and self._box is None: + self._add_box() + + # Place new vertex. + elif (not self._selection_completed + and 'move_all' not in self._state + and 'move_vertex' not in self._state): + self._xys.insert(-1, self._get_data_coords(event)) + + if self._selection_completed: + self.onselect(self.verts) + + def onmove(self, event): + """Cursor move event handler and validator.""" + # Method overrides _SelectorWidget.onmove because the polygon selector + # needs to process the move callback even if there is no button press. + # _SelectorWidget.onmove include logic to ignore move event if + # _eventpress is None. + if not self.ignore(event): + event = self._clean_event(event) + self._onmove(event) + return True + return False + + def _onmove(self, event): + """Cursor move event handler.""" + # Move the active vertex (ToolHandle). + if self._active_handle_idx >= 0: + idx = self._active_handle_idx + self._xys[idx] = self._get_data_coords(event) + # Also update the end of the polygon line if the first vertex is + # the active handle and the polygon is completed. + if idx == 0 and self._selection_completed: + self._xys[-1] = self._get_data_coords(event) + + # Move all vertices. + elif 'move_all' in self._state and self._eventpress: + xdata, ydata = self._get_data_coords(event) + dx = xdata - self._eventpress.xdata + dy = ydata - self._eventpress.ydata + for k in range(len(self._xys)): + x_at_press, y_at_press = self._xys_at_press[k] + self._xys[k] = x_at_press + dx, y_at_press + dy + + # Do nothing if completed or waiting for a move. + elif (self._selection_completed + or 'move_vertex' in self._state or 'move_all' in self._state): + return + + # Position pending vertex. + else: + # Calculate distance to the start vertex. + x0, y0 = \ + self._selection_artist.get_transform().transform(self._xys[0]) + v0_dist = np.hypot(x0 - event.x, y0 - event.y) + # Lock on to the start vertex if near it and ready to complete. + if len(self._xys) > 3 and v0_dist < self.grab_range: + self._xys[-1] = self._xys[0] + else: + self._xys[-1] = self._get_data_coords(event) + + self._draw_polygon() + + def _on_key_press(self, event): + """Key press event handler.""" + # Remove the pending vertex if entering the 'move_vertex' or + # 'move_all' mode + if (not self._selection_completed + and ('move_vertex' in self._state or + 'move_all' in self._state)): + self._xys.pop() + self._draw_polygon() + + def _on_key_release(self, event): + """Key release event handler.""" + # Add back the pending vertex if leaving the 'move_vertex' or + # 'move_all' mode (by checking the released key) + if (not self._selection_completed + and + (event.key == self._state_modifier_keys.get('move_vertex') + or event.key == self._state_modifier_keys.get('move_all'))): + self._xys.append(self._get_data_coords(event)) + self._draw_polygon() + # Reset the polygon if the released key is the 'clear' key. + elif event.key == self._state_modifier_keys.get('clear'): + event = self._clean_event(event) + self._xys = [self._get_data_coords(event)] + self._selection_completed = False + self._remove_box() + self.set_visible(True) + + def _draw_polygon_without_update(self): + """Redraw the polygon based on new vertex positions, no update().""" + xs, ys = zip(*self._xys) if self._xys else ([], []) + self._selection_artist.set_data(xs, ys) + self._update_box() + # Only show one tool handle at the start and end vertex of the polygon + # if the polygon is completed or the user is locked on to the start + # vertex. + if (self._selection_completed + or (len(self._xys) > 3 + and self._xys[-1] == self._xys[0])): + self._polygon_handles.set_data(xs[:-1], ys[:-1]) + else: + self._polygon_handles.set_data(xs, ys) + + def _draw_polygon(self): + """Redraw the polygon based on the new vertex positions.""" + self._draw_polygon_without_update() + self.update() + + @property + def verts(self): + """The polygon vertices, as a list of ``(x, y)`` pairs.""" + return self._xys[:-1] + + @verts.setter + def verts(self, xys): + """ + Set the polygon vertices. + + This will remove any preexisting vertices, creating a complete polygon + with the new vertices. + """ + self._xys = [*xys, xys[0]] + self._selection_completed = True + self.set_visible(True) + if self._draw_box and self._box is None: + self._add_box() + self._draw_polygon() + + def _clear_without_update(self): + self._selection_completed = False + self._xys = [(0, 0)] + self._draw_polygon_without_update() + + +class Lasso(AxesWidget): + """ + Selection curve of an arbitrary shape. + + The selected path can be used in conjunction with + `~matplotlib.path.Path.contains_point` to select data points from an image. + + Unlike `LassoSelector`, this must be initialized with a starting + point *xy*, and the `Lasso` events are destroyed upon release. + + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + The parent Axes for the widget. + xy : (float, float) + Coordinates of the start of the lasso. + callback : callable + Whenever the lasso is released, the *callback* function is called and + passed the vertices of the selected path. + useblit : bool, default: True + Whether to use blitting for faster drawing (if supported by the + backend). See the tutorial :ref:`blitting` + for details. + """ + + @_api.make_keyword_only("3.7", name="useblit") + def __init__(self, ax, xy, callback, useblit=True): + super().__init__(ax) + + self.useblit = useblit and self.canvas.supports_blit + if self.useblit: + self.background = self.canvas.copy_from_bbox(self.ax.bbox) + + x, y = xy + self.verts = [(x, y)] + self.line = Line2D([x], [y], linestyle='-', color='black', lw=2) + self.ax.add_line(self.line) + self.callback = callback + self.connect_event('button_release_event', self.onrelease) + self.connect_event('motion_notify_event', self.onmove) + + def onrelease(self, event): + if self.ignore(event): + return + if self.verts is not None: + self.verts.append(self._get_data_coords(event)) + if len(self.verts) > 2: + self.callback(self.verts) + self.line.remove() + self.verts = None + self.disconnect_events() + + def onmove(self, event): + if (self.ignore(event) + or self.verts is None + or event.button != 1 + or not self.ax.contains(event)[0]): + return + self.verts.append(self._get_data_coords(event)) + self.line.set_data(list(zip(*self.verts))) + + if self.useblit: + self.canvas.restore_region(self.background) + self.ax.draw_artist(self.line) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw_idle() diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.pyi new file mode 100644 index 00000000..00c2d0da --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/widgets.pyi @@ -0,0 +1,487 @@ +from .artist import Artist +from .axes import Axes +from .backend_bases import FigureCanvasBase, Event, MouseEvent, MouseButton +from .collections import LineCollection +from .figure import Figure +from .lines import Line2D +from .patches import Circle, Polygon, Rectangle +from .text import Text + +import PIL.Image + +from collections.abc import Callable, Collection, Iterable, Sequence +from typing import Any, Literal +from numpy.typing import ArrayLike +from .typing import ColorType +import numpy as np + +class LockDraw: + def __init__(self) -> None: ... + def __call__(self, o: Any) -> None: ... + def release(self, o: Any) -> None: ... + def available(self, o: Any) -> bool: ... + def isowner(self, o: Any) -> bool: ... + def locked(self) -> bool: ... + +class Widget: + drawon: bool + eventson: bool + active: bool + def set_active(self, active: bool) -> None: ... + def get_active(self) -> None: ... + def ignore(self, event) -> bool: ... + +class AxesWidget(Widget): + ax: Axes + canvas: FigureCanvasBase | None + def __init__(self, ax: Axes) -> None: ... + def connect_event(self, event: Event, callback: Callable) -> None: ... + def disconnect_events(self) -> None: ... + +class Button(AxesWidget): + label: Text + color: ColorType + hovercolor: ColorType + def __init__( + self, + ax: Axes, + label: str, + image: ArrayLike | PIL.Image.Image | None = ..., + color: ColorType = ..., + hovercolor: ColorType = ..., + *, + useblit: bool = ... + ) -> None: ... + def on_clicked(self, func: Callable[[Event], Any]) -> int: ... + def disconnect(self, cid: int) -> None: ... + +class SliderBase(AxesWidget): + orientation: Literal["horizontal", "vertical"] + closedmin: bool + closedmax: bool + valmin: float + valmax: float + valstep: float | ArrayLike | None + drag_active: bool + valfmt: str + def __init__( + self, + ax: Axes, + orientation: Literal["horizontal", "vertical"], + closedmin: bool, + closedmax: bool, + valmin: float, + valmax: float, + valfmt: str, + dragging: Slider | None, + valstep: float | ArrayLike | None, + ) -> None: ... + def disconnect(self, cid: int) -> None: ... + def reset(self) -> None: ... + +class Slider(SliderBase): + slidermin: Slider | None + slidermax: Slider | None + val: float + valinit: float + track: Rectangle + poly: Polygon + hline: Line2D + vline: Line2D + label: Text + valtext: Text + def __init__( + self, + ax: Axes, + label: str, + valmin: float, + valmax: float, + *, + valinit: float = ..., + valfmt: str | None = ..., + closedmin: bool = ..., + closedmax: bool = ..., + slidermin: Slider | None = ..., + slidermax: Slider | None = ..., + dragging: bool = ..., + valstep: float | ArrayLike | None = ..., + orientation: Literal["horizontal", "vertical"] = ..., + initcolor: ColorType = ..., + track_color: ColorType = ..., + handle_style: dict[str, Any] | None = ..., + **kwargs + ) -> None: ... + def set_val(self, val: float) -> None: ... + def on_changed(self, func: Callable[[float], Any]) -> int: ... + +class RangeSlider(SliderBase): + val: tuple[float, float] + valinit: tuple[float, float] + track: Rectangle + poly: Polygon + label: Text + valtext: Text + def __init__( + self, + ax: Axes, + label: str, + valmin: float, + valmax: float, + *, + valinit: tuple[float, float] | None = ..., + valfmt: str | None = ..., + closedmin: bool = ..., + closedmax: bool = ..., + dragging: bool = ..., + valstep: float | ArrayLike | None = ..., + orientation: Literal["horizontal", "vertical"] = ..., + track_color: ColorType = ..., + handle_style: dict[str, Any] | None = ..., + **kwargs + ) -> None: ... + def set_min(self, min: float) -> None: ... + def set_max(self, max: float) -> None: ... + def set_val(self, val: ArrayLike) -> None: ... + def on_changed(self, func: Callable[[tuple[float, float]], Any]) -> int: ... + +class CheckButtons(AxesWidget): + labels: list[Text] + def __init__( + self, + ax: Axes, + labels: Sequence[str], + actives: Iterable[bool] | None = ..., + *, + useblit: bool = ..., + label_props: dict[str, Any] | None = ..., + frame_props: dict[str, Any] | None = ..., + check_props: dict[str, Any] | None = ..., + ) -> None: ... + def set_label_props(self, props: dict[str, Any]) -> None: ... + def set_frame_props(self, props: dict[str, Any]) -> None: ... + def set_check_props(self, props: dict[str, Any]) -> None: ... + def set_active(self, index: int) -> None: ... + def get_status(self) -> list[bool]: ... + def on_clicked(self, func: Callable[[str], Any]) -> int: ... + def disconnect(self, cid: int) -> None: ... + @property + def lines(self) -> list[tuple[Line2D, Line2D]]: ... + @property + def rectangles(self) -> list[Rectangle]: ... + +class TextBox(AxesWidget): + label: Text + text_disp: Text + cursor_index: int + cursor: LineCollection + color: ColorType + hovercolor: ColorType + capturekeystrokes: bool + def __init__( + self, + ax: Axes, + label: str, + initial: str = ..., + *, + color: ColorType = ..., + hovercolor: ColorType = ..., + label_pad: float = ..., + textalignment: Literal["left", "center", "right"] = ..., + ) -> None: ... + @property + def text(self) -> str: ... + def set_val(self, val: str) -> None: ... + def begin_typing(self, x = ...) -> None: ... + def stop_typing(self) -> None: ... + def on_text_change(self, func: Callable[[str], Any]) -> int: ... + def on_submit(self, func: Callable[[str], Any]) -> int: ... + def disconnect(self, cid: int) -> None: ... + +class RadioButtons(AxesWidget): + activecolor: ColorType + value_selected: str + labels: list[Text] + def __init__( + self, + ax: Axes, + labels: Iterable[str], + active: int = ..., + activecolor: ColorType | None = ..., + *, + useblit: bool = ..., + label_props: dict[str, Any] | Sequence[dict[str, Any]] | None = ..., + radio_props: dict[str, Any] | None = ..., + ) -> None: ... + def set_label_props(self, props: dict[str, Any]) -> None: ... + def set_radio_props(self, props: dict[str, Any]) -> None: ... + def set_active(self, index: int) -> None: ... + def on_clicked(self, func: Callable[[str], Any]) -> int: ... + def disconnect(self, cid: int) -> None: ... + @property + def circles(self) -> list[Circle]: ... + +class SubplotTool(Widget): + figure: Figure + targetfig: Figure + buttonreset: Button + def __init__(self, targetfig: Figure, toolfig: Figure) -> None: ... + +class Cursor(AxesWidget): + visible: bool + horizOn: bool + vertOn: bool + useblit: bool + lineh: Line2D + linev: Line2D + background: Any + needclear: bool + def __init__( + self, + ax: Axes, + *, + horizOn: bool = ..., + vertOn: bool = ..., + useblit: bool = ..., + **lineprops + ) -> None: ... + def clear(self, event: Event) -> None: ... + def onmove(self, event: Event) -> None: ... + +class MultiCursor(Widget): + axes: Sequence[Axes] + horizOn: bool + vertOn: bool + visible: bool + useblit: bool + needclear: bool + vlines: list[Line2D] + hlines: list[Line2D] + def __init__( + self, + canvas: Any, + axes: Sequence[Axes], + *, + useblit: bool = ..., + horizOn: bool = ..., + vertOn: bool = ..., + **lineprops + ) -> None: ... + def connect(self) -> None: ... + def disconnect(self) -> None: ... + def clear(self, event: Event) -> None: ... + def onmove(self, event: Event) -> None: ... + +class _SelectorWidget(AxesWidget): + onselect: Callable[[float, float], Any] + useblit: bool + background: Any + validButtons: list[MouseButton] + def __init__( + self, + ax: Axes, + onselect: Callable[[float, float], Any], + useblit: bool = ..., + button: MouseButton | Collection[MouseButton] | None = ..., + state_modifier_keys: dict[str, str] | None = ..., + use_data_coordinates: bool = ..., + ) -> None: ... + def update_background(self, event: Event) -> None: ... + def connect_default_events(self) -> None: ... + def ignore(self, event: Event) -> bool: ... + def update(self) -> None: ... + def press(self, event: Event) -> bool: ... + def release(self, event: Event) -> bool: ... + def onmove(self, event: Event) -> bool: ... + def on_scroll(self, event: Event) -> None: ... + def on_key_press(self, event: Event) -> None: ... + def on_key_release(self, event: Event) -> None: ... + def set_visible(self, visible: bool) -> None: ... + def get_visible(self) -> bool: ... + @property + def visible(self) -> bool: ... + def clear(self) -> None: ... + @property + def artists(self) -> tuple[Artist]: ... + def set_props(self, **props) -> None: ... + def set_handle_props(self, **handle_props) -> None: ... + def add_state(self, state: str) -> None: ... + def remove_state(self, state: str) -> None: ... + +class SpanSelector(_SelectorWidget): + snap_values: ArrayLike | None + onmove_callback: Callable[[float, float], Any] + minspan: float + grab_range: float + drag_from_anywhere: bool + ignore_event_outside: bool + canvas: FigureCanvasBase | None + def __init__( + self, + ax: Axes, + onselect: Callable[[float, float], Any], + direction: Literal["horizontal", "vertical"], + *, + minspan: float = ..., + useblit: bool = ..., + props: dict[str, Any] | None = ..., + onmove_callback: Callable[[float, float], Any] | None = ..., + interactive: bool = ..., + button: MouseButton | Collection[MouseButton] | None = ..., + handle_props: dict[str, Any] | None = ..., + grab_range: float = ..., + state_modifier_keys: dict[str, str] | None = ..., + drag_from_anywhere: bool = ..., + ignore_event_outside: bool = ..., + snap_values: ArrayLike | None = ..., + ) -> None: ... + def new_axes(self, ax: Axes, *, _props: dict[str, Any] | None = ...) -> None: ... + def connect_default_events(self) -> None: ... + @property + def direction(self) -> Literal["horizontal", "vertical"]: ... + @direction.setter + def direction(self, direction: Literal["horizontal", "vertical"]) -> None: ... + @property + def extents(self) -> tuple[float, float]: ... + @extents.setter + def extents(self, extents: tuple[float, float]) -> None: ... + +class ToolLineHandles: + ax: Axes + def __init__( + self, + ax: Axes, + positions: ArrayLike, + direction: Literal["horizontal", "vertical"], + *, + line_props: dict[str, Any] | None = ..., + useblit: bool = ..., + ) -> None: ... + @property + def artists(self) -> tuple[Line2D]: ... + @property + def positions(self) -> list[float]: ... + @property + def direction(self) -> Literal["horizontal", "vertical"]: ... + def set_data(self, positions: ArrayLike) -> None: ... + def set_visible(self, value: bool) -> None: ... + def set_animated(self, value: bool) -> None: ... + def remove(self) -> None: ... + def closest(self, x: float, y: float) -> tuple[int, float]: ... + +class ToolHandles: + ax: Axes + def __init__( + self, + ax: Axes, + x: ArrayLike, + y: ArrayLike, + *, + marker: str = ..., + marker_props: dict[str, Any] | None = ..., + useblit: bool = ..., + ) -> None: ... + @property + def x(self) -> ArrayLike: ... + @property + def y(self) -> ArrayLike: ... + @property + def artists(self) -> tuple[Line2D]: ... + def set_data(self, pts: ArrayLike, y: ArrayLike | None = ...) -> None: ... + def set_visible(self, val: bool) -> None: ... + def set_animated(self, val: bool) -> None: ... + def closest(self, x: float, y: float) -> tuple[int, float]: ... + +class RectangleSelector(_SelectorWidget): + drag_from_anywhere: bool + ignore_event_outside: bool + minspanx: float + minspany: float + spancoords: Literal["data", "pixels"] + grab_range: float + def __init__( + self, + ax: Axes, + onselect: Callable[[MouseEvent, MouseEvent], Any], + *, + minspanx: float = ..., + minspany: float = ..., + useblit: bool = ..., + props: dict[str, Any] | None = ..., + spancoords: Literal["data", "pixels"] = ..., + button: MouseButton | Collection[MouseButton] | None = ..., + grab_range: float = ..., + handle_props: dict[str, Any] | None = ..., + interactive: bool = ..., + state_modifier_keys: dict[str, str] | None = ..., + drag_from_anywhere: bool = ..., + ignore_event_outside: bool = ..., + use_data_coordinates: bool = ..., + ) -> None: ... + @property + def corners(self) -> tuple[np.ndarray, np.ndarray]: ... + @property + def edge_centers(self) -> tuple[np.ndarray, np.ndarray]: ... + @property + def center(self) -> tuple[float, float]: ... + @property + def extents(self) -> tuple[float, float, float, float]: ... + @extents.setter + def extents(self, extents: tuple[float, float, float, float]) -> None: ... + @property + def rotation(self) -> float: ... + @rotation.setter + def rotation(self, value: float) -> None: ... + @property + def geometry(self) -> np.ndarray: ... + +class EllipseSelector(RectangleSelector): ... + +class LassoSelector(_SelectorWidget): + verts: None | list[tuple[float, float]] + def __init__( + self, + ax: Axes, + onselect: Callable[[list[tuple[float, float]]], Any], + *, + useblit: bool = ..., + props: dict[str, Any] | None = ..., + button: MouseButton | Collection[MouseButton] | None = ..., + ) -> None: ... + +class PolygonSelector(_SelectorWidget): + grab_range: float + def __init__( + self, + ax: Axes, + onselect: Callable[[ArrayLike, ArrayLike], Any], + *, + useblit: bool = ..., + props: dict[str, Any] | None = ..., + handle_props: dict[str, Any] | None = ..., + grab_range: float = ..., + draw_bounding_box: bool = ..., + box_handle_props: dict[str, Any] | None = ..., + box_props: dict[str, Any] | None = ... + ) -> None: ... + def onmove(self, event: Event) -> bool: ... + @property + def verts(self) -> list[tuple[float, float]]: ... + @verts.setter + def verts(self, xys: Sequence[tuple[float, float]]) -> None: ... + +class Lasso(AxesWidget): + useblit: bool + background: Any + verts: list[tuple[float, float]] | None + line: Line2D + callback: Callable[[list[tuple[float, float]]], Any] + def __init__( + self, + ax: Axes, + xy: tuple[float, float], + callback: Callable[[list[tuple[float, float]]], Any], + *, + useblit: bool = ..., + ) -> None: ... + def onrelease(self, event: Event) -> None: ... + def onmove(self, event: Event) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/__init__.py new file mode 100644 index 00000000..c5530248 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/__init__.py @@ -0,0 +1,10 @@ +from . import axes_size as Size +from .axes_divider import Divider, SubplotDivider, make_axes_locatable +from .axes_grid import AxesGrid, Grid, ImageGrid + +from .parasite_axes import host_subplot, host_axes + +__all__ = ["Size", + "Divider", "SubplotDivider", "make_axes_locatable", + "AxesGrid", "Grid", "ImageGrid", + "host_subplot", "host_axes"] diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/anchored_artists.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/anchored_artists.py new file mode 100644 index 00000000..1238310b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/anchored_artists.py @@ -0,0 +1,462 @@ +from matplotlib import _api, transforms +from matplotlib.offsetbox import (AnchoredOffsetbox, AuxTransformBox, + DrawingArea, TextArea, VPacker) +from matplotlib.patches import (Rectangle, Ellipse, ArrowStyle, + FancyArrowPatch, PathPatch) +from matplotlib.text import TextPath + +__all__ = ['AnchoredDrawingArea', 'AnchoredAuxTransformBox', + 'AnchoredEllipse', 'AnchoredSizeBar', 'AnchoredDirectionArrows'] + + +class AnchoredDrawingArea(AnchoredOffsetbox): + def __init__(self, width, height, xdescent, ydescent, + loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, + **kwargs): + """ + An anchored container with a fixed size and fillable `.DrawingArea`. + + Artists added to the *drawing_area* will have their coordinates + interpreted as pixels. Any transformations set on the artists will be + overridden. + + Parameters + ---------- + width, height : float + Width and height of the container, in pixels. + xdescent, ydescent : float + Descent of the container in the x- and y- direction, in pixels. + loc : str + Location of this artist. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + pad : float, default: 0.4 + Padding around the child objects, in fraction of the font size. + borderpad : float, default: 0.5 + Border padding, in fraction of the font size. + prop : `~matplotlib.font_manager.FontProperties`, optional + Font property used as a reference for paddings. + frameon : bool, default: True + If True, draw a box around this artist. + **kwargs + Keyword arguments forwarded to `.AnchoredOffsetbox`. + + Attributes + ---------- + drawing_area : `~matplotlib.offsetbox.DrawingArea` + A container for artists to display. + + Examples + -------- + To display blue and red circles of different sizes in the upper right + of an Axes *ax*: + + >>> ada = AnchoredDrawingArea(20, 20, 0, 0, + ... loc='upper right', frameon=False) + >>> ada.drawing_area.add_artist(Circle((10, 10), 10, fc="b")) + >>> ada.drawing_area.add_artist(Circle((30, 10), 5, fc="r")) + >>> ax.add_artist(ada) + """ + self.da = DrawingArea(width, height, xdescent, ydescent) + self.drawing_area = self.da + + super().__init__( + loc, pad=pad, borderpad=borderpad, child=self.da, prop=None, + frameon=frameon, **kwargs + ) + + +class AnchoredAuxTransformBox(AnchoredOffsetbox): + def __init__(self, transform, loc, + pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): + """ + An anchored container with transformed coordinates. + + Artists added to the *drawing_area* are scaled according to the + coordinates of the transformation used. The dimensions of this artist + will scale to contain the artists added. + + Parameters + ---------- + transform : `~matplotlib.transforms.Transform` + The transformation object for the coordinate system in use, i.e., + :attr:`matplotlib.axes.Axes.transData`. + loc : str + Location of this artist. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + pad : float, default: 0.4 + Padding around the child objects, in fraction of the font size. + borderpad : float, default: 0.5 + Border padding, in fraction of the font size. + prop : `~matplotlib.font_manager.FontProperties`, optional + Font property used as a reference for paddings. + frameon : bool, default: True + If True, draw a box around this artist. + **kwargs + Keyword arguments forwarded to `.AnchoredOffsetbox`. + + Attributes + ---------- + drawing_area : `~matplotlib.offsetbox.AuxTransformBox` + A container for artists to display. + + Examples + -------- + To display an ellipse in the upper left, with a width of 0.1 and + height of 0.4 in data coordinates: + + >>> box = AnchoredAuxTransformBox(ax.transData, loc='upper left') + >>> el = Ellipse((0, 0), width=0.1, height=0.4, angle=30) + >>> box.drawing_area.add_artist(el) + >>> ax.add_artist(box) + """ + self.drawing_area = AuxTransformBox(transform) + + super().__init__(loc, pad=pad, borderpad=borderpad, + child=self.drawing_area, prop=prop, frameon=frameon, + **kwargs) + + +@_api.deprecated("3.8") +class AnchoredEllipse(AnchoredOffsetbox): + def __init__(self, transform, width, height, angle, loc, + pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): + """ + Draw an anchored ellipse of a given size. + + Parameters + ---------- + transform : `~matplotlib.transforms.Transform` + The transformation object for the coordinate system in use, i.e., + :attr:`matplotlib.axes.Axes.transData`. + width, height : float + Width and height of the ellipse, given in coordinates of + *transform*. + angle : float + Rotation of the ellipse, in degrees, anti-clockwise. + loc : str + Location of the ellipse. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + pad : float, default: 0.1 + Padding around the ellipse, in fraction of the font size. + borderpad : float, default: 0.1 + Border padding, in fraction of the font size. + frameon : bool, default: True + If True, draw a box around the ellipse. + prop : `~matplotlib.font_manager.FontProperties`, optional + Font property used as a reference for paddings. + **kwargs + Keyword arguments forwarded to `.AnchoredOffsetbox`. + + Attributes + ---------- + ellipse : `~matplotlib.patches.Ellipse` + Ellipse patch drawn. + """ + self._box = AuxTransformBox(transform) + self.ellipse = Ellipse((0, 0), width, height, angle=angle) + self._box.add_artist(self.ellipse) + + super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box, + prop=prop, frameon=frameon, **kwargs) + + +class AnchoredSizeBar(AnchoredOffsetbox): + def __init__(self, transform, size, label, loc, + pad=0.1, borderpad=0.1, sep=2, + frameon=True, size_vertical=0, color='black', + label_top=False, fontproperties=None, fill_bar=None, + **kwargs): + """ + Draw a horizontal scale bar with a center-aligned label underneath. + + Parameters + ---------- + transform : `~matplotlib.transforms.Transform` + The transformation object for the coordinate system in use, i.e., + :attr:`matplotlib.axes.Axes.transData`. + size : float + Horizontal length of the size bar, given in coordinates of + *transform*. + label : str + Label to display. + loc : str + Location of the size bar. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + pad : float, default: 0.1 + Padding around the label and size bar, in fraction of the font + size. + borderpad : float, default: 0.1 + Border padding, in fraction of the font size. + sep : float, default: 2 + Separation between the label and the size bar, in points. + frameon : bool, default: True + If True, draw a box around the horizontal bar and label. + size_vertical : float, default: 0 + Vertical length of the size bar, given in coordinates of + *transform*. + color : str, default: 'black' + Color for the size bar and label. + label_top : bool, default: False + If True, the label will be over the size bar. + fontproperties : `~matplotlib.font_manager.FontProperties`, optional + Font properties for the label text. + fill_bar : bool, optional + If True and if *size_vertical* is nonzero, the size bar will + be filled in with the color specified by the size bar. + Defaults to True if *size_vertical* is greater than + zero and False otherwise. + **kwargs + Keyword arguments forwarded to `.AnchoredOffsetbox`. + + Attributes + ---------- + size_bar : `~matplotlib.offsetbox.AuxTransformBox` + Container for the size bar. + txt_label : `~matplotlib.offsetbox.TextArea` + Container for the label of the size bar. + + Notes + ----- + If *prop* is passed as a keyword argument, but *fontproperties* is + not, then *prop* is assumed to be the intended *fontproperties*. + Using both *prop* and *fontproperties* is not supported. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> import numpy as np + >>> from mpl_toolkits.axes_grid1.anchored_artists import ( + ... AnchoredSizeBar) + >>> fig, ax = plt.subplots() + >>> ax.imshow(np.random.random((10, 10))) + >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4) + >>> ax.add_artist(bar) + >>> fig.show() + + Using all the optional parameters + + >>> import matplotlib.font_manager as fm + >>> fontprops = fm.FontProperties(size=14, family='monospace') + >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5, + ... sep=5, borderpad=0.5, frameon=False, + ... size_vertical=0.5, color='white', + ... fontproperties=fontprops) + """ + if fill_bar is None: + fill_bar = size_vertical > 0 + + self.size_bar = AuxTransformBox(transform) + self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical, + fill=fill_bar, facecolor=color, + edgecolor=color)) + + if fontproperties is None and 'prop' in kwargs: + fontproperties = kwargs.pop('prop') + + if fontproperties is None: + textprops = {'color': color} + else: + textprops = {'color': color, 'fontproperties': fontproperties} + + self.txt_label = TextArea(label, textprops=textprops) + + if label_top: + _box_children = [self.txt_label, self.size_bar] + else: + _box_children = [self.size_bar, self.txt_label] + + self._box = VPacker(children=_box_children, + align="center", + pad=0, sep=sep) + + super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box, + prop=fontproperties, frameon=frameon, **kwargs) + + +class AnchoredDirectionArrows(AnchoredOffsetbox): + def __init__(self, transform, label_x, label_y, length=0.15, + fontsize=0.08, loc='upper left', angle=0, aspect_ratio=1, + pad=0.4, borderpad=0.4, frameon=False, color='w', alpha=1, + sep_x=0.01, sep_y=0, fontproperties=None, back_length=0.15, + head_width=10, head_length=15, tail_width=2, + text_props=None, arrow_props=None, + **kwargs): + """ + Draw two perpendicular arrows to indicate directions. + + Parameters + ---------- + transform : `~matplotlib.transforms.Transform` + The transformation object for the coordinate system in use, i.e., + :attr:`matplotlib.axes.Axes.transAxes`. + label_x, label_y : str + Label text for the x and y arrows + length : float, default: 0.15 + Length of the arrow, given in coordinates of *transform*. + fontsize : float, default: 0.08 + Size of label strings, given in coordinates of *transform*. + loc : str, default: 'upper left' + Location of the arrow. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + angle : float, default: 0 + The angle of the arrows in degrees. + aspect_ratio : float, default: 1 + The ratio of the length of arrow_x and arrow_y. + Negative numbers can be used to change the direction. + pad : float, default: 0.4 + Padding around the labels and arrows, in fraction of the font size. + borderpad : float, default: 0.4 + Border padding, in fraction of the font size. + frameon : bool, default: False + If True, draw a box around the arrows and labels. + color : str, default: 'white' + Color for the arrows and labels. + alpha : float, default: 1 + Alpha values of the arrows and labels + sep_x, sep_y : float, default: 0.01 and 0 respectively + Separation between the arrows and labels in coordinates of + *transform*. + fontproperties : `~matplotlib.font_manager.FontProperties`, optional + Font properties for the label text. + back_length : float, default: 0.15 + Fraction of the arrow behind the arrow crossing. + head_width : float, default: 10 + Width of arrow head, sent to `.ArrowStyle`. + head_length : float, default: 15 + Length of arrow head, sent to `.ArrowStyle`. + tail_width : float, default: 2 + Width of arrow tail, sent to `.ArrowStyle`. + text_props, arrow_props : dict + Properties of the text and arrows, passed to `.TextPath` and + `.FancyArrowPatch`. + **kwargs + Keyword arguments forwarded to `.AnchoredOffsetbox`. + + Attributes + ---------- + arrow_x, arrow_y : `~matplotlib.patches.FancyArrowPatch` + Arrow x and y + text_path_x, text_path_y : `~matplotlib.text.TextPath` + Path for arrow labels + p_x, p_y : `~matplotlib.patches.PathPatch` + Patch for arrow labels + box : `~matplotlib.offsetbox.AuxTransformBox` + Container for the arrows and labels. + + Notes + ----- + If *prop* is passed as a keyword argument, but *fontproperties* is + not, then *prop* is assumed to be the intended *fontproperties*. + Using both *prop* and *fontproperties* is not supported. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> import numpy as np + >>> from mpl_toolkits.axes_grid1.anchored_artists import ( + ... AnchoredDirectionArrows) + >>> fig, ax = plt.subplots() + >>> ax.imshow(np.random.random((10, 10))) + >>> arrows = AnchoredDirectionArrows(ax.transAxes, '111', '110') + >>> ax.add_artist(arrows) + >>> fig.show() + + Using several of the optional parameters, creating downward pointing + arrow and high contrast text labels. + + >>> import matplotlib.font_manager as fm + >>> fontprops = fm.FontProperties(family='monospace') + >>> arrows = AnchoredDirectionArrows(ax.transAxes, 'East', 'South', + ... loc='lower left', color='k', + ... aspect_ratio=-1, sep_x=0.02, + ... sep_y=-0.01, + ... text_props={'ec':'w', 'fc':'k'}, + ... fontproperties=fontprops) + """ + if arrow_props is None: + arrow_props = {} + + if text_props is None: + text_props = {} + + arrowstyle = ArrowStyle("Simple", + head_width=head_width, + head_length=head_length, + tail_width=tail_width) + + if fontproperties is None and 'prop' in kwargs: + fontproperties = kwargs.pop('prop') + + if 'color' not in arrow_props: + arrow_props['color'] = color + + if 'alpha' not in arrow_props: + arrow_props['alpha'] = alpha + + if 'color' not in text_props: + text_props['color'] = color + + if 'alpha' not in text_props: + text_props['alpha'] = alpha + + t_start = transform + t_end = t_start + transforms.Affine2D().rotate_deg(angle) + + self.box = AuxTransformBox(t_end) + + length_x = length + length_y = length*aspect_ratio + + self.arrow_x = FancyArrowPatch( + (0, back_length*length_y), + (length_x, back_length*length_y), + arrowstyle=arrowstyle, + shrinkA=0.0, + shrinkB=0.0, + **arrow_props) + + self.arrow_y = FancyArrowPatch( + (back_length*length_x, 0), + (back_length*length_x, length_y), + arrowstyle=arrowstyle, + shrinkA=0.0, + shrinkB=0.0, + **arrow_props) + + self.box.add_artist(self.arrow_x) + self.box.add_artist(self.arrow_y) + + text_path_x = TextPath(( + length_x+sep_x, back_length*length_y+sep_y), label_x, + size=fontsize, prop=fontproperties) + self.p_x = PathPatch(text_path_x, transform=t_start, **text_props) + self.box.add_artist(self.p_x) + + text_path_y = TextPath(( + length_x*back_length+sep_x, length_y*(1-back_length)+sep_y), + label_y, size=fontsize, prop=fontproperties) + self.p_y = PathPatch(text_path_y, **text_props) + self.box.add_artist(self.p_y) + + super().__init__(loc, pad=pad, borderpad=borderpad, child=self.box, + frameon=frameon, **kwargs) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_divider.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_divider.py new file mode 100644 index 00000000..f6c38f35 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_divider.py @@ -0,0 +1,694 @@ +""" +Helper classes to adjust the positions of multiple axes at drawing time. +""" + +import functools + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api +from matplotlib.gridspec import SubplotSpec +import matplotlib.transforms as mtransforms +from . import axes_size as Size + + +class Divider: + """ + An Axes positioning class. + + The divider is initialized with lists of horizontal and vertical sizes + (:mod:`mpl_toolkits.axes_grid1.axes_size`) based on which a given + rectangular area will be divided. + + The `new_locator` method then creates a callable object + that can be used as the *axes_locator* of the axes. + """ + + def __init__(self, fig, pos, horizontal, vertical, + aspect=None, anchor="C"): + """ + Parameters + ---------- + fig : Figure + pos : tuple of 4 floats + Position of the rectangle that will be divided. + horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size` + Sizes for horizontal division. + vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size` + Sizes for vertical division. + aspect : bool, optional + Whether overall rectangular area is reduced so that the relative + part of the horizontal and vertical scales have the same scale. + anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \ +'NW', 'W'}, default: 'C' + Placement of the reduced rectangle, when *aspect* is True. + """ + + self._fig = fig + self._pos = pos + self._horizontal = horizontal + self._vertical = vertical + self._anchor = anchor + self.set_anchor(anchor) + self._aspect = aspect + self._xrefindex = 0 + self._yrefindex = 0 + self._locator = None + + def get_horizontal_sizes(self, renderer): + return np.array([s.get_size(renderer) for s in self.get_horizontal()]) + + def get_vertical_sizes(self, renderer): + return np.array([s.get_size(renderer) for s in self.get_vertical()]) + + def set_position(self, pos): + """ + Set the position of the rectangle. + + Parameters + ---------- + pos : tuple of 4 floats + position of the rectangle that will be divided + """ + self._pos = pos + + def get_position(self): + """Return the position of the rectangle.""" + return self._pos + + def set_anchor(self, anchor): + """ + Parameters + ---------- + anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \ +'NW', 'W'} + Either an (*x*, *y*) pair of relative coordinates (0 is left or + bottom, 1 is right or top), 'C' (center), or a cardinal direction + ('SW', southwest, is bottom left, etc.). + + See Also + -------- + .Axes.set_anchor + """ + if isinstance(anchor, str): + _api.check_in_list(mtransforms.Bbox.coefs, anchor=anchor) + elif not isinstance(anchor, (tuple, list)) or len(anchor) != 2: + raise TypeError("anchor must be str or 2-tuple") + self._anchor = anchor + + def get_anchor(self): + """Return the anchor.""" + return self._anchor + + def get_subplotspec(self): + return None + + def set_horizontal(self, h): + """ + Parameters + ---------- + h : list of :mod:`~mpl_toolkits.axes_grid1.axes_size` + sizes for horizontal division + """ + self._horizontal = h + + def get_horizontal(self): + """Return horizontal sizes.""" + return self._horizontal + + def set_vertical(self, v): + """ + Parameters + ---------- + v : list of :mod:`~mpl_toolkits.axes_grid1.axes_size` + sizes for vertical division + """ + self._vertical = v + + def get_vertical(self): + """Return vertical sizes.""" + return self._vertical + + def set_aspect(self, aspect=False): + """ + Parameters + ---------- + aspect : bool + """ + self._aspect = aspect + + def get_aspect(self): + """Return aspect.""" + return self._aspect + + def set_locator(self, _locator): + self._locator = _locator + + def get_locator(self): + return self._locator + + def get_position_runtime(self, ax, renderer): + if self._locator is None: + return self.get_position() + else: + return self._locator(ax, renderer).bounds + + @staticmethod + def _calc_k(sizes, total): + # sizes is a (n, 2) array of (rel_size, abs_size); this method finds + # the k factor such that sum(rel_size * k + abs_size) == total. + rel_sum, abs_sum = sizes.sum(0) + return (total - abs_sum) / rel_sum if rel_sum else 0 + + @staticmethod + def _calc_offsets(sizes, k): + # Apply k factors to (n, 2) sizes array of (rel_size, abs_size); return + # the resulting cumulative offset positions. + return np.cumsum([0, *(sizes @ [k, 1])]) + + def new_locator(self, nx, ny, nx1=None, ny1=None): + """ + Return an axes locator callable for the specified cell. + + Parameters + ---------- + nx, nx1 : int + Integers specifying the column-position of the + cell. When *nx1* is None, a single *nx*-th column is + specified. Otherwise, location of columns spanning between *nx* + to *nx1* (but excluding *nx1*-th column) is specified. + ny, ny1 : int + Same as *nx* and *nx1*, but for row positions. + """ + if nx1 is None: + nx1 = nx + 1 + if ny1 is None: + ny1 = ny + 1 + # append_size("left") adds a new size at the beginning of the + # horizontal size lists; this shift transforms e.g. + # new_locator(nx=2, ...) into effectively new_locator(nx=3, ...). To + # take that into account, instead of recording nx, we record + # nx-self._xrefindex, where _xrefindex is shifted by 1 by each + # append_size("left"), and re-add self._xrefindex back to nx in + # _locate, when the actual axes position is computed. Ditto for y. + xref = self._xrefindex + yref = self._yrefindex + locator = functools.partial( + self._locate, nx - xref, ny - yref, nx1 - xref, ny1 - yref) + locator.get_subplotspec = self.get_subplotspec + return locator + + @_api.deprecated( + "3.8", alternative="divider.new_locator(...)(ax, renderer)") + def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None): + """ + Implementation of ``divider.new_locator().__call__``. + + Parameters + ---------- + nx, nx1 : int + Integers specifying the column-position of the cell. When *nx1* is + None, a single *nx*-th column is specified. Otherwise, the + location of columns spanning between *nx* to *nx1* (but excluding + *nx1*-th column) is specified. + ny, ny1 : int + Same as *nx* and *nx1*, but for row positions. + axes + renderer + """ + xref = self._xrefindex + yref = self._yrefindex + return self._locate( + nx - xref, (nx + 1 if nx1 is None else nx1) - xref, + ny - yref, (ny + 1 if ny1 is None else ny1) - yref, + axes, renderer) + + def _locate(self, nx, ny, nx1, ny1, axes, renderer): + """ + Implementation of ``divider.new_locator().__call__``. + + The axes locator callable returned by ``new_locator()`` is created as + a `functools.partial` of this method with *nx*, *ny*, *nx1*, and *ny1* + specifying the requested cell. + """ + nx += self._xrefindex + nx1 += self._xrefindex + ny += self._yrefindex + ny1 += self._yrefindex + + fig_w, fig_h = self._fig.bbox.size / self._fig.dpi + x, y, w, h = self.get_position_runtime(axes, renderer) + + hsizes = self.get_horizontal_sizes(renderer) + vsizes = self.get_vertical_sizes(renderer) + k_h = self._calc_k(hsizes, fig_w * w) + k_v = self._calc_k(vsizes, fig_h * h) + + if self.get_aspect(): + k = min(k_h, k_v) + ox = self._calc_offsets(hsizes, k) + oy = self._calc_offsets(vsizes, k) + + ww = (ox[-1] - ox[0]) / fig_w + hh = (oy[-1] - oy[0]) / fig_h + pb = mtransforms.Bbox.from_bounds(x, y, w, h) + pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh) + x0, y0 = pb1.anchored(self.get_anchor(), pb).p0 + + else: + ox = self._calc_offsets(hsizes, k_h) + oy = self._calc_offsets(vsizes, k_v) + x0, y0 = x, y + + if nx1 is None: + nx1 = -1 + if ny1 is None: + ny1 = -1 + + x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w + y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h + + return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) + + def append_size(self, position, size): + _api.check_in_list(["left", "right", "bottom", "top"], + position=position) + if position == "left": + self._horizontal.insert(0, size) + self._xrefindex += 1 + elif position == "right": + self._horizontal.append(size) + elif position == "bottom": + self._vertical.insert(0, size) + self._yrefindex += 1 + else: # 'top' + self._vertical.append(size) + + def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None): + """ + Add auto-adjustable padding around *use_axes* to take their decorations + (title, labels, ticks, ticklabels) into account during layout. + + Parameters + ---------- + use_axes : `~matplotlib.axes.Axes` or list of `~matplotlib.axes.Axes` + The Axes whose decorations are taken into account. + pad : float, default: 0.1 + Additional padding in inches. + adjust_dirs : list of {"left", "right", "bottom", "top"}, optional + The sides where padding is added; defaults to all four sides. + """ + if adjust_dirs is None: + adjust_dirs = ["left", "right", "bottom", "top"] + for d in adjust_dirs: + self.append_size(d, Size._AxesDecorationsSize(use_axes, d) + pad) + + +@_api.deprecated("3.8") +class AxesLocator: + """ + A callable object which returns the position and size of a given + `.AxesDivider` cell. + """ + + def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None): + """ + Parameters + ---------- + axes_divider : `~mpl_toolkits.axes_grid1.axes_divider.AxesDivider` + nx, nx1 : int + Integers specifying the column-position of the + cell. When *nx1* is None, a single *nx*-th column is + specified. Otherwise, location of columns spanning between *nx* + to *nx1* (but excluding *nx1*-th column) is specified. + ny, ny1 : int + Same as *nx* and *nx1*, but for row positions. + """ + self._axes_divider = axes_divider + + _xrefindex = axes_divider._xrefindex + _yrefindex = axes_divider._yrefindex + + self._nx, self._ny = nx - _xrefindex, ny - _yrefindex + + if nx1 is None: + nx1 = len(self._axes_divider) + if ny1 is None: + ny1 = len(self._axes_divider[0]) + + self._nx1 = nx1 - _xrefindex + self._ny1 = ny1 - _yrefindex + + def __call__(self, axes, renderer): + + _xrefindex = self._axes_divider._xrefindex + _yrefindex = self._axes_divider._yrefindex + + return self._axes_divider.locate(self._nx + _xrefindex, + self._ny + _yrefindex, + self._nx1 + _xrefindex, + self._ny1 + _yrefindex, + axes, + renderer) + + def get_subplotspec(self): + return self._axes_divider.get_subplotspec() + + +class SubplotDivider(Divider): + """ + The Divider class whose rectangle area is specified as a subplot geometry. + """ + + def __init__(self, fig, *args, horizontal=None, vertical=None, + aspect=None, anchor='C'): + """ + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + + *args : tuple (*nrows*, *ncols*, *index*) or int + The array of subplots in the figure has dimensions ``(nrows, + ncols)``, and *index* is the index of the subplot being created. + *index* starts at 1 in the upper left corner and increases to the + right. + + If *nrows*, *ncols*, and *index* are all single digit numbers, then + *args* can be passed as a single 3-digit number (e.g. 234 for + (2, 3, 4)). + horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional + Sizes for horizontal division. + vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional + Sizes for vertical division. + aspect : bool, optional + Whether overall rectangular area is reduced so that the relative + part of the horizontal and vertical scales have the same scale. + anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \ +'NW', 'W'}, default: 'C' + Placement of the reduced rectangle, when *aspect* is True. + """ + self.figure = fig + super().__init__(fig, [0, 0, 1, 1], + horizontal=horizontal or [], vertical=vertical or [], + aspect=aspect, anchor=anchor) + self.set_subplotspec(SubplotSpec._from_subplot_args(fig, args)) + + def get_position(self): + """Return the bounds of the subplot box.""" + return self.get_subplotspec().get_position(self.figure).bounds + + def get_subplotspec(self): + """Get the SubplotSpec instance.""" + return self._subplotspec + + def set_subplotspec(self, subplotspec): + """Set the SubplotSpec instance.""" + self._subplotspec = subplotspec + self.set_position(subplotspec.get_position(self.figure)) + + +class AxesDivider(Divider): + """ + Divider based on the preexisting axes. + """ + + def __init__(self, axes, xref=None, yref=None): + """ + Parameters + ---------- + axes : :class:`~matplotlib.axes.Axes` + xref + yref + """ + self._axes = axes + if xref is None: + self._xref = Size.AxesX(axes) + else: + self._xref = xref + if yref is None: + self._yref = Size.AxesY(axes) + else: + self._yref = yref + + super().__init__(fig=axes.get_figure(), pos=None, + horizontal=[self._xref], vertical=[self._yref], + aspect=None, anchor="C") + + def _get_new_axes(self, *, axes_class=None, **kwargs): + axes = self._axes + if axes_class is None: + axes_class = type(axes) + return axes_class(axes.get_figure(), axes.get_position(original=True), + **kwargs) + + def new_horizontal(self, size, pad=None, pack_start=False, **kwargs): + """ + Helper method for ``append_axes("left")`` and ``append_axes("right")``. + + See the documentation of `append_axes` for more details. + + :meta private: + """ + if pad is None: + pad = mpl.rcParams["figure.subplot.wspace"] * self._xref + pos = "left" if pack_start else "right" + if pad: + if not isinstance(pad, Size._Base): + pad = Size.from_any(pad, fraction_ref=self._xref) + self.append_size(pos, pad) + if not isinstance(size, Size._Base): + size = Size.from_any(size, fraction_ref=self._xref) + self.append_size(pos, size) + locator = self.new_locator( + nx=0 if pack_start else len(self._horizontal) - 1, + ny=self._yrefindex) + ax = self._get_new_axes(**kwargs) + ax.set_axes_locator(locator) + return ax + + def new_vertical(self, size, pad=None, pack_start=False, **kwargs): + """ + Helper method for ``append_axes("top")`` and ``append_axes("bottom")``. + + See the documentation of `append_axes` for more details. + + :meta private: + """ + if pad is None: + pad = mpl.rcParams["figure.subplot.hspace"] * self._yref + pos = "bottom" if pack_start else "top" + if pad: + if not isinstance(pad, Size._Base): + pad = Size.from_any(pad, fraction_ref=self._yref) + self.append_size(pos, pad) + if not isinstance(size, Size._Base): + size = Size.from_any(size, fraction_ref=self._yref) + self.append_size(pos, size) + locator = self.new_locator( + nx=self._xrefindex, + ny=0 if pack_start else len(self._vertical) - 1) + ax = self._get_new_axes(**kwargs) + ax.set_axes_locator(locator) + return ax + + def append_axes(self, position, size, pad=None, *, axes_class=None, + **kwargs): + """ + Add a new axes on a given side of the main axes. + + Parameters + ---------- + position : {"left", "right", "bottom", "top"} + Where the new axes is positioned relative to the main axes. + size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str + The axes width or height. float or str arguments are interpreted + as ``axes_size.from_any(size, AxesX(<main_axes>))`` for left or + right axes, and likewise with ``AxesY`` for bottom or top axes. + pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str + Padding between the axes. float or str arguments are interpreted + as for *size*. Defaults to :rc:`figure.subplot.wspace` times the + main Axes width (left or right axes) or :rc:`figure.subplot.hspace` + times the main Axes height (bottom or top axes). + axes_class : subclass type of `~.axes.Axes`, optional + The type of the new axes. Defaults to the type of the main axes. + **kwargs + All extra keywords arguments are passed to the created axes. + """ + create_axes, pack_start = _api.check_getitem({ + "left": (self.new_horizontal, True), + "right": (self.new_horizontal, False), + "bottom": (self.new_vertical, True), + "top": (self.new_vertical, False), + }, position=position) + ax = create_axes( + size, pad, pack_start=pack_start, axes_class=axes_class, **kwargs) + self._fig.add_axes(ax) + return ax + + def get_aspect(self): + if self._aspect is None: + aspect = self._axes.get_aspect() + if aspect == "auto": + return False + else: + return True + else: + return self._aspect + + def get_position(self): + if self._pos is None: + bbox = self._axes.get_position(original=True) + return bbox.bounds + else: + return self._pos + + def get_anchor(self): + if self._anchor is None: + return self._axes.get_anchor() + else: + return self._anchor + + def get_subplotspec(self): + return self._axes.get_subplotspec() + + +# Helper for HBoxDivider/VBoxDivider. +# The variable names are written for a horizontal layout, but the calculations +# work identically for vertical layouts. +def _locate(x, y, w, h, summed_widths, equal_heights, fig_w, fig_h, anchor): + + total_width = fig_w * w + max_height = fig_h * h + + # Determine the k factors. + n = len(equal_heights) + eq_rels, eq_abss = equal_heights.T + sm_rels, sm_abss = summed_widths.T + A = np.diag([*eq_rels, 0]) + A[:n, -1] = -1 + A[-1, :-1] = sm_rels + B = [*(-eq_abss), total_width - sm_abss.sum()] + # A @ K = B: This finds factors {k_0, ..., k_{N-1}, H} so that + # eq_rel_i * k_i + eq_abs_i = H for all i: all axes have the same height + # sum(sm_rel_i * k_i + sm_abs_i) = total_width: fixed total width + # (foo_rel_i * k_i + foo_abs_i will end up being the size of foo.) + *karray, height = np.linalg.solve(A, B) + if height > max_height: # Additionally, upper-bound the height. + karray = (max_height - eq_abss) / eq_rels + + # Compute the offsets corresponding to these factors. + ox = np.cumsum([0, *(sm_rels * karray + sm_abss)]) + ww = (ox[-1] - ox[0]) / fig_w + h0_rel, h0_abs = equal_heights[0] + hh = (karray[0]*h0_rel + h0_abs) / fig_h + pb = mtransforms.Bbox.from_bounds(x, y, w, h) + pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh) + x0, y0 = pb1.anchored(anchor, pb).p0 + + return x0, y0, ox, hh + + +class HBoxDivider(SubplotDivider): + """ + A `.SubplotDivider` for laying out axes horizontally, while ensuring that + they have equal heights. + + Examples + -------- + .. plot:: gallery/axes_grid1/demo_axes_hbox_divider.py + """ + + def new_locator(self, nx, nx1=None): + """ + Create an axes locator callable for the specified cell. + + Parameters + ---------- + nx, nx1 : int + Integers specifying the column-position of the + cell. When *nx1* is None, a single *nx*-th column is + specified. Otherwise, location of columns spanning between *nx* + to *nx1* (but excluding *nx1*-th column) is specified. + """ + return super().new_locator(nx, 0, nx1, 0) + + def _locate(self, nx, ny, nx1, ny1, axes, renderer): + # docstring inherited + nx += self._xrefindex + nx1 += self._xrefindex + fig_w, fig_h = self._fig.bbox.size / self._fig.dpi + x, y, w, h = self.get_position_runtime(axes, renderer) + summed_ws = self.get_horizontal_sizes(renderer) + equal_hs = self.get_vertical_sizes(renderer) + x0, y0, ox, hh = _locate( + x, y, w, h, summed_ws, equal_hs, fig_w, fig_h, self.get_anchor()) + if nx1 is None: + nx1 = -1 + x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w + y1, h1 = y0, hh + return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) + + +class VBoxDivider(SubplotDivider): + """ + A `.SubplotDivider` for laying out axes vertically, while ensuring that + they have equal widths. + """ + + def new_locator(self, ny, ny1=None): + """ + Create an axes locator callable for the specified cell. + + Parameters + ---------- + ny, ny1 : int + Integers specifying the row-position of the + cell. When *ny1* is None, a single *ny*-th row is + specified. Otherwise, location of rows spanning between *ny* + to *ny1* (but excluding *ny1*-th row) is specified. + """ + return super().new_locator(0, ny, 0, ny1) + + def _locate(self, nx, ny, nx1, ny1, axes, renderer): + # docstring inherited + ny += self._yrefindex + ny1 += self._yrefindex + fig_w, fig_h = self._fig.bbox.size / self._fig.dpi + x, y, w, h = self.get_position_runtime(axes, renderer) + summed_hs = self.get_vertical_sizes(renderer) + equal_ws = self.get_horizontal_sizes(renderer) + y0, x0, oy, ww = _locate( + y, x, h, w, summed_hs, equal_ws, fig_h, fig_w, self.get_anchor()) + if ny1 is None: + ny1 = -1 + x1, w1 = x0, ww + y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h + return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) + + +def make_axes_locatable(axes): + divider = AxesDivider(axes) + locator = divider.new_locator(nx=0, ny=0) + axes.set_axes_locator(locator) + + return divider + + +def make_axes_area_auto_adjustable( + ax, use_axes=None, pad=0.1, adjust_dirs=None): + """ + Add auto-adjustable padding around *ax* to take its decorations (title, + labels, ticks, ticklabels) into account during layout, using + `.Divider.add_auto_adjustable_area`. + + By default, padding is determined from the decorations of *ax*. + Pass *use_axes* to consider the decorations of other Axes instead. + """ + if adjust_dirs is None: + adjust_dirs = ["left", "right", "bottom", "top"] + divider = make_axes_locatable(ax) + if use_axes is None: + use_axes = ax + divider.add_auto_adjustable_area(use_axes=use_axes, pad=pad, + adjust_dirs=adjust_dirs) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_grid.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_grid.py new file mode 100644 index 00000000..720d9854 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_grid.py @@ -0,0 +1,550 @@ +from numbers import Number +import functools +from types import MethodType + +import numpy as np + +from matplotlib import _api, cbook +from matplotlib.gridspec import SubplotSpec + +from .axes_divider import Size, SubplotDivider, Divider +from .mpl_axes import Axes, SimpleAxisArtist + + +class CbarAxesBase: + def __init__(self, *args, orientation, **kwargs): + self.orientation = orientation + super().__init__(*args, **kwargs) + + def colorbar(self, mappable, **kwargs): + return self.figure.colorbar( + mappable, cax=self, location=self.orientation, **kwargs) + + @_api.deprecated("3.8", alternative="ax.tick_params and colorbar.set_label") + def toggle_label(self, b): + axis = self.axis[self.orientation] + axis.toggle(ticklabels=b, label=b) + + +_cbaraxes_class_factory = cbook._make_class_factory(CbarAxesBase, "Cbar{}") + + +class Grid: + """ + A grid of Axes. + + In Matplotlib, the Axes location (and size) is specified in normalized + figure coordinates. This may not be ideal for images that needs to be + displayed with a given aspect ratio; for example, it is difficult to + display multiple images of a same size with some fixed padding between + them. AxesGrid can be used in such case. + """ + + _defaultAxesClass = Axes + + def __init__(self, fig, + rect, + nrows_ncols, + ngrids=None, + direction="row", + axes_pad=0.02, + *, + share_all=False, + share_x=True, + share_y=True, + label_mode="L", + axes_class=None, + aspect=False, + ): + """ + Parameters + ---------- + fig : `.Figure` + The parent figure. + rect : (float, float, float, float), (int, int, int), int, or \ + `~.SubplotSpec` + The axes position, as a ``(left, bottom, width, height)`` tuple, + as a three-digit subplot position code (e.g., ``(1, 2, 1)`` or + ``121``), or as a `~.SubplotSpec`. + nrows_ncols : (int, int) + Number of rows and columns in the grid. + ngrids : int or None, default: None + If not None, only the first *ngrids* axes in the grid are created. + direction : {"row", "column"}, default: "row" + Whether axes are created in row-major ("row by row") or + column-major order ("column by column"). This also affects the + order in which axes are accessed using indexing (``grid[index]``). + axes_pad : float or (float, float), default: 0.02 + Padding or (horizontal padding, vertical padding) between axes, in + inches. + share_all : bool, default: False + Whether all axes share their x- and y-axis. Overrides *share_x* + and *share_y*. + share_x : bool, default: True + Whether all axes of a column share their x-axis. + share_y : bool, default: True + Whether all axes of a row share their y-axis. + label_mode : {"L", "1", "all", "keep"}, default: "L" + Determines which axes will get tick labels: + + - "L": All axes on the left column get vertical tick labels; + all axes on the bottom row get horizontal tick labels. + - "1": Only the bottom left axes is labelled. + - "all": All axes are labelled. + - "keep": Do not do anything. + + axes_class : subclass of `matplotlib.axes.Axes`, default: None + aspect : bool, default: False + Whether the axes aspect ratio follows the aspect ratio of the data + limits. + """ + self._nrows, self._ncols = nrows_ncols + + if ngrids is None: + ngrids = self._nrows * self._ncols + else: + if not 0 < ngrids <= self._nrows * self._ncols: + raise ValueError( + "ngrids must be positive and not larger than nrows*ncols") + + self.ngrids = ngrids + + self._horiz_pad_size, self._vert_pad_size = map( + Size.Fixed, np.broadcast_to(axes_pad, 2)) + + _api.check_in_list(["column", "row"], direction=direction) + self._direction = direction + + if axes_class is None: + axes_class = self._defaultAxesClass + elif isinstance(axes_class, (list, tuple)): + cls, kwargs = axes_class + axes_class = functools.partial(cls, **kwargs) + + kw = dict(horizontal=[], vertical=[], aspect=aspect) + if isinstance(rect, (Number, SubplotSpec)): + self._divider = SubplotDivider(fig, rect, **kw) + elif len(rect) == 3: + self._divider = SubplotDivider(fig, *rect, **kw) + elif len(rect) == 4: + self._divider = Divider(fig, rect, **kw) + else: + raise TypeError("Incorrect rect format") + + rect = self._divider.get_position() + + axes_array = np.full((self._nrows, self._ncols), None, dtype=object) + for i in range(self.ngrids): + col, row = self._get_col_row(i) + if share_all: + sharex = sharey = axes_array[0, 0] + else: + sharex = axes_array[0, col] if share_x else None + sharey = axes_array[row, 0] if share_y else None + axes_array[row, col] = axes_class( + fig, rect, sharex=sharex, sharey=sharey) + self.axes_all = axes_array.ravel( + order="C" if self._direction == "row" else "F").tolist() + self.axes_column = axes_array.T.tolist() + self.axes_row = axes_array.tolist() + self.axes_llc = self.axes_column[0][-1] + + self._init_locators() + + for ax in self.axes_all: + fig.add_axes(ax) + + self.set_label_mode(label_mode) + + def _init_locators(self): + self._divider.set_horizontal( + [Size.Scaled(1), self._horiz_pad_size] * (self._ncols-1) + [Size.Scaled(1)]) + self._divider.set_vertical( + [Size.Scaled(1), self._vert_pad_size] * (self._nrows-1) + [Size.Scaled(1)]) + for i in range(self.ngrids): + col, row = self._get_col_row(i) + self.axes_all[i].set_axes_locator( + self._divider.new_locator(nx=2 * col, ny=2 * (self._nrows - 1 - row))) + + def _get_col_row(self, n): + if self._direction == "column": + col, row = divmod(n, self._nrows) + else: + row, col = divmod(n, self._ncols) + + return col, row + + # Good to propagate __len__ if we have __getitem__ + def __len__(self): + return len(self.axes_all) + + def __getitem__(self, i): + return self.axes_all[i] + + def get_geometry(self): + """ + Return the number of rows and columns of the grid as (nrows, ncols). + """ + return self._nrows, self._ncols + + def set_axes_pad(self, axes_pad): + """ + Set the padding between the axes. + + Parameters + ---------- + axes_pad : (float, float) + The padding (horizontal pad, vertical pad) in inches. + """ + self._horiz_pad_size.fixed_size = axes_pad[0] + self._vert_pad_size.fixed_size = axes_pad[1] + + def get_axes_pad(self): + """ + Return the axes padding. + + Returns + ------- + hpad, vpad + Padding (horizontal pad, vertical pad) in inches. + """ + return (self._horiz_pad_size.fixed_size, + self._vert_pad_size.fixed_size) + + def set_aspect(self, aspect): + """Set the aspect of the SubplotDivider.""" + self._divider.set_aspect(aspect) + + def get_aspect(self): + """Return the aspect of the SubplotDivider.""" + return self._divider.get_aspect() + + def set_label_mode(self, mode): + """ + Define which axes have tick labels. + + Parameters + ---------- + mode : {"L", "1", "all", "keep"} + The label mode: + + - "L": All axes on the left column get vertical tick labels; + all axes on the bottom row get horizontal tick labels. + - "1": Only the bottom left axes is labelled. + - "all": All axes are labelled. + - "keep": Do not do anything. + """ + is_last_row, is_first_col = ( + np.mgrid[:self._nrows, :self._ncols] == [[[self._nrows - 1]], [[0]]]) + if mode == "all": + bottom = left = np.full((self._nrows, self._ncols), True) + elif mode == "L": + bottom = is_last_row + left = is_first_col + elif mode == "1": + bottom = left = is_last_row & is_first_col + else: + # Use _api.check_in_list at the top of the method when deprecation + # period expires + if mode != 'keep': + _api.warn_deprecated( + '3.7', name="Grid label_mode", + message='Passing an undefined label_mode is deprecated ' + 'since %(since)s and will become an error ' + '%(removal)s. To silence this warning, pass ' + '"keep", which gives the same behaviour.') + return + for i in range(self._nrows): + for j in range(self._ncols): + ax = self.axes_row[i][j] + if isinstance(ax.axis, MethodType): + bottom_axis = SimpleAxisArtist(ax.xaxis, 1, ax.spines["bottom"]) + left_axis = SimpleAxisArtist(ax.yaxis, 1, ax.spines["left"]) + else: + bottom_axis = ax.axis["bottom"] + left_axis = ax.axis["left"] + bottom_axis.toggle(ticklabels=bottom[i, j], label=bottom[i, j]) + left_axis.toggle(ticklabels=left[i, j], label=left[i, j]) + + def get_divider(self): + return self._divider + + def set_axes_locator(self, locator): + self._divider.set_locator(locator) + + def get_axes_locator(self): + return self._divider.get_locator() + + +class ImageGrid(Grid): + """ + A grid of Axes for Image display. + + This class is a specialization of `~.axes_grid1.axes_grid.Grid` for displaying a + grid of images. In particular, it forces all axes in a column to share their x-axis + and all axes in a row to share their y-axis. It further provides helpers to add + colorbars to some or all axes. + """ + + def __init__(self, fig, + rect, + nrows_ncols, + ngrids=None, + direction="row", + axes_pad=0.02, + *, + share_all=False, + aspect=True, + label_mode="L", + cbar_mode=None, + cbar_location="right", + cbar_pad=None, + cbar_size="5%", + cbar_set_cax=True, + axes_class=None, + ): + """ + Parameters + ---------- + fig : `.Figure` + The parent figure. + rect : (float, float, float, float) or int + The axes position, as a ``(left, bottom, width, height)`` tuple or + as a three-digit subplot position code (e.g., "121"). + nrows_ncols : (int, int) + Number of rows and columns in the grid. + ngrids : int or None, default: None + If not None, only the first *ngrids* axes in the grid are created. + direction : {"row", "column"}, default: "row" + Whether axes are created in row-major ("row by row") or + column-major order ("column by column"). This also affects the + order in which axes are accessed using indexing (``grid[index]``). + axes_pad : float or (float, float), default: 0.02in + Padding or (horizontal padding, vertical padding) between axes, in + inches. + share_all : bool, default: False + Whether all axes share their x- and y-axis. Note that in any case, + all axes in a column share their x-axis and all axes in a row share + their y-axis. + aspect : bool, default: True + Whether the axes aspect ratio follows the aspect ratio of the data + limits. + label_mode : {"L", "1", "all"}, default: "L" + Determines which axes will get tick labels: + + - "L": All axes on the left column get vertical tick labels; + all axes on the bottom row get horizontal tick labels. + - "1": Only the bottom left axes is labelled. + - "all": all axes are labelled. + + cbar_mode : {"each", "single", "edge", None}, default: None + Whether to create a colorbar for "each" axes, a "single" colorbar + for the entire grid, colorbars only for axes on the "edge" + determined by *cbar_location*, or no colorbars. The colorbars are + stored in the :attr:`cbar_axes` attribute. + cbar_location : {"left", "right", "bottom", "top"}, default: "right" + cbar_pad : float, default: None + Padding between the image axes and the colorbar axes. + cbar_size : size specification (see `.Size.from_any`), default: "5%" + Colorbar size. + cbar_set_cax : bool, default: True + If True, each axes in the grid has a *cax* attribute that is bound + to associated *cbar_axes*. + axes_class : subclass of `matplotlib.axes.Axes`, default: None + """ + _api.check_in_list(["each", "single", "edge", None], + cbar_mode=cbar_mode) + _api.check_in_list(["left", "right", "bottom", "top"], + cbar_location=cbar_location) + self._colorbar_mode = cbar_mode + self._colorbar_location = cbar_location + self._colorbar_pad = cbar_pad + self._colorbar_size = cbar_size + # The colorbar axes are created in _init_locators(). + + super().__init__( + fig, rect, nrows_ncols, ngrids, + direction=direction, axes_pad=axes_pad, + share_all=share_all, share_x=True, share_y=True, aspect=aspect, + label_mode=label_mode, axes_class=axes_class) + + for ax in self.cbar_axes: + fig.add_axes(ax) + + if cbar_set_cax: + if self._colorbar_mode == "single": + for ax in self.axes_all: + ax.cax = self.cbar_axes[0] + elif self._colorbar_mode == "edge": + for index, ax in enumerate(self.axes_all): + col, row = self._get_col_row(index) + if self._colorbar_location in ("left", "right"): + ax.cax = self.cbar_axes[row] + else: + ax.cax = self.cbar_axes[col] + else: + for ax, cax in zip(self.axes_all, self.cbar_axes): + ax.cax = cax + + def _init_locators(self): + # Slightly abusing this method to inject colorbar creation into init. + + if self._colorbar_pad is None: + # horizontal or vertical arrangement? + if self._colorbar_location in ("left", "right"): + self._colorbar_pad = self._horiz_pad_size.fixed_size + else: + self._colorbar_pad = self._vert_pad_size.fixed_size + self.cbar_axes = [ + _cbaraxes_class_factory(self._defaultAxesClass)( + self.axes_all[0].figure, self._divider.get_position(), + orientation=self._colorbar_location) + for _ in range(self.ngrids)] + + cb_mode = self._colorbar_mode + cb_location = self._colorbar_location + + h = [] + v = [] + + h_ax_pos = [] + h_cb_pos = [] + if cb_mode == "single" and cb_location in ("left", "bottom"): + if cb_location == "left": + sz = self._nrows * Size.AxesX(self.axes_llc) + h.append(Size.from_any(self._colorbar_size, sz)) + h.append(Size.from_any(self._colorbar_pad, sz)) + locator = self._divider.new_locator(nx=0, ny=0, ny1=-1) + elif cb_location == "bottom": + sz = self._ncols * Size.AxesY(self.axes_llc) + v.append(Size.from_any(self._colorbar_size, sz)) + v.append(Size.from_any(self._colorbar_pad, sz)) + locator = self._divider.new_locator(nx=0, nx1=-1, ny=0) + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[0].set_axes_locator(locator) + self.cbar_axes[0].set_visible(True) + + for col, ax in enumerate(self.axes_row[0]): + if h: + h.append(self._horiz_pad_size) + + if ax: + sz = Size.AxesX(ax, aspect="axes", ref_ax=self.axes_all[0]) + else: + sz = Size.AxesX(self.axes_all[0], + aspect="axes", ref_ax=self.axes_all[0]) + + if (cb_location == "left" + and (cb_mode == "each" + or (cb_mode == "edge" and col == 0))): + h_cb_pos.append(len(h)) + h.append(Size.from_any(self._colorbar_size, sz)) + h.append(Size.from_any(self._colorbar_pad, sz)) + + h_ax_pos.append(len(h)) + h.append(sz) + + if (cb_location == "right" + and (cb_mode == "each" + or (cb_mode == "edge" and col == self._ncols - 1))): + h.append(Size.from_any(self._colorbar_pad, sz)) + h_cb_pos.append(len(h)) + h.append(Size.from_any(self._colorbar_size, sz)) + + v_ax_pos = [] + v_cb_pos = [] + for row, ax in enumerate(self.axes_column[0][::-1]): + if v: + v.append(self._vert_pad_size) + + if ax: + sz = Size.AxesY(ax, aspect="axes", ref_ax=self.axes_all[0]) + else: + sz = Size.AxesY(self.axes_all[0], + aspect="axes", ref_ax=self.axes_all[0]) + + if (cb_location == "bottom" + and (cb_mode == "each" + or (cb_mode == "edge" and row == 0))): + v_cb_pos.append(len(v)) + v.append(Size.from_any(self._colorbar_size, sz)) + v.append(Size.from_any(self._colorbar_pad, sz)) + + v_ax_pos.append(len(v)) + v.append(sz) + + if (cb_location == "top" + and (cb_mode == "each" + or (cb_mode == "edge" and row == self._nrows - 1))): + v.append(Size.from_any(self._colorbar_pad, sz)) + v_cb_pos.append(len(v)) + v.append(Size.from_any(self._colorbar_size, sz)) + + for i in range(self.ngrids): + col, row = self._get_col_row(i) + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_ax_pos[self._nrows-1-row]) + self.axes_all[i].set_axes_locator(locator) + + if cb_mode == "each": + if cb_location in ("right", "left"): + locator = self._divider.new_locator( + nx=h_cb_pos[col], ny=v_ax_pos[self._nrows - 1 - row]) + + elif cb_location in ("top", "bottom"): + locator = self._divider.new_locator( + nx=h_ax_pos[col], ny=v_cb_pos[self._nrows - 1 - row]) + + self.cbar_axes[i].set_axes_locator(locator) + elif cb_mode == "edge": + if (cb_location == "left" and col == 0 + or cb_location == "right" and col == self._ncols - 1): + locator = self._divider.new_locator( + nx=h_cb_pos[0], ny=v_ax_pos[self._nrows - 1 - row]) + self.cbar_axes[row].set_axes_locator(locator) + elif (cb_location == "bottom" and row == self._nrows - 1 + or cb_location == "top" and row == 0): + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_cb_pos[0]) + self.cbar_axes[col].set_axes_locator(locator) + + if cb_mode == "single": + if cb_location == "right": + sz = self._nrows * Size.AxesX(self.axes_llc) + h.append(Size.from_any(self._colorbar_pad, sz)) + h.append(Size.from_any(self._colorbar_size, sz)) + locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1) + elif cb_location == "top": + sz = self._ncols * Size.AxesY(self.axes_llc) + v.append(Size.from_any(self._colorbar_pad, sz)) + v.append(Size.from_any(self._colorbar_size, sz)) + locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2) + if cb_location in ("right", "top"): + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[0].set_axes_locator(locator) + self.cbar_axes[0].set_visible(True) + elif cb_mode == "each": + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(True) + elif cb_mode == "edge": + if cb_location in ("right", "left"): + count = self._nrows + else: + count = self._ncols + for i in range(count): + self.cbar_axes[i].set_visible(True) + for j in range(i + 1, self.ngrids): + self.cbar_axes[j].set_visible(False) + else: + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[i].set_position([1., 1., 0.001, 0.001], + which="active") + + self._divider.set_horizontal(h) + self._divider.set_vertical(v) + + +AxesGrid = ImageGrid diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_rgb.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_rgb.py new file mode 100644 index 00000000..52fd707e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_rgb.py @@ -0,0 +1,157 @@ +from types import MethodType + +import numpy as np + +from .axes_divider import make_axes_locatable, Size +from .mpl_axes import Axes, SimpleAxisArtist + + +def make_rgb_axes(ax, pad=0.01, axes_class=None, **kwargs): + """ + Parameters + ---------- + ax : `~matplotlib.axes.Axes` + Axes instance to create the RGB Axes in. + pad : float, optional + Fraction of the Axes height to pad. + axes_class : `matplotlib.axes.Axes` or None, optional + Axes class to use for the R, G, and B Axes. If None, use + the same class as *ax*. + **kwargs + Forwarded to *axes_class* init for the R, G, and B Axes. + """ + + divider = make_axes_locatable(ax) + + pad_size = pad * Size.AxesY(ax) + + xsize = ((1-2*pad)/3) * Size.AxesX(ax) + ysize = ((1-2*pad)/3) * Size.AxesY(ax) + + divider.set_horizontal([Size.AxesX(ax), pad_size, xsize]) + divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize]) + + ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1)) + + ax_rgb = [] + if axes_class is None: + axes_class = type(ax) + + for ny in [4, 2, 0]: + ax1 = axes_class(ax.get_figure(), ax.get_position(original=True), + sharex=ax, sharey=ax, **kwargs) + locator = divider.new_locator(nx=2, ny=ny) + ax1.set_axes_locator(locator) + for t in ax1.yaxis.get_ticklabels() + ax1.xaxis.get_ticklabels(): + t.set_visible(False) + try: + for axis in ax1.axis.values(): + axis.major_ticklabels.set_visible(False) + except AttributeError: + pass + + ax_rgb.append(ax1) + + fig = ax.get_figure() + for ax1 in ax_rgb: + fig.add_axes(ax1) + + return ax_rgb + + +class RGBAxes: + """ + 4-panel `~.Axes.imshow` (RGB, R, G, B). + + Layout:: + + ┌───────────────┬─────┐ + │ │ R │ + │ ├─────┤ + │ RGB │ G │ + │ ├─────┤ + │ │ B │ + └───────────────┴─────┘ + + Subclasses can override the ``_defaultAxesClass`` attribute. + By default RGBAxes uses `.mpl_axes.Axes`. + + Attributes + ---------- + RGB : ``_defaultAxesClass`` + The Axes object for the three-channel `~.Axes.imshow`. + R : ``_defaultAxesClass`` + The Axes object for the red channel `~.Axes.imshow`. + G : ``_defaultAxesClass`` + The Axes object for the green channel `~.Axes.imshow`. + B : ``_defaultAxesClass`` + The Axes object for the blue channel `~.Axes.imshow`. + """ + + _defaultAxesClass = Axes + + def __init__(self, *args, pad=0, **kwargs): + """ + Parameters + ---------- + pad : float, default: 0 + Fraction of the Axes height to put as padding. + axes_class : `~matplotlib.axes.Axes` + Axes class to use. If not provided, ``_defaultAxesClass`` is used. + *args + Forwarded to *axes_class* init for the RGB Axes + **kwargs + Forwarded to *axes_class* init for the RGB, R, G, and B Axes + """ + axes_class = kwargs.pop("axes_class", self._defaultAxesClass) + self.RGB = ax = axes_class(*args, **kwargs) + ax.get_figure().add_axes(ax) + self.R, self.G, self.B = make_rgb_axes( + ax, pad=pad, axes_class=axes_class, **kwargs) + # Set the line color and ticks for the axes. + for ax1 in [self.RGB, self.R, self.G, self.B]: + if isinstance(ax1.axis, MethodType): + ad = Axes.AxisDict(self) + ad.update( + bottom=SimpleAxisArtist(ax1.xaxis, 1, ax1.spines["bottom"]), + top=SimpleAxisArtist(ax1.xaxis, 2, ax1.spines["top"]), + left=SimpleAxisArtist(ax1.yaxis, 1, ax1.spines["left"]), + right=SimpleAxisArtist(ax1.yaxis, 2, ax1.spines["right"])) + else: + ad = ax1.axis + ad[:].line.set_color("w") + ad[:].major_ticks.set_markeredgecolor("w") + + def imshow_rgb(self, r, g, b, **kwargs): + """ + Create the four images {rgb, r, g, b}. + + Parameters + ---------- + r, g, b : array-like + The red, green, and blue arrays. + **kwargs + Forwarded to `~.Axes.imshow` calls for the four images. + + Returns + ------- + rgb : `~matplotlib.image.AxesImage` + r : `~matplotlib.image.AxesImage` + g : `~matplotlib.image.AxesImage` + b : `~matplotlib.image.AxesImage` + """ + if not (r.shape == g.shape == b.shape): + raise ValueError( + f'Input shapes ({r.shape}, {g.shape}, {b.shape}) do not match') + RGB = np.dstack([r, g, b]) + R = np.zeros_like(RGB) + R[:, :, 0] = r + G = np.zeros_like(RGB) + G[:, :, 1] = g + B = np.zeros_like(RGB) + B[:, :, 2] = b + im_rgb = self.RGB.imshow(RGB, **kwargs) + im_r = self.R.imshow(R, **kwargs) + im_g = self.G.imshow(G, **kwargs) + im_b = self.B.imshow(B, **kwargs) + return im_rgb, im_r, im_g, im_b diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_size.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_size.py new file mode 100644 index 00000000..d2514720 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/axes_size.py @@ -0,0 +1,248 @@ +""" +Provides classes of simple units that will be used with `.AxesDivider` +class (or others) to determine the size of each Axes. The unit +classes define `get_size` method that returns a tuple of two floats, +meaning relative and absolute sizes, respectively. + +Note that this class is nothing more than a simple tuple of two +floats. Take a look at the Divider class to see how these two +values are used. +""" + +from numbers import Real + +from matplotlib import _api +from matplotlib.axes import Axes + + +class _Base: + def __rmul__(self, other): + return Fraction(other, self) + + def __add__(self, other): + if isinstance(other, _Base): + return Add(self, other) + else: + return Add(self, Fixed(other)) + + def get_size(self, renderer): + """ + Return two-float tuple with relative and absolute sizes. + """ + raise NotImplementedError("Subclasses must implement") + + +class Add(_Base): + """ + Sum of two sizes. + """ + + def __init__(self, a, b): + self._a = a + self._b = b + + def get_size(self, renderer): + a_rel_size, a_abs_size = self._a.get_size(renderer) + b_rel_size, b_abs_size = self._b.get_size(renderer) + return a_rel_size + b_rel_size, a_abs_size + b_abs_size + + +class Fixed(_Base): + """ + Simple fixed size with absolute part = *fixed_size* and relative part = 0. + """ + + def __init__(self, fixed_size): + _api.check_isinstance(Real, fixed_size=fixed_size) + self.fixed_size = fixed_size + + def get_size(self, renderer): + rel_size = 0. + abs_size = self.fixed_size + return rel_size, abs_size + + +class Scaled(_Base): + """ + Simple scaled(?) size with absolute part = 0 and + relative part = *scalable_size*. + """ + + def __init__(self, scalable_size): + self._scalable_size = scalable_size + + def get_size(self, renderer): + rel_size = self._scalable_size + abs_size = 0. + return rel_size, abs_size + +Scalable = Scaled + + +def _get_axes_aspect(ax): + aspect = ax.get_aspect() + if aspect == "auto": + aspect = 1. + return aspect + + +class AxesX(_Base): + """ + Scaled size whose relative part corresponds to the data width + of the *axes* multiplied by the *aspect*. + """ + + def __init__(self, axes, aspect=1., ref_ax=None): + self._axes = axes + self._aspect = aspect + if aspect == "axes" and ref_ax is None: + raise ValueError("ref_ax must be set when aspect='axes'") + self._ref_ax = ref_ax + + def get_size(self, renderer): + l1, l2 = self._axes.get_xlim() + if self._aspect == "axes": + ref_aspect = _get_axes_aspect(self._ref_ax) + aspect = ref_aspect / _get_axes_aspect(self._axes) + else: + aspect = self._aspect + + rel_size = abs(l2-l1)*aspect + abs_size = 0. + return rel_size, abs_size + + +class AxesY(_Base): + """ + Scaled size whose relative part corresponds to the data height + of the *axes* multiplied by the *aspect*. + """ + + def __init__(self, axes, aspect=1., ref_ax=None): + self._axes = axes + self._aspect = aspect + if aspect == "axes" and ref_ax is None: + raise ValueError("ref_ax must be set when aspect='axes'") + self._ref_ax = ref_ax + + def get_size(self, renderer): + l1, l2 = self._axes.get_ylim() + + if self._aspect == "axes": + ref_aspect = _get_axes_aspect(self._ref_ax) + aspect = _get_axes_aspect(self._axes) + else: + aspect = self._aspect + + rel_size = abs(l2-l1)*aspect + abs_size = 0. + return rel_size, abs_size + + +class MaxExtent(_Base): + """ + Size whose absolute part is either the largest width or the largest height + of the given *artist_list*. + """ + + def __init__(self, artist_list, w_or_h): + self._artist_list = artist_list + _api.check_in_list(["width", "height"], w_or_h=w_or_h) + self._w_or_h = w_or_h + + def add_artist(self, a): + self._artist_list.append(a) + + def get_size(self, renderer): + rel_size = 0. + extent_list = [ + getattr(a.get_window_extent(renderer), self._w_or_h) / a.figure.dpi + for a in self._artist_list] + abs_size = max(extent_list, default=0) + return rel_size, abs_size + + +class MaxWidth(MaxExtent): + """ + Size whose absolute part is the largest width of the given *artist_list*. + """ + + def __init__(self, artist_list): + super().__init__(artist_list, "width") + + +class MaxHeight(MaxExtent): + """ + Size whose absolute part is the largest height of the given *artist_list*. + """ + + def __init__(self, artist_list): + super().__init__(artist_list, "height") + + +class Fraction(_Base): + """ + An instance whose size is a *fraction* of the *ref_size*. + + >>> s = Fraction(0.3, AxesX(ax)) + """ + + def __init__(self, fraction, ref_size): + _api.check_isinstance(Real, fraction=fraction) + self._fraction_ref = ref_size + self._fraction = fraction + + def get_size(self, renderer): + if self._fraction_ref is None: + return self._fraction, 0. + else: + r, a = self._fraction_ref.get_size(renderer) + rel_size = r*self._fraction + abs_size = a*self._fraction + return rel_size, abs_size + + +def from_any(size, fraction_ref=None): + """ + Create a Fixed unit when the first argument is a float, or a + Fraction unit if that is a string that ends with %. The second + argument is only meaningful when Fraction unit is created. + + >>> from mpl_toolkits.axes_grid1.axes_size import from_any + >>> a = from_any(1.2) # => Fixed(1.2) + >>> from_any("50%", a) # => Fraction(0.5, a) + """ + if isinstance(size, Real): + return Fixed(size) + elif isinstance(size, str): + if size[-1] == "%": + return Fraction(float(size[:-1]) / 100, fraction_ref) + raise ValueError("Unknown format") + + +class _AxesDecorationsSize(_Base): + """ + Fixed size, corresponding to the size of decorations on a given Axes side. + """ + + _get_size_map = { + "left": lambda tight_bb, axes_bb: axes_bb.xmin - tight_bb.xmin, + "right": lambda tight_bb, axes_bb: tight_bb.xmax - axes_bb.xmax, + "bottom": lambda tight_bb, axes_bb: axes_bb.ymin - tight_bb.ymin, + "top": lambda tight_bb, axes_bb: tight_bb.ymax - axes_bb.ymax, + } + + def __init__(self, ax, direction): + self._get_size = _api.check_getitem( + self._get_size_map, direction=direction) + self._ax_list = [ax] if isinstance(ax, Axes) else ax + + def get_size(self, renderer): + sz = max([ + self._get_size(ax.get_tightbbox(renderer, call_axes_locator=False), + ax.bbox) + for ax in self._ax_list]) + dpi = renderer.points_to_pixels(72) + abs_size = sz / dpi + rel_size = 0 + return rel_size, abs_size diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/inset_locator.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/inset_locator.py new file mode 100644 index 00000000..6d591a45 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/inset_locator.py @@ -0,0 +1,561 @@ +""" +A collection of functions and objects for creating or placing inset axes. +""" + +from matplotlib import _api, _docstring +from matplotlib.offsetbox import AnchoredOffsetbox +from matplotlib.patches import Patch, Rectangle +from matplotlib.path import Path +from matplotlib.transforms import Bbox, BboxTransformTo +from matplotlib.transforms import IdentityTransform, TransformedBbox + +from . import axes_size as Size +from .parasite_axes import HostAxes + + +@_api.deprecated("3.8", alternative="Axes.inset_axes") +class InsetPosition: + @_docstring.dedent_interpd + def __init__(self, parent, lbwh): + """ + An object for positioning an inset axes. + + This is created by specifying the normalized coordinates in the axes, + instead of the figure. + + Parameters + ---------- + parent : `~matplotlib.axes.Axes` + Axes to use for normalizing coordinates. + + lbwh : iterable of four floats + The left edge, bottom edge, width, and height of the inset axes, in + units of the normalized coordinate of the *parent* axes. + + See Also + -------- + :meth:`matplotlib.axes.Axes.set_axes_locator` + + Examples + -------- + The following bounds the inset axes to a box with 20%% of the parent + axes height and 40%% of the width. The size of the axes specified + ([0, 0, 1, 1]) ensures that the axes completely fills the bounding box: + + >>> parent_axes = plt.gca() + >>> ax_ins = plt.axes([0, 0, 1, 1]) + >>> ip = InsetPosition(parent_axes, [0.5, 0.1, 0.4, 0.2]) + >>> ax_ins.set_axes_locator(ip) + """ + self.parent = parent + self.lbwh = lbwh + + def __call__(self, ax, renderer): + bbox_parent = self.parent.get_position(original=False) + trans = BboxTransformTo(bbox_parent) + bbox_inset = Bbox.from_bounds(*self.lbwh) + bb = TransformedBbox(bbox_inset, trans) + return bb + + +class AnchoredLocatorBase(AnchoredOffsetbox): + def __init__(self, bbox_to_anchor, offsetbox, loc, + borderpad=0.5, bbox_transform=None): + super().__init__( + loc, pad=0., child=None, borderpad=borderpad, + bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform + ) + + def draw(self, renderer): + raise RuntimeError("No draw method should be called") + + def __call__(self, ax, renderer): + if renderer is None: + renderer = ax.figure._get_renderer() + self.axes = ax + bbox = self.get_window_extent(renderer) + px, py = self.get_offset(bbox.width, bbox.height, 0, 0, renderer) + bbox_canvas = Bbox.from_bounds(px, py, bbox.width, bbox.height) + tr = ax.figure.transSubfigure.inverted() + return TransformedBbox(bbox_canvas, tr) + + +class AnchoredSizeLocator(AnchoredLocatorBase): + def __init__(self, bbox_to_anchor, x_size, y_size, loc, + borderpad=0.5, bbox_transform=None): + super().__init__( + bbox_to_anchor, None, loc, + borderpad=borderpad, bbox_transform=bbox_transform + ) + + self.x_size = Size.from_any(x_size) + self.y_size = Size.from_any(y_size) + + def get_bbox(self, renderer): + bbox = self.get_bbox_to_anchor() + dpi = renderer.points_to_pixels(72.) + + r, a = self.x_size.get_size(renderer) + width = bbox.width * r + a * dpi + r, a = self.y_size.get_size(renderer) + height = bbox.height * r + a * dpi + + fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) + pad = self.pad * fontsize + + return Bbox.from_bounds(0, 0, width, height).padded(pad) + + +class AnchoredZoomLocator(AnchoredLocatorBase): + def __init__(self, parent_axes, zoom, loc, + borderpad=0.5, + bbox_to_anchor=None, + bbox_transform=None): + self.parent_axes = parent_axes + self.zoom = zoom + if bbox_to_anchor is None: + bbox_to_anchor = parent_axes.bbox + super().__init__( + bbox_to_anchor, None, loc, borderpad=borderpad, + bbox_transform=bbox_transform) + + def get_bbox(self, renderer): + bb = self.parent_axes.transData.transform_bbox(self.axes.viewLim) + fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) + pad = self.pad * fontsize + return ( + Bbox.from_bounds( + 0, 0, abs(bb.width * self.zoom), abs(bb.height * self.zoom)) + .padded(pad)) + + +class BboxPatch(Patch): + @_docstring.dedent_interpd + def __init__(self, bbox, **kwargs): + """ + Patch showing the shape bounded by a Bbox. + + Parameters + ---------- + bbox : `~matplotlib.transforms.Bbox` + Bbox to use for the extents of this patch. + + **kwargs + Patch properties. Valid arguments include: + + %(Patch:kwdoc)s + """ + if "transform" in kwargs: + raise ValueError("transform should not be set") + + kwargs["transform"] = IdentityTransform() + super().__init__(**kwargs) + self.bbox = bbox + + def get_path(self): + # docstring inherited + x0, y0, x1, y1 = self.bbox.extents + return Path._create_closed([(x0, y0), (x1, y0), (x1, y1), (x0, y1)]) + + +class BboxConnector(Patch): + @staticmethod + def get_bbox_edge_pos(bbox, loc): + """ + Return the ``(x, y)`` coordinates of corner *loc* of *bbox*; parameters + behave as documented for the `.BboxConnector` constructor. + """ + x0, y0, x1, y1 = bbox.extents + if loc == 1: + return x1, y1 + elif loc == 2: + return x0, y1 + elif loc == 3: + return x0, y0 + elif loc == 4: + return x1, y0 + + @staticmethod + def connect_bbox(bbox1, bbox2, loc1, loc2=None): + """ + Construct a `.Path` connecting corner *loc1* of *bbox1* to corner + *loc2* of *bbox2*, where parameters behave as documented as for the + `.BboxConnector` constructor. + """ + if isinstance(bbox1, Rectangle): + bbox1 = TransformedBbox(Bbox.unit(), bbox1.get_transform()) + if isinstance(bbox2, Rectangle): + bbox2 = TransformedBbox(Bbox.unit(), bbox2.get_transform()) + if loc2 is None: + loc2 = loc1 + x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1) + x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2) + return Path([[x1, y1], [x2, y2]]) + + @_docstring.dedent_interpd + def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs): + """ + Connect two bboxes with a straight line. + + Parameters + ---------- + bbox1, bbox2 : `~matplotlib.transforms.Bbox` + Bounding boxes to connect. + + loc1, loc2 : {1, 2, 3, 4} + Corner of *bbox1* and *bbox2* to draw the line. Valid values are:: + + 'upper right' : 1, + 'upper left' : 2, + 'lower left' : 3, + 'lower right' : 4 + + *loc2* is optional and defaults to *loc1*. + + **kwargs + Patch properties for the line drawn. Valid arguments include: + + %(Patch:kwdoc)s + """ + if "transform" in kwargs: + raise ValueError("transform should not be set") + + kwargs["transform"] = IdentityTransform() + kwargs.setdefault( + "fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs))) + super().__init__(**kwargs) + self.bbox1 = bbox1 + self.bbox2 = bbox2 + self.loc1 = loc1 + self.loc2 = loc2 + + def get_path(self): + # docstring inherited + return self.connect_bbox(self.bbox1, self.bbox2, + self.loc1, self.loc2) + + +class BboxConnectorPatch(BboxConnector): + @_docstring.dedent_interpd + def __init__(self, bbox1, bbox2, loc1a, loc2a, loc1b, loc2b, **kwargs): + """ + Connect two bboxes with a quadrilateral. + + The quadrilateral is specified by two lines that start and end at + corners of the bboxes. The four sides of the quadrilateral are defined + by the two lines given, the line between the two corners specified in + *bbox1* and the line between the two corners specified in *bbox2*. + + Parameters + ---------- + bbox1, bbox2 : `~matplotlib.transforms.Bbox` + Bounding boxes to connect. + + loc1a, loc2a, loc1b, loc2b : {1, 2, 3, 4} + The first line connects corners *loc1a* of *bbox1* and *loc2a* of + *bbox2*; the second line connects corners *loc1b* of *bbox1* and + *loc2b* of *bbox2*. Valid values are:: + + 'upper right' : 1, + 'upper left' : 2, + 'lower left' : 3, + 'lower right' : 4 + + **kwargs + Patch properties for the line drawn: + + %(Patch:kwdoc)s + """ + if "transform" in kwargs: + raise ValueError("transform should not be set") + super().__init__(bbox1, bbox2, loc1a, loc2a, **kwargs) + self.loc1b = loc1b + self.loc2b = loc2b + + def get_path(self): + # docstring inherited + path1 = self.connect_bbox(self.bbox1, self.bbox2, self.loc1, self.loc2) + path2 = self.connect_bbox(self.bbox2, self.bbox1, + self.loc2b, self.loc1b) + path_merged = [*path1.vertices, *path2.vertices, path1.vertices[0]] + return Path(path_merged) + + +def _add_inset_axes(parent_axes, axes_class, axes_kwargs, axes_locator): + """Helper function to add an inset axes and disable navigation in it.""" + if axes_class is None: + axes_class = HostAxes + if axes_kwargs is None: + axes_kwargs = {} + inset_axes = axes_class( + parent_axes.figure, parent_axes.get_position(), + **{"navigate": False, **axes_kwargs, "axes_locator": axes_locator}) + return parent_axes.figure.add_axes(inset_axes) + + +@_docstring.dedent_interpd +def inset_axes(parent_axes, width, height, loc='upper right', + bbox_to_anchor=None, bbox_transform=None, + axes_class=None, axes_kwargs=None, + borderpad=0.5): + """ + Create an inset axes with a given width and height. + + Both sizes used can be specified either in inches or percentage. + For example,:: + + inset_axes(parent_axes, width='40%%', height='30%%', loc='lower left') + + creates in inset axes in the lower left corner of *parent_axes* which spans + over 30%% in height and 40%% in width of the *parent_axes*. Since the usage + of `.inset_axes` may become slightly tricky when exceeding such standard + cases, it is recommended to read :doc:`the examples + </gallery/axes_grid1/inset_locator_demo>`. + + Notes + ----- + The meaning of *bbox_to_anchor* and *bbox_to_transform* is interpreted + differently from that of legend. The value of bbox_to_anchor + (or the return value of its get_points method; the default is + *parent_axes.bbox*) is transformed by the bbox_transform (the default + is Identity transform) and then interpreted as points in the pixel + coordinate (which is dpi dependent). + + Thus, following three calls are identical and creates an inset axes + with respect to the *parent_axes*:: + + axins = inset_axes(parent_axes, "30%%", "40%%") + axins = inset_axes(parent_axes, "30%%", "40%%", + bbox_to_anchor=parent_axes.bbox) + axins = inset_axes(parent_axes, "30%%", "40%%", + bbox_to_anchor=(0, 0, 1, 1), + bbox_transform=parent_axes.transAxes) + + Parameters + ---------- + parent_axes : `matplotlib.axes.Axes` + Axes to place the inset axes. + + width, height : float or str + Size of the inset axes to create. If a float is provided, it is + the size in inches, e.g. *width=1.3*. If a string is provided, it is + the size in relative units, e.g. *width='40%%'*. By default, i.e. if + neither *bbox_to_anchor* nor *bbox_transform* are specified, those + are relative to the parent_axes. Otherwise, they are to be understood + relative to the bounding box provided via *bbox_to_anchor*. + + loc : str, default: 'upper right' + Location to place the inset axes. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + + bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional + Bbox that the inset axes will be anchored to. If None, + a tuple of (0, 0, 1, 1) is used if *bbox_transform* is set + to *parent_axes.transAxes* or *parent_axes.figure.transFigure*. + Otherwise, *parent_axes.bbox* is used. If a tuple, can be either + [left, bottom, width, height], or [left, bottom]. + If the kwargs *width* and/or *height* are specified in relative units, + the 2-tuple [left, bottom] cannot be used. Note that, + unless *bbox_transform* is set, the units of the bounding box + are interpreted in the pixel coordinate. When using *bbox_to_anchor* + with tuple, it almost always makes sense to also specify + a *bbox_transform*. This might often be the axes transform + *parent_axes.transAxes*. + + bbox_transform : `~matplotlib.transforms.Transform`, optional + Transformation for the bbox that contains the inset axes. + If None, a `.transforms.IdentityTransform` is used. The value + of *bbox_to_anchor* (or the return value of its get_points method) + is transformed by the *bbox_transform* and then interpreted + as points in the pixel coordinate (which is dpi dependent). + You may provide *bbox_to_anchor* in some normalized coordinate, + and give an appropriate transform (e.g., *parent_axes.transAxes*). + + axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes` + The type of the newly created inset axes. + + axes_kwargs : dict, optional + Keyword arguments to pass to the constructor of the inset axes. + Valid arguments include: + + %(Axes:kwdoc)s + + borderpad : float, default: 0.5 + Padding between inset axes and the bbox_to_anchor. + The units are axes font size, i.e. for a default font size of 10 points + *borderpad = 0.5* is equivalent to a padding of 5 points. + + Returns + ------- + inset_axes : *axes_class* + Inset axes object created. + """ + + if (bbox_transform in [parent_axes.transAxes, parent_axes.figure.transFigure] + and bbox_to_anchor is None): + _api.warn_external("Using the axes or figure transform requires a " + "bounding box in the respective coordinates. " + "Using bbox_to_anchor=(0, 0, 1, 1) now.") + bbox_to_anchor = (0, 0, 1, 1) + if bbox_to_anchor is None: + bbox_to_anchor = parent_axes.bbox + if (isinstance(bbox_to_anchor, tuple) and + (isinstance(width, str) or isinstance(height, str))): + if len(bbox_to_anchor) != 4: + raise ValueError("Using relative units for width or height " + "requires to provide a 4-tuple or a " + "`Bbox` instance to `bbox_to_anchor.") + return _add_inset_axes( + parent_axes, axes_class, axes_kwargs, + AnchoredSizeLocator( + bbox_to_anchor, width, height, loc=loc, + bbox_transform=bbox_transform, borderpad=borderpad)) + + +@_docstring.dedent_interpd +def zoomed_inset_axes(parent_axes, zoom, loc='upper right', + bbox_to_anchor=None, bbox_transform=None, + axes_class=None, axes_kwargs=None, + borderpad=0.5): + """ + Create an anchored inset axes by scaling a parent axes. For usage, also see + :doc:`the examples </gallery/axes_grid1/inset_locator_demo2>`. + + Parameters + ---------- + parent_axes : `~matplotlib.axes.Axes` + Axes to place the inset axes. + + zoom : float + Scaling factor of the data axes. *zoom* > 1 will enlarge the + coordinates (i.e., "zoomed in"), while *zoom* < 1 will shrink the + coordinates (i.e., "zoomed out"). + + loc : str, default: 'upper right' + Location to place the inset axes. Valid locations are + 'upper left', 'upper center', 'upper right', + 'center left', 'center', 'center right', + 'lower left', 'lower center', 'lower right'. + For backward compatibility, numeric values are accepted as well. + See the parameter *loc* of `.Legend` for details. + + bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional + Bbox that the inset axes will be anchored to. If None, + *parent_axes.bbox* is used. If a tuple, can be either + [left, bottom, width, height], or [left, bottom]. + If the kwargs *width* and/or *height* are specified in relative units, + the 2-tuple [left, bottom] cannot be used. Note that + the units of the bounding box are determined through the transform + in use. When using *bbox_to_anchor* it almost always makes sense to + also specify a *bbox_transform*. This might often be the axes transform + *parent_axes.transAxes*. + + bbox_transform : `~matplotlib.transforms.Transform`, optional + Transformation for the bbox that contains the inset axes. + If None, a `.transforms.IdentityTransform` is used (i.e. pixel + coordinates). This is useful when not providing any argument to + *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes + sense to also specify a *bbox_transform*. This might often be the + axes transform *parent_axes.transAxes*. Inversely, when specifying + the axes- or figure-transform here, be aware that not specifying + *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are + in display (pixel) coordinates. + + axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes` + The type of the newly created inset axes. + + axes_kwargs : dict, optional + Keyword arguments to pass to the constructor of the inset axes. + Valid arguments include: + + %(Axes:kwdoc)s + + borderpad : float, default: 0.5 + Padding between inset axes and the bbox_to_anchor. + The units are axes font size, i.e. for a default font size of 10 points + *borderpad = 0.5* is equivalent to a padding of 5 points. + + Returns + ------- + inset_axes : *axes_class* + Inset axes object created. + """ + + return _add_inset_axes( + parent_axes, axes_class, axes_kwargs, + AnchoredZoomLocator( + parent_axes, zoom=zoom, loc=loc, + bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform, + borderpad=borderpad)) + + +class _TransformedBboxWithCallback(TransformedBbox): + """ + Variant of `.TransformBbox` which calls *callback* before returning points. + + Used by `.mark_inset` to unstale the parent axes' viewlim as needed. + """ + + def __init__(self, *args, callback, **kwargs): + super().__init__(*args, **kwargs) + self._callback = callback + + def get_points(self): + self._callback() + return super().get_points() + + +@_docstring.dedent_interpd +def mark_inset(parent_axes, inset_axes, loc1, loc2, **kwargs): + """ + Draw a box to mark the location of an area represented by an inset axes. + + This function draws a box in *parent_axes* at the bounding box of + *inset_axes*, and shows a connection with the inset axes by drawing lines + at the corners, giving a "zoomed in" effect. + + Parameters + ---------- + parent_axes : `~matplotlib.axes.Axes` + Axes which contains the area of the inset axes. + + inset_axes : `~matplotlib.axes.Axes` + The inset axes. + + loc1, loc2 : {1, 2, 3, 4} + Corners to use for connecting the inset axes and the area in the + parent axes. + + **kwargs + Patch properties for the lines and box drawn: + + %(Patch:kwdoc)s + + Returns + ------- + pp : `~matplotlib.patches.Patch` + The patch drawn to represent the area of the inset axes. + + p1, p2 : `~matplotlib.patches.Patch` + The patches connecting two corners of the inset axes and its area. + """ + rect = _TransformedBboxWithCallback( + inset_axes.viewLim, parent_axes.transData, + callback=parent_axes._unstale_viewLim) + + kwargs.setdefault("fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs))) + pp = BboxPatch(rect, **kwargs) + parent_axes.add_patch(pp) + + p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1, **kwargs) + inset_axes.add_patch(p1) + p1.set_clip_on(False) + p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2, **kwargs) + inset_axes.add_patch(p2) + p2.set_clip_on(False) + + return pp, p1, p2 diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/mpl_axes.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/mpl_axes.py new file mode 100644 index 00000000..51c87487 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/mpl_axes.py @@ -0,0 +1,128 @@ +import matplotlib.axes as maxes +from matplotlib.artist import Artist +from matplotlib.axis import XAxis, YAxis + + +class SimpleChainedObjects: + def __init__(self, objects): + self._objects = objects + + def __getattr__(self, k): + _a = SimpleChainedObjects([getattr(a, k) for a in self._objects]) + return _a + + def __call__(self, *args, **kwargs): + for m in self._objects: + m(*args, **kwargs) + + +class Axes(maxes.Axes): + + class AxisDict(dict): + def __init__(self, axes): + self.axes = axes + super().__init__() + + def __getitem__(self, k): + if isinstance(k, tuple): + r = SimpleChainedObjects( + # super() within a list comprehension needs explicit args. + [super(Axes.AxisDict, self).__getitem__(k1) for k1 in k]) + return r + elif isinstance(k, slice): + if k.start is None and k.stop is None and k.step is None: + return SimpleChainedObjects(list(self.values())) + else: + raise ValueError("Unsupported slice") + else: + return dict.__getitem__(self, k) + + def __call__(self, *v, **kwargs): + return maxes.Axes.axis(self.axes, *v, **kwargs) + + @property + def axis(self): + return self._axislines + + def clear(self): + # docstring inherited + super().clear() + # Init axis artists. + self._axislines = self.AxisDict(self) + self._axislines.update( + bottom=SimpleAxisArtist(self.xaxis, 1, self.spines["bottom"]), + top=SimpleAxisArtist(self.xaxis, 2, self.spines["top"]), + left=SimpleAxisArtist(self.yaxis, 1, self.spines["left"]), + right=SimpleAxisArtist(self.yaxis, 2, self.spines["right"])) + + +class SimpleAxisArtist(Artist): + def __init__(self, axis, axisnum, spine): + self._axis = axis + self._axisnum = axisnum + self.line = spine + + if isinstance(axis, XAxis): + self._axis_direction = ["bottom", "top"][axisnum-1] + elif isinstance(axis, YAxis): + self._axis_direction = ["left", "right"][axisnum-1] + else: + raise ValueError( + f"axis must be instance of XAxis or YAxis, but got {axis}") + super().__init__() + + @property + def major_ticks(self): + tickline = "tick%dline" % self._axisnum + return SimpleChainedObjects([getattr(tick, tickline) + for tick in self._axis.get_major_ticks()]) + + @property + def major_ticklabels(self): + label = "label%d" % self._axisnum + return SimpleChainedObjects([getattr(tick, label) + for tick in self._axis.get_major_ticks()]) + + @property + def label(self): + return self._axis.label + + def set_visible(self, b): + self.toggle(all=b) + self.line.set_visible(b) + self._axis.set_visible(True) + super().set_visible(b) + + def set_label(self, txt): + self._axis.set_label_text(txt) + + def toggle(self, all=None, ticks=None, ticklabels=None, label=None): + + if all: + _ticks, _ticklabels, _label = True, True, True + elif all is not None: + _ticks, _ticklabels, _label = False, False, False + else: + _ticks, _ticklabels, _label = None, None, None + + if ticks is not None: + _ticks = ticks + if ticklabels is not None: + _ticklabels = ticklabels + if label is not None: + _label = label + + if _ticks is not None: + tickparam = {f"tick{self._axisnum}On": _ticks} + self._axis.set_tick_params(**tickparam) + if _ticklabels is not None: + tickparam = {f"label{self._axisnum}On": _ticklabels} + self._axis.set_tick_params(**tickparam) + + if _label is not None: + pos = self._axis.get_label_position() + if (pos == self._axis_direction) and not _label: + self._axis.label.set_visible(False) + elif _label: + self._axis.label.set_visible(True) + self._axis.set_label_position(self._axis_direction) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/parasite_axes.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/parasite_axes.py new file mode 100644 index 00000000..2a2b5957 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/parasite_axes.py @@ -0,0 +1,257 @@ +from matplotlib import _api, cbook +import matplotlib.artist as martist +import matplotlib.transforms as mtransforms +from matplotlib.transforms import Bbox +from .mpl_axes import Axes + + +class ParasiteAxesBase: + + def __init__(self, parent_axes, aux_transform=None, + *, viewlim_mode=None, **kwargs): + self._parent_axes = parent_axes + self.transAux = aux_transform + self.set_viewlim_mode(viewlim_mode) + kwargs["frameon"] = False + super().__init__(parent_axes.figure, parent_axes._position, **kwargs) + + def clear(self): + super().clear() + martist.setp(self.get_children(), visible=False) + self._get_lines = self._parent_axes._get_lines + self._parent_axes.callbacks._connect_picklable( + "xlim_changed", self._sync_lims) + self._parent_axes.callbacks._connect_picklable( + "ylim_changed", self._sync_lims) + + def pick(self, mouseevent): + # This most likely goes to Artist.pick (depending on axes_class given + # to the factory), which only handles pick events registered on the + # axes associated with each child: + super().pick(mouseevent) + # But parasite axes are additionally given pick events from their host + # axes (cf. HostAxesBase.pick), which we handle here: + for a in self.get_children(): + if (hasattr(mouseevent.inaxes, "parasites") + and self in mouseevent.inaxes.parasites): + a.pick(mouseevent) + + # aux_transform support + + def _set_lim_and_transforms(self): + if self.transAux is not None: + self.transAxes = self._parent_axes.transAxes + self.transData = self.transAux + self._parent_axes.transData + self._xaxis_transform = mtransforms.blended_transform_factory( + self.transData, self.transAxes) + self._yaxis_transform = mtransforms.blended_transform_factory( + self.transAxes, self.transData) + else: + super()._set_lim_and_transforms() + + def set_viewlim_mode(self, mode): + _api.check_in_list([None, "equal", "transform"], mode=mode) + self._viewlim_mode = mode + + def get_viewlim_mode(self): + return self._viewlim_mode + + def _sync_lims(self, parent): + viewlim = parent.viewLim.frozen() + mode = self.get_viewlim_mode() + if mode is None: + pass + elif mode == "equal": + self.viewLim.set(viewlim) + elif mode == "transform": + self.viewLim.set(viewlim.transformed(self.transAux.inverted())) + else: + _api.check_in_list([None, "equal", "transform"], mode=mode) + + # end of aux_transform support + + +parasite_axes_class_factory = cbook._make_class_factory( + ParasiteAxesBase, "{}Parasite") +ParasiteAxes = parasite_axes_class_factory(Axes) + + +class HostAxesBase: + def __init__(self, *args, **kwargs): + self.parasites = [] + super().__init__(*args, **kwargs) + + def get_aux_axes( + self, tr=None, viewlim_mode="equal", axes_class=None, **kwargs): + """ + Add a parasite axes to this host. + + Despite this method's name, this should actually be thought of as an + ``add_parasite_axes`` method. + + .. versionchanged:: 3.7 + Defaults to same base axes class as host axes. + + Parameters + ---------- + tr : `~matplotlib.transforms.Transform` or None, default: None + If a `.Transform`, the following relation will hold: + ``parasite.transData = tr + host.transData``. + If None, the parasite's and the host's ``transData`` are unrelated. + viewlim_mode : {"equal", "transform", None}, default: "equal" + How the parasite's view limits are set: directly equal to the + parent axes ("equal"), equal after application of *tr* + ("transform"), or independently (None). + axes_class : subclass type of `~matplotlib.axes.Axes`, optional + The `~.axes.Axes` subclass that is instantiated. If None, the base + class of the host axes is used. + **kwargs + Other parameters are forwarded to the parasite axes constructor. + """ + if axes_class is None: + axes_class = self._base_axes_class + parasite_axes_class = parasite_axes_class_factory(axes_class) + ax2 = parasite_axes_class( + self, tr, viewlim_mode=viewlim_mode, **kwargs) + # note that ax2.transData == tr + ax1.transData + # Anything you draw in ax2 will match the ticks and grids of ax1. + self.parasites.append(ax2) + ax2._remove_method = self.parasites.remove + return ax2 + + def draw(self, renderer): + orig_children_len = len(self._children) + + locator = self.get_axes_locator() + if locator: + pos = locator(self, renderer) + self.set_position(pos, which="active") + self.apply_aspect(pos) + else: + self.apply_aspect() + + rect = self.get_position() + for ax in self.parasites: + ax.apply_aspect(rect) + self._children.extend(ax.get_children()) + + super().draw(renderer) + del self._children[orig_children_len:] + + def clear(self): + super().clear() + for ax in self.parasites: + ax.clear() + + def pick(self, mouseevent): + super().pick(mouseevent) + # Also pass pick events on to parasite axes and, in turn, their + # children (cf. ParasiteAxesBase.pick) + for a in self.parasites: + a.pick(mouseevent) + + def twinx(self, axes_class=None): + """ + Create a twin of Axes with a shared x-axis but independent y-axis. + + The y-axis of self will have ticks on the left and the returned axes + will have ticks on the right. + """ + ax = self._add_twin_axes(axes_class, sharex=self) + self.axis["right"].set_visible(False) + ax.axis["right"].set_visible(True) + ax.axis["left", "top", "bottom"].set_visible(False) + return ax + + def twiny(self, axes_class=None): + """ + Create a twin of Axes with a shared y-axis but independent x-axis. + + The x-axis of self will have ticks on the bottom and the returned axes + will have ticks on the top. + """ + ax = self._add_twin_axes(axes_class, sharey=self) + self.axis["top"].set_visible(False) + ax.axis["top"].set_visible(True) + ax.axis["left", "right", "bottom"].set_visible(False) + return ax + + def twin(self, aux_trans=None, axes_class=None): + """ + Create a twin of Axes with no shared axis. + + While self will have ticks on the left and bottom axis, the returned + axes will have ticks on the top and right axis. + """ + if aux_trans is None: + aux_trans = mtransforms.IdentityTransform() + ax = self._add_twin_axes( + axes_class, aux_transform=aux_trans, viewlim_mode="transform") + self.axis["top", "right"].set_visible(False) + ax.axis["top", "right"].set_visible(True) + ax.axis["left", "bottom"].set_visible(False) + return ax + + def _add_twin_axes(self, axes_class, **kwargs): + """ + Helper for `.twinx`/`.twiny`/`.twin`. + + *kwargs* are forwarded to the parasite axes constructor. + """ + if axes_class is None: + axes_class = self._base_axes_class + ax = parasite_axes_class_factory(axes_class)(self, **kwargs) + self.parasites.append(ax) + ax._remove_method = self._remove_any_twin + return ax + + def _remove_any_twin(self, ax): + self.parasites.remove(ax) + restore = ["top", "right"] + if ax._sharex: + restore.remove("top") + if ax._sharey: + restore.remove("right") + self.axis[tuple(restore)].set_visible(True) + self.axis[tuple(restore)].toggle(ticklabels=False, label=False) + + @_api.make_keyword_only("3.8", "call_axes_locator") + def get_tightbbox(self, renderer=None, call_axes_locator=True, + bbox_extra_artists=None): + bbs = [ + *[ax.get_tightbbox(renderer, call_axes_locator=call_axes_locator) + for ax in self.parasites], + super().get_tightbbox(renderer, + call_axes_locator=call_axes_locator, + bbox_extra_artists=bbox_extra_artists)] + return Bbox.union([b for b in bbs if b.width != 0 or b.height != 0]) + + +host_axes_class_factory = host_subplot_class_factory = \ + cbook._make_class_factory(HostAxesBase, "{}HostAxes", "_base_axes_class") +HostAxes = SubplotHost = host_axes_class_factory(Axes) + + +def host_axes(*args, axes_class=Axes, figure=None, **kwargs): + """ + Create axes that can act as a hosts to parasitic axes. + + Parameters + ---------- + figure : `~matplotlib.figure.Figure` + Figure to which the axes will be added. Defaults to the current figure + `.pyplot.gcf()`. + + *args, **kwargs + Will be passed on to the underlying `~.axes.Axes` object creation. + """ + import matplotlib.pyplot as plt + host_axes_class = host_axes_class_factory(axes_class) + if figure is None: + figure = plt.gcf() + ax = host_axes_class(figure, *args, **kwargs) + figure.add_axes(ax) + return ax + + +host_subplot = host_axes diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/__init__.py new file mode 100644 index 00000000..ea4d8ed1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/__init__.py @@ -0,0 +1,10 @@ +from pathlib import Path + + +# Check that the test directories exist +if not (Path(__file__).parent / "baseline_images").exists(): + raise OSError( + 'The baseline image directory does not exist. ' + 'This is most likely because the test data is not installed. ' + 'You may need to install matplotlib from source to get the ' + 'test data.') diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/conftest.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/conftest.py new file mode 100644 index 00000000..61c2de3e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/conftest.py @@ -0,0 +1,2 @@ +from matplotlib.testing.conftest import (mpl_test_settings, # noqa + pytest_configure, pytest_unconfigure) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/test_axes_grid1.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/test_axes_grid1.py new file mode 100644 index 00000000..328bb6e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axes_grid1/tests/test_axes_grid1.py @@ -0,0 +1,793 @@ +from itertools import product +import io +import platform + +import matplotlib as mpl +import matplotlib.pyplot as plt +import matplotlib.ticker as mticker +from matplotlib import cbook +from matplotlib.backend_bases import MouseEvent +from matplotlib.colors import LogNorm +from matplotlib.patches import Circle, Ellipse +from matplotlib.transforms import Bbox, TransformedBbox +from matplotlib.testing.decorators import ( + check_figures_equal, image_comparison, remove_ticks_and_titles) + +from mpl_toolkits.axes_grid1 import ( + axes_size as Size, + host_subplot, make_axes_locatable, + Grid, AxesGrid, ImageGrid) +from mpl_toolkits.axes_grid1.anchored_artists import ( + AnchoredAuxTransformBox, AnchoredDrawingArea, AnchoredEllipse, + AnchoredDirectionArrows, AnchoredSizeBar) +from mpl_toolkits.axes_grid1.axes_divider import ( + Divider, HBoxDivider, make_axes_area_auto_adjustable, SubplotDivider, + VBoxDivider) +from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes +from mpl_toolkits.axes_grid1.inset_locator import ( + zoomed_inset_axes, mark_inset, inset_axes, BboxConnectorPatch, + InsetPosition) +import mpl_toolkits.axes_grid1.mpl_axes +import pytest + +import numpy as np +from numpy.testing import assert_array_equal, assert_array_almost_equal + + +def test_divider_append_axes(): + fig, ax = plt.subplots() + divider = make_axes_locatable(ax) + axs = { + "main": ax, + "top": divider.append_axes("top", 1.2, pad=0.1, sharex=ax), + "bottom": divider.append_axes("bottom", 1.2, pad=0.1, sharex=ax), + "left": divider.append_axes("left", 1.2, pad=0.1, sharey=ax), + "right": divider.append_axes("right", 1.2, pad=0.1, sharey=ax), + } + fig.canvas.draw() + bboxes = {k: axs[k].get_window_extent() for k in axs} + dpi = fig.dpi + assert bboxes["top"].height == pytest.approx(1.2 * dpi) + assert bboxes["bottom"].height == pytest.approx(1.2 * dpi) + assert bboxes["left"].width == pytest.approx(1.2 * dpi) + assert bboxes["right"].width == pytest.approx(1.2 * dpi) + assert bboxes["top"].y0 - bboxes["main"].y1 == pytest.approx(0.1 * dpi) + assert bboxes["main"].y0 - bboxes["bottom"].y1 == pytest.approx(0.1 * dpi) + assert bboxes["main"].x0 - bboxes["left"].x1 == pytest.approx(0.1 * dpi) + assert bboxes["right"].x0 - bboxes["main"].x1 == pytest.approx(0.1 * dpi) + assert bboxes["left"].y0 == bboxes["main"].y0 == bboxes["right"].y0 + assert bboxes["left"].y1 == bboxes["main"].y1 == bboxes["right"].y1 + assert bboxes["top"].x0 == bboxes["main"].x0 == bboxes["bottom"].x0 + assert bboxes["top"].x1 == bboxes["main"].x1 == bboxes["bottom"].x1 + + +# Update style when regenerating the test image +@image_comparison(['twin_axes_empty_and_removed'], extensions=["png"], tol=1, + style=('classic', '_classic_test_patch')) +def test_twin_axes_empty_and_removed(): + # Purely cosmetic font changes (avoid overlap) + mpl.rcParams.update( + {"font.size": 8, "xtick.labelsize": 8, "ytick.labelsize": 8}) + generators = ["twinx", "twiny", "twin"] + modifiers = ["", "host invisible", "twin removed", "twin invisible", + "twin removed\nhost invisible"] + # Unmodified host subplot at the beginning for reference + h = host_subplot(len(modifiers)+1, len(generators), 2) + h.text(0.5, 0.5, "host_subplot", + horizontalalignment="center", verticalalignment="center") + # Host subplots with various modifications (twin*, visibility) applied + for i, (mod, gen) in enumerate(product(modifiers, generators), + len(generators) + 1): + h = host_subplot(len(modifiers)+1, len(generators), i) + t = getattr(h, gen)() + if "twin invisible" in mod: + t.axis[:].set_visible(False) + if "twin removed" in mod: + t.remove() + if "host invisible" in mod: + h.axis[:].set_visible(False) + h.text(0.5, 0.5, gen + ("\n" + mod if mod else ""), + horizontalalignment="center", verticalalignment="center") + plt.subplots_adjust(wspace=0.5, hspace=1) + + +def test_twin_axes_both_with_units(): + host = host_subplot(111) + host.plot_date([0, 1, 2], [0, 1, 2], xdate=False, ydate=True) + twin = host.twinx() + twin.plot(["a", "b", "c"]) + assert host.get_yticklabels()[0].get_text() == "00:00:00" + assert twin.get_yticklabels()[0].get_text() == "a" + + +def test_axesgrid_colorbar_log_smoketest(): + fig = plt.figure() + grid = AxesGrid(fig, 111, # modified to be only subplot + nrows_ncols=(1, 1), + ngrids=1, + label_mode="L", + cbar_location="top", + cbar_mode="single", + ) + + Z = 10000 * np.random.rand(10, 10) + im = grid[0].imshow(Z, interpolation="nearest", norm=LogNorm()) + + grid.cbar_axes[0].colorbar(im) + + +def test_inset_colorbar_tight_layout_smoketest(): + fig, ax = plt.subplots(1, 1) + pts = ax.scatter([0, 1], [0, 1], c=[1, 5]) + + cax = inset_axes(ax, width="3%", height="70%") + plt.colorbar(pts, cax=cax) + + with pytest.warns(UserWarning, match="This figure includes Axes"): + # Will warn, but not raise an error + plt.tight_layout() + + +@image_comparison(['inset_locator.png'], style='default', remove_text=True) +def test_inset_locator(): + fig, ax = plt.subplots(figsize=[5, 4]) + + # prepare the demo image + # Z is a 15x15 array + Z = cbook.get_sample_data("axes_grid/bivariate_normal.npy") + extent = (-3, 4, -4, 3) + Z2 = np.zeros((150, 150)) + ny, nx = Z.shape + Z2[30:30+ny, 30:30+nx] = Z + + ax.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + + axins = zoomed_inset_axes(ax, zoom=6, loc='upper right') + axins.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + axins.yaxis.get_major_locator().set_params(nbins=7) + axins.xaxis.get_major_locator().set_params(nbins=7) + # sub region of the original image + x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9 + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + + plt.xticks(visible=False) + plt.yticks(visible=False) + + # draw a bbox of the region of the inset axes in the parent axes and + # connecting lines between the bbox and the inset axes area + mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") + + asb = AnchoredSizeBar(ax.transData, + 0.5, + '0.5', + loc='lower center', + pad=0.1, borderpad=0.5, sep=5, + frameon=False) + ax.add_artist(asb) + + +@image_comparison(['inset_axes.png'], style='default', remove_text=True) +def test_inset_axes(): + fig, ax = plt.subplots(figsize=[5, 4]) + + # prepare the demo image + # Z is a 15x15 array + Z = cbook.get_sample_data("axes_grid/bivariate_normal.npy") + extent = (-3, 4, -4, 3) + Z2 = np.zeros((150, 150)) + ny, nx = Z.shape + Z2[30:30+ny, 30:30+nx] = Z + + ax.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + + # creating our inset axes with a bbox_transform parameter + axins = inset_axes(ax, width=1., height=1., bbox_to_anchor=(1, 1), + bbox_transform=ax.transAxes) + + axins.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + axins.yaxis.get_major_locator().set_params(nbins=7) + axins.xaxis.get_major_locator().set_params(nbins=7) + # sub region of the original image + x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9 + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + + plt.xticks(visible=False) + plt.yticks(visible=False) + + # draw a bbox of the region of the inset axes in the parent axes and + # connecting lines between the bbox and the inset axes area + mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") + + asb = AnchoredSizeBar(ax.transData, + 0.5, + '0.5', + loc='lower center', + pad=0.1, borderpad=0.5, sep=5, + frameon=False) + ax.add_artist(asb) + + +def test_inset_axes_complete(): + dpi = 100 + figsize = (6, 5) + fig, ax = plt.subplots(figsize=figsize, dpi=dpi) + fig.subplots_adjust(.1, .1, .9, .9) + + ins = inset_axes(ax, width=2., height=2., borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, + [(0.9*figsize[0]-2.)/figsize[0], (0.9*figsize[1]-2.)/figsize[1], + 0.9, 0.9]) + + ins = inset_axes(ax, width="40%", height="30%", borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, [.9-.8*.4, .9-.8*.3, 0.9, 0.9]) + + ins = inset_axes(ax, width=1., height=1.2, bbox_to_anchor=(200, 100), + loc=3, borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, + [200/dpi/figsize[0], 100/dpi/figsize[1], + (200/dpi+1)/figsize[0], (100/dpi+1.2)/figsize[1]]) + + ins1 = inset_axes(ax, width="35%", height="60%", loc=3, borderpad=1) + ins2 = inset_axes(ax, width="100%", height="100%", + bbox_to_anchor=(0, 0, .35, .60), + bbox_transform=ax.transAxes, loc=3, borderpad=1) + fig.canvas.draw() + assert_array_equal(ins1.get_position().extents, + ins2.get_position().extents) + + with pytest.raises(ValueError): + ins = inset_axes(ax, width="40%", height="30%", + bbox_to_anchor=(0.4, 0.5)) + + with pytest.warns(UserWarning): + ins = inset_axes(ax, width="40%", height="30%", + bbox_transform=ax.transAxes) + + +def test_inset_axes_tight(): + # gh-26287 found that inset_axes raised with bbox_inches=tight + fig, ax = plt.subplots() + inset_axes(ax, width=1.3, height=0.9) + + f = io.BytesIO() + fig.savefig(f, bbox_inches="tight") + + +@image_comparison(['fill_facecolor.png'], remove_text=True, style='mpl20') +def test_fill_facecolor(): + fig, ax = plt.subplots(1, 5) + fig.set_size_inches(5, 5) + for i in range(1, 4): + ax[i].yaxis.set_visible(False) + ax[4].yaxis.tick_right() + bbox = Bbox.from_extents(0, 0.4, 1, 0.6) + + # fill with blue by setting 'fc' field + bbox1 = TransformedBbox(bbox, ax[0].transData) + bbox2 = TransformedBbox(bbox, ax[1].transData) + # set color to BboxConnectorPatch + p = BboxConnectorPatch( + bbox1, bbox2, loc1a=1, loc2a=2, loc1b=4, loc2b=3, + ec="r", fc="b") + p.set_clip_on(False) + ax[0].add_patch(p) + # set color to marked area + axins = zoomed_inset_axes(ax[0], 1, loc='upper right') + axins.set_xlim(0, 0.2) + axins.set_ylim(0, 0.2) + plt.gca().axes.xaxis.set_ticks([]) + plt.gca().axes.yaxis.set_ticks([]) + mark_inset(ax[0], axins, loc1=2, loc2=4, fc="b", ec="0.5") + + # fill with yellow by setting 'facecolor' field + bbox3 = TransformedBbox(bbox, ax[1].transData) + bbox4 = TransformedBbox(bbox, ax[2].transData) + # set color to BboxConnectorPatch + p = BboxConnectorPatch( + bbox3, bbox4, loc1a=1, loc2a=2, loc1b=4, loc2b=3, + ec="r", facecolor="y") + p.set_clip_on(False) + ax[1].add_patch(p) + # set color to marked area + axins = zoomed_inset_axes(ax[1], 1, loc='upper right') + axins.set_xlim(0, 0.2) + axins.set_ylim(0, 0.2) + plt.gca().axes.xaxis.set_ticks([]) + plt.gca().axes.yaxis.set_ticks([]) + mark_inset(ax[1], axins, loc1=2, loc2=4, facecolor="y", ec="0.5") + + # fill with green by setting 'color' field + bbox5 = TransformedBbox(bbox, ax[2].transData) + bbox6 = TransformedBbox(bbox, ax[3].transData) + # set color to BboxConnectorPatch + p = BboxConnectorPatch( + bbox5, bbox6, loc1a=1, loc2a=2, loc1b=4, loc2b=3, + ec="r", color="g") + p.set_clip_on(False) + ax[2].add_patch(p) + # set color to marked area + axins = zoomed_inset_axes(ax[2], 1, loc='upper right') + axins.set_xlim(0, 0.2) + axins.set_ylim(0, 0.2) + plt.gca().axes.xaxis.set_ticks([]) + plt.gca().axes.yaxis.set_ticks([]) + mark_inset(ax[2], axins, loc1=2, loc2=4, color="g", ec="0.5") + + # fill with green but color won't show if set fill to False + bbox7 = TransformedBbox(bbox, ax[3].transData) + bbox8 = TransformedBbox(bbox, ax[4].transData) + # BboxConnectorPatch won't show green + p = BboxConnectorPatch( + bbox7, bbox8, loc1a=1, loc2a=2, loc1b=4, loc2b=3, + ec="r", fc="g", fill=False) + p.set_clip_on(False) + ax[3].add_patch(p) + # marked area won't show green + axins = zoomed_inset_axes(ax[3], 1, loc='upper right') + axins.set_xlim(0, 0.2) + axins.set_ylim(0, 0.2) + axins.xaxis.set_ticks([]) + axins.yaxis.set_ticks([]) + mark_inset(ax[3], axins, loc1=2, loc2=4, fc="g", ec="0.5", fill=False) + + +# Update style when regenerating the test image +@image_comparison(['zoomed_axes.png', 'inverted_zoomed_axes.png'], + style=('classic', '_classic_test_patch')) +def test_zooming_with_inverted_axes(): + fig, ax = plt.subplots() + ax.plot([1, 2, 3], [1, 2, 3]) + ax.axis([1, 3, 1, 3]) + inset_ax = zoomed_inset_axes(ax, zoom=2.5, loc='lower right') + inset_ax.axis([1.1, 1.4, 1.1, 1.4]) + + fig, ax = plt.subplots() + ax.plot([1, 2, 3], [1, 2, 3]) + ax.axis([3, 1, 3, 1]) + inset_ax = zoomed_inset_axes(ax, zoom=2.5, loc='lower right') + inset_ax.axis([1.4, 1.1, 1.4, 1.1]) + + +# Update style when regenerating the test image +@image_comparison(['anchored_direction_arrows.png'], + tol=0 if platform.machine() == 'x86_64' else 0.01, + style=('classic', '_classic_test_patch')) +def test_anchored_direction_arrows(): + fig, ax = plt.subplots() + ax.imshow(np.zeros((10, 10)), interpolation='nearest') + + simple_arrow = AnchoredDirectionArrows(ax.transAxes, 'X', 'Y') + ax.add_artist(simple_arrow) + + +# Update style when regenerating the test image +@image_comparison(['anchored_direction_arrows_many_args.png'], + style=('classic', '_classic_test_patch')) +def test_anchored_direction_arrows_many_args(): + fig, ax = plt.subplots() + ax.imshow(np.ones((10, 10))) + + direction_arrows = AnchoredDirectionArrows( + ax.transAxes, 'A', 'B', loc='upper right', color='red', + aspect_ratio=-0.5, pad=0.6, borderpad=2, frameon=True, alpha=0.7, + sep_x=-0.06, sep_y=-0.08, back_length=0.1, head_width=9, + head_length=10, tail_width=5) + ax.add_artist(direction_arrows) + + +def test_axes_locatable_position(): + fig, ax = plt.subplots() + divider = make_axes_locatable(ax) + with mpl.rc_context({"figure.subplot.wspace": 0.02}): + cax = divider.append_axes('right', size='5%') + fig.canvas.draw() + assert np.isclose(cax.get_position(original=False).width, + 0.03621495327102808) + + +@image_comparison(['image_grid_each_left_label_mode_all.png'], style='mpl20', + savefig_kwarg={'bbox_inches': 'tight'}) +def test_image_grid_each_left_label_mode_all(): + imdata = np.arange(100).reshape((10, 10)) + + fig = plt.figure(1, (3, 3)) + grid = ImageGrid(fig, (1, 1, 1), nrows_ncols=(3, 2), axes_pad=(0.5, 0.3), + cbar_mode="each", cbar_location="left", cbar_size="15%", + label_mode="all") + # 3-tuple rect => SubplotDivider + assert isinstance(grid.get_divider(), SubplotDivider) + assert grid.get_axes_pad() == (0.5, 0.3) + assert grid.get_aspect() # True by default for ImageGrid + for ax, cax in zip(grid, grid.cbar_axes): + im = ax.imshow(imdata, interpolation='none') + cax.colorbar(im) + + +@image_comparison(['image_grid_single_bottom_label_mode_1.png'], style='mpl20', + savefig_kwarg={'bbox_inches': 'tight'}) +def test_image_grid_single_bottom(): + imdata = np.arange(100).reshape((10, 10)) + + fig = plt.figure(1, (2.5, 1.5)) + grid = ImageGrid(fig, (0, 0, 1, 1), nrows_ncols=(1, 3), + axes_pad=(0.2, 0.15), cbar_mode="single", + cbar_location="bottom", cbar_size="10%", label_mode="1") + # 4-tuple rect => Divider, isinstance will give True for SubplotDivider + assert type(grid.get_divider()) is Divider + for i in range(3): + im = grid[i].imshow(imdata, interpolation='none') + grid.cbar_axes[0].colorbar(im) + + +def test_image_grid_label_mode_deprecation_warning(): + imdata = np.arange(9).reshape((3, 3)) + + fig = plt.figure() + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match="Passing an undefined label_mode"): + grid = ImageGrid(fig, (0, 0, 1, 1), (2, 1), label_mode="foo") + + +@image_comparison(['image_grid.png'], + remove_text=True, style='mpl20', + savefig_kwarg={'bbox_inches': 'tight'}) +def test_image_grid(): + # test that image grid works with bbox_inches=tight. + im = np.arange(100).reshape((10, 10)) + + fig = plt.figure(1, (4, 4)) + grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=0.1) + assert grid.get_axes_pad() == (0.1, 0.1) + for i in range(4): + grid[i].imshow(im, interpolation='nearest') + + +def test_gettightbbox(): + fig, ax = plt.subplots(figsize=(8, 6)) + + l, = ax.plot([1, 2, 3], [0, 1, 0]) + + ax_zoom = zoomed_inset_axes(ax, 4) + ax_zoom.plot([1, 2, 3], [0, 1, 0]) + + mark_inset(ax, ax_zoom, loc1=1, loc2=3, fc="none", ec='0.3') + + remove_ticks_and_titles(fig) + bbox = fig.get_tightbbox(fig.canvas.get_renderer()) + np.testing.assert_array_almost_equal(bbox.extents, + [-17.7, -13.9, 7.2, 5.4]) + + +@pytest.mark.parametrize("click_on", ["big", "small"]) +@pytest.mark.parametrize("big_on_axes,small_on_axes", [ + ("gca", "gca"), + ("host", "host"), + ("host", "parasite"), + ("parasite", "host"), + ("parasite", "parasite") +]) +def test_picking_callbacks_overlap(big_on_axes, small_on_axes, click_on): + """Test pick events on normal, host or parasite axes.""" + # Two rectangles are drawn and "clicked on", a small one and a big one + # enclosing the small one. The axis on which they are drawn as well as the + # rectangle that is clicked on are varied. + # In each case we expect that both rectangles are picked if we click on the + # small one and only the big one is picked if we click on the big one. + # Also tests picking on normal axes ("gca") as a control. + big = plt.Rectangle((0.25, 0.25), 0.5, 0.5, picker=5) + small = plt.Rectangle((0.4, 0.4), 0.2, 0.2, facecolor="r", picker=5) + # Machinery for "receiving" events + received_events = [] + def on_pick(event): + received_events.append(event) + plt.gcf().canvas.mpl_connect('pick_event', on_pick) + # Shortcut + rectangles_on_axes = (big_on_axes, small_on_axes) + # Axes setup + axes = {"gca": None, "host": None, "parasite": None} + if "gca" in rectangles_on_axes: + axes["gca"] = plt.gca() + if "host" in rectangles_on_axes or "parasite" in rectangles_on_axes: + axes["host"] = host_subplot(111) + axes["parasite"] = axes["host"].twin() + # Add rectangles to axes + axes[big_on_axes].add_patch(big) + axes[small_on_axes].add_patch(small) + # Simulate picking with click mouse event + if click_on == "big": + click_axes = axes[big_on_axes] + axes_coords = (0.3, 0.3) + else: + click_axes = axes[small_on_axes] + axes_coords = (0.5, 0.5) + # In reality mouse events never happen on parasite axes, only host axes + if click_axes is axes["parasite"]: + click_axes = axes["host"] + (x, y) = click_axes.transAxes.transform(axes_coords) + m = MouseEvent("button_press_event", click_axes.figure.canvas, x, y, + button=1) + click_axes.pick(m) + # Checks + expected_n_events = 2 if click_on == "small" else 1 + assert len(received_events) == expected_n_events + event_rects = [event.artist for event in received_events] + assert big in event_rects + if click_on == "small": + assert small in event_rects + + +@image_comparison(['anchored_artists.png'], remove_text=True, style='mpl20') +def test_anchored_artists(): + fig, ax = plt.subplots(figsize=(3, 3)) + ada = AnchoredDrawingArea(40, 20, 0, 0, loc='upper right', pad=0., + frameon=False) + p1 = Circle((10, 10), 10) + ada.drawing_area.add_artist(p1) + p2 = Circle((30, 10), 5, fc="r") + ada.drawing_area.add_artist(p2) + ax.add_artist(ada) + + box = AnchoredAuxTransformBox(ax.transData, loc='upper left') + el = Ellipse((0, 0), width=0.1, height=0.4, angle=30, color='cyan') + box.drawing_area.add_artist(el) + ax.add_artist(box) + + # Manually construct the ellipse instead, once the deprecation elapses. + with pytest.warns(mpl.MatplotlibDeprecationWarning): + ae = AnchoredEllipse(ax.transData, width=0.1, height=0.25, angle=-60, + loc='lower left', pad=0.5, borderpad=0.4, + frameon=True) + ax.add_artist(ae) + + asb = AnchoredSizeBar(ax.transData, 0.2, r"0.2 units", loc='lower right', + pad=0.3, borderpad=0.4, sep=4, fill_bar=True, + frameon=False, label_top=True, prop={'size': 20}, + size_vertical=0.05, color='green') + ax.add_artist(asb) + + +def test_hbox_divider(): + arr1 = np.arange(20).reshape((4, 5)) + arr2 = np.arange(20).reshape((5, 4)) + + fig, (ax1, ax2) = plt.subplots(1, 2) + ax1.imshow(arr1) + ax2.imshow(arr2) + + pad = 0.5 # inches. + divider = HBoxDivider( + fig, 111, # Position of combined axes. + horizontal=[Size.AxesX(ax1), Size.Fixed(pad), Size.AxesX(ax2)], + vertical=[Size.AxesY(ax1), Size.Scaled(1), Size.AxesY(ax2)]) + ax1.set_axes_locator(divider.new_locator(0)) + ax2.set_axes_locator(divider.new_locator(2)) + + fig.canvas.draw() + p1 = ax1.get_position() + p2 = ax2.get_position() + assert p1.height == p2.height + assert p2.width / p1.width == pytest.approx((4 / 5) ** 2) + + +def test_vbox_divider(): + arr1 = np.arange(20).reshape((4, 5)) + arr2 = np.arange(20).reshape((5, 4)) + + fig, (ax1, ax2) = plt.subplots(1, 2) + ax1.imshow(arr1) + ax2.imshow(arr2) + + pad = 0.5 # inches. + divider = VBoxDivider( + fig, 111, # Position of combined axes. + horizontal=[Size.AxesX(ax1), Size.Scaled(1), Size.AxesX(ax2)], + vertical=[Size.AxesY(ax1), Size.Fixed(pad), Size.AxesY(ax2)]) + ax1.set_axes_locator(divider.new_locator(0)) + ax2.set_axes_locator(divider.new_locator(2)) + + fig.canvas.draw() + p1 = ax1.get_position() + p2 = ax2.get_position() + assert p1.width == p2.width + assert p1.height / p2.height == pytest.approx((4 / 5) ** 2) + + +def test_axes_class_tuple(): + fig = plt.figure() + axes_class = (mpl_toolkits.axes_grid1.mpl_axes.Axes, {}) + gr = AxesGrid(fig, 111, nrows_ncols=(1, 1), axes_class=axes_class) + + +def test_grid_axes_lists(): + """Test Grid axes_all, axes_row and axes_column relationship.""" + fig = plt.figure() + grid = Grid(fig, 111, (2, 3), direction="row") + assert_array_equal(grid, grid.axes_all) + assert_array_equal(grid.axes_row, np.transpose(grid.axes_column)) + assert_array_equal(grid, np.ravel(grid.axes_row), "row") + assert grid.get_geometry() == (2, 3) + grid = Grid(fig, 111, (2, 3), direction="column") + assert_array_equal(grid, np.ravel(grid.axes_column), "column") + + +@pytest.mark.parametrize('direction', ('row', 'column')) +def test_grid_axes_position(direction): + """Test positioning of the axes in Grid.""" + fig = plt.figure() + grid = Grid(fig, 111, (2, 2), direction=direction) + loc = [ax.get_axes_locator() for ax in np.ravel(grid.axes_row)] + # Test nx. + assert loc[1].args[0] > loc[0].args[0] + assert loc[0].args[0] == loc[2].args[0] + assert loc[3].args[0] == loc[1].args[0] + # Test ny. + assert loc[2].args[1] < loc[0].args[1] + assert loc[0].args[1] == loc[1].args[1] + assert loc[3].args[1] == loc[2].args[1] + + +@pytest.mark.parametrize('rect, ngrids, error, message', ( + ((1, 1), None, TypeError, "Incorrect rect format"), + (111, -1, ValueError, "ngrids must be positive"), + (111, 7, ValueError, "ngrids must be positive"), +)) +def test_grid_errors(rect, ngrids, error, message): + fig = plt.figure() + with pytest.raises(error, match=message): + Grid(fig, rect, (2, 3), ngrids=ngrids) + + +@pytest.mark.parametrize('anchor, error, message', ( + (None, TypeError, "anchor must be str"), + ("CC", ValueError, "'CC' is not a valid value for anchor"), + ((1, 1, 1), TypeError, "anchor must be str"), +)) +def test_divider_errors(anchor, error, message): + fig = plt.figure() + with pytest.raises(error, match=message): + Divider(fig, [0, 0, 1, 1], [Size.Fixed(1)], [Size.Fixed(1)], + anchor=anchor) + + +@check_figures_equal(extensions=["png"]) +def test_mark_inset_unstales_viewlim(fig_test, fig_ref): + inset, full = fig_test.subplots(1, 2) + full.plot([0, 5], [0, 5]) + inset.set(xlim=(1, 2), ylim=(1, 2)) + # Check that mark_inset unstales full's viewLim before drawing the marks. + mark_inset(full, inset, 1, 4) + + inset, full = fig_ref.subplots(1, 2) + full.plot([0, 5], [0, 5]) + inset.set(xlim=(1, 2), ylim=(1, 2)) + mark_inset(full, inset, 1, 4) + # Manually unstale the full's viewLim. + fig_ref.canvas.draw() + + +def test_auto_adjustable(): + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1]) + pad = 0.1 + make_axes_area_auto_adjustable(ax, pad=pad) + fig.canvas.draw() + tbb = ax.get_tightbbox() + assert tbb.x0 == pytest.approx(pad * fig.dpi) + assert tbb.x1 == pytest.approx(fig.bbox.width - pad * fig.dpi) + assert tbb.y0 == pytest.approx(pad * fig.dpi) + assert tbb.y1 == pytest.approx(fig.bbox.height - pad * fig.dpi) + + +# Update style when regenerating the test image +@image_comparison(['rgb_axes.png'], remove_text=True, + style=('classic', '_classic_test_patch')) +def test_rgb_axes(): + fig = plt.figure() + ax = RGBAxes(fig, (0.1, 0.1, 0.8, 0.8), pad=0.1) + rng = np.random.default_rng(19680801) + r = rng.random((5, 5)) + g = rng.random((5, 5)) + b = rng.random((5, 5)) + ax.imshow_rgb(r, g, b, interpolation='none') + + +# Update style when regenerating the test image +@image_comparison(['insetposition.png'], remove_text=True, + style=('classic', '_classic_test_patch')) +def test_insetposition(): + fig, ax = plt.subplots(figsize=(2, 2)) + ax_ins = plt.axes([0, 0, 1, 1]) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + ip = InsetPosition(ax, [0.2, 0.25, 0.5, 0.4]) + ax_ins.set_axes_locator(ip) + + +# The original version of this test relied on mpl_toolkits's slightly different +# colorbar implementation; moving to matplotlib's own colorbar implementation +# caused the small image comparison error. +@image_comparison(['imagegrid_cbar_mode.png'], + remove_text=True, style='mpl20', tol=0.3) +def test_imagegrid_cbar_mode_edge(): + arr = np.arange(16).reshape((4, 4)) + + fig = plt.figure(figsize=(18, 9)) + + positions = (241, 242, 243, 244, 245, 246, 247, 248) + directions = ['row']*4 + ['column']*4 + cbar_locations = ['left', 'right', 'top', 'bottom']*2 + + for position, direction, location in zip( + positions, directions, cbar_locations): + grid = ImageGrid(fig, position, + nrows_ncols=(2, 2), + direction=direction, + cbar_location=location, + cbar_size='20%', + cbar_mode='edge') + ax1, ax2, ax3, ax4 = grid + + ax1.imshow(arr, cmap='nipy_spectral') + ax2.imshow(arr.T, cmap='hot') + ax3.imshow(np.hypot(arr, arr.T), cmap='jet') + ax4.imshow(np.arctan2(arr, arr.T), cmap='hsv') + + # In each row/column, the "first" colorbars must be overwritten by the + # "second" ones. To achieve this, clear out the axes first. + for ax in grid: + ax.cax.cla() + cb = ax.cax.colorbar(ax.images[0]) + + +def test_imagegrid(): + fig = plt.figure() + grid = ImageGrid(fig, 111, nrows_ncols=(1, 1)) + ax = grid[0] + im = ax.imshow([[1, 2]], norm=mpl.colors.LogNorm()) + cb = ax.cax.colorbar(im) + assert isinstance(cb.locator, mticker.LogLocator) + + +def test_removal(): + import matplotlib.pyplot as plt + import mpl_toolkits.axisartist as AA + fig = plt.figure() + ax = host_subplot(111, axes_class=AA.Axes, figure=fig) + col = ax.fill_between(range(5), 0, range(5)) + fig.canvas.draw() + col.remove() + fig.canvas.draw() + + +@image_comparison(['anchored_locator_base_call.png'], style="mpl20") +def test_anchored_locator_base_call(): + fig = plt.figure(figsize=(3, 3)) + fig1, fig2 = fig.subfigures(nrows=2, ncols=1) + + ax = fig1.subplots() + ax.set(aspect=1, xlim=(-15, 15), ylim=(-20, 5)) + ax.set(xticks=[], yticks=[]) + + Z = cbook.get_sample_data("axes_grid/bivariate_normal.npy") + extent = (-3, 4, -4, 3) + + axins = zoomed_inset_axes(ax, zoom=2, loc="upper left") + axins.set(xticks=[], yticks=[]) + + axins.imshow(Z, extent=extent, origin="lower") + + +def test_grid_with_axes_class_not_overriding_axis(): + Grid(plt.figure(), 111, (2, 2), axes_class=mpl.axes.Axes) + RGBAxes(plt.figure(), 111, axes_class=mpl.axes.Axes) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/__init__.py new file mode 100644 index 00000000..47242cf7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/__init__.py @@ -0,0 +1,13 @@ +from .axislines import ( + Axes, AxesZero, AxisArtistHelper, AxisArtistHelperRectlinear, + GridHelperBase, GridHelperRectlinear, Subplot, SubplotZero) +from .axis_artist import AxisArtist, GridlinesCollection +from .grid_helper_curvelinear import GridHelperCurveLinear +from .floating_axes import FloatingAxes, FloatingSubplot +from mpl_toolkits.axes_grid1.parasite_axes import ( + host_axes_class_factory, parasite_axes_class_factory) + + +ParasiteAxes = parasite_axes_class_factory(Axes) +HostAxes = host_axes_class_factory(Axes) +SubplotHost = HostAxes diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/angle_helper.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/angle_helper.py new file mode 100644 index 00000000..1786cd70 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/angle_helper.py @@ -0,0 +1,394 @@ +import numpy as np +import math + +from mpl_toolkits.axisartist.grid_finder import ExtremeFinderSimple + + +def select_step_degree(dv): + + degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520] + degree_steps_ = [1, 2, 5, 10, 15, 30, 45, 90, 180, 360] + degree_factors = [1.] * len(degree_steps_) + + minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45] + minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30] + + minute_limits_ = np.array(minsec_limits_) / 60 + minute_factors = [60.] * len(minute_limits_) + + second_limits_ = np.array(minsec_limits_) / 3600 + second_factors = [3600.] * len(second_limits_) + + degree_limits = [*second_limits_, *minute_limits_, *degree_limits_] + degree_steps = [*minsec_steps_, *minsec_steps_, *degree_steps_] + degree_factors = [*second_factors, *minute_factors, *degree_factors] + + n = np.searchsorted(degree_limits, dv) + step = degree_steps[n] + factor = degree_factors[n] + + return step, factor + + +def select_step_hour(dv): + + hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36] + hour_steps_ = [1, 2, 3, 4, 6, 8, 12, 18, 24] + hour_factors = [1.] * len(hour_steps_) + + minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45] + minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30] + + minute_limits_ = np.array(minsec_limits_) / 60 + minute_factors = [60.] * len(minute_limits_) + + second_limits_ = np.array(minsec_limits_) / 3600 + second_factors = [3600.] * len(second_limits_) + + hour_limits = [*second_limits_, *minute_limits_, *hour_limits_] + hour_steps = [*minsec_steps_, *minsec_steps_, *hour_steps_] + hour_factors = [*second_factors, *minute_factors, *hour_factors] + + n = np.searchsorted(hour_limits, dv) + step = hour_steps[n] + factor = hour_factors[n] + + return step, factor + + +def select_step_sub(dv): + + # subarcsec or degree + tmp = 10.**(int(math.log10(dv))-1.) + + factor = 1./tmp + + if 1.5*tmp >= dv: + step = 1 + elif 3.*tmp >= dv: + step = 2 + elif 7.*tmp >= dv: + step = 5 + else: + step = 1 + factor = 0.1*factor + + return step, factor + + +def select_step(v1, v2, nv, hour=False, include_last=True, + threshold_factor=3600.): + + if v1 > v2: + v1, v2 = v2, v1 + + dv = (v2 - v1) / nv + + if hour: + _select_step = select_step_hour + cycle = 24. + else: + _select_step = select_step_degree + cycle = 360. + + # for degree + if dv > 1 / threshold_factor: + step, factor = _select_step(dv) + else: + step, factor = select_step_sub(dv*threshold_factor) + + factor = factor * threshold_factor + + levs = np.arange(np.floor(v1 * factor / step), + np.ceil(v2 * factor / step) + 0.5, + dtype=int) * step + + # n : number of valid levels. If there is a cycle, e.g., [0, 90, 180, + # 270, 360], the grid line needs to be extended from 0 to 360, so + # we need to return the whole array. However, the last level (360) + # needs to be ignored often. In this case, so we return n=4. + + n = len(levs) + + # we need to check the range of values + # for example, -90 to 90, 0 to 360, + + if factor == 1. and levs[-1] >= levs[0] + cycle: # check for cycle + nv = int(cycle / step) + if include_last: + levs = levs[0] + np.arange(0, nv+1, 1) * step + else: + levs = levs[0] + np.arange(0, nv, 1) * step + + n = len(levs) + + return np.array(levs), n, factor + + +def select_step24(v1, v2, nv, include_last=True, threshold_factor=3600): + v1, v2 = v1 / 15, v2 / 15 + levs, n, factor = select_step(v1, v2, nv, hour=True, + include_last=include_last, + threshold_factor=threshold_factor) + return levs * 15, n, factor + + +def select_step360(v1, v2, nv, include_last=True, threshold_factor=3600): + return select_step(v1, v2, nv, hour=False, + include_last=include_last, + threshold_factor=threshold_factor) + + +class LocatorBase: + def __init__(self, nbins, include_last=True): + self.nbins = nbins + self._include_last = include_last + + def set_params(self, nbins=None): + if nbins is not None: + self.nbins = int(nbins) + + +class LocatorHMS(LocatorBase): + def __call__(self, v1, v2): + return select_step24(v1, v2, self.nbins, self._include_last) + + +class LocatorHM(LocatorBase): + def __call__(self, v1, v2): + return select_step24(v1, v2, self.nbins, self._include_last, + threshold_factor=60) + + +class LocatorH(LocatorBase): + def __call__(self, v1, v2): + return select_step24(v1, v2, self.nbins, self._include_last, + threshold_factor=1) + + +class LocatorDMS(LocatorBase): + def __call__(self, v1, v2): + return select_step360(v1, v2, self.nbins, self._include_last) + + +class LocatorDM(LocatorBase): + def __call__(self, v1, v2): + return select_step360(v1, v2, self.nbins, self._include_last, + threshold_factor=60) + + +class LocatorD(LocatorBase): + def __call__(self, v1, v2): + return select_step360(v1, v2, self.nbins, self._include_last, + threshold_factor=1) + + +class FormatterDMS: + deg_mark = r"^{\circ}" + min_mark = r"^{\prime}" + sec_mark = r"^{\prime\prime}" + + fmt_d = "$%d" + deg_mark + "$" + fmt_ds = r"$%d.%s" + deg_mark + "$" + + # %s for sign + fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark + "$" + fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark + "$" + + fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\," + fmt_s_partial = "%02d" + sec_mark + "$" + fmt_ss_partial = "%02d.%s" + sec_mark + "$" + + def _get_number_fraction(self, factor): + ## check for fractional numbers + number_fraction = None + # check for 60 + + for threshold in [1, 60, 3600]: + if factor <= threshold: + break + + d = factor // threshold + int_log_d = int(np.floor(np.log10(d))) + if 10**int_log_d == d and d != 1: + number_fraction = int_log_d + factor = factor // 10**int_log_d + return factor, number_fraction + + return factor, number_fraction + + def __call__(self, direction, factor, values): + if len(values) == 0: + return [] + + ss = np.sign(values) + signs = ["-" if v < 0 else "" for v in values] + + factor, number_fraction = self._get_number_fraction(factor) + + values = np.abs(values) + + if number_fraction is not None: + values, frac_part = divmod(values, 10 ** number_fraction) + frac_fmt = "%%0%dd" % (number_fraction,) + frac_str = [frac_fmt % (f1,) for f1 in frac_part] + + if factor == 1: + if number_fraction is None: + return [self.fmt_d % (s * int(v),) for s, v in zip(ss, values)] + else: + return [self.fmt_ds % (s * int(v), f1) + for s, v, f1 in zip(ss, values, frac_str)] + elif factor == 60: + deg_part, min_part = divmod(values, 60) + if number_fraction is None: + return [self.fmt_d_m % (s1, d1, m1) + for s1, d1, m1 in zip(signs, deg_part, min_part)] + else: + return [self.fmt_d_ms % (s, d1, m1, f1) + for s, d1, m1, f1 + in zip(signs, deg_part, min_part, frac_str)] + + elif factor == 3600: + if ss[-1] == -1: + inverse_order = True + values = values[::-1] + signs = signs[::-1] + else: + inverse_order = False + + l_hm_old = "" + r = [] + + deg_part, min_part_ = divmod(values, 3600) + min_part, sec_part = divmod(min_part_, 60) + + if number_fraction is None: + sec_str = [self.fmt_s_partial % (s1,) for s1 in sec_part] + else: + sec_str = [self.fmt_ss_partial % (s1, f1) + for s1, f1 in zip(sec_part, frac_str)] + + for s, d1, m1, s1 in zip(signs, deg_part, min_part, sec_str): + l_hm = self.fmt_d_m_partial % (s, d1, m1) + if l_hm != l_hm_old: + l_hm_old = l_hm + l = l_hm + s1 + else: + l = "$" + s + s1 + r.append(l) + + if inverse_order: + return r[::-1] + else: + return r + + else: # factor > 3600. + return [r"$%s^{\circ}$" % v for v in ss*values] + + +class FormatterHMS(FormatterDMS): + deg_mark = r"^\mathrm{h}" + min_mark = r"^\mathrm{m}" + sec_mark = r"^\mathrm{s}" + + fmt_d = "$%d" + deg_mark + "$" + fmt_ds = r"$%d.%s" + deg_mark + "$" + + # %s for sign + fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark+"$" + fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark+"$" + + fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\," + fmt_s_partial = "%02d" + sec_mark + "$" + fmt_ss_partial = "%02d.%s" + sec_mark + "$" + + def __call__(self, direction, factor, values): # hour + return super().__call__(direction, factor, np.asarray(values) / 15) + + +class ExtremeFinderCycle(ExtremeFinderSimple): + # docstring inherited + + def __init__(self, nx, ny, + lon_cycle=360., lat_cycle=None, + lon_minmax=None, lat_minmax=(-90, 90)): + """ + This subclass handles the case where one or both coordinates should be + taken modulo 360, or be restricted to not exceed a specific range. + + Parameters + ---------- + nx, ny : int + The number of samples in each direction. + + lon_cycle, lat_cycle : 360 or None + If not None, values in the corresponding direction are taken modulo + *lon_cycle* or *lat_cycle*; in theory this can be any number but + the implementation actually assumes that it is 360 (if not None); + other values give nonsensical results. + + This is done by "unwrapping" the transformed grid coordinates so + that jumps are less than a half-cycle; then normalizing the span to + no more than a full cycle. + + For example, if values are in the union of the [0, 2] and + [358, 360] intervals (typically, angles measured modulo 360), the + values in the second interval are normalized to [-2, 0] instead so + that the values now cover [-2, 2]. If values are in a range of + [5, 1000], this gets normalized to [5, 365]. + + lon_minmax, lat_minmax : (float, float) or None + If not None, the computed bounding box is clipped to the given + range in the corresponding direction. + """ + self.nx, self.ny = nx, ny + self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle + self.lon_minmax = lon_minmax + self.lat_minmax = lat_minmax + + def __call__(self, transform_xy, x1, y1, x2, y2): + # docstring inherited + x, y = np.meshgrid( + np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)) + lon, lat = transform_xy(np.ravel(x), np.ravel(y)) + + # iron out jumps, but algorithm should be improved. + # This is just naive way of doing and my fail for some cases. + # Consider replacing this with numpy.unwrap + # We are ignoring invalid warnings. They are triggered when + # comparing arrays with NaNs using > We are already handling + # that correctly using np.nanmin and np.nanmax + with np.errstate(invalid='ignore'): + if self.lon_cycle is not None: + lon0 = np.nanmin(lon) + lon -= 360. * ((lon - lon0) > 180.) + if self.lat_cycle is not None: + lat0 = np.nanmin(lat) + lat -= 360. * ((lat - lat0) > 180.) + + lon_min, lon_max = np.nanmin(lon), np.nanmax(lon) + lat_min, lat_max = np.nanmin(lat), np.nanmax(lat) + + lon_min, lon_max, lat_min, lat_max = \ + self._add_pad(lon_min, lon_max, lat_min, lat_max) + + # check cycle + if self.lon_cycle: + lon_max = min(lon_max, lon_min + self.lon_cycle) + if self.lat_cycle: + lat_max = min(lat_max, lat_min + self.lat_cycle) + + if self.lon_minmax is not None: + min0 = self.lon_minmax[0] + lon_min = max(min0, lon_min) + max0 = self.lon_minmax[1] + lon_max = min(max0, lon_max) + + if self.lat_minmax is not None: + min0 = self.lat_minmax[0] + lat_min = max(min0, lat_min) + max0 = self.lat_minmax[1] + lat_max = min(max0, lat_max) + + return lon_min, lon_max, lat_min, lat_max diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_divider.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_divider.py new file mode 100644 index 00000000..a01d4e27 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_divider.py @@ -0,0 +1,2 @@ +from mpl_toolkits.axes_grid1.axes_divider import ( # noqa + Divider, AxesLocator, SubplotDivider, AxesDivider, make_axes_locatable) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_grid.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_grid.py new file mode 100644 index 00000000..ecb3e9d9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_grid.py @@ -0,0 +1,23 @@ +from matplotlib import _api + +import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig +from .axislines import Axes + + +_api.warn_deprecated( + "3.8", name=__name__, obj_type="module", alternative="axes_grid1.axes_grid") + + +@_api.deprecated("3.8", alternative=( + "axes_grid1.axes_grid.Grid(..., axes_class=axislines.Axes")) +class Grid(axes_grid_orig.Grid): + _defaultAxesClass = Axes + + +@_api.deprecated("3.8", alternative=( + "axes_grid1.axes_grid.ImageGrid(..., axes_class=axislines.Axes")) +class ImageGrid(axes_grid_orig.ImageGrid): + _defaultAxesClass = Axes + + +AxesGrid = ImageGrid diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_rgb.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_rgb.py new file mode 100644 index 00000000..21957474 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axes_rgb.py @@ -0,0 +1,18 @@ +from matplotlib import _api +from mpl_toolkits.axes_grid1.axes_rgb import ( # noqa + make_rgb_axes, RGBAxes as _RGBAxes) +from .axislines import Axes + + +_api.warn_deprecated( + "3.8", name=__name__, obj_type="module", alternative="axes_grid1.axes_rgb") + + +@_api.deprecated("3.8", alternative=( + "axes_grid1.axes_rgb.RGBAxes(..., axes_class=axislines.Axes")) +class RGBAxes(_RGBAxes): + """ + Subclass of `~.axes_grid1.axes_rgb.RGBAxes` with + ``_defaultAxesClass`` = `.axislines.Axes`. + """ + _defaultAxesClass = Axes diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axis_artist.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axis_artist.py new file mode 100644 index 00000000..407ad07a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axis_artist.py @@ -0,0 +1,1115 @@ +""" +The :mod:`.axis_artist` module implements custom artists to draw axis elements +(axis lines and labels, tick lines and labels, grid lines). + +Axis lines and labels and tick lines and labels are managed by the `AxisArtist` +class; grid lines are managed by the `GridlinesCollection` class. + +There is one `AxisArtist` per Axis; it can be accessed through +the ``axis`` dictionary of the parent Axes (which should be a +`mpl_toolkits.axislines.Axes`), e.g. ``ax.axis["bottom"]``. + +Children of the AxisArtist are accessed as attributes: ``.line`` and ``.label`` +for the axis line and label, ``.major_ticks``, ``.major_ticklabels``, +``.minor_ticks``, ``.minor_ticklabels`` for the tick lines and labels (e.g. +``ax.axis["bottom"].line``). + +Children properties (colors, fonts, line widths, etc.) can be set using +setters, e.g. :: + + # Make the major ticks of the bottom axis red. + ax.axis["bottom"].major_ticks.set_color("red") + +However, things like the locations of ticks, and their ticklabels need to be +changed from the side of the grid_helper. + +axis_direction +-------------- + +`AxisArtist`, `AxisLabel`, `TickLabels` have an *axis_direction* attribute, +which adjusts the location, angle, etc. The *axis_direction* must be one of +"left", "right", "bottom", "top", and follows the Matplotlib convention for +rectangular axis. + +For example, for the *bottom* axis (the left and right is relative to the +direction of the increasing coordinate), + +* ticklabels and axislabel are on the right +* ticklabels and axislabel have text angle of 0 +* ticklabels are baseline, center-aligned +* axislabel is top, center-aligned + +The text angles are actually relative to (90 + angle of the direction to the +ticklabel), which gives 0 for bottom axis. + +=================== ====== ======== ====== ======== +Property left bottom right top +=================== ====== ======== ====== ======== +ticklabel location left right right left +axislabel location left right right left +ticklabel angle 90 0 -90 180 +axislabel angle 180 0 0 180 +ticklabel va center baseline center baseline +axislabel va center top center bottom +ticklabel ha right center right center +axislabel ha right center right center +=================== ====== ======== ====== ======== + +Ticks are by default direct opposite side of the ticklabels. To make ticks to +the same side of the ticklabels, :: + + ax.axis["bottom"].major_ticks.set_tick_out(True) + +The following attributes can be customized (use the ``set_xxx`` methods): + +* `Ticks`: ticksize, tick_out +* `TickLabels`: pad +* `AxisLabel`: pad +""" + +# FIXME : +# angles are given in data coordinate - need to convert it to canvas coordinate + + +from operator import methodcaller + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook +import matplotlib.artist as martist +import matplotlib.colors as mcolors +import matplotlib.text as mtext +from matplotlib.collections import LineCollection +from matplotlib.lines import Line2D +from matplotlib.patches import PathPatch +from matplotlib.path import Path +from matplotlib.transforms import ( + Affine2D, Bbox, IdentityTransform, ScaledTranslation) + +from .axisline_style import AxislineStyle + + +class AttributeCopier: + def get_ref_artist(self): + """ + Return the underlying artist that actually defines some properties + (e.g., color) of this artist. + """ + raise RuntimeError("get_ref_artist must overridden") + + def get_attribute_from_ref_artist(self, attr_name): + getter = methodcaller("get_" + attr_name) + prop = getter(super()) + return getter(self.get_ref_artist()) if prop == "auto" else prop + + +class Ticks(AttributeCopier, Line2D): + """ + Ticks are derived from `.Line2D`, and note that ticks themselves + are markers. Thus, you should use set_mec, set_mew, etc. + + To change the tick size (length), you need to use + `set_ticksize`. To change the direction of the ticks (ticks are + in opposite direction of ticklabels by default), use + ``set_tick_out(False)`` + """ + + def __init__(self, ticksize, tick_out=False, *, axis=None, **kwargs): + self._ticksize = ticksize + self.locs_angles_labels = [] + + self.set_tick_out(tick_out) + + self._axis = axis + if self._axis is not None: + if "color" not in kwargs: + kwargs["color"] = "auto" + if "mew" not in kwargs and "markeredgewidth" not in kwargs: + kwargs["markeredgewidth"] = "auto" + + Line2D.__init__(self, [0.], [0.], **kwargs) + self.set_snap(True) + + def get_ref_artist(self): + # docstring inherited + return self._axis.majorTicks[0].tick1line + + def set_color(self, color): + # docstring inherited + # Unlike the base Line2D.set_color, this also supports "auto". + if not cbook._str_equal(color, "auto"): + mcolors._check_color_like(color=color) + self._color = color + self.stale = True + + def get_color(self): + return self.get_attribute_from_ref_artist("color") + + def get_markeredgecolor(self): + return self.get_attribute_from_ref_artist("markeredgecolor") + + def get_markeredgewidth(self): + return self.get_attribute_from_ref_artist("markeredgewidth") + + def set_tick_out(self, b): + """Set whether ticks are drawn inside or outside the axes.""" + self._tick_out = b + + def get_tick_out(self): + """Return whether ticks are drawn inside or outside the axes.""" + return self._tick_out + + def set_ticksize(self, ticksize): + """Set length of the ticks in points.""" + self._ticksize = ticksize + + def get_ticksize(self): + """Return length of the ticks in points.""" + return self._ticksize + + def set_locs_angles(self, locs_angles): + self.locs_angles = locs_angles + + _tickvert_path = Path([[0., 0.], [1., 0.]]) + + def draw(self, renderer): + if not self.get_visible(): + return + + gc = renderer.new_gc() + gc.set_foreground(self.get_markeredgecolor()) + gc.set_linewidth(self.get_markeredgewidth()) + gc.set_alpha(self._alpha) + + path_trans = self.get_transform() + marker_transform = (Affine2D() + .scale(renderer.points_to_pixels(self._ticksize))) + if self.get_tick_out(): + marker_transform.rotate_deg(180) + + for loc, angle in self.locs_angles: + locs = path_trans.transform_non_affine(np.array([loc])) + if self.axes and not self.axes.viewLim.contains(*locs[0]): + continue + renderer.draw_markers( + gc, self._tickvert_path, + marker_transform + Affine2D().rotate_deg(angle), + Path(locs), path_trans.get_affine()) + + gc.restore() + + +class LabelBase(mtext.Text): + """ + A base class for `.AxisLabel` and `.TickLabels`. The position and + angle of the text are calculated by the offset_ref_angle, + text_ref_angle, and offset_radius attributes. + """ + + def __init__(self, *args, **kwargs): + self.locs_angles_labels = [] + self._ref_angle = 0 + self._offset_radius = 0. + + super().__init__(*args, **kwargs) + + self.set_rotation_mode("anchor") + self._text_follow_ref_angle = True + + @property + def _text_ref_angle(self): + if self._text_follow_ref_angle: + return self._ref_angle + 90 + else: + return 0 + + @property + def _offset_ref_angle(self): + return self._ref_angle + + _get_opposite_direction = {"left": "right", + "right": "left", + "top": "bottom", + "bottom": "top"}.__getitem__ + + def draw(self, renderer): + if not self.get_visible(): + return + + # save original and adjust some properties + tr = self.get_transform() + angle_orig = self.get_rotation() + theta = np.deg2rad(self._offset_ref_angle) + dd = self._offset_radius + dx, dy = dd * np.cos(theta), dd * np.sin(theta) + + self.set_transform(tr + Affine2D().translate(dx, dy)) + self.set_rotation(self._text_ref_angle + angle_orig) + super().draw(renderer) + # restore original properties + self.set_transform(tr) + self.set_rotation(angle_orig) + + def get_window_extent(self, renderer=None): + if renderer is None: + renderer = self.figure._get_renderer() + + # save original and adjust some properties + tr = self.get_transform() + angle_orig = self.get_rotation() + theta = np.deg2rad(self._offset_ref_angle) + dd = self._offset_radius + dx, dy = dd * np.cos(theta), dd * np.sin(theta) + + self.set_transform(tr + Affine2D().translate(dx, dy)) + self.set_rotation(self._text_ref_angle + angle_orig) + bbox = super().get_window_extent(renderer).frozen() + # restore original properties + self.set_transform(tr) + self.set_rotation(angle_orig) + + return bbox + + +class AxisLabel(AttributeCopier, LabelBase): + """ + Axis label. Derived from `.Text`. The position of the text is updated + in the fly, so changing text position has no effect. Otherwise, the + properties can be changed as a normal `.Text`. + + To change the pad between tick labels and axis label, use `set_pad`. + """ + + def __init__(self, *args, axis_direction="bottom", axis=None, **kwargs): + self._axis = axis + self._pad = 5 + self._external_pad = 0 # in pixels + LabelBase.__init__(self, *args, **kwargs) + self.set_axis_direction(axis_direction) + + def set_pad(self, pad): + """ + Set the internal pad in points. + + The actual pad will be the sum of the internal pad and the + external pad (the latter is set automatically by the `.AxisArtist`). + + Parameters + ---------- + pad : float + The internal pad in points. + """ + self._pad = pad + + def get_pad(self): + """ + Return the internal pad in points. + + See `.set_pad` for more details. + """ + return self._pad + + def get_ref_artist(self): + # docstring inherited + return self._axis.get_label() + + def get_text(self): + # docstring inherited + t = super().get_text() + if t == "__from_axes__": + return self._axis.get_label().get_text() + return self._text + + _default_alignments = dict(left=("bottom", "center"), + right=("top", "center"), + bottom=("top", "center"), + top=("bottom", "center")) + + def set_default_alignment(self, d): + """ + Set the default alignment. See `set_axis_direction` for details. + + Parameters + ---------- + d : {"left", "bottom", "right", "top"} + """ + va, ha = _api.check_getitem(self._default_alignments, d=d) + self.set_va(va) + self.set_ha(ha) + + _default_angles = dict(left=180, + right=0, + bottom=0, + top=180) + + def set_default_angle(self, d): + """ + Set the default angle. See `set_axis_direction` for details. + + Parameters + ---------- + d : {"left", "bottom", "right", "top"} + """ + self.set_rotation(_api.check_getitem(self._default_angles, d=d)) + + def set_axis_direction(self, d): + """ + Adjust the text angle and text alignment of axis label + according to the matplotlib convention. + + ===================== ========== ========= ========== ========== + Property left bottom right top + ===================== ========== ========= ========== ========== + axislabel angle 180 0 0 180 + axislabel va center top center bottom + axislabel ha right center right center + ===================== ========== ========= ========== ========== + + Note that the text angles are actually relative to (90 + angle + of the direction to the ticklabel), which gives 0 for bottom + axis. + + Parameters + ---------- + d : {"left", "bottom", "right", "top"} + """ + self.set_default_alignment(d) + self.set_default_angle(d) + + def get_color(self): + return self.get_attribute_from_ref_artist("color") + + def draw(self, renderer): + if not self.get_visible(): + return + + self._offset_radius = \ + self._external_pad + renderer.points_to_pixels(self.get_pad()) + + super().draw(renderer) + + def get_window_extent(self, renderer=None): + if renderer is None: + renderer = self.figure._get_renderer() + if not self.get_visible(): + return + + r = self._external_pad + renderer.points_to_pixels(self.get_pad()) + self._offset_radius = r + + bb = super().get_window_extent(renderer) + + return bb + + +class TickLabels(AxisLabel): # mtext.Text + """ + Tick labels. While derived from `.Text`, this single artist draws all + ticklabels. As in `.AxisLabel`, the position of the text is updated + in the fly, so changing text position has no effect. Otherwise, + the properties can be changed as a normal `.Text`. Unlike the + ticklabels of the mainline Matplotlib, properties of a single + ticklabel alone cannot be modified. + + To change the pad between ticks and ticklabels, use `~.AxisLabel.set_pad`. + """ + + def __init__(self, *, axis_direction="bottom", **kwargs): + super().__init__(**kwargs) + self.set_axis_direction(axis_direction) + self._axislabel_pad = 0 + + def get_ref_artist(self): + # docstring inherited + return self._axis.get_ticklabels()[0] + + def set_axis_direction(self, label_direction): + """ + Adjust the text angle and text alignment of ticklabels + according to the Matplotlib convention. + + The *label_direction* must be one of [left, right, bottom, top]. + + ===================== ========== ========= ========== ========== + Property left bottom right top + ===================== ========== ========= ========== ========== + ticklabel angle 90 0 -90 180 + ticklabel va center baseline center baseline + ticklabel ha right center right center + ===================== ========== ========= ========== ========== + + Note that the text angles are actually relative to (90 + angle + of the direction to the ticklabel), which gives 0 for bottom + axis. + + Parameters + ---------- + label_direction : {"left", "bottom", "right", "top"} + + """ + self.set_default_alignment(label_direction) + self.set_default_angle(label_direction) + self._axis_direction = label_direction + + def invert_axis_direction(self): + label_direction = self._get_opposite_direction(self._axis_direction) + self.set_axis_direction(label_direction) + + def _get_ticklabels_offsets(self, renderer, label_direction): + """ + Calculate the ticklabel offsets from the tick and their total heights. + + The offset only takes account the offset due to the vertical alignment + of the ticklabels: if axis direction is bottom and va is 'top', it will + return 0; if va is 'baseline', it will return (height-descent). + """ + whd_list = self.get_texts_widths_heights_descents(renderer) + + if not whd_list: + return 0, 0 + + r = 0 + va, ha = self.get_va(), self.get_ha() + + if label_direction == "left": + pad = max(w for w, h, d in whd_list) + if ha == "left": + r = pad + elif ha == "center": + r = .5 * pad + elif label_direction == "right": + pad = max(w for w, h, d in whd_list) + if ha == "right": + r = pad + elif ha == "center": + r = .5 * pad + elif label_direction == "bottom": + pad = max(h for w, h, d in whd_list) + if va == "bottom": + r = pad + elif va == "center": + r = .5 * pad + elif va == "baseline": + max_ascent = max(h - d for w, h, d in whd_list) + max_descent = max(d for w, h, d in whd_list) + r = max_ascent + pad = max_ascent + max_descent + elif label_direction == "top": + pad = max(h for w, h, d in whd_list) + if va == "top": + r = pad + elif va == "center": + r = .5 * pad + elif va == "baseline": + max_ascent = max(h - d for w, h, d in whd_list) + max_descent = max(d for w, h, d in whd_list) + r = max_descent + pad = max_ascent + max_descent + + # r : offset + # pad : total height of the ticklabels. This will be used to + # calculate the pad for the axislabel. + return r, pad + + _default_alignments = dict(left=("center", "right"), + right=("center", "left"), + bottom=("baseline", "center"), + top=("baseline", "center")) + + _default_angles = dict(left=90, + right=-90, + bottom=0, + top=180) + + def draw(self, renderer): + if not self.get_visible(): + self._axislabel_pad = self._external_pad + return + + r, total_width = self._get_ticklabels_offsets(renderer, + self._axis_direction) + + pad = self._external_pad + renderer.points_to_pixels(self.get_pad()) + self._offset_radius = r + pad + + for (x, y), a, l in self._locs_angles_labels: + if not l.strip(): + continue + self._ref_angle = a + self.set_x(x) + self.set_y(y) + self.set_text(l) + LabelBase.draw(self, renderer) + + # the value saved will be used to draw axislabel. + self._axislabel_pad = total_width + pad + + def set_locs_angles_labels(self, locs_angles_labels): + self._locs_angles_labels = locs_angles_labels + + def get_window_extents(self, renderer=None): + if renderer is None: + renderer = self.figure._get_renderer() + + if not self.get_visible(): + self._axislabel_pad = self._external_pad + return [] + + bboxes = [] + + r, total_width = self._get_ticklabels_offsets(renderer, + self._axis_direction) + + pad = self._external_pad + renderer.points_to_pixels(self.get_pad()) + self._offset_radius = r + pad + + for (x, y), a, l in self._locs_angles_labels: + self._ref_angle = a + self.set_x(x) + self.set_y(y) + self.set_text(l) + bb = LabelBase.get_window_extent(self, renderer) + bboxes.append(bb) + + # the value saved will be used to draw axislabel. + self._axislabel_pad = total_width + pad + + return bboxes + + def get_texts_widths_heights_descents(self, renderer): + """ + Return a list of ``(width, height, descent)`` tuples for ticklabels. + + Empty labels are left out. + """ + whd_list = [] + for _loc, _angle, label in self._locs_angles_labels: + if not label.strip(): + continue + clean_line, ismath = self._preprocess_math(label) + whd = renderer.get_text_width_height_descent( + clean_line, self._fontproperties, ismath=ismath) + whd_list.append(whd) + return whd_list + + +class GridlinesCollection(LineCollection): + def __init__(self, *args, which="major", axis="both", **kwargs): + """ + Collection of grid lines. + + Parameters + ---------- + which : {"major", "minor"} + Which grid to consider. + axis : {"both", "x", "y"} + Which axis to consider. + *args, **kwargs + Passed to `.LineCollection`. + """ + self._which = which + self._axis = axis + super().__init__(*args, **kwargs) + self.set_grid_helper(None) + + def set_which(self, which): + """ + Select major or minor grid lines. + + Parameters + ---------- + which : {"major", "minor"} + """ + self._which = which + + def set_axis(self, axis): + """ + Select axis. + + Parameters + ---------- + axis : {"both", "x", "y"} + """ + self._axis = axis + + def set_grid_helper(self, grid_helper): + """ + Set grid helper. + + Parameters + ---------- + grid_helper : `.GridHelperBase` subclass + """ + self._grid_helper = grid_helper + + def draw(self, renderer): + if self._grid_helper is not None: + self._grid_helper.update_lim(self.axes) + gl = self._grid_helper.get_gridlines(self._which, self._axis) + self.set_segments([np.transpose(l) for l in gl]) + super().draw(renderer) + + +class AxisArtist(martist.Artist): + """ + An artist which draws axis (a line along which the n-th axes coord + is constant) line, ticks, tick labels, and axis label. + """ + + zorder = 2.5 + + @property + def LABELPAD(self): + return self.label.get_pad() + + @LABELPAD.setter + def LABELPAD(self, v): + self.label.set_pad(v) + + def __init__(self, axes, + helper, + offset=None, + axis_direction="bottom", + **kwargs): + """ + Parameters + ---------- + axes : `mpl_toolkits.axisartist.axislines.Axes` + helper : `~mpl_toolkits.axisartist.axislines.AxisArtistHelper` + """ + # axes is also used to follow the axis attribute (tick color, etc). + + super().__init__(**kwargs) + + self.axes = axes + + self._axis_artist_helper = helper + + if offset is None: + offset = (0, 0) + self.offset_transform = ScaledTranslation( + *offset, + Affine2D().scale(1 / 72) # points to inches. + + self.axes.figure.dpi_scale_trans) + + if axis_direction in ["left", "right"]: + self.axis = axes.yaxis + else: + self.axis = axes.xaxis + + self._axisline_style = None + self._axis_direction = axis_direction + + self._init_line() + self._init_ticks(**kwargs) + self._init_offsetText(axis_direction) + self._init_label() + + # axis direction + self._ticklabel_add_angle = 0. + self._axislabel_add_angle = 0. + self.set_axis_direction(axis_direction) + + # axis direction + + def set_axis_direction(self, axis_direction): + """ + Adjust the direction, text angle, and text alignment of tick labels + and axis labels following the Matplotlib convention for the rectangle + axes. + + The *axis_direction* must be one of [left, right, bottom, top]. + + ===================== ========== ========= ========== ========== + Property left bottom right top + ===================== ========== ========= ========== ========== + ticklabel direction "-" "+" "+" "-" + axislabel direction "-" "+" "+" "-" + ticklabel angle 90 0 -90 180 + ticklabel va center baseline center baseline + ticklabel ha right center right center + axislabel angle 180 0 0 180 + axislabel va center top center bottom + axislabel ha right center right center + ===================== ========== ========= ========== ========== + + Note that the direction "+" and "-" are relative to the direction of + the increasing coordinate. Also, the text angles are actually + relative to (90 + angle of the direction to the ticklabel), + which gives 0 for bottom axis. + + Parameters + ---------- + axis_direction : {"left", "bottom", "right", "top"} + """ + self.major_ticklabels.set_axis_direction(axis_direction) + self.label.set_axis_direction(axis_direction) + self._axis_direction = axis_direction + if axis_direction in ["left", "top"]: + self.set_ticklabel_direction("-") + self.set_axislabel_direction("-") + else: + self.set_ticklabel_direction("+") + self.set_axislabel_direction("+") + + def set_ticklabel_direction(self, tick_direction): + r""" + Adjust the direction of the tick labels. + + Note that the *tick_direction*\s '+' and '-' are relative to the + direction of the increasing coordinate. + + Parameters + ---------- + tick_direction : {"+", "-"} + """ + self._ticklabel_add_angle = _api.check_getitem( + {"+": 0, "-": 180}, tick_direction=tick_direction) + + def invert_ticklabel_direction(self): + self._ticklabel_add_angle = (self._ticklabel_add_angle + 180) % 360 + self.major_ticklabels.invert_axis_direction() + self.minor_ticklabels.invert_axis_direction() + + def set_axislabel_direction(self, label_direction): + r""" + Adjust the direction of the axis label. + + Note that the *label_direction*\s '+' and '-' are relative to the + direction of the increasing coordinate. + + Parameters + ---------- + label_direction : {"+", "-"} + """ + self._axislabel_add_angle = _api.check_getitem( + {"+": 0, "-": 180}, label_direction=label_direction) + + def get_transform(self): + return self.axes.transAxes + self.offset_transform + + def get_helper(self): + """ + Return axis artist helper instance. + """ + return self._axis_artist_helper + + def set_axisline_style(self, axisline_style=None, **kwargs): + """ + Set the axisline style. + + The new style is completely defined by the passed attributes. Existing + style attributes are forgotten. + + Parameters + ---------- + axisline_style : str or None + The line style, e.g. '->', optionally followed by a comma-separated + list of attributes. Alternatively, the attributes can be provided + as keywords. + + If *None* this returns a string containing the available styles. + + Examples + -------- + The following two commands are equal: + + >>> set_axisline_style("->,size=1.5") + >>> set_axisline_style("->", size=1.5) + """ + if axisline_style is None: + return AxislineStyle.pprint_styles() + + if isinstance(axisline_style, AxislineStyle._Base): + self._axisline_style = axisline_style + else: + self._axisline_style = AxislineStyle(axisline_style, **kwargs) + + self._init_line() + + def get_axisline_style(self): + """Return the current axisline style.""" + return self._axisline_style + + def _init_line(self): + """ + Initialize the *line* artist that is responsible to draw the axis line. + """ + tran = (self._axis_artist_helper.get_line_transform(self.axes) + + self.offset_transform) + + axisline_style = self.get_axisline_style() + if axisline_style is None: + self.line = PathPatch( + self._axis_artist_helper.get_line(self.axes), + color=mpl.rcParams['axes.edgecolor'], + fill=False, + linewidth=mpl.rcParams['axes.linewidth'], + capstyle=mpl.rcParams['lines.solid_capstyle'], + joinstyle=mpl.rcParams['lines.solid_joinstyle'], + transform=tran) + else: + self.line = axisline_style(self, transform=tran) + + def _draw_line(self, renderer): + self.line.set_path(self._axis_artist_helper.get_line(self.axes)) + if self.get_axisline_style() is not None: + self.line.set_line_mutation_scale(self.major_ticklabels.get_size()) + self.line.draw(renderer) + + def _init_ticks(self, **kwargs): + axis_name = self.axis.axis_name + + trans = (self._axis_artist_helper.get_tick_transform(self.axes) + + self.offset_transform) + + self.major_ticks = Ticks( + kwargs.get( + "major_tick_size", + mpl.rcParams[f"{axis_name}tick.major.size"]), + axis=self.axis, transform=trans) + self.minor_ticks = Ticks( + kwargs.get( + "minor_tick_size", + mpl.rcParams[f"{axis_name}tick.minor.size"]), + axis=self.axis, transform=trans) + + size = mpl.rcParams[f"{axis_name}tick.labelsize"] + self.major_ticklabels = TickLabels( + axis=self.axis, + axis_direction=self._axis_direction, + figure=self.axes.figure, + transform=trans, + fontsize=size, + pad=kwargs.get( + "major_tick_pad", mpl.rcParams[f"{axis_name}tick.major.pad"]), + ) + self.minor_ticklabels = TickLabels( + axis=self.axis, + axis_direction=self._axis_direction, + figure=self.axes.figure, + transform=trans, + fontsize=size, + pad=kwargs.get( + "minor_tick_pad", mpl.rcParams[f"{axis_name}tick.minor.pad"]), + ) + + def _get_tick_info(self, tick_iter): + """ + Return a pair of: + + - list of locs and angles for ticks + - list of locs, angles and labels for ticklabels. + """ + ticks_loc_angle = [] + ticklabels_loc_angle_label = [] + + ticklabel_add_angle = self._ticklabel_add_angle + + for loc, angle_normal, angle_tangent, label in tick_iter: + angle_label = angle_tangent - 90 + ticklabel_add_angle + angle_tick = (angle_normal + if 90 <= (angle_label - angle_normal) % 360 <= 270 + else angle_normal + 180) + ticks_loc_angle.append([loc, angle_tick]) + ticklabels_loc_angle_label.append([loc, angle_label, label]) + + return ticks_loc_angle, ticklabels_loc_angle_label + + def _update_ticks(self, renderer=None): + # set extra pad for major and minor ticklabels: use ticksize of + # majorticks even for minor ticks. not clear what is best. + + if renderer is None: + renderer = self.figure._get_renderer() + + dpi_cor = renderer.points_to_pixels(1.) + if self.major_ticks.get_visible() and self.major_ticks.get_tick_out(): + ticklabel_pad = self.major_ticks._ticksize * dpi_cor + self.major_ticklabels._external_pad = ticklabel_pad + self.minor_ticklabels._external_pad = ticklabel_pad + else: + self.major_ticklabels._external_pad = 0 + self.minor_ticklabels._external_pad = 0 + + majortick_iter, minortick_iter = \ + self._axis_artist_helper.get_tick_iterators(self.axes) + + tick_loc_angle, ticklabel_loc_angle_label = \ + self._get_tick_info(majortick_iter) + self.major_ticks.set_locs_angles(tick_loc_angle) + self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label) + + tick_loc_angle, ticklabel_loc_angle_label = \ + self._get_tick_info(minortick_iter) + self.minor_ticks.set_locs_angles(tick_loc_angle) + self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label) + + def _draw_ticks(self, renderer): + self._update_ticks(renderer) + self.major_ticks.draw(renderer) + self.major_ticklabels.draw(renderer) + self.minor_ticks.draw(renderer) + self.minor_ticklabels.draw(renderer) + if (self.major_ticklabels.get_visible() + or self.minor_ticklabels.get_visible()): + self._draw_offsetText(renderer) + + _offsetText_pos = dict(left=(0, 1, "bottom", "right"), + right=(1, 1, "bottom", "left"), + bottom=(1, 0, "top", "right"), + top=(1, 1, "bottom", "right")) + + def _init_offsetText(self, direction): + x, y, va, ha = self._offsetText_pos[direction] + self.offsetText = mtext.Annotation( + "", + xy=(x, y), xycoords="axes fraction", + xytext=(0, 0), textcoords="offset points", + color=mpl.rcParams['xtick.color'], + horizontalalignment=ha, verticalalignment=va, + ) + self.offsetText.set_transform(IdentityTransform()) + self.axes._set_artist_props(self.offsetText) + + def _update_offsetText(self): + self.offsetText.set_text(self.axis.major.formatter.get_offset()) + self.offsetText.set_size(self.major_ticklabels.get_size()) + offset = (self.major_ticklabels.get_pad() + + self.major_ticklabels.get_size() + + 2) + self.offsetText.xyann = (0, offset) + + def _draw_offsetText(self, renderer): + self._update_offsetText() + self.offsetText.draw(renderer) + + def _init_label(self, **kwargs): + tr = (self._axis_artist_helper.get_axislabel_transform(self.axes) + + self.offset_transform) + self.label = AxisLabel( + 0, 0, "__from_axes__", + color="auto", + fontsize=kwargs.get("labelsize", mpl.rcParams['axes.labelsize']), + fontweight=mpl.rcParams['axes.labelweight'], + axis=self.axis, + transform=tr, + axis_direction=self._axis_direction, + ) + self.label.set_figure(self.axes.figure) + labelpad = kwargs.get("labelpad", 5) + self.label.set_pad(labelpad) + + def _update_label(self, renderer): + if not self.label.get_visible(): + return + + if self._ticklabel_add_angle != self._axislabel_add_angle: + if ((self.major_ticks.get_visible() + and not self.major_ticks.get_tick_out()) + or (self.minor_ticks.get_visible() + and not self.major_ticks.get_tick_out())): + axislabel_pad = self.major_ticks._ticksize + else: + axislabel_pad = 0 + else: + axislabel_pad = max(self.major_ticklabels._axislabel_pad, + self.minor_ticklabels._axislabel_pad) + + self.label._external_pad = axislabel_pad + + xy, angle_tangent = \ + self._axis_artist_helper.get_axislabel_pos_angle(self.axes) + if xy is None: + return + + angle_label = angle_tangent - 90 + + x, y = xy + self.label._ref_angle = angle_label + self._axislabel_add_angle + self.label.set(x=x, y=y) + + def _draw_label(self, renderer): + self._update_label(renderer) + self.label.draw(renderer) + + def set_label(self, s): + # docstring inherited + self.label.set_text(s) + + def get_tightbbox(self, renderer=None): + if not self.get_visible(): + return + self._axis_artist_helper.update_lim(self.axes) + self._update_ticks(renderer) + self._update_label(renderer) + + self.line.set_path(self._axis_artist_helper.get_line(self.axes)) + if self.get_axisline_style() is not None: + self.line.set_line_mutation_scale(self.major_ticklabels.get_size()) + + bb = [ + *self.major_ticklabels.get_window_extents(renderer), + *self.minor_ticklabels.get_window_extents(renderer), + self.label.get_window_extent(renderer), + self.offsetText.get_window_extent(renderer), + self.line.get_window_extent(renderer), + ] + bb = [b for b in bb if b and (b.width != 0 or b.height != 0)] + if bb: + _bbox = Bbox.union(bb) + return _bbox + else: + return None + + @martist.allow_rasterization + def draw(self, renderer): + # docstring inherited + if not self.get_visible(): + return + renderer.open_group(__name__, gid=self.get_gid()) + self._axis_artist_helper.update_lim(self.axes) + self._draw_ticks(renderer) + self._draw_line(renderer) + self._draw_label(renderer) + renderer.close_group(__name__) + + def toggle(self, all=None, ticks=None, ticklabels=None, label=None): + """ + Toggle visibility of ticks, ticklabels, and (axis) label. + To turn all off, :: + + axis.toggle(all=False) + + To turn all off but ticks on :: + + axis.toggle(all=False, ticks=True) + + To turn all on but (axis) label off :: + + axis.toggle(all=True, label=False) + + """ + if all: + _ticks, _ticklabels, _label = True, True, True + elif all is not None: + _ticks, _ticklabels, _label = False, False, False + else: + _ticks, _ticklabels, _label = None, None, None + + if ticks is not None: + _ticks = ticks + if ticklabels is not None: + _ticklabels = ticklabels + if label is not None: + _label = label + + if _ticks is not None: + self.major_ticks.set_visible(_ticks) + self.minor_ticks.set_visible(_ticks) + if _ticklabels is not None: + self.major_ticklabels.set_visible(_ticklabels) + self.minor_ticklabels.set_visible(_ticklabels) + if _label is not None: + self.label.set_visible(_label) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axisline_style.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axisline_style.py new file mode 100644 index 00000000..5ae18802 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axisline_style.py @@ -0,0 +1,193 @@ +""" +Provides classes to style the axis lines. +""" +import math + +import numpy as np + +import matplotlib as mpl +from matplotlib.patches import _Style, FancyArrowPatch +from matplotlib.path import Path +from matplotlib.transforms import IdentityTransform + + +class _FancyAxislineStyle: + class SimpleArrow(FancyArrowPatch): + """The artist class that will be returned for SimpleArrow style.""" + _ARROW_STYLE = "->" + + def __init__(self, axis_artist, line_path, transform, + line_mutation_scale): + self._axis_artist = axis_artist + self._line_transform = transform + self._line_path = line_path + self._line_mutation_scale = line_mutation_scale + + FancyArrowPatch.__init__(self, + path=self._line_path, + arrowstyle=self._ARROW_STYLE, + patchA=None, + patchB=None, + shrinkA=0., + shrinkB=0., + mutation_scale=line_mutation_scale, + mutation_aspect=None, + transform=IdentityTransform(), + ) + + def set_line_mutation_scale(self, scale): + self.set_mutation_scale(scale*self._line_mutation_scale) + + def _extend_path(self, path, mutation_size=10): + """ + Extend the path to make a room for drawing arrow. + """ + (x0, y0), (x1, y1) = path.vertices[-2:] + theta = math.atan2(y1 - y0, x1 - x0) + x2 = x1 + math.cos(theta) * mutation_size + y2 = y1 + math.sin(theta) * mutation_size + if path.codes is None: + return Path(np.concatenate([path.vertices, [[x2, y2]]])) + else: + return Path(np.concatenate([path.vertices, [[x2, y2]]]), + np.concatenate([path.codes, [Path.LINETO]])) + + def set_path(self, path): + self._line_path = path + + def draw(self, renderer): + """ + Draw the axis line. + 1) Transform the path to the display coordinate. + 2) Extend the path to make a room for arrow. + 3) Update the path of the FancyArrowPatch. + 4) Draw. + """ + path_in_disp = self._line_transform.transform_path(self._line_path) + mutation_size = self.get_mutation_scale() # line_mutation_scale() + extended_path = self._extend_path(path_in_disp, + mutation_size=mutation_size) + self._path_original = extended_path + FancyArrowPatch.draw(self, renderer) + + def get_window_extent(self, renderer=None): + + path_in_disp = self._line_transform.transform_path(self._line_path) + mutation_size = self.get_mutation_scale() # line_mutation_scale() + extended_path = self._extend_path(path_in_disp, + mutation_size=mutation_size) + self._path_original = extended_path + return FancyArrowPatch.get_window_extent(self, renderer) + + class FilledArrow(SimpleArrow): + """The artist class that will be returned for FilledArrow style.""" + _ARROW_STYLE = "-|>" + + def __init__(self, axis_artist, line_path, transform, + line_mutation_scale, facecolor): + super().__init__(axis_artist, line_path, transform, + line_mutation_scale) + self.set_facecolor(facecolor) + + +class AxislineStyle(_Style): + """ + A container class which defines style classes for AxisArtists. + + An instance of any axisline style class is a callable object, + whose call signature is :: + + __call__(self, axis_artist, path, transform) + + When called, this should return an `.Artist` with the following methods:: + + def set_path(self, path): + # set the path for axisline. + + def set_line_mutation_scale(self, scale): + # set the scale + + def draw(self, renderer): + # draw + """ + + _style_list = {} + + class _Base: + # The derived classes are required to be able to be initialized + # w/o arguments, i.e., all its argument (except self) must have + # the default values. + + def __init__(self): + """ + initialization. + """ + super().__init__() + + def __call__(self, axis_artist, transform): + """ + Given the AxisArtist instance, and transform for the path (set_path + method), return the Matplotlib artist for drawing the axis line. + """ + return self.new_line(axis_artist, transform) + + class SimpleArrow(_Base): + """ + A simple arrow. + """ + + ArrowAxisClass = _FancyAxislineStyle.SimpleArrow + + def __init__(self, size=1): + """ + Parameters + ---------- + size : float + Size of the arrow as a fraction of the ticklabel size. + """ + + self.size = size + super().__init__() + + def new_line(self, axis_artist, transform): + + linepath = Path([(0, 0), (0, 1)]) + axisline = self.ArrowAxisClass(axis_artist, linepath, transform, + line_mutation_scale=self.size) + return axisline + + _style_list["->"] = SimpleArrow + + class FilledArrow(SimpleArrow): + """ + An arrow with a filled head. + """ + + ArrowAxisClass = _FancyAxislineStyle.FilledArrow + + def __init__(self, size=1, facecolor=None): + """ + Parameters + ---------- + size : float + Size of the arrow as a fraction of the ticklabel size. + facecolor : color, default: :rc:`axes.edgecolor` + Fill color. + + .. versionadded:: 3.7 + """ + + if facecolor is None: + facecolor = mpl.rcParams['axes.edgecolor'] + self.size = size + self._facecolor = facecolor + super().__init__(size=size) + + def new_line(self, axis_artist, transform): + linepath = Path([(0, 0), (0, 1)]) + axisline = self.ArrowAxisClass(axis_artist, linepath, transform, + line_mutation_scale=self.size, + facecolor=self._facecolor) + return axisline + + _style_list["-|>"] = FilledArrow diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axislines.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axislines.py new file mode 100644 index 00000000..35717da8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/axislines.py @@ -0,0 +1,531 @@ +""" +Axislines includes modified implementation of the Axes class. The +biggest difference is that the artists responsible for drawing the axis spine, +ticks, ticklabels and axis labels are separated out from Matplotlib's Axis +class. Originally, this change was motivated to support curvilinear +grid. Here are a few reasons that I came up with a new axes class: + +* "top" and "bottom" x-axis (or "left" and "right" y-axis) can have + different ticks (tick locations and labels). This is not possible + with the current Matplotlib, although some twin axes trick can help. + +* Curvilinear grid. + +* angled ticks. + +In the new axes class, xaxis and yaxis is set to not visible by +default, and new set of artist (AxisArtist) are defined to draw axis +line, ticks, ticklabels and axis label. Axes.axis attribute serves as +a dictionary of these artists, i.e., ax.axis["left"] is a AxisArtist +instance responsible to draw left y-axis. The default Axes.axis contains +"bottom", "left", "top" and "right". + +AxisArtist can be considered as a container artist and has the following +children artists which will draw ticks, labels, etc. + +* line +* major_ticks, major_ticklabels +* minor_ticks, minor_ticklabels +* offsetText +* label + +Note that these are separate artists from `matplotlib.axis.Axis`, thus most +tick-related functions in Matplotlib won't work. For example, color and +markerwidth of the ``ax.axis["bottom"].major_ticks`` will follow those of +Axes.xaxis unless explicitly specified. + +In addition to AxisArtist, the Axes will have *gridlines* attribute, +which obviously draws grid lines. The gridlines needs to be separated +from the axis as some gridlines can never pass any axis. +""" + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api +import matplotlib.axes as maxes +from matplotlib.path import Path +from mpl_toolkits.axes_grid1 import mpl_axes +from .axisline_style import AxislineStyle # noqa +from .axis_artist import AxisArtist, GridlinesCollection + + +class _AxisArtistHelperBase: + """ + Base class for axis helper. + + Subclasses should define the methods listed below. The *axes* + argument will be the ``.axes`` attribute of the caller artist. :: + + # Construct the spine. + + def get_line_transform(self, axes): + return transform + + def get_line(self, axes): + return path + + # Construct the label. + + def get_axislabel_transform(self, axes): + return transform + + def get_axislabel_pos_angle(self, axes): + return (x, y), angle + + # Construct the ticks. + + def get_tick_transform(self, axes): + return transform + + def get_tick_iterators(self, axes): + # A pair of iterables (one for major ticks, one for minor ticks) + # that yield (tick_position, tick_angle, tick_label). + return iter_major, iter_minor + """ + + def update_lim(self, axes): + pass + + def _to_xy(self, values, const): + """ + Create a (*values.shape, 2)-shape array representing (x, y) pairs. + + The other coordinate is filled with the constant *const*. + + Example:: + + >>> self.nth_coord = 0 + >>> self._to_xy([1, 2, 3], const=0) + array([[1, 0], + [2, 0], + [3, 0]]) + """ + if self.nth_coord == 0: + return np.stack(np.broadcast_arrays(values, const), axis=-1) + elif self.nth_coord == 1: + return np.stack(np.broadcast_arrays(const, values), axis=-1) + else: + raise ValueError("Unexpected nth_coord") + + +class _FixedAxisArtistHelperBase(_AxisArtistHelperBase): + """Helper class for a fixed (in the axes coordinate) axis.""" + + passthru_pt = _api.deprecated("3.7")(property( + lambda self: {"left": (0, 0), "right": (1, 0), + "bottom": (0, 0), "top": (0, 1)}[self._loc])) + + def __init__(self, loc, nth_coord=None): + """``nth_coord = 0``: x-axis; ``nth_coord = 1``: y-axis.""" + self.nth_coord = ( + nth_coord if nth_coord is not None else + _api.check_getitem( + {"bottom": 0, "top": 0, "left": 1, "right": 1}, loc=loc)) + if (nth_coord == 0 and loc not in ["left", "right"] + or nth_coord == 1 and loc not in ["bottom", "top"]): + _api.warn_deprecated( + "3.7", message=f"{loc=!r} is incompatible with " + "{nth_coord=}; support is deprecated since %(since)s") + self._loc = loc + self._pos = {"bottom": 0, "top": 1, "left": 0, "right": 1}[loc] + super().__init__() + # axis line in transAxes + self._path = Path(self._to_xy((0, 1), const=self._pos)) + + def get_nth_coord(self): + return self.nth_coord + + # LINE + + def get_line(self, axes): + return self._path + + def get_line_transform(self, axes): + return axes.transAxes + + # LABEL + + def get_axislabel_transform(self, axes): + return axes.transAxes + + def get_axislabel_pos_angle(self, axes): + """ + Return the label reference position in transAxes. + + get_label_transform() returns a transform of (transAxes+offset) + """ + return dict(left=((0., 0.5), 90), # (position, angle_tangent) + right=((1., 0.5), 90), + bottom=((0.5, 0.), 0), + top=((0.5, 1.), 0))[self._loc] + + # TICK + + def get_tick_transform(self, axes): + return [axes.get_xaxis_transform(), + axes.get_yaxis_transform()][self.nth_coord] + + +class _FloatingAxisArtistHelperBase(_AxisArtistHelperBase): + + def __init__(self, nth_coord, value): + self.nth_coord = nth_coord + self._value = value + super().__init__() + + def get_nth_coord(self): + return self.nth_coord + + def get_line(self, axes): + raise RuntimeError( + "get_line method should be defined by the derived class") + + +class FixedAxisArtistHelperRectilinear(_FixedAxisArtistHelperBase): + + def __init__(self, axes, loc, nth_coord=None): + """ + nth_coord = along which coordinate value varies + in 2D, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis + """ + super().__init__(loc, nth_coord) + self.axis = [axes.xaxis, axes.yaxis][self.nth_coord] + + # TICK + + def get_tick_iterators(self, axes): + """tick_loc, tick_angle, tick_label""" + if self._loc in ["bottom", "top"]: + angle_normal, angle_tangent = 90, 0 + else: # "left", "right" + angle_normal, angle_tangent = 0, 90 + + major = self.axis.major + major_locs = major.locator() + major_labels = major.formatter.format_ticks(major_locs) + + minor = self.axis.minor + minor_locs = minor.locator() + minor_labels = minor.formatter.format_ticks(minor_locs) + + tick_to_axes = self.get_tick_transform(axes) - axes.transAxes + + def _f(locs, labels): + for loc, label in zip(locs, labels): + c = self._to_xy(loc, const=self._pos) + # check if the tick point is inside axes + c2 = tick_to_axes.transform(c) + if mpl.transforms._interval_contains_close( + (0, 1), c2[self.nth_coord]): + yield c, angle_normal, angle_tangent, label + + return _f(major_locs, major_labels), _f(minor_locs, minor_labels) + + +class FloatingAxisArtistHelperRectilinear(_FloatingAxisArtistHelperBase): + + def __init__(self, axes, nth_coord, + passingthrough_point, axis_direction="bottom"): + super().__init__(nth_coord, passingthrough_point) + self._axis_direction = axis_direction + self.axis = [axes.xaxis, axes.yaxis][self.nth_coord] + + def get_line(self, axes): + fixed_coord = 1 - self.nth_coord + data_to_axes = axes.transData - axes.transAxes + p = data_to_axes.transform([self._value, self._value]) + return Path(self._to_xy((0, 1), const=p[fixed_coord])) + + def get_line_transform(self, axes): + return axes.transAxes + + def get_axislabel_transform(self, axes): + return axes.transAxes + + def get_axislabel_pos_angle(self, axes): + """ + Return the label reference position in transAxes. + + get_label_transform() returns a transform of (transAxes+offset) + """ + angle = [0, 90][self.nth_coord] + fixed_coord = 1 - self.nth_coord + data_to_axes = axes.transData - axes.transAxes + p = data_to_axes.transform([self._value, self._value]) + verts = self._to_xy(0.5, const=p[fixed_coord]) + if 0 <= verts[fixed_coord] <= 1: + return verts, angle + else: + return None, None + + def get_tick_transform(self, axes): + return axes.transData + + def get_tick_iterators(self, axes): + """tick_loc, tick_angle, tick_label""" + if self.nth_coord == 0: + angle_normal, angle_tangent = 90, 0 + else: + angle_normal, angle_tangent = 0, 90 + + major = self.axis.major + major_locs = major.locator() + major_labels = major.formatter.format_ticks(major_locs) + + minor = self.axis.minor + minor_locs = minor.locator() + minor_labels = minor.formatter.format_ticks(minor_locs) + + data_to_axes = axes.transData - axes.transAxes + + def _f(locs, labels): + for loc, label in zip(locs, labels): + c = self._to_xy(loc, const=self._value) + c1, c2 = data_to_axes.transform(c) + if 0 <= c1 <= 1 and 0 <= c2 <= 1: + yield c, angle_normal, angle_tangent, label + + return _f(major_locs, major_labels), _f(minor_locs, minor_labels) + + +class AxisArtistHelper: # Backcompat. + Fixed = _FixedAxisArtistHelperBase + Floating = _FloatingAxisArtistHelperBase + + +class AxisArtistHelperRectlinear: # Backcompat. + Fixed = FixedAxisArtistHelperRectilinear + Floating = FloatingAxisArtistHelperRectilinear + + +class GridHelperBase: + + def __init__(self): + self._old_limits = None + super().__init__() + + def update_lim(self, axes): + x1, x2 = axes.get_xlim() + y1, y2 = axes.get_ylim() + if self._old_limits != (x1, x2, y1, y2): + self._update_grid(x1, y1, x2, y2) + self._old_limits = (x1, x2, y1, y2) + + def _update_grid(self, x1, y1, x2, y2): + """Cache relevant computations when the axes limits have changed.""" + + def get_gridlines(self, which, axis): + """ + Return list of grid lines as a list of paths (list of points). + + Parameters + ---------- + which : {"both", "major", "minor"} + axis : {"both", "x", "y"} + """ + return [] + + +class GridHelperRectlinear(GridHelperBase): + + def __init__(self, axes): + super().__init__() + self.axes = axes + + def new_fixed_axis(self, loc, + nth_coord=None, + axis_direction=None, + offset=None, + axes=None, + ): + if axes is None: + _api.warn_external( + "'new_fixed_axis' explicitly requires the axes keyword.") + axes = self.axes + if axis_direction is None: + axis_direction = loc + + helper = FixedAxisArtistHelperRectilinear(axes, loc, nth_coord) + axisline = AxisArtist(axes, helper, offset=offset, + axis_direction=axis_direction) + return axisline + + def new_floating_axis(self, nth_coord, value, + axis_direction="bottom", + axes=None, + ): + if axes is None: + _api.warn_external( + "'new_floating_axis' explicitly requires the axes keyword.") + axes = self.axes + + helper = FloatingAxisArtistHelperRectilinear( + axes, nth_coord, value, axis_direction) + axisline = AxisArtist(axes, helper, axis_direction=axis_direction) + axisline.line.set_clip_on(True) + axisline.line.set_clip_box(axisline.axes.bbox) + return axisline + + def get_gridlines(self, which="major", axis="both"): + """ + Return list of gridline coordinates in data coordinates. + + Parameters + ---------- + which : {"both", "major", "minor"} + axis : {"both", "x", "y"} + """ + _api.check_in_list(["both", "major", "minor"], which=which) + _api.check_in_list(["both", "x", "y"], axis=axis) + gridlines = [] + + if axis in ("both", "x"): + locs = [] + y1, y2 = self.axes.get_ylim() + if which in ("both", "major"): + locs.extend(self.axes.xaxis.major.locator()) + if which in ("both", "minor"): + locs.extend(self.axes.xaxis.minor.locator()) + + for x in locs: + gridlines.append([[x, x], [y1, y2]]) + + if axis in ("both", "y"): + x1, x2 = self.axes.get_xlim() + locs = [] + if self.axes.yaxis._major_tick_kw["gridOn"]: + locs.extend(self.axes.yaxis.major.locator()) + if self.axes.yaxis._minor_tick_kw["gridOn"]: + locs.extend(self.axes.yaxis.minor.locator()) + + for y in locs: + gridlines.append([[x1, x2], [y, y]]) + + return gridlines + + +class Axes(maxes.Axes): + + @_api.deprecated("3.8", alternative="ax.axis") + def __call__(self, *args, **kwargs): + return maxes.Axes.axis(self.axes, *args, **kwargs) + + def __init__(self, *args, grid_helper=None, **kwargs): + self._axisline_on = True + self._grid_helper = (grid_helper if grid_helper + else GridHelperRectlinear(self)) + super().__init__(*args, **kwargs) + self.toggle_axisline(True) + + def toggle_axisline(self, b=None): + if b is None: + b = not self._axisline_on + if b: + self._axisline_on = True + self.spines[:].set_visible(False) + self.xaxis.set_visible(False) + self.yaxis.set_visible(False) + else: + self._axisline_on = False + self.spines[:].set_visible(True) + self.xaxis.set_visible(True) + self.yaxis.set_visible(True) + + @property + def axis(self): + return self._axislines + + def clear(self): + # docstring inherited + + # Init gridlines before clear() as clear() calls grid(). + self.gridlines = gridlines = GridlinesCollection( + [], + colors=mpl.rcParams['grid.color'], + linestyles=mpl.rcParams['grid.linestyle'], + linewidths=mpl.rcParams['grid.linewidth']) + self._set_artist_props(gridlines) + gridlines.set_grid_helper(self.get_grid_helper()) + + super().clear() + + # clip_path is set after Axes.clear(): that's when a patch is created. + gridlines.set_clip_path(self.axes.patch) + + # Init axis artists. + self._axislines = mpl_axes.Axes.AxisDict(self) + new_fixed_axis = self.get_grid_helper().new_fixed_axis + self._axislines.update({ + loc: new_fixed_axis(loc=loc, axes=self, axis_direction=loc) + for loc in ["bottom", "top", "left", "right"]}) + for axisline in [self._axislines["top"], self._axislines["right"]]: + axisline.label.set_visible(False) + axisline.major_ticklabels.set_visible(False) + axisline.minor_ticklabels.set_visible(False) + + def get_grid_helper(self): + return self._grid_helper + + def grid(self, visible=None, which='major', axis="both", **kwargs): + """ + Toggle the gridlines, and optionally set the properties of the lines. + """ + # There are some discrepancies in the behavior of grid() between + # axes_grid and Matplotlib, because axes_grid explicitly sets the + # visibility of the gridlines. + super().grid(visible, which=which, axis=axis, **kwargs) + if not self._axisline_on: + return + if visible is None: + visible = (self.axes.xaxis._minor_tick_kw["gridOn"] + or self.axes.xaxis._major_tick_kw["gridOn"] + or self.axes.yaxis._minor_tick_kw["gridOn"] + or self.axes.yaxis._major_tick_kw["gridOn"]) + self.gridlines.set(which=which, axis=axis, visible=visible) + self.gridlines.set(**kwargs) + + def get_children(self): + if self._axisline_on: + children = [*self._axislines.values(), self.gridlines] + else: + children = [] + children.extend(super().get_children()) + return children + + def new_fixed_axis(self, loc, offset=None): + gh = self.get_grid_helper() + axis = gh.new_fixed_axis(loc, + nth_coord=None, + axis_direction=None, + offset=offset, + axes=self, + ) + return axis + + def new_floating_axis(self, nth_coord, value, axis_direction="bottom"): + gh = self.get_grid_helper() + axis = gh.new_floating_axis(nth_coord, value, + axis_direction=axis_direction, + axes=self) + return axis + + +class AxesZero(Axes): + + def clear(self): + super().clear() + new_floating_axis = self.get_grid_helper().new_floating_axis + self._axislines.update( + xzero=new_floating_axis( + nth_coord=0, value=0., axis_direction="bottom", axes=self), + yzero=new_floating_axis( + nth_coord=1, value=0., axis_direction="left", axes=self), + ) + for k in ["xzero", "yzero"]: + self._axislines[k].line.set_clip_path(self.patch) + self._axislines[k].set_visible(False) + + +Subplot = Axes +SubplotZero = AxesZero diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/floating_axes.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/floating_axes.py new file mode 100644 index 00000000..97dafe98 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/floating_axes.py @@ -0,0 +1,298 @@ +""" +An experimental support for curvilinear grid. +""" + +# TODO : +# see if tick_iterator method can be simplified by reusing the parent method. + +import functools + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook +import matplotlib.patches as mpatches +from matplotlib.path import Path + +from mpl_toolkits.axes_grid1.parasite_axes import host_axes_class_factory + +from . import axislines, grid_helper_curvelinear +from .axis_artist import AxisArtist +from .grid_finder import ExtremeFinderSimple + + +class FloatingAxisArtistHelper( + grid_helper_curvelinear.FloatingAxisArtistHelper): + pass + + +class FixedAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper): + + def __init__(self, grid_helper, side, nth_coord_ticks=None): + """ + nth_coord = along which coordinate value varies. + nth_coord = 0 -> x axis, nth_coord = 1 -> y axis + """ + lon1, lon2, lat1, lat2 = grid_helper.grid_finder.extreme_finder(*[None] * 5) + value, nth_coord = _api.check_getitem( + dict(left=(lon1, 0), right=(lon2, 0), bottom=(lat1, 1), top=(lat2, 1)), + side=side) + super().__init__(grid_helper, nth_coord, value, axis_direction=side) + if nth_coord_ticks is None: + nth_coord_ticks = nth_coord + self.nth_coord_ticks = nth_coord_ticks + + self.value = value + self.grid_helper = grid_helper + self._side = side + + def update_lim(self, axes): + self.grid_helper.update_lim(axes) + self._grid_info = self.grid_helper._grid_info + + def get_tick_iterators(self, axes): + """tick_loc, tick_angle, tick_label, (optionally) tick_label""" + + grid_finder = self.grid_helper.grid_finder + + lat_levs, lat_n, lat_factor = self._grid_info["lat_info"] + yy0 = lat_levs / lat_factor + + lon_levs, lon_n, lon_factor = self._grid_info["lon_info"] + xx0 = lon_levs / lon_factor + + extremes = self.grid_helper.grid_finder.extreme_finder(*[None] * 5) + xmin, xmax = sorted(extremes[:2]) + ymin, ymax = sorted(extremes[2:]) + + def trf_xy(x, y): + trf = grid_finder.get_transform() + axes.transData + return trf.transform(np.column_stack(np.broadcast_arrays(x, y))).T + + if self.nth_coord == 0: + mask = (ymin <= yy0) & (yy0 <= ymax) + (xx1, yy1), (dxx1, dyy1), (dxx2, dyy2) = \ + grid_helper_curvelinear._value_and_jacobian( + trf_xy, self.value, yy0[mask], (xmin, xmax), (ymin, ymax)) + labels = self._grid_info["lat_labels"] + + elif self.nth_coord == 1: + mask = (xmin <= xx0) & (xx0 <= xmax) + (xx1, yy1), (dxx2, dyy2), (dxx1, dyy1) = \ + grid_helper_curvelinear._value_and_jacobian( + trf_xy, xx0[mask], self.value, (xmin, xmax), (ymin, ymax)) + labels = self._grid_info["lon_labels"] + + labels = [l for l, m in zip(labels, mask) if m] + + angle_normal = np.arctan2(dyy1, dxx1) + angle_tangent = np.arctan2(dyy2, dxx2) + mm = (dyy1 == 0) & (dxx1 == 0) # points with degenerate normal + angle_normal[mm] = angle_tangent[mm] + np.pi / 2 + + tick_to_axes = self.get_tick_transform(axes) - axes.transAxes + in_01 = functools.partial( + mpl.transforms._interval_contains_close, (0, 1)) + + def f1(): + for x, y, normal, tangent, lab \ + in zip(xx1, yy1, angle_normal, angle_tangent, labels): + c2 = tick_to_axes.transform((x, y)) + if in_01(c2[0]) and in_01(c2[1]): + yield [x, y], *np.rad2deg([normal, tangent]), lab + + return f1(), iter([]) + + def get_line(self, axes): + self.update_lim(axes) + k, v = dict(left=("lon_lines0", 0), + right=("lon_lines0", 1), + bottom=("lat_lines0", 0), + top=("lat_lines0", 1))[self._side] + xx, yy = self._grid_info[k][v] + return Path(np.column_stack([xx, yy])) + + +class ExtremeFinderFixed(ExtremeFinderSimple): + # docstring inherited + + def __init__(self, extremes): + """ + This subclass always returns the same bounding box. + + Parameters + ---------- + extremes : (float, float, float, float) + The bounding box that this helper always returns. + """ + self._extremes = extremes + + def __call__(self, transform_xy, x1, y1, x2, y2): + # docstring inherited + return self._extremes + + +class GridHelperCurveLinear(grid_helper_curvelinear.GridHelperCurveLinear): + + def __init__(self, aux_trans, extremes, + grid_locator1=None, + grid_locator2=None, + tick_formatter1=None, + tick_formatter2=None): + # docstring inherited + super().__init__(aux_trans, + extreme_finder=ExtremeFinderFixed(extremes), + grid_locator1=grid_locator1, + grid_locator2=grid_locator2, + tick_formatter1=tick_formatter1, + tick_formatter2=tick_formatter2) + + @_api.deprecated("3.8") + def get_data_boundary(self, side): + """ + Return v=0, nth=1. + """ + lon1, lon2, lat1, lat2 = self.grid_finder.extreme_finder(*[None] * 5) + return dict(left=(lon1, 0), + right=(lon2, 0), + bottom=(lat1, 1), + top=(lat2, 1))[side] + + def new_fixed_axis(self, loc, + nth_coord=None, + axis_direction=None, + offset=None, + axes=None): + if axes is None: + axes = self.axes + if axis_direction is None: + axis_direction = loc + # This is not the same as the FixedAxisArtistHelper class used by + # grid_helper_curvelinear.GridHelperCurveLinear.new_fixed_axis! + helper = FixedAxisArtistHelper( + self, loc, nth_coord_ticks=nth_coord) + axisline = AxisArtist(axes, helper, axis_direction=axis_direction) + # Perhaps should be moved to the base class? + axisline.line.set_clip_on(True) + axisline.line.set_clip_box(axisline.axes.bbox) + return axisline + + # new_floating_axis will inherit the grid_helper's extremes. + + # def new_floating_axis(self, nth_coord, + # value, + # axes=None, + # axis_direction="bottom" + # ): + + # axis = super(GridHelperCurveLinear, + # self).new_floating_axis(nth_coord, + # value, axes=axes, + # axis_direction=axis_direction) + + # # set extreme values of the axis helper + # if nth_coord == 1: + # axis.get_helper().set_extremes(*self._extremes[:2]) + # elif nth_coord == 0: + # axis.get_helper().set_extremes(*self._extremes[2:]) + + # return axis + + def _update_grid(self, x1, y1, x2, y2): + if self._grid_info is None: + self._grid_info = dict() + + grid_info = self._grid_info + + grid_finder = self.grid_finder + extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy, + x1, y1, x2, y2) + + lon_min, lon_max = sorted(extremes[:2]) + lat_min, lat_max = sorted(extremes[2:]) + grid_info["extremes"] = lon_min, lon_max, lat_min, lat_max # extremes + + lon_levs, lon_n, lon_factor = \ + grid_finder.grid_locator1(lon_min, lon_max) + lon_levs = np.asarray(lon_levs) + lat_levs, lat_n, lat_factor = \ + grid_finder.grid_locator2(lat_min, lat_max) + lat_levs = np.asarray(lat_levs) + + grid_info["lon_info"] = lon_levs, lon_n, lon_factor + grid_info["lat_info"] = lat_levs, lat_n, lat_factor + + grid_info["lon_labels"] = grid_finder.tick_formatter1( + "bottom", lon_factor, lon_levs) + grid_info["lat_labels"] = grid_finder.tick_formatter2( + "bottom", lat_factor, lat_levs) + + lon_values = lon_levs[:lon_n] / lon_factor + lat_values = lat_levs[:lat_n] / lat_factor + + lon_lines, lat_lines = grid_finder._get_raw_grid_lines( + lon_values[(lon_min < lon_values) & (lon_values < lon_max)], + lat_values[(lat_min < lat_values) & (lat_values < lat_max)], + lon_min, lon_max, lat_min, lat_max) + + grid_info["lon_lines"] = lon_lines + grid_info["lat_lines"] = lat_lines + + lon_lines, lat_lines = grid_finder._get_raw_grid_lines( + # lon_min, lon_max, lat_min, lat_max) + extremes[:2], extremes[2:], *extremes) + + grid_info["lon_lines0"] = lon_lines + grid_info["lat_lines0"] = lat_lines + + def get_gridlines(self, which="major", axis="both"): + grid_lines = [] + if axis in ["both", "x"]: + grid_lines.extend(self._grid_info["lon_lines"]) + if axis in ["both", "y"]: + grid_lines.extend(self._grid_info["lat_lines"]) + return grid_lines + + +class FloatingAxesBase: + + def __init__(self, *args, grid_helper, **kwargs): + _api.check_isinstance(GridHelperCurveLinear, grid_helper=grid_helper) + super().__init__(*args, grid_helper=grid_helper, **kwargs) + self.set_aspect(1.) + + def _gen_axes_patch(self): + # docstring inherited + x0, x1, y0, y1 = self.get_grid_helper().grid_finder.extreme_finder(*[None] * 5) + patch = mpatches.Polygon([(x0, y0), (x1, y0), (x1, y1), (x0, y1)]) + patch.get_path()._interpolation_steps = 100 + return patch + + def clear(self): + super().clear() + self.patch.set_transform( + self.get_grid_helper().grid_finder.get_transform() + + self.transData) + # The original patch is not in the draw tree; it is only used for + # clipping purposes. + orig_patch = super()._gen_axes_patch() + orig_patch.set_figure(self.figure) + orig_patch.set_transform(self.transAxes) + self.patch.set_clip_path(orig_patch) + self.gridlines.set_clip_path(orig_patch) + self.adjust_axes_lim() + + def adjust_axes_lim(self): + bbox = self.patch.get_path().get_extents( + # First transform to pixel coords, then to parent data coords. + self.patch.get_transform() - self.transData) + bbox = bbox.expanded(1.02, 1.02) + self.set_xlim(bbox.xmin, bbox.xmax) + self.set_ylim(bbox.ymin, bbox.ymax) + + +floatingaxes_class_factory = cbook._make_class_factory( + FloatingAxesBase, "Floating{}") +FloatingAxes = floatingaxes_class_factory( + host_axes_class_factory(axislines.Axes)) +FloatingSubplot = FloatingAxes diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_finder.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_finder.py new file mode 100644 index 00000000..f969b011 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_finder.py @@ -0,0 +1,335 @@ +import numpy as np + +from matplotlib import ticker as mticker +from matplotlib.transforms import Bbox, Transform + + +def _find_line_box_crossings(xys, bbox): + """ + Find the points where a polyline crosses a bbox, and the crossing angles. + + Parameters + ---------- + xys : (N, 2) array + The polyline coordinates. + bbox : `.Bbox` + The bounding box. + + Returns + ------- + list of ((float, float), float) + Four separate lists of crossings, for the left, right, bottom, and top + sides of the bbox, respectively. For each list, the entries are the + ``((x, y), ccw_angle_in_degrees)`` of the crossing, where an angle of 0 + means that the polyline is moving to the right at the crossing point. + + The entries are computed by linearly interpolating at each crossing + between the nearest points on either side of the bbox edges. + """ + crossings = [] + dxys = xys[1:] - xys[:-1] + for sl in [slice(None), slice(None, None, -1)]: + us, vs = xys.T[sl] # "this" coord, "other" coord + dus, dvs = dxys.T[sl] + umin, vmin = bbox.min[sl] + umax, vmax = bbox.max[sl] + for u0, inside in [(umin, us > umin), (umax, us < umax)]: + crossings.append([]) + idxs, = (inside[:-1] ^ inside[1:]).nonzero() + for idx in idxs: + v = vs[idx] + (u0 - us[idx]) * dvs[idx] / dus[idx] + if not vmin <= v <= vmax: + continue + crossing = (u0, v)[sl] + theta = np.degrees(np.arctan2(*dxys[idx][::-1])) + crossings[-1].append((crossing, theta)) + return crossings + + +class ExtremeFinderSimple: + """ + A helper class to figure out the range of grid lines that need to be drawn. + """ + + def __init__(self, nx, ny): + """ + Parameters + ---------- + nx, ny : int + The number of samples in each direction. + """ + self.nx = nx + self.ny = ny + + def __call__(self, transform_xy, x1, y1, x2, y2): + """ + Compute an approximation of the bounding box obtained by applying + *transform_xy* to the box delimited by ``(x1, y1, x2, y2)``. + + The intended use is to have ``(x1, y1, x2, y2)`` in axes coordinates, + and have *transform_xy* be the transform from axes coordinates to data + coordinates; this method then returns the range of data coordinates + that span the actual axes. + + The computation is done by sampling ``nx * ny`` equispaced points in + the ``(x1, y1, x2, y2)`` box and finding the resulting points with + extremal coordinates; then adding some padding to take into account the + finite sampling. + + As each sampling step covers a relative range of *1/nx* or *1/ny*, + the padding is computed by expanding the span covered by the extremal + coordinates by these fractions. + """ + x, y = np.meshgrid( + np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)) + xt, yt = transform_xy(np.ravel(x), np.ravel(y)) + return self._add_pad(xt.min(), xt.max(), yt.min(), yt.max()) + + def _add_pad(self, x_min, x_max, y_min, y_max): + """Perform the padding mentioned in `__call__`.""" + dx = (x_max - x_min) / self.nx + dy = (y_max - y_min) / self.ny + return x_min - dx, x_max + dx, y_min - dy, y_max + dy + + +class _User2DTransform(Transform): + """A transform defined by two user-set functions.""" + + input_dims = output_dims = 2 + + def __init__(self, forward, backward): + """ + Parameters + ---------- + forward, backward : callable + The forward and backward transforms, taking ``x`` and ``y`` as + separate arguments and returning ``(tr_x, tr_y)``. + """ + # The normal Matplotlib convention would be to take and return an + # (N, 2) array but axisartist uses the transposed version. + super().__init__() + self._forward = forward + self._backward = backward + + def transform_non_affine(self, values): + # docstring inherited + return np.transpose(self._forward(*np.transpose(values))) + + def inverted(self): + # docstring inherited + return type(self)(self._backward, self._forward) + + +class GridFinder: + """ + Internal helper for `~.grid_helper_curvelinear.GridHelperCurveLinear`, with + the same constructor parameters; should not be directly instantiated. + """ + + def __init__(self, + transform, + extreme_finder=None, + grid_locator1=None, + grid_locator2=None, + tick_formatter1=None, + tick_formatter2=None): + if extreme_finder is None: + extreme_finder = ExtremeFinderSimple(20, 20) + if grid_locator1 is None: + grid_locator1 = MaxNLocator() + if grid_locator2 is None: + grid_locator2 = MaxNLocator() + if tick_formatter1 is None: + tick_formatter1 = FormatterPrettyPrint() + if tick_formatter2 is None: + tick_formatter2 = FormatterPrettyPrint() + self.extreme_finder = extreme_finder + self.grid_locator1 = grid_locator1 + self.grid_locator2 = grid_locator2 + self.tick_formatter1 = tick_formatter1 + self.tick_formatter2 = tick_formatter2 + self.set_transform(transform) + + def get_grid_info(self, x1, y1, x2, y2): + """ + lon_values, lat_values : list of grid values. if integer is given, + rough number of grids in each direction. + """ + + extremes = self.extreme_finder(self.inv_transform_xy, x1, y1, x2, y2) + + # min & max rage of lat (or lon) for each grid line will be drawn. + # i.e., gridline of lon=0 will be drawn from lat_min to lat_max. + + lon_min, lon_max, lat_min, lat_max = extremes + lon_levs, lon_n, lon_factor = self.grid_locator1(lon_min, lon_max) + lon_levs = np.asarray(lon_levs) + lat_levs, lat_n, lat_factor = self.grid_locator2(lat_min, lat_max) + lat_levs = np.asarray(lat_levs) + + lon_values = lon_levs[:lon_n] / lon_factor + lat_values = lat_levs[:lat_n] / lat_factor + + lon_lines, lat_lines = self._get_raw_grid_lines(lon_values, + lat_values, + lon_min, lon_max, + lat_min, lat_max) + + ddx = (x2-x1)*1.e-10 + ddy = (y2-y1)*1.e-10 + bb = Bbox.from_extents(x1-ddx, y1-ddy, x2+ddx, y2+ddy) + + grid_info = { + "extremes": extremes, + "lon_lines": lon_lines, + "lat_lines": lat_lines, + "lon": self._clip_grid_lines_and_find_ticks( + lon_lines, lon_values, lon_levs, bb), + "lat": self._clip_grid_lines_and_find_ticks( + lat_lines, lat_values, lat_levs, bb), + } + + tck_labels = grid_info["lon"]["tick_labels"] = {} + for direction in ["left", "bottom", "right", "top"]: + levs = grid_info["lon"]["tick_levels"][direction] + tck_labels[direction] = self.tick_formatter1( + direction, lon_factor, levs) + + tck_labels = grid_info["lat"]["tick_labels"] = {} + for direction in ["left", "bottom", "right", "top"]: + levs = grid_info["lat"]["tick_levels"][direction] + tck_labels[direction] = self.tick_formatter2( + direction, lat_factor, levs) + + return grid_info + + def _get_raw_grid_lines(self, + lon_values, lat_values, + lon_min, lon_max, lat_min, lat_max): + + lons_i = np.linspace(lon_min, lon_max, 100) # for interpolation + lats_i = np.linspace(lat_min, lat_max, 100) + + lon_lines = [self.transform_xy(np.full_like(lats_i, lon), lats_i) + for lon in lon_values] + lat_lines = [self.transform_xy(lons_i, np.full_like(lons_i, lat)) + for lat in lat_values] + + return lon_lines, lat_lines + + def _clip_grid_lines_and_find_ticks(self, lines, values, levs, bb): + gi = { + "values": [], + "levels": [], + "tick_levels": dict(left=[], bottom=[], right=[], top=[]), + "tick_locs": dict(left=[], bottom=[], right=[], top=[]), + "lines": [], + } + + tck_levels = gi["tick_levels"] + tck_locs = gi["tick_locs"] + for (lx, ly), v, lev in zip(lines, values, levs): + tcks = _find_line_box_crossings(np.column_stack([lx, ly]), bb) + gi["levels"].append(v) + gi["lines"].append([(lx, ly)]) + + for tck, direction in zip(tcks, + ["left", "right", "bottom", "top"]): + for t in tck: + tck_levels[direction].append(lev) + tck_locs[direction].append(t) + + return gi + + def set_transform(self, aux_trans): + if isinstance(aux_trans, Transform): + self._aux_transform = aux_trans + elif len(aux_trans) == 2 and all(map(callable, aux_trans)): + self._aux_transform = _User2DTransform(*aux_trans) + else: + raise TypeError("'aux_trans' must be either a Transform " + "instance or a pair of callables") + + def get_transform(self): + return self._aux_transform + + update_transform = set_transform # backcompat alias. + + def transform_xy(self, x, y): + return self._aux_transform.transform(np.column_stack([x, y])).T + + def inv_transform_xy(self, x, y): + return self._aux_transform.inverted().transform( + np.column_stack([x, y])).T + + def update(self, **kwargs): + for k, v in kwargs.items(): + if k in ["extreme_finder", + "grid_locator1", + "grid_locator2", + "tick_formatter1", + "tick_formatter2"]: + setattr(self, k, v) + else: + raise ValueError(f"Unknown update property {k!r}") + + +class MaxNLocator(mticker.MaxNLocator): + def __init__(self, nbins=10, steps=None, + trim=True, + integer=False, + symmetric=False, + prune=None): + # trim argument has no effect. It has been left for API compatibility + super().__init__(nbins, steps=steps, integer=integer, + symmetric=symmetric, prune=prune) + self.create_dummy_axis() + + def __call__(self, v1, v2): + locs = super().tick_values(v1, v2) + return np.array(locs), len(locs), 1 # 1: factor (see angle_helper) + + +class FixedLocator: + def __init__(self, locs): + self._locs = locs + + def __call__(self, v1, v2): + v1, v2 = sorted([v1, v2]) + locs = np.array([l for l in self._locs if v1 <= l <= v2]) + return locs, len(locs), 1 # 1: factor (see angle_helper) + + +# Tick Formatter + +class FormatterPrettyPrint: + def __init__(self, useMathText=True): + self._fmt = mticker.ScalarFormatter( + useMathText=useMathText, useOffset=False) + self._fmt.create_dummy_axis() + + def __call__(self, direction, factor, values): + return self._fmt.format_ticks(values) + + +class DictFormatter: + def __init__(self, format_dict, formatter=None): + """ + format_dict : dictionary for format strings to be used. + formatter : fall-back formatter + """ + super().__init__() + self._format_dict = format_dict + self._fallback_formatter = formatter + + def __call__(self, direction, factor, values): + """ + factor is ignored if value is found in the dictionary + """ + if self._fallback_formatter: + fallback_strings = self._fallback_formatter( + direction, factor, values) + else: + fallback_strings = [""] * len(values) + return [self._format_dict.get(k, v) + for k, v in zip(values, fallback_strings)] diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py new file mode 100644 index 00000000..ae17452b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py @@ -0,0 +1,336 @@ +""" +An experimental support for curvilinear grid. +""" + +import functools +from itertools import chain + +import numpy as np + +import matplotlib as mpl +from matplotlib.path import Path +from matplotlib.transforms import Affine2D, IdentityTransform +from .axislines import ( + _FixedAxisArtistHelperBase, _FloatingAxisArtistHelperBase, GridHelperBase) +from .axis_artist import AxisArtist +from .grid_finder import GridFinder + + +def _value_and_jacobian(func, xs, ys, xlims, ylims): + """ + Compute *func* and its derivatives along x and y at positions *xs*, *ys*, + while ensuring that finite difference calculations don't try to evaluate + values outside of *xlims*, *ylims*. + """ + eps = np.finfo(float).eps ** (1/2) # see e.g. scipy.optimize.approx_fprime + val = func(xs, ys) + # Take the finite difference step in the direction where the bound is the + # furthest; the step size is min of epsilon and distance to that bound. + xlo, xhi = sorted(xlims) + dxlo = xs - xlo + dxhi = xhi - xs + xeps = (np.take([-1, 1], dxhi >= dxlo) + * np.minimum(eps, np.maximum(dxlo, dxhi))) + val_dx = func(xs + xeps, ys) + ylo, yhi = sorted(ylims) + dylo = ys - ylo + dyhi = yhi - ys + yeps = (np.take([-1, 1], dyhi >= dylo) + * np.minimum(eps, np.maximum(dylo, dyhi))) + val_dy = func(xs, ys + yeps) + return (val, (val_dx - val) / xeps, (val_dy - val) / yeps) + + +class FixedAxisArtistHelper(_FixedAxisArtistHelperBase): + """ + Helper class for a fixed axis. + """ + + def __init__(self, grid_helper, side, nth_coord_ticks=None): + """ + nth_coord = along which coordinate value varies. + nth_coord = 0 -> x axis, nth_coord = 1 -> y axis + """ + + super().__init__(loc=side) + + self.grid_helper = grid_helper + if nth_coord_ticks is None: + nth_coord_ticks = self.nth_coord + self.nth_coord_ticks = nth_coord_ticks + + self.side = side + + def update_lim(self, axes): + self.grid_helper.update_lim(axes) + + def get_tick_transform(self, axes): + return axes.transData + + def get_tick_iterators(self, axes): + """tick_loc, tick_angle, tick_label""" + v1, v2 = axes.get_ylim() if self.nth_coord == 0 else axes.get_xlim() + if v1 > v2: # Inverted limits. + side = {"left": "right", "right": "left", + "top": "bottom", "bottom": "top"}[self.side] + else: + side = self.side + g = self.grid_helper + ti1 = g.get_tick_iterator(self.nth_coord_ticks, side) + ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, side, minor=True) + return chain(ti1, ti2), iter([]) + + +class FloatingAxisArtistHelper(_FloatingAxisArtistHelperBase): + + def __init__(self, grid_helper, nth_coord, value, axis_direction=None): + """ + nth_coord = along which coordinate value varies. + nth_coord = 0 -> x axis, nth_coord = 1 -> y axis + """ + super().__init__(nth_coord, value) + self.value = value + self.grid_helper = grid_helper + self._extremes = -np.inf, np.inf + self._line_num_points = 100 # number of points to create a line + + def set_extremes(self, e1, e2): + if e1 is None: + e1 = -np.inf + if e2 is None: + e2 = np.inf + self._extremes = e1, e2 + + def update_lim(self, axes): + self.grid_helper.update_lim(axes) + + x1, x2 = axes.get_xlim() + y1, y2 = axes.get_ylim() + grid_finder = self.grid_helper.grid_finder + extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy, + x1, y1, x2, y2) + + lon_min, lon_max, lat_min, lat_max = extremes + e_min, e_max = self._extremes # ranges of other coordinates + if self.nth_coord == 0: + lat_min = max(e_min, lat_min) + lat_max = min(e_max, lat_max) + elif self.nth_coord == 1: + lon_min = max(e_min, lon_min) + lon_max = min(e_max, lon_max) + + lon_levs, lon_n, lon_factor = \ + grid_finder.grid_locator1(lon_min, lon_max) + lat_levs, lat_n, lat_factor = \ + grid_finder.grid_locator2(lat_min, lat_max) + + if self.nth_coord == 0: + xx0 = np.full(self._line_num_points, self.value) + yy0 = np.linspace(lat_min, lat_max, self._line_num_points) + xx, yy = grid_finder.transform_xy(xx0, yy0) + elif self.nth_coord == 1: + xx0 = np.linspace(lon_min, lon_max, self._line_num_points) + yy0 = np.full(self._line_num_points, self.value) + xx, yy = grid_finder.transform_xy(xx0, yy0) + + self._grid_info = { + "extremes": (lon_min, lon_max, lat_min, lat_max), + "lon_info": (lon_levs, lon_n, np.asarray(lon_factor)), + "lat_info": (lat_levs, lat_n, np.asarray(lat_factor)), + "lon_labels": grid_finder.tick_formatter1( + "bottom", lon_factor, lon_levs), + "lat_labels": grid_finder.tick_formatter2( + "bottom", lat_factor, lat_levs), + "line_xy": (xx, yy), + } + + def get_axislabel_transform(self, axes): + return Affine2D() # axes.transData + + def get_axislabel_pos_angle(self, axes): + def trf_xy(x, y): + trf = self.grid_helper.grid_finder.get_transform() + axes.transData + return trf.transform([x, y]).T + + xmin, xmax, ymin, ymax = self._grid_info["extremes"] + if self.nth_coord == 0: + xx0 = self.value + yy0 = (ymin + ymax) / 2 + elif self.nth_coord == 1: + xx0 = (xmin + xmax) / 2 + yy0 = self.value + xy1, dxy1_dx, dxy1_dy = _value_and_jacobian( + trf_xy, xx0, yy0, (xmin, xmax), (ymin, ymax)) + p = axes.transAxes.inverted().transform(xy1) + if 0 <= p[0] <= 1 and 0 <= p[1] <= 1: + d = [dxy1_dy, dxy1_dx][self.nth_coord] + return xy1, np.rad2deg(np.arctan2(*d[::-1])) + else: + return None, None + + def get_tick_transform(self, axes): + return IdentityTransform() # axes.transData + + def get_tick_iterators(self, axes): + """tick_loc, tick_angle, tick_label, (optionally) tick_label""" + + lat_levs, lat_n, lat_factor = self._grid_info["lat_info"] + yy0 = lat_levs / lat_factor + + lon_levs, lon_n, lon_factor = self._grid_info["lon_info"] + xx0 = lon_levs / lon_factor + + e0, e1 = self._extremes + + def trf_xy(x, y): + trf = self.grid_helper.grid_finder.get_transform() + axes.transData + return trf.transform(np.column_stack(np.broadcast_arrays(x, y))).T + + # find angles + if self.nth_coord == 0: + mask = (e0 <= yy0) & (yy0 <= e1) + (xx1, yy1), (dxx1, dyy1), (dxx2, dyy2) = _value_and_jacobian( + trf_xy, self.value, yy0[mask], (-np.inf, np.inf), (e0, e1)) + labels = self._grid_info["lat_labels"] + + elif self.nth_coord == 1: + mask = (e0 <= xx0) & (xx0 <= e1) + (xx1, yy1), (dxx2, dyy2), (dxx1, dyy1) = _value_and_jacobian( + trf_xy, xx0[mask], self.value, (-np.inf, np.inf), (e0, e1)) + labels = self._grid_info["lon_labels"] + + labels = [l for l, m in zip(labels, mask) if m] + + angle_normal = np.arctan2(dyy1, dxx1) + angle_tangent = np.arctan2(dyy2, dxx2) + mm = (dyy1 == 0) & (dxx1 == 0) # points with degenerate normal + angle_normal[mm] = angle_tangent[mm] + np.pi / 2 + + tick_to_axes = self.get_tick_transform(axes) - axes.transAxes + in_01 = functools.partial( + mpl.transforms._interval_contains_close, (0, 1)) + + def f1(): + for x, y, normal, tangent, lab \ + in zip(xx1, yy1, angle_normal, angle_tangent, labels): + c2 = tick_to_axes.transform((x, y)) + if in_01(c2[0]) and in_01(c2[1]): + yield [x, y], *np.rad2deg([normal, tangent]), lab + + return f1(), iter([]) + + def get_line_transform(self, axes): + return axes.transData + + def get_line(self, axes): + self.update_lim(axes) + x, y = self._grid_info["line_xy"] + return Path(np.column_stack([x, y])) + + +class GridHelperCurveLinear(GridHelperBase): + def __init__(self, aux_trans, + extreme_finder=None, + grid_locator1=None, + grid_locator2=None, + tick_formatter1=None, + tick_formatter2=None): + """ + Parameters + ---------- + aux_trans : `.Transform` or tuple[Callable, Callable] + The transform from curved coordinates to rectilinear coordinate: + either a `.Transform` instance (which provides also its inverse), + or a pair of callables ``(trans, inv_trans)`` that define the + transform and its inverse. The callables should have signature:: + + x_rect, y_rect = trans(x_curved, y_curved) + x_curved, y_curved = inv_trans(x_rect, y_rect) + + extreme_finder + + grid_locator1, grid_locator2 + Grid locators for each axis. + + tick_formatter1, tick_formatter2 + Tick formatters for each axis. + """ + super().__init__() + self._grid_info = None + self.grid_finder = GridFinder(aux_trans, + extreme_finder, + grid_locator1, + grid_locator2, + tick_formatter1, + tick_formatter2) + + def update_grid_finder(self, aux_trans=None, **kwargs): + if aux_trans is not None: + self.grid_finder.update_transform(aux_trans) + self.grid_finder.update(**kwargs) + self._old_limits = None # Force revalidation. + + def new_fixed_axis(self, loc, + nth_coord=None, + axis_direction=None, + offset=None, + axes=None): + if axes is None: + axes = self.axes + if axis_direction is None: + axis_direction = loc + helper = FixedAxisArtistHelper(self, loc, nth_coord_ticks=nth_coord) + axisline = AxisArtist(axes, helper, axis_direction=axis_direction) + # Why is clip not set on axisline, unlike in new_floating_axis or in + # the floating_axig.GridHelperCurveLinear subclass? + return axisline + + def new_floating_axis(self, nth_coord, + value, + axes=None, + axis_direction="bottom" + ): + if axes is None: + axes = self.axes + helper = FloatingAxisArtistHelper( + self, nth_coord, value, axis_direction) + axisline = AxisArtist(axes, helper) + axisline.line.set_clip_on(True) + axisline.line.set_clip_box(axisline.axes.bbox) + # axisline.major_ticklabels.set_visible(True) + # axisline.minor_ticklabels.set_visible(False) + return axisline + + def _update_grid(self, x1, y1, x2, y2): + self._grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2) + + def get_gridlines(self, which="major", axis="both"): + grid_lines = [] + if axis in ["both", "x"]: + for gl in self._grid_info["lon"]["lines"]: + grid_lines.extend(gl) + if axis in ["both", "y"]: + for gl in self._grid_info["lat"]["lines"]: + grid_lines.extend(gl) + return grid_lines + + def get_tick_iterator(self, nth_coord, axis_side, minor=False): + + # axisnr = dict(left=0, bottom=1, right=2, top=3)[axis_side] + angle_tangent = dict(left=90, right=90, bottom=0, top=0)[axis_side] + # angle = [0, 90, 180, 270][axisnr] + lon_or_lat = ["lon", "lat"][nth_coord] + if not minor: # major ticks + for (xy, a), l in zip( + self._grid_info[lon_or_lat]["tick_locs"][axis_side], + self._grid_info[lon_or_lat]["tick_labels"][axis_side]): + angle_normal = a + yield xy, angle_normal, angle_tangent, l + else: + for (xy, a), l in zip( + self._grid_info[lon_or_lat]["tick_locs"][axis_side], + self._grid_info[lon_or_lat]["tick_labels"][axis_side]): + angle_normal = a + yield xy, angle_normal, angle_tangent, "" + # for xy, a, l in self._grid_info[lon_or_lat]["ticks"][axis_side]: + # yield xy, a, "" diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/parasite_axes.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/parasite_axes.py new file mode 100644 index 00000000..4ebd6acc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/parasite_axes.py @@ -0,0 +1,7 @@ +from mpl_toolkits.axes_grid1.parasite_axes import ( + host_axes_class_factory, parasite_axes_class_factory) +from .axislines import Axes + + +ParasiteAxes = parasite_axes_class_factory(Axes) +HostAxes = SubplotHost = host_axes_class_factory(Axes) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/__init__.py new file mode 100644 index 00000000..ea4d8ed1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/__init__.py @@ -0,0 +1,10 @@ +from pathlib import Path + + +# Check that the test directories exist +if not (Path(__file__).parent / "baseline_images").exists(): + raise OSError( + 'The baseline image directory does not exist. ' + 'This is most likely because the test data is not installed. ' + 'You may need to install matplotlib from source to get the ' + 'test data.') diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/conftest.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/conftest.py new file mode 100644 index 00000000..61c2de3e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/conftest.py @@ -0,0 +1,2 @@ +from matplotlib.testing.conftest import (mpl_test_settings, # noqa + pytest_configure, pytest_unconfigure) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_angle_helper.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_angle_helper.py new file mode 100644 index 00000000..3156b33b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_angle_helper.py @@ -0,0 +1,141 @@ +import re + +import numpy as np +import pytest + +from mpl_toolkits.axisartist.angle_helper import ( + FormatterDMS, FormatterHMS, select_step, select_step24, select_step360) + + +_MS_RE = ( + r'''\$ # Mathtext + ( + # The sign sometimes appears on a 0 when a fraction is shown. + # Check later that there's only one. + (?P<degree_sign>-)? + (?P<degree>[0-9.]+) # Degrees value + {degree} # Degree symbol (to be replaced by format.) + )? + ( + (?(degree)\\,) # Separator if degrees are also visible. + (?P<minute_sign>-)? + (?P<minute>[0-9.]+) # Minutes value + {minute} # Minute symbol (to be replaced by format.) + )? + ( + (?(minute)\\,) # Separator if minutes are also visible. + (?P<second_sign>-)? + (?P<second>[0-9.]+) # Seconds value + {second} # Second symbol (to be replaced by format.) + )? + \$ # Mathtext + ''' +) +DMS_RE = re.compile(_MS_RE.format(degree=re.escape(FormatterDMS.deg_mark), + minute=re.escape(FormatterDMS.min_mark), + second=re.escape(FormatterDMS.sec_mark)), + re.VERBOSE) +HMS_RE = re.compile(_MS_RE.format(degree=re.escape(FormatterHMS.deg_mark), + minute=re.escape(FormatterHMS.min_mark), + second=re.escape(FormatterHMS.sec_mark)), + re.VERBOSE) + + +def dms2float(degrees, minutes=0, seconds=0): + return degrees + minutes / 60.0 + seconds / 3600.0 + + +@pytest.mark.parametrize('args, kwargs, expected_levels, expected_factor', [ + ((-180, 180, 10), {'hour': False}, np.arange(-180, 181, 30), 1.0), + ((-12, 12, 10), {'hour': True}, np.arange(-12, 13, 2), 1.0) +]) +def test_select_step(args, kwargs, expected_levels, expected_factor): + levels, n, factor = select_step(*args, **kwargs) + + assert n == len(levels) + np.testing.assert_array_equal(levels, expected_levels) + assert factor == expected_factor + + +@pytest.mark.parametrize('args, kwargs, expected_levels, expected_factor', [ + ((-180, 180, 10), {}, np.arange(-180, 181, 30), 1.0), + ((-12, 12, 10), {}, np.arange(-750, 751, 150), 60.0) +]) +def test_select_step24(args, kwargs, expected_levels, expected_factor): + levels, n, factor = select_step24(*args, **kwargs) + + assert n == len(levels) + np.testing.assert_array_equal(levels, expected_levels) + assert factor == expected_factor + + +@pytest.mark.parametrize('args, kwargs, expected_levels, expected_factor', [ + ((dms2float(20, 21.2), dms2float(21, 33.3), 5), {}, + np.arange(1215, 1306, 15), 60.0), + ((dms2float(20.5, seconds=21.2), dms2float(20.5, seconds=33.3), 5), {}, + np.arange(73820, 73835, 2), 3600.0), + ((dms2float(20, 21.2), dms2float(20, 53.3), 5), {}, + np.arange(1220, 1256, 5), 60.0), + ((21.2, 33.3, 5), {}, + np.arange(20, 35, 2), 1.0), + ((dms2float(20, 21.2), dms2float(21, 33.3), 5), {}, + np.arange(1215, 1306, 15), 60.0), + ((dms2float(20.5, seconds=21.2), dms2float(20.5, seconds=33.3), 5), {}, + np.arange(73820, 73835, 2), 3600.0), + ((dms2float(20.5, seconds=21.2), dms2float(20.5, seconds=21.4), 5), {}, + np.arange(7382120, 7382141, 5), 360000.0), + # test threshold factor + ((dms2float(20.5, seconds=11.2), dms2float(20.5, seconds=53.3), 5), + {'threshold_factor': 60}, np.arange(12301, 12310), 600.0), + ((dms2float(20.5, seconds=11.2), dms2float(20.5, seconds=53.3), 5), + {'threshold_factor': 1}, np.arange(20502, 20517, 2), 1000.0), +]) +def test_select_step360(args, kwargs, expected_levels, expected_factor): + levels, n, factor = select_step360(*args, **kwargs) + + assert n == len(levels) + np.testing.assert_array_equal(levels, expected_levels) + assert factor == expected_factor + + +@pytest.mark.parametrize('Formatter, regex', + [(FormatterDMS, DMS_RE), + (FormatterHMS, HMS_RE)], + ids=['Degree/Minute/Second', 'Hour/Minute/Second']) +@pytest.mark.parametrize('direction, factor, values', [ + ("left", 60, [0, -30, -60]), + ("left", 600, [12301, 12302, 12303]), + ("left", 3600, [0, -30, -60]), + ("left", 36000, [738210, 738215, 738220]), + ("left", 360000, [7382120, 7382125, 7382130]), + ("left", 1., [45, 46, 47]), + ("left", 10., [452, 453, 454]), +]) +def test_formatters(Formatter, regex, direction, factor, values): + fmt = Formatter() + result = fmt(direction, factor, values) + + prev_degree = prev_minute = prev_second = None + for tick, value in zip(result, values): + m = regex.match(tick) + assert m is not None, f'{tick!r} is not an expected tick format.' + + sign = sum(m.group(sign + '_sign') is not None + for sign in ('degree', 'minute', 'second')) + assert sign <= 1, f'Only one element of tick {tick!r} may have a sign.' + sign = 1 if sign == 0 else -1 + + degree = float(m.group('degree') or prev_degree or 0) + minute = float(m.group('minute') or prev_minute or 0) + second = float(m.group('second') or prev_second or 0) + if Formatter == FormatterHMS: + # 360 degrees as plot range -> 24 hours as labelled range + expected_value = pytest.approx((value // 15) / factor) + else: + expected_value = pytest.approx(value / factor) + assert sign * dms2float(degree, minute, second) == expected_value, \ + f'{tick!r} does not match expected tick value.' + + prev_degree = degree + prev_minute = minute + prev_second = second diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axis_artist.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axis_artist.py new file mode 100644 index 00000000..d44a61b6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axis_artist.py @@ -0,0 +1,99 @@ +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison + +from mpl_toolkits.axisartist import AxisArtistHelperRectlinear +from mpl_toolkits.axisartist.axis_artist import (AxisArtist, AxisLabel, + LabelBase, Ticks, TickLabels) + + +@image_comparison(['axis_artist_ticks.png'], style='default') +def test_ticks(): + fig, ax = plt.subplots() + + ax.xaxis.set_visible(False) + ax.yaxis.set_visible(False) + + locs_angles = [((i / 10, 0.0), i * 30) for i in range(-1, 12)] + + ticks_in = Ticks(ticksize=10, axis=ax.xaxis) + ticks_in.set_locs_angles(locs_angles) + ax.add_artist(ticks_in) + + ticks_out = Ticks(ticksize=10, tick_out=True, color='C3', axis=ax.xaxis) + ticks_out.set_locs_angles(locs_angles) + ax.add_artist(ticks_out) + + +@image_comparison(['axis_artist_labelbase.png'], style='default') +def test_labelbase(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, ax = plt.subplots() + + ax.plot([0.5], [0.5], "o") + + label = LabelBase(0.5, 0.5, "Test") + label._ref_angle = -90 + label._offset_radius = 50 + label.set_rotation(-90) + label.set(ha="center", va="top") + ax.add_artist(label) + + +@image_comparison(['axis_artist_ticklabels.png'], style='default') +def test_ticklabels(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, ax = plt.subplots() + + ax.xaxis.set_visible(False) + ax.yaxis.set_visible(False) + + ax.plot([0.2, 0.4], [0.5, 0.5], "o") + + ticks = Ticks(ticksize=10, axis=ax.xaxis) + ax.add_artist(ticks) + locs_angles_labels = [((0.2, 0.5), -90, "0.2"), + ((0.4, 0.5), -120, "0.4")] + tick_locs_angles = [(xy, a + 180) for xy, a, l in locs_angles_labels] + ticks.set_locs_angles(tick_locs_angles) + + ticklabels = TickLabels(axis_direction="left") + ticklabels._locs_angles_labels = locs_angles_labels + ticklabels.set_pad(10) + ax.add_artist(ticklabels) + + ax.plot([0.5], [0.5], "s") + axislabel = AxisLabel(0.5, 0.5, "Test") + axislabel._offset_radius = 20 + axislabel._ref_angle = 0 + axislabel.set_axis_direction("bottom") + ax.add_artist(axislabel) + + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + + +@image_comparison(['axis_artist.png'], style='default') +def test_axis_artist(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig, ax = plt.subplots() + + ax.xaxis.set_visible(False) + ax.yaxis.set_visible(False) + + for loc in ('left', 'right', 'bottom'): + helper = AxisArtistHelperRectlinear.Fixed(ax, loc=loc) + axisline = AxisArtist(ax, helper, offset=None, axis_direction=loc) + ax.add_artist(axisline) + + # Settings for bottom AxisArtist. + axisline.set_label("TTT") + axisline.major_ticks.set_tick_out(False) + axisline.label.set_pad(5) + + ax.set_ylabel("Test") diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axislines.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axislines.py new file mode 100644 index 00000000..b722316a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_axislines.py @@ -0,0 +1,147 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison +from matplotlib.transforms import IdentityTransform + +from mpl_toolkits.axisartist.axislines import AxesZero, SubplotZero, Subplot +from mpl_toolkits.axisartist import Axes, SubplotHost + + +@image_comparison(['SubplotZero.png'], style='default') +def test_SubplotZero(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig = plt.figure() + + ax = SubplotZero(fig, 1, 1, 1) + fig.add_subplot(ax) + + ax.axis["xzero"].set_visible(True) + ax.axis["xzero"].label.set_text("Axis Zero") + + for n in ["top", "right"]: + ax.axis[n].set_visible(False) + + xx = np.arange(0, 2 * np.pi, 0.01) + ax.plot(xx, np.sin(xx)) + ax.set_ylabel("Test") + + +@image_comparison(['Subplot.png'], style='default') +def test_Subplot(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig = plt.figure() + + ax = Subplot(fig, 1, 1, 1) + fig.add_subplot(ax) + + xx = np.arange(0, 2 * np.pi, 0.01) + ax.plot(xx, np.sin(xx)) + ax.set_ylabel("Test") + + ax.axis["top"].major_ticks.set_tick_out(True) + ax.axis["bottom"].major_ticks.set_tick_out(True) + + ax.axis["bottom"].set_label("Tk0") + + +def test_Axes(): + fig = plt.figure() + ax = Axes(fig, [0.15, 0.1, 0.65, 0.8]) + fig.add_axes(ax) + ax.plot([1, 2, 3], [0, 1, 2]) + ax.set_xscale('log') + fig.canvas.draw() + + +@image_comparison(['ParasiteAxesAuxTrans_meshplot.png'], + remove_text=True, style='default', tol=0.075) +def test_ParasiteAxesAuxTrans(): + data = np.ones((6, 6)) + data[2, 2] = 2 + data[0, :] = 0 + data[-2, :] = 0 + data[:, 0] = 0 + data[:, -2] = 0 + x = np.arange(6) + y = np.arange(6) + xx, yy = np.meshgrid(x, y) + + funcnames = ['pcolor', 'pcolormesh', 'contourf'] + + fig = plt.figure() + for i, name in enumerate(funcnames): + + ax1 = SubplotHost(fig, 1, 3, i+1) + fig.add_subplot(ax1) + + ax2 = ax1.get_aux_axes(IdentityTransform(), viewlim_mode=None) + if name.startswith('pcolor'): + getattr(ax2, name)(xx, yy, data[:-1, :-1]) + else: + getattr(ax2, name)(xx, yy, data) + ax1.set_xlim((0, 5)) + ax1.set_ylim((0, 5)) + + ax2.contour(xx, yy, data, colors='k') + + +@image_comparison(['axisline_style.png'], remove_text=True, style='mpl20') +def test_axisline_style(): + fig = plt.figure(figsize=(2, 2)) + ax = fig.add_subplot(axes_class=AxesZero) + ax.axis["xzero"].set_axisline_style("-|>") + ax.axis["xzero"].set_visible(True) + ax.axis["yzero"].set_axisline_style("->") + ax.axis["yzero"].set_visible(True) + + for direction in ("left", "right", "bottom", "top"): + ax.axis[direction].set_visible(False) + + +@image_comparison(['axisline_style_size_color.png'], remove_text=True, + style='mpl20') +def test_axisline_style_size_color(): + fig = plt.figure(figsize=(2, 2)) + ax = fig.add_subplot(axes_class=AxesZero) + ax.axis["xzero"].set_axisline_style("-|>", size=2.0, facecolor='r') + ax.axis["xzero"].set_visible(True) + ax.axis["yzero"].set_axisline_style("->, size=1.5") + ax.axis["yzero"].set_visible(True) + + for direction in ("left", "right", "bottom", "top"): + ax.axis[direction].set_visible(False) + + +@image_comparison(['axisline_style_tight.png'], remove_text=True, + style='mpl20') +def test_axisline_style_tight(): + fig = plt.figure(figsize=(2, 2)) + ax = fig.add_subplot(axes_class=AxesZero) + ax.axis["xzero"].set_axisline_style("-|>", size=5, facecolor='g') + ax.axis["xzero"].set_visible(True) + ax.axis["yzero"].set_axisline_style("->, size=8") + ax.axis["yzero"].set_visible(True) + + for direction in ("left", "right", "bottom", "top"): + ax.axis[direction].set_visible(False) + + fig.tight_layout() + + +@image_comparison(['subplotzero_ylabel.png'], style='mpl20') +def test_subplotzero_ylabel(): + fig = plt.figure() + ax = fig.add_subplot(111, axes_class=SubplotZero) + + ax.set(xlim=(-3, 7), ylim=(-3, 7), xlabel="x", ylabel="y") + + zero_axis = ax.axis["xzero", "yzero"] + zero_axis.set_visible(True) # they are hidden by default + + ax.axis["left", "right", "bottom", "top"].set_visible(False) + + zero_axis.set_axisline_style("->") diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_floating_axes.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_floating_axes.py new file mode 100644 index 00000000..31dcf24b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_floating_axes.py @@ -0,0 +1,115 @@ +import numpy as np + +import matplotlib.pyplot as plt +import matplotlib.projections as mprojections +import matplotlib.transforms as mtransforms +from matplotlib.testing.decorators import image_comparison +from mpl_toolkits.axisartist.axislines import Subplot +from mpl_toolkits.axisartist.floating_axes import ( + FloatingAxes, GridHelperCurveLinear) +from mpl_toolkits.axisartist.grid_finder import FixedLocator +from mpl_toolkits.axisartist import angle_helper + + +def test_subplot(): + fig = plt.figure(figsize=(5, 5)) + ax = Subplot(fig, 111) + fig.add_subplot(ax) + + +# Rather high tolerance to allow ongoing work with floating axes internals; +# remove when image is regenerated. +@image_comparison(['curvelinear3.png'], style='default', tol=5) +def test_curvelinear3(): + fig = plt.figure(figsize=(5, 5)) + + tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) + + mprojections.PolarAxes.PolarTransform()) + grid_helper = GridHelperCurveLinear( + tr, + extremes=(0, 360, 10, 3), + grid_locator1=angle_helper.LocatorDMS(15), + grid_locator2=FixedLocator([2, 4, 6, 8, 10]), + tick_formatter1=angle_helper.FormatterDMS(), + tick_formatter2=None) + ax1 = fig.add_subplot(axes_class=FloatingAxes, grid_helper=grid_helper) + + r_scale = 10 + tr2 = mtransforms.Affine2D().scale(1, 1 / r_scale) + tr + grid_helper2 = GridHelperCurveLinear( + tr2, + extremes=(0, 360, 10 * r_scale, 3 * r_scale), + grid_locator2=FixedLocator([30, 60, 90])) + + ax1.axis["right"] = axis = grid_helper2.new_fixed_axis("right", axes=ax1) + + ax1.axis["left"].label.set_text("Test 1") + ax1.axis["right"].label.set_text("Test 2") + ax1.axis["left", "right"].set_visible(False) + + axis = grid_helper.new_floating_axis(1, 7, axes=ax1, + axis_direction="bottom") + ax1.axis["z"] = axis + axis.toggle(all=True, label=True) + axis.label.set_text("z = ?") + axis.label.set_visible(True) + axis.line.set_color("0.5") + + ax2 = ax1.get_aux_axes(tr) + + xx, yy = [67, 90, 75, 30], [2, 5, 8, 4] + ax2.scatter(xx, yy) + l, = ax2.plot(xx, yy, "k-") + l.set_clip_path(ax1.patch) + + +# Rather high tolerance to allow ongoing work with floating axes internals; +# remove when image is regenerated. +@image_comparison(['curvelinear4.png'], style='default', tol=0.9) +def test_curvelinear4(): + # Remove this line when this test image is regenerated. + plt.rcParams['text.kerning_factor'] = 6 + + fig = plt.figure(figsize=(5, 5)) + + tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) + + mprojections.PolarAxes.PolarTransform()) + grid_helper = GridHelperCurveLinear( + tr, + extremes=(120, 30, 10, 0), + grid_locator1=angle_helper.LocatorDMS(5), + grid_locator2=FixedLocator([2, 4, 6, 8, 10]), + tick_formatter1=angle_helper.FormatterDMS(), + tick_formatter2=None) + ax1 = fig.add_subplot(axes_class=FloatingAxes, grid_helper=grid_helper) + ax1.clear() # Check that clear() also restores the correct limits on ax1. + + ax1.axis["left"].label.set_text("Test 1") + ax1.axis["right"].label.set_text("Test 2") + ax1.axis["top"].set_visible(False) + + axis = grid_helper.new_floating_axis(1, 70, axes=ax1, + axis_direction="bottom") + ax1.axis["z"] = axis + axis.toggle(all=True, label=True) + axis.label.set_axis_direction("top") + axis.label.set_text("z = ?") + axis.label.set_visible(True) + axis.line.set_color("0.5") + + ax2 = ax1.get_aux_axes(tr) + + xx, yy = [67, 90, 75, 30], [2, 5, 8, 4] + ax2.scatter(xx, yy) + l, = ax2.plot(xx, yy, "k-") + l.set_clip_path(ax1.patch) + + +def test_axis_direction(): + # Check that axis direction is propagated on a floating axis + fig = plt.figure() + ax = Subplot(fig, 111) + fig.add_subplot(ax) + ax.axis['y'] = ax.new_floating_axis(nth_coord=1, value=0, + axis_direction='left') + assert ax.axis['y']._axis_direction == 'left' diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_finder.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_finder.py new file mode 100644 index 00000000..6b397675 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_finder.py @@ -0,0 +1,34 @@ +import numpy as np +import pytest + +from matplotlib.transforms import Bbox +from mpl_toolkits.axisartist.grid_finder import ( + _find_line_box_crossings, FormatterPrettyPrint, MaxNLocator) + + +def test_find_line_box_crossings(): + x = np.array([-3, -2, -1, 0., 1, 2, 3, 2, 1, 0, -1, -2, -3, 5]) + y = np.arange(len(x)) + bbox = Bbox.from_extents(-2, 3, 2, 12.5) + left, right, bottom, top = _find_line_box_crossings( + np.column_stack([x, y]), bbox) + ((lx0, ly0), la0), ((lx1, ly1), la1), = left + ((rx0, ry0), ra0), ((rx1, ry1), ra1), = right + ((bx0, by0), ba0), = bottom + ((tx0, ty0), ta0), = top + assert (lx0, ly0, la0) == (-2, 11, 135) + assert (lx1, ly1, la1) == pytest.approx((-2., 12.125, 7.125016)) + assert (rx0, ry0, ra0) == (2, 5, 45) + assert (rx1, ry1, ra1) == (2, 7, 135) + assert (bx0, by0, ba0) == (0, 3, 45) + assert (tx0, ty0, ta0) == pytest.approx((1., 12.5, 7.125016)) + + +def test_pretty_print_format(): + locator = MaxNLocator() + locs, nloc, factor = locator(0, 100) + + fmt = FormatterPrettyPrint() + + assert fmt("left", None, locs) == \ + [r'$\mathdefault{%d}$' % (l, ) for l in locs] diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py new file mode 100644 index 00000000..037836af --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py @@ -0,0 +1,207 @@ +import numpy as np + +import matplotlib.pyplot as plt +from matplotlib.path import Path +from matplotlib.projections import PolarAxes +from matplotlib.transforms import Affine2D, Transform +from matplotlib.testing.decorators import image_comparison + +from mpl_toolkits.axisartist import SubplotHost +from mpl_toolkits.axes_grid1.parasite_axes import host_axes_class_factory +from mpl_toolkits.axisartist import angle_helper +from mpl_toolkits.axisartist.axislines import Axes +from mpl_toolkits.axisartist.grid_helper_curvelinear import \ + GridHelperCurveLinear + + +@image_comparison(['custom_transform.png'], style='default', tol=0.2) +def test_custom_transform(): + class MyTransform(Transform): + input_dims = output_dims = 2 + + def __init__(self, resolution): + """ + Resolution is the number of steps to interpolate between each input + line segment to approximate its path in transformed space. + """ + Transform.__init__(self) + self._resolution = resolution + + def transform(self, ll): + x, y = ll.T + return np.column_stack([x, y - x]) + + transform_non_affine = transform + + def transform_path(self, path): + ipath = path.interpolated(self._resolution) + return Path(self.transform(ipath.vertices), ipath.codes) + + transform_path_non_affine = transform_path + + def inverted(self): + return MyTransformInv(self._resolution) + + class MyTransformInv(Transform): + input_dims = output_dims = 2 + + def __init__(self, resolution): + Transform.__init__(self) + self._resolution = resolution + + def transform(self, ll): + x, y = ll.T + return np.column_stack([x, y + x]) + + def inverted(self): + return MyTransform(self._resolution) + + fig = plt.figure() + + SubplotHost = host_axes_class_factory(Axes) + + tr = MyTransform(1) + grid_helper = GridHelperCurveLinear(tr) + ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper) + fig.add_subplot(ax1) + + ax2 = ax1.get_aux_axes(tr, viewlim_mode="equal") + ax2.plot([3, 6], [5.0, 10.]) + + ax1.set_aspect(1.) + ax1.set_xlim(0, 10) + ax1.set_ylim(0, 10) + + ax1.grid(True) + + +# Remove tol & kerning_factor when this test image is regenerated. +@image_comparison(['polar_box.png'], style='default', tol=0.27) +def test_polar_box(): + plt.rcParams['text.kerning_factor'] = 6 + + fig = plt.figure(figsize=(5, 5)) + + # PolarAxes.PolarTransform takes radian. However, we want our coordinate + # system in degree + tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() + + # polar projection, which involves cycle, and also has limits in + # its coordinates, needs a special method to find the extremes + # (min, max of the coordinate within the view). + extreme_finder = angle_helper.ExtremeFinderCycle(20, 20, + lon_cycle=360, + lat_cycle=None, + lon_minmax=None, + lat_minmax=(0, np.inf)) + + grid_locator1 = angle_helper.LocatorDMS(12) + tick_formatter1 = angle_helper.FormatterDMS() + + grid_helper = GridHelperCurveLinear(tr, + extreme_finder=extreme_finder, + grid_locator1=grid_locator1, + tick_formatter1=tick_formatter1) + + ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper) + + ax1.axis["right"].major_ticklabels.set_visible(True) + ax1.axis["top"].major_ticklabels.set_visible(True) + + # let right axis shows ticklabels for 1st coordinate (angle) + ax1.axis["right"].get_helper().nth_coord_ticks = 0 + # let bottom axis shows ticklabels for 2nd coordinate (radius) + ax1.axis["bottom"].get_helper().nth_coord_ticks = 1 + + fig.add_subplot(ax1) + + ax1.axis["lat"] = axis = grid_helper.new_floating_axis(0, 45, axes=ax1) + axis.label.set_text("Test") + axis.label.set_visible(True) + axis.get_helper().set_extremes(2, 12) + + ax1.axis["lon"] = axis = grid_helper.new_floating_axis(1, 6, axes=ax1) + axis.label.set_text("Test 2") + axis.get_helper().set_extremes(-180, 90) + + # A parasite axes with given transform + ax2 = ax1.get_aux_axes(tr, viewlim_mode="equal") + assert ax2.transData == tr + ax1.transData + # Anything you draw in ax2 will match the ticks and grids of ax1. + ax2.plot(np.linspace(0, 30, 50), np.linspace(10, 10, 50)) + + ax1.set_aspect(1.) + ax1.set_xlim(-5, 12) + ax1.set_ylim(-5, 10) + + ax1.grid(True) + + +# Remove tol & kerning_factor when this test image is regenerated. +@image_comparison(['axis_direction.png'], style='default', tol=0.12) +def test_axis_direction(): + plt.rcParams['text.kerning_factor'] = 6 + + fig = plt.figure(figsize=(5, 5)) + + # PolarAxes.PolarTransform takes radian. However, we want our coordinate + # system in degree + tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() + + # polar projection, which involves cycle, and also has limits in + # its coordinates, needs a special method to find the extremes + # (min, max of the coordinate within the view). + + # 20, 20 : number of sampling points along x, y direction + extreme_finder = angle_helper.ExtremeFinderCycle(20, 20, + lon_cycle=360, + lat_cycle=None, + lon_minmax=None, + lat_minmax=(0, np.inf), + ) + + grid_locator1 = angle_helper.LocatorDMS(12) + tick_formatter1 = angle_helper.FormatterDMS() + + grid_helper = GridHelperCurveLinear(tr, + extreme_finder=extreme_finder, + grid_locator1=grid_locator1, + tick_formatter1=tick_formatter1) + + ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper) + + for axis in ax1.axis.values(): + axis.set_visible(False) + + fig.add_subplot(ax1) + + ax1.axis["lat1"] = axis = grid_helper.new_floating_axis( + 0, 130, + axes=ax1, axis_direction="left") + axis.label.set_text("Test") + axis.label.set_visible(True) + axis.get_helper().set_extremes(0.001, 10) + + ax1.axis["lat2"] = axis = grid_helper.new_floating_axis( + 0, 50, + axes=ax1, axis_direction="right") + axis.label.set_text("Test") + axis.label.set_visible(True) + axis.get_helper().set_extremes(0.001, 10) + + ax1.axis["lon"] = axis = grid_helper.new_floating_axis( + 1, 10, + axes=ax1, axis_direction="bottom") + axis.label.set_text("Test 2") + axis.get_helper().set_extremes(50, 130) + axis.major_ticklabels.set_axis_direction("top") + axis.label.set_axis_direction("top") + + grid_helper.grid_finder.grid_locator1.set_params(nbins=5) + grid_helper.grid_finder.grid_locator2.set_params(nbins=5) + + ax1.set_aspect(1.) + ax1.set_xlim(-8, 8) + ax1.set_ylim(-4, 12) + + ax1.grid(True) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/__init__.py new file mode 100644 index 00000000..a089fbd6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/__init__.py @@ -0,0 +1,3 @@ +from .axes3d import Axes3D + +__all__ = ['Axes3D'] diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/art3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/art3d.py new file mode 100644 index 00000000..4aff115b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/art3d.py @@ -0,0 +1,1252 @@ +# art3d.py, original mplot3d version by John Porter +# Parts rewritten by Reinier Heeres <reinier@heeres.eu> +# Minor additions by Ben Axelrod <baxelrod@coroware.com> + +""" +Module containing 3D artist code and functions to convert 2D +artists into 3D versions which can be added to an Axes3D. +""" + +import math + +import numpy as np + +from contextlib import contextmanager + +from matplotlib import ( + artist, cbook, colors as mcolors, lines, text as mtext, + path as mpath) +from matplotlib.collections import ( + Collection, LineCollection, PolyCollection, PatchCollection, PathCollection) +from matplotlib.colors import Normalize +from matplotlib.patches import Patch +from . import proj3d + + +def _norm_angle(a): + """Return the given angle normalized to -180 < *a* <= 180 degrees.""" + a = (a + 360) % 360 + if a > 180: + a = a - 360 + return a + + +def _norm_text_angle(a): + """Return the given angle normalized to -90 < *a* <= 90 degrees.""" + a = (a + 180) % 180 + if a > 90: + a = a - 180 + return a + + +def get_dir_vector(zdir): + """ + Return a direction vector. + + Parameters + ---------- + zdir : {'x', 'y', 'z', None, 3-tuple} + The direction. Possible values are: + + - 'x': equivalent to (1, 0, 0) + - 'y': equivalent to (0, 1, 0) + - 'z': equivalent to (0, 0, 1) + - *None*: equivalent to (0, 0, 0) + - an iterable (x, y, z) is converted to an array + + Returns + ------- + x, y, z : array + The direction vector. + """ + if zdir == 'x': + return np.array((1, 0, 0)) + elif zdir == 'y': + return np.array((0, 1, 0)) + elif zdir == 'z': + return np.array((0, 0, 1)) + elif zdir is None: + return np.array((0, 0, 0)) + elif np.iterable(zdir) and len(zdir) == 3: + return np.array(zdir) + else: + raise ValueError("'x', 'y', 'z', None or vector of length 3 expected") + + +class Text3D(mtext.Text): + """ + Text object with 3D position and direction. + + Parameters + ---------- + x, y, z : float + The position of the text. + text : str + The text string to display. + zdir : {'x', 'y', 'z', None, 3-tuple} + The direction of the text. See `.get_dir_vector` for a description of + the values. + + Other Parameters + ---------------- + **kwargs + All other parameters are passed on to `~matplotlib.text.Text`. + """ + + def __init__(self, x=0, y=0, z=0, text='', zdir='z', **kwargs): + mtext.Text.__init__(self, x, y, text, **kwargs) + self.set_3d_properties(z, zdir) + + def get_position_3d(self): + """Return the (x, y, z) position of the text.""" + return self._x, self._y, self._z + + def set_position_3d(self, xyz, zdir=None): + """ + Set the (*x*, *y*, *z*) position of the text. + + Parameters + ---------- + xyz : (float, float, float) + The position in 3D space. + zdir : {'x', 'y', 'z', None, 3-tuple} + The direction of the text. If unspecified, the *zdir* will not be + changed. See `.get_dir_vector` for a description of the values. + """ + super().set_position(xyz[:2]) + self.set_z(xyz[2]) + if zdir is not None: + self._dir_vec = get_dir_vector(zdir) + + def set_z(self, z): + """ + Set the *z* position of the text. + + Parameters + ---------- + z : float + """ + self._z = z + self.stale = True + + def set_3d_properties(self, z=0, zdir='z'): + """ + Set the *z* position and direction of the text. + + Parameters + ---------- + z : float + The z-position in 3D space. + zdir : {'x', 'y', 'z', 3-tuple} + The direction of the text. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + self._z = z + self._dir_vec = get_dir_vector(zdir) + self.stale = True + + @artist.allow_rasterization + def draw(self, renderer): + position3d = np.array((self._x, self._y, self._z)) + proj = proj3d._proj_trans_points( + [position3d, position3d + self._dir_vec], self.axes.M) + dx = proj[0][1] - proj[0][0] + dy = proj[1][1] - proj[1][0] + angle = math.degrees(math.atan2(dy, dx)) + with cbook._setattr_cm(self, _x=proj[0][0], _y=proj[1][0], + _rotation=_norm_text_angle(angle)): + mtext.Text.draw(self, renderer) + self.stale = False + + def get_tightbbox(self, renderer=None): + # Overwriting the 2d Text behavior which is not valid for 3d. + # For now, just return None to exclude from layout calculation. + return None + + +def text_2d_to_3d(obj, z=0, zdir='z'): + """ + Convert a `.Text` to a `.Text3D` object. + + Parameters + ---------- + z : float + The z-position in 3D space. + zdir : {'x', 'y', 'z', 3-tuple} + The direction of the text. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + obj.__class__ = Text3D + obj.set_3d_properties(z, zdir) + + +class Line3D(lines.Line2D): + """ + 3D line object. + + .. note:: Use `get_data_3d` to obtain the data associated with the line. + `~.Line2D.get_data`, `~.Line2D.get_xdata`, and `~.Line2D.get_ydata` return + the x- and y-coordinates of the projected 2D-line, not the x- and y-data of + the 3D-line. Similarly, use `set_data_3d` to set the data, not + `~.Line2D.set_data`, `~.Line2D.set_xdata`, and `~.Line2D.set_ydata`. + """ + + def __init__(self, xs, ys, zs, *args, **kwargs): + """ + + Parameters + ---------- + xs : array-like + The x-data to be plotted. + ys : array-like + The y-data to be plotted. + zs : array-like + The z-data to be plotted. + *args, **kwargs + Additional arguments are passed to `~matplotlib.lines.Line2D`. + """ + super().__init__([], [], *args, **kwargs) + self.set_data_3d(xs, ys, zs) + + def set_3d_properties(self, zs=0, zdir='z'): + """ + Set the *z* position and direction of the line. + + Parameters + ---------- + zs : float or array of floats + The location along the *zdir* axis in 3D space to position the + line. + zdir : {'x', 'y', 'z'} + Plane to plot line orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + xs = self.get_xdata() + ys = self.get_ydata() + zs = cbook._to_unmasked_float_array(zs).ravel() + zs = np.broadcast_to(zs, len(xs)) + self._verts3d = juggle_axes(xs, ys, zs, zdir) + self.stale = True + + def set_data_3d(self, *args): + """ + Set the x, y and z data + + Parameters + ---------- + x : array-like + The x-data to be plotted. + y : array-like + The y-data to be plotted. + z : array-like + The z-data to be plotted. + + Notes + ----- + Accepts x, y, z arguments or a single array-like (x, y, z) + """ + if len(args) == 1: + args = args[0] + for name, xyz in zip('xyz', args): + if not np.iterable(xyz): + raise RuntimeError(f'{name} must be a sequence') + self._verts3d = args + self.stale = True + + def get_data_3d(self): + """ + Get the current data + + Returns + ------- + verts3d : length-3 tuple or array-like + The current data as a tuple or array-like. + """ + return self._verts3d + + @artist.allow_rasterization + def draw(self, renderer): + xs3d, ys3d, zs3d = self._verts3d + xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M) + self.set_data(xs, ys) + super().draw(renderer) + self.stale = False + + +def line_2d_to_3d(line, zs=0, zdir='z'): + """ + Convert a `.Line2D` to a `.Line3D` object. + + Parameters + ---------- + zs : float + The location along the *zdir* axis in 3D space to position the line. + zdir : {'x', 'y', 'z'} + Plane to plot line orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + + line.__class__ = Line3D + line.set_3d_properties(zs, zdir) + + +def _path_to_3d_segment(path, zs=0, zdir='z'): + """Convert a path to a 3D segment.""" + + zs = np.broadcast_to(zs, len(path)) + pathsegs = path.iter_segments(simplify=False, curves=False) + seg = [(x, y, z) for (((x, y), code), z) in zip(pathsegs, zs)] + seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg] + return seg3d + + +def _paths_to_3d_segments(paths, zs=0, zdir='z'): + """Convert paths from a collection object to 3D segments.""" + + if not np.iterable(zs): + zs = np.broadcast_to(zs, len(paths)) + else: + if len(zs) != len(paths): + raise ValueError('Number of z-coordinates does not match paths.') + + segs = [_path_to_3d_segment(path, pathz, zdir) + for path, pathz in zip(paths, zs)] + return segs + + +def _path_to_3d_segment_with_codes(path, zs=0, zdir='z'): + """Convert a path to a 3D segment with path codes.""" + + zs = np.broadcast_to(zs, len(path)) + pathsegs = path.iter_segments(simplify=False, curves=False) + seg_codes = [((x, y, z), code) for ((x, y), code), z in zip(pathsegs, zs)] + if seg_codes: + seg, codes = zip(*seg_codes) + seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg] + else: + seg3d = [] + codes = [] + return seg3d, list(codes) + + +def _paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'): + """ + Convert paths from a collection object to 3D segments with path codes. + """ + + zs = np.broadcast_to(zs, len(paths)) + segments_codes = [_path_to_3d_segment_with_codes(path, pathz, zdir) + for path, pathz in zip(paths, zs)] + if segments_codes: + segments, codes = zip(*segments_codes) + else: + segments, codes = [], [] + return list(segments), list(codes) + + +class Collection3D(Collection): + """A collection of 3D paths.""" + + def do_3d_projection(self): + """Project the points according to renderer matrix.""" + xyzs_list = [proj3d.proj_transform(*vs.T, self.axes.M) + for vs, _ in self._3dverts_codes] + self._paths = [mpath.Path(np.column_stack([xs, ys]), cs) + for (xs, ys, _), (_, cs) in zip(xyzs_list, self._3dverts_codes)] + zs = np.concatenate([zs for _, _, zs in xyzs_list]) + return zs.min() if len(zs) else 1e9 + + +def collection_2d_to_3d(col, zs=0, zdir='z'): + """Convert a `.Collection` to a `.Collection3D` object.""" + zs = np.broadcast_to(zs, len(col.get_paths())) + col._3dverts_codes = [ + (np.column_stack(juggle_axes( + *np.column_stack([p.vertices, np.broadcast_to(z, len(p.vertices))]).T, + zdir)), + p.codes) + for p, z in zip(col.get_paths(), zs)] + col.__class__ = cbook._make_class_factory(Collection3D, "{}3D")(type(col)) + + +class Line3DCollection(LineCollection): + """ + A collection of 3D lines. + """ + + def set_sort_zpos(self, val): + """Set the position to use for z-sorting.""" + self._sort_zpos = val + self.stale = True + + def set_segments(self, segments): + """ + Set 3D segments. + """ + self._segments3d = segments + super().set_segments([]) + + def do_3d_projection(self): + """ + Project the points according to renderer matrix. + """ + xyslist = [proj3d._proj_trans_points(points, self.axes.M) + for points in self._segments3d] + segments_2d = [np.column_stack([xs, ys]) for xs, ys, zs in xyslist] + LineCollection.set_segments(self, segments_2d) + + # FIXME + minz = 1e9 + for xs, ys, zs in xyslist: + minz = min(minz, min(zs)) + return minz + + +def line_collection_2d_to_3d(col, zs=0, zdir='z'): + """Convert a `.LineCollection` to a `.Line3DCollection` object.""" + segments3d = _paths_to_3d_segments(col.get_paths(), zs, zdir) + col.__class__ = Line3DCollection + col.set_segments(segments3d) + + +class Patch3D(Patch): + """ + 3D patch object. + """ + + def __init__(self, *args, zs=(), zdir='z', **kwargs): + """ + Parameters + ---------- + verts : + zs : float + The location along the *zdir* axis in 3D space to position the + patch. + zdir : {'x', 'y', 'z'} + Plane to plot patch orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + super().__init__(*args, **kwargs) + self.set_3d_properties(zs, zdir) + + def set_3d_properties(self, verts, zs=0, zdir='z'): + """ + Set the *z* position and direction of the patch. + + Parameters + ---------- + verts : + zs : float + The location along the *zdir* axis in 3D space to position the + patch. + zdir : {'x', 'y', 'z'} + Plane to plot patch orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + zs = np.broadcast_to(zs, len(verts)) + self._segment3d = [juggle_axes(x, y, z, zdir) + for ((x, y), z) in zip(verts, zs)] + + def get_path(self): + return self._path2d + + def do_3d_projection(self): + s = self._segment3d + xs, ys, zs = zip(*s) + vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, + self.axes.M) + self._path2d = mpath.Path(np.column_stack([vxs, vys])) + return min(vzs) + + +class PathPatch3D(Patch3D): + """ + 3D PathPatch object. + """ + + def __init__(self, path, *, zs=(), zdir='z', **kwargs): + """ + Parameters + ---------- + path : + zs : float + The location along the *zdir* axis in 3D space to position the + path patch. + zdir : {'x', 'y', 'z', 3-tuple} + Plane to plot path patch orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + # Not super().__init__! + Patch.__init__(self, **kwargs) + self.set_3d_properties(path, zs, zdir) + + def set_3d_properties(self, path, zs=0, zdir='z'): + """ + Set the *z* position and direction of the path patch. + + Parameters + ---------- + path : + zs : float + The location along the *zdir* axis in 3D space to position the + path patch. + zdir : {'x', 'y', 'z', 3-tuple} + Plane to plot path patch orthogonal to. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + Patch3D.set_3d_properties(self, path.vertices, zs=zs, zdir=zdir) + self._code3d = path.codes + + def do_3d_projection(self): + s = self._segment3d + xs, ys, zs = zip(*s) + vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, + self.axes.M) + self._path2d = mpath.Path(np.column_stack([vxs, vys]), self._code3d) + return min(vzs) + + +def _get_patch_verts(patch): + """Return a list of vertices for the path of a patch.""" + trans = patch.get_patch_transform() + path = patch.get_path() + polygons = path.to_polygons(trans) + return polygons[0] if len(polygons) else np.array([]) + + +def patch_2d_to_3d(patch, z=0, zdir='z'): + """Convert a `.Patch` to a `.Patch3D` object.""" + verts = _get_patch_verts(patch) + patch.__class__ = Patch3D + patch.set_3d_properties(verts, z, zdir) + + +def pathpatch_2d_to_3d(pathpatch, z=0, zdir='z'): + """Convert a `.PathPatch` to a `.PathPatch3D` object.""" + path = pathpatch.get_path() + trans = pathpatch.get_patch_transform() + + mpath = trans.transform_path(path) + pathpatch.__class__ = PathPatch3D + pathpatch.set_3d_properties(mpath, z, zdir) + + +class Patch3DCollection(PatchCollection): + """ + A collection of 3D patches. + """ + + def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs): + """ + Create a collection of flat 3D patches with its normal vector + pointed in *zdir* direction, and located at *zs* on the *zdir* + axis. 'zs' can be a scalar or an array-like of the same length as + the number of patches in the collection. + + Constructor arguments are the same as for + :class:`~matplotlib.collections.PatchCollection`. In addition, + keywords *zs=0* and *zdir='z'* are available. + + Also, the keyword argument *depthshade* is available to indicate + whether to shade the patches in order to give the appearance of depth + (default is *True*). This is typically desired in scatter plots. + """ + self._depthshade = depthshade + super().__init__(*args, **kwargs) + self.set_3d_properties(zs, zdir) + + def get_depthshade(self): + return self._depthshade + + def set_depthshade(self, depthshade): + """ + Set whether depth shading is performed on collection members. + + Parameters + ---------- + depthshade : bool + Whether to shade the patches in order to give the appearance of + depth. + """ + self._depthshade = depthshade + self.stale = True + + def set_sort_zpos(self, val): + """Set the position to use for z-sorting.""" + self._sort_zpos = val + self.stale = True + + def set_3d_properties(self, zs, zdir): + """ + Set the *z* positions and direction of the patches. + + Parameters + ---------- + zs : float or array of floats + The location or locations to place the patches in the collection + along the *zdir* axis. + zdir : {'x', 'y', 'z'} + Plane to plot patches orthogonal to. + All patches must have the same direction. + See `.get_dir_vector` for a description of the values. + """ + # Force the collection to initialize the face and edgecolors + # just in case it is a scalarmappable with a colormap. + self.update_scalarmappable() + offsets = self.get_offsets() + if len(offsets) > 0: + xs, ys = offsets.T + else: + xs = [] + ys = [] + self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir) + self._z_markers_idx = slice(-1) + self._vzs = None + self.stale = True + + def do_3d_projection(self): + xs, ys, zs = self._offsets3d + vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, + self.axes.M) + self._vzs = vzs + super().set_offsets(np.column_stack([vxs, vys])) + + if vzs.size > 0: + return min(vzs) + else: + return np.nan + + def _maybe_depth_shade_and_sort_colors(self, color_array): + color_array = ( + _zalpha(color_array, self._vzs) + if self._vzs is not None and self._depthshade + else color_array + ) + if len(color_array) > 1: + color_array = color_array[self._z_markers_idx] + return mcolors.to_rgba_array(color_array, self._alpha) + + def get_facecolor(self): + return self._maybe_depth_shade_and_sort_colors(super().get_facecolor()) + + def get_edgecolor(self): + # We need this check here to make sure we do not double-apply the depth + # based alpha shading when the edge color is "face" which means the + # edge colour should be identical to the face colour. + if cbook._str_equal(self._edgecolors, 'face'): + return self.get_facecolor() + return self._maybe_depth_shade_and_sort_colors(super().get_edgecolor()) + + +class Path3DCollection(PathCollection): + """ + A collection of 3D paths. + """ + + def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs): + """ + Create a collection of flat 3D paths with its normal vector + pointed in *zdir* direction, and located at *zs* on the *zdir* + axis. 'zs' can be a scalar or an array-like of the same length as + the number of paths in the collection. + + Constructor arguments are the same as for + :class:`~matplotlib.collections.PathCollection`. In addition, + keywords *zs=0* and *zdir='z'* are available. + + Also, the keyword argument *depthshade* is available to indicate + whether to shade the patches in order to give the appearance of depth + (default is *True*). This is typically desired in scatter plots. + """ + self._depthshade = depthshade + self._in_draw = False + super().__init__(*args, **kwargs) + self.set_3d_properties(zs, zdir) + self._offset_zordered = None + + def draw(self, renderer): + with self._use_zordered_offset(): + with cbook._setattr_cm(self, _in_draw=True): + super().draw(renderer) + + def set_sort_zpos(self, val): + """Set the position to use for z-sorting.""" + self._sort_zpos = val + self.stale = True + + def set_3d_properties(self, zs, zdir): + """ + Set the *z* positions and direction of the paths. + + Parameters + ---------- + zs : float or array of floats + The location or locations to place the paths in the collection + along the *zdir* axis. + zdir : {'x', 'y', 'z'} + Plane to plot paths orthogonal to. + All paths must have the same direction. + See `.get_dir_vector` for a description of the values. + """ + # Force the collection to initialize the face and edgecolors + # just in case it is a scalarmappable with a colormap. + self.update_scalarmappable() + offsets = self.get_offsets() + if len(offsets) > 0: + xs, ys = offsets.T + else: + xs = [] + ys = [] + self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir) + # In the base draw methods we access the attributes directly which + # means we cannot resolve the shuffling in the getter methods like + # we do for the edge and face colors. + # + # This means we need to carry around a cache of the unsorted sizes and + # widths (postfixed with 3d) and in `do_3d_projection` set the + # depth-sorted version of that data into the private state used by the + # base collection class in its draw method. + # + # Grab the current sizes and linewidths to preserve them. + self._sizes3d = self._sizes + self._linewidths3d = np.array(self._linewidths) + xs, ys, zs = self._offsets3d + + # Sort the points based on z coordinates + # Performance optimization: Create a sorted index array and reorder + # points and point properties according to the index array + self._z_markers_idx = slice(-1) + self._vzs = None + self.stale = True + + def set_sizes(self, sizes, dpi=72.0): + super().set_sizes(sizes, dpi) + if not self._in_draw: + self._sizes3d = sizes + + def set_linewidth(self, lw): + super().set_linewidth(lw) + if not self._in_draw: + self._linewidths3d = np.array(self._linewidths) + + def get_depthshade(self): + return self._depthshade + + def set_depthshade(self, depthshade): + """ + Set whether depth shading is performed on collection members. + + Parameters + ---------- + depthshade : bool + Whether to shade the patches in order to give the appearance of + depth. + """ + self._depthshade = depthshade + self.stale = True + + def do_3d_projection(self): + xs, ys, zs = self._offsets3d + vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, + self.axes.M) + # Sort the points based on z coordinates + # Performance optimization: Create a sorted index array and reorder + # points and point properties according to the index array + z_markers_idx = self._z_markers_idx = np.argsort(vzs)[::-1] + self._vzs = vzs + + # we have to special case the sizes because of code in collections.py + # as the draw method does + # self.set_sizes(self._sizes, self.figure.dpi) + # so we cannot rely on doing the sorting on the way out via get_* + + if len(self._sizes3d) > 1: + self._sizes = self._sizes3d[z_markers_idx] + + if len(self._linewidths3d) > 1: + self._linewidths = self._linewidths3d[z_markers_idx] + + PathCollection.set_offsets(self, np.column_stack((vxs, vys))) + + # Re-order items + vzs = vzs[z_markers_idx] + vxs = vxs[z_markers_idx] + vys = vys[z_markers_idx] + + # Store ordered offset for drawing purpose + self._offset_zordered = np.column_stack((vxs, vys)) + + return np.min(vzs) if vzs.size else np.nan + + @contextmanager + def _use_zordered_offset(self): + if self._offset_zordered is None: + # Do nothing + yield + else: + # Swap offset with z-ordered offset + old_offset = self._offsets + super().set_offsets(self._offset_zordered) + try: + yield + finally: + self._offsets = old_offset + + def _maybe_depth_shade_and_sort_colors(self, color_array): + color_array = ( + _zalpha(color_array, self._vzs) + if self._vzs is not None and self._depthshade + else color_array + ) + if len(color_array) > 1: + color_array = color_array[self._z_markers_idx] + return mcolors.to_rgba_array(color_array, self._alpha) + + def get_facecolor(self): + return self._maybe_depth_shade_and_sort_colors(super().get_facecolor()) + + def get_edgecolor(self): + # We need this check here to make sure we do not double-apply the depth + # based alpha shading when the edge color is "face" which means the + # edge colour should be identical to the face colour. + if cbook._str_equal(self._edgecolors, 'face'): + return self.get_facecolor() + return self._maybe_depth_shade_and_sort_colors(super().get_edgecolor()) + + +def patch_collection_2d_to_3d(col, zs=0, zdir='z', depthshade=True): + """ + Convert a `.PatchCollection` into a `.Patch3DCollection` object + (or a `.PathCollection` into a `.Path3DCollection` object). + + Parameters + ---------- + zs : float or array of floats + The location or locations to place the patches in the collection along + the *zdir* axis. Default: 0. + zdir : {'x', 'y', 'z'} + The axis in which to place the patches. Default: "z". + See `.get_dir_vector` for a description of the values. + depthshade + Whether to shade the patches to give a sense of depth. Default: *True*. + + """ + if isinstance(col, PathCollection): + col.__class__ = Path3DCollection + col._offset_zordered = None + elif isinstance(col, PatchCollection): + col.__class__ = Patch3DCollection + col._depthshade = depthshade + col._in_draw = False + col.set_3d_properties(zs, zdir) + + +class Poly3DCollection(PolyCollection): + """ + A collection of 3D polygons. + + .. note:: + **Filling of 3D polygons** + + There is no simple definition of the enclosed surface of a 3D polygon + unless the polygon is planar. + + In practice, Matplotlib fills the 2D projection of the polygon. This + gives a correct filling appearance only for planar polygons. For all + other polygons, you'll find orientations in which the edges of the + polygon intersect in the projection. This will lead to an incorrect + visualization of the 3D area. + + If you need filled areas, it is recommended to create them via + `~mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf`, which creates a + triangulation and thus generates consistent surfaces. + """ + + def __init__(self, verts, *args, zsort='average', shade=False, + lightsource=None, **kwargs): + """ + Parameters + ---------- + verts : list of (N, 3) array-like + The sequence of polygons [*verts0*, *verts1*, ...] where each + element *verts_i* defines the vertices of polygon *i* as a 2D + array-like of shape (N, 3). + zsort : {'average', 'min', 'max'}, default: 'average' + The calculation method for the z-order. + See `~.Poly3DCollection.set_zsort` for details. + shade : bool, default: False + Whether to shade *facecolors* and *edgecolors*. When activating + *shade*, *facecolors* and/or *edgecolors* must be provided. + + .. versionadded:: 3.7 + + lightsource : `~matplotlib.colors.LightSource`, optional + The lightsource to use when *shade* is True. + + .. versionadded:: 3.7 + + *args, **kwargs + All other parameters are forwarded to `.PolyCollection`. + + Notes + ----- + Note that this class does a bit of magic with the _facecolors + and _edgecolors properties. + """ + if shade: + normals = _generate_normals(verts) + facecolors = kwargs.get('facecolors', None) + if facecolors is not None: + kwargs['facecolors'] = _shade_colors( + facecolors, normals, lightsource + ) + + edgecolors = kwargs.get('edgecolors', None) + if edgecolors is not None: + kwargs['edgecolors'] = _shade_colors( + edgecolors, normals, lightsource + ) + if facecolors is None and edgecolors is None: + raise ValueError( + "You must provide facecolors, edgecolors, or both for " + "shade to work.") + super().__init__(verts, *args, **kwargs) + if isinstance(verts, np.ndarray): + if verts.ndim != 3: + raise ValueError('verts must be a list of (N, 3) array-like') + else: + if any(len(np.shape(vert)) != 2 for vert in verts): + raise ValueError('verts must be a list of (N, 3) array-like') + self.set_zsort(zsort) + self._codes3d = None + + _zsort_functions = { + 'average': np.average, + 'min': np.min, + 'max': np.max, + } + + def set_zsort(self, zsort): + """ + Set the calculation method for the z-order. + + Parameters + ---------- + zsort : {'average', 'min', 'max'} + The function applied on the z-coordinates of the vertices in the + viewer's coordinate system, to determine the z-order. + """ + self._zsortfunc = self._zsort_functions[zsort] + self._sort_zpos = None + self.stale = True + + def get_vector(self, segments3d): + """Optimize points for projection.""" + if len(segments3d): + xs, ys, zs = np.vstack(segments3d).T + else: # vstack can't stack zero arrays. + xs, ys, zs = [], [], [] + ones = np.ones(len(xs)) + self._vec = np.array([xs, ys, zs, ones]) + + indices = [0, *np.cumsum([len(segment) for segment in segments3d])] + self._segslices = [*map(slice, indices[:-1], indices[1:])] + + def set_verts(self, verts, closed=True): + """ + Set 3D vertices. + + Parameters + ---------- + verts : list of (N, 3) array-like + The sequence of polygons [*verts0*, *verts1*, ...] where each + element *verts_i* defines the vertices of polygon *i* as a 2D + array-like of shape (N, 3). + closed : bool, default: True + Whether the polygon should be closed by adding a CLOSEPOLY + connection at the end. + """ + self.get_vector(verts) + # 2D verts will be updated at draw time + super().set_verts([], False) + self._closed = closed + + def set_verts_and_codes(self, verts, codes): + """Set 3D vertices with path codes.""" + # set vertices with closed=False to prevent PolyCollection from + # setting path codes + self.set_verts(verts, closed=False) + # and set our own codes instead. + self._codes3d = codes + + def set_3d_properties(self): + # Force the collection to initialize the face and edgecolors + # just in case it is a scalarmappable with a colormap. + self.update_scalarmappable() + self._sort_zpos = None + self.set_zsort('average') + self._facecolor3d = PolyCollection.get_facecolor(self) + self._edgecolor3d = PolyCollection.get_edgecolor(self) + self._alpha3d = PolyCollection.get_alpha(self) + self.stale = True + + def set_sort_zpos(self, val): + """Set the position to use for z-sorting.""" + self._sort_zpos = val + self.stale = True + + def do_3d_projection(self): + """ + Perform the 3D projection for this object. + """ + if self._A is not None: + # force update of color mapping because we re-order them + # below. If we do not do this here, the 2D draw will call + # this, but we will never port the color mapped values back + # to the 3D versions. + # + # We hold the 3D versions in a fixed order (the order the user + # passed in) and sort the 2D version by view depth. + self.update_scalarmappable() + if self._face_is_mapped: + self._facecolor3d = self._facecolors + if self._edge_is_mapped: + self._edgecolor3d = self._edgecolors + txs, tys, tzs = proj3d._proj_transform_vec(self._vec, self.axes.M) + xyzlist = [(txs[sl], tys[sl], tzs[sl]) for sl in self._segslices] + + # This extra fuss is to re-order face / edge colors + cface = self._facecolor3d + cedge = self._edgecolor3d + if len(cface) != len(xyzlist): + cface = cface.repeat(len(xyzlist), axis=0) + if len(cedge) != len(xyzlist): + if len(cedge) == 0: + cedge = cface + else: + cedge = cedge.repeat(len(xyzlist), axis=0) + + if xyzlist: + # sort by depth (furthest drawn first) + z_segments_2d = sorted( + ((self._zsortfunc(zs), np.column_stack([xs, ys]), fc, ec, idx) + for idx, ((xs, ys, zs), fc, ec) + in enumerate(zip(xyzlist, cface, cedge))), + key=lambda x: x[0], reverse=True) + + _, segments_2d, self._facecolors2d, self._edgecolors2d, idxs = \ + zip(*z_segments_2d) + else: + segments_2d = [] + self._facecolors2d = np.empty((0, 4)) + self._edgecolors2d = np.empty((0, 4)) + idxs = [] + + if self._codes3d is not None: + codes = [self._codes3d[idx] for idx in idxs] + PolyCollection.set_verts_and_codes(self, segments_2d, codes) + else: + PolyCollection.set_verts(self, segments_2d, self._closed) + + if len(self._edgecolor3d) != len(cface): + self._edgecolors2d = self._edgecolor3d + + # Return zorder value + if self._sort_zpos is not None: + zvec = np.array([[0], [0], [self._sort_zpos], [1]]) + ztrans = proj3d._proj_transform_vec(zvec, self.axes.M) + return ztrans[2][0] + elif tzs.size > 0: + # FIXME: Some results still don't look quite right. + # In particular, examine contourf3d_demo2.py + # with az = -54 and elev = -45. + return np.min(tzs) + else: + return np.nan + + def set_facecolor(self, colors): + # docstring inherited + super().set_facecolor(colors) + self._facecolor3d = PolyCollection.get_facecolor(self) + + def set_edgecolor(self, colors): + # docstring inherited + super().set_edgecolor(colors) + self._edgecolor3d = PolyCollection.get_edgecolor(self) + + def set_alpha(self, alpha): + # docstring inherited + artist.Artist.set_alpha(self, alpha) + try: + self._facecolor3d = mcolors.to_rgba_array( + self._facecolor3d, self._alpha) + except (AttributeError, TypeError, IndexError): + pass + try: + self._edgecolors = mcolors.to_rgba_array( + self._edgecolor3d, self._alpha) + except (AttributeError, TypeError, IndexError): + pass + self.stale = True + + def get_facecolor(self): + # docstring inherited + # self._facecolors2d is not initialized until do_3d_projection + if not hasattr(self, '_facecolors2d'): + self.axes.M = self.axes.get_proj() + self.do_3d_projection() + return np.asarray(self._facecolors2d) + + def get_edgecolor(self): + # docstring inherited + # self._edgecolors2d is not initialized until do_3d_projection + if not hasattr(self, '_edgecolors2d'): + self.axes.M = self.axes.get_proj() + self.do_3d_projection() + return np.asarray(self._edgecolors2d) + + +def poly_collection_2d_to_3d(col, zs=0, zdir='z'): + """ + Convert a `.PolyCollection` into a `.Poly3DCollection` object. + + Parameters + ---------- + zs : float or array of floats + The location or locations to place the polygons in the collection along + the *zdir* axis. Default: 0. + zdir : {'x', 'y', 'z'} + The axis in which to place the patches. Default: 'z'. + See `.get_dir_vector` for a description of the values. + """ + segments_3d, codes = _paths_to_3d_segments_with_codes( + col.get_paths(), zs, zdir) + col.__class__ = Poly3DCollection + col.set_verts_and_codes(segments_3d, codes) + col.set_3d_properties() + + +def juggle_axes(xs, ys, zs, zdir): + """ + Reorder coordinates so that 2D *xs*, *ys* can be plotted in the plane + orthogonal to *zdir*. *zdir* is normally 'x', 'y' or 'z'. However, if + *zdir* starts with a '-' it is interpreted as a compensation for + `rotate_axes`. + """ + if zdir == 'x': + return zs, xs, ys + elif zdir == 'y': + return xs, zs, ys + elif zdir[0] == '-': + return rotate_axes(xs, ys, zs, zdir) + else: + return xs, ys, zs + + +def rotate_axes(xs, ys, zs, zdir): + """ + Reorder coordinates so that the axes are rotated with *zdir* along + the original z axis. Prepending the axis with a '-' does the + inverse transform, so *zdir* can be 'x', '-x', 'y', '-y', 'z' or '-z'. + """ + if zdir in ('x', '-y'): + return ys, zs, xs + elif zdir in ('-x', 'y'): + return zs, xs, ys + else: + return xs, ys, zs + + +def _zalpha(colors, zs): + """Modify the alphas of the color list according to depth.""" + # FIXME: This only works well if the points for *zs* are well-spaced + # in all three dimensions. Otherwise, at certain orientations, + # the min and max zs are very close together. + # Should really normalize against the viewing depth. + if len(colors) == 0 or len(zs) == 0: + return np.zeros((0, 4)) + norm = Normalize(min(zs), max(zs)) + sats = 1 - norm(zs) * 0.7 + rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4)) + return np.column_stack([rgba[:, :3], rgba[:, 3] * sats]) + + +def _generate_normals(polygons): + """ + Compute the normals of a list of polygons, one normal per polygon. + + Normals point towards the viewer for a face with its vertices in + counterclockwise order, following the right hand rule. + + Uses three points equally spaced around the polygon. This method assumes + that the points are in a plane. Otherwise, more than one shade is required, + which is not supported. + + Parameters + ---------- + polygons : list of (M_i, 3) array-like, or (..., M, 3) array-like + A sequence of polygons to compute normals for, which can have + varying numbers of vertices. If the polygons all have the same + number of vertices and array is passed, then the operation will + be vectorized. + + Returns + ------- + normals : (..., 3) array + A normal vector estimated for the polygon. + """ + if isinstance(polygons, np.ndarray): + # optimization: polygons all have the same number of points, so can + # vectorize + n = polygons.shape[-2] + i1, i2, i3 = 0, n//3, 2*n//3 + v1 = polygons[..., i1, :] - polygons[..., i2, :] + v2 = polygons[..., i2, :] - polygons[..., i3, :] + else: + # The subtraction doesn't vectorize because polygons is jagged. + v1 = np.empty((len(polygons), 3)) + v2 = np.empty((len(polygons), 3)) + for poly_i, ps in enumerate(polygons): + n = len(ps) + i1, i2, i3 = 0, n//3, 2*n//3 + v1[poly_i, :] = ps[i1, :] - ps[i2, :] + v2[poly_i, :] = ps[i2, :] - ps[i3, :] + return np.cross(v1, v2) + + +def _shade_colors(color, normals, lightsource=None): + """ + Shade *color* using normal vectors given by *normals*, + assuming a *lightsource* (using default position if not given). + *color* can also be an array of the same length as *normals*. + """ + if lightsource is None: + # chosen for backwards-compatibility + lightsource = mcolors.LightSource(azdeg=225, altdeg=19.4712) + + with np.errstate(invalid="ignore"): + shade = ((normals / np.linalg.norm(normals, axis=1, keepdims=True)) + @ lightsource.direction) + mask = ~np.isnan(shade) + + if mask.any(): + # convert dot product to allowed shading fractions + in_norm = mcolors.Normalize(-1, 1) + out_norm = mcolors.Normalize(0.3, 1).inverse + + def norm(x): + return out_norm(in_norm(x)) + + shade[~mask] = 0 + + color = mcolors.to_rgba_array(color) + # shape of color should be (M, 4) (where M is number of faces) + # shape of shade should be (M,) + # colors should have final shape of (M, 4) + alpha = color[:, 3] + colors = norm(shade)[:, np.newaxis] * color + colors[:, 3] = alpha + else: + colors = np.asanyarray(color).copy() + + return colors diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axes3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axes3d.py new file mode 100644 index 00000000..a74c11f5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axes3d.py @@ -0,0 +1,3448 @@ +""" +axes3d.py, original mplot3d version by John Porter +Created: 23 Sep 2005 + +Parts fixed by Reinier Heeres <reinier@heeres.eu> +Minor additions by Ben Axelrod <baxelrod@coroware.com> +Significant updates and revisions by Ben Root <ben.v.root@gmail.com> + +Module containing Axes3D, an object which can plot 3D objects on a +2D matplotlib figure. +""" + +from collections import defaultdict +import functools +import itertools +import math +import textwrap + +import numpy as np + +import matplotlib as mpl +from matplotlib import _api, cbook, _docstring, _preprocess_data +import matplotlib.artist as martist +import matplotlib.axes as maxes +import matplotlib.collections as mcoll +import matplotlib.colors as mcolors +import matplotlib.image as mimage +import matplotlib.lines as mlines +import matplotlib.patches as mpatches +import matplotlib.container as mcontainer +import matplotlib.transforms as mtransforms +from matplotlib.axes import Axes +from matplotlib.axes._base import _axis_method_wrapper, _process_plot_format +from matplotlib.transforms import Bbox +from matplotlib.tri._triangulation import Triangulation + +from . import art3d +from . import proj3d +from . import axis3d + + +@_docstring.interpd +@_api.define_aliases({ + "xlim": ["xlim3d"], "ylim": ["ylim3d"], "zlim": ["zlim3d"]}) +class Axes3D(Axes): + """ + 3D Axes object. + + .. note:: + + As a user, you do not instantiate Axes directly, but use Axes creation + methods instead; e.g. from `.pyplot` or `.Figure`: + `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` or `.Figure.add_axes`. + """ + name = '3d' + + _axis_names = ("x", "y", "z") + Axes._shared_axes["z"] = cbook.Grouper() + Axes._shared_axes["view"] = cbook.Grouper() + + vvec = _api.deprecate_privatize_attribute("3.7") + eye = _api.deprecate_privatize_attribute("3.7") + sx = _api.deprecate_privatize_attribute("3.7") + sy = _api.deprecate_privatize_attribute("3.7") + + def __init__( + self, fig, rect=None, *args, + elev=30, azim=-60, roll=0, sharez=None, proj_type='persp', + box_aspect=None, computed_zorder=True, focal_length=None, + shareview=None, + **kwargs): + """ + Parameters + ---------- + fig : Figure + The parent figure. + rect : tuple (left, bottom, width, height), default: None. + The ``(left, bottom, width, height)`` axes position. + elev : float, default: 30 + The elevation angle in degrees rotates the camera above and below + the x-y plane, with a positive angle corresponding to a location + above the plane. + azim : float, default: -60 + The azimuthal angle in degrees rotates the camera about the z axis, + with a positive angle corresponding to a right-handed rotation. In + other words, a positive azimuth rotates the camera about the origin + from its location along the +x axis towards the +y axis. + roll : float, default: 0 + The roll angle in degrees rotates the camera about the viewing + axis. A positive angle spins the camera clockwise, causing the + scene to rotate counter-clockwise. + sharez : Axes3D, optional + Other Axes to share z-limits with. + proj_type : {'persp', 'ortho'} + The projection type, default 'persp'. + box_aspect : 3-tuple of floats, default: None + Changes the physical dimensions of the Axes3D, such that the ratio + of the axis lengths in display units is x:y:z. + If None, defaults to 4:4:3 + computed_zorder : bool, default: True + If True, the draw order is computed based on the average position + of the `.Artist`\\s along the view direction. + Set to False if you want to manually control the order in which + Artists are drawn on top of each other using their *zorder* + attribute. This can be used for fine-tuning if the automatic order + does not produce the desired result. Note however, that a manual + zorder will only be correct for a limited view angle. If the figure + is rotated by the user, it will look wrong from certain angles. + focal_length : float, default: None + For a projection type of 'persp', the focal length of the virtual + camera. Must be > 0. If None, defaults to 1. + For a projection type of 'ortho', must be set to either None + or infinity (numpy.inf). If None, defaults to infinity. + The focal length can be computed from a desired Field Of View via + the equation: focal_length = 1/tan(FOV/2) + shareview : Axes3D, optional + Other Axes to share view angles with. + + **kwargs + Other optional keyword arguments: + + %(Axes3D:kwdoc)s + """ + + if rect is None: + rect = [0.0, 0.0, 1.0, 1.0] + + self.initial_azim = azim + self.initial_elev = elev + self.initial_roll = roll + self.set_proj_type(proj_type, focal_length) + self.computed_zorder = computed_zorder + + self.xy_viewLim = Bbox.unit() + self.zz_viewLim = Bbox.unit() + self.xy_dataLim = Bbox.unit() + # z-limits are encoded in the x-component of the Bbox, y is un-used + self.zz_dataLim = Bbox.unit() + + # inhibit autoscale_view until the axes are defined + # they can't be defined until Axes.__init__ has been called + self.view_init(self.initial_elev, self.initial_azim, self.initial_roll) + + self._sharez = sharez + if sharez is not None: + self._shared_axes["z"].join(self, sharez) + self._adjustable = 'datalim' + + self._shareview = shareview + if shareview is not None: + self._shared_axes["view"].join(self, shareview) + + if kwargs.pop('auto_add_to_figure', False): + raise AttributeError( + 'auto_add_to_figure is no longer supported for Axes3D. ' + 'Use fig.add_axes(ax) instead.' + ) + + super().__init__( + fig, rect, frameon=True, box_aspect=box_aspect, *args, **kwargs + ) + # Disable drawing of axes by base class + super().set_axis_off() + # Enable drawing of axes by Axes3D class + self.set_axis_on() + self.M = None + self.invM = None + + # func used to format z -- fall back on major formatters + self.fmt_zdata = None + + self.mouse_init() + self.figure.canvas.callbacks._connect_picklable( + 'motion_notify_event', self._on_move) + self.figure.canvas.callbacks._connect_picklable( + 'button_press_event', self._button_press) + self.figure.canvas.callbacks._connect_picklable( + 'button_release_event', self._button_release) + self.set_top_view() + + self.patch.set_linewidth(0) + # Calculate the pseudo-data width and height + pseudo_bbox = self.transLimits.inverted().transform([(0, 0), (1, 1)]) + self._pseudo_w, self._pseudo_h = pseudo_bbox[1] - pseudo_bbox[0] + + # mplot3d currently manages its own spines and needs these turned off + # for bounding box calculations + self.spines[:].set_visible(False) + + def set_axis_off(self): + self._axis3don = False + self.stale = True + + def set_axis_on(self): + self._axis3don = True + self.stale = True + + def convert_zunits(self, z): + """ + For artists in an Axes, if the zaxis has units support, + convert *z* using zaxis unit type + """ + return self.zaxis.convert_units(z) + + def set_top_view(self): + # this happens to be the right view for the viewing coordinates + # moved up and to the left slightly to fit labels and axes + xdwl = 0.95 / self._dist + xdw = 0.9 / self._dist + ydwl = 0.95 / self._dist + ydw = 0.9 / self._dist + # Set the viewing pane. + self.viewLim.intervalx = (-xdwl, xdw) + self.viewLim.intervaly = (-ydwl, ydw) + self.stale = True + + def _init_axis(self): + """Init 3D axes; overrides creation of regular X/Y axes.""" + self.xaxis = axis3d.XAxis(self) + self.yaxis = axis3d.YAxis(self) + self.zaxis = axis3d.ZAxis(self) + + def get_zaxis(self): + """Return the ``ZAxis`` (`~.axis3d.Axis`) instance.""" + return self.zaxis + + get_zgridlines = _axis_method_wrapper("zaxis", "get_gridlines") + get_zticklines = _axis_method_wrapper("zaxis", "get_ticklines") + + @_api.deprecated("3.7") + def unit_cube(self, vals=None): + return self._unit_cube(vals) + + def _unit_cube(self, vals=None): + minx, maxx, miny, maxy, minz, maxz = vals or self.get_w_lims() + return [(minx, miny, minz), + (maxx, miny, minz), + (maxx, maxy, minz), + (minx, maxy, minz), + (minx, miny, maxz), + (maxx, miny, maxz), + (maxx, maxy, maxz), + (minx, maxy, maxz)] + + @_api.deprecated("3.7") + def tunit_cube(self, vals=None, M=None): + return self._tunit_cube(vals, M) + + def _tunit_cube(self, vals=None, M=None): + if M is None: + M = self.M + xyzs = self._unit_cube(vals) + tcube = proj3d._proj_points(xyzs, M) + return tcube + + @_api.deprecated("3.7") + def tunit_edges(self, vals=None, M=None): + return self._tunit_edges(vals, M) + + def _tunit_edges(self, vals=None, M=None): + tc = self._tunit_cube(vals, M) + edges = [(tc[0], tc[1]), + (tc[1], tc[2]), + (tc[2], tc[3]), + (tc[3], tc[0]), + + (tc[0], tc[4]), + (tc[1], tc[5]), + (tc[2], tc[6]), + (tc[3], tc[7]), + + (tc[4], tc[5]), + (tc[5], tc[6]), + (tc[6], tc[7]), + (tc[7], tc[4])] + return edges + + def set_aspect(self, aspect, adjustable=None, anchor=None, share=False): + """ + Set the aspect ratios. + + Parameters + ---------- + aspect : {'auto', 'equal', 'equalxy', 'equalxz', 'equalyz'} + Possible values: + + ========= ================================================== + value description + ========= ================================================== + 'auto' automatic; fill the position rectangle with data. + 'equal' adapt all the axes to have equal aspect ratios. + 'equalxy' adapt the x and y axes to have equal aspect ratios. + 'equalxz' adapt the x and z axes to have equal aspect ratios. + 'equalyz' adapt the y and z axes to have equal aspect ratios. + ========= ================================================== + + adjustable : None or {'box', 'datalim'}, optional + If not *None*, this defines which parameter will be adjusted to + meet the required aspect. See `.set_adjustable` for further + details. + + anchor : None or str or 2-tuple of float, optional + If not *None*, this defines where the Axes will be drawn if there + is extra space due to aspect constraints. The most common way to + specify the anchor are abbreviations of cardinal directions: + + ===== ===================== + value description + ===== ===================== + 'C' centered + 'SW' lower left corner + 'S' middle of bottom edge + 'SE' lower right corner + etc. + ===== ===================== + + See `~.Axes.set_anchor` for further details. + + share : bool, default: False + If ``True``, apply the settings to all shared Axes. + + See Also + -------- + mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect + """ + _api.check_in_list(('auto', 'equal', 'equalxy', 'equalyz', 'equalxz'), + aspect=aspect) + super().set_aspect( + aspect='auto', adjustable=adjustable, anchor=anchor, share=share) + self._aspect = aspect + + if aspect in ('equal', 'equalxy', 'equalxz', 'equalyz'): + ax_indices = self._equal_aspect_axis_indices(aspect) + + view_intervals = np.array([self.xaxis.get_view_interval(), + self.yaxis.get_view_interval(), + self.zaxis.get_view_interval()]) + ptp = np.ptp(view_intervals, axis=1) + if self._adjustable == 'datalim': + mean = np.mean(view_intervals, axis=1) + scale = max(ptp[ax_indices] / self._box_aspect[ax_indices]) + deltas = scale * self._box_aspect + + for i, set_lim in enumerate((self.set_xlim3d, + self.set_ylim3d, + self.set_zlim3d)): + if i in ax_indices: + set_lim(mean[i] - deltas[i]/2., mean[i] + deltas[i]/2.) + else: # 'box' + # Change the box aspect such that the ratio of the length of + # the unmodified axis to the length of the diagonal + # perpendicular to it remains unchanged. + box_aspect = np.array(self._box_aspect) + box_aspect[ax_indices] = ptp[ax_indices] + remaining_ax_indices = {0, 1, 2}.difference(ax_indices) + if remaining_ax_indices: + remaining = remaining_ax_indices.pop() + old_diag = np.linalg.norm(self._box_aspect[ax_indices]) + new_diag = np.linalg.norm(box_aspect[ax_indices]) + box_aspect[remaining] *= new_diag / old_diag + self.set_box_aspect(box_aspect) + + def _equal_aspect_axis_indices(self, aspect): + """ + Get the indices for which of the x, y, z axes are constrained to have + equal aspect ratios. + + Parameters + ---------- + aspect : {'auto', 'equal', 'equalxy', 'equalxz', 'equalyz'} + See descriptions in docstring for `.set_aspect()`. + """ + ax_indices = [] # aspect == 'auto' + if aspect == 'equal': + ax_indices = [0, 1, 2] + elif aspect == 'equalxy': + ax_indices = [0, 1] + elif aspect == 'equalxz': + ax_indices = [0, 2] + elif aspect == 'equalyz': + ax_indices = [1, 2] + return ax_indices + + def set_box_aspect(self, aspect, *, zoom=1): + """ + Set the Axes box aspect. + + The box aspect is the ratio of height to width in display + units for each face of the box when viewed perpendicular to + that face. This is not to be confused with the data aspect (see + `~.Axes3D.set_aspect`). The default ratios are 4:4:3 (x:y:z). + + To simulate having equal aspect in data space, set the box + aspect to match your data range in each dimension. + + *zoom* controls the overall size of the Axes3D in the figure. + + Parameters + ---------- + aspect : 3-tuple of floats or None + Changes the physical dimensions of the Axes3D, such that the ratio + of the axis lengths in display units is x:y:z. + If None, defaults to (4, 4, 3). + + zoom : float, default: 1 + Control overall size of the Axes3D in the figure. Must be > 0. + """ + if zoom <= 0: + raise ValueError(f'Argument zoom = {zoom} must be > 0') + + if aspect is None: + aspect = np.asarray((4, 4, 3), dtype=float) + else: + aspect = np.asarray(aspect, dtype=float) + _api.check_shape((3,), aspect=aspect) + # default scale tuned to match the mpl32 appearance. + aspect *= 1.8294640721620434 * zoom / np.linalg.norm(aspect) + + self._box_aspect = aspect + self.stale = True + + def apply_aspect(self, position=None): + if position is None: + position = self.get_position(original=True) + + # in the superclass, we would go through and actually deal with axis + # scales and box/datalim. Those are all irrelevant - all we need to do + # is make sure our coordinate system is square. + trans = self.get_figure().transSubfigure + bb = mtransforms.Bbox.unit().transformed(trans) + # this is the physical aspect of the panel (or figure): + fig_aspect = bb.height / bb.width + + box_aspect = 1 + pb = position.frozen() + pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect) + self._set_position(pb1.anchored(self.get_anchor(), pb), 'active') + + @martist.allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + self._unstale_viewLim() + + # draw the background patch + self.patch.draw(renderer) + self._frameon = False + + # first, set the aspect + # this is duplicated from `axes._base._AxesBase.draw` + # but must be called before any of the artist are drawn as + # it adjusts the view limits and the size of the bounding box + # of the Axes + locator = self.get_axes_locator() + self.apply_aspect(locator(self, renderer) if locator else None) + + # add the projection matrix to the renderer + self.M = self.get_proj() + self.invM = np.linalg.inv(self.M) + + collections_and_patches = ( + artist for artist in self._children + if isinstance(artist, (mcoll.Collection, mpatches.Patch)) + and artist.get_visible()) + if self.computed_zorder: + # Calculate projection of collections and patches and zorder + # them. Make sure they are drawn above the grids. + zorder_offset = max(axis.get_zorder() + for axis in self._axis_map.values()) + 1 + collection_zorder = patch_zorder = zorder_offset + + for artist in sorted(collections_and_patches, + key=lambda artist: artist.do_3d_projection(), + reverse=True): + if isinstance(artist, mcoll.Collection): + artist.zorder = collection_zorder + collection_zorder += 1 + elif isinstance(artist, mpatches.Patch): + artist.zorder = patch_zorder + patch_zorder += 1 + else: + for artist in collections_and_patches: + artist.do_3d_projection() + + if self._axis3don: + # Draw panes first + for axis in self._axis_map.values(): + axis.draw_pane(renderer) + # Then gridlines + for axis in self._axis_map.values(): + axis.draw_grid(renderer) + # Then axes, labels, text, and ticks + for axis in self._axis_map.values(): + axis.draw(renderer) + + # Then rest + super().draw(renderer) + + def get_axis_position(self): + vals = self.get_w_lims() + tc = self._tunit_cube(vals, self.M) + xhigh = tc[1][2] > tc[2][2] + yhigh = tc[3][2] > tc[2][2] + zhigh = tc[0][2] > tc[2][2] + return xhigh, yhigh, zhigh + + def update_datalim(self, xys, **kwargs): + """ + Not implemented in `~mpl_toolkits.mplot3d.axes3d.Axes3D`. + """ + pass + + get_autoscalez_on = _axis_method_wrapper("zaxis", "_get_autoscale_on") + set_autoscalez_on = _axis_method_wrapper("zaxis", "_set_autoscale_on") + + def set_zmargin(self, m): + """ + Set padding of Z data limits prior to autoscaling. + + *m* times the data interval will be added to each end of that interval + before it is used in autoscaling. If *m* is negative, this will clip + the data range instead of expanding it. + + For example, if your data is in the range [0, 2], a margin of 0.1 will + result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range + of [0.2, 1.8]. + + Parameters + ---------- + m : float greater than -0.5 + """ + if m <= -0.5: + raise ValueError("margin must be greater than -0.5") + self._zmargin = m + self._request_autoscale_view("z") + self.stale = True + + def margins(self, *margins, x=None, y=None, z=None, tight=True): + """ + Set or retrieve autoscaling margins. + + See `.Axes.margins` for full documentation. Because this function + applies to 3D Axes, it also takes a *z* argument, and returns + ``(xmargin, ymargin, zmargin)``. + """ + if margins and (x is not None or y is not None or z is not None): + raise TypeError('Cannot pass both positional and keyword ' + 'arguments for x, y, and/or z.') + elif len(margins) == 1: + x = y = z = margins[0] + elif len(margins) == 3: + x, y, z = margins + elif margins: + raise TypeError('Must pass a single positional argument for all ' + 'margins, or one for each margin (x, y, z).') + + if x is None and y is None and z is None: + if tight is not True: + _api.warn_external(f'ignoring tight={tight!r} in get mode') + return self._xmargin, self._ymargin, self._zmargin + + if x is not None: + self.set_xmargin(x) + if y is not None: + self.set_ymargin(y) + if z is not None: + self.set_zmargin(z) + + self.autoscale_view( + tight=tight, scalex=(x is not None), scaley=(y is not None), + scalez=(z is not None) + ) + + def autoscale(self, enable=True, axis='both', tight=None): + """ + Convenience method for simple axis view autoscaling. + + See `.Axes.autoscale` for full documentation. Because this function + applies to 3D Axes, *axis* can also be set to 'z', and setting *axis* + to 'both' autoscales all three axes. + """ + if enable is None: + scalex = True + scaley = True + scalez = True + else: + if axis in ['x', 'both']: + self.set_autoscalex_on(bool(enable)) + scalex = self.get_autoscalex_on() + else: + scalex = False + if axis in ['y', 'both']: + self.set_autoscaley_on(bool(enable)) + scaley = self.get_autoscaley_on() + else: + scaley = False + if axis in ['z', 'both']: + self.set_autoscalez_on(bool(enable)) + scalez = self.get_autoscalez_on() + else: + scalez = False + if scalex: + self._request_autoscale_view("x", tight=tight) + if scaley: + self._request_autoscale_view("y", tight=tight) + if scalez: + self._request_autoscale_view("z", tight=tight) + + def auto_scale_xyz(self, X, Y, Z=None, had_data=None): + # This updates the bounding boxes as to keep a record as to what the + # minimum sized rectangular volume holds the data. + if np.shape(X) == np.shape(Y): + self.xy_dataLim.update_from_data_xy( + np.column_stack([np.ravel(X), np.ravel(Y)]), not had_data) + else: + self.xy_dataLim.update_from_data_x(X, not had_data) + self.xy_dataLim.update_from_data_y(Y, not had_data) + if Z is not None: + self.zz_dataLim.update_from_data_x(Z, not had_data) + # Let autoscale_view figure out how to use this data. + self.autoscale_view() + + def autoscale_view(self, tight=None, scalex=True, scaley=True, + scalez=True): + """ + Autoscale the view limits using the data limits. + + See `.Axes.autoscale_view` for full documentation. Because this + function applies to 3D Axes, it also takes a *scalez* argument. + """ + # This method looks at the rectangular volume (see above) + # of data and decides how to scale the view portal to fit it. + if tight is None: + _tight = self._tight + if not _tight: + # if image data only just use the datalim + for artist in self._children: + if isinstance(artist, mimage.AxesImage): + _tight = True + elif isinstance(artist, (mlines.Line2D, mpatches.Patch)): + _tight = False + break + else: + _tight = self._tight = bool(tight) + + if scalex and self.get_autoscalex_on(): + x0, x1 = self.xy_dataLim.intervalx + xlocator = self.xaxis.get_major_locator() + x0, x1 = xlocator.nonsingular(x0, x1) + if self._xmargin > 0: + delta = (x1 - x0) * self._xmargin + x0 -= delta + x1 += delta + if not _tight: + x0, x1 = xlocator.view_limits(x0, x1) + self.set_xbound(x0, x1) + + if scaley and self.get_autoscaley_on(): + y0, y1 = self.xy_dataLim.intervaly + ylocator = self.yaxis.get_major_locator() + y0, y1 = ylocator.nonsingular(y0, y1) + if self._ymargin > 0: + delta = (y1 - y0) * self._ymargin + y0 -= delta + y1 += delta + if not _tight: + y0, y1 = ylocator.view_limits(y0, y1) + self.set_ybound(y0, y1) + + if scalez and self.get_autoscalez_on(): + z0, z1 = self.zz_dataLim.intervalx + zlocator = self.zaxis.get_major_locator() + z0, z1 = zlocator.nonsingular(z0, z1) + if self._zmargin > 0: + delta = (z1 - z0) * self._zmargin + z0 -= delta + z1 += delta + if not _tight: + z0, z1 = zlocator.view_limits(z0, z1) + self.set_zbound(z0, z1) + + def get_w_lims(self): + """Get 3D world limits.""" + minx, maxx = self.get_xlim3d() + miny, maxy = self.get_ylim3d() + minz, maxz = self.get_zlim3d() + return minx, maxx, miny, maxy, minz, maxz + + # set_xlim, set_ylim are directly inherited from base Axes. + def set_zlim(self, bottom=None, top=None, *, emit=True, auto=False, + zmin=None, zmax=None): + """ + Set 3D z limits. + + See `.Axes.set_ylim` for full documentation + """ + if top is None and np.iterable(bottom): + bottom, top = bottom + if zmin is not None: + if bottom is not None: + raise TypeError("Cannot pass both 'bottom' and 'zmin'") + bottom = zmin + if zmax is not None: + if top is not None: + raise TypeError("Cannot pass both 'top' and 'zmax'") + top = zmax + return self.zaxis._set_lim(bottom, top, emit=emit, auto=auto) + + set_xlim3d = maxes.Axes.set_xlim + set_ylim3d = maxes.Axes.set_ylim + set_zlim3d = set_zlim + + def get_xlim(self): + # docstring inherited + return tuple(self.xy_viewLim.intervalx) + + def get_ylim(self): + # docstring inherited + return tuple(self.xy_viewLim.intervaly) + + def get_zlim(self): + """ + Return the 3D z-axis view limits. + + Returns + ------- + left, right : (float, float) + The current z-axis limits in data coordinates. + + See Also + -------- + set_zlim + set_zbound, get_zbound + invert_zaxis, zaxis_inverted + + Notes + ----- + The z-axis may be inverted, in which case the *left* value will + be greater than the *right* value. + """ + return tuple(self.zz_viewLim.intervalx) + + get_zscale = _axis_method_wrapper("zaxis", "get_scale") + + # Redefine all three methods to overwrite their docstrings. + set_xscale = _axis_method_wrapper("xaxis", "_set_axes_scale") + set_yscale = _axis_method_wrapper("yaxis", "_set_axes_scale") + set_zscale = _axis_method_wrapper("zaxis", "_set_axes_scale") + set_xscale.__doc__, set_yscale.__doc__, set_zscale.__doc__ = map( + """ + Set the {}-axis scale. + + Parameters + ---------- + value : {{"linear"}} + The axis scale type to apply. 3D axes currently only support + linear scales; other scales yield nonsensical results. + + **kwargs + Keyword arguments are nominally forwarded to the scale class, but + none of them is applicable for linear scales. + """.format, + ["x", "y", "z"]) + + get_zticks = _axis_method_wrapper("zaxis", "get_ticklocs") + set_zticks = _axis_method_wrapper("zaxis", "set_ticks") + get_zmajorticklabels = _axis_method_wrapper("zaxis", "get_majorticklabels") + get_zminorticklabels = _axis_method_wrapper("zaxis", "get_minorticklabels") + get_zticklabels = _axis_method_wrapper("zaxis", "get_ticklabels") + set_zticklabels = _axis_method_wrapper( + "zaxis", "set_ticklabels", + doc_sub={"Axis.set_ticks": "Axes3D.set_zticks"}) + + zaxis_date = _axis_method_wrapper("zaxis", "axis_date") + if zaxis_date.__doc__: + zaxis_date.__doc__ += textwrap.dedent(""" + + Notes + ----- + This function is merely provided for completeness, but 3D axes do not + support dates for ticks, and so this may not work as expected. + """) + + def clabel(self, *args, **kwargs): + """Currently not implemented for 3D axes, and returns *None*.""" + return None + + def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z", + share=False): + """ + Set the elevation and azimuth of the axes in degrees (not radians). + + This can be used to rotate the axes programmatically. + + To look normal to the primary planes, the following elevation and + azimuth angles can be used. A roll angle of 0, 90, 180, or 270 deg + will rotate these views while keeping the axes at right angles. + + ========== ==== ==== + view plane elev azim + ========== ==== ==== + XY 90 -90 + XZ 0 -90 + YZ 0 0 + -XY -90 90 + -XZ 0 90 + -YZ 0 180 + ========== ==== ==== + + Parameters + ---------- + elev : float, default: None + The elevation angle in degrees rotates the camera above the plane + pierced by the vertical axis, with a positive angle corresponding + to a location above that plane. For example, with the default + vertical axis of 'z', the elevation defines the angle of the camera + location above the x-y plane. + If None, then the initial value as specified in the `Axes3D` + constructor is used. + azim : float, default: None + The azimuthal angle in degrees rotates the camera about the + vertical axis, with a positive angle corresponding to a + right-handed rotation. For example, with the default vertical axis + of 'z', a positive azimuth rotates the camera about the origin from + its location along the +x axis towards the +y axis. + If None, then the initial value as specified in the `Axes3D` + constructor is used. + roll : float, default: None + The roll angle in degrees rotates the camera about the viewing + axis. A positive angle spins the camera clockwise, causing the + scene to rotate counter-clockwise. + If None, then the initial value as specified in the `Axes3D` + constructor is used. + vertical_axis : {"z", "x", "y"}, default: "z" + The axis to align vertically. *azim* rotates about this axis. + share : bool, default: False + If ``True``, apply the settings to all Axes with shared views. + """ + + self._dist = 10 # The camera distance from origin. Behaves like zoom + + if elev is None: + elev = self.initial_elev + if azim is None: + azim = self.initial_azim + if roll is None: + roll = self.initial_roll + vertical_axis = _api.check_getitem( + dict(x=0, y=1, z=2), vertical_axis=vertical_axis + ) + + if share: + axes = {sibling for sibling + in self._shared_axes['view'].get_siblings(self)} + else: + axes = [self] + + for ax in axes: + ax.elev = elev + ax.azim = azim + ax.roll = roll + ax._vertical_axis = vertical_axis + + def set_proj_type(self, proj_type, focal_length=None): + """ + Set the projection type. + + Parameters + ---------- + proj_type : {'persp', 'ortho'} + The projection type. + focal_length : float, default: None + For a projection type of 'persp', the focal length of the virtual + camera. Must be > 0. If None, defaults to 1. + The focal length can be computed from a desired Field Of View via + the equation: focal_length = 1/tan(FOV/2) + """ + _api.check_in_list(['persp', 'ortho'], proj_type=proj_type) + if proj_type == 'persp': + if focal_length is None: + focal_length = 1 + elif focal_length <= 0: + raise ValueError(f"focal_length = {focal_length} must be " + "greater than 0") + self._focal_length = focal_length + else: # 'ortho': + if focal_length not in (None, np.inf): + raise ValueError(f"focal_length = {focal_length} must be " + f"None for proj_type = {proj_type}") + self._focal_length = np.inf + + def _roll_to_vertical(self, arr): + """Roll arrays to match the different vertical axis.""" + return np.roll(arr, self._vertical_axis - 2) + + def get_proj(self): + """Create the projection matrix from the current viewing position.""" + + # Transform to uniform world coordinates 0-1, 0-1, 0-1 + box_aspect = self._roll_to_vertical(self._box_aspect) + worldM = proj3d.world_transformation( + *self.get_xlim3d(), + *self.get_ylim3d(), + *self.get_zlim3d(), + pb_aspect=box_aspect, + ) + + # Look into the middle of the world coordinates: + R = 0.5 * box_aspect + + # elev: elevation angle in the z plane. + # azim: azimuth angle in the xy plane. + # Coordinates for a point that rotates around the box of data. + # p0, p1 corresponds to rotating the box only around the vertical axis. + # p2 corresponds to rotating the box only around the horizontal axis. + elev_rad = np.deg2rad(self.elev) + azim_rad = np.deg2rad(self.azim) + p0 = np.cos(elev_rad) * np.cos(azim_rad) + p1 = np.cos(elev_rad) * np.sin(azim_rad) + p2 = np.sin(elev_rad) + + # When changing vertical axis the coordinates changes as well. + # Roll the values to get the same behaviour as the default: + ps = self._roll_to_vertical([p0, p1, p2]) + + # The coordinates for the eye viewing point. The eye is looking + # towards the middle of the box of data from a distance: + eye = R + self._dist * ps + + # vvec, self._vvec and self._eye are unused, remove when deprecated + vvec = R - eye + self._eye = eye + self._vvec = vvec / np.linalg.norm(vvec) + + # Calculate the viewing axes for the eye position + u, v, w = self._calc_view_axes(eye) + self._view_u = u # _view_u is towards the right of the screen + self._view_v = v # _view_v is towards the top of the screen + self._view_w = w # _view_w is out of the screen + + # Generate the view and projection transformation matrices + if self._focal_length == np.inf: + # Orthographic projection + viewM = proj3d._view_transformation_uvw(u, v, w, eye) + projM = proj3d._ortho_transformation(-self._dist, self._dist) + else: + # Perspective projection + # Scale the eye dist to compensate for the focal length zoom effect + eye_focal = R + self._dist * ps * self._focal_length + viewM = proj3d._view_transformation_uvw(u, v, w, eye_focal) + projM = proj3d._persp_transformation(-self._dist, + self._dist, + self._focal_length) + + # Combine all the transformation matrices to get the final projection + M0 = np.dot(viewM, worldM) + M = np.dot(projM, M0) + return M + + def mouse_init(self, rotate_btn=1, pan_btn=2, zoom_btn=3): + """ + Set the mouse buttons for 3D rotation and zooming. + + Parameters + ---------- + rotate_btn : int or list of int, default: 1 + The mouse button or buttons to use for 3D rotation of the axes. + pan_btn : int or list of int, default: 2 + The mouse button or buttons to use to pan the 3D axes. + zoom_btn : int or list of int, default: 3 + The mouse button or buttons to use to zoom the 3D axes. + """ + self.button_pressed = None + # coerce scalars into array-like, then convert into + # a regular list to avoid comparisons against None + # which breaks in recent versions of numpy. + self._rotate_btn = np.atleast_1d(rotate_btn).tolist() + self._pan_btn = np.atleast_1d(pan_btn).tolist() + self._zoom_btn = np.atleast_1d(zoom_btn).tolist() + + def disable_mouse_rotation(self): + """Disable mouse buttons for 3D rotation, panning, and zooming.""" + self.mouse_init(rotate_btn=[], pan_btn=[], zoom_btn=[]) + + def can_zoom(self): + # doc-string inherited + return True + + def can_pan(self): + # doc-string inherited + return True + + def sharez(self, other): + """ + Share the z-axis with *other*. + + This is equivalent to passing ``sharez=other`` when constructing the + Axes, and cannot be used if the z-axis is already being shared with + another Axes. + """ + _api.check_isinstance(Axes3D, other=other) + if self._sharez is not None and other is not self._sharez: + raise ValueError("z-axis is already shared") + self._shared_axes["z"].join(self, other) + self._sharez = other + self.zaxis.major = other.zaxis.major # Ticker instances holding + self.zaxis.minor = other.zaxis.minor # locator and formatter. + z0, z1 = other.get_zlim() + self.set_zlim(z0, z1, emit=False, auto=other.get_autoscalez_on()) + self.zaxis._scale = other.zaxis._scale + + def shareview(self, other): + """ + Share the view angles with *other*. + + This is equivalent to passing ``shareview=other`` when + constructing the Axes, and cannot be used if the view angles are + already being shared with another Axes. + """ + _api.check_isinstance(Axes3D, other=other) + if self._shareview is not None and other is not self._shareview: + raise ValueError("view angles are already shared") + self._shared_axes["view"].join(self, other) + self._shareview = other + vertical_axis = {0: "x", 1: "y", 2: "z"}[other._vertical_axis] + self.view_init(elev=other.elev, azim=other.azim, roll=other.roll, + vertical_axis=vertical_axis, share=True) + + def clear(self): + # docstring inherited. + super().clear() + if self._focal_length == np.inf: + self._zmargin = mpl.rcParams['axes.zmargin'] + else: + self._zmargin = 0. + self.grid(mpl.rcParams['axes3d.grid']) + + def _button_press(self, event): + if event.inaxes == self: + self.button_pressed = event.button + self._sx, self._sy = event.xdata, event.ydata + toolbar = self.figure.canvas.toolbar + if toolbar and toolbar._nav_stack() is None: + toolbar.push_current() + + def _button_release(self, event): + self.button_pressed = None + toolbar = self.figure.canvas.toolbar + # backend_bases.release_zoom and backend_bases.release_pan call + # push_current, so check the navigation mode so we don't call it twice + if toolbar and self.get_navigate_mode() is None: + toolbar.push_current() + + def _get_view(self): + # docstring inherited + return { + "xlim": self.get_xlim(), "autoscalex_on": self.get_autoscalex_on(), + "ylim": self.get_ylim(), "autoscaley_on": self.get_autoscaley_on(), + "zlim": self.get_zlim(), "autoscalez_on": self.get_autoscalez_on(), + }, (self.elev, self.azim, self.roll) + + def _set_view(self, view): + # docstring inherited + props, (elev, azim, roll) = view + self.set(**props) + self.elev = elev + self.azim = azim + self.roll = roll + + def format_zdata(self, z): + """ + Return *z* string formatted. This function will use the + :attr:`fmt_zdata` attribute if it is callable, else will fall + back on the zaxis major formatter + """ + try: + return self.fmt_zdata(z) + except (AttributeError, TypeError): + func = self.zaxis.get_major_formatter().format_data_short + val = func(z) + return val + + def format_coord(self, xv, yv, renderer=None): + """ + Return a string giving the current view rotation angles, or the x, y, z + coordinates of the point on the nearest axis pane underneath the mouse + cursor, depending on the mouse button pressed. + """ + coords = '' + + if self.button_pressed in self._rotate_btn: + # ignore xv and yv and display angles instead + coords = self._rotation_coords() + + elif self.M is not None: + coords = self._location_coords(xv, yv, renderer) + + return coords + + def _rotation_coords(self): + """ + Return the rotation angles as a string. + """ + norm_elev = art3d._norm_angle(self.elev) + norm_azim = art3d._norm_angle(self.azim) + norm_roll = art3d._norm_angle(self.roll) + coords = (f"elevation={norm_elev:.0f}\N{DEGREE SIGN}, " + f"azimuth={norm_azim:.0f}\N{DEGREE SIGN}, " + f"roll={norm_roll:.0f}\N{DEGREE SIGN}" + ).replace("-", "\N{MINUS SIGN}") + return coords + + def _location_coords(self, xv, yv, renderer): + """ + Return the location on the axis pane underneath the cursor as a string. + """ + p1, pane_idx = self._calc_coord(xv, yv, renderer) + xs = self.format_xdata(p1[0]) + ys = self.format_ydata(p1[1]) + zs = self.format_zdata(p1[2]) + if pane_idx == 0: + coords = f'x pane={xs}, y={ys}, z={zs}' + elif pane_idx == 1: + coords = f'x={xs}, y pane={ys}, z={zs}' + elif pane_idx == 2: + coords = f'x={xs}, y={ys}, z pane={zs}' + return coords + + def _get_camera_loc(self): + """ + Returns the current camera location in data coordinates. + """ + cx, cy, cz, dx, dy, dz = self._get_w_centers_ranges() + c = np.array([cx, cy, cz]) + r = np.array([dx, dy, dz]) + + if self._focal_length == np.inf: # orthographic projection + focal_length = 1e9 # large enough to be effectively infinite + else: # perspective projection + focal_length = self._focal_length + eye = c + self._view_w * self._dist * r / self._box_aspect * focal_length + return eye + + def _calc_coord(self, xv, yv, renderer=None): + """ + Given the 2D view coordinates, find the point on the nearest axis pane + that lies directly below those coordinates. Returns a 3D point in data + coordinates. + """ + if self._focal_length == np.inf: # orthographic projection + zv = 1 + else: # perspective projection + zv = -1 / self._focal_length + + # Convert point on view plane to data coordinates + p1 = np.array(proj3d.inv_transform(xv, yv, zv, self.invM)).ravel() + + # Get the vector from the camera to the point on the view plane + vec = self._get_camera_loc() - p1 + + # Get the pane locations for each of the axes + pane_locs = [] + for axis in self._axis_map.values(): + xys, loc = axis.active_pane(renderer) + pane_locs.append(loc) + + # Find the distance to the nearest pane by projecting the view vector + scales = np.zeros(3) + for i in range(3): + if vec[i] == 0: + scales[i] = np.inf + else: + scales[i] = (p1[i] - pane_locs[i]) / vec[i] + pane_idx = np.argmin(abs(scales)) + scale = scales[pane_idx] + + # Calculate the point on the closest pane + p2 = p1 - scale*vec + return p2, pane_idx + + def _on_move(self, event): + """ + Mouse moving. + + By default, button-1 rotates, button-2 pans, and button-3 zooms; + these buttons can be modified via `mouse_init`. + """ + + if not self.button_pressed: + return + + if self.get_navigate_mode() is not None: + # we don't want to rotate if we are zooming/panning + # from the toolbar + return + + if self.M is None: + return + + x, y = event.xdata, event.ydata + # In case the mouse is out of bounds. + if x is None or event.inaxes != self: + return + + dx, dy = x - self._sx, y - self._sy + w = self._pseudo_w + h = self._pseudo_h + + # Rotation + if self.button_pressed in self._rotate_btn: + # rotate viewing point + # get the x and y pixel coords + if dx == 0 and dy == 0: + return + + roll = np.deg2rad(self.roll) + delev = -(dy/h)*180*np.cos(roll) + (dx/w)*180*np.sin(roll) + dazim = -(dy/h)*180*np.sin(roll) - (dx/w)*180*np.cos(roll) + elev = self.elev + delev + azim = self.azim + dazim + self.view_init(elev=elev, azim=azim, roll=roll, share=True) + self.stale = True + + # Pan + elif self.button_pressed in self._pan_btn: + # Start the pan event with pixel coordinates + px, py = self.transData.transform([self._sx, self._sy]) + self.start_pan(px, py, 2) + # pan view (takes pixel coordinate input) + self.drag_pan(2, None, event.x, event.y) + self.end_pan() + + # Zoom + elif self.button_pressed in self._zoom_btn: + # zoom view (dragging down zooms in) + scale = h/(h - dy) + self._scale_axis_limits(scale, scale, scale) + + # Store the event coordinates for the next time through. + self._sx, self._sy = x, y + # Always request a draw update at the end of interaction + self.figure.canvas.draw_idle() + + def drag_pan(self, button, key, x, y): + # docstring inherited + + # Get the coordinates from the move event + p = self._pan_start + (xdata, ydata), (xdata_start, ydata_start) = p.trans_inverse.transform( + [(x, y), (p.x, p.y)]) + self._sx, self._sy = xdata, ydata + # Calling start_pan() to set the x/y of this event as the starting + # move location for the next event + self.start_pan(x, y, button) + du, dv = xdata - xdata_start, ydata - ydata_start + dw = 0 + if key == 'x': + dv = 0 + elif key == 'y': + du = 0 + if du == 0 and dv == 0: + return + + # Transform the pan from the view axes to the data axes + R = np.array([self._view_u, self._view_v, self._view_w]) + R = -R / self._box_aspect * self._dist + duvw_projected = R.T @ np.array([du, dv, dw]) + + # Calculate pan distance + minx, maxx, miny, maxy, minz, maxz = self.get_w_lims() + dx = (maxx - minx) * duvw_projected[0] + dy = (maxy - miny) * duvw_projected[1] + dz = (maxz - minz) * duvw_projected[2] + + # Set the new axis limits + self.set_xlim3d(minx + dx, maxx + dx) + self.set_ylim3d(miny + dy, maxy + dy) + self.set_zlim3d(minz + dz, maxz + dz) + + def _calc_view_axes(self, eye): + """ + Get the unit vectors for the viewing axes in data coordinates. + `u` is towards the right of the screen + `v` is towards the top of the screen + `w` is out of the screen + """ + elev_rad = np.deg2rad(art3d._norm_angle(self.elev)) + roll_rad = np.deg2rad(art3d._norm_angle(self.roll)) + + # Look into the middle of the world coordinates + R = 0.5 * self._roll_to_vertical(self._box_aspect) + + # Define which axis should be vertical. A negative value + # indicates the plot is upside down and therefore the values + # have been reversed: + V = np.zeros(3) + V[self._vertical_axis] = -1 if abs(elev_rad) > np.pi/2 else 1 + + u, v, w = proj3d._view_axes(eye, R, V, roll_rad) + return u, v, w + + def _set_view_from_bbox(self, bbox, direction='in', + mode=None, twinx=False, twiny=False): + """ + Zoom in or out of the bounding box. + + Will center the view in the center of the bounding box, and zoom by + the ratio of the size of the bounding box to the size of the Axes3D. + """ + (start_x, start_y, stop_x, stop_y) = bbox + if mode == 'x': + start_y = self.bbox.min[1] + stop_y = self.bbox.max[1] + elif mode == 'y': + start_x = self.bbox.min[0] + stop_x = self.bbox.max[0] + + # Clip to bounding box limits + start_x, stop_x = np.clip(sorted([start_x, stop_x]), + self.bbox.min[0], self.bbox.max[0]) + start_y, stop_y = np.clip(sorted([start_y, stop_y]), + self.bbox.min[1], self.bbox.max[1]) + + # Move the center of the view to the center of the bbox + zoom_center_x = (start_x + stop_x)/2 + zoom_center_y = (start_y + stop_y)/2 + + ax_center_x = (self.bbox.max[0] + self.bbox.min[0])/2 + ax_center_y = (self.bbox.max[1] + self.bbox.min[1])/2 + + self.start_pan(zoom_center_x, zoom_center_y, 2) + self.drag_pan(2, None, ax_center_x, ax_center_y) + self.end_pan() + + # Calculate zoom level + dx = abs(start_x - stop_x) + dy = abs(start_y - stop_y) + scale_u = dx / (self.bbox.max[0] - self.bbox.min[0]) + scale_v = dy / (self.bbox.max[1] - self.bbox.min[1]) + + # Keep aspect ratios equal + scale = max(scale_u, scale_v) + + # Zoom out + if direction == 'out': + scale = 1 / scale + + self._zoom_data_limits(scale, scale, scale) + + def _zoom_data_limits(self, scale_u, scale_v, scale_w): + """ + Zoom in or out of a 3D plot. + + Will scale the data limits by the scale factors. These will be + transformed to the x, y, z data axes based on the current view angles. + A scale factor > 1 zooms out and a scale factor < 1 zooms in. + + For an axes that has had its aspect ratio set to 'equal', 'equalxy', + 'equalyz', or 'equalxz', the relevant axes are constrained to zoom + equally. + + Parameters + ---------- + scale_u : float + Scale factor for the u view axis (view screen horizontal). + scale_v : float + Scale factor for the v view axis (view screen vertical). + scale_w : float + Scale factor for the w view axis (view screen depth). + """ + scale = np.array([scale_u, scale_v, scale_w]) + + # Only perform frame conversion if unequal scale factors + if not np.allclose(scale, scale_u): + # Convert the scale factors from the view frame to the data frame + R = np.array([self._view_u, self._view_v, self._view_w]) + S = scale * np.eye(3) + scale = np.linalg.norm(R.T @ S, axis=1) + + # Set the constrained scale factors to the factor closest to 1 + if self._aspect in ('equal', 'equalxy', 'equalxz', 'equalyz'): + ax_idxs = self._equal_aspect_axis_indices(self._aspect) + min_ax_idxs = np.argmin(np.abs(scale[ax_idxs] - 1)) + scale[ax_idxs] = scale[ax_idxs][min_ax_idxs] + + self._scale_axis_limits(scale[0], scale[1], scale[2]) + + def _scale_axis_limits(self, scale_x, scale_y, scale_z): + """ + Keeping the center of the x, y, and z data axes fixed, scale their + limits by scale factors. A scale factor > 1 zooms out and a scale + factor < 1 zooms in. + + Parameters + ---------- + scale_x : float + Scale factor for the x data axis. + scale_y : float + Scale factor for the y data axis. + scale_z : float + Scale factor for the z data axis. + """ + # Get the axis centers and ranges + cx, cy, cz, dx, dy, dz = self._get_w_centers_ranges() + + # Set the scaled axis limits + self.set_xlim3d(cx - dx*scale_x/2, cx + dx*scale_x/2) + self.set_ylim3d(cy - dy*scale_y/2, cy + dy*scale_y/2) + self.set_zlim3d(cz - dz*scale_z/2, cz + dz*scale_z/2) + + def _get_w_centers_ranges(self): + """Get 3D world centers and axis ranges.""" + # Calculate center of axis limits + minx, maxx, miny, maxy, minz, maxz = self.get_w_lims() + cx = (maxx + minx)/2 + cy = (maxy + miny)/2 + cz = (maxz + minz)/2 + + # Calculate range of axis limits + dx = (maxx - minx) + dy = (maxy - miny) + dz = (maxz - minz) + return cx, cy, cz, dx, dy, dz + + def set_zlabel(self, zlabel, fontdict=None, labelpad=None, **kwargs): + """ + Set zlabel. See doc for `.set_ylabel` for description. + """ + if labelpad is not None: + self.zaxis.labelpad = labelpad + return self.zaxis.set_label_text(zlabel, fontdict, **kwargs) + + def get_zlabel(self): + """ + Get the z-label text string. + """ + label = self.zaxis.get_label() + return label.get_text() + + # Axes rectangle characteristics + + # The frame_on methods are not available for 3D axes. + # Python will raise a TypeError if they are called. + get_frame_on = None + set_frame_on = None + + def grid(self, visible=True, **kwargs): + """ + Set / unset 3D grid. + + .. note:: + + Currently, this function does not behave the same as + `.axes.Axes.grid`, but it is intended to eventually support that + behavior. + """ + # TODO: Operate on each axes separately + if len(kwargs): + visible = True + self._draw_grid = visible + self.stale = True + + def tick_params(self, axis='both', **kwargs): + """ + Convenience method for changing the appearance of ticks and + tick labels. + + See `.Axes.tick_params` for full documentation. Because this function + applies to 3D Axes, *axis* can also be set to 'z', and setting *axis* + to 'both' autoscales all three axes. + + Also, because of how Axes3D objects are drawn very differently + from regular 2D axes, some of these settings may have + ambiguous meaning. For simplicity, the 'z' axis will + accept settings as if it was like the 'y' axis. + + .. note:: + Axes3D currently ignores some of these settings. + """ + _api.check_in_list(['x', 'y', 'z', 'both'], axis=axis) + if axis in ['x', 'y', 'both']: + super().tick_params(axis, **kwargs) + if axis in ['z', 'both']: + zkw = dict(kwargs) + zkw.pop('top', None) + zkw.pop('bottom', None) + zkw.pop('labeltop', None) + zkw.pop('labelbottom', None) + self.zaxis.set_tick_params(**zkw) + + # data limits, ticks, tick labels, and formatting + + def invert_zaxis(self): + """ + Invert the z-axis. + + See Also + -------- + zaxis_inverted + get_zlim, set_zlim + get_zbound, set_zbound + """ + bottom, top = self.get_zlim() + self.set_zlim(top, bottom, auto=None) + + zaxis_inverted = _axis_method_wrapper("zaxis", "get_inverted") + + def get_zbound(self): + """ + Return the lower and upper z-axis bounds, in increasing order. + + See Also + -------- + set_zbound + get_zlim, set_zlim + invert_zaxis, zaxis_inverted + """ + bottom, top = self.get_zlim() + if bottom < top: + return bottom, top + else: + return top, bottom + + def set_zbound(self, lower=None, upper=None): + """ + Set the lower and upper numerical bounds of the z-axis. + + This method will honor axes inversion regardless of parameter order. + It will not change the autoscaling setting (`.get_autoscalez_on()`). + + Parameters + ---------- + lower, upper : float or None + The lower and upper bounds. If *None*, the respective axis bound + is not modified. + + See Also + -------- + get_zbound + get_zlim, set_zlim + invert_zaxis, zaxis_inverted + """ + if upper is None and np.iterable(lower): + lower, upper = lower + + old_lower, old_upper = self.get_zbound() + if lower is None: + lower = old_lower + if upper is None: + upper = old_upper + + self.set_zlim(sorted((lower, upper), + reverse=bool(self.zaxis_inverted())), + auto=None) + + def text(self, x, y, z, s, zdir=None, **kwargs): + """ + Add the text *s* to the 3D Axes at location *x*, *y*, *z* in data coordinates. + + Parameters + ---------- + x, y, z : float + The position to place the text. + s : str + The text. + zdir : {'x', 'y', 'z', 3-tuple}, optional + The direction to be used as the z-direction. Default: 'z'. + See `.get_dir_vector` for a description of the values. + **kwargs + Other arguments are forwarded to `matplotlib.axes.Axes.text`. + + Returns + ------- + `.Text3D` + The created `.Text3D` instance. + """ + text = super().text(x, y, s, **kwargs) + art3d.text_2d_to_3d(text, z, zdir) + return text + + text3D = text + text2D = Axes.text + + def plot(self, xs, ys, *args, zdir='z', **kwargs): + """ + Plot 2D or 3D data. + + Parameters + ---------- + xs : 1D array-like + x coordinates of vertices. + ys : 1D array-like + y coordinates of vertices. + zs : float or 1D array-like + z coordinates of vertices; either one for all points or one for + each point. + zdir : {'x', 'y', 'z'}, default: 'z' + When plotting 2D data, the direction to use as z. + **kwargs + Other arguments are forwarded to `matplotlib.axes.Axes.plot`. + """ + had_data = self.has_data() + + # `zs` can be passed positionally or as keyword; checking whether + # args[0] is a string matches the behavior of 2D `plot` (via + # `_process_plot_var_args`). + if args and not isinstance(args[0], str): + zs, *args = args + if 'zs' in kwargs: + raise TypeError("plot() for multiple values for argument 'z'") + else: + zs = kwargs.pop('zs', 0) + + # Match length + zs = np.broadcast_to(zs, np.shape(xs)) + + lines = super().plot(xs, ys, *args, **kwargs) + for line in lines: + art3d.line_2d_to_3d(line, zs=zs, zdir=zdir) + + xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir) + self.auto_scale_xyz(xs, ys, zs, had_data) + return lines + + plot3D = plot + + def plot_surface(self, X, Y, Z, *, norm=None, vmin=None, + vmax=None, lightsource=None, **kwargs): + """ + Create a surface plot. + + By default, it will be colored in shades of a solid color, but it also + supports colormapping by supplying the *cmap* argument. + + .. note:: + + The *rcount* and *ccount* kwargs, which both default to 50, + determine the maximum number of samples used in each direction. If + the input data is larger, it will be downsampled (by slicing) to + these numbers of points. + + .. note:: + + To maximize rendering speed consider setting *rstride* and *cstride* + to divisors of the number of rows minus 1 and columns minus 1 + respectively. For example, given 51 rows rstride can be any of the + divisors of 50. + + Similarly, a setting of *rstride* and *cstride* equal to 1 (or + *rcount* and *ccount* equal the number of rows and columns) can use + the optimized path. + + Parameters + ---------- + X, Y, Z : 2D arrays + Data values. + + rcount, ccount : int + Maximum number of samples used in each direction. If the input + data is larger, it will be downsampled (by slicing) to these + numbers of points. Defaults to 50. + + rstride, cstride : int + Downsampling stride in each direction. These arguments are + mutually exclusive with *rcount* and *ccount*. If only one of + *rstride* or *cstride* is set, the other defaults to 10. + + 'classic' mode uses a default of ``rstride = cstride = 10`` instead + of the new default of ``rcount = ccount = 50``. + + color : color-like + Color of the surface patches. + + cmap : Colormap + Colormap of the surface patches. + + facecolors : array-like of colors. + Colors of each individual patch. + + norm : Normalize + Normalization for the colormap. + + vmin, vmax : float + Bounds for the normalization. + + shade : bool, default: True + Whether to shade the facecolors. Shading is always disabled when + *cmap* is specified. + + lightsource : `~matplotlib.colors.LightSource` + The lightsource to use when *shade* is True. + + **kwargs + Other keyword arguments are forwarded to `.Poly3DCollection`. + """ + + had_data = self.has_data() + + if Z.ndim != 2: + raise ValueError("Argument Z must be 2-dimensional.") + + Z = cbook._to_unmasked_float_array(Z) + X, Y, Z = np.broadcast_arrays(X, Y, Z) + rows, cols = Z.shape + + has_stride = 'rstride' in kwargs or 'cstride' in kwargs + has_count = 'rcount' in kwargs or 'ccount' in kwargs + + if has_stride and has_count: + raise ValueError("Cannot specify both stride and count arguments") + + rstride = kwargs.pop('rstride', 10) + cstride = kwargs.pop('cstride', 10) + rcount = kwargs.pop('rcount', 50) + ccount = kwargs.pop('ccount', 50) + + if mpl.rcParams['_internal.classic_mode']: + # Strides have priority over counts in classic mode. + # So, only compute strides from counts + # if counts were explicitly given + compute_strides = has_count + else: + # If the strides are provided then it has priority. + # Otherwise, compute the strides from the counts. + compute_strides = not has_stride + + if compute_strides: + rstride = int(max(np.ceil(rows / rcount), 1)) + cstride = int(max(np.ceil(cols / ccount), 1)) + + fcolors = kwargs.pop('facecolors', None) + + cmap = kwargs.get('cmap', None) + shade = kwargs.pop('shade', cmap is None) + if shade is None: + raise ValueError("shade cannot be None.") + + colset = [] # the sampled facecolor + if (rows - 1) % rstride == 0 and \ + (cols - 1) % cstride == 0 and \ + fcolors is None: + polys = np.stack( + [cbook._array_patch_perimeters(a, rstride, cstride) + for a in (X, Y, Z)], + axis=-1) + else: + # evenly spaced, and including both endpoints + row_inds = list(range(0, rows-1, rstride)) + [rows-1] + col_inds = list(range(0, cols-1, cstride)) + [cols-1] + + polys = [] + for rs, rs_next in zip(row_inds[:-1], row_inds[1:]): + for cs, cs_next in zip(col_inds[:-1], col_inds[1:]): + ps = [ + # +1 ensures we share edges between polygons + cbook._array_perimeter(a[rs:rs_next+1, cs:cs_next+1]) + for a in (X, Y, Z) + ] + # ps = np.stack(ps, axis=-1) + ps = np.array(ps).T + polys.append(ps) + + if fcolors is not None: + colset.append(fcolors[rs][cs]) + + # In cases where there are non-finite values in the data (possibly NaNs from + # masked arrays), artifacts can be introduced. Here check whether such values + # are present and remove them. + if not isinstance(polys, np.ndarray) or not np.isfinite(polys).all(): + new_polys = [] + new_colset = [] + + # Depending on fcolors, colset is either an empty list or has as + # many elements as polys. In the former case new_colset results in + # a list with None entries, that is discarded later. + for p, col in itertools.zip_longest(polys, colset): + new_poly = np.array(p)[np.isfinite(p).all(axis=1)] + if len(new_poly): + new_polys.append(new_poly) + new_colset.append(col) + + # Replace previous polys and, if fcolors is not None, colset + polys = new_polys + if fcolors is not None: + colset = new_colset + + # note that the striding causes some polygons to have more coordinates + # than others + + if fcolors is not None: + polyc = art3d.Poly3DCollection( + polys, edgecolors=colset, facecolors=colset, shade=shade, + lightsource=lightsource, **kwargs) + elif cmap: + polyc = art3d.Poly3DCollection(polys, **kwargs) + # can't always vectorize, because polys might be jagged + if isinstance(polys, np.ndarray): + avg_z = polys[..., 2].mean(axis=-1) + else: + avg_z = np.array([ps[:, 2].mean() for ps in polys]) + polyc.set_array(avg_z) + if vmin is not None or vmax is not None: + polyc.set_clim(vmin, vmax) + if norm is not None: + polyc.set_norm(norm) + else: + color = kwargs.pop('color', None) + if color is None: + color = self._get_lines.get_next_color() + color = np.array(mcolors.to_rgba(color)) + + polyc = art3d.Poly3DCollection( + polys, facecolors=color, shade=shade, + lightsource=lightsource, **kwargs) + + self.add_collection(polyc) + self.auto_scale_xyz(X, Y, Z, had_data) + + return polyc + + def plot_wireframe(self, X, Y, Z, **kwargs): + """ + Plot a 3D wireframe. + + .. note:: + + The *rcount* and *ccount* kwargs, which both default to 50, + determine the maximum number of samples used in each direction. If + the input data is larger, it will be downsampled (by slicing) to + these numbers of points. + + Parameters + ---------- + X, Y, Z : 2D arrays + Data values. + + rcount, ccount : int + Maximum number of samples used in each direction. If the input + data is larger, it will be downsampled (by slicing) to these + numbers of points. Setting a count to zero causes the data to be + not sampled in the corresponding direction, producing a 3D line + plot rather than a wireframe plot. Defaults to 50. + + rstride, cstride : int + Downsampling stride in each direction. These arguments are + mutually exclusive with *rcount* and *ccount*. If only one of + *rstride* or *cstride* is set, the other defaults to 1. Setting a + stride to zero causes the data to be not sampled in the + corresponding direction, producing a 3D line plot rather than a + wireframe plot. + + 'classic' mode uses a default of ``rstride = cstride = 1`` instead + of the new default of ``rcount = ccount = 50``. + + **kwargs + Other keyword arguments are forwarded to `.Line3DCollection`. + """ + + had_data = self.has_data() + if Z.ndim != 2: + raise ValueError("Argument Z must be 2-dimensional.") + # FIXME: Support masked arrays + X, Y, Z = np.broadcast_arrays(X, Y, Z) + rows, cols = Z.shape + + has_stride = 'rstride' in kwargs or 'cstride' in kwargs + has_count = 'rcount' in kwargs or 'ccount' in kwargs + + if has_stride and has_count: + raise ValueError("Cannot specify both stride and count arguments") + + rstride = kwargs.pop('rstride', 1) + cstride = kwargs.pop('cstride', 1) + rcount = kwargs.pop('rcount', 50) + ccount = kwargs.pop('ccount', 50) + + if mpl.rcParams['_internal.classic_mode']: + # Strides have priority over counts in classic mode. + # So, only compute strides from counts + # if counts were explicitly given + if has_count: + rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0 + cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0 + else: + # If the strides are provided then it has priority. + # Otherwise, compute the strides from the counts. + if not has_stride: + rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0 + cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0 + + # We want two sets of lines, one running along the "rows" of + # Z and another set of lines running along the "columns" of Z. + # This transpose will make it easy to obtain the columns. + tX, tY, tZ = np.transpose(X), np.transpose(Y), np.transpose(Z) + + if rstride: + rii = list(range(0, rows, rstride)) + # Add the last index only if needed + if rows > 0 and rii[-1] != (rows - 1): + rii += [rows-1] + else: + rii = [] + if cstride: + cii = list(range(0, cols, cstride)) + # Add the last index only if needed + if cols > 0 and cii[-1] != (cols - 1): + cii += [cols-1] + else: + cii = [] + + if rstride == 0 and cstride == 0: + raise ValueError("Either rstride or cstride must be non zero") + + # If the inputs were empty, then just + # reset everything. + if Z.size == 0: + rii = [] + cii = [] + + xlines = [X[i] for i in rii] + ylines = [Y[i] for i in rii] + zlines = [Z[i] for i in rii] + + txlines = [tX[i] for i in cii] + tylines = [tY[i] for i in cii] + tzlines = [tZ[i] for i in cii] + + lines = ([list(zip(xl, yl, zl)) + for xl, yl, zl in zip(xlines, ylines, zlines)] + + [list(zip(xl, yl, zl)) + for xl, yl, zl in zip(txlines, tylines, tzlines)]) + + linec = art3d.Line3DCollection(lines, **kwargs) + self.add_collection(linec) + self.auto_scale_xyz(X, Y, Z, had_data) + + return linec + + def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, + lightsource=None, **kwargs): + """ + Plot a triangulated surface. + + The (optional) triangulation can be specified in one of two ways; + either:: + + plot_trisurf(triangulation, ...) + + where triangulation is a `~matplotlib.tri.Triangulation` object, or:: + + plot_trisurf(X, Y, ...) + plot_trisurf(X, Y, triangles, ...) + plot_trisurf(X, Y, triangles=triangles, ...) + + in which case a Triangulation object will be created. See + `.Triangulation` for an explanation of these possibilities. + + The remaining arguments are:: + + plot_trisurf(..., Z) + + where *Z* is the array of values to contour, one per point + in the triangulation. + + Parameters + ---------- + X, Y, Z : array-like + Data values as 1D arrays. + color + Color of the surface patches. + cmap + A colormap for the surface patches. + norm : Normalize + An instance of Normalize to map values to colors. + vmin, vmax : float, default: None + Minimum and maximum value to map. + shade : bool, default: True + Whether to shade the facecolors. Shading is always disabled when + *cmap* is specified. + lightsource : `~matplotlib.colors.LightSource` + The lightsource to use when *shade* is True. + **kwargs + All other keyword arguments are passed on to + :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` + + Examples + -------- + .. plot:: gallery/mplot3d/trisurf3d.py + .. plot:: gallery/mplot3d/trisurf3d_2.py + """ + + had_data = self.has_data() + + # TODO: Support custom face colours + if color is None: + color = self._get_lines.get_next_color() + color = np.array(mcolors.to_rgba(color)) + + cmap = kwargs.get('cmap', None) + shade = kwargs.pop('shade', cmap is None) + + tri, args, kwargs = \ + Triangulation.get_from_args_and_kwargs(*args, **kwargs) + try: + z = kwargs.pop('Z') + except KeyError: + # We do this so Z doesn't get passed as an arg to PolyCollection + z, *args = args + z = np.asarray(z) + + triangles = tri.get_masked_triangles() + xt = tri.x[triangles] + yt = tri.y[triangles] + zt = z[triangles] + verts = np.stack((xt, yt, zt), axis=-1) + + if cmap: + polyc = art3d.Poly3DCollection(verts, *args, **kwargs) + # average over the three points of each triangle + avg_z = verts[:, :, 2].mean(axis=1) + polyc.set_array(avg_z) + if vmin is not None or vmax is not None: + polyc.set_clim(vmin, vmax) + if norm is not None: + polyc.set_norm(norm) + else: + polyc = art3d.Poly3DCollection( + verts, *args, shade=shade, lightsource=lightsource, + facecolors=color, **kwargs) + + self.add_collection(polyc) + self.auto_scale_xyz(tri.x, tri.y, z, had_data) + + return polyc + + def _3d_extend_contour(self, cset, stride=5): + """ + Extend a contour in 3D by creating + """ + + dz = (cset.levels[1] - cset.levels[0]) / 2 + polyverts = [] + colors = [] + for idx, level in enumerate(cset.levels): + path = cset.get_paths()[idx] + subpaths = [*path._iter_connected_components()] + color = cset.get_edgecolor()[idx] + top = art3d._paths_to_3d_segments(subpaths, level - dz) + bot = art3d._paths_to_3d_segments(subpaths, level + dz) + if not len(top[0]): + continue + nsteps = max(round(len(top[0]) / stride), 2) + stepsize = (len(top[0]) - 1) / (nsteps - 1) + polyverts.extend([ + (top[0][round(i * stepsize)], top[0][round((i + 1) * stepsize)], + bot[0][round((i + 1) * stepsize)], bot[0][round(i * stepsize)]) + for i in range(round(nsteps) - 1)]) + colors.extend([color] * (round(nsteps) - 1)) + self.add_collection3d(art3d.Poly3DCollection( + np.array(polyverts), # All polygons have 4 vertices, so vectorize. + facecolors=colors, edgecolors=colors, shade=True)) + cset.remove() + + def add_contour_set( + self, cset, extend3d=False, stride=5, zdir='z', offset=None): + zdir = '-' + zdir + if extend3d: + self._3d_extend_contour(cset, stride) + else: + art3d.collection_2d_to_3d( + cset, zs=offset if offset is not None else cset.levels, zdir=zdir) + + def add_contourf_set(self, cset, zdir='z', offset=None): + self._add_contourf_set(cset, zdir=zdir, offset=offset) + + def _add_contourf_set(self, cset, zdir='z', offset=None): + """ + Returns + ------- + levels : `numpy.ndarray` + Levels at which the filled contours are added. + """ + zdir = '-' + zdir + + midpoints = cset.levels[:-1] + np.diff(cset.levels) / 2 + # Linearly interpolate to get levels for any extensions + if cset._extend_min: + min_level = cset.levels[0] - np.diff(cset.levels[:2]) / 2 + midpoints = np.insert(midpoints, 0, min_level) + if cset._extend_max: + max_level = cset.levels[-1] + np.diff(cset.levels[-2:]) / 2 + midpoints = np.append(midpoints, max_level) + + art3d.collection_2d_to_3d( + cset, zs=offset if offset is not None else midpoints, zdir=zdir) + return midpoints + + @_preprocess_data() + def contour(self, X, Y, Z, *args, + extend3d=False, stride=5, zdir='z', offset=None, **kwargs): + """ + Create a 3D contour plot. + + Parameters + ---------- + X, Y, Z : array-like, + Input data. See `.Axes.contour` for supported data shapes. + extend3d : bool, default: False + Whether to extend contour in 3D. + stride : int + Step size for extending contour. + zdir : {'x', 'y', 'z'}, default: 'z' + The direction to use. + offset : float, optional + If specified, plot a projection of the contour lines at this + position in a plane normal to *zdir*. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + *args, **kwargs + Other arguments are forwarded to `matplotlib.axes.Axes.contour`. + + Returns + ------- + matplotlib.contour.QuadContourSet + """ + had_data = self.has_data() + + jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) + cset = super().contour(jX, jY, jZ, *args, **kwargs) + self.add_contour_set(cset, extend3d, stride, zdir, offset) + + self.auto_scale_xyz(X, Y, Z, had_data) + return cset + + contour3D = contour + + @_preprocess_data() + def tricontour(self, *args, + extend3d=False, stride=5, zdir='z', offset=None, **kwargs): + """ + Create a 3D contour plot. + + .. note:: + This method currently produces incorrect output due to a + longstanding bug in 3D PolyCollection rendering. + + Parameters + ---------- + X, Y, Z : array-like + Input data. See `.Axes.tricontour` for supported data shapes. + extend3d : bool, default: False + Whether to extend contour in 3D. + stride : int + Step size for extending contour. + zdir : {'x', 'y', 'z'}, default: 'z' + The direction to use. + offset : float, optional + If specified, plot a projection of the contour lines at this + position in a plane normal to *zdir*. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + *args, **kwargs + Other arguments are forwarded to `matplotlib.axes.Axes.tricontour`. + + Returns + ------- + matplotlib.tri._tricontour.TriContourSet + """ + had_data = self.has_data() + + tri, args, kwargs = Triangulation.get_from_args_and_kwargs( + *args, **kwargs) + X = tri.x + Y = tri.y + if 'Z' in kwargs: + Z = kwargs.pop('Z') + else: + # We do this so Z doesn't get passed as an arg to Axes.tricontour + Z, *args = args + + jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) + tri = Triangulation(jX, jY, tri.triangles, tri.mask) + + cset = super().tricontour(tri, jZ, *args, **kwargs) + self.add_contour_set(cset, extend3d, stride, zdir, offset) + + self.auto_scale_xyz(X, Y, Z, had_data) + return cset + + def _auto_scale_contourf(self, X, Y, Z, zdir, levels, had_data): + # Autoscale in the zdir based on the levels added, which are + # different from data range if any contour extensions are present + dim_vals = {'x': X, 'y': Y, 'z': Z, zdir: levels} + # Input data and levels have different sizes, but auto_scale_xyz + # expected same-size input, so manually take min/max limits + limits = [(np.nanmin(dim_vals[dim]), np.nanmax(dim_vals[dim])) + for dim in ['x', 'y', 'z']] + self.auto_scale_xyz(*limits, had_data) + + @_preprocess_data() + def contourf(self, X, Y, Z, *args, zdir='z', offset=None, **kwargs): + """ + Create a 3D filled contour plot. + + Parameters + ---------- + X, Y, Z : array-like + Input data. See `.Axes.contourf` for supported data shapes. + zdir : {'x', 'y', 'z'}, default: 'z' + The direction to use. + offset : float, optional + If specified, plot a projection of the contour lines at this + position in a plane normal to *zdir*. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + *args, **kwargs + Other arguments are forwarded to `matplotlib.axes.Axes.contourf`. + + Returns + ------- + matplotlib.contour.QuadContourSet + """ + had_data = self.has_data() + + jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) + cset = super().contourf(jX, jY, jZ, *args, **kwargs) + levels = self._add_contourf_set(cset, zdir, offset) + + self._auto_scale_contourf(X, Y, Z, zdir, levels, had_data) + return cset + + contourf3D = contourf + + @_preprocess_data() + def tricontourf(self, *args, zdir='z', offset=None, **kwargs): + """ + Create a 3D filled contour plot. + + .. note:: + This method currently produces incorrect output due to a + longstanding bug in 3D PolyCollection rendering. + + Parameters + ---------- + X, Y, Z : array-like + Input data. See `.Axes.tricontourf` for supported data shapes. + zdir : {'x', 'y', 'z'}, default: 'z' + The direction to use. + offset : float, optional + If specified, plot a projection of the contour lines at this + position in a plane normal to zdir. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + *args, **kwargs + Other arguments are forwarded to + `matplotlib.axes.Axes.tricontourf`. + + Returns + ------- + matplotlib.tri._tricontour.TriContourSet + """ + had_data = self.has_data() + + tri, args, kwargs = Triangulation.get_from_args_and_kwargs( + *args, **kwargs) + X = tri.x + Y = tri.y + if 'Z' in kwargs: + Z = kwargs.pop('Z') + else: + # We do this so Z doesn't get passed as an arg to Axes.tricontourf + Z, *args = args + + jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) + tri = Triangulation(jX, jY, tri.triangles, tri.mask) + + cset = super().tricontourf(tri, jZ, *args, **kwargs) + levels = self._add_contourf_set(cset, zdir, offset) + + self._auto_scale_contourf(X, Y, Z, zdir, levels, had_data) + return cset + + def add_collection3d(self, col, zs=0, zdir='z'): + """ + Add a 3D collection object to the plot. + + 2D collection types are converted to a 3D version by + modifying the object and adding z coordinate information. + + Supported are: + + - PolyCollection + - LineCollection + - PatchCollection + """ + zvals = np.atleast_1d(zs) + zsortval = (np.min(zvals) if zvals.size + else 0) # FIXME: arbitrary default + + # FIXME: use issubclass() (although, then a 3D collection + # object would also pass.) Maybe have a collection3d + # abstract class to test for and exclude? + if type(col) is mcoll.PolyCollection: + art3d.poly_collection_2d_to_3d(col, zs=zs, zdir=zdir) + col.set_sort_zpos(zsortval) + elif type(col) is mcoll.LineCollection: + art3d.line_collection_2d_to_3d(col, zs=zs, zdir=zdir) + col.set_sort_zpos(zsortval) + elif type(col) is mcoll.PatchCollection: + art3d.patch_collection_2d_to_3d(col, zs=zs, zdir=zdir) + col.set_sort_zpos(zsortval) + + collection = super().add_collection(col) + return collection + + @_preprocess_data(replace_names=["xs", "ys", "zs", "s", + "edgecolors", "c", "facecolor", + "facecolors", "color"]) + def scatter(self, xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True, + *args, **kwargs): + """ + Create a scatter plot. + + Parameters + ---------- + xs, ys : array-like + The data positions. + zs : float or array-like, default: 0 + The z-positions. Either an array of the same length as *xs* and + *ys* or a single value to place all points in the same plane. + zdir : {'x', 'y', 'z', '-x', '-y', '-z'}, default: 'z' + The axis direction for the *zs*. This is useful when plotting 2D + data on a 3D Axes. The data must be passed as *xs*, *ys*. Setting + *zdir* to 'y' then plots the data to the x-z-plane. + + See also :doc:`/gallery/mplot3d/2dcollections3d`. + + s : float or array-like, default: 20 + The marker size in points**2. Either an array of the same length + as *xs* and *ys* or a single value to make all markers the same + size. + c : color, sequence, or sequence of colors, optional + The marker color. Possible values: + + - A single color format string. + - A sequence of colors of length n. + - A sequence of n numbers to be mapped to colors using *cmap* and + *norm*. + - A 2D array in which the rows are RGB or RGBA. + + For more details see the *c* argument of `~.axes.Axes.scatter`. + depthshade : bool, default: True + Whether to shade the scatter markers to give the appearance of + depth. Each call to ``scatter()`` will perform its depthshading + independently. + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + **kwargs + All other keyword arguments are passed on to `~.axes.Axes.scatter`. + + Returns + ------- + paths : `~matplotlib.collections.PathCollection` + """ + + had_data = self.has_data() + zs_orig = zs + + xs, ys, zs = np.broadcast_arrays( + *[np.ravel(np.ma.filled(t, np.nan)) for t in [xs, ys, zs]]) + s = np.ma.ravel(s) # This doesn't have to match x, y in size. + + xs, ys, zs, s, c, color = cbook.delete_masked_points( + xs, ys, zs, s, c, kwargs.get('color', None) + ) + if kwargs.get("color") is not None: + kwargs['color'] = color + + # For xs and ys, 2D scatter() will do the copying. + if np.may_share_memory(zs_orig, zs): # Avoid unnecessary copies. + zs = zs.copy() + + patches = super().scatter(xs, ys, s=s, c=c, *args, **kwargs) + art3d.patch_collection_2d_to_3d(patches, zs=zs, zdir=zdir, + depthshade=depthshade) + + if self._zmargin < 0.05 and xs.size > 0: + self.set_zmargin(0.05) + + self.auto_scale_xyz(xs, ys, zs, had_data) + + return patches + + scatter3D = scatter + + @_preprocess_data() + def bar(self, left, height, zs=0, zdir='z', *args, **kwargs): + """ + Add 2D bar(s). + + Parameters + ---------- + left : 1D array-like + The x coordinates of the left sides of the bars. + height : 1D array-like + The height of the bars. + zs : float or 1D array-like + Z coordinate of bars; if a single value is specified, it will be + used for all bars. + zdir : {'x', 'y', 'z'}, default: 'z' + When plotting 2D data, the direction to use as z ('x', 'y' or 'z'). + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + **kwargs + Other keyword arguments are forwarded to + `matplotlib.axes.Axes.bar`. + + Returns + ------- + mpl_toolkits.mplot3d.art3d.Patch3DCollection + """ + had_data = self.has_data() + + patches = super().bar(left, height, *args, **kwargs) + + zs = np.broadcast_to(zs, len(left)) + + verts = [] + verts_zs = [] + for p, z in zip(patches, zs): + vs = art3d._get_patch_verts(p) + verts += vs.tolist() + verts_zs += [z] * len(vs) + art3d.patch_2d_to_3d(p, z, zdir) + if 'alpha' in kwargs: + p.set_alpha(kwargs['alpha']) + + if len(verts) > 0: + # the following has to be skipped if verts is empty + # NOTE: Bugs could still occur if len(verts) > 0, + # but the "2nd dimension" is empty. + xs, ys = zip(*verts) + else: + xs, ys = [], [] + + xs, ys, verts_zs = art3d.juggle_axes(xs, ys, verts_zs, zdir) + self.auto_scale_xyz(xs, ys, verts_zs, had_data) + + return patches + + @_preprocess_data() + def bar3d(self, x, y, z, dx, dy, dz, color=None, + zsort='average', shade=True, lightsource=None, *args, **kwargs): + """ + Generate a 3D barplot. + + This method creates three-dimensional barplot where the width, + depth, height, and color of the bars can all be uniquely set. + + Parameters + ---------- + x, y, z : array-like + The coordinates of the anchor point of the bars. + + dx, dy, dz : float or array-like + The width, depth, and height of the bars, respectively. + + color : sequence of colors, optional + The color of the bars can be specified globally or + individually. This parameter can be: + + - A single color, to color all bars the same color. + - An array of colors of length N bars, to color each bar + independently. + - An array of colors of length 6, to color the faces of the + bars similarly. + - An array of colors of length 6 * N bars, to color each face + independently. + + When coloring the faces of the boxes specifically, this is + the order of the coloring: + + 1. -Z (bottom of box) + 2. +Z (top of box) + 3. -Y + 4. +Y + 5. -X + 6. +X + + zsort : str, optional + The z-axis sorting scheme passed onto `~.art3d.Poly3DCollection` + + shade : bool, default: True + When true, this shades the dark sides of the bars (relative + to the plot's source of light). + + lightsource : `~matplotlib.colors.LightSource` + The lightsource to use when *shade* is True. + + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + **kwargs + Any additional keyword arguments are passed onto + `~.art3d.Poly3DCollection`. + + Returns + ------- + collection : `~.art3d.Poly3DCollection` + A collection of three-dimensional polygons representing the bars. + """ + + had_data = self.has_data() + + x, y, z, dx, dy, dz = np.broadcast_arrays( + np.atleast_1d(x), y, z, dx, dy, dz) + minx = np.min(x) + maxx = np.max(x + dx) + miny = np.min(y) + maxy = np.max(y + dy) + minz = np.min(z) + maxz = np.max(z + dz) + + # shape (6, 4, 3) + # All faces are oriented facing outwards - when viewed from the + # outside, their vertices are in a counterclockwise ordering. + cuboid = np.array([ + # -z + ( + (0, 0, 0), + (0, 1, 0), + (1, 1, 0), + (1, 0, 0), + ), + # +z + ( + (0, 0, 1), + (1, 0, 1), + (1, 1, 1), + (0, 1, 1), + ), + # -y + ( + (0, 0, 0), + (1, 0, 0), + (1, 0, 1), + (0, 0, 1), + ), + # +y + ( + (0, 1, 0), + (0, 1, 1), + (1, 1, 1), + (1, 1, 0), + ), + # -x + ( + (0, 0, 0), + (0, 0, 1), + (0, 1, 1), + (0, 1, 0), + ), + # +x + ( + (1, 0, 0), + (1, 1, 0), + (1, 1, 1), + (1, 0, 1), + ), + ]) + + # indexed by [bar, face, vertex, coord] + polys = np.empty(x.shape + cuboid.shape) + + # handle each coordinate separately + for i, p, dp in [(0, x, dx), (1, y, dy), (2, z, dz)]: + p = p[..., np.newaxis, np.newaxis] + dp = dp[..., np.newaxis, np.newaxis] + polys[..., i] = p + dp * cuboid[..., i] + + # collapse the first two axes + polys = polys.reshape((-1,) + polys.shape[2:]) + + facecolors = [] + if color is None: + color = [self._get_patches_for_fill.get_next_color()] + + color = list(mcolors.to_rgba_array(color)) + + if len(color) == len(x): + # bar colors specified, need to expand to number of faces + for c in color: + facecolors.extend([c] * 6) + else: + # a single color specified, or face colors specified explicitly + facecolors = color + if len(facecolors) < len(x): + facecolors *= (6 * len(x)) + + col = art3d.Poly3DCollection(polys, + zsort=zsort, + facecolors=facecolors, + shade=shade, + lightsource=lightsource, + *args, **kwargs) + self.add_collection(col) + + self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data) + + return col + + def set_title(self, label, fontdict=None, loc='center', **kwargs): + # docstring inherited + ret = super().set_title(label, fontdict=fontdict, loc=loc, **kwargs) + (x, y) = self.title.get_position() + self.title.set_y(0.92 * y) + return ret + + @_preprocess_data() + def quiver(self, X, Y, Z, U, V, W, *, + length=1, arrow_length_ratio=.3, pivot='tail', normalize=False, + **kwargs): + """ + Plot a 3D field of arrows. + + The arguments can be array-like or scalars, so long as they can be + broadcast together. The arguments can also be masked arrays. If an + element in any of argument is masked, then that corresponding quiver + element will not be plotted. + + Parameters + ---------- + X, Y, Z : array-like + The x, y and z coordinates of the arrow locations (default is + tail of arrow; see *pivot* kwarg). + + U, V, W : array-like + The x, y and z components of the arrow vectors. + + length : float, default: 1 + The length of each quiver. + + arrow_length_ratio : float, default: 0.3 + The ratio of the arrow head with respect to the quiver. + + pivot : {'tail', 'middle', 'tip'}, default: 'tail' + The part of the arrow that is at the grid point; the arrow + rotates about this point, hence the name *pivot*. + + normalize : bool, default: False + Whether all arrows are normalized to have the same length, or keep + the lengths defined by *u*, *v*, and *w*. + + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + **kwargs + Any additional keyword arguments are delegated to + :class:`.Line3DCollection` + """ + + def calc_arrows(UVW): + # get unit direction vector perpendicular to (u, v, w) + x = UVW[:, 0] + y = UVW[:, 1] + norm = np.linalg.norm(UVW[:, :2], axis=1) + x_p = np.divide(y, norm, where=norm != 0, out=np.zeros_like(x)) + y_p = np.divide(-x, norm, where=norm != 0, out=np.ones_like(x)) + # compute the two arrowhead direction unit vectors + rangle = math.radians(15) + c = math.cos(rangle) + s = math.sin(rangle) + # construct the rotation matrices of shape (3, 3, n) + r13 = y_p * s + r32 = x_p * s + r12 = x_p * y_p * (1 - c) + Rpos = np.array( + [[c + (x_p ** 2) * (1 - c), r12, r13], + [r12, c + (y_p ** 2) * (1 - c), -r32], + [-r13, r32, np.full_like(x_p, c)]]) + # opposite rotation negates all the sin terms + Rneg = Rpos.copy() + Rneg[[0, 1, 2, 2], [2, 2, 0, 1]] *= -1 + # Batch n (3, 3) x (3) matrix multiplications ((3, 3, n) x (n, 3)). + Rpos_vecs = np.einsum("ij...,...j->...i", Rpos, UVW) + Rneg_vecs = np.einsum("ij...,...j->...i", Rneg, UVW) + # Stack into (n, 2, 3) result. + return np.stack([Rpos_vecs, Rneg_vecs], axis=1) + + had_data = self.has_data() + + input_args = [X, Y, Z, U, V, W] + + # extract the masks, if any + masks = [k.mask for k in input_args + if isinstance(k, np.ma.MaskedArray)] + # broadcast to match the shape + bcast = np.broadcast_arrays(*input_args, *masks) + input_args = bcast[:6] + masks = bcast[6:] + if masks: + # combine the masks into one + mask = functools.reduce(np.logical_or, masks) + # put mask on and compress + input_args = [np.ma.array(k, mask=mask).compressed() + for k in input_args] + else: + input_args = [np.ravel(k) for k in input_args] + + if any(len(v) == 0 for v in input_args): + # No quivers, so just make an empty collection and return early + linec = art3d.Line3DCollection([], **kwargs) + self.add_collection(linec) + return linec + + shaft_dt = np.array([0., length], dtype=float) + arrow_dt = shaft_dt * arrow_length_ratio + + _api.check_in_list(['tail', 'middle', 'tip'], pivot=pivot) + if pivot == 'tail': + shaft_dt -= length + elif pivot == 'middle': + shaft_dt -= length / 2 + + XYZ = np.column_stack(input_args[:3]) + UVW = np.column_stack(input_args[3:]).astype(float) + + # Normalize rows of UVW + norm = np.linalg.norm(UVW, axis=1) + + # If any row of UVW is all zeros, don't make a quiver for it + mask = norm > 0 + XYZ = XYZ[mask] + if normalize: + UVW = UVW[mask] / norm[mask].reshape((-1, 1)) + else: + UVW = UVW[mask] + + if len(XYZ) > 0: + # compute the shaft lines all at once with an outer product + shafts = (XYZ - np.multiply.outer(shaft_dt, UVW)).swapaxes(0, 1) + # compute head direction vectors, n heads x 2 sides x 3 dimensions + head_dirs = calc_arrows(UVW) + # compute all head lines at once, starting from the shaft ends + heads = shafts[:, :1] - np.multiply.outer(arrow_dt, head_dirs) + # stack left and right head lines together + heads = heads.reshape((len(arrow_dt), -1, 3)) + # transpose to get a list of lines + heads = heads.swapaxes(0, 1) + + lines = [*shafts, *heads] + else: + lines = [] + + linec = art3d.Line3DCollection(lines, **kwargs) + self.add_collection(linec) + + self.auto_scale_xyz(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], had_data) + + return linec + + quiver3D = quiver + + def voxels(self, *args, facecolors=None, edgecolors=None, shade=True, + lightsource=None, **kwargs): + """ + ax.voxels([x, y, z,] /, filled, facecolors=None, edgecolors=None, \ +**kwargs) + + Plot a set of filled voxels + + All voxels are plotted as 1x1x1 cubes on the axis, with + ``filled[0, 0, 0]`` placed with its lower corner at the origin. + Occluded faces are not plotted. + + Parameters + ---------- + filled : 3D np.array of bool + A 3D array of values, with truthy values indicating which voxels + to fill + + x, y, z : 3D np.array, optional + The coordinates of the corners of the voxels. This should broadcast + to a shape one larger in every dimension than the shape of + *filled*. These can be used to plot non-cubic voxels. + + If not specified, defaults to increasing integers along each axis, + like those returned by :func:`~numpy.indices`. + As indicated by the ``/`` in the function signature, these + arguments can only be passed positionally. + + facecolors, edgecolors : array-like, optional + The color to draw the faces and edges of the voxels. Can only be + passed as keyword arguments. + These parameters can be: + + - A single color value, to color all voxels the same color. This + can be either a string, or a 1D RGB/RGBA array + - ``None``, the default, to use a single color for the faces, and + the style default for the edges. + - A 3D `~numpy.ndarray` of color names, with each item the color + for the corresponding voxel. The size must match the voxels. + - A 4D `~numpy.ndarray` of RGB/RGBA data, with the components + along the last axis. + + shade : bool, default: True + Whether to shade the facecolors. + + lightsource : `~matplotlib.colors.LightSource` + The lightsource to use when *shade* is True. + + **kwargs + Additional keyword arguments to pass onto + `~mpl_toolkits.mplot3d.art3d.Poly3DCollection`. + + Returns + ------- + faces : dict + A dictionary indexed by coordinate, where ``faces[i, j, k]`` is a + `.Poly3DCollection` of the faces drawn for the voxel + ``filled[i, j, k]``. If no faces were drawn for a given voxel, + either because it was not asked to be drawn, or it is fully + occluded, then ``(i, j, k) not in faces``. + + Examples + -------- + .. plot:: gallery/mplot3d/voxels.py + .. plot:: gallery/mplot3d/voxels_rgb.py + .. plot:: gallery/mplot3d/voxels_torus.py + .. plot:: gallery/mplot3d/voxels_numpy_logo.py + """ + + # work out which signature we should be using, and use it to parse + # the arguments. Name must be voxels for the correct error message + if len(args) >= 3: + # underscores indicate position only + def voxels(__x, __y, __z, filled, **kwargs): + return (__x, __y, __z), filled, kwargs + else: + def voxels(filled, **kwargs): + return None, filled, kwargs + + xyz, filled, kwargs = voxels(*args, **kwargs) + + # check dimensions + if filled.ndim != 3: + raise ValueError("Argument filled must be 3-dimensional") + size = np.array(filled.shape, dtype=np.intp) + + # check xyz coordinates, which are one larger than the filled shape + coord_shape = tuple(size + 1) + if xyz is None: + x, y, z = np.indices(coord_shape) + else: + x, y, z = (np.broadcast_to(c, coord_shape) for c in xyz) + + def _broadcast_color_arg(color, name): + if np.ndim(color) in (0, 1): + # single color, like "red" or [1, 0, 0] + return np.broadcast_to(color, filled.shape + np.shape(color)) + elif np.ndim(color) in (3, 4): + # 3D array of strings, or 4D array with last axis rgb + if np.shape(color)[:3] != filled.shape: + raise ValueError( + f"When multidimensional, {name} must match the shape " + "of filled") + return color + else: + raise ValueError(f"Invalid {name} argument") + + # broadcast and default on facecolors + if facecolors is None: + facecolors = self._get_patches_for_fill.get_next_color() + facecolors = _broadcast_color_arg(facecolors, 'facecolors') + + # broadcast but no default on edgecolors + edgecolors = _broadcast_color_arg(edgecolors, 'edgecolors') + + # scale to the full array, even if the data is only in the center + self.auto_scale_xyz(x, y, z) + + # points lying on corners of a square + square = np.array([ + [0, 0, 0], + [1, 0, 0], + [1, 1, 0], + [0, 1, 0], + ], dtype=np.intp) + + voxel_faces = defaultdict(list) + + def permutation_matrices(n): + """Generate cyclic permutation matrices.""" + mat = np.eye(n, dtype=np.intp) + for i in range(n): + yield mat + mat = np.roll(mat, 1, axis=0) + + # iterate over each of the YZ, ZX, and XY orientations, finding faces + # to render + for permute in permutation_matrices(3): + # find the set of ranges to iterate over + pc, qc, rc = permute.T.dot(size) + pinds = np.arange(pc) + qinds = np.arange(qc) + rinds = np.arange(rc) + + square_rot_pos = square.dot(permute.T) + square_rot_neg = square_rot_pos[::-1] + + # iterate within the current plane + for p in pinds: + for q in qinds: + # iterate perpendicularly to the current plane, handling + # boundaries. We only draw faces between a voxel and an + # empty space, to avoid drawing internal faces. + + # draw lower faces + p0 = permute.dot([p, q, 0]) + i0 = tuple(p0) + if filled[i0]: + voxel_faces[i0].append(p0 + square_rot_neg) + + # draw middle faces + for r1, r2 in zip(rinds[:-1], rinds[1:]): + p1 = permute.dot([p, q, r1]) + p2 = permute.dot([p, q, r2]) + + i1 = tuple(p1) + i2 = tuple(p2) + + if filled[i1] and not filled[i2]: + voxel_faces[i1].append(p2 + square_rot_pos) + elif not filled[i1] and filled[i2]: + voxel_faces[i2].append(p2 + square_rot_neg) + + # draw upper faces + pk = permute.dot([p, q, rc-1]) + pk2 = permute.dot([p, q, rc]) + ik = tuple(pk) + if filled[ik]: + voxel_faces[ik].append(pk2 + square_rot_pos) + + # iterate over the faces, and generate a Poly3DCollection for each + # voxel + polygons = {} + for coord, faces_inds in voxel_faces.items(): + # convert indices into 3D positions + if xyz is None: + faces = faces_inds + else: + faces = [] + for face_inds in faces_inds: + ind = face_inds[:, 0], face_inds[:, 1], face_inds[:, 2] + face = np.empty(face_inds.shape) + face[:, 0] = x[ind] + face[:, 1] = y[ind] + face[:, 2] = z[ind] + faces.append(face) + + # shade the faces + facecolor = facecolors[coord] + edgecolor = edgecolors[coord] + + poly = art3d.Poly3DCollection( + faces, facecolors=facecolor, edgecolors=edgecolor, + shade=shade, lightsource=lightsource, **kwargs) + self.add_collection3d(poly) + polygons[coord] = poly + + return polygons + + @_preprocess_data(replace_names=["x", "y", "z", "xerr", "yerr", "zerr"]) + def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, fmt='', + barsabove=False, errorevery=1, ecolor=None, elinewidth=None, + capsize=None, capthick=None, xlolims=False, xuplims=False, + ylolims=False, yuplims=False, zlolims=False, zuplims=False, + **kwargs): + """ + Plot lines and/or markers with errorbars around them. + + *x*/*y*/*z* define the data locations, and *xerr*/*yerr*/*zerr* define + the errorbar sizes. By default, this draws the data markers/lines as + well the errorbars. Use fmt='none' to draw errorbars only. + + Parameters + ---------- + x, y, z : float or array-like + The data positions. + + xerr, yerr, zerr : float or array-like, shape (N,) or (2, N), optional + The errorbar sizes: + + - scalar: Symmetric +/- values for all data points. + - shape(N,): Symmetric +/-values for each data point. + - shape(2, N): Separate - and + values for each bar. First row + contains the lower errors, the second row contains the upper + errors. + - *None*: No errorbar. + + Note that all error arrays should have *positive* values. + + fmt : str, default: '' + The format for the data points / data lines. See `.plot` for + details. + + Use 'none' (case-insensitive) to plot errorbars without any data + markers. + + ecolor : color, default: None + The color of the errorbar lines. If None, use the color of the + line connecting the markers. + + elinewidth : float, default: None + The linewidth of the errorbar lines. If None, the linewidth of + the current style is used. + + capsize : float, default: :rc:`errorbar.capsize` + The length of the error bar caps in points. + + capthick : float, default: None + An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*). + This setting is a more sensible name for the property that + controls the thickness of the error bar cap in points. For + backwards compatibility, if *mew* or *markeredgewidth* are given, + then they will over-ride *capthick*. This may change in future + releases. + + barsabove : bool, default: False + If True, will plot the errorbars above the plot + symbols. Default is below. + + xlolims, ylolims, zlolims : bool, default: False + These arguments can be used to indicate that a value gives only + lower limits. In that case a caret symbol is used to indicate + this. *lims*-arguments may be scalars, or array-likes of the same + length as the errors. To use limits with inverted axes, + `~.Axes.set_xlim` or `~.Axes.set_ylim` must be called before + `errorbar`. Note the tricky parameter names: setting e.g. + *ylolims* to True means that the y-value is a *lower* limit of the + True value, so, only an *upward*-pointing arrow will be drawn! + + xuplims, yuplims, zuplims : bool, default: False + Same as above, but for controlling the upper limits. + + errorevery : int or (int, int), default: 1 + draws error bars on a subset of the data. *errorevery* =N draws + error bars on the points (x[::N], y[::N], z[::N]). + *errorevery* =(start, N) draws error bars on the points + (x[start::N], y[start::N], z[start::N]). e.g. *errorevery* =(6, 3) + adds error bars to the data at (x[6], x[9], x[12], x[15], ...). + Used to avoid overlapping error bars when two series share x-axis + values. + + Returns + ------- + errlines : list + List of `~mpl_toolkits.mplot3d.art3d.Line3DCollection` instances + each containing an errorbar line. + caplines : list + List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each + containing a capline object. + limmarks : list + List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each + containing a marker with an upper or lower limit. + + Other Parameters + ---------------- + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + **kwargs + All other keyword arguments for styling errorbar lines are passed + `~mpl_toolkits.mplot3d.art3d.Line3DCollection`. + + Examples + -------- + .. plot:: gallery/mplot3d/errorbar3d.py + """ + had_data = self.has_data() + + kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D) + # Drop anything that comes in as None to use the default instead. + kwargs = {k: v for k, v in kwargs.items() if v is not None} + kwargs.setdefault('zorder', 2) + + self._process_unit_info([("x", x), ("y", y), ("z", z)], kwargs, + convert=False) + + # make sure all the args are iterable; use lists not arrays to + # preserve units + x = x if np.iterable(x) else [x] + y = y if np.iterable(y) else [y] + z = z if np.iterable(z) else [z] + + if not len(x) == len(y) == len(z): + raise ValueError("'x', 'y', and 'z' must have the same size") + + everymask = self._errorevery_to_mask(x, errorevery) + + label = kwargs.pop("label", None) + kwargs['label'] = '_nolegend_' + + # Create the main line and determine overall kwargs for child artists. + # We avoid calling self.plot() directly, or self._get_lines(), because + # that would call self._process_unit_info again, and do other indirect + # data processing. + (data_line, base_style), = self._get_lines._plot_args( + self, (x, y) if fmt == '' else (x, y, fmt), kwargs, return_kwargs=True) + art3d.line_2d_to_3d(data_line, zs=z) + + # Do this after creating `data_line` to avoid modifying `base_style`. + if barsabove: + data_line.set_zorder(kwargs['zorder'] - .1) + else: + data_line.set_zorder(kwargs['zorder'] + .1) + + # Add line to plot, or throw it away and use it to determine kwargs. + if fmt.lower() != 'none': + self.add_line(data_line) + else: + data_line = None + # Remove alpha=0 color that _process_plot_format returns. + base_style.pop('color') + + if 'color' not in base_style: + base_style['color'] = 'C0' + if ecolor is None: + ecolor = base_style['color'] + + # Eject any line-specific information from format string, as it's not + # needed for bars or caps. + for key in ['marker', 'markersize', 'markerfacecolor', + 'markeredgewidth', 'markeredgecolor', 'markevery', + 'linestyle', 'fillstyle', 'drawstyle', 'dash_capstyle', + 'dash_joinstyle', 'solid_capstyle', 'solid_joinstyle']: + base_style.pop(key, None) + + # Make the style dict for the line collections (the bars). + eb_lines_style = {**base_style, 'color': ecolor} + + if elinewidth: + eb_lines_style['linewidth'] = elinewidth + elif 'linewidth' in kwargs: + eb_lines_style['linewidth'] = kwargs['linewidth'] + + for key in ('transform', 'alpha', 'zorder', 'rasterized'): + if key in kwargs: + eb_lines_style[key] = kwargs[key] + + # Make the style dict for caps (the "hats"). + eb_cap_style = {**base_style, 'linestyle': 'None'} + if capsize is None: + capsize = mpl.rcParams["errorbar.capsize"] + if capsize > 0: + eb_cap_style['markersize'] = 2. * capsize + if capthick is not None: + eb_cap_style['markeredgewidth'] = capthick + eb_cap_style['color'] = ecolor + + def _apply_mask(arrays, mask): + # Return, for each array in *arrays*, the elements for which *mask* + # is True, without using fancy indexing. + return [[*itertools.compress(array, mask)] for array in arrays] + + def _extract_errs(err, data, lomask, himask): + # For separate +/- error values we need to unpack err + if len(err.shape) == 2: + low_err, high_err = err + else: + low_err, high_err = err, err + + lows = np.where(lomask | ~everymask, data, data - low_err) + highs = np.where(himask | ~everymask, data, data + high_err) + + return lows, highs + + # collect drawn items while looping over the three coordinates + errlines, caplines, limmarks = [], [], [] + + # list of endpoint coordinates, used for auto-scaling + coorderrs = [] + + # define the markers used for errorbar caps and limits below + # the dictionary key is mapped by the `i_xyz` helper dictionary + capmarker = {0: '|', 1: '|', 2: '_'} + i_xyz = {'x': 0, 'y': 1, 'z': 2} + + # Calculate marker size from points to quiver length. Because these are + # not markers, and 3D Axes do not use the normal transform stack, this + # is a bit involved. Since the quiver arrows will change size as the + # scene is rotated, they are given a standard size based on viewing + # them directly in planar form. + quiversize = eb_cap_style.get('markersize', + mpl.rcParams['lines.markersize']) ** 2 + quiversize *= self.figure.dpi / 72 + quiversize = self.transAxes.inverted().transform([ + (0, 0), (quiversize, quiversize)]) + quiversize = np.mean(np.diff(quiversize, axis=0)) + # quiversize is now in Axes coordinates, and to convert back to data + # coordinates, we need to run it through the inverse 3D transform. For + # consistency, this uses a fixed elevation, azimuth, and roll. + with cbook._setattr_cm(self, elev=0, azim=0, roll=0): + invM = np.linalg.inv(self.get_proj()) + # elev=azim=roll=0 produces the Y-Z plane, so quiversize in 2D 'x' is + # 'y' in 3D, hence the 1 index. + quiversize = np.dot(invM, [quiversize, 0, 0, 0])[1] + # Quivers use a fixed 15-degree arrow head, so scale up the length so + # that the size corresponds to the base. In other words, this constant + # corresponds to the equation tan(15) = (base / 2) / (arrow length). + quiversize *= 1.8660254037844388 + eb_quiver_style = {**eb_cap_style, + 'length': quiversize, 'arrow_length_ratio': 1} + eb_quiver_style.pop('markersize', None) + + # loop over x-, y-, and z-direction and draw relevant elements + for zdir, data, err, lolims, uplims in zip( + ['x', 'y', 'z'], [x, y, z], [xerr, yerr, zerr], + [xlolims, ylolims, zlolims], [xuplims, yuplims, zuplims]): + + dir_vector = art3d.get_dir_vector(zdir) + i_zdir = i_xyz[zdir] + + if err is None: + continue + + if not np.iterable(err): + err = [err] * len(data) + + err = np.atleast_1d(err) + + # arrays fine here, they are booleans and hence not units + lolims = np.broadcast_to(lolims, len(data)).astype(bool) + uplims = np.broadcast_to(uplims, len(data)).astype(bool) + + # a nested list structure that expands to (xl,xh),(yl,yh),(zl,zh), + # where x/y/z and l/h correspond to dimensions and low/high + # positions of errorbars in a dimension we're looping over + coorderr = [ + _extract_errs(err * dir_vector[i], coord, lolims, uplims) + for i, coord in enumerate([x, y, z])] + (xl, xh), (yl, yh), (zl, zh) = coorderr + + # draws capmarkers - flat caps orthogonal to the error bars + nolims = ~(lolims | uplims) + if nolims.any() and capsize > 0: + lo_caps_xyz = _apply_mask([xl, yl, zl], nolims & everymask) + hi_caps_xyz = _apply_mask([xh, yh, zh], nolims & everymask) + + # setting '_' for z-caps and '|' for x- and y-caps; + # these markers will rotate as the viewing angle changes + cap_lo = art3d.Line3D(*lo_caps_xyz, ls='', + marker=capmarker[i_zdir], + **eb_cap_style) + cap_hi = art3d.Line3D(*hi_caps_xyz, ls='', + marker=capmarker[i_zdir], + **eb_cap_style) + self.add_line(cap_lo) + self.add_line(cap_hi) + caplines.append(cap_lo) + caplines.append(cap_hi) + + if lolims.any(): + xh0, yh0, zh0 = _apply_mask([xh, yh, zh], lolims & everymask) + self.quiver(xh0, yh0, zh0, *dir_vector, **eb_quiver_style) + if uplims.any(): + xl0, yl0, zl0 = _apply_mask([xl, yl, zl], uplims & everymask) + self.quiver(xl0, yl0, zl0, *-dir_vector, **eb_quiver_style) + + errline = art3d.Line3DCollection(np.array(coorderr).T, + **eb_lines_style) + self.add_collection(errline) + errlines.append(errline) + coorderrs.append(coorderr) + + coorderrs = np.array(coorderrs) + + def _digout_minmax(err_arr, coord_label): + return (np.nanmin(err_arr[:, i_xyz[coord_label], :, :]), + np.nanmax(err_arr[:, i_xyz[coord_label], :, :])) + + minx, maxx = _digout_minmax(coorderrs, 'x') + miny, maxy = _digout_minmax(coorderrs, 'y') + minz, maxz = _digout_minmax(coorderrs, 'z') + self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data) + + # Adapting errorbar containers for 3d case, assuming z-axis points "up" + errorbar_container = mcontainer.ErrorbarContainer( + (data_line, tuple(caplines), tuple(errlines)), + has_xerr=(xerr is not None or yerr is not None), + has_yerr=(zerr is not None), + label=label) + self.containers.append(errorbar_container) + + return errlines, caplines, limmarks + + @_api.make_keyword_only("3.8", "call_axes_locator") + def get_tightbbox(self, renderer=None, call_axes_locator=True, + bbox_extra_artists=None, *, for_layout_only=False): + ret = super().get_tightbbox(renderer, + call_axes_locator=call_axes_locator, + bbox_extra_artists=bbox_extra_artists, + for_layout_only=for_layout_only) + batch = [ret] + if self._axis3don: + for axis in self._axis_map.values(): + if axis.get_visible(): + axis_bb = martist._get_tightbbox_for_layout_only( + axis, renderer) + if axis_bb: + batch.append(axis_bb) + return mtransforms.Bbox.union(batch) + + @_preprocess_data() + def stem(self, x, y, z, *, linefmt='C0-', markerfmt='C0o', basefmt='C3-', + bottom=0, label=None, orientation='z'): + """ + Create a 3D stem plot. + + A stem plot draws lines perpendicular to a baseline, and places markers + at the heads. By default, the baseline is defined by *x* and *y*, and + stems are drawn vertically from *bottom* to *z*. + + Parameters + ---------- + x, y, z : array-like + The positions of the heads of the stems. The stems are drawn along + the *orientation*-direction from the baseline at *bottom* (in the + *orientation*-coordinate) to the heads. By default, the *x* and *y* + positions are used for the baseline and *z* for the head position, + but this can be changed by *orientation*. + + linefmt : str, default: 'C0-' + A string defining the properties of the vertical lines. Usually, + this will be a color or a color and a linestyle: + + ========= ============= + Character Line Style + ========= ============= + ``'-'`` solid line + ``'--'`` dashed line + ``'-.'`` dash-dot line + ``':'`` dotted line + ========= ============= + + Note: While it is technically possible to specify valid formats + other than color or color and linestyle (e.g. 'rx' or '-.'), this + is beyond the intention of the method and will most likely not + result in a reasonable plot. + + markerfmt : str, default: 'C0o' + A string defining the properties of the markers at the stem heads. + + basefmt : str, default: 'C3-' + A format string defining the properties of the baseline. + + bottom : float, default: 0 + The position of the baseline, in *orientation*-coordinates. + + label : str, default: None + The label to use for the stems in legends. + + orientation : {'x', 'y', 'z'}, default: 'z' + The direction along which stems are drawn. + + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER + + Returns + ------- + `.StemContainer` + The container may be treated like a tuple + (*markerline*, *stemlines*, *baseline*) + + Examples + -------- + .. plot:: gallery/mplot3d/stem3d_demo.py + """ + + from matplotlib.container import StemContainer + + had_data = self.has_data() + + _api.check_in_list(['x', 'y', 'z'], orientation=orientation) + + xlim = (np.min(x), np.max(x)) + ylim = (np.min(y), np.max(y)) + zlim = (np.min(z), np.max(z)) + + # Determine the appropriate plane for the baseline and the direction of + # stemlines based on the value of orientation. + if orientation == 'x': + basex, basexlim = y, ylim + basey, baseylim = z, zlim + lines = [[(bottom, thisy, thisz), (thisx, thisy, thisz)] + for thisx, thisy, thisz in zip(x, y, z)] + elif orientation == 'y': + basex, basexlim = x, xlim + basey, baseylim = z, zlim + lines = [[(thisx, bottom, thisz), (thisx, thisy, thisz)] + for thisx, thisy, thisz in zip(x, y, z)] + else: + basex, basexlim = x, xlim + basey, baseylim = y, ylim + lines = [[(thisx, thisy, bottom), (thisx, thisy, thisz)] + for thisx, thisy, thisz in zip(x, y, z)] + + # Determine style for stem lines. + linestyle, linemarker, linecolor = _process_plot_format(linefmt) + if linestyle is None: + linestyle = mpl.rcParams['lines.linestyle'] + + # Plot everything in required order. + baseline, = self.plot(basex, basey, basefmt, zs=bottom, + zdir=orientation, label='_nolegend_') + stemlines = art3d.Line3DCollection( + lines, linestyles=linestyle, colors=linecolor, label='_nolegend_') + self.add_collection(stemlines) + markerline, = self.plot(x, y, z, markerfmt, label='_nolegend_') + + stem_container = StemContainer((markerline, stemlines, baseline), + label=label) + self.add_container(stem_container) + + jx, jy, jz = art3d.juggle_axes(basexlim, baseylim, [bottom, bottom], + orientation) + self.auto_scale_xyz([*jx, *xlim], [*jy, *ylim], [*jz, *zlim], had_data) + + return stem_container + + stem3D = stem + + +def get_test_data(delta=0.05): + """Return a tuple X, Y, Z with a test data set.""" + x = y = np.arange(-3.0, 3.0, delta) + X, Y = np.meshgrid(x, y) + + Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi) + Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) / + (2 * np.pi * 0.5 * 1.5)) + Z = Z2 - Z1 + + X = X * 10 + Y = Y * 10 + Z = Z * 500 + return X, Y, Z diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axis3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axis3d.py new file mode 100644 index 00000000..4c5fa8a9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axis3d.py @@ -0,0 +1,753 @@ +# axis3d.py, original mplot3d version by John Porter +# Created: 23 Sep 2005 +# Parts rewritten by Reinier Heeres <reinier@heeres.eu> + +import inspect + +import numpy as np + +import matplotlib as mpl +from matplotlib import ( + _api, artist, lines as mlines, axis as maxis, patches as mpatches, + transforms as mtransforms, colors as mcolors) +from . import art3d, proj3d + + +def _move_from_center(coord, centers, deltas, axmask=(True, True, True)): + """ + For each coordinate where *axmask* is True, move *coord* away from + *centers* by *deltas*. + """ + coord = np.asarray(coord) + return coord + axmask * np.copysign(1, coord - centers) * deltas + + +def _tick_update_position(tick, tickxs, tickys, labelpos): + """Update tick line and label position and style.""" + + tick.label1.set_position(labelpos) + tick.label2.set_position(labelpos) + tick.tick1line.set_visible(True) + tick.tick2line.set_visible(False) + tick.tick1line.set_linestyle('-') + tick.tick1line.set_marker('') + tick.tick1line.set_data(tickxs, tickys) + tick.gridline.set_data([0], [0]) + + +class Axis(maxis.XAxis): + """An Axis class for the 3D plots.""" + # These points from the unit cube make up the x, y and z-planes + _PLANES = ( + (0, 3, 7, 4), (1, 2, 6, 5), # yz planes + (0, 1, 5, 4), (3, 2, 6, 7), # xz planes + (0, 1, 2, 3), (4, 5, 6, 7), # xy planes + ) + + # Some properties for the axes + _AXINFO = { + 'x': {'i': 0, 'tickdir': 1, 'juggled': (1, 0, 2)}, + 'y': {'i': 1, 'tickdir': 0, 'juggled': (0, 1, 2)}, + 'z': {'i': 2, 'tickdir': 0, 'juggled': (0, 2, 1)}, + } + + def _old_init(self, adir, v_intervalx, d_intervalx, axes, *args, + rotate_label=None, **kwargs): + return locals() + + def _new_init(self, axes, *, rotate_label=None, **kwargs): + return locals() + + def __init__(self, *args, **kwargs): + params = _api.select_matching_signature( + [self._old_init, self._new_init], *args, **kwargs) + if "adir" in params: + _api.warn_deprecated( + "3.6", message=f"The signature of 3D Axis constructors has " + f"changed in %(since)s; the new signature is " + f"{inspect.signature(type(self).__init__)}", pending=True) + if params["adir"] != self.axis_name: + raise ValueError(f"Cannot instantiate {type(self).__name__} " + f"with adir={params['adir']!r}") + axes = params["axes"] + rotate_label = params["rotate_label"] + args = params.get("args", ()) + kwargs = params["kwargs"] + + name = self.axis_name + + self._label_position = 'default' + self._tick_position = 'default' + + # This is a temporary member variable. + # Do not depend on this existing in future releases! + self._axinfo = self._AXINFO[name].copy() + # Common parts + self._axinfo.update({ + 'label': {'va': 'center', 'ha': 'center', + 'rotation_mode': 'anchor'}, + 'color': mpl.rcParams[f'axes3d.{name}axis.panecolor'], + 'tick': { + 'inward_factor': 0.2, + 'outward_factor': 0.1, + }, + }) + + if mpl.rcParams['_internal.classic_mode']: + self._axinfo.update({ + 'axisline': {'linewidth': 0.75, 'color': (0, 0, 0, 1)}, + 'grid': { + 'color': (0.9, 0.9, 0.9, 1), + 'linewidth': 1.0, + 'linestyle': '-', + }, + }) + self._axinfo['tick'].update({ + 'linewidth': { + True: mpl.rcParams['lines.linewidth'], # major + False: mpl.rcParams['lines.linewidth'], # minor + } + }) + else: + self._axinfo.update({ + 'axisline': { + 'linewidth': mpl.rcParams['axes.linewidth'], + 'color': mpl.rcParams['axes.edgecolor'], + }, + 'grid': { + 'color': mpl.rcParams['grid.color'], + 'linewidth': mpl.rcParams['grid.linewidth'], + 'linestyle': mpl.rcParams['grid.linestyle'], + }, + }) + self._axinfo['tick'].update({ + 'linewidth': { + True: ( # major + mpl.rcParams['xtick.major.width'] if name in 'xz' + else mpl.rcParams['ytick.major.width']), + False: ( # minor + mpl.rcParams['xtick.minor.width'] if name in 'xz' + else mpl.rcParams['ytick.minor.width']), + } + }) + + super().__init__(axes, *args, **kwargs) + + # data and viewing intervals for this direction + if "d_intervalx" in params: + self.set_data_interval(*params["d_intervalx"]) + if "v_intervalx" in params: + self.set_view_interval(*params["v_intervalx"]) + self.set_rotate_label(rotate_label) + self._init3d() # Inline after init3d deprecation elapses. + + __init__.__signature__ = inspect.signature(_new_init) + adir = _api.deprecated("3.6", pending=True)( + property(lambda self: self.axis_name)) + + def _init3d(self): + self.line = mlines.Line2D( + xdata=(0, 0), ydata=(0, 0), + linewidth=self._axinfo['axisline']['linewidth'], + color=self._axinfo['axisline']['color'], + antialiased=True) + + # Store dummy data in Polygon object + self.pane = mpatches.Polygon([[0, 0], [0, 1]], closed=False) + self.set_pane_color(self._axinfo['color']) + + self.axes._set_artist_props(self.line) + self.axes._set_artist_props(self.pane) + self.gridlines = art3d.Line3DCollection([]) + self.axes._set_artist_props(self.gridlines) + self.axes._set_artist_props(self.label) + self.axes._set_artist_props(self.offsetText) + # Need to be able to place the label at the correct location + self.label._transform = self.axes.transData + self.offsetText._transform = self.axes.transData + + @_api.deprecated("3.6", pending=True) + def init3d(self): # After deprecation elapses, inline _init3d to __init__. + self._init3d() + + def get_major_ticks(self, numticks=None): + ticks = super().get_major_ticks(numticks) + for t in ticks: + for obj in [ + t.tick1line, t.tick2line, t.gridline, t.label1, t.label2]: + obj.set_transform(self.axes.transData) + return ticks + + def get_minor_ticks(self, numticks=None): + ticks = super().get_minor_ticks(numticks) + for t in ticks: + for obj in [ + t.tick1line, t.tick2line, t.gridline, t.label1, t.label2]: + obj.set_transform(self.axes.transData) + return ticks + + def set_ticks_position(self, position): + """ + Set the ticks position. + + Parameters + ---------- + position : {'lower', 'upper', 'both', 'default', 'none'} + The position of the bolded axis lines, ticks, and tick labels. + """ + if position in ['top', 'bottom']: + _api.warn_deprecated('3.8', name=f'{position=}', + obj_type='argument value', + alternative="'upper' or 'lower'") + return + _api.check_in_list(['lower', 'upper', 'both', 'default', 'none'], + position=position) + self._tick_position = position + + def get_ticks_position(self): + """ + Get the ticks position. + + Returns + ------- + str : {'lower', 'upper', 'both', 'default', 'none'} + The position of the bolded axis lines, ticks, and tick labels. + """ + return self._tick_position + + def set_label_position(self, position): + """ + Set the label position. + + Parameters + ---------- + position : {'lower', 'upper', 'both', 'default', 'none'} + The position of the axis label. + """ + if position in ['top', 'bottom']: + _api.warn_deprecated('3.8', name=f'{position=}', + obj_type='argument value', + alternative="'upper' or 'lower'") + return + _api.check_in_list(['lower', 'upper', 'both', 'default', 'none'], + position=position) + self._label_position = position + + def get_label_position(self): + """ + Get the label position. + + Returns + ------- + str : {'lower', 'upper', 'both', 'default', 'none'} + The position of the axis label. + """ + return self._label_position + + def set_pane_color(self, color, alpha=None): + """ + Set pane color. + + Parameters + ---------- + color : color + Color for axis pane. + alpha : float, optional + Alpha value for axis pane. If None, base it on *color*. + """ + color = mcolors.to_rgba(color, alpha) + self._axinfo['color'] = color + self.pane.set_edgecolor(color) + self.pane.set_facecolor(color) + self.pane.set_alpha(color[-1]) + self.stale = True + + def set_rotate_label(self, val): + """ + Whether to rotate the axis label: True, False or None. + If set to None the label will be rotated if longer than 4 chars. + """ + self._rotate_label = val + self.stale = True + + def get_rotate_label(self, text): + if self._rotate_label is not None: + return self._rotate_label + else: + return len(text) > 4 + + def _get_coord_info(self, renderer): + mins, maxs = np.array([ + self.axes.get_xbound(), + self.axes.get_ybound(), + self.axes.get_zbound(), + ]).T + + # Get the mean value for each bound: + centers = 0.5 * (maxs + mins) + + # Add a small offset between min/max point and the edge of the plot: + deltas = (maxs - mins) / 12 + mins -= 0.25 * deltas + maxs += 0.25 * deltas + + # Project the bounds along the current position of the cube: + bounds = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2] + bounds_proj = self.axes._tunit_cube(bounds, self.axes.M) + + # Determine which one of the parallel planes are higher up: + means_z0 = np.zeros(3) + means_z1 = np.zeros(3) + for i in range(3): + means_z0[i] = np.mean(bounds_proj[self._PLANES[2 * i], 2]) + means_z1[i] = np.mean(bounds_proj[self._PLANES[2 * i + 1], 2]) + highs = means_z0 < means_z1 + + # Special handling for edge-on views + equals = np.abs(means_z0 - means_z1) <= np.finfo(float).eps + if np.sum(equals) == 2: + vertical = np.where(~equals)[0][0] + if vertical == 2: # looking at XY plane + highs = np.array([True, True, highs[2]]) + elif vertical == 1: # looking at XZ plane + highs = np.array([True, highs[1], False]) + elif vertical == 0: # looking at YZ plane + highs = np.array([highs[0], False, False]) + + return mins, maxs, centers, deltas, bounds_proj, highs + + def _get_axis_line_edge_points(self, minmax, maxmin, position=None): + """Get the edge points for the black bolded axis line.""" + # When changing vertical axis some of the axes has to be + # moved to the other plane so it looks the same as if the z-axis + # was the vertical axis. + mb = [minmax, maxmin] # line from origin to nearest corner to camera + mb_rev = mb[::-1] + mm = [[mb, mb_rev, mb_rev], [mb_rev, mb_rev, mb], [mb, mb, mb]] + mm = mm[self.axes._vertical_axis][self._axinfo["i"]] + + juggled = self._axinfo["juggled"] + edge_point_0 = mm[0].copy() # origin point + + if ((position == 'lower' and mm[1][juggled[-1]] < mm[0][juggled[-1]]) or + (position == 'upper' and mm[1][juggled[-1]] > mm[0][juggled[-1]])): + edge_point_0[juggled[-1]] = mm[1][juggled[-1]] + else: + edge_point_0[juggled[0]] = mm[1][juggled[0]] + + edge_point_1 = edge_point_0.copy() + edge_point_1[juggled[1]] = mm[1][juggled[1]] + + return edge_point_0, edge_point_1 + + def _get_all_axis_line_edge_points(self, minmax, maxmin, axis_position=None): + # Determine edge points for the axis lines + edgep1s = [] + edgep2s = [] + position = [] + if axis_position in (None, 'default'): + edgep1, edgep2 = self._get_axis_line_edge_points(minmax, maxmin) + edgep1s = [edgep1] + edgep2s = [edgep2] + position = ['default'] + else: + edgep1_l, edgep2_l = self._get_axis_line_edge_points(minmax, maxmin, + position='lower') + edgep1_u, edgep2_u = self._get_axis_line_edge_points(minmax, maxmin, + position='upper') + if axis_position in ('lower', 'both'): + edgep1s.append(edgep1_l) + edgep2s.append(edgep2_l) + position.append('lower') + if axis_position in ('upper', 'both'): + edgep1s.append(edgep1_u) + edgep2s.append(edgep2_u) + position.append('upper') + return edgep1s, edgep2s, position + + def _get_tickdir(self, position): + """ + Get the direction of the tick. + + Parameters + ---------- + position : str, optional : {'upper', 'lower', 'default'} + The position of the axis. + + Returns + ------- + tickdir : int + Index which indicates which coordinate the tick line will + align with. + """ + _api.check_in_list(('upper', 'lower', 'default'), position=position) + + # TODO: Move somewhere else where it's triggered less: + tickdirs_base = [v["tickdir"] for v in self._AXINFO.values()] # default + elev_mod = np.mod(self.axes.elev + 180, 360) - 180 + azim_mod = np.mod(self.axes.azim, 360) + if position == 'upper': + if elev_mod >= 0: + tickdirs_base = [2, 2, 0] + else: + tickdirs_base = [1, 0, 0] + if 0 <= azim_mod < 180: + tickdirs_base[2] = 1 + elif position == 'lower': + if elev_mod >= 0: + tickdirs_base = [1, 0, 1] + else: + tickdirs_base = [2, 2, 1] + if 0 <= azim_mod < 180: + tickdirs_base[2] = 0 + info_i = [v["i"] for v in self._AXINFO.values()] + + i = self._axinfo["i"] + vert_ax = self.axes._vertical_axis + j = vert_ax - 2 + # default: tickdir = [[1, 2, 1], [2, 2, 0], [1, 0, 0]][vert_ax][i] + tickdir = np.roll(info_i, -j)[np.roll(tickdirs_base, j)][i] + return tickdir + + def active_pane(self, renderer): + mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) + info = self._axinfo + index = info['i'] + if not highs[index]: + loc = mins[index] + plane = self._PLANES[2 * index] + else: + loc = maxs[index] + plane = self._PLANES[2 * index + 1] + xys = np.array([tc[p] for p in plane]) + return xys, loc + + def draw_pane(self, renderer): + """ + Draw pane. + + Parameters + ---------- + renderer : `~matplotlib.backend_bases.RendererBase` subclass + """ + renderer.open_group('pane3d', gid=self.get_gid()) + xys, loc = self.active_pane(renderer) + self.pane.xy = xys[:, :2] + self.pane.draw(renderer) + renderer.close_group('pane3d') + + def _axmask(self): + axmask = [True, True, True] + axmask[self._axinfo["i"]] = False + return axmask + + def _draw_ticks(self, renderer, edgep1, centers, deltas, highs, + deltas_per_point, pos): + ticks = self._update_ticks() + info = self._axinfo + index = info["i"] + + # Draw ticks: + tickdir = self._get_tickdir(pos) + tickdelta = deltas[tickdir] if highs[tickdir] else -deltas[tickdir] + + tick_info = info['tick'] + tick_out = tick_info['outward_factor'] * tickdelta + tick_in = tick_info['inward_factor'] * tickdelta + tick_lw = tick_info['linewidth'] + edgep1_tickdir = edgep1[tickdir] + out_tickdir = edgep1_tickdir + tick_out + in_tickdir = edgep1_tickdir - tick_in + + default_label_offset = 8. # A rough estimate + points = deltas_per_point * deltas + for tick in ticks: + # Get tick line positions + pos = edgep1.copy() + pos[index] = tick.get_loc() + pos[tickdir] = out_tickdir + x1, y1, z1 = proj3d.proj_transform(*pos, self.axes.M) + pos[tickdir] = in_tickdir + x2, y2, z2 = proj3d.proj_transform(*pos, self.axes.M) + + # Get position of label + labeldeltas = (tick.get_pad() + default_label_offset) * points + + pos[tickdir] = edgep1_tickdir + pos = _move_from_center(pos, centers, labeldeltas, self._axmask()) + lx, ly, lz = proj3d.proj_transform(*pos, self.axes.M) + + _tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) + tick.tick1line.set_linewidth(tick_lw[tick._major]) + tick.draw(renderer) + + def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, centers, + highs, pep, dx, dy): + # Get general axis information: + info = self._axinfo + index = info["i"] + juggled = info["juggled"] + tickdir = info["tickdir"] + + # Which of the two edge points do we want to + # use for locating the offset text? + if juggled[2] == 2: + outeredgep = edgep1 + outerindex = 0 + else: + outeredgep = edgep2 + outerindex = 1 + + pos = _move_from_center(outeredgep, centers, labeldeltas, + self._axmask()) + olx, oly, olz = proj3d.proj_transform(*pos, self.axes.M) + self.offsetText.set_text(self.major.formatter.get_offset()) + self.offsetText.set_position((olx, oly)) + angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) + self.offsetText.set_rotation(angle) + # Must set rotation mode to "anchor" so that + # the alignment point is used as the "fulcrum" for rotation. + self.offsetText.set_rotation_mode('anchor') + + # ---------------------------------------------------------------------- + # Note: the following statement for determining the proper alignment of + # the offset text. This was determined entirely by trial-and-error + # and should not be in any way considered as "the way". There are + # still some edge cases where alignment is not quite right, but this + # seems to be more of a geometry issue (in other words, I might be + # using the wrong reference points). + # + # (TT, FF, TF, FT) are the shorthand for the tuple of + # (centpt[tickdir] <= pep[tickdir, outerindex], + # centpt[index] <= pep[index, outerindex]) + # + # Three-letters (e.g., TFT, FTT) are short-hand for the array of bools + # from the variable 'highs'. + # --------------------------------------------------------------------- + centpt = proj3d.proj_transform(*centers, self.axes.M) + if centpt[tickdir] > pep[tickdir, outerindex]: + # if FT and if highs has an even number of Trues + if (centpt[index] <= pep[index, outerindex] + and np.count_nonzero(highs) % 2 == 0): + # Usually, this means align right, except for the FTT case, + # in which offset for axis 1 and 2 are aligned left. + if highs.tolist() == [False, True, True] and index in (1, 2): + align = 'left' + else: + align = 'right' + else: + # The FF case + align = 'left' + else: + # if TF and if highs has an even number of Trues + if (centpt[index] > pep[index, outerindex] + and np.count_nonzero(highs) % 2 == 0): + # Usually mean align left, except if it is axis 2 + align = 'right' if index == 2 else 'left' + else: + # The TT case + align = 'right' + + self.offsetText.set_va('center') + self.offsetText.set_ha(align) + self.offsetText.draw(renderer) + + def _draw_labels(self, renderer, edgep1, edgep2, labeldeltas, centers, dx, dy): + label = self._axinfo["label"] + + # Draw labels + lxyz = 0.5 * (edgep1 + edgep2) + lxyz = _move_from_center(lxyz, centers, labeldeltas, self._axmask()) + tlx, tly, tlz = proj3d.proj_transform(*lxyz, self.axes.M) + self.label.set_position((tlx, tly)) + if self.get_rotate_label(self.label.get_text()): + angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) + self.label.set_rotation(angle) + self.label.set_va(label['va']) + self.label.set_ha(label['ha']) + self.label.set_rotation_mode(label['rotation_mode']) + self.label.draw(renderer) + + @artist.allow_rasterization + def draw(self, renderer): + self.label._transform = self.axes.transData + self.offsetText._transform = self.axes.transData + renderer.open_group("axis3d", gid=self.get_gid()) + + # Get general axis information: + mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) + + # Calculate offset distances + # A rough estimate; points are ambiguous since 3D plots rotate + reltoinches = self.figure.dpi_scale_trans.inverted() + ax_inches = reltoinches.transform(self.axes.bbox.size) + ax_points_estimate = sum(72. * ax_inches) + deltas_per_point = 48 / ax_points_estimate + default_offset = 21. + labeldeltas = (self.labelpad + default_offset) * deltas_per_point * deltas + + # Determine edge points for the axis lines + minmax = np.where(highs, maxs, mins) # "origin" point + maxmin = np.where(~highs, maxs, mins) # "opposite" corner near camera + + for edgep1, edgep2, pos in zip(*self._get_all_axis_line_edge_points( + minmax, maxmin, self._tick_position)): + # Project the edge points along the current position + pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M) + pep = np.asarray(pep) + + # The transAxes transform is used because the Text object + # rotates the text relative to the display coordinate system. + # Therefore, if we want the labels to remain parallel to the + # axis regardless of the aspect ratio, we need to convert the + # edge points of the plane to display coordinates and calculate + # an angle from that. + # TODO: Maybe Text objects should handle this themselves? + dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) - + self.axes.transAxes.transform([pep[0:2, 0]]))[0] + + # Draw the lines + self.line.set_data(pep[0], pep[1]) + self.line.draw(renderer) + + # Draw ticks + self._draw_ticks(renderer, edgep1, centers, deltas, highs, + deltas_per_point, pos) + + # Draw Offset text + self._draw_offset_text(renderer, edgep1, edgep2, labeldeltas, + centers, highs, pep, dx, dy) + + for edgep1, edgep2, pos in zip(*self._get_all_axis_line_edge_points( + minmax, maxmin, self._label_position)): + # See comments above + pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M) + pep = np.asarray(pep) + dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) - + self.axes.transAxes.transform([pep[0:2, 0]]))[0] + + # Draw labels + self._draw_labels(renderer, edgep1, edgep2, labeldeltas, centers, dx, dy) + + renderer.close_group('axis3d') + self.stale = False + + @artist.allow_rasterization + def draw_grid(self, renderer): + if not self.axes._draw_grid: + return + + renderer.open_group("grid3d", gid=self.get_gid()) + + ticks = self._update_ticks() + if len(ticks): + # Get general axis information: + info = self._axinfo + index = info["i"] + + mins, maxs, _, _, _, highs = self._get_coord_info(renderer) + + minmax = np.where(highs, maxs, mins) + maxmin = np.where(~highs, maxs, mins) + + # Grid points where the planes meet + xyz0 = np.tile(minmax, (len(ticks), 1)) + xyz0[:, index] = [tick.get_loc() for tick in ticks] + + # Grid lines go from the end of one plane through the plane + # intersection (at xyz0) to the end of the other plane. The first + # point (0) differs along dimension index-2 and the last (2) along + # dimension index-1. + lines = np.stack([xyz0, xyz0, xyz0], axis=1) + lines[:, 0, index - 2] = maxmin[index - 2] + lines[:, 2, index - 1] = maxmin[index - 1] + self.gridlines.set_segments(lines) + gridinfo = info['grid'] + self.gridlines.set_color(gridinfo['color']) + self.gridlines.set_linewidth(gridinfo['linewidth']) + self.gridlines.set_linestyle(gridinfo['linestyle']) + self.gridlines.do_3d_projection() + self.gridlines.draw(renderer) + + renderer.close_group('grid3d') + + # TODO: Get this to work (more) properly when mplot3d supports the + # transforms framework. + def get_tightbbox(self, renderer=None, *, for_layout_only=False): + # docstring inherited + if not self.get_visible(): + return + # We have to directly access the internal data structures + # (and hope they are up to date) because at draw time we + # shift the ticks and their labels around in (x, y) space + # based on the projection, the current view port, and their + # position in 3D space. If we extend the transforms framework + # into 3D we would not need to do this different book keeping + # than we do in the normal axis + major_locs = self.get_majorticklocs() + minor_locs = self.get_minorticklocs() + + ticks = [*self.get_minor_ticks(len(minor_locs)), + *self.get_major_ticks(len(major_locs))] + view_low, view_high = self.get_view_interval() + if view_low > view_high: + view_low, view_high = view_high, view_low + interval_t = self.get_transform().transform([view_low, view_high]) + + ticks_to_draw = [] + for tick in ticks: + try: + loc_t = self.get_transform().transform(tick.get_loc()) + except AssertionError: + # Transform.transform doesn't allow masked values but + # some scales might make them, so we need this try/except. + pass + else: + if mtransforms._interval_contains_close(interval_t, loc_t): + ticks_to_draw.append(tick) + + ticks = ticks_to_draw + + bb_1, bb_2 = self._get_ticklabel_bboxes(ticks, renderer) + other = [] + + if self.line.get_visible(): + other.append(self.line.get_window_extent(renderer)) + if (self.label.get_visible() and not for_layout_only and + self.label.get_text()): + other.append(self.label.get_window_extent(renderer)) + + return mtransforms.Bbox.union([*bb_1, *bb_2, *other]) + + d_interval = _api.deprecated( + "3.6", alternative="get_data_interval", pending=True)( + property(lambda self: self.get_data_interval(), + lambda self, minmax: self.set_data_interval(*minmax))) + v_interval = _api.deprecated( + "3.6", alternative="get_view_interval", pending=True)( + property(lambda self: self.get_view_interval(), + lambda self, minmax: self.set_view_interval(*minmax))) + + +class XAxis(Axis): + axis_name = "x" + get_view_interval, set_view_interval = maxis._make_getset_interval( + "view", "xy_viewLim", "intervalx") + get_data_interval, set_data_interval = maxis._make_getset_interval( + "data", "xy_dataLim", "intervalx") + + +class YAxis(Axis): + axis_name = "y" + get_view_interval, set_view_interval = maxis._make_getset_interval( + "view", "xy_viewLim", "intervaly") + get_data_interval, set_data_interval = maxis._make_getset_interval( + "data", "xy_dataLim", "intervaly") + + +class ZAxis(Axis): + axis_name = "z" + get_view_interval, set_view_interval = maxis._make_getset_interval( + "view", "zz_viewLim", "intervalx") + get_data_interval, set_data_interval = maxis._make_getset_interval( + "data", "zz_dataLim", "intervalx") diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/proj3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/proj3d.py new file mode 100644 index 00000000..098a7b6f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/proj3d.py @@ -0,0 +1,259 @@ +""" +Various transforms used for by the 3D code +""" + +import numpy as np + +from matplotlib import _api + + +def world_transformation(xmin, xmax, + ymin, ymax, + zmin, zmax, pb_aspect=None): + """ + Produce a matrix that scales homogeneous coords in the specified ranges + to [0, 1], or [0, pb_aspect[i]] if the plotbox aspect ratio is specified. + """ + dx = xmax - xmin + dy = ymax - ymin + dz = zmax - zmin + if pb_aspect is not None: + ax, ay, az = pb_aspect + dx /= ax + dy /= ay + dz /= az + + return np.array([[1/dx, 0, 0, -xmin/dx], + [0, 1/dy, 0, -ymin/dy], + [0, 0, 1/dz, -zmin/dz], + [0, 0, 0, 1]]) + + +@_api.deprecated("3.8") +def rotation_about_vector(v, angle): + """ + Produce a rotation matrix for an angle in radians about a vector. + """ + return _rotation_about_vector(v, angle) + + +def _rotation_about_vector(v, angle): + """ + Produce a rotation matrix for an angle in radians about a vector. + """ + vx, vy, vz = v / np.linalg.norm(v) + s = np.sin(angle) + c = np.cos(angle) + t = 2*np.sin(angle/2)**2 # more numerically stable than t = 1-c + + R = np.array([ + [t*vx*vx + c, t*vx*vy - vz*s, t*vx*vz + vy*s], + [t*vy*vx + vz*s, t*vy*vy + c, t*vy*vz - vx*s], + [t*vz*vx - vy*s, t*vz*vy + vx*s, t*vz*vz + c]]) + + return R + + +def _view_axes(E, R, V, roll): + """ + Get the unit viewing axes in data coordinates. + + Parameters + ---------- + E : 3-element numpy array + The coordinates of the eye/camera. + R : 3-element numpy array + The coordinates of the center of the view box. + V : 3-element numpy array + Unit vector in the direction of the vertical axis. + roll : float + The roll angle in radians. + + Returns + ------- + u : 3-element numpy array + Unit vector pointing towards the right of the screen. + v : 3-element numpy array + Unit vector pointing towards the top of the screen. + w : 3-element numpy array + Unit vector pointing out of the screen. + """ + w = (E - R) + w = w/np.linalg.norm(w) + u = np.cross(V, w) + u = u/np.linalg.norm(u) + v = np.cross(w, u) # Will be a unit vector + + # Save some computation for the default roll=0 + if roll != 0: + # A positive rotation of the camera is a negative rotation of the world + Rroll = _rotation_about_vector(w, -roll) + u = np.dot(Rroll, u) + v = np.dot(Rroll, v) + return u, v, w + + +def _view_transformation_uvw(u, v, w, E): + """ + Return the view transformation matrix. + + Parameters + ---------- + u : 3-element numpy array + Unit vector pointing towards the right of the screen. + v : 3-element numpy array + Unit vector pointing towards the top of the screen. + w : 3-element numpy array + Unit vector pointing out of the screen. + E : 3-element numpy array + The coordinates of the eye/camera. + """ + Mr = np.eye(4) + Mt = np.eye(4) + Mr[:3, :3] = [u, v, w] + Mt[:3, -1] = -E + M = np.dot(Mr, Mt) + return M + + +@_api.deprecated("3.8") +def view_transformation(E, R, V, roll): + """ + Return the view transformation matrix. + + Parameters + ---------- + E : 3-element numpy array + The coordinates of the eye/camera. + R : 3-element numpy array + The coordinates of the center of the view box. + V : 3-element numpy array + Unit vector in the direction of the vertical axis. + roll : float + The roll angle in radians. + """ + u, v, w = _view_axes(E, R, V, roll) + M = _view_transformation_uvw(u, v, w, E) + return M + + +@_api.deprecated("3.8") +def persp_transformation(zfront, zback, focal_length): + return _persp_transformation(zfront, zback, focal_length) + + +def _persp_transformation(zfront, zback, focal_length): + e = focal_length + a = 1 # aspect ratio + b = (zfront+zback)/(zfront-zback) + c = -2*(zfront*zback)/(zfront-zback) + proj_matrix = np.array([[e, 0, 0, 0], + [0, e/a, 0, 0], + [0, 0, b, c], + [0, 0, -1, 0]]) + return proj_matrix + + +@_api.deprecated("3.8") +def ortho_transformation(zfront, zback): + return _ortho_transformation(zfront, zback) + + +def _ortho_transformation(zfront, zback): + # note: w component in the resulting vector will be (zback-zfront), not 1 + a = -(zfront + zback) + b = -(zfront - zback) + proj_matrix = np.array([[2, 0, 0, 0], + [0, 2, 0, 0], + [0, 0, -2, 0], + [0, 0, a, b]]) + return proj_matrix + + +def _proj_transform_vec(vec, M): + vecw = np.dot(M, vec) + w = vecw[3] + # clip here.. + txs, tys, tzs = vecw[0]/w, vecw[1]/w, vecw[2]/w + return txs, tys, tzs + + +def _proj_transform_vec_clip(vec, M): + vecw = np.dot(M, vec) + w = vecw[3] + # clip here. + txs, tys, tzs = vecw[0] / w, vecw[1] / w, vecw[2] / w + tis = (0 <= vecw[0]) & (vecw[0] <= 1) & (0 <= vecw[1]) & (vecw[1] <= 1) + if np.any(tis): + tis = vecw[1] < 1 + return txs, tys, tzs, tis + + +def inv_transform(xs, ys, zs, invM): + """ + Transform the points by the inverse of the projection matrix, *invM*. + """ + vec = _vec_pad_ones(xs, ys, zs) + vecr = np.dot(invM, vec) + if vecr.shape == (4,): + vecr = vecr.reshape((4, 1)) + for i in range(vecr.shape[1]): + if vecr[3][i] != 0: + vecr[:, i] = vecr[:, i] / vecr[3][i] + return vecr[0], vecr[1], vecr[2] + + +def _vec_pad_ones(xs, ys, zs): + return np.array([xs, ys, zs, np.ones_like(xs)]) + + +def proj_transform(xs, ys, zs, M): + """ + Transform the points by the projection matrix *M*. + """ + vec = _vec_pad_ones(xs, ys, zs) + return _proj_transform_vec(vec, M) + + +transform = _api.deprecated( + "3.8", obj_type="function", name="transform", + alternative="proj_transform")(proj_transform) + + +def proj_transform_clip(xs, ys, zs, M): + """ + Transform the points by the projection matrix + and return the clipping result + returns txs, tys, tzs, tis + """ + vec = _vec_pad_ones(xs, ys, zs) + return _proj_transform_vec_clip(vec, M) + + +@_api.deprecated("3.8") +def proj_points(points, M): + return _proj_points(points, M) + + +def _proj_points(points, M): + return np.column_stack(_proj_trans_points(points, M)) + + +@_api.deprecated("3.8") +def proj_trans_points(points, M): + return _proj_trans_points(points, M) + + +def _proj_trans_points(points, M): + xs, ys, zs = zip(*points) + return proj_transform(xs, ys, zs, M) + + +@_api.deprecated("3.8") +def rot_x(V, alpha): + cosa, sina = np.cos(alpha), np.sin(alpha) + M1 = np.array([[1, 0, 0, 0], + [0, cosa, -sina, 0], + [0, sina, cosa, 0], + [0, 0, 0, 1]]) + return np.dot(M1, V) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/__init__.py new file mode 100644 index 00000000..ea4d8ed1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/__init__.py @@ -0,0 +1,10 @@ +from pathlib import Path + + +# Check that the test directories exist +if not (Path(__file__).parent / "baseline_images").exists(): + raise OSError( + 'The baseline image directory does not exist. ' + 'This is most likely because the test data is not installed. ' + 'You may need to install matplotlib from source to get the ' + 'test data.') diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/conftest.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/conftest.py new file mode 100644 index 00000000..61c2de3e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/conftest.py @@ -0,0 +1,2 @@ +from matplotlib.testing.conftest import (mpl_test_settings, # noqa + pytest_configure, pytest_unconfigure) diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_art3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_art3d.py new file mode 100644 index 00000000..4ed48aae --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_art3d.py @@ -0,0 +1,56 @@ +import numpy as np + +import matplotlib.pyplot as plt + +from matplotlib.backend_bases import MouseEvent +from mpl_toolkits.mplot3d.art3d import Line3DCollection + + +def test_scatter_3d_projection_conservation(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + # fix axes3d projection + ax.roll = 0 + ax.elev = 0 + ax.azim = -45 + ax.stale = True + + x = [0, 1, 2, 3, 4] + scatter_collection = ax.scatter(x, x, x) + fig.canvas.draw_idle() + + # Get scatter location on canvas and freeze the data + scatter_offset = scatter_collection.get_offsets() + scatter_location = ax.transData.transform(scatter_offset) + + # Yaw -44 and -46 are enough to produce two set of scatter + # with opposite z-order without moving points too far + for azim in (-44, -46): + ax.azim = azim + ax.stale = True + fig.canvas.draw_idle() + + for i in range(5): + # Create a mouse event used to locate and to get index + # from each dots + event = MouseEvent("button_press_event", fig.canvas, + *scatter_location[i, :]) + contains, ind = scatter_collection.contains(event) + assert contains is True + assert len(ind["ind"]) == 1 + assert ind["ind"][0] == i + + +def test_zordered_error(): + # Smoke test for https://github.com/matplotlib/matplotlib/issues/26497 + lc = [(np.fromiter([0.0, 0.0, 0.0], dtype="float"), + np.fromiter([1.0, 1.0, 1.0], dtype="float"))] + pc = [np.fromiter([0.0, 0.0], dtype="float"), + np.fromiter([0.0, 1.0], dtype="float"), + np.fromiter([1.0, 1.0], dtype="float")] + + fig = plt.figure() + ax = fig.add_subplot(projection="3d") + ax.add_collection(Line3DCollection(lc)) + ax.scatter(*pc, visible=False) + plt.draw() diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_axes3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_axes3d.py new file mode 100644 index 00000000..9cebc8a3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -0,0 +1,2281 @@ +import functools +import itertools +import platform + +import pytest + +from mpl_toolkits.mplot3d import Axes3D, axes3d, proj3d, art3d +import matplotlib as mpl +from matplotlib.backend_bases import (MouseButton, MouseEvent, + NavigationToolbar2) +from matplotlib import cm +from matplotlib import colors as mcolors, patches as mpatch +from matplotlib.testing.decorators import image_comparison, check_figures_equal +from matplotlib.testing.widgets import mock_event +from matplotlib.collections import LineCollection, PolyCollection +from matplotlib.patches import Circle, PathPatch +from matplotlib.path import Path +from matplotlib.text import Text + +import matplotlib.pyplot as plt +import numpy as np + + +mpl3d_image_comparison = functools.partial( + image_comparison, remove_text=True, style='default') + + +def plot_cuboid(ax, scale): + # plot a rectangular cuboid with side lengths given by scale (x, y, z) + r = [0, 1] + pts = itertools.combinations(np.array(list(itertools.product(r, r, r))), 2) + for start, end in pts: + if np.sum(np.abs(start - end)) == r[1] - r[0]: + ax.plot3D(*zip(start*np.array(scale), end*np.array(scale))) + + +@check_figures_equal(extensions=["png"]) +def test_invisible_axes(fig_test, fig_ref): + ax = fig_test.subplots(subplot_kw=dict(projection='3d')) + ax.set_visible(False) + + +@mpl3d_image_comparison(['grid_off.png'], style='mpl20') +def test_grid_off(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.grid(False) + + +@mpl3d_image_comparison(['invisible_ticks_axis.png'], style='mpl20') +def test_invisible_ticks_axis(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.set_xticks([]) + ax.set_yticks([]) + ax.set_zticks([]) + for axis in [ax.xaxis, ax.yaxis, ax.zaxis]: + axis.line.set_visible(False) + + +@mpl3d_image_comparison(['axis_positions.png'], remove_text=False, style='mpl20') +def test_axis_positions(): + positions = ['upper', 'lower', 'both', 'none'] + fig, axs = plt.subplots(2, 2, subplot_kw={'projection': '3d'}) + for ax, pos in zip(axs.flatten(), positions): + for axis in ax.xaxis, ax.yaxis, ax.zaxis: + axis.set_label_position(pos) + axis.set_ticks_position(pos) + title = f'{pos}' + ax.set(xlabel='x', ylabel='y', zlabel='z', title=title) + + +@mpl3d_image_comparison(['aspects.png'], remove_text=False, style='mpl20') +def test_aspects(): + aspects = ('auto', 'equal', 'equalxy', 'equalyz', 'equalxz', 'equal') + _, axs = plt.subplots(2, 3, subplot_kw={'projection': '3d'}) + + for ax in axs.flatten()[0:-1]: + plot_cuboid(ax, scale=[1, 1, 5]) + # plot a cube as well to cover github #25443 + plot_cuboid(axs[1][2], scale=[1, 1, 1]) + + for i, ax in enumerate(axs.flatten()): + ax.set_title(aspects[i]) + ax.set_box_aspect((3, 4, 5)) + ax.set_aspect(aspects[i], adjustable='datalim') + axs[1][2].set_title('equal (cube)') + + +@mpl3d_image_comparison(['aspects_adjust_box.png'], + remove_text=False, style='mpl20') +def test_aspects_adjust_box(): + aspects = ('auto', 'equal', 'equalxy', 'equalyz', 'equalxz') + fig, axs = plt.subplots(1, len(aspects), subplot_kw={'projection': '3d'}, + figsize=(11, 3)) + + for i, ax in enumerate(axs): + plot_cuboid(ax, scale=[4, 3, 5]) + ax.set_title(aspects[i]) + ax.set_aspect(aspects[i], adjustable='box') + + +def test_axes3d_repr(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.set_label('label') + ax.set_title('title') + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') + assert repr(ax) == ( + "<Axes3D: label='label', " + "title={'center': 'title'}, xlabel='x', ylabel='y', zlabel='z'>") + + +@mpl3d_image_comparison(['axes3d_primary_views.png'], style='mpl20') +def test_axes3d_primary_views(): + # (elev, azim, roll) + views = [(90, -90, 0), # XY + (0, -90, 0), # XZ + (0, 0, 0), # YZ + (-90, 90, 0), # -XY + (0, 90, 0), # -XZ + (0, 180, 0)] # -YZ + # When viewing primary planes, draw the two visible axes so they intersect + # at their low values + fig, axs = plt.subplots(2, 3, subplot_kw={'projection': '3d'}) + for i, ax in enumerate(axs.flat): + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') + ax.set_proj_type('ortho') + ax.view_init(elev=views[i][0], azim=views[i][1], roll=views[i][2]) + plt.tight_layout() + + +@mpl3d_image_comparison(['bar3d.png'], style='mpl20') +def test_bar3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]): + xs = np.arange(20) + ys = np.arange(20) + cs = [c] * len(xs) + cs[0] = 'c' + ax.bar(xs, ys, zs=z, zdir='y', align='edge', color=cs, alpha=0.8) + + +def test_bar3d_colors(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + for c in ['red', 'green', 'blue', 'yellow']: + xs = np.arange(len(c)) + ys = np.zeros_like(xs) + zs = np.zeros_like(ys) + # Color names with same length as xs/ys/zs should not be split into + # individual letters. + ax.bar3d(xs, ys, zs, 1, 1, 1, color=c) + + +@mpl3d_image_comparison(['bar3d_shaded.png'], style='mpl20') +def test_bar3d_shaded(): + x = np.arange(4) + y = np.arange(5) + x2d, y2d = np.meshgrid(x, y) + x2d, y2d = x2d.ravel(), y2d.ravel() + z = x2d + y2d + 1 # Avoid triggering bug with zero-depth boxes. + + views = [(30, -60, 0), (30, 30, 30), (-30, 30, -90), (300, -30, 0)] + fig = plt.figure(figsize=plt.figaspect(1 / len(views))) + axs = fig.subplots( + 1, len(views), + subplot_kw=dict(projection='3d') + ) + for ax, (elev, azim, roll) in zip(axs, views): + ax.bar3d(x2d, y2d, x2d * 0, 1, 1, z, shade=True) + ax.view_init(elev=elev, azim=azim, roll=roll) + fig.canvas.draw() + + +@mpl3d_image_comparison(['bar3d_notshaded.png'], style='mpl20') +def test_bar3d_notshaded(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + x = np.arange(4) + y = np.arange(5) + x2d, y2d = np.meshgrid(x, y) + x2d, y2d = x2d.ravel(), y2d.ravel() + z = x2d + y2d + ax.bar3d(x2d, y2d, x2d * 0, 1, 1, z, shade=False) + fig.canvas.draw() + + +def test_bar3d_lightsource(): + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection="3d") + + ls = mcolors.LightSource(azdeg=0, altdeg=90) + + length, width = 3, 4 + area = length * width + + x, y = np.meshgrid(np.arange(length), np.arange(width)) + x = x.ravel() + y = y.ravel() + dz = x + y + + color = [cm.coolwarm(i/area) for i in range(area)] + + collection = ax.bar3d(x=x, y=y, z=0, + dx=1, dy=1, dz=dz, + color=color, shade=True, lightsource=ls) + + # Testing that the custom 90° lightsource produces different shading on + # the top facecolors compared to the default, and that those colors are + # precisely (within floating point rounding errors of 4 ULP) the colors + # from the colormap, due to the illumination parallel to the z-axis. + np.testing.assert_array_max_ulp(color, collection._facecolor3d[1::6], 4) + + +@mpl3d_image_comparison( + ['contour3d.png'], style='mpl20', + tol=0.002 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) +def test_contour3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) + ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) + ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) + ax.axis(xmin=-40, xmax=40, ymin=-40, ymax=40, zmin=-100, zmax=100) + + +@mpl3d_image_comparison(['contour3d_extend3d.png'], style='mpl20') +def test_contour3d_extend3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm, extend3d=True) + ax.set_xlim(-30, 30) + ax.set_ylim(-20, 40) + ax.set_zlim(-80, 80) + + +@mpl3d_image_comparison(['contourf3d.png'], style='mpl20') +def test_contourf3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) + ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) + ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) + ax.set_xlim(-40, 40) + ax.set_ylim(-40, 40) + ax.set_zlim(-100, 100) + + +@mpl3d_image_comparison(['contourf3d_fill.png'], style='mpl20') +def test_contourf3d_fill(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y = np.meshgrid(np.arange(-2, 2, 0.25), np.arange(-2, 2, 0.25)) + Z = X.clip(0, 0) + # This produces holes in the z=0 surface that causes rendering errors if + # the Poly3DCollection is not aware of path code information (issue #4784) + Z[::5, ::5] = 0.1 + ax.contourf(X, Y, Z, offset=0, levels=[-0.1, 0], cmap=cm.coolwarm) + ax.set_xlim(-2, 2) + ax.set_ylim(-2, 2) + ax.set_zlim(-1, 1) + + +@pytest.mark.parametrize('extend, levels', [['both', [2, 4, 6]], + ['min', [2, 4, 6, 8]], + ['max', [0, 2, 4, 6]]]) +@check_figures_equal(extensions=["png"]) +def test_contourf3d_extend(fig_test, fig_ref, extend, levels): + X, Y = np.meshgrid(np.arange(-2, 2, 0.25), np.arange(-2, 2, 0.25)) + # Z is in the range [0, 8] + Z = X**2 + Y**2 + + # Manually set the over/under colors to be the end of the colormap + cmap = mpl.colormaps['viridis'].copy() + cmap.set_under(cmap(0)) + cmap.set_over(cmap(255)) + # Set vmin/max to be the min/max values plotted on the reference image + kwargs = {'vmin': 1, 'vmax': 7, 'cmap': cmap} + + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.contourf(X, Y, Z, levels=[0, 2, 4, 6, 8], **kwargs) + + ax_test = fig_test.add_subplot(projection='3d') + ax_test.contourf(X, Y, Z, levels, extend=extend, **kwargs) + + for ax in [ax_ref, ax_test]: + ax.set_xlim(-2, 2) + ax.set_ylim(-2, 2) + ax.set_zlim(-10, 10) + + +@mpl3d_image_comparison(['tricontour.png'], tol=0.02, style='mpl20') +def test_tricontour(): + fig = plt.figure() + + np.random.seed(19680801) + x = np.random.rand(1000) - 0.5 + y = np.random.rand(1000) - 0.5 + z = -(x**2 + y**2) + + ax = fig.add_subplot(1, 2, 1, projection='3d') + ax.tricontour(x, y, z) + ax = fig.add_subplot(1, 2, 2, projection='3d') + ax.tricontourf(x, y, z) + + +def test_contour3d_1d_input(): + # Check that 1D sequences of different length for {x, y} doesn't error + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + nx, ny = 30, 20 + x = np.linspace(-10, 10, nx) + y = np.linspace(-10, 10, ny) + z = np.random.randint(0, 2, [ny, nx]) + ax.contour(x, y, z, [0.5]) + + +@mpl3d_image_comparison(['lines3d.png'], style='mpl20') +def test_lines3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) + z = np.linspace(-2, 2, 100) + r = z ** 2 + 1 + x = r * np.sin(theta) + y = r * np.cos(theta) + ax.plot(x, y, z) + + +@check_figures_equal(extensions=["png"]) +def test_plot_scalar(fig_test, fig_ref): + ax1 = fig_test.add_subplot(projection='3d') + ax1.plot([1], [1], "o") + ax2 = fig_ref.add_subplot(projection='3d') + ax2.plot(1, 1, "o") + + +def test_invalid_line_data(): + with pytest.raises(RuntimeError, match='x must be'): + art3d.Line3D(0, [], []) + with pytest.raises(RuntimeError, match='y must be'): + art3d.Line3D([], 0, []) + with pytest.raises(RuntimeError, match='z must be'): + art3d.Line3D([], [], 0) + + line = art3d.Line3D([], [], []) + with pytest.raises(RuntimeError, match='x must be'): + line.set_data_3d(0, [], []) + with pytest.raises(RuntimeError, match='y must be'): + line.set_data_3d([], 0, []) + with pytest.raises(RuntimeError, match='z must be'): + line.set_data_3d([], [], 0) + + +@mpl3d_image_comparison(['mixedsubplot.png'], style='mpl20') +def test_mixedsubplots(): + def f(t): + return np.cos(2*np.pi*t) * np.exp(-t) + + t1 = np.arange(0.0, 5.0, 0.1) + t2 = np.arange(0.0, 5.0, 0.02) + + fig = plt.figure(figsize=plt.figaspect(2.)) + ax = fig.add_subplot(2, 1, 1) + ax.plot(t1, f(t1), 'bo', t2, f(t2), 'k--', markerfacecolor='green') + ax.grid(True) + + ax = fig.add_subplot(2, 1, 2, projection='3d') + X, Y = np.meshgrid(np.arange(-5, 5, 0.25), np.arange(-5, 5, 0.25)) + R = np.hypot(X, Y) + Z = np.sin(R) + + ax.plot_surface(X, Y, Z, rcount=40, ccount=40, + linewidth=0, antialiased=False) + + ax.set_zlim3d(-1, 1) + + +@check_figures_equal(extensions=['png']) +def test_tight_layout_text(fig_test, fig_ref): + # text is currently ignored in tight layout. So the order of text() and + # tight_layout() calls should not influence the result. + ax1 = fig_test.add_subplot(projection='3d') + ax1.text(.5, .5, .5, s='some string') + fig_test.tight_layout() + + ax2 = fig_ref.add_subplot(projection='3d') + fig_ref.tight_layout() + ax2.text(.5, .5, .5, s='some string') + + +@mpl3d_image_comparison(['scatter3d.png'], style='mpl20') +def test_scatter3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.scatter(np.arange(10), np.arange(10), np.arange(10), + c='r', marker='o') + x = y = z = np.arange(10, 20) + ax.scatter(x, y, z, c='b', marker='^') + z[-1] = 0 # Check that scatter() copies the data. + # Ensure empty scatters do not break. + ax.scatter([], [], [], c='r', marker='X') + + +@mpl3d_image_comparison(['scatter3d_color.png'], style='mpl20') +def test_scatter3d_color(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + # Check that 'none' color works; these two should overlay to produce the + # same as setting just `color`. + ax.scatter(np.arange(10), np.arange(10), np.arange(10), + facecolor='r', edgecolor='none', marker='o') + ax.scatter(np.arange(10), np.arange(10), np.arange(10), + facecolor='none', edgecolor='r', marker='o') + + ax.scatter(np.arange(10, 20), np.arange(10, 20), np.arange(10, 20), + color='b', marker='s') + + +@mpl3d_image_comparison(['scatter3d_linewidth.png'], style='mpl20') +def test_scatter3d_linewidth(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + # Check that array-like linewidth can be set + ax.scatter(np.arange(10), np.arange(10), np.arange(10), + marker='o', linewidth=np.arange(10)) + + +@check_figures_equal(extensions=['png']) +def test_scatter3d_linewidth_modification(fig_ref, fig_test): + # Changing Path3DCollection linewidths with array-like post-creation + # should work correctly. + ax_test = fig_test.add_subplot(projection='3d') + c = ax_test.scatter(np.arange(10), np.arange(10), np.arange(10), + marker='o') + c.set_linewidths(np.arange(10)) + + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.scatter(np.arange(10), np.arange(10), np.arange(10), marker='o', + linewidths=np.arange(10)) + + +@check_figures_equal(extensions=['png']) +def test_scatter3d_modification(fig_ref, fig_test): + # Changing Path3DCollection properties post-creation should work correctly. + ax_test = fig_test.add_subplot(projection='3d') + c = ax_test.scatter(np.arange(10), np.arange(10), np.arange(10), + marker='o') + c.set_facecolor('C1') + c.set_edgecolor('C2') + c.set_alpha([0.3, 0.7] * 5) + assert c.get_depthshade() + c.set_depthshade(False) + assert not c.get_depthshade() + c.set_sizes(np.full(10, 75)) + c.set_linewidths(3) + + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.scatter(np.arange(10), np.arange(10), np.arange(10), marker='o', + facecolor='C1', edgecolor='C2', alpha=[0.3, 0.7] * 5, + depthshade=False, s=75, linewidths=3) + + +@pytest.mark.parametrize('depthshade', [True, False]) +@check_figures_equal(extensions=['png']) +def test_scatter3d_sorting(fig_ref, fig_test, depthshade): + """Test that marker properties are correctly sorted.""" + + y, x = np.mgrid[:10, :10] + z = np.arange(x.size).reshape(x.shape) + + sizes = np.full(z.shape, 25) + sizes[0::2, 0::2] = 100 + sizes[1::2, 1::2] = 100 + + facecolors = np.full(z.shape, 'C0') + facecolors[:5, :5] = 'C1' + facecolors[6:, :4] = 'C2' + facecolors[6:, 6:] = 'C3' + + edgecolors = np.full(z.shape, 'C4') + edgecolors[1:5, 1:5] = 'C5' + edgecolors[5:9, 1:5] = 'C6' + edgecolors[5:9, 5:9] = 'C7' + + linewidths = np.full(z.shape, 2) + linewidths[0::2, 0::2] = 5 + linewidths[1::2, 1::2] = 5 + + x, y, z, sizes, facecolors, edgecolors, linewidths = [ + a.flatten() + for a in [x, y, z, sizes, facecolors, edgecolors, linewidths] + ] + + ax_ref = fig_ref.add_subplot(projection='3d') + sets = (np.unique(a) for a in [sizes, facecolors, edgecolors, linewidths]) + for s, fc, ec, lw in itertools.product(*sets): + subset = ( + (sizes != s) | + (facecolors != fc) | + (edgecolors != ec) | + (linewidths != lw) + ) + subset = np.ma.masked_array(z, subset, dtype=float) + + # When depth shading is disabled, the colors are passed through as + # single-item lists; this triggers single path optimization. The + # following reshaping is a hack to disable that, since the optimization + # would not occur for the full scatter which has multiple colors. + fc = np.repeat(fc, sum(~subset.mask)) + + ax_ref.scatter(x, y, subset, s=s, fc=fc, ec=ec, lw=lw, alpha=1, + depthshade=depthshade) + + ax_test = fig_test.add_subplot(projection='3d') + ax_test.scatter(x, y, z, s=sizes, fc=facecolors, ec=edgecolors, + lw=linewidths, alpha=1, depthshade=depthshade) + + +@pytest.mark.parametrize('azim', [-50, 130]) # yellow first, blue first +@check_figures_equal(extensions=['png']) +def test_marker_draw_order_data_reversed(fig_test, fig_ref, azim): + """ + Test that the draw order does not depend on the data point order. + + For the given viewing angle at azim=-50, the yellow marker should be in + front. For azim=130, the blue marker should be in front. + """ + x = [-1, 1] + y = [1, -1] + z = [0, 0] + color = ['b', 'y'] + ax = fig_test.add_subplot(projection='3d') + ax.scatter(x, y, z, s=3500, c=color) + ax.view_init(elev=0, azim=azim, roll=0) + ax = fig_ref.add_subplot(projection='3d') + ax.scatter(x[::-1], y[::-1], z[::-1], s=3500, c=color[::-1]) + ax.view_init(elev=0, azim=azim, roll=0) + + +@check_figures_equal(extensions=['png']) +def test_marker_draw_order_view_rotated(fig_test, fig_ref): + """ + Test that the draw order changes with the direction. + + If we rotate *azim* by 180 degrees and exchange the colors, the plot + plot should look the same again. + """ + azim = 130 + x = [-1, 1] + y = [1, -1] + z = [0, 0] + color = ['b', 'y'] + ax = fig_test.add_subplot(projection='3d') + # axis are not exactly invariant under 180 degree rotation -> deactivate + ax.set_axis_off() + ax.scatter(x, y, z, s=3500, c=color) + ax.view_init(elev=0, azim=azim, roll=0) + ax = fig_ref.add_subplot(projection='3d') + ax.set_axis_off() + ax.scatter(x, y, z, s=3500, c=color[::-1]) # color reversed + ax.view_init(elev=0, azim=azim - 180, roll=0) # view rotated by 180 deg + + +@mpl3d_image_comparison(['plot_3d_from_2d.png'], tol=0.015, style='mpl20') +def test_plot_3d_from_2d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + xs = np.arange(0, 5) + ys = np.arange(5, 10) + ax.plot(xs, ys, zs=0, zdir='x') + ax.plot(xs, ys, zs=0, zdir='y') + + +@mpl3d_image_comparison(['surface3d.png'], style='mpl20') +def test_surface3d(): + # Remove this line when this test image is regenerated. + plt.rcParams['pcolormesh.snap'] = False + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X = np.arange(-5, 5, 0.25) + Y = np.arange(-5, 5, 0.25) + X, Y = np.meshgrid(X, Y) + R = np.hypot(X, Y) + Z = np.sin(R) + surf = ax.plot_surface(X, Y, Z, rcount=40, ccount=40, cmap=cm.coolwarm, + lw=0, antialiased=False) + ax.set_zlim(-1.01, 1.01) + fig.colorbar(surf, shrink=0.5, aspect=5) + + +@image_comparison(['surface3d_label_offset_tick_position.png'], style='mpl20') +def test_surface3d_label_offset_tick_position(): + ax = plt.figure().add_subplot(projection="3d") + + x, y = np.mgrid[0:6 * np.pi:0.25, 0:4 * np.pi:0.25] + z = np.sqrt(np.abs(np.cos(x) + np.cos(y))) + + ax.plot_surface(x * 1e5, y * 1e6, z * 1e8, cmap='autumn', cstride=2, rstride=2) + ax.set_xlabel("X label") + ax.set_ylabel("Y label") + ax.set_zlabel("Z label") + + ax.figure.canvas.draw() + + +@mpl3d_image_comparison(['surface3d_shaded.png'], style='mpl20') +def test_surface3d_shaded(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X = np.arange(-5, 5, 0.25) + Y = np.arange(-5, 5, 0.25) + X, Y = np.meshgrid(X, Y) + R = np.sqrt(X ** 2 + Y ** 2) + Z = np.sin(R) + ax.plot_surface(X, Y, Z, rstride=5, cstride=5, + color=[0.25, 1, 0.25], lw=1, antialiased=False) + ax.set_zlim(-1.01, 1.01) + + +@mpl3d_image_comparison(['surface3d_masked.png'], style='mpl20') +def test_surface3d_masked(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + y = [1, 2, 3, 4, 5, 6, 7, 8] + + x, y = np.meshgrid(x, y) + matrix = np.array( + [ + [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [-1, 1, 2, 3, 4, 4, 4, 3, 2, 1, 1], + [-1, -1., 4, 5, 6, 8, 6, 5, 4, 3, -1.], + [-1, -1., 7, 8, 11, 12, 11, 8, 7, -1., -1.], + [-1, -1., 8, 9, 10, 16, 10, 9, 10, 7, -1.], + [-1, -1., -1., 12, 16, 20, 16, 12, 11, -1., -1.], + [-1, -1., -1., -1., 22, 24, 22, 20, 18, -1., -1.], + [-1, -1., -1., -1., -1., 28, 26, 25, -1., -1., -1.], + ] + ) + z = np.ma.masked_less(matrix, 0) + norm = mcolors.Normalize(vmax=z.max(), vmin=z.min()) + colors = mpl.colormaps["plasma"](norm(z)) + ax.plot_surface(x, y, z, facecolors=colors) + ax.view_init(30, -80, 0) + + +@check_figures_equal(extensions=["png"]) +def test_plot_surface_None_arg(fig_test, fig_ref): + x, y = np.meshgrid(np.arange(5), np.arange(5)) + z = x + y + ax_test = fig_test.add_subplot(projection='3d') + ax_test.plot_surface(x, y, z, facecolors=None) + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.plot_surface(x, y, z) + + +@mpl3d_image_comparison(['surface3d_masked_strides.png'], style='mpl20') +def test_surface3d_masked_strides(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + x, y = np.mgrid[-6:6.1:1, -6:6.1:1] + z = np.ma.masked_less(x * y, 2) + + ax.plot_surface(x, y, z, rstride=4, cstride=4) + ax.view_init(60, -45, 0) + + +@mpl3d_image_comparison(['text3d.png'], remove_text=False, style='mpl20') +def test_text3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + zdirs = (None, 'x', 'y', 'z', (1, 1, 0), (1, 1, 1)) + xs = (2, 6, 4, 9, 7, 2) + ys = (6, 4, 8, 7, 2, 2) + zs = (4, 2, 5, 6, 1, 7) + + for zdir, x, y, z in zip(zdirs, xs, ys, zs): + label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir) + ax.text(x, y, z, label, zdir) + + ax.text(1, 1, 1, "red", color='red') + ax.text2D(0.05, 0.95, "2D Text", transform=ax.transAxes) + ax.set_xlim3d(0, 10) + ax.set_ylim3d(0, 10) + ax.set_zlim3d(0, 10) + ax.set_xlabel('X axis') + ax.set_ylabel('Y axis') + ax.set_zlabel('Z axis') + + +@check_figures_equal(extensions=['png']) +def test_text3d_modification(fig_ref, fig_test): + # Modifying the Text position after the fact should work the same as + # setting it directly. + zdirs = (None, 'x', 'y', 'z', (1, 1, 0), (1, 1, 1)) + xs = (2, 6, 4, 9, 7, 2) + ys = (6, 4, 8, 7, 2, 2) + zs = (4, 2, 5, 6, 1, 7) + + ax_test = fig_test.add_subplot(projection='3d') + ax_test.set_xlim3d(0, 10) + ax_test.set_ylim3d(0, 10) + ax_test.set_zlim3d(0, 10) + for zdir, x, y, z in zip(zdirs, xs, ys, zs): + t = ax_test.text(0, 0, 0, f'({x}, {y}, {z}), dir={zdir}') + t.set_position_3d((x, y, z), zdir=zdir) + + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.set_xlim3d(0, 10) + ax_ref.set_ylim3d(0, 10) + ax_ref.set_zlim3d(0, 10) + for zdir, x, y, z in zip(zdirs, xs, ys, zs): + ax_ref.text(x, y, z, f'({x}, {y}, {z}), dir={zdir}', zdir=zdir) + + +@mpl3d_image_comparison(['trisurf3d.png'], tol=0.061, style='mpl20') +def test_trisurf3d(): + n_angles = 36 + n_radii = 8 + radii = np.linspace(0.125, 1.0, n_radii) + angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) + angles[:, 1::2] += np.pi/n_angles + + x = np.append(0, (radii*np.cos(angles)).flatten()) + y = np.append(0, (radii*np.sin(angles)).flatten()) + z = np.sin(-x*y) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2) + + +@mpl3d_image_comparison(['trisurf3d_shaded.png'], tol=0.03, style='mpl20') +def test_trisurf3d_shaded(): + n_angles = 36 + n_radii = 8 + radii = np.linspace(0.125, 1.0, n_radii) + angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) + angles[:, 1::2] += np.pi/n_angles + + x = np.append(0, (radii*np.cos(angles)).flatten()) + y = np.append(0, (radii*np.sin(angles)).flatten()) + z = np.sin(-x*y) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.plot_trisurf(x, y, z, color=[1, 0.5, 0], linewidth=0.2) + + +@mpl3d_image_comparison(['wireframe3d.png'], style='mpl20') +def test_wireframe3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.plot_wireframe(X, Y, Z, rcount=13, ccount=13) + + +@mpl3d_image_comparison(['wireframe3dzerocstride.png'], style='mpl20') +def test_wireframe3dzerocstride(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.plot_wireframe(X, Y, Z, rcount=13, ccount=0) + + +@mpl3d_image_comparison(['wireframe3dzerorstride.png'], style='mpl20') +def test_wireframe3dzerorstride(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + ax.plot_wireframe(X, Y, Z, rstride=0, cstride=10) + + +def test_wireframe3dzerostrideraises(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + with pytest.raises(ValueError): + ax.plot_wireframe(X, Y, Z, rstride=0, cstride=0) + + +def test_mixedsamplesraises(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + X, Y, Z = axes3d.get_test_data(0.05) + with pytest.raises(ValueError): + ax.plot_wireframe(X, Y, Z, rstride=10, ccount=50) + with pytest.raises(ValueError): + ax.plot_surface(X, Y, Z, cstride=50, rcount=10) + + +@mpl3d_image_comparison(['quiver3d.png'], style='mpl20') +def test_quiver3d(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + pivots = ['tip', 'middle', 'tail'] + colors = ['tab:blue', 'tab:orange', 'tab:green'] + for i, (pivot, color) in enumerate(zip(pivots, colors)): + x, y, z = np.meshgrid([-0.5, 0.5], [-0.5, 0.5], [-0.5, 0.5]) + u = -x + v = -y + w = -z + # Offset each set in z direction + z += 2 * i + ax.quiver(x, y, z, u, v, w, length=1, pivot=pivot, color=color) + ax.scatter(x, y, z, color=color) + + ax.set_xlim(-3, 3) + ax.set_ylim(-3, 3) + ax.set_zlim(-1, 5) + + +@check_figures_equal(extensions=["png"]) +def test_quiver3d_empty(fig_test, fig_ref): + fig_ref.add_subplot(projection='3d') + x = y = z = u = v = w = [] + ax = fig_test.add_subplot(projection='3d') + ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True) + + +@mpl3d_image_comparison(['quiver3d_masked.png'], style='mpl20') +def test_quiver3d_masked(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + # Using mgrid here instead of ogrid because masked_where doesn't + # seem to like broadcasting very much... + x, y, z = np.mgrid[-1:0.8:10j, -1:0.8:10j, -1:0.6:3j] + + u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z) + v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z) + w = (2/3)**0.5 * np.cos(np.pi * x) * np.cos(np.pi * y) * np.sin(np.pi * z) + u = np.ma.masked_where((-0.4 < x) & (x < 0.1), u, copy=False) + v = np.ma.masked_where((0.1 < y) & (y < 0.7), v, copy=False) + + ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True) + + +def test_patch_modification(): + fig = plt.figure() + ax = fig.add_subplot(projection="3d") + circle = Circle((0, 0)) + ax.add_patch(circle) + art3d.patch_2d_to_3d(circle) + circle.set_facecolor((1.0, 0.0, 0.0, 1)) + + assert mcolors.same_color(circle.get_facecolor(), (1, 0, 0, 1)) + fig.canvas.draw() + assert mcolors.same_color(circle.get_facecolor(), (1, 0, 0, 1)) + + +@check_figures_equal(extensions=['png']) +def test_patch_collection_modification(fig_test, fig_ref): + # Test that modifying Patch3DCollection properties after creation works. + patch1 = Circle((0, 0), 0.05) + patch2 = Circle((0.1, 0.1), 0.03) + facecolors = np.array([[0., 0.5, 0., 1.], [0.5, 0., 0., 0.5]]) + c = art3d.Patch3DCollection([patch1, patch2], linewidths=3) + + ax_test = fig_test.add_subplot(projection='3d') + ax_test.add_collection3d(c) + c.set_edgecolor('C2') + c.set_facecolor(facecolors) + c.set_alpha(0.7) + assert c.get_depthshade() + c.set_depthshade(False) + assert not c.get_depthshade() + + patch1 = Circle((0, 0), 0.05) + patch2 = Circle((0.1, 0.1), 0.03) + facecolors = np.array([[0., 0.5, 0., 1.], [0.5, 0., 0., 0.5]]) + c = art3d.Patch3DCollection([patch1, patch2], linewidths=3, + edgecolor='C2', facecolor=facecolors, + alpha=0.7, depthshade=False) + + ax_ref = fig_ref.add_subplot(projection='3d') + ax_ref.add_collection3d(c) + + +def test_poly3dcollection_verts_validation(): + poly = [[0, 0, 1], [0, 1, 1], [0, 1, 0], [0, 0, 0]] + with pytest.raises(ValueError, match=r'list of \(N, 3\) array-like'): + art3d.Poly3DCollection(poly) # should be Poly3DCollection([poly]) + + poly = np.array(poly, dtype=float) + with pytest.raises(ValueError, match=r'list of \(N, 3\) array-like'): + art3d.Poly3DCollection(poly) # should be Poly3DCollection([poly]) + + +@mpl3d_image_comparison(['poly3dcollection_closed.png'], style='mpl20') +def test_poly3dcollection_closed(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + poly1 = np.array([[0, 0, 1], [0, 1, 1], [0, 0, 0]], float) + poly2 = np.array([[0, 1, 1], [1, 1, 1], [1, 1, 0]], float) + c1 = art3d.Poly3DCollection([poly1], linewidths=3, edgecolor='k', + facecolor=(0.5, 0.5, 1, 0.5), closed=True) + c2 = art3d.Poly3DCollection([poly2], linewidths=3, edgecolor='k', + facecolor=(1, 0.5, 0.5, 0.5), closed=False) + ax.add_collection3d(c1) + ax.add_collection3d(c2) + + +def test_poly_collection_2d_to_3d_empty(): + poly = PolyCollection([]) + art3d.poly_collection_2d_to_3d(poly) + assert isinstance(poly, art3d.Poly3DCollection) + assert poly.get_paths() == [] + + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + ax.add_artist(poly) + minz = poly.do_3d_projection() + assert np.isnan(minz) + + # Ensure drawing actually works. + fig.canvas.draw() + + +@mpl3d_image_comparison(['poly3dcollection_alpha.png'], style='mpl20') +def test_poly3dcollection_alpha(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + poly1 = np.array([[0, 0, 1], [0, 1, 1], [0, 0, 0]], float) + poly2 = np.array([[0, 1, 1], [1, 1, 1], [1, 1, 0]], float) + c1 = art3d.Poly3DCollection([poly1], linewidths=3, edgecolor='k', + facecolor=(0.5, 0.5, 1), closed=True) + c1.set_alpha(0.5) + c2 = art3d.Poly3DCollection([poly2], linewidths=3, closed=False) + # Post-creation modification should work. + c2.set_facecolor((1, 0.5, 0.5)) + c2.set_edgecolor('k') + c2.set_alpha(0.5) + ax.add_collection3d(c1) + ax.add_collection3d(c2) + + +@mpl3d_image_comparison(['add_collection3d_zs_array.png'], style='mpl20') +def test_add_collection3d_zs_array(): + theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) + z = np.linspace(-2, 2, 100) + r = z**2 + 1 + x = r * np.sin(theta) + y = r * np.cos(theta) + + points = np.column_stack([x, y, z]).reshape(-1, 1, 3) + segments = np.concatenate([points[:-1], points[1:]], axis=1) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + norm = plt.Normalize(0, 2*np.pi) + # 2D LineCollection from x & y values + lc = LineCollection(segments[:, :, :2], cmap='twilight', norm=norm) + lc.set_array(np.mod(theta, 2*np.pi)) + # Add 2D collection at z values to ax + line = ax.add_collection3d(lc, zs=segments[:, :, 2]) + + assert line is not None + + ax.set_xlim(-5, 5) + ax.set_ylim(-4, 6) + ax.set_zlim(-2, 2) + + +@mpl3d_image_comparison(['add_collection3d_zs_scalar.png'], style='mpl20') +def test_add_collection3d_zs_scalar(): + theta = np.linspace(0, 2 * np.pi, 100) + z = 1 + r = z**2 + 1 + x = r * np.sin(theta) + y = r * np.cos(theta) + + points = np.column_stack([x, y]).reshape(-1, 1, 2) + segments = np.concatenate([points[:-1], points[1:]], axis=1) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + norm = plt.Normalize(0, 2*np.pi) + lc = LineCollection(segments, cmap='twilight', norm=norm) + lc.set_array(theta) + line = ax.add_collection3d(lc, zs=z) + + assert line is not None + + ax.set_xlim(-5, 5) + ax.set_ylim(-4, 6) + ax.set_zlim(0, 2) + + +@mpl3d_image_comparison(['axes3d_labelpad.png'], + remove_text=False, style='mpl20') +def test_axes3d_labelpad(): + fig = plt.figure() + ax = fig.add_axes(Axes3D(fig)) + # labelpad respects rcParams + assert ax.xaxis.labelpad == mpl.rcParams['axes.labelpad'] + # labelpad can be set in set_label + ax.set_xlabel('X LABEL', labelpad=10) + assert ax.xaxis.labelpad == 10 + ax.set_ylabel('Y LABEL') + ax.set_zlabel('Z LABEL', labelpad=20) + assert ax.zaxis.labelpad == 20 + assert ax.get_zlabel() == 'Z LABEL' + # or manually + ax.yaxis.labelpad = 20 + ax.zaxis.labelpad = -40 + + # Tick labels also respect tick.pad (also from rcParams) + for i, tick in enumerate(ax.yaxis.get_major_ticks()): + tick.set_pad(tick.get_pad() - i * 5) + + +@mpl3d_image_comparison(['axes3d_cla.png'], remove_text=False, style='mpl20') +def test_axes3d_cla(): + # fixed in pull request 4553 + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='3d') + ax.set_axis_off() + ax.cla() # make sure the axis displayed is 3D (not 2D) + + +@mpl3d_image_comparison(['axes3d_rotated.png'], + remove_text=False, style='mpl20') +def test_axes3d_rotated(): + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='3d') + ax.view_init(90, 45, 0) # look down, rotated. Should be square + + +def test_plotsurface_1d_raises(): + x = np.linspace(0.5, 10, num=100) + y = np.linspace(0.5, 10, num=100) + X, Y = np.meshgrid(x, y) + z = np.random.randn(100) + + fig = plt.figure(figsize=(14, 6)) + ax = fig.add_subplot(1, 2, 1, projection='3d') + with pytest.raises(ValueError): + ax.plot_surface(X, Y, z) + + +def _test_proj_make_M(): + # eye point + E = np.array([1000, -1000, 2000]) + R = np.array([100, 100, 100]) + V = np.array([0, 0, 1]) + roll = 0 + u, v, w = proj3d._view_axes(E, R, V, roll) + viewM = proj3d._view_transformation_uvw(u, v, w, E) + perspM = proj3d._persp_transformation(100, -100, 1) + M = np.dot(perspM, viewM) + return M + + +def test_proj_transform(): + M = _test_proj_make_M() + invM = np.linalg.inv(M) + + xs = np.array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0]) * 300.0 + ys = np.array([0, 0, 1, 1, 0, 0, 0, 1, 1, 0]) * 300.0 + zs = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) * 300.0 + + txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M) + ixs, iys, izs = proj3d.inv_transform(txs, tys, tzs, invM) + + np.testing.assert_almost_equal(ixs, xs) + np.testing.assert_almost_equal(iys, ys) + np.testing.assert_almost_equal(izs, zs) + + +def _test_proj_draw_axes(M, s=1, *args, **kwargs): + xs = [0, s, 0, 0] + ys = [0, 0, s, 0] + zs = [0, 0, 0, s] + txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M) + o, ax, ay, az = zip(txs, tys) + lines = [(o, ax), (o, ay), (o, az)] + + fig, ax = plt.subplots(*args, **kwargs) + linec = LineCollection(lines) + ax.add_collection(linec) + for x, y, t in zip(txs, tys, ['o', 'x', 'y', 'z']): + ax.text(x, y, t) + + return fig, ax + + +@mpl3d_image_comparison(['proj3d_axes_cube.png'], style='mpl20') +def test_proj_axes_cube(): + M = _test_proj_make_M() + + ts = '0 1 2 3 0 4 5 6 7 4'.split() + xs = np.array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0]) * 300.0 + ys = np.array([0, 0, 1, 1, 0, 0, 0, 1, 1, 0]) * 300.0 + zs = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) * 300.0 + + txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M) + + fig, ax = _test_proj_draw_axes(M, s=400) + + ax.scatter(txs, tys, c=tzs) + ax.plot(txs, tys, c='r') + for x, y, t in zip(txs, tys, ts): + ax.text(x, y, t) + + ax.set_xlim(-0.2, 0.2) + ax.set_ylim(-0.2, 0.2) + + +@mpl3d_image_comparison(['proj3d_axes_cube_ortho.png'], style='mpl20') +def test_proj_axes_cube_ortho(): + E = np.array([200, 100, 100]) + R = np.array([0, 0, 0]) + V = np.array([0, 0, 1]) + roll = 0 + u, v, w = proj3d._view_axes(E, R, V, roll) + viewM = proj3d._view_transformation_uvw(u, v, w, E) + orthoM = proj3d._ortho_transformation(-1, 1) + M = np.dot(orthoM, viewM) + + ts = '0 1 2 3 0 4 5 6 7 4'.split() + xs = np.array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0]) * 100 + ys = np.array([0, 0, 1, 1, 0, 0, 0, 1, 1, 0]) * 100 + zs = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) * 100 + + txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M) + + fig, ax = _test_proj_draw_axes(M, s=150) + + ax.scatter(txs, tys, s=300-tzs) + ax.plot(txs, tys, c='r') + for x, y, t in zip(txs, tys, ts): + ax.text(x, y, t) + + ax.set_xlim(-200, 200) + ax.set_ylim(-200, 200) + + +def test_world(): + xmin, xmax = 100, 120 + ymin, ymax = -100, 100 + zmin, zmax = 0.1, 0.2 + M = proj3d.world_transformation(xmin, xmax, ymin, ymax, zmin, zmax) + np.testing.assert_allclose(M, + [[5e-2, 0, 0, -5], + [0, 5e-3, 0, 5e-1], + [0, 0, 1e1, -1], + [0, 0, 0, 1]]) + + +def test_autoscale(): + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + assert ax.get_zscale() == 'linear' + ax.margins(x=0, y=.1, z=.2) + ax.plot([0, 1], [0, 1], [0, 1]) + assert ax.get_w_lims() == (0, 1, -.1, 1.1, -.2, 1.2) + ax.autoscale(False) + ax.set_autoscalez_on(True) + ax.plot([0, 2], [0, 2], [0, 2]) + assert ax.get_w_lims() == (0, 1, -.1, 1.1, -.4, 2.4) + ax.autoscale(axis='x') + ax.plot([0, 2], [0, 2], [0, 2]) + assert ax.get_w_lims() == (0, 2, -.1, 1.1, -.4, 2.4) + + +@pytest.mark.parametrize('axis', ('x', 'y', 'z')) +@pytest.mark.parametrize('auto', (True, False, None)) +def test_unautoscale(axis, auto): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + x = np.arange(100) + y = np.linspace(-0.1, 0.1, 100) + ax.scatter(x, y) + + get_autoscale_on = getattr(ax, f'get_autoscale{axis}_on') + set_lim = getattr(ax, f'set_{axis}lim') + get_lim = getattr(ax, f'get_{axis}lim') + + post_auto = get_autoscale_on() if auto is None else auto + + set_lim((-0.5, 0.5), auto=auto) + assert post_auto == get_autoscale_on() + fig.canvas.draw() + np.testing.assert_array_equal(get_lim(), (-0.5, 0.5)) + + +def test_axes3d_focal_length_checks(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + with pytest.raises(ValueError): + ax.set_proj_type('persp', focal_length=0) + with pytest.raises(ValueError): + ax.set_proj_type('ortho', focal_length=1) + + +@mpl3d_image_comparison(['axes3d_focal_length.png'], + remove_text=False, style='mpl20') +def test_axes3d_focal_length(): + fig, axs = plt.subplots(1, 2, subplot_kw={'projection': '3d'}) + axs[0].set_proj_type('persp', focal_length=np.inf) + axs[1].set_proj_type('persp', focal_length=0.15) + + +@mpl3d_image_comparison(['axes3d_ortho.png'], remove_text=False, style='mpl20') +def test_axes3d_ortho(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.set_proj_type('ortho') + + +@mpl3d_image_comparison(['axes3d_isometric.png'], style='mpl20') +def test_axes3d_isometric(): + from itertools import combinations, product + fig, ax = plt.subplots(subplot_kw=dict( + projection='3d', + proj_type='ortho', + box_aspect=(4, 4, 4) + )) + r = (-1, 1) # stackoverflow.com/a/11156353 + for s, e in combinations(np.array(list(product(r, r, r))), 2): + if abs(s - e).sum() == r[1] - r[0]: + ax.plot3D(*zip(s, e), c='k') + ax.view_init(elev=np.degrees(np.arctan(1. / np.sqrt(2))), azim=-45, roll=0) + ax.grid(True) + + +@pytest.mark.parametrize('value', [np.inf, np.nan]) +@pytest.mark.parametrize(('setter', 'side'), [ + ('set_xlim3d', 'left'), + ('set_xlim3d', 'right'), + ('set_ylim3d', 'bottom'), + ('set_ylim3d', 'top'), + ('set_zlim3d', 'bottom'), + ('set_zlim3d', 'top'), +]) +def test_invalid_axes_limits(setter, side, value): + limit = {side: value} + fig = plt.figure() + obj = fig.add_subplot(projection='3d') + with pytest.raises(ValueError): + getattr(obj, setter)(**limit) + + +class TestVoxels: + @mpl3d_image_comparison(['voxels-simple.png'], style='mpl20') + def test_simple(self): + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + x, y, z = np.indices((5, 4, 3)) + voxels = (x == y) | (y == z) + ax.voxels(voxels) + + @mpl3d_image_comparison(['voxels-edge-style.png'], style='mpl20') + def test_edge_style(self): + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + x, y, z = np.indices((5, 5, 4)) + voxels = ((x - 2)**2 + (y - 2)**2 + (z-1.5)**2) < 2.2**2 + v = ax.voxels(voxels, linewidths=3, edgecolor='C1') + + # change the edge color of one voxel + v[max(v.keys())].set_edgecolor('C2') + + @mpl3d_image_comparison(['voxels-named-colors.png'], style='mpl20') + def test_named_colors(self): + """Test with colors set to a 3D object array of strings.""" + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + x, y, z = np.indices((10, 10, 10)) + voxels = (x == y) | (y == z) + voxels = voxels & ~(x * y * z < 1) + colors = np.full((10, 10, 10), 'C0', dtype=np.object_) + colors[(x < 5) & (y < 5)] = '0.25' + colors[(x + z) < 10] = 'cyan' + ax.voxels(voxels, facecolors=colors) + + @mpl3d_image_comparison(['voxels-rgb-data.png'], style='mpl20') + def test_rgb_data(self): + """Test with colors set to a 4d float array of rgb data.""" + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + x, y, z = np.indices((10, 10, 10)) + voxels = (x == y) | (y == z) + colors = np.zeros((10, 10, 10, 3)) + colors[..., 0] = x / 9 + colors[..., 1] = y / 9 + colors[..., 2] = z / 9 + ax.voxels(voxels, facecolors=colors) + + @mpl3d_image_comparison(['voxels-alpha.png'], style='mpl20') + def test_alpha(self): + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + x, y, z = np.indices((10, 10, 10)) + v1 = x == y + v2 = np.abs(x - y) < 2 + voxels = v1 | v2 + colors = np.zeros((10, 10, 10, 4)) + colors[v2] = [1, 0, 0, 0.5] + colors[v1] = [0, 1, 0, 0.5] + v = ax.voxels(voxels, facecolors=colors) + + assert type(v) is dict + for coord, poly in v.items(): + assert voxels[coord], "faces returned for absent voxel" + assert isinstance(poly, art3d.Poly3DCollection) + + @mpl3d_image_comparison(['voxels-xyz.png'], + tol=0.01, remove_text=False, style='mpl20') + def test_xyz(self): + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + def midpoints(x): + sl = () + for i in range(x.ndim): + x = (x[sl + np.index_exp[:-1]] + + x[sl + np.index_exp[1:]]) / 2.0 + sl += np.index_exp[:] + return x + + # prepare some coordinates, and attach rgb values to each + r, g, b = np.indices((17, 17, 17)) / 16.0 + rc = midpoints(r) + gc = midpoints(g) + bc = midpoints(b) + + # define a sphere about [0.5, 0.5, 0.5] + sphere = (rc - 0.5)**2 + (gc - 0.5)**2 + (bc - 0.5)**2 < 0.5**2 + + # combine the color components + colors = np.zeros(sphere.shape + (3,)) + colors[..., 0] = rc + colors[..., 1] = gc + colors[..., 2] = bc + + # and plot everything + ax.voxels(r, g, b, sphere, + facecolors=colors, + edgecolors=np.clip(2*colors - 0.5, 0, 1), # brighter + linewidth=0.5) + + def test_calling_conventions(self): + x, y, z = np.indices((3, 4, 5)) + filled = np.ones((2, 3, 4)) + + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + + # all the valid calling conventions + for kw in (dict(), dict(edgecolor='k')): + ax.voxels(filled, **kw) + ax.voxels(filled=filled, **kw) + ax.voxels(x, y, z, filled, **kw) + ax.voxels(x, y, z, filled=filled, **kw) + + # duplicate argument + with pytest.raises(TypeError, match='voxels'): + ax.voxels(x, y, z, filled, filled=filled) + # missing arguments + with pytest.raises(TypeError, match='voxels'): + ax.voxels(x, y) + # x, y, z are positional only - this passes them on as attributes of + # Poly3DCollection + with pytest.raises(AttributeError): + ax.voxels(filled=filled, x=x, y=y, z=z) + + +def test_line3d_set_get_data_3d(): + x, y, z = [0, 1], [2, 3], [4, 5] + x2, y2, z2 = [6, 7], [8, 9], [10, 11] + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + lines = ax.plot(x, y, z) + line = lines[0] + np.testing.assert_array_equal((x, y, z), line.get_data_3d()) + line.set_data_3d(x2, y2, z2) + np.testing.assert_array_equal((x2, y2, z2), line.get_data_3d()) + line.set_xdata(x) + line.set_ydata(y) + line.set_3d_properties(zs=z, zdir='z') + np.testing.assert_array_equal((x, y, z), line.get_data_3d()) + line.set_3d_properties(zs=0, zdir='z') + np.testing.assert_array_equal((x, y, np.zeros_like(z)), line.get_data_3d()) + + +@check_figures_equal(extensions=["png"]) +def test_inverted(fig_test, fig_ref): + # Plot then invert. + ax = fig_test.add_subplot(projection="3d") + ax.plot([1, 1, 10, 10], [1, 10, 10, 10], [1, 1, 1, 10]) + ax.invert_yaxis() + # Invert then plot. + ax = fig_ref.add_subplot(projection="3d") + ax.invert_yaxis() + ax.plot([1, 1, 10, 10], [1, 10, 10, 10], [1, 1, 1, 10]) + + +def test_inverted_cla(): + # GitHub PR #5450. Setting autoscale should reset + # axes to be non-inverted. + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + # 1. test that a new axis is not inverted per default + assert not ax.xaxis_inverted() + assert not ax.yaxis_inverted() + assert not ax.zaxis_inverted() + ax.set_xlim(1, 0) + ax.set_ylim(1, 0) + ax.set_zlim(1, 0) + assert ax.xaxis_inverted() + assert ax.yaxis_inverted() + assert ax.zaxis_inverted() + ax.cla() + assert not ax.xaxis_inverted() + assert not ax.yaxis_inverted() + assert not ax.zaxis_inverted() + + +def test_ax3d_tickcolour(): + fig = plt.figure() + ax = Axes3D(fig) + + ax.tick_params(axis='x', colors='red') + ax.tick_params(axis='y', colors='red') + ax.tick_params(axis='z', colors='red') + fig.canvas.draw() + + for tick in ax.xaxis.get_major_ticks(): + assert tick.tick1line._color == 'red' + for tick in ax.yaxis.get_major_ticks(): + assert tick.tick1line._color == 'red' + for tick in ax.zaxis.get_major_ticks(): + assert tick.tick1line._color == 'red' + + +@check_figures_equal(extensions=["png"]) +def test_ticklabel_format(fig_test, fig_ref): + axs = fig_test.subplots(4, 5, subplot_kw={"projection": "3d"}) + for ax in axs.flat: + ax.set_xlim(1e7, 1e7 + 10) + for row, name in zip(axs, ["x", "y", "z", "both"]): + row[0].ticklabel_format( + axis=name, style="plain") + row[1].ticklabel_format( + axis=name, scilimits=(-2, 2)) + row[2].ticklabel_format( + axis=name, useOffset=not mpl.rcParams["axes.formatter.useoffset"]) + row[3].ticklabel_format( + axis=name, useLocale=not mpl.rcParams["axes.formatter.use_locale"]) + row[4].ticklabel_format( + axis=name, + useMathText=not mpl.rcParams["axes.formatter.use_mathtext"]) + + def get_formatters(ax, names): + return [getattr(ax, name).get_major_formatter() for name in names] + + axs = fig_ref.subplots(4, 5, subplot_kw={"projection": "3d"}) + for ax in axs.flat: + ax.set_xlim(1e7, 1e7 + 10) + for row, names in zip( + axs, [["xaxis"], ["yaxis"], ["zaxis"], ["xaxis", "yaxis", "zaxis"]] + ): + for fmt in get_formatters(row[0], names): + fmt.set_scientific(False) + for fmt in get_formatters(row[1], names): + fmt.set_powerlimits((-2, 2)) + for fmt in get_formatters(row[2], names): + fmt.set_useOffset(not mpl.rcParams["axes.formatter.useoffset"]) + for fmt in get_formatters(row[3], names): + fmt.set_useLocale(not mpl.rcParams["axes.formatter.use_locale"]) + for fmt in get_formatters(row[4], names): + fmt.set_useMathText( + not mpl.rcParams["axes.formatter.use_mathtext"]) + + +@check_figures_equal(extensions=["png"]) +def test_quiver3D_smoke(fig_test, fig_ref): + pivot = "middle" + # Make the grid + x, y, z = np.meshgrid( + np.arange(-0.8, 1, 0.2), + np.arange(-0.8, 1, 0.2), + np.arange(-0.8, 1, 0.8) + ) + u = v = w = np.ones_like(x) + + for fig, length in zip((fig_ref, fig_test), (1, 1.0)): + ax = fig.add_subplot(projection="3d") + ax.quiver(x, y, z, u, v, w, length=length, pivot=pivot) + + +@image_comparison(["minor_ticks.png"], style="mpl20") +def test_minor_ticks(): + ax = plt.figure().add_subplot(projection="3d") + ax.set_xticks([0.25], minor=True) + ax.set_xticklabels(["quarter"], minor=True) + ax.set_yticks([0.33], minor=True) + ax.set_yticklabels(["third"], minor=True) + ax.set_zticks([0.50], minor=True) + ax.set_zticklabels(["half"], minor=True) + + +@mpl3d_image_comparison(['errorbar3d_errorevery.png'], style='mpl20') +def test_errorbar3d_errorevery(): + """Tests errorevery functionality for 3D errorbars.""" + t = np.arange(0, 2*np.pi+.1, 0.01) + x, y, z = np.sin(t), np.cos(3*t), np.sin(5*t) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + estep = 15 + i = np.arange(t.size) + zuplims = (i % estep == 0) & (i // estep % 3 == 0) + zlolims = (i % estep == 0) & (i // estep % 3 == 2) + + ax.errorbar(x, y, z, 0.2, zuplims=zuplims, zlolims=zlolims, + errorevery=estep) + + +@mpl3d_image_comparison(['errorbar3d.png'], style='mpl20') +def test_errorbar3d(): + """Tests limits, color styling, and legend for 3D errorbars.""" + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + d = [1, 2, 3, 4, 5] + e = [.5, .5, .5, .5, .5] + ax.errorbar(x=d, y=d, z=d, xerr=e, yerr=e, zerr=e, capsize=3, + zuplims=[False, True, False, True, True], + zlolims=[True, False, False, True, False], + yuplims=True, + ecolor='purple', label='Error lines') + ax.legend() + + +@image_comparison(['stem3d.png'], style='mpl20', tol=0.003) +def test_stem3d(): + fig, axs = plt.subplots(2, 3, figsize=(8, 6), + constrained_layout=True, + subplot_kw={'projection': '3d'}) + + theta = np.linspace(0, 2*np.pi) + x = np.cos(theta - np.pi/2) + y = np.sin(theta - np.pi/2) + z = theta + + for ax, zdir in zip(axs[0], ['x', 'y', 'z']): + ax.stem(x, y, z, orientation=zdir) + ax.set_title(f'orientation={zdir}') + + x = np.linspace(-np.pi/2, np.pi/2, 20) + y = np.ones_like(x) + z = np.cos(x) + + for ax, zdir in zip(axs[1], ['x', 'y', 'z']): + markerline, stemlines, baseline = ax.stem( + x, y, z, + linefmt='C4-.', markerfmt='C1D', basefmt='C2', + orientation=zdir) + ax.set_title(f'orientation={zdir}') + markerline.set(markerfacecolor='none', markeredgewidth=2) + baseline.set_linewidth(3) + + +@image_comparison(["equal_box_aspect.png"], style="mpl20") +def test_equal_box_aspect(): + from itertools import product, combinations + + fig = plt.figure() + ax = fig.add_subplot(projection="3d") + + # Make data + u = np.linspace(0, 2 * np.pi, 100) + v = np.linspace(0, np.pi, 100) + x = np.outer(np.cos(u), np.sin(v)) + y = np.outer(np.sin(u), np.sin(v)) + z = np.outer(np.ones_like(u), np.cos(v)) + + # Plot the surface + ax.plot_surface(x, y, z) + + # draw cube + r = [-1, 1] + for s, e in combinations(np.array(list(product(r, r, r))), 2): + if np.sum(np.abs(s - e)) == r[1] - r[0]: + ax.plot3D(*zip(s, e), color="b") + + # Make axes limits + xyzlim = np.column_stack( + [ax.get_xlim3d(), ax.get_ylim3d(), ax.get_zlim3d()] + ) + XYZlim = [min(xyzlim[0]), max(xyzlim[1])] + ax.set_xlim3d(XYZlim) + ax.set_ylim3d(XYZlim) + ax.set_zlim3d(XYZlim) + ax.axis('off') + ax.set_box_aspect((1, 1, 1)) + + with pytest.raises(ValueError, match="Argument zoom ="): + ax.set_box_aspect((1, 1, 1), zoom=-1) + + +def test_colorbar_pos(): + num_plots = 2 + fig, axs = plt.subplots(1, num_plots, figsize=(4, 5), + constrained_layout=True, + subplot_kw={'projection': '3d'}) + for ax in axs: + p_tri = ax.plot_trisurf(np.random.randn(5), np.random.randn(5), + np.random.randn(5)) + + cbar = plt.colorbar(p_tri, ax=axs, orientation='horizontal') + + fig.canvas.draw() + # check that actually on the bottom + assert cbar.ax.get_position().extents[1] < 0.2 + + +def test_inverted_zaxis(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + assert not ax.zaxis_inverted() + assert ax.get_zlim() == (0, 1) + assert ax.get_zbound() == (0, 1) + + # Change bound + ax.set_zbound((0, 2)) + assert not ax.zaxis_inverted() + assert ax.get_zlim() == (0, 2) + assert ax.get_zbound() == (0, 2) + + # Change invert + ax.invert_zaxis() + assert ax.zaxis_inverted() + assert ax.get_zlim() == (2, 0) + assert ax.get_zbound() == (0, 2) + + # Set upper bound + ax.set_zbound(upper=1) + assert ax.zaxis_inverted() + assert ax.get_zlim() == (1, 0) + assert ax.get_zbound() == (0, 1) + + # Set lower bound + ax.set_zbound(lower=2) + assert ax.zaxis_inverted() + assert ax.get_zlim() == (2, 1) + assert ax.get_zbound() == (1, 2) + + +def test_set_zlim(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + assert ax.get_zlim() == (0, 1) + ax.set_zlim(zmax=2) + assert ax.get_zlim() == (0, 2) + ax.set_zlim(zmin=1) + assert ax.get_zlim() == (1, 2) + + with pytest.raises( + TypeError, match="Cannot pass both 'bottom' and 'zmin'"): + ax.set_zlim(bottom=0, zmin=1) + with pytest.raises( + TypeError, match="Cannot pass both 'top' and 'zmax'"): + ax.set_zlim(top=0, zmax=1) + + +@check_figures_equal(extensions=["png"]) +def test_shared_view(fig_test, fig_ref): + elev, azim, roll = 5, 20, 30 + ax1 = fig_test.add_subplot(131, projection="3d") + ax2 = fig_test.add_subplot(132, projection="3d", shareview=ax1) + ax3 = fig_test.add_subplot(133, projection="3d") + ax3.shareview(ax1) + ax2.view_init(elev=elev, azim=azim, roll=roll, share=True) + + for subplot_num in (131, 132, 133): + ax = fig_ref.add_subplot(subplot_num, projection="3d") + ax.view_init(elev=elev, azim=azim, roll=roll) + + +def test_shared_axes_retick(): + fig = plt.figure() + ax1 = fig.add_subplot(211, projection="3d") + ax2 = fig.add_subplot(212, projection="3d", sharez=ax1) + ax1.plot([0, 1], [0, 1], [0, 2]) + ax2.plot([0, 1], [0, 1], [0, 2]) + ax1.set_zticks([-0.5, 0, 2, 2.5]) + # check that setting ticks on a shared axis is synchronized + assert ax1.get_zlim() == (-0.5, 2.5) + assert ax2.get_zlim() == (-0.5, 2.5) + + +def test_pan(): + """Test mouse panning using the middle mouse button.""" + + def convert_lim(dmin, dmax): + """Convert min/max limits to center and range.""" + center = (dmin + dmax) / 2 + range_ = dmax - dmin + return center, range_ + + ax = plt.figure().add_subplot(projection='3d') + ax.scatter(0, 0, 0) + ax.figure.canvas.draw() + + x_center0, x_range0 = convert_lim(*ax.get_xlim3d()) + y_center0, y_range0 = convert_lim(*ax.get_ylim3d()) + z_center0, z_range0 = convert_lim(*ax.get_zlim3d()) + + # move mouse diagonally to pan along all axis. + ax._button_press( + mock_event(ax, button=MouseButton.MIDDLE, xdata=0, ydata=0)) + ax._on_move( + mock_event(ax, button=MouseButton.MIDDLE, xdata=1, ydata=1)) + + x_center, x_range = convert_lim(*ax.get_xlim3d()) + y_center, y_range = convert_lim(*ax.get_ylim3d()) + z_center, z_range = convert_lim(*ax.get_zlim3d()) + + # Ranges have not changed + assert x_range == pytest.approx(x_range0) + assert y_range == pytest.approx(y_range0) + assert z_range == pytest.approx(z_range0) + + # But center positions have + assert x_center != pytest.approx(x_center0) + assert y_center != pytest.approx(y_center0) + assert z_center != pytest.approx(z_center0) + + +@pytest.mark.parametrize("tool,button,key,expected", + [("zoom", MouseButton.LEFT, None, # zoom in + ((0.00, 0.06), (0.01, 0.07), (0.02, 0.08))), + ("zoom", MouseButton.LEFT, 'x', # zoom in + ((-0.01, 0.10), (-0.03, 0.08), (-0.06, 0.06))), + ("zoom", MouseButton.LEFT, 'y', # zoom in + ((-0.07, 0.04), (-0.03, 0.08), (0.00, 0.11))), + ("zoom", MouseButton.RIGHT, None, # zoom out + ((-0.09, 0.15), (-0.07, 0.17), (-0.06, 0.18))), + ("pan", MouseButton.LEFT, None, + ((-0.70, -0.58), (-1.03, -0.91), (-1.27, -1.15))), + ("pan", MouseButton.LEFT, 'x', + ((-0.96, -0.84), (-0.58, -0.46), (-0.06, 0.06))), + ("pan", MouseButton.LEFT, 'y', + ((0.20, 0.32), (-0.51, -0.39), (-1.27, -1.15)))]) +def test_toolbar_zoom_pan(tool, button, key, expected): + # NOTE: The expected zoom values are rough ballparks of moving in the view + # to make sure we are getting the right direction of motion. + # The specific values can and should change if the zoom movement + # scaling factor gets updated. + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.scatter(0, 0, 0) + fig.canvas.draw() + xlim0, ylim0, zlim0 = ax.get_xlim3d(), ax.get_ylim3d(), ax.get_zlim3d() + + # Mouse from (0, 0) to (1, 1) + d0 = (0, 0) + d1 = (1, 1) + # Convert to screen coordinates ("s"). Events are defined only with pixel + # precision, so round the pixel values, and below, check against the + # corresponding xdata/ydata, which are close but not equal to d0/d1. + s0 = ax.transData.transform(d0).astype(int) + s1 = ax.transData.transform(d1).astype(int) + + # Set up the mouse movements + start_event = MouseEvent( + "button_press_event", fig.canvas, *s0, button, key=key) + stop_event = MouseEvent( + "button_release_event", fig.canvas, *s1, button, key=key) + + tb = NavigationToolbar2(fig.canvas) + if tool == "zoom": + tb.zoom() + tb.press_zoom(start_event) + tb.drag_zoom(stop_event) + tb.release_zoom(stop_event) + else: + tb.pan() + tb.press_pan(start_event) + tb.drag_pan(stop_event) + tb.release_pan(stop_event) + + # Should be close, but won't be exact due to screen integer resolution + xlim, ylim, zlim = expected + assert ax.get_xlim3d() == pytest.approx(xlim, abs=0.01) + assert ax.get_ylim3d() == pytest.approx(ylim, abs=0.01) + assert ax.get_zlim3d() == pytest.approx(zlim, abs=0.01) + + # Ensure that back, forward, and home buttons work + tb.back() + assert ax.get_xlim3d() == pytest.approx(xlim0) + assert ax.get_ylim3d() == pytest.approx(ylim0) + assert ax.get_zlim3d() == pytest.approx(zlim0) + + tb.forward() + assert ax.get_xlim3d() == pytest.approx(xlim, abs=0.01) + assert ax.get_ylim3d() == pytest.approx(ylim, abs=0.01) + assert ax.get_zlim3d() == pytest.approx(zlim, abs=0.01) + + tb.home() + assert ax.get_xlim3d() == pytest.approx(xlim0) + assert ax.get_ylim3d() == pytest.approx(ylim0) + assert ax.get_zlim3d() == pytest.approx(zlim0) + + +@mpl.style.context('default') +@check_figures_equal(extensions=["png"]) +def test_scalarmap_update(fig_test, fig_ref): + + x, y, z = np.array(list(itertools.product(*[np.arange(0, 5, 1), + np.arange(0, 5, 1), + np.arange(0, 5, 1)]))).T + c = x + y + + # test + ax_test = fig_test.add_subplot(111, projection='3d') + sc_test = ax_test.scatter(x, y, z, c=c, s=40, cmap='viridis') + # force a draw + fig_test.canvas.draw() + # mark it as "stale" + sc_test.changed() + + # ref + ax_ref = fig_ref.add_subplot(111, projection='3d') + sc_ref = ax_ref.scatter(x, y, z, c=c, s=40, cmap='viridis') + + +def test_subfigure_simple(): + # smoketest that subfigures can work... + fig = plt.figure() + sf = fig.subfigures(1, 2) + ax = sf[0].add_subplot(1, 1, 1, projection='3d') + ax = sf[1].add_subplot(1, 1, 1, projection='3d', label='other') + + +# Update style when regenerating the test image +@image_comparison(baseline_images=['computed_zorder'], remove_text=True, + extensions=['png'], style=('mpl20')) +def test_computed_zorder(): + fig = plt.figure() + ax1 = fig.add_subplot(221, projection='3d') + ax2 = fig.add_subplot(222, projection='3d') + ax2.computed_zorder = False + + # create a horizontal plane + corners = ((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0)) + for ax in (ax1, ax2): + tri = art3d.Poly3DCollection([corners], + facecolors='white', + edgecolors='black', + zorder=1) + ax.add_collection3d(tri) + + # plot a vector + ax.plot((2, 2), (2, 2), (0, 4), c='red', zorder=2) + + # plot some points + ax.scatter((3, 3), (1, 3), (1, 3), c='red', zorder=10) + + ax.set_xlim((0, 5.0)) + ax.set_ylim((0, 5.0)) + ax.set_zlim((0, 2.5)) + + ax3 = fig.add_subplot(223, projection='3d') + ax4 = fig.add_subplot(224, projection='3d') + ax4.computed_zorder = False + + dim = 10 + X, Y = np.meshgrid((-dim, dim), (-dim, dim)) + Z = np.zeros((2, 2)) + + angle = 0.5 + X2, Y2 = np.meshgrid((-dim, dim), (0, dim)) + Z2 = Y2 * angle + X3, Y3 = np.meshgrid((-dim, dim), (-dim, 0)) + Z3 = Y3 * angle + + r = 7 + M = 1000 + th = np.linspace(0, 2 * np.pi, M) + x, y, z = r * np.cos(th), r * np.sin(th), angle * r * np.sin(th) + for ax in (ax3, ax4): + ax.plot_surface(X2, Y3, Z3, + color='blue', + alpha=0.5, + linewidth=0, + zorder=-1) + ax.plot(x[y < 0], y[y < 0], z[y < 0], + lw=5, + linestyle='--', + color='green', + zorder=0) + + ax.plot_surface(X, Y, Z, + color='red', + alpha=0.5, + linewidth=0, + zorder=1) + + ax.plot(r * np.sin(th), r * np.cos(th), np.zeros(M), + lw=5, + linestyle='--', + color='black', + zorder=2) + + ax.plot_surface(X2, Y2, Z2, + color='blue', + alpha=0.5, + linewidth=0, + zorder=3) + + ax.plot(x[y > 0], y[y > 0], z[y > 0], lw=5, + linestyle='--', + color='green', + zorder=4) + ax.view_init(elev=20, azim=-20, roll=0) + ax.axis('off') + + +def test_format_coord(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + x = np.arange(10) + ax.plot(x, np.sin(x)) + xv = 0.1 + yv = 0.1 + fig.canvas.draw() + assert ax.format_coord(xv, yv) == 'x=10.5227, y pane=1.0417, z=0.1444' + + # Modify parameters + ax.view_init(roll=30, vertical_axis="y") + fig.canvas.draw() + assert ax.format_coord(xv, yv) == 'x pane=9.1875, y=0.9761, z=0.1291' + + # Reset parameters + ax.view_init() + fig.canvas.draw() + assert ax.format_coord(xv, yv) == 'x=10.5227, y pane=1.0417, z=0.1444' + + # Check orthographic projection + ax.set_proj_type('ortho') + fig.canvas.draw() + assert ax.format_coord(xv, yv) == 'x=10.8869, y pane=1.0417, z=0.1528' + + # Check non-default perspective projection + ax.set_proj_type('persp', focal_length=0.1) + fig.canvas.draw() + assert ax.format_coord(xv, yv) == 'x=9.0620, y pane=1.0417, z=0.1110' + + +def test_get_axis_position(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + x = np.arange(10) + ax.plot(x, np.sin(x)) + fig.canvas.draw() + assert ax.get_axis_position() == (False, True, False) + + +def test_margins(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.margins(0.2) + assert ax.margins() == (0.2, 0.2, 0.2) + ax.margins(0.1, 0.2, 0.3) + assert ax.margins() == (0.1, 0.2, 0.3) + ax.margins(x=0) + assert ax.margins() == (0, 0.2, 0.3) + ax.margins(y=0.1) + assert ax.margins() == (0, 0.1, 0.3) + ax.margins(z=0) + assert ax.margins() == (0, 0.1, 0) + + +@pytest.mark.parametrize('err, args, kwargs, match', ( + (ValueError, (-1,), {}, r'margin must be greater than -0\.5'), + (ValueError, (1, -1, 1), {}, r'margin must be greater than -0\.5'), + (ValueError, (1, 1, -1), {}, r'margin must be greater than -0\.5'), + (ValueError, tuple(), {'x': -1}, r'margin must be greater than -0\.5'), + (ValueError, tuple(), {'y': -1}, r'margin must be greater than -0\.5'), + (ValueError, tuple(), {'z': -1}, r'margin must be greater than -0\.5'), + (TypeError, (1, ), {'x': 1}, + 'Cannot pass both positional and keyword'), + (TypeError, (1, ), {'x': 1, 'y': 1, 'z': 1}, + 'Cannot pass both positional and keyword'), + (TypeError, (1, ), {'x': 1, 'y': 1}, + 'Cannot pass both positional and keyword'), + (TypeError, (1, 1), {}, 'Must pass a single positional argument for'), +)) +def test_margins_errors(err, args, kwargs, match): + with pytest.raises(err, match=match): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.margins(*args, **kwargs) + + +@check_figures_equal(extensions=["png"]) +def test_text_3d(fig_test, fig_ref): + ax = fig_ref.add_subplot(projection="3d") + txt = Text(0.5, 0.5, r'Foo bar $\int$') + art3d.text_2d_to_3d(txt, z=1) + ax.add_artist(txt) + assert txt.get_position_3d() == (0.5, 0.5, 1) + + ax = fig_test.add_subplot(projection="3d") + t3d = art3d.Text3D(0.5, 0.5, 1, r'Foo bar $\int$') + ax.add_artist(t3d) + assert t3d.get_position_3d() == (0.5, 0.5, 1) + + +def test_draw_single_lines_from_Nx1(): + # Smoke test for GH#23459 + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.plot([[0], [1]], [[0], [1]], [[0], [1]]) + + +@check_figures_equal(extensions=["png"]) +def test_pathpatch_3d(fig_test, fig_ref): + ax = fig_ref.add_subplot(projection="3d") + path = Path.unit_rectangle() + patch = PathPatch(path) + art3d.pathpatch_2d_to_3d(patch, z=(0, 0.5, 0.7, 1, 0), zdir='y') + ax.add_artist(patch) + + ax = fig_test.add_subplot(projection="3d") + pp3d = art3d.PathPatch3D(path, zs=(0, 0.5, 0.7, 1, 0), zdir='y') + ax.add_artist(pp3d) + + +@image_comparison(baseline_images=['scatter_spiral.png'], + remove_text=True, + style='mpl20') +def test_scatter_spiral(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + th = np.linspace(0, 2 * np.pi * 6, 256) + sc = ax.scatter(np.sin(th), np.cos(th), th, s=(1 + th * 5), c=th ** 2) + + # force at least 1 draw! + fig.canvas.draw() + + +def test_Poly3DCollection_get_facecolor(): + # Smoke test to see that get_facecolor does not raise + # See GH#4067 + y, x = np.ogrid[1:10:100j, 1:10:100j] + z2 = np.cos(x) ** 3 - np.sin(y) ** 2 + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + r = ax.plot_surface(x, y, z2, cmap='hot') + r.get_facecolor() + + +def test_Poly3DCollection_get_edgecolor(): + # Smoke test to see that get_edgecolor does not raise + # See GH#4067 + y, x = np.ogrid[1:10:100j, 1:10:100j] + z2 = np.cos(x) ** 3 - np.sin(y) ** 2 + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + r = ax.plot_surface(x, y, z2, cmap='hot') + r.get_edgecolor() + + +@pytest.mark.parametrize( + "vertical_axis, proj_expected, axis_lines_expected, tickdirs_expected", + [ + ( + "z", + [ + [0.0, 1.142857, 0.0, -0.571429], + [0.0, 0.0, 0.857143, -0.428571], + [0.0, 0.0, 0.0, -10.0], + [-1.142857, 0.0, 0.0, 10.571429], + ], + [ + ([0.05617978, 0.06329114], [-0.04213483, -0.04746835]), + ([-0.06329114, 0.06329114], [-0.04746835, -0.04746835]), + ([-0.06329114, -0.06329114], [-0.04746835, 0.04746835]), + ], + [1, 0, 0], + ), + ( + "y", + [ + [1.142857, 0.0, 0.0, -0.571429], + [0.0, 0.857143, 0.0, -0.428571], + [0.0, 0.0, 0.0, -10.0], + [0.0, 0.0, -1.142857, 10.571429], + ], + [ + ([-0.06329114, 0.06329114], [0.04746835, 0.04746835]), + ([0.06329114, 0.06329114], [-0.04746835, 0.04746835]), + ([-0.05617978, -0.06329114], [0.04213483, 0.04746835]), + ], + [2, 2, 0], + ), + ( + "x", + [ + [0.0, 0.0, 1.142857, -0.571429], + [0.857143, 0.0, 0.0, -0.428571], + [0.0, 0.0, 0.0, -10.0], + [0.0, -1.142857, 0.0, 10.571429], + ], + [ + ([-0.06329114, -0.06329114], [0.04746835, -0.04746835]), + ([0.06329114, 0.05617978], [0.04746835, 0.04213483]), + ([0.06329114, -0.06329114], [0.04746835, 0.04746835]), + ], + [1, 2, 1], + ), + ], +) +def test_view_init_vertical_axis( + vertical_axis, proj_expected, axis_lines_expected, tickdirs_expected +): + """ + Test the actual projection, axis lines and ticks matches expected values. + + Parameters + ---------- + vertical_axis : str + Axis to align vertically. + proj_expected : ndarray + Expected values from ax.get_proj(). + axis_lines_expected : tuple of arrays + Edgepoints of the axis line. Expected values retrieved according + to ``ax.get_[xyz]axis().line.get_data()``. + tickdirs_expected : list of int + indexes indicating which axis to create a tick line along. + """ + rtol = 2e-06 + ax = plt.subplot(1, 1, 1, projection="3d") + ax.view_init(elev=0, azim=0, roll=0, vertical_axis=vertical_axis) + ax.figure.canvas.draw() + + # Assert the projection matrix: + proj_actual = ax.get_proj() + np.testing.assert_allclose(proj_expected, proj_actual, rtol=rtol) + + for i, axis in enumerate([ax.get_xaxis(), ax.get_yaxis(), ax.get_zaxis()]): + # Assert black lines are correctly aligned: + axis_line_expected = axis_lines_expected[i] + axis_line_actual = axis.line.get_data() + np.testing.assert_allclose(axis_line_expected, axis_line_actual, + rtol=rtol) + + # Assert ticks are correctly aligned: + tickdir_expected = tickdirs_expected[i] + tickdir_actual = axis._get_tickdir('default') + np.testing.assert_array_equal(tickdir_expected, tickdir_actual) + + +@image_comparison(baseline_images=['arc_pathpatch.png'], + remove_text=True, + style='mpl20') +def test_arc_pathpatch(): + ax = plt.subplot(1, 1, 1, projection="3d") + a = mpatch.Arc((0.5, 0.5), width=0.5, height=0.9, + angle=20, theta1=10, theta2=130) + ax.add_patch(a) + art3d.pathpatch_2d_to_3d(a, z=0, zdir='z') + + +@image_comparison(baseline_images=['panecolor_rcparams.png'], + remove_text=True, + style='mpl20') +def test_panecolor_rcparams(): + with plt.rc_context({'axes3d.xaxis.panecolor': 'r', + 'axes3d.yaxis.panecolor': 'g', + 'axes3d.zaxis.panecolor': 'b'}): + fig = plt.figure(figsize=(1, 1)) + fig.add_subplot(projection='3d') + + +@check_figures_equal(extensions=["png"]) +def test_mutating_input_arrays_y_and_z(fig_test, fig_ref): + """ + Test to see if the `z` axis does not get mutated + after a call to `Axes3D.plot` + + test cases came from GH#8990 + """ + ax1 = fig_test.add_subplot(111, projection='3d') + x = [1, 2, 3] + y = [0.0, 0.0, 0.0] + z = [0.0, 0.0, 0.0] + ax1.plot(x, y, z, 'o-') + + # mutate y,z to get a nontrivial line + y[:] = [1, 2, 3] + z[:] = [1, 2, 3] + + # draw the same plot without mutating x and y + ax2 = fig_ref.add_subplot(111, projection='3d') + x = [1, 2, 3] + y = [0.0, 0.0, 0.0] + z = [0.0, 0.0, 0.0] + ax2.plot(x, y, z, 'o-') + + +def test_scatter_masked_color(): + """ + Test color parameter usage with non-finite coordinate arrays. + + GH#26236 + """ + + x = [np.nan, 1, 2, 1] + y = [0, np.inf, 2, 1] + z = [0, 1, -np.inf, 1] + colors = [ + [0.0, 0.0, 0.0, 1], + [0.0, 0.0, 0.0, 1], + [0.0, 0.0, 0.0, 1], + [0.0, 0.0, 0.0, 1] + ] + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + path3d = ax.scatter(x, y, z, color=colors) + + # Assert sizes' equality + assert len(path3d.get_offsets()) ==\ + len(super(type(path3d), path3d).get_facecolors()) + + +@mpl3d_image_comparison(['surface3d_zsort_inf.png'], style='mpl20') +def test_surface3d_zsort_inf(): + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + + x, y = np.mgrid[-2:2:0.1, -2:2:0.1] + z = np.sin(x)**2 + np.cos(y)**2 + z[x.shape[0] // 2:, x.shape[1] // 2:] = np.inf + + ax.plot_surface(x, y, z, cmap='jet') + ax.view_init(elev=45, azim=145) + + +def test_Poly3DCollection_init_value_error(): + # smoke test to ensure the input check works + # GH#26420 + with pytest.raises(ValueError, + match='You must provide facecolors, edgecolors, ' + 'or both for shade to work.'): + poly = np.array([[0, 0, 1], [0, 1, 1], [0, 0, 0]], float) + c = art3d.Poly3DCollection([poly], shade=True) + + +def test_ndarray_color_kwargs_value_error(): + # smoke test + # ensures ndarray can be passed to color in kwargs for 3d projection plot + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + ax.scatter(1, 0, 0, color=np.array([0, 0, 0, 1])) + fig.canvas.draw() diff --git a/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_legend3d.py b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_legend3d.py new file mode 100644 index 00000000..fe0e99b8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mpl_toolkits/mplot3d/tests/test_legend3d.py @@ -0,0 +1,117 @@ +import numpy as np + +import matplotlib as mpl +from matplotlib.colors import same_color +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import art3d + + +# Update style when regenerating the test image +@image_comparison(['legend_plot.png'], remove_text=True, style=('mpl20')) +def test_legend_plot(): + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + x = np.arange(10) + ax.plot(x, 5 - x, 'o', zdir='y', label='z=1') + ax.plot(x, x - 5, 'o', zdir='y', label='z=-1') + ax.legend() + + +# Update style when regenerating the test image +@image_comparison(['legend_bar.png'], remove_text=True, style=('mpl20')) +def test_legend_bar(): + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + x = np.arange(10) + b1 = ax.bar(x, x, zdir='y', align='edge', color='m') + b2 = ax.bar(x, x[::-1], zdir='x', align='edge', color='g') + ax.legend([b1[0], b2[0]], ['up', 'down']) + + +# Update style when regenerating the test image +@image_comparison(['fancy.png'], remove_text=True, style=('mpl20')) +def test_fancy(): + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + ax.plot(np.arange(10), np.full(10, 5), np.full(10, 5), 'o--', label='line') + ax.scatter(np.arange(10), np.arange(10, 0, -1), label='scatter') + ax.errorbar(np.full(10, 5), np.arange(10), np.full(10, 10), + xerr=0.5, zerr=0.5, label='errorbar') + ax.legend(loc='lower left', ncols=2, title='My legend', numpoints=1) + + +def test_linecollection_scaled_dashes(): + lines1 = [[(0, .5), (.5, 1)], [(.3, .6), (.2, .2)]] + lines2 = [[[0.7, .2], [.8, .4]], [[.5, .7], [.6, .1]]] + lines3 = [[[0.6, .2], [.8, .4]], [[.5, .7], [.1, .1]]] + lc1 = art3d.Line3DCollection(lines1, linestyles="--", lw=3) + lc2 = art3d.Line3DCollection(lines2, linestyles="-.") + lc3 = art3d.Line3DCollection(lines3, linestyles=":", lw=.5) + + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + ax.add_collection(lc1) + ax.add_collection(lc2) + ax.add_collection(lc3) + + leg = ax.legend([lc1, lc2, lc3], ['line1', 'line2', 'line 3']) + h1, h2, h3 = leg.legend_handles + + for oh, lh in zip((lc1, lc2, lc3), (h1, h2, h3)): + assert oh.get_linestyles()[0] == lh._dash_pattern + + +def test_handlerline3d(): + # Test marker consistency for monolithic Line3D legend handler. + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + ax.scatter([0, 1], [0, 1], marker="v") + handles = [art3d.Line3D([0], [0], [0], marker="v")] + leg = ax.legend(handles, ["Aardvark"], numpoints=1) + assert handles[0].get_marker() == leg.legend_handles[0].get_marker() + + +def test_contour_legend_elements(): + x, y = np.mgrid[1:10, 1:10] + h = x * y + colors = ['blue', '#00FF00', 'red'] + + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + cs = ax.contour(x, y, h, levels=[10, 30, 50], colors=colors, extend='both') + + artists, labels = cs.legend_elements() + assert labels == ['$x = 10.0$', '$x = 30.0$', '$x = 50.0$'] + assert all(isinstance(a, mpl.lines.Line2D) for a in artists) + assert all(same_color(a.get_color(), c) + for a, c in zip(artists, colors)) + + +def test_contourf_legend_elements(): + x, y = np.mgrid[1:10, 1:10] + h = x * y + + fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) + cs = ax.contourf(x, y, h, levels=[10, 30, 50], + colors=['#FFFF00', '#FF00FF', '#00FFFF'], + extend='both') + cs.cmap.set_over('red') + cs.cmap.set_under('blue') + cs.changed() + artists, labels = cs.legend_elements() + assert labels == ['$x \\leq -1e+250s$', + '$10.0 < x \\leq 30.0$', + '$30.0 < x \\leq 50.0$', + '$x > 1e+250s$'] + expected_colors = ('blue', '#FFFF00', '#FF00FF', 'red') + assert all(isinstance(a, mpl.patches.Rectangle) for a in artists) + assert all(same_color(a.get_facecolor(), c) + for a, c in zip(artists, expected_colors)) + + +def test_legend_Poly3dCollection(): + + verts = np.asarray([[0, 0, 0], [0, 1, 1], [1, 0, 1]]) + mesh = art3d.Poly3DCollection([verts], label="surface") + + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + mesh.set_edgecolor('k') + handle = ax.add_collection3d(mesh) + leg = ax.legend() + assert (leg.legend_handles[0].get_facecolor() + == handle.get_facecolor()).all() diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/LICENSE new file mode 100644 index 00000000..bdb7786b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/LICENSE @@ -0,0 +1,27 @@ +Mypy extensions are licensed under the terms of the MIT license, reproduced below. + += = = = = + +The MIT License + +Copyright (c) 2016-2017 Jukka Lehtosalo and contributors + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + += = = = = diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/METADATA new file mode 100644 index 00000000..e58c7ba3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/METADATA @@ -0,0 +1,29 @@ +Metadata-Version: 2.1 +Name: mypy-extensions +Version: 1.0.0 +Summary: Type system extensions for programs checked with the mypy type checker. +Home-page: https://github.com/python/mypy_extensions +Author: The mypy developers +Author-email: jukka.lehtosalo@iki.fi +License: MIT License +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Topic :: Software Development +Requires-Python: >=3.5 +License-File: LICENSE + +Mypy Extensions +=============== + +The "mypy_extensions" module defines extensions to the standard "typing" module +that are supported by the mypy type checker and the mypyc compiler. diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/RECORD new file mode 100644 index 00000000..ea3be936 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/RECORD @@ -0,0 +1,8 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/mypy_extensions.cpython-39.pyc,, +mypy_extensions-1.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +mypy_extensions-1.0.0.dist-info/LICENSE,sha256=pQRQ2h1TzXd7gM7XfFj_lqvgzNh5cGvRQsPsIOJF8LQ,1204 +mypy_extensions-1.0.0.dist-info/METADATA,sha256=YX1g3_sAgmoi9WYhFNgRHQL6Kf-x7GfjnWgUCE73VIY,1134 +mypy_extensions-1.0.0.dist-info/RECORD,, +mypy_extensions-1.0.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92 +mypy_extensions-1.0.0.dist-info/top_level.txt,sha256=TllnGWqDoFMhKyTiX9peoF1VC1wmkRgILHdebnubEb8,16 +mypy_extensions.py,sha256=i6mP8-60N5kj1W7ebvPbU4AeGOSph_ekHLkMbfoK2a0,6227 diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/WHEEL new file mode 100644 index 00000000..57e3d840 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.4) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/top_level.txt new file mode 100644 index 00000000..ee216652 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions-1.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +mypy_extensions diff --git a/dbdpy-env/lib/python3.9/site-packages/mypy_extensions.py b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions.py new file mode 100644 index 00000000..6600b211 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/mypy_extensions.py @@ -0,0 +1,213 @@ +"""Defines experimental extensions to the standard "typing" module that are +supported by the mypy typechecker. + +Example usage: + from mypy_extensions import TypedDict +""" + +from typing import Any + +import sys +# _type_check is NOT a part of public typing API, it is used here only to mimic +# the (convenient) behavior of types provided by typing module. +from typing import _type_check # type: ignore + + +def _check_fails(cls, other): + try: + if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools', 'typing']: + # Typed dicts are only for static structural subtyping. + raise TypeError('TypedDict does not support instance and class checks') + except (AttributeError, ValueError): + pass + return False + + +def _dict_new(cls, *args, **kwargs): + return dict(*args, **kwargs) + + +def _typeddict_new(cls, _typename, _fields=None, **kwargs): + total = kwargs.pop('total', True) + if _fields is None: + _fields = kwargs + elif kwargs: + raise TypeError("TypedDict takes either a dict or keyword arguments," + " but not both") + + ns = {'__annotations__': dict(_fields), '__total__': total} + try: + # Setting correct module is necessary to make typed dict classes pickleable. + ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + + return _TypedDictMeta(_typename, (), ns) + + +class _TypedDictMeta(type): + def __new__(cls, name, bases, ns, total=True): + # Create new typed dict class object. + # This method is called directly when TypedDict is subclassed, + # or via _typeddict_new when TypedDict is instantiated. This way + # TypedDict supports all three syntaxes described in its docstring. + # Subclasses and instances of TypedDict return actual dictionaries + # via _dict_new. + ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new + tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns) + + anns = ns.get('__annotations__', {}) + msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" + anns = {n: _type_check(tp, msg) for n, tp in anns.items()} + for base in bases: + anns.update(base.__dict__.get('__annotations__', {})) + tp_dict.__annotations__ = anns + if not hasattr(tp_dict, '__total__'): + tp_dict.__total__ = total + return tp_dict + + __instancecheck__ = __subclasscheck__ = _check_fails + + +TypedDict = _TypedDictMeta('TypedDict', (dict,), {}) +TypedDict.__module__ = __name__ +TypedDict.__doc__ = \ + """A simple typed name space. At runtime it is equivalent to a plain dict. + + TypedDict creates a dictionary type that expects all of its + instances to have a certain set of keys, with each key + associated with a value of a consistent type. This expectation + is not checked at runtime but is only enforced by typecheckers. + Usage:: + + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK + b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check + assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + + The type info could be accessed via Point2D.__annotations__. TypedDict + supports two additional equivalent forms:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + + class Point2D(TypedDict): + x: int + y: int + label: str + + The latter syntax is only supported in Python 3.6+, while two other + syntax forms work for 3.2+ + """ + +# Argument constructors for making more-detailed Callables. These all just +# return their type argument, to make them complete noops in terms of the +# `typing` module. + + +def Arg(type=Any, name=None): + """A normal positional argument""" + return type + + +def DefaultArg(type=Any, name=None): + """A positional argument with a default value""" + return type + + +def NamedArg(type=Any, name=None): + """A keyword-only argument""" + return type + + +def DefaultNamedArg(type=Any, name=None): + """A keyword-only argument with a default value""" + return type + + +def VarArg(type=Any): + """A *args-style variadic positional argument""" + return type + + +def KwArg(type=Any): + """A **kwargs-style variadic keyword argument""" + return type + + +# Return type that indicates a function does not return +class NoReturn: pass + + +def trait(cls): + return cls + + +def mypyc_attr(*attrs, **kwattrs): + return lambda x: x + + +# TODO: We may want to try to properly apply this to any type +# variables left over... +class _FlexibleAliasClsApplied: + def __init__(self, val): + self.val = val + + def __getitem__(self, args): + return self.val + + +class _FlexibleAliasCls: + def __getitem__(self, args): + return _FlexibleAliasClsApplied(args[-1]) + + +FlexibleAlias = _FlexibleAliasCls() + + +class _NativeIntMeta(type): + def __instancecheck__(cls, inst): + return isinstance(inst, int) + + +_sentinel = object() + + +class i64(metaclass=_NativeIntMeta): + def __new__(cls, x=0, base=_sentinel): + if base is not _sentinel: + return int(x, base) + return int(x) + + +class i32(metaclass=_NativeIntMeta): + def __new__(cls, x=0, base=_sentinel): + if base is not _sentinel: + return int(x, base) + return int(x) + + +class i16(metaclass=_NativeIntMeta): + def __new__(cls, x=0, base=_sentinel): + if base is not _sentinel: + return int(x, base) + return int(x) + + +class u8(metaclass=_NativeIntMeta): + def __new__(cls, x=0, base=_sentinel): + if base is not _sentinel: + return int(x, base) + return int(x) + + +for _int_type in i64, i32, i16, u8: + _int_type.__doc__ = \ + """A native fixed-width integer type when used with mypyc. + + In code not compiled with mypyc, behaves like the 'int' type in these + runtime contexts: + + * {name}(x[, base=n]) converts a number or string to 'int' + * isinstance(x, {name}) is the same as isinstance(x, int) + """.format(name=_int_type.__name__) +del _int_type diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/LICENSE new file mode 100644 index 00000000..14e2f777 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/METADATA new file mode 100644 index 00000000..9cef7248 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/METADATA @@ -0,0 +1,647 @@ +Metadata-Version: 2.1 +Name: pathspec +Version: 0.12.1 +Summary: Utility library for gitignore style pattern matching of file paths. +Author-email: "Caleb P. Burns" <cpburnz@gmail.com> +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Project-URL: Documentation, https://python-path-specification.readthedocs.io/en/latest/index.html +Project-URL: Issue Tracker, https://github.com/cpburnz/python-pathspec/issues +Project-URL: Source Code, https://github.com/cpburnz/python-pathspec + + +PathSpec +======== + +*pathspec* is a utility library for pattern matching of file paths. So +far this only includes Git's wildmatch pattern matching which itself is +derived from Rsync's wildmatch. Git uses wildmatch for its `gitignore`_ +files. + +.. _`gitignore`: http://git-scm.com/docs/gitignore + + +Tutorial +-------- + +Say you have a "Projects" directory and you want to back it up, but only +certain files, and ignore others depending on certain conditions:: + + >>> import pathspec + >>> # The gitignore-style patterns for files to select, but we're including + >>> # instead of ignoring. + >>> spec_text = """ + ... + ... # This is a comment because the line begins with a hash: "#" + ... + ... # Include several project directories (and all descendants) relative to + ... # the current directory. To reference a directory you must end with a + ... # slash: "/" + ... /project-a/ + ... /project-b/ + ... /project-c/ + ... + ... # Patterns can be negated by prefixing with exclamation mark: "!" + ... + ... # Ignore temporary files beginning or ending with "~" and ending with + ... # ".swp". + ... !~* + ... !*~ + ... !*.swp + ... + ... # These are python projects so ignore compiled python files from + ... # testing. + ... !*.pyc + ... + ... # Ignore the build directories but only directly under the project + ... # directories. + ... !/*/build/ + ... + ... """ + +We want to use the ``GitWildMatchPattern`` class to compile our patterns. The +``PathSpec`` class provides an interface around pattern implementations:: + + >>> spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, spec_text.splitlines()) + +That may be a mouthful but it allows for additional patterns to be implemented +in the future without them having to deal with anything but matching the paths +sent to them. ``GitWildMatchPattern`` is the implementation of the actual +pattern which internally gets converted into a regular expression. ``PathSpec`` +is a simple wrapper around a list of compiled patterns. + +To make things simpler, we can use the registered name for a pattern class +instead of always having to provide a reference to the class itself. The +``GitWildMatchPattern`` class is registered as **gitwildmatch**:: + + >>> spec = pathspec.PathSpec.from_lines('gitwildmatch', spec_text.splitlines()) + +If we wanted to manually compile the patterns we can just do the following:: + + >>> patterns = map(pathspec.patterns.GitWildMatchPattern, spec_text.splitlines()) + >>> spec = PathSpec(patterns) + +``PathSpec.from_lines()`` is simply a class method which does just that. + +If you want to load the patterns from file, you can pass the file instance +directly as well:: + + >>> with open('patterns.list', 'r') as fh: + >>> spec = pathspec.PathSpec.from_lines('gitwildmatch', fh) + +You can perform matching on a whole directory tree with:: + + >>> matches = spec.match_tree('path/to/directory') + +Or you can perform matching on a specific set of file paths with:: + + >>> matches = spec.match_files(file_paths) + +Or check to see if an individual file matches:: + + >>> is_matched = spec.match_file(file_path) + +There is a specialized class, ``pathspec.GitIgnoreSpec``, which more closely +implements the behavior of **gitignore**. This uses ``GitWildMatchPattern`` +pattern by default and handles some edge cases differently from the generic +``PathSpec`` class. ``GitIgnoreSpec`` can be used without specifying the pattern +factory:: + + >>> spec = pathspec.GitIgnoreSpec.from_lines(spec_text.splitlines()) + + +License +------- + +*pathspec* is licensed under the `Mozilla Public License Version 2.0`_. See +`LICENSE`_ or the `FAQ`_ for more information. + +In summary, you may use *pathspec* with any closed or open source project +without affecting the license of the larger work so long as you: + +- give credit where credit is due, + +- and release any custom changes made to *pathspec*. + +.. _`Mozilla Public License Version 2.0`: http://www.mozilla.org/MPL/2.0 +.. _`LICENSE`: LICENSE +.. _`FAQ`: http://www.mozilla.org/MPL/2.0/FAQ.html + + +Source +------ + +The source code for *pathspec* is available from the GitHub repo +`cpburnz/python-pathspec`_. + +.. _`cpburnz/python-pathspec`: https://github.com/cpburnz/python-pathspec + + +Installation +------------ + +*pathspec* is available for install through `PyPI`_:: + + pip install pathspec + +*pathspec* can also be built from source. The following packages will be +required: + +- `build`_ (>=0.6.0) + +*pathspec* can then be built and installed with:: + + python -m build + pip install dist/pathspec-*-py3-none-any.whl + +.. _`PyPI`: http://pypi.python.org/pypi/pathspec +.. _`build`: https://pypi.org/project/build/ + + +Documentation +------------- + +Documentation for *pathspec* is available on `Read the Docs`_. + +.. _`Read the Docs`: https://python-path-specification.readthedocs.io + + +Other Languages +--------------- + +The related project `pathspec-ruby`_ (by *highb*) provides a similar library as +a `Ruby gem`_. + +.. _`pathspec-ruby`: https://github.com/highb/pathspec-ruby +.. _`Ruby gem`: https://rubygems.org/gems/pathspec + + + +Change History +============== + + +0.12.1 (2023-12-10) +------------------- + +Bug fixes: + +- `Issue #84`_: PathSpec.match_file() returns None since 0.12.0. + + +.. _`Issue #84`: https://github.com/cpburnz/python-pathspec/issues/84 + + +0.12.0 (2023-12-09) +------------------- + +Major changes: + +- Dropped support of EOL Python 3.7. See `Pull #82`_. + + +API changes: + +- Signature of protected method `pathspec.pathspec.PathSpec._match_file()` (with a leading underscore) has been changed from `def _match_file(patterns: Iterable[Pattern], file: str) -> bool` to `def _match_file(patterns: Iterable[Tuple[int, Pattern]], file: str) -> Tuple[Optional[bool], Optional[int]]`. + +New features: + +- Added `pathspec.pathspec.PathSpec.check_*()` methods. These methods behave similarly to `.match_*()` but return additional information in the `pathspec.util.CheckResult` objects (e.g., `CheckResult.index` indicates the index of the last pattern that matched the file). +- Added `pathspec.pattern.RegexPattern.pattern` attribute which stores the original, uncompiled pattern. + +Bug fixes: + +- `Issue #81`_: GitIgnoreSpec behaviors differ from git. +- `Pull #83`_: Fix ReadTheDocs builds. + +Improvements: + +- Mark Python 3.12 as supported. See `Pull #82`_. +- Improve test debugging. +- Improve type hint on *on_error* parameter on `pathspec.pathspec.PathSpec.match_tree_entries()`. +- Improve type hint on *on_error* parameter on `pathspec.util.iter_tree_entries()`. + + +.. _`Issue #81`: https://github.com/cpburnz/python-pathspec/issues/81 +.. _`Pull #82`: https://github.com/cpburnz/python-pathspec/pull/82 +.. _`Pull #83`: https://github.com/cpburnz/python-pathspec/pull/83 + + +0.11.2 (2023-07-28) +------------------- + +New features: + +- `Issue #80`_: match_files with negated path spec. `pathspec.PathSpec.match_*()` now have a `negate` parameter to make using *.gitignore* logic easier and more efficient. + +Bug fixes: + +- `Pull #76`_: Add edge case: patterns that end with an escaped space +- `Issue #77`_/`Pull #78`_: Negate with caret symbol as with the exclamation mark. + + +.. _`Pull #76`: https://github.com/cpburnz/python-pathspec/pull/76 +.. _`Issue #77`: https://github.com/cpburnz/python-pathspec/issues/77 +.. _`Pull #78`: https://github.com/cpburnz/python-pathspec/pull/78/ +.. _`Issue #80`: https://github.com/cpburnz/python-pathspec/issues/80 + + +0.11.1 (2023-03-14) +------------------- + +Bug fixes: + +- `Issue #74`_: Include directory should override exclude file. + +Improvements: + +- `Pull #75`_: Fix partially unknown PathLike type. +- Convert `os.PathLike` to a string properly using `os.fspath`. + + +.. _`Issue #74`: https://github.com/cpburnz/python-pathspec/issues/74 +.. _`Pull #75`: https://github.com/cpburnz/python-pathspec/pull/75 + + +0.11.0 (2023-01-24) +------------------- + +Major changes: + +- Changed build backend to `flit_core.buildapi`_ from `setuptools.build_meta`_. Building with `setuptools` through `setup.py` is still supported for distributions that need it. See `Issue #72`_. + +Improvements: + +- `Issue #72`_/`Pull #73`_: Please consider switching the build-system to flit_core to ease setuptools bootstrap. + + +.. _`flit_core.buildapi`: https://flit.pypa.io/en/latest/index.html +.. _`Issue #72`: https://github.com/cpburnz/python-pathspec/issues/72 +.. _`Pull #73`: https://github.com/cpburnz/python-pathspec/pull/73 + + +0.10.3 (2022-12-09) +------------------- + +New features: + +- Added utility function `pathspec.util.append_dir_sep()` to aid in distinguishing between directories and files on the file-system. See `Issue #65`_. + +Bug fixes: + +- `Issue #66`_/`Pull #67`_: Package not marked as py.typed. +- `Issue #68`_: Exports are considered private. +- `Issue #70`_/`Pull #71`_: 'Self' string literal type is Unknown in pyright. + +Improvements: + +- `Issue #65`_: Checking directories via match_file() does not work on Path objects. + + +.. _`Issue #65`: https://github.com/cpburnz/python-pathspec/issues/65 +.. _`Issue #66`: https://github.com/cpburnz/python-pathspec/issues/66 +.. _`Pull #67`: https://github.com/cpburnz/python-pathspec/pull/67 +.. _`Issue #68`: https://github.com/cpburnz/python-pathspec/issues/68 +.. _`Issue #70`: https://github.com/cpburnz/python-pathspec/issues/70 +.. _`Pull #71`: https://github.com/cpburnz/python-pathspec/pull/71 + + +0.10.2 (2022-11-12) +------------------- + +Bug fixes: + +- Fix failing tests on Windows. +- Type hint on *root* parameter on `pathspec.pathspec.PathSpec.match_tree_entries()`. +- Type hint on *root* parameter on `pathspec.pathspec.PathSpec.match_tree_files()`. +- Type hint on *root* parameter on `pathspec.util.iter_tree_entries()`. +- Type hint on *root* parameter on `pathspec.util.iter_tree_files()`. +- `Issue #64`_: IndexError with my .gitignore file when trying to build a Python package. + +Improvements: + +- `Pull #58`_: CI: add GitHub Actions test workflow. + + +.. _`Pull #58`: https://github.com/cpburnz/python-pathspec/pull/58 +.. _`Issue #64`: https://github.com/cpburnz/python-pathspec/issues/64 + + +0.10.1 (2022-09-02) +------------------- + +Bug fixes: + +- Fix documentation on `pathspec.pattern.RegexPattern.match_file()`. +- `Pull #60`_: Remove redundant wheel dep from pyproject.toml. +- `Issue #61`_: Dist failure for Fedora, CentOS, EPEL. +- `Issue #62`_: Since version 0.10.0 pure wildcard does not work in some cases. + +Improvements: + +- Restore support for legacy installations using `setup.py`. See `Issue #61`_. + + +.. _`Pull #60`: https://github.com/cpburnz/python-pathspec/pull/60 +.. _`Issue #61`: https://github.com/cpburnz/python-pathspec/issues/61 +.. _`Issue #62`: https://github.com/cpburnz/python-pathspec/issues/62 + + +0.10.0 (2022-08-30) +------------------- + +Major changes: + +- Dropped support of EOL Python 2.7, 3.5, 3.6. See `Issue #47`_. +- The *gitwildmatch* pattern `dir/*` is now handled the same as `dir/`. This means `dir/*` will now match all descendants rather than only direct children. See `Issue #19`_. +- Added `pathspec.GitIgnoreSpec` class (see new features). +- Changed build system to `pyproject.toml`_ and build backend to `setuptools.build_meta`_ which may have unforeseen consequences. +- Renamed GitHub project from `python-path-specification`_ to `python-pathspec`_. See `Issue #35`_. + +API changes: + +- Deprecated: `pathspec.util.match_files()` is an old function no longer used. +- Deprecated: `pathspec.match_files()` is an old function no longer used. +- Deprecated: `pathspec.util.normalize_files()` is no longer used. +- Deprecated: `pathspec.util.iter_tree()` is an alias for `pathspec.util.iter_tree_files()`. +- Deprecated: `pathspec.iter_tree()` is an alias for `pathspec.util.iter_tree_files()`. +- Deprecated: `pathspec.pattern.Pattern.match()` is no longer used. Use or implement + `pathspec.pattern.Pattern.match_file()`. + +New features: + +- Added class `pathspec.gitignore.GitIgnoreSpec` (with alias `pathspec.GitIgnoreSpec`) to implement *gitignore* behavior not possible with standard `PathSpec` class. The particular *gitignore* behavior implemented is prioritizing patterns matching the file directly over matching an ancestor directory. + +Bug fixes: + +- `Issue #19`_: Files inside an ignored sub-directory are not matched. +- `Issue #41`_: Incorrectly (?) matches files inside directories that do match. +- `Pull #51`_: Refactor deprecated unittest aliases for Python 3.11 compatibility. +- `Issue #53`_: Symlink pathspec_meta.py breaks Windows. +- `Issue #54`_: test_util.py uses os.symlink which can fail on Windows. +- `Issue #55`_: Backslashes at start of pattern not handled correctly. +- `Pull #56`_: pyproject.toml: include subpackages in setuptools config +- `Issue #57`_: `!` doesn't exclude files in directories if the pattern doesn't have a trailing slash. + +Improvements: + +- Support Python 3.10, 3.11. +- Modernize code to Python 3.7. +- `Issue #52`_: match_files() is not a pure generator function, and it impacts tree_*() gravely. + + +.. _`python-path-specification`: https://github.com/cpburnz/python-path-specification +.. _`python-pathspec`: https://github.com/cpburnz/python-pathspec +.. _`pyproject.toml`: https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/ +.. _`setuptools.build_meta`: https://setuptools.pypa.io/en/latest/build_meta.html +.. _`Issue #19`: https://github.com/cpburnz/python-pathspec/issues/19 +.. _`Issue #35`: https://github.com/cpburnz/python-pathspec/issues/35 +.. _`Issue #41`: https://github.com/cpburnz/python-pathspec/issues/41 +.. _`Issue #47`: https://github.com/cpburnz/python-pathspec/issues/47 +.. _`Pull #51`: https://github.com/cpburnz/python-pathspec/pull/51 +.. _`Issue #52`: https://github.com/cpburnz/python-pathspec/issues/52 +.. _`Issue #53`: https://github.com/cpburnz/python-pathspec/issues/53 +.. _`Issue #54`: https://github.com/cpburnz/python-pathspec/issues/54 +.. _`Issue #55`: https://github.com/cpburnz/python-pathspec/issues/55 +.. _`Pull #56`: https://github.com/cpburnz/python-pathspec/pull/56 +.. _`Issue #57`: https://github.com/cpburnz/python-pathspec/issues/57 + + +0.9.0 (2021-07-17) +------------------ + +- `Issue #44`_/`Pull #50`_: Raise `GitWildMatchPatternError` for invalid git patterns. +- `Pull #45`_: Fix for duplicate leading double-asterisk, and edge cases. +- `Issue #46`_: Fix matching absolute paths. +- API change: `util.normalize_files()` now returns a `Dict[str, List[pathlike]]` instead of a `Dict[str, pathlike]`. +- Added type hinting. + +.. _`Issue #44`: https://github.com/cpburnz/python-pathspec/issues/44 +.. _`Pull #45`: https://github.com/cpburnz/python-pathspec/pull/45 +.. _`Issue #46`: https://github.com/cpburnz/python-pathspec/issues/46 +.. _`Pull #50`: https://github.com/cpburnz/python-pathspec/pull/50 + + +0.8.1 (2020-11-07) +------------------ + +- `Pull #43`_: Add support for addition operator. + +.. _`Pull #43`: https://github.com/cpburnz/python-pathspec/pull/43 + + +0.8.0 (2020-04-09) +------------------ + +- `Issue #30`_: Expose what patterns matched paths. Added `util.detailed_match_files()`. +- `Issue #31`_: `match_tree()` doesn't return symlinks. +- `Issue #34`_: Support `pathlib.Path`\ s. +- Add `PathSpec.match_tree_entries` and `util.iter_tree_entries()` to support directories and symlinks. +- API change: `match_tree()` has been renamed to `match_tree_files()`. The old name `match_tree()` is still available as an alias. +- API change: `match_tree_files()` now returns symlinks. This is a bug fix but it will change the returned results. + +.. _`Issue #30`: https://github.com/cpburnz/python-pathspec/issues/30 +.. _`Issue #31`: https://github.com/cpburnz/python-pathspec/issues/31 +.. _`Issue #34`: https://github.com/cpburnz/python-pathspec/issues/34 + + +0.7.0 (2019-12-27) +------------------ + +- `Pull #28`_: Add support for Python 3.8, and drop Python 3.4. +- `Pull #29`_: Publish bdist wheel. + +.. _`Pull #28`: https://github.com/cpburnz/python-pathspec/pull/28 +.. _`Pull #29`: https://github.com/cpburnz/python-pathspec/pull/29 + + +0.6.0 (2019-10-03) +------------------ + +- `Pull #24`_: Drop support for Python 2.6, 3.2, and 3.3. +- `Pull #25`_: Update README.rst. +- `Pull #26`_: Method to escape gitwildmatch. + +.. _`Pull #24`: https://github.com/cpburnz/python-pathspec/pull/24 +.. _`Pull #25`: https://github.com/cpburnz/python-pathspec/pull/25 +.. _`Pull #26`: https://github.com/cpburnz/python-pathspec/pull/26 + + +0.5.9 (2018-09-15) +------------------ + +- Fixed file system error handling. + + +0.5.8 (2018-09-15) +------------------ + +- Improved type checking. +- Created scripts to test Python 2.6 because Tox removed support for it. +- Improved byte string handling in Python 3. +- `Issue #22`_: Handle dangling symlinks. + +.. _`Issue #22`: https://github.com/cpburnz/python-pathspec/issues/22 + + +0.5.7 (2018-08-14) +------------------ + +- `Issue #21`_: Fix collections deprecation warning. + +.. _`Issue #21`: https://github.com/cpburnz/python-pathspec/issues/21 + + +0.5.6 (2018-04-06) +------------------ + +- Improved unit tests. +- Improved type checking. +- `Issue #20`_: Support current directory prefix. + +.. _`Issue #20`: https://github.com/cpburnz/python-pathspec/issues/20 + + +0.5.5 (2017-09-09) +------------------ + +- Add documentation link to README. + + +0.5.4 (2017-09-09) +------------------ + +- `Pull #17`_: Add link to Ruby implementation of *pathspec*. +- Add sphinx documentation. + +.. _`Pull #17`: https://github.com/cpburnz/python-pathspec/pull/17 + + +0.5.3 (2017-07-01) +------------------ + +- `Issue #14`_: Fix byte strings for Python 3. +- `Pull #15`_: Include "LICENSE" in source package. +- `Issue #16`_: Support Python 2.6. + +.. _`Issue #14`: https://github.com/cpburnz/python-pathspec/issues/14 +.. _`Pull #15`: https://github.com/cpburnz/python-pathspec/pull/15 +.. _`Issue #16`: https://github.com/cpburnz/python-pathspec/issues/16 + + +0.5.2 (2017-04-04) +------------------ + +- Fixed change log. + + +0.5.1 (2017-04-04) +------------------ + +- `Pull #13`_: Add equality methods to `PathSpec` and `RegexPattern`. + +.. _`Pull #13`: https://github.com/cpburnz/python-pathspec/pull/13 + + +0.5.0 (2016-08-22) +------------------ + +- `Issue #12`_: Add `PathSpec.match_file()`. +- Renamed `gitignore.GitIgnorePattern` to `patterns.gitwildmatch.GitWildMatchPattern`. +- Deprecated `gitignore.GitIgnorePattern`. + +.. _`Issue #12`: https://github.com/cpburnz/python-pathspec/issues/12 + + +0.4.0 (2016-07-15) +------------------ + +- `Issue #11`_: Support converting patterns into regular expressions without compiling them. +- API change: Subclasses of `RegexPattern` should implement `pattern_to_regex()`. + +.. _`Issue #11`: https://github.com/cpburnz/python-pathspec/issues/11 + + +0.3.4 (2015-08-24) +------------------ + +- `Pull #7`_: Fixed non-recursive links. +- `Pull #8`_: Fixed edge cases in gitignore patterns. +- `Pull #9`_: Fixed minor usage documentation. +- Fixed recursion detection. +- Fixed trivial incompatibility with Python 3.2. + +.. _`Pull #7`: https://github.com/cpburnz/python-pathspec/pull/7 +.. _`Pull #8`: https://github.com/cpburnz/python-pathspec/pull/8 +.. _`Pull #9`: https://github.com/cpburnz/python-pathspec/pull/9 + + +0.3.3 (2014-11-21) +------------------ + +- Improved documentation. + + +0.3.2 (2014-11-08) +------------------ + +- `Pull #5`_: Use tox for testing. +- `Issue #6`_: Fixed matching Windows paths. +- Improved documentation. +- API change: `spec.match_tree()` and `spec.match_files()` now return iterators instead of sets. + +.. _`Pull #5`: https://github.com/cpburnz/python-pathspec/pull/5 +.. _`Issue #6`: https://github.com/cpburnz/python-pathspec/issues/6 + + +0.3.1 (2014-09-17) +------------------ + +- Updated README. + + +0.3.0 (2014-09-17) +------------------ + +- `Pull #3`_: Fixed trailing slash in gitignore patterns. +- `Pull #4`_: Fixed test for trailing slash in gitignore patterns. +- Added registered patterns. + +.. _`Pull #3`: https://github.com/cpburnz/python-pathspec/pull/3 +.. _`Pull #4`: https://github.com/cpburnz/python-pathspec/pull/4 + + +0.2.2 (2013-12-17) +------------------ + +- Fixed setup.py. + + +0.2.1 (2013-12-17) +------------------ + +- Added tests. +- Fixed comment gitignore patterns. +- Fixed relative path gitignore patterns. + + +0.2.0 (2013-12-07) +------------------ + +- Initial release. + diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/RECORD new file mode 100644 index 00000000..dfcdeed3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/RECORD @@ -0,0 +1,22 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/_meta.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/gitignore.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/pathspec.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/pattern.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/gitwildmatch.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pathspec/util.cpython-39.pyc,, +pathspec-0.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pathspec-0.12.1.dist-info/LICENSE,sha256=-rPda9qyJvHAhjCx3ZF-Efy07F4eAg4sFvg6ChOGPoU,16726 +pathspec-0.12.1.dist-info/METADATA,sha256=RNvbPbid5TWixr8xaLyA3Bm6Wt8FQM4JLYxHuucSxWQ,21171 +pathspec-0.12.1.dist-info/RECORD,, +pathspec-0.12.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +pathspec/__init__.py,sha256=7SXysmS-FbGnfonqXtaSm6aUKdepQCXdvd4ArWAMJak,1630 +pathspec/_meta.py,sha256=DaSTHF-ynkklvBBbKIQCnNYSW0yXJaKUDYEkvWHBYWE,2268 +pathspec/gitignore.py,sha256=89sV53U9ZMHwakCyfz6ISE5aQ0RNvSRkFbV9tUkWIdc,4637 +pathspec/pathspec.py,sha256=mDLpYD3_ZECYhe774ujSNKFJcazL1QE1XPSWk5r7rv0,13273 +pathspec/pattern.py,sha256=fcvcThcL5c-EJP2WnYuFV4tzoL7mzoOQMW09etCrk14,6270 +pathspec/patterns/__init__.py,sha256=vAzIEqBc2KsvWsiszsLCeYQwQVWXIHzbHNgq5TNrPdk,302 +pathspec/patterns/gitwildmatch.py,sha256=7gpaKsoLH8AYbFQ4Mqyj2wxCEI3zXOVj1Ge-x6RtsRY,12623 +pathspec/py.typed,sha256=wq7wwDeyBungK6DsiV4O-IujgKzARwHz94uQshdpdEU,68 +pathspec/util.py,sha256=G-26tZBw8p95D9FErmb5alpQ4glzjCmpbnZ1cBSKL9k,22680 diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/WHEEL new file mode 100644 index 00000000..3b5e64b5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec-0.12.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/__init__.py new file mode 100644 index 00000000..32e03f75 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/__init__.py @@ -0,0 +1,76 @@ +""" +The *pathspec* package provides pattern matching for file paths. So far +this only includes Git's wildmatch pattern matching (the style used for +".gitignore" files). + +The following classes are imported and made available from the root of +the `pathspec` package: + +- :class:`pathspec.gitignore.GitIgnoreSpec` + +- :class:`pathspec.pathspec.PathSpec` + +- :class:`pathspec.pattern.Pattern` + +- :class:`pathspec.pattern.RegexPattern` + +- :class:`pathspec.util.RecursionError` + +The following functions are also imported: + +- :func:`pathspec.util.lookup_pattern` + +The following deprecated functions are also imported to maintain +backward compatibility: + +- :func:`pathspec.util.iter_tree` which is an alias for + :func:`pathspec.util.iter_tree_files`. + +- :func:`pathspec.util.match_files` +""" + +from .gitignore import ( + GitIgnoreSpec) +from .pathspec import ( + PathSpec) +from .pattern import ( + Pattern, + RegexPattern) +from .util import ( + RecursionError, + iter_tree, + lookup_pattern, + match_files) + +from ._meta import ( + __author__, + __copyright__, + __credits__, + __license__, + __version__, +) + +# Load pattern implementations. +from . import patterns + +# DEPRECATED: Expose the `GitIgnorePattern` class in the root module for +# backward compatibility with v0.4. +from .patterns.gitwildmatch import GitIgnorePattern + +# Declare private imports as part of the public interface. Deprecated +# imports are deliberately excluded. +__all__ = [ + 'GitIgnoreSpec', + 'PathSpec', + 'Pattern', + 'RecursionError', + 'RegexPattern', + '__author__', + '__copyright__', + '__credits__', + '__license__', + '__version__', + 'iter_tree', + 'lookup_pattern', + 'match_files', +] diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/_meta.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/_meta.py new file mode 100644 index 00000000..4d8c89d4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/_meta.py @@ -0,0 +1,58 @@ +""" +This module contains the project meta-data. +""" + +__author__ = "Caleb P. Burns" +__copyright__ = "Copyright © 2013-2023 Caleb P. Burns" +__credits__ = [ + "dahlia <https://github.com/dahlia>", + "highb <https://github.com/highb>", + "029xue <https://github.com/029xue>", + "mikexstudios <https://github.com/mikexstudios>", + "nhumrich <https://github.com/nhumrich>", + "davidfraser <https://github.com/davidfraser>", + "demurgos <https://github.com/demurgos>", + "ghickman <https://github.com/ghickman>", + "nvie <https://github.com/nvie>", + "adrienverge <https://github.com/adrienverge>", + "AndersBlomdell <https://github.com/AndersBlomdell>", + "thmxv <https://github.com/thmxv>", + "wimglenn <https://github.com/wimglenn>", + "hugovk <https://github.com/hugovk>", + "dcecile <https://github.com/dcecile>", + "mroutis <https://github.com/mroutis>", + "jdufresne <https://github.com/jdufresne>", + "groodt <https://github.com/groodt>", + "ftrofin <https://github.com/ftrofin>", + "pykong <https://github.com/pykong>", + "nhhollander <https://github.com/nhhollander>", + "KOLANICH <https://github.com/KOLANICH>", + "JonjonHays <https://github.com/JonjonHays>", + "Isaac0616 <https://github.com/Isaac0616>", + "SebastiaanZ <https://github.com/SebastiaanZ>", + "RoelAdriaans <https://github.com/RoelAdriaans>", + "raviselker <https://github.com/raviselker>", + "johanvergeer <https://github.com/johanvergeer>", + "danjer <https://github.com/danjer>", + "jhbuhrman <https://github.com/jhbuhrman>", + "WPDOrdina <https://github.com/WPDOrdina>", + "tirkarthi <https://github.com/tirkarthi>", + "jayvdb <https://github.com/jayvdb>", + "jwodder <https://github.com/jwodder>", + "kloczek <https://github.com/kloczek>", + "orens <https://github.com/orens>", + "spMohanty <https://github.com/spMohanty>", + "ichard26 <https://github.com/ichard26>", + "jack1142 <https://github.com/jack1142>", + "mgorny <https://github.com/mgorny>", + "bzakdd <https://github.com/bzakdd>", + "haimat <https://github.com/haimat>", + "Avasam <https://github.com/Avasam>", + "yschroeder <https://github.com/yschroeder>", + "axesider <https://github.com/axesider>", + "tomruk <https://github.com/tomruk>", + "oprypin <https://github.com/oprypin>", + "kurtmckee <https://github.com/kurtmckee>", +] +__license__ = "MPL 2.0" +__version__ = "0.12.1" diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/gitignore.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/gitignore.py new file mode 100644 index 00000000..994a2c74 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/gitignore.py @@ -0,0 +1,157 @@ +""" +This module provides :class:`.GitIgnoreSpec` which replicates +*.gitignore* behavior. +""" + +from typing import ( + AnyStr, + Callable, # Replaced by `collections.abc.Callable` in 3.9. + Iterable, # Replaced by `collections.abc.Iterable` in 3.9. + Optional, # Replaced by `X | None` in 3.10. + Tuple, # Replaced by `tuple` in 3.9. + Type, # Replaced by `type` in 3.9. + TypeVar, + Union, # Replaced by `X | Y` in 3.10. + cast, + overload) + +from .pathspec import ( + PathSpec) +from .pattern import ( + Pattern) +from .patterns.gitwildmatch import ( + GitWildMatchPattern, + _DIR_MARK) +from .util import ( + _is_iterable) + +Self = TypeVar("Self", bound="GitIgnoreSpec") +""" +:class:`GitIgnoreSpec` self type hint to support Python v<3.11 using PEP +673 recommendation. +""" + + +class GitIgnoreSpec(PathSpec): + """ + The :class:`GitIgnoreSpec` class extends :class:`pathspec.pathspec.PathSpec` to + replicate *.gitignore* behavior. + """ + + def __eq__(self, other: object) -> bool: + """ + Tests the equality of this gitignore-spec with *other* (:class:`GitIgnoreSpec`) + by comparing their :attr:`~pathspec.pattern.Pattern` + attributes. A non-:class:`GitIgnoreSpec` will not compare equal. + """ + if isinstance(other, GitIgnoreSpec): + return super().__eq__(other) + elif isinstance(other, PathSpec): + return False + else: + return NotImplemented + + # Support reversed order of arguments from PathSpec. + @overload + @classmethod + def from_lines( + cls: Type[Self], + pattern_factory: Union[str, Callable[[AnyStr], Pattern]], + lines: Iterable[AnyStr], + ) -> Self: + ... + + @overload + @classmethod + def from_lines( + cls: Type[Self], + lines: Iterable[AnyStr], + pattern_factory: Union[str, Callable[[AnyStr], Pattern], None] = None, + ) -> Self: + ... + + @classmethod + def from_lines( + cls: Type[Self], + lines: Iterable[AnyStr], + pattern_factory: Union[str, Callable[[AnyStr], Pattern], None] = None, + ) -> Self: + """ + Compiles the pattern lines. + + *lines* (:class:`~collections.abc.Iterable`) yields each uncompiled + pattern (:class:`str`). This simply has to yield each line so it can + be a :class:`io.TextIOBase` (e.g., from :func:`open` or + :class:`io.StringIO`) or the result from :meth:`str.splitlines`. + + *pattern_factory* can be :data:`None`, the name of a registered + pattern factory (:class:`str`), or a :class:`~collections.abc.Callable` + used to compile patterns. The callable must accept an uncompiled + pattern (:class:`str`) and return the compiled pattern + (:class:`pathspec.pattern.Pattern`). + Default is :data:`None` for :class:`.GitWildMatchPattern`). + + Returns the :class:`GitIgnoreSpec` instance. + """ + if pattern_factory is None: + pattern_factory = GitWildMatchPattern + + elif (isinstance(lines, (str, bytes)) or callable(lines)) and _is_iterable(pattern_factory): + # Support reversed order of arguments from PathSpec. + pattern_factory, lines = lines, pattern_factory + + self = super().from_lines(pattern_factory, lines) + return cast(Self, self) + + @staticmethod + def _match_file( + patterns: Iterable[Tuple[int, GitWildMatchPattern]], + file: str, + ) -> Tuple[Optional[bool], Optional[int]]: + """ + Check the file against the patterns. + + .. NOTE:: Subclasses of :class:`~pathspec.pathspec.PathSpec` may override + this method as an instance method. It does not have to be a static + method. The signature for this method is subject to change. + + *patterns* (:class:`~collections.abc.Iterable`) yields each indexed pattern + (:class:`tuple`) which contains the pattern index (:class:`int`) and actual + pattern (:class:`~pathspec.pattern.Pattern`). + + *file* (:class:`str`) is the normalized file path to be matched against + *patterns*. + + Returns a :class:`tuple` containing whether to include *file* (:class:`bool` + or :data:`None`), and the index of the last matched pattern (:class:`int` or + :data:`None`). + """ + out_include: Optional[bool] = None + out_index: Optional[int] = None + out_priority = 0 + for index, pattern in patterns: + if pattern.include is not None: + match = pattern.match_file(file) + if match is not None: + # Pattern matched. + + # Check for directory marker. + dir_mark = match.match.groupdict().get(_DIR_MARK) + + if dir_mark: + # Pattern matched by a directory pattern. + priority = 1 + else: + # Pattern matched by a file pattern. + priority = 2 + + if pattern.include and dir_mark: + out_include = pattern.include + out_index = index + out_priority = priority + elif priority >= out_priority: + out_include = pattern.include + out_index = index + out_priority = priority + + return out_include, out_index diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/pathspec.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/pathspec.py new file mode 100644 index 00000000..bdfaccda --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/pathspec.py @@ -0,0 +1,394 @@ +""" +This module provides an object oriented interface for pattern matching of files. +""" + +from collections.abc import ( + Collection as CollectionType) +from itertools import ( + zip_longest) +from typing import ( + AnyStr, + Callable, # Replaced by `collections.abc.Callable` in 3.9. + Collection, # Replaced by `collections.abc.Collection` in 3.9. + Iterable, # Replaced by `collections.abc.Iterable` in 3.9. + Iterator, # Replaced by `collections.abc.Iterator` in 3.9. + Optional, # Replaced by `X | None` in 3.10. + Type, # Replaced by `type` in 3.9. + TypeVar, + Union) # Replaced by `X | Y` in 3.10. + +from . import util +from .pattern import ( + Pattern) +from .util import ( + CheckResult, + StrPath, + TStrPath, + TreeEntry, + _filter_check_patterns, + _is_iterable, + normalize_file) + +Self = TypeVar("Self", bound="PathSpec") +""" +:class:`PathSpec` self type hint to support Python v<3.11 using PEP 673 +recommendation. +""" + + +class PathSpec(object): + """ + The :class:`PathSpec` class is a wrapper around a list of compiled + :class:`.Pattern` instances. + """ + + def __init__(self, patterns: Iterable[Pattern]) -> None: + """ + Initializes the :class:`PathSpec` instance. + + *patterns* (:class:`~collections.abc.Collection` or :class:`~collections.abc.Iterable`) + yields each compiled pattern (:class:`.Pattern`). + """ + if not isinstance(patterns, CollectionType): + patterns = list(patterns) + + self.patterns: Collection[Pattern] = patterns + """ + *patterns* (:class:`~collections.abc.Collection` of :class:`.Pattern`) + contains the compiled patterns. + """ + + def __eq__(self, other: object) -> bool: + """ + Tests the equality of this path-spec with *other* (:class:`PathSpec`) + by comparing their :attr:`~PathSpec.patterns` attributes. + """ + if isinstance(other, PathSpec): + paired_patterns = zip_longest(self.patterns, other.patterns) + return all(a == b for a, b in paired_patterns) + else: + return NotImplemented + + def __len__(self) -> int: + """ + Returns the number of compiled patterns this path-spec contains + (:class:`int`). + """ + return len(self.patterns) + + def __add__(self: Self, other: "PathSpec") -> Self: + """ + Combines the :attr:`Pathspec.patterns` patterns from two + :class:`PathSpec` instances. + """ + if isinstance(other, PathSpec): + return self.__class__(self.patterns + other.patterns) + else: + return NotImplemented + + def __iadd__(self: Self, other: "PathSpec") -> Self: + """ + Adds the :attr:`Pathspec.patterns` patterns from one :class:`PathSpec` + instance to this instance. + """ + if isinstance(other, PathSpec): + self.patterns += other.patterns + return self + else: + return NotImplemented + + def check_file( + self, + file: TStrPath, + separators: Optional[Collection[str]] = None, + ) -> CheckResult[TStrPath]: + """ + Check the files against this path-spec. + + *file* (:class:`str` or :class:`os.PathLike`) is the file path to be + matched against :attr:`self.patterns <PathSpec.patterns>`. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + :data:`None`) optionally contains the path separators to normalize. See + :func:`~pathspec.util.normalize_file` for more information. + + Returns the file check result (:class:`~pathspec.util.CheckResult`). + """ + norm_file = normalize_file(file, separators) + include, index = self._match_file(enumerate(self.patterns), norm_file) + return CheckResult(file, include, index) + + def check_files( + self, + files: Iterable[TStrPath], + separators: Optional[Collection[str]] = None, + ) -> Iterator[CheckResult[TStrPath]]: + """ + Check the files against this path-spec. + + *files* (:class:`~collections.abc.Iterable` of :class:`str` or + :class:`os.PathLike`) contains the file paths to be checked against + :attr:`self.patterns <PathSpec.patterns>`. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + :data:`None`) optionally contains the path separators to normalize. See + :func:`~pathspec.util.normalize_file` for more information. + + Returns an :class:`~collections.abc.Iterator` yielding each file check + result (:class:`~pathspec.util.CheckResult`). + """ + if not _is_iterable(files): + raise TypeError(f"files:{files!r} is not an iterable.") + + use_patterns = _filter_check_patterns(self.patterns) + for orig_file in files: + norm_file = normalize_file(orig_file, separators) + include, index = self._match_file(use_patterns, norm_file) + yield CheckResult(orig_file, include, index) + + def check_tree_files( + self, + root: StrPath, + on_error: Optional[Callable[[OSError], None]] = None, + follow_links: Optional[bool] = None, + ) -> Iterator[CheckResult[str]]: + """ + Walks the specified root path for all files and checks them against this + path-spec. + + *root* (:class:`str` or :class:`os.PathLike`) is the root directory to + search for files. + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) optionally + is the error handler for file-system exceptions. It will be called with the + exception (:exc:`OSError`). Reraise the exception to abort the walk. Default + is :data:`None` to ignore file-system exceptions. + + *follow_links* (:class:`bool` or :data:`None`) optionally is whether to walk + symbolic links that resolve to directories. Default is :data:`None` for + :data:`True`. + + *negate* (:class:`bool` or :data:`None`) is whether to negate the match + results of the patterns. If :data:`True`, a pattern matching a file will + exclude the file rather than include it. Default is :data:`None` for + :data:`False`. + + Returns an :class:`~collections.abc.Iterator` yielding each file check + result (:class:`~pathspec.util.CheckResult`). + """ + files = util.iter_tree_files(root, on_error=on_error, follow_links=follow_links) + yield from self.check_files(files) + + @classmethod + def from_lines( + cls: Type[Self], + pattern_factory: Union[str, Callable[[AnyStr], Pattern]], + lines: Iterable[AnyStr], + ) -> Self: + """ + Compiles the pattern lines. + + *pattern_factory* can be either the name of a registered pattern factory + (:class:`str`), or a :class:`~collections.abc.Callable` used to compile + patterns. It must accept an uncompiled pattern (:class:`str`) and return the + compiled pattern (:class:`.Pattern`). + + *lines* (:class:`~collections.abc.Iterable`) yields each uncompiled pattern + (:class:`str`). This simply has to yield each line so that it can be a + :class:`io.TextIOBase` (e.g., from :func:`open` or :class:`io.StringIO`) or + the result from :meth:`str.splitlines`. + + Returns the :class:`PathSpec` instance. + """ + if isinstance(pattern_factory, str): + pattern_factory = util.lookup_pattern(pattern_factory) + + if not callable(pattern_factory): + raise TypeError(f"pattern_factory:{pattern_factory!r} is not callable.") + + if not _is_iterable(lines): + raise TypeError(f"lines:{lines!r} is not an iterable.") + + patterns = [pattern_factory(line) for line in lines if line] + return cls(patterns) + + def match_entries( + self, + entries: Iterable[TreeEntry], + separators: Optional[Collection[str]] = None, + *, + negate: Optional[bool] = None, + ) -> Iterator[TreeEntry]: + """ + Matches the entries to this path-spec. + + *entries* (:class:`~collections.abc.Iterable` of :class:`~pathspec.util.TreeEntry`) + contains the entries to be matched against :attr:`self.patterns <PathSpec.patterns>`. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + :data:`None`) optionally contains the path separators to normalize. See + :func:`~pathspec.util.normalize_file` for more information. + + *negate* (:class:`bool` or :data:`None`) is whether to negate the match + results of the patterns. If :data:`True`, a pattern matching a file will + exclude the file rather than include it. Default is :data:`None` for + :data:`False`. + + Returns the matched entries (:class:`~collections.abc.Iterator` of + :class:`~pathspec.util.TreeEntry`). + """ + if not _is_iterable(entries): + raise TypeError(f"entries:{entries!r} is not an iterable.") + + use_patterns = _filter_check_patterns(self.patterns) + for entry in entries: + norm_file = normalize_file(entry.path, separators) + include, _index = self._match_file(use_patterns, norm_file) + + if negate: + include = not include + + if include: + yield entry + + _match_file = staticmethod(util.check_match_file) + """ + Match files using the `check_match_file()` utility function. Subclasses may + override this method as an instance method. It does not have to be a static + method. The signature for this method is subject to change. + """ + + def match_file( + self, + file: StrPath, + separators: Optional[Collection[str]] = None, + ) -> bool: + """ + Matches the file to this path-spec. + + *file* (:class:`str` or :class:`os.PathLike`) is the file path to be + matched against :attr:`self.patterns <PathSpec.patterns>`. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`) + optionally contains the path separators to normalize. See + :func:`~pathspec.util.normalize_file` for more information. + + Returns :data:`True` if *file* matched; otherwise, :data:`False`. + """ + norm_file = normalize_file(file, separators) + include, _index = self._match_file(enumerate(self.patterns), norm_file) + return bool(include) + + def match_files( + self, + files: Iterable[StrPath], + separators: Optional[Collection[str]] = None, + *, + negate: Optional[bool] = None, + ) -> Iterator[StrPath]: + """ + Matches the files to this path-spec. + + *files* (:class:`~collections.abc.Iterable` of :class:`str` or + :class:`os.PathLike`) contains the file paths to be matched against + :attr:`self.patterns <PathSpec.patterns>`. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + :data:`None`) optionally contains the path separators to normalize. See + :func:`~pathspec.util.normalize_file` for more information. + + *negate* (:class:`bool` or :data:`None`) is whether to negate the match + results of the patterns. If :data:`True`, a pattern matching a file will + exclude the file rather than include it. Default is :data:`None` for + :data:`False`. + + Returns the matched files (:class:`~collections.abc.Iterator` of + :class:`str` or :class:`os.PathLike`). + """ + if not _is_iterable(files): + raise TypeError(f"files:{files!r} is not an iterable.") + + use_patterns = _filter_check_patterns(self.patterns) + for orig_file in files: + norm_file = normalize_file(orig_file, separators) + include, _index = self._match_file(use_patterns, norm_file) + + if negate: + include = not include + + if include: + yield orig_file + + def match_tree_entries( + self, + root: StrPath, + on_error: Optional[Callable[[OSError], None]] = None, + follow_links: Optional[bool] = None, + *, + negate: Optional[bool] = None, + ) -> Iterator[TreeEntry]: + """ + Walks the specified root path for all files and matches them to this + path-spec. + + *root* (:class:`str` or :class:`os.PathLike`) is the root directory to + search. + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) optionally + is the error handler for file-system exceptions. It will be called with the + exception (:exc:`OSError`). Reraise the exception to abort the walk. Default + is :data:`None` to ignore file-system exceptions. + + *follow_links* (:class:`bool` or :data:`None`) optionally is whether to walk + symbolic links that resolve to directories. Default is :data:`None` for + :data:`True`. + + *negate* (:class:`bool` or :data:`None`) is whether to negate the match + results of the patterns. If :data:`True`, a pattern matching a file will + exclude the file rather than include it. Default is :data:`None` for + :data:`False`. + + Returns the matched files (:class:`~collections.abc.Iterator` of + :class:`.TreeEntry`). + """ + entries = util.iter_tree_entries(root, on_error=on_error, follow_links=follow_links) + yield from self.match_entries(entries, negate=negate) + + def match_tree_files( + self, + root: StrPath, + on_error: Optional[Callable[[OSError], None]] = None, + follow_links: Optional[bool] = None, + *, + negate: Optional[bool] = None, + ) -> Iterator[str]: + """ + Walks the specified root path for all files and matches them to this + path-spec. + + *root* (:class:`str` or :class:`os.PathLike`) is the root directory to + search for files. + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) optionally + is the error handler for file-system exceptions. It will be called with the + exception (:exc:`OSError`). Reraise the exception to abort the walk. Default + is :data:`None` to ignore file-system exceptions. + + *follow_links* (:class:`bool` or :data:`None`) optionally is whether to walk + symbolic links that resolve to directories. Default is :data:`None` for + :data:`True`. + + *negate* (:class:`bool` or :data:`None`) is whether to negate the match + results of the patterns. If :data:`True`, a pattern matching a file will + exclude the file rather than include it. Default is :data:`None` for + :data:`False`. + + Returns the matched files (:class:`~collections.abc.Iterable` of + :class:`str`). + """ + files = util.iter_tree_files(root, on_error=on_error, follow_links=follow_links) + yield from self.match_files(files, negate=negate) + + # Alias `match_tree_files()` as `match_tree()` for backward compatibility + # before v0.3.2. + match_tree = match_tree_files diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/pattern.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/pattern.py new file mode 100644 index 00000000..d0815574 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/pattern.py @@ -0,0 +1,213 @@ +""" +This module provides the base definition for patterns. +""" + +import dataclasses +import re +import warnings +from typing import ( + Any, + AnyStr, + Iterable, # Replaced by `collections.abc.Iterable` in 3.9. + Iterator, # Replaced by `collections.abc.Iterator` in 3.9. + Match as MatchHint, # Replaced by `re.Match` in 3.9. + Optional, # Replaced by `X | None` in 3.10. + Pattern as PatternHint, # Replaced by `re.Pattern` in 3.9. + Tuple, # Replaced by `tuple` in 3.9. + Union) # Replaced by `X | Y` in 3.10. + + +class Pattern(object): + """ + The :class:`Pattern` class is the abstract definition of a pattern. + """ + + # Make the class dict-less. + __slots__ = ( + 'include', + ) + + def __init__(self, include: Optional[bool]) -> None: + """ + Initializes the :class:`Pattern` instance. + + *include* (:class:`bool` or :data:`None`) is whether the matched files + should be included (:data:`True`), excluded (:data:`False`), or is a + null-operation (:data:`None`). + """ + + self.include = include + """ + *include* (:class:`bool` or :data:`None`) is whether the matched files + should be included (:data:`True`), excluded (:data:`False`), or is a + null-operation (:data:`None`). + """ + + def match(self, files: Iterable[str]) -> Iterator[str]: + """ + DEPRECATED: This method is no longer used and has been replaced by + :meth:`.match_file`. Use the :meth:`.match_file` method with a loop for + similar results. + + Matches this pattern against the specified files. + + *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains each + file relative to the root directory (e.g., ``"relative/path/to/file"``). + + Returns an :class:`~collections.abc.Iterable` yielding each matched file + path (:class:`str`). + """ + warnings.warn(( + "{cls.__module__}.{cls.__qualname__}.match() is deprecated. Use " + "{cls.__module__}.{cls.__qualname__}.match_file() with a loop for " + "similar results." + ).format(cls=self.__class__), DeprecationWarning, stacklevel=2) + + for file in files: + if self.match_file(file) is not None: + yield file + + def match_file(self, file: str) -> Optional[Any]: + """ + Matches this pattern against the specified file. + + *file* (:class:`str`) is the normalized file path to match against. + + Returns the match result if *file* matched; otherwise, :data:`None`. + """ + raise NotImplementedError(( + "{cls.__module__}.{cls.__qualname__} must override match_file()." + ).format(cls=self.__class__)) + + +class RegexPattern(Pattern): + """ + The :class:`RegexPattern` class is an implementation of a pattern using + regular expressions. + """ + + # Keep the class dict-less. + __slots__ = ( + 'pattern', + 'regex', + ) + + def __init__( + self, + pattern: Union[AnyStr, PatternHint, None], + include: Optional[bool] = None, + ) -> None: + """ + Initializes the :class:`RegexPattern` instance. + + *pattern* (:class:`str`, :class:`bytes`, :class:`re.Pattern`, or + :data:`None`) is the pattern to compile into a regular expression. + + *include* (:class:`bool` or :data:`None`) must be :data:`None` unless + *pattern* is a precompiled regular expression (:class:`re.Pattern`) in which + case it is whether matched files should be included (:data:`True`), excluded + (:data:`False`), or is a null operation (:data:`None`). + + .. NOTE:: Subclasses do not need to support the *include* parameter. + """ + + if isinstance(pattern, (str, bytes)): + assert include is None, ( + f"include:{include!r} must be null when pattern:{pattern!r} is a string." + ) + regex, include = self.pattern_to_regex(pattern) + # NOTE: Make sure to allow a null regular expression to be + # returned for a null-operation. + if include is not None: + regex = re.compile(regex) + + elif pattern is not None and hasattr(pattern, 'match'): + # Assume pattern is a precompiled regular expression. + # - NOTE: Used specified *include*. + regex = pattern + + elif pattern is None: + # NOTE: Make sure to allow a null pattern to be passed for a + # null-operation. + assert include is None, ( + f"include:{include!r} must be null when pattern:{pattern!r} is null." + ) + + else: + raise TypeError(f"pattern:{pattern!r} is not a string, re.Pattern, or None.") + + super(RegexPattern, self).__init__(include) + + self.pattern: Union[AnyStr, PatternHint, None] = pattern + """ + *pattern* (:class:`str`, :class:`bytes`, :class:`re.Pattern`, or + :data:`None`) is the uncompiled, input pattern. This is for reference. + """ + + self.regex: PatternHint = regex + """ + *regex* (:class:`re.Pattern`) is the regular expression for the pattern. + """ + + def __eq__(self, other: 'RegexPattern') -> bool: + """ + Tests the equality of this regex pattern with *other* (:class:`RegexPattern`) + by comparing their :attr:`~Pattern.include` and :attr:`~RegexPattern.regex` + attributes. + """ + if isinstance(other, RegexPattern): + return self.include == other.include and self.regex == other.regex + else: + return NotImplemented + + def match_file(self, file: str) -> Optional['RegexMatchResult']: + """ + Matches this pattern against the specified file. + + *file* (:class:`str`) contains each file relative to the root directory + (e.g., "relative/path/to/file"). + + Returns the match result (:class:`.RegexMatchResult`) if *file* matched; + otherwise, :data:`None`. + """ + if self.include is not None: + match = self.regex.match(file) + if match is not None: + return RegexMatchResult(match) + + return None + + @classmethod + def pattern_to_regex(cls, pattern: str) -> Tuple[str, bool]: + """ + Convert the pattern into an uncompiled regular expression. + + *pattern* (:class:`str`) is the pattern to convert into a regular + expression. + + Returns the uncompiled regular expression (:class:`str` or :data:`None`), + and whether matched files should be included (:data:`True`), excluded + (:data:`False`), or is a null-operation (:data:`None`). + + .. NOTE:: The default implementation simply returns *pattern* and + :data:`True`. + """ + return pattern, True + + +@dataclasses.dataclass() +class RegexMatchResult(object): + """ + The :class:`RegexMatchResult` data class is used to return information about + the matched regular expression. + """ + + # Keep the class dict-less. + __slots__ = ( + 'match', + ) + + match: MatchHint + """ + *match* (:class:`re.Match`) is the regex match result. + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/__init__.py new file mode 100644 index 00000000..7360e9c2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/__init__.py @@ -0,0 +1,11 @@ +""" +The *pathspec.patterns* package contains the pattern matching +implementations. +""" + +# Load pattern implementations. +from . import gitwildmatch + +# DEPRECATED: Expose the `GitWildMatchPattern` class in this module for +# backward compatibility with v0.5. +from .gitwildmatch import GitWildMatchPattern diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/gitwildmatch.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/gitwildmatch.py new file mode 100644 index 00000000..6a3d6d5e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/patterns/gitwildmatch.py @@ -0,0 +1,421 @@ +""" +This module implements Git's wildmatch pattern matching which itself is derived +from Rsync's wildmatch. Git uses wildmatch for its ".gitignore" files. +""" + +import re +import warnings +from typing import ( + AnyStr, + Optional, # Replaced by `X | None` in 3.10. + Tuple) # Replaced by `tuple` in 3.9. + +from .. import util +from ..pattern import RegexPattern + +_BYTES_ENCODING = 'latin1' +""" +The encoding to use when parsing a byte string pattern. +""" + +_DIR_MARK = 'ps_d' +""" +The regex group name for the directory marker. This is only used by +:class:`GitIgnoreSpec`. +""" + + +class GitWildMatchPatternError(ValueError): + """ + The :class:`GitWildMatchPatternError` indicates an invalid git wild match + pattern. + """ + pass + + +class GitWildMatchPattern(RegexPattern): + """ + The :class:`GitWildMatchPattern` class represents a compiled Git wildmatch + pattern. + """ + + # Keep the dict-less class hierarchy. + __slots__ = () + + @classmethod + def pattern_to_regex( + cls, + pattern: AnyStr, + ) -> Tuple[Optional[AnyStr], Optional[bool]]: + """ + Convert the pattern into a regular expression. + + *pattern* (:class:`str` or :class:`bytes`) is the pattern to convert into a + regular expression. + + Returns the uncompiled regular expression (:class:`str`, :class:`bytes`, or + :data:`None`); and whether matched files should be included (:data:`True`), + excluded (:data:`False`), or if it is a null-operation (:data:`None`). + """ + if isinstance(pattern, str): + return_type = str + elif isinstance(pattern, bytes): + return_type = bytes + pattern = pattern.decode(_BYTES_ENCODING) + else: + raise TypeError(f"pattern:{pattern!r} is not a unicode or byte string.") + + original_pattern = pattern + + if pattern.endswith('\\ '): + # EDGE CASE: Spaces can be escaped with backslash. If a pattern that ends + # with backslash followed by a space, only strip from left. + pattern = pattern.lstrip() + else: + pattern = pattern.strip() + + if pattern.startswith('#'): + # A pattern starting with a hash ('#') serves as a comment (neither + # includes nor excludes files). Escape the hash with a back-slash to match + # a literal hash (i.e., '\#'). + regex = None + include = None + + elif pattern == '/': + # EDGE CASE: According to `git check-ignore` (v2.4.1), a single '/' does + # not match any file. + regex = None + include = None + + elif pattern: + if pattern.startswith('!'): + # A pattern starting with an exclamation mark ('!') negates the pattern + # (exclude instead of include). Escape the exclamation mark with a + # back-slash to match a literal exclamation mark (i.e., '\!'). + include = False + # Remove leading exclamation mark. + pattern = pattern[1:] + else: + include = True + + # Allow a regex override for edge cases that cannot be handled through + # normalization. + override_regex = None + + # Split pattern into segments. + pattern_segs = pattern.split('/') + + # Check whether the pattern is specifically a directory pattern before + # normalization. + is_dir_pattern = not pattern_segs[-1] + + # Normalize pattern to make processing easier. + + # EDGE CASE: Deal with duplicate double-asterisk sequences. Collapse each + # sequence down to one double-asterisk. Iterate over the segments in + # reverse and remove the duplicate double asterisks as we go. + for i in range(len(pattern_segs) - 1, 0, -1): + prev = pattern_segs[i-1] + seg = pattern_segs[i] + if prev == '**' and seg == '**': + del pattern_segs[i] + + if len(pattern_segs) == 2 and pattern_segs[0] == '**' and not pattern_segs[1]: + # EDGE CASE: The '**/' pattern should match everything except individual + # files in the root directory. This case cannot be adequately handled + # through normalization. Use the override. + override_regex = f'^.+(?P<{_DIR_MARK}>/).*$' + + if not pattern_segs[0]: + # A pattern beginning with a slash ('/') will only match paths directly + # on the root directory instead of any descendant paths. So, remove + # empty first segment to make pattern relative to root. + del pattern_segs[0] + + elif len(pattern_segs) == 1 or (len(pattern_segs) == 2 and not pattern_segs[1]): + # A single pattern without a beginning slash ('/') will match any + # descendant path. This is equivalent to "**/{pattern}". So, prepend + # with double-asterisks to make pattern relative to root. + # - EDGE CASE: This also holds for a single pattern with a trailing + # slash (e.g. dir/). + if pattern_segs[0] != '**': + pattern_segs.insert(0, '**') + + else: + # EDGE CASE: A pattern without a beginning slash ('/') but contains at + # least one prepended directory (e.g. "dir/{pattern}") should not match + # "**/dir/{pattern}", according to `git check-ignore` (v2.4.1). + pass + + if not pattern_segs: + # After resolving the edge cases, we end up with no pattern at all. This + # must be because the pattern is invalid. + raise GitWildMatchPatternError(f"Invalid git pattern: {original_pattern!r}") + + if not pattern_segs[-1] and len(pattern_segs) > 1: + # A pattern ending with a slash ('/') will match all descendant paths if + # it is a directory but not if it is a regular file. This is equivalent + # to "{pattern}/**". So, set last segment to a double-asterisk to + # include all descendants. + pattern_segs[-1] = '**' + + if override_regex is None: + # Build regular expression from pattern. + output = ['^'] + need_slash = False + end = len(pattern_segs) - 1 + for i, seg in enumerate(pattern_segs): + if seg == '**': + if i == 0 and i == end: + # A pattern consisting solely of double-asterisks ('**') will + # match every path. + output.append(f'[^/]+(?:/.*)?') + + elif i == 0: + # A normalized pattern beginning with double-asterisks + # ('**') will match any leading path segments. + output.append('(?:.+/)?') + need_slash = False + + elif i == end: + # A normalized pattern ending with double-asterisks ('**') will + # match any trailing path segments. + if is_dir_pattern: + output.append(f'(?P<{_DIR_MARK}>/).*') + else: + output.append(f'/.*') + + else: + # A pattern with inner double-asterisks ('**') will match multiple + # (or zero) inner path segments. + output.append('(?:/.+)?') + need_slash = True + + elif seg == '*': + # Match single path segment. + if need_slash: + output.append('/') + + output.append('[^/]+') + + if i == end: + # A pattern ending without a slash ('/') will match a file or a + # directory (with paths underneath it). E.g., "foo" matches "foo", + # "foo/bar", "foo/bar/baz", etc. + output.append(f'(?:(?P<{_DIR_MARK}>/).*)?') + + need_slash = True + + else: + # Match segment glob pattern. + if need_slash: + output.append('/') + + try: + output.append(cls._translate_segment_glob(seg)) + except ValueError as e: + raise GitWildMatchPatternError(f"Invalid git pattern: {original_pattern!r}") from e + + if i == end: + # A pattern ending without a slash ('/') will match a file or a + # directory (with paths underneath it). E.g., "foo" matches "foo", + # "foo/bar", "foo/bar/baz", etc. + output.append(f'(?:(?P<{_DIR_MARK}>/).*)?') + + need_slash = True + + output.append('$') + regex = ''.join(output) + + else: + # Use regex override. + regex = override_regex + + else: + # A blank pattern is a null-operation (neither includes nor excludes + # files). + regex = None + include = None + + if regex is not None and return_type is bytes: + regex = regex.encode(_BYTES_ENCODING) + + return regex, include + + @staticmethod + def _translate_segment_glob(pattern: str) -> str: + """ + Translates the glob pattern to a regular expression. This is used in the + constructor to translate a path segment glob pattern to its corresponding + regular expression. + + *pattern* (:class:`str`) is the glob pattern. + + Returns the regular expression (:class:`str`). + """ + # NOTE: This is derived from `fnmatch.translate()` and is similar to the + # POSIX function `fnmatch()` with the `FNM_PATHNAME` flag set. + + escape = False + regex = '' + i, end = 0, len(pattern) + while i < end: + # Get next character. + char = pattern[i] + i += 1 + + if escape: + # Escape the character. + escape = False + regex += re.escape(char) + + elif char == '\\': + # Escape character, escape next character. + escape = True + + elif char == '*': + # Multi-character wildcard. Match any string (except slashes), including + # an empty string. + regex += '[^/]*' + + elif char == '?': + # Single-character wildcard. Match any single character (except a + # slash). + regex += '[^/]' + + elif char == '[': + # Bracket expression wildcard. Except for the beginning exclamation + # mark, the whole bracket expression can be used directly as regex, but + # we have to find where the expression ends. + # - "[][!]" matches ']', '[' and '!'. + # - "[]-]" matches ']' and '-'. + # - "[!]a-]" matches any character except ']', 'a' and '-'. + j = i + + # Pass bracket expression negation. + if j < end and (pattern[j] == '!' or pattern[j] == '^'): + j += 1 + + # Pass first closing bracket if it is at the beginning of the + # expression. + if j < end and pattern[j] == ']': + j += 1 + + # Find closing bracket. Stop once we reach the end or find it. + while j < end and pattern[j] != ']': + j += 1 + + if j < end: + # Found end of bracket expression. Increment j to be one past the + # closing bracket: + # + # [...] + # ^ ^ + # i j + # + j += 1 + expr = '[' + + if pattern[i] == '!': + # Bracket expression needs to be negated. + expr += '^' + i += 1 + elif pattern[i] == '^': + # POSIX declares that the regex bracket expression negation "[^...]" + # is undefined in a glob pattern. Python's `fnmatch.translate()` + # escapes the caret ('^') as a literal. Git supports the using a + # caret for negation. Maintain consistency with Git because that is + # the expected behavior. + expr += '^' + i += 1 + + # Build regex bracket expression. Escape slashes so they are treated + # as literal slashes by regex as defined by POSIX. + expr += pattern[i:j].replace('\\', '\\\\') + + # Add regex bracket expression to regex result. + regex += expr + + # Set i to one past the closing bracket. + i = j + + else: + # Failed to find closing bracket, treat opening bracket as a bracket + # literal instead of as an expression. + regex += '\\[' + + else: + # Regular character, escape it for regex. + regex += re.escape(char) + + if escape: + raise ValueError(f"Escape character found with no next character to escape: {pattern!r}") + + return regex + + @staticmethod + def escape(s: AnyStr) -> AnyStr: + """ + Escape special characters in the given string. + + *s* (:class:`str` or :class:`bytes`) a filename or a string that you want to + escape, usually before adding it to a ".gitignore". + + Returns the escaped string (:class:`str` or :class:`bytes`). + """ + if isinstance(s, str): + return_type = str + string = s + elif isinstance(s, bytes): + return_type = bytes + string = s.decode(_BYTES_ENCODING) + else: + raise TypeError(f"s:{s!r} is not a unicode or byte string.") + + # Reference: https://git-scm.com/docs/gitignore#_pattern_format + meta_characters = r"[]!*#?" + + out_string = "".join("\\" + x if x in meta_characters else x for x in string) + + if return_type is bytes: + return out_string.encode(_BYTES_ENCODING) + else: + return out_string + +util.register_pattern('gitwildmatch', GitWildMatchPattern) + + +class GitIgnorePattern(GitWildMatchPattern): + """ + The :class:`GitIgnorePattern` class is deprecated by :class:`GitWildMatchPattern`. + This class only exists to maintain compatibility with v0.4. + """ + + def __init__(self, *args, **kw) -> None: + """ + Warn about deprecation. + """ + self._deprecated() + super(GitIgnorePattern, self).__init__(*args, **kw) + + @staticmethod + def _deprecated() -> None: + """ + Warn about deprecation. + """ + warnings.warn(( + "GitIgnorePattern ('gitignore') is deprecated. Use GitWildMatchPattern " + "('gitwildmatch') instead." + ), DeprecationWarning, stacklevel=3) + + @classmethod + def pattern_to_regex(cls, *args, **kw): + """ + Warn about deprecation. + """ + cls._deprecated() + return super(GitIgnorePattern, cls).pattern_to_regex(*args, **kw) + +# Register `GitIgnorePattern` as "gitignore" for backward compatibility with +# v0.4. +util.register_pattern('gitignore', GitIgnorePattern) diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/py.typed b/dbdpy-env/lib/python3.9/site-packages/pathspec/py.typed new file mode 100644 index 00000000..b01eaaf7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. The pathspec package uses inline types. diff --git a/dbdpy-env/lib/python3.9/site-packages/pathspec/util.py b/dbdpy-env/lib/python3.9/site-packages/pathspec/util.py new file mode 100644 index 00000000..58839511 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pathspec/util.py @@ -0,0 +1,792 @@ +""" +This module provides utility methods for dealing with path-specs. +""" + +import os +import os.path +import pathlib +import posixpath +import stat +import sys +import warnings +from collections.abc import ( + Collection as CollectionType, + Iterable as IterableType) +from dataclasses import ( + dataclass) +from os import ( + PathLike) +from typing import ( + Any, + AnyStr, + Callable, # Replaced by `collections.abc.Callable` in 3.9. + Collection, # Replaced by `collections.abc.Collection` in 3.9. + Dict, # Replaced by `dict` in 3.9. + Generic, + Iterable, # Replaced by `collections.abc.Iterable` in 3.9. + Iterator, # Replaced by `collections.abc.Iterator` in 3.9. + List, # Replaced by `list` in 3.9. + Optional, # Replaced by `X | None` in 3.10. + Sequence, # Replaced by `collections.abc.Sequence` in 3.9. + Set, # Replaced by `set` in 3.9. + Tuple, # Replaced by `tuple` in 3.9. + TypeVar, + Union) # Replaced by `X | Y` in 3.10. + +from .pattern import ( + Pattern) + +if sys.version_info >= (3, 9): + StrPath = Union[str, PathLike[str]] +else: + StrPath = Union[str, PathLike] + +TStrPath = TypeVar("TStrPath", bound=StrPath) +""" +Type variable for :class:`str` or :class:`os.PathLike`. +""" + +NORMALIZE_PATH_SEPS = [ + __sep + for __sep in [os.sep, os.altsep] + if __sep and __sep != posixpath.sep +] +""" +*NORMALIZE_PATH_SEPS* (:class:`list` of :class:`str`) contains the path +separators that need to be normalized to the POSIX separator for the +current operating system. The separators are determined by examining +:data:`os.sep` and :data:`os.altsep`. +""" + +_registered_patterns = {} +""" +*_registered_patterns* (:class:`dict`) maps a name (:class:`str`) to the +registered pattern factory (:class:`~collections.abc.Callable`). +""" + + +def append_dir_sep(path: pathlib.Path) -> str: + """ + Appends the path separator to the path if the path is a directory. + This can be used to aid in distinguishing between directories and + files on the file-system by relying on the presence of a trailing path + separator. + + *path* (:class:`pathlib.Path`) is the path to use. + + Returns the path (:class:`str`). + """ + str_path = str(path) + if path.is_dir(): + str_path += os.sep + + return str_path + + +def check_match_file( + patterns: Iterable[Tuple[int, Pattern]], + file: str, +) -> Tuple[Optional[bool], Optional[int]]: + """ + Check the file against the patterns. + + *patterns* (:class:`~collections.abc.Iterable`) yields each indexed pattern + (:class:`tuple`) which contains the pattern index (:class:`int`) and actual + pattern (:class:`~pathspec.pattern.Pattern`). + + *file* (:class:`str`) is the normalized file path to be matched + against *patterns*. + + Returns a :class:`tuple` containing whether to include *file* (:class:`bool` + or :data:`None`), and the index of the last matched pattern (:class:`int` or + :data:`None`). + """ + out_include: Optional[bool] = None + out_index: Optional[int] = None + for index, pattern in patterns: + if pattern.include is not None and pattern.match_file(file) is not None: + out_include = pattern.include + out_index = index + + return out_include, out_index + + +def detailed_match_files( + patterns: Iterable[Pattern], + files: Iterable[str], + all_matches: Optional[bool] = None, +) -> Dict[str, 'MatchDetail']: + """ + Matches the files to the patterns, and returns which patterns matched + the files. + + *patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`) + contains the patterns to use. + + *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains + the normalized file paths to be matched against *patterns*. + + *all_matches* (:class:`bool` or :data:`None`) is whether to return all + matches patterns (:data:`True`), or only the last matched pattern + (:data:`False`). Default is :data:`None` for :data:`False`. + + Returns the matched files (:class:`dict`) which maps each matched file + (:class:`str`) to the patterns that matched in order (:class:`.MatchDetail`). + """ + all_files = files if isinstance(files, CollectionType) else list(files) + return_files = {} + for pattern in patterns: + if pattern.include is not None: + result_files = pattern.match(all_files) # TODO: Replace with `.match_file()`. + if pattern.include: + # Add files and record pattern. + for result_file in result_files: + if result_file in return_files: + if all_matches: + return_files[result_file].patterns.append(pattern) + else: + return_files[result_file].patterns[0] = pattern + else: + return_files[result_file] = MatchDetail([pattern]) + + else: + # Remove files. + for file in result_files: + del return_files[file] + + return return_files + + +def _filter_check_patterns( + patterns: Iterable[Pattern], +) -> List[Tuple[int, Pattern]]: + """ + Filters out null-patterns. + + *patterns* (:class:`Iterable` of :class:`.Pattern`) contains the + patterns. + + Returns a :class:`list` containing each indexed pattern (:class:`tuple`) which + contains the pattern index (:class:`int`) and the actual pattern + (:class:`~pathspec.pattern.Pattern`). + """ + return [ + (__index, __pat) + for __index, __pat in enumerate(patterns) + if __pat.include is not None + ] + + +def _is_iterable(value: Any) -> bool: + """ + Check whether the value is an iterable (excludes strings). + + *value* is the value to check, + + Returns whether *value* is a iterable (:class:`bool`). + """ + return isinstance(value, IterableType) and not isinstance(value, (str, bytes)) + + +def iter_tree_entries( + root: StrPath, + on_error: Optional[Callable[[OSError], None]] = None, + follow_links: Optional[bool] = None, +) -> Iterator['TreeEntry']: + """ + Walks the specified directory for all files and directories. + + *root* (:class:`str` or :class:`os.PathLike`) is the root directory to + search. + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) + optionally is the error handler for file-system exceptions. It will be + called with the exception (:exc:`OSError`). Reraise the exception to + abort the walk. Default is :data:`None` to ignore file-system + exceptions. + + *follow_links* (:class:`bool` or :data:`None`) optionally is whether + to walk symbolic links that resolve to directories. Default is + :data:`None` for :data:`True`. + + Raises :exc:`RecursionError` if recursion is detected. + + Returns an :class:`~collections.abc.Iterator` yielding each file or + directory entry (:class:`.TreeEntry`) relative to *root*. + """ + if on_error is not None and not callable(on_error): + raise TypeError(f"on_error:{on_error!r} is not callable.") + + if follow_links is None: + follow_links = True + + yield from _iter_tree_entries_next(os.path.abspath(root), '', {}, on_error, follow_links) + + +def _iter_tree_entries_next( + root_full: str, + dir_rel: str, + memo: Dict[str, str], + on_error: Callable[[OSError], None], + follow_links: bool, +) -> Iterator['TreeEntry']: + """ + Scan the directory for all descendant files. + + *root_full* (:class:`str`) the absolute path to the root directory. + + *dir_rel* (:class:`str`) the path to the directory to scan relative to + *root_full*. + + *memo* (:class:`dict`) keeps track of ancestor directories + encountered. Maps each ancestor real path (:class:`str`) to relative + path (:class:`str`). + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) + optionally is the error handler for file-system exceptions. + + *follow_links* (:class:`bool`) is whether to walk symbolic links that + resolve to directories. + + Yields each entry (:class:`.TreeEntry`). + """ + dir_full = os.path.join(root_full, dir_rel) + dir_real = os.path.realpath(dir_full) + + # Remember each encountered ancestor directory and its canonical + # (real) path. If a canonical path is encountered more than once, + # recursion has occurred. + if dir_real not in memo: + memo[dir_real] = dir_rel + else: + raise RecursionError(real_path=dir_real, first_path=memo[dir_real], second_path=dir_rel) + + with os.scandir(dir_full) as scan_iter: + node_ent: os.DirEntry + for node_ent in scan_iter: + node_rel = os.path.join(dir_rel, node_ent.name) + + # Inspect child node. + try: + node_lstat = node_ent.stat(follow_symlinks=False) + except OSError as e: + if on_error is not None: + on_error(e) + continue + + if node_ent.is_symlink(): + # Child node is a link, inspect the target node. + try: + node_stat = node_ent.stat() + except OSError as e: + if on_error is not None: + on_error(e) + continue + else: + node_stat = node_lstat + + if node_ent.is_dir(follow_symlinks=follow_links): + # Child node is a directory, recurse into it and yield its + # descendant files. + yield TreeEntry(node_ent.name, node_rel, node_lstat, node_stat) + + yield from _iter_tree_entries_next(root_full, node_rel, memo, on_error, follow_links) + + elif node_ent.is_file() or node_ent.is_symlink(): + # Child node is either a file or an unfollowed link, yield it. + yield TreeEntry(node_ent.name, node_rel, node_lstat, node_stat) + + # NOTE: Make sure to remove the canonical (real) path of the directory + # from the ancestors memo once we are done with it. This allows the + # same directory to appear multiple times. If this is not done, the + # second occurrence of the directory will be incorrectly interpreted + # as a recursion. See <https://github.com/cpburnz/python-path-specification/pull/7>. + del memo[dir_real] + + +def iter_tree_files( + root: StrPath, + on_error: Optional[Callable[[OSError], None]] = None, + follow_links: Optional[bool] = None, +) -> Iterator[str]: + """ + Walks the specified directory for all files. + + *root* (:class:`str` or :class:`os.PathLike`) is the root directory to + search for files. + + *on_error* (:class:`~collections.abc.Callable` or :data:`None`) + optionally is the error handler for file-system exceptions. It will be + called with the exception (:exc:`OSError`). Reraise the exception to + abort the walk. Default is :data:`None` to ignore file-system + exceptions. + + *follow_links* (:class:`bool` or :data:`None`) optionally is whether + to walk symbolic links that resolve to directories. Default is + :data:`None` for :data:`True`. + + Raises :exc:`RecursionError` if recursion is detected. + + Returns an :class:`~collections.abc.Iterator` yielding the path to + each file (:class:`str`) relative to *root*. + """ + for entry in iter_tree_entries(root, on_error=on_error, follow_links=follow_links): + if not entry.is_dir(follow_links): + yield entry.path + + +def iter_tree(root, on_error=None, follow_links=None): + """ + DEPRECATED: The :func:`.iter_tree` function is an alias for the + :func:`.iter_tree_files` function. + """ + warnings.warn(( + "util.iter_tree() is deprecated. Use util.iter_tree_files() instead." + ), DeprecationWarning, stacklevel=2) + return iter_tree_files(root, on_error=on_error, follow_links=follow_links) + + +def lookup_pattern(name: str) -> Callable[[AnyStr], Pattern]: + """ + Lookups a registered pattern factory by name. + + *name* (:class:`str`) is the name of the pattern factory. + + Returns the registered pattern factory (:class:`~collections.abc.Callable`). + If no pattern factory is registered, raises :exc:`KeyError`. + """ + return _registered_patterns[name] + + +def match_file(patterns: Iterable[Pattern], file: str) -> bool: + """ + Matches the file to the patterns. + + *patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`) + contains the patterns to use. + + *file* (:class:`str`) is the normalized file path to be matched + against *patterns*. + + Returns :data:`True` if *file* matched; otherwise, :data:`False`. + """ + matched = False + for pattern in patterns: + if pattern.include is not None and pattern.match_file(file) is not None: + matched = pattern.include + + return matched + + +def match_files( + patterns: Iterable[Pattern], + files: Iterable[str], +) -> Set[str]: + """ + DEPRECATED: This is an old function no longer used. Use the + :func:`~pathspec.util.match_file` function with a loop for better results. + + Matches the files to the patterns. + + *patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`) + contains the patterns to use. + + *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains + the normalized file paths to be matched against *patterns*. + + Returns the matched files (:class:`set` of :class:`str`). + """ + warnings.warn(( + f"{__name__}.match_files() is deprecated. Use {__name__}.match_file() with " + f"a loop for better results." + ), DeprecationWarning, stacklevel=2) + + use_patterns = [__pat for __pat in patterns if __pat.include is not None] + + return_files = set() + for file in files: + if match_file(use_patterns, file): + return_files.add(file) + + return return_files + + +def normalize_file( + file: StrPath, + separators: Optional[Collection[str]] = None, +) -> str: + """ + Normalizes the file path to use the POSIX path separator (i.e., + ``"/"``), and make the paths relative (remove leading ``"/"``). + + *file* (:class:`str` or :class:`os.PathLike`) is the file path. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + ``None``) optionally contains the path separators to normalize. + This does not need to include the POSIX path separator (``"/"``), + but including it will not affect the results. Default is ``None`` + for ``NORMALIZE_PATH_SEPS``. To prevent normalization, pass an + empty container (e.g., an empty tuple ``()``). + + Returns the normalized file path (:class:`str`). + """ + # Normalize path separators. + if separators is None: + separators = NORMALIZE_PATH_SEPS + + # Convert path object to string. + norm_file: str = os.fspath(file) + + for sep in separators: + norm_file = norm_file.replace(sep, posixpath.sep) + + if norm_file.startswith('/'): + # Make path relative. + norm_file = norm_file[1:] + + elif norm_file.startswith('./'): + # Remove current directory prefix. + norm_file = norm_file[2:] + + return norm_file + + +def normalize_files( + files: Iterable[StrPath], + separators: Optional[Collection[str]] = None, +) -> Dict[str, List[StrPath]]: + """ + DEPRECATED: This function is no longer used. Use the :func:`.normalize_file` + function with a loop for better results. + + Normalizes the file paths to use the POSIX path separator. + + *files* (:class:`~collections.abc.Iterable` of :class:`str` or + :class:`os.PathLike`) contains the file paths to be normalized. + + *separators* (:class:`~collections.abc.Collection` of :class:`str`; or + :data:`None`) optionally contains the path separators to normalize. + See :func:`normalize_file` for more information. + + Returns a :class:`dict` mapping each normalized file path (:class:`str`) + to the original file paths (:class:`list` of :class:`str` or + :class:`os.PathLike`). + """ + warnings.warn(( + "util.normalize_files() is deprecated. Use util.normalize_file() " + "with a loop for better results." + ), DeprecationWarning, stacklevel=2) + + norm_files = {} + for path in files: + norm_file = normalize_file(path, separators=separators) + if norm_file in norm_files: + norm_files[norm_file].append(path) + else: + norm_files[norm_file] = [path] + + return norm_files + + +def register_pattern( + name: str, + pattern_factory: Callable[[AnyStr], Pattern], + override: Optional[bool] = None, +) -> None: + """ + Registers the specified pattern factory. + + *name* (:class:`str`) is the name to register the pattern factory + under. + + *pattern_factory* (:class:`~collections.abc.Callable`) is used to + compile patterns. It must accept an uncompiled pattern (:class:`str`) + and return the compiled pattern (:class:`.Pattern`). + + *override* (:class:`bool` or :data:`None`) optionally is whether to + allow overriding an already registered pattern under the same name + (:data:`True`), instead of raising an :exc:`AlreadyRegisteredError` + (:data:`False`). Default is :data:`None` for :data:`False`. + """ + if not isinstance(name, str): + raise TypeError(f"name:{name!r} is not a string.") + + if not callable(pattern_factory): + raise TypeError(f"pattern_factory:{pattern_factory!r} is not callable.") + + if name in _registered_patterns and not override: + raise AlreadyRegisteredError(name, _registered_patterns[name]) + + _registered_patterns[name] = pattern_factory + + +class AlreadyRegisteredError(Exception): + """ + The :exc:`AlreadyRegisteredError` exception is raised when a pattern + factory is registered under a name already in use. + """ + + def __init__( + self, + name: str, + pattern_factory: Callable[[AnyStr], Pattern], + ) -> None: + """ + Initializes the :exc:`AlreadyRegisteredError` instance. + + *name* (:class:`str`) is the name of the registered pattern. + + *pattern_factory* (:class:`~collections.abc.Callable`) is the + registered pattern factory. + """ + super(AlreadyRegisteredError, self).__init__(name, pattern_factory) + + @property + def message(self) -> str: + """ + *message* (:class:`str`) is the error message. + """ + return "{name!r} is already registered for pattern factory:{pattern_factory!r}.".format( + name=self.name, + pattern_factory=self.pattern_factory, + ) + + @property + def name(self) -> str: + """ + *name* (:class:`str`) is the name of the registered pattern. + """ + return self.args[0] + + @property + def pattern_factory(self) -> Callable[[AnyStr], Pattern]: + """ + *pattern_factory* (:class:`~collections.abc.Callable`) is the + registered pattern factory. + """ + return self.args[1] + + +class RecursionError(Exception): + """ + The :exc:`RecursionError` exception is raised when recursion is + detected. + """ + + def __init__( + self, + real_path: str, + first_path: str, + second_path: str, + ) -> None: + """ + Initializes the :exc:`RecursionError` instance. + + *real_path* (:class:`str`) is the real path that recursion was + encountered on. + + *first_path* (:class:`str`) is the first path encountered for + *real_path*. + + *second_path* (:class:`str`) is the second path encountered for + *real_path*. + """ + super(RecursionError, self).__init__(real_path, first_path, second_path) + + @property + def first_path(self) -> str: + """ + *first_path* (:class:`str`) is the first path encountered for + :attr:`self.real_path <RecursionError.real_path>`. + """ + return self.args[1] + + @property + def message(self) -> str: + """ + *message* (:class:`str`) is the error message. + """ + return "Real path {real!r} was encountered at {first!r} and then {second!r}.".format( + real=self.real_path, + first=self.first_path, + second=self.second_path, + ) + + @property + def real_path(self) -> str: + """ + *real_path* (:class:`str`) is the real path that recursion was + encountered on. + """ + return self.args[0] + + @property + def second_path(self) -> str: + """ + *second_path* (:class:`str`) is the second path encountered for + :attr:`self.real_path <RecursionError.real_path>`. + """ + return self.args[2] + + +@dataclass(frozen=True) +class CheckResult(Generic[TStrPath]): + """ + The :class:`CheckResult` class contains information about the file and which + pattern matched it. + """ + + # Make the class dict-less. + __slots__ = ( + 'file', + 'include', + 'index', + ) + + file: TStrPath + """ + *file* (:class:`str` or :class:`os.PathLike`) is the file path. + """ + + include: Optional[bool] + """ + *include* (:class:`bool` or :data:`None`) is whether to include or exclude the + file. If :data:`None`, no pattern matched. + """ + + index: Optional[int] + """ + *index* (:class:`int` or :data:`None`) is the index of the last pattern that + matched. If :data:`None`, no pattern matched. + """ + + +class MatchDetail(object): + """ + The :class:`.MatchDetail` class contains information about + """ + + # Make the class dict-less. + __slots__ = ('patterns',) + + def __init__(self, patterns: Sequence[Pattern]) -> None: + """ + Initialize the :class:`.MatchDetail` instance. + + *patterns* (:class:`~collections.abc.Sequence` of :class:`~pathspec.pattern.Pattern`) + contains the patterns that matched the file in the order they were + encountered. + """ + + self.patterns = patterns + """ + *patterns* (:class:`~collections.abc.Sequence` of :class:`~pathspec.pattern.Pattern`) + contains the patterns that matched the file in the order they were + encountered. + """ + + +class TreeEntry(object): + """ + The :class:`.TreeEntry` class contains information about a file-system + entry. + """ + + # Make the class dict-less. + __slots__ = ('_lstat', 'name', 'path', '_stat') + + def __init__( + self, + name: str, + path: str, + lstat: os.stat_result, + stat: os.stat_result, + ) -> None: + """ + Initialize the :class:`.TreeEntry` instance. + + *name* (:class:`str`) is the base name of the entry. + + *path* (:class:`str`) is the relative path of the entry. + + *lstat* (:class:`os.stat_result`) is the stat result of the direct + entry. + + *stat* (:class:`os.stat_result`) is the stat result of the entry, + potentially linked. + """ + + self._lstat: os.stat_result = lstat + """ + *_lstat* (:class:`os.stat_result`) is the stat result of the direct + entry. + """ + + self.name: str = name + """ + *name* (:class:`str`) is the base name of the entry. + """ + + self.path: str = path + """ + *path* (:class:`str`) is the path of the entry. + """ + + self._stat: os.stat_result = stat + """ + *_stat* (:class:`os.stat_result`) is the stat result of the linked + entry. + """ + + def is_dir(self, follow_links: Optional[bool] = None) -> bool: + """ + Get whether the entry is a directory. + + *follow_links* (:class:`bool` or :data:`None`) is whether to follow + symbolic links. If this is :data:`True`, a symlink to a directory + will result in :data:`True`. Default is :data:`None` for :data:`True`. + + Returns whether the entry is a directory (:class:`bool`). + """ + if follow_links is None: + follow_links = True + + node_stat = self._stat if follow_links else self._lstat + return stat.S_ISDIR(node_stat.st_mode) + + def is_file(self, follow_links: Optional[bool] = None) -> bool: + """ + Get whether the entry is a regular file. + + *follow_links* (:class:`bool` or :data:`None`) is whether to follow + symbolic links. If this is :data:`True`, a symlink to a regular file + will result in :data:`True`. Default is :data:`None` for :data:`True`. + + Returns whether the entry is a regular file (:class:`bool`). + """ + if follow_links is None: + follow_links = True + + node_stat = self._stat if follow_links else self._lstat + return stat.S_ISREG(node_stat.st_mode) + + def is_symlink(self) -> bool: + """ + Returns whether the entry is a symbolic link (:class:`bool`). + """ + return stat.S_ISLNK(self._lstat.st_mode) + + def stat(self, follow_links: Optional[bool] = None) -> os.stat_result: + """ + Get the cached stat result for the entry. + + *follow_links* (:class:`bool` or :data:`None`) is whether to follow + symbolic links. If this is :data:`True`, the stat result of the + linked file will be returned. Default is :data:`None` for :data:`True`. + + Returns that stat result (:class:`os.stat_result`). + """ + if follow_links is None: + follow_links = True + + return self._stat if follow_links else self._lstat diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/LICENSE new file mode 100644 index 00000000..3c84770c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/LICENSE @@ -0,0 +1,1343 @@ +The Python Imaging Library (PIL) is + + Copyright © 1997-2011 by Secret Labs AB + Copyright © 1995-2011 by Fredrik Lundh + +Pillow is the friendly PIL fork. It is + + Copyright © 2010-2024 by Jeffrey A. Clark (Alex) and contributors. + +Like PIL, Pillow is licensed under the open source HPND License: + +By obtaining, using, and/or copying this software and/or its associated +documentation, you agree that you have read, understood, and will comply +with the following terms and conditions: + +Permission to use, copy, modify and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appears in all copies, and that +both that copyright notice and this permission notice appear in supporting +documentation, and that the name of Secret Labs AB or the author not be +used in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + +---- + +BROTLI + +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---- + +BZIP2 + + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2019 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward@acm.org +bzip2/libbzip2 version 1.0.8 of 13 July 2019 + +-------------------------------------------------------------------------- + + +---- + +FREETYPE2 + +The FreeType 2 font engine is copyrighted work and cannot be used +legally without a software license. In order to make this project +usable to a vast majority of developers, we distribute it under two +mutually exclusive open-source licenses. + +This means that *you* must choose *one* of the two licenses described +below, then obey all its terms and conditions when using FreeType 2 in +any of your projects or products. + + - The FreeType License, found in the file `docs/FTL.TXT`, which is + similar to the original BSD license *with* an advertising clause + that forces you to explicitly cite the FreeType project in your + product's documentation. All details are in the license file. + This license is suited to products which don't use the GNU General + Public License. + + Note that this license is compatible to the GNU General Public + License version 3, but not version 2. + + - The GNU General Public License version 2, found in + `docs/GPLv2.TXT` (any later version can be used also), for + programs which already use the GPL. Note that the FTL is + incompatible with GPLv2 due to its advertisement clause. + +The contributed BDF and PCF drivers come with a license similar to +that of the X Window System. It is compatible to the above two +licenses (see files `src/bdf/README` and `src/pcf/README`). The same +holds for the source code files `src/base/fthash.c` and +`include/freetype/internal/fthash.h`; they were part of the BDF driver +in earlier FreeType versions. + +The gzip module uses the zlib license (see `src/gzip/zlib.h`) which +too is compatible to the above two licenses. + +The files `src/autofit/ft-hb.c` and `src/autofit/ft-hb.h` contain code +taken almost verbatim from the HarfBuzz file `hb-ft.cc`, which uses +the 'Old MIT' license, compatible to the above two licenses. + +The MD5 checksum support (only used for debugging in development +builds) is in the public domain. + +-------------------------------------------------------------------------- + + The FreeType Project LICENSE + ---------------------------- + + 2006-Jan-27 + + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © <year> The FreeType + Project (www.freetype.org). All rights reserved. + """ + + Please replace <year> with the value from the FreeType version you + actually use. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@nongnu.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o freetype-devel@nongnu.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + Our home page can be found at + + https://www.freetype.org + + +--- end of FTL.TXT --- + +-------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +-------------------------------------------------------------------------- + +The following license details are part of `src/bdf/README`: + +``` +License +******* + +Copyright (C) 2001-2002 by Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*** Portions of the driver (that is, bdflib.c and bdf.h): + +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2002, 2011 Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Credits +******* + +This driver is based on excellent Mark Leisher's bdf library. If you +find something good in this driver you should probably thank him, not +me. +``` + +The following license details are part of `src/pcf/README`: + +``` +License +******* + +Copyright (C) 2000 by Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Credits +******* + +Keith Packard wrote the pcf driver found in XFree86. His work is at +the same time the specification and the sample implementation of the +PCF format. Undoubtedly, this driver is inspired from his work. +``` + + +---- + +HARFBUZZ + +HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. +For parts of HarfBuzz that are licensed under different licenses see individual +files names COPYING in subdirectories where applicable. + +Copyright © 2010-2022 Google, Inc. +Copyright © 2015-2020 Ebrahim Byagowi +Copyright © 2019,2020 Facebook, Inc. +Copyright © 2012,2015 Mozilla Foundation +Copyright © 2011 Codethink Limited +Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) +Copyright © 2009 Keith Stribley +Copyright © 2011 Martin Hosken and SIL International +Copyright © 2007 Chris Wilson +Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod +Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc. +Copyright © 1998-2005 David Turner and Werner Lemberg +Copyright © 2016 Igalia S.L. +Copyright © 2022 Matthias Clasen +Copyright © 2018,2021 Khaled Hosny +Copyright © 2018,2019,2020 Adobe, Inc +Copyright © 2013-2015 Alexei Podtelezhnikov + +For full copyright notices consult the individual files in the package. + + +Permission is hereby granted, without written agreement and without +license or royalty fees, to use, copy, modify, and distribute this +software and its documentation for any purpose, provided that the +above copyright notice and the following two paragraphs appear in +all copies of this software. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + +---- + +LCMS2 + +Little CMS +Copyright (c) 1998-2020 Marti Maria Saguer + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---- + +LIBJPEG + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +---- + +LIBLZMA + +XZ Utils Licensing +================== + + Different licenses apply to different files in this package. Here + is a rough summary of which licenses apply to which parts of this + package (but check the individual files to be sure!): + + - liblzma is in the public domain. + + - xz, xzdec, and lzmadec command line tools are in the public + domain unless GNU getopt_long had to be compiled and linked + in from the lib directory. The getopt_long code is under + GNU LGPLv2.1+. + + - The scripts to grep, diff, and view compressed files have been + adapted from gzip. These scripts and their documentation are + under GNU GPLv2+. + + - All the documentation in the doc directory and most of the + XZ Utils specific documentation files in other directories + are in the public domain. + + - Translated messages are in the public domain. + + - The build system contains public domain files, and files that + are under GNU GPLv2+ or GNU GPLv3+. None of these files end up + in the binaries being built. + + - Test files and test code in the tests directory, and debugging + utilities in the debug directory are in the public domain. + + - The extra directory may contain public domain files, and files + that are under various free software licenses. + + You can do whatever you want with the files that have been put into + the public domain. If you find public domain legally problematic, + take the previous sentence as a license grant. If you still find + the lack of copyright legally problematic, you have too many + lawyers. + + As usual, this software is provided "as is", without any warranty. + + If you copy significant amounts of public domain code from XZ Utils + into your project, acknowledging this somewhere in your software is + polite (especially if it is proprietary, non-free software), but + naturally it is not legally required. Here is an example of a good + notice to put into "about box" or into documentation: + + This software includes code from XZ Utils <http://tukaani.org/xz/>. + + The following license texts are included in the following files: + - COPYING.LGPLv2.1: GNU Lesser General Public License version 2.1 + - COPYING.GPLv2: GNU General Public License version 2 + - COPYING.GPLv3: GNU General Public License version 3 + + Note that the toolchain (compiler, linker etc.) may add some code + pieces that are copyrighted. Thus, it is possible that e.g. liblzma + binary wouldn't actually be in the public domain in its entirety + even though it contains no copyrighted code from the XZ Utils source + package. + + If you have questions, don't hesitate to ask the author(s) for more + information. + + +---- + +LIBPNG + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= + +PNG Reference Library License version 2 +--------------------------------------- + + * Copyright (c) 1995-2022 The PNG Reference Library Authors. + * Copyright (c) 2018-2022 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no event shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. + +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- + +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are +derived from libpng-1.0.6, and are distributed according to the same +disclaimer and license as libpng-1.0.6 with the following individuals +added to the list of Contributing Authors: + + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. + +Some files in the "contrib" directory and some configure-generated +files that are distributed with libpng have other copyright owners, and +are released under other open source licenses. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from +libpng-0.96, and are distributed according to the same disclaimer and +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, +and are distributed according to the same disclaimer and license as +libpng-0.88, with the following individuals added to the list of +Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +Some files in the "scripts" directory have other copyright owners, +but are released under this license. + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated. + + +---- + +LIBTIFF + +Copyright (c) 1988-1997 Sam Leffler +Copyright (c) 1991-1997 Silicon Graphics, Inc. + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. + + +---- + +LIBWEBP + +Copyright (c) 2010, Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---- + +OPENJPEG + +* + * The copyright in this software is being made available under the 2-clauses + * BSD License, included below. This software may be subject to other third + * party and contributor rights, including patent rights, and no such rights + * are granted under this license. + * + * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2014, Professor Benoit Macq + * Copyright (c) 2003-2014, Antonin Descampe + * Copyright (c) 2003-2009, Francois-Olivier Devaux + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France + * Copyright (c) 2012, CS Systemes d'Information, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +---- + +RAQM + +The MIT License (MIT) + +Copyright © 2015 Information Technology Authority (ITA) <foss@ita.gov.om> +Copyright © 2016 Khaled Hosny <khaledhosny@eglug.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +---- + +XAU + +Copyright 1988, 1993, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +---- + +XCB + +Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall +be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the authors +or their institutions shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this +Software without prior written authorization from the +authors. + + +---- + +XDMCP + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Keith Packard, MIT X Consortium + + +---- + +ZLIB + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/METADATA new file mode 100644 index 00000000..fddcff33 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/METADATA @@ -0,0 +1,182 @@ +Metadata-Version: 2.1 +Name: pillow +Version: 10.2.0 +Summary: Python Imaging Library (Fork) +Author-email: "Jeffrey A. Clark (Alex)" <aclark@aclark.net> +License: HPND +Project-URL: Changelog, https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst +Project-URL: Documentation, https://pillow.readthedocs.io +Project-URL: Funding, https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=pypi +Project-URL: Homepage, https://python-pillow.org +Project-URL: Mastodon, https://fosstodon.org/@pillow +Project-URL: Release notes, https://pillow.readthedocs.io/en/stable/releasenotes/index.html +Project-URL: Source, https://github.com/python-pillow/Pillow +Project-URL: Twitter, https://twitter.com/PythonPillow +Keywords: Imaging +Classifier: Development Status :: 6 - Mature +Classifier: License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND) +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Multimedia :: Graphics +Classifier: Topic :: Multimedia :: Graphics :: Capture :: Digital Camera +Classifier: Topic :: Multimedia :: Graphics :: Capture :: Screen Capture +Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion +Classifier: Topic :: Multimedia :: Graphics :: Viewers +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: docs +Requires-Dist: furo ; extra == 'docs' +Requires-Dist: olefile ; extra == 'docs' +Requires-Dist: sphinx >=2.4 ; extra == 'docs' +Requires-Dist: sphinx-copybutton ; extra == 'docs' +Requires-Dist: sphinx-inline-tabs ; extra == 'docs' +Requires-Dist: sphinx-removed-in ; extra == 'docs' +Requires-Dist: sphinxext-opengraph ; extra == 'docs' +Provides-Extra: fpx +Requires-Dist: olefile ; extra == 'fpx' +Provides-Extra: mic +Requires-Dist: olefile ; extra == 'mic' +Provides-Extra: tests +Requires-Dist: check-manifest ; extra == 'tests' +Requires-Dist: coverage ; extra == 'tests' +Requires-Dist: defusedxml ; extra == 'tests' +Requires-Dist: markdown2 ; extra == 'tests' +Requires-Dist: olefile ; extra == 'tests' +Requires-Dist: packaging ; extra == 'tests' +Requires-Dist: pyroma ; extra == 'tests' +Requires-Dist: pytest ; extra == 'tests' +Requires-Dist: pytest-cov ; extra == 'tests' +Requires-Dist: pytest-timeout ; extra == 'tests' +Provides-Extra: typing +Requires-Dist: typing-extensions ; (python_version < "3.10") and extra == 'typing' +Provides-Extra: xmp +Requires-Dist: defusedxml ; extra == 'xmp' + +<p align="center"> + <img width="248" height="250" src="https://raw.githubusercontent.com/python-pillow/pillow-logo/main/pillow-logo-248x250.png" alt="Pillow logo"> +</p> + +# Pillow + +## Python Imaging Library (Fork) + +Pillow is the friendly PIL fork by [Jeffrey A. Clark (Alex) and +contributors](https://github.com/python-pillow/Pillow/graphs/contributors). +PIL is the Python Imaging Library by Fredrik Lundh and Contributors. +As of 2019, Pillow development is +[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise). + +<table> + <tr> + <th>docs</th> + <td> + <a href="https://pillow.readthedocs.io/?badge=latest"><img + alt="Documentation Status" + src="https://readthedocs.org/projects/pillow/badge/?version=latest"></a> + </td> + </tr> + <tr> + <th>tests</th> + <td> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/lint.yml"><img + alt="GitHub Actions build status (Lint)" + src="https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/test.yml"><img + alt="GitHub Actions build status (Test Linux and macOS)" + src="https://github.com/python-pillow/Pillow/workflows/Test/badge.svg"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-windows.yml"><img + alt="GitHub Actions build status (Test Windows)" + src="https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml"><img + alt="GitHub Actions build status (Test MinGW)" + src="https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-cygwin.yml"><img + alt="GitHub Actions build status (Test Cygwin)" + src="https://github.com/python-pillow/Pillow/workflows/Test%20Cygwin/badge.svg"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml"><img + alt="GitHub Actions build status (Test Docker)" + src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a> + <a href="https://ci.appveyor.com/project/python-pillow/Pillow"><img + alt="AppVeyor CI build status (Windows)" + src="https://img.shields.io/appveyor/build/python-pillow/Pillow/main.svg?label=Windows%20build"></a> + <a href="https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml"><img + alt="GitHub Actions build status (Wheels)" + src="https://github.com/python-pillow/Pillow/workflows/Wheels/badge.svg"></a> + <a href="https://app.travis-ci.com/github/python-pillow/Pillow"><img + alt="Travis CI wheels build status (aarch64)" + src="https://img.shields.io/travis/com/python-pillow/Pillow/main.svg?label=aarch64%20wheels"></a> + <a href="https://app.codecov.io/gh/python-pillow/Pillow"><img + alt="Code coverage" + src="https://codecov.io/gh/python-pillow/Pillow/branch/main/graph/badge.svg"></a> + <a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:pillow"><img + alt="Fuzzing Status" + src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/pillow.svg"></a> + </td> + </tr> + <tr> + <th>package</th> + <td> + <a href="https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow"><img + alt="Zenodo" + src="https://zenodo.org/badge/17549/python-pillow/Pillow.svg"></a> + <a href="https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=badge"><img + alt="Tidelift" + src="https://tidelift.com/badges/package/pypi/Pillow?style=flat"></a> + <a href="https://pypi.org/project/Pillow/"><img + alt="Newest PyPI version" + src="https://img.shields.io/pypi/v/pillow.svg"></a> + <a href="https://pypi.org/project/Pillow/"><img + alt="Number of PyPI downloads" + src="https://img.shields.io/pypi/dm/pillow.svg"></a> + <a href="https://www.bestpractices.dev/projects/6331"><img + alt="OpenSSF Best Practices" + src="https://www.bestpractices.dev/projects/6331/badge"></a> + </td> + </tr> + <tr> + <th>social</th> + <td> + <a href="https://gitter.im/python-pillow/Pillow?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img + alt="Join the chat at https://gitter.im/python-pillow/Pillow" + src="https://badges.gitter.im/python-pillow/Pillow.svg"></a> + <a href="https://twitter.com/PythonPillow"><img + alt="Follow on https://twitter.com/PythonPillow" + src="https://img.shields.io/badge/tweet-on%20Twitter-00aced.svg"></a> + <a href="https://fosstodon.org/@pillow"><img + alt="Follow on https://fosstodon.org/@pillow" + src="https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg" + rel="me"></a> + </td> + </tr> +</table> + +## Overview + +The Python Imaging Library adds image processing capabilities to your Python interpreter. + +This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities. + +The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool. + +## More Information + +- [Documentation](https://pillow.readthedocs.io/) + - [Installation](https://pillow.readthedocs.io/en/latest/installation.html) + - [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html) +- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md) + - [Issues](https://github.com/python-pillow/Pillow/issues) + - [Pull requests](https://github.com/python-pillow/Pillow/pulls) +- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html) +- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) + - [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork) + +## Report a Vulnerability + +To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security). diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/RECORD new file mode 100644 index 00000000..4fc0e589 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/RECORD @@ -0,0 +1,223 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/BdfFontFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/BlpImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/BmpImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/BufrStubImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ContainerIO.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/CurImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/DcxImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/DdsImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/EpsImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ExifTags.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/FitsImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/FliImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/FontFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/FpxImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/FtexImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GbrImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GdImageFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GifImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GimpGradientFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GimpPaletteFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/GribStubImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/Hdf5StubImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/IcnsImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/IcoImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/Image.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageChops.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageCms.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageColor.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageDraw2.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageEnhance.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFilter.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageFont.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageGrab.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMath.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMode.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageMorph.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageOps.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePalette.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImagePath.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageQt.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageSequence.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageShow.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageStat.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTk.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageTransform.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImageWin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/ImtImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/IptcImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/Jpeg2KImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/JpegImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/JpegPresets.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/McIdasImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/MicImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/MpegImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/MpoImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/MspImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PSDraw.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PaletteFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PalmImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PcdImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PcfFontFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PcxImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PdfImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PdfParser.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PixarImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PngImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PpmImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PsdImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/PyAccess.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/QoiImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/SgiImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/SpiderImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/SunImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/TarIO.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/TgaImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/TiffImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/TiffTags.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/WalImageFile.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/WebPImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/WmfImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/XVThumbImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/XbmImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/XpmImagePlugin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/__main__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_binary.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_deprecate.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_tkinter_finder.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_typing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_util.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/_version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/PIL/features.cpython-39.pyc,, +PIL/.dylibs/libXau.6.0.0.dylib,sha256=03eUonpG-PVxdwhyjI0w_rpEjAJjrS4k_X_XK9M5XnY,70048 +PIL/.dylibs/libbrotlicommon.1.1.0.dylib,sha256=QydEAXecWtbHU9AmTgtatL8Vddlizsl6dyXHfaCkhic,201200 +PIL/.dylibs/libbrotlidec.1.1.0.dylib,sha256=__lMDbf1XWLWaQ22OQRbWG_BmwQS2zrJ6P3sbmod-tU,104544 +PIL/.dylibs/libfreetype.6.dylib,sha256=Dw7qeUujry6wdwaLDat_eWjKfQWJDqyoEJdLH53Zbzo,1142208 +PIL/.dylibs/libharfbuzz.0.dylib,sha256=SW4kdDzPE0dXlZC7ezdu31UHputYsweElquNTCbdC5Q,4348768 +PIL/.dylibs/libjpeg.62.4.0.dylib,sha256=k2MpefzZPiKoBGyZ17-W1Iln4g2spTJeEtjJEL95KVw,573248 +PIL/.dylibs/liblcms2.2.dylib,sha256=GE8XuVbPCuI4OzuAN-sk-g0XjFSgu5880yjswbkrbN8,523584 +PIL/.dylibs/liblzma.5.dylib,sha256=d0t64J6YHGHx_jJ5eWDvaSkFZDs3QhipGWAbdB3IW2E,323280 +PIL/.dylibs/libopenjp2.2.5.0.dylib,sha256=sbH3V9_LoNCnYmUL3R06xuADXwUKdtqTVrgpcprztR4,665760 +PIL/.dylibs/libpng16.16.dylib,sha256=jpauBIr-DUWxlHfUM-k0VOL0dtisiuhxQa6tTd9d1zA,344928 +PIL/.dylibs/libsharpyuv.0.dylib,sha256=N7UP6aF4wPQo5InuoXvgVNsEElwfgdDmimAXwbnFEJw,69408 +PIL/.dylibs/libtiff.6.dylib,sha256=MkSX2cmj0_1xNiZfQ3ybLn45ZgwJWDAUz8wAryjgrNc,751472 +PIL/.dylibs/libwebp.7.dylib,sha256=mI3xRQjh_X1-30VylMT6TZDwfdgAQG6NVYa5M7PxLj8,514272 +PIL/.dylibs/libwebpdemux.2.dylib,sha256=N_vZHAv8p3gm1H1NJYNsTSJz_AjqcII9nYjnFi41pW8,69872 +PIL/.dylibs/libwebpmux.3.dylib,sha256=lZS-w9G4QouoPe6Gd9itzGlXOTaWVMi13o-oG15LvcQ,105920 +PIL/.dylibs/libxcb.1.1.0.dylib,sha256=g9ejsbpk1E-Xpdyg4wtAtHRYo-OMT6caj7HhWPLDjf0,277696 +PIL/.dylibs/libz.1.3.dylib,sha256=gJqfVVxZ8AGDjYqKayKFjvkSTqjsrGYBIerySucNy8o,174784 +PIL/BdfFontFile.py,sha256=CgWJtLCciuqgkpRedO-0xvIYsEe-AGUxs5k9AGbllPg,3469 +PIL/BlpImagePlugin.py,sha256=AuzKyME8-lGusxhWNw-Gy4i5OiK58BUf341GrJwIvac,15569 +PIL/BmpImagePlugin.py,sha256=rBG0UMmwEH7sneMLRdZXLqZbiPFWbGDLzhgUDq2y3GI,17699 +PIL/BufrStubImagePlugin.py,sha256=6b85Pu28dcbLAaCCZHWfhRkAU5-_J7lMWVRi-C6QnPc,1592 +PIL/ContainerIO.py,sha256=0lHPzJmOqWx2XK_oBQeiwBbr8Y6xT182Y72q_yj6wIo,3181 +PIL/CurImagePlugin.py,sha256=9aIXiNuTVkA0WlcPb5q5C5ZiDVcGBeI-EfsP5FjtP8U,1741 +PIL/DcxImagePlugin.py,sha256=A3Av_UXMGR51I8TmBQTJIQUyLbLUwUho0gHKDEQIIp0,1993 +PIL/DdsImagePlugin.py,sha256=8EpTFrYKy49zm1c8rhf-Ts5quzSXDhG0f7JVeUEobg0,16539 +PIL/EpsImagePlugin.py,sha256=2RktUZljG27e5eLZAXA6tRIRFpshdcWD6_JXHCl4wNc,15919 +PIL/ExifTags.py,sha256=zuMaexyJLTtuVZlOv43_P7qR7YMgjHffu7SOpPdvN3E,9753 +PIL/FitsImagePlugin.py,sha256=kzGddPcFZ-wjZhv48mHv-zA8SVG9rlyIytzQ6zOdGyA,2000 +PIL/FliImagePlugin.py,sha256=Ce4lhNCfrzlleWOGs7vGmLX3wul7uLIOrVxHI_ufsbU,4523 +PIL/FontFile.py,sha256=cEA7RQKpMcsXTbTLraBYNWEz2N3x47rz0VeYnlj5Uyw,3591 +PIL/FpxImagePlugin.py,sha256=mXaNTmqTRx8v2YrA5ujT31Ph92pdQo082fqStGLLQTg,6983 +PIL/FtexImagePlugin.py,sha256=USOGJE-qbbz2i2kqsgbhNe5MkesOrCYDNDkB-MDCoOg,3465 +PIL/GbrImagePlugin.py,sha256=eMCpGbv7k1kO-o0LxfWbPivVOW85sxzhj80m79KQqlY,2945 +PIL/GdImageFile.py,sha256=SNBzEAyZIeYYue_gIue4Ngr0G93WEScsiWM5hxdYvk8,2642 +PIL/GifImagePlugin.py,sha256=s34iS6fV0kz4tD73nCABbSuono7vk2S0VdTJl22TAHE,37203 +PIL/GimpGradientFile.py,sha256=tsjtwjYF66-bf1XNsTM5wI6Ix_wDODDO4TsDAhVhA4U,3430 +PIL/GimpPaletteFile.py,sha256=cEgzwxWE7Un4ecteOuKQtOCzXKnDZB1XBUPr8eOFymw,1380 +PIL/GribStubImagePlugin.py,sha256=_RF5KKShDil6f1ZBppBxZ9ZDzLzA4SfF8NU0O3sxqWk,1586 +PIL/Hdf5StubImagePlugin.py,sha256=Ryc2pROK1Zv67JOsNqWNc69qjX4EefdnLZolryEW4ZI,1589 +PIL/IcnsImagePlugin.py,sha256=KvI7GUIPjUHvjgFib08Xnr-S95jJE47flrpEaKGGfCk,11996 +PIL/IcoImagePlugin.py,sha256=Hi5jh3H6H-1fc8q4CrhNxLqXzZu4BjWZMdFrTCH5p0g,11574 +PIL/ImImagePlugin.py,sha256=l7PD_fbTEDfbqzGbo8Pir6EudzTvnFGOVWXyYkZAYCY,10904 +PIL/Image.py,sha256=bdqvPbFUqfwuymWqnhr47-bJ-hka5jolRj8J15q9lsA,134480 +PIL/ImageChops.py,sha256=GEjlymcoDtA5OOeIxQVIX96BD-s6AXhb7TmSLYn2tUg,7946 +PIL/ImageCms.py,sha256=6uJ1DXxJYstDSckcgFetzAKDQwkGCjrQ8uLy5iz7vnU,37181 +PIL/ImageColor.py,sha256=0FcbJ8P79HwEZeD82hZQ888KMtW5CWDteuuvLaptuB8,9173 +PIL/ImageDraw.py,sha256=HvxImwYIAyIPnyLADiU1DMNDcR9jdtTYBD-6RUS4Yyk,36435 +PIL/ImageDraw2.py,sha256=mbG4zwC6tCpMwea4fzXLCO2dT7D4FS5Qu4C5n1XupE0,5535 +PIL/ImageEnhance.py,sha256=2sC99It-If3s69RzTdDVV0lLscdE0P5ZbNflOzm6FPE,3225 +PIL/ImageFile.py,sha256=FHWA782rQqbbOjoNo4uW8q3FA6HLriarpZpAuEBtAL4,24345 +PIL/ImageFilter.py,sha256=HbRCGz_ErSUs4bT9qP0eg5gfr8fB_4nGnEjPP8nRcNM,17143 +PIL/ImageFont.py,sha256=W2uoXRPwSr9Gh_2kR5Iyc2rQfwu4Gxo2ejPkZcWPrLg,60840 +PIL/ImageGrab.py,sha256=5DDhN0PhU-JIDBrjooXUnPlTAIxgcE9iNh5C3oWex0c,5630 +PIL/ImageMath.py,sha256=TqzLP2bwj6FU6vel8nqoV64190dBgr5gqw73vgG-KQg,7509 +PIL/ImageMode.py,sha256=aqTBqT_GqrlBo0azaCmEPzHj6pasdtk2aWDGGna0meA,2770 +PIL/ImageMorph.py,sha256=jUIZZMjfvxI2lsE5GeNJaFvl7rIzCRY_XxuVs7f6Lm8,8012 +PIL/ImageOps.py,sha256=uS6DkoM9laNqNZm0rAZt2bofnb4P-16GjkpU0Az1KKo,22458 +PIL/ImagePalette.py,sha256=RBsDBC1kJHEc5OuDaIup48NuLxFSOIZWtqGOAZJvj7g,7763 +PIL/ImagePath.py,sha256=5yUG5XCUil1KKTTA_8PgGhcmg-mnue-GK0FwTBlhjw4,371 +PIL/ImageQt.py,sha256=DhUBqFaQr8TGHZAYPONY_dgaOC7vxnUzUzsVJRQaKYo,5745 +PIL/ImageSequence.py,sha256=j-i3HxuBqkVFPPZSRerCeRlkAYG0orFkWc9mG5IhYSM,2192 +PIL/ImageShow.py,sha256=IjMLpgJ50pRYc-f7-xZlzqrrwGBGf-P_v8HoX4IYBNY,8392 +PIL/ImageStat.py,sha256=ImYsQY6lIdht8_pNmofHXHMz_tWlsV3ct2eHDbx0DEA,3724 +PIL/ImageTk.py,sha256=v7UpqgvLscTrc3woG_q0HQLlAX1JZMgj3nmXVi2rJb0,8496 +PIL/ImageTransform.py,sha256=QbNygcTyHzCfSpNK7wFZQJ2dEJ1d2uIUJUYjLlsvkBE,3164 +PIL/ImageWin.py,sha256=AeO3qPyeQzEOagNb9AWOiWX2ZyRK4qTyEXgdttF-YzI,7226 +PIL/ImtImagePlugin.py,sha256=Kb3yzGSr4GuN_Dp-vQI1ob7HW_s8agqp0-gKG8Lqt7U,2614 +PIL/IptcImagePlugin.py,sha256=ZCydfUtpgPeMz1o9Fg9mkE0HUrU-wUUt9ijge7g7pH4,6135 +PIL/Jpeg2KImagePlugin.py,sha256=wXem0GpIymfqrSNmA5o2-H2q0YIeBPxGT9F4q5H9GrQ,11573 +PIL/JpegImagePlugin.py,sha256=HsFU08YvgKbveI17n-Xr-ROGhYXrq8YBD62FDp2jMrg,29578 +PIL/JpegPresets.py,sha256=9TUIdnpWJQHtew5Mh__t7GE5jyLZVnilWJ28BZvhlC4,12378 +PIL/McIdasImagePlugin.py,sha256=qMFakL7l4YCbb4GaiZt2rxLceS5Dwj-PMtFrmF3JzGM,1832 +PIL/MicImagePlugin.py,sha256=ghIjl4yl-ifdH7ykjkokhd2dMCOc5Bpn2wi0FJ4gpM8,2615 +PIL/MpegImagePlugin.py,sha256=4XlVZbLjYUDLQUiJXUuoPcZKbCsjrLb4j89Ue-Mptnw,1858 +PIL/MpoImagePlugin.py,sha256=_NELKSFJqmCNLhgnAA7RjLkWUooKq2gHdgHDwXnEibw,6255 +PIL/MspImagePlugin.py,sha256=WSm2IvKq0s7k9054-LmOz6rsXZCejMSfnrZXrcBOKDw,5648 +PIL/PSDraw.py,sha256=n-UXRnVJAALbmL3aVYJz9_D_CAkpDulXCnHs2Esfn7c,6560 +PIL/PaletteFile.py,sha256=ZMuQqDZ7X9d_c9LRMV7Wku1U7v_rVIHlT0Zipu4W4Eg,1163 +PIL/PalmImagePlugin.py,sha256=Txc8OcCjyJiR80npQKgw06-JgX_pFnEv8BHsF3co64M,9179 +PIL/PcdImagePlugin.py,sha256=0fIQ-vUvMcD13NqhYk4UNCTajxsZSFqdQnSqBP4VrSw,1531 +PIL/PcfFontFile.py,sha256=NPZQ0XkbGB8uTlGqgmIPGkwuLMYBdykDeVuvFgIC7JU,7147 +PIL/PcxImagePlugin.py,sha256=Z7INEBrZt3JdYFT73H741A1P7FHd6N_lrMGdxCI_gp4,6057 +PIL/PdfImagePlugin.py,sha256=6bQN-R47u-fGMVLtBirn8sV9ENFfD13IptJzAEJqEcc,8841 +PIL/PdfParser.py,sha256=de45wTgum1mNNzBURVxbnyIE9TWhFB4lapJWT0ScVcw,34483 +PIL/PixarImagePlugin.py,sha256=_kySXXNkfkPgVLd5H_xXi7vHfEy_fY42W4fBo2cXRoY,1687 +PIL/PngImagePlugin.py,sha256=tZr5QSRYbeZmMuHGW7Z0HZ4tj_7Og2OYWPWKFk803yY,46481 +PIL/PpmImagePlugin.py,sha256=o9Nm2Y7R2uw5HtYx-cJKRMsmeof2zXA2fazB13eCz1E,11359 +PIL/PsdImagePlugin.py,sha256=IDHRQQrP--TaqNf45rM-oWnDrSNrPUBPAYzw2A38358,7697 +PIL/PyAccess.py,sha256=l0v6Sd0ha80QM4TULXuK7t_Ph2VwNG_MzGOuwhQj2S8,9909 +PIL/QoiImagePlugin.py,sha256=R3EQMRD4N-jy1mquob4xtLyzlSF6CiljiKc7cx83Vqs,3670 +PIL/SgiImagePlugin.py,sha256=irpZprRXEM01GjcWgwO5hlbWw1RuYGMG9QlxDeB2eMo,6184 +PIL/SpiderImagePlugin.py,sha256=WoiSQ-PX30v5ZR8oECFEo_z5tLobeVS1MZQWp8uEL2Y,9467 +PIL/SunImagePlugin.py,sha256=Zyzd_n8OVaD_ECUPMdg7YViGVfRLhR-2b8z6vPYCTL4,4440 +PIL/TarIO.py,sha256=p2NKGZ9-rKCVdLT5Bc3K_mpNc7SRaZ_b9g86y8WGZuo,1739 +PIL/TgaImagePlugin.py,sha256=Sgd8Zm7sLSZC1xp-35Ve2gEXgaZBPv0s1YpUN5ZyM3k,6615 +PIL/TiffImagePlugin.py,sha256=xibeBz2VQESXEgj8p876nSI6PY53q3cr76G8Cl5NlCM,76701 +PIL/TiffTags.py,sha256=ZmHL4R5_xkb_PwH0Kz7Pu6wlX80gn0800ysaAd79JSw,16567 +PIL/WalImageFile.py,sha256=HUnZ08FnSpFyLS8QEUAX3HdhS0FiVrEfweczbGmVyYM,5555 +PIL/WebPImagePlugin.py,sha256=u8vPrNJXiaA0yLIv6Qtpxv3YgN0T0vveUfF7SIGH-2g,11320 +PIL/WmfImagePlugin.py,sha256=zfqPQqk0rGPQYmoP_g0euoOYdBjQZr0RtCGk3n2Oxjg,4726 +PIL/XVThumbImagePlugin.py,sha256=QydC-4ISyYMIWWCYEVXZRBqgouv7S8cG7Sq222wNk8A,2022 +PIL/XbmImagePlugin.py,sha256=JrNSE9gesB7jEb9_iBLu3xIYHozoPbQEKQNleETJXtQ,2523 +PIL/XpmImagePlugin.py,sha256=P6RNrQQlko-1hKtKRAzad6RVUQ7JrjUizD__6zZeT1M,3219 +PIL/__init__.py,sha256=xJm_loI9xcfcm1_sa9l8mXH7l1f9573QnhcW_ngX9y8,2014 +PIL/__main__.py,sha256=LiJGDPwg067ZaSwzvYXzXsusvNCvOT3SgZp9_YwGLpI,77 +PIL/_binary.py,sha256=2qsiRyxBrHwPBm9OeqgSBN0bW_kwsiF8-OmAxzgP-Sw,2279 +PIL/_deprecate.py,sha256=Kt1jv0PTNdqqZksTO2g6XIXgnglkUv3ILRQ8nlP1IKc,2000 +PIL/_imaging.cpython-39-darwin.so,sha256=gL31YNw4qqgRt9Q9nmwwk5QNqcC3fViyvYOlYPLWlMM,560624 +PIL/_imagingcms.cpython-39-darwin.so,sha256=afxnSvBucB3v9MA6BqJAvnk-tx4fSxJ-K3UedNT2PkM,99424 +PIL/_imagingcms.pyi,sha256=uN4MUZ6avvQ7ZRsGS9neyFpi76OYlxLv7SOrmwS0TtQ,99 +PIL/_imagingft.cpython-39-darwin.so,sha256=ZAO9NF8Bm29bYcv7E3EYMPf-oRbFLPrj-J-2kj7Rfbo,117776 +PIL/_imagingft.pyi,sha256=uN4MUZ6avvQ7ZRsGS9neyFpi76OYlxLv7SOrmwS0TtQ,99 +PIL/_imagingmath.cpython-39-darwin.so,sha256=T1v6ZQRuavux3NMdZDRDZJn76hu0LcO05-xtU3XVDgU,72222 +PIL/_imagingmorph.cpython-39-darwin.so,sha256=K1xOhVpybQy4VM39Z_scbAJlqqPf3fQajDJvyVPNgSY,51327 +PIL/_imagingtk.cpython-39-darwin.so,sha256=owopQzRw0zpIuYhq-wvUizjcEUpL0tbORKKyeLEkCDQ,52636 +PIL/_tkinter_finder.py,sha256=T9mPJn0kOMBd449ks26RgIVcoJdV0Pq-hI96Jmir3pQ,539 +PIL/_typing.py,sha256=EOvAj7Z7yFQGe4CQzCdXrcH1aCNwDmD-ig1p3Y-LPLg,402 +PIL/_util.py,sha256=kYai_kiMPzmVmoHOsqtNg516QcsuGymoUE3xBh41nL4,823 +PIL/_version.py,sha256=wTAXIDScPCi6rN3xG3UOqezq0mqLgFmsKxU1U8M5iNs,87 +PIL/_webp.cpython-39-darwin.so,sha256=bu6oGmSAJh_XDfMBmzdy8WLbUrHl5RvNGg1zOoD3sqs,76864 +PIL/features.py,sha256=ZtIUwxcwRTf_MVzQ9LLbd6lDhKkU5SQ1BSxv61auazo,9654 +pillow-10.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pillow-10.2.0.dist-info/LICENSE,sha256=F64uYNddUtaEMBgLfbPmONZMbYBpqR51xYMzmvx3bHM,60064 +pillow-10.2.0.dist-info/METADATA,sha256=fZlKCvuFmrHk6sj1aII6g7Kv2q3uD3qzvp3_iYa-4p4,9708 +pillow-10.2.0.dist-info/RECORD,, +pillow-10.2.0.dist-info/WHEEL,sha256=JlTVwpqUzP01iqSUKAL8LrwscoYFkCFkZ28SRV9G62c,108 +pillow-10.2.0.dist-info/top_level.txt,sha256=riZqrk-hyZqh5f1Z0Zwii3dKfxEsByhu9cU9IODF-NY,4 +pillow-10.2.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/WHEEL new file mode 100644 index 00000000..876de0f5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: false +Tag: cp39-cp39-macosx_11_0_arm64 + diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/top_level.txt new file mode 100644 index 00000000..b338169c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/top_level.txt @@ -0,0 +1 @@ +PIL diff --git a/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/zip-safe b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/zip-safe new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pillow-10.2.0.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/LICENSE new file mode 100644 index 00000000..85f4dd63 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/METADATA new file mode 100644 index 00000000..684704f4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/METADATA @@ -0,0 +1,140 @@ +Metadata-Version: 2.1 +Name: pluggy +Version: 1.3.0 +Summary: plugin and hook calling mechanisms for python +Home-page: https://github.com/pytest-dev/pluggy +Author: Holger Krekel +Author-email: holger@merlinux.eu +License: MIT +Platform: unix +Platform: linux +Platform: osx +Platform: win32 +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Topic :: Software Development :: Testing +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE +Provides-Extra: dev +Requires-Dist: pre-commit ; extra == 'dev' +Requires-Dist: tox ; extra == 'dev' +Provides-Extra: testing +Requires-Dist: pytest ; extra == 'testing' +Requires-Dist: pytest-benchmark ; extra == 'testing' + +==================================================== +pluggy - A minimalist production ready plugin system +==================================================== + +|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov| + +This is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects. + +Please `read the docs`_ to learn more! + +A definitive example +==================== +.. code-block:: python + + import pluggy + + hookspec = pluggy.HookspecMarker("myproject") + hookimpl = pluggy.HookimplMarker("myproject") + + + class MySpec: + """A hook specification namespace.""" + + @hookspec + def myhook(self, arg1, arg2): + """My special little hook that you can customize.""" + + + class Plugin_1: + """A hook implementation namespace.""" + + @hookimpl + def myhook(self, arg1, arg2): + print("inside Plugin_1.myhook()") + return arg1 + arg2 + + + class Plugin_2: + """A 2nd hook implementation namespace.""" + + @hookimpl + def myhook(self, arg1, arg2): + print("inside Plugin_2.myhook()") + return arg1 - arg2 + + + # create a manager and add the spec + pm = pluggy.PluginManager("myproject") + pm.add_hookspecs(MySpec) + + # register plugins + pm.register(Plugin_1()) + pm.register(Plugin_2()) + + # call our ``myhook`` hook + results = pm.hook.myhook(arg1=1, arg2=2) + print(results) + + +Running this directly gets us:: + + $ python docs/examples/toy-example.py + inside Plugin_2.myhook() + inside Plugin_1.myhook() + [-1, 3] + + +.. badges + +.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg + :target: https://pypi.org/pypi/pluggy + +.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg + :target: https://pypi.org/pypi/pluggy + +.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg + :target: https://github.com/pytest-dev/pluggy/actions + +.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg + :target: https://anaconda.org/conda-forge/pytest + +.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg + :alt: Join the chat at https://gitter.im/pytest-dev/pluggy + :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + +.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg + :target: https://codecov.io/gh/pytest-dev/pluggy + :alt: Code coverage Status + +.. links +.. _pytest: + http://pytest.org +.. _tox: + https://tox.readthedocs.org +.. _devpi: + http://doc.devpi.net +.. _read the docs: + https://pluggy.readthedocs.io/en/latest/ diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/RECORD new file mode 100644 index 00000000..fdbc202a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/RECORD @@ -0,0 +1,21 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_callers.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_hooks.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_manager.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_result.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_tracing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pluggy/_version.cpython-39.pyc,, +pluggy-1.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pluggy-1.3.0.dist-info/LICENSE,sha256=1rZebCE6XQtXeRHTTW5ZSbn1nXbCOMUHGi8_wWz7JgY,1110 +pluggy-1.3.0.dist-info/METADATA,sha256=cewZlldDixhBWMw_A8PNP1-9HyUgDq7jncO9GtQOiOs,4277 +pluggy-1.3.0.dist-info/RECORD,, +pluggy-1.3.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92 +pluggy-1.3.0.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7 +pluggy/__init__.py,sha256=CjD3L_WaOpbeQEKrl4RYsMUSta_anw0gmKjaM1SaXho,714 +pluggy/_callers.py,sha256=ijxhDDj5SAIpe_dc3DNQ7Buu2sy7TesG8SkOF_VcGh0,6233 +pluggy/_hooks.py,sha256=TiGLtCACb0bT77yt_Koze3evTAZmTE3Xg_T8AtBaA9U,23877 +pluggy/_manager.py,sha256=fcYU7VER0CplRym4jAJ7RCFYl6cfDSeVM589YHHx9uA,19517 +pluggy/_result.py,sha256=CMpNNTgyptUnoYigRZHuJs11gKt9OwTOteDYhY3wAFM,3238 +pluggy/_tracing.py,sha256=ui2w1xQpsjn67ISaEmizvgojXXAUmRL2nwlV-VXmemc,2088 +pluggy/_version.py,sha256=foCZ2hOsQWwUKwjI0-E5-fQh5s9IVn0hjo8sXE-FKwQ,160 +pluggy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/WHEEL new file mode 100644 index 00000000..7e688737 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/top_level.txt new file mode 100644 index 00000000..11bdb5c1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy-1.3.0.dist-info/top_level.txt @@ -0,0 +1 @@ +pluggy diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/__init__.py new file mode 100644 index 00000000..9d9e873b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/__init__.py @@ -0,0 +1,33 @@ +try: + from ._version import version as __version__ +except ImportError: + # broken installation, we don't even try + # unknown only works because we do poor mans version compare + __version__ = "unknown" + +__all__ = [ + "__version__", + "PluginManager", + "PluginValidationError", + "HookCaller", + "HookCallError", + "HookspecOpts", + "HookimplOpts", + "HookImpl", + "HookRelay", + "HookspecMarker", + "HookimplMarker", + "Result", +] + +from ._manager import PluginManager, PluginValidationError +from ._result import HookCallError, Result +from ._hooks import ( + HookspecMarker, + HookimplMarker, + HookCaller, + HookRelay, + HookspecOpts, + HookimplOpts, + HookImpl, +) diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_callers.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_callers.py new file mode 100644 index 00000000..6498eaed --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_callers.py @@ -0,0 +1,152 @@ +""" +Call loop machinery +""" +from __future__ import annotations + +from typing import cast +from typing import Generator +from typing import Mapping +from typing import Sequence +from typing import Tuple +from typing import Union + +from ._hooks import HookImpl +from ._result import _raise_wrapfail +from ._result import HookCallError +from ._result import Result + + +# Need to distinguish between old- and new-style hook wrappers. +# Wrapping one a singleton tuple is the fastest type-safe way I found to do it. +Teardown = Union[ + Tuple[Generator[None, Result[object], None]], + Generator[None, object, object], +] + + +def _multicall( + hook_name: str, + hook_impls: Sequence[HookImpl], + caller_kwargs: Mapping[str, object], + firstresult: bool, +) -> object | list[object]: + """Execute a call into multiple python functions/methods and return the + result(s). + + ``caller_kwargs`` comes from HookCaller.__call__(). + """ + __tracebackhide__ = True + results: list[object] = [] + exception = None + only_new_style_wrappers = True + try: # run impl and wrapper setup functions in a loop + teardowns: list[Teardown] = [] + try: + for hook_impl in reversed(hook_impls): + try: + args = [caller_kwargs[argname] for argname in hook_impl.argnames] + except KeyError: + for argname in hook_impl.argnames: + if argname not in caller_kwargs: + raise HookCallError( + f"hook call must provide argument {argname!r}" + ) + + if hook_impl.hookwrapper: + only_new_style_wrappers = False + try: + # If this cast is not valid, a type error is raised below, + # which is the desired response. + res = hook_impl.function(*args) + wrapper_gen = cast(Generator[None, Result[object], None], res) + next(wrapper_gen) # first yield + teardowns.append((wrapper_gen,)) + except StopIteration: + _raise_wrapfail(wrapper_gen, "did not yield") + elif hook_impl.wrapper: + try: + # If this cast is not valid, a type error is raised below, + # which is the desired response. + res = hook_impl.function(*args) + function_gen = cast(Generator[None, object, object], res) + next(function_gen) # first yield + teardowns.append(function_gen) + except StopIteration: + _raise_wrapfail(function_gen, "did not yield") + else: + res = hook_impl.function(*args) + if res is not None: + results.append(res) + if firstresult: # halt further impl calls + break + except BaseException as exc: + exception = exc + finally: + # Fast path - only new-style wrappers, no Result. + if only_new_style_wrappers: + if firstresult: # first result hooks return a single value + result = results[0] if results else None + else: + result = results + + # run all wrapper post-yield blocks + for teardown in reversed(teardowns): + try: + if exception is not None: + teardown.throw(exception) # type: ignore[union-attr] + else: + teardown.send(result) # type: ignore[union-attr] + # Following is unreachable for a well behaved hook wrapper. + # Try to force finalizers otherwise postponed till GC action. + # Note: close() may raise if generator handles GeneratorExit. + teardown.close() # type: ignore[union-attr] + except StopIteration as si: + result = si.value + exception = None + continue + except BaseException as e: + exception = e + continue + _raise_wrapfail(teardown, "has second yield") # type: ignore[arg-type] + + if exception is not None: + raise exception.with_traceback(exception.__traceback__) + else: + return result + + # Slow path - need to support old-style wrappers. + else: + if firstresult: # first result hooks return a single value + outcome: Result[object | list[object]] = Result( + results[0] if results else None, exception + ) + else: + outcome = Result(results, exception) + + # run all wrapper post-yield blocks + for teardown in reversed(teardowns): + if isinstance(teardown, tuple): + try: + teardown[0].send(outcome) + _raise_wrapfail(teardown[0], "has second yield") + except StopIteration: + pass + else: + try: + if outcome._exception is not None: + teardown.throw(outcome._exception) + else: + teardown.send(outcome._result) + # Following is unreachable for a well behaved hook wrapper. + # Try to force finalizers otherwise postponed till GC action. + # Note: close() may raise if generator handles GeneratorExit. + teardown.close() + except StopIteration as si: + outcome.force_result(si.value) + continue + except BaseException as e: + outcome.force_exception(e) + continue + _raise_wrapfail(teardown, "has second yield") + + return outcome.get_result() diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_hooks.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_hooks.py new file mode 100644 index 00000000..916ca704 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_hooks.py @@ -0,0 +1,691 @@ +""" +Internal hook annotation, representation and calling machinery. +""" +from __future__ import annotations + +import inspect +import sys +import warnings +from types import ModuleType +from typing import AbstractSet +from typing import Any +from typing import Callable +from typing import Final +from typing import final +from typing import Generator +from typing import List +from typing import Mapping +from typing import Optional +from typing import overload +from typing import Sequence +from typing import Tuple +from typing import TYPE_CHECKING +from typing import TypedDict +from typing import TypeVar +from typing import Union + +from ._result import Result + + +_T = TypeVar("_T") +_F = TypeVar("_F", bound=Callable[..., object]) +_Namespace = Union[ModuleType, type] +_Plugin = object +_HookExec = Callable[ + [str, Sequence["HookImpl"], Mapping[str, object], bool], + Union[object, List[object]], +] +_HookImplFunction = Callable[..., Union[_T, Generator[None, Result[_T], None]]] + + +class HookspecOpts(TypedDict): + """Options for a hook specification.""" + + #: Whether the hook is :ref:`first result only <firstresult>`. + firstresult: bool + #: Whether the hook is :ref:`historic <historic>`. + historic: bool + #: Whether the hook :ref:`warns when implemented <warn_on_impl>`. + warn_on_impl: Warning | None + + +class HookimplOpts(TypedDict): + """Options for a hook implementation.""" + + #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`. + wrapper: bool + #: Whether the hook implementation is an :ref:`old-style wrapper + #: <old_style_hookwrappers>`. + hookwrapper: bool + #: Whether validation against a hook specification is :ref:`optional + #: <optionalhook>`. + optionalhook: bool + #: Whether to try to order this hook implementation :ref:`first + #: <callorder>`. + tryfirst: bool + #: Whether to try to order this hook implementation :ref:`last + #: <callorder>`. + trylast: bool + #: The name of the hook specification to match, see :ref:`specname`. + specname: str | None + + +@final +class HookspecMarker: + """Decorator for marking functions as hook specifications. + + Instantiate it with a project_name to get a decorator. + Calling :meth:`PluginManager.add_hookspecs` later will discover all marked + functions if the :class:`PluginManager` uses the same project name. + """ + + __slots__ = ("project_name",) + + def __init__(self, project_name: str) -> None: + self.project_name: Final = project_name + + @overload + def __call__( + self, + function: _F, + firstresult: bool = False, + historic: bool = False, + warn_on_impl: Warning | None = None, + ) -> _F: + ... + + @overload # noqa: F811 + def __call__( # noqa: F811 + self, + function: None = ..., + firstresult: bool = ..., + historic: bool = ..., + warn_on_impl: Warning | None = ..., + ) -> Callable[[_F], _F]: + ... + + def __call__( # noqa: F811 + self, + function: _F | None = None, + firstresult: bool = False, + historic: bool = False, + warn_on_impl: Warning | None = None, + ) -> _F | Callable[[_F], _F]: + """If passed a function, directly sets attributes on the function + which will make it discoverable to :meth:`PluginManager.add_hookspecs`. + + If passed no function, returns a decorator which can be applied to a + function later using the attributes supplied. + + :param firstresult: + If ``True``, the 1:N hook call (N being the number of registered + hook implementation functions) will stop at I<=N when the I'th + function returns a non-``None`` result. See :ref:`firstresult`. + + :param historic: + If ``True``, every call to the hook will be memorized and replayed + on plugins registered after the call was made. See :ref:`historic`. + + :param warn_on_impl: + If given, every implementation of this hook will trigger the given + warning. See :ref:`warn_on_impl`. + """ + + def setattr_hookspec_opts(func: _F) -> _F: + if historic and firstresult: + raise ValueError("cannot have a historic firstresult hook") + opts: HookspecOpts = { + "firstresult": firstresult, + "historic": historic, + "warn_on_impl": warn_on_impl, + } + setattr(func, self.project_name + "_spec", opts) + return func + + if function is not None: + return setattr_hookspec_opts(function) + else: + return setattr_hookspec_opts + + +@final +class HookimplMarker: + """Decorator for marking functions as hook implementations. + + Instantiate it with a ``project_name`` to get a decorator. + Calling :meth:`PluginManager.register` later will discover all marked + functions if the :class:`PluginManager` uses the same project name. + """ + + __slots__ = ("project_name",) + + def __init__(self, project_name: str) -> None: + self.project_name: Final = project_name + + @overload + def __call__( + self, + function: _F, + hookwrapper: bool = ..., + optionalhook: bool = ..., + tryfirst: bool = ..., + trylast: bool = ..., + specname: str | None = ..., + wrapper: bool = ..., + ) -> _F: + ... + + @overload # noqa: F811 + def __call__( # noqa: F811 + self, + function: None = ..., + hookwrapper: bool = ..., + optionalhook: bool = ..., + tryfirst: bool = ..., + trylast: bool = ..., + specname: str | None = ..., + wrapper: bool = ..., + ) -> Callable[[_F], _F]: + ... + + def __call__( # noqa: F811 + self, + function: _F | None = None, + hookwrapper: bool = False, + optionalhook: bool = False, + tryfirst: bool = False, + trylast: bool = False, + specname: str | None = None, + wrapper: bool = False, + ) -> _F | Callable[[_F], _F]: + """If passed a function, directly sets attributes on the function + which will make it discoverable to :meth:`PluginManager.register`. + + If passed no function, returns a decorator which can be applied to a + function later using the attributes supplied. + + :param optionalhook: + If ``True``, a missing matching hook specification will not result + in an error (by default it is an error if no matching spec is + found). See :ref:`optionalhook`. + + :param tryfirst: + If ``True``, this hook implementation will run as early as possible + in the chain of N hook implementations for a specification. See + :ref:`callorder`. + + :param trylast: + If ``True``, this hook implementation will run as late as possible + in the chain of N hook implementations for a specification. See + :ref:`callorder`. + + :param wrapper: + If ``True`` ("new-style hook wrapper"), the hook implementation + needs to execute exactly one ``yield``. The code before the + ``yield`` is run early before any non-hook-wrapper function is run. + The code after the ``yield`` is run after all non-hook-wrapper + functions have run. The ``yield`` receives the result value of the + inner calls, or raises the exception of inner calls (including + earlier hook wrapper calls). The return value of the function + becomes the return value of the hook, and a raised exception becomes + the exception of the hook. See :ref:`hookwrapper`. + + :param hookwrapper: + If ``True`` ("old-style hook wrapper"), the hook implementation + needs to execute exactly one ``yield``. The code before the + ``yield`` is run early before any non-hook-wrapper function is run. + The code after the ``yield`` is run after all non-hook-wrapper + function have run The ``yield`` receives a :class:`Result` object + representing the exception or result outcome of the inner calls + (including earlier hook wrapper calls). This option is mutually + exclusive with ``wrapper``. See :ref:`old_style_hookwrapper`. + + :param specname: + If provided, the given name will be used instead of the function + name when matching this hook implementation to a hook specification + during registration. See :ref:`specname`. + + .. versionadded:: 1.2.0 + The ``wrapper`` parameter. + """ + + def setattr_hookimpl_opts(func: _F) -> _F: + opts: HookimplOpts = { + "wrapper": wrapper, + "hookwrapper": hookwrapper, + "optionalhook": optionalhook, + "tryfirst": tryfirst, + "trylast": trylast, + "specname": specname, + } + setattr(func, self.project_name + "_impl", opts) + return func + + if function is None: + return setattr_hookimpl_opts + else: + return setattr_hookimpl_opts(function) + + +def normalize_hookimpl_opts(opts: HookimplOpts) -> None: + opts.setdefault("tryfirst", False) + opts.setdefault("trylast", False) + opts.setdefault("wrapper", False) + opts.setdefault("hookwrapper", False) + opts.setdefault("optionalhook", False) + opts.setdefault("specname", None) + + +_PYPY = hasattr(sys, "pypy_version_info") + + +def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]: + """Return tuple of positional and keywrord argument names for a function, + method, class or callable. + + In case of a class, its ``__init__`` method is considered. + For methods the ``self`` parameter is not included. + """ + if inspect.isclass(func): + try: + func = func.__init__ + except AttributeError: + return (), () + elif not inspect.isroutine(func): # callable object? + try: + func = getattr(func, "__call__", func) + except Exception: + return (), () + + try: + # func MUST be a function or method here or we won't parse any args. + sig = inspect.signature( + func.__func__ if inspect.ismethod(func) else func # type:ignore[arg-type] + ) + except TypeError: + return (), () + + _valid_param_kinds = ( + inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD, + ) + _valid_params = { + name: param + for name, param in sig.parameters.items() + if param.kind in _valid_param_kinds + } + args = tuple(_valid_params) + defaults = ( + tuple( + param.default + for param in _valid_params.values() + if param.default is not param.empty + ) + or None + ) + + if defaults: + index = -len(defaults) + args, kwargs = args[:index], tuple(args[index:]) + else: + kwargs = () + + # strip any implicit instance arg + # pypy3 uses "obj" instead of "self" for default dunder methods + if not _PYPY: + implicit_names: tuple[str, ...] = ("self",) + else: + implicit_names = ("self", "obj") + if args: + qualname: str = getattr(func, "__qualname__", "") + if inspect.ismethod(func) or ("." in qualname and args[0] in implicit_names): + args = args[1:] + + return args, kwargs + + +@final +class HookRelay: + """Hook holder object for performing 1:N hook calls where N is the number + of registered plugins.""" + + __slots__ = ("__dict__",) + + def __init__(self) -> None: + """:meta private:""" + + if TYPE_CHECKING: + + def __getattr__(self, name: str) -> HookCaller: + ... + + +# Historical name (pluggy<=1.2), kept for backward compatibility. +_HookRelay = HookRelay + + +_CallHistory = List[Tuple[Mapping[str, object], Optional[Callable[[Any], None]]]] + + +class HookCaller: + """A caller of all registered implementations of a hook specification.""" + + __slots__ = ( + "name", + "spec", + "_hookexec", + "_hookimpls", + "_call_history", + ) + + def __init__( + self, + name: str, + hook_execute: _HookExec, + specmodule_or_class: _Namespace | None = None, + spec_opts: HookspecOpts | None = None, + ) -> None: + """:meta private:""" + #: Name of the hook getting called. + self.name: Final = name + self._hookexec: Final = hook_execute + self._hookimpls: Final[list[HookImpl]] = [] + self._call_history: _CallHistory | None = None + # TODO: Document, or make private. + self.spec: HookSpec | None = None + if specmodule_or_class is not None: + assert spec_opts is not None + self.set_specification(specmodule_or_class, spec_opts) + + # TODO: Document, or make private. + def has_spec(self) -> bool: + return self.spec is not None + + # TODO: Document, or make private. + def set_specification( + self, + specmodule_or_class: _Namespace, + spec_opts: HookspecOpts, + ) -> None: + if self.spec is not None: + raise ValueError( + f"Hook {self.spec.name!r} is already registered " + f"within namespace {self.spec.namespace}" + ) + self.spec = HookSpec(specmodule_or_class, self.name, spec_opts) + if spec_opts.get("historic"): + self._call_history = [] + + def is_historic(self) -> bool: + """Whether this caller is :ref:`historic <historic>`.""" + return self._call_history is not None + + def _remove_plugin(self, plugin: _Plugin) -> None: + for i, method in enumerate(self._hookimpls): + if method.plugin == plugin: + del self._hookimpls[i] + return + raise ValueError(f"plugin {plugin!r} not found") + + def get_hookimpls(self) -> list[HookImpl]: + """Get all registered hook implementations for this hook.""" + return self._hookimpls.copy() + + def _add_hookimpl(self, hookimpl: HookImpl) -> None: + """Add an implementation to the callback chain.""" + for i, method in enumerate(self._hookimpls): + if method.hookwrapper or method.wrapper: + splitpoint = i + break + else: + splitpoint = len(self._hookimpls) + if hookimpl.hookwrapper or hookimpl.wrapper: + start, end = splitpoint, len(self._hookimpls) + else: + start, end = 0, splitpoint + + if hookimpl.trylast: + self._hookimpls.insert(start, hookimpl) + elif hookimpl.tryfirst: + self._hookimpls.insert(end, hookimpl) + else: + # find last non-tryfirst method + i = end - 1 + while i >= start and self._hookimpls[i].tryfirst: + i -= 1 + self._hookimpls.insert(i + 1, hookimpl) + + def __repr__(self) -> str: + return f"<HookCaller {self.name!r}>" + + def _verify_all_args_are_provided(self, kwargs: Mapping[str, object]) -> None: + # This is written to avoid expensive operations when not needed. + if self.spec: + for argname in self.spec.argnames: + if argname not in kwargs: + notincall = ", ".join( + repr(argname) + for argname in self.spec.argnames + # Avoid self.spec.argnames - kwargs.keys() - doesn't preserve order. + if argname not in kwargs.keys() + ) + warnings.warn( + "Argument(s) {} which are declared in the hookspec " + "cannot be found in this hook call".format(notincall), + stacklevel=2, + ) + break + + def __call__(self, **kwargs: object) -> Any: + """Call the hook. + + Only accepts keyword arguments, which should match the hook + specification. + + Returns the result(s) of calling all registered plugins, see + :ref:`calling`. + """ + assert ( + not self.is_historic() + ), "Cannot directly call a historic hook - use call_historic instead." + self._verify_all_args_are_provided(kwargs) + firstresult = self.spec.opts.get("firstresult", False) if self.spec else False + return self._hookexec(self.name, self._hookimpls, kwargs, firstresult) + + def call_historic( + self, + result_callback: Callable[[Any], None] | None = None, + kwargs: Mapping[str, object] | None = None, + ) -> None: + """Call the hook with given ``kwargs`` for all registered plugins and + for all plugins which will be registered afterwards, see + :ref:`historic`. + + :param result_callback: + If provided, will be called for each non-``None`` result obtained + from a hook implementation. + """ + assert self._call_history is not None + kwargs = kwargs or {} + self._verify_all_args_are_provided(kwargs) + self._call_history.append((kwargs, result_callback)) + # Historizing hooks don't return results. + # Remember firstresult isn't compatible with historic. + res = self._hookexec(self.name, self._hookimpls, kwargs, False) + if result_callback is None: + return + if isinstance(res, list): + for x in res: + result_callback(x) + + def call_extra( + self, methods: Sequence[Callable[..., object]], kwargs: Mapping[str, object] + ) -> Any: + """Call the hook with some additional temporarily participating + methods using the specified ``kwargs`` as call parameters, see + :ref:`call_extra`.""" + assert ( + not self.is_historic() + ), "Cannot directly call a historic hook - use call_historic instead." + self._verify_all_args_are_provided(kwargs) + opts: HookimplOpts = { + "wrapper": False, + "hookwrapper": False, + "optionalhook": False, + "trylast": False, + "tryfirst": False, + "specname": None, + } + hookimpls = self._hookimpls.copy() + for method in methods: + hookimpl = HookImpl(None, "<temp>", method, opts) + # Find last non-tryfirst nonwrapper method. + i = len(hookimpls) - 1 + while ( + i >= 0 + and hookimpls[i].tryfirst + and not (hookimpls[i].hookwrapper or hookimpls[i].wrapper) + ): + i -= 1 + hookimpls.insert(i + 1, hookimpl) + firstresult = self.spec.opts.get("firstresult", False) if self.spec else False + return self._hookexec(self.name, hookimpls, kwargs, firstresult) + + def _maybe_apply_history(self, method: HookImpl) -> None: + """Apply call history to a new hookimpl if it is marked as historic.""" + if self.is_historic(): + assert self._call_history is not None + for kwargs, result_callback in self._call_history: + res = self._hookexec(self.name, [method], kwargs, False) + if res and result_callback is not None: + # XXX: remember firstresult isn't compat with historic + assert isinstance(res, list) + result_callback(res[0]) + + +# Historical name (pluggy<=1.2), kept for backward compatibility. +_HookCaller = HookCaller + + +class _SubsetHookCaller(HookCaller): + """A proxy to another HookCaller which manages calls to all registered + plugins except the ones from remove_plugins.""" + + # This class is unusual: in inhertits from `HookCaller` so all of + # the *code* runs in the class, but it delegates all underlying *data* + # to the original HookCaller. + # `subset_hook_caller` used to be implemented by creating a full-fledged + # HookCaller, copying all hookimpls from the original. This had problems + # with memory leaks (#346) and historic calls (#347), which make a proxy + # approach better. + # An alternative implementation is to use a `_getattr__`/`__getattribute__` + # proxy, however that adds more overhead and is more tricky to implement. + + __slots__ = ( + "_orig", + "_remove_plugins", + ) + + def __init__(self, orig: HookCaller, remove_plugins: AbstractSet[_Plugin]) -> None: + self._orig = orig + self._remove_plugins = remove_plugins + self.name = orig.name # type: ignore[misc] + self._hookexec = orig._hookexec # type: ignore[misc] + + @property # type: ignore[misc] + def _hookimpls(self) -> list[HookImpl]: + return [ + impl + for impl in self._orig._hookimpls + if impl.plugin not in self._remove_plugins + ] + + @property + def spec(self) -> HookSpec | None: # type: ignore[override] + return self._orig.spec + + @property + def _call_history(self) -> _CallHistory | None: # type: ignore[override] + return self._orig._call_history + + def __repr__(self) -> str: + return f"<_SubsetHookCaller {self.name!r}>" + + +@final +class HookImpl: + """A hook implementation in a :class:`HookCaller`.""" + + __slots__ = ( + "function", + "argnames", + "kwargnames", + "plugin", + "opts", + "plugin_name", + "wrapper", + "hookwrapper", + "optionalhook", + "tryfirst", + "trylast", + ) + + def __init__( + self, + plugin: _Plugin, + plugin_name: str, + function: _HookImplFunction[object], + hook_impl_opts: HookimplOpts, + ) -> None: + """:meta private:""" + #: The hook implementation function. + self.function: Final = function + argnames, kwargnames = varnames(self.function) + #: The positional parameter names of ``function```. + self.argnames: Final = argnames + #: The keyword parameter names of ``function```. + self.kwargnames: Final = kwargnames + #: The plugin which defined this hook implementation. + self.plugin: Final = plugin + #: The :class:`HookimplOpts` used to configure this hook implementation. + self.opts: Final = hook_impl_opts + #: The name of the plugin which defined this hook implementation. + self.plugin_name: Final = plugin_name + #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`. + self.wrapper: Final = hook_impl_opts["wrapper"] + #: Whether the hook implementation is an :ref:`old-style wrapper + #: <old_style_hookwrappers>`. + self.hookwrapper: Final = hook_impl_opts["hookwrapper"] + #: Whether validation against a hook specification is :ref:`optional + #: <optionalhook>`. + self.optionalhook: Final = hook_impl_opts["optionalhook"] + #: Whether to try to order this hook implementation :ref:`first + #: <callorder>`. + self.tryfirst: Final = hook_impl_opts["tryfirst"] + #: Whether to try to order this hook implementation :ref:`last + #: <callorder>`. + self.trylast: Final = hook_impl_opts["trylast"] + + def __repr__(self) -> str: + return f"<HookImpl plugin_name={self.plugin_name!r}, plugin={self.plugin!r}>" + + +@final +class HookSpec: + __slots__ = ( + "namespace", + "function", + "name", + "argnames", + "kwargnames", + "opts", + "warn_on_impl", + ) + + def __init__(self, namespace: _Namespace, name: str, opts: HookspecOpts) -> None: + self.namespace = namespace + self.function: Callable[..., object] = getattr(namespace, name) + self.name = name + self.argnames, self.kwargnames = varnames(self.function) + self.opts = opts + self.warn_on_impl = opts.get("warn_on_impl") diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_manager.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_manager.py new file mode 100644 index 00000000..84717e6e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_manager.py @@ -0,0 +1,505 @@ +from __future__ import annotations + +import importlib.metadata +import inspect +import types +import warnings +from typing import Any +from typing import Callable +from typing import cast +from typing import Final +from typing import Iterable +from typing import Mapping +from typing import Sequence + +from . import _tracing +from ._callers import _multicall +from ._hooks import _HookImplFunction +from ._hooks import _Namespace +from ._hooks import _Plugin +from ._hooks import _SubsetHookCaller +from ._hooks import HookCaller +from ._hooks import HookImpl +from ._hooks import HookimplOpts +from ._hooks import HookRelay +from ._hooks import HookspecOpts +from ._hooks import normalize_hookimpl_opts +from ._result import Result + + +_BeforeTrace = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None] +_AfterTrace = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None] + + +def _warn_for_function(warning: Warning, function: Callable[..., object]) -> None: + func = cast(types.FunctionType, function) + warnings.warn_explicit( + warning, + type(warning), + lineno=func.__code__.co_firstlineno, + filename=func.__code__.co_filename, + ) + + +class PluginValidationError(Exception): + """Plugin failed validation. + + :param plugin: The plugin which failed validation. + :param message: Error message. + """ + + def __init__(self, plugin: _Plugin, message: str) -> None: + super().__init__(message) + #: The plugin which failed validation. + self.plugin = plugin + + +class DistFacade: + """Emulate a pkg_resources Distribution""" + + def __init__(self, dist: importlib.metadata.Distribution) -> None: + self._dist = dist + + @property + def project_name(self) -> str: + name: str = self.metadata["name"] + return name + + def __getattr__(self, attr: str, default=None): + return getattr(self._dist, attr, default) + + def __dir__(self) -> list[str]: + return sorted(dir(self._dist) + ["_dist", "project_name"]) + + +class PluginManager: + """Core class which manages registration of plugin objects and 1:N hook + calling. + + You can register new hooks by calling :meth:`add_hookspecs(module_or_class) + <PluginManager.add_hookspecs>`. + + You can register plugin objects (which contain hook implementations) by + calling :meth:`register(plugin) <PluginManager.register>`. + + For debugging purposes you can call :meth:`PluginManager.enable_tracing` + which will subsequently send debug information to the trace helper. + + :param project_name: + The short project name. Prefer snake case. Make sure it's unique! + """ + + def __init__(self, project_name: str) -> None: + #: The project name. + self.project_name: Final = project_name + self._name2plugin: Final[dict[str, _Plugin]] = {} + self._plugin_distinfo: Final[list[tuple[_Plugin, DistFacade]]] = [] + #: The "hook relay", used to call a hook on all registered plugins. + #: See :ref:`calling`. + self.hook: Final = HookRelay() + #: The tracing entry point. See :ref:`tracing`. + self.trace: Final[_tracing.TagTracerSub] = _tracing.TagTracer().get( + "pluginmanage" + ) + self._inner_hookexec = _multicall + + def _hookexec( + self, + hook_name: str, + methods: Sequence[HookImpl], + kwargs: Mapping[str, object], + firstresult: bool, + ) -> object | list[object]: + # called from all hookcaller instances. + # enable_tracing will set its own wrapping function at self._inner_hookexec + return self._inner_hookexec(hook_name, methods, kwargs, firstresult) + + def register(self, plugin: _Plugin, name: str | None = None) -> str | None: + """Register a plugin and return its name. + + :param name: + The name under which to register the plugin. If not specified, a + name is generated using :func:`get_canonical_name`. + + :returns: + The plugin name. If the name is blocked from registering, returns + ``None``. + + If the plugin is already registered, raises a :exc:`ValueError`. + """ + plugin_name = name or self.get_canonical_name(plugin) + + if plugin_name in self._name2plugin: + if self._name2plugin.get(plugin_name, -1) is None: + return None # blocked plugin, return None to indicate no registration + raise ValueError( + "Plugin name already registered: %s=%s\n%s" + % (plugin_name, plugin, self._name2plugin) + ) + + if plugin in self._name2plugin.values(): + raise ValueError( + "Plugin already registered under a different name: %s=%s\n%s" + % (plugin_name, plugin, self._name2plugin) + ) + + # XXX if an error happens we should make sure no state has been + # changed at point of return + self._name2plugin[plugin_name] = plugin + + # register matching hook implementations of the plugin + for name in dir(plugin): + hookimpl_opts = self.parse_hookimpl_opts(plugin, name) + if hookimpl_opts is not None: + normalize_hookimpl_opts(hookimpl_opts) + method: _HookImplFunction[object] = getattr(plugin, name) + hookimpl = HookImpl(plugin, plugin_name, method, hookimpl_opts) + name = hookimpl_opts.get("specname") or name + hook: HookCaller | None = getattr(self.hook, name, None) + if hook is None: + hook = HookCaller(name, self._hookexec) + setattr(self.hook, name, hook) + elif hook.has_spec(): + self._verify_hook(hook, hookimpl) + hook._maybe_apply_history(hookimpl) + hook._add_hookimpl(hookimpl) + return plugin_name + + def parse_hookimpl_opts(self, plugin: _Plugin, name: str) -> HookimplOpts | None: + """Try to obtain a hook implementation from an item with the given name + in the given plugin which is being searched for hook impls. + + :returns: + The parsed hookimpl options, or None to skip the given item. + + This method can be overridden by ``PluginManager`` subclasses to + customize how hook implementation are picked up. By default, returns the + options for items decorated with :class:`HookimplMarker`. + """ + method: object = getattr(plugin, name) + if not inspect.isroutine(method): + return None + try: + res: HookimplOpts | None = getattr( + method, self.project_name + "_impl", None + ) + except Exception: + res = {} # type: ignore[assignment] + if res is not None and not isinstance(res, dict): + # false positive + res = None # type:ignore[unreachable] + return res + + def unregister( + self, plugin: _Plugin | None = None, name: str | None = None + ) -> Any | None: + """Unregister a plugin and all of its hook implementations. + + The plugin can be specified either by the plugin object or the plugin + name. If both are specified, they must agree. + + Returns the unregistered plugin, or ``None`` if not found. + """ + if name is None: + assert plugin is not None, "one of name or plugin needs to be specified" + name = self.get_name(plugin) + assert name is not None, "plugin is not registered" + + if plugin is None: + plugin = self.get_plugin(name) + if plugin is None: + return None + + hookcallers = self.get_hookcallers(plugin) + if hookcallers: + for hookcaller in hookcallers: + hookcaller._remove_plugin(plugin) + + # if self._name2plugin[name] == None registration was blocked: ignore + if self._name2plugin.get(name): + assert name is not None + del self._name2plugin[name] + + return plugin + + def set_blocked(self, name: str) -> None: + """Block registrations of the given name, unregister if already registered.""" + self.unregister(name=name) + self._name2plugin[name] = None + + def is_blocked(self, name: str) -> bool: + """Return whether the given plugin name is blocked.""" + return name in self._name2plugin and self._name2plugin[name] is None + + def add_hookspecs(self, module_or_class: _Namespace) -> None: + """Add new hook specifications defined in the given ``module_or_class``. + + Functions are recognized as hook specifications if they have been + decorated with a matching :class:`HookspecMarker`. + """ + names = [] + for name in dir(module_or_class): + spec_opts = self.parse_hookspec_opts(module_or_class, name) + if spec_opts is not None: + hc: HookCaller | None = getattr(self.hook, name, None) + if hc is None: + hc = HookCaller(name, self._hookexec, module_or_class, spec_opts) + setattr(self.hook, name, hc) + else: + # Plugins registered this hook without knowing the spec. + hc.set_specification(module_or_class, spec_opts) + for hookfunction in hc.get_hookimpls(): + self._verify_hook(hc, hookfunction) + names.append(name) + + if not names: + raise ValueError( + f"did not find any {self.project_name!r} hooks in {module_or_class!r}" + ) + + def parse_hookspec_opts( + self, module_or_class: _Namespace, name: str + ) -> HookspecOpts | None: + """Try to obtain a hook specification from an item with the given name + in the given module or class which is being searched for hook specs. + + :returns: + The parsed hookspec options for defining a hook, or None to skip the + given item. + + This method can be overridden by ``PluginManager`` subclasses to + customize how hook specifications are picked up. By default, returns the + options for items decorated with :class:`HookspecMarker`. + """ + method = getattr(module_or_class, name) + opts: HookspecOpts | None = getattr(method, self.project_name + "_spec", None) + return opts + + def get_plugins(self) -> set[Any]: + """Return a set of all registered plugin objects.""" + return set(self._name2plugin.values()) + + def is_registered(self, plugin: _Plugin) -> bool: + """Return whether the plugin is already registered.""" + return any(plugin == val for val in self._name2plugin.values()) + + def get_canonical_name(self, plugin: _Plugin) -> str: + """Return a canonical name for a plugin object. + + Note that a plugin may be registered under a different name + specified by the caller of :meth:`register(plugin, name) <register>`. + To obtain the name of a registered plugin use :meth:`get_name(plugin) + <get_name>` instead. + """ + name: str | None = getattr(plugin, "__name__", None) + return name or str(id(plugin)) + + def get_plugin(self, name: str) -> Any | None: + """Return the plugin registered under the given name, if any.""" + return self._name2plugin.get(name) + + def has_plugin(self, name: str) -> bool: + """Return whether a plugin with the given name is registered.""" + return self.get_plugin(name) is not None + + def get_name(self, plugin: _Plugin) -> str | None: + """Return the name the plugin is registered under, or ``None`` if + is isn't.""" + for name, val in self._name2plugin.items(): + if plugin == val: + return name + return None + + def _verify_hook(self, hook: HookCaller, hookimpl: HookImpl) -> None: + if hook.is_historic() and (hookimpl.hookwrapper or hookimpl.wrapper): + raise PluginValidationError( + hookimpl.plugin, + "Plugin %r\nhook %r\nhistoric incompatible with yield/wrapper/hookwrapper" + % (hookimpl.plugin_name, hook.name), + ) + + assert hook.spec is not None + if hook.spec.warn_on_impl: + _warn_for_function(hook.spec.warn_on_impl, hookimpl.function) + + # positional arg checking + notinspec = set(hookimpl.argnames) - set(hook.spec.argnames) + if notinspec: + raise PluginValidationError( + hookimpl.plugin, + "Plugin %r for hook %r\nhookimpl definition: %s\n" + "Argument(s) %s are declared in the hookimpl but " + "can not be found in the hookspec" + % ( + hookimpl.plugin_name, + hook.name, + _formatdef(hookimpl.function), + notinspec, + ), + ) + + if ( + hookimpl.wrapper or hookimpl.hookwrapper + ) and not inspect.isgeneratorfunction(hookimpl.function): + raise PluginValidationError( + hookimpl.plugin, + "Plugin %r for hook %r\nhookimpl definition: %s\n" + "Declared as wrapper=True or hookwrapper=True " + "but function is not a generator function" + % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)), + ) + + if hookimpl.wrapper and hookimpl.hookwrapper: + raise PluginValidationError( + hookimpl.plugin, + "Plugin %r for hook %r\nhookimpl definition: %s\n" + "The wrapper=True and hookwrapper=True options are mutually exclusive" + % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)), + ) + + def check_pending(self) -> None: + """Verify that all hooks which have not been verified against a + hook specification are optional, otherwise raise + :exc:`PluginValidationError`.""" + for name in self.hook.__dict__: + if name[0] != "_": + hook: HookCaller = getattr(self.hook, name) + if not hook.has_spec(): + for hookimpl in hook.get_hookimpls(): + if not hookimpl.optionalhook: + raise PluginValidationError( + hookimpl.plugin, + "unknown hook %r in plugin %r" + % (name, hookimpl.plugin), + ) + + def load_setuptools_entrypoints(self, group: str, name: str | None = None) -> int: + """Load modules from querying the specified setuptools ``group``. + + :param group: + Entry point group to load plugins. + :param name: + If given, loads only plugins with the given ``name``. + + :return: + The number of plugins loaded by this call. + """ + count = 0 + for dist in list(importlib.metadata.distributions()): + for ep in dist.entry_points: + if ( + ep.group != group + or (name is not None and ep.name != name) + # already registered + or self.get_plugin(ep.name) + or self.is_blocked(ep.name) + ): + continue + plugin = ep.load() + self.register(plugin, name=ep.name) + self._plugin_distinfo.append((plugin, DistFacade(dist))) + count += 1 + return count + + def list_plugin_distinfo(self) -> list[tuple[_Plugin, DistFacade]]: + """Return a list of (plugin, distinfo) pairs for all + setuptools-registered plugins.""" + return list(self._plugin_distinfo) + + def list_name_plugin(self) -> list[tuple[str, _Plugin]]: + """Return a list of (name, plugin) pairs for all registered plugins.""" + return list(self._name2plugin.items()) + + def get_hookcallers(self, plugin: _Plugin) -> list[HookCaller] | None: + """Get all hook callers for the specified plugin. + + :returns: + The hook callers, or ``None`` if ``plugin`` is not registered in + this plugin manager. + """ + if self.get_name(plugin) is None: + return None + hookcallers = [] + for hookcaller in self.hook.__dict__.values(): + for hookimpl in hookcaller.get_hookimpls(): + if hookimpl.plugin is plugin: + hookcallers.append(hookcaller) + return hookcallers + + def add_hookcall_monitoring( + self, before: _BeforeTrace, after: _AfterTrace + ) -> Callable[[], None]: + """Add before/after tracing functions for all hooks. + + Returns an undo function which, when called, removes the added tracers. + + ``before(hook_name, hook_impls, kwargs)`` will be called ahead + of all hook calls and receive a hookcaller instance, a list + of HookImpl instances and the keyword arguments for the hook call. + + ``after(outcome, hook_name, hook_impls, kwargs)`` receives the + same arguments as ``before`` but also a :class:`~pluggy.Result` object + which represents the result of the overall hook call. + """ + oldcall = self._inner_hookexec + + def traced_hookexec( + hook_name: str, + hook_impls: Sequence[HookImpl], + caller_kwargs: Mapping[str, object], + firstresult: bool, + ) -> object | list[object]: + before(hook_name, hook_impls, caller_kwargs) + outcome = Result.from_call( + lambda: oldcall(hook_name, hook_impls, caller_kwargs, firstresult) + ) + after(outcome, hook_name, hook_impls, caller_kwargs) + return outcome.get_result() + + self._inner_hookexec = traced_hookexec + + def undo() -> None: + self._inner_hookexec = oldcall + + return undo + + def enable_tracing(self) -> Callable[[], None]: + """Enable tracing of hook calls. + + Returns an undo function which, when called, removes the added tracing. + """ + hooktrace = self.trace.root.get("hook") + + def before( + hook_name: str, methods: Sequence[HookImpl], kwargs: Mapping[str, object] + ) -> None: + hooktrace.root.indent += 1 + hooktrace(hook_name, kwargs) + + def after( + outcome: Result[object], + hook_name: str, + methods: Sequence[HookImpl], + kwargs: Mapping[str, object], + ) -> None: + if outcome.exception is None: + hooktrace("finish", hook_name, "-->", outcome.get_result()) + hooktrace.root.indent -= 1 + + return self.add_hookcall_monitoring(before, after) + + def subset_hook_caller( + self, name: str, remove_plugins: Iterable[_Plugin] + ) -> HookCaller: + """Return a proxy :class:`~pluggy.HookCaller` instance for the named + method which manages calls to all registered plugins except the ones + from remove_plugins.""" + orig: HookCaller = getattr(self.hook, name) + plugins_to_remove = {plug for plug in remove_plugins if hasattr(plug, name)} + if plugins_to_remove: + return _SubsetHookCaller(orig, plugins_to_remove) + return orig + + +def _formatdef(func: Callable[..., object]) -> str: + return f"{func.__name__}{inspect.signature(func)}" diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_result.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_result.py new file mode 100644 index 00000000..29859eb9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_result.py @@ -0,0 +1,118 @@ +""" +Hook wrapper "result" utilities. +""" +from __future__ import annotations + +from types import TracebackType +from typing import Callable +from typing import cast +from typing import final +from typing import Generator +from typing import Generic +from typing import NoReturn +from typing import Optional +from typing import Tuple +from typing import Type +from typing import TypeVar + + +_ExcInfo = Tuple[Type[BaseException], BaseException, Optional[TracebackType]] +ResultType = TypeVar("ResultType") + + +def _raise_wrapfail( + wrap_controller: ( + Generator[None, Result[ResultType], None] | Generator[None, object, object] + ), + msg: str, +) -> NoReturn: + co = wrap_controller.gi_code + raise RuntimeError( + "wrap_controller at %r %s:%d %s" + % (co.co_name, co.co_filename, co.co_firstlineno, msg) + ) + + +class HookCallError(Exception): + """Hook was called incorrectly.""" + + +@final +class Result(Generic[ResultType]): + """An object used to inspect and set the result in a :ref:`hook wrapper + <hookwrappers>`.""" + + __slots__ = ("_result", "_exception") + + def __init__( + self, + result: ResultType | None, + exception: BaseException | None, + ) -> None: + """:meta private:""" + self._result = result + self._exception = exception + + @property + def excinfo(self) -> _ExcInfo | None: + """:meta private:""" + exc = self._exception + if exc is None: + return None + else: + return (type(exc), exc, exc.__traceback__) + + @property + def exception(self) -> BaseException | None: + """:meta private:""" + return self._exception + + @classmethod + def from_call(cls, func: Callable[[], ResultType]) -> Result[ResultType]: + """:meta private:""" + __tracebackhide__ = True + result = exception = None + try: + result = func() + except BaseException as exc: + exception = exc + return cls(result, exception) + + def force_result(self, result: ResultType) -> None: + """Force the result(s) to ``result``. + + If the hook was marked as a ``firstresult`` a single value should + be set, otherwise set a (modified) list of results. Any exceptions + found during invocation will be deleted. + + This overrides any previous result or exception. + """ + self._result = result + self._exception = None + + def force_exception(self, exception: BaseException) -> None: + """Force the result to fail with ``exception``. + + This overrides any previous result or exception. + + .. versionadded:: 1.1.0 + """ + self._result = None + self._exception = exception + + def get_result(self) -> ResultType: + """Get the result(s) for this hook call. + + If the hook was marked as a ``firstresult`` only a single value + will be returned, otherwise a list of results. + """ + __tracebackhide__ = True + exc = self._exception + if exc is None: + return cast(ResultType, self._result) + else: + raise exc.with_traceback(exc.__traceback__) + + +# Historical name (pluggy<=1.2), kept for backward compatibility. +_Result = Result diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_tracing.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_tracing.py new file mode 100644 index 00000000..de1e13a7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_tracing.py @@ -0,0 +1,72 @@ +""" +Tracing utils +""" +from __future__ import annotations + +from typing import Any +from typing import Callable +from typing import Sequence +from typing import Tuple + + +_Writer = Callable[[str], object] +_Processor = Callable[[Tuple[str, ...], Tuple[Any, ...]], object] + + +class TagTracer: + def __init__(self) -> None: + self._tags2proc: dict[tuple[str, ...], _Processor] = {} + self._writer: _Writer | None = None + self.indent = 0 + + def get(self, name: str) -> TagTracerSub: + return TagTracerSub(self, (name,)) + + def _format_message(self, tags: Sequence[str], args: Sequence[object]) -> str: + if isinstance(args[-1], dict): + extra = args[-1] + args = args[:-1] + else: + extra = {} + + content = " ".join(map(str, args)) + indent = " " * self.indent + + lines = ["{}{} [{}]\n".format(indent, content, ":".join(tags))] + + for name, value in extra.items(): + lines.append(f"{indent} {name}: {value}\n") + + return "".join(lines) + + def _processmessage(self, tags: tuple[str, ...], args: tuple[object, ...]) -> None: + if self._writer is not None and args: + self._writer(self._format_message(tags, args)) + try: + processor = self._tags2proc[tags] + except KeyError: + pass + else: + processor(tags, args) + + def setwriter(self, writer: _Writer | None) -> None: + self._writer = writer + + def setprocessor(self, tags: str | tuple[str, ...], processor: _Processor) -> None: + if isinstance(tags, str): + tags = tuple(tags.split(":")) + else: + assert isinstance(tags, tuple) + self._tags2proc[tags] = processor + + +class TagTracerSub: + def __init__(self, root: TagTracer, tags: tuple[str, ...]) -> None: + self.root = root + self.tags = tags + + def __call__(self, *args: object) -> None: + self.root._processmessage(self.tags, args) + + def get(self, name: str) -> TagTracerSub: + return self.__class__(self.root, self.tags + (name,)) diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/_version.py b/dbdpy-env/lib/python3.9/site-packages/pluggy/_version.py new file mode 100644 index 00000000..4a742d24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pluggy/_version.py @@ -0,0 +1,4 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +__version__ = version = '1.3.0' +__version_tuple__ = version_tuple = (1, 3, 0) diff --git a/dbdpy-env/lib/python3.9/site-packages/pluggy/py.typed b/dbdpy-env/lib/python3.9/site-packages/pluggy/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/LICENSE new file mode 100644 index 00000000..31ecdfb1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/LICENSE @@ -0,0 +1,19 @@ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/METADATA new file mode 100644 index 00000000..a14febeb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/METADATA @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: py +Version: 1.11.0 +Summary: library with cross-python path, ini-parsing, io, code, log facilities +Home-page: https://py.readthedocs.io/ +Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others +Author-email: pytest-dev@python.org +License: MIT license +Platform: unix +Platform: linux +Platform: osx +Platform: cygwin +Platform: win32 +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Topic :: Software Development :: Testing +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* + +.. image:: https://img.shields.io/pypi/v/py.svg + :target: https://pypi.org/project/py + +.. image:: https://img.shields.io/conda/vn/conda-forge/py.svg + :target: https://anaconda.org/conda-forge/py + +.. image:: https://img.shields.io/pypi/pyversions/py.svg + :target: https://pypi.org/project/py + +.. image:: https://github.com/pytest-dev/py/workflows/build/badge.svg + :target: https://github.com/pytest-dev/py/actions + + +**NOTE**: this library is in **maintenance mode** and should not be used in new code. + +The py lib is a Python development support library featuring +the following tools and modules: + +* ``py.path``: uniform local and svn path objects -> please use pathlib/pathlib2 instead +* ``py.apipkg``: explicit API control and lazy-importing -> please use the standalone package instead +* ``py.iniconfig``: easy parsing of .ini files -> please use the standalone package instead +* ``py.code``: dynamic code generation and introspection (deprecated, moved to ``pytest`` as a implementation detail). + +**NOTE**: prior to the 1.4 release this distribution used to +contain py.test which is now its own package, see https://docs.pytest.org + +For questions and more information please visit https://py.readthedocs.io + +Bugs and issues: https://github.com/pytest-dev/py + +Authors: Holger Krekel and others, 2004-2017 + + diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/RECORD new file mode 100644 index 00000000..d4ad72d2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/RECORD @@ -0,0 +1,101 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/__metainfo.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_builtin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionnew.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionold.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/_py2traceback.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/assertion.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/code.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_code/source.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_error.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_io/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_io/capture.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_io/saferepr.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_io/terminalwriter.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_log/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_log/log.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_log/warning.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/cacheutil.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/common.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/local.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/svnurl.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_path/svnwc.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_process/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_process/cmdexec.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_process/forkedfunc.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_process/killproc.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_std.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/_xmlgen.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py/test.cpython-39.pyc,, +py-1.11.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +py-1.11.0.dist-info/LICENSE,sha256=KvaAw570k_uCgwNW0dPfGstaBgM8ui3sehniHKp3qGY,1061 +py-1.11.0.dist-info/METADATA,sha256=j1AvLZH7HqTO06dYJbYYGypPxkhP9IZjlTPSOY82ehM,2811 +py-1.11.0.dist-info/RECORD,, +py-1.11.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110 +py-1.11.0.dist-info/top_level.txt,sha256=rwh8_ukTaGscjyhGkBVcsGOMdc-Cfdz2QH7BKGENv-4,3 +py/__init__.py,sha256=56vBwkYKqNTj2StRTFjqa-p51_y6qVkvoyj10NyThtY,6022 +py/__init__.pyi,sha256=J0oNF3G0rcZL521oXyfWg7T053Spb2DmB5eDe40LcpY,341 +py/__metainfo.py,sha256=-APUcNtmuKgbYF8JfzlEyULMfp67uDDnRFKiu9nmxD0,55 +py/_builtin.py,sha256=c9wCmZ0nsZtFARJoZ5Ia7RxJuBo1Bp7IHjLC5uQvIug,4021 +py/_code/__init__.py,sha256=PsNXpJtPfle_IbAgLXQTO5YJyHi8N1xR8YtetmLs1Ac,46 +py/_code/_assertionnew.py,sha256=52ADFyZkW2aks5iFFKStINwz_2fFTomBBz40AplZ4vI,11450 +py/_code/_assertionold.py,sha256=HaDKP9esnh95ZUTZRH2gUcjGFHK4MAHi8Bk18rFBycA,17869 +py/_code/_py2traceback.py,sha256=QdRC-rUpHkhtfRq5EuBub-y6Tna_Z5BlXqBYtvf0-hE,2765 +py/_code/assertion.py,sha256=UgPH8qihF0qOIWGK-DR-usrJZztz-Njj-0cBuuqwjug,3174 +py/_code/code.py,sha256=5fTjcWOdqd8Xm37g82knNL2uK4ymp9yLpnmQrc9uWzI,27492 +py/_code/source.py,sha256=hZIzxUbKhgOElxeaiYlxEisxOevfg_OgxugXxpbMmGA,14050 +py/_error.py,sha256=59i7uYaoQlEB1QyRakvuIHh09fKGAOC521R4Rb1KVcI,2917 +py/_io/__init__.py,sha256=mroFkl-vhr0GhoOU33DR8CW5a23AmWEMkYd0Xkrn9gQ,29 +py/_io/capture.py,sha256=UD23HRIjE9sZs70RaPJj5Zk8XlKSqJpqMR8-AqlOv80,11652 +py/_io/saferepr.py,sha256=vPzOq5XoGYzdTf5-zn3_2ib6w4IdPP2URwenkDkMO8s,2483 +py/_io/terminalwriter.py,sha256=bKN8Gnd5gKZeXALbCLZkfzkjF-jGbXPyID_lxCGezX4,14714 +py/_log/__init__.py,sha256=2GE1ao7mud57-K6VXgmItZJsMDJBR500Xj7_-ou_jY4,74 +py/_log/log.py,sha256=arQ8lvZUIPlwDo6ffg6lNvAQ0x8U1yPRhkMLtHUQKx8,6003 +py/_log/warning.py,sha256=wufxpNU8YBXKNNcCZsZnaJaaNuKEjuvsIa1V-HE6YIk,2565 +py/_path/__init__.py,sha256=uBkaNhYAPiTOe8cj8WWD7rpM06XR6H0E3KghK6MgBpA,32 +py/_path/cacheutil.py,sha256=jQ0wk4Goqr_bIE8wGdr-CTiMD6dpcgdqyngGmMO48pY,3333 +py/_path/common.py,sha256=EC18Pl6zYGGMzHkDgGNbLC2W23ajtDwHMJOm3jNMdOA,14818 +py/_path/local.py,sha256=-QdTI95H2gtAPAfE4WhvRQq_2qMjlNBVRSp6_reg7kE,36759 +py/_path/svnurl.py,sha256=OC0w9p_pNpSncwgvD61Pcr4r2NrFztYb-OngD8RzNi8,14715 +py/_path/svnwc.py,sha256=IKJkzNwevB7zxxW9OIhH5n4wesAnJQcJTgxjxdgcqUk,43825 +py/_process/__init__.py,sha256=e7LQPDo7Q-LR9VjcRithvT4UoszeZ80NEeUvc9j4H-o,40 +py/_process/cmdexec.py,sha256=bTtnRydYMvW5w-K_qzRRRgycU8p4IfWQB5ymzLXMdkU,1814 +py/_process/forkedfunc.py,sha256=ZTGHp8kp5Z1icj0TonoPRmpcm64pyaVVfiRC9c5TnGU,3692 +py/_process/killproc.py,sha256=0fj_w_A8Mi_ZBJd9Koy_NnmMNoNYttb713943WxTVxw,648 +py/_std.py,sha256=JnzTePDF0TNzPKjYHIRMKwuwzE6bvLOV8q9r7FlLZZ8,668 +py/_vendored_packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +py/_vendored_packages/apipkg-2.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +py/_vendored_packages/apipkg-2.0.0.dist-info/LICENSE,sha256=6J7tEHTTqUMZi6E5uAhE9bRFuGC7p0qK6twGEFZhZOo,1054 +py/_vendored_packages/apipkg-2.0.0.dist-info/METADATA,sha256=GqNwkxraK5UTxObLVXTLc2UqktOPwZnKqdk2ThzHX0A,4292 +py/_vendored_packages/apipkg-2.0.0.dist-info/RECORD,sha256=VqARwZMQSTLsSY4QcLChtdNYtH1_llKRb1sGiK7wRm4,801 +py/_vendored_packages/apipkg-2.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +py/_vendored_packages/apipkg-2.0.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110 +py/_vendored_packages/apipkg-2.0.0.dist-info/top_level.txt,sha256=3TGS6nmN7kjxhUK4LpPCB3QkQI34QYGrT0ZQGWajoZ8,7 +py/_vendored_packages/apipkg/__init__.py,sha256=gpbD3O57S9f-LsO2e-XwI6IGISayicfnCq3B5y_8frg,6978 +py/_vendored_packages/apipkg/version.py,sha256=bgZFg-f3UKhgE-z2w8RoFrwqRBzJBZkM4_jKFiYB9eU,142 +py/_vendored_packages/iniconfig-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +py/_vendored_packages/iniconfig-1.1.1.dist-info/LICENSE,sha256=KvaAw570k_uCgwNW0dPfGstaBgM8ui3sehniHKp3qGY,1061 +py/_vendored_packages/iniconfig-1.1.1.dist-info/METADATA,sha256=_4-oFKpRXuZv5rzepScpXRwhq6DzqsgbnA5ZpgMUMcs,2405 +py/_vendored_packages/iniconfig-1.1.1.dist-info/RECORD,sha256=13Pl7e4y-9Te0285E_6IMvnDQzT4NawZCXhkodtXlk4,863 +py/_vendored_packages/iniconfig-1.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +py/_vendored_packages/iniconfig-1.1.1.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 +py/_vendored_packages/iniconfig-1.1.1.dist-info/top_level.txt,sha256=7KfM0fugdlToj9UW7enKXk2HYALQD8qHiyKtjhSzgN8,10 +py/_vendored_packages/iniconfig/__init__.py,sha256=-pBe5AF_6aAwo1CxJQ8i_zJq6ejc6IxHta7qk2tNJhY,5208 +py/_vendored_packages/iniconfig/__init__.pyi,sha256=-4KOctzq28ohRmTZsqlH6aylyFqsNKxYqtk1dteypi4,1205 +py/_vendored_packages/iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +py/_version.py,sha256=Xs0eR54RO9PHie_bsnHE9MaEmKMBiyxDAkf-poAVEX0,144 +py/_xmlgen.py,sha256=y-PCg1hZpIozJi7GXSRZv6saT_0nnNZ2D-6ue_A2xww,8364 +py/error.pyi,sha256=fQOaF1TOx_pK1StqWC_6d6DAGzSuPJ6vR6Fd_5lRol0,3409 +py/iniconfig.pyi,sha256=-4KOctzq28ohRmTZsqlH6aylyFqsNKxYqtk1dteypi4,1205 +py/io.pyi,sha256=nuC3RIVMXOp-xsaXBbPYNZHxzcCEHgDdIpS9yRmJR-g,5277 +py/path.pyi,sha256=OmDEqkp756dcWHq10Gwaw8pXtIABAdbg9mSAUCQPPyk,7168 +py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +py/test.py,sha256=1VLPdbBKEOai2WAKABJAbVdRfcJxtff2x2mXNmQgDL8,222 +py/xml.pyi,sha256=SBnALd6w7VwqrGYtEm4ESJ_u9iD7LVH7LWFZ3Y7xAoo,787 diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/WHEEL new file mode 100644 index 00000000..b733a60d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/top_level.txt new file mode 100644 index 00000000..edfce786 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py-1.11.0.dist-info/top_level.txt @@ -0,0 +1 @@ +py diff --git a/dbdpy-env/lib/python3.9/site-packages/py.py b/dbdpy-env/lib/python3.9/site-packages/py.py new file mode 100644 index 00000000..7813c9b9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py.py @@ -0,0 +1,10 @@ +# shim for pylib going away +# if pylib is installed this file will get skipped +# (`py/__init__.py` has higher precedence) +import sys + +import _pytest._py.error as error +import _pytest._py.path as path + +sys.modules["py.error"] = error +sys.modules["py.path"] = path diff --git a/dbdpy-env/lib/python3.9/site-packages/py/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/__init__.py new file mode 100644 index 00000000..b892ce1a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/__init__.py @@ -0,0 +1,156 @@ +""" +pylib: rapid testing and development utils + +this module uses apipkg.py for lazy-loading sub modules +and classes. The initpkg-dictionary below specifies +name->value mappings where value can be another namespace +dictionary or an import path. + +(c) Holger Krekel and others, 2004-2014 +""" +from py._error import error + +try: + from py._vendored_packages import apipkg + lib_not_mangled_by_packagers = True + vendor_prefix = '._vendored_packages.' +except ImportError: + import apipkg + lib_not_mangled_by_packagers = False + vendor_prefix = '' + +try: + from ._version import version as __version__ +except ImportError: + # broken installation, we don't even try + __version__ = "unknown" + + +apipkg.initpkg(__name__, attr={'_apipkg': apipkg, 'error': error}, exportdefs={ + # access to all standard lib modules + 'std': '._std:std', + + '_pydir' : '.__metainfo:pydir', + 'version': 'py:__version__', # backward compatibility + + # pytest-2.0 has a flat namespace, we use alias modules + # to keep old references compatible + 'test' : 'pytest', + + # hook into the top-level standard library + 'process' : { + '__doc__' : '._process:__doc__', + 'cmdexec' : '._process.cmdexec:cmdexec', + 'kill' : '._process.killproc:kill', + 'ForkedFunc' : '._process.forkedfunc:ForkedFunc', + }, + + 'apipkg' : { + 'initpkg' : vendor_prefix + 'apipkg:initpkg', + 'ApiModule' : vendor_prefix + 'apipkg:ApiModule', + }, + + 'iniconfig' : { + 'IniConfig' : vendor_prefix + 'iniconfig:IniConfig', + 'ParseError' : vendor_prefix + 'iniconfig:ParseError', + }, + + 'path' : { + '__doc__' : '._path:__doc__', + 'svnwc' : '._path.svnwc:SvnWCCommandPath', + 'svnurl' : '._path.svnurl:SvnCommandPath', + 'local' : '._path.local:LocalPath', + 'SvnAuth' : '._path.svnwc:SvnAuth', + }, + + # python inspection/code-generation API + 'code' : { + '__doc__' : '._code:__doc__', + 'compile' : '._code.source:compile_', + 'Source' : '._code.source:Source', + 'Code' : '._code.code:Code', + 'Frame' : '._code.code:Frame', + 'ExceptionInfo' : '._code.code:ExceptionInfo', + 'Traceback' : '._code.code:Traceback', + 'getfslineno' : '._code.source:getfslineno', + 'getrawcode' : '._code.code:getrawcode', + 'patch_builtins' : '._code.code:patch_builtins', + 'unpatch_builtins' : '._code.code:unpatch_builtins', + '_AssertionError' : '._code.assertion:AssertionError', + '_reinterpret_old' : '._code.assertion:reinterpret_old', + '_reinterpret' : '._code.assertion:reinterpret', + '_reprcompare' : '._code.assertion:_reprcompare', + '_format_explanation' : '._code.assertion:_format_explanation', + }, + + # backports and additions of builtins + 'builtin' : { + '__doc__' : '._builtin:__doc__', + 'enumerate' : '._builtin:enumerate', + 'reversed' : '._builtin:reversed', + 'sorted' : '._builtin:sorted', + 'any' : '._builtin:any', + 'all' : '._builtin:all', + 'set' : '._builtin:set', + 'frozenset' : '._builtin:frozenset', + 'BaseException' : '._builtin:BaseException', + 'GeneratorExit' : '._builtin:GeneratorExit', + '_sysex' : '._builtin:_sysex', + 'print_' : '._builtin:print_', + '_reraise' : '._builtin:_reraise', + '_tryimport' : '._builtin:_tryimport', + 'exec_' : '._builtin:exec_', + '_basestring' : '._builtin:_basestring', + '_totext' : '._builtin:_totext', + '_isbytes' : '._builtin:_isbytes', + '_istext' : '._builtin:_istext', + '_getimself' : '._builtin:_getimself', + '_getfuncdict' : '._builtin:_getfuncdict', + '_getcode' : '._builtin:_getcode', + 'builtins' : '._builtin:builtins', + 'execfile' : '._builtin:execfile', + 'callable' : '._builtin:callable', + 'bytes' : '._builtin:bytes', + 'text' : '._builtin:text', + }, + + # input-output helping + 'io' : { + '__doc__' : '._io:__doc__', + 'dupfile' : '._io.capture:dupfile', + 'TextIO' : '._io.capture:TextIO', + 'BytesIO' : '._io.capture:BytesIO', + 'FDCapture' : '._io.capture:FDCapture', + 'StdCapture' : '._io.capture:StdCapture', + 'StdCaptureFD' : '._io.capture:StdCaptureFD', + 'TerminalWriter' : '._io.terminalwriter:TerminalWriter', + 'ansi_print' : '._io.terminalwriter:ansi_print', + 'get_terminal_width' : '._io.terminalwriter:get_terminal_width', + 'saferepr' : '._io.saferepr:saferepr', + }, + + # small and mean xml/html generation + 'xml' : { + '__doc__' : '._xmlgen:__doc__', + 'html' : '._xmlgen:html', + 'Tag' : '._xmlgen:Tag', + 'raw' : '._xmlgen:raw', + 'Namespace' : '._xmlgen:Namespace', + 'escape' : '._xmlgen:escape', + }, + + 'log' : { + # logging API ('producers' and 'consumers' connected via keywords) + '__doc__' : '._log:__doc__', + '_apiwarn' : '._log.warning:_apiwarn', + 'Producer' : '._log.log:Producer', + 'setconsumer' : '._log.log:setconsumer', + '_setstate' : '._log.log:setstate', + '_getstate' : '._log.log:getstate', + 'Path' : '._log.log:Path', + 'STDOUT' : '._log.log:STDOUT', + 'STDERR' : '._log.log:STDERR', + 'Syslog' : '._log.log:Syslog', + }, + +}) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/__init__.pyi b/dbdpy-env/lib/python3.9/site-packages/py/__init__.pyi new file mode 100644 index 00000000..96859e31 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/__init__.pyi @@ -0,0 +1,20 @@ +from typing import Any + +# py allows to use e.g. py.path.local even without importing py.path. +# So import implicitly. +from . import error +from . import iniconfig +from . import path +from . import io +from . import xml + +__version__: str + +# Untyped modules below here. +std: Any +test: Any +process: Any +apipkg: Any +code: Any +builtin: Any +log: Any diff --git a/dbdpy-env/lib/python3.9/site-packages/py/__metainfo.py b/dbdpy-env/lib/python3.9/site-packages/py/__metainfo.py new file mode 100644 index 00000000..12581eb7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/__metainfo.py @@ -0,0 +1,2 @@ +import py +pydir = py.path.local(py.__file__).dirpath() diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_builtin.py b/dbdpy-env/lib/python3.9/site-packages/py/_builtin.py new file mode 100644 index 00000000..ddc89fc7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_builtin.py @@ -0,0 +1,149 @@ +import sys + + +# Passthrough for builtins supported with py27. +BaseException = BaseException +GeneratorExit = GeneratorExit +_sysex = (KeyboardInterrupt, SystemExit, MemoryError, GeneratorExit) +all = all +any = any +callable = callable +enumerate = enumerate +reversed = reversed +set, frozenset = set, frozenset +sorted = sorted + + +if sys.version_info >= (3, 0): + exec("print_ = print ; exec_=exec") + import builtins + + # some backward compatibility helpers + _basestring = str + def _totext(obj, encoding=None, errors=None): + if isinstance(obj, bytes): + if errors is None: + obj = obj.decode(encoding) + else: + obj = obj.decode(encoding, errors) + elif not isinstance(obj, str): + obj = str(obj) + return obj + + def _isbytes(x): + return isinstance(x, bytes) + + def _istext(x): + return isinstance(x, str) + + text = str + bytes = bytes + + def _getimself(function): + return getattr(function, '__self__', None) + + def _getfuncdict(function): + return getattr(function, "__dict__", None) + + def _getcode(function): + return getattr(function, "__code__", None) + + def execfile(fn, globs=None, locs=None): + if globs is None: + back = sys._getframe(1) + globs = back.f_globals + locs = back.f_locals + del back + elif locs is None: + locs = globs + fp = open(fn, "r") + try: + source = fp.read() + finally: + fp.close() + co = compile(source, fn, "exec", dont_inherit=True) + exec_(co, globs, locs) + +else: + import __builtin__ as builtins + _totext = unicode + _basestring = basestring + text = unicode + bytes = str + execfile = execfile + callable = callable + def _isbytes(x): + return isinstance(x, str) + def _istext(x): + return isinstance(x, unicode) + + def _getimself(function): + return getattr(function, 'im_self', None) + + def _getfuncdict(function): + return getattr(function, "__dict__", None) + + def _getcode(function): + try: + return getattr(function, "__code__") + except AttributeError: + return getattr(function, "func_code", None) + + def print_(*args, **kwargs): + """ minimal backport of py3k print statement. """ + sep = ' ' + if 'sep' in kwargs: + sep = kwargs.pop('sep') + end = '\n' + if 'end' in kwargs: + end = kwargs.pop('end') + file = 'file' in kwargs and kwargs.pop('file') or sys.stdout + if kwargs: + args = ", ".join([str(x) for x in kwargs]) + raise TypeError("invalid keyword arguments: %s" % args) + at_start = True + for x in args: + if not at_start: + file.write(sep) + file.write(str(x)) + at_start = False + file.write(end) + + def exec_(obj, globals=None, locals=None): + """ minimal backport of py3k exec statement. """ + __tracebackhide__ = True + if globals is None: + frame = sys._getframe(1) + globals = frame.f_globals + if locals is None: + locals = frame.f_locals + elif locals is None: + locals = globals + exec2(obj, globals, locals) + +if sys.version_info >= (3, 0): + def _reraise(cls, val, tb): + __tracebackhide__ = True + assert hasattr(val, '__traceback__') + raise cls.with_traceback(val, tb) +else: + exec (""" +def _reraise(cls, val, tb): + __tracebackhide__ = True + raise cls, val, tb +def exec2(obj, globals, locals): + __tracebackhide__ = True + exec obj in globals, locals +""") + +def _tryimport(*names): + """ return the first successfully imported module. """ + assert names + for name in names: + try: + __import__(name) + except ImportError: + excinfo = sys.exc_info() + else: + return sys.modules[name] + _reraise(*excinfo) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/__init__.py new file mode 100644 index 00000000..f15acf85 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/__init__.py @@ -0,0 +1 @@ +""" python inspection/code generation API """ diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionnew.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionnew.py new file mode 100644 index 00000000..d03f29d8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionnew.py @@ -0,0 +1,322 @@ +""" +Find intermediate evalutation results in assert statements through builtin AST. +This should replace _assertionold.py eventually. +""" + +import sys +import ast + +import py +from py._code.assertion import _format_explanation, BuiltinAssertionError + + +def _is_ast_expr(node): + return isinstance(node, ast.expr) +def _is_ast_stmt(node): + return isinstance(node, ast.stmt) + + +class Failure(Exception): + """Error found while interpreting AST.""" + + def __init__(self, explanation=""): + self.cause = sys.exc_info() + self.explanation = explanation + + +def interpret(source, frame, should_fail=False): + mod = ast.parse(source) + visitor = DebugInterpreter(frame) + try: + visitor.visit(mod) + except Failure: + failure = sys.exc_info()[1] + return getfailure(failure) + if should_fail: + return ("(assertion failed, but when it was re-run for " + "printing intermediate values, it did not fail. Suggestions: " + "compute assert expression before the assert or use --no-assert)") + +def run(offending_line, frame=None): + if frame is None: + frame = py.code.Frame(sys._getframe(1)) + return interpret(offending_line, frame) + +def getfailure(failure): + explanation = _format_explanation(failure.explanation) + value = failure.cause[1] + if str(value): + lines = explanation.splitlines() + if not lines: + lines.append("") + lines[0] += " << %s" % (value,) + explanation = "\n".join(lines) + text = "%s: %s" % (failure.cause[0].__name__, explanation) + if text.startswith("AssertionError: assert "): + text = text[16:] + return text + + +operator_map = { + ast.BitOr : "|", + ast.BitXor : "^", + ast.BitAnd : "&", + ast.LShift : "<<", + ast.RShift : ">>", + ast.Add : "+", + ast.Sub : "-", + ast.Mult : "*", + ast.Div : "/", + ast.FloorDiv : "//", + ast.Mod : "%", + ast.Eq : "==", + ast.NotEq : "!=", + ast.Lt : "<", + ast.LtE : "<=", + ast.Gt : ">", + ast.GtE : ">=", + ast.Pow : "**", + ast.Is : "is", + ast.IsNot : "is not", + ast.In : "in", + ast.NotIn : "not in" +} + +unary_map = { + ast.Not : "not %s", + ast.Invert : "~%s", + ast.USub : "-%s", + ast.UAdd : "+%s" +} + + +class DebugInterpreter(ast.NodeVisitor): + """Interpret AST nodes to gleam useful debugging information. """ + + def __init__(self, frame): + self.frame = frame + + def generic_visit(self, node): + # Fallback when we don't have a special implementation. + if _is_ast_expr(node): + mod = ast.Expression(node) + co = self._compile(mod) + try: + result = self.frame.eval(co) + except Exception: + raise Failure() + explanation = self.frame.repr(result) + return explanation, result + elif _is_ast_stmt(node): + mod = ast.Module([node]) + co = self._compile(mod, "exec") + try: + self.frame.exec_(co) + except Exception: + raise Failure() + return None, None + else: + raise AssertionError("can't handle %s" %(node,)) + + def _compile(self, source, mode="eval"): + return compile(source, "<assertion interpretation>", mode) + + def visit_Expr(self, expr): + return self.visit(expr.value) + + def visit_Module(self, mod): + for stmt in mod.body: + self.visit(stmt) + + def visit_Name(self, name): + explanation, result = self.generic_visit(name) + # See if the name is local. + source = "%r in locals() is not globals()" % (name.id,) + co = self._compile(source) + try: + local = self.frame.eval(co) + except Exception: + # have to assume it isn't + local = False + if not local: + return name.id, result + return explanation, result + + def visit_Compare(self, comp): + left = comp.left + left_explanation, left_result = self.visit(left) + for op, next_op in zip(comp.ops, comp.comparators): + next_explanation, next_result = self.visit(next_op) + op_symbol = operator_map[op.__class__] + explanation = "%s %s %s" % (left_explanation, op_symbol, + next_explanation) + source = "__exprinfo_left %s __exprinfo_right" % (op_symbol,) + co = self._compile(source) + try: + result = self.frame.eval(co, __exprinfo_left=left_result, + __exprinfo_right=next_result) + except Exception: + raise Failure(explanation) + try: + if not result: + break + except KeyboardInterrupt: + raise + except: + break + left_explanation, left_result = next_explanation, next_result + + rcomp = py.code._reprcompare + if rcomp: + res = rcomp(op_symbol, left_result, next_result) + if res: + explanation = res + return explanation, result + + def visit_BoolOp(self, boolop): + is_or = isinstance(boolop.op, ast.Or) + explanations = [] + for operand in boolop.values: + explanation, result = self.visit(operand) + explanations.append(explanation) + if result == is_or: + break + name = is_or and " or " or " and " + explanation = "(" + name.join(explanations) + ")" + return explanation, result + + def visit_UnaryOp(self, unary): + pattern = unary_map[unary.op.__class__] + operand_explanation, operand_result = self.visit(unary.operand) + explanation = pattern % (operand_explanation,) + co = self._compile(pattern % ("__exprinfo_expr",)) + try: + result = self.frame.eval(co, __exprinfo_expr=operand_result) + except Exception: + raise Failure(explanation) + return explanation, result + + def visit_BinOp(self, binop): + left_explanation, left_result = self.visit(binop.left) + right_explanation, right_result = self.visit(binop.right) + symbol = operator_map[binop.op.__class__] + explanation = "(%s %s %s)" % (left_explanation, symbol, + right_explanation) + source = "__exprinfo_left %s __exprinfo_right" % (symbol,) + co = self._compile(source) + try: + result = self.frame.eval(co, __exprinfo_left=left_result, + __exprinfo_right=right_result) + except Exception: + raise Failure(explanation) + return explanation, result + + def visit_Call(self, call): + func_explanation, func = self.visit(call.func) + arg_explanations = [] + ns = {"__exprinfo_func" : func} + arguments = [] + for arg in call.args: + arg_explanation, arg_result = self.visit(arg) + arg_name = "__exprinfo_%s" % (len(ns),) + ns[arg_name] = arg_result + arguments.append(arg_name) + arg_explanations.append(arg_explanation) + for keyword in call.keywords: + arg_explanation, arg_result = self.visit(keyword.value) + arg_name = "__exprinfo_%s" % (len(ns),) + ns[arg_name] = arg_result + keyword_source = "%s=%%s" % (keyword.arg) + arguments.append(keyword_source % (arg_name,)) + arg_explanations.append(keyword_source % (arg_explanation,)) + if call.starargs: + arg_explanation, arg_result = self.visit(call.starargs) + arg_name = "__exprinfo_star" + ns[arg_name] = arg_result + arguments.append("*%s" % (arg_name,)) + arg_explanations.append("*%s" % (arg_explanation,)) + if call.kwargs: + arg_explanation, arg_result = self.visit(call.kwargs) + arg_name = "__exprinfo_kwds" + ns[arg_name] = arg_result + arguments.append("**%s" % (arg_name,)) + arg_explanations.append("**%s" % (arg_explanation,)) + args_explained = ", ".join(arg_explanations) + explanation = "%s(%s)" % (func_explanation, args_explained) + args = ", ".join(arguments) + source = "__exprinfo_func(%s)" % (args,) + co = self._compile(source) + try: + result = self.frame.eval(co, **ns) + except Exception: + raise Failure(explanation) + pattern = "%s\n{%s = %s\n}" + rep = self.frame.repr(result) + explanation = pattern % (rep, rep, explanation) + return explanation, result + + def _is_builtin_name(self, name): + pattern = "%r not in globals() and %r not in locals()" + source = pattern % (name.id, name.id) + co = self._compile(source) + try: + return self.frame.eval(co) + except Exception: + return False + + def visit_Attribute(self, attr): + if not isinstance(attr.ctx, ast.Load): + return self.generic_visit(attr) + source_explanation, source_result = self.visit(attr.value) + explanation = "%s.%s" % (source_explanation, attr.attr) + source = "__exprinfo_expr.%s" % (attr.attr,) + co = self._compile(source) + try: + result = self.frame.eval(co, __exprinfo_expr=source_result) + except Exception: + raise Failure(explanation) + explanation = "%s\n{%s = %s.%s\n}" % (self.frame.repr(result), + self.frame.repr(result), + source_explanation, attr.attr) + # Check if the attr is from an instance. + source = "%r in getattr(__exprinfo_expr, '__dict__', {})" + source = source % (attr.attr,) + co = self._compile(source) + try: + from_instance = self.frame.eval(co, __exprinfo_expr=source_result) + except Exception: + from_instance = True + if from_instance: + rep = self.frame.repr(result) + pattern = "%s\n{%s = %s\n}" + explanation = pattern % (rep, rep, explanation) + return explanation, result + + def visit_Assert(self, assrt): + test_explanation, test_result = self.visit(assrt.test) + if test_explanation.startswith("False\n{False =") and \ + test_explanation.endswith("\n"): + test_explanation = test_explanation[15:-2] + explanation = "assert %s" % (test_explanation,) + if not test_result: + try: + raise BuiltinAssertionError + except Exception: + raise Failure(explanation) + return explanation, test_result + + def visit_Assign(self, assign): + value_explanation, value_result = self.visit(assign.value) + explanation = "... = %s" % (value_explanation,) + name = ast.Name("__exprinfo_expr", ast.Load(), + lineno=assign.value.lineno, + col_offset=assign.value.col_offset) + new_assign = ast.Assign(assign.targets, name, lineno=assign.lineno, + col_offset=assign.col_offset) + mod = ast.Module([new_assign]) + co = self._compile(mod, "exec") + try: + self.frame.exec_(co, __exprinfo_expr=value_result) + except Exception: + raise Failure(explanation) + return explanation, value_result diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionold.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionold.py new file mode 100644 index 00000000..1bb70a87 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/_assertionold.py @@ -0,0 +1,556 @@ +import py +import sys, inspect +from compiler import parse, ast, pycodegen +from py._code.assertion import BuiltinAssertionError, _format_explanation +import types + +passthroughex = py.builtin._sysex + +class Failure: + def __init__(self, node): + self.exc, self.value, self.tb = sys.exc_info() + self.node = node + +class View(object): + """View base class. + + If C is a subclass of View, then C(x) creates a proxy object around + the object x. The actual class of the proxy is not C in general, + but a *subclass* of C determined by the rules below. To avoid confusion + we call view class the class of the proxy (a subclass of C, so of View) + and object class the class of x. + + Attributes and methods not found in the proxy are automatically read on x. + Other operations like setting attributes are performed on the proxy, as + determined by its view class. The object x is available from the proxy + as its __obj__ attribute. + + The view class selection is determined by the __view__ tuples and the + optional __viewkey__ method. By default, the selected view class is the + most specific subclass of C whose __view__ mentions the class of x. + If no such subclass is found, the search proceeds with the parent + object classes. For example, C(True) will first look for a subclass + of C with __view__ = (..., bool, ...) and only if it doesn't find any + look for one with __view__ = (..., int, ...), and then ..., object,... + If everything fails the class C itself is considered to be the default. + + Alternatively, the view class selection can be driven by another aspect + of the object x, instead of the class of x, by overriding __viewkey__. + See last example at the end of this module. + """ + + _viewcache = {} + __view__ = () + + def __new__(rootclass, obj, *args, **kwds): + self = object.__new__(rootclass) + self.__obj__ = obj + self.__rootclass__ = rootclass + key = self.__viewkey__() + try: + self.__class__ = self._viewcache[key] + except KeyError: + self.__class__ = self._selectsubclass(key) + return self + + def __getattr__(self, attr): + # attributes not found in the normal hierarchy rooted on View + # are looked up in the object's real class + return getattr(self.__obj__, attr) + + def __viewkey__(self): + return self.__obj__.__class__ + + def __matchkey__(self, key, subclasses): + if inspect.isclass(key): + keys = inspect.getmro(key) + else: + keys = [key] + for key in keys: + result = [C for C in subclasses if key in C.__view__] + if result: + return result + return [] + + def _selectsubclass(self, key): + subclasses = list(enumsubclasses(self.__rootclass__)) + for C in subclasses: + if not isinstance(C.__view__, tuple): + C.__view__ = (C.__view__,) + choices = self.__matchkey__(key, subclasses) + if not choices: + return self.__rootclass__ + elif len(choices) == 1: + return choices[0] + else: + # combine the multiple choices + return type('?', tuple(choices), {}) + + def __repr__(self): + return '%s(%r)' % (self.__rootclass__.__name__, self.__obj__) + + +def enumsubclasses(cls): + for subcls in cls.__subclasses__(): + for subsubclass in enumsubclasses(subcls): + yield subsubclass + yield cls + + +class Interpretable(View): + """A parse tree node with a few extra methods.""" + explanation = None + + def is_builtin(self, frame): + return False + + def eval(self, frame): + # fall-back for unknown expression nodes + try: + expr = ast.Expression(self.__obj__) + expr.filename = '<eval>' + self.__obj__.filename = '<eval>' + co = pycodegen.ExpressionCodeGenerator(expr).getCode() + result = frame.eval(co) + except passthroughex: + raise + except: + raise Failure(self) + self.result = result + self.explanation = self.explanation or frame.repr(self.result) + + def run(self, frame): + # fall-back for unknown statement nodes + try: + expr = ast.Module(None, ast.Stmt([self.__obj__])) + expr.filename = '<run>' + co = pycodegen.ModuleCodeGenerator(expr).getCode() + frame.exec_(co) + except passthroughex: + raise + except: + raise Failure(self) + + def nice_explanation(self): + return _format_explanation(self.explanation) + + +class Name(Interpretable): + __view__ = ast.Name + + def is_local(self, frame): + source = '%r in locals() is not globals()' % self.name + try: + return frame.is_true(frame.eval(source)) + except passthroughex: + raise + except: + return False + + def is_global(self, frame): + source = '%r in globals()' % self.name + try: + return frame.is_true(frame.eval(source)) + except passthroughex: + raise + except: + return False + + def is_builtin(self, frame): + source = '%r not in locals() and %r not in globals()' % ( + self.name, self.name) + try: + return frame.is_true(frame.eval(source)) + except passthroughex: + raise + except: + return False + + def eval(self, frame): + super(Name, self).eval(frame) + if not self.is_local(frame): + self.explanation = self.name + +class Compare(Interpretable): + __view__ = ast.Compare + + def eval(self, frame): + expr = Interpretable(self.expr) + expr.eval(frame) + for operation, expr2 in self.ops: + if hasattr(self, 'result'): + # shortcutting in chained expressions + if not frame.is_true(self.result): + break + expr2 = Interpretable(expr2) + expr2.eval(frame) + self.explanation = "%s %s %s" % ( + expr.explanation, operation, expr2.explanation) + source = "__exprinfo_left %s __exprinfo_right" % operation + try: + self.result = frame.eval(source, + __exprinfo_left=expr.result, + __exprinfo_right=expr2.result) + except passthroughex: + raise + except: + raise Failure(self) + expr = expr2 + +class And(Interpretable): + __view__ = ast.And + + def eval(self, frame): + explanations = [] + for expr in self.nodes: + expr = Interpretable(expr) + expr.eval(frame) + explanations.append(expr.explanation) + self.result = expr.result + if not frame.is_true(expr.result): + break + self.explanation = '(' + ' and '.join(explanations) + ')' + +class Or(Interpretable): + __view__ = ast.Or + + def eval(self, frame): + explanations = [] + for expr in self.nodes: + expr = Interpretable(expr) + expr.eval(frame) + explanations.append(expr.explanation) + self.result = expr.result + if frame.is_true(expr.result): + break + self.explanation = '(' + ' or '.join(explanations) + ')' + + +# == Unary operations == +keepalive = [] +for astclass, astpattern in { + ast.Not : 'not __exprinfo_expr', + ast.Invert : '(~__exprinfo_expr)', + }.items(): + + class UnaryArith(Interpretable): + __view__ = astclass + + def eval(self, frame, astpattern=astpattern): + expr = Interpretable(self.expr) + expr.eval(frame) + self.explanation = astpattern.replace('__exprinfo_expr', + expr.explanation) + try: + self.result = frame.eval(astpattern, + __exprinfo_expr=expr.result) + except passthroughex: + raise + except: + raise Failure(self) + + keepalive.append(UnaryArith) + +# == Binary operations == +for astclass, astpattern in { + ast.Add : '(__exprinfo_left + __exprinfo_right)', + ast.Sub : '(__exprinfo_left - __exprinfo_right)', + ast.Mul : '(__exprinfo_left * __exprinfo_right)', + ast.Div : '(__exprinfo_left / __exprinfo_right)', + ast.Mod : '(__exprinfo_left % __exprinfo_right)', + ast.Power : '(__exprinfo_left ** __exprinfo_right)', + }.items(): + + class BinaryArith(Interpretable): + __view__ = astclass + + def eval(self, frame, astpattern=astpattern): + left = Interpretable(self.left) + left.eval(frame) + right = Interpretable(self.right) + right.eval(frame) + self.explanation = (astpattern + .replace('__exprinfo_left', left .explanation) + .replace('__exprinfo_right', right.explanation)) + try: + self.result = frame.eval(astpattern, + __exprinfo_left=left.result, + __exprinfo_right=right.result) + except passthroughex: + raise + except: + raise Failure(self) + + keepalive.append(BinaryArith) + + +class CallFunc(Interpretable): + __view__ = ast.CallFunc + + def is_bool(self, frame): + source = 'isinstance(__exprinfo_value, bool)' + try: + return frame.is_true(frame.eval(source, + __exprinfo_value=self.result)) + except passthroughex: + raise + except: + return False + + def eval(self, frame): + node = Interpretable(self.node) + node.eval(frame) + explanations = [] + vars = {'__exprinfo_fn': node.result} + source = '__exprinfo_fn(' + for a in self.args: + if isinstance(a, ast.Keyword): + keyword = a.name + a = a.expr + else: + keyword = None + a = Interpretable(a) + a.eval(frame) + argname = '__exprinfo_%d' % len(vars) + vars[argname] = a.result + if keyword is None: + source += argname + ',' + explanations.append(a.explanation) + else: + source += '%s=%s,' % (keyword, argname) + explanations.append('%s=%s' % (keyword, a.explanation)) + if self.star_args: + star_args = Interpretable(self.star_args) + star_args.eval(frame) + argname = '__exprinfo_star' + vars[argname] = star_args.result + source += '*' + argname + ',' + explanations.append('*' + star_args.explanation) + if self.dstar_args: + dstar_args = Interpretable(self.dstar_args) + dstar_args.eval(frame) + argname = '__exprinfo_kwds' + vars[argname] = dstar_args.result + source += '**' + argname + ',' + explanations.append('**' + dstar_args.explanation) + self.explanation = "%s(%s)" % ( + node.explanation, ', '.join(explanations)) + if source.endswith(','): + source = source[:-1] + source += ')' + try: + self.result = frame.eval(source, **vars) + except passthroughex: + raise + except: + raise Failure(self) + if not node.is_builtin(frame) or not self.is_bool(frame): + r = frame.repr(self.result) + self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation) + +class Getattr(Interpretable): + __view__ = ast.Getattr + + def eval(self, frame): + expr = Interpretable(self.expr) + expr.eval(frame) + source = '__exprinfo_expr.%s' % self.attrname + try: + self.result = frame.eval(source, __exprinfo_expr=expr.result) + except passthroughex: + raise + except: + raise Failure(self) + self.explanation = '%s.%s' % (expr.explanation, self.attrname) + # if the attribute comes from the instance, its value is interesting + source = ('hasattr(__exprinfo_expr, "__dict__") and ' + '%r in __exprinfo_expr.__dict__' % self.attrname) + try: + from_instance = frame.is_true( + frame.eval(source, __exprinfo_expr=expr.result)) + except passthroughex: + raise + except: + from_instance = True + if from_instance: + r = frame.repr(self.result) + self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation) + +# == Re-interpretation of full statements == + +class Assert(Interpretable): + __view__ = ast.Assert + + def run(self, frame): + test = Interpretable(self.test) + test.eval(frame) + # simplify 'assert False where False = ...' + if (test.explanation.startswith('False\n{False = ') and + test.explanation.endswith('\n}')): + test.explanation = test.explanation[15:-2] + # print the result as 'assert <explanation>' + self.result = test.result + self.explanation = 'assert ' + test.explanation + if not frame.is_true(test.result): + try: + raise BuiltinAssertionError + except passthroughex: + raise + except: + raise Failure(self) + +class Assign(Interpretable): + __view__ = ast.Assign + + def run(self, frame): + expr = Interpretable(self.expr) + expr.eval(frame) + self.result = expr.result + self.explanation = '... = ' + expr.explanation + # fall-back-run the rest of the assignment + ass = ast.Assign(self.nodes, ast.Name('__exprinfo_expr')) + mod = ast.Module(None, ast.Stmt([ass])) + mod.filename = '<run>' + co = pycodegen.ModuleCodeGenerator(mod).getCode() + try: + frame.exec_(co, __exprinfo_expr=expr.result) + except passthroughex: + raise + except: + raise Failure(self) + +class Discard(Interpretable): + __view__ = ast.Discard + + def run(self, frame): + expr = Interpretable(self.expr) + expr.eval(frame) + self.result = expr.result + self.explanation = expr.explanation + +class Stmt(Interpretable): + __view__ = ast.Stmt + + def run(self, frame): + for stmt in self.nodes: + stmt = Interpretable(stmt) + stmt.run(frame) + + +def report_failure(e): + explanation = e.node.nice_explanation() + if explanation: + explanation = ", in: " + explanation + else: + explanation = "" + sys.stdout.write("%s: %s%s\n" % (e.exc.__name__, e.value, explanation)) + +def check(s, frame=None): + if frame is None: + frame = sys._getframe(1) + frame = py.code.Frame(frame) + expr = parse(s, 'eval') + assert isinstance(expr, ast.Expression) + node = Interpretable(expr.node) + try: + node.eval(frame) + except passthroughex: + raise + except Failure: + e = sys.exc_info()[1] + report_failure(e) + else: + if not frame.is_true(node.result): + sys.stderr.write("assertion failed: %s\n" % node.nice_explanation()) + + +########################################################### +# API / Entry points +# ######################################################### + +def interpret(source, frame, should_fail=False): + module = Interpretable(parse(source, 'exec').node) + #print "got module", module + if isinstance(frame, types.FrameType): + frame = py.code.Frame(frame) + try: + module.run(frame) + except Failure: + e = sys.exc_info()[1] + return getfailure(e) + except passthroughex: + raise + except: + import traceback + traceback.print_exc() + if should_fail: + return ("(assertion failed, but when it was re-run for " + "printing intermediate values, it did not fail. Suggestions: " + "compute assert expression before the assert or use --nomagic)") + else: + return None + +def getmsg(excinfo): + if isinstance(excinfo, tuple): + excinfo = py.code.ExceptionInfo(excinfo) + #frame, line = gettbline(tb) + #frame = py.code.Frame(frame) + #return interpret(line, frame) + + tb = excinfo.traceback[-1] + source = str(tb.statement).strip() + x = interpret(source, tb.frame, should_fail=True) + if not isinstance(x, str): + raise TypeError("interpret returned non-string %r" % (x,)) + return x + +def getfailure(e): + explanation = e.node.nice_explanation() + if str(e.value): + lines = explanation.split('\n') + lines[0] += " << %s" % (e.value,) + explanation = '\n'.join(lines) + text = "%s: %s" % (e.exc.__name__, explanation) + if text.startswith('AssertionError: assert '): + text = text[16:] + return text + +def run(s, frame=None): + if frame is None: + frame = sys._getframe(1) + frame = py.code.Frame(frame) + module = Interpretable(parse(s, 'exec').node) + try: + module.run(frame) + except Failure: + e = sys.exc_info()[1] + report_failure(e) + + +if __name__ == '__main__': + # example: + def f(): + return 5 + def g(): + return 3 + def h(x): + return 'never' + check("f() * g() == 5") + check("not f()") + check("not (f() and g() or 0)") + check("f() == g()") + i = 4 + check("i == f()") + check("len(f()) == 0") + check("isinstance(2+3+4, float)") + + run("x = i") + check("x == 5") + + run("assert not f(), 'oops'") + run("a, b, c = 1, 2") + run("a, b, c = f()") + + check("max([f(),g()]) == 4") + check("'hello'[g()] == 'h'") + run("'guk%d' % h(f())") diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/_py2traceback.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/_py2traceback.py new file mode 100644 index 00000000..d65e27cb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/_py2traceback.py @@ -0,0 +1,79 @@ +# copied from python-2.7.3's traceback.py +# CHANGES: +# - some_str is replaced, trying to create unicode strings +# +import types + +def format_exception_only(etype, value): + """Format the exception part of a traceback. + + The arguments are the exception type and value such as given by + sys.last_type and sys.last_value. The return value is a list of + strings, each ending in a newline. + + Normally, the list contains a single string; however, for + SyntaxError exceptions, it contains several lines that (when + printed) display detailed information about where the syntax + error occurred. + + The message indicating which exception occurred is always the last + string in the list. + + """ + + # An instance should not have a meaningful value parameter, but + # sometimes does, particularly for string exceptions, such as + # >>> raise string1, string2 # deprecated + # + # Clear these out first because issubtype(string1, SyntaxError) + # would throw another exception and mask the original problem. + if (isinstance(etype, BaseException) or + isinstance(etype, types.InstanceType) or + etype is None or type(etype) is str): + return [_format_final_exc_line(etype, value)] + + stype = etype.__name__ + + if not issubclass(etype, SyntaxError): + return [_format_final_exc_line(stype, value)] + + # It was a syntax error; show exactly where the problem was found. + lines = [] + try: + msg, (filename, lineno, offset, badline) = value.args + except Exception: + pass + else: + filename = filename or "<string>" + lines.append(' File "%s", line %d\n' % (filename, lineno)) + if badline is not None: + lines.append(' %s\n' % badline.strip()) + if offset is not None: + caretspace = badline.rstrip('\n')[:offset].lstrip() + # non-space whitespace (likes tabs) must be kept for alignment + caretspace = ((c.isspace() and c or ' ') for c in caretspace) + # only three spaces to account for offset1 == pos 0 + lines.append(' %s^\n' % ''.join(caretspace)) + value = msg + + lines.append(_format_final_exc_line(stype, value)) + return lines + +def _format_final_exc_line(etype, value): + """Return a list of a single line -- normal case for format_exception_only""" + valuestr = _some_str(value) + if value is None or not valuestr: + line = "%s\n" % etype + else: + line = "%s: %s\n" % (etype, valuestr) + return line + +def _some_str(value): + try: + return unicode(value) + except Exception: + try: + return str(value) + except Exception: + pass + return '<unprintable %s object>' % type(value).__name__ diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/assertion.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/assertion.py new file mode 100644 index 00000000..ff164379 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/assertion.py @@ -0,0 +1,90 @@ +import sys +import py + +BuiltinAssertionError = py.builtin.builtins.AssertionError + +_reprcompare = None # if set, will be called by assert reinterp for comparison ops + +def _format_explanation(explanation): + """This formats an explanation + + Normally all embedded newlines are escaped, however there are + three exceptions: \n{, \n} and \n~. The first two are intended + cover nested explanations, see function and attribute explanations + for examples (.visit_Call(), visit_Attribute()). The last one is + for when one explanation needs to span multiple lines, e.g. when + displaying diffs. + """ + raw_lines = (explanation or '').split('\n') + # escape newlines not followed by {, } and ~ + lines = [raw_lines[0]] + for l in raw_lines[1:]: + if l.startswith('{') or l.startswith('}') or l.startswith('~'): + lines.append(l) + else: + lines[-1] += '\\n' + l + + result = lines[:1] + stack = [0] + stackcnt = [0] + for line in lines[1:]: + if line.startswith('{'): + if stackcnt[-1]: + s = 'and ' + else: + s = 'where ' + stack.append(len(result)) + stackcnt[-1] += 1 + stackcnt.append(0) + result.append(' +' + ' '*(len(stack)-1) + s + line[1:]) + elif line.startswith('}'): + assert line.startswith('}') + stack.pop() + stackcnt.pop() + result[stack[-1]] += line[1:] + else: + assert line.startswith('~') + result.append(' '*len(stack) + line[1:]) + assert len(stack) == 1 + return '\n'.join(result) + + +class AssertionError(BuiltinAssertionError): + def __init__(self, *args): + BuiltinAssertionError.__init__(self, *args) + if args: + try: + self.msg = str(args[0]) + except py.builtin._sysex: + raise + except: + self.msg = "<[broken __repr__] %s at %0xd>" %( + args[0].__class__, id(args[0])) + else: + f = py.code.Frame(sys._getframe(1)) + try: + source = f.code.fullsource + if source is not None: + try: + source = source.getstatement(f.lineno, assertion=True) + except IndexError: + source = None + else: + source = str(source.deindent()).strip() + except py.error.ENOENT: + source = None + # this can also occur during reinterpretation, when the + # co_filename is set to "<run>". + if source: + self.msg = reinterpret(source, f, should_fail=True) + else: + self.msg = "<could not determine information>" + if not self.args: + self.args = (self.msg,) + +if sys.version_info > (3, 0): + AssertionError.__module__ = "builtins" + reinterpret_old = "old reinterpretation not available for py3" +else: + from py._code._assertionold import interpret as reinterpret_old +from py._code._assertionnew import interpret as reinterpret diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/code.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/code.py new file mode 100644 index 00000000..dad79628 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/code.py @@ -0,0 +1,796 @@ +import py +import sys +from inspect import CO_VARARGS, CO_VARKEYWORDS, isclass + +builtin_repr = repr + +reprlib = py.builtin._tryimport('repr', 'reprlib') + +if sys.version_info[0] >= 3: + from traceback import format_exception_only +else: + from py._code._py2traceback import format_exception_only + +import traceback + + +class Code(object): + """ wrapper around Python code objects """ + def __init__(self, rawcode): + if not hasattr(rawcode, "co_filename"): + rawcode = py.code.getrawcode(rawcode) + try: + self.filename = rawcode.co_filename + self.firstlineno = rawcode.co_firstlineno - 1 + self.name = rawcode.co_name + except AttributeError: + raise TypeError("not a code object: %r" % (rawcode,)) + self.raw = rawcode + + def __eq__(self, other): + return self.raw == other.raw + + def __ne__(self, other): + return not self == other + + @property + def path(self): + """ return a path object pointing to source code (note that it + might not point to an actually existing file). """ + p = py.path.local(self.raw.co_filename) + # maybe don't try this checking + if not p.check(): + # XXX maybe try harder like the weird logic + # in the standard lib [linecache.updatecache] does? + p = self.raw.co_filename + return p + + @property + def fullsource(self): + """ return a py.code.Source object for the full source file of the code + """ + from py._code import source + full, _ = source.findsource(self.raw) + return full + + def source(self): + """ return a py.code.Source object for the code object's source only + """ + # return source only for that part of code + return py.code.Source(self.raw) + + def getargs(self, var=False): + """ return a tuple with the argument names for the code object + + if 'var' is set True also return the names of the variable and + keyword arguments when present + """ + # handfull shortcut for getting args + raw = self.raw + argcount = raw.co_argcount + if var: + argcount += raw.co_flags & CO_VARARGS + argcount += raw.co_flags & CO_VARKEYWORDS + return raw.co_varnames[:argcount] + +class Frame(object): + """Wrapper around a Python frame holding f_locals and f_globals + in which expressions can be evaluated.""" + + def __init__(self, frame): + self.lineno = frame.f_lineno - 1 + self.f_globals = frame.f_globals + self.f_locals = frame.f_locals + self.raw = frame + self.code = py.code.Code(frame.f_code) + + @property + def statement(self): + """ statement this frame is at """ + if self.code.fullsource is None: + return py.code.Source("") + return self.code.fullsource.getstatement(self.lineno) + + def eval(self, code, **vars): + """ evaluate 'code' in the frame + + 'vars' are optional additional local variables + + returns the result of the evaluation + """ + f_locals = self.f_locals.copy() + f_locals.update(vars) + return eval(code, self.f_globals, f_locals) + + def exec_(self, code, **vars): + """ exec 'code' in the frame + + 'vars' are optiona; additional local variables + """ + f_locals = self.f_locals.copy() + f_locals.update(vars) + py.builtin.exec_(code, self.f_globals, f_locals) + + def repr(self, object): + """ return a 'safe' (non-recursive, one-line) string repr for 'object' + """ + return py.io.saferepr(object) + + def is_true(self, object): + return object + + def getargs(self, var=False): + """ return a list of tuples (name, value) for all arguments + + if 'var' is set True also include the variable and keyword + arguments when present + """ + retval = [] + for arg in self.code.getargs(var): + try: + retval.append((arg, self.f_locals[arg])) + except KeyError: + pass # this can occur when using Psyco + return retval + + +class TracebackEntry(object): + """ a single entry in a traceback """ + + _repr_style = None + exprinfo = None + + def __init__(self, rawentry): + self._rawentry = rawentry + self.lineno = rawentry.tb_lineno - 1 + + def set_repr_style(self, mode): + assert mode in ("short", "long") + self._repr_style = mode + + @property + def frame(self): + return py.code.Frame(self._rawentry.tb_frame) + + @property + def relline(self): + return self.lineno - self.frame.code.firstlineno + + def __repr__(self): + return "<TracebackEntry %s:%d>" % (self.frame.code.path, self.lineno+1) + + @property + def statement(self): + """ py.code.Source object for the current statement """ + source = self.frame.code.fullsource + return source.getstatement(self.lineno) + + @property + def path(self): + """ path to the source code """ + return self.frame.code.path + + def getlocals(self): + return self.frame.f_locals + locals = property(getlocals, None, None, "locals of underlaying frame") + + def reinterpret(self): + """Reinterpret the failing statement and returns a detailed information + about what operations are performed.""" + if self.exprinfo is None: + source = str(self.statement).strip() + x = py.code._reinterpret(source, self.frame, should_fail=True) + if not isinstance(x, str): + raise TypeError("interpret returned non-string %r" % (x,)) + self.exprinfo = x + return self.exprinfo + + def getfirstlinesource(self): + # on Jython this firstlineno can be -1 apparently + return max(self.frame.code.firstlineno, 0) + + def getsource(self, astcache=None): + """ return failing source code. """ + # we use the passed in astcache to not reparse asttrees + # within exception info printing + from py._code.source import getstatementrange_ast + source = self.frame.code.fullsource + if source is None: + return None + key = astnode = None + if astcache is not None: + key = self.frame.code.path + if key is not None: + astnode = astcache.get(key, None) + start = self.getfirstlinesource() + try: + astnode, _, end = getstatementrange_ast(self.lineno, source, + astnode=astnode) + except SyntaxError: + end = self.lineno + 1 + else: + if key is not None: + astcache[key] = astnode + return source[start:end] + + source = property(getsource) + + def ishidden(self): + """ return True if the current frame has a var __tracebackhide__ + resolving to True + + mostly for internal use + """ + try: + return self.frame.f_locals['__tracebackhide__'] + except KeyError: + try: + return self.frame.f_globals['__tracebackhide__'] + except KeyError: + return False + + def __str__(self): + try: + fn = str(self.path) + except py.error.Error: + fn = '???' + name = self.frame.code.name + try: + line = str(self.statement).lstrip() + except KeyboardInterrupt: + raise + except: + line = "???" + return " File %r:%d in %s\n %s\n" % (fn, self.lineno+1, name, line) + + def name(self): + return self.frame.code.raw.co_name + name = property(name, None, None, "co_name of underlaying code") + + +class Traceback(list): + """ Traceback objects encapsulate and offer higher level + access to Traceback entries. + """ + Entry = TracebackEntry + + def __init__(self, tb): + """ initialize from given python traceback object. """ + if hasattr(tb, 'tb_next'): + def f(cur): + while cur is not None: + yield self.Entry(cur) + cur = cur.tb_next + list.__init__(self, f(tb)) + else: + list.__init__(self, tb) + + def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None): + """ return a Traceback instance wrapping part of this Traceback + + by provding any combination of path, lineno and firstlineno, the + first frame to start the to-be-returned traceback is determined + + this allows cutting the first part of a Traceback instance e.g. + for formatting reasons (removing some uninteresting bits that deal + with handling of the exception/traceback) + """ + for x in self: + code = x.frame.code + codepath = code.path + if ((path is None or codepath == path) and + (excludepath is None or not hasattr(codepath, 'relto') or + not codepath.relto(excludepath)) and + (lineno is None or x.lineno == lineno) and + (firstlineno is None or x.frame.code.firstlineno == firstlineno)): + return Traceback(x._rawentry) + return self + + def __getitem__(self, key): + val = super(Traceback, self).__getitem__(key) + if isinstance(key, type(slice(0))): + val = self.__class__(val) + return val + + def filter(self, fn=lambda x: not x.ishidden()): + """ return a Traceback instance with certain items removed + + fn is a function that gets a single argument, a TracebackItem + instance, and should return True when the item should be added + to the Traceback, False when not + + by default this removes all the TracebackItems which are hidden + (see ishidden() above) + """ + return Traceback(filter(fn, self)) + + def getcrashentry(self): + """ return last non-hidden traceback entry that lead + to the exception of a traceback. + """ + for i in range(-1, -len(self)-1, -1): + entry = self[i] + if not entry.ishidden(): + return entry + return self[-1] + + def recursionindex(self): + """ return the index of the frame/TracebackItem where recursion + originates if appropriate, None if no recursion occurred + """ + cache = {} + for i, entry in enumerate(self): + # id for the code.raw is needed to work around + # the strange metaprogramming in the decorator lib from pypi + # which generates code objects that have hash/value equality + #XXX needs a test + key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno + #print "checking for recursion at", key + l = cache.setdefault(key, []) + if l: + f = entry.frame + loc = f.f_locals + for otherloc in l: + if f.is_true(f.eval(co_equal, + __recursioncache_locals_1=loc, + __recursioncache_locals_2=otherloc)): + return i + l.append(entry.frame.f_locals) + return None + +co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2', + '?', 'eval') + +class ExceptionInfo(object): + """ wraps sys.exc_info() objects and offers + help for navigating the traceback. + """ + _striptext = '' + def __init__(self, tup=None, exprinfo=None): + if tup is None: + tup = sys.exc_info() + if exprinfo is None and isinstance(tup[1], AssertionError): + exprinfo = getattr(tup[1], 'msg', None) + if exprinfo is None: + exprinfo = str(tup[1]) + if exprinfo and exprinfo.startswith('assert '): + self._striptext = 'AssertionError: ' + self._excinfo = tup + #: the exception class + self.type = tup[0] + #: the exception instance + self.value = tup[1] + #: the exception raw traceback + self.tb = tup[2] + #: the exception type name + self.typename = self.type.__name__ + #: the exception traceback (py.code.Traceback instance) + self.traceback = py.code.Traceback(self.tb) + + def __repr__(self): + return "<ExceptionInfo %s tblen=%d>" % ( + self.typename, len(self.traceback)) + + def exconly(self, tryshort=False): + """ return the exception as a string + + when 'tryshort' resolves to True, and the exception is a + py.code._AssertionError, only the actual exception part of + the exception representation is returned (so 'AssertionError: ' is + removed from the beginning) + """ + lines = format_exception_only(self.type, self.value) + text = ''.join(lines) + text = text.rstrip() + if tryshort: + if text.startswith(self._striptext): + text = text[len(self._striptext):] + return text + + def errisinstance(self, exc): + """ return True if the exception is an instance of exc """ + return isinstance(self.value, exc) + + def _getreprcrash(self): + exconly = self.exconly(tryshort=True) + entry = self.traceback.getcrashentry() + path, lineno = entry.frame.code.raw.co_filename, entry.lineno + return ReprFileLocation(path, lineno+1, exconly) + + def getrepr(self, showlocals=False, style="long", + abspath=False, tbfilter=True, funcargs=False): + """ return str()able representation of this exception info. + showlocals: show locals per traceback entry + style: long|short|no|native traceback style + tbfilter: hide entries (where __tracebackhide__ is true) + + in case of style==native, tbfilter and showlocals is ignored. + """ + if style == 'native': + return ReprExceptionInfo(ReprTracebackNative( + traceback.format_exception( + self.type, + self.value, + self.traceback[0]._rawentry, + )), self._getreprcrash()) + + fmt = FormattedExcinfo( + showlocals=showlocals, style=style, + abspath=abspath, tbfilter=tbfilter, funcargs=funcargs) + return fmt.repr_excinfo(self) + + def __str__(self): + entry = self.traceback[-1] + loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) + return str(loc) + + def __unicode__(self): + entry = self.traceback[-1] + loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) + return loc.__unicode__() + + +class FormattedExcinfo(object): + """ presenting information about failing Functions and Generators. """ + # for traceback entries + flow_marker = ">" + fail_marker = "E" + + def __init__(self, showlocals=False, style="long", + abspath=True, tbfilter=True, funcargs=False): + self.showlocals = showlocals + self.style = style + self.tbfilter = tbfilter + self.funcargs = funcargs + self.abspath = abspath + self.astcache = {} + + def _getindent(self, source): + # figure out indent for given source + try: + s = str(source.getstatement(len(source)-1)) + except KeyboardInterrupt: + raise + except: + try: + s = str(source[-1]) + except KeyboardInterrupt: + raise + except: + return 0 + return 4 + (len(s) - len(s.lstrip())) + + def _getentrysource(self, entry): + source = entry.getsource(self.astcache) + if source is not None: + source = source.deindent() + return source + + def _saferepr(self, obj): + return py.io.saferepr(obj) + + def repr_args(self, entry): + if self.funcargs: + args = [] + for argname, argvalue in entry.frame.getargs(var=True): + args.append((argname, self._saferepr(argvalue))) + return ReprFuncArgs(args) + + def get_source(self, source, line_index=-1, excinfo=None, short=False): + """ return formatted and marked up source lines. """ + lines = [] + if source is None or line_index >= len(source.lines): + source = py.code.Source("???") + line_index = 0 + if line_index < 0: + line_index += len(source) + space_prefix = " " + if short: + lines.append(space_prefix + source.lines[line_index].strip()) + else: + for line in source.lines[:line_index]: + lines.append(space_prefix + line) + lines.append(self.flow_marker + " " + source.lines[line_index]) + for line in source.lines[line_index+1:]: + lines.append(space_prefix + line) + if excinfo is not None: + indent = 4 if short else self._getindent(source) + lines.extend(self.get_exconly(excinfo, indent=indent, markall=True)) + return lines + + def get_exconly(self, excinfo, indent=4, markall=False): + lines = [] + indent = " " * indent + # get the real exception information out + exlines = excinfo.exconly(tryshort=True).split('\n') + failindent = self.fail_marker + indent[1:] + for line in exlines: + lines.append(failindent + line) + if not markall: + failindent = indent + return lines + + def repr_locals(self, locals): + if self.showlocals: + lines = [] + keys = [loc for loc in locals if loc[0] != "@"] + keys.sort() + for name in keys: + value = locals[name] + if name == '__builtins__': + lines.append("__builtins__ = <builtins>") + else: + # This formatting could all be handled by the + # _repr() function, which is only reprlib.Repr in + # disguise, so is very configurable. + str_repr = self._saferepr(value) + #if len(str_repr) < 70 or not isinstance(value, + # (list, tuple, dict)): + lines.append("%-10s = %s" %(name, str_repr)) + #else: + # self._line("%-10s =\\" % (name,)) + # # XXX + # pprint.pprint(value, stream=self.excinfowriter) + return ReprLocals(lines) + + def repr_traceback_entry(self, entry, excinfo=None): + source = self._getentrysource(entry) + if source is None: + source = py.code.Source("???") + line_index = 0 + else: + # entry.getfirstlinesource() can be -1, should be 0 on jython + line_index = entry.lineno - max(entry.getfirstlinesource(), 0) + + lines = [] + style = entry._repr_style + if style is None: + style = self.style + if style in ("short", "long"): + short = style == "short" + reprargs = self.repr_args(entry) if not short else None + s = self.get_source(source, line_index, excinfo, short=short) + lines.extend(s) + if short: + message = "in %s" %(entry.name) + else: + message = excinfo and excinfo.typename or "" + path = self._makepath(entry.path) + filelocrepr = ReprFileLocation(path, entry.lineno+1, message) + localsrepr = None + if not short: + localsrepr = self.repr_locals(entry.locals) + return ReprEntry(lines, reprargs, localsrepr, filelocrepr, style) + if excinfo: + lines.extend(self.get_exconly(excinfo, indent=4)) + return ReprEntry(lines, None, None, None, style) + + def _makepath(self, path): + if not self.abspath: + try: + np = py.path.local().bestrelpath(path) + except OSError: + return path + if len(np) < len(str(path)): + path = np + return path + + def repr_traceback(self, excinfo): + traceback = excinfo.traceback + if self.tbfilter: + traceback = traceback.filter() + recursionindex = None + if excinfo.errisinstance(RuntimeError): + if "maximum recursion depth exceeded" in str(excinfo.value): + recursionindex = traceback.recursionindex() + last = traceback[-1] + entries = [] + extraline = None + for index, entry in enumerate(traceback): + einfo = (last == entry) and excinfo or None + reprentry = self.repr_traceback_entry(entry, einfo) + entries.append(reprentry) + if index == recursionindex: + extraline = "!!! Recursion detected (same locals & position)" + break + return ReprTraceback(entries, extraline, style=self.style) + + def repr_excinfo(self, excinfo): + reprtraceback = self.repr_traceback(excinfo) + reprcrash = excinfo._getreprcrash() + return ReprExceptionInfo(reprtraceback, reprcrash) + +class TerminalRepr: + def __str__(self): + s = self.__unicode__() + if sys.version_info[0] < 3: + s = s.encode('utf-8') + return s + + def __unicode__(self): + # FYI this is called from pytest-xdist's serialization of exception + # information. + io = py.io.TextIO() + tw = py.io.TerminalWriter(file=io) + self.toterminal(tw) + return io.getvalue().strip() + + def __repr__(self): + return "<%s instance at %0x>" %(self.__class__, id(self)) + + +class ReprExceptionInfo(TerminalRepr): + def __init__(self, reprtraceback, reprcrash): + self.reprtraceback = reprtraceback + self.reprcrash = reprcrash + self.sections = [] + + def addsection(self, name, content, sep="-"): + self.sections.append((name, content, sep)) + + def toterminal(self, tw): + self.reprtraceback.toterminal(tw) + for name, content, sep in self.sections: + tw.sep(sep, name) + tw.line(content) + +class ReprTraceback(TerminalRepr): + entrysep = "_ " + + def __init__(self, reprentries, extraline, style): + self.reprentries = reprentries + self.extraline = extraline + self.style = style + + def toterminal(self, tw): + # the entries might have different styles + last_style = None + for i, entry in enumerate(self.reprentries): + if entry.style == "long": + tw.line("") + entry.toterminal(tw) + if i < len(self.reprentries) - 1: + next_entry = self.reprentries[i+1] + if entry.style == "long" or \ + entry.style == "short" and next_entry.style == "long": + tw.sep(self.entrysep) + + if self.extraline: + tw.line(self.extraline) + +class ReprTracebackNative(ReprTraceback): + def __init__(self, tblines): + self.style = "native" + self.reprentries = [ReprEntryNative(tblines)] + self.extraline = None + +class ReprEntryNative(TerminalRepr): + style = "native" + + def __init__(self, tblines): + self.lines = tblines + + def toterminal(self, tw): + tw.write("".join(self.lines)) + +class ReprEntry(TerminalRepr): + localssep = "_ " + + def __init__(self, lines, reprfuncargs, reprlocals, filelocrepr, style): + self.lines = lines + self.reprfuncargs = reprfuncargs + self.reprlocals = reprlocals + self.reprfileloc = filelocrepr + self.style = style + + def toterminal(self, tw): + if self.style == "short": + self.reprfileloc.toterminal(tw) + for line in self.lines: + red = line.startswith("E ") + tw.line(line, bold=True, red=red) + #tw.line("") + return + if self.reprfuncargs: + self.reprfuncargs.toterminal(tw) + for line in self.lines: + red = line.startswith("E ") + tw.line(line, bold=True, red=red) + if self.reprlocals: + #tw.sep(self.localssep, "Locals") + tw.line("") + self.reprlocals.toterminal(tw) + if self.reprfileloc: + if self.lines: + tw.line("") + self.reprfileloc.toterminal(tw) + + def __str__(self): + return "%s\n%s\n%s" % ("\n".join(self.lines), + self.reprlocals, + self.reprfileloc) + +class ReprFileLocation(TerminalRepr): + def __init__(self, path, lineno, message): + self.path = str(path) + self.lineno = lineno + self.message = message + + def toterminal(self, tw): + # filename and lineno output for each entry, + # using an output format that most editors unterstand + msg = self.message + i = msg.find("\n") + if i != -1: + msg = msg[:i] + tw.line("%s:%s: %s" %(self.path, self.lineno, msg)) + +class ReprLocals(TerminalRepr): + def __init__(self, lines): + self.lines = lines + + def toterminal(self, tw): + for line in self.lines: + tw.line(line) + +class ReprFuncArgs(TerminalRepr): + def __init__(self, args): + self.args = args + + def toterminal(self, tw): + if self.args: + linesofar = "" + for name, value in self.args: + ns = "%s = %s" %(name, value) + if len(ns) + len(linesofar) + 2 > tw.fullwidth: + if linesofar: + tw.line(linesofar) + linesofar = ns + else: + if linesofar: + linesofar += ", " + ns + else: + linesofar = ns + if linesofar: + tw.line(linesofar) + tw.line("") + + + +oldbuiltins = {} + +def patch_builtins(assertion=True, compile=True): + """ put compile and AssertionError builtins to Python's builtins. """ + if assertion: + from py._code import assertion + l = oldbuiltins.setdefault('AssertionError', []) + l.append(py.builtin.builtins.AssertionError) + py.builtin.builtins.AssertionError = assertion.AssertionError + if compile: + l = oldbuiltins.setdefault('compile', []) + l.append(py.builtin.builtins.compile) + py.builtin.builtins.compile = py.code.compile + +def unpatch_builtins(assertion=True, compile=True): + """ remove compile and AssertionError builtins from Python builtins. """ + if assertion: + py.builtin.builtins.AssertionError = oldbuiltins['AssertionError'].pop() + if compile: + py.builtin.builtins.compile = oldbuiltins['compile'].pop() + +def getrawcode(obj, trycall=True): + """ return code object for given function. """ + try: + return obj.__code__ + except AttributeError: + obj = getattr(obj, 'im_func', obj) + obj = getattr(obj, 'func_code', obj) + obj = getattr(obj, 'f_code', obj) + obj = getattr(obj, '__code__', obj) + if trycall and not hasattr(obj, 'co_firstlineno'): + if hasattr(obj, '__call__') and not isclass(obj): + x = getrawcode(obj.__call__, trycall=False) + if hasattr(x, 'co_firstlineno'): + return x + return obj + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_code/source.py b/dbdpy-env/lib/python3.9/site-packages/py/_code/source.py new file mode 100644 index 00000000..7fc7b23a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_code/source.py @@ -0,0 +1,410 @@ +from __future__ import generators + +from bisect import bisect_right +import sys +import inspect, tokenize +import py +from types import ModuleType +cpy_compile = compile + +try: + import _ast + from _ast import PyCF_ONLY_AST as _AST_FLAG +except ImportError: + _AST_FLAG = 0 + _ast = None + + +class Source(object): + """ a immutable object holding a source code fragment, + possibly deindenting it. + """ + _compilecounter = 0 + def __init__(self, *parts, **kwargs): + self.lines = lines = [] + de = kwargs.get('deindent', True) + rstrip = kwargs.get('rstrip', True) + for part in parts: + if not part: + partlines = [] + if isinstance(part, Source): + partlines = part.lines + elif isinstance(part, (tuple, list)): + partlines = [x.rstrip("\n") for x in part] + elif isinstance(part, py.builtin._basestring): + partlines = part.split('\n') + if rstrip: + while partlines: + if partlines[-1].strip(): + break + partlines.pop() + else: + partlines = getsource(part, deindent=de).lines + if de: + partlines = deindent(partlines) + lines.extend(partlines) + + def __eq__(self, other): + try: + return self.lines == other.lines + except AttributeError: + if isinstance(other, str): + return str(self) == other + return False + + def __getitem__(self, key): + if isinstance(key, int): + return self.lines[key] + else: + if key.step not in (None, 1): + raise IndexError("cannot slice a Source with a step") + return self.__getslice__(key.start, key.stop) + + def __len__(self): + return len(self.lines) + + def __getslice__(self, start, end): + newsource = Source() + newsource.lines = self.lines[start:end] + return newsource + + def strip(self): + """ return new source object with trailing + and leading blank lines removed. + """ + start, end = 0, len(self) + while start < end and not self.lines[start].strip(): + start += 1 + while end > start and not self.lines[end-1].strip(): + end -= 1 + source = Source() + source.lines[:] = self.lines[start:end] + return source + + def putaround(self, before='', after='', indent=' ' * 4): + """ return a copy of the source object with + 'before' and 'after' wrapped around it. + """ + before = Source(before) + after = Source(after) + newsource = Source() + lines = [ (indent + line) for line in self.lines] + newsource.lines = before.lines + lines + after.lines + return newsource + + def indent(self, indent=' ' * 4): + """ return a copy of the source object with + all lines indented by the given indent-string. + """ + newsource = Source() + newsource.lines = [(indent+line) for line in self.lines] + return newsource + + def getstatement(self, lineno, assertion=False): + """ return Source statement which contains the + given linenumber (counted from 0). + """ + start, end = self.getstatementrange(lineno, assertion) + return self[start:end] + + def getstatementrange(self, lineno, assertion=False): + """ return (start, end) tuple which spans the minimal + statement region which containing the given lineno. + """ + if not (0 <= lineno < len(self)): + raise IndexError("lineno out of range") + ast, start, end = getstatementrange_ast(lineno, self) + return start, end + + def deindent(self, offset=None): + """ return a new source object deindented by offset. + If offset is None then guess an indentation offset from + the first non-blank line. Subsequent lines which have a + lower indentation offset will be copied verbatim as + they are assumed to be part of multilines. + """ + # XXX maybe use the tokenizer to properly handle multiline + # strings etc.pp? + newsource = Source() + newsource.lines[:] = deindent(self.lines, offset) + return newsource + + def isparseable(self, deindent=True): + """ return True if source is parseable, heuristically + deindenting it by default. + """ + try: + import parser + except ImportError: + syntax_checker = lambda x: compile(x, 'asd', 'exec') + else: + syntax_checker = parser.suite + + if deindent: + source = str(self.deindent()) + else: + source = str(self) + try: + #compile(source+'\n', "x", "exec") + syntax_checker(source+'\n') + except KeyboardInterrupt: + raise + except Exception: + return False + else: + return True + + def __str__(self): + return "\n".join(self.lines) + + def compile(self, filename=None, mode='exec', + flag=generators.compiler_flag, + dont_inherit=0, _genframe=None): + """ return compiled code object. if filename is None + invent an artificial filename which displays + the source/line position of the caller frame. + """ + if not filename or py.path.local(filename).check(file=0): + if _genframe is None: + _genframe = sys._getframe(1) # the caller + fn,lineno = _genframe.f_code.co_filename, _genframe.f_lineno + base = "<%d-codegen " % self._compilecounter + self.__class__._compilecounter += 1 + if not filename: + filename = base + '%s:%d>' % (fn, lineno) + else: + filename = base + '%r %s:%d>' % (filename, fn, lineno) + source = "\n".join(self.lines) + '\n' + try: + co = cpy_compile(source, filename, mode, flag) + except SyntaxError: + ex = sys.exc_info()[1] + # re-represent syntax errors from parsing python strings + msglines = self.lines[:ex.lineno] + if ex.offset: + msglines.append(" "*ex.offset + '^') + msglines.append("(code was compiled probably from here: %s)" % filename) + newex = SyntaxError('\n'.join(msglines)) + newex.offset = ex.offset + newex.lineno = ex.lineno + newex.text = ex.text + raise newex + else: + if flag & _AST_FLAG: + return co + lines = [(x + "\n") for x in self.lines] + import linecache + linecache.cache[filename] = (1, None, lines, filename) + return co + +# +# public API shortcut functions +# + +def compile_(source, filename=None, mode='exec', flags= + generators.compiler_flag, dont_inherit=0): + """ compile the given source to a raw code object, + and maintain an internal cache which allows later + retrieval of the source code for the code object + and any recursively created code objects. + """ + if _ast is not None and isinstance(source, _ast.AST): + # XXX should Source support having AST? + return cpy_compile(source, filename, mode, flags, dont_inherit) + _genframe = sys._getframe(1) # the caller + s = Source(source) + co = s.compile(filename, mode, flags, _genframe=_genframe) + return co + + +def getfslineno(obj): + """ Return source location (path, lineno) for the given object. + If the source cannot be determined return ("", -1) + """ + try: + code = py.code.Code(obj) + except TypeError: + try: + fn = (inspect.getsourcefile(obj) or + inspect.getfile(obj)) + except TypeError: + return "", -1 + + fspath = fn and py.path.local(fn) or None + lineno = -1 + if fspath: + try: + _, lineno = findsource(obj) + except IOError: + pass + else: + fspath = code.path + lineno = code.firstlineno + assert isinstance(lineno, int) + return fspath, lineno + +# +# helper functions +# + +def findsource(obj): + try: + sourcelines, lineno = inspect.findsource(obj) + except py.builtin._sysex: + raise + except: + return None, -1 + source = Source() + source.lines = [line.rstrip() for line in sourcelines] + return source, lineno + +def getsource(obj, **kwargs): + obj = py.code.getrawcode(obj) + try: + strsrc = inspect.getsource(obj) + except IndentationError: + strsrc = "\"Buggy python version consider upgrading, cannot get source\"" + assert isinstance(strsrc, str) + return Source(strsrc, **kwargs) + +def deindent(lines, offset=None): + if offset is None: + for line in lines: + line = line.expandtabs() + s = line.lstrip() + if s: + offset = len(line)-len(s) + break + else: + offset = 0 + if offset == 0: + return list(lines) + newlines = [] + def readline_generator(lines): + for line in lines: + yield line + '\n' + while True: + yield '' + + it = readline_generator(lines) + + try: + for _, _, (sline, _), (eline, _), _ in tokenize.generate_tokens(lambda: next(it)): + if sline > len(lines): + break # End of input reached + if sline > len(newlines): + line = lines[sline - 1].expandtabs() + if line.lstrip() and line[:offset].isspace(): + line = line[offset:] # Deindent + newlines.append(line) + + for i in range(sline, eline): + # Don't deindent continuing lines of + # multiline tokens (i.e. multiline strings) + newlines.append(lines[i]) + except (IndentationError, tokenize.TokenError): + pass + # Add any lines we didn't see. E.g. if an exception was raised. + newlines.extend(lines[len(newlines):]) + return newlines + + +def get_statement_startend2(lineno, node): + import ast + # flatten all statements and except handlers into one lineno-list + # AST's line numbers start indexing at 1 + l = [] + for x in ast.walk(node): + if isinstance(x, _ast.stmt) or isinstance(x, _ast.ExceptHandler): + l.append(x.lineno - 1) + for name in "finalbody", "orelse": + val = getattr(x, name, None) + if val: + # treat the finally/orelse part as its own statement + l.append(val[0].lineno - 1 - 1) + l.sort() + insert_index = bisect_right(l, lineno) + start = l[insert_index - 1] + if insert_index >= len(l): + end = None + else: + end = l[insert_index] + return start, end + + +def getstatementrange_ast(lineno, source, assertion=False, astnode=None): + if astnode is None: + content = str(source) + try: + astnode = compile(content, "source", "exec", 1024) # 1024 for AST + except ValueError: + start, end = getstatementrange_old(lineno, source, assertion) + return None, start, end + start, end = get_statement_startend2(lineno, astnode) + # we need to correct the end: + # - ast-parsing strips comments + # - there might be empty lines + # - we might have lesser indented code blocks at the end + if end is None: + end = len(source.lines) + + if end > start + 1: + # make sure we don't span differently indented code blocks + # by using the BlockFinder helper used which inspect.getsource() uses itself + block_finder = inspect.BlockFinder() + # if we start with an indented line, put blockfinder to "started" mode + block_finder.started = source.lines[start][0].isspace() + it = ((x + "\n") for x in source.lines[start:end]) + try: + for tok in tokenize.generate_tokens(lambda: next(it)): + block_finder.tokeneater(*tok) + except (inspect.EndOfBlock, IndentationError): + end = block_finder.last + start + except Exception: + pass + + # the end might still point to a comment or empty line, correct it + while end: + line = source.lines[end - 1].lstrip() + if line.startswith("#") or not line: + end -= 1 + else: + break + return astnode, start, end + + +def getstatementrange_old(lineno, source, assertion=False): + """ return (start, end) tuple which spans the minimal + statement region which containing the given lineno. + raise an IndexError if no such statementrange can be found. + """ + # XXX this logic is only used on python2.4 and below + # 1. find the start of the statement + from codeop import compile_command + for start in range(lineno, -1, -1): + if assertion: + line = source.lines[start] + # the following lines are not fully tested, change with care + if 'super' in line and 'self' in line and '__init__' in line: + raise IndexError("likely a subclass") + if "assert" not in line and "raise" not in line: + continue + trylines = source.lines[start:lineno+1] + # quick hack to prepare parsing an indented line with + # compile_command() (which errors on "return" outside defs) + trylines.insert(0, 'def xxx():') + trysource = '\n '.join(trylines) + # ^ space here + try: + compile_command(trysource) + except (SyntaxError, OverflowError, ValueError): + continue + + # 2. find the end of the statement + for end in range(lineno+1, len(source)+1): + trysource = source[start:end] + if trysource.isparseable(): + return start, end + raise SyntaxError("no valid source range around line %d " % (lineno,)) + + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_error.py b/dbdpy-env/lib/python3.9/site-packages/py/_error.py new file mode 100644 index 00000000..a6375de9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_error.py @@ -0,0 +1,91 @@ +""" +create errno-specific classes for IO or os calls. + +""" +from types import ModuleType +import sys, os, errno + +class Error(EnvironmentError): + def __repr__(self): + return "%s.%s %r: %s " %(self.__class__.__module__, + self.__class__.__name__, + self.__class__.__doc__, + " ".join(map(str, self.args)), + #repr(self.args) + ) + + def __str__(self): + s = "[%s]: %s" %(self.__class__.__doc__, + " ".join(map(str, self.args)), + ) + return s + +_winerrnomap = { + 2: errno.ENOENT, + 3: errno.ENOENT, + 17: errno.EEXIST, + 18: errno.EXDEV, + 13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailiable + 22: errno.ENOTDIR, + 20: errno.ENOTDIR, + 267: errno.ENOTDIR, + 5: errno.EACCES, # anything better? +} + +class ErrorMaker(ModuleType): + """ lazily provides Exception classes for each possible POSIX errno + (as defined per the 'errno' module). All such instances + subclass EnvironmentError. + """ + Error = Error + _errno2class = {} + + def __getattr__(self, name): + if name[0] == "_": + raise AttributeError(name) + eno = getattr(errno, name) + cls = self._geterrnoclass(eno) + setattr(self, name, cls) + return cls + + def _geterrnoclass(self, eno): + try: + return self._errno2class[eno] + except KeyError: + clsname = errno.errorcode.get(eno, "UnknownErrno%d" %(eno,)) + errorcls = type(Error)(clsname, (Error,), + {'__module__':'py.error', + '__doc__': os.strerror(eno)}) + self._errno2class[eno] = errorcls + return errorcls + + def checked_call(self, func, *args, **kwargs): + """ call a function and raise an errno-exception if applicable. """ + __tracebackhide__ = True + try: + return func(*args, **kwargs) + except self.Error: + raise + except (OSError, EnvironmentError): + cls, value, tb = sys.exc_info() + if not hasattr(value, 'errno'): + raise + __tracebackhide__ = False + errno = value.errno + try: + if not isinstance(value, WindowsError): + raise NameError + except NameError: + # we are not on Windows, or we got a proper OSError + cls = self._geterrnoclass(errno) + else: + try: + cls = self._geterrnoclass(_winerrnomap[errno]) + except KeyError: + raise value + raise cls("%s%r" % (func.__name__, args)) + __tracebackhide__ = True + + +error = ErrorMaker('py.error') +sys.modules[error.__name__] = error \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_io/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_io/__init__.py new file mode 100644 index 00000000..835f01f3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_io/__init__.py @@ -0,0 +1 @@ +""" input/output helping """ diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_io/capture.py b/dbdpy-env/lib/python3.9/site-packages/py/_io/capture.py new file mode 100644 index 00000000..cacf2fa7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_io/capture.py @@ -0,0 +1,371 @@ +import os +import sys +import py +import tempfile + +try: + from io import StringIO +except ImportError: + from StringIO import StringIO + +if sys.version_info < (3,0): + class TextIO(StringIO): + def write(self, data): + if not isinstance(data, unicode): + data = unicode(data, getattr(self, '_encoding', 'UTF-8'), 'replace') + return StringIO.write(self, data) +else: + TextIO = StringIO + +try: + from io import BytesIO +except ImportError: + class BytesIO(StringIO): + def write(self, data): + if isinstance(data, unicode): + raise TypeError("not a byte value: %r" %(data,)) + return StringIO.write(self, data) + +patchsysdict = {0: 'stdin', 1: 'stdout', 2: 'stderr'} + +class FDCapture: + """ Capture IO to/from a given os-level filedescriptor. """ + + def __init__(self, targetfd, tmpfile=None, now=True, patchsys=False): + """ save targetfd descriptor, and open a new + temporary file there. If no tmpfile is + specified a tempfile.Tempfile() will be opened + in text mode. + """ + self.targetfd = targetfd + if tmpfile is None and targetfd != 0: + f = tempfile.TemporaryFile('wb+') + tmpfile = dupfile(f, encoding="UTF-8") + f.close() + self.tmpfile = tmpfile + self._savefd = os.dup(self.targetfd) + if patchsys: + self._oldsys = getattr(sys, patchsysdict[targetfd]) + if now: + self.start() + + def start(self): + try: + os.fstat(self._savefd) + except OSError: + raise ValueError("saved filedescriptor not valid, " + "did you call start() twice?") + if self.targetfd == 0 and not self.tmpfile: + fd = os.open(devnullpath, os.O_RDONLY) + os.dup2(fd, 0) + os.close(fd) + if hasattr(self, '_oldsys'): + setattr(sys, patchsysdict[self.targetfd], DontReadFromInput()) + else: + os.dup2(self.tmpfile.fileno(), self.targetfd) + if hasattr(self, '_oldsys'): + setattr(sys, patchsysdict[self.targetfd], self.tmpfile) + + def done(self): + """ unpatch and clean up, returns the self.tmpfile (file object) + """ + os.dup2(self._savefd, self.targetfd) + os.close(self._savefd) + if self.targetfd != 0: + self.tmpfile.seek(0) + if hasattr(self, '_oldsys'): + setattr(sys, patchsysdict[self.targetfd], self._oldsys) + return self.tmpfile + + def writeorg(self, data): + """ write a string to the original file descriptor + """ + tempfp = tempfile.TemporaryFile() + try: + os.dup2(self._savefd, tempfp.fileno()) + tempfp.write(data) + finally: + tempfp.close() + + +def dupfile(f, mode=None, buffering=0, raising=False, encoding=None): + """ return a new open file object that's a duplicate of f + + mode is duplicated if not given, 'buffering' controls + buffer size (defaulting to no buffering) and 'raising' + defines whether an exception is raised when an incompatible + file object is passed in (if raising is False, the file + object itself will be returned) + """ + try: + fd = f.fileno() + mode = mode or f.mode + except AttributeError: + if raising: + raise + return f + newfd = os.dup(fd) + if sys.version_info >= (3,0): + if encoding is not None: + mode = mode.replace("b", "") + buffering = True + return os.fdopen(newfd, mode, buffering, encoding, closefd=True) + else: + f = os.fdopen(newfd, mode, buffering) + if encoding is not None: + return EncodedFile(f, encoding) + return f + +class EncodedFile(object): + def __init__(self, _stream, encoding): + self._stream = _stream + self.encoding = encoding + + def write(self, obj): + if isinstance(obj, unicode): + obj = obj.encode(self.encoding) + elif isinstance(obj, str): + pass + else: + obj = str(obj) + self._stream.write(obj) + + def writelines(self, linelist): + data = ''.join(linelist) + self.write(data) + + def __getattr__(self, name): + return getattr(self._stream, name) + +class Capture(object): + def call(cls, func, *args, **kwargs): + """ return a (res, out, err) tuple where + out and err represent the output/error output + during function execution. + call the given function with args/kwargs + and capture output/error during its execution. + """ + so = cls() + try: + res = func(*args, **kwargs) + finally: + out, err = so.reset() + return res, out, err + call = classmethod(call) + + def reset(self): + """ reset sys.stdout/stderr and return captured output as strings. """ + if hasattr(self, '_reset'): + raise ValueError("was already reset") + self._reset = True + outfile, errfile = self.done(save=False) + out, err = "", "" + if outfile and not outfile.closed: + out = outfile.read() + outfile.close() + if errfile and errfile != outfile and not errfile.closed: + err = errfile.read() + errfile.close() + return out, err + + def suspend(self): + """ return current snapshot captures, memorize tempfiles. """ + outerr = self.readouterr() + outfile, errfile = self.done() + return outerr + + +class StdCaptureFD(Capture): + """ This class allows to capture writes to FD1 and FD2 + and may connect a NULL file to FD0 (and prevent + reads from sys.stdin). If any of the 0,1,2 file descriptors + is invalid it will not be captured. + """ + def __init__(self, out=True, err=True, mixed=False, + in_=True, patchsys=True, now=True): + self._options = { + "out": out, + "err": err, + "mixed": mixed, + "in_": in_, + "patchsys": patchsys, + "now": now, + } + self._save() + if now: + self.startall() + + def _save(self): + in_ = self._options['in_'] + out = self._options['out'] + err = self._options['err'] + mixed = self._options['mixed'] + patchsys = self._options['patchsys'] + if in_: + try: + self.in_ = FDCapture(0, tmpfile=None, now=False, + patchsys=patchsys) + except OSError: + pass + if out: + tmpfile = None + if hasattr(out, 'write'): + tmpfile = out + try: + self.out = FDCapture(1, tmpfile=tmpfile, + now=False, patchsys=patchsys) + self._options['out'] = self.out.tmpfile + except OSError: + pass + if err: + if out and mixed: + tmpfile = self.out.tmpfile + elif hasattr(err, 'write'): + tmpfile = err + else: + tmpfile = None + try: + self.err = FDCapture(2, tmpfile=tmpfile, + now=False, patchsys=patchsys) + self._options['err'] = self.err.tmpfile + except OSError: + pass + + def startall(self): + if hasattr(self, 'in_'): + self.in_.start() + if hasattr(self, 'out'): + self.out.start() + if hasattr(self, 'err'): + self.err.start() + + def resume(self): + """ resume capturing with original temp files. """ + self.startall() + + def done(self, save=True): + """ return (outfile, errfile) and stop capturing. """ + outfile = errfile = None + if hasattr(self, 'out') and not self.out.tmpfile.closed: + outfile = self.out.done() + if hasattr(self, 'err') and not self.err.tmpfile.closed: + errfile = self.err.done() + if hasattr(self, 'in_'): + tmpfile = self.in_.done() + if save: + self._save() + return outfile, errfile + + def readouterr(self): + """ return snapshot value of stdout/stderr capturings. """ + if hasattr(self, "out"): + out = self._readsnapshot(self.out.tmpfile) + else: + out = "" + if hasattr(self, "err"): + err = self._readsnapshot(self.err.tmpfile) + else: + err = "" + return out, err + + def _readsnapshot(self, f): + f.seek(0) + res = f.read() + enc = getattr(f, "encoding", None) + if enc: + res = py.builtin._totext(res, enc, "replace") + f.truncate(0) + f.seek(0) + return res + + +class StdCapture(Capture): + """ This class allows to capture writes to sys.stdout|stderr "in-memory" + and will raise errors on tries to read from sys.stdin. It only + modifies sys.stdout|stderr|stdin attributes and does not + touch underlying File Descriptors (use StdCaptureFD for that). + """ + def __init__(self, out=True, err=True, in_=True, mixed=False, now=True): + self._oldout = sys.stdout + self._olderr = sys.stderr + self._oldin = sys.stdin + if out and not hasattr(out, 'file'): + out = TextIO() + self.out = out + if err: + if mixed: + err = out + elif not hasattr(err, 'write'): + err = TextIO() + self.err = err + self.in_ = in_ + if now: + self.startall() + + def startall(self): + if self.out: + sys.stdout = self.out + if self.err: + sys.stderr = self.err + if self.in_: + sys.stdin = self.in_ = DontReadFromInput() + + def done(self, save=True): + """ return (outfile, errfile) and stop capturing. """ + outfile = errfile = None + if self.out and not self.out.closed: + sys.stdout = self._oldout + outfile = self.out + outfile.seek(0) + if self.err and not self.err.closed: + sys.stderr = self._olderr + errfile = self.err + errfile.seek(0) + if self.in_: + sys.stdin = self._oldin + return outfile, errfile + + def resume(self): + """ resume capturing with original temp files. """ + self.startall() + + def readouterr(self): + """ return snapshot value of stdout/stderr capturings. """ + out = err = "" + if self.out: + out = self.out.getvalue() + self.out.truncate(0) + self.out.seek(0) + if self.err: + err = self.err.getvalue() + self.err.truncate(0) + self.err.seek(0) + return out, err + +class DontReadFromInput: + """Temporary stub class. Ideally when stdin is accessed, the + capturing should be turned off, with possibly all data captured + so far sent to the screen. This should be configurable, though, + because in automated test runs it is better to crash than + hang indefinitely. + """ + def read(self, *args): + raise IOError("reading from stdin while output is captured") + readline = read + readlines = read + __iter__ = read + + def fileno(self): + raise ValueError("redirected Stdin is pseudofile, has no fileno()") + def isatty(self): + return False + def close(self): + pass + +try: + devnullpath = os.devnull +except AttributeError: + if os.name == 'nt': + devnullpath = 'NUL' + else: + devnullpath = '/dev/null' diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_io/saferepr.py b/dbdpy-env/lib/python3.9/site-packages/py/_io/saferepr.py new file mode 100644 index 00000000..8518290e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_io/saferepr.py @@ -0,0 +1,71 @@ +import py +import sys + +builtin_repr = repr + +reprlib = py.builtin._tryimport('repr', 'reprlib') + +class SafeRepr(reprlib.Repr): + """ subclass of repr.Repr that limits the resulting size of repr() + and includes information on exceptions raised during the call. + """ + def repr(self, x): + return self._callhelper(reprlib.Repr.repr, self, x) + + def repr_unicode(self, x, level): + # Strictly speaking wrong on narrow builds + def repr(u): + if "'" not in u: + return py.builtin._totext("'%s'") % u + elif '"' not in u: + return py.builtin._totext('"%s"') % u + else: + return py.builtin._totext("'%s'") % u.replace("'", r"\'") + s = repr(x[:self.maxstring]) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = repr(x[:i] + x[len(x)-j:]) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_instance(self, x, level): + return self._callhelper(builtin_repr, x) + + def _callhelper(self, call, x, *args): + try: + # Try the vanilla repr and make sure that the result is a string + s = call(x, *args) + except py.builtin._sysex: + raise + except: + cls, e, tb = sys.exc_info() + exc_name = getattr(cls, '__name__', 'unknown') + try: + exc_info = str(e) + except py.builtin._sysex: + raise + except: + exc_info = 'unknown' + return '<[%s("%s") raised in repr()] %s object at 0x%x>' % ( + exc_name, exc_info, x.__class__.__name__, id(x)) + else: + if len(s) > self.maxsize: + i = max(0, (self.maxsize-3)//2) + j = max(0, self.maxsize-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + +def saferepr(obj, maxsize=240): + """ return a size-limited safe repr-string for the given object. + Failing __repr__ functions of user instances will be represented + with a short exception info and 'saferepr' generally takes + care to never raise exceptions itself. This function is a wrapper + around the Repr/reprlib functionality of the standard 2.6 lib. + """ + # review exception handling + srepr = SafeRepr() + srepr.maxstring = maxsize + srepr.maxsize = maxsize + srepr.maxother = 160 + return srepr.repr(obj) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_io/terminalwriter.py b/dbdpy-env/lib/python3.9/site-packages/py/_io/terminalwriter.py new file mode 100644 index 00000000..442ca239 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_io/terminalwriter.py @@ -0,0 +1,423 @@ +""" + +Helper functions for writing to terminals and files. + +""" + + +import sys, os, unicodedata +import py +py3k = sys.version_info[0] >= 3 +py33 = sys.version_info >= (3, 3) +from py.builtin import text, bytes + +win32_and_ctypes = False +colorama = None +if sys.platform == "win32": + try: + import colorama + except ImportError: + try: + import ctypes + win32_and_ctypes = True + except ImportError: + pass + + +def _getdimensions(): + if py33: + import shutil + size = shutil.get_terminal_size() + return size.lines, size.columns + else: + import termios, fcntl, struct + call = fcntl.ioctl(1, termios.TIOCGWINSZ, "\000" * 8) + height, width = struct.unpack("hhhh", call)[:2] + return height, width + + +def get_terminal_width(): + width = 0 + try: + _, width = _getdimensions() + except py.builtin._sysex: + raise + except: + # pass to fallback below + pass + + if width == 0: + # FALLBACK: + # * some exception happened + # * or this is emacs terminal which reports (0,0) + width = int(os.environ.get('COLUMNS', 80)) + + # XXX the windows getdimensions may be bogus, let's sanify a bit + if width < 40: + width = 80 + return width + +terminal_width = get_terminal_width() + +char_width = { + 'A': 1, # "Ambiguous" + 'F': 2, # Fullwidth + 'H': 1, # Halfwidth + 'N': 1, # Neutral + 'Na': 1, # Narrow + 'W': 2, # Wide +} + + +def get_line_width(text): + text = unicodedata.normalize('NFC', text) + return sum(char_width.get(unicodedata.east_asian_width(c), 1) for c in text) + + +# XXX unify with _escaped func below +def ansi_print(text, esc, file=None, newline=True, flush=False): + if file is None: + file = sys.stderr + text = text.rstrip() + if esc and not isinstance(esc, tuple): + esc = (esc,) + if esc and sys.platform != "win32" and file.isatty(): + text = (''.join(['\x1b[%sm' % cod for cod in esc]) + + text + + '\x1b[0m') # ANSI color code "reset" + if newline: + text += '\n' + + if esc and win32_and_ctypes and file.isatty(): + if 1 in esc: + bold = True + esc = tuple([x for x in esc if x != 1]) + else: + bold = False + esctable = {() : FOREGROUND_WHITE, # normal + (31,): FOREGROUND_RED, # red + (32,): FOREGROUND_GREEN, # green + (33,): FOREGROUND_GREEN|FOREGROUND_RED, # yellow + (34,): FOREGROUND_BLUE, # blue + (35,): FOREGROUND_BLUE|FOREGROUND_RED, # purple + (36,): FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan + (37,): FOREGROUND_WHITE, # white + (39,): FOREGROUND_WHITE, # reset + } + attr = esctable.get(esc, FOREGROUND_WHITE) + if bold: + attr |= FOREGROUND_INTENSITY + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + if file is sys.stderr: + handle = GetStdHandle(STD_ERROR_HANDLE) + else: + handle = GetStdHandle(STD_OUTPUT_HANDLE) + oldcolors = GetConsoleInfo(handle).wAttributes + attr |= (oldcolors & 0x0f0) + SetConsoleTextAttribute(handle, attr) + while len(text) > 32768: + file.write(text[:32768]) + text = text[32768:] + if text: + file.write(text) + SetConsoleTextAttribute(handle, oldcolors) + else: + file.write(text) + + if flush: + file.flush() + +def should_do_markup(file): + if os.environ.get('PY_COLORS') == '1': + return True + if os.environ.get('PY_COLORS') == '0': + return False + if 'NO_COLOR' in os.environ: + return False + return hasattr(file, 'isatty') and file.isatty() \ + and os.environ.get('TERM') != 'dumb' \ + and not (sys.platform.startswith('java') and os._name == 'nt') + +class TerminalWriter(object): + _esctable = dict(black=30, red=31, green=32, yellow=33, + blue=34, purple=35, cyan=36, white=37, + Black=40, Red=41, Green=42, Yellow=43, + Blue=44, Purple=45, Cyan=46, White=47, + bold=1, light=2, blink=5, invert=7) + + # XXX deprecate stringio argument + def __init__(self, file=None, stringio=False, encoding=None): + if file is None: + if stringio: + self.stringio = file = py.io.TextIO() + else: + from sys import stdout as file + elif py.builtin.callable(file) and not ( + hasattr(file, "write") and hasattr(file, "flush")): + file = WriteFile(file, encoding=encoding) + if hasattr(file, "isatty") and file.isatty() and colorama: + file = colorama.AnsiToWin32(file).stream + self.encoding = encoding or getattr(file, 'encoding', "utf-8") + self._file = file + self.hasmarkup = should_do_markup(file) + self._lastlen = 0 + self._chars_on_current_line = 0 + self._width_of_current_line = 0 + + @property + def fullwidth(self): + if hasattr(self, '_terminal_width'): + return self._terminal_width + return get_terminal_width() + + @fullwidth.setter + def fullwidth(self, value): + self._terminal_width = value + + @property + def chars_on_current_line(self): + """Return the number of characters written so far in the current line. + + Please note that this count does not produce correct results after a reline() call, + see #164. + + .. versionadded:: 1.5.0 + + :rtype: int + """ + return self._chars_on_current_line + + @property + def width_of_current_line(self): + """Return an estimate of the width so far in the current line. + + .. versionadded:: 1.6.0 + + :rtype: int + """ + return self._width_of_current_line + + def _escaped(self, text, esc): + if esc and self.hasmarkup: + text = (''.join(['\x1b[%sm' % cod for cod in esc]) + + text +'\x1b[0m') + return text + + def markup(self, text, **kw): + esc = [] + for name in kw: + if name not in self._esctable: + raise ValueError("unknown markup: %r" %(name,)) + if kw[name]: + esc.append(self._esctable[name]) + return self._escaped(text, tuple(esc)) + + def sep(self, sepchar, title=None, fullwidth=None, **kw): + if fullwidth is None: + fullwidth = self.fullwidth + # the goal is to have the line be as long as possible + # under the condition that len(line) <= fullwidth + if sys.platform == "win32": + # if we print in the last column on windows we are on a + # new line but there is no way to verify/neutralize this + # (we may not know the exact line width) + # so let's be defensive to avoid empty lines in the output + fullwidth -= 1 + if title is not None: + # we want 2 + 2*len(fill) + len(title) <= fullwidth + # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth + # 2*len(sepchar)*N <= fullwidth - len(title) - 2 + # N <= (fullwidth - len(title) - 2) // (2*len(sepchar)) + N = max((fullwidth - len(title) - 2) // (2*len(sepchar)), 1) + fill = sepchar * N + line = "%s %s %s" % (fill, title, fill) + else: + # we want len(sepchar)*N <= fullwidth + # i.e. N <= fullwidth // len(sepchar) + line = sepchar * (fullwidth // len(sepchar)) + # in some situations there is room for an extra sepchar at the right, + # in particular if we consider that with a sepchar like "_ " the + # trailing space is not important at the end of the line + if len(line) + len(sepchar.rstrip()) <= fullwidth: + line += sepchar.rstrip() + + self.line(line, **kw) + + def write(self, msg, **kw): + if msg: + if not isinstance(msg, (bytes, text)): + msg = text(msg) + + self._update_chars_on_current_line(msg) + + if self.hasmarkup and kw: + markupmsg = self.markup(msg, **kw) + else: + markupmsg = msg + write_out(self._file, markupmsg) + + def _update_chars_on_current_line(self, text_or_bytes): + newline = b'\n' if isinstance(text_or_bytes, bytes) else '\n' + current_line = text_or_bytes.rsplit(newline, 1)[-1] + if isinstance(current_line, bytes): + current_line = current_line.decode('utf-8', errors='replace') + if newline in text_or_bytes: + self._chars_on_current_line = len(current_line) + self._width_of_current_line = get_line_width(current_line) + else: + self._chars_on_current_line += len(current_line) + self._width_of_current_line += get_line_width(current_line) + + def line(self, s='', **kw): + self.write(s, **kw) + self._checkfill(s) + self.write('\n') + + def reline(self, line, **kw): + if not self.hasmarkup: + raise ValueError("cannot use rewrite-line without terminal") + self.write(line, **kw) + self._checkfill(line) + self.write('\r') + self._lastlen = len(line) + + def _checkfill(self, line): + diff2last = self._lastlen - len(line) + if diff2last > 0: + self.write(" " * diff2last) + +class Win32ConsoleWriter(TerminalWriter): + def write(self, msg, **kw): + if msg: + if not isinstance(msg, (bytes, text)): + msg = text(msg) + + self._update_chars_on_current_line(msg) + + oldcolors = None + if self.hasmarkup and kw: + handle = GetStdHandle(STD_OUTPUT_HANDLE) + oldcolors = GetConsoleInfo(handle).wAttributes + default_bg = oldcolors & 0x00F0 + attr = default_bg + if kw.pop('bold', False): + attr |= FOREGROUND_INTENSITY + + if kw.pop('red', False): + attr |= FOREGROUND_RED + elif kw.pop('blue', False): + attr |= FOREGROUND_BLUE + elif kw.pop('green', False): + attr |= FOREGROUND_GREEN + elif kw.pop('yellow', False): + attr |= FOREGROUND_GREEN|FOREGROUND_RED + else: + attr |= oldcolors & 0x0007 + + SetConsoleTextAttribute(handle, attr) + write_out(self._file, msg) + if oldcolors: + SetConsoleTextAttribute(handle, oldcolors) + +class WriteFile(object): + def __init__(self, writemethod, encoding=None): + self.encoding = encoding + self._writemethod = writemethod + + def write(self, data): + if self.encoding: + data = data.encode(self.encoding, "replace") + self._writemethod(data) + + def flush(self): + return + + +if win32_and_ctypes: + TerminalWriter = Win32ConsoleWriter + import ctypes + from ctypes import wintypes + + # ctypes access to the Windows console + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + FOREGROUND_BLACK = 0x0000 # black text + FOREGROUND_BLUE = 0x0001 # text color contains blue. + FOREGROUND_GREEN = 0x0002 # text color contains green. + FOREGROUND_RED = 0x0004 # text color contains red. + FOREGROUND_WHITE = 0x0007 + FOREGROUND_INTENSITY = 0x0008 # text color is intensified. + BACKGROUND_BLACK = 0x0000 # background color black + BACKGROUND_BLUE = 0x0010 # background color contains blue. + BACKGROUND_GREEN = 0x0020 # background color contains green. + BACKGROUND_RED = 0x0040 # background color contains red. + BACKGROUND_WHITE = 0x0070 + BACKGROUND_INTENSITY = 0x0080 # background color is intensified. + + SHORT = ctypes.c_short + class COORD(ctypes.Structure): + _fields_ = [('X', SHORT), + ('Y', SHORT)] + class SMALL_RECT(ctypes.Structure): + _fields_ = [('Left', SHORT), + ('Top', SHORT), + ('Right', SHORT), + ('Bottom', SHORT)] + class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure): + _fields_ = [('dwSize', COORD), + ('dwCursorPosition', COORD), + ('wAttributes', wintypes.WORD), + ('srWindow', SMALL_RECT), + ('dwMaximumWindowSize', COORD)] + + _GetStdHandle = ctypes.windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [wintypes.DWORD] + _GetStdHandle.restype = wintypes.HANDLE + def GetStdHandle(kind): + return _GetStdHandle(kind) + + SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute + SetConsoleTextAttribute.argtypes = [wintypes.HANDLE, wintypes.WORD] + SetConsoleTextAttribute.restype = wintypes.BOOL + + _GetConsoleScreenBufferInfo = \ + ctypes.windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [wintypes.HANDLE, + ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + def GetConsoleInfo(handle): + info = CONSOLE_SCREEN_BUFFER_INFO() + _GetConsoleScreenBufferInfo(handle, ctypes.byref(info)) + return info + + def _getdimensions(): + handle = GetStdHandle(STD_OUTPUT_HANDLE) + info = GetConsoleInfo(handle) + # Substract one from the width, otherwise the cursor wraps + # and the ending \n causes an empty line to display. + return info.dwSize.Y, info.dwSize.X - 1 + +def write_out(fil, msg): + # XXX sometimes "msg" is of type bytes, sometimes text which + # complicates the situation. Should we try to enforce unicode? + try: + # on py27 and above writing out to sys.stdout with an encoding + # should usually work for unicode messages (if the encoding is + # capable of it) + fil.write(msg) + except UnicodeEncodeError: + # on py26 it might not work because stdout expects bytes + if fil.encoding: + try: + fil.write(msg.encode(fil.encoding)) + except UnicodeEncodeError: + # it might still fail if the encoding is not capable + pass + else: + fil.flush() + return + # fallback: escape all unicode characters + msg = msg.encode("unicode-escape").decode("ascii") + fil.write(msg) + fil.flush() diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_log/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_log/__init__.py new file mode 100644 index 00000000..fad62e96 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_log/__init__.py @@ -0,0 +1,2 @@ +""" logging API ('producers' and 'consumers' connected via keywords) """ + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_log/log.py b/dbdpy-env/lib/python3.9/site-packages/py/_log/log.py new file mode 100644 index 00000000..56969bcb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_log/log.py @@ -0,0 +1,206 @@ +""" +basic logging functionality based on a producer/consumer scheme. + +XXX implement this API: (maybe put it into slogger.py?) + + log = Logger( + info=py.log.STDOUT, + debug=py.log.STDOUT, + command=None) + log.info("hello", "world") + log.command("hello", "world") + + log = Logger(info=Logger(something=...), + debug=py.log.STDOUT, + command=None) +""" +import py +import sys + + +class Message(object): + def __init__(self, keywords, args): + self.keywords = keywords + self.args = args + + def content(self): + return " ".join(map(str, self.args)) + + def prefix(self): + return "[%s] " % (":".join(self.keywords)) + + def __str__(self): + return self.prefix() + self.content() + + +class Producer(object): + """ (deprecated) Log producer API which sends messages to be logged + to a 'consumer' object, which then prints them to stdout, + stderr, files, etc. Used extensively by PyPy-1.1. + """ + + Message = Message # to allow later customization + keywords2consumer = {} + + def __init__(self, keywords, keywordmapper=None, **kw): + if hasattr(keywords, 'split'): + keywords = tuple(keywords.split()) + self._keywords = keywords + if keywordmapper is None: + keywordmapper = default_keywordmapper + self._keywordmapper = keywordmapper + + def __repr__(self): + return "<py.log.Producer %s>" % ":".join(self._keywords) + + def __getattr__(self, name): + if '_' in name: + raise AttributeError(name) + producer = self.__class__(self._keywords + (name,)) + setattr(self, name, producer) + return producer + + def __call__(self, *args): + """ write a message to the appropriate consumer(s) """ + func = self._keywordmapper.getconsumer(self._keywords) + if func is not None: + func(self.Message(self._keywords, args)) + +class KeywordMapper: + def __init__(self): + self.keywords2consumer = {} + + def getstate(self): + return self.keywords2consumer.copy() + + def setstate(self, state): + self.keywords2consumer.clear() + self.keywords2consumer.update(state) + + def getconsumer(self, keywords): + """ return a consumer matching the given keywords. + + tries to find the most suitable consumer by walking, starting from + the back, the list of keywords, the first consumer matching a + keyword is returned (falling back to py.log.default) + """ + for i in range(len(keywords), 0, -1): + try: + return self.keywords2consumer[keywords[:i]] + except KeyError: + continue + return self.keywords2consumer.get('default', default_consumer) + + def setconsumer(self, keywords, consumer): + """ set a consumer for a set of keywords. """ + # normalize to tuples + if isinstance(keywords, str): + keywords = tuple(filter(None, keywords.split())) + elif hasattr(keywords, '_keywords'): + keywords = keywords._keywords + elif not isinstance(keywords, tuple): + raise TypeError("key %r is not a string or tuple" % (keywords,)) + if consumer is not None and not py.builtin.callable(consumer): + if not hasattr(consumer, 'write'): + raise TypeError( + "%r should be None, callable or file-like" % (consumer,)) + consumer = File(consumer) + self.keywords2consumer[keywords] = consumer + + +def default_consumer(msg): + """ the default consumer, prints the message to stdout (using 'print') """ + sys.stderr.write(str(msg)+"\n") + +default_keywordmapper = KeywordMapper() + + +def setconsumer(keywords, consumer): + default_keywordmapper.setconsumer(keywords, consumer) + + +def setstate(state): + default_keywordmapper.setstate(state) + + +def getstate(): + return default_keywordmapper.getstate() + +# +# Consumers +# + + +class File(object): + """ log consumer wrapping a file(-like) object """ + def __init__(self, f): + assert hasattr(f, 'write') + # assert isinstance(f, file) or not hasattr(f, 'open') + self._file = f + + def __call__(self, msg): + """ write a message to the log """ + self._file.write(str(msg) + "\n") + if hasattr(self._file, 'flush'): + self._file.flush() + + +class Path(object): + """ log consumer that opens and writes to a Path """ + def __init__(self, filename, append=False, + delayed_create=False, buffering=False): + self._append = append + self._filename = str(filename) + self._buffering = buffering + if not delayed_create: + self._openfile() + + def _openfile(self): + mode = self._append and 'a' or 'w' + f = open(self._filename, mode) + self._file = f + + def __call__(self, msg): + """ write a message to the log """ + if not hasattr(self, "_file"): + self._openfile() + self._file.write(str(msg) + "\n") + if not self._buffering: + self._file.flush() + + +def STDOUT(msg): + """ consumer that writes to sys.stdout """ + sys.stdout.write(str(msg)+"\n") + + +def STDERR(msg): + """ consumer that writes to sys.stderr """ + sys.stderr.write(str(msg)+"\n") + + +class Syslog: + """ consumer that writes to the syslog daemon """ + + def __init__(self, priority=None): + if priority is None: + priority = self.LOG_INFO + self.priority = priority + + def __call__(self, msg): + """ write a message to the log """ + import syslog + syslog.syslog(self.priority, str(msg)) + + +try: + import syslog +except ImportError: + pass +else: + for _prio in "EMERG ALERT CRIT ERR WARNING NOTICE INFO DEBUG".split(): + _prio = "LOG_" + _prio + try: + setattr(Syslog, _prio, getattr(syslog, _prio)) + except AttributeError: + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_log/warning.py b/dbdpy-env/lib/python3.9/site-packages/py/_log/warning.py new file mode 100644 index 00000000..6ef20d98 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_log/warning.py @@ -0,0 +1,79 @@ +import py, sys + +class DeprecationWarning(DeprecationWarning): + def __init__(self, msg, path, lineno): + self.msg = msg + self.path = path + self.lineno = lineno + def __repr__(self): + return "%s:%d: %s" %(self.path, self.lineno+1, self.msg) + def __str__(self): + return self.msg + +def _apiwarn(startversion, msg, stacklevel=2, function=None): + # below is mostly COPIED from python2.4/warnings.py's def warn() + # Get context information + if isinstance(stacklevel, str): + frame = sys._getframe(1) + level = 1 + found = frame.f_code.co_filename.find(stacklevel) != -1 + while frame: + co = frame.f_code + if co.co_filename.find(stacklevel) == -1: + if found: + stacklevel = level + break + else: + found = True + level += 1 + frame = frame.f_back + else: + stacklevel = 1 + msg = "%s (since version %s)" %(msg, startversion) + warn(msg, stacklevel=stacklevel+1, function=function) + + +def warn(msg, stacklevel=1, function=None): + if function is not None: + import inspect + filename = inspect.getfile(function) + lineno = py.code.getrawcode(function).co_firstlineno + else: + try: + caller = sys._getframe(stacklevel) + except ValueError: + globals = sys.__dict__ + lineno = 1 + else: + globals = caller.f_globals + lineno = caller.f_lineno + if '__name__' in globals: + module = globals['__name__'] + else: + module = "<string>" + filename = globals.get('__file__') + if filename: + fnl = filename.lower() + if fnl.endswith(".pyc") or fnl.endswith(".pyo"): + filename = filename[:-1] + elif fnl.endswith("$py.class"): + filename = filename.replace('$py.class', '.py') + else: + if module == "__main__": + try: + filename = sys.argv[0] + except AttributeError: + # embedded interpreters don't have sys.argv, see bug #839151 + filename = '__main__' + if not filename: + filename = module + path = py.path.local(filename) + warning = DeprecationWarning(msg, path, lineno) + import warnings + warnings.warn_explicit(warning, category=Warning, + filename=str(warning.path), + lineno=warning.lineno, + registry=warnings.__dict__.setdefault( + "__warningsregistry__", {}) + ) + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/__init__.py new file mode 100644 index 00000000..51f3246f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/__init__.py @@ -0,0 +1 @@ +""" unified file system api """ diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/cacheutil.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/cacheutil.py new file mode 100644 index 00000000..99225047 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/cacheutil.py @@ -0,0 +1,114 @@ +""" +This module contains multithread-safe cache implementations. + +All Caches have + + getorbuild(key, builder) + delentry(key) + +methods and allow configuration when instantiating the cache class. +""" +from time import time as gettime + +class BasicCache(object): + def __init__(self, maxentries=128): + self.maxentries = maxentries + self.prunenum = int(maxentries - maxentries/8) + self._dict = {} + + def clear(self): + self._dict.clear() + + def _getentry(self, key): + return self._dict[key] + + def _putentry(self, key, entry): + self._prunelowestweight() + self._dict[key] = entry + + def delentry(self, key, raising=False): + try: + del self._dict[key] + except KeyError: + if raising: + raise + + def getorbuild(self, key, builder): + try: + entry = self._getentry(key) + except KeyError: + entry = self._build(key, builder) + self._putentry(key, entry) + return entry.value + + def _prunelowestweight(self): + """ prune out entries with lowest weight. """ + numentries = len(self._dict) + if numentries >= self.maxentries: + # evict according to entry's weight + items = [(entry.weight, key) + for key, entry in self._dict.items()] + items.sort() + index = numentries - self.prunenum + if index > 0: + for weight, key in items[:index]: + # in MT situations the element might be gone + self.delentry(key, raising=False) + +class BuildcostAccessCache(BasicCache): + """ A BuildTime/Access-counting cache implementation. + the weight of a value is computed as the product of + + num-accesses-of-a-value * time-to-build-the-value + + The values with the least such weights are evicted + if the cache maxentries threshold is superceded. + For implementation flexibility more than one object + might be evicted at a time. + """ + # time function to use for measuring build-times + + def _build(self, key, builder): + start = gettime() + val = builder() + end = gettime() + return WeightedCountingEntry(val, end-start) + + +class WeightedCountingEntry(object): + def __init__(self, value, oneweight): + self._value = value + self.weight = self._oneweight = oneweight + + def value(self): + self.weight += self._oneweight + return self._value + value = property(value) + +class AgingCache(BasicCache): + """ This cache prunes out cache entries that are too old. + """ + def __init__(self, maxentries=128, maxseconds=10.0): + super(AgingCache, self).__init__(maxentries) + self.maxseconds = maxseconds + + def _getentry(self, key): + entry = self._dict[key] + if entry.isexpired(): + self.delentry(key) + raise KeyError(key) + return entry + + def _build(self, key, builder): + val = builder() + entry = AgingEntry(val, gettime() + self.maxseconds) + return entry + +class AgingEntry(object): + def __init__(self, value, expirationtime): + self.value = value + self.weight = expirationtime + + def isexpired(self): + t = gettime() + return t >= self.weight diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/common.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/common.py new file mode 100644 index 00000000..2364e5fe --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/common.py @@ -0,0 +1,459 @@ +""" +""" +import warnings +import os +import sys +import posixpath +import fnmatch +import py + +# Moved from local.py. +iswin32 = sys.platform == "win32" or (getattr(os, '_name', False) == 'nt') + +try: + # FileNotFoundError might happen in py34, and is not available with py27. + import_errors = (ImportError, FileNotFoundError) +except NameError: + import_errors = (ImportError,) + +try: + from os import fspath +except ImportError: + def fspath(path): + """ + Return the string representation of the path. + If str or bytes is passed in, it is returned unchanged. + This code comes from PEP 519, modified to support earlier versions of + python. + + This is required for python < 3.6. + """ + if isinstance(path, (py.builtin.text, py.builtin.bytes)): + return path + + # Work from the object's type to match method resolution of other magic + # methods. + path_type = type(path) + try: + return path_type.__fspath__(path) + except AttributeError: + if hasattr(path_type, '__fspath__'): + raise + try: + import pathlib + except import_errors: + pass + else: + if isinstance(path, pathlib.PurePath): + return py.builtin.text(path) + + raise TypeError("expected str, bytes or os.PathLike object, not " + + path_type.__name__) + +class Checkers: + _depend_on_existence = 'exists', 'link', 'dir', 'file' + + def __init__(self, path): + self.path = path + + def dir(self): + raise NotImplementedError + + def file(self): + raise NotImplementedError + + def dotfile(self): + return self.path.basename.startswith('.') + + def ext(self, arg): + if not arg.startswith('.'): + arg = '.' + arg + return self.path.ext == arg + + def exists(self): + raise NotImplementedError + + def basename(self, arg): + return self.path.basename == arg + + def basestarts(self, arg): + return self.path.basename.startswith(arg) + + def relto(self, arg): + return self.path.relto(arg) + + def fnmatch(self, arg): + return self.path.fnmatch(arg) + + def endswith(self, arg): + return str(self.path).endswith(arg) + + def _evaluate(self, kw): + for name, value in kw.items(): + invert = False + meth = None + try: + meth = getattr(self, name) + except AttributeError: + if name[:3] == 'not': + invert = True + try: + meth = getattr(self, name[3:]) + except AttributeError: + pass + if meth is None: + raise TypeError( + "no %r checker available for %r" % (name, self.path)) + try: + if py.code.getrawcode(meth).co_argcount > 1: + if (not meth(value)) ^ invert: + return False + else: + if bool(value) ^ bool(meth()) ^ invert: + return False + except (py.error.ENOENT, py.error.ENOTDIR, py.error.EBUSY): + # EBUSY feels not entirely correct, + # but its kind of necessary since ENOMEDIUM + # is not accessible in python + for name in self._depend_on_existence: + if name in kw: + if kw.get(name): + return False + name = 'not' + name + if name in kw: + if not kw.get(name): + return False + return True + +class NeverRaised(Exception): + pass + +class PathBase(object): + """ shared implementation for filesystem path objects.""" + Checkers = Checkers + + def __div__(self, other): + return self.join(fspath(other)) + __truediv__ = __div__ # py3k + + def basename(self): + """ basename part of path. """ + return self._getbyspec('basename')[0] + basename = property(basename, None, None, basename.__doc__) + + def dirname(self): + """ dirname part of path. """ + return self._getbyspec('dirname')[0] + dirname = property(dirname, None, None, dirname.__doc__) + + def purebasename(self): + """ pure base name of the path.""" + return self._getbyspec('purebasename')[0] + purebasename = property(purebasename, None, None, purebasename.__doc__) + + def ext(self): + """ extension of the path (including the '.').""" + return self._getbyspec('ext')[0] + ext = property(ext, None, None, ext.__doc__) + + def dirpath(self, *args, **kwargs): + """ return the directory path joined with any given path arguments. """ + return self.new(basename='').join(*args, **kwargs) + + def read_binary(self): + """ read and return a bytestring from reading the path. """ + with self.open('rb') as f: + return f.read() + + def read_text(self, encoding): + """ read and return a Unicode string from reading the path. """ + with self.open("r", encoding=encoding) as f: + return f.read() + + + def read(self, mode='r'): + """ read and return a bytestring from reading the path. """ + with self.open(mode) as f: + return f.read() + + def readlines(self, cr=1): + """ read and return a list of lines from the path. if cr is False, the +newline will be removed from the end of each line. """ + if sys.version_info < (3, ): + mode = 'rU' + else: # python 3 deprecates mode "U" in favor of "newline" option + mode = 'r' + + if not cr: + content = self.read(mode) + return content.split('\n') + else: + f = self.open(mode) + try: + return f.readlines() + finally: + f.close() + + def load(self): + """ (deprecated) return object unpickled from self.read() """ + f = self.open('rb') + try: + import pickle + return py.error.checked_call(pickle.load, f) + finally: + f.close() + + def move(self, target): + """ move this path to target. """ + if target.relto(self): + raise py.error.EINVAL( + target, + "cannot move path into a subdirectory of itself") + try: + self.rename(target) + except py.error.EXDEV: # invalid cross-device link + self.copy(target) + self.remove() + + def __repr__(self): + """ return a string representation of this path. """ + return repr(str(self)) + + def check(self, **kw): + """ check a path for existence and properties. + + Without arguments, return True if the path exists, otherwise False. + + valid checkers:: + + file=1 # is a file + file=0 # is not a file (may not even exist) + dir=1 # is a dir + link=1 # is a link + exists=1 # exists + + You can specify multiple checker definitions, for example:: + + path.check(file=1, link=1) # a link pointing to a file + """ + if not kw: + kw = {'exists': 1} + return self.Checkers(self)._evaluate(kw) + + def fnmatch(self, pattern): + """return true if the basename/fullname matches the glob-'pattern'. + + valid pattern characters:: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any char not in seq + + If the pattern contains a path-separator then the full path + is used for pattern matching and a '*' is prepended to the + pattern. + + if the pattern doesn't contain a path-separator the pattern + is only matched against the basename. + """ + return FNMatcher(pattern)(self) + + def relto(self, relpath): + """ return a string which is the relative part of the path + to the given 'relpath'. + """ + if not isinstance(relpath, (str, PathBase)): + raise TypeError("%r: not a string or path object" %(relpath,)) + strrelpath = str(relpath) + if strrelpath and strrelpath[-1] != self.sep: + strrelpath += self.sep + #assert strrelpath[-1] == self.sep + #assert strrelpath[-2] != self.sep + strself = self.strpath + if sys.platform == "win32" or getattr(os, '_name', None) == 'nt': + if os.path.normcase(strself).startswith( + os.path.normcase(strrelpath)): + return strself[len(strrelpath):] + elif strself.startswith(strrelpath): + return strself[len(strrelpath):] + return "" + + def ensure_dir(self, *args): + """ ensure the path joined with args is a directory. """ + return self.ensure(*args, **{"dir": True}) + + def bestrelpath(self, dest): + """ return a string which is a relative path from self + (assumed to be a directory) to dest such that + self.join(bestrelpath) == dest and if not such + path can be determined return dest. + """ + try: + if self == dest: + return os.curdir + base = self.common(dest) + if not base: # can be the case on windows + return str(dest) + self2base = self.relto(base) + reldest = dest.relto(base) + if self2base: + n = self2base.count(self.sep) + 1 + else: + n = 0 + l = [os.pardir] * n + if reldest: + l.append(reldest) + target = dest.sep.join(l) + return target + except AttributeError: + return str(dest) + + def exists(self): + return self.check() + + def isdir(self): + return self.check(dir=1) + + def isfile(self): + return self.check(file=1) + + def parts(self, reverse=False): + """ return a root-first list of all ancestor directories + plus the path itself. + """ + current = self + l = [self] + while 1: + last = current + current = current.dirpath() + if last == current: + break + l.append(current) + if not reverse: + l.reverse() + return l + + def common(self, other): + """ return the common part shared with the other path + or None if there is no common part. + """ + last = None + for x, y in zip(self.parts(), other.parts()): + if x != y: + return last + last = x + return last + + def __add__(self, other): + """ return new path object with 'other' added to the basename""" + return self.new(basename=self.basename+str(other)) + + def __cmp__(self, other): + """ return sort value (-1, 0, +1). """ + try: + return cmp(self.strpath, other.strpath) + except AttributeError: + return cmp(str(self), str(other)) # self.path, other.path) + + def __lt__(self, other): + try: + return self.strpath < other.strpath + except AttributeError: + return str(self) < str(other) + + def visit(self, fil=None, rec=None, ignore=NeverRaised, bf=False, sort=False): + """ yields all paths below the current one + + fil is a filter (glob pattern or callable), if not matching the + path will not be yielded, defaulting to None (everything is + returned) + + rec is a filter (glob pattern or callable) that controls whether + a node is descended, defaulting to None + + ignore is an Exception class that is ignoredwhen calling dirlist() + on any of the paths (by default, all exceptions are reported) + + bf if True will cause a breadthfirst search instead of the + default depthfirst. Default: False + + sort if True will sort entries within each directory level. + """ + for x in Visitor(fil, rec, ignore, bf, sort).gen(self): + yield x + + def _sortlist(self, res, sort): + if sort: + if hasattr(sort, '__call__'): + warnings.warn(DeprecationWarning( + "listdir(sort=callable) is deprecated and breaks on python3" + ), stacklevel=3) + res.sort(sort) + else: + res.sort() + + def samefile(self, other): + """ return True if other refers to the same stat object as self. """ + return self.strpath == str(other) + + def __fspath__(self): + return self.strpath + +class Visitor: + def __init__(self, fil, rec, ignore, bf, sort): + if isinstance(fil, py.builtin._basestring): + fil = FNMatcher(fil) + if isinstance(rec, py.builtin._basestring): + self.rec = FNMatcher(rec) + elif not hasattr(rec, '__call__') and rec: + self.rec = lambda path: True + else: + self.rec = rec + self.fil = fil + self.ignore = ignore + self.breadthfirst = bf + self.optsort = sort and sorted or (lambda x: x) + + def gen(self, path): + try: + entries = path.listdir() + except self.ignore: + return + rec = self.rec + dirs = self.optsort([p for p in entries + if p.check(dir=1) and (rec is None or rec(p))]) + if not self.breadthfirst: + for subdir in dirs: + for p in self.gen(subdir): + yield p + for p in self.optsort(entries): + if self.fil is None or self.fil(p): + yield p + if self.breadthfirst: + for subdir in dirs: + for p in self.gen(subdir): + yield p + +class FNMatcher: + def __init__(self, pattern): + self.pattern = pattern + + def __call__(self, path): + pattern = self.pattern + + if (pattern.find(path.sep) == -1 and + iswin32 and + pattern.find(posixpath.sep) != -1): + # Running on Windows, the pattern has no Windows path separators, + # and the pattern has one or more Posix path separators. Replace + # the Posix path separators with the Windows path separator. + pattern = pattern.replace(posixpath.sep, path.sep) + + if pattern.find(path.sep) == -1: + name = path.basename + else: + name = str(path) # path.strpath # XXX svn? + if not os.path.isabs(pattern): + pattern = '*' + path.sep + pattern + return fnmatch.fnmatch(name, pattern) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/local.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/local.py new file mode 100644 index 00000000..1385a039 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/local.py @@ -0,0 +1,1030 @@ +""" +local path implementation. +""" +from __future__ import with_statement + +from contextlib import contextmanager +import sys, os, atexit, io, uuid +import py +from py._path import common +from py._path.common import iswin32, fspath +from stat import S_ISLNK, S_ISDIR, S_ISREG + +from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink, dirname + +if sys.version_info > (3,0): + def map_as_list(func, iter): + return list(map(func, iter)) +else: + map_as_list = map + +ALLOW_IMPORTLIB_MODE = sys.version_info > (3,5) +if ALLOW_IMPORTLIB_MODE: + import importlib + + +class Stat(object): + def __getattr__(self, name): + return getattr(self._osstatresult, "st_" + name) + + def __init__(self, path, osstatresult): + self.path = path + self._osstatresult = osstatresult + + @property + def owner(self): + if iswin32: + raise NotImplementedError("XXX win32") + import pwd + entry = py.error.checked_call(pwd.getpwuid, self.uid) + return entry[0] + + @property + def group(self): + """ return group name of file. """ + if iswin32: + raise NotImplementedError("XXX win32") + import grp + entry = py.error.checked_call(grp.getgrgid, self.gid) + return entry[0] + + def isdir(self): + return S_ISDIR(self._osstatresult.st_mode) + + def isfile(self): + return S_ISREG(self._osstatresult.st_mode) + + def islink(self): + st = self.path.lstat() + return S_ISLNK(self._osstatresult.st_mode) + +class PosixPath(common.PathBase): + def chown(self, user, group, rec=0): + """ change ownership to the given user and group. + user and group may be specified by a number or + by a name. if rec is True change ownership + recursively. + """ + uid = getuserid(user) + gid = getgroupid(group) + if rec: + for x in self.visit(rec=lambda x: x.check(link=0)): + if x.check(link=0): + py.error.checked_call(os.chown, str(x), uid, gid) + py.error.checked_call(os.chown, str(self), uid, gid) + + def readlink(self): + """ return value of a symbolic link. """ + return py.error.checked_call(os.readlink, self.strpath) + + def mklinkto(self, oldname): + """ posix style hard link to another name. """ + py.error.checked_call(os.link, str(oldname), str(self)) + + def mksymlinkto(self, value, absolute=1): + """ create a symbolic link with the given value (pointing to another name). """ + if absolute: + py.error.checked_call(os.symlink, str(value), self.strpath) + else: + base = self.common(value) + # with posix local paths '/' is always a common base + relsource = self.__class__(value).relto(base) + reldest = self.relto(base) + n = reldest.count(self.sep) + target = self.sep.join(('..', )*n + (relsource, )) + py.error.checked_call(os.symlink, target, self.strpath) + +def getuserid(user): + import pwd + if not isinstance(user, int): + user = pwd.getpwnam(user)[2] + return user + +def getgroupid(group): + import grp + if not isinstance(group, int): + group = grp.getgrnam(group)[2] + return group + +FSBase = not iswin32 and PosixPath or common.PathBase + +class LocalPath(FSBase): + """ object oriented interface to os.path and other local filesystem + related information. + """ + class ImportMismatchError(ImportError): + """ raised on pyimport() if there is a mismatch of __file__'s""" + + sep = os.sep + class Checkers(common.Checkers): + def _stat(self): + try: + return self._statcache + except AttributeError: + try: + self._statcache = self.path.stat() + except py.error.ELOOP: + self._statcache = self.path.lstat() + return self._statcache + + def dir(self): + return S_ISDIR(self._stat().mode) + + def file(self): + return S_ISREG(self._stat().mode) + + def exists(self): + return self._stat() + + def link(self): + st = self.path.lstat() + return S_ISLNK(st.mode) + + def __init__(self, path=None, expanduser=False): + """ Initialize and return a local Path instance. + + Path can be relative to the current directory. + If path is None it defaults to the current working directory. + If expanduser is True, tilde-expansion is performed. + Note that Path instances always carry an absolute path. + Note also that passing in a local path object will simply return + the exact same path object. Use new() to get a new copy. + """ + if path is None: + self.strpath = py.error.checked_call(os.getcwd) + else: + try: + path = fspath(path) + except TypeError: + raise ValueError("can only pass None, Path instances " + "or non-empty strings to LocalPath") + if expanduser: + path = os.path.expanduser(path) + self.strpath = abspath(path) + + def __hash__(self): + s = self.strpath + if iswin32: + s = s.lower() + return hash(s) + + def __eq__(self, other): + s1 = fspath(self) + try: + s2 = fspath(other) + except TypeError: + return False + if iswin32: + s1 = s1.lower() + try: + s2 = s2.lower() + except AttributeError: + return False + return s1 == s2 + + def __ne__(self, other): + return not (self == other) + + def __lt__(self, other): + return fspath(self) < fspath(other) + + def __gt__(self, other): + return fspath(self) > fspath(other) + + def samefile(self, other): + """ return True if 'other' references the same file as 'self'. + """ + other = fspath(other) + if not isabs(other): + other = abspath(other) + if self == other: + return True + if not hasattr(os.path, "samefile"): + return False + return py.error.checked_call( + os.path.samefile, self.strpath, other) + + def remove(self, rec=1, ignore_errors=False): + """ remove a file or directory (or a directory tree if rec=1). + if ignore_errors is True, errors while removing directories will + be ignored. + """ + if self.check(dir=1, link=0): + if rec: + # force remove of readonly files on windows + if iswin32: + self.chmod(0o700, rec=1) + import shutil + py.error.checked_call( + shutil.rmtree, self.strpath, + ignore_errors=ignore_errors) + else: + py.error.checked_call(os.rmdir, self.strpath) + else: + if iswin32: + self.chmod(0o700) + py.error.checked_call(os.remove, self.strpath) + + def computehash(self, hashtype="md5", chunksize=524288): + """ return hexdigest of hashvalue for this file. """ + try: + try: + import hashlib as mod + except ImportError: + if hashtype == "sha1": + hashtype = "sha" + mod = __import__(hashtype) + hash = getattr(mod, hashtype)() + except (AttributeError, ImportError): + raise ValueError("Don't know how to compute %r hash" %(hashtype,)) + f = self.open('rb') + try: + while 1: + buf = f.read(chunksize) + if not buf: + return hash.hexdigest() + hash.update(buf) + finally: + f.close() + + def new(self, **kw): + """ create a modified version of this path. + the following keyword arguments modify various path parts:: + + a:/some/path/to/a/file.ext + xx drive + xxxxxxxxxxxxxxxxx dirname + xxxxxxxx basename + xxxx purebasename + xxx ext + """ + obj = object.__new__(self.__class__) + if not kw: + obj.strpath = self.strpath + return obj + drive, dirname, basename, purebasename,ext = self._getbyspec( + "drive,dirname,basename,purebasename,ext") + if 'basename' in kw: + if 'purebasename' in kw or 'ext' in kw: + raise ValueError("invalid specification %r" % kw) + else: + pb = kw.setdefault('purebasename', purebasename) + try: + ext = kw['ext'] + except KeyError: + pass + else: + if ext and not ext.startswith('.'): + ext = '.' + ext + kw['basename'] = pb + ext + + if ('dirname' in kw and not kw['dirname']): + kw['dirname'] = drive + else: + kw.setdefault('dirname', dirname) + kw.setdefault('sep', self.sep) + obj.strpath = normpath( + "%(dirname)s%(sep)s%(basename)s" % kw) + return obj + + def _getbyspec(self, spec): + """ see new for what 'spec' can be. """ + res = [] + parts = self.strpath.split(self.sep) + + args = filter(None, spec.split(',') ) + append = res.append + for name in args: + if name == 'drive': + append(parts[0]) + elif name == 'dirname': + append(self.sep.join(parts[:-1])) + else: + basename = parts[-1] + if name == 'basename': + append(basename) + else: + i = basename.rfind('.') + if i == -1: + purebasename, ext = basename, '' + else: + purebasename, ext = basename[:i], basename[i:] + if name == 'purebasename': + append(purebasename) + elif name == 'ext': + append(ext) + else: + raise ValueError("invalid part specification %r" % name) + return res + + def dirpath(self, *args, **kwargs): + """ return the directory path joined with any given path arguments. """ + if not kwargs: + path = object.__new__(self.__class__) + path.strpath = dirname(self.strpath) + if args: + path = path.join(*args) + return path + return super(LocalPath, self).dirpath(*args, **kwargs) + + def join(self, *args, **kwargs): + """ return a new path by appending all 'args' as path + components. if abs=1 is used restart from root if any + of the args is an absolute path. + """ + sep = self.sep + strargs = [fspath(arg) for arg in args] + strpath = self.strpath + if kwargs.get('abs'): + newargs = [] + for arg in reversed(strargs): + if isabs(arg): + strpath = arg + strargs = newargs + break + newargs.insert(0, arg) + # special case for when we have e.g. strpath == "/" + actual_sep = "" if strpath.endswith(sep) else sep + for arg in strargs: + arg = arg.strip(sep) + if iswin32: + # allow unix style paths even on windows. + arg = arg.strip('/') + arg = arg.replace('/', sep) + strpath = strpath + actual_sep + arg + actual_sep = sep + obj = object.__new__(self.__class__) + obj.strpath = normpath(strpath) + return obj + + def open(self, mode='r', ensure=False, encoding=None): + """ return an opened file with the given mode. + + If ensure is True, create parent directories if needed. + """ + if ensure: + self.dirpath().ensure(dir=1) + if encoding: + return py.error.checked_call(io.open, self.strpath, mode, encoding=encoding) + return py.error.checked_call(open, self.strpath, mode) + + def _fastjoin(self, name): + child = object.__new__(self.__class__) + child.strpath = self.strpath + self.sep + name + return child + + def islink(self): + return islink(self.strpath) + + def check(self, **kw): + if not kw: + return exists(self.strpath) + if len(kw) == 1: + if "dir" in kw: + return not kw["dir"] ^ isdir(self.strpath) + if "file" in kw: + return not kw["file"] ^ isfile(self.strpath) + return super(LocalPath, self).check(**kw) + + _patternchars = set("*?[" + os.path.sep) + def listdir(self, fil=None, sort=None): + """ list directory contents, possibly filter by the given fil func + and possibly sorted. + """ + if fil is None and sort is None: + names = py.error.checked_call(os.listdir, self.strpath) + return map_as_list(self._fastjoin, names) + if isinstance(fil, py.builtin._basestring): + if not self._patternchars.intersection(fil): + child = self._fastjoin(fil) + if exists(child.strpath): + return [child] + return [] + fil = common.FNMatcher(fil) + names = py.error.checked_call(os.listdir, self.strpath) + res = [] + for name in names: + child = self._fastjoin(name) + if fil is None or fil(child): + res.append(child) + self._sortlist(res, sort) + return res + + def size(self): + """ return size of the underlying file object """ + return self.stat().size + + def mtime(self): + """ return last modification time of the path. """ + return self.stat().mtime + + def copy(self, target, mode=False, stat=False): + """ copy path to target. + + If mode is True, will copy copy permission from path to target. + If stat is True, copy permission, last modification + time, last access time, and flags from path to target. + """ + if self.check(file=1): + if target.check(dir=1): + target = target.join(self.basename) + assert self!=target + copychunked(self, target) + if mode: + copymode(self.strpath, target.strpath) + if stat: + copystat(self, target) + else: + def rec(p): + return p.check(link=0) + for x in self.visit(rec=rec): + relpath = x.relto(self) + newx = target.join(relpath) + newx.dirpath().ensure(dir=1) + if x.check(link=1): + newx.mksymlinkto(x.readlink()) + continue + elif x.check(file=1): + copychunked(x, newx) + elif x.check(dir=1): + newx.ensure(dir=1) + if mode: + copymode(x.strpath, newx.strpath) + if stat: + copystat(x, newx) + + def rename(self, target): + """ rename this path to target. """ + target = fspath(target) + return py.error.checked_call(os.rename, self.strpath, target) + + def dump(self, obj, bin=1): + """ pickle object into path location""" + f = self.open('wb') + import pickle + try: + py.error.checked_call(pickle.dump, obj, f, bin) + finally: + f.close() + + def mkdir(self, *args): + """ create & return the directory joined with args. """ + p = self.join(*args) + py.error.checked_call(os.mkdir, fspath(p)) + return p + + def write_binary(self, data, ensure=False): + """ write binary data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + with self.open('wb') as f: + f.write(data) + + def write_text(self, data, encoding, ensure=False): + """ write text data into path using the specified encoding. + If ensure is True create missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + with self.open('w', encoding=encoding) as f: + f.write(data) + + def write(self, data, mode='w', ensure=False): + """ write data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + if 'b' in mode: + if not py.builtin._isbytes(data): + raise ValueError("can only process bytes") + else: + if not py.builtin._istext(data): + if not py.builtin._isbytes(data): + data = str(data) + else: + data = py.builtin._totext(data, sys.getdefaultencoding()) + f = self.open(mode) + try: + f.write(data) + finally: + f.close() + + def _ensuredirs(self): + parent = self.dirpath() + if parent == self: + return self + if parent.check(dir=0): + parent._ensuredirs() + if self.check(dir=0): + try: + self.mkdir() + except py.error.EEXIST: + # race condition: file/dir created by another thread/process. + # complain if it is not a dir + if self.check(dir=0): + raise + return self + + def ensure(self, *args, **kwargs): + """ ensure that an args-joined path exists (by default as + a file). if you specify a keyword argument 'dir=True' + then the path is forced to be a directory path. + """ + p = self.join(*args) + if kwargs.get('dir', 0): + return p._ensuredirs() + else: + p.dirpath()._ensuredirs() + if not p.check(file=1): + p.open('w').close() + return p + + def stat(self, raising=True): + """ Return an os.stat() tuple. """ + if raising == True: + return Stat(self, py.error.checked_call(os.stat, self.strpath)) + try: + return Stat(self, os.stat(self.strpath)) + except KeyboardInterrupt: + raise + except Exception: + return None + + def lstat(self): + """ Return an os.lstat() tuple. """ + return Stat(self, py.error.checked_call(os.lstat, self.strpath)) + + def setmtime(self, mtime=None): + """ set modification time for the given path. if 'mtime' is None + (the default) then the file's mtime is set to current time. + + Note that the resolution for 'mtime' is platform dependent. + """ + if mtime is None: + return py.error.checked_call(os.utime, self.strpath, mtime) + try: + return py.error.checked_call(os.utime, self.strpath, (-1, mtime)) + except py.error.EINVAL: + return py.error.checked_call(os.utime, self.strpath, (self.atime(), mtime)) + + def chdir(self): + """ change directory to self and return old current directory """ + try: + old = self.__class__() + except py.error.ENOENT: + old = None + py.error.checked_call(os.chdir, self.strpath) + return old + + + @contextmanager + def as_cwd(self): + """ + Return a context manager, which changes to the path's dir during the + managed "with" context. + On __enter__ it returns the old dir, which might be ``None``. + """ + old = self.chdir() + try: + yield old + finally: + if old is not None: + old.chdir() + + def realpath(self): + """ return a new path which contains no symbolic links.""" + return self.__class__(os.path.realpath(self.strpath)) + + def atime(self): + """ return last access time of the path. """ + return self.stat().atime + + def __repr__(self): + return 'local(%r)' % self.strpath + + def __str__(self): + """ return string representation of the Path. """ + return self.strpath + + def chmod(self, mode, rec=0): + """ change permissions to the given mode. If mode is an + integer it directly encodes the os-specific modes. + if rec is True perform recursively. + """ + if not isinstance(mode, int): + raise TypeError("mode %r must be an integer" % (mode,)) + if rec: + for x in self.visit(rec=rec): + py.error.checked_call(os.chmod, str(x), mode) + py.error.checked_call(os.chmod, self.strpath, mode) + + def pypkgpath(self): + """ return the Python package path by looking for the last + directory upwards which still contains an __init__.py. + Return None if a pkgpath can not be determined. + """ + pkgpath = None + for parent in self.parts(reverse=True): + if parent.isdir(): + if not parent.join('__init__.py').exists(): + break + if not isimportable(parent.basename): + break + pkgpath = parent + return pkgpath + + def _ensuresyspath(self, ensuremode, path): + if ensuremode: + s = str(path) + if ensuremode == "append": + if s not in sys.path: + sys.path.append(s) + else: + if s != sys.path[0]: + sys.path.insert(0, s) + + def pyimport(self, modname=None, ensuresyspath=True): + """ return path as an imported python module. + + If modname is None, look for the containing package + and construct an according module name. + The module will be put/looked up in sys.modules. + if ensuresyspath is True then the root dir for importing + the file (taking __init__.py files into account) will + be prepended to sys.path if it isn't there already. + If ensuresyspath=="append" the root dir will be appended + if it isn't already contained in sys.path. + if ensuresyspath is False no modification of syspath happens. + + Special value of ensuresyspath=="importlib" is intended + purely for using in pytest, it is capable only of importing + separate .py files outside packages, e.g. for test suite + without any __init__.py file. It effectively allows having + same-named test modules in different places and offers + mild opt-in via this option. Note that it works only in + recent versions of python. + """ + if not self.check(): + raise py.error.ENOENT(self) + + if ensuresyspath == 'importlib': + if modname is None: + modname = self.purebasename + if not ALLOW_IMPORTLIB_MODE: + raise ImportError( + "Can't use importlib due to old version of Python") + spec = importlib.util.spec_from_file_location( + modname, str(self)) + if spec is None: + raise ImportError( + "Can't find module %s at location %s" % + (modname, str(self)) + ) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + pkgpath = None + if modname is None: + pkgpath = self.pypkgpath() + if pkgpath is not None: + pkgroot = pkgpath.dirpath() + names = self.new(ext="").relto(pkgroot).split(self.sep) + if names[-1] == "__init__": + names.pop() + modname = ".".join(names) + else: + pkgroot = self.dirpath() + modname = self.purebasename + + self._ensuresyspath(ensuresyspath, pkgroot) + __import__(modname) + mod = sys.modules[modname] + if self.basename == "__init__.py": + return mod # we don't check anything as we might + # be in a namespace package ... too icky to check + modfile = mod.__file__ + if modfile[-4:] in ('.pyc', '.pyo'): + modfile = modfile[:-1] + elif modfile.endswith('$py.class'): + modfile = modfile[:-9] + '.py' + if modfile.endswith(os.path.sep + "__init__.py"): + if self.basename != "__init__.py": + modfile = modfile[:-12] + try: + issame = self.samefile(modfile) + except py.error.ENOENT: + issame = False + if not issame: + ignore = os.getenv('PY_IGNORE_IMPORTMISMATCH') + if ignore != '1': + raise self.ImportMismatchError(modname, modfile, self) + return mod + else: + try: + return sys.modules[modname] + except KeyError: + # we have a custom modname, do a pseudo-import + import types + mod = types.ModuleType(modname) + mod.__file__ = str(self) + sys.modules[modname] = mod + try: + py.builtin.execfile(str(self), mod.__dict__) + except: + del sys.modules[modname] + raise + return mod + + def sysexec(self, *argv, **popen_opts): + """ return stdout text from executing a system child process, + where the 'self' path points to executable. + The process is directly invoked and not through a system shell. + """ + from subprocess import Popen, PIPE + argv = map_as_list(str, argv) + popen_opts['stdout'] = popen_opts['stderr'] = PIPE + proc = Popen([str(self)] + argv, **popen_opts) + stdout, stderr = proc.communicate() + ret = proc.wait() + if py.builtin._isbytes(stdout): + stdout = py.builtin._totext(stdout, sys.getdefaultencoding()) + if ret != 0: + if py.builtin._isbytes(stderr): + stderr = py.builtin._totext(stderr, sys.getdefaultencoding()) + raise py.process.cmdexec.Error(ret, ret, str(self), + stdout, stderr,) + return stdout + + def sysfind(cls, name, checker=None, paths=None): + """ return a path object found by looking at the systems + underlying PATH specification. If the checker is not None + it will be invoked to filter matching paths. If a binary + cannot be found, None is returned + Note: This is probably not working on plain win32 systems + but may work on cygwin. + """ + if isabs(name): + p = py.path.local(name) + if p.check(file=1): + return p + else: + if paths is None: + if iswin32: + paths = os.environ['Path'].split(';') + if '' not in paths and '.' not in paths: + paths.append('.') + try: + systemroot = os.environ['SYSTEMROOT'] + except KeyError: + pass + else: + paths = [path.replace('%SystemRoot%', systemroot) + for path in paths] + else: + paths = os.environ['PATH'].split(':') + tryadd = [] + if iswin32: + tryadd += os.environ['PATHEXT'].split(os.pathsep) + tryadd.append("") + + for x in paths: + for addext in tryadd: + p = py.path.local(x).join(name, abs=True) + addext + try: + if p.check(file=1): + if checker: + if not checker(p): + continue + return p + except py.error.EACCES: + pass + return None + sysfind = classmethod(sysfind) + + def _gethomedir(cls): + try: + x = os.environ['HOME'] + except KeyError: + try: + x = os.environ["HOMEDRIVE"] + os.environ['HOMEPATH'] + except KeyError: + return None + return cls(x) + _gethomedir = classmethod(_gethomedir) + + # """ + # special class constructors for local filesystem paths + # """ + @classmethod + def get_temproot(cls): + """ return the system's temporary directory + (where tempfiles are usually created in) + """ + import tempfile + return py.path.local(tempfile.gettempdir()) + + @classmethod + def mkdtemp(cls, rootdir=None): + """ return a Path object pointing to a fresh new temporary directory + (which we created ourself). + """ + import tempfile + if rootdir is None: + rootdir = cls.get_temproot() + return cls(py.error.checked_call(tempfile.mkdtemp, dir=str(rootdir))) + + def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3, + lock_timeout=172800): # two days + """ return unique directory with a number greater than the current + maximum one. The number is assumed to start directly after prefix. + if keep is true directories with a number less than (maxnum-keep) + will be removed. If .lock files are used (lock_timeout non-zero), + algorithm is multi-process safe. + """ + if rootdir is None: + rootdir = cls.get_temproot() + + nprefix = prefix.lower() + def parse_num(path): + """ parse the number out of a path (if it matches the prefix) """ + nbasename = path.basename.lower() + if nbasename.startswith(nprefix): + try: + return int(nbasename[len(nprefix):]) + except ValueError: + pass + + def create_lockfile(path): + """ exclusively create lockfile. Throws when failed """ + mypid = os.getpid() + lockfile = path.join('.lock') + if hasattr(lockfile, 'mksymlinkto'): + lockfile.mksymlinkto(str(mypid)) + else: + fd = py.error.checked_call(os.open, str(lockfile), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644) + with os.fdopen(fd, 'w') as f: + f.write(str(mypid)) + return lockfile + + def atexit_remove_lockfile(lockfile): + """ ensure lockfile is removed at process exit """ + mypid = os.getpid() + def try_remove_lockfile(): + # in a fork() situation, only the last process should + # remove the .lock, otherwise the other processes run the + # risk of seeing their temporary dir disappear. For now + # we remove the .lock in the parent only (i.e. we assume + # that the children finish before the parent). + if os.getpid() != mypid: + return + try: + lockfile.remove() + except py.error.Error: + pass + atexit.register(try_remove_lockfile) + + # compute the maximum number currently in use with the prefix + lastmax = None + while True: + maxnum = -1 + for path in rootdir.listdir(): + num = parse_num(path) + if num is not None: + maxnum = max(maxnum, num) + + # make the new directory + try: + udir = rootdir.mkdir(prefix + str(maxnum+1)) + if lock_timeout: + lockfile = create_lockfile(udir) + atexit_remove_lockfile(lockfile) + except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY): + # race condition (1): another thread/process created the dir + # in the meantime - try again + # race condition (2): another thread/process spuriously acquired + # lock treating empty directory as candidate + # for removal - try again + # race condition (3): another thread/process tried to create the lock at + # the same time (happened in Python 3.3 on Windows) + # https://ci.appveyor.com/project/pytestbot/py/build/1.0.21/job/ffi85j4c0lqwsfwa + if lastmax == maxnum: + raise + lastmax = maxnum + continue + break + + def get_mtime(path): + """ read file modification time """ + try: + return path.lstat().mtime + except py.error.Error: + pass + + garbage_prefix = prefix + 'garbage-' + + def is_garbage(path): + """ check if path denotes directory scheduled for removal """ + bn = path.basename + return bn.startswith(garbage_prefix) + + # prune old directories + udir_time = get_mtime(udir) + if keep and udir_time: + for path in rootdir.listdir(): + num = parse_num(path) + if num is not None and num <= (maxnum - keep): + try: + # try acquiring lock to remove directory as exclusive user + if lock_timeout: + create_lockfile(path) + except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY): + path_time = get_mtime(path) + if not path_time: + # assume directory doesn't exist now + continue + if abs(udir_time - path_time) < lock_timeout: + # assume directory with lockfile exists + # and lock timeout hasn't expired yet + continue + + # path dir locked for exclusive use + # and scheduled for removal to avoid another thread/process + # treating it as a new directory or removal candidate + garbage_path = rootdir.join(garbage_prefix + str(uuid.uuid4())) + try: + path.rename(garbage_path) + garbage_path.remove(rec=1) + except KeyboardInterrupt: + raise + except: # this might be py.error.Error, WindowsError ... + pass + if is_garbage(path): + try: + path.remove(rec=1) + except KeyboardInterrupt: + raise + except: # this might be py.error.Error, WindowsError ... + pass + + # make link... + try: + username = os.environ['USER'] #linux, et al + except KeyError: + try: + username = os.environ['USERNAME'] #windows + except KeyError: + username = 'current' + + src = str(udir) + dest = src[:src.rfind('-')] + '-' + username + try: + os.unlink(dest) + except OSError: + pass + try: + os.symlink(src, dest) + except (OSError, AttributeError, NotImplementedError): + pass + + return udir + make_numbered_dir = classmethod(make_numbered_dir) + + +def copymode(src, dest): + """ copy permission from src to dst. """ + import shutil + shutil.copymode(src, dest) + + +def copystat(src, dest): + """ copy permission, last modification time, + last access time, and flags from src to dst.""" + import shutil + shutil.copystat(str(src), str(dest)) + + +def copychunked(src, dest): + chunksize = 524288 # half a meg of bytes + fsrc = src.open('rb') + try: + fdest = dest.open('wb') + try: + while 1: + buf = fsrc.read(chunksize) + if not buf: + break + fdest.write(buf) + finally: + fdest.close() + finally: + fsrc.close() + + +def isimportable(name): + if name and (name[0].isalpha() or name[0] == '_'): + name = name.replace("_", '') + return not name or name.isalnum() diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/svnurl.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/svnurl.py new file mode 100644 index 00000000..6589a71d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/svnurl.py @@ -0,0 +1,380 @@ +""" +module defining a subversion path object based on the external +command 'svn'. This modules aims to work with svn 1.3 and higher +but might also interact well with earlier versions. +""" + +import os, sys, time, re +import py +from py import path, process +from py._path import common +from py._path import svnwc as svncommon +from py._path.cacheutil import BuildcostAccessCache, AgingCache + +DEBUG=False + +class SvnCommandPath(svncommon.SvnPathBase): + """ path implementation that offers access to (possibly remote) subversion + repositories. """ + + _lsrevcache = BuildcostAccessCache(maxentries=128) + _lsnorevcache = AgingCache(maxentries=1000, maxseconds=60.0) + + def __new__(cls, path, rev=None, auth=None): + self = object.__new__(cls) + if isinstance(path, cls): + rev = path.rev + auth = path.auth + path = path.strpath + svncommon.checkbadchars(path) + path = path.rstrip('/') + self.strpath = path + self.rev = rev + self.auth = auth + return self + + def __repr__(self): + if self.rev == -1: + return 'svnurl(%r)' % self.strpath + else: + return 'svnurl(%r, %r)' % (self.strpath, self.rev) + + def _svnwithrev(self, cmd, *args): + """ execute an svn command, append our own url and revision """ + if self.rev is None: + return self._svnwrite(cmd, *args) + else: + args = ['-r', self.rev] + list(args) + return self._svnwrite(cmd, *args) + + def _svnwrite(self, cmd, *args): + """ execute an svn command, append our own url """ + l = ['svn %s' % cmd] + args = ['"%s"' % self._escape(item) for item in args] + l.extend(args) + l.append('"%s"' % self._encodedurl()) + # fixing the locale because we can't otherwise parse + string = " ".join(l) + if DEBUG: + print("execing %s" % string) + out = self._svncmdexecauth(string) + return out + + def _svncmdexecauth(self, cmd): + """ execute an svn command 'as is' """ + cmd = svncommon.fixlocale() + cmd + if self.auth is not None: + cmd += ' ' + self.auth.makecmdoptions() + return self._cmdexec(cmd) + + def _cmdexec(self, cmd): + try: + out = process.cmdexec(cmd) + except py.process.cmdexec.Error: + e = sys.exc_info()[1] + if (e.err.find('File Exists') != -1 or + e.err.find('File already exists') != -1): + raise py.error.EEXIST(self) + raise + return out + + def _svnpopenauth(self, cmd): + """ execute an svn command, return a pipe for reading stdin """ + cmd = svncommon.fixlocale() + cmd + if self.auth is not None: + cmd += ' ' + self.auth.makecmdoptions() + return self._popen(cmd) + + def _popen(self, cmd): + return os.popen(cmd) + + def _encodedurl(self): + return self._escape(self.strpath) + + def _norev_delentry(self, path): + auth = self.auth and self.auth.makecmdoptions() or None + self._lsnorevcache.delentry((str(path), auth)) + + def open(self, mode='r'): + """ return an opened file with the given mode. """ + if mode not in ("r", "rU",): + raise ValueError("mode %r not supported" % (mode,)) + assert self.check(file=1) # svn cat returns an empty file otherwise + if self.rev is None: + return self._svnpopenauth('svn cat "%s"' % ( + self._escape(self.strpath), )) + else: + return self._svnpopenauth('svn cat -r %s "%s"' % ( + self.rev, self._escape(self.strpath))) + + def dirpath(self, *args, **kwargs): + """ return the directory path of the current path joined + with any given path arguments. + """ + l = self.strpath.split(self.sep) + if len(l) < 4: + raise py.error.EINVAL(self, "base is not valid") + elif len(l) == 4: + return self.join(*args, **kwargs) + else: + return self.new(basename='').join(*args, **kwargs) + + # modifying methods (cache must be invalidated) + def mkdir(self, *args, **kwargs): + """ create & return the directory joined with args. + pass a 'msg' keyword argument to set the commit message. + """ + commit_msg = kwargs.get('msg', "mkdir by py lib invocation") + createpath = self.join(*args) + createpath._svnwrite('mkdir', '-m', commit_msg) + self._norev_delentry(createpath.dirpath()) + return createpath + + def copy(self, target, msg='copied by py lib invocation'): + """ copy path to target with checkin message msg.""" + if getattr(target, 'rev', None) is not None: + raise py.error.EINVAL(target, "revisions are immutable") + self._svncmdexecauth('svn copy -m "%s" "%s" "%s"' %(msg, + self._escape(self), self._escape(target))) + self._norev_delentry(target.dirpath()) + + def rename(self, target, msg="renamed by py lib invocation"): + """ rename this path to target with checkin message msg. """ + if getattr(self, 'rev', None) is not None: + raise py.error.EINVAL(self, "revisions are immutable") + self._svncmdexecauth('svn move -m "%s" --force "%s" "%s"' %( + msg, self._escape(self), self._escape(target))) + self._norev_delentry(self.dirpath()) + self._norev_delentry(self) + + def remove(self, rec=1, msg='removed by py lib invocation'): + """ remove a file or directory (or a directory tree if rec=1) with +checkin message msg.""" + if self.rev is not None: + raise py.error.EINVAL(self, "revisions are immutable") + self._svncmdexecauth('svn rm -m "%s" "%s"' %(msg, self._escape(self))) + self._norev_delentry(self.dirpath()) + + def export(self, topath): + """ export to a local path + + topath should not exist prior to calling this, returns a + py.path.local instance + """ + topath = py.path.local(topath) + args = ['"%s"' % (self._escape(self),), + '"%s"' % (self._escape(topath),)] + if self.rev is not None: + args = ['-r', str(self.rev)] + args + self._svncmdexecauth('svn export %s' % (' '.join(args),)) + return topath + + def ensure(self, *args, **kwargs): + """ ensure that an args-joined path exists (by default as + a file). If you specify a keyword argument 'dir=True' + then the path is forced to be a directory path. + """ + if getattr(self, 'rev', None) is not None: + raise py.error.EINVAL(self, "revisions are immutable") + target = self.join(*args) + dir = kwargs.get('dir', 0) + for x in target.parts(reverse=True): + if x.check(): + break + else: + raise py.error.ENOENT(target, "has not any valid base!") + if x == target: + if not x.check(dir=dir): + raise dir and py.error.ENOTDIR(x) or py.error.EISDIR(x) + return x + tocreate = target.relto(x) + basename = tocreate.split(self.sep, 1)[0] + tempdir = py.path.local.mkdtemp() + try: + tempdir.ensure(tocreate, dir=dir) + cmd = 'svn import -m "%s" "%s" "%s"' % ( + "ensure %s" % self._escape(tocreate), + self._escape(tempdir.join(basename)), + x.join(basename)._encodedurl()) + self._svncmdexecauth(cmd) + self._norev_delentry(x) + finally: + tempdir.remove() + return target + + # end of modifying methods + def _propget(self, name): + res = self._svnwithrev('propget', name) + return res[:-1] # strip trailing newline + + def _proplist(self): + res = self._svnwithrev('proplist') + lines = res.split('\n') + lines = [x.strip() for x in lines[1:]] + return svncommon.PropListDict(self, lines) + + def info(self): + """ return an Info structure with svn-provided information. """ + parent = self.dirpath() + nameinfo_seq = parent._listdir_nameinfo() + bn = self.basename + for name, info in nameinfo_seq: + if name == bn: + return info + raise py.error.ENOENT(self) + + + def _listdir_nameinfo(self): + """ return sequence of name-info directory entries of self """ + def builder(): + try: + res = self._svnwithrev('ls', '-v') + except process.cmdexec.Error: + e = sys.exc_info()[1] + if e.err.find('non-existent in that revision') != -1: + raise py.error.ENOENT(self, e.err) + elif e.err.find("E200009:") != -1: + raise py.error.ENOENT(self, e.err) + elif e.err.find('File not found') != -1: + raise py.error.ENOENT(self, e.err) + elif e.err.find('not part of a repository')!=-1: + raise py.error.ENOENT(self, e.err) + elif e.err.find('Unable to open')!=-1: + raise py.error.ENOENT(self, e.err) + elif e.err.lower().find('method not allowed')!=-1: + raise py.error.EACCES(self, e.err) + raise py.error.Error(e.err) + lines = res.split('\n') + nameinfo_seq = [] + for lsline in lines: + if lsline: + info = InfoSvnCommand(lsline) + if info._name != '.': # svn 1.5 produces '.' dirs, + nameinfo_seq.append((info._name, info)) + nameinfo_seq.sort() + return nameinfo_seq + auth = self.auth and self.auth.makecmdoptions() or None + if self.rev is not None: + return self._lsrevcache.getorbuild((self.strpath, self.rev, auth), + builder) + else: + return self._lsnorevcache.getorbuild((self.strpath, auth), + builder) + + def listdir(self, fil=None, sort=None): + """ list directory contents, possibly filter by the given fil func + and possibly sorted. + """ + if isinstance(fil, str): + fil = common.FNMatcher(fil) + nameinfo_seq = self._listdir_nameinfo() + if len(nameinfo_seq) == 1: + name, info = nameinfo_seq[0] + if name == self.basename and info.kind == 'file': + #if not self.check(dir=1): + raise py.error.ENOTDIR(self) + paths = [self.join(name) for (name, info) in nameinfo_seq] + if fil: + paths = [x for x in paths if fil(x)] + self._sortlist(paths, sort) + return paths + + + def log(self, rev_start=None, rev_end=1, verbose=False): + """ return a list of LogEntry instances for this path. +rev_start is the starting revision (defaulting to the first one). +rev_end is the last revision (defaulting to HEAD). +if verbose is True, then the LogEntry instances also know which files changed. +""" + assert self.check() #make it simpler for the pipe + rev_start = rev_start is None and "HEAD" or rev_start + rev_end = rev_end is None and "HEAD" or rev_end + + if rev_start == "HEAD" and rev_end == 1: + rev_opt = "" + else: + rev_opt = "-r %s:%s" % (rev_start, rev_end) + verbose_opt = verbose and "-v" or "" + xmlpipe = self._svnpopenauth('svn log --xml %s %s "%s"' % + (rev_opt, verbose_opt, self.strpath)) + from xml.dom import minidom + tree = minidom.parse(xmlpipe) + result = [] + for logentry in filter(None, tree.firstChild.childNodes): + if logentry.nodeType == logentry.ELEMENT_NODE: + result.append(svncommon.LogEntry(logentry)) + return result + +#01234567890123456789012345678901234567890123467 +# 2256 hpk 165 Nov 24 17:55 __init__.py +# XXX spotted by Guido, SVN 1.3.0 has different aligning, breaks the code!!! +# 1312 johnny 1627 May 05 14:32 test_decorators.py +# +class InfoSvnCommand: + # the '0?' part in the middle is an indication of whether the resource is + # locked, see 'svn help ls' + lspattern = re.compile( + r'^ *(?P<rev>\d+) +(?P<author>.+?) +(0? *(?P<size>\d+))? ' + r'*(?P<date>\w+ +\d{2} +[\d:]+) +(?P<file>.*)$') + def __init__(self, line): + # this is a typical line from 'svn ls http://...' + #_ 1127 jum 0 Jul 13 15:28 branch/ + match = self.lspattern.match(line) + data = match.groupdict() + self._name = data['file'] + if self._name[-1] == '/': + self._name = self._name[:-1] + self.kind = 'dir' + else: + self.kind = 'file' + #self.has_props = l.pop(0) == 'P' + self.created_rev = int(data['rev']) + self.last_author = data['author'] + self.size = data['size'] and int(data['size']) or 0 + self.mtime = parse_time_with_missing_year(data['date']) + self.time = self.mtime * 1000000 + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + +#____________________________________________________ +# +# helper functions +#____________________________________________________ +def parse_time_with_missing_year(timestr): + """ analyze the time part from a single line of "svn ls -v" + the svn output doesn't show the year makes the 'timestr' + ambigous. + """ + import calendar + t_now = time.gmtime() + + tparts = timestr.split() + month = time.strptime(tparts.pop(0), '%b')[1] + day = time.strptime(tparts.pop(0), '%d')[2] + last = tparts.pop(0) # year or hour:minute + try: + if ":" in last: + raise ValueError() + year = time.strptime(last, '%Y')[0] + hour = minute = 0 + except ValueError: + hour, minute = time.strptime(last, '%H:%M')[3:5] + year = t_now[0] + + t_result = (year, month, day, hour, minute, 0,0,0,0) + if t_result > t_now: + year -= 1 + t_result = (year, month, day, hour, minute, 0,0,0,0) + return calendar.timegm(t_result) + +class PathEntry: + def __init__(self, ppart): + self.strpath = ppart.firstChild.nodeValue.encode('UTF-8') + self.action = ppart.getAttribute('action').encode('UTF-8') + if self.action == 'A': + self.copyfrom_path = ppart.getAttribute('copyfrom-path').encode('UTF-8') + if self.copyfrom_path: + self.copyfrom_rev = int(ppart.getAttribute('copyfrom-rev')) + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_path/svnwc.py b/dbdpy-env/lib/python3.9/site-packages/py/_path/svnwc.py new file mode 100644 index 00000000..b5b9d8d5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_path/svnwc.py @@ -0,0 +1,1240 @@ +""" +svn-Command based Implementation of a Subversion WorkingCopy Path. + + SvnWCCommandPath is the main class. + +""" + +import os, sys, time, re, calendar +import py +import subprocess +from py._path import common + +#----------------------------------------------------------- +# Caching latest repository revision and repo-paths +# (getting them is slow with the current implementations) +# +# XXX make mt-safe +#----------------------------------------------------------- + +class cache: + proplist = {} + info = {} + entries = {} + prop = {} + +class RepoEntry: + def __init__(self, url, rev, timestamp): + self.url = url + self.rev = rev + self.timestamp = timestamp + + def __str__(self): + return "repo: %s;%s %s" %(self.url, self.rev, self.timestamp) + +class RepoCache: + """ The Repocache manages discovered repository paths + and their revisions. If inside a timeout the cache + will even return the revision of the root. + """ + timeout = 20 # seconds after which we forget that we know the last revision + + def __init__(self): + self.repos = [] + + def clear(self): + self.repos = [] + + def put(self, url, rev, timestamp=None): + if rev is None: + return + if timestamp is None: + timestamp = time.time() + + for entry in self.repos: + if url == entry.url: + entry.timestamp = timestamp + entry.rev = rev + #print "set repo", entry + break + else: + entry = RepoEntry(url, rev, timestamp) + self.repos.append(entry) + #print "appended repo", entry + + def get(self, url): + now = time.time() + for entry in self.repos: + if url.startswith(entry.url): + if now < entry.timestamp + self.timeout: + #print "returning immediate Etrny", entry + return entry.url, entry.rev + return entry.url, -1 + return url, -1 + +repositories = RepoCache() + + +# svn support code + +ALLOWED_CHARS = "_ -/\\=$.~+%" #add characters as necessary when tested +if sys.platform == "win32": + ALLOWED_CHARS += ":" +ALLOWED_CHARS_HOST = ALLOWED_CHARS + '@:' + +def _getsvnversion(ver=[]): + try: + return ver[0] + except IndexError: + v = py.process.cmdexec("svn -q --version") + v.strip() + v = '.'.join(v.split('.')[:2]) + ver.append(v) + return v + +def _escape_helper(text): + text = str(text) + if sys.platform != 'win32': + text = str(text).replace('$', '\\$') + return text + +def _check_for_bad_chars(text, allowed_chars=ALLOWED_CHARS): + for c in str(text): + if c.isalnum(): + continue + if c in allowed_chars: + continue + return True + return False + +def checkbadchars(url): + # (hpk) not quite sure about the exact purpose, guido w.? + proto, uri = url.split("://", 1) + if proto != "file": + host, uripath = uri.split('/', 1) + # only check for bad chars in the non-protocol parts + if (_check_for_bad_chars(host, ALLOWED_CHARS_HOST) \ + or _check_for_bad_chars(uripath, ALLOWED_CHARS)): + raise ValueError("bad char in %r" % (url, )) + + +#_______________________________________________________________ + +class SvnPathBase(common.PathBase): + """ Base implementation for SvnPath implementations. """ + sep = '/' + + def _geturl(self): + return self.strpath + url = property(_geturl, None, None, "url of this svn-path.") + + def __str__(self): + """ return a string representation (including rev-number) """ + return self.strpath + + def __hash__(self): + return hash(self.strpath) + + def new(self, **kw): + """ create a modified version of this path. A 'rev' argument + indicates a new revision. + the following keyword arguments modify various path parts:: + + http://host.com/repo/path/file.ext + |-----------------------| dirname + |------| basename + |--| purebasename + |--| ext + """ + obj = object.__new__(self.__class__) + obj.rev = kw.get('rev', self.rev) + obj.auth = kw.get('auth', self.auth) + dirname, basename, purebasename, ext = self._getbyspec( + "dirname,basename,purebasename,ext") + if 'basename' in kw: + if 'purebasename' in kw or 'ext' in kw: + raise ValueError("invalid specification %r" % kw) + else: + pb = kw.setdefault('purebasename', purebasename) + ext = kw.setdefault('ext', ext) + if ext and not ext.startswith('.'): + ext = '.' + ext + kw['basename'] = pb + ext + + kw.setdefault('dirname', dirname) + kw.setdefault('sep', self.sep) + if kw['basename']: + obj.strpath = "%(dirname)s%(sep)s%(basename)s" % kw + else: + obj.strpath = "%(dirname)s" % kw + return obj + + def _getbyspec(self, spec): + """ get specified parts of the path. 'arg' is a string + with comma separated path parts. The parts are returned + in exactly the order of the specification. + + you may specify the following parts: + + http://host.com/repo/path/file.ext + |-----------------------| dirname + |------| basename + |--| purebasename + |--| ext + """ + res = [] + parts = self.strpath.split(self.sep) + for name in spec.split(','): + name = name.strip() + if name == 'dirname': + res.append(self.sep.join(parts[:-1])) + elif name == 'basename': + res.append(parts[-1]) + else: + basename = parts[-1] + i = basename.rfind('.') + if i == -1: + purebasename, ext = basename, '' + else: + purebasename, ext = basename[:i], basename[i:] + if name == 'purebasename': + res.append(purebasename) + elif name == 'ext': + res.append(ext) + else: + raise NameError("Don't know part %r" % name) + return res + + def __eq__(self, other): + """ return true if path and rev attributes each match """ + return (str(self) == str(other) and + (self.rev == other.rev or self.rev == other.rev)) + + def __ne__(self, other): + return not self == other + + def join(self, *args): + """ return a new Path (with the same revision) which is composed + of the self Path followed by 'args' path components. + """ + if not args: + return self + + args = tuple([arg.strip(self.sep) for arg in args]) + parts = (self.strpath, ) + args + newpath = self.__class__(self.sep.join(parts), self.rev, self.auth) + return newpath + + def propget(self, name): + """ return the content of the given property. """ + value = self._propget(name) + return value + + def proplist(self): + """ list all property names. """ + content = self._proplist() + return content + + def size(self): + """ Return the size of the file content of the Path. """ + return self.info().size + + def mtime(self): + """ Return the last modification time of the file. """ + return self.info().mtime + + # shared help methods + + def _escape(self, cmd): + return _escape_helper(cmd) + + + #def _childmaxrev(self): + # """ return maximum revision number of childs (or self.rev if no childs) """ + # rev = self.rev + # for name, info in self._listdir_nameinfo(): + # rev = max(rev, info.created_rev) + # return rev + + #def _getlatestrevision(self): + # """ return latest repo-revision for this path. """ + # url = self.strpath + # path = self.__class__(url, None) + # + # # we need a long walk to find the root-repo and revision + # while 1: + # try: + # rev = max(rev, path._childmaxrev()) + # previous = path + # path = path.dirpath() + # except (IOError, process.cmdexec.Error): + # break + # if rev is None: + # raise IOError, "could not determine newest repo revision for %s" % self + # return rev + + class Checkers(common.Checkers): + def dir(self): + try: + return self.path.info().kind == 'dir' + except py.error.Error: + return self._listdirworks() + + def _listdirworks(self): + try: + self.path.listdir() + except py.error.ENOENT: + return False + else: + return True + + def file(self): + try: + return self.path.info().kind == 'file' + except py.error.ENOENT: + return False + + def exists(self): + try: + return self.path.info() + except py.error.ENOENT: + return self._listdirworks() + +def parse_apr_time(timestr): + i = timestr.rfind('.') + if i == -1: + raise ValueError("could not parse %s" % timestr) + timestr = timestr[:i] + parsedtime = time.strptime(timestr, "%Y-%m-%dT%H:%M:%S") + return time.mktime(parsedtime) + +class PropListDict(dict): + """ a Dictionary which fetches values (InfoSvnCommand instances) lazily""" + def __init__(self, path, keynames): + dict.__init__(self, [(x, None) for x in keynames]) + self.path = path + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + if value is None: + value = self.path.propget(key) + dict.__setitem__(self, key, value) + return value + +def fixlocale(): + if sys.platform != 'win32': + return 'LC_ALL=C ' + return '' + +# some nasty chunk of code to solve path and url conversion and quoting issues +ILLEGAL_CHARS = '* | \\ / : < > ? \t \n \x0b \x0c \r'.split(' ') +if os.sep in ILLEGAL_CHARS: + ILLEGAL_CHARS.remove(os.sep) +ISWINDOWS = sys.platform == 'win32' +_reg_allow_disk = re.compile(r'^([a-z]\:\\)?[^:]+$', re.I) +def _check_path(path): + illegal = ILLEGAL_CHARS[:] + sp = path.strpath + if ISWINDOWS: + illegal.remove(':') + if not _reg_allow_disk.match(sp): + raise ValueError('path may not contain a colon (:)') + for char in sp: + if char not in string.printable or char in illegal: + raise ValueError('illegal character %r in path' % (char,)) + +def path_to_fspath(path, addat=True): + _check_path(path) + sp = path.strpath + if addat and path.rev != -1: + sp = '%s@%s' % (sp, path.rev) + elif addat: + sp = '%s@HEAD' % (sp,) + return sp + +def url_from_path(path): + fspath = path_to_fspath(path, False) + from urllib import quote + if ISWINDOWS: + match = _reg_allow_disk.match(fspath) + fspath = fspath.replace('\\', '/') + if match.group(1): + fspath = '/%s%s' % (match.group(1).replace('\\', '/'), + quote(fspath[len(match.group(1)):])) + else: + fspath = quote(fspath) + else: + fspath = quote(fspath) + if path.rev != -1: + fspath = '%s@%s' % (fspath, path.rev) + else: + fspath = '%s@HEAD' % (fspath,) + return 'file://%s' % (fspath,) + +class SvnAuth(object): + """ container for auth information for Subversion """ + def __init__(self, username, password, cache_auth=True, interactive=True): + self.username = username + self.password = password + self.cache_auth = cache_auth + self.interactive = interactive + + def makecmdoptions(self): + uname = self.username.replace('"', '\\"') + passwd = self.password.replace('"', '\\"') + ret = [] + if uname: + ret.append('--username="%s"' % (uname,)) + if passwd: + ret.append('--password="%s"' % (passwd,)) + if not self.cache_auth: + ret.append('--no-auth-cache') + if not self.interactive: + ret.append('--non-interactive') + return ' '.join(ret) + + def __str__(self): + return "<SvnAuth username=%s ...>" %(self.username,) + +rex_blame = re.compile(r'\s*(\d+)\s+(\S+) (.*)') + +class SvnWCCommandPath(common.PathBase): + """ path implementation offering access/modification to svn working copies. + It has methods similar to the functions in os.path and similar to the + commands of the svn client. + """ + sep = os.sep + + def __new__(cls, wcpath=None, auth=None): + self = object.__new__(cls) + if isinstance(wcpath, cls): + if wcpath.__class__ == cls: + return wcpath + wcpath = wcpath.localpath + if _check_for_bad_chars(str(wcpath), + ALLOWED_CHARS): + raise ValueError("bad char in wcpath %s" % (wcpath, )) + self.localpath = py.path.local(wcpath) + self.auth = auth + return self + + strpath = property(lambda x: str(x.localpath), None, None, "string path") + rev = property(lambda x: x.info(usecache=0).rev, None, None, "revision") + + def __eq__(self, other): + return self.localpath == getattr(other, 'localpath', None) + + def _geturl(self): + if getattr(self, '_url', None) is None: + info = self.info() + self._url = info.url #SvnPath(info.url, info.rev) + assert isinstance(self._url, py.builtin._basestring) + return self._url + + url = property(_geturl, None, None, "url of this WC item") + + def _escape(self, cmd): + return _escape_helper(cmd) + + def dump(self, obj): + """ pickle object into path location""" + return self.localpath.dump(obj) + + def svnurl(self): + """ return current SvnPath for this WC-item. """ + info = self.info() + return py.path.svnurl(info.url) + + def __repr__(self): + return "svnwc(%r)" % (self.strpath) # , self._url) + + def __str__(self): + return str(self.localpath) + + def _makeauthoptions(self): + if self.auth is None: + return '' + return self.auth.makecmdoptions() + + def _authsvn(self, cmd, args=None): + args = args and list(args) or [] + args.append(self._makeauthoptions()) + return self._svn(cmd, *args) + + def _svn(self, cmd, *args): + l = ['svn %s' % cmd] + args = [self._escape(item) for item in args] + l.extend(args) + l.append('"%s"' % self._escape(self.strpath)) + # try fixing the locale because we can't otherwise parse + string = fixlocale() + " ".join(l) + try: + try: + key = 'LC_MESSAGES' + hold = os.environ.get(key) + os.environ[key] = 'C' + out = py.process.cmdexec(string) + finally: + if hold: + os.environ[key] = hold + else: + del os.environ[key] + except py.process.cmdexec.Error: + e = sys.exc_info()[1] + strerr = e.err.lower() + if strerr.find('not found') != -1: + raise py.error.ENOENT(self) + elif strerr.find("E200009:") != -1: + raise py.error.ENOENT(self) + if (strerr.find('file exists') != -1 or + strerr.find('file already exists') != -1 or + strerr.find('w150002:') != -1 or + strerr.find("can't create directory") != -1): + raise py.error.EEXIST(strerr) #self) + raise + return out + + def switch(self, url): + """ switch to given URL. """ + self._authsvn('switch', [url]) + + def checkout(self, url=None, rev=None): + """ checkout from url to local wcpath. """ + args = [] + if url is None: + url = self.url + if rev is None or rev == -1: + if (sys.platform != 'win32' and + _getsvnversion() == '1.3'): + url += "@HEAD" + else: + if _getsvnversion() == '1.3': + url += "@%d" % rev + else: + args.append('-r' + str(rev)) + args.append(url) + self._authsvn('co', args) + + def update(self, rev='HEAD', interactive=True): + """ update working copy item to given revision. (None -> HEAD). """ + opts = ['-r', rev] + if not interactive: + opts.append("--non-interactive") + self._authsvn('up', opts) + + def write(self, content, mode='w'): + """ write content into local filesystem wc. """ + self.localpath.write(content, mode) + + def dirpath(self, *args): + """ return the directory Path of the current Path. """ + return self.__class__(self.localpath.dirpath(*args), auth=self.auth) + + def _ensuredirs(self): + parent = self.dirpath() + if parent.check(dir=0): + parent._ensuredirs() + if self.check(dir=0): + self.mkdir() + return self + + def ensure(self, *args, **kwargs): + """ ensure that an args-joined path exists (by default as + a file). if you specify a keyword argument 'directory=True' + then the path is forced to be a directory path. + """ + p = self.join(*args) + if p.check(): + if p.check(versioned=False): + p.add() + return p + if kwargs.get('dir', 0): + return p._ensuredirs() + parent = p.dirpath() + parent._ensuredirs() + p.write("") + p.add() + return p + + def mkdir(self, *args): + """ create & return the directory joined with args. """ + if args: + return self.join(*args).mkdir() + else: + self._svn('mkdir') + return self + + def add(self): + """ add ourself to svn """ + self._svn('add') + + def remove(self, rec=1, force=1): + """ remove a file or a directory tree. 'rec'ursive is + ignored and considered always true (because of + underlying svn semantics. + """ + assert rec, "svn cannot remove non-recursively" + if not self.check(versioned=True): + # not added to svn (anymore?), just remove + py.path.local(self).remove() + return + flags = [] + if force: + flags.append('--force') + self._svn('remove', *flags) + + def copy(self, target): + """ copy path to target.""" + py.process.cmdexec("svn copy %s %s" %(str(self), str(target))) + + def rename(self, target): + """ rename this path to target. """ + py.process.cmdexec("svn move --force %s %s" %(str(self), str(target))) + + def lock(self): + """ set a lock (exclusive) on the resource """ + out = self._authsvn('lock').strip() + if not out: + # warning or error, raise exception + raise ValueError("unknown error in svn lock command") + + def unlock(self): + """ unset a previously set lock """ + out = self._authsvn('unlock').strip() + if out.startswith('svn:'): + # warning or error, raise exception + raise Exception(out[4:]) + + def cleanup(self): + """ remove any locks from the resource """ + # XXX should be fixed properly!!! + try: + self.unlock() + except: + pass + + def status(self, updates=0, rec=0, externals=0): + """ return (collective) Status object for this file. """ + # http://svnbook.red-bean.com/book.html#svn-ch-3-sect-4.3.1 + # 2201 2192 jum test + # XXX + if externals: + raise ValueError("XXX cannot perform status() " + "on external items yet") + else: + #1.2 supports: externals = '--ignore-externals' + externals = '' + if rec: + rec= '' + else: + rec = '--non-recursive' + + # XXX does not work on all subversion versions + #if not externals: + # externals = '--ignore-externals' + + if updates: + updates = '-u' + else: + updates = '' + + try: + cmd = 'status -v --xml --no-ignore %s %s %s' % ( + updates, rec, externals) + out = self._authsvn(cmd) + except py.process.cmdexec.Error: + cmd = 'status -v --no-ignore %s %s %s' % ( + updates, rec, externals) + out = self._authsvn(cmd) + rootstatus = WCStatus(self).fromstring(out, self) + else: + rootstatus = XMLWCStatus(self).fromstring(out, self) + return rootstatus + + def diff(self, rev=None): + """ return a diff of the current path against revision rev (defaulting + to the last one). + """ + args = [] + if rev is not None: + args.append("-r %d" % rev) + out = self._authsvn('diff', args) + return out + + def blame(self): + """ return a list of tuples of three elements: + (revision, commiter, line) + """ + out = self._svn('blame') + result = [] + blamelines = out.splitlines() + reallines = py.path.svnurl(self.url).readlines() + for i, (blameline, line) in enumerate( + zip(blamelines, reallines)): + m = rex_blame.match(blameline) + if not m: + raise ValueError("output line %r of svn blame does not match " + "expected format" % (line, )) + rev, name, _ = m.groups() + result.append((int(rev), name, line)) + return result + + _rex_commit = re.compile(r'.*Committed revision (\d+)\.$', re.DOTALL) + def commit(self, msg='', rec=1): + """ commit with support for non-recursive commits """ + # XXX i guess escaping should be done better here?!? + cmd = 'commit -m "%s" --force-log' % (msg.replace('"', '\\"'),) + if not rec: + cmd += ' -N' + out = self._authsvn(cmd) + try: + del cache.info[self] + except KeyError: + pass + if out: + m = self._rex_commit.match(out) + return int(m.group(1)) + + def propset(self, name, value, *args): + """ set property name to value on this path. """ + d = py.path.local.mkdtemp() + try: + p = d.join('value') + p.write(value) + self._svn('propset', name, '--file', str(p), *args) + finally: + d.remove() + + def propget(self, name): + """ get property name on this path. """ + res = self._svn('propget', name) + return res[:-1] # strip trailing newline + + def propdel(self, name): + """ delete property name on this path. """ + res = self._svn('propdel', name) + return res[:-1] # strip trailing newline + + def proplist(self, rec=0): + """ return a mapping of property names to property values. +If rec is True, then return a dictionary mapping sub-paths to such mappings. +""" + if rec: + res = self._svn('proplist -R') + return make_recursive_propdict(self, res) + else: + res = self._svn('proplist') + lines = res.split('\n') + lines = [x.strip() for x in lines[1:]] + return PropListDict(self, lines) + + def revert(self, rec=0): + """ revert the local changes of this path. if rec is True, do so +recursively. """ + if rec: + result = self._svn('revert -R') + else: + result = self._svn('revert') + return result + + def new(self, **kw): + """ create a modified version of this path. A 'rev' argument + indicates a new revision. + the following keyword arguments modify various path parts: + + http://host.com/repo/path/file.ext + |-----------------------| dirname + |------| basename + |--| purebasename + |--| ext + """ + if kw: + localpath = self.localpath.new(**kw) + else: + localpath = self.localpath + return self.__class__(localpath, auth=self.auth) + + def join(self, *args, **kwargs): + """ return a new Path (with the same revision) which is composed + of the self Path followed by 'args' path components. + """ + if not args: + return self + localpath = self.localpath.join(*args, **kwargs) + return self.__class__(localpath, auth=self.auth) + + def info(self, usecache=1): + """ return an Info structure with svn-provided information. """ + info = usecache and cache.info.get(self) + if not info: + try: + output = self._svn('info') + except py.process.cmdexec.Error: + e = sys.exc_info()[1] + if e.err.find('Path is not a working copy directory') != -1: + raise py.error.ENOENT(self, e.err) + elif e.err.find("is not under version control") != -1: + raise py.error.ENOENT(self, e.err) + raise + # XXX SVN 1.3 has output on stderr instead of stdout (while it does + # return 0!), so a bit nasty, but we assume no output is output + # to stderr... + if (output.strip() == '' or + output.lower().find('not a versioned resource') != -1): + raise py.error.ENOENT(self, output) + info = InfoSvnWCCommand(output) + + # Can't reliably compare on Windows without access to win32api + if sys.platform != 'win32': + if info.path != self.localpath: + raise py.error.ENOENT(self, "not a versioned resource:" + + " %s != %s" % (info.path, self.localpath)) + cache.info[self] = info + return info + + def listdir(self, fil=None, sort=None): + """ return a sequence of Paths. + + listdir will return either a tuple or a list of paths + depending on implementation choices. + """ + if isinstance(fil, str): + fil = common.FNMatcher(fil) + # XXX unify argument naming with LocalPath.listdir + def notsvn(path): + return path.basename != '.svn' + + paths = [] + for localpath in self.localpath.listdir(notsvn): + p = self.__class__(localpath, auth=self.auth) + if notsvn(p) and (not fil or fil(p)): + paths.append(p) + self._sortlist(paths, sort) + return paths + + def open(self, mode='r'): + """ return an opened file with the given mode. """ + return open(self.strpath, mode) + + def _getbyspec(self, spec): + return self.localpath._getbyspec(spec) + + class Checkers(py.path.local.Checkers): + def __init__(self, path): + self.svnwcpath = path + self.path = path.localpath + def versioned(self): + try: + s = self.svnwcpath.info() + except (py.error.ENOENT, py.error.EEXIST): + return False + except py.process.cmdexec.Error: + e = sys.exc_info()[1] + if e.err.find('is not a working copy')!=-1: + return False + if e.err.lower().find('not a versioned resource') != -1: + return False + raise + else: + return True + + def log(self, rev_start=None, rev_end=1, verbose=False): + """ return a list of LogEntry instances for this path. +rev_start is the starting revision (defaulting to the first one). +rev_end is the last revision (defaulting to HEAD). +if verbose is True, then the LogEntry instances also know which files changed. +""" + assert self.check() # make it simpler for the pipe + rev_start = rev_start is None and "HEAD" or rev_start + rev_end = rev_end is None and "HEAD" or rev_end + if rev_start == "HEAD" and rev_end == 1: + rev_opt = "" + else: + rev_opt = "-r %s:%s" % (rev_start, rev_end) + verbose_opt = verbose and "-v" or "" + locale_env = fixlocale() + # some blather on stderr + auth_opt = self._makeauthoptions() + #stdin, stdout, stderr = os.popen3(locale_env + + # 'svn log --xml %s %s %s "%s"' % ( + # rev_opt, verbose_opt, auth_opt, + # self.strpath)) + cmd = locale_env + 'svn log --xml %s %s %s "%s"' % ( + rev_opt, verbose_opt, auth_opt, self.strpath) + + popen = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, + ) + stdout, stderr = popen.communicate() + stdout = py.builtin._totext(stdout, sys.getdefaultencoding()) + minidom,ExpatError = importxml() + try: + tree = minidom.parseString(stdout) + except ExpatError: + raise ValueError('no such revision') + result = [] + for logentry in filter(None, tree.firstChild.childNodes): + if logentry.nodeType == logentry.ELEMENT_NODE: + result.append(LogEntry(logentry)) + return result + + def size(self): + """ Return the size of the file content of the Path. """ + return self.info().size + + def mtime(self): + """ Return the last modification time of the file. """ + return self.info().mtime + + def __hash__(self): + return hash((self.strpath, self.__class__, self.auth)) + + +class WCStatus: + attrnames = ('modified','added', 'conflict', 'unchanged', 'external', + 'deleted', 'prop_modified', 'unknown', 'update_available', + 'incomplete', 'kindmismatch', 'ignored', 'locked', 'replaced' + ) + + def __init__(self, wcpath, rev=None, modrev=None, author=None): + self.wcpath = wcpath + self.rev = rev + self.modrev = modrev + self.author = author + + for name in self.attrnames: + setattr(self, name, []) + + def allpath(self, sort=True, **kw): + d = {} + for name in self.attrnames: + if name not in kw or kw[name]: + for path in getattr(self, name): + d[path] = 1 + l = d.keys() + if sort: + l.sort() + return l + + # XXX a bit scary to assume there's always 2 spaces between username and + # path, however with win32 allowing spaces in user names there doesn't + # seem to be a more solid approach :( + _rex_status = re.compile(r'\s+(\d+|-)\s+(\S+)\s+(.+?)\s{2,}(.*)') + + def fromstring(data, rootwcpath, rev=None, modrev=None, author=None): + """ return a new WCStatus object from data 's' + """ + rootstatus = WCStatus(rootwcpath, rev, modrev, author) + update_rev = None + for line in data.split('\n'): + if not line.strip(): + continue + #print "processing %r" % line + flags, rest = line[:8], line[8:] + # first column + c0,c1,c2,c3,c4,c5,x6,c7 = flags + #if '*' in line: + # print "flags", repr(flags), "rest", repr(rest) + + if c0 in '?XI': + fn = line.split(None, 1)[1] + if c0 == '?': + wcpath = rootwcpath.join(fn, abs=1) + rootstatus.unknown.append(wcpath) + elif c0 == 'X': + wcpath = rootwcpath.__class__( + rootwcpath.localpath.join(fn, abs=1), + auth=rootwcpath.auth) + rootstatus.external.append(wcpath) + elif c0 == 'I': + wcpath = rootwcpath.join(fn, abs=1) + rootstatus.ignored.append(wcpath) + + continue + + #elif c0 in '~!' or c4 == 'S': + # raise NotImplementedError("received flag %r" % c0) + + m = WCStatus._rex_status.match(rest) + if not m: + if c7 == '*': + fn = rest.strip() + wcpath = rootwcpath.join(fn, abs=1) + rootstatus.update_available.append(wcpath) + continue + if line.lower().find('against revision:')!=-1: + update_rev = int(rest.split(':')[1].strip()) + continue + if line.lower().find('status on external') > -1: + # XXX not sure what to do here... perhaps we want to + # store some state instead of just continuing, as right + # now it makes the top-level external get added twice + # (once as external, once as 'normal' unchanged item) + # because of the way SVN presents external items + continue + # keep trying + raise ValueError("could not parse line %r" % line) + else: + rev, modrev, author, fn = m.groups() + wcpath = rootwcpath.join(fn, abs=1) + #assert wcpath.check() + if c0 == 'M': + assert wcpath.check(file=1), "didn't expect a directory with changed content here" + rootstatus.modified.append(wcpath) + elif c0 == 'A' or c3 == '+' : + rootstatus.added.append(wcpath) + elif c0 == 'D': + rootstatus.deleted.append(wcpath) + elif c0 == 'C': + rootstatus.conflict.append(wcpath) + elif c0 == '~': + rootstatus.kindmismatch.append(wcpath) + elif c0 == '!': + rootstatus.incomplete.append(wcpath) + elif c0 == 'R': + rootstatus.replaced.append(wcpath) + elif not c0.strip(): + rootstatus.unchanged.append(wcpath) + else: + raise NotImplementedError("received flag %r" % c0) + + if c1 == 'M': + rootstatus.prop_modified.append(wcpath) + # XXX do we cover all client versions here? + if c2 == 'L' or c5 == 'K': + rootstatus.locked.append(wcpath) + if c7 == '*': + rootstatus.update_available.append(wcpath) + + if wcpath == rootwcpath: + rootstatus.rev = rev + rootstatus.modrev = modrev + rootstatus.author = author + if update_rev: + rootstatus.update_rev = update_rev + continue + return rootstatus + fromstring = staticmethod(fromstring) + +class XMLWCStatus(WCStatus): + def fromstring(data, rootwcpath, rev=None, modrev=None, author=None): + """ parse 'data' (XML string as outputted by svn st) into a status obj + """ + # XXX for externals, the path is shown twice: once + # with external information, and once with full info as if + # the item was a normal non-external... the current way of + # dealing with this issue is by ignoring it - this does make + # externals appear as external items as well as 'normal', + # unchanged ones in the status object so this is far from ideal + rootstatus = WCStatus(rootwcpath, rev, modrev, author) + update_rev = None + minidom, ExpatError = importxml() + try: + doc = minidom.parseString(data) + except ExpatError: + e = sys.exc_info()[1] + raise ValueError(str(e)) + urevels = doc.getElementsByTagName('against') + if urevels: + rootstatus.update_rev = urevels[-1].getAttribute('revision') + for entryel in doc.getElementsByTagName('entry'): + path = entryel.getAttribute('path') + statusel = entryel.getElementsByTagName('wc-status')[0] + itemstatus = statusel.getAttribute('item') + + if itemstatus == 'unversioned': + wcpath = rootwcpath.join(path, abs=1) + rootstatus.unknown.append(wcpath) + continue + elif itemstatus == 'external': + wcpath = rootwcpath.__class__( + rootwcpath.localpath.join(path, abs=1), + auth=rootwcpath.auth) + rootstatus.external.append(wcpath) + continue + elif itemstatus == 'ignored': + wcpath = rootwcpath.join(path, abs=1) + rootstatus.ignored.append(wcpath) + continue + elif itemstatus == 'incomplete': + wcpath = rootwcpath.join(path, abs=1) + rootstatus.incomplete.append(wcpath) + continue + + rev = statusel.getAttribute('revision') + if itemstatus == 'added' or itemstatus == 'none': + rev = '0' + modrev = '?' + author = '?' + date = '' + elif itemstatus == "replaced": + pass + else: + #print entryel.toxml() + commitel = entryel.getElementsByTagName('commit')[0] + if commitel: + modrev = commitel.getAttribute('revision') + author = '' + author_els = commitel.getElementsByTagName('author') + if author_els: + for c in author_els[0].childNodes: + author += c.nodeValue + date = '' + for c in commitel.getElementsByTagName('date')[0]\ + .childNodes: + date += c.nodeValue + + wcpath = rootwcpath.join(path, abs=1) + + assert itemstatus != 'modified' or wcpath.check(file=1), ( + 'did\'t expect a directory with changed content here') + + itemattrname = { + 'normal': 'unchanged', + 'unversioned': 'unknown', + 'conflicted': 'conflict', + 'none': 'added', + }.get(itemstatus, itemstatus) + + attr = getattr(rootstatus, itemattrname) + attr.append(wcpath) + + propsstatus = statusel.getAttribute('props') + if propsstatus not in ('none', 'normal'): + rootstatus.prop_modified.append(wcpath) + + if wcpath == rootwcpath: + rootstatus.rev = rev + rootstatus.modrev = modrev + rootstatus.author = author + rootstatus.date = date + + # handle repos-status element (remote info) + rstatusels = entryel.getElementsByTagName('repos-status') + if rstatusels: + rstatusel = rstatusels[0] + ritemstatus = rstatusel.getAttribute('item') + if ritemstatus in ('added', 'modified'): + rootstatus.update_available.append(wcpath) + + lockels = entryel.getElementsByTagName('lock') + if len(lockels): + rootstatus.locked.append(wcpath) + + return rootstatus + fromstring = staticmethod(fromstring) + +class InfoSvnWCCommand: + def __init__(self, output): + # Path: test + # URL: http://codespeak.net/svn/std.path/trunk/dist/std.path/test + # Repository UUID: fd0d7bf2-dfb6-0310-8d31-b7ecfe96aada + # Revision: 2151 + # Node Kind: directory + # Schedule: normal + # Last Changed Author: hpk + # Last Changed Rev: 2100 + # Last Changed Date: 2003-10-27 20:43:14 +0100 (Mon, 27 Oct 2003) + # Properties Last Updated: 2003-11-03 14:47:48 +0100 (Mon, 03 Nov 2003) + + d = {} + for line in output.split('\n'): + if not line.strip(): + continue + key, value = line.split(':', 1) + key = key.lower().replace(' ', '') + value = value.strip() + d[key] = value + try: + self.url = d['url'] + except KeyError: + raise ValueError("Not a versioned resource") + #raise ValueError, "Not a versioned resource %r" % path + self.kind = d['nodekind'] == 'directory' and 'dir' or d['nodekind'] + try: + self.rev = int(d['revision']) + except KeyError: + self.rev = None + + self.path = py.path.local(d['path']) + self.size = self.path.size() + if 'lastchangedrev' in d: + self.created_rev = int(d['lastchangedrev']) + if 'lastchangedauthor' in d: + self.last_author = d['lastchangedauthor'] + if 'lastchangeddate' in d: + self.mtime = parse_wcinfotime(d['lastchangeddate']) + self.time = self.mtime * 1000000 + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + +def parse_wcinfotime(timestr): + """ Returns seconds since epoch, UTC. """ + # example: 2003-10-27 20:43:14 +0100 (Mon, 27 Oct 2003) + m = re.match(r'(\d+-\d+-\d+ \d+:\d+:\d+) ([+-]\d+) .*', timestr) + if not m: + raise ValueError("timestring %r does not match" % timestr) + timestr, timezone = m.groups() + # do not handle timezone specially, return value should be UTC + parsedtime = time.strptime(timestr, "%Y-%m-%d %H:%M:%S") + return calendar.timegm(parsedtime) + +def make_recursive_propdict(wcroot, + output, + rex = re.compile("Properties on '(.*)':")): + """ Return a dictionary of path->PropListDict mappings. """ + lines = [x for x in output.split('\n') if x] + pdict = {} + while lines: + line = lines.pop(0) + m = rex.match(line) + if not m: + raise ValueError("could not parse propget-line: %r" % line) + path = m.groups()[0] + wcpath = wcroot.join(path, abs=1) + propnames = [] + while lines and lines[0].startswith(' '): + propname = lines.pop(0).strip() + propnames.append(propname) + assert propnames, "must have found properties!" + pdict[wcpath] = PropListDict(wcpath, propnames) + return pdict + + +def importxml(cache=[]): + if cache: + return cache + from xml.dom import minidom + from xml.parsers.expat import ExpatError + cache.extend([minidom, ExpatError]) + return cache + +class LogEntry: + def __init__(self, logentry): + self.rev = int(logentry.getAttribute('revision')) + for lpart in filter(None, logentry.childNodes): + if lpart.nodeType == lpart.ELEMENT_NODE: + if lpart.nodeName == 'author': + self.author = lpart.firstChild.nodeValue + elif lpart.nodeName == 'msg': + if lpart.firstChild: + self.msg = lpart.firstChild.nodeValue + else: + self.msg = '' + elif lpart.nodeName == 'date': + #2003-07-29T20:05:11.598637Z + timestr = lpart.firstChild.nodeValue + self.date = parse_apr_time(timestr) + elif lpart.nodeName == 'paths': + self.strpaths = [] + for ppart in filter(None, lpart.childNodes): + if ppart.nodeType == ppart.ELEMENT_NODE: + self.strpaths.append(PathEntry(ppart)) + def __repr__(self): + return '<Logentry rev=%d author=%s date=%s>' % ( + self.rev, self.author, self.date) + + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_process/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_process/__init__.py new file mode 100644 index 00000000..86c714ad --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_process/__init__.py @@ -0,0 +1 @@ +""" high-level sub-process handling """ diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_process/cmdexec.py b/dbdpy-env/lib/python3.9/site-packages/py/_process/cmdexec.py new file mode 100644 index 00000000..f83a2494 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_process/cmdexec.py @@ -0,0 +1,49 @@ +import sys +import subprocess +import py +from subprocess import Popen, PIPE + +def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + raise ExecutionFailed(status, status, cmd, out, err) + return out + +class ExecutionFailed(py.error.Error): + def __init__(self, status, systemstatus, cmd, out, err): + Exception.__init__(self) + self.status = status + self.systemstatus = systemstatus + self.cmd = cmd + self.err = err + self.out = out + + def __str__(self): + return "ExecutionFailed: %d %s\n%s" %(self.status, self.cmd, self.err) + +# export the exception under the name 'py.process.cmdexec.Error' +cmdexec.Error = ExecutionFailed +try: + ExecutionFailed.__module__ = 'py.process.cmdexec' + ExecutionFailed.__name__ = 'Error' +except (AttributeError, TypeError): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_process/forkedfunc.py b/dbdpy-env/lib/python3.9/site-packages/py/_process/forkedfunc.py new file mode 100644 index 00000000..1c285306 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_process/forkedfunc.py @@ -0,0 +1,120 @@ + +""" + ForkedFunc provides a way to run a function in a forked process + and get at its return value, stdout and stderr output as well + as signals and exitstatusus. +""" + +import py +import os +import sys +import marshal + + +def get_unbuffered_io(fd, filename): + f = open(str(filename), "w") + if fd != f.fileno(): + os.dup2(f.fileno(), fd) + class AutoFlush: + def write(self, data): + f.write(data) + f.flush() + def __getattr__(self, name): + return getattr(f, name) + return AutoFlush() + + +class ForkedFunc: + EXITSTATUS_EXCEPTION = 3 + + + def __init__(self, fun, args=None, kwargs=None, nice_level=0, + child_on_start=None, child_on_exit=None): + if args is None: + args = [] + if kwargs is None: + kwargs = {} + self.fun = fun + self.args = args + self.kwargs = kwargs + self.tempdir = tempdir = py.path.local.mkdtemp() + self.RETVAL = tempdir.ensure('retval') + self.STDOUT = tempdir.ensure('stdout') + self.STDERR = tempdir.ensure('stderr') + + pid = os.fork() + if pid: # in parent process + self.pid = pid + else: # in child process + self.pid = None + self._child(nice_level, child_on_start, child_on_exit) + + def _child(self, nice_level, child_on_start, child_on_exit): + # right now we need to call a function, but first we need to + # map all IO that might happen + sys.stdout = stdout = get_unbuffered_io(1, self.STDOUT) + sys.stderr = stderr = get_unbuffered_io(2, self.STDERR) + retvalf = self.RETVAL.open("wb") + EXITSTATUS = 0 + try: + if nice_level: + os.nice(nice_level) + try: + if child_on_start is not None: + child_on_start() + retval = self.fun(*self.args, **self.kwargs) + retvalf.write(marshal.dumps(retval)) + if child_on_exit is not None: + child_on_exit() + except: + excinfo = py.code.ExceptionInfo() + stderr.write(str(excinfo._getreprcrash())) + EXITSTATUS = self.EXITSTATUS_EXCEPTION + finally: + stdout.close() + stderr.close() + retvalf.close() + os.close(1) + os.close(2) + os._exit(EXITSTATUS) + + def waitfinish(self, waiter=os.waitpid): + pid, systemstatus = waiter(self.pid, 0) + if systemstatus: + if os.WIFSIGNALED(systemstatus): + exitstatus = os.WTERMSIG(systemstatus) + 128 + else: + exitstatus = os.WEXITSTATUS(systemstatus) + else: + exitstatus = 0 + signal = systemstatus & 0x7f + if not exitstatus and not signal: + retval = self.RETVAL.open('rb') + try: + retval_data = retval.read() + finally: + retval.close() + retval = marshal.loads(retval_data) + else: + retval = None + stdout = self.STDOUT.read() + stderr = self.STDERR.read() + self._removetemp() + return Result(exitstatus, signal, retval, stdout, stderr) + + def _removetemp(self): + if self.tempdir.check(): + self.tempdir.remove() + + def __del__(self): + if self.pid is not None: # only clean up in main process + self._removetemp() + + +class Result(object): + def __init__(self, exitstatus, signal, retval, stdout, stderr): + self.exitstatus = exitstatus + self.signal = signal + self.retval = retval + self.out = stdout + self.err = stderr diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_process/killproc.py b/dbdpy-env/lib/python3.9/site-packages/py/_process/killproc.py new file mode 100644 index 00000000..18e8310b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_process/killproc.py @@ -0,0 +1,23 @@ +import py +import os, sys + +if sys.platform == "win32" or getattr(os, '_name', '') == 'nt': + try: + import ctypes + except ImportError: + def dokill(pid): + py.process.cmdexec("taskkill /F /PID %d" %(pid,)) + else: + def dokill(pid): + PROCESS_TERMINATE = 1 + handle = ctypes.windll.kernel32.OpenProcess( + PROCESS_TERMINATE, False, pid) + ctypes.windll.kernel32.TerminateProcess(handle, -1) + ctypes.windll.kernel32.CloseHandle(handle) +else: + def dokill(pid): + os.kill(pid, 15) + +def kill(pid): + """ kill process by id. """ + dokill(pid) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_std.py b/dbdpy-env/lib/python3.9/site-packages/py/_std.py new file mode 100644 index 00000000..66adb7b0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_std.py @@ -0,0 +1,27 @@ +import sys +import warnings + + +class PyStdIsDeprecatedWarning(DeprecationWarning): + pass + + +class Std(object): + """ makes top-level python modules available as an attribute, + importing them on first access. + """ + + def __init__(self): + self.__dict__ = sys.modules + + def __getattr__(self, name): + warnings.warn("py.std is deprecated, please import %s directly" % name, + category=PyStdIsDeprecatedWarning, + stacklevel=2) + try: + m = __import__(name) + except ImportError: + raise AttributeError("py.std: could not import %s" % name) + return m + +std = Std() diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/LICENSE new file mode 100644 index 00000000..ff33b8f7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/LICENSE @@ -0,0 +1,18 @@ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/METADATA new file mode 100644 index 00000000..7eea770a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/METADATA @@ -0,0 +1,125 @@ +Metadata-Version: 2.1 +Name: apipkg +Version: 2.0.0 +Summary: apipkg: namespace control and lazy-import mechanism +Home-page: https://github.com/pytest-dev/apipkg +Author: holger krekel +Maintainer: Ronny Pfannschmidt +Maintainer-email: opensource@ronnypfannschmidt.de +License: MIT +Platform: unix +Platform: linux +Platform: osx +Platform: cygwin +Platform: win32 +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Topic :: Software Development :: Libraries +Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7 +Description-Content-Type: text/x-rst +License-File: LICENSE + +Welcome to apipkg ! +------------------- + +With apipkg you can control the exported namespace of a Python package and +greatly reduce the number of imports for your users. +It is a `small pure Python module`_ that works on CPython 2.7 and 3.4+, +Jython and PyPy. It cooperates well with Python's ``help()`` system, +custom importers (PEP302) and common command-line completion tools. + +Usage is very simple: you can require 'apipkg' as a dependency or you +can copy paste the ~200 lines of code into your project. + + +Tutorial example +------------------- + +Here is a simple ``mypkg`` package that specifies one namespace +and exports two objects imported from different modules:: + + + # mypkg/__init__.py + import apipkg + apipkg.initpkg(__name__, { + 'path': { + 'Class1': "_mypkg.somemodule:Class1", + 'clsattr': "_mypkg.othermodule:Class2.attr", + } + } + +The package is initialized with a dictionary as namespace. + +You need to create a ``_mypkg`` package with a ``somemodule.py`` +and ``othermodule.py`` containing the respective classes. +The ``_mypkg`` is not special - it's a completely +regular Python package. + +Namespace dictionaries contain ``name: value`` mappings +where the value may be another namespace dictionary or +a string specifying an import location. On accessing +an namespace attribute an import will be performed:: + + >>> import mypkg + >>> mypkg.path + <ApiModule 'mypkg.path'> + >>> mypkg.path.Class1 # '_mypkg.somemodule' gets imported now + <class _mypkg.somemodule.Class1 at 0xb7d428fc> + >>> mypkg.path.clsattr # '_mypkg.othermodule' gets imported now + 4 # the value of _mypkg.othermodule.Class2.attr + +The ``mypkg.path`` namespace and its two entries are +loaded when they are accessed. This means: + +* lazy loading - only what is actually needed is ever loaded + +* only the root "mypkg" ever needs to be imported to get + access to the complete functionality + +* the underlying modules are also accessible, for example:: + + from mypkg.sub import Class1 + + +Including apipkg in your package +-------------------------------------- + +If you don't want to add an ``apipkg`` dependency to your package you +can copy the `apipkg.py`_ file somewhere to your own package, +for example ``_mypkg/apipkg.py`` in the above example. You +then import the ``initpkg`` function from that new place and +are good to go. + +.. _`small pure Python module`: +.. _`apipkg.py`: https://github.com/pytest-dev/apipkg/blob/master/src/apipkg/__init__.py + +Feedback? +----------------------- + +If you have questions you are welcome to + +* join the **#pytest** channel on irc.libera.chat_ + (using an IRC client, via webchat_, or via Matrix_). +* create an issue on the bugtracker_ + +.. _irc.libera.chat: ircs://irc.libera.chat:6697/#pytest +.. _webchat: https://web.libera.chat/#pytest +.. _matrix: https://matrix.to/#/%23pytest:libera.chat +.. _bugtracker: https://github.com/pytest-dev/apipkg/issues + + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/RECORD new file mode 100644 index 00000000..357b8b9c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/RECORD @@ -0,0 +1,11 @@ +apipkg-2.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +apipkg-2.0.0.dist-info/LICENSE,sha256=6J7tEHTTqUMZi6E5uAhE9bRFuGC7p0qK6twGEFZhZOo,1054 +apipkg-2.0.0.dist-info/METADATA,sha256=GqNwkxraK5UTxObLVXTLc2UqktOPwZnKqdk2ThzHX0A,4292 +apipkg-2.0.0.dist-info/RECORD,, +apipkg-2.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apipkg-2.0.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110 +apipkg-2.0.0.dist-info/top_level.txt,sha256=3TGS6nmN7kjxhUK4LpPCB3QkQI34QYGrT0ZQGWajoZ8,7 +apipkg/__init__.py,sha256=gpbD3O57S9f-LsO2e-XwI6IGISayicfnCq3B5y_8frg,6978 +apipkg/__pycache__/__init__.cpython-39.pyc,, +apipkg/__pycache__/version.cpython-39.pyc,, +apipkg/version.py,sha256=bgZFg-f3UKhgE-z2w8RoFrwqRBzJBZkM4_jKFiYB9eU,142 diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/WHEEL new file mode 100644 index 00000000..b733a60d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/top_level.txt new file mode 100644 index 00000000..e2221c8f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg-2.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +apipkg diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/__init__.py new file mode 100644 index 00000000..350d8c4b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/__init__.py @@ -0,0 +1,217 @@ +""" +apipkg: control the exported namespace of a Python package. + +see https://pypi.python.org/pypi/apipkg + +(c) holger krekel, 2009 - MIT license +""" +import os +import sys +from types import ModuleType + +from .version import version as __version__ # NOQA:F401 + + +def _py_abspath(path): + """ + special version of abspath + that will leave paths from jython jars alone + """ + if path.startswith("__pyclasspath__"): + + return path + else: + return os.path.abspath(path) + + +def distribution_version(name): + """try to get the version of the named distribution, + returs None on failure""" + from pkg_resources import get_distribution, DistributionNotFound + + try: + dist = get_distribution(name) + except DistributionNotFound: + pass + else: + return dist.version + + +def initpkg(pkgname, exportdefs, attr=None, eager=False): + """ initialize given package from the export definitions. """ + attr = attr or {} + oldmod = sys.modules.get(pkgname) + d = {} + f = getattr(oldmod, "__file__", None) + if f: + f = _py_abspath(f) + d["__file__"] = f + if hasattr(oldmod, "__version__"): + d["__version__"] = oldmod.__version__ + if hasattr(oldmod, "__loader__"): + d["__loader__"] = oldmod.__loader__ + if hasattr(oldmod, "__path__"): + d["__path__"] = [_py_abspath(p) for p in oldmod.__path__] + if hasattr(oldmod, "__package__"): + d["__package__"] = oldmod.__package__ + if "__doc__" not in exportdefs and getattr(oldmod, "__doc__", None): + d["__doc__"] = oldmod.__doc__ + d["__spec__"] = getattr(oldmod, "__spec__", None) + d.update(attr) + if hasattr(oldmod, "__dict__"): + oldmod.__dict__.update(d) + mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d) + sys.modules[pkgname] = mod + # eagerload in bypthon to avoid their monkeypatching breaking packages + if "bpython" in sys.modules or eager: + for module in list(sys.modules.values()): + if isinstance(module, ApiModule): + module.__dict__ + return mod + + +def importobj(modpath, attrname): + """imports a module, then resolves the attrname on it""" + module = __import__(modpath, None, None, ["__doc__"]) + if not attrname: + return module + + retval = module + names = attrname.split(".") + for x in names: + retval = getattr(retval, x) + return retval + + +class ApiModule(ModuleType): + """the magical lazy-loading module standing""" + + def __docget(self): + try: + return self.__doc + except AttributeError: + if "__doc__" in self.__map__: + return self.__makeattr("__doc__") + + def __docset(self, value): + self.__doc = value + + __doc__ = property(__docget, __docset) + + def __init__(self, name, importspec, implprefix=None, attr=None): + self.__name__ = name + self.__all__ = [x for x in importspec if x != "__onfirstaccess__"] + self.__map__ = {} + self.__implprefix__ = implprefix or name + if attr: + for name, val in attr.items(): + # print "setting", self.__name__, name, val + setattr(self, name, val) + for name, importspec in importspec.items(): + if isinstance(importspec, dict): + subname = "{}.{}".format(self.__name__, name) + apimod = ApiModule(subname, importspec, implprefix) + sys.modules[subname] = apimod + setattr(self, name, apimod) + else: + parts = importspec.split(":") + modpath = parts.pop(0) + attrname = parts and parts[0] or "" + if modpath[0] == ".": + modpath = implprefix + modpath + + if not attrname: + subname = "{}.{}".format(self.__name__, name) + apimod = AliasModule(subname, modpath) + sys.modules[subname] = apimod + if "." not in name: + setattr(self, name, apimod) + else: + self.__map__[name] = (modpath, attrname) + + def __repr__(self): + repr_list = [] + if hasattr(self, "__version__"): + repr_list.append("version=" + repr(self.__version__)) + if hasattr(self, "__file__"): + repr_list.append("from " + repr(self.__file__)) + if repr_list: + return "<ApiModule {!r} {}>".format(self.__name__, " ".join(repr_list)) + return "<ApiModule {!r}>".format(self.__name__) + + def __makeattr(self, name): + """lazily compute value for name or raise AttributeError if unknown.""" + # print "makeattr", self.__name__, name + target = None + if "__onfirstaccess__" in self.__map__: + target = self.__map__.pop("__onfirstaccess__") + importobj(*target)() + try: + modpath, attrname = self.__map__[name] + except KeyError: + if target is not None and name != "__onfirstaccess__": + # retry, onfirstaccess might have set attrs + return getattr(self, name) + raise AttributeError(name) + else: + result = importobj(modpath, attrname) + setattr(self, name, result) + try: + del self.__map__[name] + except KeyError: + pass # in a recursive-import situation a double-del can happen + return result + + __getattr__ = __makeattr + + @property + def __dict__(self): + # force all the content of the module + # to be loaded when __dict__ is read + dictdescr = ModuleType.__dict__["__dict__"] + dict = dictdescr.__get__(self) + if dict is not None: + hasattr(self, "some") + for name in self.__all__: + try: + self.__makeattr(name) + except AttributeError: + pass + return dict + + +def AliasModule(modname, modpath, attrname=None): + mod = [] + + def getmod(): + if not mod: + x = importobj(modpath, None) + if attrname is not None: + x = getattr(x, attrname) + mod.append(x) + return mod[0] + + x = modpath + ("." + attrname if attrname else "") + repr_result = "<AliasModule {!r} for {!r}>".format(modname, x) + + class AliasModule(ModuleType): + def __repr__(self): + return repr_result + + def __getattribute__(self, name): + try: + return getattr(getmod(), name) + except ImportError: + if modpath == "pytest" and attrname is None: + # hack for pylibs py.test + return None + else: + raise + + def __setattr__(self, name, value): + setattr(getmod(), name, value) + + def __delattr__(self, name): + delattr(getmod(), name) + + return AliasModule(str(modname)) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/version.py b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/version.py new file mode 100644 index 00000000..c5b4e0e7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/apipkg/version.py @@ -0,0 +1,5 @@ +# coding: utf-8 +# file generated by setuptools_scm +# don't change, don't track in version control +version = '2.0.0' +version_tuple = (2, 0, 0) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/LICENSE new file mode 100644 index 00000000..31ecdfb1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/LICENSE @@ -0,0 +1,19 @@ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/METADATA new file mode 100644 index 00000000..c078a753 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/METADATA @@ -0,0 +1,78 @@ +Metadata-Version: 2.1 +Name: iniconfig +Version: 1.1.1 +Summary: iniconfig: brain-dead simple config-ini parsing +Home-page: http://github.com/RonnyPfannschmidt/iniconfig +Author: Ronny Pfannschmidt, Holger Krekel +Author-email: opensource@ronnypfannschmidt.de, holger.krekel@gmail.com +License: MIT License +Platform: unix +Platform: linux +Platform: osx +Platform: cygwin +Platform: win32 +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 + +iniconfig: brain-dead simple parsing of ini files +======================================================= + +iniconfig is a small and simple INI-file parser module +having a unique set of features: + +* tested against Python2.4 across to Python3.2, Jython, PyPy +* maintains order of sections and entries +* supports multi-line values with or without line-continuations +* supports "#" comments everywhere +* raises errors with proper line-numbers +* no bells and whistles like automatic substitutions +* iniconfig raises an Error if two sections have the same name. + +If you encounter issues or have feature wishes please report them to: + + http://github.com/RonnyPfannschmidt/iniconfig/issues + +Basic Example +=================================== + +If you have an ini file like this:: + + # content of example.ini + [section1] # comment + name1=value1 # comment + name1b=value1,value2 # comment + + [section2] + name2= + line1 + line2 + +then you can do:: + + >>> import iniconfig + >>> ini = iniconfig.IniConfig("example.ini") + >>> ini['section1']['name1'] # raises KeyError if not exists + 'value1' + >>> ini.get('section1', 'name1b', [], lambda x: x.split(",")) + ['value1', 'value2'] + >>> ini.get('section1', 'notexist', [], lambda x: x.split(",")) + [] + >>> [x.name for x in list(ini)] + ['section1', 'section2'] + >>> list(list(ini)[0].items()) + [('name1', 'value1'), ('name1b', 'value1,value2')] + >>> 'section1' in ini + True + >>> 'inexistendsection' in ini + False + + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/RECORD new file mode 100644 index 00000000..16823333 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/RECORD @@ -0,0 +1,11 @@ +iniconfig-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +iniconfig-1.1.1.dist-info/LICENSE,sha256=KvaAw570k_uCgwNW0dPfGstaBgM8ui3sehniHKp3qGY,1061 +iniconfig-1.1.1.dist-info/METADATA,sha256=_4-oFKpRXuZv5rzepScpXRwhq6DzqsgbnA5ZpgMUMcs,2405 +iniconfig-1.1.1.dist-info/RECORD,, +iniconfig-1.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +iniconfig-1.1.1.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 +iniconfig-1.1.1.dist-info/top_level.txt,sha256=7KfM0fugdlToj9UW7enKXk2HYALQD8qHiyKtjhSzgN8,10 +iniconfig/__init__.py,sha256=-pBe5AF_6aAwo1CxJQ8i_zJq6ejc6IxHta7qk2tNJhY,5208 +iniconfig/__init__.pyi,sha256=-4KOctzq28ohRmTZsqlH6aylyFqsNKxYqtk1dteypi4,1205 +iniconfig/__pycache__/__init__.cpython-39.pyc,, +iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/WHEEL new file mode 100644 index 00000000..6d38aa06 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.35.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/top_level.txt new file mode 100644 index 00000000..9dda5369 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig-1.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +iniconfig diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.py b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.py new file mode 100644 index 00000000..6ad9eaf8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.py @@ -0,0 +1,165 @@ +""" brain-dead simple parser for ini-style files. +(C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed +""" +__all__ = ['IniConfig', 'ParseError'] + +COMMENTCHARS = "#;" + + +class ParseError(Exception): + def __init__(self, path, lineno, msg): + Exception.__init__(self, path, lineno, msg) + self.path = path + self.lineno = lineno + self.msg = msg + + def __str__(self): + return "%s:%s: %s" % (self.path, self.lineno+1, self.msg) + + +class SectionWrapper(object): + def __init__(self, config, name): + self.config = config + self.name = name + + def lineof(self, name): + return self.config.lineof(self.name, name) + + def get(self, key, default=None, convert=str): + return self.config.get(self.name, key, + convert=convert, default=default) + + def __getitem__(self, key): + return self.config.sections[self.name][key] + + def __iter__(self): + section = self.config.sections.get(self.name, []) + + def lineof(key): + return self.config.lineof(self.name, key) + for name in sorted(section, key=lineof): + yield name + + def items(self): + for name in self: + yield name, self[name] + + +class IniConfig(object): + def __init__(self, path, data=None): + self.path = str(path) # convenience + if data is None: + f = open(self.path) + try: + tokens = self._parse(iter(f)) + finally: + f.close() + else: + tokens = self._parse(data.splitlines(True)) + + self._sources = {} + self.sections = {} + + for lineno, section, name, value in tokens: + if section is None: + self._raise(lineno, 'no section header defined') + self._sources[section, name] = lineno + if name is None: + if section in self.sections: + self._raise(lineno, 'duplicate section %r' % (section, )) + self.sections[section] = {} + else: + if name in self.sections[section]: + self._raise(lineno, 'duplicate name %r' % (name, )) + self.sections[section][name] = value + + def _raise(self, lineno, msg): + raise ParseError(self.path, lineno, msg) + + def _parse(self, line_iter): + result = [] + section = None + for lineno, line in enumerate(line_iter): + name, data = self._parseline(line, lineno) + # new value + if name is not None and data is not None: + result.append((lineno, section, name, data)) + # new section + elif name is not None and data is None: + if not name: + self._raise(lineno, 'empty section name') + section = name + result.append((lineno, section, None, None)) + # continuation + elif name is None and data is not None: + if not result: + self._raise(lineno, 'unexpected value continuation') + last = result.pop() + last_name, last_data = last[-2:] + if last_name is None: + self._raise(lineno, 'unexpected value continuation') + + if last_data: + data = '%s\n%s' % (last_data, data) + result.append(last[:-1] + (data,)) + return result + + def _parseline(self, line, lineno): + # blank lines + if iscommentline(line): + line = "" + else: + line = line.rstrip() + if not line: + return None, None + # section + if line[0] == '[': + realline = line + for c in COMMENTCHARS: + line = line.split(c)[0].rstrip() + if line[-1] == "]": + return line[1:-1], None + return None, realline.strip() + # value + elif not line[0].isspace(): + try: + name, value = line.split('=', 1) + if ":" in name: + raise ValueError() + except ValueError: + try: + name, value = line.split(":", 1) + except ValueError: + self._raise(lineno, 'unexpected line: %r' % line) + return name.strip(), value.strip() + # continuation + else: + return None, line.strip() + + def lineof(self, section, name=None): + lineno = self._sources.get((section, name)) + if lineno is not None: + return lineno + 1 + + def get(self, section, name, default=None, convert=str): + try: + return convert(self.sections[section][name]) + except KeyError: + return default + + def __getitem__(self, name): + if name not in self.sections: + raise KeyError(name) + return SectionWrapper(self, name) + + def __iter__(self): + for name in sorted(self.sections, key=self.lineof): + yield SectionWrapper(self, name) + + def __contains__(self, arg): + return arg in self.sections + + +def iscommentline(line): + c = line.lstrip()[:1] + return c in COMMENTCHARS diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.pyi b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.pyi new file mode 100644 index 00000000..b6284bec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/__init__.pyi @@ -0,0 +1,31 @@ +from typing import Callable, Iterator, Mapping, Optional, Tuple, TypeVar, Union +from typing_extensions import Final + +_D = TypeVar('_D') +_T = TypeVar('_T') + +class ParseError(Exception): + # Private __init__. + path: Final[str] + lineno: Final[int] + msg: Final[str] + +class SectionWrapper: + # Private __init__. + config: Final[IniConfig] + name: Final[str] + def __getitem__(self, key: str) -> str: ... + def __iter__(self) -> Iterator[str]: ... + def get(self, key: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... + def items(self) -> Iterator[Tuple[str, str]]: ... + def lineof(self, name: str) -> Optional[int]: ... + +class IniConfig: + path: Final[str] + sections: Final[Mapping[str, Mapping[str, str]]] + def __init__(self, path: str, data: Optional[str] = None): ... + def __contains__(self, arg: str) -> bool: ... + def __getitem__(self, name: str) -> SectionWrapper: ... + def __iter__(self) -> Iterator[SectionWrapper]: ... + def get(self, section: str, name: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... + def lineof(self, section: str, name: Optional[str] = ...) -> Optional[int]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/py.typed b/dbdpy-env/lib/python3.9/site-packages/py/_vendored_packages/iniconfig/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_version.py b/dbdpy-env/lib/python3.9/site-packages/py/_version.py new file mode 100644 index 00000000..3d30fbec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_version.py @@ -0,0 +1,5 @@ +# coding: utf-8 +# file generated by setuptools_scm +# don't change, don't track in version control +version = '1.11.0' +version_tuple = (1, 11, 0) diff --git a/dbdpy-env/lib/python3.9/site-packages/py/_xmlgen.py b/dbdpy-env/lib/python3.9/site-packages/py/_xmlgen.py new file mode 100644 index 00000000..1c835458 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/_xmlgen.py @@ -0,0 +1,255 @@ +""" +module for generating and serializing xml and html structures +by using simple python objects. + +(c) holger krekel, holger at merlinux eu. 2009 +""" +import sys, re + +if sys.version_info >= (3,0): + def u(s): + return s + def unicode(x, errors=None): + if hasattr(x, '__unicode__'): + return x.__unicode__() + return str(x) +else: + def u(s): + return unicode(s) + unicode = unicode + + +class NamespaceMetaclass(type): + def __getattr__(self, name): + if name[:1] == '_': + raise AttributeError(name) + if self == Namespace: + raise ValueError("Namespace class is abstract") + tagspec = self.__tagspec__ + if tagspec is not None and name not in tagspec: + raise AttributeError(name) + classattr = {} + if self.__stickyname__: + classattr['xmlname'] = name + cls = type(name, (self.__tagclass__,), classattr) + setattr(self, name, cls) + return cls + +class Tag(list): + class Attr(object): + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + def __init__(self, *args, **kwargs): + super(Tag, self).__init__(args) + self.attr = self.Attr(**kwargs) + + def __unicode__(self): + return self.unicode(indent=0) + __str__ = __unicode__ + + def unicode(self, indent=2): + l = [] + SimpleUnicodeVisitor(l.append, indent).visit(self) + return u("").join(l) + + def __repr__(self): + name = self.__class__.__name__ + return "<%r tag object %d>" % (name, id(self)) + +Namespace = NamespaceMetaclass('Namespace', (object, ), { + '__tagspec__': None, + '__tagclass__': Tag, + '__stickyname__': False, +}) + +class HtmlTag(Tag): + def unicode(self, indent=2): + l = [] + HtmlVisitor(l.append, indent, shortempty=False).visit(self) + return u("").join(l) + +# exported plain html namespace +class html(Namespace): + __tagclass__ = HtmlTag + __stickyname__ = True + __tagspec__ = dict([(x,1) for x in ( + 'a,abbr,acronym,address,applet,area,article,aside,audio,b,' + 'base,basefont,bdi,bdo,big,blink,blockquote,body,br,button,' + 'canvas,caption,center,cite,code,col,colgroup,command,comment,' + 'datalist,dd,del,details,dfn,dir,div,dl,dt,em,embed,' + 'fieldset,figcaption,figure,footer,font,form,frame,frameset,h1,' + 'h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,img,input,' + 'ins,isindex,kbd,keygen,label,legend,li,link,listing,map,mark,' + 'marquee,menu,meta,meter,multicol,nav,nobr,noembed,noframes,' + 'noscript,object,ol,optgroup,option,output,p,param,pre,progress,' + 'q,rp,rt,ruby,s,samp,script,section,select,small,source,span,' + 'strike,strong,style,sub,summary,sup,table,tbody,td,textarea,' + 'tfoot,th,thead,time,title,tr,track,tt,u,ul,xmp,var,video,wbr' + ).split(',') if x]) + + class Style(object): + def __init__(self, **kw): + for x, y in kw.items(): + x = x.replace('_', '-') + setattr(self, x, y) + + +class raw(object): + """just a box that can contain a unicode string that will be + included directly in the output""" + def __init__(self, uniobj): + self.uniobj = uniobj + +class SimpleUnicodeVisitor(object): + """ recursive visitor to write unicode. """ + def __init__(self, write, indent=0, curindent=0, shortempty=True): + self.write = write + self.cache = {} + self.visited = {} # for detection of recursion + self.indent = indent + self.curindent = curindent + self.parents = [] + self.shortempty = shortempty # short empty tags or not + + def visit(self, node): + """ dispatcher on node's class/bases name. """ + cls = node.__class__ + try: + visitmethod = self.cache[cls] + except KeyError: + for subclass in cls.__mro__: + visitmethod = getattr(self, subclass.__name__, None) + if visitmethod is not None: + break + else: + visitmethod = self.__object + self.cache[cls] = visitmethod + visitmethod(node) + + # the default fallback handler is marked private + # to avoid clashes with the tag name object + def __object(self, obj): + #self.write(obj) + self.write(escape(unicode(obj))) + + def raw(self, obj): + self.write(obj.uniobj) + + def list(self, obj): + assert id(obj) not in self.visited + self.visited[id(obj)] = 1 + for elem in obj: + self.visit(elem) + + def Tag(self, tag): + assert id(tag) not in self.visited + try: + tag.parent = self.parents[-1] + except IndexError: + tag.parent = None + self.visited[id(tag)] = 1 + tagname = getattr(tag, 'xmlname', tag.__class__.__name__) + if self.curindent and not self._isinline(tagname): + self.write("\n" + u(' ') * self.curindent) + if tag: + self.curindent += self.indent + self.write(u('<%s%s>') % (tagname, self.attributes(tag))) + self.parents.append(tag) + for x in tag: + self.visit(x) + self.parents.pop() + self.write(u('</%s>') % tagname) + self.curindent -= self.indent + else: + nameattr = tagname+self.attributes(tag) + if self._issingleton(tagname): + self.write(u('<%s/>') % (nameattr,)) + else: + self.write(u('<%s></%s>') % (nameattr, tagname)) + + def attributes(self, tag): + # serialize attributes + attrlist = dir(tag.attr) + attrlist.sort() + l = [] + for name in attrlist: + res = self.repr_attribute(tag.attr, name) + if res is not None: + l.append(res) + l.extend(self.getstyle(tag)) + return u("").join(l) + + def repr_attribute(self, attrs, name): + if name[:2] != '__': + value = getattr(attrs, name) + if name.endswith('_'): + name = name[:-1] + if isinstance(value, raw): + insert = value.uniobj + else: + insert = escape(unicode(value)) + return ' %s="%s"' % (name, insert) + + def getstyle(self, tag): + """ return attribute list suitable for styling. """ + try: + styledict = tag.style.__dict__ + except AttributeError: + return [] + else: + stylelist = [x+': ' + y for x,y in styledict.items()] + return [u(' style="%s"') % u('; ').join(stylelist)] + + def _issingleton(self, tagname): + """can (and will) be overridden in subclasses""" + return self.shortempty + + def _isinline(self, tagname): + """can (and will) be overridden in subclasses""" + return False + +class HtmlVisitor(SimpleUnicodeVisitor): + + single = dict([(x, 1) for x in + ('br,img,area,param,col,hr,meta,link,base,' + 'input,frame').split(',')]) + inline = dict([(x, 1) for x in + ('a abbr acronym b basefont bdo big br cite code dfn em font ' + 'i img input kbd label q s samp select small span strike ' + 'strong sub sup textarea tt u var'.split(' '))]) + + def repr_attribute(self, attrs, name): + if name == 'class_': + value = getattr(attrs, name) + if value is None: + return + return super(HtmlVisitor, self).repr_attribute(attrs, name) + + def _issingleton(self, tagname): + return tagname in self.single + + def _isinline(self, tagname): + return tagname in self.inline + + +class _escape: + def __init__(self): + self.escape = { + u('"') : u('&quot;'), u('<') : u('&lt;'), u('>') : u('&gt;'), + u('&') : u('&amp;'), u("'") : u('&apos;'), + } + self.charef_rex = re.compile(u("|").join(self.escape.keys())) + + def _replacer(self, match): + return self.escape[match.group(0)] + + def __call__(self, ustring): + """ xml-escape the given unicode string. """ + try: + ustring = unicode(ustring) + except UnicodeDecodeError: + ustring = unicode(ustring, 'utf-8', errors='replace') + return self.charef_rex.sub(self._replacer, ustring) + +escape = _escape() diff --git a/dbdpy-env/lib/python3.9/site-packages/py/error.pyi b/dbdpy-env/lib/python3.9/site-packages/py/error.pyi new file mode 100644 index 00000000..034eba60 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/error.pyi @@ -0,0 +1,129 @@ +from typing import Any, Callable, TypeVar + +_T = TypeVar('_T') + +def checked_call(func: Callable[..., _T], *args: Any, **kwargs: Any) -> _T: ... +class Error(EnvironmentError): ... +class EPERM(Error): ... +class ENOENT(Error): ... +class ESRCH(Error): ... +class EINTR(Error): ... +class EIO(Error): ... +class ENXIO(Error): ... +class E2BIG(Error): ... +class ENOEXEC(Error): ... +class EBADF(Error): ... +class ECHILD(Error): ... +class EAGAIN(Error): ... +class ENOMEM(Error): ... +class EACCES(Error): ... +class EFAULT(Error): ... +class ENOTBLK(Error): ... +class EBUSY(Error): ... +class EEXIST(Error): ... +class EXDEV(Error): ... +class ENODEV(Error): ... +class ENOTDIR(Error): ... +class EISDIR(Error): ... +class EINVAL(Error): ... +class ENFILE(Error): ... +class EMFILE(Error): ... +class ENOTTY(Error): ... +class ETXTBSY(Error): ... +class EFBIG(Error): ... +class ENOSPC(Error): ... +class ESPIPE(Error): ... +class EROFS(Error): ... +class EMLINK(Error): ... +class EPIPE(Error): ... +class EDOM(Error): ... +class ERANGE(Error): ... +class EDEADLCK(Error): ... +class ENAMETOOLONG(Error): ... +class ENOLCK(Error): ... +class ENOSYS(Error): ... +class ENOTEMPTY(Error): ... +class ELOOP(Error): ... +class EWOULDBLOCK(Error): ... +class ENOMSG(Error): ... +class EIDRM(Error): ... +class ECHRNG(Error): ... +class EL2NSYNC(Error): ... +class EL3HLT(Error): ... +class EL3RST(Error): ... +class ELNRNG(Error): ... +class EUNATCH(Error): ... +class ENOCSI(Error): ... +class EL2HLT(Error): ... +class EBADE(Error): ... +class EBADR(Error): ... +class EXFULL(Error): ... +class ENOANO(Error): ... +class EBADRQC(Error): ... +class EBADSLT(Error): ... +class EDEADLOCK(Error): ... +class EBFONT(Error): ... +class ENOSTR(Error): ... +class ENODATA(Error): ... +class ETIME(Error): ... +class ENOSR(Error): ... +class ENONET(Error): ... +class ENOPKG(Error): ... +class EREMOTE(Error): ... +class ENOLINK(Error): ... +class EADV(Error): ... +class ESRMNT(Error): ... +class ECOMM(Error): ... +class EPROTO(Error): ... +class EMULTIHOP(Error): ... +class EDOTDOT(Error): ... +class EBADMSG(Error): ... +class EOVERFLOW(Error): ... +class ENOTUNIQ(Error): ... +class EBADFD(Error): ... +class EREMCHG(Error): ... +class ELIBACC(Error): ... +class ELIBBAD(Error): ... +class ELIBSCN(Error): ... +class ELIBMAX(Error): ... +class ELIBEXEC(Error): ... +class EILSEQ(Error): ... +class ERESTART(Error): ... +class ESTRPIPE(Error): ... +class EUSERS(Error): ... +class ENOTSOCK(Error): ... +class EDESTADDRREQ(Error): ... +class EMSGSIZE(Error): ... +class EPROTOTYPE(Error): ... +class ENOPROTOOPT(Error): ... +class EPROTONOSUPPORT(Error): ... +class ESOCKTNOSUPPORT(Error): ... +class ENOTSUP(Error): ... +class EOPNOTSUPP(Error): ... +class EPFNOSUPPORT(Error): ... +class EAFNOSUPPORT(Error): ... +class EADDRINUSE(Error): ... +class EADDRNOTAVAIL(Error): ... +class ENETDOWN(Error): ... +class ENETUNREACH(Error): ... +class ENETRESET(Error): ... +class ECONNABORTED(Error): ... +class ECONNRESET(Error): ... +class ENOBUFS(Error): ... +class EISCONN(Error): ... +class ENOTCONN(Error): ... +class ESHUTDOWN(Error): ... +class ETOOMANYREFS(Error): ... +class ETIMEDOUT(Error): ... +class ECONNREFUSED(Error): ... +class EHOSTDOWN(Error): ... +class EHOSTUNREACH(Error): ... +class EALREADY(Error): ... +class EINPROGRESS(Error): ... +class ESTALE(Error): ... +class EUCLEAN(Error): ... +class ENOTNAM(Error): ... +class ENAVAIL(Error): ... +class EISNAM(Error): ... +class EREMOTEIO(Error): ... +class EDQUOT(Error): ... diff --git a/dbdpy-env/lib/python3.9/site-packages/py/iniconfig.pyi b/dbdpy-env/lib/python3.9/site-packages/py/iniconfig.pyi new file mode 100644 index 00000000..b6284bec --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/iniconfig.pyi @@ -0,0 +1,31 @@ +from typing import Callable, Iterator, Mapping, Optional, Tuple, TypeVar, Union +from typing_extensions import Final + +_D = TypeVar('_D') +_T = TypeVar('_T') + +class ParseError(Exception): + # Private __init__. + path: Final[str] + lineno: Final[int] + msg: Final[str] + +class SectionWrapper: + # Private __init__. + config: Final[IniConfig] + name: Final[str] + def __getitem__(self, key: str) -> str: ... + def __iter__(self) -> Iterator[str]: ... + def get(self, key: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... + def items(self) -> Iterator[Tuple[str, str]]: ... + def lineof(self, name: str) -> Optional[int]: ... + +class IniConfig: + path: Final[str] + sections: Final[Mapping[str, Mapping[str, str]]] + def __init__(self, path: str, data: Optional[str] = None): ... + def __contains__(self, arg: str) -> bool: ... + def __getitem__(self, name: str) -> SectionWrapper: ... + def __iter__(self) -> Iterator[SectionWrapper]: ... + def get(self, section: str, name: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... + def lineof(self, section: str, name: Optional[str] = ...) -> Optional[int]: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/py/io.pyi b/dbdpy-env/lib/python3.9/site-packages/py/io.pyi new file mode 100644 index 00000000..d377e240 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/io.pyi @@ -0,0 +1,130 @@ +from io import StringIO as TextIO +from io import BytesIO as BytesIO +from typing import Any, AnyStr, Callable, Generic, IO, List, Optional, Text, Tuple, TypeVar, Union, overload +from typing_extensions import Final +import sys + +_T = TypeVar("_T") + +class FDCapture(Generic[AnyStr]): + def __init__(self, targetfd: int, tmpfile: Optional[IO[AnyStr]] = ..., now: bool = ..., patchsys: bool = ...) -> None: ... + def start(self) -> None: ... + def done(self) -> IO[AnyStr]: ... + def writeorg(self, data: AnyStr) -> None: ... + +class StdCaptureFD: + def __init__( + self, + out: Union[bool, IO[str]] = ..., + err: Union[bool, IO[str]] = ..., + mixed: bool = ..., + in_: bool = ..., + patchsys: bool = ..., + now: bool = ..., + ) -> None: ... + @classmethod + def call(cls, func: Callable[..., _T], *args: Any, **kwargs: Any) -> Tuple[_T, str, str]: ... + def reset(self) -> Tuple[str, str]: ... + def suspend(self) -> Tuple[str, str]: ... + def startall(self) -> None: ... + def resume(self) -> None: ... + def done(self, save: bool = ...) -> Tuple[IO[str], IO[str]]: ... + def readouterr(self) -> Tuple[str, str]: ... + +class StdCapture: + def __init__( + self, + out: Union[bool, IO[str]] = ..., + err: Union[bool, IO[str]] = ..., + in_: bool = ..., + mixed: bool = ..., + now: bool = ..., + ) -> None: ... + @classmethod + def call(cls, func: Callable[..., _T], *args: Any, **kwargs: Any) -> Tuple[_T, str, str]: ... + def reset(self) -> Tuple[str, str]: ... + def suspend(self) -> Tuple[str, str]: ... + def startall(self) -> None: ... + def resume(self) -> None: ... + def done(self, save: bool = ...) -> Tuple[IO[str], IO[str]]: ... + def readouterr(self) -> Tuple[IO[str], IO[str]]: ... + +# XXX: The type here is not exactly right. If f is IO[bytes] and +# encoding is not None, returns some weird hybrid, not exactly IO[bytes]. +def dupfile( + f: IO[AnyStr], + mode: Optional[str] = ..., + buffering: int = ..., + raising: bool = ..., + encoding: Optional[str] = ..., +) -> IO[AnyStr]: ... +def get_terminal_width() -> int: ... +def ansi_print( + text: Union[str, Text], + esc: Union[Union[str, Text], Tuple[Union[str, Text], ...]], + file: Optional[IO[Any]] = ..., + newline: bool = ..., + flush: bool = ..., +) -> None: ... +def saferepr(obj, maxsize: int = ...) -> str: ... + +class TerminalWriter: + stringio: TextIO + encoding: Final[str] + hasmarkup: bool + def __init__(self, file: Optional[IO[str]] = ..., stringio: bool = ..., encoding: Optional[str] = ...) -> None: ... + @property + def fullwidth(self) -> int: ... + @fullwidth.setter + def fullwidth(self, value: int) -> None: ... + @property + def chars_on_current_line(self) -> int: ... + @property + def width_of_current_line(self) -> int: ... + def markup( + self, + text: str, + *, + black: int = ..., red: int = ..., green: int = ..., yellow: int = ..., blue: int = ..., purple: int = ..., + cyan: int = ..., white: int = ..., Black: int = ..., Red: int = ..., Green: int = ..., Yellow: int = ..., + Blue: int = ..., Purple: int = ..., Cyan: int = ..., White: int = ..., bold: int = ..., light: int = ..., + blink: int = ..., invert: int = ..., + ) -> str: ... + def sep( + self, + sepchar: str, + title: Optional[str] = ..., + fullwidth: Optional[int] = ..., + *, + black: int = ..., red: int = ..., green: int = ..., yellow: int = ..., blue: int = ..., purple: int = ..., + cyan: int = ..., white: int = ..., Black: int = ..., Red: int = ..., Green: int = ..., Yellow: int = ..., + Blue: int = ..., Purple: int = ..., Cyan: int = ..., White: int = ..., bold: int = ..., light: int = ..., + blink: int = ..., invert: int = ..., + ) -> None: ... + def write( + self, + msg: str, + *, + black: int = ..., red: int = ..., green: int = ..., yellow: int = ..., blue: int = ..., purple: int = ..., + cyan: int = ..., white: int = ..., Black: int = ..., Red: int = ..., Green: int = ..., Yellow: int = ..., + Blue: int = ..., Purple: int = ..., Cyan: int = ..., White: int = ..., bold: int = ..., light: int = ..., + blink: int = ..., invert: int = ..., + ) -> None: ... + def line( + self, + s: str = ..., + *, + black: int = ..., red: int = ..., green: int = ..., yellow: int = ..., blue: int = ..., purple: int = ..., + cyan: int = ..., white: int = ..., Black: int = ..., Red: int = ..., Green: int = ..., Yellow: int = ..., + Blue: int = ..., Purple: int = ..., Cyan: int = ..., White: int = ..., bold: int = ..., light: int = ..., + blink: int = ..., invert: int = ..., + ) -> None: ... + def reline( + self, + line: str, + *, + black: int = ..., red: int = ..., green: int = ..., yellow: int = ..., blue: int = ..., purple: int = ..., + cyan: int = ..., white: int = ..., Black: int = ..., Red: int = ..., Green: int = ..., Yellow: int = ..., + Blue: int = ..., Purple: int = ..., Cyan: int = ..., White: int = ..., bold: int = ..., light: int = ..., + blink: int = ..., invert: int = ..., + ) -> None: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/py/path.pyi b/dbdpy-env/lib/python3.9/site-packages/py/path.pyi new file mode 100644 index 00000000..1ddab960 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/path.pyi @@ -0,0 +1,197 @@ +from typing import Any, AnyStr, Callable, ContextManager, Generic, IO, Iterable, Iterator, List, Optional, Text, Type, Union +from typing_extensions import Final, Literal +import os +import sys + +class _FNMatcher(Generic[AnyStr]): + pattern: AnyStr = ... + def __init__(self, pattern: AnyStr) -> None: ... + def __call__(self, path: local) -> bool: ... + +class _Stat: + path: Final[local] = ... + mode: Final[int] + ino: Final[int] + dev: Final[int] + nlink: Final[int] + uid: Final[int] + gid: Final[int] + size: Final[int] + atime: Final[float] + mtime: Final[float] + ctime: Final[float] + atime_ns: Final[int] + mtime_ns: Final[int] + ctime_ns: Final[int] + if sys.version_info >= (3, 8) and sys.platform == "win32": + reparse_tag: Final[int] + blocks: Final[int] + blksize: Final[int] + rdev: Final[int] + flags: Final[int] + gen: Final[int] + birthtime: Final[int] + rsize: Final[int] + creator: Final[int] + type: Final[int] + if sys.platform != 'win32': + @property + def owner(self) -> str: ... + @property + def group(self) -> str: ... + def isdir(self) -> bool: ... + def isfile(self) -> bool: ... + def islink(self) -> bool: ... + + +if sys.version_info >= (3, 6): + _PathLike = os.PathLike +else: + class _PathLike(Generic[AnyStr]): + def __fspath__(self) -> AnyStr: ... +_PathType = Union[bytes, Text, _PathLike[str], _PathLike[bytes], local] + +class local(_PathLike[str]): + class ImportMismatchError(ImportError): ... + + sep: Final[str] + strpath: Final[str] + + def __init__(self, path: _PathType = ..., expanduser: bool = ...) -> None: ... + def __hash__(self) -> int: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __lt__(self, other: object) -> bool: ... + def __gt__(self, other: object) -> bool: ... + def __add__(self, other: object) -> local: ... + def __cmp__(self, other: object) -> int: ... + def __div__(self, other: _PathType) -> local: ... + def __truediv__(self, other: _PathType) -> local: ... + def __fspath__(self) -> str: ... + + @classmethod + def get_temproot(cls) -> local: ... + @classmethod + def make_numbered_dir( + cls, + prefix: str = ..., + rootdir: Optional[local] = ..., + keep: Optional[int] = ..., + lock_timeout: int = ..., + ) -> local: ... + @classmethod + def mkdtemp(cls, rootdir: Optional[local] = ...) -> local: ... + @classmethod + def sysfind( + cls, + name: _PathType, + checker: Optional[Callable[[local], bool]] = ..., + paths: Optional[Iterable[_PathType]] = ..., + ) -> Optional[local]: ... + + @property + def basename(self) -> str: ... + @property + def dirname(self) -> str: ... + @property + def purebasename(self) -> str: ... + @property + def ext(self) -> str: ... + + def as_cwd(self) -> ContextManager[Optional[local]]: ... + def atime(self) -> float: ... + def bestrelpath(self, dest: local) -> str: ... + def chdir(self) -> local: ... + def check( + self, + *, + basename: int = ..., notbasename: int = ..., + basestarts: int = ..., notbasestarts: int = ..., + dir: int = ..., notdir: int = ..., + dotfile: int = ..., notdotfile: int = ..., + endswith: int = ..., notendswith: int = ..., + exists: int = ..., notexists: int = ..., + ext: int = ..., notext: int = ..., + file: int = ..., notfile: int = ..., + fnmatch: int = ..., notfnmatch: int = ..., + link: int = ..., notlink: int = ..., + relto: int = ..., notrelto: int = ..., + ) -> bool: ... + def chmod(self, mode: int, rec: Union[int, str, Text, Callable[[local], bool]] = ...) -> None: ... + if sys.platform != 'win32': + def chown(self, user: Union[int, str], group: Union[int, str], rec: int = ...) -> None: ... + def common(self, other: local) -> Optional[local]: ... + def computehash(self, hashtype: str = ..., chunksize: int = ...) -> str: ... + def copy(self, target: local, mode: bool = ..., stat: bool = ...) -> None: ... + def dirpath(self, *args: _PathType, abs: int = ...) -> local: ... + def dump(self, obj: Any, bin: Optional[int] = ...) -> None: ... + def ensure(self, *args: _PathType, dir: int = ...) -> local: ... + def ensure_dir(self, *args: _PathType) -> local: ... + def exists(self) -> bool: ... + def fnmatch(self, pattern: str): _FNMatcher + def isdir(self) -> bool: ... + def isfile(self) -> bool: ... + def islink(self) -> bool: ... + def join(self, *args: _PathType, abs: int = ...) -> local: ... + def listdir( + self, + fil: Optional[Union[str, Text, Callable[[local], bool]]] = ..., + sort: Optional[bool] = ..., + ) -> List[local]: ... + def load(self) -> Any: ... + def lstat(self) -> _Stat: ... + def mkdir(self, *args: _PathType) -> local: ... + if sys.platform != 'win32': + def mklinkto(self, oldname: Union[str, local]) -> None: ... + def mksymlinkto(self, value: local, absolute: int = ...) -> None: ... + def move(self, target: local) -> None: ... + def mtime(self) -> float: ... + def new( + self, + *, + drive: str = ..., + dirname: str = ..., + basename: str = ..., + purebasename: str = ..., + ext: str = ..., + ) -> local: ... + def open(self, mode: str = ..., ensure: bool = ..., encoding: Optional[str] = ...) -> IO[Any]: ... + def parts(self, reverse: bool = ...) -> List[local]: ... + def pyimport( + self, + modname: Optional[str] = ..., + ensuresyspath: Union[bool, Literal["append", "importlib"]] = ..., + ) -> Any: ... + def pypkgpath(self) -> Optional[local]: ... + def read(self, mode: str = ...) -> Union[Text, bytes]: ... + def read_binary(self) -> bytes: ... + def read_text(self, encoding: str) -> Text: ... + def readlines(self, cr: int = ...) -> List[str]: ... + if sys.platform != 'win32': + def readlink(self) -> str: ... + def realpath(self) -> local: ... + def relto(self, relpath: Union[str, local]) -> str: ... + def remove(self, rec: int = ..., ignore_errors: bool = ...) -> None: ... + def rename(self, target: _PathType) -> None: ... + def samefile(self, other: _PathType) -> bool: ... + def setmtime(self, mtime: Optional[float] = ...) -> None: ... + def size(self) -> int: ... + def stat(self, raising: bool = ...) -> _Stat: ... + def sysexec(self, *argv: Any, **popen_opts: Any) -> Text: ... + def visit( + self, + fil: Optional[Union[str, Text, Callable[[local], bool]]] = ..., + rec: Optional[Union[Literal[1, True], str, Text, Callable[[local], bool]]] = ..., + ignore: Type[Exception] = ..., + bf: bool = ..., + sort: bool = ..., + ) -> Iterator[local]: ... + def write(self, data: Any, mode: str = ..., ensure: bool = ...) -> None: ... + def write_binary(self, data: bytes, ensure: bool = ...) -> None: ... + def write_text(self, data: Union[str, Text], encoding: str, ensure: bool = ...) -> None: ... + + +# Untyped types below here. +svnwc: Any +svnurl: Any +SvnAuth: Any diff --git a/dbdpy-env/lib/python3.9/site-packages/py/py.typed b/dbdpy-env/lib/python3.9/site-packages/py/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/py/test.py b/dbdpy-env/lib/python3.9/site-packages/py/test.py new file mode 100644 index 00000000..aa5beb17 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/test.py @@ -0,0 +1,10 @@ +import sys +if __name__ == '__main__': + import pytest + sys.exit(pytest.main()) +else: + import sys, pytest + sys.modules['py.test'] = pytest + +# for more API entry points see the 'tests' definition +# in __init__.py diff --git a/dbdpy-env/lib/python3.9/site-packages/py/xml.pyi b/dbdpy-env/lib/python3.9/site-packages/py/xml.pyi new file mode 100644 index 00000000..9c44480a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/py/xml.pyi @@ -0,0 +1,25 @@ +from typing import ClassVar, Generic, Iterable, Text, Type, Union +from typing_extensions import Final + +class raw: + uniobj: Final[Text] + def __init__(self, uniobj: Text) -> None: ... + +class _NamespaceMetaclass(type): + def __getattr__(self, name: str) -> Type[Tag]: ... + +class Namespace(metaclass=_NamespaceMetaclass): ... + +class Tag(list): + class Attr: + def __getattr__(self, attr: str) -> Text: ... + attr: Final[Attr] + def __init__(self, *args: Union[Text, raw, Tag, Iterable[Tag]], **kwargs: Union[Text, raw]) -> None: ... + def unicode(self, indent: int = ...) -> Text: ... + +class html(Namespace): + class Style: + def __init__(self, **kw: Union[str, Text]) -> None: ... + style: ClassVar[Style] + +def escape(ustring: Union[str, Text]) -> Text: ... diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/LICENSE new file mode 100644 index 00000000..72d9921c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/LICENSE @@ -0,0 +1,25 @@ +Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net> +Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> +Copyright © 2014-2020 Ian Lee <IanLee1521@gmail.com> + +Licensed under the terms of the Expat License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/METADATA new file mode 100644 index 00000000..fd9fcb1e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/METADATA @@ -0,0 +1,131 @@ +Metadata-Version: 2.1 +Name: pycodestyle +Version: 2.11.1 +Summary: Python style guide checker +Home-page: https://pycodestyle.pycqa.org/ +Author: Johann C. Rocholl +Author-email: johann@rocholl.net +Maintainer: Ian Lee +Maintainer-email: IanLee1521@gmail.com +License: MIT +Project-URL: Changes, https://pycodestyle.pycqa.org/en/latest/developer.html#changes +Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8 +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE + +pycodestyle (formerly called pep8) - Python style guide checker +=============================================================== + +.. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg + :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml + :alt: Build status + +.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest + :target: https://pycodestyle.pycqa.org + :alt: Documentation Status + +.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg + :target: https://pypi.org/project/pycodestyle/ + :alt: Wheel Status + +.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg + :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle + :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +pycodestyle is a tool to check your Python code against some of the style +conventions in `PEP 8`_. + +.. _PEP 8: http://www.python.org/dev/peps/pep-0008/ + +.. note:: + + This package used to be called ``pep8`` but was renamed to ``pycodestyle`` + to reduce confusion. Further discussion can be found `in the issue where + Guido requested this + change <https://github.com/PyCQA/pycodestyle/issues/466>`_, or in the + lightning talk at PyCon 2016 by @IanLee1521: + `slides <https://speakerdeck.com/ianlee1521/pep8-vs-pep-8>`_ + `video <https://youtu.be/PulzIT8KYLk?t=36m>`_. + +Features +-------- + +* Plugin architecture: Adding new checks is easy. + +* Parseable output: Jump to error location in your editor. + +* Small: Just one Python file, requires only stdlib. You can use just + the ``pycodestyle.py`` file for this purpose. + +* Comes with a comprehensive test suite. + +Installation +------------ + +You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: + + $ pip install pycodestyle + $ pip install --upgrade pycodestyle + $ pip uninstall pycodestyle + +There's also a package for Debian/Ubuntu, but it's not always the +latest version. + +Example usage and output +------------------------ + +:: + + $ pycodestyle --first optparse.py + optparse.py:69:11: E401 multiple imports on one line + optparse.py:77:1: E302 expected 2 blank lines, found 1 + optparse.py:88:5: E301 expected 1 blank line, found 0 + optparse.py:347:31: E211 whitespace before '(' + optparse.py:357:17: E201 whitespace after '{' + optparse.py:472:29: E221 multiple spaces before operator + +You can also make ``pycodestyle.py`` show the source code for each error, and +even the relevant text from PEP 8:: + + $ pycodestyle --show-source --show-pep8 testing/data/E40.py + testing/data/E40.py:2:10: E401 multiple imports on one line + import os, sys + ^ + Imports should usually be on separate lines. + + Okay: import os\nimport sys + E401: import sys, os + + +Or you can display how often each error was found:: + + $ pycodestyle --statistics -qq Python-2.5/Lib + 232 E201 whitespace after '[' + 599 E202 whitespace before ')' + 631 E203 whitespace before ',' + 842 E211 whitespace before '(' + 2531 E221 multiple spaces before operator + 4473 E301 expected 1 blank line, found 0 + 4006 E302 expected 2 blank lines, found 1 + 165 E303 too many blank lines (4) + 325 E401 multiple imports on one line + 3615 E501 line too long (82 characters) + +Links +----- + +* `Read the documentation <https://pycodestyle.pycqa.org/>`_ + +* `Fork me on GitHub <http://github.com/PyCQA/pycodestyle>`_ diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/RECORD new file mode 100644 index 00000000..9a659c3b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/RECORD @@ -0,0 +1,10 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pycodestyle.cpython-39.pyc,, +../../../bin/pycodestyle,sha256=KCrkWSgZqdwNyl5EuqULDlXdLPeRGb8f01Xy6LbDXCU,247 +pycodestyle-2.11.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pycodestyle-2.11.1.dist-info/LICENSE,sha256=93IpXoGvNHjTTojlLQdiACMOx91qOeEjvFyzWqZqva4,1254 +pycodestyle-2.11.1.dist-info/METADATA,sha256=brzYGoa8G0mb4TyOX4f_kwNMHAX_hZqFrInR-6sQcNU,4533 +pycodestyle-2.11.1.dist-info/RECORD,, +pycodestyle-2.11.1.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110 +pycodestyle-2.11.1.dist-info/entry_points.txt,sha256=MwLE0guIt64aEHtZzaErZQwFVsR4U1jmzn1L_C3RfXo,50 +pycodestyle-2.11.1.dist-info/top_level.txt,sha256=rHbIEiXmvsJ016mFcLVcF_d-dKgP3VdfOB6CWbivZug,12 +pycodestyle.py,sha256=SZfFJaMsom1LSFNWNEev388EMnQI7uPYG-bjhrPk3oo,99725 diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/WHEEL new file mode 100644 index 00000000..f771c29b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/entry_points.txt b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/entry_points.txt new file mode 100644 index 00000000..9b5d849a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +pycodestyle = pycodestyle:_main diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/top_level.txt new file mode 100644 index 00000000..282a93fb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle-2.11.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pycodestyle diff --git a/dbdpy-env/lib/python3.9/site-packages/pycodestyle.py b/dbdpy-env/lib/python3.9/site-packages/pycodestyle.py new file mode 100644 index 00000000..3354346a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pycodestyle.py @@ -0,0 +1,2655 @@ +#!/usr/bin/env python +# pycodestyle.py - Check Python source code formatting, according to +# PEP 8 +# +# Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net> +# Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> +# Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com> +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +r""" +Check Python source code formatting, according to PEP 8. + +For usage and a list of options, try this: +$ python pycodestyle.py -h + +This program and its regression test suite live here: +https://github.com/pycqa/pycodestyle + +Groups of errors and warnings: +E errors +W warnings +100 indentation +200 whitespace +300 blank lines +400 imports +500 line length +600 deprecation +700 statements +900 syntax error +""" +import bisect +import configparser +import inspect +import io +import keyword +import os +import re +import sys +import time +import tokenize +import warnings +from fnmatch import fnmatch +from functools import lru_cache +from optparse import OptionParser + +# this is a performance hack. see https://bugs.python.org/issue43014 +if ( + sys.version_info < (3, 10) and + callable(getattr(tokenize, '_compile', None)) +): # pragma: no cover (<py310) + tokenize._compile = lru_cache(tokenize._compile) # type: ignore + +__version__ = '2.11.1' + +DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' +DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' +try: + if sys.platform == 'win32': # pragma: win32 cover + USER_CONFIG = os.path.expanduser(r'~\.pycodestyle') + else: # pragma: win32 no cover + USER_CONFIG = os.path.join( + os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), + 'pycodestyle' + ) +except ImportError: + USER_CONFIG = None + +PROJECT_CONFIG = ('setup.cfg', 'tox.ini') +MAX_LINE_LENGTH = 79 +# Number of blank lines between various code parts. +BLANK_LINES_CONFIG = { + # Top level class and function. + 'top_level': 2, + # Methods and nested class and function. + 'method': 1, +} +MAX_DOC_LENGTH = 72 +INDENT_SIZE = 4 +REPORT_FORMAT = { + 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', + 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', +} + +PyCF_ONLY_AST = 1024 +SINGLETONS = frozenset(['False', 'None', 'True']) +KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS +UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) +ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-', '@']) +WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) +WS_NEEDED_OPERATORS = frozenset([ + '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<', '>', + '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=', + 'and', 'in', 'is', 'or', '->', ':=']) +WHITESPACE = frozenset(' \t\xa0') +NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) +SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) +# ERRORTOKEN is triggered by backticks in Python 3 +SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) +BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] + +INDENT_REGEX = re.compile(r'([ \t]*)') +ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') +DOCSTRING_REGEX = re.compile(r'u?r?["\']') +EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[\[({][ \t]|[ \t][\]}),;:](?!=)') +WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') +COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)' + r'\s*(?(1)|(None|False|True))\b') +COMPARE_NEGATIVE_REGEX = re.compile(r'\b(?<!is\s)(not)\s+[^][)(}{ ]+\s+' + r'(in|is)\s') +COMPARE_TYPE_REGEX = re.compile( + r'[=!]=\s+type(?:\s*\(\s*([^)]*[^ )])\s*\))' + r'|\btype(?:\s*\(\s*([^)]*[^ )])\s*\))\s+[=!]=' +) +KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS)) +OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+|:=)(\s*)') +LAMBDA_REGEX = re.compile(r'\blambda\b') +HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') +STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\b') +STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)') +STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( + r'^\s*({})\b'.format('|'.join(s.replace(' ', r'\s+') for s in ( + 'def', 'async def', + 'for', 'async for', + 'if', 'elif', 'else', + 'try', 'except', 'finally', + 'with', 'async with', + 'class', + 'while', + ))) +) +DUNDER_REGEX = re.compile(r"^__([^\s]+)__(?::\s*[a-zA-Z.0-9_\[\]\"]+)? = ") +BLANK_EXCEPT_REGEX = re.compile(r"except\s*:") + +if sys.version_info >= (3, 12): # pragma: >=3.12 cover + FSTRING_START = tokenize.FSTRING_START + FSTRING_MIDDLE = tokenize.FSTRING_MIDDLE + FSTRING_END = tokenize.FSTRING_END +else: # pragma: <3.12 cover + FSTRING_START = FSTRING_MIDDLE = FSTRING_END = -1 + +_checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} + + +def _get_parameters(function): + return [parameter.name + for parameter + in inspect.signature(function).parameters.values() + if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] + + +def register_check(check, codes=None): + """Register a new check object.""" + def _add_check(check, kind, codes, args): + if check in _checks[kind]: + _checks[kind][check][0].extend(codes or []) + else: + _checks[kind][check] = (codes or [''], args) + if inspect.isfunction(check): + args = _get_parameters(check) + if args and args[0] in ('physical_line', 'logical_line'): + if codes is None: + codes = ERRORCODE_REGEX.findall(check.__doc__ or '') + _add_check(check, args[0], codes, args) + elif inspect.isclass(check): + if _get_parameters(check.__init__)[:2] == ['self', 'tree']: + _add_check(check, 'tree', codes, None) + return check + + +######################################################################## +# Plugins (check functions) for physical lines +######################################################################## + +@register_check +def tabs_or_spaces(physical_line, indent_char): + r"""Never mix tabs and spaces. + + The most popular way of indenting Python is with spaces only. The + second-most popular way is with tabs only. Code indented with a + mixture of tabs and spaces should be converted to using spaces + exclusively. When invoking the Python command line interpreter with + the -t option, it issues warnings about code that illegally mixes + tabs and spaces. When using -tt these warnings become errors. + These options are highly recommended! + + Okay: if a == 0:\n a = 1\n b = 1 + """ + indent = INDENT_REGEX.match(physical_line).group(1) + for offset, char in enumerate(indent): + if char != indent_char: + return offset, "E101 indentation contains mixed spaces and tabs" + + +@register_check +def tabs_obsolete(physical_line): + r"""On new projects, spaces-only are strongly recommended over tabs. + + Okay: if True:\n return + W191: if True:\n\treturn + """ + indent = INDENT_REGEX.match(physical_line).group(1) + if '\t' in indent: + return indent.index('\t'), "W191 indentation contains tabs" + + +@register_check +def trailing_whitespace(physical_line): + r"""Trailing whitespace is superfluous. + + The warning returned varies on whether the line itself is blank, + for easier filtering for those who want to indent their blank lines. + + Okay: spam(1)\n# + W291: spam(1) \n# + W293: class Foo(object):\n \n bang = 12 + """ + physical_line = physical_line.rstrip('\n') # chr(10), newline + physical_line = physical_line.rstrip('\r') # chr(13), carriage return + physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L + stripped = physical_line.rstrip(' \t\v') + if physical_line != stripped: + if stripped: + return len(stripped), "W291 trailing whitespace" + else: + return 0, "W293 blank line contains whitespace" + + +@register_check +def trailing_blank_lines(physical_line, lines, line_number, total_lines): + r"""Trailing blank lines are superfluous. + + Okay: spam(1) + W391: spam(1)\n + + However the last line should end with a new line (warning W292). + """ + if line_number == total_lines: + stripped_last_line = physical_line.rstrip('\r\n') + if physical_line and not stripped_last_line: + return 0, "W391 blank line at end of file" + if stripped_last_line == physical_line: + return len(lines[-1]), "W292 no newline at end of file" + + +@register_check +def maximum_line_length(physical_line, max_line_length, multiline, + line_number, noqa): + r"""Limit all lines to a maximum of 79 characters. + + There are still many devices around that are limited to 80 character + lines; plus, limiting windows to 80 characters makes it possible to + have several windows side-by-side. The default wrapping on such + devices looks ugly. Therefore, please limit all lines to a maximum + of 79 characters. For flowing long blocks of text (docstrings or + comments), limiting the length to 72 characters is recommended. + + Reports error E501. + """ + line = physical_line.rstrip() + length = len(line) + if length > max_line_length and not noqa: + # Special case: ignore long shebang lines. + if line_number == 1 and line.startswith('#!'): + return + # Special case for long URLs in multi-line docstrings or + # comments, but still report the error when the 72 first chars + # are whitespaces. + chunks = line.split() + if ((len(chunks) == 1 and multiline) or + (len(chunks) == 2 and chunks[0] == '#')) and \ + len(line) - len(chunks[-1]) < max_line_length - 7: + return + if length > max_line_length: + return (max_line_length, "E501 line too long " + "(%d > %d characters)" % (length, max_line_length)) + + +######################################################################## +# Plugins (check functions) for logical lines +######################################################################## + + +def _is_one_liner(logical_line, indent_level, lines, line_number): + if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): + return False + + line_idx = line_number - 1 + + if line_idx < 1: + prev_indent = 0 + else: + prev_indent = expand_indent(lines[line_idx - 1]) + + if prev_indent > indent_level: + return False + + while line_idx < len(lines): + line = lines[line_idx].strip() + if not line.startswith('@') and STARTSWITH_TOP_LEVEL_REGEX.match(line): + break + else: + line_idx += 1 + else: + return False # invalid syntax: EOF while searching for def/class + + next_idx = line_idx + 1 + while next_idx < len(lines): + if lines[next_idx].strip(): + break + else: + next_idx += 1 + else: + return True # line is last in the file + + return expand_indent(lines[next_idx]) <= indent_level + + +@register_check +def blank_lines(logical_line, blank_lines, indent_level, line_number, + blank_before, previous_logical, + previous_unindented_logical_line, previous_indent_level, + lines): + r"""Separate top-level function and class definitions with two blank + lines. + + Method definitions inside a class are separated by a single blank + line. + + Extra blank lines may be used (sparingly) to separate groups of + related functions. Blank lines may be omitted between a bunch of + related one-liners (e.g. a set of dummy implementations). + + Use blank lines in functions, sparingly, to indicate logical + sections. + + Okay: def a():\n pass\n\n\ndef b():\n pass + Okay: def a():\n pass\n\n\nasync def b():\n pass + Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass + Okay: default = 1\nfoo = 1 + Okay: classify = 1\nfoo = 1 + + E301: class Foo:\n b = 0\n def bar():\n pass + E302: def a():\n pass\n\ndef b(n):\n pass + E302: def a():\n pass\n\nasync def b(n):\n pass + E303: def a():\n pass\n\n\n\ndef b(n):\n pass + E303: def a():\n\n\n\n pass + E304: @decorator\n\ndef a():\n pass + E305: def a():\n pass\na() + E306: def a():\n def b():\n pass\n def c():\n pass + """ # noqa + top_level_lines = BLANK_LINES_CONFIG['top_level'] + method_lines = BLANK_LINES_CONFIG['method'] + + if not previous_logical and blank_before < top_level_lines: + return # Don't expect blank lines before the first line + if previous_logical.startswith('@'): + if blank_lines: + yield 0, "E304 blank lines found after function decorator" + elif (blank_lines > top_level_lines or + (indent_level and blank_lines == method_lines + 1) + ): + yield 0, "E303 too many blank lines (%d)" % blank_lines + elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): + # allow a group of one-liners + if ( + _is_one_liner(logical_line, indent_level, lines, line_number) and + blank_before == 0 + ): + return + if indent_level: + if not (blank_before == method_lines or + previous_indent_level < indent_level or + DOCSTRING_REGEX.match(previous_logical) + ): + ancestor_level = indent_level + nested = False + # Search backwards for a def ancestor or tree root + # (top level). + for line in lines[line_number - top_level_lines::-1]: + if line.strip() and expand_indent(line) < ancestor_level: + ancestor_level = expand_indent(line) + nested = STARTSWITH_DEF_REGEX.match(line.lstrip()) + if nested or ancestor_level == 0: + break + if nested: + yield 0, "E306 expected %s blank line before a " \ + "nested definition, found 0" % (method_lines,) + else: + yield 0, "E301 expected {} blank line, found 0".format( + method_lines) + elif blank_before != top_level_lines: + yield 0, "E302 expected %s blank lines, found %d" % ( + top_level_lines, blank_before) + elif (logical_line and + not indent_level and + blank_before != top_level_lines and + previous_unindented_logical_line.startswith(('def ', 'class ')) + ): + yield 0, "E305 expected %s blank lines after " \ + "class or function definition, found %d" % ( + top_level_lines, blank_before) + + +@register_check +def extraneous_whitespace(logical_line): + r"""Avoid extraneous whitespace. + + Avoid extraneous whitespace in these situations: + - Immediately inside parentheses, brackets or braces. + - Immediately before a comma, semicolon, or colon. + + Okay: spam(ham[1], {eggs: 2}) + E201: spam( ham[1], {eggs: 2}) + E201: spam(ham[ 1], {eggs: 2}) + E201: spam(ham[1], { eggs: 2}) + E202: spam(ham[1], {eggs: 2} ) + E202: spam(ham[1 ], {eggs: 2}) + E202: spam(ham[1], {eggs: 2 }) + + E203: if x == 4: print x, y; x, y = y , x + E203: if x == 4: print x, y ; x, y = y, x + E203: if x == 4 : print x, y; x, y = y, x + """ + line = logical_line + for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): + text = match.group() + char = text.strip() + found = match.start() + if text[-1].isspace(): + # assert char in '([{' + yield found + 1, "E201 whitespace after '%s'" % char + elif line[found - 1] != ',': + code = ('E202' if char in '}])' else 'E203') # if char in ',;:' + yield found, f"{code} whitespace before '{char}'" + + +@register_check +def whitespace_around_keywords(logical_line): + r"""Avoid extraneous whitespace around keywords. + + Okay: True and False + E271: True and False + E272: True and False + E273: True and\tFalse + E274: True\tand False + """ + for match in KEYWORD_REGEX.finditer(logical_line): + before, after = match.groups() + + if '\t' in before: + yield match.start(1), "E274 tab before keyword" + elif len(before) > 1: + yield match.start(1), "E272 multiple spaces before keyword" + + if '\t' in after: + yield match.start(2), "E273 tab after keyword" + elif len(after) > 1: + yield match.start(2), "E271 multiple spaces after keyword" + + +@register_check +def missing_whitespace_after_keyword(logical_line, tokens): + r"""Keywords should be followed by whitespace. + + Okay: from foo import (bar, baz) + E275: from foo import(bar, baz) + E275: from importable.module import(bar, baz) + E275: if(foo): bar + """ + for tok0, tok1 in zip(tokens, tokens[1:]): + # This must exclude the True/False/None singletons, which can + # appear e.g. as "if x is None:", and async/await, which were + # valid identifier names in old Python versions. + if (tok0.end == tok1.start and + tok0.type == tokenize.NAME and + keyword.iskeyword(tok0.string) and + tok0.string not in SINGLETONS and + not (tok0.string == 'except' and tok1.string == '*') and + not (tok0.string == 'yield' and tok1.string == ')') and + tok1.string not in ':\n'): + yield tok0.end, "E275 missing whitespace after keyword" + + +@register_check +def indentation(logical_line, previous_logical, indent_char, + indent_level, previous_indent_level, + indent_size): + r"""Use indent_size (PEP8 says 4) spaces per indentation level. + + For really old code that you don't want to mess up, you can continue + to use 8-space tabs. + + Okay: a = 1 + Okay: if a == 0:\n a = 1 + E111: a = 1 + E114: # a = 1 + + Okay: for item in items:\n pass + E112: for item in items:\npass + E115: for item in items:\n# Hi\n pass + + Okay: a = 1\nb = 2 + E113: a = 1\n b = 2 + E116: a = 1\n # b = 2 + """ + c = 0 if logical_line else 3 + tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" + if indent_level % indent_size: + yield 0, tmpl % ( + 1 + c, + "indentation is not a multiple of " + str(indent_size), + ) + indent_expect = previous_logical.endswith(':') + if indent_expect and indent_level <= previous_indent_level: + yield 0, tmpl % (2 + c, "expected an indented block") + elif not indent_expect and indent_level > previous_indent_level: + yield 0, tmpl % (3 + c, "unexpected indentation") + + if indent_expect: + expected_indent_amount = 8 if indent_char == '\t' else 4 + expected_indent_level = previous_indent_level + expected_indent_amount + if indent_level > expected_indent_level: + yield 0, tmpl % (7, 'over-indented') + + +@register_check +def continued_indentation(logical_line, tokens, indent_level, hang_closing, + indent_char, indent_size, noqa, verbose): + r"""Continuation lines indentation. + + Continuation lines should align wrapped elements either vertically + using Python's implicit line joining inside parentheses, brackets + and braces, or using a hanging indent. + + When using a hanging indent these considerations should be applied: + - there should be no arguments on the first line, and + - further indentation should be used to clearly distinguish itself + as a continuation line. + + Okay: a = (\n) + E123: a = (\n ) + + Okay: a = (\n 42) + E121: a = (\n 42) + E122: a = (\n42) + E123: a = (\n 42\n ) + E124: a = (24,\n 42\n) + E125: if (\n b):\n pass + E126: a = (\n 42) + E127: a = (24,\n 42) + E128: a = (24,\n 42) + E129: if (a or\n b):\n pass + E131: a = (\n 42\n 24) + """ + first_row = tokens[0][2][0] + nrows = 1 + tokens[-1][2][0] - first_row + if noqa or nrows == 1: + return + + # indent_next tells us whether the next block is indented; assuming + # that it is indented by 4 spaces, then we should not allow 4-space + # indents on the final continuation line; in turn, some other + # indents are allowed to have an extra 4 spaces. + indent_next = logical_line.endswith(':') + + row = depth = 0 + valid_hangs = (indent_size,) if indent_char != '\t' \ + else (indent_size, indent_size * 2) + # remember how many brackets were opened on each line + parens = [0] * nrows + # relative indents of physical lines + rel_indent = [0] * nrows + # for each depth, collect a list of opening rows + open_rows = [[0]] + # for each depth, memorize the hanging indentation + hangs = [None] + # visual indents + indent_chances = {} + last_indent = tokens[0][2] + visual_indent = None + last_token_multiline = False + # for each depth, memorize the visual indent column + indent = [last_indent[1]] + if verbose >= 3: + print(">>> " + tokens[0][4].rstrip()) + + for token_type, text, start, end, line in tokens: + + newline = row < start[0] - first_row + if newline: + row = start[0] - first_row + newline = not last_token_multiline and token_type not in NEWLINE + + if newline: + # this is the beginning of a continuation line. + last_indent = start + if verbose >= 3: + print("... " + line.rstrip()) + + # record the initial indent. + rel_indent[row] = expand_indent(line) - indent_level + + # identify closing bracket + close_bracket = (token_type == tokenize.OP and text in ']})') + + # is the indent relative to an opening bracket line? + for open_row in reversed(open_rows[depth]): + hang = rel_indent[row] - rel_indent[open_row] + hanging_indent = hang in valid_hangs + if hanging_indent: + break + if hangs[depth]: + hanging_indent = (hang == hangs[depth]) + # is there any chance of visual indent? + visual_indent = (not close_bracket and hang > 0 and + indent_chances.get(start[1])) + + if close_bracket and indent[depth]: + # closing bracket for visual indent + if start[1] != indent[depth]: + yield (start, "E124 closing bracket does not match " + "visual indentation") + elif close_bracket and not hang: + # closing bracket matches indentation of opening + # bracket's line + if hang_closing: + yield start, "E133 closing bracket is missing indentation" + elif indent[depth] and start[1] < indent[depth]: + if visual_indent is not True: + # visual indent is broken + yield (start, "E128 continuation line " + "under-indented for visual indent") + elif hanging_indent or (indent_next and + rel_indent[row] == 2 * indent_size): + # hanging indent is verified + if close_bracket and not hang_closing: + yield (start, "E123 closing bracket does not match " + "indentation of opening bracket's line") + hangs[depth] = hang + elif visual_indent is True: + # visual indent is verified + indent[depth] = start[1] + elif visual_indent in (text, str): + # ignore token lined up with matching one from a + # previous line + pass + else: + # indent is broken + if hang <= 0: + error = "E122", "missing indentation or outdented" + elif indent[depth]: + error = "E127", "over-indented for visual indent" + elif not close_bracket and hangs[depth]: + error = "E131", "unaligned for hanging indent" + else: + hangs[depth] = hang + if hang > indent_size: + error = "E126", "over-indented for hanging indent" + else: + error = "E121", "under-indented for hanging indent" + yield start, "%s continuation line %s" % error + + # look for visual indenting + if (parens[row] and + token_type not in (tokenize.NL, tokenize.COMMENT) and + not indent[depth]): + indent[depth] = start[1] + indent_chances[start[1]] = True + if verbose >= 4: + print(f"bracket depth {depth} indent to {start[1]}") + # deal with implicit string concatenation + elif token_type in (tokenize.STRING, tokenize.COMMENT, FSTRING_START): + indent_chances[start[1]] = str + # visual indent after assert/raise/with + elif not row and not depth and text in ["assert", "raise", "with"]: + indent_chances[end[1] + 1] = True + # special case for the "if" statement because len("if (") == 4 + elif not indent_chances and not row and not depth and text == 'if': + indent_chances[end[1] + 1] = True + elif text == ':' and line[end[1]:].isspace(): + open_rows[depth].append(row) + + # keep track of bracket depth + if token_type == tokenize.OP: + if text in '([{': + depth += 1 + indent.append(0) + hangs.append(None) + if len(open_rows) == depth: + open_rows.append([]) + open_rows[depth].append(row) + parens[row] += 1 + if verbose >= 4: + print("bracket depth %s seen, col %s, visual min = %s" % + (depth, start[1], indent[depth])) + elif text in ')]}' and depth > 0: + # parent indents should not be more than this one + prev_indent = indent.pop() or last_indent[1] + hangs.pop() + for d in range(depth): + if indent[d] > prev_indent: + indent[d] = 0 + for ind in list(indent_chances): + if ind >= prev_indent: + del indent_chances[ind] + del open_rows[depth + 1:] + depth -= 1 + if depth: + indent_chances[indent[depth]] = True + for idx in range(row, -1, -1): + if parens[idx]: + parens[idx] -= 1 + break + assert len(indent) == depth + 1 + if start[1] not in indent_chances: + # allow lining up tokens + indent_chances[start[1]] = text + + last_token_multiline = (start[0] != end[0]) + if last_token_multiline: + rel_indent[end[0] - first_row] = rel_indent[row] + + if indent_next and expand_indent(line) == indent_level + indent_size: + pos = (start[0], indent[0] + indent_size) + if visual_indent: + code = "E129 visually indented line" + else: + code = "E125 continuation line" + yield pos, "%s with same indent as next logical line" % code + + +@register_check +def whitespace_before_parameters(logical_line, tokens): + r"""Avoid extraneous whitespace. + + Avoid extraneous whitespace in the following situations: + - before the open parenthesis that starts the argument list of a + function call. + - before the open parenthesis that starts an indexing or slicing. + + Okay: spam(1) + E211: spam (1) + + Okay: dict['key'] = list[index] + E211: dict ['key'] = list[index] + E211: dict['key'] = list [index] + """ + prev_type, prev_text, __, prev_end, __ = tokens[0] + for index in range(1, len(tokens)): + token_type, text, start, end, __ = tokens[index] + if ( + token_type == tokenize.OP and + text in '([' and + start != prev_end and + (prev_type == tokenize.NAME or prev_text in '}])') and + # Syntax "class A (B):" is allowed, but avoid it + (index < 2 or tokens[index - 2][1] != 'class') and + # Allow "return (a.foo for a in range(5))" + not keyword.iskeyword(prev_text) and + ( + sys.version_info < (3, 9) or + # 3.12+: type is a soft keyword but no braces after + prev_text == 'type' or + not keyword.issoftkeyword(prev_text) + ) + ): + yield prev_end, "E211 whitespace before '%s'" % text + prev_type = token_type + prev_text = text + prev_end = end + + +@register_check +def whitespace_around_operator(logical_line): + r"""Avoid extraneous whitespace around an operator. + + Okay: a = 12 + 3 + E221: a = 4 + 5 + E222: a = 4 + 5 + E223: a = 4\t+ 5 + E224: a = 4 +\t5 + """ + for match in OPERATOR_REGEX.finditer(logical_line): + before, after = match.groups() + + if '\t' in before: + yield match.start(1), "E223 tab before operator" + elif len(before) > 1: + yield match.start(1), "E221 multiple spaces before operator" + + if '\t' in after: + yield match.start(2), "E224 tab after operator" + elif len(after) > 1: + yield match.start(2), "E222 multiple spaces after operator" + + +@register_check +def missing_whitespace(logical_line, tokens): + r"""Surround operators with the correct amount of whitespace. + + - Always surround these binary operators with a single space on + either side: assignment (=), augmented assignment (+=, -= etc.), + comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), + Booleans (and, or, not). + + - Each comma, semicolon or colon should be followed by whitespace. + + - If operators with different priorities are used, consider adding + whitespace around the operators with the lowest priorities. + + Okay: i = i + 1 + Okay: submitted += 1 + Okay: x = x * 2 - 1 + Okay: hypot2 = x * x + y * y + Okay: c = (a + b) * (a - b) + Okay: foo(bar, key='word', *args, **kwargs) + Okay: alpha[:-i] + Okay: [a, b] + Okay: (3,) + Okay: a[3,] = 1 + Okay: a[1:4] + Okay: a[:4] + Okay: a[1:] + Okay: a[1:4:2] + + E225: i=i+1 + E225: submitted +=1 + E225: x = x /2 - 1 + E225: z = x **y + E225: z = 1and 1 + E226: c = (a+b) * (a-b) + E226: hypot2 = x*x + y*y + E227: c = a|b + E228: msg = fmt%(errno, errmsg) + E231: ['a','b'] + E231: foo(bar,baz) + E231: [{'a':'b'}] + """ + need_space = False + prev_type = tokenize.OP + prev_text = prev_end = None + operator_types = (tokenize.OP, tokenize.NAME) + brace_stack = [] + for token_type, text, start, end, line in tokens: + if token_type == tokenize.OP and text in {'[', '(', '{'}: + brace_stack.append(text) + elif token_type == FSTRING_START: # pragma: >=3.12 cover + brace_stack.append('f') + elif token_type == tokenize.NAME and text == 'lambda': + brace_stack.append('l') + elif brace_stack: + if token_type == tokenize.OP and text in {']', ')', '}'}: + brace_stack.pop() + elif token_type == FSTRING_END: # pragma: >=3.12 cover + brace_stack.pop() + elif ( + brace_stack[-1] == 'l' and + token_type == tokenize.OP and + text == ':' + ): + brace_stack.pop() + + if token_type in SKIP_COMMENTS: + continue + + if token_type == tokenize.OP and text in {',', ';', ':'}: + next_char = line[end[1]:end[1] + 1] + if next_char not in WHITESPACE and next_char not in '\r\n': + # slice + if text == ':' and brace_stack[-1:] == ['[']: + pass + # 3.12+ fstring format specifier + elif text == ':' and brace_stack[-2:] == ['f', '{']: # pragma: >=3.12 cover # noqa: E501 + pass + # tuple (and list for some reason?) + elif text == ',' and next_char in ')]': + pass + else: + yield start, f'E231 missing whitespace after {text!r}' + + if need_space: + if start != prev_end: + # Found a (probably) needed space + if need_space is not True and not need_space[1]: + yield (need_space[0], + "E225 missing whitespace around operator") + need_space = False + elif ( + # def f(a, /, b): + # ^ + # def f(a, b, /): + # ^ + # f = lambda a, /: + # ^ + prev_text == '/' and text in {',', ')', ':'} or + # def f(a, b, /): + # ^ + prev_text == ')' and text == ':' + ): + # Tolerate the "/" operator in function definition + # For more info see PEP570 + pass + else: + if need_space is True or need_space[1]: + # A needed trailing space was not found + yield prev_end, "E225 missing whitespace around operator" + elif prev_text != '**': + code, optype = 'E226', 'arithmetic' + if prev_text == '%': + code, optype = 'E228', 'modulo' + elif prev_text not in ARITHMETIC_OP: + code, optype = 'E227', 'bitwise or shift' + yield (need_space[0], "%s missing whitespace " + "around %s operator" % (code, optype)) + need_space = False + elif token_type in operator_types and prev_end is not None: + if ( + text == '=' and ( + # allow lambda default args: lambda x=None: None + brace_stack[-1:] == ['l'] or + # allow keyword args or defaults: foo(bar=None). + brace_stack[-1:] == ['('] or + # allow python 3.8 fstring repr specifier + brace_stack[-2:] == ['f', '{'] + ) + ): + pass + elif text in WS_NEEDED_OPERATORS: + need_space = True + elif text in UNARY_OPERATORS: + # Check if the operator is used as a binary operator + # Allow unary operators: -123, -x, +1. + # Allow argument unpacking: foo(*args, **kwargs). + if prev_type == tokenize.OP and prev_text in '}])' or ( + prev_type != tokenize.OP and + prev_text not in KEYWORDS and ( + sys.version_info < (3, 9) or + not keyword.issoftkeyword(prev_text) + ) + ): + need_space = None + elif text in WS_OPTIONAL_OPERATORS: + need_space = None + + if need_space is None: + # Surrounding space is optional, but ensure that + # trailing space matches opening space + need_space = (prev_end, start != prev_end) + elif need_space and start == prev_end: + # A needed opening space was not found + yield prev_end, "E225 missing whitespace around operator" + need_space = False + prev_type = token_type + prev_text = text + prev_end = end + + +@register_check +def whitespace_around_comma(logical_line): + r"""Avoid extraneous whitespace after a comma or a colon. + + Note: these checks are disabled by default + + Okay: a = (1, 2) + E241: a = (1, 2) + E242: a = (1,\t2) + """ + line = logical_line + for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): + found = m.start() + 1 + if '\t' in m.group(): + yield found, "E242 tab after '%s'" % m.group()[0] + else: + yield found, "E241 multiple spaces after '%s'" % m.group()[0] + + +@register_check +def whitespace_around_named_parameter_equals(logical_line, tokens): + r"""Don't use spaces around the '=' sign in function arguments. + + Don't use spaces around the '=' sign when used to indicate a + keyword argument or a default parameter value, except when + using a type annotation. + + Okay: def complex(real, imag=0.0): + Okay: return magic(r=real, i=imag) + Okay: boolean(a == b) + Okay: boolean(a != b) + Okay: boolean(a <= b) + Okay: boolean(a >= b) + Okay: def foo(arg: int = 42): + Okay: async def foo(arg: int = 42): + + E251: def complex(real, imag = 0.0): + E251: return magic(r = real, i = imag) + E252: def complex(real, image: float=0.0): + """ + parens = 0 + no_space = False + require_space = False + prev_end = None + annotated_func_arg = False + in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line)) + + message = "E251 unexpected spaces around keyword / parameter equals" + missing_message = "E252 missing whitespace around parameter equals" + + for token_type, text, start, end, line in tokens: + if token_type == tokenize.NL: + continue + if no_space: + no_space = False + if start != prev_end: + yield (prev_end, message) + if require_space: + require_space = False + if start == prev_end: + yield (prev_end, missing_message) + if token_type == tokenize.OP: + if text in '([': + parens += 1 + elif text in ')]': + parens -= 1 + elif in_def and text == ':' and parens == 1: + annotated_func_arg = True + elif parens == 1 and text == ',': + annotated_func_arg = False + elif parens and text == '=': + if annotated_func_arg and parens == 1: + require_space = True + if start == prev_end: + yield (prev_end, missing_message) + else: + no_space = True + if start != prev_end: + yield (prev_end, message) + if not parens: + annotated_func_arg = False + + prev_end = end + + +@register_check +def whitespace_before_comment(logical_line, tokens): + """Separate inline comments by at least two spaces. + + An inline comment is a comment on the same line as a statement. + Inline comments should be separated by at least two spaces from the + statement. They should start with a # and a single space. + + Each line of a block comment starts with a # and one or multiple + spaces as there can be indented text inside the comment. + + Okay: x = x + 1 # Increment x + Okay: x = x + 1 # Increment x + Okay: # Block comments: + Okay: # - Block comment list + Okay: # \xa0- Block comment list + E261: x = x + 1 # Increment x + E262: x = x + 1 #Increment x + E262: x = x + 1 # Increment x + E262: x = x + 1 # \xa0Increment x + E265: #Block comment + E266: ### Block comment + """ + prev_end = (0, 0) + for token_type, text, start, end, line in tokens: + if token_type == tokenize.COMMENT: + inline_comment = line[:start[1]].strip() + if inline_comment: + if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: + yield (prev_end, + "E261 at least two spaces before inline comment") + symbol, sp, comment = text.partition(' ') + bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#') + if inline_comment: + if bad_prefix or comment[:1] in WHITESPACE: + yield start, "E262 inline comment should start with '# '" + elif bad_prefix and (bad_prefix != '!' or start[0] > 1): + if bad_prefix != '#': + yield start, "E265 block comment should start with '# '" + elif comment: + yield start, "E266 too many leading '#' for block comment" + elif token_type != tokenize.NL: + prev_end = end + + +@register_check +def imports_on_separate_lines(logical_line): + r"""Place imports on separate lines. + + Okay: import os\nimport sys + E401: import sys, os + + Okay: from subprocess import Popen, PIPE + Okay: from myclas import MyClass + Okay: from foo.bar.yourclass import YourClass + Okay: import myclass + Okay: import foo.bar.yourclass + """ + line = logical_line + if line.startswith('import '): + found = line.find(',') + if -1 < found and ';' not in line[:found]: + yield found, "E401 multiple imports on one line" + + +@register_check +def module_imports_on_top_of_file( + logical_line, indent_level, checker_state, noqa): + r"""Place imports at the top of the file. + + Always put imports at the top of the file, just after any module + comments and docstrings, and before module globals and constants. + + Okay: import os + Okay: # this is a comment\nimport os + Okay: '''this is a module docstring'''\nimport os + Okay: r'''this is a module docstring'''\nimport os + E402: a=1\nimport os + E402: 'One string'\n"Two string"\nimport os + E402: a=1\nfrom sys import x + + Okay: if x:\n import os + """ # noqa + def is_string_literal(line): + if line[0] in 'uUbB': + line = line[1:] + if line and line[0] in 'rR': + line = line[1:] + return line and (line[0] == '"' or line[0] == "'") + + allowed_keywords = ( + 'try', 'except', 'else', 'finally', 'with', 'if', 'elif') + + if indent_level: # Allow imports in conditional statement/function + return + if not logical_line: # Allow empty lines or comments + return + if noqa: + return + line = logical_line + if line.startswith('import ') or line.startswith('from '): + if checker_state.get('seen_non_imports', False): + yield 0, "E402 module level import not at top of file" + elif re.match(DUNDER_REGEX, line): + return + elif any(line.startswith(kw) for kw in allowed_keywords): + # Allow certain keywords intermixed with imports in order to + # support conditional or filtered importing + return + elif is_string_literal(line): + # The first literal is a docstring, allow it. Otherwise, report + # error. + if checker_state.get('seen_docstring', False): + checker_state['seen_non_imports'] = True + else: + checker_state['seen_docstring'] = True + else: + checker_state['seen_non_imports'] = True + + +@register_check +def compound_statements(logical_line): + r"""Compound statements (on the same line) are generally + discouraged. + + While sometimes it's okay to put an if/for/while with a small body + on the same line, never do this for multi-clause statements. + Also avoid folding such long lines! + + Always use a def statement instead of an assignment statement that + binds a lambda expression directly to a name. + + Okay: if foo == 'blah':\n do_blah_thing() + Okay: do_one() + Okay: do_two() + Okay: do_three() + + E701: if foo == 'blah': do_blah_thing() + E701: for x in lst: total += x + E701: while t < 10: t = delay() + E701: if foo == 'blah': do_blah_thing() + E701: else: do_non_blah_thing() + E701: try: something() + E701: finally: cleanup() + E701: if foo == 'blah': one(); two(); three() + E702: do_one(); do_two(); do_three() + E703: do_four(); # useless semicolon + E704: def f(x): return 2*x + E731: f = lambda x: 2*x + """ + line = logical_line + last_char = len(line) - 1 + found = line.find(':') + prev_found = 0 + counts = {char: 0 for char in '{}[]()'} + while -1 < found < last_char: + update_counts(line[prev_found:found], counts) + if ( + counts['{'] <= counts['}'] and # {'a': 1} (dict) + counts['['] <= counts[']'] and # [1:2] (slice) + counts['('] <= counts[')'] and # (annotation) + line[found + 1] != '=' # assignment expression + ): + lambda_kw = LAMBDA_REGEX.search(line, 0, found) + if lambda_kw: + before = line[:lambda_kw.start()].rstrip() + if before[-1:] == '=' and before[:-1].strip().isidentifier(): + yield 0, ("E731 do not assign a lambda expression, use a " + "def") + break + if STARTSWITH_DEF_REGEX.match(line): + yield 0, "E704 multiple statements on one line (def)" + elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): + yield found, "E701 multiple statements on one line (colon)" + prev_found = found + found = line.find(':', found + 1) + found = line.find(';') + while -1 < found: + if found < last_char: + yield found, "E702 multiple statements on one line (semicolon)" + else: + yield found, "E703 statement ends with a semicolon" + found = line.find(';', found + 1) + + +@register_check +def explicit_line_join(logical_line, tokens): + r"""Avoid explicit line join between brackets. + + The preferred way of wrapping long lines is by using Python's + implied line continuation inside parentheses, brackets and braces. + Long lines can be broken over multiple lines by wrapping expressions + in parentheses. These should be used in preference to using a + backslash for line continuation. + + E502: aaa = [123, \\n 123] + E502: aaa = ("bbb " \\n "ccc") + + Okay: aaa = [123,\n 123] + Okay: aaa = ("bbb "\n "ccc") + Okay: aaa = "bbb " \\n "ccc" + Okay: aaa = 123 # \\ + """ + prev_start = prev_end = parens = 0 + comment = False + backslash = None + for token_type, text, start, end, line in tokens: + if token_type == tokenize.COMMENT: + comment = True + if start[0] != prev_start and parens and backslash and not comment: + yield backslash, "E502 the backslash is redundant between brackets" + if end[0] != prev_end: + if line.rstrip('\r\n').endswith('\\'): + backslash = (end[0], len(line.splitlines()[-1]) - 1) + else: + backslash = None + prev_start = prev_end = end[0] + else: + prev_start = start[0] + if token_type == tokenize.OP: + if text in '([{': + parens += 1 + elif text in ')]}': + parens -= 1 + + +# The % character is strictly speaking a binary operator, but the +# common usage seems to be to put it next to the format parameters, +# after a line break. +_SYMBOLIC_OPS = frozenset("()[]{},:.;@=%~") | frozenset(("...",)) + + +def _is_binary_operator(token_type, text): + return ( + token_type == tokenize.OP or + text in {'and', 'or'} + ) and ( + text not in _SYMBOLIC_OPS + ) + + +def _break_around_binary_operators(tokens): + """Private function to reduce duplication. + + This factors out the shared details between + :func:`break_before_binary_operator` and + :func:`break_after_binary_operator`. + """ + line_break = False + unary_context = True + # Previous non-newline token types and text + previous_token_type = None + previous_text = None + for token_type, text, start, end, line in tokens: + if token_type == tokenize.COMMENT: + continue + if ('\n' in text or '\r' in text) and token_type != tokenize.STRING: + line_break = True + else: + yield (token_type, text, previous_token_type, previous_text, + line_break, unary_context, start) + unary_context = text in '([{,;' + line_break = False + previous_token_type = token_type + previous_text = text + + +@register_check +def break_before_binary_operator(logical_line, tokens): + r""" + Avoid breaks before binary operators. + + The preferred place to break around a binary operator is after the + operator, not before it. + + W503: (width == 0\n + height == 0) + W503: (width == 0\n and height == 0) + W503: var = (1\n & ~2) + W503: var = (1\n / -2) + W503: var = (1\n + -1\n + -2) + + Okay: foo(\n -x) + Okay: foo(x\n []) + Okay: x = '''\n''' + '' + Okay: foo(x,\n -y) + Okay: foo(x, # comment\n -y) + """ + for context in _break_around_binary_operators(tokens): + (token_type, text, previous_token_type, previous_text, + line_break, unary_context, start) = context + if (_is_binary_operator(token_type, text) and line_break and + not unary_context and + not _is_binary_operator(previous_token_type, + previous_text)): + yield start, "W503 line break before binary operator" + + +@register_check +def break_after_binary_operator(logical_line, tokens): + r""" + Avoid breaks after binary operators. + + The preferred place to break around a binary operator is before the + operator, not after it. + + W504: (width == 0 +\n height == 0) + W504: (width == 0 and\n height == 0) + W504: var = (1 &\n ~2) + + Okay: foo(\n -x) + Okay: foo(x\n []) + Okay: x = '''\n''' + '' + Okay: x = '' + '''\n''' + Okay: foo(x,\n -y) + Okay: foo(x, # comment\n -y) + + The following should be W504 but unary_context is tricky with these + Okay: var = (1 /\n -2) + Okay: var = (1 +\n -1 +\n -2) + """ + prev_start = None + for context in _break_around_binary_operators(tokens): + (token_type, text, previous_token_type, previous_text, + line_break, unary_context, start) = context + if (_is_binary_operator(previous_token_type, previous_text) and + line_break and + not unary_context and + not _is_binary_operator(token_type, text)): + yield prev_start, "W504 line break after binary operator" + prev_start = start + + +@register_check +def comparison_to_singleton(logical_line, noqa): + r"""Comparison to singletons should use "is" or "is not". + + Comparisons to singletons like None should always be done + with "is" or "is not", never the equality operators. + + Okay: if arg is not None: + E711: if arg != None: + E711: if None == arg: + E712: if arg == True: + E712: if False == arg: + + Also, beware of writing if x when you really mean if x is not None + -- e.g. when testing whether a variable or argument that defaults to + None was set to some other value. The other value might have a type + (such as a container) that could be false in a boolean context! + """ + if noqa: + return + + for match in COMPARE_SINGLETON_REGEX.finditer(logical_line): + singleton = match.group(1) or match.group(3) + same = (match.group(2) == '==') + + msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) + if singleton in ('None',): + code = 'E711' + else: + code = 'E712' + nonzero = ((singleton == 'True' and same) or + (singleton == 'False' and not same)) + msg += " or 'if %scond:'" % ('' if nonzero else 'not ') + yield match.start(2), ("%s comparison to %s should be %s" % + (code, singleton, msg)) + + +@register_check +def comparison_negative(logical_line): + r"""Negative comparison should be done using "not in" and "is not". + + Okay: if x not in y:\n pass + Okay: assert (X in Y or X is Z) + Okay: if not (X in Y):\n pass + Okay: zz = x is not y + E713: Z = not X in Y + E713: if not X.B in Y:\n pass + E714: if not X is Y:\n pass + E714: Z = not X.B is Y + """ + match = COMPARE_NEGATIVE_REGEX.search(logical_line) + if match: + pos = match.start(1) + if match.group(2) == 'in': + yield pos, "E713 test for membership should be 'not in'" + else: + yield pos, "E714 test for object identity should be 'is not'" + + +@register_check +def comparison_type(logical_line, noqa): + r"""Object type comparisons should `is` / `is not` / `isinstance()`. + + Do not compare types directly. + + Okay: if isinstance(obj, int): + Okay: if type(obj) is int: + E721: if type(obj) == type(1): + """ + match = COMPARE_TYPE_REGEX.search(logical_line) + if match and not noqa: + inst = match.group(1) + if inst and inst.isidentifier() and inst not in SINGLETONS: + return # Allow comparison for types which are not obvious + yield ( + match.start(), + "E721 do not compare types, for exact checks use `is` / `is not`, " + "for instance checks use `isinstance()`", + ) + + +@register_check +def bare_except(logical_line, noqa): + r"""When catching exceptions, mention specific exceptions when + possible. + + Okay: except Exception: + Okay: except BaseException: + E722: except: + """ + if noqa: + return + + match = BLANK_EXCEPT_REGEX.match(logical_line) + if match: + yield match.start(), "E722 do not use bare 'except'" + + +@register_check +def ambiguous_identifier(logical_line, tokens): + r"""Never use the characters 'l', 'O', or 'I' as variable names. + + In some fonts, these characters are indistinguishable from the + numerals one and zero. When tempted to use 'l', use 'L' instead. + + Okay: L = 0 + Okay: o = 123 + Okay: i = 42 + E741: l = 0 + E741: O = 123 + E741: I = 42 + + Variables can be bound in several other contexts, including class + and function definitions, lambda functions, 'global' and 'nonlocal' + statements, exception handlers, and 'with' and 'for' statements. + In addition, we have a special handling for function parameters. + + Okay: except AttributeError as o: + Okay: with lock as L: + Okay: foo(l=12) + Okay: foo(l=I) + Okay: for a in foo(l=12): + Okay: lambda arg: arg * l + Okay: lambda a=l[I:5]: None + Okay: lambda x=a.I: None + Okay: if l >= 12: + E741: except AttributeError as O: + E741: with lock as l: + E741: global I + E741: nonlocal l + E741: def foo(l): + E741: def foo(l=12): + E741: l = foo(l=12) + E741: for l in range(10): + E741: [l for l in lines if l] + E741: lambda l: None + E741: lambda a=x[1:5], l: None + E741: lambda **l: + E741: def f(**l): + E742: class I(object): + E743: def l(x): + """ + func_depth = None # set to brace depth if 'def' or 'lambda' is found + seen_colon = False # set to true if we're done with function parameters + brace_depth = 0 + idents_to_avoid = ('l', 'O', 'I') + prev_type, prev_text, prev_start, prev_end, __ = tokens[0] + for index in range(1, len(tokens)): + token_type, text, start, end, line = tokens[index] + ident = pos = None + # find function definitions + if prev_text in {'def', 'lambda'}: + func_depth = brace_depth + seen_colon = False + elif ( + func_depth is not None and + text == ':' and + brace_depth == func_depth + ): + seen_colon = True + # update parameter parentheses level + if text in '([{': + brace_depth += 1 + elif text in ')]}': + brace_depth -= 1 + # identifiers on the lhs of an assignment operator + if text == ':=' or (text == '=' and brace_depth == 0): + if prev_text in idents_to_avoid: + ident = prev_text + pos = prev_start + # identifiers bound to values with 'as', 'for', + # 'global', or 'nonlocal' + if prev_text in ('as', 'for', 'global', 'nonlocal'): + if text in idents_to_avoid: + ident = text + pos = start + # function / lambda parameter definitions + if ( + func_depth is not None and + not seen_colon and + index < len(tokens) - 1 and tokens[index + 1][1] in ':,=)' and + prev_text in {'lambda', ',', '*', '**', '('} and + text in idents_to_avoid + ): + ident = text + pos = start + if prev_text == 'class': + if text in idents_to_avoid: + yield start, "E742 ambiguous class definition '%s'" % text + if prev_text == 'def': + if text in idents_to_avoid: + yield start, "E743 ambiguous function definition '%s'" % text + if ident: + yield pos, "E741 ambiguous variable name '%s'" % ident + prev_text = text + prev_start = start + + +@register_check +def python_3000_invalid_escape_sequence(logical_line, tokens, noqa): + r"""Invalid escape sequences are deprecated in Python 3.6. + + Okay: regex = r'\.png$' + W605: regex = '\.png$' + """ + if noqa: + return + + # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals + valid = [ + '\n', + '\\', + '\'', + '"', + 'a', + 'b', + 'f', + 'n', + 'r', + 't', + 'v', + '0', '1', '2', '3', '4', '5', '6', '7', + 'x', + + # Escape sequences only recognized in string literals + 'N', + 'u', + 'U', + ] + + prefixes = [] + for token_type, text, start, _, _ in tokens: + if token_type in {tokenize.STRING, FSTRING_START}: + # Extract string modifiers (e.g. u or r) + prefixes.append(text[:text.index(text[-1])].lower()) + + if token_type in {tokenize.STRING, FSTRING_MIDDLE}: + if 'r' not in prefixes[-1]: + start_line, start_col = start + pos = text.find('\\') + while pos >= 0: + pos += 1 + if text[pos] not in valid: + line = start_line + text.count('\n', 0, pos) + if line == start_line: + col = start_col + pos + else: + col = pos - text.rfind('\n', 0, pos) - 1 + yield ( + (line, col - 1), + f"W605 invalid escape sequence '\\{text[pos]}'" + ) + pos = text.find('\\', pos + 1) + + if token_type in {tokenize.STRING, FSTRING_END}: + prefixes.pop() + + +######################################################################## +@register_check +def maximum_doc_length(logical_line, max_doc_length, noqa, tokens): + r"""Limit all doc lines to a maximum of 72 characters. + + For flowing long blocks of text (docstrings or comments), limiting + the length to 72 characters is recommended. + + Reports warning W505 + """ + if max_doc_length is None or noqa: + return + + prev_token = None + skip_lines = set() + # Skip lines that + for token_type, text, start, end, line in tokens: + if token_type not in SKIP_COMMENTS.union([tokenize.STRING]): + skip_lines.add(line) + + for token_type, text, start, end, line in tokens: + # Skip lines that aren't pure strings + if token_type == tokenize.STRING and skip_lines: + continue + if token_type in (tokenize.STRING, tokenize.COMMENT): + # Only check comment-only lines + if prev_token is None or prev_token in SKIP_TOKENS: + lines = line.splitlines() + for line_num, physical_line in enumerate(lines): + if start[0] + line_num == 1 and line.startswith('#!'): + return + length = len(physical_line) + chunks = physical_line.split() + if token_type == tokenize.COMMENT: + if (len(chunks) == 2 and + length - len(chunks[-1]) < MAX_DOC_LENGTH): + continue + if len(chunks) == 1 and line_num + 1 < len(lines): + if (len(chunks) == 1 and + length - len(chunks[-1]) < MAX_DOC_LENGTH): + continue + if length > max_doc_length: + doc_error = (start[0] + line_num, max_doc_length) + yield (doc_error, "W505 doc line too long " + "(%d > %d characters)" + % (length, max_doc_length)) + prev_token = token_type + + +######################################################################## +# Helper functions +######################################################################## + + +def readlines(filename): + """Read the source code.""" + try: + with tokenize.open(filename) as f: + return f.readlines() + except (LookupError, SyntaxError, UnicodeError): + # Fall back if file encoding is improperly declared + with open(filename, encoding='latin-1') as f: + return f.readlines() + + +def stdin_get_value(): + """Read the value from stdin.""" + return io.TextIOWrapper(sys.stdin.buffer, errors='ignore').read() + + +noqa = lru_cache(512)(re.compile(r'# no(?:qa|pep8)\b', re.I).search) + + +def expand_indent(line): + r"""Return the amount of indentation. + + Tabs are expanded to the next multiple of 8. + """ + line = line.rstrip('\n\r') + if '\t' not in line: + return len(line) - len(line.lstrip()) + result = 0 + for char in line: + if char == '\t': + result = result // 8 * 8 + 8 + elif char == ' ': + result += 1 + else: + break + return result + + +def mute_string(text): + """Replace contents with 'xxx' to prevent syntax matching.""" + # String modifiers (e.g. u or r) + start = text.index(text[-1]) + 1 + end = len(text) - 1 + # Triple quotes + if text[-3:] in ('"""', "'''"): + start += 2 + end -= 2 + return text[:start] + 'x' * (end - start) + text[end:] + + +def parse_udiff(diff, patterns=None, parent='.'): + """Return a dictionary of matching lines.""" + # For each file of the diff, the entry key is the filename, + # and the value is a set of row numbers to consider. + rv = {} + path = nrows = None + for line in diff.splitlines(): + if nrows: + if line[:1] != '-': + nrows -= 1 + continue + if line[:3] == '@@ ': + hunk_match = HUNK_REGEX.match(line) + (row, nrows) = (int(g or '1') for g in hunk_match.groups()) + rv[path].update(range(row, row + nrows)) + elif line[:3] == '+++': + path = line[4:].split('\t', 1)[0] + # Git diff will use (i)ndex, (w)ork tree, (c)ommit and + # (o)bject instead of a/b/c/d as prefixes for patches + if path[:2] in ('b/', 'w/', 'i/'): + path = path[2:] + rv[path] = set() + return { + os.path.join(parent, filepath): rows + for (filepath, rows) in rv.items() + if rows and filename_match(filepath, patterns) + } + + +def normalize_paths(value, parent=os.curdir): + """Parse a comma-separated list of paths. + + Return a list of absolute paths. + """ + if not value: + return [] + if isinstance(value, list): + return value + paths = [] + for path in value.split(','): + path = path.strip() + if '/' in path: + path = os.path.abspath(os.path.join(parent, path)) + paths.append(path.rstrip('/')) + return paths + + +def filename_match(filename, patterns, default=True): + """Check if patterns contains a pattern that matches filename. + + If patterns is unspecified, this always returns True. + """ + if not patterns: + return default + return any(fnmatch(filename, pattern) for pattern in patterns) + + +def update_counts(s, counts): + r"""Adds one to the counts of each appearance of characters in s, + for characters in counts""" + for char in s: + if char in counts: + counts[char] += 1 + + +def _is_eol_token(token): + return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n' + + +######################################################################## +# Framework to run all checks +######################################################################## + + +class Checker: + """Load a Python source file, tokenize it, check coding style.""" + + def __init__(self, filename=None, lines=None, + options=None, report=None, **kwargs): + if options is None: + options = StyleGuide(kwargs).options + else: + assert not kwargs + self._io_error = None + self._physical_checks = options.physical_checks + self._logical_checks = options.logical_checks + self._ast_checks = options.ast_checks + self.max_line_length = options.max_line_length + self.max_doc_length = options.max_doc_length + self.indent_size = options.indent_size + self.fstring_start = 0 + self.multiline = False # in a multiline string? + self.hang_closing = options.hang_closing + self.indent_size = options.indent_size + self.verbose = options.verbose + self.filename = filename + # Dictionary where a checker can store its custom state. + self._checker_states = {} + if filename is None: + self.filename = 'stdin' + self.lines = lines or [] + elif filename == '-': + self.filename = 'stdin' + self.lines = stdin_get_value().splitlines(True) + elif lines is None: + try: + self.lines = readlines(filename) + except OSError: + (exc_type, exc) = sys.exc_info()[:2] + self._io_error = f'{exc_type.__name__}: {exc}' + self.lines = [] + else: + self.lines = lines + if self.lines: + ord0 = ord(self.lines[0][0]) + if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM + if ord0 == 0xfeff: + self.lines[0] = self.lines[0][1:] + elif self.lines[0][:3] == '\xef\xbb\xbf': + self.lines[0] = self.lines[0][3:] + self.report = report or options.report + self.report_error = self.report.error + self.noqa = False + + def report_invalid_syntax(self): + """Check if the syntax is valid.""" + (exc_type, exc) = sys.exc_info()[:2] + if len(exc.args) > 1: + offset = exc.args[1] + if len(offset) > 2: + offset = offset[1:3] + else: + offset = (1, 0) + self.report_error(offset[0], offset[1] or 0, + f'E901 {exc_type.__name__}: {exc.args[0]}', + self.report_invalid_syntax) + + def readline(self): + """Get the next line from the input buffer.""" + if self.line_number >= self.total_lines: + return '' + line = self.lines[self.line_number] + self.line_number += 1 + if self.indent_char is None and line[:1] in WHITESPACE: + self.indent_char = line[0] + return line + + def run_check(self, check, argument_names): + """Run a check plugin.""" + arguments = [] + for name in argument_names: + arguments.append(getattr(self, name)) + return check(*arguments) + + def init_checker_state(self, name, argument_names): + """Prepare custom state for the specific checker plugin.""" + if 'checker_state' in argument_names: + self.checker_state = self._checker_states.setdefault(name, {}) + + def check_physical(self, line): + """Run all physical checks on a raw input line.""" + self.physical_line = line + for name, check, argument_names in self._physical_checks: + self.init_checker_state(name, argument_names) + result = self.run_check(check, argument_names) + if result is not None: + (offset, text) = result + self.report_error(self.line_number, offset, text, check) + if text[:4] == 'E101': + self.indent_char = line[0] + + def build_tokens_line(self): + """Build a logical line from tokens.""" + logical = [] + comments = [] + length = 0 + prev_row = prev_col = mapping = None + for token_type, text, start, end, line in self.tokens: + if token_type in SKIP_TOKENS: + continue + if not mapping: + mapping = [(0, start)] + if token_type == tokenize.COMMENT: + comments.append(text) + continue + if token_type == tokenize.STRING: + text = mute_string(text) + elif token_type == FSTRING_MIDDLE: # pragma: >=3.12 cover + text = 'x' * len(text) + if prev_row: + (start_row, start_col) = start + if prev_row != start_row: # different row + prev_text = self.lines[prev_row - 1][prev_col - 1] + if prev_text == ',' or (prev_text not in '{[(' and + text not in '}])'): + text = ' ' + text + elif prev_col != start_col: # different column + text = line[prev_col:start_col] + text + logical.append(text) + length += len(text) + mapping.append((length, end)) + (prev_row, prev_col) = end + self.logical_line = ''.join(logical) + self.noqa = comments and noqa(''.join(comments)) + return mapping + + def check_logical(self): + """Build a line from tokens and run all logical checks on it.""" + self.report.increment_logical_line() + mapping = self.build_tokens_line() + if not mapping: + return + + mapping_offsets = [offset for offset, _ in mapping] + (start_row, start_col) = mapping[0][1] + start_line = self.lines[start_row - 1] + self.indent_level = expand_indent(start_line[:start_col]) + if self.blank_before < self.blank_lines: + self.blank_before = self.blank_lines + if self.verbose >= 2: + print(self.logical_line[:80].rstrip()) + for name, check, argument_names in self._logical_checks: + if self.verbose >= 4: + print(' ' + name) + self.init_checker_state(name, argument_names) + for offset, text in self.run_check(check, argument_names) or (): + if not isinstance(offset, tuple): + # As mappings are ordered, bisecting is a fast way + # to find a given offset in them. + token_offset, pos = mapping[bisect.bisect_left( + mapping_offsets, offset)] + offset = (pos[0], pos[1] + offset - token_offset) + self.report_error(offset[0], offset[1], text, check) + if self.logical_line: + self.previous_indent_level = self.indent_level + self.previous_logical = self.logical_line + if not self.indent_level: + self.previous_unindented_logical_line = self.logical_line + self.blank_lines = 0 + self.tokens = [] + + def check_ast(self): + """Build the file's AST and run all AST checks.""" + try: + tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) + except (ValueError, SyntaxError, TypeError): + return self.report_invalid_syntax() + for name, cls, __ in self._ast_checks: + checker = cls(tree, self.filename) + for lineno, offset, text, check in checker.run(): + if not self.lines or not noqa(self.lines[lineno - 1]): + self.report_error(lineno, offset, text, check) + + def generate_tokens(self): + """Tokenize file, run physical line checks and yield tokens.""" + if self._io_error: + self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) + tokengen = tokenize.generate_tokens(self.readline) + try: + prev_physical = '' + for token in tokengen: + if token[2][0] > self.total_lines: + return + self.noqa = token[4] and noqa(token[4]) + self.maybe_check_physical(token, prev_physical) + yield token + prev_physical = token[4] + except (SyntaxError, tokenize.TokenError): + self.report_invalid_syntax() + + def maybe_check_physical(self, token, prev_physical): + """If appropriate for token, check current physical line(s).""" + # Called after every token, but act only on end of line. + + if token.type == FSTRING_START: # pragma: >=3.12 cover + self.fstring_start = token.start[0] + # a newline token ends a single physical line. + elif _is_eol_token(token): + # if the file does not end with a newline, the NEWLINE + # token is inserted by the parser, but it does not contain + # the previous physical line in `token[4]` + if token.line == '': + self.check_physical(prev_physical) + else: + self.check_physical(token.line) + elif ( + token.type == tokenize.STRING and '\n' in token.string or + token.type == FSTRING_END + ): + # Less obviously, a string that contains newlines is a + # multiline string, either triple-quoted or with internal + # newlines backslash-escaped. Check every physical line in + # the string *except* for the last one: its newline is + # outside of the multiline string, so we consider it a + # regular physical line, and will check it like any other + # physical line. + # + # Subtleties: + # - we don't *completely* ignore the last line; if it + # contains the magical "# noqa" comment, we disable all + # physical checks for the entire multiline string + # - have to wind self.line_number back because initially it + # points to the last line of the string, and we want + # check_physical() to give accurate feedback + if noqa(token.line): + return + if token.type == FSTRING_END: # pragma: >=3.12 cover + start = self.fstring_start + else: + start = token.start[0] + end = token.end[0] + + self.multiline = True + self.line_number = start + for line_number in range(start, end): + self.check_physical(self.lines[line_number - 1] + '\n') + self.line_number += 1 + self.multiline = False + + def check_all(self, expected=None, line_offset=0): + """Run all checks on the input file.""" + self.report.init_file(self.filename, self.lines, expected, line_offset) + self.total_lines = len(self.lines) + if self._ast_checks: + self.check_ast() + self.line_number = 0 + self.indent_char = None + self.indent_level = self.previous_indent_level = 0 + self.previous_logical = '' + self.previous_unindented_logical_line = '' + self.tokens = [] + self.blank_lines = self.blank_before = 0 + parens = 0 + for token in self.generate_tokens(): + self.tokens.append(token) + token_type, text = token[0:2] + if self.verbose >= 3: + if token[2][0] == token[3][0]: + pos = '[{}:{}]'.format(token[2][1] or '', token[3][1]) + else: + pos = 'l.%s' % token[3][0] + print('l.%s\t%s\t%s\t%r' % + (token[2][0], pos, tokenize.tok_name[token[0]], text)) + if token_type == tokenize.OP: + if text in '([{': + parens += 1 + elif text in '}])': + parens -= 1 + elif not parens: + if token_type in NEWLINE: + if token_type == tokenize.NEWLINE: + self.check_logical() + self.blank_before = 0 + elif len(self.tokens) == 1: + # The physical line contains only this token. + self.blank_lines += 1 + del self.tokens[0] + else: + self.check_logical() + if self.tokens: + self.check_physical(self.lines[-1]) + self.check_logical() + return self.report.get_file_results() + + +class BaseReport: + """Collect the results of the checks.""" + + print_filename = False + + def __init__(self, options): + self._benchmark_keys = options.benchmark_keys + self._ignore_code = options.ignore_code + # Results + self.elapsed = 0 + self.total_errors = 0 + self.counters = dict.fromkeys(self._benchmark_keys, 0) + self.messages = {} + + def start(self): + """Start the timer.""" + self._start_time = time.time() + + def stop(self): + """Stop the timer.""" + self.elapsed = time.time() - self._start_time + + def init_file(self, filename, lines, expected, line_offset): + """Signal a new file.""" + self.filename = filename + self.lines = lines + self.expected = expected or () + self.line_offset = line_offset + self.file_errors = 0 + self.counters['files'] += 1 + self.counters['physical lines'] += len(lines) + + def increment_logical_line(self): + """Signal a new logical line.""" + self.counters['logical lines'] += 1 + + def error(self, line_number, offset, text, check): + """Report an error, according to options.""" + code = text[:4] + if self._ignore_code(code): + return + if code in self.counters: + self.counters[code] += 1 + else: + self.counters[code] = 1 + self.messages[code] = text[5:] + # Don't care about expected errors or warnings + if code in self.expected: + return + if self.print_filename and not self.file_errors: + print(self.filename) + self.file_errors += 1 + self.total_errors += 1 + return code + + def get_file_results(self): + """Return the count of errors and warnings for this file.""" + return self.file_errors + + def get_count(self, prefix=''): + """Return the total count of errors and warnings.""" + return sum(self.counters[key] + for key in self.messages if key.startswith(prefix)) + + def get_statistics(self, prefix=''): + """Get statistics for message codes that start with the prefix. + + prefix='' matches all errors and warnings + prefix='E' matches all errors + prefix='W' matches all warnings + prefix='E4' matches all errors that have to do with imports + """ + return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) + for key in sorted(self.messages) if key.startswith(prefix)] + + def print_statistics(self, prefix=''): + """Print overall statistics (number of errors and warnings).""" + for line in self.get_statistics(prefix): + print(line) + + def print_benchmark(self): + """Print benchmark numbers.""" + print('{:<7.2f} {}'.format(self.elapsed, 'seconds elapsed')) + if self.elapsed: + for key in self._benchmark_keys: + print('%-7d %s per second (%d total)' % + (self.counters[key] / self.elapsed, key, + self.counters[key])) + + +class FileReport(BaseReport): + """Collect the results of the checks and print the filenames.""" + + print_filename = True + + +class StandardReport(BaseReport): + """Collect and print the results of the checks.""" + + def __init__(self, options): + super().__init__(options) + self._fmt = REPORT_FORMAT.get(options.format.lower(), + options.format) + self._repeat = options.repeat + self._show_source = options.show_source + self._show_pep8 = options.show_pep8 + + def init_file(self, filename, lines, expected, line_offset): + """Signal a new file.""" + self._deferred_print = [] + return super().init_file( + filename, lines, expected, line_offset) + + def error(self, line_number, offset, text, check): + """Report an error, according to options.""" + code = super().error(line_number, offset, text, check) + if code and (self.counters[code] == 1 or self._repeat): + self._deferred_print.append( + (line_number, offset, code, text[5:], check.__doc__)) + return code + + def get_file_results(self): + """Print results and return the overall count for this file.""" + self._deferred_print.sort() + for line_number, offset, code, text, doc in self._deferred_print: + print(self._fmt % { + 'path': self.filename, + 'row': self.line_offset + line_number, 'col': offset + 1, + 'code': code, 'text': text, + }) + if self._show_source: + if line_number > len(self.lines): + line = '' + else: + line = self.lines[line_number - 1] + print(line.rstrip()) + print(re.sub(r'\S', ' ', line[:offset]) + '^') + if self._show_pep8 and doc: + print(' ' + doc.strip()) + + # stdout is block buffered when not stdout.isatty(). + # line can be broken where buffer boundary since other + # processes write to same file. + # flush() after print() to avoid buffer boundary. + # Typical buffer size is 8192. line written safely when + # len(line) < 8192. + sys.stdout.flush() + return self.file_errors + + +class DiffReport(StandardReport): + """Collect and print the results for the changed lines only.""" + + def __init__(self, options): + super().__init__(options) + self._selected = options.selected_lines + + def error(self, line_number, offset, text, check): + if line_number not in self._selected[self.filename]: + return + return super().error(line_number, offset, text, check) + + +class StyleGuide: + """Initialize a PEP-8 instance with few options.""" + + def __init__(self, *args, **kwargs): + # build options from the command line + self.checker_class = kwargs.pop('checker_class', Checker) + parse_argv = kwargs.pop('parse_argv', False) + config_file = kwargs.pop('config_file', False) + parser = kwargs.pop('parser', None) + # build options from dict + options_dict = dict(*args, **kwargs) + arglist = None if parse_argv else options_dict.get('paths', None) + verbose = options_dict.get('verbose', None) + options, self.paths = process_options( + arglist, parse_argv, config_file, parser, verbose) + if options_dict: + options.__dict__.update(options_dict) + if 'paths' in options_dict: + self.paths = options_dict['paths'] + + self.runner = self.input_file + self.options = options + + if not options.reporter: + options.reporter = BaseReport if options.quiet else StandardReport + + options.select = tuple(options.select or ()) + if not (options.select or options.ignore) and DEFAULT_IGNORE: + # The default choice: ignore controversial checks + options.ignore = tuple(DEFAULT_IGNORE.split(',')) + else: + # Ignore all checks which are not explicitly selected + options.ignore = ('',) if options.select else tuple(options.ignore) + options.benchmark_keys = BENCHMARK_KEYS[:] + options.ignore_code = self.ignore_code + options.physical_checks = self.get_checks('physical_line') + options.logical_checks = self.get_checks('logical_line') + options.ast_checks = self.get_checks('tree') + self.init_report() + + def init_report(self, reporter=None): + """Initialize the report instance.""" + self.options.report = (reporter or self.options.reporter)(self.options) + return self.options.report + + def check_files(self, paths=None): + """Run all checks on the paths.""" + if paths is None: + paths = self.paths + report = self.options.report + runner = self.runner + report.start() + try: + for path in paths: + if os.path.isdir(path): + self.input_dir(path) + elif not self.excluded(path): + runner(path) + except KeyboardInterrupt: + print('... stopped') + report.stop() + return report + + def input_file(self, filename, lines=None, expected=None, line_offset=0): + """Run all checks on a Python source file.""" + if self.options.verbose: + print('checking %s' % filename) + fchecker = self.checker_class( + filename, lines=lines, options=self.options) + return fchecker.check_all(expected=expected, line_offset=line_offset) + + def input_dir(self, dirname): + """Check all files in this directory and all subdirectories.""" + dirname = dirname.rstrip('/') + if self.excluded(dirname): + return 0 + counters = self.options.report.counters + verbose = self.options.verbose + filepatterns = self.options.filename + runner = self.runner + for root, dirs, files in os.walk(dirname): + if verbose: + print('directory ' + root) + counters['directories'] += 1 + for subdir in sorted(dirs): + if self.excluded(subdir, root): + dirs.remove(subdir) + for filename in sorted(files): + # contain a pattern that matches? + if ( + filename_match(filename, filepatterns) and + not self.excluded(filename, root) + ): + runner(os.path.join(root, filename)) + + def excluded(self, filename, parent=None): + """Check if the file should be excluded. + + Check if 'options.exclude' contains a pattern matching filename. + """ + if not self.options.exclude: + return False + basename = os.path.basename(filename) + if filename_match(basename, self.options.exclude): + return True + if parent: + filename = os.path.join(parent, filename) + filename = os.path.abspath(filename) + return filename_match(filename, self.options.exclude) + + def ignore_code(self, code): + """Check if the error code should be ignored. + + If 'options.select' contains a prefix of the error code, + return False. Else, if 'options.ignore' contains a prefix of + the error code, return True. + """ + if len(code) < 4 and any(s.startswith(code) + for s in self.options.select): + return False + return (code.startswith(self.options.ignore) and + not code.startswith(self.options.select)) + + def get_checks(self, argument_name): + """Get all the checks for this category. + + Find all globally visible functions where the first argument + name starts with argument_name and which contain selected tests. + """ + checks = [] + for check, attrs in _checks[argument_name].items(): + (codes, args) = attrs + if any(not (code and self.ignore_code(code)) for code in codes): + checks.append((check.__name__, check, args)) + return sorted(checks) + + +def get_parser(prog='pycodestyle', version=__version__): + """Create the parser for the program.""" + parser = OptionParser(prog=prog, version=version, + usage="%prog [options] input ...") + parser.config_options = [ + 'exclude', 'filename', 'select', 'ignore', 'max-line-length', + 'max-doc-length', 'indent-size', 'hang-closing', 'count', 'format', + 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'] + parser.add_option('-v', '--verbose', default=0, action='count', + help="print status messages, or debug with -vv") + parser.add_option('-q', '--quiet', default=0, action='count', + help="report only file names, or nothing with -qq") + parser.add_option('-r', '--repeat', default=True, action='store_true', + help="(obsolete) show all occurrences of the same error") + parser.add_option('--first', action='store_false', dest='repeat', + help="show first occurrence of each error") + parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, + help="exclude files or directories which match these " + "comma separated patterns (default: %default)") + parser.add_option('--filename', metavar='patterns', default='*.py', + help="when parsing directories, only check filenames " + "matching these comma separated patterns " + "(default: %default)") + parser.add_option('--select', metavar='errors', default='', + help="select errors and warnings (e.g. E,W6)") + parser.add_option('--ignore', metavar='errors', default='', + help="skip errors and warnings (e.g. E4,W) " + "(default: %s)" % DEFAULT_IGNORE) + parser.add_option('--show-source', action='store_true', + help="show source code for each error") + parser.add_option('--show-pep8', action='store_true', + help="show text of PEP 8 for each error " + "(implies --first)") + parser.add_option('--statistics', action='store_true', + help="count errors and warnings") + parser.add_option('--count', action='store_true', + help="print total number of errors and warnings " + "to standard error and set exit code to 1 if " + "total is not null") + parser.add_option('--max-line-length', type='int', metavar='n', + default=MAX_LINE_LENGTH, + help="set maximum allowed line length " + "(default: %default)") + parser.add_option('--max-doc-length', type='int', metavar='n', + default=None, + help="set maximum allowed doc line length and perform " + "these checks (unchecked if not set)") + parser.add_option('--indent-size', type='int', metavar='n', + default=INDENT_SIZE, + help="set how many spaces make up an indent " + "(default: %default)") + parser.add_option('--hang-closing', action='store_true', + help="hang closing bracket instead of matching " + "indentation of opening bracket's line") + parser.add_option('--format', metavar='format', default='default', + help="set the error format [default|pylint|<custom>]") + parser.add_option('--diff', action='store_true', + help="report changes only within line number ranges in " + "the unified diff received on STDIN") + group = parser.add_option_group("Testing Options") + group.add_option('--benchmark', action='store_true', + help="measure processing speed") + return parser + + +def read_config(options, args, arglist, parser): + """Read and parse configurations. + + If a config file is specified on the command line with the + "--config" option, then only it is used for configuration. + + Otherwise, the user configuration (~/.config/pycodestyle) and any + local configurations in the current directory or above will be + merged together (in that order) using the read method of + ConfigParser. + """ + config = configparser.RawConfigParser() + + cli_conf = options.config + + local_dir = os.curdir + + if USER_CONFIG and os.path.isfile(USER_CONFIG): + if options.verbose: + print('user configuration: %s' % USER_CONFIG) + config.read(USER_CONFIG) + + parent = tail = args and os.path.abspath(os.path.commonprefix(args)) + while tail: + if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): + local_dir = parent + if options.verbose: + print('local configuration: in %s' % parent) + break + (parent, tail) = os.path.split(parent) + + if cli_conf and os.path.isfile(cli_conf): + if options.verbose: + print('cli configuration: %s' % cli_conf) + config.read(cli_conf) + + pycodestyle_section = None + if config.has_section(parser.prog): + pycodestyle_section = parser.prog + elif config.has_section('pep8'): + pycodestyle_section = 'pep8' # Deprecated + warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') + + if pycodestyle_section: + option_list = {o.dest: o.type or o.action for o in parser.option_list} + + # First, read the default values + (new_options, __) = parser.parse_args([]) + + # Second, parse the configuration + for opt in config.options(pycodestyle_section): + if opt.replace('_', '-') not in parser.config_options: + print(" unknown option '%s' ignored" % opt) + continue + if options.verbose > 1: + print(" {} = {}".format(opt, + config.get(pycodestyle_section, opt))) + normalized_opt = opt.replace('-', '_') + opt_type = option_list[normalized_opt] + if opt_type in ('int', 'count'): + value = config.getint(pycodestyle_section, opt) + elif opt_type in ('store_true', 'store_false'): + value = config.getboolean(pycodestyle_section, opt) + else: + value = config.get(pycodestyle_section, opt) + if normalized_opt == 'exclude': + value = normalize_paths(value, local_dir) + setattr(new_options, normalized_opt, value) + + # Third, overwrite with the command-line options + (options, __) = parser.parse_args(arglist, values=new_options) + return options + + +def process_options(arglist=None, parse_argv=False, config_file=None, + parser=None, verbose=None): + """Process options passed either via arglist or command line args. + + Passing in the ``config_file`` parameter allows other tools, such as + flake8 to specify their own options to be processed in pycodestyle. + """ + if not parser: + parser = get_parser() + if not parser.has_option('--config'): + group = parser.add_option_group("Configuration", description=( + "The project options are read from the [%s] section of the " + "tox.ini file or the setup.cfg file located in any parent folder " + "of the path(s) being processed. Allowed options are: %s." % + (parser.prog, ', '.join(parser.config_options)))) + group.add_option('--config', metavar='path', default=config_file, + help="user config file location") + # Don't read the command line if the module is used as a library. + if not arglist and not parse_argv: + arglist = [] + # If parse_argv is True and arglist is None, arguments are + # parsed from the command line (sys.argv) + (options, args) = parser.parse_args(arglist) + options.reporter = None + + # If explicitly specified verbosity, override any `-v` CLI flag + if verbose is not None: + options.verbose = verbose + + if parse_argv and not args: + if options.diff or any(os.path.exists(name) + for name in PROJECT_CONFIG): + args = ['.'] + else: + parser.error('input not specified') + options = read_config(options, args, arglist, parser) + options.reporter = parse_argv and options.quiet == 1 and FileReport + + options.filename = _parse_multi_options(options.filename) + options.exclude = normalize_paths(options.exclude) + options.select = _parse_multi_options(options.select) + options.ignore = _parse_multi_options(options.ignore) + + if options.diff: + options.reporter = DiffReport + stdin = stdin_get_value() + options.selected_lines = parse_udiff(stdin, options.filename, args[0]) + args = sorted(options.selected_lines) + + return options, args + + +def _parse_multi_options(options, split_token=','): + r"""Split and strip and discard empties. + + Turns the following: + + A, + B, + + into ["A", "B"] + """ + if options: + return [o.strip() for o in options.split(split_token) if o.strip()] + else: + return options + + +def _main(): + """Parse options and run checks on Python source.""" + import signal + + # Handle "Broken pipe" gracefully + try: + signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) + except AttributeError: + pass # not supported on Windows + + style_guide = StyleGuide(parse_argv=True) + options = style_guide.options + + report = style_guide.check_files() + + if options.statistics: + report.print_statistics() + + if options.benchmark: + report.print_benchmark() + + if report.total_errors: + if options.count: + sys.stderr.write(str(report.total_errors) + '\n') + sys.exit(1) + + +if __name__ == '__main__': + _main() diff --git a/dbdpy-env/lib/python3.9/site-packages/pylab.py b/dbdpy-env/lib/python3.9/site-packages/pylab.py new file mode 100644 index 00000000..f9d135d3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pylab.py @@ -0,0 +1,3 @@ +from matplotlib.pylab import * +import matplotlib.pylab +__doc__ = matplotlib.pylab.__doc__ diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/LICENSE new file mode 100644 index 00000000..1bf98523 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/LICENSE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/METADATA new file mode 100644 index 00000000..dbad8472 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/METADATA @@ -0,0 +1,126 @@ +Metadata-Version: 2.1 +Name: pyparsing +Version: 3.1.1 +Summary: pyparsing module - Classes and methods to define and execute parsing grammars +Author-email: Paul McGuire <ptmcg.gm+pyparsing@gmail.com> +Requires-Python: >=3.6.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Compilers +Classifier: Topic :: Text Processing +Classifier: Typing :: Typed +Requires-Dist: railroad-diagrams ; extra == "diagrams" +Requires-Dist: jinja2 ; extra == "diagrams" +Project-URL: Homepage, https://github.com/pyparsing/pyparsing/ +Provides-Extra: diagrams + +PyParsing -- A Python Parsing Module +==================================== + +|Version| |Build Status| |Coverage| |License| |Python Versions| |Snyk Score| + +Introduction +============ + +The pyparsing module is an alternative approach to creating and +executing simple grammars, vs. the traditional lex/yacc approach, or the +use of regular expressions. The pyparsing module provides a library of +classes that client code uses to construct the grammar directly in +Python code. + +*[Since first writing this description of pyparsing in late 2003, this +technique for developing parsers has become more widespread, under the +name Parsing Expression Grammars - PEGs. See more information on PEGs* +`here <https://en.wikipedia.org/wiki/Parsing_expression_grammar>`__ +*.]* + +Here is a program to parse ``"Hello, World!"`` (or any greeting of the form +``"salutation, addressee!"``): + +.. code:: python + + from pyparsing import Word, alphas + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print(hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the +self-explanatory class names, and the use of '+', '|' and '^' operator +definitions. + +The parsed results returned from ``parseString()`` is a collection of type +``ParseResults``, which can be accessed as a +nested list, a dictionary, or an object with named attributes. + +The pyparsing module handles some of the problems that are typically +vexing when writing text parsers: + +- extra or missing whitespace (the above program will also handle ``"Hello,World!"``, ``"Hello , World !"``, etc.) +- quoted strings +- embedded comments + +The examples directory includes a simple SQL parser, simple CORBA IDL +parser, a config file parser, a chemical formula parser, and a four- +function algebraic notation parser, among many others. + +Documentation +============= + +There are many examples in the online docstrings of the classes +and methods in pyparsing. You can find them compiled into `online docs <https://pyparsing-docs.readthedocs.io/en/latest/>`__. Additional +documentation resources and project info are listed in the online +`GitHub wiki <https://github.com/pyparsing/pyparsing/wiki>`__. An +entire directory of examples can be found `here <https://github.com/pyparsing/pyparsing/tree/master/examples>`__. + +License +======= + +MIT License. See header of the `pyparsing __init__.py <https://github.com/pyparsing/pyparsing/blob/master/pyparsing/__init__.py#L1-L23>`__ file. + +History +======= + +See `CHANGES <https://github.com/pyparsing/pyparsing/blob/master/CHANGES>`__ file. + +.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg + :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml + +.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg + :target: https://codecov.io/gh/pyparsing/pyparsing + +.. |Version| image:: https://img.shields.io/pypi/v/pyparsing?style=flat-square + :target: https://pypi.org/project/pyparsing/ + :alt: Version + +.. |License| image:: https://img.shields.io/pypi/l/pyparsing.svg?style=flat-square + :target: https://pypi.org/project/pyparsing/ + :alt: License + +.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pyparsing.svg?style=flat-square + :target: https://pypi.org/project/python-liquid/ + :alt: Python versions + +.. |Snyk Score| image:: https://snyk.io//advisor/python/pyparsing/badge.svg + :target: https://snyk.io//advisor/python/pyparsing + :alt: pyparsing + diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/RECORD new file mode 100644 index 00000000..ebaf76f3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/RECORD @@ -0,0 +1,28 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/actions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/common.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/core.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/diagram/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/exceptions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/helpers.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/results.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/testing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/unicode.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pyparsing/util.cpython-39.pyc,, +pyparsing-3.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyparsing-3.1.1.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023 +pyparsing-3.1.1.dist-info/METADATA,sha256=E8_EMvvNkZCq0__T31WduJ0R086qI7adBDU58_308Z0,5090 +pyparsing-3.1.1.dist-info/RECORD,, +pyparsing-3.1.1.dist-info/WHEEL,sha256=rSgq_JpHF9fHR1lx53qwg_1-2LypZE_qmcuXbVUq948,81 +pyparsing/__init__.py,sha256=AbjlceFXuVPySz7tdBjyUyVMWyW-0nRNP9AeeY3ASu4,9148 +pyparsing/actions.py,sha256=05uaIPOznJPQ7VgRdmGCmG4sDnUPtwgv5qOYIqbL2UY,6567 +pyparsing/common.py,sha256=p-3c83E5-DjlkF35G0O9-kjQRpoejP-2_z0hxZ-eol4,13387 +pyparsing/core.py,sha256=SL7dkYDhhJliWU3vHWPWZIGVRMfbja0hfm--woDdOHg,226596 +pyparsing/diagram/__init__.py,sha256=TUqky0L642MJU8r6zTWW8oAr-s-8jOWLyiWgJev04Yo,24198 +pyparsing/exceptions.py,sha256=6Jc6W1eDZBzyFu1J0YrcdNFVBC-RINujZmveSnB8Rxw,9523 +pyparsing/helpers.py,sha256=BZJHCA8SS0pYio30KGQTc9w2qMOaK4YpZ7hcvHbnTgk,38646 +pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pyparsing/results.py,sha256=9dyqQ-w3MjfmxWbFt8KEPU6IfXeyRdoWp2Og802rUQY,26692 +pyparsing/testing.py,sha256=eJncg0p83zm1FTPvM9auNT6oavIvXaibmRFDf1qmwkY,13488 +pyparsing/unicode.py,sha256=bXy63t4uevWZH0JKJtd6XFIKgsCOfIlxvcDCRw-MkN8,10634 +pyparsing/util.py,sha256=vTMzTdwSDyV8d_dSgquUTdWgBFoA_W30nfxEJDsshRQ,8670 diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/WHEEL new file mode 100644 index 00000000..db4a255f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing-3.1.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.8.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/__init__.py new file mode 100644 index 00000000..3dbc3cf8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/__init__.py @@ -0,0 +1,325 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2022 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = """ +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and +executing simple grammars, vs. the traditional lex/yacc approach, or the +use of regular expressions. With pyparsing, you don't need to learn +a new syntax for defining grammars or matching expressions - the parsing +module provides a library of classes that you use to construct the +grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +``"<salutation>, <addressee>!"``), built up using :class:`Word`, +:class:`Literal`, and :class:`And` elements +(the :meth:`'+'<ParserElement.__add__>` operators create :class:`And` expressions, +and the strings are auto-converted to :class:`Literal` expressions):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print(hello, "->", greet.parse_string(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the +self-explanatory class names, and the use of :class:`'+'<And>`, +:class:`'|'<MatchFirst>`, :class:`'^'<Or>` and :class:`'&'<Each>` operators. + +The :class:`ParseResults` object returned from +:class:`ParserElement.parse_string` can be +accessed as a nested list, a dictionary, or an object with named +attributes. + +The pyparsing module handles some of the problems that are typically +vexing when writing text parsers: + + - extra or missing whitespace (the above program will also handle + "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes :class:`ParserElement` and :class:`ParseResults` to +see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + + - construct literal match expressions from :class:`Literal` and + :class:`CaselessLiteral` classes + - construct character word-group expressions using the :class:`Word` + class + - see how to create repetitive expressions using :class:`ZeroOrMore` + and :class:`OneOrMore` classes + - use :class:`'+'<And>`, :class:`'|'<MatchFirst>`, :class:`'^'<Or>`, + and :class:`'&'<Each>` operators to combine simple expressions into + more complex ones + - associate names with your parsed results using + :class:`ParserElement.set_results_name` + - access the parsed data, which is returned as a :class:`ParseResults` + object + - find some helpful expression short-cuts like :class:`DelimitedList` + and :class:`one_of` + - find more useful common expressions in the :class:`pyparsing_common` + namespace class +""" +from typing import NamedTuple + + +class version_info(NamedTuple): + major: int + minor: int + micro: int + releaselevel: str + serial: int + + @property + def __version__(self): + return ( + f"{self.major}.{self.minor}.{self.micro}" + + ( + f"{'r' if self.releaselevel[0] == 'c' else ''}{self.releaselevel[0]}{self.serial}", + "", + )[self.releaselevel == "final"] + ) + + def __str__(self): + return f"{__name__} {self.__version__} / {__version_time__}" + + def __repr__(self): + return f"{__name__}.{type(self).__name__}({', '.join('{}={!r}'.format(*nv) for nv in zip(self._fields, self))})" + + +__version_info__ = version_info(3, 1, 1, "final", 1) +__version_time__ = "29 Jul 2023 22:27 UTC" +__version__ = __version_info__.__version__ +__versionTime__ = __version_time__ +__author__ = "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>" + +from .util import * +from .exceptions import * +from .actions import * +from .core import __diag__, __compat__ +from .results import * +from .core import * # type: ignore[misc, assignment] +from .core import _builtin_exprs as core_builtin_exprs +from .helpers import * # type: ignore[misc, assignment] +from .helpers import _builtin_exprs as helper_builtin_exprs + +from .unicode import unicode_set, UnicodeRangeList, pyparsing_unicode as unicode +from .testing import pyparsing_test as testing +from .common import ( + pyparsing_common as common, + _builtin_exprs as common_builtin_exprs, +) + +# define backward compat synonyms +if "pyparsing_unicode" not in globals(): + pyparsing_unicode = unicode # type: ignore[misc] +if "pyparsing_common" not in globals(): + pyparsing_common = common # type: ignore[misc] +if "pyparsing_test" not in globals(): + pyparsing_test = testing # type: ignore[misc] + +core_builtin_exprs += common_builtin_exprs + helper_builtin_exprs + + +__all__ = [ + "__version__", + "__version_time__", + "__author__", + "__compat__", + "__diag__", + "And", + "AtLineStart", + "AtStringStart", + "CaselessKeyword", + "CaselessLiteral", + "CharsNotIn", + "CloseMatch", + "Combine", + "DelimitedList", + "Dict", + "Each", + "Empty", + "FollowedBy", + "Forward", + "GoToColumn", + "Group", + "IndentedBlock", + "Keyword", + "LineEnd", + "LineStart", + "Literal", + "Located", + "PrecededBy", + "MatchFirst", + "NoMatch", + "NotAny", + "OneOrMore", + "OnlyOnce", + "OpAssoc", + "Opt", + "Optional", + "Or", + "ParseBaseException", + "ParseElementEnhance", + "ParseException", + "ParseExpression", + "ParseFatalException", + "ParseResults", + "ParseSyntaxException", + "ParserElement", + "PositionToken", + "QuotedString", + "RecursiveGrammarException", + "Regex", + "SkipTo", + "StringEnd", + "StringStart", + "Suppress", + "Token", + "TokenConverter", + "White", + "Word", + "WordEnd", + "WordStart", + "ZeroOrMore", + "Char", + "alphanums", + "alphas", + "alphas8bit", + "any_close_tag", + "any_open_tag", + "autoname_elements", + "c_style_comment", + "col", + "common_html_entity", + "condition_as_parse_action", + "counted_array", + "cpp_style_comment", + "dbl_quoted_string", + "dbl_slash_comment", + "delimited_list", + "dict_of", + "empty", + "hexnums", + "html_comment", + "identchars", + "identbodychars", + "infix_notation", + "java_style_comment", + "line", + "line_end", + "line_start", + "lineno", + "make_html_tags", + "make_xml_tags", + "match_only_at_col", + "match_previous_expr", + "match_previous_literal", + "nested_expr", + "null_debug_action", + "nums", + "one_of", + "original_text_for", + "printables", + "punc8bit", + "pyparsing_common", + "pyparsing_test", + "pyparsing_unicode", + "python_style_comment", + "quoted_string", + "remove_quotes", + "replace_with", + "replace_html_entity", + "rest_of_line", + "sgl_quoted_string", + "srange", + "string_end", + "string_start", + "token_map", + "trace_parse_action", + "ungroup", + "unicode_set", + "unicode_string", + "with_attribute", + "with_class", + # pre-PEP8 compatibility names + "__versionTime__", + "anyCloseTag", + "anyOpenTag", + "cStyleComment", + "commonHTMLEntity", + "conditionAsParseAction", + "countedArray", + "cppStyleComment", + "dblQuotedString", + "dblSlashComment", + "delimitedList", + "dictOf", + "htmlComment", + "indentedBlock", + "infixNotation", + "javaStyleComment", + "lineEnd", + "lineStart", + "locatedExpr", + "makeHTMLTags", + "makeXMLTags", + "matchOnlyAtCol", + "matchPreviousExpr", + "matchPreviousLiteral", + "nestedExpr", + "nullDebugAction", + "oneOf", + "opAssoc", + "originalTextFor", + "pythonStyleComment", + "quotedString", + "removeQuotes", + "replaceHTMLEntity", + "replaceWith", + "restOfLine", + "sglQuotedString", + "stringEnd", + "stringStart", + "tokenMap", + "traceParseAction", + "unicodeString", + "withAttribute", + "withClass", + "common", + "unicode", + "testing", +] diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/actions.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/actions.py new file mode 100644 index 00000000..ca6e4c6a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/actions.py @@ -0,0 +1,217 @@ +# actions.py + +from .exceptions import ParseException +from .util import col, replaced_by_pep8 + + +class OnlyOnce: + """ + Wrapper for parse actions, to ensure they are only called once. + """ + + def __init__(self, method_call): + from .core import _trim_arity + + self.callable = _trim_arity(method_call) + self.called = False + + def __call__(self, s, l, t): + if not self.called: + results = self.callable(s, l, t) + self.called = True + return results + raise ParseException(s, l, "OnlyOnce obj called multiple times w/out reset") + + def reset(self): + """ + Allow the associated parse action to be called once more. + """ + + self.called = False + + +def match_only_at_col(n): + """ + Helper method for defining parse actions that require matching at + a specific column in the input text. + """ + + def verify_col(strg, locn, toks): + if col(locn, strg) != n: + raise ParseException(strg, locn, f"matched token not at column {n}") + + return verify_col + + +def replace_with(repl_str): + """ + Helper method for common parse actions that simply return + a literal value. Especially useful when used with + :class:`transform_string<ParserElement.transform_string>` (). + + Example:: + + num = Word(nums).set_parse_action(lambda toks: int(toks[0])) + na = one_of("N/A NA").set_parse_action(replace_with(math.nan)) + term = na | num + + term[1, ...].parse_string("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s, l, t: [repl_str] + + +def remove_quotes(s, l, t): + """ + Helper parse action for removing quotation marks from parsed + quoted strings. + + Example:: + + # by default, quotation marks are included in parsed results + quoted_string.parse_string("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use remove_quotes to strip quotation marks from parsed results + quoted_string.set_parse_action(remove_quotes) + quoted_string.parse_string("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + + +def with_attribute(*args, **attr_dict): + """ + Helper to create a validating parse action to be used with start + tags created with :class:`make_xml_tags` or + :class:`make_html_tags`. Use ``with_attribute`` to qualify + a starting tag with a required attribute value, to avoid false + matches on common tags such as ``<TD>`` or ``<DIV>``. + + Call ``with_attribute`` with a series of attribute names and + values. Specify the list of filter attributes names and values as: + + - keyword arguments, as in ``(align="right")``, or + - as an explicit dict with ``**`` operator, when an attribute + name is also a Python reserved word, as in ``**{"class":"Customer", "align":"right"}`` + - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align", "right"))`` + + For attribute names with a namespace prefix, you must use the second + form. Attribute names are matched insensitive to upper/lower case. + + If just testing for ``class`` (with or without a namespace), use + :class:`with_class`. + + To verify that the attribute exists, but without specifying a value, + pass ``with_attribute.ANY_VALUE`` as the value. + + Example:: + + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = make_html_tags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().set_parse_action(with_attribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.search_string(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().set_parse_action(with_attribute(type=with_attribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.search_string(html): + print(div_header.body) + + prints:: + + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attr_dict.items() + attrs = [(k, v) for k, v in attrs] + + def pa(s, l, tokens): + for attrName, attrValue in attrs: + if attrName not in tokens: + raise ParseException(s, l, "no matching attribute " + attrName) + if attrValue != with_attribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException( + s, + l, + f"attribute {attrName!r} has value {tokens[attrName]!r}, must be {attrValue!r}", + ) + + return pa + + +with_attribute.ANY_VALUE = object() # type: ignore [attr-defined] + + +def with_class(classname, namespace=""): + """ + Simplified version of :class:`with_attribute` when + matching on a div class - made difficult because ``class`` is + a reserved word in Python. + + Example:: + + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this &lt;div&gt; has no class</div> + </div> + + ''' + div,div_end = make_html_tags("div") + div_grid = div().set_parse_action(with_class("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.search_string(html): + print(grid_header.body) + + div_any_type = div().set_parse_action(with_class(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.search_string(html): + print(div_header.body) + + prints:: + + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = f"{namespace}:class" if namespace else "class" + return with_attribute(**{classattr: classname}) + + +# pre-PEP8 compatibility symbols +# fmt: off +@replaced_by_pep8(replace_with) +def replaceWith(): ... + +@replaced_by_pep8(remove_quotes) +def removeQuotes(): ... + +@replaced_by_pep8(with_attribute) +def withAttribute(): ... + +@replaced_by_pep8(with_class) +def withClass(): ... + +@replaced_by_pep8(match_only_at_col) +def matchOnlyAtCol(): ... + +# fmt: on diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/common.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/common.py new file mode 100644 index 00000000..7a666b27 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/common.py @@ -0,0 +1,432 @@ +# common.py +from .core import * +from .helpers import DelimitedList, any_open_tag, any_close_tag +from datetime import datetime + + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """Here are some common low-level expressions that may be useful in + jump-starting parser development: + + - numeric forms (:class:`integers<integer>`, :class:`reals<real>`, + :class:`scientific notation<sci_real>`) + - common :class:`programming identifiers<identifier>` + - network addresses (:class:`MAC<mac_address>`, + :class:`IPv4<ipv4_address>`, :class:`IPv6<ipv6_address>`) + - ISO8601 :class:`dates<iso8601_date>` and + :class:`datetime<iso8601_datetime>` + - :class:`UUID<uuid>` + - :class:`comma-separated list<comma_separated_list>` + - :class:`url` + + Parse actions: + + - :class:`convert_to_integer` + - :class:`convert_to_float` + - :class:`convert_to_date` + - :class:`convert_to_datetime` + - :class:`strip_html_tags` + - :class:`upcase_tokens` + - :class:`downcase_tokens` + + Example:: + + pyparsing_common.number.run_tests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.run_tests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.run_tests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.run_tests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.run_tests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.set_parse_action(token_map(uuid.UUID)) + pyparsing_common.uuid.run_tests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + + prints:: + + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convert_to_integer = token_map(int) + """ + Parse action for converting parsed integers to Python int + """ + + convert_to_float = token_map(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).set_name("integer").set_parse_action(convert_to_integer) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = ( + Word(hexnums).set_name("hex integer").set_parse_action(token_map(int, 16)) + ) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = ( + Regex(r"[+-]?\d+") + .set_name("signed integer") + .set_parse_action(convert_to_integer) + ) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = ( + signed_integer().set_parse_action(convert_to_float) + + "/" + + signed_integer().set_parse_action(convert_to_float) + ).set_name("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.add_parse_action(lambda tt: tt[0] / tt[-1]) + + mixed_integer = ( + fraction | signed_integer + Opt(Opt("-").suppress() + fraction) + ).set_name("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.add_parse_action(sum) + + real = ( + Regex(r"[+-]?(?:\d+\.\d*|\.\d+)") + .set_name("real number") + .set_parse_action(convert_to_float) + ) + """expression that parses a floating point number and returns a float""" + + sci_real = ( + Regex(r"[+-]?(?:\d+(?:[eE][+-]?\d+)|(?:\d+\.\d*|\.\d+)(?:[eE][+-]?\d+)?)") + .set_name("real number with scientific notation") + .set_parse_action(convert_to_float) + ) + """expression that parses a floating point number with optional + scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).setName("number").streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = ( + Regex(r"[+-]?\d+\.?\d*([eE][+-]?\d+)?") + .set_name("fnumber") + .set_parse_action(convert_to_float) + ) + """any int or real number, returned as float""" + + identifier = Word(identchars, identbodychars).set_name("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex( + r"(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}" + ).set_name("IPv4 address") + "IPv4 address (``0.0.0.0 - 255.255.255.255``)" + + _ipv6_part = Regex(r"[0-9a-fA-F]{1,4}").set_name("hex_integer") + _full_ipv6_address = (_ipv6_part + (":" + _ipv6_part) * 7).set_name( + "full IPv6 address" + ) + _short_ipv6_address = ( + Opt(_ipv6_part + (":" + _ipv6_part) * (0, 6)) + + "::" + + Opt(_ipv6_part + (":" + _ipv6_part) * (0, 6)) + ).set_name("short IPv6 address") + _short_ipv6_address.add_condition( + lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8 + ) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).set_name("mixed IPv6 address") + ipv6_address = Combine( + (_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).set_name( + "IPv6 address" + ) + ).set_name("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex( + r"[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}" + ).set_name("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convert_to_date(fmt: str = "%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%d"``) + + Example:: + + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.set_parse_action(pyparsing_common.convert_to_date()) + print(date_expr.parse_string("1999-12-31")) + + prints:: + + [datetime.date(1999, 12, 31)] + """ + + def cvt_fn(ss, ll, tt): + try: + return datetime.strptime(tt[0], fmt).date() + except ValueError as ve: + raise ParseException(ss, ll, str(ve)) + + return cvt_fn + + @staticmethod + def convert_to_datetime(fmt: str = "%Y-%m-%dT%H:%M:%S.%f"): + """Helper to create a parse action for converting parsed + datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%dT%H:%M:%S.%f"``) + + Example:: + + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.set_parse_action(pyparsing_common.convert_to_datetime()) + print(dt_expr.parse_string("1999-12-31T23:59:59.999")) + + prints:: + + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + + def cvt_fn(s, l, t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + + return cvt_fn + + iso8601_date = Regex( + r"(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?" + ).set_name("ISO8601 date") + "ISO8601 date (``yyyy-mm-dd``)" + + iso8601_datetime = Regex( + r"(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?" + ).set_name("ISO8601 datetime") + "ISO8601 datetime (``yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)``) - trailing seconds, milliseconds, and timezone optional; accepts separating ``'T'`` or ``' '``" + + uuid = Regex(r"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}").set_name("UUID") + "UUID (``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``)" + + _html_stripper = any_open_tag.suppress() | any_close_tag.suppress() + + @staticmethod + def strip_html_tags(s: str, l: int, tokens: ParseResults): + """Parse action to remove HTML tags from web page HTML source + + Example:: + + # strip HTML links from normal text + text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' + td, td_end = make_html_tags("TD") + table_text = td + SkipTo(td_end).set_parse_action(pyparsing_common.strip_html_tags)("body") + td_end + print(table_text.parse_string(text).body) + + Prints:: + + More info at the pyparsing wiki page + """ + return pyparsing_common._html_stripper.transform_string(tokens[0]) + + _commasepitem = ( + Combine( + OneOrMore( + ~Literal(",") + + ~LineEnd() + + Word(printables, exclude_chars=",") + + Opt(White(" \t") + ~FollowedBy(LineEnd() | ",")) + ) + ) + .streamline() + .set_name("commaItem") + ) + comma_separated_list = DelimitedList( + Opt(quoted_string.copy() | _commasepitem, default="") + ).set_name("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcase_tokens = staticmethod(token_map(lambda t: t.upper())) + """Parse action to convert tokens to upper case.""" + + downcase_tokens = staticmethod(token_map(lambda t: t.lower())) + """Parse action to convert tokens to lower case.""" + + # fmt: off + url = Regex( + # https://mathiasbynens.be/demo/url-regex + # https://gist.github.com/dperini/729294 + r"(?P<url>" + + # protocol identifier (optional) + # short syntax // still required + r"(?:(?:(?P<scheme>https?|ftp):)?\/\/)" + + # user:pass BasicAuth (optional) + r"(?:(?P<auth>\S+(?::\S*)?)@)?" + + r"(?P<host>" + + # IP address exclusion + # private & local networks + r"(?!(?:10|127)(?:\.\d{1,3}){3})" + + r"(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})" + + r"(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})" + + # IP address dotted notation octets + # excludes loopback network 0.0.0.0 + # excludes reserved space >= 224.0.0.0 + # excludes network & broadcast addresses + # (first & last IP address of each class) + r"(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])" + + r"(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}" + + r"(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))" + + r"|" + + # host & domain names, may end with dot + # can be replaced by a shortest alternative + # (?![-_])(?:[-\w\u00a1-\uffff]{0,63}[^-_]\.)+ + r"(?:" + + r"(?:" + + r"[a-z0-9\u00a1-\uffff]" + + r"[a-z0-9\u00a1-\uffff_-]{0,62}" + + r")?" + + r"[a-z0-9\u00a1-\uffff]\." + + r")+" + + # TLD identifier name, may end with dot + r"(?:[a-z\u00a1-\uffff]{2,}\.?)" + + r")" + + # port number (optional) + r"(:(?P<port>\d{2,5}))?" + + # resource path (optional) + r"(?P<path>\/[^?# ]*)?" + + # query string (optional) + r"(\?(?P<query>[^#]*))?" + + # fragment (optional) + r"(#(?P<fragment>\S*))?" + + r")" + ).set_name("url") + """URL (http/https/ftp scheme)""" + # fmt: on + + # pre-PEP8 compatibility names + convertToInteger = convert_to_integer + """Deprecated - use :class:`convert_to_integer`""" + convertToFloat = convert_to_float + """Deprecated - use :class:`convert_to_float`""" + convertToDate = convert_to_date + """Deprecated - use :class:`convert_to_date`""" + convertToDatetime = convert_to_datetime + """Deprecated - use :class:`convert_to_datetime`""" + stripHTMLTags = strip_html_tags + """Deprecated - use :class:`strip_html_tags`""" + upcaseTokens = upcase_tokens + """Deprecated - use :class:`upcase_tokens`""" + downcaseTokens = downcase_tokens + """Deprecated - use :class:`downcase_tokens`""" + + +_builtin_exprs = [ + v for v in vars(pyparsing_common).values() if isinstance(v, ParserElement) +] diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/core.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/core.py new file mode 100644 index 00000000..73514ed0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/core.py @@ -0,0 +1,6159 @@ +# +# core.py +# + +from collections import deque +import os +import typing +from typing import ( + Any, + Callable, + Generator, + List, + NamedTuple, + Sequence, + Set, + TextIO, + Tuple, + Union, + cast, +) +from abc import ABC, abstractmethod +from enum import Enum +import string +import copy +import warnings +import re +import sys +from collections.abc import Iterable +import traceback +import types +from operator import itemgetter +from functools import wraps +from threading import RLock +from pathlib import Path + +from .util import ( + _FifoCache, + _UnboundedCache, + __config_flags, + _collapse_string_to_ranges, + _escape_regex_range_chars, + _bslash, + _flatten, + LRUMemo as _LRUMemo, + UnboundedMemo as _UnboundedMemo, + replaced_by_pep8, +) +from .exceptions import * +from .actions import * +from .results import ParseResults, _ParseResultsWithOffset +from .unicode import pyparsing_unicode + +_MAX_INT = sys.maxsize +str_type: Tuple[type, ...] = (str, bytes) + +# +# Copyright (c) 2003-2022 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + + +if sys.version_info >= (3, 8): + from functools import cached_property +else: + + class cached_property: + def __init__(self, func): + self._func = func + + def __get__(self, instance, owner=None): + ret = instance.__dict__[self._func.__name__] = self._func(instance) + return ret + + +class __compat__(__config_flags): + """ + A cross-version compatibility configuration for pyparsing features that will be + released in a future version. By setting values in this configuration to True, + those features can be enabled in prior versions for compatibility development + and testing. + + - ``collect_all_And_tokens`` - flag to enable fix for Issue #63 that fixes erroneous grouping + of results names when an :class:`And` expression is nested within an :class:`Or` or :class:`MatchFirst`; + maintained for compatibility, but setting to ``False`` no longer restores pre-2.3.1 + behavior + """ + + _type_desc = "compatibility" + + collect_all_And_tokens = True + + _all_names = [__ for __ in locals() if not __.startswith("_")] + _fixed_names = """ + collect_all_And_tokens + """.split() + + +class __diag__(__config_flags): + _type_desc = "diagnostic" + + warn_multiple_tokens_in_named_alternation = False + warn_ungrouped_named_tokens_in_collection = False + warn_name_set_on_empty_Forward = False + warn_on_parse_using_empty_Forward = False + warn_on_assignment_to_Forward = False + warn_on_multiple_string_args_to_oneof = False + warn_on_match_first_with_lshift_operator = False + enable_debug_on_named_expressions = False + + _all_names = [__ for __ in locals() if not __.startswith("_")] + _warning_names = [name for name in _all_names if name.startswith("warn")] + _debug_names = [name for name in _all_names if name.startswith("enable_debug")] + + @classmethod + def enable_all_warnings(cls) -> None: + for name in cls._warning_names: + cls.enable(name) + + +class Diagnostics(Enum): + """ + Diagnostic configuration (all default to disabled) + + - ``warn_multiple_tokens_in_named_alternation`` - flag to enable warnings when a results + name is defined on a :class:`MatchFirst` or :class:`Or` expression with one or more :class:`And` subexpressions + - ``warn_ungrouped_named_tokens_in_collection`` - flag to enable warnings when a results + name is defined on a containing expression with ungrouped subexpressions that also + have results names + - ``warn_name_set_on_empty_Forward`` - flag to enable warnings when a :class:`Forward` is defined + with a results name, but has no contents defined + - ``warn_on_parse_using_empty_Forward`` - flag to enable warnings when a :class:`Forward` is + defined in a grammar but has never had an expression attached to it + - ``warn_on_assignment_to_Forward`` - flag to enable warnings when a :class:`Forward` is defined + but is overwritten by assigning using ``'='`` instead of ``'<<='`` or ``'<<'`` + - ``warn_on_multiple_string_args_to_oneof`` - flag to enable warnings when :class:`one_of` is + incorrectly called with multiple str arguments + - ``enable_debug_on_named_expressions`` - flag to auto-enable debug on all subsequent + calls to :class:`ParserElement.set_name` + + Diagnostics are enabled/disabled by calling :class:`enable_diag` and :class:`disable_diag`. + All warnings can be enabled by calling :class:`enable_all_warnings`. + """ + + warn_multiple_tokens_in_named_alternation = 0 + warn_ungrouped_named_tokens_in_collection = 1 + warn_name_set_on_empty_Forward = 2 + warn_on_parse_using_empty_Forward = 3 + warn_on_assignment_to_Forward = 4 + warn_on_multiple_string_args_to_oneof = 5 + warn_on_match_first_with_lshift_operator = 6 + enable_debug_on_named_expressions = 7 + + +def enable_diag(diag_enum: Diagnostics) -> None: + """ + Enable a global pyparsing diagnostic flag (see :class:`Diagnostics`). + """ + __diag__.enable(diag_enum.name) + + +def disable_diag(diag_enum: Diagnostics) -> None: + """ + Disable a global pyparsing diagnostic flag (see :class:`Diagnostics`). + """ + __diag__.disable(diag_enum.name) + + +def enable_all_warnings() -> None: + """ + Enable all global pyparsing diagnostic warnings (see :class:`Diagnostics`). + """ + __diag__.enable_all_warnings() + + +# hide abstract class +del __config_flags + + +def _should_enable_warnings( + cmd_line_warn_options: typing.Iterable[str], warn_env_var: typing.Optional[str] +) -> bool: + enable = bool(warn_env_var) + for warn_opt in cmd_line_warn_options: + w_action, w_message, w_category, w_module, w_line = (warn_opt + "::::").split( + ":" + )[:5] + if not w_action.lower().startswith("i") and ( + not (w_message or w_category or w_module) or w_module == "pyparsing" + ): + enable = True + elif w_action.lower().startswith("i") and w_module in ("pyparsing", ""): + enable = False + return enable + + +if _should_enable_warnings( + sys.warnoptions, os.environ.get("PYPARSINGENABLEALLWARNINGS") +): + enable_all_warnings() + + +# build list of single arg builtins, that can be used as parse actions +_single_arg_builtins = { + sum, + len, + sorted, + reversed, + list, + tuple, + set, + any, + all, + min, + max, +} + +_generatorType = types.GeneratorType +ParseImplReturnType = Tuple[int, Any] +PostParseReturnType = Union[ParseResults, Sequence[ParseResults]] +ParseAction = Union[ + Callable[[], Any], + Callable[[ParseResults], Any], + Callable[[int, ParseResults], Any], + Callable[[str, int, ParseResults], Any], +] +ParseCondition = Union[ + Callable[[], bool], + Callable[[ParseResults], bool], + Callable[[int, ParseResults], bool], + Callable[[str, int, ParseResults], bool], +] +ParseFailAction = Callable[[str, int, "ParserElement", Exception], None] +DebugStartAction = Callable[[str, int, "ParserElement", bool], None] +DebugSuccessAction = Callable[ + [str, int, int, "ParserElement", ParseResults, bool], None +] +DebugExceptionAction = Callable[[str, int, "ParserElement", Exception, bool], None] + + +alphas = string.ascii_uppercase + string.ascii_lowercase +identchars = pyparsing_unicode.Latin1.identchars +identbodychars = pyparsing_unicode.Latin1.identbodychars +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +printables = "".join([c for c in string.printable if c not in string.whitespace]) + +_trim_arity_call_line: traceback.StackSummary = None # type: ignore[assignment] + + +def _trim_arity(func, max_limit=3): + """decorator to trim function calls to match the arity of the target""" + global _trim_arity_call_line + + if func in _single_arg_builtins: + return lambda s, l, t: func(t) + + limit = 0 + found_arity = False + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + # fmt: off + LINE_DIFF = 7 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + _trim_arity_call_line = (_trim_arity_call_line or traceback.extract_stack(limit=2)[-1]) + pa_call_line_synth = (_trim_arity_call_line[0], _trim_arity_call_line[1] + LINE_DIFF) + + def wrapper(*args): + nonlocal found_arity, limit + while 1: + try: + ret = func(*args[limit:]) + found_arity = True + return ret + except TypeError as te: + # re-raise TypeErrors if they did not come from our arity testing + if found_arity: + raise + else: + tb = te.__traceback__ + frames = traceback.extract_tb(tb, limit=2) + frame_summary = frames[-1] + trim_arity_type_error = ( + [frame_summary[:2]][-1][:2] == pa_call_line_synth + ) + del tb + + if trim_arity_type_error: + if limit < max_limit: + limit += 1 + continue + + raise + # fmt: on + + # copy func name to wrapper for sensible debug output + # (can't use functools.wraps, since that messes with function signature) + func_name = getattr(func, "__name__", getattr(func, "__class__").__name__) + wrapper.__name__ = func_name + wrapper.__doc__ = func.__doc__ + + return wrapper + + +def condition_as_parse_action( + fn: ParseCondition, message: typing.Optional[str] = None, fatal: bool = False +) -> ParseAction: + """ + Function to convert a simple predicate function that returns ``True`` or ``False`` + into a parse action. Can be used in places when a parse action is required + and :class:`ParserElement.add_condition` cannot be used (such as when adding a condition + to an operator level in :class:`infix_notation`). + + Optional keyword arguments: + + - ``message`` - define a custom message to be used in the raised exception + - ``fatal`` - if True, will raise :class:`ParseFatalException` to stop parsing immediately; + otherwise will raise :class:`ParseException` + + """ + msg = message if message is not None else "failed user-defined condition" + exc_type = ParseFatalException if fatal else ParseException + fn = _trim_arity(fn) + + @wraps(fn) + def pa(s, l, t): + if not bool(fn(s, l, t)): + raise exc_type(s, l, msg) + + return pa + + +def _default_start_debug_action( + instring: str, loc: int, expr: "ParserElement", cache_hit: bool = False +): + cache_hit_str = "*" if cache_hit else "" + print( + ( + f"{cache_hit_str}Match {expr} at loc {loc}({lineno(loc, instring)},{col(loc, instring)})\n" + f" {line(loc, instring)}\n" + f" {' ' * (col(loc, instring) - 1)}^" + ) + ) + + +def _default_success_debug_action( + instring: str, + startloc: int, + endloc: int, + expr: "ParserElement", + toks: ParseResults, + cache_hit: bool = False, +): + cache_hit_str = "*" if cache_hit else "" + print(f"{cache_hit_str}Matched {expr} -> {toks.as_list()}") + + +def _default_exception_debug_action( + instring: str, + loc: int, + expr: "ParserElement", + exc: Exception, + cache_hit: bool = False, +): + cache_hit_str = "*" if cache_hit else "" + print(f"{cache_hit_str}Match {expr} failed, {type(exc).__name__} raised: {exc}") + + +def null_debug_action(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + + +class ParserElement(ABC): + """Abstract base level parser element class.""" + + DEFAULT_WHITE_CHARS: str = " \n\t\r" + verbose_stacktrace: bool = False + _literalStringClass: type = None # type: ignore[assignment] + + @staticmethod + def set_default_whitespace_chars(chars: str) -> None: + r""" + Overrides the default whitespace chars + + Example:: + + # default whitespace chars are space, <TAB> and newline + Word(alphas)[1, ...].parse_string("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.set_default_whitespace_chars(" \t") + Word(alphas)[1, ...].parse_string("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + # update whitespace all parse expressions defined in this module + for expr in _builtin_exprs: + if expr.copyDefaultWhiteChars: + expr.whiteChars = set(chars) + + @staticmethod + def inline_literals_using(cls: type) -> None: + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parse_string("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inline_literals_using(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parse_string("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + @classmethod + def using_each(cls, seq, **class_kwargs): + """ + Yields a sequence of class(obj, **class_kwargs) for obj in seq. + + Example:: + + LPAR, RPAR, LBRACE, RBRACE, SEMI = Suppress.using_each("(){};") + + """ + yield from (cls(obj, **class_kwargs) for obj in seq) + + class DebugActions(NamedTuple): + debug_try: typing.Optional[DebugStartAction] + debug_match: typing.Optional[DebugSuccessAction] + debug_fail: typing.Optional[DebugExceptionAction] + + def __init__(self, savelist: bool = False): + self.parseAction: List[ParseAction] = list() + self.failAction: typing.Optional[ParseFailAction] = None + self.customName: str = None # type: ignore[assignment] + self._defaultName: typing.Optional[str] = None + self.resultsName: str = None # type: ignore[assignment] + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = set(ParserElement.DEFAULT_WHITE_CHARS) + self.copyDefaultWhiteChars = True + # used when checking for left-recursion + self.mayReturnEmpty = False + self.keepTabs = False + self.ignoreExprs: List["ParserElement"] = list() + self.debug = False + self.streamlined = False + # optimize exception handling for subclasses that don't advance parse index + self.mayIndexError = True + self.errmsg = "" + # mark results names as modal (report only last) or cumulative (list all) + self.modalResults = True + # custom debug actions + self.debugActions = self.DebugActions(None, None, None) + # avoid redundant calls to preParse + self.callPreparse = True + self.callDuringTry = False + self.suppress_warnings_: List[Diagnostics] = [] + + def suppress_warning(self, warning_type: Diagnostics) -> "ParserElement": + """ + Suppress warnings emitted for a particular diagnostic on this expression. + + Example:: + + base = pp.Forward() + base.suppress_warning(Diagnostics.warn_on_parse_using_empty_Forward) + + # statement would normally raise a warning, but is now suppressed + print(base.parse_string("x")) + + """ + self.suppress_warnings_.append(warning_type) + return self + + def visit_all(self): + """General-purpose method to yield all expressions and sub-expressions + in a grammar. Typically just for internal use. + """ + to_visit = deque([self]) + seen = set() + while to_visit: + cur = to_visit.popleft() + + # guard against looping forever through recursive grammars + if cur in seen: + continue + seen.add(cur) + + to_visit.extend(cur.recurse()) + yield cur + + def copy(self) -> "ParserElement": + """ + Make a copy of this :class:`ParserElement`. Useful for defining + different parse actions for the same parsing pattern, using copies of + the original parse element. + + Example:: + + integer = Word(nums).set_parse_action(lambda toks: int(toks[0])) + integerK = integer.copy().add_parse_action(lambda toks: toks[0] * 1024) + Suppress("K") + integerM = integer.copy().add_parse_action(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") + + print((integerK | integerM | integer)[1, ...].parse_string("5K 100 640K 256M")) + + prints:: + + [5120, 100, 655360, 268435456] + + Equivalent form of ``expr.copy()`` is just ``expr()``:: + + integerM = integer().add_parse_action(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") + """ + cpy = copy.copy(self) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = set(ParserElement.DEFAULT_WHITE_CHARS) + return cpy + + def set_results_name( + self, name: str, list_all_matches: bool = False, *, listAllMatches: bool = False + ) -> "ParserElement": + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + + Normally, results names are assigned as you would assign keys in a dict: + any existing value is overwritten by later values. If it is necessary to + keep all values captured for a particular results name, call ``set_results_name`` + with ``list_all_matches`` = True. + + NOTE: ``set_results_name`` returns a *copy* of the original :class:`ParserElement` object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + ``expr("name")`` in place of ``expr.set_results_name("name")`` + - see :class:`__call__`. If ``list_all_matches`` is required, use + ``expr("name*")``. + + Example:: + + date_str = (integer.set_results_name("year") + '/' + + integer.set_results_name("month") + '/' + + integer.set_results_name("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + listAllMatches = listAllMatches or list_all_matches + return self._setResultsName(name, listAllMatches) + + def _setResultsName(self, name, listAllMatches=False): + if name is None: + return self + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches = True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def set_break(self, break_flag: bool = True) -> "ParserElement": + """ + Method to invoke the Python pdb debugger when this element is + about to be parsed. Set ``break_flag`` to ``True`` to enable, ``False`` to + disable. + """ + if break_flag: + _parseMethod = self._parse + + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + + # this call to pdb.set_trace() is intentional, not a checkin error + pdb.set_trace() + return _parseMethod(instring, loc, doActions, callPreParse) + + breaker._originalParseMethod = _parseMethod # type: ignore [attr-defined] + self._parse = breaker # type: ignore [assignment] + else: + if hasattr(self._parse, "_originalParseMethod"): + self._parse = self._parse._originalParseMethod # type: ignore [attr-defined, assignment] + return self + + def set_parse_action(self, *fns: ParseAction, **kwargs) -> "ParserElement": + """ + Define one or more actions to perform when successfully matching parse element definition. + + Parse actions can be called to perform data conversions, do extra validation, + update external data structures, or enhance or replace the parsed tokens. + Each parse action ``fn`` is a callable method with 0-3 arguments, called as + ``fn(s, loc, toks)`` , ``fn(loc, toks)`` , ``fn(toks)`` , or just ``fn()`` , where: + + - ``s`` = the original string being parsed (see note below) + - ``loc`` = the location of the matching substring + - ``toks`` = a list of the matched tokens, packaged as a :class:`ParseResults` object + + The parsed tokens are passed to the parse action as ParseResults. They can be + modified in place using list-style append, extend, and pop operations to update + the parsed list elements; and with dictionary-style item set and del operations + to add, update, or remove any named results. If the tokens are modified in place, + it is not necessary to return them with a return statement. + + Parse actions can also completely replace the given tokens, with another ``ParseResults`` + object, or with some entirely different object (common for parse actions that perform data + conversions). A convenient way to build a new parse result is to define the values + using a dict, and then create the return value using :class:`ParseResults.from_dict`. + + If None is passed as the ``fn`` parse action, all previously added parse actions for this + expression are cleared. + + Optional keyword arguments: + + - ``call_during_try`` = (default= ``False``) indicate if parse action should be run during + lookaheads and alternate testing. For parse actions that have side effects, it is + important to only call the parse action once it is determined that it is being + called as part of a successful parse. For parse actions that perform additional + validation, then call_during_try should be passed as True, so that the validation + code is included in the preliminary "try" parses. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See :class:`parse_string` for more + information on parsing strings containing ``<TAB>`` s, and suggested + methods to maintain a consistent view of the parsed string, the parse + location, and line and column positions within the parsed string. + + Example:: + + # parse dates in the form YYYY/MM/DD + + # use parse action to convert toks from str to int at parse time + def convert_to_int(toks): + return int(toks[0]) + + # use a parse action to verify that the date is a valid date + def is_valid_date(instring, loc, toks): + from datetime import date + year, month, day = toks[::2] + try: + date(year, month, day) + except ValueError: + raise ParseException(instring, loc, "invalid date given") + + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + # add parse actions + integer.set_parse_action(convert_to_int) + date_str.set_parse_action(is_valid_date) + + # note that integer fields are now ints, not strings + date_str.run_tests(''' + # successful parse - note that integer fields were converted to ints + 1999/12/31 + + # fail - invalid date + 1999/13/31 + ''') + """ + if list(fns) == [None]: + self.parseAction = [] + else: + if not all(callable(fn) for fn in fns): + raise TypeError("parse actions must be callable") + self.parseAction = [_trim_arity(fn) for fn in fns] + self.callDuringTry = kwargs.get( + "call_during_try", kwargs.get("callDuringTry", False) + ) + return self + + def add_parse_action(self, *fns: ParseAction, **kwargs) -> "ParserElement": + """ + Add one or more parse actions to expression's list of parse actions. See :class:`set_parse_action`. + + See examples in :class:`copy`. + """ + self.parseAction += [_trim_arity(fn) for fn in fns] + self.callDuringTry = self.callDuringTry or kwargs.get( + "call_during_try", kwargs.get("callDuringTry", False) + ) + return self + + def add_condition(self, *fns: ParseCondition, **kwargs) -> "ParserElement": + """Add a boolean predicate function to expression's list of parse actions. See + :class:`set_parse_action` for function call signatures. Unlike ``set_parse_action``, + functions passed to ``add_condition`` need to return boolean success/fail of the condition. + + Optional keyword arguments: + + - ``message`` = define a custom message to be used in the raised exception + - ``fatal`` = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise + ParseException + - ``call_during_try`` = boolean to indicate if this method should be called during internal tryParse calls, + default=False + + Example:: + + integer = Word(nums).set_parse_action(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.add_condition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parse_string("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), + (line:1, col:1) + """ + for fn in fns: + self.parseAction.append( + condition_as_parse_action( + fn, + message=str(kwargs.get("message")), + fatal=bool(kwargs.get("fatal", False)), + ) + ) + + self.callDuringTry = self.callDuringTry or kwargs.get( + "call_during_try", kwargs.get("callDuringTry", False) + ) + return self + + def set_fail_action(self, fn: ParseFailAction) -> "ParserElement": + """ + Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + ``fn(s, loc, expr, err)`` where: + + - ``s`` = string being parsed + - ``loc`` = location where expression match was attempted and failed + - ``expr`` = the parse expression that failed + - ``err`` = the exception thrown + + The function returns no value. It may throw :class:`ParseFatalException` + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables(self, instring: str, loc: int) -> int: + if not self.ignoreExprs: + return loc + exprsFound = True + ignore_expr_fns = [e._parse for e in self.ignoreExprs] + last_loc = loc + while exprsFound: + exprsFound = False + for ignore_fn in ignore_expr_fns: + try: + while 1: + loc, dummy = ignore_fn(instring, loc) + exprsFound = True + except ParseException: + pass + # check if all ignore exprs matched but didn't actually advance the parse location + if loc == last_loc: + break + last_loc = loc + return loc + + def preParse(self, instring: str, loc: int) -> int: + if self.ignoreExprs: + loc = self._skipIgnorables(instring, loc) + + if self.skipWhitespace: + instrlen = len(instring) + white_chars = self.whiteChars + while loc < instrlen and instring[loc] in white_chars: + loc += 1 + + return loc + + def parseImpl(self, instring, loc, doActions=True): + return loc, [] + + def postParse(self, instring, loc, tokenlist): + return tokenlist + + # @profile + def _parseNoCache( + self, instring, loc, doActions=True, callPreParse=True + ) -> Tuple[int, ParseResults]: + TRY, MATCH, FAIL = 0, 1, 2 + debugging = self.debug # and doActions) + len_instring = len(instring) + + if debugging or self.failAction: + # print("Match {} at loc {}({}, {})".format(self, loc, lineno(loc, instring), col(loc, instring))) + try: + if callPreParse and self.callPreparse: + pre_loc = self.preParse(instring, loc) + else: + pre_loc = loc + tokens_start = pre_loc + if self.debugActions.debug_try: + self.debugActions.debug_try(instring, tokens_start, self, False) + if self.mayIndexError or pre_loc >= len_instring: + try: + loc, tokens = self.parseImpl(instring, pre_loc, doActions) + except IndexError: + raise ParseException(instring, len_instring, self.errmsg, self) + else: + loc, tokens = self.parseImpl(instring, pre_loc, doActions) + except Exception as err: + # print("Exception raised:", err) + if self.debugActions.debug_fail: + self.debugActions.debug_fail( + instring, tokens_start, self, err, False + ) + if self.failAction: + self.failAction(instring, tokens_start, self, err) + raise + else: + if callPreParse and self.callPreparse: + pre_loc = self.preParse(instring, loc) + else: + pre_loc = loc + tokens_start = pre_loc + if self.mayIndexError or pre_loc >= len_instring: + try: + loc, tokens = self.parseImpl(instring, pre_loc, doActions) + except IndexError: + raise ParseException(instring, len_instring, self.errmsg, self) + else: + loc, tokens = self.parseImpl(instring, pre_loc, doActions) + + tokens = self.postParse(instring, loc, tokens) + + ret_tokens = ParseResults( + tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults + ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + try: + tokens = fn(instring, tokens_start, ret_tokens) # type: ignore [call-arg, arg-type] + except IndexError as parse_action_exc: + exc = ParseException("exception raised in parse action") + raise exc from parse_action_exc + + if tokens is not None and tokens is not ret_tokens: + ret_tokens = ParseResults( + tokens, + self.resultsName, + asList=self.saveAsList + and isinstance(tokens, (ParseResults, list)), + modal=self.modalResults, + ) + except Exception as err: + # print "Exception raised in user parse action:", err + if self.debugActions.debug_fail: + self.debugActions.debug_fail( + instring, tokens_start, self, err, False + ) + raise + else: + for fn in self.parseAction: + try: + tokens = fn(instring, tokens_start, ret_tokens) # type: ignore [call-arg, arg-type] + except IndexError as parse_action_exc: + exc = ParseException("exception raised in parse action") + raise exc from parse_action_exc + + if tokens is not None and tokens is not ret_tokens: + ret_tokens = ParseResults( + tokens, + self.resultsName, + asList=self.saveAsList + and isinstance(tokens, (ParseResults, list)), + modal=self.modalResults, + ) + if debugging: + # print("Matched", self, "->", ret_tokens.as_list()) + if self.debugActions.debug_match: + self.debugActions.debug_match( + instring, tokens_start, loc, self, ret_tokens, False + ) + + return loc, ret_tokens + + def try_parse( + self, + instring: str, + loc: int, + *, + raise_fatal: bool = False, + do_actions: bool = False, + ) -> int: + try: + return self._parse(instring, loc, doActions=do_actions)[0] + except ParseFatalException: + if raise_fatal: + raise + raise ParseException(instring, loc, self.errmsg, self) + + def can_parse_next(self, instring: str, loc: int, do_actions: bool = False) -> bool: + try: + self.try_parse(instring, loc, do_actions=do_actions) + except (ParseException, IndexError): + return False + else: + return True + + # cache for left-recursion in Forward references + recursion_lock = RLock() + recursion_memos: typing.Dict[ + Tuple[int, "Forward", bool], Tuple[int, Union[ParseResults, Exception]] + ] = {} + + class _CacheType(dict): + """ + class to help type checking + """ + + not_in_cache: bool + + def get(self, *args): + ... + + def set(self, *args): + ... + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = ( + _CacheType() + ) # set later by enable_packrat(); this is here so that reset_cache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( + self, instring, loc, doActions=True, callPreParse=True + ) -> Tuple[int, ParseResults]: + HIT, MISS = 0, 1 + TRY, MATCH, FAIL = 0, 1, 2 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy(), loc)) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if self.debug and self.debugActions.debug_try: + try: + self.debugActions.debug_try(instring, loc, self, cache_hit=True) # type: ignore [call-arg] + except TypeError: + pass + if isinstance(value, Exception): + if self.debug and self.debugActions.debug_fail: + try: + self.debugActions.debug_fail( + instring, loc, self, value, cache_hit=True # type: ignore [call-arg] + ) + except TypeError: + pass + raise value + + value = cast(Tuple[int, ParseResults, int], value) + loc_, result, endloc = value[0], value[1].copy(), value[2] + if self.debug and self.debugActions.debug_match: + try: + self.debugActions.debug_match( + instring, loc_, endloc, self, result, cache_hit=True # type: ignore [call-arg] + ) + except TypeError: + pass + + return loc_, result + + _parse = _parseNoCache + + @staticmethod + def reset_cache() -> None: + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len( + ParserElement.packrat_cache_stats + ) + ParserElement.recursion_memos.clear() + + _packratEnabled = False + _left_recursion_enabled = False + + @staticmethod + def disable_memoization() -> None: + """ + Disables active Packrat or Left Recursion parsing and their memoization + + This method also works if neither Packrat nor Left Recursion are enabled. + This makes it safe to call before activating Packrat nor Left Recursion + to clear any previous settings. + """ + ParserElement.reset_cache() + ParserElement._left_recursion_enabled = False + ParserElement._packratEnabled = False + ParserElement._parse = ParserElement._parseNoCache + + @staticmethod + def enable_left_recursion( + cache_size_limit: typing.Optional[int] = None, *, force=False + ) -> None: + """ + Enables "bounded recursion" parsing, which allows for both direct and indirect + left-recursion. During parsing, left-recursive :class:`Forward` elements are + repeatedly matched with a fixed recursion depth that is gradually increased + until finding the longest match. + + Example:: + + import pyparsing as pp + pp.ParserElement.enable_left_recursion() + + E = pp.Forward("E") + num = pp.Word(pp.nums) + # match `num`, or `num '+' num`, or `num '+' num '+' num`, ... + E <<= E + '+' - num | num + + print(E.parse_string("1+2+3")) + + Recursion search naturally memoizes matches of ``Forward`` elements and may + thus skip reevaluation of parse actions during backtracking. This may break + programs with parse actions which rely on strict ordering of side-effects. + + Parameters: + + - ``cache_size_limit`` - (default=``None``) - memoize at most this many + ``Forward`` elements during matching; if ``None`` (the default), + memoize all ``Forward`` elements. + + Bounded Recursion parsing works similar but not identical to Packrat parsing, + thus the two cannot be used together. Use ``force=True`` to disable any + previous, conflicting settings. + """ + if force: + ParserElement.disable_memoization() + elif ParserElement._packratEnabled: + raise RuntimeError("Packrat and Bounded Recursion are not compatible") + if cache_size_limit is None: + ParserElement.recursion_memos = _UnboundedMemo() # type: ignore[assignment] + elif cache_size_limit > 0: + ParserElement.recursion_memos = _LRUMemo(capacity=cache_size_limit) # type: ignore[assignment] + else: + raise NotImplementedError("Memo size of %s" % cache_size_limit) + ParserElement._left_recursion_enabled = True + + @staticmethod + def enable_packrat( + cache_size_limit: Union[int, None] = 128, *, force: bool = False + ) -> None: + """ + Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + + - ``cache_size_limit`` - (default= ``128``) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method :class:`ParserElement.enable_packrat`. + For best results, call ``enable_packrat()`` immediately after + importing pyparsing. + + Example:: + + import pyparsing + pyparsing.ParserElement.enable_packrat() + + Packrat parsing works similar but not identical to Bounded Recursion parsing, + thus the two cannot be used together. Use ``force=True`` to disable any + previous, conflicting settings. + """ + if force: + ParserElement.disable_memoization() + elif ParserElement._left_recursion_enabled: + raise RuntimeError("Packrat and Bounded Recursion are not compatible") + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = _UnboundedCache() + else: + ParserElement.packrat_cache = _FifoCache(cache_size_limit) # type: ignore[assignment] + ParserElement._parse = ParserElement._parseCache + + def parse_string( + self, instring: str, parse_all: bool = False, *, parseAll: bool = False + ) -> ParseResults: + """ + Parse a string with respect to the parser definition. This function is intended as the primary interface to the + client code. + + :param instring: The input string to be parsed. + :param parse_all: If set, the entire input string must match the grammar. + :param parseAll: retained for pre-PEP8 compatibility, will be removed in a future release. + :raises ParseException: Raised if ``parse_all`` is set and the input string does not match the whole grammar. + :returns: the parsed data as a :class:`ParseResults` object, which may be accessed as a `list`, a `dict`, or + an object with attributes if the given parser includes results names. + + If the input string is required to match the entire grammar, ``parse_all`` flag must be set to ``True``. This + is also equivalent to ending the grammar with :class:`StringEnd`\\ (). + + To report proper column numbers, ``parse_string`` operates on a copy of the input string where all tabs are + converted to spaces (8 spaces per tab, as per the default in ``string.expandtabs``). If the input string + contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string + being parsed, one can ensure a consistent view of the input string by doing one of the following: + + - calling ``parse_with_tabs`` on your grammar before calling ``parse_string`` (see :class:`parse_with_tabs`), + - define your parse action using the full ``(s,loc,toks)`` signature, and reference the input string using the + parse action's ``s`` argument, or + - explicitly expand the tabs in your input string before calling ``parse_string``. + + Examples: + + By default, partial matches are OK. + + >>> res = Word('a').parse_string('aaaaabaaa') + >>> print(res) + ['aaaaa'] + + The parsing behavior varies by the inheriting class of this abstract class. Please refer to the children + directly to see more examples. + + It raises an exception if parse_all flag is set and instring does not match the whole grammar. + + >>> res = Word('a').parse_string('aaaaabaaa', parse_all=True) + Traceback (most recent call last): + ... + pyparsing.ParseException: Expected end of text, found 'b' (at char 5), (line:1, col:6) + """ + parseAll = parse_all or parseAll + + ParserElement.reset_cache() + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse(instring, 0) + if parseAll: + loc = self.preParse(instring, loc) + se = Empty() + StringEnd() + se._parse(instring, loc) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + raise exc.with_traceback(None) + else: + return tokens + + def scan_string( + self, + instring: str, + max_matches: int = _MAX_INT, + overlap: bool = False, + *, + debug: bool = False, + maxMatches: int = _MAX_INT, + ) -> Generator[Tuple[ParseResults, int, int], None, None]: + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + ``max_matches`` argument, to clip scanning after 'n' matches are found. If + ``overlap`` is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See :class:`parse_string` for more information on parsing + strings with embedded tabs. + + Example:: + + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens, start, end in Word(alphas).scan_string(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + maxMatches = min(maxMatches, max_matches) + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = str(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc: int = preparseFn(instring, loc) + nextLoc: int + tokens: ParseResults + nextLoc, tokens = parseFn(instring, preloc, callPreParse=False) + except ParseException: + loc = preloc + 1 + else: + if nextLoc > loc: + matches += 1 + if debug: + print( + { + "tokens": tokens.asList(), + "start": preloc, + "end": nextLoc, + } + ) + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn(instring, loc) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc + 1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc.with_traceback(None) + + def transform_string(self, instring: str, *, debug: bool = False) -> str: + """ + Extension to :class:`scan_string`, to modify matching text with modified tokens that may + be returned from a parse action. To use ``transform_string``, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking ``transform_string()`` on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. ``transform_string()`` returns the resulting transformed string. + + Example:: + + wd = Word(alphas) + wd.set_parse_action(lambda toks: toks[0].title()) + + print(wd.transform_string("now is the winter of our discontent made glorious summer by this sun of york.")) + + prints:: + + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out: List[str] = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transform_string and scan_string + self.keepTabs = True + try: + for t, s, e in self.scan_string(instring, debug=debug): + out.append(instring[lastE:s]) + if t: + if isinstance(t, ParseResults): + out += t.as_list() + elif isinstance(t, Iterable) and not isinstance(t, str_type): + out.extend(t) + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join([str(s) for s in _flatten(out)]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc.with_traceback(None) + + def search_string( + self, + instring: str, + max_matches: int = _MAX_INT, + *, + debug: bool = False, + maxMatches: int = _MAX_INT, + ) -> ParseResults: + """ + Another extension to :class:`scan_string`, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + ``max_matches`` argument, to clip searching after 'n' matches are found. + + Example:: + + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.search_string("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.search_string("More than Iron, more than Lead, more than Gold I need Electricity"))) + + prints:: + + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + maxMatches = min(maxMatches, max_matches) + try: + return ParseResults( + [t for t, s, e in self.scan_string(instring, maxMatches, debug=debug)] + ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc.with_traceback(None) + + def split( + self, + instring: str, + maxsplit: int = _MAX_INT, + include_separators: bool = False, + *, + includeSeparators=False, + ) -> Generator[str, None, None]: + """ + Generator method to split a string using the given expression as a separator. + May be called with optional ``maxsplit`` argument, to limit the number of splits; + and the optional ``include_separators`` argument (default= ``False``), if the separating + matching text should be included in the split results. + + Example:: + + punc = one_of(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + + prints:: + + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + includeSeparators = includeSeparators or include_separators + last = 0 + for t, s, e in self.scan_string(instring, max_matches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other) -> "ParserElement": + """ + Implementation of ``+`` operator - returns :class:`And`. Adding strings to a :class:`ParserElement` + converts them to :class:`Literal`\\ s by default. + + Example:: + + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print(hello, "->", greet.parse_string(hello)) + + prints:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + + ``...`` may be used as a parse expression as a short form of :class:`SkipTo`:: + + Literal('start') + ... + Literal('end') + + is equivalent to:: + + Literal('start') + SkipTo('end')("_skipped*") + Literal('end') + + Note that the skipped text is returned with '_skipped' as a results name, + and to support having multiple skips in the same parser, the value returned is + a list of all skipped text. + """ + if other is Ellipsis: + return _PendingSkip(self) + + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return And([self, other]) + + def __radd__(self, other) -> "ParserElement": + """ + Implementation of ``+`` operator when left operand is not a :class:`ParserElement` + """ + if other is Ellipsis: + return SkipTo(self)("_skipped*") + self + + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return other + self + + def __sub__(self, other) -> "ParserElement": + """ + Implementation of ``-`` operator, returns :class:`And` with error stop + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return self + And._ErrorStop() + other + + def __rsub__(self, other) -> "ParserElement": + """ + Implementation of ``-`` operator when left operand is not a :class:`ParserElement` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return other - self + + def __mul__(self, other) -> "ParserElement": + """ + Implementation of ``*`` operator, allows use of ``expr * 3`` in place of + ``expr + expr + expr``. Expressions may also be multiplied by a 2-integer + tuple, similar to ``{min, max}`` multipliers in regular expressions. Tuples + may also include ``None`` as in: + + - ``expr*(n, None)`` or ``expr*(n, )`` is equivalent + to ``expr*n + ZeroOrMore(expr)`` + (read as "at least n instances of ``expr``") + - ``expr*(None, n)`` is equivalent to ``expr*(0, n)`` + (read as "0 to n instances of ``expr``") + - ``expr*(None, None)`` is equivalent to ``ZeroOrMore(expr)`` + - ``expr*(1, None)`` is equivalent to ``OneOrMore(expr)`` + + Note that ``expr*(None, n)`` does not raise an exception if + more than n exprs exist in the input stream; that is, + ``expr*(None, n)`` does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + ``expr*(None, n) + ~expr`` + """ + if other is Ellipsis: + other = (0, None) + elif isinstance(other, tuple) and other[:1] == (Ellipsis,): + other = ((0,) + other[1:] + (None,))[:2] + + if isinstance(other, int): + minElements, optElements = other, 0 + elif isinstance(other, tuple): + other = tuple(o if o is not Ellipsis else None for o in other) + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0], int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self * other[0] + ZeroOrMore(self) + elif isinstance(other[0], int) and isinstance(other[1], int): + minElements, optElements = other + optElements -= minElements + else: + return NotImplemented + else: + return NotImplemented + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError( + "second tuple value must be greater or equal to first tuple value" + ) + if minElements == optElements == 0: + return And([]) + + if optElements: + + def makeOptionalList(n): + if n > 1: + return Opt(self + makeOptionalList(n - 1)) + else: + return Opt(self) + + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self] * minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self] * minElements) + return ret + + def __rmul__(self, other) -> "ParserElement": + return self.__mul__(other) + + def __or__(self, other) -> "ParserElement": + """ + Implementation of ``|`` operator - returns :class:`MatchFirst` + """ + if other is Ellipsis: + return _PendingSkip(self, must_skip=True) + + if isinstance(other, str_type): + # `expr | ""` is equivalent to `Opt(expr)` + if other == "": + return Opt(self) + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return MatchFirst([self, other]) + + def __ror__(self, other) -> "ParserElement": + """ + Implementation of ``|`` operator when left operand is not a :class:`ParserElement` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return other | self + + def __xor__(self, other) -> "ParserElement": + """ + Implementation of ``^`` operator - returns :class:`Or` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return Or([self, other]) + + def __rxor__(self, other) -> "ParserElement": + """ + Implementation of ``^`` operator when left operand is not a :class:`ParserElement` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return other ^ self + + def __and__(self, other) -> "ParserElement": + """ + Implementation of ``&`` operator - returns :class:`Each` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return Each([self, other]) + + def __rand__(self, other) -> "ParserElement": + """ + Implementation of ``&`` operator when left operand is not a :class:`ParserElement` + """ + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return other & self + + def __invert__(self) -> "ParserElement": + """ + Implementation of ``~`` operator - returns :class:`NotAny` + """ + return NotAny(self) + + # disable __iter__ to override legacy use of sequential access to __getitem__ to + # iterate over a sequence + __iter__ = None + + def __getitem__(self, key): + """ + use ``[]`` indexing notation as a short form for expression repetition: + + - ``expr[n]`` is equivalent to ``expr*n`` + - ``expr[m, n]`` is equivalent to ``expr*(m, n)`` + - ``expr[n, ...]`` or ``expr[n,]`` is equivalent + to ``expr*n + ZeroOrMore(expr)`` + (read as "at least n instances of ``expr``") + - ``expr[..., n]`` is equivalent to ``expr*(0, n)`` + (read as "0 to n instances of ``expr``") + - ``expr[...]`` and ``expr[0, ...]`` are equivalent to ``ZeroOrMore(expr)`` + - ``expr[1, ...]`` is equivalent to ``OneOrMore(expr)`` + + ``None`` may be used in place of ``...``. + + Note that ``expr[..., n]`` and ``expr[m, n]`` do not raise an exception + if more than ``n`` ``expr``\\ s exist in the input stream. If this behavior is + desired, then write ``expr[..., n] + ~expr``. + + For repetition with a stop_on expression, use slice notation: + + - ``expr[...: end_expr]`` and ``expr[0, ...: end_expr]`` are equivalent to ``ZeroOrMore(expr, stop_on=end_expr)`` + - ``expr[1, ...: end_expr]`` is equivalent to ``OneOrMore(expr, stop_on=end_expr)`` + + """ + + stop_on_defined = False + stop_on = NoMatch() + if isinstance(key, slice): + key, stop_on = key.start, key.stop + if key is None: + key = ... + stop_on_defined = True + elif isinstance(key, tuple) and isinstance(key[-1], slice): + key, stop_on = (key[0], key[1].start), key[1].stop + stop_on_defined = True + + # convert single arg keys to tuples + if isinstance(key, str_type): + key = (key,) + try: + iter(key) + except TypeError: + key = (key, key) + + if len(key) > 2: + raise TypeError( + f"only 1 or 2 index arguments supported ({key[:5]}{f'... [{len(key)}]' if len(key) > 5 else ''})" + ) + + # clip to 2 elements + ret = self * tuple(key[:2]) + ret = typing.cast(_MultipleMatch, ret) + + if stop_on_defined: + ret.stopOn(stop_on) + + return ret + + def __call__(self, name: typing.Optional[str] = None) -> "ParserElement": + """ + Shortcut for :class:`set_results_name`, with ``list_all_matches=False``. + + If ``name`` is given with a trailing ``'*'`` character, then ``list_all_matches`` will be + passed as ``True``. + + If ``name`` is omitted, same as calling :class:`copy`. + + Example:: + + # these are equivalent + userdata = Word(alphas).set_results_name("name") + Word(nums + "-").set_results_name("socsecno") + userdata = Word(alphas)("name") + Word(nums + "-")("socsecno") + """ + if name is not None: + return self._setResultsName(name) + else: + return self.copy() + + def suppress(self) -> "ParserElement": + """ + Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress(self) + + def ignore_whitespace(self, recursive: bool = True) -> "ParserElement": + """ + Enables the skipping of whitespace before matching the characters in the + :class:`ParserElement`'s defined pattern. + + :param recursive: If ``True`` (the default), also enable whitespace skipping in child elements (if any) + """ + self.skipWhitespace = True + return self + + def leave_whitespace(self, recursive: bool = True) -> "ParserElement": + """ + Disables the skipping of whitespace before matching the characters in the + :class:`ParserElement`'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + + :param recursive: If true (the default), also disable whitespace skipping in child elements (if any) + """ + self.skipWhitespace = False + return self + + def set_whitespace_chars( + self, chars: Union[Set[str], str], copy_defaults: bool = False + ) -> "ParserElement": + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = set(chars) + self.copyDefaultWhiteChars = copy_defaults + return self + + def parse_with_tabs(self) -> "ParserElement": + """ + Overrides default behavior to expand ``<TAB>`` s to spaces before parsing the input string. + Must be called before ``parse_string`` when the input grammar contains elements that + match ``<TAB>`` characters. + """ + self.keepTabs = True + return self + + def ignore(self, other: "ParserElement") -> "ParserElement": + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + + patt = Word(alphas)[1, ...] + patt.parse_string('ablaj /* comment */ lskjd') + # -> ['ablaj'] + + patt.ignore(c_style_comment) + patt.parse_string('ablaj /* comment */ lskjd') + # -> ['ablaj', 'lskjd'] + """ + import typing + + if isinstance(other, str_type): + other = Suppress(other) + + if isinstance(other, Suppress): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append(Suppress(other.copy())) + return self + + def set_debug_actions( + self, + start_action: DebugStartAction, + success_action: DebugSuccessAction, + exception_action: DebugExceptionAction, + ) -> "ParserElement": + """ + Customize display of debugging messages while doing pattern matching: + + - ``start_action`` - method to be called when an expression is about to be parsed; + should have the signature ``fn(input_string: str, location: int, expression: ParserElement, cache_hit: bool)`` + + - ``success_action`` - method to be called when an expression has successfully parsed; + should have the signature ``fn(input_string: str, start_location: int, end_location: int, expression: ParserELement, parsed_tokens: ParseResults, cache_hit: bool)`` + + - ``exception_action`` - method to be called when expression fails to parse; + should have the signature ``fn(input_string: str, location: int, expression: ParserElement, exception: Exception, cache_hit: bool)`` + """ + self.debugActions = self.DebugActions( + start_action or _default_start_debug_action, # type: ignore[truthy-function] + success_action or _default_success_debug_action, # type: ignore[truthy-function] + exception_action or _default_exception_debug_action, # type: ignore[truthy-function] + ) + self.debug = True + return self + + def set_debug(self, flag: bool = True, recurse: bool = False) -> "ParserElement": + """ + Enable display of debugging messages while doing pattern matching. + Set ``flag`` to ``True`` to enable, ``False`` to disable. + Set ``recurse`` to ``True`` to set the debug flag on this expression and all sub-expressions. + + Example:: + + wd = Word(alphas).set_name("alphaword") + integer = Word(nums).set_name("numword") + term = wd | integer + + # turn on debugging for wd + wd.set_debug() + + term[1, ...].parse_string("abc 123 xyz 890") + + prints:: + + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using :class:`set_debug_actions`. Prior to attempting + to match the ``wd`` expression, the debugging message ``"Match <exprname> at loc <n>(<line>,<col>)"`` + is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"`` + message is shown. Also note the use of :class:`set_name` to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the :class:`Word` expression without calling ``set_name`` is ``"W:(A-Za-z)"``. + """ + if recurse: + for expr in self.visit_all(): + expr.set_debug(flag, recurse=False) + return self + + if flag: + self.set_debug_actions( + _default_start_debug_action, + _default_success_debug_action, + _default_exception_debug_action, + ) + else: + self.debug = False + return self + + @property + def default_name(self) -> str: + if self._defaultName is None: + self._defaultName = self._generateDefaultName() + return self._defaultName + + @abstractmethod + def _generateDefaultName(self) -> str: + """ + Child classes must define this method, which defines how the ``default_name`` is set. + """ + + def set_name(self, name: str) -> "ParserElement": + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + + Word(nums).parse_string("ABC") # -> Exception: Expected W:(0-9) (at char 0), (line:1, col:1) + Word(nums).set_name("integer").parse_string("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.customName = name + self.errmsg = "Expected " + self.name + if __diag__.enable_debug_on_named_expressions: + self.set_debug() + return self + + @property + def name(self) -> str: + # This will use a user-defined name if available, but otherwise defaults back to the auto-generated name + return self.customName if self.customName is not None else self.default_name + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return str(self) + + def streamline(self) -> "ParserElement": + self.streamlined = True + self._defaultName = None + return self + + def recurse(self) -> List["ParserElement"]: + return [] + + def _checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] + for e in self.recurse(): + e._checkRecursion(subRecCheckList) + + def validate(self, validateTrace=None) -> None: + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + warnings.warn( + "ParserElement.validate() is deprecated, and should not be used to check for left recursion", + DeprecationWarning, + stacklevel=2, + ) + self._checkRecursion([]) + + def parse_file( + self, + file_or_filename: Union[str, Path, TextIO], + encoding: str = "utf-8", + parse_all: bool = False, + *, + parseAll: bool = False, + ) -> ParseResults: + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + parseAll = parseAll or parse_all + try: + file_or_filename = typing.cast(TextIO, file_or_filename) + file_contents = file_or_filename.read() + except AttributeError: + file_or_filename = typing.cast(str, file_or_filename) + with open(file_or_filename, "r", encoding=encoding) as f: + file_contents = f.read() + try: + return self.parse_string(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc.with_traceback(None) + + def __eq__(self, other): + if self is other: + return True + elif isinstance(other, str_type): + return self.matches(other, parse_all=True) + elif isinstance(other, ParserElement): + return vars(self) == vars(other) + return False + + def __hash__(self): + return id(self) + + def matches( + self, test_string: str, parse_all: bool = True, *, parseAll: bool = True + ) -> bool: + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + + - ``test_string`` - to test against this expression for a match + - ``parse_all`` - (default= ``True``) - flag to pass to :class:`parse_string` when running tests + + Example:: + + expr = Word(nums) + assert expr.matches("100") + """ + parseAll = parseAll and parse_all + try: + self.parse_string(str(test_string), parse_all=parseAll) + return True + except ParseBaseException: + return False + + def run_tests( + self, + tests: Union[str, List[str]], + parse_all: bool = True, + comment: typing.Optional[Union["ParserElement", str]] = "#", + full_dump: bool = True, + print_results: bool = True, + failure_tests: bool = False, + post_parse: typing.Optional[Callable[[str, ParseResults], str]] = None, + file: typing.Optional[TextIO] = None, + with_line_numbers: bool = False, + *, + parseAll: bool = True, + fullDump: bool = True, + printResults: bool = True, + failureTests: bool = False, + postParse: typing.Optional[Callable[[str, ParseResults], str]] = None, + ) -> Tuple[bool, List[Tuple[str, Union[ParseResults, Exception]]]]: + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + + - ``tests`` - a list of separate test strings, or a multiline string of test strings + - ``parse_all`` - (default= ``True``) - flag to pass to :class:`parse_string` when running tests + - ``comment`` - (default= ``'#'``) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - ``full_dump`` - (default= ``True``) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - ``print_results`` - (default= ``True``) prints test output to stdout + - ``failure_tests`` - (default= ``False``) indicates if these tests are expected to fail parsing + - ``post_parse`` - (default= ``None``) optional callback for successful parse results; called as + `fn(test_string, parse_results)` and returns a string to be added to the test output + - ``file`` - (default= ``None``) optional file-like object to which test output will be written; + if None, will default to ``sys.stdout`` + - ``with_line_numbers`` - default= ``False``) show test strings with line and column numbers + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if ``failure_tests`` is True), and the results contain a list of lines of each + test's output + + Example:: + + number_expr = pyparsing_common.number.copy() + + result = number_expr.run_tests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.run_tests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failure_tests=True) + print("Success" if result[0] else "Failed!") + + prints:: + + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.run_tests(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading ``'r'``.) + """ + from .testing import pyparsing_test + + parseAll = parseAll and parse_all + fullDump = fullDump and full_dump + printResults = printResults and print_results + failureTests = failureTests or failure_tests + postParse = postParse or post_parse + if isinstance(tests, str_type): + tests = typing.cast(str, tests) + line_strip = type(tests).strip + tests = [line_strip(test_line) for test_line in tests.rstrip().splitlines()] + comment_specified = comment is not None + if comment_specified: + if isinstance(comment, str_type): + comment = typing.cast(str, comment) + comment = Literal(comment) + comment = typing.cast(ParserElement, comment) + if file is None: + file = sys.stdout + print_ = file.write + + result: Union[ParseResults, Exception] + allResults: List[Tuple[str, Union[ParseResults, Exception]]] = [] + comments: List[str] = [] + success = True + NL = Literal(r"\n").add_parse_action(replace_with("\n")).ignore(quoted_string) + BOM = "\ufeff" + for t in tests: + if comment_specified and comment.matches(t, False) or comments and not t: + comments.append( + pyparsing_test.with_line_numbers(t) if with_line_numbers else t + ) + continue + if not t: + continue + out = [ + "\n" + "\n".join(comments) if comments else "", + pyparsing_test.with_line_numbers(t) if with_line_numbers else t, + ] + comments = [] + try: + # convert newline marks to actual newlines, and strip leading BOM if present + t = NL.transform_string(t.lstrip(BOM)) + result = self.parse_string(t, parse_all=parseAll) + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + out.append(pe.explain()) + out.append("FAIL: " + str(pe)) + if ParserElement.verbose_stacktrace: + out.extend(traceback.format_tb(pe.__traceback__)) + success = success and failureTests + result = pe + except Exception as exc: + out.append(f"FAIL-EXCEPTION: {type(exc).__name__}: {exc}") + if ParserElement.verbose_stacktrace: + out.extend(traceback.format_tb(exc.__traceback__)) + success = success and failureTests + result = exc + else: + success = success and not failureTests + if postParse is not None: + try: + pp_value = postParse(t, result) + if pp_value is not None: + if isinstance(pp_value, ParseResults): + out.append(pp_value.dump()) + else: + out.append(str(pp_value)) + else: + out.append(result.dump()) + except Exception as e: + out.append(result.dump(full=fullDump)) + out.append( + f"{postParse.__name__} failed: {type(e).__name__}: {e}" + ) + else: + out.append(result.dump(full=fullDump)) + out.append("") + + if printResults: + print_("\n".join(out)) + + allResults.append((t, result)) + + return success, allResults + + def create_diagram( + self, + output_html: Union[TextIO, Path, str], + vertical: int = 3, + show_results_names: bool = False, + show_groups: bool = False, + embed: bool = False, + **kwargs, + ) -> None: + """ + Create a railroad diagram for the parser. + + Parameters: + + - ``output_html`` (str or file-like object) - output target for generated + diagram HTML + - ``vertical`` (int) - threshold for formatting multiple alternatives vertically + instead of horizontally (default=3) + - ``show_results_names`` - bool flag whether diagram should show annotations for + defined results names + - ``show_groups`` - bool flag whether groups should be highlighted with an unlabeled surrounding box + - ``embed`` - bool flag whether generated HTML should omit <HEAD>, <BODY>, and <DOCTYPE> tags to embed + the resulting HTML in an enclosing HTML source + - ``head`` - str containing additional HTML to insert into the <HEAD> section of the generated code; + can be used to insert custom CSS styling + - ``body`` - str containing additional HTML to insert at the beginning of the <BODY> section of the + generated code + + Additional diagram-formatting keyword arguments can also be included; + see railroad.Diagram class. + """ + + try: + from .diagram import to_railroad, railroad_to_html + except ImportError as ie: + raise Exception( + "must ``pip install pyparsing[diagrams]`` to generate parser railroad diagrams" + ) from ie + + self.streamline() + + railroad = to_railroad( + self, + vertical=vertical, + show_results_names=show_results_names, + show_groups=show_groups, + diagram_kwargs=kwargs, + ) + if isinstance(output_html, (str, Path)): + with open(output_html, "w", encoding="utf-8") as diag_file: + diag_file.write(railroad_to_html(railroad, embed=embed, **kwargs)) + else: + # we were passed a file-like object, just write to it + output_html.write(railroad_to_html(railroad, embed=embed, **kwargs)) + + # Compatibility synonyms + # fmt: off + @staticmethod + @replaced_by_pep8(inline_literals_using) + def inlineLiteralsUsing(): ... + + @staticmethod + @replaced_by_pep8(set_default_whitespace_chars) + def setDefaultWhitespaceChars(): ... + + @replaced_by_pep8(set_results_name) + def setResultsName(self): ... + + @replaced_by_pep8(set_break) + def setBreak(self): ... + + @replaced_by_pep8(set_parse_action) + def setParseAction(self): ... + + @replaced_by_pep8(add_parse_action) + def addParseAction(self): ... + + @replaced_by_pep8(add_condition) + def addCondition(self): ... + + @replaced_by_pep8(set_fail_action) + def setFailAction(self): ... + + @replaced_by_pep8(try_parse) + def tryParse(self): ... + + @staticmethod + @replaced_by_pep8(enable_left_recursion) + def enableLeftRecursion(): ... + + @staticmethod + @replaced_by_pep8(enable_packrat) + def enablePackrat(): ... + + @replaced_by_pep8(parse_string) + def parseString(self): ... + + @replaced_by_pep8(scan_string) + def scanString(self): ... + + @replaced_by_pep8(transform_string) + def transformString(self): ... + + @replaced_by_pep8(search_string) + def searchString(self): ... + + @replaced_by_pep8(ignore_whitespace) + def ignoreWhitespace(self): ... + + @replaced_by_pep8(leave_whitespace) + def leaveWhitespace(self): ... + + @replaced_by_pep8(set_whitespace_chars) + def setWhitespaceChars(self): ... + + @replaced_by_pep8(parse_with_tabs) + def parseWithTabs(self): ... + + @replaced_by_pep8(set_debug_actions) + def setDebugActions(self): ... + + @replaced_by_pep8(set_debug) + def setDebug(self): ... + + @replaced_by_pep8(set_name) + def setName(self): ... + + @replaced_by_pep8(parse_file) + def parseFile(self): ... + + @replaced_by_pep8(run_tests) + def runTests(self): ... + + canParseNext = can_parse_next + resetCache = reset_cache + defaultName = default_name + # fmt: on + + +class _PendingSkip(ParserElement): + # internal placeholder class to hold a place were '...' is added to a parser element, + # once another ParserElement is added, this placeholder will be replaced with a SkipTo + def __init__(self, expr: ParserElement, must_skip: bool = False): + super().__init__() + self.anchor = expr + self.must_skip = must_skip + + def _generateDefaultName(self) -> str: + return str(self.anchor + Empty()).replace("Empty", "...") + + def __add__(self, other) -> "ParserElement": + skipper = SkipTo(other).set_name("...")("_skipped*") + if self.must_skip: + + def must_skip(t): + if not t._skipped or t._skipped.as_list() == [""]: + del t[0] + t.pop("_skipped", None) + + def show_skip(t): + if t._skipped.as_list()[-1:] == [""]: + t.pop("_skipped") + t["_skipped"] = "missing <" + repr(self.anchor) + ">" + + return ( + self.anchor + skipper().add_parse_action(must_skip) + | skipper().add_parse_action(show_skip) + ) + other + + return self.anchor + skipper + other + + def __repr__(self): + return self.defaultName + + def parseImpl(self, *args): + raise Exception( + "use of `...` expression without following SkipTo target expression" + ) + + +class Token(ParserElement): + """Abstract :class:`ParserElement` subclass, for defining atomic + matching patterns. + """ + + def __init__(self): + super().__init__(savelist=False) + + def _generateDefaultName(self) -> str: + return type(self).__name__ + + +class NoMatch(Token): + """ + A token that will never match. + """ + + def __init__(self): + super().__init__() + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl(self, instring, loc, doActions=True): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + + Literal('blah').parse_string('blah') # -> ['blah'] + Literal('blah').parse_string('blahfooblah') # -> ['blah'] + Literal('blah').parse_string('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use :class:`CaselessLiteral`. + + For keyword matching (force word break before and after the matched string), + use :class:`Keyword` or :class:`CaselessKeyword`. + """ + + def __new__(cls, match_string: str = "", *, matchString: str = ""): + # Performance tuning: select a subclass with optimized parseImpl + if cls is Literal: + match_string = matchString or match_string + if not match_string: + return super().__new__(Empty) + if len(match_string) == 1: + return super().__new__(_SingleCharLiteral) + + # Default behavior + return super().__new__(cls) + + # Needed to make copy.copy() work correctly if we customize __new__ + def __getnewargs__(self): + return (self.match,) + + def __init__(self, match_string: str = "", *, matchString: str = ""): + super().__init__() + match_string = matchString or match_string + self.match = match_string + self.matchLen = len(match_string) + self.firstMatchChar = match_string[:1] + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + def _generateDefaultName(self) -> str: + return repr(self.match) + + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] == self.firstMatchChar and instring.startswith( + self.match, loc + ): + return loc + self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + +class Empty(Literal): + """ + An empty token, will always match. + """ + + def __init__(self, match_string="", *, matchString=""): + super().__init__("") + self.mayReturnEmpty = True + self.mayIndexError = False + + def _generateDefaultName(self) -> str: + return "Empty" + + def parseImpl(self, instring, loc, doActions=True): + return loc, [] + + +class _SingleCharLiteral(Literal): + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] == self.firstMatchChar: + return loc + 1, self.match + raise ParseException(instring, loc, self.errmsg, self) + + +ParserElement._literalStringClass = Literal + + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, + it must be immediately preceded and followed by whitespace or + non-keyword characters. Compare with :class:`Literal`: + + - ``Literal("if")`` will match the leading ``'if'`` in + ``'ifAndOnlyIf'``. + - ``Keyword("if")`` will not; it will only match the leading + ``'if'`` in ``'if x=1'``, or ``'if(y==2)'`` + + Accepts two optional constructor arguments in addition to the + keyword string: + + - ``ident_chars`` is a string of characters that would be valid + identifier characters, defaulting to all alphanumerics + "_" and + "$" + - ``caseless`` allows case-insensitive matching, default is ``False``. + + Example:: + + Keyword("start").parse_string("start") # -> ['start'] + Keyword("start").parse_string("starting") # -> Exception + + For case-insensitive matching, use :class:`CaselessKeyword`. + """ + + DEFAULT_KEYWORD_CHARS = alphanums + "_$" + + def __init__( + self, + match_string: str = "", + ident_chars: typing.Optional[str] = None, + caseless: bool = False, + *, + matchString: str = "", + identChars: typing.Optional[str] = None, + ): + super().__init__() + identChars = identChars or ident_chars + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + match_string = matchString or match_string + self.match = match_string + self.matchLen = len(match_string) + try: + self.firstMatchChar = match_string[0] + except IndexError: + raise ValueError("null string passed to Keyword; use Empty() instead") + self.errmsg = f"Expected {type(self).__name__} {self.name}" + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = match_string.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def _generateDefaultName(self) -> str: + return repr(self.match) + + def parseImpl(self, instring, loc, doActions=True): + errmsg = self.errmsg + errloc = loc + if self.caseless: + if instring[loc : loc + self.matchLen].upper() == self.caselessmatch: + if loc == 0 or instring[loc - 1].upper() not in self.identChars: + if ( + loc >= len(instring) - self.matchLen + or instring[loc + self.matchLen].upper() not in self.identChars + ): + return loc + self.matchLen, self.match + else: + # followed by keyword char + errmsg += ", was immediately followed by keyword character" + errloc = loc + self.matchLen + else: + # preceded by keyword char + errmsg += ", keyword was immediately preceded by keyword character" + errloc = loc - 1 + # else no match just raise plain exception + + else: + if ( + instring[loc] == self.firstMatchChar + and self.matchLen == 1 + or instring.startswith(self.match, loc) + ): + if loc == 0 or instring[loc - 1] not in self.identChars: + if ( + loc >= len(instring) - self.matchLen + or instring[loc + self.matchLen] not in self.identChars + ): + return loc + self.matchLen, self.match + else: + # followed by keyword char + errmsg += ( + ", keyword was immediately followed by keyword character" + ) + errloc = loc + self.matchLen + else: + # preceded by keyword char + errmsg += ", keyword was immediately preceded by keyword character" + errloc = loc - 1 + # else no match just raise plain exception + + raise ParseException(instring, errloc, errmsg, self) + + @staticmethod + def set_default_keyword_chars(chars) -> None: + """ + Overrides the default characters used by :class:`Keyword` expressions. + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + + setDefaultKeywordChars = set_default_keyword_chars + + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + + CaselessLiteral("CMD")[1, ...].parse_string("cmd CMD Cmd10") + # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for :class:`CaselessKeyword`.) + """ + + def __init__(self, match_string: str = "", *, matchString: str = ""): + match_string = matchString or match_string + super().__init__(match_string.upper()) + # Preserve the defining literal. + self.returnString = match_string + self.errmsg = "Expected " + self.name + + def parseImpl(self, instring, loc, doActions=True): + if instring[loc : loc + self.matchLen].upper() == self.match: + return loc + self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + + +class CaselessKeyword(Keyword): + """ + Caseless version of :class:`Keyword`. + + Example:: + + CaselessKeyword("CMD")[1, ...].parse_string("cmd CMD Cmd10") + # -> ['CMD', 'CMD'] + + (Contrast with example for :class:`CaselessLiteral`.) + """ + + def __init__( + self, + match_string: str = "", + ident_chars: typing.Optional[str] = None, + *, + matchString: str = "", + identChars: typing.Optional[str] = None, + ): + identChars = identChars or ident_chars + match_string = matchString or match_string + super().__init__(match_string, identChars, caseless=True) + + +class CloseMatch(Token): + """A variation on :class:`Literal` which matches "close" matches, + that is, strings with at most 'n' mismatching characters. + :class:`CloseMatch` takes parameters: + + - ``match_string`` - string to be matched + - ``caseless`` - a boolean indicating whether to ignore casing when comparing characters + - ``max_mismatches`` - (``default=1``) maximum number of + mismatches allowed to count as a match + + The results from a successful parse will contain the matched text + from the input string and the following named results: + + - ``mismatches`` - a list of the positions within the + match_string where mismatches were found + - ``original`` - the original match_string used to compare + against the input string + + If ``mismatches`` is an empty list, then the match was an exact + match. + + Example:: + + patt = CloseMatch("ATCATCGAATGGA") + patt.parse_string("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parse_string("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parse_string("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", max_mismatches=2) + patt.parse_string("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + + def __init__( + self, + match_string: str, + max_mismatches: typing.Optional[int] = None, + *, + maxMismatches: int = 1, + caseless=False, + ): + maxMismatches = max_mismatches if max_mismatches is not None else maxMismatches + super().__init__() + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = f"Expected {self.match_string!r} (with up to {self.maxMismatches} mismatches)" + self.caseless = caseless + self.mayIndexError = False + self.mayReturnEmpty = False + + def _generateDefaultName(self) -> str: + return f"{type(self).__name__}:{self.match_string!r}" + + def parseImpl(self, instring, loc, doActions=True): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc, s_m in enumerate( + zip(instring[loc:maxloc], match_string) + ): + src, mat = s_m + if self.caseless: + src, mat = src.lower(), mat.lower() + + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = start + match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results["original"] = match_string + results["mismatches"] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """Token for matching words composed of allowed character sets. + + Parameters: + + - ``init_chars`` - string of all characters that should be used to + match as a word; "ABC" will match "AAA", "ABAB", "CBAC", etc.; + if ``body_chars`` is also specified, then this is the string of + initial characters + - ``body_chars`` - string of characters that + can be used for matching after a matched initial character as + given in ``init_chars``; if omitted, same as the initial characters + (default=``None``) + - ``min`` - minimum number of characters to match (default=1) + - ``max`` - maximum number of characters to match (default=0) + - ``exact`` - exact number of characters to match (default=0) + - ``as_keyword`` - match as a keyword (default=``False``) + - ``exclude_chars`` - characters that might be + found in the input ``body_chars`` string but which should not be + accepted for matching ;useful to define a word of all + printables except for one or two characters, for instance + (default=``None``) + + :class:`srange` is useful for defining custom character set strings + for defining :class:`Word` expressions, using range notation from + regular expression character sets. + + A common mistake is to use :class:`Word` to match a specific literal + string, as in ``Word("Address")``. Remember that :class:`Word` + uses the string argument to define *sets* of matchable characters. + This expression would match "Add", "AAA", "dAred", or any other word + made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an + exact literal string, use :class:`Literal` or :class:`Keyword`. + + pyparsing includes helper strings for building Words: + + - :class:`alphas` + - :class:`nums` + - :class:`alphanums` + - :class:`hexnums` + - :class:`alphas8bit` (alphabetic characters in ASCII range 128-255 + - accented, tilded, umlauted, etc.) + - :class:`punc8bit` (non-alphabetic characters in ASCII range + 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - :class:`printables` (any non-whitespace character) + + ``alphas``, ``nums``, and ``printables`` are also defined in several + Unicode sets - see :class:`pyparsing_unicode``. + + Example:: + + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums + '-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, exclude_chars=",") + """ + + def __init__( + self, + init_chars: str = "", + body_chars: typing.Optional[str] = None, + min: int = 1, + max: int = 0, + exact: int = 0, + as_keyword: bool = False, + exclude_chars: typing.Optional[str] = None, + *, + initChars: typing.Optional[str] = None, + bodyChars: typing.Optional[str] = None, + asKeyword: bool = False, + excludeChars: typing.Optional[str] = None, + ): + initChars = initChars or init_chars + bodyChars = bodyChars or body_chars + asKeyword = asKeyword or as_keyword + excludeChars = excludeChars or exclude_chars + super().__init__() + if not initChars: + raise ValueError( + f"invalid {type(self).__name__}, initChars cannot be empty string" + ) + + initChars_set = set(initChars) + if excludeChars: + excludeChars_set = set(excludeChars) + initChars_set -= excludeChars_set + if bodyChars: + bodyChars = "".join(set(bodyChars) - excludeChars_set) + self.initChars = initChars_set + self.initCharsOrig = "".join(sorted(initChars_set)) + + if bodyChars: + self.bodyChars = set(bodyChars) + self.bodyCharsOrig = "".join(sorted(bodyChars)) + else: + self.bodyChars = initChars_set + self.bodyCharsOrig = self.initCharsOrig + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError( + "cannot specify a minimum length < 1; use Opt(Word()) if zero-length word is permitted" + ) + + if self.maxSpecified and min > max: + raise ValueError( + f"invalid args, if min and max both specified min must be <= max (min={min}, max={max})" + ) + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + min = max = exact + self.maxLen = exact + self.minLen = exact + + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + if self.asKeyword: + self.errmsg += " as a keyword" + + # see if we can make a regex for this Word + if " " not in (self.initChars | self.bodyChars): + if len(self.initChars) == 1: + re_leading_fragment = re.escape(self.initCharsOrig) + else: + re_leading_fragment = f"[{_collapse_string_to_ranges(self.initChars)}]" + + if self.bodyChars == self.initChars: + if max == 0 and self.minLen == 1: + repeat = "+" + elif max == 1: + repeat = "" + else: + if self.minLen != self.maxLen: + repeat = f"{{{self.minLen},{'' if self.maxLen == _MAX_INT else self.maxLen}}}" + else: + repeat = f"{{{self.minLen}}}" + self.reString = f"{re_leading_fragment}{repeat}" + else: + if max == 1: + re_body_fragment = "" + repeat = "" + else: + re_body_fragment = f"[{_collapse_string_to_ranges(self.bodyChars)}]" + if max == 0 and self.minLen == 1: + repeat = "*" + elif max == 2: + repeat = "?" if min <= 1 else "" + else: + if min != max: + repeat = f"{{{min - 1 if min > 0 else ''},{max - 1 if max > 0 else ''}}}" + else: + repeat = f"{{{min - 1 if min > 0 else ''}}}" + + self.reString = f"{re_leading_fragment}{re_body_fragment}{repeat}" + + if self.asKeyword: + self.reString = rf"\b{self.reString}\b" + + try: + self.re = re.compile(self.reString) + except re.error: + self.re = None # type: ignore[assignment] + else: + self.re_match = self.re.match + self.parseImpl = self.parseImpl_regex # type: ignore[assignment] + + def _generateDefaultName(self) -> str: + def charsAsStr(s): + max_repr_len = 16 + s = _collapse_string_to_ranges(s, re_escape=False) + if len(s) > max_repr_len: + return s[: max_repr_len - 3] + "..." + else: + return s + + if self.initChars != self.bodyChars: + base = f"W:({charsAsStr(self.initChars)}, {charsAsStr(self.bodyChars)})" + else: + base = f"W:({charsAsStr(self.initChars)})" + + # add length specification + if self.minLen > 1 or self.maxLen != _MAX_INT: + if self.minLen == self.maxLen: + if self.minLen == 1: + return base[2:] + else: + return base + f"{{{self.minLen}}}" + elif self.maxLen == _MAX_INT: + return base + f"{{{self.minLen},...}}" + else: + return base + f"{{{self.minLen},{self.maxLen}}}" + return base + + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] not in self.initChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min(maxloc, instrlen) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + elif self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + elif self.asKeyword: + if ( + start > 0 + and instring[start - 1] in bodychars + or loc < instrlen + and instring[loc] in bodychars + ): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def parseImpl_regex(self, instring, loc, doActions=True): + result = self.re_match(instring, loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + +class Char(Word): + """A short-cut class for defining :class:`Word` ``(characters, exact=1)``, + when defining a match of any single character in a string of + characters. + """ + + def __init__( + self, + charset: str, + as_keyword: bool = False, + exclude_chars: typing.Optional[str] = None, + *, + asKeyword: bool = False, + excludeChars: typing.Optional[str] = None, + ): + asKeyword = asKeyword or as_keyword + excludeChars = excludeChars or exclude_chars + super().__init__( + charset, exact=1, as_keyword=asKeyword, exclude_chars=excludeChars + ) + + +class Regex(Token): + r"""Token for matching strings that match a given regular + expression. Defined with string specifying the regular expression in + a form recognized by the stdlib Python `re module <https://docs.python.org/3/library/re.html>`_. + If the given regex contains named groups (defined using ``(?P<name>...)``), + these will be preserved as named :class:`ParseResults`. + + If instead of the Python stdlib ``re`` module you wish to use a different RE module + (such as the ``regex`` module), you can do so by building your ``Regex`` object with + a compiled RE that was compiled using ``regex``. + + Example:: + + realnum = Regex(r"[+-]?\d+\.\d*") + # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + + # named fields in a regex will be returned as named results + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + + # the Regex class will accept re's compiled using the regex module + import regex + parser = pp.Regex(regex.compile(r'[0-9]')) + """ + + def __init__( + self, + pattern: Any, + flags: Union[re.RegexFlag, int] = 0, + as_group_list: bool = False, + as_match: bool = False, + *, + asGroupList: bool = False, + asMatch: bool = False, + ): + """The parameters ``pattern`` and ``flags`` are passed + to the ``re.compile()`` function as-is. See the Python + `re module <https://docs.python.org/3/library/re.html>`_ module for an + explanation of the acceptable patterns and flags. + """ + super().__init__() + asGroupList = asGroupList or as_group_list + asMatch = asMatch or as_match + + if isinstance(pattern, str_type): + if not pattern: + raise ValueError("null string passed to Regex; use Empty() instead") + + self._re = None + self.reString = self.pattern = pattern + self.flags = flags + + elif hasattr(pattern, "pattern") and hasattr(pattern, "match"): + self._re = pattern + self.pattern = self.reString = pattern.pattern + self.flags = flags + + else: + raise TypeError( + "Regex may only be constructed with a string or a compiled RE object" + ) + + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asGroupList = asGroupList + self.asMatch = asMatch + if self.asGroupList: + self.parseImpl = self.parseImplAsGroupList # type: ignore [assignment] + if self.asMatch: + self.parseImpl = self.parseImplAsMatch # type: ignore [assignment] + + @cached_property + def re(self): + if self._re: + return self._re + else: + try: + return re.compile(self.pattern, self.flags) + except re.error: + raise ValueError(f"invalid pattern ({self.pattern!r}) passed to Regex") + + @cached_property + def re_match(self): + return self.re.match + + @cached_property + def mayReturnEmpty(self): + return self.re_match("") is not None + + def _generateDefaultName(self) -> str: + return "Re:({})".format(repr(self.pattern).replace("\\\\", "\\")) + + def parseImpl(self, instring, loc, doActions=True): + result = self.re_match(instring, loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = ParseResults(result.group()) + d = result.groupdict() + if d: + for k, v in d.items(): + ret[k] = v + return loc, ret + + def parseImplAsGroupList(self, instring, loc, doActions=True): + result = self.re_match(instring, loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.groups() + return loc, ret + + def parseImplAsMatch(self, instring, loc, doActions=True): + result = self.re_match(instring, loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result + return loc, ret + + def sub(self, repl: str) -> ParserElement: + r""" + Return :class:`Regex` with an attached parse action to transform the parsed + result as if called using `re.sub(expr, repl, string) <https://docs.python.org/3/library/re.html#re.sub>`_. + + Example:: + + make_html = Regex(r"(\w+):(.*?):").sub(r"<\1>\2</\1>") + print(make_html.transform_string("h1:main title:")) + # prints "<h1>main title</h1>" + """ + if self.asGroupList: + raise TypeError("cannot use sub() with Regex(as_group_list=True)") + + if self.asMatch and callable(repl): + raise TypeError( + "cannot use sub() with a callable with Regex(as_match=True)" + ) + + if self.asMatch: + + def pa(tokens): + return tokens[0].expand(repl) + + else: + + def pa(tokens): + return self.re.sub(repl, tokens[0]) + + return self.add_parse_action(pa) + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + + - ``quote_char`` - string of one or more characters defining the + quote delimiting string + - ``esc_char`` - character to re_escape quotes, typically backslash + (default= ``None``) + - ``esc_quote`` - special quote sequence to re_escape an embedded quote + string (such as SQL's ``""`` to re_escape an embedded ``"``) + (default= ``None``) + - ``multiline`` - boolean indicating whether quotes can span + multiple lines (default= ``False``) + - ``unquote_results`` - boolean indicating whether the matched text + should be unquoted (default= ``True``) + - ``end_quote_char`` - string of one or more characters defining the + end of the quote delimited string (default= ``None`` => same as + quote_char) + - ``convert_whitespace_escapes`` - convert escaped whitespace + (``'\t'``, ``'\n'``, etc.) to actual whitespace + (default= ``True``) + + Example:: + + qs = QuotedString('"') + print(qs.search_string('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', end_quote_char='}}') + print(complex_qs.search_string('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', esc_quote='""') + print(sql_qs.search_string('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + + prints:: + + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + ws_map = dict(((r"\t", "\t"), (r"\n", "\n"), (r"\f", "\f"), (r"\r", "\r"))) + + def __init__( + self, + quote_char: str = "", + esc_char: typing.Optional[str] = None, + esc_quote: typing.Optional[str] = None, + multiline: bool = False, + unquote_results: bool = True, + end_quote_char: typing.Optional[str] = None, + convert_whitespace_escapes: bool = True, + *, + quoteChar: str = "", + escChar: typing.Optional[str] = None, + escQuote: typing.Optional[str] = None, + unquoteResults: bool = True, + endQuoteChar: typing.Optional[str] = None, + convertWhitespaceEscapes: bool = True, + ): + super().__init__() + esc_char = escChar or esc_char + esc_quote = escQuote or esc_quote + unquote_results = unquoteResults and unquote_results + end_quote_char = endQuoteChar or end_quote_char + convert_whitespace_escapes = ( + convertWhitespaceEscapes and convert_whitespace_escapes + ) + quote_char = quoteChar or quote_char + + # remove white space from quote chars + quote_char = quote_char.strip() + if not quote_char: + raise ValueError("quote_char cannot be the empty string") + + if end_quote_char is None: + end_quote_char = quote_char + else: + end_quote_char = end_quote_char.strip() + if not end_quote_char: + raise ValueError("end_quote_char cannot be the empty string") + + self.quote_char: str = quote_char + self.quote_char_len: int = len(quote_char) + self.first_quote_char: str = quote_char[0] + self.end_quote_char: str = end_quote_char + self.end_quote_char_len: int = len(end_quote_char) + self.esc_char: str = esc_char or "" + self.has_esc_char: bool = esc_char is not None + self.esc_quote: str = esc_quote or "" + self.unquote_results: bool = unquote_results + self.convert_whitespace_escapes: bool = convert_whitespace_escapes + self.multiline = multiline + self.re_flags = re.RegexFlag(0) + + # fmt: off + # build up re pattern for the content between the quote delimiters + inner_pattern = [] + + if esc_quote: + inner_pattern.append(rf"(?:{re.escape(esc_quote)})") + + if esc_char: + inner_pattern.append(rf"(?:{re.escape(esc_char)}.)") + + if len(self.end_quote_char) > 1: + inner_pattern.append( + "(?:" + + "|".join( + f"(?:{re.escape(self.end_quote_char[:i])}(?!{re.escape(self.end_quote_char[i:])}))" + for i in range(len(self.end_quote_char) - 1, 0, -1) + ) + + ")" + ) + + if self.multiline: + self.re_flags |= re.MULTILINE | re.DOTALL + inner_pattern.append( + rf"(?:[^{_escape_regex_range_chars(self.end_quote_char[0])}" + rf"{(_escape_regex_range_chars(esc_char) if self.has_esc_char else '')}])" + ) + else: + inner_pattern.append( + rf"(?:[^{_escape_regex_range_chars(self.end_quote_char[0])}\n\r" + rf"{(_escape_regex_range_chars(esc_char) if self.has_esc_char else '')}])" + ) + + self.pattern = "".join( + [ + re.escape(self.quote_char), + "(?:", + '|'.join(inner_pattern), + ")*", + re.escape(self.end_quote_char), + ] + ) + + if self.unquote_results: + if self.convert_whitespace_escapes: + self.unquote_scan_re = re.compile( + rf"({'|'.join(re.escape(k) for k in self.ws_map)})" + rf"|({re.escape(self.esc_char)}.)" + rf"|(\n|.)", + flags=self.re_flags, + ) + else: + self.unquote_scan_re = re.compile( + rf"({re.escape(self.esc_char)}.)" + rf"|(\n|.)", + flags=self.re_flags + ) + # fmt: on + + try: + self.re = re.compile(self.pattern, self.re_flags) + self.reString = self.pattern + self.re_match = self.re.match + except re.error: + raise ValueError(f"invalid pattern {self.pattern!r} passed to Regex") + + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def _generateDefaultName(self) -> str: + if self.quote_char == self.end_quote_char and isinstance( + self.quote_char, str_type + ): + return f"string enclosed in {self.quote_char!r}" + + return f"quoted string, starting with {self.quote_char} ending with {self.end_quote_char}" + + def parseImpl(self, instring, loc, doActions=True): + # check first character of opening quote to see if that is a match + # before doing the more complicated regex match + result = ( + instring[loc] == self.first_quote_char + and self.re_match(instring, loc) + or None + ) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + # get ending loc and matched string from regex matching result + loc = result.end() + ret = result.group() + + if self.unquote_results: + # strip off quotes + ret = ret[self.quote_char_len : -self.end_quote_char_len] + + if isinstance(ret, str_type): + # fmt: off + if self.convert_whitespace_escapes: + # as we iterate over matches in the input string, + # collect from whichever match group of the unquote_scan_re + # regex matches (only 1 group will match at any given time) + ret = "".join( + # match group 1 matches \t, \n, etc. + self.ws_map[match.group(1)] if match.group(1) + # match group 2 matches escaped characters + else match.group(2)[-1] if match.group(2) + # match group 3 matches any character + else match.group(3) + for match in self.unquote_scan_re.finditer(ret) + ) + else: + ret = "".join( + # match group 1 matches escaped characters + match.group(1)[-1] if match.group(1) + # match group 2 matches any character + else match.group(2) + for match in self.unquote_scan_re.finditer(ret) + ) + # fmt: on + + # replace escaped quotes + if self.esc_quote: + ret = ret.replace(self.esc_quote, self.end_quote_char) + + return loc, ret + + +class CharsNotIn(Token): + """Token for matching words composed of characters *not* in a given + set (will include whitespace in matched characters if not listed in + the provided exclusion set - see example). Defined with string + containing all disallowed characters, and an optional minimum, + maximum, and/or exact length. The default value for ``min`` is + 1 (a minimum value < 1 is not valid); the default values for + ``max`` and ``exact`` are 0, meaning no maximum or exact + length restriction. + + Example:: + + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(DelimitedList(csv_value).parse_string("dkls,lsdkjf,s12 34,@!#,213")) + + prints:: + + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + + def __init__( + self, + not_chars: str = "", + min: int = 1, + max: int = 0, + exact: int = 0, + *, + notChars: str = "", + ): + super().__init__() + self.skipWhitespace = False + self.notChars = not_chars or notChars + self.notCharsSet = set(self.notChars) + + if min < 1: + raise ValueError( + "cannot specify a minimum length < 1; use " + "Opt(CharsNotIn()) if zero-length char group is permitted" + ) + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = self.minLen == 0 + self.mayIndexError = False + + def _generateDefaultName(self) -> str: + not_chars_str = _collapse_string_to_ranges(self.notChars) + if len(not_chars_str) > 16: + return f"!W:({self.notChars[: 16 - 3]}...)" + else: + return f"!W:({self.notChars})" + + def parseImpl(self, instring, loc, doActions=True): + notchars = self.notCharsSet + if instring[loc] in notchars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + maxlen = min(start + self.maxLen, len(instring)) + while loc < maxlen and instring[loc] not in notchars: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class White(Token): + """Special matching class for matching whitespace. Normally, + whitespace is ignored by pyparsing grammars. This class is included + when some whitespace structures are significant. Define with + a string containing the whitespace characters to be matched; default + is ``" \\t\\r\\n"``. Also takes optional ``min``, + ``max``, and ``exact`` arguments, as defined for the + :class:`Word` class. + """ + + whiteStrs = { + " ": "<SP>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + "\u00A0": "<NBSP>", + "\u1680": "<OGHAM_SPACE_MARK>", + "\u180E": "<MONGOLIAN_VOWEL_SEPARATOR>", + "\u2000": "<EN_QUAD>", + "\u2001": "<EM_QUAD>", + "\u2002": "<EN_SPACE>", + "\u2003": "<EM_SPACE>", + "\u2004": "<THREE-PER-EM_SPACE>", + "\u2005": "<FOUR-PER-EM_SPACE>", + "\u2006": "<SIX-PER-EM_SPACE>", + "\u2007": "<FIGURE_SPACE>", + "\u2008": "<PUNCTUATION_SPACE>", + "\u2009": "<THIN_SPACE>", + "\u200A": "<HAIR_SPACE>", + "\u200B": "<ZERO_WIDTH_SPACE>", + "\u202F": "<NNBSP>", + "\u205F": "<MMSP>", + "\u3000": "<IDEOGRAPHIC_SPACE>", + } + + def __init__(self, ws: str = " \t\r\n", min: int = 1, max: int = 0, exact: int = 0): + super().__init__() + self.matchWhite = ws + self.set_whitespace_chars( + "".join(c for c in self.whiteStrs if c not in self.matchWhite), + copy_defaults=True, + ) + # self.leave_whitespace() + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def _generateDefaultName(self) -> str: + return "".join(White.whiteStrs[c] for c in self.matchWhite) + + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] not in self.matchWhite: + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min(maxloc, len(instring)) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class PositionToken(Token): + def __init__(self): + super().__init__() + self.mayReturnEmpty = True + self.mayIndexError = False + + +class GoToColumn(PositionToken): + """Token to advance to a specific column of input text; useful for + tabular report scraping. + """ + + def __init__(self, colno: int): + super().__init__() + self.col = colno + + def preParse(self, instring: str, loc: int) -> int: + if col(loc, instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables(instring, loc) + while ( + loc < instrlen + and instring[loc].isspace() + and col(loc, instring) != self.col + ): + loc += 1 + return loc + + def parseImpl(self, instring, loc, doActions=True): + thiscol = col(loc, instring) + if thiscol > self.col: + raise ParseException(instring, loc, "Text not in expected column", self) + newloc = loc + self.col - thiscol + ret = instring[loc:newloc] + return newloc, ret + + +class LineStart(PositionToken): + r"""Matches if current position is at the beginning of a line within + the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + rest_of_line).search_string(test): + print(t) + + prints:: + + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + + def __init__(self): + super().__init__() + self.leave_whitespace() + self.orig_whiteChars = set() | self.whiteChars + self.whiteChars.discard("\n") + self.skipper = Empty().set_whitespace_chars(self.whiteChars) + self.errmsg = "Expected start of line" + + def preParse(self, instring: str, loc: int) -> int: + if loc == 0: + return loc + else: + ret = self.skipper.preParse(instring, loc) + if "\n" in self.orig_whiteChars: + while instring[ret : ret + 1] == "\n": + ret = self.skipper.preParse(instring, ret + 1) + return ret + + def parseImpl(self, instring, loc, doActions=True): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + + +class LineEnd(PositionToken): + """Matches if current position is at the end of a line within the + parse string + """ + + def __init__(self): + super().__init__() + self.whiteChars.discard("\n") + self.set_whitespace_chars(self.whiteChars, copy_defaults=False) + self.errmsg = "Expected end of line" + + def parseImpl(self, instring, loc, doActions=True): + if loc < len(instring): + if instring[loc] == "\n": + return loc + 1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc + 1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + + +class StringStart(PositionToken): + """Matches if current position is at the beginning of the parse + string + """ + + def __init__(self): + super().__init__() + self.errmsg = "Expected start of text" + + def parseImpl(self, instring, loc, doActions=True): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse(instring, 0): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class StringEnd(PositionToken): + """ + Matches if current position is at the end of the parse string + """ + + def __init__(self): + super().__init__() + self.errmsg = "Expected end of text" + + def parseImpl(self, instring, loc, doActions=True): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc + 1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + + +class WordStart(PositionToken): + """Matches if the current position is at the beginning of a + :class:`Word`, and is not preceded by any character in a given + set of ``word_chars`` (default= ``printables``). To emulate the + ``\b`` behavior of regular expressions, use + ``WordStart(alphanums)``. ``WordStart`` will also match at + the beginning of the string being parsed, or at the beginning of + a line. + """ + + def __init__(self, word_chars: str = printables, *, wordChars: str = printables): + wordChars = word_chars if wordChars == printables else wordChars + super().__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True): + if loc != 0: + if ( + instring[loc - 1] in self.wordChars + or instring[loc] not in self.wordChars + ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class WordEnd(PositionToken): + """Matches if the current position is at the end of a :class:`Word`, + and is not followed by any character in a given set of ``word_chars`` + (default= ``printables``). To emulate the ``\b`` behavior of + regular expressions, use ``WordEnd(alphanums)``. ``WordEnd`` + will also match at the end of the string being parsed, or at the end + of a line. + """ + + def __init__(self, word_chars: str = printables, *, wordChars: str = printables): + wordChars = word_chars if wordChars == printables else wordChars + super().__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True): + instrlen = len(instring) + if instrlen > 0 and loc < instrlen: + if ( + instring[loc] in self.wordChars + or instring[loc - 1] not in self.wordChars + ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """Abstract subclass of ParserElement, for combining and + post-processing parsed tokens. + """ + + def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool = False): + super().__init__(savelist) + self.exprs: List[ParserElement] + if isinstance(exprs, _generatorType): + exprs = list(exprs) + + if isinstance(exprs, str_type): + self.exprs = [self._literalStringClass(exprs)] + elif isinstance(exprs, ParserElement): + self.exprs = [exprs] + elif isinstance(exprs, Iterable): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if any(isinstance(expr, str_type) for expr in exprs): + exprs = ( + self._literalStringClass(e) if isinstance(e, str_type) else e + for e in exprs + ) + self.exprs = list(exprs) + else: + try: + self.exprs = list(exprs) + except TypeError: + self.exprs = [exprs] + self.callPreparse = False + + def recurse(self) -> List[ParserElement]: + return self.exprs[:] + + def append(self, other) -> ParserElement: + self.exprs.append(other) + self._defaultName = None + return self + + def leave_whitespace(self, recursive: bool = True) -> ParserElement: + """ + Extends ``leave_whitespace`` defined in base class, and also invokes ``leave_whitespace`` on + all contained expressions. + """ + super().leave_whitespace(recursive) + + if recursive: + self.exprs = [e.copy() for e in self.exprs] + for e in self.exprs: + e.leave_whitespace(recursive) + return self + + def ignore_whitespace(self, recursive: bool = True) -> ParserElement: + """ + Extends ``ignore_whitespace`` defined in base class, and also invokes ``leave_whitespace`` on + all contained expressions. + """ + super().ignore_whitespace(recursive) + if recursive: + self.exprs = [e.copy() for e in self.exprs] + for e in self.exprs: + e.ignore_whitespace(recursive) + return self + + def ignore(self, other) -> ParserElement: + if isinstance(other, Suppress): + if other not in self.ignoreExprs: + super().ignore(other) + for e in self.exprs: + e.ignore(self.ignoreExprs[-1]) + else: + super().ignore(other) + for e in self.exprs: + e.ignore(self.ignoreExprs[-1]) + return self + + def _generateDefaultName(self) -> str: + return f"{self.__class__.__name__}:({str(self.exprs)})" + + def streamline(self) -> ParserElement: + if self.streamlined: + return self + + super().streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested :class:`And`'s of the form ``And(And(And(a, b), c), d)`` to ``And(a, b, c, d)`` + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for :class:`Or`'s and :class:`MatchFirst`'s) + if len(self.exprs) == 2: + other = self.exprs[0] + if ( + isinstance(other, self.__class__) + and not other.parseAction + and other.resultsName is None + and not other.debug + ): + self.exprs = other.exprs[:] + [self.exprs[1]] + self._defaultName = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( + isinstance(other, self.__class__) + and not other.parseAction + and other.resultsName is None + and not other.debug + ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self._defaultName = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + str(self) + + return self + + def validate(self, validateTrace=None) -> None: + warnings.warn( + "ParserElement.validate() is deprecated, and should not be used to check for left recursion", + DeprecationWarning, + stacklevel=2, + ) + tmp = (validateTrace if validateTrace is not None else [])[:] + [self] + for e in self.exprs: + e.validate(tmp) + self._checkRecursion([]) + + def copy(self) -> ParserElement: + ret = super().copy() + ret = typing.cast(ParseExpression, ret) + ret.exprs = [e.copy() for e in self.exprs] + return ret + + def _setResultsName(self, name, listAllMatches=False): + if ( + __diag__.warn_ungrouped_named_tokens_in_collection + and Diagnostics.warn_ungrouped_named_tokens_in_collection + not in self.suppress_warnings_ + ): + for e in self.exprs: + if ( + isinstance(e, ParserElement) + and e.resultsName + and Diagnostics.warn_ungrouped_named_tokens_in_collection + not in e.suppress_warnings_ + ): + warnings.warn( + "{}: setting results name {!r} on {} expression " + "collides with {!r} on contained expression".format( + "warn_ungrouped_named_tokens_in_collection", + name, + type(self).__name__, + e.resultsName, + ), + stacklevel=3, + ) + + return super()._setResultsName(name, listAllMatches) + + # Compatibility synonyms + # fmt: off + @replaced_by_pep8(leave_whitespace) + def leaveWhitespace(self): ... + + @replaced_by_pep8(ignore_whitespace) + def ignoreWhitespace(self): ... + # fmt: on + + +class And(ParseExpression): + """ + Requires all given :class:`ParseExpression` s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the ``'+'`` operator. + May also be constructed using the ``'-'`` operator, which will + suppress backtracking. + + Example:: + + integer = Word(nums) + name_expr = Word(alphas)[1, ...] + + expr = And([integer("id"), name_expr("name"), integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.leave_whitespace() + + def _generateDefaultName(self) -> str: + return "-" + + def __init__( + self, exprs_arg: typing.Iterable[ParserElement], savelist: bool = True + ): + exprs: List[ParserElement] = list(exprs_arg) + if exprs and Ellipsis in exprs: + tmp = [] + for i, expr in enumerate(exprs): + if expr is Ellipsis: + if i < len(exprs) - 1: + skipto_arg: ParserElement = typing.cast( + ParseExpression, (Empty() + exprs[i + 1]) + ).exprs[-1] + tmp.append(SkipTo(skipto_arg)("_skipped*")) + else: + raise Exception( + "cannot construct And with sequence ending in ..." + ) + else: + tmp.append(expr) + exprs[:] = tmp + super().__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + if not isinstance(self.exprs[0], White): + self.set_whitespace_chars( + self.exprs[0].whiteChars, + copy_defaults=self.exprs[0].copyDefaultWhiteChars, + ) + self.skipWhitespace = self.exprs[0].skipWhitespace + else: + self.skipWhitespace = False + else: + self.mayReturnEmpty = True + self.callPreparse = True + + def streamline(self) -> ParserElement: + # collapse any _PendingSkip's + if self.exprs: + if any( + isinstance(e, ParseExpression) + and e.exprs + and isinstance(e.exprs[-1], _PendingSkip) + for e in self.exprs[:-1] + ): + deleted_expr_marker = NoMatch() + for i, e in enumerate(self.exprs[:-1]): + if e is deleted_expr_marker: + continue + if ( + isinstance(e, ParseExpression) + and e.exprs + and isinstance(e.exprs[-1], _PendingSkip) + ): + e.exprs[-1] = e.exprs[-1] + self.exprs[i + 1] + self.exprs[i + 1] = deleted_expr_marker + self.exprs = [e for e in self.exprs if e is not deleted_expr_marker] + + super().streamline() + + # link any IndentedBlocks to the prior expression + prev: ParserElement + cur: ParserElement + for prev, cur in zip(self.exprs, self.exprs[1:]): + # traverse cur or any first embedded expr of cur looking for an IndentedBlock + # (but watch out for recursive grammar) + seen = set() + while True: + if id(cur) in seen: + break + seen.add(id(cur)) + if isinstance(cur, IndentedBlock): + prev.add_parse_action( + lambda s, l, t, cur_=cur: setattr( + cur_, "parent_anchor", col(l, s) + ) + ) + break + subs = cur.recurse() + next_first = next(iter(subs), None) + if next_first is None: + break + cur = typing.cast(ParserElement, next_first) + + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + return self + + def parseImpl(self, instring, loc, doActions=True): + # pass False as callPreParse arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( + instring, loc, doActions, callPreParse=False + ) + errorStop = False + for e in self.exprs[1:]: + # if isinstance(e, And._ErrorStop): + if type(e) is And._ErrorStop: + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse(instring, loc, doActions) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException( + instring, len(instring), self.errmsg, self + ) + else: + loc, exprtokens = e._parse(instring, loc, doActions) + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other): + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return self.append(other) # And([self, other]) + + def _checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] + for e in self.exprs: + e._checkRecursion(subRecCheckList) + if not e.mayReturnEmpty: + break + + def _generateDefaultName(self) -> str: + inner = " ".join(str(e) for e in self.exprs) + # strip off redundant inner {}'s + while len(inner) > 1 and inner[0 :: len(inner) - 1] == "{}": + inner = inner[1:-1] + return "{" + inner + "}" + + +class Or(ParseExpression): + """Requires that at least one :class:`ParseExpression` is found. If + two expressions match, the expression that matches the longest + string will be used. May be constructed using the ``'^'`` + operator. + + Example:: + + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.search_string("123 3.1416 789")) + + prints:: + + [['123'], ['3.1416'], ['789']] + """ + + def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool = False): + super().__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = all(e.skipWhitespace for e in self.exprs) + else: + self.mayReturnEmpty = True + + def streamline(self) -> ParserElement: + super().streamline() + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + self.saveAsList = any(e.saveAsList for e in self.exprs) + self.skipWhitespace = all( + e.skipWhitespace and not isinstance(e, White) for e in self.exprs + ) + else: + self.saveAsList = False + return self + + def parseImpl(self, instring, loc, doActions=True): + maxExcLoc = -1 + maxException = None + matches = [] + fatals = [] + if all(e.callPreparse for e in self.exprs): + loc = self.preParse(instring, loc) + for e in self.exprs: + try: + loc2 = e.try_parse(instring, loc, raise_fatal=True) + except ParseFatalException as pfe: + pfe.__traceback__ = None + pfe.parser_element = e + fatals.append(pfe) + maxException = None + maxExcLoc = -1 + except ParseException as err: + if not fatals: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException( + instring, len(instring), e.errmsg, self + ) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + # re-evaluate all matches in descending order of length of match, in case attached actions + # might change whether or how much they match of the input. + matches.sort(key=itemgetter(0), reverse=True) + + if not doActions: + # no further conditions or parse actions to change the selection of + # alternative, so the first match will be the best match + best_expr = matches[0][1] + return best_expr._parse(instring, loc, doActions) + + longest = -1, None + for loc1, expr1 in matches: + if loc1 <= longest[0]: + # already have a longer match than this one will deliver, we are done + return longest + + try: + loc2, toks = expr1._parse(instring, loc, doActions) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + else: + if loc2 >= loc1: + return loc2, toks + # didn't match as much as before + elif loc2 > longest[0]: + longest = loc2, toks + + if longest != (-1, None): + return longest + + if fatals: + if len(fatals) > 1: + fatals.sort(key=lambda e: -e.loc) + if fatals[0].loc == fatals[1].loc: + fatals.sort(key=lambda e: (-e.loc, -len(str(e.parser_element)))) + max_fatal = fatals[0] + raise max_fatal + + if maxException is not None: + # infer from this check that all alternatives failed at the current position + # so emit this collective error message instead of any single error message + if maxExcLoc == loc: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException( + instring, loc, "no defined alternatives to match", self + ) + + def __ixor__(self, other): + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return self.append(other) # Or([self, other]) + + def _generateDefaultName(self) -> str: + return "{" + " ^ ".join(str(e) for e in self.exprs) + "}" + + def _setResultsName(self, name, listAllMatches=False): + if ( + __diag__.warn_multiple_tokens_in_named_alternation + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in self.suppress_warnings_ + ): + if any( + isinstance(e, And) + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in e.suppress_warnings_ + for e in self.exprs + ): + warnings.warn( + "{}: setting results name {!r} on {} expression " + "will return a list of all parsed tokens in an And alternative, " + "in prior versions only the first token was returned; enclose " + "contained argument in Group".format( + "warn_multiple_tokens_in_named_alternation", + name, + type(self).__name__, + ), + stacklevel=3, + ) + + return super()._setResultsName(name, listAllMatches) + + +class MatchFirst(ParseExpression): + """Requires that at least one :class:`ParseExpression` is found. If + more than one expression matches, the first one listed is the one that will + match. May be constructed using the ``'|'`` operator. + + Example:: + + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.search_string("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.search_string("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + + def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool = False): + super().__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = all(e.skipWhitespace for e in self.exprs) + else: + self.mayReturnEmpty = True + + def streamline(self) -> ParserElement: + if self.streamlined: + return self + + super().streamline() + if self.exprs: + self.saveAsList = any(e.saveAsList for e in self.exprs) + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = all( + e.skipWhitespace and not isinstance(e, White) for e in self.exprs + ) + else: + self.saveAsList = False + self.mayReturnEmpty = True + return self + + def parseImpl(self, instring, loc, doActions=True): + maxExcLoc = -1 + maxException = None + + for e in self.exprs: + try: + return e._parse( + instring, + loc, + doActions, + ) + except ParseFatalException as pfe: + pfe.__traceback__ = None + pfe.parser_element = e + raise + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException( + instring, len(instring), e.errmsg, self + ) + maxExcLoc = len(instring) + + if maxException is not None: + # infer from this check that all alternatives failed at the current position + # so emit this collective error message instead of any individual error message + if maxExcLoc == loc: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException( + instring, loc, "no defined alternatives to match", self + ) + + def __ior__(self, other): + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return self.append(other) # MatchFirst([self, other]) + + def _generateDefaultName(self) -> str: + return "{" + " | ".join(str(e) for e in self.exprs) + "}" + + def _setResultsName(self, name, listAllMatches=False): + if ( + __diag__.warn_multiple_tokens_in_named_alternation + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in self.suppress_warnings_ + ): + if any( + isinstance(e, And) + and Diagnostics.warn_multiple_tokens_in_named_alternation + not in e.suppress_warnings_ + for e in self.exprs + ): + warnings.warn( + "{}: setting results name {!r} on {} expression " + "will return a list of all parsed tokens in an And alternative, " + "in prior versions only the first token was returned; enclose " + "contained argument in Group".format( + "warn_multiple_tokens_in_named_alternation", + name, + type(self).__name__, + ), + stacklevel=3, + ) + + return super()._setResultsName(name, listAllMatches) + + +class Each(ParseExpression): + """Requires all given :class:`ParseExpression` s to be found, but in + any order. Expressions may be separated by whitespace. + + May be constructed using the ``'&'`` operator. + + Example:: + + color = one_of("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = one_of("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Opt(color_attr) & Opt(size_attr) + + shape_spec.run_tests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + + prints:: + + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + + def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool = True): + super().__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + self.skipWhitespace = True + self.initExprGroups = True + self.saveAsList = True + + def __iand__(self, other): + if isinstance(other, str_type): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + return NotImplemented + return self.append(other) # Each([self, other]) + + def streamline(self) -> ParserElement: + super().streamline() + if self.exprs: + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + return self + + def parseImpl(self, instring, loc, doActions=True): + if self.initExprGroups: + self.opt1map = dict( + (id(e.expr), e) for e in self.exprs if isinstance(e, Opt) + ) + opt1 = [e.expr for e in self.exprs if isinstance(e, Opt)] + opt2 = [ + e + for e in self.exprs + if e.mayReturnEmpty and not isinstance(e, (Opt, Regex, ZeroOrMore)) + ] + self.optionals = opt1 + opt2 + self.multioptionals = [ + e.expr.set_results_name(e.resultsName, list_all_matches=True) + for e in self.exprs + if isinstance(e, _MultipleMatch) + ] + self.multirequired = [ + e.expr.set_results_name(e.resultsName, list_all_matches=True) + for e in self.exprs + if isinstance(e, OneOrMore) + ] + self.required = [ + e for e in self.exprs if not isinstance(e, (Opt, ZeroOrMore, OneOrMore)) + ] + self.required += self.multirequired + self.initExprGroups = False + + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + multis = self.multioptionals[:] + matchOrder = [] + + keepMatching = True + failed = [] + fatals = [] + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + multis + failed.clear() + fatals.clear() + for e in tmpExprs: + try: + tmpLoc = e.try_parse(instring, tmpLoc, raise_fatal=True) + except ParseFatalException as pfe: + pfe.__traceback__ = None + pfe.parser_element = e + fatals.append(pfe) + failed.append(e) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e), e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + # look for any ParseFatalExceptions + if fatals: + if len(fatals) > 1: + fatals.sort(key=lambda e: -e.loc) + if fatals[0].loc == fatals[1].loc: + fatals.sort(key=lambda e: (-e.loc, -len(str(e.parser_element)))) + max_fatal = fatals[0] + raise max_fatal + + if tmpReqd: + missing = ", ".join([str(e) for e in tmpReqd]) + raise ParseException( + instring, + loc, + f"Missing one or more required elements ({missing})", + ) + + # add any unmatched Opts, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e, Opt) and e.expr in tmpOpt] + + total_results = ParseResults([]) + for e in matchOrder: + loc, results = e._parse(instring, loc, doActions) + total_results += results + + return loc, total_results + + def _generateDefaultName(self) -> str: + return "{" + " & ".join(str(e) for e in self.exprs) + "}" + + +class ParseElementEnhance(ParserElement): + """Abstract subclass of :class:`ParserElement`, for combining and + post-processing parsed tokens. + """ + + def __init__(self, expr: Union[ParserElement, str], savelist: bool = False): + super().__init__(savelist) + if isinstance(expr, str_type): + expr_str = typing.cast(str, expr) + if issubclass(self._literalStringClass, Token): + expr = self._literalStringClass(expr_str) # type: ignore[call-arg] + elif issubclass(type(self), self._literalStringClass): + expr = Literal(expr_str) + else: + expr = self._literalStringClass(Literal(expr_str)) # type: ignore[assignment, call-arg] + expr = typing.cast(ParserElement, expr) + self.expr = expr + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.set_whitespace_chars( + expr.whiteChars, copy_defaults=expr.copyDefaultWhiteChars + ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def recurse(self) -> List[ParserElement]: + return [self.expr] if self.expr is not None else [] + + def parseImpl(self, instring, loc, doActions=True): + if self.expr is not None: + try: + return self.expr._parse(instring, loc, doActions, callPreParse=False) + except ParseBaseException as pbe: + if not isinstance(self, Forward) or self.customName is not None: + pbe.msg = self.errmsg + raise + else: + raise ParseException(instring, loc, "No expression defined", self) + + def leave_whitespace(self, recursive: bool = True) -> ParserElement: + super().leave_whitespace(recursive) + + if recursive: + if self.expr is not None: + self.expr = self.expr.copy() + self.expr.leave_whitespace(recursive) + return self + + def ignore_whitespace(self, recursive: bool = True) -> ParserElement: + super().ignore_whitespace(recursive) + + if recursive: + if self.expr is not None: + self.expr = self.expr.copy() + self.expr.ignore_whitespace(recursive) + return self + + def ignore(self, other) -> ParserElement: + if isinstance(other, Suppress): + if other not in self.ignoreExprs: + super().ignore(other) + if self.expr is not None: + self.expr.ignore(self.ignoreExprs[-1]) + else: + super().ignore(other) + if self.expr is not None: + self.expr.ignore(self.ignoreExprs[-1]) + return self + + def streamline(self) -> ParserElement: + super().streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def _checkRecursion(self, parseElementList): + if self in parseElementList: + raise RecursiveGrammarException(parseElementList + [self]) + subRecCheckList = parseElementList[:] + [self] + if self.expr is not None: + self.expr._checkRecursion(subRecCheckList) + + def validate(self, validateTrace=None) -> None: + warnings.warn( + "ParserElement.validate() is deprecated, and should not be used to check for left recursion", + DeprecationWarning, + stacklevel=2, + ) + if validateTrace is None: + validateTrace = [] + tmp = validateTrace[:] + [self] + if self.expr is not None: + self.expr.validate(tmp) + self._checkRecursion([]) + + def _generateDefaultName(self) -> str: + return f"{self.__class__.__name__}:({str(self.expr)})" + + # Compatibility synonyms + # fmt: off + @replaced_by_pep8(leave_whitespace) + def leaveWhitespace(self): ... + + @replaced_by_pep8(ignore_whitespace) + def ignoreWhitespace(self): ... + # fmt: on + + +class IndentedBlock(ParseElementEnhance): + """ + Expression to match one or more expressions at a given indentation level. + Useful for parsing text where structure is implied by indentation (like Python source code). + """ + + class _Indent(Empty): + def __init__(self, ref_col: int): + super().__init__() + self.errmsg = f"expected indent at column {ref_col}" + self.add_condition(lambda s, l, t: col(l, s) == ref_col) + + class _IndentGreater(Empty): + def __init__(self, ref_col: int): + super().__init__() + self.errmsg = f"expected indent at column greater than {ref_col}" + self.add_condition(lambda s, l, t: col(l, s) > ref_col) + + def __init__( + self, expr: ParserElement, *, recursive: bool = False, grouped: bool = True + ): + super().__init__(expr, savelist=True) + # if recursive: + # raise NotImplementedError("IndentedBlock with recursive is not implemented") + self._recursive = recursive + self._grouped = grouped + self.parent_anchor = 1 + + def parseImpl(self, instring, loc, doActions=True): + # advance parse position to non-whitespace by using an Empty() + # this should be the column to be used for all subsequent indented lines + anchor_loc = Empty().preParse(instring, loc) + + # see if self.expr matches at the current location - if not it will raise an exception + # and no further work is necessary + self.expr.try_parse(instring, anchor_loc, do_actions=doActions) + + indent_col = col(anchor_loc, instring) + peer_detect_expr = self._Indent(indent_col) + + inner_expr = Empty() + peer_detect_expr + self.expr + if self._recursive: + sub_indent = self._IndentGreater(indent_col) + nested_block = IndentedBlock( + self.expr, recursive=self._recursive, grouped=self._grouped + ) + nested_block.set_debug(self.debug) + nested_block.parent_anchor = indent_col + inner_expr += Opt(sub_indent + nested_block) + + inner_expr.set_name(f"inner {hex(id(inner_expr))[-4:].upper()}@{indent_col}") + block = OneOrMore(inner_expr) + + trailing_undent = self._Indent(self.parent_anchor) | StringEnd() + + if self._grouped: + wrapper = Group + else: + wrapper = lambda expr: expr + return (wrapper(block) + Optional(trailing_undent)).parseImpl( + instring, anchor_loc, doActions + ) + + +class AtStringStart(ParseElementEnhance): + """Matches if expression matches at the beginning of the parse + string:: + + AtStringStart(Word(nums)).parse_string("123") + # prints ["123"] + + AtStringStart(Word(nums)).parse_string(" 123") + # raises ParseException + """ + + def __init__(self, expr: Union[ParserElement, str]): + super().__init__(expr) + self.callPreparse = False + + def parseImpl(self, instring, loc, doActions=True): + if loc != 0: + raise ParseException(instring, loc, "not found at string start") + return super().parseImpl(instring, loc, doActions) + + +class AtLineStart(ParseElementEnhance): + r"""Matches if an expression matches at the beginning of a line within + the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (AtLineStart('AAA') + rest_of_line).search_string(test): + print(t) + + prints:: + + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + + def __init__(self, expr: Union[ParserElement, str]): + super().__init__(expr) + self.callPreparse = False + + def parseImpl(self, instring, loc, doActions=True): + if col(loc, instring) != 1: + raise ParseException(instring, loc, "not found at line start") + return super().parseImpl(instring, loc, doActions) + + +class FollowedBy(ParseElementEnhance): + """Lookahead matching of the given parse expression. + ``FollowedBy`` does *not* advance the parsing position within + the input string, it only verifies that the specified parse + expression matches at the current position. ``FollowedBy`` + always returns a null token list. If any results names are defined + in the lookahead expression, those *will* be returned for access by + name. + + Example:: + + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join)) + + attr_expr[1, ...].parse_string("shape: SQUARE color: BLACK posn: upper left").pprint() + + prints:: + + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + + def __init__(self, expr: Union[ParserElement, str]): + super().__init__(expr) + self.mayReturnEmpty = True + + def parseImpl(self, instring, loc, doActions=True): + # by using self._expr.parse and deleting the contents of the returned ParseResults list + # we keep any named results that were defined in the FollowedBy expression + _, ret = self.expr._parse(instring, loc, doActions=doActions) + del ret[:] + + return loc, ret + + +class PrecededBy(ParseElementEnhance): + """Lookbehind matching of the given parse expression. + ``PrecededBy`` does not advance the parsing position within the + input string, it only verifies that the specified parse expression + matches prior to the current position. ``PrecededBy`` always + returns a null token list, but if a results name is defined on the + given expression, it is returned. + + Parameters: + + - ``expr`` - expression that must match prior to the current parse + location + - ``retreat`` - (default= ``None``) - (int) maximum number of characters + to lookbehind prior to the current parse location + + If the lookbehind expression is a string, :class:`Literal`, + :class:`Keyword`, or a :class:`Word` or :class:`CharsNotIn` + with a specified exact or maximum length, then the retreat + parameter is not required. Otherwise, retreat must be specified to + give a maximum number of characters to look back from + the current parse position for a lookbehind match. + + Example:: + + # VB-style variable names with type prefixes + int_var = PrecededBy("#") + pyparsing_common.identifier + str_var = PrecededBy("$") + pyparsing_common.identifier + + """ + + def __init__( + self, expr: Union[ParserElement, str], retreat: typing.Optional[int] = None + ): + super().__init__(expr) + self.expr = self.expr().leave_whitespace() + self.mayReturnEmpty = True + self.mayIndexError = False + self.exact = False + if isinstance(expr, str_type): + expr = typing.cast(str, expr) + retreat = len(expr) + self.exact = True + elif isinstance(expr, (Literal, Keyword)): + retreat = expr.matchLen + self.exact = True + elif isinstance(expr, (Word, CharsNotIn)) and expr.maxLen != _MAX_INT: + retreat = expr.maxLen + self.exact = True + elif isinstance(expr, PositionToken): + retreat = 0 + self.exact = True + self.retreat = retreat + self.errmsg = "not preceded by " + str(expr) + self.skipWhitespace = False + self.parseAction.append(lambda s, l, t: t.__delitem__(slice(None, None))) + + def parseImpl(self, instring, loc=0, doActions=True): + if self.exact: + if loc < self.retreat: + raise ParseException(instring, loc, self.errmsg) + start = loc - self.retreat + _, ret = self.expr._parse(instring, start) + else: + # retreat specified a maximum lookbehind window, iterate + test_expr = self.expr + StringEnd() + instring_slice = instring[max(0, loc - self.retreat) : loc] + last_expr = ParseException(instring, loc, self.errmsg) + for offset in range(1, min(loc, self.retreat + 1) + 1): + try: + # print('trying', offset, instring_slice, repr(instring_slice[loc - offset:])) + _, ret = test_expr._parse( + instring_slice, len(instring_slice) - offset + ) + except ParseBaseException as pbe: + last_expr = pbe + else: + break + else: + raise last_expr + return loc, ret + + +class Located(ParseElementEnhance): + """ + Decorates a returned token with its starting and ending + locations in the input string. + + This helper adds the following results names: + + - ``locn_start`` - location where matched expression begins + - ``locn_end`` - location where matched expression ends + - ``value`` - the actual parsed results + + Be careful if the input text contains ``<TAB>`` characters, you + may want to call :class:`ParserElement.parse_with_tabs` + + Example:: + + wd = Word(alphas) + for match in Located(wd).search_string("ljsdf123lksdjjf123lkkjj1222"): + print(match) + + prints:: + + [0, ['ljsdf'], 5] + [8, ['lksdjjf'], 15] + [18, ['lkkjj'], 23] + + """ + + def parseImpl(self, instring, loc, doActions=True): + start = loc + loc, tokens = self.expr._parse(instring, start, doActions, callPreParse=False) + ret_tokens = ParseResults([start, tokens, loc]) + ret_tokens["locn_start"] = start + ret_tokens["value"] = tokens + ret_tokens["locn_end"] = loc + if self.resultsName: + # must return as a list, so that the name will be attached to the complete group + return loc, [ret_tokens] + else: + return loc, ret_tokens + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. + ``NotAny`` does *not* advance the parsing position within the + input string, it only verifies that the specified parse expression + does *not* match at the current position. Also, ``NotAny`` does + *not* skip over leading whitespace. ``NotAny`` always returns + a null token list. May be constructed using the ``'~'`` operator. + + Example:: + + AND, OR, NOT = map(CaselessKeyword, "AND OR NOT".split()) + + # take care not to mistake keywords for identifiers + ident = ~(AND | OR | NOT) + Word(alphas) + boolean_term = Opt(NOT) + ident + + # very crude boolean expression - to support parenthesis groups and + # operation hierarchy, use infix_notation + boolean_expr = boolean_term + ((AND | OR) + boolean_term)[...] + + # integers that are followed by "." are actually floats + integer = Word(nums) + ~Char(".") + """ + + def __init__(self, expr: Union[ParserElement, str]): + super().__init__(expr) + # do NOT use self.leave_whitespace(), don't want to propagate to exprs + # self.leave_whitespace() + self.skipWhitespace = False + + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, " + str(self.expr) + + def parseImpl(self, instring, loc, doActions=True): + if self.expr.can_parse_next(instring, loc, do_actions=doActions): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def _generateDefaultName(self) -> str: + return "~{" + str(self.expr) + "}" + + +class _MultipleMatch(ParseElementEnhance): + def __init__( + self, + expr: Union[str, ParserElement], + stop_on: typing.Optional[Union[ParserElement, str]] = None, + *, + stopOn: typing.Optional[Union[ParserElement, str]] = None, + ): + super().__init__(expr) + stopOn = stopOn or stop_on + self.saveAsList = True + ender = stopOn + if isinstance(ender, str_type): + ender = self._literalStringClass(ender) + self.stopOn(ender) + + def stopOn(self, ender) -> ParserElement: + if isinstance(ender, str_type): + ender = self._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + return self + + def parseImpl(self, instring, loc, doActions=True): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.try_parse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse(instring, loc, doActions) + try: + hasIgnoreExprs = not not self.ignoreExprs + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables(instring, loc) + else: + preloc = loc + loc, tmptokens = self_expr_parse(instring, preloc, doActions) + tokens += tmptokens + except (ParseException, IndexError): + pass + + return loc, tokens + + def _setResultsName(self, name, listAllMatches=False): + if ( + __diag__.warn_ungrouped_named_tokens_in_collection + and Diagnostics.warn_ungrouped_named_tokens_in_collection + not in self.suppress_warnings_ + ): + for e in [self.expr] + self.expr.recurse(): + if ( + isinstance(e, ParserElement) + and e.resultsName + and Diagnostics.warn_ungrouped_named_tokens_in_collection + not in e.suppress_warnings_ + ): + warnings.warn( + "{}: setting results name {!r} on {} expression " + "collides with {!r} on contained expression".format( + "warn_ungrouped_named_tokens_in_collection", + name, + type(self).__name__, + e.resultsName, + ), + stacklevel=3, + ) + + return super()._setResultsName(name, listAllMatches) + + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + + - ``expr`` - expression that must match one or more times + - ``stop_on`` - (default= ``None``) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).set_parse_action(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + attr_expr[1, ...].parse_string(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stop_on attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join)) + OneOrMore(attr_expr).parse_string(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parse_string(text).pprint() + """ + + def _generateDefaultName(self) -> str: + return "{" + str(self.expr) + "}..." + + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + + - ``expr`` - expression that must match zero or more times + - ``stop_on`` - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) - (default= ``None``) + + Example: similar to :class:`OneOrMore` + """ + + def __init__( + self, + expr: Union[str, ParserElement], + stop_on: typing.Optional[Union[ParserElement, str]] = None, + *, + stopOn: typing.Optional[Union[ParserElement, str]] = None, + ): + super().__init__(expr, stopOn=stopOn or stop_on) + self.mayReturnEmpty = True + + def parseImpl(self, instring, loc, doActions=True): + try: + return super().parseImpl(instring, loc, doActions) + except (ParseException, IndexError): + return loc, ParseResults([], name=self.resultsName) + + def _generateDefaultName(self) -> str: + return "[" + str(self.expr) + "]..." + + +class DelimitedList(ParseElementEnhance): + def __init__( + self, + expr: Union[str, ParserElement], + delim: Union[str, ParserElement] = ",", + combine: bool = False, + min: typing.Optional[int] = None, + max: typing.Optional[int] = None, + *, + allow_trailing_delim: bool = False, + ): + """Helper to define a delimited list of expressions - the delimiter + defaults to ','. By default, the list elements and delimiters can + have intervening whitespace, and comments, but this can be + overridden by passing ``combine=True`` in the constructor. If + ``combine`` is set to ``True``, the matching tokens are + returned as a single token string, with the delimiters included; + otherwise, the matching tokens are returned as a list of tokens, + with the delimiters suppressed. + + If ``allow_trailing_delim`` is set to True, then the list may end with + a delimiter. + + Example:: + + DelimitedList(Word(alphas)).parse_string("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + DelimitedList(Word(hexnums), delim=':', combine=True).parse_string("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + if isinstance(expr, str_type): + expr = ParserElement._literalStringClass(expr) + expr = typing.cast(ParserElement, expr) + + if min is not None: + if min < 1: + raise ValueError("min must be greater than 0") + if max is not None: + if min is not None and max < min: + raise ValueError("max must be greater than, or equal to min") + + self.content = expr + self.raw_delim = str(delim) + self.delim = delim + self.combine = combine + if not combine: + self.delim = Suppress(delim) + self.min = min or 1 + self.max = max + self.allow_trailing_delim = allow_trailing_delim + + delim_list_expr = self.content + (self.delim + self.content) * ( + self.min - 1, + None if self.max is None else self.max - 1, + ) + if self.allow_trailing_delim: + delim_list_expr += Opt(self.delim) + + if self.combine: + delim_list_expr = Combine(delim_list_expr) + + super().__init__(delim_list_expr, savelist=True) + + def _generateDefaultName(self) -> str: + return "{0} [{1} {0}]...".format(self.content.streamline(), self.raw_delim) + + +class _NullToken: + def __bool__(self): + return False + + def __str__(self): + return "" + + +class Opt(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + + - ``expr`` - expression that must match zero or more times + - ``default`` (optional) - value to be returned if the optional expression is not found. + + Example:: + + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Opt('-' + Word(nums, exact=4))) + zip.run_tests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + + prints:: + + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + + __optionalNotMatched = _NullToken() + + def __init__( + self, expr: Union[ParserElement, str], default: Any = __optionalNotMatched + ): + super().__init__(expr, savelist=False) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl(self, instring, loc, doActions=True): + self_expr = self.expr + try: + loc, tokens = self_expr._parse(instring, loc, doActions, callPreParse=False) + except (ParseException, IndexError): + default_value = self.defaultValue + if default_value is not self.__optionalNotMatched: + if self_expr.resultsName: + tokens = ParseResults([default_value]) + tokens[self_expr.resultsName] = default_value + else: + tokens = [default_value] + else: + tokens = [] + return loc, tokens + + def _generateDefaultName(self) -> str: + inner = str(self.expr) + # strip off redundant inner {}'s + while len(inner) > 1 and inner[0 :: len(inner) - 1] == "{}": + inner = inner[1:-1] + return "[" + inner + "]" + + +Optional = Opt + + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched + expression is found. + + Parameters: + + - ``expr`` - target expression marking the end of the data to be skipped + - ``include`` - if ``True``, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element + list) (default= ``False``). + - ``ignore`` - (default= ``None``) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - ``fail_on`` - (default= ``None``) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the :class:`SkipTo` is not a match + + Example:: + + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quoted_string) + string_data.set_parse_action(token_map(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.search_string(report): + print tkt.dump() + + prints:: + + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: '6' + - desc: 'Intermittent system crash' + - issue_num: '101' + - sev: 'Critical' + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: '14' + - desc: "Spelling error on Login ('log|n')" + - issue_num: '94' + - sev: 'Cosmetic' + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: '47' + - desc: 'System slow when running too many reports' + - issue_num: '79' + - sev: 'Minor' + """ + + def __init__( + self, + other: Union[ParserElement, str], + include: bool = False, + ignore: typing.Optional[Union[ParserElement, str]] = None, + fail_on: typing.Optional[Union[ParserElement, str]] = None, + *, + failOn: typing.Optional[Union[ParserElement, str]] = None, + ): + super().__init__(other) + failOn = failOn or fail_on + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.saveAsList = False + if isinstance(failOn, str_type): + self.failOn = self._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for " + str(self.expr) + self.ignorer = Empty().leave_whitespace() + self._update_ignorer() + + def _update_ignorer(self): + # rebuild internal ignore expr from current ignore exprs and assigned ignoreExpr + self.ignorer.ignoreExprs.clear() + for e in self.expr.ignoreExprs: + self.ignorer.ignore(e) + if self.ignoreExpr: + self.ignorer.ignore(self.ignoreExpr) + + def ignore(self, expr): + super().ignore(expr) + self._update_ignorer() + + def parseImpl(self, instring, loc, doActions=True): + startloc = loc + instrlen = len(instring) + self_expr_parse = self.expr._parse + self_failOn_canParseNext = ( + self.failOn.canParseNext if self.failOn is not None else None + ) + ignorer_try_parse = self.ignorer.try_parse if self.ignorer.ignoreExprs else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if ignorer_try_parse is not None: + # advance past ignore expressions + prev_tmploc = tmploc + while 1: + try: + tmploc = ignorer_try_parse(instring, tmploc) + except ParseBaseException: + break + # see if all ignorers matched, but didn't actually ignore anything + if tmploc == prev_tmploc: + break + prev_tmploc = tmploc + + try: + self_expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = self_expr_parse(instring, loc, doActions, callPreParse=False) + skipresult += mat + + return loc, skipresult + + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the ``Forward`` + variable using the ``'<<'`` operator. + + Note: take care when assigning to ``Forward`` not to overlook + precedence of operators. + + Specifically, ``'|'`` has a lower precedence than ``'<<'``, so that:: + + fwd_expr << a | b | c + + will actually be evaluated as:: + + (fwd_expr << a) | b | c + + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the ``Forward``:: + + fwd_expr << (a | b | c) + + Converting to use the ``'<<='`` operator instead will avoid this problem. + + See :class:`ParseResults.pprint` for an example of a recursive + parser created using ``Forward``. + """ + + def __init__(self, other: typing.Optional[Union[ParserElement, str]] = None): + self.caller_frame = traceback.extract_stack(limit=2)[0] + super().__init__(other, savelist=False) # type: ignore[arg-type] + self.lshift_line = None + + def __lshift__(self, other) -> "Forward": + if hasattr(self, "caller_frame"): + del self.caller_frame + if isinstance(other, str_type): + other = self._literalStringClass(other) + + if not isinstance(other, ParserElement): + return NotImplemented + + self.expr = other + self.streamlined = other.streamlined + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.set_whitespace_chars( + self.expr.whiteChars, copy_defaults=self.expr.copyDefaultWhiteChars + ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + self.lshift_line = traceback.extract_stack(limit=2)[-2] # type: ignore[assignment] + return self + + def __ilshift__(self, other) -> "Forward": + if not isinstance(other, ParserElement): + return NotImplemented + + return self << other + + def __or__(self, other) -> "ParserElement": + caller_line = traceback.extract_stack(limit=2)[-2] + if ( + __diag__.warn_on_match_first_with_lshift_operator + and caller_line == self.lshift_line + and Diagnostics.warn_on_match_first_with_lshift_operator + not in self.suppress_warnings_ + ): + warnings.warn( + "using '<<' operator with '|' is probably an error, use '<<='", + stacklevel=2, + ) + ret = super().__or__(other) + return ret + + def __del__(self): + # see if we are getting dropped because of '=' reassignment of var instead of '<<=' or '<<' + if ( + self.expr is None + and __diag__.warn_on_assignment_to_Forward + and Diagnostics.warn_on_assignment_to_Forward not in self.suppress_warnings_ + ): + warnings.warn_explicit( + "Forward defined here but no expression attached later using '<<=' or '<<'", + UserWarning, + filename=self.caller_frame.filename, + lineno=self.caller_frame.lineno, + ) + + def parseImpl(self, instring, loc, doActions=True): + if ( + self.expr is None + and __diag__.warn_on_parse_using_empty_Forward + and Diagnostics.warn_on_parse_using_empty_Forward + not in self.suppress_warnings_ + ): + # walk stack until parse_string, scan_string, search_string, or transform_string is found + parse_fns = ( + "parse_string", + "scan_string", + "search_string", + "transform_string", + ) + tb = traceback.extract_stack(limit=200) + for i, frm in enumerate(reversed(tb), start=1): + if frm.name in parse_fns: + stacklevel = i + 1 + break + else: + stacklevel = 2 + warnings.warn( + "Forward expression was never assigned a value, will not parse any input", + stacklevel=stacklevel, + ) + if not ParserElement._left_recursion_enabled: + return super().parseImpl(instring, loc, doActions) + # ## Bounded Recursion algorithm ## + # Recursion only needs to be processed at ``Forward`` elements, since they are + # the only ones that can actually refer to themselves. The general idea is + # to handle recursion stepwise: We start at no recursion, then recurse once, + # recurse twice, ..., until more recursion offers no benefit (we hit the bound). + # + # The "trick" here is that each ``Forward`` gets evaluated in two contexts + # - to *match* a specific recursion level, and + # - to *search* the bounded recursion level + # and the two run concurrently. The *search* must *match* each recursion level + # to find the best possible match. This is handled by a memo table, which + # provides the previous match to the next level match attempt. + # + # See also "Left Recursion in Parsing Expression Grammars", Medeiros et al. + # + # There is a complication since we not only *parse* but also *transform* via + # actions: We do not want to run the actions too often while expanding. Thus, + # we expand using `doActions=False` and only run `doActions=True` if the next + # recursion level is acceptable. + with ParserElement.recursion_lock: + memo = ParserElement.recursion_memos + try: + # we are parsing at a specific recursion expansion - use it as-is + prev_loc, prev_result = memo[loc, self, doActions] + if isinstance(prev_result, Exception): + raise prev_result + return prev_loc, prev_result.copy() + except KeyError: + act_key = (loc, self, True) + peek_key = (loc, self, False) + # we are searching for the best recursion expansion - keep on improving + # both `doActions` cases must be tracked separately here! + prev_loc, prev_peek = memo[peek_key] = ( + loc - 1, + ParseException( + instring, loc, "Forward recursion without base case", self + ), + ) + if doActions: + memo[act_key] = memo[peek_key] + while True: + try: + new_loc, new_peek = super().parseImpl(instring, loc, False) + except ParseException: + # we failed before getting any match – do not hide the error + if isinstance(prev_peek, Exception): + raise + new_loc, new_peek = prev_loc, prev_peek + # the match did not get better: we are done + if new_loc <= prev_loc: + if doActions: + # replace the match for doActions=False as well, + # in case the action did backtrack + prev_loc, prev_result = memo[peek_key] = memo[act_key] + del memo[peek_key], memo[act_key] + return prev_loc, prev_result.copy() + del memo[peek_key] + return prev_loc, prev_peek.copy() + # the match did get better: see if we can improve further + else: + if doActions: + try: + memo[act_key] = super().parseImpl(instring, loc, True) + except ParseException as e: + memo[peek_key] = memo[act_key] = (new_loc, e) + raise + prev_loc, prev_peek = memo[peek_key] = new_loc, new_peek + + def leave_whitespace(self, recursive: bool = True) -> ParserElement: + self.skipWhitespace = False + return self + + def ignore_whitespace(self, recursive: bool = True) -> ParserElement: + self.skipWhitespace = True + return self + + def streamline(self) -> ParserElement: + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate(self, validateTrace=None) -> None: + warnings.warn( + "ParserElement.validate() is deprecated, and should not be used to check for left recursion", + DeprecationWarning, + stacklevel=2, + ) + if validateTrace is None: + validateTrace = [] + + if self not in validateTrace: + tmp = validateTrace[:] + [self] + if self.expr is not None: + self.expr.validate(tmp) + self._checkRecursion([]) + + def _generateDefaultName(self) -> str: + # Avoid infinite recursion by setting a temporary _defaultName + self._defaultName = ": ..." + + # Use the string representation of main expression. + retString = "..." + try: + if self.expr is not None: + retString = str(self.expr)[:1000] + else: + retString = "None" + finally: + return self.__class__.__name__ + ": " + retString + + def copy(self) -> ParserElement: + if self.expr is not None: + return super().copy() + else: + ret = Forward() + ret <<= self + return ret + + def _setResultsName(self, name, list_all_matches=False): + if ( + __diag__.warn_name_set_on_empty_Forward + and Diagnostics.warn_name_set_on_empty_Forward + not in self.suppress_warnings_ + ): + if self.expr is None: + warnings.warn( + "{}: setting results name {!r} on {} expression " + "that has no contained expression".format( + "warn_name_set_on_empty_Forward", name, type(self).__name__ + ), + stacklevel=3, + ) + + return super()._setResultsName(name, list_all_matches) + + # Compatibility synonyms + # fmt: off + @replaced_by_pep8(leave_whitespace) + def leaveWhitespace(self): ... + + @replaced_by_pep8(ignore_whitespace) + def ignoreWhitespace(self): ... + # fmt: on + + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of :class:`ParseExpression`, for converting parsed results. + """ + + def __init__(self, expr: Union[ParserElement, str], savelist=False): + super().__init__(expr) # , savelist) + self.saveAsList = False + + +class Combine(TokenConverter): + """Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the + input string; this can be disabled by specifying + ``'adjacent=False'`` in the constructor. + + Example:: + + real = Word(nums) + '.' + Word(nums) + print(real.parse_string('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parse_string('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parse_string('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parse_string('3. 1416')) # -> Exception: Expected W:(0123...) + """ + + def __init__( + self, + expr: ParserElement, + join_string: str = "", + adjacent: bool = True, + *, + joinString: typing.Optional[str] = None, + ): + super().__init__(expr) + joinString = joinString if joinString is not None else join_string + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leave_whitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore(self, other) -> ParserElement: + if self.adjacent: + ParserElement.ignore(self, other) + else: + super().ignore(other) + return self + + def postParse(self, instring, loc, tokenlist): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults( + ["".join(tokenlist._asStringList(self.joinString))], modal=self.modalResults + ) + + if self.resultsName and retToks.haskeys(): + return [retToks] + else: + return retToks + + +class Group(TokenConverter): + """Converter to return the matched tokens as a list - useful for + returning tokens of :class:`ZeroOrMore` and :class:`OneOrMore` expressions. + + The optional ``aslist`` argument when set to True will return the + parsed tokens as a Python list instead of a pyparsing ParseResults. + + Example:: + + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Opt(DelimitedList(term)) + print(func.parse_string("fn a, b, 100")) + # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Opt(DelimitedList(term))) + print(func.parse_string("fn a, b, 100")) + # -> ['fn', ['a', 'b', '100']] + """ + + def __init__(self, expr: ParserElement, aslist: bool = False): + super().__init__(expr) + self.saveAsList = True + self._asPythonList = aslist + + def postParse(self, instring, loc, tokenlist): + if self._asPythonList: + return ParseResults.List( + tokenlist.asList() + if isinstance(tokenlist, ParseResults) + else list(tokenlist) + ) + else: + return [tokenlist] + + +class Dict(TokenConverter): + """Converter to return a repetitive expression as a list, but also + as a dictionary. Each element can also be referenced using the first + token in the expression as its key. Useful for tabular report + scraping when the first column can be used as a item key. + + The optional ``asdict`` argument when set to True will return the + parsed tokens as a Python dict instead of a pyparsing ParseResults. + + Example:: + + data_word = Word(alphas) + label = data_word + FollowedBy(':') + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join)) + + # print attributes as plain groups + print(attr_expr[1, ...].parse_string(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(Group(expr)[1, ...]) - Dict will auto-assign names + result = Dict(Group(attr_expr)[1, ...]).parse_string(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.as_dict()) + + prints:: + + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: 'light blue' + - posn: 'upper left' + - shape: 'SQUARE' + - texture: 'burlap' + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + + See more examples at :class:`ParseResults` of accessing fields by results name. + """ + + def __init__(self, expr: ParserElement, asdict: bool = False): + super().__init__(expr) + self.saveAsList = True + self._asPythonDict = asdict + + def postParse(self, instring, loc, tokenlist): + for i, tok in enumerate(tokenlist): + if len(tok) == 0: + continue + + ikey = tok[0] + if isinstance(ikey, int): + ikey = str(ikey).strip() + + if len(tok) == 1: + tokenlist[ikey] = _ParseResultsWithOffset("", i) + + elif len(tok) == 2 and not isinstance(tok[1], ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1], i) + + else: + try: + dictvalue = tok.copy() # ParseResults(i) + except Exception: + exc = TypeError( + "could not extract dict values from parsed results" + " - Dict expression must contain Grouped expressions" + ) + raise exc from None + + del dictvalue[0] + + if len(dictvalue) != 1 or ( + isinstance(dictvalue, ParseResults) and dictvalue.haskeys() + ): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue, i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0], i) + + if self._asPythonDict: + return [tokenlist.as_dict()] if self.resultsName else tokenlist.as_dict() + else: + return [tokenlist] if self.resultsName else tokenlist + + +class Suppress(TokenConverter): + """Converter for ignoring the results of a parsed expression. + + Example:: + + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + (',' + wd)[...] + print(wd_list1.parse_string(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + (Suppress(',') + wd)[...] + print(wd_list2.parse_string(source)) + + # Skipped text (using '...') can be suppressed as well + source = "lead in START relevant text END trailing text" + start_marker = Keyword("START") + end_marker = Keyword("END") + find_body = Suppress(...) + start_marker + ... + end_marker + print(find_body.parse_string(source) + + prints:: + + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + ['START', 'relevant text ', 'END'] + + (See also :class:`DelimitedList`.) + """ + + def __init__(self, expr: Union[ParserElement, str], savelist: bool = False): + if expr is ...: + expr = _PendingSkip(NoMatch()) + super().__init__(expr) + + def __add__(self, other) -> "ParserElement": + if isinstance(self.expr, _PendingSkip): + return Suppress(SkipTo(other)) + other + else: + return super().__add__(other) + + def __sub__(self, other) -> "ParserElement": + if isinstance(self.expr, _PendingSkip): + return Suppress(SkipTo(other)) - other + else: + return super().__sub__(other) + + def postParse(self, instring, loc, tokenlist): + return [] + + def suppress(self) -> ParserElement: + return self + + +def trace_parse_action(f: ParseAction) -> ParseAction: + """Decorator for debugging parse actions. + + When the parse action is called, this decorator will print + ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``. + When the parse action completes, the decorator will print + ``"<<"`` followed by the returned value, or any exception that the parse action raised. + + Example:: + + wd = Word(alphas) + + @trace_parse_action + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = wd[1, ...].set_parse_action(remove_duplicate_chars) + print(wds.parse_string("slkdjs sld sldd sdlf sdljf")) + + prints:: + + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + + def z(*paArgs): + thisFunc = f.__name__ + s, l, t = paArgs[-3:] + if len(paArgs) > 3: + thisFunc = paArgs[0].__class__.__name__ + "." + thisFunc + sys.stderr.write(f">>entering {thisFunc}(line: {line(l, s)!r}, {l}, {t!r})\n") + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write(f"<<leaving {thisFunc} (exception: {exc})\n") + raise + sys.stderr.write(f"<<leaving {thisFunc} (ret: {ret!r})\n") + return ret + + z.__name__ = f.__name__ + return z + + +# convenience constants for positional expressions +empty = Empty().set_name("empty") +line_start = LineStart().set_name("line_start") +line_end = LineEnd().set_name("line_end") +string_start = StringStart().set_name("string_start") +string_end = StringEnd().set_name("string_end") + +_escapedPunc = Regex(r"\\[\\[\]\/\-\*\.\$\+\^\?()~ ]").set_parse_action( + lambda s, l, t: t[0][1] +) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").set_parse_action( + lambda s, l, t: chr(int(t[0].lstrip(r"\0x"), 16)) +) +_escapedOctChar = Regex(r"\\0[0-7]+").set_parse_action( + lambda s, l, t: chr(int(t[0][1:], 8)) +) +_singleChar = ( + _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r"\]", exact=1) +) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = ( + Literal("[") + + Opt("^").set_results_name("negate") + + Group(OneOrMore(_charRange | _singleChar)).set_results_name("body") + + Literal("]") +) + + +def srange(s: str) -> str: + r"""Helper to easily define string ranges for use in :class:`Word` + construction. Borrows syntax from regexp ``'[]'`` string range + definitions:: + + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + + The input string must be enclosed in []'s, and the returned string + is the expanded character set joined into a single string. The + values enclosed in the []'s may be: + + - a single character + - an escaped character with a leading backslash (such as ``\-`` + or ``\]``) + - an escaped hex character with a leading ``'\x'`` + (``\x21``, which is a ``'!'`` character) (``\0x##`` + is also supported for backwards compatibility) + - an escaped octal character with a leading ``'\0'`` + (``\041``, which is a ``'!'`` character) + - a range of any of the above, separated by a dash (``'a-z'``, + etc.) + - any combination of the above (``'aeiouy'``, + ``'a-zA-Z0-9_$'``, etc.) + """ + _expanded = ( + lambda p: p + if not isinstance(p, ParseResults) + else "".join(chr(c) for c in range(ord(p[0]), ord(p[1]) + 1)) + ) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parse_string(s).body) + except Exception as e: + return "" + + +def token_map(func, *args) -> ParseAction: + """Helper to define a parse action by mapping a function to all + elements of a :class:`ParseResults` list. If any additional args are passed, + they are forwarded to the given function as additional arguments + after the token, as in + ``hex_integer = Word(hexnums).set_parse_action(token_map(int, 16))``, + which will convert the parsed data to an integer using base 16. + + Example (compare the last to example in :class:`ParserElement.transform_string`:: + + hex_ints = Word(hexnums)[1, ...].set_parse_action(token_map(int, 16)) + hex_ints.run_tests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).set_parse_action(token_map(str.upper)) + upperword[1, ...].run_tests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).set_parse_action(token_map(str.title)) + wd[1, ...].set_parse_action(' '.join).run_tests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + + prints:: + + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + + def pa(s, l, t): + return [func(tokn, *args) for tokn in t] + + func_name = getattr(func, "__name__", getattr(func, "__class__").__name__) + pa.__name__ = func_name + + return pa + + +def autoname_elements() -> None: + """ + Utility to simplify mass-naming of parser elements, for + generating railroad diagram with named subdiagrams. + """ + calling_frame = sys._getframe().f_back + if calling_frame is None: + return + calling_frame = typing.cast(types.FrameType, calling_frame) + for name, var in calling_frame.f_locals.items(): + if isinstance(var, ParserElement) and not var.customName: + var.set_name(name) + + +dbl_quoted_string = Combine( + Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"' +).set_name("string enclosed in double quotes") + +sgl_quoted_string = Combine( + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'" +).set_name("string enclosed in single quotes") + +quoted_string = Combine( + (Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"').set_name( + "double quoted string" + ) + | (Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").set_name( + "single quoted string" + ) +).set_name("quoted string using single or double quotes") + +python_quoted_string = Combine( + (Regex(r'"""(?:[^"\\]|""(?!")|"(?!"")|\\.)*', flags=re.MULTILINE) + '"""').set_name( + "multiline double quoted string" + ) + ^ ( + Regex(r"'''(?:[^'\\]|''(?!')|'(?!'')|\\.)*", flags=re.MULTILINE) + "'''" + ).set_name("multiline single quoted string") + ^ (Regex(r'"(?:[^"\n\r\\]|(?:\\")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"').set_name( + "double quoted string" + ) + ^ (Regex(r"'(?:[^'\n\r\\]|(?:\\')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").set_name( + "single quoted string" + ) +).set_name("Python quoted string") + +unicode_string = Combine("u" + quoted_string.copy()).set_name("unicode string literal") + + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +# build list of built-in expressions, for future reference if a global default value +# gets updated +_builtin_exprs: List[ParserElement] = [ + v for v in vars().values() if isinstance(v, ParserElement) +] + +# backward compatibility names +# fmt: off +sglQuotedString = sgl_quoted_string +dblQuotedString = dbl_quoted_string +quotedString = quoted_string +unicodeString = unicode_string +lineStart = line_start +lineEnd = line_end +stringStart = string_start +stringEnd = string_end + +@replaced_by_pep8(null_debug_action) +def nullDebugAction(): ... + +@replaced_by_pep8(trace_parse_action) +def traceParseAction(): ... + +@replaced_by_pep8(condition_as_parse_action) +def conditionAsParseAction(): ... + +@replaced_by_pep8(token_map) +def tokenMap(): ... +# fmt: on diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/diagram/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/diagram/__init__.py new file mode 100644 index 00000000..267f3447 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/diagram/__init__.py @@ -0,0 +1,656 @@ +# mypy: ignore-errors +import railroad +import pyparsing +import typing +from typing import ( + List, + NamedTuple, + Generic, + TypeVar, + Dict, + Callable, + Set, + Iterable, +) +from jinja2 import Template +from io import StringIO +import inspect + + +jinja2_template_source = """\ +{% if not embed %} +<!DOCTYPE html> +<html> +<head> +{% endif %} + {% if not head %} + <style> + .railroad-heading { + font-family: monospace; + } + </style> + {% else %} + {{ head | safe }} + {% endif %} +{% if not embed %} +</head> +<body> +{% endif %} +{{ body | safe }} +{% for diagram in diagrams %} + <div class="railroad-group"> + <h1 class="railroad-heading">{{ diagram.title }}</h1> + <div class="railroad-description">{{ diagram.text }}</div> + <div class="railroad-svg"> + {{ diagram.svg }} + </div> + </div> +{% endfor %} +{% if not embed %} +</body> +</html> +{% endif %} +""" + +template = Template(jinja2_template_source) + +# Note: ideally this would be a dataclass, but we're supporting Python 3.5+ so we can't do this yet +NamedDiagram = NamedTuple( + "NamedDiagram", + [("name", str), ("diagram", typing.Optional[railroad.DiagramItem]), ("index", int)], +) +""" +A simple structure for associating a name with a railroad diagram +""" + +T = TypeVar("T") + + +class EachItem(railroad.Group): + """ + Custom railroad item to compose a: + - Group containing a + - OneOrMore containing a + - Choice of the elements in the Each + with the group label indicating that all must be matched + """ + + all_label = "[ALL]" + + def __init__(self, *items): + choice_item = railroad.Choice(len(items) - 1, *items) + one_or_more_item = railroad.OneOrMore(item=choice_item) + super().__init__(one_or_more_item, label=self.all_label) + + +class AnnotatedItem(railroad.Group): + """ + Simple subclass of Group that creates an annotation label + """ + + def __init__(self, label: str, item): + super().__init__(item=item, label="[{}]".format(label) if label else label) + + +class EditablePartial(Generic[T]): + """ + Acts like a functools.partial, but can be edited. In other words, it represents a type that hasn't yet been + constructed. + """ + + # We need this here because the railroad constructors actually transform the data, so can't be called until the + # entire tree is assembled + + def __init__(self, func: Callable[..., T], args: list, kwargs: dict): + self.func = func + self.args = args + self.kwargs = kwargs + + @classmethod + def from_call(cls, func: Callable[..., T], *args, **kwargs) -> "EditablePartial[T]": + """ + If you call this function in the same way that you would call the constructor, it will store the arguments + as you expect. For example EditablePartial.from_call(Fraction, 1, 3)() == Fraction(1, 3) + """ + return EditablePartial(func=func, args=list(args), kwargs=kwargs) + + @property + def name(self): + return self.kwargs["name"] + + def __call__(self) -> T: + """ + Evaluate the partial and return the result + """ + args = self.args.copy() + kwargs = self.kwargs.copy() + + # This is a helpful hack to allow you to specify varargs parameters (e.g. *args) as keyword args (e.g. + # args=['list', 'of', 'things']) + arg_spec = inspect.getfullargspec(self.func) + if arg_spec.varargs in self.kwargs: + args += kwargs.pop(arg_spec.varargs) + + return self.func(*args, **kwargs) + + +def railroad_to_html(diagrams: List[NamedDiagram], embed=False, **kwargs) -> str: + """ + Given a list of NamedDiagram, produce a single HTML string that visualises those diagrams + :params kwargs: kwargs to be passed in to the template + """ + data = [] + for diagram in diagrams: + if diagram.diagram is None: + continue + io = StringIO() + try: + css = kwargs.get('css') + diagram.diagram.writeStandalone(io.write, css=css) + except AttributeError: + diagram.diagram.writeSvg(io.write) + title = diagram.name + if diagram.index == 0: + title += " (root)" + data.append({"title": title, "text": "", "svg": io.getvalue()}) + + return template.render(diagrams=data, embed=embed, **kwargs) + + +def resolve_partial(partial: "EditablePartial[T]") -> T: + """ + Recursively resolves a collection of Partials into whatever type they are + """ + if isinstance(partial, EditablePartial): + partial.args = resolve_partial(partial.args) + partial.kwargs = resolve_partial(partial.kwargs) + return partial() + elif isinstance(partial, list): + return [resolve_partial(x) for x in partial] + elif isinstance(partial, dict): + return {key: resolve_partial(x) for key, x in partial.items()} + else: + return partial + + +def to_railroad( + element: pyparsing.ParserElement, + diagram_kwargs: typing.Optional[dict] = None, + vertical: int = 3, + show_results_names: bool = False, + show_groups: bool = False, +) -> List[NamedDiagram]: + """ + Convert a pyparsing element tree into a list of diagrams. This is the recommended entrypoint to diagram + creation if you want to access the Railroad tree before it is converted to HTML + :param element: base element of the parser being diagrammed + :param diagram_kwargs: kwargs to pass to the Diagram() constructor + :param vertical: (optional) - int - limit at which number of alternatives should be + shown vertically instead of horizontally + :param show_results_names - bool to indicate whether results name annotations should be + included in the diagram + :param show_groups - bool to indicate whether groups should be highlighted with an unlabeled + surrounding box + """ + # Convert the whole tree underneath the root + lookup = ConverterState(diagram_kwargs=diagram_kwargs or {}) + _to_diagram_element( + element, + lookup=lookup, + parent=None, + vertical=vertical, + show_results_names=show_results_names, + show_groups=show_groups, + ) + + root_id = id(element) + # Convert the root if it hasn't been already + if root_id in lookup: + if not element.customName: + lookup[root_id].name = "" + lookup[root_id].mark_for_extraction(root_id, lookup, force=True) + + # Now that we're finished, we can convert from intermediate structures into Railroad elements + diags = list(lookup.diagrams.values()) + if len(diags) > 1: + # collapse out duplicate diags with the same name + seen = set() + deduped_diags = [] + for d in diags: + # don't extract SkipTo elements, they are uninformative as subdiagrams + if d.name == "...": + continue + if d.name is not None and d.name not in seen: + seen.add(d.name) + deduped_diags.append(d) + resolved = [resolve_partial(partial) for partial in deduped_diags] + else: + # special case - if just one diagram, always display it, even if + # it has no name + resolved = [resolve_partial(partial) for partial in diags] + return sorted(resolved, key=lambda diag: diag.index) + + +def _should_vertical( + specification: int, exprs: Iterable[pyparsing.ParserElement] +) -> bool: + """ + Returns true if we should return a vertical list of elements + """ + if specification is None: + return False + else: + return len(_visible_exprs(exprs)) >= specification + + +class ElementState: + """ + State recorded for an individual pyparsing Element + """ + + # Note: this should be a dataclass, but we have to support Python 3.5 + def __init__( + self, + element: pyparsing.ParserElement, + converted: EditablePartial, + parent: EditablePartial, + number: int, + name: str = None, + parent_index: typing.Optional[int] = None, + ): + #: The pyparsing element that this represents + self.element: pyparsing.ParserElement = element + #: The name of the element + self.name: typing.Optional[str] = name + #: The output Railroad element in an unconverted state + self.converted: EditablePartial = converted + #: The parent Railroad element, which we store so that we can extract this if it's duplicated + self.parent: EditablePartial = parent + #: The order in which we found this element, used for sorting diagrams if this is extracted into a diagram + self.number: int = number + #: The index of this inside its parent + self.parent_index: typing.Optional[int] = parent_index + #: If true, we should extract this out into a subdiagram + self.extract: bool = False + #: If true, all of this element's children have been filled out + self.complete: bool = False + + def mark_for_extraction( + self, el_id: int, state: "ConverterState", name: str = None, force: bool = False + ): + """ + Called when this instance has been seen twice, and thus should eventually be extracted into a sub-diagram + :param el_id: id of the element + :param state: element/diagram state tracker + :param name: name to use for this element's text + :param force: If true, force extraction now, regardless of the state of this. Only useful for extracting the + root element when we know we're finished + """ + self.extract = True + + # Set the name + if not self.name: + if name: + # Allow forcing a custom name + self.name = name + elif self.element.customName: + self.name = self.element.customName + else: + self.name = "" + + # Just because this is marked for extraction doesn't mean we can do it yet. We may have to wait for children + # to be added + # Also, if this is just a string literal etc, don't bother extracting it + if force or (self.complete and _worth_extracting(self.element)): + state.extract_into_diagram(el_id) + + +class ConverterState: + """ + Stores some state that persists between recursions into the element tree + """ + + def __init__(self, diagram_kwargs: typing.Optional[dict] = None): + #: A dictionary mapping ParserElements to state relating to them + self._element_diagram_states: Dict[int, ElementState] = {} + #: A dictionary mapping ParserElement IDs to subdiagrams generated from them + self.diagrams: Dict[int, EditablePartial[NamedDiagram]] = {} + #: The index of the next unnamed element + self.unnamed_index: int = 1 + #: The index of the next element. This is used for sorting + self.index: int = 0 + #: Shared kwargs that are used to customize the construction of diagrams + self.diagram_kwargs: dict = diagram_kwargs or {} + self.extracted_diagram_names: Set[str] = set() + + def __setitem__(self, key: int, value: ElementState): + self._element_diagram_states[key] = value + + def __getitem__(self, key: int) -> ElementState: + return self._element_diagram_states[key] + + def __delitem__(self, key: int): + del self._element_diagram_states[key] + + def __contains__(self, key: int): + return key in self._element_diagram_states + + def generate_unnamed(self) -> int: + """ + Generate a number used in the name of an otherwise unnamed diagram + """ + self.unnamed_index += 1 + return self.unnamed_index + + def generate_index(self) -> int: + """ + Generate a number used to index a diagram + """ + self.index += 1 + return self.index + + def extract_into_diagram(self, el_id: int): + """ + Used when we encounter the same token twice in the same tree. When this + happens, we replace all instances of that token with a terminal, and + create a new subdiagram for the token + """ + position = self[el_id] + + # Replace the original definition of this element with a regular block + if position.parent: + ret = EditablePartial.from_call(railroad.NonTerminal, text=position.name) + if "item" in position.parent.kwargs: + position.parent.kwargs["item"] = ret + elif "items" in position.parent.kwargs: + position.parent.kwargs["items"][position.parent_index] = ret + + # If the element we're extracting is a group, skip to its content but keep the title + if position.converted.func == railroad.Group: + content = position.converted.kwargs["item"] + else: + content = position.converted + + self.diagrams[el_id] = EditablePartial.from_call( + NamedDiagram, + name=position.name, + diagram=EditablePartial.from_call( + railroad.Diagram, content, **self.diagram_kwargs + ), + index=position.number, + ) + + del self[el_id] + + +def _worth_extracting(element: pyparsing.ParserElement) -> bool: + """ + Returns true if this element is worth having its own sub-diagram. Simply, if any of its children + themselves have children, then its complex enough to extract + """ + children = element.recurse() + return any(child.recurse() for child in children) + + +def _apply_diagram_item_enhancements(fn): + """ + decorator to ensure enhancements to a diagram item (such as results name annotations) + get applied on return from _to_diagram_element (we do this since there are several + returns in _to_diagram_element) + """ + + def _inner( + element: pyparsing.ParserElement, + parent: typing.Optional[EditablePartial], + lookup: ConverterState = None, + vertical: int = None, + index: int = 0, + name_hint: str = None, + show_results_names: bool = False, + show_groups: bool = False, + ) -> typing.Optional[EditablePartial]: + ret = fn( + element, + parent, + lookup, + vertical, + index, + name_hint, + show_results_names, + show_groups, + ) + + # apply annotation for results name, if present + if show_results_names and ret is not None: + element_results_name = element.resultsName + if element_results_name: + # add "*" to indicate if this is a "list all results" name + element_results_name += "" if element.modalResults else "*" + ret = EditablePartial.from_call( + railroad.Group, item=ret, label=element_results_name + ) + + return ret + + return _inner + + +def _visible_exprs(exprs: Iterable[pyparsing.ParserElement]): + non_diagramming_exprs = ( + pyparsing.ParseElementEnhance, + pyparsing.PositionToken, + pyparsing.And._ErrorStop, + ) + return [ + e + for e in exprs + if not (e.customName or e.resultsName or isinstance(e, non_diagramming_exprs)) + ] + + +@_apply_diagram_item_enhancements +def _to_diagram_element( + element: pyparsing.ParserElement, + parent: typing.Optional[EditablePartial], + lookup: ConverterState = None, + vertical: int = None, + index: int = 0, + name_hint: str = None, + show_results_names: bool = False, + show_groups: bool = False, +) -> typing.Optional[EditablePartial]: + """ + Recursively converts a PyParsing Element to a railroad Element + :param lookup: The shared converter state that keeps track of useful things + :param index: The index of this element within the parent + :param parent: The parent of this element in the output tree + :param vertical: Controls at what point we make a list of elements vertical. If this is an integer (the default), + it sets the threshold of the number of items before we go vertical. If True, always go vertical, if False, never + do so + :param name_hint: If provided, this will override the generated name + :param show_results_names: bool flag indicating whether to add annotations for results names + :returns: The converted version of the input element, but as a Partial that hasn't yet been constructed + :param show_groups: bool flag indicating whether to show groups using bounding box + """ + exprs = element.recurse() + name = name_hint or element.customName or element.__class__.__name__ + + # Python's id() is used to provide a unique identifier for elements + el_id = id(element) + + element_results_name = element.resultsName + + # Here we basically bypass processing certain wrapper elements if they contribute nothing to the diagram + if not element.customName: + if isinstance( + element, + ( + # pyparsing.TokenConverter, + # pyparsing.Forward, + pyparsing.Located, + ), + ): + # However, if this element has a useful custom name, and its child does not, we can pass it on to the child + if exprs: + if not exprs[0].customName: + propagated_name = name + else: + propagated_name = None + + return _to_diagram_element( + element.expr, + parent=parent, + lookup=lookup, + vertical=vertical, + index=index, + name_hint=propagated_name, + show_results_names=show_results_names, + show_groups=show_groups, + ) + + # If the element isn't worth extracting, we always treat it as the first time we say it + if _worth_extracting(element): + if el_id in lookup: + # If we've seen this element exactly once before, we are only just now finding out that it's a duplicate, + # so we have to extract it into a new diagram. + looked_up = lookup[el_id] + looked_up.mark_for_extraction(el_id, lookup, name=name_hint) + ret = EditablePartial.from_call(railroad.NonTerminal, text=looked_up.name) + return ret + + elif el_id in lookup.diagrams: + # If we have seen the element at least twice before, and have already extracted it into a subdiagram, we + # just put in a marker element that refers to the sub-diagram + ret = EditablePartial.from_call( + railroad.NonTerminal, text=lookup.diagrams[el_id].kwargs["name"] + ) + return ret + + # Recursively convert child elements + # Here we find the most relevant Railroad element for matching pyparsing Element + # We use ``items=[]`` here to hold the place for where the child elements will go once created + if isinstance(element, pyparsing.And): + # detect And's created with ``expr*N`` notation - for these use a OneOrMore with a repeat + # (all will have the same name, and resultsName) + if not exprs: + return None + if len(set((e.name, e.resultsName) for e in exprs)) == 1: + ret = EditablePartial.from_call( + railroad.OneOrMore, item="", repeat=str(len(exprs)) + ) + elif _should_vertical(vertical, exprs): + ret = EditablePartial.from_call(railroad.Stack, items=[]) + else: + ret = EditablePartial.from_call(railroad.Sequence, items=[]) + elif isinstance(element, (pyparsing.Or, pyparsing.MatchFirst)): + if not exprs: + return None + if _should_vertical(vertical, exprs): + ret = EditablePartial.from_call(railroad.Choice, 0, items=[]) + else: + ret = EditablePartial.from_call(railroad.HorizontalChoice, items=[]) + elif isinstance(element, pyparsing.Each): + if not exprs: + return None + ret = EditablePartial.from_call(EachItem, items=[]) + elif isinstance(element, pyparsing.NotAny): + ret = EditablePartial.from_call(AnnotatedItem, label="NOT", item="") + elif isinstance(element, pyparsing.FollowedBy): + ret = EditablePartial.from_call(AnnotatedItem, label="LOOKAHEAD", item="") + elif isinstance(element, pyparsing.PrecededBy): + ret = EditablePartial.from_call(AnnotatedItem, label="LOOKBEHIND", item="") + elif isinstance(element, pyparsing.Group): + if show_groups: + ret = EditablePartial.from_call(AnnotatedItem, label="", item="") + else: + ret = EditablePartial.from_call(railroad.Group, label="", item="") + elif isinstance(element, pyparsing.TokenConverter): + label = type(element).__name__.lower() + if label == "tokenconverter": + ret = EditablePartial.from_call(railroad.Sequence, items=[]) + else: + ret = EditablePartial.from_call(AnnotatedItem, label=label, item="") + elif isinstance(element, pyparsing.Opt): + ret = EditablePartial.from_call(railroad.Optional, item="") + elif isinstance(element, pyparsing.OneOrMore): + ret = EditablePartial.from_call(railroad.OneOrMore, item="") + elif isinstance(element, pyparsing.ZeroOrMore): + ret = EditablePartial.from_call(railroad.ZeroOrMore, item="") + elif isinstance(element, pyparsing.Group): + ret = EditablePartial.from_call( + railroad.Group, item=None, label=element_results_name + ) + elif isinstance(element, pyparsing.Empty) and not element.customName: + # Skip unnamed "Empty" elements + ret = None + elif isinstance(element, pyparsing.ParseElementEnhance): + ret = EditablePartial.from_call(railroad.Sequence, items=[]) + elif len(exprs) > 0 and not element_results_name: + ret = EditablePartial.from_call(railroad.Group, item="", label=name) + elif len(exprs) > 0: + ret = EditablePartial.from_call(railroad.Sequence, items=[]) + else: + terminal = EditablePartial.from_call(railroad.Terminal, element.defaultName) + ret = terminal + + if ret is None: + return + + # Indicate this element's position in the tree so we can extract it if necessary + lookup[el_id] = ElementState( + element=element, + converted=ret, + parent=parent, + parent_index=index, + number=lookup.generate_index(), + ) + if element.customName: + lookup[el_id].mark_for_extraction(el_id, lookup, element.customName) + + i = 0 + for expr in exprs: + # Add a placeholder index in case we have to extract the child before we even add it to the parent + if "items" in ret.kwargs: + ret.kwargs["items"].insert(i, None) + + item = _to_diagram_element( + expr, + parent=ret, + lookup=lookup, + vertical=vertical, + index=i, + show_results_names=show_results_names, + show_groups=show_groups, + ) + + # Some elements don't need to be shown in the diagram + if item is not None: + if "item" in ret.kwargs: + ret.kwargs["item"] = item + elif "items" in ret.kwargs: + # If we've already extracted the child, don't touch this index, since it's occupied by a nonterminal + ret.kwargs["items"][i] = item + i += 1 + elif "items" in ret.kwargs: + # If we're supposed to skip this element, remove it from the parent + del ret.kwargs["items"][i] + + # If all this items children are none, skip this item + if ret and ( + ("items" in ret.kwargs and len(ret.kwargs["items"]) == 0) + or ("item" in ret.kwargs and ret.kwargs["item"] is None) + ): + ret = EditablePartial.from_call(railroad.Terminal, name) + + # Mark this element as "complete", ie it has all of its children + if el_id in lookup: + lookup[el_id].complete = True + + if el_id in lookup and lookup[el_id].extract and lookup[el_id].complete: + lookup.extract_into_diagram(el_id) + if ret is not None: + ret = EditablePartial.from_call( + railroad.NonTerminal, text=lookup.diagrams[el_id].kwargs["name"] + ) + + return ret diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/exceptions.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/exceptions.py new file mode 100644 index 00000000..12219f12 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/exceptions.py @@ -0,0 +1,299 @@ +# exceptions.py + +import re +import sys +import typing + +from .util import ( + col, + line, + lineno, + _collapse_string_to_ranges, + replaced_by_pep8, +) +from .unicode import pyparsing_unicode as ppu + + +class ExceptionWordUnicode(ppu.Latin1, ppu.LatinA, ppu.LatinB, ppu.Greek, ppu.Cyrillic): + pass + + +_extract_alphanums = _collapse_string_to_ranges(ExceptionWordUnicode.alphanums) +_exception_word_extractor = re.compile("([" + _extract_alphanums + "]{1,16})|.") + + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + + loc: int + msg: str + pstr: str + parser_element: typing.Any # "ParserElement" + args: typing.Tuple[str, int, typing.Optional[str]] + + __slots__ = ( + "loc", + "msg", + "pstr", + "parser_element", + "args", + ) + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( + self, + pstr: str, + loc: int = 0, + msg: typing.Optional[str] = None, + elem=None, + ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parser_element = elem + self.args = (pstr, loc, msg) + + @staticmethod + def explain_exception(exc, depth=16): + """ + Method to take an exception and translate the Python internal traceback into a list + of the pyparsing expressions that caused the exception to be raised. + + Parameters: + + - exc - exception raised during parsing (need not be a ParseException, in support + of Python exceptions that might be raised in a parse action) + - depth (default=16) - number of levels back in the stack trace to list expression + and function names; if None, the full stack trace names will be listed; if 0, only + the failing input line, marker, and exception string will be shown + + Returns a multi-line string listing the ParserElements and/or function names in the + exception's stack trace. + """ + import inspect + from .core import ParserElement + + if depth is None: + depth = sys.getrecursionlimit() + ret = [] + if isinstance(exc, ParseBaseException): + ret.append(exc.line) + ret.append(" " * (exc.column - 1) + "^") + ret.append(f"{type(exc).__name__}: {exc}") + + if depth > 0: + callers = inspect.getinnerframes(exc.__traceback__, context=depth) + seen = set() + for i, ff in enumerate(callers[-depth:]): + frm = ff[0] + + f_self = frm.f_locals.get("self", None) + if isinstance(f_self, ParserElement): + if not frm.f_code.co_name.startswith( + ("parseImpl", "_parseNoCache") + ): + continue + if id(f_self) in seen: + continue + seen.add(id(f_self)) + + self_type = type(f_self) + ret.append( + f"{self_type.__module__}.{self_type.__name__} - {f_self}" + ) + + elif f_self is not None: + self_type = type(f_self) + ret.append(f"{self_type.__module__}.{self_type.__name__}") + + else: + code = frm.f_code + if code.co_name in ("wrapper", "<module>"): + continue + + ret.append(code.co_name) + + depth -= 1 + if not depth: + break + + return "\n".join(ret) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parser_element) + + @property + def line(self) -> str: + """ + Return the line of text where the exception occurred. + """ + return line(self.loc, self.pstr) + + @property + def lineno(self) -> int: + """ + Return the 1-based line number of text where the exception occurred. + """ + return lineno(self.loc, self.pstr) + + @property + def col(self) -> int: + """ + Return the 1-based column on the line of text where the exception occurred. + """ + return col(self.loc, self.pstr) + + @property + def column(self) -> int: + """ + Return the 1-based column on the line of text where the exception occurred. + """ + return col(self.loc, self.pstr) + + # pre-PEP8 compatibility + @property + def parserElement(self): + return self.parser_element + + @parserElement.setter + def parserElement(self, elem): + self.parser_element = elem + + def __str__(self) -> str: + if self.pstr: + if self.loc >= len(self.pstr): + foundstr = ", found end of text" + else: + # pull out next word at error location + found_match = _exception_word_extractor.match(self.pstr, self.loc) + if found_match is not None: + found = found_match.group(0) + else: + found = self.pstr[self.loc : self.loc + 1] + foundstr = (", found %r" % found).replace(r"\\", "\\") + else: + foundstr = "" + return f"{self.msg}{foundstr} (at char {self.loc}), (line:{self.lineno}, col:{self.column})" + + def __repr__(self): + return str(self) + + def mark_input_line( + self, marker_string: typing.Optional[str] = None, *, markerString: str = ">!<" + ) -> str: + """ + Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + markerString = marker_string if marker_string is not None else markerString + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join( + (line_str[:line_column], markerString, line_str[line_column:]) + ) + return line_str.strip() + + def explain(self, depth=16) -> str: + """ + Method to translate the Python internal traceback into a list + of the pyparsing expressions that caused the exception to be raised. + + Parameters: + + - depth (default=16) - number of levels back in the stack trace to list expression + and function names; if None, the full stack trace names will be listed; if 0, only + the failing input line, marker, and exception string will be shown + + Returns a multi-line string listing the ParserElements and/or function names in the + exception's stack trace. + + Example:: + + expr = pp.Word(pp.nums) * 3 + try: + expr.parse_string("123 456 A789") + except pp.ParseException as pe: + print(pe.explain(depth=0)) + + prints:: + + 123 456 A789 + ^ + ParseException: Expected W:(0-9), found 'A' (at char 8), (line:1, col:9) + + Note: the diagnostic output will include string representations of the expressions + that failed to parse. These representations will be more helpful if you use `set_name` to + give identifiable names to your expressions. Otherwise they will use the default string + forms, which may be cryptic to read. + + Note: pyparsing's default truncation of exception tracebacks may also truncate the + stack of expressions that are displayed in the ``explain`` output. To get the full listing + of parser expressions, you may have to set ``ParserElement.verbose_stacktrace = True`` + """ + return self.explain_exception(self, depth) + + # fmt: off + @replaced_by_pep8(mark_input_line) + def markInputline(self): ... + # fmt: on + + +class ParseException(ParseBaseException): + """ + Exception thrown when a parse expression doesn't match the input string + + Example:: + + try: + Word(nums).set_name("integer").parse_string("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.column)) + + prints:: + + Expected integer (at char 0), (line:1, col:1) + column: 1 + + """ + + +class ParseFatalException(ParseBaseException): + """ + User-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately + """ + + +class ParseSyntaxException(ParseFatalException): + """ + Just like :class:`ParseFatalException`, but thrown internally + when an :class:`ErrorStop<And._ErrorStop>` ('-' operator) indicates + that parsing is to stop immediately because an unbacktrackable + syntax error has been found. + """ + + +class RecursiveGrammarException(Exception): + """ + Exception thrown by :class:`ParserElement.validate` if the + grammar could be left-recursive; parser may need to enable + left recursion using :class:`ParserElement.enable_left_recursion<ParserElement.enable_left_recursion>` + """ + + def __init__(self, parseElementList): + self.parseElementTrace = parseElementList + + def __str__(self) -> str: + return f"RecursiveGrammarException: {self.parseElementTrace}" diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/helpers.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/helpers.py new file mode 100644 index 00000000..018f0d6a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/helpers.py @@ -0,0 +1,1100 @@ +# helpers.py +import html.entities +import re +import sys +import typing + +from . import __diag__ +from .core import * +from .util import ( + _bslash, + _flatten, + _escape_regex_range_chars, + replaced_by_pep8, +) + + +# +# global helpers +# +def counted_array( + expr: ParserElement, + int_expr: typing.Optional[ParserElement] = None, + *, + intExpr: typing.Optional[ParserElement] = None, +) -> ParserElement: + """Helper to define a counted list of expressions. + + This helper defines a pattern of the form:: + + integer expr expr expr... + + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the + leading count token is suppressed. + + If ``int_expr`` is specified, it should be a pyparsing expression + that produces an integer value. + + Example:: + + counted_array(Word(alphas)).parse_string('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binary_constant = Word('01').set_parse_action(lambda t: int(t[0], 2)) + counted_array(Word(alphas), int_expr=binary_constant).parse_string('10 ab cd ef') # -> ['ab', 'cd'] + + # if other fields must be parsed after the count but before the + # list items, give the fields results names and they will + # be preserved in the returned ParseResults: + count_with_metadata = integer + Word(alphas)("type") + typed_array = counted_array(Word(alphanums), int_expr=count_with_metadata)("items") + result = typed_array.parse_string("3 bool True True False") + print(result.dump()) + + # prints + # ['True', 'True', 'False'] + # - items: ['True', 'True', 'False'] + # - type: 'bool' + """ + intExpr = intExpr or int_expr + array_expr = Forward() + + def count_field_parse_action(s, l, t): + nonlocal array_expr + n = t[0] + array_expr <<= (expr * n) if n else Empty() + # clear list contents, but keep any named results + del t[:] + + if intExpr is None: + intExpr = Word(nums).set_parse_action(lambda t: int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.set_name("arrayLen") + intExpr.add_parse_action(count_field_parse_action, call_during_try=True) + return (intExpr + array_expr).set_name("(len) " + str(expr) + "...") + + +def match_previous_literal(expr: ParserElement) -> ParserElement: + """Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks for + a 'repeat' of a previous expression. For example:: + + first = Word(nums) + second = match_previous_literal(first) + match_expr = first + ":" + second + + will match ``"1:1"``, but not ``"1:2"``. Because this + matches a previous literal, will also match the leading + ``"1:1"`` in ``"1:10"``. If this is not desired, use + :class:`match_previous_expr`. Do *not* use with packrat parsing + enabled. + """ + rep = Forward() + + def copy_token_to_repeater(s, l, t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.as_list()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + + expr.add_parse_action(copy_token_to_repeater, callDuringTry=True) + rep.set_name("(prev) " + str(expr)) + return rep + + +def match_previous_expr(expr: ParserElement) -> ParserElement: + """Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks for + a 'repeat' of a previous expression. For example:: + + first = Word(nums) + second = match_previous_expr(first) + match_expr = first + ":" + second + + will match ``"1:1"``, but not ``"1:2"``. Because this + matches by expressions, will *not* match the leading ``"1:1"`` + in ``"1:10"``; the expressions are evaluated first, and then + compared, so ``"1"`` is compared with ``"10"``. Do *not* use + with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + + def copy_token_to_repeater(s, l, t): + matchTokens = _flatten(t.as_list()) + + def must_match_these_tokens(s, l, t): + theseTokens = _flatten(t.as_list()) + if theseTokens != matchTokens: + raise ParseException( + s, l, f"Expected {matchTokens}, found{theseTokens}" + ) + + rep.set_parse_action(must_match_these_tokens, callDuringTry=True) + + expr.add_parse_action(copy_token_to_repeater, callDuringTry=True) + rep.set_name("(prev) " + str(expr)) + return rep + + +def one_of( + strs: Union[typing.Iterable[str], str], + caseless: bool = False, + use_regex: bool = True, + as_keyword: bool = False, + *, + useRegex: bool = True, + asKeyword: bool = False, +) -> ParserElement: + """Helper to quickly define a set of alternative :class:`Literal` s, + and makes sure to do longest-first testing when there is a conflict, + regardless of the input order, but returns + a :class:`MatchFirst` for best performance. + + Parameters: + + - ``strs`` - a string of space-delimited literals, or a collection of + string literals + - ``caseless`` - treat all literals as caseless - (default= ``False``) + - ``use_regex`` - as an optimization, will + generate a :class:`Regex` object; otherwise, will generate + a :class:`MatchFirst` object (if ``caseless=True`` or ``as_keyword=True``, or if + creating a :class:`Regex` raises an exception) - (default= ``True``) + - ``as_keyword`` - enforce :class:`Keyword`-style matching on the + generated expressions - (default= ``False``) + - ``asKeyword`` and ``useRegex`` are retained for pre-PEP8 compatibility, + but will be removed in a future release + + Example:: + + comp_oper = one_of("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.search_string("B = 12 AA=23 B<=AA AA>12")) + + prints:: + + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + asKeyword = asKeyword or as_keyword + useRegex = useRegex and use_regex + + if ( + isinstance(caseless, str_type) + and __diag__.warn_on_multiple_string_args_to_oneof + ): + warnings.warn( + "More than one string argument passed to one_of, pass" + " choices as a list or space-delimited string", + stacklevel=2, + ) + + if caseless: + isequal = lambda a, b: a.upper() == b.upper() + masks = lambda a, b: b.upper().startswith(a.upper()) + parseElementClass = CaselessKeyword if asKeyword else CaselessLiteral + else: + isequal = lambda a, b: a == b + masks = lambda a, b: b.startswith(a) + parseElementClass = Keyword if asKeyword else Literal + + symbols: List[str] = [] + if isinstance(strs, str_type): + strs = typing.cast(str, strs) + symbols = strs.split() + elif isinstance(strs, Iterable): + symbols = list(strs) + else: + raise TypeError("Invalid argument to one_of, expected string or iterable") + if not symbols: + return NoMatch() + + # reorder given symbols to take care to avoid masking longer choices with shorter ones + # (but only if the given symbols are not just single characters) + if any(len(sym) > 1 for sym in symbols): + i = 0 + while i < len(symbols) - 1: + cur = symbols[i] + for j, other in enumerate(symbols[i + 1 :]): + if isequal(other, cur): + del symbols[i + j + 1] + break + elif masks(cur, other): + del symbols[i + j + 1] + symbols.insert(i, other) + break + else: + i += 1 + + if useRegex: + re_flags: int = re.IGNORECASE if caseless else 0 + + try: + if all(len(sym) == 1 for sym in symbols): + # symbols are just single characters, create range regex pattern + patt = f"[{''.join(_escape_regex_range_chars(sym) for sym in symbols)}]" + else: + patt = "|".join(re.escape(sym) for sym in symbols) + + # wrap with \b word break markers if defining as keywords + if asKeyword: + patt = rf"\b(?:{patt})\b" + + ret = Regex(patt, flags=re_flags).set_name(" | ".join(symbols)) + + if caseless: + # add parse action to return symbols as specified, not in random + # casing as found in input string + symbol_map = {sym.lower(): sym for sym in symbols} + ret.add_parse_action(lambda s, l, t: symbol_map[t[0].lower()]) + + return ret + + except re.error: + warnings.warn( + "Exception creating Regex for one_of, building MatchFirst", stacklevel=2 + ) + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).set_name( + " | ".join(symbols) + ) + + +def dict_of(key: ParserElement, value: ParserElement) -> ParserElement: + """Helper to easily and clearly define a dictionary by specifying + the respective patterns for the key and value. Takes care of + defining the :class:`Dict`, :class:`ZeroOrMore`, and + :class:`Group` tokens in the proper order. The key pattern + can include delimiting markers or punctuation, as long as they are + suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the :class:`Dict` results + can include named token fields. + + Example:: + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join)) + print(attr_expr[1, ...].parse_string(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join) + + # similar to Dict, but simpler call format + result = dict_of(attr_label, attr_value).parse_string(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.as_dict()) + + prints:: + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: 'light blue' + - posn: 'upper left' + - shape: 'SQUARE' + - texture: 'burlap' + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict(OneOrMore(Group(key + value))) + + +def original_text_for( + expr: ParserElement, as_string: bool = True, *, asString: bool = True +) -> ParserElement: + """Helper to return the original, untokenized text for a given + expression. Useful to restore the parsed fields of an HTML start + tag into the raw tag text itself, or to revert separate tokens with + intervening whitespace back to the original matching input text. By + default, returns a string containing the original parsed text. + + If the optional ``as_string`` argument is passed as + ``False``, then the return value is + a :class:`ParseResults` containing any results names that + were originally matched, and a single token containing the original + matched text from the input string. So if the expression passed to + :class:`original_text_for` contains expressions with defined + results names, you must set ``as_string`` to ``False`` if you + want to preserve those results name values. + + The ``asString`` pre-PEP8 argument is retained for compatibility, + but will be removed in a future release. + + Example:: + + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b", "i"): + opener, closer = make_html_tags(tag) + patt = original_text_for(opener + ... + closer) + print(patt.search_string(src)[0]) + + prints:: + + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + asString = asString and as_string + + locMarker = Empty().set_parse_action(lambda s, loc, t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s, l, t: s[t._original_start : t._original_end] + else: + + def extractText(s, l, t): + t[:] = [s[t.pop("_original_start") : t.pop("_original_end")]] + + matchExpr.set_parse_action(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + matchExpr.suppress_warning(Diagnostics.warn_ungrouped_named_tokens_in_collection) + return matchExpr + + +def ungroup(expr: ParserElement) -> ParserElement: + """Helper to undo pyparsing's default grouping of And expressions, + even if all but one are non-empty. + """ + return TokenConverter(expr).add_parse_action(lambda t: t[0]) + + +def locatedExpr(expr: ParserElement) -> ParserElement: + """ + (DEPRECATED - future code should use the :class:`Located` class) + Helper to decorate a returned token with its starting and ending + locations in the input string. + + This helper adds the following results names: + + - ``locn_start`` - location where matched expression begins + - ``locn_end`` - location where matched expression ends + - ``value`` - the actual parsed results + + Be careful if the input text contains ``<TAB>`` characters, you + may want to call :class:`ParserElement.parse_with_tabs` + + Example:: + + wd = Word(alphas) + for match in locatedExpr(wd).search_string("ljsdf123lksdjjf123lkkjj1222"): + print(match) + + prints:: + + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().set_parse_action(lambda ss, ll, tt: ll) + return Group( + locator("locn_start") + + expr("value") + + locator.copy().leaveWhitespace()("locn_end") + ) + + +def nested_expr( + opener: Union[str, ParserElement] = "(", + closer: Union[str, ParserElement] = ")", + content: typing.Optional[ParserElement] = None, + ignore_expr: ParserElement = quoted_string(), + *, + ignoreExpr: ParserElement = quoted_string(), +) -> ParserElement: + """Helper method for defining nested lists enclosed in opening and + closing delimiters (``"("`` and ``")"`` are the default). + + Parameters: + + - ``opener`` - opening character for a nested list + (default= ``"("``); can also be a pyparsing expression + - ``closer`` - closing character for a nested list + (default= ``")"``); can also be a pyparsing expression + - ``content`` - expression for items within the nested lists + (default= ``None``) + - ``ignore_expr`` - expression for ignoring opening and closing delimiters + (default= :class:`quoted_string`) + - ``ignoreExpr`` - this pre-PEP8 argument is retained for compatibility + but will be removed in a future release + + If an expression is not provided for the content argument, the + nested expression will capture all whitespace-delimited content + between delimiters as a list of separate values. + + Use the ``ignore_expr`` argument to define expressions that may + contain opening or closing characters that should not be treated as + opening or closing characters for nesting, such as quoted_string or + a comment expression. Specify multiple expressions using an + :class:`Or` or :class:`MatchFirst`. The default is + :class:`quoted_string`, but if no expressions are to be ignored, then + pass ``None`` for this argument. + + Example:: + + data_type = one_of("void int short long char float double") + decl_data_type = Combine(data_type + Opt(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR, RPAR = map(Suppress, "()") + + code_body = nested_expr('{', '}', ignore_expr=(quoted_string | c_style_comment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Opt(DelimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(c_style_comment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.search_string(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + + prints:: + + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if ignoreExpr != ignore_expr: + ignoreExpr = ignore_expr if ignoreExpr == quoted_string() else ignoreExpr + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener, str_type) and isinstance(closer, str_type): + opener = typing.cast(str, opener) + closer = typing.cast(str, closer) + if len(opener) == 1 and len(closer) == 1: + if ignoreExpr is not None: + content = Combine( + OneOrMore( + ~ignoreExpr + + CharsNotIn( + opener + closer + ParserElement.DEFAULT_WHITE_CHARS, + exact=1, + ) + ) + ).set_parse_action(lambda t: t[0].strip()) + else: + content = empty.copy() + CharsNotIn( + opener + closer + ParserElement.DEFAULT_WHITE_CHARS + ).set_parse_action(lambda t: t[0].strip()) + else: + if ignoreExpr is not None: + content = Combine( + OneOrMore( + ~ignoreExpr + + ~Literal(opener) + + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS, exact=1) + ) + ).set_parse_action(lambda t: t[0].strip()) + else: + content = Combine( + OneOrMore( + ~Literal(opener) + + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS, exact=1) + ) + ).set_parse_action(lambda t: t[0].strip()) + else: + raise ValueError( + "opening and closing arguments must be strings if no content expression is given" + ) + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( + Suppress(opener) + ZeroOrMore(ignoreExpr | ret | content) + Suppress(closer) + ) + else: + ret <<= Group(Suppress(opener) + ZeroOrMore(ret | content) + Suppress(closer)) + ret.set_name("nested %s%s expression" % (opener, closer)) + return ret + + +def _makeTags(tagStr, xml, suppress_LT=Suppress("<"), suppress_GT=Suppress(">")): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr, str_type): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas, alphanums + "_-:") + if xml: + tagAttrValue = dbl_quoted_string.copy().set_parse_action(remove_quotes) + openTag = ( + suppress_LT + + tagStr("tag") + + Dict(ZeroOrMore(Group(tagAttrName + Suppress("=") + tagAttrValue))) + + Opt("/", default=[False])("empty").set_parse_action( + lambda s, l, t: t[0] == "/" + ) + + suppress_GT + ) + else: + tagAttrValue = quoted_string.copy().set_parse_action(remove_quotes) | Word( + printables, exclude_chars=">" + ) + openTag = ( + suppress_LT + + tagStr("tag") + + Dict( + ZeroOrMore( + Group( + tagAttrName.set_parse_action(lambda t: t[0].lower()) + + Opt(Suppress("=") + tagAttrValue) + ) + ) + ) + + Opt("/", default=[False])("empty").set_parse_action( + lambda s, l, t: t[0] == "/" + ) + + suppress_GT + ) + closeTag = Combine(Literal("</") + tagStr + ">", adjacent=False) + + openTag.set_name("<%s>" % resname) + # add start<tagname> results name in parse action now that ungrouped names are not reported at two levels + openTag.add_parse_action( + lambda t: t.__setitem__( + "start" + "".join(resname.replace(":", " ").title().split()), t.copy() + ) + ) + closeTag = closeTag( + "end" + "".join(resname.replace(":", " ").title().split()) + ).set_name("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + openTag.tag_body = SkipTo(closeTag()) + return openTag, closeTag + + +def make_html_tags( + tag_str: Union[str, ParserElement] +) -> Tuple[ParserElement, ParserElement]: + """Helper to construct opening and closing tag expressions for HTML, + given a tag name. Matches tags in either upper or lower case, + attributes with namespaces and with quoted or unquoted values. + + Example:: + + text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' + # make_html_tags returns pyparsing expressions for the opening and + # closing tags as a 2-tuple + a, a_end = make_html_tags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.search_string(text): + # attributes in the <A> tag (like "href" shown here) are + # also accessible as named results + print(link.link_text, '->', link.href) + + prints:: + + pyparsing -> https://github.com/pyparsing/pyparsing/wiki + """ + return _makeTags(tag_str, False) + + +def make_xml_tags( + tag_str: Union[str, ParserElement] +) -> Tuple[ParserElement, ParserElement]: + """Helper to construct opening and closing tag expressions for XML, + given a tag name. Matches tags only in the given upper/lower case. + + Example: similar to :class:`make_html_tags` + """ + return _makeTags(tag_str, True) + + +any_open_tag: ParserElement +any_close_tag: ParserElement +any_open_tag, any_close_tag = make_html_tags( + Word(alphas, alphanums + "_:").set_name("any tag") +) + +_htmlEntityMap = {k.rstrip(";"): v for k, v in html.entities.html5.items()} +common_html_entity = Regex("&(?P<entity>" + "|".join(_htmlEntityMap) + ");").set_name( + "common HTML entity" +) + + +def replace_html_entity(s, l, t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + + +class OpAssoc(Enum): + """Enumeration of operator associativity + - used in constructing InfixNotationOperatorSpec for :class:`infix_notation`""" + + LEFT = 1 + RIGHT = 2 + + +InfixNotationOperatorArgType = Union[ + ParserElement, str, Tuple[Union[ParserElement, str], Union[ParserElement, str]] +] +InfixNotationOperatorSpec = Union[ + Tuple[ + InfixNotationOperatorArgType, + int, + OpAssoc, + typing.Optional[ParseAction], + ], + Tuple[ + InfixNotationOperatorArgType, + int, + OpAssoc, + ], +] + + +def infix_notation( + base_expr: ParserElement, + op_list: List[InfixNotationOperatorSpec], + lpar: Union[str, ParserElement] = Suppress("("), + rpar: Union[str, ParserElement] = Suppress(")"), +) -> ParserElement: + """Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary + or binary, left- or right-associative. Parse actions can also be + attached to operator expressions. The generated parser will also + recognize the use of parentheses to override operator precedences + (see example below). + + Note: if you define a deep operator list, you may see performance + issues when using infix_notation. See + :class:`ParserElement.enable_packrat` for a mechanism to potentially + improve your parser performance. + + Parameters: + + - ``base_expr`` - expression representing the most basic operand to + be used in the expression + - ``op_list`` - list of tuples, one for each operator precedence level + in the expression grammar; each tuple is of the form ``(op_expr, + num_operands, right_left_assoc, (optional)parse_action)``, where: + + - ``op_expr`` is the pyparsing expression for the operator; may also + be a string, which will be converted to a Literal; if ``num_operands`` + is 3, ``op_expr`` is a tuple of two expressions, for the two + operators separating the 3 terms + - ``num_operands`` is the number of terms for this operator (must be 1, + 2, or 3) + - ``right_left_assoc`` is the indicator whether the operator is right + or left associative, using the pyparsing-defined constants + ``OpAssoc.RIGHT`` and ``OpAssoc.LEFT``. + - ``parse_action`` is the parse action to be associated with + expressions matching this operator expression (the parse action + tuple member may be omitted); if the parse action is passed + a tuple or list of functions, this is equivalent to calling + ``set_parse_action(*fn)`` + (:class:`ParserElement.set_parse_action`) + - ``lpar`` - expression for matching left-parentheses; if passed as a + str, then will be parsed as ``Suppress(lpar)``. If lpar is passed as + an expression (such as ``Literal('(')``), then it will be kept in + the parsed results, and grouped with them. (default= ``Suppress('(')``) + - ``rpar`` - expression for matching right-parentheses; if passed as a + str, then will be parsed as ``Suppress(rpar)``. If rpar is passed as + an expression (such as ``Literal(')')``), then it will be kept in + the parsed results, and grouped with them. (default= ``Suppress(')')``) + + Example:: + + # simple example of four-function arithmetic with ints and + # variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infix_notation(integer | varname, + [ + ('-', 1, OpAssoc.RIGHT), + (one_of('* /'), 2, OpAssoc.LEFT), + (one_of('+ -'), 2, OpAssoc.LEFT), + ]) + + arith_expr.run_tests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', full_dump=False) + + prints:: + + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + (5+x)*y + [[[5, '+', 'x'], '*', 'y']] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + + # captive version of FollowedBy that does not do parse actions or capture results names + class _FB(FollowedBy): + def parseImpl(self, instring, loc, doActions=True): + self.expr.try_parse(instring, loc) + return loc, [] + + _FB.__name__ = "FollowedBy>" + + ret = Forward() + if isinstance(lpar, str): + lpar = Suppress(lpar) + if isinstance(rpar, str): + rpar = Suppress(rpar) + + # if lpar and rpar are not suppressed, wrap in group + if not (isinstance(rpar, Suppress) and isinstance(rpar, Suppress)): + lastExpr = base_expr | Group(lpar + ret + rpar) + else: + lastExpr = base_expr | (lpar + ret + rpar) + + arity: int + rightLeftAssoc: opAssoc + pa: typing.Optional[ParseAction] + opExpr1: ParserElement + opExpr2: ParserElement + for i, operDef in enumerate(op_list): + opExpr, arity, rightLeftAssoc, pa = (operDef + (None,))[:4] # type: ignore[assignment] + if isinstance(opExpr, str_type): + opExpr = ParserElement._literalStringClass(opExpr) + opExpr = typing.cast(ParserElement, opExpr) + if arity == 3: + if not isinstance(opExpr, (tuple, list)) or len(opExpr) != 2: + raise ValueError( + "if numterms=3, opExpr must be a tuple or list of two expressions" + ) + opExpr1, opExpr2 = opExpr + term_name = f"{opExpr1}{opExpr2} term" + else: + term_name = f"{opExpr} term" + + if not 1 <= arity <= 3: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + + if rightLeftAssoc not in (OpAssoc.LEFT, OpAssoc.RIGHT): + raise ValueError("operator must indicate right or left associativity") + + thisExpr: ParserElement = Forward().set_name(term_name) + thisExpr = typing.cast(Forward, thisExpr) + if rightLeftAssoc is OpAssoc.LEFT: + if arity == 1: + matchExpr = _FB(lastExpr + opExpr) + Group(lastExpr + opExpr[1, ...]) + elif arity == 2: + if opExpr is not None: + matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group( + lastExpr + (opExpr + lastExpr)[1, ...] + ) + else: + matchExpr = _FB(lastExpr + lastExpr) + Group(lastExpr[2, ...]) + elif arity == 3: + matchExpr = _FB( + lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr + ) + Group(lastExpr + OneOrMore(opExpr1 + lastExpr + opExpr2 + lastExpr)) + elif rightLeftAssoc is OpAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Opt): + opExpr = Opt(opExpr) + matchExpr = _FB(opExpr.expr + thisExpr) + Group(opExpr + thisExpr) + elif arity == 2: + if opExpr is not None: + matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group( + lastExpr + (opExpr + thisExpr)[1, ...] + ) + else: + matchExpr = _FB(lastExpr + thisExpr) + Group( + lastExpr + thisExpr[1, ...] + ) + elif arity == 3: + matchExpr = _FB( + lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr + ) + Group(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.set_parse_action(*pa) + else: + matchExpr.set_parse_action(pa) + thisExpr <<= (matchExpr | lastExpr).setName(term_name) + lastExpr = thisExpr + ret <<= lastExpr + return ret + + +def indentedBlock(blockStatementExpr, indentStack, indent=True, backup_stacks=[]): + """ + (DEPRECATED - use :class:`IndentedBlock` class instead) + Helper method for defining space-delimited indentation blocks, + such as those used to define block statements in Python source code. + + Parameters: + + - ``blockStatementExpr`` - expression defining syntax of statement that + is repeated within the indented block + - ``indentStack`` - list created by caller to manage indentation stack + (multiple ``statementWithIndentedBlock`` expressions within a single + grammar should share a common ``indentStack``) + - ``indent`` - boolean indicating whether block must be indented beyond + the current level; set to ``False`` for block of left-most statements + (default= ``True``) + + A valid block must contain at least one ``blockStatement``. + + (Note that indentedBlock uses internal parse actions which make it + incompatible with packrat parsing.) + + Example:: + + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group("(" + Opt(delimitedList(identifier)) + ")") + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group(funcDecl + func_body) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Opt(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << (funcDef | assignment | identifier) + + module_body = stmt[1, ...] + + parseTree = module_body.parseString(data) + parseTree.pprint() + + prints:: + + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + backup_stacks.append(indentStack[:]) + + def reset_stack(): + indentStack[:] = backup_stacks[-1] + + def checkPeerIndent(s, l, t): + if l >= len(s): + return + curCol = col(l, s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseException(s, l, "illegal nesting") + raise ParseException(s, l, "not a peer entry") + + def checkSubIndent(s, l, t): + curCol = col(l, s) + if curCol > indentStack[-1]: + indentStack.append(curCol) + else: + raise ParseException(s, l, "not a subentry") + + def checkUnindent(s, l, t): + if l >= len(s): + return + curCol = col(l, s) + if not (indentStack and curCol in indentStack): + raise ParseException(s, l, "not an unindent") + if curCol < indentStack[-1]: + indentStack.pop() + + NL = OneOrMore(LineEnd().set_whitespace_chars("\t ").suppress()) + INDENT = (Empty() + Empty().set_parse_action(checkSubIndent)).set_name("INDENT") + PEER = Empty().set_parse_action(checkPeerIndent).set_name("") + UNDENT = Empty().set_parse_action(checkUnindent).set_name("UNINDENT") + if indent: + smExpr = Group( + Opt(NL) + + INDENT + + OneOrMore(PEER + Group(blockStatementExpr) + Opt(NL)) + + UNDENT + ) + else: + smExpr = Group( + Opt(NL) + + OneOrMore(PEER + Group(blockStatementExpr) + Opt(NL)) + + Opt(UNDENT) + ) + + # add a parse action to remove backup_stack from list of backups + smExpr.add_parse_action( + lambda: backup_stacks.pop(-1) and None if backup_stacks else None + ) + smExpr.set_fail_action(lambda a, b, c, d: reset_stack()) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.set_name("indented block") + + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +c_style_comment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + "*/").set_name( + "C style comment" +) +"Comment of the form ``/* ... */``" + +html_comment = Regex(r"<!--[\s\S]*?-->").set_name("HTML comment") +"Comment of the form ``<!-- ... -->``" + +rest_of_line = Regex(r".*").leave_whitespace().set_name("rest of line") +dbl_slash_comment = Regex(r"//(?:\\\n|[^\n])*").set_name("// comment") +"Comment of the form ``// ... (to end of line)``" + +cpp_style_comment = Combine( + Regex(r"/\*(?:[^*]|\*(?!/))*") + "*/" | dbl_slash_comment +).set_name("C++ style comment") +"Comment of either form :class:`c_style_comment` or :class:`dbl_slash_comment`" + +java_style_comment = cpp_style_comment +"Same as :class:`cpp_style_comment`" + +python_style_comment = Regex(r"#.*").set_name("Python style comment") +"Comment of the form ``# ... (to end of line)``" + + +# build list of built-in expressions, for future reference if a global default value +# gets updated +_builtin_exprs: List[ParserElement] = [ + v for v in vars().values() if isinstance(v, ParserElement) +] + + +# compatibility function, superseded by DelimitedList class +def delimited_list( + expr: Union[str, ParserElement], + delim: Union[str, ParserElement] = ",", + combine: bool = False, + min: typing.Optional[int] = None, + max: typing.Optional[int] = None, + *, + allow_trailing_delim: bool = False, +) -> ParserElement: + """(DEPRECATED - use :class:`DelimitedList` class)""" + return DelimitedList( + expr, delim, combine, min, max, allow_trailing_delim=allow_trailing_delim + ) + + +# pre-PEP8 compatible names +# fmt: off +opAssoc = OpAssoc +anyOpenTag = any_open_tag +anyCloseTag = any_close_tag +commonHTMLEntity = common_html_entity +cStyleComment = c_style_comment +htmlComment = html_comment +restOfLine = rest_of_line +dblSlashComment = dbl_slash_comment +cppStyleComment = cpp_style_comment +javaStyleComment = java_style_comment +pythonStyleComment = python_style_comment + +@replaced_by_pep8(DelimitedList) +def delimitedList(): ... + +@replaced_by_pep8(DelimitedList) +def delimited_list(): ... + +@replaced_by_pep8(counted_array) +def countedArray(): ... + +@replaced_by_pep8(match_previous_literal) +def matchPreviousLiteral(): ... + +@replaced_by_pep8(match_previous_expr) +def matchPreviousExpr(): ... + +@replaced_by_pep8(one_of) +def oneOf(): ... + +@replaced_by_pep8(dict_of) +def dictOf(): ... + +@replaced_by_pep8(original_text_for) +def originalTextFor(): ... + +@replaced_by_pep8(nested_expr) +def nestedExpr(): ... + +@replaced_by_pep8(make_html_tags) +def makeHTMLTags(): ... + +@replaced_by_pep8(make_xml_tags) +def makeXMLTags(): ... + +@replaced_by_pep8(replace_html_entity) +def replaceHTMLEntity(): ... + +@replaced_by_pep8(infix_notation) +def infixNotation(): ... +# fmt: on diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/py.typed b/dbdpy-env/lib/python3.9/site-packages/pyparsing/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/results.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/results.py new file mode 100644 index 00000000..03130497 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/results.py @@ -0,0 +1,796 @@ +# results.py +from collections.abc import ( + MutableMapping, + Mapping, + MutableSequence, + Iterator, + Sequence, + Container, +) +import pprint +from typing import Tuple, Any, Dict, Set, List + +str_type: Tuple[type, ...] = (str, bytes) +_generator_type = type((_ for _ in ())) + + +class _ParseResultsWithOffset: + tup: Tuple["ParseResults", int] + __slots__ = ["tup"] + + def __init__(self, p1: "ParseResults", p2: int): + self.tup: Tuple[ParseResults, int] = (p1, p2) + + def __getitem__(self, i): + return self.tup[i] + + def __getstate__(self): + return self.tup + + def __setstate__(self, *args): + self.tup = args[0] + + +class ParseResults: + """Structured parse results, to provide multiple means of access to + the parsed data: + + - as a list (``len(results)``) + - by list index (``results[0], results[1]``, etc.) + - by attribute (``results.<results_name>`` - see :class:`ParserElement.set_results_name`) + + Example:: + + integer = Word(nums) + date_str = (integer.set_results_name("year") + '/' + + integer.set_results_name("month") + '/' + + integer.set_results_name("day")) + # equivalent form: + # date_str = (integer("year") + '/' + # + integer("month") + '/' + # + integer("day")) + + # parse_string returns a ParseResults object + result = date_str.parse_string("1999/12/31") + + def test(s, fn=repr): + print(f"{s} -> {fn(eval(s))}") + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + + prints:: + + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: '31' + - month: '12' + - year: '1999' + """ + + _null_values: Tuple[Any, ...] = (None, [], ()) + + _name: str + _parent: "ParseResults" + _all_names: Set[str] + _modal: bool + _toklist: List[Any] + _tokdict: Dict[str, Any] + + __slots__ = ( + "_name", + "_parent", + "_all_names", + "_modal", + "_toklist", + "_tokdict", + ) + + class List(list): + """ + Simple wrapper class to distinguish parsed list results that should be preserved + as actual Python lists, instead of being converted to :class:`ParseResults`:: + + LBRACK, RBRACK = map(pp.Suppress, "[]") + element = pp.Forward() + item = ppc.integer + element_list = LBRACK + pp.DelimitedList(element) + RBRACK + + # add parse actions to convert from ParseResults to actual Python collection types + def as_python_list(t): + return pp.ParseResults.List(t.as_list()) + element_list.add_parse_action(as_python_list) + + element <<= item | element_list + + element.run_tests(''' + 100 + [2,3,4] + [[2, 1],3,4] + [(2, 1),3,4] + (2,3,4) + ''', post_parse=lambda s, r: (r[0], type(r[0]))) + + prints:: + + 100 + (100, <class 'int'>) + + [2,3,4] + ([2, 3, 4], <class 'list'>) + + [[2, 1],3,4] + ([[2, 1], 3, 4], <class 'list'>) + + (Used internally by :class:`Group` when `aslist=True`.) + """ + + def __new__(cls, contained=None): + if contained is None: + contained = [] + + if not isinstance(contained, list): + raise TypeError( + f"{cls.__name__} may only be constructed with a list, not {type(contained).__name__}" + ) + + return list.__new__(cls) + + def __new__(cls, toklist=None, name=None, **kwargs): + if isinstance(toklist, ParseResults): + return toklist + self = object.__new__(cls) + self._name = None + self._parent = None + self._all_names = set() + + if toklist is None: + self._toklist = [] + elif isinstance(toklist, (list, _generator_type)): + self._toklist = ( + [toklist[:]] + if isinstance(toklist, ParseResults.List) + else list(toklist) + ) + else: + self._toklist = [toklist] + self._tokdict = dict() + return self + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( + self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance + ): + self._tokdict: Dict[str, _ParseResultsWithOffset] + self._modal = modal + if name is not None and name != "": + if isinstance(name, int): + name = str(name) + if not modal: + self._all_names = {name} + self._name = name + if toklist not in self._null_values: + if isinstance(toklist, (str_type, type)): + toklist = [toklist] + if asList: + if isinstance(toklist, ParseResults): + self[name] = _ParseResultsWithOffset( + ParseResults(toklist._toklist), 0 + ) + else: + self[name] = _ParseResultsWithOffset( + ParseResults(toklist[0]), 0 + ) + self[name]._name = name + else: + try: + self[name] = toklist[0] + except (KeyError, TypeError, IndexError): + if toklist is not self: + self[name] = toklist + else: + self._name = name + + def __getitem__(self, i): + if isinstance(i, (int, slice)): + return self._toklist[i] + else: + if i not in self._all_names: + return self._tokdict[i][-1][0] + else: + return ParseResults([v[0] for v in self._tokdict[i]]) + + def __setitem__(self, k, v, isinstance=isinstance): + if isinstance(v, _ParseResultsWithOffset): + self._tokdict[k] = self._tokdict.get(k, list()) + [v] + sub = v[0] + elif isinstance(k, (int, slice)): + self._toklist[k] = v + sub = v + else: + self._tokdict[k] = self._tokdict.get(k, list()) + [ + _ParseResultsWithOffset(v, 0) + ] + sub = v + if isinstance(sub, ParseResults): + sub._parent = self + + def __delitem__(self, i): + if isinstance(i, (int, slice)): + mylen = len(self._toklist) + del self._toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i + 1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name, occurrences in self._tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset( + value, position - (position > j) + ) + else: + del self._tokdict[i] + + def __contains__(self, k) -> bool: + return k in self._tokdict + + def __len__(self) -> int: + return len(self._toklist) + + def __bool__(self) -> bool: + return not not (self._toklist or self._tokdict) + + def __iter__(self) -> Iterator: + return iter(self._toklist) + + def __reversed__(self) -> Iterator: + return iter(self._toklist[::-1]) + + def keys(self): + return iter(self._tokdict) + + def values(self): + return (self[k] for k in self.keys()) + + def items(self): + return ((k, self[k]) for k in self.keys()) + + def haskeys(self) -> bool: + """ + Since ``keys()`` returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return not not self._tokdict + + def pop(self, *args, **kwargs): + """ + Removes and returns item at specified index (default= ``last``). + Supports both ``list`` and ``dict`` semantics for ``pop()``. If + passed no argument or an integer argument, it will use ``list`` + semantics and pop tokens from the list of parsed tokens. If passed + a non-integer argument (most likely a string), it will use ``dict`` + semantics and pop the corresponding value from any defined results + names. A second default return value argument is supported, just as in + ``dict.pop()``. + + Example:: + + numlist = Word(nums)[...] + print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321'] + + def remove_first(tokens): + tokens.pop(0) + numlist.add_parse_action(remove_first) + print(numlist.parse_string("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + Word(nums)[1, ...] + print(patt.parse_string("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.add_parse_action(remove_LABEL) + print(patt.parse_string("AAB 123 321").dump()) + + prints:: + + ['AAB', '123', '321'] + - LABEL: 'AAB' + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k, v in kwargs.items(): + if k == "default": + args = (args[0], v) + else: + raise TypeError(f"pop() got an unexpected keyword argument {k!r}") + if isinstance(args[0], int) or len(args) == 1 or args[0] in self: + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, default_value=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given ``default_value`` or ``None`` if no + ``default_value`` is specified. + + Similar to ``dict.get()``. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parse_string("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return default_value + + def insert(self, index, ins_string): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to ``list.insert()``. + + Example:: + + numlist = Word(nums)[...] + print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + numlist.add_parse_action(insert_locn) + print(numlist.parse_string("0 123 321")) # -> [0, '0', '123', '321'] + """ + self._toklist.insert(index, ins_string) + # fixup indices in token dictionary + for name, occurrences in self._tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset( + value, position + (position > index) + ) + + def append(self, item): + """ + Add single element to end of ``ParseResults`` list of elements. + + Example:: + + numlist = Word(nums)[...] + print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + numlist.add_parse_action(append_sum) + print(numlist.parse_string("0 123 321")) # -> ['0', '123', '321', 444] + """ + self._toklist.append(item) + + def extend(self, itemseq): + """ + Add sequence of elements to end of ``ParseResults`` list of elements. + + Example:: + + patt = Word(alphas)[1, ...] + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + patt.add_parse_action(make_palindrome) + print(patt.parse_string("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self.__iadd__(itemseq) + else: + self._toklist.extend(itemseq) + + def clear(self): + """ + Clear all elements and results names. + """ + del self._toklist[:] + self._tokdict.clear() + + def __getattr__(self, name): + try: + return self[name] + except KeyError: + if name.startswith("__"): + raise AttributeError(name) + return "" + + def __add__(self, other: "ParseResults") -> "ParseResults": + ret = self.copy() + ret += other + return ret + + def __iadd__(self, other: "ParseResults") -> "ParseResults": + if not other: + return self + + if other._tokdict: + offset = len(self._toklist) + addoffset = lambda a: offset if a < 0 else a + offset + otheritems = other._tokdict.items() + otherdictitems = [ + (k, _ParseResultsWithOffset(v[0], addoffset(v[1]))) + for k, vlist in otheritems + for v in vlist + ] + for k, v in otherdictitems: + self[k] = v + if isinstance(v[0], ParseResults): + v[0]._parent = self + + self._toklist += other._toklist + self._all_names |= other._all_names + return self + + def __radd__(self, other) -> "ParseResults": + if isinstance(other, int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__(self) -> str: + return f"{type(self).__name__}({self._toklist!r}, {self.as_dict()})" + + def __str__(self) -> str: + return ( + "[" + + ", ".join( + [ + str(i) if isinstance(i, ParseResults) else repr(i) + for i in self._toklist + ] + ) + + "]" + ) + + def _asStringList(self, sep=""): + out = [] + for item in self._toklist: + if out and sep: + out.append(sep) + if isinstance(item, ParseResults): + out += item._asStringList() + else: + out.append(str(item)) + return out + + def as_list(self) -> list: + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + + patt = Word(alphas)[1, ...] + result = patt.parse_string("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use as_list() to create an actual list + result_list = result.as_list() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [ + res.as_list() if isinstance(res, ParseResults) else res + for res in self._toklist + ] + + def as_dict(self) -> dict: + """ + Returns the named parse results as a nested dictionary. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parse_string('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.as_dict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.as_dict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + + def to_item(obj): + if isinstance(obj, ParseResults): + return obj.as_dict() if obj.haskeys() else [to_item(v) for v in obj] + else: + return obj + + return dict((k, to_item(v)) for k, v in self.items()) + + def copy(self) -> "ParseResults": + """ + Returns a new shallow copy of a :class:`ParseResults` object. `ParseResults` + items contained within the source are shared with the copy. Use + :class:`ParseResults.deepcopy()` to create a copy with its own separate + content values. + """ + ret = ParseResults(self._toklist) + ret._tokdict = self._tokdict.copy() + ret._parent = self._parent + ret._all_names |= self._all_names + ret._name = self._name + return ret + + def deepcopy(self) -> "ParseResults": + """ + Returns a new deep copy of a :class:`ParseResults` object. + """ + ret = self.copy() + # replace values with copies if they are of known mutable types + for i, obj in enumerate(self._toklist): + if isinstance(obj, ParseResults): + self._toklist[i] = obj.deepcopy() + elif isinstance(obj, (str, bytes)): + pass + elif isinstance(obj, MutableMapping): + self._toklist[i] = dest = type(obj)() + for k, v in obj.items(): + dest[k] = v.deepcopy() if isinstance(v, ParseResults) else v + elif isinstance(obj, Container): + self._toklist[i] = type(obj)( + v.deepcopy() if isinstance(v, ParseResults) else v for v in obj + ) + return ret + + def get_name(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = user_data[1, ...] + + result = user_info.parse_string("22 111-22-3333 #221B") + for item in result: + print(item.get_name(), ':', item[0]) + + prints:: + + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self._name: + return self._name + elif self._parent: + par: "ParseResults" = self._parent + parent_tokdict_items = par._tokdict.items() + return next( + ( + k + for k, vlist in parent_tokdict_items + for v, loc in vlist + if v is self + ), + None, + ) + elif ( + len(self) == 1 + and len(self._tokdict) == 1 + and next(iter(self._tokdict.values()))[0][1] in (0, -1) + ): + return next(iter(self._tokdict.keys())) + else: + return None + + def dump(self, indent="", full=True, include_list=True, _depth=0) -> str: + """ + Diagnostic method for listing out the contents of + a :class:`ParseResults`. Accepts an optional ``indent`` argument so + that this string can be embedded in a nested display of other data. + + Example:: + + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parse_string('1999/12/31') + print(result.dump()) + + prints:: + + ['1999', '/', '12', '/', '31'] + - day: '31' + - month: '12' + - year: '1999' + """ + out = [] + NL = "\n" + out.append(indent + str(self.as_list()) if include_list else "") + + if full: + if self.haskeys(): + items = sorted((str(k), v) for k, v in self.items()) + for k, v in items: + if out: + out.append(NL) + out.append(f"{indent}{(' ' * _depth)}- {k}: ") + if isinstance(v, ParseResults): + if v: + out.append( + v.dump( + indent=indent, + full=full, + include_list=include_list, + _depth=_depth + 1, + ) + ) + else: + out.append(str(v)) + else: + out.append(repr(v)) + if any(isinstance(vv, ParseResults) for vv in self): + v = self + for i, vv in enumerate(v): + if isinstance(vv, ParseResults): + out.append( + "\n{}{}[{}]:\n{}{}{}".format( + indent, + (" " * (_depth)), + i, + indent, + (" " * (_depth + 1)), + vv.dump( + indent=indent, + full=full, + include_list=include_list, + _depth=_depth + 1, + ), + ) + ) + else: + out.append( + "\n%s%s[%d]:\n%s%s%s" + % ( + indent, + (" " * (_depth)), + i, + indent, + (" " * (_depth + 1)), + str(vv), + ) + ) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the + `pprint <https://docs.python.org/3/library/pprint.html>`_ module. + Accepts additional positional or keyword args as defined for + `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ . + + Example:: + + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(DelimitedList(term))) + result = func.parse_string("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + + prints:: + + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.as_list(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( + self._toklist, + ( + self._tokdict.copy(), + None, + self._all_names, + self._name, + ), + ) + + def __setstate__(self, state): + self._toklist, (self._tokdict, par, inAccumNames, self._name) = state + self._all_names = set(inAccumNames) + self._parent = None + + def __getnewargs__(self): + return self._toklist, self._name + + def __dir__(self): + return dir(type(self)) + list(self.keys()) + + @classmethod + def from_dict(cls, other, name=None) -> "ParseResults": + """ + Helper classmethod to construct a ``ParseResults`` from a ``dict``, preserving the + name-value relations as results names. If an optional ``name`` argument is + given, a nested ``ParseResults`` will be returned. + """ + + def is_iterable(obj): + try: + iter(obj) + except Exception: + return False + # str's are iterable, but in pyparsing, we don't want to iterate over them + else: + return not isinstance(obj, str_type) + + ret = cls([]) + for k, v in other.items(): + if isinstance(v, Mapping): + ret += cls.from_dict(v, name=k) + else: + ret += cls([v], name=k, asList=is_iterable(v)) + if name is not None: + ret = cls([ret], name=name) + return ret + + asList = as_list + """Deprecated - use :class:`as_list`""" + asDict = as_dict + """Deprecated - use :class:`as_dict`""" + getName = get_name + """Deprecated - use :class:`get_name`""" + + +MutableMapping.register(ParseResults) +MutableSequence.register(ParseResults) diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/testing.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/testing.py new file mode 100644 index 00000000..6a254c1c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/testing.py @@ -0,0 +1,331 @@ +# testing.py + +from contextlib import contextmanager +import typing + +from .core import ( + ParserElement, + ParseException, + Keyword, + __diag__, + __compat__, +) + + +class pyparsing_test: + """ + namespace class for classes useful in writing unit tests + """ + + class reset_pyparsing_context: + """ + Context manager to be used when writing unit tests that modify pyparsing config values: + - packrat parsing + - bounded recursion parsing + - default whitespace characters. + - default keyword characters + - literal string auto-conversion class + - __diag__ settings + + Example:: + + with reset_pyparsing_context(): + # test that literals used to construct a grammar are automatically suppressed + ParserElement.inlineLiteralsUsing(Suppress) + + term = Word(alphas) | Word(nums) + group = Group('(' + term[...] + ')') + + # assert that the '()' characters are not included in the parsed tokens + self.assertParseAndCheckList(group, "(abc 123 def)", ['abc', '123', 'def']) + + # after exiting context manager, literals are converted to Literal expressions again + """ + + def __init__(self): + self._save_context = {} + + def save(self): + self._save_context["default_whitespace"] = ParserElement.DEFAULT_WHITE_CHARS + self._save_context["default_keyword_chars"] = Keyword.DEFAULT_KEYWORD_CHARS + + self._save_context[ + "literal_string_class" + ] = ParserElement._literalStringClass + + self._save_context["verbose_stacktrace"] = ParserElement.verbose_stacktrace + + self._save_context["packrat_enabled"] = ParserElement._packratEnabled + if ParserElement._packratEnabled: + self._save_context[ + "packrat_cache_size" + ] = ParserElement.packrat_cache.size + else: + self._save_context["packrat_cache_size"] = None + self._save_context["packrat_parse"] = ParserElement._parse + self._save_context[ + "recursion_enabled" + ] = ParserElement._left_recursion_enabled + + self._save_context["__diag__"] = { + name: getattr(__diag__, name) for name in __diag__._all_names + } + + self._save_context["__compat__"] = { + "collect_all_And_tokens": __compat__.collect_all_And_tokens + } + + return self + + def restore(self): + # reset pyparsing global state + if ( + ParserElement.DEFAULT_WHITE_CHARS + != self._save_context["default_whitespace"] + ): + ParserElement.set_default_whitespace_chars( + self._save_context["default_whitespace"] + ) + + ParserElement.verbose_stacktrace = self._save_context["verbose_stacktrace"] + + Keyword.DEFAULT_KEYWORD_CHARS = self._save_context["default_keyword_chars"] + ParserElement.inlineLiteralsUsing( + self._save_context["literal_string_class"] + ) + + for name, value in self._save_context["__diag__"].items(): + (__diag__.enable if value else __diag__.disable)(name) + + ParserElement._packratEnabled = False + if self._save_context["packrat_enabled"]: + ParserElement.enable_packrat(self._save_context["packrat_cache_size"]) + else: + ParserElement._parse = self._save_context["packrat_parse"] + ParserElement._left_recursion_enabled = self._save_context[ + "recursion_enabled" + ] + + __compat__.collect_all_And_tokens = self._save_context["__compat__"] + + return self + + def copy(self): + ret = type(self)() + ret._save_context.update(self._save_context) + return ret + + def __enter__(self): + return self.save() + + def __exit__(self, *args): + self.restore() + + class TestParseResultsAsserts: + """ + A mixin class to add parse results assertion methods to normal unittest.TestCase classes. + """ + + def assertParseResultsEquals( + self, result, expected_list=None, expected_dict=None, msg=None + ): + """ + Unit test assertion to compare a :class:`ParseResults` object with an optional ``expected_list``, + and compare any defined results names with an optional ``expected_dict``. + """ + if expected_list is not None: + self.assertEqual(expected_list, result.as_list(), msg=msg) + if expected_dict is not None: + self.assertEqual(expected_dict, result.as_dict(), msg=msg) + + def assertParseAndCheckList( + self, expr, test_string, expected_list, msg=None, verbose=True + ): + """ + Convenience wrapper assert to test a parser element and input string, and assert that + the resulting ``ParseResults.asList()`` is equal to the ``expected_list``. + """ + result = expr.parse_string(test_string, parse_all=True) + if verbose: + print(result.dump()) + else: + print(result.as_list()) + self.assertParseResultsEquals(result, expected_list=expected_list, msg=msg) + + def assertParseAndCheckDict( + self, expr, test_string, expected_dict, msg=None, verbose=True + ): + """ + Convenience wrapper assert to test a parser element and input string, and assert that + the resulting ``ParseResults.asDict()`` is equal to the ``expected_dict``. + """ + result = expr.parse_string(test_string, parseAll=True) + if verbose: + print(result.dump()) + else: + print(result.as_list()) + self.assertParseResultsEquals(result, expected_dict=expected_dict, msg=msg) + + def assertRunTestResults( + self, run_tests_report, expected_parse_results=None, msg=None + ): + """ + Unit test assertion to evaluate output of ``ParserElement.runTests()``. If a list of + list-dict tuples is given as the ``expected_parse_results`` argument, then these are zipped + with the report tuples returned by ``runTests`` and evaluated using ``assertParseResultsEquals``. + Finally, asserts that the overall ``runTests()`` success value is ``True``. + + :param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests + :param expected_parse_results (optional): [tuple(str, list, dict, Exception)] + """ + run_test_success, run_test_results = run_tests_report + + if expected_parse_results is not None: + merged = [ + (*rpt, expected) + for rpt, expected in zip(run_test_results, expected_parse_results) + ] + for test_string, result, expected in merged: + # expected should be a tuple containing a list and/or a dict or an exception, + # and optional failure message string + # an empty tuple will skip any result validation + fail_msg = next( + (exp for exp in expected if isinstance(exp, str)), None + ) + expected_exception = next( + ( + exp + for exp in expected + if isinstance(exp, type) and issubclass(exp, Exception) + ), + None, + ) + if expected_exception is not None: + with self.assertRaises( + expected_exception=expected_exception, msg=fail_msg or msg + ): + if isinstance(result, Exception): + raise result + else: + expected_list = next( + (exp for exp in expected if isinstance(exp, list)), None + ) + expected_dict = next( + (exp for exp in expected if isinstance(exp, dict)), None + ) + if (expected_list, expected_dict) != (None, None): + self.assertParseResultsEquals( + result, + expected_list=expected_list, + expected_dict=expected_dict, + msg=fail_msg or msg, + ) + else: + # warning here maybe? + print(f"no validation for {test_string!r}") + + # do this last, in case some specific test results can be reported instead + self.assertTrue( + run_test_success, msg=msg if msg is not None else "failed runTests" + ) + + @contextmanager + def assertRaisesParseException(self, exc_type=ParseException, msg=None): + with self.assertRaises(exc_type, msg=msg): + yield + + @staticmethod + def with_line_numbers( + s: str, + start_line: typing.Optional[int] = None, + end_line: typing.Optional[int] = None, + expand_tabs: bool = True, + eol_mark: str = "|", + mark_spaces: typing.Optional[str] = None, + mark_control: typing.Optional[str] = None, + ) -> str: + """ + Helpful method for debugging a parser - prints a string with line and column numbers. + (Line and column numbers are 1-based.) + + :param s: tuple(bool, str - string to be printed with line and column numbers + :param start_line: int - (optional) starting line number in s to print (default=1) + :param end_line: int - (optional) ending line number in s to print (default=len(s)) + :param expand_tabs: bool - (optional) expand tabs to spaces, to match the pyparsing default + :param eol_mark: str - (optional) string to mark the end of lines, helps visualize trailing spaces (default="|") + :param mark_spaces: str - (optional) special character to display in place of spaces + :param mark_control: str - (optional) convert non-printing control characters to a placeholding + character; valid values: + - "unicode" - replaces control chars with Unicode symbols, such as "␍" and "␊" + - any single character string - replace control characters with given string + - None (default) - string is displayed as-is + + :return: str - input string with leading line numbers and column number headers + """ + if expand_tabs: + s = s.expandtabs() + if mark_control is not None: + mark_control = typing.cast(str, mark_control) + if mark_control == "unicode": + transtable_map = { + c: u for c, u in zip(range(0, 33), range(0x2400, 0x2433)) + } + transtable_map[127] = 0x2421 + tbl = str.maketrans(transtable_map) + eol_mark = "" + else: + ord_mark_control = ord(mark_control) + tbl = str.maketrans( + {c: ord_mark_control for c in list(range(0, 32)) + [127]} + ) + s = s.translate(tbl) + if mark_spaces is not None and mark_spaces != " ": + if mark_spaces == "unicode": + tbl = str.maketrans({9: 0x2409, 32: 0x2423}) + s = s.translate(tbl) + else: + s = s.replace(" ", mark_spaces) + if start_line is None: + start_line = 1 + if end_line is None: + end_line = len(s) + end_line = min(end_line, len(s)) + start_line = min(max(1, start_line), end_line) + + if mark_control != "unicode": + s_lines = s.splitlines()[start_line - 1 : end_line] + else: + s_lines = [line + "␊" for line in s.split("␊")[start_line - 1 : end_line]] + if not s_lines: + return "" + + lineno_width = len(str(end_line)) + max_line_len = max(len(line) for line in s_lines) + lead = " " * (lineno_width + 1) + if max_line_len >= 99: + header0 = ( + lead + + "".join( + f"{' ' * 99}{(i + 1) % 100}" + for i in range(max(max_line_len // 100, 1)) + ) + + "\n" + ) + else: + header0 = "" + header1 = ( + header0 + + lead + + "".join(f" {(i + 1) % 10}" for i in range(-(-max_line_len // 10))) + + "\n" + ) + header2 = lead + "1234567890" * (-(-max_line_len // 10)) + "\n" + return ( + header1 + + header2 + + "\n".join( + f"{i:{lineno_width}d}:{line}{eol_mark}" + for i, line in enumerate(s_lines, start=start_line) + ) + + "\n" + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/unicode.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/unicode.py new file mode 100644 index 00000000..b0a87b23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/unicode.py @@ -0,0 +1,361 @@ +# unicode.py + +import sys +from itertools import filterfalse +from typing import List, Tuple, Union + + +class _lazyclassproperty: + def __init__(self, fn): + self.fn = fn + self.__doc__ = fn.__doc__ + self.__name__ = fn.__name__ + + def __get__(self, obj, cls): + if cls is None: + cls = type(obj) + if not hasattr(cls, "_intern") or any( + cls._intern is getattr(superclass, "_intern", []) + for superclass in cls.__mro__[1:] + ): + cls._intern = {} + attrname = self.fn.__name__ + if attrname not in cls._intern: + cls._intern[attrname] = self.fn(cls) + return cls._intern[attrname] + + +UnicodeRangeList = List[Union[Tuple[int, int], Tuple[int]]] + + +class unicode_set: + """ + A set of Unicode characters, for language-specific strings for + ``alphas``, ``nums``, ``alphanums``, and ``printables``. + A unicode_set is defined by a list of ranges in the Unicode character + set, in a class attribute ``_ranges``. Ranges can be specified using + 2-tuples or a 1-tuple, such as:: + + _ranges = [ + (0x0020, 0x007e), + (0x00a0, 0x00ff), + (0x0100,), + ] + + Ranges are left- and right-inclusive. A 1-tuple of (x,) is treated as (x, x). + + A unicode set can also be defined using multiple inheritance of other unicode sets:: + + class CJK(Chinese, Japanese, Korean): + pass + """ + + _ranges: UnicodeRangeList = [] + + @_lazyclassproperty + def _chars_for_ranges(cls): + ret = [] + for cc in cls.__mro__: + if cc is unicode_set: + break + for rr in getattr(cc, "_ranges", ()): + ret.extend(range(rr[0], rr[-1] + 1)) + return [chr(c) for c in sorted(set(ret))] + + @_lazyclassproperty + def printables(cls): + """all non-whitespace characters in this range""" + return "".join(filterfalse(str.isspace, cls._chars_for_ranges)) + + @_lazyclassproperty + def alphas(cls): + """all alphabetic characters in this range""" + return "".join(filter(str.isalpha, cls._chars_for_ranges)) + + @_lazyclassproperty + def nums(cls): + """all numeric digit characters in this range""" + return "".join(filter(str.isdigit, cls._chars_for_ranges)) + + @_lazyclassproperty + def alphanums(cls): + """all alphanumeric characters in this range""" + return cls.alphas + cls.nums + + @_lazyclassproperty + def identchars(cls): + """all characters in this range that are valid identifier characters, plus underscore '_'""" + return "".join( + sorted( + set( + "".join(filter(str.isidentifier, cls._chars_for_ranges)) + + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµº" + + "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ" + + "_" + ) + ) + ) + + @_lazyclassproperty + def identbodychars(cls): + """ + all characters in this range that are valid identifier body characters, + plus the digits 0-9, and · (Unicode MIDDLE DOT) + """ + return "".join( + sorted( + set( + cls.identchars + + "0123456789·" + + "".join( + [c for c in cls._chars_for_ranges if ("_" + c).isidentifier()] + ) + ) + ) + ) + + @_lazyclassproperty + def identifier(cls): + """ + a pyparsing Word expression for an identifier using this range's definitions for + identchars and identbodychars + """ + from pyparsing import Word + + return Word(cls.identchars, cls.identbodychars) + + +class pyparsing_unicode(unicode_set): + """ + A namespace class for defining common language unicode_sets. + """ + + # fmt: off + + # define ranges in language character sets + _ranges: UnicodeRangeList = [ + (0x0020, sys.maxunicode), + ] + + class BasicMultilingualPlane(unicode_set): + """Unicode set for the Basic Multilingual Plane""" + _ranges: UnicodeRangeList = [ + (0x0020, 0xFFFF), + ] + + class Latin1(unicode_set): + """Unicode set for Latin-1 Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0020, 0x007E), + (0x00A0, 0x00FF), + ] + + class LatinA(unicode_set): + """Unicode set for Latin-A Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0100, 0x017F), + ] + + class LatinB(unicode_set): + """Unicode set for Latin-B Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0180, 0x024F), + ] + + class Greek(unicode_set): + """Unicode set for Greek Unicode Character Ranges""" + _ranges: UnicodeRangeList = [ + (0x0342, 0x0345), + (0x0370, 0x0377), + (0x037A, 0x037F), + (0x0384, 0x038A), + (0x038C,), + (0x038E, 0x03A1), + (0x03A3, 0x03E1), + (0x03F0, 0x03FF), + (0x1D26, 0x1D2A), + (0x1D5E,), + (0x1D60,), + (0x1D66, 0x1D6A), + (0x1F00, 0x1F15), + (0x1F18, 0x1F1D), + (0x1F20, 0x1F45), + (0x1F48, 0x1F4D), + (0x1F50, 0x1F57), + (0x1F59,), + (0x1F5B,), + (0x1F5D,), + (0x1F5F, 0x1F7D), + (0x1F80, 0x1FB4), + (0x1FB6, 0x1FC4), + (0x1FC6, 0x1FD3), + (0x1FD6, 0x1FDB), + (0x1FDD, 0x1FEF), + (0x1FF2, 0x1FF4), + (0x1FF6, 0x1FFE), + (0x2129,), + (0x2719, 0x271A), + (0xAB65,), + (0x10140, 0x1018D), + (0x101A0,), + (0x1D200, 0x1D245), + (0x1F7A1, 0x1F7A7), + ] + + class Cyrillic(unicode_set): + """Unicode set for Cyrillic Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0400, 0x052F), + (0x1C80, 0x1C88), + (0x1D2B,), + (0x1D78,), + (0x2DE0, 0x2DFF), + (0xA640, 0xA672), + (0xA674, 0xA69F), + (0xFE2E, 0xFE2F), + ] + + class Chinese(unicode_set): + """Unicode set for Chinese Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x2E80, 0x2E99), + (0x2E9B, 0x2EF3), + (0x31C0, 0x31E3), + (0x3400, 0x4DB5), + (0x4E00, 0x9FEF), + (0xA700, 0xA707), + (0xF900, 0xFA6D), + (0xFA70, 0xFAD9), + (0x16FE2, 0x16FE3), + (0x1F210, 0x1F212), + (0x1F214, 0x1F23B), + (0x1F240, 0x1F248), + (0x20000, 0x2A6D6), + (0x2A700, 0x2B734), + (0x2B740, 0x2B81D), + (0x2B820, 0x2CEA1), + (0x2CEB0, 0x2EBE0), + (0x2F800, 0x2FA1D), + ] + + class Japanese(unicode_set): + """Unicode set for Japanese Unicode Character Range, combining Kanji, Hiragana, and Katakana ranges""" + + class Kanji(unicode_set): + "Unicode set for Kanji Unicode Character Range" + _ranges: UnicodeRangeList = [ + (0x4E00, 0x9FBF), + (0x3000, 0x303F), + ] + + class Hiragana(unicode_set): + """Unicode set for Hiragana Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x3041, 0x3096), + (0x3099, 0x30A0), + (0x30FC,), + (0xFF70,), + (0x1B001,), + (0x1B150, 0x1B152), + (0x1F200,), + ] + + class Katakana(unicode_set): + """Unicode set for Katakana Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x3099, 0x309C), + (0x30A0, 0x30FF), + (0x31F0, 0x31FF), + (0x32D0, 0x32FE), + (0xFF65, 0xFF9F), + (0x1B000,), + (0x1B164, 0x1B167), + (0x1F201, 0x1F202), + (0x1F213,), + ] + + 漢字 = Kanji + カタカナ = Katakana + ひらがな = Hiragana + + _ranges = ( + Kanji._ranges + + Hiragana._ranges + + Katakana._ranges + ) + + class Hangul(unicode_set): + """Unicode set for Hangul (Korean) Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x1100, 0x11FF), + (0x302E, 0x302F), + (0x3131, 0x318E), + (0x3200, 0x321C), + (0x3260, 0x327B), + (0x327E,), + (0xA960, 0xA97C), + (0xAC00, 0xD7A3), + (0xD7B0, 0xD7C6), + (0xD7CB, 0xD7FB), + (0xFFA0, 0xFFBE), + (0xFFC2, 0xFFC7), + (0xFFCA, 0xFFCF), + (0xFFD2, 0xFFD7), + (0xFFDA, 0xFFDC), + ] + + Korean = Hangul + + class CJK(Chinese, Japanese, Hangul): + """Unicode set for combined Chinese, Japanese, and Korean (CJK) Unicode Character Range""" + + class Thai(unicode_set): + """Unicode set for Thai Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0E01, 0x0E3A), + (0x0E3F, 0x0E5B) + ] + + class Arabic(unicode_set): + """Unicode set for Arabic Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0600, 0x061B), + (0x061E, 0x06FF), + (0x0700, 0x077F), + ] + + class Hebrew(unicode_set): + """Unicode set for Hebrew Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0591, 0x05C7), + (0x05D0, 0x05EA), + (0x05EF, 0x05F4), + (0xFB1D, 0xFB36), + (0xFB38, 0xFB3C), + (0xFB3E,), + (0xFB40, 0xFB41), + (0xFB43, 0xFB44), + (0xFB46, 0xFB4F), + ] + + class Devanagari(unicode_set): + """Unicode set for Devanagari Unicode Character Range""" + _ranges: UnicodeRangeList = [ + (0x0900, 0x097F), + (0xA8E0, 0xA8FF) + ] + + BMP = BasicMultilingualPlane + + # add language identifiers using language Unicode + العربية = Arabic + 中文 = Chinese + кириллица = Cyrillic + Ελληνικά = Greek + עִברִית = Hebrew + 日本語 = Japanese + 한국어 = Korean + ไทย = Thai + देवनागरी = Devanagari + + # fmt: on diff --git a/dbdpy-env/lib/python3.9/site-packages/pyparsing/util.py b/dbdpy-env/lib/python3.9/site-packages/pyparsing/util.py new file mode 100644 index 00000000..d8d3f414 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pyparsing/util.py @@ -0,0 +1,284 @@ +# util.py +import inspect +import warnings +import types +import collections +import itertools +from functools import lru_cache, wraps +from typing import Callable, List, Union, Iterable, TypeVar, cast + +_bslash = chr(92) +C = TypeVar("C", bound=Callable) + + +class __config_flags: + """Internal class for defining compatibility and debugging flags""" + + _all_names: List[str] = [] + _fixed_names: List[str] = [] + _type_desc = "configuration" + + @classmethod + def _set(cls, dname, value): + if dname in cls._fixed_names: + warnings.warn( + f"{cls.__name__}.{dname} {cls._type_desc} is {str(getattr(cls, dname)).upper()}" + f" and cannot be overridden", + stacklevel=3, + ) + return + if dname in cls._all_names: + setattr(cls, dname, value) + else: + raise ValueError(f"no such {cls._type_desc} {dname!r}") + + enable = classmethod(lambda cls, name: cls._set(name, True)) + disable = classmethod(lambda cls, name: cls._set(name, False)) + + +@lru_cache(maxsize=128) +def col(loc: int, strg: str) -> int: + """ + Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See + :class:`ParserElement.parse_string` for more + information on parsing strings containing ``<TAB>`` s, and suggested + methods to maintain a consistent view of the parsed string, the parse + location, and line and column positions within the parsed string. + """ + s = strg + return 1 if 0 < loc < len(s) and s[loc - 1] == "\n" else loc - s.rfind("\n", 0, loc) + + +@lru_cache(maxsize=128) +def lineno(loc: int, strg: str) -> int: + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note - the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See :class:`ParserElement.parse_string` + for more information on parsing strings containing ``<TAB>`` s, and + suggested methods to maintain a consistent view of the parsed string, the + parse location, and line and column positions within the parsed string. + """ + return strg.count("\n", 0, loc) + 1 + + +@lru_cache(maxsize=128) +def line(loc: int, strg: str) -> str: + """ + Returns the line of text containing loc within a string, counting newlines as line separators. + """ + last_cr = strg.rfind("\n", 0, loc) + next_cr = strg.find("\n", loc) + return strg[last_cr + 1 : next_cr] if next_cr >= 0 else strg[last_cr + 1 :] + + +class _UnboundedCache: + def __init__(self): + cache = {} + cache_get = cache.get + self.not_in_cache = not_in_cache = object() + + def get(_, key): + return cache_get(key, not_in_cache) + + def set_(_, key, value): + cache[key] = value + + def clear(_): + cache.clear() + + self.size = None + self.get = types.MethodType(get, self) + self.set = types.MethodType(set_, self) + self.clear = types.MethodType(clear, self) + + +class _FifoCache: + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + cache = {} + keyring = [object()] * size + cache_get = cache.get + cache_pop = cache.pop + keyiter = itertools.cycle(range(size)) + + def get(_, key): + return cache_get(key, not_in_cache) + + def set_(_, key, value): + cache[key] = value + i = next(keyiter) + cache_pop(keyring[i], None) + keyring[i] = key + + def clear(_): + cache.clear() + keyring[:] = [object()] * size + + self.size = size + self.get = types.MethodType(get, self) + self.set = types.MethodType(set_, self) + self.clear = types.MethodType(clear, self) + + +class LRUMemo: + """ + A memoizing mapping that retains `capacity` deleted items + + The memo tracks retained items by their access order; once `capacity` items + are retained, the least recently used item is discarded. + """ + + def __init__(self, capacity): + self._capacity = capacity + self._active = {} + self._memory = collections.OrderedDict() + + def __getitem__(self, key): + try: + return self._active[key] + except KeyError: + self._memory.move_to_end(key) + return self._memory[key] + + def __setitem__(self, key, value): + self._memory.pop(key, None) + self._active[key] = value + + def __delitem__(self, key): + try: + value = self._active.pop(key) + except KeyError: + pass + else: + while len(self._memory) >= self._capacity: + self._memory.popitem(last=False) + self._memory[key] = value + + def clear(self): + self._active.clear() + self._memory.clear() + + +class UnboundedMemo(dict): + """ + A memoizing mapping that retains all deleted items + """ + + def __delitem__(self, key): + pass + + +def _escape_regex_range_chars(s: str) -> str: + # escape these chars: ^-[] + for c in r"\^-[]": + s = s.replace(c, _bslash + c) + s = s.replace("\n", r"\n") + s = s.replace("\t", r"\t") + return str(s) + + +def _collapse_string_to_ranges( + s: Union[str, Iterable[str]], re_escape: bool = True +) -> str: + def is_consecutive(c): + c_int = ord(c) + is_consecutive.prev, prev = c_int, is_consecutive.prev + if c_int - prev > 1: + is_consecutive.value = next(is_consecutive.counter) + return is_consecutive.value + + is_consecutive.prev = 0 # type: ignore [attr-defined] + is_consecutive.counter = itertools.count() # type: ignore [attr-defined] + is_consecutive.value = -1 # type: ignore [attr-defined] + + def escape_re_range_char(c): + return "\\" + c if c in r"\^-][" else c + + def no_escape_re_range_char(c): + return c + + if not re_escape: + escape_re_range_char = no_escape_re_range_char + + ret = [] + s = "".join(sorted(set(s))) + if len(s) > 3: + for _, chars in itertools.groupby(s, key=is_consecutive): + first = last = next(chars) + last = collections.deque( + itertools.chain(iter([last]), chars), maxlen=1 + ).pop() + if first == last: + ret.append(escape_re_range_char(first)) + else: + sep = "" if ord(last) == ord(first) + 1 else "-" + ret.append( + f"{escape_re_range_char(first)}{sep}{escape_re_range_char(last)}" + ) + else: + ret = [escape_re_range_char(c) for c in s] + + return "".join(ret) + + +def _flatten(ll: list) -> list: + ret = [] + for i in ll: + if isinstance(i, list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + + +def _make_synonym_function(compat_name: str, fn: C) -> C: + # In a future version, uncomment the code in the internal _inner() functions + # to begin emitting DeprecationWarnings. + + # Unwrap staticmethod/classmethod + fn = getattr(fn, "__func__", fn) + + # (Presence of 'self' arg in signature is used by explain_exception() methods, so we take + # some extra steps to add it if present in decorated function.) + if "self" == list(inspect.signature(fn).parameters)[0]: + + @wraps(fn) + def _inner(self, *args, **kwargs): + # warnings.warn( + # f"Deprecated - use {fn.__name__}", DeprecationWarning, stacklevel=3 + # ) + return fn(self, *args, **kwargs) + + else: + + @wraps(fn) + def _inner(*args, **kwargs): + # warnings.warn( + # f"Deprecated - use {fn.__name__}", DeprecationWarning, stacklevel=3 + # ) + return fn(*args, **kwargs) + + _inner.__doc__ = f"""Deprecated - use :class:`{fn.__name__}`""" + _inner.__name__ = compat_name + _inner.__annotations__ = fn.__annotations__ + if isinstance(fn, types.FunctionType): + _inner.__kwdefaults__ = fn.__kwdefaults__ + elif isinstance(fn, type) and hasattr(fn, "__init__"): + _inner.__kwdefaults__ = fn.__init__.__kwdefaults__ + else: + _inner.__kwdefaults__ = None + _inner.__qualname__ = fn.__qualname__ + return cast(C, _inner) + + +def replaced_by_pep8(fn: C) -> Callable[[Callable], C]: + """ + Decorator for pre-PEP8 compatibility synonyms, to link them to the new function. + """ + return lambda other: _make_synonym_function(other.__name__, fn) diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/LICENSE new file mode 100644 index 00000000..c3f1657f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2004 Holger Krekel and others + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/METADATA new file mode 100644 index 00000000..20b02c24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/METADATA @@ -0,0 +1,222 @@ +Metadata-Version: 2.1 +Name: pytest +Version: 7.4.4 +Summary: pytest: simple powerful testing with Python +Home-page: https://docs.pytest.org/en/latest/ +Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others +License: MIT +Project-URL: Changelog, https://docs.pytest.org/en/stable/changelog.html +Project-URL: Twitter, https://twitter.com/pytestdotorg +Project-URL: Source, https://github.com/pytest-dev/pytest +Project-URL: Tracker, https://github.com/pytest-dev/pytest/issues +Keywords: test,unittest +Platform: unix +Platform: linux +Platform: osx +Platform: cygwin +Platform: win32 +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development :: Testing +Classifier: Topic :: Utilities +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: iniconfig +Requires-Dist: packaging +Requires-Dist: pluggy <2.0,>=0.12 +Requires-Dist: exceptiongroup >=1.0.0rc8 ; python_version < "3.11" +Requires-Dist: tomli >=1.0.0 ; python_version < "3.11" +Requires-Dist: importlib-metadata >=0.12 ; python_version < "3.8" +Requires-Dist: colorama ; sys_platform == "win32" +Provides-Extra: testing +Requires-Dist: argcomplete ; extra == 'testing' +Requires-Dist: attrs >=19.2.0 ; extra == 'testing' +Requires-Dist: hypothesis >=3.56 ; extra == 'testing' +Requires-Dist: mock ; extra == 'testing' +Requires-Dist: nose ; extra == 'testing' +Requires-Dist: pygments >=2.7.2 ; extra == 'testing' +Requires-Dist: requests ; extra == 'testing' +Requires-Dist: setuptools ; extra == 'testing' +Requires-Dist: xmlschema ; extra == 'testing' + +.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg + :target: https://docs.pytest.org/en/stable/ + :align: center + :height: 200 + :alt: pytest + + +------ + +.. image:: https://img.shields.io/pypi/v/pytest.svg + :target: https://pypi.org/project/pytest/ + +.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg + :target: https://anaconda.org/conda-forge/pytest + +.. image:: https://img.shields.io/pypi/pyversions/pytest.svg + :target: https://pypi.org/project/pytest/ + +.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg + :target: https://codecov.io/gh/pytest-dev/pytest + :alt: Code coverage Status + +.. image:: https://github.com/pytest-dev/pytest/workflows/test/badge.svg + :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Atest + +.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg + :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main + :alt: pre-commit.ci status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + +.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg + :target: https://www.codetriage.com/pytest-dev/pytest + +.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest + :target: https://pytest.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue + :target: https://discord.com/invite/pytest-dev + :alt: Discord + +.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange + :target: https://web.libera.chat/#pytest + :alt: Libera chat + + +The ``pytest`` framework makes it easy to write small tests, yet +scales to support complex functional testing for applications and libraries. + +An example of a simple test: + +.. code-block:: python + + # content of test_sample.py + def inc(x): + return x + 1 + + + def test_answer(): + assert inc(3) == 5 + + +To execute it:: + + $ pytest + ============================= test session starts ============================= + collected 1 items + + test_sample.py F + + ================================== FAILURES =================================== + _________________________________ test_answer _________________________________ + + def test_answer(): + > assert inc(3) == 5 + E assert 4 == 5 + E + where 4 = inc(3) + + test_sample.py:5: AssertionError + ========================== 1 failed in 0.04 seconds =========================== + + +Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <https://docs.pytest.org/en/stable/getting-started.html#our-first-test-run>`_ for more examples. + + +Features +-------- + +- Detailed info on failing `assert statements <https://docs.pytest.org/en/stable/how-to/assert.html>`_ (no need to remember ``self.assert*`` names) + +- `Auto-discovery + <https://docs.pytest.org/en/stable/explanation/goodpractices.html#python-test-discovery>`_ + of test modules and functions + +- `Modular fixtures <https://docs.pytest.org/en/stable/explanation/fixtures.html>`_ for + managing small or parametrized long-lived test resources + +- Can run `unittest <https://docs.pytest.org/en/stable/how-to/unittest.html>`_ (or trial), + `nose <https://docs.pytest.org/en/stable/how-to/nose.html>`_ test suites out of the box + +- Python 3.7+ or PyPy3 + +- Rich plugin architecture, with over 850+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community + + +Documentation +------------- + +For full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/stable/. + + +Bugs/Requests +------------- + +Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issues>`_ to submit bugs or request features. + + +Changelog +--------- + +Consult the `Changelog <https://docs.pytest.org/en/stable/changelog.html>`__ page for fixes and enhancements of each version. + + +Support pytest +-------------- + +`Open Collective`_ is an online funding platform for open and transparent communities. +It provides tools to raise money and share your finances in full transparency. + +It is the platform of choice for individuals and companies that want to make one-time or +monthly donations directly to the project. + +See more details in the `pytest collective`_. + +.. _Open Collective: https://opencollective.com +.. _pytest collective: https://opencollective.com/pytest + + +pytest for enterprise +--------------------- + +Available as part of the Tidelift Subscription. + +The maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and +maintenance for the open source dependencies you use to build your applications. +Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. + +`Learn more. <https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_ + +Security +^^^^^^^^ + +pytest has never been associated with a security vulnerability, but in any case, to report a +security vulnerability please use the `Tidelift security contact <https://tidelift.com/security>`_. +Tidelift will coordinate the fix and disclosure. + + +License +------- + +Copyright Holger Krekel and others, 2004. + +Distributed under the terms of the `MIT`_ license, pytest is free and open source software. + +.. _`MIT`: https://github.com/pytest-dev/pytest/blob/main/LICENSE diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/RECORD new file mode 100644 index 00000000..6e790b7d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/RECORD @@ -0,0 +1,154 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_argcomplete.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/code.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_code/source.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/saferepr.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/terminalwriter.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_io/wcwidth.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/error.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_py/path.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/_version.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/rewrite.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/truncate.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/assertion/util.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/cacheprovider.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/capture.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/compat.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/config/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/config/argparsing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/config/compat.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/config/exceptions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/config/findpaths.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/debugging.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/deprecated.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/doctest.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/faulthandler.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/fixtures.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/freeze_support.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/helpconfig.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/hookspec.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/junitxml.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/legacypath.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/logging.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/main.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/expression.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/mark/structures.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/monkeypatch.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/nodes.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/nose.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/outcomes.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/pastebin.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/pathlib.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/pytester_assertions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/python.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/python_api.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/python_path.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/recwarn.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/reports.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/runner.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/scope.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/setuponly.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/setupplan.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/skipping.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/stash.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/stepwise.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/terminal.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/threadexception.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/timing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/tmpdir.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/unittest.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/unraisableexception.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/warning_types.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/_pytest/warnings.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/py.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pytest/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pytest/__main__.cpython-39.pyc,, +../../../bin/py.test,sha256=W9DVyHrRRj5PceJIHVaOoU80-yCj-Cj7oiCSyaVVQqM,256 +../../../bin/pytest,sha256=W9DVyHrRRj5PceJIHVaOoU80-yCj-Cj7oiCSyaVVQqM,256 +_pytest/__init__.py,sha256=4K-_CZFPuvNtJXNwxyTtnbmpjVkSb-dC75bs29Sg0d4,356 +_pytest/_argcomplete.py,sha256=YpnQdf25q066cF9hAQKXIw55HmAx-HWLOPg3wKmT1so,3794 +_pytest/_code/__init__.py,sha256=S_sBUyBt-DdDWGJKJviYTWFHhhDFBM7pIMaENaocwaM,483 +_pytest/_code/code.py,sha256=q74apRbmc8m9UYFSRZRRIIVzHnfG3JsCKNc29hsAmIc,46740 +_pytest/_code/source.py,sha256=URY36RBYU0mtBZF4HQoNC0OqVRjmHLetIrjNnvzjh9g,7436 +_pytest/_io/__init__.py,sha256=NWs125Ln6IqP5BZNw-V2iN_yYPwGM7vfrAP5ta6MhPA,154 +_pytest/_io/saferepr.py,sha256=r222Mkvyl_TXXQvGqGURDaQZBH55l0y7VDxyzBqNw9k,5394 +_pytest/_io/terminalwriter.py,sha256=aLbaFJ3KO-B8ZgeWonQ4-dZEcAt1ReX7xAW5BRoaODE,8152 +_pytest/_io/wcwidth.py,sha256=YhE3To-vBI7udLtV4B-g-04S3l8VoRD5ki935QipmJA,1253 +_pytest/_py/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +_pytest/_py/error.py,sha256=Ocm93fwIaLxWvXBQV-0-GbItURWOCdQg8uG6994QhLI,3014 +_pytest/_py/path.py,sha256=Fc6aZ7rvsB-7xiM5ZOJr6cHLBh3nNnuPbxkXwbRkNjE,49149 +_pytest/_version.py,sha256=rOnwFyU9bnJNsp7ITC0OdiA7PacdTSiieniqkvTzqpc,411 +_pytest/assertion/__init__.py,sha256=9eQINJEUWPPvHx3neW5SI6SWf0ntPp2iQXihzPGJA9Q,6458 +_pytest/assertion/rewrite.py,sha256=-9oY0gJnZl9phrwA6FINv6w0aEicSKz6cHyKZAaAidQ,47741 +_pytest/assertion/truncate.py,sha256=68YnKJcR34tkKU146CzFmiWXdNE6NmKgBXpQb_HNUSI,4382 +_pytest/assertion/util.py,sha256=m6-zlEfGciwT0Qh7qA6y8DDlJ8wGI2cwjZ_qLQXR5k8,18009 +_pytest/cacheprovider.py,sha256=2uTxVGIdcXPUsIqGA2owpugK3THrVoaBBA7VvWlxakc,21659 +_pytest/capture.py,sha256=5p7ak0e5XBi0qfcaU0ZPKO47cy-vGoGzn6S7Os-M1Gg,34737 +_pytest/compat.py,sha256=ta-0FxRsHe4N2FRsDRG8RXi-_lJeQXevQCVo_6bUbzE,13637 +_pytest/config/__init__.py,sha256=Behe_CVnLJpkd8Ct4u8hXkx5pE9quk6jcgNZGodh2LU,64177 +_pytest/config/argparsing.py,sha256=VcBUsFlK2Th9dtAwjD5UIYquXkFYZtbJpOAWAFLiBw4,21225 +_pytest/config/compat.py,sha256=fj_LbkWm9yJKeY64C_8AeKqbYHr5k9MDrZugTJs8AWI,2393 +_pytest/config/exceptions.py,sha256=21I5MARt26OLRmgvaAPu0BblFgYZXp2cxNZBpRRciAE,260 +_pytest/config/findpaths.py,sha256=B1LaW1JunqZXYsPPXhZUGU1_rOziO7ybVbnacVbLYgY,7615 +_pytest/debugging.py,sha256=cQxelK2gKBogv_c4e9q0xybHCcbsdLJmz4L5WBE68cs,13498 +_pytest/deprecated.py,sha256=Me3lX-KEKCxpSjPh9qNPDKMX16eltg5ben0Zn-Id0qg,5487 +_pytest/doctest.py,sha256=ec6FDUBzjLsOvjyKba2XazIp_ZnfkigmjrtA08EREn4,26845 +_pytest/faulthandler.py,sha256=MT3CFuxgqqa7fTQdH0cfU6_2BUmu7QYFXMfr_LT5uT4,3578 +_pytest/fixtures.py,sha256=KdU2XEdUm0VdmN9zd9oM8VCknzgYYH8oSrwXvTD6GPs,67085 +_pytest/freeze_support.py,sha256=Wmx-CJvzCbOAK3brpNJO6X_WHXcCA6Tr6-Tb_tjIyVQ,1339 +_pytest/helpconfig.py,sha256=gbtjfcN-anYzCbVTC43jsOe3psMjWNsx7xB0z0SW7kQ,8658 +_pytest/hookspec.py,sha256=pSGZ5hQeI7yIbLWdm_uXRHDkMGLH44wrMOWjUammxos,32558 +_pytest/junitxml.py,sha256=NwK1539G5o4ny2nyr2KNi_QYZXjen3jf2u68dxYosMM,25710 +_pytest/legacypath.py,sha256=CRBfhIuToQNTFDzA6fdhTgnQFVN-V_EQOPOY7KUk2HE,16929 +_pytest/logging.py,sha256=fazFyIeZkkH812KqOBWrz-MUra7ARY9SrtRk9EtXW88,34130 +_pytest/main.py,sha256=-BRQXXwMrbTMtSdD0chYyDHHHzuHPsIUBQnzCckYxv0,32658 +_pytest/mark/__init__.py,sha256=tfeYUQwpIDqfcvZWOjcb07F1mnyoeqXLtjX-ZWTVg1Q,8468 +_pytest/mark/expression.py,sha256=Se6Cl15lBb92RGa2g30pLpi9ozn72PKjiTS6B_bTeNg,6507 +_pytest/mark/structures.py,sha256=yvqwKM0lx6xdOP4iI2YIvK1yEHHpOHfSf11sEYb-w9U,21219 +_pytest/monkeypatch.py,sha256=vT0wc75BgW4ElVtDhflPqvbyEc3ndxaz28EYcu_HLM0,14857 +_pytest/nodes.py,sha256=u3MrDgkcVx96ZgxBLqwCkgtJsv4MpheuqOJKMRLT7ao,26687 +_pytest/nose.py,sha256=mjb1d2J0PlCc7YnQvfAt3LhCMBGjsPrx5MZX59Ri-mU,1688 +_pytest/outcomes.py,sha256=7J82mRR3e89dlfJ9TLrnB--GWq6tqU8BP4Pbzt3NQMY,10323 +_pytest/pastebin.py,sha256=l-Jm8hJ_zuT_VdilatBUzvtuAfAN27Oxs7nS1UM8d-M,3949 +_pytest/pathlib.py,sha256=r_Vbw3FQ6FGjAs6KcTRur2ViH9xjCVU6e_II9wbMgWY,27059 +_pytest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +_pytest/pytester.py,sha256=PAhvDdI4OygMrfHOM60JL7aNtKGL5EKOSSWUJKEPhM4,62002 +_pytest/pytester_assertions.py,sha256=1BW3jDRSiHqGqdzmGSc7LfQt7nwc0w1lVRHMHHcFEQs,2327 +_pytest/python.py,sha256=5BVlKnGb02ixGDIOi0PJgAKKnx8fA2Izgs7R0ffpT2Q,71399 +_pytest/python_api.py,sha256=zQunfXCbgOE69O0DIu1ACoQ4Fm2w9J7OtxFvjjTQ0pk,38534 +_pytest/python_path.py,sha256=TD7qJJ0S91XctgtpIjaq21DWh3rlxxVwXMvrjsjevaU,709 +_pytest/recwarn.py,sha256=KOUdXBVOc3ZqHDvOCZSVxBbT4SUezs68uMaWH0ujasA,10930 +_pytest/reports.py,sha256=TVt5M3EtGrZfROJF23U8gX5_YDjumS34vlw3VXHPbhc,20840 +_pytest/runner.py,sha256=7BD2m-Rhpf5b2DlT3e1uvZUWqUGtlE6ADBff6n21sO4,18447 +_pytest/scope.py,sha256=dNx6zm8ZWPrwsz8v7sAoemp537tEsdl1-_EOegPrwYE,2882 +_pytest/setuponly.py,sha256=KEmb8N4On3_yH1T5cyo9_QYbxWgm3H3QkvshDf77z3o,3261 +_pytest/setupplan.py,sha256=0HVsIdKbYfJEbAiwidBfQZwNE7RziZ1BI0vrFeohAOc,1214 +_pytest/skipping.py,sha256=P4BvQ73DnQhI0s7ezGuc2F6h3APigHKLkELjpxlfhDs,10200 +_pytest/stash.py,sha256=x_ywAeTfX84tI0vUyXmKmCDxwcXIETqnCrVkOUAtqQ8,3055 +_pytest/stepwise.py,sha256=oaLyCsqteCgi4QEu_rMeJq7adUhaBv3aINQSETQZ0d8,4714 +_pytest/terminal.py,sha256=Fh9Bb-8YsyGPzJiQvtFa5gMEECHUDBlwO3NQ6e56MYg,53509 +_pytest/threadexception.py,sha256=TEohIXnQcof6D7cg10Ly4oMSRgHLCNsXPF6Du9FV4K8,2915 +_pytest/timing.py,sha256=vufB2Wrk_Bf4uol6U16WfpikCBttEmmtGKBNBshPN_k,375 +_pytest/tmpdir.py,sha256=NfyrD4hF3axsMBx74P9K-PfhlPXyuRpiqScolKLZW5k,11708 +_pytest/unittest.py,sha256=fvKUT_OBB0nHfog5ApCzqRBwqwuKtn6qz503gQHALag,14809 +_pytest/unraisableexception.py,sha256=FJmftKtjMHmUnlYyg1o9B_oQjvA_U0p1ABSNlKx1K2I,3191 +_pytest/warning_types.py,sha256=ZqFZR7e0CNeb6V6lXf37qdTKOaKI5TsqkDgbzYtwgds,4474 +_pytest/warnings.py,sha256=pBY3hIrOZobaWk9vHgW_ac44jXYhlyUuferDOhwaMGI,5070 +py.py,sha256=UEzy74zelHEaKeqgb96pBWOmeEEtqhOszJdX7UuwTsQ,263 +pytest-7.4.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pytest-7.4.4.dist-info/LICENSE,sha256=yoNqX57Mo7LzUCMPqiCkj7ixRWU7VWjXhIYt-GRwa5s,1091 +pytest-7.4.4.dist-info/METADATA,sha256=NM3rHw_7aymXADHSxF4Ad1K7cqY7_ZZgB2xxKI_4dbE,7946 +pytest-7.4.4.dist-info/RECORD,, +pytest-7.4.4.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pytest-7.4.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +pytest-7.4.4.dist-info/entry_points.txt,sha256=8IPrHPH3LNZQ7v5tNEOcNTZYk_SheNg64jsTM9erqL4,77 +pytest-7.4.4.dist-info/top_level.txt,sha256=yyhjvmXH7-JOaoQIdmNQHPuoBCxOyXS3jIths_6C8A4,18 +pytest/__init__.py,sha256=_yW6iMPyE3fU_LiXPCwILu-rWcMYouVSmWQ49S4vmkc,5237 +pytest/__main__.py,sha256=PJoBBgRxbsenpjfDenJmkO0-UGzTad7Htcxgstu4g30,116 +pytest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/WHEEL new file mode 100644 index 00000000..98c0d20b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/entry_points.txt b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/entry_points.txt new file mode 100644 index 00000000..192205df --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +py.test = pytest:console_main +pytest = pytest:console_main diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/top_level.txt new file mode 100644 index 00000000..3084ae51 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest-7.4.4.dist-info/top_level.txt @@ -0,0 +1,3 @@ +_pytest +py +pytest diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest/__init__.py b/dbdpy-env/lib/python3.9/site-packages/pytest/__init__.py new file mode 100644 index 00000000..9c1d5d20 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest/__init__.py @@ -0,0 +1,171 @@ +# PYTHON_ARGCOMPLETE_OK +"""pytest: unit and functional testing with Python.""" +from _pytest import __version__ +from _pytest import version_tuple +from _pytest._code import ExceptionInfo +from _pytest.assertion import register_assert_rewrite +from _pytest.cacheprovider import Cache +from _pytest.capture import CaptureFixture +from _pytest.config import cmdline +from _pytest.config import Config +from _pytest.config import console_main +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config import hookspec +from _pytest.config import main +from _pytest.config import PytestPluginManager +from _pytest.config import UsageError +from _pytest.config.argparsing import OptionGroup +from _pytest.config.argparsing import Parser +from _pytest.debugging import pytestPDB as __pytestPDB +from _pytest.doctest import DoctestItem +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureLookupError +from _pytest.fixtures import FixtureRequest +from _pytest.fixtures import yield_fixture +from _pytest.freeze_support import freeze_includes +from _pytest.legacypath import TempdirFactory +from _pytest.legacypath import Testdir +from _pytest.logging import LogCaptureFixture +from _pytest.main import Session +from _pytest.mark import Mark +from _pytest.mark import MARK_GEN as mark +from _pytest.mark import MarkDecorator +from _pytest.mark import MarkGenerator +from _pytest.mark import param +from _pytest.monkeypatch import MonkeyPatch +from _pytest.nodes import Collector +from _pytest.nodes import File +from _pytest.nodes import Item +from _pytest.outcomes import exit +from _pytest.outcomes import fail +from _pytest.outcomes import importorskip +from _pytest.outcomes import skip +from _pytest.outcomes import xfail +from _pytest.pytester import HookRecorder +from _pytest.pytester import LineMatcher +from _pytest.pytester import Pytester +from _pytest.pytester import RecordedHookCall +from _pytest.pytester import RunResult +from _pytest.python import Class +from _pytest.python import Function +from _pytest.python import Metafunc +from _pytest.python import Module +from _pytest.python import Package +from _pytest.python_api import approx +from _pytest.python_api import raises +from _pytest.recwarn import deprecated_call +from _pytest.recwarn import WarningsRecorder +from _pytest.recwarn import warns +from _pytest.reports import CollectReport +from _pytest.reports import TestReport +from _pytest.runner import CallInfo +from _pytest.stash import Stash +from _pytest.stash import StashKey +from _pytest.terminal import TestShortLogReport +from _pytest.tmpdir import TempPathFactory +from _pytest.warning_types import PytestAssertRewriteWarning +from _pytest.warning_types import PytestCacheWarning +from _pytest.warning_types import PytestCollectionWarning +from _pytest.warning_types import PytestConfigWarning +from _pytest.warning_types import PytestDeprecationWarning +from _pytest.warning_types import PytestExperimentalApiWarning +from _pytest.warning_types import PytestRemovedIn8Warning +from _pytest.warning_types import PytestReturnNotNoneWarning +from _pytest.warning_types import PytestUnhandledCoroutineWarning +from _pytest.warning_types import PytestUnhandledThreadExceptionWarning +from _pytest.warning_types import PytestUnknownMarkWarning +from _pytest.warning_types import PytestUnraisableExceptionWarning +from _pytest.warning_types import PytestWarning + +set_trace = __pytestPDB.set_trace + + +__all__ = [ + "__version__", + "approx", + "Cache", + "CallInfo", + "CaptureFixture", + "Class", + "cmdline", + "Collector", + "CollectReport", + "Config", + "console_main", + "deprecated_call", + "DoctestItem", + "exit", + "ExceptionInfo", + "ExitCode", + "fail", + "File", + "fixture", + "FixtureLookupError", + "FixtureRequest", + "freeze_includes", + "Function", + "hookimpl", + "HookRecorder", + "hookspec", + "importorskip", + "Item", + "LineMatcher", + "LogCaptureFixture", + "main", + "mark", + "Mark", + "MarkDecorator", + "MarkGenerator", + "Metafunc", + "Module", + "MonkeyPatch", + "OptionGroup", + "Package", + "param", + "Parser", + "PytestAssertRewriteWarning", + "PytestCacheWarning", + "PytestCollectionWarning", + "PytestConfigWarning", + "PytestDeprecationWarning", + "PytestExperimentalApiWarning", + "PytestRemovedIn8Warning", + "PytestReturnNotNoneWarning", + "Pytester", + "PytestPluginManager", + "PytestUnhandledCoroutineWarning", + "PytestUnhandledThreadExceptionWarning", + "PytestUnknownMarkWarning", + "PytestUnraisableExceptionWarning", + "PytestWarning", + "raises", + "RecordedHookCall", + "register_assert_rewrite", + "RunResult", + "Session", + "set_trace", + "skip", + "Stash", + "StashKey", + "version_tuple", + "TempdirFactory", + "TempPathFactory", + "Testdir", + "TestReport", + "TestShortLogReport", + "UsageError", + "WarningsRecorder", + "warns", + "xfail", + "yield_fixture", +] + + +def __getattr__(name: str) -> object: + if name == "Instance": + # The import emits a deprecation warning. + from _pytest.python import Instance + + return Instance + raise AttributeError(f"module {__name__} has no attribute {name}") diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest/__main__.py b/dbdpy-env/lib/python3.9/site-packages/pytest/__main__.py new file mode 100644 index 00000000..b1701529 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest/__main__.py @@ -0,0 +1,5 @@ +"""The pytest entry point.""" +import pytest + +if __name__ == "__main__": + raise SystemExit(pytest.console_main()) diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest/py.typed b/dbdpy-env/lib/python3.9/site-packages/pytest/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/LICENSE new file mode 100644 index 00000000..f08fc453 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/LICENSE @@ -0,0 +1,22 @@ + +The MIT License (MIT) + +Copyright (c) 2018 ShopKeep Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/METADATA new file mode 100644 index 00000000..5b6c4666 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/METADATA @@ -0,0 +1,112 @@ +Metadata-Version: 2.1 +Name: pytest-black +Version: 0.3.12 +Summary: A pytest plugin to enable format checking with black +Home-page: https://github.com/shopkeep/pytest-black +Author: ShopKeep Inc +Author-email: oss@shopkeep.com +Maintainer: ShopKeep Inc +Maintainer-email: oss@shopkeep.com +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: Pytest +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Testing +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Operating System :: OS Independent +Classifier: License :: OSI Approved :: MIT License +Requires-Python: >=2.7 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: pytest (>=3.5.0) +Requires-Dist: toml +Requires-Dist: black ; python_version >= "3.6" + +pytest-black +============ + +[![Build Status](https://travis-ci.org/shopkeep/pytest-black.svg?branch=master)](https://travis-ci.org/shopkeep/pytest-black) + +A pytest plugin to enable format checking with [black](https://github.com/ambv/black). + + +Requirements +------------ + +* [pytest](https://docs.pytest.org/en/latest/) +* [black](https://github.com/ambv/black) + +There is a minimum requirement of black 19.3b0 or later. + +Installation +------------ + +``` +$ pip install pytest-black +``` + + +Usage +----- + +To run pytest with formatting checks provided by black: + +``` +$ pytest --black +``` + +The plugin will output a diff of suggested formatting changes (if any exist). Changes will _not_ be applied automatically. + + +Configuration +------------- + +You can override default black configuration options by placing a `pyproject.toml` file in your project directory. See example configuration [here](https://github.com/ambv/black/blob/master/pyproject.toml). + + +Python package management +------------------------- +For *poetry* to work correctly, include this in your pyproject.toml configuration file: + +``` +[tool.poetry.dev-dependencies] +... +black = { version = "*", allow-prereleases = true } +... +``` + +This is necessary because at the time of writing all the *black* releases in PyPI have been tagged as pre-releases (beta code), which breaks *poetry*'s dependency resolution. + + +Testing +------- + +To run the tests against a selection of Python interpreters: + +``` +$ tox +``` + +To run against a specific interpreter (e.g. Python 3.6): + +``` +$ tox -e py36 +``` + +The `tox.ini` file in the root of this repository is used to configure the test environment. + + +License +------- + +Distributed under the terms of the `MIT` license, `pytest-black` is free and open source software + + +Issues +------ + +If you encounter any problems, please [file an issue](https://github.com/shopkeep/pytest-black/issues) along with a detailed description. + + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/RECORD new file mode 100644 index 00000000..c6fbab52 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/RECORD @@ -0,0 +1,10 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pytest_black.cpython-39.pyc,, +pytest_black-0.3.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pytest_black-0.3.12.dist-info/LICENSE,sha256=wklCfk4iaWDVzDCNB1YE-mGzgq6o4Om6vtes8uqBuOc,1080 +pytest_black-0.3.12.dist-info/METADATA,sha256=9Y4w6JUnP_xWvhHLPu5KGg_kpjOxnZLtdYPlp3dc8Vw,2767 +pytest_black-0.3.12.dist-info/RECORD,, +pytest_black-0.3.12.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pytest_black-0.3.12.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +pytest_black-0.3.12.dist-info/entry_points.txt,sha256=VctP288h7dEuolJ5kiIBmNyWI_qcNZ-1FEAQYKK6rQ8,33 +pytest_black-0.3.12.dist-info/top_level.txt,sha256=ZFdWQh4rthslKfP3FJhwtLYC_vwS3YGVfEOs64jcms4,13 +pytest_black.py,sha256=aU3Zc0krbpK-meYjToMEYQtxq3QTkBKyhdxf1Jz_F08,3635 diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/WHEEL new file mode 100644 index 00000000..5bad85fd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/entry_points.txt b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/entry_points.txt new file mode 100644 index 00000000..851a766b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[pytest11] +black = pytest_black + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/top_level.txt new file mode 100644 index 00000000..4f9d4d39 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black-0.3.12.dist-info/top_level.txt @@ -0,0 +1 @@ +pytest_black diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_black.py b/dbdpy-env/lib/python3.9/site-packages/pytest_black.py new file mode 100644 index 00000000..04c80cb3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_black.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- + +# stdlib imports +import subprocess +import re +import sys + +# third-party imports +import pytest +import toml + + +HISTKEY = "black/mtimes" + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group.addoption( + "--black", action="store_true", help="enable format checking with black" + ) + + +def pytest_collect_file(path, parent): + config = parent.config + if config.option.black and path.ext == ".py": + if hasattr(BlackItem, "from_parent"): + return BlackItem.from_parent(parent, fspath=path) + else: + return BlackItem(path, parent) + + +def pytest_configure(config): + # load cached mtimes at session startup + if config.option.black and hasattr(config, "cache"): + config._blackmtimes = config.cache.get(HISTKEY, {}) + config.addinivalue_line("markers", "black: enable format checking with black") + + +def pytest_unconfigure(config): + # save cached mtimes at end of session + if hasattr(config, "_blackmtimes"): + config.cache.set(HISTKEY, config._blackmtimes) + + +class BlackItem(pytest.Item, pytest.File): + def __init__(self, fspath, parent): + super(BlackItem, self).__init__(fspath, parent) + self._nodeid += "::BLACK" + self.add_marker("black") + try: + with open("pyproject.toml") as toml_file: + settings = toml.load(toml_file)["tool"]["black"] + if "include" in settings.keys(): + settings["include"] = self._re_fix_verbose(settings["include"]) + if "exclude" in settings.keys(): + settings["exclude"] = self._re_fix_verbose(settings["exclude"]) + self.pyproject = settings + except Exception: + self.pyproject = {} + + def setup(self): + pytest.importorskip("black") + mtimes = getattr(self.config, "_blackmtimes", {}) + self._blackmtime = self.fspath.mtime() + old = mtimes.get(str(self.fspath), 0) + if self._blackmtime == old: + pytest.skip("file(s) previously passed black format checks") + + if self._skip_test(): + pytest.skip("file(s) excluded by pyproject.toml") + + def runtest(self): + cmd = [sys.executable, "-m", "black", "--check", "--diff", "--quiet", str(self.fspath)] + try: + subprocess.run( + cmd, check=True, stdout=subprocess.PIPE, universal_newlines=True + ) + except subprocess.CalledProcessError as e: + raise BlackError(e) + + mtimes = getattr(self.config, "_blackmtimes", {}) + mtimes[str(self.fspath)] = self._blackmtime + + def repr_failure(self, excinfo): + if excinfo.errisinstance(BlackError): + return excinfo.value.args[0].stdout + return super(BlackItem, self).repr_failure(excinfo) + + def reportinfo(self): + return (self.fspath, -1, "Black format check") + + def _skip_test(self): + return self._excluded() or (not self._included()) + + def _included(self): + if "include" not in self.pyproject: + return True + return re.search(self.pyproject["include"], str(self.fspath)) + + def _excluded(self): + if "exclude" not in self.pyproject: + return False + return re.search(self.pyproject["exclude"], str(self.fspath)) + + def _re_fix_verbose(self, regex): + if "\n" in regex: + regex = "(?x)" + regex + return re.compile(regex) + + def collect(self): + """ returns a list of children (items and collectors) + for this collection node. + """ + return (self,) + + +class BlackError(Exception): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/LICENSE new file mode 100644 index 00000000..b478359e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 OMOTO Tsukasa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/METADATA new file mode 100644 index 00000000..fc29dc35 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/METADATA @@ -0,0 +1,74 @@ +Metadata-Version: 2.1 +Name: pytest-pycodestyle +Version: 2.3.1 +Summary: pytest plugin to run pycodestyle +Home-page: https://github.com/henry0312/pytest-pycodestyle +Author: OMOTO Tsukasa +Author-email: tsukasa@oomo.to +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Testing +Classifier: License :: OSI Approved :: MIT License +Classifier: Framework :: Pytest +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: ~=3.7 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: pytest (>=7.0) +Requires-Dist: pycodestyle +Requires-Dist: py +Provides-Extra: tests +Requires-Dist: pytest-isort ; extra == 'tests' + +# pytest-pycodestyle + +[![PyPI version](https://badge.fury.io/py/pytest-pycodestyle.svg)](https://pypi.org/project/pytest-pycodestyle/) + +[pytest](https://docs.pytest.org/en/latest/) plugin to run [pycodestyle](https://github.com/PyCQA/pycodestyle) + +## Installation + +```sh +pip install pytest-pycodestyle +``` + +## Usage + +```sh +pytest --pycodestyle ... +``` + +For detail, please see `pytest -h` after installation. + +## Configuration + +The behavior can be configured in the same style of pycodestyle. +(cf. [Configuration — pytest documentation](https://docs.pytest.org/en/latest/customize.html) and [Configuration — pycodestyle documentation](https://pycodestyle.readthedocs.io/en/latest/intro.html#configuration)) + +For example, + +``` +[pycodestyle] +max-line-length = 127 + +[tool:pytest] +addopts = --pycodestyle +``` + +## Licence + +The MIT License +Copyright (c) 2019 OMOTO Tsukasa + +## Acknowledgments + +- [pytest-dev / pytest-pep8 — Bitbucket](https://bitbucket.org/pytest-dev/pytest-pep8) + + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/RECORD new file mode 100644 index 00000000..dcdbf118 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/RECORD @@ -0,0 +1,10 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle.cpython-39.pyc,, +pytest_pycodestyle-2.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pytest_pycodestyle-2.3.1.dist-info/LICENSE,sha256=88r1Ih3IEXnIuS_XHjFVELXUZX7mkTlC09ntRjlDR4U,1070 +pytest_pycodestyle-2.3.1.dist-info/METADATA,sha256=-FlIIb63t7PZx_AiP3SRwZ66upaYIcBPwHBSSQPQ9dU,1986 +pytest_pycodestyle-2.3.1.dist-info/RECORD,, +pytest_pycodestyle-2.3.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pytest_pycodestyle-2.3.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +pytest_pycodestyle-2.3.1.dist-info/entry_points.txt,sha256=s5NYx4Z1U6-USOikzzI6jNW2qlf9m3_4-P07uJY1seI,45 +pytest_pycodestyle-2.3.1.dist-info/top_level.txt,sha256=qfXk0sV2Vj9gvwm1f3KrGREgeYXdrQ5vTcLVDOHl6MQ,19 +pytest_pycodestyle.py,sha256=tbsv7KpK4cJHrUDmF1e2PIU1Jc7FW1tGiEVhOdatgio,3966 diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/WHEEL new file mode 100644 index 00000000..5bad85fd --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/entry_points.txt b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/entry_points.txt new file mode 100644 index 00000000..43c9234a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[pytest11] +pycodestyle = pytest_pycodestyle + diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/top_level.txt new file mode 100644 index 00000000..68d4f910 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle-2.3.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pytest_pycodestyle diff --git a/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle.py b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle.py new file mode 100644 index 00000000..5d7c2da1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/pytest_pycodestyle.py @@ -0,0 +1,98 @@ +# https://docs.pytest.org/en/latest/writing_plugins.html +# https://docs.pytest.org/en/latest/example/nonpython.html#yaml-plugin + +import optparse +import pathlib + +import py.io +import pycodestyle +import pytest + + +def pytest_addoption(parser): + group = parser.getgroup('pycodestyle') + group.addoption('--pycodestyle', action='store_true', + default=False, help='run pycodestyle') + + +def pytest_configure(config): + config.addinivalue_line('markers', 'pycodestyle: mark tests to be checked by pycodestyle.') + + +def pytest_collect_file(file_path: pathlib.Path, path, parent): + """Create a Collector for the given path, or None if not relevant. + + See: + - https://docs.pytest.org/en/7.0.x/reference/reference.html#pytest.hookspec.pytest_collect_file + """ + config = parent.config + if config.getoption('pycodestyle') and file_path.suffix == '.py': + # https://github.com/PyCQA/pycodestyle/blob/2.5.0/pycodestyle.py#L2295 + style_guide = pycodestyle.StyleGuide(paths=[str(file_path)], verbose=False) + if not style_guide.excluded(filename=str(file_path)): + return File.from_parent(parent=parent, path=file_path, style_guide_options=style_guide.options) + + +class File(pytest.File): + + @classmethod + def from_parent(cls, parent, path: pathlib.Path, style_guide_options: optparse.Values): + # https://github.com/pytest-dev/pytest/blob/3e4c14bfaa046bcb5b75903470accf83d93f01ce/src/_pytest/nodes.py#L624 + _file = super().from_parent(parent=parent, path=path) + # store options of pycodestyle + _file.style_guide_options = style_guide_options + return _file + + def collect(self): + # https://github.com/pytest-dev/pytest/blob/3e4c14bfaa046bcb5b75903470accf83d93f01ce/src/_pytest/nodes.py#L524 + yield Item.from_parent(parent=self, name=self.name, nodeid=self.nodeid) + + +class Item(pytest.Item): + CACHE_KEY = 'pycodestyle/mtimes' + + def __init__(self, name, parent, nodeid): + # https://github.com/pytest-dev/pytest/blob/ee1950af7793624793ee297e5f48b49c8bdf2065/src/_pytest/nodes.py#L544 + super().__init__(name, parent=parent, nodeid=f"{nodeid}::PYCODESTYLE") + self.add_marker('pycodestyle') + # load options of pycodestyle + self.options: optparse.Values = self.parent.style_guide_options + + def setup(self): + if not hasattr(self.config, 'cache'): + return + + old_mtime = self.config.cache.get(self.CACHE_KEY, {}).get(str(self.fspath), -1) + mtime = self.fspath.mtime() + if old_mtime == mtime: + pytest.skip('previously passed pycodestyle checks') + + def runtest(self): + # http://pycodestyle.pycqa.org/en/latest/api.html#pycodestyle.Checker + # http://pycodestyle.pycqa.org/en/latest/advanced.html + checker = pycodestyle.Checker(filename=str(self.fspath), + options=self.options) + file_errors, out, err = py.io.StdCapture.call(checker.check_all) + if file_errors > 0: + raise PyCodeStyleError(out) + elif hasattr(self.config, 'cache'): + # update cache + # http://pythonhosted.org/pytest-cache/api.html + cache = self.config.cache.get(self.CACHE_KEY, {}) + cache[str(self.fspath)] = self.fspath.mtime() + self.config.cache.set(self.CACHE_KEY, cache) + + def repr_failure(self, excinfo): + if excinfo.errisinstance(PyCodeStyleError): + return excinfo.value.args[0] + else: + return super().repr_failure(excinfo) + + def reportinfo(self): + # https://github.com/pytest-dev/pytest/blob/4678cbeb913385f00cc21b79662459a8c9fafa87/_pytest/main.py#L550 + # https://github.com/pytest-dev/pytest/blob/4678cbeb913385f00cc21b79662459a8c9fafa87/_pytest/doctest.py#L149 + return self.fspath, None, 'pycodestyle-check' + + +class PyCodeStyleError(Exception): + """custom exception for error reporting.""" diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/tests/__init__.py new file mode 100644 index 00000000..2650dbcb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/__init__.py @@ -0,0 +1,11 @@ +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +# __init__.py for the fit sdk tests module + +__version__ = '21.126.0' \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/data.py b/dbdpy-env/lib/python3.9/site-packages/tests/data.py new file mode 100644 index 00000000..f3f00fbb --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/data.py @@ -0,0 +1,647 @@ +'''data.py: Contains various byte arrays which are reused in testing the FIT SDK.''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +class Data: + '''Helper class that holds example fit files and byte arrays to be used for testing.''' + + fit_file_invalid = bytearray([ + 0x0E, 0x20, 0x9F, 0x03, 0x64, 0x00, 0x00, 0x00, + 0x2E, 0x99, 0x49, 0x54, 0xB9, 0xE3, 0x00, 0x00 + ]) + + fit_file_minimum = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x2E, 0x46, 0x49, 0x54, 0x8D, 0x48, 0x00, 0x00, + ]) + + fit_file_incorrect_data_size = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0xFF, 0x00, 0x00, 0x00, + 0x2E, 0x46, 0x49, 0x54, 0x8D, 0x48, 0x00, 0x00, + ]) + + fit_file_short = bytearray([ + 0x0E, 0x20, 0x9F, 0x03, 0x64, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0xB9, 0xE3, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x04, 0x8C, 0x04, + 0x04, 0x86, 0x08, 0x14, 0x07, 0x01, 0x02, 0x84, 0x02, 0x02, 0x84, 0x05, + 0x02, 0x84, 0x06, 0x02, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x40, 0x00, + 0x00, 0xD3, 0x00, 0x05, 0xFD, 0x04, 0x86, 0x03, 0x02, 0x84, 0x04, 0x02, + 0x84, 0x00, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0xCA, 0x9A, 0x3B, + 0x32, 0x00, 0x37, 0x00, 0x2C, 0x2E, 0x87, 0x4F + ]) + + fit_file_short_new = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x24, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x8E, 0xA3, # File Header + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x84, 0x04, 0x04, 0x86, 0x08, 0x0A, 0x07, # Message Definition + 0x00, 0x04, 0x01, 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00, # Message + 0x5D, 0xF2 # CRC + ]) + + fit_file_short_compressed_timestamp = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x24, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x8E, 0xA3, # File Header + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x84, 0x04, 0x04, 0x86, 0x08, 0x0A, 0x07, # Message Definition + 0x80, 0x04, 0x01, 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00, # Message + 0x5D, 0xF2 + ]) + + fit_file_short_new_invalid_crc = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x24, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x8E, 0xA3, # File Header + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x84, 0x04, 0x04, 0x86, 0x08, 0x0A, 0x07, # Message Definition + 0x00, 0x04, 0x01, 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00, # Message + 0xFF, 0xFF # CRC + ]) + + fit_file_short_none_array = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x24, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x8E, 0xA3, # File Header + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x84, 0x04, 0x04, 0x86, 0x08, 0x0A, 0x07, # Message Definition + 0x00, 0x04, 0x01, 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Message + 0x6C, 0x15 # CRC + ]) + + fit_file_short_with_wrong_field_def_size = bytearray([ + 0x0E, 0x20, 0x8B, 0x08, 0x21, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x8E, 0xA3, # File Header + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x84, 0x04, 0x01, 0x86, 0x08, 0x0A, 0x07, # Message Definition + 0x00, 0x04, 0x01, 0x00, 0x12, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00, # Message + 0x65, 0xFE # CRC + ]) + + fit_file_arrays = bytearray([ + 0x0E, 0x20, 0x9F, 0x03, 0x32, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0x3C, 0xF5, 0x40, 0x00, 0x01, 0x00, 0x00, 0x03, 0x01, 0x02, 0x84, 0x00, + 0x01, 0x00, 0x03, 0x04, 0x8C, 0x00, 0x00, 0xFF, 0x04, 0x00, 0x00, 0x30, + 0x39, 0x40, 0x00, 0x01, 0x00, 0x0C, 0x03, 0x03, 0x05, 0x07, 0x0A, 0x04, + 0x02, 0x13, 0x02, 0x00, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x05, 0x01, 0x5C, 0x21 + ]) + + fit_file_chained = bytearray([ + 0x0E, 0x20, 0x9F, 0x03, 0x64, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0xB9, 0xE3, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x04, 0x8C, 0x04, + 0x04, 0x86, 0x08, 0x14, 0x07, 0x01, 0x02, 0x84, 0x02, 0x02, 0x84, 0x05, + 0x02, 0x84, 0x06, 0x02, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x40, 0x00, + 0x00, 0xD3, 0x00, 0x05, 0xFD, 0x04, 0x86, 0x03, 0x02, 0x84, 0x04, 0x02, + 0x84, 0x00, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0xCA, 0x9A, 0x3B, + 0x32, 0x00, 0x37, 0x00, 0x2C, 0x2E, 0x7C, 0xD5, + 0x0E, 0x20, 0x9F, 0x03, 0x64, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0xB9, 0xE3, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x04, 0x8C, 0x04, + 0x04, 0x86, 0x08, 0x14, 0x07, 0x01, 0x02, 0x84, 0x02, 0x02, 0x84, 0x05, + 0x02, 0x84, 0x06, 0x02, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x40, 0x00, + 0x00, 0xD3, 0x00, 0x05, 0xFD, 0x04, 0x86, 0x03, 0x02, 0x84, 0x04, 0x02, + 0x84, 0x00, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0xCA, 0x9A, 0x3B, + 0x32, 0x00, 0x37, 0x00, 0x2C, 0x2E, 0x7C, 0xD5 + ]) + + fit_file_800m_repeats_little_endian = bytearray([ + 0x0E, 0x10, 0x8D, 0x08, 0xDB, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0xDE, 0xB8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, + 0x02, 0x84, 0x02, 0x02, 0x84, 0x04, 0x04, 0x86, 0x03, 0x04, 0x8C, 0x00, + 0x05, 0xFF, 0x00, 0x00, 0x00, 0x12, 0xAD, 0x66, 0x3D, 0x38, 0xB6, 0xC1, + 0x0A, 0x40, 0x00, 0x00, 0x1A, 0x00, 0x04, 0x08, 0x15, 0x07, 0x04, 0x01, + 0x00, 0x0B, 0x01, 0x00, 0x06, 0x02, 0x84, 0x00, 0x52, 0x75, 0x6E, 0x6E, + 0x69, 0x6E, 0x67, 0x20, 0x38, 0x30, 0x30, 0x6D, 0x20, 0x52, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x73, 0x00, 0x01, 0xFF, 0x05, 0x00, 0x40, 0x00, 0x00, + 0x1B, 0x00, 0x08, 0x02, 0x04, 0x86, 0xFE, 0x02, 0x84, 0x07, 0x01, 0x00, + 0x01, 0x01, 0x00, 0x03, 0x01, 0x00, 0x04, 0x04, 0x86, 0x05, 0x04, 0x86, + 0x06, 0x04, 0x86, 0x00, 0x80, 0x1A, 0x06, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x38, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x4E, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x00, 0xFF, 0x06, 0x02, 0x05, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xA0, 0x86, 0x01, 0x00, + 0x04, 0x00, 0x03, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE, 0xC4 + ]) + + fit_file_800m_repeats_big_endian = bytearray([ + 0x0E, 0x20, 0x9F, 0x03, 0xDB, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0xF2, 0xD7, 0x40, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, + 0x02, 0x84, 0x02, 0x02, 0x84, 0x04, 0x04, 0x86, 0x03, 0x04, 0x8C, 0x00, + 0x05, 0x00, 0xFF, 0x00, 0x00, 0x3D, 0x66, 0xAD, 0x12, 0x0A, 0xC1, 0xB6, + 0x38, 0x40, 0x00, 0x01, 0x00, 0x1A, 0x04, 0x08, 0x15, 0x07, 0x04, 0x01, + 0x00, 0x0B, 0x01, 0x00, 0x06, 0x02, 0x84, 0x00, 0x52, 0x75, 0x6E, 0x6E, + 0x69, 0x6E, 0x67, 0x20, 0x38, 0x30, 0x30, 0x6D, 0x20, 0x52, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x73, 0x00, 0x01, 0xFF, 0x00, 0x05, 0x40, 0x00, 0x01, + 0x00, 0x1B, 0x08, 0x02, 0x04, 0x86, 0xFE, 0x02, 0x84, 0x07, 0x01, 0x00, + 0x01, 0x01, 0x00, 0x03, 0x01, 0x00, 0x04, 0x04, 0x86, 0x05, 0x04, 0x86, + 0x06, 0x04, 0x86, 0x00, 0x00, 0x06, 0x1A, 0x80, 0x00, 0x00, 0x02, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x38, 0x80, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4E, 0x20, 0x00, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x03, 0xFF, 0x06, 0x02, 0x00, 0x00, 0x00, 0x05, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x86, 0xA0, + 0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x67 + ]) + + fit_file_dev_data_missing_field_description = bytearray([ + 0x0E, 0x20, 0x64, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0x12, 0x7E, 0x40, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, + 0x02, 0x84, 0x02, 0x02, 0x84, 0x04, 0x04, 0x86, 0x03, 0x04, 0x8C, 0x00, + 0x04, 0x00, 0xFF, 0x00, 0x00, 0x3D, 0x5D, 0x38, 0xBD, 0x1E, 0x29, 0x25, + 0x9B, 0x60, 0x00, 0x01, 0x00, 0x14, 0x09, 0xFD, 0x04, 0x86, 0x05, 0x04, + 0x86, 0x06, 0x02, 0x84, 0x03, 0x01, 0x02, 0x04, 0x01, 0x02, 0x07, 0x02, + 0x84, 0x02, 0x02, 0x84, 0x00, 0x04, 0x85, 0x01, 0x04, 0x85, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x3D, 0x5D, 0x38, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xE8, 0x7E, 0x00, 0x00, 0x96, 0x07, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7E, 0x00, 0x3D, 0x5D, 0x38, 0xBE, 0x00, 0x00, 0x00, + 0x64, 0x03, 0xE8, 0x86, 0x01, 0x00, 0x96, 0x07, 0x4E, 0x7F, 0xFF, 0xFF, + 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x86, 0x00, 0x3D, 0x5D, 0x38, 0xBF, 0x00, + 0x00, 0x00, 0xC8, 0x03, 0xE8, 0x8E, 0x02, 0x00, 0x96, 0x07, 0x53, 0x7F, + 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x8E, 0x00, 0x3D, 0x5D, 0x38, + 0xC0, 0x00, 0x00, 0x01, 0x2C, 0x03, 0xE8, 0x96, 0x03, 0x00, 0x96, 0x07, + 0x58, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x96, 0x40, 0x00, + 0x01, 0x00, 0x22, 0x04, 0xFD, 0x04, 0x86, 0x01, 0x02, 0x84, 0x05, 0x04, + 0x86, 0x00, 0x04, 0x86, 0x00, 0x3D, 0x5D, 0x46, 0xCD, 0x00, 0x01, 0x3D, + 0x5C, 0xF2, 0x6D, 0x00, 0x36, 0xEE, 0x80, 0x78, 0x3B + ]) + + fit_file_monitoring = bytearray([ + 0x0E, 0x10, 0x28, 0x23, 0x37, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0x2C, 0xC6, 0x41, 0x00, 0x01, 0x00, 0x37, 0x03, 0xFD, 0x04, 0x86, 0x18, + 0x01, 0x0D, 0x03, 0x04, 0x86, 0x01, 0x3F, 0x2A, 0xE2, 0xFF, 0x61, 0x00, + 0x00, 0x00, 0x14, 0x01, 0x3F, 0x2A, 0xE2, 0xFF, 0x06, 0x00, 0x00, 0x00, + 0x3C, 0x01, 0x3F, 0x2A, 0xE2, 0xFF, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x01, + 0x3F, 0x2A, 0xE2, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1E, 0xED, 0xF9 + ]) + + fit_file_messages_with_no_fields = bytearray([ + 0x0E, 0x20, 0x84, 0x52, 0x44, 0x00, 0x00, 0x00, 0x2E, 0x46, 0x49, 0x54, + 0x3A, 0x18, 0x40, 0x00, 0x01, 0x00, 0x69, 0x00, 0x41, 0x00, 0x01, 0x00, + 0x00, 0x07, 0x03, 0x04, 0x8C, 0x04, 0x04, 0x86, 0x01, 0x02, 0x84, 0x02, + 0x02, 0x84, 0x05, 0x02, 0x84, 0x00, 0x01, 0x00, 0xFB, 0x01, 0x0D, 0x01, + 0xCD, 0xC3, 0x1F, 0xAE, 0x3F, 0x92, 0x50, 0x78, 0x00, 0x01, 0x10, 0x22, + 0x00, 0x00, 0x20, 0xFF, 0x00, 0x01, 0xCD, 0xC3, 0x1F, 0xAE, 0x3F, 0x92, + 0x50, 0x78, 0x00, 0x01, 0x10, 0x22, 0x00, 0x00, 0x20, 0xFF, 0x25, 0xFB + ]) + + gear_change_data = [ + { + "timestamp": 1024873717, + "rear_gear_num": 5, + "rear_gear": 24, + "front_gear_num": 255, + "front_gear": 22, + "data": 385816581, + "gear_change_data": 385816581 + }, + { + "timestamp": 1024873760, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024873819, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024873850, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024874601, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024874624, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024874694, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024874698, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024874727, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024874755, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024874824, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024874829, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024874864, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024874913, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024874927, + "rear_gear_num": 4, + "rear_gear": 27, + "front_gear_num": 255, + "front_gear": None, + "data": 16718596, + "gear_change_data": 16718596 + }, + { + "timestamp": 1024875097, + "rear_gear_num": 5, + "rear_gear": 24, + "front_gear_num": 255, + "front_gear": None, + "data": 16717829, + "gear_change_data": 16717829 + }, + { + "timestamp": 1024875097, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024875111, + "rear_gear_num": 5, + "rear_gear": 24, + "front_gear_num": 255, + "front_gear": None, + "data": 16717829, + "gear_change_data": 16717829 + }, + { + "timestamp": 1024875126, + "rear_gear_num": 4, + "rear_gear": 27, + "front_gear_num": 255, + "front_gear": None, + "data": 16718596, + "gear_change_data": 16718596 + }, + { + "timestamp": 1024875251, + "rear_gear_num": 3, + "rear_gear": 31, + "front_gear_num": 255, + "front_gear": None, + "data": 16719619, + "gear_change_data": 16719619 + }, + { + "timestamp": 1024875265, + "rear_gear_num": 4, + "rear_gear": 27, + "front_gear_num": 255, + "front_gear": None, + "data": 16718596, + "gear_change_data": 16718596 + }, + { + "timestamp": 1024875271, + "rear_gear_num": 5, + "rear_gear": 24, + "front_gear_num": 255, + "front_gear": None, + "data": 16717829, + "gear_change_data": 16717829 + }, + { + "timestamp": 1024875291, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024875364, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024875388, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024875423, + "rear_gear_num": 9, + "rear_gear": 15, + "front_gear_num": 255, + "front_gear": None, + "data": 16715529, + "gear_change_data": 16715529 + }, + { + "timestamp": 1024875515, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024875589, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024875615, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024875616, + "rear_gear_num": 9, + "rear_gear": 15, + "front_gear_num": 255, + "front_gear": None, + "data": 16715529, + "gear_change_data": 16715529 + }, + { + "timestamp": 1024875621, + "rear_gear_num": 10, + "rear_gear": 13, + "front_gear_num": 255, + "front_gear": None, + "data": 16715018, + "gear_change_data": 16715018 + }, + { + "timestamp": 1024875622, + "rear_gear_num": 11, + "rear_gear": 11, + "front_gear_num": 255, + "front_gear": None, + "data": 16714507, + "gear_change_data": 16714507 + }, + { + "timestamp": 1024875651, + "rear_gear_num": 9, + "rear_gear": 15, + "front_gear_num": 255, + "front_gear": None, + "data": 16715529, + "gear_change_data": 16715529 + }, + { + "timestamp": 1024875658, + "rear_gear_num": 8, + "rear_gear": 17, + "front_gear_num": 255, + "front_gear": None, + "data": 16716040, + "gear_change_data": 16716040 + }, + { + "timestamp": 1024875658, + "rear_gear_num": 7, + "rear_gear": 19, + "front_gear_num": 255, + "front_gear": None, + "data": 16716551, + "gear_change_data": 16716551 + }, + { + "timestamp": 1024875665, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": None, + "data": 16717062, + "gear_change_data": 16717062 + }, + { + "timestamp": 1024875695, + "rear_gear_num": 6, + "rear_gear": 21, + "front_gear_num": 255, + "front_gear": 22, + "data": 385815814, + "gear_change_data": 385815814 + } +] + + hrm_plugin_test_activity_expected = [ + 1242209, + 1242212.0, 1242213.7314453125, 1242215.5029296875, 1242215.865234375, 1242216.9541015625, 1242218.3369140625, 1242219.6220703125, 1242219.9853515625, + 1242220.71875, 1242221.2607421875, 1242221.83203125, 1242222.103515625, 1242222.970703125, 1242223.849609375, 1242224.234375, 1242225.193359375, + 1242225.537109375, 1242226.345703125, 1242226.9990234375, 1242227.599609375, 1242227.978515625, 1242228.5849609375, 1242228.962890625, 1242229.291015625, + 1242229.8154296875, 1242230.1708984375, 1242230.630859375, 1242230.9794921875, 1242231.3359375, 1242231.7421875, 1242232.041015625, 1242232.517578125, + 1242232.93359375, 1242233.2890625, 1242233.6767578125, 1242234.0703125, 1242234.4638671875, 1242234.9033203125, 1242235.23828125, 1242235.625, + 1242236.0126953125, 1242236.28125, 1242236.6396484375, 1242237.56640625, 1242239.478515625, 1242240.4189453125, 1242241.388671875, 1242242.35546875, + 1242244.2861328125, 1242245.2841796875, 1242246.279296875, 1242247.2900390625, 1242248.3251953125, 1242249.36328125, 1242250.736328125, 1242251.0703125, + 1242251.1640625, 1242251.921875, 1242252.546875, 1242253.5751953125, 1242254.6064453125, 1242255.6201171875, 1242256.626953125, 1242257.568359375, + 1242258.5009765625, 1242259.509765625, 1242260.5712890625, 1242261.142578125, 1242261.66796875, 1242262.72265625, 1242263.7890625, 1242264.869140625, + 1242265.951171875, 1242266.9794921875, 1242268.0087890625, 1242269.0380859375, 1242270.046875, 1242271.0712890625, 1242272.162109375, 1242273.3310546875, + 1242274.494140625, 1242275.6552734375, 1242276.802734375, 1242277.8896484375, 1242278.9677734375, 1242280.048828125, 1242281.115234375, 1242282.1796875, + 1242283.25, 1242284.296875, 1242285.30859375, 1242286.3388671875, 1242287.40625, 1242288.45703125, 1242289.4921875, 1242290.5458984375, + 1242291.5986328125, 1242292.62109375, 1242293.65625, 1242294.6943359375, 1242295.7236328125, 1242296.7744140625, 1242297.849609375, 1242298.5556640625, + 1242299.51953125, 1242300.2177734375, 1242301.1015625, 1242302.2080078125, 1242303.3037109375, 1242304.3857421875, 1242305.453125, 1242306.4921875, + 1242307.544921875, 1242308.609375, 1242309.6494140625, 1242310.6845703125, 1242311.732421875, 1242312.775390625, 1242313.8115234375, 1242314.8408203125, + 1242315.859375, 1242316.9033203125, 1242317.9716796875, 1242319.04296875, 1242320.0966796875, 1242321.1630859375, 1242322.1953125, 1242323.2197265625, + 1242324.2373046875, 1242325.2265625, 1242326.1767578125, 1242327.123046875, 1242328.013671875, 1242328.6884765625, 1242329.87109375, 1242330.8564453125, + 1242331.814453125, 1242332.830078125, 1242333.8212890625, 1242334.83203125, 1242335.818359375, 1242336.8076171875, 1242337.78515625, 1242338.7470703125, + 1242339.7216796875, 1242340.6982421875, 1242341.6806640625, 1242342.6708984375, 1242343.666015625, 1242344.6630859375, 1242345.685546875, 1242346.7275390625, + 1242347.77734375, 1242348.791015625, 1242349.7216796875, 1242350.5986328125, 1242351.5146484375, 1242352.513671875, 1242353.6279296875, 1242354.7880859375, + 1242355.931640625, 1242357.0771484375, 1242358.205078125, 1242359.259765625, 1242360.314453125, 1242361.353515625, 1242362.4091796875, 1242363.470703125, + 1242364.474609375, 1242365.4462890625, 1242366.568359375, 1242367.7119140625, 1242368.8740234375, 1242369.982421875, 1242369.982421875, 1242369.982421875, + 1242371, + 1242372.0, 1242373.0419921875, 1242374.0595703125, 1242375.05078125, 1242376.0244140625, 1242376.9765625, 1242378.0068359375, 1242379.0810546875, + 1242380.2138671875, 1242381.3935546875, 1242382.5712890625, 1242383.7431640625, 1242384.8720703125, 1242385.97265625, 1242387.052734375, 1242388.087890625, + 1242389.091796875, 1242390.1025390625, 1242391.1162109375, 1242392.1533203125, 1242393.1689453125, 1242394.20703125, 1242395.2685546875, 1242396.3369140625, + 1242397.40625, 1242398.4853515625, 1242399.5390625, 1242400.5693359375, 1242401.5380859375, 1242402.552734375, 1242403.6220703125, 1242404.7431640625, + 1242405.86328125, 1242407.0126953125, 1242408.162109375, 1242409.2705078125, 1242410.3994140625, 1242411.5, 1242412.537109375, 1242413.5380859375, + 1242414.4072265625, 1242415.48046875, 1242416.5419921875, 1242417.6337890625, 1242418.68359375, 1242419.787109375, 1242420.8564453125, 1242421.9287109375, + 1242423.005859375, 1242424.02734375, 1242425.076171875, 1242426.12109375, 1242427.1767578125, 1242428.25, 1242429.3076171875, 1242430.3662109375, + 1242431.41015625, 1242432.4521484375, 1242433.4482421875, 1242434.455078125, 1242435.5009765625, 1242436.58984375, 1242437.6796875, 1242438.79296875, + 1242439.8974609375, 1242441.0107421875, 1242442.1044921875, 1242443.228515625, 1242444.3642578125, 1242445.474609375, 1242446.5673828125, 1242447.328125, + 1242448.6318359375, 1242449.6572265625, 1242450.7001953125, 1242451.7587890625, 1242452.8447265625, 1242453.94140625, 1242455.126953125, 1242456.3349609375, + 1242457.541015625, 1242458.7265625, 1242459.9248046875, 1242461.1240234375, 1242462.2998046875, 1242463.4736328125, 1242464.650390625, 1242465.81640625, + 1242466.9931640625, 1242468.1953125, 1242469.3505859375, 1242470.5322265625, 1242471.7412109375, 1242472.94140625, 1242474.1318359375, 1242475.3251953125, + 1242476.5107421875, 1242477.6181640625, 1242478.712890625, 1242479.8349609375, 1242480.9765625, 1242482.10546875, 1242483.21875, 1242484.33984375, + 1242485.396484375, 1242486.486328125, 1242487.6201171875, 1242488.7890625, 1242489.9208984375, 1242491.0703125, 1242492.2373046875, 1242493.4111328125, + 1242494.5732421875, 1242495.7470703125, 1242496.919921875, 1242498.0927734375, 1242499.2978515625, 1242500.4833984375, 1242501.65234375, 1242502.84765625, + 1242504.0380859375, 1242505.185546875, 1242506.326171875, 1242507.306640625, 1242508.5546875, 1242509.6640625, 1242510.7578125, 1242511.8408203125, + 1242512.943359375, 1242514.0673828125, 1242515.19921875, 1242516.3330078125, 1242517.4306640625, 1242518.533203125, 1242519.6357421875, 1242520.7138671875, + 1242521.80859375, 1242522.91015625, 1242523.9892578125, 1242525.08984375, 1242526.20703125, 1242527.3232421875, 1242528.4365234375, 1242529.53515625, + 1242530.6279296875, 1242531.673828125, 1242532.7119140625, 1242533.759765625, 1242534.8017578125, 1242535.83203125, 1242536.8779296875, 1242537.9150390625, + 1242538.9453125, 1242539.982421875, 1242540.98828125, 1242542.01171875, 1242543.0478515625, 1242544.1103515625, 1242545.2109375, 1242546.3203125, + 1242547.4580078125, 1242548.6123046875, 1242549.7822265625, 1242550.9775390625, 1242552.1669921875, 1242553.3349609375, 1242554.5078125, 1242555.6220703125, + 1242556.63671875, 1242557.666015625, 1242558.77734375, 1242559.89453125, 1242561.0458984375, 1242562.2314453125, 1242563.38671875, 1242564.5478515625, + 1242565.7177734375, 1242566.87109375, 1242568.041015625, 1242569.2255859375, 1242570.392578125, 1242571.5810546875, 1242572.79296875, 1242573.93359375, + 1242575.0634765625, 1242576.2080078125, 1242577.33203125, 1242578.447265625, 1242579.5517578125, 1242580.6748046875, 1242581.8388671875, 1242582.9521484375, + 1242584.0771484375, 1242585.220703125, 1242586.34375, 1242587.474609375, 1242588.6162109375, 1242589.7529296875, 1242590.9287109375, 1242592.11328125, + 1242593.3251953125, 1242594.53515625, 1242595.7724609375, 1242596.9892578125, 1242598.1728515625, 1242599.3134765625, 1242600.4345703125, 1242601.4814453125, + 1242602.4345703125, 1242603.390625, 1242604.404296875, 1242605.4287109375, 1242606.44921875, 1242607.4765625, 1242608.5234375, 1242609.35546875, + 1242609.8701171875, 1242610.9150390625, 1242611.9345703125, 1242612.939453125, 1242613.8974609375, 1242614.3642578125, 1242615.4052734375, 1242616.30078125, + 1242617.1884765625, 1242618.3427734375, 1242619.396484375, 1242619.9580078125, 1242621.015625, 1242621.939453125, 1242622.609375, 1242623.1474609375, + 1242623.92578125, 1242624.7041015625, 1242625.482421875, 1242626.5693359375, 1242627.5361328125, 1242628.419921875, 1242629.4208984375, 1242630.4853515625, + 1242631.486328125, 1242632.6103515625, 1242633.177734375, 1242633.8720703125, 1242634.8076171875, 1242635.220703125, 1242636.041015625, 1242636.732421875, + 1242637.4638671875, 1242638.1318359375, 1242638.765625, 1242639.2099609375, 1242639.8291015625, 1242640.5673828125, 1242640.9833984375, 1242641.58203125, + 1242642.1806640625, 1242642.6279296875, 1242643.330078125, 1242643.92578125, 1242644.515625, 1242645.1103515625, 1242645.5888671875, 1242646.17578125, + 1242646.74609375, 1242647.3330078125, 1242647.9072265625, 1242648.5498046875, 1242649.166015625, 1242649.681640625, 1242650.4130859375, 1242651.2177734375, + 1242651.8798828125, 1242652.744140625, 1242653.45703125, 1242654.244140625, 1242654.9755859375, 1242655.544921875, 1242656.203125, 1242656.8857421875, + 1242657.6220703125, 1242658.3173828125, 1242659.0693359375, 1242659.779296875, 1242660.4892578125, 1242661.1982421875, 1242662.560546875, 1242662.869140625, + 1242663.185546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, + 1242959, + 1242960.0, 1242962.28515625, 1242963.3388671875, 1242964.3212890625, 1242965.3193359375, 1242966.2392578125, 1242967.150390625, 1242968.0263671875, + 1242969.041015625, 1242969.5400390625, 1242970.552734375, 1242971.1083984375, 1242972.1123046875, 1242973.158203125, 1242973.439453125, 1242973.9423828125, + 1242974.7841796875, 1242975.8095703125, 1242976.6220703125, 1242977.3203125, 1242978.3544921875, 1242979.2958984375, 1242980.1875, 1242981.12890625, + 1242982.130859375, 1242983.130859375, 1242984.1640625, 1242985.2080078125, 1242986.33203125, 1242987.5859375, 1242988.6240234375, 1242989.298828125, + 1242990.4794921875, 1242991.49609375, 1242992.0546875, 1242992.6044921875, 1242993.2138671875, 1242993.474609375, 1242994.2900390625, 1242994.9638671875, + 1242995.2333984375, 1242995.810546875, 1242996.0703125, 1242996.724609375, 1242997.26171875, 1242997.7607421875, 1242998.0234375, 1242998.400390625, + 1242998.8408203125, 1242999.455078125, 1242999.943359375, 1243000.59765625, 1243001.2041015625, 1243001.748046875, 1243002.2939453125, 1243002.8583984375, + 1243003.5771484375, 1243004.2158203125, 1243004.8154296875, 1243005.2958984375, 1243005.9736328125, 1243006.2998046875, 1243006.9052734375, 1243007.490234375, + 1243008.0478515625, 1243008.818359375, 1243009.2353515625, 1243009.9482421875, 1243010.71875, 1243011.47265625, 1243012.20703125, 1243012.9541015625, + 1243013.701171875, 1243014.4716796875, 1243015.236328125, 1243016.005859375, 1243016.6005859375, 1243017.5107421875, 1243018.248046875, 1243018.876953125, + 1243019.7783203125, 1243020.5439453125, 1243021.337890625, 1243022.1103515625, 1243022.931640625, 1243023.73046875, 1243024.5263671875, 1243025.3125, + 1243026.12890625, 1243026.6640625, 1243027.3427734375, 1243027.7578125, 1243028.578125, 1243029.4013671875, 1243030.1923828125, 1243031.0107421875, + 1243031.8251953125, 1243032.62890625, 1243033.40625, 1243034.197265625, 1243034.982421875, 1243035.8359375, 1243036.56640625, 1243037.3828125, + 1243038.197265625, 1243039.0830078125, 1243039.9013671875, 1243040.7587890625, 1243041.333984375, 1243042.330078125, 1243043.4169921875, 1243044.494140625, + 1243045.0302734375, 1243045.888671875, 1243046.4521484375, 1243047.0185546875, 1243047.5419921875, 1243048.1904296875, 1243048.619140625, 1243049.40234375, + 1243049.8798828125, 1243050.65625, 1243051.419921875, 1243052.0634765625, 1243052.9853515625, 1243053.783203125, 1243054.595703125, 1243055.4287109375, + 1243056.26171875, 1243057.1005859375, 1243057.92578125, 1243058.7275390625, 1243059.4921875, 1243060.2705078125, 1243061.0703125, 1243061.8583984375, + 1243062.6826171875, 1243063.5068359375, 1243064.3251953125, 1243065.146484375, 1243065.998046875, 1243066.880859375, 1243067.748046875, 1243068.626953125, + 1243069.509765625, 1243070.400390625, 1243071.251953125, 1243072.125, 1243072.984375, 1243073.86328125, 1243074.6982421875, 1243075.576171875, + 1243076.4404296875, 1243077.3369140625, 1243078.224609375, 1243079.2919921875, 1243079.97265625, 1243080.8681640625, 1243081.76953125, 1243082.71484375, + 1243083.6669921875, 1243084.6142578125, 1243085.5546875, 1243086.474609375, 1243087.390625, 1243088.2919921875, 1243089.197265625, 1243090.0693359375, + 1243090.9384765625, 1243091.8349609375, 1243092.751953125, 1243093.716796875, 1243094.640625, 1243095.576171875, 1243096.50390625, 1243097.400390625, + 1243098.2666015625, 1243099.16796875, 1243100.0771484375, 1243100.9423828125, 1243101.8251953125, 1243102.7099609375, 1243103.6357421875, 1243104.544921875, + 1243105.462890625, 1243106.357421875, 1243107.283203125, 1243108.162109375, 1243109.291015625, 1243109.92578125, 1243110.8173828125, 1243111.69921875, + 1243112.591796875, 1243113.484375, 1243114.3818359375, 1243115.3056640625, 1243116.1572265625, 1243117.0439453125, 1243117.9130859375, 1243118.759765625, + 1243119.619140625, 1243120.49609375, 1243121.3037109375, 1243122.15625, 1243122.9951171875, 1243123.8408203125, 1243124.6572265625, 1243125.5234375, + 1243126.4296875, 1243127.345703125, 1243128.24609375, 1243129.1162109375, 1243129.9873046875, 1243130.8427734375, 1243131.693359375, 1243132.537109375, + 1243133.392578125, 1243134.2099609375, 1243135.0498046875, 1243135.8857421875, 1243136.6962890625, 1243137.5595703125, 1243138.41015625, 1243139.1396484375, + 1243140.056640625, 1243141.23046875, 1243142.0625, 1243142.68359375, 1243143.3212890625, 1243144.1484375, 1243145.0078125, 1243145.8818359375, + 1243146.7666015625, 1243147.6484375, 1243148.5732421875, 1243149.482421875, 1243150.423828125, 1243151.373046875, 1243152.3349609375, 1243153.25, + 1243154.19140625, 1243155.1259765625, 1243156.0615234375, 1243157.0126953125, 1243157.9677734375, 1243158.9013671875, 1243159.8447265625, 1243160.779296875, + 1243161.6953125, 1243162.6357421875, 1243163.60546875, 1243164.5810546875, 1243165.5107421875, 1243166.4619140625, 1243167.3974609375, 1243168.33984375, + 1243169.1240234375, 1243170.2392578125, 1243171.1533203125, 1243172.0419921875, 1243172.9208984375, 1243173.6552734375, 1243174.66015625, 1243175.5439453125, + 1243176.466796875, 1243177.404296875, 1243178.35546875, 1243179.318359375, 1243180.25, 1243181.1796875, 1243182.0869140625, 1243183.0, + 1243183.9267578125, 1243184.849609375, 1243185.75, 1243186.6474609375, 1243187.546875, 1243188.4638671875, 1243189.3857421875, 1243190.2900390625, + 1243191.1982421875, 1243192.091796875, 1243192.978515625, 1243193.818359375, 1243194.638671875, 1243195.4541015625, 1243196.2802734375, 1243197.1318359375, + 1243198.0029296875, 1243198.8828125, 1243199.7529296875, 1243200.6591796875, 1243201.5380859375, 1243202.447265625, 1243203.3681640625, 1243204.236328125, + 1243205.1572265625, 1243206.103515625, 1243207.09765625, 1243208.09765625, 1243209.115234375, 1243210.1513671875, 1243211.1650390625, 1243212.1845703125, + 1243213.208984375, 1243214.201171875, 1243215.1787109375, 1243216.1171875, 1243217.0703125, 1243218.0224609375, 1243218.9775390625, 1243219.9580078125, + 1243220.9599609375, 1243221.953125, 1243222.8662109375, 1243223.7861328125, 1243224.69921875, 1243225.6396484375, 1243226.541015625, 1243227.4970703125, + 1243228.4462890625, 1243229.2880859375, 1243230.248046875, 1243231.1767578125, 1243232.1533203125, 1243233.0966796875, 1243234.033203125, 1243234.9755859375, + 1243235.919921875, 1243236.837890625, 1243237.71875, 1243238.6357421875, 1243239.5068359375, 1243240.43359375, 1243241.3515625, 1243242.26953125, + 1243243.107421875, 1243244.044921875, 1243244.9619140625, 1243245.94921875, 1243246.9560546875, 1243247.96484375, 1243249.080078125, 1243249.9404296875, + 1243250.89453125, 1243251.8291015625, 1243252.744140625, 1243253.6474609375, 1243254.55078125, 1243255.46484375, 1243256.3544921875, 1243257.2412109375, + 1243258.1591796875, 1243259.27734375, 1243260.03515625, 1243260.9609375, 1243261.9052734375, 1243262.791015625, 1243263.6513671875, 1243264.478515625, + 1243265.25, 1243266.01953125, 1243266.7841796875, 1243267.5302734375, 1243268.26953125, 1243269.0107421875, 1243269.751953125, 1243270.4755859375, + 1243271.1796875, 1243271.876953125, 1243272.5615234375, 1243273.2373046875, 1243273.9189453125, 1243274.591796875, 1243275.2490234375, 1243275.9033203125, + 1243276.595703125, 1243277.2861328125, 1243277.96484375, 1243278.626953125, 1243279.3115234375, 1243279.98046875, 1243280.6591796875, 1243281.3291015625, + 1243281.9873046875, 1243282.6435546875, 1243283.287109375, 1243283.9296875, 1243284.587890625, 1243285.2509765625, 1243285.904296875, 1243286.5712890625, + 1243287.228515625, 1243287.8857421875, 1243288.55859375, 1243289.1240234375, 1243289.76171875, 1243290.3994140625, 1243291.037109375, 1243291.6748046875, + 1243292.0361328125, 1243292.7470703125, 1243293.453125, 1243294.1689453125, 1243294.8798828125, 1243295.58203125, 1243296.2900390625, 1243296.9912109375, + 1243297.6904296875, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, +] diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/data_expand_hr_mesgs.py b/dbdpy-env/lib/python3.9/site-packages/tests/data_expand_hr_mesgs.py new file mode 100644 index 00000000..02c0e5b5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/data_expand_hr_mesgs.py @@ -0,0 +1,16012 @@ +'''data_expand_hr_mesgs.py: Contains the data for running the hr_mesgs_utils tests''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +component_expansion_of_hr_messages = [ + 1242209, + 1242212.0, 1242213.7314453125, 1242215.5029296875, 1242215.865234375, 1242216.9541015625, 1242218.3369140625, 1242219.6220703125, 1242219.9853515625, + 1242220.71875, 1242221.2607421875, 1242221.83203125, 1242222.103515625, 1242222.970703125, 1242223.849609375, 1242224.234375, 1242225.193359375, + 1242225.537109375, 1242226.345703125, 1242226.9990234375, 1242227.599609375, 1242227.978515625, 1242228.5849609375, 1242228.962890625, 1242229.291015625, + 1242229.8154296875, 1242230.1708984375, 1242230.630859375, 1242230.9794921875, 1242231.3359375, 1242231.7421875, 1242232.041015625, 1242232.517578125, + 1242232.93359375, 1242233.2890625, 1242233.6767578125, 1242234.0703125, 1242234.4638671875, 1242234.9033203125, 1242235.23828125, 1242235.625, + 1242236.0126953125, 1242236.28125, 1242236.6396484375, 1242237.56640625, 1242239.478515625, 1242240.4189453125, 1242241.388671875, 1242242.35546875, + 1242244.2861328125, 1242245.2841796875, 1242246.279296875, 1242247.2900390625, 1242248.3251953125, 1242249.36328125, 1242250.736328125, 1242251.0703125, + 1242251.1640625, 1242251.921875, 1242252.546875, 1242253.5751953125, 1242254.6064453125, 1242255.6201171875, 1242256.626953125, 1242257.568359375, + 1242258.5009765625, 1242259.509765625, 1242260.5712890625, 1242261.142578125, 1242261.66796875, 1242262.72265625, 1242263.7890625, 1242264.869140625, + 1242265.951171875, 1242266.9794921875, 1242268.0087890625, 1242269.0380859375, 1242270.046875, 1242271.0712890625, 1242272.162109375, 1242273.3310546875, + 1242274.494140625, 1242275.6552734375, 1242276.802734375, 1242277.8896484375, 1242278.9677734375, 1242280.048828125, 1242281.115234375, 1242282.1796875, + 1242283.25, 1242284.296875, 1242285.30859375, 1242286.3388671875, 1242287.40625, 1242288.45703125, 1242289.4921875, 1242290.5458984375, + 1242291.5986328125, 1242292.62109375, 1242293.65625, 1242294.6943359375, 1242295.7236328125, 1242296.7744140625, 1242297.849609375, 1242298.5556640625, + 1242299.51953125, 1242300.2177734375, 1242301.1015625, 1242302.2080078125, 1242303.3037109375, 1242304.3857421875, 1242305.453125, 1242306.4921875, + 1242307.544921875, 1242308.609375, 1242309.6494140625, 1242310.6845703125, 1242311.732421875, 1242312.775390625, 1242313.8115234375, 1242314.8408203125, + 1242315.859375, 1242316.9033203125, 1242317.9716796875, 1242319.04296875, 1242320.0966796875, 1242321.1630859375, 1242322.1953125, 1242323.2197265625, + 1242324.2373046875, 1242325.2265625, 1242326.1767578125, 1242327.123046875, 1242328.013671875, 1242328.6884765625, 1242329.87109375, 1242330.8564453125, + 1242331.814453125, 1242332.830078125, 1242333.8212890625, 1242334.83203125, 1242335.818359375, 1242336.8076171875, 1242337.78515625, 1242338.7470703125, + 1242339.7216796875, 1242340.6982421875, 1242341.6806640625, 1242342.6708984375, 1242343.666015625, 1242344.6630859375, 1242345.685546875, 1242346.7275390625, + 1242347.77734375, 1242348.791015625, 1242349.7216796875, 1242350.5986328125, 1242351.5146484375, 1242352.513671875, 1242353.6279296875, 1242354.7880859375, + 1242355.931640625, 1242357.0771484375, 1242358.205078125, 1242359.259765625, 1242360.314453125, 1242361.353515625, 1242362.4091796875, 1242363.470703125, + 1242364.474609375, 1242365.4462890625, 1242366.568359375, 1242367.7119140625, 1242368.8740234375, 1242369.982421875, 1242369.982421875, 1242369.982421875, + 1242371, + 1242372.0, 1242373.0419921875, 1242374.0595703125, 1242375.05078125, 1242376.0244140625, 1242376.9765625, 1242378.0068359375, 1242379.0810546875, + 1242380.2138671875, 1242381.3935546875, 1242382.5712890625, 1242383.7431640625, 1242384.8720703125, 1242385.97265625, 1242387.052734375, 1242388.087890625, + 1242389.091796875, 1242390.1025390625, 1242391.1162109375, 1242392.1533203125, 1242393.1689453125, 1242394.20703125, 1242395.2685546875, 1242396.3369140625, + 1242397.40625, 1242398.4853515625, 1242399.5390625, 1242400.5693359375, 1242401.5380859375, 1242402.552734375, 1242403.6220703125, 1242404.7431640625, + 1242405.86328125, 1242407.0126953125, 1242408.162109375, 1242409.2705078125, 1242410.3994140625, 1242411.5, 1242412.537109375, 1242413.5380859375, + 1242414.4072265625, 1242415.48046875, 1242416.5419921875, 1242417.6337890625, 1242418.68359375, 1242419.787109375, 1242420.8564453125, 1242421.9287109375, + 1242423.005859375, 1242424.02734375, 1242425.076171875, 1242426.12109375, 1242427.1767578125, 1242428.25, 1242429.3076171875, 1242430.3662109375, + 1242431.41015625, 1242432.4521484375, 1242433.4482421875, 1242434.455078125, 1242435.5009765625, 1242436.58984375, 1242437.6796875, 1242438.79296875, + 1242439.8974609375, 1242441.0107421875, 1242442.1044921875, 1242443.228515625, 1242444.3642578125, 1242445.474609375, 1242446.5673828125, 1242447.328125, + 1242448.6318359375, 1242449.6572265625, 1242450.7001953125, 1242451.7587890625, 1242452.8447265625, 1242453.94140625, 1242455.126953125, 1242456.3349609375, + 1242457.541015625, 1242458.7265625, 1242459.9248046875, 1242461.1240234375, 1242462.2998046875, 1242463.4736328125, 1242464.650390625, 1242465.81640625, + 1242466.9931640625, 1242468.1953125, 1242469.3505859375, 1242470.5322265625, 1242471.7412109375, 1242472.94140625, 1242474.1318359375, 1242475.3251953125, + 1242476.5107421875, 1242477.6181640625, 1242478.712890625, 1242479.8349609375, 1242480.9765625, 1242482.10546875, 1242483.21875, 1242484.33984375, + 1242485.396484375, 1242486.486328125, 1242487.6201171875, 1242488.7890625, 1242489.9208984375, 1242491.0703125, 1242492.2373046875, 1242493.4111328125, + 1242494.5732421875, 1242495.7470703125, 1242496.919921875, 1242498.0927734375, 1242499.2978515625, 1242500.4833984375, 1242501.65234375, 1242502.84765625, + 1242504.0380859375, 1242505.185546875, 1242506.326171875, 1242507.306640625, 1242508.5546875, 1242509.6640625, 1242510.7578125, 1242511.8408203125, + 1242512.943359375, 1242514.0673828125, 1242515.19921875, 1242516.3330078125, 1242517.4306640625, 1242518.533203125, 1242519.6357421875, 1242520.7138671875, + 1242521.80859375, 1242522.91015625, 1242523.9892578125, 1242525.08984375, 1242526.20703125, 1242527.3232421875, 1242528.4365234375, 1242529.53515625, + 1242530.6279296875, 1242531.673828125, 1242532.7119140625, 1242533.759765625, 1242534.8017578125, 1242535.83203125, 1242536.8779296875, 1242537.9150390625, + 1242538.9453125, 1242539.982421875, 1242540.98828125, 1242542.01171875, 1242543.0478515625, 1242544.1103515625, 1242545.2109375, 1242546.3203125, + 1242547.4580078125, 1242548.6123046875, 1242549.7822265625, 1242550.9775390625, 1242552.1669921875, 1242553.3349609375, 1242554.5078125, 1242555.6220703125, + 1242556.63671875, 1242557.666015625, 1242558.77734375, 1242559.89453125, 1242561.0458984375, 1242562.2314453125, 1242563.38671875, 1242564.5478515625, + 1242565.7177734375, 1242566.87109375, 1242568.041015625, 1242569.2255859375, 1242570.392578125, 1242571.5810546875, 1242572.79296875, 1242573.93359375, + 1242575.0634765625, 1242576.2080078125, 1242577.33203125, 1242578.447265625, 1242579.5517578125, 1242580.6748046875, 1242581.8388671875, 1242582.9521484375, + 1242584.0771484375, 1242585.220703125, 1242586.34375, 1242587.474609375, 1242588.6162109375, 1242589.7529296875, 1242590.9287109375, 1242592.11328125, + 1242593.3251953125, 1242594.53515625, 1242595.7724609375, 1242596.9892578125, 1242598.1728515625, 1242599.3134765625, 1242600.4345703125, 1242601.4814453125, + 1242602.4345703125, 1242603.390625, 1242604.404296875, 1242605.4287109375, 1242606.44921875, 1242607.4765625, 1242608.5234375, 1242609.35546875, + 1242609.8701171875, 1242610.9150390625, 1242611.9345703125, 1242612.939453125, 1242613.8974609375, 1242614.3642578125, 1242615.4052734375, 1242616.30078125, + 1242617.1884765625, 1242618.3427734375, 1242619.396484375, 1242619.9580078125, 1242621.015625, 1242621.939453125, 1242622.609375, 1242623.1474609375, + 1242623.92578125, 1242624.7041015625, 1242625.482421875, 1242626.5693359375, 1242627.5361328125, 1242628.419921875, 1242629.4208984375, 1242630.4853515625, + 1242631.486328125, 1242632.6103515625, 1242633.177734375, 1242633.8720703125, 1242634.8076171875, 1242635.220703125, 1242636.041015625, 1242636.732421875, + 1242637.4638671875, 1242638.1318359375, 1242638.765625, 1242639.2099609375, 1242639.8291015625, 1242640.5673828125, 1242640.9833984375, 1242641.58203125, + 1242642.1806640625, 1242642.6279296875, 1242643.330078125, 1242643.92578125, 1242644.515625, 1242645.1103515625, 1242645.5888671875, 1242646.17578125, + 1242646.74609375, 1242647.3330078125, 1242647.9072265625, 1242648.5498046875, 1242649.166015625, 1242649.681640625, 1242650.4130859375, 1242651.2177734375, + 1242651.8798828125, 1242652.744140625, 1242653.45703125, 1242654.244140625, 1242654.9755859375, 1242655.544921875, 1242656.203125, 1242656.8857421875, + 1242657.6220703125, 1242658.3173828125, 1242659.0693359375, 1242659.779296875, 1242660.4892578125, 1242661.1982421875, 1242662.560546875, 1242662.869140625, + 1242663.185546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, 1242663.560546875, + 1242959, + 1242960.0, 1242962.28515625, 1242963.3388671875, 1242964.3212890625, 1242965.3193359375, 1242966.2392578125, 1242967.150390625, 1242968.0263671875, + 1242969.041015625, 1242969.5400390625, 1242970.552734375, 1242971.1083984375, 1242972.1123046875, 1242973.158203125, 1242973.439453125, 1242973.9423828125, + 1242974.7841796875, 1242975.8095703125, 1242976.6220703125, 1242977.3203125, 1242978.3544921875, 1242979.2958984375, 1242980.1875, 1242981.12890625, + 1242982.130859375, 1242983.130859375, 1242984.1640625, 1242985.2080078125, 1242986.33203125, 1242987.5859375, 1242988.6240234375, 1242989.298828125, + 1242990.4794921875, 1242991.49609375, 1242992.0546875, 1242992.6044921875, 1242993.2138671875, 1242993.474609375, 1242994.2900390625, 1242994.9638671875, + 1242995.2333984375, 1242995.810546875, 1242996.0703125, 1242996.724609375, 1242997.26171875, 1242997.7607421875, 1242998.0234375, 1242998.400390625, + 1242998.8408203125, 1242999.455078125, 1242999.943359375, 1243000.59765625, 1243001.2041015625, 1243001.748046875, 1243002.2939453125, 1243002.8583984375, + 1243003.5771484375, 1243004.2158203125, 1243004.8154296875, 1243005.2958984375, 1243005.9736328125, 1243006.2998046875, 1243006.9052734375, 1243007.490234375, + 1243008.0478515625, 1243008.818359375, 1243009.2353515625, 1243009.9482421875, 1243010.71875, 1243011.47265625, 1243012.20703125, 1243012.9541015625, + 1243013.701171875, 1243014.4716796875, 1243015.236328125, 1243016.005859375, 1243016.6005859375, 1243017.5107421875, 1243018.248046875, 1243018.876953125, + 1243019.7783203125, 1243020.5439453125, 1243021.337890625, 1243022.1103515625, 1243022.931640625, 1243023.73046875, 1243024.5263671875, 1243025.3125, + 1243026.12890625, 1243026.6640625, 1243027.3427734375, 1243027.7578125, 1243028.578125, 1243029.4013671875, 1243030.1923828125, 1243031.0107421875, + 1243031.8251953125, 1243032.62890625, 1243033.40625, 1243034.197265625, 1243034.982421875, 1243035.8359375, 1243036.56640625, 1243037.3828125, + 1243038.197265625, 1243039.0830078125, 1243039.9013671875, 1243040.7587890625, 1243041.333984375, 1243042.330078125, 1243043.4169921875, 1243044.494140625, + 1243045.0302734375, 1243045.888671875, 1243046.4521484375, 1243047.0185546875, 1243047.5419921875, 1243048.1904296875, 1243048.619140625, 1243049.40234375, + 1243049.8798828125, 1243050.65625, 1243051.419921875, 1243052.0634765625, 1243052.9853515625, 1243053.783203125, 1243054.595703125, 1243055.4287109375, + 1243056.26171875, 1243057.1005859375, 1243057.92578125, 1243058.7275390625, 1243059.4921875, 1243060.2705078125, 1243061.0703125, 1243061.8583984375, + 1243062.6826171875, 1243063.5068359375, 1243064.3251953125, 1243065.146484375, 1243065.998046875, 1243066.880859375, 1243067.748046875, 1243068.626953125, + 1243069.509765625, 1243070.400390625, 1243071.251953125, 1243072.125, 1243072.984375, 1243073.86328125, 1243074.6982421875, 1243075.576171875, + 1243076.4404296875, 1243077.3369140625, 1243078.224609375, 1243079.2919921875, 1243079.97265625, 1243080.8681640625, 1243081.76953125, 1243082.71484375, + 1243083.6669921875, 1243084.6142578125, 1243085.5546875, 1243086.474609375, 1243087.390625, 1243088.2919921875, 1243089.197265625, 1243090.0693359375, + 1243090.9384765625, 1243091.8349609375, 1243092.751953125, 1243093.716796875, 1243094.640625, 1243095.576171875, 1243096.50390625, 1243097.400390625, + 1243098.2666015625, 1243099.16796875, 1243100.0771484375, 1243100.9423828125, 1243101.8251953125, 1243102.7099609375, 1243103.6357421875, 1243104.544921875, + 1243105.462890625, 1243106.357421875, 1243107.283203125, 1243108.162109375, 1243109.291015625, 1243109.92578125, 1243110.8173828125, 1243111.69921875, + 1243112.591796875, 1243113.484375, 1243114.3818359375, 1243115.3056640625, 1243116.1572265625, 1243117.0439453125, 1243117.9130859375, 1243118.759765625, + 1243119.619140625, 1243120.49609375, 1243121.3037109375, 1243122.15625, 1243122.9951171875, 1243123.8408203125, 1243124.6572265625, 1243125.5234375, + 1243126.4296875, 1243127.345703125, 1243128.24609375, 1243129.1162109375, 1243129.9873046875, 1243130.8427734375, 1243131.693359375, 1243132.537109375, + 1243133.392578125, 1243134.2099609375, 1243135.0498046875, 1243135.8857421875, 1243136.6962890625, 1243137.5595703125, 1243138.41015625, 1243139.1396484375, + 1243140.056640625, 1243141.23046875, 1243142.0625, 1243142.68359375, 1243143.3212890625, 1243144.1484375, 1243145.0078125, 1243145.8818359375, + 1243146.7666015625, 1243147.6484375, 1243148.5732421875, 1243149.482421875, 1243150.423828125, 1243151.373046875, 1243152.3349609375, 1243153.25, + 1243154.19140625, 1243155.1259765625, 1243156.0615234375, 1243157.0126953125, 1243157.9677734375, 1243158.9013671875, 1243159.8447265625, 1243160.779296875, + 1243161.6953125, 1243162.6357421875, 1243163.60546875, 1243164.5810546875, 1243165.5107421875, 1243166.4619140625, 1243167.3974609375, 1243168.33984375, + 1243169.1240234375, 1243170.2392578125, 1243171.1533203125, 1243172.0419921875, 1243172.9208984375, 1243173.6552734375, 1243174.66015625, 1243175.5439453125, + 1243176.466796875, 1243177.404296875, 1243178.35546875, 1243179.318359375, 1243180.25, 1243181.1796875, 1243182.0869140625, 1243183.0, + 1243183.9267578125, 1243184.849609375, 1243185.75, 1243186.6474609375, 1243187.546875, 1243188.4638671875, 1243189.3857421875, 1243190.2900390625, + 1243191.1982421875, 1243192.091796875, 1243192.978515625, 1243193.818359375, 1243194.638671875, 1243195.4541015625, 1243196.2802734375, 1243197.1318359375, + 1243198.0029296875, 1243198.8828125, 1243199.7529296875, 1243200.6591796875, 1243201.5380859375, 1243202.447265625, 1243203.3681640625, 1243204.236328125, + 1243205.1572265625, 1243206.103515625, 1243207.09765625, 1243208.09765625, 1243209.115234375, 1243210.1513671875, 1243211.1650390625, 1243212.1845703125, + 1243213.208984375, 1243214.201171875, 1243215.1787109375, 1243216.1171875, 1243217.0703125, 1243218.0224609375, 1243218.9775390625, 1243219.9580078125, + 1243220.9599609375, 1243221.953125, 1243222.8662109375, 1243223.7861328125, 1243224.69921875, 1243225.6396484375, 1243226.541015625, 1243227.4970703125, + 1243228.4462890625, 1243229.2880859375, 1243230.248046875, 1243231.1767578125, 1243232.1533203125, 1243233.0966796875, 1243234.033203125, 1243234.9755859375, + 1243235.919921875, 1243236.837890625, 1243237.71875, 1243238.6357421875, 1243239.5068359375, 1243240.43359375, 1243241.3515625, 1243242.26953125, + 1243243.107421875, 1243244.044921875, 1243244.9619140625, 1243245.94921875, 1243246.9560546875, 1243247.96484375, 1243249.080078125, 1243249.9404296875, + 1243250.89453125, 1243251.8291015625, 1243252.744140625, 1243253.6474609375, 1243254.55078125, 1243255.46484375, 1243256.3544921875, 1243257.2412109375, + 1243258.1591796875, 1243259.27734375, 1243260.03515625, 1243260.9609375, 1243261.9052734375, 1243262.791015625, 1243263.6513671875, 1243264.478515625, + 1243265.25, 1243266.01953125, 1243266.7841796875, 1243267.5302734375, 1243268.26953125, 1243269.0107421875, 1243269.751953125, 1243270.4755859375, + 1243271.1796875, 1243271.876953125, 1243272.5615234375, 1243273.2373046875, 1243273.9189453125, 1243274.591796875, 1243275.2490234375, 1243275.9033203125, + 1243276.595703125, 1243277.2861328125, 1243277.96484375, 1243278.626953125, 1243279.3115234375, 1243279.98046875, 1243280.6591796875, 1243281.3291015625, + 1243281.9873046875, 1243282.6435546875, 1243283.287109375, 1243283.9296875, 1243284.587890625, 1243285.2509765625, 1243285.904296875, 1243286.5712890625, + 1243287.228515625, 1243287.8857421875, 1243288.55859375, 1243289.1240234375, 1243289.76171875, 1243290.3994140625, 1243291.037109375, 1243291.6748046875, + 1243292.0361328125, 1243292.7470703125, 1243293.453125, 1243294.1689453125, 1243294.8798828125, 1243295.58203125, 1243296.2900390625, 1243296.9912109375, + 1243297.6904296875, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, 1243298.39453125, +] + +expanded_hr_messages = [ + { + "timestamp": 1030731510, + "heart_rate": 71 + }, + { + "timestamp": 1030731510.25, + "heart_rate": 71 + }, + { + "timestamp": 1030731510.5, + "heart_rate": 71 + }, + { + "timestamp": 1030731510.75, + "heart_rate": 71 + }, + { + "timestamp": 1030731511, + "heart_rate": 71 + }, + { + "timestamp": 1030731511.25, + "heart_rate": 71 + }, + { + "timestamp": 1030731511.5, + "heart_rate": 71 + }, + { + "timestamp": 1030731511.75, + "heart_rate": 71 + }, + { + "timestamp": 1030731512, + "heart_rate": 71 + }, + { + "timestamp": 1030731512.25, + "heart_rate": 71 + }, + { + "timestamp": 1030731512.5, + "heart_rate": 71 + }, + { + "timestamp": 1030731512.75, + "heart_rate": 71 + }, + { + "timestamp": 1030731513, + "heart_rate": 71 + }, + { + "timestamp": 1030731513.25, + "heart_rate": 71 + }, + { + "timestamp": 1030731513.5, + "heart_rate": 71 + }, + { + "timestamp": 1030731513.75, + "heart_rate": 71 + }, + { + "timestamp": 1030731514, + "heart_rate": 71 + }, + { + "timestamp": 1030731514.25, + "heart_rate": 71 + }, + { + "timestamp": 1030731514.5, + "heart_rate": 71 + }, + { + "timestamp": 1030731514.7314453, + "heart_rate": 71 + }, + { + "timestamp": 1030731514.9814453, + "heart_rate": 71 + }, + { + "timestamp": 1030731515.2314453, + "heart_rate": 71 + }, + { + "timestamp": 1030731515.4814453, + "heart_rate": 71 + }, + { + "timestamp": 1030731515.7314453, + "heart_rate": 71 + }, + { + "timestamp": 1030731515.9814453, + "heart_rate": 71 + }, + { + "timestamp": 1030731516.2314453, + "heart_rate": 71 + }, + { + "timestamp": 1030731516.4814453, + "heart_rate": 71 + }, + { + "timestamp": 1030731516.5029297, + "heart_rate": 71 + }, + { + "timestamp": 1030731516.7529297, + "heart_rate": 71 + }, + { + "timestamp": 1030731516.8652344, + "heart_rate": 71 + }, + { + "timestamp": 1030731517.1152344, + "heart_rate": 71 + }, + { + "timestamp": 1030731517.3652344, + "heart_rate": 71 + }, + { + "timestamp": 1030731517.6152344, + "heart_rate": 71 + }, + { + "timestamp": 1030731517.8652344, + "heart_rate": 71 + }, + { + "timestamp": 1030731517.9541016, + "heart_rate": 71 + }, + { + "timestamp": 1030731518.2041016, + "heart_rate": 71 + }, + { + "timestamp": 1030731518.4541016, + "heart_rate": 71 + }, + { + "timestamp": 1030731518.7041016, + "heart_rate": 71 + }, + { + "timestamp": 1030731518.9541016, + "heart_rate": 71 + }, + { + "timestamp": 1030731519.2041016, + "heart_rate": 71 + }, + { + "timestamp": 1030731519.3369141, + "heart_rate": 71 + }, + { + "timestamp": 1030731519.5869141, + "heart_rate": 71 + }, + { + "timestamp": 1030731519.8369141, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.0869141, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.3369141, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.5869141, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.6220703, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.8720703, + "heart_rate": 71 + }, + { + "timestamp": 1030731520.9853516, + "heart_rate": 71 + }, + { + "timestamp": 1030731521.2353516, + "heart_rate": 71 + }, + { + "timestamp": 1030731521.4853516, + "heart_rate": 71 + }, + { + "timestamp": 1030731521.71875, + "heart_rate": 71 + }, + { + "timestamp": 1030731521.96875, + "heart_rate": 71 + }, + { + "timestamp": 1030731522.21875, + "heart_rate": 71 + }, + { + "timestamp": 1030731522.2607422, + "heart_rate": 71 + }, + { + "timestamp": 1030731522.5107422, + "heart_rate": 71 + }, + { + "timestamp": 1030731522.7607422, + "heart_rate": 71 + }, + { + "timestamp": 1030731522.8320312, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.0820312, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.1035156, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.3535156, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.6035156, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.8535156, + "heart_rate": 71 + }, + { + "timestamp": 1030731523.9707031, + "heart_rate": 71 + }, + { + "timestamp": 1030731524.2207031, + "heart_rate": 71 + }, + { + "timestamp": 1030731524.4707031, + "heart_rate": 71 + }, + { + "timestamp": 1030731524.7207031, + "heart_rate": 71 + }, + { + "timestamp": 1030731524.8496094, + "heart_rate": 71 + }, + { + "timestamp": 1030731525.0996094, + "heart_rate": 71 + }, + { + "timestamp": 1030731525.234375, + "heart_rate": 71 + }, + { + "timestamp": 1030731525.484375, + "heart_rate": 71 + }, + { + "timestamp": 1030731525.734375, + "heart_rate": 71 + }, + { + "timestamp": 1030731525.984375, + "heart_rate": 71 + }, + { + "timestamp": 1030731526.1933594, + "heart_rate": 71 + }, + { + "timestamp": 1030731526.4433594, + "heart_rate": 71 + }, + { + "timestamp": 1030731526.5371094, + "heart_rate": 71 + }, + { + "timestamp": 1030731526.7871094, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.0371094, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.2871094, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.3457031, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.5957031, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.8457031, + "heart_rate": 71 + }, + { + "timestamp": 1030731527.9990234, + "heart_rate": 71 + }, + { + "timestamp": 1030731528.2490234, + "heart_rate": 71 + }, + { + "timestamp": 1030731528.4990234, + "heart_rate": 71 + }, + { + "timestamp": 1030731528.5996094, + "heart_rate": 71 + }, + { + "timestamp": 1030731528.8496094, + "heart_rate": 71 + }, + { + "timestamp": 1030731528.9785156, + "heart_rate": 71 + }, + { + "timestamp": 1030731529.2285156, + "heart_rate": 71 + }, + { + "timestamp": 1030731529.4785156, + "heart_rate": 71 + }, + { + "timestamp": 1030731529.5849609, + "heart_rate": 71 + }, + { + "timestamp": 1030731529.8349609, + "heart_rate": 71 + }, + { + "timestamp": 1030731529.9628906, + "heart_rate": 71 + }, + { + "timestamp": 1030731530.2128906, + "heart_rate": 71 + }, + { + "timestamp": 1030731530.2910156, + "heart_rate": 72 + }, + { + "timestamp": 1030731530.5410156, + "heart_rate": 72 + }, + { + "timestamp": 1030731530.7910156, + "heart_rate": 72 + }, + { + "timestamp": 1030731530.8154297, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.0654297, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.1708984, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.4208984, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.6308594, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.8808594, + "heart_rate": 72 + }, + { + "timestamp": 1030731531.9794922, + "heart_rate": 72 + }, + { + "timestamp": 1030731532.2294922, + "heart_rate": 72 + }, + { + "timestamp": 1030731532.3359375, + "heart_rate": 73 + }, + { + "timestamp": 1030731532.5859375, + "heart_rate": 73 + }, + { + "timestamp": 1030731532.7421875, + "heart_rate": 73 + }, + { + "timestamp": 1030731532.9921875, + "heart_rate": 73 + }, + { + "timestamp": 1030731533.0410156, + "heart_rate": 74 + }, + { + "timestamp": 1030731533.2910156, + "heart_rate": 74 + }, + { + "timestamp": 1030731533.5175781, + "heart_rate": 74 + }, + { + "timestamp": 1030731533.7675781, + "heart_rate": 74 + }, + { + "timestamp": 1030731533.9335938, + "heart_rate": 75 + }, + { + "timestamp": 1030731534.1835938, + "heart_rate": 75 + }, + { + "timestamp": 1030731534.2890625, + "heart_rate": 76 + }, + { + "timestamp": 1030731534.5390625, + "heart_rate": 76 + }, + { + "timestamp": 1030731534.6767578, + "heart_rate": 77 + }, + { + "timestamp": 1030731534.9267578, + "heart_rate": 77 + }, + { + "timestamp": 1030731535.0703125, + "heart_rate": 79 + }, + { + "timestamp": 1030731535.3203125, + "heart_rate": 79 + }, + { + "timestamp": 1030731535.4638672, + "heart_rate": 81 + }, + { + "timestamp": 1030731535.7138672, + "heart_rate": 81 + }, + { + "timestamp": 1030731535.9033203, + "heart_rate": 81 + }, + { + "timestamp": 1030731536.1533203, + "heart_rate": 81 + }, + { + "timestamp": 1030731536.2382812, + "heart_rate": 81 + }, + { + "timestamp": 1030731536.4882812, + "heart_rate": 81 + }, + { + "timestamp": 1030731536.625, + "heart_rate": 81 + }, + { + "timestamp": 1030731536.875, + "heart_rate": 81 + }, + { + "timestamp": 1030731537.0126953, + "heart_rate": 81 + }, + { + "timestamp": 1030731537.2626953, + "heart_rate": 81 + }, + { + "timestamp": 1030731537.28125, + "heart_rate": 81 + }, + { + "timestamp": 1030731537.53125, + "heart_rate": 81 + }, + { + "timestamp": 1030731537.6396484, + "heart_rate": 82 + }, + { + "timestamp": 1030731537.8896484, + "heart_rate": 82 + }, + { + "timestamp": 1030731538.1396484, + "heart_rate": 82 + }, + { + "timestamp": 1030731538.3896484, + "heart_rate": 82 + }, + { + "timestamp": 1030731538.5664062, + "heart_rate": 82 + }, + { + "timestamp": 1030731538.8164062, + "heart_rate": 82 + }, + { + "timestamp": 1030731539.0664062, + "heart_rate": 82 + }, + { + "timestamp": 1030731539.3164062, + "heart_rate": 82 + }, + { + "timestamp": 1030731539.5664062, + "heart_rate": 82 + }, + { + "timestamp": 1030731539.8164062, + "heart_rate": 82 + }, + { + "timestamp": 1030731540.0664062, + "heart_rate": 82 + }, + { + "timestamp": 1030731540.3164062, + "heart_rate": 82 + }, + { + "timestamp": 1030731540.4785156, + "heart_rate": 82 + }, + { + "timestamp": 1030731540.7285156, + "heart_rate": 82 + }, + { + "timestamp": 1030731540.9785156, + "heart_rate": 82 + }, + { + "timestamp": 1030731541.2285156, + "heart_rate": 82 + }, + { + "timestamp": 1030731541.4189453, + "heart_rate": 82 + }, + { + "timestamp": 1030731541.6689453, + "heart_rate": 82 + }, + { + "timestamp": 1030731541.9189453, + "heart_rate": 82 + }, + { + "timestamp": 1030731542.1689453, + "heart_rate": 82 + }, + { + "timestamp": 1030731542.3886719, + "heart_rate": 82 + }, + { + "timestamp": 1030731542.6386719, + "heart_rate": 82 + }, + { + "timestamp": 1030731542.8886719, + "heart_rate": 82 + }, + { + "timestamp": 1030731543.1386719, + "heart_rate": 82 + }, + { + "timestamp": 1030731543.3554688, + "heart_rate": 83 + }, + { + "timestamp": 1030731543.6054688, + "heart_rate": 83 + }, + { + "timestamp": 1030731543.8554688, + "heart_rate": 83 + }, + { + "timestamp": 1030731544.1054688, + "heart_rate": 83 + }, + { + "timestamp": 1030731544.3554688, + "heart_rate": 83 + }, + { + "timestamp": 1030731544.6054688, + "heart_rate": 83 + }, + { + "timestamp": 1030731544.8554688, + "heart_rate": 83 + }, + { + "timestamp": 1030731545.1054688, + "heart_rate": 83 + }, + { + "timestamp": 1030731545.2861328, + "heart_rate": 83 + }, + { + "timestamp": 1030731545.5361328, + "heart_rate": 83 + }, + { + "timestamp": 1030731545.7861328, + "heart_rate": 83 + }, + { + "timestamp": 1030731546.0361328, + "heart_rate": 83 + }, + { + "timestamp": 1030731546.2841797, + "heart_rate": 83 + }, + { + "timestamp": 1030731546.5341797, + "heart_rate": 83 + }, + { + "timestamp": 1030731546.7841797, + "heart_rate": 83 + }, + { + "timestamp": 1030731547.0341797, + "heart_rate": 83 + }, + { + "timestamp": 1030731547.2792969, + "heart_rate": 83 + }, + { + "timestamp": 1030731547.5292969, + "heart_rate": 83 + }, + { + "timestamp": 1030731547.7792969, + "heart_rate": 83 + }, + { + "timestamp": 1030731548.0292969, + "heart_rate": 83 + }, + { + "timestamp": 1030731548.2792969, + "heart_rate": 83 + }, + { + "timestamp": 1030731548.2900391, + "heart_rate": 83 + }, + { + "timestamp": 1030731548.5400391, + "heart_rate": 83 + }, + { + "timestamp": 1030731548.7900391, + "heart_rate": 83 + }, + { + "timestamp": 1030731549.0400391, + "heart_rate": 83 + }, + { + "timestamp": 1030731549.2900391, + "heart_rate": 83 + }, + { + "timestamp": 1030731549.3251953, + "heart_rate": 84 + }, + { + "timestamp": 1030731549.5751953, + "heart_rate": 84 + }, + { + "timestamp": 1030731549.8251953, + "heart_rate": 84 + }, + { + "timestamp": 1030731550.0751953, + "heart_rate": 84 + }, + { + "timestamp": 1030731550.3251953, + "heart_rate": 84 + }, + { + "timestamp": 1030731550.3632812, + "heart_rate": 85 + }, + { + "timestamp": 1030731550.6132812, + "heart_rate": 85 + }, + { + "timestamp": 1030731550.8632812, + "heart_rate": 85 + }, + { + "timestamp": 1030731551.1132812, + "heart_rate": 85 + }, + { + "timestamp": 1030731551.3632812, + "heart_rate": 85 + }, + { + "timestamp": 1030731551.6132812, + "heart_rate": 85 + }, + { + "timestamp": 1030731551.7363281, + "heart_rate": 85 + }, + { + "timestamp": 1030731551.9863281, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.0703125, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.1640625, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.4140625, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.6640625, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.9140625, + "heart_rate": 85 + }, + { + "timestamp": 1030731552.921875, + "heart_rate": 85 + }, + { + "timestamp": 1030731553.171875, + "heart_rate": 85 + }, + { + "timestamp": 1030731553.421875, + "heart_rate": 85 + }, + { + "timestamp": 1030731553.546875, + "heart_rate": 85 + }, + { + "timestamp": 1030731553.796875, + "heart_rate": 85 + }, + { + "timestamp": 1030731554.046875, + "heart_rate": 85 + }, + { + "timestamp": 1030731554.296875, + "heart_rate": 85 + }, + { + "timestamp": 1030731554.546875, + "heart_rate": 85 + }, + { + "timestamp": 1030731554.5751953, + "heart_rate": 85 + }, + { + "timestamp": 1030731554.8251953, + "heart_rate": 85 + }, + { + "timestamp": 1030731555.0751953, + "heart_rate": 85 + }, + { + "timestamp": 1030731555.3251953, + "heart_rate": 85 + }, + { + "timestamp": 1030731555.5751953, + "heart_rate": 85 + }, + { + "timestamp": 1030731555.6064453, + "heart_rate": 85 + }, + { + "timestamp": 1030731555.8564453, + "heart_rate": 85 + }, + { + "timestamp": 1030731556.1064453, + "heart_rate": 85 + }, + { + "timestamp": 1030731556.3564453, + "heart_rate": 85 + }, + { + "timestamp": 1030731556.6064453, + "heart_rate": 85 + }, + { + "timestamp": 1030731556.6201172, + "heart_rate": 85 + }, + { + "timestamp": 1030731556.8701172, + "heart_rate": 85 + }, + { + "timestamp": 1030731557.1201172, + "heart_rate": 85 + }, + { + "timestamp": 1030731557.3701172, + "heart_rate": 85 + }, + { + "timestamp": 1030731557.6201172, + "heart_rate": 85 + }, + { + "timestamp": 1030731557.6269531, + "heart_rate": 85 + }, + { + "timestamp": 1030731557.8769531, + "heart_rate": 85 + }, + { + "timestamp": 1030731558.1269531, + "heart_rate": 85 + }, + { + "timestamp": 1030731558.3769531, + "heart_rate": 85 + }, + { + "timestamp": 1030731558.5683594, + "heart_rate": 85 + }, + { + "timestamp": 1030731558.8183594, + "heart_rate": 85 + }, + { + "timestamp": 1030731559.0683594, + "heart_rate": 85 + }, + { + "timestamp": 1030731559.3183594, + "heart_rate": 85 + }, + { + "timestamp": 1030731559.5009766, + "heart_rate": 85 + }, + { + "timestamp": 1030731559.7509766, + "heart_rate": 85 + }, + { + "timestamp": 1030731560.0009766, + "heart_rate": 85 + }, + { + "timestamp": 1030731560.2509766, + "heart_rate": 85 + }, + { + "timestamp": 1030731560.5009766, + "heart_rate": 85 + }, + { + "timestamp": 1030731560.5097656, + "heart_rate": 86 + }, + { + "timestamp": 1030731560.7597656, + "heart_rate": 86 + }, + { + "timestamp": 1030731561.0097656, + "heart_rate": 86 + }, + { + "timestamp": 1030731561.2597656, + "heart_rate": 86 + }, + { + "timestamp": 1030731561.5097656, + "heart_rate": 86 + }, + { + "timestamp": 1030731561.5712891, + "heart_rate": 83 + }, + { + "timestamp": 1030731561.8212891, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.0712891, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.1425781, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.3925781, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.6425781, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.6679688, + "heart_rate": 83 + }, + { + "timestamp": 1030731562.9179688, + "heart_rate": 83 + }, + { + "timestamp": 1030731563.1679688, + "heart_rate": 83 + }, + { + "timestamp": 1030731563.4179688, + "heart_rate": 83 + }, + { + "timestamp": 1030731563.6679688, + "heart_rate": 83 + }, + { + "timestamp": 1030731563.7226562, + "heart_rate": 83 + }, + { + "timestamp": 1030731563.9726562, + "heart_rate": 83 + }, + { + "timestamp": 1030731564.2226562, + "heart_rate": 83 + }, + { + "timestamp": 1030731564.4726562, + "heart_rate": 83 + }, + { + "timestamp": 1030731564.7226562, + "heart_rate": 83 + }, + { + "timestamp": 1030731564.7890625, + "heart_rate": 83 + }, + { + "timestamp": 1030731565.0390625, + "heart_rate": 83 + }, + { + "timestamp": 1030731565.2890625, + "heart_rate": 83 + }, + { + "timestamp": 1030731565.5390625, + "heart_rate": 83 + }, + { + "timestamp": 1030731565.7890625, + "heart_rate": 83 + }, + { + "timestamp": 1030731565.8691406, + "heart_rate": 82 + }, + { + "timestamp": 1030731566.1191406, + "heart_rate": 82 + }, + { + "timestamp": 1030731566.3691406, + "heart_rate": 82 + }, + { + "timestamp": 1030731566.6191406, + "heart_rate": 82 + }, + { + "timestamp": 1030731566.8691406, + "heart_rate": 82 + }, + { + "timestamp": 1030731566.9511719, + "heart_rate": 82 + }, + { + "timestamp": 1030731567.2011719, + "heart_rate": 82 + }, + { + "timestamp": 1030731567.4511719, + "heart_rate": 82 + }, + { + "timestamp": 1030731567.7011719, + "heart_rate": 82 + }, + { + "timestamp": 1030731567.9511719, + "heart_rate": 82 + }, + { + "timestamp": 1030731567.9794922, + "heart_rate": 81 + }, + { + "timestamp": 1030731568.2294922, + "heart_rate": 81 + }, + { + "timestamp": 1030731568.4794922, + "heart_rate": 81 + }, + { + "timestamp": 1030731568.7294922, + "heart_rate": 81 + }, + { + "timestamp": 1030731568.9794922, + "heart_rate": 81 + }, + { + "timestamp": 1030731569.0087891, + "heart_rate": 80 + }, + { + "timestamp": 1030731569.2587891, + "heart_rate": 80 + }, + { + "timestamp": 1030731569.5087891, + "heart_rate": 80 + }, + { + "timestamp": 1030731569.7587891, + "heart_rate": 80 + }, + { + "timestamp": 1030731570.0087891, + "heart_rate": 80 + }, + { + "timestamp": 1030731570.0380859, + "heart_rate": 79 + }, + { + "timestamp": 1030731570.2880859, + "heart_rate": 79 + }, + { + "timestamp": 1030731570.5380859, + "heart_rate": 79 + }, + { + "timestamp": 1030731570.7880859, + "heart_rate": 79 + }, + { + "timestamp": 1030731571.0380859, + "heart_rate": 79 + }, + { + "timestamp": 1030731571.046875, + "heart_rate": 79 + }, + { + "timestamp": 1030731571.296875, + "heart_rate": 79 + }, + { + "timestamp": 1030731571.546875, + "heart_rate": 79 + }, + { + "timestamp": 1030731571.796875, + "heart_rate": 79 + }, + { + "timestamp": 1030731572.046875, + "heart_rate": 79 + }, + { + "timestamp": 1030731572.0712891, + "heart_rate": 79 + }, + { + "timestamp": 1030731572.3212891, + "heart_rate": 79 + }, + { + "timestamp": 1030731572.5712891, + "heart_rate": 79 + }, + { + "timestamp": 1030731572.8212891, + "heart_rate": 79 + }, + { + "timestamp": 1030731573.0712891, + "heart_rate": 79 + }, + { + "timestamp": 1030731573.1621094, + "heart_rate": 77 + }, + { + "timestamp": 1030731573.4121094, + "heart_rate": 77 + }, + { + "timestamp": 1030731573.6621094, + "heart_rate": 77 + }, + { + "timestamp": 1030731573.9121094, + "heart_rate": 77 + }, + { + "timestamp": 1030731574.1621094, + "heart_rate": 77 + }, + { + "timestamp": 1030731574.3310547, + "heart_rate": 76 + }, + { + "timestamp": 1030731574.5810547, + "heart_rate": 76 + }, + { + "timestamp": 1030731574.8310547, + "heart_rate": 76 + }, + { + "timestamp": 1030731575.0810547, + "heart_rate": 76 + }, + { + "timestamp": 1030731575.3310547, + "heart_rate": 76 + }, + { + "timestamp": 1030731575.4941406, + "heart_rate": 74 + }, + { + "timestamp": 1030731575.7441406, + "heart_rate": 74 + }, + { + "timestamp": 1030731575.9941406, + "heart_rate": 74 + }, + { + "timestamp": 1030731576.2441406, + "heart_rate": 74 + }, + { + "timestamp": 1030731576.4941406, + "heart_rate": 74 + }, + { + "timestamp": 1030731576.6552734, + "heart_rate": 72 + }, + { + "timestamp": 1030731576.9052734, + "heart_rate": 72 + }, + { + "timestamp": 1030731577.1552734, + "heart_rate": 72 + }, + { + "timestamp": 1030731577.4052734, + "heart_rate": 72 + }, + { + "timestamp": 1030731577.6552734, + "heart_rate": 72 + }, + { + "timestamp": 1030731577.8027344, + "heart_rate": 70 + }, + { + "timestamp": 1030731578.0527344, + "heart_rate": 70 + }, + { + "timestamp": 1030731578.3027344, + "heart_rate": 70 + }, + { + "timestamp": 1030731578.5527344, + "heart_rate": 70 + }, + { + "timestamp": 1030731578.8027344, + "heart_rate": 70 + }, + { + "timestamp": 1030731578.8896484, + "heart_rate": 69 + }, + { + "timestamp": 1030731579.1396484, + "heart_rate": 69 + }, + { + "timestamp": 1030731579.3896484, + "heart_rate": 69 + }, + { + "timestamp": 1030731579.6396484, + "heart_rate": 69 + }, + { + "timestamp": 1030731579.8896484, + "heart_rate": 69 + }, + { + "timestamp": 1030731579.9677734, + "heart_rate": 68 + }, + { + "timestamp": 1030731580.2177734, + "heart_rate": 68 + }, + { + "timestamp": 1030731580.4677734, + "heart_rate": 68 + }, + { + "timestamp": 1030731580.7177734, + "heart_rate": 68 + }, + { + "timestamp": 1030731580.9677734, + "heart_rate": 68 + }, + { + "timestamp": 1030731581.0488281, + "heart_rate": 64 + }, + { + "timestamp": 1030731581.2988281, + "heart_rate": 64 + }, + { + "timestamp": 1030731581.5488281, + "heart_rate": 64 + }, + { + "timestamp": 1030731581.7988281, + "heart_rate": 64 + }, + { + "timestamp": 1030731582.0488281, + "heart_rate": 64 + }, + { + "timestamp": 1030731582.1152344, + "heart_rate": 61 + }, + { + "timestamp": 1030731582.3652344, + "heart_rate": 61 + }, + { + "timestamp": 1030731582.6152344, + "heart_rate": 61 + }, + { + "timestamp": 1030731582.8652344, + "heart_rate": 61 + }, + { + "timestamp": 1030731583.1152344, + "heart_rate": 61 + }, + { + "timestamp": 1030731583.1796875, + "heart_rate": 60 + }, + { + "timestamp": 1030731583.4296875, + "heart_rate": 60 + }, + { + "timestamp": 1030731583.6796875, + "heart_rate": 60 + }, + { + "timestamp": 1030731583.9296875, + "heart_rate": 60 + }, + { + "timestamp": 1030731584.1796875, + "heart_rate": 60 + }, + { + "timestamp": 1030731584.25, + "heart_rate": 58 + }, + { + "timestamp": 1030731584.5, + "heart_rate": 58 + }, + { + "timestamp": 1030731584.75, + "heart_rate": 58 + }, + { + "timestamp": 1030731585, + "heart_rate": 58 + }, + { + "timestamp": 1030731585.25, + "heart_rate": 58 + }, + { + "timestamp": 1030731585.296875, + "heart_rate": 58 + }, + { + "timestamp": 1030731585.546875, + "heart_rate": 58 + }, + { + "timestamp": 1030731585.796875, + "heart_rate": 58 + }, + { + "timestamp": 1030731586.046875, + "heart_rate": 58 + }, + { + "timestamp": 1030731586.296875, + "heart_rate": 58 + }, + { + "timestamp": 1030731586.3085938, + "heart_rate": 58 + }, + { + "timestamp": 1030731586.5585938, + "heart_rate": 58 + }, + { + "timestamp": 1030731586.8085938, + "heart_rate": 58 + }, + { + "timestamp": 1030731587.0585938, + "heart_rate": 58 + }, + { + "timestamp": 1030731587.3085938, + "heart_rate": 58 + }, + { + "timestamp": 1030731587.3388672, + "heart_rate": 59 + }, + { + "timestamp": 1030731587.5888672, + "heart_rate": 59 + }, + { + "timestamp": 1030731587.8388672, + "heart_rate": 59 + }, + { + "timestamp": 1030731588.0888672, + "heart_rate": 59 + }, + { + "timestamp": 1030731588.3388672, + "heart_rate": 59 + }, + { + "timestamp": 1030731588.40625, + "heart_rate": 59 + }, + { + "timestamp": 1030731588.65625, + "heart_rate": 59 + }, + { + "timestamp": 1030731588.90625, + "heart_rate": 59 + }, + { + "timestamp": 1030731589.15625, + "heart_rate": 59 + }, + { + "timestamp": 1030731589.40625, + "heart_rate": 59 + }, + { + "timestamp": 1030731589.4570312, + "heart_rate": 59 + }, + { + "timestamp": 1030731589.7070312, + "heart_rate": 59 + }, + { + "timestamp": 1030731589.9570312, + "heart_rate": 59 + }, + { + "timestamp": 1030731590.2070312, + "heart_rate": 59 + }, + { + "timestamp": 1030731590.4570312, + "heart_rate": 59 + }, + { + "timestamp": 1030731590.4921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731590.7421875, + "heart_rate": 59 + }, + { + "timestamp": 1030731590.9921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731591.2421875, + "heart_rate": 59 + }, + { + "timestamp": 1030731591.4921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731591.5458984, + "heart_rate": 59 + }, + { + "timestamp": 1030731591.7958984, + "heart_rate": 59 + }, + { + "timestamp": 1030731592.0458984, + "heart_rate": 59 + }, + { + "timestamp": 1030731592.2958984, + "heart_rate": 59 + }, + { + "timestamp": 1030731592.5458984, + "heart_rate": 59 + }, + { + "timestamp": 1030731592.5986328, + "heart_rate": 59 + }, + { + "timestamp": 1030731592.8486328, + "heart_rate": 59 + }, + { + "timestamp": 1030731593.0986328, + "heart_rate": 59 + }, + { + "timestamp": 1030731593.3486328, + "heart_rate": 59 + }, + { + "timestamp": 1030731593.5986328, + "heart_rate": 59 + }, + { + "timestamp": 1030731593.6210938, + "heart_rate": 58 + }, + { + "timestamp": 1030731593.8710938, + "heart_rate": 58 + }, + { + "timestamp": 1030731594.1210938, + "heart_rate": 58 + }, + { + "timestamp": 1030731594.3710938, + "heart_rate": 58 + }, + { + "timestamp": 1030731594.6210938, + "heart_rate": 58 + }, + { + "timestamp": 1030731594.65625, + "heart_rate": 59 + }, + { + "timestamp": 1030731594.90625, + "heart_rate": 59 + }, + { + "timestamp": 1030731595.15625, + "heart_rate": 59 + }, + { + "timestamp": 1030731595.40625, + "heart_rate": 59 + }, + { + "timestamp": 1030731595.65625, + "heart_rate": 59 + }, + { + "timestamp": 1030731595.6943359, + "heart_rate": 59 + }, + { + "timestamp": 1030731595.9443359, + "heart_rate": 59 + }, + { + "timestamp": 1030731596.1943359, + "heart_rate": 59 + }, + { + "timestamp": 1030731596.4443359, + "heart_rate": 59 + }, + { + "timestamp": 1030731596.6943359, + "heart_rate": 59 + }, + { + "timestamp": 1030731596.7236328, + "heart_rate": 59 + }, + { + "timestamp": 1030731596.9736328, + "heart_rate": 59 + }, + { + "timestamp": 1030731597.2236328, + "heart_rate": 59 + }, + { + "timestamp": 1030731597.4736328, + "heart_rate": 59 + }, + { + "timestamp": 1030731597.7236328, + "heart_rate": 59 + }, + { + "timestamp": 1030731597.7744141, + "heart_rate": 59 + }, + { + "timestamp": 1030731598.0244141, + "heart_rate": 59 + }, + { + "timestamp": 1030731598.2744141, + "heart_rate": 59 + }, + { + "timestamp": 1030731598.5244141, + "heart_rate": 59 + }, + { + "timestamp": 1030731598.7744141, + "heart_rate": 59 + }, + { + "timestamp": 1030731598.8496094, + "heart_rate": 59 + }, + { + "timestamp": 1030731599.0996094, + "heart_rate": 59 + }, + { + "timestamp": 1030731599.3496094, + "heart_rate": 59 + }, + { + "timestamp": 1030731599.5556641, + "heart_rate": 59 + }, + { + "timestamp": 1030731599.8056641, + "heart_rate": 59 + }, + { + "timestamp": 1030731600.0556641, + "heart_rate": 59 + }, + { + "timestamp": 1030731600.3056641, + "heart_rate": 59 + }, + { + "timestamp": 1030731600.5195312, + "heart_rate": 59 + }, + { + "timestamp": 1030731600.7695312, + "heart_rate": 59 + }, + { + "timestamp": 1030731601.0195312, + "heart_rate": 59 + }, + { + "timestamp": 1030731601.2177734, + "heart_rate": 59 + }, + { + "timestamp": 1030731601.4677734, + "heart_rate": 59 + }, + { + "timestamp": 1030731601.7177734, + "heart_rate": 59 + }, + { + "timestamp": 1030731601.9677734, + "heart_rate": 59 + }, + { + "timestamp": 1030731602.1015625, + "heart_rate": 59 + }, + { + "timestamp": 1030731602.3515625, + "heart_rate": 59 + }, + { + "timestamp": 1030731602.6015625, + "heart_rate": 59 + }, + { + "timestamp": 1030731602.8515625, + "heart_rate": 59 + }, + { + "timestamp": 1030731603.1015625, + "heart_rate": 59 + }, + { + "timestamp": 1030731603.2080078, + "heart_rate": 59 + }, + { + "timestamp": 1030731603.4580078, + "heart_rate": 59 + }, + { + "timestamp": 1030731603.7080078, + "heart_rate": 59 + }, + { + "timestamp": 1030731603.9580078, + "heart_rate": 59 + }, + { + "timestamp": 1030731604.2080078, + "heart_rate": 59 + }, + { + "timestamp": 1030731604.3037109, + "heart_rate": 59 + }, + { + "timestamp": 1030731604.5537109, + "heart_rate": 59 + }, + { + "timestamp": 1030731604.8037109, + "heart_rate": 59 + }, + { + "timestamp": 1030731605.0537109, + "heart_rate": 59 + }, + { + "timestamp": 1030731605.3037109, + "heart_rate": 59 + }, + { + "timestamp": 1030731605.3857422, + "heart_rate": 59 + }, + { + "timestamp": 1030731605.6357422, + "heart_rate": 59 + }, + { + "timestamp": 1030731605.8857422, + "heart_rate": 59 + }, + { + "timestamp": 1030731606.1357422, + "heart_rate": 59 + }, + { + "timestamp": 1030731606.3857422, + "heart_rate": 59 + }, + { + "timestamp": 1030731606.453125, + "heart_rate": 59 + }, + { + "timestamp": 1030731606.703125, + "heart_rate": 59 + }, + { + "timestamp": 1030731606.953125, + "heart_rate": 59 + }, + { + "timestamp": 1030731607.203125, + "heart_rate": 59 + }, + { + "timestamp": 1030731607.453125, + "heart_rate": 59 + }, + { + "timestamp": 1030731607.4921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731607.7421875, + "heart_rate": 59 + }, + { + "timestamp": 1030731607.9921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731608.2421875, + "heart_rate": 59 + }, + { + "timestamp": 1030731608.4921875, + "heart_rate": 59 + }, + { + "timestamp": 1030731608.5449219, + "heart_rate": 59 + }, + { + "timestamp": 1030731608.7949219, + "heart_rate": 59 + }, + { + "timestamp": 1030731609.0449219, + "heart_rate": 59 + }, + { + "timestamp": 1030731609.2949219, + "heart_rate": 59 + }, + { + "timestamp": 1030731609.5449219, + "heart_rate": 59 + }, + { + "timestamp": 1030731609.609375, + "heart_rate": 59 + }, + { + "timestamp": 1030731609.859375, + "heart_rate": 59 + }, + { + "timestamp": 1030731610.109375, + "heart_rate": 59 + }, + { + "timestamp": 1030731610.359375, + "heart_rate": 59 + }, + { + "timestamp": 1030731610.609375, + "heart_rate": 59 + }, + { + "timestamp": 1030731610.6494141, + "heart_rate": 59 + }, + { + "timestamp": 1030731610.8994141, + "heart_rate": 59 + }, + { + "timestamp": 1030731611.1494141, + "heart_rate": 59 + }, + { + "timestamp": 1030731611.3994141, + "heart_rate": 59 + }, + { + "timestamp": 1030731611.6494141, + "heart_rate": 59 + }, + { + "timestamp": 1030731611.6845703, + "heart_rate": 59 + }, + { + "timestamp": 1030731611.9345703, + "heart_rate": 59 + }, + { + "timestamp": 1030731612.1845703, + "heart_rate": 59 + }, + { + "timestamp": 1030731612.4345703, + "heart_rate": 59 + }, + { + "timestamp": 1030731612.6845703, + "heart_rate": 59 + }, + { + "timestamp": 1030731612.7324219, + "heart_rate": 60 + }, + { + "timestamp": 1030731612.9824219, + "heart_rate": 60 + }, + { + "timestamp": 1030731613.2324219, + "heart_rate": 60 + }, + { + "timestamp": 1030731613.4824219, + "heart_rate": 60 + }, + { + "timestamp": 1030731613.7324219, + "heart_rate": 60 + }, + { + "timestamp": 1030731613.7753906, + "heart_rate": 60 + }, + { + "timestamp": 1030731614.0253906, + "heart_rate": 60 + }, + { + "timestamp": 1030731614.2753906, + "heart_rate": 60 + }, + { + "timestamp": 1030731614.5253906, + "heart_rate": 60 + }, + { + "timestamp": 1030731614.7753906, + "heart_rate": 60 + }, + { + "timestamp": 1030731614.8115234, + "heart_rate": 60 + }, + { + "timestamp": 1030731615.0615234, + "heart_rate": 60 + }, + { + "timestamp": 1030731615.3115234, + "heart_rate": 60 + }, + { + "timestamp": 1030731615.5615234, + "heart_rate": 60 + }, + { + "timestamp": 1030731615.8115234, + "heart_rate": 60 + }, + { + "timestamp": 1030731615.8408203, + "heart_rate": 59 + }, + { + "timestamp": 1030731616.0908203, + "heart_rate": 59 + }, + { + "timestamp": 1030731616.3408203, + "heart_rate": 59 + }, + { + "timestamp": 1030731616.5908203, + "heart_rate": 59 + }, + { + "timestamp": 1030731616.8408203, + "heart_rate": 59 + }, + { + "timestamp": 1030731616.859375, + "heart_rate": 60 + }, + { + "timestamp": 1030731617.109375, + "heart_rate": 60 + }, + { + "timestamp": 1030731617.359375, + "heart_rate": 60 + }, + { + "timestamp": 1030731617.609375, + "heart_rate": 60 + }, + { + "timestamp": 1030731617.859375, + "heart_rate": 60 + }, + { + "timestamp": 1030731617.9033203, + "heart_rate": 60 + }, + { + "timestamp": 1030731618.1533203, + "heart_rate": 60 + }, + { + "timestamp": 1030731618.4033203, + "heart_rate": 60 + }, + { + "timestamp": 1030731618.6533203, + "heart_rate": 60 + }, + { + "timestamp": 1030731618.9033203, + "heart_rate": 60 + }, + { + "timestamp": 1030731618.9716797, + "heart_rate": 59 + }, + { + "timestamp": 1030731619.2216797, + "heart_rate": 59 + }, + { + "timestamp": 1030731619.4716797, + "heart_rate": 59 + }, + { + "timestamp": 1030731619.7216797, + "heart_rate": 59 + }, + { + "timestamp": 1030731619.9716797, + "heart_rate": 59 + }, + { + "timestamp": 1030731620.0429688, + "heart_rate": 58 + }, + { + "timestamp": 1030731620.2929688, + "heart_rate": 58 + }, + { + "timestamp": 1030731620.5429688, + "heart_rate": 58 + }, + { + "timestamp": 1030731620.7929688, + "heart_rate": 58 + }, + { + "timestamp": 1030731621.0429688, + "heart_rate": 58 + }, + { + "timestamp": 1030731621.0966797, + "heart_rate": 57 + }, + { + "timestamp": 1030731621.3466797, + "heart_rate": 57 + }, + { + "timestamp": 1030731621.5966797, + "heart_rate": 57 + }, + { + "timestamp": 1030731621.8466797, + "heart_rate": 57 + }, + { + "timestamp": 1030731622.0966797, + "heart_rate": 57 + }, + { + "timestamp": 1030731622.1630859, + "heart_rate": 57 + }, + { + "timestamp": 1030731622.4130859, + "heart_rate": 57 + }, + { + "timestamp": 1030731622.6630859, + "heart_rate": 57 + }, + { + "timestamp": 1030731622.9130859, + "heart_rate": 57 + }, + { + "timestamp": 1030731623.1630859, + "heart_rate": 57 + }, + { + "timestamp": 1030731623.1953125, + "heart_rate": 57 + }, + { + "timestamp": 1030731623.4453125, + "heart_rate": 57 + }, + { + "timestamp": 1030731623.6953125, + "heart_rate": 57 + }, + { + "timestamp": 1030731623.9453125, + "heart_rate": 57 + }, + { + "timestamp": 1030731624.1953125, + "heart_rate": 57 + }, + { + "timestamp": 1030731624.2197266, + "heart_rate": 58 + }, + { + "timestamp": 1030731624.4697266, + "heart_rate": 58 + }, + { + "timestamp": 1030731624.7197266, + "heart_rate": 58 + }, + { + "timestamp": 1030731624.9697266, + "heart_rate": 58 + }, + { + "timestamp": 1030731625.2197266, + "heart_rate": 58 + }, + { + "timestamp": 1030731625.2373047, + "heart_rate": 58 + }, + { + "timestamp": 1030731625.4873047, + "heart_rate": 58 + }, + { + "timestamp": 1030731625.7373047, + "heart_rate": 58 + }, + { + "timestamp": 1030731625.9873047, + "heart_rate": 58 + }, + { + "timestamp": 1030731626.2265625, + "heart_rate": 58 + }, + { + "timestamp": 1030731626.4765625, + "heart_rate": 58 + }, + { + "timestamp": 1030731626.7265625, + "heart_rate": 58 + }, + { + "timestamp": 1030731626.9765625, + "heart_rate": 58 + }, + { + "timestamp": 1030731627.1767578, + "heart_rate": 60 + }, + { + "timestamp": 1030731627.4267578, + "heart_rate": 60 + }, + { + "timestamp": 1030731627.6767578, + "heart_rate": 60 + }, + { + "timestamp": 1030731627.9267578, + "heart_rate": 60 + }, + { + "timestamp": 1030731628.1230469, + "heart_rate": 61 + }, + { + "timestamp": 1030731628.3730469, + "heart_rate": 61 + }, + { + "timestamp": 1030731628.6230469, + "heart_rate": 61 + }, + { + "timestamp": 1030731628.8730469, + "heart_rate": 61 + }, + { + "timestamp": 1030731629.0136719, + "heart_rate": 62 + }, + { + "timestamp": 1030731629.2636719, + "heart_rate": 62 + }, + { + "timestamp": 1030731629.5136719, + "heart_rate": 62 + }, + { + "timestamp": 1030731629.6884766, + "heart_rate": 62 + }, + { + "timestamp": 1030731629.9384766, + "heart_rate": 62 + }, + { + "timestamp": 1030731630.1884766, + "heart_rate": 62 + }, + { + "timestamp": 1030731630.4384766, + "heart_rate": 62 + }, + { + "timestamp": 1030731630.6884766, + "heart_rate": 62 + }, + { + "timestamp": 1030731630.8710938, + "heart_rate": 62 + }, + { + "timestamp": 1030731631.1210938, + "heart_rate": 62 + }, + { + "timestamp": 1030731631.3710938, + "heart_rate": 62 + }, + { + "timestamp": 1030731631.6210938, + "heart_rate": 62 + }, + { + "timestamp": 1030731631.8564453, + "heart_rate": 62 + }, + { + "timestamp": 1030731632.1064453, + "heart_rate": 62 + }, + { + "timestamp": 1030731632.3564453, + "heart_rate": 62 + }, + { + "timestamp": 1030731632.6064453, + "heart_rate": 62 + }, + { + "timestamp": 1030731632.8144531, + "heart_rate": 62 + }, + { + "timestamp": 1030731633.0644531, + "heart_rate": 62 + }, + { + "timestamp": 1030731633.3144531, + "heart_rate": 62 + }, + { + "timestamp": 1030731633.5644531, + "heart_rate": 62 + }, + { + "timestamp": 1030731633.8144531, + "heart_rate": 62 + }, + { + "timestamp": 1030731633.8300781, + "heart_rate": 62 + }, + { + "timestamp": 1030731634.0800781, + "heart_rate": 62 + }, + { + "timestamp": 1030731634.3300781, + "heart_rate": 62 + }, + { + "timestamp": 1030731634.5800781, + "heart_rate": 62 + }, + { + "timestamp": 1030731634.8212891, + "heart_rate": 62 + }, + { + "timestamp": 1030731635.0712891, + "heart_rate": 62 + }, + { + "timestamp": 1030731635.3212891, + "heart_rate": 62 + }, + { + "timestamp": 1030731635.5712891, + "heart_rate": 62 + }, + { + "timestamp": 1030731635.8212891, + "heart_rate": 62 + }, + { + "timestamp": 1030731635.8320312, + "heart_rate": 60 + }, + { + "timestamp": 1030731636.0820312, + "heart_rate": 60 + }, + { + "timestamp": 1030731636.3320312, + "heart_rate": 60 + }, + { + "timestamp": 1030731636.5820312, + "heart_rate": 60 + }, + { + "timestamp": 1030731636.8183594, + "heart_rate": 60 + }, + { + "timestamp": 1030731637.0683594, + "heart_rate": 60 + }, + { + "timestamp": 1030731637.3183594, + "heart_rate": 60 + }, + { + "timestamp": 1030731637.5683594, + "heart_rate": 60 + }, + { + "timestamp": 1030731637.8076172, + "heart_rate": 61 + }, + { + "timestamp": 1030731638.0576172, + "heart_rate": 61 + }, + { + "timestamp": 1030731638.3076172, + "heart_rate": 61 + }, + { + "timestamp": 1030731638.5576172, + "heart_rate": 61 + }, + { + "timestamp": 1030731638.7851562, + "heart_rate": 61 + }, + { + "timestamp": 1030731639.0351562, + "heart_rate": 61 + }, + { + "timestamp": 1030731639.2851562, + "heart_rate": 61 + }, + { + "timestamp": 1030731639.5351562, + "heart_rate": 61 + }, + { + "timestamp": 1030731639.7470703, + "heart_rate": 61 + }, + { + "timestamp": 1030731639.9970703, + "heart_rate": 61 + }, + { + "timestamp": 1030731640.2470703, + "heart_rate": 61 + }, + { + "timestamp": 1030731640.4970703, + "heart_rate": 61 + }, + { + "timestamp": 1030731640.7216797, + "heart_rate": 61 + }, + { + "timestamp": 1030731640.9716797, + "heart_rate": 61 + }, + { + "timestamp": 1030731641.2216797, + "heart_rate": 61 + }, + { + "timestamp": 1030731641.4716797, + "heart_rate": 61 + }, + { + "timestamp": 1030731641.6982422, + "heart_rate": 61 + }, + { + "timestamp": 1030731641.9482422, + "heart_rate": 61 + }, + { + "timestamp": 1030731642.1982422, + "heart_rate": 61 + }, + { + "timestamp": 1030731642.4482422, + "heart_rate": 61 + }, + { + "timestamp": 1030731642.6806641, + "heart_rate": 61 + }, + { + "timestamp": 1030731642.9306641, + "heart_rate": 61 + }, + { + "timestamp": 1030731643.1806641, + "heart_rate": 61 + }, + { + "timestamp": 1030731643.4306641, + "heart_rate": 61 + }, + { + "timestamp": 1030731643.6708984, + "heart_rate": 61 + }, + { + "timestamp": 1030731643.9208984, + "heart_rate": 61 + }, + { + "timestamp": 1030731644.1708984, + "heart_rate": 61 + }, + { + "timestamp": 1030731644.4208984, + "heart_rate": 61 + }, + { + "timestamp": 1030731644.6660156, + "heart_rate": 61 + }, + { + "timestamp": 1030731644.9160156, + "heart_rate": 61 + }, + { + "timestamp": 1030731645.1660156, + "heart_rate": 61 + }, + { + "timestamp": 1030731645.4160156, + "heart_rate": 61 + }, + { + "timestamp": 1030731645.6630859, + "heart_rate": 61 + }, + { + "timestamp": 1030731645.9130859, + "heart_rate": 61 + }, + { + "timestamp": 1030731646.1630859, + "heart_rate": 61 + }, + { + "timestamp": 1030731646.4130859, + "heart_rate": 61 + }, + { + "timestamp": 1030731646.6630859, + "heart_rate": 61 + }, + { + "timestamp": 1030731646.6855469, + "heart_rate": 60 + }, + { + "timestamp": 1030731646.9355469, + "heart_rate": 60 + }, + { + "timestamp": 1030731647.1855469, + "heart_rate": 60 + }, + { + "timestamp": 1030731647.4355469, + "heart_rate": 60 + }, + { + "timestamp": 1030731647.6855469, + "heart_rate": 60 + }, + { + "timestamp": 1030731647.7275391, + "heart_rate": 60 + }, + { + "timestamp": 1030731647.9775391, + "heart_rate": 60 + }, + { + "timestamp": 1030731648.2275391, + "heart_rate": 60 + }, + { + "timestamp": 1030731648.4775391, + "heart_rate": 60 + }, + { + "timestamp": 1030731648.7275391, + "heart_rate": 60 + }, + { + "timestamp": 1030731648.7773438, + "heart_rate": 59 + }, + { + "timestamp": 1030731649.0273438, + "heart_rate": 59 + }, + { + "timestamp": 1030731649.2773438, + "heart_rate": 59 + }, + { + "timestamp": 1030731649.5273438, + "heart_rate": 59 + }, + { + "timestamp": 1030731649.7773438, + "heart_rate": 59 + }, + { + "timestamp": 1030731649.7910156, + "heart_rate": 58 + }, + { + "timestamp": 1030731650.0410156, + "heart_rate": 58 + }, + { + "timestamp": 1030731650.2910156, + "heart_rate": 58 + }, + { + "timestamp": 1030731650.5410156, + "heart_rate": 58 + }, + { + "timestamp": 1030731650.7216797, + "heart_rate": 59 + }, + { + "timestamp": 1030731650.9716797, + "heart_rate": 59 + }, + { + "timestamp": 1030731651.2216797, + "heart_rate": 59 + }, + { + "timestamp": 1030731651.4716797, + "heart_rate": 59 + }, + { + "timestamp": 1030731651.5986328, + "heart_rate": 61 + }, + { + "timestamp": 1030731651.8486328, + "heart_rate": 61 + }, + { + "timestamp": 1030731652.0986328, + "heart_rate": 61 + }, + { + "timestamp": 1030731652.3486328, + "heart_rate": 61 + }, + { + "timestamp": 1030731652.5146484, + "heart_rate": 63 + }, + { + "timestamp": 1030731652.7646484, + "heart_rate": 63 + }, + { + "timestamp": 1030731653.0146484, + "heart_rate": 63 + }, + { + "timestamp": 1030731653.2646484, + "heart_rate": 63 + }, + { + "timestamp": 1030731653.5136719, + "heart_rate": 64 + }, + { + "timestamp": 1030731653.7636719, + "heart_rate": 64 + }, + { + "timestamp": 1030731654.0136719, + "heart_rate": 64 + }, + { + "timestamp": 1030731654.2636719, + "heart_rate": 64 + }, + { + "timestamp": 1030731654.5136719, + "heart_rate": 64 + }, + { + "timestamp": 1030731654.6279297, + "heart_rate": 62 + }, + { + "timestamp": 1030731654.8779297, + "heart_rate": 62 + }, + { + "timestamp": 1030731655.1279297, + "heart_rate": 62 + }, + { + "timestamp": 1030731655.3779297, + "heart_rate": 62 + }, + { + "timestamp": 1030731655.6279297, + "heart_rate": 62 + }, + { + "timestamp": 1030731655.7880859, + "heart_rate": 58 + }, + { + "timestamp": 1030731656.0380859, + "heart_rate": 58 + }, + { + "timestamp": 1030731656.2880859, + "heart_rate": 58 + }, + { + "timestamp": 1030731656.5380859, + "heart_rate": 58 + }, + { + "timestamp": 1030731656.7880859, + "heart_rate": 58 + }, + { + "timestamp": 1030731656.9316406, + "heart_rate": 56 + }, + { + "timestamp": 1030731657.1816406, + "heart_rate": 56 + }, + { + "timestamp": 1030731657.4316406, + "heart_rate": 56 + }, + { + "timestamp": 1030731657.6816406, + "heart_rate": 56 + }, + { + "timestamp": 1030731657.9316406, + "heart_rate": 56 + }, + { + "timestamp": 1030731658.0771484, + "heart_rate": 54 + }, + { + "timestamp": 1030731658.3271484, + "heart_rate": 54 + }, + { + "timestamp": 1030731658.5771484, + "heart_rate": 54 + }, + { + "timestamp": 1030731658.8271484, + "heart_rate": 54 + }, + { + "timestamp": 1030731659.0771484, + "heart_rate": 54 + }, + { + "timestamp": 1030731659.2050781, + "heart_rate": 53 + }, + { + "timestamp": 1030731659.4550781, + "heart_rate": 53 + }, + { + "timestamp": 1030731659.7050781, + "heart_rate": 53 + }, + { + "timestamp": 1030731659.9550781, + "heart_rate": 53 + }, + { + "timestamp": 1030731660.2050781, + "heart_rate": 53 + }, + { + "timestamp": 1030731660.2597656, + "heart_rate": 53 + }, + { + "timestamp": 1030731660.5097656, + "heart_rate": 53 + }, + { + "timestamp": 1030731660.7597656, + "heart_rate": 53 + }, + { + "timestamp": 1030731661.0097656, + "heart_rate": 53 + }, + { + "timestamp": 1030731661.2597656, + "heart_rate": 53 + }, + { + "timestamp": 1030731661.3144531, + "heart_rate": 55 + }, + { + "timestamp": 1030731661.5644531, + "heart_rate": 55 + }, + { + "timestamp": 1030731661.8144531, + "heart_rate": 55 + }, + { + "timestamp": 1030731662.0644531, + "heart_rate": 55 + }, + { + "timestamp": 1030731662.3144531, + "heart_rate": 55 + }, + { + "timestamp": 1030731662.3535156, + "heart_rate": 56 + }, + { + "timestamp": 1030731662.6035156, + "heart_rate": 56 + }, + { + "timestamp": 1030731662.8535156, + "heart_rate": 56 + }, + { + "timestamp": 1030731663.1035156, + "heart_rate": 56 + }, + { + "timestamp": 1030731663.3535156, + "heart_rate": 56 + }, + { + "timestamp": 1030731663.4091797, + "heart_rate": 56 + }, + { + "timestamp": 1030731663.6591797, + "heart_rate": 56 + }, + { + "timestamp": 1030731663.9091797, + "heart_rate": 56 + }, + { + "timestamp": 1030731664.1591797, + "heart_rate": 56 + }, + { + "timestamp": 1030731664.4091797, + "heart_rate": 56 + }, + { + "timestamp": 1030731664.4707031, + "heart_rate": 57 + }, + { + "timestamp": 1030731664.7207031, + "heart_rate": 57 + }, + { + "timestamp": 1030731664.9707031, + "heart_rate": 57 + }, + { + "timestamp": 1030731665.2207031, + "heart_rate": 57 + }, + { + "timestamp": 1030731665.4707031, + "heart_rate": 57 + }, + { + "timestamp": 1030731665.4746094, + "heart_rate": 57 + }, + { + "timestamp": 1030731665.7246094, + "heart_rate": 57 + }, + { + "timestamp": 1030731665.9746094, + "heart_rate": 57 + }, + { + "timestamp": 1030731666.2246094, + "heart_rate": 57 + }, + { + "timestamp": 1030731666.4462891, + "heart_rate": 58 + }, + { + "timestamp": 1030731666.6962891, + "heart_rate": 58 + }, + { + "timestamp": 1030731666.9462891, + "heart_rate": 58 + }, + { + "timestamp": 1030731667.1962891, + "heart_rate": 58 + }, + { + "timestamp": 1030731667.4462891, + "heart_rate": 58 + }, + { + "timestamp": 1030731667.5683594, + "heart_rate": 59 + }, + { + "timestamp": 1030731667.8183594, + "heart_rate": 59 + }, + { + "timestamp": 1030731668.0683594, + "heart_rate": 59 + }, + { + "timestamp": 1030731668.3183594, + "heart_rate": 59 + }, + { + "timestamp": 1030731668.5683594, + "heart_rate": 59 + }, + { + "timestamp": 1030731668.7119141, + "heart_rate": 57 + }, + { + "timestamp": 1030731668.9619141, + "heart_rate": 57 + }, + { + "timestamp": 1030731669.2119141, + "heart_rate": 57 + }, + { + "timestamp": 1030731669.4619141, + "heart_rate": 57 + }, + { + "timestamp": 1030731669.7119141, + "heart_rate": 57 + }, + { + "timestamp": 1030731669.8740234, + "heart_rate": 54 + }, + { + "timestamp": 1030731670.1240234, + "heart_rate": 54 + }, + { + "timestamp": 1030731670.3740234, + "heart_rate": 54 + }, + { + "timestamp": 1030731670.6240234, + "heart_rate": 54 + }, + { + "timestamp": 1030731670.8740234, + "heart_rate": 54 + }, + { + "timestamp": 1030731670.9824219, + "heart_rate": 53 + }, + { + "timestamp": 1030731670.9824219, + "heart_rate": 53 + }, + { + "timestamp": 1030731670.9824219, + "heart_rate": 53 + }, + { + "timestamp": 1030731671.2324219, + "heart_rate": 53 + }, + { + "timestamp": 1030731671.4824219, + "heart_rate": 53 + }, + { + "timestamp": 1030731671.7324219, + "heart_rate": 53 + }, + { + "timestamp": 1030731671.9824219, + "heart_rate": 53 + }, + { + "timestamp": 1030731672, + "heart_rate": 55 + }, + { + "timestamp": 1030731672.25, + "heart_rate": 55 + }, + { + "timestamp": 1030731672.5, + "heart_rate": 55 + }, + { + "timestamp": 1030731672.75, + "heart_rate": 55 + }, + { + "timestamp": 1030731673, + "heart_rate": 55 + }, + { + "timestamp": 1030731673.25, + "heart_rate": 55 + }, + { + "timestamp": 1030731673.5, + "heart_rate": 55 + }, + { + "timestamp": 1030731673.75, + "heart_rate": 55 + }, + { + "timestamp": 1030731674, + "heart_rate": 55 + }, + { + "timestamp": 1030731674.0419922, + "heart_rate": 56 + }, + { + "timestamp": 1030731674.2919922, + "heart_rate": 56 + }, + { + "timestamp": 1030731674.5419922, + "heart_rate": 56 + }, + { + "timestamp": 1030731674.7919922, + "heart_rate": 56 + }, + { + "timestamp": 1030731675.0419922, + "heart_rate": 56 + }, + { + "timestamp": 1030731675.0595703, + "heart_rate": 57 + }, + { + "timestamp": 1030731675.3095703, + "heart_rate": 57 + }, + { + "timestamp": 1030731675.5595703, + "heart_rate": 57 + }, + { + "timestamp": 1030731675.8095703, + "heart_rate": 57 + }, + { + "timestamp": 1030731676.0507812, + "heart_rate": 58 + }, + { + "timestamp": 1030731676.3007812, + "heart_rate": 58 + }, + { + "timestamp": 1030731676.5507812, + "heart_rate": 58 + }, + { + "timestamp": 1030731676.8007812, + "heart_rate": 58 + }, + { + "timestamp": 1030731677.0244141, + "heart_rate": 59 + }, + { + "timestamp": 1030731677.2744141, + "heart_rate": 59 + }, + { + "timestamp": 1030731677.5244141, + "heart_rate": 59 + }, + { + "timestamp": 1030731677.7744141, + "heart_rate": 59 + }, + { + "timestamp": 1030731677.9765625, + "heart_rate": 60 + }, + { + "timestamp": 1030731678.2265625, + "heart_rate": 60 + }, + { + "timestamp": 1030731678.4765625, + "heart_rate": 60 + }, + { + "timestamp": 1030731678.7265625, + "heart_rate": 60 + }, + { + "timestamp": 1030731678.9765625, + "heart_rate": 60 + }, + { + "timestamp": 1030731679.0068359, + "heart_rate": 61 + }, + { + "timestamp": 1030731679.2568359, + "heart_rate": 61 + }, + { + "timestamp": 1030731679.5068359, + "heart_rate": 61 + }, + { + "timestamp": 1030731679.7568359, + "heart_rate": 61 + }, + { + "timestamp": 1030731680.0068359, + "heart_rate": 61 + }, + { + "timestamp": 1030731680.0810547, + "heart_rate": 60 + }, + { + "timestamp": 1030731680.3310547, + "heart_rate": 60 + }, + { + "timestamp": 1030731680.5810547, + "heart_rate": 60 + }, + { + "timestamp": 1030731680.8310547, + "heart_rate": 60 + }, + { + "timestamp": 1030731681.0810547, + "heart_rate": 60 + }, + { + "timestamp": 1030731681.2138672, + "heart_rate": 58 + }, + { + "timestamp": 1030731681.4638672, + "heart_rate": 58 + }, + { + "timestamp": 1030731681.7138672, + "heart_rate": 58 + }, + { + "timestamp": 1030731681.9638672, + "heart_rate": 58 + }, + { + "timestamp": 1030731682.2138672, + "heart_rate": 58 + }, + { + "timestamp": 1030731682.3935547, + "heart_rate": 55 + }, + { + "timestamp": 1030731682.6435547, + "heart_rate": 55 + }, + { + "timestamp": 1030731682.8935547, + "heart_rate": 55 + }, + { + "timestamp": 1030731683.1435547, + "heart_rate": 55 + }, + { + "timestamp": 1030731683.3935547, + "heart_rate": 55 + }, + { + "timestamp": 1030731683.5712891, + "heart_rate": 53 + }, + { + "timestamp": 1030731683.8212891, + "heart_rate": 53 + }, + { + "timestamp": 1030731684.0712891, + "heart_rate": 53 + }, + { + "timestamp": 1030731684.3212891, + "heart_rate": 53 + }, + { + "timestamp": 1030731684.5712891, + "heart_rate": 53 + }, + { + "timestamp": 1030731684.7431641, + "heart_rate": 52 + }, + { + "timestamp": 1030731684.9931641, + "heart_rate": 52 + }, + { + "timestamp": 1030731685.2431641, + "heart_rate": 52 + }, + { + "timestamp": 1030731685.4931641, + "heart_rate": 52 + }, + { + "timestamp": 1030731685.7431641, + "heart_rate": 52 + }, + { + "timestamp": 1030731685.8720703, + "heart_rate": 52 + }, + { + "timestamp": 1030731686.1220703, + "heart_rate": 52 + }, + { + "timestamp": 1030731686.3720703, + "heart_rate": 52 + }, + { + "timestamp": 1030731686.6220703, + "heart_rate": 52 + }, + { + "timestamp": 1030731686.8720703, + "heart_rate": 52 + }, + { + "timestamp": 1030731686.9726562, + "heart_rate": 52 + }, + { + "timestamp": 1030731687.2226562, + "heart_rate": 52 + }, + { + "timestamp": 1030731687.4726562, + "heart_rate": 52 + }, + { + "timestamp": 1030731687.7226562, + "heart_rate": 52 + }, + { + "timestamp": 1030731687.9726562, + "heart_rate": 52 + }, + { + "timestamp": 1030731688.0527344, + "heart_rate": 53 + }, + { + "timestamp": 1030731688.3027344, + "heart_rate": 53 + }, + { + "timestamp": 1030731688.5527344, + "heart_rate": 53 + }, + { + "timestamp": 1030731688.8027344, + "heart_rate": 53 + }, + { + "timestamp": 1030731689.0527344, + "heart_rate": 53 + }, + { + "timestamp": 1030731689.0878906, + "heart_rate": 54 + }, + { + "timestamp": 1030731689.3378906, + "heart_rate": 54 + }, + { + "timestamp": 1030731689.5878906, + "heart_rate": 54 + }, + { + "timestamp": 1030731689.8378906, + "heart_rate": 54 + }, + { + "timestamp": 1030731690.0878906, + "heart_rate": 54 + }, + { + "timestamp": 1030731690.0917969, + "heart_rate": 56 + }, + { + "timestamp": 1030731690.3417969, + "heart_rate": 56 + }, + { + "timestamp": 1030731690.5917969, + "heart_rate": 56 + }, + { + "timestamp": 1030731690.8417969, + "heart_rate": 56 + }, + { + "timestamp": 1030731691.0917969, + "heart_rate": 56 + }, + { + "timestamp": 1030731691.1025391, + "heart_rate": 58 + }, + { + "timestamp": 1030731691.3525391, + "heart_rate": 58 + }, + { + "timestamp": 1030731691.6025391, + "heart_rate": 58 + }, + { + "timestamp": 1030731691.8525391, + "heart_rate": 58 + }, + { + "timestamp": 1030731692.1025391, + "heart_rate": 58 + }, + { + "timestamp": 1030731692.1162109, + "heart_rate": 59 + }, + { + "timestamp": 1030731692.3662109, + "heart_rate": 59 + }, + { + "timestamp": 1030731692.6162109, + "heart_rate": 59 + }, + { + "timestamp": 1030731692.8662109, + "heart_rate": 59 + }, + { + "timestamp": 1030731693.1162109, + "heart_rate": 59 + }, + { + "timestamp": 1030731693.1533203, + "heart_rate": 59 + }, + { + "timestamp": 1030731693.4033203, + "heart_rate": 59 + }, + { + "timestamp": 1030731693.6533203, + "heart_rate": 59 + }, + { + "timestamp": 1030731693.9033203, + "heart_rate": 59 + }, + { + "timestamp": 1030731694.1533203, + "heart_rate": 59 + }, + { + "timestamp": 1030731694.1689453, + "heart_rate": 59 + }, + { + "timestamp": 1030731694.4189453, + "heart_rate": 59 + }, + { + "timestamp": 1030731694.6689453, + "heart_rate": 59 + }, + { + "timestamp": 1030731694.9189453, + "heart_rate": 59 + }, + { + "timestamp": 1030731695.1689453, + "heart_rate": 59 + }, + { + "timestamp": 1030731695.2070312, + "heart_rate": 58 + }, + { + "timestamp": 1030731695.4570312, + "heart_rate": 58 + }, + { + "timestamp": 1030731695.7070312, + "heart_rate": 58 + }, + { + "timestamp": 1030731695.9570312, + "heart_rate": 58 + }, + { + "timestamp": 1030731696.2070312, + "heart_rate": 58 + }, + { + "timestamp": 1030731696.2685547, + "heart_rate": 58 + }, + { + "timestamp": 1030731696.5185547, + "heart_rate": 58 + }, + { + "timestamp": 1030731696.7685547, + "heart_rate": 58 + }, + { + "timestamp": 1030731697.0185547, + "heart_rate": 58 + }, + { + "timestamp": 1030731697.2685547, + "heart_rate": 58 + }, + { + "timestamp": 1030731697.3369141, + "heart_rate": 57 + }, + { + "timestamp": 1030731697.5869141, + "heart_rate": 57 + }, + { + "timestamp": 1030731697.8369141, + "heart_rate": 57 + }, + { + "timestamp": 1030731698.0869141, + "heart_rate": 57 + }, + { + "timestamp": 1030731698.3369141, + "heart_rate": 57 + }, + { + "timestamp": 1030731698.40625, + "heart_rate": 57 + }, + { + "timestamp": 1030731698.65625, + "heart_rate": 57 + }, + { + "timestamp": 1030731698.90625, + "heart_rate": 57 + }, + { + "timestamp": 1030731699.15625, + "heart_rate": 57 + }, + { + "timestamp": 1030731699.40625, + "heart_rate": 57 + }, + { + "timestamp": 1030731699.4853516, + "heart_rate": 56 + }, + { + "timestamp": 1030731699.7353516, + "heart_rate": 56 + }, + { + "timestamp": 1030731699.9853516, + "heart_rate": 56 + }, + { + "timestamp": 1030731700.2353516, + "heart_rate": 56 + }, + { + "timestamp": 1030731700.4853516, + "heart_rate": 56 + }, + { + "timestamp": 1030731700.5390625, + "heart_rate": 56 + }, + { + "timestamp": 1030731700.7890625, + "heart_rate": 56 + }, + { + "timestamp": 1030731701.0390625, + "heart_rate": 56 + }, + { + "timestamp": 1030731701.2890625, + "heart_rate": 56 + }, + { + "timestamp": 1030731701.5390625, + "heart_rate": 56 + }, + { + "timestamp": 1030731701.5693359, + "heart_rate": 57 + }, + { + "timestamp": 1030731701.8193359, + "heart_rate": 57 + }, + { + "timestamp": 1030731702.0693359, + "heart_rate": 57 + }, + { + "timestamp": 1030731702.3193359, + "heart_rate": 57 + }, + { + "timestamp": 1030731702.5380859, + "heart_rate": 57 + }, + { + "timestamp": 1030731702.7880859, + "heart_rate": 57 + }, + { + "timestamp": 1030731703.0380859, + "heart_rate": 57 + }, + { + "timestamp": 1030731703.2880859, + "heart_rate": 57 + }, + { + "timestamp": 1030731703.5380859, + "heart_rate": 57 + }, + { + "timestamp": 1030731703.5527344, + "heart_rate": 58 + }, + { + "timestamp": 1030731703.8027344, + "heart_rate": 58 + }, + { + "timestamp": 1030731704.0527344, + "heart_rate": 58 + }, + { + "timestamp": 1030731704.3027344, + "heart_rate": 58 + }, + { + "timestamp": 1030731704.5527344, + "heart_rate": 58 + }, + { + "timestamp": 1030731704.6220703, + "heart_rate": 59 + }, + { + "timestamp": 1030731704.8720703, + "heart_rate": 59 + }, + { + "timestamp": 1030731705.1220703, + "heart_rate": 59 + }, + { + "timestamp": 1030731705.3720703, + "heart_rate": 59 + }, + { + "timestamp": 1030731705.6220703, + "heart_rate": 59 + }, + { + "timestamp": 1030731705.7431641, + "heart_rate": 57 + }, + { + "timestamp": 1030731705.9931641, + "heart_rate": 57 + }, + { + "timestamp": 1030731706.2431641, + "heart_rate": 57 + }, + { + "timestamp": 1030731706.4931641, + "heart_rate": 57 + }, + { + "timestamp": 1030731706.7431641, + "heart_rate": 57 + }, + { + "timestamp": 1030731706.8632812, + "heart_rate": 55 + }, + { + "timestamp": 1030731707.1132812, + "heart_rate": 55 + }, + { + "timestamp": 1030731707.3632812, + "heart_rate": 55 + }, + { + "timestamp": 1030731707.6132812, + "heart_rate": 55 + }, + { + "timestamp": 1030731707.8632812, + "heart_rate": 55 + }, + { + "timestamp": 1030731708.0126953, + "heart_rate": 55 + }, + { + "timestamp": 1030731708.2626953, + "heart_rate": 55 + }, + { + "timestamp": 1030731708.5126953, + "heart_rate": 55 + }, + { + "timestamp": 1030731708.7626953, + "heart_rate": 55 + }, + { + "timestamp": 1030731709.0126953, + "heart_rate": 55 + }, + { + "timestamp": 1030731709.1621094, + "heart_rate": 53 + }, + { + "timestamp": 1030731709.4121094, + "heart_rate": 53 + }, + { + "timestamp": 1030731709.6621094, + "heart_rate": 53 + }, + { + "timestamp": 1030731709.9121094, + "heart_rate": 53 + }, + { + "timestamp": 1030731710.1621094, + "heart_rate": 53 + }, + { + "timestamp": 1030731710.2705078, + "heart_rate": 53 + }, + { + "timestamp": 1030731710.5205078, + "heart_rate": 53 + }, + { + "timestamp": 1030731710.7705078, + "heart_rate": 53 + }, + { + "timestamp": 1030731711.0205078, + "heart_rate": 53 + }, + { + "timestamp": 1030731711.2705078, + "heart_rate": 53 + }, + { + "timestamp": 1030731711.3994141, + "heart_rate": 53 + }, + { + "timestamp": 1030731711.6494141, + "heart_rate": 53 + }, + { + "timestamp": 1030731711.8994141, + "heart_rate": 53 + }, + { + "timestamp": 1030731712.1494141, + "heart_rate": 53 + }, + { + "timestamp": 1030731712.3994141, + "heart_rate": 53 + }, + { + "timestamp": 1030731712.5, + "heart_rate": 54 + }, + { + "timestamp": 1030731712.75, + "heart_rate": 54 + }, + { + "timestamp": 1030731713, + "heart_rate": 54 + }, + { + "timestamp": 1030731713.25, + "heart_rate": 54 + }, + { + "timestamp": 1030731713.5, + "heart_rate": 54 + }, + { + "timestamp": 1030731713.5371094, + "heart_rate": 54 + }, + { + "timestamp": 1030731713.7871094, + "heart_rate": 54 + }, + { + "timestamp": 1030731714.0371094, + "heart_rate": 54 + }, + { + "timestamp": 1030731714.2871094, + "heart_rate": 54 + }, + { + "timestamp": 1030731714.5371094, + "heart_rate": 54 + }, + { + "timestamp": 1030731714.5380859, + "heart_rate": 56 + }, + { + "timestamp": 1030731714.7880859, + "heart_rate": 56 + }, + { + "timestamp": 1030731715.0380859, + "heart_rate": 56 + }, + { + "timestamp": 1030731715.2880859, + "heart_rate": 56 + }, + { + "timestamp": 1030731715.4072266, + "heart_rate": 58 + }, + { + "timestamp": 1030731715.6572266, + "heart_rate": 58 + }, + { + "timestamp": 1030731715.9072266, + "heart_rate": 58 + }, + { + "timestamp": 1030731716.1572266, + "heart_rate": 58 + }, + { + "timestamp": 1030731716.4072266, + "heart_rate": 58 + }, + { + "timestamp": 1030731716.4804688, + "heart_rate": 58 + }, + { + "timestamp": 1030731716.7304688, + "heart_rate": 58 + }, + { + "timestamp": 1030731716.9804688, + "heart_rate": 58 + }, + { + "timestamp": 1030731717.2304688, + "heart_rate": 58 + }, + { + "timestamp": 1030731717.4804688, + "heart_rate": 58 + }, + { + "timestamp": 1030731717.5419922, + "heart_rate": 58 + }, + { + "timestamp": 1030731717.7919922, + "heart_rate": 58 + }, + { + "timestamp": 1030731718.0419922, + "heart_rate": 58 + }, + { + "timestamp": 1030731718.2919922, + "heart_rate": 58 + }, + { + "timestamp": 1030731718.5419922, + "heart_rate": 58 + }, + { + "timestamp": 1030731718.6337891, + "heart_rate": 57 + }, + { + "timestamp": 1030731718.8837891, + "heart_rate": 57 + }, + { + "timestamp": 1030731719.1337891, + "heart_rate": 57 + }, + { + "timestamp": 1030731719.3837891, + "heart_rate": 57 + }, + { + "timestamp": 1030731719.6337891, + "heart_rate": 57 + }, + { + "timestamp": 1030731719.6835938, + "heart_rate": 57 + }, + { + "timestamp": 1030731719.9335938, + "heart_rate": 57 + }, + { + "timestamp": 1030731720.1835938, + "heart_rate": 57 + }, + { + "timestamp": 1030731720.4335938, + "heart_rate": 57 + }, + { + "timestamp": 1030731720.6835938, + "heart_rate": 57 + }, + { + "timestamp": 1030731720.7871094, + "heart_rate": 56 + }, + { + "timestamp": 1030731721.0371094, + "heart_rate": 56 + }, + { + "timestamp": 1030731721.2871094, + "heart_rate": 56 + }, + { + "timestamp": 1030731721.5371094, + "heart_rate": 56 + }, + { + "timestamp": 1030731721.7871094, + "heart_rate": 56 + }, + { + "timestamp": 1030731721.8564453, + "heart_rate": 56 + }, + { + "timestamp": 1030731722.1064453, + "heart_rate": 56 + }, + { + "timestamp": 1030731722.3564453, + "heart_rate": 56 + }, + { + "timestamp": 1030731722.6064453, + "heart_rate": 56 + }, + { + "timestamp": 1030731722.8564453, + "heart_rate": 56 + }, + { + "timestamp": 1030731722.9287109, + "heart_rate": 56 + }, + { + "timestamp": 1030731723.1787109, + "heart_rate": 56 + }, + { + "timestamp": 1030731723.4287109, + "heart_rate": 56 + }, + { + "timestamp": 1030731723.6787109, + "heart_rate": 56 + }, + { + "timestamp": 1030731723.9287109, + "heart_rate": 56 + }, + { + "timestamp": 1030731724.0058594, + "heart_rate": 56 + }, + { + "timestamp": 1030731724.2558594, + "heart_rate": 56 + }, + { + "timestamp": 1030731724.5058594, + "heart_rate": 56 + }, + { + "timestamp": 1030731724.7558594, + "heart_rate": 56 + }, + { + "timestamp": 1030731725.0058594, + "heart_rate": 56 + }, + { + "timestamp": 1030731725.0273438, + "heart_rate": 56 + }, + { + "timestamp": 1030731725.2773438, + "heart_rate": 56 + }, + { + "timestamp": 1030731725.5273438, + "heart_rate": 56 + }, + { + "timestamp": 1030731725.7773438, + "heart_rate": 56 + }, + { + "timestamp": 1030731726.0273438, + "heart_rate": 56 + }, + { + "timestamp": 1030731726.0761719, + "heart_rate": 57 + }, + { + "timestamp": 1030731726.3261719, + "heart_rate": 57 + }, + { + "timestamp": 1030731726.5761719, + "heart_rate": 57 + }, + { + "timestamp": 1030731726.8261719, + "heart_rate": 57 + }, + { + "timestamp": 1030731727.0761719, + "heart_rate": 57 + }, + { + "timestamp": 1030731727.1210938, + "heart_rate": 57 + }, + { + "timestamp": 1030731727.3710938, + "heart_rate": 57 + }, + { + "timestamp": 1030731727.6210938, + "heart_rate": 57 + }, + { + "timestamp": 1030731727.8710938, + "heart_rate": 57 + }, + { + "timestamp": 1030731728.1210938, + "heart_rate": 57 + }, + { + "timestamp": 1030731728.1767578, + "heart_rate": 57 + }, + { + "timestamp": 1030731728.4267578, + "heart_rate": 57 + }, + { + "timestamp": 1030731728.6767578, + "heart_rate": 57 + }, + { + "timestamp": 1030731728.9267578, + "heart_rate": 57 + }, + { + "timestamp": 1030731729.1767578, + "heart_rate": 57 + }, + { + "timestamp": 1030731729.25, + "heart_rate": 57 + }, + { + "timestamp": 1030731729.5, + "heart_rate": 57 + }, + { + "timestamp": 1030731729.75, + "heart_rate": 57 + }, + { + "timestamp": 1030731730, + "heart_rate": 57 + }, + { + "timestamp": 1030731730.25, + "heart_rate": 57 + }, + { + "timestamp": 1030731730.3076172, + "heart_rate": 57 + }, + { + "timestamp": 1030731730.5576172, + "heart_rate": 57 + }, + { + "timestamp": 1030731730.8076172, + "heart_rate": 57 + }, + { + "timestamp": 1030731731.0576172, + "heart_rate": 57 + }, + { + "timestamp": 1030731731.3076172, + "heart_rate": 57 + }, + { + "timestamp": 1030731731.3662109, + "heart_rate": 57 + }, + { + "timestamp": 1030731731.6162109, + "heart_rate": 57 + }, + { + "timestamp": 1030731731.8662109, + "heart_rate": 57 + }, + { + "timestamp": 1030731732.1162109, + "heart_rate": 57 + }, + { + "timestamp": 1030731732.3662109, + "heart_rate": 57 + }, + { + "timestamp": 1030731732.4101562, + "heart_rate": 57 + }, + { + "timestamp": 1030731732.6601562, + "heart_rate": 57 + }, + { + "timestamp": 1030731732.9101562, + "heart_rate": 57 + }, + { + "timestamp": 1030731733.1601562, + "heart_rate": 57 + }, + { + "timestamp": 1030731733.4101562, + "heart_rate": 57 + }, + { + "timestamp": 1030731733.4521484, + "heart_rate": 57 + }, + { + "timestamp": 1030731733.7021484, + "heart_rate": 57 + }, + { + "timestamp": 1030731733.9521484, + "heart_rate": 57 + }, + { + "timestamp": 1030731734.2021484, + "heart_rate": 57 + }, + { + "timestamp": 1030731734.4482422, + "heart_rate": 57 + }, + { + "timestamp": 1030731734.6982422, + "heart_rate": 57 + }, + { + "timestamp": 1030731734.9482422, + "heart_rate": 57 + }, + { + "timestamp": 1030731735.1982422, + "heart_rate": 57 + }, + { + "timestamp": 1030731735.4482422, + "heart_rate": 57 + }, + { + "timestamp": 1030731735.4550781, + "heart_rate": 58 + }, + { + "timestamp": 1030731735.7050781, + "heart_rate": 58 + }, + { + "timestamp": 1030731735.9550781, + "heart_rate": 58 + }, + { + "timestamp": 1030731736.2050781, + "heart_rate": 58 + }, + { + "timestamp": 1030731736.4550781, + "heart_rate": 58 + }, + { + "timestamp": 1030731736.5009766, + "heart_rate": 59 + }, + { + "timestamp": 1030731736.7509766, + "heart_rate": 59 + }, + { + "timestamp": 1030731737.0009766, + "heart_rate": 59 + }, + { + "timestamp": 1030731737.2509766, + "heart_rate": 59 + }, + { + "timestamp": 1030731737.5009766, + "heart_rate": 59 + }, + { + "timestamp": 1030731737.5898438, + "heart_rate": 58 + }, + { + "timestamp": 1030731737.8398438, + "heart_rate": 58 + }, + { + "timestamp": 1030731738.0898438, + "heart_rate": 58 + }, + { + "timestamp": 1030731738.3398438, + "heart_rate": 58 + }, + { + "timestamp": 1030731738.5898438, + "heart_rate": 58 + }, + { + "timestamp": 1030731738.6796875, + "heart_rate": 57 + }, + { + "timestamp": 1030731738.9296875, + "heart_rate": 57 + }, + { + "timestamp": 1030731739.1796875, + "heart_rate": 57 + }, + { + "timestamp": 1030731739.4296875, + "heart_rate": 57 + }, + { + "timestamp": 1030731739.6796875, + "heart_rate": 57 + }, + { + "timestamp": 1030731739.7929688, + "heart_rate": 56 + }, + { + "timestamp": 1030731740.0429688, + "heart_rate": 56 + }, + { + "timestamp": 1030731740.2929688, + "heart_rate": 56 + }, + { + "timestamp": 1030731740.5429688, + "heart_rate": 56 + }, + { + "timestamp": 1030731740.7929688, + "heart_rate": 56 + }, + { + "timestamp": 1030731740.8974609, + "heart_rate": 55 + }, + { + "timestamp": 1030731741.1474609, + "heart_rate": 55 + }, + { + "timestamp": 1030731741.3974609, + "heart_rate": 55 + }, + { + "timestamp": 1030731741.6474609, + "heart_rate": 55 + }, + { + "timestamp": 1030731741.8974609, + "heart_rate": 55 + }, + { + "timestamp": 1030731742.0107422, + "heart_rate": 55 + }, + { + "timestamp": 1030731742.2607422, + "heart_rate": 55 + }, + { + "timestamp": 1030731742.5107422, + "heart_rate": 55 + }, + { + "timestamp": 1030731742.7607422, + "heart_rate": 55 + }, + { + "timestamp": 1030731743.0107422, + "heart_rate": 55 + }, + { + "timestamp": 1030731743.1044922, + "heart_rate": 54 + }, + { + "timestamp": 1030731743.3544922, + "heart_rate": 54 + }, + { + "timestamp": 1030731743.6044922, + "heart_rate": 54 + }, + { + "timestamp": 1030731743.8544922, + "heart_rate": 54 + }, + { + "timestamp": 1030731744.1044922, + "heart_rate": 54 + }, + { + "timestamp": 1030731744.2285156, + "heart_rate": 54 + }, + { + "timestamp": 1030731744.4785156, + "heart_rate": 54 + }, + { + "timestamp": 1030731744.7285156, + "heart_rate": 54 + }, + { + "timestamp": 1030731744.9785156, + "heart_rate": 54 + }, + { + "timestamp": 1030731745.2285156, + "heart_rate": 54 + }, + { + "timestamp": 1030731745.3642578, + "heart_rate": 54 + }, + { + "timestamp": 1030731745.6142578, + "heart_rate": 54 + }, + { + "timestamp": 1030731745.8642578, + "heart_rate": 54 + }, + { + "timestamp": 1030731746.1142578, + "heart_rate": 54 + }, + { + "timestamp": 1030731746.3642578, + "heart_rate": 54 + }, + { + "timestamp": 1030731746.4746094, + "heart_rate": 54 + }, + { + "timestamp": 1030731746.7246094, + "heart_rate": 54 + }, + { + "timestamp": 1030731746.9746094, + "heart_rate": 54 + }, + { + "timestamp": 1030731747.2246094, + "heart_rate": 54 + }, + { + "timestamp": 1030731747.4746094, + "heart_rate": 54 + }, + { + "timestamp": 1030731747.5673828, + "heart_rate": 54 + }, + { + "timestamp": 1030731747.8173828, + "heart_rate": 54 + }, + { + "timestamp": 1030731748.0673828, + "heart_rate": 54 + }, + { + "timestamp": 1030731748.3173828, + "heart_rate": 54 + }, + { + "timestamp": 1030731748.328125, + "heart_rate": 54 + }, + { + "timestamp": 1030731748.578125, + "heart_rate": 54 + }, + { + "timestamp": 1030731748.828125, + "heart_rate": 54 + }, + { + "timestamp": 1030731749.078125, + "heart_rate": 54 + }, + { + "timestamp": 1030731749.328125, + "heart_rate": 54 + }, + { + "timestamp": 1030731749.578125, + "heart_rate": 54 + }, + { + "timestamp": 1030731749.6318359, + "heart_rate": 54 + }, + { + "timestamp": 1030731749.8818359, + "heart_rate": 54 + }, + { + "timestamp": 1030731750.1318359, + "heart_rate": 54 + }, + { + "timestamp": 1030731750.3818359, + "heart_rate": 54 + }, + { + "timestamp": 1030731750.6318359, + "heart_rate": 54 + }, + { + "timestamp": 1030731750.6572266, + "heart_rate": 54 + }, + { + "timestamp": 1030731750.9072266, + "heart_rate": 54 + }, + { + "timestamp": 1030731751.1572266, + "heart_rate": 54 + }, + { + "timestamp": 1030731751.4072266, + "heart_rate": 54 + }, + { + "timestamp": 1030731751.6572266, + "heart_rate": 54 + }, + { + "timestamp": 1030731751.7001953, + "heart_rate": 54 + }, + { + "timestamp": 1030731751.9501953, + "heart_rate": 54 + }, + { + "timestamp": 1030731752.2001953, + "heart_rate": 54 + }, + { + "timestamp": 1030731752.4501953, + "heart_rate": 54 + }, + { + "timestamp": 1030731752.7001953, + "heart_rate": 54 + }, + { + "timestamp": 1030731752.7587891, + "heart_rate": 54 + }, + { + "timestamp": 1030731753.0087891, + "heart_rate": 54 + }, + { + "timestamp": 1030731753.2587891, + "heart_rate": 54 + }, + { + "timestamp": 1030731753.5087891, + "heart_rate": 54 + }, + { + "timestamp": 1030731753.7587891, + "heart_rate": 54 + }, + { + "timestamp": 1030731753.8447266, + "heart_rate": 55 + }, + { + "timestamp": 1030731754.0947266, + "heart_rate": 55 + }, + { + "timestamp": 1030731754.3447266, + "heart_rate": 55 + }, + { + "timestamp": 1030731754.5947266, + "heart_rate": 55 + }, + { + "timestamp": 1030731754.8447266, + "heart_rate": 55 + }, + { + "timestamp": 1030731754.9414062, + "heart_rate": 55 + }, + { + "timestamp": 1030731755.1914062, + "heart_rate": 55 + }, + { + "timestamp": 1030731755.4414062, + "heart_rate": 55 + }, + { + "timestamp": 1030731755.6914062, + "heart_rate": 55 + }, + { + "timestamp": 1030731755.9414062, + "heart_rate": 55 + }, + { + "timestamp": 1030731756.1269531, + "heart_rate": 55 + }, + { + "timestamp": 1030731756.3769531, + "heart_rate": 55 + }, + { + "timestamp": 1030731756.6269531, + "heart_rate": 55 + }, + { + "timestamp": 1030731756.8769531, + "heart_rate": 55 + }, + { + "timestamp": 1030731757.1269531, + "heart_rate": 55 + }, + { + "timestamp": 1030731757.3349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731757.5849609, + "heart_rate": 53 + }, + { + "timestamp": 1030731757.8349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731758.0849609, + "heart_rate": 53 + }, + { + "timestamp": 1030731758.3349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731758.5410156, + "heart_rate": 51 + }, + { + "timestamp": 1030731758.7910156, + "heart_rate": 51 + }, + { + "timestamp": 1030731759.0410156, + "heart_rate": 51 + }, + { + "timestamp": 1030731759.2910156, + "heart_rate": 51 + }, + { + "timestamp": 1030731759.5410156, + "heart_rate": 51 + }, + { + "timestamp": 1030731759.7265625, + "heart_rate": 51 + }, + { + "timestamp": 1030731759.9765625, + "heart_rate": 51 + }, + { + "timestamp": 1030731760.2265625, + "heart_rate": 51 + }, + { + "timestamp": 1030731760.4765625, + "heart_rate": 51 + }, + { + "timestamp": 1030731760.7265625, + "heart_rate": 51 + }, + { + "timestamp": 1030731760.9248047, + "heart_rate": 50 + }, + { + "timestamp": 1030731761.1748047, + "heart_rate": 50 + }, + { + "timestamp": 1030731761.4248047, + "heart_rate": 50 + }, + { + "timestamp": 1030731761.6748047, + "heart_rate": 50 + }, + { + "timestamp": 1030731761.9248047, + "heart_rate": 50 + }, + { + "timestamp": 1030731762.1240234, + "heart_rate": 50 + }, + { + "timestamp": 1030731762.3740234, + "heart_rate": 50 + }, + { + "timestamp": 1030731762.6240234, + "heart_rate": 50 + }, + { + "timestamp": 1030731762.8740234, + "heart_rate": 50 + }, + { + "timestamp": 1030731763.1240234, + "heart_rate": 50 + }, + { + "timestamp": 1030731763.2998047, + "heart_rate": 50 + }, + { + "timestamp": 1030731763.5498047, + "heart_rate": 50 + }, + { + "timestamp": 1030731763.7998047, + "heart_rate": 50 + }, + { + "timestamp": 1030731764.0498047, + "heart_rate": 50 + }, + { + "timestamp": 1030731764.2998047, + "heart_rate": 50 + }, + { + "timestamp": 1030731764.4736328, + "heart_rate": 51 + }, + { + "timestamp": 1030731764.7236328, + "heart_rate": 51 + }, + { + "timestamp": 1030731764.9736328, + "heart_rate": 51 + }, + { + "timestamp": 1030731765.2236328, + "heart_rate": 51 + }, + { + "timestamp": 1030731765.4736328, + "heart_rate": 51 + }, + { + "timestamp": 1030731765.6503906, + "heart_rate": 51 + }, + { + "timestamp": 1030731765.9003906, + "heart_rate": 51 + }, + { + "timestamp": 1030731766.1503906, + "heart_rate": 51 + }, + { + "timestamp": 1030731766.4003906, + "heart_rate": 51 + }, + { + "timestamp": 1030731766.6503906, + "heart_rate": 51 + }, + { + "timestamp": 1030731766.8164062, + "heart_rate": 51 + }, + { + "timestamp": 1030731767.0664062, + "heart_rate": 51 + }, + { + "timestamp": 1030731767.3164062, + "heart_rate": 51 + }, + { + "timestamp": 1030731767.5664062, + "heart_rate": 51 + }, + { + "timestamp": 1030731767.8164062, + "heart_rate": 51 + }, + { + "timestamp": 1030731767.9931641, + "heart_rate": 51 + }, + { + "timestamp": 1030731768.2431641, + "heart_rate": 51 + }, + { + "timestamp": 1030731768.4931641, + "heart_rate": 51 + }, + { + "timestamp": 1030731768.7431641, + "heart_rate": 51 + }, + { + "timestamp": 1030731768.9931641, + "heart_rate": 51 + }, + { + "timestamp": 1030731769.1953125, + "heart_rate": 51 + }, + { + "timestamp": 1030731769.4453125, + "heart_rate": 51 + }, + { + "timestamp": 1030731769.6953125, + "heart_rate": 51 + }, + { + "timestamp": 1030731769.9453125, + "heart_rate": 51 + }, + { + "timestamp": 1030731770.1953125, + "heart_rate": 51 + }, + { + "timestamp": 1030731770.3505859, + "heart_rate": 51 + }, + { + "timestamp": 1030731770.6005859, + "heart_rate": 51 + }, + { + "timestamp": 1030731770.8505859, + "heart_rate": 51 + }, + { + "timestamp": 1030731771.1005859, + "heart_rate": 51 + }, + { + "timestamp": 1030731771.3505859, + "heart_rate": 51 + }, + { + "timestamp": 1030731771.5322266, + "heart_rate": 51 + }, + { + "timestamp": 1030731771.7822266, + "heart_rate": 51 + }, + { + "timestamp": 1030731772.0322266, + "heart_rate": 51 + }, + { + "timestamp": 1030731772.2822266, + "heart_rate": 51 + }, + { + "timestamp": 1030731772.5322266, + "heart_rate": 51 + }, + { + "timestamp": 1030731772.7412109, + "heart_rate": 51 + }, + { + "timestamp": 1030731772.9912109, + "heart_rate": 51 + }, + { + "timestamp": 1030731773.2412109, + "heart_rate": 51 + }, + { + "timestamp": 1030731773.4912109, + "heart_rate": 51 + }, + { + "timestamp": 1030731773.7412109, + "heart_rate": 51 + }, + { + "timestamp": 1030731773.9414062, + "heart_rate": 50 + }, + { + "timestamp": 1030731774.1914062, + "heart_rate": 50 + }, + { + "timestamp": 1030731774.4414062, + "heart_rate": 50 + }, + { + "timestamp": 1030731774.6914062, + "heart_rate": 50 + }, + { + "timestamp": 1030731774.9414062, + "heart_rate": 50 + }, + { + "timestamp": 1030731775.1318359, + "heart_rate": 50 + }, + { + "timestamp": 1030731775.3818359, + "heart_rate": 50 + }, + { + "timestamp": 1030731775.6318359, + "heart_rate": 50 + }, + { + "timestamp": 1030731775.8818359, + "heart_rate": 50 + }, + { + "timestamp": 1030731776.1318359, + "heart_rate": 50 + }, + { + "timestamp": 1030731776.3251953, + "heart_rate": 50 + }, + { + "timestamp": 1030731776.5751953, + "heart_rate": 50 + }, + { + "timestamp": 1030731776.8251953, + "heart_rate": 50 + }, + { + "timestamp": 1030731777.0751953, + "heart_rate": 50 + }, + { + "timestamp": 1030731777.3251953, + "heart_rate": 50 + }, + { + "timestamp": 1030731777.5107422, + "heart_rate": 50 + }, + { + "timestamp": 1030731777.7607422, + "heart_rate": 50 + }, + { + "timestamp": 1030731778.0107422, + "heart_rate": 50 + }, + { + "timestamp": 1030731778.2607422, + "heart_rate": 50 + }, + { + "timestamp": 1030731778.5107422, + "heart_rate": 50 + }, + { + "timestamp": 1030731778.6181641, + "heart_rate": 50 + }, + { + "timestamp": 1030731778.8681641, + "heart_rate": 50 + }, + { + "timestamp": 1030731779.1181641, + "heart_rate": 50 + }, + { + "timestamp": 1030731779.3681641, + "heart_rate": 50 + }, + { + "timestamp": 1030731779.6181641, + "heart_rate": 50 + }, + { + "timestamp": 1030731779.7128906, + "heart_rate": 52 + }, + { + "timestamp": 1030731779.9628906, + "heart_rate": 52 + }, + { + "timestamp": 1030731780.2128906, + "heart_rate": 52 + }, + { + "timestamp": 1030731780.4628906, + "heart_rate": 52 + }, + { + "timestamp": 1030731780.7128906, + "heart_rate": 52 + }, + { + "timestamp": 1030731780.8349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731781.0849609, + "heart_rate": 53 + }, + { + "timestamp": 1030731781.3349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731781.5849609, + "heart_rate": 53 + }, + { + "timestamp": 1030731781.8349609, + "heart_rate": 53 + }, + { + "timestamp": 1030731781.9765625, + "heart_rate": 53 + }, + { + "timestamp": 1030731782.2265625, + "heart_rate": 53 + }, + { + "timestamp": 1030731782.4765625, + "heart_rate": 53 + }, + { + "timestamp": 1030731782.7265625, + "heart_rate": 53 + }, + { + "timestamp": 1030731782.9765625, + "heart_rate": 53 + }, + { + "timestamp": 1030731783.1054688, + "heart_rate": 53 + }, + { + "timestamp": 1030731783.3554688, + "heart_rate": 53 + }, + { + "timestamp": 1030731783.6054688, + "heart_rate": 53 + }, + { + "timestamp": 1030731783.8554688, + "heart_rate": 53 + }, + { + "timestamp": 1030731784.1054688, + "heart_rate": 53 + }, + { + "timestamp": 1030731784.21875, + "heart_rate": 53 + }, + { + "timestamp": 1030731784.46875, + "heart_rate": 53 + }, + { + "timestamp": 1030731784.71875, + "heart_rate": 53 + }, + { + "timestamp": 1030731784.96875, + "heart_rate": 53 + }, + { + "timestamp": 1030731785.21875, + "heart_rate": 53 + }, + { + "timestamp": 1030731785.3398438, + "heart_rate": 53 + }, + { + "timestamp": 1030731785.5898438, + "heart_rate": 53 + }, + { + "timestamp": 1030731785.8398438, + "heart_rate": 53 + }, + { + "timestamp": 1030731786.0898438, + "heart_rate": 53 + }, + { + "timestamp": 1030731786.3398438, + "heart_rate": 53 + }, + { + "timestamp": 1030731786.3964844, + "heart_rate": 54 + }, + { + "timestamp": 1030731786.6464844, + "heart_rate": 54 + }, + { + "timestamp": 1030731786.8964844, + "heart_rate": 54 + }, + { + "timestamp": 1030731787.1464844, + "heart_rate": 54 + }, + { + "timestamp": 1030731787.3964844, + "heart_rate": 54 + }, + { + "timestamp": 1030731787.4863281, + "heart_rate": 54 + }, + { + "timestamp": 1030731787.7363281, + "heart_rate": 54 + }, + { + "timestamp": 1030731787.9863281, + "heart_rate": 54 + }, + { + "timestamp": 1030731788.2363281, + "heart_rate": 54 + }, + { + "timestamp": 1030731788.4863281, + "heart_rate": 54 + }, + { + "timestamp": 1030731788.6201172, + "heart_rate": 55 + }, + { + "timestamp": 1030731788.8701172, + "heart_rate": 55 + }, + { + "timestamp": 1030731789.1201172, + "heart_rate": 55 + }, + { + "timestamp": 1030731789.3701172, + "heart_rate": 55 + }, + { + "timestamp": 1030731789.6201172, + "heart_rate": 55 + }, + { + "timestamp": 1030731789.7890625, + "heart_rate": 54 + }, + { + "timestamp": 1030731790.0390625, + "heart_rate": 54 + }, + { + "timestamp": 1030731790.2890625, + "heart_rate": 54 + }, + { + "timestamp": 1030731790.5390625, + "heart_rate": 54 + }, + { + "timestamp": 1030731790.7890625, + "heart_rate": 54 + }, + { + "timestamp": 1030731790.9208984, + "heart_rate": 53 + }, + { + "timestamp": 1030731791.1708984, + "heart_rate": 53 + }, + { + "timestamp": 1030731791.4208984, + "heart_rate": 53 + }, + { + "timestamp": 1030731791.6708984, + "heart_rate": 53 + }, + { + "timestamp": 1030731791.9208984, + "heart_rate": 53 + }, + { + "timestamp": 1030731792.0703125, + "heart_rate": 53 + }, + { + "timestamp": 1030731792.3203125, + "heart_rate": 53 + }, + { + "timestamp": 1030731792.5703125, + "heart_rate": 53 + }, + { + "timestamp": 1030731792.8203125, + "heart_rate": 53 + }, + { + "timestamp": 1030731793.0703125, + "heart_rate": 53 + }, + { + "timestamp": 1030731793.2373047, + "heart_rate": 53 + }, + { + "timestamp": 1030731793.4873047, + "heart_rate": 53 + }, + { + "timestamp": 1030731793.7373047, + "heart_rate": 53 + }, + { + "timestamp": 1030731793.9873047, + "heart_rate": 53 + }, + { + "timestamp": 1030731794.2373047, + "heart_rate": 53 + }, + { + "timestamp": 1030731794.4111328, + "heart_rate": 52 + }, + { + "timestamp": 1030731794.6611328, + "heart_rate": 52 + }, + { + "timestamp": 1030731794.9111328, + "heart_rate": 52 + }, + { + "timestamp": 1030731795.1611328, + "heart_rate": 52 + }, + { + "timestamp": 1030731795.4111328, + "heart_rate": 52 + }, + { + "timestamp": 1030731795.5732422, + "heart_rate": 52 + }, + { + "timestamp": 1030731795.8232422, + "heart_rate": 52 + }, + { + "timestamp": 1030731796.0732422, + "heart_rate": 52 + }, + { + "timestamp": 1030731796.3232422, + "heart_rate": 52 + }, + { + "timestamp": 1030731796.5732422, + "heart_rate": 52 + }, + { + "timestamp": 1030731796.7470703, + "heart_rate": 51 + }, + { + "timestamp": 1030731796.9970703, + "heart_rate": 51 + }, + { + "timestamp": 1030731797.2470703, + "heart_rate": 51 + }, + { + "timestamp": 1030731797.4970703, + "heart_rate": 51 + }, + { + "timestamp": 1030731797.7470703, + "heart_rate": 51 + }, + { + "timestamp": 1030731797.9199219, + "heart_rate": 51 + }, + { + "timestamp": 1030731798.1699219, + "heart_rate": 51 + }, + { + "timestamp": 1030731798.4199219, + "heart_rate": 51 + }, + { + "timestamp": 1030731798.6699219, + "heart_rate": 51 + }, + { + "timestamp": 1030731798.9199219, + "heart_rate": 51 + }, + { + "timestamp": 1030731799.0927734, + "heart_rate": 51 + }, + { + "timestamp": 1030731799.3427734, + "heart_rate": 51 + }, + { + "timestamp": 1030731799.5927734, + "heart_rate": 51 + }, + { + "timestamp": 1030731799.8427734, + "heart_rate": 51 + }, + { + "timestamp": 1030731800.0927734, + "heart_rate": 51 + }, + { + "timestamp": 1030731800.2978516, + "heart_rate": 51 + }, + { + "timestamp": 1030731800.5478516, + "heart_rate": 51 + }, + { + "timestamp": 1030731800.7978516, + "heart_rate": 51 + }, + { + "timestamp": 1030731801.0478516, + "heart_rate": 51 + }, + { + "timestamp": 1030731801.2978516, + "heart_rate": 51 + }, + { + "timestamp": 1030731801.4833984, + "heart_rate": 51 + }, + { + "timestamp": 1030731801.7333984, + "heart_rate": 51 + }, + { + "timestamp": 1030731801.9833984, + "heart_rate": 51 + }, + { + "timestamp": 1030731802.2333984, + "heart_rate": 51 + }, + { + "timestamp": 1030731802.4833984, + "heart_rate": 51 + }, + { + "timestamp": 1030731802.6523438, + "heart_rate": 51 + }, + { + "timestamp": 1030731802.9023438, + "heart_rate": 51 + }, + { + "timestamp": 1030731803.1523438, + "heart_rate": 51 + }, + { + "timestamp": 1030731803.4023438, + "heart_rate": 51 + }, + { + "timestamp": 1030731803.6523438, + "heart_rate": 51 + }, + { + "timestamp": 1030731803.8476562, + "heart_rate": 51 + }, + { + "timestamp": 1030731804.0976562, + "heart_rate": 51 + }, + { + "timestamp": 1030731804.3476562, + "heart_rate": 51 + }, + { + "timestamp": 1030731804.5976562, + "heart_rate": 51 + }, + { + "timestamp": 1030731804.8476562, + "heart_rate": 51 + }, + { + "timestamp": 1030731805.0380859, + "heart_rate": 51 + }, + { + "timestamp": 1030731805.2880859, + "heart_rate": 51 + }, + { + "timestamp": 1030731805.5380859, + "heart_rate": 51 + }, + { + "timestamp": 1030731805.7880859, + "heart_rate": 51 + }, + { + "timestamp": 1030731806.0380859, + "heart_rate": 51 + }, + { + "timestamp": 1030731806.1855469, + "heart_rate": 50 + }, + { + "timestamp": 1030731806.4355469, + "heart_rate": 50 + }, + { + "timestamp": 1030731806.6855469, + "heart_rate": 50 + }, + { + "timestamp": 1030731806.9355469, + "heart_rate": 50 + }, + { + "timestamp": 1030731807.1855469, + "heart_rate": 50 + }, + { + "timestamp": 1030731807.3261719, + "heart_rate": 51 + }, + { + "timestamp": 1030731807.5761719, + "heart_rate": 51 + }, + { + "timestamp": 1030731807.8261719, + "heart_rate": 51 + }, + { + "timestamp": 1030731808.0761719, + "heart_rate": 51 + }, + { + "timestamp": 1030731808.3066406, + "heart_rate": 52 + }, + { + "timestamp": 1030731808.5566406, + "heart_rate": 52 + }, + { + "timestamp": 1030731808.8066406, + "heart_rate": 52 + }, + { + "timestamp": 1030731809.0566406, + "heart_rate": 52 + }, + { + "timestamp": 1030731809.3066406, + "heart_rate": 52 + }, + { + "timestamp": 1030731809.5546875, + "heart_rate": 52 + }, + { + "timestamp": 1030731809.8046875, + "heart_rate": 52 + }, + { + "timestamp": 1030731810.0546875, + "heart_rate": 52 + }, + { + "timestamp": 1030731810.3046875, + "heart_rate": 52 + }, + { + "timestamp": 1030731810.5546875, + "heart_rate": 52 + }, + { + "timestamp": 1030731810.6640625, + "heart_rate": 52 + }, + { + "timestamp": 1030731810.9140625, + "heart_rate": 52 + }, + { + "timestamp": 1030731811.1640625, + "heart_rate": 52 + }, + { + "timestamp": 1030731811.4140625, + "heart_rate": 52 + }, + { + "timestamp": 1030731811.6640625, + "heart_rate": 52 + }, + { + "timestamp": 1030731811.7578125, + "heart_rate": 52 + }, + { + "timestamp": 1030731812.0078125, + "heart_rate": 52 + }, + { + "timestamp": 1030731812.2578125, + "heart_rate": 52 + }, + { + "timestamp": 1030731812.5078125, + "heart_rate": 52 + }, + { + "timestamp": 1030731812.7578125, + "heart_rate": 52 + }, + { + "timestamp": 1030731812.8408203, + "heart_rate": 53 + }, + { + "timestamp": 1030731813.0908203, + "heart_rate": 53 + }, + { + "timestamp": 1030731813.3408203, + "heart_rate": 53 + }, + { + "timestamp": 1030731813.5908203, + "heart_rate": 53 + }, + { + "timestamp": 1030731813.8408203, + "heart_rate": 53 + }, + { + "timestamp": 1030731813.9433594, + "heart_rate": 54 + }, + { + "timestamp": 1030731814.1933594, + "heart_rate": 54 + }, + { + "timestamp": 1030731814.4433594, + "heart_rate": 54 + }, + { + "timestamp": 1030731814.6933594, + "heart_rate": 54 + }, + { + "timestamp": 1030731814.9433594, + "heart_rate": 54 + }, + { + "timestamp": 1030731815.0673828, + "heart_rate": 54 + }, + { + "timestamp": 1030731815.3173828, + "heart_rate": 54 + }, + { + "timestamp": 1030731815.5673828, + "heart_rate": 54 + }, + { + "timestamp": 1030731815.8173828, + "heart_rate": 54 + }, + { + "timestamp": 1030731816.0673828, + "heart_rate": 54 + }, + { + "timestamp": 1030731816.1992188, + "heart_rate": 54 + }, + { + "timestamp": 1030731816.4492188, + "heart_rate": 54 + }, + { + "timestamp": 1030731816.6992188, + "heart_rate": 54 + }, + { + "timestamp": 1030731816.9492188, + "heart_rate": 54 + }, + { + "timestamp": 1030731817.1992188, + "heart_rate": 54 + }, + { + "timestamp": 1030731817.3330078, + "heart_rate": 53 + }, + { + "timestamp": 1030731817.5830078, + "heart_rate": 53 + }, + { + "timestamp": 1030731817.8330078, + "heart_rate": 53 + }, + { + "timestamp": 1030731818.0830078, + "heart_rate": 53 + }, + { + "timestamp": 1030731818.3330078, + "heart_rate": 53 + }, + { + "timestamp": 1030731818.4306641, + "heart_rate": 53 + }, + { + "timestamp": 1030731818.6806641, + "heart_rate": 53 + }, + { + "timestamp": 1030731818.9306641, + "heart_rate": 53 + }, + { + "timestamp": 1030731819.1806641, + "heart_rate": 53 + }, + { + "timestamp": 1030731819.4306641, + "heart_rate": 53 + }, + { + "timestamp": 1030731819.5332031, + "heart_rate": 54 + }, + { + "timestamp": 1030731819.7832031, + "heart_rate": 54 + }, + { + "timestamp": 1030731820.0332031, + "heart_rate": 54 + }, + { + "timestamp": 1030731820.2832031, + "heart_rate": 54 + }, + { + "timestamp": 1030731820.5332031, + "heart_rate": 54 + }, + { + "timestamp": 1030731820.6357422, + "heart_rate": 54 + }, + { + "timestamp": 1030731820.8857422, + "heart_rate": 54 + }, + { + "timestamp": 1030731821.1357422, + "heart_rate": 54 + }, + { + "timestamp": 1030731821.3857422, + "heart_rate": 54 + }, + { + "timestamp": 1030731821.6357422, + "heart_rate": 54 + }, + { + "timestamp": 1030731821.7138672, + "heart_rate": 54 + }, + { + "timestamp": 1030731821.9638672, + "heart_rate": 54 + }, + { + "timestamp": 1030731822.2138672, + "heart_rate": 54 + }, + { + "timestamp": 1030731822.4638672, + "heart_rate": 54 + }, + { + "timestamp": 1030731822.7138672, + "heart_rate": 54 + }, + { + "timestamp": 1030731822.8085938, + "heart_rate": 55 + }, + { + "timestamp": 1030731823.0585938, + "heart_rate": 55 + }, + { + "timestamp": 1030731823.3085938, + "heart_rate": 55 + }, + { + "timestamp": 1030731823.5585938, + "heart_rate": 55 + }, + { + "timestamp": 1030731823.8085938, + "heart_rate": 55 + }, + { + "timestamp": 1030731823.9101562, + "heart_rate": 55 + }, + { + "timestamp": 1030731824.1601562, + "heart_rate": 55 + }, + { + "timestamp": 1030731824.4101562, + "heart_rate": 55 + }, + { + "timestamp": 1030731824.6601562, + "heart_rate": 55 + }, + { + "timestamp": 1030731824.9101562, + "heart_rate": 55 + }, + { + "timestamp": 1030731824.9892578, + "heart_rate": 55 + }, + { + "timestamp": 1030731825.2392578, + "heart_rate": 55 + }, + { + "timestamp": 1030731825.4892578, + "heart_rate": 55 + }, + { + "timestamp": 1030731825.7392578, + "heart_rate": 55 + }, + { + "timestamp": 1030731825.9892578, + "heart_rate": 55 + }, + { + "timestamp": 1030731826.0898438, + "heart_rate": 55 + }, + { + "timestamp": 1030731826.3398438, + "heart_rate": 55 + }, + { + "timestamp": 1030731826.5898438, + "heart_rate": 55 + }, + { + "timestamp": 1030731826.8398438, + "heart_rate": 55 + }, + { + "timestamp": 1030731827.0898438, + "heart_rate": 55 + }, + { + "timestamp": 1030731827.2070312, + "heart_rate": 55 + }, + { + "timestamp": 1030731827.4570312, + "heart_rate": 55 + }, + { + "timestamp": 1030731827.7070312, + "heart_rate": 55 + }, + { + "timestamp": 1030731827.9570312, + "heart_rate": 55 + }, + { + "timestamp": 1030731828.2070312, + "heart_rate": 55 + }, + { + "timestamp": 1030731828.3232422, + "heart_rate": 54 + }, + { + "timestamp": 1030731828.5732422, + "heart_rate": 54 + }, + { + "timestamp": 1030731828.8232422, + "heart_rate": 54 + }, + { + "timestamp": 1030731829.0732422, + "heart_rate": 54 + }, + { + "timestamp": 1030731829.3232422, + "heart_rate": 54 + }, + { + "timestamp": 1030731829.4365234, + "heart_rate": 54 + }, + { + "timestamp": 1030731829.6865234, + "heart_rate": 54 + }, + { + "timestamp": 1030731829.9365234, + "heart_rate": 54 + }, + { + "timestamp": 1030731830.1865234, + "heart_rate": 54 + }, + { + "timestamp": 1030731830.4365234, + "heart_rate": 54 + }, + { + "timestamp": 1030731830.5351562, + "heart_rate": 54 + }, + { + "timestamp": 1030731830.7851562, + "heart_rate": 54 + }, + { + "timestamp": 1030731831.0351562, + "heart_rate": 54 + }, + { + "timestamp": 1030731831.2851562, + "heart_rate": 54 + }, + { + "timestamp": 1030731831.5351562, + "heart_rate": 54 + }, + { + "timestamp": 1030731831.6279297, + "heart_rate": 54 + }, + { + "timestamp": 1030731831.8779297, + "heart_rate": 54 + }, + { + "timestamp": 1030731832.1279297, + "heart_rate": 54 + }, + { + "timestamp": 1030731832.3779297, + "heart_rate": 54 + }, + { + "timestamp": 1030731832.6279297, + "heart_rate": 54 + }, + { + "timestamp": 1030731832.6738281, + "heart_rate": 55 + }, + { + "timestamp": 1030731832.9238281, + "heart_rate": 55 + }, + { + "timestamp": 1030731833.1738281, + "heart_rate": 55 + }, + { + "timestamp": 1030731833.4238281, + "heart_rate": 55 + }, + { + "timestamp": 1030731833.6738281, + "heart_rate": 55 + }, + { + "timestamp": 1030731833.7119141, + "heart_rate": 56 + }, + { + "timestamp": 1030731833.9619141, + "heart_rate": 56 + }, + { + "timestamp": 1030731834.2119141, + "heart_rate": 56 + }, + { + "timestamp": 1030731834.4619141, + "heart_rate": 56 + }, + { + "timestamp": 1030731834.7119141, + "heart_rate": 56 + }, + { + "timestamp": 1030731834.7597656, + "heart_rate": 57 + }, + { + "timestamp": 1030731835.0097656, + "heart_rate": 57 + }, + { + "timestamp": 1030731835.2597656, + "heart_rate": 57 + }, + { + "timestamp": 1030731835.5097656, + "heart_rate": 57 + }, + { + "timestamp": 1030731835.7597656, + "heart_rate": 57 + }, + { + "timestamp": 1030731835.8017578, + "heart_rate": 57 + }, + { + "timestamp": 1030731836.0517578, + "heart_rate": 57 + }, + { + "timestamp": 1030731836.3017578, + "heart_rate": 57 + }, + { + "timestamp": 1030731836.5517578, + "heart_rate": 57 + }, + { + "timestamp": 1030731836.8017578, + "heart_rate": 57 + }, + { + "timestamp": 1030731836.8320312, + "heart_rate": 57 + }, + { + "timestamp": 1030731837.0820312, + "heart_rate": 57 + }, + { + "timestamp": 1030731837.3320312, + "heart_rate": 57 + }, + { + "timestamp": 1030731837.5820312, + "heart_rate": 57 + }, + { + "timestamp": 1030731837.8320312, + "heart_rate": 57 + }, + { + "timestamp": 1030731837.8779297, + "heart_rate": 57 + }, + { + "timestamp": 1030731838.1279297, + "heart_rate": 57 + }, + { + "timestamp": 1030731838.3779297, + "heart_rate": 57 + }, + { + "timestamp": 1030731838.6279297, + "heart_rate": 57 + }, + { + "timestamp": 1030731838.8779297, + "heart_rate": 57 + }, + { + "timestamp": 1030731838.9150391, + "heart_rate": 58 + }, + { + "timestamp": 1030731839.1650391, + "heart_rate": 58 + }, + { + "timestamp": 1030731839.4150391, + "heart_rate": 58 + }, + { + "timestamp": 1030731839.6650391, + "heart_rate": 58 + }, + { + "timestamp": 1030731839.9150391, + "heart_rate": 58 + }, + { + "timestamp": 1030731839.9453125, + "heart_rate": 58 + }, + { + "timestamp": 1030731840.1953125, + "heart_rate": 58 + }, + { + "timestamp": 1030731840.4453125, + "heart_rate": 58 + }, + { + "timestamp": 1030731840.6953125, + "heart_rate": 58 + }, + { + "timestamp": 1030731840.9453125, + "heart_rate": 58 + }, + { + "timestamp": 1030731840.9824219, + "heart_rate": 58 + }, + { + "timestamp": 1030731841.2324219, + "heart_rate": 58 + }, + { + "timestamp": 1030731841.4824219, + "heart_rate": 58 + }, + { + "timestamp": 1030731841.7324219, + "heart_rate": 58 + }, + { + "timestamp": 1030731841.9824219, + "heart_rate": 58 + }, + { + "timestamp": 1030731841.9882812, + "heart_rate": 58 + }, + { + "timestamp": 1030731842.2382812, + "heart_rate": 58 + }, + { + "timestamp": 1030731842.4882812, + "heart_rate": 58 + }, + { + "timestamp": 1030731842.7382812, + "heart_rate": 58 + }, + { + "timestamp": 1030731842.9882812, + "heart_rate": 58 + }, + { + "timestamp": 1030731843.0117188, + "heart_rate": 58 + }, + { + "timestamp": 1030731843.2617188, + "heart_rate": 58 + }, + { + "timestamp": 1030731843.5117188, + "heart_rate": 58 + }, + { + "timestamp": 1030731843.7617188, + "heart_rate": 58 + }, + { + "timestamp": 1030731844.0117188, + "heart_rate": 58 + }, + { + "timestamp": 1030731844.0478516, + "heart_rate": 58 + }, + { + "timestamp": 1030731844.2978516, + "heart_rate": 58 + }, + { + "timestamp": 1030731844.5478516, + "heart_rate": 58 + }, + { + "timestamp": 1030731844.7978516, + "heart_rate": 58 + }, + { + "timestamp": 1030731845.0478516, + "heart_rate": 58 + }, + { + "timestamp": 1030731845.1103516, + "heart_rate": 58 + }, + { + "timestamp": 1030731845.3603516, + "heart_rate": 58 + }, + { + "timestamp": 1030731845.6103516, + "heart_rate": 58 + }, + { + "timestamp": 1030731845.8603516, + "heart_rate": 58 + }, + { + "timestamp": 1030731846.1103516, + "heart_rate": 58 + }, + { + "timestamp": 1030731846.2109375, + "heart_rate": 57 + }, + { + "timestamp": 1030731846.4609375, + "heart_rate": 57 + }, + { + "timestamp": 1030731846.7109375, + "heart_rate": 57 + }, + { + "timestamp": 1030731846.9609375, + "heart_rate": 57 + }, + { + "timestamp": 1030731847.2109375, + "heart_rate": 57 + }, + { + "timestamp": 1030731847.3203125, + "heart_rate": 56 + }, + { + "timestamp": 1030731847.5703125, + "heart_rate": 56 + }, + { + "timestamp": 1030731847.8203125, + "heart_rate": 56 + }, + { + "timestamp": 1030731848.0703125, + "heart_rate": 56 + }, + { + "timestamp": 1030731848.3203125, + "heart_rate": 56 + }, + { + "timestamp": 1030731848.4580078, + "heart_rate": 55 + }, + { + "timestamp": 1030731848.7080078, + "heart_rate": 55 + }, + { + "timestamp": 1030731848.9580078, + "heart_rate": 55 + }, + { + "timestamp": 1030731849.2080078, + "heart_rate": 55 + }, + { + "timestamp": 1030731849.4580078, + "heart_rate": 55 + }, + { + "timestamp": 1030731849.6123047, + "heart_rate": 54 + }, + { + "timestamp": 1030731849.8623047, + "heart_rate": 54 + }, + { + "timestamp": 1030731850.1123047, + "heart_rate": 54 + }, + { + "timestamp": 1030731850.3623047, + "heart_rate": 54 + }, + { + "timestamp": 1030731850.6123047, + "heart_rate": 54 + }, + { + "timestamp": 1030731850.7822266, + "heart_rate": 53 + }, + { + "timestamp": 1030731851.0322266, + "heart_rate": 53 + }, + { + "timestamp": 1030731851.2822266, + "heart_rate": 53 + }, + { + "timestamp": 1030731851.5322266, + "heart_rate": 53 + }, + { + "timestamp": 1030731851.7822266, + "heart_rate": 53 + }, + { + "timestamp": 1030731851.9775391, + "heart_rate": 52 + }, + { + "timestamp": 1030731852.2275391, + "heart_rate": 52 + }, + { + "timestamp": 1030731852.4775391, + "heart_rate": 52 + }, + { + "timestamp": 1030731852.7275391, + "heart_rate": 52 + }, + { + "timestamp": 1030731852.9775391, + "heart_rate": 52 + }, + { + "timestamp": 1030731853.1669922, + "heart_rate": 51 + }, + { + "timestamp": 1030731853.4169922, + "heart_rate": 51 + }, + { + "timestamp": 1030731853.6669922, + "heart_rate": 51 + }, + { + "timestamp": 1030731853.9169922, + "heart_rate": 51 + }, + { + "timestamp": 1030731854.1669922, + "heart_rate": 51 + }, + { + "timestamp": 1030731854.3349609, + "heart_rate": 51 + }, + { + "timestamp": 1030731854.5849609, + "heart_rate": 51 + }, + { + "timestamp": 1030731854.8349609, + "heart_rate": 51 + }, + { + "timestamp": 1030731855.0849609, + "heart_rate": 51 + }, + { + "timestamp": 1030731855.3349609, + "heart_rate": 51 + }, + { + "timestamp": 1030731855.5078125, + "heart_rate": 51 + }, + { + "timestamp": 1030731855.7578125, + "heart_rate": 51 + }, + { + "timestamp": 1030731856.0078125, + "heart_rate": 51 + }, + { + "timestamp": 1030731856.2578125, + "heart_rate": 51 + }, + { + "timestamp": 1030731856.5078125, + "heart_rate": 51 + }, + { + "timestamp": 1030731856.6220703, + "heart_rate": 51 + }, + { + "timestamp": 1030731856.8720703, + "heart_rate": 51 + }, + { + "timestamp": 1030731857.1220703, + "heart_rate": 51 + }, + { + "timestamp": 1030731857.3720703, + "heart_rate": 51 + }, + { + "timestamp": 1030731857.6220703, + "heart_rate": 51 + }, + { + "timestamp": 1030731857.6367188, + "heart_rate": 53 + }, + { + "timestamp": 1030731857.8867188, + "heart_rate": 53 + }, + { + "timestamp": 1030731858.1367188, + "heart_rate": 53 + }, + { + "timestamp": 1030731858.3867188, + "heart_rate": 53 + }, + { + "timestamp": 1030731858.6367188, + "heart_rate": 53 + }, + { + "timestamp": 1030731858.6660156, + "heart_rate": 55 + }, + { + "timestamp": 1030731858.9160156, + "heart_rate": 55 + }, + { + "timestamp": 1030731859.1660156, + "heart_rate": 55 + }, + { + "timestamp": 1030731859.4160156, + "heart_rate": 55 + }, + { + "timestamp": 1030731859.6660156, + "heart_rate": 55 + }, + { + "timestamp": 1030731859.7773438, + "heart_rate": 57 + }, + { + "timestamp": 1030731860.0273438, + "heart_rate": 57 + }, + { + "timestamp": 1030731860.2773438, + "heart_rate": 57 + }, + { + "timestamp": 1030731860.5273438, + "heart_rate": 57 + }, + { + "timestamp": 1030731860.7773438, + "heart_rate": 57 + }, + { + "timestamp": 1030731860.8945312, + "heart_rate": 55 + }, + { + "timestamp": 1030731861.1445312, + "heart_rate": 55 + }, + { + "timestamp": 1030731861.3945312, + "heart_rate": 55 + }, + { + "timestamp": 1030731861.6445312, + "heart_rate": 55 + }, + { + "timestamp": 1030731861.8945312, + "heart_rate": 55 + }, + { + "timestamp": 1030731862.0458984, + "heart_rate": 55 + }, + { + "timestamp": 1030731862.2958984, + "heart_rate": 55 + }, + { + "timestamp": 1030731862.5458984, + "heart_rate": 55 + }, + { + "timestamp": 1030731862.7958984, + "heart_rate": 55 + }, + { + "timestamp": 1030731863.0458984, + "heart_rate": 55 + }, + { + "timestamp": 1030731863.2314453, + "heart_rate": 53 + }, + { + "timestamp": 1030731863.4814453, + "heart_rate": 53 + }, + { + "timestamp": 1030731863.7314453, + "heart_rate": 53 + }, + { + "timestamp": 1030731863.9814453, + "heart_rate": 53 + }, + { + "timestamp": 1030731864.2314453, + "heart_rate": 53 + }, + { + "timestamp": 1030731864.3867188, + "heart_rate": 53 + }, + { + "timestamp": 1030731864.6367188, + "heart_rate": 53 + }, + { + "timestamp": 1030731864.8867188, + "heart_rate": 53 + }, + { + "timestamp": 1030731865.1367188, + "heart_rate": 53 + }, + { + "timestamp": 1030731865.3867188, + "heart_rate": 53 + }, + { + "timestamp": 1030731865.5478516, + "heart_rate": 52 + }, + { + "timestamp": 1030731865.7978516, + "heart_rate": 52 + }, + { + "timestamp": 1030731866.0478516, + "heart_rate": 52 + }, + { + "timestamp": 1030731866.2978516, + "heart_rate": 52 + }, + { + "timestamp": 1030731866.5478516, + "heart_rate": 52 + }, + { + "timestamp": 1030731866.7177734, + "heart_rate": 52 + }, + { + "timestamp": 1030731866.9677734, + "heart_rate": 52 + }, + { + "timestamp": 1030731867.2177734, + "heart_rate": 52 + }, + { + "timestamp": 1030731867.4677734, + "heart_rate": 52 + }, + { + "timestamp": 1030731867.7177734, + "heart_rate": 52 + }, + { + "timestamp": 1030731867.8710938, + "heart_rate": 52 + }, + { + "timestamp": 1030731868.1210938, + "heart_rate": 52 + }, + { + "timestamp": 1030731868.3710938, + "heart_rate": 52 + }, + { + "timestamp": 1030731868.6210938, + "heart_rate": 52 + }, + { + "timestamp": 1030731868.8710938, + "heart_rate": 52 + }, + { + "timestamp": 1030731869.0410156, + "heart_rate": 52 + }, + { + "timestamp": 1030731869.2910156, + "heart_rate": 52 + }, + { + "timestamp": 1030731869.5410156, + "heart_rate": 52 + }, + { + "timestamp": 1030731869.7910156, + "heart_rate": 52 + }, + { + "timestamp": 1030731870.0410156, + "heart_rate": 52 + }, + { + "timestamp": 1030731870.2255859, + "heart_rate": 51 + }, + { + "timestamp": 1030731870.4755859, + "heart_rate": 51 + }, + { + "timestamp": 1030731870.7255859, + "heart_rate": 51 + }, + { + "timestamp": 1030731870.9755859, + "heart_rate": 51 + }, + { + "timestamp": 1030731871.2255859, + "heart_rate": 51 + }, + { + "timestamp": 1030731871.3925781, + "heart_rate": 51 + }, + { + "timestamp": 1030731871.6425781, + "heart_rate": 51 + }, + { + "timestamp": 1030731871.8925781, + "heart_rate": 51 + }, + { + "timestamp": 1030731872.1425781, + "heart_rate": 51 + }, + { + "timestamp": 1030731872.3925781, + "heart_rate": 51 + }, + { + "timestamp": 1030731872.5810547, + "heart_rate": 51 + }, + { + "timestamp": 1030731872.8310547, + "heart_rate": 51 + }, + { + "timestamp": 1030731873.0810547, + "heart_rate": 51 + }, + { + "timestamp": 1030731873.3310547, + "heart_rate": 51 + }, + { + "timestamp": 1030731873.5810547, + "heart_rate": 51 + }, + { + "timestamp": 1030731873.7929688, + "heart_rate": 51 + }, + { + "timestamp": 1030731874.0429688, + "heart_rate": 51 + }, + { + "timestamp": 1030731874.2929688, + "heart_rate": 51 + }, + { + "timestamp": 1030731874.5429688, + "heart_rate": 51 + }, + { + "timestamp": 1030731874.7929688, + "heart_rate": 51 + }, + { + "timestamp": 1030731874.9335938, + "heart_rate": 51 + }, + { + "timestamp": 1030731875.1835938, + "heart_rate": 51 + }, + { + "timestamp": 1030731875.4335938, + "heart_rate": 51 + }, + { + "timestamp": 1030731875.6835938, + "heart_rate": 51 + }, + { + "timestamp": 1030731875.9335938, + "heart_rate": 51 + }, + { + "timestamp": 1030731876.0634766, + "heart_rate": 52 + }, + { + "timestamp": 1030731876.3134766, + "heart_rate": 52 + }, + { + "timestamp": 1030731876.5634766, + "heart_rate": 52 + }, + { + "timestamp": 1030731876.8134766, + "heart_rate": 52 + }, + { + "timestamp": 1030731877.0634766, + "heart_rate": 52 + }, + { + "timestamp": 1030731877.2080078, + "heart_rate": 52 + }, + { + "timestamp": 1030731877.4580078, + "heart_rate": 52 + }, + { + "timestamp": 1030731877.7080078, + "heart_rate": 52 + }, + { + "timestamp": 1030731877.9580078, + "heart_rate": 52 + }, + { + "timestamp": 1030731878.2080078, + "heart_rate": 52 + }, + { + "timestamp": 1030731878.3320312, + "heart_rate": 53 + }, + { + "timestamp": 1030731878.5820312, + "heart_rate": 53 + }, + { + "timestamp": 1030731878.8320312, + "heart_rate": 53 + }, + { + "timestamp": 1030731879.0820312, + "heart_rate": 53 + }, + { + "timestamp": 1030731879.3320312, + "heart_rate": 53 + }, + { + "timestamp": 1030731879.4472656, + "heart_rate": 53 + }, + { + "timestamp": 1030731879.6972656, + "heart_rate": 53 + }, + { + "timestamp": 1030731879.9472656, + "heart_rate": 53 + }, + { + "timestamp": 1030731880.1972656, + "heart_rate": 53 + }, + { + "timestamp": 1030731880.4472656, + "heart_rate": 53 + }, + { + "timestamp": 1030731880.5517578, + "heart_rate": 53 + }, + { + "timestamp": 1030731880.8017578, + "heart_rate": 53 + }, + { + "timestamp": 1030731881.0517578, + "heart_rate": 53 + }, + { + "timestamp": 1030731881.3017578, + "heart_rate": 53 + }, + { + "timestamp": 1030731881.5517578, + "heart_rate": 53 + }, + { + "timestamp": 1030731881.6748047, + "heart_rate": 54 + }, + { + "timestamp": 1030731881.9248047, + "heart_rate": 54 + }, + { + "timestamp": 1030731882.1748047, + "heart_rate": 54 + }, + { + "timestamp": 1030731882.4248047, + "heart_rate": 54 + }, + { + "timestamp": 1030731882.6748047, + "heart_rate": 54 + }, + { + "timestamp": 1030731882.8388672, + "heart_rate": 54 + }, + { + "timestamp": 1030731883.0888672, + "heart_rate": 54 + }, + { + "timestamp": 1030731883.3388672, + "heart_rate": 54 + }, + { + "timestamp": 1030731883.5888672, + "heart_rate": 54 + }, + { + "timestamp": 1030731883.8388672, + "heart_rate": 54 + }, + { + "timestamp": 1030731883.9521484, + "heart_rate": 53 + }, + { + "timestamp": 1030731884.2021484, + "heart_rate": 53 + }, + { + "timestamp": 1030731884.4521484, + "heart_rate": 53 + }, + { + "timestamp": 1030731884.7021484, + "heart_rate": 53 + }, + { + "timestamp": 1030731884.9521484, + "heart_rate": 53 + }, + { + "timestamp": 1030731885.0771484, + "heart_rate": 53 + }, + { + "timestamp": 1030731885.3271484, + "heart_rate": 53 + }, + { + "timestamp": 1030731885.5771484, + "heart_rate": 53 + }, + { + "timestamp": 1030731885.8271484, + "heart_rate": 53 + }, + { + "timestamp": 1030731886.0771484, + "heart_rate": 53 + }, + { + "timestamp": 1030731886.2207031, + "heart_rate": 53 + }, + { + "timestamp": 1030731886.4707031, + "heart_rate": 53 + }, + { + "timestamp": 1030731886.7207031, + "heart_rate": 53 + }, + { + "timestamp": 1030731886.9707031, + "heart_rate": 53 + }, + { + "timestamp": 1030731887.2207031, + "heart_rate": 53 + }, + { + "timestamp": 1030731887.34375, + "heart_rate": 53 + }, + { + "timestamp": 1030731887.59375, + "heart_rate": 53 + }, + { + "timestamp": 1030731887.84375, + "heart_rate": 53 + }, + { + "timestamp": 1030731888.09375, + "heart_rate": 53 + }, + { + "timestamp": 1030731888.34375, + "heart_rate": 53 + }, + { + "timestamp": 1030731888.4746094, + "heart_rate": 53 + }, + { + "timestamp": 1030731888.7246094, + "heart_rate": 53 + }, + { + "timestamp": 1030731888.9746094, + "heart_rate": 53 + }, + { + "timestamp": 1030731889.2246094, + "heart_rate": 53 + }, + { + "timestamp": 1030731889.4746094, + "heart_rate": 53 + }, + { + "timestamp": 1030731889.6162109, + "heart_rate": 53 + }, + { + "timestamp": 1030731889.8662109, + "heart_rate": 53 + }, + { + "timestamp": 1030731890.1162109, + "heart_rate": 53 + }, + { + "timestamp": 1030731890.3662109, + "heart_rate": 53 + }, + { + "timestamp": 1030731890.6162109, + "heart_rate": 53 + }, + { + "timestamp": 1030731890.7529297, + "heart_rate": 53 + }, + { + "timestamp": 1030731891.0029297, + "heart_rate": 53 + }, + { + "timestamp": 1030731891.2529297, + "heart_rate": 53 + }, + { + "timestamp": 1030731891.5029297, + "heart_rate": 53 + }, + { + "timestamp": 1030731891.7529297, + "heart_rate": 53 + }, + { + "timestamp": 1030731891.9287109, + "heart_rate": 53 + }, + { + "timestamp": 1030731892.1787109, + "heart_rate": 53 + }, + { + "timestamp": 1030731892.4287109, + "heart_rate": 53 + }, + { + "timestamp": 1030731892.6787109, + "heart_rate": 53 + }, + { + "timestamp": 1030731892.9287109, + "heart_rate": 53 + }, + { + "timestamp": 1030731893.1132812, + "heart_rate": 52 + }, + { + "timestamp": 1030731893.3632812, + "heart_rate": 52 + }, + { + "timestamp": 1030731893.6132812, + "heart_rate": 52 + }, + { + "timestamp": 1030731893.8632812, + "heart_rate": 52 + }, + { + "timestamp": 1030731894.1132812, + "heart_rate": 52 + }, + { + "timestamp": 1030731894.3251953, + "heart_rate": 51 + }, + { + "timestamp": 1030731894.5751953, + "heart_rate": 51 + }, + { + "timestamp": 1030731894.8251953, + "heart_rate": 51 + }, + { + "timestamp": 1030731895.0751953, + "heart_rate": 51 + }, + { + "timestamp": 1030731895.3251953, + "heart_rate": 51 + }, + { + "timestamp": 1030731895.5351562, + "heart_rate": 50 + }, + { + "timestamp": 1030731895.7851562, + "heart_rate": 50 + }, + { + "timestamp": 1030731896.0351562, + "heart_rate": 50 + }, + { + "timestamp": 1030731896.2851562, + "heart_rate": 50 + }, + { + "timestamp": 1030731896.5351562, + "heart_rate": 50 + }, + { + "timestamp": 1030731896.7724609, + "heart_rate": 50 + }, + { + "timestamp": 1030731897.0224609, + "heart_rate": 50 + }, + { + "timestamp": 1030731897.2724609, + "heart_rate": 50 + }, + { + "timestamp": 1030731897.5224609, + "heart_rate": 50 + }, + { + "timestamp": 1030731897.7724609, + "heart_rate": 50 + }, + { + "timestamp": 1030731897.9892578, + "heart_rate": 50 + }, + { + "timestamp": 1030731898.2392578, + "heart_rate": 50 + }, + { + "timestamp": 1030731898.4892578, + "heart_rate": 50 + }, + { + "timestamp": 1030731898.7392578, + "heart_rate": 50 + }, + { + "timestamp": 1030731898.9892578, + "heart_rate": 50 + }, + { + "timestamp": 1030731899.1728516, + "heart_rate": 49 + }, + { + "timestamp": 1030731899.4228516, + "heart_rate": 49 + }, + { + "timestamp": 1030731899.6728516, + "heart_rate": 49 + }, + { + "timestamp": 1030731899.9228516, + "heart_rate": 49 + }, + { + "timestamp": 1030731900.1728516, + "heart_rate": 49 + }, + { + "timestamp": 1030731900.3134766, + "heart_rate": 50 + }, + { + "timestamp": 1030731900.5634766, + "heart_rate": 50 + }, + { + "timestamp": 1030731900.8134766, + "heart_rate": 50 + }, + { + "timestamp": 1030731901.0634766, + "heart_rate": 50 + }, + { + "timestamp": 1030731901.3134766, + "heart_rate": 50 + }, + { + "timestamp": 1030731901.4345703, + "heart_rate": 51 + }, + { + "timestamp": 1030731901.6845703, + "heart_rate": 51 + }, + { + "timestamp": 1030731901.9345703, + "heart_rate": 51 + }, + { + "timestamp": 1030731902.1845703, + "heart_rate": 51 + }, + { + "timestamp": 1030731902.4345703, + "heart_rate": 51 + }, + { + "timestamp": 1030731902.4814453, + "heart_rate": 52 + }, + { + "timestamp": 1030731902.7314453, + "heart_rate": 52 + }, + { + "timestamp": 1030731902.9814453, + "heart_rate": 52 + }, + { + "timestamp": 1030731903.2314453, + "heart_rate": 52 + }, + { + "timestamp": 1030731903.4345703, + "heart_rate": 55 + }, + { + "timestamp": 1030731903.6845703, + "heart_rate": 55 + }, + { + "timestamp": 1030731903.9345703, + "heart_rate": 55 + }, + { + "timestamp": 1030731904.1845703, + "heart_rate": 55 + }, + { + "timestamp": 1030731904.390625, + "heart_rate": 58 + }, + { + "timestamp": 1030731904.640625, + "heart_rate": 58 + }, + { + "timestamp": 1030731904.890625, + "heart_rate": 58 + }, + { + "timestamp": 1030731905.140625, + "heart_rate": 58 + }, + { + "timestamp": 1030731905.390625, + "heart_rate": 58 + }, + { + "timestamp": 1030731905.4042969, + "heart_rate": 60 + }, + { + "timestamp": 1030731905.6542969, + "heart_rate": 60 + }, + { + "timestamp": 1030731905.9042969, + "heart_rate": 60 + }, + { + "timestamp": 1030731906.1542969, + "heart_rate": 60 + }, + { + "timestamp": 1030731906.4042969, + "heart_rate": 60 + }, + { + "timestamp": 1030731906.4287109, + "heart_rate": 60 + }, + { + "timestamp": 1030731906.6787109, + "heart_rate": 60 + }, + { + "timestamp": 1030731906.9287109, + "heart_rate": 60 + }, + { + "timestamp": 1030731907.1787109, + "heart_rate": 60 + }, + { + "timestamp": 1030731907.4287109, + "heart_rate": 60 + }, + { + "timestamp": 1030731907.4492188, + "heart_rate": 59 + }, + { + "timestamp": 1030731907.6992188, + "heart_rate": 59 + }, + { + "timestamp": 1030731907.9492188, + "heart_rate": 59 + }, + { + "timestamp": 1030731908.1992188, + "heart_rate": 59 + }, + { + "timestamp": 1030731908.4492188, + "heart_rate": 59 + }, + { + "timestamp": 1030731908.4765625, + "heart_rate": 59 + }, + { + "timestamp": 1030731908.7265625, + "heart_rate": 59 + }, + { + "timestamp": 1030731908.9765625, + "heart_rate": 59 + }, + { + "timestamp": 1030731909.2265625, + "heart_rate": 59 + }, + { + "timestamp": 1030731909.4765625, + "heart_rate": 59 + }, + { + "timestamp": 1030731909.5234375, + "heart_rate": 59 + }, + { + "timestamp": 1030731909.7734375, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.0234375, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.2734375, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.3554688, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.6054688, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.8554688, + "heart_rate": 59 + }, + { + "timestamp": 1030731910.8701172, + "heart_rate": 59 + }, + { + "timestamp": 1030731911.1201172, + "heart_rate": 59 + }, + { + "timestamp": 1030731911.3701172, + "heart_rate": 59 + }, + { + "timestamp": 1030731911.6201172, + "heart_rate": 59 + }, + { + "timestamp": 1030731911.8701172, + "heart_rate": 59 + }, + { + "timestamp": 1030731911.9150391, + "heart_rate": 59 + }, + { + "timestamp": 1030731912.1650391, + "heart_rate": 59 + }, + { + "timestamp": 1030731912.4150391, + "heart_rate": 59 + }, + { + "timestamp": 1030731912.6650391, + "heart_rate": 59 + }, + { + "timestamp": 1030731912.9150391, + "heart_rate": 59 + }, + { + "timestamp": 1030731912.9345703, + "heart_rate": 59 + }, + { + "timestamp": 1030731913.1845703, + "heart_rate": 59 + }, + { + "timestamp": 1030731913.4345703, + "heart_rate": 59 + }, + { + "timestamp": 1030731913.6845703, + "heart_rate": 59 + }, + { + "timestamp": 1030731913.9345703, + "heart_rate": 59 + }, + { + "timestamp": 1030731913.9394531, + "heart_rate": 59 + }, + { + "timestamp": 1030731914.1894531, + "heart_rate": 59 + }, + { + "timestamp": 1030731914.4394531, + "heart_rate": 59 + }, + { + "timestamp": 1030731914.6894531, + "heart_rate": 59 + }, + { + "timestamp": 1030731914.8974609, + "heart_rate": 59 + }, + { + "timestamp": 1030731915.1474609, + "heart_rate": 59 + }, + { + "timestamp": 1030731915.3642578, + "heart_rate": 59 + }, + { + "timestamp": 1030731915.6142578, + "heart_rate": 59 + }, + { + "timestamp": 1030731915.8642578, + "heart_rate": 59 + }, + { + "timestamp": 1030731916.1142578, + "heart_rate": 59 + }, + { + "timestamp": 1030731916.3642578, + "heart_rate": 59 + }, + { + "timestamp": 1030731916.4052734, + "heart_rate": 59 + }, + { + "timestamp": 1030731916.6552734, + "heart_rate": 59 + }, + { + "timestamp": 1030731916.9052734, + "heart_rate": 59 + }, + { + "timestamp": 1030731917.1552734, + "heart_rate": 59 + }, + { + "timestamp": 1030731917.3007812, + "heart_rate": 59 + }, + { + "timestamp": 1030731917.5507812, + "heart_rate": 59 + }, + { + "timestamp": 1030731917.8007812, + "heart_rate": 59 + }, + { + "timestamp": 1030731918.0507812, + "heart_rate": 59 + }, + { + "timestamp": 1030731918.1884766, + "heart_rate": 59 + }, + { + "timestamp": 1030731918.4384766, + "heart_rate": 59 + }, + { + "timestamp": 1030731918.6884766, + "heart_rate": 59 + }, + { + "timestamp": 1030731918.9384766, + "heart_rate": 59 + }, + { + "timestamp": 1030731919.1884766, + "heart_rate": 59 + }, + { + "timestamp": 1030731919.3427734, + "heart_rate": 59 + }, + { + "timestamp": 1030731919.5927734, + "heart_rate": 59 + }, + { + "timestamp": 1030731919.8427734, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.0927734, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.3427734, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.3964844, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.6464844, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.8964844, + "heart_rate": 59 + }, + { + "timestamp": 1030731920.9580078, + "heart_rate": 59 + }, + { + "timestamp": 1030731921.2080078, + "heart_rate": 59 + }, + { + "timestamp": 1030731921.4580078, + "heart_rate": 59 + }, + { + "timestamp": 1030731921.7080078, + "heart_rate": 59 + }, + { + "timestamp": 1030731921.9580078, + "heart_rate": 59 + }, + { + "timestamp": 1030731922.015625, + "heart_rate": 59 + }, + { + "timestamp": 1030731922.265625, + "heart_rate": 59 + }, + { + "timestamp": 1030731922.515625, + "heart_rate": 59 + }, + { + "timestamp": 1030731922.765625, + "heart_rate": 59 + }, + { + "timestamp": 1030731922.9394531, + "heart_rate": 59 + }, + { + "timestamp": 1030731923.1894531, + "heart_rate": 59 + }, + { + "timestamp": 1030731923.4394531, + "heart_rate": 59 + }, + { + "timestamp": 1030731923.609375, + "heart_rate": 59 + }, + { + "timestamp": 1030731923.859375, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.109375, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.1474609, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.3974609, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.6474609, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.8974609, + "heart_rate": 59 + }, + { + "timestamp": 1030731924.9257812, + "heart_rate": 60 + }, + { + "timestamp": 1030731925.1757812, + "heart_rate": 60 + }, + { + "timestamp": 1030731925.4257812, + "heart_rate": 60 + }, + { + "timestamp": 1030731925.6757812, + "heart_rate": 60 + }, + { + "timestamp": 1030731925.7041016, + "heart_rate": 60 + }, + { + "timestamp": 1030731925.9541016, + "heart_rate": 60 + }, + { + "timestamp": 1030731926.2041016, + "heart_rate": 60 + }, + { + "timestamp": 1030731926.4541016, + "heart_rate": 60 + }, + { + "timestamp": 1030731926.4824219, + "heart_rate": 60 + }, + { + "timestamp": 1030731926.7324219, + "heart_rate": 60 + }, + { + "timestamp": 1030731926.9824219, + "heart_rate": 60 + }, + { + "timestamp": 1030731927.2324219, + "heart_rate": 60 + }, + { + "timestamp": 1030731927.4824219, + "heart_rate": 60 + }, + { + "timestamp": 1030731927.5693359, + "heart_rate": 59 + }, + { + "timestamp": 1030731927.8193359, + "heart_rate": 59 + }, + { + "timestamp": 1030731928.0693359, + "heart_rate": 59 + }, + { + "timestamp": 1030731928.3193359, + "heart_rate": 59 + }, + { + "timestamp": 1030731928.5361328, + "heart_rate": 59 + }, + { + "timestamp": 1030731928.7861328, + "heart_rate": 59 + }, + { + "timestamp": 1030731929.0361328, + "heart_rate": 59 + }, + { + "timestamp": 1030731929.2861328, + "heart_rate": 59 + }, + { + "timestamp": 1030731929.4199219, + "heart_rate": 59 + }, + { + "timestamp": 1030731929.6699219, + "heart_rate": 59 + }, + { + "timestamp": 1030731929.9199219, + "heart_rate": 59 + }, + { + "timestamp": 1030731930.1699219, + "heart_rate": 59 + }, + { + "timestamp": 1030731930.4199219, + "heart_rate": 59 + }, + { + "timestamp": 1030731930.4208984, + "heart_rate": 59 + }, + { + "timestamp": 1030731930.6708984, + "heart_rate": 59 + }, + { + "timestamp": 1030731930.9208984, + "heart_rate": 59 + }, + { + "timestamp": 1030731931.1708984, + "heart_rate": 59 + }, + { + "timestamp": 1030731931.4208984, + "heart_rate": 59 + }, + { + "timestamp": 1030731931.4853516, + "heart_rate": 58 + }, + { + "timestamp": 1030731931.7353516, + "heart_rate": 58 + }, + { + "timestamp": 1030731931.9853516, + "heart_rate": 58 + }, + { + "timestamp": 1030731932.2353516, + "heart_rate": 58 + }, + { + "timestamp": 1030731932.4853516, + "heart_rate": 58 + }, + { + "timestamp": 1030731932.4863281, + "heart_rate": 58 + }, + { + "timestamp": 1030731932.7363281, + "heart_rate": 58 + }, + { + "timestamp": 1030731932.9863281, + "heart_rate": 58 + }, + { + "timestamp": 1030731933.2363281, + "heart_rate": 58 + }, + { + "timestamp": 1030731933.4863281, + "heart_rate": 58 + }, + { + "timestamp": 1030731933.6103516, + "heart_rate": 58 + }, + { + "timestamp": 1030731933.8603516, + "heart_rate": 58 + }, + { + "timestamp": 1030731934.1103516, + "heart_rate": 58 + }, + { + "timestamp": 1030731934.1777344, + "heart_rate": 58 + }, + { + "timestamp": 1030731934.4277344, + "heart_rate": 58 + }, + { + "timestamp": 1030731934.6777344, + "heart_rate": 58 + }, + { + "timestamp": 1030731934.8720703, + "heart_rate": 58 + }, + { + "timestamp": 1030731935.1220703, + "heart_rate": 58 + }, + { + "timestamp": 1030731935.3720703, + "heart_rate": 58 + }, + { + "timestamp": 1030731935.6220703, + "heart_rate": 58 + }, + { + "timestamp": 1030731935.8076172, + "heart_rate": 58 + }, + { + "timestamp": 1030731936.0576172, + "heart_rate": 58 + }, + { + "timestamp": 1030731936.2207031, + "heart_rate": 58 + }, + { + "timestamp": 1030731936.4707031, + "heart_rate": 58 + }, + { + "timestamp": 1030731936.7207031, + "heart_rate": 58 + }, + { + "timestamp": 1030731936.9707031, + "heart_rate": 58 + }, + { + "timestamp": 1030731937.0410156, + "heart_rate": 58 + }, + { + "timestamp": 1030731937.2910156, + "heart_rate": 58 + }, + { + "timestamp": 1030731937.5410156, + "heart_rate": 58 + }, + { + "timestamp": 1030731937.7324219, + "heart_rate": 58 + }, + { + "timestamp": 1030731937.9824219, + "heart_rate": 58 + }, + { + "timestamp": 1030731938.2324219, + "heart_rate": 58 + }, + { + "timestamp": 1030731938.4638672, + "heart_rate": 58 + }, + { + "timestamp": 1030731938.7138672, + "heart_rate": 58 + }, + { + "timestamp": 1030731938.9638672, + "heart_rate": 58 + }, + { + "timestamp": 1030731939.1318359, + "heart_rate": 58 + }, + { + "timestamp": 1030731939.3818359, + "heart_rate": 58 + }, + { + "timestamp": 1030731939.6318359, + "heart_rate": 58 + }, + { + "timestamp": 1030731939.765625, + "heart_rate": 58 + }, + { + "timestamp": 1030731940.015625, + "heart_rate": 58 + }, + { + "timestamp": 1030731940.2099609, + "heart_rate": 58 + }, + { + "timestamp": 1030731940.4599609, + "heart_rate": 58 + }, + { + "timestamp": 1030731940.7099609, + "heart_rate": 58 + }, + { + "timestamp": 1030731940.8291016, + "heart_rate": 59 + }, + { + "timestamp": 1030731941.0791016, + "heart_rate": 59 + }, + { + "timestamp": 1030731941.3291016, + "heart_rate": 59 + }, + { + "timestamp": 1030731941.5673828, + "heart_rate": 59 + }, + { + "timestamp": 1030731941.8173828, + "heart_rate": 59 + }, + { + "timestamp": 1030731941.9833984, + "heart_rate": 59 + }, + { + "timestamp": 1030731942.2333984, + "heart_rate": 59 + }, + { + "timestamp": 1030731942.4833984, + "heart_rate": 59 + }, + { + "timestamp": 1030731942.5820312, + "heart_rate": 59 + }, + { + "timestamp": 1030731942.8320312, + "heart_rate": 59 + }, + { + "timestamp": 1030731943.0820312, + "heart_rate": 59 + }, + { + "timestamp": 1030731943.1806641, + "heart_rate": 60 + }, + { + "timestamp": 1030731943.4306641, + "heart_rate": 60 + }, + { + "timestamp": 1030731943.6279297, + "heart_rate": 60 + }, + { + "timestamp": 1030731943.8779297, + "heart_rate": 60 + }, + { + "timestamp": 1030731944.1279297, + "heart_rate": 60 + }, + { + "timestamp": 1030731944.3300781, + "heart_rate": 60 + }, + { + "timestamp": 1030731944.5800781, + "heart_rate": 60 + }, + { + "timestamp": 1030731944.8300781, + "heart_rate": 60 + }, + { + "timestamp": 1030731944.9257812, + "heart_rate": 60 + }, + { + "timestamp": 1030731945.1757812, + "heart_rate": 60 + }, + { + "timestamp": 1030731945.4257812, + "heart_rate": 60 + }, + { + "timestamp": 1030731945.515625, + "heart_rate": 61 + }, + { + "timestamp": 1030731945.765625, + "heart_rate": 61 + }, + { + "timestamp": 1030731946.015625, + "heart_rate": 61 + }, + { + "timestamp": 1030731946.1103516, + "heart_rate": 63 + }, + { + "timestamp": 1030731946.3603516, + "heart_rate": 63 + }, + { + "timestamp": 1030731946.5888672, + "heart_rate": 63 + }, + { + "timestamp": 1030731946.8388672, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.0888672, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.1757812, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.4257812, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.6757812, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.7460938, + "heart_rate": 63 + }, + { + "timestamp": 1030731947.9960938, + "heart_rate": 63 + }, + { + "timestamp": 1030731948.2460938, + "heart_rate": 63 + }, + { + "timestamp": 1030731948.3330078, + "heart_rate": 62 + }, + { + "timestamp": 1030731948.5830078, + "heart_rate": 62 + }, + { + "timestamp": 1030731948.8330078, + "heart_rate": 62 + }, + { + "timestamp": 1030731948.9072266, + "heart_rate": 62 + }, + { + "timestamp": 1030731949.1572266, + "heart_rate": 62 + }, + { + "timestamp": 1030731949.4072266, + "heart_rate": 62 + }, + { + "timestamp": 1030731949.5498047, + "heart_rate": 62 + }, + { + "timestamp": 1030731949.7998047, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.0498047, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.1660156, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.4160156, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.6660156, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.6816406, + "heart_rate": 62 + }, + { + "timestamp": 1030731950.9316406, + "heart_rate": 62 + }, + { + "timestamp": 1030731951.1816406, + "heart_rate": 62 + }, + { + "timestamp": 1030731951.4130859, + "heart_rate": 62 + }, + { + "timestamp": 1030731951.6630859, + "heart_rate": 62 + }, + { + "timestamp": 1030731951.9130859, + "heart_rate": 62 + }, + { + "timestamp": 1030731952.1630859, + "heart_rate": 62 + }, + { + "timestamp": 1030731952.2177734, + "heart_rate": 62 + }, + { + "timestamp": 1030731952.4677734, + "heart_rate": 62 + }, + { + "timestamp": 1030731952.7177734, + "heart_rate": 62 + }, + { + "timestamp": 1030731952.8798828, + "heart_rate": 62 + }, + { + "timestamp": 1030731953.1298828, + "heart_rate": 62 + }, + { + "timestamp": 1030731953.3798828, + "heart_rate": 62 + }, + { + "timestamp": 1030731953.6298828, + "heart_rate": 62 + }, + { + "timestamp": 1030731953.7441406, + "heart_rate": 62 + }, + { + "timestamp": 1030731953.9941406, + "heart_rate": 62 + }, + { + "timestamp": 1030731954.2441406, + "heart_rate": 62 + }, + { + "timestamp": 1030731954.4570312, + "heart_rate": 62 + }, + { + "timestamp": 1030731954.7070312, + "heart_rate": 62 + }, + { + "timestamp": 1030731954.9570312, + "heart_rate": 62 + }, + { + "timestamp": 1030731955.2070312, + "heart_rate": 62 + }, + { + "timestamp": 1030731955.2441406, + "heart_rate": 62 + }, + { + "timestamp": 1030731955.4941406, + "heart_rate": 62 + }, + { + "timestamp": 1030731955.7441406, + "heart_rate": 62 + }, + { + "timestamp": 1030731955.9755859, + "heart_rate": 62 + }, + { + "timestamp": 1030731956.2255859, + "heart_rate": 62 + }, + { + "timestamp": 1030731956.4755859, + "heart_rate": 62 + }, + { + "timestamp": 1030731956.5449219, + "heart_rate": 62 + }, + { + "timestamp": 1030731956.7949219, + "heart_rate": 62 + }, + { + "timestamp": 1030731957.0449219, + "heart_rate": 62 + }, + { + "timestamp": 1030731957.203125, + "heart_rate": 62 + }, + { + "timestamp": 1030731957.453125, + "heart_rate": 62 + }, + { + "timestamp": 1030731957.703125, + "heart_rate": 62 + }, + { + "timestamp": 1030731957.8857422, + "heart_rate": 62 + }, + { + "timestamp": 1030731958.1357422, + "heart_rate": 62 + }, + { + "timestamp": 1030731958.3857422, + "heart_rate": 62 + }, + { + "timestamp": 1030731958.6220703, + "heart_rate": 62 + }, + { + "timestamp": 1030731958.8720703, + "heart_rate": 62 + }, + { + "timestamp": 1030731959.1220703, + "heart_rate": 62 + }, + { + "timestamp": 1030731959.3173828, + "heart_rate": 62 + }, + { + "timestamp": 1030731959.5673828, + "heart_rate": 62 + }, + { + "timestamp": 1030731959.8173828, + "heart_rate": 62 + }, + { + "timestamp": 1030731960.0673828, + "heart_rate": 62 + }, + { + "timestamp": 1030731960.0693359, + "heart_rate": 62 + }, + { + "timestamp": 1030731960.3193359, + "heart_rate": 62 + }, + { + "timestamp": 1030731960.5693359, + "heart_rate": 62 + }, + { + "timestamp": 1030731960.7792969, + "heart_rate": 61 + }, + { + "timestamp": 1030731961.0292969, + "heart_rate": 61 + }, + { + "timestamp": 1030731961.2792969, + "heart_rate": 61 + }, + { + "timestamp": 1030731961.4892578, + "heart_rate": 61 + }, + { + "timestamp": 1030731961.7392578, + "heart_rate": 61 + }, + { + "timestamp": 1030731961.9892578, + "heart_rate": 61 + }, + { + "timestamp": 1030731962.1982422, + "heart_rate": 61 + }, + { + "timestamp": 1030731962.4482422, + "heart_rate": 61 + }, + { + "timestamp": 1030731962.6982422, + "heart_rate": 61 + }, + { + "timestamp": 1030731962.9482422, + "heart_rate": 61 + }, + { + "timestamp": 1030731963.1982422, + "heart_rate": 61 + }, + { + "timestamp": 1030731963.4482422, + "heart_rate": 61 + }, + { + "timestamp": 1030731963.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731963.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731963.8691406, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.1191406, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.1855469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.4355469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731964.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731965.0605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731965.3105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731965.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731965.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731966.0605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731966.3105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731966.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731966.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731967.0605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731967.3105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731967.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731967.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731968.0605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731968.3105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731968.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731968.8105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731969.0605469, + "heart_rate": 71 + }, + { + "timestamp": 1030731969.3105469, + "heart_rate": 71 + }, + { + "timestamp": 1030731969.5605469, + "heart_rate": 71 + }, + { + "timestamp": 1030732260, + "heart_rate": 71 + }, + { + "timestamp": 1030732260.25, + "heart_rate": 71 + }, + { + "timestamp": 1030732260.5, + "heart_rate": 71 + }, + { + "timestamp": 1030732260.75, + "heart_rate": 71 + }, + { + "timestamp": 1030732261, + "heart_rate": 71 + }, + { + "timestamp": 1030732261.25, + "heart_rate": 71 + }, + { + "timestamp": 1030732261.5, + "heart_rate": 71 + }, + { + "timestamp": 1030732261.75, + "heart_rate": 71 + }, + { + "timestamp": 1030732262, + "heart_rate": 71 + }, + { + "timestamp": 1030732262.25, + "heart_rate": 71 + }, + { + "timestamp": 1030732262.5, + "heart_rate": 71 + }, + { + "timestamp": 1030732262.75, + "heart_rate": 71 + }, + { + "timestamp": 1030732263, + "heart_rate": 71 + }, + { + "timestamp": 1030732263.25, + "heart_rate": 71 + }, + { + "timestamp": 1030732263.2851562, + "heart_rate": 71 + }, + { + "timestamp": 1030732263.5351562, + "heart_rate": 71 + }, + { + "timestamp": 1030732263.7851562, + "heart_rate": 71 + }, + { + "timestamp": 1030732264.0351562, + "heart_rate": 71 + }, + { + "timestamp": 1030732264.2851562, + "heart_rate": 71 + }, + { + "timestamp": 1030732264.3388672, + "heart_rate": 71 + }, + { + "timestamp": 1030732264.5888672, + "heart_rate": 71 + }, + { + "timestamp": 1030732264.8388672, + "heart_rate": 71 + }, + { + "timestamp": 1030732265.0888672, + "heart_rate": 71 + }, + { + "timestamp": 1030732265.3212891, + "heart_rate": 71 + }, + { + "timestamp": 1030732265.5712891, + "heart_rate": 71 + }, + { + "timestamp": 1030732265.8212891, + "heart_rate": 71 + }, + { + "timestamp": 1030732266.0712891, + "heart_rate": 71 + }, + { + "timestamp": 1030732266.3193359, + "heart_rate": 71 + }, + { + "timestamp": 1030732266.5693359, + "heart_rate": 71 + }, + { + "timestamp": 1030732266.8193359, + "heart_rate": 71 + }, + { + "timestamp": 1030732267.0693359, + "heart_rate": 71 + }, + { + "timestamp": 1030732267.2392578, + "heart_rate": 71 + }, + { + "timestamp": 1030732267.4892578, + "heart_rate": 71 + }, + { + "timestamp": 1030732267.7392578, + "heart_rate": 71 + }, + { + "timestamp": 1030732267.9892578, + "heart_rate": 71 + }, + { + "timestamp": 1030732268.1503906, + "heart_rate": 71 + }, + { + "timestamp": 1030732268.4003906, + "heart_rate": 71 + }, + { + "timestamp": 1030732268.6503906, + "heart_rate": 71 + }, + { + "timestamp": 1030732268.9003906, + "heart_rate": 71 + }, + { + "timestamp": 1030732269.0263672, + "heart_rate": 69 + }, + { + "timestamp": 1030732269.2763672, + "heart_rate": 69 + }, + { + "timestamp": 1030732269.5263672, + "heart_rate": 69 + }, + { + "timestamp": 1030732269.7763672, + "heart_rate": 69 + }, + { + "timestamp": 1030732270.0263672, + "heart_rate": 69 + }, + { + "timestamp": 1030732270.0410156, + "heart_rate": 68 + }, + { + "timestamp": 1030732270.2910156, + "heart_rate": 68 + }, + { + "timestamp": 1030732270.5400391, + "heart_rate": 68 + }, + { + "timestamp": 1030732270.7900391, + "heart_rate": 68 + }, + { + "timestamp": 1030732271.0400391, + "heart_rate": 68 + }, + { + "timestamp": 1030732271.2900391, + "heart_rate": 68 + }, + { + "timestamp": 1030732271.5400391, + "heart_rate": 68 + }, + { + "timestamp": 1030732271.5527344, + "heart_rate": 68 + }, + { + "timestamp": 1030732271.8027344, + "heart_rate": 68 + }, + { + "timestamp": 1030732272.0527344, + "heart_rate": 68 + }, + { + "timestamp": 1030732272.1083984, + "heart_rate": 68 + }, + { + "timestamp": 1030732272.3583984, + "heart_rate": 68 + }, + { + "timestamp": 1030732272.6083984, + "heart_rate": 68 + }, + { + "timestamp": 1030732272.8583984, + "heart_rate": 68 + }, + { + "timestamp": 1030732273.1083984, + "heart_rate": 68 + }, + { + "timestamp": 1030732273.1123047, + "heart_rate": 68 + }, + { + "timestamp": 1030732273.3623047, + "heart_rate": 68 + }, + { + "timestamp": 1030732273.6123047, + "heart_rate": 68 + }, + { + "timestamp": 1030732273.8623047, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.1123047, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.1582031, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.4082031, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.4394531, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.6894531, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.9394531, + "heart_rate": 68 + }, + { + "timestamp": 1030732274.9423828, + "heart_rate": 68 + }, + { + "timestamp": 1030732275.1923828, + "heart_rate": 68 + }, + { + "timestamp": 1030732275.4423828, + "heart_rate": 68 + }, + { + "timestamp": 1030732275.6923828, + "heart_rate": 68 + }, + { + "timestamp": 1030732275.7841797, + "heart_rate": 68 + }, + { + "timestamp": 1030732276.0341797, + "heart_rate": 68 + }, + { + "timestamp": 1030732276.2841797, + "heart_rate": 68 + }, + { + "timestamp": 1030732276.5341797, + "heart_rate": 68 + }, + { + "timestamp": 1030732276.7841797, + "heart_rate": 68 + }, + { + "timestamp": 1030732276.8095703, + "heart_rate": 68 + }, + { + "timestamp": 1030732277.0595703, + "heart_rate": 68 + }, + { + "timestamp": 1030732277.3095703, + "heart_rate": 68 + }, + { + "timestamp": 1030732277.5595703, + "heart_rate": 68 + }, + { + "timestamp": 1030732277.6220703, + "heart_rate": 68 + }, + { + "timestamp": 1030732277.8720703, + "heart_rate": 68 + }, + { + "timestamp": 1030732278.1220703, + "heart_rate": 68 + }, + { + "timestamp": 1030732278.3203125, + "heart_rate": 68 + }, + { + "timestamp": 1030732278.5703125, + "heart_rate": 68 + }, + { + "timestamp": 1030732278.8203125, + "heart_rate": 68 + }, + { + "timestamp": 1030732279.0703125, + "heart_rate": 68 + }, + { + "timestamp": 1030732279.3203125, + "heart_rate": 68 + }, + { + "timestamp": 1030732279.3544922, + "heart_rate": 68 + }, + { + "timestamp": 1030732279.6044922, + "heart_rate": 68 + }, + { + "timestamp": 1030732279.8544922, + "heart_rate": 68 + }, + { + "timestamp": 1030732280.1044922, + "heart_rate": 68 + }, + { + "timestamp": 1030732280.2958984, + "heart_rate": 68 + }, + { + "timestamp": 1030732280.5458984, + "heart_rate": 68 + }, + { + "timestamp": 1030732280.7958984, + "heart_rate": 68 + }, + { + "timestamp": 1030732281.0458984, + "heart_rate": 68 + }, + { + "timestamp": 1030732281.1875, + "heart_rate": 69 + }, + { + "timestamp": 1030732281.4375, + "heart_rate": 69 + }, + { + "timestamp": 1030732281.6875, + "heart_rate": 69 + }, + { + "timestamp": 1030732281.9375, + "heart_rate": 69 + }, + { + "timestamp": 1030732282.1289062, + "heart_rate": 69 + }, + { + "timestamp": 1030732282.3789062, + "heart_rate": 69 + }, + { + "timestamp": 1030732282.6289062, + "heart_rate": 69 + }, + { + "timestamp": 1030732282.8789062, + "heart_rate": 69 + }, + { + "timestamp": 1030732283.1289062, + "heart_rate": 69 + }, + { + "timestamp": 1030732283.1308594, + "heart_rate": 69 + }, + { + "timestamp": 1030732283.3808594, + "heart_rate": 69 + }, + { + "timestamp": 1030732283.6308594, + "heart_rate": 69 + }, + { + "timestamp": 1030732283.8808594, + "heart_rate": 69 + }, + { + "timestamp": 1030732284.1308594, + "heart_rate": 70 + }, + { + "timestamp": 1030732284.3808594, + "heart_rate": 70 + }, + { + "timestamp": 1030732284.6308594, + "heart_rate": 70 + }, + { + "timestamp": 1030732284.8808594, + "heart_rate": 70 + }, + { + "timestamp": 1030732285.1308594, + "heart_rate": 70 + }, + { + "timestamp": 1030732285.1640625, + "heart_rate": 70 + }, + { + "timestamp": 1030732285.4140625, + "heart_rate": 70 + }, + { + "timestamp": 1030732285.6640625, + "heart_rate": 70 + }, + { + "timestamp": 1030732285.9140625, + "heart_rate": 70 + }, + { + "timestamp": 1030732286.1640625, + "heart_rate": 70 + }, + { + "timestamp": 1030732286.2080078, + "heart_rate": 69 + }, + { + "timestamp": 1030732286.4580078, + "heart_rate": 69 + }, + { + "timestamp": 1030732286.7080078, + "heart_rate": 69 + }, + { + "timestamp": 1030732286.9580078, + "heart_rate": 69 + }, + { + "timestamp": 1030732287.2080078, + "heart_rate": 69 + }, + { + "timestamp": 1030732287.3320312, + "heart_rate": 68 + }, + { + "timestamp": 1030732287.5820312, + "heart_rate": 68 + }, + { + "timestamp": 1030732287.8320312, + "heart_rate": 68 + }, + { + "timestamp": 1030732288.0820312, + "heart_rate": 68 + }, + { + "timestamp": 1030732288.3320312, + "heart_rate": 68 + }, + { + "timestamp": 1030732288.5820312, + "heart_rate": 68 + }, + { + "timestamp": 1030732288.5859375, + "heart_rate": 66 + }, + { + "timestamp": 1030732288.8359375, + "heart_rate": 66 + }, + { + "timestamp": 1030732289.0859375, + "heart_rate": 66 + }, + { + "timestamp": 1030732289.3359375, + "heart_rate": 66 + }, + { + "timestamp": 1030732289.5859375, + "heart_rate": 66 + }, + { + "timestamp": 1030732289.6240234, + "heart_rate": 65 + }, + { + "timestamp": 1030732289.8740234, + "heart_rate": 65 + }, + { + "timestamp": 1030732290.1240234, + "heart_rate": 65 + }, + { + "timestamp": 1030732290.2988281, + "heart_rate": 65 + }, + { + "timestamp": 1030732290.5488281, + "heart_rate": 65 + }, + { + "timestamp": 1030732290.7988281, + "heart_rate": 65 + }, + { + "timestamp": 1030732291.0488281, + "heart_rate": 65 + }, + { + "timestamp": 1030732291.2988281, + "heart_rate": 65 + }, + { + "timestamp": 1030732291.4794922, + "heart_rate": 65 + }, + { + "timestamp": 1030732291.7294922, + "heart_rate": 65 + }, + { + "timestamp": 1030732291.9794922, + "heart_rate": 65 + }, + { + "timestamp": 1030732292.2294922, + "heart_rate": 65 + }, + { + "timestamp": 1030732292.4794922, + "heart_rate": 65 + }, + { + "timestamp": 1030732292.4960938, + "heart_rate": 65 + }, + { + "timestamp": 1030732292.7460938, + "heart_rate": 65 + }, + { + "timestamp": 1030732292.9960938, + "heart_rate": 65 + }, + { + "timestamp": 1030732293.0546875, + "heart_rate": 65 + }, + { + "timestamp": 1030732293.3046875, + "heart_rate": 65 + }, + { + "timestamp": 1030732293.5546875, + "heart_rate": 65 + }, + { + "timestamp": 1030732293.6044922, + "heart_rate": 65 + }, + { + "timestamp": 1030732293.8544922, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.1044922, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.2138672, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.4638672, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.4746094, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.7246094, + "heart_rate": 65 + }, + { + "timestamp": 1030732294.9746094, + "heart_rate": 65 + }, + { + "timestamp": 1030732295.2246094, + "heart_rate": 65 + }, + { + "timestamp": 1030732295.2900391, + "heart_rate": 65 + }, + { + "timestamp": 1030732295.5400391, + "heart_rate": 65 + }, + { + "timestamp": 1030732295.7900391, + "heart_rate": 65 + }, + { + "timestamp": 1030732295.9638672, + "heart_rate": 65 + }, + { + "timestamp": 1030732296.2138672, + "heart_rate": 65 + }, + { + "timestamp": 1030732296.2333984, + "heart_rate": 65 + }, + { + "timestamp": 1030732296.4833984, + "heart_rate": 65 + }, + { + "timestamp": 1030732296.7333984, + "heart_rate": 65 + }, + { + "timestamp": 1030732296.8105469, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.0605469, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.0703125, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.3203125, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.5703125, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.7246094, + "heart_rate": 65 + }, + { + "timestamp": 1030732297.9746094, + "heart_rate": 65 + }, + { + "timestamp": 1030732298.2246094, + "heart_rate": 65 + }, + { + "timestamp": 1030732298.2617188, + "heart_rate": 65 + }, + { + "timestamp": 1030732298.5117188, + "heart_rate": 65 + }, + { + "timestamp": 1030732298.7607422, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.0107422, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.0234375, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.2734375, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.4003906, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.6503906, + "heart_rate": 66 + }, + { + "timestamp": 1030732299.8408203, + "heart_rate": 66 + }, + { + "timestamp": 1030732300.0908203, + "heart_rate": 66 + }, + { + "timestamp": 1030732300.3408203, + "heart_rate": 66 + }, + { + "timestamp": 1030732300.4550781, + "heart_rate": 66 + }, + { + "timestamp": 1030732300.7050781, + "heart_rate": 66 + }, + { + "timestamp": 1030732300.9433594, + "heart_rate": 66 + }, + { + "timestamp": 1030732301.1933594, + "heart_rate": 66 + }, + { + "timestamp": 1030732301.4433594, + "heart_rate": 66 + }, + { + "timestamp": 1030732301.5976562, + "heart_rate": 65 + }, + { + "timestamp": 1030732301.8476562, + "heart_rate": 65 + }, + { + "timestamp": 1030732302.0976562, + "heart_rate": 65 + }, + { + "timestamp": 1030732302.2041016, + "heart_rate": 65 + }, + { + "timestamp": 1030732302.4541016, + "heart_rate": 65 + }, + { + "timestamp": 1030732302.7041016, + "heart_rate": 65 + }, + { + "timestamp": 1030732302.7480469, + "heart_rate": 66 + }, + { + "timestamp": 1030732302.9980469, + "heart_rate": 66 + }, + { + "timestamp": 1030732303.2480469, + "heart_rate": 66 + }, + { + "timestamp": 1030732303.2939453, + "heart_rate": 66 + }, + { + "timestamp": 1030732303.5439453, + "heart_rate": 66 + }, + { + "timestamp": 1030732303.7939453, + "heart_rate": 66 + }, + { + "timestamp": 1030732303.8583984, + "heart_rate": 66 + }, + { + "timestamp": 1030732304.1083984, + "heart_rate": 66 + }, + { + "timestamp": 1030732304.3583984, + "heart_rate": 66 + }, + { + "timestamp": 1030732304.5771484, + "heart_rate": 67 + }, + { + "timestamp": 1030732304.8271484, + "heart_rate": 67 + }, + { + "timestamp": 1030732305.0771484, + "heart_rate": 67 + }, + { + "timestamp": 1030732305.2158203, + "heart_rate": 68 + }, + { + "timestamp": 1030732305.4658203, + "heart_rate": 68 + }, + { + "timestamp": 1030732305.7158203, + "heart_rate": 68 + }, + { + "timestamp": 1030732305.8154297, + "heart_rate": 69 + }, + { + "timestamp": 1030732306.0654297, + "heart_rate": 69 + }, + { + "timestamp": 1030732306.2958984, + "heart_rate": 69 + }, + { + "timestamp": 1030732306.5458984, + "heart_rate": 69 + }, + { + "timestamp": 1030732306.7958984, + "heart_rate": 69 + }, + { + "timestamp": 1030732306.9736328, + "heart_rate": 69 + }, + { + "timestamp": 1030732307.2236328, + "heart_rate": 69 + }, + { + "timestamp": 1030732307.2998047, + "heart_rate": 69 + }, + { + "timestamp": 1030732307.5498047, + "heart_rate": 69 + }, + { + "timestamp": 1030732307.7998047, + "heart_rate": 69 + }, + { + "timestamp": 1030732307.9052734, + "heart_rate": 70 + }, + { + "timestamp": 1030732308.1552734, + "heart_rate": 70 + }, + { + "timestamp": 1030732308.4052734, + "heart_rate": 70 + }, + { + "timestamp": 1030732308.4902344, + "heart_rate": 70 + }, + { + "timestamp": 1030732308.7402344, + "heart_rate": 70 + }, + { + "timestamp": 1030732308.9902344, + "heart_rate": 70 + }, + { + "timestamp": 1030732309.0478516, + "heart_rate": 71 + }, + { + "timestamp": 1030732309.2978516, + "heart_rate": 71 + }, + { + "timestamp": 1030732309.5478516, + "heart_rate": 71 + }, + { + "timestamp": 1030732309.7978516, + "heart_rate": 71 + }, + { + "timestamp": 1030732309.8183594, + "heart_rate": 72 + }, + { + "timestamp": 1030732310.0683594, + "heart_rate": 72 + }, + { + "timestamp": 1030732310.2353516, + "heart_rate": 73 + }, + { + "timestamp": 1030732310.4853516, + "heart_rate": 73 + }, + { + "timestamp": 1030732310.7353516, + "heart_rate": 73 + }, + { + "timestamp": 1030732310.9482422, + "heart_rate": 74 + }, + { + "timestamp": 1030732311.1982422, + "heart_rate": 74 + }, + { + "timestamp": 1030732311.4482422, + "heart_rate": 74 + }, + { + "timestamp": 1030732311.6982422, + "heart_rate": 74 + }, + { + "timestamp": 1030732311.71875, + "heart_rate": 74 + }, + { + "timestamp": 1030732311.96875, + "heart_rate": 74 + }, + { + "timestamp": 1030732312.21875, + "heart_rate": 74 + }, + { + "timestamp": 1030732312.46875, + "heart_rate": 74 + }, + { + "timestamp": 1030732312.4726562, + "heart_rate": 74 + }, + { + "timestamp": 1030732312.7226562, + "heart_rate": 74 + }, + { + "timestamp": 1030732312.9726562, + "heart_rate": 74 + }, + { + "timestamp": 1030732313.2070312, + "heart_rate": 74 + }, + { + "timestamp": 1030732313.4570312, + "heart_rate": 74 + }, + { + "timestamp": 1030732313.7070312, + "heart_rate": 74 + }, + { + "timestamp": 1030732313.9541016, + "heart_rate": 74 + }, + { + "timestamp": 1030732314.2041016, + "heart_rate": 74 + }, + { + "timestamp": 1030732314.4541016, + "heart_rate": 74 + }, + { + "timestamp": 1030732314.7011719, + "heart_rate": 76 + }, + { + "timestamp": 1030732314.9511719, + "heart_rate": 76 + }, + { + "timestamp": 1030732315.2011719, + "heart_rate": 76 + }, + { + "timestamp": 1030732315.4511719, + "heart_rate": 76 + }, + { + "timestamp": 1030732315.4716797, + "heart_rate": 77 + }, + { + "timestamp": 1030732315.7216797, + "heart_rate": 77 + }, + { + "timestamp": 1030732315.9716797, + "heart_rate": 77 + }, + { + "timestamp": 1030732316.2216797, + "heart_rate": 77 + }, + { + "timestamp": 1030732316.2363281, + "heart_rate": 78 + }, + { + "timestamp": 1030732316.4863281, + "heart_rate": 78 + }, + { + "timestamp": 1030732316.7363281, + "heart_rate": 78 + }, + { + "timestamp": 1030732316.9863281, + "heart_rate": 78 + }, + { + "timestamp": 1030732317.0058594, + "heart_rate": 80 + }, + { + "timestamp": 1030732317.2558594, + "heart_rate": 80 + }, + { + "timestamp": 1030732317.5058594, + "heart_rate": 80 + }, + { + "timestamp": 1030732317.6005859, + "heart_rate": 80 + }, + { + "timestamp": 1030732317.8505859, + "heart_rate": 80 + }, + { + "timestamp": 1030732318.1005859, + "heart_rate": 80 + }, + { + "timestamp": 1030732318.3505859, + "heart_rate": 80 + }, + { + "timestamp": 1030732318.5107422, + "heart_rate": 80 + }, + { + "timestamp": 1030732318.7607422, + "heart_rate": 80 + }, + { + "timestamp": 1030732319.0107422, + "heart_rate": 80 + }, + { + "timestamp": 1030732319.2480469, + "heart_rate": 80 + }, + { + "timestamp": 1030732319.4980469, + "heart_rate": 80 + }, + { + "timestamp": 1030732319.7480469, + "heart_rate": 80 + }, + { + "timestamp": 1030732319.8769531, + "heart_rate": 81 + }, + { + "timestamp": 1030732320.1269531, + "heart_rate": 81 + }, + { + "timestamp": 1030732320.3769531, + "heart_rate": 81 + }, + { + "timestamp": 1030732320.6269531, + "heart_rate": 81 + }, + { + "timestamp": 1030732320.7783203, + "heart_rate": 81 + }, + { + "timestamp": 1030732321.0283203, + "heart_rate": 81 + }, + { + "timestamp": 1030732321.2783203, + "heart_rate": 81 + }, + { + "timestamp": 1030732321.5283203, + "heart_rate": 81 + }, + { + "timestamp": 1030732321.5439453, + "heart_rate": 82 + }, + { + "timestamp": 1030732321.7939453, + "heart_rate": 82 + }, + { + "timestamp": 1030732322.0439453, + "heart_rate": 82 + }, + { + "timestamp": 1030732322.2939453, + "heart_rate": 82 + }, + { + "timestamp": 1030732322.3378906, + "heart_rate": 82 + }, + { + "timestamp": 1030732322.5878906, + "heart_rate": 82 + }, + { + "timestamp": 1030732322.8378906, + "heart_rate": 82 + }, + { + "timestamp": 1030732323.0878906, + "heart_rate": 82 + }, + { + "timestamp": 1030732323.1103516, + "heart_rate": 83 + }, + { + "timestamp": 1030732323.3603516, + "heart_rate": 83 + }, + { + "timestamp": 1030732323.6103516, + "heart_rate": 83 + }, + { + "timestamp": 1030732323.8603516, + "heart_rate": 83 + }, + { + "timestamp": 1030732323.9316406, + "heart_rate": 84 + }, + { + "timestamp": 1030732324.1816406, + "heart_rate": 84 + }, + { + "timestamp": 1030732324.4316406, + "heart_rate": 84 + }, + { + "timestamp": 1030732324.6816406, + "heart_rate": 84 + }, + { + "timestamp": 1030732324.7304688, + "heart_rate": 86 + }, + { + "timestamp": 1030732324.9804688, + "heart_rate": 86 + }, + { + "timestamp": 1030732325.2304688, + "heart_rate": 86 + }, + { + "timestamp": 1030732325.4804688, + "heart_rate": 86 + }, + { + "timestamp": 1030732325.5263672, + "heart_rate": 85 + }, + { + "timestamp": 1030732325.7763672, + "heart_rate": 85 + }, + { + "timestamp": 1030732326.0263672, + "heart_rate": 85 + }, + { + "timestamp": 1030732326.2763672, + "heart_rate": 85 + }, + { + "timestamp": 1030732326.3125, + "heart_rate": 85 + }, + { + "timestamp": 1030732326.5625, + "heart_rate": 85 + }, + { + "timestamp": 1030732326.8125, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.0625, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.1289062, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.3789062, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.6289062, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.6640625, + "heart_rate": 85 + }, + { + "timestamp": 1030732327.9140625, + "heart_rate": 85 + }, + { + "timestamp": 1030732328.1640625, + "heart_rate": 85 + }, + { + "timestamp": 1030732328.3427734, + "heart_rate": 85 + }, + { + "timestamp": 1030732328.5927734, + "heart_rate": 85 + }, + { + "timestamp": 1030732328.7578125, + "heart_rate": 85 + }, + { + "timestamp": 1030732329.0078125, + "heart_rate": 85 + }, + { + "timestamp": 1030732329.2578125, + "heart_rate": 85 + }, + { + "timestamp": 1030732329.5078125, + "heart_rate": 85 + }, + { + "timestamp": 1030732329.578125, + "heart_rate": 85 + }, + { + "timestamp": 1030732329.828125, + "heart_rate": 85 + }, + { + "timestamp": 1030732330.078125, + "heart_rate": 85 + }, + { + "timestamp": 1030732330.328125, + "heart_rate": 85 + }, + { + "timestamp": 1030732330.4013672, + "heart_rate": 86 + }, + { + "timestamp": 1030732330.6513672, + "heart_rate": 86 + }, + { + "timestamp": 1030732330.9013672, + "heart_rate": 86 + }, + { + "timestamp": 1030732331.1513672, + "heart_rate": 86 + }, + { + "timestamp": 1030732331.1923828, + "heart_rate": 86 + }, + { + "timestamp": 1030732331.4423828, + "heart_rate": 86 + }, + { + "timestamp": 1030732331.6923828, + "heart_rate": 86 + }, + { + "timestamp": 1030732331.9423828, + "heart_rate": 86 + }, + { + "timestamp": 1030732332.0107422, + "heart_rate": 87 + }, + { + "timestamp": 1030732332.2607422, + "heart_rate": 87 + }, + { + "timestamp": 1030732332.5107422, + "heart_rate": 87 + }, + { + "timestamp": 1030732332.7607422, + "heart_rate": 87 + }, + { + "timestamp": 1030732332.8251953, + "heart_rate": 89 + }, + { + "timestamp": 1030732333.0751953, + "heart_rate": 89 + }, + { + "timestamp": 1030732333.3251953, + "heart_rate": 89 + }, + { + "timestamp": 1030732333.5751953, + "heart_rate": 89 + }, + { + "timestamp": 1030732333.6289062, + "heart_rate": 90 + }, + { + "timestamp": 1030732333.8789062, + "heart_rate": 90 + }, + { + "timestamp": 1030732334.1289062, + "heart_rate": 90 + }, + { + "timestamp": 1030732334.3789062, + "heart_rate": 90 + }, + { + "timestamp": 1030732334.40625, + "heart_rate": 89 + }, + { + "timestamp": 1030732334.65625, + "heart_rate": 89 + }, + { + "timestamp": 1030732334.90625, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.15625, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.1972656, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.4472656, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.6972656, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.9472656, + "heart_rate": 89 + }, + { + "timestamp": 1030732335.9824219, + "heart_rate": 89 + }, + { + "timestamp": 1030732336.2324219, + "heart_rate": 89 + }, + { + "timestamp": 1030732336.4824219, + "heart_rate": 89 + }, + { + "timestamp": 1030732336.7324219, + "heart_rate": 89 + }, + { + "timestamp": 1030732336.8359375, + "heart_rate": 88 + }, + { + "timestamp": 1030732337.0859375, + "heart_rate": 88 + }, + { + "timestamp": 1030732337.3359375, + "heart_rate": 88 + }, + { + "timestamp": 1030732337.5664062, + "heart_rate": 88 + }, + { + "timestamp": 1030732337.8164062, + "heart_rate": 88 + }, + { + "timestamp": 1030732338.0664062, + "heart_rate": 88 + }, + { + "timestamp": 1030732338.3164062, + "heart_rate": 88 + }, + { + "timestamp": 1030732338.3828125, + "heart_rate": 88 + }, + { + "timestamp": 1030732338.6328125, + "heart_rate": 88 + }, + { + "timestamp": 1030732338.8828125, + "heart_rate": 88 + }, + { + "timestamp": 1030732339.1328125, + "heart_rate": 88 + }, + { + "timestamp": 1030732339.1972656, + "heart_rate": 88 + }, + { + "timestamp": 1030732339.4472656, + "heart_rate": 88 + }, + { + "timestamp": 1030732339.6972656, + "heart_rate": 88 + }, + { + "timestamp": 1030732339.9472656, + "heart_rate": 88 + }, + { + "timestamp": 1030732340.0830078, + "heart_rate": 88 + }, + { + "timestamp": 1030732340.3330078, + "heart_rate": 88 + }, + { + "timestamp": 1030732340.5830078, + "heart_rate": 88 + }, + { + "timestamp": 1030732340.8330078, + "heart_rate": 88 + }, + { + "timestamp": 1030732340.9013672, + "heart_rate": 89 + }, + { + "timestamp": 1030732341.1513672, + "heart_rate": 89 + }, + { + "timestamp": 1030732341.4013672, + "heart_rate": 89 + }, + { + "timestamp": 1030732341.6513672, + "heart_rate": 89 + }, + { + "timestamp": 1030732341.7587891, + "heart_rate": 89 + }, + { + "timestamp": 1030732342.0087891, + "heart_rate": 89 + }, + { + "timestamp": 1030732342.2587891, + "heart_rate": 89 + }, + { + "timestamp": 1030732342.3339844, + "heart_rate": 89 + }, + { + "timestamp": 1030732342.5839844, + "heart_rate": 89 + }, + { + "timestamp": 1030732342.8339844, + "heart_rate": 89 + }, + { + "timestamp": 1030732343.0839844, + "heart_rate": 89 + }, + { + "timestamp": 1030732343.3300781, + "heart_rate": 89 + }, + { + "timestamp": 1030732343.5800781, + "heart_rate": 89 + }, + { + "timestamp": 1030732343.8300781, + "heart_rate": 89 + }, + { + "timestamp": 1030732344.0800781, + "heart_rate": 89 + }, + { + "timestamp": 1030732344.3300781, + "heart_rate": 89 + }, + { + "timestamp": 1030732344.4169922, + "heart_rate": 89 + }, + { + "timestamp": 1030732344.6669922, + "heart_rate": 89 + }, + { + "timestamp": 1030732344.9169922, + "heart_rate": 89 + }, + { + "timestamp": 1030732345.1669922, + "heart_rate": 89 + }, + { + "timestamp": 1030732345.4169922, + "heart_rate": 89 + }, + { + "timestamp": 1030732345.4941406, + "heart_rate": 89 + }, + { + "timestamp": 1030732345.7441406, + "heart_rate": 89 + }, + { + "timestamp": 1030732345.9941406, + "heart_rate": 89 + }, + { + "timestamp": 1030732346.0302734, + "heart_rate": 89 + }, + { + "timestamp": 1030732346.2802734, + "heart_rate": 89 + }, + { + "timestamp": 1030732346.5302734, + "heart_rate": 89 + }, + { + "timestamp": 1030732346.7802734, + "heart_rate": 89 + }, + { + "timestamp": 1030732346.8886719, + "heart_rate": 89 + }, + { + "timestamp": 1030732347.1386719, + "heart_rate": 89 + }, + { + "timestamp": 1030732347.3886719, + "heart_rate": 89 + }, + { + "timestamp": 1030732347.4521484, + "heart_rate": 89 + }, + { + "timestamp": 1030732347.7021484, + "heart_rate": 89 + }, + { + "timestamp": 1030732347.9521484, + "heart_rate": 89 + }, + { + "timestamp": 1030732348.0185547, + "heart_rate": 89 + }, + { + "timestamp": 1030732348.2685547, + "heart_rate": 89 + }, + { + "timestamp": 1030732348.5185547, + "heart_rate": 89 + }, + { + "timestamp": 1030732348.5419922, + "heart_rate": 88 + }, + { + "timestamp": 1030732348.7919922, + "heart_rate": 88 + }, + { + "timestamp": 1030732349.0419922, + "heart_rate": 88 + }, + { + "timestamp": 1030732349.1904297, + "heart_rate": 88 + }, + { + "timestamp": 1030732349.4404297, + "heart_rate": 88 + }, + { + "timestamp": 1030732349.6191406, + "heart_rate": 88 + }, + { + "timestamp": 1030732349.8691406, + "heart_rate": 88 + }, + { + "timestamp": 1030732350.1191406, + "heart_rate": 88 + }, + { + "timestamp": 1030732350.3691406, + "heart_rate": 88 + }, + { + "timestamp": 1030732350.4023438, + "heart_rate": 88 + }, + { + "timestamp": 1030732350.6523438, + "heart_rate": 88 + }, + { + "timestamp": 1030732350.8798828, + "heart_rate": 88 + }, + { + "timestamp": 1030732351.1298828, + "heart_rate": 88 + }, + { + "timestamp": 1030732351.3798828, + "heart_rate": 88 + }, + { + "timestamp": 1030732351.6298828, + "heart_rate": 88 + }, + { + "timestamp": 1030732351.65625, + "heart_rate": 88 + }, + { + "timestamp": 1030732351.90625, + "heart_rate": 88 + }, + { + "timestamp": 1030732352.15625, + "heart_rate": 88 + }, + { + "timestamp": 1030732352.40625, + "heart_rate": 88 + }, + { + "timestamp": 1030732352.4199219, + "heart_rate": 87 + }, + { + "timestamp": 1030732352.6699219, + "heart_rate": 87 + }, + { + "timestamp": 1030732352.9199219, + "heart_rate": 87 + }, + { + "timestamp": 1030732353.0634766, + "heart_rate": 87 + }, + { + "timestamp": 1030732353.3134766, + "heart_rate": 87 + }, + { + "timestamp": 1030732353.5634766, + "heart_rate": 87 + }, + { + "timestamp": 1030732353.8134766, + "heart_rate": 87 + }, + { + "timestamp": 1030732353.9853516, + "heart_rate": 87 + }, + { + "timestamp": 1030732354.2353516, + "heart_rate": 87 + }, + { + "timestamp": 1030732354.4853516, + "heart_rate": 87 + }, + { + "timestamp": 1030732354.7353516, + "heart_rate": 87 + }, + { + "timestamp": 1030732354.7832031, + "heart_rate": 87 + }, + { + "timestamp": 1030732355.0332031, + "heart_rate": 87 + }, + { + "timestamp": 1030732355.2832031, + "heart_rate": 87 + }, + { + "timestamp": 1030732355.5332031, + "heart_rate": 87 + }, + { + "timestamp": 1030732355.5957031, + "heart_rate": 87 + }, + { + "timestamp": 1030732355.8457031, + "heart_rate": 87 + }, + { + "timestamp": 1030732356.0957031, + "heart_rate": 87 + }, + { + "timestamp": 1030732356.3457031, + "heart_rate": 87 + }, + { + "timestamp": 1030732356.4287109, + "heart_rate": 87 + }, + { + "timestamp": 1030732356.6787109, + "heart_rate": 87 + }, + { + "timestamp": 1030732356.9287109, + "heart_rate": 87 + }, + { + "timestamp": 1030732357.1787109, + "heart_rate": 87 + }, + { + "timestamp": 1030732357.2617188, + "heart_rate": 87 + }, + { + "timestamp": 1030732357.5117188, + "heart_rate": 87 + }, + { + "timestamp": 1030732357.7617188, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.0117188, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.1005859, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.3505859, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.6005859, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.8505859, + "heart_rate": 87 + }, + { + "timestamp": 1030732358.9257812, + "heart_rate": 86 + }, + { + "timestamp": 1030732359.1757812, + "heart_rate": 86 + }, + { + "timestamp": 1030732359.4257812, + "heart_rate": 86 + }, + { + "timestamp": 1030732359.6757812, + "heart_rate": 86 + }, + { + "timestamp": 1030732359.7275391, + "heart_rate": 87 + }, + { + "timestamp": 1030732359.9775391, + "heart_rate": 87 + }, + { + "timestamp": 1030732360.2275391, + "heart_rate": 87 + }, + { + "timestamp": 1030732360.4775391, + "heart_rate": 87 + }, + { + "timestamp": 1030732360.4921875, + "heart_rate": 87 + }, + { + "timestamp": 1030732360.7421875, + "heart_rate": 87 + }, + { + "timestamp": 1030732360.9921875, + "heart_rate": 87 + }, + { + "timestamp": 1030732361.2421875, + "heart_rate": 87 + }, + { + "timestamp": 1030732361.2705078, + "heart_rate": 87 + }, + { + "timestamp": 1030732361.5205078, + "heart_rate": 87 + }, + { + "timestamp": 1030732361.7705078, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.0205078, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.0703125, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.3203125, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.5703125, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.8203125, + "heart_rate": 87 + }, + { + "timestamp": 1030732362.8583984, + "heart_rate": 86 + }, + { + "timestamp": 1030732363.1083984, + "heart_rate": 86 + }, + { + "timestamp": 1030732363.3583984, + "heart_rate": 86 + }, + { + "timestamp": 1030732363.6083984, + "heart_rate": 86 + }, + { + "timestamp": 1030732363.6826172, + "heart_rate": 86 + }, + { + "timestamp": 1030732363.9326172, + "heart_rate": 86 + }, + { + "timestamp": 1030732364.1826172, + "heart_rate": 86 + }, + { + "timestamp": 1030732364.4326172, + "heart_rate": 86 + }, + { + "timestamp": 1030732364.5068359, + "heart_rate": 85 + }, + { + "timestamp": 1030732364.7568359, + "heart_rate": 85 + }, + { + "timestamp": 1030732365.0068359, + "heart_rate": 85 + }, + { + "timestamp": 1030732365.2568359, + "heart_rate": 85 + }, + { + "timestamp": 1030732365.3251953, + "heart_rate": 85 + }, + { + "timestamp": 1030732365.5751953, + "heart_rate": 85 + }, + { + "timestamp": 1030732365.8251953, + "heart_rate": 85 + }, + { + "timestamp": 1030732366.0751953, + "heart_rate": 85 + }, + { + "timestamp": 1030732366.1464844, + "heart_rate": 86 + }, + { + "timestamp": 1030732366.3964844, + "heart_rate": 86 + }, + { + "timestamp": 1030732366.6464844, + "heart_rate": 86 + }, + { + "timestamp": 1030732366.8964844, + "heart_rate": 86 + }, + { + "timestamp": 1030732366.9980469, + "heart_rate": 86 + }, + { + "timestamp": 1030732367.2480469, + "heart_rate": 86 + }, + { + "timestamp": 1030732367.4980469, + "heart_rate": 86 + }, + { + "timestamp": 1030732367.7480469, + "heart_rate": 86 + }, + { + "timestamp": 1030732367.8808594, + "heart_rate": 85 + }, + { + "timestamp": 1030732368.1308594, + "heart_rate": 85 + }, + { + "timestamp": 1030732368.3808594, + "heart_rate": 85 + }, + { + "timestamp": 1030732368.6308594, + "heart_rate": 85 + }, + { + "timestamp": 1030732368.7480469, + "heart_rate": 85 + }, + { + "timestamp": 1030732368.9980469, + "heart_rate": 85 + }, + { + "timestamp": 1030732369.2480469, + "heart_rate": 85 + }, + { + "timestamp": 1030732369.4980469, + "heart_rate": 85 + }, + { + "timestamp": 1030732369.6269531, + "heart_rate": 85 + }, + { + "timestamp": 1030732369.8769531, + "heart_rate": 85 + }, + { + "timestamp": 1030732370.1269531, + "heart_rate": 85 + }, + { + "timestamp": 1030732370.3769531, + "heart_rate": 85 + }, + { + "timestamp": 1030732370.5097656, + "heart_rate": 85 + }, + { + "timestamp": 1030732370.7597656, + "heart_rate": 85 + }, + { + "timestamp": 1030732371.0097656, + "heart_rate": 85 + }, + { + "timestamp": 1030732371.2597656, + "heart_rate": 85 + }, + { + "timestamp": 1030732371.4003906, + "heart_rate": 85 + }, + { + "timestamp": 1030732371.6503906, + "heart_rate": 85 + }, + { + "timestamp": 1030732371.9003906, + "heart_rate": 85 + }, + { + "timestamp": 1030732372.1503906, + "heart_rate": 85 + }, + { + "timestamp": 1030732372.2519531, + "heart_rate": 84 + }, + { + "timestamp": 1030732372.5019531, + "heart_rate": 84 + }, + { + "timestamp": 1030732372.7519531, + "heart_rate": 84 + }, + { + "timestamp": 1030732373.0019531, + "heart_rate": 84 + }, + { + "timestamp": 1030732373.125, + "heart_rate": 85 + }, + { + "timestamp": 1030732373.375, + "heart_rate": 85 + }, + { + "timestamp": 1030732373.625, + "heart_rate": 85 + }, + { + "timestamp": 1030732373.875, + "heart_rate": 85 + }, + { + "timestamp": 1030732373.984375, + "heart_rate": 85 + }, + { + "timestamp": 1030732374.234375, + "heart_rate": 85 + }, + { + "timestamp": 1030732374.484375, + "heart_rate": 85 + }, + { + "timestamp": 1030732374.734375, + "heart_rate": 85 + }, + { + "timestamp": 1030732374.8632812, + "heart_rate": 84 + }, + { + "timestamp": 1030732375.1132812, + "heart_rate": 84 + }, + { + "timestamp": 1030732375.3632812, + "heart_rate": 84 + }, + { + "timestamp": 1030732375.6132812, + "heart_rate": 84 + }, + { + "timestamp": 1030732375.6982422, + "heart_rate": 85 + }, + { + "timestamp": 1030732375.9482422, + "heart_rate": 85 + }, + { + "timestamp": 1030732376.1982422, + "heart_rate": 85 + }, + { + "timestamp": 1030732376.4482422, + "heart_rate": 85 + }, + { + "timestamp": 1030732376.5761719, + "heart_rate": 84 + }, + { + "timestamp": 1030732376.8261719, + "heart_rate": 84 + }, + { + "timestamp": 1030732377.0761719, + "heart_rate": 84 + }, + { + "timestamp": 1030732377.3261719, + "heart_rate": 84 + }, + { + "timestamp": 1030732377.4404297, + "heart_rate": 84 + }, + { + "timestamp": 1030732377.6904297, + "heart_rate": 84 + }, + { + "timestamp": 1030732377.9404297, + "heart_rate": 84 + }, + { + "timestamp": 1030732378.1904297, + "heart_rate": 84 + }, + { + "timestamp": 1030732378.3369141, + "heart_rate": 84 + }, + { + "timestamp": 1030732378.5869141, + "heart_rate": 84 + }, + { + "timestamp": 1030732378.8369141, + "heart_rate": 84 + }, + { + "timestamp": 1030732379.0869141, + "heart_rate": 84 + }, + { + "timestamp": 1030732379.2246094, + "heart_rate": 83 + }, + { + "timestamp": 1030732379.4746094, + "heart_rate": 83 + }, + { + "timestamp": 1030732379.7246094, + "heart_rate": 83 + }, + { + "timestamp": 1030732379.9746094, + "heart_rate": 83 + }, + { + "timestamp": 1030732380.2246094, + "heart_rate": 83 + }, + { + "timestamp": 1030732380.2919922, + "heart_rate": 83 + }, + { + "timestamp": 1030732380.5419922, + "heart_rate": 83 + }, + { + "timestamp": 1030732380.7919922, + "heart_rate": 83 + }, + { + "timestamp": 1030732380.9726562, + "heart_rate": 83 + }, + { + "timestamp": 1030732381.2226562, + "heart_rate": 83 + }, + { + "timestamp": 1030732381.4726562, + "heart_rate": 83 + }, + { + "timestamp": 1030732381.7226562, + "heart_rate": 83 + }, + { + "timestamp": 1030732381.8681641, + "heart_rate": 83 + }, + { + "timestamp": 1030732382.1181641, + "heart_rate": 83 + }, + { + "timestamp": 1030732382.3681641, + "heart_rate": 83 + }, + { + "timestamp": 1030732382.6181641, + "heart_rate": 83 + }, + { + "timestamp": 1030732382.7695312, + "heart_rate": 83 + }, + { + "timestamp": 1030732383.0195312, + "heart_rate": 83 + }, + { + "timestamp": 1030732383.2695312, + "heart_rate": 83 + }, + { + "timestamp": 1030732383.5195312, + "heart_rate": 83 + }, + { + "timestamp": 1030732383.7148438, + "heart_rate": 84 + }, + { + "timestamp": 1030732383.9648438, + "heart_rate": 84 + }, + { + "timestamp": 1030732384.2148438, + "heart_rate": 84 + }, + { + "timestamp": 1030732384.4648438, + "heart_rate": 84 + }, + { + "timestamp": 1030732384.6669922, + "heart_rate": 85 + }, + { + "timestamp": 1030732384.9169922, + "heart_rate": 85 + }, + { + "timestamp": 1030732385.1669922, + "heart_rate": 85 + }, + { + "timestamp": 1030732385.4169922, + "heart_rate": 85 + }, + { + "timestamp": 1030732385.6142578, + "heart_rate": 86 + }, + { + "timestamp": 1030732385.8642578, + "heart_rate": 86 + }, + { + "timestamp": 1030732386.1142578, + "heart_rate": 86 + }, + { + "timestamp": 1030732386.3642578, + "heart_rate": 86 + }, + { + "timestamp": 1030732386.5546875, + "heart_rate": 86 + }, + { + "timestamp": 1030732386.8046875, + "heart_rate": 86 + }, + { + "timestamp": 1030732387.0546875, + "heart_rate": 86 + }, + { + "timestamp": 1030732387.3046875, + "heart_rate": 86 + }, + { + "timestamp": 1030732387.4746094, + "heart_rate": 86 + }, + { + "timestamp": 1030732387.7246094, + "heart_rate": 86 + }, + { + "timestamp": 1030732387.9746094, + "heart_rate": 86 + }, + { + "timestamp": 1030732388.2246094, + "heart_rate": 86 + }, + { + "timestamp": 1030732388.390625, + "heart_rate": 84 + }, + { + "timestamp": 1030732388.640625, + "heart_rate": 84 + }, + { + "timestamp": 1030732388.890625, + "heart_rate": 84 + }, + { + "timestamp": 1030732389.140625, + "heart_rate": 84 + }, + { + "timestamp": 1030732389.2919922, + "heart_rate": 83 + }, + { + "timestamp": 1030732389.5419922, + "heart_rate": 83 + }, + { + "timestamp": 1030732389.7919922, + "heart_rate": 83 + }, + { + "timestamp": 1030732390.0419922, + "heart_rate": 83 + }, + { + "timestamp": 1030732390.1972656, + "heart_rate": 81 + }, + { + "timestamp": 1030732390.4472656, + "heart_rate": 81 + }, + { + "timestamp": 1030732390.6972656, + "heart_rate": 81 + }, + { + "timestamp": 1030732390.9472656, + "heart_rate": 81 + }, + { + "timestamp": 1030732391.0693359, + "heart_rate": 79 + }, + { + "timestamp": 1030732391.3193359, + "heart_rate": 79 + }, + { + "timestamp": 1030732391.5693359, + "heart_rate": 79 + }, + { + "timestamp": 1030732391.8193359, + "heart_rate": 79 + }, + { + "timestamp": 1030732391.9384766, + "heart_rate": 75 + }, + { + "timestamp": 1030732392.1884766, + "heart_rate": 75 + }, + { + "timestamp": 1030732392.4384766, + "heart_rate": 75 + }, + { + "timestamp": 1030732392.6884766, + "heart_rate": 75 + }, + { + "timestamp": 1030732392.8349609, + "heart_rate": 73 + }, + { + "timestamp": 1030732393.0849609, + "heart_rate": 73 + }, + { + "timestamp": 1030732393.3349609, + "heart_rate": 73 + }, + { + "timestamp": 1030732393.5849609, + "heart_rate": 73 + }, + { + "timestamp": 1030732393.7519531, + "heart_rate": 71 + }, + { + "timestamp": 1030732394.0019531, + "heart_rate": 71 + }, + { + "timestamp": 1030732394.2519531, + "heart_rate": 71 + }, + { + "timestamp": 1030732394.5019531, + "heart_rate": 71 + }, + { + "timestamp": 1030732394.7167969, + "heart_rate": 69 + }, + { + "timestamp": 1030732394.9667969, + "heart_rate": 69 + }, + { + "timestamp": 1030732395.2167969, + "heart_rate": 69 + }, + { + "timestamp": 1030732395.4667969, + "heart_rate": 69 + }, + { + "timestamp": 1030732395.640625, + "heart_rate": 68 + }, + { + "timestamp": 1030732395.890625, + "heart_rate": 68 + }, + { + "timestamp": 1030732396.140625, + "heart_rate": 68 + }, + { + "timestamp": 1030732396.390625, + "heart_rate": 68 + }, + { + "timestamp": 1030732396.5761719, + "heart_rate": 66 + }, + { + "timestamp": 1030732396.8261719, + "heart_rate": 66 + }, + { + "timestamp": 1030732397.0761719, + "heart_rate": 66 + }, + { + "timestamp": 1030732397.3261719, + "heart_rate": 66 + }, + { + "timestamp": 1030732397.5039062, + "heart_rate": 66 + }, + { + "timestamp": 1030732397.7539062, + "heart_rate": 66 + }, + { + "timestamp": 1030732398.0039062, + "heart_rate": 66 + }, + { + "timestamp": 1030732398.2539062, + "heart_rate": 66 + }, + { + "timestamp": 1030732398.4003906, + "heart_rate": 66 + }, + { + "timestamp": 1030732398.6503906, + "heart_rate": 66 + }, + { + "timestamp": 1030732398.9003906, + "heart_rate": 66 + }, + { + "timestamp": 1030732399.1503906, + "heart_rate": 66 + }, + { + "timestamp": 1030732399.2666016, + "heart_rate": 67 + }, + { + "timestamp": 1030732399.5166016, + "heart_rate": 67 + }, + { + "timestamp": 1030732399.7666016, + "heart_rate": 67 + }, + { + "timestamp": 1030732400.0166016, + "heart_rate": 67 + }, + { + "timestamp": 1030732400.1679688, + "heart_rate": 68 + }, + { + "timestamp": 1030732400.4179688, + "heart_rate": 68 + }, + { + "timestamp": 1030732400.6679688, + "heart_rate": 68 + }, + { + "timestamp": 1030732400.9179688, + "heart_rate": 68 + }, + { + "timestamp": 1030732401.0771484, + "heart_rate": 68 + }, + { + "timestamp": 1030732401.3271484, + "heart_rate": 68 + }, + { + "timestamp": 1030732401.5771484, + "heart_rate": 68 + }, + { + "timestamp": 1030732401.8271484, + "heart_rate": 68 + }, + { + "timestamp": 1030732401.9423828, + "heart_rate": 68 + }, + { + "timestamp": 1030732402.1923828, + "heart_rate": 68 + }, + { + "timestamp": 1030732402.4423828, + "heart_rate": 68 + }, + { + "timestamp": 1030732402.6923828, + "heart_rate": 68 + }, + { + "timestamp": 1030732402.8251953, + "heart_rate": 69 + }, + { + "timestamp": 1030732403.0751953, + "heart_rate": 69 + }, + { + "timestamp": 1030732403.3251953, + "heart_rate": 69 + }, + { + "timestamp": 1030732403.5751953, + "heart_rate": 69 + }, + { + "timestamp": 1030732403.7099609, + "heart_rate": 70 + }, + { + "timestamp": 1030732403.9599609, + "heart_rate": 70 + }, + { + "timestamp": 1030732404.2099609, + "heart_rate": 70 + }, + { + "timestamp": 1030732404.4599609, + "heart_rate": 70 + }, + { + "timestamp": 1030732404.6357422, + "heart_rate": 70 + }, + { + "timestamp": 1030732404.8857422, + "heart_rate": 70 + }, + { + "timestamp": 1030732405.1357422, + "heart_rate": 70 + }, + { + "timestamp": 1030732405.3857422, + "heart_rate": 70 + }, + { + "timestamp": 1030732405.5449219, + "heart_rate": 68 + }, + { + "timestamp": 1030732405.7949219, + "heart_rate": 68 + }, + { + "timestamp": 1030732406.0449219, + "heart_rate": 68 + }, + { + "timestamp": 1030732406.2949219, + "heart_rate": 68 + }, + { + "timestamp": 1030732406.4628906, + "heart_rate": 67 + }, + { + "timestamp": 1030732406.7128906, + "heart_rate": 67 + }, + { + "timestamp": 1030732406.9628906, + "heart_rate": 67 + }, + { + "timestamp": 1030732407.2128906, + "heart_rate": 67 + }, + { + "timestamp": 1030732407.3574219, + "heart_rate": 67 + }, + { + "timestamp": 1030732407.6074219, + "heart_rate": 67 + }, + { + "timestamp": 1030732407.8574219, + "heart_rate": 67 + }, + { + "timestamp": 1030732408.1074219, + "heart_rate": 67 + }, + { + "timestamp": 1030732408.2832031, + "heart_rate": 67 + }, + { + "timestamp": 1030732408.5332031, + "heart_rate": 67 + }, + { + "timestamp": 1030732408.7832031, + "heart_rate": 67 + }, + { + "timestamp": 1030732409.0332031, + "heart_rate": 67 + }, + { + "timestamp": 1030732409.1621094, + "heart_rate": 67 + }, + { + "timestamp": 1030732409.4121094, + "heart_rate": 67 + }, + { + "timestamp": 1030732409.6621094, + "heart_rate": 67 + }, + { + "timestamp": 1030732409.9121094, + "heart_rate": 67 + }, + { + "timestamp": 1030732410.1621094, + "heart_rate": 67 + }, + { + "timestamp": 1030732410.2910156, + "heart_rate": 67 + }, + { + "timestamp": 1030732410.5410156, + "heart_rate": 67 + }, + { + "timestamp": 1030732410.7910156, + "heart_rate": 67 + }, + { + "timestamp": 1030732410.9257812, + "heart_rate": 68 + }, + { + "timestamp": 1030732411.1757812, + "heart_rate": 68 + }, + { + "timestamp": 1030732411.4257812, + "heart_rate": 68 + }, + { + "timestamp": 1030732411.6757812, + "heart_rate": 68 + }, + { + "timestamp": 1030732411.8173828, + "heart_rate": 68 + }, + { + "timestamp": 1030732412.0673828, + "heart_rate": 68 + }, + { + "timestamp": 1030732412.3173828, + "heart_rate": 68 + }, + { + "timestamp": 1030732412.5673828, + "heart_rate": 68 + }, + { + "timestamp": 1030732412.6992188, + "heart_rate": 68 + }, + { + "timestamp": 1030732412.9492188, + "heart_rate": 68 + }, + { + "timestamp": 1030732413.1992188, + "heart_rate": 68 + }, + { + "timestamp": 1030732413.4492188, + "heart_rate": 68 + }, + { + "timestamp": 1030732413.5917969, + "heart_rate": 69 + }, + { + "timestamp": 1030732413.8417969, + "heart_rate": 69 + }, + { + "timestamp": 1030732414.0917969, + "heart_rate": 69 + }, + { + "timestamp": 1030732414.3417969, + "heart_rate": 69 + }, + { + "timestamp": 1030732414.484375, + "heart_rate": 69 + }, + { + "timestamp": 1030732414.734375, + "heart_rate": 69 + }, + { + "timestamp": 1030732414.984375, + "heart_rate": 69 + }, + { + "timestamp": 1030732415.234375, + "heart_rate": 69 + }, + { + "timestamp": 1030732415.3818359, + "heart_rate": 69 + }, + { + "timestamp": 1030732415.6318359, + "heart_rate": 69 + }, + { + "timestamp": 1030732415.8818359, + "heart_rate": 69 + }, + { + "timestamp": 1030732416.1318359, + "heart_rate": 69 + }, + { + "timestamp": 1030732416.3056641, + "heart_rate": 69 + }, + { + "timestamp": 1030732416.5556641, + "heart_rate": 69 + }, + { + "timestamp": 1030732416.8056641, + "heart_rate": 69 + }, + { + "timestamp": 1030732417.0556641, + "heart_rate": 69 + }, + { + "timestamp": 1030732417.1572266, + "heart_rate": 68 + }, + { + "timestamp": 1030732417.4072266, + "heart_rate": 68 + }, + { + "timestamp": 1030732417.6572266, + "heart_rate": 68 + }, + { + "timestamp": 1030732417.9072266, + "heart_rate": 68 + }, + { + "timestamp": 1030732418.0439453, + "heart_rate": 68 + }, + { + "timestamp": 1030732418.2939453, + "heart_rate": 68 + }, + { + "timestamp": 1030732418.5439453, + "heart_rate": 68 + }, + { + "timestamp": 1030732418.7939453, + "heart_rate": 68 + }, + { + "timestamp": 1030732418.9130859, + "heart_rate": 69 + }, + { + "timestamp": 1030732419.1630859, + "heart_rate": 69 + }, + { + "timestamp": 1030732419.4130859, + "heart_rate": 69 + }, + { + "timestamp": 1030732419.6630859, + "heart_rate": 69 + }, + { + "timestamp": 1030732419.7597656, + "heart_rate": 70 + }, + { + "timestamp": 1030732420.0097656, + "heart_rate": 70 + }, + { + "timestamp": 1030732420.2597656, + "heart_rate": 70 + }, + { + "timestamp": 1030732420.5097656, + "heart_rate": 70 + }, + { + "timestamp": 1030732420.6191406, + "heart_rate": 71 + }, + { + "timestamp": 1030732420.8691406, + "heart_rate": 71 + }, + { + "timestamp": 1030732421.1191406, + "heart_rate": 71 + }, + { + "timestamp": 1030732421.3691406, + "heart_rate": 71 + }, + { + "timestamp": 1030732421.4960938, + "heart_rate": 71 + }, + { + "timestamp": 1030732421.7460938, + "heart_rate": 71 + }, + { + "timestamp": 1030732421.9960938, + "heart_rate": 71 + }, + { + "timestamp": 1030732422.2460938, + "heart_rate": 71 + }, + { + "timestamp": 1030732422.3037109, + "heart_rate": 70 + }, + { + "timestamp": 1030732422.5537109, + "heart_rate": 70 + }, + { + "timestamp": 1030732422.8037109, + "heart_rate": 70 + }, + { + "timestamp": 1030732423.0537109, + "heart_rate": 70 + }, + { + "timestamp": 1030732423.15625, + "heart_rate": 71 + }, + { + "timestamp": 1030732423.40625, + "heart_rate": 71 + }, + { + "timestamp": 1030732423.65625, + "heart_rate": 71 + }, + { + "timestamp": 1030732423.90625, + "heart_rate": 71 + }, + { + "timestamp": 1030732423.9951172, + "heart_rate": 71 + }, + { + "timestamp": 1030732424.2451172, + "heart_rate": 71 + }, + { + "timestamp": 1030732424.4951172, + "heart_rate": 71 + }, + { + "timestamp": 1030732424.7451172, + "heart_rate": 71 + }, + { + "timestamp": 1030732424.8408203, + "heart_rate": 71 + }, + { + "timestamp": 1030732425.0908203, + "heart_rate": 71 + }, + { + "timestamp": 1030732425.3408203, + "heart_rate": 71 + }, + { + "timestamp": 1030732425.5908203, + "heart_rate": 71 + }, + { + "timestamp": 1030732425.6572266, + "heart_rate": 72 + }, + { + "timestamp": 1030732425.9072266, + "heart_rate": 72 + }, + { + "timestamp": 1030732426.1572266, + "heart_rate": 72 + }, + { + "timestamp": 1030732426.4072266, + "heart_rate": 72 + }, + { + "timestamp": 1030732426.5234375, + "heart_rate": 72 + }, + { + "timestamp": 1030732426.7734375, + "heart_rate": 72 + }, + { + "timestamp": 1030732427.0234375, + "heart_rate": 72 + }, + { + "timestamp": 1030732427.2734375, + "heart_rate": 72 + }, + { + "timestamp": 1030732427.4296875, + "heart_rate": 71 + }, + { + "timestamp": 1030732427.6796875, + "heart_rate": 71 + }, + { + "timestamp": 1030732427.9296875, + "heart_rate": 71 + }, + { + "timestamp": 1030732428.1796875, + "heart_rate": 71 + }, + { + "timestamp": 1030732428.3457031, + "heart_rate": 69 + }, + { + "timestamp": 1030732428.5957031, + "heart_rate": 69 + }, + { + "timestamp": 1030732428.8457031, + "heart_rate": 69 + }, + { + "timestamp": 1030732429.0957031, + "heart_rate": 69 + }, + { + "timestamp": 1030732429.2460938, + "heart_rate": 68 + }, + { + "timestamp": 1030732429.4960938, + "heart_rate": 68 + }, + { + "timestamp": 1030732429.7460938, + "heart_rate": 68 + }, + { + "timestamp": 1030732429.9960938, + "heart_rate": 68 + }, + { + "timestamp": 1030732430.1162109, + "heart_rate": 67 + }, + { + "timestamp": 1030732430.3662109, + "heart_rate": 67 + }, + { + "timestamp": 1030732430.6162109, + "heart_rate": 67 + }, + { + "timestamp": 1030732430.8662109, + "heart_rate": 67 + }, + { + "timestamp": 1030732430.9873047, + "heart_rate": 68 + }, + { + "timestamp": 1030732431.2373047, + "heart_rate": 68 + }, + { + "timestamp": 1030732431.4873047, + "heart_rate": 68 + }, + { + "timestamp": 1030732431.7373047, + "heart_rate": 68 + }, + { + "timestamp": 1030732431.8427734, + "heart_rate": 68 + }, + { + "timestamp": 1030732432.0927734, + "heart_rate": 68 + }, + { + "timestamp": 1030732432.3427734, + "heart_rate": 68 + }, + { + "timestamp": 1030732432.5927734, + "heart_rate": 68 + }, + { + "timestamp": 1030732432.6933594, + "heart_rate": 69 + }, + { + "timestamp": 1030732432.9433594, + "heart_rate": 69 + }, + { + "timestamp": 1030732433.1933594, + "heart_rate": 69 + }, + { + "timestamp": 1030732433.4433594, + "heart_rate": 69 + }, + { + "timestamp": 1030732433.5371094, + "heart_rate": 70 + }, + { + "timestamp": 1030732433.7871094, + "heart_rate": 70 + }, + { + "timestamp": 1030732434.0371094, + "heart_rate": 70 + }, + { + "timestamp": 1030732434.2871094, + "heart_rate": 70 + }, + { + "timestamp": 1030732434.3925781, + "heart_rate": 70 + }, + { + "timestamp": 1030732434.6425781, + "heart_rate": 70 + }, + { + "timestamp": 1030732434.8925781, + "heart_rate": 70 + }, + { + "timestamp": 1030732435.1425781, + "heart_rate": 70 + }, + { + "timestamp": 1030732435.2099609, + "heart_rate": 71 + }, + { + "timestamp": 1030732435.4599609, + "heart_rate": 71 + }, + { + "timestamp": 1030732435.7099609, + "heart_rate": 71 + }, + { + "timestamp": 1030732435.9599609, + "heart_rate": 71 + }, + { + "timestamp": 1030732436.0498047, + "heart_rate": 71 + }, + { + "timestamp": 1030732436.2998047, + "heart_rate": 71 + }, + { + "timestamp": 1030732436.5498047, + "heart_rate": 71 + }, + { + "timestamp": 1030732436.7998047, + "heart_rate": 71 + }, + { + "timestamp": 1030732436.8857422, + "heart_rate": 71 + }, + { + "timestamp": 1030732437.1357422, + "heart_rate": 71 + }, + { + "timestamp": 1030732437.3857422, + "heart_rate": 71 + }, + { + "timestamp": 1030732437.6357422, + "heart_rate": 71 + }, + { + "timestamp": 1030732437.6962891, + "heart_rate": 72 + }, + { + "timestamp": 1030732437.9462891, + "heart_rate": 72 + }, + { + "timestamp": 1030732438.1962891, + "heart_rate": 72 + }, + { + "timestamp": 1030732438.4462891, + "heart_rate": 72 + }, + { + "timestamp": 1030732438.5595703, + "heart_rate": 72 + }, + { + "timestamp": 1030732438.8095703, + "heart_rate": 72 + }, + { + "timestamp": 1030732439.0595703, + "heart_rate": 72 + }, + { + "timestamp": 1030732439.3095703, + "heart_rate": 72 + }, + { + "timestamp": 1030732439.4101562, + "heart_rate": 71 + }, + { + "timestamp": 1030732439.6601562, + "heart_rate": 71 + }, + { + "timestamp": 1030732439.9101562, + "heart_rate": 71 + }, + { + "timestamp": 1030732440.1396484, + "heart_rate": 71 + }, + { + "timestamp": 1030732440.3896484, + "heart_rate": 71 + }, + { + "timestamp": 1030732440.6396484, + "heart_rate": 71 + }, + { + "timestamp": 1030732440.8896484, + "heart_rate": 71 + }, + { + "timestamp": 1030732441.0566406, + "heart_rate": 71 + }, + { + "timestamp": 1030732441.3066406, + "heart_rate": 71 + }, + { + "timestamp": 1030732441.5566406, + "heart_rate": 71 + }, + { + "timestamp": 1030732441.8066406, + "heart_rate": 71 + }, + { + "timestamp": 1030732442.0566406, + "heart_rate": 71 + }, + { + "timestamp": 1030732442.2304688, + "heart_rate": 71 + }, + { + "timestamp": 1030732442.4804688, + "heart_rate": 71 + }, + { + "timestamp": 1030732442.7304688, + "heart_rate": 71 + }, + { + "timestamp": 1030732442.9804688, + "heart_rate": 71 + }, + { + "timestamp": 1030732443.0625, + "heart_rate": 72 + }, + { + "timestamp": 1030732443.3125, + "heart_rate": 72 + }, + { + "timestamp": 1030732443.5625, + "heart_rate": 72 + }, + { + "timestamp": 1030732443.6835938, + "heart_rate": 72 + }, + { + "timestamp": 1030732443.9335938, + "heart_rate": 72 + }, + { + "timestamp": 1030732444.1835938, + "heart_rate": 72 + }, + { + "timestamp": 1030732444.3212891, + "heart_rate": 72 + }, + { + "timestamp": 1030732444.5712891, + "heart_rate": 72 + }, + { + "timestamp": 1030732444.8212891, + "heart_rate": 72 + }, + { + "timestamp": 1030732445.0712891, + "heart_rate": 72 + }, + { + "timestamp": 1030732445.1484375, + "heart_rate": 73 + }, + { + "timestamp": 1030732445.3984375, + "heart_rate": 73 + }, + { + "timestamp": 1030732445.6484375, + "heart_rate": 73 + }, + { + "timestamp": 1030732445.8984375, + "heart_rate": 73 + }, + { + "timestamp": 1030732446.0078125, + "heart_rate": 74 + }, + { + "timestamp": 1030732446.2578125, + "heart_rate": 74 + }, + { + "timestamp": 1030732446.5078125, + "heart_rate": 74 + }, + { + "timestamp": 1030732446.7578125, + "heart_rate": 74 + }, + { + "timestamp": 1030732446.8818359, + "heart_rate": 75 + }, + { + "timestamp": 1030732447.1318359, + "heart_rate": 75 + }, + { + "timestamp": 1030732447.3818359, + "heart_rate": 75 + }, + { + "timestamp": 1030732447.6318359, + "heart_rate": 75 + }, + { + "timestamp": 1030732447.7666016, + "heart_rate": 74 + }, + { + "timestamp": 1030732448.0166016, + "heart_rate": 74 + }, + { + "timestamp": 1030732448.2666016, + "heart_rate": 74 + }, + { + "timestamp": 1030732448.5166016, + "heart_rate": 74 + }, + { + "timestamp": 1030732448.6484375, + "heart_rate": 70 + }, + { + "timestamp": 1030732448.8984375, + "heart_rate": 70 + }, + { + "timestamp": 1030732449.1484375, + "heart_rate": 70 + }, + { + "timestamp": 1030732449.3984375, + "heart_rate": 70 + }, + { + "timestamp": 1030732449.5732422, + "heart_rate": 69 + }, + { + "timestamp": 1030732449.8232422, + "heart_rate": 69 + }, + { + "timestamp": 1030732450.0732422, + "heart_rate": 69 + }, + { + "timestamp": 1030732450.3232422, + "heart_rate": 69 + }, + { + "timestamp": 1030732450.4824219, + "heart_rate": 68 + }, + { + "timestamp": 1030732450.7324219, + "heart_rate": 68 + }, + { + "timestamp": 1030732450.9824219, + "heart_rate": 68 + }, + { + "timestamp": 1030732451.2324219, + "heart_rate": 68 + }, + { + "timestamp": 1030732451.4238281, + "heart_rate": 66 + }, + { + "timestamp": 1030732451.6738281, + "heart_rate": 66 + }, + { + "timestamp": 1030732451.9238281, + "heart_rate": 66 + }, + { + "timestamp": 1030732452.1738281, + "heart_rate": 66 + }, + { + "timestamp": 1030732452.3730469, + "heart_rate": 65 + }, + { + "timestamp": 1030732452.6230469, + "heart_rate": 65 + }, + { + "timestamp": 1030732452.8730469, + "heart_rate": 65 + }, + { + "timestamp": 1030732453.1230469, + "heart_rate": 65 + }, + { + "timestamp": 1030732453.3349609, + "heart_rate": 64 + }, + { + "timestamp": 1030732453.5849609, + "heart_rate": 64 + }, + { + "timestamp": 1030732453.8349609, + "heart_rate": 64 + }, + { + "timestamp": 1030732454.0849609, + "heart_rate": 64 + }, + { + "timestamp": 1030732454.25, + "heart_rate": 64 + }, + { + "timestamp": 1030732454.5, + "heart_rate": 64 + }, + { + "timestamp": 1030732454.75, + "heart_rate": 64 + }, + { + "timestamp": 1030732455, + "heart_rate": 64 + }, + { + "timestamp": 1030732455.1914062, + "heart_rate": 64 + }, + { + "timestamp": 1030732455.4414062, + "heart_rate": 64 + }, + { + "timestamp": 1030732455.6914062, + "heart_rate": 64 + }, + { + "timestamp": 1030732455.9414062, + "heart_rate": 64 + }, + { + "timestamp": 1030732456.1259766, + "heart_rate": 64 + }, + { + "timestamp": 1030732456.3759766, + "heart_rate": 64 + }, + { + "timestamp": 1030732456.6259766, + "heart_rate": 64 + }, + { + "timestamp": 1030732456.8759766, + "heart_rate": 64 + }, + { + "timestamp": 1030732457.0615234, + "heart_rate": 64 + }, + { + "timestamp": 1030732457.3115234, + "heart_rate": 64 + }, + { + "timestamp": 1030732457.5615234, + "heart_rate": 64 + }, + { + "timestamp": 1030732457.8115234, + "heart_rate": 64 + }, + { + "timestamp": 1030732458.0126953, + "heart_rate": 64 + }, + { + "timestamp": 1030732458.2626953, + "heart_rate": 64 + }, + { + "timestamp": 1030732458.5126953, + "heart_rate": 64 + }, + { + "timestamp": 1030732458.7626953, + "heart_rate": 64 + }, + { + "timestamp": 1030732458.9677734, + "heart_rate": 64 + }, + { + "timestamp": 1030732459.2177734, + "heart_rate": 64 + }, + { + "timestamp": 1030732459.4677734, + "heart_rate": 64 + }, + { + "timestamp": 1030732459.7177734, + "heart_rate": 64 + }, + { + "timestamp": 1030732459.9013672, + "heart_rate": 63 + }, + { + "timestamp": 1030732460.1513672, + "heart_rate": 63 + }, + { + "timestamp": 1030732460.4013672, + "heart_rate": 63 + }, + { + "timestamp": 1030732460.6513672, + "heart_rate": 63 + }, + { + "timestamp": 1030732460.8447266, + "heart_rate": 63 + }, + { + "timestamp": 1030732461.0947266, + "heart_rate": 63 + }, + { + "timestamp": 1030732461.3447266, + "heart_rate": 63 + }, + { + "timestamp": 1030732461.5947266, + "heart_rate": 63 + }, + { + "timestamp": 1030732461.7792969, + "heart_rate": 64 + }, + { + "timestamp": 1030732462.0292969, + "heart_rate": 64 + }, + { + "timestamp": 1030732462.2792969, + "heart_rate": 64 + }, + { + "timestamp": 1030732462.5292969, + "heart_rate": 64 + }, + { + "timestamp": 1030732462.6953125, + "heart_rate": 64 + }, + { + "timestamp": 1030732462.9453125, + "heart_rate": 64 + }, + { + "timestamp": 1030732463.1953125, + "heart_rate": 64 + }, + { + "timestamp": 1030732463.4453125, + "heart_rate": 64 + }, + { + "timestamp": 1030732463.6357422, + "heart_rate": 64 + }, + { + "timestamp": 1030732463.8857422, + "heart_rate": 64 + }, + { + "timestamp": 1030732464.1357422, + "heart_rate": 64 + }, + { + "timestamp": 1030732464.3857422, + "heart_rate": 64 + }, + { + "timestamp": 1030732464.6054688, + "heart_rate": 64 + }, + { + "timestamp": 1030732464.8554688, + "heart_rate": 64 + }, + { + "timestamp": 1030732465.1054688, + "heart_rate": 64 + }, + { + "timestamp": 1030732465.3554688, + "heart_rate": 64 + }, + { + "timestamp": 1030732465.5810547, + "heart_rate": 63 + }, + { + "timestamp": 1030732465.8310547, + "heart_rate": 63 + }, + { + "timestamp": 1030732466.0810547, + "heart_rate": 63 + }, + { + "timestamp": 1030732466.3310547, + "heart_rate": 63 + }, + { + "timestamp": 1030732466.5107422, + "heart_rate": 62 + }, + { + "timestamp": 1030732466.7607422, + "heart_rate": 62 + }, + { + "timestamp": 1030732467.0107422, + "heart_rate": 62 + }, + { + "timestamp": 1030732467.2607422, + "heart_rate": 62 + }, + { + "timestamp": 1030732467.4619141, + "heart_rate": 63 + }, + { + "timestamp": 1030732467.7119141, + "heart_rate": 63 + }, + { + "timestamp": 1030732467.9619141, + "heart_rate": 63 + }, + { + "timestamp": 1030732468.2119141, + "heart_rate": 63 + }, + { + "timestamp": 1030732468.3974609, + "heart_rate": 63 + }, + { + "timestamp": 1030732468.6474609, + "heart_rate": 63 + }, + { + "timestamp": 1030732468.8974609, + "heart_rate": 63 + }, + { + "timestamp": 1030732469.1474609, + "heart_rate": 63 + }, + { + "timestamp": 1030732469.3398438, + "heart_rate": 64 + }, + { + "timestamp": 1030732469.5898438, + "heart_rate": 64 + }, + { + "timestamp": 1030732469.8398438, + "heart_rate": 64 + }, + { + "timestamp": 1030732470.0898438, + "heart_rate": 64 + }, + { + "timestamp": 1030732470.1240234, + "heart_rate": 64 + }, + { + "timestamp": 1030732470.3740234, + "heart_rate": 64 + }, + { + "timestamp": 1030732470.6240234, + "heart_rate": 64 + }, + { + "timestamp": 1030732470.8740234, + "heart_rate": 64 + }, + { + "timestamp": 1030732471.1240234, + "heart_rate": 64 + }, + { + "timestamp": 1030732471.2392578, + "heart_rate": 64 + }, + { + "timestamp": 1030732471.4892578, + "heart_rate": 64 + }, + { + "timestamp": 1030732471.7392578, + "heart_rate": 64 + }, + { + "timestamp": 1030732471.9892578, + "heart_rate": 64 + }, + { + "timestamp": 1030732472.1533203, + "heart_rate": 64 + }, + { + "timestamp": 1030732472.4033203, + "heart_rate": 64 + }, + { + "timestamp": 1030732472.6533203, + "heart_rate": 64 + }, + { + "timestamp": 1030732472.9033203, + "heart_rate": 64 + }, + { + "timestamp": 1030732473.0419922, + "heart_rate": 64 + }, + { + "timestamp": 1030732473.2919922, + "heart_rate": 64 + }, + { + "timestamp": 1030732473.5419922, + "heart_rate": 64 + }, + { + "timestamp": 1030732473.7919922, + "heart_rate": 64 + }, + { + "timestamp": 1030732473.9208984, + "heart_rate": 64 + }, + { + "timestamp": 1030732474.1708984, + "heart_rate": 64 + }, + { + "timestamp": 1030732474.4208984, + "heart_rate": 64 + }, + { + "timestamp": 1030732474.6552734, + "heart_rate": 65 + }, + { + "timestamp": 1030732474.9052734, + "heart_rate": 65 + }, + { + "timestamp": 1030732475.1552734, + "heart_rate": 65 + }, + { + "timestamp": 1030732475.4052734, + "heart_rate": 65 + }, + { + "timestamp": 1030732475.6552734, + "heart_rate": 65 + }, + { + "timestamp": 1030732475.6601562, + "heart_rate": 65 + }, + { + "timestamp": 1030732475.9101562, + "heart_rate": 65 + }, + { + "timestamp": 1030732476.1601562, + "heart_rate": 65 + }, + { + "timestamp": 1030732476.4101562, + "heart_rate": 65 + }, + { + "timestamp": 1030732476.5439453, + "heart_rate": 66 + }, + { + "timestamp": 1030732476.7939453, + "heart_rate": 66 + }, + { + "timestamp": 1030732477.0439453, + "heart_rate": 66 + }, + { + "timestamp": 1030732477.2939453, + "heart_rate": 66 + }, + { + "timestamp": 1030732477.4667969, + "heart_rate": 67 + }, + { + "timestamp": 1030732477.7167969, + "heart_rate": 67 + }, + { + "timestamp": 1030732477.9667969, + "heart_rate": 67 + }, + { + "timestamp": 1030732478.2167969, + "heart_rate": 67 + }, + { + "timestamp": 1030732478.4042969, + "heart_rate": 67 + }, + { + "timestamp": 1030732478.6542969, + "heart_rate": 67 + }, + { + "timestamp": 1030732478.9042969, + "heart_rate": 67 + }, + { + "timestamp": 1030732479.1542969, + "heart_rate": 67 + }, + { + "timestamp": 1030732479.3554688, + "heart_rate": 65 + }, + { + "timestamp": 1030732479.6054688, + "heart_rate": 65 + }, + { + "timestamp": 1030732479.8554688, + "heart_rate": 65 + }, + { + "timestamp": 1030732480.1054688, + "heart_rate": 65 + }, + { + "timestamp": 1030732480.3183594, + "heart_rate": 64 + }, + { + "timestamp": 1030732480.5683594, + "heart_rate": 64 + }, + { + "timestamp": 1030732480.8183594, + "heart_rate": 64 + }, + { + "timestamp": 1030732481.0683594, + "heart_rate": 64 + }, + { + "timestamp": 1030732481.25, + "heart_rate": 64 + }, + { + "timestamp": 1030732481.5, + "heart_rate": 64 + }, + { + "timestamp": 1030732481.75, + "heart_rate": 64 + }, + { + "timestamp": 1030732482, + "heart_rate": 64 + }, + { + "timestamp": 1030732482.1796875, + "heart_rate": 64 + }, + { + "timestamp": 1030732482.4296875, + "heart_rate": 64 + }, + { + "timestamp": 1030732482.6796875, + "heart_rate": 64 + }, + { + "timestamp": 1030732482.9296875, + "heart_rate": 64 + }, + { + "timestamp": 1030732483.0869141, + "heart_rate": 64 + }, + { + "timestamp": 1030732483.3369141, + "heart_rate": 64 + }, + { + "timestamp": 1030732483.5869141, + "heart_rate": 64 + }, + { + "timestamp": 1030732483.8369141, + "heart_rate": 64 + }, + { + "timestamp": 1030732484, + "heart_rate": 65 + }, + { + "timestamp": 1030732484.25, + "heart_rate": 65 + }, + { + "timestamp": 1030732484.5, + "heart_rate": 65 + }, + { + "timestamp": 1030732484.75, + "heart_rate": 65 + }, + { + "timestamp": 1030732484.9267578, + "heart_rate": 65 + }, + { + "timestamp": 1030732485.1767578, + "heart_rate": 65 + }, + { + "timestamp": 1030732485.4267578, + "heart_rate": 65 + }, + { + "timestamp": 1030732485.6767578, + "heart_rate": 65 + }, + { + "timestamp": 1030732485.8496094, + "heart_rate": 65 + }, + { + "timestamp": 1030732486.0996094, + "heart_rate": 65 + }, + { + "timestamp": 1030732486.3496094, + "heart_rate": 65 + }, + { + "timestamp": 1030732486.5996094, + "heart_rate": 65 + }, + { + "timestamp": 1030732486.75, + "heart_rate": 65 + }, + { + "timestamp": 1030732487, + "heart_rate": 65 + }, + { + "timestamp": 1030732487.25, + "heart_rate": 65 + }, + { + "timestamp": 1030732487.5, + "heart_rate": 65 + }, + { + "timestamp": 1030732487.6474609, + "heart_rate": 66 + }, + { + "timestamp": 1030732487.8974609, + "heart_rate": 66 + }, + { + "timestamp": 1030732488.1474609, + "heart_rate": 66 + }, + { + "timestamp": 1030732488.3974609, + "heart_rate": 66 + }, + { + "timestamp": 1030732488.546875, + "heart_rate": 66 + }, + { + "timestamp": 1030732488.796875, + "heart_rate": 66 + }, + { + "timestamp": 1030732489.046875, + "heart_rate": 66 + }, + { + "timestamp": 1030732489.296875, + "heart_rate": 66 + }, + { + "timestamp": 1030732489.4638672, + "heart_rate": 67 + }, + { + "timestamp": 1030732489.7138672, + "heart_rate": 67 + }, + { + "timestamp": 1030732489.9638672, + "heart_rate": 67 + }, + { + "timestamp": 1030732490.2138672, + "heart_rate": 67 + }, + { + "timestamp": 1030732490.3857422, + "heart_rate": 66 + }, + { + "timestamp": 1030732490.6357422, + "heart_rate": 66 + }, + { + "timestamp": 1030732490.8857422, + "heart_rate": 66 + }, + { + "timestamp": 1030732491.1357422, + "heart_rate": 66 + }, + { + "timestamp": 1030732491.2900391, + "heart_rate": 66 + }, + { + "timestamp": 1030732491.5400391, + "heart_rate": 66 + }, + { + "timestamp": 1030732491.7900391, + "heart_rate": 66 + }, + { + "timestamp": 1030732492.0400391, + "heart_rate": 66 + }, + { + "timestamp": 1030732492.1982422, + "heart_rate": 66 + }, + { + "timestamp": 1030732492.4482422, + "heart_rate": 66 + }, + { + "timestamp": 1030732492.6982422, + "heart_rate": 66 + }, + { + "timestamp": 1030732492.9482422, + "heart_rate": 66 + }, + { + "timestamp": 1030732493.0917969, + "heart_rate": 66 + }, + { + "timestamp": 1030732493.3417969, + "heart_rate": 66 + }, + { + "timestamp": 1030732493.5917969, + "heart_rate": 66 + }, + { + "timestamp": 1030732493.8417969, + "heart_rate": 66 + }, + { + "timestamp": 1030732493.9785156, + "heart_rate": 67 + }, + { + "timestamp": 1030732494.2285156, + "heart_rate": 67 + }, + { + "timestamp": 1030732494.4785156, + "heart_rate": 67 + }, + { + "timestamp": 1030732494.7285156, + "heart_rate": 67 + }, + { + "timestamp": 1030732494.8183594, + "heart_rate": 67 + }, + { + "timestamp": 1030732495.0683594, + "heart_rate": 67 + }, + { + "timestamp": 1030732495.3183594, + "heart_rate": 67 + }, + { + "timestamp": 1030732495.5683594, + "heart_rate": 67 + }, + { + "timestamp": 1030732495.6386719, + "heart_rate": 69 + }, + { + "timestamp": 1030732495.8886719, + "heart_rate": 69 + }, + { + "timestamp": 1030732496.1386719, + "heart_rate": 69 + }, + { + "timestamp": 1030732496.3886719, + "heart_rate": 69 + }, + { + "timestamp": 1030732496.4541016, + "heart_rate": 71 + }, + { + "timestamp": 1030732496.7041016, + "heart_rate": 71 + }, + { + "timestamp": 1030732496.9541016, + "heart_rate": 71 + }, + { + "timestamp": 1030732497.2041016, + "heart_rate": 71 + }, + { + "timestamp": 1030732497.2802734, + "heart_rate": 72 + }, + { + "timestamp": 1030732497.5302734, + "heart_rate": 72 + }, + { + "timestamp": 1030732497.7802734, + "heart_rate": 72 + }, + { + "timestamp": 1030732498.0302734, + "heart_rate": 72 + }, + { + "timestamp": 1030732498.1318359, + "heart_rate": 72 + }, + { + "timestamp": 1030732498.3818359, + "heart_rate": 72 + }, + { + "timestamp": 1030732498.6318359, + "heart_rate": 72 + }, + { + "timestamp": 1030732498.8818359, + "heart_rate": 72 + }, + { + "timestamp": 1030732499.0029297, + "heart_rate": 71 + }, + { + "timestamp": 1030732499.2529297, + "heart_rate": 71 + }, + { + "timestamp": 1030732499.5029297, + "heart_rate": 71 + }, + { + "timestamp": 1030732499.7529297, + "heart_rate": 71 + }, + { + "timestamp": 1030732499.8828125, + "heart_rate": 70 + }, + { + "timestamp": 1030732500.1328125, + "heart_rate": 70 + }, + { + "timestamp": 1030732500.3828125, + "heart_rate": 70 + }, + { + "timestamp": 1030732500.6328125, + "heart_rate": 70 + }, + { + "timestamp": 1030732500.7529297, + "heart_rate": 69 + }, + { + "timestamp": 1030732501.0029297, + "heart_rate": 69 + }, + { + "timestamp": 1030732501.2529297, + "heart_rate": 69 + }, + { + "timestamp": 1030732501.5029297, + "heart_rate": 69 + }, + { + "timestamp": 1030732501.6591797, + "heart_rate": 69 + }, + { + "timestamp": 1030732501.9091797, + "heart_rate": 69 + }, + { + "timestamp": 1030732502.1591797, + "heart_rate": 69 + }, + { + "timestamp": 1030732502.4091797, + "heart_rate": 69 + }, + { + "timestamp": 1030732502.5380859, + "heart_rate": 69 + }, + { + "timestamp": 1030732502.7880859, + "heart_rate": 69 + }, + { + "timestamp": 1030732503.0380859, + "heart_rate": 69 + }, + { + "timestamp": 1030732503.2880859, + "heart_rate": 69 + }, + { + "timestamp": 1030732503.4472656, + "heart_rate": 67 + }, + { + "timestamp": 1030732503.6972656, + "heart_rate": 67 + }, + { + "timestamp": 1030732503.9472656, + "heart_rate": 67 + }, + { + "timestamp": 1030732504.1972656, + "heart_rate": 67 + }, + { + "timestamp": 1030732504.3681641, + "heart_rate": 67 + }, + { + "timestamp": 1030732504.6181641, + "heart_rate": 67 + }, + { + "timestamp": 1030732504.8681641, + "heart_rate": 67 + }, + { + "timestamp": 1030732505.1181641, + "heart_rate": 67 + }, + { + "timestamp": 1030732505.2363281, + "heart_rate": 66 + }, + { + "timestamp": 1030732505.4863281, + "heart_rate": 66 + }, + { + "timestamp": 1030732505.7363281, + "heart_rate": 66 + }, + { + "timestamp": 1030732505.9863281, + "heart_rate": 66 + }, + { + "timestamp": 1030732506.1572266, + "heart_rate": 66 + }, + { + "timestamp": 1030732506.4072266, + "heart_rate": 66 + }, + { + "timestamp": 1030732506.6572266, + "heart_rate": 66 + }, + { + "timestamp": 1030732506.9072266, + "heart_rate": 66 + }, + { + "timestamp": 1030732507.1035156, + "heart_rate": 65 + }, + { + "timestamp": 1030732507.3535156, + "heart_rate": 65 + }, + { + "timestamp": 1030732507.6035156, + "heart_rate": 65 + }, + { + "timestamp": 1030732507.8535156, + "heart_rate": 65 + }, + { + "timestamp": 1030732508.0976562, + "heart_rate": 64 + }, + { + "timestamp": 1030732508.3476562, + "heart_rate": 64 + }, + { + "timestamp": 1030732508.5976562, + "heart_rate": 64 + }, + { + "timestamp": 1030732508.8476562, + "heart_rate": 64 + }, + { + "timestamp": 1030732509.0976562, + "heart_rate": 62 + }, + { + "timestamp": 1030732509.3476562, + "heart_rate": 62 + }, + { + "timestamp": 1030732509.5976562, + "heart_rate": 62 + }, + { + "timestamp": 1030732509.8476562, + "heart_rate": 62 + }, + { + "timestamp": 1030732510.0976562, + "heart_rate": 62 + }, + { + "timestamp": 1030732510.1152344, + "heart_rate": 61 + }, + { + "timestamp": 1030732510.3652344, + "heart_rate": 61 + }, + { + "timestamp": 1030732510.6152344, + "heart_rate": 61 + }, + { + "timestamp": 1030732510.8652344, + "heart_rate": 61 + }, + { + "timestamp": 1030732511.1152344, + "heart_rate": 61 + }, + { + "timestamp": 1030732511.1513672, + "heart_rate": 60 + }, + { + "timestamp": 1030732511.4013672, + "heart_rate": 60 + }, + { + "timestamp": 1030732511.6513672, + "heart_rate": 60 + }, + { + "timestamp": 1030732511.9013672, + "heart_rate": 60 + }, + { + "timestamp": 1030732512.1513672, + "heart_rate": 60 + }, + { + "timestamp": 1030732512.1650391, + "heart_rate": 60 + }, + { + "timestamp": 1030732512.4150391, + "heart_rate": 60 + }, + { + "timestamp": 1030732512.6650391, + "heart_rate": 60 + }, + { + "timestamp": 1030732512.9150391, + "heart_rate": 60 + }, + { + "timestamp": 1030732513.1650391, + "heart_rate": 60 + }, + { + "timestamp": 1030732513.1845703, + "heart_rate": 59 + }, + { + "timestamp": 1030732513.4345703, + "heart_rate": 59 + }, + { + "timestamp": 1030732513.6845703, + "heart_rate": 59 + }, + { + "timestamp": 1030732513.9345703, + "heart_rate": 59 + }, + { + "timestamp": 1030732514.1845703, + "heart_rate": 59 + }, + { + "timestamp": 1030732514.2089844, + "heart_rate": 59 + }, + { + "timestamp": 1030732514.4589844, + "heart_rate": 59 + }, + { + "timestamp": 1030732514.7089844, + "heart_rate": 59 + }, + { + "timestamp": 1030732514.9589844, + "heart_rate": 59 + }, + { + "timestamp": 1030732515.2011719, + "heart_rate": 59 + }, + { + "timestamp": 1030732515.4511719, + "heart_rate": 59 + }, + { + "timestamp": 1030732515.7011719, + "heart_rate": 59 + }, + { + "timestamp": 1030732515.9511719, + "heart_rate": 59 + }, + { + "timestamp": 1030732516.1787109, + "heart_rate": 60 + }, + { + "timestamp": 1030732516.4287109, + "heart_rate": 60 + }, + { + "timestamp": 1030732516.6787109, + "heart_rate": 60 + }, + { + "timestamp": 1030732516.9287109, + "heart_rate": 60 + }, + { + "timestamp": 1030732517.1171875, + "heart_rate": 61 + }, + { + "timestamp": 1030732517.3671875, + "heart_rate": 61 + }, + { + "timestamp": 1030732517.6171875, + "heart_rate": 61 + }, + { + "timestamp": 1030732517.8671875, + "heart_rate": 61 + }, + { + "timestamp": 1030732518.0703125, + "heart_rate": 62 + }, + { + "timestamp": 1030732518.3203125, + "heart_rate": 62 + }, + { + "timestamp": 1030732518.5703125, + "heart_rate": 62 + }, + { + "timestamp": 1030732518.8203125, + "heart_rate": 62 + }, + { + "timestamp": 1030732519.0224609, + "heart_rate": 62 + }, + { + "timestamp": 1030732519.2724609, + "heart_rate": 62 + }, + { + "timestamp": 1030732519.5224609, + "heart_rate": 62 + }, + { + "timestamp": 1030732519.7724609, + "heart_rate": 62 + }, + { + "timestamp": 1030732519.9775391, + "heart_rate": 63 + }, + { + "timestamp": 1030732520.2275391, + "heart_rate": 63 + }, + { + "timestamp": 1030732520.4775391, + "heart_rate": 63 + }, + { + "timestamp": 1030732520.7275391, + "heart_rate": 63 + }, + { + "timestamp": 1030732520.9580078, + "heart_rate": 63 + }, + { + "timestamp": 1030732521.2080078, + "heart_rate": 63 + }, + { + "timestamp": 1030732521.4580078, + "heart_rate": 63 + }, + { + "timestamp": 1030732521.7080078, + "heart_rate": 63 + }, + { + "timestamp": 1030732521.9580078, + "heart_rate": 63 + }, + { + "timestamp": 1030732521.9599609, + "heart_rate": 62 + }, + { + "timestamp": 1030732522.2099609, + "heart_rate": 62 + }, + { + "timestamp": 1030732522.4599609, + "heart_rate": 62 + }, + { + "timestamp": 1030732522.7099609, + "heart_rate": 62 + }, + { + "timestamp": 1030732522.953125, + "heart_rate": 61 + }, + { + "timestamp": 1030732523.203125, + "heart_rate": 61 + }, + { + "timestamp": 1030732523.453125, + "heart_rate": 61 + }, + { + "timestamp": 1030732523.703125, + "heart_rate": 61 + }, + { + "timestamp": 1030732523.8662109, + "heart_rate": 61 + }, + { + "timestamp": 1030732524.1162109, + "heart_rate": 61 + }, + { + "timestamp": 1030732524.3662109, + "heart_rate": 61 + }, + { + "timestamp": 1030732524.6162109, + "heart_rate": 61 + }, + { + "timestamp": 1030732524.7861328, + "heart_rate": 63 + }, + { + "timestamp": 1030732525.0361328, + "heart_rate": 63 + }, + { + "timestamp": 1030732525.2861328, + "heart_rate": 63 + }, + { + "timestamp": 1030732525.5361328, + "heart_rate": 63 + }, + { + "timestamp": 1030732525.6992188, + "heart_rate": 64 + }, + { + "timestamp": 1030732525.9492188, + "heart_rate": 64 + }, + { + "timestamp": 1030732526.1992188, + "heart_rate": 64 + }, + { + "timestamp": 1030732526.4492188, + "heart_rate": 64 + }, + { + "timestamp": 1030732526.6396484, + "heart_rate": 65 + }, + { + "timestamp": 1030732526.8896484, + "heart_rate": 65 + }, + { + "timestamp": 1030732527.1396484, + "heart_rate": 65 + }, + { + "timestamp": 1030732527.3896484, + "heart_rate": 65 + }, + { + "timestamp": 1030732527.5410156, + "heart_rate": 65 + }, + { + "timestamp": 1030732527.7910156, + "heart_rate": 65 + }, + { + "timestamp": 1030732528.0410156, + "heart_rate": 65 + }, + { + "timestamp": 1030732528.2910156, + "heart_rate": 65 + }, + { + "timestamp": 1030732528.4970703, + "heart_rate": 65 + }, + { + "timestamp": 1030732528.7470703, + "heart_rate": 65 + }, + { + "timestamp": 1030732528.9970703, + "heart_rate": 65 + }, + { + "timestamp": 1030732529.2470703, + "heart_rate": 65 + }, + { + "timestamp": 1030732529.4462891, + "heart_rate": 64 + }, + { + "timestamp": 1030732529.6962891, + "heart_rate": 64 + }, + { + "timestamp": 1030732529.9462891, + "heart_rate": 64 + }, + { + "timestamp": 1030732530.1962891, + "heart_rate": 64 + }, + { + "timestamp": 1030732530.2880859, + "heart_rate": 64 + }, + { + "timestamp": 1030732530.5380859, + "heart_rate": 64 + }, + { + "timestamp": 1030732530.7880859, + "heart_rate": 64 + }, + { + "timestamp": 1030732531.0380859, + "heart_rate": 64 + }, + { + "timestamp": 1030732531.2480469, + "heart_rate": 63 + }, + { + "timestamp": 1030732531.4980469, + "heart_rate": 63 + }, + { + "timestamp": 1030732531.7480469, + "heart_rate": 63 + }, + { + "timestamp": 1030732531.9980469, + "heart_rate": 63 + }, + { + "timestamp": 1030732532.1767578, + "heart_rate": 64 + }, + { + "timestamp": 1030732532.4267578, + "heart_rate": 64 + }, + { + "timestamp": 1030732532.6767578, + "heart_rate": 64 + }, + { + "timestamp": 1030732532.9267578, + "heart_rate": 64 + }, + { + "timestamp": 1030732533.1533203, + "heart_rate": 63 + }, + { + "timestamp": 1030732533.4033203, + "heart_rate": 63 + }, + { + "timestamp": 1030732533.6533203, + "heart_rate": 63 + }, + { + "timestamp": 1030732533.9033203, + "heart_rate": 63 + }, + { + "timestamp": 1030732534.0966797, + "heart_rate": 63 + }, + { + "timestamp": 1030732534.3466797, + "heart_rate": 63 + }, + { + "timestamp": 1030732534.5966797, + "heart_rate": 63 + }, + { + "timestamp": 1030732534.8466797, + "heart_rate": 63 + }, + { + "timestamp": 1030732535.0332031, + "heart_rate": 64 + }, + { + "timestamp": 1030732535.2832031, + "heart_rate": 64 + }, + { + "timestamp": 1030732535.5332031, + "heart_rate": 64 + }, + { + "timestamp": 1030732535.7832031, + "heart_rate": 64 + }, + { + "timestamp": 1030732535.9755859, + "heart_rate": 64 + }, + { + "timestamp": 1030732536.2255859, + "heart_rate": 64 + }, + { + "timestamp": 1030732536.4755859, + "heart_rate": 64 + }, + { + "timestamp": 1030732536.7255859, + "heart_rate": 64 + }, + { + "timestamp": 1030732536.9199219, + "heart_rate": 64 + }, + { + "timestamp": 1030732537.1699219, + "heart_rate": 64 + }, + { + "timestamp": 1030732537.4199219, + "heart_rate": 64 + }, + { + "timestamp": 1030732537.6699219, + "heart_rate": 64 + }, + { + "timestamp": 1030732537.8378906, + "heart_rate": 64 + }, + { + "timestamp": 1030732538.0878906, + "heart_rate": 64 + }, + { + "timestamp": 1030732538.3378906, + "heart_rate": 64 + }, + { + "timestamp": 1030732538.5878906, + "heart_rate": 64 + }, + { + "timestamp": 1030732538.71875, + "heart_rate": 65 + }, + { + "timestamp": 1030732538.96875, + "heart_rate": 65 + }, + { + "timestamp": 1030732539.21875, + "heart_rate": 65 + }, + { + "timestamp": 1030732539.46875, + "heart_rate": 65 + }, + { + "timestamp": 1030732539.6357422, + "heart_rate": 65 + }, + { + "timestamp": 1030732539.8857422, + "heart_rate": 65 + }, + { + "timestamp": 1030732540.1357422, + "heart_rate": 65 + }, + { + "timestamp": 1030732540.3857422, + "heart_rate": 65 + }, + { + "timestamp": 1030732540.5068359, + "heart_rate": 67 + }, + { + "timestamp": 1030732540.7568359, + "heart_rate": 67 + }, + { + "timestamp": 1030732541.0068359, + "heart_rate": 67 + }, + { + "timestamp": 1030732541.2568359, + "heart_rate": 67 + }, + { + "timestamp": 1030732541.4335938, + "heart_rate": 66 + }, + { + "timestamp": 1030732541.6835938, + "heart_rate": 66 + }, + { + "timestamp": 1030732541.9335938, + "heart_rate": 66 + }, + { + "timestamp": 1030732542.1835938, + "heart_rate": 66 + }, + { + "timestamp": 1030732542.3515625, + "heart_rate": 66 + }, + { + "timestamp": 1030732542.6015625, + "heart_rate": 66 + }, + { + "timestamp": 1030732542.8515625, + "heart_rate": 66 + }, + { + "timestamp": 1030732543.1015625, + "heart_rate": 66 + }, + { + "timestamp": 1030732543.2695312, + "heart_rate": 66 + }, + { + "timestamp": 1030732543.5195312, + "heart_rate": 66 + }, + { + "timestamp": 1030732543.7695312, + "heart_rate": 66 + }, + { + "timestamp": 1030732544.0195312, + "heart_rate": 66 + }, + { + "timestamp": 1030732544.1074219, + "heart_rate": 65 + }, + { + "timestamp": 1030732544.3574219, + "heart_rate": 65 + }, + { + "timestamp": 1030732544.6074219, + "heart_rate": 65 + }, + { + "timestamp": 1030732544.8574219, + "heart_rate": 65 + }, + { + "timestamp": 1030732545.0449219, + "heart_rate": 65 + }, + { + "timestamp": 1030732545.2949219, + "heart_rate": 65 + }, + { + "timestamp": 1030732545.5449219, + "heart_rate": 65 + }, + { + "timestamp": 1030732545.7949219, + "heart_rate": 65 + }, + { + "timestamp": 1030732545.9619141, + "heart_rate": 65 + }, + { + "timestamp": 1030732546.2119141, + "heart_rate": 65 + }, + { + "timestamp": 1030732546.4619141, + "heart_rate": 65 + }, + { + "timestamp": 1030732546.7119141, + "heart_rate": 65 + }, + { + "timestamp": 1030732546.9492188, + "heart_rate": 65 + }, + { + "timestamp": 1030732547.1992188, + "heart_rate": 65 + }, + { + "timestamp": 1030732547.4492188, + "heart_rate": 65 + }, + { + "timestamp": 1030732547.6992188, + "heart_rate": 65 + }, + { + "timestamp": 1030732547.9492188, + "heart_rate": 65 + }, + { + "timestamp": 1030732547.9560547, + "heart_rate": 63 + }, + { + "timestamp": 1030732548.2060547, + "heart_rate": 63 + }, + { + "timestamp": 1030732548.4560547, + "heart_rate": 63 + }, + { + "timestamp": 1030732548.7060547, + "heart_rate": 63 + }, + { + "timestamp": 1030732548.9560547, + "heart_rate": 63 + }, + { + "timestamp": 1030732548.9648438, + "heart_rate": 61 + }, + { + "timestamp": 1030732549.2148438, + "heart_rate": 61 + }, + { + "timestamp": 1030732549.4648438, + "heart_rate": 61 + }, + { + "timestamp": 1030732549.7148438, + "heart_rate": 61 + }, + { + "timestamp": 1030732549.9648438, + "heart_rate": 61 + }, + { + "timestamp": 1030732550.0800781, + "heart_rate": 60 + }, + { + "timestamp": 1030732550.3300781, + "heart_rate": 60 + }, + { + "timestamp": 1030732550.5800781, + "heart_rate": 60 + }, + { + "timestamp": 1030732550.8300781, + "heart_rate": 60 + }, + { + "timestamp": 1030732550.9404297, + "heart_rate": 60 + }, + { + "timestamp": 1030732551.1904297, + "heart_rate": 60 + }, + { + "timestamp": 1030732551.4404297, + "heart_rate": 60 + }, + { + "timestamp": 1030732551.6904297, + "heart_rate": 60 + }, + { + "timestamp": 1030732551.8945312, + "heart_rate": 60 + }, + { + "timestamp": 1030732552.1445312, + "heart_rate": 60 + }, + { + "timestamp": 1030732552.3945312, + "heart_rate": 60 + }, + { + "timestamp": 1030732552.6445312, + "heart_rate": 60 + }, + { + "timestamp": 1030732552.8291016, + "heart_rate": 61 + }, + { + "timestamp": 1030732553.0791016, + "heart_rate": 61 + }, + { + "timestamp": 1030732553.3291016, + "heart_rate": 61 + }, + { + "timestamp": 1030732553.5791016, + "heart_rate": 61 + }, + { + "timestamp": 1030732553.7441406, + "heart_rate": 62 + }, + { + "timestamp": 1030732553.9941406, + "heart_rate": 62 + }, + { + "timestamp": 1030732554.2441406, + "heart_rate": 62 + }, + { + "timestamp": 1030732554.4941406, + "heart_rate": 62 + }, + { + "timestamp": 1030732554.6474609, + "heart_rate": 64 + }, + { + "timestamp": 1030732554.8974609, + "heart_rate": 64 + }, + { + "timestamp": 1030732555.1474609, + "heart_rate": 64 + }, + { + "timestamp": 1030732555.3974609, + "heart_rate": 64 + }, + { + "timestamp": 1030732555.5507812, + "heart_rate": 65 + }, + { + "timestamp": 1030732555.8007812, + "heart_rate": 65 + }, + { + "timestamp": 1030732556.0507812, + "heart_rate": 65 + }, + { + "timestamp": 1030732556.3007812, + "heart_rate": 65 + }, + { + "timestamp": 1030732556.4648438, + "heart_rate": 66 + }, + { + "timestamp": 1030732556.7148438, + "heart_rate": 66 + }, + { + "timestamp": 1030732556.9648438, + "heart_rate": 66 + }, + { + "timestamp": 1030732557.2148438, + "heart_rate": 66 + }, + { + "timestamp": 1030732557.3544922, + "heart_rate": 66 + }, + { + "timestamp": 1030732557.6044922, + "heart_rate": 66 + }, + { + "timestamp": 1030732557.8544922, + "heart_rate": 66 + }, + { + "timestamp": 1030732558.1044922, + "heart_rate": 66 + }, + { + "timestamp": 1030732558.2412109, + "heart_rate": 67 + }, + { + "timestamp": 1030732558.4912109, + "heart_rate": 67 + }, + { + "timestamp": 1030732558.7412109, + "heart_rate": 67 + }, + { + "timestamp": 1030732558.9912109, + "heart_rate": 67 + }, + { + "timestamp": 1030732559.1591797, + "heart_rate": 67 + }, + { + "timestamp": 1030732559.4091797, + "heart_rate": 67 + }, + { + "timestamp": 1030732559.6591797, + "heart_rate": 67 + }, + { + "timestamp": 1030732559.9091797, + "heart_rate": 67 + }, + { + "timestamp": 1030732560.1591797, + "heart_rate": 67 + }, + { + "timestamp": 1030732560.2773438, + "heart_rate": 67 + }, + { + "timestamp": 1030732560.5273438, + "heart_rate": 67 + }, + { + "timestamp": 1030732560.7773438, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.0273438, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.0351562, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.2851562, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.5351562, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.7851562, + "heart_rate": 67 + }, + { + "timestamp": 1030732561.9609375, + "heart_rate": 67 + }, + { + "timestamp": 1030732562.2109375, + "heart_rate": 67 + }, + { + "timestamp": 1030732562.4609375, + "heart_rate": 67 + }, + { + "timestamp": 1030732562.7109375, + "heart_rate": 67 + }, + { + "timestamp": 1030732562.9052734, + "heart_rate": 67 + }, + { + "timestamp": 1030732563.1552734, + "heart_rate": 67 + }, + { + "timestamp": 1030732563.4052734, + "heart_rate": 67 + }, + { + "timestamp": 1030732563.6552734, + "heart_rate": 67 + }, + { + "timestamp": 1030732563.7910156, + "heart_rate": 67 + }, + { + "timestamp": 1030732564.0410156, + "heart_rate": 67 + }, + { + "timestamp": 1030732564.2910156, + "heart_rate": 67 + }, + { + "timestamp": 1030732564.5410156, + "heart_rate": 67 + }, + { + "timestamp": 1030732564.6513672, + "heart_rate": 67 + }, + { + "timestamp": 1030732564.9013672, + "heart_rate": 67 + }, + { + "timestamp": 1030732565.1513672, + "heart_rate": 67 + }, + { + "timestamp": 1030732565.4013672, + "heart_rate": 67 + }, + { + "timestamp": 1030732565.4785156, + "heart_rate": 69 + }, + { + "timestamp": 1030732565.7285156, + "heart_rate": 69 + }, + { + "timestamp": 1030732565.9785156, + "heart_rate": 69 + }, + { + "timestamp": 1030732566.2285156, + "heart_rate": 69 + }, + { + "timestamp": 1030732566.25, + "heart_rate": 71 + }, + { + "timestamp": 1030732566.5, + "heart_rate": 71 + }, + { + "timestamp": 1030732566.75, + "heart_rate": 71 + }, + { + "timestamp": 1030732567, + "heart_rate": 71 + }, + { + "timestamp": 1030732567.0195312, + "heart_rate": 74 + }, + { + "timestamp": 1030732567.2695312, + "heart_rate": 74 + }, + { + "timestamp": 1030732567.5195312, + "heart_rate": 74 + }, + { + "timestamp": 1030732567.7695312, + "heart_rate": 74 + }, + { + "timestamp": 1030732567.7841797, + "heart_rate": 76 + }, + { + "timestamp": 1030732568.0341797, + "heart_rate": 76 + }, + { + "timestamp": 1030732568.2841797, + "heart_rate": 76 + }, + { + "timestamp": 1030732568.5302734, + "heart_rate": 77 + }, + { + "timestamp": 1030732568.7802734, + "heart_rate": 77 + }, + { + "timestamp": 1030732569.0302734, + "heart_rate": 77 + }, + { + "timestamp": 1030732569.2695312, + "heart_rate": 79 + }, + { + "timestamp": 1030732569.5195312, + "heart_rate": 79 + }, + { + "timestamp": 1030732569.7695312, + "heart_rate": 79 + }, + { + "timestamp": 1030732570.0107422, + "heart_rate": 80 + }, + { + "timestamp": 1030732570.2607422, + "heart_rate": 80 + }, + { + "timestamp": 1030732570.5107422, + "heart_rate": 80 + }, + { + "timestamp": 1030732570.7519531, + "heart_rate": 80 + }, + { + "timestamp": 1030732571.0019531, + "heart_rate": 80 + }, + { + "timestamp": 1030732571.2519531, + "heart_rate": 80 + }, + { + "timestamp": 1030732571.4755859, + "heart_rate": 81 + }, + { + "timestamp": 1030732571.7255859, + "heart_rate": 81 + }, + { + "timestamp": 1030732571.9755859, + "heart_rate": 81 + }, + { + "timestamp": 1030732572.1796875, + "heart_rate": 82 + }, + { + "timestamp": 1030732572.4296875, + "heart_rate": 82 + }, + { + "timestamp": 1030732572.6796875, + "heart_rate": 82 + }, + { + "timestamp": 1030732572.8769531, + "heart_rate": 84 + }, + { + "timestamp": 1030732573.1269531, + "heart_rate": 84 + }, + { + "timestamp": 1030732573.3769531, + "heart_rate": 84 + }, + { + "timestamp": 1030732573.5615234, + "heart_rate": 85 + }, + { + "timestamp": 1030732573.8115234, + "heart_rate": 85 + }, + { + "timestamp": 1030732574.0615234, + "heart_rate": 85 + }, + { + "timestamp": 1030732574.2373047, + "heart_rate": 86 + }, + { + "timestamp": 1030732574.4873047, + "heart_rate": 86 + }, + { + "timestamp": 1030732574.7373047, + "heart_rate": 86 + }, + { + "timestamp": 1030732574.9189453, + "heart_rate": 87 + }, + { + "timestamp": 1030732575.1689453, + "heart_rate": 87 + }, + { + "timestamp": 1030732575.4189453, + "heart_rate": 87 + }, + { + "timestamp": 1030732575.5917969, + "heart_rate": 88 + }, + { + "timestamp": 1030732575.8417969, + "heart_rate": 88 + }, + { + "timestamp": 1030732576.0917969, + "heart_rate": 88 + }, + { + "timestamp": 1030732576.2490234, + "heart_rate": 89 + }, + { + "timestamp": 1030732576.4990234, + "heart_rate": 89 + }, + { + "timestamp": 1030732576.7490234, + "heart_rate": 89 + }, + { + "timestamp": 1030732576.9033203, + "heart_rate": 90 + }, + { + "timestamp": 1030732577.1533203, + "heart_rate": 90 + }, + { + "timestamp": 1030732577.4033203, + "heart_rate": 90 + }, + { + "timestamp": 1030732577.5957031, + "heart_rate": 91 + }, + { + "timestamp": 1030732577.8457031, + "heart_rate": 91 + }, + { + "timestamp": 1030732578.0957031, + "heart_rate": 91 + }, + { + "timestamp": 1030732578.2861328, + "heart_rate": 89 + }, + { + "timestamp": 1030732578.5361328, + "heart_rate": 89 + }, + { + "timestamp": 1030732578.7861328, + "heart_rate": 89 + }, + { + "timestamp": 1030732578.9648438, + "heart_rate": 88 + }, + { + "timestamp": 1030732579.2148438, + "heart_rate": 88 + }, + { + "timestamp": 1030732579.4648438, + "heart_rate": 88 + }, + { + "timestamp": 1030732579.6269531, + "heart_rate": 88 + }, + { + "timestamp": 1030732579.8769531, + "heart_rate": 88 + }, + { + "timestamp": 1030732580.1269531, + "heart_rate": 88 + }, + { + "timestamp": 1030732580.3115234, + "heart_rate": 88 + }, + { + "timestamp": 1030732580.5615234, + "heart_rate": 88 + }, + { + "timestamp": 1030732580.8115234, + "heart_rate": 88 + }, + { + "timestamp": 1030732580.9804688, + "heart_rate": 89 + }, + { + "timestamp": 1030732581.2304688, + "heart_rate": 89 + }, + { + "timestamp": 1030732581.4804688, + "heart_rate": 89 + }, + { + "timestamp": 1030732581.6591797, + "heart_rate": 89 + }, + { + "timestamp": 1030732581.9091797, + "heart_rate": 89 + }, + { + "timestamp": 1030732582.1591797, + "heart_rate": 89 + }, + { + "timestamp": 1030732582.3291016, + "heart_rate": 89 + }, + { + "timestamp": 1030732582.5791016, + "heart_rate": 89 + }, + { + "timestamp": 1030732582.8291016, + "heart_rate": 89 + }, + { + "timestamp": 1030732582.9873047, + "heart_rate": 89 + }, + { + "timestamp": 1030732583.2373047, + "heart_rate": 89 + }, + { + "timestamp": 1030732583.4873047, + "heart_rate": 89 + }, + { + "timestamp": 1030732583.6435547, + "heart_rate": 90 + }, + { + "timestamp": 1030732583.8935547, + "heart_rate": 90 + }, + { + "timestamp": 1030732584.1435547, + "heart_rate": 90 + }, + { + "timestamp": 1030732584.2871094, + "heart_rate": 91 + }, + { + "timestamp": 1030732584.5371094, + "heart_rate": 91 + }, + { + "timestamp": 1030732584.7871094, + "heart_rate": 91 + }, + { + "timestamp": 1030732584.9296875, + "heart_rate": 92 + }, + { + "timestamp": 1030732585.1796875, + "heart_rate": 92 + }, + { + "timestamp": 1030732585.4296875, + "heart_rate": 92 + }, + { + "timestamp": 1030732585.5878906, + "heart_rate": 93 + }, + { + "timestamp": 1030732585.8378906, + "heart_rate": 93 + }, + { + "timestamp": 1030732586.0878906, + "heart_rate": 93 + }, + { + "timestamp": 1030732586.2509766, + "heart_rate": 92 + }, + { + "timestamp": 1030732586.5009766, + "heart_rate": 92 + }, + { + "timestamp": 1030732586.7509766, + "heart_rate": 92 + }, + { + "timestamp": 1030732586.9042969, + "heart_rate": 92 + }, + { + "timestamp": 1030732587.1542969, + "heart_rate": 92 + }, + { + "timestamp": 1030732587.4042969, + "heart_rate": 92 + }, + { + "timestamp": 1030732587.5712891, + "heart_rate": 91 + }, + { + "timestamp": 1030732587.8212891, + "heart_rate": 91 + }, + { + "timestamp": 1030732588.0712891, + "heart_rate": 91 + }, + { + "timestamp": 1030732588.2285156, + "heart_rate": 91 + }, + { + "timestamp": 1030732588.4785156, + "heart_rate": 91 + }, + { + "timestamp": 1030732588.7285156, + "heart_rate": 91 + }, + { + "timestamp": 1030732588.8857422, + "heart_rate": 91 + }, + { + "timestamp": 1030732589.1357422, + "heart_rate": 91 + }, + { + "timestamp": 1030732589.3857422, + "heart_rate": 91 + }, + { + "timestamp": 1030732589.5585938, + "heart_rate": 91 + }, + { + "timestamp": 1030732589.8085938, + "heart_rate": 91 + }, + { + "timestamp": 1030732590.0585938, + "heart_rate": 91 + }, + { + "timestamp": 1030732590.1240234, + "heart_rate": 91 + }, + { + "timestamp": 1030732590.3740234, + "heart_rate": 91 + }, + { + "timestamp": 1030732590.6240234, + "heart_rate": 91 + }, + { + "timestamp": 1030732590.7617188, + "heart_rate": 91 + }, + { + "timestamp": 1030732591.0117188, + "heart_rate": 91 + }, + { + "timestamp": 1030732591.2617188, + "heart_rate": 91 + }, + { + "timestamp": 1030732591.3994141, + "heart_rate": 91 + }, + { + "timestamp": 1030732591.6494141, + "heart_rate": 91 + }, + { + "timestamp": 1030732591.8994141, + "heart_rate": 91 + }, + { + "timestamp": 1030732592.0371094, + "heart_rate": 92 + }, + { + "timestamp": 1030732592.2871094, + "heart_rate": 92 + }, + { + "timestamp": 1030732592.5371094, + "heart_rate": 92 + }, + { + "timestamp": 1030732592.6748047, + "heart_rate": 94 + }, + { + "timestamp": 1030732592.9248047, + "heart_rate": 94 + }, + { + "timestamp": 1030732593.0361328, + "heart_rate": 94 + }, + { + "timestamp": 1030732593.2861328, + "heart_rate": 94 + }, + { + "timestamp": 1030732593.5361328, + "heart_rate": 94 + }, + { + "timestamp": 1030732593.7470703, + "heart_rate": 94 + }, + { + "timestamp": 1030732593.9970703, + "heart_rate": 94 + }, + { + "timestamp": 1030732594.2470703, + "heart_rate": 94 + }, + { + "timestamp": 1030732594.453125, + "heart_rate": 94 + }, + { + "timestamp": 1030732594.703125, + "heart_rate": 94 + }, + { + "timestamp": 1030732594.953125, + "heart_rate": 94 + }, + { + "timestamp": 1030732595.1689453, + "heart_rate": 94 + }, + { + "timestamp": 1030732595.4189453, + "heart_rate": 94 + }, + { + "timestamp": 1030732595.6689453, + "heart_rate": 94 + }, + { + "timestamp": 1030732595.8798828, + "heart_rate": 94 + }, + { + "timestamp": 1030732596.1298828, + "heart_rate": 94 + }, + { + "timestamp": 1030732596.3798828, + "heart_rate": 94 + }, + { + "timestamp": 1030732596.5820312, + "heart_rate": 94 + }, + { + "timestamp": 1030732596.8320312, + "heart_rate": 94 + }, + { + "timestamp": 1030732597.0820312, + "heart_rate": 94 + }, + { + "timestamp": 1030732597.2900391, + "heart_rate": 92 + }, + { + "timestamp": 1030732597.5400391, + "heart_rate": 92 + }, + { + "timestamp": 1030732597.7900391, + "heart_rate": 92 + }, + { + "timestamp": 1030732597.9912109, + "heart_rate": 87 + }, + { + "timestamp": 1030732598.2412109, + "heart_rate": 87 + }, + { + "timestamp": 1030732598.4912109, + "heart_rate": 87 + }, + { + "timestamp": 1030732598.6904297, + "heart_rate": 87 + }, + { + "timestamp": 1030732598.9404297, + "heart_rate": 87 + }, + { + "timestamp": 1030732599.1904297, + "heart_rate": 87 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + }, + { + "timestamp": 1030732599.3945312, + "heart_rate": 86 + } +] + +merged_record_messages = [ + { + "timestamp": 1030732282, + "heart_rate": 69 + }, + { + "timestamp": 1030732283, + "heart_rate": 69 + }, + { + "timestamp": 1030732284, + "heart_rate": 69 + }, + { + "timestamp": 1030732285, + "heart_rate": 70 + }, + { + "timestamp": 1030732286, + "heart_rate": 70 + }, + { + "timestamp": 1030732287, + "heart_rate": 69 + }, + { + "timestamp": 1030732288, + "heart_rate": 68 + }, + { + "timestamp": 1030732289, + "heart_rate": 67 + }, + { + "timestamp": 1030732290, + "heart_rate": 66 + }, + { + "timestamp": 1030732291, + "heart_rate": 65 + }, + { + "timestamp": 1030732292, + "heart_rate": 65 + }, + { + "timestamp": 1030732293, + "heart_rate": 65 + }, + { + "timestamp": 1030732294, + "heart_rate": 65 + }, + { + "timestamp": 1030732295, + "heart_rate": 65 + }, + { + "timestamp": 1030732296, + "heart_rate": 65 + }, + { + "timestamp": 1030732297, + "heart_rate": 65 + }, + { + "timestamp": 1030732298, + "heart_rate": 65 + }, + { + "timestamp": 1030732299, + "heart_rate": 65 + }, + { + "timestamp": 1030732300, + "heart_rate": 66 + }, + { + "timestamp": 1030732301, + "heart_rate": 66 + }, + { + "timestamp": 1030732302, + "heart_rate": 66 + }, + { + "timestamp": 1030732303, + "heart_rate": 65 + }, + { + "timestamp": 1030732304, + "heart_rate": 66 + }, + { + "timestamp": 1030732305, + "heart_rate": 67 + }, + { + "timestamp": 1030732306, + "heart_rate": 68 + }, + { + "timestamp": 1030732307, + "heart_rate": 69 + }, + { + "timestamp": 1030732308, + "heart_rate": 69 + }, + { + "timestamp": 1030732309, + "heart_rate": 70 + }, + { + "timestamp": 1030732310, + "heart_rate": 71 + }, + { + "timestamp": 1030732311, + "heart_rate": 73 + }, + { + "timestamp": 1030732312, + "heart_rate": 74 + }, + { + "timestamp": 1030732313, + "heart_rate": 74 + }, + { + "timestamp": 1030732314, + "heart_rate": 74 + }, + { + "timestamp": 1030732315, + "heart_rate": 75 + }, + { + "timestamp": 1030732316, + "heart_rate": 77 + }, + { + "timestamp": 1030732317, + "heart_rate": 78 + }, + { + "timestamp": 1030732318, + "heart_rate": 80 + }, + { + "timestamp": 1030732319, + "heart_rate": 80 + }, + { + "timestamp": 1030732320, + "heart_rate": 80 + }, + { + "timestamp": 1030732321, + "heart_rate": 81 + }, + { + "timestamp": 1030732322, + "heart_rate": 81 + }, + { + "timestamp": 1030732323, + "heart_rate": 82 + }, + { + "timestamp": 1030732324, + "heart_rate": 83 + }, + { + "timestamp": 1030732325, + "heart_rate": 85 + }, + { + "timestamp": 1030732326, + "heart_rate": 86 + }, + { + "timestamp": 1030732327, + "heart_rate": 85 + }, + { + "timestamp": 1030732328, + "heart_rate": 85 + }, + { + "timestamp": 1030732329, + "heart_rate": 85 + }, + { + "timestamp": 1030732330, + "heart_rate": 85 + }, + { + "timestamp": 1030732331, + "heart_rate": 86 + }, + { + "timestamp": 1030732332, + "heart_rate": 86 + }, + { + "timestamp": 1030732333, + "heart_rate": 87 + }, + { + "timestamp": 1030732334, + "heart_rate": 89 + }, + { + "timestamp": 1030732335, + "heart_rate": 89 + }, + { + "timestamp": 1030732336, + "heart_rate": 89 + }, + { + "timestamp": 1030732337, + "heart_rate": 89 + }, + { + "timestamp": 1030732338, + "heart_rate": 88 + }, + { + "timestamp": 1030732339, + "heart_rate": 88 + }, + { + "timestamp": 1030732340, + "heart_rate": 88 + }, + { + "timestamp": 1030732341, + "heart_rate": 88 + }, + { + "timestamp": 1030732342, + "heart_rate": 89 + }, + { + "timestamp": 1030732343, + "heart_rate": 89 + }, + { + "timestamp": 1030732344, + "heart_rate": 89 + }, + { + "timestamp": 1030732345, + "heart_rate": 89 + }, + { + "timestamp": 1030732346, + "heart_rate": 89 + }, + { + "timestamp": 1030732347, + "heart_rate": 89 + }, + { + "timestamp": 1030732348, + "heart_rate": 89 + }, + { + "timestamp": 1030732349, + "heart_rate": 89 + }, + { + "timestamp": 1030732350, + "heart_rate": 88 + }, + { + "timestamp": 1030732351, + "heart_rate": 88 + }, + { + "timestamp": 1030732352, + "heart_rate": 88 + }, + { + "timestamp": 1030732353, + "heart_rate": 87 + }, + { + "timestamp": 1030732354, + "heart_rate": 87 + }, + { + "timestamp": 1030732355, + "heart_rate": 87 + }, + { + "timestamp": 1030732356, + "heart_rate": 87 + }, + { + "timestamp": 1030732357, + "heart_rate": 87 + }, + { + "timestamp": 1030732358, + "heart_rate": 87 + }, + { + "timestamp": 1030732359, + "heart_rate": 87 + }, + { + "timestamp": 1030732360, + "heart_rate": 86 + }, + { + "timestamp": 1030732361, + "heart_rate": 87 + }, + { + "timestamp": 1030732362, + "heart_rate": 87 + }, + { + "timestamp": 1030732363, + "heart_rate": 87 + }, + { + "timestamp": 1030732364, + "heart_rate": 86 + }, + { + "timestamp": 1030732365, + "heart_rate": 86 + }, + { + "timestamp": 1030732366, + "heart_rate": 85 + }, + { + "timestamp": 1030732367, + "heart_rate": 86 + }, + { + "timestamp": 1030732368, + "heart_rate": 86 + }, + { + "timestamp": 1030732369, + "heart_rate": 85 + }, + { + "timestamp": 1030732370, + "heart_rate": 85 + }, + { + "timestamp": 1030732371, + "heart_rate": 85 + }, + { + "timestamp": 1030732372, + "heart_rate": 85 + }, + { + "timestamp": 1030732373, + "heart_rate": 84 + }, + { + "timestamp": 1030732374, + "heart_rate": 85 + }, + { + "timestamp": 1030732375, + "heart_rate": 85 + }, + { + "timestamp": 1030732376, + "heart_rate": 84 + }, + { + "timestamp": 1030732377, + "heart_rate": 85 + }, + { + "timestamp": 1030732378, + "heart_rate": 84 + }, + { + "timestamp": 1030732379, + "heart_rate": 84 + }, + { + "timestamp": 1030732380, + "heart_rate": 83 + }, + { + "timestamp": 1030732381, + "heart_rate": 83 + }, + { + "timestamp": 1030732382, + "heart_rate": 83 + }, + { + "timestamp": 1030732383, + "heart_rate": 83 + }, + { + "timestamp": 1030732384, + "heart_rate": 83 + }, + { + "timestamp": 1030732385, + "heart_rate": 85 + }, + { + "timestamp": 1030732386, + "heart_rate": 86 + }, + { + "timestamp": 1030732387, + "heart_rate": 86 + }, + { + "timestamp": 1030732388, + "heart_rate": 86 + }, + { + "timestamp": 1030732389, + "heart_rate": 85 + }, + { + "timestamp": 1030732390, + "heart_rate": 83 + }, + { + "timestamp": 1030732391, + "heart_rate": 81 + }, + { + "timestamp": 1030732392, + "heart_rate": 78 + }, + { + "timestamp": 1030732393, + "heart_rate": 75 + }, + { + "timestamp": 1030732394, + "heart_rate": 73 + }, + { + "timestamp": 1030732395, + "heart_rate": 70 + }, + { + "timestamp": 1030732396, + "heart_rate": 69 + }, + { + "timestamp": 1030732397, + "heart_rate": 67 + }, + { + "timestamp": 1030732398, + "heart_rate": 66 + }, + { + "timestamp": 1030732399, + "heart_rate": 66 + }, + { + "timestamp": 1030732400, + "heart_rate": 67 + }, + { + "timestamp": 1030732401, + "heart_rate": 68 + }, + { + "timestamp": 1030732402, + "heart_rate": 68 + }, + { + "timestamp": 1030732403, + "heart_rate": 68 + }, + { + "timestamp": 1030732404, + "heart_rate": 69 + }, + { + "timestamp": 1030732405, + "heart_rate": 70 + }, + { + "timestamp": 1030732406, + "heart_rate": 69 + }, + { + "timestamp": 1030732407, + "heart_rate": 67 + }, + { + "timestamp": 1030732408, + "heart_rate": 67 + }, + { + "timestamp": 1030732409, + "heart_rate": 67 + }, + { + "timestamp": 1030732410, + "heart_rate": 67 + }, + { + "timestamp": 1030732411, + "heart_rate": 67 + }, + { + "timestamp": 1030732412, + "heart_rate": 68 + }, + { + "timestamp": 1030732413, + "heart_rate": 68 + }, + { + "timestamp": 1030732414, + "heart_rate": 69 + }, + { + "timestamp": 1030732415, + "heart_rate": 69 + }, + { + "timestamp": 1030732416, + "heart_rate": 69 + }, + { + "timestamp": 1030732417, + "heart_rate": 69 + }, + { + "timestamp": 1030732418, + "heart_rate": 68 + }, + { + "timestamp": 1030732419, + "heart_rate": 68 + }, + { + "timestamp": 1030732420, + "heart_rate": 69 + }, + { + "timestamp": 1030732421, + "heart_rate": 70 + }, + { + "timestamp": 1030732422, + "heart_rate": 71 + }, + { + "timestamp": 1030732423, + "heart_rate": 70 + }, + { + "timestamp": 1030732424, + "heart_rate": 71 + }, + { + "timestamp": 1030732425, + "heart_rate": 71 + }, + { + "timestamp": 1030732426, + "heart_rate": 71 + }, + { + "timestamp": 1030732427, + "heart_rate": 72 + }, + { + "timestamp": 1030732428, + "heart_rate": 71 + }, + { + "timestamp": 1030732429, + "heart_rate": 70 + }, + { + "timestamp": 1030732430, + "heart_rate": 68 + }, + { + "timestamp": 1030732431, + "heart_rate": 67 + }, + { + "timestamp": 1030732432, + "heart_rate": 68 + }, + { + "timestamp": 1030732433, + "heart_rate": 68 + }, + { + "timestamp": 1030732434, + "heart_rate": 70 + }, + { + "timestamp": 1030732435, + "heart_rate": 70 + }, + { + "timestamp": 1030732436, + "heart_rate": 71 + }, + { + "timestamp": 1030732437, + "heart_rate": 71 + }, + { + "timestamp": 1030732438, + "heart_rate": 71 + }, + { + "timestamp": 1030732439, + "heart_rate": 72 + }, + { + "timestamp": 1030732440, + "heart_rate": 71 + }, + { + "timestamp": 1030732441, + "heart_rate": 71 + }, + { + "timestamp": 1030732442, + "heart_rate": 71 + }, + { + "timestamp": 1030732443, + "heart_rate": 71 + }, + { + "timestamp": 1030732444, + "heart_rate": 72 + }, + { + "timestamp": 1030732445, + "heart_rate": 72 + }, + { + "timestamp": 1030732446, + "heart_rate": 73 + }, + { + "timestamp": 1030732447, + "heart_rate": 74 + }, + { + "timestamp": 1030732448, + "heart_rate": 75 + }, + { + "timestamp": 1030732449, + "heart_rate": 72 + }, + { + "timestamp": 1030732450, + "heart_rate": 70 + }, + { + "timestamp": 1030732451, + "heart_rate": 68 + }, + { + "timestamp": 1030732452, + "heart_rate": 67 + }, + { + "timestamp": 1030732453, + "heart_rate": 65 + }, + { + "timestamp": 1030732454, + "heart_rate": 64 + }, + { + "timestamp": 1030732455, + "heart_rate": 64 + }, + { + "timestamp": 1030732456, + "heart_rate": 64 + }, + { + "timestamp": 1030732457, + "heart_rate": 64 + }, + { + "timestamp": 1030732458, + "heart_rate": 64 + }, + { + "timestamp": 1030732459, + "heart_rate": 64 + }, + { + "timestamp": 1030732460, + "heart_rate": 64 + }, + { + "timestamp": 1030732461, + "heart_rate": 63 + }, + { + "timestamp": 1030732462, + "heart_rate": 63 + }, + { + "timestamp": 1030732463, + "heart_rate": 64 + }, + { + "timestamp": 1030732464, + "heart_rate": 64 + }, + { + "timestamp": 1030732465, + "heart_rate": 64 + }, + { + "timestamp": 1030732466, + "heart_rate": 64 + }, + { + "timestamp": 1030732467, + "heart_rate": 63 + }, + { + "timestamp": 1030732468, + "heart_rate": 63 + }, + { + "timestamp": 1030732469, + "heart_rate": 63 + }, + { + "timestamp": 1030732470, + "heart_rate": 64 + }, + { + "timestamp": 1030732471, + "heart_rate": 64 + }, + { + "timestamp": 1030732472, + "heart_rate": 64 + }, + { + "timestamp": 1030732473, + "heart_rate": 64 + }, + { + "timestamp": 1030732474, + "heart_rate": 64 + }, + { + "timestamp": 1030732475, + "heart_rate": 65 + }, + { + "timestamp": 1030732476, + "heart_rate": 65 + }, + { + "timestamp": 1030732477, + "heart_rate": 66 + }, + { + "timestamp": 1030732478, + "heart_rate": 67 + }, + { + "timestamp": 1030732479, + "heart_rate": 67 + }, + { + "timestamp": 1030732480, + "heart_rate": 66 + }, + { + "timestamp": 1030732481, + "heart_rate": 64 + }, + { + "timestamp": 1030732482, + "heart_rate": 64 + }, + { + "timestamp": 1030732483, + "heart_rate": 64 + }, + { + "timestamp": 1030732484, + "heart_rate": 64 + }, + { + "timestamp": 1030732485, + "heart_rate": 65 + }, + { + "timestamp": 1030732486, + "heart_rate": 65 + }, + { + "timestamp": 1030732487, + "heart_rate": 65 + }, + { + "timestamp": 1030732488, + "heart_rate": 66 + }, + { + "timestamp": 1030732489, + "heart_rate": 66 + }, + { + "timestamp": 1030732490, + "heart_rate": 67 + }, + { + "timestamp": 1030732491, + "heart_rate": 66 + }, + { + "timestamp": 1030732492, + "heart_rate": 66 + }, + { + "timestamp": 1030732493, + "heart_rate": 66 + }, + { + "timestamp": 1030732494, + "heart_rate": 66 + }, + { + "timestamp": 1030732495, + "heart_rate": 67 + }, + { + "timestamp": 1030732496, + "heart_rate": 68 + }, + { + "timestamp": 1030732497, + "heart_rate": 70 + }, + { + "timestamp": 1030732498, + "heart_rate": 72 + }, + { + "timestamp": 1030732499, + "heart_rate": 72 + }, + { + "timestamp": 1030732500, + "heart_rate": 71 + }, + { + "timestamp": 1030732501, + "heart_rate": 70 + }, + { + "timestamp": 1030732502, + "heart_rate": 69 + }, + { + "timestamp": 1030732503, + "heart_rate": 69 + }, + { + "timestamp": 1030732504, + "heart_rate": 68 + }, + { + "timestamp": 1030732505, + "heart_rate": 67 + }, + { + "timestamp": 1030732506, + "heart_rate": 66 + }, + { + "timestamp": 1030732507, + "heart_rate": 66 + }, + { + "timestamp": 1030732508, + "heart_rate": 65 + }, + { + "timestamp": 1030732509, + "heart_rate": 64 + }, + { + "timestamp": 1030732510, + "heart_rate": 62 + }, + { + "timestamp": 1030732511, + "heart_rate": 61 + }, + { + "timestamp": 1030732512, + "heart_rate": 60 + }, + { + "timestamp": 1030732513, + "heart_rate": 60 + }, + { + "timestamp": 1030732514, + "heart_rate": 59 + }, + { + "timestamp": 1030732515, + "heart_rate": 59 + }, + { + "timestamp": 1030732516, + "heart_rate": 59 + }, + { + "timestamp": 1030732517, + "heart_rate": 60 + }, + { + "timestamp": 1030732518, + "heart_rate": 61 + }, + { + "timestamp": 1030732519, + "heart_rate": 62 + }, + { + "timestamp": 1030732520, + "heart_rate": 62 + }, + { + "timestamp": 1030732521, + "heart_rate": 63 + }, + { + "timestamp": 1030732522, + "heart_rate": 63 + }, + { + "timestamp": 1030732523, + "heart_rate": 62 + }, + { + "timestamp": 1030732524, + "heart_rate": 61 + }, + { + "timestamp": 1030732525, + "heart_rate": 62 + }, + { + "timestamp": 1030732526, + "heart_rate": 63 + }, + { + "timestamp": 1030732527, + "heart_rate": 65 + }, + { + "timestamp": 1030732528, + "heart_rate": 65 + }, + { + "timestamp": 1030732529, + "heart_rate": 65 + }, + { + "timestamp": 1030732530, + "heart_rate": 64 + }, + { + "timestamp": 1030732531, + "heart_rate": 64 + }, + { + "timestamp": 1030732532, + "heart_rate": 63 + }, + { + "timestamp": 1030732533, + "heart_rate": 64 + }, + { + "timestamp": 1030732534, + "heart_rate": 63 + }, + { + "timestamp": 1030732535, + "heart_rate": 63 + }, + { + "timestamp": 1030732536, + "heart_rate": 64 + }, + { + "timestamp": 1030732537, + "heart_rate": 64 + }, + { + "timestamp": 1030732538, + "heart_rate": 64 + }, + { + "timestamp": 1030732539, + "heart_rate": 64 + }, + { + "timestamp": 1030732540, + "heart_rate": 65 + }, + { + "timestamp": 1030732541, + "heart_rate": 66 + }, + { + "timestamp": 1030732542, + "heart_rate": 66 + }, + { + "timestamp": 1030732543, + "heart_rate": 66 + }, + { + "timestamp": 1030732544, + "heart_rate": 66 + }, + { + "timestamp": 1030732545, + "heart_rate": 65 + }, + { + "timestamp": 1030732546, + "heart_rate": 65 + }, + { + "timestamp": 1030732547, + "heart_rate": 65 + }, + { + "timestamp": 1030732548, + "heart_rate": 65 + }, + { + "timestamp": 1030732549, + "heart_rate": 63 + }, + { + "timestamp": 1030732550, + "heart_rate": 61 + }, + { + "timestamp": 1030732551, + "heart_rate": 60 + }, + { + "timestamp": 1030732552, + "heart_rate": 60 + }, + { + "timestamp": 1030732553, + "heart_rate": 60 + }, + { + "timestamp": 1030732554, + "heart_rate": 61 + }, + { + "timestamp": 1030732555, + "heart_rate": 63 + }, + { + "timestamp": 1030732556, + "heart_rate": 65 + }, + { + "timestamp": 1030732557, + "heart_rate": 66 + }, + { + "timestamp": 1030732558, + "heart_rate": 66 + }, + { + "timestamp": 1030732559, + "heart_rate": 67 + }, + { + "timestamp": 1030732560, + "heart_rate": 67 + }, + { + "timestamp": 1030732561, + "heart_rate": 67 + }, + { + "timestamp": 1030732562, + "heart_rate": 67 + }, + { + "timestamp": 1030732563, + "heart_rate": 67 + }, + { + "timestamp": 1030732564, + "heart_rate": 67 + }, + { + "timestamp": 1030732565, + "heart_rate": 67 + }, + { + "timestamp": 1030732566, + "heart_rate": 68 + }, + { + "timestamp": 1030732567, + "heart_rate": 71 + }, + { + "timestamp": 1030732568, + "heart_rate": 74 + }, + { + "timestamp": 1030732569, + "heart_rate": 77 + }, + { + "timestamp": 1030732570, + "heart_rate": 79 + }, + { + "timestamp": 1030732571, + "heart_rate": 80 + }, + { + "timestamp": 1030732572, + "heart_rate": 81 + }, + { + "timestamp": 1030732573, + "heart_rate": 83 + }, + { + "timestamp": 1030732574, + "heart_rate": 85 + }, + { + "timestamp": 1030732575, + "heart_rate": 86 + }, + { + "timestamp": 1030732576, + "heart_rate": 88 + }, + { + "timestamp": 1030732577, + "heart_rate": 89 + }, + { + "timestamp": 1030732578, + "heart_rate": 91 + }, + { + "timestamp": 1030732579, + "heart_rate": 89 + }, + { + "timestamp": 1030732580, + "heart_rate": 88 + }, + { + "timestamp": 1030732581, + "heart_rate": 88 + }, + { + "timestamp": 1030732582, + "heart_rate": 89 + }, + { + "timestamp": 1030732583, + "heart_rate": 89 + }, + { + "timestamp": 1030732584, + "heart_rate": 90 + }, + { + "timestamp": 1030732585, + "heart_rate": 91 + }, + { + "timestamp": 1030732586, + "heart_rate": 93 + }, + { + "timestamp": 1030732587, + "heart_rate": 92 + }, + { + "timestamp": 1030732588, + "heart_rate": 92 + }, + { + "timestamp": 1030732589, + "heart_rate": 91 + }, + { + "timestamp": 1030732590, + "heart_rate": 91 + }, + { + "timestamp": 1030732591, + "heart_rate": 91 + } +] diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/fits/ActivityDevFields.fit b/dbdpy-env/lib/python3.9/site-packages/tests/fits/ActivityDevFields.fit new file mode 100644 index 0000000000000000000000000000000000000000..5f1d71d696a3dfca1638edd2c8c38e6823b9b9d8 GIT binary patch literal 94199 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 AYybcN literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/fits/HrmPluginTestActivity.fit b/dbdpy-env/lib/python3.9/site-packages/tests/fits/HrmPluginTestActivity.fit new file mode 100644 index 0000000000000000000000000000000000000000..d12136e4e6877e6b2ea43cd8b324ae090dfdf819 GIT binary patch literal 25121 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 Zf2q-n$zoTeB0u(KES#6^`1eA={{t%gDn<YR literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/fits/WithGearChangeData.fit b/dbdpy-env/lib/python3.9/site-packages/tests/fits/WithGearChangeData.fit new file mode 100644 index 0000000000000000000000000000000000000000..bfc68f0f01fdc14fb629aa8b89835f67164e0dd6 GIT binary patch literal 90970 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_accumulator.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_accumulator.py new file mode 100644 index 00000000..aba0f02b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_accumulator.py @@ -0,0 +1,27 @@ +'''test_accumulator.py: Contains the set of tests for the Accumulator class in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +from garmin_fit_sdk.accumulator import Accumulator + +def test_accumulator(): + '''Tests functionality of the accumulator class.''' + accumulator = Accumulator() + + accumulator.add(0,0,0) + assert accumulator.accumulate(0,0,1,8) == 1 + + accumulator.add(0,0,0) + assert accumulator.accumulate(0,0,2,8) == 2 + + accumulator.add(0,0,0) + assert accumulator.accumulate(0,0,3,8) == 3 + + accumulator.add(0,0,0) + assert accumulator.accumulate(0,0,4,8) == 4 diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_bitstream.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_bitstream.py new file mode 100644 index 00000000..2883d177 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_bitstream.py @@ -0,0 +1,165 @@ +'''test_bitstream.py: Contains the set of tests for the Bitstream class in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +import pytest +from garmin_fit_sdk import BitStream +from garmin_fit_sdk import fit as FIT + + +class TestFromByteArray: + def test_next_bit(self): + bit_stream = BitStream([0xAA, 0xAA], FIT.BASE_TYPE['UINT8']) + values = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + + index = 0 + for expected in values: + assert bit_stream.bits_available() == len(values) - index + assert bit_stream.has_bits_available() is True + + actual = bit_stream.read_bit() + assert actual == expected + + assert bit_stream.bits_available() == len(values) - index - 1 + + index += 1 + + @pytest.mark.parametrize( + "test_data", + [ + { + 'data': [0xAA], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [4, 4], + 'values': [0xA, 0xA] + }, + { + 'data': [0xAA], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [8], + 'values': [0xAA] + }, + { + 'data': [0xAA, 0xAA], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [16], + 'values': [0xAAAA] + }, + { + 'data': [0xFF, 0xFF], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [16], + 'values': [0xFFFF] + }, + { + 'data': [0xAA, 0xAA, 0xAA, 0x2A], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [32], + 'values': [0x2AAAAAAA] + }, + { + 'data': [0x10, 0x32, 0x54, 0x76], + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [32], + 'values': [0x76543210] + }, + ], + ) + def test_from_byte_array(self, test_data): + bit_stream = BitStream(test_data['data'], test_data['base_type']) + index = 0 + for expected in test_data['values']: + actual = bit_stream.read_bits(test_data['bits_to_read'][index]) + assert actual == expected + index += 1 + +class TestFromInteger: + + def test_next_bit(self): + bit_stream = BitStream(0x0FAA, FIT.BASE_TYPE['UINT16']) + values = [0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0] + + index = 0 + for expected in values: + assert bit_stream.bits_available() == len(values) - index + assert bit_stream.has_bits_available() is True + + actual = bit_stream.read_bit() + assert actual == expected + + assert bit_stream.bits_available() == len(values) - index - 1 + + index += 1 + + @pytest.mark.parametrize( + "test_data", + [ + { + 'data': 0xAA, + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [4], + 'values': [0xA] + }, + { + 'data': 0xAA, + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [4, 4], + 'values': [0xA, 0xA] + }, + { + 'data': 0xAA, + 'base_type': FIT.BASE_TYPE['UINT8'], + 'bits_to_read': [4, 1, 1, 1, 1], + 'values': [0xA, 0x0, 0x1, 0x0, 0x1] + }, + { + 'data': 0xAA, + 'base_type': FIT.BASE_TYPE['UINT16'], + 'bits_to_read': [4, 1, 1, 1, 1], + 'values': [0xA, 0x0, 0x1, 0x0, 0x1] + }, + { + 'data': [0xAAAA, 0x2AAA], + 'base_type': FIT.BASE_TYPE['UINT16'], + 'bits_to_read': [32], + 'values': [0x2AAAAAAA] + }, + { + 'data': [0xAAAAAAAA], + 'base_type': FIT.BASE_TYPE['UINT32'], + 'bits_to_read': [16, 8, 8], + 'values': [0xAAAA, 0xAA, 0xAA] + }, + ], + ) + def test_from_integer(self, test_data): + bit_stream = BitStream(test_data['data'], test_data['base_type']) + index = 0 + for expected in test_data['values']: + actual = bit_stream.read_bits(test_data['bits_to_read'][index]) + assert actual == expected + index += 1 + +def test_exception_raised_big_overstep(): + '''Test that makes sure that an index error exception is raised when reading too many bits.''' + try: + bit_stream = BitStream(0x0FAA, FIT.BASE_TYPE['UINT16']) + bit_stream.read_bits(20) + assert False + except IndexError: + assert True +def test_exception_raised_boundary(): + '''Test that makes sure that an index error exception is raised when reading one too many bits.''' + try: + bit_stream = BitStream(0x0FAA, FIT.BASE_TYPE['UINT16']) + bit_stream.read_bits(16) + bit_stream.read_bit() + assert False + except IndexError: + assert True diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_crc_calculator.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_crc_calculator.py new file mode 100644 index 00000000..5dbf1927 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_crc_calculator.py @@ -0,0 +1,45 @@ +'''test_crc_calculator.py: Contains the set of tests for the Stream class in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +import pytest +from garmin_fit_sdk import CrcCalculator + +from tests.data import Data + + +@pytest.mark.parametrize( + "data,crc_expected,is_correct_crc", + [ + (Data.fit_file_invalid, 0x0000, False), + (Data.fit_file_minimum, 0x488D, True), + (Data.fit_file_short, 0xE3B9, True), + ], +) +def test_file_header_crc(data, crc_expected, is_correct_crc): + '''Tests which validate crc calcualtion on fit file headers''' + if is_correct_crc: + assert (CrcCalculator.calculate_crc(data, 0, 12) == + crc_expected) == is_correct_crc + + +@pytest.mark.parametrize( + "data,file_length,crc_expected,is_correct_crc", + [ + (Data.fit_file_invalid, len(Data.fit_file_invalid) - 2, 0x0000, False), + (Data.fit_file_minimum, len(Data.fit_file_minimum) - 2, 0x0000, True), + (Data.fit_file_short, len(Data.fit_file_short) - 2, 0x4F87, True), + ], +) +def test_file_crc(data, crc_expected, is_correct_crc, file_length): + '''Tests which validate crc calcualtion on fit file data.''' + if is_correct_crc: + assert ( + CrcCalculator.calculate_crc(data, 0, file_length) == crc_expected + ) == is_correct_crc diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_decoder.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_decoder.py new file mode 100644 index 00000000..949381d0 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_decoder.py @@ -0,0 +1,561 @@ +'''test_decoder.py: Contains the set of tests for the decoder class in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +from datetime import datetime, timezone + +import pytest +from garmin_fit_sdk import Decoder, Stream, CrcCalculator + +from tests.data import Data + + +class TestCheckIntegrity: + '''Set of tests verify that the decoder class correctly tests the integrity of one or more fit files.''' + @pytest.mark.parametrize( + "data,expected_value", + [ + (bytearray(), False), + (Data.fit_file_invalid, False), + (Data.fit_file_minimum, True), + (Data.fit_file_short, True), + + (Data.fit_file_incorrect_data_size, False) + ], ids=["Empty File", "Invalid Fit File", "Minimum Size Fit File", + "Fit File with Messages", "Incorrect Data Size"] + ) + def test_check_integrity(self, data, expected_value): + '''Tests the validity of the decoder when it checks a fit file's integrity.''' + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + assert decoder.check_integrity() == expected_value + + def test_check_integrity_is_fit_fail(self, mocker): + '''Tests that an invalid fit file will fail when checking integrity.''' + stream = Stream.from_byte_array(Data.fit_file_short) + mocker.patch('garmin_fit_sdk.Decoder.is_fit', return_value=False) + decoder = Decoder(stream) + + assert decoder.check_integrity() is False + + @pytest.mark.parametrize( + "data,expected_value", + [ + (Data.fit_file_invalid, False), + (Data.fit_file_minimum, True), + (Data.fit_file_short, True), + (bytearray(), False), + (bytearray([0xE]), False), + (bytearray([0x0A, 0x10, 0xD9, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x2E, 0x46, 0x49, 0x54, 0x91, 0x33, 0x00, 0x00]), False), + (bytearray([0x0E, 0x10, 0xD9, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x2C, 0x46, 0x49, 0x54, 0x91, 0x33, 0x00, 0x00]), False), + ], ids=["Invalid Fit File", "Minimum Size Fit File", "Fit File with Messages", + "Empty File", "Input Length < 14", "Header Size != 14 || 12", "Data Type != .FIT"] + ) + def test_is_fit(self, data, expected_value): + '''Tests the validity of the decoder function used to determine if a file is a valid fit file.''' + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + assert decoder.is_fit() == expected_value + +class TestDecoderConstructor: + '''Set of tests that test the functionality of the Decoder constructor''' + def test_fails_if_stream_is_none(self): + '''Tests that the decoder will properly throw an error if a stream that is None is provided.''' + try: + decoder = Decoder(None) + assert False + except RuntimeError: + assert True + +class TestReadFileHeader: + '''Set of tests that test the functionality of reading file headers and the File Header class''' + def test_read_file_header(self): + '''Tests reading the file header with the decoder and decoding the profile and protocol versions.''' + stream = Stream.from_byte_array(Data.fit_file_minimum) + decoder = Decoder(stream) + + file_header = decoder.read_file_header(stream) + + assert file_header.header_size == 14 + assert file_header.protocol_version == 32 + assert file_header.profile_version == 2187 + assert file_header.data_size == 0 + assert file_header.data_type == [b'.FIT'] + assert file_header.header_crc == 18573 + assert file_header.file_total_size == 14 + + def test_read_file_header_dict(self): + '''Tests reading the file header and converting the class to a dictionary.''' + stream = Stream.from_byte_array(Data.fit_file_minimum) + decoder = Decoder(stream) + + file_header = decoder.read_file_header(stream) + file_header_dict = file_header.get_dict() + + protocol_version = (file_header.protocol_version >> 4) + ((file_header.protocol_version & 0x0F) / 10) + profile_version = file_header.profile_version / 1000 if file_header.profile_version > 2199 else 100 + + assert file_header.header_size == file_header_dict['header_size'] + assert protocol_version == file_header_dict['protocol_version'] + assert profile_version == file_header_dict['profile_version'] + assert file_header.data_size == file_header_dict['data_size'] + assert file_header.data_type == file_header_dict['data_type'] + assert file_header.header_crc == file_header_dict['header_crc'] + assert file_header.file_total_size == file_header_dict['file_total_size'] + +class TestDecoderRead(): + '''Set of tests that verify the validity and accuracy of the decoder when reading files.''' + @pytest.mark.parametrize( + "data,num_messages", + [ + (Data.fit_file_minimum, 0), + (Data.fit_file_short, 2), + (Data.fit_file_short_new, 1), + (Data.fit_file_chained, 4) + ], ids=["Fit File Minimum", "Fit File Short with Invalids", "Fit File Short", "Chained Fit File"] + ) + def test_successful_read(self, data, num_messages): + '''Tests that the decoder successfully reads fit files and returns the correct number of messages.''' + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + assert decoder.get_num_messages() == num_messages + + def test_compressed_timestamp_message_should_throw(self): + '''Tests that the decoder should throw an error when reading a message with a compressed timestamp''' + stream = Stream.from_byte_array(Data.fit_file_short_compressed_timestamp) + decoder = Decoder(stream) + messages, errors = decoder.read() + + assert len(errors) == 1 + assert "Compressed timestamp messages are not currently supported" in str(errors[0]) + + def test_read_incorrect_field_def_size(self): + '''Tests that the decoder doesn't break when reading a message with an incorrect field definition size.''' + stream = Stream.from_byte_array(Data.fit_file_short_with_wrong_field_def_size) + decoder = Decoder(stream) + messages, errors = decoder.read(convert_datetimes_to_dates=False) + + assert len(errors) == 0 + assert "time_created" in messages["file_id_mesgs"][0] + + + @pytest.mark.parametrize( + "data,expected_output", + [ + (Data.fit_file_short_new, {'file_id_mesgs' : [{'manufacturer': 'garmin', 'type': 'activity', 'time_created': 1000000000, 'product_name': 'abcdefghi'}]}), + (Data.fit_file_short_none_array, {'file_id_mesgs' : [{'manufacturer': 'garmin', 'type': 'activity', 'time_created': 1000000000}]}) + ], ids=["Fit File Short", "Fit File Short w/ Invalid String"] + ) + def test_read_decoder_output(self, data, expected_output): + '''Tests the validity of the decoder's output after reading a fit file.''' + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + messages, errors = decoder.read(convert_datetimes_to_dates=False) + assert expected_output == messages + assert len(errors) == 0 + + + @pytest.mark.parametrize( + "option_status,expected_value", + [ + (True, -127), + (False, 1865), + (None, -127) + ], ids=["Set to True", "Set to False", "Default Should Apply Scale and Offset"] + ) + def test_apply_scale_and_offset(self, option_status, expected_value): + '''Tests the validity of applying scales and offsets to the decoded fields.''' + stream = Stream.from_file('tests/fits/ActivityDevFields.fit') + decoder = Decoder(stream) + if option_status is not None: + messages, errors = decoder.read(apply_scale_and_offset=option_status, merge_heart_rates=False) + else: + messages, errors = decoder.read() + assert len(errors) == 0 + assert messages['record_mesgs'][0]['altitude'] == expected_value + + def test_scale_and_offset_apply_to_arrays(self): + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + + left_power_phase = messages['record_mesgs'][28]['left_power_phase'] + left_power_phase_peak = messages['record_mesgs'][28]['left_power_phase_peak'] + + right_power_phase = messages['record_mesgs'][28]['right_power_phase'] + right_power_phase_peak = messages['record_mesgs'][28]['right_power_phase_peak'] + + assert left_power_phase == [337.5000052734376, 199.68750312011724] + assert left_power_phase_peak == [75.93750118652346, 104.0625016259766] + assert right_power_phase == [7.031250109863283, 205.31250320800785] + assert right_power_phase_peak == [70.31250109863284, 106.8750016699219] + + def test_scale_and_offset_correct_type_conversion(self): + '''Tests applying scale and offset producing the correct data type.''' + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + + assert messages['file_id_mesgs'][0]['serial_number'] == 3390945015 + assert isinstance(messages['file_id_mesgs'][0]['serial_number'], int) is True + + assert messages['file_id_mesgs'][0]['product'] == 3843 + assert isinstance(messages['file_id_mesgs'][0]['product'], int) is True + + assert isinstance(messages['event_mesgs'][4]['rear_gear_num'], int) is True + + @pytest.mark.parametrize( + "option_status,expected_value", + [ + (True, datetime.utcfromtimestamp(1000000000 + 631065600)), + (False, 1000000000), + (None, datetime.utcfromtimestamp(1000000000 + 631065600)) + ], ids=["Set to True", "Set to False", "Default Should Convert Timestamps"] + ) + def test_convert_datetimes_to_python_datetimes(self, option_status, expected_value): + '''Tests the validity of converting timestamps to python datetimes when decoding files.''' + stream = Stream.from_byte_array(Data.fit_file_short_new) + decoder = Decoder(stream) + if option_status is not None: + messages, errors = decoder.read(convert_datetimes_to_dates=option_status) + else: + messages, errors = decoder.read() + + assert len(errors) == 0 + + if option_status is False: + assert messages['file_id_mesgs'][0]['time_created'] == expected_value + else: + assert str(messages['file_id_mesgs'][0]['time_created']) == str(expected_value.replace(tzinfo=timezone.utc)) + + @pytest.mark.parametrize( + "option_status,expected_type_value", + [ + (True, 'activity'), + (False, 4), + (None, 'activity') + ], ids=["Set to True", "Set to False", "Default Should Convert"] + ) + def test_convert_types_to_strings(self, option_status, expected_type_value): + '''Tests the validity of converting types to strings when decoding files.''' + stream = Stream.from_byte_array(Data.fit_file_short_new) + decoder = Decoder(stream) + if option_status is not None: + messages, errors = decoder.read(convert_types_to_strings=option_status) + else: + messages, errors = decoder.read() + assert len(errors) == 0 + assert messages['file_id_mesgs'][0]['type'] == expected_type_value + + + @pytest.mark.parametrize( + "field_key,expected_value", + [ + (0, pytest.approx(3.0, 0.1)), + (2, [-10, 12]), + (3, ['Hello!', 'Good Job!']) + ], ids=["Single Value", "Array of Values", "String Value(s)"] + ) + def test_read_developer_data(self, field_key, expected_value): + '''Tests the validity of reading developer data from a fit file''' + stream = Stream.from_file('tests/fits/ActivityDevFields.fit') + decoder = Decoder(stream) + decoder.read() + messages, errors = decoder.read() + + assert len(errors) == 0 + assert len(messages['record_mesgs']) == 3601 and len(messages['session_mesgs']) == 1 + + assert messages['session_mesgs'][0]['developer_fields'][field_key] == expected_value + + def test_read_dev_data_no_field_description(self): + '''Tests reading past dev data with no field description message or dev data ID.''' + + stream = Stream.from_byte_array(Data.fit_file_dev_data_missing_field_description) + decoder = Decoder(stream) + decoder.read() + messages, errors = decoder.read() + + assert len(errors) == 0 and len(messages['activity_mesgs']) == 1 + + @pytest.mark.parametrize( + "option_status", + [ + (True), + (False), + (None) + ], ids=["Set to True", "Set to False", "Default should have CRC calculations enabled"] + ) + def test_enable_crc_options(self, mocker, option_status): + '''Tests enabling and disabling CRC calculation when decoding a FIT file.''' + spy_add_bytes = mocker.spy(CrcCalculator, "add_bytes") + spy_get_crc = mocker.spy(CrcCalculator, "get_crc") + + stream = Stream.from_byte_array(Data.fit_file_short) + decoder = Decoder(stream) + + if option_status is not None: + messages, errors = decoder.read(enable_crc_check=option_status) + else: + messages, errors = decoder.read() + + assert len(errors) == 0 + + assert spy_add_bytes.call_count == 0 if option_status is False else spy_add_bytes.call_count > 0 + assert spy_get_crc.call_count == 0 if option_status is False else spy_get_crc.call_count > 0 + + @pytest.mark.parametrize( + "option_status, data, expected_error_status", + [ + (True, Data.fit_file_short_new, False), + (True, Data.fit_file_short_new_invalid_crc, True), + (False, Data.fit_file_short_new, False), + (False, Data.fit_file_short_new_invalid_crc, False), + ], ids=["With CRC | Valid File", "With CRC | Invalid File", "Without CRC | Valid File", "Without CRC | Invalid File"] + ) + def test_enable_crc_options_errors_returned(self, option_status, data, expected_error_status): + '''Tests if errors are returned when decoding a file when CRC calculations are enabled or disabled.''' + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + messages, errors = decoder.read(enable_crc_check=option_status) + + assert len(errors) == 0 if expected_error_status is False else len(errors) > 0 + + @pytest.mark.parametrize( + "option_status", + [ + (True), + (False), + (None) + ], ids=["Set to True", "Set to False", "Default should expand sub fields"] + ) + def test_expand_sub_fields_options(self, option_status): + '''Tests the validity of expanding sub fields of messages decoded from a fit file''' + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + if option_status is not None: + messages, errors = decoder.read(expand_sub_fields=option_status, convert_types_to_strings=False) + else: + messages, errors = decoder.read(convert_types_to_strings=False) + + assert len(errors) == 0 + assert decoder.get_num_messages() == 2055 + + for message in (message for message in messages['event_mesgs'] if message['event'] == 'rider_position_change'): + if option_status is True or option_status is None: + assert message['rider_position'] == message['data'] + + @pytest.mark.parametrize( + "option_status, is_integer", + [ + (True, False), + (False, True), + ], ids=["Convert Types is True, No Ints", "Convert Types is True, All Ints"] + ) + def test_expand_sub_fields_convert_types_to_strings(self, option_status, is_integer): + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + messages, errors = decoder.read(convert_types_to_strings=option_status) + + assert len(errors) == 0 + + rider_position_event_mesgs = [mesg for mesg in messages['event_mesgs'] if 'rider_position' in mesg] + + for mesg in rider_position_event_mesgs: + assert isinstance(mesg['rider_position'], int) is is_integer + + @pytest.mark.parametrize( + "option_status, data, distances", + [ + (True, Data.fit_file_800m_repeats_little_endian, [4000, 800, 200, 1000]), + (False, Data.fit_file_800m_repeats_little_endian, [400000, 80000, 20000, 100000]), + (True, Data.fit_file_800m_repeats_big_endian, [4000, 800, 200, 1000]), + (False, Data.fit_file_800m_repeats_big_endian, [400000, 80000, 20000, 100000]), + ], ids=["Apply Scale and Offset is True, Little Endian", "Apply Scale and Offset is False, Little Endian", + "Apply Scale and Offset is True, Big Endian", "Apply Scale and Offset is False, Big Endian"] + ) + def test_expand_sub_fields_scale_and_offset(self, option_status, data, distances): + stream = Stream.from_byte_array(data) + decoder = Decoder(stream) + messages, errors = decoder.read(apply_scale_and_offset=option_status, merge_heart_rates=False) + + assert len(errors) == 0 + + duration_distance_workout_step_mesgs = [mesg for mesg in messages['workout_step_mesgs'] if 'duration_distance' in mesg] + + for mesg, distance in zip(duration_distance_workout_step_mesgs, distances): + assert mesg['duration_distance'] == distance + + def test_messages_with_no_fields(self): + '''Tests reading messages with no fields assigned in their message definition''' + stream = Stream.from_byte_array(Data.fit_file_messages_with_no_fields) + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + + serial_number = 3452116910 + + assert len(messages['pad_mesgs']) == 1 + assert len(messages['file_id_mesgs']) == 2 + + assert messages['pad_mesgs'][0] == {} + + assert messages['file_id_mesgs'][0]["serial_number"] == serial_number + assert messages['file_id_mesgs'][1]["serial_number"] == serial_number + +class TestComponentExpansion: + def test_sub_field_and_component_expansion(self): + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + messages, errors = decoder.read() + + assert len(errors) == 0 + + rider_position_event_mesgs = [mesg for mesg in messages['event_mesgs'] if 'gear_change_data' in mesg] + + index = 0 + for mesg in rider_position_event_mesgs: + expected = Data.gear_change_data[index] + assert mesg['front_gear_num'] == expected['front_gear_num'] + assert mesg['front_gear'] == expected['front_gear'] + assert mesg['rear_gear_num'] == expected['rear_gear_num'] + assert mesg['rear_gear'] == expected['rear_gear'] + assert mesg['data'] == expected['data'] + assert mesg['gear_change_data'] == expected['gear_change_data'] + + index += 1 + + @pytest.mark.parametrize( + "option_status", + [ + (True), + (False), + (None) + ], ids=["Set to True", "Set to False", "Default should expand components"] + ) + def test_component_expansion_options(self, option_status): + '''Tests the validity of expanding components of messages decoded from a fit file''' + stream = Stream.from_file('tests/fits/WithGearChangeData.fit') + decoder = Decoder(stream) + if option_status is not None: + messages, errors = decoder.read(expand_components=option_status, merge_heart_rates=False) + else: + messages, errors = decoder.read() + + assert len(errors) == 0 + + for message in messages['record_mesgs']: + if option_status is True or option_status is None: + assert message['speed'] == message['enhanced_speed'] + assert message['altitude'] == message['enhanced_altitude'] + else: + assert 'enhanced_speed' not in message + assert 'enhanced_altitude' not in message + + def test_hr_message_component_expansion(self): + '''Tests component expansion given heart rate messages.''' + stream = Stream.from_file('tests/fits/HrmPluginTestActivity.fit') + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + + assert messages['hr_mesgs'][0]['event_timestamp'] == 1242209 + + hr_mesgs = messages['hr_mesgs'] + + index = 0 + for message in hr_mesgs: + if isinstance(message['event_timestamp'], float): + assert message['event_timestamp'] == pytest.approx(Data.hrm_plugin_test_activity_expected[index]) + index += 1 + continue + for timestamp in message['event_timestamp']: + assert timestamp == pytest.approx(Data.hrm_plugin_test_activity_expected[index]) + index += 1 + + def test_enum_component_expansion(self): + '''Tests component expansion in a monitoring file which includes expanded components which are enums.''' + stream = Stream.from_byte_array(Data.fit_file_monitoring) + decoder = Decoder(stream) + messages, errors = decoder.read() + assert len(errors) == 0 + assert len(messages['monitoring_mesgs']) == 4 + assert messages['monitoring_mesgs'][0]['activity_type'] == "running" and messages['monitoring_mesgs'][0]['intensity'] == 3 + assert messages['monitoring_mesgs'][0]['cycles'] == 10 + + assert messages['monitoring_mesgs'][1]['activity_type'] == "walking" and messages['monitoring_mesgs'][1]['intensity'] == 0 + assert messages['monitoring_mesgs'][1]['cycles'] == 30 + + assert messages['monitoring_mesgs'][2]['activity_type'] == 30 and messages['monitoring_mesgs'][2]['intensity'] == 0 + assert messages['monitoring_mesgs'][2]['cycles'] == 15 + + assert 'activity_type' not in messages['monitoring_mesgs'][3] and 'intensity' not in messages['monitoring_mesgs'][3] + assert messages['monitoring_mesgs'][3]['cycles'] == 15 + +class TestMergeHeartrates: + '''Set of tests which verify the functionality of merging heartrates to records when decoding.''' + @pytest.mark.parametrize( + "option_status, expected", + [ + (True, False), + (False, True), + (None, False) + ], ids=["Set to True", "Set to False", "Default should merge heart rates"] + ) + def test_merge_heart_rates_options(self, option_status, expected): + '''Tests that all the options settings for merge_heart_rates work as expected when decoding.''' + stream = Stream.from_file('tests/fits/HrmPluginTestActivity.fit') + decoder = Decoder(stream) + + if option_status is not None: + messages, errors = decoder.read(merge_heart_rates=option_status) + else: + messages, errors = decoder.read() + + assert len(errors) == 0 + + missing_hr = False + for message in messages['record_mesgs']: + if 'heart_rate' not in message: + missing_hr = True + assert missing_hr == expected + + def test_merge_heart_rate_fails_without_scale_and_offset(self): + '''Tests to ensure that decoding fails when merge_heart_rates == True but apply_scale_and_offset == False''' + stream = Stream.from_file('tests/fits/HrmPluginTestActivity.fit') + decoder = Decoder(stream) + messages, errors = decoder.read(apply_scale_and_offset=False) + assert len(errors) == 1 + + def test_merge_heart_rate_fails_without_expand_components(self): + '''Tests to ensure that decoding fails when merge_heart_rates == True but expand_components == False''' + stream = Stream.from_file('tests/fits/HrmPluginTestActivity.fit') + decoder = Decoder(stream) + messages, errors = decoder.read(expand_components=False) + assert len(errors) == 1 + + +def test_mesg_listener(): + '''Tests that a message listener passed to the decoder is correctly called.''' + stream = Stream.from_byte_array(Data.fit_file_short) + decoder = Decoder(stream) + + def mesg_listener(mesg_num, message): + raise Exception("The message listener was called!") + + messages, errors = decoder.read(mesg_listener=mesg_listener) + + assert len(errors) == 1 + assert str(errors[0]) == "The message listener was called!" diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_errors.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_errors.py new file mode 100644 index 00000000..773c0492 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_errors.py @@ -0,0 +1,56 @@ +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +import pytest +from garmin_fit_sdk import Decoder, Stream + + +@pytest.mark.skip +@pytest.mark.parametrize( + "filename", + ['Corrupt_00000.fit', 'Corrupt_00001.fit', 'Corrupt_00002.fit', 'Corrupt_00003.fit', 'Corrupt_00004.fit', 'Corrupt_00005.fit', 'Corrupt_00006.fit', + 'Corrupt_00007.fit', 'Corrupt_00008.fit', 'Corrupt_00009.fit', 'Corrupt_00010.fit', 'Corrupt_00011.fit', 'Corrupt_00012.fit', 'Corrupt_00013.fit', + 'Corrupt_00014.fit', 'Corrupt_00015.fit', 'Corrupt_00016.fit', 'Corrupt_00017.fit', 'Corrupt_00018.fit', 'Corrupt_00019.fit', 'Corrupt_00020.fit', + 'Corrupt_00021.fit', 'Corrupt_00022.fit', 'Corrupt_00023.fit', 'Corrupt_00024.fit', 'TBD_00000.fit', 'TBD_00001.fit', 'TBD_00002.fit', 'TBD_00003.fit', + 'TBD_00004.fit', 'TBD_00005.fit', 'TBD_00006.fit', 'TBD_00007.fit', 'TBD_00008.fit', 'TBD_00009.fit', 'TBD_00010.fit', 'TBD_00011.fit', 'TBD_00012.fit', + 'TBD_00013.fit', 'TBD_00014.fit', 'TBD_00015.fit', 'TBD_00016.fit', 'TBD_00017.fit', 'TBD_00018.fit', 'TBD_00018.fit', 'TBD_00019.fit', 'TBD_00020.fit', + 'TBD_00021.fit', 'TBD_00022.fit', 'TBD_00023.fit', 'TBD_00024.fit', 'TBD_00025.fit', 'TBD_00026.fit', 'TBD_00027.fit', 'TBD_00028.fit', 'TBD_00029.fit', + 'TBD_00030.fit', 'TBD_00031.fit', 'TBD_00032.fit', 'TBD_00033.fit', 'TBD_00034.fit', 'TBD_00035.fit', 'TBD_00036.fit', 'TBD_00037.fit', 'TBD_00038.fit', + 'TBD_00039.fit', 'TBD_00040.fit', 'TBD_00041.fit', 'TBD_00042.fit', 'TBD_00043.fit', 'TBD_00044.fit', 'TBD_00045.fit', 'TBD_00046.fit', 'TBD_00047.fit', + 'TBD_00048.fit', 'TBD_00049.fit', 'TBD_00050.fit', 'TBD_00051.fit', 'TBD_00052.fit', 'TBD_00053.fit', 'TBD_00054.fit', 'TBD_00055.fit', 'TBD_00056.fit', + 'TBD_00057.fit', 'TBD_00058.fit', 'TBD_00059.fit', 'TBD_00060.fit', 'TBD_00061.fit', 'TBD_00062.fit', 'TBD_00063.fit', 'TBD_00064.fit', 'TBD_00065.fit', + 'TBD_00066.fit', 'TBD_00067.fit', 'TBD_00068.fit', 'TBD_00069.fit', 'TBD_00070.fit', 'TBD_00071.fit', 'TBD_00072.fit', 'TBD_00073.fit', 'TBD_00074.fit', + 'TBD_00075.fit', 'TBD_00076.fit', 'TBD_00077.fit', 'TBD_00078.fit', 'TBD_00079.fit', 'TBD_00080.fit', 'TBD_00081.fit', 'TBD_00082.fit', 'TBD_00083.fit', + 'TBD_00084.fit', 'TBD_00085.fit', 'TBD_00086.fit', 'TBD_00087.fit', 'TBD_00088.fit', 'TBD_00089.fit', 'TBD_00090.fit', 'TBD_00091.fit', 'TBD_00092.fit', + 'TBD_00093.fit', 'TBD_00094.fit', 'TBD_00095.fit', 'TBD_00096.fit', 'TBD_00097.fit', 'TBD_00098.fit', 'TBD_00099.fit', 'TBD_00100.fit', 'TBD_00101.fit', + 'TBD_00102.fit', 'TBD_00103.fit', 'TBD_00104.fit', 'TBD_00105.fit', 'TBD_00106.fit', 'TBD_00107.fit', 'TBD_00108.fit', 'TBD_00109.fit', 'TBD_00110.fit', + 'TBD_00111.fit', 'TBD_00112.fit', 'TBD_00113.fit', 'TBD_00114.fit', 'TBD_00115.fit', 'TBD_00116.fit', 'TBD_00117.fit', 'TBD_00118.fit', 'TBD_00119.fit', + 'TBD_00120.fit', 'TBD_00121.fit', 'TBD_00122.fit', 'TBD_00123.fit', 'TBD_00124.fit', 'TBD_00125.fit', 'TBD_00126.fit', 'TBD_00127.fit', 'TBD_00128.fit', + 'TBD_00129.fit', 'TBD_00130.fit', 'TBD_00131.fit', 'TBD_00132.fit', 'TBD_00133.fit', 'TBD_00134.fit', 'TBD_00135.fit', 'TBD_00136.fit', 'TBD_00137.fit', + 'TBD_00138.fit', 'TBD_00139.fit', 'TBD_00140.fit', 'TBD_00141.fit', 'TBD_00142.fit', 'TBD_00143.fit', 'TBD_00144.fit', 'TBD_00145.fit', 'TBD_00146.fit', + 'TBD_00147.fit', 'TBD_00148.fit', 'TBD_00149.fit', 'TBD_00150.fit', 'TBD_00151.fit', 'TBD_00152.fit', 'TBD_00153.fit', 'TBD_00154.fit', 'TBD_00155.fit', + 'TBD_00156.fit', 'TBD_00157.fit', 'TBD_00158.fit', 'TBD_00159.fit', 'TBD_00160.fit', 'TBD_00161.fit', 'TBD_00162.fit', 'TBD_00163.fit', 'TBD_00164.fit', + 'TBD_00165.fit', 'TBD_00166.fit', 'TBD_00167.fit', 'TBD_00168.fit', 'TBD_00169.fit', 'TBD_00170.fit', 'TBD_00171.fit', 'TBD_00172.fit', 'TBD_00173.fit', + 'TBD_00174.fit', 'TBD_00175.fit', 'TBD_00176.fit', 'TBD_00177.fit', 'TBD_00178.fit', 'TBD_00179.fit', 'TBD_00180.fit', 'TBD_00181.fit', 'TBD_00182.fit', + 'TBD_00183.fit', 'TBD_00184.fit', 'TBD_00185.fit', 'TBD_00186.fit', 'TBD_00187.fit', 'TBD_00188.fit', 'TBD_00189.fit', 'TBD_00190.fit', 'TBD_00191.fit', + 'TBD_00192.fit', 'TBD_00193.fit', 'TBD_00194.fit', 'TBD_00195.fit', 'TBD_00196.fit', 'TBD_00197.fit', 'TBD_00198.fit', 'TBD_00199.fit', 'TBD_00200.fit', + 'TBD_00201.fit', 'TBD_00202.fit', 'TBD_00203.fit', 'TBD_00204.fit', 'TBD_00205.fit', 'TBD_00206.fit', 'TBD_00207.fit', 'TBD_00208.fit', 'TBD_00209.fit', + 'TBD_00210.fit', 'TBD_00211.fit', 'TBD_00212.fit', 'TBD_00213.fit', 'TBD_00214.fit', 'TBD_00215.fit', 'TBD_00216.fit', 'TBD_00217.fit', 'TBD_00218.fit', + 'TBD_00219.fit' +], +) +def test_errors(filename): + filestring = 'tests/ignore/'+filename + stream = Stream.from_file(filestring) + decoder = Decoder(stream) + messages, errors = decoder.read() + + if len(errors) > 0: + assert "FIT Runtime Error" in str(errors[0]) + + diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_hr_mesg_utils.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_hr_mesg_utils.py new file mode 100644 index 00000000..62ddc856 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_hr_mesg_utils.py @@ -0,0 +1,51 @@ +'''test_hr_mesg_utils.py: Contains the tests for the heart rate message merging functionality''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +from garmin_fit_sdk import hr_mesg_utils +from garmin_fit_sdk.decoder import Decoder +from garmin_fit_sdk.stream import Stream + +from . import data_expand_hr_mesgs + + +def test_expand_heart_rates(): + '''Tests expanding heart rates''' + stream = Stream.from_file("tests/fits/HrmPluginTestActivity.fit") + decoder = Decoder(stream) + messages, errors = decoder.read() + + assert len(errors) == 0 + + heartrates = hr_mesg_utils.expand_heart_rates(messages['hr_mesgs']) + + assert len(heartrates) == len(data_expand_hr_mesgs.expanded_hr_messages) + + index = 0 + for message in heartrates: + expected = data_expand_hr_mesgs.expanded_hr_messages[index] + assert message['timestamp'] == expected['timestamp'] + assert message['heart_rate'] == expected['heart_rate'] + index += 1 + +def test_hr_mesgs_to_record_mesgs(): + '''Tests that the heart rate messages are merged into the record messages correctly.''' + stream = Stream.from_file("tests/fits/HrmPluginTestActivity.fit") + decoder = Decoder(stream) + messages, errors = decoder.read(merge_heart_rates=True, convert_datetimes_to_dates=False) + + assert len(errors) == 0 + assert len(messages['record_mesgs']) == len(data_expand_hr_mesgs.merged_record_messages) + + index = 0 + for message in messages['record_mesgs']: + expected = data_expand_hr_mesgs.merged_record_messages[index] + assert message['timestamp'] == expected['timestamp'] + assert message['heart_rate'] == expected['heart_rate'] + index += 1 diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_stream.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_stream.py new file mode 100644 index 00000000..09ec0a67 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_stream.py @@ -0,0 +1,234 @@ +'''test_stream.py: Contains the set of tests for the Stream class in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +import io + +import pytest +from garmin_fit_sdk import Stream, util + + +def test_stream_from_buffered_reader(): + '''Tests creating a stream from a buffered reader object''' + buffered_reader = io.BufferedReader( + io.BytesIO(bytearray([0x0E, 0x20, 0x8B]))) + stream = Stream.from_buffered_reader(buffered_reader) + assert stream.get_buffered_reader() is not None + assert stream.peek_byte() == 0x0E + +def test_stream_from_bytes_io(): + '''Tests creating a stream from a BytesIO object''' + bytes_io = io.BytesIO(bytearray([0x0E, 0x20, 0x8B])) + stream = Stream.from_bytes_io(bytes_io) + assert stream.get_buffered_reader() is not None + assert stream.peek_byte() == 0x0E + +def test_stream_from_byte_array(): + '''Tests creating a stream from a bytearray object''' + byte_array = bytearray([0x0E, 0x20, 0x8B]) + stream = Stream.from_byte_array(byte_array) + assert stream.get_buffered_reader() is not None + assert stream.peek_byte() == 0x0E + +def test_stream_from_file(): + '''Tests creating a stream from a binary fit file''' + stream = Stream.from_file("tests/fits/ActivityDevFields.fit") + assert stream.get_buffered_reader() is not None + assert stream.peek_byte() == 0x0E + + +@pytest.mark.parametrize( + "given_bytes,position,expected_value", + [ + (bytearray([0x0E, 0x20, 0x8B]), 0, 0x0E), + (bytearray([0x0E, 0x20, 0x8B]), 1, 0x20), + (bytearray([0x0E, 0x20, 0x8B]), 2, 0x8B), + ], +) +class TestParametrizedByByte: + '''Group of tests for testing read and peek by byte''' + def test_peek_byte(self, given_bytes, position, expected_value): + '''Tests peeking a single byte from the stream and returning its value''' + stream = Stream.from_byte_array(given_bytes) + stream.seek(position) + assert stream.peek_byte() == expected_value + assert stream.peek_byte() == stream.read_byte() + + def test_read_byte(self, given_bytes, position, expected_value): + '''Tests reading a single byte from the stream and returning its value''' + stream = Stream.from_byte_array(given_bytes) + stream.seek(position) + assert stream.read_byte() == expected_value + stream.seek(position) + assert stream.peek_byte() == stream.read_byte() + + +@pytest.mark.parametrize( + "given_bytes,num_bytes,expected_value", + [ + (bytearray([0x0E, 0x20, 0x8B]), 0, bytearray([])), + (bytearray([0x0E, 0x20, 0x8B]), 1, bytearray([0x0E])), + (bytearray([0x0E, 0x20, 0x8B]), 2, bytearray([0x0E, 0x20])), + (bytearray([0x0E, 0x20, 0x8B]), 3, bytearray([0x0E, 0x20, 0x8B])), + ], +) +class TestParametrizedByBytes: + '''Set of tests for verifying reads and peeks greater than one byte''' + def test_peek_bytes(self, given_bytes, num_bytes, expected_value): + '''Tests peeking a number of bytes from a stream''' + stream = Stream.from_byte_array(given_bytes) + assert stream.peek_bytes(num_bytes) == expected_value + assert stream.peek_bytes(num_bytes) == stream.read_bytes(num_bytes) + + def test_read_bytes(self, given_bytes, num_bytes, expected_value): + '''Tests peeking a number of bytes from a stream''' + stream = Stream.from_byte_array(given_bytes) + assert stream.read_bytes(num_bytes) == expected_value + stream.reset() + assert stream.peek_bytes(num_bytes) == stream.read_bytes(num_bytes) + + +@pytest.mark.parametrize( + "given_bytes,start,end,expected_value", + [ + (bytearray([0x0E, 0x20, 0x8B]), 0, 1, bytearray([0x0E])), + (bytearray([0x0E, 0x20, 0x8B]), 1, 2, bytearray([0x20])), + (bytearray([0x0E, 0x20, 0x8B]), 0, 2, bytearray([0x0E, 0x20])), + (bytearray([0x0E, 0x20, 0x8B]), 0, 3, bytearray([0x0E, 0x20, 0x8B])), + ], +) +def test_slice(given_bytes, start, end, expected_value): + '''Tests taking an array values from the stream from the start index to the end''' + stream = Stream.from_byte_array(given_bytes) + starting_position = stream.position() + assert stream.slice(start, end) == expected_value + assert stream.position() == starting_position + + +class TestReadValues: + '''Set of tests which validate correct reading of numeric values and strings from the stream.''' + @pytest.mark.parametrize( + "given_bytes", + [ + (bytearray([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])), + ], + ) + class TestInts: + '''Set of tests which verify decoding of int values from a fit file.''' + def test_read_unint8(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=8B' ) + assert values == [255, 255, 255, 255, 255, 255, 255, 255] + + def test_read_sint8(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=8b' ) + assert values == [-1, -1, -1, -1, -1, -1, -1, -1] + + def test_read_unint16(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=4H' ) + assert values == [65535, 65535, 65535, 65535] + + def test_read_sint16(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=4h' ) + assert values == [-1, -1, -1, -1] + + def test_read_uint32(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=2I' ) + assert values == [4294967295, 4294967295] + + def test_read_sint32(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=2i' ) + assert values == [-1, -1] + + def test_read_uint64(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=Q' ) + assert values == [18446744073709551615] + def test_read_sint64(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=q' ) + assert values == [-1] + + + @pytest.mark.parametrize( + "given_bytes", + [ + (bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F])), + ], + ) + class TestFloats: + '''Set of tests which verify decoding of float values from a fit file.''' + def test_read_float_32(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=2f' ) + assert values == [0.0, 1.875] + + def test_read_double_64(self, given_bytes): + stream = Stream.from_byte_array(given_bytes) + values = stream.read_and_unpack(stream.get_length(), '=d' ) + assert values == [1] + + + class TestStrings: + '''Set of tests which verify decoding of strings from a fit file.''' + @pytest.mark.parametrize( + "given_bytes,expected_value", + [ + (bytearray([0x2E, 0x46, 0x49, 0x54]), ".FIT"), + (bytearray([0x2E, 0x46, 0x49, 0x54, 0x00, 0x00]), ".FIT"), + (bytearray([0xe8, 0xbf, 0x99, 0xe5, 0xa5, 0x97, 0xe5, 0x8a, 0xa8, 0xe4, 0xbd, + 0x9c, 0xe7, 0x94, 0xb1, 0xe4, 0xb8, 0xa4, 0xe7, 0xbb, 0x84]), "这套动作由两组"), + (bytearray([0xe8, 0xbf, 0x99, 0xe5, 0xa5, 0x97, 0xe5, 0x8a, 0xa8, 0xe4, 0xbd, + 0x9c, 0xe7, 0x94, 0xb1, 0xe4, 0xb8, 0xa4, 0xe7, 0xbb, 0x84, 0x00]), "这套动作由两组"), + ], ids=["Regular String", "String w/ Null Terminator", "Multibyte String w/o Null Terminator", "Multibyte String w/ Null Terminator"], + ) + def test_read_string(self, given_bytes, expected_value): + '''Tests reading any given string from the stream.''' + stream = Stream.from_byte_array(given_bytes) + value = stream.read_string(stream.get_length()) + assert util._convert_string(value[0]) == expected_value + + def test_read_string_array(self): + '''Tests reading an array of strings from the stream.''' + stream = Stream.from_byte_array(bytearray([0x2E, 0x46, 0x49, 0x54, 0x00, 0x2E, 0x46, 0x49, 0x54, 0x00])) + string = stream.read_string(stream.get_length()) + strings = util._convert_string(string[0]) + for string in strings: + assert string == '.FIT' + + def test_read_string_bad_utf8_characters(self): + '''Tests correctly reading bad utf8 characters after decoding from the stream.''' + stream = Stream.from_byte_array(bytearray([ + 0x37, 0x35, 0x25, 0x20, 0x65, 0x66, 0x66, 0x6F, 0x72, 0x74, 0x2E, 0x00, 0x65, 0x66, 0x66, 0x6F, + 0x72, 0x74, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x75, 0x6E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x03, 0x40, 0x00, 0x01, 0x00, 0x1B, 0x07, + 0xFE, 0x02, 0x84, 0x07, 0x01, 0x00, 0x03, 0x01, 0x00, 0x04, 0x04, 0x86, 0x01, 0x01, + 0x00, 0x02, 0x04, 0x86, 0x08, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0xD7, 0x7C, 0x37, 0x35, 0x25, 0x20, 0x65, 0x66, 0x66, 0x6F, 0x72, 0x74, 0x2E, + 0x00, 0x40, 0x00, 0x01, 0x00, 0x1B, 0x0B, 0xFE, 0x02, 0x84, 0x07, 0x01, 0x00, 0x03, 0x01, + 0x00, 0x05, 0x04, 0x86, 0x06, 0x04, 0x86, 0x04, 0x04, 0x86, 0x01, 0x01, 0x00, 0x02, + 0x04, 0x86, 0x08, 0x10, 0x07, 0x0A, 0x02, 0x84, 0x0B, 0x02, 0x84, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x08, 0xEB, 0x00, 0x03, 0x7B, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x03, 0xAE, 0xF8, 0x52, 0x61, 0x63, 0x65, 0x20, 0x67, 0x6F, 0x61, 0x6C, 0x20, 0x70, + 0x61, 0x63, 0x65, 0x2E, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0xD7, 0x7C, 0x37, 0x35, 0x25, 0x20, 0x65, 0x66])) + string = stream.read_string(stream.get_length()) + strings = util._convert_string(string[0]) + assert len(strings) == 54 + assert strings[0] == "75% effort." + assert strings[6] == "un" # Not '����un' + assert strings[13] == "" # Not '��' + assert strings[42] == "Race goal pace." # Not '��Race goal pace.' + assert strings[53] == "|75% ef" # Not '�|75% ef' diff --git a/dbdpy-env/lib/python3.9/site-packages/tests/test_util.py b/dbdpy-env/lib/python3.9/site-packages/tests/test_util.py new file mode 100644 index 00000000..f9159ef7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tests/test_util.py @@ -0,0 +1,30 @@ +'''test_util.py: Contains the set of tests for the util module in the Python FIT SDK''' + +########################################################################################### +# Copyright 2023 Garmin International, Inc. +# Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +# may not use this file except in compliance with the Flexible and Interoperable Data +# Transfer (FIT) Protocol License. +########################################################################################### + + +from datetime import datetime, timezone + +import pytest +from garmin_fit_sdk import util + + +@pytest.mark.parametrize( + "given_timestamp,expected_datetime", + [ + (1029086357, datetime.utcfromtimestamp(1029086357 + 631065600)), + (0, datetime.utcfromtimestamp(631065600)), + (None, datetime.utcfromtimestamp(631065600)), + ], ids=["Regular timestamp", "0 timestamp defaults to FITEPOCH", "Null timestamp defaults to FITEPOCH"], +) +def test_convert_datetime(given_timestamp, expected_datetime): + '''Tests converting a FIT timestamp to a python utc datetime''' + expected_datetime = expected_datetime.replace(tzinfo=timezone.utc) + + actual_datetime = util.convert_timestamp_to_datetime(given_timestamp) + assert str(actual_datetime) == str(expected_datetime) diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/LICENSE new file mode 100644 index 00000000..5010e307 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/LICENSE @@ -0,0 +1,27 @@ +The MIT License + +Copyright 2013-2019 William Pearson +Copyright 2015-2016 Julien Enselme +Copyright 2016 Google Inc. +Copyright 2017 Samuel Vasko +Copyright 2017 Nate Prewitt +Copyright 2017 Jack Evans +Copyright 2019 Filippo Broggini + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/METADATA new file mode 100644 index 00000000..6f2635ce --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/METADATA @@ -0,0 +1,255 @@ +Metadata-Version: 2.1 +Name: toml +Version: 0.10.2 +Summary: Python Library for Tom's Obvious, Minimal Language +Home-page: https://github.com/uiri/toml +Author: William Pearson +Author-email: uiri@xqz.ca +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.* + +**** +TOML +**** + +.. image:: https://img.shields.io/pypi/v/toml + :target: https://pypi.org/project/toml/ + +.. image:: https://travis-ci.org/uiri/toml.svg?branch=master + :target: https://travis-ci.org/uiri/toml + +.. image:: https://img.shields.io/pypi/pyversions/toml.svg + :target: https://pypi.org/project/toml/ + + +A Python library for parsing and creating `TOML <https://en.wikipedia.org/wiki/TOML>`_. + +The module passes `the TOML test suite <https://github.com/BurntSushi/toml-test>`_. + +See also: + +* `The TOML Standard <https://github.com/toml-lang/toml>`_ +* `The currently supported TOML specification <https://github.com/toml-lang/toml/blob/v0.5.0/README.md>`_ + +Installation +============ + +To install the latest release on `PyPI <https://pypi.org/project/toml/>`_, +simply run: + +:: + + pip install toml + +Or to install the latest development version, run: + +:: + + git clone https://github.com/uiri/toml.git + cd toml + python setup.py install + +Quick Tutorial +============== + +*toml.loads* takes in a string containing standard TOML-formatted data and +returns a dictionary containing the parsed data. + +.. code:: pycon + + >>> import toml + >>> toml_string = """ + ... # This is a TOML document. + ... + ... title = "TOML Example" + ... + ... [owner] + ... name = "Tom Preston-Werner" + ... dob = 1979-05-27T07:32:00-08:00 # First class dates + ... + ... [database] + ... server = "192.168.1.1" + ... ports = [ 8001, 8001, 8002 ] + ... connection_max = 5000 + ... enabled = true + ... + ... [servers] + ... + ... # Indentation (tabs and/or spaces) is allowed but not required + ... [servers.alpha] + ... ip = "10.0.0.1" + ... dc = "eqdc10" + ... + ... [servers.beta] + ... ip = "10.0.0.2" + ... dc = "eqdc10" + ... + ... [clients] + ... data = [ ["gamma", "delta"], [1, 2] ] + ... + ... # Line breaks are OK when inside arrays + ... hosts = [ + ... "alpha", + ... "omega" + ... ] + ... """ + >>> parsed_toml = toml.loads(toml_string) + + +*toml.dumps* takes a dictionary and returns a string containing the +corresponding TOML-formatted data. + +.. code:: pycon + + >>> new_toml_string = toml.dumps(parsed_toml) + >>> print(new_toml_string) + title = "TOML Example" + [owner] + name = "Tom Preston-Werner" + dob = 1979-05-27T07:32:00Z + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002,] + connection_max = 5000 + enabled = true + [clients] + data = [ [ "gamma", "delta",], [ 1, 2,],] + hosts = [ "alpha", "omega",] + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +*toml.dump* takes a dictionary and a file descriptor and returns a string containing the +corresponding TOML-formatted data. + +.. code:: pycon + + >>> with open('new_toml_file.toml', 'w') as f: + ... new_toml_string = toml.dump(parsed_toml, f) + >>> print(new_toml_string) + title = "TOML Example" + [owner] + name = "Tom Preston-Werner" + dob = 1979-05-27T07:32:00Z + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002,] + connection_max = 5000 + enabled = true + [clients] + data = [ [ "gamma", "delta",], [ 1, 2,],] + hosts = [ "alpha", "omega",] + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +For more functions, view the API Reference below. + +Note +---- + +For Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data. + +.. code:: pycon + + >>> import toml + >>> import numpy as np + >>> a = np.arange(0, 10, dtype=np.double) + >>> output = {'a': a} + >>> toml.dumps(output) + 'a = [ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0",]\n' + >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder()) + 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\n' + +API Reference +============= + +``toml.load(f, _dict=dict)`` + Parse a file or a list of files as TOML and return a dictionary. + + :Args: + * ``f``: A path to a file, list of filepaths (to be read into single + object) or a file descriptor + * ``_dict``: The class of the dictionary object to be returned + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When ``f`` is an invalid type or is a list containing + invalid types + * ``TomlDecodeError``: When an error occurs while decoding the file(s) + +``toml.loads(s, _dict=dict)`` + Parse a TOML-formatted string to a dictionary. + + :Args: + * ``s``: The TOML-formatted string to be parsed + * ``_dict``: Specifies the class of the returned toml dictionary + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When a non-string object is passed + * ``TomlDecodeError``: When an error occurs while decoding the + TOML-formatted string + +``toml.dump(o, f, encoder=None)`` + Write a dictionary to a file containing TOML-formatted data + + :Args: + * ``o``: An object to be converted into TOML + * ``f``: A File descriptor where the TOML-formatted output should be stored + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + :Raises: + * ``TypeError``: When anything other than file descriptor is passed + +``toml.dumps(o, encoder=None)`` + Create a TOML-formatted string from an input object + + :Args: + * ``o``: An object to be converted into TOML + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + + +Licensing +========= + +This project is released under the terms of the MIT Open Source License. View +*LICENSE.txt* for more information. + + diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/RECORD new file mode 100644 index 00000000..e761cd99 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/RECORD @@ -0,0 +1,16 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/toml/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/toml/decoder.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/toml/encoder.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/toml/ordered.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/toml/tz.cpython-39.pyc,, +toml-0.10.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +toml-0.10.2.dist-info/LICENSE,sha256=LZKUgj32yJNXyL5JJ_znk2HWVh5e51MtWSbmOTmqpTY,1252 +toml-0.10.2.dist-info/METADATA,sha256=n_YkspvEihd_QXLIZZ50WVSFz3rZ_k7jQP-OU1WUpWY,7142 +toml-0.10.2.dist-info/RECORD,, +toml-0.10.2.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 +toml-0.10.2.dist-info/top_level.txt,sha256=2BO8ZRNnvJWgXyiQv66LBb_v87qBzcoUtEBefA75Ouk,5 +toml/__init__.py,sha256=Au3kqCwKD0cjbf4yJGOpUFwpsY0WHsC1ZRGvWgIKmpc,723 +toml/decoder.py,sha256=hSGTLf-2WBDZ_ddoCHWFy6N647XyMSh1o3rN2o4dEFg,38942 +toml/encoder.py,sha256=XjBc8ayvvlsLyd_qDA4tMWDNmMFRS4DpwtuDSWBq7zo,9940 +toml/ordered.py,sha256=mz03lZmV0bmc9lsYRIUOuj7Dsu5Ptwq-UtGVq5FdVZ4,354 +toml/tz.py,sha256=-5vg8wkg_atnVi2TnEveexIVE7T_FxBVr_-2WVfO1oA,701 diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/WHEEL new file mode 100644 index 00000000..6d38aa06 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.35.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/top_level.txt new file mode 100644 index 00000000..bd79a658 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml-0.10.2.dist-info/top_level.txt @@ -0,0 +1 @@ +toml diff --git a/dbdpy-env/lib/python3.9/site-packages/toml/__init__.py b/dbdpy-env/lib/python3.9/site-packages/toml/__init__.py new file mode 100644 index 00000000..7719ac23 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml/__init__.py @@ -0,0 +1,25 @@ +"""Python module which parses and emits TOML. + +Released under the MIT license. +""" + +from toml import encoder +from toml import decoder + +__version__ = "0.10.2" +_spec_ = "0.5.0" + +load = decoder.load +loads = decoder.loads +TomlDecoder = decoder.TomlDecoder +TomlDecodeError = decoder.TomlDecodeError +TomlPreserveCommentDecoder = decoder.TomlPreserveCommentDecoder + +dump = encoder.dump +dumps = encoder.dumps +TomlEncoder = encoder.TomlEncoder +TomlArraySeparatorEncoder = encoder.TomlArraySeparatorEncoder +TomlPreserveInlineDictEncoder = encoder.TomlPreserveInlineDictEncoder +TomlNumpyEncoder = encoder.TomlNumpyEncoder +TomlPreserveCommentEncoder = encoder.TomlPreserveCommentEncoder +TomlPathlibEncoder = encoder.TomlPathlibEncoder diff --git a/dbdpy-env/lib/python3.9/site-packages/toml/decoder.py b/dbdpy-env/lib/python3.9/site-packages/toml/decoder.py new file mode 100644 index 00000000..bf400e97 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml/decoder.py @@ -0,0 +1,1057 @@ +import datetime +import io +from os import linesep +import re +import sys + +from toml.tz import TomlTz + +if sys.version_info < (3,): + _range = xrange # noqa: F821 +else: + unicode = str + _range = range + basestring = str + unichr = chr + + +def _detect_pathlib_path(p): + if (3, 4) <= sys.version_info: + import pathlib + if isinstance(p, pathlib.PurePath): + return True + return False + + +def _ispath(p): + if isinstance(p, (bytes, basestring)): + return True + return _detect_pathlib_path(p) + + +def _getpath(p): + if (3, 6) <= sys.version_info: + import os + return os.fspath(p) + if _detect_pathlib_path(p): + return str(p) + return p + + +try: + FNFError = FileNotFoundError +except NameError: + FNFError = IOError + + +TIME_RE = re.compile(r"([0-9]{2}):([0-9]{2}):([0-9]{2})(\.([0-9]{3,6}))?") + + +class TomlDecodeError(ValueError): + """Base toml Exception / Error.""" + + def __init__(self, msg, doc, pos): + lineno = doc.count('\n', 0, pos) + 1 + colno = pos - doc.rfind('\n', 0, pos) + emsg = '{} (line {} column {} char {})'.format(msg, lineno, colno, pos) + ValueError.__init__(self, emsg) + self.msg = msg + self.doc = doc + self.pos = pos + self.lineno = lineno + self.colno = colno + + +# Matches a TOML number, which allows underscores for readability +_number_with_underscores = re.compile('([0-9])(_([0-9]))*') + + +class CommentValue(object): + def __init__(self, val, comment, beginline, _dict): + self.val = val + separator = "\n" if beginline else " " + self.comment = separator + comment + self._dict = _dict + + def __getitem__(self, key): + return self.val[key] + + def __setitem__(self, key, value): + self.val[key] = value + + def dump(self, dump_value_func): + retstr = dump_value_func(self.val) + if isinstance(self.val, self._dict): + return self.comment + "\n" + unicode(retstr) + else: + return unicode(retstr) + self.comment + + +def _strictly_valid_num(n): + n = n.strip() + if not n: + return False + if n[0] == '_': + return False + if n[-1] == '_': + return False + if "_." in n or "._" in n: + return False + if len(n) == 1: + return True + if n[0] == '0' and n[1] not in ['.', 'o', 'b', 'x']: + return False + if n[0] == '+' or n[0] == '-': + n = n[1:] + if len(n) > 1 and n[0] == '0' and n[1] != '.': + return False + if '__' in n: + return False + return True + + +def load(f, _dict=dict, decoder=None): + """Parses named file or files as toml and returns a dictionary + + Args: + f: Path to the file to open, array of files to read into single dict + or a file descriptor + _dict: (optional) Specifies the class of the returned toml dictionary + decoder: The decoder to use + + Returns: + Parsed toml file represented as a dictionary + + Raises: + TypeError -- When f is invalid type + TomlDecodeError: Error while decoding toml + IOError / FileNotFoundError -- When an array with no valid (existing) + (Python 2 / Python 3) file paths is passed + """ + + if _ispath(f): + with io.open(_getpath(f), encoding='utf-8') as ffile: + return loads(ffile.read(), _dict, decoder) + elif isinstance(f, list): + from os import path as op + from warnings import warn + if not [path for path in f if op.exists(path)]: + error_msg = "Load expects a list to contain filenames only." + error_msg += linesep + error_msg += ("The list needs to contain the path of at least one " + "existing file.") + raise FNFError(error_msg) + if decoder is None: + decoder = TomlDecoder(_dict) + d = decoder.get_empty_table() + for l in f: # noqa: E741 + if op.exists(l): + d.update(load(l, _dict, decoder)) + else: + warn("Non-existent filename in list with at least one valid " + "filename") + return d + else: + try: + return loads(f.read(), _dict, decoder) + except AttributeError: + raise TypeError("You can only load a file descriptor, filename or " + "list") + + +_groupname_re = re.compile(r'^[A-Za-z0-9_-]+$') + + +def loads(s, _dict=dict, decoder=None): + """Parses string as toml + + Args: + s: String to be parsed + _dict: (optional) Specifies the class of the returned toml dictionary + + Returns: + Parsed toml file represented as a dictionary + + Raises: + TypeError: When a non-string is passed + TomlDecodeError: Error while decoding toml + """ + + implicitgroups = [] + if decoder is None: + decoder = TomlDecoder(_dict) + retval = decoder.get_empty_table() + currentlevel = retval + if not isinstance(s, basestring): + raise TypeError("Expecting something like a string") + + if not isinstance(s, unicode): + s = s.decode('utf8') + + original = s + sl = list(s) + openarr = 0 + openstring = False + openstrchar = "" + multilinestr = False + arrayoftables = False + beginline = True + keygroup = False + dottedkey = False + keyname = 0 + key = '' + prev_key = '' + line_no = 1 + + for i, item in enumerate(sl): + if item == '\r' and sl[i + 1] == '\n': + sl[i] = ' ' + continue + if keyname: + key += item + if item == '\n': + raise TomlDecodeError("Key name found without value." + " Reached end of line.", original, i) + if openstring: + if item == openstrchar: + oddbackslash = False + k = 1 + while i >= k and sl[i - k] == '\\': + oddbackslash = not oddbackslash + k += 1 + if not oddbackslash: + keyname = 2 + openstring = False + openstrchar = "" + continue + elif keyname == 1: + if item.isspace(): + keyname = 2 + continue + elif item == '.': + dottedkey = True + continue + elif item.isalnum() or item == '_' or item == '-': + continue + elif (dottedkey and sl[i - 1] == '.' and + (item == '"' or item == "'")): + openstring = True + openstrchar = item + continue + elif keyname == 2: + if item.isspace(): + if dottedkey: + nextitem = sl[i + 1] + if not nextitem.isspace() and nextitem != '.': + keyname = 1 + continue + if item == '.': + dottedkey = True + nextitem = sl[i + 1] + if not nextitem.isspace() and nextitem != '.': + keyname = 1 + continue + if item == '=': + keyname = 0 + prev_key = key[:-1].rstrip() + key = '' + dottedkey = False + else: + raise TomlDecodeError("Found invalid character in key name: '" + + item + "'. Try quoting the key name.", + original, i) + if item == "'" and openstrchar != '"': + k = 1 + try: + while sl[i - k] == "'": + k += 1 + if k == 3: + break + except IndexError: + pass + if k == 3: + multilinestr = not multilinestr + openstring = multilinestr + else: + openstring = not openstring + if openstring: + openstrchar = "'" + else: + openstrchar = "" + if item == '"' and openstrchar != "'": + oddbackslash = False + k = 1 + tripquote = False + try: + while sl[i - k] == '"': + k += 1 + if k == 3: + tripquote = True + break + if k == 1 or (k == 3 and tripquote): + while sl[i - k] == '\\': + oddbackslash = not oddbackslash + k += 1 + except IndexError: + pass + if not oddbackslash: + if tripquote: + multilinestr = not multilinestr + openstring = multilinestr + else: + openstring = not openstring + if openstring: + openstrchar = '"' + else: + openstrchar = "" + if item == '#' and (not openstring and not keygroup and + not arrayoftables): + j = i + comment = "" + try: + while sl[j] != '\n': + comment += s[j] + sl[j] = ' ' + j += 1 + except IndexError: + break + if not openarr: + decoder.preserve_comment(line_no, prev_key, comment, beginline) + if item == '[' and (not openstring and not keygroup and + not arrayoftables): + if beginline: + if len(sl) > i + 1 and sl[i + 1] == '[': + arrayoftables = True + else: + keygroup = True + else: + openarr += 1 + if item == ']' and not openstring: + if keygroup: + keygroup = False + elif arrayoftables: + if sl[i - 1] == ']': + arrayoftables = False + else: + openarr -= 1 + if item == '\n': + if openstring or multilinestr: + if not multilinestr: + raise TomlDecodeError("Unbalanced quotes", original, i) + if ((sl[i - 1] == "'" or sl[i - 1] == '"') and ( + sl[i - 2] == sl[i - 1])): + sl[i] = sl[i - 1] + if sl[i - 3] == sl[i - 1]: + sl[i - 3] = ' ' + elif openarr: + sl[i] = ' ' + else: + beginline = True + line_no += 1 + elif beginline and sl[i] != ' ' and sl[i] != '\t': + beginline = False + if not keygroup and not arrayoftables: + if sl[i] == '=': + raise TomlDecodeError("Found empty keyname. ", original, i) + keyname = 1 + key += item + if keyname: + raise TomlDecodeError("Key name found without value." + " Reached end of file.", original, len(s)) + if openstring: # reached EOF and have an unterminated string + raise TomlDecodeError("Unterminated string found." + " Reached end of file.", original, len(s)) + s = ''.join(sl) + s = s.split('\n') + multikey = None + multilinestr = "" + multibackslash = False + pos = 0 + for idx, line in enumerate(s): + if idx > 0: + pos += len(s[idx - 1]) + 1 + + decoder.embed_comments(idx, currentlevel) + + if not multilinestr or multibackslash or '\n' not in multilinestr: + line = line.strip() + if line == "" and (not multikey or multibackslash): + continue + if multikey: + if multibackslash: + multilinestr += line + else: + multilinestr += line + multibackslash = False + closed = False + if multilinestr[0] == '[': + closed = line[-1] == ']' + elif len(line) > 2: + closed = (line[-1] == multilinestr[0] and + line[-2] == multilinestr[0] and + line[-3] == multilinestr[0]) + if closed: + try: + value, vtype = decoder.load_value(multilinestr) + except ValueError as err: + raise TomlDecodeError(str(err), original, pos) + currentlevel[multikey] = value + multikey = None + multilinestr = "" + else: + k = len(multilinestr) - 1 + while k > -1 and multilinestr[k] == '\\': + multibackslash = not multibackslash + k -= 1 + if multibackslash: + multilinestr = multilinestr[:-1] + else: + multilinestr += "\n" + continue + if line[0] == '[': + arrayoftables = False + if len(line) == 1: + raise TomlDecodeError("Opening key group bracket on line by " + "itself.", original, pos) + if line[1] == '[': + arrayoftables = True + line = line[2:] + splitstr = ']]' + else: + line = line[1:] + splitstr = ']' + i = 1 + quotesplits = decoder._get_split_on_quotes(line) + quoted = False + for quotesplit in quotesplits: + if not quoted and splitstr in quotesplit: + break + i += quotesplit.count(splitstr) + quoted = not quoted + line = line.split(splitstr, i) + if len(line) < i + 1 or line[-1].strip() != "": + raise TomlDecodeError("Key group not on a line by itself.", + original, pos) + groups = splitstr.join(line[:-1]).split('.') + i = 0 + while i < len(groups): + groups[i] = groups[i].strip() + if len(groups[i]) > 0 and (groups[i][0] == '"' or + groups[i][0] == "'"): + groupstr = groups[i] + j = i + 1 + while ((not groupstr[0] == groupstr[-1]) or + len(groupstr) == 1): + j += 1 + if j > len(groups) + 2: + raise TomlDecodeError("Invalid group name '" + + groupstr + "' Something " + + "went wrong.", original, pos) + groupstr = '.'.join(groups[i:j]).strip() + groups[i] = groupstr[1:-1] + groups[i + 1:j] = [] + else: + if not _groupname_re.match(groups[i]): + raise TomlDecodeError("Invalid group name '" + + groups[i] + "'. Try quoting it.", + original, pos) + i += 1 + currentlevel = retval + for i in _range(len(groups)): + group = groups[i] + if group == "": + raise TomlDecodeError("Can't have a keygroup with an empty " + "name", original, pos) + try: + currentlevel[group] + if i == len(groups) - 1: + if group in implicitgroups: + implicitgroups.remove(group) + if arrayoftables: + raise TomlDecodeError("An implicitly defined " + "table can't be an array", + original, pos) + elif arrayoftables: + currentlevel[group].append(decoder.get_empty_table() + ) + else: + raise TomlDecodeError("What? " + group + + " already exists?" + + str(currentlevel), + original, pos) + except TypeError: + currentlevel = currentlevel[-1] + if group not in currentlevel: + currentlevel[group] = decoder.get_empty_table() + if i == len(groups) - 1 and arrayoftables: + currentlevel[group] = [decoder.get_empty_table()] + except KeyError: + if i != len(groups) - 1: + implicitgroups.append(group) + currentlevel[group] = decoder.get_empty_table() + if i == len(groups) - 1 and arrayoftables: + currentlevel[group] = [decoder.get_empty_table()] + currentlevel = currentlevel[group] + if arrayoftables: + try: + currentlevel = currentlevel[-1] + except KeyError: + pass + elif line[0] == "{": + if line[-1] != "}": + raise TomlDecodeError("Line breaks are not allowed in inline" + "objects", original, pos) + try: + decoder.load_inline_object(line, currentlevel, multikey, + multibackslash) + except ValueError as err: + raise TomlDecodeError(str(err), original, pos) + elif "=" in line: + try: + ret = decoder.load_line(line, currentlevel, multikey, + multibackslash) + except ValueError as err: + raise TomlDecodeError(str(err), original, pos) + if ret is not None: + multikey, multilinestr, multibackslash = ret + return retval + + +def _load_date(val): + microsecond = 0 + tz = None + try: + if len(val) > 19: + if val[19] == '.': + if val[-1].upper() == 'Z': + subsecondval = val[20:-1] + tzval = "Z" + else: + subsecondvalandtz = val[20:] + if '+' in subsecondvalandtz: + splitpoint = subsecondvalandtz.index('+') + subsecondval = subsecondvalandtz[:splitpoint] + tzval = subsecondvalandtz[splitpoint:] + elif '-' in subsecondvalandtz: + splitpoint = subsecondvalandtz.index('-') + subsecondval = subsecondvalandtz[:splitpoint] + tzval = subsecondvalandtz[splitpoint:] + else: + tzval = None + subsecondval = subsecondvalandtz + if tzval is not None: + tz = TomlTz(tzval) + microsecond = int(int(subsecondval) * + (10 ** (6 - len(subsecondval)))) + else: + tz = TomlTz(val[19:]) + except ValueError: + tz = None + if "-" not in val[1:]: + return None + try: + if len(val) == 10: + d = datetime.date( + int(val[:4]), int(val[5:7]), + int(val[8:10])) + else: + d = datetime.datetime( + int(val[:4]), int(val[5:7]), + int(val[8:10]), int(val[11:13]), + int(val[14:16]), int(val[17:19]), microsecond, tz) + except ValueError: + return None + return d + + +def _load_unicode_escapes(v, hexbytes, prefix): + skip = False + i = len(v) - 1 + while i > -1 and v[i] == '\\': + skip = not skip + i -= 1 + for hx in hexbytes: + if skip: + skip = False + i = len(hx) - 1 + while i > -1 and hx[i] == '\\': + skip = not skip + i -= 1 + v += prefix + v += hx + continue + hxb = "" + i = 0 + hxblen = 4 + if prefix == "\\U": + hxblen = 8 + hxb = ''.join(hx[i:i + hxblen]).lower() + if hxb.strip('0123456789abcdef'): + raise ValueError("Invalid escape sequence: " + hxb) + if hxb[0] == "d" and hxb[1].strip('01234567'): + raise ValueError("Invalid escape sequence: " + hxb + + ". Only scalar unicode points are allowed.") + v += unichr(int(hxb, 16)) + v += unicode(hx[len(hxb):]) + return v + + +# Unescape TOML string values. + +# content after the \ +_escapes = ['0', 'b', 'f', 'n', 'r', 't', '"'] +# What it should be replaced by +_escapedchars = ['\0', '\b', '\f', '\n', '\r', '\t', '\"'] +# Used for substitution +_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) + + +def _unescape(v): + """Unescape characters in a TOML string.""" + i = 0 + backslash = False + while i < len(v): + if backslash: + backslash = False + if v[i] in _escapes: + v = v[:i - 1] + _escape_to_escapedchars[v[i]] + v[i + 1:] + elif v[i] == '\\': + v = v[:i - 1] + v[i:] + elif v[i] == 'u' or v[i] == 'U': + i += 1 + else: + raise ValueError("Reserved escape sequence used") + continue + elif v[i] == '\\': + backslash = True + i += 1 + return v + + +class InlineTableDict(object): + """Sentinel subclass of dict for inline tables.""" + + +class TomlDecoder(object): + + def __init__(self, _dict=dict): + self._dict = _dict + + def get_empty_table(self): + return self._dict() + + def get_empty_inline_table(self): + class DynamicInlineTableDict(self._dict, InlineTableDict): + """Concrete sentinel subclass for inline tables. + It is a subclass of _dict which is passed in dynamically at load + time + + It is also a subclass of InlineTableDict + """ + + return DynamicInlineTableDict() + + def load_inline_object(self, line, currentlevel, multikey=False, + multibackslash=False): + candidate_groups = line[1:-1].split(",") + groups = [] + if len(candidate_groups) == 1 and not candidate_groups[0].strip(): + candidate_groups.pop() + while len(candidate_groups) > 0: + candidate_group = candidate_groups.pop(0) + try: + _, value = candidate_group.split('=', 1) + except ValueError: + raise ValueError("Invalid inline table encountered") + value = value.strip() + if ((value[0] == value[-1] and value[0] in ('"', "'")) or ( + value[0] in '-0123456789' or + value in ('true', 'false') or + (value[0] == "[" and value[-1] == "]") or + (value[0] == '{' and value[-1] == '}'))): + groups.append(candidate_group) + elif len(candidate_groups) > 0: + candidate_groups[0] = (candidate_group + "," + + candidate_groups[0]) + else: + raise ValueError("Invalid inline table value encountered") + for group in groups: + status = self.load_line(group, currentlevel, multikey, + multibackslash) + if status is not None: + break + + def _get_split_on_quotes(self, line): + doublequotesplits = line.split('"') + quoted = False + quotesplits = [] + if len(doublequotesplits) > 1 and "'" in doublequotesplits[0]: + singlequotesplits = doublequotesplits[0].split("'") + doublequotesplits = doublequotesplits[1:] + while len(singlequotesplits) % 2 == 0 and len(doublequotesplits): + singlequotesplits[-1] += '"' + doublequotesplits[0] + doublequotesplits = doublequotesplits[1:] + if "'" in singlequotesplits[-1]: + singlequotesplits = (singlequotesplits[:-1] + + singlequotesplits[-1].split("'")) + quotesplits += singlequotesplits + for doublequotesplit in doublequotesplits: + if quoted: + quotesplits.append(doublequotesplit) + else: + quotesplits += doublequotesplit.split("'") + quoted = not quoted + return quotesplits + + def load_line(self, line, currentlevel, multikey, multibackslash): + i = 1 + quotesplits = self._get_split_on_quotes(line) + quoted = False + for quotesplit in quotesplits: + if not quoted and '=' in quotesplit: + break + i += quotesplit.count('=') + quoted = not quoted + pair = line.split('=', i) + strictly_valid = _strictly_valid_num(pair[-1]) + if _number_with_underscores.match(pair[-1]): + pair[-1] = pair[-1].replace('_', '') + while len(pair[-1]) and (pair[-1][0] != ' ' and pair[-1][0] != '\t' and + pair[-1][0] != "'" and pair[-1][0] != '"' and + pair[-1][0] != '[' and pair[-1][0] != '{' and + pair[-1].strip() != 'true' and + pair[-1].strip() != 'false'): + try: + float(pair[-1]) + break + except ValueError: + pass + if _load_date(pair[-1]) is not None: + break + if TIME_RE.match(pair[-1]): + break + i += 1 + prev_val = pair[-1] + pair = line.split('=', i) + if prev_val == pair[-1]: + raise ValueError("Invalid date or number") + if strictly_valid: + strictly_valid = _strictly_valid_num(pair[-1]) + pair = ['='.join(pair[:-1]).strip(), pair[-1].strip()] + if '.' in pair[0]: + if '"' in pair[0] or "'" in pair[0]: + quotesplits = self._get_split_on_quotes(pair[0]) + quoted = False + levels = [] + for quotesplit in quotesplits: + if quoted: + levels.append(quotesplit) + else: + levels += [level.strip() for level in + quotesplit.split('.')] + quoted = not quoted + else: + levels = pair[0].split('.') + while levels[-1] == "": + levels = levels[:-1] + for level in levels[:-1]: + if level == "": + continue + if level not in currentlevel: + currentlevel[level] = self.get_empty_table() + currentlevel = currentlevel[level] + pair[0] = levels[-1].strip() + elif (pair[0][0] == '"' or pair[0][0] == "'") and \ + (pair[0][-1] == pair[0][0]): + pair[0] = _unescape(pair[0][1:-1]) + k, koffset = self._load_line_multiline_str(pair[1]) + if k > -1: + while k > -1 and pair[1][k + koffset] == '\\': + multibackslash = not multibackslash + k -= 1 + if multibackslash: + multilinestr = pair[1][:-1] + else: + multilinestr = pair[1] + "\n" + multikey = pair[0] + else: + value, vtype = self.load_value(pair[1], strictly_valid) + try: + currentlevel[pair[0]] + raise ValueError("Duplicate keys!") + except TypeError: + raise ValueError("Duplicate keys!") + except KeyError: + if multikey: + return multikey, multilinestr, multibackslash + else: + currentlevel[pair[0]] = value + + def _load_line_multiline_str(self, p): + poffset = 0 + if len(p) < 3: + return -1, poffset + if p[0] == '[' and (p.strip()[-1] != ']' and + self._load_array_isstrarray(p)): + newp = p[1:].strip().split(',') + while len(newp) > 1 and newp[-1][0] != '"' and newp[-1][0] != "'": + newp = newp[:-2] + [newp[-2] + ',' + newp[-1]] + newp = newp[-1] + poffset = len(p) - len(newp) + p = newp + if p[0] != '"' and p[0] != "'": + return -1, poffset + if p[1] != p[0] or p[2] != p[0]: + return -1, poffset + if len(p) > 5 and p[-1] == p[0] and p[-2] == p[0] and p[-3] == p[0]: + return -1, poffset + return len(p) - 1, poffset + + def load_value(self, v, strictly_valid=True): + if not v: + raise ValueError("Empty value is invalid") + if v == 'true': + return (True, "bool") + elif v.lower() == 'true': + raise ValueError("Only all lowercase booleans allowed") + elif v == 'false': + return (False, "bool") + elif v.lower() == 'false': + raise ValueError("Only all lowercase booleans allowed") + elif v[0] == '"' or v[0] == "'": + quotechar = v[0] + testv = v[1:].split(quotechar) + triplequote = False + triplequotecount = 0 + if len(testv) > 1 and testv[0] == '' and testv[1] == '': + testv = testv[2:] + triplequote = True + closed = False + for tv in testv: + if tv == '': + if triplequote: + triplequotecount += 1 + else: + closed = True + else: + oddbackslash = False + try: + i = -1 + j = tv[i] + while j == '\\': + oddbackslash = not oddbackslash + i -= 1 + j = tv[i] + except IndexError: + pass + if not oddbackslash: + if closed: + raise ValueError("Found tokens after a closed " + + "string. Invalid TOML.") + else: + if not triplequote or triplequotecount > 1: + closed = True + else: + triplequotecount = 0 + if quotechar == '"': + escapeseqs = v.split('\\')[1:] + backslash = False + for i in escapeseqs: + if i == '': + backslash = not backslash + else: + if i[0] not in _escapes and (i[0] != 'u' and + i[0] != 'U' and + not backslash): + raise ValueError("Reserved escape sequence used") + if backslash: + backslash = False + for prefix in ["\\u", "\\U"]: + if prefix in v: + hexbytes = v.split(prefix) + v = _load_unicode_escapes(hexbytes[0], hexbytes[1:], + prefix) + v = _unescape(v) + if len(v) > 1 and v[1] == quotechar and (len(v) < 3 or + v[1] == v[2]): + v = v[2:-2] + return (v[1:-1], "str") + elif v[0] == '[': + return (self.load_array(v), "array") + elif v[0] == '{': + inline_object = self.get_empty_inline_table() + self.load_inline_object(v, inline_object) + return (inline_object, "inline_object") + elif TIME_RE.match(v): + h, m, s, _, ms = TIME_RE.match(v).groups() + time = datetime.time(int(h), int(m), int(s), int(ms) if ms else 0) + return (time, "time") + else: + parsed_date = _load_date(v) + if parsed_date is not None: + return (parsed_date, "date") + if not strictly_valid: + raise ValueError("Weirdness with leading zeroes or " + "underscores in your number.") + itype = "int" + neg = False + if v[0] == '-': + neg = True + v = v[1:] + elif v[0] == '+': + v = v[1:] + v = v.replace('_', '') + lowerv = v.lower() + if '.' in v or ('x' not in v and ('e' in v or 'E' in v)): + if '.' in v and v.split('.', 1)[1] == '': + raise ValueError("This float is missing digits after " + "the point") + if v[0] not in '0123456789': + raise ValueError("This float doesn't have a leading " + "digit") + v = float(v) + itype = "float" + elif len(lowerv) == 3 and (lowerv == 'inf' or lowerv == 'nan'): + v = float(v) + itype = "float" + if itype == "int": + v = int(v, 0) + if neg: + return (0 - v, itype) + return (v, itype) + + def bounded_string(self, s): + if len(s) == 0: + return True + if s[-1] != s[0]: + return False + i = -2 + backslash = False + while len(s) + i > 0: + if s[i] == "\\": + backslash = not backslash + i -= 1 + else: + break + return not backslash + + def _load_array_isstrarray(self, a): + a = a[1:-1].strip() + if a != '' and (a[0] == '"' or a[0] == "'"): + return True + return False + + def load_array(self, a): + atype = None + retval = [] + a = a.strip() + if '[' not in a[1:-1] or "" != a[1:-1].split('[')[0].strip(): + strarray = self._load_array_isstrarray(a) + if not a[1:-1].strip().startswith('{'): + a = a[1:-1].split(',') + else: + # a is an inline object, we must find the matching parenthesis + # to define groups + new_a = [] + start_group_index = 1 + end_group_index = 2 + open_bracket_count = 1 if a[start_group_index] == '{' else 0 + in_str = False + while end_group_index < len(a[1:]): + if a[end_group_index] == '"' or a[end_group_index] == "'": + if in_str: + backslash_index = end_group_index - 1 + while (backslash_index > -1 and + a[backslash_index] == '\\'): + in_str = not in_str + backslash_index -= 1 + in_str = not in_str + if not in_str and a[end_group_index] == '{': + open_bracket_count += 1 + if in_str or a[end_group_index] != '}': + end_group_index += 1 + continue + elif a[end_group_index] == '}' and open_bracket_count > 1: + open_bracket_count -= 1 + end_group_index += 1 + continue + + # Increase end_group_index by 1 to get the closing bracket + end_group_index += 1 + + new_a.append(a[start_group_index:end_group_index]) + + # The next start index is at least after the closing + # bracket, a closing bracket can be followed by a comma + # since we are in an array. + start_group_index = end_group_index + 1 + while (start_group_index < len(a[1:]) and + a[start_group_index] != '{'): + start_group_index += 1 + end_group_index = start_group_index + 1 + a = new_a + b = 0 + if strarray: + while b < len(a) - 1: + ab = a[b].strip() + while (not self.bounded_string(ab) or + (len(ab) > 2 and + ab[0] == ab[1] == ab[2] and + ab[-2] != ab[0] and + ab[-3] != ab[0])): + a[b] = a[b] + ',' + a[b + 1] + ab = a[b].strip() + if b < len(a) - 2: + a = a[:b + 1] + a[b + 2:] + else: + a = a[:b + 1] + b += 1 + else: + al = list(a[1:-1]) + a = [] + openarr = 0 + j = 0 + for i in _range(len(al)): + if al[i] == '[': + openarr += 1 + elif al[i] == ']': + openarr -= 1 + elif al[i] == ',' and not openarr: + a.append(''.join(al[j:i])) + j = i + 1 + a.append(''.join(al[j:])) + for i in _range(len(a)): + a[i] = a[i].strip() + if a[i] != '': + nval, ntype = self.load_value(a[i]) + if atype: + if ntype != atype: + raise ValueError("Not a homogeneous array") + else: + atype = ntype + retval.append(nval) + return retval + + def preserve_comment(self, line_no, key, comment, beginline): + pass + + def embed_comments(self, idx, currentlevel): + pass + + +class TomlPreserveCommentDecoder(TomlDecoder): + + def __init__(self, _dict=dict): + self.saved_comments = {} + super(TomlPreserveCommentDecoder, self).__init__(_dict) + + def preserve_comment(self, line_no, key, comment, beginline): + self.saved_comments[line_no] = (key, comment, beginline) + + def embed_comments(self, idx, currentlevel): + if idx not in self.saved_comments: + return + + key, comment, beginline = self.saved_comments[idx] + currentlevel[key] = CommentValue(currentlevel[key], comment, beginline, + self._dict) diff --git a/dbdpy-env/lib/python3.9/site-packages/toml/encoder.py b/dbdpy-env/lib/python3.9/site-packages/toml/encoder.py new file mode 100644 index 00000000..bf17a72b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml/encoder.py @@ -0,0 +1,304 @@ +import datetime +import re +import sys +from decimal import Decimal + +from toml.decoder import InlineTableDict + +if sys.version_info >= (3,): + unicode = str + + +def dump(o, f, encoder=None): + """Writes out dict as toml to a file + + Args: + o: Object to dump into toml + f: File descriptor where the toml should be stored + encoder: The ``TomlEncoder`` to use for constructing the output string + + Returns: + String containing the toml corresponding to dictionary + + Raises: + TypeError: When anything other than file descriptor is passed + """ + + if not f.write: + raise TypeError("You can only dump an object to a file descriptor") + d = dumps(o, encoder=encoder) + f.write(d) + return d + + +def dumps(o, encoder=None): + """Stringifies input dict as toml + + Args: + o: Object to dump into toml + encoder: The ``TomlEncoder`` to use for constructing the output string + + Returns: + String containing the toml corresponding to dict + + Examples: + ```python + >>> import toml + >>> output = { + ... 'a': "I'm a string", + ... 'b': ["I'm", "a", "list"], + ... 'c': 2400 + ... } + >>> toml.dumps(output) + 'a = "I\'m a string"\nb = [ "I\'m", "a", "list",]\nc = 2400\n' + ``` + """ + + retval = "" + if encoder is None: + encoder = TomlEncoder(o.__class__) + addtoretval, sections = encoder.dump_sections(o, "") + retval += addtoretval + outer_objs = [id(o)] + while sections: + section_ids = [id(section) for section in sections.values()] + for outer_obj in outer_objs: + if outer_obj in section_ids: + raise ValueError("Circular reference detected") + outer_objs += section_ids + newsections = encoder.get_empty_table() + for section in sections: + addtoretval, addtosections = encoder.dump_sections( + sections[section], section) + + if addtoretval or (not addtoretval and not addtosections): + if retval and retval[-2:] != "\n\n": + retval += "\n" + retval += "[" + section + "]\n" + if addtoretval: + retval += addtoretval + for s in addtosections: + newsections[section + "." + s] = addtosections[s] + sections = newsections + return retval + + +def _dump_str(v): + if sys.version_info < (3,) and hasattr(v, 'decode') and isinstance(v, str): + v = v.decode('utf-8') + v = "%r" % v + if v[0] == 'u': + v = v[1:] + singlequote = v.startswith("'") + if singlequote or v.startswith('"'): + v = v[1:-1] + if singlequote: + v = v.replace("\\'", "'") + v = v.replace('"', '\\"') + v = v.split("\\x") + while len(v) > 1: + i = -1 + if not v[0]: + v = v[1:] + v[0] = v[0].replace("\\\\", "\\") + # No, I don't know why != works and == breaks + joinx = v[0][i] != "\\" + while v[0][:i] and v[0][i] == "\\": + joinx = not joinx + i -= 1 + if joinx: + joiner = "x" + else: + joiner = "u00" + v = [v[0] + joiner + v[1]] + v[2:] + return unicode('"' + v[0] + '"') + + +def _dump_float(v): + return "{}".format(v).replace("e+0", "e+").replace("e-0", "e-") + + +def _dump_time(v): + utcoffset = v.utcoffset() + if utcoffset is None: + return v.isoformat() + # The TOML norm specifies that it's local time thus we drop the offset + return v.isoformat()[:-6] + + +class TomlEncoder(object): + + def __init__(self, _dict=dict, preserve=False): + self._dict = _dict + self.preserve = preserve + self.dump_funcs = { + str: _dump_str, + unicode: _dump_str, + list: self.dump_list, + bool: lambda v: unicode(v).lower(), + int: lambda v: v, + float: _dump_float, + Decimal: _dump_float, + datetime.datetime: lambda v: v.isoformat().replace('+00:00', 'Z'), + datetime.time: _dump_time, + datetime.date: lambda v: v.isoformat() + } + + def get_empty_table(self): + return self._dict() + + def dump_list(self, v): + retval = "[" + for u in v: + retval += " " + unicode(self.dump_value(u)) + "," + retval += "]" + return retval + + def dump_inline_table(self, section): + """Preserve inline table in its compact syntax instead of expanding + into subsection. + + https://github.com/toml-lang/toml#user-content-inline-table + """ + retval = "" + if isinstance(section, dict): + val_list = [] + for k, v in section.items(): + val = self.dump_inline_table(v) + val_list.append(k + " = " + val) + retval += "{ " + ", ".join(val_list) + " }\n" + return retval + else: + return unicode(self.dump_value(section)) + + def dump_value(self, v): + # Lookup function corresponding to v's type + dump_fn = self.dump_funcs.get(type(v)) + if dump_fn is None and hasattr(v, '__iter__'): + dump_fn = self.dump_funcs[list] + # Evaluate function (if it exists) else return v + return dump_fn(v) if dump_fn is not None else self.dump_funcs[str](v) + + def dump_sections(self, o, sup): + retstr = "" + if sup != "" and sup[-1] != ".": + sup += '.' + retdict = self._dict() + arraystr = "" + for section in o: + section = unicode(section) + qsection = section + if not re.match(r'^[A-Za-z0-9_-]+$', section): + qsection = _dump_str(section) + if not isinstance(o[section], dict): + arrayoftables = False + if isinstance(o[section], list): + for a in o[section]: + if isinstance(a, dict): + arrayoftables = True + if arrayoftables: + for a in o[section]: + arraytabstr = "\n" + arraystr += "[[" + sup + qsection + "]]\n" + s, d = self.dump_sections(a, sup + qsection) + if s: + if s[0] == "[": + arraytabstr += s + else: + arraystr += s + while d: + newd = self._dict() + for dsec in d: + s1, d1 = self.dump_sections(d[dsec], sup + + qsection + "." + + dsec) + if s1: + arraytabstr += ("[" + sup + qsection + + "." + dsec + "]\n") + arraytabstr += s1 + for s1 in d1: + newd[dsec + "." + s1] = d1[s1] + d = newd + arraystr += arraytabstr + else: + if o[section] is not None: + retstr += (qsection + " = " + + unicode(self.dump_value(o[section])) + '\n') + elif self.preserve and isinstance(o[section], InlineTableDict): + retstr += (qsection + " = " + + self.dump_inline_table(o[section])) + else: + retdict[qsection] = o[section] + retstr += arraystr + return (retstr, retdict) + + +class TomlPreserveInlineDictEncoder(TomlEncoder): + + def __init__(self, _dict=dict): + super(TomlPreserveInlineDictEncoder, self).__init__(_dict, True) + + +class TomlArraySeparatorEncoder(TomlEncoder): + + def __init__(self, _dict=dict, preserve=False, separator=","): + super(TomlArraySeparatorEncoder, self).__init__(_dict, preserve) + if separator.strip() == "": + separator = "," + separator + elif separator.strip(' \t\n\r,'): + raise ValueError("Invalid separator for arrays") + self.separator = separator + + def dump_list(self, v): + t = [] + retval = "[" + for u in v: + t.append(self.dump_value(u)) + while t != []: + s = [] + for u in t: + if isinstance(u, list): + for r in u: + s.append(r) + else: + retval += " " + unicode(u) + self.separator + t = s + retval += "]" + return retval + + +class TomlNumpyEncoder(TomlEncoder): + + def __init__(self, _dict=dict, preserve=False): + import numpy as np + super(TomlNumpyEncoder, self).__init__(_dict, preserve) + self.dump_funcs[np.float16] = _dump_float + self.dump_funcs[np.float32] = _dump_float + self.dump_funcs[np.float64] = _dump_float + self.dump_funcs[np.int16] = self._dump_int + self.dump_funcs[np.int32] = self._dump_int + self.dump_funcs[np.int64] = self._dump_int + + def _dump_int(self, v): + return "{}".format(int(v)) + + +class TomlPreserveCommentEncoder(TomlEncoder): + + def __init__(self, _dict=dict, preserve=False): + from toml.decoder import CommentValue + super(TomlPreserveCommentEncoder, self).__init__(_dict, preserve) + self.dump_funcs[CommentValue] = lambda v: v.dump(self.dump_value) + + +class TomlPathlibEncoder(TomlEncoder): + + def _dump_pathlib_path(self, v): + return _dump_str(str(v)) + + def dump_value(self, v): + if (3, 4) <= sys.version_info: + import pathlib + if isinstance(v, pathlib.PurePath): + v = str(v) + return super(TomlPathlibEncoder, self).dump_value(v) diff --git a/dbdpy-env/lib/python3.9/site-packages/toml/ordered.py b/dbdpy-env/lib/python3.9/site-packages/toml/ordered.py new file mode 100644 index 00000000..9c20c41a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml/ordered.py @@ -0,0 +1,15 @@ +from collections import OrderedDict +from toml import TomlEncoder +from toml import TomlDecoder + + +class TomlOrderedDecoder(TomlDecoder): + + def __init__(self): + super(self.__class__, self).__init__(_dict=OrderedDict) + + +class TomlOrderedEncoder(TomlEncoder): + + def __init__(self): + super(self.__class__, self).__init__(_dict=OrderedDict) diff --git a/dbdpy-env/lib/python3.9/site-packages/toml/tz.py b/dbdpy-env/lib/python3.9/site-packages/toml/tz.py new file mode 100644 index 00000000..bf20593a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/toml/tz.py @@ -0,0 +1,24 @@ +from datetime import tzinfo, timedelta + + +class TomlTz(tzinfo): + def __init__(self, toml_offset): + if toml_offset == "Z": + self._raw_offset = "+00:00" + else: + self._raw_offset = toml_offset + self._sign = -1 if self._raw_offset[0] == '-' else 1 + self._hours = int(self._raw_offset[1:3]) + self._minutes = int(self._raw_offset[4:6]) + + def __deepcopy__(self, memo): + return self.__class__(self._raw_offset) + + def tzname(self, dt): + return "UTC" + self._raw_offset + + def utcoffset(self, dt): + return self._sign * timedelta(hours=self._hours, minutes=self._minutes) + + def dst(self, dt): + return timedelta(0) diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/LICENSE b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/LICENSE new file mode 100644 index 00000000..e859590f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Taneli Hukkinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/METADATA new file mode 100644 index 00000000..efd87ecc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/METADATA @@ -0,0 +1,206 @@ +Metadata-Version: 2.1 +Name: tomli +Version: 2.0.1 +Summary: A lil' TOML parser +Keywords: toml +Author-email: Taneli Hukkinen <hukkin@users.noreply.github.com> +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: MacOS +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Typing :: Typed +Project-URL: Changelog, https://github.com/hukkin/tomli/blob/master/CHANGELOG.md +Project-URL: Homepage, https://github.com/hukkin/tomli + +[![Build Status](https://github.com/hukkin/tomli/workflows/Tests/badge.svg?branch=master)](https://github.com/hukkin/tomli/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush) +[![codecov.io](https://codecov.io/gh/hukkin/tomli/branch/master/graph/badge.svg)](https://codecov.io/gh/hukkin/tomli) +[![PyPI version](https://img.shields.io/pypi/v/tomli)](https://pypi.org/project/tomli) + +# Tomli + +> A lil' TOML parser + +**Table of Contents** *generated with [mdformat-toc](https://github.com/hukkin/mdformat-toc)* + +<!-- mdformat-toc start --slug=github --maxlevel=6 --minlevel=2 --> + +- [Intro](#intro) +- [Installation](#installation) +- [Usage](#usage) + - [Parse a TOML string](#parse-a-toml-string) + - [Parse a TOML file](#parse-a-toml-file) + - [Handle invalid TOML](#handle-invalid-toml) + - [Construct `decimal.Decimal`s from TOML floats](#construct-decimaldecimals-from-toml-floats) +- [FAQ](#faq) + - [Why this parser?](#why-this-parser) + - [Is comment preserving round-trip parsing supported?](#is-comment-preserving-round-trip-parsing-supported) + - [Is there a `dumps`, `write` or `encode` function?](#is-there-a-dumps-write-or-encode-function) + - [How do TOML types map into Python types?](#how-do-toml-types-map-into-python-types) +- [Performance](#performance) + +<!-- mdformat-toc end --> + +## Intro<a name="intro"></a> + +Tomli is a Python library for parsing [TOML](https://toml.io). +Tomli is fully compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0). + +## Installation<a name="installation"></a> + +```bash +pip install tomli +``` + +## Usage<a name="usage"></a> + +### Parse a TOML string<a name="parse-a-toml-string"></a> + +```python +import tomli + +toml_str = """ + gretzky = 99 + + [kurri] + jari = 17 + """ + +toml_dict = tomli.loads(toml_str) +assert toml_dict == {"gretzky": 99, "kurri": {"jari": 17}} +``` + +### Parse a TOML file<a name="parse-a-toml-file"></a> + +```python +import tomli + +with open("path_to_file/conf.toml", "rb") as f: + toml_dict = tomli.load(f) +``` + +The file must be opened in binary mode (with the `"rb"` flag). +Binary mode will enforce decoding the file as UTF-8 with universal newlines disabled, +both of which are required to correctly parse TOML. + +### Handle invalid TOML<a name="handle-invalid-toml"></a> + +```python +import tomli + +try: + toml_dict = tomli.loads("]] this is invalid TOML [[") +except tomli.TOMLDecodeError: + print("Yep, definitely not valid.") +``` + +Note that error messages are considered informational only. +They should not be assumed to stay constant across Tomli versions. + +### Construct `decimal.Decimal`s from TOML floats<a name="construct-decimaldecimals-from-toml-floats"></a> + +```python +from decimal import Decimal +import tomli + +toml_dict = tomli.loads("precision-matters = 0.982492", parse_float=Decimal) +assert toml_dict["precision-matters"] == Decimal("0.982492") +``` + +Note that `decimal.Decimal` can be replaced with another callable that converts a TOML float from string to a Python type. +The `decimal.Decimal` is, however, a practical choice for use cases where float inaccuracies can not be tolerated. + +Illegal types are `dict` and `list`, and their subtypes. +A `ValueError` will be raised if `parse_float` produces illegal types. + +## FAQ<a name="faq"></a> + +### Why this parser?<a name="why-this-parser"></a> + +- it's lil' +- pure Python with zero dependencies +- the fastest pure Python parser [\*](#performance): + 15x as fast as [tomlkit](https://pypi.org/project/tomlkit/), + 2.4x as fast as [toml](https://pypi.org/project/toml/) +- outputs [basic data types](#how-do-toml-types-map-into-python-types) only +- 100% spec compliant: passes all tests in + [a test set](https://github.com/toml-lang/compliance/pull/8) + soon to be merged to the official + [compliance tests for TOML](https://github.com/toml-lang/compliance) + repository +- thoroughly tested: 100% branch coverage + +### Is comment preserving round-trip parsing supported?<a name="is-comment-preserving-round-trip-parsing-supported"></a> + +No. + +The `tomli.loads` function returns a plain `dict` that is populated with builtin types and types from the standard library only. +Preserving comments requires a custom type to be returned so will not be supported, +at least not by the `tomli.loads` and `tomli.load` functions. + +Look into [TOML Kit](https://github.com/sdispater/tomlkit) if preservation of style is what you need. + +### Is there a `dumps`, `write` or `encode` function?<a name="is-there-a-dumps-write-or-encode-function"></a> + +[Tomli-W](https://github.com/hukkin/tomli-w) is the write-only counterpart of Tomli, providing `dump` and `dumps` functions. + +The core library does not include write capability, as most TOML use cases are read-only, and Tomli intends to be minimal. + +### How do TOML types map into Python types?<a name="how-do-toml-types-map-into-python-types"></a> + +| TOML type | Python type | Details | +| ---------------- | ------------------- | ------------------------------------------------------------ | +| Document Root | `dict` | | +| Key | `str` | | +| String | `str` | | +| Integer | `int` | | +| Float | `float` | | +| Boolean | `bool` | | +| Offset Date-Time | `datetime.datetime` | `tzinfo` attribute set to an instance of `datetime.timezone` | +| Local Date-Time | `datetime.datetime` | `tzinfo` attribute set to `None` | +| Local Date | `datetime.date` | | +| Local Time | `datetime.time` | | +| Array | `list` | | +| Table | `dict` | | +| Inline Table | `dict` | | + +## Performance<a name="performance"></a> + +The `benchmark/` folder in this repository contains a performance benchmark for comparing the various Python TOML parsers. +The benchmark can be run with `tox -e benchmark-pypi`. +Running the benchmark on my personal computer output the following: + +```console +foo@bar:~/dev/tomli$ tox -e benchmark-pypi +benchmark-pypi installed: attrs==19.3.0,click==7.1.2,pytomlpp==1.0.2,qtoml==0.3.0,rtoml==0.7.0,toml==0.10.2,tomli==1.1.0,tomlkit==0.7.2 +benchmark-pypi run-test-pre: PYTHONHASHSEED='2658546909' +benchmark-pypi run-test: commands[0] | python -c 'import datetime; print(datetime.date.today())' +2021-07-23 +benchmark-pypi run-test: commands[1] | python --version +Python 3.8.10 +benchmark-pypi run-test: commands[2] | python benchmark/run.py +Parsing data.toml 5000 times: +------------------------------------------------------ + parser | exec time | performance (more is better) +-----------+------------+----------------------------- + rtoml | 0.901 s | baseline (100%) + pytomlpp | 1.08 s | 83.15% + tomli | 3.89 s | 23.15% + toml | 9.36 s | 9.63% + qtoml | 11.5 s | 7.82% + tomlkit | 56.8 s | 1.59% +``` + +The parsers are ordered from fastest to slowest, using the fastest parser as baseline. +Tomli performed the best out of all pure Python TOML parsers, +losing only to pytomlpp (wraps C++) and rtoml (wraps Rust). + diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/RECORD new file mode 100644 index 00000000..49e28298 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/RECORD @@ -0,0 +1,14 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/tomli/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/tomli/_parser.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/tomli/_re.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/tomli/_types.cpython-39.pyc,, +tomli-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072 +tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875 +tomli-2.0.1.dist-info/RECORD,, +tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81 +tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396 +tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633 +tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943 +tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254 +tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26 diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/WHEEL new file mode 100644 index 00000000..c727d148 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli-2.0.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.6.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli/__init__.py b/dbdpy-env/lib/python3.9/site-packages/tomli/__init__.py new file mode 100644 index 00000000..4c6ec97e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli/__init__.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +__all__ = ("loads", "load", "TOMLDecodeError") +__version__ = "2.0.1" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT + +from ._parser import TOMLDecodeError, load, loads + +# Pretend this exception was created here. +TOMLDecodeError.__module__ = __name__ diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli/_parser.py b/dbdpy-env/lib/python3.9/site-packages/tomli/_parser.py new file mode 100644 index 00000000..f1bb0aa1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli/_parser.py @@ -0,0 +1,691 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from collections.abc import Iterable +import string +from types import MappingProxyType +from typing import Any, BinaryIO, NamedTuple + +from ._re import ( + RE_DATETIME, + RE_LOCALTIME, + RE_NUMBER, + match_to_datetime, + match_to_localtime, + match_to_number, +) +from ._types import Key, ParseFloat, Pos + +ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) + +# Neither of these sets include quotation mark or backslash. They are +# currently handled as separate cases in the parser functions. +ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") +ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n") + +ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS +ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ILLEGAL_MULTILINE_BASIC_STR_CHARS + +ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS + +TOML_WS = frozenset(" \t") +TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n") +BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_") +KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'") +HEXDIGIT_CHARS = frozenset(string.hexdigits) + +BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( + { + "\\b": "\u0008", # backspace + "\\t": "\u0009", # tab + "\\n": "\u000A", # linefeed + "\\f": "\u000C", # form feed + "\\r": "\u000D", # carriage return + '\\"': "\u0022", # quote + "\\\\": "\u005C", # backslash + } +) + + +class TOMLDecodeError(ValueError): + """An error raised if a document is not valid TOML.""" + + +def load(__fp: BinaryIO, *, parse_float: ParseFloat = float) -> dict[str, Any]: + """Parse TOML from a binary file object.""" + b = __fp.read() + try: + s = b.decode() + except AttributeError: + raise TypeError( + "File must be opened in binary mode, e.g. use `open('foo.toml', 'rb')`" + ) from None + return loads(s, parse_float=parse_float) + + +def loads(__s: str, *, parse_float: ParseFloat = float) -> dict[str, Any]: # noqa: C901 + """Parse TOML from a string.""" + + # The spec allows converting "\r\n" to "\n", even in string + # literals. Let's do so to simplify parsing. + src = __s.replace("\r\n", "\n") + pos = 0 + out = Output(NestedDict(), Flags()) + header: Key = () + parse_float = make_safe_parse_float(parse_float) + + # Parse one statement at a time + # (typically means one line in TOML source) + while True: + # 1. Skip line leading whitespace + pos = skip_chars(src, pos, TOML_WS) + + # 2. Parse rules. Expect one of the following: + # - end of file + # - end of line + # - comment + # - key/value pair + # - append dict to list (and move to its namespace) + # - create dict (and move to its namespace) + # Skip trailing whitespace when applicable. + try: + char = src[pos] + except IndexError: + break + if char == "\n": + pos += 1 + continue + if char in KEY_INITIAL_CHARS: + pos = key_value_rule(src, pos, out, header, parse_float) + pos = skip_chars(src, pos, TOML_WS) + elif char == "[": + try: + second_char: str | None = src[pos + 1] + except IndexError: + second_char = None + out.flags.finalize_pending() + if second_char == "[": + pos, header = create_list_rule(src, pos, out) + else: + pos, header = create_dict_rule(src, pos, out) + pos = skip_chars(src, pos, TOML_WS) + elif char != "#": + raise suffixed_err(src, pos, "Invalid statement") + + # 3. Skip comment + pos = skip_comment(src, pos) + + # 4. Expect end of line or end of file + try: + char = src[pos] + except IndexError: + break + if char != "\n": + raise suffixed_err( + src, pos, "Expected newline or end of document after a statement" + ) + pos += 1 + + return out.data.dict + + +class Flags: + """Flags that map to parsed keys/namespaces.""" + + # Marks an immutable namespace (inline array or inline table). + FROZEN = 0 + # Marks a nest that has been explicitly created and can no longer + # be opened using the "[table]" syntax. + EXPLICIT_NEST = 1 + + def __init__(self) -> None: + self._flags: dict[str, dict] = {} + self._pending_flags: set[tuple[Key, int]] = set() + + def add_pending(self, key: Key, flag: int) -> None: + self._pending_flags.add((key, flag)) + + def finalize_pending(self) -> None: + for key, flag in self._pending_flags: + self.set(key, flag, recursive=False) + self._pending_flags.clear() + + def unset_all(self, key: Key) -> None: + cont = self._flags + for k in key[:-1]: + if k not in cont: + return + cont = cont[k]["nested"] + cont.pop(key[-1], None) + + def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003 + cont = self._flags + key_parent, key_stem = key[:-1], key[-1] + for k in key_parent: + if k not in cont: + cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + if key_stem not in cont: + cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag) + + def is_(self, key: Key, flag: int) -> bool: + if not key: + return False # document root has no flags + cont = self._flags + for k in key[:-1]: + if k not in cont: + return False + inner_cont = cont[k] + if flag in inner_cont["recursive_flags"]: + return True + cont = inner_cont["nested"] + key_stem = key[-1] + if key_stem in cont: + cont = cont[key_stem] + return flag in cont["flags"] or flag in cont["recursive_flags"] + return False + + +class NestedDict: + def __init__(self) -> None: + # The parsed content of the TOML document + self.dict: dict[str, Any] = {} + + def get_or_create_nest( + self, + key: Key, + *, + access_lists: bool = True, + ) -> dict: + cont: Any = self.dict + for k in key: + if k not in cont: + cont[k] = {} + cont = cont[k] + if access_lists and isinstance(cont, list): + cont = cont[-1] + if not isinstance(cont, dict): + raise KeyError("There is no nest behind this key") + return cont + + def append_nest_to_list(self, key: Key) -> None: + cont = self.get_or_create_nest(key[:-1]) + last_key = key[-1] + if last_key in cont: + list_ = cont[last_key] + if not isinstance(list_, list): + raise KeyError("An object other than list found behind this key") + list_.append({}) + else: + cont[last_key] = [{}] + + +class Output(NamedTuple): + data: NestedDict + flags: Flags + + +def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos: + try: + while src[pos] in chars: + pos += 1 + except IndexError: + pass + return pos + + +def skip_until( + src: str, + pos: Pos, + expect: str, + *, + error_on: frozenset[str], + error_on_eof: bool, +) -> Pos: + try: + new_pos = src.index(expect, pos) + except ValueError: + new_pos = len(src) + if error_on_eof: + raise suffixed_err(src, new_pos, f"Expected {expect!r}") from None + + if not error_on.isdisjoint(src[pos:new_pos]): + while src[pos] not in error_on: + pos += 1 + raise suffixed_err(src, pos, f"Found invalid character {src[pos]!r}") + return new_pos + + +def skip_comment(src: str, pos: Pos) -> Pos: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char == "#": + return skip_until( + src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False + ) + return pos + + +def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos: + while True: + pos_before_skip = pos + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + pos = skip_comment(src, pos) + if pos == pos_before_skip: + return pos + + +def create_dict_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 1 # Skip "[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.EXPLICIT_NEST) or out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot declare {key} twice") + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.get_or_create_nest(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]", pos): + raise suffixed_err(src, pos, "Expected ']' at the end of a table declaration") + return pos + 1, key + + +def create_list_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 2 # Skip "[[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + # Free the namespace now that it points to another empty list item... + out.flags.unset_all(key) + # ...but this key precisely is still prohibited from table declaration + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.append_nest_to_list(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]]", pos): + raise suffixed_err(src, pos, "Expected ']]' at the end of an array declaration") + return pos + 2, key + + +def key_value_rule( + src: str, pos: Pos, out: Output, header: Key, parse_float: ParseFloat +) -> Pos: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + abs_key_parent = header + key_parent + + relative_path_cont_keys = (header + key[:i] for i in range(1, len(key))) + for cont_key in relative_path_cont_keys: + # Check that dotted key syntax does not redefine an existing table + if out.flags.is_(cont_key, Flags.EXPLICIT_NEST): + raise suffixed_err(src, pos, f"Cannot redefine namespace {cont_key}") + # Containers in the relative path can't be opened with the table syntax or + # dotted key/value syntax in following table sections. + out.flags.add_pending(cont_key, Flags.EXPLICIT_NEST) + + if out.flags.is_(abs_key_parent, Flags.FROZEN): + raise suffixed_err( + src, pos, f"Cannot mutate immutable namespace {abs_key_parent}" + ) + + try: + nest = out.data.get_or_create_nest(abs_key_parent) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, "Cannot overwrite a value") + # Mark inline table and array namespaces recursively immutable + if isinstance(value, (dict, list)): + out.flags.set(header + key, Flags.FROZEN, recursive=True) + nest[key_stem] = value + return pos + + +def parse_key_value_pair( + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Key, Any]: + pos, key = parse_key(src, pos) + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != "=": + raise suffixed_err(src, pos, "Expected '=' after a key in a key/value pair") + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, value = parse_value(src, pos, parse_float) + return pos, key, value + + +def parse_key(src: str, pos: Pos) -> tuple[Pos, Key]: + pos, key_part = parse_key_part(src, pos) + key: Key = (key_part,) + pos = skip_chars(src, pos, TOML_WS) + while True: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != ".": + return pos, key + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, key_part = parse_key_part(src, pos) + key += (key_part,) + pos = skip_chars(src, pos, TOML_WS) + + +def parse_key_part(src: str, pos: Pos) -> tuple[Pos, str]: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char in BARE_KEY_CHARS: + start_pos = pos + pos = skip_chars(src, pos, BARE_KEY_CHARS) + return pos, src[start_pos:pos] + if char == "'": + return parse_literal_str(src, pos) + if char == '"': + return parse_one_line_basic_str(src, pos) + raise suffixed_err(src, pos, "Invalid initial character for a key part") + + +def parse_one_line_basic_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 + return parse_basic_str(src, pos, multiline=False) + + +def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list]: + pos += 1 + array: list = [] + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + while True: + pos, val = parse_value(src, pos, parse_float) + array.append(val) + pos = skip_comments_and_array_ws(src, pos) + + c = src[pos : pos + 1] + if c == "]": + return pos + 1, array + if c != ",": + raise suffixed_err(src, pos, "Unclosed array") + pos += 1 + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + + +def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, dict]: + pos += 1 + nested_dict = NestedDict() + flags = Flags() + + pos = skip_chars(src, pos, TOML_WS) + if src.startswith("}", pos): + return pos + 1, nested_dict.dict + while True: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + if flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + try: + nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, f"Duplicate inline table key {key_stem!r}") + nest[key_stem] = value + pos = skip_chars(src, pos, TOML_WS) + c = src[pos : pos + 1] + if c == "}": + return pos + 1, nested_dict.dict + if c != ",": + raise suffixed_err(src, pos, "Unclosed inline table") + if isinstance(value, (dict, list)): + flags.set(key, Flags.FROZEN, recursive=True) + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + + +def parse_basic_str_escape( + src: str, pos: Pos, *, multiline: bool = False +) -> tuple[Pos, str]: + escape_id = src[pos : pos + 2] + pos += 2 + if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}: + # Skip whitespace until next non-whitespace character or end of + # the doc. Error if non-whitespace is found before newline. + if escape_id != "\\\n": + pos = skip_chars(src, pos, TOML_WS) + try: + char = src[pos] + except IndexError: + return pos, "" + if char != "\n": + raise suffixed_err(src, pos, "Unescaped '\\' in a string") + pos += 1 + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + return pos, "" + if escape_id == "\\u": + return parse_hex_char(src, pos, 4) + if escape_id == "\\U": + return parse_hex_char(src, pos, 8) + try: + return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] + except KeyError: + raise suffixed_err(src, pos, "Unescaped '\\' in a string") from None + + +def parse_basic_str_escape_multiline(src: str, pos: Pos) -> tuple[Pos, str]: + return parse_basic_str_escape(src, pos, multiline=True) + + +def parse_hex_char(src: str, pos: Pos, hex_len: int) -> tuple[Pos, str]: + hex_str = src[pos : pos + hex_len] + if len(hex_str) != hex_len or not HEXDIGIT_CHARS.issuperset(hex_str): + raise suffixed_err(src, pos, "Invalid hex value") + pos += hex_len + hex_int = int(hex_str, 16) + if not is_unicode_scalar_value(hex_int): + raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") + return pos, chr(hex_int) + + +def parse_literal_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 # Skip starting apostrophe + start_pos = pos + pos = skip_until( + src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True + ) + return pos + 1, src[start_pos:pos] # Skip ending apostrophe + + +def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> tuple[Pos, str]: + pos += 3 + if src.startswith("\n", pos): + pos += 1 + + if literal: + delim = "'" + end_pos = skip_until( + src, + pos, + "'''", + error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS, + error_on_eof=True, + ) + result = src[pos:end_pos] + pos = end_pos + 3 + else: + delim = '"' + pos, result = parse_basic_str(src, pos, multiline=True) + + # Add at maximum two extra apostrophes/quotes if the end sequence + # is 4 or 5 chars long instead of just 3. + if not src.startswith(delim, pos): + return pos, result + pos += 1 + if not src.startswith(delim, pos): + return pos, result + delim + pos += 1 + return pos, result + (delim * 2) + + +def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]: + if multiline: + error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape_multiline + else: + error_on = ILLEGAL_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape + result = "" + start_pos = pos + while True: + try: + char = src[pos] + except IndexError: + raise suffixed_err(src, pos, "Unterminated string") from None + if char == '"': + if not multiline: + return pos + 1, result + src[start_pos:pos] + if src.startswith('"""', pos): + return pos + 3, result + src[start_pos:pos] + pos += 1 + continue + if char == "\\": + result += src[start_pos:pos] + pos, parsed_escape = parse_escapes(src, pos) + result += parsed_escape + start_pos = pos + continue + if char in error_on: + raise suffixed_err(src, pos, f"Illegal character {char!r}") + pos += 1 + + +def parse_value( # noqa: C901 + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Any]: + try: + char: str | None = src[pos] + except IndexError: + char = None + + # IMPORTANT: order conditions based on speed of checking and likelihood + + # Basic strings + if char == '"': + if src.startswith('"""', pos): + return parse_multiline_str(src, pos, literal=False) + return parse_one_line_basic_str(src, pos) + + # Literal strings + if char == "'": + if src.startswith("'''", pos): + return parse_multiline_str(src, pos, literal=True) + return parse_literal_str(src, pos) + + # Booleans + if char == "t": + if src.startswith("true", pos): + return pos + 4, True + if char == "f": + if src.startswith("false", pos): + return pos + 5, False + + # Arrays + if char == "[": + return parse_array(src, pos, parse_float) + + # Inline tables + if char == "{": + return parse_inline_table(src, pos, parse_float) + + # Dates and times + datetime_match = RE_DATETIME.match(src, pos) + if datetime_match: + try: + datetime_obj = match_to_datetime(datetime_match) + except ValueError as e: + raise suffixed_err(src, pos, "Invalid date or datetime") from e + return datetime_match.end(), datetime_obj + localtime_match = RE_LOCALTIME.match(src, pos) + if localtime_match: + return localtime_match.end(), match_to_localtime(localtime_match) + + # Integers and "normal" floats. + # The regex will greedily match any type starting with a decimal + # char, so needs to be located after handling of dates and times. + number_match = RE_NUMBER.match(src, pos) + if number_match: + return number_match.end(), match_to_number(number_match, parse_float) + + # Special floats + first_three = src[pos : pos + 3] + if first_three in {"inf", "nan"}: + return pos + 3, parse_float(first_three) + first_four = src[pos : pos + 4] + if first_four in {"-inf", "+inf", "-nan", "+nan"}: + return pos + 4, parse_float(first_four) + + raise suffixed_err(src, pos, "Invalid value") + + +def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: + """Return a `TOMLDecodeError` where error message is suffixed with + coordinates in source.""" + + def coord_repr(src: str, pos: Pos) -> str: + if pos >= len(src): + return "end of document" + line = src.count("\n", 0, pos) + 1 + if line == 1: + column = pos + 1 + else: + column = pos - src.rindex("\n", 0, pos) + return f"line {line}, column {column}" + + return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") + + +def is_unicode_scalar_value(codepoint: int) -> bool: + return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111) + + +def make_safe_parse_float(parse_float: ParseFloat) -> ParseFloat: + """A decorator to make `parse_float` safe. + + `parse_float` must not return dicts or lists, because these types + would be mixed with parsed TOML tables and arrays, thus confusing + the parser. The returned decorated callable raises `ValueError` + instead of returning illegal types. + """ + # The default `float` callable never returns illegal types. Optimize it. + if parse_float is float: # type: ignore[comparison-overlap] + return float + + def safe_parse_float(float_str: str) -> Any: + float_value = parse_float(float_str) + if isinstance(float_value, (dict, list)): + raise ValueError("parse_float must not return dicts or lists") + return float_value + + return safe_parse_float diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli/_re.py b/dbdpy-env/lib/python3.9/site-packages/tomli/_re.py new file mode 100644 index 00000000..994bb749 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli/_re.py @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from datetime import date, datetime, time, timedelta, timezone, tzinfo +from functools import lru_cache +import re +from typing import Any + +from ._types import ParseFloat + +# E.g. +# - 00:32:00.999999 +# - 00:32:00 +_TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.([0-9]{1,6})[0-9]*)?" + +RE_NUMBER = re.compile( + r""" +0 +(?: + x[0-9A-Fa-f](?:_?[0-9A-Fa-f])* # hex + | + b[01](?:_?[01])* # bin + | + o[0-7](?:_?[0-7])* # oct +) +| +[+-]?(?:0|[1-9](?:_?[0-9])*) # dec, integer part +(?P<floatpart> + (?:\.[0-9](?:_?[0-9])*)? # optional fractional part + (?:[eE][+-]?[0-9](?:_?[0-9])*)? # optional exponent part +) +""", + flags=re.VERBOSE, +) +RE_LOCALTIME = re.compile(_TIME_RE_STR) +RE_DATETIME = re.compile( + rf""" +([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) # date, e.g. 1988-10-27 +(?: + [Tt ] + {_TIME_RE_STR} + (?:([Zz])|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))? # optional time offset +)? +""", + flags=re.VERBOSE, +) + + +def match_to_datetime(match: re.Match) -> datetime | date: + """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. + + Raises ValueError if the match does not correspond to a valid date + or datetime. + """ + ( + year_str, + month_str, + day_str, + hour_str, + minute_str, + sec_str, + micros_str, + zulu_time, + offset_sign_str, + offset_hour_str, + offset_minute_str, + ) = match.groups() + year, month, day = int(year_str), int(month_str), int(day_str) + if hour_str is None: + return date(year, month, day) + hour, minute, sec = int(hour_str), int(minute_str), int(sec_str) + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + if offset_sign_str: + tz: tzinfo | None = cached_tz( + offset_hour_str, offset_minute_str, offset_sign_str + ) + elif zulu_time: + tz = timezone.utc + else: # local date-time + tz = None + return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz) + + +@lru_cache(maxsize=None) +def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone: + sign = 1 if sign_str == "+" else -1 + return timezone( + timedelta( + hours=sign * int(hour_str), + minutes=sign * int(minute_str), + ) + ) + + +def match_to_localtime(match: re.Match) -> time: + hour_str, minute_str, sec_str, micros_str = match.groups() + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + return time(int(hour_str), int(minute_str), int(sec_str), micros) + + +def match_to_number(match: re.Match, parse_float: ParseFloat) -> Any: + if match.group("floatpart"): + return parse_float(match.group()) + return int(match.group(), 0) diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli/_types.py b/dbdpy-env/lib/python3.9/site-packages/tomli/_types.py new file mode 100644 index 00000000..d949412e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli/_types.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from typing import Any, Callable, Tuple + +# Type annotations +ParseFloat = Callable[[str], Any] +Key = Tuple[str, ...] +Pos = int diff --git a/dbdpy-env/lib/python3.9/site-packages/tomli/py.typed b/dbdpy-env/lib/python3.9/site-packages/tomli/py.typed new file mode 100644 index 00000000..7632ecf7 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/tomli/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561 diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1-py3.9-nspkg.pth b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1-py3.9-nspkg.pth new file mode 100644 index 00000000..4fa827e2 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1-py3.9-nspkg.pth @@ -0,0 +1 @@ +import sys, types, os;has_mfs = sys.version_info > (3, 5);p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('zope',));importlib = has_mfs and __import__('importlib.util');has_mfs and __import__('importlib.machinery');m = has_mfs and sys.modules.setdefault('zope', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('zope', [os.path.dirname(p)])));m = m or sys.modules.setdefault('zope', types.ModuleType('zope'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/LICENSE.txt b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/LICENSE.txt new file mode 100644 index 00000000..e1f9ad7b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/LICENSE.txt @@ -0,0 +1,44 @@ +Zope Public License (ZPL) Version 2.1 + +A copyright notice accompanies this license document that identifies the +copyright holders. + +This license has been certified as open source. It has also been designated as +GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions in source code must retain the accompanying copyright +notice, this list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the accompanying copyright +notice, this list of conditions, and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Names of the copyright holders must not be used to endorse or promote +products derived from this software without prior written permission from the +copyright holders. + +4. The right to distribute this software or to use it for any purpose does not +give you the right to use Servicemarks (sm) or Trademarks (tm) of the +copyright +holders. Use of them is covered by separate agreement with the copyright +holders. + +5. If any files are modified, you must cause the modified files to carry +prominent notices stating that you changed the files and the date of any +change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/METADATA new file mode 100644 index 00000000..f0bfe5f5 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/METADATA @@ -0,0 +1,1120 @@ +Metadata-Version: 2.1 +Name: zope.interface +Version: 6.1 +Summary: Interfaces for Python +Home-page: https://github.com/zopefoundation/zope.interface +Author: Zope Foundation and Contributors +Author-email: zope-dev@zope.org +License: ZPL 2.1 +Keywords: interface,components,plugins +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Zope Public License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Framework :: Zope :: 3 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.7 +License-File: LICENSE.txt +Requires-Dist: setuptools +Provides-Extra: docs +Requires-Dist: Sphinx ; extra == 'docs' +Requires-Dist: repoze.sphinx.autointerface ; extra == 'docs' +Requires-Dist: sphinx-rtd-theme ; extra == 'docs' +Provides-Extra: test +Requires-Dist: coverage >=5.0.3 ; extra == 'test' +Requires-Dist: zope.event ; extra == 'test' +Requires-Dist: zope.testing ; extra == 'test' +Provides-Extra: testing +Requires-Dist: coverage >=5.0.3 ; extra == 'testing' +Requires-Dist: zope.event ; extra == 'testing' +Requires-Dist: zope.testing ; extra == 'testing' + +==================== + ``zope.interface`` +==================== + +.. image:: https://img.shields.io/pypi/v/zope.interface.svg + :target: https://pypi.python.org/pypi/zope.interface/ + :alt: Latest Version + +.. image:: https://img.shields.io/pypi/pyversions/zope.interface.svg + :target: https://pypi.org/project/zope.interface/ + :alt: Supported Python versions + +.. image:: https://github.com/zopefoundation/zope.interface/actions/workflows/tests.yml/badge.svg + :target: https://github.com/zopefoundation/zope.interface/actions/workflows/tests.yml + +.. image:: https://readthedocs.org/projects/zopeinterface/badge/?version=latest + :target: https://zopeinterface.readthedocs.io/en/latest/ + :alt: Documentation Status + +This package is intended to be independently reusable in any Python +project. It is maintained by the `Zope Toolkit project +<https://zopetoolkit.readthedocs.io/>`_. + +This package provides an implementation of "object interfaces" for Python. +Interfaces are a mechanism for labeling objects as conforming to a given +API or contract. So, this package can be considered as implementation of +the `Design By Contract`_ methodology support in Python. + +.. _Design By Contract: http://en.wikipedia.org/wiki/Design_by_contract + +For detailed documentation, please see https://zopeinterface.readthedocs.io/en/latest/ + +========= + Changes +========= + +6.1 (2023-10-05) +================ + +- Build Linux binary wheels for Python 3.12. + +- Add support for Python 3.12. + +- Fix building of the docs for non-final versions. + + +6.0 (2023-03-17) +================ + +- Build Linux binary wheels for Python 3.11. + +- Drop support for Python 2.7, 3.5, 3.6. + +- Fix test deprecation warning on Python 3.11. + +- Add preliminary support for Python 3.12 as of 3.12a5. + +- Drop: + + + `zope.interface.implements` + + `zope.interface.implementsOnly` + + `zope.interface.classProvides` + + +5.5.2 (2022-11-17) +================== + +- Add support for building arm64 wheels on macOS. + + +5.5.1 (2022-11-03) +================== + +- Add support for final Python 3.11 release. + + +5.5.0 (2022-10-10) +================== + +- Add support for Python 3.10 and 3.11 (as of 3.11.0rc2). + +- Add missing Trove classifier showing support for Python 3.9. + +- Add some more entries to ``zope.interface.interfaces.__all__``. + +- Disable unsafe math optimizations in C code. See `pull request 262 + <https://github.com/zopefoundation/zope.interface/pull/262>`_. + + +5.4.0 (2021-04-15) +================== + +- Make the C implementation of the ``__providedBy__`` descriptor stop + ignoring all errors raised when accessing the instance's + ``__provides__``. Now it behaves like the Python version and only + catches ``AttributeError``. The previous behaviour could lead to + crashing the interpreter in cases of recursion and errors. See + `issue 239 <https://github.com/zopefoundation/zope.interface/issues>`_. + +- Update the ``repr()`` and ``str()`` of various objects to be shorter + and more informative. In many cases, the ``repr()`` is now something + that can be evaluated to produce an equal object. For example, what + was previously printed as ``<implementedBy builtins.list>`` is now + shown as ``classImplements(list, IMutableSequence, IIterable)``. See + `issue 236 <https://github.com/zopefoundation/zope.interface/issues/236>`_. + +- Make ``Declaration.__add__`` (as in ``implementedBy(Cls) + + ISomething``) try harder to preserve a consistent resolution order + when the two arguments share overlapping pieces of the interface + inheritance hierarchy. Previously, the right hand side was always + put at the end of the resolution order, which could easily produce + invalid orders. See `issue 193 + <https://github.com/zopefoundation/zope.interface/issues/193>`_. + +5.3.0 (2020-03-21) +================== + +- No changes from 5.3.0a1 + + +5.3.0a1 (2021-03-18) +==================== + +- Improve the repr of ``zope.interface.Provides`` to remove ambiguity + about what is being provided. This is especially helpful diagnosing + IRO issues. + +- Allow subclasses of ``BaseAdapterRegistry`` (including + ``AdapterRegistry`` and ``VerifyingAdapterRegistry``) to have + control over the data structures. This allows persistent + implementations such as those based on ZODB to choose more scalable + options (e.g., BTrees instead of dicts). See `issue 224 + <https://github.com/zopefoundation/zope.interface/issues/224>`_. + +- Fix a reference counting issue in ``BaseAdapterRegistry`` that could + lead to references to interfaces being kept around even when all + utilities/adapters/subscribers providing that interface have been + removed. This is mostly an issue for persistent implementations. + Note that this only corrects the issue moving forward, it does not + solve any already corrupted reference counts. See `issue 227 + <https://github.com/zopefoundation/zope.interface/issues/227>`_. + +- Add the method ``BaseAdapterRegistry.rebuild()``. This can be used + to fix the reference counting issue mentioned above, as well as to + update the data structures when custom data types have changed. + +- Add the interface method ``IAdapterRegistry.subscribed()`` and + implementation ``BaseAdapterRegistry.subscribed()`` for querying + directly registered subscribers. See `issue 230 + <https://github.com/zopefoundation/zope.interface/issues/230>`_. + +- Add the maintenance method + ``Components.rebuildUtilityRegistryFromLocalCache()``. Most users + will not need this, but it can be useful if the ``Components.utilities`` + registry is suspected to be out of sync with the ``Components`` + object itself (this might happen to persistent ``Components`` + implementations in the face of bugs). + +- Fix the ``Provides`` and ``ClassProvides`` descriptors to stop + allowing redundant interfaces (those already implemented by the + underlying class or meta class) to produce an inconsistent + resolution order. This is similar to the change in ``@implementer`` + in 5.1.0, and resolves inconsistent resolution orders with + ``zope.proxy`` and ``zope.location``. See `issue 207 + <https://github.com/zopefoundation/zope.interface/issues/207>`_. + +5.2.0 (2020-11-05) +================== + +- Add documentation section ``Persistency and Equality`` + (`#218 <https://github.com/zopefoundation/zope.interface/issues/218>`_). + +- Create arm64 wheels. + +- Add support for Python 3.9. + + +5.1.2 (2020-10-01) +================== + +- Make sure to call each invariant only once when validating invariants. + Previously, invariants could be called multiple times because when an + invariant is defined in an interface, it's found by in all interfaces + inheriting from that interface. See `pull request 215 + <https://github.com/zopefoundation/zope.interface/pull/215/>`_. + +5.1.1 (2020-09-30) +================== + +- Fix the method definitions of ``IAdapterRegistry.subscribe``, + ``subscriptions`` and ``subscribers``. Previously, they all were + defined to accept a ``name`` keyword argument, but subscribers have + no names and the implementation of that interface did not accept + that argument. See `issue 208 + <https://github.com/zopefoundation/zope.interface/issues/208>`_. + +- Fix a potential reference leak in the C optimizations. Previously, + applications that dynamically created unique ``Specification`` + objects (e.g., used ``@implementer`` on dynamic classes) could + notice a growth of small objects over time leading to increased + garbage collection times. See `issue 216 + <https://github.com/zopefoundation/zope.interface/issues/216>`_. + + .. caution:: + + This leak could prevent interfaces used as the bases of + other interfaces from being garbage collected. Those interfaces + will now be collected. + + One way in which this would manifest was that ``weakref.ref`` + objects (and things built upon them, like + ``Weak[Key|Value]Dictionary``) would continue to have access to + the original object even if there were no other visible + references to Python and the original object *should* have been + collected. This could be especially problematic for the + ``WeakKeyDictionary`` when combined with dynamic or local + (created in the scope of a function) interfaces, since interfaces + are hashed based just on their name and module name. See the + linked issue for an example of a resulting ``KeyError``. + + Note that such potential errors are not new, they are just once + again a possibility. + +5.1.0 (2020-04-08) +================== + +- Make ``@implementer(*iface)`` and ``classImplements(cls, *iface)`` + ignore redundant interfaces. If the class already implements an + interface through inheritance, it is no longer redeclared + specifically for *cls*. This solves many instances of inconsistent + resolution orders, while still allowing the interface to be declared + for readability and maintenance purposes. See `issue 199 + <https://github.com/zopefoundation/zope.interface/issues/199>`_. + +- Remove all bare ``except:`` statements. Previously, when accessing + special attributes such as ``__provides__``, ``__providedBy__``, + ``__class__`` and ``__conform__``, this package wrapped such access + in a bare ``except:`` statement, meaning that many errors could pass + silently; typically this would result in a fallback path being taken + and sometimes (like with ``providedBy()``) the result would be + non-sensical. This is especially true when those attributes are + implemented with descriptors. Now, only ``AttributeError`` is + caught. This makes errors more obvious. + + Obviously, this means that some exceptions will be propagated + differently than before. In particular, ``RuntimeError`` raised by + Acquisition in the case of circular containment will now be + propagated. Previously, when adapting such a broken object, a + ``TypeError`` would be the common result, but now it will be a more + informative ``RuntimeError``. + + In addition, ZODB errors like ``POSKeyError`` could now be + propagated where previously they would ignored by this package. + + See `issue 200 <https://github.com/zopefoundation/zope.interface/issues/200>`_. + +- Require that the second argument (*bases*) to ``InterfaceClass`` is + a tuple. This only matters when directly using ``InterfaceClass`` to + create new interfaces dynamically. Previously, an individual + interface was allowed, but did not work correctly. Now it is + consistent with ``type`` and requires a tuple. + +- Let interfaces define custom ``__adapt__`` methods. This implements + the other side of the :pep:`246` adaptation protocol: objects being + adapted could already implement ``__conform__`` if they know about + the interface, and now interfaces can implement ``__adapt__`` if + they know about particular objects. There is no performance penalty + for interfaces that do not supply custom ``__adapt__`` methods. + + This includes the ability to add new methods, or override existing + interface methods using the new ``@interfacemethod`` decorator. + + See `issue 3 <https://github.com/zopefoundation/zope.interface/issues/3>`_. + +- Make the internal singleton object returned by APIs like + ``implementedBy`` and ``directlyProvidedBy`` for objects that + implement or provide no interfaces more immutable. Previously an + internal cache could be mutated. See `issue 204 + <https://github.com/zopefoundation/zope.interface/issues/204>`_. + +5.0.2 (2020-03-30) +================== + +- Ensure that objects that implement no interfaces (such as direct + subclasses of ``object``) still include ``Interface`` itself in + their ``__iro___`` and ``__sro___``. This fixes adapter registry + lookups for such objects when the adapter is registered for + ``Interface``. See `issue 197 + <https://github.com/zopefoundation/zope.interface/issues/197>`_. + + +5.0.1 (2020-03-21) +================== + +- Ensure the resolution order for ``InterfaceClass`` is consistent. + See `issue 192 <https://github.com/zopefoundation/zope.interface/issues/192>`_. + +- Ensure the resolution order for ``collections.OrderedDict`` is + consistent on CPython 2. (It was already consistent on Python 3 and PyPy). + +- Fix the handling of the ``ZOPE_INTERFACE_STRICT_IRO`` environment + variable. Previously, ``ZOPE_INTERFACE_STRICT_RO`` was read, in + contrast with the documentation. See `issue 194 + <https://github.com/zopefoundation/zope.interface/issues/194>`_. + + +5.0.0 (2020-03-19) +================== + +- Make an internal singleton object returned by APIs like + ``implementedBy`` and ``directlyProvidedBy`` immutable. Previously, + it was fully mutable and allowed changing its ``__bases___``. That + could potentially lead to wrong results in pathological corner + cases. See `issue 158 + <https://github.com/zopefoundation/zope.interface/issues/158>`_. + +- Support the ``PURE_PYTHON`` environment variable at runtime instead + of just at wheel build time. A value of 0 forces the C extensions to + be used (even on PyPy) failing if they aren't present. Any other + value forces the Python implementation to be used, ignoring the C + extensions. See `PR 151 <https://github.com/zopefoundation/zope.interface/pull/151>`_. + +- Cache the result of ``__hash__`` method in ``InterfaceClass`` as a + speed optimization. The method is called very often (i.e several + hundred thousand times during Plone 5.2 startup). Because the hash value never + changes it can be cached. This improves test performance from 0.614s + down to 0.575s (1.07x faster). In a real world Plone case a reindex + index came down from 402s to 320s (1.26x faster). See `PR 156 + <https://github.com/zopefoundation/zope.interface/pull/156>`_. + +- Change the C classes ``SpecificationBase`` and its subclass + ``ClassProvidesBase`` to store implementation attributes in their structures + instead of their instance dictionaries. This eliminates the use of + an undocumented private C API function, and helps make some + instances require less memory. See `PR 154 <https://github.com/zopefoundation/zope.interface/pull/154>`_. + +- Reduce memory usage in other ways based on observations of usage + patterns in Zope (3) and Plone code bases. + + - Specifications with no dependents are common (more than 50%) so + avoid allocating a ``WeakKeyDictionary`` unless we need it. + - Likewise, tagged values are relatively rare, so don't allocate a + dictionary to hold them until they are used. + - Use ``__slots___`` or the C equivalent ``tp_members`` in more + common places. Note that this removes the ability to set arbitrary + instance variables on certain objects. + See `PR 155 <https://github.com/zopefoundation/zope.interface/pull/155>`_. + + The changes in this release resulted in a 7% memory reduction after + loading about 6,000 modules that define about 2,200 interfaces. + + .. caution:: + + Details of many private attributes have changed, and external use + of those private attributes may break. In particular, the + lifetime and default value of ``_v_attrs`` has changed. + +- Remove support for hashing uninitialized interfaces. This could only + be done by subclassing ``InterfaceClass``. This has generated a + warning since it was first added in 2011 (3.6.5). Please call the + ``InterfaceClass`` constructor or otherwise set the appropriate + fields in your subclass before attempting to hash or sort it. See + `issue 157 <https://github.com/zopefoundation/zope.interface/issues/157>`_. + +- Remove unneeded override of the ``__hash__`` method from + ``zope.interface.declarations.Implements``. Watching a reindex index + process in ZCatalog with on a Py-Spy after 10k samples the time for + ``.adapter._lookup`` was reduced from 27.5s to 18.8s (~1.5x faster). + Overall reindex index time shrunk from 369s to 293s (1.26x faster). + See `PR 161 + <https://github.com/zopefoundation/zope.interface/pull/161>`_. + +- Make the Python implementation closer to the C implementation by + ignoring all exceptions, not just ``AttributeError``, during (parts + of) interface adaptation. See `issue 163 + <https://github.com/zopefoundation/zope.interface/issues/163>`_. + +- Micro-optimization in ``.adapter._lookup`` , ``.adapter._lookupAll`` + and ``.adapter._subscriptions``: By loading ``components.get`` into + a local variable before entering the loop a bytcode "LOAD_FAST 0 + (components)" in the loop can be eliminated. In Plone, while running + all tests, average speedup of the "owntime" of ``_lookup`` is ~5x. + See `PR 167 + <https://github.com/zopefoundation/zope.interface/pull/167>`_. + +- Add ``__all__`` declarations to all modules. This helps tools that + do auto-completion and documentation and results in less cluttered + results. Wildcard ("*") are not recommended and may be affected. See + `issue 153 + <https://github.com/zopefoundation/zope.interface/issues/153>`_. + +- Fix ``verifyClass`` and ``verifyObject`` for builtin types like + ``dict`` that have methods taking an optional, unnamed argument with + no default value like ``dict.pop``. On PyPy3, the verification is + strict, but on PyPy2 (as on all versions of CPython) those methods + cannot be verified and are ignored. See `issue 118 + <https://github.com/zopefoundation/zope.interface/issues/118>`_. + +- Update the common interfaces ``IEnumerableMapping``, + ``IExtendedReadMapping``, ``IExtendedWriteMapping``, + ``IReadSequence`` and ``IUniqueMemberWriteSequence`` to no longer + require methods that were removed from Python 3 on Python 3, such as + ``__setslice___``. Now, ``dict``, ``list`` and ``tuple`` properly + verify as ``IFullMapping``, ``ISequence`` and ``IReadSequence,`` + respectively on all versions of Python. + +- Add human-readable ``__str___`` and ``__repr___`` to ``Attribute`` + and ``Method``. These contain the name of the defining interface + and the attribute. For methods, it also includes the signature. + +- Change the error strings raised by ``verifyObject`` and + ``verifyClass``. They now include more human-readable information + and exclude extraneous lines and spaces. See `issue 170 + <https://github.com/zopefoundation/zope.interface/issues/170>`_. + + .. caution:: This will break consumers (such as doctests) that + depended on the exact error messages. + +- Make ``verifyObject`` and ``verifyClass`` report all errors, if the + candidate object has multiple detectable violations. Previously they + reported only the first error. See `issue + <https://github.com/zopefoundation/zope.interface/issues/171>`_. + + Like the above, this will break consumers depending on the exact + output of error messages if more than one error is present. + +- Add ``zope.interface.common.collections``, + ``zope.interface.common.numbers``, and ``zope.interface.common.io``. + These modules define interfaces based on the ABCs defined in the + standard library ``collections.abc``, ``numbers`` and ``io`` + modules, respectively. Importing these modules will make the + standard library concrete classes that are registered with those + ABCs declare the appropriate interface. See `issue 138 + <https://github.com/zopefoundation/zope.interface/issues/138>`_. + +- Add ``zope.interface.common.builtins``. This module defines + interfaces of common builtin types, such as ``ITextString`` and + ``IByteString``, ``IDict``, etc. These interfaces extend the + appropriate interfaces from ``collections`` and ``numbers``, and the + standard library classes implement them after importing this module. + This is intended as a replacement for third-party packages like + `dolmen.builtins <https://pypi.org/project/dolmen.builtins/>`_. + See `issue 138 <https://github.com/zopefoundation/zope.interface/issues/138>`_. + +- Make ``providedBy()`` and ``implementedBy()`` respect ``super`` + objects. For instance, if class ``Derived`` implements ``IDerived`` + and extends ``Base`` which in turn implements ``IBase``, then + ``providedBy(super(Derived, derived))`` will return ``[IBase]``. + Previously it would have returned ``[IDerived]`` (in general, it + would previously have returned whatever would have been returned + without ``super``). + + Along with this change, adapter registries will unpack ``super`` + objects into their ``__self___`` before passing it to the factory. + Together, this means that ``component.getAdapter(super(Derived, + self), ITarget)`` is now meaningful. + + See `issue 11 <https://github.com/zopefoundation/zope.interface/issues/11>`_. + +- Fix a potential interpreter crash in the low-level adapter + registry lookup functions. See issue 11. + +- Adopt Python's standard `C3 resolution order + <https://www.python.org/download/releases/2.3/mro/>`_ to compute the + ``__iro__`` and ``__sro__`` of interfaces, with tweaks to support + additional cases that are common in interfaces but disallowed for + Python classes. Previously, an ad-hoc ordering that made no + particular guarantees was used. + + This has many beneficial properties, including the fact that base + interface and base classes tend to appear near the end of the + resolution order instead of the beginning. The resolution order in + general should be more predictable and consistent. + + .. caution:: + In some cases, especially with complex interface inheritance + trees or when manually providing or implementing interfaces, the + resulting IRO may be quite different. This may affect adapter + lookup. + + The C3 order enforces some constraints in order to be able to + guarantee a sensible ordering. Older versions of zope.interface did + not impose similar constraints, so it was possible to create + interfaces and declarations that are inconsistent with the C3 + constraints. In that event, zope.interface will still produce a + resolution order equal to the old order, but it won't be guaranteed + to be fully C3 compliant. In the future, strict enforcement of C3 + order may be the default. + + A set of environment variables and module constants allows + controlling several aspects of this new behaviour. It is possible to + request warnings about inconsistent resolution orders encountered, + and even to forbid them. Differences between the C3 resolution order + and the previous order can be logged, and, in extreme cases, the + previous order can still be used (this ability will be removed in + the future). For details, see the documentation for + ``zope.interface.ro``. + +- Make inherited tagged values in interfaces respect the resolution + order (``__iro__``), as method and attribute lookup does. Previously + tagged values could give inconsistent results. See `issue 190 + <https://github.com/zopefoundation/zope.interface/issues/190>`_. + +- Add ``getDirectTaggedValue`` (and related methods) to interfaces to + allow accessing tagged values irrespective of inheritance. See + `issue 190 + <https://github.com/zopefoundation/zope.interface/issues/190>`_. + +- Ensure that ``Interface`` is always the last item in the ``__iro__`` + and ``__sro__``. This is usually the case, but if classes that do + not implement any interfaces are part of a class inheritance + hierarchy, ``Interface`` could be assigned too high a priority. + See `issue 8 <https://github.com/zopefoundation/zope.interface/issues/8>`_. + +- Implement sorting, equality, and hashing in C for ``Interface`` + objects. In micro benchmarks, this makes those operations 40% to 80% + faster. This translates to a 20% speed up in querying adapters. + + Note that this changes certain implementation details. In + particular, ``InterfaceClass`` now has a non-default metaclass, and + it is enforced that ``__module__`` in instances of + ``InterfaceClass`` is read-only. + + See `PR 183 <https://github.com/zopefoundation/zope.interface/pull/183>`_. + + +4.7.2 (2020-03-10) +================== + +- Remove deprecated use of setuptools features. See `issue 30 + <https://github.com/zopefoundation/zope.interface/issues/30>`_. + + +4.7.1 (2019-11-11) +================== + +- Use Python 3 syntax in the documentation. See `issue 119 + <https://github.com/zopefoundation/zope.interface/issues/119>`_. + + +4.7.0 (2019-11-11) +================== + +- Drop support for Python 3.4. + +- Change ``queryTaggedValue``, ``getTaggedValue``, + ``getTaggedValueTags`` in interfaces. They now include inherited + values by following ``__bases__``. See `PR 144 + <https://github.com/zopefoundation/zope.interface/pull/144>`_. + + .. caution:: This may be a breaking change. + +- Add support for Python 3.8. + + +4.6.0 (2018-10-23) +================== + +- Add support for Python 3.7 + +- Fix ``verifyObject`` for class objects with staticmethods on + Python 3. See `issue 126 + <https://github.com/zopefoundation/zope.interface/issues/126>`_. + + +4.5.0 (2018-04-19) +================== + +- Drop support for 3.3, avoid accidental dependence breakage via setup.py. + See `PR 110 <https://github.com/zopefoundation/zope.interface/pull/110>`_. +- Allow registering and unregistering instance methods as listeners. + See `issue 12 <https://github.com/zopefoundation/zope.interface/issues/12>`_ + and `PR 102 <https://github.com/zopefoundation/zope.interface/pull/102>`_. +- Synchronize and simplify zope/__init__.py. See `issue 114 + <https://github.com/zopefoundation/zope.interface/issues/114>`_ + + +4.4.3 (2017-09-22) +================== + +- Avoid exceptions when the ``__annotations__`` attribute is added to + interface definitions with Python 3.x type hints. See `issue 98 + <https://github.com/zopefoundation/zope.interface/issues/98>`_. +- Fix the possibility of a rare crash in the C extension when + deallocating items. See `issue 100 + <https://github.com/zopefoundation/zope.interface/issues/100>`_. + + +4.4.2 (2017-06-14) +================== + +- Fix a regression storing + ``zope.component.persistentregistry.PersistentRegistry`` instances. + See `issue 85 <https://github.com/zopefoundation/zope.interface/issues/85>`_. + +- Fix a regression that could lead to the utility registration cache + of ``Components`` getting out of sync. See `issue 93 + <https://github.com/zopefoundation/zope.interface/issues/93>`_. + +4.4.1 (2017-05-13) +================== + +- Simplify the caching of utility-registration data. In addition to + simplification, avoids spurious test failures when checking for + leaks in tests with persistent registries. See `pull 84 + <https://github.com/zopefoundation/zope.interface/pull/84>`_. + +- Raise ``ValueError`` when non-text names are passed to adapter registry + methods: prevents corruption of lookup caches. + +4.4.0 (2017-04-21) +================== + +- Avoid a warning from the C compiler. + (https://github.com/zopefoundation/zope.interface/issues/71) + +- Add support for Python 3.6. + +4.3.3 (2016-12-13) +================== + +- Correct typos and ReST formatting errors in documentation. + +- Add API documentation for the adapter registry. + +- Ensure that the ``LICENSE.txt`` file is included in built wheels. + +- Fix C optimizations broken on Py3k. See the Python bug at: + http://bugs.python.org/issue15657 + (https://github.com/zopefoundation/zope.interface/issues/60) + + +4.3.2 (2016-09-05) +================== + +- Fix equality testing of ``implementedBy`` objects and proxies. + (https://github.com/zopefoundation/zope.interface/issues/55) + + +4.3.1 (2016-08-31) +================== + +- Support Components subclasses that are not hashable. + (https://github.com/zopefoundation/zope.interface/issues/53) + + +4.3.0 (2016-08-31) +================== + +- Add the ability to sort the objects returned by ``implementedBy``. + This is compatible with the way interface classes sort so they can + be used together in ordered containers like BTrees. + (https://github.com/zopefoundation/zope.interface/issues/42) + +- Make ``setuptools`` a hard dependency of ``setup.py``. + (https://github.com/zopefoundation/zope.interface/issues/13) + +- Change a linear algorithm (O(n)) in ``Components.registerUtility`` and + ``Components.unregisterUtility`` into a dictionary lookup (O(1)) for + hashable components. This substantially improves the time taken to + manipulate utilities in large registries at the cost of some + additional memory usage. (https://github.com/zopefoundation/zope.interface/issues/46) + + +4.2.0 (2016-06-10) +================== + +- Add support for Python 3.5 + +- Drop support for Python 2.6 and 3.2. + + +4.1.3 (2015-10-05) +================== + +- Fix installation without a C compiler on Python 3.5 + (https://github.com/zopefoundation/zope.interface/issues/24). + + +4.1.2 (2014-12-27) +================== + +- Add support for PyPy3. + +- Remove unittest assertions deprecated in Python3.x. + +- Add ``zope.interface.document.asReStructuredText``, which formats the + generated text for an interface using ReST double-backtick markers. + + +4.1.1 (2014-03-19) +================== + +- Add support for Python 3.4. + + +4.1.0 (2014-02-05) +================== + +- Update ``boostrap.py`` to version 2.2. + +- Add ``@named(name)`` declaration, that specifies the component name, so it + does not have to be passed in during registration. + + +4.0.5 (2013-02-28) +================== + +- Fix a bug where a decorated method caused false positive failures on + ``verifyClass()``. + + +4.0.4 (2013-02-21) +================== + +- Fix a bug that was revealed by porting zope.traversing. During a loop, the + loop body modified a weakref dict causing a ``RuntimeError`` error. + +4.0.3 (2012-12-31) +================== + +- Fleshed out PyPI Trove classifiers. + +4.0.2 (2012-11-21) +================== + +- Add support for Python 3.3. + +- Restored ability to install the package in the absence of ``setuptools``. + +- LP #1055223: Fix test which depended on dictionary order and failed randomly + in Python 3.3. + +4.0.1 (2012-05-22) +================== + +- Drop explicit ``DeprecationWarnings`` for "class advice" APIS (these + APIs are still deprecated under Python 2.x, and still raise an exception + under Python 3.x, but no longer cause a warning to be emitted under + Python 2.x). + +4.0.0 (2012-05-16) +================== + +- Automated build of Sphinx HTML docs and running doctest snippets via tox. + +- Deprecate the "class advice" APIs from ``zope.interface.declarations``: + ``implements``, ``implementsOnly``, and ``classProvides``. In their place, + prefer the equivalent class decorators: ``@implementer``, + ``@implementer_only``, and ``@provider``. Code which uses the deprecated + APIs will not work as expected under Py3k. + +- Remove use of '2to3' and associated fixers when installing under Py3k. + The code is now in a "compatible subset" which supports Python 2.6, 2.7, + and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language + spec). + +- Drop explicit support for Python 2.4 / 2.5 / 3.1. + +- Add support for PyPy. + +- Add support for continuous integration using ``tox`` and ``jenkins``. + +- Add 'setup.py dev' alias (runs ``setup.py develop`` plus installs + ``nose`` and ``coverage``). + +- Add 'setup.py docs' alias (installs ``Sphinx`` and dependencies). + +- Replace all unittest coverage previously accomplished via doctests with + unittests. The doctests have been moved into a ``docs`` section, managed + as a Sphinx collection. + +- LP #910987: Ensure that the semantics of the ``lookup`` method of + ``zope.interface.adapter.LookupBase`` are the same in both the C and + Python implementations. + +- LP #900906: Avoid exceptions due to tne new ``__qualname__`` attribute + added in Python 3.3 (see PEP 3155 for rationale). Thanks to Antoine + Pitrou for the patch. + +3.8.0 (2011-09-22) +================== + +- New module ``zope.interface.registry``. This is code moved from + ``zope.component.registry`` which implements a basic nonperistent component + registry as ``zope.interface.registry.Components``. This class was moved + from ``zope.component`` to make porting systems (such as Pyramid) that rely + only on a basic component registry to Python 3 possible without needing to + port the entirety of the ``zope.component`` package. Backwards + compatibility import shims have been left behind in ``zope.component``, so + this change will not break any existing code. + +- New ``tests_require`` dependency: ``zope.event`` to test events sent by + Components implementation. The ``zope.interface`` package does not have a + hard dependency on ``zope.event``, but if ``zope.event`` is importable, it + will send component registration events when methods of an instance of + ``zope.interface.registry.Components`` are called. + +- New interfaces added to support ``zope.interface.registry.Components`` + addition: ``ComponentLookupError``, ``Invalid``, ``IObjectEvent``, + ``ObjectEvent``, ``IComponentLookup``, ``IRegistration``, + ``IUtilityRegistration``, ``IAdapterRegistration``, + ``ISubscriptionAdapterRegistration``, ``IHandlerRegistration``, + ``IRegistrationEvent``, ``RegistrationEvent``, ``IRegistered``, + ``Registered``, ``IUnregistered``, ``Unregistered``, + ``IComponentRegistry``, and ``IComponents``. + +- No longer Python 2.4 compatible (tested under 2.5, 2.6, 2.7, and 3.2). + +3.7.0 (2011-08-13) +================== + +- Move changes from 3.6.2 - 3.6.5 to a new 3.7.x release line. + +3.6.7 (2011-08-20) +================== + +- Fix sporadic failures on x86-64 platforms in tests of rich comparisons + of interfaces. + +3.6.6 (2011-08-13) +================== + +- LP #570942: Now correctly compare interfaces from different modules but + with the same names. + + N.B.: This is a less intrusive / destabilizing fix than the one applied in + 3.6.3: we only fix the underlying cmp-alike function, rather than adding + the other "rich comparison" functions. + +- Revert to software as released with 3.6.1 for "stable" 3.6 release branch. + +3.6.5 (2011-08-11) +================== + +- LP #811792: work around buggy behavior in some subclasses of + ``zope.interface.interface.InterfaceClass``, which invoke ``__hash__`` + before initializing ``__module__`` and ``__name__``. The workaround + returns a fixed constant hash in such cases, and issues a ``UserWarning``. + +- LP #804832: Under PyPy, ``zope.interface`` should not build its C + extension. Also, prevent attempting to build it under Jython. + +- Add a tox.ini for easier xplatform testing. + +- Fix testing deprecation warnings issued when tested under Py3K. + +3.6.4 (2011-07-04) +================== + +- LP 804951: InterfaceClass instances were unhashable under Python 3.x. + +3.6.3 (2011-05-26) +================== + +- LP #570942: Now correctly compare interfaces from different modules but + with the same names. + +3.6.2 (2011-05-17) +================== + +- Moved detailed documentation out-of-line from PyPI page, linking instead to + http://docs.zope.org/zope.interface . + +- Fixes for small issues when running tests under Python 3.2 using + ``zope.testrunner``. + +- LP # 675064: Specify return value type for C optimizations module init + under Python 3: undeclared value caused warnings, and segfaults on some + 64 bit architectures. + +- setup.py now raises RuntimeError if you don't have Distutils installed when + running under Python 3. + +3.6.1 (2010-05-03) +================== + +- A non-ASCII character in the changelog made 3.6.0 uninstallable on + Python 3 systems with another default encoding than UTF-8. + +- Fix compiler warnings under GCC 4.3.3. + +3.6.0 (2010-04-29) +================== + +- LP #185974: Clear the cache used by ``Specificaton.get`` inside + ``Specification.changed``. Thanks to Jacob Holm for the patch. + +- Add support for Python 3.1. Contributors: + + Lennart Regebro + Martin v Loewis + Thomas Lotze + Wolfgang Schnerring + + The 3.1 support is completely backwards compatible. However, the implements + syntax used under Python 2.X does not work under 3.X, since it depends on + how metaclasses are implemented and this has changed. Instead it now supports + a decorator syntax (also under Python 2.X):: + + class Foo: + implements(IFoo) + ... + + can now also be written:: + + @implementer(IFoo): + class Foo: + ... + + There are 2to3 fixers available to do this change automatically in the + zope.fixers package. + +- Python 2.3 is no longer supported. + + +3.5.4 (2009-12-23) +================== + +- Use the standard Python doctest module instead of zope.testing.doctest, which + has been deprecated. + + +3.5.3 (2009-12-08) +================== + +- Fix an edge case: make providedBy() work when a class has '__provides__' in + its __slots__ (see http://thread.gmane.org/gmane.comp.web.zope.devel/22490) + + +3.5.2 (2009-07-01) +================== + +- BaseAdapterRegistry.unregister, unsubscribe: Remove empty portions of + the data structures when something is removed. This avoids leaving + references to global objects (interfaces) that may be slated for + removal from the calling application. + + +3.5.1 (2009-03-18) +================== + +- verifyObject: use getattr instead of hasattr to test for object attributes + in order to let exceptions other than AttributeError raised by properties + propagate to the caller + +- Add Sphinx-based documentation building to the package buildout + configuration. Use the ``bin/docs`` command after buildout. + +- Improve package description a bit. Unify changelog entries formatting. + +- Change package's mailing list address to zope-dev at zope.org as + zope3-dev at zope.org is now retired. + + +3.5.0 (2008-10-26) +================== + +- Fix declaration of _zope_interface_coptimizations, it's not a top level + package. + +- Add a DocTestSuite for odd.py module, so their tests are run. + +- Allow to bootstrap on Jython. + +- Fix https://bugs.launchpad.net/zope3/3.3/+bug/98388: ISpecification + was missing a declaration for __iro__. + +- Add optional code optimizations support, which allows the building + of C code optimizations to fail (Jython). + +- Replace `_flatten` with a non-recursive implementation, effectively making + it 3x faster. + + +3.4.1 (2007-10-02) +================== + +- Fix a setup bug that prevented installation from source on systems + without setuptools. + + +3.4.0 (2007-07-19) +================== + +- Final release for 3.4.0. + + +3.4.0b3 (2007-05-22) +==================== + + +- When checking whether an object is already registered, use identity + comparison, to allow adding registering with picky custom comparison methods. + + +3.3.0.1 (2007-01-03) +==================== + +- Made a reference to OverflowWarning, which disappeared in Python + 2.5, conditional. + + +3.3.0 (2007/01/03) +================== + +New Features +------------ + +- Refactor the adapter-lookup algorithim to make it much simpler and faster. + + Also, implement more of the adapter-lookup logic in C, making + debugging of application code easier, since there is less + infrastructre code to step through. + +- Treat objects without interface declarations as if they + declared that they provide ``zope.interface.Interface``. + +- Add a number of richer new adapter-registration interfaces + that provide greater control and introspection. + +- Add a new interface decorator to zope.interface that allows the + setting of tagged values on an interface at definition time (see + zope.interface.taggedValue). + +Bug Fixes +--------- + +- A bug in multi-adapter lookup sometimes caused incorrect adapters to + be returned. + + +3.2.0.2 (2006-04-15) +==================== + +- Fix packaging bug: 'package_dir' must be a *relative* path. + + +3.2.0.1 (2006-04-14) +==================== + +- Packaging change: suppress inclusion of 'setup.cfg' in 'sdist' builds. + + +3.2.0 (2006-01-05) +================== + +- Corresponds to the version of the zope.interface package shipped as part of + the Zope 3.2.0 release. + + +3.1.0 (2005-10-03) +================== + +- Corresponds to the version of the zope.interface package shipped as part of + the Zope 3.1.0 release. + +- Made attribute resolution order consistent with component lookup order, + i.e. new-style class MRO semantics. + +- Deprecate 'isImplementedBy' and 'isImplementedByInstancesOf' APIs in + favor of 'implementedBy' and 'providedBy'. + + +3.0.1 (2005-07-27) +================== + +- Corresponds to the version of the zope.interface package shipped as part of + the Zope X3.0.1 release. + +- Fix a bug reported by James Knight, which caused adapter registries + to fail occasionally to reflect declaration changes. + + +3.0.0 (2004-11-07) +================== + +- Corresponds to the version of the zope.interface package shipped as part of + the Zope X3.0.0 release. diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/RECORD new file mode 100644 index 00000000..cfbc2a96 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/RECORD @@ -0,0 +1,110 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/_compat.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/_flatten.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/adapter.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/advice.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/builtins.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/collections.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/idatetime.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/interfaces.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/io.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/mapping.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/numbers.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/sequence.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/basemapping.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_builtins.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_collections.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_idatetime.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_import_interfaces.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_io.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_numbers.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/declarations.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/document.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/exceptions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/interface.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/interfaces.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/registry.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/ro.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/advisory_testing.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/dummy.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/idummy.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/m1.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/odd.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_adapter.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_advice.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_compile_flags.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_declarations.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_document.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_element.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_exceptions.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interface.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interfaces.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_odd_declarations.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_registry.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_ro.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_sorting.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_verify.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/zope/interface/verify.cpython-39.pyc,, +zope.interface-6.1-py3.9-nspkg.pth,sha256=SWEVH-jEWsKYrL0qoC6GBJaStx_iKxGoAY9PQycFVC4,529 +zope.interface-6.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +zope.interface-6.1.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070 +zope.interface-6.1.dist-info/METADATA,sha256=Kfvg65yPd2T3IyqaccKo0-RI31sQzjlPX1Wby7fbnt8,41699 +zope.interface-6.1.dist-info/RECORD,, +zope.interface-6.1.dist-info/WHEEL,sha256=RXcaVXR1VzLQNykyQkOwdYMhFRpSIriy9vgf0qPtPa0,108 +zope.interface-6.1.dist-info/namespace_packages.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5 +zope.interface-6.1.dist-info/top_level.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5 +zope/interface/__init__.py,sha256=7Ob9s9vBYst9JHP798YhLkKjENnp2fWoU1o1HpBdhEA,3463 +zope/interface/_compat.py,sha256=INsHdSwp4imu-1CL552I3S79YRSDCloB1J0x17PEHvw,4369 +zope/interface/_flatten.py,sha256=nY3YJjWfeslmcWfjfxVYkoZb2lFrVGbw30xF_sAyQ60,1056 +zope/interface/_zope_interface_coptimizations.c,sha256=y3uYh6x9FEaygkgpfxyuiEkN3Yf_xrBVUH9w7aeHjxw,57678 +zope/interface/_zope_interface_coptimizations.cpython-39-darwin.so,sha256=ziqNFTC9joPM87-Y9-PS9ArcU8YRQ1S0E6UD6ngtdzA,77904 +zope/interface/adapter.py,sha256=A8XBjmXGLrpWapfJE5wURin5AunYsiZEa3wfF8jxqiY,36218 +zope/interface/advice.py,sha256=vbguNfFU4SPqT9MoraePAIlqwAz65vvqfJcVbYXg3h4,3890 +zope/interface/common/__init__.py,sha256=INMzX7PUMD15FoLxdPQQaHDDamU0b29VmUL8lAAdq-I,10461 +zope/interface/common/builtins.py,sha256=CDLOD5FMyDH6_kKdEgwNC4CIBCar4HPUlaXNQ-yXXRg,3027 +zope/interface/common/collections.py,sha256=CInuuT93KpS97UwNAiU489CM0IlUdewYRuGdmVFut9s,6792 +zope/interface/common/idatetime.py,sha256=FS1ksWeQSxq4K31ah0I0eXhOf_qT5Jg0jKMapOC2vE0,20858 +zope/interface/common/interfaces.py,sha256=pRfzmB8uLCL02TtbxSVswRYDrhSXo4e50larc__UhyU,5367 +zope/interface/common/io.py,sha256=TkO9ctZmZr-_5Ae6iHIU4iZN7CHjpVdrs7aaQz8N5Tc,1241 +zope/interface/common/mapping.py,sha256=FJ0lWWGoKBAVL7KUum4tW8QXRsmyOSbAN8SyN1jq0p0,4677 +zope/interface/common/numbers.py,sha256=D4kUnF5OgAk6CKcxaW86VH_OPLh1OXt_cF6WaOfvjLk,1682 +zope/interface/common/sequence.py,sha256=TL8A4xoxAimqzARmEXO_04uQh2sOERjxmUpJJl_xWeU,5525 +zope/interface/common/tests/__init__.py,sha256=cN-iLusqVi2gDvhXJCWkcjDU9_k-5bd7ZuQ92I1ujR4,5310 +zope/interface/common/tests/basemapping.py,sha256=67rNaBDL0Bj6IvM_4nJ-mCmAslKSKxiwpvki9QTbtXI,3906 +zope/interface/common/tests/test_builtins.py,sha256=slmlaiZjaZJXjplCEaWXAaUFaWW6bcK3z8Je7al5mdE,1345 +zope/interface/common/tests/test_collections.py,sha256=MJk8KcAQYVkhY7ygUXmfJxYd5s4eXoHcvTekQzHvpJE,5724 +zope/interface/common/tests/test_idatetime.py,sha256=LoyLA7wgDrma8U3AOwQeZtTpwZMRtdsqEkDLFN4u8rA,1594 +zope/interface/common/tests/test_import_interfaces.py,sha256=_x5QozzgaVN5YvhG7k2GpDnld11SLwsWYfNjCqd0phw,812 +zope/interface/common/tests/test_io.py,sha256=_VR8u92CjLYMkeVGz08SCDhRsZoxWcPU-uXuNDhBhbU,1597 +zope/interface/common/tests/test_numbers.py,sha256=CEQxxOfmxDDmAym15gnGd8wtGnC7tMG94_d3L0m_lqc,1394 +zope/interface/declarations.py,sha256=Wrow3Nova7vIo11B1mry5teKFVRFsiiAxwiK7e7H_Sc,43006 +zope/interface/document.py,sha256=6tgPd57kEJayTX4JzsC5RkB3-hROGMPgVTC6FBiESMM,4067 +zope/interface/exceptions.py,sha256=DIBkWoz1cxxg6uJE6N1yWeWHEk4KpT0JILGYkNh1ZpU,8635 +zope/interface/interface.py,sha256=uLKz-b7OAaxt_mgtzofotMc8PSdqh14tP6H99MS__do,38825 +zope/interface/interfaces.py,sha256=XRzm0qQ1vRfbixD9shAAJd9m-nridMHwflTrwZzypOU,50125 +zope/interface/registry.py,sha256=TzXHUhpZCV8HPUq2WTInFJSDraBGXYzS-Fo_ORDQgQ4,25828 +zope/interface/ro.py,sha256=RBPne6B8hwf9rSHTEWKwsIXPzZVTOmdg3t7aLFANZHw,24155 +zope/interface/tests/__init__.py,sha256=2sMjAaqsnDB5aCcIIkz9lXeivO1Cpbo78GeV7qYfjgY,3961 +zope/interface/tests/advisory_testing.py,sha256=0GMNyS4DHcnY6cPOxY7UYYWCtVsBxJTkoOS6KNzqPZM,897 +zope/interface/tests/dummy.py,sha256=80FPlPOyoshfHF1jFFpeYIyn_15z5MVVfLVf4irpNQU,911 +zope/interface/tests/idummy.py,sha256=Hc-iM7RwEzcVp7znPx7yMmFwERQXhBGeRQsmKIPfkns,889 +zope/interface/tests/m1.py,sha256=uEUxuYj_3ZVSF2yeNnHbcFX0Kyj_FFzUAM5O-gbcsMs,812 +zope/interface/tests/odd.py,sha256=DITySuFOf7f1ERI7qWGcosW98AO6-MvLoOAawsz07N8,3015 +zope/interface/tests/test_adapter.py,sha256=MyfMHn4lfTzUA2w9UMPMCiZ2Q9fJkyEe3eR2odkVRfY,79548 +zope/interface/tests/test_advice.py,sha256=hSrsMG09u3lY5RbyAEYxQxD73Hp3QqvwjeX8lBW5D2U,5962 +zope/interface/tests/test_compile_flags.py,sha256=wU3vtmqgzll6HMPbzFErMpORoVghrcZ5krIV4x6rfo4,1290 +zope/interface/tests/test_declarations.py,sha256=sjdX2fU3zMbSo8cLdU5M8HyhewaabRvTO2VCLbuK3Ec,82128 +zope/interface/tests/test_document.py,sha256=P3AsX3KrVz3xyjVlqyJqkdJivDLrN3Vue0SgsqYbisk,16899 +zope/interface/tests/test_element.py,sha256=HgaP7r-M2odSPVTCbby3HQADJIBIJbYmDjK01ErwkZk,1118 +zope/interface/tests/test_exceptions.py,sha256=tpJ-XFO7zPU_VHQIT8sfAeObfskdvHnyGTw8OIGdWOU,6411 +zope/interface/tests/test_interface.py,sha256=NX9-duWPWL8cvNlCp93O9_m8lqH8uXBbe9DfTSRI8Zw,91465 +zope/interface/tests/test_interfaces.py,sha256=d8tvF4Wiof7TrZ9Em85z23oMDyHqV4jCpYGtzsRMSVE,4377 +zope/interface/tests/test_odd_declarations.py,sha256=G_b3-iAG5Q95JixsMic_QlA3BW314ynjrWgPoemonzY,7565 +zope/interface/tests/test_registry.py,sha256=znF4zGxMOk2E0JWkeO4oBFfJ3CeC38F6dpRb17UPi24,112819 +zope/interface/tests/test_ro.py,sha256=qpEx-YXiunA3lsE6xUjo6b1SDmabNWBuIx1p8Paa96k,14121 +zope/interface/tests/test_sorting.py,sha256=fJ8-V-cQJhb77YGbO0H_qbHCZKdPFALf-eD_o6IknIA,1933 +zope/interface/tests/test_verify.py,sha256=-S3R2TI3_XrQTkaRSBYal1OBTITryLLiKLtBglnJbBw,19190 +zope/interface/verify.py,sha256=yMIXl5GSyRDCFjMe6RDiB0diGzHw9i-IEJh85jki6Ns,7154 diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/WHEEL new file mode 100644 index 00000000..e834d608 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp39-cp39-macosx_11_0_arm64 + diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/namespace_packages.txt b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/namespace_packages.txt new file mode 100644 index 00000000..66179d49 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/namespace_packages.txt @@ -0,0 +1 @@ +zope diff --git a/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/top_level.txt new file mode 100644 index 00000000..66179d49 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope.interface-6.1.dist-info/top_level.txt @@ -0,0 +1 @@ +zope diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/__init__.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/__init__.py new file mode 100644 index 00000000..17a272f1 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/__init__.py @@ -0,0 +1,93 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Interfaces + +This package implements the Python "scarecrow" proposal. + +The package exports two objects, `Interface` and `Attribute` directly. It also +exports several helper methods. Interface is used to create an interface with +a class statement, as in: + + class IMyInterface(Interface): + '''Interface documentation + ''' + + def meth(arg1, arg2): + '''Documentation for meth + ''' + + # Note that there is no self argument + +To find out what you can do with interfaces, see the interface +interface, `IInterface` in the `interfaces` module. + +The package has several public modules: + + o `declarations` provides utilities to declare interfaces on objects. It + also provides a wide range of helpful utilities that aid in managing + declared interfaces. Most of its public names are however imported here. + + o `document` has a utility for documenting an interface as structured text. + + o `exceptions` has the interface-defined exceptions + + o `interfaces` contains a list of all public interfaces for this package. + + o `verify` has utilities for verifying implementations of interfaces. + +See the module doc strings for more information. +""" +__docformat__ = 'restructuredtext' +# pylint:disable=wrong-import-position,unused-import +from zope.interface.interface import Interface +from zope.interface.interface import _wire + +# Need to actually get the interface elements to implement the right interfaces +_wire() +del _wire + +from zope.interface.declarations import Declaration +from zope.interface.declarations import alsoProvides +from zope.interface.declarations import classImplements +from zope.interface.declarations import classImplementsFirst +from zope.interface.declarations import classImplementsOnly +from zope.interface.declarations import directlyProvidedBy +from zope.interface.declarations import directlyProvides +from zope.interface.declarations import implementedBy +from zope.interface.declarations import implementer +from zope.interface.declarations import implementer_only +from zope.interface.declarations import moduleProvides +from zope.interface.declarations import named +from zope.interface.declarations import noLongerProvides +from zope.interface.declarations import providedBy +from zope.interface.declarations import provider + +from zope.interface.exceptions import Invalid + +from zope.interface.interface import Attribute +from zope.interface.interface import interfacemethod +from zope.interface.interface import invariant +from zope.interface.interface import taggedValue + +# The following are to make spec pickles cleaner +from zope.interface.declarations import Provides + + +from zope.interface.interfaces import IInterfaceDeclaration + +moduleProvides(IInterfaceDeclaration) + +__all__ = ('Interface', 'Attribute') + tuple(IInterfaceDeclaration) + +assert all(k in globals() for k in __all__) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/_compat.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_compat.py new file mode 100644 index 00000000..2ff8d83e --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_compat.py @@ -0,0 +1,135 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" +Support functions for dealing with differences in platforms, including Python +versions and implementations. + +This file should have no imports from the rest of zope.interface because it is +used during early bootstrapping. +""" +import os +import sys + + +def _normalize_name(name): + if isinstance(name, bytes): + name = str(name, 'ascii') + if isinstance(name, str): + return name + raise TypeError("name must be a string or ASCII-only bytes") + +PYPY = hasattr(sys, 'pypy_version_info') + + +def _c_optimizations_required(): + """ + Return a true value if the C optimizations are required. + + This uses the ``PURE_PYTHON`` variable as documented in `_use_c_impl`. + """ + pure_env = os.environ.get('PURE_PYTHON') + require_c = pure_env == "0" + return require_c + + +def _c_optimizations_available(): + """ + Return the C optimization module, if available, otherwise + a false value. + + If the optimizations are required but not available, this + raises the ImportError. + + This does not say whether they should be used or not. + """ + catch = () if _c_optimizations_required() else (ImportError,) + try: + from zope.interface import _zope_interface_coptimizations as c_opt + return c_opt + except catch: # pragma: no cover (only Jython doesn't build extensions) + return False + + +def _c_optimizations_ignored(): + """ + The opposite of `_c_optimizations_required`. + """ + pure_env = os.environ.get('PURE_PYTHON') + return pure_env is not None and pure_env != "0" + + +def _should_attempt_c_optimizations(): + """ + Return a true value if we should attempt to use the C optimizations. + + This takes into account whether we're on PyPy and the value of the + ``PURE_PYTHON`` environment variable, as defined in `_use_c_impl`. + """ + is_pypy = hasattr(sys, 'pypy_version_info') + + if _c_optimizations_required(): + return True + if is_pypy: + return False + return not _c_optimizations_ignored() + + +def _use_c_impl(py_impl, name=None, globs=None): + """ + Decorator. Given an object implemented in Python, with a name like + ``Foo``, import the corresponding C implementation from + ``zope.interface._zope_interface_coptimizations`` with the name + ``Foo`` and use it instead. + + If the ``PURE_PYTHON`` environment variable is set to any value + other than ``"0"``, or we're on PyPy, ignore the C implementation + and return the Python version. If the C implementation cannot be + imported, return the Python version. If ``PURE_PYTHON`` is set to + 0, *require* the C implementation (let the ImportError propagate); + note that PyPy can import the C implementation in this case (and all + tests pass). + + In all cases, the Python version is kept available. in the module + globals with the name ``FooPy`` and the name ``FooFallback`` (both + conventions have been used; the C implementation of some functions + looks for the ``Fallback`` version, as do some of the Sphinx + documents). + + Example:: + + @_use_c_impl + class Foo(object): + ... + """ + name = name or py_impl.__name__ + globs = globs or sys._getframe(1).f_globals + + def find_impl(): + if not _should_attempt_c_optimizations(): + return py_impl + + c_opt = _c_optimizations_available() + if not c_opt: # pragma: no cover (only Jython doesn't build extensions) + return py_impl + + __traceback_info__ = c_opt + return getattr(c_opt, name) + + c_impl = find_impl() + # Always make available by the FooPy name and FooFallback + # name (for testing and documentation) + globs[name + 'Py'] = py_impl + globs[name + 'Fallback'] = py_impl + + return c_impl diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/_flatten.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_flatten.py new file mode 100644 index 00000000..a80c2de4 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_flatten.py @@ -0,0 +1,35 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Adapter-style interface registry + +See Adapter class. +""" +from zope.interface import Declaration + +def _flatten(implements, include_None=0): + + try: + r = implements.flattened() + except AttributeError: + if implements is None: + r=() + else: + r = Declaration(implements).flattened() + + if not include_None: + return r + + r = list(r) + r.append(None) + return r diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.c b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.c new file mode 100644 index 00000000..91899283 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.c @@ -0,0 +1,2101 @@ +/*########################################################################### + # + # Copyright (c) 2003 Zope Foundation and Contributors. + # All Rights Reserved. + # + # This software is subject to the provisions of the Zope Public License, + # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. + # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED + # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS + # FOR A PARTICULAR PURPOSE. + # + ############################################################################*/ + +#include "Python.h" +#include "structmember.h" + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif + +#define TYPE(O) ((PyTypeObject*)(O)) +#define OBJECT(O) ((PyObject*)(O)) +#define CLASSIC(O) ((PyClassObject*)(O)) +#ifndef PyVarObject_HEAD_INIT +#define PyVarObject_HEAD_INIT(a, b) PyObject_HEAD_INIT(a) b, +#endif +#ifndef Py_TYPE +#define Py_TYPE(o) ((o)->ob_type) +#endif + +#define PyNative_FromString PyUnicode_FromString + +static PyObject *str__dict__, *str__implemented__, *strextends; +static PyObject *BuiltinImplementationSpecifications, *str__provides__; +static PyObject *str__class__, *str__providedBy__; +static PyObject *empty, *fallback; +static PyObject *str__conform__, *str_call_conform, *adapter_hooks; +static PyObject *str_uncached_lookup, *str_uncached_lookupAll; +static PyObject *str_uncached_subscriptions; +static PyObject *str_registry, *strro, *str_generation, *strchanged; +static PyObject *str__self__; +static PyObject *str__module__; +static PyObject *str__name__; +static PyObject *str__adapt__; +static PyObject *str_CALL_CUSTOM_ADAPT; + +static PyTypeObject *Implements; + +static int imported_declarations = 0; + +static int +import_declarations(void) +{ + PyObject *declarations, *i; + + declarations = PyImport_ImportModule("zope.interface.declarations"); + if (declarations == NULL) + return -1; + + BuiltinImplementationSpecifications = PyObject_GetAttrString( + declarations, "BuiltinImplementationSpecifications"); + if (BuiltinImplementationSpecifications == NULL) + return -1; + + empty = PyObject_GetAttrString(declarations, "_empty"); + if (empty == NULL) + return -1; + + fallback = PyObject_GetAttrString(declarations, "implementedByFallback"); + if (fallback == NULL) + return -1; + + + + i = PyObject_GetAttrString(declarations, "Implements"); + if (i == NULL) + return -1; + + if (! PyType_Check(i)) + { + PyErr_SetString(PyExc_TypeError, + "zope.interface.declarations.Implements is not a type"); + return -1; + } + + Implements = (PyTypeObject *)i; + + Py_DECREF(declarations); + + imported_declarations = 1; + return 0; +} + + +static PyTypeObject SpecificationBaseType; /* Forward */ + +static PyObject * +implementedByFallback(PyObject *cls) +{ + if (imported_declarations == 0 && import_declarations() < 0) + return NULL; + + return PyObject_CallFunctionObjArgs(fallback, cls, NULL); +} + +static PyObject * +implementedBy(PyObject *ignored, PyObject *cls) +{ + /* Fast retrieval of implements spec, if possible, to optimize + common case. Use fallback code if we get stuck. + */ + + PyObject *dict = NULL, *spec; + + if (PyObject_TypeCheck(cls, &PySuper_Type)) + { + // Let merging be handled by Python. + return implementedByFallback(cls); + } + + if (PyType_Check(cls)) + { + dict = TYPE(cls)->tp_dict; + Py_XINCREF(dict); + } + + if (dict == NULL) + dict = PyObject_GetAttr(cls, str__dict__); + + if (dict == NULL) + { + /* Probably a security proxied class, use more expensive fallback code */ + PyErr_Clear(); + return implementedByFallback(cls); + } + + spec = PyObject_GetItem(dict, str__implemented__); + Py_DECREF(dict); + if (spec) + { + if (imported_declarations == 0 && import_declarations() < 0) + return NULL; + + if (PyObject_TypeCheck(spec, Implements)) + return spec; + + /* Old-style declaration, use more expensive fallback code */ + Py_DECREF(spec); + return implementedByFallback(cls); + } + + PyErr_Clear(); + + /* Maybe we have a builtin */ + if (imported_declarations == 0 && import_declarations() < 0) + return NULL; + + spec = PyDict_GetItem(BuiltinImplementationSpecifications, cls); + if (spec != NULL) + { + Py_INCREF(spec); + return spec; + } + + /* We're stuck, use fallback */ + return implementedByFallback(cls); +} + +static PyObject * +getObjectSpecification(PyObject *ignored, PyObject *ob) +{ + PyObject *cls, *result; + + result = PyObject_GetAttr(ob, str__provides__); + if (!result) + { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + { + /* Propagate non AttributeError exceptions. */ + return NULL; + } + PyErr_Clear(); + } + else + { + int is_instance = -1; + is_instance = PyObject_IsInstance(result, (PyObject*)&SpecificationBaseType); + if (is_instance < 0) + { + /* Propagate all errors */ + return NULL; + } + if (is_instance) + { + return result; + } + } + + /* We do a getattr here so as not to be defeated by proxies */ + cls = PyObject_GetAttr(ob, str__class__); + if (cls == NULL) + { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + { + /* Propagate non-AttributeErrors */ + return NULL; + } + PyErr_Clear(); + if (imported_declarations == 0 && import_declarations() < 0) + return NULL; + + Py_INCREF(empty); + return empty; + } + result = implementedBy(NULL, cls); + Py_DECREF(cls); + + return result; +} + +static PyObject * +providedBy(PyObject *ignored, PyObject *ob) +{ + PyObject *result, *cls, *cp; + int is_instance = -1; + result = NULL; + + is_instance = PyObject_IsInstance(ob, (PyObject*)&PySuper_Type); + if (is_instance < 0) + { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + { + /* Propagate non-AttributeErrors */ + return NULL; + } + PyErr_Clear(); + } + if (is_instance) + { + return implementedBy(NULL, ob); + } + + result = PyObject_GetAttr(ob, str__providedBy__); + + if (result == NULL) + { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + { + return NULL; + } + + PyErr_Clear(); + return getObjectSpecification(NULL, ob); + } + + + /* We want to make sure we have a spec. We can't do a type check + because we may have a proxy, so we'll just try to get the + only attribute. + */ + if (PyObject_TypeCheck(result, &SpecificationBaseType) + || + PyObject_HasAttr(result, strextends) + ) + return result; + + /* + The object's class doesn't understand descriptors. + Sigh. We need to get an object descriptor, but we have to be + careful. We want to use the instance's __provides__,l if + there is one, but only if it didn't come from the class. + */ + Py_DECREF(result); + + cls = PyObject_GetAttr(ob, str__class__); + if (cls == NULL) + return NULL; + + result = PyObject_GetAttr(ob, str__provides__); + if (result == NULL) + { + /* No __provides__, so just fall back to implementedBy */ + PyErr_Clear(); + result = implementedBy(NULL, cls); + Py_DECREF(cls); + return result; + } + + cp = PyObject_GetAttr(cls, str__provides__); + if (cp == NULL) + { + /* The the class has no provides, assume we're done: */ + PyErr_Clear(); + Py_DECREF(cls); + return result; + } + + if (cp == result) + { + /* + Oops, we got the provides from the class. This means + the object doesn't have it's own. We should use implementedBy + */ + Py_DECREF(result); + result = implementedBy(NULL, cls); + } + + Py_DECREF(cls); + Py_DECREF(cp); + + return result; +} + +typedef struct { + PyObject_HEAD + PyObject* weakreflist; + /* + In the past, these fields were stored in the __dict__ + and were technically allowed to contain any Python object, though + other type checks would fail or fall back to generic code paths if + they didn't have the expected type. We preserve that behaviour and don't + make any assumptions about contents. + */ + PyObject* _implied; + /* + The remainder aren't used in C code but must be stored here + to prevent instance layout conflicts. + */ + PyObject* _dependents; + PyObject* _bases; + PyObject* _v_attrs; + PyObject* __iro__; + PyObject* __sro__; +} Spec; + +/* + We know what the fields are *supposed* to define, but + they could have anything, so we need to traverse them. +*/ +static int +Spec_traverse(Spec* self, visitproc visit, void* arg) +{ + Py_VISIT(self->_implied); + Py_VISIT(self->_dependents); + Py_VISIT(self->_bases); + Py_VISIT(self->_v_attrs); + Py_VISIT(self->__iro__); + Py_VISIT(self->__sro__); + return 0; +} + +static int +Spec_clear(Spec* self) +{ + Py_CLEAR(self->_implied); + Py_CLEAR(self->_dependents); + Py_CLEAR(self->_bases); + Py_CLEAR(self->_v_attrs); + Py_CLEAR(self->__iro__); + Py_CLEAR(self->__sro__); + return 0; +} + +static void +Spec_dealloc(Spec* self) +{ + /* PyType_GenericAlloc that you get when you don't + specify a tp_alloc always tracks the object. */ + PyObject_GC_UnTrack((PyObject *)self); + if (self->weakreflist != NULL) { + PyObject_ClearWeakRefs(OBJECT(self)); + } + Spec_clear(self); + Py_TYPE(self)->tp_free(OBJECT(self)); +} + +static PyObject * +Spec_extends(Spec *self, PyObject *other) +{ + PyObject *implied; + + implied = self->_implied; + if (implied == NULL) { + return NULL; + } + + if (PyDict_GetItem(implied, other) != NULL) + Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + +static char Spec_extends__doc__[] = +"Test whether a specification is or extends another" +; + +static char Spec_providedBy__doc__[] = +"Test whether an interface is implemented by the specification" +; + +static PyObject * +Spec_call(Spec *self, PyObject *args, PyObject *kw) +{ + PyObject *spec; + + if (! PyArg_ParseTuple(args, "O", &spec)) + return NULL; + return Spec_extends(self, spec); +} + +static PyObject * +Spec_providedBy(PyObject *self, PyObject *ob) +{ + PyObject *decl, *item; + + decl = providedBy(NULL, ob); + if (decl == NULL) + return NULL; + + if (PyObject_TypeCheck(decl, &SpecificationBaseType)) + item = Spec_extends((Spec*)decl, self); + else + /* decl is probably a security proxy. We have to go the long way + around. + */ + item = PyObject_CallFunctionObjArgs(decl, self, NULL); + + Py_DECREF(decl); + return item; +} + + +static char Spec_implementedBy__doc__[] = +"Test whether the specification is implemented by a class or factory.\n" +"Raise TypeError if argument is neither a class nor a callable." +; + +static PyObject * +Spec_implementedBy(PyObject *self, PyObject *cls) +{ + PyObject *decl, *item; + + decl = implementedBy(NULL, cls); + if (decl == NULL) + return NULL; + + if (PyObject_TypeCheck(decl, &SpecificationBaseType)) + item = Spec_extends((Spec*)decl, self); + else + item = PyObject_CallFunctionObjArgs(decl, self, NULL); + + Py_DECREF(decl); + return item; +} + +static struct PyMethodDef Spec_methods[] = { + {"providedBy", + (PyCFunction)Spec_providedBy, METH_O, + Spec_providedBy__doc__}, + {"implementedBy", + (PyCFunction)Spec_implementedBy, METH_O, + Spec_implementedBy__doc__}, + {"isOrExtends", (PyCFunction)Spec_extends, METH_O, + Spec_extends__doc__}, + + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef Spec_members[] = { + {"_implied", T_OBJECT_EX, offsetof(Spec, _implied), 0, ""}, + {"_dependents", T_OBJECT_EX, offsetof(Spec, _dependents), 0, ""}, + {"_bases", T_OBJECT_EX, offsetof(Spec, _bases), 0, ""}, + {"_v_attrs", T_OBJECT_EX, offsetof(Spec, _v_attrs), 0, ""}, + {"__iro__", T_OBJECT_EX, offsetof(Spec, __iro__), 0, ""}, + {"__sro__", T_OBJECT_EX, offsetof(Spec, __sro__), 0, ""}, + {NULL}, +}; + + +static PyTypeObject SpecificationBaseType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_interface_coptimizations." + "SpecificationBase", + /* tp_basicsize */ sizeof(Spec), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)Spec_dealloc, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)0, + /* tp_call */ (ternaryfunc)Spec_call, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + "Base type for Specification objects", + /* tp_traverse */ (traverseproc)Spec_traverse, + /* tp_clear */ (inquiry)Spec_clear, + /* tp_richcompare */ (richcmpfunc)0, + /* tp_weaklistoffset */ offsetof(Spec, weakreflist), + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ Spec_methods, + /* tp_members */ Spec_members, +}; + +static PyObject * +OSD_descr_get(PyObject *self, PyObject *inst, PyObject *cls) +{ + PyObject *provides; + + if (inst == NULL) + return getObjectSpecification(NULL, cls); + + provides = PyObject_GetAttr(inst, str__provides__); + /* Return __provides__ if we got it, or return NULL and propagate non-AttributeError. */ + if (provides != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) + return provides; + + PyErr_Clear(); + return implementedBy(NULL, cls); +} + +static PyTypeObject OSDType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_interface_coptimizations." + "ObjectSpecificationDescriptor", + /* tp_basicsize */ 0, + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)0, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)0, + /* tp_call */ (ternaryfunc)0, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE , + "Object Specification Descriptor", + /* tp_traverse */ (traverseproc)0, + /* tp_clear */ (inquiry)0, + /* tp_richcompare */ (richcmpfunc)0, + /* tp_weaklistoffset */ (long)0, + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ 0, + /* tp_members */ 0, + /* tp_getset */ 0, + /* tp_base */ 0, + /* tp_dict */ 0, /* internal use */ + /* tp_descr_get */ (descrgetfunc)OSD_descr_get, +}; + +typedef struct { + Spec spec; + /* These members are handled generically, as for Spec members. */ + PyObject* _cls; + PyObject* _implements; +} CPB; + +static PyObject * +CPB_descr_get(CPB *self, PyObject *inst, PyObject *cls) +{ + PyObject *implements; + + if (self->_cls == NULL) + return NULL; + + if (cls == self->_cls) + { + if (inst == NULL) + { + Py_INCREF(self); + return OBJECT(self); + } + + implements = self->_implements; + Py_XINCREF(implements); + return implements; + } + + PyErr_SetObject(PyExc_AttributeError, str__provides__); + return NULL; +} + +static int +CPB_traverse(CPB* self, visitproc visit, void* arg) +{ + Py_VISIT(self->_cls); + Py_VISIT(self->_implements); + return Spec_traverse((Spec*)self, visit, arg); +} + +static int +CPB_clear(CPB* self) +{ + Py_CLEAR(self->_cls); + Py_CLEAR(self->_implements); + Spec_clear((Spec*)self); + return 0; +} + +static void +CPB_dealloc(CPB* self) +{ + PyObject_GC_UnTrack((PyObject *)self); + CPB_clear(self); + Spec_dealloc((Spec*)self); +} + +static PyMemberDef CPB_members[] = { + {"_cls", T_OBJECT_EX, offsetof(CPB, _cls), 0, "Defining class."}, + {"_implements", T_OBJECT_EX, offsetof(CPB, _implements), 0, "Result of implementedBy."}, + {NULL} +}; + +static PyTypeObject CPBType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_interface_coptimizations." + "ClassProvidesBase", + /* tp_basicsize */ sizeof(CPB), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)CPB_dealloc, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)0, + /* tp_call */ (ternaryfunc)0, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + "C Base class for ClassProvides", + /* tp_traverse */ (traverseproc)CPB_traverse, + /* tp_clear */ (inquiry)CPB_clear, + /* tp_richcompare */ (richcmpfunc)0, + /* tp_weaklistoffset */ (long)0, + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ 0, + /* tp_members */ CPB_members, + /* tp_getset */ 0, + /* tp_base */ &SpecificationBaseType, + /* tp_dict */ 0, /* internal use */ + /* tp_descr_get */ (descrgetfunc)CPB_descr_get, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ 0, +}; + +/* ==================================================================== */ +/* ========== Begin: __call__ and __adapt__ =========================== */ + +/* + def __adapt__(self, obj): + """Adapt an object to the receiver + """ + if self.providedBy(obj): + return obj + + for hook in adapter_hooks: + adapter = hook(self, obj) + if adapter is not None: + return adapter + + +*/ +static PyObject * +__adapt__(PyObject *self, PyObject *obj) +{ + PyObject *decl, *args, *adapter; + int implements, i, l; + + decl = providedBy(NULL, obj); + if (decl == NULL) + return NULL; + + if (PyObject_TypeCheck(decl, &SpecificationBaseType)) + { + PyObject *implied; + + implied = ((Spec*)decl)->_implied; + if (implied == NULL) + { + Py_DECREF(decl); + return NULL; + } + + implements = PyDict_GetItem(implied, self) != NULL; + Py_DECREF(decl); + } + else + { + /* decl is probably a security proxy. We have to go the long way + around. + */ + PyObject *r; + r = PyObject_CallFunctionObjArgs(decl, self, NULL); + Py_DECREF(decl); + if (r == NULL) + return NULL; + implements = PyObject_IsTrue(r); + Py_DECREF(r); + } + + if (implements) + { + Py_INCREF(obj); + return obj; + } + + l = PyList_GET_SIZE(adapter_hooks); + args = PyTuple_New(2); + if (args == NULL) + return NULL; + Py_INCREF(self); + PyTuple_SET_ITEM(args, 0, self); + Py_INCREF(obj); + PyTuple_SET_ITEM(args, 1, obj); + for (i = 0; i < l; i++) + { + adapter = PyObject_CallObject(PyList_GET_ITEM(adapter_hooks, i), args); + if (adapter == NULL || adapter != Py_None) + { + Py_DECREF(args); + return adapter; + } + Py_DECREF(adapter); + } + + Py_DECREF(args); + + Py_INCREF(Py_None); + return Py_None; +} + +typedef struct { + Spec spec; + PyObject* __name__; + PyObject* __module__; + Py_hash_t _v_cached_hash; +} IB; + +static struct PyMethodDef ib_methods[] = { + {"__adapt__", (PyCFunction)__adapt__, METH_O, + "Adapt an object to the receiver"}, + {NULL, NULL} /* sentinel */ +}; + +/* + def __call__(self, obj, alternate=_marker): + try: + conform = obj.__conform__ + except AttributeError: # pylint:disable=bare-except + conform = None + + if conform is not None: + adapter = self._call_conform(conform) + if adapter is not None: + return adapter + + adapter = self.__adapt__(obj) + + if adapter is not None: + return adapter + if alternate is not _marker: + return alternate + raise TypeError("Could not adapt", obj, self) + +*/ +static PyObject * +IB_call(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *conform, *obj, *alternate, *adapter; + static char *kwlist[] = {"obj", "alternate", NULL}; + conform = obj = alternate = adapter = NULL; + + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, + &obj, &alternate)) + return NULL; + + conform = PyObject_GetAttr(obj, str__conform__); + if (conform == NULL) + { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + { + /* Propagate non-AttributeErrors */ + return NULL; + } + PyErr_Clear(); + + Py_INCREF(Py_None); + conform = Py_None; + } + + if (conform != Py_None) + { + adapter = PyObject_CallMethodObjArgs(self, str_call_conform, + conform, NULL); + Py_DECREF(conform); + if (adapter == NULL || adapter != Py_None) + return adapter; + Py_DECREF(adapter); + } + else + { + Py_DECREF(conform); + } + + /* We differ from the Python code here. For speed, instead of always calling + self.__adapt__(), we check to see if the type has defined it. Checking in + the dict for __adapt__ isn't sufficient because there's no cheap way to + tell if it's the __adapt__ that InterfaceBase itself defines (our type + will *never* be InterfaceBase, we're always subclassed by + InterfaceClass). Instead, we cooperate with InterfaceClass in Python to + set a flag in a new subclass when this is necessary. */ + if (PyDict_GetItem(self->ob_type->tp_dict, str_CALL_CUSTOM_ADAPT)) + { + /* Doesn't matter what the value is. Simply being present is enough. */ + adapter = PyObject_CallMethodObjArgs(self, str__adapt__, obj, NULL); + } + else + { + adapter = __adapt__(self, obj); + } + + if (adapter == NULL || adapter != Py_None) + { + return adapter; + } + Py_DECREF(adapter); + + if (alternate != NULL) + { + Py_INCREF(alternate); + return alternate; + } + + adapter = Py_BuildValue("sOO", "Could not adapt", obj, self); + if (adapter != NULL) + { + PyErr_SetObject(PyExc_TypeError, adapter); + Py_DECREF(adapter); + } + return NULL; +} + + +static int +IB_traverse(IB* self, visitproc visit, void* arg) +{ + Py_VISIT(self->__name__); + Py_VISIT(self->__module__); + return Spec_traverse((Spec*)self, visit, arg); +} + +static int +IB_clear(IB* self) +{ + Py_CLEAR(self->__name__); + Py_CLEAR(self->__module__); + return Spec_clear((Spec*)self); +} + +static void +IB_dealloc(IB* self) +{ + PyObject_GC_UnTrack((PyObject *)self); + IB_clear(self); + Spec_dealloc((Spec*)self); +} + +static PyMemberDef IB_members[] = { + {"__name__", T_OBJECT_EX, offsetof(IB, __name__), 0, ""}, + // The redundancy between __module__ and __ibmodule__ is because + // __module__ is often shadowed by subclasses. + {"__module__", T_OBJECT_EX, offsetof(IB, __module__), READONLY, ""}, + {"__ibmodule__", T_OBJECT_EX, offsetof(IB, __module__), 0, ""}, + {NULL} +}; + +static Py_hash_t +IB_hash(IB* self) +{ + PyObject* tuple; + if (!self->__module__) { + PyErr_SetString(PyExc_AttributeError, "__module__"); + return -1; + } + if (!self->__name__) { + PyErr_SetString(PyExc_AttributeError, "__name__"); + return -1; + } + + if (self->_v_cached_hash) { + return self->_v_cached_hash; + } + + tuple = PyTuple_Pack(2, self->__name__, self->__module__); + if (!tuple) { + return -1; + } + self->_v_cached_hash = PyObject_Hash(tuple); + Py_CLEAR(tuple); + return self->_v_cached_hash; +} + +static PyTypeObject InterfaceBaseType; + +static PyObject* +IB_richcompare(IB* self, PyObject* other, int op) +{ + PyObject* othername; + PyObject* othermod; + PyObject* oresult; + IB* otherib; + int result; + + otherib = NULL; + oresult = othername = othermod = NULL; + + if (OBJECT(self) == other) { + switch(op) { + case Py_EQ: + case Py_LE: + case Py_GE: + Py_RETURN_TRUE; + break; + case Py_NE: + Py_RETURN_FALSE; + } + } + + if (other == Py_None) { + switch(op) { + case Py_LT: + case Py_LE: + case Py_NE: + Py_RETURN_TRUE; + default: + Py_RETURN_FALSE; + } + } + + if (PyObject_TypeCheck(other, &InterfaceBaseType)) { + // This branch borrows references. No need to clean + // up if otherib is not null. + otherib = (IB*)other; + othername = otherib->__name__; + othermod = otherib->__module__; + } + else { + othername = PyObject_GetAttrString(other, "__name__"); + if (othername) { + othermod = PyObject_GetAttrString(other, "__module__"); + } + if (!othername || !othermod) { + if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + oresult = Py_NotImplemented; + } + goto cleanup; + } + } +#if 0 +// This is the simple, straightforward version of what Python does. + PyObject* pt1 = PyTuple_Pack(2, self->__name__, self->__module__); + PyObject* pt2 = PyTuple_Pack(2, othername, othermod); + oresult = PyObject_RichCompare(pt1, pt2, op); +#endif + + // tuple comparison is decided by the first non-equal element. + result = PyObject_RichCompareBool(self->__name__, othername, Py_EQ); + if (result == 0) { + result = PyObject_RichCompareBool(self->__name__, othername, op); + } + else if (result == 1) { + result = PyObject_RichCompareBool(self->__module__, othermod, op); + } + // If either comparison failed, we have an error set. + // Leave oresult NULL so we raise it. + if (result == -1) { + goto cleanup; + } + + oresult = result ? Py_True : Py_False; + + +cleanup: + Py_XINCREF(oresult); + + if (!otherib) { + Py_XDECREF(othername); + Py_XDECREF(othermod); + } + return oresult; + +} + +static int +IB_init(IB* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"__name__", "__module__", NULL}; + PyObject* module = NULL; + PyObject* name = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:InterfaceBase.__init__", kwlist, + &name, &module)) { + return -1; + } + IB_clear(self); + self->__module__ = module ? module : Py_None; + Py_INCREF(self->__module__); + self->__name__ = name ? name : Py_None; + Py_INCREF(self->__name__); + return 0; +} + + +static PyTypeObject InterfaceBaseType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_zope_interface_coptimizations." + "InterfaceBase", + /* tp_basicsize */ sizeof(IB), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)IB_dealloc, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)IB_hash, + /* tp_call */ (ternaryfunc)IB_call, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_doc */ "Interface base type providing __call__ and __adapt__", + /* tp_traverse */ (traverseproc)IB_traverse, + /* tp_clear */ (inquiry)IB_clear, + /* tp_richcompare */ (richcmpfunc)IB_richcompare, + /* tp_weaklistoffset */ (long)0, + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ ib_methods, + /* tp_members */ IB_members, + /* tp_getset */ 0, + /* tp_base */ &SpecificationBaseType, + /* tp_dict */ 0, + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ (initproc)IB_init, +}; + +/* =================== End: __call__ and __adapt__ ==================== */ +/* ==================================================================== */ + +/* ==================================================================== */ +/* ========================== Begin: Lookup Bases ===================== */ + +typedef struct { + PyObject_HEAD + PyObject *_cache; + PyObject *_mcache; + PyObject *_scache; +} lookup; + +typedef struct { + PyObject_HEAD + PyObject *_cache; + PyObject *_mcache; + PyObject *_scache; + PyObject *_verify_ro; + PyObject *_verify_generations; +} verify; + +static int +lookup_traverse(lookup *self, visitproc visit, void *arg) +{ + int vret; + + if (self->_cache) { + vret = visit(self->_cache, arg); + if (vret != 0) + return vret; + } + + if (self->_mcache) { + vret = visit(self->_mcache, arg); + if (vret != 0) + return vret; + } + + if (self->_scache) { + vret = visit(self->_scache, arg); + if (vret != 0) + return vret; + } + + return 0; +} + +static int +lookup_clear(lookup *self) +{ + Py_CLEAR(self->_cache); + Py_CLEAR(self->_mcache); + Py_CLEAR(self->_scache); + return 0; +} + +static void +lookup_dealloc(lookup *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + lookup_clear(self); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +/* + def changed(self, ignored=None): + self._cache.clear() + self._mcache.clear() + self._scache.clear() +*/ +static PyObject * +lookup_changed(lookup *self, PyObject *ignored) +{ + lookup_clear(self); + Py_INCREF(Py_None); + return Py_None; +} + +#define ASSURE_DICT(N) if (N == NULL) { N = PyDict_New(); \ + if (N == NULL) return NULL; \ + } + +/* + def _getcache(self, provided, name): + cache = self._cache.get(provided) + if cache is None: + cache = {} + self._cache[provided] = cache + if name: + c = cache.get(name) + if c is None: + c = {} + cache[name] = c + cache = c + return cache +*/ +static PyObject * +_subcache(PyObject *cache, PyObject *key) +{ + PyObject *subcache; + + subcache = PyDict_GetItem(cache, key); + if (subcache == NULL) + { + int status; + + subcache = PyDict_New(); + if (subcache == NULL) + return NULL; + status = PyDict_SetItem(cache, key, subcache); + Py_DECREF(subcache); + if (status < 0) + return NULL; + } + + return subcache; +} +static PyObject * +_getcache(lookup *self, PyObject *provided, PyObject *name) +{ + PyObject *cache; + + ASSURE_DICT(self->_cache); + cache = _subcache(self->_cache, provided); + if (cache == NULL) + return NULL; + + if (name != NULL && PyObject_IsTrue(name)) + cache = _subcache(cache, name); + + return cache; +} + + +/* + def lookup(self, required, provided, name=u'', default=None): + cache = self._getcache(provided, name) + if len(required) == 1: + result = cache.get(required[0], _not_in_mapping) + else: + result = cache.get(tuple(required), _not_in_mapping) + + if result is _not_in_mapping: + result = self._uncached_lookup(required, provided, name) + if len(required) == 1: + cache[required[0]] = result + else: + cache[tuple(required)] = result + + if result is None: + return default + + return result +*/ + +static PyObject * +_lookup(lookup *self, + PyObject *required, PyObject *provided, PyObject *name, + PyObject *default_) +{ + PyObject *result, *key, *cache; + result = key = cache = NULL; + if ( name && !PyUnicode_Check(name) ) + { + PyErr_SetString(PyExc_ValueError, + "name is not a string or unicode"); + return NULL; + } + + /* If `required` is a lazy sequence, it could have arbitrary side-effects, + such as clearing our caches. So we must not retrieve the cache until + after resolving it. */ + required = PySequence_Tuple(required); + if (required == NULL) + return NULL; + + + cache = _getcache(self, provided, name); + if (cache == NULL) + return NULL; + + if (PyTuple_GET_SIZE(required) == 1) + key = PyTuple_GET_ITEM(required, 0); + else + key = required; + + result = PyDict_GetItem(cache, key); + if (result == NULL) + { + int status; + + result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookup, + required, provided, name, NULL); + if (result == NULL) + { + Py_DECREF(required); + return NULL; + } + status = PyDict_SetItem(cache, key, result); + Py_DECREF(required); + if (status < 0) + { + Py_DECREF(result); + return NULL; + } + } + else + { + Py_INCREF(result); + Py_DECREF(required); + } + + if (result == Py_None && default_ != NULL) + { + Py_DECREF(Py_None); + Py_INCREF(default_); + return default_; + } + + return result; +} +static PyObject * +lookup_lookup(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", "name", "default", NULL}; + PyObject *required, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.lookup", kwlist, + &required, &provided, &name, &default_)) + return NULL; + + return _lookup(self, required, provided, name, default_); +} + + +/* + def lookup1(self, required, provided, name=u'', default=None): + cache = self._getcache(provided, name) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + return self.lookup((required, ), provided, name, default) + + if result is None: + return default + + return result +*/ +static PyObject * +_lookup1(lookup *self, + PyObject *required, PyObject *provided, PyObject *name, + PyObject *default_) +{ + PyObject *result, *cache; + + if ( name && !PyUnicode_Check(name) ) + { + PyErr_SetString(PyExc_ValueError, + "name is not a string or unicode"); + return NULL; + } + + cache = _getcache(self, provided, name); + if (cache == NULL) + return NULL; + + result = PyDict_GetItem(cache, required); + if (result == NULL) + { + PyObject *tup; + + tup = PyTuple_New(1); + if (tup == NULL) + return NULL; + Py_INCREF(required); + PyTuple_SET_ITEM(tup, 0, required); + result = _lookup(self, tup, provided, name, default_); + Py_DECREF(tup); + } + else + { + if (result == Py_None && default_ != NULL) + { + result = default_; + } + Py_INCREF(result); + } + + return result; +} +static PyObject * +lookup_lookup1(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", "name", "default", NULL}; + PyObject *required, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.lookup1", kwlist, + &required, &provided, &name, &default_)) + return NULL; + + return _lookup1(self, required, provided, name, default_); +} + +/* + def adapter_hook(self, provided, object, name=u'', default=None): + required = providedBy(object) + cache = self._getcache(provided, name) + factory = cache.get(required, _not_in_mapping) + if factory is _not_in_mapping: + factory = self.lookup((required, ), provided, name) + + if factory is not None: + if isinstance(object, super): + object = object.__self__ + result = factory(object) + if result is not None: + return result + + return default +*/ +static PyObject * +_adapter_hook(lookup *self, + PyObject *provided, PyObject *object, PyObject *name, + PyObject *default_) +{ + PyObject *required, *factory, *result; + + if ( name && !PyUnicode_Check(name) ) + { + PyErr_SetString(PyExc_ValueError, + "name is not a string or unicode"); + return NULL; + } + + required = providedBy(NULL, object); + if (required == NULL) + return NULL; + + factory = _lookup1(self, required, provided, name, Py_None); + Py_DECREF(required); + if (factory == NULL) + return NULL; + + if (factory != Py_None) + { + if (PyObject_TypeCheck(object, &PySuper_Type)) { + PyObject* self = PyObject_GetAttr(object, str__self__); + if (self == NULL) + { + Py_DECREF(factory); + return NULL; + } + // Borrow the reference to self + Py_DECREF(self); + object = self; + } + result = PyObject_CallFunctionObjArgs(factory, object, NULL); + Py_DECREF(factory); + if (result == NULL || result != Py_None) + return result; + } + else + result = factory; /* None */ + + if (default_ == NULL || default_ == result) /* No default specified, */ + return result; /* Return None. result is owned None */ + + Py_DECREF(result); + Py_INCREF(default_); + + return default_; +} +static PyObject * +lookup_adapter_hook(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"provided", "object", "name", "default", NULL}; + PyObject *object, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.adapter_hook", kwlist, + &provided, &object, &name, &default_)) + return NULL; + + return _adapter_hook(self, provided, object, name, default_); +} + +static PyObject * +lookup_queryAdapter(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"object", "provided", "name", "default", NULL}; + PyObject *object, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:LookupBase.queryAdapter", kwlist, + &object, &provided, &name, &default_)) + return NULL; + + return _adapter_hook(self, provided, object, name, default_); +} + +/* + def lookupAll(self, required, provided): + cache = self._mcache.get(provided) + if cache is None: + cache = {} + self._mcache[provided] = cache + + required = tuple(required) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + result = self._uncached_lookupAll(required, provided) + cache[required] = result + + return result +*/ +static PyObject * +_lookupAll(lookup *self, PyObject *required, PyObject *provided) +{ + PyObject *cache, *result; + + /* resolve before getting cache. See note in _lookup. */ + required = PySequence_Tuple(required); + if (required == NULL) + return NULL; + + ASSURE_DICT(self->_mcache); + cache = _subcache(self->_mcache, provided); + if (cache == NULL) + return NULL; + + result = PyDict_GetItem(cache, required); + if (result == NULL) + { + int status; + + result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookupAll, + required, provided, NULL); + if (result == NULL) + { + Py_DECREF(required); + return NULL; + } + status = PyDict_SetItem(cache, required, result); + Py_DECREF(required); + if (status < 0) + { + Py_DECREF(result); + return NULL; + } + } + else + { + Py_INCREF(result); + Py_DECREF(required); + } + + return result; +} +static PyObject * +lookup_lookupAll(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", NULL}; + PyObject *required, *provided; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO:LookupBase.lookupAll", kwlist, + &required, &provided)) + return NULL; + + return _lookupAll(self, required, provided); +} + +/* + def subscriptions(self, required, provided): + cache = self._scache.get(provided) + if cache is None: + cache = {} + self._scache[provided] = cache + + required = tuple(required) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + result = self._uncached_subscriptions(required, provided) + cache[required] = result + + return result +*/ +static PyObject * +_subscriptions(lookup *self, PyObject *required, PyObject *provided) +{ + PyObject *cache, *result; + + /* resolve before getting cache. See note in _lookup. */ + required = PySequence_Tuple(required); + if (required == NULL) + return NULL; + + ASSURE_DICT(self->_scache); + cache = _subcache(self->_scache, provided); + if (cache == NULL) + return NULL; + + result = PyDict_GetItem(cache, required); + if (result == NULL) + { + int status; + + result = PyObject_CallMethodObjArgs( + OBJECT(self), str_uncached_subscriptions, + required, provided, NULL); + if (result == NULL) + { + Py_DECREF(required); + return NULL; + } + status = PyDict_SetItem(cache, required, result); + Py_DECREF(required); + if (status < 0) + { + Py_DECREF(result); + return NULL; + } + } + else + { + Py_INCREF(result); + Py_DECREF(required); + } + + return result; +} +static PyObject * +lookup_subscriptions(lookup *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", NULL}; + PyObject *required, *provided; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, + &required, &provided)) + return NULL; + + return _subscriptions(self, required, provided); +} + +static struct PyMethodDef lookup_methods[] = { + {"changed", (PyCFunction)lookup_changed, METH_O, ""}, + {"lookup", (PyCFunction)lookup_lookup, METH_KEYWORDS | METH_VARARGS, ""}, + {"lookup1", (PyCFunction)lookup_lookup1, METH_KEYWORDS | METH_VARARGS, ""}, + {"queryAdapter", (PyCFunction)lookup_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""}, + {"adapter_hook", (PyCFunction)lookup_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""}, + {"lookupAll", (PyCFunction)lookup_lookupAll, METH_KEYWORDS | METH_VARARGS, ""}, + {"subscriptions", (PyCFunction)lookup_subscriptions, METH_KEYWORDS | METH_VARARGS, ""}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject LookupBase = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_zope_interface_coptimizations." + "LookupBase", + /* tp_basicsize */ sizeof(lookup), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)&lookup_dealloc, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)0, + /* tp_call */ (ternaryfunc)0, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC, + /* tp_doc */ "", + /* tp_traverse */ (traverseproc)lookup_traverse, + /* tp_clear */ (inquiry)lookup_clear, + /* tp_richcompare */ (richcmpfunc)0, + /* tp_weaklistoffset */ (long)0, + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ lookup_methods, +}; + +static int +verifying_traverse(verify *self, visitproc visit, void *arg) +{ + int vret; + + vret = lookup_traverse((lookup *)self, visit, arg); + if (vret != 0) + return vret; + + if (self->_verify_ro) { + vret = visit(self->_verify_ro, arg); + if (vret != 0) + return vret; + } + if (self->_verify_generations) { + vret = visit(self->_verify_generations, arg); + if (vret != 0) + return vret; + } + + return 0; +} + +static int +verifying_clear(verify *self) +{ + lookup_clear((lookup *)self); + Py_CLEAR(self->_verify_generations); + Py_CLEAR(self->_verify_ro); + return 0; +} + + +static void +verifying_dealloc(verify *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + verifying_clear(self); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +/* + def changed(self, originally_changed): + super(VerifyingBasePy, self).changed(originally_changed) + self._verify_ro = self._registry.ro[1:] + self._verify_generations = [r._generation for r in self._verify_ro] +*/ +static PyObject * +_generations_tuple(PyObject *ro) +{ + int i, l; + PyObject *generations; + + l = PyTuple_GET_SIZE(ro); + generations = PyTuple_New(l); + for (i=0; i < l; i++) + { + PyObject *generation; + + generation = PyObject_GetAttr(PyTuple_GET_ITEM(ro, i), str_generation); + if (generation == NULL) + { + Py_DECREF(generations); + return NULL; + } + PyTuple_SET_ITEM(generations, i, generation); + } + + return generations; +} +static PyObject * +verifying_changed(verify *self, PyObject *ignored) +{ + PyObject *t, *ro; + + verifying_clear(self); + + t = PyObject_GetAttr(OBJECT(self), str_registry); + if (t == NULL) + return NULL; + ro = PyObject_GetAttr(t, strro); + Py_DECREF(t); + if (ro == NULL) + return NULL; + + t = PyObject_CallFunctionObjArgs(OBJECT(&PyTuple_Type), ro, NULL); + Py_DECREF(ro); + if (t == NULL) + return NULL; + + ro = PyTuple_GetSlice(t, 1, PyTuple_GET_SIZE(t)); + Py_DECREF(t); + if (ro == NULL) + return NULL; + + self->_verify_generations = _generations_tuple(ro); + if (self->_verify_generations == NULL) + { + Py_DECREF(ro); + return NULL; + } + + self->_verify_ro = ro; + + Py_INCREF(Py_None); + return Py_None; +} + +/* + def _verify(self): + if ([r._generation for r in self._verify_ro] + != self._verify_generations): + self.changed(None) +*/ +static int +_verify(verify *self) +{ + PyObject *changed_result; + + if (self->_verify_ro != NULL && self->_verify_generations != NULL) + { + PyObject *generations; + int changed; + + generations = _generations_tuple(self->_verify_ro); + if (generations == NULL) + return -1; + + changed = PyObject_RichCompareBool(self->_verify_generations, + generations, Py_NE); + Py_DECREF(generations); + if (changed == -1) + return -1; + + if (changed == 0) + return 0; + } + + changed_result = PyObject_CallMethodObjArgs(OBJECT(self), strchanged, + Py_None, NULL); + if (changed_result == NULL) + return -1; + + Py_DECREF(changed_result); + return 0; +} + +static PyObject * +verifying_lookup(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", "name", "default", NULL}; + PyObject *required, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, + &required, &provided, &name, &default_)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _lookup((lookup *)self, required, provided, name, default_); +} + +static PyObject * +verifying_lookup1(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", "name", "default", NULL}; + PyObject *required, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, + &required, &provided, &name, &default_)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _lookup1((lookup *)self, required, provided, name, default_); +} + +static PyObject * +verifying_adapter_hook(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"provided", "object", "name", "default", NULL}; + PyObject *object, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, + &provided, &object, &name, &default_)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _adapter_hook((lookup *)self, provided, object, name, default_); +} + +static PyObject * +verifying_queryAdapter(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"object", "provided", "name", "default", NULL}; + PyObject *object, *provided, *name=NULL, *default_=NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, + &object, &provided, &name, &default_)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _adapter_hook((lookup *)self, provided, object, name, default_); +} + +static PyObject * +verifying_lookupAll(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", NULL}; + PyObject *required, *provided; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, + &required, &provided)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _lookupAll((lookup *)self, required, provided); +} + +static PyObject * +verifying_subscriptions(verify *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"required", "provided", NULL}; + PyObject *required, *provided; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, + &required, &provided)) + return NULL; + + if (_verify(self) < 0) + return NULL; + + return _subscriptions((lookup *)self, required, provided); +} + +static struct PyMethodDef verifying_methods[] = { + {"changed", (PyCFunction)verifying_changed, METH_O, ""}, + {"lookup", (PyCFunction)verifying_lookup, METH_KEYWORDS | METH_VARARGS, ""}, + {"lookup1", (PyCFunction)verifying_lookup1, METH_KEYWORDS | METH_VARARGS, ""}, + {"queryAdapter", (PyCFunction)verifying_queryAdapter, METH_KEYWORDS | METH_VARARGS, ""}, + {"adapter_hook", (PyCFunction)verifying_adapter_hook, METH_KEYWORDS | METH_VARARGS, ""}, + {"lookupAll", (PyCFunction)verifying_lookupAll, METH_KEYWORDS | METH_VARARGS, ""}, + {"subscriptions", (PyCFunction)verifying_subscriptions, METH_KEYWORDS | METH_VARARGS, ""}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject VerifyingBase = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_zope_interface_coptimizations." + "VerifyingBase", + /* tp_basicsize */ sizeof(verify), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)&verifying_dealloc, + /* tp_print */ (printfunc)0, + /* tp_getattr */ (getattrfunc)0, + /* tp_setattr */ (setattrfunc)0, + /* tp_compare */ 0, + /* tp_repr */ (reprfunc)0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ (hashfunc)0, + /* tp_call */ (ternaryfunc)0, + /* tp_str */ (reprfunc)0, + /* tp_getattro */ (getattrofunc)0, + /* tp_setattro */ (setattrofunc)0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC, + /* tp_doc */ "", + /* tp_traverse */ (traverseproc)verifying_traverse, + /* tp_clear */ (inquiry)verifying_clear, + /* tp_richcompare */ (richcmpfunc)0, + /* tp_weaklistoffset */ (long)0, + /* tp_iter */ (getiterfunc)0, + /* tp_iternext */ (iternextfunc)0, + /* tp_methods */ verifying_methods, + /* tp_members */ 0, + /* tp_getset */ 0, + /* tp_base */ &LookupBase, +}; + +/* ========================== End: Lookup Bases ======================= */ +/* ==================================================================== */ + + + +static struct PyMethodDef m_methods[] = { + {"implementedBy", (PyCFunction)implementedBy, METH_O, + "Interfaces implemented by a class or factory.\n" + "Raises TypeError if argument is neither a class nor a callable."}, + {"getObjectSpecification", (PyCFunction)getObjectSpecification, METH_O, + "Get an object's interfaces (internal api)"}, + {"providedBy", (PyCFunction)providedBy, METH_O, + "Get an object's interfaces"}, + + {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ +}; + +#if PY_MAJOR_VERSION >= 3 +static char module_doc[] = "C optimizations for zope.interface\n\n"; + +static struct PyModuleDef _zic_module = { + PyModuleDef_HEAD_INIT, + "_zope_interface_coptimizations", + module_doc, + -1, + m_methods, + NULL, + NULL, + NULL, + NULL +}; +#endif + +static PyObject * +init(void) +{ + PyObject *m; + +#if PY_MAJOR_VERSION < 3 +#define DEFINE_STRING(S) \ + if(! (str ## S = PyString_FromString(# S))) return NULL +#else +#define DEFINE_STRING(S) \ + if(! (str ## S = PyUnicode_FromString(# S))) return NULL +#endif + + DEFINE_STRING(__dict__); + DEFINE_STRING(__implemented__); + DEFINE_STRING(__provides__); + DEFINE_STRING(__class__); + DEFINE_STRING(__providedBy__); + DEFINE_STRING(extends); + DEFINE_STRING(__conform__); + DEFINE_STRING(_call_conform); + DEFINE_STRING(_uncached_lookup); + DEFINE_STRING(_uncached_lookupAll); + DEFINE_STRING(_uncached_subscriptions); + DEFINE_STRING(_registry); + DEFINE_STRING(_generation); + DEFINE_STRING(ro); + DEFINE_STRING(changed); + DEFINE_STRING(__self__); + DEFINE_STRING(__name__); + DEFINE_STRING(__module__); + DEFINE_STRING(__adapt__); + DEFINE_STRING(_CALL_CUSTOM_ADAPT); +#undef DEFINE_STRING + adapter_hooks = PyList_New(0); + if (adapter_hooks == NULL) + return NULL; + + /* Initialize types: */ + SpecificationBaseType.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&SpecificationBaseType) < 0) + return NULL; + OSDType.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&OSDType) < 0) + return NULL; + CPBType.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&CPBType) < 0) + return NULL; + + InterfaceBaseType.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&InterfaceBaseType) < 0) + return NULL; + + LookupBase.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&LookupBase) < 0) + return NULL; + + VerifyingBase.tp_new = PyBaseObject_Type.tp_new; + if (PyType_Ready(&VerifyingBase) < 0) + return NULL; + + #if PY_MAJOR_VERSION < 3 + /* Create the module and add the functions */ + m = Py_InitModule3("_zope_interface_coptimizations", m_methods, + "C optimizations for zope.interface\n\n"); + #else + m = PyModule_Create(&_zic_module); + #endif + if (m == NULL) + return NULL; + + /* Add types: */ + if (PyModule_AddObject(m, "SpecificationBase", OBJECT(&SpecificationBaseType)) < 0) + return NULL; + if (PyModule_AddObject(m, "ObjectSpecificationDescriptor", + (PyObject *)&OSDType) < 0) + return NULL; + if (PyModule_AddObject(m, "ClassProvidesBase", OBJECT(&CPBType)) < 0) + return NULL; + if (PyModule_AddObject(m, "InterfaceBase", OBJECT(&InterfaceBaseType)) < 0) + return NULL; + if (PyModule_AddObject(m, "LookupBase", OBJECT(&LookupBase)) < 0) + return NULL; + if (PyModule_AddObject(m, "VerifyingBase", OBJECT(&VerifyingBase)) < 0) + return NULL; + if (PyModule_AddObject(m, "adapter_hooks", adapter_hooks) < 0) + return NULL; + return m; +} + +PyMODINIT_FUNC +#if PY_MAJOR_VERSION < 3 +init_zope_interface_coptimizations(void) +{ + init(); +} +#else +PyInit__zope_interface_coptimizations(void) +{ + return init(); +} +#endif + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.cpython-39-darwin.so b/dbdpy-env/lib/python3.9/site-packages/zope/interface/_zope_interface_coptimizations.cpython-39-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..a72259450817e2eff764947455ed0c08b4086e11 GIT binary patch literal 77904 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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/adapter.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/adapter.py new file mode 100644 index 00000000..dbff0d19 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/adapter.py @@ -0,0 +1,1015 @@ +############################################################################## +# +# Copyright (c) 2004 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Adapter management +""" +import itertools +import weakref + +from zope.interface import implementer +from zope.interface import providedBy +from zope.interface import Interface +from zope.interface import ro +from zope.interface.interfaces import IAdapterRegistry + +from zope.interface._compat import _normalize_name +from zope.interface._compat import _use_c_impl + +__all__ = [ + 'AdapterRegistry', + 'VerifyingAdapterRegistry', +] + +# In the CPython implementation, +# ``tuple`` and ``list`` cooperate so that ``tuple([some list])`` +# directly allocates and iterates at the C level without using a +# Python iterator. That's not the case for +# ``tuple(generator_expression)`` or ``tuple(map(func, it))``. +## +# 3.8 +# ``tuple([t for t in range(10)])`` -> 610ns +# ``tuple(t for t in range(10))`` -> 696ns +# ``tuple(map(lambda t: t, range(10)))`` -> 881ns +## +# 2.7 +# ``tuple([t fon t in range(10)])`` -> 625ns +# ``tuple(t for t in range(10))`` -> 665ns +# ``tuple(map(lambda t: t, range(10)))`` -> 958ns +# +# All three have substantial variance. +## +# On PyPy, this is also the best option. +## +# PyPy 2.7.18-7.3.3 +# ``tuple([t fon t in range(10)])`` -> 128ns +# ``tuple(t for t in range(10))`` -> 175ns +# ``tuple(map(lambda t: t, range(10)))`` -> 153ns +## +# PyPy 3.7.9 7.3.3-beta +# ``tuple([t fon t in range(10)])`` -> 82ns +# ``tuple(t for t in range(10))`` -> 177ns +# ``tuple(map(lambda t: t, range(10)))`` -> 168ns +# + +class BaseAdapterRegistry: + """ + A basic implementation of the data storage and algorithms required + for a :class:`zope.interface.interfaces.IAdapterRegistry`. + + Subclasses can set the following attributes to control how the data + is stored; in particular, these hooks can be helpful for ZODB + persistence. They can be class attributes that are the named (or similar) type, or + they can be methods that act as a constructor for an object that behaves + like the types defined here; this object will not assume that they are type + objects, but subclasses are free to do so: + + _sequenceType = list + This is the type used for our two mutable top-level "byorder" sequences. + Must support mutation operations like ``append()`` and ``del seq[index]``. + These are usually small (< 10). Although at least one of them is + accessed when performing lookups or queries on this object, the other + is untouched. In many common scenarios, both are only required when + mutating registrations and subscriptions (like what + :meth:`zope.interface.interfaces.IComponents.registerUtility` does). + This use pattern makes it an ideal candidate to be a + :class:`~persistent.list.PersistentList`. + _leafSequenceType = tuple + This is the type used for the leaf sequences of subscribers. + It could be set to a ``PersistentList`` to avoid many unnecessary data + loads when subscribers aren't being used. Mutation operations are directed + through :meth:`_addValueToLeaf` and :meth:`_removeValueFromLeaf`; if you use + a mutable type, you'll need to override those. + _mappingType = dict + This is the mutable mapping type used for the keyed mappings. + A :class:`~persistent.mapping.PersistentMapping` + could be used to help reduce the number of data loads when the registry is large + and parts of it are rarely used. Further reductions in data loads can come from + using a :class:`~BTrees.OOBTree.OOBTree`, but care is required + to be sure that all required/provided + values are fully ordered (e.g., no required or provided values that are classes + can be used). + _providedType = dict + This is the mutable mapping type used for the ``_provided`` mapping. + This is separate from the generic mapping type because the values + are always integers, so one might choose to use a more optimized data + structure such as a :class:`~BTrees.OIBTree.OIBTree`. + The same caveats regarding key types + apply as for ``_mappingType``. + + It is possible to also set these on an instance, but because of the need to + potentially also override :meth:`_addValueToLeaf` and :meth:`_removeValueFromLeaf`, + this may be less useful in a persistent scenario; using a subclass is recommended. + + .. versionchanged:: 5.3.0 + Add support for customizing the way internal data + structures are created. + .. versionchanged:: 5.3.0 + Add methods :meth:`rebuild`, :meth:`allRegistrations` + and :meth:`allSubscriptions`. + """ + + # List of methods copied from lookup sub-objects: + _delegated = ('lookup', 'queryMultiAdapter', 'lookup1', 'queryAdapter', + 'adapter_hook', 'lookupAll', 'names', + 'subscriptions', 'subscribers') + + # All registries maintain a generation that can be used by verifying + # registries + _generation = 0 + + def __init__(self, bases=()): + + # The comments here could be improved. Possibly this bit needs + # explaining in a separate document, as the comments here can + # be quite confusing. /regebro + + # {order -> {required -> {provided -> {name -> value}}}} + # Here "order" is actually an index in a list, "required" and + # "provided" are interfaces, and "required" is really a nested + # key. So, for example: + # for order == 0 (that is, self._adapters[0]), we have: + # {provided -> {name -> value}} + # but for order == 2 (that is, self._adapters[2]), we have: + # {r1 -> {r2 -> {provided -> {name -> value}}}} + # + self._adapters = self._sequenceType() + + # {order -> {required -> {provided -> {name -> [value]}}}} + # where the remarks about adapters above apply + self._subscribers = self._sequenceType() + + # Set, with a reference count, keeping track of the interfaces + # for which we have provided components: + self._provided = self._providedType() + + # Create ``_v_lookup`` object to perform lookup. We make this a + # separate object to to make it easier to implement just the + # lookup functionality in C. This object keeps track of cache + # invalidation data in two kinds of registries. + + # Invalidating registries have caches that are invalidated + # when they or their base registies change. An invalidating + # registry can only have invalidating registries as bases. + # See LookupBaseFallback below for the pertinent logic. + + # Verifying registies can't rely on getting invalidation messages, + # so have to check the generations of base registries to determine + # if their cache data are current. See VerifyingBasePy below + # for the pertinent object. + self._createLookup() + + # Setting the bases causes the registries described above + # to be initialized (self._setBases -> self.changed -> + # self._v_lookup.changed). + + self.__bases__ = bases + + def _setBases(self, bases): + """ + If subclasses need to track when ``__bases__`` changes, they + can override this method. + + Subclasses must still call this method. + """ + self.__dict__['__bases__'] = bases + self.ro = ro.ro(self) + self.changed(self) + + __bases__ = property(lambda self: self.__dict__['__bases__'], + lambda self, bases: self._setBases(bases), + ) + + def _createLookup(self): + self._v_lookup = self.LookupClass(self) + for name in self._delegated: + self.__dict__[name] = getattr(self._v_lookup, name) + + # Hooks for subclasses to define the types of objects used in + # our data structures. + # These have to be documented in the docstring, instead of local + # comments, because Sphinx autodoc ignores the comment and just writes + # "alias of list" + _sequenceType = list + _leafSequenceType = tuple + _mappingType = dict + _providedType = dict + + def _addValueToLeaf(self, existing_leaf_sequence, new_item): + """ + Add the value *new_item* to the *existing_leaf_sequence*, which may + be ``None``. + + Subclasses that redefine `_leafSequenceType` should override this method. + + :param existing_leaf_sequence: + If *existing_leaf_sequence* is not *None*, it will be an instance + of `_leafSequenceType`. (Unless the object has been unpickled + from an old pickle and the class definition has changed, in which case + it may be an instance of a previous definition, commonly a `tuple`.) + + :return: + This method returns the new value to be stored. It may mutate the + sequence in place if it was not ``None`` and the type is mutable, but + it must also return it. + + .. versionadded:: 5.3.0 + """ + if existing_leaf_sequence is None: + return (new_item,) + return existing_leaf_sequence + (new_item,) + + def _removeValueFromLeaf(self, existing_leaf_sequence, to_remove): + """ + Remove the item *to_remove* from the (non-``None``, non-empty) + *existing_leaf_sequence* and return the mutated sequence. + + If there is more than one item that is equal to *to_remove* + they must all be removed. + + Subclasses that redefine `_leafSequenceType` should override + this method. Note that they can call this method to help + in their implementation; this implementation will always + return a new tuple constructed by iterating across + the *existing_leaf_sequence* and omitting items equal to *to_remove*. + + :param existing_leaf_sequence: + As for `_addValueToLeaf`, probably an instance of + `_leafSequenceType` but possibly an older type; never `None`. + :return: + A version of *existing_leaf_sequence* with all items equal to + *to_remove* removed. Must not return `None`. However, + returning an empty + object, even of another type such as the empty tuple, ``()`` is + explicitly allowed; such an object will never be stored. + + .. versionadded:: 5.3.0 + """ + return tuple([v for v in existing_leaf_sequence if v != to_remove]) + + def changed(self, originally_changed): + self._generation += 1 + self._v_lookup.changed(originally_changed) + + def register(self, required, provided, name, value): + if not isinstance(name, str): + raise ValueError('name is not a string') + if value is None: + self.unregister(required, provided, name, value) + return + + required = tuple([_convert_None_to_Interface(r) for r in required]) + name = _normalize_name(name) + order = len(required) + byorder = self._adapters + while len(byorder) <= order: + byorder.append(self._mappingType()) + components = byorder[order] + key = required + (provided,) + + for k in key: + d = components.get(k) + if d is None: + d = self._mappingType() + components[k] = d + components = d + + if components.get(name) is value: + return + + components[name] = value + + n = self._provided.get(provided, 0) + 1 + self._provided[provided] = n + if n == 1: + self._v_lookup.add_extendor(provided) + + self.changed(self) + + def _find_leaf(self, byorder, required, provided, name): + # Find the leaf value, if any, in the *byorder* list + # for the interface sequence *required* and the interface + # *provided*, given the already normalized *name*. + # + # If no such leaf value exists, returns ``None`` + required = tuple([_convert_None_to_Interface(r) for r in required]) + order = len(required) + if len(byorder) <= order: + return None + + components = byorder[order] + key = required + (provided,) + + for k in key: + d = components.get(k) + if d is None: + return None + components = d + + return components.get(name) + + def registered(self, required, provided, name=''): + return self._find_leaf( + self._adapters, + required, + provided, + _normalize_name(name) + ) + + @classmethod + def _allKeys(cls, components, i, parent_k=()): + if i == 0: + for k, v in components.items(): + yield parent_k + (k,), v + else: + for k, v in components.items(): + new_parent_k = parent_k + (k,) + yield from cls._allKeys(v, i - 1, new_parent_k) + + def _all_entries(self, byorder): + # Recurse through the mapping levels of the `byorder` sequence, + # reconstructing a flattened sequence of ``(required, provided, name, value)`` + # tuples that can be used to reconstruct the sequence with the appropriate + # registration methods. + # + # Locally reference the `byorder` data; it might be replaced while + # this method is running (see ``rebuild``). + for i, components in enumerate(byorder): + # We will have *i* levels of dictionaries to go before + # we get to the leaf. + for key, value in self._allKeys(components, i + 1): + assert len(key) == i + 2 + required = key[:i] + provided = key[-2] + name = key[-1] + yield (required, provided, name, value) + + def allRegistrations(self): + """ + Yields tuples ``(required, provided, name, value)`` for all + the registrations that this object holds. + + These tuples could be passed as the arguments to the + :meth:`register` method on another adapter registry to + duplicate the registrations this object holds. + + .. versionadded:: 5.3.0 + """ + yield from self._all_entries(self._adapters) + + def unregister(self, required, provided, name, value=None): + required = tuple([_convert_None_to_Interface(r) for r in required]) + order = len(required) + byorder = self._adapters + if order >= len(byorder): + return False + components = byorder[order] + key = required + (provided,) + + # Keep track of how we got to `components`: + lookups = [] + for k in key: + d = components.get(k) + if d is None: + return + lookups.append((components, k)) + components = d + + old = components.get(name) + if old is None: + return + if (value is not None) and (old is not value): + return + + del components[name] + if not components: + # Clean out empty containers, since we don't want our keys + # to reference global objects (interfaces) unnecessarily. + # This is often a problem when an interface is slated for + # removal; a hold-over entry in the registry can make it + # difficult to remove such interfaces. + for comp, k in reversed(lookups): + d = comp[k] + if d: + break + else: + del comp[k] + while byorder and not byorder[-1]: + del byorder[-1] + n = self._provided[provided] - 1 + if n == 0: + del self._provided[provided] + self._v_lookup.remove_extendor(provided) + else: + self._provided[provided] = n + + self.changed(self) + + def subscribe(self, required, provided, value): + required = tuple([_convert_None_to_Interface(r) for r in required]) + name = '' + order = len(required) + byorder = self._subscribers + while len(byorder) <= order: + byorder.append(self._mappingType()) + components = byorder[order] + key = required + (provided,) + + for k in key: + d = components.get(k) + if d is None: + d = self._mappingType() + components[k] = d + components = d + + components[name] = self._addValueToLeaf(components.get(name), value) + + if provided is not None: + n = self._provided.get(provided, 0) + 1 + self._provided[provided] = n + if n == 1: + self._v_lookup.add_extendor(provided) + + self.changed(self) + + def subscribed(self, required, provided, subscriber): + subscribers = self._find_leaf( + self._subscribers, + required, + provided, + '' + ) or () + return subscriber if subscriber in subscribers else None + + def allSubscriptions(self): + """ + Yields tuples ``(required, provided, value)`` for all the + subscribers that this object holds. + + These tuples could be passed as the arguments to the + :meth:`subscribe` method on another adapter registry to + duplicate the registrations this object holds. + + .. versionadded:: 5.3.0 + """ + for required, provided, _name, value in self._all_entries(self._subscribers): + for v in value: + yield (required, provided, v) + + def unsubscribe(self, required, provided, value=None): + required = tuple([_convert_None_to_Interface(r) for r in required]) + order = len(required) + byorder = self._subscribers + if order >= len(byorder): + return + components = byorder[order] + key = required + (provided,) + + # Keep track of how we got to `components`: + lookups = [] + for k in key: + d = components.get(k) + if d is None: + return + lookups.append((components, k)) + components = d + + old = components.get('') + if not old: + # this is belt-and-suspenders against the failure of cleanup below + return # pragma: no cover + len_old = len(old) + if value is None: + # Removing everything; note that the type of ``new`` won't + # necessarily match the ``_leafSequenceType``, but that's + # OK because we're about to delete the entire entry + # anyway. + new = () + else: + new = self._removeValueFromLeaf(old, value) + # ``new`` may be the same object as ``old``, just mutated in place, + # so we cannot compare it to ``old`` to check for changes. Remove + # our reference to it now to avoid trying to do so below. + del old + + if len(new) == len_old: + # No changes, so nothing could have been removed. + return + + if new: + components[''] = new + else: + # Instead of setting components[u''] = new, we clean out + # empty containers, since we don't want our keys to + # reference global objects (interfaces) unnecessarily. This + # is often a problem when an interface is slated for + # removal; a hold-over entry in the registry can make it + # difficult to remove such interfaces. + del components[''] + for comp, k in reversed(lookups): + d = comp[k] + if d: + break + else: + del comp[k] + while byorder and not byorder[-1]: + del byorder[-1] + + if provided is not None: + n = self._provided[provided] + len(new) - len_old + if n == 0: + del self._provided[provided] + self._v_lookup.remove_extendor(provided) + else: + self._provided[provided] = n + + self.changed(self) + + def rebuild(self): + """ + Rebuild (and replace) all the internal data structures of this + object. + + This is useful, especially for persistent implementations, if + you suspect an issue with reference counts keeping interfaces + alive even though they are no longer used. + + It is also useful if you or a subclass change the data types + (``_mappingType`` and friends) that are to be used. + + This method replaces all internal data structures with new objects; + it specifically does not re-use any storage. + + .. versionadded:: 5.3.0 + """ + + # Grab the iterators, we're about to discard their data. + registrations = self.allRegistrations() + subscriptions = self.allSubscriptions() + + def buffer(it): + # The generator doesn't actually start running until we + # ask for its next(), by which time the attributes will change + # unless we do so before calling __init__. + try: + first = next(it) + except StopIteration: + return iter(()) + + return itertools.chain((first,), it) + + registrations = buffer(registrations) + subscriptions = buffer(subscriptions) + + + # Replace the base data structures as well as _v_lookup. + self.__init__(self.__bases__) + # Re-register everything previously registered and subscribed. + # + # XXX: This is going to call ``self.changed()`` a lot, all of + # which is unnecessary (because ``self.__init__`` just + # re-created those dependent objects and also called + # ``self.changed()``). Is this a bottleneck that needs fixed? + # (We could do ``self.changed = lambda _: None`` before + # beginning and remove it after to disable the presumably expensive + # part of passing that notification to the change of objects.) + for args in registrations: + self.register(*args) + for args in subscriptions: + self.subscribe(*args) + + # XXX hack to fake out twisted's use of a private api. We need to get them + # to use the new registered method. + def get(self, _): # pragma: no cover + class XXXTwistedFakeOut: + selfImplied = {} + return XXXTwistedFakeOut + + +_not_in_mapping = object() + +@_use_c_impl +class LookupBase: + + def __init__(self): + self._cache = {} + self._mcache = {} + self._scache = {} + + def changed(self, ignored=None): + self._cache.clear() + self._mcache.clear() + self._scache.clear() + + def _getcache(self, provided, name): + cache = self._cache.get(provided) + if cache is None: + cache = {} + self._cache[provided] = cache + if name: + c = cache.get(name) + if c is None: + c = {} + cache[name] = c + cache = c + return cache + + def lookup(self, required, provided, name='', default=None): + if not isinstance(name, str): + raise ValueError('name is not a string') + cache = self._getcache(provided, name) + required = tuple(required) + if len(required) == 1: + result = cache.get(required[0], _not_in_mapping) + else: + result = cache.get(tuple(required), _not_in_mapping) + + if result is _not_in_mapping: + result = self._uncached_lookup(required, provided, name) + if len(required) == 1: + cache[required[0]] = result + else: + cache[tuple(required)] = result + + if result is None: + return default + + return result + + def lookup1(self, required, provided, name='', default=None): + if not isinstance(name, str): + raise ValueError('name is not a string') + cache = self._getcache(provided, name) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + return self.lookup((required, ), provided, name, default) + + if result is None: + return default + + return result + + def queryAdapter(self, object, provided, name='', default=None): + return self.adapter_hook(provided, object, name, default) + + def adapter_hook(self, provided, object, name='', default=None): + if not isinstance(name, str): + raise ValueError('name is not a string') + required = providedBy(object) + cache = self._getcache(provided, name) + factory = cache.get(required, _not_in_mapping) + if factory is _not_in_mapping: + factory = self.lookup((required, ), provided, name) + + if factory is not None: + if isinstance(object, super): + object = object.__self__ + result = factory(object) + if result is not None: + return result + + return default + + def lookupAll(self, required, provided): + cache = self._mcache.get(provided) + if cache is None: + cache = {} + self._mcache[provided] = cache + + required = tuple(required) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + result = self._uncached_lookupAll(required, provided) + cache[required] = result + + return result + + + def subscriptions(self, required, provided): + cache = self._scache.get(provided) + if cache is None: + cache = {} + self._scache[provided] = cache + + required = tuple(required) + result = cache.get(required, _not_in_mapping) + if result is _not_in_mapping: + result = self._uncached_subscriptions(required, provided) + cache[required] = result + + return result + + +@_use_c_impl +class VerifyingBase(LookupBaseFallback): + # Mixin for lookups against registries which "chain" upwards, and + # whose lookups invalidate their own caches whenever a parent registry + # bumps its own '_generation' counter. E.g., used by + # zope.component.persistentregistry + + def changed(self, originally_changed): + LookupBaseFallback.changed(self, originally_changed) + self._verify_ro = self._registry.ro[1:] + self._verify_generations = [r._generation for r in self._verify_ro] + + def _verify(self): + if ([r._generation for r in self._verify_ro] + != self._verify_generations): + self.changed(None) + + def _getcache(self, provided, name): + self._verify() + return LookupBaseFallback._getcache(self, provided, name) + + def lookupAll(self, required, provided): + self._verify() + return LookupBaseFallback.lookupAll(self, required, provided) + + def subscriptions(self, required, provided): + self._verify() + return LookupBaseFallback.subscriptions(self, required, provided) + + +class AdapterLookupBase: + + def __init__(self, registry): + self._registry = registry + self._required = {} + self.init_extendors() + super().__init__() + + def changed(self, ignored=None): + super().changed(None) + for r in self._required.keys(): + r = r() + if r is not None: + r.unsubscribe(self) + self._required.clear() + + + # Extendors + # --------- + + # When given an target interface for an adapter lookup, we need to consider + # adapters for interfaces that extend the target interface. This is + # what the extendors dictionary is about. It tells us all of the + # interfaces that extend an interface for which there are adapters + # registered. + + # We could separate this by order and name, thus reducing the + # number of provided interfaces to search at run time. The tradeoff, + # however, is that we have to store more information. For example, + # if the same interface is provided for multiple names and if the + # interface extends many interfaces, we'll have to keep track of + # a fair bit of information for each name. It's better to + # be space efficient here and be time efficient in the cache + # implementation. + + # TODO: add invalidation when a provided interface changes, in case + # the interface's __iro__ has changed. This is unlikely enough that + # we'll take our chances for now. + + def init_extendors(self): + self._extendors = {} + for p in self._registry._provided: + self.add_extendor(p) + + def add_extendor(self, provided): + _extendors = self._extendors + for i in provided.__iro__: + extendors = _extendors.get(i, ()) + _extendors[i] = ( + [e for e in extendors if provided.isOrExtends(e)] + + + [provided] + + + [e for e in extendors if not provided.isOrExtends(e)] + ) + + def remove_extendor(self, provided): + _extendors = self._extendors + for i in provided.__iro__: + _extendors[i] = [e for e in _extendors.get(i, ()) + if e != provided] + + + def _subscribe(self, *required): + _refs = self._required + for r in required: + ref = r.weakref() + if ref not in _refs: + r.subscribe(self) + _refs[ref] = 1 + + def _uncached_lookup(self, required, provided, name=''): + required = tuple(required) + result = None + order = len(required) + for registry in self._registry.ro: + byorder = registry._adapters + if order >= len(byorder): + continue + + extendors = registry._v_lookup._extendors.get(provided) + if not extendors: + continue + + components = byorder[order] + result = _lookup(components, required, extendors, name, 0, + order) + if result is not None: + break + + self._subscribe(*required) + + return result + + def queryMultiAdapter(self, objects, provided, name='', default=None): + factory = self.lookup([providedBy(o) for o in objects], provided, name) + if factory is None: + return default + + result = factory(*[o.__self__ if isinstance(o, super) else o for o in objects]) + if result is None: + return default + + return result + + def _uncached_lookupAll(self, required, provided): + required = tuple(required) + order = len(required) + result = {} + for registry in reversed(self._registry.ro): + byorder = registry._adapters + if order >= len(byorder): + continue + extendors = registry._v_lookup._extendors.get(provided) + if not extendors: + continue + components = byorder[order] + _lookupAll(components, required, extendors, result, 0, order) + + self._subscribe(*required) + + return tuple(result.items()) + + def names(self, required, provided): + return [c[0] for c in self.lookupAll(required, provided)] + + def _uncached_subscriptions(self, required, provided): + required = tuple(required) + order = len(required) + result = [] + for registry in reversed(self._registry.ro): + byorder = registry._subscribers + if order >= len(byorder): + continue + + if provided is None: + extendors = (provided, ) + else: + extendors = registry._v_lookup._extendors.get(provided) + if extendors is None: + continue + + _subscriptions(byorder[order], required, extendors, '', + result, 0, order) + + self._subscribe(*required) + + return result + + def subscribers(self, objects, provided): + subscriptions = self.subscriptions([providedBy(o) for o in objects], provided) + if provided is None: + result = () + for subscription in subscriptions: + subscription(*objects) + else: + result = [] + for subscription in subscriptions: + subscriber = subscription(*objects) + if subscriber is not None: + result.append(subscriber) + return result + +class AdapterLookup(AdapterLookupBase, LookupBase): + pass + +@implementer(IAdapterRegistry) +class AdapterRegistry(BaseAdapterRegistry): + """ + A full implementation of ``IAdapterRegistry`` that adds support for + sub-registries. + """ + + LookupClass = AdapterLookup + + def __init__(self, bases=()): + # AdapterRegisties are invalidating registries, so + # we need to keep track of our invalidating subregistries. + self._v_subregistries = weakref.WeakKeyDictionary() + + super().__init__(bases) + + def _addSubregistry(self, r): + self._v_subregistries[r] = 1 + + def _removeSubregistry(self, r): + if r in self._v_subregistries: + del self._v_subregistries[r] + + def _setBases(self, bases): + old = self.__dict__.get('__bases__', ()) + for r in old: + if r not in bases: + r._removeSubregistry(self) + for r in bases: + if r not in old: + r._addSubregistry(self) + + super()._setBases(bases) + + def changed(self, originally_changed): + super().changed(originally_changed) + + for sub in self._v_subregistries.keys(): + sub.changed(originally_changed) + + +class VerifyingAdapterLookup(AdapterLookupBase, VerifyingBase): + pass + +@implementer(IAdapterRegistry) +class VerifyingAdapterRegistry(BaseAdapterRegistry): + """ + The most commonly-used adapter registry. + """ + + LookupClass = VerifyingAdapterLookup + +def _convert_None_to_Interface(x): + if x is None: + return Interface + else: + return x + +def _lookup(components, specs, provided, name, i, l): + # this function is called very often. + # The components.get in loops is executed 100 of 1000s times. + # by loading get into a local variable the bytecode + # "LOAD_FAST 0 (components)" in the loop can be eliminated. + components_get = components.get + if i < l: + for spec in specs[i].__sro__: + comps = components_get(spec) + if comps: + r = _lookup(comps, specs, provided, name, i+1, l) + if r is not None: + return r + else: + for iface in provided: + comps = components_get(iface) + if comps: + r = comps.get(name) + if r is not None: + return r + + return None + +def _lookupAll(components, specs, provided, result, i, l): + components_get = components.get # see _lookup above + if i < l: + for spec in reversed(specs[i].__sro__): + comps = components_get(spec) + if comps: + _lookupAll(comps, specs, provided, result, i+1, l) + else: + for iface in reversed(provided): + comps = components_get(iface) + if comps: + result.update(comps) + +def _subscriptions(components, specs, provided, name, result, i, l): + components_get = components.get # see _lookup above + if i < l: + for spec in reversed(specs[i].__sro__): + comps = components_get(spec) + if comps: + _subscriptions(comps, specs, provided, name, result, i+1, l) + else: + for iface in reversed(provided): + comps = components_get(iface) + if comps: + comps = comps.get(name) + if comps: + result.extend(comps) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/advice.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/advice.py new file mode 100644 index 00000000..54e356e6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/advice.py @@ -0,0 +1,118 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Class advice. + +This module was adapted from 'protocols.advice', part of the Python +Enterprise Application Kit (PEAK). Please notify the PEAK authors +(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or +Zope-specific changes are required, so that the PEAK version of this module +can be kept in sync. + +PEAK is a Python application framework that interoperates with (but does +not require) Zope 3 and Twisted. It provides tools for manipulating UML +models, object-relational persistence, aspect-oriented programming, and more. +Visit the PEAK home page at http://peak.telecommunity.com for more information. +""" + +from types import FunctionType + +__all__ = [ + 'determineMetaclass', + 'getFrameInfo', + 'isClassAdvisor', + 'minimalBases', +] + +import sys + +def getFrameInfo(frame): + """Return (kind,module,locals,globals) for a frame + + 'kind' is one of "exec", "module", "class", "function call", or "unknown". + """ + + f_locals = frame.f_locals + f_globals = frame.f_globals + + sameNamespace = f_locals is f_globals + hasModule = '__module__' in f_locals + hasName = '__name__' in f_globals + + sameName = hasModule and hasName + sameName = sameName and f_globals['__name__']==f_locals['__module__'] + + module = hasName and sys.modules.get(f_globals['__name__']) or None + + namespaceIsModule = module and module.__dict__ is f_globals + + if not namespaceIsModule: + # some kind of funky exec + kind = "exec" + elif sameNamespace and not hasModule: + kind = "module" + elif sameName and not sameNamespace: + kind = "class" + elif not sameNamespace: + kind = "function call" + else: # pragma: no cover + # How can you have f_locals is f_globals, and have '__module__' set? + # This is probably module-level code, but with a '__module__' variable. + kind = "unknown" + return kind, module, f_locals, f_globals + + +def isClassAdvisor(ob): + """True if 'ob' is a class advisor function""" + return isinstance(ob,FunctionType) and hasattr(ob,'previousMetaclass') + + +def determineMetaclass(bases, explicit_mc=None): + """Determine metaclass from 1+ bases and optional explicit __metaclass__""" + + meta = [getattr(b,'__class__',type(b)) for b in bases] + + if explicit_mc is not None: + # The explicit metaclass needs to be verified for compatibility + # as well, and allowed to resolve the incompatible bases, if any + meta.append(explicit_mc) + + if len(meta)==1: + # easy case + return meta[0] + + candidates = minimalBases(meta) # minimal set of metaclasses + + if len(candidates)>1: + # We could auto-combine, but for now we won't... + raise TypeError("Incompatible metatypes", bases) + + # Just one, return it + return candidates[0] + + +def minimalBases(classes): + """Reduce a list of base classes to its ordered minimum equivalent""" + candidates = [] + + for m in classes: + for n in classes: + if issubclass(n,m) and m is not n: + break + else: + # m has no subclasses in 'classes' + if m in candidates: + candidates.remove(m) # ensure that we're later in the list + candidates.append(m) + + return candidates diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/__init__.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/__init__.py new file mode 100644 index 00000000..56f4566a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/__init__.py @@ -0,0 +1,272 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + +import itertools +from types import FunctionType + +from zope.interface import classImplements +from zope.interface import Interface +from zope.interface.interface import fromFunction +from zope.interface.interface import InterfaceClass +from zope.interface.interface import _decorator_non_return + +__all__ = [ + # Nothing public here. +] + + +# pylint:disable=inherit-non-class, +# pylint:disable=no-self-argument,no-method-argument +# pylint:disable=unexpected-special-method-signature + +class optional: + # Apply this decorator to a method definition to make it + # optional (remove it from the list of required names), overriding + # the definition inherited from the ABC. + def __init__(self, method): + self.__doc__ = method.__doc__ + + +class ABCInterfaceClass(InterfaceClass): + """ + An interface that is automatically derived from a + :class:`abc.ABCMeta` type. + + Internal use only. + + The body of the interface definition *must* define + a property ``abc`` that is the ABC to base the interface on. + + If ``abc`` is *not* in the interface definition, a regular + interface will be defined instead (but ``extra_classes`` is still + respected). + + Use the ``@optional`` decorator on method definitions if + the ABC defines methods that are not actually required in all cases + because the Python language has multiple ways to implement a protocol. + For example, the ``iter()`` protocol can be implemented with + ``__iter__`` or the pair ``__len__`` and ``__getitem__``. + + When created, any existing classes that are registered to conform + to the ABC are declared to implement this interface. This is *not* + automatically updated as the ABC registry changes. If the body of the + interface definition defines ``extra_classes``, it should be a + tuple giving additional classes to declare implement the interface. + + Note that this is not fully symmetric. For example, it is usually + the case that a subclass relationship carries the interface + declarations over:: + + >>> from zope.interface import Interface + >>> class I1(Interface): + ... pass + ... + >>> from zope.interface import implementer + >>> @implementer(I1) + ... class Root(object): + ... pass + ... + >>> class Child(Root): + ... pass + ... + >>> child = Child() + >>> isinstance(child, Root) + True + >>> from zope.interface import providedBy + >>> list(providedBy(child)) + [<InterfaceClass __main__.I1>] + + However, that's not the case with ABCs and ABC interfaces. Just + because ``isinstance(A(), AnABC)`` and ``isinstance(B(), AnABC)`` + are both true, that doesn't mean there's any class hierarchy + relationship between ``A`` and ``B``, or between either of them + and ``AnABC``. Thus, if ``AnABC`` implemented ``IAnABC``, it would + not follow that either ``A`` or ``B`` implements ``IAnABC`` (nor + their instances provide it):: + + >>> class SizedClass(object): + ... def __len__(self): return 1 + ... + >>> from collections.abc import Sized + >>> isinstance(SizedClass(), Sized) + True + >>> from zope.interface import classImplements + >>> classImplements(Sized, I1) + None + >>> list(providedBy(SizedClass())) + [] + + Thus, to avoid conflicting assumptions, ABCs should not be + declared to implement their parallel ABC interface. Only concrete + classes specifically registered with the ABC should be declared to + do so. + + .. versionadded:: 5.0.0 + """ + + # If we could figure out invalidation, and used some special + # Specification/Declaration instances, and override the method ``providedBy`` here, + # perhaps we could more closely integrate with ABC virtual inheritance? + + def __init__(self, name, bases, attrs): + # go ahead and give us a name to ease debugging. + self.__name__ = name + extra_classes = attrs.pop('extra_classes', ()) + ignored_classes = attrs.pop('ignored_classes', ()) + + if 'abc' not in attrs: + # Something like ``IList(ISequence)``: We're extending + # abc interfaces but not an ABC interface ourself. + InterfaceClass.__init__(self, name, bases, attrs) + ABCInterfaceClass.__register_classes(self, extra_classes, ignored_classes) + self.__class__ = InterfaceClass + return + + based_on = attrs.pop('abc') + self.__abc = based_on + self.__extra_classes = tuple(extra_classes) + self.__ignored_classes = tuple(ignored_classes) + + assert name[1:] == based_on.__name__, (name, based_on) + methods = { + # Passing the name is important in case of aliases, + # e.g., ``__ror__ = __or__``. + k: self.__method_from_function(v, k) + for k, v in vars(based_on).items() + if isinstance(v, FunctionType) and not self.__is_private_name(k) + and not self.__is_reverse_protocol_name(k) + } + + methods['__doc__'] = self.__create_class_doc(attrs) + # Anything specified in the body takes precedence. + methods.update(attrs) + InterfaceClass.__init__(self, name, bases, methods) + self.__register_classes() + + @staticmethod + def __optional_methods_to_docs(attrs): + optionals = {k: v for k, v in attrs.items() if isinstance(v, optional)} + for k in optionals: + attrs[k] = _decorator_non_return + + if not optionals: + return '' + + docs = "\n\nThe following methods are optional:\n - " + "\n-".join( + "{}\n{}".format(k, v.__doc__) for k, v in optionals.items() + ) + return docs + + def __create_class_doc(self, attrs): + based_on = self.__abc + def ref(c): + mod = c.__module__ + name = c.__name__ + if mod == str.__module__: + return "`%s`" % name + if mod == '_io': + mod = 'io' + return "`{}.{}`".format(mod, name) + implementations_doc = "\n - ".join( + ref(c) + for c in sorted(self.getRegisteredConformers(), key=ref) + ) + if implementations_doc: + implementations_doc = "\n\nKnown implementations are:\n\n - " + implementations_doc + + based_on_doc = (based_on.__doc__ or '') + based_on_doc = based_on_doc.splitlines() + based_on_doc = based_on_doc[0] if based_on_doc else '' + + doc = """Interface for the ABC `{}.{}`.\n\n{}{}{}""".format( + based_on.__module__, based_on.__name__, + attrs.get('__doc__', based_on_doc), + self.__optional_methods_to_docs(attrs), + implementations_doc + ) + return doc + + + @staticmethod + def __is_private_name(name): + if name.startswith('__') and name.endswith('__'): + return False + return name.startswith('_') + + @staticmethod + def __is_reverse_protocol_name(name): + # The reverse names, like __rand__, + # aren't really part of the protocol. The interpreter has + # very complex behaviour around invoking those. PyPy + # doesn't always even expose them as attributes. + return name.startswith('__r') and name.endswith('__') + + def __method_from_function(self, function, name): + method = fromFunction(function, self, name=name) + # Eliminate the leading *self*, which is implied in + # an interface, but explicit in an ABC. + method.positional = method.positional[1:] + return method + + def __register_classes(self, conformers=None, ignored_classes=None): + # Make the concrete classes already present in our ABC's registry + # declare that they implement this interface. + conformers = conformers if conformers is not None else self.getRegisteredConformers() + ignored = ignored_classes if ignored_classes is not None else self.__ignored_classes + for cls in conformers: + if cls in ignored: + continue + classImplements(cls, self) + + def getABC(self): + """ + Return the ABC this interface represents. + """ + return self.__abc + + def getRegisteredConformers(self): + """ + Return an iterable of the classes that are known to conform to + the ABC this interface parallels. + """ + based_on = self.__abc + + # The registry only contains things that aren't already + # known to be subclasses of the ABC. But the ABC is in charge + # of checking that, so its quite possible that registrations + # are in fact ignored, winding up just in the _abc_cache. + try: + registered = list(based_on._abc_registry) + list(based_on._abc_cache) + except AttributeError: + # Rewritten in C in CPython 3.7. + # These expose the underlying weakref. + from abc import _get_dump + data = _get_dump(based_on) + registry = data[0] + cache = data[1] + registered = [x() for x in itertools.chain(registry, cache)] + registered = [x for x in registered if x is not None] + + return set(itertools.chain(registered, self.__extra_classes)) + + +def _create_ABCInterface(): + # It's a two-step process to create the root ABCInterface, because + # without specifying a corresponding ABC, using the normal constructor + # gets us a plain InterfaceClass object, and there is no ABC to associate with the + # root. + abc_name_bases_attrs = ('ABCInterface', (Interface,), {}) + instance = ABCInterfaceClass.__new__(ABCInterfaceClass, *abc_name_bases_attrs) + InterfaceClass.__init__(instance, *abc_name_bases_attrs) + return instance + +ABCInterface = _create_ABCInterface() diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/builtins.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/builtins.py new file mode 100644 index 00000000..17090e4a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/builtins.py @@ -0,0 +1,119 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +""" +Interface definitions for builtin types. + +After this module is imported, the standard library types will declare +that they implement the appropriate interface. + +.. versionadded:: 5.0.0 +""" + +from zope.interface import classImplements + +from zope.interface.common import collections +from zope.interface.common import numbers +from zope.interface.common import io + +__all__ = [ + 'IList', + 'ITuple', + 'ITextString', + 'IByteString', + 'INativeString', + 'IBool', + 'IDict', + 'IFile', +] + +# pylint:disable=no-self-argument +class IList(collections.IMutableSequence): + """ + Interface for :class:`list` + """ + extra_classes = (list,) + + def sort(key=None, reverse=False): + """ + Sort the list in place and return None. + + *key* and *reverse* must be passed by name only. + """ + + +class ITuple(collections.ISequence): + """ + Interface for :class:`tuple` + """ + extra_classes = (tuple,) + + +class ITextString(collections.ISequence): + """ + Interface for text ("unicode") strings. + + This is :class:`str` + """ + extra_classes = (str,) + + +class IByteString(collections.IByteString): + """ + Interface for immutable byte strings. + + On all Python versions this is :class:`bytes`. + + Unlike :class:`zope.interface.common.collections.IByteString` + (the parent of this interface) this does *not* include + :class:`bytearray`. + """ + extra_classes = (bytes,) + + +class INativeString(ITextString): + """ + Interface for native strings. + + On all Python versions, this is :class:`str`. Tt extends + :class:`ITextString`. + """ +# We're not extending ABCInterface so extra_classes won't work +classImplements(str, INativeString) + + +class IBool(numbers.IIntegral): + """ + Interface for :class:`bool` + """ + extra_classes = (bool,) + + +class IDict(collections.IMutableMapping): + """ + Interface for :class:`dict` + """ + extra_classes = (dict,) + + +class IFile(io.IIOBase): + """ + Interface for :class:`file`. + + It is recommended to use the interfaces from :mod:`zope.interface.common.io` + instead of this interface. + + On Python 3, there is no single implementation of this interface; + depending on the arguments, the :func:`open` builtin can return + many different classes that implement different interfaces from + :mod:`zope.interface.common.io`. + """ + extra_classes = () diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/collections.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/collections.py new file mode 100644 index 00000000..c5490282 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/collections.py @@ -0,0 +1,253 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +""" +Interface definitions paralleling the abstract base classes defined in +:mod:`collections.abc`. + +After this module is imported, the standard library types will declare +that they implement the appropriate interface. While most standard +library types will properly implement that interface (that +is, ``verifyObject(ISequence, list()))`` will pass, for example), a few might not: + + - `memoryview` doesn't feature all the defined methods of + ``ISequence`` such as ``count``; it is still declared to provide + ``ISequence`` though. + + - `collections.deque.pop` doesn't accept the ``index`` argument of + `collections.abc.MutableSequence.pop` + + - `range.index` does not accept the ``start`` and ``stop`` arguments. + +.. versionadded:: 5.0.0 +""" + +import sys + +from abc import ABCMeta +from collections import abc +from collections import OrderedDict +from collections import UserList +from collections import UserDict +from collections import UserString + +from zope.interface.common import ABCInterface +from zope.interface.common import optional + +# pylint:disable=inherit-non-class, +# pylint:disable=no-self-argument,no-method-argument +# pylint:disable=unexpected-special-method-signature +# pylint:disable=no-value-for-parameter + + +def _new_in_ver(name, ver, + bases_if_missing=(ABCMeta,), + register_if_missing=()): + if ver: + return getattr(abc, name) + + # TODO: It's a shame to have to repeat the bases when + # the ABC is missing. Can we DRY that? + missing = ABCMeta(name, bases_if_missing, { + '__doc__': "The ABC %s is not defined in this version of Python." % ( + name + ), + }) + + for c in register_if_missing: + missing.register(c) + + return missing + +__all__ = [ + 'IAsyncGenerator', + 'IAsyncIterable', + 'IAsyncIterator', + 'IAwaitable', + 'ICollection', + 'IContainer', + 'ICoroutine', + 'IGenerator', + 'IHashable', + 'IItemsView', + 'IIterable', + 'IIterator', + 'IKeysView', + 'IMapping', + 'IMappingView', + 'IMutableMapping', + 'IMutableSequence', + 'IMutableSet', + 'IReversible', + 'ISequence', + 'ISet', + 'ISized', + 'IValuesView', +] + +class IContainer(ABCInterface): + abc = abc.Container + + @optional + def __contains__(other): + """ + Optional method. If not provided, the interpreter will use + ``__iter__`` or the old ``__getitem__`` protocol + to implement ``in``. + """ + +class IHashable(ABCInterface): + abc = abc.Hashable + +class IIterable(ABCInterface): + abc = abc.Iterable + + @optional + def __iter__(): + """ + Optional method. If not provided, the interpreter will + implement `iter` using the old ``__getitem__`` protocol. + """ + +class IIterator(IIterable): + abc = abc.Iterator + +class IReversible(IIterable): + abc = _new_in_ver('Reversible', True, (IIterable.getABC(),)) + + @optional + def __reversed__(): + """ + Optional method. If this isn't present, the interpreter + will use ``__len__`` and ``__getitem__`` to implement the + `reversed` builtin. + """ + +class IGenerator(IIterator): + # New in Python 3.5 + abc = _new_in_ver('Generator', True, (IIterator.getABC(),)) + + +class ISized(ABCInterface): + abc = abc.Sized + + +# ICallable is not defined because there's no standard signature. + +class ICollection(ISized, + IIterable, + IContainer): + abc = _new_in_ver('Collection', True, + (ISized.getABC(), IIterable.getABC(), IContainer.getABC())) + + +class ISequence(IReversible, + ICollection): + abc = abc.Sequence + extra_classes = (UserString,) + # On Python 2, basestring is registered as an ISequence, and + # its subclass str is an IByteString. If we also register str as + # an ISequence, that tends to lead to inconsistent resolution order. + ignored_classes = (basestring,) if str is bytes else () # pylint:disable=undefined-variable + + @optional + def __reversed__(): + """ + Optional method. If this isn't present, the interpreter + will use ``__len__`` and ``__getitem__`` to implement the + `reversed` builtin. + """ + + @optional + def __iter__(): + """ + Optional method. If not provided, the interpreter will + implement `iter` using the old ``__getitem__`` protocol. + """ + +class IMutableSequence(ISequence): + abc = abc.MutableSequence + extra_classes = (UserList,) + + +class IByteString(ISequence): + """ + This unifies `bytes` and `bytearray`. + """ + abc = _new_in_ver('ByteString', True, + (ISequence.getABC(),), + (bytes, bytearray)) + + +class ISet(ICollection): + abc = abc.Set + + +class IMutableSet(ISet): + abc = abc.MutableSet + + +class IMapping(ICollection): + abc = abc.Mapping + extra_classes = (dict,) + # OrderedDict is a subclass of dict. On CPython 2, + # it winds up registered as a IMutableMapping, which + # produces an inconsistent IRO if we also try to register it + # here. + ignored_classes = (OrderedDict,) + + +class IMutableMapping(IMapping): + abc = abc.MutableMapping + extra_classes = (dict, UserDict,) + ignored_classes = (OrderedDict,) + +class IMappingView(ISized): + abc = abc.MappingView + + +class IItemsView(IMappingView, ISet): + abc = abc.ItemsView + + +class IKeysView(IMappingView, ISet): + abc = abc.KeysView + + +class IValuesView(IMappingView, ICollection): + abc = abc.ValuesView + + @optional + def __contains__(other): + """ + Optional method. If not provided, the interpreter will use + ``__iter__`` or the old ``__len__`` and ``__getitem__`` protocol + to implement ``in``. + """ + +class IAwaitable(ABCInterface): + abc = _new_in_ver('Awaitable', True) + + +class ICoroutine(IAwaitable): + abc = _new_in_ver('Coroutine', True) + + +class IAsyncIterable(ABCInterface): + abc = _new_in_ver('AsyncIterable', True) + + +class IAsyncIterator(IAsyncIterable): + abc = _new_in_ver('AsyncIterator', True) + + +class IAsyncGenerator(IAsyncIterator): + abc = _new_in_ver('AsyncGenerator', True) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/idatetime.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/idatetime.py new file mode 100644 index 00000000..82f0059c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/idatetime.py @@ -0,0 +1,606 @@ +############################################################################## +# Copyright (c) 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +"""Datetime interfaces. + +This module is called idatetime because if it were called datetime the import +of the real datetime would fail. +""" +from datetime import timedelta, date, datetime, time, tzinfo + +from zope.interface import Interface, Attribute +from zope.interface import classImplements + + +class ITimeDeltaClass(Interface): + """This is the timedelta class interface. + + This is symbolic; this module does **not** make + `datetime.timedelta` provide this interface. + """ + + min = Attribute("The most negative timedelta object") + + max = Attribute("The most positive timedelta object") + + resolution = Attribute( + "The smallest difference between non-equal timedelta objects") + + +class ITimeDelta(ITimeDeltaClass): + """Represent the difference between two datetime objects. + + Implemented by `datetime.timedelta`. + + Supported operators: + + - add, subtract timedelta + - unary plus, minus, abs + - compare to timedelta + - multiply, divide by int/long + + In addition, `.datetime` supports subtraction of two `.datetime` objects + returning a `.timedelta`, and addition or subtraction of a `.datetime` + and a `.timedelta` giving a `.datetime`. + + Representation: (days, seconds, microseconds). + """ + + days = Attribute("Days between -999999999 and 999999999 inclusive") + + seconds = Attribute("Seconds between 0 and 86399 inclusive") + + microseconds = Attribute("Microseconds between 0 and 999999 inclusive") + + +class IDateClass(Interface): + """This is the date class interface. + + This is symbolic; this module does **not** make + `datetime.date` provide this interface. + """ + + min = Attribute("The earliest representable date") + + max = Attribute("The latest representable date") + + resolution = Attribute( + "The smallest difference between non-equal date objects") + + def today(): + """Return the current local time. + + This is equivalent to ``date.fromtimestamp(time.time())``""" + + def fromtimestamp(timestamp): + """Return the local date from a POSIX timestamp (like time.time()) + + This may raise `ValueError`, if the timestamp is out of the range of + values supported by the platform C ``localtime()`` function. It's common + for this to be restricted to years from 1970 through 2038. Note that + on non-POSIX systems that include leap seconds in their notion of a + timestamp, leap seconds are ignored by `fromtimestamp`. + """ + + def fromordinal(ordinal): + """Return the date corresponding to the proleptic Gregorian ordinal. + + January 1 of year 1 has ordinal 1. `ValueError` is raised unless + 1 <= ordinal <= date.max.toordinal(). + + For any date *d*, ``date.fromordinal(d.toordinal()) == d``. + """ + + +class IDate(IDateClass): + """Represents a date (year, month and day) in an idealized calendar. + + Implemented by `datetime.date`. + + Operators: + + __repr__, __str__ + __cmp__, __hash__ + __add__, __radd__, __sub__ (add/radd only with timedelta arg) + """ + + year = Attribute("Between MINYEAR and MAXYEAR inclusive.") + + month = Attribute("Between 1 and 12 inclusive") + + day = Attribute( + "Between 1 and the number of days in the given month of the given year.") + + def replace(year, month, day): + """Return a date with the same value. + + Except for those members given new values by whichever keyword + arguments are specified. For example, if ``d == date(2002, 12, 31)``, then + ``d.replace(day=26) == date(2000, 12, 26)``. + """ + + def timetuple(): + """Return a 9-element tuple of the form returned by `time.localtime`. + + The hours, minutes and seconds are 0, and the DST flag is -1. + ``d.timetuple()`` is equivalent to + ``(d.year, d.month, d.day, 0, 0, 0, d.weekday(), d.toordinal() - + date(d.year, 1, 1).toordinal() + 1, -1)`` + """ + + def toordinal(): + """Return the proleptic Gregorian ordinal of the date + + January 1 of year 1 has ordinal 1. For any date object *d*, + ``date.fromordinal(d.toordinal()) == d``. + """ + + def weekday(): + """Return the day of the week as an integer. + + Monday is 0 and Sunday is 6. For example, + ``date(2002, 12, 4).weekday() == 2``, a Wednesday. + + .. seealso:: `isoweekday`. + """ + + def isoweekday(): + """Return the day of the week as an integer. + + Monday is 1 and Sunday is 7. For example, + date(2002, 12, 4).isoweekday() == 3, a Wednesday. + + .. seealso:: `weekday`, `isocalendar`. + """ + + def isocalendar(): + """Return a 3-tuple, (ISO year, ISO week number, ISO weekday). + + The ISO calendar is a widely used variant of the Gregorian calendar. + See http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. + + The ISO year consists of 52 or 53 full weeks, and where a week starts + on a Monday and ends on a Sunday. The first week of an ISO year is the + first (Gregorian) calendar week of a year containing a Thursday. This + is called week number 1, and the ISO year of that Thursday is the same + as its Gregorian year. + + For example, 2004 begins on a Thursday, so the first week of ISO year + 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004, so + that ``date(2003, 12, 29).isocalendar() == (2004, 1, 1)`` and + ``date(2004, 1, 4).isocalendar() == (2004, 1, 7)``. + """ + + def isoformat(): + """Return a string representing the date in ISO 8601 format. + + This is 'YYYY-MM-DD'. + For example, ``date(2002, 12, 4).isoformat() == '2002-12-04'``. + """ + + def __str__(): + """For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``.""" + + def ctime(): + """Return a string representing the date. + + For example date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'. + d.ctime() is equivalent to time.ctime(time.mktime(d.timetuple())) + on platforms where the native C ctime() function + (which `time.ctime` invokes, but which date.ctime() does not invoke) + conforms to the C standard. + """ + + def strftime(format): + """Return a string representing the date. + + Controlled by an explicit format string. Format codes referring to + hours, minutes or seconds will see 0 values. + """ + + +class IDateTimeClass(Interface): + """This is the datetime class interface. + + This is symbolic; this module does **not** make + `datetime.datetime` provide this interface. + """ + + min = Attribute("The earliest representable datetime") + + max = Attribute("The latest representable datetime") + + resolution = Attribute( + "The smallest possible difference between non-equal datetime objects") + + def today(): + """Return the current local datetime, with tzinfo None. + + This is equivalent to ``datetime.fromtimestamp(time.time())``. + + .. seealso:: `now`, `fromtimestamp`. + """ + + def now(tz=None): + """Return the current local date and time. + + If optional argument *tz* is None or not specified, this is like `today`, + but, if possible, supplies more precision than can be gotten from going + through a `time.time` timestamp (for example, this may be possible on + platforms supplying the C ``gettimeofday()`` function). + + Else tz must be an instance of a class tzinfo subclass, and the current + date and time are converted to tz's time zone. In this case the result + is equivalent to tz.fromutc(datetime.utcnow().replace(tzinfo=tz)). + + .. seealso:: `today`, `utcnow`. + """ + + def utcnow(): + """Return the current UTC date and time, with tzinfo None. + + This is like `now`, but returns the current UTC date and time, as a + naive datetime object. + + .. seealso:: `now`. + """ + + def fromtimestamp(timestamp, tz=None): + """Return the local date and time corresponding to the POSIX timestamp. + + Same as is returned by time.time(). If optional argument tz is None or + not specified, the timestamp is converted to the platform's local date + and time, and the returned datetime object is naive. + + Else tz must be an instance of a class tzinfo subclass, and the + timestamp is converted to tz's time zone. In this case the result is + equivalent to + ``tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))``. + + fromtimestamp() may raise `ValueError`, if the timestamp is out of the + range of values supported by the platform C localtime() or gmtime() + functions. It's common for this to be restricted to years in 1970 + through 2038. Note that on non-POSIX systems that include leap seconds + in their notion of a timestamp, leap seconds are ignored by + fromtimestamp(), and then it's possible to have two timestamps + differing by a second that yield identical datetime objects. + + .. seealso:: `utcfromtimestamp`. + """ + + def utcfromtimestamp(timestamp): + """Return the UTC datetime from the POSIX timestamp with tzinfo None. + + This may raise `ValueError`, if the timestamp is out of the range of + values supported by the platform C ``gmtime()`` function. It's common for + this to be restricted to years in 1970 through 2038. + + .. seealso:: `fromtimestamp`. + """ + + def fromordinal(ordinal): + """Return the datetime from the proleptic Gregorian ordinal. + + January 1 of year 1 has ordinal 1. `ValueError` is raised unless + 1 <= ordinal <= datetime.max.toordinal(). + The hour, minute, second and microsecond of the result are all 0, and + tzinfo is None. + """ + + def combine(date, time): + """Return a new datetime object. + + Its date members are equal to the given date object's, and whose time + and tzinfo members are equal to the given time object's. For any + datetime object *d*, ``d == datetime.combine(d.date(), d.timetz())``. + If date is a datetime object, its time and tzinfo members are ignored. + """ + + +class IDateTime(IDate, IDateTimeClass): + """Object contains all the information from a date object and a time object. + + Implemented by `datetime.datetime`. + """ + + year = Attribute("Year between MINYEAR and MAXYEAR inclusive") + + month = Attribute("Month between 1 and 12 inclusive") + + day = Attribute( + "Day between 1 and the number of days in the given month of the year") + + hour = Attribute("Hour in range(24)") + + minute = Attribute("Minute in range(60)") + + second = Attribute("Second in range(60)") + + microsecond = Attribute("Microsecond in range(1000000)") + + tzinfo = Attribute( + """The object passed as the tzinfo argument to the datetime constructor + or None if none was passed""") + + def date(): + """Return date object with same year, month and day.""" + + def time(): + """Return time object with same hour, minute, second, microsecond. + + tzinfo is None. + + .. seealso:: Method :meth:`timetz`. + """ + + def timetz(): + """Return time object with same hour, minute, second, microsecond, + and tzinfo. + + .. seealso:: Method :meth:`time`. + """ + + def replace(year, month, day, hour, minute, second, microsecond, tzinfo): + """Return a datetime with the same members, except for those members + given new values by whichever keyword arguments are specified. + + Note that ``tzinfo=None`` can be specified to create a naive datetime from + an aware datetime with no conversion of date and time members. + """ + + def astimezone(tz): + """Return a datetime object with new tzinfo member tz, adjusting the + date and time members so the result is the same UTC time as self, but + in tz's local time. + + tz must be an instance of a tzinfo subclass, and its utcoffset() and + dst() methods must not return None. self must be aware (self.tzinfo + must not be None, and self.utcoffset() must not return None). + + If self.tzinfo is tz, self.astimezone(tz) is equal to self: no + adjustment of date or time members is performed. Else the result is + local time in time zone tz, representing the same UTC time as self: + + after astz = dt.astimezone(tz), astz - astz.utcoffset() + + will usually have the same date and time members as dt - dt.utcoffset(). + The discussion of class `datetime.tzinfo` explains the cases at Daylight Saving + Time transition boundaries where this cannot be achieved (an issue only + if tz models both standard and daylight time). + + If you merely want to attach a time zone object *tz* to a datetime *dt* + without adjustment of date and time members, use ``dt.replace(tzinfo=tz)``. + If you merely want to remove the time zone object from an aware + datetime dt without conversion of date and time members, use + ``dt.replace(tzinfo=None)``. + + Note that the default `tzinfo.fromutc` method can be overridden in a + tzinfo subclass to effect the result returned by `astimezone`. + """ + + def utcoffset(): + """Return the timezone offset in minutes east of UTC (negative west of + UTC).""" + + def dst(): + """Return 0 if DST is not in effect, or the DST offset (in minutes + eastward) if DST is in effect. + """ + + def tzname(): + """Return the timezone name.""" + + def timetuple(): + """Return a 9-element tuple of the form returned by `time.localtime`.""" + + def utctimetuple(): + """Return UTC time tuple compatilble with `time.gmtime`.""" + + def toordinal(): + """Return the proleptic Gregorian ordinal of the date. + + The same as self.date().toordinal(). + """ + + def weekday(): + """Return the day of the week as an integer. + + Monday is 0 and Sunday is 6. The same as self.date().weekday(). + See also isoweekday(). + """ + + def isoweekday(): + """Return the day of the week as an integer. + + Monday is 1 and Sunday is 7. The same as self.date().isoweekday. + + .. seealso:: `weekday`, `isocalendar`. + """ + + def isocalendar(): + """Return a 3-tuple, (ISO year, ISO week number, ISO weekday). + + The same as self.date().isocalendar(). + """ + + def isoformat(sep='T'): + """Return a string representing the date and time in ISO 8601 format. + + YYYY-MM-DDTHH:MM:SS.mmmmmm or YYYY-MM-DDTHH:MM:SS if microsecond is 0 + + If `utcoffset` does not return None, a 6-character string is appended, + giving the UTC offset in (signed) hours and minutes: + + YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or YYYY-MM-DDTHH:MM:SS+HH:MM + if microsecond is 0. + + The optional argument sep (default 'T') is a one-character separator, + placed between the date and time portions of the result. + """ + + def __str__(): + """For a datetime instance *d*, ``str(d)`` is equivalent to ``d.isoformat(' ')``. + """ + + def ctime(): + """Return a string representing the date and time. + + ``datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'``. + ``d.ctime()`` is equivalent to ``time.ctime(time.mktime(d.timetuple()))`` on + platforms where the native C ``ctime()`` function (which `time.ctime` + invokes, but which `datetime.ctime` does not invoke) conforms to the + C standard. + """ + + def strftime(format): + """Return a string representing the date and time. + + This is controlled by an explicit format string. + """ + + +class ITimeClass(Interface): + """This is the time class interface. + + This is symbolic; this module does **not** make + `datetime.time` provide this interface. + + """ + + min = Attribute("The earliest representable time") + + max = Attribute("The latest representable time") + + resolution = Attribute( + "The smallest possible difference between non-equal time objects") + + +class ITime(ITimeClass): + """Represent time with time zone. + + Implemented by `datetime.time`. + + Operators: + + __repr__, __str__ + __cmp__, __hash__ + """ + + hour = Attribute("Hour in range(24)") + + minute = Attribute("Minute in range(60)") + + second = Attribute("Second in range(60)") + + microsecond = Attribute("Microsecond in range(1000000)") + + tzinfo = Attribute( + """The object passed as the tzinfo argument to the time constructor + or None if none was passed.""") + + def replace(hour, minute, second, microsecond, tzinfo): + """Return a time with the same value. + + Except for those members given new values by whichever keyword + arguments are specified. Note that tzinfo=None can be specified + to create a naive time from an aware time, without conversion of the + time members. + """ + + def isoformat(): + """Return a string representing the time in ISO 8601 format. + + That is HH:MM:SS.mmmmmm or, if self.microsecond is 0, HH:MM:SS + If utcoffset() does not return None, a 6-character string is appended, + giving the UTC offset in (signed) hours and minutes: + HH:MM:SS.mmmmmm+HH:MM or, if self.microsecond is 0, HH:MM:SS+HH:MM + """ + + def __str__(): + """For a time t, str(t) is equivalent to t.isoformat().""" + + def strftime(format): + """Return a string representing the time. + + This is controlled by an explicit format string. + """ + + def utcoffset(): + """Return the timezone offset in minutes east of UTC (negative west of + UTC). + + If tzinfo is None, returns None, else returns + self.tzinfo.utcoffset(None), and raises an exception if the latter + doesn't return None or a timedelta object representing a whole number + of minutes with magnitude less than one day. + """ + + def dst(): + """Return 0 if DST is not in effect, or the DST offset (in minutes + eastward) if DST is in effect. + + If tzinfo is None, returns None, else returns self.tzinfo.dst(None), + and raises an exception if the latter doesn't return None, or a + timedelta object representing a whole number of minutes with + magnitude less than one day. + """ + + def tzname(): + """Return the timezone name. + + If tzinfo is None, returns None, else returns self.tzinfo.tzname(None), + or raises an exception if the latter doesn't return None or a string + object. + """ + + +class ITZInfo(Interface): + """Time zone info class. + """ + + def utcoffset(dt): + """Return offset of local time from UTC, in minutes east of UTC. + + If local time is west of UTC, this should be negative. + Note that this is intended to be the total offset from UTC; + for example, if a tzinfo object represents both time zone and DST + adjustments, utcoffset() should return their sum. If the UTC offset + isn't known, return None. Else the value returned must be a timedelta + object specifying a whole number of minutes in the range -1439 to 1439 + inclusive (1440 = 24*60; the magnitude of the offset must be less + than one day). + """ + + def dst(dt): + """Return the daylight saving time (DST) adjustment, in minutes east + of UTC, or None if DST information isn't known. + """ + + def tzname(dt): + """Return the time zone name corresponding to the datetime object as + a string. + """ + + def fromutc(dt): + """Return an equivalent datetime in self's local time.""" + + +classImplements(timedelta, ITimeDelta) +classImplements(date, IDate) +classImplements(datetime, IDateTime) +classImplements(time, ITime) +classImplements(tzinfo, ITZInfo) + +## directlyProvides(timedelta, ITimeDeltaClass) +## directlyProvides(date, IDateClass) +## directlyProvides(datetime, IDateTimeClass) +## directlyProvides(time, ITimeClass) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/interfaces.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/interfaces.py new file mode 100644 index 00000000..70bd294f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/interfaces.py @@ -0,0 +1,208 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Interfaces for standard python exceptions +""" +from zope.interface import Interface +from zope.interface import classImplements + +class IException(Interface): + "Interface for `Exception`" +classImplements(Exception, IException) + + +class IStandardError(IException): + "Interface for `StandardError` (no longer existing.)" + + +class IWarning(IException): + "Interface for `Warning`" +classImplements(Warning, IWarning) + + +class ISyntaxError(IStandardError): + "Interface for `SyntaxError`" +classImplements(SyntaxError, ISyntaxError) + + +class ILookupError(IStandardError): + "Interface for `LookupError`" +classImplements(LookupError, ILookupError) + + +class IValueError(IStandardError): + "Interface for `ValueError`" +classImplements(ValueError, IValueError) + + +class IRuntimeError(IStandardError): + "Interface for `RuntimeError`" +classImplements(RuntimeError, IRuntimeError) + + +class IArithmeticError(IStandardError): + "Interface for `ArithmeticError`" +classImplements(ArithmeticError, IArithmeticError) + + +class IAssertionError(IStandardError): + "Interface for `AssertionError`" +classImplements(AssertionError, IAssertionError) + + +class IAttributeError(IStandardError): + "Interface for `AttributeError`" +classImplements(AttributeError, IAttributeError) + + +class IDeprecationWarning(IWarning): + "Interface for `DeprecationWarning`" +classImplements(DeprecationWarning, IDeprecationWarning) + + +class IEOFError(IStandardError): + "Interface for `EOFError`" +classImplements(EOFError, IEOFError) + + +class IEnvironmentError(IStandardError): + "Interface for `EnvironmentError`" +classImplements(EnvironmentError, IEnvironmentError) + + +class IFloatingPointError(IArithmeticError): + "Interface for `FloatingPointError`" +classImplements(FloatingPointError, IFloatingPointError) + + +class IIOError(IEnvironmentError): + "Interface for `IOError`" +classImplements(IOError, IIOError) + + +class IImportError(IStandardError): + "Interface for `ImportError`" +classImplements(ImportError, IImportError) + + +class IIndentationError(ISyntaxError): + "Interface for `IndentationError`" +classImplements(IndentationError, IIndentationError) + + +class IIndexError(ILookupError): + "Interface for `IndexError`" +classImplements(IndexError, IIndexError) + + +class IKeyError(ILookupError): + "Interface for `KeyError`" +classImplements(KeyError, IKeyError) + + +class IKeyboardInterrupt(IStandardError): + "Interface for `KeyboardInterrupt`" +classImplements(KeyboardInterrupt, IKeyboardInterrupt) + + +class IMemoryError(IStandardError): + "Interface for `MemoryError`" +classImplements(MemoryError, IMemoryError) + + +class INameError(IStandardError): + "Interface for `NameError`" +classImplements(NameError, INameError) + + +class INotImplementedError(IRuntimeError): + "Interface for `NotImplementedError`" +classImplements(NotImplementedError, INotImplementedError) + + +class IOSError(IEnvironmentError): + "Interface for `OSError`" +classImplements(OSError, IOSError) + + +class IOverflowError(IArithmeticError): + "Interface for `ArithmeticError`" +classImplements(OverflowError, IOverflowError) + + +class IOverflowWarning(IWarning): + """Deprecated, no standard class implements this. + + This was the interface for ``OverflowWarning`` prior to Python 2.5, + but that class was removed for all versions after that. + """ + + +class IReferenceError(IStandardError): + "Interface for `ReferenceError`" +classImplements(ReferenceError, IReferenceError) + + +class IRuntimeWarning(IWarning): + "Interface for `RuntimeWarning`" +classImplements(RuntimeWarning, IRuntimeWarning) + + +class IStopIteration(IException): + "Interface for `StopIteration`" +classImplements(StopIteration, IStopIteration) + + +class ISyntaxWarning(IWarning): + "Interface for `SyntaxWarning`" +classImplements(SyntaxWarning, ISyntaxWarning) + + +class ISystemError(IStandardError): + "Interface for `SystemError`" +classImplements(SystemError, ISystemError) + + +class ISystemExit(IException): + "Interface for `SystemExit`" +classImplements(SystemExit, ISystemExit) + + +class ITabError(IIndentationError): + "Interface for `TabError`" +classImplements(TabError, ITabError) + + +class ITypeError(IStandardError): + "Interface for `TypeError`" +classImplements(TypeError, ITypeError) + + +class IUnboundLocalError(INameError): + "Interface for `UnboundLocalError`" +classImplements(UnboundLocalError, IUnboundLocalError) + + +class IUnicodeError(IValueError): + "Interface for `UnicodeError`" +classImplements(UnicodeError, IUnicodeError) + + +class IUserWarning(IWarning): + "Interface for `UserWarning`" +classImplements(UserWarning, IUserWarning) + + +class IZeroDivisionError(IArithmeticError): + "Interface for `ZeroDivisionError`" +classImplements(ZeroDivisionError, IZeroDivisionError) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/io.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/io.py new file mode 100644 index 00000000..0d6f3bad --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/io.py @@ -0,0 +1,43 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +""" +Interface definitions paralleling the abstract base classes defined in +:mod:`io`. + +After this module is imported, the standard library types will declare +that they implement the appropriate interface. + +.. versionadded:: 5.0.0 +""" + +import io as abc + +from zope.interface.common import ABCInterface + +# pylint:disable=inherit-non-class, +# pylint:disable=no-member + +class IIOBase(ABCInterface): + abc = abc.IOBase + + +class IRawIOBase(IIOBase): + abc = abc.RawIOBase + + +class IBufferedIOBase(IIOBase): + abc = abc.BufferedIOBase + extra_classes = () + + +class ITextIOBase(IIOBase): + abc = abc.TextIOBase diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/mapping.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/mapping.py new file mode 100644 index 00000000..d0433335 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/mapping.py @@ -0,0 +1,168 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" +Mapping Interfaces. + +Importing this module does *not* mark any standard classes as +implementing any of these interfaces. + +While this module is not deprecated, new code should generally use +:mod:`zope.interface.common.collections`, specifically +:class:`~zope.interface.common.collections.IMapping` and +:class:`~zope.interface.common.collections.IMutableMapping`. This +module is occasionally useful for its extremely fine grained breakdown +of interfaces. + +The standard library :class:`dict` and :class:`collections.UserDict` +implement ``IMutableMapping``, but *do not* implement any of the +interfaces in this module. +""" +from zope.interface import Interface +from zope.interface.common import collections + +class IItemMapping(Interface): + """Simplest readable mapping object + """ + + def __getitem__(key): + """Get a value for a key + + A `KeyError` is raised if there is no value for the key. + """ + + +class IReadMapping(collections.IContainer, IItemMapping): + """ + Basic mapping interface. + + .. versionchanged:: 5.0.0 + Extend ``IContainer`` + """ + + def get(key, default=None): + """Get a value for a key + + The default is returned if there is no value for the key. + """ + + def __contains__(key): + """Tell if a key exists in the mapping.""" + # Optional in IContainer, required by this interface. + + +class IWriteMapping(Interface): + """Mapping methods for changing data""" + + def __delitem__(key): + """Delete a value from the mapping using the key.""" + + def __setitem__(key, value): + """Set a new item in the mapping.""" + + +class IEnumerableMapping(collections.ISized, IReadMapping): + """ + Mapping objects whose items can be enumerated. + + .. versionchanged:: 5.0.0 + Extend ``ISized`` + """ + + def keys(): + """Return the keys of the mapping object. + """ + + def __iter__(): + """Return an iterator for the keys of the mapping object. + """ + + def values(): + """Return the values of the mapping object. + """ + + def items(): + """Return the items of the mapping object. + """ + +class IMapping(IWriteMapping, IEnumerableMapping): + ''' Simple mapping interface ''' + +class IIterableMapping(IEnumerableMapping): + """A mapping that has distinct methods for iterating + without copying. + + """ + + +class IClonableMapping(Interface): + """Something that can produce a copy of itself. + + This is available in `dict`. + """ + + def copy(): + "return copy of dict" + +class IExtendedReadMapping(IIterableMapping): + """ + Something with a particular method equivalent to ``__contains__``. + + On Python 2, `dict` provided the ``has_key`` method, but it was removed + in Python 3. + """ + + +class IExtendedWriteMapping(IWriteMapping): + """Additional mutation methods. + + These are all provided by `dict`. + """ + + def clear(): + "delete all items" + + def update(d): + " Update D from E: for k in E.keys(): D[k] = E[k]" + + def setdefault(key, default=None): + "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D" + + def pop(k, default=None): + """ + pop(k[,default]) -> value + + Remove specified key and return the corresponding value. + + If key is not found, *default* is returned if given, otherwise + `KeyError` is raised. Note that *default* must not be passed by + name. + """ + + def popitem(): + """remove and return some (key, value) pair as a + 2-tuple; but raise KeyError if mapping is empty""" + +class IFullMapping( + collections.IMutableMapping, + IExtendedReadMapping, IExtendedWriteMapping, IClonableMapping, IMapping,): + """ + Full mapping interface. + + Most uses of this interface should instead use + :class:`~zope.interface.commons.collections.IMutableMapping` (one of the + bases of this interface). The required methods are the same. + + .. versionchanged:: 5.0.0 + Extend ``IMutableMapping`` + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/numbers.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/numbers.py new file mode 100644 index 00000000..6b20e09d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/numbers.py @@ -0,0 +1,65 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +""" +Interface definitions paralleling the abstract base classes defined in +:mod:`numbers`. + +After this module is imported, the standard library types will declare +that they implement the appropriate interface. + +.. versionadded:: 5.0.0 +""" + +import numbers as abc + +from zope.interface.common import ABCInterface +from zope.interface.common import optional + + +# pylint:disable=inherit-non-class, +# pylint:disable=no-self-argument,no-method-argument +# pylint:disable=unexpected-special-method-signature +# pylint:disable=no-value-for-parameter + + +class INumber(ABCInterface): + abc = abc.Number + + +class IComplex(INumber): + abc = abc.Complex + + @optional + def __complex__(): + """ + Rarely implemented, even in builtin types. + """ + + +class IReal(IComplex): + abc = abc.Real + + @optional + def __complex__(): + """ + Rarely implemented, even in builtin types. + """ + + __floor__ = __ceil__ = __complex__ + + +class IRational(IReal): + abc = abc.Rational + + +class IIntegral(IRational): + abc = abc.Integral diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/sequence.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/sequence.py new file mode 100644 index 00000000..5edc73dc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/sequence.py @@ -0,0 +1,189 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" +Sequence Interfaces + +Importing this module does *not* mark any standard classes as +implementing any of these interfaces. + +While this module is not deprecated, new code should generally use +:mod:`zope.interface.common.collections`, specifically +:class:`~zope.interface.common.collections.ISequence` and +:class:`~zope.interface.common.collections.IMutableSequence`. This +module is occasionally useful for its fine-grained breakdown of interfaces. + +The standard library :class:`list`, :class:`tuple` and +:class:`collections.UserList`, among others, implement ``ISequence`` +or ``IMutableSequence`` but *do not* implement any of the interfaces +in this module. +""" + +__docformat__ = 'restructuredtext' +from zope.interface import Interface +from zope.interface.common import collections + +class IMinimalSequence(collections.IIterable): + """Most basic sequence interface. + + All sequences are iterable. This requires at least one of the + following: + + - a `__getitem__()` method that takes a single argument; integer + values starting at 0 must be supported, and `IndexError` should + be raised for the first index for which there is no value, or + + - an `__iter__()` method that returns an iterator as defined in + the Python documentation (http://docs.python.org/lib/typeiter.html). + + """ + + def __getitem__(index): + """``x.__getitem__(index) <==> x[index]`` + + Declaring this interface does not specify whether `__getitem__` + supports slice objects.""" + +class IFiniteSequence(collections.ISized, IMinimalSequence): + """ + A sequence of bound size. + + .. versionchanged:: 5.0.0 + Extend ``ISized`` + """ + +class IReadSequence(collections.IContainer, IFiniteSequence): + """ + read interface shared by tuple and list + + This interface is similar to + :class:`~zope.interface.common.collections.ISequence`, but + requires that all instances be totally ordered. Most users + should prefer ``ISequence``. + + .. versionchanged:: 5.0.0 + Extend ``IContainer`` + """ + + def __contains__(item): + """``x.__contains__(item) <==> item in x``""" + # Optional in IContainer, required here. + + def __lt__(other): + """``x.__lt__(other) <==> x < other``""" + + def __le__(other): + """``x.__le__(other) <==> x <= other``""" + + def __eq__(other): + """``x.__eq__(other) <==> x == other``""" + + def __ne__(other): + """``x.__ne__(other) <==> x != other``""" + + def __gt__(other): + """``x.__gt__(other) <==> x > other``""" + + def __ge__(other): + """``x.__ge__(other) <==> x >= other``""" + + def __add__(other): + """``x.__add__(other) <==> x + other``""" + + def __mul__(n): + """``x.__mul__(n) <==> x * n``""" + + def __rmul__(n): + """``x.__rmul__(n) <==> n * x``""" + + +class IExtendedReadSequence(IReadSequence): + """Full read interface for lists""" + + def count(item): + """Return number of occurrences of value""" + + def index(item, *args): + """index(value, [start, [stop]]) -> int + + Return first index of *value* + """ + +class IUniqueMemberWriteSequence(Interface): + """The write contract for a sequence that may enforce unique members""" + + def __setitem__(index, item): + """``x.__setitem__(index, item) <==> x[index] = item`` + + Declaring this interface does not specify whether `__setitem__` + supports slice objects. + """ + + def __delitem__(index): + """``x.__delitem__(index) <==> del x[index]`` + + Declaring this interface does not specify whether `__delitem__` + supports slice objects. + """ + + def __iadd__(y): + """``x.__iadd__(y) <==> x += y``""" + + def append(item): + """Append item to end""" + + def insert(index, item): + """Insert item before index""" + + def pop(index=-1): + """Remove and return item at index (default last)""" + + def remove(item): + """Remove first occurrence of value""" + + def reverse(): + """Reverse *IN PLACE*""" + + def sort(cmpfunc=None): + """Stable sort *IN PLACE*; `cmpfunc(x, y)` -> -1, 0, 1""" + + def extend(iterable): + """Extend list by appending elements from the iterable""" + +class IWriteSequence(IUniqueMemberWriteSequence): + """Full write contract for sequences""" + + def __imul__(n): + """``x.__imul__(n) <==> x *= n``""" + +class ISequence(IReadSequence, IWriteSequence): + """ + Full sequence contract. + + New code should prefer + :class:`~zope.interface.common.collections.IMutableSequence`. + + Compared to that interface, which is implemented by :class:`list` + (:class:`~zope.interface.common.builtins.IList`), among others, + this interface is missing the following methods: + + - clear + + - count + + - index + + This interface adds the following methods: + + - sort + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/__init__.py new file mode 100644 index 00000000..0503495c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/__init__.py @@ -0,0 +1,136 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + +import unittest + +from zope.interface.verify import verifyClass +from zope.interface.verify import verifyObject + +from zope.interface.common import ABCInterface +from zope.interface.common import ABCInterfaceClass + + +def iter_abc_interfaces(predicate=lambda iface: True): + # Iterate ``(iface, classes)``, where ``iface`` is a descendent of + # the ABCInterfaceClass passing the *predicate* and ``classes`` is + # an iterable of classes registered to conform to that interface. + # + # Note that some builtin classes are registered for two distinct + # parts of the ABC/interface tree. For example, bytearray is both ByteString + # and MutableSequence. + seen = set() + stack = list(ABCInterface.dependents) # subclasses, but also implementedBy objects + while stack: + iface = stack.pop(0) + if iface in seen or not isinstance(iface, ABCInterfaceClass): + continue + seen.add(iface) + stack.extend(list(iface.dependents)) + if not predicate(iface): + continue + + registered = set(iface.getRegisteredConformers()) + registered -= set(iface._ABCInterfaceClass__ignored_classes) + if registered: + yield iface, registered + + +def add_abc_interface_tests(cls, module): + def predicate(iface): + return iface.__module__ == module + add_verify_tests(cls, iter_abc_interfaces(predicate)) + + +def add_verify_tests(cls, iface_classes_iter): + cls.maxDiff = None + for iface, registered_classes in iface_classes_iter: + for stdlib_class in registered_classes: + def test(self, stdlib_class=stdlib_class, iface=iface): + if stdlib_class in self.UNVERIFIABLE or stdlib_class.__name__ in self.UNVERIFIABLE: + self.skipTest("Unable to verify %s" % stdlib_class) + + self.assertTrue(self.verify(iface, stdlib_class)) + + suffix = "{}_{}_{}_{}".format( + stdlib_class.__module__.replace('.', '_'), + stdlib_class.__name__, + iface.__module__.replace('.', '_'), + iface.__name__ + ) + name = 'test_auto_' + suffix + test.__name__ = name + assert not hasattr(cls, name), (name, list(cls.__dict__)) + setattr(cls, name, test) + + def test_ro(self, stdlib_class=stdlib_class, iface=iface): + from zope.interface import ro + from zope.interface import implementedBy + from zope.interface import Interface + self.assertEqual( + tuple(ro.ro(iface, strict=True)), + iface.__sro__) + implements = implementedBy(stdlib_class) + sro = implements.__sro__ + self.assertIs(sro[-1], Interface) + + if stdlib_class not in self.UNVERIFIABLE_RO: + # Check that we got the strict C3 resolution order, unless + # we know we cannot. Note that 'Interface' is virtual base + # that doesn't necessarily appear at the same place in the + # calculated SRO as in the final SRO. + strict = stdlib_class not in self.NON_STRICT_RO + isro = ro.ro(implements, strict=strict) + isro.remove(Interface) + isro.append(Interface) + + self.assertEqual(tuple(isro), sro) + + name = 'test_auto_ro_' + suffix + test_ro.__name__ = name + assert not hasattr(cls, name) + setattr(cls, name, test_ro) + +class VerifyClassMixin(unittest.TestCase): + verifier = staticmethod(verifyClass) + UNVERIFIABLE = () + NON_STRICT_RO = () + UNVERIFIABLE_RO = () + + def _adjust_object_before_verify(self, iface, x): + return x + + def verify(self, iface, klass, **kwargs): + return self.verifier(iface, + self._adjust_object_before_verify(iface, klass), + **kwargs) + + +class VerifyObjectMixin(VerifyClassMixin): + verifier = staticmethod(verifyObject) + CONSTRUCTORS = { + } + + def _adjust_object_before_verify(self, iface, x): + constructor = self.CONSTRUCTORS.get(x) + if not constructor: + constructor = self.CONSTRUCTORS.get(iface) + if not constructor: + constructor = self.CONSTRUCTORS.get(x.__name__) + if not constructor: + constructor = x + if constructor is unittest.SkipTest: + self.skipTest("Cannot create " + str(x)) + + result = constructor() + if hasattr(result, 'close'): + self.addCleanup(result.close) + return result diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/basemapping.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/basemapping.py new file mode 100644 index 00000000..6fe91a1c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/basemapping.py @@ -0,0 +1,107 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Base Mapping tests +""" +from operator import __getitem__ + +def testIReadMapping(self, inst, state, absent): + for key in state: + self.assertEqual(inst[key], state[key]) + self.assertEqual(inst.get(key, None), state[key]) + self.assertTrue(key in inst) + + for key in absent: + self.assertEqual(inst.get(key, None), None) + self.assertEqual(inst.get(key), None) + self.assertEqual(inst.get(key, self), self) + self.assertRaises(KeyError, __getitem__, inst, key) + + +def test_keys(self, inst, state): + # Return the keys of the mapping object + inst_keys = list(inst.keys()); inst_keys.sort() + state_keys = list(state.keys()) ; state_keys.sort() + self.assertEqual(inst_keys, state_keys) + +def test_iter(self, inst, state): + # Return the keys of the mapping object + inst_keys = list(inst); inst_keys.sort() + state_keys = list(state.keys()) ; state_keys.sort() + self.assertEqual(inst_keys, state_keys) + +def test_values(self, inst, state): + # Return the values of the mapping object + inst_values = list(inst.values()); inst_values.sort() + state_values = list(state.values()) ; state_values.sort() + self.assertEqual(inst_values, state_values) + +def test_items(self, inst, state): + # Return the items of the mapping object + inst_items = list(inst.items()); inst_items.sort() + state_items = list(state.items()) ; state_items.sort() + self.assertEqual(inst_items, state_items) + +def test___len__(self, inst, state): + # Return the number of items + self.assertEqual(len(inst), len(state)) + +def testIEnumerableMapping(self, inst, state): + test_keys(self, inst, state) + test_items(self, inst, state) + test_values(self, inst, state) + test___len__(self, inst, state) + + +class BaseTestIReadMapping: + def testIReadMapping(self): + inst = self._IReadMapping__sample() + state = self._IReadMapping__stateDict() + absent = self._IReadMapping__absentKeys() + testIReadMapping(self, inst, state, absent) + + +class BaseTestIEnumerableMapping(BaseTestIReadMapping): + # Mapping objects whose items can be enumerated + def test_keys(self): + # Return the keys of the mapping object + inst = self._IEnumerableMapping__sample() + state = self._IEnumerableMapping__stateDict() + test_keys(self, inst, state) + + def test_values(self): + # Return the values of the mapping object + inst = self._IEnumerableMapping__sample() + state = self._IEnumerableMapping__stateDict() + test_values(self, inst, state) + + def test_items(self): + # Return the items of the mapping object + inst = self._IEnumerableMapping__sample() + state = self._IEnumerableMapping__stateDict() + test_items(self, inst, state) + + def test___len__(self): + # Return the number of items + inst = self._IEnumerableMapping__sample() + state = self._IEnumerableMapping__stateDict() + test___len__(self, inst, state) + + def _IReadMapping__stateDict(self): + return self._IEnumerableMapping__stateDict() + + def _IReadMapping__sample(self): + return self._IEnumerableMapping__sample() + + def _IReadMapping__absentKeys(self): + return self._IEnumerableMapping__absentKeys() diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_builtins.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_builtins.py new file mode 100644 index 00000000..cf7019bf --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_builtins.py @@ -0,0 +1,43 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + +import unittest + +from zope.interface.common import builtins + +from . import VerifyClassMixin +from . import VerifyObjectMixin +from . import add_verify_tests + + +class TestVerifyClass(VerifyClassMixin, + unittest.TestCase): + pass + + +add_verify_tests(TestVerifyClass, ( + (builtins.IList, (list,)), + (builtins.ITuple, (tuple,)), + (builtins.ITextString, (str,)), + (builtins.IByteString, (bytes,)), + (builtins.INativeString, (str,)), + (builtins.IBool, (bool,)), + (builtins.IDict, (dict,)), + (builtins.IFile, ()), +)) + + +class TestVerifyObject(VerifyObjectMixin, + TestVerifyClass): + CONSTRUCTORS = { + builtins.IFile: lambda: open(__file__) + } diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_collections.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_collections.py new file mode 100644 index 00000000..2bd6f506 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_collections.py @@ -0,0 +1,142 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + + +import array +import unittest +from collections import abc +from collections import deque +from collections import OrderedDict + + +from types import MappingProxyType + +from zope.interface import Invalid + + +# Note that importing z.i.c.collections does work on import. +from zope.interface.common import collections + + +from zope.interface._compat import PYPY + + +from . import add_abc_interface_tests +from . import VerifyClassMixin +from . import VerifyObjectMixin + +class TestVerifyClass(VerifyClassMixin, unittest.TestCase): + + # Here we test some known builtin classes that are defined to implement + # various collection interfaces as a quick sanity test. + def test_frozenset(self): + self.assertIsInstance(frozenset(), abc.Set) + self.assertTrue(self.verify(collections.ISet, frozenset)) + + def test_list(self): + self.assertIsInstance(list(), abc.MutableSequence) + self.assertTrue(self.verify(collections.IMutableSequence, list)) + + # Here we test some derived classes. + def test_UserList(self): + self.assertTrue(self.verify(collections.IMutableSequence, + collections.UserList)) + + def test_UserDict(self): + self.assertTrue(self.verify(collections.IMutableMapping, + collections.UserDict)) + + def test_UserString(self): + self.assertTrue(self.verify(collections.ISequence, + collections.UserString)) + + # Now we go through the registry, which should have several things, + # mostly builtins, but if we've imported other libraries already, + # it could contain things from outside of there too. We aren't concerned + # about third-party code here, just standard library types. We start with a + # blacklist of things to exclude, but if that gets out of hand we can figure + # out a better whitelisting. + UNVERIFIABLE = { + # This is declared to be an ISequence, but is missing lots of methods, + # including some that aren't part of a language protocol, such as + # ``index`` and ``count``. + memoryview, + # 'pkg_resources._vendor.pyparsing.ParseResults' is registered as a + # MutableMapping but is missing methods like ``popitem`` and ``setdefault``. + # It's imported due to namespace packages. + 'ParseResults', + # sqlite3.Row claims ISequence but also misses ``index`` and ``count``. + # It's imported because...? Coverage imports it, but why do we have it without + # coverage? + 'Row', + # In Python 3.10 ``array.array`` appears as ``IMutableSequence`` but it + # does not provide a ``clear()`` method and it cannot be instantiated + # using ``array.array()``. + array.array, + } + + if PYPY: + UNVERIFIABLE.update({ + # collections.deque.pop() doesn't support the index= argument to + # MutableSequence.pop(). We can't verify this on CPython because we can't + # get the signature, but on PyPy we /can/ get the signature, and of course + # it doesn't match. + deque, + # Likewise for index + range, + }) + UNVERIFIABLE_RO = { + # ``array.array`` fails the ``test_auto_ro_*`` tests with and + # without strict RO but only on Windows (AppVeyor) on Python 3.10.0 + # (in older versions ``array.array`` does not appear as + # ``IMutableSequence``). + array.array, + } + +add_abc_interface_tests(TestVerifyClass, collections.ISet.__module__) + + +class TestVerifyObject(VerifyObjectMixin, + TestVerifyClass): + CONSTRUCTORS = { + collections.IValuesView: {}.values, + collections.IItemsView: {}.items, + collections.IKeysView: {}.keys, + memoryview: lambda: memoryview(b'abc'), + range: lambda: range(10), + MappingProxyType: lambda: MappingProxyType({}), + collections.UserString: lambda: collections.UserString('abc'), + type(iter(bytearray())): lambda: iter(bytearray()), + type(iter(b'abc')): lambda: iter(b'abc'), + 'coroutine': unittest.SkipTest, + type(iter({}.keys())): lambda: iter({}.keys()), + type(iter({}.items())): lambda: iter({}.items()), + type(iter({}.values())): lambda: iter({}.values()), + type(i for i in range(1)): lambda: (i for i in range(3)), + type(iter([])): lambda: iter([]), + type(reversed([])): lambda: reversed([]), + 'longrange_iterator': unittest.SkipTest, + 'range_iterator': lambda: iter(range(3)), + 'rangeiterator': lambda: iter(range(3)), + type(iter(set())): lambda: iter(set()), + type(iter('')): lambda: iter(''), + 'async_generator': unittest.SkipTest, + type(iter(tuple())): lambda: iter(tuple()), + } + + UNVERIFIABLE_RO = { + # ``array.array`` fails the ``test_auto_ro_*`` tests with and + # without strict RO but only on Windows (AppVeyor) on Python 3.10.0 + # (in older versions ``array.array`` does not appear as + # ``IMutableSequence``). + array.array, + } diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_idatetime.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_idatetime.py new file mode 100644 index 00000000..496a5c94 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_idatetime.py @@ -0,0 +1,37 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test for datetime interfaces +""" + +import unittest + +from zope.interface.verify import verifyObject, verifyClass +from zope.interface.common.idatetime import ITimeDelta, ITimeDeltaClass +from zope.interface.common.idatetime import IDate, IDateClass +from zope.interface.common.idatetime import IDateTime, IDateTimeClass +from zope.interface.common.idatetime import ITime, ITimeClass, ITZInfo +from datetime import timedelta, date, datetime, time, tzinfo + +class TestDateTimeInterfaces(unittest.TestCase): + + def test_interfaces(self): + verifyObject(ITimeDelta, timedelta(minutes=20)) + verifyObject(IDate, date(2000, 1, 2)) + verifyObject(IDateTime, datetime(2000, 1, 2, 10, 20)) + verifyObject(ITime, time(20, 30, 15, 1234)) + verifyObject(ITZInfo, tzinfo()) + verifyClass(ITimeDeltaClass, timedelta) + verifyClass(IDateClass, date) + verifyClass(IDateTimeClass, datetime) + verifyClass(ITimeClass, time) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_import_interfaces.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_import_interfaces.py new file mode 100644 index 00000000..fe3766f6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_import_interfaces.py @@ -0,0 +1,20 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +import unittest + +class TestInterfaceImport(unittest.TestCase): + + def test_import(self): + import zope.interface.common.interfaces as x + self.assertIsNotNone(x) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_io.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_io.py new file mode 100644 index 00000000..0e8e74d6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_io.py @@ -0,0 +1,42 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + + +import unittest +import io as abc + +# Note that importing z.i.c.io does work on import. +from zope.interface.common import io + +from . import add_abc_interface_tests +from . import VerifyClassMixin +from . import VerifyObjectMixin + + +class TestVerifyClass(VerifyClassMixin, + unittest.TestCase): + pass + +add_abc_interface_tests(TestVerifyClass, io.IIOBase.__module__) + + +class TestVerifyObject(VerifyObjectMixin, + TestVerifyClass): + CONSTRUCTORS = { + abc.BufferedWriter: lambda: abc.BufferedWriter(abc.StringIO()), + abc.BufferedReader: lambda: abc.BufferedReader(abc.StringIO()), + abc.TextIOWrapper: lambda: abc.TextIOWrapper(abc.BytesIO()), + abc.BufferedRandom: lambda: abc.BufferedRandom(abc.BytesIO()), + abc.BufferedRWPair: lambda: abc.BufferedRWPair(abc.BytesIO(), abc.BytesIO()), + abc.FileIO: lambda: abc.FileIO(__file__), + '_WindowsConsoleIO': unittest.SkipTest, + } diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_numbers.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_numbers.py new file mode 100644 index 00000000..abf96958 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/common/tests/test_numbers.py @@ -0,0 +1,41 @@ +############################################################################## +# Copyright (c) 2020 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## + + +import unittest +import numbers as abc + +# Note that importing z.i.c.numbers does work on import. +from zope.interface.common import numbers + +from . import add_abc_interface_tests +from . import VerifyClassMixin +from . import VerifyObjectMixin + + +class TestVerifyClass(VerifyClassMixin, + unittest.TestCase): + + def test_int(self): + self.assertIsInstance(int(), abc.Integral) + self.assertTrue(self.verify(numbers.IIntegral, int)) + + def test_float(self): + self.assertIsInstance(float(), abc.Real) + self.assertTrue(self.verify(numbers.IReal, float)) + +add_abc_interface_tests(TestVerifyClass, numbers.INumber.__module__) + + +class TestVerifyObject(VerifyObjectMixin, + TestVerifyClass): + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/declarations.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/declarations.py new file mode 100644 index 00000000..61e25439 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/declarations.py @@ -0,0 +1,1188 @@ +############################################################################## +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +"""Implementation of interface declarations + +There are three flavors of declarations: + + - Declarations are used to simply name declared interfaces. + + - ImplementsDeclarations are used to express the interfaces that a + class implements (that instances of the class provides). + + Implements specifications support inheriting interfaces. + + - ProvidesDeclarations are used to express interfaces directly + provided by objects. + +""" +__docformat__ = 'restructuredtext' + +import sys +from types import FunctionType +from types import MethodType +from types import ModuleType +import weakref + +from zope.interface.interface import Interface +from zope.interface.interface import InterfaceClass +from zope.interface.interface import SpecificationBase +from zope.interface.interface import Specification +from zope.interface.interface import NameAndModuleComparisonMixin +from zope.interface._compat import _use_c_impl + +__all__ = [ + # None. The public APIs of this module are + # re-exported from zope.interface directly. +] + +# pylint:disable=too-many-lines + +# Registry of class-implementation specifications +BuiltinImplementationSpecifications = {} + + +def _next_super_class(ob): + # When ``ob`` is an instance of ``super``, return + # the next class in the MRO that we should actually be + # looking at. Watch out for diamond inheritance! + self_class = ob.__self_class__ + class_that_invoked_super = ob.__thisclass__ + complete_mro = self_class.__mro__ + next_class = complete_mro[complete_mro.index(class_that_invoked_super) + 1] + return next_class + +class named: + + def __init__(self, name): + self.name = name + + def __call__(self, ob): + ob.__component_name__ = self.name + return ob + + +class Declaration(Specification): + """Interface declarations""" + + __slots__ = () + + def __init__(self, *bases): + Specification.__init__(self, _normalizeargs(bases)) + + def __contains__(self, interface): + """Test whether an interface is in the specification + """ + + return self.extends(interface) and interface in self.interfaces() + + def __iter__(self): + """Return an iterator for the interfaces in the specification + """ + return self.interfaces() + + def flattened(self): + """Return an iterator of all included and extended interfaces + """ + return iter(self.__iro__) + + def __sub__(self, other): + """Remove interfaces from a specification + """ + return Declaration(*[ + i for i in self.interfaces() + if not [ + j + for j in other.interfaces() + if i.extends(j, 0) # non-strict extends + ] + ]) + + def __add__(self, other): + """ + Add two specifications or a specification and an interface + and produce a new declaration. + + .. versionchanged:: 5.4.0 + Now tries to preserve a consistent resolution order. Interfaces + being added to this object are added to the front of the resulting resolution + order if they already extend an interface in this object. Previously, + they were always added to the end of the order, which easily resulted in + invalid orders. + """ + before = [] + result = list(self.interfaces()) + seen = set(result) + for i in other.interfaces(): + if i in seen: + continue + seen.add(i) + if any(i.extends(x) for x in result): + # It already extends us, e.g., is a subclass, + # so it needs to go at the front of the RO. + before.append(i) + else: + result.append(i) + return Declaration(*(before + result)) + + # XXX: Is __radd__ needed? No tests break if it's removed. + # If it is needed, does it need to handle the C3 ordering differently? + # I (JAM) don't *think* it does. + __radd__ = __add__ + + @staticmethod + def _add_interfaces_to_cls(interfaces, cls): + # Strip redundant interfaces already provided + # by the cls so we don't produce invalid + # resolution orders. + implemented_by_cls = implementedBy(cls) + interfaces = tuple([ + iface + for iface in interfaces + if not implemented_by_cls.isOrExtends(iface) + ]) + return interfaces + (implemented_by_cls,) + + @staticmethod + def _argument_names_for_repr(interfaces): + # These don't actually have to be interfaces, they could be other + # Specification objects like Implements. Also, the first + # one is typically/nominally the cls. + ordered_names = [] + names = set() + for iface in interfaces: + duplicate_transform = repr + if isinstance(iface, InterfaceClass): + # Special case to get 'foo.bar.IFace' + # instead of '<InterfaceClass foo.bar.IFace>' + this_name = iface.__name__ + duplicate_transform = str + elif isinstance(iface, type): + # Likewise for types. (Ignoring legacy old-style + # classes.) + this_name = iface.__name__ + duplicate_transform = _implements_name + elif (isinstance(iface, Implements) + and not iface.declared + and iface.inherit in interfaces): + # If nothing is declared, there's no need to even print this; + # it would just show as ``classImplements(Class)``, and the + # ``Class`` has typically already. + continue + else: + this_name = repr(iface) + + already_seen = this_name in names + names.add(this_name) + if already_seen: + this_name = duplicate_transform(iface) + + ordered_names.append(this_name) + return ', '.join(ordered_names) + + +class _ImmutableDeclaration(Declaration): + # A Declaration that is immutable. Used as a singleton to + # return empty answers for things like ``implementedBy``. + # We have to define the actual singleton after normalizeargs + # is defined, and that in turn is defined after InterfaceClass and + # Implements. + + __slots__ = () + + __instance = None + + def __new__(cls): + if _ImmutableDeclaration.__instance is None: + _ImmutableDeclaration.__instance = object.__new__(cls) + return _ImmutableDeclaration.__instance + + def __reduce__(self): + return "_empty" + + @property + def __bases__(self): + return () + + @__bases__.setter + def __bases__(self, new_bases): + # We expect the superclass constructor to set ``self.__bases__ = ()``. + # Rather than attempt to special case that in the constructor and allow + # setting __bases__ only at that time, it's easier to just allow setting + # the empty tuple at any time. That makes ``x.__bases__ = x.__bases__`` a nice + # no-op too. (Skipping the superclass constructor altogether is a recipe + # for maintenance headaches.) + if new_bases != (): + raise TypeError("Cannot set non-empty bases on shared empty Declaration.") + + # As the immutable empty declaration, we cannot be changed. + # This means there's no logical reason for us to have dependents + # or subscriptions: we'll never notify them. So there's no need for + # us to keep track of any of that. + @property + def dependents(self): + return {} + + changed = subscribe = unsubscribe = lambda self, _ignored: None + + def interfaces(self): + # An empty iterator + return iter(()) + + def extends(self, interface, strict=True): + return interface is self._ROOT + + def get(self, name, default=None): + return default + + def weakref(self, callback=None): + # We're a singleton, we never go away. So there's no need to return + # distinct weakref objects here; their callbacks will never + # be called. Instead, we only need to return a callable that + # returns ourself. The easiest one is to return _ImmutableDeclaration + # itself; testing on Python 3.8 shows that's faster than a function that + # returns _empty. (Remember, one goal is to avoid allocating any + # object, and that includes a method.) + return _ImmutableDeclaration + + @property + def _v_attrs(self): + # _v_attrs is not a public, documented property, but some client code + # uses it anyway as a convenient place to cache things. To keep the + # empty declaration truly immutable, we must ignore that. That includes + # ignoring assignments as well. + return {} + + @_v_attrs.setter + def _v_attrs(self, new_attrs): + pass + + +############################################################################## +# +# Implementation specifications +# +# These specify interfaces implemented by instances of classes + +class Implements(NameAndModuleComparisonMixin, + Declaration): + # Inherit from NameAndModuleComparisonMixin to be + # mutually comparable with InterfaceClass objects. + # (The two must be mutually comparable to be able to work in e.g., BTrees.) + # Instances of this class generally don't have a __module__ other than + # `zope.interface.declarations`, whereas they *do* have a __name__ that is the + # fully qualified name of the object they are representing. + + # Note, though, that equality and hashing are still identity based. This + # accounts for things like nested objects that have the same name (typically + # only in tests) and is consistent with pickling. As far as comparisons to InterfaceClass + # goes, we'll never have equal name and module to those, so we're still consistent there. + # Instances of this class are essentially intended to be unique and are + # heavily cached (note how our __reduce__ handles this) so having identity + # based hash and eq should also work. + + # We want equality and hashing to be based on identity. However, we can't actually + # implement __eq__/__ne__ to do this because sometimes we get wrapped in a proxy. + # We need to let the proxy types implement these methods so they can handle unwrapping + # and then rely on: (1) the interpreter automatically changing `implements == proxy` into + # `proxy == implements` (which will call proxy.__eq__ to do the unwrapping) and then + # (2) the default equality and hashing semantics being identity based. + + # class whose specification should be used as additional base + inherit = None + + # interfaces actually declared for a class + declared = () + + # Weak cache of {class: <implements>} for super objects. + # Created on demand. These are rare, as of 5.0 anyway. Using a class + # level default doesn't take space in instances. Using _v_attrs would be + # another place to store this without taking space unless needed. + _super_cache = None + + __name__ = '?' + + @classmethod + def named(cls, name, *bases): + # Implementation method: Produce an Implements interface with + # a fully fleshed out __name__ before calling the constructor, which + # sets bases to the given interfaces and which may pass this object to + # other objects (e.g., to adjust dependents). If they're sorting or comparing + # by name, this needs to be set. + inst = cls.__new__(cls) + inst.__name__ = name + inst.__init__(*bases) + return inst + + def changed(self, originally_changed): + try: + del self._super_cache + except AttributeError: + pass + return super().changed(originally_changed) + + def __repr__(self): + if self.inherit: + name = getattr(self.inherit, '__name__', None) or _implements_name(self.inherit) + else: + name = self.__name__ + declared_names = self._argument_names_for_repr(self.declared) + if declared_names: + declared_names = ', ' + declared_names + return 'classImplements({}{})'.format(name, declared_names) + + def __reduce__(self): + return implementedBy, (self.inherit, ) + + +def _implements_name(ob): + # Return the __name__ attribute to be used by its __implemented__ + # property. + # This must be stable for the "same" object across processes + # because it is used for sorting. It needn't be unique, though, in cases + # like nested classes named Foo created by different functions, because + # equality and hashing is still based on identity. + # It might be nice to use __qualname__ on Python 3, but that would produce + # different values between Py2 and Py3. + return (getattr(ob, '__module__', '?') or '?') + \ + '.' + (getattr(ob, '__name__', '?') or '?') + + +def _implementedBy_super(sup): + # TODO: This is now simple enough we could probably implement + # in C if needed. + + # If the class MRO is strictly linear, we could just + # follow the normal algorithm for the next class in the + # search order (e.g., just return + # ``implemented_by_next``). But when diamond inheritance + # or mixins + interface declarations are present, we have + # to consider the whole MRO and compute a new Implements + # that excludes the classes being skipped over but + # includes everything else. + implemented_by_self = implementedBy(sup.__self_class__) + cache = implemented_by_self._super_cache # pylint:disable=protected-access + if cache is None: + cache = implemented_by_self._super_cache = weakref.WeakKeyDictionary() + + key = sup.__thisclass__ + try: + return cache[key] + except KeyError: + pass + + next_cls = _next_super_class(sup) + # For ``implementedBy(cls)``: + # .__bases__ is .declared + [implementedBy(b) for b in cls.__bases__] + # .inherit is cls + + implemented_by_next = implementedBy(next_cls) + mro = sup.__self_class__.__mro__ + ix_next_cls = mro.index(next_cls) + classes_to_keep = mro[ix_next_cls:] + new_bases = [implementedBy(c) for c in classes_to_keep] + + new = Implements.named( + implemented_by_self.__name__ + ':' + implemented_by_next.__name__, + *new_bases + ) + new.inherit = implemented_by_next.inherit + new.declared = implemented_by_next.declared + # I don't *think* that new needs to subscribe to ``implemented_by_self``; + # it auto-subscribed to its bases, and that should be good enough. + cache[key] = new + + return new + + +@_use_c_impl +def implementedBy(cls): # pylint:disable=too-many-return-statements,too-many-branches + """Return the interfaces implemented for a class' instances + + The value returned is an `~zope.interface.interfaces.IDeclaration`. + """ + try: + if isinstance(cls, super): + # Yes, this needs to be inside the try: block. Some objects + # like security proxies even break isinstance. + return _implementedBy_super(cls) + + spec = cls.__dict__.get('__implemented__') + except AttributeError: + + # we can't get the class dict. This is probably due to a + # security proxy. If this is the case, then probably no + # descriptor was installed for the class. + + # We don't want to depend directly on zope.security in + # zope.interface, but we'll try to make reasonable + # accommodations in an indirect way. + + # We'll check to see if there's an implements: + + spec = getattr(cls, '__implemented__', None) + if spec is None: + # There's no spec stred in the class. Maybe its a builtin: + spec = BuiltinImplementationSpecifications.get(cls) + if spec is not None: + return spec + return _empty + + if spec.__class__ == Implements: + # we defaulted to _empty or there was a spec. Good enough. + # Return it. + return spec + + # TODO: need old style __implements__ compatibility? + # Hm, there's an __implemented__, but it's not a spec. Must be + # an old-style declaration. Just compute a spec for it + return Declaration(*_normalizeargs((spec, ))) + + if isinstance(spec, Implements): + return spec + + if spec is None: + spec = BuiltinImplementationSpecifications.get(cls) + if spec is not None: + return spec + + # TODO: need old style __implements__ compatibility? + spec_name = _implements_name(cls) + if spec is not None: + # old-style __implemented__ = foo declaration + spec = (spec, ) # tuplefy, as it might be just an int + spec = Implements.named(spec_name, *_normalizeargs(spec)) + spec.inherit = None # old-style implies no inherit + del cls.__implemented__ # get rid of the old-style declaration + else: + try: + bases = cls.__bases__ + except AttributeError: + if not callable(cls): + raise TypeError("ImplementedBy called for non-factory", cls) + bases = () + + spec = Implements.named(spec_name, *[implementedBy(c) for c in bases]) + spec.inherit = cls + + try: + cls.__implemented__ = spec + if not hasattr(cls, '__providedBy__'): + cls.__providedBy__ = objectSpecificationDescriptor + + if isinstance(cls, type) and '__provides__' not in cls.__dict__: + # Make sure we get a __provides__ descriptor + cls.__provides__ = ClassProvides( + cls, + getattr(cls, '__class__', type(cls)), + ) + + except TypeError: + if not isinstance(cls, type): + raise TypeError("ImplementedBy called for non-type", cls) + BuiltinImplementationSpecifications[cls] = spec + + return spec + + +def classImplementsOnly(cls, *interfaces): + """ + Declare the only interfaces implemented by instances of a class + + The arguments after the class are one or more interfaces or interface + specifications (`~zope.interface.interfaces.IDeclaration` objects). + + The interfaces given (including the interfaces in the specifications) + replace any previous declarations, *including* inherited definitions. If you + wish to preserve inherited declarations, you can pass ``implementedBy(cls)`` + in *interfaces*. This can be used to alter the interface resolution order. + """ + spec = implementedBy(cls) + # Clear out everything inherited. It's important to + # also clear the bases right now so that we don't improperly discard + # interfaces that are already implemented by *old* bases that we're + # about to get rid of. + spec.declared = () + spec.inherit = None + spec.__bases__ = () + _classImplements_ordered(spec, interfaces, ()) + + +def classImplements(cls, *interfaces): + """ + Declare additional interfaces implemented for instances of a class + + The arguments after the class are one or more interfaces or + interface specifications (`~zope.interface.interfaces.IDeclaration` objects). + + The interfaces given (including the interfaces in the specifications) + are added to any interfaces previously declared. An effort is made to + keep a consistent C3 resolution order, but this cannot be guaranteed. + + .. versionchanged:: 5.0.0 + Each individual interface in *interfaces* may be added to either the + beginning or end of the list of interfaces declared for *cls*, + based on inheritance, in order to try to maintain a consistent + resolution order. Previously, all interfaces were added to the end. + .. versionchanged:: 5.1.0 + If *cls* is already declared to implement an interface (or derived interface) + in *interfaces* through inheritance, the interface is ignored. Previously, it + would redundantly be made direct base of *cls*, which often produced inconsistent + interface resolution orders. Now, the order will be consistent, but may change. + Also, if the ``__bases__`` of the *cls* are later changed, the *cls* will no + longer be considered to implement such an interface (changing the ``__bases__`` of *cls* + has never been supported). + """ + spec = implementedBy(cls) + interfaces = tuple(_normalizeargs(interfaces)) + + before = [] + after = [] + + # Take steps to try to avoid producing an invalid resolution + # order, while still allowing for BWC (in the past, we always + # appended) + for iface in interfaces: + for b in spec.declared: + if iface.extends(b): + before.append(iface) + break + else: + after.append(iface) + _classImplements_ordered(spec, tuple(before), tuple(after)) + + +def classImplementsFirst(cls, iface): + """ + Declare that instances of *cls* additionally provide *iface*. + + The second argument is an interface or interface specification. + It is added as the highest priority (first in the IRO) interface; + no attempt is made to keep a consistent resolution order. + + .. versionadded:: 5.0.0 + """ + spec = implementedBy(cls) + _classImplements_ordered(spec, (iface,), ()) + + +def _classImplements_ordered(spec, before=(), after=()): + # Elide everything already inherited. + # Except, if it is the root, and we don't already declare anything else + # that would imply it, allow the root through. (TODO: When we disallow non-strict + # IRO, this part of the check can be removed because it's not possible to re-declare + # like that.) + before = [ + x + for x in before + if not spec.isOrExtends(x) or (x is Interface and not spec.declared) + ] + after = [ + x + for x in after + if not spec.isOrExtends(x) or (x is Interface and not spec.declared) + ] + + # eliminate duplicates + new_declared = [] + seen = set() + for l in before, spec.declared, after: + for b in l: + if b not in seen: + new_declared.append(b) + seen.add(b) + + spec.declared = tuple(new_declared) + + # compute the bases + bases = new_declared # guaranteed no dupes + + if spec.inherit is not None: + for c in spec.inherit.__bases__: + b = implementedBy(c) + if b not in seen: + seen.add(b) + bases.append(b) + + spec.__bases__ = tuple(bases) + + +def _implements_advice(cls): + interfaces, do_classImplements = cls.__dict__['__implements_advice_data__'] + del cls.__implements_advice_data__ + do_classImplements(cls, *interfaces) + return cls + + +class implementer: + """ + Declare the interfaces implemented by instances of a class. + + This function is called as a class decorator. + + The arguments are one or more interfaces or interface + specifications (`~zope.interface.interfaces.IDeclaration` + objects). + + The interfaces given (including the interfaces in the + specifications) are added to any interfaces previously declared, + unless the interface is already implemented. + + Previous declarations include declarations for base classes unless + implementsOnly was used. + + This function is provided for convenience. It provides a more + convenient way to call `classImplements`. For example:: + + @implementer(I1) + class C(object): + pass + + is equivalent to calling:: + + classImplements(C, I1) + + after the class has been created. + + .. seealso:: `classImplements` + The change history provided there applies to this function too. + """ + __slots__ = ('interfaces',) + + def __init__(self, *interfaces): + self.interfaces = interfaces + + def __call__(self, ob): + if isinstance(ob, type): + # This is the common branch for classes. + classImplements(ob, *self.interfaces) + return ob + + spec_name = _implements_name(ob) + spec = Implements.named(spec_name, *self.interfaces) + try: + ob.__implemented__ = spec + except AttributeError: + raise TypeError("Can't declare implements", ob) + return ob + +class implementer_only: + """Declare the only interfaces implemented by instances of a class + + This function is called as a class decorator. + + The arguments are one or more interfaces or interface + specifications (`~zope.interface.interfaces.IDeclaration` objects). + + Previous declarations including declarations for base classes + are overridden. + + This function is provided for convenience. It provides a more + convenient way to call `classImplementsOnly`. For example:: + + @implementer_only(I1) + class C(object): pass + + is equivalent to calling:: + + classImplementsOnly(I1) + + after the class has been created. + """ + + def __init__(self, *interfaces): + self.interfaces = interfaces + + def __call__(self, ob): + if isinstance(ob, (FunctionType, MethodType)): + # XXX Does this decorator make sense for anything but classes? + # I don't think so. There can be no inheritance of interfaces + # on a method or function.... + raise ValueError('The implementer_only decorator is not ' + 'supported for methods or functions.') + + # Assume it's a class: + classImplementsOnly(ob, *self.interfaces) + return ob + + +############################################################################## +# +# Instance declarations + +class Provides(Declaration): # Really named ProvidesClass + """Implement ``__provides__``, the instance-specific specification + + When an object is pickled, we pickle the interfaces that it implements. + """ + + def __init__(self, cls, *interfaces): + self.__args = (cls, ) + interfaces + self._cls = cls + Declaration.__init__(self, *self._add_interfaces_to_cls(interfaces, cls)) + + # Added to by ``moduleProvides``, et al + _v_module_names = () + + def __repr__(self): + # The typical way to create instances of this + # object is via calling ``directlyProvides(...)`` or ``alsoProvides()``, + # but that's not the only way. Proxies, for example, + # directly use the ``Provides(...)`` function (which is the + # more generic method, and what we pickle as). We're after the most + # readable, useful repr in the common case, so we use the most + # common name. + # + # We also cooperate with ``moduleProvides`` to attempt to do the + # right thing for that API. See it for details. + function_name = 'directlyProvides' + if self._cls is ModuleType and self._v_module_names: + # See notes in ``moduleProvides``/``directlyProvides`` + providing_on_module = True + interfaces = self.__args[1:] + else: + providing_on_module = False + interfaces = (self._cls,) + self.__bases__ + ordered_names = self._argument_names_for_repr(interfaces) + if providing_on_module: + mod_names = self._v_module_names + if len(mod_names) == 1: + mod_names = "sys.modules[%r]" % mod_names[0] + ordered_names = ( + '{}, '.format(mod_names) + ) + ordered_names + return "{}({})".format( + function_name, + ordered_names, + ) + + def __reduce__(self): + # This reduces to the Provides *function*, not + # this class. + return Provides, self.__args + + __module__ = 'zope.interface' + + def __get__(self, inst, cls): + """Make sure that a class __provides__ doesn't leak to an instance + """ + if inst is None and cls is self._cls: + # We were accessed through a class, so we are the class' + # provides spec. Just return this object, but only if we are + # being called on the same class that we were defined for: + return self + + raise AttributeError('__provides__') + +ProvidesClass = Provides + +# Registry of instance declarations +# This is a memory optimization to allow objects to share specifications. +InstanceDeclarations = weakref.WeakValueDictionary() + +def Provides(*interfaces): # pylint:disable=function-redefined + """Declaration for an instance of *cls*. + + The correct signature is ``cls, *interfaces``. + The *cls* is necessary to avoid the + construction of inconsistent resolution orders. + + Instance declarations are shared among instances that have the same + declaration. The declarations are cached in a weak value dictionary. + """ + spec = InstanceDeclarations.get(interfaces) + if spec is None: + spec = ProvidesClass(*interfaces) + InstanceDeclarations[interfaces] = spec + + return spec + +Provides.__safe_for_unpickling__ = True + + +def directlyProvides(object, *interfaces): # pylint:disable=redefined-builtin + """Declare interfaces declared directly for an object + + The arguments after the object are one or more interfaces or interface + specifications (`~zope.interface.interfaces.IDeclaration` objects). + + The interfaces given (including the interfaces in the specifications) + replace interfaces previously declared for the object. + """ + cls = getattr(object, '__class__', None) + if cls is not None and getattr(cls, '__class__', None) is cls: + # It's a meta class (well, at least it it could be an extension class) + # Note that we can't get here from the tests: there is no normal + # class which isn't descriptor aware. + if not isinstance(object, type): + raise TypeError("Attempt to make an interface declaration on a " + "non-descriptor-aware class") + + interfaces = _normalizeargs(interfaces) + if cls is None: + cls = type(object) + + if issubclass(cls, type): + # we have a class or type. We'll use a special descriptor + # that provides some extra caching + object.__provides__ = ClassProvides(object, cls, *interfaces) + else: + provides = object.__provides__ = Provides(cls, *interfaces) + # See notes in ``moduleProvides``. + if issubclass(cls, ModuleType) and hasattr(object, '__name__'): + provides._v_module_names += (object.__name__,) + + + +def alsoProvides(object, *interfaces): # pylint:disable=redefined-builtin + """Declare interfaces declared directly for an object + + The arguments after the object are one or more interfaces or interface + specifications (`~zope.interface.interfaces.IDeclaration` objects). + + The interfaces given (including the interfaces in the specifications) are + added to the interfaces previously declared for the object. + """ + directlyProvides(object, directlyProvidedBy(object), *interfaces) + + +def noLongerProvides(object, interface): # pylint:disable=redefined-builtin + """ Removes a directly provided interface from an object. + """ + directlyProvides(object, directlyProvidedBy(object) - interface) + if interface.providedBy(object): + raise ValueError("Can only remove directly provided interfaces.") + + +@_use_c_impl +class ClassProvidesBase(SpecificationBase): + + __slots__ = ( + '_cls', + '_implements', + ) + + def __get__(self, inst, cls): + # member slots are set by subclass + # pylint:disable=no-member + if cls is self._cls: + # We only work if called on the class we were defined for + + if inst is None: + # We were accessed through a class, so we are the class' + # provides spec. Just return this object as is: + return self + + return self._implements + + raise AttributeError('__provides__') + + +class ClassProvides(Declaration, ClassProvidesBase): + """Special descriptor for class ``__provides__`` + + The descriptor caches the implementedBy info, so that + we can get declarations for objects without instance-specific + interfaces a bit quicker. + """ + + __slots__ = ( + '__args', + ) + + def __init__(self, cls, metacls, *interfaces): + self._cls = cls + self._implements = implementedBy(cls) + self.__args = (cls, metacls, ) + interfaces + Declaration.__init__(self, *self._add_interfaces_to_cls(interfaces, metacls)) + + def __repr__(self): + # There are two common ways to get instances of this object: + # The most interesting way is calling ``@provider(..)`` as a decorator + # of a class; this is the same as calling ``directlyProvides(cls, ...)``. + # + # The other way is by default: anything that invokes ``implementedBy(x)`` + # will wind up putting an instance in ``type(x).__provides__``; this includes + # the ``@implementer(...)`` decorator. Those instances won't have any + # interfaces. + # + # Thus, as our repr, we go with the ``directlyProvides()`` syntax. + interfaces = (self._cls, ) + self.__args[2:] + ordered_names = self._argument_names_for_repr(interfaces) + return "directlyProvides({})".format(ordered_names) + + def __reduce__(self): + return self.__class__, self.__args + + # Copy base-class method for speed + __get__ = ClassProvidesBase.__get__ + + +def directlyProvidedBy(object): # pylint:disable=redefined-builtin + """Return the interfaces directly provided by the given object + + The value returned is an `~zope.interface.interfaces.IDeclaration`. + """ + provides = getattr(object, "__provides__", None) + if ( + provides is None # no spec + # We might have gotten the implements spec, as an + # optimization. If so, it's like having only one base, that we + # lop off to exclude class-supplied declarations: + or isinstance(provides, Implements) + ): + return _empty + + # Strip off the class part of the spec: + return Declaration(provides.__bases__[:-1]) + + +class provider: + """Declare interfaces provided directly by a class + + This function is called in a class definition. + + The arguments are one or more interfaces or interface specifications + (`~zope.interface.interfaces.IDeclaration` objects). + + The given interfaces (including the interfaces in the specifications) + are used to create the class's direct-object interface specification. + An error will be raised if the module class has an direct interface + specification. In other words, it is an error to call this function more + than once in a class definition. + + Note that the given interfaces have nothing to do with the interfaces + implemented by instances of the class. + + This function is provided for convenience. It provides a more convenient + way to call `directlyProvides` for a class. For example:: + + @provider(I1) + class C: + pass + + is equivalent to calling:: + + directlyProvides(C, I1) + + after the class has been created. + """ + + def __init__(self, *interfaces): + self.interfaces = interfaces + + def __call__(self, ob): + directlyProvides(ob, *self.interfaces) + return ob + + +def moduleProvides(*interfaces): + """Declare interfaces provided by a module + + This function is used in a module definition. + + The arguments are one or more interfaces or interface specifications + (`~zope.interface.interfaces.IDeclaration` objects). + + The given interfaces (including the interfaces in the specifications) are + used to create the module's direct-object interface specification. An + error will be raised if the module already has an interface specification. + In other words, it is an error to call this function more than once in a + module definition. + + This function is provided for convenience. It provides a more convenient + way to call directlyProvides. For example:: + + moduleProvides(I1) + + is equivalent to:: + + directlyProvides(sys.modules[__name__], I1) + """ + frame = sys._getframe(1) # pylint:disable=protected-access + locals = frame.f_locals # pylint:disable=redefined-builtin + + # Try to make sure we were called from a module body + if (locals is not frame.f_globals) or ('__name__' not in locals): + raise TypeError( + "moduleProvides can only be used from a module definition.") + + if '__provides__' in locals: + raise TypeError( + "moduleProvides can only be used once in a module definition.") + + # Note: This is cached based on the key ``(ModuleType, *interfaces)``; + # One consequence is that any module that provides the same interfaces + # gets the same ``__repr__``, meaning that you can't tell what module + # such a declaration came from. Adding the module name to ``_v_module_names`` + # attempts to correct for this; it works in some common situations, but fails + # (1) after pickling (the data is lost) and (2) if declarations are + # actually shared and (3) if the alternate spelling of ``directlyProvides()`` + # is used. Problem (3) is fixed by cooperating with ``directlyProvides`` + # to maintain this information, and problem (2) is worked around by + # printing all the names, but (1) is unsolvable without introducing + # new classes or changing the stored data...but it doesn't actually matter, + # because ``ModuleType`` can't be pickled! + p = locals["__provides__"] = Provides(ModuleType, + *_normalizeargs(interfaces)) + p._v_module_names += (locals['__name__'],) + + +############################################################################## +# +# Declaration querying support + +# XXX: is this a fossil? Nobody calls it, no unit tests exercise it, no +# doctests import it, and the package __init__ doesn't import it. +# (Answer: Versions of zope.container prior to 4.4.0 called this, +# and zope.proxy.decorator up through at least 4.3.5 called this.) +def ObjectSpecification(direct, cls): + """Provide object specifications + + These combine information for the object and for it's classes. + """ + return Provides(cls, direct) # pragma: no cover fossil + +@_use_c_impl +def getObjectSpecification(ob): + try: + provides = ob.__provides__ + except AttributeError: + provides = None + + if provides is not None: + if isinstance(provides, SpecificationBase): + return provides + + try: + cls = ob.__class__ + except AttributeError: + # We can't get the class, so just consider provides + return _empty + return implementedBy(cls) + + +@_use_c_impl +def providedBy(ob): + """ + Return the interfaces provided by *ob*. + + If *ob* is a :class:`super` object, then only interfaces implemented + by the remainder of the classes in the method resolution order are + considered. Interfaces directly provided by the object underlying *ob* + are not. + """ + # Here we have either a special object, an old-style declaration + # or a descriptor + + # Try to get __providedBy__ + try: + if isinstance(ob, super): # Some objects raise errors on isinstance() + return implementedBy(ob) + + r = ob.__providedBy__ + except AttributeError: + # Not set yet. Fall back to lower-level thing that computes it + return getObjectSpecification(ob) + + try: + # We might have gotten a descriptor from an instance of a + # class (like an ExtensionClass) that doesn't support + # descriptors. We'll make sure we got one by trying to get + # the only attribute, which all specs have. + r.extends + except AttributeError: + + # The object's class doesn't understand descriptors. + # Sigh. We need to get an object descriptor, but we have to be + # careful. We want to use the instance's __provides__, if + # there is one, but only if it didn't come from the class. + + try: + r = ob.__provides__ + except AttributeError: + # No __provides__, so just fall back to implementedBy + return implementedBy(ob.__class__) + + # We need to make sure we got the __provides__ from the + # instance. We'll do this by making sure we don't get the same + # thing from the class: + + try: + cp = ob.__class__.__provides__ + except AttributeError: + # The ob doesn't have a class or the class has no + # provides, assume we're done: + return r + + if r is cp: + # Oops, we got the provides from the class. This means + # the object doesn't have it's own. We should use implementedBy + return implementedBy(ob.__class__) + + return r + + +@_use_c_impl +class ObjectSpecificationDescriptor: + """Implement the ``__providedBy__`` attribute + + The ``__providedBy__`` attribute computes the interfaces provided by + an object. If an object has an ``__provides__`` attribute, that is returned. + Otherwise, `implementedBy` the *cls* is returned. + + .. versionchanged:: 5.4.0 + Both the default (C) implementation and the Python implementation + now let exceptions raised by accessing ``__provides__`` propagate. + Previously, the C version ignored all exceptions. + .. versionchanged:: 5.4.0 + The Python implementation now matches the C implementation and lets + a ``__provides__`` of ``None`` override what the class is declared to + implement. + """ + + def __get__(self, inst, cls): + """Get an object specification for an object + """ + if inst is None: + return getObjectSpecification(cls) + + try: + return inst.__provides__ + except AttributeError: + return implementedBy(cls) + + +############################################################################## + +def _normalizeargs(sequence, output=None): + """Normalize declaration arguments + + Normalization arguments might contain Declarions, tuples, or single + interfaces. + + Anything but individual interfaces or implements specs will be expanded. + """ + if output is None: + output = [] + + cls = sequence.__class__ + if InterfaceClass in cls.__mro__ or Implements in cls.__mro__: + output.append(sequence) + else: + for v in sequence: + _normalizeargs(v, output) + + return output + +_empty = _ImmutableDeclaration() + +objectSpecificationDescriptor = ObjectSpecificationDescriptor() diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/document.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/document.py new file mode 100644 index 00000000..84cfaa0b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/document.py @@ -0,0 +1,124 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" Pretty-Print an Interface object as structured text (Yum) + +This module provides a function, asStructuredText, for rendering an +interface as structured text. +""" +import zope.interface + +__all__ = [ + 'asReStructuredText', + 'asStructuredText', +] + +def asStructuredText(I, munge=0, rst=False): + """ Output structured text format. Note, this will whack any existing + 'structured' format of the text. + + If `rst=True`, then the output will quote all code as inline literals in + accordance with 'reStructuredText' markup principles. + """ + + if rst: + inline_literal = lambda s: "``{}``".format(s) + else: + inline_literal = lambda s: s + + r = [inline_literal(I.getName())] + outp = r.append + level = 1 + + if I.getDoc(): + outp(_justify_and_indent(_trim_doc_string(I.getDoc()), level)) + + bases = [base + for base in I.__bases__ + if base is not zope.interface.Interface + ] + if bases: + outp(_justify_and_indent("This interface extends:", level, munge)) + level += 1 + for b in bases: + item = "o %s" % inline_literal(b.getName()) + outp(_justify_and_indent(_trim_doc_string(item), level, munge)) + level -= 1 + + namesAndDescriptions = sorted(I.namesAndDescriptions()) + + outp(_justify_and_indent("Attributes:", level, munge)) + level += 1 + for name, desc in namesAndDescriptions: + if not hasattr(desc, 'getSignatureString'): # ugh... + item = "{} -- {}".format(inline_literal(desc.getName()), + desc.getDoc() or 'no documentation') + outp(_justify_and_indent(_trim_doc_string(item), level, munge)) + level -= 1 + + outp(_justify_and_indent("Methods:", level, munge)) + level += 1 + for name, desc in namesAndDescriptions: + if hasattr(desc, 'getSignatureString'): # ugh... + _call = "{}{}".format(desc.getName(), desc.getSignatureString()) + item = "{} -- {}".format(inline_literal(_call), + desc.getDoc() or 'no documentation') + outp(_justify_and_indent(_trim_doc_string(item), level, munge)) + + return "\n\n".join(r) + "\n\n" + + +def asReStructuredText(I, munge=0): + """ Output reStructuredText format. Note, this will whack any existing + 'structured' format of the text.""" + return asStructuredText(I, munge=munge, rst=True) + + +def _trim_doc_string(text): + """ Trims a doc string to make it format + correctly with structured text. """ + + lines = text.replace('\r\n', '\n').split('\n') + nlines = [lines.pop(0)] + if lines: + min_indent = min([len(line) - len(line.lstrip()) + for line in lines]) + for line in lines: + nlines.append(line[min_indent:]) + + return '\n'.join(nlines) + + +def _justify_and_indent(text, level, munge=0, width=72): + """ indent and justify text, rejustify (munge) if specified """ + + indent = " " * level + + if munge: + lines = [] + line = indent + text = text.split() + + for word in text: + line = ' '.join([line, word]) + if len(line) > width: + lines.append(line) + line = indent + else: + lines.append(line) + + return '\n'.join(lines) + + else: + return indent + \ + text.strip().replace("\r\n", "\n") .replace("\n", "\n" + indent) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/exceptions.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/exceptions.py new file mode 100644 index 00000000..d5c234a6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/exceptions.py @@ -0,0 +1,275 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Interface-specific exceptions +""" + +__all__ = [ + # Invalid tree + 'Invalid', + 'DoesNotImplement', + 'BrokenImplementation', + 'BrokenMethodImplementation', + 'MultipleInvalid', + # Other + 'BadImplements', + 'InvalidInterface', +] + +class Invalid(Exception): + """A specification is violated + """ + + +class _TargetInvalid(Invalid): + # Internal use. Subclass this when you're describing + # a particular target object that's invalid according + # to a specific interface. + # + # For backwards compatibility, the *target* and *interface* are + # optional, and the signatures are inconsistent in their ordering. + # + # We deal with the inconsistency in ordering by defining the index + # of the two values in ``self.args``. *target* uses a marker object to + # distinguish "not given" from "given, but None", because the latter + # can be a value that gets passed to validation. For this reason, it must + # always be the last argument (we detect absence by the ``IndexError``). + + _IX_INTERFACE = 0 + _IX_TARGET = 1 + # The exception to catch when indexing self.args indicating that + # an argument was not given. If all arguments are expected, + # a subclass should set this to (). + _NOT_GIVEN_CATCH = IndexError + _NOT_GIVEN = '<Not Given>' + + def _get_arg_or_default(self, ix, default=None): + try: + return self.args[ix] # pylint:disable=unsubscriptable-object + except self._NOT_GIVEN_CATCH: + return default + + @property + def interface(self): + return self._get_arg_or_default(self._IX_INTERFACE) + + @property + def target(self): + return self._get_arg_or_default(self._IX_TARGET, self._NOT_GIVEN) + + ### + # str + # + # The ``__str__`` of self is implemented by concatenating (%s), in order, + # these properties (none of which should have leading or trailing + # whitespace): + # + # - self._str_subject + # Begin the message, including a description of the target. + # - self._str_description + # Provide a general description of the type of error, including + # the interface name if possible and relevant. + # - self._str_conjunction + # Join the description to the details. Defaults to ": ". + # - self._str_details + # Provide details about how this particular instance of the error. + # - self._str_trailer + # End the message. Usually just a period. + ### + + @property + def _str_subject(self): + target = self.target + if target is self._NOT_GIVEN: + return "An object" + return "The object {!r}".format(target) + + @property + def _str_description(self): + return "has failed to implement interface %s" % ( + self.interface or '<Unknown>' + ) + + _str_conjunction = ": " + _str_details = "<unknown>" + _str_trailer = '.' + + def __str__(self): + return "{} {}{}{}{}".format( + self._str_subject, + self._str_description, + self._str_conjunction, + self._str_details, + self._str_trailer + ) + + +class DoesNotImplement(_TargetInvalid): + """ + DoesNotImplement(interface[, target]) + + The *target* (optional) does not implement the *interface*. + + .. versionchanged:: 5.0.0 + Add the *target* argument and attribute, and change the resulting + string value of this object accordingly. + """ + + _str_details = "Does not declaratively implement the interface" + + +class BrokenImplementation(_TargetInvalid): + """ + BrokenImplementation(interface, name[, target]) + + The *target* (optional) is missing the attribute *name*. + + .. versionchanged:: 5.0.0 + Add the *target* argument and attribute, and change the resulting + string value of this object accordingly. + + The *name* can either be a simple string or a ``Attribute`` object. + """ + + _IX_NAME = _TargetInvalid._IX_INTERFACE + 1 + _IX_TARGET = _IX_NAME + 1 + + @property + def name(self): + return self.args[1] # pylint:disable=unsubscriptable-object + + @property + def _str_details(self): + return "The %s attribute was not provided" % ( + repr(self.name) if isinstance(self.name, str) else self.name + ) + + +class BrokenMethodImplementation(_TargetInvalid): + """ + BrokenMethodImplementation(method, message[, implementation, interface, target]) + + The *target* (optional) has a *method* in *implementation* that violates + its contract in a way described by *mess*. + + .. versionchanged:: 5.0.0 + Add the *interface* and *target* argument and attribute, + and change the resulting string value of this object accordingly. + + The *method* can either be a simple string or a ``Method`` object. + + .. versionchanged:: 5.0.0 + If *implementation* is given, then the *message* will have the + string "implementation" replaced with an short but informative + representation of *implementation*. + + """ + + _IX_IMPL = 2 + _IX_INTERFACE = _IX_IMPL + 1 + _IX_TARGET = _IX_INTERFACE + 1 + + @property + def method(self): + return self.args[0] # pylint:disable=unsubscriptable-object + + @property + def mess(self): + return self.args[1] # pylint:disable=unsubscriptable-object + + @staticmethod + def __implementation_str(impl): + # It could be a callable or some arbitrary object, we don't + # know yet. + import inspect # Inspect is a heavy-weight dependency, lots of imports + try: + sig = inspect.signature + formatsig = str + except AttributeError: + sig = inspect.getargspec + f = inspect.formatargspec + formatsig = lambda sig: f(*sig) # pylint:disable=deprecated-method + + try: + sig = sig(impl) + except (ValueError, TypeError): + # Unable to introspect. Darn. + # This could be a non-callable, or a particular builtin, + # or a bound method that doesn't even accept 'self', e.g., + # ``Class.method = lambda: None; Class().method`` + return repr(impl) + + try: + name = impl.__qualname__ + except AttributeError: + name = impl.__name__ + + return name + formatsig(sig) + + @property + def _str_details(self): + impl = self._get_arg_or_default(self._IX_IMPL, self._NOT_GIVEN) + message = self.mess + if impl is not self._NOT_GIVEN and 'implementation' in message: + message = message.replace("implementation", '%r') + message = message % (self.__implementation_str(impl),) + + return 'The contract of {} is violated because {}'.format( + repr(self.method) if isinstance(self.method, str) else self.method, + message, + ) + + +class MultipleInvalid(_TargetInvalid): + """ + The *target* has failed to implement the *interface* in + multiple ways. + + The failures are described by *exceptions*, a collection of + other `Invalid` instances. + + .. versionadded:: 5.0 + """ + + _NOT_GIVEN_CATCH = () + + def __init__(self, interface, target, exceptions): + super().__init__(interface, target, tuple(exceptions)) + + @property + def exceptions(self): + return self.args[2] # pylint:disable=unsubscriptable-object + + @property + def _str_details(self): + # It would be nice to use tabs here, but that + # is hard to represent in doctests. + return '\n ' + '\n '.join( + x._str_details.strip() if isinstance(x, _TargetInvalid) else str(x) + for x in self.exceptions + ) + + _str_conjunction = ':' # We don't want a trailing space, messes up doctests + _str_trailer = '' + + +class InvalidInterface(Exception): + """The interface has invalid contents + """ + +class BadImplements(TypeError): + """An implementation assertion is invalid + + because it doesn't contain an interface or a sequence of valid + implementation assertions. + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/interface.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/interface.py new file mode 100644 index 00000000..1bd6f9e8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/interface.py @@ -0,0 +1,1131 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Interface object implementation +""" +# pylint:disable=protected-access +import sys +from types import MethodType +from types import FunctionType +import weakref + +from zope.interface._compat import _use_c_impl +from zope.interface.exceptions import Invalid +from zope.interface.ro import ro as calculate_ro +from zope.interface import ro + +__all__ = [ + # Most of the public API from this module is directly exported + # from zope.interface. The only remaining public API intended to + # be imported from here should be those few things documented as + # such. + 'InterfaceClass', + 'Specification', + 'adapter_hooks', +] + +CO_VARARGS = 4 +CO_VARKEYWORDS = 8 +# Put in the attrs dict of an interface by ``taggedValue`` and ``invariants`` +TAGGED_DATA = '__interface_tagged_values__' +# Put in the attrs dict of an interface by ``interfacemethod`` +INTERFACE_METHODS = '__interface_methods__' + +_decorator_non_return = object() +_marker = object() + + + +def invariant(call): + f_locals = sys._getframe(1).f_locals + tags = f_locals.setdefault(TAGGED_DATA, {}) + invariants = tags.setdefault('invariants', []) + invariants.append(call) + return _decorator_non_return + + +def taggedValue(key, value): + """Attaches a tagged value to an interface at definition time.""" + f_locals = sys._getframe(1).f_locals + tagged_values = f_locals.setdefault(TAGGED_DATA, {}) + tagged_values[key] = value + return _decorator_non_return + + +class Element: + """ + Default implementation of `zope.interface.interfaces.IElement`. + """ + + # We can't say this yet because we don't have enough + # infrastructure in place. + # + #implements(IElement) + + def __init__(self, __name__, __doc__=''): # pylint:disable=redefined-builtin + if not __doc__ and __name__.find(' ') >= 0: + __doc__ = __name__ + __name__ = None + + self.__name__ = __name__ + self.__doc__ = __doc__ + # Tagged values are rare, especially on methods or attributes. + # Deferring the allocation can save substantial memory. + self.__tagged_values = None + + def getName(self): + """ Returns the name of the object. """ + return self.__name__ + + def getDoc(self): + """ Returns the documentation for the object. """ + return self.__doc__ + + ### + # Tagged values. + # + # Direct tagged values are set only in this instance. Others + # may be inherited (for those subclasses that have that concept). + ### + + def getTaggedValue(self, tag): + """ Returns the value associated with 'tag'. """ + if not self.__tagged_values: + raise KeyError(tag) + return self.__tagged_values[tag] + + def queryTaggedValue(self, tag, default=None): + """ Returns the value associated with 'tag'. """ + return self.__tagged_values.get(tag, default) if self.__tagged_values else default + + def getTaggedValueTags(self): + """ Returns a collection of all tags. """ + return self.__tagged_values.keys() if self.__tagged_values else () + + def setTaggedValue(self, tag, value): + """ Associates 'value' with 'key'. """ + if self.__tagged_values is None: + self.__tagged_values = {} + self.__tagged_values[tag] = value + + queryDirectTaggedValue = queryTaggedValue + getDirectTaggedValue = getTaggedValue + getDirectTaggedValueTags = getTaggedValueTags + + +SpecificationBasePy = object # filled by _use_c_impl. + + +@_use_c_impl +class SpecificationBase: + # This object is the base of the inheritance hierarchy for ClassProvides: + # + # ClassProvides < ClassProvidesBase, Declaration + # Declaration < Specification < SpecificationBase + # ClassProvidesBase < SpecificationBase + # + # In order to have compatible instance layouts, we need to declare + # the storage used by Specification and Declaration here (and + # those classes must have ``__slots__ = ()``); fortunately this is + # not a waste of space because those are the only two inheritance + # trees. These all translate into tp_members in C. + __slots__ = ( + # Things used here. + '_implied', + # Things used in Specification. + '_dependents', + '_bases', + '_v_attrs', + '__iro__', + '__sro__', + '__weakref__', + ) + + def providedBy(self, ob): + """Is the interface implemented by an object + """ + spec = providedBy(ob) + return self in spec._implied + + def implementedBy(self, cls): + """Test whether the specification is implemented by a class or factory. + + Raise TypeError if argument is neither a class nor a callable. + """ + spec = implementedBy(cls) + return self in spec._implied + + def isOrExtends(self, interface): + """Is the interface the same as or extend the given interface + """ + return interface in self._implied # pylint:disable=no-member + + __call__ = isOrExtends + + +class NameAndModuleComparisonMixin: + # Internal use. Implement the basic sorting operators (but not (in)equality + # or hashing). Subclasses must provide ``__name__`` and ``__module__`` + # attributes. Subclasses will be mutually comparable; but because equality + # and hashing semantics are missing from this class, take care in how + # you define those two attributes: If you stick with the default equality + # and hashing (identity based) you should make sure that all possible ``__name__`` + # and ``__module__`` pairs are unique ACROSS ALL SUBCLASSES. (Actually, pretty + # much the same thing goes if you define equality and hashing to be based on + # those two attributes: they must still be consistent ACROSS ALL SUBCLASSES.) + + # pylint:disable=assigning-non-slot + __slots__ = () + + def _compare(self, other): + """ + Compare *self* to *other* based on ``__name__`` and ``__module__``. + + Return 0 if they are equal, return 1 if *self* is + greater than *other*, and return -1 if *self* is less than + *other*. + + If *other* does not have ``__name__`` or ``__module__``, then + return ``NotImplemented``. + + .. caution:: + This allows comparison to things well outside the type hierarchy, + perhaps not symmetrically. + + For example, ``class Foo(object)`` and ``class Foo(Interface)`` + in the same file would compare equal, depending on the order of + operands. Writing code like this by hand would be unusual, but it could + happen with dynamic creation of types and interfaces. + + None is treated as a pseudo interface that implies the loosest + contact possible, no contract. For that reason, all interfaces + sort before None. + """ + if other is self: + return 0 + + if other is None: + return -1 + + n1 = (self.__name__, self.__module__) + try: + n2 = (other.__name__, other.__module__) + except AttributeError: + return NotImplemented + + # This spelling works under Python3, which doesn't have cmp(). + return (n1 > n2) - (n1 < n2) + + def __lt__(self, other): + c = self._compare(other) + if c is NotImplemented: + return c + return c < 0 + + def __le__(self, other): + c = self._compare(other) + if c is NotImplemented: + return c + return c <= 0 + + def __gt__(self, other): + c = self._compare(other) + if c is NotImplemented: + return c + return c > 0 + + def __ge__(self, other): + c = self._compare(other) + if c is NotImplemented: + return c + return c >= 0 + + +@_use_c_impl +class InterfaceBase(NameAndModuleComparisonMixin, SpecificationBasePy): + """Base class that wants to be replaced with a C base :) + """ + + __slots__ = ( + '__name__', + '__ibmodule__', + '_v_cached_hash', + ) + + def __init__(self, name=None, module=None): + self.__name__ = name + self.__ibmodule__ = module + + def _call_conform(self, conform): + raise NotImplementedError + + @property + def __module_property__(self): + # This is for _InterfaceMetaClass + return self.__ibmodule__ + + def __call__(self, obj, alternate=_marker): + """Adapt an object to the interface + """ + try: + conform = obj.__conform__ + except AttributeError: + conform = None + + if conform is not None: + adapter = self._call_conform(conform) + if adapter is not None: + return adapter + + adapter = self.__adapt__(obj) + + if adapter is not None: + return adapter + if alternate is not _marker: + return alternate + raise TypeError("Could not adapt", obj, self) + + def __adapt__(self, obj): + """Adapt an object to the receiver + """ + if self.providedBy(obj): + return obj + + for hook in adapter_hooks: + adapter = hook(self, obj) + if adapter is not None: + return adapter + + return None + + def __hash__(self): + # pylint:disable=assigning-non-slot,attribute-defined-outside-init + try: + return self._v_cached_hash + except AttributeError: + self._v_cached_hash = hash((self.__name__, self.__module__)) + return self._v_cached_hash + + def __eq__(self, other): + c = self._compare(other) + if c is NotImplemented: + return c + return c == 0 + + def __ne__(self, other): + if other is self: + return False + + c = self._compare(other) + if c is NotImplemented: + return c + return c != 0 + +adapter_hooks = _use_c_impl([], 'adapter_hooks') + + +class Specification(SpecificationBase): + """Specifications + + An interface specification is used to track interface declarations + and component registrations. + + This class is a base class for both interfaces themselves and for + interface specifications (declarations). + + Specifications are mutable. If you reassign their bases, their + relations with other specifications are adjusted accordingly. + """ + __slots__ = () + + # The root of all Specifications. This will be assigned `Interface`, + # once it is defined. + _ROOT = None + + # Copy some base class methods for speed + isOrExtends = SpecificationBase.isOrExtends + providedBy = SpecificationBase.providedBy + + def __init__(self, bases=()): + # There are many leaf interfaces with no dependents, + # and a few with very many. It's a heavily left-skewed + # distribution. In a survey of Plone and Zope related packages + # that loaded 2245 InterfaceClass objects and 2235 ClassProvides + # instances, there were a total of 7000 Specification objects created. + # 4700 had 0 dependents, 1400 had 1, 382 had 2 and so on. Only one + # for <type> had 1664. So there's savings to be had deferring + # the creation of dependents. + self._dependents = None # type: weakref.WeakKeyDictionary + self._bases = () + self._implied = {} + self._v_attrs = None + self.__iro__ = () + self.__sro__ = () + + self.__bases__ = tuple(bases) + + @property + def dependents(self): + if self._dependents is None: + self._dependents = weakref.WeakKeyDictionary() + return self._dependents + + def subscribe(self, dependent): + self._dependents[dependent] = self.dependents.get(dependent, 0) + 1 + + def unsubscribe(self, dependent): + try: + n = self._dependents[dependent] + except TypeError: + raise KeyError(dependent) + n -= 1 + if not n: + del self.dependents[dependent] + else: + assert n > 0 + self.dependents[dependent] = n + + def __setBases(self, bases): + # Remove ourselves as a dependent of our old bases + for b in self.__bases__: + b.unsubscribe(self) + + # Register ourselves as a dependent of our new bases + self._bases = bases + for b in bases: + b.subscribe(self) + + self.changed(self) + + __bases__ = property( + lambda self: self._bases, + __setBases, + ) + + # This method exists for tests to override the way we call + # ro.calculate_ro(), usually by adding extra kwargs. We don't + # want to have a mutable dictionary as a class member that we pass + # ourself because mutability is bad, and passing **kw is slower than + # calling the bound function. + _do_calculate_ro = calculate_ro + + def _calculate_sro(self): + """ + Calculate and return the resolution order for this object, using its ``__bases__``. + + Ensures that ``Interface`` is always the last (lowest priority) element. + """ + # We'd like to make Interface the lowest priority as a + # property of the resolution order algorithm. That almost + # works out naturally, but it fails when class inheritance has + # some bases that DO implement an interface, and some that DO + # NOT. In such a mixed scenario, you wind up with a set of + # bases to consider that look like this: [[..., Interface], + # [..., object], ...]. Depending on the order of inheritance, + # Interface can wind up before or after object, and that can + # happen at any point in the tree, meaning Interface can wind + # up somewhere in the middle of the order. Since Interface is + # treated as something that everything winds up implementing + # anyway (a catch-all for things like adapters), having it high up + # the order is bad. It's also bad to have it at the end, just before + # some concrete class: concrete classes should be HIGHER priority than + # interfaces (because there's only one class, but many implementations). + # + # One technically nice way to fix this would be to have + # ``implementedBy(object).__bases__ = (Interface,)`` + # + # But: (1) That fails for old-style classes and (2) that causes + # everything to appear to *explicitly* implement Interface, when up + # to this point it's been an implicit virtual sort of relationship. + # + # So we force the issue by mutating the resolution order. + + # Note that we let C3 use pre-computed __sro__ for our bases. + # This requires that by the time this method is invoked, our bases + # have settled their SROs. Thus, ``changed()`` must first + # update itself before telling its descendents of changes. + sro = self._do_calculate_ro(base_mros={ + b: b.__sro__ + for b in self.__bases__ + }) + root = self._ROOT + if root is not None and sro and sro[-1] is not root: + # In one dataset of 1823 Interface objects, 1117 ClassProvides objects, + # sro[-1] was root 4496 times, and only not root 118 times. So it's + # probably worth checking. + + # Once we don't have to deal with old-style classes, + # we can add a check and only do this if base_count > 1, + # if we tweak the bootstrapping for ``<implementedBy object>`` + sro = [ + x + for x in sro + if x is not root + ] + sro.append(root) + + return sro + + def changed(self, originally_changed): + """ + We, or something we depend on, have changed. + + By the time this is called, the things we depend on, + such as our bases, should themselves be stable. + """ + self._v_attrs = None + + implied = self._implied + implied.clear() + + ancestors = self._calculate_sro() + self.__sro__ = tuple(ancestors) + self.__iro__ = tuple([ancestor for ancestor in ancestors + if isinstance(ancestor, InterfaceClass) + ]) + + for ancestor in ancestors: + # We directly imply our ancestors: + implied[ancestor] = () + + # Now, advise our dependents of change + # (being careful not to create the WeakKeyDictionary if not needed): + for dependent in tuple(self._dependents.keys() if self._dependents else ()): + dependent.changed(originally_changed) + + # Just in case something called get() at some point + # during that process and we have a cycle of some sort + # make sure we didn't cache incomplete results. + self._v_attrs = None + + def interfaces(self): + """Return an iterator for the interfaces in the specification. + """ + seen = {} + for base in self.__bases__: + for interface in base.interfaces(): + if interface not in seen: + seen[interface] = 1 + yield interface + + def extends(self, interface, strict=True): + """Does the specification extend the given interface? + + Test whether an interface in the specification extends the + given interface + """ + return ((interface in self._implied) + and + ((not strict) or (self != interface)) + ) + + def weakref(self, callback=None): + return weakref.ref(self, callback) + + def get(self, name, default=None): + """Query for an attribute description + """ + attrs = self._v_attrs + if attrs is None: + attrs = self._v_attrs = {} + attr = attrs.get(name) + if attr is None: + for iface in self.__iro__: + attr = iface.direct(name) + if attr is not None: + attrs[name] = attr + break + + return default if attr is None else attr + + +class _InterfaceMetaClass(type): + # Handling ``__module__`` on ``InterfaceClass`` is tricky. We need + # to be able to read it on a type and get the expected string. We + # also need to be able to set it on an instance and get the value + # we set. So far so good. But what gets tricky is that we'd like + # to store the value in the C structure (``InterfaceBase.__ibmodule__``) for + # direct access during equality, sorting, and hashing. "No + # problem, you think, I'll just use a property" (well, the C + # equivalents, ``PyMemberDef`` or ``PyGetSetDef``). + # + # Except there is a problem. When a subclass is created, the + # metaclass (``type``) always automatically puts the expected + # string in the class's dictionary under ``__module__``, thus + # overriding the property inherited from the superclass. Writing + # ``Subclass.__module__`` still works, but + # ``Subclass().__module__`` fails. + # + # There are multiple ways to work around this: + # + # (1) Define ``InterfaceBase.__getattribute__`` to watch for + # ``__module__`` and return the C storage. + # + # This works, but slows down *all* attribute access (except, + # ironically, to ``__module__``) by about 25% (40ns becomes 50ns) + # (when implemented in C). Since that includes methods like + # ``providedBy``, that's probably not acceptable. + # + # All the other methods involve modifying subclasses. This can be + # done either on the fly in some cases, as instances are + # constructed, or by using a metaclass. These next few can be done on the fly. + # + # (2) Make ``__module__`` a descriptor in each subclass dictionary. + # It can't be a straight up ``@property`` descriptor, though, because accessing + # it on the class returns a ``property`` object, not the desired string. + # + # (3) Implement a data descriptor (``__get__`` and ``__set__``) + # that is both a subclass of string, and also does the redirect of + # ``__module__`` to ``__ibmodule__`` and does the correct thing + # with the ``instance`` argument to ``__get__`` is None (returns + # the class's value.) (Why must it be a subclass of string? Because + # when it' s in the class's dict, it's defined on an *instance* of the + # metaclass; descriptors in an instance's dict aren't honored --- their + # ``__get__`` is never invoked --- so it must also *be* the value we want + # returned.) + # + # This works, preserves the ability to read and write + # ``__module__``, and eliminates any penalty accessing other + # attributes. But it slows down accessing ``__module__`` of + # instances by 200% (40ns to 124ns), requires editing class dicts on the fly + # (in InterfaceClass.__init__), thus slightly slowing down all interface creation, + # and is ugly. + # + # (4) As in the last step, but make it a non-data descriptor (no ``__set__``). + # + # If you then *also* store a copy of ``__ibmodule__`` in + # ``__module__`` in the instance's dict, reading works for both + # class and instance and is full speed for instances. But the cost + # is storage space, and you can't write to it anymore, not without + # things getting out of sync. + # + # (Actually, ``__module__`` was never meant to be writable. Doing + # so would break BTrees and normal dictionaries, as well as the + # repr, maybe more.) + # + # That leaves us with a metaclass. (Recall that a class is an + # instance of its metaclass, so properties/descriptors defined in + # the metaclass are used when accessing attributes on the + # instance/class. We'll use that to define ``__module__``.) Here + # we can have our cake and eat it too: no extra storage, and + # C-speed access to the underlying storage. The only substantial + # cost is that metaclasses tend to make people's heads hurt. (But + # still less than the descriptor-is-string, hopefully.) + + __slots__ = () + + def __new__(cls, name, bases, attrs): + # Figure out what module defined the interface. + # This is copied from ``InterfaceClass.__init__``; + # reviewers aren't sure how AttributeError or KeyError + # could be raised. + __module__ = sys._getframe(1).f_globals['__name__'] + # Get the C optimized __module__ accessor and give it + # to the new class. + moduledescr = InterfaceBase.__dict__['__module__'] + if isinstance(moduledescr, str): + # We're working with the Python implementation, + # not the C version + moduledescr = InterfaceBase.__dict__['__module_property__'] + attrs['__module__'] = moduledescr + kind = type.__new__(cls, name, bases, attrs) + kind.__module = __module__ + return kind + + @property + def __module__(cls): + return cls.__module + + def __repr__(cls): + return "<class '{}.{}'>".format( + cls.__module, + cls.__name__, + ) + + +_InterfaceClassBase = _InterfaceMetaClass( + 'InterfaceClass', + # From least specific to most specific. + (InterfaceBase, Specification, Element), + {'__slots__': ()} +) + + +def interfacemethod(func): + """ + Convert a method specification to an actual method of the interface. + + This is a decorator that functions like `staticmethod` et al. + + The primary use of this decorator is to allow interface definitions to + define the ``__adapt__`` method, but other interface methods can be + overridden this way too. + + .. seealso:: `zope.interface.interfaces.IInterfaceDeclaration.interfacemethod` + """ + f_locals = sys._getframe(1).f_locals + methods = f_locals.setdefault(INTERFACE_METHODS, {}) + methods[func.__name__] = func + return _decorator_non_return + + +class InterfaceClass(_InterfaceClassBase): + """ + Prototype (scarecrow) Interfaces Implementation. + + Note that it is not possible to change the ``__name__`` or ``__module__`` + after an instance of this object has been constructed. + """ + + # We can't say this yet because we don't have enough + # infrastructure in place. + # + #implements(IInterface) + + def __new__(cls, name=None, bases=(), attrs=None, __doc__=None, # pylint:disable=redefined-builtin + __module__=None): + assert isinstance(bases, tuple) + attrs = attrs or {} + needs_custom_class = attrs.pop(INTERFACE_METHODS, None) + if needs_custom_class: + needs_custom_class.update( + {'__classcell__': attrs.pop('__classcell__')} + if '__classcell__' in attrs + else {} + ) + if '__adapt__' in needs_custom_class: + # We need to tell the C code to call this. + needs_custom_class['_CALL_CUSTOM_ADAPT'] = 1 + + if issubclass(cls, _InterfaceClassWithCustomMethods): + cls_bases = (cls,) + elif cls is InterfaceClass: + cls_bases = (_InterfaceClassWithCustomMethods,) + else: + cls_bases = (cls, _InterfaceClassWithCustomMethods) + + cls = type(cls)( # pylint:disable=self-cls-assignment + name + "<WithCustomMethods>", + cls_bases, + needs_custom_class + ) + + return _InterfaceClassBase.__new__(cls) + + def __init__(self, name, bases=(), attrs=None, __doc__=None, # pylint:disable=redefined-builtin + __module__=None): + # We don't call our metaclass parent directly + # pylint:disable=non-parent-init-called + # pylint:disable=super-init-not-called + if not all(isinstance(base, InterfaceClass) for base in bases): + raise TypeError('Expected base interfaces') + + if attrs is None: + attrs = {} + + if __module__ is None: + __module__ = attrs.get('__module__') + if isinstance(__module__, str): + del attrs['__module__'] + else: + try: + # Figure out what module defined the interface. + # This is how cPython figures out the module of + # a class, but of course it does it in C. :-/ + __module__ = sys._getframe(1).f_globals['__name__'] + except (AttributeError, KeyError): # pragma: no cover + pass + + InterfaceBase.__init__(self, name, __module__) + # These asserts assisted debugging the metaclass + # assert '__module__' not in self.__dict__ + # assert self.__ibmodule__ is self.__module__ is __module__ + + d = attrs.get('__doc__') + if d is not None: + if not isinstance(d, Attribute): + if __doc__ is None: + __doc__ = d + del attrs['__doc__'] + + if __doc__ is None: + __doc__ = '' + + Element.__init__(self, name, __doc__) + + tagged_data = attrs.pop(TAGGED_DATA, None) + if tagged_data is not None: + for key, val in tagged_data.items(): + self.setTaggedValue(key, val) + + Specification.__init__(self, bases) + self.__attrs = self.__compute_attrs(attrs) + + self.__identifier__ = "{}.{}".format(__module__, name) + + def __compute_attrs(self, attrs): + # Make sure that all recorded attributes (and methods) are of type + # `Attribute` and `Method` + def update_value(aname, aval): + if isinstance(aval, Attribute): + aval.interface = self + if not aval.__name__: + aval.__name__ = aname + elif isinstance(aval, FunctionType): + aval = fromFunction(aval, self, name=aname) + else: + raise InvalidInterface("Concrete attribute, " + aname) + return aval + + return { + aname: update_value(aname, aval) + for aname, aval in attrs.items() + if aname not in ( + # __locals__: Python 3 sometimes adds this. + '__locals__', + # __qualname__: PEP 3155 (Python 3.3+) + '__qualname__', + # __annotations__: PEP 3107 (Python 3.0+) + '__annotations__', + ) + and aval is not _decorator_non_return + } + + def interfaces(self): + """Return an iterator for the interfaces in the specification. + """ + yield self + + def getBases(self): + return self.__bases__ + + def isEqualOrExtendedBy(self, other): + """Same interface or extends?""" + return self == other or other.extends(self) + + def names(self, all=False): # pylint:disable=redefined-builtin + """Return the attribute names defined by the interface.""" + if not all: + return self.__attrs.keys() + + r = self.__attrs.copy() + + for base in self.__bases__: + r.update(dict.fromkeys(base.names(all))) + + return r.keys() + + def __iter__(self): + return iter(self.names(all=True)) + + def namesAndDescriptions(self, all=False): # pylint:disable=redefined-builtin + """Return attribute names and descriptions defined by interface.""" + if not all: + return self.__attrs.items() + + r = {} + for base in self.__bases__[::-1]: + r.update(dict(base.namesAndDescriptions(all))) + + r.update(self.__attrs) + + return r.items() + + def getDescriptionFor(self, name): + """Return the attribute description for the given name.""" + r = self.get(name) + if r is not None: + return r + + raise KeyError(name) + + __getitem__ = getDescriptionFor + + def __contains__(self, name): + return self.get(name) is not None + + def direct(self, name): + return self.__attrs.get(name) + + def queryDescriptionFor(self, name, default=None): + return self.get(name, default) + + def validateInvariants(self, obj, errors=None): + """validate object to defined invariants.""" + + for iface in self.__iro__: + for invariant in iface.queryDirectTaggedValue('invariants', ()): + try: + invariant(obj) + except Invalid as error: + if errors is not None: + errors.append(error) + else: + raise + + if errors: + raise Invalid(errors) + + def queryTaggedValue(self, tag, default=None): + """ + Queries for the value associated with *tag*, returning it from the nearest + interface in the ``__iro__``. + + If not found, returns *default*. + """ + for iface in self.__iro__: + value = iface.queryDirectTaggedValue(tag, _marker) + if value is not _marker: + return value + return default + + def getTaggedValue(self, tag): + """ Returns the value associated with 'tag'. """ + value = self.queryTaggedValue(tag, default=_marker) + if value is _marker: + raise KeyError(tag) + return value + + def getTaggedValueTags(self): + """ Returns a list of all tags. """ + keys = set() + for base in self.__iro__: + keys.update(base.getDirectTaggedValueTags()) + return keys + + def __repr__(self): + try: + return self._v_repr + except AttributeError: + name = str(self) + r = "<{} {}>".format(self.__class__.__name__, name) + self._v_repr = r # pylint:disable=attribute-defined-outside-init + return r + + def __str__(self): + name = self.__name__ + m = self.__ibmodule__ + if m: + name = '{}.{}'.format(m, name) + return name + + def _call_conform(self, conform): + try: + return conform(self) + except TypeError: # pragma: no cover + # We got a TypeError. It might be an error raised by + # the __conform__ implementation, or *we* may have + # made the TypeError by calling an unbound method + # (object is a class). In the later case, we behave + # as though there is no __conform__ method. We can + # detect this case by checking whether there is more + # than one traceback object in the traceback chain: + if sys.exc_info()[2].tb_next is not None: + # There is more than one entry in the chain, so + # reraise the error: + raise + # This clever trick is from Phillip Eby + + return None # pragma: no cover + + def __reduce__(self): + return self.__name__ + +Interface = InterfaceClass("Interface", __module__='zope.interface') +# Interface is the only member of its own SRO. +Interface._calculate_sro = lambda: (Interface,) +Interface.changed(Interface) +assert Interface.__sro__ == (Interface,) +Specification._ROOT = Interface +ro._ROOT = Interface + +class _InterfaceClassWithCustomMethods(InterfaceClass): + """ + Marker class for interfaces with custom methods that override InterfaceClass methods. + """ + + +class Attribute(Element): + """Attribute descriptions + """ + + # We can't say this yet because we don't have enough + # infrastructure in place. + # + # implements(IAttribute) + + interface = None + + def _get_str_info(self): + """Return extra data to put at the end of __str__.""" + return "" + + def __str__(self): + of = '' + if self.interface is not None: + of = self.interface.__module__ + '.' + self.interface.__name__ + '.' + # self.__name__ may be None during construction (e.g., debugging) + return of + (self.__name__ or '<unknown>') + self._get_str_info() + + def __repr__(self): + return "<{}.{} object at 0x{:x} {}>".format( + type(self).__module__, + type(self).__name__, + id(self), + self + ) + + +class Method(Attribute): + """Method interfaces + + The idea here is that you have objects that describe methods. + This provides an opportunity for rich meta-data. + """ + + # We can't say this yet because we don't have enough + # infrastructure in place. + # + # implements(IMethod) + + positional = required = () + _optional = varargs = kwargs = None + def _get_optional(self): + if self._optional is None: + return {} + return self._optional + def _set_optional(self, opt): + self._optional = opt + def _del_optional(self): + self._optional = None + optional = property(_get_optional, _set_optional, _del_optional) + + def __call__(self, *args, **kw): + raise BrokenImplementation(self.interface, self.__name__) + + def getSignatureInfo(self): + return {'positional': self.positional, + 'required': self.required, + 'optional': self.optional, + 'varargs': self.varargs, + 'kwargs': self.kwargs, + } + + def getSignatureString(self): + sig = [] + for v in self.positional: + sig.append(v) + if v in self.optional.keys(): + sig[-1] += "=" + repr(self.optional[v]) + if self.varargs: + sig.append("*" + self.varargs) + if self.kwargs: + sig.append("**" + self.kwargs) + + return "(%s)" % ", ".join(sig) + + _get_str_info = getSignatureString + + +def fromFunction(func, interface=None, imlevel=0, name=None): + name = name or func.__name__ + method = Method(name, func.__doc__) + defaults = getattr(func, '__defaults__', None) or () + code = func.__code__ + # Number of positional arguments + na = code.co_argcount - imlevel + names = code.co_varnames[imlevel:] + opt = {} + # Number of required arguments + defaults_count = len(defaults) + if not defaults_count: + # PyPy3 uses ``__defaults_count__`` for builtin methods + # like ``dict.pop``. Surprisingly, these don't have recorded + # ``__defaults__`` + defaults_count = getattr(func, '__defaults_count__', 0) + + nr = na - defaults_count + if nr < 0: + defaults = defaults[-nr:] + nr = 0 + + # Determine the optional arguments. + opt.update(dict(zip(names[nr:], defaults))) + + method.positional = names[:na] + method.required = names[:nr] + method.optional = opt + + argno = na + + # Determine the function's variable argument's name (i.e. *args) + if code.co_flags & CO_VARARGS: + method.varargs = names[argno] + argno = argno + 1 + else: + method.varargs = None + + # Determine the function's keyword argument's name (i.e. **kw) + if code.co_flags & CO_VARKEYWORDS: + method.kwargs = names[argno] + else: + method.kwargs = None + + method.interface = interface + + for key, value in func.__dict__.items(): + method.setTaggedValue(key, value) + + return method + + +def fromMethod(meth, interface=None, name=None): + if isinstance(meth, MethodType): + func = meth.__func__ + else: + func = meth + return fromFunction(func, interface, imlevel=1, name=name) + + +# Now we can create the interesting interfaces and wire them up: +def _wire(): + from zope.interface.declarations import classImplements + # From lest specific to most specific. + from zope.interface.interfaces import IElement + classImplements(Element, IElement) + + from zope.interface.interfaces import IAttribute + classImplements(Attribute, IAttribute) + + from zope.interface.interfaces import IMethod + classImplements(Method, IMethod) + + from zope.interface.interfaces import ISpecification + classImplements(Specification, ISpecification) + + from zope.interface.interfaces import IInterface + classImplements(InterfaceClass, IInterface) + + +# We import this here to deal with module dependencies. +# pylint:disable=wrong-import-position +from zope.interface.declarations import implementedBy +from zope.interface.declarations import providedBy +from zope.interface.exceptions import InvalidInterface +from zope.interface.exceptions import BrokenImplementation + +# This ensures that ``Interface`` winds up in the flattened() +# list of the immutable declaration. It correctly overrides changed() +# as a no-op, so we bypass that. +from zope.interface.declarations import _empty +Specification.changed(_empty, _empty) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/interfaces.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/interfaces.py new file mode 100644 index 00000000..2b67ce1a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/interfaces.py @@ -0,0 +1,1480 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Interface Package Interfaces +""" +__docformat__ = 'restructuredtext' + +from zope.interface.interface import Attribute +from zope.interface.interface import Interface +from zope.interface.declarations import implementer + +__all__ = [ + 'ComponentLookupError', + 'IAdapterRegistration', + 'IAdapterRegistry', + 'IAttribute', + 'IComponentLookup', + 'IComponentRegistry', + 'IComponents', + 'IDeclaration', + 'IElement', + 'IHandlerRegistration', + 'IInterface', + 'IInterfaceDeclaration', + 'IMethod', + 'Invalid', + 'IObjectEvent', + 'IRegistered', + 'IRegistration', + 'IRegistrationEvent', + 'ISpecification', + 'ISubscriptionAdapterRegistration', + 'IUnregistered', + 'IUtilityRegistration', + 'ObjectEvent', + 'Registered', + 'Unregistered', +] + +# pylint:disable=inherit-non-class,no-method-argument,no-self-argument +# pylint:disable=unexpected-special-method-signature +# pylint:disable=too-many-lines + +class IElement(Interface): + """ + Objects that have basic documentation and tagged values. + + Known derivatives include :class:`IAttribute` and its derivative + :class:`IMethod`; these have no notion of inheritance. + :class:`IInterface` is also a derivative, and it does have a + notion of inheritance, expressed through its ``__bases__`` and + ordered in its ``__iro__`` (both defined by + :class:`ISpecification`). + """ + + # pylint:disable=arguments-differ + + # Note that defining __doc__ as an Attribute hides the docstring + # from introspection. When changing it, also change it in the Sphinx + # ReST files. + + __name__ = Attribute('__name__', 'The object name') + __doc__ = Attribute('__doc__', 'The object doc string') + + ### + # Tagged values. + # + # Direct values are established in this instance. Others may be + # inherited. Although ``IElement`` itself doesn't have a notion of + # inheritance, ``IInterface`` *does*. It might have been better to + # make ``IInterface`` define new methods + # ``getIndirectTaggedValue``, etc, to include inheritance instead + # of overriding ``getTaggedValue`` to do that, but that ship has sailed. + # So to keep things nice and symmetric, we define the ``Direct`` methods here. + ### + + def getTaggedValue(tag): + """Returns the value associated with *tag*. + + Raise a `KeyError` if the tag isn't set. + + If the object has a notion of inheritance, this searches + through the inheritance hierarchy and returns the nearest result. + If there is no such notion, this looks only at this object. + + .. versionchanged:: 4.7.0 + This method should respect inheritance if present. + """ + + def queryTaggedValue(tag, default=None): + """ + As for `getTaggedValue`, but instead of raising a `KeyError`, returns *default*. + + + .. versionchanged:: 4.7.0 + This method should respect inheritance if present. + """ + + def getTaggedValueTags(): + """ + Returns a collection of all tags in no particular order. + + If the object has a notion of inheritance, this + includes all the inherited tagged values. If there is + no such notion, this looks only at this object. + + .. versionchanged:: 4.7.0 + This method should respect inheritance if present. + """ + + def setTaggedValue(tag, value): + """ + Associates *value* with *key* directly in this object. + """ + + def getDirectTaggedValue(tag): + """ + As for `getTaggedValue`, but never includes inheritance. + + .. versionadded:: 5.0.0 + """ + + def queryDirectTaggedValue(tag, default=None): + """ + As for `queryTaggedValue`, but never includes inheritance. + + .. versionadded:: 5.0.0 + """ + + def getDirectTaggedValueTags(): + """ + As for `getTaggedValueTags`, but includes only tags directly + set on this object. + + .. versionadded:: 5.0.0 + """ + + +class IAttribute(IElement): + """Attribute descriptors""" + + interface = Attribute('interface', + 'Stores the interface instance in which the ' + 'attribute is located.') + + +class IMethod(IAttribute): + """Method attributes""" + + def getSignatureInfo(): + """Returns the signature information. + + This method returns a dictionary with the following string keys: + + - positional + A sequence of the names of positional arguments. + - required + A sequence of the names of required arguments. + - optional + A dictionary mapping argument names to their default values. + - varargs + The name of the varargs argument (or None). + - kwargs + The name of the kwargs argument (or None). + """ + + def getSignatureString(): + """Return a signature string suitable for inclusion in documentation. + + This method returns the function signature string. For example, if you + have ``def func(a, b, c=1, d='f')``, then the signature string is ``"(a, b, + c=1, d='f')"``. + """ + +class ISpecification(Interface): + """Object Behavioral specifications""" + # pylint:disable=arguments-differ + def providedBy(object): # pylint:disable=redefined-builtin + """Test whether the interface is implemented by the object + + Return true of the object asserts that it implements the + interface, including asserting that it implements an extended + interface. + """ + + def implementedBy(class_): + """Test whether the interface is implemented by instances of the class + + Return true of the class asserts that its instances implement the + interface, including asserting that they implement an extended + interface. + """ + + def isOrExtends(other): + """Test whether the specification is or extends another + """ + + def extends(other, strict=True): + """Test whether a specification extends another + + The specification extends other if it has other as a base + interface or if one of it's bases extends other. + + If strict is false, then the specification extends itself. + """ + + def weakref(callback=None): + """Return a weakref to the specification + + This method is, regrettably, needed to allow weakrefs to be + computed to security-proxied specifications. While the + zope.interface package does not require zope.security or + zope.proxy, it has to be able to coexist with it. + + """ + + __bases__ = Attribute("""Base specifications + + A tuple of specifications from which this specification is + directly derived. + + """) + + __sro__ = Attribute("""Specification-resolution order + + A tuple of the specification and all of it's ancestor + specifications from most specific to least specific. The specification + itself is the first element. + + (This is similar to the method-resolution order for new-style classes.) + """) + + __iro__ = Attribute("""Interface-resolution order + + A tuple of the specification's ancestor interfaces from + most specific to least specific. The specification itself is + included if it is an interface. + + (This is similar to the method-resolution order for new-style classes.) + """) + + def get(name, default=None): + """Look up the description for a name + + If the named attribute is not defined, the default is + returned. + """ + + +class IInterface(ISpecification, IElement): + """Interface objects + + Interface objects describe the behavior of an object by containing + useful information about the object. This information includes: + + - Prose documentation about the object. In Python terms, this + is called the "doc string" of the interface. In this element, + you describe how the object works in prose language and any + other useful information about the object. + + - Descriptions of attributes. Attribute descriptions include + the name of the attribute and prose documentation describing + the attributes usage. + + - Descriptions of methods. Method descriptions can include: + + - Prose "doc string" documentation about the method and its + usage. + + - A description of the methods arguments; how many arguments + are expected, optional arguments and their default values, + the position or arguments in the signature, whether the + method accepts arbitrary arguments and whether the method + accepts arbitrary keyword arguments. + + - Optional tagged data. Interface objects (and their attributes and + methods) can have optional, application specific tagged data + associated with them. Examples uses for this are examples, + security assertions, pre/post conditions, and other possible + information you may want to associate with an Interface or its + attributes. + + Not all of this information is mandatory. For example, you may + only want the methods of your interface to have prose + documentation and not describe the arguments of the method in + exact detail. Interface objects are flexible and let you give or + take any of these components. + + Interfaces are created with the Python class statement using + either `zope.interface.Interface` or another interface, as in:: + + from zope.interface import Interface + + class IMyInterface(Interface): + '''Interface documentation''' + + def meth(arg1, arg2): + '''Documentation for meth''' + + # Note that there is no self argument + + class IMySubInterface(IMyInterface): + '''Interface documentation''' + + def meth2(): + '''Documentation for meth2''' + + You use interfaces in two ways: + + - You assert that your object implement the interfaces. + + There are several ways that you can declare that an object + provides an interface: + + 1. Call `zope.interface.implementer` on your class definition. + + 2. Call `zope.interface.directlyProvides` on your object. + + 3. Call `zope.interface.classImplements` to declare that instances + of a class implement an interface. + + For example:: + + from zope.interface import classImplements + + classImplements(some_class, some_interface) + + This approach is useful when it is not an option to modify + the class source. Note that this doesn't affect what the + class itself implements, but only what its instances + implement. + + - You query interface meta-data. See the IInterface methods and + attributes for details. + + """ + # pylint:disable=arguments-differ + def names(all=False): # pylint:disable=redefined-builtin + """Get the interface attribute names + + Return a collection of the names of the attributes, including + methods, included in the interface definition. + + Normally, only directly defined attributes are included. If + a true positional or keyword argument is given, then + attributes defined by base classes will be included. + """ + + def namesAndDescriptions(all=False): # pylint:disable=redefined-builtin + """Get the interface attribute names and descriptions + + Return a collection of the names and descriptions of the + attributes, including methods, as name-value pairs, included + in the interface definition. + + Normally, only directly defined attributes are included. If + a true positional or keyword argument is given, then + attributes defined by base classes will be included. + """ + + def __getitem__(name): + """Get the description for a name + + If the named attribute is not defined, a `KeyError` is raised. + """ + + def direct(name): + """Get the description for the name if it was defined by the interface + + If the interface doesn't define the name, returns None. + """ + + def validateInvariants(obj, errors=None): + """Validate invariants + + Validate object to defined invariants. If errors is None, + raises first Invalid error; if errors is a list, appends all errors + to list, then raises Invalid with the errors as the first element + of the "args" tuple.""" + + def __contains__(name): + """Test whether the name is defined by the interface""" + + def __iter__(): + """Return an iterator over the names defined by the interface + + The names iterated include all of the names defined by the + interface directly and indirectly by base interfaces. + """ + + __module__ = Attribute("""The name of the module defining the interface""") + + +class IDeclaration(ISpecification): + """Interface declaration + + Declarations are used to express the interfaces implemented by + classes or provided by objects. + """ + + def __contains__(interface): + """Test whether an interface is in the specification + + Return true if the given interface is one of the interfaces in + the specification and false otherwise. + """ + + def __iter__(): + """Return an iterator for the interfaces in the specification + """ + + def flattened(): + """Return an iterator of all included and extended interfaces + + An iterator is returned for all interfaces either included in + or extended by interfaces included in the specifications + without duplicates. The interfaces are in "interface + resolution order". The interface resolution order is such that + base interfaces are listed after interfaces that extend them + and, otherwise, interfaces are included in the order that they + were defined in the specification. + """ + + def __sub__(interfaces): + """Create an interface specification with some interfaces excluded + + The argument can be an interface or an interface + specifications. The interface or interfaces given in a + specification are subtracted from the interface specification. + + Removing an interface that is not in the specification does + not raise an error. Doing so has no effect. + + Removing an interface also removes sub-interfaces of the interface. + + """ + + def __add__(interfaces): + """Create an interface specification with some interfaces added + + The argument can be an interface or an interface + specifications. The interface or interfaces given in a + specification are added to the interface specification. + + Adding an interface that is already in the specification does + not raise an error. Doing so has no effect. + """ + + def __nonzero__(): + """Return a true value of the interface specification is non-empty + """ + +class IInterfaceDeclaration(Interface): + """ + Declare and check the interfaces of objects. + + The functions defined in this interface are used to declare the + interfaces that objects provide and to query the interfaces that + have been declared. + + Interfaces can be declared for objects in two ways: + + - Interfaces are declared for instances of the object's class + + - Interfaces are declared for the object directly. + + The interfaces declared for an object are, therefore, the union of + interfaces declared for the object directly and the interfaces + declared for instances of the object's class. + + Note that we say that a class implements the interfaces provided + by it's instances. An instance can also provide interfaces + directly. The interfaces provided by an object are the union of + the interfaces provided directly and the interfaces implemented by + the class. + + This interface is implemented by :mod:`zope.interface`. + """ + # pylint:disable=arguments-differ + ### + # Defining interfaces + ### + + Interface = Attribute("The base class used to create new interfaces") + + def taggedValue(key, value): + """ + Attach a tagged value to an interface while defining the interface. + + This is a way of executing :meth:`IElement.setTaggedValue` from + the definition of the interface. For example:: + + class IFoo(Interface): + taggedValue('key', 'value') + + .. seealso:: `zope.interface.taggedValue` + """ + + def invariant(checker_function): + """ + Attach an invariant checker function to an interface while defining it. + + Invariants can later be validated against particular implementations by + calling :meth:`IInterface.validateInvariants`. + + For example:: + + def check_range(ob): + if ob.max < ob.min: + raise ValueError("max value is less than min value") + + class IRange(Interface): + min = Attribute("The min value") + max = Attribute("The max value") + + invariant(check_range) + + .. seealso:: `zope.interface.invariant` + """ + + def interfacemethod(method): + """ + A decorator that transforms a method specification into an + implementation method. + + This is used to override methods of ``Interface`` or provide new methods. + Definitions using this decorator will not appear in :meth:`IInterface.names()`. + It is possible to have an implementation method and a method specification + of the same name. + + For example:: + + class IRange(Interface): + @interfacemethod + def __adapt__(self, obj): + if isinstance(obj, range): + # Return the builtin ``range`` as-is + return obj + return super(type(IRange), self).__adapt__(obj) + + You can use ``super`` to call the parent class functionality. Note that + the zero-argument version (``super().__adapt__``) works on Python 3.6 and above, but + prior to that the two-argument version must be used, and the class must be explicitly + passed as the first argument. + + .. versionadded:: 5.1.0 + .. seealso:: `zope.interface.interfacemethod` + """ + + ### + # Querying interfaces + ### + + def providedBy(ob): + """ + Return the interfaces provided by an object. + + This is the union of the interfaces directly provided by an + object and interfaces implemented by it's class. + + The value returned is an `IDeclaration`. + + .. seealso:: `zope.interface.providedBy` + """ + + def implementedBy(class_): + """ + Return the interfaces implemented for a class's instances. + + The value returned is an `IDeclaration`. + + .. seealso:: `zope.interface.implementedBy` + """ + + ### + # Declaring interfaces + ### + + def classImplements(class_, *interfaces): + """ + Declare additional interfaces implemented for instances of a class. + + The arguments after the class are one or more interfaces or + interface specifications (`IDeclaration` objects). + + The interfaces given (including the interfaces in the + specifications) are added to any interfaces previously + declared. + + Consider the following example:: + + class C(A, B): + ... + + classImplements(C, I1, I2) + + + Instances of ``C`` provide ``I1``, ``I2``, and whatever interfaces + instances of ``A`` and ``B`` provide. This is equivalent to:: + + @implementer(I1, I2) + class C(A, B): + pass + + .. seealso:: `zope.interface.classImplements` + .. seealso:: `zope.interface.implementer` + """ + + def classImplementsFirst(cls, interface): + """ + See :func:`zope.interface.classImplementsFirst`. + """ + + def implementer(*interfaces): + """ + Create a decorator for declaring interfaces implemented by a + factory. + + A callable is returned that makes an implements declaration on + objects passed to it. + + .. seealso:: :meth:`classImplements` + """ + + def classImplementsOnly(class_, *interfaces): + """ + Declare the only interfaces implemented by instances of a class. + + The arguments after the class are one or more interfaces or + interface specifications (`IDeclaration` objects). + + The interfaces given (including the interfaces in the + specifications) replace any previous declarations. + + Consider the following example:: + + class C(A, B): + ... + + classImplements(C, IA, IB. IC) + classImplementsOnly(C. I1, I2) + + Instances of ``C`` provide only ``I1``, ``I2``, and regardless of + whatever interfaces instances of ``A`` and ``B`` implement. + + .. seealso:: `zope.interface.classImplementsOnly` + """ + + def implementer_only(*interfaces): + """ + Create a decorator for declaring the only interfaces implemented. + + A callable is returned that makes an implements declaration on + objects passed to it. + + .. seealso:: `zope.interface.implementer_only` + """ + + def directlyProvidedBy(object): # pylint:disable=redefined-builtin + """ + Return the interfaces directly provided by the given object. + + The value returned is an `IDeclaration`. + + .. seealso:: `zope.interface.directlyProvidedBy` + """ + + def directlyProvides(object, *interfaces): # pylint:disable=redefined-builtin + """ + Declare interfaces declared directly for an object. + + The arguments after the object are one or more interfaces or + interface specifications (`IDeclaration` objects). + + .. caution:: + The interfaces given (including the interfaces in the + specifications) *replace* interfaces previously + declared for the object. See :meth:`alsoProvides` to add + additional interfaces. + + Consider the following example:: + + class C(A, B): + ... + + ob = C() + directlyProvides(ob, I1, I2) + + The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces + instances have been declared for instances of ``C``. + + To remove directly provided interfaces, use `directlyProvidedBy` and + subtract the unwanted interfaces. For example:: + + directlyProvides(ob, directlyProvidedBy(ob)-I2) + + removes I2 from the interfaces directly provided by + ``ob``. The object, ``ob`` no longer directly provides ``I2``, + although it might still provide ``I2`` if it's class + implements ``I2``. + + To add directly provided interfaces, use `directlyProvidedBy` and + include additional interfaces. For example:: + + directlyProvides(ob, directlyProvidedBy(ob), I2) + + adds I2 to the interfaces directly provided by ob. + + .. seealso:: `zope.interface.directlyProvides` + """ + + def alsoProvides(object, *interfaces): # pylint:disable=redefined-builtin + """ + Declare additional interfaces directly for an object. + + For example:: + + alsoProvides(ob, I1) + + is equivalent to:: + + directlyProvides(ob, directlyProvidedBy(ob), I1) + + .. seealso:: `zope.interface.alsoProvides` + """ + + def noLongerProvides(object, interface): # pylint:disable=redefined-builtin + """ + Remove an interface from the list of an object's directly provided + interfaces. + + For example:: + + noLongerProvides(ob, I1) + + is equivalent to:: + + directlyProvides(ob, directlyProvidedBy(ob) - I1) + + with the exception that if ``I1`` is an interface that is + provided by ``ob`` through the class's implementation, + `ValueError` is raised. + + .. seealso:: `zope.interface.noLongerProvides` + """ + + def provider(*interfaces): + """ + Declare interfaces provided directly by a class. + + .. seealso:: `zope.interface.provider` + """ + + def moduleProvides(*interfaces): + """ + Declare interfaces provided by a module. + + This function is used in a module definition. + + The arguments are one or more interfaces or interface + specifications (`IDeclaration` objects). + + The given interfaces (including the interfaces in the + specifications) are used to create the module's direct-object + interface specification. An error will be raised if the module + already has an interface specification. In other words, it is + an error to call this function more than once in a module + definition. + + This function is provided for convenience. It provides a more + convenient way to call `directlyProvides` for a module. For example:: + + moduleImplements(I1) + + is equivalent to:: + + directlyProvides(sys.modules[__name__], I1) + + .. seealso:: `zope.interface.moduleProvides` + """ + + def Declaration(*interfaces): + """ + Create an interface specification. + + The arguments are one or more interfaces or interface + specifications (`IDeclaration` objects). + + A new interface specification (`IDeclaration`) with the given + interfaces is returned. + + .. seealso:: `zope.interface.Declaration` + """ + +class IAdapterRegistry(Interface): + """Provide an interface-based registry for adapters + + This registry registers objects that are in some sense "from" a + sequence of specification to an interface and a name. + + No specific semantics are assumed for the registered objects, + however, the most common application will be to register factories + that adapt objects providing required specifications to a provided + interface. + """ + + def register(required, provided, name, value): + """Register a value + + A value is registered for a *sequence* of required specifications, a + provided interface, and a name, which must be text. + """ + + def registered(required, provided, name=''): + """Return the component registered for the given interfaces and name + + name must be text. + + Unlike the lookup method, this methods won't retrieve + components registered for more specific required interfaces or + less specific provided interfaces. + + If no component was registered exactly for the given + interfaces and name, then None is returned. + + """ + + def lookup(required, provided, name='', default=None): + """Lookup a value + + A value is looked up based on a *sequence* of required + specifications, a provided interface, and a name, which must be + text. + """ + + def queryMultiAdapter(objects, provided, name='', default=None): + """Adapt a sequence of objects to a named, provided, interface + """ + + def lookup1(required, provided, name='', default=None): + """Lookup a value using a single required interface + + A value is looked up based on a single required + specifications, a provided interface, and a name, which must be + text. + """ + + def queryAdapter(object, provided, name='', default=None): # pylint:disable=redefined-builtin + """Adapt an object using a registered adapter factory. + """ + + def adapter_hook(provided, object, name='', default=None): # pylint:disable=redefined-builtin + """Adapt an object using a registered adapter factory. + + name must be text. + """ + + def lookupAll(required, provided): + """Find all adapters from the required to the provided interfaces + + An iterable object is returned that provides name-value two-tuples. + """ + + def names(required, provided): # pylint:disable=arguments-differ + """Return the names for which there are registered objects + """ + + def subscribe(required, provided, subscriber): # pylint:disable=arguments-differ + """Register a subscriber + + A subscriber is registered for a *sequence* of required + specifications, a provided interface, and a name. + + Multiple subscribers may be registered for the same (or + equivalent) interfaces. + + .. versionchanged:: 5.1.1 + Correct the method signature to remove the ``name`` parameter. + Subscribers have no names. + """ + + def subscribed(required, provided, subscriber): + """ + Check whether the object *subscriber* is registered directly + with this object via a previous call to + ``subscribe(required, provided, subscriber)``. + + If the *subscriber*, or one equal to it, has been subscribed, + for the given *required* sequence and *provided* interface, + return that object. (This does not guarantee whether the *subscriber* + itself is returned, or an object equal to it.) + + If it has not, return ``None``. + + Unlike :meth:`subscriptions`, this method won't retrieve + components registered for more specific required interfaces or + less specific provided interfaces. + + .. versionadded:: 5.3.0 + """ + + def subscriptions(required, provided): + """ + Get a sequence of subscribers. + + Subscribers for a sequence of *required* interfaces, and a *provided* + interface are returned. This takes into account subscribers + registered with this object, as well as those registered with + base adapter registries in the resolution order, and interfaces that + extend *provided*. + + .. versionchanged:: 5.1.1 + Correct the method signature to remove the ``name`` parameter. + Subscribers have no names. + """ + + def subscribers(objects, provided): + """ + Get a sequence of subscription **adapters**. + + This is like :meth:`subscriptions`, but calls the returned + subscribers with *objects* (and optionally returns the results + of those calls), instead of returning the subscribers directly. + + :param objects: A sequence of objects; they will be used to + determine the *required* argument to :meth:`subscriptions`. + :param provided: A single interface, or ``None``, to pass + as the *provided* parameter to :meth:`subscriptions`. + If an interface is given, the results of calling each returned + subscriber with the the *objects* are collected and returned + from this method; each result should be an object implementing + the *provided* interface. If ``None``, the resulting subscribers + are still called, but the results are ignored. + :return: A sequence of the results of calling the subscribers + if *provided* is not ``None``. If there are no registered + subscribers, or *provided* is ``None``, this will be an empty + sequence. + + .. versionchanged:: 5.1.1 + Correct the method signature to remove the ``name`` parameter. + Subscribers have no names. + """ + +# begin formerly in zope.component + +class ComponentLookupError(LookupError): + """A component could not be found.""" + +class Invalid(Exception): + """A component doesn't satisfy a promise.""" + +class IObjectEvent(Interface): + """An event related to an object. + + The object that generated this event is not necessarily the object + referred to by location. + """ + + object = Attribute("The subject of the event.") + + +@implementer(IObjectEvent) +class ObjectEvent: + + def __init__(self, object): # pylint:disable=redefined-builtin + self.object = object + + +class IComponentLookup(Interface): + """Component Manager for a Site + + This object manages the components registered at a particular site. The + definition of a site is intentionally vague. + """ + + adapters = Attribute( + "Adapter Registry to manage all registered adapters.") + + utilities = Attribute( + "Adapter Registry to manage all registered utilities.") + + def queryAdapter(object, interface, name='', default=None): # pylint:disable=redefined-builtin + """Look for a named adapter to an interface for an object + + If a matching adapter cannot be found, returns the default. + """ + + def getAdapter(object, interface, name=''): # pylint:disable=redefined-builtin + """Look for a named adapter to an interface for an object + + If a matching adapter cannot be found, a `ComponentLookupError` + is raised. + """ + + def queryMultiAdapter(objects, interface, name='', default=None): + """Look for a multi-adapter to an interface for multiple objects + + If a matching adapter cannot be found, returns the default. + """ + + def getMultiAdapter(objects, interface, name=''): + """Look for a multi-adapter to an interface for multiple objects + + If a matching adapter cannot be found, a `ComponentLookupError` + is raised. + """ + + def getAdapters(objects, provided): + """Look for all matching adapters to a provided interface for objects + + Return an iterable of name-adapter pairs for adapters that + provide the given interface. + """ + + def subscribers(objects, provided): + """Get subscribers + + Subscribers are returned that provide the provided interface + and that depend on and are computed from the sequence of + required objects. + """ + + def handle(*objects): + """Call handlers for the given objects + + Handlers registered for the given objects are called. + """ + + def queryUtility(interface, name='', default=None): + """Look up a utility that provides an interface. + + If one is not found, returns default. + """ + + def getUtilitiesFor(interface): + """Look up the registered utilities that provide an interface. + + Returns an iterable of name-utility pairs. + """ + + def getAllUtilitiesRegisteredFor(interface): + """Return all registered utilities for an interface + + This includes overridden utilities. + + An iterable of utility instances is returned. No names are + returned. + """ + +class IRegistration(Interface): + """A registration-information object + """ + + registry = Attribute("The registry having the registration") + + name = Attribute("The registration name") + + info = Attribute("""Information about the registration + + This is information deemed useful to people browsing the + configuration of a system. It could, for example, include + commentary or information about the source of the configuration. + """) + +class IUtilityRegistration(IRegistration): + """Information about the registration of a utility + """ + + factory = Attribute("The factory used to create the utility. Optional.") + component = Attribute("The object registered") + provided = Attribute("The interface provided by the component") + +class _IBaseAdapterRegistration(IRegistration): + """Information about the registration of an adapter + """ + + factory = Attribute("The factory used to create adapters") + + required = Attribute("""The adapted interfaces + + This is a sequence of interfaces adapters by the registered + factory. The factory will be caled with a sequence of objects, as + positional arguments, that provide these interfaces. + """) + + provided = Attribute("""The interface provided by the adapters. + + This interface is implemented by the factory + """) + +class IAdapterRegistration(_IBaseAdapterRegistration): + """Information about the registration of an adapter + """ + +class ISubscriptionAdapterRegistration(_IBaseAdapterRegistration): + """Information about the registration of a subscription adapter + """ + +class IHandlerRegistration(IRegistration): + + handler = Attribute("An object called used to handle an event") + + required = Attribute("""The handled interfaces + + This is a sequence of interfaces handled by the registered + handler. The handler will be caled with a sequence of objects, as + positional arguments, that provide these interfaces. + """) + +class IRegistrationEvent(IObjectEvent): + """An event that involves a registration""" + + +@implementer(IRegistrationEvent) +class RegistrationEvent(ObjectEvent): + """There has been a change in a registration + """ + def __repr__(self): + return "{} event:\n{!r}".format(self.__class__.__name__, self.object) + +class IRegistered(IRegistrationEvent): + """A component or factory was registered + """ + +@implementer(IRegistered) +class Registered(RegistrationEvent): + pass + +class IUnregistered(IRegistrationEvent): + """A component or factory was unregistered + """ + +@implementer(IUnregistered) +class Unregistered(RegistrationEvent): + """A component or factory was unregistered + """ + + +class IComponentRegistry(Interface): + """Register components + """ + + def registerUtility(component=None, provided=None, name='', + info='', factory=None): + """Register a utility + + :param factory: + Factory for the component to be registered. + + :param component: + The registered component + + :param provided: + This is the interface provided by the utility. If the + component provides a single interface, then this + argument is optional and the component-implemented + interface will be used. + + :param name: + The utility name. + + :param info: + An object that can be converted to a string to provide + information about the registration. + + Only one of *component* and *factory* can be used. + + A `IRegistered` event is generated with an `IUtilityRegistration`. + """ + + def unregisterUtility(component=None, provided=None, name='', + factory=None): + """Unregister a utility + + :returns: + A boolean is returned indicating whether the registry was + changed. If the given *component* is None and there is no + component registered, or if the given *component* is not + None and is not registered, then the function returns + False, otherwise it returns True. + + :param factory: + Factory for the component to be unregistered. + + :param component: + The registered component The given component can be + None, in which case any component registered to provide + the given provided interface with the given name is + unregistered. + + :param provided: + This is the interface provided by the utility. If the + component is not None and provides a single interface, + then this argument is optional and the + component-implemented interface will be used. + + :param name: + The utility name. + + Only one of *component* and *factory* can be used. + An `IUnregistered` event is generated with an `IUtilityRegistration`. + """ + + def registeredUtilities(): + """Return an iterable of `IUtilityRegistration` instances. + + These registrations describe the current utility registrations + in the object. + """ + + def registerAdapter(factory, required=None, provided=None, name='', + info=''): + """Register an adapter factory + + :param factory: + The object used to compute the adapter + + :param required: + This is a sequence of specifications for objects to be + adapted. If omitted, then the value of the factory's + ``__component_adapts__`` attribute will be used. The + ``__component_adapts__`` attribute is + normally set in class definitions using + the `.adapter` + decorator. If the factory doesn't have a + ``__component_adapts__`` adapts attribute, then this + argument is required. + + :param provided: + This is the interface provided by the adapter and + implemented by the factory. If the factory + implements a single interface, then this argument is + optional and the factory-implemented interface will be + used. + + :param name: + The adapter name. + + :param info: + An object that can be converted to a string to provide + information about the registration. + + A `IRegistered` event is generated with an `IAdapterRegistration`. + """ + + def unregisterAdapter(factory=None, required=None, + provided=None, name=''): + """Unregister an adapter factory + + :returns: + A boolean is returned indicating whether the registry was + changed. If the given component is None and there is no + component registered, or if the given component is not + None and is not registered, then the function returns + False, otherwise it returns True. + + :param factory: + This is the object used to compute the adapter. The + factory can be None, in which case any factory + registered to implement the given provided interface + for the given required specifications with the given + name is unregistered. + + :param required: + This is a sequence of specifications for objects to be + adapted. If the factory is not None and the required + arguments is omitted, then the value of the factory's + __component_adapts__ attribute will be used. The + __component_adapts__ attribute attribute is normally + set in class definitions using adapts function, or for + callables using the adapter decorator. If the factory + is None or doesn't have a __component_adapts__ adapts + attribute, then this argument is required. + + :param provided: + This is the interface provided by the adapter and + implemented by the factory. If the factory is not + None and implements a single interface, then this + argument is optional and the factory-implemented + interface will be used. + + :param name: + The adapter name. + + An `IUnregistered` event is generated with an `IAdapterRegistration`. + """ + + def registeredAdapters(): + """Return an iterable of `IAdapterRegistration` instances. + + These registrations describe the current adapter registrations + in the object. + """ + + def registerSubscriptionAdapter(factory, required=None, provides=None, + name='', info=''): + """Register a subscriber factory + + :param factory: + The object used to compute the adapter + + :param required: + This is a sequence of specifications for objects to be + adapted. If omitted, then the value of the factory's + ``__component_adapts__`` attribute will be used. The + ``__component_adapts__`` attribute is + normally set using the adapter + decorator. If the factory doesn't have a + ``__component_adapts__`` adapts attribute, then this + argument is required. + + :param provided: + This is the interface provided by the adapter and + implemented by the factory. If the factory implements + a single interface, then this argument is optional and + the factory-implemented interface will be used. + + :param name: + The adapter name. + + Currently, only the empty string is accepted. Other + strings will be accepted in the future when support for + named subscribers is added. + + :param info: + An object that can be converted to a string to provide + information about the registration. + + A `IRegistered` event is generated with an + `ISubscriptionAdapterRegistration`. + """ + + def unregisterSubscriptionAdapter(factory=None, required=None, + provides=None, name=''): + """Unregister a subscriber factory. + + :returns: + A boolean is returned indicating whether the registry was + changed. If the given component is None and there is no + component registered, or if the given component is not + None and is not registered, then the function returns + False, otherwise it returns True. + + :param factory: + This is the object used to compute the adapter. The + factory can be None, in which case any factories + registered to implement the given provided interface + for the given required specifications with the given + name are unregistered. + + :param required: + This is a sequence of specifications for objects to be + adapted. If omitted, then the value of the factory's + ``__component_adapts__`` attribute will be used. The + ``__component_adapts__`` attribute is + normally set using the adapter + decorator. If the factory doesn't have a + ``__component_adapts__`` adapts attribute, then this + argument is required. + + :param provided: + This is the interface provided by the adapter and + implemented by the factory. If the factory is not + None implements a single interface, then this argument + is optional and the factory-implemented interface will + be used. + + :param name: + The adapter name. + + Currently, only the empty string is accepted. Other + strings will be accepted in the future when support for + named subscribers is added. + + An `IUnregistered` event is generated with an + `ISubscriptionAdapterRegistration`. + """ + + def registeredSubscriptionAdapters(): + """Return an iterable of `ISubscriptionAdapterRegistration` instances. + + These registrations describe the current subscription adapter + registrations in the object. + """ + + def registerHandler(handler, required=None, name='', info=''): + """Register a handler. + + A handler is a subscriber that doesn't compute an adapter + but performs some function when called. + + :param handler: + The object used to handle some event represented by + the objects passed to it. + + :param required: + This is a sequence of specifications for objects to be + adapted. If omitted, then the value of the factory's + ``__component_adapts__`` attribute will be used. The + ``__component_adapts__`` attribute is + normally set using the adapter + decorator. If the factory doesn't have a + ``__component_adapts__`` adapts attribute, then this + argument is required. + + :param name: + The handler name. + + Currently, only the empty string is accepted. Other + strings will be accepted in the future when support for + named handlers is added. + + :param info: + An object that can be converted to a string to provide + information about the registration. + + + A `IRegistered` event is generated with an `IHandlerRegistration`. + """ + + def unregisterHandler(handler=None, required=None, name=''): + """Unregister a handler. + + A handler is a subscriber that doesn't compute an adapter + but performs some function when called. + + :returns: A boolean is returned indicating whether the registry was + changed. + + :param handler: + This is the object used to handle some event + represented by the objects passed to it. The handler + can be None, in which case any handlers registered for + the given required specifications with the given are + unregistered. + + :param required: + This is a sequence of specifications for objects to be + adapted. If omitted, then the value of the factory's + ``__component_adapts__`` attribute will be used. The + ``__component_adapts__`` attribute is + normally set using the adapter + decorator. If the factory doesn't have a + ``__component_adapts__`` adapts attribute, then this + argument is required. + + :param name: + The handler name. + + Currently, only the empty string is accepted. Other + strings will be accepted in the future when support for + named handlers is added. + + An `IUnregistered` event is generated with an `IHandlerRegistration`. + """ + + def registeredHandlers(): + """Return an iterable of `IHandlerRegistration` instances. + + These registrations describe the current handler registrations + in the object. + """ + + +class IComponents(IComponentLookup, IComponentRegistry): + """Component registration and access + """ + + +# end formerly in zope.component diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/registry.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/registry.py new file mode 100644 index 00000000..292499db --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/registry.py @@ -0,0 +1,723 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Basic components support +""" +from collections import defaultdict + +try: + from zope.event import notify +except ImportError: # pragma: no cover + def notify(*arg, **kw): pass + +from zope.interface.interfaces import ISpecification +from zope.interface.interfaces import ComponentLookupError +from zope.interface.interfaces import IAdapterRegistration +from zope.interface.interfaces import IComponents +from zope.interface.interfaces import IHandlerRegistration +from zope.interface.interfaces import ISubscriptionAdapterRegistration +from zope.interface.interfaces import IUtilityRegistration +from zope.interface.interfaces import Registered +from zope.interface.interfaces import Unregistered + +from zope.interface.interface import Interface +from zope.interface.declarations import implementedBy +from zope.interface.declarations import implementer +from zope.interface.declarations import implementer_only +from zope.interface.declarations import providedBy +from zope.interface.adapter import AdapterRegistry + +__all__ = [ + # Components is public API, but + # the *Registration classes are just implementations + # of public interfaces. + 'Components', +] + +class _UnhashableComponentCounter: + # defaultdict(int)-like object for unhashable components + + def __init__(self, otherdict): + # [(component, count)] + self._data = [item for item in otherdict.items()] + + def __getitem__(self, key): + for component, count in self._data: + if component == key: + return count + return 0 + + def __setitem__(self, component, count): + for i, data in enumerate(self._data): + if data[0] == component: + self._data[i] = component, count + return + self._data.append((component, count)) + + def __delitem__(self, component): + for i, data in enumerate(self._data): + if data[0] == component: + del self._data[i] + return + raise KeyError(component) # pragma: no cover + +def _defaultdict_int(): + return defaultdict(int) + +class _UtilityRegistrations: + + def __init__(self, utilities, utility_registrations): + # {provided -> {component: count}} + self._cache = defaultdict(_defaultdict_int) + self._utilities = utilities + self._utility_registrations = utility_registrations + + self.__populate_cache() + + def __populate_cache(self): + for ((p, _), data) in iter(self._utility_registrations.items()): + component = data[0] + self.__cache_utility(p, component) + + def __cache_utility(self, provided, component): + try: + self._cache[provided][component] += 1 + except TypeError: + # The component is not hashable, and we have a dict. Switch to a strategy + # that doesn't use hashing. + prov = self._cache[provided] = _UnhashableComponentCounter(self._cache[provided]) + prov[component] += 1 + + def __uncache_utility(self, provided, component): + provided = self._cache[provided] + # It seems like this line could raise a TypeError if component isn't + # hashable and we haven't yet switched to _UnhashableComponentCounter. However, + # we can't actually get in that situation. In order to get here, we would + # have had to cache the utility already which would have switched + # the datastructure if needed. + count = provided[component] + count -= 1 + if count == 0: + del provided[component] + else: + provided[component] = count + return count > 0 + + def _is_utility_subscribed(self, provided, component): + try: + return self._cache[provided][component] > 0 + except TypeError: + # Not hashable and we're still using a dict + return False + + def registerUtility(self, provided, name, component, info, factory): + subscribed = self._is_utility_subscribed(provided, component) + + self._utility_registrations[(provided, name)] = component, info, factory + self._utilities.register((), provided, name, component) + + if not subscribed: + self._utilities.subscribe((), provided, component) + + self.__cache_utility(provided, component) + + def unregisterUtility(self, provided, name, component): + del self._utility_registrations[(provided, name)] + self._utilities.unregister((), provided, name) + + subscribed = self.__uncache_utility(provided, component) + + if not subscribed: + self._utilities.unsubscribe((), provided, component) + + +@implementer(IComponents) +class Components: + + _v_utility_registrations_cache = None + + def __init__(self, name='', bases=()): + # __init__ is used for test cleanup as well as initialization. + # XXX add a separate API for test cleanup. + assert isinstance(name, str) + self.__name__ = name + self._init_registries() + self._init_registrations() + self.__bases__ = tuple(bases) + self._v_utility_registrations_cache = None + + def __repr__(self): + return "<{} {}>".format(self.__class__.__name__, self.__name__) + + def __reduce__(self): + # Mimic what a persistent.Persistent object does and elide + # _v_ attributes so that they don't get saved in ZODB. + # This allows us to store things that cannot be pickled in such + # attributes. + reduction = super().__reduce__() + # (callable, args, state, listiter, dictiter) + # We assume the state is always a dict; the last three items + # are technically optional and can be missing or None. + filtered_state = {k: v for k, v in reduction[2].items() + if not k.startswith('_v_')} + reduction = list(reduction) + reduction[2] = filtered_state + return tuple(reduction) + + def _init_registries(self): + # Subclasses have never been required to call this method + # if they override it, merely to fill in these two attributes. + self.adapters = AdapterRegistry() + self.utilities = AdapterRegistry() + + def _init_registrations(self): + self._utility_registrations = {} + self._adapter_registrations = {} + self._subscription_registrations = [] + self._handler_registrations = [] + + @property + def _utility_registrations_cache(self): + # We use a _v_ attribute internally so that data aren't saved in ZODB, + # because this object cannot be pickled. + cache = self._v_utility_registrations_cache + if (cache is None + or cache._utilities is not self.utilities + or cache._utility_registrations is not self._utility_registrations): + cache = self._v_utility_registrations_cache = _UtilityRegistrations( + self.utilities, + self._utility_registrations) + return cache + + def _getBases(self): + # Subclasses might override + return self.__dict__.get('__bases__', ()) + + def _setBases(self, bases): + # Subclasses might override + self.adapters.__bases__ = tuple([ + base.adapters for base in bases]) + self.utilities.__bases__ = tuple([ + base.utilities for base in bases]) + self.__dict__['__bases__'] = tuple(bases) + + __bases__ = property( + lambda self: self._getBases(), + lambda self, bases: self._setBases(bases), + ) + + def registerUtility(self, component=None, provided=None, name='', + info='', event=True, factory=None): + if factory: + if component: + raise TypeError("Can't specify factory and component.") + component = factory() + + if provided is None: + provided = _getUtilityProvided(component) + + if name == '': + name = _getName(component) + + reg = self._utility_registrations.get((provided, name)) + if reg is not None: + if reg[:2] == (component, info): + # already registered + return + self.unregisterUtility(reg[0], provided, name) + + self._utility_registrations_cache.registerUtility( + provided, name, component, info, factory) + + if event: + notify(Registered( + UtilityRegistration(self, provided, name, component, info, + factory) + )) + + def unregisterUtility(self, component=None, provided=None, name='', + factory=None): + if factory: + if component: + raise TypeError("Can't specify factory and component.") + component = factory() + + if provided is None: + if component is None: + raise TypeError("Must specify one of component, factory and " + "provided") + provided = _getUtilityProvided(component) + + old = self._utility_registrations.get((provided, name)) + if (old is None) or ((component is not None) and + (component != old[0])): + return False + + if component is None: + component = old[0] + + # Note that component is now the old thing registered + self._utility_registrations_cache.unregisterUtility( + provided, name, component) + + notify(Unregistered( + UtilityRegistration(self, provided, name, component, *old[1:]) + )) + + return True + + def registeredUtilities(self): + for ((provided, name), data + ) in iter(self._utility_registrations.items()): + yield UtilityRegistration(self, provided, name, *data) + + def queryUtility(self, provided, name='', default=None): + return self.utilities.lookup((), provided, name, default) + + def getUtility(self, provided, name=''): + utility = self.utilities.lookup((), provided, name) + if utility is None: + raise ComponentLookupError(provided, name) + return utility + + def getUtilitiesFor(self, interface): + yield from self.utilities.lookupAll((), interface) + + def getAllUtilitiesRegisteredFor(self, interface): + return self.utilities.subscriptions((), interface) + + def registerAdapter(self, factory, required=None, provided=None, + name='', info='', event=True): + if provided is None: + provided = _getAdapterProvided(factory) + required = _getAdapterRequired(factory, required) + if name == '': + name = _getName(factory) + self._adapter_registrations[(required, provided, name) + ] = factory, info + self.adapters.register(required, provided, name, factory) + + if event: + notify(Registered( + AdapterRegistration(self, required, provided, name, + factory, info) + )) + + + def unregisterAdapter(self, factory=None, + required=None, provided=None, name='', + ): + if provided is None: + if factory is None: + raise TypeError("Must specify one of factory and provided") + provided = _getAdapterProvided(factory) + + if (required is None) and (factory is None): + raise TypeError("Must specify one of factory and required") + + required = _getAdapterRequired(factory, required) + old = self._adapter_registrations.get((required, provided, name)) + if (old is None) or ((factory is not None) and + (factory != old[0])): + return False + + del self._adapter_registrations[(required, provided, name)] + self.adapters.unregister(required, provided, name) + + notify(Unregistered( + AdapterRegistration(self, required, provided, name, + *old) + )) + + return True + + def registeredAdapters(self): + for ((required, provided, name), (component, info) + ) in iter(self._adapter_registrations.items()): + yield AdapterRegistration(self, required, provided, name, + component, info) + + def queryAdapter(self, object, interface, name='', default=None): + return self.adapters.queryAdapter(object, interface, name, default) + + def getAdapter(self, object, interface, name=''): + adapter = self.adapters.queryAdapter(object, interface, name) + if adapter is None: + raise ComponentLookupError(object, interface, name) + return adapter + + def queryMultiAdapter(self, objects, interface, name='', + default=None): + return self.adapters.queryMultiAdapter( + objects, interface, name, default) + + def getMultiAdapter(self, objects, interface, name=''): + adapter = self.adapters.queryMultiAdapter(objects, interface, name) + if adapter is None: + raise ComponentLookupError(objects, interface, name) + return adapter + + def getAdapters(self, objects, provided): + for name, factory in self.adapters.lookupAll( + list(map(providedBy, objects)), + provided): + adapter = factory(*objects) + if adapter is not None: + yield name, adapter + + def registerSubscriptionAdapter(self, + factory, required=None, provided=None, + name='', info='', + event=True): + if name: + raise TypeError("Named subscribers are not yet supported") + if provided is None: + provided = _getAdapterProvided(factory) + required = _getAdapterRequired(factory, required) + self._subscription_registrations.append( + (required, provided, name, factory, info) + ) + self.adapters.subscribe(required, provided, factory) + + if event: + notify(Registered( + SubscriptionRegistration(self, required, provided, name, + factory, info) + )) + + def registeredSubscriptionAdapters(self): + for data in self._subscription_registrations: + yield SubscriptionRegistration(self, *data) + + def unregisterSubscriptionAdapter(self, factory=None, + required=None, provided=None, name='', + ): + if name: + raise TypeError("Named subscribers are not yet supported") + if provided is None: + if factory is None: + raise TypeError("Must specify one of factory and provided") + provided = _getAdapterProvided(factory) + + if (required is None) and (factory is None): + raise TypeError("Must specify one of factory and required") + + required = _getAdapterRequired(factory, required) + + if factory is None: + new = [(r, p, n, f, i) + for (r, p, n, f, i) + in self._subscription_registrations + if not (r == required and p == provided) + ] + else: + new = [(r, p, n, f, i) + for (r, p, n, f, i) + in self._subscription_registrations + if not (r == required and p == provided and f == factory) + ] + + if len(new) == len(self._subscription_registrations): + return False + + + self._subscription_registrations[:] = new + self.adapters.unsubscribe(required, provided, factory) + + notify(Unregistered( + SubscriptionRegistration(self, required, provided, name, + factory, '') + )) + + return True + + def subscribers(self, objects, provided): + return self.adapters.subscribers(objects, provided) + + def registerHandler(self, + factory, required=None, + name='', info='', + event=True): + if name: + raise TypeError("Named handlers are not yet supported") + required = _getAdapterRequired(factory, required) + self._handler_registrations.append( + (required, name, factory, info) + ) + self.adapters.subscribe(required, None, factory) + + if event: + notify(Registered( + HandlerRegistration(self, required, name, factory, info) + )) + + def registeredHandlers(self): + for data in self._handler_registrations: + yield HandlerRegistration(self, *data) + + def unregisterHandler(self, factory=None, required=None, name=''): + if name: + raise TypeError("Named subscribers are not yet supported") + + if (required is None) and (factory is None): + raise TypeError("Must specify one of factory and required") + + required = _getAdapterRequired(factory, required) + + if factory is None: + new = [(r, n, f, i) + for (r, n, f, i) + in self._handler_registrations + if r != required + ] + else: + new = [(r, n, f, i) + for (r, n, f, i) + in self._handler_registrations + if not (r == required and f == factory) + ] + + if len(new) == len(self._handler_registrations): + return False + + self._handler_registrations[:] = new + self.adapters.unsubscribe(required, None, factory) + + notify(Unregistered( + HandlerRegistration(self, required, name, factory, '') + )) + + return True + + def handle(self, *objects): + self.adapters.subscribers(objects, None) + + def rebuildUtilityRegistryFromLocalCache(self, rebuild=False): + """ + Emergency maintenance method to rebuild the ``.utilities`` + registry from the local copy maintained in this object, or + detect the need to do so. + + Most users will never need to call this, but it can be helpful + in the event of suspected corruption. + + By default, this method only checks for corruption. To make it + actually rebuild the registry, pass `True` for *rebuild*. + + :param bool rebuild: If set to `True` (not the default), + this method will actually register and subscribe utilities + in the registry as needed to synchronize with the local cache. + + :return: A dictionary that's meant as diagnostic data. The keys + and values may change over time. When called with a false *rebuild*, + the keys ``"needed_registered"`` and ``"needed_subscribed"`` will be + non-zero if any corruption was detected, but that will not be corrected. + + .. versionadded:: 5.3.0 + """ + regs = dict(self._utility_registrations) + utils = self.utilities + needed_registered = 0 + did_not_register = 0 + needed_subscribed = 0 + did_not_subscribe = 0 + + + # Avoid the expensive change process during this; we'll call + # it once at the end if needed. + assert 'changed' not in utils.__dict__ + utils.changed = lambda _: None + + if rebuild: + register = utils.register + subscribe = utils.subscribe + else: + register = subscribe = lambda *args: None + + try: + for (provided, name), (value, _info, _factory) in regs.items(): + if utils.registered((), provided, name) != value: + register((), provided, name, value) + needed_registered += 1 + else: + did_not_register += 1 + + if utils.subscribed((), provided, value) is None: + needed_subscribed += 1 + subscribe((), provided, value) + else: + did_not_subscribe += 1 + finally: + del utils.changed + if rebuild and (needed_subscribed or needed_registered): + utils.changed(utils) + + return { + 'needed_registered': needed_registered, + 'did_not_register': did_not_register, + 'needed_subscribed': needed_subscribed, + 'did_not_subscribe': did_not_subscribe + } + +def _getName(component): + try: + return component.__component_name__ + except AttributeError: + return '' + +def _getUtilityProvided(component): + provided = list(providedBy(component)) + if len(provided) == 1: + return provided[0] + raise TypeError( + "The utility doesn't provide a single interface " + "and no provided interface was specified.") + +def _getAdapterProvided(factory): + provided = list(implementedBy(factory)) + if len(provided) == 1: + return provided[0] + raise TypeError( + "The adapter factory doesn't implement a single interface " + "and no provided interface was specified.") + +def _getAdapterRequired(factory, required): + if required is None: + try: + required = factory.__component_adapts__ + except AttributeError: + raise TypeError( + "The adapter factory doesn't have a __component_adapts__ " + "attribute and no required specifications were specified" + ) + elif ISpecification.providedBy(required): + raise TypeError("the required argument should be a list of " + "interfaces, not a single interface") + + result = [] + for r in required: + if r is None: + r = Interface + elif not ISpecification.providedBy(r): + if isinstance(r, type): + r = implementedBy(r) + else: + raise TypeError("Required specification must be a " + "specification or class, not %r" % type(r) + ) + result.append(r) + return tuple(result) + + +@implementer(IUtilityRegistration) +class UtilityRegistration: + + def __init__(self, registry, provided, name, component, doc, factory=None): + (self.registry, self.provided, self.name, self.component, self.info, + self.factory + ) = registry, provided, name, component, doc, factory + + def __repr__(self): + return '{}({!r}, {}, {!r}, {}, {!r}, {!r})'.format( + self.__class__.__name__, + self.registry, + getattr(self.provided, '__name__', None), self.name, + getattr(self.component, '__name__', repr(self.component)), + self.factory, self.info, + ) + + def __hash__(self): + return id(self) + + def __eq__(self, other): + return repr(self) == repr(other) + + def __ne__(self, other): + return repr(self) != repr(other) + + def __lt__(self, other): + return repr(self) < repr(other) + + def __le__(self, other): + return repr(self) <= repr(other) + + def __gt__(self, other): + return repr(self) > repr(other) + + def __ge__(self, other): + return repr(self) >= repr(other) + +@implementer(IAdapterRegistration) +class AdapterRegistration: + + def __init__(self, registry, required, provided, name, component, doc): + (self.registry, self.required, self.provided, self.name, + self.factory, self.info + ) = registry, required, provided, name, component, doc + + def __repr__(self): + return '{}({!r}, {}, {}, {!r}, {}, {!r})'.format( + self.__class__.__name__, + self.registry, + '[' + ", ".join([r.__name__ for r in self.required]) + ']', + getattr(self.provided, '__name__', None), self.name, + getattr(self.factory, '__name__', repr(self.factory)), self.info, + ) + + def __hash__(self): + return id(self) + + def __eq__(self, other): + return repr(self) == repr(other) + + def __ne__(self, other): + return repr(self) != repr(other) + + def __lt__(self, other): + return repr(self) < repr(other) + + def __le__(self, other): + return repr(self) <= repr(other) + + def __gt__(self, other): + return repr(self) > repr(other) + + def __ge__(self, other): + return repr(self) >= repr(other) + +@implementer_only(ISubscriptionAdapterRegistration) +class SubscriptionRegistration(AdapterRegistration): + pass + + +@implementer_only(IHandlerRegistration) +class HandlerRegistration(AdapterRegistration): + + def __init__(self, registry, required, name, handler, doc): + (self.registry, self.required, self.name, self.handler, self.info + ) = registry, required, name, handler, doc + + @property + def factory(self): + return self.handler + + provided = None + + def __repr__(self): + return '{}({!r}, {}, {!r}, {}, {!r})'.format( + self.__class__.__name__, + self.registry, + '[' + ", ".join([r.__name__ for r in self.required]) + ']', + self.name, + getattr(self.factory, '__name__', repr(self.factory)), self.info, + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/ro.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/ro.py new file mode 100644 index 00000000..17468e92 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/ro.py @@ -0,0 +1,665 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" +Compute a resolution order for an object and its bases. + +.. versionchanged:: 5.0 + The resolution order is now based on the same C3 order that Python + uses for classes. In complex instances of multiple inheritance, this + may result in a different ordering. + + In older versions, the ordering wasn't required to be C3 compliant, + and for backwards compatibility, it still isn't. If the ordering + isn't C3 compliant (if it is *inconsistent*), zope.interface will + make a best guess to try to produce a reasonable resolution order. + Still (just as before), the results in such cases may be + surprising. + +.. rubric:: Environment Variables + +Due to the change in 5.0, certain environment variables can be used to control errors +and warnings about inconsistent resolution orders. They are listed in priority order, with +variables at the bottom generally overriding variables above them. + +ZOPE_INTERFACE_WARN_BAD_IRO + If this is set to "1", then if there is at least one inconsistent resolution + order discovered, a warning (:class:`InconsistentResolutionOrderWarning`) will + be issued. Use the usual warning mechanisms to control this behaviour. The warning + text will contain additional information on debugging. +ZOPE_INTERFACE_TRACK_BAD_IRO + If this is set to "1", then zope.interface will log information about each + inconsistent resolution order discovered, and keep those details in memory in this module + for later inspection. +ZOPE_INTERFACE_STRICT_IRO + If this is set to "1", any attempt to use :func:`ro` that would produce a non-C3 + ordering will fail by raising :class:`InconsistentResolutionOrderError`. + +.. important:: + + ``ZOPE_INTERFACE_STRICT_IRO`` is intended to become the default in the future. + +There are two environment variables that are independent. + +ZOPE_INTERFACE_LOG_CHANGED_IRO + If this is set to "1", then if the C3 resolution order is different from + the legacy resolution order for any given object, a message explaining the differences + will be logged. This is intended to be used for debugging complicated IROs. +ZOPE_INTERFACE_USE_LEGACY_IRO + If this is set to "1", then the C3 resolution order will *not* be used. The + legacy IRO will be used instead. This is a temporary measure and will be removed in the + future. It is intended to help during the transition. + It implies ``ZOPE_INTERFACE_LOG_CHANGED_IRO``. + +.. rubric:: Debugging Behaviour Changes in zope.interface 5 + +Most behaviour changes from zope.interface 4 to 5 are related to +inconsistent resolution orders. ``ZOPE_INTERFACE_STRICT_IRO`` is the +most effective tool to find such inconsistent resolution orders, and +we recommend running your code with this variable set if at all +possible. Doing so will ensure that all interface resolution orders +are consistent, and if they're not, will immediately point the way to +where this is violated. + +Occasionally, however, this may not be enough. This is because in some +cases, a C3 ordering can be found (the resolution order is fully +consistent) that is substantially different from the ad-hoc legacy +ordering. In such cases, you may find that you get an unexpected value +returned when adapting one or more objects to an interface. To debug +this, *also* enable ``ZOPE_INTERFACE_LOG_CHANGED_IRO`` and examine the +output. The main thing to look for is changes in the relative +positions of interfaces for which there are registered adapters. +""" +__docformat__ = 'restructuredtext' + +__all__ = [ + 'ro', + 'InconsistentResolutionOrderError', + 'InconsistentResolutionOrderWarning', +] + +__logger = None + +def _logger(): + global __logger # pylint:disable=global-statement + if __logger is None: + import logging + __logger = logging.getLogger(__name__) + return __logger + +def _legacy_mergeOrderings(orderings): + """Merge multiple orderings so that within-ordering order is preserved + + Orderings are constrained in such a way that if an object appears + in two or more orderings, then the suffix that begins with the + object must be in both orderings. + + For example: + + >>> _mergeOrderings([ + ... ['x', 'y', 'z'], + ... ['q', 'z'], + ... [1, 3, 5], + ... ['z'] + ... ]) + ['x', 'y', 'q', 1, 3, 5, 'z'] + + """ + + seen = set() + result = [] + for ordering in reversed(orderings): + for o in reversed(ordering): + if o not in seen: + seen.add(o) + result.insert(0, o) + + return result + +def _legacy_flatten(begin): + result = [begin] + i = 0 + for ob in iter(result): + i += 1 + # The recursive calls can be avoided by inserting the base classes + # into the dynamically growing list directly after the currently + # considered object; the iterator makes sure this will keep working + # in the future, since it cannot rely on the length of the list + # by definition. + result[i:i] = ob.__bases__ + return result + +def _legacy_ro(ob): + return _legacy_mergeOrderings([_legacy_flatten(ob)]) + +### +# Compare base objects using identity, not equality. This matches what +# the CPython MRO algorithm does, and is *much* faster to boot: that, +# plus some other small tweaks makes the difference between 25s and 6s +# in loading 446 plone/zope interface.py modules (1925 InterfaceClass, +# 1200 Implements, 1100 ClassProvides objects) +### + + +class InconsistentResolutionOrderWarning(PendingDeprecationWarning): + """ + The warning issued when an invalid IRO is requested. + """ + +class InconsistentResolutionOrderError(TypeError): + """ + The error raised when an invalid IRO is requested in strict mode. + """ + + def __init__(self, c3, base_tree_remaining): + self.C = c3.leaf + base_tree = c3.base_tree + self.base_ros = { + base: base_tree[i + 1] + for i, base in enumerate(self.C.__bases__) + } + # Unfortunately, this doesn't necessarily directly match + # up to any transformation on C.__bases__, because + # if any were fully used up, they were removed already. + self.base_tree_remaining = base_tree_remaining + + TypeError.__init__(self) + + def __str__(self): + import pprint + return "{}: For object {!r}.\nBase ROs:\n{}\nConflict Location:\n{}".format( + self.__class__.__name__, + self.C, + pprint.pformat(self.base_ros), + pprint.pformat(self.base_tree_remaining), + ) + + +class _NamedBool(int): # cannot actually inherit bool + + def __new__(cls, val, name): + inst = super(cls, _NamedBool).__new__(cls, val) + inst.__name__ = name + return inst + + +class _ClassBoolFromEnv: + """ + Non-data descriptor that reads a transformed environment variable + as a boolean, and caches the result in the class. + """ + + def __get__(self, inst, klass): + import os + for cls in klass.__mro__: + my_name = None + for k in dir(klass): + if k in cls.__dict__ and cls.__dict__[k] is self: + my_name = k + break + if my_name is not None: + break + else: # pragma: no cover + raise RuntimeError("Unable to find self") + + env_name = 'ZOPE_INTERFACE_' + my_name + val = os.environ.get(env_name, '') == '1' + val = _NamedBool(val, my_name) + setattr(klass, my_name, val) + setattr(klass, 'ORIG_' + my_name, self) + return val + + +class _StaticMRO: + # A previously resolved MRO, supplied by the caller. + # Used in place of calculating it. + + had_inconsistency = None # We don't know... + + def __init__(self, C, mro): + self.leaf = C + self.__mro = tuple(mro) + + def mro(self): + return list(self.__mro) + + +class C3: + # Holds the shared state during computation of an MRO. + + @staticmethod + def resolver(C, strict, base_mros): + strict = strict if strict is not None else C3.STRICT_IRO + factory = C3 + if strict: + factory = _StrictC3 + elif C3.TRACK_BAD_IRO: + factory = _TrackingC3 + + memo = {} + base_mros = base_mros or {} + for base, mro in base_mros.items(): + assert base in C.__bases__ + memo[base] = _StaticMRO(base, mro) + + return factory(C, memo) + + __mro = None + __legacy_ro = None + direct_inconsistency = False + + def __init__(self, C, memo): + self.leaf = C + self.memo = memo + kind = self.__class__ + + base_resolvers = [] + for base in C.__bases__: + if base not in memo: + resolver = kind(base, memo) + memo[base] = resolver + base_resolvers.append(memo[base]) + + self.base_tree = [ + [C] + ] + [ + memo[base].mro() for base in C.__bases__ + ] + [ + list(C.__bases__) + ] + + self.bases_had_inconsistency = any(base.had_inconsistency for base in base_resolvers) + + if len(C.__bases__) == 1: + self.__mro = [C] + memo[C.__bases__[0]].mro() + + @property + def had_inconsistency(self): + return self.direct_inconsistency or self.bases_had_inconsistency + + @property + def legacy_ro(self): + if self.__legacy_ro is None: + self.__legacy_ro = tuple(_legacy_ro(self.leaf)) + return list(self.__legacy_ro) + + TRACK_BAD_IRO = _ClassBoolFromEnv() + STRICT_IRO = _ClassBoolFromEnv() + WARN_BAD_IRO = _ClassBoolFromEnv() + LOG_CHANGED_IRO = _ClassBoolFromEnv() + USE_LEGACY_IRO = _ClassBoolFromEnv() + BAD_IROS = () + + def _warn_iro(self): + if not self.WARN_BAD_IRO: + # For the initial release, one must opt-in to see the warning. + # In the future (2021?) seeing at least the first warning will + # be the default + return + import warnings + warnings.warn( + "An inconsistent resolution order is being requested. " + "(Interfaces should follow the Python class rules known as C3.) " + "For backwards compatibility, zope.interface will allow this, " + "making the best guess it can to produce as meaningful an order as possible. " + "In the future this might be an error. Set the warning filter to error, or set " + "the environment variable 'ZOPE_INTERFACE_TRACK_BAD_IRO' to '1' and examine " + "ro.C3.BAD_IROS to debug, or set 'ZOPE_INTERFACE_STRICT_IRO' to raise exceptions.", + InconsistentResolutionOrderWarning, + ) + + @staticmethod + def _can_choose_base(base, base_tree_remaining): + # From C3: + # nothead = [s for s in nonemptyseqs if cand in s[1:]] + for bases in base_tree_remaining: + if not bases or bases[0] is base: + continue + + for b in bases: + if b is base: + return False + return True + + @staticmethod + def _nonempty_bases_ignoring(base_tree, ignoring): + return list(filter(None, [ + [b for b in bases if b is not ignoring] + for bases + in base_tree + ])) + + def _choose_next_base(self, base_tree_remaining): + """ + Return the next base. + + The return value will either fit the C3 constraints or be our best + guess about what to do. If we cannot guess, this may raise an exception. + """ + base = self._find_next_C3_base(base_tree_remaining) + if base is not None: + return base + return self._guess_next_base(base_tree_remaining) + + def _find_next_C3_base(self, base_tree_remaining): + """ + Return the next base that fits the constraints, or ``None`` if there isn't one. + """ + for bases in base_tree_remaining: + base = bases[0] + if self._can_choose_base(base, base_tree_remaining): + return base + return None + + class _UseLegacyRO(Exception): + pass + + def _guess_next_base(self, base_tree_remaining): + # Narf. We may have an inconsistent order (we won't know for + # sure until we check all the bases). Python cannot create + # classes like this: + # + # class B1: + # pass + # class B2(B1): + # pass + # class C(B1, B2): # -> TypeError; this is like saying C(B1, B2, B1). + # pass + # + # However, older versions of zope.interface were fine with this order. + # A good example is ``providedBy(IOError())``. Because of the way + # ``classImplements`` works, it winds up with ``__bases__`` == + # ``[IEnvironmentError, IIOError, IOSError, <implementedBy Exception>]`` + # (on Python 3). But ``IEnvironmentError`` is a base of both ``IIOError`` + # and ``IOSError``. Previously, we would get a resolution order of + # ``[IIOError, IOSError, IEnvironmentError, IStandardError, IException, Interface]`` + # but the standard Python algorithm would forbid creating that order entirely. + + # Unlike Python's MRO, we attempt to resolve the issue. A few + # heuristics have been tried. One was: + # + # Strip off the first (highest priority) base of each direct + # base one at a time and seeing if we can come to an agreement + # with the other bases. (We're trying for a partial ordering + # here.) This often resolves cases (such as the IOSError case + # above), and frequently produces the same ordering as the + # legacy MRO did. If we looked at all the highest priority + # bases and couldn't find any partial ordering, then we strip + # them *all* out and begin the C3 step again. We take care not + # to promote a common root over all others. + # + # If we only did the first part, stripped off the first + # element of the first item, we could resolve simple cases. + # But it tended to fail badly. If we did the whole thing, it + # could be extremely painful from a performance perspective + # for deep/wide things like Zope's OFS.SimpleItem.Item. Plus, + # anytime you get ExtensionClass.Base into the mix, you're + # likely to wind up in trouble, because it messes with the MRO + # of classes. Sigh. + # + # So now, we fall back to the old linearization (fast to compute). + self._warn_iro() + self.direct_inconsistency = InconsistentResolutionOrderError(self, base_tree_remaining) + raise self._UseLegacyRO + + def _merge(self): + # Returns a merged *list*. + result = self.__mro = [] + base_tree_remaining = self.base_tree + base = None + while 1: + # Take last picked base out of the base tree wherever it is. + # This differs slightly from the standard Python MRO and is needed + # because we have no other step that prevents duplicates + # from coming in (e.g., in the inconsistent fallback path) + base_tree_remaining = self._nonempty_bases_ignoring(base_tree_remaining, base) + + if not base_tree_remaining: + return result + try: + base = self._choose_next_base(base_tree_remaining) + except self._UseLegacyRO: + self.__mro = self.legacy_ro + return self.legacy_ro + + result.append(base) + + def mro(self): + if self.__mro is None: + self.__mro = tuple(self._merge()) + return list(self.__mro) + + +class _StrictC3(C3): + __slots__ = () + def _guess_next_base(self, base_tree_remaining): + raise InconsistentResolutionOrderError(self, base_tree_remaining) + + +class _TrackingC3(C3): + __slots__ = () + def _guess_next_base(self, base_tree_remaining): + import traceback + bad_iros = C3.BAD_IROS + if self.leaf not in bad_iros: + if bad_iros == (): + import weakref + # This is a race condition, but it doesn't matter much. + bad_iros = C3.BAD_IROS = weakref.WeakKeyDictionary() + bad_iros[self.leaf] = t = ( + InconsistentResolutionOrderError(self, base_tree_remaining), + traceback.format_stack() + ) + _logger().warning("Tracking inconsistent IRO: %s", t[0]) + return C3._guess_next_base(self, base_tree_remaining) + + +class _ROComparison: + # Exists to compute and print a pretty string comparison + # for differing ROs. + # Since we're used in a logging context, and may actually never be printed, + # this is a class so we can defer computing the diff until asked. + + # Components we use to build up the comparison report + class Item: + prefix = ' ' + def __init__(self, item): + self.item = item + def __str__(self): + return "{}{}".format( + self.prefix, + self.item, + ) + + class Deleted(Item): + prefix = '- ' + + class Inserted(Item): + prefix = '+ ' + + Empty = str + + class ReplacedBy: # pragma: no cover + prefix = '- ' + suffix = '' + def __init__(self, chunk, total_count): + self.chunk = chunk + self.total_count = total_count + + def __iter__(self): + lines = [ + self.prefix + str(item) + self.suffix + for item in self.chunk + ] + while len(lines) < self.total_count: + lines.append('') + + return iter(lines) + + class Replacing(ReplacedBy): + prefix = "+ " + suffix = '' + + + _c3_report = None + _legacy_report = None + + def __init__(self, c3, c3_ro, legacy_ro): + self.c3 = c3 + self.c3_ro = c3_ro + self.legacy_ro = legacy_ro + + def __move(self, from_, to_, chunk, operation): + for x in chunk: + to_.append(operation(x)) + from_.append(self.Empty()) + + def _generate_report(self): + if self._c3_report is None: + import difflib + # The opcodes we get describe how to turn 'a' into 'b'. So + # the old one (legacy) needs to be first ('a') + matcher = difflib.SequenceMatcher(None, self.legacy_ro, self.c3_ro) + # The reports are equal length sequences. We're going for a + # side-by-side diff. + self._c3_report = c3_report = [] + self._legacy_report = legacy_report = [] + for opcode, leg1, leg2, c31, c32 in matcher.get_opcodes(): + c3_chunk = self.c3_ro[c31:c32] + legacy_chunk = self.legacy_ro[leg1:leg2] + + if opcode == 'equal': + # Guaranteed same length + c3_report.extend(self.Item(x) for x in c3_chunk) + legacy_report.extend(self.Item(x) for x in legacy_chunk) + if opcode == 'delete': + # Guaranteed same length + assert not c3_chunk + self.__move(c3_report, legacy_report, legacy_chunk, self.Deleted) + if opcode == 'insert': + # Guaranteed same length + assert not legacy_chunk + self.__move(legacy_report, c3_report, c3_chunk, self.Inserted) + if opcode == 'replace': # pragma: no cover (How do you make it output this?) + # Either side could be longer. + chunk_size = max(len(c3_chunk), len(legacy_chunk)) + c3_report.extend(self.Replacing(c3_chunk, chunk_size)) + legacy_report.extend(self.ReplacedBy(legacy_chunk, chunk_size)) + + return self._c3_report, self._legacy_report + + @property + def _inconsistent_label(self): + inconsistent = [] + if self.c3.direct_inconsistency: + inconsistent.append('direct') + if self.c3.bases_had_inconsistency: + inconsistent.append('bases') + return '+'.join(inconsistent) if inconsistent else 'no' + + def __str__(self): + c3_report, legacy_report = self._generate_report() + assert len(c3_report) == len(legacy_report) + + left_lines = [str(x) for x in legacy_report] + right_lines = [str(x) for x in c3_report] + + # We have the same number of lines in the report; this is not + # necessarily the same as the number of items in either RO. + assert len(left_lines) == len(right_lines) + + padding = ' ' * 2 + max_left = max(len(x) for x in left_lines) + max_right = max(len(x) for x in right_lines) + + left_title = 'Legacy RO (len={})'.format(len(self.legacy_ro)) + + right_title = 'C3 RO (len={}; inconsistent={})'.format( + len(self.c3_ro), + self._inconsistent_label, + ) + lines = [ + (padding + left_title.ljust(max_left) + padding + right_title.ljust(max_right)), + padding + '=' * (max_left + len(padding) + max_right) + ] + lines += [ + padding + left.ljust(max_left) + padding + right + for left, right in zip(left_lines, right_lines) + ] + + return '\n'.join(lines) + + +# Set to `Interface` once it is defined. This is used to +# avoid logging false positives about changed ROs. +_ROOT = None + +def ro(C, strict=None, base_mros=None, log_changed_ro=None, use_legacy_ro=None): + """ + ro(C) -> list + + Compute the precedence list (mro) according to C3. + + :return: A fresh `list` object. + + .. versionchanged:: 5.0.0 + Add the *strict*, *log_changed_ro* and *use_legacy_ro* + keyword arguments. These are provisional and likely to be + removed in the future. They are most useful for testing. + """ + # The ``base_mros`` argument is for internal optimization and + # not documented. + resolver = C3.resolver(C, strict, base_mros) + mro = resolver.mro() + + log_changed = log_changed_ro if log_changed_ro is not None else resolver.LOG_CHANGED_IRO + use_legacy = use_legacy_ro if use_legacy_ro is not None else resolver.USE_LEGACY_IRO + + if log_changed or use_legacy: + legacy_ro = resolver.legacy_ro + assert isinstance(legacy_ro, list) + assert isinstance(mro, list) + changed = legacy_ro != mro + if changed: + # Did only Interface move? The fix for issue #8 made that + # somewhat common. It's almost certainly not a problem, though, + # so allow ignoring it. + legacy_without_root = [x for x in legacy_ro if x is not _ROOT] + mro_without_root = [x for x in mro if x is not _ROOT] + changed = legacy_without_root != mro_without_root + + if changed: + comparison = _ROComparison(resolver, mro, legacy_ro) + _logger().warning( + "Object %r has different legacy and C3 MROs:\n%s", + C, comparison + ) + if resolver.had_inconsistency and legacy_ro == mro: + comparison = _ROComparison(resolver, mro, legacy_ro) + _logger().warning( + "Object %r had inconsistent IRO and used the legacy RO:\n%s" + "\nInconsistency entered at:\n%s", + C, comparison, resolver.direct_inconsistency + ) + if use_legacy: + return legacy_ro + + return mro + + +def is_consistent(C): + """ + Check if the resolution order for *C*, as computed by :func:`ro`, is consistent + according to C3. + """ + return not C3.resolver(C, False, None).had_inconsistency diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/__init__.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/__init__.py new file mode 100644 index 00000000..04ff9399 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/__init__.py @@ -0,0 +1,115 @@ +from zope.interface._compat import _should_attempt_c_optimizations + + +class OptimizationTestMixin: + """ + Helper for testing that C optimizations are used + when appropriate. + """ + + def _getTargetClass(self): + """ + Define this to return the implementation in use, + without the 'Py' or 'Fallback' suffix. + """ + raise NotImplementedError + + def _getFallbackClass(self): + """ + Define this to return the fallback Python implementation. + """ + # Is there an algorithmic way to do this? The C + # objects all come from the same module so I don't see how we can + # get the Python object from that. + raise NotImplementedError + + def test_optimizations(self): + used = self._getTargetClass() + fallback = self._getFallbackClass() + + if _should_attempt_c_optimizations(): + self.assertIsNot(used, fallback) + else: + self.assertIs(used, fallback) + + +class MissingSomeAttrs: + """ + Helper for tests that raises a specific exception + for attributes that are missing. This is usually not + an AttributeError, and this object is used to test that + those errors are not improperly caught and treated like + an AttributeError. + """ + + def __init__(self, exc_kind, **other_attrs): + self.__exc_kind = exc_kind + d = object.__getattribute__(self, '__dict__') + d.update(other_attrs) + + def __getattribute__(self, name): + # Note that we ignore objects found in the class dictionary. + d = object.__getattribute__(self, '__dict__') + try: + return d[name] + except KeyError: + raise d['_MissingSomeAttrs__exc_kind'](name) + + EXCEPTION_CLASSES = ( + TypeError, + RuntimeError, + BaseException, + ValueError, + ) + + @classmethod + def test_raises(cls, unittest, test_func, expected_missing, **other_attrs): + """ + Loop through various exceptions, calling *test_func* inside a ``assertRaises`` block. + + :param test_func: A callable of one argument, the instance of this + class. + :param str expected_missing: The attribute that should fail with the exception. + This is used to ensure that we're testing the path we think we are. + :param other_attrs: Attributes that should be provided on the test object. + Must not contain *expected_missing*. + """ + assert isinstance(expected_missing, str) + assert expected_missing not in other_attrs + for exc in cls.EXCEPTION_CLASSES: + ob = cls(exc, **other_attrs) + with unittest.assertRaises(exc) as ex: + test_func(ob) + + unittest.assertEqual(ex.exception.args[0], expected_missing) + + # Now test that the AttributeError for that expected_missing is *not* raised. + ob = cls(AttributeError, **other_attrs) + try: + test_func(ob) + except AttributeError as e: + unittest.assertNotIn(expected_missing, str(e)) + except Exception: # pylint:disable=broad-except + pass + +# Be sure cleanup functionality is available; classes that use the adapter hook +# need to be sure to subclass ``CleanUp``. +# +# If zope.component is installed and imported when we run our tests +# (import chain: +# zope.testrunner->zope.security->zope.location->zope.component.api) +# it adds an adapter hook that uses its global site manager. That can cause +# leakage from one test to another unless its cleanup hooks are run. The symptoms can +# be odd, especially if one test used C objects and the next used the Python +# implementation. (For example, you can get strange TypeErrors or find inexplicable +# comparisons being done.) +try: + from zope.testing import cleanup +except ImportError: + class CleanUp: + def cleanUp(self): + pass + + setUp = tearDown = cleanUp +else: + CleanUp = cleanup.CleanUp diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/advisory_testing.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/advisory_testing.py new file mode 100644 index 00000000..bed9dd86 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/advisory_testing.py @@ -0,0 +1,26 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +import sys + +from zope.interface.advice import getFrameInfo + +my_globals = globals() + +ClassicClass = None + +class NewStyleClass: + __metaclass__ = type + classLevelFrameInfo = getFrameInfo(sys._getframe()) + +moduleLevelFrameInfo = getFrameInfo(sys._getframe()) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/dummy.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/dummy.py new file mode 100644 index 00000000..6b142ff6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/dummy.py @@ -0,0 +1,23 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" Dummy Module +""" +from zope.interface import moduleProvides +from zope.interface.tests.idummy import IDummyModule + +moduleProvides(IDummyModule) + +def bar(baz): + # Note: no 'self', because the module provides the interface directly. + raise NotImplementedError() diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/idummy.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/idummy.py new file mode 100644 index 00000000..1e34fe0f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/idummy.py @@ -0,0 +1,23 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" Interface describing API of zope.interface.tests.dummy test module +""" +from zope.interface import Interface + +class IDummyModule(Interface): + """ Dummy interface for unit tests. + """ + def bar(baz): + """ Just a note. + """ diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/m1.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/m1.py new file mode 100644 index 00000000..d311fb40 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/m1.py @@ -0,0 +1,21 @@ +############################################################################## +# +# Copyright (c) 2004 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test module that declares an interface +""" +from zope.interface import Interface, moduleProvides + +class I1(Interface): pass +class I2(Interface): pass + +moduleProvides(I1, I2) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/odd.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/odd.py new file mode 100644 index 00000000..27b42cad --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/odd.py @@ -0,0 +1,124 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Odd meta class that doesn't subclass type. + +This is used for testing support for ExtensionClass in new interfaces. + + >>> class A(object): + ... __metaclass__ = MetaClass + ... a = 1 + ... + >>> A.__name__ + 'A' + >>> A.__bases__ == (object,) + True + >>> class B(object): + ... __metaclass__ = MetaClass + ... b = 1 + ... + >>> class C(A, B): pass + ... + >>> C.__name__ + 'C' + >>> int(C.__bases__ == (A, B)) + 1 + >>> a = A() + >>> aa = A() + >>> a.a + 1 + >>> aa.a + 1 + >>> aa.a = 2 + >>> a.a + 1 + >>> aa.a + 2 + >>> c = C() + >>> c.a + 1 + >>> c.b + 1 + >>> c.b = 2 + >>> c.b + 2 + >>> C.c = 1 + >>> c.c + 1 + + >>> int(C.__class__.__class__ is C.__class__) + 1 +""" + +# class OddClass is an odd meta class + +class MetaMetaClass(type): + + def __getattribute__(cls, name): + if name == '__class__': + return cls + # Under Python 3.6, __prepare__ gets requested + return type.__getattribute__(cls, name) + + +class MetaClass: + """Odd classes + """ + + def __init__(self, name, bases, dict): + self.__name__ = name + self.__bases__ = bases + self.__dict__.update(dict) + + def __call__(self): + return OddInstance(self) + + def __getattr__(self, name): + for b in self.__bases__: + v = getattr(b, name, self) + if v is not self: + return v + raise AttributeError(name) + + def __repr__(self): # pragma: no cover + return "<odd class {} at {}>".format(self.__name__, hex(id(self))) + + +MetaClass = MetaMetaClass('MetaClass', + MetaClass.__bases__, + {k: v for k, v in MetaClass.__dict__.items() + if k not in ('__dict__',)}) + +class OddInstance: + + def __init__(self, cls): + self.__dict__['__class__'] = cls + + def __getattribute__(self, name): + dict = object.__getattribute__(self, '__dict__') + if name == '__dict__': + return dict + v = dict.get(name, self) + if v is not self: + return v + return getattr(dict['__class__'], name) + + def __setattr__(self, name, v): + self.__dict__[name] = v + + def __delattr__(self, name): + raise NotImplementedError() + + def __repr__(self): # pragma: no cover + return "<odd {} instance at {}>".format( + self.__class__.__name__, hex(id(self))) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_adapter.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_adapter.py new file mode 100644 index 00000000..203ba813 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_adapter.py @@ -0,0 +1,2107 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Adapter registry tests +""" +import unittest + +from zope.interface.tests import OptimizationTestMixin + +# pylint:disable=inherit-non-class,protected-access,too-many-lines +# pylint:disable=attribute-defined-outside-init,blacklisted-name + +def _makeInterfaces(): + from zope.interface import Interface + + class IB0(Interface): + pass + class IB1(IB0): + pass + class IB2(IB0): + pass + class IB3(IB2, IB1): + pass + class IB4(IB1, IB2): + pass + + class IF0(Interface): + pass + class IF1(IF0): + pass + + class IR0(Interface): + pass + class IR1(IR0): + pass + + return IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 + + +# Custom types to use as part of the AdapterRegistry data structures. +# Our custom types do strict type checking to make sure +# types propagate through the data tree as expected. +class CustomDataTypeBase: + _data = None + def __getitem__(self, name): + return self._data[name] + + def __setitem__(self, name, value): + self._data[name] = value + + def __delitem__(self, name): + del self._data[name] + + def __len__(self): + return len(self._data) + + def __contains__(self, name): + return name in self._data + + def __eq__(self, other): + if other is self: + return True + # pylint:disable=unidiomatic-typecheck + if type(other) != type(self): + return False + return other._data == self._data + + def __repr__(self): + return repr(self._data) + +class CustomMapping(CustomDataTypeBase): + def __init__(self, other=None): + self._data = {} + if other: + self._data.update(other) + self.get = self._data.get + self.items = self._data.items + + +class CustomSequence(CustomDataTypeBase): + def __init__(self, other=None): + self._data = [] + if other: + self._data.extend(other) + self.append = self._data.append + +class CustomLeafSequence(CustomSequence): + pass + +class CustomProvided(CustomMapping): + pass + + +class BaseAdapterRegistryTests(unittest.TestCase): + + maxDiff = None + + def _getBaseAdapterRegistry(self): + from zope.interface.adapter import BaseAdapterRegistry + return BaseAdapterRegistry + + def _getTargetClass(self): + BaseAdapterRegistry = self._getBaseAdapterRegistry() + class _CUT(BaseAdapterRegistry): + class LookupClass: + _changed = _extendors = () + def __init__(self, reg): + pass + def changed(self, orig): + self._changed += (orig,) + def add_extendor(self, provided): + self._extendors += (provided,) + def remove_extendor(self, provided): + self._extendors = tuple([x for x in self._extendors + if x != provided]) + for name in BaseAdapterRegistry._delegated: + setattr(_CUT.LookupClass, name, object()) + return _CUT + + def _makeOne(self): + return self._getTargetClass()() + + def _getMappingType(self): + return dict + + def _getProvidedType(self): + return dict + + def _getMutableListType(self): + return list + + def _getLeafSequenceType(self): + return tuple + + def test_lookup_delegation(self): + CUT = self._getTargetClass() + registry = CUT() + for name in CUT._delegated: + self.assertIs(getattr(registry, name), getattr(registry._v_lookup, name)) + + def test__generation_on_first_creation(self): + registry = self._makeOne() + # Bumped to 1 in BaseAdapterRegistry.__init__ + self.assertEqual(registry._generation, 1) + + def test__generation_after_calling_changed(self): + registry = self._makeOne() + orig = object() + registry.changed(orig) + # Bumped to 1 in BaseAdapterRegistry.__init__ + self.assertEqual(registry._generation, 2) + self.assertEqual(registry._v_lookup._changed, (registry, orig,)) + + def test__generation_after_changing___bases__(self): + class _Base: + pass + registry = self._makeOne() + registry.__bases__ = (_Base,) + self.assertEqual(registry._generation, 2) + + def _check_basic_types_of_adapters(self, registry, expected_order=2): + self.assertEqual(len(registry._adapters), expected_order) # order 0 and order 1 + self.assertIsInstance(registry._adapters, self._getMutableListType()) + MT = self._getMappingType() + for mapping in registry._adapters: + self.assertIsInstance(mapping, MT) + self.assertEqual(registry._adapters[0], MT()) + self.assertIsInstance(registry._adapters[1], MT) + self.assertEqual(len(registry._adapters[expected_order - 1]), 1) + + def _check_basic_types_of_subscribers(self, registry, expected_order=2): + self.assertEqual(len(registry._subscribers), expected_order) # order 0 and order 1 + self.assertIsInstance(registry._subscribers, self._getMutableListType()) + MT = self._getMappingType() + for mapping in registry._subscribers: + self.assertIsInstance(mapping, MT) + if expected_order: + self.assertEqual(registry._subscribers[0], MT()) + self.assertIsInstance(registry._subscribers[1], MT) + self.assertEqual(len(registry._subscribers[expected_order - 1]), 1) + + def test_register(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.register([IB0], IR0, '', 'A1') + self.assertEqual(registry.registered([IB0], IR0, ''), 'A1') + self.assertEqual(registry._generation, 2) + self._check_basic_types_of_adapters(registry) + MT = self._getMappingType() + self.assertEqual(registry._adapters[1], MT({ + IB0: MT({ + IR0: MT({'': 'A1'}) + }) + })) + PT = self._getProvidedType() + self.assertEqual(registry._provided, PT({ + IR0: 1 + })) + + registered = list(registry.allRegistrations()) + self.assertEqual(registered, [( + (IB0,), # required + IR0, # provided + '', # name + 'A1' # value + )]) + + def test_register_multiple_allRegistrations(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + # Use several different depths and several different names + registry.register([], IR0, '', 'A1') + registry.register([], IR0, 'name1', 'A2') + + registry.register([IB0], IR0, '', 'A1') + registry.register([IB0], IR0, 'name2', 'A2') + registry.register([IB0], IR1, '', 'A3') + registry.register([IB0], IR1, 'name3', 'A4') + + registry.register([IB0, IB1], IR0, '', 'A1') + registry.register([IB0, IB2], IR0, 'name2', 'A2') + registry.register([IB0, IB2], IR1, 'name4', 'A4') + registry.register([IB0, IB3], IR1, '', 'A3') + + def build_adapters(L, MT): + return L([ + # 0 + MT({ + IR0: MT({ + '': 'A1', + 'name1': 'A2' + }) + }), + # 1 + MT({ + IB0: MT({ + IR0: MT({ + '': 'A1', + 'name2': 'A2' + }), + IR1: MT({ + '': 'A3', + 'name3': 'A4' + }) + }) + }), + # 3 + MT({ + IB0: MT({ + IB1: MT({ + IR0: MT({'': 'A1'}) + }), + IB2: MT({ + IR0: MT({'name2': 'A2'}), + IR1: MT({'name4': 'A4'}), + }), + IB3: MT({ + IR1: MT({'': 'A3'}) + }) + }), + }), + ]) + + self.assertEqual(registry._adapters, + build_adapters(L=self._getMutableListType(), + MT=self._getMappingType())) + + registered = sorted(registry.allRegistrations()) + self.assertEqual(registered, [ + ((), IR0, '', 'A1'), + ((), IR0, 'name1', 'A2'), + ((IB0,), IR0, '', 'A1'), + ((IB0,), IR0, 'name2', 'A2'), + ((IB0,), IR1, '', 'A3'), + ((IB0,), IR1, 'name3', 'A4'), + ((IB0, IB1), IR0, '', 'A1'), + ((IB0, IB2), IR0, 'name2', 'A2'), + ((IB0, IB2), IR1, 'name4', 'A4'), + ((IB0, IB3), IR1, '', 'A3') + ]) + + # We can duplicate to another object. + registry2 = self._makeOne() + for args in registered: + registry2.register(*args) + + self.assertEqual(registry2._adapters, registry._adapters) + self.assertEqual(registry2._provided, registry._provided) + + # We can change the types and rebuild the data structures. + registry._mappingType = CustomMapping + registry._leafSequenceType = CustomLeafSequence + registry._sequenceType = CustomSequence + registry._providedType = CustomProvided + def addValue(existing, new): + existing = existing if existing is not None else CustomLeafSequence() + existing.append(new) + return existing + registry._addValueToLeaf = addValue + + registry.rebuild() + + self.assertEqual(registry._adapters, + build_adapters( + L=CustomSequence, + MT=CustomMapping + )) + + def test_register_with_invalid_name(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + with self.assertRaises(ValueError): + registry.register([IB0], IR0, object(), 'A1') + + def test_register_with_value_None_unregisters(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.register([None], IR0, '', 'A1') + registry.register([None], IR0, '', None) + self.assertEqual(len(registry._adapters), 0) + self.assertIsInstance(registry._adapters, self._getMutableListType()) + registered = list(registry.allRegistrations()) + self.assertEqual(registered, []) + + def test_register_with_same_value(self): + from zope.interface import Interface + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + _value = object() + registry.register([None], IR0, '', _value) + _before = registry._generation + registry.register([None], IR0, '', _value) + self.assertEqual(registry._generation, _before) # skipped changed() + self._check_basic_types_of_adapters(registry) + MT = self._getMappingType() + self.assertEqual(registry._adapters[1], MT( + { + Interface: MT( + { + IR0: MT({'': _value}) + } + ) + } + )) + registered = list(registry.allRegistrations()) + self.assertEqual(registered, [( + (Interface,), # required + IR0, # provided + '', # name + _value # value + )]) + + + def test_registered_empty(self): + registry = self._makeOne() + self.assertEqual(registry.registered([None], None, ''), None) + registered = list(registry.allRegistrations()) + self.assertEqual(registered, []) + + def test_registered_non_empty_miss(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.register([IB1], None, '', 'A1') + self.assertEqual(registry.registered([IB2], None, ''), None) + + def test_registered_non_empty_hit(self): + registry = self._makeOne() + registry.register([None], None, '', 'A1') + self.assertEqual(registry.registered([None], None, ''), 'A1') + + def test_unregister_empty(self): + registry = self._makeOne() + registry.unregister([None], None, '') # doesn't raise + self.assertEqual(registry.registered([None], None, ''), None) + self.assertEqual(len(registry._provided), 0) + + def test_unregister_non_empty_miss_on_required(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.register([IB1], None, '', 'A1') + registry.unregister([IB2], None, '') # doesn't raise + self.assertEqual(registry.registered([IB1], None, ''), 'A1') + self._check_basic_types_of_adapters(registry) + MT = self._getMappingType() + self.assertEqual(registry._adapters[1], MT( + { + IB1: MT( + { + None: MT({'': 'A1'}) + } + ) + } + )) + PT = self._getProvidedType() + self.assertEqual(registry._provided, PT({ + None: 1 + })) + + def test_unregister_non_empty_miss_on_name(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.register([IB1], None, '', 'A1') + registry.unregister([IB1], None, 'nonesuch') # doesn't raise + self.assertEqual(registry.registered([IB1], None, ''), 'A1') + self._check_basic_types_of_adapters(registry) + MT = self._getMappingType() + self.assertEqual(registry._adapters[1], MT( + { + IB1: MT( + { + None: MT({'': 'A1'}) + } + ) + } + )) + PT = self._getProvidedType() + self.assertEqual(registry._provided, PT({ + None: 1 + })) + + def test_unregister_with_value_not_None_miss(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + orig = object() + nomatch = object() + registry.register([IB1], None, '', orig) + registry.unregister([IB1], None, '', nomatch) #doesn't raise + self.assertIs(registry.registered([IB1], None, ''), orig) + + def test_unregister_hit_clears_empty_subcomponents(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + one = object() + another = object() + registry.register([IB1, IB2], None, '', one) + registry.register([IB1, IB3], None, '', another) + self._check_basic_types_of_adapters(registry, expected_order=3) + self.assertIn(IB2, registry._adapters[2][IB1]) + self.assertIn(IB3, registry._adapters[2][IB1]) + MT = self._getMappingType() + self.assertEqual(registry._adapters[2], MT( + { + IB1: MT( + { + IB2: MT({None: MT({'': one})}), + IB3: MT({None: MT({'': another})}) + } + ) + } + )) + PT = self._getProvidedType() + self.assertEqual(registry._provided, PT({ + None: 2 + })) + + registry.unregister([IB1, IB3], None, '', another) + self.assertIn(IB2, registry._adapters[2][IB1]) + self.assertNotIn(IB3, registry._adapters[2][IB1]) + self.assertEqual(registry._adapters[2], MT( + { + IB1: MT( + { + IB2: MT({None: MT({'': one})}), + } + ) + } + )) + self.assertEqual(registry._provided, PT({ + None: 1 + })) + + def test_unsubscribe_empty(self): + registry = self._makeOne() + registry.unsubscribe([None], None, '') #doesn't raise + self.assertEqual(registry.registered([None], None, ''), None) + self._check_basic_types_of_subscribers(registry, expected_order=0) + + def test_unsubscribe_hit(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + orig = object() + registry.subscribe([IB1], None, orig) + MT = self._getMappingType() + L = self._getLeafSequenceType() + PT = self._getProvidedType() + self._check_basic_types_of_subscribers(registry) + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + None: MT({ + '': L((orig,)) + }) + }) + })) + self.assertEqual(registry._provided, PT({})) + registry.unsubscribe([IB1], None, orig) #doesn't raise + self.assertEqual(len(registry._subscribers), 0) + self.assertEqual(registry._provided, PT({})) + + def assertLeafIdentity(self, leaf1, leaf2): + """ + Implementations may choose to use new, immutable objects + instead of mutating existing subscriber leaf objects, or vice versa. + + The default implementation uses immutable tuples, so they are never + the same. Other implementations may use persistent lists so they should be + the same and mutated in place. Subclasses testing this behaviour need to + override this method. + """ + self.assertIsNot(leaf1, leaf2) + + def test_unsubscribe_after_multiple(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + first = object() + second = object() + third = object() + fourth = object() + registry.subscribe([IB1], None, first) + registry.subscribe([IB1], None, second) + registry.subscribe([IB1], IR0, third) + registry.subscribe([IB1], IR0, fourth) + self._check_basic_types_of_subscribers(registry, expected_order=2) + MT = self._getMappingType() + L = self._getLeafSequenceType() + PT = self._getProvidedType() + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + None: MT({'': L((first, second))}), + IR0: MT({'': L((third, fourth))}), + }) + })) + self.assertEqual(registry._provided, PT({ + IR0: 2 + })) + # The leaf objects may or may not stay the same as they are unsubscribed, + # depending on the implementation + IR0_leaf_orig = registry._subscribers[1][IB1][IR0][''] + Non_leaf_orig = registry._subscribers[1][IB1][None][''] + + registry.unsubscribe([IB1], None, first) + registry.unsubscribe([IB1], IR0, third) + + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + None: MT({'': L((second,))}), + IR0: MT({'': L((fourth,))}), + }) + })) + self.assertEqual(registry._provided, PT({ + IR0: 1 + })) + IR0_leaf_new = registry._subscribers[1][IB1][IR0][''] + Non_leaf_new = registry._subscribers[1][IB1][None][''] + + self.assertLeafIdentity(IR0_leaf_orig, IR0_leaf_new) + self.assertLeafIdentity(Non_leaf_orig, Non_leaf_new) + + registry.unsubscribe([IB1], None, second) + registry.unsubscribe([IB1], IR0, fourth) + self.assertEqual(len(registry._subscribers), 0) + self.assertEqual(len(registry._provided), 0) + + def test_subscribe_unsubscribe_identical_objects_provided(self): + # https://github.com/zopefoundation/zope.interface/issues/227 + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + first = object() + registry.subscribe([IB1], IR0, first) + registry.subscribe([IB1], IR0, first) + + MT = self._getMappingType() + L = self._getLeafSequenceType() + PT = self._getProvidedType() + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + IR0: MT({'': L((first, first))}), + }) + })) + self.assertEqual(registry._provided, PT({ + IR0: 2 + })) + + registry.unsubscribe([IB1], IR0, first) + registry.unsubscribe([IB1], IR0, first) + self.assertEqual(len(registry._subscribers), 0) + self.assertEqual(registry._provided, PT()) + + def test_subscribe_unsubscribe_nonequal_objects_provided(self): + # https://github.com/zopefoundation/zope.interface/issues/227 + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + first = object() + second = object() + registry.subscribe([IB1], IR0, first) + registry.subscribe([IB1], IR0, second) + + MT = self._getMappingType() + L = self._getLeafSequenceType() + PT = self._getProvidedType() + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + IR0: MT({'': L((first, second))}), + }) + })) + self.assertEqual(registry._provided, PT({ + IR0: 2 + })) + + registry.unsubscribe([IB1], IR0, first) + registry.unsubscribe([IB1], IR0, second) + self.assertEqual(len(registry._subscribers), 0) + self.assertEqual(registry._provided, PT()) + + def test_subscribed_empty(self): + registry = self._makeOne() + self.assertIsNone(registry.subscribed([None], None, '')) + subscribed = list(registry.allSubscriptions()) + self.assertEqual(subscribed, []) + + def test_subscribed_non_empty_miss(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.subscribe([IB1], IF0, 'A1') + # Mismatch required + self.assertIsNone(registry.subscribed([IB2], IF0, '')) + # Mismatch provided + self.assertIsNone(registry.subscribed([IB1], IF1, '')) + # Mismatch value + self.assertIsNone(registry.subscribed([IB1], IF0, '')) + + def test_subscribed_non_empty_hit(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.subscribe([IB0], IF0, 'A1') + self.assertEqual(registry.subscribed([IB0], IF0, 'A1'), 'A1') + + def test_unsubscribe_w_None_after_multiple(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + first = object() + second = object() + + registry.subscribe([IB1], None, first) + registry.subscribe([IB1], None, second) + self._check_basic_types_of_subscribers(registry, expected_order=2) + registry.unsubscribe([IB1], None) + self.assertEqual(len(registry._subscribers), 0) + + def test_unsubscribe_non_empty_miss_on_required(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.subscribe([IB1], None, 'A1') + self._check_basic_types_of_subscribers(registry, expected_order=2) + registry.unsubscribe([IB2], None, '') # doesn't raise + self.assertEqual(len(registry._subscribers), 2) + MT = self._getMappingType() + L = self._getLeafSequenceType() + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + None: MT({'': L(('A1',))}), + }) + })) + + def test_unsubscribe_non_empty_miss_on_value(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + registry.subscribe([IB1], None, 'A1') + self._check_basic_types_of_subscribers(registry, expected_order=2) + registry.unsubscribe([IB1], None, 'A2') # doesn't raise + self.assertEqual(len(registry._subscribers), 2) + MT = self._getMappingType() + L = self._getLeafSequenceType() + self.assertEqual(registry._subscribers[1], MT({ + IB1: MT({ + None: MT({'': L(('A1',))}), + }) + })) + + def test_unsubscribe_with_value_not_None_miss(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + orig = object() + nomatch = object() + registry.subscribe([IB1], None, orig) + registry.unsubscribe([IB1], None, nomatch) #doesn't raise + self.assertEqual(len(registry._subscribers), 2) + + def _instance_method_notify_target(self): + self.fail("Example method, not intended to be called.") + + def test_unsubscribe_instance_method(self): + # Checking that the values are compared by equality, not identity + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + self.assertEqual(len(registry._subscribers), 0) + registry.subscribe([IB1], None, self._instance_method_notify_target) + registry.unsubscribe([IB1], None, self._instance_method_notify_target) + self.assertEqual(len(registry._subscribers), 0) + + def test_subscribe_multiple_allRegistrations(self): + IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces() # pylint:disable=unused-variable + registry = self._makeOne() + # Use several different depths and several different values + registry.subscribe([], IR0, 'A1') + registry.subscribe([], IR0, 'A2') + + registry.subscribe([IB0], IR0, 'A1') + registry.subscribe([IB0], IR0, 'A2') + registry.subscribe([IB0], IR1, 'A3') + registry.subscribe([IB0], IR1, 'A4') + + registry.subscribe([IB0, IB1], IR0, 'A1') + registry.subscribe([IB0, IB2], IR0, 'A2') + registry.subscribe([IB0, IB2], IR1, 'A4') + registry.subscribe([IB0, IB3], IR1, 'A3') + + + def build_subscribers(L, F, MT): + return L([ + # 0 + MT({ + IR0: MT({ + '': F(['A1', 'A2']) + }) + }), + # 1 + MT({ + IB0: MT({ + IR0: MT({ + '': F(['A1', 'A2']) + }), + IR1: MT({ + '': F(['A3', 'A4']) + }) + }) + }), + # 3 + MT({ + IB0: MT({ + IB1: MT({ + IR0: MT({'': F(['A1'])}) + }), + IB2: MT({ + IR0: MT({'': F(['A2'])}), + IR1: MT({'': F(['A4'])}), + }), + IB3: MT({ + IR1: MT({'': F(['A3'])}) + }) + }), + }), + ]) + + self.assertEqual(registry._subscribers, + build_subscribers( + L=self._getMutableListType(), + F=self._getLeafSequenceType(), + MT=self._getMappingType() + )) + + def build_provided(P): + return P({ + IR0: 6, + IR1: 4, + }) + + + self.assertEqual(registry._provided, + build_provided(P=self._getProvidedType())) + + registered = sorted(registry.allSubscriptions()) + self.assertEqual(registered, [ + ((), IR0, 'A1'), + ((), IR0, 'A2'), + ((IB0,), IR0, 'A1'), + ((IB0,), IR0, 'A2'), + ((IB0,), IR1, 'A3'), + ((IB0,), IR1, 'A4'), + ((IB0, IB1), IR0, 'A1'), + ((IB0, IB2), IR0, 'A2'), + ((IB0, IB2), IR1, 'A4'), + ((IB0, IB3), IR1, 'A3') + ]) + + # We can duplicate this to another object + registry2 = self._makeOne() + for args in registered: + registry2.subscribe(*args) + + self.assertEqual(registry2._subscribers, registry._subscribers) + self.assertEqual(registry2._provided, registry._provided) + + # We can change the types and rebuild the data structures. + registry._mappingType = CustomMapping + registry._leafSequenceType = CustomLeafSequence + registry._sequenceType = CustomSequence + registry._providedType = CustomProvided + def addValue(existing, new): + existing = existing if existing is not None else CustomLeafSequence() + existing.append(new) + return existing + registry._addValueToLeaf = addValue + + registry.rebuild() + + self.assertEqual(registry._subscribers, + build_subscribers( + L=CustomSequence, + F=CustomLeafSequence, + MT=CustomMapping + )) + + +class CustomTypesBaseAdapterRegistryTests(BaseAdapterRegistryTests): + """ + This class may be extended by other packages to test their own + adapter registries that use custom types. (So be cautious about + breaking changes.) + + One known user is ``zope.component.persistentregistry``. + """ + + def _getMappingType(self): + return CustomMapping + + def _getProvidedType(self): + return CustomProvided + + def _getMutableListType(self): + return CustomSequence + + def _getLeafSequenceType(self): + return CustomLeafSequence + + def _getBaseAdapterRegistry(self): + from zope.interface.adapter import BaseAdapterRegistry + class CustomAdapterRegistry(BaseAdapterRegistry): + _mappingType = self._getMappingType() + _sequenceType = self._getMutableListType() + _leafSequenceType = self._getLeafSequenceType() + _providedType = self._getProvidedType() + + def _addValueToLeaf(self, existing_leaf_sequence, new_item): + if not existing_leaf_sequence: + existing_leaf_sequence = self._leafSequenceType() + existing_leaf_sequence.append(new_item) + return existing_leaf_sequence + + def _removeValueFromLeaf(self, existing_leaf_sequence, to_remove): + without_removed = BaseAdapterRegistry._removeValueFromLeaf( + self, + existing_leaf_sequence, + to_remove) + existing_leaf_sequence[:] = without_removed + assert to_remove not in existing_leaf_sequence + return existing_leaf_sequence + + return CustomAdapterRegistry + + def assertLeafIdentity(self, leaf1, leaf2): + self.assertIs(leaf1, leaf2) + + +class LookupBaseFallbackTests(unittest.TestCase): + + def _getFallbackClass(self): + from zope.interface.adapter import LookupBaseFallback # pylint:disable=no-name-in-module + return LookupBaseFallback + + _getTargetClass = _getFallbackClass + + def _makeOne(self, uc_lookup=None, uc_lookupAll=None, + uc_subscriptions=None): + # pylint:disable=function-redefined + if uc_lookup is None: + def uc_lookup(self, required, provided, name): + pass + if uc_lookupAll is None: + def uc_lookupAll(self, required, provided): + raise NotImplementedError() + if uc_subscriptions is None: + def uc_subscriptions(self, required, provided): + raise NotImplementedError() + class Derived(self._getTargetClass()): + _uncached_lookup = uc_lookup + _uncached_lookupAll = uc_lookupAll + _uncached_subscriptions = uc_subscriptions + return Derived() + + def test_lookup_w_invalid_name(self): + def _lookup(self, required, provided, name): + self.fail("This should never be called") + lb = self._makeOne(uc_lookup=_lookup) + with self.assertRaises(ValueError): + lb.lookup(('A',), 'B', object()) + + def test_lookup_miss_no_default(self): + _called_with = [] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C') + self.assertIsNone(found) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + + def test_lookup_miss_w_default(self): + _called_with = [] + _default = object() + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C', _default) + self.assertIs(found, _default) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + + def test_lookup_not_cached(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup_cached(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C') + found = lb.lookup(('A',), 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup_not_cached_multi_required(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A', 'D'), 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A', 'D'), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup_cached_multi_required(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A', 'D'), 'B', 'C') + found = lb.lookup(('A', 'D'), 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A', 'D'), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup_not_cached_after_changed(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C') + lb.changed(lb) + found = lb.lookup(('A',), 'B', 'C') + self.assertIs(found, b) + self.assertEqual(_called_with, + [(('A',), 'B', 'C'), (('A',), 'B', 'C')]) + self.assertEqual(_results, [c]) + + def test_lookup1_w_invalid_name(self): + def _lookup(self, required, provided, name): + self.fail("This should never be called") + + lb = self._makeOne(uc_lookup=_lookup) + with self.assertRaises(ValueError): + lb.lookup1('A', 'B', object()) + + def test_lookup1_miss_no_default(self): + _called_with = [] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C') + self.assertIsNone(found) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + + def test_lookup1_miss_w_default(self): + _called_with = [] + _default = object() + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C', _default) + self.assertIs(found, _default) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + + def test_lookup1_miss_w_default_negative_cache(self): + _called_with = [] + _default = object() + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C', _default) + self.assertIs(found, _default) + found = lb.lookup1('A', 'B', 'C', _default) + self.assertIs(found, _default) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + + def test_lookup1_not_cached(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup1_cached(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C') + found = lb.lookup1('A', 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + + def test_lookup1_not_cached_after_changed(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + lb = self._makeOne(uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C') + lb.changed(lb) + found = lb.lookup1('A', 'B', 'C') + self.assertIs(found, b) + self.assertEqual(_called_with, + [(('A',), 'B', 'C'), (('A',), 'B', 'C')]) + self.assertEqual(_results, [c]) + + def test_adapter_hook_w_invalid_name(self): + req, prv = object(), object() + lb = self._makeOne() + with self.assertRaises(ValueError): + lb.adapter_hook(prv, req, object()) + + def test_adapter_hook_miss_no_default(self): + req, prv = object(), object() + lb = self._makeOne() + found = lb.adapter_hook(prv, req, '') + self.assertIsNone(found) + + def test_adapter_hook_miss_w_default(self): + req, prv, _default = object(), object(), object() + lb = self._makeOne() + found = lb.adapter_hook(prv, req, '', _default) + self.assertIs(found, _default) + + def test_adapter_hook_hit_factory_returns_None(self): + _f_called_with = [] + def _factory(context): + _f_called_with.append(context) + + def _lookup(self, required, provided, name): + return _factory + req, prv, _default = object(), object(), object() + lb = self._makeOne(uc_lookup=_lookup) + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, _default) + self.assertEqual(_f_called_with, [req]) + + def test_adapter_hook_hit_factory_returns_adapter(self): + _f_called_with = [] + _adapter = object() + def _factory(context): + _f_called_with.append(context) + return _adapter + def _lookup(self, required, provided, name): + return _factory + req, prv, _default = object(), object(), object() + lb = self._makeOne(uc_lookup=_lookup) + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, _adapter) + self.assertEqual(_f_called_with, [req]) + + def test_adapter_hook_super_unwraps(self): + _f_called_with = [] + def _factory(context): + _f_called_with.append(context) + return context + def _lookup(self, required, provided, name=''): + return _factory + required = super() + provided = object() + lb = self._makeOne(uc_lookup=_lookup) + adapted = lb.adapter_hook(provided, required) + self.assertIs(adapted, self) + self.assertEqual(_f_called_with, [self]) + + def test_queryAdapter(self): + _f_called_with = [] + _adapter = object() + def _factory(context): + _f_called_with.append(context) + return _adapter + def _lookup(self, required, provided, name): + return _factory + req, prv, _default = object(), object(), object() + lb = self._makeOne(uc_lookup=_lookup) + adapted = lb.queryAdapter(req, prv, 'C', _default) + self.assertIs(adapted, _adapter) + self.assertEqual(_f_called_with, [req]) + + def test_lookupAll_uncached(self): + _called_with = [] + _results = [object(), object(), object()] + def _lookupAll(self, required, provided): + _called_with.append((required, provided)) + return tuple(_results) + lb = self._makeOne(uc_lookupAll=_lookupAll) + found = lb.lookupAll('A', 'B') + self.assertEqual(found, tuple(_results)) + self.assertEqual(_called_with, [(('A',), 'B')]) + + def test_lookupAll_cached(self): + _called_with = [] + _results = [object(), object(), object()] + def _lookupAll(self, required, provided): + _called_with.append((required, provided)) + return tuple(_results) + lb = self._makeOne(uc_lookupAll=_lookupAll) + found = lb.lookupAll('A', 'B') + found = lb.lookupAll('A', 'B') + self.assertEqual(found, tuple(_results)) + self.assertEqual(_called_with, [(('A',), 'B')]) + + def test_subscriptions_uncached(self): + _called_with = [] + _results = [object(), object(), object()] + def _subscriptions(self, required, provided): + _called_with.append((required, provided)) + return tuple(_results) + lb = self._makeOne(uc_subscriptions=_subscriptions) + found = lb.subscriptions('A', 'B') + self.assertEqual(found, tuple(_results)) + self.assertEqual(_called_with, [(('A',), 'B')]) + + def test_subscriptions_cached(self): + _called_with = [] + _results = [object(), object(), object()] + def _subscriptions(self, required, provided): + _called_with.append((required, provided)) + return tuple(_results) + lb = self._makeOne(uc_subscriptions=_subscriptions) + found = lb.subscriptions('A', 'B') + found = lb.subscriptions('A', 'B') + self.assertEqual(found, tuple(_results)) + self.assertEqual(_called_with, [(('A',), 'B')]) + + +class LookupBaseTests(LookupBaseFallbackTests, + OptimizationTestMixin): + + def _getTargetClass(self): + from zope.interface.adapter import LookupBase + return LookupBase + + +class VerifyingBaseFallbackTests(unittest.TestCase): + + def _getFallbackClass(self): + from zope.interface.adapter import VerifyingBaseFallback # pylint:disable=no-name-in-module + return VerifyingBaseFallback + + _getTargetClass = _getFallbackClass + + def _makeOne(self, registry, uc_lookup=None, uc_lookupAll=None, + uc_subscriptions=None): + # pylint:disable=function-redefined + if uc_lookup is None: + def uc_lookup(self, required, provided, name): + raise NotImplementedError() + if uc_lookupAll is None: + def uc_lookupAll(self, required, provided): + raise NotImplementedError() + if uc_subscriptions is None: + def uc_subscriptions(self, required, provided): + raise NotImplementedError() + class Derived(self._getTargetClass()): + _uncached_lookup = uc_lookup + _uncached_lookupAll = uc_lookupAll + _uncached_subscriptions = uc_subscriptions + def __init__(self, registry): + super().__init__() + self._registry = registry + derived = Derived(registry) + derived.changed(derived) # init. '_verify_ro' / '_verify_generations' + return derived + + def _makeRegistry(self, depth): + class WithGeneration: + _generation = 1 + class Registry: + def __init__(self, depth): + self.ro = [WithGeneration() for i in range(depth)] + return Registry(depth) + + def test_lookup(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_lookup=_lookup) + found = lb.lookup(('A',), 'B', 'C') + found = lb.lookup(('A',), 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + reg.ro[1]._generation += 1 + found = lb.lookup(('A',), 'B', 'C') + self.assertIs(found, b) + self.assertEqual(_called_with, + [(('A',), 'B', 'C'), (('A',), 'B', 'C')]) + self.assertEqual(_results, [c]) + + def test_lookup1(self): + _called_with = [] + a, b, c = object(), object(), object() + _results = [a, b, c] + def _lookup(self, required, provided, name): + _called_with.append((required, provided, name)) + return _results.pop(0) + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_lookup=_lookup) + found = lb.lookup1('A', 'B', 'C') + found = lb.lookup1('A', 'B', 'C') + self.assertIs(found, a) + self.assertEqual(_called_with, [(('A',), 'B', 'C')]) + self.assertEqual(_results, [b, c]) + reg.ro[1]._generation += 1 + found = lb.lookup1('A', 'B', 'C') + self.assertIs(found, b) + self.assertEqual(_called_with, + [(('A',), 'B', 'C'), (('A',), 'B', 'C')]) + self.assertEqual(_results, [c]) + + def test_adapter_hook(self): + a, b, _c = [object(), object(), object()] + def _factory1(context): + return a + def _factory2(context): + return b + def _factory3(context): + self.fail("This should never be called") + _factories = [_factory1, _factory2, _factory3] + def _lookup(self, required, provided, name): + return _factories.pop(0) + req, prv, _default = object(), object(), object() + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_lookup=_lookup) + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, a) + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, a) + reg.ro[1]._generation += 1 + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, b) + + def test_queryAdapter(self): + a, b, _c = [object(), object(), object()] + def _factory1(context): + return a + def _factory2(context): + return b + def _factory3(context): + self.fail("This should never be called") + _factories = [_factory1, _factory2, _factory3] + def _lookup(self, required, provided, name): + return _factories.pop(0) + req, prv, _default = object(), object(), object() + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_lookup=_lookup) + adapted = lb.queryAdapter(req, prv, 'C', _default) + self.assertIs(adapted, a) + adapted = lb.queryAdapter(req, prv, 'C', _default) + self.assertIs(adapted, a) + reg.ro[1]._generation += 1 + adapted = lb.adapter_hook(prv, req, 'C', _default) + self.assertIs(adapted, b) + + def test_lookupAll(self): + _results_1 = [object(), object(), object()] + _results_2 = [object(), object(), object()] + _results = [_results_1, _results_2] + def _lookupAll(self, required, provided): + return tuple(_results.pop(0)) + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_lookupAll=_lookupAll) + found = lb.lookupAll('A', 'B') + self.assertEqual(found, tuple(_results_1)) + found = lb.lookupAll('A', 'B') + self.assertEqual(found, tuple(_results_1)) + reg.ro[1]._generation += 1 + found = lb.lookupAll('A', 'B') + self.assertEqual(found, tuple(_results_2)) + + def test_subscriptions(self): + _results_1 = [object(), object(), object()] + _results_2 = [object(), object(), object()] + _results = [_results_1, _results_2] + def _subscriptions(self, required, provided): + return tuple(_results.pop(0)) + reg = self._makeRegistry(3) + lb = self._makeOne(reg, uc_subscriptions=_subscriptions) + found = lb.subscriptions('A', 'B') + self.assertEqual(found, tuple(_results_1)) + found = lb.subscriptions('A', 'B') + self.assertEqual(found, tuple(_results_1)) + reg.ro[1]._generation += 1 + found = lb.subscriptions('A', 'B') + self.assertEqual(found, tuple(_results_2)) + + +class VerifyingBaseTests(VerifyingBaseFallbackTests, + OptimizationTestMixin): + + def _getTargetClass(self): + from zope.interface.adapter import VerifyingBase + return VerifyingBase + + +class AdapterLookupBaseTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.adapter import AdapterLookupBase + return AdapterLookupBase + + def _makeOne(self, registry): + return self._getTargetClass()(registry) + + def _makeSubregistry(self, *provided): + class Subregistry: + def __init__(self): + self._adapters = [] + self._subscribers = [] + return Subregistry() + + def _makeRegistry(self, *provided): + class Registry: + def __init__(self, provided): + self._provided = provided + self.ro = [] + return Registry(provided) + + def test_ctor_empty_registry(self): + registry = self._makeRegistry() + alb = self._makeOne(registry) + self.assertEqual(alb._extendors, {}) + + def test_ctor_w_registry_provided(self): + from zope.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + alb = self._makeOne(registry) + self.assertEqual(sorted(alb._extendors.keys()), + sorted([IBar, IFoo, Interface])) + self.assertEqual(alb._extendors[IFoo], [IFoo, IBar]) + self.assertEqual(alb._extendors[IBar], [IBar]) + self.assertEqual(sorted(alb._extendors[Interface]), + sorted([IFoo, IBar])) + + def test_changed_empty_required(self): + # ALB.changed expects to call a mixed in changed. + class Mixin: + def changed(self, *other): + pass + class Derived(self._getTargetClass(), Mixin): + pass + registry = self._makeRegistry() + alb = Derived(registry) + alb.changed(alb) + + def test_changed_w_required(self): + # ALB.changed expects to call a mixed in changed. + class Mixin: + def changed(self, *other): + pass + class Derived(self._getTargetClass(), Mixin): + pass + class FauxWeakref: + _unsub = None + def __init__(self, here): + self._here = here + def __call__(self): + return self if self._here else None + def unsubscribe(self, target): + self._unsub = target + gone = FauxWeakref(False) + here = FauxWeakref(True) + registry = self._makeRegistry() + alb = Derived(registry) + alb._required[gone] = 1 + alb._required[here] = 1 + alb.changed(alb) + self.assertEqual(len(alb._required), 0) + self.assertEqual(gone._unsub, None) + self.assertEqual(here._unsub, alb) + + def test_init_extendors_after_registry_update(self): + from zope.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + alb = self._makeOne(registry) + registry._provided = [IFoo, IBar] + alb.init_extendors() + self.assertEqual(sorted(alb._extendors.keys()), + sorted([IBar, IFoo, Interface])) + self.assertEqual(alb._extendors[IFoo], [IFoo, IBar]) + self.assertEqual(alb._extendors[IBar], [IBar]) + self.assertEqual(sorted(alb._extendors[Interface]), + sorted([IFoo, IBar])) + + def test_add_extendor(self): + from zope.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + alb = self._makeOne(registry) + alb.add_extendor(IFoo) + alb.add_extendor(IBar) + self.assertEqual(sorted(alb._extendors.keys()), + sorted([IBar, IFoo, Interface])) + self.assertEqual(alb._extendors[IFoo], [IFoo, IBar]) + self.assertEqual(alb._extendors[IBar], [IBar]) + self.assertEqual(sorted(alb._extendors[Interface]), + sorted([IFoo, IBar])) + + def test_remove_extendor(self): + from zope.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + alb = self._makeOne(registry) + alb.remove_extendor(IFoo) + self.assertEqual(sorted(alb._extendors.keys()), + sorted([IFoo, IBar, Interface])) + self.assertEqual(alb._extendors[IFoo], [IBar]) + self.assertEqual(alb._extendors[IBar], [IBar]) + self.assertEqual(sorted(alb._extendors[Interface]), + sorted([IBar])) + + # test '_subscribe' via its callers, '_uncached_lookup', etc. + + def test__uncached_lookup_empty_ro(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + alb = self._makeOne(registry) + result = alb._uncached_lookup((IFoo,), IBar) + self.assertEqual(result, None) + self.assertEqual(len(alb._required), 1) + self.assertIn(IFoo.weakref(), alb._required) + + def test__uncached_lookup_order_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + registry.ro.append(subr) + alb = self._makeOne(registry) + result = alb._uncached_lookup((IFoo,), IBar) + self.assertEqual(result, None) + + def test__uncached_lookup_extendors_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + subr = self._makeSubregistry() + subr._adapters = [{}, {}] #utilities, single adapters + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookup((IFoo,), IBar) + self.assertEqual(result, None) + + def test__uncached_lookup_components_miss_wrong_iface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + IQux = InterfaceClass('IQux') + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + irrelevant = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IQux: {'': irrelevant}, + }}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookup((IFoo,), IBar) + self.assertEqual(result, None) + + def test__uncached_lookup_components_miss_wrong_name(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + + wrongname = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'wrongname': wrongname}, + }}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookup((IFoo,), IBar) + self.assertEqual(result, None) + + def test__uncached_lookup_simple_hit(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _expected}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookup((IFoo,), IBar) + self.assertIs(result, _expected) + + def test__uncached_lookup_repeated_hit(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _expected}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookup((IFoo,), IBar) + result2 = alb._uncached_lookup((IFoo,), IBar) + self.assertIs(result, _expected) + self.assertIs(result2, _expected) + + def test_queryMultiAdaptor_lookup_miss(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + @implementer(IFoo) + class Foo: + pass + foo = Foo() + registry = self._makeRegistry() + subr = self._makeSubregistry() + subr._adapters = [ #utilities, single adapters + {}, + {}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.lookup = alb._uncached_lookup # provided by derived + subr._v_lookup = alb + _default = object() + result = alb.queryMultiAdapter((foo,), IBar, default=_default) + self.assertIs(result, _default) + + def test_queryMultiAdapter_errors_on_attribute_access(self): + # Any error on attribute access previously lead to using the _empty singleton as "requires" + # argument (See https://github.com/zopefoundation/zope.interface/issues/162) + # but after https://github.com/zopefoundation/zope.interface/issues/200 + # they get propagated. + from zope.interface.interface import InterfaceClass + from zope.interface.tests import MissingSomeAttrs + + IFoo = InterfaceClass('IFoo') + registry = self._makeRegistry() + alb = self._makeOne(registry) + alb.lookup = alb._uncached_lookup + + def test(ob): + return alb.queryMultiAdapter( + (ob,), + IFoo, + ) + + MissingSomeAttrs.test_raises(self, test, expected_missing='__class__') + + def test_queryMultiAdaptor_factory_miss(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + @implementer(IFoo) + class Foo: + pass + foo = Foo() + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + _called_with = [] + def _factory(context): + _called_with.append(context) + + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _factory}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.lookup = alb._uncached_lookup # provided by derived + subr._v_lookup = alb + _default = object() + result = alb.queryMultiAdapter((foo,), IBar, default=_default) + self.assertIs(result, _default) + self.assertEqual(_called_with, [foo]) + + def test_queryMultiAdaptor_factory_hit(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + @implementer(IFoo) + class Foo: + pass + foo = Foo() + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + _called_with = [] + def _factory(context): + _called_with.append(context) + return _expected + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _factory}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.lookup = alb._uncached_lookup # provided by derived + subr._v_lookup = alb + _default = object() + result = alb.queryMultiAdapter((foo,), IBar, default=_default) + self.assertIs(result, _expected) + self.assertEqual(_called_with, [foo]) + + def test_queryMultiAdapter_super_unwraps(self): + alb = self._makeOne(self._makeRegistry()) + def lookup(*args): + return factory + def factory(*args): + return args + alb.lookup = lookup + + objects = [ + super(), + 42, + "abc", + super(), + ] + + result = alb.queryMultiAdapter(objects, None) + self.assertEqual(result, ( + self, + 42, + "abc", + self, + )) + + def test__uncached_lookupAll_empty_ro(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + alb = self._makeOne(registry) + result = alb._uncached_lookupAll((IFoo,), IBar) + self.assertEqual(result, ()) + self.assertEqual(len(alb._required), 1) + self.assertIn(IFoo.weakref(), alb._required) + + def test__uncached_lookupAll_order_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookupAll((IFoo,), IBar) + self.assertEqual(result, ()) + + def test__uncached_lookupAll_extendors_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + subr = self._makeSubregistry() + subr._adapters = [{}, {}] #utilities, single adapters + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookupAll((IFoo,), IBar) + self.assertEqual(result, ()) + + def test__uncached_lookupAll_components_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + IQux = InterfaceClass('IQux') + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + irrelevant = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IQux: {'': irrelevant}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookupAll((IFoo,), IBar) + self.assertEqual(result, ()) + + def test__uncached_lookupAll_simple_hit(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + _named = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _expected, 'named': _named}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_lookupAll((IFoo,), IBar) + self.assertEqual(sorted(result), [('', _expected), ('named', _named)]) + + def test_names(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _expected = object() + _named = object() + subr._adapters = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': _expected, 'named': _named}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.lookupAll = alb._uncached_lookupAll + subr._v_lookup = alb + result = alb.names((IFoo,), IBar) + self.assertEqual(sorted(result), ['', 'named']) + + def test__uncached_subscriptions_empty_ro(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + alb = self._makeOne(registry) + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(result, []) + self.assertEqual(len(alb._required), 1) + self.assertIn(IFoo.weakref(), alb._required) + + def test__uncached_subscriptions_order_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(result, []) + + def test__uncached_subscriptions_extendors_miss(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry() + subr = self._makeSubregistry() + subr._subscribers = [{}, {}] #utilities, single adapters + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(result, []) + + def test__uncached_subscriptions_components_miss_wrong_iface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + IQux = InterfaceClass('IQux') + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + irrelevant = object() + subr._subscribers = [ #utilities, single adapters + {}, + {IFoo: {IQux: {'': irrelevant}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(result, []) + + def test__uncached_subscriptions_components_miss_wrong_name(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + wrongname = object() + subr._subscribers = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'wrongname': wrongname}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(result, []) + + def test__uncached_subscriptions_simple_hit(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + class Foo: + def __lt__(self, other): + return True + _exp1, _exp2 = Foo(), Foo() + subr._subscribers = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': (_exp1, _exp2)}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + subr._v_lookup = alb + result = alb._uncached_subscriptions((IFoo,), IBar) + self.assertEqual(sorted(result), sorted([_exp1, _exp2])) + + def test_subscribers_wo_provided(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + @implementer(IFoo) + class Foo: + pass + foo = Foo() + registry = self._makeRegistry(IFoo, IBar) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _called = {} + def _factory1(context): + _called.setdefault('_factory1', []).append(context) + def _factory2(context): + _called.setdefault('_factory2', []).append(context) + subr._subscribers = [ #utilities, single adapters + {}, + {IFoo: {None: {'': (_factory1, _factory2)}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.subscriptions = alb._uncached_subscriptions + subr._v_lookup = alb + result = alb.subscribers((foo,), None) + self.assertEqual(result, ()) + self.assertEqual(_called, {'_factory1': [foo], '_factory2': [foo]}) + + def test_subscribers_w_provided(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + @implementer(IFoo) + class Foo: + pass + foo = Foo() + registry = self._makeRegistry(IFoo, IBar) + registry = self._makeRegistry(IFoo, IBar) + subr = self._makeSubregistry() + _called = {} + _exp1, _exp2 = object(), object() + def _factory1(context): + _called.setdefault('_factory1', []).append(context) + return _exp1 + def _factory2(context): + _called.setdefault('_factory2', []).append(context) + return _exp2 + def _side_effect_only(context): + _called.setdefault('_side_effect_only', []).append(context) + + subr._subscribers = [ #utilities, single adapters + {}, + {IFoo: {IBar: {'': (_factory1, _factory2, _side_effect_only)}}}, + ] + registry.ro.append(subr) + alb = self._makeOne(registry) + alb.subscriptions = alb._uncached_subscriptions + subr._v_lookup = alb + result = alb.subscribers((foo,), IBar) + self.assertEqual(result, [_exp1, _exp2]) + self.assertEqual(_called, + {'_factory1': [foo], + '_factory2': [foo], + '_side_effect_only': [foo], + }) + + +class VerifyingAdapterRegistryTests(unittest.TestCase): + # This is also the base for AdapterRegistryTests. That makes the + # inheritance seems backwards, but even though they implement the + # same interfaces, VAR and AR each only extend BAR; and neither + # one will pass the test cases for BAR (it uses a special + # LookupClass just for the tests). + + def _getTargetClass(self): + from zope.interface.adapter import VerifyingAdapterRegistry + return VerifyingAdapterRegistry + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_verify_object_provides_IAdapterRegistry(self): + from zope.interface.verify import verifyObject + from zope.interface.interfaces import IAdapterRegistry + registry = self._makeOne() + verifyObject(IAdapterRegistry, registry) + + +class AdapterRegistryTests(VerifyingAdapterRegistryTests): + + def _getTargetClass(self): + from zope.interface.adapter import AdapterRegistry + return AdapterRegistry + + def test_ctor_no_bases(self): + ar = self._makeOne() + self.assertEqual(len(ar._v_subregistries), 0) + + def test_ctor_w_bases(self): + base = self._makeOne() + sub = self._makeOne([base]) + self.assertEqual(len(sub._v_subregistries), 0) + self.assertEqual(len(base._v_subregistries), 1) + self.assertIn(sub, base._v_subregistries) + + # test _addSubregistry / _removeSubregistry via only caller, _setBases + + def test__setBases_removing_existing_subregistry(self): + before = self._makeOne() + after = self._makeOne() + sub = self._makeOne([before]) + sub.__bases__ = [after] + self.assertEqual(len(before._v_subregistries), 0) + self.assertEqual(len(after._v_subregistries), 1) + self.assertIn(sub, after._v_subregistries) + + def test__setBases_wo_stray_entry(self): + before = self._makeOne() + stray = self._makeOne() + after = self._makeOne() + sub = self._makeOne([before]) + sub.__dict__['__bases__'].append(stray) + sub.__bases__ = [after] + self.assertEqual(len(before._v_subregistries), 0) + self.assertEqual(len(after._v_subregistries), 1) + self.assertIn(sub, after._v_subregistries) + + def test__setBases_w_existing_entry_continuing(self): + before = self._makeOne() + after = self._makeOne() + sub = self._makeOne([before]) + sub.__bases__ = [before, after] + self.assertEqual(len(before._v_subregistries), 1) + self.assertEqual(len(after._v_subregistries), 1) + self.assertIn(sub, before._v_subregistries) + self.assertIn(sub, after._v_subregistries) + + def test_changed_w_subregistries(self): + base = self._makeOne() + class Derived: + _changed = None + def changed(self, originally_changed): + self._changed = originally_changed + derived1, derived2 = Derived(), Derived() + base._addSubregistry(derived1) + base._addSubregistry(derived2) + orig = object() + base.changed(orig) + self.assertIs(derived1._changed, orig) + self.assertIs(derived2._changed, orig) + + +class Test_utils(unittest.TestCase): + + def test__convert_None_to_Interface_w_None(self): + from zope.interface.adapter import _convert_None_to_Interface + from zope.interface.interface import Interface + self.assertIs(_convert_None_to_Interface(None), Interface) + + def test__convert_None_to_Interface_w_other(self): + from zope.interface.adapter import _convert_None_to_Interface + other = object() + self.assertIs(_convert_None_to_Interface(other), other) + + def test__normalize_name_str(self): + from zope.interface.adapter import _normalize_name + STR = b'str' + UNICODE = 'str' + norm = _normalize_name(STR) + self.assertEqual(norm, UNICODE) + self.assertIsInstance(norm, type(UNICODE)) + + def test__normalize_name_unicode(self): + from zope.interface.adapter import _normalize_name + + USTR = 'ustr' + self.assertEqual(_normalize_name(USTR), USTR) + + def test__normalize_name_other(self): + from zope.interface.adapter import _normalize_name + for other in 1, 1.0, (), [], {}, object(): + self.assertRaises(TypeError, _normalize_name, other) + + # _lookup, _lookupAll, and _subscriptions tested via their callers + # (AdapterLookupBase.{lookup,lookupAll,subscriptions}). diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_advice.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_advice.py new file mode 100644 index 00000000..caf5ee7b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_advice.py @@ -0,0 +1,191 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for advice + +This module was adapted from 'protocols.tests.advice', part of the Python +Enterprise Application Kit (PEAK). Please notify the PEAK authors +(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or +Zope-specific changes are required, so that the PEAK version of this module +can be kept in sync. + +PEAK is a Python application framework that interoperates with (but does +not require) Zope 3 and Twisted. It provides tools for manipulating UML +models, object-relational persistence, aspect-oriented programming, and more. +Visit the PEAK home page at http://peak.telecommunity.com for more information. +""" + +import unittest +import sys + + +class FrameInfoTest(unittest.TestCase): + + def test_w_module(self): + from zope.interface.tests import advisory_testing + (kind, module, + f_locals, f_globals) = advisory_testing.moduleLevelFrameInfo + self.assertEqual(kind, "module") + for d in module.__dict__, f_locals, f_globals: + self.assertTrue(d is advisory_testing.my_globals) + + def test_w_class(self): + from zope.interface.tests import advisory_testing + (kind, + module, + f_locals, + f_globals) = advisory_testing.NewStyleClass.classLevelFrameInfo + self.assertEqual(kind, "class") + + for d in module.__dict__, f_globals: + self.assertTrue(d is advisory_testing.my_globals) + + def test_inside_function_call(self): + from zope.interface.advice import getFrameInfo + kind, module, f_locals, f_globals = getFrameInfo(sys._getframe()) + self.assertEqual(kind, "function call") + self.assertTrue(f_locals is locals()) # ??? + for d in module.__dict__, f_globals: + self.assertTrue(d is globals()) + + def test_inside_exec(self): + from zope.interface.advice import getFrameInfo + _globals = {'getFrameInfo': getFrameInfo} + _locals = {} + exec(_FUNKY_EXEC, _globals, _locals) + self.assertEqual(_locals['kind'], "exec") + self.assertTrue(_locals['f_locals'] is _locals) + self.assertTrue(_locals['module'] is None) + self.assertTrue(_locals['f_globals'] is _globals) + + +_FUNKY_EXEC = """\ +import sys +kind, module, f_locals, f_globals = getFrameInfo(sys._getframe()) +""" + +class Test_isClassAdvisor(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.advice import isClassAdvisor + return isClassAdvisor(*args, **kw) + + def test_w_non_function(self): + self.assertEqual(self._callFUT(self), False) + + def test_w_normal_function(self): + def foo(): + raise NotImplementedError() + self.assertEqual(self._callFUT(foo), False) + + def test_w_advisor_function(self): + def bar(): + raise NotImplementedError() + bar.previousMetaclass = object() + self.assertEqual(self._callFUT(bar), True) + + +class Test_determineMetaclass(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.advice import determineMetaclass + return determineMetaclass(*args, **kw) + + def test_empty_w_explicit_metatype(self): + class Meta(type): + pass + self.assertEqual(self._callFUT((), Meta), Meta) + + def test_single(self): + class Meta(type): + pass + self.assertEqual(self._callFUT((Meta,)), type) + + def test_meta_of_class(self): + class Metameta(type): + pass + class Meta(type, metaclass=Metameta): + pass + + self.assertEqual(self._callFUT((Meta, type)), Metameta) + + def test_multiple_in_hierarchy_py3k(self): + class Meta_A(type): + pass + + class Meta_B(Meta_A): + pass + + class A(type, metaclass=Meta_A): + pass + + class B(type, metaclass=Meta_B): + pass + + self.assertEqual(self._callFUT((A, B)), Meta_B) + + + def test_multiple_not_in_hierarchy_py3k(self): + class Meta_A(type): + pass + + class Meta_B(type): + pass + + class A(type, metaclass=Meta_A): + pass + + class B(type, metaclass=Meta_B): + pass + + self.assertRaises(TypeError, self._callFUT, (A, B)) + + +class Test_minimalBases(unittest.TestCase): + + def _callFUT(self, klasses): + from zope.interface.advice import minimalBases + return minimalBases(klasses) + + def test_empty(self): + self.assertEqual(self._callFUT([]), []) + + def test_w_newstyle_meta(self): + self.assertEqual(self._callFUT([type]), [type]) + + def test_w_newstyle_class(self): + class C: + pass + self.assertEqual(self._callFUT([C]), [C]) + + def test_simple_hierarchy_skips_implied(self): + class A: + pass + class B(A): + pass + class C(B): + pass + class D: + pass + self.assertEqual(self._callFUT([A, B, C]), [C]) + self.assertEqual(self._callFUT([A, C]), [C]) + self.assertEqual(self._callFUT([B, C]), [C]) + self.assertEqual(self._callFUT([A, B]), [B]) + self.assertEqual(self._callFUT([D, B, D]), [B, D]) + + def test_repeats_kicked_to_end_of_queue(self): + class A: + pass + class B: + pass + self.assertEqual(self._callFUT([A, B, A]), [B, A]) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_compile_flags.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_compile_flags.py new file mode 100644 index 00000000..3455c445 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_compile_flags.py @@ -0,0 +1,29 @@ +############################################################################## +# +# Copyright (c) 2022 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## +import struct +import unittest + +import zope.interface # noqa: try to load a C module for side effects + + +class TestFloatingPoint(unittest.TestCase): + + def test_no_fast_math_optimization(self): + # Building with -Ofast enables -ffast-math, which sets certain FPU + # flags that can cause breakage elsewhere. A library such as BTrees + # has no business changing global FPU flags for the entire process. + zero_bits = struct.unpack("!Q", struct.pack("!d", 0.0))[0] + next_up = zero_bits + 1 + smallest_subnormal = struct.unpack("!d", struct.pack("!Q", next_up))[0] + self.assertNotEqual(smallest_subnormal, 0.0) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_declarations.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_declarations.py new file mode 100644 index 00000000..c17e323c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_declarations.py @@ -0,0 +1,2453 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test the new API for making and checking interface declarations +""" +import unittest + +from zope.interface.tests import OptimizationTestMixin +from zope.interface.tests import MissingSomeAttrs +from zope.interface.tests.test_interface import NameAndModuleComparisonTestsMixin + +# pylint:disable=inherit-non-class,too-many-lines,protected-access +# pylint:disable=blacklisted-name,attribute-defined-outside-init + +class _Py3ClassAdvice: + + def _run_generated_code(self, code, globs, locs, + fails_under_py3k=True, + ): + # pylint:disable=exec-used,no-member + import warnings + with warnings.catch_warnings(record=True) as log: + warnings.resetwarnings() + + try: + exec(code, globs, locs) + except TypeError: + return False + else: + if fails_under_py3k: + self.fail("Didn't raise TypeError") + return None + + +class NamedTests(unittest.TestCase): + + def test_class(self): + from zope.interface.declarations import named + + @named('foo') + class Foo: + pass + + self.assertEqual(Foo.__component_name__, 'foo') # pylint:disable=no-member + + def test_function(self): + from zope.interface.declarations import named + + @named('foo') + def doFoo(o): + raise NotImplementedError() + + self.assertEqual(doFoo.__component_name__, 'foo') + + def test_instance(self): + from zope.interface.declarations import named + + class Foo: + pass + foo = Foo() + named('foo')(foo) + + self.assertEqual(foo.__component_name__, 'foo') # pylint:disable=no-member + + +class EmptyDeclarationTests(unittest.TestCase): + # Tests that should pass for all objects that are empty + # declarations. This includes a Declaration explicitly created + # that way, and the empty ImmutableDeclaration. + def _getEmpty(self): + from zope.interface.declarations import Declaration + return Declaration() + + def test___iter___empty(self): + decl = self._getEmpty() + self.assertEqual(list(decl), []) + + def test_flattened_empty(self): + from zope.interface.interface import Interface + decl = self._getEmpty() + self.assertEqual(list(decl.flattened()), [Interface]) + + def test___contains___empty(self): + from zope.interface.interface import Interface + decl = self._getEmpty() + self.assertNotIn(Interface, decl) + + def test_extends_empty(self): + from zope.interface.interface import Interface + decl = self._getEmpty() + self.assertTrue(decl.extends(Interface)) + self.assertTrue(decl.extends(Interface, strict=True)) + + def test_interfaces_empty(self): + decl = self._getEmpty() + l = list(decl.interfaces()) + self.assertEqual(l, []) + + def test___sro___(self): + from zope.interface.interface import Interface + decl = self._getEmpty() + self.assertEqual(decl.__sro__, (decl, Interface,)) + + def test___iro___(self): + from zope.interface.interface import Interface + decl = self._getEmpty() + self.assertEqual(decl.__iro__, (Interface,)) + + def test_get(self): + decl = self._getEmpty() + self.assertIsNone(decl.get('attr')) + self.assertEqual(decl.get('abc', 'def'), 'def') + # It's a positive cache only (when it even exists) + # so this added nothing. + self.assertFalse(decl._v_attrs) + + def test_changed_w_existing__v_attrs(self): + decl = self._getEmpty() + decl._v_attrs = object() + decl.changed(decl) + self.assertFalse(decl._v_attrs) + + +class DeclarationTests(EmptyDeclarationTests): + + def _getTargetClass(self): + from zope.interface.declarations import Declaration + return Declaration + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_ctor_no_bases(self): + decl = self._makeOne() + self.assertEqual(list(decl.__bases__), []) + + def test_ctor_w_interface_in_bases(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decl = self._makeOne(IFoo) + self.assertEqual(list(decl.__bases__), [IFoo]) + + def test_ctor_w_implements_in_bases(self): + from zope.interface.declarations import Implements + impl = Implements() + decl = self._makeOne(impl) + self.assertEqual(list(decl.__bases__), [impl]) + + def test_changed_wo_existing__v_attrs(self): + decl = self._makeOne() + decl.changed(decl) # doesn't raise + self.assertIsNone(decl._v_attrs) + + def test___contains__w_self(self): + decl = self._makeOne() + self.assertNotIn(decl, decl) + + def test___contains__w_unrelated_iface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decl = self._makeOne() + self.assertNotIn(IFoo, decl) + + def test___contains__w_base_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decl = self._makeOne(IFoo) + self.assertIn(IFoo, decl) + + def test___iter___single_base(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decl = self._makeOne(IFoo) + self.assertEqual(list(decl), [IFoo]) + + def test___iter___multiple_bases(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + decl = self._makeOne(IFoo, IBar) + self.assertEqual(list(decl), [IFoo, IBar]) + + def test___iter___inheritance(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + decl = self._makeOne(IBar) + self.assertEqual(list(decl), [IBar]) #IBar.interfaces() omits bases + + def test___iter___w_nested_sequence_overlap(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + decl = self._makeOne(IBar, (IFoo, IBar)) + self.assertEqual(list(decl), [IBar, IFoo]) + + def test_flattened_single_base(self): + from zope.interface.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decl = self._makeOne(IFoo) + self.assertEqual(list(decl.flattened()), [IFoo, Interface]) + + def test_flattened_multiple_bases(self): + from zope.interface.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + decl = self._makeOne(IFoo, IBar) + self.assertEqual(list(decl.flattened()), [IFoo, IBar, Interface]) + + def test_flattened_inheritance(self): + from zope.interface.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + decl = self._makeOne(IBar) + self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface]) + + def test_flattened_w_nested_sequence_overlap(self): + from zope.interface.interface import Interface + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + # This is the same as calling ``Declaration(IBar, IFoo, IBar)`` + # which doesn't make much sense, but here it is. In older + # versions of zope.interface, the __iro__ would have been + # IFoo, IBar, Interface, which especially makes no sense. + decl = self._makeOne(IBar, (IFoo, IBar)) + # Note that decl.__iro__ has IFoo first. + self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface]) + + def test___sub___unrelated_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + before = self._makeOne(IFoo) + after = before - IBar + self.assertIsInstance(after, self._getTargetClass()) + self.assertEqual(list(after), [IFoo]) + + def test___sub___related_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + before = self._makeOne(IFoo) + after = before - IFoo + self.assertEqual(list(after), []) + + def test___sub___related_interface_by_inheritance(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar', (IFoo,)) + before = self._makeOne(IBar) + after = before - IBar + self.assertEqual(list(after), []) + + def test___add___unrelated_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + before = self._makeOne(IFoo) + after = before + IBar + self.assertIsInstance(after, self._getTargetClass()) + self.assertEqual(list(after), [IFoo, IBar]) + + def test___add___related_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + IBaz = InterfaceClass('IBaz') + before = self._makeOne(IFoo, IBar) + other = self._makeOne(IBar, IBaz) + after = before + other + self.assertEqual(list(after), [IFoo, IBar, IBaz]) + + def test___add___overlapping_interface(self): + # The derived interfaces end up with higher priority, and + # don't produce a C3 resolution order violation. This + # example produced a C3 error, and the resulting legacy order + # used to be wrong ([IBase, IDerived] instead of + # the other way). + from zope.interface import Interface + from zope.interface.interface import InterfaceClass + from zope.interface.tests.test_ro import C3Setting + from zope.interface import ro + + IBase = InterfaceClass('IBase') + IDerived = InterfaceClass('IDerived', (IBase,)) + + with C3Setting(ro.C3.STRICT_IRO, True): + base = self._makeOne(IBase) + after = base + IDerived + + self.assertEqual(after.__iro__, (IDerived, IBase, Interface)) + self.assertEqual(after.__bases__, (IDerived, IBase)) + self.assertEqual(list(after), [IDerived, IBase]) + + def test___add___overlapping_interface_implementedBy(self): + # Like test___add___overlapping_interface, but pulling + # in a realistic example. This one previously produced a + # C3 error, but the resulting legacy order was (somehow) + # correct. + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import implementer + from zope.interface.tests.test_ro import C3Setting + from zope.interface import ro + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IBase) + class Base: + pass + + with C3Setting(ro.C3.STRICT_IRO, True): + after = implementedBy(Base) + IDerived + + self.assertEqual(after.__sro__, (after, IDerived, IBase, Interface)) + self.assertEqual(after.__bases__, (IDerived, IBase)) + self.assertEqual(list(after), [IDerived, IBase]) + + +class TestImmutableDeclaration(EmptyDeclarationTests): + + def _getTargetClass(self): + from zope.interface.declarations import _ImmutableDeclaration + return _ImmutableDeclaration + + def _getEmpty(self): + from zope.interface.declarations import _empty + return _empty + + def test_pickle(self): + import pickle + copied = pickle.loads(pickle.dumps(self._getEmpty())) + self.assertIs(copied, self._getEmpty()) + + def test_singleton(self): + self.assertIs( + self._getTargetClass()(), + self._getEmpty() + ) + + def test__bases__(self): + self.assertEqual(self._getEmpty().__bases__, ()) + + def test_change__bases__(self): + empty = self._getEmpty() + empty.__bases__ = () + self.assertEqual(self._getEmpty().__bases__, ()) + + with self.assertRaises(TypeError): + empty.__bases__ = (1,) + + def test_dependents(self): + empty = self._getEmpty() + deps = empty.dependents + self.assertEqual({}, deps) + # Doesn't change the return. + deps[1] = 2 + self.assertEqual({}, empty.dependents) + + def test_changed(self): + # Does nothing, has no visible side-effects + self._getEmpty().changed(None) + + def test_extends_always_false(self): + self.assertFalse(self._getEmpty().extends(self)) + self.assertFalse(self._getEmpty().extends(self, strict=True)) + self.assertFalse(self._getEmpty().extends(self, strict=False)) + + def test_get_always_default(self): + self.assertIsNone(self._getEmpty().get('name')) + self.assertEqual(self._getEmpty().get('name', 42), 42) + + def test_v_attrs(self): + decl = self._getEmpty() + self.assertEqual(decl._v_attrs, {}) + + decl._v_attrs['attr'] = 42 + self.assertEqual(decl._v_attrs, {}) + self.assertIsNone(decl.get('attr')) + + attrs = decl._v_attrs = {} + attrs['attr'] = 42 + self.assertEqual(decl._v_attrs, {}) + self.assertIsNone(decl.get('attr')) + + +class TestImplements(NameAndModuleComparisonTestsMixin, + unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import Implements + return Implements + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def _makeOneToCompare(self): + from zope.interface.declarations import implementedBy + class A: + pass + + return implementedBy(A) + + def test_ctor_no_bases(self): + impl = self._makeOne() + self.assertEqual(impl.inherit, None) + self.assertEqual(impl.declared, ()) + self.assertEqual(impl.__name__, '?') + self.assertEqual(list(impl.__bases__), []) + + def test___repr__(self): + impl = self._makeOne() + impl.__name__ = 'Testing' + self.assertEqual(repr(impl), 'classImplements(Testing)') + + def test___reduce__(self): + from zope.interface.declarations import implementedBy + impl = self._makeOne() + self.assertEqual(impl.__reduce__(), (implementedBy, (None,))) + + def test_sort(self): + from zope.interface.declarations import implementedBy + class A: + pass + class B: + pass + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + + self.assertEqual(implementedBy(A), implementedBy(A)) + self.assertEqual(hash(implementedBy(A)), hash(implementedBy(A))) + self.assertTrue(implementedBy(A) < None) + self.assertTrue(None > implementedBy(A)) # pylint:disable=misplaced-comparison-constant + self.assertTrue(implementedBy(A) < implementedBy(B)) + self.assertTrue(implementedBy(A) > IFoo) + self.assertTrue(implementedBy(A) <= implementedBy(B)) + self.assertTrue(implementedBy(A) >= IFoo) + self.assertTrue(implementedBy(A) != IFoo) + + def test_proxy_equality(self): + # https://github.com/zopefoundation/zope.interface/issues/55 + class Proxy: + def __init__(self, wrapped): + self._wrapped = wrapped + + def __getattr__(self, name): + raise NotImplementedError() + + def __eq__(self, other): + return self._wrapped == other + + def __ne__(self, other): + return self._wrapped != other + + from zope.interface.declarations import implementedBy + class A: + pass + + class B: + pass + + implementedByA = implementedBy(A) + implementedByB = implementedBy(B) + proxy = Proxy(implementedByA) + + # The order of arguments to the operators matters, + # test both + self.assertTrue(implementedByA == implementedByA) # pylint:disable=comparison-with-itself + self.assertTrue(implementedByA != implementedByB) + self.assertTrue(implementedByB != implementedByA) + + self.assertTrue(proxy == implementedByA) + self.assertTrue(implementedByA == proxy) + self.assertFalse(proxy != implementedByA) + self.assertFalse(implementedByA != proxy) + + self.assertTrue(proxy != implementedByB) + self.assertTrue(implementedByB != proxy) + + def test_changed_deletes_super_cache(self): + impl = self._makeOne() + self.assertIsNone(impl._super_cache) + self.assertNotIn('_super_cache', impl.__dict__) + + impl._super_cache = 42 + self.assertIn('_super_cache', impl.__dict__) + + impl.changed(None) + self.assertIsNone(impl._super_cache) + self.assertNotIn('_super_cache', impl.__dict__) + + def test_changed_does_not_add_super_cache(self): + impl = self._makeOne() + self.assertIsNone(impl._super_cache) + self.assertNotIn('_super_cache', impl.__dict__) + + impl.changed(None) + self.assertIsNone(impl._super_cache) + self.assertNotIn('_super_cache', impl.__dict__) + + +class Test_implementedByFallback(unittest.TestCase): + + def _getTargetClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations import implementedByFallback + return implementedByFallback + + _getFallbackClass = _getTargetClass + + def _callFUT(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_dictless_wo_existing_Implements_wo_registrations(self): + class Foo: + __slots__ = ('__implemented__',) + foo = Foo() + foo.__implemented__ = None + self.assertEqual(list(self._callFUT(foo)), []) + + def test_dictless_wo_existing_Implements_cant_assign___implemented__(self): + class Foo: + def _get_impl(self): + raise NotImplementedError() + def _set_impl(self, val): + raise TypeError + __implemented__ = property(_get_impl, _set_impl) + def __call__(self): + # act like a factory + raise NotImplementedError() + foo = Foo() + self.assertRaises(TypeError, self._callFUT, foo) + + def test_dictless_wo_existing_Implements_w_registrations(self): + from zope.interface import declarations + class Foo: + __slots__ = ('__implemented__',) + foo = Foo() + foo.__implemented__ = None + reg = object() + with _MonkeyDict(declarations, + 'BuiltinImplementationSpecifications') as specs: + specs[foo] = reg + self.assertTrue(self._callFUT(foo) is reg) + + def test_dictless_w_existing_Implements(self): + from zope.interface.declarations import Implements + impl = Implements() + class Foo: + __slots__ = ('__implemented__',) + foo = Foo() + foo.__implemented__ = impl + self.assertTrue(self._callFUT(foo) is impl) + + def test_dictless_w_existing_not_Implements(self): + from zope.interface.interface import InterfaceClass + class Foo: + __slots__ = ('__implemented__',) + foo = Foo() + IFoo = InterfaceClass('IFoo') + foo.__implemented__ = (IFoo,) + self.assertEqual(list(self._callFUT(foo)), [IFoo]) + + def test_w_existing_attr_as_Implements(self): + from zope.interface.declarations import Implements + impl = Implements() + class Foo: + __implemented__ = impl + self.assertTrue(self._callFUT(Foo) is impl) + + def test_builtins_added_to_cache(self): + from zope.interface import declarations + from zope.interface.declarations import Implements + with _MonkeyDict(declarations, + 'BuiltinImplementationSpecifications') as specs: + self.assertEqual(list(self._callFUT(tuple)), []) + self.assertEqual(list(self._callFUT(list)), []) + self.assertEqual(list(self._callFUT(dict)), []) + for typ in (tuple, list, dict): + spec = specs[typ] + self.assertIsInstance(spec, Implements) + self.assertEqual(repr(spec), + 'classImplements(%s)' + % (typ.__name__,)) + + def test_builtins_w_existing_cache(self): + from zope.interface import declarations + t_spec, l_spec, d_spec = object(), object(), object() + with _MonkeyDict(declarations, + 'BuiltinImplementationSpecifications') as specs: + specs[tuple] = t_spec + specs[list] = l_spec + specs[dict] = d_spec + self.assertTrue(self._callFUT(tuple) is t_spec) + self.assertTrue(self._callFUT(list) is l_spec) + self.assertTrue(self._callFUT(dict) is d_spec) + + def test_oldstyle_class_no_assertions(self): + # TODO: Figure out P3 story + class Foo: + pass + self.assertEqual(list(self._callFUT(Foo)), []) + + def test_no_assertions(self): + # TODO: Figure out P3 story + class Foo: + pass + self.assertEqual(list(self._callFUT(Foo)), []) + + def test_w_None_no_bases_not_factory(self): + class Foo: + __implemented__ = None + foo = Foo() + self.assertRaises(TypeError, self._callFUT, foo) + + def test_w_None_no_bases_w_factory(self): + from zope.interface.declarations import objectSpecificationDescriptor + class Foo: + __implemented__ = None + def __call__(self): + raise NotImplementedError() + + foo = Foo() + foo.__name__ = 'foo' + spec = self._callFUT(foo) + self.assertEqual(spec.__name__, + 'zope.interface.tests.test_declarations.foo') + self.assertIs(spec.inherit, foo) + self.assertIs(foo.__implemented__, spec) + self.assertIs(foo.__providedBy__, objectSpecificationDescriptor) # pylint:disable=no-member + self.assertNotIn('__provides__', foo.__dict__) + + def test_w_None_no_bases_w_class(self): + from zope.interface.declarations import ClassProvides + class Foo: + __implemented__ = None + spec = self._callFUT(Foo) + self.assertEqual(spec.__name__, + 'zope.interface.tests.test_declarations.Foo') + self.assertIs(spec.inherit, Foo) + self.assertIs(Foo.__implemented__, spec) + self.assertIsInstance(Foo.__providedBy__, ClassProvides) # pylint:disable=no-member + self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member + self.assertEqual(Foo.__provides__, Foo.__providedBy__) # pylint:disable=no-member + + def test_w_existing_Implements(self): + from zope.interface.declarations import Implements + impl = Implements() + class Foo: + __implemented__ = impl + self.assertTrue(self._callFUT(Foo) is impl) + + def test_super_when_base_implements_interface(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase]) + sup = super(Derived, Derived) + self.assertEqual(list(self._callFUT(sup)), [IBase]) + + def test_super_when_base_implements_interface_diamond(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IBase) + class Base: + pass + + class Child1(Base): + pass + + class Child2(Base): + pass + + @implementer(IDerived) + class Derived(Child1, Child2): + pass + + self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase]) + sup = super(Derived, Derived) + self.assertEqual(list(self._callFUT(sup)), [IBase]) + + def test_super_when_parent_implements_interface_diamond(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + + class Base: + pass + + class Child1(Base): + pass + + @implementer(IBase) + class Child2(Base): + pass + + @implementer(IDerived) + class Derived(Child1, Child2): + pass + + self.assertEqual(Derived.__mro__, (Derived, Child1, Child2, Base, object)) + self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase]) + sup = super(Derived, Derived) + fut = self._callFUT(sup) + self.assertEqual(list(fut), [IBase]) + self.assertIsNone(fut._dependents) + + def test_super_when_base_doesnt_implement_interface(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + self.assertEqual(list(self._callFUT(Derived)), [IDerived]) + + sup = super(Derived, Derived) + self.assertEqual(list(self._callFUT(sup)), []) + + def test_super_when_base_is_object(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IDerived) + class Derived: + pass + + self.assertEqual(list(self._callFUT(Derived)), [IDerived]) + + sup = super(Derived, Derived) + self.assertEqual(list(self._callFUT(sup)), []) + def test_super_multi_level_multi_inheritance(self): + from zope.interface.declarations import implementer + from zope.interface import Interface + + class IBase(Interface): + pass + + class IM1(Interface): + pass + + class IM2(Interface): + pass + + class IDerived(IBase): + pass + + class IUnrelated(Interface): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IM1) + class M1(Base): + pass + + @implementer(IM2) + class M2(Base): + pass + + @implementer(IDerived, IUnrelated) + class Derived(M1, M2): + pass + + d = Derived + sd = super(Derived, Derived) + sm1 = super(M1, Derived) + sm2 = super(M2, Derived) + + self.assertEqual(list(self._callFUT(d)), + [IDerived, IUnrelated, IM1, IBase, IM2]) + self.assertEqual(list(self._callFUT(sd)), + [IM1, IBase, IM2]) + self.assertEqual(list(self._callFUT(sm1)), + [IM2, IBase]) + self.assertEqual(list(self._callFUT(sm2)), + [IBase]) + + +class Test_implementedBy(Test_implementedByFallback, + OptimizationTestMixin): + # Repeat tests for C optimizations + + def _getTargetClass(self): + from zope.interface.declarations import implementedBy + return implementedBy + + +class _ImplementsTestMixin: + FUT_SETS_PROVIDED_BY = True + + def _callFUT(self, cls, iface): + # Declare that *cls* implements *iface*; return *cls* + raise NotImplementedError + + def _check_implementer(self, Foo, + orig_spec=None, + spec_name=__name__ + '.Foo', + inherit="not given"): + from zope.interface.declarations import ClassProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + + returned = self._callFUT(Foo, IFoo) + + self.assertIs(returned, Foo) + spec = Foo.__implemented__ + if orig_spec is not None: + self.assertIs(spec, orig_spec) + + self.assertEqual(spec.__name__, + spec_name) + inherit = Foo if inherit == "not given" else inherit + self.assertIs(spec.inherit, inherit) + self.assertIs(Foo.__implemented__, spec) + if self.FUT_SETS_PROVIDED_BY: + self.assertIsInstance(Foo.__providedBy__, ClassProvides) + self.assertIsInstance(Foo.__provides__, ClassProvides) + self.assertEqual(Foo.__provides__, Foo.__providedBy__) + + return Foo, IFoo + + def test_class(self): + class Foo: + pass + self._check_implementer(Foo) + +class Test_classImplementsOnly(_ImplementsTestMixin, unittest.TestCase): + FUT_SETS_PROVIDED_BY = False + + def _callFUT(self, cls, iface): + from zope.interface.declarations import classImplementsOnly + classImplementsOnly(cls, iface) + return cls + + def test_w_existing_Implements(self): + from zope.interface.declarations import Implements + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + impl = Implements(IFoo) + impl.declared = (IFoo,) + class Foo: + __implemented__ = impl + impl.inherit = Foo + self._callFUT(Foo, IBar) + # Same spec, now different values + self.assertTrue(Foo.__implemented__ is impl) + self.assertEqual(impl.inherit, None) + self.assertEqual(impl.declared, (IBar,)) + + def test_class(self): + from zope.interface.declarations import Implements + from zope.interface.interface import InterfaceClass + IBar = InterfaceClass('IBar') + old_spec = Implements(IBar) + + class Foo: + __implemented__ = old_spec + self._check_implementer(Foo, old_spec, '?', inherit=None) + + + def test_redundant_with_super_still_implements(self): + Base, IBase = self._check_implementer( + type('Foo', (object,), {}), + inherit=None, + ) + + class Child(Base): + pass + + self._callFUT(Child, IBase) + self.assertTrue(IBase.implementedBy(Child)) + + +class Test_classImplements(_ImplementsTestMixin, unittest.TestCase): + + def _callFUT(self, cls, iface): + from zope.interface.declarations import classImplements + result = classImplements(cls, iface) # pylint:disable=assignment-from-no-return + self.assertIsNone(result) + return cls + + def __check_implementer_redundant(self, Base): + # If we @implementer exactly what was already present, we write + # no declared attributes on the parent (we still set everything, though) + Base, IBase = self._check_implementer(Base) + + class Child(Base): + pass + + returned = self._callFUT(Child, IBase) + self.assertIn('__implemented__', returned.__dict__) + self.assertNotIn('__providedBy__', returned.__dict__) + self.assertIn('__provides__', returned.__dict__) + + spec = Child.__implemented__ + self.assertEqual(spec.declared, ()) + self.assertEqual(spec.inherit, Child) + + self.assertTrue(IBase.providedBy(Child())) + + def test_redundant_implementer_empty_class_declarations(self): + class Foo: + pass + self.__check_implementer_redundant(Foo) + + def test_redundant_implementer_Interface(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import ro + from zope.interface.tests.test_ro import C3Setting + + class Foo: + pass + + with C3Setting(ro.C3.STRICT_IRO, False): + self._callFUT(Foo, Interface) + self.assertEqual(list(implementedBy(Foo)), [Interface]) + + class Baz(Foo): + pass + + self._callFUT(Baz, Interface) + self.assertEqual(list(implementedBy(Baz)), [Interface]) + + def _order_for_two(self, applied_first, applied_second): + return (applied_first, applied_second) + + def test_w_existing_Implements(self): + from zope.interface.declarations import Implements + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + impl = Implements(IFoo) + impl.declared = (IFoo,) + class Foo: + __implemented__ = impl + impl.inherit = Foo + self._callFUT(Foo, IBar) + # Same spec, now different values + self.assertIs(Foo.__implemented__, impl) + self.assertEqual(impl.inherit, Foo) + self.assertEqual(impl.declared, + self._order_for_two(IFoo, IBar)) + + def test_w_existing_Implements_w_bases(self): + from zope.interface.declarations import Implements + from zope.interface.interface import InterfaceClass + IRoot = InterfaceClass('IRoot') + ISecondRoot = InterfaceClass('ISecondRoot') + IExtendsRoot = InterfaceClass('IExtendsRoot', (IRoot,)) + + impl_root = Implements.named('Root', IRoot) + impl_root.declared = (IRoot,) + + class Root1: + __implemented__ = impl_root + class Root2: + __implemented__ = impl_root + + impl_extends_root = Implements.named('ExtendsRoot1', IExtendsRoot) + impl_extends_root.declared = (IExtendsRoot,) + class ExtendsRoot(Root1, Root2): + __implemented__ = impl_extends_root + impl_extends_root.inherit = ExtendsRoot + + self._callFUT(ExtendsRoot, ISecondRoot) + # Same spec, now different values + self.assertIs(ExtendsRoot.__implemented__, impl_extends_root) + self.assertEqual(impl_extends_root.inherit, ExtendsRoot) + self.assertEqual(impl_extends_root.declared, + self._order_for_two(IExtendsRoot, ISecondRoot,)) + self.assertEqual(impl_extends_root.__bases__, + self._order_for_two(IExtendsRoot, ISecondRoot) + (impl_root,)) + + +class Test_classImplementsFirst(Test_classImplements): + + def _callFUT(self, cls, iface): + from zope.interface.declarations import classImplementsFirst + result = classImplementsFirst(cls, iface) # pylint:disable=assignment-from-no-return + self.assertIsNone(result) + return cls + + def _order_for_two(self, applied_first, applied_second): + return (applied_second, applied_first) + + +class Test__implements_advice(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import _implements_advice + return _implements_advice(*args, **kw) + + def test_no_existing_implements(self): + from zope.interface.declarations import classImplements + from zope.interface.declarations import Implements + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + class Foo: + __implements_advice_data__ = ((IFoo,), classImplements) + self._callFUT(Foo) + self.assertNotIn('__implements_advice_data__', Foo.__dict__) + self.assertIsInstance(Foo.__implemented__, Implements) # pylint:disable=no-member + self.assertEqual(list(Foo.__implemented__), [IFoo]) # pylint:disable=no-member + + +class Test_implementer(Test_classImplements): + + def _getTargetClass(self): + from zope.interface.declarations import implementer + return implementer + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def _callFUT(self, cls, *ifaces): + decorator = self._makeOne(*ifaces) + return decorator(cls) + + def test_nonclass_cannot_assign_attr(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decorator = self._makeOne(IFoo) + self.assertRaises(TypeError, decorator, object()) + + def test_nonclass_can_assign_attr(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + class Foo: + pass + foo = Foo() + decorator = self._makeOne(IFoo) + returned = decorator(foo) + self.assertTrue(returned is foo) + spec = foo.__implemented__ # pylint:disable=no-member + self.assertEqual(spec.__name__, 'zope.interface.tests.test_declarations.?') + self.assertIsNone(spec.inherit,) + self.assertIs(foo.__implemented__, spec) # pylint:disable=no-member + + def test_does_not_leak_on_unique_classes(self): + # Make sure nothing is hanging on to the class or Implements + # object after they go out of scope. There was briefly a bug + # in 5.x that caused SpecificationBase._bases (in C) to not be + # traversed or cleared. + # https://github.com/zopefoundation/zope.interface/issues/216 + import gc + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + + begin_count = len(gc.get_objects()) + + for _ in range(1900): + class TestClass: + pass + + self._callFUT(TestClass, IFoo) + + gc.collect() + + end_count = len(gc.get_objects()) + + # How many new objects might still be around? In all currently + # tested interpreters, there aren't any, so our counts should + # match exactly. When the bug existed, in a steady state, the loop + # would grow by two objects each iteration + fudge_factor = 0 + self.assertLessEqual(end_count, begin_count + fudge_factor) + + + +class Test_implementer_only(Test_classImplementsOnly): + + def _getTargetClass(self): + from zope.interface.declarations import implementer_only + return implementer_only + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def _callFUT(self, cls, iface): + decorator = self._makeOne(iface) + return decorator(cls) + + def test_function(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decorator = self._makeOne(IFoo) + def _function(): + raise NotImplementedError() + self.assertRaises(ValueError, decorator, _function) + + def test_method(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + decorator = self._makeOne(IFoo) + class Bar: + def _method(self): + raise NotImplementedError() + self.assertRaises(ValueError, decorator, Bar._method) + + + + + +class ProvidesClassTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import ProvidesClass + return ProvidesClass + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_simple_class_one_interface(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + spec = self._makeOne(Foo, IFoo) + self.assertEqual(list(spec), [IFoo]) + + def test___reduce__(self): + from zope.interface.declarations import Provides # the function + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + spec = self._makeOne(Foo, IFoo) + klass, args = spec.__reduce__() + self.assertIs(klass, Provides) + self.assertEqual(args, (Foo, IFoo)) + + def test___get___class(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + spec = self._makeOne(Foo, IFoo) + Foo.__provides__ = spec + self.assertIs(Foo.__provides__, spec) + + def test___get___instance(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + spec = self._makeOne(Foo, IFoo) + Foo.__provides__ = spec + def _test(): + foo = Foo() + return foo.__provides__ + self.assertRaises(AttributeError, _test) + + +class ProvidesClassStrictTests(ProvidesClassTests): + # Tests that require the strict C3 resolution order. + + def _getTargetClass(self): + ProvidesClass = super()._getTargetClass() + class StrictProvides(ProvidesClass): + def _do_calculate_ro(self, base_mros): + return ProvidesClass._do_calculate_ro(self, base_mros=base_mros, strict=True) + return StrictProvides + + def test_overlapping_interfaces_corrected(self): + # Giving Provides(cls, IFace), where IFace is already + # provided by cls, doesn't produce invalid resolution orders. + from zope.interface import implementedBy + from zope.interface import Interface + from zope.interface import implementer + + class IBase(Interface): + pass + + @implementer(IBase) + class Base: + pass + + spec = self._makeOne(Base, IBase) + self.assertEqual(spec.__sro__, ( + spec, + implementedBy(Base), + IBase, + implementedBy(object), + Interface + )) + + +class TestProvidesClassRepr(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import ProvidesClass + return ProvidesClass + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test__repr__(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + assert IFoo.__name__ == 'IFoo' + assert IFoo.__module__ == __name__ + assert repr(IFoo) == '<InterfaceClass {}.IFoo>'.format(__name__) + + IBar = InterfaceClass("IBar") + + inst = self._makeOne(type(self), IFoo, IBar) + self.assertEqual( + repr(inst), + "directlyProvides(TestProvidesClassRepr, IFoo, IBar)" + ) + + def test__repr__module_provides_typical_use(self): + # as created through a ``moduleProvides()`` statement + # in a module body + from zope.interface.tests import dummy + provides = dummy.__provides__ # pylint:disable=no-member + self.assertEqual( + repr(provides), + "directlyProvides(sys.modules['zope.interface.tests.dummy'], IDummyModule)" + ) + + def test__repr__module_after_pickle(self): + # It doesn't matter, these objects can't be pickled. + import pickle + from zope.interface.tests import dummy + provides = dummy.__provides__ # pylint:disable=no-member + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(pickle.PicklingError): + pickle.dumps(provides, proto) + + def test__repr__directlyProvides_module(self): + import sys + from zope.interface.tests import dummy + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import alsoProvides + from zope.interface.interface import InterfaceClass + + IFoo = InterfaceClass('IFoo') + IBar = InterfaceClass('IBar') + + orig_provides = dummy.__provides__ # pylint:disable=no-member + del dummy.__provides__ # pylint:disable=no-member + self.addCleanup(setattr, dummy, '__provides__', orig_provides) + + directlyProvides(dummy, IFoo) + provides = dummy.__provides__ # pylint:disable=no-member + + self.assertEqual( + repr(provides), + "directlyProvides(sys.modules['zope.interface.tests.dummy'], IFoo)" + ) + + alsoProvides(dummy, IBar) + provides = dummy.__provides__ # pylint:disable=no-member + + self.assertEqual( + repr(provides), + "directlyProvides(sys.modules['zope.interface.tests.dummy'], IFoo, IBar)" + ) + + # If we make this module also provide IFoo and IBar, then the repr + # lists both names. + my_module = sys.modules[__name__] + assert not hasattr(my_module, '__provides__') + + directlyProvides(my_module, IFoo, IBar) + self.addCleanup(delattr, my_module, '__provides__') + self.assertIs(my_module.__provides__, provides) + self.assertEqual( + repr(provides), + "directlyProvides(('zope.interface.tests.dummy', " + "'zope.interface.tests.test_declarations'), " + "IFoo, IBar)" + ) + + def test__repr__module_provides_cached_shared(self): + from zope.interface.interface import InterfaceClass + from zope.interface.declarations import ModuleType + IFoo = InterfaceClass("IFoo") + + inst = self._makeOne(ModuleType, IFoo) + inst._v_module_names += ('some.module',) + inst._v_module_names += ('another.module',) + self.assertEqual( + repr(inst), + "directlyProvides(('some.module', 'another.module'), IFoo)" + ) + + def test__repr__duplicate_names(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo", __module__='mod1') + IFoo2 = InterfaceClass("IFoo", __module__='mod2') + IBaz = InterfaceClass("IBaz") + + inst = self._makeOne(type(self), IFoo, IBaz, IFoo2) + self.assertEqual( + repr(inst), + "directlyProvides(TestProvidesClassRepr, IFoo, IBaz, mod2.IFoo)" + ) + + def test__repr__implementedBy_in_interfaces(self): + from zope.interface import Interface + from zope.interface import implementedBy + class IFoo(Interface): + "Does nothing" + + class Bar: + "Does nothing" + + impl = implementedBy(type(self)) + + inst = self._makeOne(Bar, IFoo, impl) + self.assertEqual( + repr(inst), + 'directlyProvides(Bar, IFoo, classImplements(TestProvidesClassRepr))' + ) + + def test__repr__empty_interfaces(self): + inst = self._makeOne(type(self)) + self.assertEqual( + repr(inst), + 'directlyProvides(TestProvidesClassRepr)', + ) + + def test__repr__non_class(self): + class Object: + __bases__ = () + __str__ = lambda _: self.fail("Should not call str") + + def __repr__(self): + return '<Object>' + inst = self._makeOne(Object()) + self.assertEqual( + repr(inst), + 'directlyProvides(<Object>)', + ) + + def test__repr__providedBy_from_class(self): + from zope.interface.declarations import implementer + from zope.interface.declarations import providedBy + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + + @implementer(IFoo) + class Foo: + pass + + inst = providedBy(Foo()) + self.assertEqual( + repr(inst), + 'classImplements(Foo, IFoo)' + ) + + def test__repr__providedBy_alsoProvides(self): + from zope.interface.declarations import implementer + from zope.interface.declarations import providedBy + from zope.interface.declarations import alsoProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + + @implementer(IFoo) + class Foo: + pass + + foo = Foo() + alsoProvides(foo, IBar) + + inst = providedBy(foo) + self.assertEqual( + repr(inst), + "directlyProvides(Foo, IBar, classImplements(Foo, IFoo))" + ) + + + +class Test_Provides(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import Provides + return Provides(*args, **kw) + + def test_no_cached_spec(self): + from zope.interface import declarations + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + cache = {} + class Foo: + pass + with _Monkey(declarations, InstanceDeclarations=cache): + spec = self._callFUT(Foo, IFoo) + self.assertEqual(list(spec), [IFoo]) + self.assertTrue(cache[(Foo, IFoo)] is spec) + + def test_w_cached_spec(self): + from zope.interface import declarations + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + prior = object() + class Foo: + pass + cache = {(Foo, IFoo): prior} + with _Monkey(declarations, InstanceDeclarations=cache): + spec = self._callFUT(Foo, IFoo) + self.assertTrue(spec is prior) + + +class Test_directlyProvides(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import directlyProvides + return directlyProvides(*args, **kw) + + def test_w_normal_object(self): + from zope.interface.declarations import ProvidesClass + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + obj = Foo() + self._callFUT(obj, IFoo) + self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member + self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member + + def test_w_class(self): + from zope.interface.declarations import ClassProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + self._callFUT(Foo, IFoo) + self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member + self.assertEqual(list(Foo.__provides__), [IFoo]) # pylint:disable=no-member + + def test_w_classless_object(self): + from zope.interface.declarations import ProvidesClass + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + the_dict = {} + class Foo: + def __getattribute__(self, name): + # Emulate object w/o any class + if name == '__class__': + return None + raise NotImplementedError(name) + def __setattr__(self, name, value): + the_dict[name] = value + obj = Foo() + self._callFUT(obj, IFoo) + self.assertIsInstance(the_dict['__provides__'], ProvidesClass) + self.assertEqual(list(the_dict['__provides__']), [IFoo]) + + +class Test_alsoProvides(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import alsoProvides + return alsoProvides(*args, **kw) + + def test_wo_existing_provides(self): + from zope.interface.declarations import ProvidesClass + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + obj = Foo() + self._callFUT(obj, IFoo) + self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member + self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member + + def test_w_existing_provides(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import ProvidesClass + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + class Foo: + pass + obj = Foo() + directlyProvides(obj, IFoo) + self._callFUT(obj, IBar) + self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member + self.assertEqual(list(obj.__provides__), [IFoo, IBar]) # pylint:disable=no-member + + +class Test_noLongerProvides(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import noLongerProvides + return noLongerProvides(*args, **kw) + + def test_wo_existing_provides(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + obj = Foo() + self._callFUT(obj, IFoo) + self.assertEqual(list(obj.__provides__), []) # pylint:disable=no-member + + def test_w_existing_provides_hit(self): + from zope.interface.declarations import directlyProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + obj = Foo() + directlyProvides(obj, IFoo) + self._callFUT(obj, IFoo) + self.assertEqual(list(obj.__provides__), []) # pylint:disable=no-member + + def test_w_existing_provides_miss(self): + from zope.interface.declarations import directlyProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + class Foo: + pass + obj = Foo() + directlyProvides(obj, IFoo) + self._callFUT(obj, IBar) + self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member + + def test_w_iface_implemented_by_class(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @implementer(IFoo) + class Foo: + pass + obj = Foo() + self.assertRaises(ValueError, self._callFUT, obj, IFoo) + + +class ClassProvidesBaseFallbackTests(unittest.TestCase): + + def _getTargetClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations import ClassProvidesBaseFallback + return ClassProvidesBaseFallback + + def _makeOne(self, klass, implements): + # Don't instantiate directly: the C version can't have attributes + # assigned. + class Derived(self._getTargetClass()): + def __init__(self, k, i): + self._cls = k + self._implements = i + return Derived(klass, implements) + + def test_w_same_class_via_class(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + cpbp = Foo.__provides__ = self._makeOne(Foo, IFoo) + self.assertTrue(Foo.__provides__ is cpbp) + + def test_w_same_class_via_instance(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + foo = Foo() + Foo.__provides__ = self._makeOne(Foo, IFoo) + self.assertIs(foo.__provides__, IFoo) + + def test_w_different_class(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + class Bar(Foo): + pass + bar = Bar() + Foo.__provides__ = self._makeOne(Foo, IFoo) + self.assertRaises(AttributeError, getattr, Bar, '__provides__') + self.assertRaises(AttributeError, getattr, bar, '__provides__') + + +class ClassProvidesBaseTests(OptimizationTestMixin, + ClassProvidesBaseFallbackTests): + # Repeat tests for C optimizations + + def _getTargetClass(self): + from zope.interface.declarations import ClassProvidesBase + return ClassProvidesBase + + def _getFallbackClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations import ClassProvidesBaseFallback + return ClassProvidesBaseFallback + + +class ClassProvidesTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import ClassProvides + return ClassProvides + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_w_simple_metaclass(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + @implementer(IFoo) + class Foo: + pass + cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar) + self.assertTrue(Foo.__provides__ is cp) + self.assertEqual(list(Foo().__provides__), [IFoo]) + + def test___reduce__(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + @implementer(IFoo) + class Foo: + pass + cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar) + self.assertEqual(cp.__reduce__(), + (type(cp), (Foo, type(Foo), IBar))) + + +class ClassProvidesStrictTests(ClassProvidesTests): + # Tests that require the strict C3 resolution order. + + def _getTargetClass(self): + ClassProvides = super()._getTargetClass() + class StrictClassProvides(ClassProvides): + def _do_calculate_ro(self, base_mros): + return ClassProvides._do_calculate_ro(self, base_mros=base_mros, strict=True) + return StrictClassProvides + + def test_overlapping_interfaces_corrected(self): + # Giving ClassProvides(cls, metaclass, IFace), where IFace is already + # provided by metacls, doesn't produce invalid resolution orders. + from zope.interface import implementedBy + from zope.interface import Interface + from zope.interface import implementer + + class IBase(Interface): + pass + + @implementer(IBase) + class metaclass(type): + pass + + cls = metaclass( + 'cls', + (object,), + {} + ) + + spec = self._makeOne(cls, metaclass, IBase) + self.assertEqual(spec.__sro__, ( + spec, + implementedBy(metaclass), + IBase, + implementedBy(type), + implementedBy(object), + Interface + )) + + +class TestClassProvidesRepr(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import ClassProvides + return ClassProvides + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test__repr__empty(self): + inst = self._makeOne(type(self), type) + self.assertEqual( + repr(inst), + "directlyProvides(TestClassProvidesRepr)" + ) + + def test__repr__providing_one(self): + from zope.interface import Interface + class IFoo(Interface): + "Does nothing" + + inst = self._makeOne(type(self), type, IFoo) + self.assertEqual( + repr(inst), + "directlyProvides(TestClassProvidesRepr, IFoo)" + ) + + def test__repr__duplicate_names(self): + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo", __module__='mod1') + IFoo2 = InterfaceClass("IFoo", __module__='mod2') + IBaz = InterfaceClass("IBaz") + + inst = self._makeOne(type(self), type, IFoo, IBaz, IFoo2) + self.assertEqual( + repr(inst), + "directlyProvides(TestClassProvidesRepr, IFoo, IBaz, mod2.IFoo)" + ) + + def test__repr__implementedBy(self): + from zope.interface.declarations import implementer + from zope.interface.declarations import implementedBy + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + + @implementer(IFoo) + class Foo: + pass + + inst = implementedBy(Foo) + self.assertEqual( + repr(inst), + 'classImplements(Foo, IFoo)' + ) + + def test__repr__implementedBy_generic_callable(self): + from zope.interface.declarations import implementedBy + # We can't get a __name__ by default, so we get a + # module name and a question mark + class Callable: + def __call__(self): + return self + + inst = implementedBy(Callable()) + self.assertEqual( + repr(inst), + 'classImplements({}.?)'.format(__name__) + ) + + c = Callable() + c.__name__ = 'Callable' + inst = implementedBy(c) + self.assertEqual( + repr(inst), + 'classImplements(Callable)' + ) + + +class Test_directlyProvidedBy(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.declarations import directlyProvidedBy + return directlyProvidedBy(*args, **kw) + + def test_wo_declarations_in_class_or_instance(self): + class Foo: + pass + foo = Foo() + self.assertEqual(list(self._callFUT(foo)), []) + + def test_w_declarations_in_class_but_not_instance(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @implementer(IFoo) + class Foo: + pass + foo = Foo() + self.assertEqual(list(self._callFUT(foo)), []) + + def test_w_declarations_in_instance_but_not_class(self): + from zope.interface.declarations import directlyProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + foo = Foo() + directlyProvides(foo, IFoo) + self.assertEqual(list(self._callFUT(foo)), [IFoo]) + + def test_w_declarations_in_instance_and_class(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + @implementer(IFoo) + class Foo: + pass + foo = Foo() + directlyProvides(foo, IBar) + self.assertEqual(list(self._callFUT(foo)), [IBar]) + + +class Test_provider(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.declarations import provider + return provider + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_w_class(self): + from zope.interface.declarations import ClassProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @self._makeOne(IFoo) + class Foo: + pass + self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member + self.assertEqual(list(Foo.__provides__), [IFoo]) # pylint:disable=no-member + + +class Test_moduleProvides(unittest.TestCase): + # pylint:disable=exec-used + + def test_called_from_function(self): + from zope.interface.declarations import moduleProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + globs = {'__name__': 'zope.interface.tests.foo', + 'moduleProvides': moduleProvides, 'IFoo': IFoo} + locs = {} + CODE = "\n".join([ + 'def foo():', + ' moduleProvides(IFoo)' + ]) + exec(CODE, globs, locs) + foo = locs['foo'] + self.assertRaises(TypeError, foo) + + def test_called_from_class(self): + from zope.interface.declarations import moduleProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + globs = {'__name__': 'zope.interface.tests.foo', + 'moduleProvides': moduleProvides, 'IFoo': IFoo} + locs = {} + CODE = "\n".join([ + 'class Foo(object):', + ' moduleProvides(IFoo)', + ]) + with self.assertRaises(TypeError): + exec(CODE, globs, locs) + + def test_called_once_from_module_scope(self): + from zope.interface.declarations import moduleProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + globs = {'__name__': 'zope.interface.tests.foo', + 'moduleProvides': moduleProvides, 'IFoo': IFoo} + CODE = "\n".join([ + 'moduleProvides(IFoo)', + ]) + exec(CODE, globs) + spec = globs['__provides__'] + self.assertEqual(list(spec), [IFoo]) + + def test_called_twice_from_module_scope(self): + from zope.interface.declarations import moduleProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + globs = {'__name__': 'zope.interface.tests.foo', + 'moduleProvides': moduleProvides, 'IFoo': IFoo} + + CODE = "\n".join([ + 'moduleProvides(IFoo)', + 'moduleProvides(IFoo)', + ]) + with self.assertRaises(TypeError): + exec(CODE, globs) + + +class Test_getObjectSpecificationFallback(unittest.TestCase): + + def _getFallbackClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations import getObjectSpecificationFallback + return getObjectSpecificationFallback + + _getTargetClass = _getFallbackClass + + def _callFUT(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_wo_existing_provides_classless(self): + the_dict = {} + class Foo: + def __getattribute__(self, name): + # Emulate object w/o any class + if name == '__class__': + raise AttributeError(name) + try: + return the_dict[name] + except KeyError: + raise AttributeError(name) + def __setattr__(self, name, value): + raise NotImplementedError() + foo = Foo() + spec = self._callFUT(foo) + self.assertEqual(list(spec), []) + + def test_existing_provides_is_spec(self): + from zope.interface.declarations import directlyProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + def foo(): + raise NotImplementedError() + directlyProvides(foo, IFoo) + spec = self._callFUT(foo) + self.assertIs(spec, foo.__provides__) # pylint:disable=no-member + + def test_existing_provides_is_not_spec(self): + def foo(): + raise NotImplementedError() + foo.__provides__ = object() # not a valid spec + spec = self._callFUT(foo) + self.assertEqual(list(spec), []) + + def test_existing_provides(self): + from zope.interface.declarations import directlyProvides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + foo = Foo() + directlyProvides(foo, IFoo) + spec = self._callFUT(foo) + self.assertEqual(list(spec), [IFoo]) + + def test_wo_provides_on_class_w_implements(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @implementer(IFoo) + class Foo: + pass + foo = Foo() + spec = self._callFUT(foo) + self.assertEqual(list(spec), [IFoo]) + + def test_wo_provides_on_class_wo_implements(self): + class Foo: + pass + foo = Foo() + spec = self._callFUT(foo) + self.assertEqual(list(spec), []) + + def test_catches_only_AttributeError_on_provides(self): + MissingSomeAttrs.test_raises(self, self._callFUT, expected_missing='__provides__') + + def test_catches_only_AttributeError_on_class(self): + MissingSomeAttrs.test_raises(self, self._callFUT, expected_missing='__class__', + __provides__=None) + + def test_raises_AttributeError_when_provides_fails_type_check_AttributeError(self): + # isinstance(ob.__provides__, SpecificationBase) is not + # protected inside any kind of block. + + class Foo: + __provides__ = MissingSomeAttrs(AttributeError) + + # isinstance() ignores AttributeError on __class__ + self._callFUT(Foo()) + + def test_raises_AttributeError_when_provides_fails_type_check_RuntimeError(self): + # isinstance(ob.__provides__, SpecificationBase) is not + # protected inside any kind of block. + class Foo: + __provides__ = MissingSomeAttrs(RuntimeError) + + with self.assertRaises(RuntimeError) as exc: + self._callFUT(Foo()) + + self.assertEqual('__class__', exc.exception.args[0]) + + +class Test_getObjectSpecification(Test_getObjectSpecificationFallback, + OptimizationTestMixin): + # Repeat tests for C optimizations + + def _getTargetClass(self): + from zope.interface.declarations import getObjectSpecification + return getObjectSpecification + + +class Test_providedByFallback(unittest.TestCase): + + def _getFallbackClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations import providedByFallback + return providedByFallback + + _getTargetClass = _getFallbackClass + + def _callFUT(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_wo_providedBy_on_class_wo_implements(self): + class Foo: + pass + foo = Foo() + spec = self._callFUT(foo) + self.assertEqual(list(spec), []) + + def test_w_providedBy_valid_spec(self): + from zope.interface.declarations import Provides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + foo = Foo() + foo.__providedBy__ = Provides(Foo, IFoo) + spec = self._callFUT(foo) + self.assertEqual(list(spec), [IFoo]) + + def test_w_providedBy_invalid_spec(self): + class Foo: + pass + foo = Foo() + foo.__providedBy__ = object() + spec = self._callFUT(foo) + self.assertEqual(list(spec), []) + + def test_w_providedBy_invalid_spec_class_w_implements(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @implementer(IFoo) + class Foo: + pass + foo = Foo() + foo.__providedBy__ = object() + spec = self._callFUT(foo) + self.assertEqual(list(spec), [IFoo]) + + def test_w_providedBy_invalid_spec_w_provides_no_provides_on_class(self): + class Foo: + pass + foo = Foo() + foo.__providedBy__ = object() + expected = foo.__provides__ = object() + spec = self._callFUT(foo) + self.assertTrue(spec is expected) + + def test_w_providedBy_invalid_spec_w_provides_diff_provides_on_class(self): + class Foo: + pass + foo = Foo() + foo.__providedBy__ = object() + expected = foo.__provides__ = object() + Foo.__provides__ = object() + spec = self._callFUT(foo) + self.assertTrue(spec is expected) + + def test_w_providedBy_invalid_spec_w_provides_same_provides_on_class(self): + from zope.interface.declarations import implementer + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + @implementer(IFoo) + class Foo: + pass + foo = Foo() + foo.__providedBy__ = object() + foo.__provides__ = Foo.__provides__ = object() + spec = self._callFUT(foo) + self.assertEqual(list(spec), [IFoo]) + + def test_super_when_base_implements_interface(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + derived = Derived() + self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase]) + + sup = super(Derived, derived) + fut = self._callFUT(sup) + self.assertIsNone(fut._dependents) + self.assertEqual(list(fut), [IBase]) + + def test_super_when_base_doesnt_implement_interface(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + derived = Derived() + self.assertEqual(list(self._callFUT(derived)), [IDerived]) + + sup = super(Derived, derived) + self.assertEqual(list(self._callFUT(sup)), []) + + def test_super_when_base_is_object(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IDerived) + class Derived: + pass + + derived = Derived() + self.assertEqual(list(self._callFUT(derived)), [IDerived]) + + sup = super(Derived, derived) + fut = self._callFUT(sup) + self.assertIsNone(fut._dependents) + self.assertEqual(list(fut), []) + + def test_super_when_object_directly_provides(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + from zope.interface.declarations import directlyProvides + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + @implementer(IBase) + class Base: + pass + + class Derived(Base): + pass + + derived = Derived() + self.assertEqual(list(self._callFUT(derived)), [IBase]) + + directlyProvides(derived, IDerived) + self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase]) + + sup = super(Derived, derived) + fut = self._callFUT(sup) + self.assertIsNone(fut._dependents) + self.assertEqual(list(fut), [IBase]) + + def test_super_multi_level_multi_inheritance(self): + from zope.interface.declarations import implementer + from zope.interface import Interface + + class IBase(Interface): + pass + + class IM1(Interface): + pass + + class IM2(Interface): + pass + + class IDerived(IBase): + pass + + class IUnrelated(Interface): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IM1) + class M1(Base): + pass + + @implementer(IM2) + class M2(Base): + pass + + @implementer(IDerived, IUnrelated) + class Derived(M1, M2): + pass + + d = Derived() + sd = super(Derived, d) + sm1 = super(M1, d) + sm2 = super(M2, d) + + self.assertEqual(list(self._callFUT(d)), + [IDerived, IUnrelated, IM1, IBase, IM2]) + self.assertEqual(list(self._callFUT(sd)), + [IM1, IBase, IM2]) + self.assertEqual(list(self._callFUT(sm1)), + [IM2, IBase]) + self.assertEqual(list(self._callFUT(sm2)), + [IBase]) + + def test_catches_only_AttributeError_on_providedBy(self): + MissingSomeAttrs.test_raises(self, self._callFUT, + expected_missing='__providedBy__', + __class__=object) + + def test_catches_only_AttributeError_on_class(self): + # isinstance() tries to get the __class__, which is non-obvious, + # so it must be protected too. + MissingSomeAttrs.test_raises( + self, self._callFUT, expected_missing='__class__') + + + +class Test_providedBy(Test_providedByFallback, + OptimizationTestMixin): + # Repeat tests for C optimizations + + def _getTargetClass(self): + from zope.interface.declarations import providedBy + return providedBy + + +class ObjectSpecificationDescriptorFallbackTests(unittest.TestCase): + + def _getFallbackClass(self): + # pylint:disable=no-name-in-module + from zope.interface.declarations \ + import ObjectSpecificationDescriptorFallback + return ObjectSpecificationDescriptorFallback + + _getTargetClass = _getFallbackClass + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_accessed_via_class(self): + from zope.interface.declarations import Provides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + class Foo: + pass + Foo.__provides__ = Provides(Foo, IFoo) + Foo.__providedBy__ = self._makeOne() + self.assertEqual(list(Foo.__providedBy__), [IFoo]) + + def test_accessed_via_inst_wo_provides(self): + from zope.interface.declarations import implementer + from zope.interface.declarations import Provides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + @implementer(IFoo) + class Foo: + pass + Foo.__provides__ = Provides(Foo, IBar) + Foo.__providedBy__ = self._makeOne() + foo = Foo() + self.assertEqual(list(foo.__providedBy__), [IFoo]) + + def test_accessed_via_inst_w_provides(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import implementer + from zope.interface.declarations import Provides + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass("IFoo") + IBar = InterfaceClass("IBar") + IBaz = InterfaceClass("IBaz") + @implementer(IFoo) + class Foo: + pass + Foo.__provides__ = Provides(Foo, IBar) + Foo.__providedBy__ = self._makeOne() + foo = Foo() + directlyProvides(foo, IBaz) + self.assertEqual(list(foo.__providedBy__), [IBaz, IFoo]) + + def test_arbitrary_exception_accessing_provides_not_caught(self): + + class MyException(Exception): + pass + + class Foo: + __providedBy__ = self._makeOne() + + @property + def __provides__(self): + raise MyException + + foo = Foo() + with self.assertRaises(MyException): + getattr(foo, '__providedBy__') + + def test_AttributeError_accessing_provides_caught(self): + + class MyException(Exception): + pass + + class Foo: + __providedBy__ = self._makeOne() + + @property + def __provides__(self): + raise AttributeError + + foo = Foo() + provided = getattr(foo, '__providedBy__') + self.assertIsNotNone(provided) + + def test_None_in__provides__overrides(self): + from zope.interface import Interface + from zope.interface import implementer + + class IFoo(Interface): + pass + + @implementer(IFoo) + class Foo: + + @property + def __provides__(self): + return None + + Foo.__providedBy__ = self._makeOne() + + provided = getattr(Foo(), '__providedBy__') + self.assertIsNone(provided) + +class ObjectSpecificationDescriptorTests( + ObjectSpecificationDescriptorFallbackTests, + OptimizationTestMixin): + # Repeat tests for C optimizations + + def _getTargetClass(self): + from zope.interface.declarations import ObjectSpecificationDescriptor + return ObjectSpecificationDescriptor + + +# Test _normalizeargs through its callers. + + +class _Monkey: + # context-manager for replacing module names in the scope of a test. + def __init__(self, module, **kw): + self.module = module + self.to_restore = {key: getattr(module, key) for key in kw} + for key, value in kw.items(): + setattr(module, key, value) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + for key, value in self.to_restore.items(): + setattr(self.module, key, value) + + +class _MonkeyDict: + # context-manager for restoring a dict w/in a module in the scope of a test. + def __init__(self, module, attrname, **kw): + self.module = module + self.target = getattr(module, attrname) + self.to_restore = self.target.copy() + self.target.clear() + self.target.update(kw) + + def __enter__(self): + return self.target + + def __exit__(self, exc_type, exc_val, exc_tb): + self.target.clear() + self.target.update(self.to_restore) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_document.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_document.py new file mode 100644 index 00000000..3e6dddd8 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_document.py @@ -0,0 +1,505 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Documentation tests. +""" +import unittest + + +class Test_asStructuredText(unittest.TestCase): + + def _callFUT(self, iface): + from zope.interface.document import asStructuredText + return asStructuredText(iface) + + def test_asStructuredText_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "INoDocstring", + " Attributes:", + " Methods:", + "" + ]) + class INoDocstring(Interface): + pass + self.assertEqual(self._callFUT(INoDocstring), EXPECTED) + + def test_asStructuredText_empty_with_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IEmpty", + " This is an empty interface.", + " Attributes:", + " Methods:", + "" + ]) + class IEmpty(Interface): + """ This is an empty interface. + """ + self.assertEqual(self._callFUT(IEmpty), EXPECTED) + + def test_asStructuredText_empty_with_multiline_docstring(self): + from zope.interface import Interface + EXPECTED = '\n'.join([ + "IEmpty", + "", + " This is an empty interface.", + " ", + (" It can be used to annotate any class or object, " + "because it promises"), + " nothing.", + "", + " Attributes:", + "", + " Methods:", + "", + "" + ]) + class IEmpty(Interface): + """ This is an empty interface. + + It can be used to annotate any class or object, because it promises + nothing. + """ + self.assertEqual(self._callFUT(IEmpty), EXPECTED) + + def test_asStructuredText_with_attribute_no_docstring(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasAttribute", + " This interface has an attribute.", + " Attributes:", + " an_attribute -- no documentation", + " Methods:", + "" + ]) + class IHasAttribute(Interface): + """ This interface has an attribute. + """ + an_attribute = Attribute('an_attribute') + + self.assertEqual(self._callFUT(IHasAttribute), EXPECTED) + + def test_asStructuredText_with_attribute_with_docstring(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasAttribute", + " This interface has an attribute.", + " Attributes:", + " an_attribute -- This attribute is documented.", + " Methods:", + "" + ]) + class IHasAttribute(Interface): + """ This interface has an attribute. + """ + an_attribute = Attribute('an_attribute', + 'This attribute is documented.') + + self.assertEqual(self._callFUT(IHasAttribute), EXPECTED) + + def test_asStructuredText_with_method_no_args_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasMethod", + " This interface has a method.", + " Attributes:", + " Methods:", + " aMethod() -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asStructuredText_with_method_positional_args_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasMethod", + " This interface has a method.", + " Attributes:", + " Methods:", + " aMethod(first, second) -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asStructuredText_with_method_starargs_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasMethod", + " This interface has a method.", + " Attributes:", + " Methods:", + " aMethod(first, second, *rest) -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second, *rest): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asStructuredText_with_method_kwargs_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasMethod", + " This interface has a method.", + " Attributes:", + " Methods:", + " aMethod(first, second, **kw) -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second, **kw): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asStructuredText_with_method_with_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IHasMethod", + " This interface has a method.", + " Attributes:", + " Methods:", + " aMethod() -- This method is documented.", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(): + """This method is documented. + """ + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asStructuredText_derived_ignores_base(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "IDerived", + " IDerived doc", + " This interface extends:", + " o IBase", + " Attributes:", + " attr1 -- no documentation", + " attr2 -- attr2 doc", + " Methods:", + " method3() -- method3 doc", + " method4() -- no documentation", + " method5() -- method5 doc", + "", + ]) + + class IBase(Interface): + def method1(): + """docstring""" + def method2(): + """docstring""" + + class IDerived(IBase): + "IDerived doc" + attr1 = Attribute('attr1') + attr2 = Attribute('attr2', 'attr2 doc') + + def method3(): + "method3 doc" + def method4(): + pass # pragma: no cover + def method5(): + "method5 doc" + + self.assertEqual(self._callFUT(IDerived), EXPECTED) + + +class Test_asReStructuredText(unittest.TestCase): + + def _callFUT(self, iface): + from zope.interface.document import asReStructuredText + return asReStructuredText(iface) + + def test_asReStructuredText_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``INoDocstring``", + " Attributes:", + " Methods:", + "" + ]) + class INoDocstring(Interface): + pass + self.assertEqual(self._callFUT(INoDocstring), EXPECTED) + + def test_asReStructuredText_empty_with_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IEmpty``", + " This is an empty interface.", + " Attributes:", + " Methods:", + "" + ]) + class IEmpty(Interface): + """ This is an empty interface. + """ + self.assertEqual(self._callFUT(IEmpty), EXPECTED) + + def test_asReStructuredText_empty_with_multiline_docstring(self): + from zope.interface import Interface + EXPECTED = '\n'.join([ + "``IEmpty``", + "", + " This is an empty interface.", + " ", + (" It can be used to annotate any class or object, " + "because it promises"), + " nothing.", + "", + " Attributes:", + "", + " Methods:", + "", + "" + ]) + class IEmpty(Interface): + """ This is an empty interface. + + It can be used to annotate any class or object, because it promises + nothing. + """ + self.assertEqual(self._callFUT(IEmpty), EXPECTED) + + def test_asReStructuredText_with_attribute_no_docstring(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasAttribute``", + " This interface has an attribute.", + " Attributes:", + " ``an_attribute`` -- no documentation", + " Methods:", + "" + ]) + class IHasAttribute(Interface): + """ This interface has an attribute. + """ + an_attribute = Attribute('an_attribute') + + self.assertEqual(self._callFUT(IHasAttribute), EXPECTED) + + def test_asReStructuredText_with_attribute_with_docstring(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasAttribute``", + " This interface has an attribute.", + " Attributes:", + " ``an_attribute`` -- This attribute is documented.", + " Methods:", + "" + ]) + class IHasAttribute(Interface): + """ This interface has an attribute. + """ + an_attribute = Attribute('an_attribute', + 'This attribute is documented.') + + self.assertEqual(self._callFUT(IHasAttribute), EXPECTED) + + def test_asReStructuredText_with_method_no_args_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasMethod``", + " This interface has a method.", + " Attributes:", + " Methods:", + " ``aMethod()`` -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asReStructuredText_with_method_positional_args_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasMethod``", + " This interface has a method.", + " Attributes:", + " Methods:", + " ``aMethod(first, second)`` -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asReStructuredText_with_method_starargs_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasMethod``", + " This interface has a method.", + " Attributes:", + " Methods:", + " ``aMethod(first, second, *rest)`` -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second, *rest): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asReStructuredText_with_method_kwargs_no_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasMethod``", + " This interface has a method.", + " Attributes:", + " Methods:", + " ``aMethod(first, second, **kw)`` -- no documentation", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(first, second, **kw): + pass # pragma: no cover + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asReStructuredText_with_method_with_docstring(self): + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IHasMethod``", + " This interface has a method.", + " Attributes:", + " Methods:", + " ``aMethod()`` -- This method is documented.", + "" + ]) + class IHasMethod(Interface): + """ This interface has a method. + """ + def aMethod(): + """This method is documented. + """ + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + def test_asReStructuredText_derived_ignores_base(self): + from zope.interface import Attribute + from zope.interface import Interface + EXPECTED = '\n\n'.join([ + "``IDerived``", + " IDerived doc", + " This interface extends:", + " o ``IBase``", + " Attributes:", + " ``attr1`` -- no documentation", + " ``attr2`` -- attr2 doc", + " Methods:", + " ``method3()`` -- method3 doc", + " ``method4()`` -- no documentation", + " ``method5()`` -- method5 doc", + "", + ]) + + class IBase(Interface): + def method1(): + pass # pragma: no cover + def method2(): + pass # pragma: no cover + + class IDerived(IBase): + "IDerived doc" + attr1 = Attribute('attr1') + attr2 = Attribute('attr2', 'attr2 doc') + + def method3(): + "method3 doc" + def method4(): + pass # pragma: no cover + def method5(): + "method5 doc" + + self.assertEqual(self._callFUT(IDerived), EXPECTED) + + +class Test__justify_and_indent(unittest.TestCase): + + def _callFUT(self, text, level, **kw): + from zope.interface.document import _justify_and_indent + return _justify_and_indent(text, level, **kw) + + def test_simple_level_0(self): + LINES = ['Three blind mice', 'See how they run'] + text = '\n'.join(LINES) + self.assertEqual(self._callFUT(text, 0), text) + + def test_simple_level_1(self): + LINES = ['Three blind mice', 'See how they run'] + text = '\n'.join(LINES) + self.assertEqual(self._callFUT(text, 1), + '\n'.join([' ' + line for line in LINES])) + + def test_simple_level_2(self): + LINES = ['Three blind mice', 'See how they run'] + text = '\n'.join(LINES) + self.assertEqual(self._callFUT(text, 1), + '\n'.join([' ' + line for line in LINES])) + + def test_simple_w_CRLF(self): + LINES = ['Three blind mice', 'See how they run'] + text = '\r\n'.join(LINES) + self.assertEqual(self._callFUT(text, 1), + '\n'.join([' ' + line for line in LINES])) + + def test_with_munge(self): + TEXT = ("This is a piece of text longer than 15 characters, \n" + "and split across multiple lines.") + EXPECTED = (" This is a piece\n" + " of text longer\n" + " than 15 characters,\n" + " and split across\n" + " multiple lines.\n" + " ") + self.assertEqual(self._callFUT(TEXT, 1, munge=1, width=15), EXPECTED) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_element.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_element.py new file mode 100644 index 00000000..eb003cda --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_element.py @@ -0,0 +1,31 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test Element meta-class. +""" + +import unittest +from zope.interface.interface import Element + +class TestElement(unittest.TestCase): + + def test_taggedValues(self): + """Test that we can update tagged values of more than one element + """ + + e1 = Element("foo") + e2 = Element("bar") + e1.setTaggedValue("x", 1) + e2.setTaggedValue("x", 2) + self.assertEqual(e1.getTaggedValue("x"), 1) + self.assertEqual(e2.getTaggedValue("x"), 2) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_exceptions.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_exceptions.py new file mode 100644 index 00000000..dc22c71d --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_exceptions.py @@ -0,0 +1,184 @@ +############################################################################## +# +# Copyright (c) 2010 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" zope.interface.exceptions unit tests +""" +import unittest + +def _makeIface(): + from zope.interface import Interface + class IDummy(Interface): + pass + return IDummy + +class DoesNotImplementTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.exceptions import DoesNotImplement + return DoesNotImplement + + def _makeOne(self, *args): + iface = _makeIface() + return self._getTargetClass()(iface, *args) + + def test___str__(self): + dni = self._makeOne() + self.assertEqual( + str(dni), + "An object has failed to implement interface " + "zope.interface.tests.test_exceptions.IDummy: " + "Does not declaratively implement the interface." + ) + + def test___str__w_candidate(self): + dni = self._makeOne('candidate') + self.assertEqual( + str(dni), + "The object 'candidate' has failed to implement interface " + "zope.interface.tests.test_exceptions.IDummy: " + "Does not declaratively implement the interface." + ) + + +class BrokenImplementationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.exceptions import BrokenImplementation + return BrokenImplementation + + def _makeOne(self, *args): + iface = _makeIface() + return self._getTargetClass()(iface, 'missing', *args) + + def test___str__(self): + dni = self._makeOne() + self.assertEqual( + str(dni), + 'An object has failed to implement interface ' + 'zope.interface.tests.test_exceptions.IDummy: ' + "The 'missing' attribute was not provided.") + + def test___str__w_candidate(self): + dni = self._makeOne('candidate') + self.assertEqual( + str(dni), + 'The object \'candidate\' has failed to implement interface ' + 'zope.interface.tests.test_exceptions.IDummy: ' + "The 'missing' attribute was not provided.") + + +def broken_function(): + """ + This is a global function with a simple argument list. + + It exists to be able to report the same information when + formatting signatures. + """ + + +class BrokenMethodImplementationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.exceptions import BrokenMethodImplementation + return BrokenMethodImplementation + + message = 'I said so' + + def _makeOne(self, *args): + return self._getTargetClass()('aMethod', self.message, *args) + + def test___str__(self): + dni = self._makeOne() + self.assertEqual( + str(dni), + "An object has failed to implement interface <Unknown>: " + "The contract of 'aMethod' is violated because I said so." + ) + + def test___str__w_candidate_no_implementation(self): + dni = self._makeOne('some_function', '<IFoo>', 'candidate') + self.assertEqual( + str(dni), + "The object 'candidate' has failed to implement interface <IFoo>: " + "The contract of 'aMethod' is violated because I said so." + ) + + def test___str__w_candidate_w_implementation(self): + self.message = 'implementation is wonky' + dni = self._makeOne(broken_function, '<IFoo>', 'candidate') + self.assertEqual( + str(dni), + "The object 'candidate' has failed to implement interface <IFoo>: " + "The contract of 'aMethod' is violated because " + "'broken_function()' is wonky." + ) + + def test___str__w_candidate_w_implementation_not_callable(self): + self.message = 'implementation is not callable' + dni = self._makeOne(42, '<IFoo>', 'candidate') + self.assertEqual( + str(dni), + "The object 'candidate' has failed to implement interface <IFoo>: " + "The contract of 'aMethod' is violated because " + "'42' is not callable." + ) + + def test___repr__w_candidate(self): + dni = self._makeOne(None, 'candidate') + self.assertEqual( + repr(dni), + "BrokenMethodImplementation('aMethod', 'I said so', None, 'candidate')" + ) + + +class MultipleInvalidTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.exceptions import MultipleInvalid + return MultipleInvalid + + def _makeOne(self, excs): + iface = _makeIface() + return self._getTargetClass()(iface, 'target', excs) + + def test__str__(self): + from zope.interface.exceptions import BrokenMethodImplementation + excs = [ + BrokenMethodImplementation('aMethod', 'I said so'), + Exception("Regular exception") + ] + dni = self._makeOne(excs) + self.assertEqual( + str(dni), + "The object 'target' has failed to implement interface " + "zope.interface.tests.test_exceptions.IDummy:\n" + " The contract of 'aMethod' is violated because I said so\n" + " Regular exception" + ) + + def test__repr__(self): + from zope.interface.exceptions import BrokenMethodImplementation + excs = [ + BrokenMethodImplementation('aMethod', 'I said so'), + # Use multiple arguments to normalize repr; versions of Python + # prior to 3.7 add a trailing comma if there's just one. + Exception("Regular", "exception") + ] + dni = self._makeOne(excs) + self.assertEqual( + repr(dni), + "MultipleInvalid(<InterfaceClass zope.interface.tests.test_exceptions.IDummy>," + " 'target'," + " (BrokenMethodImplementation('aMethod', 'I said so')," + " Exception('Regular', 'exception')))" + ) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interface.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interface.py new file mode 100644 index 00000000..b3a440e6 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interface.py @@ -0,0 +1,2638 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test Interface implementation +""" +# Things we let slide because it's a test +# pylint:disable=protected-access,blacklisted-name,attribute-defined-outside-init +# pylint:disable=too-many-public-methods,too-many-lines,abstract-method +# pylint:disable=redefined-builtin,signature-differs,arguments-differ +# Things you get inheriting from Interface +# pylint:disable=inherit-non-class,no-self-argument,no-method-argument +# Things you get using methods of an Interface 'subclass' +# pylint:disable=no-value-for-parameter +import unittest + +from zope.interface.tests import MissingSomeAttrs +from zope.interface.tests import OptimizationTestMixin +from zope.interface.tests import CleanUp + +_marker = object() + + +class Test_invariant(unittest.TestCase): + + def test_w_single(self): + from zope.interface.interface import invariant + from zope.interface.interface import TAGGED_DATA + + def _check(*args, **kw): + raise NotImplementedError() + + class Foo: + invariant(_check) + + self.assertEqual(getattr(Foo, TAGGED_DATA, None), + {'invariants': [_check]}) + + def test_w_multiple(self): + from zope.interface.interface import invariant + from zope.interface.interface import TAGGED_DATA + + def _check(*args, **kw): + raise NotImplementedError() + + def _another_check(*args, **kw): + raise NotImplementedError() + + class Foo: + invariant(_check) + invariant(_another_check) + + self.assertEqual(getattr(Foo, TAGGED_DATA, None), + {'invariants': [_check, _another_check]}) + + +class Test_taggedValue(unittest.TestCase): + + def test_w_single(self): + from zope.interface.interface import taggedValue + from zope.interface.interface import TAGGED_DATA + + class Foo: + taggedValue('bar', ['baz']) + + self.assertEqual(getattr(Foo, TAGGED_DATA, None), + {'bar': ['baz']}) + + def test_w_multiple(self): + from zope.interface.interface import taggedValue + from zope.interface.interface import TAGGED_DATA + + class Foo: + taggedValue('bar', ['baz']) + taggedValue('qux', 'spam') + + self.assertEqual(getattr(Foo, TAGGED_DATA, None), + {'bar': ['baz'], 'qux': 'spam'}) + + def test_w_multiple_overwriting(self): + from zope.interface.interface import taggedValue + from zope.interface.interface import TAGGED_DATA + + class Foo: + taggedValue('bar', ['baz']) + taggedValue('qux', 'spam') + taggedValue('bar', 'frob') + + self.assertEqual(getattr(Foo, TAGGED_DATA, None), + {'bar': 'frob', 'qux': 'spam'}) + + +class ElementTests(unittest.TestCase): + + DEFAULT_NAME = 'AnElement' + + def _getTargetClass(self): + from zope.interface.interface import Element + return Element + + def _makeOne(self, name=None): + if name is None: + name = self.DEFAULT_NAME + return self._getTargetClass()(name) + + def test_ctor_defaults(self): + element = self._makeOne() + self.assertEqual(element.__name__, self.DEFAULT_NAME) + self.assertEqual(element.getName(), self.DEFAULT_NAME) + self.assertEqual(element.__doc__, '') + self.assertEqual(element.getDoc(), '') + self.assertEqual(list(element.getTaggedValueTags()), []) + + def test_ctor_no_doc_space_in_name(self): + element = self._makeOne('An Element') + self.assertEqual(element.__name__, None) + self.assertEqual(element.__doc__, 'An Element') + + def test_getTaggedValue_miss(self): + element = self._makeOne() + self.assertRaises(KeyError, element.getTaggedValue, 'nonesuch') + + def test_getDirectTaggedValueTags(self): + element = self._makeOne() + self.assertEqual([], list(element.getDirectTaggedValueTags())) + + element.setTaggedValue('foo', 'bar') + self.assertEqual(['foo'], list(element.getDirectTaggedValueTags())) + + def test_queryTaggedValue_miss(self): + element = self._makeOne() + self.assertEqual(element.queryTaggedValue('nonesuch'), None) + + def test_queryTaggedValue_miss_w_default(self): + element = self._makeOne() + self.assertEqual(element.queryTaggedValue('nonesuch', 'bar'), 'bar') + + def test_getDirectTaggedValue_miss(self): + element = self._makeOne() + self.assertRaises(KeyError, element.getDirectTaggedValue, 'nonesuch') + + def test_queryDirectTaggedValue_miss(self): + element = self._makeOne() + self.assertEqual(element.queryDirectTaggedValue('nonesuch'), None) + + def test_queryDirectTaggedValue_miss_w_default(self): + element = self._makeOne() + self.assertEqual(element.queryDirectTaggedValue('nonesuch', 'bar'), 'bar') + + def test_setTaggedValue(self): + element = self._makeOne() + element.setTaggedValue('foo', 'bar') + self.assertEqual(list(element.getTaggedValueTags()), ['foo']) + self.assertEqual(element.getTaggedValue('foo'), 'bar') + self.assertEqual(element.queryTaggedValue('foo'), 'bar') + + def test_verifies(self): + from zope.interface.interfaces import IElement + from zope.interface.verify import verifyObject + + element = self._makeOne() + verifyObject(IElement, element) + + +class GenericSpecificationBaseTests(unittest.TestCase): + # Tests that work with both implementations + def _getFallbackClass(self): + from zope.interface.interface import SpecificationBasePy # pylint:disable=no-name-in-module + return SpecificationBasePy + + _getTargetClass = _getFallbackClass + + def _makeOne(self): + return self._getTargetClass()() + + def test_providedBy_miss(self): + from zope.interface import interface + from zope.interface.declarations import _empty + sb = self._makeOne() + def _providedBy(obj): + return _empty + with _Monkey(interface, providedBy=_providedBy): + self.assertFalse(sb.providedBy(object())) + + def test_implementedBy_miss(self): + from zope.interface import interface + from zope.interface.declarations import _empty + sb = self._makeOne() + def _implementedBy(obj): + return _empty + with _Monkey(interface, implementedBy=_implementedBy): + self.assertFalse(sb.implementedBy(object())) + + +class SpecificationBaseTests(GenericSpecificationBaseTests, + OptimizationTestMixin): + # Tests that use the C implementation + + def _getTargetClass(self): + from zope.interface.interface import SpecificationBase + return SpecificationBase + +class SpecificationBasePyTests(GenericSpecificationBaseTests): + # Tests that only work with the Python implementation + + def test___call___miss(self): + sb = self._makeOne() + sb._implied = {} # not defined by SpecificationBasePy + self.assertFalse(sb.isOrExtends(object())) + + def test___call___hit(self): + sb = self._makeOne() + testing = object() + sb._implied = {testing: {}} # not defined by SpecificationBasePy + self.assertTrue(sb(testing)) + + def test_isOrExtends_miss(self): + sb = self._makeOne() + sb._implied = {} # not defined by SpecificationBasePy + self.assertFalse(sb.isOrExtends(object())) + + def test_isOrExtends_hit(self): + sb = self._makeOne() + testing = object() + sb._implied = {testing: {}} # not defined by SpecificationBasePy + self.assertTrue(sb(testing)) + + def test_implementedBy_hit(self): + from zope.interface import interface + sb = self._makeOne() + class _Decl: + _implied = {sb: {},} + def _implementedBy(obj): + return _Decl() + with _Monkey(interface, implementedBy=_implementedBy): + self.assertTrue(sb.implementedBy(object())) + + def test_providedBy_hit(self): + from zope.interface import interface + sb = self._makeOne() + class _Decl: + _implied = {sb: {},} + def _providedBy(obj): + return _Decl() + with _Monkey(interface, providedBy=_providedBy): + self.assertTrue(sb.providedBy(object())) + + +class NameAndModuleComparisonTestsMixin(CleanUp): + + def _makeOneToCompare(self): + return self._makeOne('a', 'b') + + def __check_NotImplemented_comparison(self, name): + # Without the correct attributes of __name__ and __module__, + # comparison switches to the reverse direction. + + import operator + ib = self._makeOneToCompare() + op = getattr(operator, name) + meth = getattr(ib, '__%s__' % name) + + # If either the __name__ or __module__ attribute + # is missing from the other object, then we return + # NotImplemented. + class RaisesErrorOnMissing: + Exc = AttributeError + def __getattribute__(self, name): + try: + return object.__getattribute__(self, name) + except AttributeError: + exc = RaisesErrorOnMissing.Exc + raise exc(name) + + class RaisesErrorOnModule(RaisesErrorOnMissing): + def __init__(self): + self.__name__ = 'foo' + @property + def __module__(self): + raise AttributeError + + class RaisesErrorOnName(RaisesErrorOnMissing): + def __init__(self): + self.__module__ = 'foo' + + self.assertEqual(RaisesErrorOnModule().__name__, 'foo') + self.assertEqual(RaisesErrorOnName().__module__, 'foo') + with self.assertRaises(AttributeError): + getattr(RaisesErrorOnModule(), '__module__') + with self.assertRaises(AttributeError): + getattr(RaisesErrorOnName(), '__name__') + + for cls in RaisesErrorOnModule, RaisesErrorOnName: + self.assertIs(meth(cls()), NotImplemented) + + # If the other object has a comparison function, returning + # NotImplemented means Python calls it. + + class AllowsAnyComparison(RaisesErrorOnMissing): + def __eq__(self, other): + return True + __lt__ = __eq__ + __le__ = __eq__ + __gt__ = __eq__ + __ge__ = __eq__ + __ne__ = __eq__ + + self.assertTrue(op(ib, AllowsAnyComparison())) + self.assertIs(meth(AllowsAnyComparison()), NotImplemented) + + # If it doesn't have the comparison, Python raises a TypeError. + class AllowsNoComparison: + __eq__ = None + __lt__ = __eq__ + __le__ = __eq__ + __gt__ = __eq__ + __ge__ = __eq__ + __ne__ = __eq__ + + self.assertIs(meth(AllowsNoComparison()), NotImplemented) + with self.assertRaises(TypeError): + op(ib, AllowsNoComparison()) + + # Errors besides AttributeError are passed + class MyException(Exception): + pass + + RaisesErrorOnMissing.Exc = MyException + + with self.assertRaises(MyException): + getattr(RaisesErrorOnModule(), '__module__') + with self.assertRaises(MyException): + getattr(RaisesErrorOnName(), '__name__') + + for cls in RaisesErrorOnModule, RaisesErrorOnName: + with self.assertRaises(MyException): + op(ib, cls()) + with self.assertRaises(MyException): + meth(cls()) + + def test__lt__NotImplemented(self): + self.__check_NotImplemented_comparison('lt') + + def test__le__NotImplemented(self): + self.__check_NotImplemented_comparison('le') + + def test__gt__NotImplemented(self): + self.__check_NotImplemented_comparison('gt') + + def test__ge__NotImplemented(self): + self.__check_NotImplemented_comparison('ge') + + +class InterfaceBaseTestsMixin(NameAndModuleComparisonTestsMixin): + # Tests for both C and Python implementation + + def _getTargetClass(self): + raise NotImplementedError + + def _getFallbackClass(self): + # pylint:disable=no-name-in-module + from zope.interface.interface import InterfaceBasePy + return InterfaceBasePy + + def _makeOne(self, object_should_provide=False, name=None, module=None): + class IB(self._getTargetClass()): + def _call_conform(self, conform): + return conform(self) + def providedBy(self, obj): + return object_should_provide + return IB(name, module) + + def test___call___w___conform___returning_value(self): + ib = self._makeOne(False) + conformed = object() + class _Adapted: + def __conform__(self, iface): + return conformed + self.assertIs(ib(_Adapted()), conformed) + + def test___call___wo___conform___ob_no_provides_w_alternate(self): + ib = self._makeOne(False) + __traceback_info__ = ib, self._getTargetClass() + adapted = object() + alternate = object() + self.assertIs(ib(adapted, alternate), alternate) + + def test___call___w___conform___ob_no_provides_wo_alternate(self): + ib = self._makeOne(False) + with self.assertRaises(TypeError) as exc: + ib(object()) + + self.assertIn('Could not adapt', str(exc.exception)) + + def test___call___w_no_conform_catches_only_AttributeError(self): + MissingSomeAttrs.test_raises(self, self._makeOne(), expected_missing='__conform__') + + +class InterfaceBaseTests(InterfaceBaseTestsMixin, + OptimizationTestMixin, + unittest.TestCase): + # Tests that work with the C implementation + def _getTargetClass(self): + from zope.interface.interface import InterfaceBase + return InterfaceBase + + +class InterfaceBasePyTests(InterfaceBaseTestsMixin, unittest.TestCase): + # Tests that only work with the Python implementation + + _getTargetClass = InterfaceBaseTestsMixin._getFallbackClass + + def test___call___w___conform___miss_ob_provides(self): + ib = self._makeOne(True) + class _Adapted: + def __conform__(self, iface): + return None + adapted = _Adapted() + self.assertIs(ib(adapted), adapted) + + def test___adapt___ob_provides(self): + ib = self._makeOne(True) + adapted = object() + self.assertIs(ib.__adapt__(adapted), adapted) + + def test___adapt___ob_no_provides_uses_hooks(self): + from zope.interface import interface + ib = self._makeOne(False) + adapted = object() + _missed = [] + def _hook_miss(iface, obj): + _missed.append((iface, obj)) + def _hook_hit(iface, obj): + return obj + with _Monkey(interface, adapter_hooks=[_hook_miss, _hook_hit]): + self.assertIs(ib.__adapt__(adapted), adapted) + self.assertEqual(_missed, [(ib, adapted)]) + +class SpecificationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.interface import Specification + return Specification + + def _makeOne(self, bases=_marker): + if bases is _marker: + return self._getTargetClass()() + return self._getTargetClass()(bases) + + def test_ctor(self): + from zope.interface.interface import Interface + spec = self._makeOne() + self.assertEqual(spec.__bases__, ()) + self.assertEqual(len(spec._implied), 2) + self.assertTrue(spec in spec._implied) + self.assertTrue(Interface in spec._implied) + self.assertEqual(len(spec.dependents), 0) + + def test_subscribe_first_time(self): + spec = self._makeOne() + dep = DummyDependent() + spec.subscribe(dep) + self.assertEqual(len(spec.dependents), 1) + self.assertEqual(spec.dependents[dep], 1) + + def test_subscribe_again(self): + spec = self._makeOne() + dep = DummyDependent() + spec.subscribe(dep) + spec.subscribe(dep) + self.assertEqual(spec.dependents[dep], 2) + + def test_unsubscribe_miss(self): + spec = self._makeOne() + dep = DummyDependent() + self.assertRaises(KeyError, spec.unsubscribe, dep) + + def test_unsubscribe(self): + spec = self._makeOne() + dep = DummyDependent() + spec.subscribe(dep) + spec.subscribe(dep) + spec.unsubscribe(dep) + self.assertEqual(spec.dependents[dep], 1) + spec.unsubscribe(dep) + self.assertFalse(dep in spec.dependents) + + def test___setBases_subscribes_bases_and_notifies_dependents(self): + from zope.interface.interface import Interface + spec = self._makeOne() + dep = DummyDependent() + spec.subscribe(dep) + class I(Interface): + pass + class J(Interface): + pass + spec.__bases__ = (I,) + self.assertEqual(dep._changed, [spec]) + self.assertEqual(I.dependents[spec], 1) + spec.__bases__ = (J,) + self.assertEqual(I.dependents.get(spec), None) + self.assertEqual(J.dependents[spec], 1) + + def test_changed_clears_volatiles_and_implied(self): + from zope.interface.interface import Interface + class I(Interface): + pass + spec = self._makeOne() + spec._v_attrs = 'Foo' + spec._implied[I] = () + spec.changed(spec) + self.assertIsNone(spec._v_attrs) + self.assertFalse(I in spec._implied) + + def test_interfaces_skips_already_seen(self): + from zope.interface.interface import Interface + class IFoo(Interface): + pass + spec = self._makeOne([IFoo, IFoo]) + self.assertEqual(list(spec.interfaces()), [IFoo]) + + def test_extends_strict_wo_self(self): + from zope.interface.interface import Interface + class IFoo(Interface): + pass + spec = self._makeOne(IFoo) + self.assertFalse(spec.extends(IFoo, strict=True)) + + def test_extends_strict_w_self(self): + spec = self._makeOne() + self.assertFalse(spec.extends(spec, strict=True)) + + def test_extends_non_strict_w_self(self): + spec = self._makeOne() + self.assertTrue(spec.extends(spec, strict=False)) + + def test_get_hit_w__v_attrs(self): + spec = self._makeOne() + foo = object() + spec._v_attrs = {'foo': foo} + self.assertTrue(spec.get('foo') is foo) + + def test_get_hit_from_base_wo__v_attrs(self): + from zope.interface.interface import Attribute + from zope.interface.interface import Interface + class IFoo(Interface): + foo = Attribute('foo') + class IBar(Interface): + bar = Attribute('bar') + spec = self._makeOne([IFoo, IBar]) + self.assertTrue(spec.get('foo') is IFoo.get('foo')) + self.assertTrue(spec.get('bar') is IBar.get('bar')) + + def test_multiple_inheritance_no_interfaces(self): + # If we extend an object that implements interfaces, + # plus one that doesn't, we do not interject `Interface` + # early in the resolution order. It stays at the end, + # like it should. + # See https://github.com/zopefoundation/zope.interface/issues/8 + from zope.interface.interface import Interface + from zope.interface.declarations import implementer + from zope.interface.declarations import implementedBy + + class IDefaultViewName(Interface): + pass + + class Context: + pass + + class RDBModel(Context): + pass + + class IOther(Interface): + pass + + @implementer(IOther) + class OtherBase: + pass + + class Model(OtherBase, Context): + pass + + self.assertEqual( + implementedBy(Model).__sro__, + ( + implementedBy(Model), + implementedBy(OtherBase), + IOther, + implementedBy(Context), + implementedBy(object), + Interface, # This used to be wrong, it used to be 2 too high. + ) + ) + + +class InterfaceClassTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.interface import InterfaceClass + return InterfaceClass + + def _makeOne(self, name='ITest', bases=(), attrs=None, __doc__=None, + __module__=None): + return self._getTargetClass()(name, bases, attrs, __doc__, __module__) + + def test_ctor_defaults(self): + klass = self._getTargetClass() + inst = klass('ITesting') + self.assertEqual(inst.__name__, 'ITesting') + self.assertEqual(inst.__doc__, '') + self.assertEqual(inst.__bases__, ()) + self.assertEqual(inst.getBases(), ()) + + def test_ctor_bad_bases(self): + klass = self._getTargetClass() + self.assertRaises(TypeError, klass, 'ITesting', (object(),)) + + def test_ctor_w_attrs_attrib_methods(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + klass = self._getTargetClass() + inst = klass('ITesting', attrs=ATTRS) + self.assertEqual(inst.__name__, 'ITesting') + self.assertEqual(inst.__doc__, '') + self.assertEqual(inst.__bases__, ()) + self.assertEqual(inst.names(), ATTRS.keys()) + + def test_ctor_attrs_w___locals__(self): + ATTRS = {'__locals__': {}} + klass = self._getTargetClass() + inst = klass('ITesting', attrs=ATTRS) + self.assertEqual(inst.__name__, 'ITesting') + self.assertEqual(inst.__doc__, '') + self.assertEqual(inst.__bases__, ()) + self.assertEqual(list(inst.names()), []) + + def test_ctor_attrs_w___annotations__(self): + ATTRS = {'__annotations__': {}} + klass = self._getTargetClass() + inst = klass('ITesting', attrs=ATTRS) + self.assertEqual(inst.__name__, 'ITesting') + self.assertEqual(inst.__doc__, '') + self.assertEqual(inst.__bases__, ()) + self.assertEqual(list(inst.names()), []) + + def test_ctor_attrs_w__decorator_non_return(self): + from zope.interface.interface import _decorator_non_return + ATTRS = {'dropme': _decorator_non_return} + klass = self._getTargetClass() + inst = klass('ITesting', attrs=ATTRS) + self.assertEqual(inst.__name__, 'ITesting') + self.assertEqual(inst.__doc__, '') + self.assertEqual(inst.__bases__, ()) + self.assertEqual(list(inst.names()), []) + + def test_ctor_attrs_w_invalid_attr_type(self): + from zope.interface.exceptions import InvalidInterface + ATTRS = {'invalid': object()} + klass = self._getTargetClass() + self.assertRaises(InvalidInterface, klass, 'ITesting', attrs=ATTRS) + + def test_ctor_w_explicit___doc__(self): + ATTRS = {'__doc__': 'ATTR'} + klass = self._getTargetClass() + inst = klass('ITesting', attrs=ATTRS, __doc__='EXPLICIT') + self.assertEqual(inst.__doc__, 'EXPLICIT') + + def test_interfaces(self): + iface = self._makeOne() + self.assertEqual(list(iface.interfaces()), [iface]) + + def test_getBases(self): + iface = self._makeOne() + sub = self._makeOne('ISub', bases=(iface,)) + self.assertEqual(sub.getBases(), (iface,)) + + def test_isEqualOrExtendedBy_identity(self): + iface = self._makeOne() + self.assertTrue(iface.isEqualOrExtendedBy(iface)) + + def test_isEqualOrExtendedBy_subiface(self): + iface = self._makeOne() + sub = self._makeOne('ISub', bases=(iface,)) + self.assertTrue(iface.isEqualOrExtendedBy(sub)) + self.assertFalse(sub.isEqualOrExtendedBy(iface)) + + def test_isEqualOrExtendedBy_unrelated(self): + one = self._makeOne('One') + another = self._makeOne('Another') + self.assertFalse(one.isEqualOrExtendedBy(another)) + self.assertFalse(another.isEqualOrExtendedBy(one)) + + def test_names_w_all_False_ignores_bases(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.names(all=False)), ['baz']) + + def test_names_w_all_True_no_bases(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + one = self._makeOne(attrs=ATTRS) + self.assertEqual(sorted(one.names(all=True)), ['bar', 'foo']) + + def test_names_w_all_True_w_bases_simple(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.names(all=True)), ['bar', 'baz', 'foo']) + + def test_names_w_all_True_bases_w_same_names(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + def _foo(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'foo': fromFunction(_foo), + 'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.names(all=True)), ['bar', 'baz', 'foo']) + + def test___iter__(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + def _foo(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'foo': fromFunction(_foo), + 'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived), ['bar', 'baz', 'foo']) + + def test_namesAndDescriptions_w_all_False_ignores_bases(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.namesAndDescriptions(all=False)), + [('baz', DERIVED_ATTRS['baz']), + ]) + + def test_namesAndDescriptions_w_all_True_no_bases(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + one = self._makeOne(attrs=ATTRS) + self.assertEqual(sorted(one.namesAndDescriptions(all=False)), + [('bar', ATTRS['bar']), + ('foo', ATTRS['foo']), + ]) + + def test_namesAndDescriptions_w_all_True_simple(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.namesAndDescriptions(all=True)), + [('bar', BASE_ATTRS['bar']), + ('baz', DERIVED_ATTRS['baz']), + ('foo', BASE_ATTRS['foo']), + ]) + + def test_namesAndDescriptions_w_all_True_bases_w_same_names(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + def _foo(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'foo': fromFunction(_foo), + 'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(sorted(derived.namesAndDescriptions(all=True)), + [('bar', BASE_ATTRS['bar']), + ('baz', DERIVED_ATTRS['baz']), + ('foo', DERIVED_ATTRS['foo']), + ]) + + def test_getDescriptionFor_miss(self): + one = self._makeOne() + self.assertRaises(KeyError, one.getDescriptionFor, 'nonesuch') + + def test_getDescriptionFor_hit(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + one = self._makeOne(attrs=ATTRS) + self.assertEqual(one.getDescriptionFor('foo'), ATTRS['foo']) + self.assertEqual(one.getDescriptionFor('bar'), ATTRS['bar']) + + def test___getitem___miss(self): + one = self._makeOne() + def _test(): + return one['nonesuch'] + self.assertRaises(KeyError, _test) + + def test___getitem___hit(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + one = self._makeOne(attrs=ATTRS) + self.assertEqual(one['foo'], ATTRS['foo']) + self.assertEqual(one['bar'], ATTRS['bar']) + + def test___contains___miss(self): + one = self._makeOne() + self.assertFalse('nonesuch' in one) + + def test___contains___hit(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + one = self._makeOne(attrs=ATTRS) + self.assertTrue('foo' in one) + self.assertTrue('bar' in one) + + def test_direct_miss(self): + one = self._makeOne() + self.assertEqual(one.direct('nonesuch'), None) + + def test_direct_hit_local_miss_bases(self): + from zope.interface.interface import Attribute + from zope.interface.interface import fromFunction + def _bar(): + """DOCSTRING""" + def _foo(): + """DOCSTRING""" + BASE_ATTRS = {'foo': Attribute('Foo', ''), + 'bar': fromFunction(_bar), + } + DERIVED_ATTRS = {'foo': fromFunction(_foo), + 'baz': Attribute('Baz', ''), + } + base = self._makeOne('IBase', attrs=BASE_ATTRS) + derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS) + self.assertEqual(derived.direct('foo'), DERIVED_ATTRS['foo']) + self.assertEqual(derived.direct('baz'), DERIVED_ATTRS['baz']) + self.assertEqual(derived.direct('bar'), None) + + def test_queryDescriptionFor_miss(self): + iface = self._makeOne() + self.assertEqual(iface.queryDescriptionFor('nonesuch'), None) + + def test_queryDescriptionFor_hit(self): + from zope.interface import Attribute + ATTRS = {'attr': Attribute('Title', 'Description')} + iface = self._makeOne(attrs=ATTRS) + self.assertEqual(iface.queryDescriptionFor('attr'), ATTRS['attr']) + + def test_validateInvariants_pass(self): + _called_with = [] + def _passable(*args, **kw): + _called_with.append((args, kw)) + return True + iface = self._makeOne() + obj = object() + iface.setTaggedValue('invariants', [_passable]) + self.assertEqual(iface.validateInvariants(obj), None) + self.assertEqual(_called_with, [((obj,), {})]) + + def test_validateInvariants_fail_wo_errors_passed(self): + from zope.interface.exceptions import Invalid + _passable_called_with = [] + def _passable(*args, **kw): + _passable_called_with.append((args, kw)) + return True + _fail_called_with = [] + def _fail(*args, **kw): + _fail_called_with.append((args, kw)) + raise Invalid + iface = self._makeOne() + obj = object() + iface.setTaggedValue('invariants', [_passable, _fail]) + self.assertRaises(Invalid, iface.validateInvariants, obj) + self.assertEqual(_passable_called_with, [((obj,), {})]) + self.assertEqual(_fail_called_with, [((obj,), {})]) + + def test_validateInvariants_fail_w_errors_passed(self): + from zope.interface.exceptions import Invalid + _errors = [] + _fail_called_with = [] + def _fail(*args, **kw): + _fail_called_with.append((args, kw)) + raise Invalid + iface = self._makeOne() + obj = object() + iface.setTaggedValue('invariants', [_fail]) + self.assertRaises(Invalid, iface.validateInvariants, obj, _errors) + self.assertEqual(_fail_called_with, [((obj,), {})]) + self.assertEqual(len(_errors), 1) + self.assertTrue(isinstance(_errors[0], Invalid)) + + def test_validateInvariants_fail_in_base_wo_errors_passed(self): + from zope.interface.exceptions import Invalid + _passable_called_with = [] + def _passable(*args, **kw): + _passable_called_with.append((args, kw)) + return True + _fail_called_with = [] + def _fail(*args, **kw): + _fail_called_with.append((args, kw)) + raise Invalid + base = self._makeOne('IBase') + derived = self._makeOne('IDerived', (base,)) + obj = object() + base.setTaggedValue('invariants', [_fail]) + derived.setTaggedValue('invariants', [_passable]) + self.assertRaises(Invalid, derived.validateInvariants, obj) + self.assertEqual(_passable_called_with, [((obj,), {})]) + self.assertEqual(_fail_called_with, [((obj,), {})]) + + def test_validateInvariants_fail_in_base_w_errors_passed(self): + from zope.interface.exceptions import Invalid + _errors = [] + _passable_called_with = [] + def _passable(*args, **kw): + _passable_called_with.append((args, kw)) + return True + _fail_called_with = [] + def _fail(*args, **kw): + _fail_called_with.append((args, kw)) + raise Invalid + base = self._makeOne('IBase') + derived = self._makeOne('IDerived', (base,)) + obj = object() + base.setTaggedValue('invariants', [_fail]) + derived.setTaggedValue('invariants', [_passable]) + self.assertRaises(Invalid, derived.validateInvariants, obj, _errors) + self.assertEqual(_passable_called_with, [((obj,), {})]) + self.assertEqual(_fail_called_with, [((obj,), {})]) + self.assertEqual(len(_errors), 1) + self.assertTrue(isinstance(_errors[0], Invalid)) + + def test_validateInvariants_inherited_not_called_multiple_times(self): + _passable_called_with = [] + + def _passable(*args, **kw): + _passable_called_with.append((args, kw)) + return True + + obj = object() + base = self._makeOne('IBase') + base.setTaggedValue('invariants', [_passable]) + derived = self._makeOne('IDerived', (base,)) + derived.validateInvariants(obj) + self.assertEqual(1, len(_passable_called_with)) + + def test___reduce__(self): + iface = self._makeOne('PickleMe') + self.assertEqual(iface.__reduce__(), 'PickleMe') + + def test___hash___normal(self): + iface = self._makeOne('HashMe') + self.assertEqual(hash(iface), + hash(('HashMe', + 'zope.interface.tests.test_interface'))) + + def test___hash___missing_required_attrs(self): + class Derived(self._getTargetClass()): + def __init__(self): # pylint:disable=super-init-not-called + pass # Don't call base class. + derived = Derived() + with self.assertRaises(AttributeError): + hash(derived) + + def test_comparison_with_None(self): + # pylint:disable=singleton-comparison,misplaced-comparison-constant + iface = self._makeOne() + self.assertTrue(iface < None) + self.assertTrue(iface <= None) + self.assertFalse(iface == None) + self.assertTrue(iface != None) + self.assertFalse(iface >= None) + self.assertFalse(iface > None) + + self.assertFalse(None < iface) + self.assertFalse(None <= iface) + self.assertFalse(None == iface) + self.assertTrue(None != iface) + self.assertTrue(None >= iface) + self.assertTrue(None > iface) + + def test_comparison_with_same_instance(self): + # pylint:disable=comparison-with-itself + iface = self._makeOne() + + self.assertFalse(iface < iface) + self.assertTrue(iface <= iface) + self.assertTrue(iface == iface) + self.assertFalse(iface != iface) + self.assertTrue(iface >= iface) + self.assertFalse(iface > iface) + + def test_comparison_with_same_named_instance_in_other_module(self): + + one = self._makeOne('IName', __module__='zope.interface.tests.one') + other = self._makeOne('IName', __module__='zope.interface.tests.other') + + self.assertTrue(one < other) + self.assertFalse(other < one) + self.assertTrue(one <= other) + self.assertFalse(other <= one) + self.assertFalse(one == other) + self.assertFalse(other == one) + self.assertTrue(one != other) + self.assertTrue(other != one) + self.assertFalse(one >= other) + self.assertTrue(other >= one) + self.assertFalse(one > other) + self.assertTrue(other > one) + + def test_assignment_to__class__(self): + # https://github.com/zopefoundation/zope.interface/issues/6 + class MyException(Exception): + pass + + class MyInterfaceClass(self._getTargetClass()): + def __call__(self, target): + raise MyException(target) + + IFoo = self._makeOne('IName') + self.assertIsInstance(IFoo, self._getTargetClass()) + self.assertIs(type(IFoo), self._getTargetClass()) + + with self.assertRaises(TypeError): + IFoo(1) + + IFoo.__class__ = MyInterfaceClass + self.assertIsInstance(IFoo, MyInterfaceClass) + self.assertIs(type(IFoo), MyInterfaceClass) + + with self.assertRaises(MyException): + IFoo(1) + + def test_assignment_to__class__2(self): + # https://github.com/zopefoundation/zope.interface/issues/6 + # This is essentially a transcription of the + # test presented in the bug report. + from zope.interface import Interface + class MyInterfaceClass(self._getTargetClass()): + def __call__(self, *args): + return args + + IFoo = MyInterfaceClass('IFoo', (Interface,)) + self.assertEqual(IFoo(1), (1,)) + + class IBar(IFoo): + pass + + self.assertEqual(IBar(1), (1,)) + + class ISpam(Interface): + pass + + with self.assertRaises(TypeError): + ISpam() + + ISpam.__class__ = MyInterfaceClass + self.assertEqual(ISpam(1), (1,)) + + def test__module__is_readonly(self): + inst = self._makeOne() + with self.assertRaises(AttributeError): + inst.__module__ = 'different.module' + + +class InterfaceTests(unittest.TestCase): + + def test_attributes_link_to_interface(self): + from zope.interface import Interface + from zope.interface import Attribute + + class I1(Interface): + attr = Attribute("My attr") + + self.assertTrue(I1['attr'].interface is I1) + + def test_methods_link_to_interface(self): + from zope.interface import Interface + + class I1(Interface): + + def method(foo, bar, bingo): + "A method" + + self.assertTrue(I1['method'].interface is I1) + + def test_classImplements_simple(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + + class ICurrent(Interface): + def method1(a, b): + """docstring""" + def method2(a, b): + """docstring""" + + class IOther(Interface): + pass + + class Current: + __implemented__ = ICurrent + def method1(self, a, b): + raise NotImplementedError() + def method2(self, a, b): + raise NotImplementedError() + + current = Current() + + self.assertTrue(ICurrent.implementedBy(Current)) + self.assertFalse(IOther.implementedBy(Current)) + self.assertEqual(ICurrent, ICurrent) + self.assertTrue(ICurrent in implementedBy(Current)) + self.assertFalse(IOther in implementedBy(Current)) + self.assertTrue(ICurrent in providedBy(current)) + self.assertFalse(IOther in providedBy(current)) + + def test_classImplements_base_not_derived(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + class IBase(Interface): + def method(): + """docstring""" + class IDerived(IBase): + pass + class Current(): + __implemented__ = IBase + def method(self): + raise NotImplementedError() + current = Current() + + self.assertTrue(IBase.implementedBy(Current)) + self.assertFalse(IDerived.implementedBy(Current)) + self.assertTrue(IBase in implementedBy(Current)) + self.assertFalse(IDerived in implementedBy(Current)) + self.assertTrue(IBase in providedBy(current)) + self.assertFalse(IDerived in providedBy(current)) + + def test_classImplements_base_and_derived(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + + class IBase(Interface): + def method(): + """docstring""" + + class IDerived(IBase): + pass + + class Current: + __implemented__ = IDerived + def method(self): + raise NotImplementedError() + + current = Current() + + self.assertTrue(IBase.implementedBy(Current)) + self.assertTrue(IDerived.implementedBy(Current)) + self.assertFalse(IBase in implementedBy(Current)) + self.assertTrue(IBase in implementedBy(Current).flattened()) + self.assertTrue(IDerived in implementedBy(Current)) + self.assertFalse(IBase in providedBy(current)) + self.assertTrue(IBase in providedBy(current).flattened()) + self.assertTrue(IDerived in providedBy(current)) + + def test_classImplements_multiple(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + + class ILeft(Interface): + def method(): + """docstring""" + + class IRight(ILeft): + pass + + class Left: + __implemented__ = ILeft + + def method(self): + raise NotImplementedError() + + class Right: + __implemented__ = IRight + + class Ambi(Left, Right): + pass + + ambi = Ambi() + + self.assertTrue(ILeft.implementedBy(Ambi)) + self.assertTrue(IRight.implementedBy(Ambi)) + self.assertTrue(ILeft in implementedBy(Ambi)) + self.assertTrue(IRight in implementedBy(Ambi)) + self.assertTrue(ILeft in providedBy(ambi)) + self.assertTrue(IRight in providedBy(ambi)) + + def test_classImplements_multiple_w_explict_implements(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + + class ILeft(Interface): + + def method(): + """docstring""" + + class IRight(ILeft): + pass + + class IOther(Interface): + pass + + class Left(): + __implemented__ = ILeft + + def method(self): + raise NotImplementedError() + + class Right: + __implemented__ = IRight + + class Other: + __implemented__ = IOther + + class Mixed(Left, Right): + __implemented__ = Left.__implemented__, Other.__implemented__ + + mixed = Mixed() + + self.assertTrue(ILeft.implementedBy(Mixed)) + self.assertFalse(IRight.implementedBy(Mixed)) + self.assertTrue(IOther.implementedBy(Mixed)) + self.assertTrue(ILeft in implementedBy(Mixed)) + self.assertFalse(IRight in implementedBy(Mixed)) + self.assertTrue(IOther in implementedBy(Mixed)) + self.assertTrue(ILeft in providedBy(mixed)) + self.assertFalse(IRight in providedBy(mixed)) + self.assertTrue(IOther in providedBy(mixed)) + + def testInterfaceExtendsInterface(self): + from zope.interface import Interface + + new = Interface.__class__ + FunInterface = new('FunInterface') + BarInterface = new('BarInterface', (FunInterface,)) + BobInterface = new('BobInterface') + BazInterface = new('BazInterface', (BobInterface, BarInterface,)) + + self.assertTrue(BazInterface.extends(BobInterface)) + self.assertTrue(BazInterface.extends(BarInterface)) + self.assertTrue(BazInterface.extends(FunInterface)) + self.assertFalse(BobInterface.extends(FunInterface)) + self.assertFalse(BobInterface.extends(BarInterface)) + self.assertTrue(BarInterface.extends(FunInterface)) + self.assertFalse(BarInterface.extends(BazInterface)) + + def test_verifyClass(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface.verify import verifyClass + + + class ICheckMe(Interface): + attr = Attribute('My attr') + + def method(): + "A method" + + class CheckMe: + __implemented__ = ICheckMe + attr = 'value' + + def method(self): + raise NotImplementedError() + + self.assertTrue(verifyClass(ICheckMe, CheckMe)) + + def test_verifyObject(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface.verify import verifyObject + + + class ICheckMe(Interface): + attr = Attribute('My attr') + + def method(): + "A method" + + class CheckMe: + __implemented__ = ICheckMe + attr = 'value' + + def method(self): + raise NotImplementedError() + + check_me = CheckMe() + + self.assertTrue(verifyObject(ICheckMe, check_me)) + + def test_interface_object_provides_Interface(self): + from zope.interface import Interface + + class AnInterface(Interface): + pass + + self.assertTrue(Interface.providedBy(AnInterface)) + + def test_names_simple(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + """docstring""" + + self.assertEqual(sorted(ISimple.names()), ['attr', 'method']) + + def test_names_derived(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + """docstring""" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + """docstring""" + + def method2(): + """docstring""" + + self.assertEqual(sorted(IDerived.names()), + ['attr2', 'method', 'method2']) + self.assertEqual(sorted(IDerived.names(all=True)), + ['attr', 'attr2', 'method', 'method2']) + + def test_namesAndDescriptions_simple(self): + from zope.interface import Attribute + from zope.interface.interface import Method + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + name_values = sorted(ISimple.namesAndDescriptions()) + + self.assertEqual(len(name_values), 2) + self.assertEqual(name_values[0][0], 'attr') + self.assertTrue(isinstance(name_values[0][1], Attribute)) + self.assertEqual(name_values[0][1].__name__, 'attr') + self.assertEqual(name_values[0][1].__doc__, 'My attr') + self.assertEqual(name_values[1][0], 'method') + self.assertTrue(isinstance(name_values[1][1], Method)) + self.assertEqual(name_values[1][1].__name__, 'method') + self.assertEqual(name_values[1][1].__doc__, 'My method') + + def test_namesAndDescriptions_derived(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface.interface import Method + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + "My method, overridden" + + def method2(): + "My method2" + + name_values = sorted(IDerived.namesAndDescriptions()) + + self.assertEqual(len(name_values), 3) + self.assertEqual(name_values[0][0], 'attr2') + self.assertTrue(isinstance(name_values[0][1], Attribute)) + self.assertEqual(name_values[0][1].__name__, 'attr2') + self.assertEqual(name_values[0][1].__doc__, 'My attr2') + self.assertEqual(name_values[1][0], 'method') + self.assertTrue(isinstance(name_values[1][1], Method)) + self.assertEqual(name_values[1][1].__name__, 'method') + self.assertEqual(name_values[1][1].__doc__, 'My method, overridden') + self.assertEqual(name_values[2][0], 'method2') + self.assertTrue(isinstance(name_values[2][1], Method)) + self.assertEqual(name_values[2][1].__name__, 'method2') + self.assertEqual(name_values[2][1].__doc__, 'My method2') + + name_values = sorted(IDerived.namesAndDescriptions(all=True)) + + self.assertEqual(len(name_values), 4) + self.assertEqual(name_values[0][0], 'attr') + self.assertTrue(isinstance(name_values[0][1], Attribute)) + self.assertEqual(name_values[0][1].__name__, 'attr') + self.assertEqual(name_values[0][1].__doc__, 'My attr') + self.assertEqual(name_values[1][0], 'attr2') + self.assertTrue(isinstance(name_values[1][1], Attribute)) + self.assertEqual(name_values[1][1].__name__, 'attr2') + self.assertEqual(name_values[1][1].__doc__, 'My attr2') + self.assertEqual(name_values[2][0], 'method') + self.assertTrue(isinstance(name_values[2][1], Method)) + self.assertEqual(name_values[2][1].__name__, 'method') + self.assertEqual(name_values[2][1].__doc__, 'My method, overridden') + self.assertEqual(name_values[3][0], 'method2') + self.assertTrue(isinstance(name_values[3][1], Method)) + self.assertEqual(name_values[3][1].__name__, 'method2') + self.assertEqual(name_values[3][1].__doc__, 'My method2') + + def test_getDescriptionFor_nonesuch_no_default(self): + from zope.interface import Interface + + class IEmpty(Interface): + pass + + self.assertRaises(KeyError, IEmpty.getDescriptionFor, 'nonesuch') + + def test_getDescriptionFor_simple(self): + from zope.interface import Attribute + from zope.interface.interface import Method + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + a_desc = ISimple.getDescriptionFor('attr') + self.assertTrue(isinstance(a_desc, Attribute)) + self.assertEqual(a_desc.__name__, 'attr') + self.assertEqual(a_desc.__doc__, 'My attr') + + m_desc = ISimple.getDescriptionFor('method') + self.assertTrue(isinstance(m_desc, Method)) + self.assertEqual(m_desc.__name__, 'method') + self.assertEqual(m_desc.__doc__, 'My method') + + def test_getDescriptionFor_derived(self): + from zope.interface import Attribute + from zope.interface.interface import Method + from zope.interface import Interface + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + "My method, overridden" + + def method2(): + "My method2" + + a_desc = IDerived.getDescriptionFor('attr') + self.assertTrue(isinstance(a_desc, Attribute)) + self.assertEqual(a_desc.__name__, 'attr') + self.assertEqual(a_desc.__doc__, 'My attr') + + m_desc = IDerived.getDescriptionFor('method') + self.assertTrue(isinstance(m_desc, Method)) + self.assertEqual(m_desc.__name__, 'method') + self.assertEqual(m_desc.__doc__, 'My method, overridden') + + a2_desc = IDerived.getDescriptionFor('attr2') + self.assertTrue(isinstance(a2_desc, Attribute)) + self.assertEqual(a2_desc.__name__, 'attr2') + self.assertEqual(a2_desc.__doc__, 'My attr2') + + m2_desc = IDerived.getDescriptionFor('method2') + self.assertTrue(isinstance(m2_desc, Method)) + self.assertEqual(m2_desc.__name__, 'method2') + self.assertEqual(m2_desc.__doc__, 'My method2') + + def test___getitem__nonesuch(self): + from zope.interface import Interface + + class IEmpty(Interface): + pass + + self.assertRaises(KeyError, IEmpty.__getitem__, 'nonesuch') + + def test___getitem__simple(self): + from zope.interface import Attribute + from zope.interface.interface import Method + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + a_desc = ISimple['attr'] + self.assertTrue(isinstance(a_desc, Attribute)) + self.assertEqual(a_desc.__name__, 'attr') + self.assertEqual(a_desc.__doc__, 'My attr') + + m_desc = ISimple['method'] + self.assertTrue(isinstance(m_desc, Method)) + self.assertEqual(m_desc.__name__, 'method') + self.assertEqual(m_desc.__doc__, 'My method') + + def test___getitem___derived(self): + from zope.interface import Attribute + from zope.interface.interface import Method + from zope.interface import Interface + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + "My method, overridden" + + def method2(): + "My method2" + + a_desc = IDerived['attr'] + self.assertTrue(isinstance(a_desc, Attribute)) + self.assertEqual(a_desc.__name__, 'attr') + self.assertEqual(a_desc.__doc__, 'My attr') + + m_desc = IDerived['method'] + self.assertTrue(isinstance(m_desc, Method)) + self.assertEqual(m_desc.__name__, 'method') + self.assertEqual(m_desc.__doc__, 'My method, overridden') + + a2_desc = IDerived['attr2'] + self.assertTrue(isinstance(a2_desc, Attribute)) + self.assertEqual(a2_desc.__name__, 'attr2') + self.assertEqual(a2_desc.__doc__, 'My attr2') + + m2_desc = IDerived['method2'] + self.assertTrue(isinstance(m2_desc, Method)) + self.assertEqual(m2_desc.__name__, 'method2') + self.assertEqual(m2_desc.__doc__, 'My method2') + + def test___contains__nonesuch(self): + from zope.interface import Interface + + class IEmpty(Interface): + pass + + self.assertFalse('nonesuch' in IEmpty) + + def test___contains__simple(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + self.assertTrue('attr' in ISimple) + self.assertTrue('method' in ISimple) + + def test___contains__derived(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + "My method, overridden" + + def method2(): + "My method2" + + self.assertTrue('attr' in IDerived) + self.assertTrue('method' in IDerived) + self.assertTrue('attr2' in IDerived) + self.assertTrue('method2' in IDerived) + + def test___iter__empty(self): + from zope.interface import Interface + + class IEmpty(Interface): + pass + + self.assertEqual(list(IEmpty), []) + + def test___iter__simple(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class ISimple(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + self.assertEqual(sorted(list(ISimple)), ['attr', 'method']) + + def test___iter__derived(self): + from zope.interface import Attribute + from zope.interface import Interface + + + class IBase(Interface): + attr = Attribute('My attr') + + def method(): + "My method" + + class IDerived(IBase): + attr2 = Attribute('My attr2') + + def method(): + "My method, overridden" + + def method2(): + "My method2" + + self.assertEqual(sorted(list(IDerived)), + ['attr', 'attr2', 'method', 'method2']) + + def test_function_attributes_become_tagged_values(self): + from zope.interface import Interface + + class ITagMe(Interface): + def method(): + """docstring""" + method.optional = 1 + + method = ITagMe['method'] + self.assertEqual(method.getTaggedValue('optional'), 1) + + def test___doc___non_element(self): + from zope.interface import Interface + + class IHaveADocString(Interface): + "xxx" + + self.assertEqual(IHaveADocString.__doc__, "xxx") + self.assertEqual(list(IHaveADocString), []) + + def test___doc___as_element(self): + from zope.interface import Attribute + from zope.interface import Interface + + class IHaveADocString(Interface): + "xxx" + __doc__ = Attribute('the doc') + + self.assertEqual(IHaveADocString.__doc__, "") + self.assertEqual(list(IHaveADocString), ['__doc__']) + + def _errorsEqual(self, has_invariant, error_len, error_msgs, iface): + from zope.interface.exceptions import Invalid + self.assertRaises(Invalid, iface.validateInvariants, has_invariant) + e = [] + try: + iface.validateInvariants(has_invariant, e) + self.fail("validateInvariants should always raise") + except Invalid as error: + self.assertEqual(error.args[0], e) + + self.assertEqual(len(e), error_len) + msgs = [error.args[0] for error in e] + msgs.sort() + for msg in msgs: + self.assertEqual(msg, error_msgs.pop(0)) + + def test_invariant_simple(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import directlyProvides + from zope.interface import invariant + + class IInvariant(Interface): + foo = Attribute('foo') + bar = Attribute('bar; must eval to Boolean True if foo does') + invariant(_ifFooThenBar) + + class HasInvariant: + pass + + # set up + has_invariant = HasInvariant() + directlyProvides(has_invariant, IInvariant) + + # the tests + self.assertEqual(IInvariant.getTaggedValue('invariants'), + [_ifFooThenBar]) + self.assertEqual(IInvariant.validateInvariants(has_invariant), None) + has_invariant.bar = 27 + self.assertEqual(IInvariant.validateInvariants(has_invariant), None) + has_invariant.foo = 42 + self.assertEqual(IInvariant.validateInvariants(has_invariant), None) + del has_invariant.bar + self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'], + IInvariant) + + def test_invariant_nested(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import directlyProvides + from zope.interface import invariant + + class IInvariant(Interface): + foo = Attribute('foo') + bar = Attribute('bar; must eval to Boolean True if foo does') + invariant(_ifFooThenBar) + + class ISubInvariant(IInvariant): + invariant(_barGreaterThanFoo) + + class HasInvariant: + pass + + # nested interfaces with invariants: + self.assertEqual(ISubInvariant.getTaggedValue('invariants'), + [_barGreaterThanFoo]) + has_invariant = HasInvariant() + directlyProvides(has_invariant, ISubInvariant) + has_invariant.foo = 42 + # even though the interface has changed, we should still only have one + # error. + self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'], + ISubInvariant) + # however, if we set foo to 0 (Boolean False) and bar to a negative + # number then we'll get the new error + has_invariant.foo = 2 + has_invariant.bar = 1 + self._errorsEqual(has_invariant, 1, + ['Please, Boo MUST be greater than Foo!'], + ISubInvariant) + # and if we set foo to a positive number and boo to 0, we'll + # get both errors! + has_invariant.foo = 1 + has_invariant.bar = 0 + self._errorsEqual(has_invariant, 2, + ['If Foo, then Bar!', + 'Please, Boo MUST be greater than Foo!'], + ISubInvariant) + # for a happy ending, we'll make the invariants happy + has_invariant.foo = 1 + has_invariant.bar = 2 + self.assertEqual(IInvariant.validateInvariants(has_invariant), None) + + def test_invariant_mutandis(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import directlyProvides + from zope.interface import invariant + + class IInvariant(Interface): + foo = Attribute('foo') + bar = Attribute('bar; must eval to Boolean True if foo does') + invariant(_ifFooThenBar) + + class HasInvariant: + pass + + # now we'll do two invariants on the same interface, + # just to make sure that a small + # multi-invariant interface is at least minimally tested. + has_invariant = HasInvariant() + directlyProvides(has_invariant, IInvariant) + has_invariant.foo = 42 + + # if you really need to mutate, then this would be the way to do it. + # Probably a bad idea, though. :-) + old_invariants = IInvariant.getTaggedValue('invariants') + invariants = old_invariants[:] + invariants.append(_barGreaterThanFoo) + IInvariant.setTaggedValue('invariants', invariants) + + # even though the interface has changed, we should still only have one + # error. + self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'], + IInvariant) + # however, if we set foo to 0 (Boolean False) and bar to a negative + # number then we'll get the new error + has_invariant.foo = 2 + has_invariant.bar = 1 + self._errorsEqual(has_invariant, 1, + ['Please, Boo MUST be greater than Foo!'], IInvariant) + # and if we set foo to a positive number and boo to 0, we'll + # get both errors! + has_invariant.foo = 1 + has_invariant.bar = 0 + self._errorsEqual(has_invariant, 2, + ['If Foo, then Bar!', + 'Please, Boo MUST be greater than Foo!'], + IInvariant) + # for another happy ending, we'll make the invariants happy again + has_invariant.foo = 1 + has_invariant.bar = 2 + self.assertEqual(IInvariant.validateInvariants(has_invariant), None) + # clean up + IInvariant.setTaggedValue('invariants', old_invariants) + + def test___doc___element(self): + from zope.interface import Interface + from zope.interface import Attribute + class IDocstring(Interface): + "xxx" + + self.assertEqual(IDocstring.__doc__, "xxx") + self.assertEqual(list(IDocstring), []) + + class IDocstringAndAttribute(Interface): + "xxx" + + __doc__ = Attribute('the doc') + + self.assertEqual(IDocstringAndAttribute.__doc__, "") + self.assertEqual(list(IDocstringAndAttribute), ['__doc__']) + + def test_invariant_as_decorator(self): + from zope.interface import Interface + from zope.interface import Attribute + from zope.interface import implementer + from zope.interface import invariant + from zope.interface.exceptions import Invalid + + class IRange(Interface): + min = Attribute("Lower bound") + max = Attribute("Upper bound") + + @invariant + def range_invariant(ob): + if ob.max < ob.min: + raise Invalid('max < min') + + @implementer(IRange) + class Range: + + def __init__(self, min, max): + self.min, self.max = min, max + + IRange.validateInvariants(Range(1, 2)) + IRange.validateInvariants(Range(1, 1)) + try: + IRange.validateInvariants(Range(2, 1)) + except Invalid as e: + self.assertEqual(str(e), 'max < min') + + def test_taggedValue(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import taggedValue + + class ITagged(Interface): + foo = Attribute('foo') + bar = Attribute('bar; must eval to Boolean True if foo does') + taggedValue('qux', 'Spam') + + class IDerived(ITagged): + taggedValue('qux', 'Spam Spam') + taggedValue('foo', 'bar') + + class IDerived2(IDerived): + pass + + self.assertEqual(ITagged.getTaggedValue('qux'), 'Spam') + self.assertRaises(KeyError, ITagged.getTaggedValue, 'foo') + self.assertEqual(list(ITagged.getTaggedValueTags()), ['qux']) + + self.assertEqual(IDerived2.getTaggedValue('qux'), 'Spam Spam') + self.assertEqual(IDerived2.getTaggedValue('foo'), 'bar') + self.assertEqual(set(IDerived2.getTaggedValueTags()), {'qux', 'foo'}) + + def _make_taggedValue_tree(self, base): + from zope.interface import taggedValue + from zope.interface import Attribute + O = base + class F(O): + taggedValue('tag', 'F') + tag = Attribute('F') + class E(O): + taggedValue('tag', 'E') + tag = Attribute('E') + class D(O): + taggedValue('tag', 'D') + tag = Attribute('D') + class C(D, F): + taggedValue('tag', 'C') + tag = Attribute('C') + class B(D, E): + pass + class A(B, C): + pass + + return A + + def test_getTaggedValue_follows__iro__(self): + # And not just looks at __bases__. + # https://github.com/zopefoundation/zope.interface/issues/190 + from zope.interface import Interface + + # First, confirm that looking at a true class + # hierarchy follows the __mro__. + class_A = self._make_taggedValue_tree(object) + self.assertEqual(class_A.tag.__name__, 'C') + + # Now check that Interface does, both for attributes... + iface_A = self._make_taggedValue_tree(Interface) + self.assertEqual(iface_A['tag'].__name__, 'C') + # ... and for tagged values. + self.assertEqual(iface_A.getTaggedValue('tag'), 'C') + self.assertEqual(iface_A.queryTaggedValue('tag'), 'C') + # Of course setting something lower overrides it. + assert iface_A.__bases__[0].__name__ == 'B' + iface_A.__bases__[0].setTaggedValue('tag', 'B') + self.assertEqual(iface_A.getTaggedValue('tag'), 'B') + + def test_getDirectTaggedValue_ignores__iro__(self): + # https://github.com/zopefoundation/zope.interface/issues/190 + from zope.interface import Interface + + A = self._make_taggedValue_tree(Interface) + self.assertIsNone(A.queryDirectTaggedValue('tag')) + self.assertEqual([], list(A.getDirectTaggedValueTags())) + + with self.assertRaises(KeyError): + A.getDirectTaggedValue('tag') + + A.setTaggedValue('tag', 'A') + self.assertEqual(A.queryDirectTaggedValue('tag'), 'A') + self.assertEqual(A.getDirectTaggedValue('tag'), 'A') + self.assertEqual(['tag'], list(A.getDirectTaggedValueTags())) + + assert A.__bases__[1].__name__ == 'C' + C = A.__bases__[1] + self.assertEqual(C.queryDirectTaggedValue('tag'), 'C') + self.assertEqual(C.getDirectTaggedValue('tag'), 'C') + self.assertEqual(['tag'], list(C.getDirectTaggedValueTags())) + + def test_description_cache_management(self): + # See https://bugs.launchpad.net/zope.interface/+bug/185974 + # There was a bug where the cache used by Specification.get() was not + # cleared when the bases were changed. + from zope.interface import Interface + from zope.interface import Attribute + + class I1(Interface): + a = Attribute('a') + + class I2(I1): + pass + + class I3(I2): + pass + + self.assertTrue(I3.get('a') is I1.get('a')) + + I2.__bases__ = (Interface,) + self.assertTrue(I3.get('a') is None) + + def test___call___defers_to___conform___(self): + from zope.interface import Interface + from zope.interface import implementer + + class I(Interface): + pass + + @implementer(I) + class C: + def __conform__(self, proto): + return 0 + + self.assertEqual(I(C()), 0) + + def test___call___object_implements(self): + from zope.interface import Interface + from zope.interface import implementer + + class I(Interface): + pass + + @implementer(I) + class C: + pass + + c = C() + self.assertTrue(I(c) is c) + + def test___call___miss_wo_alternate(self): + from zope.interface import Interface + + class I(Interface): + pass + + class C: + pass + + c = C() + self.assertRaises(TypeError, I, c) + + def test___call___miss_w_alternate(self): + from zope.interface import Interface + + class I(Interface): + pass + + class C: + pass + + c = C() + self.assertTrue(I(c, self) is self) + + def test___call___w_adapter_hook(self): + from zope.interface import Interface + from zope.interface.interface import adapter_hooks + + def _miss(iface, obj): + pass + + def _hit(iface, obj): + return self + + class I(Interface): + pass + + class C: + pass + + c = C() + + old_adapter_hooks = adapter_hooks[:] + adapter_hooks[:] = [_miss, _hit] + try: + self.assertTrue(I(c) is self) + finally: + adapter_hooks[:] = old_adapter_hooks + + def test___call___w_overridden_adapt(self): + from zope.interface import Interface + from zope.interface import interfacemethod + from zope.interface import implementer + + class I(Interface): + + @interfacemethod + def __adapt__(self, obj): + return 42 + + @implementer(I) + class O: + pass + + self.assertEqual(42, I(object())) + # __adapt__ can ignore the fact that the object provides + # the interface if it chooses. + self.assertEqual(42, I(O())) + + def test___call___w_overridden_adapt_and_conform(self): + # Conform is first, taking precedence over __adapt__, + # *if* it returns non-None + from zope.interface import Interface + from zope.interface import interfacemethod + from zope.interface import implementer + + class IAdapt(Interface): + @interfacemethod + def __adapt__(self, obj): + return 42 + + class ISimple(Interface): + """Nothing special.""" + + @implementer(IAdapt) + class Conform24: + def __conform__(self, iface): + return 24 + + @implementer(IAdapt) + class ConformNone: + def __conform__(self, iface): + return None + + self.assertEqual(42, IAdapt(object())) + + self.assertEqual(24, ISimple(Conform24())) + self.assertEqual(24, IAdapt(Conform24())) + + with self.assertRaises(TypeError): + ISimple(ConformNone()) + + self.assertEqual(42, IAdapt(ConformNone())) + + + def test___call___w_overridden_adapt_call_super(self): + import sys + from zope.interface import Interface + from zope.interface import interfacemethod + from zope.interface import implementer + + class I(Interface): + + @interfacemethod + def __adapt__(self, obj): + if not self.providedBy(obj): + return 42 + return super().__adapt__(obj) + + @implementer(I) + class O: + pass + + self.assertEqual(42, I(object())) + o = O() + self.assertIs(o, I(o)) + + def test___adapt___as_method_and_implementation(self): + from zope.interface import Interface + from zope.interface import interfacemethod + + class I(Interface): + @interfacemethod + def __adapt__(self, obj): + return 42 + + def __adapt__(to_adapt): + "This is a protocol" + + self.assertEqual(42, I(object())) + self.assertEqual(I['__adapt__'].getSignatureString(), '(to_adapt)') + + def test___adapt__inheritance_and_type(self): + from zope.interface import Interface + from zope.interface import interfacemethod + + class IRoot(Interface): + """Root""" + + class IWithAdapt(IRoot): + @interfacemethod + def __adapt__(self, obj): + return 42 + + class IOther(IRoot): + """Second branch""" + + class IUnrelated(Interface): + """Unrelated""" + + class IDerivedAdapt(IUnrelated, IWithAdapt, IOther): + """Inherits an adapt""" + # Order of "inheritance" matters here. + + class IDerived2Adapt(IDerivedAdapt): + """Overrides an inherited custom adapt.""" + @interfacemethod + def __adapt__(self, obj): + return 24 + + self.assertEqual(42, IDerivedAdapt(object())) + for iface in IRoot, IWithAdapt, IOther, IUnrelated, IDerivedAdapt: + self.assertEqual(__name__, iface.__module__) + + for iface in IRoot, IOther, IUnrelated: + self.assertEqual(type(IRoot), type(Interface)) + + # But things that implemented __adapt__ got a new type + self.assertNotEqual(type(Interface), type(IWithAdapt)) + self.assertEqual(type(IWithAdapt), type(IDerivedAdapt)) + self.assertIsInstance(IWithAdapt, type(Interface)) + + self.assertEqual(24, IDerived2Adapt(object())) + self.assertNotEqual(type(IDerived2Adapt), type(IDerivedAdapt)) + self.assertIsInstance(IDerived2Adapt, type(IDerivedAdapt)) + + def test_interfacemethod_is_general(self): + from zope.interface import Interface + from zope.interface import interfacemethod + + class I(Interface): + + @interfacemethod + def __call__(self, obj): + """Replace an existing method""" + return 42 + + @interfacemethod + def this_is_new(self): + return 42 + + self.assertEqual(I(self), 42) + self.assertEqual(I.this_is_new(), 42) + + +class AttributeTests(ElementTests): + + DEFAULT_NAME = 'TestAttribute' + + def _getTargetClass(self): + from zope.interface.interface import Attribute + return Attribute + + def test__repr__w_interface(self): + method = self._makeOne() + method.interface = type(self) + r = repr(method) + self.assertTrue(r.startswith('<zope.interface.interface.Attribute object at'), r) + self.assertTrue(r.endswith(' ' + __name__ + '.AttributeTests.TestAttribute>'), r) + + def test__repr__wo_interface(self): + method = self._makeOne() + r = repr(method) + self.assertTrue(r.startswith('<zope.interface.interface.Attribute object at'), r) + self.assertTrue(r.endswith(' TestAttribute>'), r) + + def test__str__w_interface(self): + method = self._makeOne() + method.interface = type(self) + r = str(method) + self.assertEqual(r, __name__ + '.AttributeTests.TestAttribute') + + def test__str__wo_interface(self): + method = self._makeOne() + r = str(method) + self.assertEqual(r, 'TestAttribute') + + +class MethodTests(AttributeTests): + + DEFAULT_NAME = 'TestMethod' + + def _getTargetClass(self): + from zope.interface.interface import Method + return Method + + def test_optional_as_property(self): + method = self._makeOne() + self.assertEqual(method.optional, {}) + method.optional = {'foo': 'bar'} + self.assertEqual(method.optional, {'foo': 'bar'}) + del method.optional + self.assertEqual(method.optional, {}) + + def test___call___raises_BrokenImplementation(self): + from zope.interface.exceptions import BrokenImplementation + method = self._makeOne() + try: + method() + except BrokenImplementation as e: + self.assertEqual(e.interface, None) + self.assertEqual(e.name, self.DEFAULT_NAME) + else: + self.fail('__call__ should raise BrokenImplementation') + + def test_getSignatureInfo_bare(self): + method = self._makeOne() + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_getSignatureString_bare(self): + method = self._makeOne() + self.assertEqual(method.getSignatureString(), '()') + + def test_getSignatureString_w_only_required(self): + method = self._makeOne() + method.positional = method.required = ['foo'] + self.assertEqual(method.getSignatureString(), '(foo)') + + def test_getSignatureString_w_optional(self): + method = self._makeOne() + method.positional = method.required = ['foo'] + method.optional = {'foo': 'bar'} + self.assertEqual(method.getSignatureString(), "(foo='bar')") + + def test_getSignatureString_w_varargs(self): + method = self._makeOne() + method.varargs = 'args' + self.assertEqual(method.getSignatureString(), "(*args)") + + def test_getSignatureString_w_kwargs(self): + method = self._makeOne() + method.kwargs = 'kw' + self.assertEqual(method.getSignatureString(), "(**kw)") + + def test__repr__w_interface(self): + method = self._makeOne() + method.kwargs = 'kw' + method.interface = type(self) + r = repr(method) + self.assertTrue(r.startswith('<zope.interface.interface.Method object at'), r) + self.assertTrue(r.endswith(' ' + __name__ + '.MethodTests.TestMethod(**kw)>'), r) + + def test__repr__wo_interface(self): + method = self._makeOne() + method.kwargs = 'kw' + r = repr(method) + self.assertTrue(r.startswith('<zope.interface.interface.Method object at'), r) + self.assertTrue(r.endswith(' TestMethod(**kw)>'), r) + + def test__str__w_interface(self): + method = self._makeOne() + method.kwargs = 'kw' + method.interface = type(self) + r = str(method) + self.assertEqual(r, __name__ + '.MethodTests.TestMethod(**kw)') + + def test__str__wo_interface(self): + method = self._makeOne() + method.kwargs = 'kw' + r = str(method) + self.assertEqual(r, 'TestMethod(**kw)') + + +class Test_fromFunction(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.interface import fromFunction + return fromFunction(*args, **kw) + + def test_bare(self): + def _func(): + "DOCSTRING" + method = self._callFUT(_func) + self.assertEqual(method.getName(), '_func') + self.assertEqual(method.getDoc(), 'DOCSTRING') + self.assertEqual(method.interface, None) + self.assertEqual(list(method.getTaggedValueTags()), []) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_w_interface(self): + from zope.interface.interface import InterfaceClass + class IFoo(InterfaceClass): + pass + def _func(): + "DOCSTRING" + method = self._callFUT(_func, interface=IFoo) + self.assertEqual(method.interface, IFoo) + + def test_w_name(self): + def _func(): + "DOCSTRING" + method = self._callFUT(_func, name='anotherName') + self.assertEqual(method.getName(), 'anotherName') + + def test_w_only_required(self): + def _func(foo): + "DOCSTRING" + method = self._callFUT(_func) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), ['foo']) + self.assertEqual(list(info['required']), ['foo']) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_w_optional(self): + def _func(foo='bar'): + "DOCSTRING" + method = self._callFUT(_func) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), ['foo']) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {'foo': 'bar'}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_w_optional_self(self): + # This is a weird case, trying to cover the following code in + # FUT:: + # + # nr = na-len(defaults) + # if nr < 0: + # defaults=defaults[-nr:] + # nr = 0 + def _func(self='bar'): + "DOCSTRING" + method = self._callFUT(_func, imlevel=1) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_w_varargs(self): + def _func(*args): + "DOCSTRING" + method = self._callFUT(_func) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], 'args') + self.assertEqual(info['kwargs'], None) + + def test_w_kwargs(self): + def _func(**kw): + "DOCSTRING" + method = self._callFUT(_func) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], 'kw') + + def test_full_spectrum(self): + def _func(foo, bar='baz', *args, **kw): # pylint:disable=keyword-arg-before-vararg + "DOCSTRING" + method = self._callFUT(_func) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), ['foo', 'bar']) + self.assertEqual(list(info['required']), ['foo']) + self.assertEqual(info['optional'], {'bar': 'baz'}) + self.assertEqual(info['varargs'], 'args') + self.assertEqual(info['kwargs'], 'kw') + + +class Test_fromMethod(unittest.TestCase): + + def _callFUT(self, *args, **kw): + from zope.interface.interface import fromMethod + return fromMethod(*args, **kw) + + def test_no_args(self): + class Foo: + def bar(self): + "DOCSTRING" + method = self._callFUT(Foo.bar) + self.assertEqual(method.getName(), 'bar') + self.assertEqual(method.getDoc(), 'DOCSTRING') + self.assertEqual(method.interface, None) + self.assertEqual(list(method.getTaggedValueTags()), []) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + + def test_full_spectrum(self): + class Foo: + def bar(self, foo, bar='baz', *args, **kw): # pylint:disable=keyword-arg-before-vararg + "DOCSTRING" + method = self._callFUT(Foo.bar) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), ['foo', 'bar']) + self.assertEqual(list(info['required']), ['foo']) + self.assertEqual(info['optional'], {'bar': 'baz'}) + self.assertEqual(info['varargs'], 'args') + self.assertEqual(info['kwargs'], 'kw') + + def test_w_non_method(self): + def foo(): + "DOCSTRING" + method = self._callFUT(foo) + self.assertEqual(method.getName(), 'foo') + self.assertEqual(method.getDoc(), 'DOCSTRING') + self.assertEqual(method.interface, None) + self.assertEqual(list(method.getTaggedValueTags()), []) + info = method.getSignatureInfo() + self.assertEqual(list(info['positional']), []) + self.assertEqual(list(info['required']), []) + self.assertEqual(info['optional'], {}) + self.assertEqual(info['varargs'], None) + self.assertEqual(info['kwargs'], None) + +class DummyDependent: + + def __init__(self): + self._changed = [] + + def changed(self, originally_changed): + self._changed.append(originally_changed) + + +def _barGreaterThanFoo(obj): + from zope.interface.exceptions import Invalid + foo = getattr(obj, 'foo', None) + bar = getattr(obj, 'bar', None) + if foo is not None and isinstance(foo, type(bar)): + # type checking should be handled elsewhere (like, say, + # schema); these invariants should be intra-interface + # constraints. This is a hacky way to do it, maybe, but you + # get the idea + if not bar > foo: + raise Invalid('Please, Boo MUST be greater than Foo!') + +def _ifFooThenBar(obj): + from zope.interface.exceptions import Invalid + if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None): + raise Invalid('If Foo, then Bar!') + + +class _Monkey: + # context-manager for replacing module names in the scope of a test. + def __init__(self, module, **kw): + self.module = module + self.to_restore = {key: getattr(module, key) for key in kw} + for key, value in kw.items(): + setattr(module, key, value) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + for key, value in self.to_restore.items(): + setattr(self.module, key, value) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interfaces.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interfaces.py new file mode 100644 index 00000000..11ba0c04 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_interfaces.py @@ -0,0 +1,128 @@ +import unittest + + +class _ConformsToIObjectEvent: + + def _makeOne(self, target=None): + if target is None: + target = object() + return self._getTargetClass()(target) + + def test_class_conforms_to_IObjectEvent(self): + from zope.interface.interfaces import IObjectEvent + from zope.interface.verify import verifyClass + verifyClass(IObjectEvent, self._getTargetClass()) + + def test_instance_conforms_to_IObjectEvent(self): + from zope.interface.interfaces import IObjectEvent + from zope.interface.verify import verifyObject + verifyObject(IObjectEvent, self._makeOne()) + + +class _ConformsToIRegistrationEvent(_ConformsToIObjectEvent): + + def test_class_conforms_to_IRegistrationEvent(self): + from zope.interface.interfaces import IRegistrationEvent + from zope.interface.verify import verifyClass + verifyClass(IRegistrationEvent, self._getTargetClass()) + + def test_instance_conforms_to_IRegistrationEvent(self): + from zope.interface.interfaces import IRegistrationEvent + from zope.interface.verify import verifyObject + verifyObject(IRegistrationEvent, self._makeOne()) + + +class ObjectEventTests(unittest.TestCase, _ConformsToIObjectEvent): + + def _getTargetClass(self): + from zope.interface.interfaces import ObjectEvent + return ObjectEvent + + def test_ctor(self): + target = object() + event = self._makeOne(target) + self.assertTrue(event.object is target) + + +class RegistrationEventTests(unittest.TestCase, + _ConformsToIRegistrationEvent): + + def _getTargetClass(self): + from zope.interface.interfaces import RegistrationEvent + return RegistrationEvent + + def test___repr__(self): + target = object() + event = self._makeOne(target) + r = repr(event) + self.assertEqual(r.splitlines(), + ['RegistrationEvent event:', repr(target)]) + + +class RegisteredTests(unittest.TestCase, + _ConformsToIRegistrationEvent): + + def _getTargetClass(self): + from zope.interface.interfaces import Registered + return Registered + + def test_class_conforms_to_IRegistered(self): + from zope.interface.interfaces import IRegistered + from zope.interface.verify import verifyClass + verifyClass(IRegistered, self._getTargetClass()) + + def test_instance_conforms_to_IRegistered(self): + from zope.interface.interfaces import IRegistered + from zope.interface.verify import verifyObject + verifyObject(IRegistered, self._makeOne()) + + +class UnregisteredTests(unittest.TestCase, + _ConformsToIRegistrationEvent): + + def _getTargetClass(self): + from zope.interface.interfaces import Unregistered + return Unregistered + + def test_class_conforms_to_IUnregistered(self): + from zope.interface.interfaces import IUnregistered + from zope.interface.verify import verifyClass + verifyClass(IUnregistered, self._getTargetClass()) + + def test_instance_conforms_to_IUnregistered(self): + from zope.interface.interfaces import IUnregistered + from zope.interface.verify import verifyObject + verifyObject(IUnregistered, self._makeOne()) + + +class InterfaceClassTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.interface import InterfaceClass + return InterfaceClass + + def _getTargetInterface(self): + from zope.interface.interfaces import IInterface + return IInterface + + def _makeOne(self): + from zope.interface.interface import Interface + return Interface + + def test_class_conforms(self): + from zope.interface.verify import verifyClass + verifyClass(self._getTargetInterface(), self._getTargetClass()) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + verifyObject(self._getTargetInterface(), self._makeOne()) + + def test_instance_consistent__iro__(self): + from zope.interface import ro + self.assertTrue(ro.is_consistent(self._getTargetInterface())) + + def test_class_consistent__iro__(self): + from zope.interface import ro + from zope.interface import implementedBy + + self.assertTrue(ro.is_consistent(implementedBy(self._getTargetClass()))) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_odd_declarations.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_odd_declarations.py new file mode 100644 index 00000000..55089157 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_odd_declarations.py @@ -0,0 +1,255 @@ +############################################################################## +# +# Copyright (c) 2003 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test interface declarations against ExtensionClass-like classes. + +These tests are to make sure we do something sane in the presence of +classic ExtensionClass classes and instances. +""" +import unittest + +from zope.interface.tests import odd +from zope.interface import Interface +from zope.interface import implementer +from zope.interface import directlyProvides +from zope.interface import providedBy +from zope.interface import directlyProvidedBy +from zope.interface import classImplements +from zope.interface import classImplementsOnly +from zope.interface import implementedBy + +class I1(Interface): pass +class I2(Interface): pass +class I3(Interface): pass +class I31(I3): pass +class I4(Interface): pass +class I5(Interface): pass + +class Odd: + pass +Odd = odd.MetaClass('Odd', Odd.__bases__, {}) + + +class B(Odd): __implemented__ = I2 + + +# TODO: We are going to need more magic to make classProvides work with odd +# classes. This will work in the next iteration. For now, we'll use +# a different mechanism. + +# from zope.interface import classProvides +class A(Odd): + pass +classImplements(A, I1) + +class C(A, B): + pass +classImplements(C, I31) + + +class Test(unittest.TestCase): + + def test_ObjectSpecification(self): + c = C() + directlyProvides(c, I4) + self.assertEqual([i.getName() for i in providedBy(c)], + ['I4', 'I31', 'I1', 'I2'] + ) + self.assertEqual([i.getName() for i in providedBy(c).flattened()], + ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface'] + ) + self.assertTrue(I1 in providedBy(c)) + self.assertFalse(I3 in providedBy(c)) + self.assertTrue(providedBy(c).extends(I3)) + self.assertTrue(providedBy(c).extends(I31)) + self.assertFalse(providedBy(c).extends(I5)) + + class COnly(A, B): + pass + classImplementsOnly(COnly, I31) + + class D(COnly): + pass + classImplements(D, I5) + + classImplements(D, I5) + + c = D() + directlyProvides(c, I4) + self.assertEqual([i.getName() for i in providedBy(c)], + ['I4', 'I5', 'I31']) + self.assertEqual([i.getName() for i in providedBy(c).flattened()], + ['I4', 'I5', 'I31', 'I3', 'Interface']) + self.assertFalse(I1 in providedBy(c)) + self.assertFalse(I3 in providedBy(c)) + self.assertTrue(providedBy(c).extends(I3)) + self.assertFalse(providedBy(c).extends(I1)) + self.assertTrue(providedBy(c).extends(I31)) + self.assertTrue(providedBy(c).extends(I5)) + + class COnly(A, B): __implemented__ = I31 + class D(COnly): + pass + classImplements(D, I5) + + classImplements(D, I5) + c = D() + directlyProvides(c, I4) + self.assertEqual([i.getName() for i in providedBy(c)], + ['I4', 'I5', 'I31']) + self.assertEqual([i.getName() for i in providedBy(c).flattened()], + ['I4', 'I5', 'I31', 'I3', 'Interface']) + self.assertFalse(I1 in providedBy(c)) + self.assertFalse(I3 in providedBy(c)) + self.assertTrue(providedBy(c).extends(I3)) + self.assertFalse(providedBy(c).extends(I1)) + self.assertTrue(providedBy(c).extends(I31)) + self.assertTrue(providedBy(c).extends(I5)) + + def test_classImplements(self): + + @implementer(I3) + class A(Odd): + pass + + @implementer(I4) + class B(Odd): + pass + + class C(A, B): + pass + classImplements(C, I1, I2) + self.assertEqual([i.getName() for i in implementedBy(C)], + ['I1', 'I2', 'I3', 'I4']) + classImplements(C, I5) + self.assertEqual([i.getName() for i in implementedBy(C)], + ['I1', 'I2', 'I5', 'I3', 'I4']) + + def test_classImplementsOnly(self): + @implementer(I3) + class A(Odd): + pass + + @implementer(I4) + class B(Odd): + pass + + class C(A, B): + pass + classImplementsOnly(C, I1, I2) + self.assertEqual([i.__name__ for i in implementedBy(C)], + ['I1', 'I2']) + + + def test_directlyProvides(self): + class IA1(Interface): pass + class IA2(Interface): pass + class IB(Interface): pass + class IC(Interface): pass + class A(Odd): + pass + classImplements(A, IA1, IA2) + + class B(Odd): + pass + classImplements(B, IB) + + class C(A, B): + pass + classImplements(C, IC) + + + ob = C() + directlyProvides(ob, I1, I2) + self.assertTrue(I1 in providedBy(ob)) + self.assertTrue(I2 in providedBy(ob)) + self.assertTrue(IA1 in providedBy(ob)) + self.assertTrue(IA2 in providedBy(ob)) + self.assertTrue(IB in providedBy(ob)) + self.assertTrue(IC in providedBy(ob)) + + directlyProvides(ob, directlyProvidedBy(ob)-I2) + self.assertTrue(I1 in providedBy(ob)) + self.assertFalse(I2 in providedBy(ob)) + self.assertFalse(I2 in providedBy(ob)) + directlyProvides(ob, directlyProvidedBy(ob), I2) + self.assertTrue(I2 in providedBy(ob)) + + # see above + #def TODO_test_classProvides_fails_for_odd_class(self): + # try: + # class A(Odd): + # classProvides(I1) + # except TypeError: + # pass # Success + # self.assert_(False, + # "Shouldn't be able to use directlyProvides on odd class." + # ) + + def test_implementedBy(self): + class I2(I1): pass + + class C1(Odd): + pass + classImplements(C1, I2) + + class C2(C1): + pass + classImplements(C2, I3) + + self.assertEqual([i.getName() for i in implementedBy(C2)], + ['I3', 'I2']) + + def test_odd_metaclass_that_doesnt_subclass_type(self): + # This was originally a doctest in odd.py. + # It verifies that the metaclass the rest of these tests use + # works as expected. + + # This is used for testing support for ExtensionClass in new interfaces. + + class A: + a = 1 + + A = odd.MetaClass('A', A.__bases__, A.__dict__) + + class B: + b = 1 + + B = odd.MetaClass('B', B.__bases__, B.__dict__) + + class C(A, B): + pass + + self.assertEqual(C.__bases__, (A, B)) + + a = A() + aa = A() + self.assertEqual(a.a, 1) + self.assertEqual(aa.a, 1) + + aa.a = 2 + self.assertEqual(a.a, 1) + self.assertEqual(aa.a, 2) + + c = C() + self.assertEqual(c.a, 1) + self.assertEqual(c.b, 1) + + c.b = 2 + self.assertEqual(c.b, 2) + + C.c = 1 + self.assertEqual(c.c, 1) + c.c + + self.assertIs(C.__class__.__class__, C.__class__) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_registry.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_registry.py new file mode 100644 index 00000000..eaaabb28 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_registry.py @@ -0,0 +1,3057 @@ +############################################################################## +# +# Copyright (c) 2001, 2002, 2009 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Component Registry Tests""" +# pylint:disable=protected-access +import unittest + +from zope.interface import Interface +from zope.interface.adapter import VerifyingAdapterRegistry + +from zope.interface.registry import Components + +class ComponentsTests(unittest.TestCase): + + def _getTargetClass(self): + return Components + + def _makeOne(self, name='test', *args, **kw): + return self._getTargetClass()(name, *args, **kw) + + def _wrapEvents(self): + from zope.interface import registry + _events = [] + def _notify(*args, **kw): + _events.append((args, kw)) + _monkey = _Monkey(registry, notify=_notify) + return _monkey, _events + + def test_ctor_no_bases(self): + from zope.interface.adapter import AdapterRegistry + comp = self._makeOne('testing') + self.assertEqual(comp.__name__, 'testing') + self.assertEqual(comp.__bases__, ()) + self.assertTrue(isinstance(comp.adapters, AdapterRegistry)) + self.assertTrue(isinstance(comp.utilities, AdapterRegistry)) + self.assertEqual(comp.adapters.__bases__, ()) + self.assertEqual(comp.utilities.__bases__, ()) + self.assertEqual(comp._utility_registrations, {}) + self.assertEqual(comp._adapter_registrations, {}) + self.assertEqual(comp._subscription_registrations, []) + self.assertEqual(comp._handler_registrations, []) + + def test_ctor_w_base(self): + base = self._makeOne('base') + comp = self._makeOne('testing', (base,)) + self.assertEqual(comp.__name__, 'testing') + self.assertEqual(comp.__bases__, (base,)) + self.assertEqual(comp.adapters.__bases__, (base.adapters,)) + self.assertEqual(comp.utilities.__bases__, (base.utilities,)) + + def test___repr__(self): + comp = self._makeOne('testing') + self.assertEqual(repr(comp), '<Components testing>') + + # test _init_registries / _init_registrations via only caller, __init__. + + def test_assign_to___bases__(self): + base1 = self._makeOne('base1') + base2 = self._makeOne('base2') + comp = self._makeOne() + comp.__bases__ = (base1, base2) + self.assertEqual(comp.__bases__, (base1, base2)) + self.assertEqual(comp.adapters.__bases__, + (base1.adapters, base2.adapters)) + self.assertEqual(comp.utilities.__bases__, + (base1.utilities, base2.utilities)) + + def test_registerUtility_with_component_name(self): + from zope.interface.declarations import named, InterfaceClass + + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + + @named('foo') + class Foo: + pass + foo = Foo() + _info = 'info' + + comp = self._makeOne() + comp.registerUtility(foo, ifoo, info=_info) + self.assertEqual( + comp._utility_registrations[ifoo, 'foo'], + (foo, _info, None)) + + def test_registerUtility_both_factory_and_component(self): + def _factory(): + raise NotImplementedError() + _to_reg = object() + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerUtility, + component=_to_reg, factory=_factory) + + def test_registerUtility_w_component(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = object() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name, _info) + self.assertTrue(comp.utilities._adapters[0][ifoo][_name] is _to_reg) + self.assertEqual(comp._utility_registrations[ifoo, _name], + (_to_reg, _info, None)) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + + def test_registerUtility_w_factory(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = object() + def _factory(): + return _to_reg + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(None, ifoo, _name, _info, factory=_factory) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _factory) + + def test_registerUtility_no_provided_available(self): + class Foo: + pass + + _info = 'info' + _name = 'name' + _to_reg = Foo() + comp = self._makeOne() + self.assertRaises(TypeError, + comp.registerUtility, _to_reg, None, _name, _info) + + def test_registerUtility_wo_provided(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + class Foo: + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = Foo() + directlyProvides(_to_reg, ifoo) + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, None, _name, _info) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + + def test_registerUtility_duplicates_existing_reg(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name, _info) + self.assertEqual(len(_events), 0) + + def test_registerUtility_w_different_info(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info1 = 'info1' + _info2 = 'info2' + _name = 'name' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name, _info1) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name, _info2) + self.assertEqual(len(_events), 2) # unreg, reg + self.assertEqual(comp._utility_registrations[(ifoo, _name)], + (_to_reg, _info2, None)) # replaced + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], + (_to_reg,)) + + def test_registerUtility_w_different_names_same_component(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _other_reg = object() + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_other_reg, ifoo, _name1, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name2, _info) + self.assertEqual(len(_events), 1) # reg + self.assertEqual(comp._utility_registrations[(ifoo, _name1)], + (_other_reg, _info, None)) + self.assertEqual(comp._utility_registrations[(ifoo, _name2)], + (_to_reg, _info, None)) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], + (_other_reg, _to_reg,)) + + def test_registerUtility_replaces_existing_reg(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.interfaces import Registered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _before, _after = object(), object() + comp = self._makeOne() + comp.registerUtility(_before, ifoo, _name, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_after, ifoo, _name, _info) + self.assertEqual(len(_events), 2) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _before) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + args, kw = _events[1] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _after) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + + def test_registerUtility_w_existing_subscr(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name2, _info) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,)) + + def test_registerUtility_wo_event(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = object() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerUtility(_to_reg, ifoo, _name, _info, False) + self.assertEqual(len(_events), 0) + + def test_registerUtility_changes_object_identity_after(self): + # If a subclass changes the identity of the _utility_registrations, + # the cache is updated and the right thing still happens. + class CompThatChangesAfter1Reg(self._getTargetClass()): + reg_count = 0 + def registerUtility(self, *args): + self.reg_count += 1 + super().registerUtility(*args) + if self.reg_count == 1: + self._utility_registrations = dict(self._utility_registrations) + + comp = CompThatChangesAfter1Reg() + comp.registerUtility(object(), Interface) + + self.assertEqual(len(list(comp.registeredUtilities())), 1) + + class IFoo(Interface): + pass + + comp.registerUtility(object(), IFoo) + self.assertEqual(len(list(comp.registeredUtilities())), 2) + + def test_registerUtility_changes_object_identity_before(self): + # If a subclass changes the identity of the _utility_registrations, + # the cache is updated and the right thing still happens. + class CompThatChangesAfter2Reg(self._getTargetClass()): + reg_count = 0 + def registerUtility(self, *args): + self.reg_count += 1 + if self.reg_count == 2: + self._utility_registrations = dict(self._utility_registrations) + + super().registerUtility(*args) + + comp = CompThatChangesAfter2Reg() + comp.registerUtility(object(), Interface) + + self.assertEqual(len(list(comp.registeredUtilities())), 1) + + class IFoo(Interface): + pass + + comp.registerUtility(object(), IFoo) + self.assertEqual(len(list(comp.registeredUtilities())), 2) + + + class IBar(Interface): + pass + + comp.registerUtility(object(), IBar) + self.assertEqual(len(list(comp.registeredUtilities())), 3) + + + def test_unregisterUtility_neither_factory_nor_component_nor_provided(self): + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterUtility, + component=None, provided=None, factory=None) + + def test_unregisterUtility_both_factory_and_component(self): + def _factory(): + raise NotImplementedError() + _to_reg = object() + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterUtility, + component=_to_reg, factory=_factory) + + def test_unregisterUtility_w_component_miss(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _name = 'name' + _to_reg = object() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterUtility(_to_reg, ifoo, _name) + self.assertFalse(unreg) + self.assertFalse(_events) + + def test_unregisterUtility_w_component(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _name = 'name' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterUtility(_to_reg, ifoo, _name) + self.assertTrue(unreg) + self.assertFalse(comp.utilities._adapters) # all erased + self.assertFalse((ifoo, _name) in comp._utility_registrations) + self.assertFalse(comp.utilities._subscribers) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.factory is None) + + def test_unregisterUtility_w_factory(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = object() + def _factory(): + return _to_reg + comp = self._makeOne() + comp.registerUtility(None, ifoo, _name, _info, factory=_factory) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterUtility(None, ifoo, _name, factory=_factory) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.factory is _factory) + + def test_unregisterUtility_wo_explicit_provided(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + class Foo: + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = Foo() + directlyProvides(_to_reg, ifoo) + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterUtility(_to_reg, None, _name) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + + def test_unregisterUtility_wo_component_or_factory(self): + from zope.interface.declarations import directlyProvides + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import UtilityRegistration + + class IFoo(InterfaceClass): + pass + class Foo: + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + _to_reg = Foo() + directlyProvides(_to_reg, ifoo) + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + # Just pass the interface / name + unreg = comp.unregisterUtility(provided=ifoo, name=_name) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, UtilityRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.component is _to_reg) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is None) + + def test_unregisterUtility_w_existing_subscr(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,)) + + def test_unregisterUtility_w_existing_subscr_non_hashable(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = dict() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,)) + + def test_unregisterUtility_w_existing_subscr_non_hashable_fresh_cache(self): + # We correctly populate the cache of registrations if it has gone away + # (for example, the Components was unpickled) + from zope.interface.declarations import InterfaceClass + from zope.interface.registry import _UtilityRegistrations + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = dict() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + + _monkey, _events = self._wrapEvents() + with _monkey: + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,)) + + def test_unregisterUtility_w_existing_subscr_non_hashable_reinitted(self): + # We correctly populate the cache of registrations if the base objects change + # out from under us + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = dict() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + + # zope.component.testing does this + comp.__init__('base') + + comp.registerUtility(_to_reg, ifoo, _name2, _info) + + _monkey, _events = self._wrapEvents() + with _monkey: + # Nothing to do, but we don't break either + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(0, len(comp.utilities._subscribers)) + + def test_unregisterUtility_w_existing_subscr_other_component(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _other_reg = object() + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_other_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], + (_other_reg,)) + + def test_unregisterUtility_w_existing_subscr_other_component_mixed_hash(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + # First register something hashable + _other_reg = object() + # Then it transfers to something unhashable + _to_reg = dict() + comp = self._makeOne() + comp.registerUtility(_other_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + _monkey, _events = self._wrapEvents() + with _monkey: + comp.unregisterUtility(_to_reg, ifoo, _name2) + self.assertEqual(comp.utilities._subscribers[0][ifoo][''], + (_other_reg,)) + + def test_registeredUtilities_empty(self): + comp = self._makeOne() + self.assertEqual(list(comp.registeredUtilities()), []) + + def test_registeredUtilities_notempty(self): + from zope.interface.declarations import InterfaceClass + + from zope.interface.registry import UtilityRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, _name1, _info) + comp.registerUtility(_to_reg, ifoo, _name2, _info) + reg = sorted(comp.registeredUtilities(), key=lambda r: r.name) + self.assertEqual(len(reg), 2) + self.assertTrue(isinstance(reg[0], UtilityRegistration)) + self.assertTrue(reg[0].registry is comp) + self.assertTrue(reg[0].provided is ifoo) + self.assertTrue(reg[0].name is _name1) + self.assertTrue(reg[0].component is _to_reg) + self.assertTrue(reg[0].info is _info) + self.assertTrue(reg[0].factory is None) + self.assertTrue(isinstance(reg[1], UtilityRegistration)) + self.assertTrue(reg[1].registry is comp) + self.assertTrue(reg[1].provided is ifoo) + self.assertTrue(reg[1].name is _name2) + self.assertTrue(reg[1].component is _to_reg) + self.assertTrue(reg[1].info is _info) + self.assertTrue(reg[1].factory is None) + + def test_queryUtility_miss_no_default(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertTrue(comp.queryUtility(ifoo) is None) + + def test_queryUtility_miss_w_default(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + _default = object() + self.assertTrue(comp.queryUtility(ifoo, default=_default) is _default) + + def test_queryUtility_hit(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo) + self.assertTrue(comp.queryUtility(ifoo) is _to_reg) + + def test_getUtility_miss(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import ComponentLookupError + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertRaises(ComponentLookupError, comp.getUtility, ifoo) + + def test_getUtility_hit(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo) + self.assertTrue(comp.getUtility(ifoo) is _to_reg) + + def test_getUtilitiesFor_miss(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertEqual(list(comp.getUtilitiesFor(ifoo)), []) + + def test_getUtilitiesFor_hit(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _name1 = 'name1' + _name2 = 'name2' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, name=_name1) + comp.registerUtility(_to_reg, ifoo, name=_name2) + self.assertEqual(sorted(comp.getUtilitiesFor(ifoo)), + [(_name1, _to_reg), (_name2, _to_reg)]) + + def test_getAllUtilitiesRegisteredFor_miss(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertEqual(list(comp.getAllUtilitiesRegisteredFor(ifoo)), []) + + def test_getAllUtilitiesRegisteredFor_hit(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _name1 = 'name1' + _name2 = 'name2' + _to_reg = object() + comp = self._makeOne() + comp.registerUtility(_to_reg, ifoo, name=_name1) + comp.registerUtility(_to_reg, ifoo, name=_name2) + self.assertEqual(list(comp.getAllUtilitiesRegisteredFor(ifoo)), + [_to_reg]) + + def test_registerAdapter_with_component_name(self): + from zope.interface.declarations import named, InterfaceClass + + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + + @named('foo') + class Foo: + pass + _info = 'info' + + comp = self._makeOne() + comp.registerAdapter(Foo, (ibar,), ifoo, info=_info) + + self.assertEqual( + comp._adapter_registrations[(ibar,), ifoo, 'foo'], + (Foo, _info)) + + def test_registerAdapter_w_explicit_provided_and_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import AdapterRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + + def _factory(context): + raise NotImplementedError() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_factory, (ibar,), ifoo, _name, _info) + self.assertTrue(comp.adapters._adapters[1][ibar][ifoo][_name] + is _factory) + self.assertEqual(comp._adapter_registrations[(ibar,), ifoo, _name], + (_factory, _info)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _factory) + + def test_registerAdapter_no_provided_available(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + + class _Factory: + pass + + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerAdapter, _Factory, (ibar,), + name=_name, info=_info) + + def test_registerAdapter_wo_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import Registered + from zope.interface.registry import AdapterRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + _to_reg = object() + + @implementer(ifoo) + class _Factory: + pass + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_Factory, (ibar,), name=_name, info=_info) + self.assertTrue(comp.adapters._adapters[1][ibar][ifoo][_name] + is _Factory) + self.assertEqual(comp._adapter_registrations[(ibar,), ifoo, _name], + (_Factory, _info)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerAdapter_no_required_available(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + + _info = 'info' + _name = 'name' + class _Factory: + pass + + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerAdapter, _Factory, + provided=ifoo, name=_name, info=_info) + + def test_registerAdapter_w_invalid_required(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + class _Factory: + pass + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerAdapter, _Factory, + ibar, provided=ifoo, name=_name, info=_info) + + def test_registerAdapter_w_required_containing_None(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interface import Interface + from zope.interface.interfaces import Registered + from zope.interface.registry import AdapterRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _name = 'name' + class _Factory: + pass + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_Factory, [None], provided=ifoo, + name=_name, info=_info) + self.assertTrue(comp.adapters._adapters[1][Interface][ifoo][_name] + is _Factory) + self.assertEqual(comp._adapter_registrations[(Interface,), ifoo, _name], + (_Factory, _info)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (Interface,)) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerAdapter_w_required_containing_class(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.declarations import implementedBy + from zope.interface.interfaces import Registered + from zope.interface.registry import AdapterRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + class _Factory: + pass + + @implementer(ibar) + class _Context: + pass + _ctx_impl = implementedBy(_Context) + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_Factory, [_Context], provided=ifoo, + name=_name, info=_info) + self.assertTrue(comp.adapters._adapters[1][_ctx_impl][ifoo][_name] + is _Factory) + self.assertEqual(comp._adapter_registrations[(_ctx_impl,), ifoo, _name], + (_Factory, _info)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (_ctx_impl,)) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerAdapter_w_required_containing_junk(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + + _info = 'info' + _name = 'name' + class _Factory: + pass + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerAdapter, _Factory, [object()], + provided=ifoo, name=_name, info=_info) + + def test_registerAdapter_wo_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import AdapterRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + class _Factory: + __component_adapts__ = (ibar,) + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_Factory, provided=ifoo, name=_name, + info=_info) + self.assertTrue(comp.adapters._adapters[1][ibar][ifoo][_name] + is _Factory) + self.assertEqual(comp._adapter_registrations[(ibar,), ifoo, _name], + (_Factory, _info)) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertTrue(event.object.name is _name) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerAdapter_wo_event(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _name = 'name' + + def _factory(context): + raise NotImplementedError() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerAdapter(_factory, (ibar,), ifoo, _name, _info, + event=False) + self.assertEqual(len(_events), 0) + + def test_unregisterAdapter_neither_factory_nor_provided(self): + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterAdapter, + factory=None, provided=None) + + def test_unregisterAdapter_neither_factory_nor_required(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterAdapter, + factory=None, provided=ifoo, required=None) + + def test_unregisterAdapter_miss(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + pass + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterAdapter(_Factory, (ibar,), ifoo) + self.assertFalse(unreg) + + def test_unregisterAdapter_hit_w_explicit_provided_and_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import AdapterRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + pass + + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterAdapter(_Factory, (ibar,), ifoo) + self.assertTrue(unreg) + self.assertFalse(comp.adapters._adapters) + self.assertFalse(comp._adapter_registrations) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_unregisterAdapter_wo_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import Unregistered + from zope.interface.registry import AdapterRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + @implementer(ifoo) + class _Factory: + pass + + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterAdapter(_Factory, (ibar,)) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_unregisterAdapter_wo_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import AdapterRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + __component_adapts__ = (ibar,) + + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterAdapter(_Factory, provided=ifoo) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, AdapterRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_registeredAdapters_empty(self): + comp = self._makeOne() + self.assertEqual(list(comp.registeredAdapters()), []) + + def test_registeredAdapters_notempty(self): + from zope.interface.declarations import InterfaceClass + + from zope.interface.registry import AdapterRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IFoo') + _info = 'info' + _name1 = 'name1' + _name2 = 'name2' + class _Factory: + pass + + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo, _name1, _info) + comp.registerAdapter(_Factory, (ibar,), ifoo, _name2, _info) + reg = sorted(comp.registeredAdapters(), key=lambda r: r.name) + self.assertEqual(len(reg), 2) + self.assertTrue(isinstance(reg[0], AdapterRegistration)) + self.assertTrue(reg[0].registry is comp) + self.assertTrue(reg[0].provided is ifoo) + self.assertEqual(reg[0].required, (ibar,)) + self.assertTrue(reg[0].name is _name1) + self.assertTrue(reg[0].info is _info) + self.assertTrue(reg[0].factory is _Factory) + self.assertTrue(isinstance(reg[1], AdapterRegistration)) + self.assertTrue(reg[1].registry is comp) + self.assertTrue(reg[1].provided is ifoo) + self.assertEqual(reg[1].required, (ibar,)) + self.assertTrue(reg[1].name is _name2) + self.assertTrue(reg[1].info is _info) + self.assertTrue(reg[1].factory is _Factory) + + def test_queryAdapter_miss_no_default(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + _context = object() + self.assertTrue(comp.queryAdapter(_context, ifoo) is None) + + def test_queryAdapter_miss_w_default(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + _context = object() + _default = object() + self.assertTrue( + comp.queryAdapter(_context, ifoo, default=_default) is _default) + + def test_queryAdapter_hit(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + def __init__(self, context): + self.context = context + @implementer(ibar) + class _Context: + pass + _context = _Context() + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo) + adapter = comp.queryAdapter(_context, ifoo) + self.assertTrue(isinstance(adapter, _Factory)) + self.assertTrue(adapter.context is _context) + + def test_getAdapter_miss(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import ComponentLookupError + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + @implementer(ibar) + class _Context: + pass + _context = _Context() + comp = self._makeOne() + self.assertRaises(ComponentLookupError, + comp.getAdapter, _context, ifoo) + + def test_getAdapter_hit(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + def __init__(self, context): + self.context = context + @implementer(ibar) + class _Context: + pass + _context = _Context() + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar,), ifoo) + adapter = comp.getAdapter(_context, ifoo) + self.assertIsInstance(adapter, _Factory) + self.assertIs(adapter.context, _context) + + def test_getAdapter_hit_super(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + class IFoo(Interface): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + class AdapterBase: + def __init__(self, context): + self.context = context + + class AdapterDerived: + def __init__(self, context): + self.context = context + + comp = self._makeOne() + comp.registerAdapter(AdapterDerived, (IDerived,), IFoo) + comp.registerAdapter(AdapterBase, (IBase,), IFoo) + self._should_not_change(comp) + + derived = Derived() + adapter = comp.getAdapter(derived, IFoo) + self.assertIsInstance(adapter, AdapterDerived) + self.assertIs(adapter.context, derived) + + supe = super(Derived, derived) + adapter = comp.getAdapter(supe, IFoo) + self.assertIsInstance(adapter, AdapterBase) + self.assertIs(adapter.context, derived) + + def test_getAdapter_hit_super_when_parent_implements_interface_diamond(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + class IFoo(Interface): + pass + + class Base: + pass + + class Child1(Base): + pass + + @implementer(IBase) + class Child2(Base): + pass + + @implementer(IDerived) + class Derived(Child1, Child2): + pass + + class AdapterBase: + def __init__(self, context): + self.context = context + + class AdapterDerived: + def __init__(self, context): + self.context = context + + comp = self._makeOne() + comp.registerAdapter(AdapterDerived, (IDerived,), IFoo) + comp.registerAdapter(AdapterBase, (IBase,), IFoo) + self._should_not_change(comp) + + derived = Derived() + adapter = comp.getAdapter(derived, IFoo) + self.assertIsInstance(adapter, AdapterDerived) + self.assertIs(adapter.context, derived) + + supe = super(Derived, derived) + adapter = comp.getAdapter(supe, IFoo) + self.assertIsInstance(adapter, AdapterBase) + self.assertIs(adapter.context, derived) + + def test_queryMultiAdapter_miss(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + comp = self._makeOne() + self.assertEqual(comp.queryMultiAdapter((_context1, _context2), ifoo), + None) + + def test_queryMultiAdapter_miss_w_default(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + _default = object() + comp = self._makeOne() + self.assertTrue( + comp.queryMultiAdapter((_context1, _context2), ifoo, + default=_default) is _default) + + def test_queryMultiAdapter_hit(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + class _Factory: + def __init__(self, context1, context2): + self.context = context1, context2 + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar, ibaz), ifoo) + adapter = comp.queryMultiAdapter((_context1, _context2), ifoo) + self.assertTrue(isinstance(adapter, _Factory)) + self.assertEqual(adapter.context, (_context1, _context2)) + + def test_getMultiAdapter_miss(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import ComponentLookupError + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + comp = self._makeOne() + self.assertRaises(ComponentLookupError, + comp.getMultiAdapter, (_context1, _context2), ifoo) + + def test_getMultiAdapter_hit(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + class _Factory: + def __init__(self, context1, context2): + self.context = context1, context2 + comp = self._makeOne() + comp.registerAdapter(_Factory, (ibar, ibaz), ifoo) + adapter = comp.getMultiAdapter((_context1, _context2), ifoo) + self.assertTrue(isinstance(adapter, _Factory)) + self.assertEqual(adapter.context, (_context1, _context2)) + + def _should_not_change(self, comp): + # Be sure that none of the underlying structures + # get told that they have changed during this process + # because that invalidates caches. + def no_changes(*args): + self.fail("Nothing should get changed") + comp.changed = no_changes + comp.adapters.changed = no_changes + comp.adapters._v_lookup.changed = no_changes + + def test_getMultiAdapter_hit_super(self): + from zope.interface import Interface + from zope.interface.declarations import implementer + + class IBase(Interface): + pass + + class IDerived(IBase): + pass + + class IFoo(Interface): + pass + + @implementer(IBase) + class Base: + pass + + @implementer(IDerived) + class Derived(Base): + pass + + class AdapterBase: + def __init__(self, context1, context2): + self.context1 = context1 + self.context2 = context2 + + class AdapterDerived(AdapterBase): + pass + + comp = self._makeOne() + comp.registerAdapter(AdapterDerived, (IDerived, IDerived), IFoo) + comp.registerAdapter(AdapterBase, (IBase, IDerived), IFoo) + self._should_not_change(comp) + + derived = Derived() + adapter = comp.getMultiAdapter((derived, derived), IFoo) + self.assertIsInstance(adapter, AdapterDerived) + self.assertIs(adapter.context1, derived) + self.assertIs(adapter.context2, derived) + + supe = super(Derived, derived) + adapter = comp.getMultiAdapter((supe, derived), IFoo) + self.assertIsInstance(adapter, AdapterBase) + self.assertNotIsInstance(adapter, AdapterDerived) + self.assertIs(adapter.context1, derived) + self.assertIs(adapter.context2, derived) + + def test_getAdapters_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + comp = self._makeOne() + self.assertEqual( + list(comp.getAdapters((_context1, _context2), ifoo)), []) + + def test_getAdapters_factory_returns_None(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + comp = self._makeOne() + _called_with = [] + def _side_effect_only(context1, context2): + _called_with.append((context1, context2)) + return None + comp.registerAdapter(_side_effect_only, (ibar, ibaz), ifoo) + self.assertEqual( + list(comp.getAdapters((_context1, _context2), ifoo)), []) + self.assertEqual(_called_with, [(_context1, _context2)]) + + def test_getAdapters_non_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + ibaz = IFoo('IBaz') + @implementer(ibar) + class _Context1: + pass + @implementer(ibaz) + class _Context2: + pass + _context1 = _Context1() + _context2 = _Context2() + class _Factory1: + def __init__(self, context1, context2): + self.context = context1, context2 + class _Factory2: + def __init__(self, context1, context2): + self.context = context1, context2 + _name1 = 'name1' + _name2 = 'name2' + comp = self._makeOne() + comp.registerAdapter(_Factory1, (ibar, ibaz), ifoo, name=_name1) + comp.registerAdapter(_Factory2, (ibar, ibaz), ifoo, name=_name2) + found = sorted(comp.getAdapters((_context1, _context2), ifoo)) + self.assertEqual(len(found), 2) + self.assertEqual(found[0][0], _name1) + self.assertTrue(isinstance(found[0][1], _Factory1)) + self.assertEqual(found[1][0], _name2) + self.assertTrue(isinstance(found[1][1], _Factory2)) + + def test_registerSubscriptionAdapter_w_nonblank_name(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _name = 'name' + _info = 'info' + def _factory(context): + raise NotImplementedError() + + comp = self._makeOne() + self.assertRaises(TypeError, comp.registerSubscriptionAdapter, + _factory, (ibar,), ifoo, _name, _info) + + def test_registerSubscriptionAdapter_w_explicit_provided_and_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import SubscriptionRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _blank = '' + _info = 'info' + def _factory(context): + raise NotImplementedError() + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerSubscriptionAdapter(_factory, (ibar,), ifoo, + info=_info) + reg = comp.adapters._subscribers[1][ibar][ifoo][_blank] + self.assertEqual(len(reg), 1) + self.assertTrue(reg[0] is _factory) + self.assertEqual(comp._subscription_registrations, + [((ibar,), ifoo, _blank, _factory, _info)]) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, _blank) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _factory) + + def test_registerSubscriptionAdapter_wo_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import Registered + from zope.interface.registry import SubscriptionRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _blank = '' + + @implementer(ifoo) + class _Factory: + pass + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerSubscriptionAdapter(_Factory, (ibar,), info=_info) + reg = comp.adapters._subscribers[1][ibar][ifoo][_blank] + self.assertEqual(len(reg), 1) + self.assertTrue(reg[0] is _Factory) + self.assertEqual(comp._subscription_registrations, + [((ibar,), ifoo, _blank, _Factory, _info)]) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, _blank) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerSubscriptionAdapter_wo_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import SubscriptionRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _info = 'info' + _blank = '' + class _Factory: + __component_adapts__ = (ibar,) + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerSubscriptionAdapter( + _Factory, provided=ifoo, info=_info) + reg = comp.adapters._subscribers[1][ibar][ifoo][_blank] + self.assertEqual(len(reg), 1) + self.assertTrue(reg[0] is _Factory) + self.assertEqual(comp._subscription_registrations, + [((ibar,), ifoo, _blank, _Factory, _info)]) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, _blank) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _Factory) + + def test_registerSubscriptionAdapter_wo_event(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _blank = '' + _info = 'info' + + def _factory(context): + raise NotImplementedError() + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerSubscriptionAdapter(_factory, (ibar,), ifoo, + info=_info, event=False) + self.assertEqual(len(_events), 0) + + def test_registeredSubscriptionAdapters_empty(self): + comp = self._makeOne() + self.assertEqual(list(comp.registeredSubscriptionAdapters()), []) + + def test_registeredSubscriptionAdapters_notempty(self): + from zope.interface.declarations import InterfaceClass + + from zope.interface.registry import SubscriptionRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IFoo') + _info = 'info' + _blank = '' + class _Factory: + pass + + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo, info=_info) + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo, info=_info) + reg = list(comp.registeredSubscriptionAdapters()) + self.assertEqual(len(reg), 2) + self.assertTrue(isinstance(reg[0], SubscriptionRegistration)) + self.assertTrue(reg[0].registry is comp) + self.assertTrue(reg[0].provided is ifoo) + self.assertEqual(reg[0].required, (ibar,)) + self.assertEqual(reg[0].name, _blank) + self.assertTrue(reg[0].info is _info) + self.assertTrue(reg[0].factory is _Factory) + self.assertTrue(isinstance(reg[1], SubscriptionRegistration)) + self.assertTrue(reg[1].registry is comp) + self.assertTrue(reg[1].provided is ifoo) + self.assertEqual(reg[1].required, (ibar,)) + self.assertEqual(reg[1].name, _blank) + self.assertTrue(reg[1].info is _info) + self.assertTrue(reg[1].factory is _Factory) + + def test_unregisterSubscriptionAdapter_w_nonblank_name(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + _nonblank = 'nonblank' + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterSubscriptionAdapter, + required=ifoo, provided=ibar, name=_nonblank) + + def test_unregisterSubscriptionAdapter_neither_factory_nor_provided(self): + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterSubscriptionAdapter, + factory=None, provided=None) + + def test_unregisterSubscriptionAdapter_neither_factory_nor_required(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterSubscriptionAdapter, + factory=None, provided=ifoo, required=None) + + def test_unregisterSubscriptionAdapter_miss(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + pass + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterSubscriptionAdapter(_Factory, (ibar,), ifoo) + self.assertFalse(unreg) + self.assertFalse(_events) + + def test_unregisterSubscriptionAdapter_hit_wo_factory(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import SubscriptionRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + pass + + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterSubscriptionAdapter(None, (ibar,), ifoo) + self.assertTrue(unreg) + self.assertFalse(comp.adapters._subscribers) + self.assertFalse(comp._subscription_registrations) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is None) + + def test_unregisterSubscriptionAdapter_hit_w_factory(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import SubscriptionRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + pass + + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterSubscriptionAdapter(_Factory, (ibar,), ifoo) + self.assertTrue(unreg) + self.assertFalse(comp.adapters._subscribers) + self.assertFalse(comp._subscription_registrations) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_unregisterSubscriptionAdapter_wo_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + from zope.interface.interfaces import Unregistered + from zope.interface.registry import SubscriptionRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + @implementer(ifoo) + class _Factory: + pass + + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterSubscriptionAdapter(_Factory, (ibar,)) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_unregisterSubscriptionAdapter_wo_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import SubscriptionRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + __component_adapts__ = (ibar,) + + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterSubscriptionAdapter(_Factory, provided=ifoo) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, SubscriptionRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertTrue(event.object.provided is ifoo) + self.assertEqual(event.object.required, (ibar,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_subscribers_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + comp = self._makeOne() + @implementer(ibar) + class Bar: + pass + bar = Bar() + self.assertEqual(list(comp.subscribers((bar,), ifoo)), []) + + def test_subscribers_non_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Factory: + __component_adapts__ = (ibar,) + def __init__(self, context): + self._context = context + class _Derived(_Factory): + pass + comp = self._makeOne() + comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo) + comp.registerSubscriptionAdapter(_Derived, (ibar,), ifoo) + @implementer(ibar) + class Bar: + pass + bar = Bar() + subscribers = comp.subscribers((bar,), ifoo) + def _klassname(x): + return x.__class__.__name__ + subscribers = sorted(subscribers, key=_klassname) + self.assertEqual(len(subscribers), 2) + self.assertTrue(isinstance(subscribers[0], _Derived)) + self.assertTrue(isinstance(subscribers[1], _Factory)) + + def test_registerHandler_w_nonblank_name(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _nonblank = 'nonblank' + comp = self._makeOne() + def _factory(context): + raise NotImplementedError() + + self.assertRaises(TypeError, comp.registerHandler, _factory, + required=ifoo, name=_nonblank) + + def test_registerHandler_w_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Registered + from zope.interface.registry import HandlerRegistration + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _blank = '' + _info = 'info' + def _factory(context): + raise NotImplementedError() + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerHandler(_factory, (ifoo,), info=_info) + reg = comp.adapters._subscribers[1][ifoo][None][_blank] + self.assertEqual(len(reg), 1) + self.assertTrue(reg[0] is _factory) + self.assertEqual(comp._handler_registrations, + [((ifoo,), _blank, _factory, _info)]) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Registered)) + self.assertTrue(isinstance(event.object, HandlerRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertEqual(event.object.required, (ifoo,)) + self.assertEqual(event.object.name, _blank) + self.assertTrue(event.object.info is _info) + self.assertTrue(event.object.factory is _factory) + + def test_registerHandler_wo_explicit_required_no_event(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _info = 'info' + _blank = '' + class _Factory: + __component_adapts__ = (ifoo,) + pass + + comp = self._makeOne() + _monkey, _events = self._wrapEvents() + with _monkey: + comp.registerHandler(_Factory, info=_info, event=False) + reg = comp.adapters._subscribers[1][ifoo][None][_blank] + self.assertEqual(len(reg), 1) + self.assertTrue(reg[0] is _Factory) + self.assertEqual(comp._handler_registrations, + [((ifoo,), _blank, _Factory, _info)]) + self.assertEqual(len(_events), 0) + + def test_registeredHandlers_empty(self): + comp = self._makeOne() + self.assertFalse(list(comp.registeredHandlers())) + + def test_registeredHandlers_non_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.registry import HandlerRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + def _factory1(context): + raise NotImplementedError() + def _factory2(context): + raise NotImplementedError() + comp = self._makeOne() + comp.registerHandler(_factory1, (ifoo,)) + comp.registerHandler(_factory2, (ifoo,)) + def _factory_name(x): + return x.factory.__code__.co_name + subscribers = sorted(comp.registeredHandlers(), key=_factory_name) + self.assertEqual(len(subscribers), 2) + self.assertTrue(isinstance(subscribers[0], HandlerRegistration)) + self.assertEqual(subscribers[0].required, (ifoo,)) + self.assertEqual(subscribers[0].name, '') + self.assertEqual(subscribers[0].factory, _factory1) + self.assertEqual(subscribers[0].info, '') + self.assertTrue(isinstance(subscribers[1], HandlerRegistration)) + self.assertEqual(subscribers[1].required, (ifoo,)) + self.assertEqual(subscribers[1].name, '') + self.assertEqual(subscribers[1].factory, _factory2) + self.assertEqual(subscribers[1].info, '') + + def test_unregisterHandler_w_nonblank_name(self): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _nonblank = 'nonblank' + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterHandler, + required=(ifoo,), name=_nonblank) + + def test_unregisterHandler_neither_factory_nor_required(self): + comp = self._makeOne() + self.assertRaises(TypeError, comp.unregisterHandler) + + def test_unregisterHandler_miss(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + unreg = comp.unregisterHandler(required=(ifoo,)) + self.assertFalse(unreg) + + def test_unregisterHandler_hit_w_factory_and_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import HandlerRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + def _factory(context): + raise NotImplementedError() + comp = self._makeOne() + comp.registerHandler(_factory, (ifoo,)) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterHandler(_factory, (ifoo,)) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, HandlerRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertEqual(event.object.required, (ifoo,)) + self.assertEqual(event.object.name, '') + self.assertTrue(event.object.factory is _factory) + + def test_unregisterHandler_hit_w_only_explicit_provided(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import HandlerRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + def _factory(context): + raise NotImplementedError() + comp = self._makeOne() + comp.registerHandler(_factory, (ifoo,)) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterHandler(required=(ifoo,)) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, HandlerRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertEqual(event.object.required, (ifoo,)) + self.assertEqual(event.object.name, '') + self.assertTrue(event.object.factory is None) + + def test_unregisterHandler_wo_explicit_required(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.interfaces import Unregistered + from zope.interface.registry import HandlerRegistration + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + class _Factory: + __component_adapts__ = (ifoo,) + + comp = self._makeOne() + comp.registerHandler(_Factory) + _monkey, _events = self._wrapEvents() + with _monkey: + unreg = comp.unregisterHandler(_Factory) + self.assertTrue(unreg) + self.assertEqual(len(_events), 1) + args, kw = _events[0] + event, = args + self.assertEqual(kw, {}) + self.assertTrue(isinstance(event, Unregistered)) + self.assertTrue(isinstance(event.object, HandlerRegistration)) + self.assertTrue(event.object.registry is comp) + self.assertEqual(event.object.required, (ifoo,)) + self.assertEqual(event.object.name, '') + self.assertEqual(event.object.info, '') + self.assertTrue(event.object.factory is _Factory) + + def test_handle_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + comp = self._makeOne() + @implementer(ifoo) + class Bar: + pass + bar = Bar() + comp.handle((bar,)) # doesn't raise + + def test_handle_non_empty(self): + from zope.interface.declarations import InterfaceClass + from zope.interface.declarations import implementer + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + _called_1 = [] + def _factory_1(context): + _called_1.append(context) + _called_2 = [] + def _factory_2(context): + _called_2.append(context) + comp = self._makeOne() + comp.registerHandler(_factory_1, (ifoo,)) + comp.registerHandler(_factory_2, (ifoo,)) + @implementer(ifoo) + class Bar: + pass + bar = Bar() + comp.handle(bar) + self.assertEqual(_called_1, [bar]) + self.assertEqual(_called_2, [bar]) + + def test_register_unregister_identical_objects_provided(self, identical=True): + # https://github.com/zopefoundation/zope.interface/issues/227 + class IFoo(Interface): + pass + + comp = self._makeOne() + first = object() + second = first if identical else object() + + comp.registerUtility(first, provided=IFoo) + comp.registerUtility(second, provided=IFoo, name='bar') + + self.assertEqual(len(comp.utilities._subscribers), 1) + self.assertEqual(comp.utilities._subscribers, [{ + IFoo: {'': (first, ) if identical else (first, second)} + }]) + self.assertEqual(comp.utilities._provided, { + IFoo: 3 if identical else 4 + }) + + res = comp.unregisterUtility(first, provided=IFoo) + self.assertTrue(res) + res = comp.unregisterUtility(second, provided=IFoo, name='bar') + self.assertTrue(res) + + self.assertEqual(comp.utilities._provided, {}) + self.assertEqual(len(comp.utilities._subscribers), 0) + + def test_register_unregister_nonequal_objects_provided(self): + self.test_register_unregister_identical_objects_provided(identical=False) + + def test_rebuildUtilityRegistryFromLocalCache(self): + class IFoo(Interface): + "Does nothing" + + class UtilityImplementingFoo: + "Does nothing" + + comps = self._makeOne() + + for i in range(30): + comps.registerUtility(UtilityImplementingFoo(), IFoo, name='{}'.format(i)) + + orig_generation = comps.utilities._generation + + orig_adapters = comps.utilities._adapters + self.assertEqual(len(orig_adapters), 1) + self.assertEqual(len(orig_adapters[0]), 1) + self.assertEqual(len(orig_adapters[0][IFoo]), 30) + + orig_subscribers = comps.utilities._subscribers + self.assertEqual(len(orig_subscribers), 1) + self.assertEqual(len(orig_subscribers[0]), 1) + self.assertEqual(len(orig_subscribers[0][IFoo]), 1) + self.assertEqual(len(orig_subscribers[0][IFoo]['']), 30) + + # Blow a bunch of them away, creating artificial corruption + new_adapters = comps.utilities._adapters = type(orig_adapters)() + new_adapters.append({}) + d = new_adapters[0][IFoo] = {} + for name in range(10): + name = str(str(name)) + d[name] = orig_adapters[0][IFoo][name] + + self.assertNotEqual(orig_adapters, new_adapters) + + new_subscribers = comps.utilities._subscribers = type(orig_subscribers)() + new_subscribers.append({}) + d = new_subscribers[0][IFoo] = {} + d[''] = () + + for name in range(5, 12): # 12 - 5 = 7 + name = str(str(name)) + comp = orig_adapters[0][IFoo][name] + d[''] += (comp,) + + # We can preflight (by default) and nothing changes + rebuild_results_preflight = comps.rebuildUtilityRegistryFromLocalCache() + + self.assertEqual(comps.utilities._generation, orig_generation) + self.assertEqual(rebuild_results_preflight, { + 'did_not_register': 10, + 'needed_registered': 20, + + 'did_not_subscribe': 7, + 'needed_subscribed': 23, + }) + + # Now for real + rebuild_results = comps.rebuildUtilityRegistryFromLocalCache(rebuild=True) + + # The generation only got incremented once + self.assertEqual(comps.utilities._generation, orig_generation + 1) + # The result was the same + self.assertEqual(rebuild_results_preflight, rebuild_results) + self.assertEqual(new_adapters, orig_adapters) + self.assertEqual( + len(new_subscribers[0][IFoo]['']), + len(orig_subscribers[0][IFoo][''])) + + for orig_subscriber in orig_subscribers[0][IFoo]['']: + self.assertIn(orig_subscriber, new_subscribers[0][IFoo]['']) + + # Preflighting, rebuilding again produce no changes. + preflight_after = comps.rebuildUtilityRegistryFromLocalCache() + self.assertEqual(preflight_after, { + 'did_not_register': 30, + 'needed_registered': 0, + + 'did_not_subscribe': 30, + 'needed_subscribed': 0, + }) + + rebuild_after = comps.rebuildUtilityRegistryFromLocalCache(rebuild=True) + self.assertEqual(rebuild_after, preflight_after) + self.assertEqual(comps.utilities._generation, orig_generation + 1) + + +class UnhashableComponentsTests(ComponentsTests): + + def _getTargetClass(self): + # Mimic what pyramid does to create an unhashable + # registry + class Components(super(UnhashableComponentsTests, self)._getTargetClass(), dict): + pass + return Components + +# Test _getUtilityProvided, _getAdapterProvided, _getAdapterRequired via their +# callers (Component.registerUtility, Component.registerAdapter). + + +class UtilityRegistrationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.registry import UtilityRegistration + return UtilityRegistration + + def _makeOne(self, component=None, factory=None): + from zope.interface.declarations import InterfaceClass + + class InterfaceClassSubclass(InterfaceClass): + pass + + ifoo = InterfaceClassSubclass('IFoo') + class _Registry: + def __repr__(self): + return '_REGISTRY' + registry = _Registry() + name = 'name' + doc = 'DOCSTRING' + klass = self._getTargetClass() + return (klass(registry, ifoo, name, component, doc, factory), + registry, + name, + ) + + def test_class_conforms_to_IUtilityRegistration(self): + from zope.interface.verify import verifyClass + from zope.interface.interfaces import IUtilityRegistration + verifyClass(IUtilityRegistration, self._getTargetClass()) + + def test_instance_conforms_to_IUtilityRegistration(self): + from zope.interface.verify import verifyObject + from zope.interface.interfaces import IUtilityRegistration + ur, _, _ = self._makeOne() + verifyObject(IUtilityRegistration, ur) + + def test___repr__(self): + class _Component: + __name__ = 'TEST' + _component = _Component() + ur, _registry, _name = self._makeOne(_component) + self.assertEqual(repr(ur), + "UtilityRegistration(_REGISTRY, IFoo, %r, TEST, None, 'DOCSTRING')" + % (_name)) + + def test___repr___provided_wo_name(self): + class _Component: + def __repr__(self): + return 'TEST' + _component = _Component() + ur, _registry, _name = self._makeOne(_component) + ur.provided = object() + self.assertEqual(repr(ur), + "UtilityRegistration(_REGISTRY, None, %r, TEST, None, 'DOCSTRING')" + % (_name)) + + def test___repr___component_wo_name(self): + class _Component: + def __repr__(self): + return 'TEST' + _component = _Component() + ur, _registry, _name = self._makeOne(_component) + ur.provided = object() + self.assertEqual(repr(ur), + "UtilityRegistration(_REGISTRY, None, %r, TEST, None, 'DOCSTRING')" + % (_name)) + + def test___hash__(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertEqual(ur.__hash__(), id(ur)) + + def test___eq___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertTrue(ur == ur) + + def test___eq___hit(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + self.assertTrue(ur == ur2) + + def test___eq___miss(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + self.assertFalse(ur == ur2) + + def test___ne___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertFalse(ur != ur) + + def test___ne___hit(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + self.assertFalse(ur != ur2) + + def test___ne___miss(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + self.assertTrue(ur != ur2) + + def test___lt___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertFalse(ur < ur) + + def test___lt___hit(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + self.assertFalse(ur < ur2) + + def test___lt___miss(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + ur2.name = _name + '2' + self.assertTrue(ur < ur2) + + def test___le___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertTrue(ur <= ur) + + def test___le___hit(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + self.assertTrue(ur <= ur2) + + def test___le___miss(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + ur2.name = _name + '2' + self.assertTrue(ur <= ur2) + + def test___gt___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertFalse(ur > ur) + + def test___gt___hit(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + ur2.name = _name + '2' + self.assertTrue(ur2 > ur) + + def test___gt___miss(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + self.assertFalse(ur2 > ur) + + def test___ge___identity(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + self.assertTrue(ur >= ur) + + def test___ge___miss(self): + _component = object() + _component2 = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component2) + ur2.name = _name + '2' + self.assertFalse(ur >= ur2) + + def test___ge___hit(self): + _component = object() + ur, _registry, _name = self._makeOne(_component) + ur2, _, _ = self._makeOne(_component) + ur2.name = _name + '2' + self.assertTrue(ur2 >= ur) + + +class AdapterRegistrationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.registry import AdapterRegistration + return AdapterRegistration + + def _makeOne(self, component=None): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Registry: + def __repr__(self): + return '_REGISTRY' + registry = _Registry() + name = 'name' + doc = 'DOCSTRING' + klass = self._getTargetClass() + return (klass(registry, (ibar,), ifoo, name, component, doc), + registry, + name, + ) + + def test_class_conforms_to_IAdapterRegistration(self): + from zope.interface.verify import verifyClass + from zope.interface.interfaces import IAdapterRegistration + verifyClass(IAdapterRegistration, self._getTargetClass()) + + def test_instance_conforms_to_IAdapterRegistration(self): + from zope.interface.verify import verifyObject + from zope.interface.interfaces import IAdapterRegistration + ar, _, _ = self._makeOne() + verifyObject(IAdapterRegistration, ar) + + def test___repr__(self): + class _Component: + __name__ = 'TEST' + _component = _Component() + ar, _registry, _name = self._makeOne(_component) + self.assertEqual(repr(ar), + ("AdapterRegistration(_REGISTRY, [IBar], IFoo, %r, TEST, " + + "'DOCSTRING')") % (_name)) + + def test___repr___provided_wo_name(self): + class _Component: + def __repr__(self): + return 'TEST' + _component = _Component() + ar, _registry, _name = self._makeOne(_component) + ar.provided = object() + self.assertEqual(repr(ar), + ("AdapterRegistration(_REGISTRY, [IBar], None, %r, TEST, " + + "'DOCSTRING')") % (_name)) + + def test___repr___component_wo_name(self): + class _Component: + def __repr__(self): + return 'TEST' + _component = _Component() + ar, _registry, _name = self._makeOne(_component) + ar.provided = object() + self.assertEqual(repr(ar), + ("AdapterRegistration(_REGISTRY, [IBar], None, %r, TEST, " + + "'DOCSTRING')") % (_name)) + + def test___hash__(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertEqual(ar.__hash__(), id(ar)) + + def test___eq___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertTrue(ar == ar) + + def test___eq___hit(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + self.assertTrue(ar == ar2) + + def test___eq___miss(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + self.assertFalse(ar == ar2) + + def test___ne___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertFalse(ar != ar) + + def test___ne___miss(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + self.assertFalse(ar != ar2) + + def test___ne___hit_component(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + self.assertTrue(ar != ar2) + + def test___ne___hit_provided(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ibaz = IFoo('IBaz') + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + ar2.provided = ibaz + self.assertTrue(ar != ar2) + + def test___ne___hit_required(self): + from zope.interface.declarations import InterfaceClass + class IFoo(InterfaceClass): + pass + ibaz = IFoo('IBaz') + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + ar2.required = (ibaz,) + self.assertTrue(ar != ar2) + + def test___lt___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertFalse(ar < ar) + + def test___lt___hit(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + self.assertFalse(ar < ar2) + + def test___lt___miss(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + ar2.name = _name + '2' + self.assertTrue(ar < ar2) + + def test___le___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertTrue(ar <= ar) + + def test___le___hit(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + self.assertTrue(ar <= ar2) + + def test___le___miss(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + ar2.name = _name + '2' + self.assertTrue(ar <= ar2) + + def test___gt___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertFalse(ar > ar) + + def test___gt___hit(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + ar2.name = _name + '2' + self.assertTrue(ar2 > ar) + + def test___gt___miss(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + self.assertFalse(ar2 > ar) + + def test___ge___identity(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + self.assertTrue(ar >= ar) + + def test___ge___miss(self): + _component = object() + _component2 = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component2) + ar2.name = _name + '2' + self.assertFalse(ar >= ar2) + + def test___ge___hit(self): + _component = object() + ar, _registry, _name = self._makeOne(_component) + ar2, _, _ = self._makeOne(_component) + ar2.name = _name + '2' + self.assertTrue(ar2 >= ar) + + +class SubscriptionRegistrationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.registry import SubscriptionRegistration + return SubscriptionRegistration + + def _makeOne(self, component=None): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + ibar = IFoo('IBar') + class _Registry: + def __repr__(self): # pragma: no cover + return '_REGISTRY' + registry = _Registry() + name = 'name' + doc = 'DOCSTRING' + klass = self._getTargetClass() + return (klass(registry, (ibar,), ifoo, name, component, doc), + registry, + name, + ) + + def test_class_conforms_to_ISubscriptionAdapterRegistration(self): + from zope.interface.verify import verifyClass + from zope.interface.interfaces import ISubscriptionAdapterRegistration + verifyClass(ISubscriptionAdapterRegistration, self._getTargetClass()) + + def test_instance_conforms_to_ISubscriptionAdapterRegistration(self): + from zope.interface.verify import verifyObject + from zope.interface.interfaces import ISubscriptionAdapterRegistration + sar, _, _ = self._makeOne() + verifyObject(ISubscriptionAdapterRegistration, sar) + + +class HandlerRegistrationTests(unittest.TestCase): + + def _getTargetClass(self): + from zope.interface.registry import HandlerRegistration + return HandlerRegistration + + def _makeOne(self, component=None): + from zope.interface.declarations import InterfaceClass + + class IFoo(InterfaceClass): + pass + ifoo = IFoo('IFoo') + class _Registry: + def __repr__(self): + return '_REGISTRY' + registry = _Registry() + name = 'name' + doc = 'DOCSTRING' + klass = self._getTargetClass() + return (klass(registry, (ifoo,), name, component, doc), + registry, + name, + ) + + def test_class_conforms_to_IHandlerRegistration(self): + from zope.interface.verify import verifyClass + from zope.interface.interfaces import IHandlerRegistration + verifyClass(IHandlerRegistration, self._getTargetClass()) + + def test_instance_conforms_to_IHandlerRegistration(self): + from zope.interface.verify import verifyObject + from zope.interface.interfaces import IHandlerRegistration + hr, _, _ = self._makeOne() + verifyObject(IHandlerRegistration, hr) + + def test_properties(self): + def _factory(context): + raise NotImplementedError() + hr, _, _ = self._makeOne(_factory) + self.assertTrue(hr.handler is _factory) + self.assertTrue(hr.factory is hr.handler) + self.assertTrue(hr.provided is None) + + def test___repr___factory_w_name(self): + class _Factory: + __name__ = 'TEST' + hr, _registry, _name = self._makeOne(_Factory()) + self.assertEqual(repr(hr), + ("HandlerRegistration(_REGISTRY, [IFoo], %r, TEST, " + + "'DOCSTRING')") % (_name)) + + def test___repr___factory_wo_name(self): + class _Factory: + def __repr__(self): + return 'TEST' + hr, _registry, _name = self._makeOne(_Factory()) + self.assertEqual(repr(hr), + ("HandlerRegistration(_REGISTRY, [IFoo], %r, TEST, " + + "'DOCSTRING')") % (_name)) + +class PersistentAdapterRegistry(VerifyingAdapterRegistry): + + def __getstate__(self): + state = self.__dict__.copy() + for k in list(state): + if k in self._delegated or k.startswith('_v'): + state.pop(k) + state.pop('ro', None) + return state + + def __setstate__(self, state): + bases = state.pop('__bases__', ()) + self.__dict__.update(state) + self._createLookup() + self.__bases__ = bases + self._v_lookup.changed(self) + +class PersistentComponents(Components): + # Mimic zope.component.persistentregistry.PersistentComponents: + # we should be picklalable, but not persistent.Persistent ourself. + + def _init_registries(self): + self.adapters = PersistentAdapterRegistry() + self.utilities = PersistentAdapterRegistry() + +class PersistentDictComponents(PersistentComponents, dict): + # Like Pyramid's Registry, we subclass Components and dict + pass + + +class PersistentComponentsDict(dict, PersistentComponents): + # Like the above, but inheritance is flipped + def __init__(self, name): + dict.__init__(self) + PersistentComponents.__init__(self, name) + +class TestPersistentComponents(unittest.TestCase): + + def _makeOne(self): + return PersistentComponents('test') + + def _check_equality_after_pickle(self, made): + pass + + def test_pickles_empty(self): + import pickle + comp = self._makeOne() + pickle.dumps(comp) + comp2 = pickle.loads(pickle.dumps(comp)) + + self.assertEqual(comp2.__name__, 'test') + + def test_pickles_with_utility_registration(self): + import pickle + comp = self._makeOne() + utility = object() + comp.registerUtility( + utility, + Interface) + + self.assertIs(utility, + comp.getUtility(Interface)) + + comp2 = pickle.loads(pickle.dumps(comp)) + self.assertEqual(comp2.__name__, 'test') + + # The utility is still registered + self.assertIsNotNone(comp2.getUtility(Interface)) + + # We can register another one + comp2.registerUtility( + utility, + Interface) + self.assertIs(utility, + comp2.getUtility(Interface)) + + self._check_equality_after_pickle(comp2) + + +class TestPersistentDictComponents(TestPersistentComponents): + + def _getTargetClass(self): + return PersistentDictComponents + + def _makeOne(self): + comp = self._getTargetClass()(name='test') + comp['key'] = 42 + return comp + + def _check_equality_after_pickle(self, made): + self.assertIn('key', made) + self.assertEqual(made['key'], 42) + +class TestPersistentComponentsDict(TestPersistentDictComponents): + + def _getTargetClass(self): + return PersistentComponentsDict + +class _Monkey: + # context-manager for replacing module names in the scope of a test. + def __init__(self, module, **kw): + self.module = module + self.to_restore = {key: getattr(module, key) for key in kw} + for key, value in kw.items(): + setattr(module, key, value) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + for key, value in self.to_restore.items(): + setattr(self.module, key, value) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_ro.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_ro.py new file mode 100644 index 00000000..6f7a6440 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_ro.py @@ -0,0 +1,426 @@ +############################################################################## +# +# Copyright (c) 2014 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Resolution ordering utility tests""" +import unittest + +# pylint:disable=blacklisted-name,protected-access,attribute-defined-outside-init + +class Test__mergeOrderings(unittest.TestCase): + + def _callFUT(self, orderings): + from zope.interface.ro import _legacy_mergeOrderings + return _legacy_mergeOrderings(orderings) + + def test_empty(self): + self.assertEqual(self._callFUT([]), []) + + def test_single(self): + self.assertEqual(self._callFUT(['a', 'b', 'c']), ['a', 'b', 'c']) + + def test_w_duplicates(self): + self.assertEqual(self._callFUT([['a'], ['b', 'a']]), ['b', 'a']) + + def test_suffix_across_multiple_duplicates(self): + O1 = ['x', 'y', 'z'] + O2 = ['q', 'z'] + O3 = [1, 3, 5] + O4 = ['z'] + self.assertEqual(self._callFUT([O1, O2, O3, O4]), + ['x', 'y', 'q', 1, 3, 5, 'z']) + + +class Test__flatten(unittest.TestCase): + + def _callFUT(self, ob): + from zope.interface.ro import _legacy_flatten + return _legacy_flatten(ob) + + def test_w_empty_bases(self): + class Foo: + pass + foo = Foo() + foo.__bases__ = () + self.assertEqual(self._callFUT(foo), [foo]) + + def test_w_single_base(self): + class Foo: + pass + self.assertEqual(self._callFUT(Foo), [Foo, object]) + + def test_w_bases(self): + class Foo: + pass + class Bar(Foo): + pass + self.assertEqual(self._callFUT(Bar), [Bar, Foo, object]) + + def test_w_diamond(self): + class Foo: + pass + class Bar(Foo): + pass + class Baz(Foo): + pass + class Qux(Bar, Baz): + pass + self.assertEqual(self._callFUT(Qux), + [Qux, Bar, Foo, object, Baz, Foo, object]) + + +class Test_ro(unittest.TestCase): + maxDiff = None + def _callFUT(self, ob, **kwargs): + from zope.interface.ro import _legacy_ro + return _legacy_ro(ob, **kwargs) + + def test_w_empty_bases(self): + class Foo: + pass + foo = Foo() + foo.__bases__ = () + self.assertEqual(self._callFUT(foo), [foo]) + + def test_w_single_base(self): + class Foo: + pass + self.assertEqual(self._callFUT(Foo), [Foo, object]) + + def test_w_bases(self): + class Foo: + pass + class Bar(Foo): + pass + self.assertEqual(self._callFUT(Bar), [Bar, Foo, object]) + + def test_w_diamond(self): + class Foo: + pass + class Bar(Foo): + pass + class Baz(Foo): + pass + class Qux(Bar, Baz): + pass + self.assertEqual(self._callFUT(Qux), + [Qux, Bar, Baz, Foo, object]) + + def _make_IOErr(self): + # This can't be done in the standard C3 ordering. + class Foo: + def __init__(self, name, *bases): + self.__name__ = name + self.__bases__ = bases + def __repr__(self): # pragma: no cover + return self.__name__ + + # Mimic what classImplements(IOError, IIOError) + # does. + IEx = Foo('IEx') + IStdErr = Foo('IStdErr', IEx) + IEnvErr = Foo('IEnvErr', IStdErr) + IIOErr = Foo('IIOErr', IEnvErr) + IOSErr = Foo('IOSErr', IEnvErr) + + IOErr = Foo('IOErr', IEnvErr, IIOErr, IOSErr) + return IOErr, [IOErr, IIOErr, IOSErr, IEnvErr, IStdErr, IEx] + + def test_non_orderable(self): + IOErr, bases = self._make_IOErr() + + self.assertEqual(self._callFUT(IOErr), bases) + + def test_mixed_inheritance_and_implementation(self): + # https://github.com/zopefoundation/zope.interface/issues/8 + # This test should fail, but doesn't, as described in that issue. + # pylint:disable=inherit-non-class + from zope.interface import implementer + from zope.interface import Interface + from zope.interface import providedBy + from zope.interface import implementedBy + + class IFoo(Interface): + pass + + @implementer(IFoo) + class ImplementsFoo: + pass + + class ExtendsFoo(ImplementsFoo): + pass + + class ImplementsNothing: + pass + + class ExtendsFooImplementsNothing(ExtendsFoo, ImplementsNothing): + pass + + self.assertEqual( + self._callFUT(providedBy(ExtendsFooImplementsNothing())), + [implementedBy(ExtendsFooImplementsNothing), + implementedBy(ExtendsFoo), + implementedBy(ImplementsFoo), + IFoo, + Interface, + implementedBy(ImplementsNothing), + implementedBy(object)]) + + +class C3Setting: + + def __init__(self, setting, value): + self._setting = setting + self._value = value + + def __enter__(self): + from zope.interface import ro + setattr(ro.C3, self._setting.__name__, self._value) + + def __exit__(self, t, v, tb): + from zope.interface import ro + setattr(ro.C3, self._setting.__name__, self._setting) + +class Test_c3_ro(Test_ro): + + def setUp(self): + Test_ro.setUp(self) + from zope.testing.loggingsupport import InstalledHandler + self.log_handler = handler = InstalledHandler('zope.interface.ro') + self.addCleanup(handler.uninstall) + + def _callFUT(self, ob, **kwargs): + from zope.interface.ro import ro + return ro(ob, **kwargs) + + def _make_complex_diamond(self, base): + # https://github.com/zopefoundation/zope.interface/issues/21 + O = base + class F(O): + pass + class E(O): + pass + class D(O): + pass + class C(D, F): + pass + class B(D, E): + pass + class A(B, C): + pass + + if hasattr(A, 'mro'): + self.assertEqual(A.mro(), self._callFUT(A)) + + return A + + def test_complex_diamond_object(self): + self._make_complex_diamond(object) + + def test_complex_diamond_interface(self): + from zope.interface import Interface + + IA = self._make_complex_diamond(Interface) + + self.assertEqual( + [x.__name__ for x in IA.__iro__], + ['A', 'B', 'C', 'D', 'E', 'F', 'Interface'] + ) + + def test_complex_diamond_use_legacy_argument(self): + from zope.interface import Interface + + A = self._make_complex_diamond(Interface) + legacy_A_iro = self._callFUT(A, use_legacy_ro=True) + self.assertNotEqual(A.__iro__, legacy_A_iro) + + # And logging happened as a side-effect. + self._check_handler_complex_diamond() + + def test_complex_diamond_compare_legacy_argument(self): + from zope.interface import Interface + + A = self._make_complex_diamond(Interface) + computed_A_iro = self._callFUT(A, log_changed_ro=True) + # It matches, of course, but we did log a warning. + self.assertEqual(tuple(computed_A_iro), A.__iro__) + self._check_handler_complex_diamond() + + def _check_handler_complex_diamond(self): + handler = self.log_handler + self.assertEqual(1, len(handler.records)) + record = handler.records[0] + + self.assertEqual('\n'.join(l.rstrip() for l in record.getMessage().splitlines()), """\ +Object <InterfaceClass zope.interface.tests.test_ro.A> has different legacy and C3 MROs: + Legacy RO (len=7) C3 RO (len=7; inconsistent=no) + ================================================================== + zope.interface.tests.test_ro.A zope.interface.tests.test_ro.A + zope.interface.tests.test_ro.B zope.interface.tests.test_ro.B + - zope.interface.tests.test_ro.E + zope.interface.tests.test_ro.C zope.interface.tests.test_ro.C + zope.interface.tests.test_ro.D zope.interface.tests.test_ro.D + + zope.interface.tests.test_ro.E + zope.interface.tests.test_ro.F zope.interface.tests.test_ro.F + zope.interface.Interface zope.interface.Interface""") + + def test_ExtendedPathIndex_implement_thing_implementedby_super(self): + # See https://github.com/zopefoundation/zope.interface/pull/182#issuecomment-598754056 + from zope.interface import ro + # pylint:disable=inherit-non-class + class _Based: + __bases__ = () + + def __init__(self, name, bases=(), attrs=None): + self.__name__ = name + self.__bases__ = bases + + def __repr__(self): + return self.__name__ + + Interface = _Based('Interface', (), {}) + + class IPluggableIndex(Interface): + pass + + class ILimitedResultIndex(IPluggableIndex): + pass + + class IQueryIndex(IPluggableIndex): + pass + + class IPathIndex(Interface): + pass + + # A parent class who implements two distinct interfaces whose + # only common ancestor is Interface. An easy case. + # @implementer(IPathIndex, IQueryIndex) + # class PathIndex(object): + # pass + obj = _Based('object') + PathIndex = _Based('PathIndex', (IPathIndex, IQueryIndex, obj)) + + # Child class that tries to put an interface the parent declares + # later ahead of the parent. + # @implementer(ILimitedResultIndex, IQueryIndex) + # class ExtendedPathIndex(PathIndex): + # pass + ExtendedPathIndex = _Based('ExtendedPathIndex', + (ILimitedResultIndex, IQueryIndex, PathIndex)) + + # We were able to resolve it, and in exactly the same way as + # the legacy RO did, even though it is inconsistent. + result = self._callFUT(ExtendedPathIndex, log_changed_ro=True, strict=False) + self.assertEqual(result, [ + ExtendedPathIndex, + ILimitedResultIndex, + PathIndex, + IPathIndex, + IQueryIndex, + IPluggableIndex, + Interface, + obj]) + + record, = self.log_handler.records + self.assertIn('used the legacy', record.getMessage()) + + with self.assertRaises(ro.InconsistentResolutionOrderError): + self._callFUT(ExtendedPathIndex, strict=True) + + def test_OSError_IOError(self): + from zope.interface.common import interfaces + from zope.interface import providedBy + + self.assertEqual( + list(providedBy(OSError()).flattened()), + [ + interfaces.IOSError, + interfaces.IIOError, + interfaces.IEnvironmentError, + interfaces.IStandardError, + interfaces.IException, + interfaces.Interface, + ]) + + def test_non_orderable(self): + import warnings + from zope.interface import ro + try: + # If we've already warned, we must reset that state. + del ro.__warningregistry__ + except AttributeError: + pass + + with warnings.catch_warnings(): + warnings.simplefilter('error') + with C3Setting(ro.C3.WARN_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False): + with self.assertRaises(ro.InconsistentResolutionOrderWarning): + super().test_non_orderable() + + IOErr, _ = self._make_IOErr() + with self.assertRaises(ro.InconsistentResolutionOrderError): + self._callFUT(IOErr, strict=True) + + with C3Setting(ro.C3.TRACK_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False): + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + self._callFUT(IOErr) + self.assertIn(IOErr, ro.C3.BAD_IROS) + + iro = self._callFUT(IOErr, strict=False) + legacy_iro = self._callFUT(IOErr, use_legacy_ro=True, strict=False) + self.assertEqual(iro, legacy_iro) + + +class TestC3(unittest.TestCase): + def _makeOne(self, C, strict=False, base_mros=None): + from zope.interface.ro import C3 + return C3.resolver(C, strict, base_mros) + + def test_base_mros_given(self): + c3 = self._makeOne(type(self), base_mros={unittest.TestCase: unittest.TestCase.__mro__}) + memo = c3.memo + self.assertIn(unittest.TestCase, memo) + # We used the StaticMRO class + self.assertIsNone(memo[unittest.TestCase].had_inconsistency) + + def test_one_base_optimization(self): + c3 = self._makeOne(type(self)) + # Even though we didn't call .mro() yet, the MRO has been + # computed. + self.assertIsNotNone(c3._C3__mro) # pylint:disable=no-member + c3._merge = None + self.assertEqual(c3.mro(), list(type(self).__mro__)) + + +class Test_ROComparison(unittest.TestCase): + + class MockC3: + direct_inconsistency = False + bases_had_inconsistency = False + + def _makeOne(self, c3=None, c3_ro=(), legacy_ro=()): + from zope.interface.ro import _ROComparison + return _ROComparison(c3 or self.MockC3(), c3_ro, legacy_ro) + + def test_inconsistent_label(self): + comp = self._makeOne() + self.assertEqual('no', comp._inconsistent_label) + + comp.c3.direct_inconsistency = True + self.assertEqual("direct", comp._inconsistent_label) + + comp.c3.bases_had_inconsistency = True + self.assertEqual("direct+bases", comp._inconsistent_label) + + comp.c3.direct_inconsistency = False + self.assertEqual('bases', comp._inconsistent_label) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_sorting.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_sorting.py new file mode 100644 index 00000000..0e33f47f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_sorting.py @@ -0,0 +1,64 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Test interface sorting +""" + +import unittest + +from zope.interface import Interface + +class I1(Interface): pass +class I2(I1): pass +class I3(I1): pass +class I4(Interface): pass +class I5(I4): pass +class I6(I2): pass + + +class Test(unittest.TestCase): + + def test(self): + l = [I1, I3, I5, I6, I4, I2] + l.sort() + self.assertEqual(l, [I1, I2, I3, I4, I5, I6]) + + def test_w_None(self): + l = [I1, None, I3, I5, I6, I4, I2] + l.sort() + self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None]) + + def test_w_equal_names(self): + # interfaces with equal names but different modules should sort by + # module name + from zope.interface.tests.m1 import I1 as m1_I1 + l = [I1, m1_I1] + l.sort() + self.assertEqual(l, [m1_I1, I1]) + + def test_I1_I2(self): + self.assertLess(I1.__name__, I2.__name__) + self.assertEqual(I1.__module__, I2.__module__) + self.assertEqual(I1.__module__, __name__) + self.assertLess(I1, I2) + + def _makeI1(self): + class I1(Interface): + pass + return I1 + + def test_nested(self): + nested_I1 = self._makeI1() + self.assertEqual(I1, nested_I1) + self.assertEqual(nested_I1, I1) + self.assertEqual(hash(I1), hash(nested_I1)) diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_verify.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_verify.py new file mode 100644 index 00000000..5227a92c --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/tests/test_verify.py @@ -0,0 +1,656 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" zope.interface.verify unit tests +""" +import unittest + +# pylint:disable=inherit-non-class,no-method-argument,no-self-argument + +class Test_verifyClass(unittest.TestCase): + + verifier = None + + def setUp(self): + self.verifier = self._get_FUT() + + @classmethod + def _get_FUT(cls): + from zope.interface.verify import verifyClass + return verifyClass + + _adjust_object_before_verify = lambda self, x: x + + def _callFUT(self, iface, klass, **kwargs): + return self.verifier(iface, + self._adjust_object_before_verify(klass), + **kwargs) + + def test_class_doesnt_implement(self): + from zope.interface import Interface + from zope.interface.exceptions import DoesNotImplement + + class ICurrent(Interface): + pass + + class Current: + pass + + self.assertRaises(DoesNotImplement, self._callFUT, ICurrent, Current) + + def test_class_doesnt_implement_but_classImplements_later(self): + from zope.interface import Interface + from zope.interface import classImplements + + class ICurrent(Interface): + pass + + class Current: + pass + + classImplements(Current, ICurrent) + + self._callFUT(ICurrent, Current) + + def test_class_doesnt_have_required_method_simple(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenImplementation + + class ICurrent(Interface): + def method(): + """docstring""" + + @implementer(ICurrent) + class Current: + pass + + self.assertRaises(BrokenImplementation, + self._callFUT, ICurrent, Current) + + def test_class_has_required_method_simple(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + def method(): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_class_doesnt_have_required_method_derived(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenImplementation + + class IBase(Interface): + def method(): + """docstring""" + + class IDerived(IBase): + pass + + @implementer(IDerived) + class Current: + pass + + self.assertRaises(BrokenImplementation, + self._callFUT, IDerived, Current) + + def test_class_has_required_method_derived(self): + from zope.interface import Interface + from zope.interface import implementer + + class IBase(Interface): + def method(): + """docstring""" + + class IDerived(IBase): + pass + + @implementer(IDerived) + class Current: + + def method(self): + raise NotImplementedError() + + self._callFUT(IDerived, Current) + + def test_method_takes_wrong_arg_names_but_OK(self): + # We no longer require names to match. + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, b): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_not_enough_args(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_doesnt_take_required_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(*args): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_doesnt_take_required_only_kwargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(**kw): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_takes_extra_arg(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, b): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_takes_extra_arg_with_default(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, b=None): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_only_positional_args(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, *args): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_only_kwargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, **kw): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_takes_extra_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, *args): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_extra_starargs_and_kwargs(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, *args, **kw): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_doesnt_take_required_positional_and_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(a, *args): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_method_takes_required_positional_and_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a, *args): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, *args): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_only_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(a, *args): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, *args): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_required_kwargs(self): + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + + def method(**kwargs): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, **kw): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_method_takes_positional_plus_required_starargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(*args): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a, *args): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + + def test_method_doesnt_take_required_kwargs(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(**kwargs): + """docstring""" + + @implementer(ICurrent) + class Current: + + def method(self, a): + raise NotImplementedError() + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + + def test_class_has_method_for_iface_attr(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + attr = Attribute("The foo Attribute") + + @implementer(ICurrent) + class Current: + + def attr(self): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_class_has_nonmethod_for_method(self): + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + def method(): + """docstring""" + + @implementer(ICurrent) + class Current: + method = 1 + + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) + + def test_class_has_attribute_for_attribute(self): + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + attr = Attribute("The foo Attribute") + + @implementer(ICurrent) + class Current: + + attr = 1 + + self._callFUT(ICurrent, Current) + + def test_class_misses_attribute_for_attribute(self): + # This check *passes* for verifyClass + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import implementer + + class ICurrent(Interface): + attr = Attribute("The foo Attribute") + + @implementer(ICurrent) + class Current: + pass + + self._callFUT(ICurrent, Current) + + def test_w_callable_non_func_method(self): + from zope.interface.interface import Method + from zope.interface import Interface + from zope.interface import implementer + + class QuasiMethod(Method): + def __call__(self, *args, **kw): + raise NotImplementedError() + + class QuasiCallable: + def __call__(self, *args, **kw): + raise NotImplementedError() + + class ICurrent(Interface): + attr = QuasiMethod('This is callable') + + @implementer(ICurrent) + class Current: + attr = QuasiCallable() + + self._callFUT(ICurrent, Current) + + + def test_w_decorated_method(self): + from zope.interface import Interface + from zope.interface import implementer + + def decorator(func): + # this is, in fact, zope.proxy.non_overridable + return property(lambda self: func.__get__(self)) + + class ICurrent(Interface): + + def method(a): + """docstring""" + + @implementer(ICurrent) + class Current: + + @decorator + def method(self, a): + raise NotImplementedError() + + self._callFUT(ICurrent, Current) + + def test_dict_IFullMapping(self): + # A dict should be an IFullMapping, but this exposes two + # issues. First, on CPython, methods of builtin types are + # "method_descriptor" objects, and are harder to introspect. + # Second, on PyPy, the signatures can be just plain wrong, + # specifying as required arguments that are actually optional. + # See https://github.com/zopefoundation/zope.interface/issues/118 + from zope.interface.common.mapping import IFullMapping + self._callFUT(IFullMapping, dict, tentative=True) + + def test_list_ISequence(self): + # As for test_dict_IFullMapping + from zope.interface.common.sequence import ISequence + self._callFUT(ISequence, list, tentative=True) + + def test_tuple_IReadSequence(self): + # As for test_dict_IFullMapping + from zope.interface.common.sequence import IReadSequence + self._callFUT(IReadSequence, tuple, tentative=True) + + + def test_multiple_invalid(self): + from zope.interface.exceptions import MultipleInvalid + from zope.interface.exceptions import DoesNotImplement + from zope.interface.exceptions import BrokenImplementation + from zope.interface import Interface + from zope.interface import classImplements + + class ISeveralMethods(Interface): + def meth1(arg1): + "Method 1" + def meth2(arg1): + "Method 2" + + class SeveralMethods: + pass + + with self.assertRaises(MultipleInvalid) as exc: + self._callFUT(ISeveralMethods, SeveralMethods) + + ex = exc.exception + self.assertEqual(3, len(ex.exceptions)) + self.assertIsInstance(ex.exceptions[0], DoesNotImplement) + self.assertIsInstance(ex.exceptions[1], BrokenImplementation) + self.assertIsInstance(ex.exceptions[2], BrokenImplementation) + + # If everything else is correct, only the single error is raised without + # the wrapper. + classImplements(SeveralMethods, ISeveralMethods) + SeveralMethods.meth1 = lambda self, arg1: "Hi" + + with self.assertRaises(BrokenImplementation): + self._callFUT(ISeveralMethods, SeveralMethods) + +class Test_verifyObject(Test_verifyClass): + + @classmethod + def _get_FUT(cls): + from zope.interface.verify import verifyObject + return verifyObject + + def _adjust_object_before_verify(self, target): + if isinstance(target, (type, type(OldSkool))): + target = target() + return target + + def test_class_misses_attribute_for_attribute(self): + # This check *fails* for verifyObject + from zope.interface import Attribute + from zope.interface import Interface + from zope.interface import implementer + from zope.interface.exceptions import BrokenImplementation + + class ICurrent(Interface): + attr = Attribute("The foo Attribute") + + @implementer(ICurrent) + class Current: + pass + + self.assertRaises(BrokenImplementation, + self._callFUT, ICurrent, Current) + + def test_module_hit(self): + from zope.interface.tests.idummy import IDummyModule + from zope.interface.tests import dummy + + self._callFUT(IDummyModule, dummy) + + def test_module_miss(self): + from zope.interface import Interface + from zope.interface.tests import dummy + from zope.interface.exceptions import DoesNotImplement + + # same name, different object + class IDummyModule(Interface): + pass + + self.assertRaises(DoesNotImplement, + self._callFUT, IDummyModule, dummy) + + def test_staticmethod_hit_on_class(self): + from zope.interface import Interface + from zope.interface import provider + from zope.interface.verify import verifyObject + + class IFoo(Interface): + + def bar(a, b): + "The bar method" + + @provider(IFoo) + class Foo: + + @staticmethod + def bar(a, b): + raise AssertionError("We're never actually called") + + # Don't use self._callFUT, we don't want to instantiate the + # class. + verifyObject(IFoo, Foo) + +class OldSkool: + pass diff --git a/dbdpy-env/lib/python3.9/site-packages/zope/interface/verify.py b/dbdpy-env/lib/python3.9/site-packages/zope/interface/verify.py new file mode 100644 index 00000000..0ab0b3f9 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/zope/interface/verify.py @@ -0,0 +1,185 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Verify interface implementations +""" +import inspect +import sys +from types import FunctionType +from types import MethodType + +from zope.interface.exceptions import BrokenImplementation +from zope.interface.exceptions import BrokenMethodImplementation +from zope.interface.exceptions import DoesNotImplement +from zope.interface.exceptions import Invalid +from zope.interface.exceptions import MultipleInvalid + +from zope.interface.interface import fromMethod, fromFunction, Method + +__all__ = [ + 'verifyObject', + 'verifyClass', +] + +# This will be monkey-patched when running under Zope 2, so leave this +# here: +MethodTypes = (MethodType, ) + + +def _verify(iface, candidate, tentative=False, vtype=None): + """ + Verify that *candidate* might correctly provide *iface*. + + This involves: + + - Making sure the candidate claims that it provides the + interface using ``iface.providedBy`` (unless *tentative* is `True`, + in which case this step is skipped). This means that the candidate's class + declares that it `implements <zope.interface.implementer>` the interface, + or the candidate itself declares that it `provides <zope.interface.provider>` + the interface + + - Making sure the candidate defines all the necessary methods + + - Making sure the methods have the correct signature (to the + extent possible) + + - Making sure the candidate defines all the necessary attributes + + :return bool: Returns a true value if everything that could be + checked passed. + :raises zope.interface.Invalid: If any of the previous + conditions does not hold. + + .. versionchanged:: 5.0 + If multiple methods or attributes are invalid, all such errors + are collected and reported. Previously, only the first error was reported. + As a special case, if only one such error is present, it is raised + alone, like before. + """ + + if vtype == 'c': + tester = iface.implementedBy + else: + tester = iface.providedBy + + excs = [] + if not tentative and not tester(candidate): + excs.append(DoesNotImplement(iface, candidate)) + + for name, desc in iface.namesAndDescriptions(all=True): + try: + _verify_element(iface, name, desc, candidate, vtype) + except Invalid as e: + excs.append(e) + + if excs: + if len(excs) == 1: + raise excs[0] + raise MultipleInvalid(iface, candidate, excs) + + return True + +def _verify_element(iface, name, desc, candidate, vtype): + # Here the `desc` is either an `Attribute` or `Method` instance + try: + attr = getattr(candidate, name) + except AttributeError: + if (not isinstance(desc, Method)) and vtype == 'c': + # We can't verify non-methods on classes, since the + # class may provide attrs in it's __init__. + return + # TODO: This should use ``raise...from`` + raise BrokenImplementation(iface, desc, candidate) + + if not isinstance(desc, Method): + # If it's not a method, there's nothing else we can test + return + + if inspect.ismethoddescriptor(attr) or inspect.isbuiltin(attr): + # The first case is what you get for things like ``dict.pop`` + # on CPython (e.g., ``verifyClass(IFullMapping, dict))``). The + # second case is what you get for things like ``dict().pop`` on + # CPython (e.g., ``verifyObject(IFullMapping, dict()))``. + # In neither case can we get a signature, so there's nothing + # to verify. Even the inspect module gives up and raises + # ValueError: no signature found. The ``__text_signature__`` attribute + # isn't typically populated either. + # + # Note that on PyPy 2 or 3 (up through 7.3 at least), these are + # not true for things like ``dict.pop`` (but might be true for C extensions?) + return + + if isinstance(attr, FunctionType): + if isinstance(candidate, type) and vtype == 'c': + # This is an "unbound method". + # Only unwrap this if we're verifying implementedBy; + # otherwise we can unwrap @staticmethod on classes that directly + # provide an interface. + meth = fromFunction(attr, iface, name=name, imlevel=1) + else: + # Nope, just a normal function + meth = fromFunction(attr, iface, name=name) + elif (isinstance(attr, MethodTypes) + and type(attr.__func__) is FunctionType): + meth = fromMethod(attr, iface, name) + elif isinstance(attr, property) and vtype == 'c': + # Without an instance we cannot be sure it's not a + # callable. + # TODO: This should probably check inspect.isdatadescriptor(), + # a more general form than ``property`` + return + + else: + if not callable(attr): + raise BrokenMethodImplementation(desc, "implementation is not a method", + attr, iface, candidate) + # sigh, it's callable, but we don't know how to introspect it, so + # we have to give it a pass. + return + + # Make sure that the required and implemented method signatures are + # the same. + mess = _incompat(desc.getSignatureInfo(), meth.getSignatureInfo()) + if mess: + raise BrokenMethodImplementation(desc, mess, attr, iface, candidate) + + + +def verifyClass(iface, candidate, tentative=False): + """ + Verify that the *candidate* might correctly provide *iface*. + """ + return _verify(iface, candidate, tentative, vtype='c') + +def verifyObject(iface, candidate, tentative=False): + return _verify(iface, candidate, tentative, vtype='o') + +verifyObject.__doc__ = _verify.__doc__ + +_MSG_TOO_MANY = 'implementation requires too many arguments' + +def _incompat(required, implemented): + #if (required['positional'] != + # implemented['positional'][:len(required['positional'])] + # and implemented['kwargs'] is None): + # return 'imlementation has different argument names' + if len(implemented['required']) > len(required['required']): + return _MSG_TOO_MANY + if ((len(implemented['positional']) < len(required['positional'])) + and not implemented['varargs']): + return "implementation doesn't allow enough arguments" + if required['kwargs'] and not implemented['kwargs']: + return "implementation doesn't support keyword arguments" + if required['varargs'] and not implemented['varargs']: + return "implementation doesn't support variable arguments" diff --git a/dbdpy-env/share/man/man1/ttx.1 b/dbdpy-env/share/man/man1/ttx.1 new file mode 100644 index 00000000..bba23b5e --- /dev/null +++ b/dbdpy-env/share/man/man1/ttx.1 @@ -0,0 +1,225 @@ +.Dd May 18, 2004 +.\" ttx is not specific to any OS, but contrary to what groff_mdoc(7) +.\" seems to imply, entirely omitting the .Os macro causes 'BSD' to +.\" be used, so I give a zero-width space as its argument. +.Os \& +.\" The "FontTools Manual" argument apparently has no effect in +.\" groff 1.18.1. I think it is a bug in the -mdoc groff package. +.Dt TTX 1 "FontTools Manual" +.Sh NAME +.Nm ttx +.Nd tool for manipulating TrueType and OpenType fonts +.Sh SYNOPSIS +.Nm +.Bk +.Op Ar option ... +.Ek +.Bk +.Ar file ... +.Ek +.Sh DESCRIPTION +.Nm +is a tool for manipulating TrueType and OpenType fonts. It can convert +TrueType and OpenType fonts to and from an +.Tn XML Ns -based format called +.Tn TTX . +.Tn TTX +files have a +.Ql .ttx +extension. +.Pp +For each +.Ar file +argument it is given, +.Nm +detects whether it is a +.Ql .ttf , +.Ql .otf +or +.Ql .ttx +file and acts accordingly: if it is a +.Ql .ttf +or +.Ql .otf +file, it generates a +.Ql .ttx +file; if it is a +.Ql .ttx +file, it generates a +.Ql .ttf +or +.Ql .otf +file. +.Pp +By default, every output file is created in the same directory as the +corresponding input file and with the same name except for the +extension, which is substituted appropriately. +.Nm +never overwrites existing files; if necessary, it appends a suffix to +the output file name before the extension, as in +.Pa Arial#1.ttf . +.Ss "General options" +.Bl -tag -width ".Fl t Ar table" +.It Fl h +Display usage information. +.It Fl d Ar dir +Write the output files to directory +.Ar dir +instead of writing every output file to the same directory as the +corresponding input file. +.It Fl o Ar file +Write the output to +.Ar file +instead of writing it to the same directory as the +corresponding input file. +.It Fl v +Be verbose. Write more messages to the standard output describing what +is being done. +.It Fl a +Allow virtual glyphs ID's on compile or decompile. +.El +.Ss "Dump options" +The following options control the process of dumping font files +(TrueType or OpenType) to +.Tn TTX +files. +.Bl -tag -width ".Fl t Ar table" +.It Fl l +List table information. Instead of dumping the font to a +.Tn TTX +file, display minimal information about each table. +.It Fl t Ar table +Dump table +.Ar table . +This option may be given multiple times to dump several tables at +once. When not specified, all tables are dumped. +.It Fl x Ar table +Exclude table +.Ar table +from the list of tables to dump. This option may be given multiple +times to exclude several tables from the dump. The +.Fl t +and +.Fl x +options are mutually exclusive. +.It Fl s +Split tables. Dump each table to a separate +.Tn TTX +file and write (under the name that would have been used for the output +file if the +.Fl s +option had not been given) one small +.Tn TTX +file containing references to the individual table dump files. This +file can be used as input to +.Nm +as long as the referenced files can be found in the same directory. +.It Fl i +.\" XXX: I suppose OpenType programs (exist and) are also affected. +Don't disassemble TrueType instructions. When this option is specified, +all TrueType programs (glyph programs, the font program and the +pre-program) are written to the +.Tn TTX +file as hexadecimal data instead of +assembly. This saves some time and results in smaller +.Tn TTX +files. +.It Fl y Ar n +When decompiling a TrueType Collection (TTC) file, +decompile font number +.Ar n , +starting from 0. +.El +.Ss "Compilation options" +The following options control the process of compiling +.Tn TTX +files into font files (TrueType or OpenType): +.Bl -tag -width ".Fl t Ar table" +.It Fl m Ar fontfile +Merge the input +.Tn TTX +file +.Ar file +with +.Ar fontfile . +No more than one +.Ar file +argument can be specified when this option is used. +.It Fl b +Don't recalculate glyph bounding boxes. Use the values in the +.Tn TTX +file as is. +.El +.Sh "THE TTX FILE FORMAT" +You can find some information about the +.Tn TTX +file format in +.Pa documentation.html . +In particular, you will find in that file the list of tables understood by +.Nm +and the relations between TrueType GlyphIDs and the glyph names used in +.Tn TTX +files. +.Sh EXAMPLES +In the following examples, all files are read from and written to the +current directory. Additionally, the name given for the output file +assumes in every case that it did not exist before +.Nm +was invoked. +.Pp +Dump the TrueType font contained in +.Pa FreeSans.ttf +to +.Pa FreeSans.ttx : +.Pp +.Dl ttx FreeSans.ttf +.Pp +Compile +.Pa MyFont.ttx +into a TrueType or OpenType font file: +.Pp +.Dl ttx MyFont.ttx +.Pp +List the tables in +.Pa FreeSans.ttf +along with some information: +.Pp +.Dl ttx -l FreeSans.ttf +.Pp +Dump the +.Sq cmap +table from +.Pa FreeSans.ttf +to +.Pa FreeSans.ttx : +.Pp +.Dl ttx -t cmap FreeSans.ttf +.Sh NOTES +On MS\-Windows and MacOS, +.Nm +is available as a graphical application to which files can be dropped. +.Sh SEE ALSO +.Pa documentation.html +.Pp +.Xr fontforge 1 , +.Xr ftinfo 1 , +.Xr gfontview 1 , +.Xr xmbdfed 1 , +.Xr Font::TTF 3pm +.Sh AUTHORS +.Nm +was written by +.An -nosplit +.An "Just van Rossum" Aq just@letterror.com . +.Pp +This manual page was written by +.An "Florent Rougon" Aq f.rougon@free.fr +for the Debian GNU/Linux system based on the existing FontTools +documentation. It may be freely used, modified and distributed without +restrictions. +.\" For Emacs: +.\" Local Variables: +.\" fill-column: 72 +.\" sentence-end: "[.?!][]\"')}]*\\($\\| $\\| \\| \\)[ \n]*" +.\" sentence-end-double-space: t +.\" End: \ No newline at end of file diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 64ada9a3..00000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --pycodestyle \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..43efc44e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[tool:pytest] +addopts = --pycodestyle + +[pycodestyle] +max-line-length = 100 \ No newline at end of file

    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 literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.pyi b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_ttconv.pyi new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_type1font.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_type1font.py new file mode 100644 index 00000000..a3124a24 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_type1font.py @@ -0,0 +1,876 @@ +""" +A class representing a Type 1 font. + +This version reads pfa and pfb files and splits them for embedding in +pdf files. It also supports SlantFont and ExtendFont transformations, +similarly to pdfTeX and friends. There is no support yet for subsetting. + +Usage:: + + font = Type1Font(filename) + clear_part, encrypted_part, finale = font.parts + slanted_font = font.transform({'slant': 0.167}) + extended_font = font.transform({'extend': 1.2}) + +Sources: + +* Adobe Technical Note #5040, Supporting Downloadable PostScript + Language Fonts. + +* Adobe Type 1 Font Format, Adobe Systems Incorporated, third printing, + v1.1, 1993. ISBN 0-201-57044-0. +""" + +import binascii +import functools +import logging +import re +import string +import struct + +import numpy as np + +from matplotlib.cbook import _format_approx +from . import _api + +_log = logging.getLogger(__name__) + + +class _Token: + """ + A token in a PostScript stream. + + Attributes + ---------- + pos : int + Position, i.e. offset from the beginning of the data. + raw : str + Raw text of the token. + kind : str + Description of the token (for debugging or testing). + """ + __slots__ = ('pos', 'raw') + kind = '?' + + def __init__(self, pos, raw): + _log.debug('type1font._Token %s at %d: %r', self.kind, pos, raw) + self.pos = pos + self.raw = raw + + def __str__(self): + return f"<{self.kind} {self.raw} @{self.pos}>" + + def endpos(self): + """Position one past the end of the token""" + return self.pos + len(self.raw) + + def is_keyword(self, *names): + """Is this a name token with one of the names?""" + return False + + def is_slash_name(self): + """Is this a name token that starts with a slash?""" + return False + + def is_delim(self): + """Is this a delimiter token?""" + return False + + def is_number(self): + """Is this a number token?""" + return False + + def value(self): + return self.raw + + +class _NameToken(_Token): + kind = 'name' + + def is_slash_name(self): + return self.raw.startswith('/') + + def value(self): + return self.raw[1:] + + +class _BooleanToken(_Token): + kind = 'boolean' + + def value(self): + return self.raw == 'true' + + +class _KeywordToken(_Token): + kind = 'keyword' + + def is_keyword(self, *names): + return self.raw in names + + +class _DelimiterToken(_Token): + kind = 'delimiter' + + def is_delim(self): + return True + + def opposite(self): + return {'[': ']', ']': '[', + '{': '}', '}': '{', + '<<': '>>', '>>': '<<' + }[self.raw] + + +class _WhitespaceToken(_Token): + kind = 'whitespace' + + +class _StringToken(_Token): + kind = 'string' + _escapes_re = re.compile(r'\\([\\()nrtbf]|[0-7]{1,3})') + _replacements = {'\\': '\\', '(': '(', ')': ')', 'n': '\n', + 'r': '\r', 't': '\t', 'b': '\b', 'f': '\f'} + _ws_re = re.compile('[\0\t\r\f\n ]') + + @classmethod + def _escape(cls, match): + group = match.group(1) + try: + return cls._replacements[group] + except KeyError: + return chr(int(group, 8)) + + @functools.lru_cache + def value(self): + if self.raw[0] == '(': + return self._escapes_re.sub(self._escape, self.raw[1:-1]) + else: + data = self._ws_re.sub('', self.raw[1:-1]) + if len(data) % 2 == 1: + data += '0' + return binascii.unhexlify(data) + + +class _BinaryToken(_Token): + kind = 'binary' + + def value(self): + return self.raw[1:] + + +class _NumberToken(_Token): + kind = 'number' + + def is_number(self): + return True + + def value(self): + if '.' not in self.raw: + return int(self.raw) + else: + return float(self.raw) + + +def _tokenize(data: bytes, skip_ws: bool): + """ + A generator that produces _Token instances from Type-1 font code. + + The consumer of the generator may send an integer to the tokenizer to + indicate that the next token should be _BinaryToken of the given length. + + Parameters + ---------- + data : bytes + The data of the font to tokenize. + + skip_ws : bool + If true, the generator will drop any _WhitespaceTokens from the output. + """ + + text = data.decode('ascii', 'replace') + whitespace_or_comment_re = re.compile(r'[\0\t\r\f\n ]+|%[^\r\n]*') + token_re = re.compile(r'/{0,2}[^]\0\t\r\f\n ()<>{}/%[]+') + instring_re = re.compile(r'[()\\]') + hex_re = re.compile(r'^<[0-9a-fA-F\0\t\r\f\n ]*>$') + oct_re = re.compile(r'[0-7]{1,3}') + pos = 0 + next_binary = None + + while pos < len(text): + if next_binary is not None: + n = next_binary + next_binary = (yield _BinaryToken(pos, data[pos:pos+n])) + pos += n + continue + match = whitespace_or_comment_re.match(text, pos) + if match: + if not skip_ws: + next_binary = (yield _WhitespaceToken(pos, match.group())) + pos = match.end() + elif text[pos] == '(': + # PostScript string rules: + # - parentheses must be balanced + # - backslashes escape backslashes and parens + # - also codes \n\r\t\b\f and octal escapes are recognized + # - other backslashes do not escape anything + start = pos + pos += 1 + depth = 1 + while depth: + match = instring_re.search(text, pos) + if match is None: + raise ValueError( + f'Unterminated string starting at {start}') + pos = match.end() + if match.group() == '(': + depth += 1 + elif match.group() == ')': + depth -= 1 + else: # a backslash + char = text[pos] + if char in r'\()nrtbf': + pos += 1 + else: + octal = oct_re.match(text, pos) + if octal: + pos = octal.end() + else: + pass # non-escaping backslash + next_binary = (yield _StringToken(start, text[start:pos])) + elif text[pos:pos + 2] in ('<<', '>>'): + next_binary = (yield _DelimiterToken(pos, text[pos:pos + 2])) + pos += 2 + elif text[pos] == '<': + start = pos + try: + pos = text.index('>', pos) + 1 + except ValueError as e: + raise ValueError(f'Unterminated hex string starting at {start}' + ) from e + if not hex_re.match(text[start:pos]): + raise ValueError(f'Malformed hex string starting at {start}') + next_binary = (yield _StringToken(pos, text[start:pos])) + else: + match = token_re.match(text, pos) + if match: + raw = match.group() + if raw.startswith('/'): + next_binary = (yield _NameToken(pos, raw)) + elif match.group() in ('true', 'false'): + next_binary = (yield _BooleanToken(pos, raw)) + else: + try: + float(raw) + next_binary = (yield _NumberToken(pos, raw)) + except ValueError: + next_binary = (yield _KeywordToken(pos, raw)) + pos = match.end() + else: + next_binary = (yield _DelimiterToken(pos, text[pos])) + pos += 1 + + +class _BalancedExpression(_Token): + pass + + +def _expression(initial, tokens, data): + """ + Consume some number of tokens and return a balanced PostScript expression. + + Parameters + ---------- + initial : _Token + The token that triggered parsing a balanced expression. + tokens : iterator of _Token + Following tokens. + data : bytes + Underlying data that the token positions point to. + + Returns + ------- + _BalancedExpression + """ + delim_stack = [] + token = initial + while True: + if token.is_delim(): + if token.raw in ('[', '{'): + delim_stack.append(token) + elif token.raw in (']', '}'): + if not delim_stack: + raise RuntimeError(f"unmatched closing token {token}") + match = delim_stack.pop() + if match.raw != token.opposite(): + raise RuntimeError( + f"opening token {match} closed by {token}" + ) + if not delim_stack: + break + else: + raise RuntimeError(f'unknown delimiter {token}') + elif not delim_stack: + break + token = next(tokens) + return _BalancedExpression( + initial.pos, + data[initial.pos:token.endpos()].decode('ascii', 'replace') + ) + + +class Type1Font: + """ + A class representing a Type-1 font, for use by backends. + + Attributes + ---------- + parts : tuple + A 3-tuple of the cleartext part, the encrypted part, and the finale of + zeros. + + decrypted : bytes + The decrypted form of ``parts[1]``. + + prop : dict[str, Any] + A dictionary of font properties. Noteworthy keys include: + + - FontName: PostScript name of the font + - Encoding: dict from numeric codes to glyph names + - FontMatrix: bytes object encoding a matrix + - UniqueID: optional font identifier, dropped when modifying the font + - CharStrings: dict from glyph names to byte code + - Subrs: array of byte code subroutines + - OtherSubrs: bytes object encoding some PostScript code + """ + __slots__ = ('parts', 'decrypted', 'prop', '_pos', '_abbr') + # the _pos dict contains (begin, end) indices to parts[0] + decrypted + # so that they can be replaced when transforming the font; + # but since sometimes a definition appears in both parts[0] and decrypted, + # _pos[name] is an array of such pairs + # + # _abbr maps three standard abbreviations to their particular names in + # this font (e.g. 'RD' is named '-|' in some fonts) + + def __init__(self, input): + """ + Initialize a Type-1 font. + + Parameters + ---------- + input : str or 3-tuple + Either a pfb file name, or a 3-tuple of already-decoded Type-1 + font `~.Type1Font.parts`. + """ + if isinstance(input, tuple) and len(input) == 3: + self.parts = input + else: + with open(input, 'rb') as file: + data = self._read(file) + self.parts = self._split(data) + + self.decrypted = self._decrypt(self.parts[1], 'eexec') + self._abbr = {'RD': 'RD', 'ND': 'ND', 'NP': 'NP'} + self._parse() + + def _read(self, file): + """Read the font from a file, decoding into usable parts.""" + rawdata = file.read() + if not rawdata.startswith(b'\x80'): + return rawdata + + data = b'' + while rawdata: + if not rawdata.startswith(b'\x80'): + raise RuntimeError('Broken pfb file (expected byte 128, ' + 'got %d)' % rawdata[0]) + type = rawdata[1] + if type in (1, 2): + length, = struct.unpack('> 8)) + key = ((key+byte) * 52845 + 22719) & 0xffff + + return bytes(plaintext[ndiscard:]) + + @staticmethod + def _encrypt(plaintext, key, ndiscard=4): + """ + Encrypt plaintext using the Type-1 font algorithm. + + The algorithm is described in Adobe's "Adobe Type 1 Font Format". + The key argument can be an integer, or one of the strings + 'eexec' and 'charstring', which map to the key specified for the + corresponding part of Type-1 fonts. + + The ndiscard argument should be an integer, usually 4. That + number of bytes is prepended to the plaintext before encryption. + This function prepends NUL bytes for reproducibility, even though + the original algorithm uses random bytes, presumably to avoid + cryptanalysis. + """ + + key = _api.check_getitem({'eexec': 55665, 'charstring': 4330}, key=key) + ciphertext = [] + for byte in b'\0' * ndiscard + plaintext: + c = byte ^ (key >> 8) + ciphertext.append(c) + key = ((key + c) * 52845 + 22719) & 0xffff + + return bytes(ciphertext) + + def _parse(self): + """ + Find the values of various font properties. This limited kind + of parsing is described in Chapter 10 "Adobe Type Manager + Compatibility" of the Type-1 spec. + """ + # Start with reasonable defaults + prop = {'Weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False, + 'UnderlinePosition': -100, 'UnderlineThickness': 50} + pos = {} + data = self.parts[0] + self.decrypted + + source = _tokenize(data, True) + while True: + # See if there is a key to be assigned a value + # e.g. /FontName in /FontName /Helvetica def + try: + token = next(source) + except StopIteration: + break + if token.is_delim(): + # skip over this - we want top-level keys only + _expression(token, source, data) + if token.is_slash_name(): + key = token.value() + keypos = token.pos + else: + continue + + # Some values need special parsing + if key in ('Subrs', 'CharStrings', 'Encoding', 'OtherSubrs'): + prop[key], endpos = { + 'Subrs': self._parse_subrs, + 'CharStrings': self._parse_charstrings, + 'Encoding': self._parse_encoding, + 'OtherSubrs': self._parse_othersubrs + }[key](source, data) + pos.setdefault(key, []).append((keypos, endpos)) + continue + + try: + token = next(source) + except StopIteration: + break + + if isinstance(token, _KeywordToken): + # constructs like + # FontDirectory /Helvetica known {...} {...} ifelse + # mean the key was not really a key + continue + + if token.is_delim(): + value = _expression(token, source, data).raw + else: + value = token.value() + + # look for a 'def' possibly preceded by access modifiers + try: + kw = next( + kw for kw in source + if not kw.is_keyword('readonly', 'noaccess', 'executeonly') + ) + except StopIteration: + break + + # sometimes noaccess def and readonly def are abbreviated + if kw.is_keyword('def', self._abbr['ND'], self._abbr['NP']): + prop[key] = value + pos.setdefault(key, []).append((keypos, kw.endpos())) + + # detect the standard abbreviations + if value == '{noaccess def}': + self._abbr['ND'] = key + elif value == '{noaccess put}': + self._abbr['NP'] = key + elif value == '{string currentfile exch readstring pop}': + self._abbr['RD'] = key + + # Fill in the various *Name properties + if 'FontName' not in prop: + prop['FontName'] = (prop.get('FullName') or + prop.get('FamilyName') or + 'Unknown') + if 'FullName' not in prop: + prop['FullName'] = prop['FontName'] + if 'FamilyName' not in prop: + extras = ('(?i)([ -](regular|plain|italic|oblique|(semi)?bold|' + '(ultra)?light|extra|condensed))+$') + prop['FamilyName'] = re.sub(extras, '', prop['FullName']) + # Decrypt the encrypted parts + ndiscard = prop.get('lenIV', 4) + cs = prop['CharStrings'] + for key, value in cs.items(): + cs[key] = self._decrypt(value, 'charstring', ndiscard) + if 'Subrs' in prop: + prop['Subrs'] = [ + self._decrypt(value, 'charstring', ndiscard) + for value in prop['Subrs'] + ] + + self.prop = prop + self._pos = pos + + def _parse_subrs(self, tokens, _data): + count_token = next(tokens) + if not count_token.is_number(): + raise RuntimeError( + f"Token following /Subrs must be a number, was {count_token}" + ) + count = count_token.value() + array = [None] * count + next(t for t in tokens if t.is_keyword('array')) + for _ in range(count): + next(t for t in tokens if t.is_keyword('dup')) + index_token = next(tokens) + if not index_token.is_number(): + raise RuntimeError( + "Token following dup in Subrs definition must be a " + f"number, was {index_token}" + ) + nbytes_token = next(tokens) + if not nbytes_token.is_number(): + raise RuntimeError( + "Second token following dup in Subrs definition must " + f"be a number, was {nbytes_token}" + ) + token = next(tokens) + if not token.is_keyword(self._abbr['RD']): + raise RuntimeError( + f"Token preceding subr must be {self._abbr['RD']}, " + f"was {token}" + ) + binary_token = tokens.send(1+nbytes_token.value()) + array[index_token.value()] = binary_token.value() + + return array, next(tokens).endpos() + + @staticmethod + def _parse_charstrings(tokens, _data): + count_token = next(tokens) + if not count_token.is_number(): + raise RuntimeError( + "Token following /CharStrings must be a number, " + f"was {count_token}" + ) + count = count_token.value() + charstrings = {} + next(t for t in tokens if t.is_keyword('begin')) + while True: + token = next(t for t in tokens + if t.is_keyword('end') or t.is_slash_name()) + if token.raw == 'end': + return charstrings, token.endpos() + glyphname = token.value() + nbytes_token = next(tokens) + if not nbytes_token.is_number(): + raise RuntimeError( + f"Token following /{glyphname} in CharStrings definition " + f"must be a number, was {nbytes_token}" + ) + next(tokens) # usually RD or |- + binary_token = tokens.send(1+nbytes_token.value()) + charstrings[glyphname] = binary_token.value() + + @staticmethod + def _parse_encoding(tokens, _data): + # this only works for encodings that follow the Adobe manual + # but some old fonts include non-compliant data - we log a warning + # and return a possibly incomplete encoding + encoding = {} + while True: + token = next(t for t in tokens + if t.is_keyword('StandardEncoding', 'dup', 'def')) + if token.is_keyword('StandardEncoding'): + return _StandardEncoding, token.endpos() + if token.is_keyword('def'): + return encoding, token.endpos() + index_token = next(tokens) + if not index_token.is_number(): + _log.warning( + f"Parsing encoding: expected number, got {index_token}" + ) + continue + name_token = next(tokens) + if not name_token.is_slash_name(): + _log.warning( + f"Parsing encoding: expected slash-name, got {name_token}" + ) + continue + encoding[index_token.value()] = name_token.value() + + @staticmethod + def _parse_othersubrs(tokens, data): + init_pos = None + while True: + token = next(tokens) + if init_pos is None: + init_pos = token.pos + if token.is_delim(): + _expression(token, tokens, data) + elif token.is_keyword('def', 'ND', '|-'): + return data[init_pos:token.endpos()], token.endpos() + + def transform(self, effects): + """ + Return a new font that is slanted and/or extended. + + Parameters + ---------- + effects : dict + A dict with optional entries: + + - 'slant' : float, default: 0 + Tangent of the angle that the font is to be slanted to the + right. Negative values slant to the left. + - 'extend' : float, default: 1 + Scaling factor for the font width. Values less than 1 condense + the glyphs. + + Returns + ------- + `Type1Font` + """ + fontname = self.prop['FontName'] + italicangle = self.prop['ItalicAngle'] + + array = [ + float(x) for x in (self.prop['FontMatrix'] + .lstrip('[').rstrip(']').split()) + ] + oldmatrix = np.eye(3, 3) + oldmatrix[0:3, 0] = array[::2] + oldmatrix[0:3, 1] = array[1::2] + modifier = np.eye(3, 3) + + if 'slant' in effects: + slant = effects['slant'] + fontname += f'_Slant_{int(1000 * slant)}' + italicangle = round( + float(italicangle) - np.arctan(slant) / np.pi * 180, + 5 + ) + modifier[1, 0] = slant + + if 'extend' in effects: + extend = effects['extend'] + fontname += f'_Extend_{int(1000 * extend)}' + modifier[0, 0] = extend + + newmatrix = np.dot(modifier, oldmatrix) + array[::2] = newmatrix[0:3, 0] + array[1::2] = newmatrix[0:3, 1] + fontmatrix = ( + f"[{' '.join(_format_approx(x, 6) for x in array)}]" + ) + replacements = ( + [(x, f'/FontName/{fontname} def') + for x in self._pos['FontName']] + + [(x, f'/ItalicAngle {italicangle} def') + for x in self._pos['ItalicAngle']] + + [(x, f'/FontMatrix {fontmatrix} readonly def') + for x in self._pos['FontMatrix']] + + [(x, '') for x in self._pos.get('UniqueID', [])] + ) + + data = bytearray(self.parts[0]) + data.extend(self.decrypted) + len0 = len(self.parts[0]) + for (pos0, pos1), value in sorted(replacements, reverse=True): + data[pos0:pos1] = value.encode('ascii', 'replace') + if pos0 < len(self.parts[0]): + if pos1 >= len(self.parts[0]): + raise RuntimeError( + f"text to be replaced with {value} spans " + "the eexec boundary" + ) + len0 += len(value) - pos1 + pos0 + + data = bytes(data) + return Type1Font(( + data[:len0], + self._encrypt(data[len0:], 'eexec'), + self.parts[2] + )) + + +_StandardEncoding = { + **{ord(letter): letter for letter in string.ascii_letters}, + 0: '.notdef', + 32: 'space', + 33: 'exclam', + 34: 'quotedbl', + 35: 'numbersign', + 36: 'dollar', + 37: 'percent', + 38: 'ampersand', + 39: 'quoteright', + 40: 'parenleft', + 41: 'parenright', + 42: 'asterisk', + 43: 'plus', + 44: 'comma', + 45: 'hyphen', + 46: 'period', + 47: 'slash', + 48: 'zero', + 49: 'one', + 50: 'two', + 51: 'three', + 52: 'four', + 53: 'five', + 54: 'six', + 55: 'seven', + 56: 'eight', + 57: 'nine', + 58: 'colon', + 59: 'semicolon', + 60: 'less', + 61: 'equal', + 62: 'greater', + 63: 'question', + 64: 'at', + 91: 'bracketleft', + 92: 'backslash', + 93: 'bracketright', + 94: 'asciicircum', + 95: 'underscore', + 96: 'quoteleft', + 123: 'braceleft', + 124: 'bar', + 125: 'braceright', + 126: 'asciitilde', + 161: 'exclamdown', + 162: 'cent', + 163: 'sterling', + 164: 'fraction', + 165: 'yen', + 166: 'florin', + 167: 'section', + 168: 'currency', + 169: 'quotesingle', + 170: 'quotedblleft', + 171: 'guillemotleft', + 172: 'guilsinglleft', + 173: 'guilsinglright', + 174: 'fi', + 175: 'fl', + 177: 'endash', + 178: 'dagger', + 179: 'daggerdbl', + 180: 'periodcentered', + 182: 'paragraph', + 183: 'bullet', + 184: 'quotesinglbase', + 185: 'quotedblbase', + 186: 'quotedblright', + 187: 'guillemotright', + 188: 'ellipsis', + 189: 'perthousand', + 191: 'questiondown', + 193: 'grave', + 194: 'acute', + 195: 'circumflex', + 196: 'tilde', + 197: 'macron', + 198: 'breve', + 199: 'dotaccent', + 200: 'dieresis', + 202: 'ring', + 203: 'cedilla', + 205: 'hungarumlaut', + 206: 'ogonek', + 207: 'caron', + 208: 'emdash', + 225: 'AE', + 227: 'ordfeminine', + 232: 'Lslash', + 233: 'Oslash', + 234: 'OE', + 235: 'ordmasculine', + 241: 'ae', + 245: 'dotlessi', + 248: 'lslash', + 249: 'oslash', + 250: 'oe', + 251: 'germandbls', +} diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/_version.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_version.py new file mode 100644 index 00000000..f14d882a --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '3.8.2' +__version_tuple__ = version_tuple = (3, 8, 2) diff --git a/dbdpy-env/lib/python3.9/site-packages/matplotlib/animation.py b/dbdpy-env/lib/python3.9/site-packages/matplotlib/animation.py new file mode 100644 index 00000000..e9b1c236 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/matplotlib/animation.py @@ -0,0 +1,1804 @@ +# TODO: +# * Documentation -- this will need a new section of the User's Guide. +# Both for Animations and just timers. +# - Also need to update +# https://scipy-cookbook.readthedocs.io/items/Matplotlib_Animations.html +# * Blit +# * Currently broken with Qt4 for widgets that don't start on screen +# * Still a few edge cases that aren't working correctly +# * Can this integrate better with existing matplotlib animation artist flag? +# - If animated removes from default draw(), perhaps we could use this to +# simplify initial draw. +# * Example +# * Frameless animation - pure procedural with no loop +# * Need example that uses something like inotify or subprocess +# * Complex syncing examples +# * Movies +# * Can blit be enabled for movies? +# * Need to consider event sources to allow clicking through multiple figures + + +import abc +import base64 +import contextlib +from io import BytesIO, TextIOWrapper +import itertools +import logging +from pathlib import Path +import shutil +import subprocess +import sys +from tempfile import TemporaryDirectory +import uuid +import warnings + +import numpy as np +from PIL import Image + +import matplotlib as mpl +from matplotlib._animation_data import ( + DISPLAY_TEMPLATE, INCLUDED_FRAMES, JS_INCLUDE, STYLE_INCLUDE) +from matplotlib import _api, cbook +import matplotlib.colors as mcolors + +_log = logging.getLogger(__name__) + +# Process creation flag for subprocess to prevent it raising a terminal +# window. See for example https://stackoverflow.com/q/24130623/ +subprocess_creation_flags = ( + subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0) + +# Other potential writing methods: +# * http://pymedia.org/ +# * libming (produces swf) python wrappers: https://github.com/libming/libming +# * Wrap x264 API: + +# (https://stackoverflow.com/q/2940671/) + + +def adjusted_figsize(w, h, dpi, n): + """ + Compute figure size so that pixels are a multiple of n. + + Parameters + ---------- + w, h : float + Size in inches. + + dpi : float + The dpi. + + n : int + The target multiple. + + Returns + ------- + wnew, hnew : float + The new figure size in inches. + """ + + # this maybe simplified if / when we adopt consistent rounding for + # pixel size across the whole library + def correct_roundoff(x, dpi, n): + if int(x*dpi) % n != 0: + if int(np.nextafter(x, np.inf)*dpi) % n == 0: + x = np.nextafter(x, np.inf) + elif int(np.nextafter(x, -np.inf)*dpi) % n == 0: + x = np.nextafter(x, -np.inf) + return x + + wnew = int(w * dpi / n) * n / dpi + hnew = int(h * dpi / n) * n / dpi + return correct_roundoff(wnew, dpi, n), correct_roundoff(hnew, dpi, n) + + +class MovieWriterRegistry: + """Registry of available writer classes by human readable name.""" + + def __init__(self): + self._registered = dict() + + def register(self, name): + """ + Decorator for registering a class under a name. + + Example use:: + + @registry.register(name) + class Foo: + pass + """ + def wrapper(writer_cls): + self._registered[name] = writer_cls + return writer_cls + return wrapper + + def is_available(self, name): + """ + Check if given writer is available by name. + + Parameters + ---------- + name : str + + Returns + ------- + bool + """ + try: + cls = self._registered[name] + except KeyError: + return False + return cls.isAvailable() + + def __iter__(self): + """Iterate over names of available writer class.""" + for name in self._registered: + if self.is_available(name): + yield name + + def list(self): + """Get a list of available MovieWriters.""" + return [*self] + + def __getitem__(self, name): + """Get an available writer class from its name.""" + if self.is_available(name): + return self._registered[name] + raise RuntimeError(f"Requested MovieWriter ({name}) not available") + + +writers = MovieWriterRegistry() + + +class AbstractMovieWriter(abc.ABC): + """ + Abstract base class for writing movies, providing a way to grab frames by + calling `~AbstractMovieWriter.grab_frame`. + + `setup` is called to start the process and `finish` is called afterwards. + `saving` is provided as a context manager to facilitate this process as :: + + with moviewriter.saving(fig, outfile='myfile.mp4', dpi=100): + # Iterate over frames + moviewriter.grab_frame(**savefig_kwargs) + + The use of the context manager ensures that `setup` and `finish` are + performed as necessary. + + An instance of a concrete subclass of this class can be given as the + ``writer`` argument of `Animation.save()`. + """ + + def __init__(self, fps=5, metadata=None, codec=None, bitrate=None): + self.fps = fps + self.metadata = metadata if metadata is not None else {} + self.codec = mpl._val_or_rc(codec, 'animation.codec') + self.bitrate = mpl._val_or_rc(bitrate, 'animation.bitrate') + + @abc.abstractmethod + def setup(self, fig, outfile, dpi=None): + """ + Setup for writing the movie file. + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + The figure object that contains the information for frames. + outfile : str + The filename of the resulting movie file. + dpi : float, default: ``fig.dpi`` + The DPI (or resolution) for the file. This controls the size + in pixels of the resulting movie file. + """ + # Check that path is valid + Path(outfile).parent.resolve(strict=True) + self.outfile = outfile + self.fig = fig + if dpi is None: + dpi = self.fig.dpi + self.dpi = dpi + + @property + def frame_size(self): + """A tuple ``(width, height)`` in pixels of a movie frame.""" + w, h = self.fig.get_size_inches() + return int(w * self.dpi), int(h * self.dpi) + + @abc.abstractmethod + def grab_frame(self, **savefig_kwargs): + """ + Grab the image information from the figure and save as a movie frame. + + All keyword arguments in *savefig_kwargs* are passed on to the + `~.Figure.savefig` call that saves the figure. However, several + keyword arguments that are supported by `~.Figure.savefig` may not be + passed as they are controlled by the MovieWriter: + + - *dpi*, *bbox_inches*: These may not be passed because each frame of the + animation much be exactly the same size in pixels. + - *format*: This is controlled by the MovieWriter. + """ + + @abc.abstractmethod + def finish(self): + """Finish any processing for writing the movie.""" + + @contextlib.contextmanager + def saving(self, fig, outfile, dpi, *args, **kwargs): + """ + Context manager to facilitate writing the movie file. + + ``*args, **kw`` are any parameters that should be passed to `setup`. + """ + if mpl.rcParams['savefig.bbox'] == 'tight': + _log.info("Disabling savefig.bbox = 'tight', as it may cause " + "frame size to vary, which is inappropriate for " + "animation.") + + # This particular sequence is what contextlib.contextmanager wants + self.setup(fig, outfile, dpi, *args, **kwargs) + with mpl.rc_context({'savefig.bbox': None}): + try: + yield self + finally: + self.finish() + + +class MovieWriter(AbstractMovieWriter): + """ + Base class for writing movies. + + This is a base class for MovieWriter subclasses that write a movie frame + data to a pipe. You cannot instantiate this class directly. + See examples for how to use its subclasses. + + Attributes + ---------- + frame_format : str + The format used in writing frame data, defaults to 'rgba'. + fig : `~matplotlib.figure.Figure` + The figure to capture data from. + This must be provided by the subclasses. + """ + + # Builtin writer subclasses additionally define the _exec_key and _args_key + # attributes, which indicate the rcParams entries where the path to the + # executable and additional command-line arguments to the executable are + # stored. Third-party writers cannot meaningfully set these as they cannot + # extend rcParams with new keys. + + # Pipe-based writers only support RGBA, but file-based ones support more + # formats. + supported_formats = ["rgba"] + + def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None, + metadata=None): + """ + Parameters + ---------- + fps : int, default: 5 + Movie frame rate (per second). + codec : str or None, default: :rc:`animation.codec` + The codec to use. + bitrate : int, default: :rc:`animation.bitrate` + The bitrate of the movie, in kilobits per second. Higher values + means higher quality movies, but increase the file size. A value + of -1 lets the underlying movie encoder select the bitrate. + extra_args : list of str or None, optional + Extra command-line arguments passed to the underlying movie encoder. These + arguments are passed last to the encoder, just before the filename. The + default, None, means to use :rc:`animation.[name-of-encoder]_args` for the + builtin writers. + metadata : dict[str, str], default: {} + A dictionary of keys and values for metadata to include in the + output file. Some keys that may be of use include: + title, artist, genre, subject, copyright, srcform, comment. + """ + if type(self) is MovieWriter: + # TODO MovieWriter is still an abstract class and needs to be + # extended with a mixin. This should be clearer in naming + # and description. For now, just give a reasonable error + # message to users. + raise TypeError( + 'MovieWriter cannot be instantiated directly. Please use one ' + 'of its subclasses.') + + super().__init__(fps=fps, metadata=metadata, codec=codec, + bitrate=bitrate) + self.frame_format = self.supported_formats[0] + self.extra_args = extra_args + + def _adjust_frame_size(self): + if self.codec == 'h264': + wo, ho = self.fig.get_size_inches() + w, h = adjusted_figsize(wo, ho, self.dpi, 2) + if (wo, ho) != (w, h): + self.fig.set_size_inches(w, h, forward=True) + _log.info('figure size in inches has been adjusted ' + 'from %s x %s to %s x %s', wo, ho, w, h) + else: + w, h = self.fig.get_size_inches() + _log.debug('frame size in pixels is %s x %s', *self.frame_size) + return w, h + + def setup(self, fig, outfile, dpi=None): + # docstring inherited + super().setup(fig, outfile, dpi=dpi) + self._w, self._h = self._adjust_frame_size() + # Run here so that grab_frame() can write the data to a pipe. This + # eliminates the need for temp files. + self._run() + + def _run(self): + # Uses subprocess to call the program for assembling frames into a + # movie file. *args* returns the sequence of command line arguments + # from a few configuration options. + command = self._args() + _log.info('MovieWriter._run: running command: %s', + cbook._pformat_subprocess(command)) + PIPE = subprocess.PIPE + self._proc = subprocess.Popen( + command, stdin=PIPE, stdout=PIPE, stderr=PIPE, + creationflags=subprocess_creation_flags) + + def finish(self): + """Finish any processing for writing the movie.""" + out, err = self._proc.communicate() + # Use the encoding/errors that universal_newlines would use. + out = TextIOWrapper(BytesIO(out)).read() + err = TextIOWrapper(BytesIO(err)).read() + if out: + _log.log( + logging.WARNING if self._proc.returncode else logging.DEBUG, + "MovieWriter stdout:\n%s", out) + if err: + _log.log( + logging.WARNING if self._proc.returncode else logging.DEBUG, + "MovieWriter stderr:\n%s", err) + if self._proc.returncode: + raise subprocess.CalledProcessError( + self._proc.returncode, self._proc.args, out, err) + + def grab_frame(self, **savefig_kwargs): + # docstring inherited + _validate_grabframe_kwargs(savefig_kwargs) + _log.debug('MovieWriter.grab_frame: Grabbing frame.') + # Readjust the figure size in case it has been changed by the user. + # All frames must have the same size to save the movie correctly. + self.fig.set_size_inches(self._w, self._h) + # Save the figure data to the sink, using the frame format and dpi. + self.fig.savefig(self._proc.stdin, format=self.frame_format, + dpi=self.dpi, **savefig_kwargs) + + def _args(self): + """Assemble list of encoder-specific command-line arguments.""" + return NotImplementedError("args needs to be implemented by subclass.") + + @classmethod + def bin_path(cls): + """ + Return the binary path to the commandline tool used by a specific + subclass. This is a class method so that the tool can be looked for + before making a particular MovieWriter subclass available. + """ + return str(mpl.rcParams[cls._exec_key]) + + @classmethod + def isAvailable(cls): + """Return whether a MovieWriter subclass is actually available.""" + return shutil.which(cls.bin_path()) is not None + + +class FileMovieWriter(MovieWriter): + """ + `MovieWriter` for writing to individual files and stitching at the end. + + This must be sub-classed to be useful. + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.frame_format = mpl.rcParams['animation.frame_format'] + + def setup(self, fig, outfile, dpi=None, frame_prefix=None): + """ + Setup for writing the movie file. + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + The figure to grab the rendered frames from. + outfile : str + The filename of the resulting movie file. + dpi : float, default: ``fig.dpi`` + The dpi of the output file. This, with the figure size, + controls the size in pixels of the resulting movie file. + frame_prefix : str, optional + The filename prefix to use for temporary files. If *None* (the + default), files are written to a temporary directory which is + deleted by `finish`; if not *None*, no temporary files are + deleted. + """ + # Check that path is valid + Path(outfile).parent.resolve(strict=True) + self.fig = fig + self.outfile = outfile + if dpi is None: + dpi = self.fig.dpi + self.dpi = dpi + self._adjust_frame_size() + + if frame_prefix is None: + self._tmpdir = TemporaryDirectory() + self.temp_prefix = str(Path(self._tmpdir.name, 'tmp')) + else: + self._tmpdir = None + self.temp_prefix = frame_prefix + self._frame_counter = 0 # used for generating sequential file names + self._temp_paths = list() + self.fname_format_str = '%s%%07d.%s' + + def __del__(self): + if hasattr(self, '_tmpdir') and self._tmpdir: + self._tmpdir.cleanup() + + @property + def frame_format(self): + """ + Format (png, jpeg, etc.) to use for saving the frames, which can be + decided by the individual subclasses. + """ + return self._frame_format + + @frame_format.setter + def frame_format(self, frame_format): + if frame_format in self.supported_formats: + self._frame_format = frame_format + else: + _api.warn_external( + f"Ignoring file format {frame_format!r} which is not " + f"supported by {type(self).__name__}; using " + f"{self.supported_formats[0]} instead.") + self._frame_format = self.supported_formats[0] + + def _base_temp_name(self): + # Generates a template name (without number) given the frame format + # for extension and the prefix. + return self.fname_format_str % (self.temp_prefix, self.frame_format) + + def grab_frame(self, **savefig_kwargs): + # docstring inherited + # Creates a filename for saving using basename and counter. + _validate_grabframe_kwargs(savefig_kwargs) + path = Path(self._base_temp_name() % self._frame_counter) + self._temp_paths.append(path) # Record the filename for later use. + self._frame_counter += 1 # Ensures each created name is unique. + _log.debug('FileMovieWriter.grab_frame: Grabbing frame %d to path=%s', + self._frame_counter, path) + with open(path, 'wb') as sink: # Save figure to the sink. + self.fig.savefig(sink, format=self.frame_format, dpi=self.dpi, + **savefig_kwargs) + + def finish(self): + # Call run here now that all frame grabbing is done. All temp files + # are available to be assembled. + try: + self._run() + super().finish() + finally: + if self._tmpdir: + _log.debug( + 'MovieWriter: clearing temporary path=%s', self._tmpdir + ) + self._tmpdir.cleanup() + + +@writers.register('pillow') +class PillowWriter(AbstractMovieWriter): + @classmethod + def isAvailable(cls): + return True + + def setup(self, fig, outfile, dpi=None): + super().setup(fig, outfile, dpi=dpi) + self._frames = [] + + def grab_frame(self, **savefig_kwargs): + _validate_grabframe_kwargs(savefig_kwargs) + buf = BytesIO() + self.fig.savefig( + buf, **{**savefig_kwargs, "format": "rgba", "dpi": self.dpi}) + self._frames.append(Image.frombuffer( + "RGBA", self.frame_size, buf.getbuffer(), "raw", "RGBA", 0, 1)) + + def finish(self): + self._frames[0].save( + self.outfile, save_all=True, append_images=self._frames[1:], + duration=int(1000 / self.fps), loop=0) + + +# Base class of ffmpeg information. Has the config keys and the common set +# of arguments that controls the *output* side of things. +class FFMpegBase: + """ + Mixin class for FFMpeg output. + + This is a base class for the concrete `FFMpegWriter` and `FFMpegFileWriter` + classes. + """ + + _exec_key = 'animation.ffmpeg_path' + _args_key = 'animation.ffmpeg_args' + + @property + def output_args(self): + args = [] + if Path(self.outfile).suffix == '.gif': + self.codec = 'gif' + else: + args.extend(['-vcodec', self.codec]) + extra_args = (self.extra_args if self.extra_args is not None + else mpl.rcParams[self._args_key]) + # For h264, the default format is yuv444p, which is not compatible + # with quicktime (and others). Specifying yuv420p fixes playback on + # iOS, as well as HTML5 video in firefox and safari (on both Win and + # OSX). Also fixes internet explorer. This is as of 2015/10/29. + if self.codec == 'h264' and '-pix_fmt' not in extra_args: + args.extend(['-pix_fmt', 'yuv420p']) + # For GIF, we're telling FFMPEG to split the video stream, to generate + # a palette, and then use it for encoding. + elif self.codec == 'gif' and '-filter_complex' not in extra_args: + args.extend(['-filter_complex', + 'split [a][b];[a] palettegen [p];[b][p] paletteuse']) + if self.bitrate > 0: + args.extend(['-b', '%dk' % self.bitrate]) # %dk: bitrate in kbps. + for k, v in self.metadata.items(): + args.extend(['-metadata', f'{k}={v}']) + args.extend(extra_args) + + return args + ['-y', self.outfile] + + +# Combine FFMpeg options with pipe-based writing +@writers.register('ffmpeg') +class FFMpegWriter(FFMpegBase, MovieWriter): + """ + Pipe-based ffmpeg writer. + + Frames are streamed directly to ffmpeg via a pipe and written in a single pass. + + This effectively works as a slideshow input to ffmpeg with the fps passed as + ``-framerate``, so see also `their notes on frame rates`_ for further details. + + .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates + """ + def _args(self): + # Returns the command line parameters for subprocess to use + # ffmpeg to create a movie using a pipe. + args = [self.bin_path(), '-f', 'rawvideo', '-vcodec', 'rawvideo', + '-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format, + '-framerate', str(self.fps)] + # Logging is quieted because subprocess.PIPE has limited buffer size. + # If you have a lot of frames in your animation and set logging to + # DEBUG, you will have a buffer overrun. + if _log.getEffectiveLevel() > logging.DEBUG: + args += ['-loglevel', 'error'] + args += ['-i', 'pipe:'] + self.output_args + return args + + +# Combine FFMpeg options with temp file-based writing +@writers.register('ffmpeg_file') +class FFMpegFileWriter(FFMpegBase, FileMovieWriter): + """ + File-based ffmpeg writer. + + Frames are written to temporary files on disk and then stitched together at the end. + + This effectively works as a slideshow input to ffmpeg with the fps passed as + ``-framerate``, so see also `their notes on frame rates`_ for further details. + + .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates + """ + supported_formats = ['png', 'jpeg', 'tiff', 'raw', 'rgba'] + + def _args(self): + # Returns the command line parameters for subprocess to use + # ffmpeg to create a movie using a collection of temp images + args = [] + # For raw frames, we need to explicitly tell ffmpeg the metadata. + if self.frame_format in {'raw', 'rgba'}: + args += [ + '-f', 'image2', '-vcodec', 'rawvideo', + '-video_size', '%dx%d' % self.frame_size, + '-pixel_format', 'rgba', + ] + args += ['-framerate', str(self.fps), '-i', self._base_temp_name()] + if not self._tmpdir: + args += ['-frames:v', str(self._frame_counter)] + # Logging is quieted because subprocess.PIPE has limited buffer size. + # If you have a lot of frames in your animation and set logging to + # DEBUG, you will have a buffer overrun. + if _log.getEffectiveLevel() > logging.DEBUG: + args += ['-loglevel', 'error'] + return [self.bin_path(), *args, *self.output_args] + + +# Base class for animated GIFs with ImageMagick +class ImageMagickBase: + """ + Mixin class for ImageMagick output. + + This is a base class for the concrete `ImageMagickWriter` and + `ImageMagickFileWriter` classes, which define an ``input_names`` attribute + (or property) specifying the input names passed to ImageMagick. + """ + + _exec_key = 'animation.convert_path' + _args_key = 'animation.convert_args' + + def _args(self): + # ImageMagick does not recognize "raw". + fmt = "rgba" if self.frame_format == "raw" else self.frame_format + extra_args = (self.extra_args if self.extra_args is not None + else mpl.rcParams[self._args_key]) + return [ + self.bin_path(), + "-size", "%ix%i" % self.frame_size, + "-depth", "8", + "-delay", str(100 / self.fps), + "-loop", "0", + f"{fmt}:{self.input_names}", + *extra_args, + self.outfile, + ] + + @classmethod + def bin_path(cls): + binpath = super().bin_path() + if binpath == 'convert': + binpath = mpl._get_executable_info('magick').executable + return binpath + + @classmethod + def isAvailable(cls): + try: + return super().isAvailable() + except mpl.ExecutableNotFoundError as _enf: + # May be raised by get_executable_info. + _log.debug('ImageMagick unavailable due to: %s', _enf) + return False + + +# Combine ImageMagick options with pipe-based writing +@writers.register('imagemagick') +class ImageMagickWriter(ImageMagickBase, MovieWriter): + """ + Pipe-based animated gif writer. + + Frames are streamed directly to ImageMagick via a pipe and written + in a single pass. + """ + + input_names = "-" # stdin + + +# Combine ImageMagick options with temp file-based writing +@writers.register('imagemagick_file') +class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter): + """ + File-based animated gif writer. + + Frames are written to temporary files on disk and then stitched + together at the end. + """ + + supported_formats = ['png', 'jpeg', 'tiff', 'raw', 'rgba'] + input_names = property( + lambda self: f'{self.temp_prefix}*.{self.frame_format}') + + +# Taken directly from jakevdp's JSAnimation package at +# http://github.com/jakevdp/JSAnimation +def _included_frames(frame_count, frame_format, frame_dir): + return INCLUDED_FRAMES.format(Nframes=frame_count, + frame_dir=frame_dir, + frame_format=frame_format) + + +def _embedded_frames(frame_list, frame_format): + """frame_list should be a list of base64-encoded png files""" + if frame_format == 'svg': + # Fix MIME type for svg + frame_format = 'svg+xml' + template = ' frames[{0}] = "data:image/{1};base64,{2}"\n' + return "\n" + "".join( + template.format(i, frame_format, frame_data.replace('\n', '\\\n')) + for i, frame_data in enumerate(frame_list)) + + +@writers.register('html') +class HTMLWriter(FileMovieWriter): + """Writer for JavaScript-based HTML movies.""" + + supported_formats = ['png', 'jpeg', 'tiff', 'svg'] + + @classmethod + def isAvailable(cls): + return True + + def __init__(self, fps=30, codec=None, bitrate=None, extra_args=None, + metadata=None, embed_frames=False, default_mode='loop', + embed_limit=None): + + if extra_args: + _log.warning("HTMLWriter ignores 'extra_args'") + extra_args = () # Don't lookup nonexistent rcParam[args_key]. + self.embed_frames = embed_frames + self.default_mode = default_mode.lower() + _api.check_in_list(['loop', 'once', 'reflect'], + default_mode=self.default_mode) + + # Save embed limit, which is given in MB + self._bytes_limit = mpl._val_or_rc(embed_limit, 'animation.embed_limit') + # Convert from MB to bytes + self._bytes_limit *= 1024 * 1024 + + super().__init__(fps, codec, bitrate, extra_args, metadata) + + def setup(self, fig, outfile, dpi=None, frame_dir=None): + outfile = Path(outfile) + _api.check_in_list(['.html', '.htm'], outfile_extension=outfile.suffix) + + self._saved_frames = [] + self._total_bytes = 0 + self._hit_limit = False + + if not self.embed_frames: + if frame_dir is None: + frame_dir = outfile.with_name(outfile.stem + '_frames') + frame_dir.mkdir(parents=True, exist_ok=True) + frame_prefix = frame_dir / 'frame' + else: + frame_prefix = None + + super().setup(fig, outfile, dpi, frame_prefix) + self._clear_temp = False + + def grab_frame(self, **savefig_kwargs): + _validate_grabframe_kwargs(savefig_kwargs) + if self.embed_frames: + # Just stop processing if we hit the limit + if self._hit_limit: + return + f = BytesIO() + self.fig.savefig(f, format=self.frame_format, + dpi=self.dpi, **savefig_kwargs) + imgdata64 = base64.encodebytes(f.getvalue()).decode('ascii') + self._total_bytes += len(imgdata64) + if self._total_bytes >= self._bytes_limit: + _log.warning( + "Animation size has reached %s bytes, exceeding the limit " + "of %s. If you're sure you want a larger animation " + "embedded, set the animation.embed_limit rc parameter to " + "a larger value (in MB). This and further frames will be " + "dropped.", self._total_bytes, self._bytes_limit) + self._hit_limit = True + else: + self._saved_frames.append(imgdata64) + else: + return super().grab_frame(**savefig_kwargs) + + def finish(self): + # save the frames to an html file + if self.embed_frames: + fill_frames = _embedded_frames(self._saved_frames, + self.frame_format) + frame_count = len(self._saved_frames) + else: + # temp names is filled by FileMovieWriter + frame_count = len(self._temp_paths) + fill_frames = _included_frames( + frame_count, self.frame_format, + self._temp_paths[0].parent.relative_to(self.outfile.parent)) + mode_dict = dict(once_checked='', + loop_checked='', + reflect_checked='') + mode_dict[self.default_mode + '_checked'] = 'checked' + + interval = 1000 // self.fps + + with open(self.outfile, 'w') as of: + of.write(JS_INCLUDE + STYLE_INCLUDE) + of.write(DISPLAY_TEMPLATE.format(id=uuid.uuid4().hex, + Nframes=frame_count, + fill_frames=fill_frames, + interval=interval, + **mode_dict)) + + # Duplicate the temporary file clean up logic from + # FileMovieWriter.finish. We cannot call the inherited version of + # finish because it assumes that there is a subprocess that we either + # need to call to merge many frames together or that there is a + # subprocess call that we need to clean up. + if self._tmpdir: + _log.debug('MovieWriter: clearing temporary path=%s', self._tmpdir) + self._tmpdir.cleanup() + + +class Animation: + """ + A base class for Animations. + + This class is not usable as is, and should be subclassed to provide needed + behavior. + + .. note:: + + You must store the created Animation in a variable that lives as long + as the animation should run. Otherwise, the Animation object will be + garbage-collected and the animation stops. + + Parameters + ---------- + fig : `~matplotlib.figure.Figure` + The figure object used to get needed events, such as draw or resize. + + event_source : object, optional + A class that can run a callback when desired events + are generated, as well as be stopped and started. + + Examples include timers (see `TimedAnimation`) and file + system notifications. + + blit : bool, default: False + Whether blitting is used to optimize drawing. If the backend does not + support blitting, then this parameter has no effect. + + See Also + -------- + FuncAnimation, ArtistAnimation + """ + + def __init__(self, fig, event_source=None, blit=False): + self._draw_was_started = False + + self._fig = fig + # Disables blitting for backends that don't support it. This + # allows users to request it if available, but still have a + # fallback that works if it is not. + self._blit = blit and fig.canvas.supports_blit + + # These are the basics of the animation. The frame sequence represents + # information for each frame of the animation and depends on how the + # drawing is handled by the subclasses. The event source fires events + # that cause the frame sequence to be iterated. + self.frame_seq = self.new_frame_seq() + self.event_source = event_source + + # Instead of starting the event source now, we connect to the figure's + # draw_event, so that we only start once the figure has been drawn. + self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start) + + # Connect to the figure's close_event so that we don't continue to + # fire events and try to draw to a deleted figure. + self._close_id = self._fig.canvas.mpl_connect('close_event', + self._stop) + if self._blit: + self._setup_blit() + + def __del__(self): + if not getattr(self, '_draw_was_started', True): + warnings.warn( + 'Animation was deleted without rendering anything. This is ' + 'most likely not intended. To prevent deletion, assign the ' + 'Animation to a variable, e.g. `anim`, that exists until you ' + 'output the Animation using `plt.show()` or ' + '`anim.save()`.' + ) + + def _start(self, *args): + """ + Starts interactive animation. Adds the draw frame command to the GUI + handler, calls show to start the event loop. + """ + # Do not start the event source if saving() it. + if self._fig.canvas.is_saving(): + return + # First disconnect our draw event handler + self._fig.canvas.mpl_disconnect(self._first_draw_id) + + # Now do any initial draw + self._init_draw() + + # Add our callback for stepping the animation and + # actually start the event_source. + self.event_source.add_callback(self._step) + self.event_source.start() + + def _stop(self, *args): + # On stop we disconnect all of our events. + if self._blit: + self._fig.canvas.mpl_disconnect(self._resize_id) + self._fig.canvas.mpl_disconnect(self._close_id) + self.event_source.remove_callback(self._step) + self.event_source = None + + def save(self, filename, writer=None, fps=None, dpi=None, codec=None, + bitrate=None, extra_args=None, metadata=None, extra_anim=None, + savefig_kwargs=None, *, progress_callback=None): + """ + Save the animation as a movie file by drawing every frame. + + Parameters + ---------- + filename : str + The output filename, e.g., :file:`mymovie.mp4`. + + writer : `MovieWriter` or str, default: :rc:`animation.writer` + A `MovieWriter` instance to use or a key that identifies a + class to use, such as 'ffmpeg'. + + fps : int, optional + Movie frame rate (per second). If not set, the frame rate from the + animation's frame interval. + + dpi : float, default: :rc:`savefig.dpi` + Controls the dots per inch for the movie frames. Together with + the figure's size in inches, this controls the size of the movie. + + codec : str, default: :rc:`animation.codec`. + The video codec to use. Not all codecs are supported by a given + `MovieWriter`. + + bitrate : int, default: :rc:`animation.bitrate` + The bitrate of the movie, in kilobits per second. Higher values + means higher quality movies, but increase the file size. A value + of -1 lets the underlying movie encoder select the bitrate. + + extra_args : list of str or None, optional + Extra command-line arguments passed to the underlying movie encoder. These + arguments are passed last to the encoder, just before the output filename. + The default, None, means to use :rc:`animation.[name-of-encoder]_args` for + the builtin writers. + + metadata : dict[str, str], default: {} + Dictionary of keys and values for metadata to include in + the output file. Some keys that may be of use include: + title, artist, genre, subject, copyright, srcform, comment. + + extra_anim : list, default: [] + Additional `Animation` objects that should be included + in the saved movie file. These need to be from the same + `.Figure` instance. Also, animation frames will + just be simply combined, so there should be a 1:1 correspondence + between the frames from the different animations. + + savefig_kwargs : dict, default: {} + Keyword arguments passed to each `~.Figure.savefig` call used to + save the individual frames. + + progress_callback : function, optional + A callback function that will be called for every frame to notify + the saving progress. It must have the signature :: + + def func(current_frame: int, total_frames: int) -> Any + + where *current_frame* is the current frame number and *total_frames* is the + total number of frames to be saved. *total_frames* is set to None, if the + total number of frames cannot be determined. Return values may exist but are + ignored. + + Example code to write the progress to stdout:: + + progress_callback = lambda i, n: print(f'Saving frame {i}/{n}') + + Notes + ----- + *fps*, *codec*, *bitrate*, *extra_args* and *metadata* are used to + construct a `.MovieWriter` instance and can only be passed if + *writer* is a string. If they are passed as non-*None* and *writer* + is a `.MovieWriter`, a `RuntimeError` will be raised. + """ + + all_anim = [self] + if extra_anim is not None: + all_anim.extend(anim for anim in extra_anim + if anim._fig is self._fig) + + # Disable "Animation was deleted without rendering" warning. + for anim in all_anim: + anim._draw_was_started = True + + if writer is None: + writer = mpl.rcParams['animation.writer'] + elif (not isinstance(writer, str) and + any(arg is not None + for arg in (fps, codec, bitrate, extra_args, metadata))): + raise RuntimeError('Passing in values for arguments ' + 'fps, codec, bitrate, extra_args, or metadata ' + 'is not supported when writer is an existing ' + 'MovieWriter instance. These should instead be ' + 'passed as arguments when creating the ' + 'MovieWriter instance.') + + if savefig_kwargs is None: + savefig_kwargs = {} + else: + # we are going to mutate this below + savefig_kwargs = dict(savefig_kwargs) + + if fps is None and hasattr(self, '_interval'): + # Convert interval in ms to frames per second + fps = 1000. / self._interval + + # Re-use the savefig DPI for ours if none is given + dpi = mpl._val_or_rc(dpi, 'savefig.dpi') + if dpi == 'figure': + dpi = self._fig.dpi + + writer_kwargs = {} + if codec is not None: + writer_kwargs['codec'] = codec + if bitrate is not None: + writer_kwargs['bitrate'] = bitrate + if extra_args is not None: + writer_kwargs['extra_args'] = extra_args + if metadata is not None: + writer_kwargs['metadata'] = metadata + + # If we have the name of a writer, instantiate an instance of the + # registered class. + if isinstance(writer, str): + try: + writer_cls = writers[writer] + except RuntimeError: # Raised if not available. + writer_cls = PillowWriter # Always available. + _log.warning("MovieWriter %s unavailable; using Pillow " + "instead.", writer) + writer = writer_cls(fps, **writer_kwargs) + _log.info('Animation.save using %s', type(writer)) + + if 'bbox_inches' in savefig_kwargs: + _log.warning("Warning: discarding the 'bbox_inches' argument in " + "'savefig_kwargs' as it may cause frame size " + "to vary, which is inappropriate for animation.") + savefig_kwargs.pop('bbox_inches') + + # Create a new sequence of frames for saved data. This is different + # from new_frame_seq() to give the ability to save 'live' generated + # frame information to be saved later. + # TODO: Right now, after closing the figure, saving a movie won't work + # since GUI widgets are gone. Either need to remove extra code to + # allow for this non-existent use case or find a way to make it work. + + facecolor = savefig_kwargs.get('facecolor', + mpl.rcParams['savefig.facecolor']) + if facecolor == 'auto': + facecolor = self._fig.get_facecolor() + + def _pre_composite_to_white(color): + r, g, b, a = mcolors.to_rgba(color) + return a * np.array([r, g, b]) + 1 - a + + savefig_kwargs['facecolor'] = _pre_composite_to_white(facecolor) + savefig_kwargs['transparent'] = False # just to be safe! + # canvas._is_saving = True makes the draw_event animation-starting + # callback a no-op; canvas.manager = None prevents resizing the GUI + # widget (both are likewise done in savefig()). + with writer.saving(self._fig, filename, dpi), \ + cbook._setattr_cm(self._fig.canvas, _is_saving=True, manager=None): + for anim in all_anim: + anim._init_draw() # Clear the initial frame + frame_number = 0 + # TODO: Currently only FuncAnimation has a save_count + # attribute. Can we generalize this to all Animations? + save_count_list = [getattr(a, '_save_count', None) + for a in all_anim] + if None in save_count_list: + total_frames = None + else: + total_frames = sum(save_count_list) + for data in zip(*[a.new_saved_frame_seq() for a in all_anim]): + for anim, d in zip(all_anim, data): + # TODO: See if turning off blit is really necessary + anim._draw_next_frame(d, blit=False) + if progress_callback is not None: + progress_callback(frame_number, total_frames) + frame_number += 1 + writer.grab_frame(**savefig_kwargs) + + def _step(self, *args): + """ + Handler for getting events. By default, gets the next frame in the + sequence and hands the data off to be drawn. + """ + # Returns True to indicate that the event source should continue to + # call _step, until the frame sequence reaches the end of iteration, + # at which point False will be returned. + try: + framedata = next(self.frame_seq) + self._draw_next_frame(framedata, self._blit) + return True + except StopIteration: + return False + + def new_frame_seq(self): + """Return a new sequence of frame information.""" + # Default implementation is just an iterator over self._framedata + return iter(self._framedata) + + def new_saved_frame_seq(self): + """Return a new sequence of saved/cached frame information.""" + # Default is the same as the regular frame sequence + return self.new_frame_seq() + + def _draw_next_frame(self, framedata, blit): + # Breaks down the drawing of the next frame into steps of pre- and + # post- draw, as well as the drawing of the frame itself. + self._pre_draw(framedata, blit) + self._draw_frame(framedata) + self._post_draw(framedata, blit) + + def _init_draw(self): + # Initial draw to clear the frame. Also used by the blitting code + # when a clean base is required. + self._draw_was_started = True + + def _pre_draw(self, framedata, blit): + # Perform any cleaning or whatnot before the drawing of the frame. + # This default implementation allows blit to clear the frame. + if blit: + self._blit_clear(self._drawn_artists) + + def _draw_frame(self, framedata): + # Performs actual drawing of the frame. + raise NotImplementedError('Needs to be implemented by subclasses to' + ' actually make an animation.') + + def _post_draw(self, framedata, blit): + # After the frame is rendered, this handles the actual flushing of + # the draw, which can be a direct draw_idle() or make use of the + # blitting. + if blit and self._drawn_artists: + self._blit_draw(self._drawn_artists) + else: + self._fig.canvas.draw_idle() + + # The rest of the code in this class is to facilitate easy blitting + def _blit_draw(self, artists): + # Handles blitted drawing, which renders only the artists given instead + # of the entire figure. + updated_ax = {a.axes for a in artists} + # Enumerate artists to cache Axes backgrounds. We do not draw + # artists yet to not cache foreground from plots with shared axes + for ax in updated_ax: + # If we haven't cached the background for the current view of this + # Axes object, do so now. This might not always be reliable, but + # it's an attempt to automate the process. + cur_view = ax._get_view() + view, bg = self._blit_cache.get(ax, (object(), None)) + if cur_view != view: + self._blit_cache[ax] = ( + cur_view, ax.figure.canvas.copy_from_bbox(ax.bbox)) + # Make a separate pass to draw foreground. + for a in artists: + a.axes.draw_artist(a) + # After rendering all the needed artists, blit each Axes individually. + for ax in updated_ax: + ax.figure.canvas.blit(ax.bbox) + + def _blit_clear(self, artists): + # Get a list of the Axes that need clearing from the artists that + # have been drawn. Grab the appropriate saved background from the + # cache and restore. + axes = {a.axes for a in artists} + for ax in axes: + try: + view, bg = self._blit_cache[ax] + except KeyError: + continue + if ax._get_view() == view: + ax.figure.canvas.restore_region(bg) + else: + self._blit_cache.pop(ax) + + def _setup_blit(self): + # Setting up the blit requires: a cache of the background for the Axes + self._blit_cache = dict() + self._drawn_artists = [] + # _post_draw needs to be called first to initialize the renderer + self._post_draw(None, self._blit) + # Then we need to clear the Frame for the initial draw + # This is typically handled in _on_resize because QT and Tk + # emit a resize event on launch, but the macosx backend does not, + # thus we force it here for everyone for consistency + self._init_draw() + # Connect to future resize events + self._resize_id = self._fig.canvas.mpl_connect('resize_event', + self._on_resize) + + def _on_resize(self, event): + # On resize, we need to disable the resize event handling so we don't + # get too many events. Also stop the animation events, so that + # we're paused. Reset the cache and re-init. Set up an event handler + # to catch once the draw has actually taken place. + self._fig.canvas.mpl_disconnect(self._resize_id) + self.event_source.stop() + self._blit_cache.clear() + self._init_draw() + self._resize_id = self._fig.canvas.mpl_connect('draw_event', + self._end_redraw) + + def _end_redraw(self, event): + # Now that the redraw has happened, do the post draw flushing and + # blit handling. Then re-enable all of the original events. + self._post_draw(None, False) + self.event_source.start() + self._fig.canvas.mpl_disconnect(self._resize_id) + self._resize_id = self._fig.canvas.mpl_connect('resize_event', + self._on_resize) + + def to_html5_video(self, embed_limit=None): + """ + Convert the animation to an HTML5 ``

$*SJWv+j7{lE=( zZfMxx-T3Cl0h|7{>Ca8+_wT;H=L4%B`00W3AAIV;jt?z*=<|n$SKeFsS7rLq~oLIkG}tC|Hp28Z2x0pAK&=+UyonB_1|0DK9T>#Yfp50 z^2#Sadb0nvRoiN|4S(wPr+#{B?9=x>{m0Xj|NY><|N8fgXC8URwf&;)Teml_nqBo| zRrIrSo_+G!=;vlXxAnPZ&tLTXqt82DnEpcL3xB>a`Na({{`TV79e3w{fqymZ-1ufEiAclPdQc1OQF^W_I$KK$~SS8jWy=9Pi3E`4?Ht6g8qd#&oV z=sh#`Y~1tno)NEK|N6(T_jse|jpyHpd2_~_8{Yi!%^`1H^VYj>b$)yP+fTfG^zD>) zeD8em&Y63Q_CC8e>fOoj-tlhW-Cq03_PwyL`Fm5|Tl=2>y}0*_->-V#@j>bbz7IbA z!1H0whmU`F_`?w&UGveKAGQ1VqL0^o{O!kQeNytt_D}x$Wb~)2KHd9ihtDqlY~5$y zd=~$C!ROmP|Ks!FUo8FNl`mqxob;vd%MZUi^{d%mt^ca#tDaw9`t_q-U#@f8Y0CeScc;lHk3;FN0lcXV>0S`+04r{TJ=OWBrw!&^VJ_;K8i*ZuhNkItVGf4cgo=YFdD>D-^oetzQTpMLIrFz4U{2dfXp9-4jV zjzb?FYWvINU#|b<)n8n{j{J4;uh0DY%ddTZyY#mQe+&H9_4f;ZzxDUMzqdF%=J3+P z&mBH|c)%a|e?0g{;E&EnE;zF0$eTx+)s3uMRJX0}$GV>X$@tIR|M}oQC;mC^&t-o; z_vdea_BlHL==!6d9&J}Yq5his=j(s3@B7#Mzt;Wr@n3Bk#x*Q!sA|~z`hClavo21X zG;Va_h+#v{J$vAQetrA&?iC-`v*(#-oPK(b?%lg}^LS!oPdn|ju3fuy>Czd0ojP?o z6@RDTuOt6XmcNtauY>w)um0Lue{Dm5ZNmOqNBo`G_^(ydeFj|w!!w9rsKK{<2a*l@P~IQ-zBIaTGm^5=T%Eq8@S?Z)Q#ucn)EKS_$ zSwGj`X3f-h`)@5e=w3N)Ph4eA@RU0){A9@X%a24|Gy3Jz@6Y#cr@JoxZ0NIB z{HOVKV_!YI``j~9X|1<$?x=itl+29?z`lx^Ip9AFUPW^UEMZh1lsz} z-#6fi;zKd3QeThXoLhV9ofmzYP_?M8*|lR{IpYEEwCQG&*SzbQyWZcwXzRhK(bv4( zVft+!oSt?6H)oeU^_zR#$~~uCc*iGkIhDa7mv29E!o(Zi>N5MDFV4z;Z;dIz39$Q<8wFHCM>F| zYc=V{x4X`{_sc#D9{q8|RWH;#M=gJ;UD_@0b)UDfdSJj!!5>N|3;^a@A|CQr4R2Pdd0K^$r4&wJ->IWTPTbAPs;a`WEU z^mSkND}4OtkxOppN) z+PsqGw`_d!rT40TakcL;D0y0DX~nIZw(Wku=GUkWr=LA~dREyrx848L%O8C6TeFkS zIA_cZZ~3*iKk)P`AAb9L^OMg!ckBi8FT3tv5B~erkG?w`-LdE3l$qHJSFC;Lnb$u4 z{tx#laYM#km~;8cJ1V#D`6PHG=G6Fv)QfT#t-5n_)$5b_ zjnDS~r)B5f!zRqiTfF-2EziCA`GG%A=yKNZiL>*syy2clo`36$AC9)_+GoV1ISa13 z@!m&Yc>BvA>rXtb?|G9iDY*Kk`yPAoov(iSt95L@kyFwOm)yMW@f~}={<-0JT=&oO zrWY1^7GxAG^2}RQ<}LNiFD&t3RqH9u%`V6&D=+aHQwz(y1!cJz`JTedye0GV3m1BF z3p_;y+38ngE>0`kveO?EYB#7Ukz=W|ZX?7I@~B=jNAr7Uq`ac=B`Sp>!Vu zX=R?0@`8fgf^0L#m{E{dP`I$bGrz>^E%6j(lw>UMmLa4%$jT_oNS8dr)0+a-NX;%N zEMfiJg3B`UbF(~UxeL4=1k1ff3$r5+pe!W_CR8nw3yT(&7}958 z|AB)%$%Um0(9iUe^0JJGLIV;KSg8NNv+&Q^{O4Rm2MqC~$!UhF9?1BeTZ1-YfAL@QFVax*!D86}GhX(Dxs$6HcTSYph} z$O=tSsi&+^x-hab7Gz|jzffbj1*PTl=jUeTf^IwuybB7^R2e27q~Xm17^US!MTI36 zjB38@@Y!HDvNIMe$S|kaQwRzI+$9+W*ACaJk#sVD)nU8xGFz)K`y`p z6=s96B5Dyd`abY>2ECZ|OXOsYSdT33IO2z{`m*!@9Jz3uQxdoV8 z6XCj+O*SM?^W^5|mxGZq&_S*_h|%ZtH;A*$!hA@R(xQw^uMDopTLSPo@4!NKNyehm z%#3_5#f_1I*zwD=L6+1&q$VeO)QIgBt$go-dETrn^p!LZG@g-J=CReV)7oh7Wx1K& ziMf~tTM18Qenx4jz1(ETrmSQcQd8whyqSgB1-VzC$ELC^wq)j1pv?>V$pSqY_R^dy zje9+vk@=-%86{WSH;VmijKw74b8=YpPD%qQBFQfD9X%rHQ+JxZ%NUJ>KR2S*nQgGVJEuLm`zdAVhv`XY{6x1e%NYA#z;|lrWFr#;*65;EAL==SQcekaqlL~~m{CGIO|oh0WqZrgxqu5P zorQ%ZdBZ$lRJ)Fv?z^W z20-d1CFMnIV%{Q8B=sAUl;I={GS3Sw@AagPPMU6IU!yC|+W?bea5rF4VtC684a@JnP7FKo~2kI>-EYHrt*i12l!3lFuE)?J;;)x5N zG2CmcZMevK6gx6#{xj5*Gy3UGt2W$>1~?7 zq%=@uR(g36Wk5Pjx_(R)g=}VtMjYy~EK?5*oP49HLQ*rbxkfd$aL$0$w4jI<9OMdy z%7Ms)m3oWILC##AH9fe90>>CzDtS}%k!1>$<`kCagXX;+t{^}lK>5NP$f|N#C|KB# zAscCgstDE`0L7$ac`x^v%9i4lN&bDCPByIr=zEIj94LPxKykY%b}cXv zz(SN!0VsW*H#@h$oRs-k6kw9Fatnt7G}G3H6BEaCd(Z`;(1)5dcb0)iYhR4*-+l4+D% zlmSLFjT(p+F4ZQ_m^jf8Zk*>`REV{sT2u>PYC1EU6Q+d{&dkfk!X8CUTXI2pX&D)e z>*4%du$Zv-0!S#R#iE>yeh`QSSUy2vWiB$fV45{#P6*vYW%%>G3(+&s;Vm_b3^@01 z%k-A!|E{Gze_tx&@5_{A&zqH>F`o78(nc_+ zlFI_IvP3HtLJvV)Hd3H!+B1qQE#!$Cl{6Ys$!;3Oo1PZasG??%)Vkbb4wRu=uNa^?@~`_criFy(4q%KMb0Gu*;}V2 zQ&{SiGX1hM#7{zd8<2$g4TkjLnlQX&dpp*O(MX1|z@8{sOg%pzPBW5{sb9y48!kDc zpeL3lUWkrDEK_9|q`LI^So=Y?EG)rV!nB2v0_&Rm(MN z&8ys}ChWaKk};oVyUZ7T zTsEQLfgjNl6E^$Xs;U-PBy|eq9EcM%Wv#EtBz6abhF+waH(f}Ig2y6DvD?`agb^m1 zc!7+D7hl^6Cf$Y@MUP=2@CdYtogHV+Ts%2|BDaV#PlIf^+{LA)e8T7@!ZBKwHhCJ{ ze5Row2r{^P8j-|J)`%nxkgS4A4O&XF%>(n9{80-3GGr16Eqn#2KviatDcd7mQKFyn zyo=xg$ilK&d3XW3>CDc|fT!JDhjRZGJ|PNlppe_SW*OPpRmEkJphMKEH&h4=2a6HZ zWG`KU1y3&4bCS8B9L{nDsvfUwIhis-Nn?$1AQ$TrD<(vm@4XB}s_TjxLrfdQB+xz> zB&NL-yDGW!bFt{wg+sel;$4SG*DfCn6;PUMM`1TzCCoG|2SW)aO((0V8T)_WMGY1V73o2 z$uh&hI@m~qFNPXY3-mm%w79hNmEFLK3m@$`3LNDQ-573sRPA5N; z{B0%E02aB);&pRN7qbnt6>|5Dv#0ol!p-ifZBo9e#r_q_lRTjBAVY;QMc5(1=4%!h zqOli>x{_35B0p@xm1Ce(0b+XkOU>P|ncNxhTxgG6WJc03aFx!WN=*@EsnX4e${B?n zVO>GOwstNyn>5R-h?Kcl^a72A3t0sKVeysVoPV5qD90ukK%-OdXEW#S**N7tl(pTDTOHN zO8=%E?*0FhGCUuErc7oMSF;GxuoP2nh9xN}IZ3?6njeT~$~6$w!W{Z~l~fdI1SEv_ zV{)_7)Ztl5JV)l~8CI%I1Ei9zCUSA+%u>XJ$=sqrev^!)MYmav^6?*)REqytWlPKG zx~4h^*$N@$00Tl4h0S|QE1iyZWiglrQK&|wM@0-7lU^yKP>Z`MQj4n-2zc}G36?|Y zvH=$YBV-bkTAakRkh_a9(@F@pUo1%&CV{9X%$2CX6A5XqBCfDPPz2`577KzV)K3T? zW*)yJ9cQxlpN}&H$1iG)LMm|g)}(&BqE@?blqE*8ZI*25(4GZ!T*2d{_Jt74%-{|V z7O0p>Cw6c&}_QsdhEL$r$& z>OKF1wN5gPA0S`WX0ponSpI>TT=e4<5zpx;M#t>nED5+u_8oclighU3L~!I5U<$D+ zxD#a0Em16UN%rX z3n2>%V1$>5Z6_3huFX9~vlthfmQ^K5A!kaMc{W2aHLWuMMZ)1I)P8q=`#d3UsAtC1 zen}Uk^qZPAX8JfAZ)C`+5p#ZIYsWgJmWgFp;R4;Z64Fx&^0BLE<2Z8#Sn3%*!ZT=K zo;Y{S!%o;fgwbUjv%+~JJOj@;_a9VHBN{>y4V|S@%|osL0j4aq;aa)iP4AEaIMS!5 zB~6|-c1qf$^l8)6Qm3YmO`V8syP=*@V~{wechXp#yA?;b)rDYC>`gU;aD|xGWJvHe zv9V%KV^~?ez#<&sTPg%OqKm)Zy0Ln&iXOXzh4wugt0IZ`pAABnJa!K=6`S$QOdnJA z!&4YqY&0E;?=}kP&PfCFbc2bG;CeWiEWElJs7V zu#OdjA*vih5hV4u-dYpG(kbx^#^ZrJS;v{{B5f3fWGk7L^3^;YCRHs{DZCWVgdHzG zT!0;;5vwb;y>Pq+(P2_Vk5b$wg6M z&oX7A$}KBXADN|W#}OH-5SbO8cHrRz(+q)Lv@juZ>f-b%6S(PnF(kv})M?|)4Odg= znXU#4p`u|T&l1|egyPUjiIZzLTy3ZLNY>bO#yOl+TdHCpt;geN!9*NB(w4up}3v_ z+cv&A12&^L%pfL~LWc0M>kl~B++3iO(40ouqPMD2Lkz*b0(T5-J(@l;Y!`5sQ7jT{ zT3E9g@+gNZ^y7>}!69zQW5aRmao8#z4-d-j4WS+93CnQ2BV&Qy0<~eCZ;LdZZ8KGt zDWo@XFVcw>DjCVG^0G-NTN4Q1T=~0HTT_N%R)D!1^0kS^OlEXtdgN6e)-Z9w2Qj799wV;kSY)BJ_oi%r&L@diTqaYK; zJC3fKokMFyR5agZ!YlShEBtV8f&B5w_nhz-Wq1&5V@BIB-XGz)_$A^u6~7|t$wsrXj)vPcF1OHJ2H#J8(I~TZ@dS{#T;SD~+g6uEHGyR~ympWf=H!Bg((rFmAZkaQLq^ zoTpredk9t-QBzkMj?p(7M%+zEzZvk~Vl=z_R>N`SZASCy_ZW^n_Zrdf-iN-|p{;dB zvm@&aNB(-el>;_`|PaSrDvxF}}$K!4`6&Ea}?n!`BjB8O}EMGj|&iyek%mLtla=P=GLb~v+&9mc_H9gZ(n zIb2F9XPlaA&^&p1v#^0C7;{S!ybnt;RgNB|$^sc|%0`K=>nYOTXD ze7~c`=pP-%%ZD5;;}=Ks{=Yj;daA+EqA1E~{D5~6&u->)yw%Lg54WW949H)RhTN{Ip=wXGq1hYzOA#*-uvt` zYg43FUmJ@-Ec_l zm3vgJDLD%9k3pG_!TCqEy5dJQ8*oOg2|c4`+Oulk#CiyWfB0K?3F>i4t@6LDR+n5> zvy$J`>c~bY%kOG+s>VCYu4xrCP18DWhK9w>)TleXq3L+@4UK>OTbd3P z>6-Qf=V}7{Gd0@uEKR$_#Tsq!QjPzR98KHs<(f7D0brLBsGpjbe$fMNl~0*VC`3n&&)ETC9Gv4CO$#R7^26bmR8P%NNWK(T;g0mTA} z1r!S?7EmmpSU|CWVgbbhiUkx4C>BsGpjbe$fMNl~0*VC`3n&&)ETCB6|F#7N?B=_I zFgAqFqv#w)=SVuo&^c!p>L(JX(m9{P3+Y@!=W;q%(K&ajNH|gyAIo6{SorCB+h|VE&9!uv4I!DvlL}v$`|8HMM zC4a>NiUkx4C>BsGpjbe$fMNl~0*VC`3n&&)ETC9Gv4CO$#R7^26bmR8P%NNWK(T;g z0mTA}1r!S?7EmmpSU|CWVgbbhiUkx4C>BsGpjbe$fMNl~0*VC`3n&&)ETC9Gv4CO$ z#R7^26bmR8P%NNWK(T;g0mTA}1r!S?7WjYL0`2>;n0uiL9YS?Fo!y}~Owk!kQ*;R_ zdRrWOb}Gxp@HnH*X62A*Nlth@iGPiokr)RtQet(n=46nwY;Fk~rUdF19%Azq2`3qo z4AvPuWgZsb46_>@&agm_0>tahiCi}b!u7Ehn}fqZ0e1d%NP7s6OElVs591iZB@RnG z{~ik8V`my|77k&cXRsMiD*_$ zR>&jXkZ7@sgi<-Vs+_Lk7@wG8H*wWWfflPVnNzkPtIeG35QWVZY%}Ub{`o{A)lCGc zU~OhA5;War#TH z<~TBABQJ`pT`*fS=Ole%qQ$@qp04Hy4S=^AFozSZGlV?|$*#EqEpfs&`5dg4>0ECU z|86rTS*D5l7IB0)qA4<4i9mMIH%yhznw+3xZ8fZ53S;f`27}RV*G)6p z>}E@{E;%JB7MieMEPGdFV0%?@tW1N6E!W1|j7FBHO@PMA4rxvLWN3CeyoEPfsuVNa zNC`Im47))ODO=%>11@s0O2f*GOv~zXV5biFOvoSeYk1I3%$)sXV(Px;^KKU+hY><(Ls!J%^`u@!3G zs&o$a87Nl$#f9-UOOlR#sCHO%ws^zPp~Hr=Z`B%BYf$N8Q{tiNvtIz~qM3#@Jqaa% zmS};#fv3pM@dEOmLeL70Xu?k1qS3P4%Nmt#7%PCUb(b|zprWg-dB6?`XujGS(#(Gu z%Aj}Xb^KD;*ykD}q-L3+V?Ss#tUk;m!y1h|!v$Km470Ub*0@Fsxs<=_4}VKmaT7GX z2Stcug<1{Ecnb4k8@0xGeM+K(?SUx8t9Zehu7PpredEoE4x>%ym|-=t)xHU%Cyr(Xz9zQU*UT>XCYob;3xuo2uK2KGwSyh;Phm^jOyf5hd#7!xj#ajW+U{!y*JBRk3w`!qJ<1|%{$3zgL{wPc5Jhcb%xEHU~;gpAfv3s zJV9(xI=gwMk*)I)#w-J2&ev*a3e|CtV#P_`D6M+9f$7FQ;$yQ+cfw_!6sSP;uR`^Q zvVS0;`KqY;gm~8E!v`l}{#;+Uy~>5jj`6=$f4I!G9YnRi^T2d|)zuT8i)6cep(Vow z=GX9BUk%GPs(3ZnPw;&czg4T6Kvg?tOawdao1{;GyK;eFvV(2*v*_3nKP@YS%fr+r zqo{F)-*j^vT(?yqIDLfYRJz|6#5x$P*7+H2iFyOvg}g281&vBkzy`1=(-=f2AVdfJ zcr&W^gP|Mxj7xqRR`Cj?R1JC>*1(Nbxtd>uj9WZ|lD{E;uQ8*;Sw^d{m+Wj$E9`8< z6{~6m?Ie+1Y-O_~hzm3gIwMGYU2Cvj2ERe9W_Gw0w7wsBS{X}ux)sM=7CQr?%5QlE zp?9yjz66Lhneiv(2qxD5wJE>cc#Z*clF^ogIcd=0^z269%k#2cmjCF(HzjZp~}C z*dOjvw%vd7lTWZ+{?O?{LeL}c^@rPkHq?lH2;Umhd4701tnjz9k0Gpn4lhZ~U%XVc zSNPuwxCyi@a{;&igo)$W0sqO9o?}1x8&e(Z48*tz5~zPB|65(ouj9}M*+u{1Y<3$k z-jSs#Y@gFM@buO zKjNDG*~VehC)?vKHtbJsv=MDe$lh+NW%+Q6LU~T`o8dIvT~Mb(ydK%LuFIAOYPF}p zqEH^VlkIF_+a$BWW=XcQvbI*O0Ii$fxvuZo zws?JS@eJVRg{nxoF6DjM_p)5)v~%YASv$(L6m;@W@`yLxa?K?L%=H)0D&*zIR#n>$ zbG-t=l~ugU$TRV3Z`VQ%p@TNEzd<9(Vw=HM2iP5P&_D|Uw5;GWJ|vY2fOxD;;<hgXLJ?~t%Uho-gm7S>nvsf2Rexvz{$>f_Dknjw!Djh<#aW&tZwlvw|fHnvb%{78O`0z zEThL1qtWV|FFJ4ZUwY7#Q5T=g>U;1R0erdK!@{ojfb4rtP0=Si_!yYp%f?Rhva_YV z9qe?U6t=1_wnX-8U%2*{TY*JNcJNCa7pK!FT1|RZ+nJwqNtQSxyU`g+eaXu?3s}$v z41U%N;-nvfs%ZHfBD)Jb_9fUXDR8;I=pvgu+S#{V5^U@{h?9HTmBdlNnmV3D!DimC zRBz*dE04B)CJ}oT`jUn!JBu=qvV0R)lcpm-ca=>?W$G){w&uRIVQrm6y=H9`AKn8D5mPKQijUJ+|{*x7H8Le4UN&sM-+ zXs|krbvV#rvc$1pL0tR3xTS?s*>e6p=Lc@5o5#T-L)pA;(2ITx*3d-3G~`C0n1;YL z-_R}93QrZR5ac;xHj@3GHyE=NxMG<%k@trf%zwRq4{*Su)97fNzZ=h&c|i`G>{O>{s4`VrBGl@xdE^~TNGv(SE1zLE^{|Tew4f)L>pJhBo4HKO zX9?Lo#ayVTp8eQUHuu2+AemipoNaCHPhaG=#x_vb8!QfCMQ6C#au)JDGp>LpeLtm*`E$Anjl@tl&*)WLJuH?na&hzKS zegwW|+~R|6{sumYqD6u={rF0gj$H!%%mr=W8Xtyl#hEZ%YQz+vydNLkf9?m_!Q$LG z5N?{^22!b?3o1Thy2^G7ot6D@Eo@DHGyAwdp9%c8Kc5Nw(BE!OV3+zs9WL`aR4w4e zs+c28%4Y)``}5gADJT^F0@pCs2;IL?Cq~_Gc;NRuRy9-udf4l&VTy1LLYuDf&`lXo z3VvihoUY1K7pMk>6smKz85&2Ps-bO>YLhA?c+gGn)W89Ofu-u8YLzM6w?I8GOWmZ( zR7aJm@>MnJYE`c4rlwibs4Z4m)BWo-kdkk;s@5wQpP|n4%2Xw0 zsv;{@rK&QODMwr9Tcb+X7O85qRjQbLb!1hWQm-=aJXNNuL=_pCrK(otdv$71MO(8~ z4XV@HLdYmCJUrJcyhv56s#K?|Vjxm!J(m{ zjq0#4N2&Ivwm@@J?Z{F&GS#M#OqC;BQ>-e1@)xMGRW*>Sqg3T6RGUIaMU8?ZFfhD8 z<%qK8sA8<8YO5nGA|y2`PnD-?)($CD=X9;}&ew#6)q9n8>>1UpjZ6&*D^_LrCq|d~ z_ssMv(3Ghw{4-VQn&3R|I#sQ@T3x9wRNqt;dp8X3*{Q^*Q*rxp)#(la0f}Ymw8T19 zjyhMBtquq)X&aF5SKc+ou}PJq2@K3u7pYRAa+TVE8dU_?t#6eoDk35*A|j$zlRBhe zplOq~Toc;tce-6>o8m529UJ^INB0aZ?a(t*o1v~!RroZhGQHFNMiqHybT0Kv3(Hjv z$yH~nOI11Am~wR^)IH0qXRUWOT+aekj@N0gO7*6;x!Oi;zPi9~lXs?1skTW|sHxT# zx61IYROf5Uz3Y9lT2*`1X)?N%cgThWn!L+Z^_u!N8Qvvuh04{e>Uxc%#HR>~)U0w;XcFVnRdt%^O>J`3McQ<)3~fDJ>xgupI@Q=hh!r+=$dItm zOg6O^M088s@#5jwU?Ri-Ud=lJLNq{W2YgiBcD z+Y<_-jdobeRi)lRK|#U6WAjvTkO2QXwq8@C$x%l(s0-SaYid*hb?pMGy>5D^t24B9 zKBfM}zLj3l!DT8(jmi;|mZeIqZPl|-bK0lGx6G?XJvJ<^QX5k5)vPMfW@t0jRhlwQ zj;c~sr7qLddk2(46U_p{=BjhOOTA9Fs`t$Yl?qj{x<;L)t$=JQR7I+KRRfr=&iAxe zlW&6;glh6&TF;JlW~{f0u>rmL-N@K?#1+J+iJOS85D)5u`rchIepC>0Z(?gd(!t;;}CxF98SxoiOA}1Sf5Jbj>I8JDDO{PM*IkIr(~2rO%?Wm?Ym?Au(weDA7I{oOtX+jlDw2SoH%P9 z%3pQHpO0)M&dfrdO*~*Bat?7J@khjQi%`CY*ncr{6)-PPF7XearGZ-}$LK|V(uT#bC4IOYU$yIxqnraI*Q#F3|wA9l*mAcqr=I*S}b zoIyODIPpBn7ZQ)Xf}BsBN4y)DU$0SK@CT0L#HsC(PZJO9ihPYYBM> zQ&C<^T%Lk_g}7lFvTqQk*RT-z9$;RdfVIe@h*ODQBhD{Cc^btp*nqr@IPW9mPf0(0 zJMtl7-`&VH#G?)%HxT=Ojm-LDd78gP4j`^=Lhel*{5SG&;!zA9Zs3?e9I8TofjB^o zoIqUTg*=0}+#C5l;z~c{b;Ox%kv}CaX^;FB@u;52KLYdXmC+BmfjF-}vZf!(3kD!} zBaXQXc_^{t9^}V~tBIc>4!jrTuMzwH2bs^Cc>aaNZxct}kMgC&MMIF+5r+;%E(Yf9 zA#51(A(A%`pCV2lf%1#QaUsYziHjaaZqpyrs|iI8B5r&Fc^GlbIOH+Fy!`3okt2x* zJdJE54xfZPjkx+*ew-!!LGX5pAJ>RW`MV`JeDB8eGT@yhKROc!|A>4y z@u;7WM-dnNiX2AlIEx%loN*C(8u4l3MZ{4JC|^OGOI!%d@1KU>P`-~i3w}SrkMD_t zy^${ycj|zwy$9nDgm)eM=t*4P33(WCL~rErPW?W}FB69lCp+c$pnNXz&3lno5~tpe zycL*VpVYy~l_XCag8UtEbTINc;@n4&*+49RO1v&fr?E1pN*MVuLhe30VTy@dQ<;sGxsUm{KM}SZT^GhEwmx`A`VDFet@{=G~~yLYlxpAZk&$tIAY&7 zkY^H?zlpq*cp$ux=f`GXaXtB)emK4)E`k^D{HP{Qhu87^xJVrKF7hqnv@GP#_hEX~ z@UER71BvVSPf_4_f_M}B+JPT05)W98YysxiuYq_mao+nVFC@;$MLt4oR#$ zA#pVEH^c_wCgRtLyA8$iOeG#goJt%^Jd1c9@jT*>i5C(d=j;db%hAxN;NYWVJ816( zw4Mi#hk{FTxs)+5kKnRl0$Dh*=`eB>arP=?EAh=0$Zr$J5%XmVo?rEK9G{DbBW@rc zBCdsU^5bXtaDCpc!~x$qH}yy4kFlHsuObg2jv;=ExQNm>5H}OQMH~d}oF9vbO)xLx z$427D0Qdq&8F9H6Uf)y1C5wcZogr@G6@lY7VlB*@`0+P!@iF88sJ5t2DROV(i2cZe zh_kt&;CO`Cu>pA^vGx<>SBOKmBPS7;?m(VP9J3R71u>)aKO&BV} z-cri{58|wYsL!WOT%NNLnNMptM^gIpASP^-b~E9ea@z} zDBnV?rTq31N9;oRQR3PX8gQ)(G6Q5p> z@<`&+zF-(Q;)uhkd}+iDWY71AE2#agBd#X-4&p>A&mrRQuQ9(<#2H^8*As{AMgEI8 zbsw_U3+t1;6}bzsmfGum#9^CJ{v>fFv6kvM|V*ZN}lswn;b z#6gtaqr^9fUmzYt`csL+H(~karfzpX!}*Ffn%Ks=T>jMzaO>*V8@9{+U)FHcS@ zwBKst3gSJ)wXIS99q~<)UnLGDd0-n#FB$7Uh&XLC=JyD35%E*Roz{x#vuNV%`4~Tu zxMBhFEaD-=9}?&C-zmefjkwtx%e$92lFECE*g<@QxJirpt=eMwwR~a%M<8+j7UV(1 zAymGR#HLIvUj%XByU0f3XiCrS)ZdNiy-gfS%A zrajiLhV=Uo2T}hMOzcbXpK!{lJ-k31z8}jMM;yl|)^ON}Q|bPhPaH<;v+om!`s4ku zlh{H0y)%9rl;0%YMDjizu>7^e(Se_fizWl)w4&RPgo(vjKdJ_k|hw}S~eaB(^QN+PxktY*xB2FN#e*)!i5rchuiYTzCojd*Vo{&jsSNTPVLq+;kJ!uM^g9AeAQ&815Vt zLKXXZ@B<$Fs0Tme!Lc5k)I{E-Lm_TUO+SN*Fz zxWWln z34_lB_&f!lr{NP0pNa6{uM3}nPXv6Ph0kR8JO`gh_&g6E{(6wV5{!b+OYnIaKCi$h z8a}VW=Qa57SAsF{(Zh$o4m7|g4nB{;=W+P(IQ%u>{|jXfV!~fqZ@8VCv=F&@8Dq#D zJeh?MepJpK!tuNKU3<#}(8&$`m1T-f$7Kv6$7kW01wYLur{$J1a$q+P+t}fZp`u+Zm!685;)`VpIMW~vrvsAuV=Y)wVObe zFXrlu(K1_^jfH!=NQZyZi63{%ki5!7NCJ3B3Ew9di63LTD3*H@N#ycOb_I!F{kxHl zJ0rIUAy*RjaC9w@!oX!jcqGe0xG#|80OTQ%c>_rji_0%r7AE-w$lZi)t00_kWfG@5 zvlK+0)N*g-7DAcxvP)*a{JC8)diIIGpJwnmZSqengJUPqVouzOKI?JIKv^T$?kQ)i_XDLMHH!THnXIXdO=YNrTUI%n~6+W%PJ=#4gx=^EQt0a+m zE4f(&+_JdKi`;wK6$#oJI`hawWR;fvYSF^fM=(qA@{41l~MS`NG{cqK6kv4xmUXjBu5%I zV~fNjw`*4%+`hqusXFqSCO7Ll2|VrVis$r?ZW)pMrDcLUHl|daOytp=X56WS9sNqS2D!Uz3rFvNk&{36zi6PNwoD;j=IbpF z=3d`2c6o_=7QrQGnYT+M&y;VWLLT6lJog3%H*f*Y-DU*PhBLD7e3v8P3@#57Zs8&T zc4KJa42}YuMRM|P5dvG&KwHNGSY?_z;V14?zpZDu5Q_N;_ZpK3J*#ERJ-#I5&SDaA zr!hC8J6fbG_bMkPxo@}#vU5jo@(Y&&-1-%v;?|GwRHR7{Cu!2dN$+yI#w2-=7%Y46GQJ|OMe&2HD9^f7+){!8b!=(ruJrfmk67n2(X-acYp0qTt6qMY;N8A;U_5zTq3jy3$ z9DRM|YCKf9i@O4EwV$F<$$x9J^k zqvPI1woquHIQ|&n9V0&k49=rxS5EOXn_~ z&iy%^8*{=|GJHo)T|8~Y$rsx6kQT0n!C%;QQx`Al&7Ave!qgEr*mQmoxl^DscS6ct zPVihx=-NHgwQVL%jF@wyOtP(DuqvGSo|s}YOy@3`&h0Px$|PM9_{KN9Y_T(|xZ*Qq z3$Qb>nsE6cHF4E!&ZSv>q9KKEkjgENy}7tUU|1D9_Q4Keu+@o3&;S+#J)Q_;%(r^P zU@-%9-qEgoU9b$itokHp6XH<~d8Djqu*RrKNKM=$1YPG;4#+_2VQ#`wC z+%g*sI(WL`kB@h-lPeEsH4fNFPn4fW!-7K-NPukxbuB}hp~4&?o2|`dHW} z&6O;#wp2d8Wr`m5;g~RHjH{f}%?^{BirX~>&D)xiPZ10jV|+YZ2-s|rOqP_A7-ybF z5yaz$^z@bBYGdLt#OmDf5w9RVn^<{kbj_~xc7xfB+qlKU9nCEOJIW3nf?wrQSiGYr zQ`vL{3!{@Booz;gnLqpL6EOwRUSY4wgk&>R19t4fU`Y+`dY&ojg}_cyP-WO#(|NaG z_|OOMAaK)lF6Uz$*+q)Q7cXME-6B}z*&=l4gAPlG{6a&e;@}>p;$n(eELmJ!Y~h`U zEUcNpVD(~?@N)!H&ZW>qRPJ|$zr!Wo9mXytok3!91N zE3dY=Ua(U#L_-a32f2b^w@RZ%s?m@lmes9v3t6p6@;q=Q6R)e=+Mlzf@|G_j8|d*r zR_|O!q5!=O_7lUDIX6hYEhg7}n0C&HbJlg<^gIC#;?g)kD?^kVT9OCbX3>R<@o(xhyrCL{}V8zsbD z4ii1tJyWFLA_*}XCc)ldvR*-??G#v@S5uZnoLTA*sfQ8wCMH7D3}*shQ3veZ2}9o$ zBQA?LCC)HC&M91_!0s~H;vB@Jm|~3eh>n92j9;$!P6bFd$;x+p7ZVj6pOX!iIC1yJ z8Q~igNLm5Gn((Dj=ow%R1$&1GRn*il9(5rO}gx41-&aC;;vq;VLpd>aiqq?BJ!vr^? z$&yIzT`XPGUgpxefjpYf5X%J4Eo|jd_v~a7JZICsZBal7Gk0!L=QiqS5oa(NNNil_ zd_(36Yq2y1skyE>?-hV$7ntY8uRm-CFLvE@=Hy&h;OU3B5;vGEbXPz;_k|js5Ek0G zvH&5X{w+k>Bz-rNnR?gt;N) zq0Z^12!};co)Fd=o*-cHhVPIov1~A#32$kgPeiCduXv>S9tB7X?oN$ylg7G5k=7>p zZxnC@6!UO5EorHV(vgA;NzZONL!#bHqo6ZLssq9u0BOmG z0;IP96d)}oQ-HKcN&(WMA_Yh*l1>fRY8nMduX8CtT8MH6jEkZ{fC6SlIsu!$Mc|AQb4F zk5Zo`^gYH^N<(bf%tdY~<3`TT@l&XZwHSGB^z_eLx<`3*_LNw+-_hes(%YwtYVdsGFng-<=QXh|2a|bvBy{dNDc)9DV7q4dB@oX| zQ;ajFTi}1bI4=TrJuZ}%G@(1;{f%1yf8w%2n&KBZt~jyIw@?rT%i$ak#NNHmCvRL_ zk|t@+;mb2zw)Evxp&-8b`y8BcJLviNQQaed+hNUEo zPqQNt!6Qso0o3IeO6uDvXEDbTPhOajJeWVrVQ5M+>{}|XzBQ3%&aS%NX=HR8Cfvsm z%*1nqaHZIC9Kr}K#|sLFegfWKxHU8J6oOr&E)g~*me)?|@iD$+6jzTU-LP=+ae+$K z5euV<{}>@aEZCG6r&k2{#=1lO2>?D+xOz)A7>a?5>CT=O18?*Ef&!0Wz@-ga^NYa%4GuR_3atCU|Du9tBb_DL zc}uv3%T+=9cA6M0SA=f*wwe?!SH&LrcFDRVsP3!;A0wb~xE|+jJDll~jj&s==#@Q( z5Gd`PgQNkgvSe7cc-15A(XgW;(K-wr!WG;D}RK50>!cM5~~AN=8j_{P_@#*P@GOCB>} zoNG->NM!3}f~D0CfpNw}=YyJHF)~uVZfjD5LX~M@3lV`QM~Brta*{zANJ-sA_)+6fZ>P#dvxXMB|mvb5@X?WI4>Z&B2|2dTw=DA%m zl4V3`T=P#UBhSLzM#a4>w^3+Ol-udJQsHxy+x%2Qc8Oro6PDi?bi2k_tCi0o=nim9 zx3~wyTT*Q9A-p+acX*pZh#fTw&Bc0n_ofgHpoznjzot6cwQ+ zA7*OUtO0$+4#Symt-|9)Fzp{KNX@{r_kVGSBv223r9Je)`$xbL{BUrvVfb+UkYIQf zICR*E;c+934;zL(I4t(zxFHY5KRCo-e2C@F2+E%Hk+E$`YL?ei`9+f_y`H}JVE1+R zHy?j!L)S6a=KW9kN2PDbdu?>bZTY`{dwALKSBe75btNy&oVMi4XZAgPa{aZbT~@u8 zqzlVEzpv_}i4VTv_0aD@!;k;o>#%Ob>J5goD+iT69Q0#X^9>ieOC$7mY67ChJgsp_qN<}F*jc!uqrT@m+% zemw2&tR_F}%Y&~^Qmy>@TCc6M9++IS`0&QxA0EH;gE6CTg_nP>89Qd^nqI%Nm&3>0 z^SWWw`S1yyqXu-$9sc6EbGvf-JU956;WI)4-l)8>rA_Tx?@I@&W^Wns>nTK$}`r}aqxRbBPJKG%2q8|lw?cu)k|KE555)P_2%QVjxAk3dt{w){lMd+ zpFc3@k8uX;V-H>b#pjhtqpSB#-XE$N{q`UF^SAzd<&!;|R~@`^;aa~pBc|P0`|b9< zzrM9|R@-|&N$WkZdF_{JH+orz_C6or;~09RchY2Y&+~OpEq_8?_HElqAOGj2=9@=e zzi(KVEidisuzqb?MRCLEVcvVp6`w77IOf;5?}tA!-KXNq2b)ZL=kz_+dD7fN9n#*~ zlg>U~bLdFU@mX(w`sS|hZf4x?v-E`|&D1CEi`=!USKPUpH}1-A?SKE4L@TYZ}F(EUS{WiYwkv@M$4-b9nrGwkA91a{gxqM9Zi*3?MOGh5> z^x?XMb&1K#t^Ke1%?qCK%w0n-KJ@XH%Cq~gm(;JgcVhn1|2}hlN?~H!Zqwc;D*LBi zoca1ksgy0EeFo(H~&ymz_j^cUZ~F=gow^YxPh zPi99P-1^w~dD6bTL;x2TJQVdmCMubDY5OJ zl3-tWWYL@6@sGY&bn3rfb^fZ~i8u11FT8$nEGs?q_?L@%pFM8>DrHTZ?c?X%KSS4d zo9~7y5Bm9)VHc8ij5)dFxx16bfA`mo zjMox>w;0OuckVmn6Z6sRxhGR{xBWch(~66`qbHqAKao86(W$d`ztioX?^F7Jk=moz zjrl*t<;?!&z7;Hl*?{`mAC-}5>VceQ6m#>u3{*<;@Sb@jEZ!e^!*+p#FaI4I1g zZJyuZV@(Iv2G4l0-@wN%B_*8NvOXqZdQjnfuN~1#KGXJo{jHae)}N^vxASsB&iL`G z?muwPe>yC^|4jDa$6L)@_(jOLn|D2QD(CRqwzi*~tiLg7Nl!y_z~0|pncMO4Un|C* z47hlBwf7sgwl`|tdTVmOp~FhLjJR}p`Q>wsJx0x~Zui)(!gr6g%g|pg34eJ0UzKmY zZ(VqI{BCpBt6#*l|Lvt#wxN*+U+6kv)W!RMRfR9UfA;E~?=(Nxv?qDVhX<>C7WDZv zeB^+a7v0^%^7hE;@88JA;31Sec;{nBS$_s7qlx$uvaBbTC3$C91>2kh#;O;NeR1d75wRHbyf6mb@GIZ~7 zeC)dGEjf%}#fwmCGQEWPceS)C_5d1hUQTg9m(zP_=- z==DbM3Ek{Lk2bcR_2h@cUQ6q8bJs(DJF5nVkD56#((=s6&zF@%muD@gy{FjkeV@t< zW4~!9ue|nf`TA2o&*Wp*rRR$G(3eb|v3qSifRQ?U~-4+Oq*awQG0(f9jt-@V9!|h2u|-9F^QN>FyqX z{n|I~#ImcOe72@~y17k~Ipp{}$JBRU{nhL3cB4P&F{stv*=;*a4jtUsE<9p zPsQ{-33Gyv{MfO}kow%s4;>yCH|V?RrcveBN5mKU;<;u@r8x{DL=A{>(*LOPd zWZ2_fcl{N(ZqCA|>i-^;vCCAy*Egf&+WFXd?=C(0RQ#ffteWWOKU{F4-}rqCOvgIU z8~Odt$rrXXT&*ey`p2Z(b@at(KlQLppHJxC`sAFG_b+}ubfy2tvkE_rvV3(uzD)by zZ@!tLekRK6pS0q%nR8F=c{gnSppE~h<+nO5?RLJ$lGMsW8H=BO{0kOyZgX_y`4#Ir zcyD{}{;gZL|DVp^@#cFs#{6_>){a>A<6n<1?dNmf^p8UC-`KnPo>3!9#yt_<&acgj zAFW*y+~MHaKI30#U3R+H(ba2v~A1`RO&7AvM zoAf{9ziD;+;qU)0U-$WJ)0BqwSD*I%DPp(j`R&Fvlkys$G(9!ymD!m;yfDVx=HQ~I z3ZjbYZ%oh3>Gu3P`ZrcZ^nEHieOhkBlQ)B2+K`fSB=(sB^ZG>h9hw+-Fnr^P3qiAP z{dnt%L0*35_Ej-!ZK;1x)<$jCz4^#j8-AKHw|;8crKeyf%jdLWrh5Iy*8Dr{*Q6YZ z1r!S?7EmmpSU|CWVgbbhiUkx4C>BsGpjbe$fMNl~0*VC`3n&&)ETC9Gv4CO$#R7^2 z6bmR8P%NNWK(T;g0mTA}1r!S?7EmmpSU|CWVgbbhiUkx4C>BsGpjbe$fMNl~0*VC` w3n&&)ETC9Gv4CO$#R7^26bmR8P%NNWK(T;g0mTA}1r!S?7Emnk|33@-e;Hz=h5!Hn literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libsharpyuv.0.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libsharpyuv.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..daaedfc42c3e30d5c0d4ea5e591ecf0ad405e46f GIT binary patch literal 69408 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 Z> zfTwqkM^P>ZF9%OQKe1Oyj@>Sl!hbICqbvOB2EWSixrQ8{6H02^-FVYc$LAPQ$LAQ- zcj5RPqXItDDGAm@9`_&;Gd;Hka8gAc?u>I*R&1bm(v~q26Fo~tfM(k&T4w#avIVhl z;-Xrx&Ee!mdY766n=X#yOc#T3c884GhL&nvucI9I4$$`lU>rRrmB8Db}^% zT-DdFiuTJpc{TbSF80eom%d~4jpvT_?tX0Gop=m)^!qFLCJF6ReNVq0Xv=vAB~#P) z16i0{y@uX3hsf2q1M`vL4pGj_=0t+JaCUzYaVI0PIcqSlI{ol2`D}!t4)f@wFR8^E zQ@pj?o_1&1Y{bnh#LrB`(G0}XbgT!{Oo*>q8fTPh7CGMwKjVnwz5y|43m0W;eEMZa zvz>bK;r%jNANOCrve1w5oq+I2dWLhy9U|_%QpkByNLsJ`Sw>HBITV`(dX76dHM2TPpH-c$sm@Q=RA*&qGFumF zs$EvaW`-}+FU)Ds%R)(QFz4Boi!~#!=sw?p{pH~te35sL>_WTwockB`xbsYuk+fvQ z_oKwys7E@Fco}^_2RNUuYoqH`JmeKb*>w*27zytlm-A&;$DJ2w4=hJ7kgm z8pf&gE!KA^i=(bJHE3e6clnwdH1n~4DfMq^I`To`>0WN&JBAl)IxzmmvPJss+mz!P zwQIPWGytIugj^?6N5b-ShymwI5;fc05}vCqZW#)7;+ zdBEq3QG($e&^pAnj`N;V$SDs1JE|)!>r^j~B8Cd&b&nYr$T)>D3F|fe zJhmP8Vl)=0|IOG>5fdrF@VO3srNZab*PZb7Mfkc4zP<#XgaCthPzJ_Ns?+tPIzzJ% zV{`h{qf2hLr{%z>w4EgQ&BDtfJ5eu^lYOCGMX)81G!Kkp4)HLKMXDj5MsH9B=iPM$ zK2ky+Eb;2Piu@H$=|0v`=GoN+ek{rka8AGejVF_JoTs}H>734G>vOQyy|jwdQhYo? zGzPBV-mSrr4yRN`y`q_b&Q#d{|ptdK$jxit)P&mf52KX0%H1I(L=Q$?=cf_-SxePdm z0+0Ur_KAvqZb~qh4&XZl^t%UIV4o+>JuN5EDS*#9yq{>5kPmatNh<&1K9cq#{ zn+F<$_Z|-rja^Up=@(uSx%$lM*eduY3u!jeM);<>I#aV9V{1(FNv;Ncf-yEq?@Rs| zvTCHO{WCOg`DbdTO-a-w7!oy!8!MWtQ0Gn5&CFk@$;?XEBp^*d8nz~`xfyde0yrmu zs4sHy-jxJ@QyY_T=iKR-yAsS@xnu4g_9SVK;&aV6f!oVO;+VhD$RFc8jWH7C7o%`) zd!D!$zrtNDozr%4PP-AM(N0{uI^g%w5;w=3wxd5fk7H04CvkPm{cO~=b1sh9$w2#B z)Hw?sH+M4mE6&Fq?N0uMleoWx^d-#s&#*5h!9N6Z{bd61w zWgc<%bSy79I5mp^1Crr2%JopJD`cONY|Rmp?NwC0T~k}VLlg7-R*e#rvdzysVVhs_ zk+jg{4$#@^H#JA9-vjMNJiV()kj5tOfKDTHGErU)+E%?ybFTU=#M*B7=w0|CHaUCR zSmW+$VXn(|<+uc8k^U3^*yQb4TaI8InThm5IQ2z?rjZh4)4?|mU!)lU{c2^gJ_GuR z(91;G3rNqQyc)W+P6A}B!Os|;scFRh%g@tC85^s~+-BS@DHBL-LI~CboU`kJF@D69 zmIR+A-HFF~Q<*Zid}T`>VqFKHu0=}E9b@6I2+U1S(A#HD8^+PW37t7TyO^&VK3Gx>`PKJofGkA zw6_zU6K;ng9f@?*Hl_C}lI}GPX$E{7249839|@rJ>aChk>D1&5$P$ny_%~`o{kLfn zr>w&Mg>}!cN|T|?@(NXEQ9PqYgs1D{^B3y3V*S(k;Qj>It)cUwEXXk*KKEnu;s1yE zP>DOb|4H+K?l<&~D%wZ#B#{I=^2!1EtIB@)-v{J(56G_*^LW8?oG-7=JYb@2uJa;} zHs|3dhBmwh6FfA36M6dEL7Kmgyh_Z|@8yMy`OC=T9nqn45&1`v|1_SEFuctB(;rac zmxJ=}?e=H(+U=D^l&>T-{c@|_z6X^l{~`1-fr(Po_k#W^=og9lH2n_x`$T=?Tta5N zg5NaKA131Y>TA1w{7$r0Njdz3|Blt!?c=(f?f(ZZHXr#5A?^6GCABB^g592Ky1V_; zo9*^@@ntqzxnL3@0s9D9?o0Iv*?HD(f9x-JxBsEhZcn`7)F)DzhtfZAxLtfW)WL5r z2~9&l^a%kuf4fN}^mp*|_nefzn~Hz%&^-P9rw5Ud2Z)r4$a0QI=R){^l<*%*iR3nZ zP}*=G;bb9%1mmaW_vFa#I^3;~7!Lx3T`5MT%}1Q-Gg0fqoWfFZyTUvFa#I^3;~7!Lx3T`5MT%}1Q-Gg0fqoW zfFZyT_vFa#I^3;~7!Lx3T`5MT%}1Q-Gg0fqoWfFZyT zUvFa#I^3;~7!Lx3T`5MT%}1Q-Gg z0fqoW;Qs;vpHSIjBgo_NDPmn8A*(z;OIupDBtx5#tIx_VA@hsLI#NP>1nr`d>};Bs zAzzT5pI?|sIVI(?3o?t!DHjN?sPGw@4WZexoRaMHEN#J(vTTDEHFUHj{GO5}dalR{Kz5B@(Us#F7kGfw+?ld4}~t(FA8w-W09xr zH95N{4~zWV7-#ux@Kk@#1SkKr$hV4ofv9g4`6`i@PIBsR5&4|SPQHcmQbH=lzvpmJ zcY0e^4y%`#TZSX}LQgHDdYW zBEL@Lb47lW$S-vpQ+_e_X^g?)45H<@EDIj4W$#P6H(j>-Oe(|nLjoZ$DYF52{xg2Z`` z&DJj}>>m>CZ(3>5-GZ6v1qJD8=^6RirTqm?Vd30deRg_Dzu3vA6*`KEc6LEgVM$rC zK05^~llHNqtaL0SIVFV!=_o^AeM?Ph>h$qz>HYC=ypKtu7@yb5eB7+}wiPvh1uu(iuzg^9PD1M?dsCijWRe)H<*&D#=}n z(e>L*o!y78_R;K;#o1Xi^9wW5^9P_Pj;p_tQ-C4$i+&po(dzC(9WF_wA?bK}fATnp z^>!r~-YIc}GN!2{&pE3kOQA#g8AO7G2pQ0J(34``laM3xLL|fk{J-!Bzv<-XW|Y!B zqkPHIsA#gOJY=0_XSUZ8!&;Z5hTSQeyvhTgs@@uFJwADRK%(vW->UsV#>MOO_O6cD z4|k~7pKLwh^1V_u?d*l`wrD>kg)xu+`FiEi2N&Enl}>T}V&=yQ8^p~@XXRF9h2M+d>VUX$)@?-fAoAtMp<5apmX7>%lEJT z%c$2vC#F(f_Xd2Z!%k3NDywVW?*XGwOn{CC^`XZ2SpHDB)WXgaLRIYe&7 zwm(F^*?H`?;_Z^<75{5wUdy(*h$0TIb3{q+PYRls{edf)m?6LrUvFa#I^3;~7!Lx3T`5MT%}1Q-Gg0fqoWfFZyTUvFa#I^3;~7!Lx3T`5MT%}1Q-Gg0fqoW QfFZyTULHkpMM~ahyVZp literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libtiff.6.dylib b/dbdpy-env/lib/python3.9/site-packages/PIL/.dylibs/libtiff.6.dylib new file mode 100755 index 0000000000000000000000000000000000000000..e6068175d2cf03c723e9c4fbecfa2c50abb6cf48 GIT binary patch literal 751472 zcmeFa4R}@6l|OvWy@{Ng5FmVi<^xo2z={;BQnlP9GA5`+1JnnnAx%+-3 zV(0(9@AJM-d7g03-h1t}*IIk+wb$Nzoqb;U?_d9Eq~o{_{+)%tarldkaGXb+G0bwN z;4d0-ocj9Zi*HyiS?T{BjO0w`BbR@~$$$0r_pIG=k9t<=bbQmcdc&&i^%anqffQw(R~^I8?Yo1YQUJ4|cTnxgcd`ufJr_uRey&f9c$CcazGRsAsd zm;x|qgC&htWY*Vz?9O}F-+62O`a3_mNz&>4acf-Rds25G)0sF7ZvIkF68NjHzoK$^ zWqtM14=+>NV)P@1LjKE0lV|=BH#M%l{H{Y;IrjMa+m2M{y=US{g6)I z1)82qKBy`&ZR4|0$s_sPhAvZl+NA|55i@z|X~SopF0QY?qoICt^Tt~?-BEwnJ$Da@ z@5w;u1!;6qdu}vM;kUm2)`oi;QW=@_JsDE;Ox7Sw565SH{VkhQqbr-=eH!0BrM`mI z#%E!;=U0_V#)3Z@~C?R+pfjOOrsVR#OH>^`7x*Hyazy|3FGM ztQW&yP%rO8NPQ@)-tBj-z3u#q-hcju=U&*Mu=DSHJ|CTjxzGv;m^Q)|C&UEx+RJS{C(_Qz>Yq)#kMHjyBmXEE!<5uZ>l=0uW z_@jKHs|%cU=+_FJW`FYE44rnS7CLvWlB~b{_ZJELMFM}3z+WWr7YY1D0)LUfUnKAs z3H(I@{~wURVAwr6a9_A{pxg1=!lnJ~-6dVeraAHBg-$XtEf!xFaxTQGWPC^W>aG(= zN1T?i6_M{w_1wsY?XI(&Wo_a5{@%h^GJ(Iou;WKvC;3pGv#)CB6#uN<&aMO9rCnG? z2#!AB@a~UH>p-5=?XK?{xUaesbod9u^*_#}r+2iIJO)~hj{rTu4|-l;y~OBP@&wYL z=P}UpS7Im>$&kT<6sH93=i#|9)%}kR4({%O?y!&1Cqjdiqfd?@@5wFht{&78T^a|Nkn?rZ{~f^Ny0PTRNwMT! z;OhWB>d{>2^_+Ys8I5TDeru}#Va-Pma17kHxO1>o>#-#>(%cKV9fRDCLvEzw802vr zJiiH-7FM(AM6) z3i+%0pBm-tYID?hjXEuL9T>}1A&$FMU5U|7+)IX=4i;%$9gT4q$!j_|%1X~bdbE|U zKzfXou0^`oO0PhAtd+hI>2X%N0qOBpdM(lutaMXeQ_B=9-H!BBEB*Dnrm{<{^dIt? zoM~1%nb*|z0V_Q}zv*C^m0pG-M}~HfDZ#coDTnlf&W+z_|_@Fe`6Yc*nK6R%X7&G z@L_=uU}aoR zsmvN@eOIE+m5Miksl{B9F?Rc^0aGn7LI-L6vBntzP7m#ozeJ%EFSqo|11`w3nYxvj z^z>Ag%RE*Ho9;Sev)WmNb{3_}`9(wfIXU{}Qovs-@WGhbXXsj`bUUZqFNWMNPRacl z(+28f(X;?6wjsvlTtkUlVe`%mU1;beeBBIH%-*F9m#QI{fNfG*1KEG);4HQ5wy42LE>Wv#$10 zIOoI8;4EcV%ym8>eoN-~d~Lcvdl!B0lCDY%M^-<;f9ivugE0XA3-$~)w-dh=)IZE! z)UmJF_U_X;^ca3rAN-#Hho1umzE~gpF2ayr(&F;CHB_`JsOsb%QpV=bil z#2KFO=pc{0a(+2BB9=`4$lYb?UvBE_zVITc`Z(QF^^s@S??e5Ro|Sf;ZOJm>==DIj zzTed8LK}n^d6Sk*803A`hGBb|Fv$A{3nrKDuwRuva@~7H=OETJvc|F23ucYQHIo}| zd3E3(=m})vJmJWi%fndNX6Z>4=|;J?7CJe_X{yxvAbEgw-gM?c$M&0a-=>bbGIw@~ zGa;4d6j{&tsprTV4O^Vbb0W@uoC%K~9HHl(5tw(1oTg7^w0i>iwXnT&?k||O#C3{= zj@ReBD0E>sZ`er$PN446cko917eHZoZi>I+(9OuNbj*F+Q!&;rA><_MMId(Ay;t8jp zC+*{VM#Kg@=c8XB-94qwew?#Q9>-wXc>6TQ7si#zb7HrY5MFSU#`X`knssh=TZgT- z1n+2P0O!AF)DG6a1JVZULeNGv+OTcG6QHfEp~UQAcw_dBb)XxlyPx(puo=FB`?j`s z-k7!k4u{VICw!rvZgc-2vwds|uDS1TW7{r@E7cK2lhX>x5RmY^hQ^O1P}9E*q}#XFGRPIehAOM z5nE08s$dUFa2HdTYc3*g!ZXhW%*RkCXb&*k+#3W&>YS635!)`GqS7;GRAC-l^y8r3 z;;Q7fvn;x6t1yo_r~2|$KXN`7Sj@}BQz7M%lT~`|khXxM6Xjm>`u<=JEr#tgdw}eh z`SgR`rbD_PX)|Y+i(ho1;fwv}qTV7c7xwLCnn%JII%r$yC;k-j3giJA=G*dEtNGA$ zQioZe`XGErIrz}FQ21!5qVE$gfGvkjdkTKl4$Og&tJG8rU*i`zQ&`XRr+E(&15Bp&3FWA;VpVGz{ zZ3$qp2N}m4fpO{V^!zzK{jJ)sxXC``ExIl&Ws>(bo!1kBGvZ74v8N+!Hl63w|5cAEjN&AGPOy zOJ3F<=ixl(2=qhzKJJP3z(-HOM|V!aHz#fMO_44@n){N8aKYXve8{%V&e7IT%d5TN z@Lt-khx44B4_{K|Px&GG6Yw&I@JqV^+b90gVeP|+-@|;!mU|T)z{O|kb}xKDjw|X5 z+hbeU1K3$rQ|6EIu?N7uwP+^qYqY%{_<_3%x>%RCH=1E5+c7Wi372*~gR%D}bmA9i z_m_~r=r-o(in5kEmuCjy`mWHb$;)^a5ytPEpy?N&>6hpe(44O8XajR>viD*qery58 z$~-6jCgk=D@cm1)(Q|QZzw=u81Ky1tbuN7&ue`+TdAcs~+m5>>J-J-wK={=AI~M-gS0jvw$>yAHC7cK3$n{zGe zu8V)7uH(>`RNGOsUFhtWxe@KVW6p(N4*aV$t)va*Y}-NGuxHYK=C5g=eb}==_+9PY zmBLZ;VCq@wvfUBRevG~S-t$k@t^2N~2Rxsn*MQPyG1>&o;eCqc5O^rRWTxUn^JQd6 zy`l{0v)FaXGjZ6z23F_=PrdVE`^#S|7n-Gw$ump5^&NHQ*}3El>7DW(=!H(D(W~p) zbQ-#8rwB`WgY&D_(9xcy(68Oj{@%x({l^}~Z#DM*7h&%o`znd07=KL|v-9vgkM%*@ zZY2k%-Tc`8V~>Mx5AsBRNL~bakEZf^HlXiWw^m$BSIIn&aY*W(#9_uQuIuF9y3{GMf2U6eB| zb(i58H1{;>x(yk1kq>#N+C@3jQgc@AYcuMS=4z`h%9)nB)p%}1U0cr3bCG#I@L=qF&Lt&@O-@{N$&JPP zHo+&rUd?wkUnW1X$cf9oGs^i){E0<)HgylVe&42+xYNA;MX#)^WTW<>q`p<=9Gn^K z4fITN1`q`*eeC6exul_lFv80;u8*2a^d4tCt^W;Ak@v_G?0CQvo`t7*DW0~Ue&|*D zS2katw)n~{PvdQzGa&m3(BC29$RFT@zj2zsMer+d{*tDnhChta_ta;l7Jqma{z_B) zMNU34EPt8hY5WzY_!|oV}@GWaSfJb+_}8%E4;8e$y7Z{Ki+Rr4*nSt|#KE4M?6+a< zE%~r1{1tl%osef&&1=*PfysCFAE?&rp=!Mzf_ylp-?G*b&Na{__$=@T_qSKCez7c8 zR^oiIY&7=;h$jTRmB=ec9{2x92Yk1I`d6`@!(Ly{B(#gY2hL@L=lJcc{z8}2toBzr z(6+3BK+AvVHKVisf52B{Xud{T>pbT=&DXg1##e>mYg{^CX6z2d+s_Se8~+Eq6`dh( zD>QGT-y3iL3B8g&8=cOZ8Mnjpwz{8wh3HnXgI}aEcSw4IPQ&g>dWy4O`RCSNB-SE5 z@K1WLhwr=$zVlM}&a>b#d(Bfz-9c11aZyMxKPGt!8Hrds3Xs_@eH~!Pi5nU%@n*W%fySg zCYd`>mcX;%LOfE!wzJ@szLhrtYaR00yuPas=?bjJPAqMSS2W+=g>hL3|BZ0j?N8F} zvn;dyak_n!;e0{0kNw63>If~9V3TI4xg;kI*uyxnOwn)xG%YDYj0$L4(!8My`&orv z<@TZJf*lsQ>4*L1tt7wlfu)rmTLyFcF*T|eg%(#3chv6HCtd)g9|JHXis-3`TBUVSlWXQVIq z^YuOlbjWkZsJw{IgY1I5BAthR4f2Y09{N7Wn}ED9_v&C<#*~$~u;*M0wYAQ8v8{EL z_;O~fanHSHk=n~;nG1N^Z)g3UOP&237cA#9dF;6qekkh6^CGMV-%hQQZJ)w(wv=>K z&*&mOv^nj-A@d9A)Bb8(7<7em&~>q<3uQU!TA=Adc@Lh2mIa^-_2l{Dq3Mc%F4`H+ zp&i}Rg+A=1WyotfnI0s#`jl71SYnG80=)$wmG7EH}o;=SUnyz$tP3z)#NQ}l_`&DWziq3OfOjP@~ ziL1EZxw^lsIJTc>L^HXMfjxi-)+UrW&O}NM*Qa!b=N&Q+O+X(2j?dVW-7otF&|R)S z+RT_k8TU0j;N@CB7d+M&qO;DJ^SRzo{NXI6cN*}+uk!YF$-a)aPvO{({UKR5UFpOF z+9CflqJ5I4y~v^+b%&%Ka9Oll@K`^jXveek4Scg+_%XR?zsb;E?Zi8(S9Kw-L}F;Y z@>sEV|Cn*KF`S>oMm5jr>ZrcC3%+(X3~WsR(+wDnN9x1oq{>#N)t7SEA5%{Gd2Xm! z`X6K7?(+oB7R`Pd&yZ5Shr|w{?^R!y*?ld(NvfQCTeL^gw|Ex$zz>o=svLbgR?A1| z#Jp|jWIfwf3*9_Fgic=#yRH15TI^XH|6k7Eu(##xKNfcOW6x9exo9tgJ%bS#PvA?= z;8-3;pV|8$NVA;uvp$~<{lT7dclxmt7ZzqHfb!<~aUFN%5T7PM7$_SydDb~w9u z-e=e0JX#3crp}3Q;oh`*Uq0LaJJch8kR{H-tT^s7;c-m4|8iE`>lw%nTSXo0w(O1SdhfZY2Ow4nd6F4LC zZmh&PnvcDJ!~OD|yfP6}aW zec#>XwK=|vxG0Q)SI6Fg_X1lniuJ_c!Oq4&7fk z-$`~)e92rJVRt)(IT;nZMKEoMJmz z7bQc$9s76mEyk6{xC787dW>?>bI`>&gu_P9AyX;Wa;wSLx<$D`&p+HhxZBB7@dUZ( z|JjD2=})4J^yA))ccq{GMB0mU&>qmo@dSE*1p0H)5+8<^A8T6Zi@cjGWnB+idR|uX z3TLXf;%{L;gmDsl4+nh`KaTl;eR($i&cyFJhW%8Hf*sJkF7O zzz@q2zp45U{ktu!;3!MRp7H&q9-P^){ZGW8X&v({T<|fIr*BtyaNa0*Oq&LdX=68z z0lpJ5AuaqnBOd~Gopc+TpuZv$%H!af_*z5A^9t18cP8~AN4(>glLq2=`b=;PLBqqS z|LB?2ABG0vc;HNM3`4`6XHx%NXjpY7IEJ7h&uw}2nlq_C3=PC_*}LGNf6+H9cbp~O zIpq9EKQi5C$l;@KO=NtJPorK;$4kjva9veU#xZ33Cf;zqNp(idH)2j0XWWjMk_V=M zHpGa?*eZ7=&Y3X@+pJhy+)bupgy*ZcvzUpC032h{BE`6F9)(1OLvA7a2IM+38aBg@ObKvNfv{*9QTKWXE zLHLVH%pB@9XrG7gdD0Hh&T+2czV5GJo0+!TDbTTbln3!)zbtt-?2f5xU@P!W0O>k0 z3|$eN!E&xE1ihwR%!PH{`{q35xCbvUb6YN_ZyAjQb}^vs7od%8Mae(fiY|8Jq=A2( zpe+g?*>h*SpT03=o&GMdb&fGiU&FVm`@2c1zuCvpuz9xvagb=E5VG70omh|em@7Uo z*I$QUZ^B%ENoB05pnUshDdPmzA@r^0!Y0qjcZ3)CSNqC8HHSXQzN&+B{Qva{_5O1y zXlLA#mydTE&6ytBfsY#R2wfoYm88R4A6tlcPyJ4ZqJ`^rDZ?I&y>?G)>yo+tbGj|= zJq#SjJdmY;Fa{ zNP&zIykGu0&Rulg9E_<7;HxN?_s$DyY&)>RvIEc=u>;U=%D_V%bA|z59rniZWi#kE zbTGD-`Y*l(V(DIbNzJ?7InWVnPNt5y$lJSK&+q40^KwNFSmZrzU@I)xg*jl6x68mT zv|umK0gJrt2KI6bwlW7S@*Xg-l@@Gm4p`)EHn6o8?A9Ex$XjP%w_32D&jE|PRR;F+ z7A)RV$dWJe>J01?7VP#Mu*kd8z;3r-Kb->>d6ya3Pg}5l4p`*PH?Y11dtDA#V7F~vdnL&pVe>3dlU5q?%5P?PH)KPxWf85 z9?ENZm22ozhuvLR>&EGa6W(bE`)?sHZLI2jkC*bCx1+1neggc{WOS9A?18Tv>~plH z?^kiJ3TsJucc!!mb0pHG#rpTtYQF_GVr;Z1tYU*FgyUEPV9(9k#~Q{?ESLcMrfnYA z>z5!M*p9g^ul@`8kok&s2sSjj(P@_Sjrw=J{%z8~A9L_tVts!EG}T^?e#i5o8Tz+e z{c?|N&N)u}Ih57ndHo@$na}H1so&eDIC0{rEe;8;+6f`m<`kq`k&pKxE3PZ@Yb!&t zCSP<-2zMN?O~fr1pX=9N7o-8___ZrE+>Q7J-srbAtqtmTQH7#w(N>-R2;R8`TeU~{Mamk|Z6;hrfZXV_K8XEf(x#Q+D;HbmZ&_UxjupRMz z&~9ej{6fHy#?rMRp|!LjBx|h0&^M3zremZ{nsc0a*MZNnzk>Av#zC^7tflUUB-vh_Tp{Rhz&*P^EF*Tmgn*+)qNNAFG^&*P3`9yPe=C@oble&pYqj9y6%X;=R%%& zM`Ww^hYtXjdePB+V^`v7NAAUFG51tF4L!j*XPLRDf@%0{!Mzns^`=YsGJC^z?FFufM_ z&Ak&$uSfe;R{f1=?+Po;dpG{dN;iYP8Y_K2@YP!BcF1Fim3|iGS6gY^)8X7_rCr>+ zvD8ZEEm9D@&9Cumi59Bw+9K%Tug4mT4|A`Fvpxl9 z?)8Y>n95s^by0=WhW-A?hMq^A!UE$n57Yga3lI*(T01Qf<0; zC(OWHpMqh0Z$OtD$_e8FW~jg0a>=U|@@l=I%fop}NB1^QUQ^`%m@?ejBIeCoQc;P=W&&h?m8n~;|aj(;N3Xm2c-*nW=t9n5`Y zSv+1b&p$tno^k2)pxqN|HII7D#eOg}MB&dqbyf~L6-J+gug4$bplI6#_IG5qpQ}#mc(lJft^NP4+dn@gqhv7ugaIF3e!49@4Sy?7 zx8slRWgpVxk$E28?Ovh}C{jkBi%Gn=E z;Z4n#)#EVkm!;b&*pxIo1-oVJ)Og?s^cHKJU*`vUo0386SkPK`dY)-}t+W4lF1Rq@ z!gZ(5F>vdh{jaCsQZ#lKLpQI>qS3Z{>)_|oE*ZOb0(b&C4>`@|9;RpjJtYM1XY#iNVK>M|-jR|gZJL%$>%((l6V>}o;hjQue z80hY`xXbV6uD{{@X2wi!Hf&;%i}&a%lZ4%5!@8lYF`2j&u$L;>TLIe)`iQ$7ve+}u zJz5K0N8ign>k}wz${~ZqrV!qhs)}P?zdJGF>8T#x_ZNG^wJmvtja{erB9A>6@wrAx z{3NeA-~lltvygWM+NWK-Ay*r>p^e+BVC$4EEC{vKMR30+@4jHa*O>b^LAzHJi^Eo4 zNL+uX`Js*EIV0|X3-+Uz=7?Atqgn&ccSc}zdsjUji9UXz0StHn)qY5L+dIh z=@mJrwqZ~D`TUtNtw5597{ zj=AWAuPk$FWfk^fA}4!|e+3^U5WZJaEQq)zr~^V-Ruq zne%mG7Hq>T+;Inf!lx>mUmor3DgrGsZrKjTlkDkW9Hseu7rfuE+luoX?PuSbi}ppJ zW09df)Vwkm%%y<2RKsAOE{m6oQGT&5$Nt?C@=w`Yz8lWhHc;0ppex?DpPovc8(a`l zduj_%S9CkF;h63xW0QEdRUgXTqR5UcxlDpwCMmg?I}F1(#~hE?682RB^<)nX?eP5Y zY|v%!y6rjSJP!EARVKSZ=VIWPoJ$s^;I%ZR|5-E@A~vv)G)={v%DtbJU3*$@>feMu z>nY7^PLy5&za3-vC(1r^kI3YGx={J@0gb(RKI=XM9M7YEFgE9NFB|<1KYm-@&eR%r zYgKcf;E!x*(>}D|0&Ed3-NKlkIbNbE@&tG9OxHm$6c11cF-)egJ#g4HWv0>=syaY%{b;SWMuB+3w(`4VF>ST zrux^&IT5}~(TlziT0sMC+)%U@QqF+onXAyszR|SKg`9_^^MZ@~wV>0C*>fo~-DVVW zHu6h^hn8QDJ%-TtMt)f|S@Ii}rjK9Z$1-GhT`t*;fb2$CvIE^*TlZRaTlSdU0-48o z&L7O7&5>aL;Df+z_CcdzbGD3iDtJ-n+^cxby;Gla@3hakjgC{+_BnT&F7z+-M`{_D zT5a)Op0W(x`#;j&!4LXxKdAaNjP?cx5j*ia6(f-NU8T$$=1gpFp0%ET7Iyu2TT|x= z>(|rP!&c&bF6dsnJ*Q>DGM)kLBnD#=6AK^f1*P+=`^(^6NB=f?4u z`-{J&{Nk*+_b1@xCzbKUuUz<}>37>Eeg!%FDwa(A)=AEiv6fMO9OcJVdCzZS$?4sQ z4bDR>z@bA^C=k8R))U-f4(z6@Fm%Yy3Y=2dnP=#7u)qB&iq~tWBee) zFUOd{Z}Ql#`J*hTKONfc*)lhC_(;f{I3j?P`328&K^yO-o&!0tKRBPC7tAwRb9t(d ze)b{%r3did4(=Qd`XbU2KlaYnxai(%i~QyU;_N|}!?{(_mx?iiPW(phOon_IBUYK; z)Nc0gKo4SllMS%d<(E1B1JL1vddy|@*K_EL=PKj9&!6QdR)({E%rBw*OO;qlg+UH! z!M)DVk!gqAU0*isgZIN4zmYNQ*!(hMCqa+t!xpVK0UY|w^tI^&&RrXel|43XW{t5| z5DWea^j7yfxKkmWy}wc z>ap^u($5Oo6xjUl>iHq@GREDbu(h~ruJ6IvKXIJaX3SmG7XvqvchUjZNo~^##6Q73 z`#L7f=*wL6@f`S0+UFBJk+u06$6o|J`4wbMT_rA=BS7a*Fh?w69%W$oT8uTTr!LVgH5 z?=?IFm+%Z8j(}$~X8BtH7_9@z#5aR+LincPZ2Zi-TIw1xJ{tcm?EgD-g}6i~+25>t zrIYj)JEzv+I{+uIl(qiOCG!_$t@X3U(*}%}4H!=c^8Lht{DnQ=MC>-k^is6(A7~>B zz7g<^fPWhBPp9Ck0sm?)_?3WP3HbYnKh$jSUkv#Fl?#3u;Fke@CE&lBf}accf5`=Z z72vM|`~tu)b>jwqDd7Jx7ko9~s{ua_@K>hb#{qs%3O-q(&nFX4p^u(IoWk)u@Qb(s zEuRs9H{-P?tjFuq)Jdg_ojH8#lPG7OWsWJXOXye6!I;wPk<@r{^85|=JG;g~Z~i71 zeUF2_$3fpSpl^4IzBdk}=t~&-c7r}WR?JPUOVPE(t1kNnWy8XHEx&-fo=vwnD%KNj?wamu+p%YNU7Ht&lKeDuWN z?%v;p{hmR*N2_(=VYJCR?Xv1@MxD*z>lwh`o8oH=;PIu}@ut2D-(W5B%v#RSVSf4E z^I`4NkQaUzC4z6F^lU=kZ?fJ!!*h15Hs+La-iM{)Pz$qSwF~Az9^!8WYb+guY`4$* zL-F3I%>8V?uL$jLaG)FT%Pv*FwCT8yD_GAaszKid`1FoiQ}CI7VB%sYDSL{rXI`=A zGtIVeH$(D7HFRzfVW5}UYqQk2cyfgQ?8g~{T+-EH(bY}5Zqszlwdk4$y23ZhJeF7h zx^A=R!n4pdJA*Eyg|4}vYXRt*2fAjzJ6#WIx*oFV`aJ1s)O1a==qhDw(8|+2vz&oM zqeT;*g{DavG$AcCO^YRaX2k|hl!B&7iYEHjW%DTN{ET&FrSXlho|E`}8cCXqRzniF)v- z@6na#h^)t6AaB%h=5g)0Z8gR-p3U0RT31T^Jn2t7uX%Ysofi|wAMo;giWkQ5GhgEP zQIE6@8^^C<*w!yWKliXQ*I_fa>p8l^^N;^4#xrzN_~~BVh1f8k@t3DJeXHXjz6XZ* zO@6o7iQ?}<{4xDG1UuY?-y`^Y7#r;|{4&1{e-02a?-Ib=fj`0!o`3w-^b!2=H!U75 zJo4zf#hpovSvWoZ?14hw*E|j9t}D~x&VDTWwJWpZ&QKps!ym!;n&+tRF_}2Cd5|sQ z&RR@d8PkY6i%rtL8qxU++H8gXaA_mo(UxU-n~o)XiDJ9EtUlbBwN z`im@lh(n9n<%mOr@Kfy}4(*_wUWM|QRgSncd>lFjzZURz8gXeY=UL^9OEceBB0Y#p z3%;+!G~&_@n(r+!jkvUyc~*VIrNzwmmstKR>YF$(rWu#E!h%O!+QAF0G~&{FYo~)TFbH&J`=arX34PD^Jv_+C`J*qmDw=YYe0zWz>Be1w6UkOM9ZIQW8`dk46; z$aZnYocaBa&eqg-p?+uJ5Ob9U7Y@D$#rU&Nv8@Q$%?ONY)I%MFmubfR^>ibRKFmRXWk{{ss9Vf`|D+X?BE_@TvA1esg z{EUHnBnMm=aELV_+-C@fISBJFVzO17jP%brcrONfXSMKimSBA#-zh`9NoVVF*26sy zTJC^z+}J={>$uZV_;wwQ!?+=V1HB8Q(Aze-*j-8w>vG()k0N;;&fqH&*jk zH#C2!)7e<3`MXZ|E3)~s%G+9tE&l4ZDE`K3{;tcxUorT*F5s_1_cQP6&5}jy7|d(e z5_Z4r>7zfKRXO0ofJ6KS;U*Zp$?<)%z7c%iqB2RnDKzb_&Bm7qJb=l> z^9jv=+BeVUI`MK_?`z=)yNEsD9uB{GhH}!7n2UKX*Ei38fOdZ%?KW>R@m6|j=;t13|x5*xNg98D>%gWs5$7I9B>B! zcR;~?$iOlFf-)HANX*JQ?DL%*r(;$SEA3^(tYnUB?xpp86Ki4avtukW)*}n%8-V!+ z+SM>)bHO|hnCB78s$uBoXW{uO#^_hox2xD!MHUZPGJX#Do)cc1!v=0j4w-xja9>g~ z!2(ao4lx{A_?`jWGYX&d>((6o`ZQpk7MSEO4X#|@aeE4IPbpkKGjO@SA-5ZFyR9~J zeM9bXz&x&CUNX40=b-ITz&)yH6Z);#5AIu22j2C&Y&(EshlRt>(at9T^9comHB@#V zwxSPPr4O+$ka6DiAj%$8W$fQ43_nlgXy-n(bDwHwhk^Ti4!C;(cdvrmYT$6zpVhyc z0k>J;n(r03)Ou^EGv`{|b;dL98h)$7dY7B)H|`;1?xV=L;jTiSqaLZkne(zO>dbj1 z+T$M7;2YWoy^+42UZTGtEB*E?@V=2+PowX4BsM^98^oT`rUmEEYxEh{hYUYBe@U1# zPSO}rXPl6W^2><>``THuxecCU zQ-!eyn)Df!8=SMRlrt)k9nPqJ^i6jc`a|L@H63EdvuIw4HdZQH0=WDfbMW*qI7uf z-)nl}S@on#ely!9sZUSe0E@hm-&yn{*mF}=K+3RI{XsA zx1rD89)Z2g>v7-c_2@fmU!S~jU65r@XG2eBi%&aX`UZPn>U$cvXEO_a7T{+oAK1W4 zTbXB>!_9;^2*a9>=~?FtqD(&I`B#$-_DyznOC+*2r&{pO#poBUMKV z{ZIZi;uwL4cf&41`<-YHzj3^OAO9fyI+hU+_Y4v<)pz9#dmjt8F82Qkm#o3RGRdIovV8QYFL%n7IF>NM}-!TxJM+p3sR1zI8}1N*M| zPva>u(qECm6L}e7^D?DMVyaxs?QK`NN2}1MFLhx*-r}{xQSSn>{8w$}TpIKqziG=S zUBvM+-v3Yq_S)5cvR6z#)ib~EPCDnBI1t#DjCv=pGIL%SWt=b4WPo&WrVLi5$>7sw zj>{#3TZ{bhS_b6(Fz5d8>VD|v3)EB2vvMYe{uaG8e2ZLGLf;^lM)&ALkW1@OazXjm zj9gl8>Z1N&eUikzPiSjZf5dHhtZ(qQ|4F{K4@WEdtM6k<2TAMaL96QXRsC|FwE((@ zJt_13C0h@Ml>zYnz{2|p;0^j0eD(n^`Ru{BghRL^t9A%JS?+5-X}i73*s0dx`1x6p z|8=X~^=udQ5)a}YNX$EZ55}55iFZc$jnxRgZCP<>&dG{$=M?2MEI;Ver!Bn8w48|Z z1aR&E&L#I3LMP|!z*;+rb+(e5o}s$`$35D`ooo zZwxV}0Dqa5DfJI$_Nl(1%`Vb$2U@q~?s1I&caGtGBmMpkbtFo=^u8+j?y-CW^mmTW zvCQ{!Jd(eY6jz4Ye0d!u!ZyM0^ zffPMhKQ+@8yw|#vSy0F3|2V#JWB4EQ9{JB3?T@hd z|K?EqqmAb^|M;Fy+>Cqi0Wc^AH@g|Q!PzxWV0{&nv{0HNg*uG15G47qt(`(B>SLhSO;%_l7 z4|pa1SmUQJ0=pHTgEbh(tcfRzMquCgUPe*I82;2~|2O}@_nTMC{hh2IMSZT}Fy6&S z3uMWCFw8ehi+w1fe|9y#?;XzmwiNCdYllxeSju;taR*!_{4xDrAMX$Pd+52yMVCQG zg8SfjPvNmv$KUXN_-)#Du|2t)r`SpIt|s*y7Tl$kPJA?HHfRAPjF#CGw{&=WZekbll!BvXGK3= z@F9=i+@Y;fY5KXw*MmIhSED}H1X51F8foG;ZICbGHQ({+n}&W7zCb5@?>@bkLfL@M zQ(SYKyWkR|0UJ_&HRat4d4^!;j&FAS^Ko}ii+(SZ-)iSQ7Q!#_bL~FOiSvF!;x+yc z#xrHnv|YE!db3f_?ib3a#>fbClimWzMD-Q=#4RX{;;tUXJCQHpCnygGx@P2uwnZmc zAAI9ok8qqZBmq9^DDp@pV4BY^beDIPeG%_H2z?y)&_&`>cMMwJYrs0JX9R4^2>1&a6Tv-YR=!uP z^%G|rn7_xSV6yKimA;2vfgT0+06xc&@(X1BwX^EYbNxA+8S7Qrb(}JR9t{b*bGBcq zVP7L`7$#b*E;Wms7u4_d%38%-Shq*Rb@6wi`JsBhDCnH-A;{vvJxuiK}g7;SH z`|Ue4qso6u@$y2{f9Gz+%RbO&#_6$Y_)8e4SDa2Cr(Xh0&?d(zXz1ZNFX*+$_eB}? zK4W-?pT)70`R#WjmyZ0D4+);J?#JD!Vp}37Gxqa#I%ijKKW``Z^JY%j%6Cq7Hh!+c z@A$g$^OUU3oY;f$bNA=1viTM*D6@UAn6}sCE3NM*&+(tr^12l~aUUn3U9UZRT8C)| zW%k@ZTsyvQhx=TVx#{;_doF=48Jiy1!GTa*_IV&Tu~S>!BXqDsqwZESw66=P z@6$`#txA2{1n|t`_v&9-&KO>dQ#T}YPU!^w8_~Z-A!$e1M!bjghtJoY7)X6zfwDY} zcvb%9y@fGPT<`_tw^;v9(7(7hka)!A;@&{PiF*ST?l9iJsqg=Xp26L;fkWO)o3Xdl zi?IbeF@SH*VE;(@ObNZVrrlv4{GQ~a;FGeFyfE@k-T#CCT81?d%3(WFb@kj$*aYAr z`OYbfLC%9OFb{XS4VZTNP>%0Ep8hY46_%ylo!?3ul#lPLxqcgc7QL55xiD51V+=N$ z>vZ^Oi~~ox@dtPpl3v%r4_S@%dyKX_$#OaptxR81y z{-32E7+>;^p!6Sbpg(-#<=!fMwIuwnB==AnwZ8FvH0B$)j^nFTybWkJI82@DKMpQu z9$`9;mu|twkwi}@bB-OZNzB~07cdx`@@{Q3A7hy7kcg9%`2+VzSMeU{s|)-Kn=lsw z7xA_ouir9o-(PhOcK>;O!gm2*{#AOPwBSs@aU#;k^1Q}+KB%5E_rz(p#P3>MmGnj^ z+al>&q~UX~*L`T;Yfhi3LdtR1XK-c+djcHLO?m$cJ|W})S;IHlru{of<9=wqQ+!DG zZx3M3!@fD@stZLfz)d)OS1x%4>>}-CFVdBGX1V!;uB-71AA#T42z)!xa1mg|=Ua@q z1NBR5)!Y%-;RwbG>}@C#i{o8}U1i1>1FW3kT~@66tfkoh&RyzUB~AA&-w!@v>f1hH zj)`#RK(`}fLcTGBwUx|4*Qj}nGU_n?ZWuDta*kMbg77ZkbUDTc#zSOB7~}9(_=*qj z8s(q&zttS)fJdGWi!A_LFV@WT0U80<2)Lyd9AzgsfxE`?;lu~Ic9i1z_r?Av!885O z1%My4){3Nqw%GK!u|M#k;ss~n8!Gn~Jms!mk9$*KXCYVPH%CKi?Lqrw!vYuXui)Ls zRXD?|?_UC0M4RVe9~x^2$_3*&s{4+#!v|4)4w`<3J|{1ZmXiy3@(tU*vvJIa{E4`m zhU>NT`P;rboZlTCfxfcrS8GXE&ohqC`_5hP5CTtscwWuTT)T?wu7Uqz_aD+8<|u97 zHn_SUvER@YHETsY3!i{B?<^iN>l^UkA)ntpIos-=Z6;0&`TTwoZ7SoXh!=a{qEkjk zLg1Z#A@u`yrtf?h{7(nnyw{jAKdk)_K7&@QWt=47c(?kid=}YaeIs(Go}x|Wal8!N zcV*{bI26nqJ&*(Sn*N~Rf~;)3+9#2_n9bac@wHsqz?h?~`p}jsV+=iGlcZiGX0J2l z+f*LQ0Pmr!5A}`wKzCfz9VZSx_sqjs#MnECcMd>vs(--`zXL9|8$6M2+H3TWveEa9 z^?&nEsdpGC>ogmu-`O;FQu-S2j;e3dVm<);DS3xf`8dDP&tnkl!MSfV-b0qT8$8IK z7V?T<2bouZZv`NxWoO0uag1r%>8%*&FTq?_SiJqSdr`gw@gqzZAT2mx7fE|(>x};S zp#OZ#H@^vw*?T_bo8N>-?>)Z=?>NKXeJfnF_q+*s*KP`8b!RxqXt|k>#`@2LSISG~ zX~xrH?(W8TO6zOdxI(o?@;LXxo_n?WekIuB0_fS2uZ_rxRiod*bsN81RimF7SGG+* zbAQ9b{x@OhhnabW>u$4d#yP5-0rNNWy^+j3*co}JgugNU$FpSfhwp!p53%>#^qAtF z9q%F)ox>VO_`^8xzK1;~jNg;cH{q|LFgJgw&ogu370&^$cn)~QbHFQ}g;)HFo|b~w zR;8zgSMq6iH9V1rnEuOrX4=T&OzZtW0Y8+yd9SOHH~Ze(h&zwoXRQU$|K8_SUMFlL z_bEhwv>Zi$hLK~YU&C)%(0=iocbtzN{uA%uh901AJIvgN@=laz#8vDpZyCqAaA(!O zjq~f<)mY&j+G##OcY16A{V294-_}BV^eaqz+pP8|gEZT7-gwp4J>&f=hHA^UWw2wi zhO5S01s!4=X0BR-aZUcXrW zCY29a7@L!p4?CSRAGSDWKJ0wXeAxXU-_jTI%I_!O+X->Rfbctk+>ea^6#Lda;4uOI zJnb{t<(MbceeSFSn3>SCMtiRt^BnhPjEvIfacfUA!%yWo#xd-PbAEK;^SrtgzC(u1 z2X4}1^lkG#_}Q5II4?(CN9N~_!KZomN3-M=;d~o=`T zIzO5LKS$@U%gCqyMtV9j^69^c3^MR@|DE|Y8Ts^wn146}59b-?Co=Lm&(N;myBKl# zg>0w;(xwNV=Ij2T?AJRBC4Zx{Q2HC+@c0P&oAn&{4gBSrEurU1!qBGm0){$Ze6>>e z7OGBa9c=8H3!JpMVSM}Y3fR$ye>mP>4_zUAx=yD2an4OqJ=ZY~>@NIm!yoh8@YjVu z=JD?c{y?9^crnh)!QW*3F%RqM^nD5LcfnSQJzPs)9s6k79~FO)I^R&G>?O)WSaXDN zR}^DXLx8~=YhNQ^{>y>^8ETCMoa>C;M;lmU?JIvx z)>u2Mu*RCdk+EVexWlrv3v`d?`lkl%W1r8jT^mBoowDH(;K5i)7NWhA+ux!Pj*D}u|6284C7GvM!BpNG2RUy{{}uzz^@ls0VnrDxTfPe z&50;_yo`MK<-_v%&K)T}|Iv~Sai@I~1b8~&(+~1G{|!YcJx$7|W{nUT`(oxG>H$+w-PqzA)yq$`-~J3SY1RS!JM8%3v3=%Fs85 z^?XF#NkGPO518hax>*6;i=Z!zFEz)-nj>G%;!}G6_IQ7@r4O{Drmaj}5L#f5ME7ywqtvwj1ZGb3qICqPLoL?ot)6?wa)O*uoC`Top9`nmj1Dre1T` z5#Y9+rF=5Msm{P;e%!`)grGyPLHm}p7iG*w#| zxrS>nz`Ts-bvpkro;&pOxAC0N&)*`9hChJkZTk5|JbU^XAEOx`)zANoXO80+@N0NH zIUJ9L$_Lm+9x+DwXN>#thxPMnJbUnY$lFRhZ`041H!=69{1tdk=;t~- zM>Wh+!szF#@qAc6*W$TGKmQe;*XieKJd@8#{0g7ApU-_aKH7Nmv{!~=w^Ne(zex8iy4*ksaW>mw|XQ7Y9x?Hy( z)-d#^68f3zcJj$}C&#?~$9$&k{U!P(X5G!Tcnp7#r}!)A2M2u@tljCed>nsm`fnS4 zcj1qD|9{0Zm}8B>wE|;rJU_3A_bapA z?Y~iZ?3;+iW1r^>JuMc_&LWkEbz(qw~{RE$KN{q z@$6V&(Z89nx1g+Emtzkedv&VMgZ|~2fbR2-jCPix-nFLgXw-$?9W=T!8ugyQH?WL8 zF|Bnjq4NyAmBaxZp&n4*GHG0ha@e>O4Bp+zgt-9aF807}BSp53xX5XBgZkBW|8UKJgXohv2*c=^(~a zo?$;IXVS~_3Fx1Rk*forh-Fm#v5af(;Oqirq%jdjoircQl5cp#(bJoz;(L43a7J|& z&J#-{UZtaYTGxTtiwXPl!yz`Jv8 zjfe+m#2I?vcjL}#z?r=Qtc!P+uN$rQKtEUPZ&=T>$C9qDfcA7ci9d)3#B)^f5yS%u z?bf%r%tt}=^H8((8tOC7$+72sQ^W5f-< zJ->60zJ~9%w}sWW%OLL{e#eH{F;&5cjKVi`turwL;He$yTcAr-(4|?tAG%|rp9gwg zMxE(eKlfJOAaNQJp8?(*KvxxbH++oE;6t6Or^}0VK48_!M;+30pmF*ZrCZa*{&Y0n z9O%g$eZQBy`__POgBO_CPmYC~`7U4co(1mFTc<%kt5`@xfYMS1EeN(&-YH}wQ(xuvTVG6Y~n*I=JJN|{#DPV z$9||Wa&x~2S=NlyXBgm-u@#+^AJ1mZJ9s!}J*@TArj5P@jZ_rECi<%e?tDf1v5t|A*MOUbA&{XpMSlE@Buq#z<mnR^GBhHjRXSnv%>zavH$3B$Yf&aq%{w_eNHRvNmBFEWZOaR)WlI@aBF zOyjP*7UNGdjl1rsvlV8&gFJIL-67mLXJkV?+*24jx^go61K$yB#kU<%&+M0}ep4`` zI4=N(bqROax*L`{M%%d+-=&c|93l6_O8S@AcO?#RZ**na`>k@WalLvcC5pcEPEC;S z6%%*wfmpm}Wh{C8`dG3G{mprV^T(xV|5NBc(q!7(d;I#edE{&Vk(xucntSj-7yGE) zUX#FYV_Q$+{mBEkBTmK$be8&7k&kfzAGpni@1EGj{fIyw)uE$Ta1KPi$OGR*%q5S@ zZFww(JOG#Y(h%~vDnlMfi#)yrc`SuIu1c53JLt0-@(7wCPsn&8&Wq`Xq5t(aOl(=< z82p+-84IL!9>62GbuYl{0_czB{mx8XLCB;U88LN z@6Eygz5n;~zt`sf;vx87kikFF!vDqKf5FiFdzt)iP4R!C!`;Pw>I1Fg`#Y*{qMqyb zWm4m?)uwIU5VXzBpbcrEZ60WwI|OZCoapyH>F(NR^r;VHxxs0=M%zwXzi+W=m^}my zvodHvT43XJuyCAn!emT$$t?v?a(wu03U^Y^5_S2Pk;?oa|La>na7OY zcXqGnqHQ^($4Lj$9jz0vj-1fNH7d*35f{GEziUpN@x)-VXn+ z4f#?xoZCK4uw^FaoUl)ehOkeF=S~}2NE3JOBG@OKAs(NUvQLPKu6t#Yvuh&C?LK<0 zbvbP9a>V+q=qkW_0DS&3o@)VLasS9^-r|ZKls)d3NMa3`j7FT~Wk1Kb$Czvf?93W9 zPUmR6GJl;69er-1#AB!!8r)~exOLhc_)BWeoQ?4bn?;$?j#$x!9x7|8d;4dpIq)Fv)nKf>;QIsT!PMCp z=L*!Ti~hlBCZ06>|329d1Ha)RMb8Df>G7ue@9a*|<01Z)a;gM9|8CLqInX2WKzsZa zanx%Od^UaN{*f%2-kR$Fht*&$TJ1K-GyL2kaZaD^zcd8SFIYJ51WvA@ z44n!6ez8e&E;M7^^hwmBZ-<3zrKZow)|N*iq`u8e90xz8){V|DFdiwd8?he2Z*;9r zKcds?b-F>PH#!PV_9iCC-UIg-1?R35&Xlj9zFQj5@r%?up{&EU@$HB>)=qC%{9=Y5 zrN8#Q8HkOYc(;dGSYs>G^ylgs{!ed3JU@69+JRHr>(#XCwMMz|3)lwyE(L?Jif^_? z0UOW+U0IiRIHfCk{bKr6+7Q2IqI_F+o9m=t(Kh?1SK9(<1Nc05#QUSQDrPi;&m$F| znM^*9c=@Hmrwcy60ekiq{D6Qa?c22LxkzYmtC~^o!T{!x820$IuLB;ve3a|?Q{cCw zT%YGlx)SB~H)@|ix$%`)e=*AS{++;o2IWC~(CYr}xC>ym(NoA{UEaZz96;M)%cilu z3qOayA;^fo;r6iqIOdHtdY!q?<`=YO)rX&uR{v1gZ?)>T>H3t1k%@ybIdwYcChncy z)Rpiod1)P}=oB9u?{nY8`EtYe^qCC%DNWCu694tTS32#XPRH?aTS$*5cvM~K?@s*< zQZ6tpi;~ULI{2<}R#fmIry% z-@GHKzNKG;^Q;Zlc%lqg?~tYUHQL^fF*>5_y==imHH?|l$}!%{KVI&?gE(=-a7(FH-^Au0oCIo8*_La69dQG;WN7G3eg06k#cTMq+ zg08bbm)4CVdVkpcsh6Jw|&bgjsl zct*_-n|2}j&uTAkmVZ%3d!Nf_?`NpTcO4Dx!)Im7sa)@S1#-fiy+BvG!sJzYyi{4_+|5u+D{wzaS4fpOR#xSb*A>j!+(-AW7%A?<@msn5QdYNE6E53~` z=Vib{m_CeS=mT~>Kx2Q9sV7<>dCv>g63ranF#`qh+FLHTy7<@<0@xQO}@mzHj{)pp6$RTFg z<}{tW;#~ibu0wdrh4zc@(TJWv_YP<1UNLl!aQ1gn2JTylZ=~FW_p3&zcb2O8&XR{S z)lk|ywd7%&c^?etg-PI%v&$)nyVmo346#H`&s4t>zvV}!`M1E2s2Ukde))$uQ(%0< z6bG`v88+%*{?Kzyz1pX2iE?lANY(G7{tob^cq#3AL-Qu}W?($qZ5^4e+FCP1?p=Az zw1anz4E%8IG+FI1){L?tpY4c~?+DM3cd8KUhq;=xgO49`A5fh~dG?-f1U_E(YMHOw zwZ0nqzY3fZ7l`sAj5Arw0-kpw?nPT{k8`cOD}{B#T&(@(VC@$za+2lTzcq5Xtit~} zbc$!;pA|Ym6XZc!|JI_bra;*>y%tYW-?{EK@gF9?_c-SFQpgE(VNWS8JObZl;Od#? zNW8DHU8bxTYu!gtuH>X-LOdTGst#nvIuGeOPN?P8__H|2#`+nt9;y4=!P8ps#Jslf z&o6V_mdlOIdyyCUk-VF$=b{XKxpj^|*r47OU2e&R_5KKb!1&2sFFMyhrR)6_>X9eY zXH^Cd=)VCtJm-q0=K}jwFa70(+GL%V)<a{+~gj| zzlXfy{r8QsK7%a+-oyG%7UJZ+eWZu?x3s_P$Q_(=4;=38Lp#ewE+`k+q1qYm`Zwuz zmRaqXds^Cnw||G`|2WU9VwMk$_rK|T7@EKA`d4aPG2q&Um{Z(g+NI{5bb5Qc)9+q+ zFZ7B7Dd3>07pi6y1URz&F<-ut#0T z@GE-pR>=Ri?{Y0beOi^8Z+KsUq08sT1MbDuu(xRY7}q+`$94MqY0~%5o2dTIW2WBpKA(QqPK%xsObn-~ zZ}g!D@DCgL&cj@SwxZB|?jdI4ray1ruhXV+=Nc~te;exjt;SFJ^AGRsD%==Dyzi59 z#E^aZTG;;w$c3_a+Nu}4;|E!EjL`QQ(dWk9x(RLb7#~I4JG8#gwxRq~p_P_*{bp1N zTxu3=LE8ehBc(y|8+$4(w6mDq-lrx*${D9DkGF!}z;Rx4Q=In(_A` z$WYoSe-~cM|2$ro=r*f!@Y++Y#`(8wUP(s|UI{zG=vLvokKOZhyXT(N^8D$#{shz)zh{VX{@s^ykMj|17ky`sYv|98Ono|O>yKpvsB1&%)>nqI zS)a=He^Z|t_g7Y_asMXzxGjuWEzS#;u2BZYzR-59(fz>J->XIx??y*&$*J-W!yNq#tH&3#@dzx9*BxC!jf zx&H@r{3{vuiS*GPWztBSHfjj^2>%gHpRr$=^GFEim6$`0G-3`}Ai4!VJ$y6Q-@!VA zHvLGY>RZPDa*n}y3G4&la2_^@yO4<&-y&(I{y~>EEHSagv+!;s;^#7LNe|A?@{R29 z?BTq&53sP`%?YMy3#E+=nWOBT?ONt`z5Lwu%r}p7wf~27JaK71A3i7XQm@cH&-nOF zPsu}Ej==C;O$%m{$Yf|b$?F^C*joWE$Ka>k0e+UfX39)Ex=dt>I*i4koQ;gJZ&A$q zr@x5U95d&xL;tWpWS#D!Z_p3C`$+oxIPWW}#T`=GAGPCY5p&D?HTE1Y*)oXue$2Ja zlvQGcZf_p@bhY&9?Rq~bF+%qjWA@S4GmU*{6}z^te9Rd7jr*!DxYU2ZcXu&n+0+r* z(T?x}+>%C{Qcgb6F2B1vaGw=Vi?tfp0*w1T2H4|s0gtgySd3kzd!wO0#0PqA*M5s> zvv01-Z`Wgr`MhhY5OfJ0X?kZ;n?$ev% zCihg&=qfF8lg^CFq&KCKcgHpF`GIqECGN}Z=!SoV7(w`DVtcrDGjOT+K-@uvJ{14| zbiP{O*PP`)zFO^_TrnE*_^$Y4sm6_508Am*uMef#K^PGxa|=!mqaK9|+Ir z3TVLoIPJRk64pjPcjX&fbNJ5H(MZ<2NJfSc@Lqv2dIJ8e#v|()^FCvmJTLM5MUZFD zC?!jQ#~lHXo!nJ66z|{qy_Vh2BK~-bcJ`r*zTPv-J?dgS!x!&@o$QKER&zdSEX_y% zMDPth?GKC0Q3vY+=`(YW6z^1v0uFc4B`Z)?fqhDE{rXEloA?jHFUsFU`|=FD-2XE5 zq62E|N;*G<$E&P38M5@w8(_P!h3oX$4d)oC!+hS~1UymHmuIxWyV*Ei_-Aml%+N{v z-!lFMco4m&J{G5~EBBS(A?wN`RaX@Ff4$S?+0l^rB4!>r6MWZ>^lt$^q0Pt@w$jiC zIr{W-?E6A9b^Dh8*8MxZ$p2iMo@Y$k7EZ3g?p>tipM;(!;q&Qz3h7t$kJ$&3KB9gg z?@y>h`Ef6?&gh=Oi*ak#5>f{^S%)@+Iug1+_SiU!rU=RlP_~3RQaNV_zVoq=`jxBQ z9^J0U2KAy5*eczZhQ0`Jl}qefWv~y>_rt;6EN|<9$1&kI3$m~MT*DogjY{6|+J`gUR_{e!$;x_vo`{!e47T zf1k?W?=bkH9sT-ypSUxnz!~$-VisE;Txy%_N~#HH{3V-Ba5~(UVH7eN7#OIAI%02Z^3smt{gZsWIOXcgfn`P zy)o3R<6TVnk&J`-)l7W0!Hu$iIt{-K@yx#6{60HAb92W>HuE>{J8FJrU7m$!$4HB3 z^YHNF9-e(2pR!T5KI604*7w&^)mmSduWr;Dia4NxxVd{0t&Q$zpW2<_^+$I*8jo((^SreX&+dih;<1+c z3$y6{%8+Qz>)kK;oj31G(0=Wa8QLFy2(;hi>O=d#+!NvVR?z+{miFJZ{f*~LWpei< zPtMFQM*F8Sv|kd_epG9U=Xtc}*%>kIFUX?(KX|mizMr(8c2tJ;-?g-h$F8tXCu`o+ zx%$xlzPFI}b1dySj~&Z9BjX#Ay9W>N1K&TMq5Z*Kj_*gdrg)x5d!GIJRLA!VvuJ;U zNBfEWr2URb8QPzB2(<5T^`U*uTS)uo*xQrL*Im;_DwBOJ9ZNcad->-G`q5WQ4|E-WYjh6Pe z=hD72x%;Z)`at`KGPJLaX@5j(isyN>=UGKe`}4AB|0$35OZrLsvSTu|zx@zsKh4#L z_G{ll+8^W)+EP5vqdm`dyxa2S;JUVTp5JVg zM|;k8XZY6H*d_RWQ&oocvk!sxJ6wHeU-=f&{@>W|l+5|5?XT0d9i4;2p6Wi(eq)CA zO^)_|OthtVo=1D0H8|S;u{MkL57WMrInDi~ecd}UwEw9+OWzlnlhBy}*6quq`s*8@ z{SR#YzlF@H(7FF;pJ9C+Hs)oP_Mge6{pP`8OJ8XJ)eP;AcC`O3wC8yq?Rhr9(f+sD zw7d;LzmtvHO%o?fY9YwEu{s{gcq1=Xtc}*?S!ApUkHH29Nel z`Lv&v<9EoS{qi}M_Ir*9AF=1ovt&;GUQ$;5wXXiE5#cxe`p)lATeE+&jSVod%+Q2< zkXbf)N9UmMR+Hx_+Sgr?@_Yzuyt~HaD{^r0D{Qeb6Gp~Su9|oLo^Fe~`_isyjqNug zL-Q;-wr4~*o$)LPix?^5e&;$HP~+^@$NHYm9$||1wH`m`^qSk94`u&P?0kBJG39;U znDT7*DRw?Rl0Bx=yfHnzpJTfA)XbRH`D3E}Vy)SF8PiR!K4W^KU*FNbz?kZsqxdGC z1DgkhM|xwrv&b4Zre9+|{Wd!KeG~feK97DpTjS{W&20KTWAjgG%>JFl%%{XWodt*a0HI{f+ zTkFy96aA!LU2TSboBaOwk^h#v`q1xozkYw{S2-vgHZ-IEdZpi0`SeRT`h5}l@jj1! zJli|R&fhO))9*x&ev|u2ziDS?=(o`Ce;?^r=jubhI=_B@=+`+ge5bcR+AIB*< zr>*?E4*KyvkA6H09sRD$re6p7t(+bGAN-EzUmxag+1VNTmHGYeBmJhi`q1w+@)0<> zAM2hz$-jZ&-+TL$z0&WJeEKbO^t%%J@jj1!Jgar|yE2=8w|n%vv7hwoSdgLLKl%Od zBmK(GvGt+fCcl1v_^)AL_&aYOtylV;pHIILj(&@vAMf+%$Fu$Kvg5lbn|^g3{kTi4 zU;MY@eHr>K_xs;R`gOSa&~Kq%zd!V=92lPJ`PzD=--3MlJ^o`mf6s<~yw9T_&o(;x zot;g;*T_@l=I{UTyFc@H)43V?jr9B9NBZq>^`T#xU%x-}>l_gFcs}}G=~tUizm<-D zbD$sZ^XSL3^Bw)>WYcexN53!kLcc&~+M=~AXS7C#YZo>xO!BM&n|=pp;A8n!gnqg8 zH@W)I@1Oko{h{CH0pYQpzp+>P&CRD@g`?kb(2w_d^y68=(eJoy`YrV6cSb+yxBQ|E z{XXUQzmN1=>*_Bn6W{+c|Oe$y_s^h=EjpCQLXf9G$Vs}KElc=hA8 zS!Xi*?wAa3&G*;a6@6T9Q|=Jf+q>j9gtuO;W4-->&)fBOF08(+x2fayzpDmvF42wE zAA`0O@AAfqXK$QjY57Oa?Rx(5v+Y=&WXI{?Z-F6Rm95#!SZ!L88LKNjTE}q#Icx3Q zvEJe8Gggao>l1H()pgO`0~=jV(~J+Kk#jV0-Vx37czo|5?+$jiWN-ywmpC z=;9H?RNHe%`aflS&@;-e;ZyiGbQUX>IK||SFt90~{%v%R@{Kn{bTqyao>x&j3Hw&lD$#5h*r)QFB&X#uN70=&N#7EEtY;*2leD;`sl`~a>w})Kp%HNPT z<~(b3V@{5Cf6RZx*zMCo$c*_u@*nhfes;L}jQKCU`tkTxCc`ma zY(_D<#J-dAY`R?F=<+0V;awhGcsAS7<;iTi+-&Kx($b}`G%5Q?h9(bqed_BxnC9w3 zle@h7F--r*8C=C?s%R{ zlf69K;%M^CY?}OuGqK|P-|B2E^QW(Tvi74HdQ9;8(^q zk8`u>akJ>L0ebK}j~+bxu%pL@YbTz6ecto<|d&O?5Q+Vm3`yTAD2BCy$g}lcC4$UVr+^Bhy@c z=&{zTAJd~V5nk*0wtA(9%~kCD`v3bR^tcXs@H~$mJbV5`JBHU~)8lwckE0xq%;`Ii z)UC|WA> z`XN`3%cjRWMUS(g2ha29!L#9x9%pCML+2NzXWrjCJ+k^!wkku9HC})EN{?x-KJ-}W z)sN}X8H9ceXRrJ*C7T}meh5A0Ko6eh(Sv6{o@IG*PBuMs=Y{B@^Q5dLvitmZrqAme zT2kSe;B0Jan`2ZuTDX&Mz?=h4Vz=L4zqoZ8_wUxRCObP3oqx{cTbgWgFE^8m>tOP* z@WA!8s0Om<=c< z#uVU9AcySf~tNG6X=5g=f|M4J3BBIw%2!g{-41%e%Ne+Bc z5S)23@7_hbbHMkMAh?ao$?hTf9v*^7& zYl$4M4fa=!^zQ0@Xl&kDYLicZdYd)`yTijdul~=APq8@#8kIxsX2vuw^Yvi&?UZTW z{NJa1P2cV8jkmK#a=DK6n>yD~r-d>;oKN|1l1sYproP~R%zNIkISBue=X);L-q>0K zzV4VyUqGG$;8c-6LU2Ch!?_~}|3z?)BWG0!IA;D*#)mWChtm{Tc9QR1ltfzx)U!8rq0`IuIUc*!aJM!wiJN=r-=}|wW zbrX5!I!AG*pY8undv{e!{Zi$iSeYJ5pT?74f%~fL-M#D2*D+VvJVP0LMeG8+%?j+a1MZk&aDIRh3 zWb9Eb+!0*ecY3})J3Mi9qBK2kJ1MNDOi6ma&&lCf%9Nz%s&|ElQ>G+6 zSIr3rQl=z5FFYmu^G%6@^j!N!hMqOhQ@nlP`V3zid4k-~y}X~}!@LQ8z$eY8)H`yu z>{h-^bI&(DNF53KP6EU4qoNSlLZEIvVUL@@W-G%p{w^OFCj4!qum8kYZ{&6XLe zyC+h^o;r&BBoVx`$fq`HHSs@Jbt5C%y3UQ}_%aI%6C(0I6e;Iq81oBwL7QZ(`E7Ch zxy`$wXDh4>qwgL}-6zZaI={$n|8m3uCFS11QN&3Rc2x8Z^Rj|KjWW|N2 zhn?>ejJhpxTggG(lX)cfWRB&Y%zF%F!k6Rm~6%SkBw z@q1_AA*^Q=Jj3VQW&3W*)kb#@K|3RtMc+t=O>P}4e;IuYE@7XJwl;MJyOZRKyg!-P z{p>L5--*~Tm$mM6x`VRXXGYFP`a}QE$2Y5-OO#U{VREcQ`Hn2^saf1}#q(<5OXezumi%oozAB&Cf5WpEy%XIa7-t1Nsk2Pk7&p@| zVC+#Dqqirw{?fv5v^9K@q^|74x#)tVkzL!)nKe33b~&7?YJ;9CwRJjp*}JiH*N@5X zrkqf=zx%*zel2>C+$#&H!~B>VBpN2qKb>dfxmrMdoh=p*sy?`kXaSz?gZ)SFjN3ce zwl_<37-#JM7V-kP_UiohPPXk)NA0C11*3w*^2zgO**1X@w+Rf>CNQOMZ}Ho#wrw7x zKH7WC>KA3&^z&iaG2Ll%!EpzIgA;ItQ|fd}EA}PK_|Q&_7wtr} z8q=yAU1#`sjj(tPBPZ7*R<=H(oSfvlf**RtYXostK3@FizQk|=a1)7|N2k_sBi?h% zZk#{N;zc_SuQcrluQcrnuW>$J11(<6pM&>Vyza~3wYE2U4Xo+8+Q*Ck1~1^oc-=pB zIJhmDkAL3KjJ9IjXv^S6+a2JxU$S^G<(QLQ?}g^fq4e3{_C<@^7c;n(6~HadJ^0?5 zo~0JAG{4oZ;01}A1EQ1spynB{V_bl3aG|Z=fXjdQxXiP-oC+@2SX{2@BQEo5dQNk= z@Y}QtJd4Yc^r`k4uwz_+ZE&G2;qsu5%WR9w3~)Ku;&N^VmmTh&Pw41mX-t>dH9ZGE zWBn4m@8bV-_-G$6vAx^6mIfwHP4d^T^O~zed5v$EaG-qpQgr;K;OcT)%&>g{x8Ma< z@yM=W;J$ZhhDSRtt$DN-eyv~}f^o|xr~Nus)=A#szmI4@A9q57kNPyIv^1Ci4Q5&z z%*@cB%-uO(hz6B4J^$|dBO37E^nG4n@)uUCe}aDr^z-RJxoxf?SjA!U5VP7N94O zCq97x(uKaBRyp~l4qU$opVSArCty&#J|2w^>UHc_Y?ray3n@lsCw)T*->j0P{4U$-z0w<$sRBk-x%6vv=cn?TIsRF0?@&=&4t}ijc@~t{^!(?wR{p3A z|AWN##+2^Rwlt`6{!Wz_y=ZUMJMe{C`?1>LLERMgf^ZQ(2@mmN3wZqsUUaxt(_dg3 z`_Sy$Sh%teQ;kzDkWKmY4D3HWM{lOkp_GqoL=T5W;NWaT#>LRn(O$fePEr>ev1L+h zBd$MZxad#zs^fY_=`j|xf9#FN)wzA{Cv*?79S_z8 zCyBn2UwSV*3_Qwp)uTVaV;^uG9^|==WCHE{7Cg3icyyf_^*KEUJg&5OTfaS;z_$Pp0sQ51P|dUpNiw5u1bsN z6!4s5@to5~JS%H@j&ykPTl4(qFvqD8^@`{5q~bpQJB-8K?InnqStvYr4+xPHDxLZ~W^jE4`xp0jHJmm& zto$eX$9%z0t^GoyUtIm|w*Ju`t>z~p`tPB>KKNuS7o>>1s_S7CHFZCY(6Z3Cnd|$hsVP8%4%gDacJ#Ee|qs&zUqBzRfR^!<% z<jz8WPu0H3LhJs#!D_MmK6QZ<=kzOR(|LkYVJr?lMfgjiae07o;!Cb!+k4RWtLF}y`VA? zA943o6Zfo8HhqoV_qj&?-eBeNLo7~B^aY>gjzf(Jso%?uia7YY!sSplNQ%|cCW8gtp`UFqrt8nY(km3`*g(^}c!XYZ?A zZRfx0oaWx;%2dW8%@~?}F=Wm<$78_PvwghFQOuSO%BH zqFu1^DK}o&T4tZ0=ZdQ@G;R+5aNAGWs#}434t2QK>g$>-n{3})S*Hut*9_e=`;EE# zUwg3uWJB#m7nd=A&WG07`(WC4AH+Twu{rF6wKOqDjNW9-_^mPH9*GSaD~(0kj)f@) zJyzJY=k4^tmB(i1E-%W{mz3n1*4~3Nc^|PK*9V^)9qyIRP%hlNY)sYbqr=~?i}bCj z`(f(pF7tS-qWQZs_@w1Y{*S3^Y-yj=D!N28niSCm+&8u_ZrzQ4&E0E=FJr&63uS{E zokAJpYTIb)>zU?Umu;_0|AU*KF|v0GdQj^j%IkhH)zN=b#_A``|Iz31(YPS9ne$7# zt4|kSlwaLo$8kRIOy7_RU6h$FI}3dR?_I5O%UxfoE4iUE)s*4gQ2jRY1D}}sn__Iz z{5I|3-!k_1ahW|<$s#vS>nz`#$cd_K4P3(B&n! zM;QIHlzZ%8j zWZ8BFc=KZBA7>RJp0)SS=JDCXN5*`%_Fl_pRb#`89G|JbR*saayUEq<9vi;LuZxZ5 z-)CD2Mu&sZIxalf!9cEd>CRi`y4E%GZEjREM?BoizF~2HdVF}St?TAnlKHl$$h`ci z@M1` zd6D&ypl@wLgGLC3`Mh~L5;dJwyh zjGUK|N3(eDMn$t(}ywXE3oJIdQE?WJ;Ir z;N~t?)^qyam|W6bLw~q zX~u}P%og5B4@{pN%}c@48YO}6se`!F|9J!6Mou$cv-aA#>>JjLK&2eag-korU*l zBf|&L#ln-dzM+k4N8e=wYZ`n0>)-}#0&{=+H2U#g(aT$Rs$9R?>>e3@nKreq&|IqG z9=9=!p~K(x@d2-o{ynz%L|zS69Vh*{8HDe-PEoV-EZx`zX^ubB~bJbx@+^8{= zuF+b;zHi%^45G87(Rht;_JEPU#EfYUtoH2-55JUr+k(xQ3O0U{3k_WEpcfqJ>_UC| zsn)!-*F`ziTjOM?<)fkC8m-ffd<;zWN5C95=-&fs2}<|gbhjXgTa&_7Xw%+}rM8GMY-ME+{ zqu%opv=wZ8O+8!cxv!jcR2MRF2KSqmd$jXoKD^Sxd&S+G z{$tCoE3^JamFK_Yi+dOE^IZ^xAH)`Pyu}=CbH4P>h9JBIUEK^^@v~{S9QuLdV?0wG z_YnfU4 z1D8K5Uqdx>6PbOEeD9QL+k=lSj*qo<6&GvjWAmzhI>|RUBJ;3!V;C<$~r*4a%D~_?B+TZ^Jt?keq^yo7~;OycEx^^ZZCU8)5isd`*x4 z+|7%<;3N9z{!o<*C^z$8B0FFBV>cQ(YWgjlnCm40|r}- zteJe7?D0+RoNu4pYWfMTsY%&=(wtD+2kB2sJ2KPtiE@AXUXea&ETcZfvZ!D9KzB#q zmKi_2nfT;N|n);!nO z#+oR{*Oop1b;hNGIbzl{*zTGqT6b)$U)n0ZPxE%VWqfSX1HsP7wuDcNo?+i5ZEZ=> zaT;>3#>E%{f2VEB?7zzF9Ykgm2zaI*W53`CkQ;ma0R*kT04a(@ufa53EuGaUeuRN6NJo&3Q zlem3&S!K#tr|VmM{m*~Q+{@)+Pb9l`+O_?dYGU1X~(7DzD+pFpQzBO3dU z`FxW21bA)Q*V7p-+3*H_IW_`y;CZv|aX7^7@Xoc9ZO3@`po>S)acS9twV9mdz4HE> zM2G4UbihV@)9B#Z=?fj;jYka4Elv8&8@W2e+P>2Ll5Nbv{plw&eqiXnEx2~3d|BHn zl*=N$M!u|V4LfIsBawl^!HsEE@?yiU;uoEpee_$beXMU}g|&G(-XE1ep1mT)n?g~Gmn$;CeCnf7Dxf#t;Kcx!ujKCA{u0mnP=6ZG;IY9X}bmmX}?eglU zs>%6p;m;@DNIEGCKL4GJ*aAGW7djI=LBE4-Beg$i_C%roCJSe$<(dDa9kYMhOSvZ~ zC%o;sePo*WgZ&BDUOn=vUTeYvJRZ!Ad3@96)e(<>Zf;<<@zR>ys7>k;zF5| z&&>^k7W@K~laG(_GcgfqOUE0i>(AG9gCm~}vC5_$;#4m*V`ST{vi}vQC_YKlvKHfA z2W@_Lb>dFhXNG^IL-6&w{>8GLeSlxC$d(a~enzL@{}uiYW+&}Dr~Q{1QA}UKGMzz) zoqDIr7+hzV@ih8J<>i-cn2K%2bLpZQ+h=o@S^b3GS^eaHseXQjepb7FqRX@v&Fd%Y z%74x2=X}d21}EmW-^csZN7kw3z|DJ4|Hi6+yf^);%aJa~CoM5e|HYNAVklp_>B@^GlT_k3nXe`ukzbx(CD&O%w=GQsDc(=KO zbvph<=SSY5xW(Tc6@K(|@@Lw4Hkm#eIYhe}3qwm!-aL9a&Xvy|d#_$+X^V($vq)&BoU!ODa^r)lh7+VRg2Tnb$GysBLDH22ua_h7l+G#A|y`I!u^zPL74Ar)C&L4EhXQ=929J*-4xHF#k zH*8K^;mZ7)ab+Zr%y{#kXN?bebcB}-9Ti8nk2>=yQ_h(u#uwgTk6UN4pr1X9HCOV) zKa2G|G<=q4g0FL5y`IJL$JOHObY(N=uMU31>dNS>RwKzp3Z5-8XSKjHI;+JRzMiu% z;JL3JpO3o>=_Ytn`+YY>XJNK@cy^si|ArwC=ipbp((0Kjv1b@>vs%KFc4Itg*Wd{rIl6`lmXSI}X>o63E`}`n)NM)J-?z#K^KJTu;!FDM5 z={`#jneXHC z=^z|0IPlrB5^zk;I?Vy-EZ!7-vU1kd2jM$_Q;fcvUy9wkq(mFjgeztIHnMWoRR-Zj zCEC!whhnimP@)a3CDO)^k?BXqM)LOuvvby63~zrD{tuWF`d!6O{C7bspZWHgp67nn z^X_#%f3rEUdvftP0q<8C-d}vmQ6*?{3pB~){hN8_&#kGzDKsZev~%K!67c&nCr+|+ z;;<5M`Z6cZ6dd@y6r8@yi3e9m-}rYPd@`3;gBWY@d<^3kMHN3CEy!gri_)D z27Z=&M^9`N9OlI45^xMJXY_=DlO^99g79JBl;manH}{li!|*a?d|b2Sdwmf8cZoI( zFQXsA5^We>&gc-+kG{zFBP6@6JlF4&#LIj)^DUXL--SMs{W`aPDDu5eygcjVlDxdF zJBydw3i0wolu-`ei%QUqeJVc(uYq%w$EV`=M}Xt;vMF=9Uk2M|2W4d2%rDW_1=LAX z#`1xI^8pWzY`JHEqrT+w@+*Q5pPo?yehx1i__@5CD8XmOR)J4vmuO>}`jFve(?%{Y zPcPAiX``>ath@?oK5rE-Ydu;>E|X6=BbRIEmE`3E#2R>V+4R@v!A;2J zzo<+`E}Jr0JP4l-E5N7nr#gG413n$6G9`GhqbUeySzddlL=NOy@j*sz8hms{(zPXC zt_6;GIhO}7=Xr1PbVrG{`@(~_lxV~8U~7ps4wVOYA`>M~oB8OsHV^h_+&=D)Cp@^AGLok^mZ00^)M?p#?ZH$I?c}L}Q{%&dmv2;C89p^-=J;h;2X0VX z*t}PiXiNLc=_#w7y7?`UdrMVcF7U`fb5W1H^A7_@tvg2&b0d zgQI{af5Cs3$b&zEGM>M{^ye@S5AosxzYTb?FMJ}umy=!kEk4n=WY-VuZ~f2xNZ-DX z=bZH@d~Pk0O+Bnz_BY%8nJT*%_HW=_h)?Dp>G4ToYDw93ym)|hO^~RZtbK1}>7$Zg z_xm(~S4_Fhi%&_JytmV`%6`=^yE)kXZozC?yeb#wKltSy40fNXaysi~^227syxA{H zT->FUZB8!!e(+qyjXs`#=a+jn*!^jhYrjn8miXoH!^HZvqdf?}Y|0h(>wTEAdnVKz zNChAH27UO34`+!FXLAt#dkHwQSviMd;Y`bd^FAL=QxMK8!Lzl3Gm0FnHOnXaxX5O8 zHbX~45Pr4ltW(PyO{~cgx{EzmYYu^2P3E1NWdno5J%7RxDchw#UrY@U& znBBLFpNG-&2P_Y-vpme&+tkhN+W?+Ndyu|=Ewle>d^8pl z@OhqRQ~7@iA3b-U6wlA&!#oNMuY32SDQoO9>>!Ogh_ zH=YMXbJ@f3STN^Ixp>aSV{gh{>z8HDEf!2O=dxjb)Gx=JyHe%iIhPGnzB1Ro=E#kd z-8(yTM#u7=Y5zjM>^}$LT`D^>J5Q@$K6g#_9m>c0K1ZLQ4(vVRcXHkOFtT(C{Qm0_ zFy0{;;&*Z=`!ICA#Pw19zRcufw{n0nP<(;^eq+x2Bfa+>7X)Dk@0sH!*Q?)7u1Xd2p&%STOKNjyTSFvyTQqua$9?#FuDVmvB!^$9hm2(H^*fz5Vo`~XQ96d}Kbo4tJ zyEw)bx)-KLCPq*6fagkn{4yumvid%h+_uOKnQ+lrHul)%H@wBgA{;^-#pk`f|J*o= z|1f+U=}~RUlU4S4U=I zCFX;l;ekVll^`G>j^*erhGIHx%BCw7L-9S8u`w-uj-gmKG*6DJoxbFu?Mn>BFPG%U zQ2f}->B~CcB=O+?l^BZeSbS~1+s5w{!1ZwOeY;~Q?sRmuF%(}Zg6G>EL-A3E=gcUE z;_r&#$@{l6hT=mGPa8wAycnKua}31^4o@3H@t$IMz6miD8^;unq4=78_m;;{{2$EW zjt|7FxBd9RdK*7@1a`uq#1Aelr1#L#+wIx{`^Cf}UrwxGJ@UxK;uX_#%X^D=Lw{Yf z*pt=#Cq}1nyO&S7kS-kO@xh5spGg-IUnX26+xwD#z0&r#zj^4tW^q;?`jOr^DE83h zaKChP@4E9hDr0pg{sA+dE_T!GrzWHQ)Ru{!jX3MrL)M*tZ4UQ#=<4)zuW^IcR_bq# z_TLjvx5aDcuZ{cr?PZp~tj?O_@s_g#q+1K>EcnUB{WTh!^=}yW_o&0u>Z}RH@GPXW zgy#$srxxM)H;nuHw!_ovtYk4f3+XK38O8lYc>WFJ{+b+~R%iV-RX8qHvFhcDPxRyd zgl81@7vZVc6UC(#iTitfRB@g4vVC``I_u_S5a^?IslMg+bkA;sDc$efZ{6AXJfA~Z zqmhRyZ;ke5-ak@EcQskvwd}PwQFpP<&eC1S1S>D6Z}pyh>CgQm7h0Z@+^=_fhZyR= zM*lr_X`cRT`>4mOh4kOW9#2&`Jf#1KTkenk%hO$-nQZPK`PRtZb=Mql=%?=5b`JR& zQfz}SXnasH+qVXZDL-@iq&$JHBfk5P?;oM>Hs-y}=>MGiN7}tH?^SnM{F_EXm! zVwZ(S6tf=T;pr~jgCd`(qkWfR$Q4_U4mp(jMgH<3%fm)@ZEyTm5qg>XMTDn`S>N8+ zHN)Z=>8=RRzoG7m@wB?@8^!P}q`O4VNOwhe{tb24PaQq2?rJKAXCd7sJR{u|;n|Ds zI*YlkGdOv227WlhzWZx*m+lsEy2s2cU3$DA4^447=CcJIB>z_SY-K*{@weFH^D59IR z?$Um9tP^@WZ`F%#YP=+~?&_~@y3WU=H{DbU5A@L@hlkcp{m?zqk#FXCsih7Nt9xd8 zbIrFYh~kIdC#y5~Oo?of5lndlL% zne?rXbdSD2hCXu73VpxM`+Kx*A~wR$d*yNvnOw=pOyw?2D(3~dIV;!D|3P2jIi9R^ zdt~n3?18^OG@V64SR*T(+%!6i^Uhi8t+QBfy@@*O%NOUZm3msa=?1kB?H| z9P2FB{Qc2cJ)TVJ&zkXNi?eiA+QN{}*66I2lgxVSyy3m;tY4{&^%efi!f~{ZeT5a= z_c+eeS+ytq?Q|COv+J!MrcBluW8L?-*`wE?>8#b!eU7wab(U$zUr$MA-QubUJ@SBdMU!gTQ5mxo#o>p9fBQ?->UE# z-%`30J#@FjLpllB-WBO2lRJC5@QBt!5gy)pNO)BGc*wUVJXn_$Ji}WG5A@Jy9UfZm z2oK|{Tis^P=n9W$y%XW#t#^cncvCiw%Q;ZaJTfu>eEj`yl`D2n;sEr9bcu9>eoL3= zTe{?P#>X~@JATJ<$L~1q_#H(4vdP3eO(Nz=_jQm9#N-9XrYF`Rj(-@7Pf_s?eB$^A zJtMb^Z2vB|=b~pN@<{v%nbu6ajdEV=jzzZ?`G=P?a=pdIKC~psp=9&xxSU8X|3Vr# z4%gK2l0p2;e_N0#kv`X9aWL0yJY0-JIZRb36WS&e@`z^@`eoNC)-H+AV{1o+> zyMW!^M@#b3=+0QmV_(fRv6M|8>K0#Zp|0XI#S1OemCv^YSdwSN!I2wDeIIZ7(UKhB z{aE|BR#Ue9;`pB2X^w79m)N^$$D4LC@tr(ZThx!+qP}ShcrVk|4X&-^xTvkBvGi$d z)K>kXxUCM?mK`JK8){Bo-2K%LMzXAh-?DqR0E_-MM*Ur6`#Uy+18}4Mj&0Svxy<3v zbfoR?k@R+u#5!;gE?-<+-87kr_PNFS4{4)2h4X z-|g^7jE(}k86qcb?vUubDD+R$RW z#UZ_vyg2Z1`cmZBcWo|$?{eM`J~ufiij2per8PZgSsc>*R-d`sUTbdQu!KA7qi4W% zJdp;j#v@HT8jo)AB>b1Yz~XQ&IBc*uY{=kHY&i@&f#2oG%`RYpLmZFG8TSYe zV8?g>+u%W48V}hX29L8X9`)csz7EX;>1IcZqIjHL(=*ZG!Eb{Hurhc|`$oFn;sNX! z4`3TSXiIoJ?C@ZnYQ|(Xcr3MeEY09iXY<E`_1b!?>2aK4Bt}D)O{~? z-|O|+vk|iTd~U?!d*AEz*)Qw&nSPi))2|=XXT@PVoC@imBjb6^yqI9=f^Be+yl#eu zI*aS(ri(?GV0n)6;yGd^`Is2%^)ANxCrnpgI$690UNJ9&m+2>X{+xcQywTyz@4bhyCPv2i`qaE{U&7r87juX6BJOY=6yM?e zQ<9d-HhGmosR2O%p9Ffgg8$cIn{@L`|9>|y`qpoKx_P%68>W|7?M7_2$QS8iA4h@v z$-&AR|G&TP)B6R%%4L=|G#|&CXPw<5wpwe@7l?Ix{9q(K(A-Q+A#9 zo1x@iV;nW6%ynzW5T8pMpJv=5J7!AjY#+a&mVS;`h~E|cYCV3GT`ZXNrH6Z6Bi_aC zBj=jYD?4JnLXLB6F{fkqjN*>;3#|;}x0#>7()`ptkH$s^W>v!G$&@WAokAPwnC~L| z>xDl!I9iDY8iyzsUnYKUQ&Sdoef#k|>TY9WxO{+146$|Hrj_Yl2jB^W* z-QIr~j05X{HnmNB$%X1$pW3$d;QL%2K8dnfKXyEC#;c!j;_*rx(s*UHZ^o>j?Z;!5IHWP7{fFZIo3T&y zZ`|Bmsi;}`;34oU`^A0F2d+8h=v`5h88^|bzwJA^RrDk0wc5|r%cdJ}`qlqK$v5xG z80322^VIuv>u){V->#dY`!M?@lWg6zmrvWl>6dJCPiYTu zbpO?#Z9CG_F|6Urk!kOr8(QPmQwN3uhr4bbomw+>vd*)Si~P}Aepm227`JS)@%bep zdpz5g$((&Ec8<&8*H`*{pagx+FF~JU`bnRM`#~SAS7Q3yKXtgy>m3q}+6(W4iN1zs z82degYaV6%&HAR$-4%l@-dX!({pC$$l^d7X{)KOTf4;|?@Qr`p!)w3w&cZp~grCHl z%59M1W6tE2V|z2l_9R&cipMP9kr?fPV4|R|c}lSH>}yoaHxuVV=b?mwM*s?A8B@=%?R*xIfo@DCfS_B zl+)hqA`3U}4{HnIvEAXNHOExlgHV>|C!>r4aQ7+$!mVdN| zb}H>@ZBqqaRpp$o^L@RPmme-ZcOY06zLPbE28{Rhb{tI~`LFgiDDSfFAfRtm?hGC< z49#foPbt>sw%_9&9@J$lGJA=h-}qOou^g_|^cR@qMVQ<=#2X8IY4Q5<1Hd=<4TCPj zOnI}$G|x0{;P4BTvHO7X2^#z@FNu$g&s_U}6Jnn^xjGA+8K7TT=k0R+*_M`NcI~;3 z^7EllIk|AnxZykBk|ftKecwu5_07n3&zCK~xpFB8N3~^q(DW;PHtXCk+I8+1S?Aie zGCtgkS(k60TkeeqJbjYjn{#mTX@f`P(`KI#KcZRd0@vY@1}^j%k)|E_Pfcu##iMIp zMBg<2KJE#Q*4x+Q<6&rP`6re+^J;o_oM+eE{FYzaz*F4isTL35#&`hN;6XdW!^E~Y zJZ4)wW`f5ei^n1l50}%J@{W&VJn$PfJ3ROey&8YaorsQqeR>%mqwrLF3HA|ZT0Cht z#*=mpp5UR}w(s}Gt?M|8XC-+0KF6GKD@d>7YI?rl@Z`7gQ3#%V6qOba;Kq1(K0wiH zhK~n6JIxE-VVdRRb9j`Z7e1OR93K2;zPJ5-F?#Xd;HmZ!>@(sQG5kflF`ma+dL8HG z0%n|?toZ%lNLEnZ@U3WL-U)yEE{<*CT@}xL86jSe_9M^7=Xc(ggG~cspWhWYOB7eB zI7$81ex$w?SNVOO9jy26U1=i!Lj9E1P2^zMTtB(h-M`n;G^ty$EV?(WoV$0MnCPtIJJX&F);Bbd3E%kg!40}|Mm{*doOyr3k>M-6-!lrl z7_XKfcvv({;}@&4cO~fgPW#-%@$moijD;(g^^STs+IN}@Svj)7PkN@zp8u9F(%t#s zY;*0ewm@^i)_d{LzB%Z*#_2p?((UkLkJQ|2BVC=s1|}Dgk)yIhy1>EJ(Y-+`OS`w~ zj$!kkHbhr3e2LvvUk%#SZ~uN_@$=);RxkX}J>mi5 z@9a)oRMRt$zQ_O1ujx6J|HeNkI2S=yVU2}RJIw-oo$=qE5uc*A}{3U2#UH+r5sa^D&;bEVaz8xhWf95m+imd z*}YR%FC?!Ae(BY>cQPlBppWF(XwzMCrabtTsy~48E~iNr58Xc@JPaO+`wbpf&}YHa zos{u&;4g8{nQ!JjxT}x)7&)ELJc;C7?%eR_&P1=gyYDldtlGN5yF+GUlDzGVz2GK+ zJBs^!*yAyKF?v?cGqtf#Z|$KAZ} zRqmfXq6~dlHt%N#ht}*qm`v_w{k4nr5dEQ@rpeuV76m=%?hD#F-wQu1;+>H( zMT6z}e;fOqR2Y+AUPXARFy48Qyl zEB~XqjVa=BHrhEeU-I~DbUyvFup5CLzh7tHPx0Tg_Hp$!4^&@#5Z7ldl>2@d@AuF@ z_+(eb4@QQYbU)8Ylft!?!JS?2MF-rsy3Nu2;3GlXJk}4Qx%;HCf74Bt7SL#C!rs-T zKCwR0-l*(hbk0etv!^`>PyK-HH}eeI^#})pBlXiWf#sJc578J`ekSiJFF0x0zt$(U zz^)V2kFNVDWACpw`o-_pfXU(eiu9{o>mp#vo>!l%Zy54*=Hsoh)6MzZVC^&9x%Rcx zPp*A7J%?v=%y@_C+0lE|Q~9ph=KCclThsbKu*Q^gcz0oE?xTF%#&N(nj<#)GCpYy> z@J&71bMNc>(cdGA^!Fzk3+S~Mxc99mn#0bwLSv4+AFY0Lsn6&r#weN-$Jh0A0Yi5Z zcFY7;XIW@;+YH{%pghl1{zq1)^*TQHOb%a|7ThU5dq8cTnrYL}7y26+&wK~&)$n&) zn(^jc8~=wgFIVof^GAFD-^S$(4Jntdw|YnQ>TBA{ske{uP}%ClkgM^Rv~6<&EvxdlO?~Wjx>)JaG8Wm{oWWPORPCwe~hF;n7pdkq7xc0EG3$-`SWkKW zPYsS@K8F97$uHNM8WPE77w^(icDdnWvmY0VQWUEeY{SIx3cBby$OkMMTOdawe*#Gf3#sGY!0}>~g_62t}`7VmK^V6#E zIor;iemlTuDVuL#n069%T8BL>JOoqE55}dNm(;XvBu{2?>gt8RAtxQYXvTY<9p|{* z;;39D<(~J-o$S-jv~fg!8y}A9)>o}w_!F=0vAJzr6_snCT)S6pVon=X$#HpY1RIIh z+CFWv`chxHdg1?g^$*KwCwL%Jwt=$GdSw%NZB5N@>)V<7?bP>i-9ISe6Gyk;p-kCM z%C>rK{f4qJe?z;LL{(l}16D>fX~(XA(yROPyt)~_cWn>os%bRzV9b8z)!ms_H{w0< zcU%`9RNV&ZjwIKoURxfioI`qq>`^>yObV^6IY3ulspBzSJG$ z;k-1j?)v;Pwfxou8M&&DLoGw`E?P9~HoDeqvV^oz>O~Z_Yky>lj>-QS+1C znZ9hPZEPuvbc}HCN(N!erHS2D_~u%g_#PPa)J|W$aO~gXqqDN*{>>j+^+57N-D;&6t)1?C%GkkY;Vx0m^6`lcxtG=Xqnfg0bu{>l)}Nn&7)Dh1>FvTbdkke7N54SGl1{ z$+~M@-POm3Yy7%>pvfjz7n*#k7)^#oGHFn{=)f7h7tfAlsOG|H-duP9TF4JAd8_^LW_aSO-(^2^ zPJrx%KSpHsQ{4absGvvw`xg1$k2xXKf7x5)UGI5`y~Ok={3FcQeaWF)r(=rSRvm@Y==~@CEuXV|?%t4J?mnKiRWU&K3{ix9%^DpLj6d1&s3#0mkzljAMX- zkEY*vyyU?c4UCzG07Lne-JDDUWAY)u=<@J*tt=Ql>=0mddocC_Y+1 zL;KGCg>j?@<1t|T@(^G&dN95N4E8e2+;+U~_%eXsH-4LWepAq9awAl5_R9M5`ipm$ z*JenY6^DTLJ)Uj08W;vA^is3ueYGUcWCm#D4$MgHfk`3#Z(E^UU8D%kB3UynZX@q`%|$3lE11a5(J{ zU?4N&xy*fqqZNPEUp)Tk!8ph~*8Nfag)xY`7@bUc1sLT9Mv!IWuKl9XtLqzDQsKm< z*2YDLMEd8b)+^9II;*_G#{8_ccqr#VqU-u+Upt_E_=(u2mvyt&{+@VFcxLIi^|QjM zjLT2JLB8O1HlEAqh+*ta*?bDB_Z|=D$0@HpRa5R{#hona)*c=4R?pP27Le~gH6RF6 zJvZHMeA>ez-K%|mU_LBdTpR8zX#5O6OjRO^-B(|3;T&a(eKFPqBj7o7?}XNr>g!#Z zeOJLdK6)3!0sk%Smn!DrR)fP`i5}A?@KX*xc&F~F?MdBG6X8jjxIWL#+6g#XJ0?}!n_|*#WUfo&(J@?6B@^qTZ7R*`8Wng>qZ0j-rAlOgCl-8 zc%5tvVzlPiJ>ctV+FYDS&YnW1U-M54@1S4O$7YXOIS;A_#%E&1%fclMEb(fZHcYuS zoWrIa#XUy-!xr(!L3CCeC-uI>n43LI#*T4i{mC8b_a=H2_iyT|EYD3@cpxr2D^u3d zMBn1y7RF2Q^Y1Y8f_xguOLON%rjN{v57EcLZtUQhorhVTq@MQ7#eZGwSu?j9WJ1ea_&t5j_k#b!I8aa&a5lmwgl{76o75&5p!Rv-j9pd>)HG1 zL`V*Zwmr1FmU;Yj_QeYI>qkBeovnu!s-yN3wLz%5w^7&h+rBrrY5eKC#>3BF|5%0} zdenYio8a|r+oswPo@(RMw6V~ErHhpMU&Vz;Q-JieZV0#q*e0M+sX+HEbXyK!~ z=bq=k?y%BbwZG%DjacXwHtK)J=L8nG3R2VO1j;HW!nOPsj1%;p&(YK|-@J3r-p=o% z!T+Eihmd5hB;nCv>>F5K*~5Q5!>7hMo?u(ug;T;e#z(QK#O{r@#^+`Nb;o}7J>7H0=FE$#lb-A`Bi za0M{S_$YSbd%FL#ehM*$oFgQ*!qk;*#Q$8|XfOUi#a?`ioD9wNOW}h$c);S|(*`({ zHE|l9^g(SYR^w~5rMQn6@A~W*WD|GH{DTLr-M6%Rjk%w6O6#>orx7pAd&MHUb6`7< zboz~V2kJPtvb4KedKTNK*5-3iS>Z6{KpAp+Y4;TDI#b`+fKfl!K#RTjXf$s-@U@ut zW^PCC1-D}VP!q?MIwII#6VGYI&=Rxn#{A-`VWS&EMY-F5WG*t4l@TwQx> z70;MHEc}3NZ=!1to5AUyX5jp;-rDfMPI>fFym~dZ?bgaAt8T^aIp>C<6NnQVx)<3e zS{wPNIzC=^1iRNdymDxmh1V6s!YYf`8;*WHUcmX8!>fHUKK;y?SGf59&B1Q@&Vw*kye{2%yz`etxz8ikV&u03c%g>3!B7UBl%_A!7 z^Yat7KX-sv%+KKF&Nvv{StDIgiYGgR-O|m5Cv)1%8hdzhi*4^ZM+blGfwR($eG_Ld zYHRk_7n@JtuL!?lVO=3uly7O6xXRGN=Vfpo0&e?;20hi-BwHIUTXie;xp=zb@#(iZ ze(oSv&eZjIdT(b?kcL@(f}gLoc+?f>(;i@)X8V+8pDAn1-F=40S$yj~2Zt~S-qW_1#fvzDwT|6J< zu*t-uAFLlt%-#fI_9l|Aaj^Qj9y?SvtdaLR3$>B4+mxKxy18jW_x*|q>m0v|J;POx zu@CrI(>NpJAFChN`dD%-XO=Fb{AH`2_@-j{;1hUge&XV250n39e2zA8dE4sloE9FY z{v{{1p3MG@DUS|8Pe*zvuY6?~*z(nsS6iwh+wu0#AKb9r*^c(P`XHZuRl@k{*H^f9 zuMNUi#zyUq_1bMAx1hthWq{Rhz%sIwZ|UWY?@eUMc-o9?%mQt0)Onex&GmJo6X9;# z=AZBj$L-iPU^8&9sf%R(I_5-6@+fdwg#VsBLhw4)&Z8_`n#!`~c7JgBj>YBYg>V7x zXDu!*$q#n7bRM;8U73dyb5%Gw8QRkMp;amNLci^FKn~3|DK_JugWcly7Jkb%?=!Be zjt-kFuHO=_^@~@vz<+u4yEU%S{)~bO)PxiPT6JBcZyIJ@(fFE-s55GGSyZ=~gb-L)oyr{A{C$#Qp zX&=*?U#D#MpIjYsL7IK{_TpuK@0Vp>>a0ZzbVpWWD=AlJ)NX8Nv?q4|+0{|G$0 zymFn1-LKhl8gt$CvhMI`j%xp`%KdJ?WYx}L_MD99KVsm@?am*i|7Q(YS!?Hu+86>2 zZoy7SN#-YpeJVBLmZL@mdrrvH?W+u*<89_?TW zH^1&NIdwhUTWsC9U&7t5OAfoNcKyEDy2bjY{%J0xuf)E9*V7G*ZTkmXAN@z}I&U!g zYwMmXwZ6r^zoF(1;#k%<+y&Kha0xm4{A*;-9|WjB<6UFZIWaTfx#G_X_9YNM0&cATC4 z|5(##qZgD*c8lgN>%r-cpJ;mv&lN+o1$?&ho3nGswMF*%7Vy5*Jg;v2sHxj*>1^x@ z%3ap2d5w+X>(-}_3I8-E(&v@*KcXq^;4g0hpZ`YAuXMP>Bab`2v;3Ulp%1pE7|X1_ zF_v-PlD2QjB7Ng|+&6y5eT$w)edBkrz8zDfZ|$~k_;aGZ37+}}KI+?C*EgNl^T$Q= z#r}V+X_Ot83yO@(1sU9%E)edkqH!_LS4HD;K~db__+x=_x%SxbPK!H&y33` zgS*+w${o*%$Aw?8^}cKCX-xIe+<4;wglYu z?#gNFtem#KTA;17yteL&{Llt>><%Yi_LkfJAZxckvs6X()wTASkrhoBcYkRuzU8vW zHgU3Kf#q4#Pj9V|C0kf4bdHW>3p9`HcGhs5^+Se2Kh^~4_wpP5O4nPt%9&7&-TN3j z&Q|v9tw(;JO&pPA>w6_*hi*LwewapVk8I*S7ub5|M)l6nn4fE9@dX)K%)aK=Wjp7} z#IZSZ4E@%|t261Z*z$HORV_yk??oW`yG;?}Cc?rbytF+Rv>t&_lKR0mHA z$7W|2s_!$szO$cW`aZ+<;kc*|!_@cV=sWv7>6y0g?8oHw{Zw0TPE_yU{q%i~?Yqt> zT0K;(@6WxFEq7esKWqDbAALMt{e)k&kD+n-joPS;bgOinfz6y;=H`XQk{DD|hjqW| z{6cjm&>z;@tOsJ<*gQL_dj_64i~RpB^%r2Tj_bysj{O4+{F(*^{xHGVDH!;-_KwYg zfqhNxsb@~IcL<2T-FP+AKdq}Z_o8*hrI9T!yP{#zD#L@=(L3!rQucnpn(_HFvez0b z+**Tq(~=y8&K0is=fuOg_1TBZ)W0}WzP(6!5_IwOZ@Ui5V*7S$4KHa5tz47I)J1+c{ zg)JM;&8=+vKbWRBxUl__BJU%!4 zCPwZn-_-)*57oD7_UQ4Ww<&L&Im^%4Qr4F%iTg7;MgAsoLjbD=Sezf`{Q%-KpD=eL zPa$Uqyq#0#1t*}K`qpk=X;i3P z_4ga4`dhED8Gt`7Va8@7`z{^Gkj{CG&8eKnMuxclZf(MMU0`h9W$A2uj+{?P^xX7p z&+7qafrB26?R@8BV=R~}yDC{aKZ?4Tc=^J*G};{f2jNL!~9Gsl>= z86M&P<$vIOdy>5o@X7GTnaqJD>X)?+GYN{n2hM$ zTie9p7Mu?+GSB}+e0x#eY}X#%5YAbb#XMs22z5?cbw6_bf#f9QHgPa^oQv_vUufU( z$g=m$ZL#}WZhSUTe{<(z{05vO6dqS_xi~BOj){7{&}UAKTO?^988hJDYsPFM=VYSxE~34&fg95XnfLww4|#$ur+t!A zwAqJ#6t3?UUX)dy7(*LuxUBqomNwHIZLsC!Cq@VE-&~9?>34_E0AF~?ew<#rnm4J6r;d`{BmBsF*S12>h{===x>(~;Ob0b* zc=Zc*JgR|B{tCu|z0t*t3-HQ-bMOLUm3S`r!9eA$;{CGB`#;+ELdM3(l&J z%6&Lf?q$k3I!YfodtYk zpc}Lv0AKjLEkS;*QKAX55SaNqI&OSCe`_sG%Crupe(GiHEAWz>Z5|ofU&0F>Svl3- zePjO1FEq)nkyVdzO05Z2K5g@|`1fpdfs^L`4yV^eld;ga@v1-HbR+8*aE$&}f8X+I z#Ghk>Hea_po_qm#FH+|-1L)(Zpv~z!?YU=_p`F`o8NqG0JY{gL=s&JMV9a7%uc|(! zKe%317U4S2#{pkjf9cikK?jd;OySVL9|C>}~Wx+Sgb}R%lIi?`!b% zs9d>o7I9sDu!Y|woAd$tSkxx{D|85Z7zK5Rk#npK%$kGT0OVV`TKc3KnU{Kkd{=XV z#)I_D%q`YcaK)r}n($G92W<+7t9`Fivj;TrajjopVG za0U1{n8q%l4c!xjZ_4D+N_e?6gKt~?^u3H;`7n99w>v*7;}@5CC{yM#$~4>DIBHjY zQJZee)t2;;)19~MXI>Q6o!cs+e(b7a{q_iFPGrl>23D*)!O`i?6KL1;0~&tZ$@yGe z>fw2`%{gxBpj*D})hVc7JvxlBb$uP{`sH-&W^!*lmZEQ-j_shY(p}m1N*~vKZxXN9 zl;ZUwI^OW>8vNScxT+894S)B(9{YkR2hVb5#P|=TuUTJJ4Yhj;{C920_8%agC~P}y zt9ae;w&95rEl+&H!G8dL5HBHD3a;#fG86^x!2 zuF;t_&e=~pe9gipemC4aFZ^GZQ{L3WW+=RN$l!SYys#V`ovd3(@Ql)2^+vX-oUkjz?ve zxH|eC2(47_psi=x!!Ac=ovh!&)A&6pTg6zV5~ED+UpG#YUBnU_KSxS*W!`O!_aKSs z;;af`*rTKTt(4`z;5u2P-%;GwTPy2>Qv9DR?LT}o{2zaKoBc2Q-sbkjr$u$`TR{IO z2EV=S|D@A=+0R?LQ59HNs`GaB=WigT?Yx&*X!U z?_`c$L(IVjqD)G@8F2rv969S~^&;@!1+DPAL^78DuRtT&AKCi+>@5eA*8h-vbH?+! zevD^><*$$CjOWZ!7zsCneUh2nccDhJ)T+CE6@DxbFXDeb!{T!e zb$lJz@iKF_*gE9y$*~SRg8eR2J4Af&*@nqU%S>V(sSTfY!5=~iKhpde#dKxlV~r0-Rj>N zT;S}TcP7Syrx3`Iq5?h+_14Kg&DUM%}eV&X3_kSzj@AN;JN|J3PD_+G~8Dz(*~()0e%c zF%^)XxMKQHt$|X+0;FvWwOJR@uIQ{aPZXnX*HDck&G}k?9kk8)z17F$|GaV7r7@<80@JA&Q& zPxktJpsp=Fz{Yc_EcFbX50tf;y6*oN%TFGS)-c9d-Os7HIDi?Iiq|GcdsgO{_?@%=P%tD zF1P0|UqP;mPbWB>d_DrsZ9Yvs8fkCToWE>X-1qaB?Y++*gBR!3c3Qmt;Ar9F1)R^u zcr9+->5ucF;FvS6z0GlOG-uN8vp7EOaP)X8igRDg{{N)b+p+bC2aU#5{L5LgJpSzr zc3&Fz30~lQBm8UDP+9zH&t1m+T!4QQ#L)G2{&FMj8UD>V3#qnr_R{h1M{FPO0RJlF zV#bFT@$1eYcsQ0b@Nc@(<&U#{;J?qmdlheZU2)#kdB)!4kK^5W7PpT%+Il>qGmV2S zJ&lcCn|)5x%>(+mt&Ve=@362g0hY>hKBdvn-Q%Y&aQDw??z^U@vCro;HwR%MdOJK! zpWyo;77wjoa(QGAFrGOnl5u9;?DIz#1v2TL+HU5rwj2ts@ZQj{S=JSE;%dp>w!E2h*y%$@9ye>VR#7Plfrr4!M ze6x)vH-JCJLxb=NOAqB0(4Mr;mv-Ui^<&Xi~3*p7lm9kUYC#`w_ zS@Dncll~uj?;mGnS?B-XXAUFhFcJ)i{1{;v(U<{^3=LT#=0~plSXcQ`YKVx`3bL({ zyQ_T21)TOHMs1w5rJ@4Fat3mn($<-^7Hn$$Ri8lHwbtDn!14^#F0QrBlr-Px>$}1Y_px% zUTZkBigOWfZz4?K3 zr5^n5w^!v?CV6l0_wP@Iuek4RQIb7aYuJNVQ~pt%%e!W-wHb(?pNLsm$2Y4oXCGwq z^Xj~mY)Z=Wu*T>GKE`*tzO1zjcuZ>z&7>j!Ez+x9KYzmW^;fgTz}Z@gGZ?_vx-*va z$BtOKD2>hISbgpsU~5&Y@yRu3Y5gy@1ohKZ)WOXK?*8kZZRjAzX0I^Qx7{~Cn4api z-z-(VsVDc#J)^RN``mNBdB?@6|FGZuscUOMrU(<&HFGYF+K&G|bufIBuMSVx{LK7F zZKa+%^UGi*95ZKvDLiy07-_Xuw94*3F>5>O%QoEUj2-mR_f6032jUAuN8+RhOooQ# zw8_vc$V=iKn_nX4@3#r^mh!mC<}DiPSIGBJasIkSV1Cr7Ij!$I^F+>G^h(YOnt<&R z8HtW6Us%>cPq4muA~ErX372Is za6Yg1TbX$V{q6z2dqlo|%-fW=?v_LDBWsp-1u+mWI=}Htpbuxl;5Qyv6KV*|EgLIe zm0!1fhZ!SY6-LfiSMsVd=JSRAJ?L#@W%b*A%s&10)Hj&t|E=i5w@u&~`%Im|Y^cRq ze3@WghYVt@@blAMrb@qyU$wVxLM*m&f^e>Lv{5|>H$2UElBF6Sm4~sxy0TW+o3cvn zcj7nIQ|VoqvfHaH=F5u?&EOoecx=yojHkPgcn7h^-rIrATJcrHACAXTM~-+Y&PBRc z_I9@x$-XBmzpu-LZMJ11e=}>A^f{AG`jPu~wUzxUs_iaLZFX_u&78YT<8k_G8EY^l>_zmBCrW)AO;aO% zwXx#WoedSOyW$nCho{kBr+VF+*|V8=>}>SG{j+z*zwnMkk}(4wHQ`mGZTRPGxcrxw zX7*ciKH%51=AijS!t45^o>iZYk@RKSjqT|~Q^V3$Xmzo|Idk-D8b>r<$d^;L1_rsNoH*jnGHalkrR8 zJ5vw(=v=#At~8u+`K-!QS+U_aOz;vbCJ3uTjPVMie|#a0{@63kem_lmL~QLIyPr*Y ztg`!k=c-NOQ{~HDbdBhGi*M0!@Ess+Y4TX7ThCU0_WRv7tU7^j3+>@Zv9q-Q z#^A!YrazlP#x*sC;XoC+8#`OUL1H*9TNr`P7PL+n^b7CZBkgW~vYVqvozfbN&_I2y2zuNg0ao zoM!BaK9*DcXUXnhpHLZ2cK^$~82a%7*1qDs_b||R!aDg+L|6R2&`13H0|R%_8rgB? z%#7@)A7^x3&Viko`Yh$BJx-TTyYnWYnevl8WzR)^8e|CNW_9|X5U(_6aG&l=q}ROS zP58v+==H(51hfn9A+kOI)cgMY^*%5wQ|}wkwe|k8I{e_( z@Oe3bxlFLlMQPQPzsu^GQLGbSd6 z``>B4r1*q)`vm19zU!E?e`e+`!EpKOLgn{-LU%l`%PIe_B9!lKHQ(iwPd=vn%KhsK zmcJ>t`~-JNYu=kv{vA=uZ&{@8a?0o3l#l;fzVZ|3V(3-|zn(DWf9sd|vm%(MxwlOi zXUkj{z`Qmu<~e1CasFFhw<}s^&yEnzl$pV~HZRUOWrne}`ed;(8D|Yma@v^>+rXT` z>AZ#f?R7u6{N~>NQvUU-O*&WNVdHbZRlbz(EA{2eO!ygjh&(|SGbhzp+Y=b$JEv-# zPOiB#FlKtOT62G(&TiB=8Dl;$8W}3ykY19o>q}+~#a?B`Z}bH-hLQJCjW1TFxw%${ z%2rvlLvrmyZ?*E9bU~l`pO8lBj9lXz%{RXA8+@7><1+JMFi11j<@#g<<`WTQUA}SS zr;HmKGu}m+n%JPQcLEzsFI!gN+Z+9FTUNd+mbx$WZN4#McwcSSxF=dM?wvh= zHW#D+i_kxIit{{=Jb(7<{_|9^dVZTcpBq4)KA+~*$y&T`#4>z(xWdvKo$QhbG`nnC zG@Wb^eA+zVdKc(l*Og@I{jG`F{xvv4y|3)6-c~<3k9w~!R`34nk}Y0sGF$KSvi<8v ze{AJ~m7^hDvZadejGd?>nd;;Wtth(WEZ0u*ET&7IN1v*rodtb32QY4J{z<`c>p<12 zb5b{IeUowPA8lK7c2<;e>&D!1>qKzOx|u$l8M8D_X$(YWB=U?|$0Ceb-+4>)G3({- z+%fAvXn)Z$YXF!|FNSIL_zb2iP9dh;C1U1gMh`dzn0_!KrthNfeJ+IQU43C%z^>HKX>3n+~bB_Ztt9$3#5?gX?iFeubzAf=~Y>C*ru*V#- zbN5{h*MDPT?ZgS*{S${_|G8f2WJ}Tf!`ZHk-HJL^W7oPhSpMC1_( zj`hoo&9Ox`$B%JdzuLA7TcfclPRe6bB%Zy+zRj^B6d%Xth`muZOVRB8&fe1Sh1RSs zhxH5SVr-4rQ1m{-U%W7B|3K^x=%`umI*i^$NQW&8X4!Aax6snY%5(i4!Q zr$G0=^}=X!RDFI&SFRlWC>W$qQui;Sr*HLkW_jz}8w_t9Ux}ULmz-}PSy0R-^@wX% zAA0)xXxD1mHL&?bUOj!Q_l}{NK5=-3tv5EQ$0OAHKl`e;)wMrDy=R5%-Hv?*o3^u| zY0OS=U%KYl$clB$2{Y$zYX0eLtg>4sV%`YZJk40IwA}sZW%mxOON{c?Zgl4rD4zYi zUf_M+*;|dR>IS=}q4JuCrcBs=C&LKqO!#5$oLr?#-u!8kZev!it*fzN9Zs&1Zk`QW z;nLYQ%*SV^2HUi;!D82RZPA=xe4;T%ZPRlHGBY-} zbsv>(qW449=yZua^Pcp>%=5umx6)VtD3ET~1%A5k1=9ViP4}PvzsWE4wp8^`V%-`O za_ll_)dLBYL@d0{iYHEyiq*AZDI_Y&| zqd?a)K9^hTUmTX2#eQkYsd4I8M$fJHZR^;aJ&X5FWUS(1<@II_@+QN=eex7S5h_)9~bTc{*dk5Li>&U_ayDRkP-Yw4D zFIAbzV;8zHL+v5V#F_eFtLIyjulbHWiI3;(N!;pfF8AjG-!4zxdB#TVN!+^98?u?q_$vCe(X*hh+U&2F2kg;-et=GH`a(^2UH1^iPs8T{y5^1d>u+eB z%fo*EdXja>nq5QKSLD-7dOu@zH@4pHa34_G>Wko6=ws4dRFazx85j0@XpssK4rqg#8YO$Z;3-U>@w$(QFo8E9QSR`Jt}$XCSR;z z`I$24kNN6{p8)cRHGZ&hW%R0F_*?21Y}b*%w>kAIWH%FE(Y{37dsujwXRt)iHt(GQ zEM1(|rm9M*C%k%uI=>je1)16=K3QegQLD%^gL6bW$woO4Iyt*!hE|rwIpcdnK(^ZT zm-|>J?1jPV`YZ;GS$dgt#0hhQ!v}Q!-}0{A$j29vg`%7GAThROFwpst7K4^vyc)XRIb#%F^w+*wujX0xkzCb0U28%2 zQPz<_Str&9XQlXXHTntiq9^q%dSr}(%<1F^bf6vWz(^Sk%)E8Fy-+qnO4Jh z$h0+k?f9Nd%a8J>GNx{f`Gx(XNRgVm*8x4Gw(I>xv=`a}ow z9NOl$Gk5Pky54bb%m`oCyboVHbPl7g>ykmZw#5?NWuaJi4 zJsJmMoacO)vQ&0wPpUth?Kj#z|X^{ANvqK`CINC2)0l0>bKR) zN=zTfp+$ROKa{0~WW#Q36k4a(xT~@FZms7J#fQQ2f#QJMeQ+erO_e3uwrBix16IDLjR)_-x0(J3?sCLfo+ zX@tFtlQt?{%^mT@^5dICPml2f zmA)oy6`${%rJEhyD7$ksWk8Ee{YIPo%GtZt_6qW&lRB7oT6!5AMXvyk$SH$|ct-2E zLu#HJ$DWd|YUqHjJ*3*UUH;|zUUL@4@|Hx^#VO?IrJ_;pH&Zg-h%b}yrQs9!u_?gA ziBig=9w*JOrSL$YJ=G%}ef!U^$zfT3og3iS99+y<@#7snQ-qJ>>ArY%?hwCjY3LH< z)z$fUwTyP<<5j{9@04-ghvij6FIz9w)zM7rt&U&K+HF7hwG%$9mK_*=Wjy^PdG_Mj z^l$U<>_}U`k?@Mjr~iI5$g?BWcIG3&dXkoUmg7U$_CFE%mbPd6F}!*d-b{AvSX5K< zl>Eh~U~?GZ^ReG|qx0_&LsMaF_!mA6^RJ6bfRB8{w(BlyWTBI-k|}d7ZOj<+){*|W zcKgWG;Xkrt%>5%%@3Ck0pI9I8HxB6iPXCb}Uxj^sV%%@D-XD{1=EUKtbI~_;e=O@q zt~g^uJuuQ=Cm3^9>T1^bH6K5dHYvU{&Rm8uM>MVSb}stXU;1l8(&u{5?E-r>LUqg3 zV`q8lKI*Y4Up;;}%CE=pvs0JYdi<@eN9?SP&vgCRj?=%4`Fg=G>$<_t?6*?>*cMu< z-gU8`N5|Qz^K2e}Ngf(|J<`h-UP4}5=lEwZCI~aW3&bae!iVT`w6#s?6Ys9~?Jc92 z5A$Blm86N(#8maWOZ@T|+W4`7_)XYx7TWl0ZT$FP{Kcv2Yl)|v$|}m?KcVs1&Yev; zL~ZN+>HH6Vdfe8lhV(_{$%Re=Ks%C zU0xoZs(vi+UUzn?`a6Dl6Tf0?)=otp#-1fR70=bOQ}J)oEv!ma9}2u5;=MDL$A(jw z*EA0hPRp@bbC#s(`x*Z0@cY4`EqVIE56<#==bTZgPvL{6elQ8%QJW3ksTo|`!2>=onERZ zUVcz}40fRp+!r6;wfo39w;LaSc)|BI_0P(0YOHA0eZGk*=?=PsN50h8bxmQukQ|!z zvt4E9B=Y??{i^kyJ~lfirv4Ockn=6?mx_)nYgg$f_Tv-TX+ zQy=b!<1RJr^Qkd59O;N-jUMC6OY|-D?+<)9wnXpy+ACW3wU6`jnyq?|;rp@tXva+6 z<7e~y9$ydUS^X(^50max=Dv+qjW6@Z`g!V%|7Ona-$NerSFjW6MwcjJe@q-#(6;#T!<*-WcT(HC`ZThiD~TdEul-ddIVIqP+f z245@lY2af=JF%fZ<@R?8=f-QnBzbI-8(ZT`wYSLVkUu{I*@*lQt<2pI+)vQVH`r@a zd!SQ|bUSo6?$BvXayG8~)HP=MbmqCrE7!Lw+x?U#Io2D2?zc6ua84?5MGgMZ{+)Ze zTOwInJ5&DgqKD5THcWY+uQIavDLwR@$(X;EyC1mEkh$Owyd`_%i@R8JJ21a$mSo}Z zdF%Enzb#&@(%9AF`nY9G;>xsQf8$0z9rc5olq2-B{n z_C>9m6aKtge3sCB3%;m<_lomRd5C}Xp5dPZmVXZ9^3RAO{4+enKf`^w5MRhQi{PJy z@Xu9+_=i1arVk&ehkup@_~%^s$Fz%n(@gtn&|}cM%5-lB`0;;stBE%{%-LOELGQ}Y zx*vF?cWWeRwt2Af_GOQF)6M5M zU*PkX!&U#Lk8r2gl)*m#8kyO6E&U;XU;cF|-!NZRpTb9jdF#OXa)L7F=aC<7PlPMu zRLKk1W+OK)@zAYB>aU*1)hj(gBax7T$a+XnwuM&sYr_-eWF;4R``_)_=OsV}P! zH^Xx}cXCgBY?t&~D~B1Aj2xzq`(v!if0KB}m(w}%*|03nYhTQtz;}xSGQr1_d@qX5 zy9>x;^Qqun$}Gmau8h;dyBC@<@6_>b1-#2xUTeqgbOpS7zPI)Uw-%}Q3*qhl@^NE` zkMD}W$6Jc+w1 z^>;rbhx@_HpC%v2XD20x|B!h3Hzm2e{G0k*Ue^0Sc=^^4FW(k{m)95J^Ay!_wX=PX`!Jgooz>JvZJozSO3CjTMn6VJoPL4D$R z_;#TB#L5uw-V}j%*A(I1eIefE-SF;8cy|rFdlS67FB8cxH-Ps7@V*?pH{{2Ah4$6?bLSS#o&PR?_u`YlJBW2LJ3@MT2#XmJu$WZ@ zi{&9KcsE!~2a8!?F#{}?N5f)40E^+mLh}yh!LqT~wcXxxkDU2)@A-%3&r$3v=}946 zCP%Ip^Ca-ryX7 z!>cNQ*H2|9D`KO=Z@ho~@%dO`y@NQ@AD^!qnBH+Dgy~BWFg;cT(|sXKc{i9I0n=k( z`VyG#i-zfUf0^x%DU0bq`lIZovZsc4cFlZi_t*sw$!=W2I?Qg;-N1P4F&>{i)w}m# zh*m}W^Rpo=pNoLy^F^@S5yFypgXObe`8-%Y2bMdcVYx1VN39Bd>YoL z5<|TabFE)Up*H=^l;C-3;7GmAdQ}6@cMMwW)~TvhKh`(jVtKJpem9ff`J^cneKnY9zR^zKc$&WPIDKP7 zw7&7RUu5OXZOl>BKGuiJd)c%Nud^N*uw|R}6YkdaI;#D(lrRnMhv%JK`E!e-kx7Iz z4>oIs>GiQTx9>AJCpG6U5vQ`S5oONIQX0RXjkW#E^hNqvMXNb~DNwJY_6|(Hzj|vw zYW*;^_8p`leKNCV1dYx5axlKA{Cg-w<3}RU_|YOXULK+`@2X43L(uq9X#5B?ULK9c zGXpgKt?W+yq;X^nc84%{AOZ$^i(oJ(gaPjcgWX`T7YrT%gE`SK=z1l~=ijs#h;NI| zrHIe2MH>FfS<8Wsz%tAK4-U_+g*zTD$}{(b@Y8@%oT zukGNq4ZJD~;&s5z!?$W4{^bB(YXf-Y8y|&ZzOgVe-!z7BxGMq?eej}{OH}HH%EHh@i_D1Rh zw}xncTLjv#FGBklLbT^y_35}3+OLQ9w?X?CqS5}?|72xG3$z=E+%#B0<9_Q5D?_;4 z6akktMR3^{!i9H(%Sv!r11>j#%f4v1d@+E_%>%$CC^P%e84hSJvb@^Y6?^Fnk9vi5 z2IAB{#>(Gaondi^##cw6@zNqR-VvfP?}o;Uq482^d^I%Q5sk(d1Ze!S?!q`-IzvMU zgUcgeu%HMA8$uZHZZK#7g9Tu4IT&n+hQYCy1O4A(@Ve^^(?fX8h=A9uB6uwi;l;bb zYdUz%0eMe=xUsJ<1@+rMo?|;otHiYDO`G(@lJM``~Q|ws`@+aOSpJU?XQ!D*uO3e3l z&CzRas7_rRs3V)7u^r&=dtoj6Uzg$Md<}li*RuC@X{+0#8fh#a8KTMP2sEiELX*l6 zO?Wpn83|1)pvh=xQW=dVUB|P1`I~BQKjfLgW_B&U(egj`{i3yoQazixH@@4fr&P~W zJMh0ORXX`t+r4=%OtfNtsWXbrx7gdzpUSI0J5Qf) zw0ApAz9pCW|8e#Kj6gRGo{cd|-;%~7O(s3{Sob#VOQt?NYj3Cer}ork!pcmTIgdkU zuKU;p_l5+{)(Gvta{Gd`*Gc*ZBt?1f=`XD>|4{Hh7P_QIGx!`cKs^_CZ|MfV!`zNZ?y@2UDV+V_;h z-`M=V@?Tm0zTd6|xb^FNI(*h=-Po;iY@?FH`Qo!-SwHtAX~Sy}lKExQIPm3-j*b3ipMd{XE+j7|YFk;q~qd7tt3UL}p)Bpf7w$b4})L3D%wG+WXAR z`=;fsPuM+)=Do^$*^MC|#GYHI?=7G_^()Pl`fI;zifeCKkhcC_v*NV%_wePTZMwi( z&`$QEHL*u;Z{t;6Mb?6{<2Z8euL88ac>p&3pd9MMeraUbG>c;|`{k@6Yo5djdwd3e zckP$=*f}rr8rd7t+w|`HBo*qv>Fs`+yfi+!^{X5jzxuOm|9u&m)Svl&b}Z?8JWn@< zFt{rM2B&ZBDhGo{0~omVi`U(Ld20x-+aln#-cOU4XI==|h;qZ7Qp<==J{T1kUFnyT#gOT%#})O`@MGbzrWU9V12FK36oR1o{_L; z6zObn(Mjz+)nyo)LU8?}J(071aSrPj*HQRe`MH0sX%wx+i$%C~GCVXov2ebL%AL+)lGjn0x+eEn}UxWK61#|0>R@yKnc# zMGZW!{MeY(moKn)B((eYKqpdz%vl@F?o5By7ZPJj*WO_L$I^NqU%GapJ>$f@SCy{i zEaxSnnR&0PUF*3s5J=CNDT``2?@awEgmc7gYOv|VfAy0a<&`Fz2% z0|V#H_Lufw&eHx{pU=|%LPvYyHdbpldH5#q?P2%ri(^s~+_&PJGOta1li`svc;r)q z*6w#ap?7#_qB{pe@9@z6;5$5YgSGpy_SKdM@(}Mq9@+^H=^PldKFYq?8hED}-bqjM z%vrVe%*-~wuUEEyAe**3lNO#x!xQFweAXDNFZ42J)~yh&ppovxVBf)7caKD`@)*m~ z_zIZvs{Cqh#C;s)9!sU1E30$Hgcs+1 ztMAqjS2l<~KlJHw$tP>JR6`@qo7LHyZSH)$gsCHED`Rs_#KxPm6CJ%INBpz%0{q`l z8CRW@O*D9?0_l2Uz=5S?2ugh18>Lt{G3~YHqN4tT`Xm#EB0?%ZyLV z@-8DwKR7n^Y4Q*sN$$*zCCvB2P3ys(_{z}cZj<&KV^bfu<-OHnYr@YQm%1yEN0U8U zG;bc)j7xo(w5EQa8fWTfWUej0Ddy`ddB6SKxRlyk=-a;Pe!Z=`p^e&S%RI`N!Fo>8 z{;+?LY2OdVrLMH!W^g{k*M(G1AA^e2ACt!9iM-Vr$8+soAMt(ypJ3)n{`jKzBzMg4 z&bVxN)a3Dwiqs|KQ5FolrXuxL!gL>drmU8V)Kps^gA;WxQStS~?g!wa@;;7i%rMrGCu#)Wa|N{uXCzPN%%++to4uOhu)?eT?q<;vRM72UblD z=df4Dr%gwBAdc@8=l9L)IGg;s)|&BNYKZRd;mk|)h+{(neQ{5tpT=S6{L|`!^*cU3 z^)Xw&|DsIYoo3`H^lc)4^IR?;9O?!y*C5wAFZYm5zK^=8^9o-M=+4wMafTL`!;jpF z)YLwnxxlh6o%yQ#z^Xj4$-4+&J;S$|usgi+B(jlv-N&UHyf%B!!XiDJ{2It_b;aUl z@~U1xrI@R_Z5)f4U~5&a?FSzot&e7{;6d)df8u zgDcOfO9$gpnscPn@x&C}Wqc>TBIv*^EAOvN{qt4ar3a3lXvaTeTlZ$qKc`s!LpM5% z2-i3>pgL6s>cq3D6MbL$gX&bmJ<&SrIL>+8&(`Q30>2)HPVxza59Ydau>*02_DS7m z1i#Gm@9ogHl{_2THp0*1TlAPJ+h(LPwi3~oJN&xVKY<_8Wcf-VKlx8w#yP?E%;#P*BQY`cz)yXdA^o`2(%qb$ z%=fB)Z=GOXb5CPQYCpba!8sZCK6dR|S$VsW&C&;jIe3veTb_qLYU&2`;hTr1Y4Nj-;(u;+Cm*h*CPWtu{)y1z5_8877n-cL% z&TH_&T6HRXHz;#{kuy168PZ_}dhVxdWANYDjB30QtL)l5enwdw3hb@=$9(6G;j8gf zp8DrIlei4b5*D*l)gIb$DQ&n|ZOdr`^~(D6CNe&~&)7Do{j2PlouPk$cK_0SgPkc+ zAk98}v4Z#ppN;Jgf0d}b^#|k|$2rlb=Db(mH;yyFGrn=}@z04)4L?P`alU_j_Dpd9 zyl?9>V$L|J)?HdTXM*c|a>h;Maqlz1&kFeion`oAC+C6dj1u|w?P*_<*B>ZHe&REd zelaUQ2e~t026zVS$@<1Iw?FP7+bw#AgHXYiNoWKD)k#`((85A32w^@4qR2dd{v#&K;=o^+dDp z{~wNI<=j)J@jMW4JRlji%HkOIjcaNg-dgB95XBkn8?Vwl%h+e+*NBaib9a76&I383 zxo5WjreD%~#y742jf z>**qRZ3yATyTPj+yq;$NQZ8yp@2heyHT5pY-@4TnDq;Be;ve1}!8`_1HgJr86IN$(C}^gslR_7=ftP6#93 z4Mw}cXfGH&07i47VKhE~k=l5=eB<00^4#bGzHxup{?&QMkkjQ~9hRT>AIi$l{R8w7 z)tKGq7}6Nx^SdJO`IaJl-V^e1;@$9hBYeIEKEDe-@5#TXJdDB000tWZ{=%>8nNqig z@VYGmUh9kC^+E_Q-VI*2g4cTRx(&Quh=$kb0AAArc%7CpWMv44nyjZJSoyTI7A{SVr2JO9|Upa_jO zglNpWp>YE=UI2|RhsGPC(fGs*+5RHNNL1Tgra?Z>~%e%l4{npy;}IU&4wH+W3~ zuc_cQ8NB91!|Q_qygnAd>$HqbBSU;MIs)HR6v3e~gahvehmqh=0S=?Vp)wi{ZwcTq z-{Qc!Y~=G`Rc`QCY;01x)8RMl);V8O-{g2%zkQRVu7h*m^l@+J`Kc=YwGLjgV&kGo zJZl~NfhvC;Tx-!<*VB0(X`Xe)hxy-R*QPHE_#_dp^HCIEf^HyRhDkObg~_KTG0580 zSV#B1So=+UhQI0iQq}qX3D#GpV{q*^Hy=wanmefJL$TQ830|UVg3=oPBkqYCn-(ct zJ}{g4c@wK9Bp$naoLNi%l&#yRD33Kg6PEJY+(xYy~Nl~Z`W4s(^3s)?8Q;{oUET>4|*cSHU$21{Xtzr_bQOk0BTL*n#Dc)DO<1e0-9{-uV zX9Rt4qTiRCUt*>{)Z=}jHfZhK;TGjgq5E0CR(qT9QPOw5&urjKp+=ptf;X4<`FQO~wuyK{YJ#vQ~*$DH?~JES+e=f<Bzx?_L zpAXD9cM5!IgsJiQf|d_nRbu*P=IkH&>)11b-1!Zs!jI;khQHxQWBfz<;YafUFiZUZ zz>mh@!q^OJ`rU^q&&ad^oSnses=2-+`}FSn zjufJ8y4_Ec*KgvM5N&x^-8vqv?@qVZcOTnV-+lC!Xte#(zh`CK{|@tM%h(**J`|Ke z#m>%hINo4!4EqPA*OV4M`=2%uj6mBGQaUO`3J2J z;jkeB4vj@{`0qivV;}DZhxOpl2o4*-;lJM%Y3#c`fWtpn9Qq?4Rj&KJpYQcNpf%Vv zA&hQ`fYGf*F#3K7Bi;>0YryDMFuDbdz8?*vQ2~t9#?$B@WOU%~zp20)?9+n^k0HdV zed(v)^}9QUEDh0kc?24-EJEY2glNpWq482^yb>BOhsIxtM&r-@Fe^WQHnjgVHhdpt z3|SDu;K~RXEG~ka_I0JTMstd7m&vi- zh-zq@SU4wjDr^i1?6K*QCEe_meRv^soH8?X|y)Iez~B^cz1--Z}mYAv}0Dc)Y^;;BV@< z&%F*m&1iT$7{KF1nU4p1YiJjDT7!$u+mlQ-Sn#a5IT&&GZuU%nrO{oy#qNUtBKy#t z>=AErZqzf0p-+Bx?gjpwUG;ar{@Nw~SNqc5uuFpP)#Bxu>F49d2cpBCJCc6Bq0OD? z-v!kbo7^ppAGTwa}jv>`64{LBgDhJ z8yhKKvHw)qq7T{{)B`1QIQsPWXUZKl`5!}!Q#bcprvY>nx+vU;t_UF%L`F8ee%(s`qb3q*-dyDg0u zp1TnzEYeFG1~zxw9ir6(IkYl+Jy>hbIj3I4+!>(NGYR_Z0OxLZGG6&I!qn2J_yc`#*E$%h@@_zV>m}x9vTgbs52aaBB#c+alnyz6dTa zgmB^A@W`#;vL0M+1D6+~;qv(aE28$ihuqX{+@or%e>UVpvdCX_dj!m;ncBx*WVVM8m7?U{+2g z`{ptf=QaK4&)B2$_h-hUmyIp^vE|sPjV+tB z-0cFMx^F%!8*=4FAzHi&E&ig9Z-tGqVV6f=kGhO+HlK#|D9#rifnVIks#BpholTn* zAFOxwEYCrivpkKjKj&_~#qwgI{7T60e9{z(|8=Q%@Ax9||3mz!BJmS#eKi*J_pZ|P z$WY%H9ieYj6zLn4p}xVpaO@aK->9H(jHYi?M(Z2%4`gNcXYE;g{qZLXuJ;!6w{&ua zvn>tXjZC61WYz{NN(%eR5U2K~E9!rDeP!Yy8V`;@L2`mmc~^Bpt0XaBdpuJ654nEtL(n>PS&TjhM(3tb>Mu}^lysn zJAWaB0q+KbSJ?aa8}^<5ihbuVM8jZf0E3R-mGjt+gz$PP0$#_8;I%J=7w-nIBj9xm zyj}vYebMlGR{*bj19;^dA5Z!`wr4{)JQo3n=ZoO5BZLF*28UY^ye179w8hxXP9E|*V1=pOz+43xU1MRV8+Z- z>|?_D+h*VPMDh>TD?4V#GGn%Dud^){)f?MGw0}GT?Vm0}`wb!5^RD`Iv_t!+q5b2~ zenT|cH~zn@+4(nHqPfVg;stburA6*HCr<5S?*F^1Gwcr0_<;yC-dlvmb3!!c-OzY9G~Nr1 zAArVlqS5%<-^=p;Sp%T4%8k_j?+IbBEdmDHi(pV0!hm;!!98HG9SpXCL1i=y8Uq+S z%iO@oYGia#`>UPb`Tk11=Z7B^F73<#t*n1=xPLxIWV{+fc-<8NuPsIJ>It3g!@I$& z5xlm5*InS%lmBd=u%0<1fY)6CyiSYGaBB#M+alnwz6cI4gmB>9;BYHAtOtkNz~O~x zIQ;Uv*}ij`#bF@hhRS!pV&@zc>Ss5yW}5vzg8sfTgy~HYFkMpw(|sXKc{iA@1k*KO zdJ~xLi-zgW0H((WaORr9Z+0y{k^UVJiJ7|ZkvnT=tN!mcYa+Tc$@ol`lCF_Emtx5+ z<{nk~Q7VkPln6W46d&)W|BN{!ro8$yUfb0FK0W6d7MwRNRb310wcQcIop*!#VsKvy z?pK5Rj%c{o2XH@~=NV!jFk}6zu>xcL_CMV73=7hDK@l2n2+^2#L*oW$yZ{>heBIAHAqIeW@a*LjAFT{#$R4q)*6 zaGqg7yrvf6nK>bz;ob1eBzR^jJTn=dnG=m?-Vwm-^*qn8APyBpaHtI7z`Ma=Bsf%n z!)S1*jE2LnpUU=~H_kJx=Zvr+$ErtZU&VVFBd_O9-;!=&Yitt1yVm35a?UfvPuOe0 z$(g;--osp4{I0V-uXe2GeV9WQd;JJ6d^daGZfxBH$i1fbQSR=>3G5Z%9?8-01!oTG zKFQ{G?yHU`_xNM{@-FR-D8x^hdr(P}y$6ar055B3OHX$E#QP}!U2Q%DFLl66x-9>SEb$uU!7PVxbrx8-}~=t zyWV$h>R(>fnR9`5HRul7MDvL_chH8~b$^4US*4}fB(Hl9`0Z`DzSW#l@ykgm{K5_- zzBws1KUTITanaqMZE8HHD??ZGG|{{$T^s#0xqDtLU1x;o%DbT}^0K3{wtFu$eGr}S z9~!Ug`q>P8_^F%jKyIdf?oQLUK;sLc@l@!0EPm#msn8f-f$r*2mez?$sZ9oxxy?Nd z?k>we03M!uUh1JILp&Thf709w{7cp|hI#xrU+{|BHr@AZp6BsA(mq%5T<+gzy_xmO zbe!-weU)!&_(nF<{dOK54!^>#bG!VH@?8?2TkS{Fyi|D&rmwnq&W$wrDO|Kxew_2^ zKM$tN(SAI8G0fa5ZNoI**IHJxhP!-6nlw{Xf2CI%)lvDFHjk?J@0u^IM_wk6O|^B@ z8I@<0=AI4u@6^H6gFN>Vzq-6$G9z^}a>@DaqX)%1qEc;rIjmlTF#| zXGqW3F>bCstHh(vcz^lkRE&R}_xi16+%?Pd%AIdcO+7Pn?IF*3B|`H8rH4`*L(e|%7G+qa)Y+l86?Y3zZ=+BOT9 zGI&S422V9vJm4cgY?J5&R@~`ay{>Y)zTvD_ogG`Q?_7Qg>%|A;(MkAG+G}t*KZFb6 zCNJ>;dG&?GM?zR!a}rn>K2SUQ;DeIomJgnIbE>(_@_}m?<75rIPy;X2th>22!w2M> zmk$UZC?8xFYCFUIfct>!JCYUE^PnemFwa+bZN5%Y;Jnn3tU82@I!vF+$gII$caN13 z9prroIdPc0%S*g_IbXHSoHt8fI2X+7TPjlr2;XS$Vbwj-x6`Ih^%Y;<7&)Y8$5$)u zK02K-9n62tpgj4fYf`PD{BMYuzxI_K@a2R#pEprDVZ;+je{BlcVPvv=@+S`ROOy%l)Y4AZl`e#mO@+hU>4jN<6Tw+z_BC_=> zp}LJeg>_T?it^`u8-2BLLf3uq30=F}$G7fl zliu!#jz)uYDPQy&D(Zirs{;a>W^}n8!6W=pOn!-_Nq& z6X(8P>Aokvv?d<5TKv!*<*875iN#EHM;0Z~Isu+OATz`_ zt=4*klj^}7vsLoOZ^L!1$)R4kuu62#P8~zfdWt?%bK#WjRbVKds3G2j-7#f*$?Da& zKMcKsZM;?aQeWk(GPIXC&AcRs4hxsB`%>t;_v^bxzdojJVCi_vjXBqvH1L)lug5eFqKjtu%ZASre-W;-%~IFfbKTp49*`;1hGWJs;igQ+c{{H#Wq#TD zXrKou-ao5-9_O&z`5(GR2lk0W$hpJF3v6?3oya;TSJFHu?}(3-tt#Seftyz8Z zrADq%hd&c9l8*Y78w^wqb(P!>*5xPClgJDGy<26QcB|jUVr#{>ZXSo8-<^z6FP%5R z{7&-;#hd!Vf7H#4hv~|V&@7hn%QVj~n=<*H@>443C6&p$u+aA=4_m(laUX|)w7I4~ zZ8o@jYcC9yr}<%qe^$dk@LF2*Ht9qBK>yQtsCdnP41Q%i3wMq0j>h5zXrlOzIkjy) z@tD1vKsJ$5^ru+L=taWT2);5R3>%d#nLv8=`NwnQy2K~ak zWn>Gy)ZG4sR`j)J;FIm}$rdM1%>0Nr6OJDDTFRAIdUAEfj1B2@(*D{k?Z>>1w0}6% z_KXc_0Bv{u1>1~oLqfip=PUBrkS;@yvt!n4tH&Kk9GdyM>2Y_{xB9Ecl?D8hj1Gey zw<@H^B~HZGatFo|Ljzxi1a-LsHMBXX%iTmhqUdrj_FtF#B>nod>2hmAx>bMM9aWz* z?S_97%oPggb3PxPZhbCfU){wxec0(rS`$L|HG0_<=oaYC=2`lj)g7f@b)rjaOm=#i z#&e^W5uVY@&@o9fMc*lXfAq55zbzm?$up8(Mwv!0qy9zovaR0M$y$rqYVO`!XyoTs z>19u_7G%a3*DhZ#JCI|8r%gF}S+Kp*%Pd9)L!P7RW$z2MJtIE{(00>z`HuAwUw%># z^L#}<`5CygEW{&D*Jo^Po164)LME)dzWa%UKmT)SXm58lI-P77o246La{vqGRkhi5 zAFatKY?I#~GV4BkW7f2^?qh8gJ%RaKVyw6JW-F6qZ#hIhhp}TU=;_&J+A7TTE#Le? zx+iIh*`<>qtZ{wtbu`rto{z$7YKO6z>l@mudm2?2VG!v~xH$bS&bLFs$F5VjZ?T`8 z)j`}_uxSKsP;Zv3)i>p}ZL3O}{5h?CPshd>`;5yok@VJL+ck1rdCeiOot|%(aOL3k z;kVo7k)$2TK|4Q0{~dz7x>)Vew|~*pvn^N;%`06VO5@v83fybw+DV<8ytkST>u(b^A_Tx9Z`==KNc*9=cc3)$!gFv@gfL6R1zS?&2$H zKEb_vx=*r0bCxFTMevJ}bI@R}y=PEy3X5S+I4pbTlFHP7KIY%Gc!%ms95m}D{nt&| zykmPiUUk(l?f=_ae_c)LpiRHlrKde}WBwY7^3O?+&GS1py=;Xhe_?e-lTS~T7pq@~ z95M7T@qbJCald@?UP^q4zvgS+?pBc03ZD1Ei&T<#97X3c^zF;ULlq1377C$()ykhgk1 zkNje@y%8lP8y78V?%B4}wq4li`%b=ZD)#-l?DzHh-nQMyK*L)@3~y!M$C`J?m$HFr z%}{mrd7E6??VXKrtt$;~KGAONB8}E2QWfL;So^%Np>37BI}|<4k6FZICic0kUiBg>{;P@Ty;6y-?YU$sPZ41xN*_ynLXRE-(DhYwLa0rT87%3X-~Vq z7PFJ~$i{1Ea%BANx>IznWGm0Iy=x6cdBgX|6ORo`)~t(~Lk$gIp>K=<-7w!KAzgPH)X2NBD ziQi7uLF+@#|7r+j%>UFysVUG~W%kN9{npeSHs8bK_hWt;KH2N@$)=i(i#~H<&$gzO z%WgLq1j^b&nBi&s*ApMFG;}v@$XC{Zi&8h*vL096!O7rCf4Vu4r@;;Uly3$j>R&M5 zd*7D&6Pxc>$rn4kpZAK|b$9=lrFkI#OnsZrHuc^7Ut6Eai_LY@Q*XEV$`@x_zI-k1 zOFTR3z#aG6E6M7q7Tln^r^X2T-u6r*@9WJr`pYj_*b%^<~-(Sp8yz{$XTJZtjUIU}{h=8<22 zyS%w4Zr8&abMG!r4`zI?$?61p_t1~@A0zzbUG~1;8tP8nO!^B8q$m6*F8zgp^cNLK zPxy~q`ilbTFDa0o@b9_wmju$!ERde?$6WfEf%NQMnj7=yI63Vl{Oc|~dzmurtt*h8 z@Mf33E|7i{n8x$uPx$9;`V7WnYr8)k4jW(FeUHm`JiG%fD#zM?@ep(f-nrZpkE6Gg zp|{}o8@GNh4f4|--z8pR9l7ht6S;c+r?i(YzPzjQZqKZ#RDRt4lfMb4Jo8Wa<{$c- zf9Pudp_loG4(1dU-!W*wS$jpa=Z*W>%aa}wV!>ZkOHwO&g6 zuJ}51iQyM8MkstHHvTIa(-|-IbGlRdO2+Vj?quE>Kb@{&-s#UPtSs{Nie;v(A>?V~ zb{^fy^e1$ur&&ir&-O85u9B(ex@3 zXX0$Q;xctkW$XMH*!H}gI@>vcq18NZozknGwAt6+guTiJWAs>~Cz<-pBMe5L8dwK$xf_i>Sy(xs*0%>TfYndWA_J#m8~oP=n(#r;lc2aW6TJ zKKf30=254Ms{LS4pLg$ex?%(MlRj$wtI~Q8>Z5u`AKf^{>YI8;AKh=)+e~_R z-K)vQJAHKjIoYs`K047`@=ofN!GBWhpx+PqhfmWhV@7X`G4Hw^Y?+T39@vT8=+(~J zOH+erC*!H%&m?_Gbe9iA`f9(QbY8u&4g8*A4Y)gYM{@gjcQA%jYLDphu8GJOQxDQ8 z?mNLaWKJ;dpNSK#(7TOHNgzMxTDfib0@=yj_Tdb_AvcLPbN9S;-+yW9Us=amWb5vc z->$}`UFoaw(O6fxSbA>B9kusdOBz!y`R|JNj$i2FDeurU#>&w5^N2TfYWMqnR`<7k zDo6MCWn8ZA@5`w(;UCqbjDDzpC%1BS0$=}6OV@~?{~P%x{hvAx2M6$zPnD5RE1b@> zn|IFfcm3Y+4Rn4+d{YO#tGt~bie1vPE!bD&|EhND_ci59-xOa@$>^`k@UNr4$`*jU zJW8Dl%_mGfnNO^yok^eM+8-s%$awkO z7nw_#a?ts&q#S$(4Np6{mz@XMaRWNoJbkRGLqVO4JpYJ1A0f|MlrNaN`GXgzXQqxt z<`1Th%pcxNe!ETk{PAX$rAI98)8q3O`}9zMl;^w#}ps16+gTDy5hZG?K| zn`fB%G0*rd>xAo7j^(FdetQVZU{_>rVe(>bag4k)x99Hb4Bf-+U18fhH&1(I|MX?Q zr5$}q<>&St=EumtUNR1S`f19aYs)sWW?^;=jZNIR=q>QR_|e3z$i`I>H#r!$DH~UZ zzVPog&`9`D=NiTU`Te@F)a0cx7hX<3ho6(;s6%=N@;~NbZ}3KlrpztcOj>N4X>0$| zJbM9l;Nr4-X6jS4OV}8Fh;OR!x$Enj&3vP=Qgsn;$p)@>mHD$*efz2DckRntPpn_S zTqExL8KDO`+pPAZ?QFC*qp8{P|35^-mCJ8ezBR}Str2Xre3%JG2T{1jbCr_`7k-3$ zPCp@^)t)~`H-2Ko8T>}pD$R%!>jSpF#()nLb<;jZ>E!?CKJVV7$NuS;C+L2z1Btpb zQbRn(@AA7p+f173D#jxIE6?};HO51iwN2Oxk>M|=FYuP^g)jJ~Wqw_GuRFf@s^>1|>(r?Vd`voh3qH`d z*SA}2exe69v3onL4yyK%*YU)ra+8;^JJaQ-a-mPC+~bMZ=uBFr*N^pxY#pe7Uv+qH zNS-=ege{BqD8DJe{AkmzJZ&n=$gbsG?c{fZ>ld`?@kFou4P%sfQP%B^ zSukwvoSgbqlW(FfkyF22wr*ddZrM1jEs4|_rVW+U(}uy*%)RMv+9Q<-TU%wqWS7c>rTn%A za5|ny#Z9^ZPUuHvCd~0H<&w^)nd>Y1uizKN<*`6Nu7Fq2Aud)rlg8qSyvoWng&{W& z*)ZYxz&Xqt`1h>*aC)i9ql)!G#+pvnrIFhYXYxKDn@tS)jZY%|#2+_Ui}uHjtRK>u zEFkGe`@Ij6@y8ele?cZ)gz5P_ew&H=OMagl;O_>$`;!5FJJ2$N-(5=C^ea<;wNr6w zQwu+}OaJbtbnZFd|8U~f7Ug*ZKc&~d`zap3Wb}kM_AAfqTQ{_$4`8IYcOKc-tUWh1 zS26{;+t*m!6t8U6c&xE+o*Osg%Ud;{W_{S_8@+2jJ=9zB$pCN3zcpt}##h9Q$=HOi zbm{Dv?D$Rng1Q|@9Q6B?*1Zj%+40wn-Qvsh2j`AM=DR9i#)uDHUoqjSYSVuduHUp^ zz5$&;`3??^;pY28zD(A)>gT~a#R7ed0Y7J~)cM#Q0eyhHjwe?5ZBt(A<0|uLXiPQf z%HNbzXIFQvC7be{Jalv+A2-*kvthoR@$Fj{+vADHMrQJTb11JWXTx`SAzL?P)*F_0 z9VyQpbBoE=SKi!PwjK(MAEu29{qe)K&HbD9IoX2mRYBQ8oW7ColrLKf`{=lRvPVW* zeV_c(*1lo%fBJ}gto5vRHSX~4Jrwu$bPP8B4F~F5W~RQ_=IiH1&XO*Hoa>cGJe$Xd zTpn?o$C-bWy4U7G-}C3k)I+-eA;uc*(>-GJ>pB0H>!Xov*Q>YubMuMyG4>mHsh;+c z2h$Dl6ncAi4eN4I-CnY`dt_J7w*Ah3g76q&ho7!(>p0@2j_}>gUlVV~5PjGAeLoKWknYY$ zJal)$p2zQNvG3=mbLr%t9-CLQ&d;NNM3pdo?HfN_WpTro!wWwdT-){$#=I}k zj+{AAzI@0d^F80<*T7M|I%gz1cgmq>!&wK_PTBhM((_kdTL~B(c?mjB8k7VK z&=i|`GWpavx8LB2a5?al>hN_}4m@RO_1#&i=WIEe%eZn5QUBY1Wo*wEn?6kWhTmR- zry63ZBgB6m-tesMtvaOP+mb^{cZ4lfWQ7i zb=pwdeHZQCX>HkQ-q|nEt?-!+564&Ect>ifrT3FyuQWlPs>3e+=jY?w;=)Jzytaby zKO;OJuhH*~4L$t|dyo+a}uY z5AogM0Pp>_3*K|SV#*s{QQjv$Z}XP?lUyR7pjHmb zTDQk6hsSRU@i^}p9%oG?!{a;~UL#+_-|(#ZjOjb{n?twJM%F)$%&Bd=)bYFIF#LK2 z?bTX{?N@7@4v{9UZNr*fu8UPv2zX4x|F+36&$+H;@Vk4Aa=_9$`kd#*v(k{r>V z6EB(El2$z5V!S0Ts}?*<#SIx^z7nXoA0ywU9qw=WroT+Gf!EaDyx88NN_JgzOn0X z$S1E{XdHC#)mw(650s-148pH2b}&5&IaSX1KGf^JuVH-a?)doDWVx>wBul++^L##I z1LMfP#<5*BVA9+;rqyH2e0wM5%z|fTvG(KqA}5iSxK73-rJ3#cztZx*{EI&GPS*!o zG&V1NM0(PM*6UdlN%OtFQ(tMiHFi*aMKa*4)8MyYT%#W+Ik3mYQSZMSi`?O!m8OPk zT35OAG#a>Xu3;H-lVn-aYZ)Or&vSHg_0_mXx#h0D$S2cZRo@f2^_^zx`!=(dMZWN9 zQv-Ln+j4YARsx(qPioaeJtP%7?eh^439PB6T?axvV@YREIa&I+Rlfm9>xZ zn{65DJFaZQpR^HsW_RM_wQYMy6O@PPM)X_4IvaidPj8UEd#!sfOW)PpW7~9&p zf%iD?chS$c(4O|u_+Y*VKNsIYGB;Hi`E*Z&9*5!Y-R(oAmcnmoK(o)A}Xydua=_0GmCH@9m=eEl26+^J26QA9U4Ob*CL=P0+}H51c)2 z>*?yJdVNy+5*n^)1#9Ey-b^{J?@52sSl2|Dvn%ObBDKMkL7!2(^o@AVgu&~7ESYO* zrn%iN>ic(}#;!#!O=2_{=(Jhp}(%F2E(GHV0 z^)O=>b=LkJg{d#g=A!4F*ji4kU&tKiD)#&hvisCeeylKK$0)xqYTW3&%WD%KOQtnF z>dWt@cK#V>WMBQCbLDq*?d?xE{S6$0W67TFRxUD@Fjr`)-#91r-LLy&#~%g8j(>WA ze!{mMbKom@GC78E3OScX#x=!#KGB&YZY+4x+CTJ-DbJ1tf9J|`y6Tx;s>PN!At?Ld z8FQYC@(jp+@n;fzjeI7J=x+GI%4gTFRBi^BhkRT#m-+|raB<(GO*`Xbx=cCnD}1sB zKVQF3^X~dNJYaZUW$M}T7I!(0Zr#`JWL;KfpL@2Shmq0rPu*vgBcloHC8N26)tvp` z{$A5(9RKIYX!21V;cwdq-`lEZQ=h5ogTf4%8s|TbOo8sfajD6TFNA9>*vo&g9y+7Q z+$kejK_1Gt6C719C!^J$_fY>}zHVGe-==Zynyv(P=LcPXyN&)zSkgQG$(o^0eO7(3 z7jKO8W$|Fg8|d|B-a6My)mYw;f3fOP4XOb^wPdc1%G=m+b|IA$F|geT~{F8E(>id}G^G(yn0~ zVJv1G8M37*K8|(StgJ62<9Czhe)#%}4NF_UgzV19_js;+S9>Mn)dw@Ons0i^YQl14 zHTjET2q~l&U>q;+g#!vHD+^u1s z*=r5^RPvdv-zn<@Z{&A!GURmNr#w3=kX6Vp>Fly&c2?%fE>o`LCUyYLL%+hgXzsix z?s)OAgL+r-^Z03mh8=x{P{wqzpng24Ga_^q^X(sAk#|5azkQY9bVwCD)W zE9b^iFaOfor;wi-Gw=<4=KJ?DX6Svkm8;~r%C23RaLsA(|E#JWp86L5^;<7W{rYSE zTGeFQYx)S^qz7|0>@eRyoq6ZFL~PL7kJ|OUo-!L==7&2!Q@<xUx=TO5#MU9IO^4 zhCVs2ll6=#oP~CjJdyu1fkNf1GxHMi`Y$(E(YOAd^L0lEt443g-S?ec3+ZWK+?&d{ zH<@v7664++#yxCuFV0}xo6fk$IQSCdplq>>WB$0uIA_lHmSRx=BAl2 zjh6~z9Z74GnxmSrbR_>8N0qn6P{w#OhSJt*jiKU0)kR|{Z8VswuHr+mcn17Br;>*6 z4Da$?=d?WEsO|a&%>J2gz}24vo(8>Q-kXc)73|%#d_kKE>lKOdiMO4sKJi8#RzI`4 z+V2w{mPd>(D!t%?@GP>#@1t2B@_Cy6D81kb&ehN81*xh1)(fKGbEmg;_`_xS$Y zC++xNXUBK)T$OKpe_wWdFZrrJzRSnZjPHD7#`nQ?Za0|zQ&+pzoe`bZd#t3qW+LNv zvcUMQG#abP<9J_V^#I2b)m39^vAOCzcUFMrs%|{j_|BO9r1eoU^IqEA$vDioyiVgS zdO&v#VMhs@&$*fA{H-eFVlX^u!!-^E!-v{%jm!Dww&a;8_4NVqSX%Yb7)$+rq;WZ) zP8t3tpi_QF<8nNEhG=>^dJp#AL)ecGUy0tc0KMmO^qvOv9>)Hc(1WC_Qm(J}P_A@X z=?U17(QT-Y^dHii`Zf4?HM?^fE+-B7nz$?dxEhDE@)VZRalj#?yZB`(+}DNB_246w z=i^NJ`CxBwmcCO-ox<^s4vLrF6pnZFP`q>~>=)qg>r2v`L?@Lmx}X~xeF=<=zT|Wt z(Z%UYYMbanTmMCLnYGckwM*CMyUsbhOUDX+BdqidSbt4)X*@Z7DGHA_yYrCq@OaHB zfVeu&{p8*=UD>J^rOPIGerR@jKiZjK|+p z-^icc@GmkXVf`OhSetnbeNu5c`{uC`x##MfPk5D$n~i^XqLzIR_B*A&g)r?+72VKN zjeOFx=3kpWWo^3Pgty;gkG55)d zn;wWm56y|2M%)bYoQ`~{8ZzbRH2&*`Oc8%-tzrST#AA~@?Ky2bnwbZ&7OAYVY zdjq!|o_d4dvVD>Hbq+Rv!2Pt-$Pn}aBSYA?Bl`g|q)%Ilm3@+h|BTLWWTAA*^E0y0 z*8}37nPaBU3(PSun$~-c8IYZ)TQ;3Un=|tLjXGk>960a1fuqKMJC47B@_b6 z+vvk|GkW=SI|s#P|BsqW4b*0T5%_DKj%_0$zW`?slI?-9F6q`h^2|H$c5^Px(P_I` z?^w6Gi#d_zR=g6A6E#dTH)G$!mKqIEU;n531ex=7{I! zvBqTPD%eOe*wXgq;93xK9TR8gpY3)XEIo|2!+U0Ji@ArxKs>GXCYh&n@@y~(=^TB< z2g{?bZHH(t<+b5!eX)%jaM}7k%vWK)Gi3z$?4N>sb`p5sT>$SV?LBd3?JbBmd->ZP zAD%|M`=Uo*@fmvQ%na&p_6dkz;H7y^P8F*^Y2h2g-y0o&Xih^a?FC(>OX{gpfaFMylQI2ee3 zq|u3l4ZLmYWObruHx}j5iE11s@jN;avPOQAHRBVDYnFL$Ll+v-OHUeBTu=I`u&5wS zKm3v82a;JkI>lHdi(rw_5A$IW)(`t=_iL^nitcadhyC&$Iw}1yfcG2vVS)L?8~S0c zKVN`nl5gmT1Daz-(xar~oeur*vDv+C#8A2RM|&UuP+=3;z# zSK<=R@U{E4-8nX~Ga8@Sceg$J_Y(hX8l_tmIQvHH-1rZ-RDHwx7ybF5)X@ig|Dsj2 zLG5t)b?VH6m7H%D<9tN+_;sJw@Lf|h?6~qxNqv8yMn&yO{|*mn6on} zuGGfyued{QUTovM{pU_dOuS*j#9(;Re#5`MalQktjr@P~d!^ zc;aC5%Gg2H^}CzMZ(I|xAz|2K8ZY!Q(f-NA9VLsKXp`c_XUU=H z<#n|)o8#lS&z|SYcy1rtnydl?@J$c~FV4I#{@&Kz?bo*6zdLsDi|o_w_)j(d0 zOAh|K%d6pP_G#L@+TW9#*U(U2<$=6blGm-|)mU=yahF%)d%%l43|@h};G14}jSA#- z4|(k-uZK$hKla`~&Z_FV`#*Os$hp7-2Sh|=hLITVfR-pRNQ`lqi4icr6pcyL0FoaN zYArQ3POQz~^l351Z#mW0R`UZSX=X^$VolnaR;y&%r>IE-+NRC7zZg(+2a;B5+lOhK z@Vr0k?0xROckT=jF;DV5{xPq)=bXLQUVE*z*IIk+z1QCJH4m%*YUp*fqZj{u9|fzL zUNZw&{lIz#So`btZ1u46!0Nxs(To2ftZI7A3ShkmtbBgY?@!C``Tsnu_N$_?6ngdvK@_W9x5LoT`J-2yST`Qm$FpORSEXLCadYv7>S^=yzz`8lVXRU|TeqBy$G!QxIGIztgd%MFJKtG0$A9c5%jvC4C~p2S{%U21M9_n^8EgMQt+_yz&b+y3&Hv!|2@3~ ztD0UH2e6*WC(rc*>*0LzUo(!}H;CS{+($3UHv`tc@gG=PbD9UNrO->dnH-8q5gjgl zY`>+O;j{ggKBlbwMh6$sbMZ3Dqt{J$_M1N4AYHlZJ4ehesom}E_xBoX>3U$>v*0`3 zZ_jE&&$MCBYDdqsv%UW_*bbgKXPmVqU5=jCU2XTU*8&8bAHjR#QFp$jtiQeP?iPN0 z8(i%6V+6W<@L)uooHo$qrSEapo3h$3s#s<8I#+%MG$Xd&Ix~1Cw%$3}wFOSv`=L6s zeJpueS|=*U$7qN6eBh&0=z4g#?;tspzSr9KY!^Jd86K|5C;!9qa6kEs{soxg;Xm-- z@vsGYL7TqJMl}bvh;fv`Tmj5>U@pujzvyB99WbA9FuxtZgeRlIM3-eS=KymWF!TB3 zS`YInVE&bZ*&o1!@1w%Ro@6jztV^ETUza@pOkMIe5A!i#{+WaMCjm_4*2DBRyhLoe zf)7(D5AQNQ=y@zYFfKD(`oZO4aM@Ou%<;H93@(2N4DsR1{15rSxU9(sbYlkd9$ z^X9tbH6G@dfVs`V{CogYd>9QT_9=t82AC^=*;TVE#q`Q+#kRGd{TWscbw4ng_<+63U_O&WPXhDdT=EqU^W(t0*}=RifGIwV1{0qngSicu z_W-jim)z%Jt_S8v9LzNVOz~kfnD~7e%$tF^2AC^y$sHc%N?=~=U|tiz6dxSSj1R2S z$Dv-DK>3gldLD}p*v|}?c5qn;E^~6pN{`D5aCsLnG#)PJe>fg;qwoPACWAQ*n0a8n z7$wU+%*%k;?qFULz!V=wgNYxR!Q3Au&pi_*&-X{k1s>)_z+B{DE(~Cb52L}vm(O56 z49so7yeCR#dzcG=Ip4vY8^9DF98BYb><>2UEEn^aZIqokKwh`dK4$O0$=k^69eww9 zGJ6-;%Ez$1x-&wskJp|Hp4n74*D)A@jek9M*5*+3fqA>l8FfC$`ho59_V`5G`$@Db z`W?x~m3b@k6yb^bb_0U&SWk+eT=!Ne3|L;O~4yJBb$qAZpnO7 z>rR?Cx;#0|Dakv-oYKddmxc36!C+oln(61_*Y|Fkncmaw$DhVpzq=!9#GGWVu*>T>bbINO(Q@+3V3u~AM-po9(E4SxYr!#j0Mo*V=#=YP9 zu>5BX+MJSpnhzVoLbp7acd+gO);3^0oZGYB!(!gLojI!c!4*ypjalO3!li~n^QVi*y!i5k!K}%O#)pbjDvea1$`a|MmQLbguBrt6|FD^)T-NW*0DT&LyAnFh2s!H4Y}WK7$Fp zi^#h8lIa(Clg%lr+mVmx+gU?9D`=-Zm;9n{=UUp4{~+A4<5@fMp^!JVA^lQ85BZ25 z=0af30p_$^a;=B?E?{2nU|tr$6z&e@G2t%1%D0oJofoma`=exuZ>ODh?u-%HYkz)Mx+3!@ zDC@^__AVIH@-cMRkm}gjSInSFe~j=YR5s8llNt9m<`|RSmoUFYcm(?4c=gM_IbUJ; zwiV`Z&3};GhTFOtiCH%ivu-42J&Tz2tX_1~ zVfDq^{U@AXkm)7e1!eK!G&f?m?x9eO!QEd`q7Cxh9VW*d_WVq8RPq~{?jas7ofTbR z{XJ~99sgn*zQ-3{jIevy&}q3nzX4wjM*DTxz3ZIaBWE4@#cVr#k*%tLCEM;{&B2B) z1Xg=)&&ND0a-?l1FIsB%s$e1C6|iL6J**Wu>>lGB{ju7^!WYpT#OxkAqyjI-c?B%l zb_eTO^pBrIyi>9Zol5AQT62gjJ|!8Htidm2;mS^QSxt79qs1=bB=?F4yk|{=ne5nbejl$&0knH&th~TKh(a;ZSVSQ zua$9eyq^BgGM?at^3KAyREIj=G3L6TOZ|%QUOLXbM!oD=`=H;q)}?V=Pd@5=qVcP{ z>bB;a4v#s0yRPqD#<(rs9-pyYvO#`B-EnI=iZ!BeOlys-M`bwA-2?vm-`#a)8CUdG z*L3fnd;l21xaZrp?B1GG=DPE??sPat=9D{FcaKzzdB(JI1%DwJr=Nl+meZIqs=Pjy zgOYRV^4siALHJPtN8{bYVT^up4deah+@4znhw-U-fx%&Jp!4n-9Au>ej`{HppDy6s zliMR7=fi@N2M%)r%QLiI^5NigU3XY^r2>xm@F|>U?_r#GrGCv-z$tx%z5Z(?XPmEF zSp`SxT|NV%Qkay1yeq$@89Xt$^a z?Jk0L=(A@7{q&Cw^cmeWXu8SrDU|zMi+0j;9!{W>o)nz9z?tJ{XZom0ZbgsdkQ3!< z@N%-+#b2_%o)Pqwn16*VOHR(9uQMbk=*@-b%{fuBRX9!q$0-iSNdbRdU&TB94d3<- z@+7-^HuH7puL;B}a>uT}`cwU-_3ZeT#%wLx?APr%o&z0(Eqfvy2gs*e`##M2M#|T& zDjkGP-VYz1eTM$QPx->@)Iaz;2tREch^KzcyZ%+s$@v@xXB%+fr+nRO1P2>62tN&u zcpAc~9`k0aN80r#oLw*a9Q`Us-%9LBHa@Cv;$v0c_8~j_;oq|>z^NUa7DmbW!U=wI z4kyJ)JPdKl31%=h1DtF;VizjL<5BF|u7CG-?K1q)I_HlbzZ~>*T_41y7}MmrEop4_ zlQUd?X&@iMuiB15t8^~!^n*X|AUVop$kUZ`Vi{c*)SxSJu^*XuHsJL?o_rKui>_UP z>}mXaI5)$eHSh;MJt;WwtvXMO>=t{%hfD|4Kd(D&-!-~Z{Y%GmDnH_tAM@&8amd9j z7Imilb^3IWXM@4BV2q_tb>6}BEB@vZx0ksl{a6Rg=*L=AMZcv}kiGrL-LrG(_cZ#Q zkCIQT-{=wMRjFL&k54YczV7;A+SgS71agO6AHHoo{?pO*kI#h|%GbIY^B*re=tKFj zHYV-2#%C}l^-lAgT4VAZ>iZaDQfKeCWBbH=gIy25ISWwDFpE$bIPf zC_A~!$;R+)<@+O*FLL;{aXrKNTvB5Hntb$_IY@U`(_!67RwBmEUayLMX*=h3UitP( z#z))p70;gCxH{ZhM){50G1fe}LAf+Hx2-xUnfp2JbfPcUBd>xPFD~!1^KESW?xv@o z`y_e1)aK%}ZIxT=^LRO2DqxpRN=|mL-{x%5gDavv@%y^Ttv$DKOTOt5ktl9%+|u7@-{IM#(aAs87+u)hsPa}W{2kV52d3fZ`njqhIb}+^&un6_ z<}JEa;QECL$#b8DZmu8tpQC?o?u_mgZFEh{Q&l%mS)nVPE;OOfv4eK0*_8!NJ!a7I6ajB!@&p8~=3F{sON8g_A|IB!O6dZlO z6gSK29EJ8CN9BwXuQ{S`|1}o&Vsnve^G|d}Oy~7=ZeQp3tDkG;B4%vrJ}mn3blm*J z{fvo2#9%n1>c%Z&(#uVWd{FwPcJ*EQfd733Vq^M@&x8}MK#N5B5r(Y>i9 z)svFXQS&PIqYKfeW?zXNv-c+b&H4#EPJgo&F8yd_s^mocGy1_Z_=s* zy$f`YXF3if=eo}n-(-k50{FY%>YMth_v)Masozz7voS#X)<5vslt26@_8Yr{pEneD zth+Vl3?y@rp#wY@JLcUgJ6G|I=jI2)(@HM59l6q?7P{*59X6u_oue7$=gC;m@UK}Yfav8>AxPFv4w6Ajr=XMg_PY+ z48&}q`h|~Z^VN&7g|mbC>YkDF)$Xnj9PR;b3${=>7_i%mx%ZPl_TKPkab5lQ_Kr3! zS0Z@H-j(a0G_3`l_3~hhKLIetod6j569A*`1i;9>d>B6_Pi~RyXR?7m^Ri?Eo}g1- z9t`ODa$)?K_0O-M1@`Ub&;tGZP?Gv=VpOz=)^60=Bt&i@T!GG}Iw=hcf&xw-v z#>7HdBN%Oc@mS;G-(e1Tys_|aP^Tge{$tQn{nuPevUEb|N^AhSc9i%JUF|<~?Fi|5 z<1x^+?s(`*TiRo!ex$ZFwVRTGQR%8W!95P)8p8;><|nX!{dD%PpTTZEnOQ8 zMJ=>!%%lEYDxpjKlW5L3ij*w>80@ z_UXM5bN0V`f;if>jD`G+!+PG%8CdaU6MxH*<3huorz`H3BkuNK{+h$vn18S7jFWk} zBlm6TI+eW`?>W3FioPy7=TJFZbW*$AbR` zc78g3)z!y#_c|~OYVR6o#Q#4czFs;(e^dHaP#8lP?d7h1|J&62gce-l~-q||hPWQ&X$nJFC>f?_NR>|M%u4nPK5Zvp| z_+)}}irOjCuEt6C{;O`4oDTRnvFb7YyBX))Wlk*X>fWV3KZN_nIs3zm=coO>?(B6O zl1w0PPwThQ=`z8XariVZAHeLPo_qy^-SytX*|Td0+*6+C%iq{LS%%GTgWaCO)^E)P zJ>8mV<3aYfX+K+wqg$SR3*(Tf@%%OaaY{4x;9liSZGPZr|G{yV+%sTbbwT&zbfHD0=|lFpdq$4!glgXxoY z-B(Wj0^R3fdgatq&ycslo*9p(XVT|M-Hc1|RPE|+@9osr9n*rL^CG32m_I7^dIx#m^9r4{-QeXr5`_w-^@`?~YIU#a^?n48vX zJW+ok^^u$Gc@fX>xW&G+7vv(I;S)MI<5PFnHRbQb#IrHRZr5U%t!wG4!11-tFirdOn4}E_=$jH9gz|9b|Jv|I%EiJ9($yMtk;U ziFRol?#^t!YrNXKt}}W+>0oAeX8)bjyML$q#}#iVtZ(yq{Uk&1XpnE>C;I4&co}&c zKN1bG_tWyWXy0Poz}ny%M>F0Jt`ScP2XF8?k9X+2zS3jF%k3M!Fz?WhyyG|T?6=Bk z?~mZCoP(?Uf5s2+K$kX@!1-_dJ8+brG#go9FT>EBTZzrI(`Wny)!EYjf!^WUuI2o| z``NEG!Obb;tDT9jHjBM86O!(2_-e>!bT)lx4tzEGZob+~d^P>%uP_}yt${!I+5~^S z-)7&Z%U3(K*M6Jdc1r5E!P5xYzvnT=Ci1=|f9hd9E7!>Aej7H5y(McNiIYcu^dtPX z>G*9|SNLsHwj5n%K2IOnZUl@Y-|A;_Hx*b&sTuXdVY*D(j_JPT&ji+rtsw=BF;KGhcM)S)EtjP=}u?TJUWnbl!q(G<^G0 zeYMZ|Slv8(eOG!a9YexhzYYFV8bj0ZF=iUx-JF;7umHrBx`cpXb zTzj_fJwL->OD^TZ2)@oh779h(PS)OOw#q8EOvrT)qL zsef>UoUBacSY9(Zt0ZcqM?s{AeoH}kvnEIBF!ei!4bL4FtCir`@OZBFWU z<^1_D*Z0zCYep(cg7FqDCnypJ1_0vs;=yi!7rq+ z?Af&i-OcV8oyN;oQ+ezXbC0YIerIhk2T>b(K7+rEp6{xpX90TZn~mXjF`uR%o~C(d zy6X?B{22AM2K{!@hT7_Obj#N3DQ|qdyxi_t@bTcE1?^r=yYxA1cl$B6yKSsCFDtj% zMw@>fwt1Oi2bFE!eT;4Xy4r;Qn|w|;-^ccHdk;c~KMLDxr#);;*vAdW*xpASZN(>z z^@-4bG@YUGD8Jvz+}+tXiL%~zL#N!;gD>BcSH3Z`#}D-6ryVX#M<3!($?go!;eWH_ zZ^hvj{HnpZ5wiBaUgp_-(tCsWPtpm4_)k6USN9IC;eVe0AK|>UjRAZn+8JB~9Ft@B zd{Ja`sUCbPlUw{v(Xc|Up-=Yxj6kmWE!isJFMaPL_)}}}r|_$u#jnztje)uNQgiU7 z@LRus5xx}ulyW22@};Ch1BI|uK#uUMZola(PRBnQ~lq6Wv2f#zer;U8u#!m^ozRlQxA9NuRLt_#rs7cPy4R- zgCD0JI@bF|dKb$t`W}9eeQSjmR~}~E^A5j=clvGRbe;tGR!)8qaJ^sD4Ic7~y1_Z~ zizL&?gZV}1#DBU4zo-k}pu#V@9>3^1&NFzwD7WVzek^C(h6dq-<`GA`XY?SvJuoBU zE((0MDUQ$WvPHz97P@)hW%O}|v#&Gw)*Nlv?{oLV=K^=b4*~~TES3*FPj|%w6W?pG ztw&9B?`Xr`u{K34H7!S*_HMPEQAyXT=A+|9!&hOCxCixBn*3zt#Ppt%d5wWq<}J1_ zfblVSsv95r?$>a+uRP{`w&(bv=8^lEUO~Awd|!n>s!n;8KIrB#bgt;5zrjm7P5)x= z?o!Ohp3&|0EPJ8v=yiKWuiG;^-JXFzcoE;{^Q?0`=yRjH?25(-=e<9Iz4mu6zneA7 z7bviqKi$Q?n>{1H$e;F(Xn)9wv}rB=UKH6hVpN6~F(KKz?A{FeVK$9^$flJhMSZ0O z^yT7K-Iay?qfdG4Wu9lon%O&OWOmHoZLM$Bwou=u0ZZSiZKA$S;TyW7`YfEaS;IbN zxQnLrMfYYHAHeCA;@cn4hUeRf=1pP#82-jI_wC2jZFXJ_d9=MSFVnwx6;?VfM#y(F zwz*oa@%4U|=w)Lnu=lG1d%w=hV3ob!L|&uJ-fy_%gxULAbTj-;;23xn-m%YFep37p zPmWuUAI08&DX_P)wOjamH-GHaiFWXB6@O-L`?0qdF^6RCNWO%j5^KRin;;yKoJp2y~V@A9bc;2h?V#4j`l#77<~&7q#=lf(-&r_`JU8_GBSPjJ2f zYcaC9%Uo{WBftigQ%b}Y2Cvb#U>#!-_H2o>nVda2kj^91dp!9@{&&v)aIZYy4$|Io z_NHX#0Q~n!?mKv7-_cEj{`&;?9sIKIvbhVL&7l89=A<4+&DXVtrTO~cyE;=}NPA7d z&7S28=~=#zzSF)v)4n~^p1(6|@N&M>j`>QoV{M2&vg^?K>$17zD0n=-@;jVa-*XVY z9Dpx_mqX8Y!5?Bd0~f)co8ZrS_(Lp+^V@yTgWvby*Fo&v0pdu5@JZ`-^25`y_WC9d*dDQVY~yU zjP{`)<;%@*<-ob3ocF1GIc$)@gBKO$rbJ`=SIE8j2hcL(wfZVP(0A<_8e9plz}I*O zzV-}W_6%P3O#AjMSy1^<7Ov%)c8u4wlhImjz_SO%>%7ZLZ~}ba>ai!EUB0WeD}P+` zSjWdB?<)JlgZRf9gEx$Ge%AtU))+*NjmOBb=P~iQl#jK>kbDCF9lzK3Li-tCM)3~} zKl$YvXW;b@qWvY%E*wXC4#$z6X~Sqw8%LXiJT6*yxp8#@XdTjY-5B$XbuK4}p1=5q{_-0OXLE18&L2uR*Y)`2@L)$#hVQ!Nj9{JHR=TVUC z_;YcJ@y0KuIU_7rLO@@8mc9|a!J#^rg7Re9xe4ao%1>l)wRaZ%qTCAo&~x~9@F^^-G5*dz6R%neUH*?-cnJJU5*k^$Aw@NsO}=#)jU_bZ{5D=R?tA zy;oid;lBkrsK_;-J<{O07aX%a&h8y+c=$KqD;>l-L21V4PshIs_CiOe<&$v%S3YvPH?hv<*dls2N~*1qA}mJs{* z`>aR8F6E-Hsl0G4vc8f77xFUPt9B!3^*f@Ue$Q+jdJpeaE^%#C!0s39I>ud;Xq*XF zF^VU4-`sSe_D;vO`mk$a)`vUJEcf9J4n8>_QeT37)yntK(vsSn1Hm3{@pEumXCLQs zO;&v0H|5iQS=$BCy7GCDerVl9>rB2*JigWJUiZx_FGOx_KaTo)HTXyd#peN@7jPci z>cB(Eqt5NB9j&b$5H9TD)43fh1Macx6Ma$aMdg~1pW)lu7+>Wx%OUMlCL9~^-FTGR zwX{v0Gg{zyqq6^HV>W=9*O<+-PZ@sXn+^|5VQl3`;lqVxKC~?=^Wo`lr~TYQJ>5Zd zr}$4>!edjNqo-ho^mWhj0V?QAeZ4C(#w8o@gFP$J)b1CXF8l>(Yq%k=I{P#aJ};w; z_BVV~|LdPTU4F)={GJB2aj13i+VO4=jGoVyY(yKr<$RG4p5$hE0Ou=izkucDQ$6@o zWZbKtx6{YYx-=Jf@O^{68%+9I3Ur$KE4@O|Hnnv;ZQH(4(H%HN=x#V@ydc9GFZOZ zA4VJWX*JKRPcN>#P`YdQw(@;rx{J5A+#RLwlLGvZlj`wY4CRe+>c_9-QncUV#%l@u zrI#l_bN#k44PF0@@gY4gyilqh5 ze**llJ@(anZ>1gO>o6VAl*+Z_P;yKx_^M1M#E&NAK>7%Y0vqA=NQ_-s>Ue8?;9289ywh0;!+){K;fA8@uj8q`mtE#r{FZ)> z>N=nP5ctaes81=M1D#ma{(#z%tX0`2#{UaZ=fs43M=!{})?LzhWtYxZU|;Y4>r^L7 z|H>A;^~jO?{8-)P_l-ka@l1GeWa^YkxeM^=s%Ov?JSueIE#_qsk=J*P*%dJKB>(v9&_81X!%o^*-VnKAfySnC+Y7U;z-FJ>y@Af% zP^_VIE$<6uOB&-2AB~l#7{k?cvo>q#=Nd9+ur$VUbsL`adq@SJvFQ6NS_tgu50rlNNtf)LfF5~QN-KESr!wjb-zw(@ z?dhDwWMSvYiSc-PfYW&kl45gR8K)($Pl{&;&xg)SiY@80(WU`@oEv;^enV0`uP*Jw zEcbtAU3q>~MIUrCxI!cPc}mdFDC(SwzU@0H?Spi1-|vg&yt97M$58%i(jAybs8dZl zjp?H3=xFzAlo^v|RXBTmOEqB2K8YW<3fIwi&|jWI$v)zeN%W> zx25{!M&v>8uW-*B-1Ga~^DXZA2TRiO9q##%d%nGHNcgm9yb2DwpEk@dlm3eT8~alj z-={LtV{zfqz5(){-LC%e9Bl-i-fwKn^mY2aEye%8JD;8f{sl*y3fkRTpKNpe7LO%^ zlA%#^Z-wIwdKxW|3)8dcFSXm`@M!{Pyg|sAj7y4r!SlxEq_{J9e(1ua_?H>n-SN)1q;S6#!2MeX_n)$Q zFT{r?CB?zu`JpLE@dv^4YVbYe>NUuwopye)Axdf2QP)?F$Bg5A$P{eT$>a+iN6dm; zB8ojJhZg_i9P~tvw(xskO_U5U9%Zv7U*rurJo^I4W@L98m^{pWjmFaMws99FO~`}l zZ9ry}he|q3cIfwcKGI&leEYIx16`HvD?T+=`}eV@c`O_CuTMqy4&U}} zY}32Qk2%hrm$7sGLyBu@USQ*hKFYr^n~Grhih&BxA8Zh~iOSMx9VAn}dk zH>~n!udoq=UD5fPTh8`tF}$-FO0?yd^nOe5Ugwco-22(gMblgu%Flgi-*)768N69e zuJ-NVto2&$Un=JCtA#T0x=B;}-=t=${jEQYcbIz6bdr`SOMX!oQCG47YcvoDl+_F!9?XLZ#)n>lVn zt6%exU5AHz10Kf9;tjLi-L$g%o~K*7RP~PeeWp&{lIk1P6L;No}tET$oH$N=9 zYV(#W=ufWk{Nfc+pX~pLwwq|P$<@J@c^i36t+HoO_6%1Rdndd;R*3HPb(T}dc)ejH zugU#r<=0Z4b(lWc;kVRkV;XHtb8TQpJ?w=ltA5G8Vpm6NM>16$0}p-Id_}lR79Zt) zXw7k2eXN5qMQ+57LPIoFZB1-`;&jsw%{lhTqpSEfX`Eu8Pn}+PqJ=wKMBjwBmB;cb?q)6H`STs!hP za`-NL+tYQQx`~}n_d*xNm_)yQ$Vi^Qm!>jrf%h6WdN03X@+6)6kk2y0p6re~XULwU ze7nnHKE}6yAis#&6V+>$Y%#|O)|jwG6?Jb&>+W9j_>AP6zAo*H&ui-(pMli|F7kck z_uusrdBo#r1M`lnOdct3xPX)SN^d?b`I}!)=N)tCkKvOCpAWTm$bTsg#2wbJfu$+$ zJgrowp)D=*9A)%8-8~P+9g6*0eQ+r9-G1}lZ~*S5;H7c1G#9-PUs2CoyKZRYxLJyC zOO%e=uJ zjaLEuJATLD8?RP7_*=lM5#DqLI)5c+i}hYIG+VqPM#6XFm2AQ_mV*Vn@QG4AQ#WKd z;1AjJbUh;j=%4P~yKStSzMRE#`>bC34ZgZJQnGsXpE!T`;<}-k@W{Tat}i@&O@E(xoalSd z{!9KRS=+Mp0=MY!WeCLJJlG}QnE>U{{9;>r;j!Haw z!q_srcKA&)K2J~iywTz6F7Rk$M~HV*84K*N?-godXl zzx6*-J@^UEIGgMWpT+P1U(Lpeb}EIfPHA_^b4new%FIn+@XUNftugTfw*4 zXC}9}Hm|oF0JPV##C*Dz_tDl^b$|EFmf*yrqlg|ByJ<I(QNXWvy(-;SQB#bEz$NMb&TfJnMfVAUs$^7>A~EVe}_(Y(JuESK5_qGK1$~2 z7{`p|B4fFNCtsVL9Qw6X2EUu(?DQvn%=x>>gg3MnO*0(`FP4PkMc<*1*L&jCmT=qz zFj5_q!YoinI!E>9qmT7}9y(BXO9vIfyOf`_UAUL>6So)ZtNO6z?BsFR2mG}(4mXPI zd^FQRY1`GZV=_a(H&*p)L^;V3;D({Vdj;?~2 zt7=#DJX$*&T|4VsJCF6Bnc85dJK%R&r#YW$XV?yNakbIx-iiKeH9jwnjF(IGdr8!% zeFeg|iTC!OccG3N2w}oU!5r{EB)8?7M(5;4*FiaUO3=u za11PNAZAJYal3zRo|MK8i9?!SLLBln9!KiAa+|~0rQZ42rLUv*rGrkMSm`HC7c6k{ z`pxVo<#O;#{jWnGomW){JZ%mflc&G9XPoJ`w4Y7Z&vb4U_?TUa8Kw6;`8{@u8ExA? zEAutAZkF1^wlt1HjLM#;yXRSTw)P)i+%~ky@5RH9Tj^+_*h>rFxOeP+Vn~L&-p%7( zf!rX&PYEsXPi%NFzt!i0vyd5=kRya6wMiD^?nXpt@oOneR6{4jMvqgtL%t=Wr5}@ zJ2cndcgW@vn>E*e=l}F`M(X)_NaeazMcul8ck`S_79^MWx_Ro_{EmA_HNVrd_ifxc z4||7i(*u55Up73QzRGzWCfuFA+UaCZ<(JYo=_{?p=y|Ps7H=+){N>a3OIe=0^jZ37 zb*8s?NBepg!Y(>kX9aLHw-`~6_(53D<7BZ+*M7{MOe5-XUr|_ZlWWg%UC6s>>cA<5AP?=oG<*SK527IErZagpYX=k5deWSiOx!tlEip51zI){CTo4G&iIBB)U!MB_{juzI= zGUNifeqL2Ko z>&T6!wxWyE7@3u2{A6X3H~B?AMy7g{@6&o&b&SmFB8w_x{Gr~%UoOM9{;Pf2-!Woj zT1PScrSSxvYQ@OHGCqdo>sSnHQV_%9x3xXV^-K8E=dogB)<;*S0>0)FI_t!q8rjJh zxzlfh&)y*4cj3p`v<=@V`>FQap6R-ksm=SQvw81cl$^UUoe$&N+FdEav3Q=Nw|-v` z_36GiqqFm2miY6IqANax)xj>C{5T(Gz|Zx8;eD9MuS@71bPnaw>eiSud7o2#W$X;C zrthDtu=h>9()m^&m`3As!Mot_0cQ5DKHWPeI4Yk*Ztkjrbr-PIRF6&ic-zAAqLImQP}V{g($f}ev2`d{~s*1lU$s-&rWPfw2~=D4ZO z59hbR-tQ`1ZaUHCIc~qrp0{e=wBcKB4)9oeBe4tSbZVcuqT12D&05Q80T*n?`j7hc zZ>$r6z0v?dx3*9CZKk>F`VI=bRH+AFk1O9*CY1^ej?N>w}_K z8e<4~P+p%5?QlBxY~);+Okxi7U+bsDFpr$U-vVem2ilIbv74h?FO-el zY-_`3ZM<@g_R2F~{Dz~2e855KX0Zq2vi{xZu?PAO4leevxh=XdS&eNpIS_8x#HDrV znt0W&#Zq9~xZH*|(H;InM3;{A%0C5^ow zbYsTG4fqyxekK*vl&yxTzckF z-wL{qOy#&Q+;aEn`}kh8GDgPJ$am40_R(E4tc3w>T7W6L1yA_TO_Kx>C z#`!yWSK@aQdwuo(`!D|JzKZ>J`QThv7kfwAo6yh1W2GaIDf=y7+{seh;r4B`ujI@W zd$3fV-;$+l&g5h8+55JR7W7}WkNFKhhO5eDexSij>zXf!9msq^ew)0&zqD;v4m;2d zPWrY5xTBt7Q(uwY>U}a` zE9JLRN4}-EOMG9#{JZ(Rr=)i2SEeMNX3vD_+%?3)kY(9=wRz+sXia-&|J!qm1^W*d zk$+w1W1u(seW-!`_OpE~t{V0WCnvW6TeMN#0r0qBRr*}9C#}jaRC%kDXV2GV(H`RM z6@L5=)$bQSaA7>0->};8Rebyp=VQrlRlWZNH~b`v&uK3UJjm*Kz3%G?p8T{pm){UG z4_@czaPr|A@*5s6`viUQ*_6TGTjuSu%B;?BU~Tp);f?+2i`S)P3gNq3DC1>QWj0dg zV%C>kAFSR`euHp(3^$&~#vaJPfwpvB7Tx1&q&BPMSzj@SRnwfG8J?m8v8 z1sp@Xid*YC)IX0)@r!jG;;*N-bgJZ73X)y`pVsq4cYUU^I+vwKc z-aI4u1@64Cx@u3jpIZa>@vO@NdmsBKgumKRZh_9A58Cf!_^7PFl3ysyDnA%MU?L7N@XzM_wVdVb9_f<3;UwzN=3uuYZA6xR>QzY?tuO&Tqh@My{!O0<*(6q zqqXo2c@Vx2cmQvPnvh4u=IwXNN6TF!`s%NIKBeq?W#MPj`6k{Q?#OkvugcMN6)}nEcTY=7e;(cYxbuf9%dS0iz>N{TF9^md zTb?eSo65JRq5co@-NrvSSFZC1^4nE8Ka|fjm%d1rVx8&TIl<1;R?M-g>WGgzBYcwX z6tdrpA^w++9H}@XY|o>d5x!LSq<25n3}fN$rQw;T8+`L3(P&f5^$6!ry7@i zZf+&mrHc&yq!PTgx{5ifEsZ>i&bYDn!8n5Uhra)OdGD9O=wU3W-Mbl&=mL#Z zWFy<#CE5QSYzw-`)_V2L`Z`H{Pxp4^;f;J%y-$6YW#n0N=S8Y?lEnhHPDw02P>3u} zU^bxPbxDzUo8E7lj6XSRe4p8=z4Mc|Jj(pt&G}0%2Z?-~nD-Vxpsd=q-{{h(cweFC z;U#UPx)l7S3pY>(86zH)_9u;LhBm9l9>jLmVc?DV2AuPhtSRQKaRrJi~^DG_LduO0w&~y|x-I^91c-vserFe~p?m zqAD&cJQZu#fB9*}aj8FM&tFCE`{8GQn!~AO7JEqG*+H+r)W-|jhV(r>2SScA%J_32 z*cQe4wQu}|=8v6|+LeDiCt1^>^X@ATe;qs}EB?Iu0iH#JvEqJ;Ba=(A4||=___Tl) zG3zYyHI%2t`XIlopmX`edD>S}m;0rlx#l{G%Nfn_M=EH36rR2Wo=4;9J>tP}^7Q!t zF8#253E7x*{!JHUN@Mw40q%Z0*jU8JG1)+Va;$f2Eu1rf6)~?jIr-6eT3_`|zPDsg z>)0i~9xhmv?VzlEbNdx`I(x771ZxA|MQ8n$VWfKpRYovAeiRrt1u#@+fU(2=_zL`$ z%SPY+tm=I@hY$`U=8o-d{)Rjle$6BD+3bjS=9!b$nLiCrc38fOhT!=Sc`~L4K5W1T z`I%mBC6ki(_0_yao`t{ci|j`zuXdl`SbDfdTfUtus@q}gXpU>`(57$aCEaVsxWETW z^$_EvVoY?U`5p#lly&9cj85~Z6bJ4O@?JG`$?{1~O#(FHEKcThCiBNs5xG^m#{o zsLo_cygJr-qvTie^$h&RnFfEqszWz5t%mH%3g?O z;(@1iymd;$KK!xi&^yav>+@Jrw~!+TugkA1Sb8@9=iJl=;1>_+PqHk%?)8l5*a9!H zS$7%j!P#hgJ2^tYSN*d08`Jkil?4~cLV8v^u*0=zQD_^om<#s9>f#rwZWcFjV@AG( z@4w=Q8ZV}2a&2k*q9wS*>qoD%URy1@qv)(h|McbQ ztX)oL8E%ZR;&JM&5%tH=U89xF=yA+31?DfB&(B5nnRmoh`v#Z~?2dLVO3+7khQIC{ z+c#im_z(1@I?w8z=jPbjJIMHm*;it7Zas6}$N%0=8_St5>8wu+_b@2;tbJRC?pGe# zSy578uW-c~A@j{04C<7yjk4^2HQ!G2Ps8^e`1<&+6B}GC0pA|KFx@As-}U@P&e->v?FSpY zjQI78G)|zpnui=&=-OY{sy&AW^P@i2z#PZo4A9f!JjNel4;MkJF!n$_i#-6t#~!-# zXCAgar$Kz6MEj+7*Iv7e5AaOCv-m(dhizS~coO>{$iZ{w;iBRLb35^mZGLOG`1rtB zFxUC`z#`Y?BKk=G)ps8s5X`|v^hYv7JfgZ?)4kL~o*GKPvG_n0Ei6DFs)~J0YV9MJz0I4e_ui%FAg@2{<6jn2s1eK199Z*Z(O75JOr~ATB9(jA zfEZ7gfbU41J$hWh@4=CO@D#eB!aqRvYx#vYQf^GYFz~ywcq-$>>+*+!c1D~3uAI_boac?=0^E6&cD;;DHW~80%ttcXG{BE@(`V~b?%W?cPw4@0_hZoHi@s?+&gQohTKj%QH0Pc4 z7(N~Iu^^{2zNOET>wRX8>%R?PdfI_!#Tv=`k4CdmVE=gy*god;PT@Mi;R@~*xCZ0Q z=4R*z=@fj2inB51yS#aE=DR3QDSLx=uOUzApOOE;=zy=eRld!t(=1QvDdQ^hl$zf| zo>KE6$WyxOW9dBXD$!8$4#wAA??GnxJzAd93K--m{SybH9T;i7a-PyT;AQg|zZNQA z`0BQyLHXi0)}?ctE8O!2_xwKhe2aVj!IHFmhkJgRc}iEPf3$xrc}id8e75wyXj9Se zTkDe!*KhGyv@eb|4-Lnerv>BR=x_o30-vUh?mu%RyDG&rAW!KF@g8zf zmh+Up5D%Q5oy$02^dJ{%tvsdDLt&oMJ@YH`lx`%S^0DM84dc7Sb#;%&z8SO%xEKVLIhnydC|Lo50Yi&?*TJ8H)Zr=IGmtv>l=~BN}knbixz)Jo1`eg9t zbnG>1+)&omY*@drm@lvt_Y=G;X-93`#9oYS?ZC~EBXXSSe7er6cWSIn)BeixnG@o? z_v-wDWK=L%tG8##YZ~VZa=r!oCDG*-XX*W(e7|lXyQ{TZtqCfpxN!aN2HMyBVC0<3 z&au<~>T8tM$Z!KVF^qq~2`htAHV z`}Xy2r}G&M7YFOC08Y&Qwbj9Tqn(`(&cKH_O$+M4qn6LWl&$g>C z{!i;K8E%eNzMR&Xz6+l_v;9Kp8F-`JA=XFS87zAy7Vgi$OGcWt&hhRUl7Bk`zw?Xu zalk85E<6KocpXZ4q%-ga3tnk{8CRcymz@mGz+1oB8*XqplWouJowjGrz#A;)@P3Tg zGjj*VX}Yhb8qZbdCr5rs<1{@3Z}6(lz^iY1Ke6fzd_{jb1OEdDXAksMoxwbNgx9c_ zE0>-{f9t{W8F=50)?u+LPsh#V7$HX3jqj12fyXAbglFLOd<HytRSfw#WE zlj<|@6@B3h{GYnM=saX5E7051S+eB&pmRWboje~atsZpne?5R>u$Lhh&@OH$pMke_ z&>i|d)){!;w_0c5EBeP7_&Z$tANK9fa`2Iz(aykU@F`P$2EGD5XW&2T;QKT1)`yE} z13AjhbNGGI(r5a1qWZ@f_~ovBe+J&hfyQBQ2HxInET4hbv(CU$9 z0agD8Pp;Grr%FC}UxZ(AF3qWG&sXTV@(g_TJ~#s}eWSBRv(Y(>gUU1T#1?F=Kd@Ed zoGb>nbiFvp*;?gmXTGWIseDt}G;Fv0JapQpEJ zfB&`A7q@!erUkh`tLrKksM$1ffj;5u3KwYPbAf8k^CohY>c4F5A64Z7b^hs&W^hXN z>uJfJ4XJ;jJ(D&b@iEL!0zl(w{0L{i$c^Pd&R_p!QpKMC0AP7kuIN z^WbG`208qPQFDQY>jsti+h0!Jc;f|m@r{T{rXSE#h zKY_gQ3vxfZdE=4s&B_~(jHkH)$Q$2|o>p#vKXYgK<-=?`&b;vkkG%2E2QYpX^2RSm zwxo;Gy$C_xTkYP&IEir=KMBqw7ASM<`=Jq zul(YstMLDpIUeYY{W+ZHFVC~dI~n8`KmWg9`TXMbTb$o?@hg*G{DZ$&hHo}ix7ys^!sSN%s z`Nem~8_o>#i|>v%&Pvz(j+S3MSaZzsuLX4^C-ReSugXm~o%ct}FaEizIx%%Lj^ks^ zFP@i=IiY8`KWBFnjd{kgp^ddY@_^2)v$Z|qY3cJUJ!`L2Wq$F$5&qy}`||i^dj~DY zSNd-B9A9o7l6^B410%oq+RwXKB)PE+9=1_B%IC1K_IbxSJK~DO>?v2AmY$VV?h^aX zJr;`L`K5F&K-!TW(b>MgV{ck>*iX)mZgh6TXbx?|ezO0r?+9~cqb2iY z)&j)G^-ubBLiJ->XI~5X)#7#QE>vE>13VYk&AZUov9^Jsy^eb4|FW}!;C4J`1r09p z0^CEAAAGPw-+UoG8z{Q&a{GrRFN)#ciA?x5t&cM`4wR3`je}Y4d3yR>=xOa!xr%dz ztO5F*@sgwQk{^GrkZ*>Q)&xi7jK8esNZ#K+_44xInq4Ok?rJv=R~}qHKm6_=xbdbn z8^!*$U)8Pm+8ps1^We5JuUD?!C0aAp9dYErwKiDye%!TT@EV|zyDQ4%ZWd!1S+U=m zpTcj^|NhU|-hfvu5ALDgF2i>`cr_0$W6b#%JDN|Mk+i|fHuB)EU!VGI=-{83Jh)qk zwS=*Vmy-wg?kZTyVI-Mp=5H_KM(bO@R#oN>zWp@h!Top@USs9K{SC^hKU#BAf8=BM z{%sDvi5@m)q%&B9tm#;V(nd5wjIVUC$?%UuOKA+{GV0>RC zUg{ivbspTSD0eJ*a9QizT;98_J6L|aJh*26$oHDrKl0#W|8^_Z9ep*Wg?xj-In28& zeB|`q=st2e53cEB&e41x+o*oqoDqBa(~t*u`{k+sEI(>#wukTo$~X8zGjuWB$%Fg% z>tsuQrt{!-n6EN=9^4MojdPvcbFS-Xd2k;`M^?@$UfDdj&%i6;Xz>epVY1}bhu!{^ zY)okGwaSgNRgCGEn+Mm%33+g{aY7zk8z@iXv-Tznf;4ZiyUBJFG z?aPg$&g0I5oBS4QXe1brz@-SKCEo*yF)oo`5)#y9q(ZIoDWCVM17C7pWbWh zL#*F-cb$INaBP2nZ?+zW4f<4;Q{?@JEl=KR(1_-Qs;oX z56EC!tnGfgi^|~Amjjfuyd%`{c}FZSOV_oB2iJ76mP5`{*11a80#EBYKHo(bknkJ_c}Plg$?HOXn8CS`bZp0<)>(5=M^F9%a-5=b9c-V6q)bkFMSc+B zq(1ufz#8oxSj76^_=$I^UD33($oi4xA*sg2=OGycc4>{lpTv2!bd3!fL4$@8bpDcC zPwa+Ade<%fi5KJz5&sgt8_l(zi@a?0_%DQKHP&=3XD#0h$A#s!T))=YEq*MlTI=LF zTkE8b;RX!R)BKnk?PP1mtjE^6_o-s-nD|r0+A-_Ih6nGnwPTmV3;r(7){a?AhTe;v zZCz|@$Fj4;yDHX>RZeTi{+rg0_0F#y(~k9NZn}0X+DLAT8iQK5{R!oM{mMV5>$}oN zTj9eg=o}lL;BqYMwZEsF9Am84D!+q=J^Z%l-pZV?!Cj`oIWE})&3(yDHZmvd>bH!@ z32VL(Ibr+0#9Y?#tQ6#g?c%-7rK@tnzOB2;jSiFuc`dLniCd& z_Uk^VW6udI8hU?Ww7fFcrMxp8k)H7j&XkSfhkU0R?u2qq*foO3vt)UM?-Awea>D-enlvZu>%mj&{{Af6hjbcD~SE$D4Z(TRUpb(2c2FmviY=wOy5ObVS=f1$q0>**lcC&&CDw zSLN+v{%ScSULucxw?Vd_9b43*Jbgc9dHZZEv)4fkICDI-|X`Cbqvn!WIQVOU5bnMmrq#UKH$nfuWr|PQ{^vL?1Za6jHy3AW1Hv3r9yM#H^+EZhS-ndK|fyv66W(t2}88*@8% zcM)R%Ik$6i;BEUNyInkpylq3j{rzLR@8~Ydg}KU=bKS-zFh;xYXf|~^vs^Vzy|1Ir zZ2r_Pa#FFUZLIr_%>HoS(N{Rr|G3X_t-f&XBfT5xmA&t%#2Tr5zOw_~jV2%80LNpM z4?q7IEeHOe4Oh}H%z=Mv75&5y;aMvO{@(z{zKxOt|C@XlFO8oWjLIDNx6s~LFmB|# zhoLS%zr&1 zUdsJc9}xe*G0JhSp8x56ROQ@|_B={%$j?%@LjR#ZG9T6H56cb7{ZuoKLr!eJ0(VPz z9nw|Z&L}?j^Ed~W7yKW(}1|D`RJBjq$0E%$vJWfZG9mfZK|vy%JX{6BKvuV0nM zUu|!s+NhQL{-HOevZU|IeV<$u=Dyz?4-nUwUU$@-27G zo)Z22>JQ{j{`tmSadjhdxjPze8;;`icW#K^7p`u+`$3c4VZrW>Ze1k%LZ61&?=$T3 z!wyHSs~h!f-}0@)jE$Gf4t1@3sp6iIN}dm+JNt-#4Xf?k%=Y1E_UgtjyZwcwBfn|) zVvuiJ>zHYo>1i4Ib(P?kj(pzAoFA5HNXxv#t#7FAF8YvbU6uB+z<1xr@$JJ|-*f4E z#XQMpX#0gludMC*6z&%Txa#*q#|c|GE$Q3TI2X;+y&rknsEiW_vA`Pil0Dkx_-eRC zw>Aon?%dR~`0x$!3_j$d8yc79q8)X2whcGOH#A1@S^O4XV^`1kWHHX5U1ElNSu0}g zcu4CzQLgpT+~a4Z^t(8vliugXw?2B7d!Jj}p0#1$3cf2Ue)O3&3x7wQJ-v|zU5B-g~ke*Z7Rp_ z?EB+xTshei%{4Ynb{U^K>tw%YwDwv4IM!PBPOH%-sb> zrYAYFHd(hp=12AuyJ~Int!A6}W7ej=*J_jR)@ERbvA1cPtP33>C%V~zN`1*1dZpgN zZVqcN!@z_w^wy;*uT76E;WzTVl3WX_D;%V+#>iP+sfXS{{n>#Y`eb@PkMjFxx?ova zW>awH!0opf{;Kj*ROy=B$sa1~Sago`kMvATPTb0K36*1T__jP}blGp4Z+eMbzsRH3 zrB}YRl|SJ);My1e$fIj`&vt95rq8c$A68xa{l0efGo=S*jaFBu{dms75p2OBucPU| zrRsB7R(eCa`U=+vT!(giL2E=-ocut)~P2|-q%#lL0oYsK>KU_P| z^IaXDH%&?776bD~ju+{F^(nUwyXS0RBpKlS-Z|0m;QXpSi%#qnAgVBSJPJWMkig)<>7%vozzg zG~=_>VZ-)KiiVquH&}n_=#RH=d*?Dv<~aFA=A{b;=BCeejECk6Z)jY!CAxPXwlW*1 zA4=ufXtUbUqX{@o)RWGJ7y7;bn$|~G2Y9Ic=x+vom9yf*{tH=69klT$hHI7Q%; zJNYIXXZ4d(|H=3?$MInf_&gD9*zRyHA%}x{2acaYKDpQDbnP!GFm6m1zgvd)A;)*E zf13=ep7vJ&`v5pvJ58<~o!6qBCxdnbKTdKD>?=`w>yN7~)lpl(AEd1kZF@M`ev(o8 zqP8;He|K%Kcp)Cx{pHjd4X@Gad0u_a^;xisSB$f9uy;X~OfIaH$=_1018+BK$fK7- z@zeAN^1{7Cmd8=&<<|zf2K)}Lay~8&|5I-XF*JnJT$k0grX>tLdLZ84Yb)4HQ{$yXizCH#RB?b$rfecK*>0|(0o?#juZ79VuZ zN;+R{D&N3C+SK@#&C$JX%j+lIwVZZ!-!C~J`v&>mf?djV&ZLn#XO7c1(w}S4pHXoQ z{+z|ShWF#2tP18;5oN1&EchrcHhcs+3P)suJ6GIYa9zQDyV%REoUiG|FOP43&5G#k zXzCvmW8^&IOXLiBNj~XPXXkA_{n=1Ng-hSRz?RKCYYBi1>*4O`9xA~G_H@DuW z$5y@b&-72_O|MfY`%l{{CmbVJRx}a*75g`;_CsWA@yumpYql`Yz13*#;)Tq8^j@(; zKi|pi{!rR~?54eUbDiADtF!l-hk<{uw~?BUiEqWSf40Nu4PBu3j!5)|7E{GD+VXR* z=wxgReHx&CL?4Nj4BL0`)toGX&K2Li&kK$4nTOS%8`U59ue`4sTg$6(Q2ROAO6>Lx zuB_Th-@&$$GpZo)t}va%&o8 z<8$eF+Y#NE`YQv-Bjqm4@!f1MbdgU>OrtEH$lI9m>E+PNCv=j$ai{38WHkr9^(_Cu z-or=HaUb+I`J`VX0lD zQlI+_Y)%!-lKbYzKz#jaE8-=EdCZynqFmK@2ziFy-U>cFjJ56my7@}^K6a-(HVoZw zaVw3(JNafdkKF3AZ^B>p3cYT=@NDH!d1-OdtTWRWz9~8DUplXx!|ye#-jv+**)+z_ zoJjYwywJSrjHHcrb`AdMzE-zZsc$*Pb@Qs%CudQn?YfJSUwMBTyZ<0<+4l*ZPhaw8 zwkNGdEY9CKb?Nx1Z##Ya zvg`Nq+@$p_(?5T@zAr1_3-TWxZ*DnnR6yfzMAHAu;&4u9}1p#&P|q) zJ4^W+?E8{)l4aiwo_D@JS=JXkH(!+K9-gc`_XjN_KZJYU(b7CFSvC+n=O!e}xSvOP zBwDU+8!~*SXZYcpPfV6wU6+2p!hN3^eBUrRS$0JoccnM=);ro7-I(_c=F>YeDtIyO z&B;v13-Nu#T{gr-&}*y#;+qi@&-OmGr|TB8;X$@05$a<3431yv-GaLJJ-z2feM9$e z_Id5)w!{N_6gsVwewd(4T8_4T-S&96yiR`T+(d~`2AF=!LkMwYc%rk*@fR(-qOh$%gl(Yuc5u z>A+4^$(?e@vEOiL|0Pj}+WSlw^A5K*hK~Qba1t!-XBRG}3+kV|pE>0Nny(<6he{JZ ze>(Ea$cyMU=^VAAUd===g*=b>rX66bGRc% z*mCe{?a=+v$duhn7wX)#u1$1VDktu4PCX00@FQ+J^ql4t_MG0Q0nYf2t#y%JlgjYh0y2>@e-*9pg2f8X( zsjGI!hu)YJ$t#rUiKFQ%@;pmVXkO}c&U+`F_}L#4^m7K^8eCiA;Zb$Z$>*nj3cBaY_ojZz%nUyFwd5Gzj5V!Eg!=3* z?9?)JMa#D)Bun`p_f1ITcf`3n@2{}Ez-JG`=C-{jC2w-@MUUehw;#UaM2y=w(`#qF zzdUY-TyB6d$L+U9(QD+PELHiE|0nd?A8vYi^fABpS)nTKWpA@{+RYTU|X;s756e(--`vwhV}idZ(HAYtRWxHFS)*_^;*k!)v>>zfPVZG z<6tdzP;-qKpIdvcinl}^`XARZe%_bt!BS)?VW2_`t#i|GA{+neG{X*`5p7Sbu(ra(b8J-B%Z5r?L6TGJN*s-0yLKy6BH|PY}At z`*O@b+&)3}VB+WKju`nD@+~UY^2+N%NBR{nIjLv3%jMf;e)u4{#XN3ymjiILW)k8T zdHjg|w*+|4#@20=Zp@>5bA0pnkq}qZ8iCzM!d%SmH=$oKF(3S$A^gZgOR;+gi9@o+ zwRw4RYJ$E$d0EGoi3=6(igHcgiMb=RyM0!#WT~_;>YGD5k{`X3?C4#i-nnw3i{6PA zrf)fqQ_Mv}ThHpea>ZZ&=)P$xOI~8t_hnzhJC#@ebGA0d`8&-I@`deQXWN{0b0PWm zds18Q4p&F{{=;%hW_Mn>n0BoFg_ST?&+EMMe7+f-8?;{aZu2cw_710~6g!TUvj%>f z-i4R4&BZU~jK2pu-Tau`G{RptDD~Z|XwTYPX}+U9b6ul-p|x+5yHnCXYre79@%4Xm z_x5pe71y2j?Ri1n5@TtQ1n6}%5?I{=4C2LTj4|^ffh0pfyd+={AY>8=nb?yx8z#V7 zLdFrsc<0)9@e8&k44aW`Z-xZN>cm+PGLCTUtdL{J&SO8(2q)>0>@1TQuV#(Vet)N` zZr^^Hk+9ipcK_&4->O@6>eQ)Ir_MQbs;<#sGkvFAx=-lh{q0TXx%F`Q#Q3A02GTVG z4&pTea5*S7NaG z`Hn=Vs8Q#3RB z{Mc-jz1{a-5?|`+^L}Vz@=-kB94#L5J|gx%Mmx}V^e$pvgmKoKx4D6A(A>y!w)YUS zz|D>JnzZagGs)>$a(c^lQDqz6Bv{ejO8g9vMUWn zy4-YE?j5Oef){8PwRDbdVy?fH_qTexOZ_wY^DgtsfB4S8g`VcQXq53Y8?c53r)A>r zUFYVw=3?M)wNvdE5&zEPcMiW!e%y%+{~pIZ<}aV9rXAp9xBT`D18;5B>5_@{knXkv&p5$=Qtm(fBMpq_(Vw;bZ0nzQT72x z57LJAQLS7H{swSKV1tXnr3`a4#wRptdv(Atx!c-cW$k%7&y))^xz+C(ize33mY$;a z^1yLa{Sw`@ez2#d^XT$v^tT7PeWW3NyQdrT+tIsKvU4?O!SN9QLu+^~|E2EUPRq;9 z_<0*sci?FZSVM$Y33+0DgcdpO7sodNZqdk>!<3rCj`!2ry$ML(EUa9u|m?ykIztsMA%BcO86TD1t<5(Oxy6Nid;uRBDZ2XXX(UUZG zi#V@#5Pb8T?XvL$&j$7n_xG@GxFCvu=WxxwVSj2Lt3T{xssH$k<#+GT+~wmdh^44* zL$O)f6Vd*5^*d`{w4h(#Hd>_oE1S#vrPzHh!;jFo6Z_rW+d9OYlRwJtMHOx6llUZA z=S2gJ4P}frAs#_vMw=QljnTGiq8Hg48vP{wHeHml+xZG(#y@k##_6Zvrn@rJc!(Eo z_4DczkLp{QsWar8CAV_hkMuOuet%&sS+%sWEUWTmS@j-Zi`F(D(AV7^FvyzP_4?%~ z1*4%*UaxOVU{uMig`(dWa*KIfA-5Ka{&nQmt!24&)3r{{|5=!S8W%4Qh_4wf0i%I+ zBZF-E`hRkI7vFOoEiG{KO5dK4EX|?|5A62eTG@Tm&g@hdxA08kY`bqo=N}IWpCIEF zq-30ApJ?+p$T;$Co)R;{_Z>_(Bz{DE)RE0J^lk|AMRhp$c!wX)8^K@Y;GcLH+^qa) z#>GihhBrg@d>TI*A6= z@_#6!y)omzz1_(FuU*5uWqgu#hQ5b&M!sq3bZXbWztSG{ipSO&4$Ohp)LKD%S}Vqa zRlA0)*nV`g|9-=-xQ0BOT0=}uu}*}wWF|7IG=cH-Ysm<>SF9hj9pbtVFy6K%`*lO> zY*;tMr;OXku;v-{^Ze#<*gw*!#bGt=RcL%4@}0+&w(TT9M$9UMnUd_bS$k9^u}!{Rr{Wy7$ZE zJT_Xgzb79JYnY>Hjjp;k+Gy*>pnPe!4VcWgdk6miaE>1xK{i_01FW&pQuXh5_4lrQ zwlV&zbp5-$jh5EWfIE?V>0`(P&KI5&=QH4`y{BgOHZ?aN^KR*XGi@+_lF7h7H6~ByNl&7xcP8lIymBw3O1X) z^R`$hC!6j6OTm!MR#Of*D)(ZloaC9wWox^0vRTKY`n|1bmHOoz;`Y>-{V!2&kH)=XdeZ6OI^uuQ9J;uL}pKAQOcP%#BTLS+{KdIGq zD(XGw>KWh9OX`iI>#!zoOWSD2q3alZe(3ob8?D{b=W7}#;aE@Cf!@+}9(-gRT}QsN zl&+J119Y9z>(F&>(tNDaX|l)Cb>55Z@J8!8?|rtfMsMK0i+o10qo(WhN!K~M4!-|8 zbscp6L~l&%I@yb(sblIpRe1j`cx#S6%>S>f?*tx1-`Tk8_3JyoWjOrX(Rb1|b53^< zn!fXF->wnv$Ry@Y`i|*A*k}>4qHnm(oYH-)eb(9tp4&$Iip4Y=mpHZoFE6spXY?p{ zb_#u_?%65gr?j@HuFg(L=ZVs1#CUHqdlLG6DmKh?F7$kFpLcwhu{v^3TGqO_p^|La z8;I@UKf9W>xh1y<9f9>U)4MUmW-G3wHPaiV)6EUNthv28uV=GfQKq4HW3Y{tZf>$N z4+cF{c`Z%7&-(tmI!(PBNy}e-^pvQmbyaIDHb(h8KhN4fUgz_*jzGJURL1%)+|eJ@ zf8mtCpRD%WdM=+Ua>jgWTg&uMV5t4@KFITQ8`W)cX0MpUT2<|b4K<>(z-z>TvX{Sc z-~PtN9s7z^dr;H~F)v1c`3R&N>DvG^@Qsl!Xgu(fS-(!t_C|r$>eu3Inbu05KBbb@ zR%S{se15H`Q89bgyxuOKK8hYB-&S5U@PU}~-l=U|`8 z=Kaz`l`$JS_k29~7_Z1K47MBXEs`9e59s6_lA-RMv)#m})$fChrCdkNd*Ld-F@66! zGD-H%vHBw(t&E*2?^9LmOL;$M@~sh#t*5=l*v|uJuhPDB!EgKdAb*{FqwFUa8@wH6 z{h&T`h_fN!?QP}%Zn8ABXZx$#>HdtBqpft5sP`jYMjf3H6?LXDyj$_P%@t>DN}M^R zZ$+Iy_rBdC^)2o))XBbZUT^lk20K$@a*)2TmwMkkJA*Q1ayZ{#%5dJVkNA1w(4#4L z*jWL=jG)Q7mu06qc_2ClKH;204V*@u8`pUk;5Epf%UKQK(v<7GZQ2J#zAGqB6O0hep@U0TzW;%VX-BD4m;fjq{H{zSt-cUnQ zugdN)-zNH2GySaI8$#wvrX}`+WUy=r$uxBGIx=l<`y(dP1|`#?E1gX12zOp1(~|uT z>et9L?3^HfG=CGBhTP3o`&<_|pR07-5;6GZ<7BN4K3LOZJ&qIGQ~smYl-x5vAbaht z4N1E}R;T6OZ-2N_?zwxnu^lCc$HCc+(@pG2dO3ky3Ur$|!Q+IC7jNk-9WodG%uUoe zx3Gp9AIgV-yegm{0jqd0=tF|nwz0^W$cGN9uPUQGHOhQ5tkE9+LCW#&p>#XLXIpz4 zEN+WBY75z^*k5N;IA4aHZTvgQRi#_Gv)s!Ot?v%MjYab@frt9~jYI}JpJ*0e-dUl) zCYyb}#v=H*!P9)GRdmoeQa{Fqa5eUTYCFF`xPAFU-_E;}!3;j^l?ne;552z~8Ny%HS^!;~m;une$_u>a+ThJ(3yu zvZrBbGWW-Zz5!o-E3mJlxs|NX$H}K(C#Dy@*W|SP$=WAK*5_mJX-TxI*I)VOnSaI` zlrg_7_+ocHZFzp&L?_)dsqqN(%W{@#JeWU$Po7Tk)nA4&5}%FQdE83+dtN@SHvBj# z?p1PDxaz0*Vmt+}YW#lwnzMb=KKBxN&ek7aHq`16Z=9dKo(}P;e|Emy2pZ=F-3Oo8+J zIB2X>nJ?Me8awEPH7!Qclt5B5aNWZ+x~K}gH>K_qc^B-Jzb%s z_58jb&do)(w;S|;%m2ylLDIhWk?c*Jr}DVU<`b+2bcxO?{Y87jq5j*cFMBRG``CTi zOJ6E&jdR?hHsIrz*+dJSnmI`Izbt~5_CAWPEal% z`tvL41kl9Rw8H;=I>9r)U&*)sXLN$$y953H_vr-3(Z+G=1poYRR44dp(CH_nea_|k z0c2BO#+|*=#dC?TI_mo;TZ_`Zg+}~slepW-$N%h}yK_IWRoV+`Xx+H4lXXF{>f2jl z^9xk%$@WJ-n<#%#IzJGQ+ADGYmZRNROd|!j@ zOD(>*zx&xq@xOnkTNC~hI*00Jx;O6YILqxxMRm>ve^9zfVn-{E{buefXt4M&;g5gx zW0!-AmAOv-F~v%|^R-!>6?$q)tn&c&ewBaUoO-`_YMfuyVDXC5}C=3W-s+ZpXl{j(av zsl*)3X8c(x=2H5MhJ4}Ti%S1vYJR5m_JAMyvhk1NEzp%UKhyYSyd5q5I**^Vz?lri z7MgC0&MJLed@MazJY>2v{Wu36(sOpStGK1n-5Kr5G`KRHRad&G@sr&E)l97{h7t zL_fFW9~R!C2W!X28tD7u;6;p=;sTR1V!}!KuJ(L%Hr9AVdaq)0GM+~Q{FkT2|GdJ@ z-TLz+%>%Njvcx9UiDRYBB(|e|j7ER-$>|Ag8>W|O`_+#Gy9i&W#vU7}W(`c$oljlv z#^_)B_380IQrFoA_MNd5%`FYhW#8KK6&er!yh_isxk_V!?8gUGGY+NlI1G3?-R0+# z)$Qs8_H5Qf;4r2o@89)fboE;_K9?{)mta58uQlEerC1`%n?dY}-;*^MjIHgx0Z%X% zQh!Ku92-UB{bs?t2zVC(FD(;@-P=#zUnv$y<=Ka-81K*z#{1vXkJD*i-zEw4Qp`u7 zmF=s6@18V#FAsCX;Op#?Wa56x{1NRPM3z{a@TS^a1drvLJ)ebkm!2G7PrJc~8R)J# zxaSr3owkq{d|jFgHott_e|SG;8{axPzQm7__JXZE<6~=^`JCMtS$cXya=uIQ#I0G& zxtGVsZT>Q{t^bsSzaO7d=I^8I3#Rd+shZEbiKc)qS=zv2qq zTI`=0L&L?^;W1?YmOz_nalzB(l0X~a1sVSp+S$(@Qi;8c(y?SFWo~CI#+8|&-Od^D zB;Rg3?Ha!D$Uyj}fFJiXzkHs1SkitocV+|r5Wk29X?{`K^NWo)X{}-K??`rZtT9jR z+rLg38DXPFduGHL*{ayG-EXmRw)5_P!k(XSkS_bciI`*4f- z(-(ukrCZ-*>9az*&!r0?ottd$wFX=H&$_h6*wPnFvG+RbY3bOdwJuw_rPbc+{DP(X zTv~AfmVU*h6^CW%3r@1~n%9<|G1bz|A-%?>jsD1x5EF$AiRSS;hhHbZtN7i@?|u9> z^6TffmER!0XZdlrCHi3l=iZ}OaZ%h2Df_3GonAR-jSmh7KA0Id{Gsu|%WJQi8J{2c z06CsHedE5V1;&kM`6cu(9dn((UuY@#hrG7Cn9u%w+nUsK?4MgYi`pkFP(S~v$ezv4 zZk=p)x$Pm!PG3VByF5wvo@{ox>`yB{G&ix!l^5)CmCs|B`+C^VZDyAz=@IV6!Y)tJ ztKMvOxraNL9l0Q}%M-ZRi%jx$>|b`rDsAKW>08yLZlv ze{pHGU7osgyr+&$S2c!#rkW3$KLd^KT(8>F_89&wK0s^Nukw;wJ=(=pG?bm*PUwgFmpC3~DypJ^gzTBAYpE)c3s&8NWUW#L& z?ZhV}*;1e#-B(*^<=fK*i;$2#be~RM(m&ABcyzZ@)Li0 z?{~8DIjvu0=ht{w%(2c6gUg;@94*KFP(Etzbbdm7PV%$e&7QO7Y3*8^8rLfQWn0?z zWnS8tR;|G{Cm);TW%JDVHfTdE%b;xYD}9?*51a=4_?q64vVFt*EvfszZUtB2Yh|&4 zv-pI+==TyKavELddC%L({q6HEaD2XZR{VpzqetY= zVvg?3zBt3q){f^ttHGV|vAG8C312;zE@4cYGkubqO7HP$JqKBkPnFN(XTCpxsP zaCDZgXzA-BgAdGoT5~P$2LHd>{fo!5U7W+Be*VsKo~74Urll(u*elM$d-lH9!y0k1 zEMxk*HaETa>U*bbKXOki=TVzDV>FlZ&~u3YoJ0KQYLdZz%)$6{Afz7kbwjF5H zzv4(LeLBWBgYy!;d7OL60^jV~;&|2Ssc*-q`<$!$^4jmui~lHHcLcr4uk+l83?A&0 zdpk5`Ppn|!)$>Ynn%RMd+ajvx7=2^sMUg-GXAU63y-sKfjW3bEk z3~H~Q!G)a~(g z?^M1o-%I{wKL0MB&(QOYhu3-8`1J-S7uA>TjqhTf-QZ}bHtabXIT+%Z&K9p^MjC^k zX!G@lcTfg8?Nj_2v3Q?`ZpDGk?*axm2xrP|xU?V|we?cv+oO@&JP+@s52~YfCn_EZnwui>4NbNUOPPWQuj=L}^10{VjNEG?w(dd@YCto8l+ zEzN1=Wtx({%5PQ|*@85ljccmVe55L1Bz$A!MaYgU_f8IzE->E@QHF0v92zEGpg=xt-XR&{+MhU4 zI>>-<>0&>E{iE&h-fEzL{u zdkMN3EukCmM;w1&e|VVuiRfdC(8nz1k+ybwn5v_)nipYgL@&)5>o4-cV%d--k_%~B zm7XtDo_2v^*HX0pLf9ip<)Lp}t9Cj({S%r)Q{5k{`sqBCEsa6zFG9x+&>VVi7?0kn zZ)2D_zH$D)W_&~|c(nAp@aFHrtDM8xk?;^QA6@Pveh%BXk;eWo`ft@bK>bW1(p}Z2 zyYBuFd&J~Z5BVc~!okqGv61n;o?pFsUm2$!-~2fx;I_u^$r)VEC%nhU&xQ1^Aa4Q> zfQxv}cmlbZWvsU=k8fmIUP$NQOW{qNXo5HJh4C{{Cy0 z0~d|4kCjcqSpJ&xlPOJ zMvlPy$k$xc{rl(-@wKPI&rXKR&KOH(3s?Q#5WNGx=dYx9DE@o1(`SxX@AxC(PMtSe z?|AH&gd6B-JOEx}=^c7+Is|$}^fSjdmQLvux|cWP1zqApK2Ll*)>-KEQJN#H_>29lImW(d}KpUo*)zQN_M5N-Uk>~LGVDYIVrjGfBgN&aOXCU&)xmz=5a@*>!v z*<@dmd7s+%+@-rNoGrSyyVMrX>~^-O?tu=rl=kwiE%}YG*#penbhp16?Ai)gpPU^} z@UXPMS+9PE@x=GHxBK$>@vB{~UD0>z?wfZWxn~vMgSv{lX`06TCa-M&;E&5@(DBeS zm#1a^*XGOCH<^E6qscKl!}$&Nsnm}71+V_lzAkjZCl+|$Tns%Yz*{jkZOS)jefyf( z?0dTp&yV*SzHK|}@6Vy^YiE#Icq*5Jujcfa}NIx&*uNp|1$hO{AUk*a9{pDM~Aje{{I30 z|DgEO?a}C7F~4W}5PtI!YwuzFp}_bj?q0Mu`3`RWmB?aWD(>{Hig_^~mwY*#@3m*< zR*8A3{jeWxdl=AVp71&!+etIA3 z$i0>OQ2!0y2);ex;O4x1P59;M5A`?PI>oKWhDVOJ8)=47@m5oKp?hwAi z_)@hWOZp-8#mbT{U}wti%g*Wim}HV<#2DY2Xsn7Su5*4r+zYrR<%|D0`n|=(AcwQ{ zWc%#X68ZSt!+w00o)%x}$H(eEfP6Ru`Ji|w$%=*k`97W(_~&IjxB2H4JfrhldCh6* zi>eF%0LMK`&Mee3GEg##xol;SHzt=<9yu|vcGlekYj3{D%4b=ub;H&(X#_ zUI-7$ccFO&F2f5q7G3NC^HesC%E&HZ{wK16F*8{~`+3=gyqA2i^8PuI6|b|t$qM1H z(8~(Z4Ox*xHo5a&ogLP{Mr5M-TjrX-h38oG4s#>)^@=mgva$lk=2<(fOdS~8H-BcQ z=$BnA-|cMl)EixTdT!;wZqm=Kp%9c2kRl>sd~RGu2Y!AEWsY{H$sdyKP!x&%uWq{I_n*)<=&7kB1~{ zmCj~v9oZ1pV9Ayv%ReqXq=Zhwd^0_^bWi6Wp@Z1>vkb2E72Q)!p7Cd6C*`A2^KlF2 zkM91?uwbbS`BsKHiVrPpA|IU2OpW{U{|Coiu`!~d#l*tTqCxfVv+~nHFDvr^G>2yP z{2(O|j<{Jj)LPea(J=*X)_SXYrOjYhT&RA>E%)s~@D! zTWnSwPKNzm;&2#0*$(IQI9p8ion&5>T{jp#VQatf>T_T6yt?#AvPj zGFP?^``B7nT}-z2ihXQ$y*^*h_vm%kAoKIU?HjLt3A8(K28k##;lLG zlh)j0e4Vd^IYAlC3E4GHpL1*Foj%TC2WzN}p_NPR8w*Cp!LvDrt&-IqC~zcm1@kA~ zzZhh%=DvK;R$leJkGeoT?E&xL9rC%u@JqqA_1ScS*@@pJ@X)pFmB>y~8xH>L!3sB;vG0)Xlhgj~ zLi#AZ0Q}|8Lhp>FBk6g&Z~LIPQ{|7!NpCz(7{)8WXAM&uAI@H^@7O`J&F|W&^~c)A zURK*`%i0$|)4rvVJL-GTX9jk^Yp3poTjO=X-$hsAu?Uk5>9RI0QPp-Z9ws-v9T;!078~{;c;USC313 zYFxru*1)&&6KcLy$I(FB!S0*p#6NwziyOSc!;ta4qw7)ske)`?7io<6;4o8p`>a$>H+5b0OwErLSd<=l)`xpQ{i#E^s`DL=4 zx;k5EdWqiqw9V~P&`-(BD{esV{N6wJ%bSfWSi@d!Y0e{$TQ%RLv!?d`Z4Me=QKpVw z>f~qDytMXNhfJn=emrBcmz!Fjw11rXMsYo!s~EqnbK_t0wEHijore+D!?VJ@B;?zg zdb`(8RSp_!Z4NlO_1UeX<-Lrs7PAJx(;n^{wx(K4vd4L#M>3W+dYBi#!}m_L2LoJFm&{sawlizI+t=ZaAJ+I}U&p^s?gaDezwPTt=1V8O zL1RUGdX^r{T4vA7nA2Jxl`kEd_067F@yxup=k+`@C+zu7o`cTaD;+?6O7H7bpEu)M z1eNxrA20Zea)O+cvlsDL2JOlfmk@?~50N<;AQMLzn0u_e^-_F42 zTr7P^zc{HJOHZC;j=uY?@`|O`xwquI*JH&r>-%N2ZFq18ZdPa4QtO5CCz7vm4BtUU z-VC-MHXW_Md-mz^x#Nyw>YVs)oqwIk`Gz{@U#n~m(NX-BgHGF-Gop8k$4m1j&sr)Q zrPQXqq^RQ+TQ7qyj1A*;VQ0UPKgzz`8RFTS4<9@O9!h;nd3ox4T-LX9-WnfZP3+z} zFaE{b9FLx;b=+`tI=sm}=vx3U;3jdY!M|wVOCjI*0ef`MZ0E<b6i4E~Z`;rlAzCtqf6k`!Y-)3fzAn z9M1^)0diRRnzI4_JA*G&?SlU>Wg^3O_2CTl4^VzKeGyG^q|^N==au`k88}CYD%2q<1^Y8FWFcL$0L`1Jlov)v69XSD?OcO`lk2l1H3n) zG_u8wzv7a^Tqh3nAifCqZsG=X_F_Yz0kSjnz4{w9dzyW$KJ|0*8`6(#v*Huk2V#C^ ziI>_!?AW16%tvIw%3Wie{(SO-o%iR=xf1wdgB2Oq4I%z>9&ofyguVu!f6$$)b>=YV(4G6c zA3Hss>*t*Ark4!BpJ#qJoo_Y%8)yFXgOkR|#>(aZ`vLIb0CD;@2N-MdpltEUCNoys z`s&tC=`&hi%l@JCw>QVdd&-;Rmph!SP}}Z2^vdl=cf0e@Q#jvs8o#&myOv+YoxT3f z4Be5DM= z%KK}KzBj#9XFdA6*DZ{{;qkmzcv3g>t^4;qIEyowejPv_8ol+dqVB2r_^ZAybJxWx z&|U-ePXiatE4P+Lw)W{MBnm# z0|)NAS=Hd>ny-%zmb_mDEpBLV?I7#2naStoTaR&;#p@Uqdcx*f->31w&Wpr9gWcD* z#DBFRdZgw|{aE@1KE*`8SiiJm!0%yc{Qs=U`#YgewrfR4K4s@Do>I9l^rWBDqGfj1 zgn0W)H{V?tzUMpH_3M|wuNQ=Qu#NoFTPy48o+iDoyACYtDdLwgyU^ZGcWITkwwA5v z$TqsWku3e>(mu5;nT zF5uhvPjBiN2+vP8_32sTT^ORB`*O3a%ykV#N0aM2O5rT8@R{CYJXY9rd7tE;$`+v8 z4qz0fPkgA5qYU|5eLS**;pm#3PJDWEXVKu#IKjhDz03J`bLzfxygj|q_`Yq|sU0=2 zTUZ;wCqKuR*>qx`%Cw!{Xltx^WdZ|tK7MAfg92ocIskvryVaml$F6^Hh zpR>fRe`nIJl?UfB%RkW;pXSTY3*}q*R-d0Mx)0dL%h;H%OSL)|ixtC~LV^7=t?N^my{6zvI6%Sa2cL|&WziJ$}Omq7; zHm2*DySz{C6u8r;S)1%V`vCTywaC&%?3wEC)svT*>E)pK|Ih1`A@49_XY*ZUcGW3E z-hWS*dA?2=^8O)R=7lu^hZys_NsAZ5e&)$vdhJo+QaR_U?kV0qcc;F^5@grFW_$tCt25bN z$=~dXXk;CGEQf$^c2w&rHFlJJC;ov>^vIhJugJJN^L7AJHoN)3GSTSofrpiQuueH_ zNpFLVzAu!k(tYmbUNQB>VDv8SsBH@v*gko_D{N)%sx33Tko9CCbCEK?9$?*9r`!U{ zEwFM$gSD-RyU#28X1;Fu!0B60fVHU(tXaUqwxgVbmErq-)v!*X4E{sGIw!z-pbo65 zl*7M~z~b)68d$7H=v4+w_jwrpYwEz7L^t|124ZI1IgQrw37s{>IcOGux zUd5Z?9o^08?(wVdmn`3z{v`%bcHI(wf6eo&sox&*rjfoim6v{>e!i8m*ol?CvE$(5 z((Du;w=b&UV~h8Pe+&2~x5K~kf0fSYWFHWJ?*q~3-+^LH8F;D$Pg$7|`-^2SJ{~o)~#sz*iduUrj!rPX9vZ3!!%Q%(Wz!xGv z!$8lRodZ3qcW!C+-~8nnzew*2uWxG%ZN0nKY!&Wm&Bl}7>U0wJf~Kji;dx(zXPGwe zwR{%x13lB@zm?o`)6VT`16}Mn--g?dxM?SM`ZLGb2h&`l9N%v@|Iq-?S?v!2L*G_o z_@_NkuTN*wC;TR_yH8i;;_qGH`t)$RPn+uWiTS1Yf!Ez9&FN$G>8g5t!q>%K!RznS zk8|-h->2)-eR`lypP1*e6<&9rBwLQrr&;y-G?_kO*BRfeX)@ng4UbQv%p_lCTVq+S zpc~bbD>}y#@;~&A*B;%9FG~JTbYJtkNcTNibdaxVac3XC&yzI&Ch;w3v;Xiv?BLx> z-ksRA@#>W=-HWY}Xc@cSAn^V4O*Gvik2)58AQhF>fB4prI@AfI`q9n&A(Jux2AxgUI7-Pc+y zk=>mVaW9GHkl9eH_y$vEip9f=e&T~H>$Lnx$n#P2kqu6a&#tL+YGs`VtLmINDV|?d zXL-}Sq>jPm-sc&V!N2Tm_Dk4{ru_ozt>nX^R9uVUgjO0WGey>i7C-}CIX&sUk z+&$2tZ;Pl;*4DHWwaB)n2%%O^UQJJ^CwmKY{@K1@Dcqdq9cgzVb99w`q+u_Kux{Q%6i*+ zD)zdp-j7d=KOJxq&-I%A@U-~S#+tNjt!<3o0d$pc)~VuK;ytPFQZqM#PhfyKV!A5& zVOI7%cM&Z2XFk}6dpTOSD47@YAM`PHdltoSOZP)(NmvIrC2N%IcJ}h{C3l81+~8+< zg{W71Nj9gzH+$#O4(87JN+Bewtba`)wD#NYW%$A`8)O9!wu9v`{Za_YDBHFfk; zH+jEaG8-S2*7$#!yTqQ+UAMpFp7Xck`vsQ=xx>%;-Dmx__7fPXHUge))U)yi_vR(y zsZ8jv`eALj{CUYacJhHgkiHv<{x0`^72zS6lYpuJiNJ6?Giit9iSbTzB>SDaaXd}# zJv06&G&#l7OZ8fO{S&GG#ecbZ2|l(Z4o-`QbE192yVMBWoQK;Ijc&7Zj()H4@LS@$ zJ*`8Zh5Huod$hj0v2wmnaIdI;=HhrA^(TA0D)Ff7Per}2pC7-gPP@w+Q};=U=Jc~b z|3r80L^l38UiwwEH*HD$j#PWvpXwIRm!VB-gEG+Wp>%seZ?$rFd0fDWa)(q-cjycE@H2emj}>0{Uail6 zk1tkb+e1D+RlUcjs(Sl*9=aupujGE$jj3;KWfj|X3+vC3#@<_fzdz>7zn8MSsc0lw9c^Tq3clf^k8fCTqqQqCw>A#YHnSVDM zn>|g#uae*C-wjs18zjHOzZ-(icM#*Bt~EX@NDug_$0USZqYdJKNa3hue)aK zjh1w1&DbklYW`o?nz487BOURV?{ed+e*TcXmoz>f1ZE3Ay*miL>9y15Z=iAZZSkL+ z>+Fx;rM&pW#(jNb@3x=#Gx=lmi|_EcK3{QJ$H0l@J)3uME;o(K8p?^MvwVj>ziL9q z(JQ^qbtQO_Uubo5h_SoY+7J1gCd3DM)*U*?Z>Oh`HXREXvd2X89P-R)FL~DLzWtSd zctVHhUpiJ>!t3D)@i1`p9m9MBIF8d+cGS<$A7pIaawn^suRqGTf32xkOtAgXXR7EB z?1UFisHBhXF+DC^16`gxHeE!=z<+vn``6{Yjh{tPq~8;~)c^PWv(j(GZ;FR^4)DI_ zpSPykn8x$3^800RRGT&TvLfG1@6+CzUng~Lzi&eAI3?wz+xHsl5ohzjh2don1wz`Jta<;rX*Np0~{_|oE zr|~CUjejlAr)XKHKN{zuwkUr7=+Q?vrq)yVWSa6zZOEI|r(Wa7s!!$rw5qK9jt42{ z%CN?{_?o_PajDv)(cTg=jD1u7C-Fal{|UtDF-CsRcf+@XK0{s>+Nz9r>Yy)YwAr=j zA&qU4XJasNgT@wE23tB`Xa~Ka_u&vj?BOb}%5K>koq2J>TemIpWA^Tg;}iXu)!;lw zJf1uBLK%)&n6^u2JH6>AVSUt^RZnl)>v3QDj(8Wii&oN``UJz*VQft|F}=yd zmELp{?Y<|~7IAjQTh?}SCi!Ny^a-O=s;&R*>2wSA^EuYssk*-ff6mm-;t*r}nFcG1vvO(U+(T-96#dWTp>KDYc$38rGJYHZH+qgylxh2>~v!L#S=4pUY5K$ zQHS-5{04mF?c|+DfB%np3x`>yx%;UCS5 zt>|ji{Bx-v@7vX`=O6Kotrab^Pa5#wupNh&_O?6v4R%An@10%drL#S3*)PT~T_=pq zOa7gBslA$)co%r-LctP0f?Ku=f036Xp06u#`QsEWCwg4YNa`PRj#R+fnu0aTm}<_Q z8v3Q@q9mCTWHzchFBdp+}D8$PULE==-zANC7!$>d@}lfA~@gWWGLiGQ1Z z2=@=j#%7(6?8TREHtPWXA=68+YlMsG6BkAC-yf-*TklidHu&!>?r{im+`~dfr0w6m z?V;_hm&8}nw&1G$TLO%B)@R~*1n&-HRrBdzXiCSrEk^sA_+r>Q43jdZn`{xldfA!z1Kl<0-$p zdfvEkqQ4FC-@nE2$j@nOh;{SPt?x}@a>D_iLzZt8Y)td4@^s!N=)A&JdFYw#fv1!wKLvG( z1uyfv@~C@j8lL$xqTXjcJZm4G&f}vO?TB}Ab7$GuWmHaa_X(Zwb)@NJeZems)-2Is zOPKE(Yw%q}AM`JOG2ek$q_OWDYc4$26wmj(CH+dev(XP6$E!2l*LgGLg>(3YFrDf>|=nXzCrg^{LOv0$#aV@UJ+oQ62-6mqH-Q~3-&2acM|Ml!Tg+u zc|P@yPW67gsg?B)`nYB54{Z)rwW)aFA@Y-UpJa^b+sf%nI}QPBWoFW(f^1)WcY^U^ zRegOMD5?9@*mZ3TfMIaK(; z9fujiL$~^K%13YXZAw3;Oo1{QqJ733!{O+5^vkjP~L}1)2^Mq z>Kl~WAGUI5rOLrG?Wad^Lw4gny)W?%N_-MU<~M74CRro2Hp_-wJlW~TZ}DTFl?@3V zW7?3slYYE_dO>a&Zn7bHXEvnzA)b*uNC``{T{rxs!>roHNNb!>7cq4X{_fpLjy%qKirPF-_TR<+-76b(+k(>1|Ht zF*hDQ6PedDcc<5z+}!wp=hF|+PvWA&+?Yrlo#9JfHUk}bZ*-jD=LYFyZd8>qIMg{v zne^P~JjKC0dXI1O9@?Z#&DBd^!Wb z%W+nRcHn2ulv2lNp2By;;akk!?rePZS94N6p`n)A`JARln9q|vJ$_p}JI;JgY<%H! z1?${>S?9Bzfn6T*=Agqd*Yb17W9-5lukLGz{VApTN*~?)p#DMfS2DN5e5&rZzIR_u zf3?*P9T<<|0nXnhGQp37@+D(~?kHMFE}Vhf)3}&i5N~1EC;S}lopN+d-bpUZp`PId z4C4{%iKk62@SnYN_BEETwNUx%7cDWlpf<=$css}i@(aFfy5H7@;7PAyKF$ep0i5-2 zpy%eDl6yK2gB<7&a)7=bLVvM&`tWay7drV~^)l{a&bYgnE9FO0Z%p~|50f z8~6BrvghVxHua7vKRmu~g#7p%?fz@Xj~7oIQ+^mdkROB62aYas<9@dr_oB`DIzHvs zD?e-wvR4crFZ#bhj?6&bN{+nM^M6)8HqBdP1v>N7nyX$ub2i7llN^~uy$U(PyF`wp zWQERc8a&Y>B`YLX^c_ykxgb}pY^sc{voGASq=1cW^h~`|eYI~mq~y%hUqa6OyF2U1 znVxbSpY$1>9ojy|6PH7Sh%}d!Cjip3LFn&dl1gd_Ba6y&o7#FZb#91(iaUD-yTZi8vLhLZVa4+bM?>R$C#iK<%#Rl`$m4E zYu1;?zAt8f1!M}L%Rw_%}gm)Msk->%vzUDC;( z1#Po$VRSZFxg@S3z*iZSmw!rm8Dc(EN8fV#2zM16^z|#^9YS6@-hn)|3Eyo{pNEx} z&rjcR@_l#jqu!tV54W#6?pPel=hx-WbXUfF4@UiylQFsNky5(-)(QaJr$> z=_VuCWlFF1=~sNZwX>LSbobrZ``i8dQU89uPah$T&Trq5;J%65#f1PQ-^%SMgt!w&w6CA#4o~SB6X|c9S7TAy-2=< z!S1C~;@`_V|LH@%eUp{6uexotZ?La(c<%Cj6rN6|Hg)LCd4f0isUOxq%4DI9-WBM( z`0lyz%}TxNUD~0(Zw$6{$V=}TguK?&o`Lf2@^!-+6Y^9y4Nv8$+nJ&XzLawRJ6q$o z`ToCCbQGL`Gj$jB&bcOiXF*uwysx+n=S!_|-oxn#a7KOK)z6k(nde9sfSXP6oyK-0 z?X4ugz#R#8{{?w@VrWE5wfFv?Rr;M3Uy;y#*97C20&B7H$t%QPQok_Ar$>Dn`EG3? z7qD9oS=o%cQ%y2I_3j~i*X-|G>&kW1%7Xg7UX_zR5ahGTF@HX4Oga6;N%1blIuq0T z+-FTD^sjyOq+ma0$h8agAb{vwYP5l96k}fm)^sF`c9JyI4!=M;?GnL zUDE#jy(R`5oWuPwi~POxfq#cCiQ+$erILql)Lgj)yNfvecJEJ5m;XXl`72Z9gTF-b z$J4a9{5Ai5WWgk6dySV@C-^d<+?HRsa<1PdOIk%^t@T%oR^oWB+N8hf@ycRn1n#|S5i+z z6%#u2A8pFTm(qs5H-sM9pWSv*obTYitdP!d@6}@Nq*9u)%FjRG?x?coIK#O%-35R1 z;SBixuT)yYy0_z0Dq7>GvoXVsdN|VZ>Q36Q=ES>mEP4H=f9guXC}n? zA2c}pGABFyK2?d+eA;GSRGc4p+S5blr}B%u?X5n}Fh1^mxZu|R1ozt;i-!B{t`FIv zU+-9+Pu2TrH?|12aJ5|9J1rUK`8)hLpEfPkLh9X%{@u6TyG1W9E3RM+{hddXtp0bKEgsbR z{M}{vzq32qxhL-AEN2GkXY^Cg6O7C9%J|U!_RHU{c)x!6@=koS)7v;xVDlqOd4oUV z>yNl}0bJ0%9bU*!D;U`>ntGrjz4|elBTG%<6Aj>fl31!Eg7rkG*@+zZ3n`w%56mwyFD* z&^Bf5dt2af2C&r6Mbr~6XL?-focS%|cKs>wOQ*Scu5$rKC#|L23#c)uJmZtv>pGTS zVfv-m^yp34H`$g;i_86eDVAnlncYLa`p2{VZ}v3Crm^>Vdp~hf9$pM^te&5j+fuf? z_*G*YaPH)}x-HJiZ6MFu3b?7B%C)sPAAn$}OuC&fc)S!-qq5=~{Wl;F^{=(7k+tjN zRp%Kkwx0Jn@D)t;)!LPfVCkrL{c*y+w+c48RD!4IlkU5oogSI8{f;$W+8)&4E857yP8Q+@AgdhylwPTqdxo+*5Hs3|UC!)BA% zj=6`Ed)>8Pf&FA>4bX#iccSfiqt7cQWu9y+=9SjDAxWPU4pObxR3YBjr->EKFr6uJlW&!m#=$2{AO&9&G^H?JGq}i zcF$yJ-^1PjV{_m<{wKS0JM5J{a%(E~dYAkZZhT(uK5a(413E~4uBDvu558=TY5w^J z>yJI}Y8Z8Q%BEt1QvDD2X$HLDJv*;e(bi*gTHqF)MrIQw{@&Dp*huXC%$OY&ZL4z+c5JkQvVJ63gI%gz=I zrk`c|hcB=F>lyJ0v{O+R-9&aaFh)vmO5JldG_B?y0r6J2?-L*GBO9QB@^lx=OW>8E zAH;$`qVqTDeD&{BjUG`%z#@VTfeU+}qW;1T$+0w2NW4Avux*G}Up_`;`9l`r_hXMxWTH2XSvS}z16 z6NSw z_nr8JI+OoJ#pO2qDHd#qq(g`ZwK|kJ)$nPcG=$`X^ zr}5eC{Y%G#5Ak1h@k!;^;FEs$M&m;qNnLzW`8D{Y-@P7u#^DPabMA=R zCo0!=gX5ho%)9*Rj*d{*&J>DQ*7&@x%Z$hJw>$pYqw;n5%f@sp9&1!wO5^q;jIq|r zG4Ec(R$C8z*=e}~_9L++rW^l3Ic~z_^pcs0oNjoBm(yEj#*e+*%W2KoG^}>?LFUV` zV9gJ(?w%Dt=wXRx!(21}?JDRYK4!kzx&j?7Kh<8A_N)wa)qhq#DbZ8UKjQqA;yDEa znp$43hq>OTe~>D3r_WpC%k=s*?HP=_Iy!3ZS>v7hdeGlBWo>LK?^hhezs~;AB<&p| z+YC+tS)u$5(BJHL=pW7?Sbg0q0?yj+7_WY)yAnB5QD5=ducto#gHT_*W%~@$>o18q zz9BnFv`o_+e7*cB+B^DVu?xr}qf<)ORNQ^`I(Re7xsx1YJ0@SAKRe;e$GbgWesFgD z^R<d5dGA2)^;5--LynjyoV-H9D2|TIiNeTY4&q)dC%yDjvQGHtvQ9){l-YoB0c zeSZ?YYMgai<&*gyERf?y$Q@<#_l5O-~8TXCV_BZ@H1n;8f7q8*{xO6>^ zHl9328y6q54c#d{0i7UI@xA9TH|%co#+%(e#`v4`{o}E|i?&HNTj#~{x$Nz}YF_-6 zHs`l2GH%H?&noB4-stP|G-vGW;(^|cK323ne&{wQtL1OC?@fb4sm;fhai_9;mg|x` z8du|s;Co>B{q!%tpWPwt{eGX|9+LfjPt5M<760H*RP3DYvlCxg`4N2ky0017JNTC` zUHb?2oZ71>aSybWf2FE?YQMq0)d`I3=s0B*bJw`~uzV(pZxW&DaRQGMxi{TtxaHI7lWN z4%F3rgx(!GcVd0Dy*}Clp7+yIpKmJy$LfHO)d9aB_&Ron8hBf5obJx%Oo_FPol~#v z67hrf9=gwB7|jw3UOO?c5P#puV{8n)B@Q zi4RmC4+Xw+>1gCce}`S|+`Vl3(MIyO4Q=V6fR}>Cm4DFs9@X5mz%1)6@oF$fr`Qq=%dlnsn z_3(jA??&&dMlUF4U&xf#N2Pznd-(qp=9m1DhG+A$9oa9J*O=w>RdB^)D!07TrLAm+ zvcT9C)+1zhHgod1p}hGrHgks&W24BjwxUdr^EnRr_!F&{`BvlxzF$Y*WygxHx@We+mpcXzshq}%`wEcZ%thKv?+e=6 zb?ce&35-|8IMwOb0nr$|mxudeQ+@k#(A~jPef@HfztT}ihd!$B2g%DtFMq7S_eM2m z@E=~QKB=!Ee%5rG`*NQ#J>Jvl&J>-DhQMi{jM3}u3*u*3_XI_(86cxc=&9tk#)uCHHbaj;`?q^o%E1C!SA9nU-iFr)N6ybN- z8|_@+?2PEN_`pmr+s`~Leg|~4xzPA7c>LzW>d$7%uYL9%@fVTf`+p1B_gly=;;h$r z9wT1Me6DS*3)%fsW8TH?d$aEXpKwOwU95?YZ(G87{e?PD@vg%K%g-IU!pq;SzU?n+ zj!|ZSwCZY(odNC8HAeH$?tbZr;AQgh`qSdl?4yqs!DWa#cwqPalkmNe@wpHfN&JrM zmvqx0Un}4|dwTpm;QRq__ES$j@rKWD-1i}PMR2l1Q{!R&^WdSh&YegWaHi^GP0-G0 zbJz5ftPJ|0{v$RzBajR=XD{ z-#>RKpYPc!|6=9yeOdnvEImu-kep-BZZO+AD^BYmR;OL{8KY2#XX&L$olVpsEq*{( zbaRL zgKT()24%eYriCA0joBvnq8+|4Ieht><0lx;A@ao&N8pKb{MbGgzxJrL%NVo18DE#Y zj&J#`TBE1i_brVE@ckZdi`h71Ll5~mP%ht^l$YJXJ$a6PXN&jIZzub+S(Zj87-DWp zm;El^-PJwTr`Y$R23I~+`@JZ&S&EjwRk)Pfn~}7qyCp1+m%cJzirKs760;ng>&iyO zYc-A)@7j`g+EWtk#LGsvriJl8{hH_bIA zMZJN{RTt{L(fTZO188G+BJkfnG%0S#xcd&W^P-W+-)&-LTf}dUo)u&9zI^;IvyMJ` zA2E6=HxW7)3J+dAu>C<|yJq}Ow)Mf8*7uR-zA(P)8a`<_D1Uh~{QZi1*LI|#7|QI4 z+_x;0j)o`28!vUTUv;wbbGM$*r#nfNUgu#X??wYW|Gz0?@=$!2_ut3}aPI)FJ&#O^ ze=FUF{4BJQ(CUIRt&qF>!Z}sLcX9cha1b5!kKM!hD}Qf+@Fty&vWKFe*N`Wkeq3wC zy_4f@(2+I7jm^lizU|NueQCo`%{+GVD)_H79&i7|YmeUQ<-<%5gP0=gciVLT--R5Z ztnLFiwN5)*!`ergEbVI?)&Blqd-(kA*$-Pj`<|x91%43hNz~K-ME66m^00^M;>&J$1CAYcq_ zwD}d<6h0B~ewe1qC^W$DSeFL8GaB$eCJo-bC_X&%=%e?CwvR09%Qv_+qk;#>H(30S z3G4hb;=c#hdx2%N@$*g3PF9!YU^(v;lYxTWmT4HZ|5pFs?EiEAzlHUiH7<*7i@s+z z^sT|yv=CW_4Luanz>{n!MNTdWZuUrb(X|_mN|(31OB?EVXu}@f(OXCirRYE2cr?^}|8FyA^Z>(t39i?-b*v_X{5>%M|Hd>YvIaF>s_6 zw`gUzxbITR9#h-SUcG|z9F1m|EB;{Xar{`9BlMhTT~*olk(aKIz7TEodG}V8O_zJU z&r^VTVjXz8lRpjXe993sQWHOc9(VOvzJ(;e$N4Zy6P%7-&v)VcGM(nTk_~Qt2;}H~ z>ePk9`K<(whmUWfs5Y{^!?x42?VDhq6!$mQmN$F~-F1B_h7a%L?@I8&CKwYR^o23; z;avqj;-N9{(Y(YL^*gc=qfB&CHB7^~rKhGX%WoYcfBG2td1 zHjD3f%3r_rt?>QS2-^~W+H{`rZ6gk*X-;B4UtPf8B|q&? zy`Glr1^vzEXDVN1nKQ-Zt&x+%_)N892b!{K^9Jj;z-$EZy+b8V~;f zy1aZ*w7pMj2K8dWFk9Wq<_=9v{1xsSfja-9vRaSx$Pw(&!S?JWE`E6DS@Eaesc(^C z69UKZrEiq8`y~{!R#E%$?VTJIO?LRcd0MFdBg3?% zezpW1YO?l*I6pvtcHmE<{f<}Yt6~8|-wM1_Ka%fnft%}G|Je%zjPbk+w*k!BLutbR~C-q$sF=8od1Ak>9Otap7Q4Sp;O&{3jVx0``lxn zso+~4_U(=gHevVwB#s;WqgOJHKVRt@-IBU5XBx1LZ%tmiI~U{|U9tjQlz;6BAI(ZrLz6h>@r#W7+chFe&q1McE#?9@+ zGRHOF@lV-&&#=DIK9P>kamhjx}AYZ1k#^Q&4*2@>*TFk|o@QoAd4WHubn0(^dXab!k0>|;E=%eqE zG~f@u`DK)XzejG*~_Io1B8B@lj zX!)6jkrpqD)sMW!OZ}LFe?c)qjCFPYLOqS^$Gtp|ybSWbrhFY3@*RmL^55xSJUL9e z7Qa-dyyl*8R{uYux{_108Tz#D4eZm+zhs|uCz|*$uX&;UaOjuie#-2TOz$SoyPBIe zhIRU={OeMEyCUpinN0rG#;Nd2_UTs{r}?SAtO>pw#yUH6%M#s{uq*gKZ0kXJj(a?akVACg(y zSOc^l`x5sb-Gwh6-LW^6&9YA-oLeX>IL^1=*Ll)z&a#d(Xa5dfsO@8F|9^MY9QdJSYDBlbt>w-;3&I7H!=_$C^;cj6csPTF%n9*|Vk$lIrg#N5LGpgnN%0D70uOhvFmj56i(Qbw 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

J*j(F7y? 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

xW7Ga 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
-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

m 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�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⋘̸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
VMhSgy}J(D0c@!$-Eh8U826Xy0kz#}OL-wc|Lg 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
)d;V9? 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%0AcDM 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 V?njaBEw+WFRH_MJ;uZ11{|}mQG^YRn literal 0 HcmV?d00001 diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/INSTALLER b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/LICENSE.txt b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/LICENSE.txt new file mode 100644 index 00000000..e1f9ad7b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/LICENSE.txt @@ -0,0 +1,44 @@ +Zope Public License (ZPL) Version 2.1 + +A copyright notice accompanies this license document that identifies the +copyright holders. + +This license has been certified as open source. It has also been designated as +GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions in source code must retain the accompanying copyright +notice, this list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the accompanying copyright +notice, this list of conditions, and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Names of the copyright holders must not be used to endorse or promote +products derived from this software without prior written permission from the +copyright holders. + +4. The right to distribute this software or to use it for any purpose does not +give you the right to use Servicemarks (sm) or Trademarks (tm) of the +copyright +holders. Use of them is covered by separate agreement with the copyright +holders. + +5. If any files are modified, you must cause the modified files to carry +prominent notices stating that you changed the files and the date of any +change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/METADATA b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/METADATA new file mode 100644 index 00000000..87ef7454 --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/METADATA @@ -0,0 +1,1159 @@ +Metadata-Version: 2.1 +Name: DateTime +Version: 5.4 +Summary: This package provides a DateTime data type, as known from Zope. Unless you need to communicate with Zope APIs, you're probably better off using Python's built-in datetime module. +Home-page: https://github.com/zopefoundation/DateTime +Author: Zope Foundation and Contributors +Author-email: zope-dev@zope.org +License: ZPL 2.1 +Classifier: Development Status :: 6 - Mature +Classifier: Environment :: Web Environment +Classifier: Framework :: Zope :: 4 +Classifier: License :: OSI Approved :: Zope Public License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.7 +License-File: LICENSE.txt +Requires-Dist: zope.interface +Requires-Dist: pytz + +.. image:: https://github.com/zopefoundation/DateTime/workflows/tests/badge.svg + :target: https://github.com/zopefoundation/DateTime/actions?query=workflow%3Atests + :alt: CI status + +.. image:: https://img.shields.io/pypi/v/DateTime.svg + :target: https://pypi.org/project/DateTime/ + :alt: Current version on PyPI + +.. image:: https://img.shields.io/pypi/pyversions/DateTime.svg + :target: https://pypi.org/project/DateTime/ + :alt: Supported Python versions + + +DateTime +======== + +This package provides a DateTime data type, as known from Zope. + +Unless you need to communicate with Zope APIs, you're probably better +off using Python's built-in datetime module. + +For further documentation, please have a look at `src/DateTime/DateTime.txt`. + + +.. contents:: + +The DateTime package +==================== + +Encapsulation of date/time values. + + +Function Timezones() +-------------------- + +Returns the list of recognized timezone names: + + >>> from DateTime import Timezones + >>> zones = set(Timezones()) + +Almost all of the standard pytz timezones are included, with the exception +of some commonly-used but ambiguous abbreviations, where historical Zope +usage conflicts with the name used by pytz: + + >>> import pytz + >>> [x for x in pytz.all_timezones if x not in zones] + ['CET', 'EET', 'EST', 'MET', 'MST', 'WET'] + +Class DateTime +-------------- + +DateTime objects represent instants in time and provide interfaces for +controlling its representation without affecting the absolute value of +the object. + +DateTime objects may be created from a wide variety of string or +numeric data, or may be computed from other DateTime objects. +DateTimes support the ability to convert their representations to many +major timezones, as well as the ability to create a DateTime object +in the context of a given timezone. + +DateTime objects provide partial numerical behavior: + +* Two date-time objects can be subtracted to obtain a time, in days + between the two. + +* A date-time object and a positive or negative number may be added to + obtain a new date-time object that is the given number of days later + than the input date-time object. + +* A positive or negative number and a date-time object may be added to + obtain a new date-time object that is the given number of days later + than the input date-time object. + +* A positive or negative number may be subtracted from a date-time + object to obtain a new date-time object that is the given number of + days earlier than the input date-time object. + +DateTime objects may be converted to integer, long, or float numbers +of days since January 1, 1901, using the standard int, long, and float +functions (Compatibility Note: int, long and float return the number +of days since 1901 in GMT rather than local machine timezone). +DateTime objects also provide access to their value in a float format +usable with the Python time module, provided that the value of the +object falls in the range of the epoch-based time module. + +A DateTime object should be considered immutable; all conversion and numeric +operations return a new DateTime object rather than modify the current object. + +A DateTime object always maintains its value as an absolute UTC time, +and is represented in the context of some timezone based on the +arguments used to create the object. A DateTime object's methods +return values based on the timezone context. + +Note that in all cases the local machine timezone is used for +representation if no timezone is specified. + +Constructor for DateTime +------------------------ + +DateTime() returns a new date-time object. DateTimes may be created +with from zero to seven arguments: + +* If the function is called with no arguments, then the current date/ + time is returned, represented in the timezone of the local machine. + +* If the function is invoked with a single string argument which is a + recognized timezone name, an object representing the current time is + returned, represented in the specified timezone. + +* If the function is invoked with a single string argument + representing a valid date/time, an object representing that date/ + time will be returned. + + As a general rule, any date-time representation that is recognized + and unambiguous to a resident of North America is acceptable. (The + reason for this qualification is that in North America, a date like: + 2/1/1994 is interpreted as February 1, 1994, while in some parts of + the world, it is interpreted as January 2, 1994.) A date/ time + string consists of two components, a date component and an optional + time component, separated by one or more spaces. If the time + component is omitted, 12:00am is assumed. + + Any recognized timezone name specified as the final element of the + date/time string will be used for computing the date/time value. + (If you create a DateTime with the string, + "Mar 9, 1997 1:45pm US/Pacific", the value will essentially be the + same as if you had captured time.time() at the specified date and + time on a machine in that timezone). If no timezone is passed, then + the timezone configured on the local machine will be used, **except** + that if the date format matches ISO 8601 ('YYYY-MM-DD'), the instance + will use UTC / GMT+0 as the timezone. + + o Returns current date/time, represented in US/Eastern: + + >>> from DateTime import DateTime + >>> e = DateTime('US/Eastern') + >>> e.timezone() + 'US/Eastern' + + o Returns specified time, represented in local machine zone: + + >>> x = DateTime('1997/3/9 1:45pm') + >>> x.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ...) + + o Specified time in local machine zone, verbose format: + + >>> y = DateTime('Mar 9, 1997 13:45:00') + >>> y.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ...) + >>> y == x + True + + o Specified time in UTC via ISO 8601 rule: + + >>> z = DateTime('2014-03-24') + >>> z.parts() # doctest: +ELLIPSIS + (2014, 3, 24, 0, 0, ...) + >>> z.timezone() + 'GMT+0' + + The date component consists of year, month, and day values. The + year value must be a one-, two-, or four-digit integer. If a one- + or two-digit year is used, the year is assumed to be in the + twentieth century. The month may an integer, from 1 to 12, a month + name, or a month abbreviation, where a period may optionally follow + the abbreviation. The day must be an integer from 1 to the number of + days in the month. The year, month, and day values may be separated + by periods, hyphens, forward slashes, or spaces. Extra spaces are + permitted around the delimiters. Year, month, and day values may be + given in any order as long as it is possible to distinguish the + components. If all three components are numbers that are less than + 13, then a month-day-year ordering is assumed. + + The time component consists of hour, minute, and second values + separated by colons. The hour value must be an integer between 0 + and 23 inclusively. The minute value must be an integer between 0 + and 59 inclusively. The second value may be an integer value + between 0 and 59.999 inclusively. The second value or both the + minute and second values may be omitted. The time may be followed + by am or pm in upper or lower case, in which case a 12-hour clock is + assumed. + +* If the DateTime function is invoked with a single numeric argument, + the number is assumed to be either a floating point value such as + that returned by time.time(), or a number of days after January 1, + 1901 00:00:00 UTC. + + A DateTime object is returned that represents either the GMT value + of the time.time() float represented in the local machine's + timezone, or that number of days after January 1, 1901. Note that + the number of days after 1901 need to be expressed from the + viewpoint of the local machine's timezone. A negative argument will + yield a date-time value before 1901. + +* If the function is invoked with two numeric arguments, then the + first is taken to be an integer year and the second argument is + taken to be an offset in days from the beginning of the year, in the + context of the local machine timezone. The date-time value returned + is the given offset number of days from the beginning of the given + year, represented in the timezone of the local machine. The offset + may be positive or negative. Two-digit years are assumed to be in + the twentieth century. + +* If the function is invoked with two arguments, the first a float + representing a number of seconds past the epoch in GMT (such as + those returned by time.time()) and the second a string naming a + recognized timezone, a DateTime with a value of that GMT time will + be returned, represented in the given timezone. + + >>> import time + >>> t = time.time() + + Time t represented as US/Eastern: + + >>> now_east = DateTime(t, 'US/Eastern') + + Time t represented as US/Pacific: + + >>> now_west = DateTime(t, 'US/Pacific') + + Only their representations are different: + + >>> now_east.equalTo(now_west) + True + +* If the function is invoked with three or more numeric arguments, + then the first is taken to be an integer year, the second is taken + to be an integer month, and the third is taken to be an integer day. + If the combination of values is not valid, then a DateTimeError is + raised. One- or two-digit years up to 69 are assumed to be in the + 21st century, whereas values 70-99 are assumed to be 20th century. + The fourth, fifth, and sixth arguments are floating point, positive + or negative offsets in units of hours, minutes, and days, and + default to zero if not given. An optional string may be given as + the final argument to indicate timezone (the effect of this is as if + you had taken the value of time.time() at that time on a machine in + the specified timezone). + +If a string argument passed to the DateTime constructor cannot be +parsed, it will raise SyntaxError. Invalid date, time, or +timezone components will raise a DateTimeError. + +The module function Timezones() will return a list of the timezones +recognized by the DateTime module. Recognition of timezone names is +case-insensitive. + +Instance Methods for DateTime (IDateTime interface) +--------------------------------------------------- + +Conversion and comparison methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``timeTime()`` returns the date/time as a floating-point number in + UTC, in the format used by the Python time module. Note that it is + possible to create date /time values with DateTime that have no + meaningful value to the time module, and in such cases a + DateTimeError is raised. A DateTime object's value must generally + be between Jan 1, 1970 (or your local machine epoch) and Jan 2038 to + produce a valid time.time() style value. + + >>> dt = DateTime('Mar 9, 1997 13:45:00 US/Eastern') + >>> dt.timeTime() + 857933100.0 + + >>> DateTime('2040/01/01 UTC').timeTime() + 2208988800.0 + + >>> DateTime('1900/01/01 UTC').timeTime() + -2208988800.0 + +* ``toZone(z)`` returns a DateTime with the value as the current + object, represented in the indicated timezone: + + >>> dt.toZone('UTC') + DateTime('1997/03/09 18:45:00 UTC') + + >>> dt.toZone('UTC').equalTo(dt) + True + +* ``isFuture()`` returns true if this object represents a date/time + later than the time of the call: + + >>> dt.isFuture() + False + >>> DateTime('Jan 1 3000').isFuture() # not time-machine safe! + True + +* ``isPast()`` returns true if this object represents a date/time + earlier than the time of the call: + + >>> dt.isPast() + True + >>> DateTime('Jan 1 3000').isPast() # not time-machine safe! + False + +* ``isCurrentYear()`` returns true if this object represents a + date/time that falls within the current year, in the context of this + object's timezone representation: + + >>> dt.isCurrentYear() + False + >>> DateTime().isCurrentYear() + True + +* ``isCurrentMonth()`` returns true if this object represents a + date/time that falls within the current month, in the context of + this object's timezone representation: + + >>> dt.isCurrentMonth() + False + >>> DateTime().isCurrentMonth() + True + +* ``isCurrentDay()`` returns true if this object represents a + date/time that falls within the current day, in the context of this + object's timezone representation: + + >>> dt.isCurrentDay() + False + >>> DateTime().isCurrentDay() + True + +* ``isCurrentHour()`` returns true if this object represents a + date/time that falls within the current hour, in the context of this + object's timezone representation: + + >>> dt.isCurrentHour() + False + + >>> DateTime().isCurrentHour() + True + +* ``isCurrentMinute()`` returns true if this object represents a + date/time that falls within the current minute, in the context of + this object's timezone representation: + + >>> dt.isCurrentMinute() + False + >>> DateTime().isCurrentMinute() + True + +* ``isLeapYear()`` returns true if the current year (in the context of + the object's timezone) is a leap year: + + >>> dt.isLeapYear() + False + >>> DateTime('Mar 8 2004').isLeapYear() + True + +* ``earliestTime()`` returns a new DateTime object that represents the + earliest possible time (in whole seconds) that still falls within + the current object's day, in the object's timezone context: + + >>> dt.earliestTime() + DateTime('1997/03/09 00:00:00 US/Eastern') + +* ``latestTime()`` return a new DateTime object that represents the + latest possible time (in whole seconds) that still falls within the + current object's day, in the object's timezone context + + >>> dt.latestTime() + DateTime('1997/03/09 23:59:59 US/Eastern') + +Component access +~~~~~~~~~~~~~~~~ + +* ``parts()`` returns a tuple containing the calendar year, month, + day, hour, minute second and timezone of the object + + >>> dt.parts() # doctest: +ELLIPSIS + (1997, 3, 9, 13, 45, ... 'US/Eastern') + +* ``timezone()`` returns the timezone in which the object is represented: + + >>> dt.timezone() in Timezones() + True + +* ``tzoffset()`` returns the timezone offset for the objects timezone: + + >>> dt.tzoffset() + -18000 + +* ``year()`` returns the calendar year of the object: + + >>> dt.year() + 1997 + +* ``month()`` returns the month of the object as an integer: + + >>> dt.month() + 3 + +* ``Month()`` returns the full month name: + + >>> dt.Month() + 'March' + +* ``aMonth()`` returns the abbreviated month name: + + >>> dt.aMonth() + 'Mar' + +* ``pMonth()`` returns the abbreviated (with period) month name: + + >>> dt.pMonth() + 'Mar.' + +* ``day()`` returns the integer day: + + >>> dt.day() + 9 + +* ``Day()`` returns the full name of the day of the week: + + >>> dt.Day() + 'Sunday' + +* ``dayOfYear()`` returns the day of the year, in context of the + timezone representation of the object: + + >>> dt.dayOfYear() + 68 + +* ``aDay()`` returns the abbreviated name of the day of the week: + + >>> dt.aDay() + 'Sun' + +* ``pDay()`` returns the abbreviated (with period) name of the day of + the week: + + >>> dt.pDay() + 'Sun.' + +* ``dow()`` returns the integer day of the week, where Sunday is 0: + + >>> dt.dow() + 0 + +* ``dow_1()`` returns the integer day of the week, where sunday is 1: + + >>> dt.dow_1() + 1 + +* ``h_12()`` returns the 12-hour clock representation of the hour: + + >>> dt.h_12() + 1 + +* ``h_24()`` returns the 24-hour clock representation of the hour: + + >>> dt.h_24() + 13 + +* ``ampm()`` returns the appropriate time modifier (am or pm): + + >>> dt.ampm() + 'pm' + +* ``hour()`` returns the 24-hour clock representation of the hour: + + >>> dt.hour() + 13 + +* ``minute()`` returns the minute: + + >>> dt.minute() + 45 + +* ``second()`` returns the second: + + >>> dt.second() == 0 + True + +* ``millis()`` returns the milliseconds since the epoch in GMT. + + >>> dt.millis() == 857933100000 + True + +strftime() +~~~~~~~~~~ + +See ``tests/test_datetime.py``. + +General formats from previous DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``Date()`` return the date string for the object: + + >>> dt.Date() + '1997/03/09' + +* ``Time()`` returns the time string for an object to the nearest + second: + + >>> dt.Time() + '13:45:00' + +* ``TimeMinutes()`` returns the time string for an object not showing + seconds: + + >>> dt.TimeMinutes() + '13:45' + +* ``AMPM()`` returns the time string for an object to the nearest second: + + >>> dt.AMPM() + '01:45:00 pm' + +* ``AMPMMinutes()`` returns the time string for an object not showing + seconds: + + >>> dt.AMPMMinutes() + '01:45 pm' + +* ``PreciseTime()`` returns the time string for the object: + + >>> dt.PreciseTime() + '13:45:00.000' + +* ``PreciseAMPM()`` returns the time string for the object: + + >>> dt.PreciseAMPM() + '01:45:00.000 pm' + +* ``yy()`` returns the calendar year as a 2 digit string + + >>> dt.yy() + '97' + +* ``mm()`` returns the month as a 2 digit string + + >>> dt.mm() + '03' + +* ``dd()`` returns the day as a 2 digit string: + + >>> dt.dd() + '09' + +* ``rfc822()`` returns the date in RFC 822 format: + + >>> dt.rfc822() + 'Sun, 09 Mar 1997 13:45:00 -0500' + +New formats +~~~~~~~~~~~ + +* ``fCommon()`` returns a string representing the object's value in + the format: March 9, 1997 1:45 pm: + + >>> dt.fCommon() + 'March 9, 1997 1:45 pm' + +* ``fCommonZ()`` returns a string representing the object's value in + the format: March 9, 1997 1:45 pm US/Eastern: + + >>> dt.fCommonZ() + 'March 9, 1997 1:45 pm US/Eastern' + +* ``aCommon()`` returns a string representing the object's value in + the format: Mar 9, 1997 1:45 pm: + + >>> dt.aCommon() + 'Mar 9, 1997 1:45 pm' + +* ``aCommonZ()`` return a string representing the object's value in + the format: Mar 9, 1997 1:45 pm US/Eastern: + + >>> dt.aCommonZ() + 'Mar 9, 1997 1:45 pm US/Eastern' + +* ``pCommon()`` returns a string representing the object's value in + the format Mar. 9, 1997 1:45 pm: + + >>> dt.pCommon() + 'Mar. 9, 1997 1:45 pm' + +* ``pCommonZ()`` returns a string representing the object's value in + the format: Mar. 9, 1997 1:45 pm US/Eastern: + + >>> dt.pCommonZ() + 'Mar. 9, 1997 1:45 pm US/Eastern' + +* ``ISO()`` returns a string with the date/time in ISO format. Note: + this is not ISO 8601-format! See the ISO8601 and HTML4 methods below + for ISO 8601-compliant output. Dates are output as: YYYY-MM-DD HH:MM:SS + + >>> dt.ISO() + '1997-03-09 13:45:00' + +* ``ISO8601()`` returns the object in ISO 8601-compatible format + containing the date, time with seconds-precision and the time zone + identifier - see http://www.w3.org/TR/NOTE-datetime. Dates are + output as: YYYY-MM-DDTHH:MM:SSTZD (T is a literal character, TZD is + Time Zone Designator, format +HH:MM or -HH:MM). + + The ``HTML4()`` method below offers the same formatting, but + converts to UTC before returning the value and sets the TZD"Z" + + >>> dt.ISO8601() + '1997-03-09T13:45:00-05:00' + + +* ``HTML4()`` returns the object in the format used in the HTML4.0 + specification, one of the standard forms in ISO8601. See + http://www.w3.org/TR/NOTE-datetime. Dates are output as: + YYYY-MM-DDTHH:MM:SSZ (T, Z are literal characters, the time is in + UTC.): + + >>> dt.HTML4() + '1997-03-09T18:45:00Z' + +* ``JulianDay()`` returns the Julian day according to + http://www.tondering.dk/claus/cal/node3.html#sec-calcjd + + >>> dt.JulianDay() + 2450517 + +* ``week()`` returns the week number according to ISO + see http://www.tondering.dk/claus/cal/node6.html#SECTION00670000000000000000 + + >>> dt.week() + 10 + +Deprecated API +~~~~~~~~~~~~~~ + +* DayOfWeek(): see Day() + +* Day_(): see pDay() + +* Mon(): see aMonth() + +* Mon_(): see pMonth + +General Services Provided by DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DateTimes can be repr()'ed; the result will be a string indicating how +to make a DateTime object like this: + + >>> repr(dt) + "DateTime('1997/03/09 13:45:00 US/Eastern')" + +When we convert them into a string, we get a nicer string that could +actually be shown to a user: + + >>> str(dt) + '1997/03/09 13:45:00 US/Eastern' + +The hash value of a DateTime is based on the date and time and is +equal for different representations of the DateTime: + + >>> hash(dt) + 3618678 + >>> hash(dt.toZone('UTC')) + 3618678 + +DateTime objects can be compared to other DateTime objects OR floating +point numbers such as the ones which are returned by the Python time +module by using the equalTo method. Using this API, True is returned if the +object represents a date/time equal to the specified DateTime or time module +style time: + + >>> dt.equalTo(dt) + True + >>> dt.equalTo(dt.toZone('UTC')) + True + >>> dt.equalTo(dt.timeTime()) + True + >>> dt.equalTo(DateTime()) + False + +Same goes for inequalities: + + >>> dt.notEqualTo(dt) + False + >>> dt.notEqualTo(dt.toZone('UTC')) + False + >>> dt.notEqualTo(dt.timeTime()) + False + >>> dt.notEqualTo(DateTime()) + True + +Normal equality operations only work with DateTime objects and take the +timezone setting into account: + + >>> dt == dt + True + >>> dt == dt.toZone('UTC') + False + >>> dt == DateTime() + False + + >>> dt != dt + False + >>> dt != dt.toZone('UTC') + True + >>> dt != DateTime() + True + +But the other comparison operations compare the referenced moment in time and +not the representation itself: + + >>> dt > dt + False + >>> DateTime() > dt + True + >>> dt > DateTime().timeTime() + False + >>> DateTime().timeTime() > dt + True + + >>> dt.greaterThan(dt) + False + >>> DateTime().greaterThan(dt) + True + >>> dt.greaterThan(DateTime().timeTime()) + False + + >>> dt >= dt + True + >>> DateTime() >= dt + True + >>> dt >= DateTime().timeTime() + False + >>> DateTime().timeTime() >= dt + True + + >>> dt.greaterThanEqualTo(dt) + True + >>> DateTime().greaterThanEqualTo(dt) + True + >>> dt.greaterThanEqualTo(DateTime().timeTime()) + False + + >>> dt < dt + False + >>> DateTime() < dt + False + >>> dt < DateTime().timeTime() + True + >>> DateTime().timeTime() < dt + False + + >>> dt.lessThan(dt) + False + >>> DateTime().lessThan(dt) + False + >>> dt.lessThan(DateTime().timeTime()) + True + + >>> dt <= dt + True + >>> DateTime() <= dt + False + >>> dt <= DateTime().timeTime() + True + >>> DateTime().timeTime() <= dt + False + + >>> dt.lessThanEqualTo(dt) + True + >>> DateTime().lessThanEqualTo(dt) + False + >>> dt.lessThanEqualTo(DateTime().timeTime()) + True + +Numeric Services Provided by DateTime +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A DateTime may be added to a number and a number may be added to a +DateTime: + + >>> dt + 5 + DateTime('1997/03/14 13:45:00 US/Eastern') + >>> 5 + dt + DateTime('1997/03/14 13:45:00 US/Eastern') + +Two DateTimes cannot be added: + + >>> from DateTime.interfaces import DateTimeError + >>> try: + ... dt + dt + ... print('fail') + ... except DateTimeError: + ... print('ok') + ok + +Either a DateTime or a number may be subtracted from a DateTime, +however, a DateTime may not be subtracted from a number: + + >>> DateTime('1997/03/10 13:45 US/Eastern') - dt + 1.0 + >>> dt - 1 + DateTime('1997/03/08 13:45:00 US/Eastern') + >>> 1 - dt + Traceback (most recent call last): + ... + TypeError: unsupported operand type(s) for -: 'int' and 'DateTime' + +DateTimes can also be converted to integers (number of seconds since +the epoch) and floats: + + >>> int(dt) + 857933100 + >>> float(dt) + 857933100.0 + + +Changelog +========= + +5.4 (2023-12-15) +---------------- + +- Fix ``UnknownTimeZoneError`` when unpickling ``DateTime.DateTime().asdatetime()``. + (`#58 `_) + +- Repair equality comparison between DateTime instances and other types. + (`#60 `_) + + +5.3 (2023-11-14) +---------------- + +- Add support for Python 3.12. + +- Add preliminary support for Python 3.13a2. + + +5.2 (2023-07-19) +---------------- + +- Cast int to float in compare methods. +- Fix compare methods between DateTime instances and None. + (`#52 `_) + + +5.1 (2023-03-14) +---------------- + +- Add missing ``python_requires`` to ``setup.py``. + + +5.0 (2023-01-12) +---------------- + +- Drop support for Python 2.7, 3.5, 3.6. + + +4.8 (2022-12-16) +---------------- + +- Fix insidious buildout configuration bug that prevented tests on Python 2.7 + and 3.5, and fix test code that was incompatible with Python 3.5. + (`#44 `_) + +- Add support for Python 3.11. + + +4.7 (2022-09-14) +---------------- + +- Fix rounding problem with `DateTime` addition beyond the year 2038 + (`#41 `_) + + +4.6 (2022-09-10) +---------------- + +- Fix ``__format__`` method for DateTime objects + (`#39 `_) + + +4.5 (2022-07-04) +---------------- + +- Add ``__format__`` method for DateTime objects + (`#35 `_) + + +4.4 (2022-02-11) +---------------- + +- Fix WAT definition + `#31 `_. + +- Add support for Python 3.8, 3.9, and 3.10. + +- Drop support for Python 3.4. + +4.3 (2018-10-05) +---------------- + +- Add support for Python 3.7. + +4.2 (2017-04-26) +---------------- + +- Add support for Python 3.6, drop support for Python 3.3. + +4.1.1 (2016-04-30) +------------------ + +- Support unpickling instances having a numeric timezone like `+0430`. + +4.1 (2016-04-03) +---------------- + +- Add support for Python 3.4 and 3.5. + +- Drop support for Python 2.6 and 3.2. + +4.0.1 (2013-10-15) +------------------ + +- Provide more backward compatible timezones. + [vangheem] + +4.0 (2013-02-23) +---------------- + +- Added support for Python 3.2 and 3.3 in addition to 2.6 and 2.7. + +- Removed unused legacy pytz tests and the DateTimeZone module and renamed + some test internals. + +3.0.3 (2013-01-22) +------------------ + +- Allow timezone argument to be a Unicode string while creating a DateTime + object using two arguments. + +3.0.2 (2012-10-21) +------------------ + +- LP #1045233: Respect date format setting for parsing dates like `11-01-2001`. + +3.0.1 (2012-09-23) +------------------ + +- Add `_dt_reconstructor` function introduced in DateTime 2.12.7 to provide + forward compatibility with pickles that might reference this function. + +3.0 (2011-12-09) +---------------- + +- No changes. + +Backwards compatibility of DateTime 3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DateTime 3 changes its pickle representation. DateTime instances pickled with +former versions of DateTime can be read, but older DateTime versions cannot read +DateTime instances pickled with version 3. + +DateTime 3 changes DateTime to be a new-style class with slots instead of being +an old-style class. + +DateTime 3 tries to preserve microsecond resolution throughout most of its API's +while former versions were often only accurate to millisecond resolution. Due to +the representation of float values in Python versions before Python 2.7 you +shouldn't compare string or float representations of DateTime instances if you +want high accuracy. The same is true for calculated values returned by methods +like `timeTime()`. You get the highest accuracy of comparing DateTime values by +calling its `micros()` methods. DateTime is not particular well suited to be +used in comparing timestamps of file systems - use the time and datetime objects +from the Python standard library instead. + +3.0b3 (2011-10-19) +------------------ + +- Allow comparison of DateTime objects against None. + +3.0b2 (2011-10-19) +------------------ + +- Reverted the single argument `None` special case handling for unpickling and + continue to treat it as meaning `now`. + +3.0b1 (2011-05-07) +------------------ + +- Restored `strftimeFormatter` as a class. + +- Added tests for read-only class attributes and interface. + +3.0a2 (2011-05-07) +------------------ + +- Added back support for reading old DateTime pickles without a `_micros` value. + +- Avoid storing `_t` representing the time as a float in seconds since the + epoch, as we already have `_micros` doing the same as a long. Memory use is + down to about 300 bytes per DateTime instance. + +- Updated exception raising syntax to current style. + +- Avoid storing `_aday`, `_fday`, `_pday`, `_amon`, `_fmon`, `_pmon`, `_pmhour` + and `_pm` in memory for every instance but look them up dynamically based on + `_dayoffset`, `_month` and `_hour`. This saves another 150 bytes of memory + per DateTime instance. + +- Moved various internal parsing related class variables to module constants. + +- No longer provide the `DateError`, `DateTimeError`, `SyntaxError` and + `TimeError` exceptions as class attributes, import them from their canonical + `DateTime.interfaces` location instead. + +- Removed deprecated `_isDST` and `_localzone` class variables. + +- Moved pytz cache from `DateTime._tzinfo` to a module global `_TZINFO`. + +- Make DateTime a new-style class and limit its available attributes via a + slots definition. The pickle size increases to 110 bytes thanks to the + `ccopy_reg\n_reconstructor` stanza. But the memory size drops from 3kb to + 500 bytes for each instance. + +3.0a1 (2011-05-06) +------------------ + +- Reordered some calculations in `_calcIndependentSecondEtc` to preserve more + floating point precision. + +- Optimized the pickled data, by only storing a tuple of `_micros` and time + zone information - this reduces the pickle size from an average of 300 bytes + to just 60 bytes. + +- Optimized un-pickling, by avoiding the creation of an intermediate DateTime + value representing the current time. + +- Removed in-place migration of old DateTime pickles without a `_micros` value. + +- Removed deprecated support for using `DateTime.__cmp__`. + +- Take time zone settings into account when comparing two date times for + (non-) equality. + +- Fixed (possibly unused) _parse_iso8601 function. + +- Removed unused import of legacy DateTimeZone, strftime and re. + Remove trailing whitespace. + +- Removed reference to missing version section from buildout. + +2.12.7 (2012-08-11) +------------------- + +- Added forward compatibility with DateTime 3 pickle format. DateTime + instances constructed under version 3 can be read and unpickled by this + version. The pickled data is converted to the current versions format + (old-style class / no slots). Once converted it will be stored again in the + old format. This should allow for a transparent upgrade/downgrade path + between DateTime 2 and 3. + +2.12.6 (2010-10-17) +------------------- + +- Changed ``testDayOfWeek`` test to be independent of OS locale. + +2.12.5 (2010-07-29) +------------------- + +- Launchpad #143269: Corrected the documentation for year value + behavior when constructing a DateTime object with three numeric + arguments. + +- Launchpad #142521: Removed confusing special case in + DateTime.__str__ where DateTime instances for midnight + (e.g. '2010-07-27 00:00:00 US/Eastern') values would + render only their date and nothing else. + +2.12.4 (2010-07-12) +------------------- + +- Fixed mapping of EDT (was -> 'GMT-0400', now 'GMT-4'). + +2.12.3 (2010-07-09) +------------------- + +- Added EDT timezone support. Addresses bug #599856. + [vangheem] + +2.12.2 (2010-05-05) +------------------- + +- Launchpad #572715: Relaxed pin on pytz, after applying a patch from + Marius Gedminus which fixes the apparent API breakage. + +2.12.1 (2010-04-30) +------------------- + +- Removed an undeclared testing dependency on zope.testing.doctest in favor of + the standard libraries doctest module. + +- Added a maximum version requirement on pytz <= 2010b. Later versions produce + test failures related to timezone changes. + +2.12.0 (2009-03-04) +------------------- + +- Launchpad #290254: Forward-ported fix for '_micros'-less pickles from + the Zope 2.11 branch version. + +2.11.2 (2009-02-02) +------------------- + +- Include *all* pytz zone names, not just "common" ones. + +- Fix one fragile doctest, band-aid another. + +- Fix for launchpad #267545: DateTime(DateTime()) should preserve the + correct hour. + +2.11.1 (2008-08-05) +------------------- + +- DateTime conversion of datetime objects with non-pytz tzinfo. Timezones() + returns a copy of the timezone list (allows tests to run). + +- Merged the slinkp-datetime-200007 branch: fix the DateTime(anotherDateTime) + constructor to preserve timezones. + +2.11.0b1 (2008-01-06) +--------------------- + +- Split off from the Zope2 main source code tree. diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/RECORD b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/RECORD new file mode 100644 index 00000000..59a993bc --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/RECORD @@ -0,0 +1,22 @@ +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/interfaces.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/pytz_support.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/__init__.cpython-39.pyc,, +../../../../../../Library/Caches/com.apple.python/Users/billchen/Desktop/dbdpy/dbdpy-env/lib/python3.9/site-packages/DateTime/tests/test_datetime.cpython-39.pyc,, +DateTime-5.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +DateTime-5.4.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070 +DateTime-5.4.dist-info/METADATA,sha256=aa2Ts6CsOlO4gtI6h7mS3CKb_ViWN_f5OcPDRCnvQOs,33527 +DateTime-5.4.dist-info/RECORD,, +DateTime-5.4.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +DateTime-5.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +DateTime-5.4.dist-info/top_level.txt,sha256=iVdUvuV_RIkkMzsnPGNfwojRWvuonInryaK3hA5Hh0o,9 +DateTime/DateTime.py,sha256=dtd-xuhJPPYbtg4Z-vRKdMNO81I-Zu2baNZ6gVzC1WY,71351 +DateTime/DateTime.txt,sha256=KZFzxoQItLsar1ZDd2vZN74Y6L4a04H8jXMwqc8KjmY,22487 +DateTime/__init__.py,sha256=trlFzEmNkmUpxZT7krPSVDayDK1bRxToccg3CcCF8wg,714 +DateTime/interfaces.py,sha256=n47sexf1eQ6YMdYB_60PgHtSzYIj4FND-RmHFiNpm1E,12187 +DateTime/pytz.txt,sha256=9Phns9ESXs9MaOKxXztX6sJ09QczGxsbYoSRSllKUfk,5619 +DateTime/pytz_support.py,sha256=inR1SO0X17fp9C2GsRw99S_MhxKiEt5dOV3-TGsBxDI,11853 +DateTime/tests/__init__.py,sha256=H7Ixo1xp-8BlJ65u14hk5i_TKEmETyi2FmLMD6H-mpo,683 +DateTime/tests/julian_testdata.txt,sha256=qxvLvabVB9ayhh5UHBvPhuqW5mRL_lizzbUh6lc3d4I,1397 +DateTime/tests/test_datetime.py,sha256=J0bzZHJECSmYwHbXM7IhN7AIJLAvZVPhTyTbSfx0xQs,29598 diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/REQUESTED b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/WHEEL b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/WHEEL new file mode 100644 index 00000000..98c0d20b --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/top_level.txt b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/top_level.txt new file mode 100644 index 00000000..1b8c206f --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime-5.4.dist-info/top_level.txt @@ -0,0 +1 @@ +DateTime diff --git a/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.py b/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.py new file mode 100644 index 00000000..8e1ec6da --- /dev/null +++ b/dbdpy-env/lib/python3.9/site-packages/DateTime/DateTime.py @@ -0,0 +1,1946 @@ +############################################################################## +# +# Copyright (c) 2002 Zope Foundation and Contributors. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## + +import copyreg as copy_reg +import math +import re +from datetime import datetime +from time import altzone +from time import daylight +from time import gmtime +from time import localtime +from time import time +from time import timezone +from time import tzname + +from zope.interface import implementer + +from .interfaces import DateError +from .interfaces import DateTimeError +from .interfaces import IDateTime +from .interfaces import SyntaxError +from .interfaces import TimeError +from .pytz_support import PytzCache + + +basestring = str +long = int +explicit_unicode_type = type(None) + +default_datefmt = None + + +def getDefaultDateFormat(): + global default_datefmt + if default_datefmt is None: + try: + from App.config import getConfiguration + default_datefmt = getConfiguration().datetime_format + return default_datefmt + except Exception: + return 'us' + else: + return default_datefmt + + +# To control rounding errors, we round system time to the nearest +# microsecond. Then delicate calculations can rely on the fact that the +# maximum precision that needs to be preserved is known. +_system_time = time + + +def time(): + return round(_system_time(), 6) + + +# Determine machine epoch +tm = ((0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334), + (0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335)) +yr, mo, dy, hr, mn, sc = gmtime(0)[:6] +i = int(yr - 1) +to_year = int(i * 365 + i // 4 - i // 100 + i // 400 - 693960.0) +to_month = tm[yr % 4 == 0 and (yr % 100 != 0 or yr % 400 == 0)][mo] +EPOCH = ((to_year + to_month + dy + + (hr / 24.0 + mn / 1440.0 + sc / 86400.0)) * 86400) +jd1901 = 2415385 + +_TZINFO = PytzCache() + +INT_PATTERN = re.compile(r'([0-9]+)') +FLT_PATTERN = re.compile(r':([0-9]+\.[0-9]+)') +NAME_PATTERN = re.compile(r'([a-zA-Z]+)', re.I) +SPACE_CHARS = ' \t\n' +DELIMITERS = '-/.:,+' + +_MONTH_LEN = ((0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), + (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)) +_MONTHS = ('', 'January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December') +_MONTHS_A = ('', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') +_MONTHS_P = ('', 'Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'June', + 'July', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.') +_MONTHMAP = {'january': 1, 'jan': 1, + 'february': 2, 'feb': 2, + 'march': 3, 'mar': 3, + 'april': 4, 'apr': 4, + 'may': 5, + 'june': 6, 'jun': 6, + 'july': 7, 'jul': 7, + 'august': 8, 'aug': 8, + 'september': 9, 'sep': 9, 'sept': 9, + 'october': 10, 'oct': 10, + 'november': 11, 'nov': 11, + 'december': 12, 'dec': 12} +_DAYS = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', + 'Thursday', 'Friday', 'Saturday') +_DAYS_A = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat') +_DAYS_P = ('Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.') +_DAYMAP = {'sunday': 1, 'sun': 1, + 'monday': 2, 'mon': 2, + 'tuesday': 3, 'tues': 3, 'tue': 3, + 'wednesday': 4, 'wed': 4, + 'thursday': 5, 'thurs': 5, 'thur': 5, 'thu': 5, + 'friday': 6, 'fri': 6, + 'saturday': 7, 'sat': 7} + +numericTimeZoneMatch = re.compile(r'[+-][0-9][0-9][0-9][0-9]').match +iso8601Match = re.compile(r''' + (?P\d\d\d\d) # four digits year + (?:-? # one optional dash + (?: # followed by: + (?P\d\d\d # three digits year day + (?!\d)) # when there is no fourth digit + | # or: + W # one W + (?P\d\d) # two digits week + (?:-? # one optional dash + (?P\d) # one digit week day + )? # week day is optional + | # or: + (?P\d\d)? # two digits month + (?:-? # one optional dash + (?P\d\d)? # two digits day + )? # after day is optional + ) # + )? # after year is optional + (?:[T ] # one T or one whitespace + (?P\d\d) # two digits hour + (?::? # one optional colon + (?P\d\d)? # two digits minute + (?::? # one optional colon + (?P\d\d)? # two digits second + (?:[.,] # one dot or one comma + (?P\d+) # n digits fraction + )? # after second is optional + )? # after minute is optional + )? # after hour is optional + (?: # timezone: + (?PZ) # one Z + | # or: + (?P[-+]) # one plus or one minus as signal + (?P\d # one digit for hour offset... + (?:\d(?!\d$) # ...or two, if not the last two digits + )?) # second hour offset digit is optional + (?::? # one optional colon + (?P\d\d) # two digits minute offset + )? # after hour offset is optional + )? # timezone is optional + )? # time is optional + (?P.*) # store the extra garbage +''', re.VERBOSE).match + + +def _findLocalTimeZoneName(isDST): + if not daylight: + # Daylight savings does not occur in this time zone. + isDST = 0 + try: + # Get the name of the current time zone depending + # on DST. + _localzone = PytzCache._zmap[tzname[isDST].lower()] + except BaseException: + try: + # Generate a GMT-offset zone name. + if isDST: + localzone = altzone + else: + localzone = timezone + offset = (-localzone / 3600.0) + majorOffset = int(offset) + if majorOffset != 0: + minorOffset = abs(int((offset % majorOffset) * 60.0)) + else: + minorOffset = 0 + m = majorOffset >= 0 and '+' or '' + lz = '%s%0.02d%0.02d' % (m, majorOffset, minorOffset) + _localzone = PytzCache._zmap[('GMT%s' % lz).lower()] + except BaseException: + _localzone = '' + return _localzone + + +_localzone0 = _findLocalTimeZoneName(0) +_localzone1 = _findLocalTimeZoneName(1) +_multipleZones = (_localzone0 != _localzone1) + +# Some utility functions for calculating dates: + + +def _calcSD(t): + # Returns timezone-independent days since epoch and the fractional + # part of the days. + dd = t + EPOCH - 86400.0 + d = dd / 86400.0 + s = d - math.floor(d) + return s, d + + +def _calcDependentSecond(tz, t): + # Calculates the timezone-dependent second (integer part only) + # from the timezone-independent second. + fset = _tzoffset(tz, t) + return fset + long(math.floor(t)) + long(EPOCH) - 86400 + + +def _calcDependentSecond2(yr, mo, dy, hr, mn, sc): + # Calculates the timezone-dependent second (integer part only) + # from the date given. + ss = int(hr) * 3600 + int(mn) * 60 + int(sc) + x = long(_julianday(yr, mo, dy) - jd1901) * 86400 + ss + return x + + +def _calcIndependentSecondEtc(tz, x, ms): + # Derive the timezone-independent second from the timezone + # dependent second. + fsetAtEpoch = _tzoffset(tz, 0.0) + nearTime = x - fsetAtEpoch - long(EPOCH) + 86400 + ms + # nearTime is now within an hour of being correct. + # Recalculate t according to DST. + fset = long(_tzoffset(tz, nearTime)) + d = (x - fset) / 86400.0 + (ms / 86400.0) + t = x - fset - long(EPOCH) + 86400 + ms + micros = (x + 86400 - fset) * 1000000 + \ + long(round(ms * 1000000.0)) - long(EPOCH * 1000000.0) + s = d - math.floor(d) + return (s, d, t, micros) + + +def _calcHMS(x, ms): + # hours, minutes, seconds from integer and float. + hr = x // 3600 + x = x - hr * 3600 + mn = x // 60 + sc = x - mn * 60 + ms + return (hr, mn, sc) + + +def _calcYMDHMS(x, ms): + # x is a timezone-dependent integer of seconds. + # Produces yr,mo,dy,hr,mn,sc. + yr, mo, dy = _calendarday(x // 86400 + jd1901) + x = int(x - (x // 86400) * 86400) + hr = x // 3600 + x = x - hr * 3600 + mn = x // 60 + sc = x - mn * 60 + ms + return (yr, mo, dy, hr, mn, sc) + + +def _julianday(yr, mo, dy): + y, m, d = long(yr), long(mo), long(dy) + if m > 12: + y = y + m // 12 + m = m % 12 + elif m < 1: + m = -m + y = y - m // 12 - 1 + m = 12 - m % 12 + if y > 0: + yr_correct = 0 + else: + yr_correct = 3 + if m < 3: + y, m = y - 1, m + 12 + if y * 10000 + m * 100 + d > 15821014: + b = 2 - y // 100 + y // 400 + else: + b = 0 + return ((1461 * y - yr_correct) // 4 + + 306001 * (m + 1) // 10000 + d + 1720994 + b) + + +def _calendarday(j): + j = long(j) + if (j < 2299160): + b = j + 1525 + else: + a = (4 * j - 7468861) // 146097 + b = j + 1526 + a - a // 4 + c = (20 * b - 2442) // 7305 + d = 1461 * c // 4 + e = 10000 * (b - d) // 306001 + dy = int(b - d - 306001 * e // 10000) + mo = (e < 14) and int(e - 1) or int(e - 13) + yr = (mo > 2) and (c - 4716) or (c - 4715) + return (int(yr), int(mo), int(dy)) + + +def _tzoffset(tz, t): + """Returns the offset in seconds to GMT from a specific timezone (tz) at + a specific time (t). NB! The _tzoffset result is the same same sign as + the time zone, i.e. GMT+2 has a 7200 second offset. This is the opposite + sign of time.timezone which (confusingly) is -7200 for GMT+2.""" + try: + return _TZINFO[tz].info(t)[0] + except Exception: + if numericTimeZoneMatch(tz) is not None: + return int(tz[0:3]) * 3600 + int(tz[0] + tz[3:5]) * 60 + else: + return 0 # ?? + + +def _correctYear(year): + # Y2K patch. + if year >= 0 and year < 100: + # 00-69 means 2000-2069, 70-99 means 1970-1999. + if year < 70: + year = 2000 + year + else: + year = 1900 + year + return year + + +def safegmtime(t): + '''gmtime with a safety zone.''' + try: + return gmtime(t) + except (ValueError, OverflowError): + raise TimeError('The time %f is beyond the range of this Python ' + 'implementation.' % float(t)) + + +def safelocaltime(t): + '''localtime with a safety zone.''' + try: + return localtime(t) + except (ValueError, OverflowError): + raise TimeError('The time %f is beyond the range of this Python ' + 'implementation.' % float(t)) + + +def _tzoffset2rfc822zone(seconds): + """Takes an offset, such as from _tzoffset(), and returns an rfc822 + compliant zone specification. Please note that the result of + _tzoffset() is the negative of what time.localzone and time.altzone is. + """ + return "%+03d%02d" % divmod((seconds // 60), 60) + + +def _tzoffset2iso8601zone(seconds): + """Takes an offset, such as from _tzoffset(), and returns an ISO 8601 + compliant zone specification. Please note that the result of + _tzoffset() is the negative of what time.localzone and time.altzone is. + """ + return "%+03d:%02d" % divmod((seconds // 60), 60) + + +def Timezones(): + """Return the list of recognized timezone names""" + return sorted(list(PytzCache._zmap.values())) + + +class strftimeFormatter: + + def __init__(self, dt, format): + self.dt = dt + self.format = format + + def __call__(self): + return self.dt.strftime(self.format) + + +@implementer(IDateTime) +class DateTime: + """DateTime objects represent instants in time and provide + interfaces for controlling its representation without + affecting the absolute value of the object. + + DateTime objects may be created from a wide variety of string + or numeric data, or may be computed from other DateTime objects. + DateTimes support the ability to convert their representations + to many major timezones, as well as the ability to create a + DateTime object in the context of a given timezone. + + DateTime objects provide partial numerical behavior: + + - Two date-time objects can be subtracted to obtain a time, + in days between the two. + + - A date-time object and a positive or negative number may + be added to obtain a new date-time object that is the given + number of days later than the input date-time object. + + - A positive or negative number and a date-time object may + be added to obtain a new date-time object that is the given + number of days later than the input date-time object. + + - A positive or negative number may be subtracted from a + date-time object to obtain a new date-time object that is + the given number of days earlier than the input date-time + object. + + DateTime objects may be converted to integer, long, or float + numbers of days since January 1, 1901, using the standard int, + long, and float functions (Compatibility Note: int, long and + float return the number of days since 1901 in GMT rather than + local machine timezone). DateTime objects also provide access + to their value in a float format usable with the Python time + module, provided that the value of the object falls in the + range of the epoch-based time module, and as a datetime.datetime + object. + + A DateTime object should be considered immutable; all conversion + and numeric operations return a new DateTime object rather than + modify the current object.""" + + # For security machinery: + __roles__ = None + __allow_access_to_unprotected_subobjects__ = 1 + + # Limit the amount of instance attributes + __slots__ = ( + '_timezone_naive', + '_tz', + '_dayoffset', + '_year', + '_month', + '_day', + '_hour', + '_minute', + '_second', + '_nearsec', + '_d', + '_micros', + 'time', + ) + + def __init__(self, *args, **kw): + """Return a new date-time object""" + try: + return self._parse_args(*args, **kw) + except (DateError, TimeError, DateTimeError): + raise + except Exception: + raise SyntaxError('Unable to parse {}, {}'.format(args, kw)) + + def __getstate__(self): + # We store a float of _micros, instead of the _micros long, as we most + # often don't have any sub-second resolution and can save those bytes + return (self._micros / 1000000.0, + getattr(self, '_timezone_naive', False), + self._tz) + + def __setstate__(self, value): + if isinstance(value, tuple): + self._parse_args(value[0], value[2]) + self._micros = long(value[0] * 1000000) + self._timezone_naive = value[1] + else: + for k, v in value.items(): + if k in self.__slots__: + setattr(self, k, v) + # BBB: support for very old DateTime pickles + if '_micros' not in value: + self._micros = long(value['_t'] * 1000000) + if '_timezone_naive' not in value: + self._timezone_naive = False + + def _parse_args(self, *args, **kw): + """Return a new date-time object. + + A DateTime object always maintains its value as an absolute + UTC time, and is represented in the context of some timezone + based on the arguments used to create the object. A DateTime + object's methods return values based on the timezone context. + + Note that in all cases the local machine timezone is used for + representation if no timezone is specified. + + DateTimes may be created with zero to seven arguments. + + - If the function is called with no arguments or with None, + then the current date/time is returned, represented in the + timezone of the local machine. + + - If the function is invoked with a single string argument + which is a recognized timezone name, an object representing + the current time is returned, represented in the specified + timezone. + + - If the function is invoked with a single string argument + representing a valid date/time, an object representing + that date/time will be returned. + + As a general rule, any date-time representation that is + recognized and unambiguous to a resident of North America + is acceptable. The reason for this qualification is that + in North America, a date like: 2/1/1994 is interpreted + as February 1, 1994, while in some parts of the world, + it is interpreted as January 2, 1994. + + A date/time string consists of two components, a date + component and an optional time component, separated by one + or more spaces. If the time component is omitted, 12:00am is + assumed. Any recognized timezone name specified as the final + element of the date/time string will be used for computing + the date/time value. If you create a DateTime with the + string 'Mar 9, 1997 1:45pm US/Pacific', the value will + essentially be the same as if you had captured time.time() + at the specified date and time on a machine in that timezone: + +

7X1(37~5dvP@8uGdJJH%*o+M=c(0}6 zJ(@k*q{zx4;PG^h&Q+AhC+6M(9ppFFZp*gQws)?Q?|!Op`#KXVF5?_&gwqhIA$NrC z)FY=%H9VYf@F#U59ZSGzJ~(VZr)b@$=N=r-7Aw54aWTi25d zBZxEb%ie=#>v>KGzSg5RDW`W1ajO>2f7H(Js6Xi-Z*2=tm!00ViX14vHMr%w8!kZB1!(T&K*@7m+B9YJoraPD*g>&*p4nh?10C$0 z`Re?07wj~9JkdlH|u zflgzkty4)I@lkDH926I=Gf>UdTYwY%ww~BWjo*#DH#Uy|96!$CTD~1ceY5WL+HR|4 zyZtTg8~NhJFIU<4<*LH7$0yg|AN0Rh?p>Wn-ArYCoj_&nc^SUxCKfscmS1k}6i;{f z47lpgf%kgyYk%|1b@%0|xCPz8#Q9l@9$R{#cc#(3Oy>{1In_F6PbCjpY2Bw+|F*Vi z!0b0N;i|U(2<_GGj@4ef+szYSNS=m1y*hV&;n$8z-qH_!vVezEx}i-Tea1#sAMH9S zxl#UBOUCzZx!8MHb%w5HPOj4XPp5Quz zuVs~dEOidQ9)G`z9=VPUx}SUpN$^>LuOxl~Rjt@kn_25}u0<~)?g1XJFFwp$*SNor z99`u0htATgng%$HuR>ERPm+=+rcKrr$&|1*%UO$F`_$MCs;sV2-(zQJ9h{tcRAScA ztdVMG(G&QJ`0iXP0`dO3Hu zWZ`o=Prm56?pX9?or?;$&GbR*f_#m27u?yo`%be43po}{k@5q!P=O8bJ(c%;A&($%Na zziHdPzy|wlCnG5?~;jKeguOja&c!uFq4b2~-9nFQXIc4N3cW-HK$(L98 z~ z0B`Z-6!Xk;PvvRg^sZwqh0!6&KLRTg{(@O#@eS*rzQ1U4pXa!T+4dTscP4miDF3uA z?@~_VlyC9N?TcT1A@^oH+z)<&_Ym;z1ycU|3>Cp`9(fGd-w4m_Y?R!`0Wqqg3L9O&vXScT)ApI zIkl*>E)X-|+kO0dRDIize#g<>#ZNigz1WaiJ8x@y<}LX1iooB5yf$BD`>sy_MoMTc?!YK5&^ z(St*d`yAyt^C31e+z-X~L5|}?6;}V3)Gz3#e!pXh4NPOHxqg=A^Vuu?xXEyQGQnE| zoM=YA9g^I@_xH&I{dag(Ig@vuGZ6dBAaeXhlI_F^YCYY$%t?Ou5PwHR>gtvei#gAE z<-;SKx);%(=M|j7x~yEkik*$R%g)=ox&S-bnjyE;y}$od?rY6)|HN4P`m~?N7~1ya zH}>Bxfu{;rkb?zyTljmQzu#=ax8JyHv+-hj%^}(yJ zeSz@x+wt4D3%K1cI?%P(uGK?V*8i;ooG#Os@-L_KWh8y64(ZDh`tm+`YW#MB{khK2 z*~#;LHv8;6PD+#849I~M7-#9QI5Tj8zQj}5J85wljCSB@y|X@l%sv6Q+a=_rAaM) zBCZ!YEl;77$7{LJCFZ`h&C6|I>ugt@a_CTLWoae9s|{T=w!J!*KiAdwdC(wOzQ)jo zdru5)!s`Wj-_MH}h99^b@}T`~8^mPWxoCRpF)pJ?jv|M|T-_V#ArIOz5jmWCDlj`Q2- zTc-td;kAR4*ZeBF;#X#E!^V+D$2sJjNx<)9Uhf*px17(|uOVw*x|H*rP4T)NihcL{ zcF`GK!{{5l(x6<#an`KM`Q3y)PWy+v)=1qq`JI|`E8m?+`|0+oIOjjC+Y_2;+mGc< zupg?UKeDCP89I?0k(k{A-Y>WBm-AlsNRz*3Xixu*Y*4POV%n;;G^wSmzxUV#UP0P6 z(SDG24zPSWM4et4mMNcGvu#7;km$8B8s2W=cd#udt*s^eKGW(NkAYVZkI28hIsXgZ z-)Z#KeD`7ge`9y|#M(f=;%RLNhaeo`(8@UaIm=#o92sJBmc7gWN7BC5B+<8!oYr2< zOHRiU{%6g4^-anI+bbmZ^5X^{Y#eDgm-0UUimG~WM5(4+q@SwMjl7q`#zFB)|=;|T)yYn?Q~y*?7*h4>^G%5 zn{Vdch%EQ+kbbiklgGl#F*d8G-@UN=wUbTDeg)YU$Yn9IvwQJ?I_0vs?(wu-7UQvD z4I#$w*G}0<4Ngfghs8<5WMdlWl5=W%Ir4H$4)JYI8o5~&UFqd-(7DBbGk-&bx%4Ju zVfTxM2MjGZZ<|V68&2l*wqNQcq?U%49}4trLffJQrs^O7wlaTvbc zM|v?g(5^@P-{fhqIXf=J+LPBh&aTEy5oMUf1~T`F4i!+iymn@hdoy_@dKO$11LO zGgIG{^RCbMeL3F60ZW6Gqu%&!@y73z!1%qJ>>aZhL?{fPEs;M`4z|~vI^g0oz*s`<-4fW+zOmgs*NBlU)NYm8?XHwn8$>l-`Def z0da=qw2`2kov+EL!@V3fr=jdImEdQ;nfYDHT2n*aOfjAJ3obF826y0E+`dB^!>`Y_%E$Rg6Uk-0I5X%kxFC?3xb-Vq)o&STh>*e>nj&kH_urIO~y$Ao6rTOk$KNXv}+IVBe zf80j=sZ47(pksT55awqwlyvfm}kuW2~VFV+Ky1Xd;kvT0)D*r68;yQ;TF!F7S0_O&T^g) z5nt2u(|N8+hMGh9l!*FL}8!IIFFSJ~l-*`TFAT4=`u7*yLM` zO&-~%+!%iXh8a71&Y^ko@uS8j-)G#l=Y9%2S5c=tZH%=l7hB=R+ZQw)BJND)5v(&|lt;C9iguC5``Kt~&?#4X@&(iY|gZ+LxU@ z^6?_RcOS_f`~T5)?(tC;SL1&+7ubNPm@7B40ny-{3JIv_Cdj?sFnFuhfVB-)U$uft z(YgV(@!D(^@mhkdHhEfXRPge?wI*2G*uJ*0DqdP^g0%*b7Aj!Y3;BJ|JTtq`v->;? zec#{v2cIR+IdkUBnKNh3oS8X;e8xz7j^KVZZ!C(RH46RNYhCEl7G2j&sq0m*lQIl3-1YlHX%={~>l_wK<*m_nOH&rcM&jPu>|Y!1tw=eWE!p;N-1=l9V`S!1_~ z@5G+xmQZTXlecx)OOy4A+4FSrpE!G-a(>6z^E?0^#b+np2(I(p+21U&KZ3rj(Y4)E z>sT|NvhIRgYpMU>}`Bs zLmtZrYhuaUH2FsFyd^oN>Kc=Et2xn+$3H`7JvLb7+W}wWBgEQF2{cDkhvws-*1#! zlV0GgO($!sgiYVmZ!*uSb(6C$++M+&V8vmaUlCstz5CO8e$jQ38WaWT;X}d;I4x=8 zp@({m-HXaP^&FjlA?*yF)0c(zZP0n_tbx^+QkUqPDO*FV?O&{y)ALnyZWyTh8D}@s zzb|}opstKD)F5}4@s}**&6-!;&wPb;2etVX@PtHQhyY)r#bxL^y?_rIc4le{QbH$ysN9LLw z#apRuX&(37m6~%z_Vrgf`2!k|z4TQy$J!ugnS{pmn#K;w$hiEc`YpD%rO}9S4|X;& zH$@}BCXJxq8noUupm(8@>33vU$oE~$dtak2Y}p3YH_3hJ68jqg{jvyM{1*KpvOGrj z%Tc;tj#qZF$o>L5=GOJjK8XjF*t_|@s*k)r_`!9I>n8YWP~*PH{wJ_CtPf+vn1gKj z-@%c0GA7A*=In0hiJ6`=x0M$227Yp-#aUdLcUAt9>^Wv$h33*mt4eq(TH(zh!y2!9 z3we&-;aBai!rL5mwh~{Ly*od>{RZ>&P3*ztVDo>4e1pd5Q__~NkV`|`G9!m|S`OA` z@=*vp=E$jlc1f&LWYn_Ks{1oME#`b>+fC%ZAjdRzWJk*_tW~gQVvh~I`=M7=YE?`A zj)m{xlb~Y}bf%pCjY3=Ol)MFqawqDK_qWweBBSH2#D7s|nDR2OtmIph)+?#6gWNhL zoC{HX`%Ucbw@yji>dMFS5pr~7=bTGzB&Om%m%5PLQ>xEclgPPL^?&u|rqh2i7rE;* z^UXr|*mSlz3t4Qp(5|5M!P($0SU;enbPB&gbX(dMqm4$dD=M%}@PSRp@TCTc{8*Lr@H&vk8Vvw>`t*Q zHdK7~>)SH@i|DoiKBuu5F*7@64y`TDMOxzc-`bl7lCmwrWFao$hJFb3U~H?nB$O;qUc( zRzaIDLwo%6 zS75hf8yB4a6CAmhC~~_CI&#O~*ca6=&nM$No_;yYhwqpV-=<#%quUv@hdcRI)Ai{@ zAKHtv(B^!vvxd|5RmCu@y!as6?$&?x{ftojY-q{Yf8ll~pGCS%g=e{kUBsH#$U^m@ z&b^S%?}0x2PV?b+1+sqBtT#2UtT(q;a1MAP_^sOBw&J(;es7>|C+#YB@u2!+K{B4@ z>5qRhuH9{wxZCIe9^|gw@TgwjzHr&tmm-*gg)^XUfp7_9q zyHmQ>o!lcP79ex=7sz{;qd(meCsZ;^=})tJPJGefH+9D!ez!lSY=(!fqd&#=_KO^Q z`fR({?IQaO`tEA(m}beIsQeZ7mZg7- zkZXc|D{=a*Th1^ehj!N)W)EMDK72jy!RskjZ!PuyM?k#-YXFu}=Q{tk9^+Hz1wM5yg6^4q zbOYKl!iVlmAG#aqpU06=fPN?$zL6=zZr7aZ>ATMvyNqYg_^9-$cQf@$ZXLgR1y=fR zwDqq(bq@8ZGY1)pzc7?BvM#etQR z#%2>^!4HS=*e++sFF}6tK9tZ~Au$hZSnDsueiYi#+Z;P`62D5$`s}}o|8a-y75MU_ zEwtv*W^I?%-8E(BI{n*xt52Js4rueYX|v2tX*#cT+qX72CaAiB=@{L@U% zRk(Z#=l(A5+)}^bl0$fXh!~yRfv!K+s=EhzYjQ&BT|%*uLZgxOh^(>Y|1UvrX@OO} zgxJCQuXxwv(vCMKd1FL!$K1qm%zcSo;&DRDiMJHn5&9%OhSo#e$IW+ywp|nIuX;?k z>o)jz!z%`ywfRkafBLxoYT;!;8ZUA;+TkIUYqJ;md*W5qnX!$axW;1Ys-q5xZCE=7 zJh6>N-lLcMm~#H1rz#ouh=(nU_m=2)a?|ha{KT2i56Xu;7ntNjZlZ4+v`)?7o9I-8 z{Tr1p_;_#s2rSB(02RM<#Re_TG6cm?j)kVgd}0yP%mQ81?4Eo%MF-h0b_7B*5oX;}iUij6F6{eCG>;vl$$T z6Z{;SiG;t+Gq^db{$hKru74NvjE$`4GS=ANN~}dcB^K0&?n?V4W~uZXJvDk>&;R}G zs;Yx?i3ehHq)cx#l?QlN6?-pwyh`jkf<9hTO)lWyg?23DoUDwyd#b(ts`_QBPrq>P zEAx%;KZ#d9nh&&YW!aSd53ehsBEzW8(t0G(lW+1=N|mxhTj(W`THI>T==IwN>?tVT=Q<9Is9#ZzhOD}>Hc5qk9~Y4 z^!j?S)yz9rt#f>vf+okeId6u)Z*wnn{B%=|BXoUVeVh3{Jl+_h|@$1L__?C)4};NT0gJHi_?jq?Y9$0@kF0CwH#>cr!NWNn#P%;J-@2+x1$% zUH1JYzS)!V4cqlvpS%-}F4q#%aIf{doVK+m^ZBvX-}Q*nWe?p&@GNi2Yo0tXcvkm8 zmv9e5?q~|G#ANSC#c5J}XuV12<1rsTUi0BY+V@kx_MPhJV>;btAG*)`(A@~n@x8Q< zHH&)FR&W;t$X{STC+GAmbWe|&RNDi1{FV=o_xSL*8QKl|$fMwv2Jk4bmGCIzeG)n< z_W9^jh$p$`w~CjYeY6sI+uh~ljXV+@neSS<$gBBp^zAV|?YqFIeKLm~OZ$>G&g`QE z$ZdoV-I)P&KM#m{*!&X2fGlxPQM5H_$U7NU{&3bd{5oWsoUIx2fLZ?er5hA_h6OmV_}c% z->XU8gZ0RsHI}&tYh)tl3IE-DuwDQ9-`|5>iwxYh-rR$IP|3#s9;{n8j`YzDrO)~v z?8m@Uy7BMbgC!=@EO$j)`IURHv9(SNqJwjp#=lU!XSoM^qn44ojWN#O{k!*I@%h@r z`W~#(eeS_N-jccpdwQB26ZzJd4vCcmrX!4RKm%XBMl-gj60bqq<~e-+*$d7k^P&F22A_yD~_IV0@cb8Vi> zneUV3UaXpj!uDk!iN96Ly<#U92D~?$d#-Xmk-yt5_9FjsPG&olePR73=Zqdowj)Jr zfIKMfoFu9p}_^eCd&&h2Xvd`ykZ+Y0dO8U;o9$r;05M@6fjwU!;l;u79 znl^*K*EU+il5PCQ$^W}HE)Q(u;CL-LYEE#q@n_rqKejP9=hZK+$RWRDE_cxLxQm|8 zo%BKEn;G2p<%^-XlG&s9eVljiJHSe)JhVDj(me8oN?wjK{9nn7#9ixV&et|CpMFSO z@*?FgzOKLZkZ7BnXKuBu#B6nMJG`}*avMgozvkEq6(4T3lyA91@ErS)Z$F5g`tH@U z+Llab{>pWH&)Mi#lm35`{9n@$dvh({>p6q)*&5CT@8`rXM{WQZY)IpS$$mUC{2}?>=I;=uY#50w;zW;yxGhX%3@P1Kj`H zS-NIqpDxo!8GPQlC3)6lx#J~1p3GlvnvKlQa^`a(-_vPFfkpAjtpjBpQfhy4_MX*s zw9QSwLX|JI&!qgMkTrR#&h1o2J5L@Q-fDBt=J%fr$T*lUciGnrv978oo*of8+>cjn zp>HS9w<_l%urHU-qW@>22Q$!zQ_zd)O zEIKAO|F7tBlsY7*(ip~mP?;6r-VCnD=ED{8TVj8}uauQ@cG=2ZtLyj!ctx~-FJqNF zP5URuYA$0{)~3cDNgl)2oG>}=L-vUSS;v;@Yb7`CGL>7_RgqBB17SyZ)t-&41C9Mq z{l~efo9Mg1wj9m*KiWbcsWqf2>z=y?riWiudZx!=>&k=sgK8JnArSj=+SIsC-p4EMhDe14!rRC=v2WIzS>rPz5i0i%3Rto z7k#@3+rN-Ch&6^hgwrM8Y--J>cuDQCZ?D*IT72ij_#C2pv?(U*a~EG@;j4`Le0h0z zm~WdO_i6K=sUw|sEwtsF?Vstx+32NTJ9-iWbyq`gALjP%i=zi5_3*lr(0OFpy7Hp_ zf_%mydbl_@Qf20J8NYLN?urUz*h7AbcQ&Q#XKGG1wkW%Prtp=1E)n|@CV!|^r2Zz? z#arZZR)~06vuI~M>#x|LT-Aoz?AN{n-TKFQYo2*E zyf!BuV(jGHdA7=#$ojMSoVMa^umq2+497!gp`#svX3WtJ?PPH z>gmbtuU0g9Yb<9M=aSR#WbXPHya;#>y`$qf%QETJBm2$5cTRtGgz@2)*B>5&pU(%X z#`1lC^y_#0UH`>E74xskW&Ioej(j;#wTQpv{N+ae?&0qh{H@B4X!znoQi}a=3!I1kM zl4G|6J(F+gF&($A$R1@XzTm{ncAxX2(sL=hn0^U@XXX3pEPOB2d<)M15#J~L8+?mQ z(WmX!b6%chkF|yT#Y)zlN2vE8cxR${1N$;J=E!-JyB{b(KjofdL5LU{exu)Bs?0|Q zziEHYp3*<*ec~re;mg!_GI{P=a~eJMS=_7ftM3bRdX3`mo(CGJ&(Upf-}==jF+!zt zzw*jK*)pSZjgj~S^ta*AP+OPa{U7z;?`cDj-nng)>bK5Jewmw`erx=S8Y801jALbU zL)b0%7%*%4$31nX=5)#bwELV8z9ny)EYD?aVZ}uzZoj5)Fni^qLvK6wF7)n<#80pZ zQEZ~k{dgfFT0rWU8M45$KW+RrrS%q z_QMu&&z!Y_gDdyR^Pq9I55CjxBKt~U#pJSUg&*-J`*JI*>H~E75^$Glo$6yvobHFO z#r8^ms-36T;)ml;=7v(f_siNIhKGqgY_EupjMw5vKUL@0#E*^N?1QI#^qcY(zMOB_ zsmn+X>FMy~)(JI-|7IWN@Qz|NhkyJa^WSfnpOJx?!>70Prbas5YzRoflm4yUIu@kq|M<*=Y|7Qw4ZSJEq@}jeAwV@&^Q}1aR%U5(ZPm^ z?^6C;CeChy^E~;!1?PD$4z{kY4IQpzJau9BEcE8&&b)-SaXZAu^^%WHe7X0bCAq%c z<4F7xk%N0~dmB7Mvx!`WLemYGaoG({dbxqzJl6I@Si=ovEw>-KGz^{EpYeA9<1bg% z_Nm-syfGs_NrTHrd5*u+eU!tcpF278;_^|R&@u@(9vX+w?g^cT#`}Ics0~?mhkHjm z-+JZSVCP%Kh2gh{sH4*H!*#3olOF7dpLAhJT#$B-N_#ZuI#y8#(q$Q{P4nq^{CTF z;!oWIuc}Pr#CT}oQNI{I<&+nRHv@ zIr9aNp)*fOT!rjfhB)swi9e>+ox={S5?|&OVD(Qp=j-bE+v4w@c56MfIj_lmi3fno z-v`Ou=lCd(fOjo;$~L-uTXeUsRsY>8aR_v331>aI*jXfHX9#aDxH%JfGT$ZNL=!e_ zj@-W^&M}wYxx_a_57rV_Uz0Or>nFrHnsoUl=u3S4tRdE<8;LKpV7q2h#_UrlTd@6z z_)YLHeSf8(Bbu1R+BISePe*T0Lw`?2kH3mO&m$%= z7rU6J?4lpt70~?%yXFVW0rq|XY%H+91i)&6y%7Mzwszmt5ROZ|lK=c++Vp#HSyOd8 zF`OcM#r!?1&!W%VvUB3=MRpJUSV%rhrJJ2&OcPn1(-LWAO= zJJ0p#=Fcb-Ytv=6rF8QpQ>JEcJha$b=0}w2Xw_vBsWQ)+GMy9Sg$tr>B^TDTH8?sD zZ$JmMKB-tk3(e^^_SF^TO9dZ6$xnY1o{Z>f22YGzk&a|@HFe><>ye(2~{j^ykpWNxcxz0O?y47Nb} zUv#`x=G1~bXMU@Q#EaL?N)*KBsQCI8-rSYB;8bWu8Xb8VTQBR;9KNUft7e>Z16y^Y z)4oFdAGa~$a5+MNS+j{tkc2i8e$-KT*423XIs{_6kYw`G~r-e>v0g|4V}N*}G7p?I!E2WoGU zd1&O;9(=5q;Jb&I1MTV#<+EO3&N4XSw+mhec>e`nhl960G_gjVzm~P5{6OgNW|_!6ytW{olOJu9c~$C`dSlGd z_fRiBaMgL#yAu4KA^p`4g1>xaZhR5;WZ`SkB)?Lo1s(i8Wm*cf9zU#oi<;?)^ZDL$ zwX^5(MY&o>b(b!vNj%PX$!pz3-R^Z#msuyhFY6p~{h+7sv(J!PCzYu@P_lNaLbqgp zMBDWpV%L-FBvn3z`!{IFm`cZY^t8l26xcKWA!n;4SC^c@l05Up_6F7>8RrP_CA1#z zkU1vC-%T#RgSCdo&#};F>9_aD2U^4bpQRs;Lar^l{rfYAzPbV&;l+Y4cU_(2&6BbB z8S-=2Df#rI4|nptRrAscZ}Jw8=-of~Zg{Y+<{Sk2`TAc|_QdF%tU*74H?avV4mu#Og+FjnF=cMQs63=ClYoPd*uCC8kn`8Xu-lbIYoaMu&vvUskhT{+jkNEoaXx zY~cfH8{nod`$t0mkCdsWjMNc!m65s*POnS9OO;$_zqt2x_G5;ItM8Kfqsn{N+1LBv z8#{Nez{r*3?ki%Zb<)00`m_Ek+Ji zDO))u=RjGbs5RIyZM#E}c+sQS?ssbwLzqXyZ_G*XMo8Nh=Kp$Z_+O~E=PbvLIX2v} zIdR>WZrw5bTm(OL@WUL@UC8=Ww^8|5rvE}Wdu@0F|MWQ>Wu_ou&I?d6CI?)aEQ`_V2(7R6k#@32HM;L1h;UVJ0p1VUK zmpzV&&2wyRJ^Fl(@Tz0Vp*Lpu+HF}wp9)?}7Q1bMa|$>X?fwYeKMp=4#Fle7ufRJu zMaS@W4}Xv4@2mLx2>x!tX4mrf<@|jZf5%2;x6emHU+lBI5jP5aYh-`5pIx?iKea-5 z8Ift1cM2b~wOuYv+2z^bXSK^e-n(7yhDN%bO^z#7-fNd1^T9WExdYfU(=+Yz>G&?` zcG==yo_qX7`Mb$AwqyM5*6$Af7MpD0s}dV+@A#AQN4i6|&P@DV`r!m;ob@nvB8;73 z@Dk+1-wUir?yE6Iw4c>%MPyHncQbf1Ms(ZFi?JI`lsjt*c7uH<8OzqqFHVzjrvCr@ zifIq=|A)qni8pPnO{_XB+SbSWK2do22>v4QC;Yg5u{C^GW5U&LQ`hCxwQ8!;h4w;X zNLp6zaoin>d&eVio>F)5W!k zTR*8yn6^9veQRQ7TQ1AemgA{+=`p%3#JYUja=*7NG0qWO2+df2f7NB&)B5VY*p&|l zsy6d3_Fd}UR;hgmbTutCw}<}W%(n;g-Q9nkI)7Ff-&Le9U6_&T7k6?%kF>42?irrpkM5+0{Py#+Ka) z?An7fZP{q%^mJPmz>6M3!-yTe(PU5C9&|fnThWrBdgSF z$NtQ>be(f}EVRD?kN5D#jK_}kj8b;&h%bVTd>LUcqim1I8Y}1~n#S;!qeKiEd>QFBnaeCJ-HUpdyB2d$voMtCZqfBkTTr;XIRk^24MyUCL%GC3ES z$eQeI^;>K|lZ97#@5hhUX5zMA4`|2OoY?$x0${bk&Io|505&H8R+}4}UmE~hl*f6` z0N4s-DtF}k+8}*@R2G<=!SE|5dLcQqePPJ{AuZ=U*Ew>&2pP)TVV`{~hj@H0arr#r z^Sqh3oO7cqLuy}FjS0qen6;6d8x=bjUU+z1`G3DVB~eBUS=MUjV8=c^ROZvttuhD7 zdh{s9fsDBr_OXAcmAHYwm5tKtUGjuiSHQ2}M()9`VGjl0y>^vySEQ9QZz?C(uG9Cv zc9nTH-99FLY*pU7c74SM-?8~c_J;zKy&{(%(}QntE;1sQn4#hFm6I}5<-Ibz-Ur{v@LphV?ypYC2hU|0qF8f(NvP{ZemG{bC=DT!#H?pq=R?PmOTjnuzvO)K&#OONs zTl7oL7qge=ncFMqAFmYgGW&Nzt93J-3Y&N*q`IOh8nY|ljjeb5ll2b<}G zZ_@`dSG;nqK1c1tUxat4L)0PXIMd%NO}pRFd~tng@*L;7W7#uvohMf9#t)M{(-8V~ z7IL`yN1U;?3b*#Kclrcx`O3M)&g2~h?>$RpJN5ZuD|C0-`C>0F`qnP{i{GB7&TO{l za_%Et2RAY=96|dnb#B00exKSJD@(R@{c+CSTKC!MCeEyid`{R*9h`ZPHMpF=ll5~c zIviuX(x!GatJXK9@e1`!}7; zW2&9B_hgH_E%dpZ_n6bS$8#UYw8M4&wpseJpM1Lb+?nmVo*bO}#pXZjY8UNLd*E5$ znaeGBRj=LJ!+K6`T{*H}Wb=m~I`P1I*1b}v^{R@^w1<|>NX%e7)gS823%l7`@`KmR4xK)6N}Q%#AWf(x&z>=MKYRD{&ru zByYG?>b=@ZY^=3k!1+Jwy`Qre%*E|id`4pDn>lUr?qn@8Gj~Uh1E+=hwcnx68~1P) z!fhWVt|Mm}queo3`J7lYsyj5yL9*8pp}eeno!sB0_P+*M_gG_-afjwGdxT}|4~`Uk z>YhoR(w8mZe0EW&t^XV+PIWA~5M&MBr{&a#Eq3Hos^+G1S-<}${TqFX{e}CY3E7vF z`lasrkdk4$oQ3VM5Lq>Xi}hgut$ zAB%kTxA~xW?MU9^Mt{W?UwV!F7TXQ{mcWmkRg~P%YV4q=<_t&=G85ff%|EwnYt%Wa zVmr=vk+HRFV1v|Kj1A;$5oeDMl6w!`6DkVT9e}aifl&7z3Z3_d)=^H`C3EkA@9)I% zh2+eJi6O!B3V4=1sz+&8laC%=1syGyxX8t?4IS)7{E@k<&!>MDQofY7YZ^O*hSRnZ z`+Q(-8HZGx%j`P7zln~E9OZscH+-kZHcbD|0r#4r#EOtn7@xX4#QO`pVOUxmO_UN7 zK*yU)E;+?>R>QBI)zI1fp4Em8Pvx(_(itlln&y5Gx!rU z{_Pt7R`pwImuD#_e2>!QZqVhH>vGG~Z?SzXzX$Gx#t=>8GEL)BUA95}me_m9JtDl9 z_>AA8EOJn1ufAFspMias9G=qO)2M5NE|aA9ZlPlj@{4@!K^t>nx;@y`oM{h)zU0^4 zM7~4OnJKzG{|*0H=iwI%UhN@ns_HQFFy}7Cu76BDGGDdar{}Y@^Vs;8>&3n!pY|}Z zKAF#cw$t$=7qb86wh_*_FSF;-9$#I!vM9cpdrgli{)_A|{NuAb_SZRs*Y1wV^*-YG z?P{F9n0=f|eQqCO5_Tzaw-Y<=D5<3K~;=7a`RC9elcVN@sY@9;*`XB6lu9v=C zCOX4>ulAxu9*LR6%W3;zoSPUIifg zM&fW@kA9Cmm^(yyPTW}Z?HbO%291SUaNj3?`DpMbUnuu| zO6?oIbOGKu#wS2j3)=#B>FQ%82A?61S?MZELeQD@ct=iyeh!IxYi zQpUk6wd=qeLH%!Y#-P&W&n_6Kx%<16llk(Wv_bgq;C-c@Tkcj?Jbfc5EJ0W6ZwaUrpM$eg6-Lf%OwZZ@3I}Uyl_bjXKQ_dRv zl6U{UsKc&l{b-`E-Ti2Et`i=6(B0nL(e|Hmt$SjeuMzouO1nP8_wQql`-Hg7PR7M< z*0D|SCF_!6)+J@|YsO>j9O99b>%ThGw(AOKT{46`9LjEKT^AmldPmzorrv&Nt~%FR z&pD}#dwQa$dTpZa=`|74P2JNQjXsZ1=lEnD(-Z2i-VKlLevF}$?mpQ`J48=Ep-uhh z4C8&nGwh{m`RowhgoccV(P=u-iO!%$MLo!9DST(Z)%mXx_J06NuhTg*#{GX_rtTAu zlQAi8Ez*v=^t#$dM(0!Jjfwr$iBi_B&bT2zi4$9rJg?`3t?JEtYVKZb^*>#SZ3>5S zZqNC$^)}H-S>uTv6ZyO4;>dr5JssMg4z;RRp`S8$hy@AAHuvc{LTp>b>oR6a?J?l~2w#eISiAM}B4RM3 z?5D^lEo-FXnSb2$*KQi9liZZ1y_+e&;RHwL+->gcAE7PZA9vu zva=O$4AecQ=#I390{hzMH~#P!{JrJXf%P9L{V`)=h|M^Dq5|6$#>V&MhUXRB5WV|I zbY%f$UedgMb`1GdW$s|Cf0cLf#CAzrKj-`8odX+2@%IqgcQWuJ7u@>J&@-+0o!Eyw z=w7z$vS;sDHstn;mVI^WN4fjiALkCUBjmAm$IgfkJlUtlsPHBF9kwr_?s;E+@3q_6 zqZGPx9=+`yxo10P&%o0KR^Oj461#$47g+s&N-rzUvwE+8%8Kov~GYW$i3_62y0PyUG@CkpvyH-PS&dK zx_kIr_n+#k2=Cg7O)6YFgZX5X{cChf>UQgiv30k=SKUnI>v8vqxDIFbB-UP!UJX7z zc;Edx$~`qhmD_INn@L+kXUY z-!gl+`Yp5%P`@SiF!ft%4^_XT>=5r0Y*suu^&5YAlu!RTGAyZ?mlv0h4#_F zYT&yfCUZM`;UXV$fyw{JJO5XHv19uR?d7z`O{Wo?CN@Im@fu_xZ5YA--ThzlvDk?c zyO8e}P~Q4@V11BG#J9Ul%jBo(>`}3uPr29c8`uz7CK8)}5oKh)5MG`or?~L@Dg3+j zwD%+7qs-pHcXu1ss_%vNR=&IWUZ}p4hZo8+xm)h^~{WNS;3|lPc*(OO}YrH1L zfg|H0`wj4dc;85SkA?R;;5i6qGkS8EmdUMGIePMa^;>A)tbR-EmGaA+)2RL~wO>7Y z&*~-cCh{C6b0#{d<81BWZAG%KZl5rw*sQCa{31^|akkgsSLw2ev+>=cZOXnoaW+SP zp(U^v}l{Z(n(M(uarl?#Sd}1$9WQ?>+KNOP|-M_LtcwtKULP*sx)`e=2nS<+}bcy8cn>x73#R z1%qf37iqs~O0lvF3F`k0o9^kick$q)-$s=9_S+>sGW(&A%*5`9%z8C_Kigz@Spn`Q zc==a){~2Cp9OTPOtq(6(`0yh1g_kR+<5Tqatt>L%2<|1|Nk9MgO8G6bUsAt?_KWJb z#O{<|=)9o*9$_D#`g^qf6lV&9-a7SLWdBTlq1&eZF0~U! zN&Tbk2eQae=uXviA5`T=+V`v9GJCc9EwWe1FLdu#f0x?tE4riXAE>`a*f(e4JBM*q z0sXz|DSK~%D|g5**7Cbn(J!-?s^3EUYV})Uf0OnIZjh|e!1ZJ`5LQl51waaoZYMC z(0_%bJ!Hm-;QWx2xY#_CM6`2>T>-@^73|D&coL^8kC8S@+x7i|xL+ zV`OqKw(v;q!sdAMcQvpVD|^t7y$dg_>D_zK*I*~=*@GzT-naeb2)0=Em+zfU4syS_ z=-0#Jiw=m*Kb!W;+BbdAx(EISR!UyIJnkyzb4F?qXQT#mMk>tyc0t>h({tiV-Z}={ z$KGmXSaRISo@L0E_1c73bn462lxor2*WkZA&zji7+Ew0UY0d3_#v+zfW5wn_{gpkd zf$fM81D1H2eEU!2D(!zd&#L}}f3x|<-RvD#Z)|!%&IPHuC$Mf0asM-@k4GOAUsTL{ zVYIPN&-WR29h?>56oK=e7suT3Zms}F&iV}nXOr^3O6*@DpQ}F~On((Bet&+9++m5_5nZQ zRLQ!b0zM8#rozh&w-M`RUsm`DTdCNS@MYS29qqgBvm1XXJpDF}r&~WSuXcQKr_OQo zo8%pt;#05V3y!eo13R0yh1`Cr10((qtV^%!TPK-yeTm&fy)Bdbt0iw^1H8!jJlSWm z*x!=2&Za+FhC6XPY1j2imLu%Qr2gvi(VTncJha=djS!DxoT&aXeI%xBCjD2!zIs~!-Tj%Ps|EC3f*76fdu}?vpV4=U zM~5HNcP|?}7f(+AjI`eeR>i)2rAwbozy1Z7>AS9R(syNQteho0z~8gHzjgn=23Mav zE_cT(oMEm|Z7j1tJYvu4Wdnn&B){-e6Rhff{&lU0PHk1Tq{QxkuGo?oZ`XHWOJ7U>%kY>Qwe?u+jI3nR`rd%|FxC7JrWm`HT`kKdfj?aPi*r! zzBMq0!*|X|^qu9z1drnEveXk{%&Puy*3;dxo^GWNegs#sz^$6M%#P1^NyM_9k zx8n-!Bk-%GkEH%8>R+;La20yPJ3OZ(cI$ibYbHB5ZXI*_rNlmvy6$1@sxmJ-ah*OL z*NIb3>9vbT*=x8u$6DXV+mI8GvwOc&@=^*PUoM}+oIRVldlqx}Oy=?#_JdFYfGJXm4o0pz)w+fFR>rHe9vmh2b2wWs>Xc~T;Xx+;ZAOQzjjDo z%2(hokRE+7UibOi(2+iWQ~i#x-*tRoUtPnO?Y>FY0F)PBb`dnblLcRNbEvN81zpce zS?~>gDJS&jQdaOK$8bw_8LSckEuFJ?DpmL&zf79h!s6)!%OZn?I ziOnyw@8LVW9oS>!Vooq2|`E5MmSJp=g9*>Z~GKeu13?iS^+UlO*@pWvL~^yD24rOq~fZQ%^qBgp)GS6g(^)B`Y-Ht2)mtw{U+Do^1QY$bDeuB z_lcj%oxKKpl2F@>#2roSeR}T271{UmP5ckPIqe$yVQEQ!^$Xk`tH%$%7COE6k}nRs zu#9pY+#is6ELq388HuaqJLm3%rpy@<=a2DC))MYIIygVss_jZEc7-#nb!U@9MDD3c zjxAHqMU-tB=FnS4{S{BmNSx2NbRWm~EOX#_5@!XIJZ+efI1T*BL0+D|=ED>BLOeVX z%dgu+{t@9x`S-f*$5Xarh_mh%eyTJ-4Z1xI$@q1lJsy6RaOXkw!E>@_Q)C|we)=5k z@Lyz)0RNN0;On(a*RY8A2HQi=OW8uzU($AWT`lE*!*(kCl%TM1lLVN^4tiG zEquS193(+B#zI5xW=UKA3a;>7gMTvq`|NGtqXdBqXh~|syBT3tH*J0Qm3!j_yqm?CxJ3h6#zl_h#9qob*@y3P`5eaYosYhhG9CxSMi7f={H=_MV*6~$2o1MB8hbEK@)PwG1>ci|2@v+=TypbIJg~(R;`f_>d&8Gf~Y8kgR_~E}v=2spLU+#8x>RdcS z`7U|>vek15^++ARy;OdSZD~gkel2{R2fmJv`|_UDWpKrJeNfZ?1@!+r3oo0|{aSE; zy)Swnt4Qj7_o3*0S}e57k~ubHpUF6oJfVyu<#(ZEeG6qz?>R4v$%F+E6=Z+%GHxdJ@Vw`Ov*K@g5vX${!S4f;Q%=xV2 zI5Tn>vhLyx4)ajA#kt)z=3y2qQ#ad~t3g`ASDQO*c#f#1H2pK}=Oq>d4jqH zzKpj0EU0Y(^&jU`f4xurB0G8OLB>a==A&pIi#xRJAk zYZ;f0opthc=R;TZJ7?W!5*>B5A>q^<@DzvxJ2Lmt49#TH@-5~tc!Pwt0{ww=O z%ZG5!K8JhuAd?U`zO!1-(C2bCADh-4VqJ17u#Tg>zQ*}{ z6JNt^dm`A$E|>37&)?6G>r43@hgx-}uBlSj5e_}pMcutm&PYt+TaZ674tc*ZLCypg z+joC4pmMXg>y6<9Z_2SIm#Tdu?*D-A=A&1gu`RKO^Zgm#nef%ou2Jzvc>i_@<5}t% z1nxBvYf{(2)Zb0dapE5o+jEHRr1!P)5r0XUb1I0B;^)bk#aHO_EsUGV>>1ieN88L?dnvJ^+r~z! z$~mjJj`_1HKbrWRhX0OnBk&>YU&xvHZM0(wXX3-oen&h^e3o&i`lW^Xq^)vJ^TU%pzR`v)F3Ml{fUdq3v%OBt1 z_>5Ed6@Q@bFcnMo+<9*~fb*NQ&5zF)s7KZZeR^#5AumV%rS=7sd21v#3Ogs~a+^je zeQ6JqcW?wb2jxEKC~^*p-R%^8U~f(O^7D&%%k68SwgmS=>*2{J_MJ!@&z!0DjOP~q z)_tPxarW@{RQw?4y~ko(#^rMK+bfxcci^xB4dkK zp7bsGKqB#0d3z=KhKZazE+s}eLftpDxP#EDWz(9JO|e}J{o*vaNi3q$wT~w2|6S}G z#sX}89yC^A<7NCLZ)AUEff8%(f&_{j|6-pV`FL- zxY)u<^ml$1oJG`8nFVfq6B&mxhJ40acLltRg-(e>r&;sbt=Ihu4xMH>^Coz5mgo%l zI(l#T5+~63r+~lzKI50zQ@}qc3%=0pip z=)Vko!9POdPf)*Q_CG1-7ehAw(iUvx#q3jE+%eAM)15JnSU$NYw2#z0LHkIJ%$<^> zLHxRZVCS>tn_&H=-UycUT3FwgNk7wqpVMt=-=v#!()7818_|ho+9-A@orc#>b$mhm z!0y`0(c%a4HrmK|p2UJWPSkA-+us?3ZFRSgdy(P;R?t3a+ogX`e-AD7=8S*4TySaA zk)xHr^BEa0Spnvf#ea`N|cXiw62=@D0Z0A>0Zew!OFweN*&Yg@B`$fK2U*h<2(K+m4 zYo2~f9rfRE>cy9A4-wDZ$hROr?g{AZTIBd~6`y7LarN-`v}H}6sPBk83jU@UDId&Q zn5w&#dODybZB}x?xA}3Fx_=0*1q)ri%_WX+bI|9Rd>G&6X39KGE@ji++o2yL&LHiR zwtk<#(`9VRUPIaH1FZGmMJ_eJ7vHVaUatA;^O?sl1%CsvdgFWbEp+DbP_N_nedJRY zcS7q1@P%6VeUp4fB8TD+W+b|dFE*Y2W?n1B2heq@do1ogcKBuQl=@fKgv+MFm z)vk-2_{HxzCnjz7FHq~t zGW#%S?p~0JJ2ow{s#Kfs9eWqirjgO-%7~r%wWEx(<#P9pyKUDkvZ^iaIX=_qobifW z?X-_LOZ$ZJV)G<#MHzY43%16_axYQy84?KN-DgI7{oz7DsO` z03KA&E5M{Ztexwg8Ej2X>dj>C)u2n^Z8H)t)34R&&z8fZZIT;n3;xv{{LIA{N2>a? zeoW7zAM2^3m~&^Q|6ZBu=wv?rzr6W7L}GE4<-BPL&1Z=FweoiZ=URGl^X;Ed{#v<1 z0zYM}*$tg_$7|h&j_xm|+j4fWHKAM3hkxP+I5QQ$6|XqxKgfFzF$$k@#ayo1FcWvu&G)I(Nc<1g+Rvjz0O-eKz!rPBdwqDExAU zy1(>ikq`Gh)%fGC=oacReOtP~YFn)TmON;MJ`#G)A)FpWcH!EE4 znXFF@ea)j=#=|MMlN`-{@)`n+vrFyfY}Q!edz5oFE9Cs&b2jT7Way?-!<#aqA2P20 z2yc17W8{`qGPY9wQlI9l57}Df-t|E7_-=r>ePIeAF z=v+caftOyt_!zA&**iXlwP6u5k#jQblySoyAEVf|`Cg5E+;}5%1^4NtuKO8>kr%vq zh{O)oJL^L7TR86{w(>q=rQod+n{L*IPA;OLwc%aVm%cW%u!C+{M)`Xc>pJn*C2kke z^6ql!zt~Q9dph{Ll)W#pS8Ba@dWakm-u2=ypwq+Iz_6ni$@ga$!;`ERC1;G9qaID| z1%%k+-+S(xQu|zJxZ5B(XhrVx`Tj;itrvagtFgzC3q|!&i9HKkcbgj7w-dS6@co>G zil6z?$brTfXb{6_H}?@k#BC+kau@xYp1Y{=mz<~NUSSL!m3wR}z-iL5ZDM>l`dDO- zqu!u-cEwj>^S?J`&+6d;^EBl`c49MrvX3&~=flH1Xb}&V^Oo(Y z^OodT;=APf>2r_3T)MmPN#U`?{yn@j(+_@iM5rUZ-;B@rJmppsUo(EG5zxD}E z;%uhaKDSJaeG&cNG?qDGoXjmD)>XXs!na-HqP&HeIk)^6STXm38B^PJe4t&&2ihy} zwQ6bWjkGNYzKHq$+P%QHRXZ~JUKYF+(77ZFd=Y&nd7*;%kUo7)*K;@e8iY3%yq7iJ z5%k@;S!l8jcJ2eho5V&|WudEZiAjiWD)%FU>VE`z9+9Qajg%jk1#aruta>_hT>>G!aovUlyA8Bw|+ zGMBx&rCOeY;KM>@R^?EocR%Hf`4nvKHtt6@JUpwLakURQe?&yC2tc*MQ zI|L^{2TeaneX^hbQ(fOj#A{OZmD;!K`o{7-{A;JawFf%$v8it)FsbiQeuL^09f_(s zI8(n!bhp(0V-|eVC(?HxfIBox{~KJ<13722gnFLKLR;|0C|(Nf$FtzM=`P5k4??d% z%TMk(2FbwC%Taum+TYAVvlg74$X@K=&HF%eEcjLM(7q42LR)0IlKQ{RUSt7tf$W70 zUC{K-@8(BPA-q&Rdh0vKL07)bb$z=LyzmzTPlw6# zaB?WTbuD{kVe&jwimrc|`p*4-_5Et__aXk+eR0nrp7`Uj2dCnXoWJ?XJSHU4$1uAM!NAl+F(tnNzm!7u)pHD1SA7FWEE+z{}?`dIR$ z60d7E{Mph)gVr_Iq}D>= z>m*)>pRjvC#iIQ9y`M5~EJ?-d)<}Ex898a|gZwQr_A7fEWuGCALcFfo#9e-%`RjA} zb;gJJ9{5%4mv`y)Rl^b$cWDl(xC=Q7ed_9AZ&czf5%!$U8Dvdv)p5F`%2-1XXDLCC zx(n>9nHe$G1T)WvNm#_3~rFG zcnG-Hxa3?(ToRs|Ln9n{{3J^~#kxI4-cqiF_^6TlI`YAY+)I(W?qg*?TU|PC^f3oo zpAw%izHa5Uk*eL=*ImhZ_8|Uu!r$4`EPvk>Ij*S2r$mmE_9E{^;0<@lyAOQ!`&E2F zbo+1o9i-c@!9z9cSR?PZ!42ZK3*1e4DZNh0Tg9PE?Acl5{TwhAPh_5YCRgj<7_EQI zL3akodjr0R^5yjYJZnak!zKiu6~MMF&#sG)Ae-NT=htudz|&IfZwop1XY*Thq4N$6 z>+5ET0ZZ(+hw}!q{=A?1Bt91nTN^%u-XHf;?;^&)&!t{Hj<<1!JZKy@EY^BE+|k?J zS^Dc+MvlYD&sM1ASezQiM~(3x#~;CqpB#TdJ7f*#me1NP19fxpSESwN0q@~XoV49N zw-OK2`FRTMufs3rOeRT;Ynt=_^%BREzlFx#&}h=*rU~0sLmWinhLdQ^F#&wtN|^-# zuoXT$o3U69P4`%wePL=Wws5{XNVkVmZg(WhSfoE!z)!u3N6=mI zp#9$o;JYph-#etwT{dL)*(tuilZEg1DOWWrnD33~e;xdcqi%_f1=;LJXy0+NVp-Y^Ur8v<2)3%vq4y4>&nXTiT^9*djA0oho-(py|6G z0L}FMfEJM(U{hYQ|6AMrF@u8`GinWJk-=}!k$cdZ-Qx0|HbRu<0-O*}z z_?okSoeN%i{c`W5OWXD?Y`fe$c{A7AuoT&dOmCr#o8Lyx8%i8K#`gvNDi-NG-o|1( z-r){`jF+DhJCHJ0Q^sAFbMK_YzMSu}=W#RrR3C9<#u~Caea}P2zOn0O&!fw;=OOzO zavm-K84*r%s59#lq zJ&*6uFFojt*2CnU$C2<9(R&_Bryou2dG!8%pw7AbknLVisXYoB?lzb`k7B-WV$UPU zX4TSHC#pWe#)0c@le6bhV(0N)_B?`UNPjPNVnn|Bkb_+umjyl+xa8jqqQ3(A7iNJI z1M602SA_FLoihm5C4St$ta{s2HiH zt7E?S7e#XSq}k*LB<9<$V!qgLiTVB>9a8qn#C-YQe;xXhHh&B667%in-i?gIm*9yQ zY_}8hEw&HmyTp7spIX}YniGTVx@#ZgE$btZ_q;6qXmn$d){W>s z;I4qK%U;Mamz zull0IJ}L{Ik?UCS9|8a8`+zI7C7yg)7Jo}{&Vkk+M|k7S_CCa$wJlfoNuMQF{2p}v zxAEpO^fo=-+y&kAc=Isu{Nl~ei(Gu-%^~pjA>Q16v2~~?-h5A)C*Iuc7jM3WGl<#Z z%@#h^KE#`w&DqeRV^zG_cOH0z{hHT-`^B4gpYuHDz$NEg4)=Ae_)hLW?c&aktj8-Y zwI3R=yN6WIy+{1JjQREqaF-k;`>uud6$e`PNc+L7lR4PL(s!Tp zqPkzG#w+m(WnU+ak$c$96`XU;8HVkoEm5B`UoL-v912!k%352zXE%D_hwt0NYa{Ai zl1j>li>ySr(n@@}yi?WbDZkBIK4!|-9Iwjzmf7JgW9jv9xYJc9_05*L>qAq^zX-RL zN3BHp7em_0&ye5!+RE$YcmKBXD+Bo2<*g&hSLlRbz7pOt7Hd5vi(W5Z<=4Z{i2?O~ z>7|jZw=+wdP5bdK0qGjUkqw1KURJndHBjU-%Bf5f8&Y4?Jh_wW9qNS zUcc!NA3oZxVQDlSz32|tObg5-ZEMTxZmR9!POVOZ6D*Mk*v2fOT87|GRb-y|BZUbdub%=Z9F-+ zy%W4;lJ&0rH|jmgOCzasHN4jm4(OYS-ZII)?o8Ed4GW)U74Z&wTA%yMe6p8bl7~rI+NPF(+6ibG&7uMkW>hJY=y&?bfMYTFLrra)awX(_5y+ znH#VH-ulCn^!z}7q}zh>>xZ?Ke?w$*KwJ3|>8AtR%I}chgWAd;3Xs(TZ@o!gLwUix zp64yoV`R0^%d62JV=oPVVd3q1c)LD;rwhIGlRR~1;c20_Oj3s$y*$a7GV@qg9lFFz zFUdn=ez05?d&?wwSexP@V{CtcJ)a#Qhs(Y6l04K53g+P|ZyC$-f3BODkD_XO{XKy=9X1hj^h3Tbyn~vetjImsYa=#&B@^ zZ}pamnD$qA>ks2UnQ`kY`#ZgKl6BV<1lJw+mPz(`jkj(y9)0Uw<)x9VH#8);-ut~} zI!v1vdg~Rx#mpfEk({Yv^gWF4Qhq)D>;(b3|FD;KlAq2j{H*nsN%GU^;^#=}rVkW9 z7QBc*eLep4W%8TFCOzt2-v}Qf>$HruO1t%hw``L4n*D-#-{371F}!!Wco$jHms$CK&Pyj*cW78}-Oqc= zSf=h?SKTf0FO6iqomuLA$y+9B=HSpFidSVr=&w0Z{GsjEGVzBBjtwnS>$QfQ zsb*bf{mr_*lKeI9A1s$we9Lr)D;)lO>v`2%ro-q>jjK(_ z(zomzL1mAOzids-u5)jD%O=}bb3kzW-u0GA`ala^yrOev{tnCB$=W!K4ROYE?o>6u zPQrH+|t(2KkT4E#C6UerY^1 zzU8Xpv&(jyw``K%&Mf@yNGoH;)LIw6+BTMJpCpWrZ+tdi{n(X8(~-gUaO3b`xh1@1 zl5*>G@sUk#UwX?Y<<@y*eDTRAWtSWKqV9M@Qf@T|1@YT#u}A1Bp9!hT+x>kUrrf`?+N|G z`9HCsW^4GMM8|AvJ+!x5(XsImXLdFdr<=(A%GgJFiJn;+)>4^-9WJnc<|X9)0#(jB zCJ7q{tp1a{L}aFh)lW{sMgxm}nwN<3R+%c-aY7PS3@q|_UZS2o@s>jPisU3=`vbEE z@)9xbDk@kkoP-Sq){~Q;XkqVN!Fu*j!Yp8_jrqW9G(1|Ig!hwEUcn21M>V`kC9iG+9|N2_ zgihO2GV3z%3gFyV1>SD;gp%|-417HBsTv+l$?jPLp8%ZuZ>oGtN`CDIeiU%_wiVn; z$*DwU@HxPbRq$@BB_+Qr4g6H#$7r~fl3#;?p9!3MlF;wA z>QnNoH}D0(xfiM69Ysn0&NcA!fFG&hk(B(-Fz^e3b4Em!C%>W@qq7ZsA@IXByyvha zJZj*V0H2`Y(UknA82Dn~l^WiXlHaigemU^NG~7zbuhPJ;0?s)V_}gyPr{otg@TI^x zm!jYugOmJ~8Tc~bhiG^tCBFj={088>MWM>aQt}HMcq8z!8s0N9N#8Q?n}Jtocr+!y ze(sB@@p&uoh=#YMz#j%aO2cC*`E?oiTHxekQssMwCFyq<_@lr_Xm~Uwzh@1+4S1P` zx1{9PZs6;Hmuk3`l3%NVKLMPxoT~o%l>Ax@d;@TDOe=WDQAz&pGw|nt7ioATCBJ3^ ze;znFw^aF9N`6fS-U*z1(ZI2PR+4_qz+VDR{#yl)rsQ{>fxir#92*MWl9Jz*2L1|g z@@go!m6BhBfxilz+}a9WpORm_fxiKqJR1t$5lQlQu7SS|ob!bW9!bgX3R0>KWg9~058z+Xi9!l415c4&dE?7` z(!h5B=lqU>*QewcG4Nf$$#6Dpn>yT&Y7n|y9n6T_*V5LGky0%_XB=o$)JS78R?IcD>x%H z&cXgTpIrsc!Gk1EShH2(@LFDx$?JCT6wU|aU4-ZI5ArhF^P#~Ruj!1>r1MvBVjnp) z*5DhapR3v=@PBGJ{$V=&55Vg`ao{)NBc{WD13dbv1HTAAF&+LZ;E~TA_{sQ+>F}q4 zTLTWf9Dgw#{y6ZS9CB(Pg8_WTbogVym7MY&obvokoQDlgfyODw#JR`d4AVHnGI4G< zIKws0@JyT)2B%o#6ldZrGdLqO&WKE$D-F&VjWZ?_=UWD+LgQ3q;(XoUjMq5hGjSFe zoCz9dLMF~v4bD*-=cr7a=>}(_#+jIjbG*TstZ^o1;!HF+Q#H=iOq@!CGfm@6%fu-+ zI5irlCKIQ`;LOlCGcs|88Jsy9XHF(gp20a)N#*4v_hhBm`-f*G z)?ALS*=4P-AC#-wIGcMZhwAo+8_VKzz?)DpBHnt~)V96@t!~+ev(DT&P0Gu8tCrmR zPPEpZmpG5V#}>{^phsK<%-n1PD?q<$e zZUr8B+PPC^J)GhpA0AYhwUmjU=PC17%EUHU>(8dnj>l4E`u{`OhURdHwd1XIo-(ge zrf0pb=TXNembPv+Wja~!E%4U!YvJ9Lc_LNMUrm|Nn0V;b1)h53ZQPcpbUn))y^(re zHDwkO&z<0{$EJ*B%Dj@Q=hw+HdGXLTuiPG{O#PF(p59cMXG|H+l7v3+mT9I;#}m5D z2dOf)Dbt%D5543qvyw6qQ)Wx5%)?HZ_V8NdcGa048C*k|Si7$0hLjANO__znb}sam zSxlLpU+6N8sWK}KZ;hni$DAJD(imIsDdMCgW}7)*i;&3dWh} zd{0Q-)oCs)jwTww@8K;7!LhIz@}|H!;K|+IdUAVL3^QMB!gTyz}7X_?yUg*)wU<>-;9lvTyClzZT_hY2)4GI02WtTt#*v zGHTUju$PGtIalOf;xN7o?r}G$zCeB{dC0zt$Rx@gyh&Ofn&%zDvxzT!0jy}bbN4Ac zXJ(==*Gfca!#DZf^8-f?=g>EsS8yI%Vqz`FaUZeB{w4Pp)7#?EEV4hOY~fuFPvMF& z@#2bTo1uFKFiX>Q?p_yj@2kkp=eykdbIZoidkxsqI~^ViiAm^oDA{Y>X%Ef8UZV@9 z-QEn(T_5h4%sm`F?845#D0mniD6&P zP3#|Z^`}?2t>ACbsjflZ_ny1R zBU*`1w03&Vt8(|Nma&+NKVyYX-n1Eflgm`T4S^3uL(8*^ac$mvengdb@}5qIhPk?yUwr~&X5pLUJw|Izm5@ljUSK@qoB zlb~&o+7j6^Ak6Q5?sK2ynaT4E*l&M-c8ekbSddlFr zggXC?3`V=~)b3MmGU(@0-j=}$zfxPXniDvWBxdEt1kZP;0|bJ{tY;kJJyObdJeJhOffg9{q?rtv;b2y`=M;c=G9E z{~+%-Pvb{WTOG@KgXShCDCOTe2x zrn6|piF&T_GqGj(`@;9p%2#bRGP~zYV<@kD23c>S+&PppM(J|7-Q`Z9oamO68A+KI zVn-PNn~meFG8ODq3e82>(p@8_DVjwN>|rwQWSFODnk8mJ$}u0We1DDAHYsOtH-X&$ zF^qCD)(42a*m;!^y@TJ%U)FNEsZUPP6nHLl^o1rTFW2vu`9g;2BVFDU9EQvj`INsm z7FK9yeQg zOGs!R)Y_;(jx+B)|Pu*5d+%kwv2HTS?!H?1h#el5Y^7A!VGhN~CKZ_DJ;d z9?=KN_mC|#ZcL!Dhisodv}`YNkyV#$RsDF`p5#*AmTj@*5!>OEZHp~iWaG3adGxy* zv|QZm$!WlP>F7@U!tku0!1qP)fpyM?cKoF7yS3BJ`$!iZz>lt!b%$2`=X};3%2{^^ z=O3*49(AvGt(#-s=23S(zW2#m)<;5zl63<8`N*_@`iZihM|v}|p6-G35)Yi^;FPz! z$9vS9&$-tDoN`C|z8l@-oN1;esoO`lzm#?d(3hIjD?7KLC(b*|=4Bha zr*wxP4{QTDGM`2y=Lk36aSnn#|{__9Y{8~j=e&KEuMQ+(lBza`)F z$R9@jv*fSw$S)!PN%9}}$S)`VQSu-0$S+~N<6-h2^vIu2{twA7_sB0#<^F&2@A1fA zL;e!-@9@Zfqi=ZDZRFqVk>5uC4dl=F$bZ8ho^>txS9;{PrG;l*O8zX5{1oJR5&1L7 z|C|3{mH0lX+_{iw@0hm^m`u3<<=W^g$>P>ysYh*6cGR&4lf~T;Ti&^&wP(jY z1L6a>5a(4Y?+C5-N1AxQu>g2Y+&wWpz_;93+AekQLuF1Z>q4@QDeE+WQM{j_eUVb| zwQwI{g~K<=<9(tf_?*>Q?sr^NLD$+Wt8KnNvv$Ea`wQ$&;5}=cHSl@1@wlfISo&}M6$MAi%5<2UObb&XAGUeN3>8xzT$7pRr8AChOVZzXe$R^DW6;& z&LaCxwm12`jIpaa)LAqV97{i*s@6`hUCq|rZL;p3ww-YgUm(|9N_m;H=dpIZmwAk& z-EjlH-!<0VU`~Hx*Hr^*_x>DSLR;RV;S5BwY$gI&s7x{+g!A@8HhxkpyZP4vcK z&7)oaZs&J^-_-*H%)N~Uxvx(2K*n5W8EdUR+Z;x^l!aIJS&Z)ZKl0WMG@|3-@s-PR zBUda4)L!=TBqh(=;Y;HmYg_*8N1r(d)r^or{b=Ii_~+PrGG2g}O;) zJp9ly{xdKqIu@BRG@VzL7g_t_vmfbjme)OE_a zRlNzDZPt)(mv@tOHTmm?7*W>Nn(uu&H*z;Jx(iuJf80f1F@9&uI>-E+-+87j>uj?{ z`ckdck8`$J{r#U(r`DEjj`;z>y_}rQfw!sVdE%I!+&Rd>&YL1v|=2BMV8SZ5?3`Cwy4%^idGJc1dyKVP8K=6(>s;EFt;Xvs z;f3g{lZRd7wW@EGwZ`il^9+~rmJGAa8RT7#pV8#dc`Gl=6n(26;VzGJ$a`gk5gjW& z)K1H$K0@2VkJxg^Hp}_l_+V#Ij?RCO-+>41KAU6S!*6AC7kKwkbV2z@XHeF*xkqZ7 zTL{ksA-8^WMD5+ru&wiuo$M>7}T*}-1<}31+UKP)CSDSlU ze7_MLcFNqgxgU{UOYxsh}=9wm$gDa?t!fKOtl zZUmnbb}{=CVhiSxE;!uednI}6&a&n_*#|87)*%DgXSeKOwpq<@!5v^P_fWR&Qp(!4 z?Fl8n9CIeLhg|k--M~rvfGUMwMPe{kAAlcmYPG0%!a%bs}g=W?Wf$6 zo$WV9wGS}{3{5i@Rxebs4Ru*lrbfryL;MOhGsibg`L0u-KTQ09HJ8jWNAo*CT#+?y zWt(rody%74FYNYxLfN&qbEb;1MCsdN_VW$@_7?GL(7*gef#`I~gnAjH-E@zbgt`ZU zCq>$dt$Skc9(=Is2iVsB9y*-kp~J(_;Za(L*Mje|&e&-2eWbmY61$;!qj(lZ4@C!M z&6xSHdXKq#E}Ubo1&6JF{j~l)KOg%Pa2Z=~?^Cv(DJGA~SgZ@N) z>Ka>B{doPm!lk?|pF7EuJyfS|*!uS!@~X$X>)-X{y)s_e?7Hl}mY)2Mw&mfc+kN`i z{0>}-&DQxZ@w;(Ow;nysZ;^Q(`>+n1t@v%l{qgp-iu=noub`~7xrMmD|6_0Sr|?_b zFvokBx#nY}Ydvc2iUkyZ7WvP@_Q{-fGG)T-_X)f>Kj@QQwR=yuWF_ksmEcTj>xYZ1 zlH2+m_~dEpRsDEd|8H<6mbc`QWBP%$?(}$B1?Wf4ei!C<^|{E5dBO-ipWO${9`l2n zW5G_|QJdhw$EhBCTmv7^8)U8Z|9UE4eAxNOLu^3{c$~DXXCFz%hL1^CG`Xygyhq-; zbJf^Tmz`$mQ6XuKGrRRDm)|1O>Jf2cL!6$V3;19;=3k-P?wix0OVXO=0grR(k{&1T z+f!@z4Darn8Q@9UH#ZoE92c{uZJ6y`!ee)-h$KI-2-~0i2)g|tI^ZVqz zQlfc!l*QA{@Wq(g&C@rvd>iw3cqSS||Lp{0B$h%Q4rH?$-C-KxY_8 zlq{~NOde<4d&uHHzS=$6-LiNAoJnP|;Lx%d=fc}AJE`i&%Rb*2W z*UPl(eMLRFvqSbGt1oh|_p#Kw$cT<&ye%7O)%%Qkteso+X1Uk7 zxzxSR>r&@ZE6({kc-NacJ#{tLJeqVjT`hs8|)n z*z=^`C$9B!&CfmRl~eDZ?0?9f>v>b;JII`-zFFoJ^_BU#k@1!*+#K^S9&pzHSN4Km z_NdqBQSS}vZP4_bpy?T|>B;9CFuL|e>zsR|t9fsRJ)ualGd-?+!=`-Bev?~XIeF3s zx4abcWDnFWZw+~m=r-({Y>jQQAL>@Njk0f&hYwkq&ia|0{qeUBjchxHSnrPpM79k# zYTsZUrQV3x*-O0-HM*NT%19rar415y_vvR;v?=)?&0@UQGIK`keN&BC=-@VqL?{k9iY17aeWH#gK*uxR+f= z*~R*8i4XT$Z)=3`&syZn*h+jj$9njIdneQGNyO@u)WQc9pF=;WGhQLa3%lG49d490 zvQWA@4>TeBU{wJzpxQ>)=~%Ejd5@y}NZxXwyjQ-wSFxM=2KzT|c=z4-JK}}#jT2*Kh_t8M~^_1-GvNlvo-BNsf*+aS+-l>@3+Q7PrK4amwm!BH=8Rfprern)E z-w`*j9`NYn#<8m&ck-}6^RvJ(;$$gt6i;7k#ozYeSHY0T{9||vojHb+o&a-NCp}aD z$MoC}JyUaDof+nTDBHlgU>6?s$f1)`&)fky;ZsnVMa^KZa<9o@?(-cn#} zE{&(P0vP^Vh?xLJ4c|0ipkE!Q4(HvsqXN-P#=08)=5!5kr4RWzrzvm2=ieG1cVpB4 zIyfb!rWqbfY*3Bnht#)av6eC`ea5H?&Fl5K7O&m(aae!u&_wn^e~@z%nrBMRtDt`s zcTH*>N*{E798Vt?o>DG!n!9a!g#5+qe~5l9PJmaBjO#gP;>4@*#pzcWFcvXCT?~#@ zly}m!7Py}whw3T3y$#J`54d+Txc5Ax$X>(!ckDoqH`Hx@-3)BM@SgLBImje;j08-~=T!b*{Ap~o>Z9B}=!98?tc#9EKF}`x&^VFU zG}1&D!u)?}p~zoith3D9kiW#7w@}umBQVt{BBt85-*Gzqg~;APv%%O>fc;FQIe$wm z_*?Cpd`O*k&D(a`vwDZMKKL%_OLoK>T*pYpgc8PtQ?kV0VGcuI6q?_nj#EypoGTPv zex3CCuam=?1n<8(z0FE{{H$*EX{ZTUW33;BfWv z_b#-2c~wt)Fbo@*0Wag|*82D<Mlv)_~<*G-9XwPknVu!y_~Dss)Tb;m{KU3qpr51B7;p}*3D{;kNhGQ+Zq zUr)4b{SNibH2=+4=Ko?J$0(hUSlw*%N&c68Pf0K0e`h=M*D?ksk%#bXk;b=0bf(KFL`y+isD5;7ZkJEA`yJGM_PA@K1oRFM;39pDX)AEcg>krp>zTl`_6# zyDA;yR~+saTyTHtf?NC*KW&Gv&Dv&iABkR{#`fwqcjq0V%`05+HhSQd^}z<+E^U9} z`0^(H)&m)Z5us7uCQe27P0G&(M+v<8=JxnEM`M%xn-st8Gb786>rBrGMAQ3N=l$%p zj+>5P{um8>J&#ymnJ*H+8r#vN5Hl$yHY!dOV;hk#nDX&OBSQTV` z;np^0hrtf`@y+cX>rOpnF{sney3=NOwDJ+=4jX+P^NuuvvQB6mW38)+e9{af`aWeE z9+mi?%r89j!n#{9E5j(t zrtir-mixeiML9;1te*`MILv`%Y|a{J%}3|L2W6L;8`C;)H`pFaUYKU>i%9M)7 zD=e65jwycjqnaL_uI6+GF*dW6u3yzd*Yn|Ts7u%5{qt{bxBPQ~I}iNnw$4u>=0Mg} zznd+0aniKKzI@VW7>{UrpgarT@3@(_3uX%_ffY1>2K5W0(@@lw@> zEVGFJMK_zaTlA0Tx6D8PV)<3gJ!pAiv@0zWTxhvD2`x8kT83zRgZauFQT&bp{4f1L z`hLql)g0K9ZGiOnbfZW6OM-cFklz=HA}52iTivXFXr-$t*J>Up~#>Nxs_J zWyU6Rfw4*UVTKPd>K25~B5q0cV^TQB=r?~HWlx6n&ozC&U%QpFErRnO(O8we2M-Rl z=V9$hOksSRTx+MThrjvoSMH|V%HN04SoW@&uR#xQ&#^CL)1&Z)N5|jTP$tLTR6;3>rtr(f>s!vUj21*FFAp z`9(JW1-_I2W$rZZ$S<|{UkuIN`r9po#6GBO@Tx#`u3>a!_{tw&P9G`M`wRDzmhM~j zxE|{iP1482e>oeTO5b&kVS#S?JH)RG^IOL2#C|Aa)mrSUhO5f1SLgfE%{tQE>PVm4 zb6G07*t6foV%&|l0Db9aM7J%o`=IW3Eo0(%|D5oiy_Hh-LY?~WV}GQ*Z%OSo_Cw#H zf6ag=L)izJBcOqc$W312wV)frRwHtITR-C6tyC!eYnU&KCH z{d&)3le+r0wEcE?;4Hsd@g~E(N%6*`o}+K>W1V05z0BE_&TuaVeUrUVOP^mwce-_> zCk?R;zD=ETiOamK7yQP?-OKxV*dwuV>ZPX#5V?Kr*`eJbu^J?a1UXr!*&Pwt@L(E*V^%p z{8#!!?z_yt@_985XP840csP$U5{<}J_L;NEOXnWrc5KY1qYqZ?elJkF6S;S_>xya7 z9NLARsQBanJkZ#tK{t*6w_%1K-|CT+m(KU{C1rl%w4Nf>hLkn_jeVTX(`u?Yv zVm~klKYD^}?l=G_S}ExDzecaUz4_3m;Im^UTBT(4m+ zNPub4kZxW>`a0;m2%G0IHdQV##>UylbN3#oVvoOA$HBkNwX{27LNBT~yt?G?-XxH=&wK15q3PQ?$NBjI6) z{W|M+;1SuE>y;bWS4>}Blx4-?8u(DoyDii{DK<>uFCMS^^$))jbd z$X{S2@;$s;&1F1cpP*o8m>*GJWamcPyW}Odqm{J|q3K21?pEh5>d3xLQa|y2HP%-y z$Qu`@%P;Q1Pwef`WgYkABj%_T8_~-AqJZ;7avy7ZiZQ0Z&zR3RR7R{zK~7+uFM9ub zLffS=@yp|VzkKvb@@Bf^DgD=RN~!1&zw3;Gevu6KKGG$h&E#8sBpz4O{uuZB8!t#7 z6uR0|{pb7d3#|AMzN9I8W_0wMQ}OYLi;c*4p#M$!&-qJldF7U+X+NI0^!)AHQu~?P zQ;#(BxYs)02)rnC=ey87;=uRcdyust@p}rMS^jY&@GB0+*7}Y1cU8Oxeu&@beD_t- zJ!7IKrO7&BbJzX;#6-pJ?^PSSKeblYlydO zliJIaIH|qNm-f)tYgtn$ylG?v`i?ny>D_nFNbC3GfN$s)*0Y*rJ?pcS%y%<^ zOZ9r=ap+VNeqNd*W-3NGJ7#MAfGT399zE=ssY~bhSDwn-uBv_bho7bRw;L0U;6`wa z0LNV7vc4oPD@J-daanVH{+k6y-nYOp0UY>Pbz29-+0h;OV~0ml283swkB+o6=Y0A| z`fzsRgqFVH3GE{}*OzWYcOlpC(bGFy&};06Iun5ni{{RpTEu3{|I5c6tg_>k!cVgH%l-1N zv;GyDZUi?6_BCGE=iv_{f;@bw~M))vI`r8U*!>mv@nj&$&~dL?`vZt=A-!2jIi z>y(S|^(5iztUz=Q_v0^lcSdcEmRk*SYtsKW@xQYkzG<`Vo3`BU=9^}150k!;`Z71% zC^~@eqkLAtnxLEGS5F4QTNcgn>tt=NMk!2gQEZ4I9xSv-axuAzE1D7MW8{*{_ zlC+!S)54_nkma?+5?vlIi`K1jHVXgUAmkeA0?|dB1$XkHb%Q0#-$09P?=E!6vU(}99AwEdFoOR% zizV`#Eb_Yp`El39l6Noq*76I@ahIP#x|{r}gFWT98u{&ITxfZ?q_btQQO{ay-R4V~ zzXt=g(-|j&j5n{RFgNP&Q}LlIpNVgK1-@?+wj}d7eBhe+*gMT5HE*}(F&Sn6crsU+ zdR|Q33s+;=oVfVABFa2n1u`_~!k z8_y+X^0MBw0eO?PF)gwO8XAeoY-OA-!9Pnec6^=6cO2<5H)zs45j$-0EzA6xJSVS0 z#ERF?HX8m#>`NRCj2lZBj}vK-*m5Tg?*lJHTyi1}IZ0^Plt4rH9PWtTO3bYIXv}+7 zUt$CwLZ9O3!S-#ru_rxwXUEg?0uSgHRYcy=*UZgl$ z=)0G?&|=_AXx`L`d>*Dgep?S(HYK6u!30|79k6J5fb>xZx_K19M-N?T6#0Et>}U&i zA=GR%{IHLa!9!bdc4bKkyjyD2-?e3Wt=5T%=tR4vAL_jutrKdl$~awTjni4%8;J>b z>VT|8yo0U;6LH`R?BOnnySB{u);Ow*dg53Ij*LVc^8?YW?+K0zzBLXR`x4tx1CGu8 z5_p9j9dn=HxaeEs2#xHCqY4}?_)^7J<0CK*Pn0jRn!uOwuFgNFYi+SE|4m=yhFSiV z+9z+8_!6}@Dn2=J1UE1?i7&f~7<}<%C*sSt;Qx-$unRQo6Fp$hOagnRz($6Pue1EQ z0u4J|U_$?~8g_pV*khBx9xJes-JJQBe2xG8SAydJo@&@n!SMSi>&nergZBW4OdX)fN807daWbdy~MrG~S0<{fk&| zfutwQIm$@C#tjGK$D&`j;K-d2ISU*Y3#z5%z8es z-=fd7oXpx{sUb1-m3mDs9v5?!rF{>LXWoWbFh}EQ2ky!Zv4&By4si(j^52dHPov(U z$`x;n1tmt$*8laD-TI#&vGjkS*8iW5w))OP>dP5qzJs8}u3P-;?z*e_U;0izT{o=j zeqY!99$(wH@V#vW&tQy{wZkTB{OeHu5&iEK;?fe+*Aut;o=bY!Ys5~uq~{~6qr2M3 z`8w7Bw}D6Iv)j~sHrpK7Wk3G^%eQP2YgOQPj_tC4DERIC7S2O+>|mBTSjmBQt8b>6yO&(mn%{Xb%GPqeOdfE4UKv!5U&`WxxB@G-!nW(O2?i z+#M-j{Dw2-i{EfM-_zi)&>(T74*OkMsLzQc(lFG8h6_AsxQ)Ic_Z;o(kT{ ztf$p^#DJ?wtl0{1Bb2OGqa~`+h~6d ze07nT8gu0=ylWm~rH&6xlyzMpW1PflC(8PlE;Ma&p^3gVK*pa<-1RQ{_A~e(`c@@h z^lcSiIkVwHm*?2`0~g#cCc*up;6?`b2u^hW`+g&10dkn`=*NK@jfQjadwTdPWht)h zzs`k*ND>+%y8Tz^_FtykKS#dMHkTa#(>|*C zPTld50q9Hd=BnWtuztqF?m8 z-(Aj^ez#7(^t+eki{3TJm;QMnbT8w~L{B=p^e>K%U%Jq-DG42$G#x+FbW~|NR%tp` zXgW@Yj=Ou(QRmRZI6BH*=y*N}9nWhz?$UHD)^yyd=~$@gNP~`B-RS7n$2dAdE_6JU zgpP-V4){Mu)auIFb?M=7o6X9!+9)skl=p^Y&o}~U~_Im z&BgS&jkrAP+(2F7!sG3}7l-!*7re7P@CG$rJzt2|QRuo==j*XhwVA!q9fgdAb=YH} z%dPG&DWlGN07K4u;D36S9Y&eiN$8OLLgXPnf5&Ck_dojkmHwVg{ZXU4=R;-E-aJrI2#nKm3TG|~?nBK~SE4M+sx@B>sNY$LMk1Aw>L-lOL=3E%oLCSNJlI-`61LtN3lxK7C(owA86O zI?#1T#BB1V9Wm3_(RwOp(z$0=)2sL>?b*!vdyUJpJ;lHob(7VeEeS9Z+jFN&dyMWi z9kr(r;J37+jPFR=Av`MphqKMr-PXKcN4k{FyWWyXPyAVCK78D|$J$5G?X%{XS{}y& zqrN;=FSO>PHxkR|#AWYs^rhUAvRHkH^%}Q0o)~qPaGz$AzBfZ;UXWxR!PdtP>SeJ0 zW3M69^IP?q@5kcy^H;a?9wm8l@0F1%v4@%Fxfe3dIdrV}t5{IZ{o46s67ts*f472s z8SC8I@E5_&_~(}Q2gzehbjxcbFAZGP-!mGduT&7{toq7*5--KtQ(jPO4g#KjGTE| z4(#RV`bN@5uMUiR9UTcki{LC(aUvP!3hM4Y${3~SdziY=bp&-Eq|69K*Ad(2RT{xn zz;V|50rg%V$lX1hwNiDTwdxA(&Nj_spKH|+?oqMiqt^1>+OQCKvX&I<>wRxZDP=~n zA18ZeyZP2Q?`F|FT+g1Fyr<%~_^95&2?f|s;$0L?Lq`p53zH^vZw|QAz5X!io}}qM z_Xuyg$5Uprrn^D*5nbpmGkel4L#~jB^zx~oykAC5kJo-g-LTn%JHwMLbNlb6Vu9fOO zTZ%l2PnU5a-TV*zN6*LO?rAW{AB@lQPx77h%COmA)0emWG~RBDy%d}G>~3$Hw;5Qn z-z_%p^9%HwmzpNgVcX`tL%Gq!n}jZM@Aq$zzxX2b%PCi7^D@=_FER!@b$Z7!@mp*ju?TTCPxPQxaL~VZv$v{YslHT?4v&Ji3f;eiZZ}*%6I{fGE@r&Vq`VV` zH9lpU_IUfpUWT&&PB<;Bsc9T)e9Get>Sx%K5MQBdP7j!wivLqJ|DCYx_Ai2_Mf5+x z|3DJ{-%PpD>{*6bTX)mT`NErP51;?C-Y&K#NWDjy>&gF@@V~Qt`6@Ou!#tmKX=iIE z@qZrv?o?XZ&_#Jn9Q;a_) zhXn#lcurY?wRuiFEZbhMzs&0M?_bVdtUgoZ?yBC5C-{aU|Mzc>*D2A z^OlrYa8xSiLq#VO?6TODmB6$8t;_jeY!9(QakdA$9kj=Z_53eu8b740ofaUiWxo5} zOP1cIoA*%u(Vg9Et+kv*ao)kZK4|eNHYtts?D1!O?K^lxE~UVU<8OymZ$9a&k8+luaB@*S~JrgNw-%pJ3(du?B&o=b4qV&Z1&)yVqRn zocn9vp`P+JSzr1247I)zhkH%Bb&hwkHSg>RcgjS2?i>gAQsCCWtFC(vpF5Fv$>{vt z0W;kNrnG(Zx1{s04wwhe>#1`BQ|`eyn8Ml-^PIP5^Tl_2Q@;3VZ^&2df_(A2zS*nR zlj3wUS(~1B;Q!PGe+pxwtmS{I@jt8a|5D>$qw!a3{GV$4ZhcqwP5#Yz>ZRZ1lY^f9(|g*2`HG%QbHDFkRqD5tV}k?s=Pt0{ z&~1H4x7Cfu_V^=Zm%8vowcA6FRypv$>4HB+>(8x+fnUmAK{@dyZv2wH72P*w&Xi9) zkNCec!Kd^bKY7=)mhW`eEXzjrKUKb&=3MHk{;ux|S&gpbpHUR~1@uW>Hy#M?pTmEd z+a~%yd9TER*LTLU8@OX)sJ0JYFh(Y6r}U+AaQue7Bh?0L{oWq)Jp1Z74j$j)!edK+ zGE4$6Jo}L?V<~IsatZy(6aQcb{_|b%muMZ^m82ir_@!(?l5&#Yrt=S%zFqWjyT1>2 zp|4HT_opOyZTh6_7wFjy$SI)Z~a3kI}SRd(|X#0VY;uZ0j{*i z9;g0IS?4%awjvh%nYF)^I8J%W@YfF9AA8{bEJ=H9{s@h-M>7Qed`Mq-V4M5BZDmiy zg4;BWPB|vykBpnP9A9vuQTzyrtNJ#5=T-;IU%0{4x-sQ2bfcWIa+i*m4UznjIzPdG z@RZ9G2Yrh?=v#UiauM94lF(+$Zw=){zkh2StSU`n%cR_8l(}D*Io$Rf>u68Fr9A?7 z%3-v}qBGNc02;&(K6tTZ;~za)z8U69_02TL?v7<|ZRc(%$J%J%vRK1w`(oKIlkRyI zl>6~_>$~oEa)wi_r^sBc>khd=ontu@N^oEE-Nze6dvBN;-OF9cMyz^JBwnRIm{<^?k?89+pV!p#nH3p&}?j) z9NpWWvug{uE1+-ji*hDov+$2K5wAC=ega&7U+{58xMF?1m$6L6g+DT&`>(5KGJBz~Lkvq_~aOb+; zfbX1lu3=5&qkD!7i0un}Eo&R1-!o~0ohEUH(cZ@BQrU;ORoalQ)^l693&Xl=Q}!v- z&7u8LRu1*^hUHKr_!w=!JCE}f-Li^^tfX!mJUZ&A6i+#x0q&}NU~`_eh5H=jUX5ST z#yy-z)%@v@Hd=DeHjk(LqsPMUu6-iwz7e@|oLIgw6)DBzWdF&42lzOnmvXm(oKy8L z9WubrZ)?3T-TeEAl$EUScFCoTy=7!jCwB(|XNTM!$XKx>fAevXVZ0}?nDJfqbQW_b zU5(bW8sR;5Tlg{aq?qSj?t5vES~ng7P4KFKd-41)1jg0qedRDbwCR$yzL_VbtZdvD z>!Pii_nJyI&QfrOPjp|~`a5`5@D}zT@OM`t`+D$H=z8!%>7&p(d#ZImp3YNi+ZKN_ z%s&C+y}Zt%Jm}DVTeEZBY98m^lHD6^w__OfkE0#oUES>non*E1#R5xrR_|16SFSuy zf#*5!T=ZV_!KvT*+r)3pF;|lwZI6xdl-m)!VPpAat~l0^AJhG~`kx1?#2(#6|H#>Y z|06PPD;%Wb_cq&iN23$X`K7s$Pp2rq*A;GgT6oqrYuu=l`y`pq?2x-AmCvv5H(kTr zMy;oz^AfNA7;RB_>=;JU-vURXE|x&^CKuTF06Pjhj=z>D)O}$r>lwX4!xj^ zqC21V*R~E%i95$C{V}9*>T#$;#vyCWNH-_a4#w}gEyK=?H1)YCy77pMqK%9@yN36z z<=v`i>jqz>t)Jz8EfW1=y!VRhI0aZuM+0Mk1!MQqy=%7>i4WHeV*xO#@i)Bo>jnvo zEMPp$IH~C9RlALII&$BFO~))?gc-}d=r}@P47{)l#_p$6YPSsq#?$zcx-G@Rm%%;h zXk<@L#=%p`H~M$3eS$G4&8N7`!M(;^-&q$r`l4;RqV2AN@g{yg(bO`x&EzhDz&yb#IjIv;1RH ze4NE9D& zEq`l%Bn!DN*RqiKB;T1c6g_3Y@Y27V!LyrwqUJHbFNyBPKW@b*u;(#r1V4MoGC!)( zZLaC+lbPm~icagE{Q2GVn{Cdd?5ZKy31rDSU2|a?a~bXkop&r}j>PwQ zg1Zi|9ecRr#)&IT{+45n(XtOGe3}3pC%@-_vwBx-bQrj@zx*)#t&P+)w_YJ$|^98OHqgkB7)#3Jjs~las9V%neD(3(kL& zuiCEHI~6?-jEjV5gBPu9sQ12Y`(5ai{MQbFcWsjVHtJ8)?Wm<4Z&UU`=wTk#v5Y&q zGr8+&^uPL!5k1}c`GG3Y!}4Hb%) z8RoBPbG69rnBL6aGR;f5&-hYw&Z#Tw|84Cz*P|0-m=DW*sD=IoU6m>K@y`0!WiCE6I=QdMrFy=3SJ@1jeq*tarKg z|NDTtGql3d7Yt%bYV_|K;7g3j3hvm{bFjE`T4kIi6kR@W?Jtj+S2*U%4OD4Ob&?ThCB!%rK|$b<*flZ_Q_# z6G?w>pNb!F#a99?KLe*Ld}5B;(I2s?rvk^xztt+%A$YB6}TYBw* z4ZR{t-{ejK+jnCO$BtL}=Z%e|?Y=<0CtH8gxLO(4oj%*C=updR)?J2v?x{;-Y+wF* z-k4W_mGdJR!&rCmvMy5U(CxB;mVU`RQ|kYL`chWT)gN8LJ*htBAN1tyFVBvYXN6~-K|S$J zYln%)MB-jOc!HfnkeV#?O0TJ$m|HaC>_j;tMKL}YzX`sHfY zaRl$W=hu^I~*E&PuLOaMDfT`SP!)WZPuPHzIcOcl=*!t!YL|Q@MXc)=JYR zN9(T|Te~_nB~B+RMBd!lCbm~}QuNE;V2r6@{Y~ypoQG^{1_st;b9bV%jUm<%V@DV- zRLfW1!TSwsU+9GBZ!7FCr8_Fw`^$*@~~||<67Q7q|R>q^lxa>W78%_OQE@e{?l-x=vFHIhqKt&R#{)p z2gg3j^O8mVx@Fm&3;8W;t2VA-uG0{6Xq!o^}XN zt@J@=C+QWM_Z5_{Nxf3`LgVat@!v&fVF&Kyw{=BTwPZO%1D{i!Zt6i$W_h@}J)=%h3*5=5eQ!v~m9+ zBlg@!Mv!2bjQk!p+gl~gf_?8Rb1}VPXYva~!6&>i}o2qY>wfT05OL<#oZXxeyC-4@6 zLk2cauOm?%wD+yB+A|KX>t_C2ooCA!{;Efl_C^WfP)^E%r44LsOQJXD~7@-vO- zOQZ>}D>UEIQgVvqJqjs*DSVT%ykl7}^_;wuy1z`Q3(wU&umavyV9Qz;q;N0ZU>DvE zgm;4#?@pmjvM$!9%3A3*pZb!gXw$r?=+dFVs{f83#+=W=^DuMkrt-kJCS&Xv%Qg-& zvwN{dE0?1(UGE`8%54KhOQGDX4NSe z*7>r5%^N{^;fvTd)vteG&7H~~GJ^L$WE5S^-#qrW%K7_wm#y>t*oUqAMc40c+xK($ zDRa83eqt2;g1--b!gvB~HP3%c+dt-%gMG;4SYqSPN6#jubj=F~Q$LUU=aimndtFLB z(O=+kAG!z<*Ok`o%R%MG@ z@LNjt?^0}S9%nvk^zRyehxpyDf4B3y_`O*0Z|I%)5jC^0Lo=;Dl}?{(eB9D^p-1@E z#`@n2=cX!qnK7eV}<$6589K{T7Y$&jO1+@ka$S+Z?2E{z3iDG2c?(Tyul^4l);lQ|p@AkFK!v zPMs5r()P+jwDm%b_j!Q_-scqDO!L?3n`73hZ?5?(^&MzFqrQX8-7N>IW_RO`+dF-q zepPDes`C5xU*)T9N5<`pC1K_gbGCDDJpC?;-r~14w4tMW`Jel+vqc}@lKPJRmH&mz z>C?^ENw0DAv)0e8x&AuRH4hXW>$%%Uu2H< z$-Z+NZGB}zs=W&;vlSgv5-OD32o_YC^fie!{GY(8-9N5bGwvKan9KEi- z-ijUQ^4sr_alpdAihQBR?_!6~hyNch=q#FxjcqxKH_Nlt9HGv?epqBLGHDqwDVo_k zPZ9v+?6d7rXB8&y=qqepZF}3d`g^ z+Fk7*4D!B=JH4TEB(A3GWe#&omwstvHSZUp3MAWusISM zy!@5j(8vGVq;f1jqHm&xfW4=DHL6`nPXq z?Zqj(oxCX%om*0C)z2|MroNJgS_4QoujMzsks62OjS@K{AbtftOJ$+rwlBw7 z>&fp;pbuH|c~?6$jB;Cfb3o>9Q-)!Gu#uD0mv`&bm$fnV%{3>eZ?=itvei6&{_&h; z^s-pP8}tLqCgz$s`0|1MeaAR) z1_s2#3G=%~!x5jdk>5_Z25q@K-6;AfEbH*O=CPk0s7fVfQ~LaFc{;udtg*O>^q2qSO~Wu~7^Z1>K+{mJX$bSZow44@PZ>{IuvLCT*%@_K zedkprwRx=FJNX*mcd0{u;e@sRMt=J>y?*E|UK|S&yMrvnU(YeWgMTJ^E5GYLJy13F zVxwpudn4U8i@QQ-o7goceYTE?{y)YY0rZtK%Q)}fd=6`KN2+nx-4+ZXUSYRo3rZ9p z(#?SSW}4htf&97u1DMV>t>?}L@t+l*KW10pKhK>dXsLS^zSmg-hVRbPT9`8LE4aGo|)*;lljL1#tSEo)gen>dr41$ZpLF*-I>pt^Cj^3dfv#6Vq~PO?9;8F{1t~$Ue@E~9!W2_Da>)sQhJ+ZZc=v2T7Q-K?n2#mR&YJX%5v%t zqyEK7aM-lV+PcKKUq|_ZB($#?9G-QQqAA0?JnKd`ul;ZzuhVS8z1rF(tC+RvT=sJs~4lp;l)O&+^FY9`_x?Z-fccavUuj%|=PhBs48Akh_ z1qPQvWhBzo2K=Wqe4oHYUa_Gf7h()F{Qc^8y7{HDC)wtCq{}*6`*jn?j7ZW)N*HIJ zk$J60AF_EW{Qm-cf7En*CitM^?|kLyJA9@+YZR4nNz#A#@+aeqwu? zE!#8D%piR%wr9v8>c2}lu|K0!o3hNa)HmHcL%zW60B%!%qe0dbO0u1;rt(Z>IzrMgYi!0SR#)P!11gapRBpzF!XC9vDuC;Ki3|bK<*eFOb&ccy~?ivX^()eoeZ(11EdK zGN-f0E75}r+9-Lg_&LtJFn*wu#u>b`E^owrj{oCDqn-~$rsGFno*H;j;4cKe8=ULF zcQ|ma5IE@KJ;0In&fv}v`<*#~f4NS-*^zz;wAbwKet)i5);QpUl)r%T^uw;V=~fe$ zB6*XkBX0$F&P`$8H2%F{*~hGKoIh&sZ$vW(6QgMPfl4M#j3jMup1e*B7N;VE5-Y_!dotEFr{1L2TbqsMK9(KL zI3hBvPk2@>c1HY)Cz6!2`;C;B^Kf5M=Ml<}_~by97wi(sKB8b}n7fV>J0a)Oj0|Pt zR6JRh`383p&w*#oHu(05Z=Gf4(f;?NvC$$&A7?F=v3@1CGzA{ACOAOJku@AiTk&Cv ziYchjyr}5nV}^M&a7L#Y;^(^Z;0@?3g--1gRQi0A6rM>UpCj3i8f@GlaUFu^@{hdn z?4tbc-rjgp`i5s+1fI$8K((nMzD>u&hgHA;mul1ZKJmu&5#?5;c;hMo*GO;`f=lSW z>SJ$MZv$&I@o1rhd*+JSZ+)G-#oRTQ2W{=FjVfIv_NfqEmplG^*dFKG*PX0W+Hc#7 z{JnU7q}Geu&X|eE$cV@NzslA{O z=d|3)-b`6}Z&uMXA)Y3&Nvx&T%U+q^mvz|h&CUU)+k3M<*5eZ2Y0V=|bi#fIbBb%>c z57W&&+T>P8#ss&w_lF-Is0tA$TZ(PxoJVuv?#U`9yBJ@ic`}ZSDRqZ9h1+E6&ealT^IPFgr=NHQ#Y3X$F+~v zUt&UeMM=(E5=SL)T813p7<>NIk8UDorm@UuI~_fHoa01f=fzJK!=iy!Tp_I7BO zJ<>xBFH^ z`c@l!eG^ zIpD*@t%W!8yF$aR5ZDR0%J_Yrl1G*~9lD%!SZn&}W(nzXKbEZZOyvJ9dt#$&9PJ7u z;1C*|aD;{yAzaxQ<`Fmo) z-zs`C%s~k>7n3JCok{xhs!WzSfd8HJmZ`hcGtDDOuW<0DSl_YUCjq76rTecOr~Kt@^gYizZZ`NgF@`mFo$XmRh*dfxn$CIK^hwtF z(=^71o3N{Qj|fC1)}nd}cce@=isWvbz0584z?-{|HtL7=GdhZ=t1+?b?eqX=DmUWu zkEji-o9i6mi~xwm2e_{! zENfpDUbTlGk~E1Oa-@ajUX#9!6T&ILWUsE`2qU_PySNkYC6O^ebgda$)E+GVFU&ny zCHJ<-T`r+X+-1!A{p;NI)5tkTg0bqQd?{rXpUXYWm+%I~tm%jK-nMf*4;8wN=ULkg z(l;^&$T+_dIofZKRu^=Qn`-VZ{t@%BjK|Q2oGMvs%h_(Ian62gAl;O)OxEYpkSBiV z!fi^PIorQPo)djXD0v#+LY^;-;y!F}?n>=tE{E4b<8tIKZ;CA8t{^AfPoXzq;$HU5 zPOT*_MZHyhKJ-+dK&%}ycdj!&jGhSZn`pQAbWOC|8soCeY1DC!UwPa&H0K(lUTjiG zbR2tE3~x%HOZsHysZ*o7x!*|M7}*0&8fHXbZsz`*;JHSxrinIm6C|B!o5>p4&6gsI-{=02&rE*LYkM_%>*S-XGY<7-Zx_Aa zruAZ*(u-_$o~VU;eQGSesWoNkcRTT4l%1H<)qB0{0{$xCr6g^E&RRpZdti~4-Wb$_uy;+hT@xj4-V<6@GQ}G z3BP3SmI}|r&i`@3!KxRq+tSyZZ@4Dv^m^_NI$!yK8D<1rySK#}iqId?vxoS-_*_HX z7bSM58o4fJeQq@8hMe-1vv2;mUI0fnKzT4;Pa_5fi?WP z2QDax3}Zb{*6^c@3(Mh;@K|)H_ygM)&)B}2|HT*o=}7SvGRyY zH_@dZe?_{Sk!Jlo?#?ZFGyM|!qsUC&J5~MYqY=`N>g@MU6Z=swbRn@Hok=?q`%yV( znq_V1Oyn%GiJo(?O77|rTyn>xqtDja@0up!+6LW;xUxKPvCjj)WiNKaX7NvR%qG50 zepq};H)}1pb^h}#8@m5271La)^|o2=x@QfcS$r93hd~=ePc#qX&RBAPP4F?`(Jt5e zZPfn@bZOfh2V4B4ZE{`!ALIr2Q)R_hRLcF0@TXbZv}W6;&Bwl}yS=ncTWz<)VblIX zTaZN@9&vJNLy~RWLT+X*iGZ^AraPUYZGa_ z+l9twTxb;7Vt1FpD@B)XlcH;7e&jLgG&%Zd>-t#mNX@SVS}N^(v=eEW<3dZh3oT-! zgcjE7L| z>!|Wc1+Mr)@9ejHOsD>~VAFMdHCE@b4$NJU4JW~C8SBErN5@!WzkhO%&@x>7*G%(4 zXqI(_8eOi2c3U)On%|||%3=~AlFK_u(=y#TcXV%+t$=^r2l6sj>^Uf0I zr(2Niar~ATpKAOAzhU|KeuJ@*y;!w;Z)}F299%0rUl<#_{ThU$KH}7c_%JB zD?86uYaHdj$O!-N9Eq>UIfnJ3kg>FoHS9F@q5LhqYMX$U#vZiHk>uVj|M&XT>bPQc zKk3j=-`e#);&x-hm{p#6uxbc4Ff_)!?Jr5&$6$x)i>$-N_0Prd>wVtn)O|(Gr=)+1uPAc5 zdSTCdRt>px*U<+9{FeKL!h8kCDDFhl`IZfUu1C4!tjVeqX9K=6thcCiUPlwUAE1vo z;fMJxu`|BE$AWTBUi$d=X_K>z54{$;?}Soy0(|Nu(9tFPwrx~)_)uezNdW;H=j{xz7u$}lklt@*-TH8&wQy; z-r22(4v}vHUp?DB*rna)xwKn!L-=}3?O&bQQzr(x zz!rTJ+B>xj5_AHcbEo}%7x*b2@b86oxBUp&_iSPg<2z2y17@(7nQk@$BdokilmeRqX5F0g+ZR6fn42|mql;HKaGm4IfWQ%J$G}XscCy6_DvE_AkJk7Q6P;8W4U*bS?JWX61 z{t4W}h^MJs5b71zme#+^H@8crm(9`@%tv) zmpoKFP33}c@3=Np(}p}3c^oR9200LSX360kXr_H)Jk5vD=ER}nX(|ok$2O5?$J6}yi}-jN)i&a3-USxA(iKm0 zCUu4-y+~kL^01rfW>9q93{19UV_|8FnerH*oV`)xH(>#fZkor-ZuW(JTF} z@$od@CKg@#_2I_L{DHC(FC*K^6`}Z zwfN)ouN3{u>t)4rDgDziGpiXlTXoEgO4so*^YnOnt9xuqouOk}Qe{mFzs~4&O5|VM z5uJ<|zkwH)uEzU(-`xH?Vhw%79HtO^m`bc^ui69L9}-JVlh~NbxY(HcQ)^Xh%&qRR zF)gRi~oO#lhHOwtp~|| z_f@C(SIW4q_kV0(vM&GP(<3R|yLuD6Xs3J5DAHFL$xVE9>8R#IOWU zx8f(Bq|D+H-mB*hswM9pcAQMtIBgKWz)FjxL8C3Cyn zzfy`{SjwGs(%*i|_|wF`b$pym=3&RlB;xz$$^Mnc${k=1o#8F4|EbRW1sq;F)5hAz z-{@bWGow6pW@-VMUSvPg+OhD4uA8@9HNb8|9?4_(cGeKvzS~{~7{gpeQMP~-0 z4^29@DsL`(btX)@YYYnM zi86eSJr<|lshA$_@N(9dcL|JBiE$$C-C+IAXiSR?K$k-Foy0qh=FrDwylT?^R}=d8 z{}FfQ@l_S)!#|e*xh#s34RA>UT8aC@>c&l6idt(MFKD%v09u1f)e5+vlHk&y)+P$l zS}h4wO^#Zxmbg`G0&1hy8j<4CRukNUs09TjDBkz`%$alVoO92;1f=ipk9pXCqHJCB^Gyh(9o?XiROY^FDN=_pOR?aNY)~M5*vHb-y=wE|6 z^>XdEsJDsyP3e4Wukn5sKDI{fTWW+Jj&CV*T+0f+TfiAc7w?<+t?-67Cf?P=ggwDK zi3{`a5jmaxlK?&zIehFG%=`o&>!n?En4gdDfpa=O-px0Sn!kdN#PF=z5?>~90WSSR z#8Wf^Q=pS=&d|H@MY68~-Yd@o4{7&p`WD)~sh+v^YM!@2 z$6b(}3g3L)usj~kmU7>mT}^pN0u zZ}>}+=b@(^o_CcvJU>VC{A|thpYU|`K}6PcM`reW-$Z{)R(`vvH~6^ywZ53_ulOaW zzrXALN_Bq|bbrV2lz4~-uFeSud@SK_4kQ*gxSO+ z;J3^by8IM4&G&9R!eq+t-*ypQQeZ!? zo_Y2Po-VGfo8!?JkXNaHqOSiJUH?h-%(WlqxsiU|Ze>Kn zM3+fChc9Nt0;ft%%S!lK%-J;2x2vf?8Q53x^t|U>*=As59oVj83v0tS9#S`hy;3)} zkoYW*&iYi^5Z!I)tYP5i*IDzF|1ZZLMqWi3GiwfqR>0iB^Kf91KDEzL=}Fb+ImZO* zpZ0)0w~kELCu?x>|4E`_S=*@6x`&sQn8b zeJr@WPah(q60bD_dYJd5Hta8S&$U?-r^La0bIJ4SEPcARd$Hb>yp-wQ%i5w1p6Ru! z2QK;cuacV@I^P8DeHkx7^`wnuQV-kz8qJrhdG11eKVQ`Rm5dMY$if9K%?w#s6u=jO zOXjazHD1~moaFn$ae;g<4`_dG+V=D8xf=KH3r@&=b~=30%*SH_`kNlqpN>DDPJcnN zoQY;KZ~Dj2$pL)`k51KN(;O$N?KJar-+;D{2xuFfG+6j?1n|o^`T8(tY<9~Ny44Mo zXP*6}#Q42P?4G7$&{z=O7SqlUc>7Q4y1Hx9+wtZ%_^zF@kpb};)yxeg8QK;62WWo2 zuHjk;JUVVOX>nNTxlMY^4S@NhIZG z9od!|hwyR_;}E8z=lyXAPp64PP<*2O7JP(RPSmNZi zthL@hLd79mLvCUJ9HG{KI#K0%5Zr#;K5nJm9_&%KPmc`r;PNcE)N3EU ziAyy$h~)Kf`!VskOwrl9pRDW#jnnrXoMNJ9)IK#a{@_&W#vx=UaPqbhwpe3e2Zk-H zJ6&E6_z|04v5N%hT{LjZ@E%a2gfj;a$oN^mggs9@7D4-1Bwd%~T(9&hu$Cvgbp zBC9(Rhp;C!_3r^ilJIX3_^bFWW6STG5F6z*<_FUra^nzAqCDuE9gIVWO|RP3L;Dkj z_Q^PeB<+p79xhFGBo1NqPKZMYLxUP^PuD<4Hx8kfqD^odf+-t!ke`_`nkvsaugB>g z+1TzlgqV&)h)Ep6N8d}vA25YfU2)#~q17VE$@%;}96H?GlHO2Rv?GkH^sa zW*-uVP{B76hww1(+&F|8o|mR;Hos%iEbRi4=8uz5KiL%?;3|N z8@jl02=n-VTX6{2_~>ZHA?)je*^NUeq}+`|*pvTFKDcoR`IMXT=f)xI=4;bk3-+hn znLE?RA%uKwx^W0!BdaED-8h6zluI1KhcBd!Lx@eUALP-ItDpD8AtZEUgX~!ubCSd% zn0iO@KnLm_9fvR)z2vtIGQ=Uotk4M_zkj`sLlFBT94hwY^(g$NZ&Tr+lE1^r>!JCf z_P^8R#`_br>1jN|QtIk>1nwyJ!sW&zD7dPR?s5K(+h}tq#3T6i{Ce>p&to0)7W~K% zkC67em-$Zkd{94GkEO;IT!k#9%i-}8a0>dS2ew{pddqGeIXoUYEK0^BByxB(U{@IN z2#FjXQ-0I_?RMNhqqfqE{}p#un~jZD?F7`B8h@W_-d)vN!g~5q0ED-R*#@uDtT(egkfa zgbG*BVoq`W+Yx+{Vs}+)|Mr*YwYHt;-#%m?^ivbkrhdq&p#HS zEQNpg6lRi>!=!^7)AD2Z=f<>ro^8am)FxwEs@PMFa`&0&w6)ZkRfg~6QOAeb=-4u9 zj%m~Xw=w?AzC8ScA3^@cBFY2#$9+j=Tf)D$ef+cVHSf&vHzouBmczf}HUI7=KWgy! zJ2@r3Byudgnv6blY)vP3kCdI|Evup|g?~TfJgqNxi<`Tr6IfjS%`^CC-H^=PBY9Pp z;p-CqT_yZ0hky4A|4!~vdrGv}u@X5dacI-&b|52}*7@Bl37?<*XM`AFh@tqliu`jh+{c}caqz{l=s=_()=4!V=&|%Ly4s!1|udh7!&xms5~_WV;(sB{kRU!`SwwK z)2P=Ljf}w}<|Tg&Mk)Mw3Hp0rLO-m&J{6|=L%c8zqy5MaQ(-zM157fPnJ|@(N50|n zZj|Sax0+MvgRHNfmkLW2u{$PxzM{|ilT%?iG6O7M@Xmy#b%F!Sr<5<4U^Vv^xg>9% zuA^j9;znjK*siz{JywWKIng^N#0Pu`eQd;ruhF`)20lsr%VgwdJK|pweMEe*fYOJ= z{EhPW!I=M2^>K3A_!krJ8eyNlDyAl(BmaNI)YO89jH5pEEj-UsPtI%etbjM; zkZFIcN<%CjJzUCtHeWU62U4Cg@1Uz@#++D{O86JPakS%~4vkSh!!kGDijJu{fi{#3 z7(U5g0%s8K#Rv9F=q>At>A*Ws;PTlw#ZShgeWl!Ijp!g%vMN#_Uw{KjVMp zyG4!+NBcN3T&|wE_K$d~n4L1Oo>VbA$9wg&*fbKe^W?`pkJ)*cIa%<&1iZB#Rxv$p z%+3tTSC0}KBj3IXI*X0brsq|$ZQc2H3iTFZ7pIHaIfM7x6SL#An`fWIcLc+DVs|2^ zC1ZEq6FrIU4T=*wl5gGk&~JfVY?FFoQBAv3@_8Ogy+O2-;Ljfo{_wx>=L*fAPkKB2 z`B*)3?Jk~Tzl|nOpgCsMp2tJEw3YdY07VaNt>dh*Z948p=AVkeR`Z>DE(+?qlQvu$->Yd{RO+R1Df@(P z@Xn1dnhMP&-qWRb!+lA5hwgXiy@#fEt)};Fn%=kablZu@{$nI_%-oao`_Hy-7rjG& z{#dTi!|~`W{O$ho&PU_X1p(#NkHw>pQ0~A@Y!`T}Wh|JnUxO2P?f82)_DkB=@{oxA zlJ=eVoL?Z%rzvw1J9domp8e63_wYi+j;$yZeUopGQ*VH`Tf+KU+c!C`RDwJ0<)Q?1Y2Mhefj77G8KoEW6$DF0g8oe_9CUvkbDOpU)1&g##8Ry3#uR?zmBnzon96MfNV zJLxthpx;{q`V~1CgNy{yENSz5crr1d?O6eBqk~l3+bnQW;~!k)9^k;flJ>f%uY&^m zIx9n8XKDHk&(v4a=Jxb8IH0cy8Ty)_Wb{`LtTmady~2owcV2Ua=iH*bp7j;jSPzUdo~{J&d{##epgMe)%!VP zf0aCuw+nUbnJeQn7^@{GB-Vf)x;=+}L|=Nw=!U&g$EYh08^}@rK5$EHo2UKm#G1|1 z{(}MSzm=i=w`l+Ep!Oe1thGGtlXxx#{?-ibf59D{CcbLlqh?IqK=_kVe)Kpu<}g7Y zRe$~Xx<>jCTJMhB1nEwp*Nh-M((qwg03N@|fX8p3lgR5C!gF-aBrOA{D;dbM*M+`a zv=Ce+=CLPyDhufUlC=G^7L)$zcdYJrwCXq4euaK-4(c}z|Mm&!_s1Ff{jv1Rd^A+| z_Xz#XrN4EI_3e#$TuO}M^p4#<{@ZoWq{cixN)8hDJ|p^2_r{1$^p_FGSL=^?T*|En zLAexE-&T&N?|bRn&ArsbJX^AhC+1PLEi&iEBbvFF=F<;$Ld@FpC>8TK;h*G3r466{ zs&#WO#d+`G;JwStkHh7(yDdMs!lfwJgUdW{abq4$T&l6DbPW=OL zD#hk-V;)~h;N)#Xucb4_JSrR_c^(`}MHY12rinu+xh_Z-^O)enf5@jB$Oj$scn>i5 zFy?WGaxY~;Q@_t8l7xSoF^_{8SEilq#yk$BT=b7WPI5fB4rpDOp#n|mZ<9%KPK zJ%(2(cjnIYF^|vr+H_+c|LSYgjd^^6a*26tdOA4fQR&F40*{XT-CvS1kLbvD*IsA{ zj(MzgZG&-)Bj%)bZ5!0e9sznM=H6wtnfHF%AYII(v}5)2#uj!k7FAw5bWgarIAhGC zdzYE!i}K;7i+#KV8uc{x@m%Uk?4yDYJ1Qs_6YtiCOONSs?Bi*)`CVfl{d8CQkiD5Q z)^m43_jIw3nZCP~?_|FD>|1%J#y%d2Or?u`90pE7-}J!dYoA^}#3PS=kjEk&`>5nG zAQzJ=*Y}rA#SRg;X9UMS)|$DPBI1uG_HjNrj5E>Vq=f8xZNN;ij}zsLt}pgcaxr~z zzAx^P*aEqytmOjk$hg>>i)q}TWG*KB5h@o`=S5ajwXNgUtfHM8_q2IvcmeZ#yIy~) zajfKN;L&wU_NXfF3oRsW?Psqc7eTq0ZcB}OvP!L#JInBuq}*8+p)AEuiZ6a9eif}t zow!4ti)ksaxN%R%Bd6}2Wko+X;?{^6S%#0w{9a^p9Q9}6!)>06pTGQ+9>qY_2v6NP zoESSZen#w8@o`E#-izpc@r}GF`}g=7O|%y@x|_}yiC>bwv#?R^0Sk3c~xeRpJ~X?Y{r_%&p*fs94tSnagRmBMOBGU+TxG< z(ZUvXm6Y}OmQ_%eB0pv1W%BXgja$tzo;X^He)6KN2zgB5%S|m+*FIs?b9@j z7_QN&aZ{hbyL547_wr4nwr7;Rxj^)6p1qjzQN%`7h#u2-Z${45eroPm5Pt&sJ(~Xo zta2Z~##6ksoV7PJB%VySt>)@021mND0FN%GKb4o~%UvVgVA%9IJt7ncJ=!Wa?gWfiw&_app7@ECw!K;f;Eic_wbk9 z)W=#NcN^DeI@Hi_#fXHjaf8sMp5JZyeH*{IXE$oXS+oy&d;s?<@~nU!#8SF`d9|02 zo9oSI9=4J)Uy2QO9I&Ok+u>;5h1o-z`EB2(RTo&zKj`g~k22!FCZ@_q6}j0=`6#9x zi(D!G+)w9bkdM9ircvW9bSNU9S?<+IxhN)n_{YdVO5P`Q@R#Qh_cr;I9>t_3buf1Y z%G^hvuC5ioF8e6C#AbTN>ukp9o#gtuV)9Ab-A9$g75n;7IW3UuU50~XV<6$553|=T_I*xA5sq^(2mjJb||% zSAP9ojIW|b%6&RMMEN|*Q}jH#Z{uGR@l>_phmMvwHSSI0{u$=HSpj{7h<~~yppVX1 z;?WsFeK3Ajy^_*LZOJ3Y)(z}Iyj5s*Jo*s(_cEtvjLZ5U9zB3{oABZLz_Iazc=J}; z7kzXbzs+&h@NdamPW%JqZF>BP-kGY(^X;*ecj@vj%8ONbfqfX|qK7)U%P-LO#ok*! ztg8HG=IN{9k;_|&$8+N}s`($8Uik~n+xNb9c-yI-x%Rs}_c6XLHF7pJ@V|UJMSr_W zf4fqD+s;#Blv83Y<|J=^A}42>|Gk@^ zXn%!MzP(uCQefYso_Y4~dAjpt=L_-ZSl|^J?5*qHq3hS_`oA&iOUzH?FddJg=hYTp z%!$koe?eb}55*sMQo$In)N)XX9LS!VJz(a}sh%qHdgl0qCG=so)yjEd(JOaT zuG?%k+pOaKm+%rfQ+Fs%L{EmtA6_0KH2b_WpwAU)`jqoS5;Jny z6C(3N?Abg`nmD#Zj(vvPrj8wHqCKI5?2`oH@+a{4BW=t2%l}^1UmuBoIN+Vw*5B|> z+BWe;2NFAD)k&@||2stso%_d6i_=}WjX2(_09vd;M=aKKmKX?w&g)BxoqSUMwvP^I zdq$eJd!auB?tFjS$@mZt5BCjdyF5+X?=cURYq>c%m_F-8x3A^SMn4V%0{R&j(2vad z5+^c_ejb5Nrc5h)fqNVG=esULM~Ccq^i;=BA1Eh6^L=PfblE3`j=X;?PsYK#Eh3M( z_U|=M3VKMlH_$;QY-0QM4!}qH7F)Qtrdu9#Grv$M#mXb@jdE8`=g= z|0Tb-;Pkl0safN6s>bOQ^&~b{J@f6iu=Uc(wA^=F_c(Tr#71a+S-(2o{3JS8;tX6l zRpX<99CiUbzCC~@&w`hKT)I4d7WhR6{Yt}sBhMSb+3b%ox4vXkuuRPk=x=F;{+8z)JNCZDE?&*Xhe#UhyHihtuK)ZIwGB2S-nZ&k4fK{)@D zHYFCIC$yXpfZIiBam%wW(zuP%xE(G}s}9Uxc2sb>;sOPQMtLs8S~194pYzF+pxsG#ztgcGgd;5`Nw$59m~a(4`944r_Z4G zRm}e{PUhZe>Xr%&oP`Lo5gz6HndFf)`xn}F^>gmu)8!j#uoEh1v)QsnpHIJ1XDQz< z9GJYPyMkQea&LMb_j;PSjN5=?LMXhhn6uc+SmT?0HELbgNc+w_nP>l+c4rS`|Kecp z8ei55azEJH@XQ~BUy+kohbUO<`MoK}xr4MK8@Sj5m_!a^-Ji1K#8xh5Y#ja9^zrEz z0LwCXC-`2i`!#9ez|7sZ)SE?K&x*2OI-e=;%eFs0{bat2-o*W(I=A&M{O%xz-{LMs zQ%=O*o4`9cClU4CvnV`SNG?$??#_Nj)6L(i^V%jKI%vzpu?Sg{+@{Dme9yD@r62RX zdrqQ|^8DSLa}tLH@W`Q6zMV(Ce{#1#1?#jRnG_snm2W?-;`BM{q9m=B^IK?DF(8#z z8+qrB)hcpxhPmIflKWj}GFGGHvkjO_)|d1-w(bl?gM9mazBg&mz}@L0Bkxc?>y!8x z`98?5E5kM$$DI-*r5)ynApBnuxUt)V-o3!Pio=upYwXvI9VzjB%xjf;ELA4P5_cR^ zfA!PfE|Qq}bTA!{?XB*b2R6BD{%61^u)VpLV^6G>C;I;vo0GB3tQ9(Ixbi zt`D(SxBPwUqK}<;QjcA#boNQX^WZYtH0LC-MLKg*=iTA7FSb=DeY~do2%^8(#&1$b z@^%LDIE^iNdjK5I2EZYBzN6dr*}&~3rv}>=a{}6KOw%^wJjl*T+xEEuZPx{~T?X8- z40Ka6f`3fveSi-5Co~ipIZeyRsai%p_)2WfJbP9!4c3?ZI+)K#2EciK8aUsh{quGI zhv@zf(*0jdtlswUb&bAt#7<_z8{b7!~1V8d8%p4`62FQ>BYS) zS=`IQoh)0}=~iQJU-r_ut3~E_^hC6i@%bun%e;ubZhn)sl9aU#CRXJt@f}*^ zWmk5E+FMqA*RfBwG^UU%fQ+wlbck}OQ!++;oC-aBIzphc=J9S6U#{0B!SwMYfp2)Lr z;oa*q6Z^MnUU%N*+Bfj7QufXsDjOeuDmzAm=c0nGOWz%qotCpnvOHs?|1 z91`h%n*XEdx&`Hj)m7p{7&haI%@g;FG)ca~iR}50yySStPPx{KPQpI`%{+7FM7@TQ zx(*z}>}kL;8v0hjdvQfU2hDt_J}1DJP!{j1?t zU14^3-6`BpjD46}L0@9)+z0>6ejC1tN7o={LArhdZNtmj@Oj5|cRgn<3pJH?PrwgT z@q!g?0pBW%Tsl^09nWZ(KKigWKz6tnKHpxGUDkBtJt1|^cEu|41mKUTao|@rsmyH` zgO~7DmwWh8MBk^sfIr*d!-dlwKI{pv<=%%UfKB-E#UQI&&SOuRZf*FwVDYe#+%rBO zUW$zvIn!%e`ud~I@sSRCrVs|yU1SD>H z`Q`CNkuC92;XSRvh5hhtEdn-uuZi?8_z0h?AEz9>v&Y5X@0NA`I^?|Q32T|qsWWR2 z`(OO7dUEqvp?N3z<-GxAO-<18Yabnp1`z{cjLQms&xM{6yY&z9G6`}+FnF?nhNXO-jCo*+uj%I7*x6(&n68OVL=3>Dy#XJKtM# zQpfafX=68meXupAA9R*=q2O=P{(N8)-`IR$D^X)2ysn<{kpqoPoN8qJ0;9k#`aPZ8 z?gL)Ker+u~inb=6rgZ2A(TmdN++KUE`(jX}yPETil2ci58A5%xyp?l|CVa9V9R#06 z`BLB$Si*d7^0{-p(07>KOWK9s4Ijp%$yYlySo5jS#^rlT49d|Nw#m(FoRI2CHmP%**b?CXG2zVzV4=!G9#1e&` z*JE{_Q#X?3%qykn_B!??_XW<5zSbxir$XDC8KWobc}!?qdc8vffqTN@km8f6V_bTc zLQk1P8iq380`DN&ErRaPB9l{@GfW*8;a*2`yt{KnCwf}+*_Phc*t4@Dx4ZL&)c-wq zOij7o+7N>0E`D9V1;1ZA_;sLP#lGm^Td^;AMh}7(ro421MxF>Cehs1n`R?jMd|6sX zO8*;=Ucvlo!l>#n*C;&#KjobXV~9CP_#59nyx?ElF(vi#s3$O2ZHY(aE|Hh8+Zl^v zJoJ0U`ECQ>$$31}4iWh?e}~XzCQQ=b`>$FlJgFGS*kMm>Vxcqth0t}_FsVBBux;zu zmx1d@a$*IImu!rZg14XwQOhuEbR9Az zJi40tPf^d+88W^<+27F_tcyHjqlJ0WDh13;YbsBPGext_Fw~nk{ z{D{{ksOJ7FfoYP^xzVX}A$9fuCXcK&#udG*$&HmlCuHA+Au;}GPxgz%PPzkKEpb~x zv>QvkQR6m`T}&+7HCYRW9RTby2OK6eY8M(gI#Tp%!*FXs(N{@3uH`1Lj{Lo*VF){G zEb@K9AndgdfIi85%2u6 z)cUD2*JlIg-Ji<%-oxIDdLmn$YlzQCvmW{yS`>jxW7b*X+xDEjmpj&3k8>wX^4!bj zDP^qPOPjvAa+#{TsMdYFVhnrgLN=$Nnqj zuB=O(!lg?>Y1eFjrY?5NWu5TQfHS7?i79-Vs>%lf+kc?3Yty$}?TsIB`(8|YdMv25 zMzOYm{~-FDSa?k@Py1!iYa{vRS7fNO4}LPCRj&txR>SN%)-37TQ*>=VNby1H9sukQ z(zej_SZFGHQ%CcJr?uf@9G>Fmsx7`@Ox?@7D%&V6oG$_A?=!%;{JyI4HhisW|4Z|+ zSoN7}7pmtl`x45{zKg-F_{;lL!rcefm52|qWK`W+e3rxA z{0K)lciNo?KU80?-=6Z@=?DLvmj|>z4p~h{Q$>IF{-!-xRel(>7yORV_^tiik@b(% zbC^9g4Sq8-;Mc3Ms{C^BJAOOyJ179ZvjXsw_Qk({7JUfpyK2~<(y%|FVGmP2A_IS2 zI+Q`LH#MKXe%KkW_v^Oqz;ify^dimUQ#6mi+Te`iO+16-_l68SUVeX7`Ss8(8bCLtpF+X< z>6iezT@XMwXcoAhx=6Ivv|m$x)U6eqxn|uh7)+Y{^aPA1sa~)eek$*MR5jrM8=9}bA#BW zY3AH{)G45j>|-=$pp~NOmAmP=G{-)ZZ~m2`U6%**?yV}XrCp1Cy+3Q5rf8hbNrTfT z1JmmeX>T2Q@1NFvn>s|v*S&`Yj>~(|g?|0Gl79SrkoHBs-pVlM)*x4lGtg=Y?-%i2 z_&8hRJY3^klm_RAGvM3{yX#NjJU0O6lO&F>H5`a@WdP0#18|o11?Rgn;Oz2q4dd^K z47khtGc&wb?O;EM-1Vnkkbb!+11*MQBVPzDj@Go0Tx1^mCyjpDH-Hx90kn|z#h+D9 zA0slzx7g|@QAgx@>qF$+$xzp&T^ai3l^)P|2|8j$hI;aTfBF{rdWXKnp1pa!qqA#x zzE4h`bmLvV-9vx-s{VG4{`M;Uyh1&P*=sViGmmz5%K+nW=Fim`-Y+uZmuCc4iAI;E4FW|K^yidTwSh>6>^?gXBFn zAicg@PJa)BTb0I5;s`wQK7MrI*q_0?;MaF|(vM%?N&DhMzpw{5Ee9uANA1;vy0Shi z$xu(;XR>QtdOLmQ+D}6Rk@w-qY-xse-S4i^4hf@MrYu48Ssn(mOdF^mpTV1T5vZmeXJ$M!OZ!ie6n)ZocO?g z#0SW}Uj_S@dVio!_6Kg}{mGn*o+7>t_Gf3Z@48X%XUY2r^%t<8wU|BQ4t%oa9eZXw z^4(0ezm;n@Kj@8f52^jF9Qz)0>?*zI{%7i-FU!sL&{OSMCwyP>4#uoY3+fb|{yw1& z9<|@VJhA+8;Zcr#G&sv1i23dI=3u&>IHl<=Lp|rnZ+?LN@sKrYN%nP3?++?#5+2sB z?^zC}V$MkTb1+q}_wu8QxD4Tm>bql@r|;wG8{h6IiCvfv9ZK?&IhfqG1)iWBOy|>& z8q48cDhJa$%h_KPTB08)ua$ipWh3f)C;zZQ&sB50Ihfpj+&+FxyW2XCuW+&U^x#qq zF7*MpRI@iKIhfpjOnk;DI(yH~n>aNE;}mmqFwIEdMCmx zP%ip+XXIc~w2$oVp?#y!Uguyk$Aaw5b`g)Vmi38Clfsa-VWCxXSEIA%sp5AhP`1FD ze^-qzs{wXL*77)`%ee>WBI8hhv!Rjq70Eq*wMSXcZ-=+ZePA~So8W$d=x)8wD(yGu zJ^XVOZGv+!nX<8oJhA~}G*+y0Ff}7PN!dt+A-*E?+U6-)#FF(UmW(*EIenY9ULUFx zy!fzPaxhi$lpIVa^-tzt8ig$NJzRK{p&qUyYh3B4^H?c%J<>aGA6X%E9E)A#5de*#G+8$z{N0^3ct}^e4*Q983@J z|98#7^kx_x!dxKnW$*L<0oY8keiHghyp40lGG|>i|Kpom`3`kVI!YYRpV$`_f6A|X zFqiU9#%?v`ZVsmF_}~2A$$yk*UrD*ihtjVcU)(Q!ZMwdUizrv?ygBJ}FirQh*{a(- z$JeF<1LyxJmmEwJ(R-%-=CKzl3OzbSceK6(UDCF>L4>Yj(J|^Cg z@2EJLkLggWJ3P+nF1)5+Q{nOQ9MDu4wYs~UaiVfLSi1$sxetU^R}8kg+jL#gI~Bwv z;*U!?_Yk7)Y{|u>>&p16;QUBX-7guZvxa%kyHwzd4ywD3x-<8tuHcNF=Fjm|FS!K- z=g_e|&hfOGHdT%%BZj}Ck2Q9#FP^xHxC@c_t#gipA7${Rl$he@lwVTdF>St5@n7ll zuf^~+nd52uz8%cBB2zOzan>_IeLssl`eALwA1U802DfxDXUf~Sb~OVIsGb#Elk7 zZYlPr<-4%^JGvjg^X%T9-&yur@-=7TZxiF%8MmqZrp-aMBK(?~pWRqXsZ- zfBwF;YzE^7KfRjEuG}B|$w3t%#`K9(t+AUJ|6l3xe! zyTgC~QN5ILUQffNatXCi))92y<=%-nbQS08-nS?B1W0VX$o+lml6iwFPI6>Y@&;ME zv9``7K7~5>P-hlnf7Th~=~#JUk8%Z>wo1|Wf@~FJdf(vu92Jz;XuVj2UX)x@`>_Y> z+K2D<%3Wu1N5%}^&Ct1~9zx#R;HNj&RPMTu;V1FUil5eY@bkmI#8=VhM(%H&58qWB zDtwo_?`Cs<&x^n(WiJB5V&tYJpByx&XEoIiX54W1T@~*B4dto>$jknL~a+tub#@S(v=^xN0fj+Z(YTn!SZWSZpwk1U#6aXM4GN@ z+=={(pQbnb^^fO<&Uo}&WWqnDt0~`1dC<6?$yq;rCc8G=nk6|QYD-S-?e4ES`2>)= z>SL?Qcc)K9H#eSw@?)V{5WQsmc`P&&UEO!LZx=m+-6vzp%=O}z-Rh6y(I0DD_wT^l z{BgW_e{dBZxAEJQuVNJwm1{4jJdgZLvSwKcEE4;r`K{Kw?mFZN>a8MoS-Sf#W4xbv zFt&~nt3UFxWQ?M~YWDB6n`L8}I#0 zlN?#grjK;;BX|v@AK`ZpO&gf2Wo*P(go&j*p0&zxtX0Zbt4JK>^X_^jP=3Xhdli@i z=N#UBMvitlQ}h`4O?Bcc+;hW8TI!rNep=q=;%MmV*L$b(O~#PuYVDJZ=`*|AoC|IX zX#Xz(?aSOL`DBE?J~<%w$KHYS%oPD`|1qd-V80IfN!upeO2*RAr6Qp1U#DqXe1yM- z2O`gt;KAqcU;;8V5uZ#Y`fTQV@#Z4ke~^9>{*DIsl=-zTczzup0Nc-lVAFYYBo@US zFUnq7)w}K|d?R{bd6$!~#6MPrCue|HkUZC~jYrpK7!M*Z6Zuxo`s%zRNm)sQS5^RC zho;3V&puS-9+}*{i<9T17Caijwd3C4yL=>f-No=`2Yh3(>Gj2)HTH@>vc~rL#xD4# z$G)+4zi;ep{F-U@x??z2RpJ+tLKh(S#yRY9$x## zKI45-Hd6Pyw&5GA)xNP>@r}*P^7zJLJ@JhlsA**4xP!j2nBg0X72_L=^-B82e(a;8 z_Kn5FH+C}bT;Evlr&4@lwIO_Cr+}O38?*Us`o`|zx8FB5i~ckC#$r3uH#UR58nvA+ z>o9jsn&ZPejc-iR!PH^@Yv0(X(90b2u5auk%3a^s`~3f1ePg>r7uPqo7yoa|H&)=I zqv;!K@xko+#-5_w^^HBw|0W+?-`FFRn=8>B{rQDf2)BDEm_OH5ZMDHq>ZHF_`2{8T$VvY$ssUbe*J8>@Bgg@yp%n5lPmV;o@{r0N~*8*Asi-!|~i zM;oyf)Sd|KSVO(Op$dIJiP#_EsfIsnBtEcj`Zg6F>fQ5B=L3^*-P8L>BGjFU4@~f~ zu$%n8D*Q>y6g;gx_f;K0o61*(Pk`}vyX185Jv6c<#Quu^zK@IrKg$kzyD)4hWvoiAt@b#}lPl$e`$qAy6w3 zt)XCFP=s=!eVef->C9L8b~o?L`K@9n`hp5y`tH7@&&0_`%u_9Tf5LX zXVZ&$OXUaGzM$J^gT1F%A}2ZJe~D+yzOY9}3B6>0@h|8nu_>Tb&ybT;&qz2)}z zWS-Br|Dm3__TPCLzM$H)z94cBBz!@AQhY(R+80#Y6JJmlxKv`#nZBT1Gtl_oyjykH z_W6Qd<(qZ)CwxIM$-^YRppe*1_<}}2k3f5hxo`<{;c#S3`+`z!C+h5jO`&oQ$h-+% z&y_h7J8E0Lpzd!SKKw%S;Udk43wZ9RFX(;MX1@Is)mDLhhI;1NlX&ikFQ`iR6W|NF znsU9*TN~sHf~V{Cd9wEK#o2ZJptXAs0b{=19P@Rw#h6dr)h+P|e+3W5d`!pQw--a_ zY0y`EL4PH`o{agM!j3OU`Vt=i`lUULeo=jCUy#4A*#UhmP1_f_m~~$l(wFem^#%Q) zUU)pj{xMIJKJHrXaJL`r3%Y?m1WvstlY-ZL`Z0V#9-8*V7nH7TvE>Y3kf&dHcOm_X zFX#yH6JJmuEw#_XPsOnY z+IM|He%O`2M*D*Nuy16{`(>^;plzX%_=5a!D;Y~em;VH`-9Js+;tT4pWo%`(;|qFv zajGv!`VW#Ff$zuK7v##nqUl?S`PD3rdVl)(Gvzd-kha%{MY0 zCag*Lf;_S%->)KPUXYFuU(m(CA%32oz&t+y=Eu^)oM%f8Nm(mg2R-GP4~#Z`o^&)6 z`E25wFnm4-+K-gH&%U^V9rXoGCq8m|Rf%VP8~MX`@&(oQ)EA`suHWC&_m+E-zMvV% zRLQ;`Uyy2B_?pfar0lSY{>m4$fP82HG_7^-s*gfb|9+451$l7ji7!au(sFa{`hq^^eR97)qc2F^%Ra@D^FQ-E=YQr>c87KSU3#w5=QDCS50qnnS6|Ti z=tgr6b$vloDHl7{zYmou<~be@H3h{zE81HJduabNp}jsQ<)OXzoRp%;|CKMO2pZIA z`>TdMe%BW?OwlH-FR0zpWAp*?^ZCc9l4tD;y3ivV+vf|q0{tPrpou)i7Zm>{Tlqd( z*b^lVwnul>??hivt>Ft&chw&RJP$KB${g?y<_nXK+83nmX#X4UTwhT2pS`{yg&V%0 zHrg_MLHqHI=?fahZ@(|-^RFFxbZP!|!M_N3Bk$~oFMcQARsSJ{q?D~R6`r35Y55p;U=FarKprO7tU0+a+uT9q%vS zd_lG0>K*q5$++&RFX$QSiZ4jPgWZ(I7X&;LdVFrFkv6}pF9>+r_1d6Tua{%)die|Z zkj@vB>AMg3PVB(%zw6l2{yF##WGJ04=yGrpo$LQ*TfQLVuYG#tP>=lm4EZb4z98hU zJ;)cN%6sMuN}L~(T;=r_>Rb?ZWm1N!2GsT1i+nNQFTS9s9zhoVk9|RLU~zpx_3v!k7qo~v+v^LOXq;i* zS-zlL+LYLsAYah^%sD&L7u3<6y+gjBDt&kP)xZ;UF6bHLB%Lp4Hs6@@+s^a_-M!-f zuP-Rc|DERxQsZ}$vG0s8=tlUYeL>za$KJ_}=%gL-1^w$kDp$^WH_m8h`GUTM_d&j( z%~BrV3;LY$ZTNy>;gbeBX9QjwsN%KRql=mQ!UK>gMK@!AaU3*D(NWqLG!B}Hp0={K z-xu@(@S47$<@`3~+4TiIO}Tq6==?jX9FQ^`R1lmQ+g~OQ(7c&QnUngCi-q;lC&Nu3cFQ`-I zOzfy_`GRI^KCJtK8g1$25vw9_b zLG9WXr1XpGE9ndJ^z{XB`}-V;4?%4MyY>Zn;8rr0 zhAw9XwEe3zZHq7HSMWe&>@;{F=Yqx~QxkpXg3`&3*y@HaC`r@2T>|IVBLZNn2!c(| zui^_b#|wMRvEnm#sXLu-M8`e-uY@niD_ea3WAF;n5#kH_nDL-}LED76Zvf0kq=h-p zK0;)gwdmKD;|sb27_~1baEyq2evfa&7xeaTce*bqHof97&-(V6MLX^b3i-~|h;Jp` zxggfovFTNZd-}eDzAN-O6xPtOl7o`IAh+#p_=0M!+Fg||Xm@fxBbPDRhhSa3UY|K= zcYQ&x@m}QGe=f-F$MrY$&=f8FWv1tsLiJQw8BSAof1m|9_qfVvcHeeL>3C#knARQ_>f7ijR)s z3$pk|&IKLMJJ%QVEjd;&_tH6ju9%z)Isx2FU(g@M z@b1K%dDH2uF~AqJix2N0Uyw@&Q-}SpeL){VFLTVh=Yl#ZcYQ(c@c(!91r2~Mt}m#7 z|F`7}+TBM-(--uV4`$aFw2X4s7xW1Kn|yG6K@U)Fj$_vsbg!>Xcm1%Ka%b*L?+d!q z*QV(JN?Ns9XO9_U(idu z_uB>;d_gg*#Or%;eL-RuhZ}a>7bN4lr@o*gsjGcKF$=pX$QJ}W`lA2yrRKx2i27oR+Ya4jk?~m>c)_#y5ss4M|Vh`xc!Vg zakov}+!6BTDU$qeRg$O4QfKB>PPh&!lRFfRGK;%GQ}&I^BHg3NPh`R=F~TBObKr;T z584y?bk7D=-ASG}@+C>0xCnXTR_Q!(InZ~IoG+TzKk`Tn<<|L5(aiepr(KET1DJ5SVa^@^p_O{}TIg#Im_w`(U zMR!knL-~agXM{RV50>L9%7f&%i1HeTp9wi$2>e&V1OK?5%2}XaO1W=rmr{Na<$>c{ z=Zg!ocM!g6Hz$Vw)4^)rYRw>hMhKlF`QmP*4MjJ1uaWXcp;-{UWUujYWM9UUnIq0G zw+-ZoE5{xZU&wK^Kk5XlS@~5?@anP7y=z(kq4YSw327H;(nx+~V}o(|kZ)!mOYTbO_HJM9%9vzDAM0z4%|D3TdeE)o?Cqo5 zN}0oGD=uyQ)QXNJ7jQ>bfnCa8>J!)zo6%cOP!^7t-ti(dc{8;6amj7_GG~dEY-zuc zAYbTR8!b2s%+>WiLu<_@u= z^6lk31vj8`=x?|l20{Px4spw65Z*gpZ!E5DX|YxC_(s3-6h@$O%m&eJI~ z@o4x)VhjuHQ}|B$Z3GARj`Wr@iOaOCvG4W@t+SAU`*a(Fv27(kxAZZY_6l;XG3SB* zjf{_`qDYgBk0!>4$hy!~@E2N34n)EK6Y!V+TjyKR#~JIUd^B3lSa0Nehj)GKeSobC zd6Ye-i?Iv3;7LAb)!MXNwLxnWC+E8YJD=~qoWVSrj^79S_{|;7Z_xG|1FW%|;kRyo zgS2mP2lSZ(t>*ZV@SFch zx)%6>_0B3E{NVJ)y!7yoAD9Zi$c5Qwgx}ra$R-D+aX z3sl_#`!BbnhkUdzRd@T63zzysHi~Q)*iTSTc+v7jT;Vc#Vk$0+PEL#$n!<$7#_a|YL)pmPh4ih6CtS@3xlW4cj~l}2P))(E06Z+R-dNcP|K zyAA3cd!P9(StazDgA4U0?qr~ncUIIBy7ZY_D^)`)X z{wfQe^GbL>tBjl_MlMw+H*B75g(j>{7h59p(K2#(x_LcY@x%WN8paF37hC9UVCpDj zULhBD*z(#F1NqkdZYtw1hwo(XMe>z~?s9XB=B}H{|BU06KUy#A_dNUgRnDBXLOpZs zR-SG<5$I_BICDPM&w#1_@4j7xu1xgT`e3rZ;)k66M(O^Vbbt5j{_f>@7vIYMMVsbX z8$9d0J06ug`b1W=@5y5`6OZAX&Bd?x0sOkQY3riDC15C6*RaHefqbe<9T;*H4Ec7A z>btxI8+e*HS4>FeQWaaV1)lin9Ru%54R0mzmhQs(7JJ;L{Cwcp7Tmq|7Pt%S z(}4STJ*YpN`Y)g(1INzL!F98B8xoJ9#?=Rd#MZ8L<1zfUw!rDPwcq$}s;xZ@`pQ|L zH@Hhc@9Q@KeLbC~uPAMcy>LOD$mJ0G5}qcVop~|G{*l|J zj=fkyd+BH{INT5XB4cv5J+T)tGoGb*vhXg~j%Q`Q-#!56^(76#YngHvK4UF2Hvs45 zz*Z1U&-Eou!EGNE&~{}&+e;Mha_vgZyF=lf$Y|T^TNgbOEK9W|I^Mz0!@UFgJSCt{ zk?Z$@+fGZX?0~jMrE42LjnepxWDbAe-dFdVUxQ@KBb```UIet>@PkBPwnaL8D+ zb=z7u#S(sT*7NhA`%>OdWS=wZt>Xd81>T_|s0>Ek5(Wx(_~c;_ZU^7TAx`u*n?U#W&&Z1MAlE zEGcpBorW&$Dqd5s%NILzNt_k#r2Oyn!MfZ7x3n$m^1o}?7if47)bL&dyoDL)B6v?S zU_+0!%btOPEh(2C*sctK?cN~RXxqfwZCmNcq&#@qo*K~hZE4#64Yox(eh;T_7jJF% zD7;jBQF1TD(|1`w-95$&whpHa^y_p=TQBwjWSbi*q>@I z9=Lnm8ML1c2a)NAX-D4saEQ6_SAMzKJphMe18|VGSJSqFN$X3sXSSfY?r`dxc0uWs zc=W3++a6mYiz79>>BhlRyno|2$v7-E*SEx*`)?IdC6_sRqxmaGSKLQzm*kUn`%*G@SdOdzJTiB0Kwm2Z`f_FN zb@=cr=r=OpT>aFCf;hvr)iG+9aA z&u(+>&{F$_(Rj082f1)JZzoP`8KeGjn;(GF8eslYK--z-j+Fsz$3ICOx6-!g?>M>2 zW!(PlOK03pf&VhcpTn~}1HI(?8s7hg{xbS1uMfZW1#yJ3_Eb2#KFjNeZJrXgF58kd zZ`e=J?IYRaa_>YgVjWrItZ|fY;AGyPj1N}!{Tjwv(S__YHS0T(YghwW)IWndT|ejS zcrUB@BILmQUe#B3A?Mk@gs1wQTBDchdqU3w54VjP?#Xla@ghgiANzREvX3WmbKj$F zncs?7AISP&{y&#C^V#PV9OkoMruORC!!cnnai~7b!67f(*}D`RDr9dC_#3n7yN)(w zuYXLkZ`muFrTY#UeV;(zU+yCJo#omSt`99}At!uzPit^tKkKq$)`ouFQY=29k$H7X zo~j)+$uHxpwZgp#>d%jPKb8Nca76zQ0s||DynUPwLJdBeco)(YtfA>|f>D z-y-h{-_7x6sh2}NB_BSU@<+&SIvC~w!)Y3ZLo^P5ydkupg7cj&4T_+F@MVVPixH!w zVkbO&nE;KEtx5eHzR3Ezp7ZqrXIDS?f`452Vu=iDnGn7V(tPt^Kn z+1soQr*4Ty-@rCD+YlP%edX}?58$caZIJdG^j)7fY5rDz>G1dW)C=P8o9oi^cMbe~ zgWUEaqmKiF$VqkYs`9H1I^QUC-jqF7?jH5S*nDJ?kJeERA1AWU7Rqz@SaeL1kFpn< zt@&7Dw0|+}fBAW~8r!Z6$-bW1mr2ul_O5JbYQ7hG{j(+sOA&kbB2$&~lQI>#B?(K# zf0MBEHDEazSnm96`(XK104$qsNx~Aj)q$nvR$wV{=u&Z85*BM+5|;O{xm@|)Pw4*f z_Q7&)04$S!lZ2)IH+ro723UrcsEJeU5x701b=vQexK(f`lsguFZs2Bv z+nsOwaKo2p_QhCecjxLN-hJf2ug+_MTf40JOJslW$vk&05L0XZI~-s967+qS`0U;N zE6QK}SlKVNIu}8$%wK}D><_-WRP2>J`+8s#+#d?U{VoIdyEN{<2lpmN#_FMmtIw-m zPvX9xf%}ED|JX_|?g4rrfxGB|MsPQ2qx8VSnfwngED`1yvoDhmE%4z+%?G_E_0V!nOI7)`&{61jjCqx~kG8*hLyy(Zd+E`UK`twJSDJwy z?zj?|BN^&VYpp6jMAL1Mrdtqwmq6crb-g|T@;S?(L5rqASZKh#eqwJ_88oQ+Ymx?Y z4H~St1^Il&O9KnrC7n!EahE81r9B8<7yo(S_W@(=+_6h&BR?Yc=eJ`QUx4ADsWbr9y{o#>C)?Do+pB^5l zJMNJFeY&HCzSuAH$h-8hA%G9fcO+%eLe~o}6Bi_9vB=O9kw=q!*vsI0~a_xPgN1OKje~Lb86T40BTGZb)@?9ADRy1?tQwFg<;N0>rp_`l;)qQM`KAd** z?LoA=X@a%P2EVhxrIJ_$!FLMy$XZO+Y1_o>2P5m|ftQ?Veo*uKSonR*{*k5&q0=q& zC+$>0pF-k5VH8W5zkL6Ek!i2X=o{Xe9C=G|Gqzv{|BPlW(5~ZDh<{^@=kl zHsPC;-+Nq#-Ot%BcP&vw{Ee*JPp7=YSYuRR_nNY3q5Di(6!=6A#YV{p6L!Y&$V#I_ z(+wg!4!-!p!B^8v$qDPpXc6Q0B?W7~eLe5x_Y3^4(LAZ)`=0P;{j7 z2Md|!O!#U<#%2(6hK(kEc!~ef?>*ynJTP%!YS~C^LF={SyT2NQKYF@Vw)V}QRlw6Lr@Yk>4UMB->x_GXXsHQEsv!o+@w z?1!^lx(u<0(8kzotGN-nxbhleJdI_XZ+?_LNave6`KEqvzPEH67QY8^7x~_aJ5!X5 zv{2S&wngmpCfaG#av*Zl;%lcAK7R>}|D>%p&AT??9WpBP{V(sz3auQWXD9Pc1@}J{ zvX@kxL56!hUsZm*;#01D5d6{oD;Q;-H2diwuFGtHqHe!P#RTQrm)#gzfZd)Ldljs? zMTT5`U%~yQ<`@$?${4dK&nQ#)=7zuE*z#8((={6R8gOsD&e=DKf%_Nu<^1i7UTHm% zJtvX1i?=Onf1sT=K2dv`f%EXZ=c>v#lZ*O56}yvX-%fp#Mxn3b(R-ldt(5zDUcFvm z&9iTmZw%f?DBl+TYv@m!z^PR)n9DBXW_03(T%;`7Np3Ivq z$h^#5@>KR0vTzjm%iPxqUtL-M2HBJS8I8{d!N+25tTALI!tZDMGafFEM+bnb*k;3l z->ehTu}6DSE_GWkOwSvEdloQ@O*RSHOUFZ*&o9*VPRUSD=C-NSI~n{%PIj5^wI_?O zaO}xV=x??6Hruf$`%^E-p8P(1O9#_(Y`qgTOyAQm>2-E;Et+O+6PNyd_T+)|<+mrL zk8_yY(!v0~`vSui8sFDyy!eJ@I`}@R@ol@@!S^533&MARgKtc1_YVB$iI{%Y#cP12 zzsC1t$Bz@!_{L=IjqiZ_Y!hp_T668a!oj!QTzjwo5T98}V|uoa`#Rx=)DEKbn)PQ2K`H<||D zx(xUZ2bNlm@1^PR9X~n{-;)CHogIL$^l`s4W&&w0bHpXUAh^Evl4JY4s-C&_E9zNb zYadeJ_exG?_NkM0KEOVyMOUSx>vHDrsOl@%K1Rz^{8!#_GrZ zBRYDZrjM)uTKmQ3A*uyhToX8Ou+0JGcbtI+s3<{N&ohv@9O1W${2Qi;qALf%$SD%*E$AFrTeq z?wanvd}$h(AIbppJYarM!+fiT*`&XcmlJ~J<-7p;-yT4J>0?DYSu7@A$%!rV@b-rR zZO;j4d%3_*+d`)jADyO7cj&ac%UeyS@1>#B^bB;8ex_+Ul|d)PL)Mn*WWlwEm-3D1 z&SL{)ThaEMVA}2)fd5ee_^$!3i!}agZ}RGuYK{MEjA6AWr1AfddO><+L_u=MLy`X59Ms}W+{(XAvllN2g zg7mQ$wA)r3z^1HToIQ480aUv>7GNB@YRL7Y>l!)79PTx*Je(E2Wr}587S5`d{QbDgT0rnru!4`kDmXu_ajpmFzku(v;M*90XQL0#XBD1#cBof+Jg+wJ zY}B|kCUD8Kv%w|Z-l4_2O}kmkWKG<~+UKY6OV+L}_%GJdme7AKZOzyFQq`Qd?Mm#Q z6sY|Z+4t|#{dOh#EwI-z4#xDcmi2;fp|4M1&!fN|L|N6Yo7H}-^e254rRfVgMwK2q z;rrc1vS)m0K^^fDwZ%6aQ|IcbC6|b;Qee-$XX~P$%R175L!DPraH_R;Fr4-H;>Ucg z*4(kIfIgMLC>@(R)CR{jD)!_I_k7 z+{wAC@E(yThj!0>{mI>}vE92PYr5XZU6S>xiI;He1?>;j($|D+&T+Aila5wGqqTQ$ zU9>lN2<+GM&FnAY%@P-#?wjF!bBf~!4WvyO?^n_0!5Qkzqt46Jk#TxZn`4(Apq}}5 z3C~d(zIFLKjW&e8+3-Qy*+aK8l;=Kt&sr#EjT}Iphaq+sxx~}qBe8^y8kYXLjj(#= z+kMq@h~1m#Alj__BEAeBJyOlSu+Y9MD||}$+Q=QktG7PS9#brIH2Qsse#bM$e+xa^ zK6k!tDDr+=%e#K)8aemZe^SlcC+AspQ-)d_ZYZ{*1Lj=t#D!P&yXE9Q)@u{4I%VD3 ztO0fr`vKD;wZY=Rv7^1nH9ewli5ZdE;p+RxsgY?GL=hOU)0^fzmi-CZmChkcCo zqT`5cG1D$X;pb0ZAX$aLObsGAHewU zf4Wt75%a*g=$KQkx=@XOckHjr8kjQvW!zV>U$y_%>t4TrGmN4~M&3LBZP7{N|B*fB z8~yHP$Q*fvzm_M{K@plcuzi`Z|A`i z;vbh}U)S{hpfY8z9sF5*ksCutA9a#H(PF&&%Q_`4l6-A$-bl%PS@;<-?5F(|m_op0 zC16s0R~+f-`w9B4(76`z@79)#PUgOJ+ZMSu+jnzU_MsoO$M!_7${$pImzq~<^_sU` z_V+kr6LWK44u1YWlvw~zmR3SC!N&=vUS^lI7)EfaJdft`h(Q@B(e<-uhk zxZn>QRf)Z1;v#2x-^XTf`!VrZ^{LR=o5RS&X|DjBTG1uNxnoowlK=4D!O7c3*i!x_ zmD?g+?n{M3{m~vAq9O|cI2g8ho#<%6!R3RrZ^FD@a^;E+a`su1e5mZJV2%N^%pLwV z{JF;7N49Q2wpi0_*F9)+p{dySHF{2|0bbeLH}yspzhw>S(*DacRwQCW_eGDIb=};T zg_H+@qE{ALHFq^?JGv1ZCs4M)ntzwZTlsz* zS`UeVkt1RRqNih9wQ1REqs-dXD_aqMtGWGz#5uoMF}W|- zbtH3N-s+>HD4{@j-_ z`uDE^BlvLT9<-5?|7a)XzWgJ7HEJ4(Y&z@pJo|?}yjzm7R*p{&U$0Atu$9zd|LfeB zBY~?@!&?cwZtlzBl)Jev3;F-M=Dz#^bm?F&Sd(4WbSD3AEB9r&kB(;U%dg?F3A3B~ zauell?#s{l-{gancQViZgz_4VZw>gC;+O6~M||jO)7^vVpxl{f(&xT>!`Ei3Zu2!? zn+^;)_REw@?#rjEgL7Xh9occLM@K$bwRKSoaXS7vwgLaIIiGxqZDi`5Qy547IZ5dq zo%?bCddY7a_~)aI*a|YQNITYH-dvL{j78BwyyI?#WbRAZKeKYHjtL)%|9qU)U3g8u zro!VBu^x3YHmu!(a~50=eR`S)^GfPU9!v!rHk7#@lr>fr`#ZejuIEsX^I%S=&F`8A zQ{eI00qcu7b3KhSqmfxbML7sLZ?zIMyVgNf|cN*>I6$VHxs z7Uw_!a;7XkH>*kVV17YtyXcgD>?fLeFgu9<9`^@t9!&O> zYtQ0u9P53_X-Hn34Hc}*3v;XurT6GLkh4GUN-jh4Nxq0(ynj>V$tfZ0vX38MJS@As}ccUCLsQK6My@h(;>Mr4={3L?s`f}ZcK^!tN0mnj??dkF#T3Z*)(riJ!Ku) zEyq;#qRkv)>c}fQb8@766=!6$PE~NaxiOaki|7rJyGbjOxiKpqPUgle+Rutc$+2dB zFZEBN{;ab&xAy{h23MZaqdb|+<+biy-VsTYUy$+_;j`=;zlaW!J(|K$?z$q%O&EmM zTiI)4@442^lZl-Xt>l|ZohS1r9ZtMbKX{7`df8gV+a1r7dHXxr3(h4s6Ea%s=2op5 zx^v~{D*7NcZ@reEm|iQki~KAvtSbK%<4)w~U2-i4%g>1^^21$iQOOZ#%1^zNk#or` zYoRPfehwzr=7C=R%ei!sfqjr4CuTp_et!AZMQwXK=M?44!zS_zy(_s@hj0dOFUf_J zXFp9HxwCANGGn$eoAELEkEuCM zD@GEth%JxasI^-9)jh+wwx*He6xx?DH@G=YEy`scYXdH^#oK_(u}$*rCwbSX%Nr@T z7)u*hT8X?&Q-5wnk0Afstii-_FZJi8%Cn2HpD+KFvlnT$7T=gO>)4YVzgyzV#E<3X zXqx&{EBYQWdC|UJ`JRnloBRlQUss>fqr9(4y_UbOqTDNs65sk8`j~{Bqv27umE^H} zO!{CPv^g?TC$iI}|L@}e8vTC_|C@b8ew5nBb@ZY1(xk-NuC|yv1ZV!o$ra075lOZY!_2b+{-8b>J2PJo=wtT+6*t1Ze!JS&XIx57T!B-`ha1C0`KSK| z_5it%J(*9LUxbFg>OpSY&Nt)H=l&mWXC5C#kv{w$!Vy66U?$+11Uv|M%OPG&A|l|8 z1Ku)#N4(aHfHxD=HLR|iD2KPfGa1+2sKomS9&1q7jS6_~nxOs!*ai3;<6pX%zF z?w;x)DEt1APiLyT>N)GFr>dTMO6E22^jhGAKS?#72``)Rt8(Sk4Sku4MVMzvz28x9 z@RzB^|Im&jyM?c2WLMl|%Wi?-%=aZ)c6(~s?aq_^ue97NIcw+0y^a4x?vLoYJL~ac^!yq2qh=|8C6e5m@5@Ko`@3<@e-w5pSlMGB<8)cHy>&ovzTF|@ z+pVK5#vf%{{5bZZ-8y7Z!hYOXeP%`S?G{VhW25c0zA+(ApQ;$kc)-~mr_G7%v)58S zM#a9{=Xc)6o?Emn?V7%qH8_cZ4jo0V-d@;Lay)!QK1&%V>#%9k-jD1zeDOkPbus;Z zDC1oh+LS)|%XRpp(B%H!UejaEkp4^TE#qE6vYqdwei5+Bmz5632N^865)$}})1YnI zNY=#kxYi6zcOF{dh0v8ij(1}}<$uZHwgg<)k`KTc&!ga(Pd?ZxaNUFNME@28x7p^o z8uRV=>w@G<;HJJkf^%lOzjzQ#+7-R?LS45Z_(aR$sG&MZyp|; zJJ#mEojdknaFKnPN$0^|^i<=c#*sR$r*#(RF}iUc0zE5a9d>KZ37XE0xoL6yms!x# zcr@dd%#V<y@rkyahi+xdxlZ#(WF047;aPIVenFnnHvX@G z≪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